summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2021-12-18 14:53:38 -0700
committerSean Whitton <spwhitton@spwhitton.name>2021-12-18 14:53:38 -0700
commit1afad25eec805ac37021f46fdeeba1b233c83fea (patch)
tree2b92e59e0c5646b128dc0ba02f4d55d72875d8c9
parenta9e7b7a8d7dccdec7a8aa0f0613e3e05fbd1f6b6 (diff)
parentf315d3121654ba5a752efbae3835af3e8b964f9f (diff)
downloademacs-1afad25eec805ac37021f46fdeeba1b233c83fea.tar.gz
Merge remote-tracking branch 'origin/master' into athena/unstable
-rw-r--r--.gitignore10
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--CONTRIBUTE40
-rw-r--r--ChangeLog.12
-rw-r--r--ChangeLog.22
-rw-r--r--ChangeLog.388703
-rw-r--r--GNUmakefile5
-rw-r--r--INSTALL11
-rw-r--r--INSTALL.REPO23
-rw-r--r--Makefile.in60
-rw-r--r--README2
-rw-r--r--admin/CPP-DEFINES2
-rw-r--r--admin/MAINTAINERS4
-rw-r--r--admin/README13
-rw-r--r--admin/authors.el88
-rwxr-xr-xadmin/automerge29
-rw-r--r--admin/charsets/mapfiles/CP720.map2
-rw-r--r--admin/charsets/mapfiles/CP858.map2
-rwxr-xr-xadmin/diff-tar-files4
-rwxr-xr-xadmin/emake7
-rw-r--r--admin/gitmerge.el96
-rw-r--r--admin/make-tarball.txt39
-rwxr-xr-xadmin/merge-gnulib13
-rw-r--r--admin/notes/bugtracker2
-rw-r--r--admin/notes/emba34
-rw-r--r--admin/notes/git-workflow8
-rw-r--r--admin/notes/multi-tty2
-rw-r--r--admin/notes/unicode60
-rw-r--r--admin/nt/dist-build/README-scripts37
-rwxr-xr-xadmin/nt/dist-build/build-dep-zips.py46
-rwxr-xr-xadmin/nt/dist-build/build-zips.sh2
-rw-r--r--admin/release-branch.txt76
-rw-r--r--admin/unidata/BidiBrackets.txt20
-rw-r--r--admin/unidata/BidiMirroring.txt26
-rw-r--r--admin/unidata/Blocks.txt22
-rw-r--r--admin/unidata/IVD_Sequences.txt142
-rw-r--r--admin/unidata/Makefile.in22
-rw-r--r--admin/unidata/NormalizationTest.txt849
-rw-r--r--admin/unidata/README42
-rw-r--r--admin/unidata/SpecialCasing.txt6
-rw-r--r--admin/unidata/UnicodeData.txt837
-rwxr-xr-xadmin/unidata/blocks.awk39
-rw-r--r--admin/unidata/copyright.html2
-rw-r--r--admin/unidata/emoji-data.txt1297
-rw-r--r--admin/unidata/emoji-sequences.txt1469
-rw-r--r--admin/unidata/emoji-test.txt4991
-rw-r--r--admin/unidata/emoji-zwj-sequences.txt1410
-rw-r--r--admin/unidata/emoji-zwj.awk140
-rwxr-xr-xadmin/update_autogen88
-rwxr-xr-xbuild-aux/config.guess1229
-rwxr-xr-xbuild-aux/config.sub87
-rwxr-xr-xbuild-aux/gitlog-to-changelog5
-rw-r--r--config.bat7
-rw-r--r--configure.ac506
-rw-r--r--doc/emacs/Makefile.in1
-rw-r--r--doc/emacs/abbrevs.texi2
-rw-r--r--doc/emacs/anti.texi198
-rw-r--r--doc/emacs/basic.texi20
-rw-r--r--doc/emacs/building.texi7
-rw-r--r--doc/emacs/calendar.texi14
-rw-r--r--doc/emacs/cmdargs.texi14
-rw-r--r--doc/emacs/custom.texi218
-rw-r--r--doc/emacs/dired.texi47
-rw-r--r--doc/emacs/display.texi65
-rw-r--r--doc/emacs/emacs.texi27
-rw-r--r--doc/emacs/files.texi32
-rw-r--r--doc/emacs/fixit.texi7
-rw-r--r--doc/emacs/frames.texi241
-rw-r--r--doc/emacs/glossary.texi15
-rw-r--r--doc/emacs/haiku.texi124
-rw-r--r--doc/emacs/help.texi72
-rw-r--r--doc/emacs/killing.texi10
-rw-r--r--doc/emacs/kmacro.texi10
-rw-r--r--doc/emacs/m-x.texi9
-rw-r--r--doc/emacs/macos.texi2
-rw-r--r--doc/emacs/maintaining.texi201
-rw-r--r--doc/emacs/mark.texi7
-rw-r--r--doc/emacs/mini.texi5
-rw-r--r--doc/emacs/misc.texi98
-rw-r--r--doc/emacs/msdos-xtra.texi2
-rw-r--r--doc/emacs/msdos.texi10
-rw-r--r--doc/emacs/mule.texi50
-rw-r--r--doc/emacs/package.texi2
-rw-r--r--doc/emacs/programs.texi73
-rw-r--r--doc/emacs/regs.texi30
-rw-r--r--doc/emacs/search.texi39
-rw-r--r--doc/emacs/text.texi11
-rw-r--r--doc/emacs/trouble.texi11
-rw-r--r--doc/emacs/windows.texi16
-rw-r--r--doc/emacs/xresources.texi8
-rw-r--r--doc/lispintro/emacs-lisp-intro.texi164
-rw-r--r--doc/lispref/anti.texi241
-rw-r--r--doc/lispref/buffers.texi44
-rw-r--r--doc/lispref/commands.texi345
-rw-r--r--doc/lispref/compile.texi26
-rw-r--r--doc/lispref/control.texi11
-rw-r--r--doc/lispref/customize.texi5
-rw-r--r--doc/lispref/debugging.texi6
-rw-r--r--doc/lispref/display.texi451
-rw-r--r--doc/lispref/edebug.texi16
-rw-r--r--doc/lispref/elisp.texi16
-rw-r--r--doc/lispref/eval.texi13
-rw-r--r--doc/lispref/files.texi70
-rw-r--r--doc/lispref/frames.texi144
-rw-r--r--doc/lispref/functions.texi54
-rw-r--r--doc/lispref/help.texi17
-rw-r--r--doc/lispref/hooks.texi13
-rw-r--r--doc/lispref/internals.texi26
-rw-r--r--doc/lispref/keymaps.texi502
-rw-r--r--doc/lispref/lists.texi31
-rw-r--r--doc/lispref/loading.texi4
-rw-r--r--doc/lispref/minibuf.texi2
-rw-r--r--doc/lispref/modes.texi97
-rw-r--r--doc/lispref/nonascii.texi32
-rw-r--r--doc/lispref/objects.texi46
-rw-r--r--doc/lispref/os.texi51
-rw-r--r--doc/lispref/package.texi5
-rw-r--r--doc/lispref/processes.texi31
-rw-r--r--doc/lispref/searching.texi153
-rw-r--r--doc/lispref/sequences.texi18
-rw-r--r--doc/lispref/spellfile18
-rw-r--r--doc/lispref/strings.texi20
-rw-r--r--doc/lispref/symbols.texi205
-rw-r--r--doc/lispref/syntax.texi1
-rw-r--r--doc/lispref/text.texi309
-rw-r--r--doc/lispref/tips.texi57
-rw-r--r--doc/lispref/variables.texi243
-rw-r--r--doc/lispref/windows.texi1106
-rw-r--r--doc/man/emacs.1.in5
-rw-r--r--doc/man/emacsclient.15
-rw-r--r--doc/misc/ChangeLog.12
-rw-r--r--doc/misc/calc.texi2
-rw-r--r--doc/misc/cc-mode.texi57
-rw-r--r--doc/misc/cl.texi78
-rw-r--r--doc/misc/ede.texi2
-rw-r--r--doc/misc/efaq-w32.texi4
-rw-r--r--doc/misc/efaq.texi461
-rw-r--r--doc/misc/eieio.texi17
-rw-r--r--doc/misc/emacs-mime.texi3
-rw-r--r--doc/misc/erc.texi60
-rw-r--r--doc/misc/ert.texi271
-rw-r--r--doc/misc/eshell.texi378
-rw-r--r--doc/misc/eww.texi37
-rw-r--r--doc/misc/flymake.texi285
-rw-r--r--doc/misc/gnus-faq.texi4
-rw-r--r--doc/misc/gnus.texi61
-rw-r--r--doc/misc/htmlfontify.texi4
-rw-r--r--doc/misc/mairix-el.texi14
-rw-r--r--doc/misc/message.texi17
-rw-r--r--doc/misc/mh-e.texi14
-rw-r--r--doc/misc/modus-themes.org848
-rw-r--r--doc/misc/org.org920
-rw-r--r--doc/misc/pcl-cvs.texi4
-rw-r--r--doc/misc/pgg.texi3
-rw-r--r--doc/misc/rcirc.texi91
-rw-r--r--doc/misc/reftex.texi30
-rw-r--r--doc/misc/speedbar.texi6
-rw-r--r--doc/misc/texinfo.tex267
-rw-r--r--doc/misc/tramp.texi134
-rw-r--r--doc/misc/trampver.texi4
-rw-r--r--doc/misc/url.texi6
-rw-r--r--doc/misc/vhdl-mode.texi6
-rw-r--r--etc/AUTHORS1678
-rw-r--r--etc/DEBUG35
-rw-r--r--etc/DISTRIB3
-rw-r--r--etc/ERC-NEWS196
-rw-r--r--etc/HELLO2
-rw-r--r--etc/MACHINES28
-rw-r--r--etc/NEWS4128
-rw-r--r--etc/NEWS.284603
-rw-r--r--etc/ORG-NEWS700
-rw-r--r--etc/PROBLEMS510
-rw-r--r--etc/TODO268
-rw-r--r--etc/charsets/README4
-rw-r--r--etc/compilation.txt3
-rw-r--r--etc/e/README18
-rw-r--r--etc/e/eterm-colorbin1179 -> 1296 bytes
-rw-r--r--etc/e/eterm-color.ti19
-rw-r--r--etc/e/eterm-directbin0 -> 1375 bytes
-rw-r--r--etc/images/README1
-rw-r--r--etc/images/connect-to-url.pbmbin0 -> 81 bytes
-rw-r--r--etc/images/connect-to-url.xpm281
-rw-r--r--etc/images/down.svg2
-rw-r--r--etc/images/left.svg2
-rw-r--r--etc/images/right.svg2
-rw-r--r--etc/images/up.svg2
-rw-r--r--etc/org.gnu.emacs.defaults.gschema.xml51
-rw-r--r--etc/org/csl/README10
-rw-r--r--etc/org/csl/chicago-author-date.csl658
-rw-r--r--etc/org/csl/locales-en-US.xml357
-rw-r--r--etc/publicsuffix.txt854
-rw-r--r--etc/refcards/README47
-rw-r--r--etc/refcards/orgcard.tex4
-rw-r--r--etc/refcards/pl-refcard.tex2
-rw-r--r--etc/refcards/refcard.tex8
-rw-r--r--etc/refcards/ru-refcard.tex2
-rw-r--r--etc/themes/adwaita-theme.el3
-rw-r--r--etc/themes/deeper-blue-theme.el2
-rw-r--r--etc/themes/dichromacy-theme.el37
-rw-r--r--etc/themes/leuven-theme.el27
-rw-r--r--etc/themes/light-blue-theme.el3
-rw-r--r--etc/themes/manoj-dark-theme.el27
-rw-r--r--etc/themes/misterioso-theme.el33
-rw-r--r--etc/themes/modus-operandi-theme.el4
-rw-r--r--etc/themes/modus-themes.el894
-rw-r--r--etc/themes/modus-vivendi-theme.el4
-rw-r--r--etc/themes/tango-dark-theme.el37
-rw-r--r--etc/themes/tango-theme.el37
-rw-r--r--etc/themes/whiteboard-theme.el2
-rw-r--r--etc/themes/wombat-theme.el24
-rw-r--r--etc/tutorials/TUTORIAL18
-rw-r--r--etc/tutorials/TUTORIAL.he15
-rw-r--r--etc/tutorials/TUTORIAL.it19
-rw-r--r--etc/tutorials/TUTORIAL.sv14
-rw-r--r--leim/MISC-DIC/README2
-rw-r--r--leim/MISC-DIC/pinyin.map2
-rw-r--r--leim/MISC-DIC/ziranma.cin2
-rw-r--r--leim/SKK-DIC/SKK-JISYO.L7
-rw-r--r--lib-src/Makefile.in26
-rw-r--r--lib-src/be_resources.cc144
-rw-r--r--lib-src/emacsclient.c50
-rw-r--r--lib-src/etags.c11
-rw-r--r--lib-src/ntlib.c6
-rw-r--r--lib-src/seccomp-filter.c11
-rw-r--r--lib/_Noreturn.h10
-rw-r--r--lib/af_alg.h18
-rw-r--r--lib/alloca.in.h20
-rw-r--r--lib/allocator.c17
-rw-r--r--lib/allocator.h14
-rw-r--r--lib/arg-nonnull.h8
-rw-r--r--lib/attribute.h26
-rw-r--r--lib/binary-io.c14
-rw-r--r--lib/binary-io.h16
-rw-r--r--lib/byteswap.in.h14
-rw-r--r--lib/c++defs.h8
-rw-r--r--lib/c-ctype.c18
-rw-r--r--lib/c-ctype.h24
-rw-r--r--lib/c-strcase.h16
-rw-r--r--lib/c-strcasecmp.c16
-rw-r--r--lib/c-strncasecmp.c16
-rw-r--r--lib/canonicalize-lgpl.c18
-rw-r--r--lib/careadlinkat.c42
-rw-r--r--lib/careadlinkat.h14
-rw-r--r--lib/cdefs.h63
-rw-r--r--lib/cloexec.c18
-rw-r--r--lib/cloexec.h18
-rw-r--r--lib/close-stream.h18
-rw-r--r--lib/copy-file-range.c14
-rw-r--r--lib/count-leading-zeros.c18
-rw-r--r--lib/count-leading-zeros.h14
-rw-r--r--lib/count-one-bits.c18
-rw-r--r--lib/count-one-bits.h14
-rw-r--r--lib/count-trailing-zeros.c18
-rw-r--r--lib/count-trailing-zeros.h14
-rw-r--r--lib/dirent.in.h137
-rw-r--r--lib/dirfd.c14
-rw-r--r--lib/dtoastr.c17
-rw-r--r--lib/dup2.c14
-rw-r--r--lib/dynarray.h273
-rw-r--r--lib/eloop-threshold.h8
-rw-r--r--lib/errno.in.h16
-rw-r--r--lib/euidaccess.c14
-rw-r--r--lib/execinfo.c18
-rw-r--r--lib/execinfo.in.h8
-rw-r--r--lib/explicit_bzero.c8
-rw-r--r--lib/fcntl.c14
-rw-r--r--lib/fcntl.in.h14
-rw-r--r--lib/file-has-acl.c14
-rw-r--r--lib/filename.h8
-rw-r--r--lib/filevercmp.c16
-rw-r--r--lib/filevercmp.h16
-rw-r--r--lib/flexmember.h8
-rw-r--r--lib/free.c30
-rw-r--r--lib/fsusage.c14
-rw-r--r--lib/fsusage.h14
-rw-r--r--lib/fsync.c16
-rw-r--r--lib/futimens.c14
-rw-r--r--lib/getdtablesize.c14
-rw-r--r--lib/getgroups.c22
-rw-r--r--lib/getopt-cdefs.in.h21
-rw-r--r--lib/getopt-core.h8
-rw-r--r--lib/getopt-ext.h8
-rw-r--r--lib/getopt-pfx-core.h21
-rw-r--r--lib/getopt-pfx-ext.h21
-rw-r--r--lib/getopt.c12
-rw-r--r--lib/getopt.in.h24
-rw-r--r--lib/getopt1.c8
-rw-r--r--lib/getopt_int.h8
-rw-r--r--lib/getrandom.c20
-rw-r--r--lib/gettext.h16
-rw-r--r--lib/gettime.c14
-rw-r--r--lib/gettimeofday.c16
-rw-r--r--lib/gnulib.mk.in1303
-rw-r--r--lib/group-member.c22
-rw-r--r--lib/idx.h28
-rw-r--r--lib/ieee754.in.h8
-rw-r--r--lib/ignore-value.h14
-rw-r--r--lib/intprops.h27
-rw-r--r--lib/inttypes.in.h14
-rw-r--r--lib/libc-config.h34
-rw-r--r--lib/limits.in.h32
-rw-r--r--lib/lstat.c14
-rw-r--r--lib/malloc.c51
-rw-r--r--lib/malloc/dynarray-skeleton.c41
-rw-r--r--lib/malloc/dynarray.h8
-rw-r--r--lib/malloc/dynarray_at_failure.c15
-rw-r--r--lib/malloc/dynarray_emplace_enlarge.c12
-rw-r--r--lib/malloc/dynarray_finalize.c12
-rw-r--r--lib/malloc/dynarray_resize.c12
-rw-r--r--lib/malloc/dynarray_resize_clear.c12
-rw-r--r--lib/malloc/scratch_buffer.h8
-rw-r--r--lib/malloc/scratch_buffer_dupfree.c8
-rw-r--r--lib/malloc/scratch_buffer_grow.c8
-rw-r--r--lib/malloc/scratch_buffer_grow_preserve.c8
-rw-r--r--lib/malloc/scratch_buffer_set_array_size.c8
-rw-r--r--lib/malloca.c106
-rw-r--r--lib/malloca.h123
-rw-r--r--lib/md5-stream.c141
-rw-r--r--lib/md5.c116
-rw-r--r--lib/md5.h17
-rw-r--r--lib/memmem.c16
-rw-r--r--lib/mempcpy.c21
-rw-r--r--lib/memrchr.c14
-rw-r--r--lib/mini-gmp-gnulib.c28
-rw-r--r--lib/mini-gmp.c22
-rw-r--r--lib/mini-gmp.h9
-rw-r--r--lib/minmax.h16
-rw-r--r--lib/mkostemp.c14
-rw-r--r--lib/mktime-internal.h8
-rw-r--r--lib/mktime.c8
-rw-r--r--lib/nproc.c403
-rw-r--r--lib/nproc.h46
-rw-r--r--lib/nstrftime.c19
-rw-r--r--lib/open.c14
-rw-r--r--lib/pathmax.h16
-rw-r--r--lib/pipe2.c18
-rw-r--r--lib/pselect.c16
-rw-r--r--lib/pthread_sigmask.c14
-rw-r--r--lib/rawmemchr.c95
-rw-r--r--lib/rawmemchr.valgrind14
-rw-r--r--lib/readlink.c18
-rw-r--r--lib/realloc.c63
-rw-r--r--lib/regcomp.c16
-rw-r--r--lib/regex.c9
-rw-r--r--lib/regex.h58
-rw-r--r--lib/regex_internal.c18
-rw-r--r--lib/regex_internal.h17
-rw-r--r--lib/regexec.c109
-rw-r--r--lib/root-uid.h18
-rw-r--r--lib/save-cwd.h4
-rw-r--r--lib/scratch_buffer.h115
-rw-r--r--lib/set-permissions.c2
-rw-r--r--lib/sha1.c115
-rw-r--r--lib/sha1.h19
-rw-r--r--lib/sha256.c130
-rw-r--r--lib/sha256.h15
-rw-r--r--lib/sha512.c130
-rw-r--r--lib/sha512.h15
-rw-r--r--lib/sigdescr_np.c16
-rw-r--r--lib/signal.in.h14
-rw-r--r--lib/stat-time.c18
-rw-r--r--lib/stat-time.h20
-rw-r--r--lib/stdalign.in.h29
-rw-r--r--lib/stddef.in.h27
-rw-r--r--lib/stdint.in.h20
-rw-r--r--lib/stdio-impl.h14
-rw-r--r--lib/stdio.in.h211
-rw-r--r--lib/stdlib.in.h335
-rw-r--r--lib/stpcpy.c14
-rw-r--r--lib/str-two-way.h16
-rw-r--r--lib/strftime.h14
-rw-r--r--lib/string.in.h98
-rw-r--r--lib/strnlen.c16
-rw-r--r--lib/strtoimax.c14
-rw-r--r--lib/strtol.c55
-rw-r--r--lib/strtoll.c14
-rw-r--r--lib/symlink.c18
-rw-r--r--lib/sys_random.in.h16
-rw-r--r--lib/sys_select.in.h19
-rw-r--r--lib/sys_stat.in.h16
-rw-r--r--lib/sys_time.in.h16
-rw-r--r--lib/sys_types.in.h16
-rw-r--r--lib/tempname.c12
-rw-r--r--lib/tempname.h14
-rw-r--r--lib/time-internal.h16
-rw-r--r--lib/time.in.h58
-rw-r--r--lib/time_r.c16
-rw-r--r--lib/time_rz.c16
-rw-r--r--lib/timegm.c8
-rw-r--r--lib/timespec.c18
-rw-r--r--lib/timespec.h14
-rw-r--r--lib/u64.c18
-rw-r--r--lib/u64.h14
-rw-r--r--lib/unistd.c18
-rw-r--r--lib/unistd.in.h29
-rw-r--r--lib/unlocked-io.h26
-rw-r--r--lib/utimens.c20
-rw-r--r--lib/utimens.h14
-rw-r--r--lib/verify.h18
-rw-r--r--lib/warn-on-use.h8
-rw-r--r--lib/xalloc-oversized.h53
-rw-r--r--lisp/ChangeLog.122
-rw-r--r--lisp/ChangeLog.152
-rw-r--r--lisp/ChangeLog.174
-rw-r--r--lisp/ChangeLog.72
-rw-r--r--lisp/ChangeLog.82
-rw-r--r--lisp/Makefile.in31
-rw-r--r--lisp/abbrev.el29
-rw-r--r--lisp/align.el64
-rw-r--r--lisp/allout-widgets.el20
-rw-r--r--lisp/allout.el102
-rw-r--r--lisp/ansi-color.el696
-rw-r--r--lisp/apropos.el35
-rw-r--r--lisp/arc-mode.el18
-rw-r--r--lisp/array.el5
-rw-r--r--lisp/auth-source-pass.el2
-rw-r--r--lisp/auth-source.el79
-rw-r--r--lisp/autoarg.el2
-rw-r--r--lisp/autoinsert.el8
-rw-r--r--lisp/autorevert.el23
-rw-r--r--lisp/avoid.el10
-rw-r--r--lisp/bindings.el63
-rw-r--r--lisp/bookmark.el243
-rw-r--r--lisp/bs.el5
-rw-r--r--lisp/buff-menu.el6
-rw-r--r--lisp/button.el59
-rw-r--r--lisp/calc/calc-aent.el5
-rw-r--r--lisp/calc/calc-bin.el2
-rw-r--r--lisp/calc/calc-ext.el40
-rw-r--r--lisp/calc/calc-forms.el15
-rw-r--r--lisp/calc/calc-graph.el38
-rw-r--r--lisp/calc/calc-help.el31
-rw-r--r--lisp/calc/calc-map.el2
-rw-r--r--lisp/calc/calc-math.el5
-rw-r--r--lisp/calc/calc-menu.el2
-rw-r--r--lisp/calc/calc-misc.el45
-rw-r--r--lisp/calc/calc-mode.el9
-rw-r--r--lisp/calc/calc-poly.el2
-rw-r--r--lisp/calc/calc-prog.el11
-rw-r--r--lisp/calc/calc-store.el43
-rw-r--r--lisp/calc/calc-units.el41
-rw-r--r--lisp/calc/calc.el90
-rw-r--r--lisp/calc/calcalg3.el2
-rw-r--r--lisp/calculator.el54
-rw-r--r--lisp/calendar/cal-tex.el6
-rw-r--r--lisp/calendar/calendar.el11
-rw-r--r--lisp/calendar/diary-lib.el18
-rw-r--r--lisp/calendar/holidays.el2
-rw-r--r--lisp/calendar/icalendar.el21
-rw-r--r--lisp/calendar/time-date.el13
-rw-r--r--lisp/calendar/timeclock.el28
-rw-r--r--lisp/calendar/todo-mode.el18
-rw-r--r--lisp/cedet/ChangeLog.12
-rw-r--r--lisp/cedet/data-debug.el4
-rw-r--r--lisp/cedet/ede/auto.el4
-rw-r--r--lisp/cedet/ede/base.el4
-rw-r--r--lisp/cedet/ede/cpp-root.el2
-rw-r--r--lisp/cedet/ede/makefile-edit.el2
-rw-r--r--lisp/cedet/ede/proj-elisp.el4
-rw-r--r--lisp/cedet/ede/proj.el2
-rw-r--r--lisp/cedet/ede/project-am.el6
-rw-r--r--lisp/cedet/ede/source.el4
-rw-r--r--lisp/cedet/ede/system.el2
-rw-r--r--lisp/cedet/mode-local.el17
-rw-r--r--lisp/cedet/pulse.el6
-rw-r--r--lisp/cedet/semantic.el2
-rw-r--r--lisp/cedet/semantic/analyze/complete.el5
-rw-r--r--lisp/cedet/semantic/bovine/c.el46
-rw-r--r--lisp/cedet/semantic/bovine/debug.el2
-rw-r--r--lisp/cedet/semantic/complete.el15
-rw-r--r--lisp/cedet/semantic/db-el.el2
-rw-r--r--lisp/cedet/semantic/db-find.el4
-rw-r--r--lisp/cedet/semantic/db-typecache.el3
-rw-r--r--lisp/cedet/semantic/debug.el8
-rw-r--r--lisp/cedet/semantic/decorate/include.el16
-rw-r--r--lisp/cedet/semantic/decorate/mode.el8
-rw-r--r--lisp/cedet/semantic/dep.el3
-rw-r--r--lisp/cedet/semantic/ede-grammar.el2
-rw-r--r--lisp/cedet/semantic/fw.el4
-rw-r--r--lisp/cedet/semantic/grammar.el2
-rw-r--r--lisp/cedet/semantic/grm-wy-boot.el8
-rw-r--r--lisp/cedet/semantic/idle.el17
-rw-r--r--lisp/cedet/semantic/lex-spp.el9
-rw-r--r--lisp/cedet/semantic/lex.el17
-rw-r--r--lisp/cedet/semantic/symref/cscope.el2
-rw-r--r--lisp/cedet/semantic/symref/grep.el24
-rw-r--r--lisp/cedet/semantic/symref/list.el2
-rw-r--r--lisp/cedet/semantic/tag-ls.el19
-rw-r--r--lisp/cedet/semantic/tag.el13
-rw-r--r--lisp/cedet/semantic/util-modes.el4
-rw-r--r--lisp/cedet/semantic/wisent.el2
-rw-r--r--lisp/cedet/semantic/wisent/python.el6
-rw-r--r--lisp/cedet/srecode/ctxt.el2
-rw-r--r--lisp/cedet/srecode/dictionary.el4
-rw-r--r--lisp/cedet/srecode/semantic.el2
-rw-r--r--lisp/char-fold.el148
-rw-r--r--lisp/cmuscheme.el13
-rw-r--r--lisp/comint.el242
-rw-r--r--lisp/completion.el11
-rw-r--r--lisp/composite.el33
-rw-r--r--lisp/cus-edit.el22
-rw-r--r--lisp/cus-face.el38
-rw-r--r--lisp/cus-start.el23
-rw-r--r--lisp/cus-theme.el36
-rw-r--r--lisp/custom.el33
-rw-r--r--lisp/dabbrev.el3
-rw-r--r--lisp/delim-col.el4
-rw-r--r--lisp/descr-text.el13
-rw-r--r--lisp/dired-aux.el166
-rw-r--r--lisp/dired-x.el61
-rw-r--r--lisp/dired.el468
-rw-r--r--lisp/display-fill-column-indicator.el2
-rw-r--r--lisp/dnd.el2
-rw-r--r--lisp/doc-view.el106
-rw-r--r--lisp/dos-fns.el4
-rw-r--r--lisp/dos-vars.el6
-rw-r--r--lisp/edmacro.el128
-rw-r--r--lisp/elec-pair.el137
-rw-r--r--lisp/electric.el10
-rw-r--r--lisp/emacs-lisp/advice.el116
-rw-r--r--lisp/emacs-lisp/autoload.el36
-rw-r--r--lisp/emacs-lisp/avl-tree.el3
-rw-r--r--lisp/emacs-lisp/backquote.el5
-rw-r--r--lisp/emacs-lisp/backtrace.el26
-rw-r--r--lisp/emacs-lisp/byte-opt.el416
-rw-r--r--lisp/emacs-lisp/byte-run.el24
-rw-r--r--lisp/emacs-lisp/bytecomp.el105
-rw-r--r--lisp/emacs-lisp/cconv.el42
-rw-r--r--lisp/emacs-lisp/check-declare.el6
-rw-r--r--lisp/emacs-lisp/checkdoc.el540
-rw-r--r--lisp/emacs-lisp/cl-extra.el4
-rw-r--r--lisp/emacs-lisp/cl-generic.el38
-rw-r--r--lisp/emacs-lisp/cl-indent.el4
-rw-r--r--lisp/emacs-lisp/cl-lib.el5
-rw-r--r--lisp/emacs-lisp/cl-macs.el55
-rw-r--r--lisp/emacs-lisp/comp-cstr.el68
-rw-r--r--lisp/emacs-lisp/comp.el114
-rw-r--r--lisp/emacs-lisp/copyright.el4
-rw-r--r--lisp/emacs-lisp/crm.el47
-rw-r--r--lisp/emacs-lisp/debug.el41
-rw-r--r--lisp/emacs-lisp/derived.el39
-rw-r--r--lisp/emacs-lisp/disass.el4
-rw-r--r--lisp/emacs-lisp/easy-mmode.el25
-rw-r--r--lisp/emacs-lisp/edebug.el12
-rw-r--r--lisp/emacs-lisp/eieio-base.el2
-rw-r--r--lisp/emacs-lisp/eieio-compat.el5
-rw-r--r--lisp/emacs-lisp/eieio-core.el31
-rw-r--r--lisp/emacs-lisp/eieio-custom.el2
-rw-r--r--lisp/emacs-lisp/eieio-opt.el1
-rw-r--r--lisp/emacs-lisp/eieio.el16
-rw-r--r--lisp/emacs-lisp/eldoc.el13
-rw-r--r--lisp/emacs-lisp/elint.el2
-rw-r--r--lisp/emacs-lisp/elp.el17
-rw-r--r--lisp/emacs-lisp/ert-x.el128
-rw-r--r--lisp/emacs-lisp/ert.el478
-rw-r--r--lisp/emacs-lisp/ewoc.el12
-rw-r--r--lisp/emacs-lisp/faceup.el2
-rw-r--r--lisp/emacs-lisp/find-func.el52
-rw-r--r--lisp/emacs-lisp/generator.el33
-rw-r--r--lisp/emacs-lisp/gv.el2
-rw-r--r--lisp/emacs-lisp/hierarchy.el5
-rw-r--r--lisp/emacs-lisp/let-alist.el4
-rw-r--r--lisp/emacs-lisp/lisp-mnt.el11
-rw-r--r--lisp/emacs-lisp/lisp-mode.el109
-rw-r--r--lisp/emacs-lisp/lisp.el32
-rw-r--r--lisp/emacs-lisp/macroexp.el19
-rw-r--r--lisp/emacs-lisp/map-ynp.el14
-rw-r--r--lisp/emacs-lisp/map.el44
-rw-r--r--lisp/emacs-lisp/memory-report.el20
-rw-r--r--lisp/emacs-lisp/multisession.el446
-rw-r--r--lisp/emacs-lisp/nadvice.el71
-rw-r--r--lisp/emacs-lisp/package-x.el2
-rw-r--r--lisp/emacs-lisp/package.el277
-rw-r--r--lisp/emacs-lisp/pcase.el8
-rw-r--r--lisp/emacs-lisp/pp.el242
-rw-r--r--lisp/emacs-lisp/re-builder.el21
-rw-r--r--lisp/emacs-lisp/rx.el3
-rw-r--r--lisp/emacs-lisp/seq.el20
-rw-r--r--lisp/emacs-lisp/shadow.el13
-rw-r--r--lisp/emacs-lisp/shortdoc.el140
-rw-r--r--lisp/emacs-lisp/shorthands.el80
-rw-r--r--lisp/emacs-lisp/smie.el2
-rw-r--r--lisp/emacs-lisp/subr-x.el130
-rw-r--r--lisp/emacs-lisp/tabulated-list.el106
-rw-r--r--lisp/emacs-lisp/testcover.el38
-rw-r--r--lisp/emacs-lisp/thunk.el2
-rw-r--r--lisp/emacs-lisp/timer.el124
-rw-r--r--lisp/emacs-lisp/warnings.el4
-rw-r--r--lisp/emulation/cua-base.el47
-rw-r--r--lisp/emulation/cua-rect.el12
-rw-r--r--lisp/emulation/edt-mapper.el6
-rw-r--r--lisp/emulation/keypad.el4
-rw-r--r--lisp/emulation/viper-cmd.el69
-rw-r--r--lisp/emulation/viper-ex.el9
-rw-r--r--lisp/emulation/viper-init.el79
-rw-r--r--lisp/emulation/viper-keym.el19
-rw-r--r--lisp/emulation/viper-macs.el12
-rw-r--r--lisp/emulation/viper-mous.el13
-rw-r--r--lisp/emulation/viper-util.el89
-rw-r--r--lisp/emulation/viper.el7
-rw-r--r--lisp/env.el17
-rw-r--r--lisp/epa-dired.el2
-rw-r--r--lisp/epa-file.el3
-rw-r--r--lisp/epa-hook.el22
-rw-r--r--lisp/epa-ks.el18
-rw-r--r--lisp/epa-mail.el3
-rw-r--r--lisp/epa.el25
-rw-r--r--lisp/epg.el45
-rw-r--r--lisp/erc/erc-autoaway.el8
-rw-r--r--lisp/erc/erc-backend.el92
-rw-r--r--lisp/erc/erc-button.el16
-rw-r--r--lisp/erc/erc-compat.el (renamed from lisp/obsolete/erc-compat.el)36
-rw-r--r--lisp/erc/erc-dcc.el42
-rw-r--r--lisp/erc/erc-fill.el12
-rw-r--r--lisp/erc/erc-goodies.el2
-rw-r--r--lisp/erc/erc-ibuffer.el9
-rw-r--r--lisp/erc/erc-identd.el3
-rw-r--r--lisp/erc/erc-imenu.el3
-rw-r--r--lisp/erc/erc-join.el53
-rw-r--r--lisp/erc/erc-log.el10
-rw-r--r--lisp/erc/erc-match.el10
-rw-r--r--lisp/erc/erc-menu.el3
-rw-r--r--lisp/erc/erc-netsplit.el5
-rw-r--r--lisp/erc/erc-networks.el15
-rw-r--r--lisp/erc/erc-notify.el6
-rw-r--r--lisp/erc/erc-pcomplete.el5
-rw-r--r--lisp/erc/erc-replace.el5
-rw-r--r--lisp/erc/erc-ring.el2
-rw-r--r--lisp/erc/erc-services.el168
-rw-r--r--lisp/erc/erc-sound.el5
-rw-r--r--lisp/erc/erc-speedbar.el25
-rw-r--r--lisp/erc/erc-spelling.el2
-rw-r--r--lisp/erc/erc-stamp.el16
-rw-r--r--lisp/erc/erc-status-sidebar.el2
-rw-r--r--lisp/erc/erc-track.el164
-rw-r--r--lisp/erc/erc-truncate.el6
-rw-r--r--lisp/erc/erc-xdcc.el2
-rw-r--r--lisp/erc/erc.el456
-rw-r--r--lisp/eshell/em-basic.el2
-rw-r--r--lisp/eshell/em-cmpl.el9
-rw-r--r--lisp/eshell/em-glob.el4
-rw-r--r--lisp/eshell/em-hist.el2
-rw-r--r--lisp/eshell/em-ls.el14
-rw-r--r--lisp/eshell/em-pred.el4
-rw-r--r--lisp/eshell/em-rebind.el2
-rw-r--r--lisp/eshell/em-smart.el4
-rw-r--r--lisp/eshell/em-term.el6
-rw-r--r--lisp/eshell/em-unix.el5
-rw-r--r--lisp/eshell/esh-arg.el2
-rw-r--r--lisp/eshell/esh-cmd.el38
-rw-r--r--lisp/eshell/esh-ext.el2
-rw-r--r--lisp/eshell/esh-io.el4
-rw-r--r--lisp/eshell/esh-mode.el30
-rw-r--r--lisp/eshell/esh-module.el2
-rw-r--r--lisp/eshell/esh-util.el4
-rw-r--r--lisp/eshell/esh-var.el2
-rw-r--r--lisp/eshell/eshell.el12
-rw-r--r--lisp/expand.el2
-rw-r--r--lisp/ezimage.el1
-rw-r--r--lisp/face-remap.el13
-rw-r--r--lisp/facemenu.el11
-rw-r--r--lisp/faces.el162
-rw-r--r--lisp/ffap.el21
-rw-r--r--lisp/fileloop.el1
-rw-r--r--lisp/filenotify.el33
-rw-r--r--lisp/files-x.el2
-rw-r--r--lisp/files.el490
-rw-r--r--lisp/filesets.el16
-rw-r--r--lisp/find-dired.el2
-rw-r--r--lisp/find-file.el18
-rw-r--r--lisp/find-lisp.el6
-rw-r--r--lisp/finder.el26
-rw-r--r--lisp/foldout.el2
-rw-r--r--lisp/follow.el45
-rw-r--r--lisp/font-core.el2
-rw-r--r--lisp/font-lock.el12
-rw-r--r--lisp/format.el6
-rw-r--r--lisp/forms.el22
-rw-r--r--lisp/frame.el111
-rw-r--r--lisp/frameset.el5
-rw-r--r--lisp/gnus/ChangeLog.22
-rw-r--r--lisp/gnus/ChangeLog.32
-rw-r--r--lisp/gnus/gmm-utils.el1
-rw-r--r--lisp/gnus/gnus-agent.el138
-rw-r--r--lisp/gnus/gnus-art.el325
-rw-r--r--lisp/gnus/gnus-bookmark.el53
-rw-r--r--lisp/gnus/gnus-cite.el4
-rw-r--r--lisp/gnus/gnus-diary.el6
-rw-r--r--lisp/gnus/gnus-dired.el22
-rw-r--r--lisp/gnus/gnus-draft.el15
-rw-r--r--lisp/gnus/gnus-eform.el11
-rw-r--r--lisp/gnus/gnus-fun.el7
-rw-r--r--lisp/gnus/gnus-group.el455
-rw-r--r--lisp/gnus/gnus-html.el26
-rw-r--r--lisp/gnus/gnus-icalendar.el67
-rw-r--r--lisp/gnus/gnus-int.el3
-rw-r--r--lisp/gnus/gnus-kill.el21
-rw-r--r--lisp/gnus/gnus-ml.el19
-rw-r--r--lisp/gnus/gnus-mlspl.el2
-rw-r--r--lisp/gnus/gnus-msg.el98
-rw-r--r--lisp/gnus/gnus-range.el11
-rw-r--r--lisp/gnus/gnus-registry.el15
-rw-r--r--lisp/gnus/gnus-salt.el50
-rw-r--r--lisp/gnus/gnus-score.el52
-rw-r--r--lisp/gnus/gnus-search.el72
-rw-r--r--lisp/gnus/gnus-sieve.el5
-rw-r--r--lisp/gnus/gnus-srvr.el141
-rw-r--r--lisp/gnus/gnus-start.el18
-rw-r--r--lisp/gnus/gnus-sum.el1045
-rw-r--r--lisp/gnus/gnus-topic.el105
-rw-r--r--lisp/gnus/gnus-undo.el15
-rw-r--r--lisp/gnus/gnus-util.el21
-rw-r--r--lisp/gnus/gnus-uu.el40
-rw-r--r--lisp/gnus/gnus.el65
-rw-r--r--lisp/gnus/mail-source.el19
-rw-r--r--lisp/gnus/message.el247
-rw-r--r--lisp/gnus/mm-decode.el26
-rw-r--r--lisp/gnus/mm-util.el2
-rw-r--r--lisp/gnus/mm-uu.el12
-rw-r--r--lisp/gnus/mm-view.el61
-rw-r--r--lisp/gnus/mml-sec.el6
-rw-r--r--lisp/gnus/mml-smime.el8
-rw-r--r--lisp/gnus/mml.el100
-rw-r--r--lisp/gnus/mml1991.el3
-rw-r--r--lisp/gnus/mml2015.el19
-rw-r--r--lisp/gnus/nndiary.el15
-rw-r--r--lisp/gnus/nnimap.el50
-rw-r--r--lisp/gnus/nnmaildir.el10
-rw-r--r--lisp/gnus/nnrss.el18
-rw-r--r--lisp/gnus/nnselect.el4
-rw-r--r--lisp/gnus/nntp.el4
-rw-r--r--lisp/gnus/nnvirtual.el11
-rw-r--r--lisp/gnus/spam.el28
-rw-r--r--lisp/help-at-pt.el10
-rw-r--r--lisp/help-fns.el655
-rw-r--r--lisp/help-macro.el12
-rw-r--r--lisp/help-mode.el103
-rw-r--r--lisp/help.el499
-rw-r--r--lisp/hexl.el6
-rw-r--r--lisp/hi-lock.el8
-rw-r--r--lisp/hilit-chg.el2
-rw-r--r--lisp/hippie-exp.el2
-rw-r--r--lisp/htmlfontify.el249
-rw-r--r--lisp/ibuf-ext.el11
-rw-r--r--lisp/ibuffer.el8
-rw-r--r--lisp/icomplete.el28
-rw-r--r--lisp/ido.el18
-rw-r--r--lisp/ielm.el41
-rw-r--r--lisp/iimage.el2
-rw-r--r--lisp/image-dired.el1888
-rw-r--r--lisp/image-file.el2
-rw-r--r--lisp/image-mode.el136
-rw-r--r--lisp/image.el126
-rw-r--r--lisp/image/exif.el22
-rw-r--r--lisp/image/gravatar.el4
-rw-r--r--lisp/imenu.el25
-rw-r--r--lisp/indent.el34
-rw-r--r--lisp/info-look.el119
-rw-r--r--lisp/info-xref.el8
-rw-r--r--lisp/info.el111
-rw-r--r--lisp/informat.el2
-rw-r--r--lisp/international/ccl.el21
-rw-r--r--lisp/international/characters.el220
-rw-r--r--lisp/international/emoji.el657
-rw-r--r--lisp/international/fontset.el212
-rw-r--r--lisp/international/iso-cvt.el4
-rw-r--r--lisp/international/iso-transl.el23
-rw-r--r--lisp/international/latexenc.el4
-rw-r--r--lisp/international/mule-cmds.el441
-rw-r--r--lisp/international/mule-conf.el2
-rw-r--r--lisp/international/mule-diag.el383
-rw-r--r--lisp/international/mule-util.el13
-rw-r--r--lisp/international/mule.el37
-rw-r--r--lisp/international/quail.el11
-rw-r--r--lisp/international/robin.el11
-rw-r--r--lisp/international/titdic-cnv.el10
-rw-r--r--lisp/international/ucs-normalize.el92
-rw-r--r--lisp/isearch.el131
-rw-r--r--lisp/jit-lock.el17
-rw-r--r--lisp/jka-cmpr-hook.el5
-rw-r--r--lisp/jsonrpc.el6
-rw-r--r--lisp/kermit.el2
-rw-r--r--lisp/keymap.el457
-rw-r--r--lisp/kmacro.el52
-rw-r--r--lisp/language/burmese.el2
-rw-r--r--lisp/language/cyril-util.el2
-rw-r--r--lisp/language/ethio-util.el4
-rw-r--r--lisp/language/hanja-util.el4
-rw-r--r--lisp/language/ind-util.el12
-rw-r--r--lisp/language/japan-util.el4
-rw-r--r--lisp/language/japanese.el23
-rw-r--r--lisp/language/khmer.el2
-rw-r--r--lisp/language/lao.el10
-rw-r--r--lisp/language/misc-lang.el20
-rw-r--r--lisp/language/sinhala.el2
-rw-r--r--lisp/language/thai-word.el13
-rw-r--r--lisp/language/tibet-util.el12
-rw-r--r--lisp/language/tibetan.el4
-rw-r--r--lisp/language/tv-util.el12
-rw-r--r--lisp/ldefs-boot.el1942
-rw-r--r--lisp/leim/quail/hangul.el4
-rw-r--r--lisp/leim/quail/ipa.el8
-rw-r--r--lisp/leim/quail/latin-post.el18
-rw-r--r--lisp/leim/quail/latin-pre.el18
-rw-r--r--lisp/leim/quail/persian.el2
-rw-r--r--lisp/leim/quail/sami.el2
-rw-r--r--lisp/leim/quail/vnvni.el2
-rw-r--r--lisp/linum.el3
-rw-r--r--lisp/loadhist.el3
-rw-r--r--lisp/loadup.el35
-rw-r--r--lisp/locate.el16
-rw-r--r--lisp/ls-lisp.el16
-rw-r--r--lisp/macros.el15
-rw-r--r--lisp/mail/blessmail.el2
-rw-r--r--lisp/mail/emacsbug.el4
-rw-r--r--lisp/mail/feedmail.el34
-rw-r--r--lisp/mail/footnote.el24
-rw-r--r--lisp/mail/mail-utils.el15
-rw-r--r--lisp/mail/mailabbrev.el12
-rw-r--r--lisp/mail/mailclient.el2
-rw-r--r--lisp/mail/mspools.el4
-rw-r--r--lisp/mail/reporter.el4
-rw-r--r--lisp/mail/rfc6068.el83
-rw-r--r--lisp/mail/rmail-spam-filter.el2
-rw-r--r--lisp/mail/rmail.el13
-rw-r--r--lisp/mail/rmailkwd.el9
-rw-r--r--lisp/mail/rmailmm.el2
-rw-r--r--lisp/mail/rmailout.el7
-rw-r--r--lisp/mail/rmailsum.el12
-rw-r--r--lisp/mail/sendmail.el40
-rw-r--r--lisp/mail/smtpmail.el6
-rw-r--r--lisp/mail/supercite.el4
-rw-r--r--lisp/mail/uce.el32
-rw-r--r--lisp/man.el58
-rw-r--r--lisp/menu-bar.el104
-rw-r--r--lisp/mh-e/ChangeLog.16
-rw-r--r--lisp/mh-e/mh-acros.el39
-rw-r--r--lisp/mh-e/mh-alias.el39
-rw-r--r--lisp/mh-e/mh-comp.el64
-rw-r--r--lisp/mh-e/mh-compat.el364
-rw-r--r--lisp/mh-e/mh-e.el570
-rw-r--r--lisp/mh-e/mh-folder.el450
-rw-r--r--lisp/mh-e/mh-funcs.el2
-rw-r--r--lisp/mh-e/mh-gnus.el149
-rw-r--r--lisp/mh-e/mh-identity.el27
-rw-r--r--lisp/mh-e/mh-junk.el14
-rw-r--r--lisp/mh-e/mh-letter.el184
-rw-r--r--lisp/mh-e/mh-limit.el8
-rw-r--r--lisp/mh-e/mh-mime.el201
-rw-r--r--lisp/mh-e/mh-scan.el77
-rw-r--r--lisp/mh-e/mh-search.el103
-rw-r--r--lisp/mh-e/mh-seq.el40
-rw-r--r--lisp/mh-e/mh-show.el298
-rw-r--r--lisp/mh-e/mh-speed.el85
-rw-r--r--lisp/mh-e/mh-thread.el50
-rw-r--r--lisp/mh-e/mh-tool-bar.el217
-rw-r--r--lisp/mh-e/mh-utils.el150
-rw-r--r--lisp/mh-e/mh-xface.el124
-rw-r--r--lisp/midnight.el4
-rw-r--r--lisp/minibuf-eldef.el2
-rw-r--r--lisp/minibuffer.el136
-rw-r--r--lisp/mouse-copy.el4
-rw-r--r--lisp/mouse-drag.el4
-rw-r--r--lisp/mouse.el625
-rw-r--r--lisp/mpc.el41
-rw-r--r--lisp/mwheel.el94
-rw-r--r--lisp/net/ange-ftp.el152
-rw-r--r--lisp/net/browse-url.el314
-rw-r--r--lisp/net/dbus.el27
-rw-r--r--lisp/net/dictionary.el54
-rw-r--r--lisp/net/eudc-bob.el15
-rw-r--r--lisp/net/eudc-hotlist.el5
-rw-r--r--lisp/net/eudc.el18
-rw-r--r--lisp/net/eudcb-ldap.el2
-rw-r--r--lisp/net/eww.el512
-rw-r--r--lisp/net/gnutls.el2
-rw-r--r--lisp/net/goto-addr.el5
-rw-r--r--lisp/net/hmac-def.el5
-rw-r--r--lisp/net/ldap.el6
-rw-r--r--lisp/net/mailcap.el71
-rw-r--r--lisp/net/mairix.el2
-rw-r--r--lisp/net/net-utils.el8
-rw-r--r--lisp/net/newst-backend.el57
-rw-r--r--lisp/net/newst-plainview.el6
-rw-r--r--lisp/net/newst-reader.el2
-rw-r--r--lisp/net/newst-ticker.el2
-rw-r--r--lisp/net/newsticker.el5
-rw-r--r--lisp/net/nsm.el11
-rw-r--r--lisp/net/ntlm.el29
-rw-r--r--lisp/net/puny.el1
-rw-r--r--lisp/net/quickurl.el20
-rw-r--r--lisp/net/rcirc.el539
-rw-r--r--lisp/net/rlogin.el4
-rw-r--r--lisp/net/sasl-cram.el2
-rw-r--r--lisp/net/sasl-digest.el4
-rw-r--r--lisp/net/sasl-ntlm.el4
-rw-r--r--lisp/net/sasl.el23
-rw-r--r--lisp/net/secrets.el2
-rw-r--r--lisp/net/shr-color.el2
-rw-r--r--lisp/net/shr.el290
-rw-r--r--lisp/net/sieve-manage.el2
-rw-r--r--lisp/net/sieve-mode.el2
-rw-r--r--lisp/net/sieve.el2
-rw-r--r--lisp/net/snmp-mode.el4
-rw-r--r--lisp/net/soap-client.el13
-rw-r--r--lisp/net/soap-inspect.el10
-rw-r--r--lisp/net/socks.el4
-rw-r--r--lisp/net/telnet.el16
-rw-r--r--lisp/net/tramp-adb.el131
-rw-r--r--lisp/net/tramp-archive.el15
-rw-r--r--lisp/net/tramp-cache.el37
-rw-r--r--lisp/net/tramp-cmds.el13
-rw-r--r--lisp/net/tramp-compat.el205
-rw-r--r--lisp/net/tramp-crypt.el22
-rw-r--r--lisp/net/tramp-ftp.el15
-rw-r--r--lisp/net/tramp-fuse.el88
-rw-r--r--lisp/net/tramp-gvfs.el147
-rw-r--r--lisp/net/tramp-integration.el23
-rw-r--r--lisp/net/tramp-rclone.el27
-rw-r--r--lisp/net/tramp-sh.el378
-rw-r--r--lisp/net/tramp-smb.el386
-rw-r--r--lisp/net/tramp-sshfs.el83
-rw-r--r--lisp/net/tramp-sudoedit.el56
-rw-r--r--lisp/net/tramp.el664
-rw-r--r--lisp/net/trampver.el15
-rw-r--r--lisp/net/webjump.el4
-rw-r--r--lisp/net/zeroconf.el6
-rw-r--r--lisp/newcomment.el13
-rw-r--r--lisp/notifications.el2
-rw-r--r--lisp/nxml/nxml-mode.el18
-rw-r--r--lisp/nxml/nxml-ns.el2
-rw-r--r--lisp/nxml/nxml-outln.el10
-rw-r--r--lisp/nxml/nxml-rap.el16
-rw-r--r--lisp/nxml/rng-cmpct.el2
-rw-r--r--lisp/nxml/rng-loc.el4
-rw-r--r--lisp/nxml/rng-nxml.el2
-rw-r--r--lisp/nxml/rng-valid.el23
-rw-r--r--lisp/nxml/rng-xsd.el2
-rw-r--r--lisp/nxml/xmltok.el18
-rw-r--r--lisp/nxml/xsd-regexp.el9
-rw-r--r--lisp/obsolete/cc-compat.el4
-rw-r--r--lisp/obsolete/cl-compat.el1
-rw-r--r--lisp/obsolete/cl.el9
-rw-r--r--lisp/obsolete/crisp.el22
-rw-r--r--lisp/obsolete/cust-print.el10
-rw-r--r--lisp/obsolete/eieio-compat.el277
-rw-r--r--lisp/obsolete/eudcb-ph.el4
-rw-r--r--lisp/obsolete/fast-lock.el35
-rw-r--r--lisp/obsolete/iswitchb.el20
-rw-r--r--lisp/obsolete/landmark.el14
-rw-r--r--lisp/obsolete/otodo-mode.el3
-rw-r--r--lisp/obsolete/pgg-parse.el3
-rw-r--r--lisp/obsolete/pgg.el3
-rw-r--r--lisp/obsolete/rcompile.el8
-rw-r--r--lisp/obsolete/rfc2368.el (renamed from lisp/mail/rfc2368.el)1
-rw-r--r--lisp/obsolete/terminal.el7
-rw-r--r--lisp/obsolete/tls.el4
-rw-r--r--lisp/obsolete/tpu-edt.el23
-rw-r--r--lisp/obsolete/tpu-mapper.el54
-rw-r--r--lisp/obsolete/vc-arch.el4
-rw-r--r--lisp/obsolete/vip.el14
-rw-r--r--lisp/org/ob-C.el116
-rw-r--r--lisp/org/ob-J.el189
-rw-r--r--lisp/org/ob-R.el122
-rw-r--r--lisp/org/ob-abc.el90
-rw-r--r--lisp/org/ob-asymptote.el137
-rw-r--r--lisp/org/ob-awk.el13
-rw-r--r--lisp/org/ob-calc.el3
-rw-r--r--lisp/org/ob-clojure.el1
-rw-r--r--lisp/org/ob-comint.el174
-rw-r--r--lisp/org/ob-coq.el80
-rw-r--r--lisp/org/ob-core.el162
-rw-r--r--lisp/org/ob-dot.el3
-rw-r--r--lisp/org/ob-ebnf.el81
-rw-r--r--lisp/org/ob-eshell.el3
-rw-r--r--lisp/org/ob-eval.el87
-rw-r--r--lisp/org/ob-exp.el30
-rw-r--r--lisp/org/ob-forth.el4
-rw-r--r--lisp/org/ob-fortran.el10
-rw-r--r--lisp/org/ob-gnuplot.el26
-rw-r--r--lisp/org/ob-groovy.el3
-rw-r--r--lisp/org/ob-haskell.el11
-rw-r--r--lisp/org/ob-hledger.el69
-rw-r--r--lisp/org/ob-io.el105
-rw-r--r--lisp/org/ob-java.el482
-rw-r--r--lisp/org/ob-js.el4
-rw-r--r--lisp/org/ob-julia.el333
-rw-r--r--lisp/org/ob-latex.el63
-rw-r--r--lisp/org/ob-ledger.el68
-rw-r--r--lisp/org/ob-lilypond.el26
-rw-r--r--lisp/org/ob-lisp.el2
-rw-r--r--lisp/org/ob-lua.el6
-rw-r--r--lisp/org/ob-makefile.el3
-rw-r--r--lisp/org/ob-mscgen.el81
-rw-r--r--lisp/org/ob-ocaml.el6
-rw-r--r--lisp/org/ob-octave.el18
-rw-r--r--lisp/org/ob-perl.el1
-rw-r--r--lisp/org/ob-picolisp.el185
-rw-r--r--lisp/org/ob-plantuml.el15
-rw-r--r--lisp/org/ob-processing.el2
-rw-r--r--lisp/org/ob-python.el69
-rw-r--r--lisp/org/ob-ruby.el2
-rw-r--r--lisp/org/ob-sass.el2
-rw-r--r--lisp/org/ob-scheme.el2
-rw-r--r--lisp/org/ob-screen.el5
-rw-r--r--lisp/org/ob-sed.el12
-rw-r--r--lisp/org/ob-shen.el79
-rw-r--r--lisp/org/ob-sql.el82
-rw-r--r--lisp/org/ob-sqlite.el30
-rw-r--r--lisp/org/ob-stan.el86
-rw-r--r--lisp/org/ob-table.el3
-rw-r--r--lisp/org/ob-tangle.el202
-rw-r--r--lisp/org/ob-vala.el116
-rw-r--r--lisp/org/oc-basic.el789
-rw-r--r--lisp/org/oc-biblatex.el318
-rw-r--r--lisp/org/oc-csl.el631
-rw-r--r--lisp/org/oc-natbib.el193
-rw-r--r--lisp/org/oc.el1650
-rw-r--r--lisp/org/ol-bbdb.el4
-rw-r--r--lisp/org/ol-bibtex.el38
-rw-r--r--lisp/org/ol-doi.el72
-rw-r--r--lisp/org/ol-eshell.el8
-rw-r--r--lisp/org/ol-gnus.el4
-rw-r--r--lisp/org/ol-info.el6
-rw-r--r--lisp/org/ol-man.el86
-rw-r--r--lisp/org/ol-rmail.el2
-rw-r--r--lisp/org/ol-w3m.el105
-rw-r--r--lisp/org/ol.el176
-rw-r--r--lisp/org/org-agenda.el1232
-rw-r--r--lisp/org/org-archive.el2
-rw-r--r--lisp/org/org-attach-git.el33
-rw-r--r--lisp/org/org-attach.el93
-rw-r--r--lisp/org/org-capture.el338
-rw-r--r--lisp/org/org-clock.el166
-rw-r--r--lisp/org/org-colview.el40
-rw-r--r--lisp/org/org-compat.el352
-rw-r--r--lisp/org/org-crypt.el8
-rw-r--r--lisp/org/org-ctags.el6
-rw-r--r--lisp/org/org-datetree.el6
-rw-r--r--lisp/org/org-duration.el6
-rw-r--r--lisp/org/org-element.el268
-rw-r--r--lisp/org/org-entities.el4
-rw-r--r--lisp/org/org-faces.el74
-rw-r--r--lisp/org/org-feed.el2
-rw-r--r--lisp/org/org-footnote.el15
-rw-r--r--lisp/org/org-goto.el71
-rw-r--r--lisp/org/org-habit.el2
-rw-r--r--lisp/org/org-id.el177
-rw-r--r--lisp/org/org-indent.el51
-rw-r--r--lisp/org/org-inlinetask.el26
-rw-r--r--lisp/org/org-keys.el109
-rw-r--r--lisp/org/org-lint.el104
-rw-r--r--lisp/org/org-list.el337
-rw-r--r--lisp/org/org-macro.el135
-rw-r--r--lisp/org/org-macs.el91
-rw-r--r--lisp/org/org-mobile.el2
-rw-r--r--lisp/org/org-mouse.el170
-rw-r--r--lisp/org/org-num.el10
-rw-r--r--lisp/org/org-pcomplete.el7
-rw-r--r--lisp/org/org-plot.el624
-rw-r--r--lisp/org/org-protocol.el73
-rw-r--r--lisp/org/org-refile.el54
-rw-r--r--lisp/org/org-src.el108
-rw-r--r--lisp/org/org-table.el321
-rw-r--r--lisp/org/org-timer.el8
-rw-r--r--lisp/org/org-version.el4
-rw-r--r--lisp/org/org.el1405
-rw-r--r--lisp/org/ox-ascii.el65
-rw-r--r--lisp/org/ox-beamer.el67
-rw-r--r--lisp/org/ox-html.el377
-rw-r--r--lisp/org/ox-icalendar.el27
-rw-r--r--lisp/org/ox-koma-letter.el989
-rw-r--r--lisp/org/ox-latex.el259
-rw-r--r--lisp/org/ox-man.el34
-rw-r--r--lisp/org/ox-md.el53
-rw-r--r--lisp/org/ox-odt.el80
-rw-r--r--lisp/org/ox-org.el19
-rw-r--r--lisp/org/ox-publish.el60
-rw-r--r--lisp/org/ox-texinfo.el113
-rw-r--r--lisp/org/ox.el490
-rw-r--r--lisp/outline.el166
-rw-r--r--lisp/paren.el55
-rw-r--r--lisp/pcmpl-x.el2
-rw-r--r--lisp/pcomplete.el14
-rw-r--r--lisp/pixel-scroll.el411
-rw-r--r--lisp/play/5x5.el21
-rw-r--r--lisp/play/animate.el14
-rw-r--r--lisp/play/cookie1.el6
-rw-r--r--lisp/play/decipher.el6
-rw-r--r--lisp/play/doctor.el11
-rw-r--r--lisp/play/dunnet.el25
-rw-r--r--lisp/play/fortune.el2
-rw-r--r--lisp/play/gamegrid.el2
-rw-r--r--lisp/play/gametree.el2
-rw-r--r--lisp/play/handwrite.el2
-rw-r--r--lisp/play/hanoi.el8
-rw-r--r--lisp/play/life.el4
-rw-r--r--lisp/play/mpuz.el13
-rw-r--r--lisp/play/pong.el15
-rw-r--r--lisp/play/snake.el47
-rw-r--r--lisp/play/solitaire.el27
-rw-r--r--lisp/play/spook.el2
-rw-r--r--lisp/play/tetris.el40
-rw-r--r--lisp/play/zone.el4
-rw-r--r--lisp/plstore.el2
-rw-r--r--lisp/printing.el68
-rw-r--r--lisp/proced.el83
-rw-r--r--lisp/profiler.el21
-rw-r--r--lisp/progmodes/antlr-mode.el7
-rw-r--r--lisp/progmodes/autoconf.el2
-rw-r--r--lisp/progmodes/bat-mode.el2
-rw-r--r--lisp/progmodes/bug-reference.el395
-rw-r--r--lisp/progmodes/cc-align.el8
-rw-r--r--lisp/progmodes/cc-awk.el9
-rw-r--r--lisp/progmodes/cc-bytecomp.el30
-rw-r--r--lisp/progmodes/cc-cmds.el51
-rw-r--r--lisp/progmodes/cc-defs.el84
-rw-r--r--lisp/progmodes/cc-engine.el112
-rw-r--r--lisp/progmodes/cc-fonts.el224
-rw-r--r--lisp/progmodes/cc-guess.el20
-rw-r--r--lisp/progmodes/cc-langs.el17
-rw-r--r--lisp/progmodes/cc-menus.el2
-rw-r--r--lisp/progmodes/cc-mode.el171
-rw-r--r--lisp/progmodes/cc-styles.el14
-rw-r--r--lisp/progmodes/cc-vars.el79
-rw-r--r--lisp/progmodes/cfengine.el9
-rw-r--r--lisp/progmodes/cl-font-lock.el1
-rw-r--r--lisp/progmodes/cmacexp.el2
-rw-r--r--lisp/progmodes/compile.el49
-rw-r--r--lisp/progmodes/cperl-mode.el1265
-rw-r--r--lisp/progmodes/cpp.el13
-rw-r--r--lisp/progmodes/dcl-mode.el4
-rw-r--r--lisp/progmodes/ebnf-abn.el3
-rw-r--r--lisp/progmodes/ebnf-dtd.el10
-rw-r--r--lisp/progmodes/ebnf-ebx.el2
-rw-r--r--lisp/progmodes/ebnf-yac.el2
-rw-r--r--lisp/progmodes/ebnf2ps.el12
-rw-r--r--lisp/progmodes/ebrowse.el48
-rw-r--r--lisp/progmodes/elisp-mode.el429
-rw-r--r--lisp/progmodes/erts-mode.el225
-rw-r--r--lisp/progmodes/etags.el98
-rw-r--r--lisp/progmodes/f90.el28
-rw-r--r--lisp/progmodes/flymake-cc.el41
-rw-r--r--lisp/progmodes/flymake-proc.el21
-rw-r--r--lisp/progmodes/flymake.el745
-rw-r--r--lisp/progmodes/fortran.el2
-rw-r--r--lisp/progmodes/gdb-mi.el32
-rw-r--r--lisp/progmodes/grep.el16
-rw-r--r--lisp/progmodes/gud.el57
-rw-r--r--lisp/progmodes/hideif.el48
-rw-r--r--lisp/progmodes/hideshow.el2
-rw-r--r--lisp/progmodes/idlw-complete-structtag.el4
-rw-r--r--lisp/progmodes/idlw-help.el27
-rw-r--r--lisp/progmodes/idlw-shell.el62
-rw-r--r--lisp/progmodes/idlw-toolbar.el2
-rw-r--r--lisp/progmodes/idlwave.el36
-rw-r--r--lisp/progmodes/js.el1195
-rw-r--r--lisp/progmodes/ld-script.el4
-rw-r--r--lisp/progmodes/octave.el12
-rw-r--r--lisp/progmodes/opascal.el24
-rw-r--r--lisp/progmodes/pascal.el4
-rw-r--r--lisp/progmodes/perl-mode.el12
-rw-r--r--lisp/progmodes/prog-mode.el71
-rw-r--r--lisp/progmodes/project.el362
-rw-r--r--lisp/progmodes/prolog.el28
-rw-r--r--lisp/progmodes/ps-mode.el2
-rw-r--r--lisp/progmodes/python.el391
-rw-r--r--lisp/progmodes/ruby-mode.el19
-rw-r--r--lisp/progmodes/scheme.el1
-rw-r--r--lisp/progmodes/sh-script.el20
-rw-r--r--lisp/progmodes/sql.el81
-rw-r--r--lisp/progmodes/tcl.el2
-rw-r--r--lisp/progmodes/verilog-mode.el280
-rw-r--r--lisp/progmodes/vhdl-mode.el162
-rw-r--r--lisp/progmodes/which-func.el13
-rw-r--r--lisp/progmodes/xref.el723
-rw-r--r--lisp/progmodes/xscheme.el11
-rw-r--r--lisp/ps-def.el2
-rw-r--r--lisp/ps-mule.el4
-rw-r--r--lisp/ps-print.el164
-rw-r--r--lisp/ps-samp.el2
-rw-r--r--lisp/recentf.el58
-rw-r--r--lisp/rect.el4
-rw-r--r--lisp/register.el9
-rw-r--r--lisp/registry.el4
-rw-r--r--lisp/repeat.el166
-rw-r--r--lisp/replace.el85
-rw-r--r--lisp/rfn-eshadow.el2
-rw-r--r--lisp/rot13.el32
-rw-r--r--lisp/rtree.el2
-rw-r--r--lisp/ruler-mode.el2
-rw-r--r--lisp/saveplace.el23
-rw-r--r--lisp/select.el52
-rw-r--r--lisp/server.el178
-rw-r--r--lisp/ses.el77
-rw-r--r--lisp/shadowfile.el72
-rw-r--r--lisp/shell.el20
-rw-r--r--lisp/simple.el326
-rw-r--r--lisp/skeleton.el3
-rw-r--r--lisp/so-long.el73
-rw-r--r--lisp/sort.el17
-rw-r--r--lisp/speedbar.el32
-rw-r--r--lisp/sqlite-mode.el216
-rw-r--r--lisp/sqlite.el43
-rw-r--r--lisp/startup.el139
-rw-r--r--lisp/strokes.el37
-rw-r--r--lisp/subr.el414
-rw-r--r--lisp/svg.el2
-rw-r--r--lisp/t-mouse.el2
-rw-r--r--lisp/tab-bar.el885
-rw-r--r--lisp/tab-line.el202
-rw-r--r--lisp/tar-mode.el12
-rw-r--r--lisp/tempo.el34
-rw-r--r--lisp/term.el484
-rw-r--r--lisp/term/haiku-win.el139
-rw-r--r--lisp/term/ns-win.el12
-rw-r--r--lisp/term/pgtk-win.el504
-rw-r--r--lisp/term/st.el3
-rw-r--r--lisp/term/sun.el4
-rw-r--r--lisp/term/w32-win.el10
-rw-r--r--lisp/term/x-win.el2
-rw-r--r--lisp/term/xterm.el44
-rw-r--r--lisp/textmodes/artist.el9
-rw-r--r--lisp/textmodes/bib-mode.el2
-rw-r--r--lisp/textmodes/bibtex.el37
-rw-r--r--lisp/textmodes/conf-mode.el14
-rw-r--r--lisp/textmodes/css-mode.el63
-rw-r--r--lisp/textmodes/enriched.el3
-rw-r--r--lisp/textmodes/etc-authors-mode.el133
-rw-r--r--lisp/textmodes/fill.el18
-rw-r--r--lisp/textmodes/flyspell.el72
-rw-r--r--lisp/textmodes/glyphless-mode.el68
-rw-r--r--lisp/textmodes/ispell.el149
-rw-r--r--lisp/textmodes/makeinfo.el7
-rw-r--r--lisp/textmodes/mhtml-mode.el2
-rw-r--r--lisp/textmodes/page-ext.el2
-rw-r--r--lisp/textmodes/picture.el10
-rw-r--r--lisp/textmodes/pixel-fill.el240
-rw-r--r--lisp/textmodes/refbib.el2
-rw-r--r--lisp/textmodes/refill.el2
-rw-r--r--lisp/textmodes/reftex-cite.el12
-rw-r--r--lisp/textmodes/reftex-dcr.el21
-rw-r--r--lisp/textmodes/reftex-global.el12
-rw-r--r--lisp/textmodes/reftex-index.el20
-rw-r--r--lisp/textmodes/reftex-parse.el18
-rw-r--r--lisp/textmodes/reftex-ref.el8
-rw-r--r--lisp/textmodes/reftex-toc.el6
-rw-r--r--lisp/textmodes/reftex-vars.el60
-rw-r--r--lisp/textmodes/reftex.el7
-rw-r--r--lisp/textmodes/rst.el8
-rw-r--r--lisp/textmodes/sgml-mode.el52
-rw-r--r--lisp/textmodes/table.el129
-rw-r--r--lisp/textmodes/tex-mode.el110
-rw-r--r--lisp/textmodes/texinfmt.el24
-rw-r--r--lisp/textmodes/texinfo.el78
-rw-r--r--lisp/textmodes/texnfo-upd.el8
-rw-r--r--lisp/textmodes/text-mode.el25
-rw-r--r--lisp/textmodes/tildify.el4
-rw-r--r--lisp/thingatpt.el97
-rw-r--r--lisp/thumbs.el22
-rw-r--r--lisp/time-stamp.el205
-rw-r--r--lisp/time.el16
-rw-r--r--lisp/timezone.el14
-rw-r--r--lisp/tool-bar.el2
-rw-r--r--lisp/tooltip.el7
-rw-r--r--lisp/transient.el578
-rw-r--r--lisp/tree-widget.el4
-rw-r--r--lisp/tutorial.el8
-rw-r--r--lisp/url/url-auth.el5
-rw-r--r--lisp/url/url-cache.el4
-rw-r--r--lisp/url/url-cid.el2
-rw-r--r--lisp/url/url-dired.el2
-rw-r--r--lisp/url/url-expand.el2
-rw-r--r--lisp/url/url-gw.el2
-rw-r--r--lisp/url/url-handlers.el1
-rw-r--r--lisp/url/url-http.el100
-rw-r--r--lisp/url/url-imap.el4
-rw-r--r--lisp/url/url-ldap.el2
-rw-r--r--lisp/url/url-misc.el2
-rw-r--r--lisp/url/url-news.el2
-rw-r--r--lisp/url/url-privacy.el3
-rw-r--r--lisp/url/url-proxy.el2
-rw-r--r--lisp/url/url-tramp.el10
-rw-r--r--lisp/url/url-util.el2
-rw-r--r--lisp/url/url-vars.el5
-rw-r--r--lisp/userlock.el83
-rw-r--r--lisp/vc/add-log.el3
-rw-r--r--lisp/vc/compare-w.el4
-rw-r--r--lisp/vc/cvs-status.el27
-rw-r--r--lisp/vc/diff-mode.el157
-rw-r--r--lisp/vc/diff.el18
-rw-r--r--lisp/vc/ediff-diff.el39
-rw-r--r--lisp/vc/ediff-help.el10
-rw-r--r--lisp/vc/ediff-init.el248
-rw-r--r--lisp/vc/ediff-merg.el8
-rw-r--r--lisp/vc/ediff-mult.el82
-rw-r--r--lisp/vc/ediff-ptch.el50
-rw-r--r--lisp/vc/ediff-util.el138
-rw-r--r--lisp/vc/ediff-vers.el4
-rw-r--r--lisp/vc/ediff-wind.el58
-rw-r--r--lisp/vc/ediff.el34
-rw-r--r--lisp/vc/emerge.el133
-rw-r--r--lisp/vc/log-edit.el34
-rw-r--r--lisp/vc/log-view.el55
-rw-r--r--lisp/vc/pcvs-defs.el154
-rw-r--r--lisp/vc/pcvs.el164
-rw-r--r--lisp/vc/smerge-mode.el47
-rw-r--r--lisp/vc/vc-annotate.el8
-rw-r--r--lisp/vc/vc-bzr.el5
-rw-r--r--lisp/vc/vc-cvs.el21
-rw-r--r--lisp/vc/vc-dav.el15
-rw-r--r--lisp/vc/vc-dir.el48
-rw-r--r--lisp/vc/vc-dispatcher.el32
-rw-r--r--lisp/vc/vc-git.el108
-rw-r--r--lisp/vc/vc-hg.el34
-rw-r--r--lisp/vc/vc-hooks.el13
-rw-r--r--lisp/vc/vc-rcs.el73
-rw-r--r--lisp/vc/vc-sccs.el16
-rw-r--r--lisp/vc/vc-src.el11
-rw-r--r--lisp/vc/vc-svn.el2
-rw-r--r--lisp/vc/vc.el133
-rw-r--r--lisp/vcursor.el6
-rw-r--r--lisp/version.el4
-rw-r--r--lisp/view.el124
-rw-r--r--lisp/vt-control.el2
-rw-r--r--lisp/wdired.el4
-rw-r--r--lisp/whitespace.el132
-rw-r--r--lisp/wid-edit.el19
-rw-r--r--lisp/widget.el8
-rw-r--r--lisp/windmove.el20
-rw-r--r--lisp/window.el271
-rw-r--r--lisp/winner.el3
-rw-r--r--lisp/woman.el4
-rw-r--r--lisp/x-dnd.el2
-rw-r--r--lisp/xdg.el99
-rw-r--r--lisp/xml.el12
-rw-r--r--lisp/xt-mouse.el8
-rw-r--r--lisp/xwidget.el687
-rw-r--r--lisp/yank-media.el194
-rw-r--r--lwlib/xlwmenu.c36
-rw-r--r--lwlib/xlwmenu.h2
-rw-r--r--lwlib/xlwmenuP.h1
-rw-r--r--m4/close-stream.m411
-rw-r--r--m4/dirent_h.m445
-rw-r--r--m4/environ.m45
-rw-r--r--m4/explicit_bzero.m42
-rw-r--r--m4/extern-inline.m47
-rw-r--r--m4/fcntl_h.m439
-rw-r--r--m4/free.m47
-rw-r--r--m4/gettimeofday.m46
-rw-r--r--m4/glibc21.m434
-rw-r--r--m4/gnulib-common.m4269
-rw-r--r--m4/gnulib-comp.m4164
-rw-r--r--m4/gsettings.m488
-rw-r--r--m4/inttypes.m431
-rw-r--r--m4/largefile.m428
-rw-r--r--m4/limits-h.m43
-rw-r--r--m4/malloc.m4174
-rw-r--r--m4/malloca.m414
-rw-r--r--m4/manywarnings.m412
-rw-r--r--m4/memmem.m45
-rw-r--r--m4/mempcpy.m44
-rw-r--r--m4/memrchr.m44
-rw-r--r--m4/mktime.m44
-rw-r--r--m4/nproc.m454
-rw-r--r--m4/pselect.m44
-rw-r--r--m4/pthread_sigmask.m410
-rw-r--r--m4/rawmemchr.m44
-rw-r--r--m4/realloc.m463
-rw-r--r--m4/regex.m444
-rw-r--r--m4/sigdescr_np.m44
-rw-r--r--m4/signal_h.m433
-rw-r--r--m4/stdalign.m44
-rw-r--r--m4/stddef_h.m423
-rw-r--r--m4/stdint.m46
-rw-r--r--m4/stdio_h.m4168
-rw-r--r--m4/stdlib_h.m4122
-rw-r--r--m4/stpcpy.m44
-rw-r--r--m4/string_h.m4126
-rw-r--r--m4/strnlen.m44
-rw-r--r--m4/strtoll.m436
-rw-r--r--m4/sys_random_h.m425
-rw-r--r--m4/sys_select_h.m429
-rw-r--r--m4/sys_socket_h.m453
-rw-r--r--m4/sys_stat_h.m465
-rw-r--r--m4/sys_time_h.m434
-rw-r--r--m4/sys_types_h.m416
-rw-r--r--m4/time_h.m462
-rw-r--r--m4/time_r.m42
-rw-r--r--m4/time_rz.m42
-rw-r--r--m4/timegm.m44
-rw-r--r--m4/timer_time.m411
-rw-r--r--m4/unistd_h.m4194
-rw-r--r--m4/unlocked-io.m47
-rw-r--r--m4/year2038.m4124
-rwxr-xr-xmake-dist17
-rw-r--r--msdos/autogen/config.in2
-rw-r--r--msdos/langinfo.h20
-rw-r--r--msdos/sed1v2.inp24
-rw-r--r--msdos/sed2v2.inp3
-rw-r--r--msdos/sed3v2.inp1
-rw-r--r--msdos/sedlibmk.inp63
-rw-r--r--nextstep/templates/Info.plist.in2
-rw-r--r--nt/ChangeLog.12
-rw-r--r--nt/INSTALL17
-rw-r--r--nt/INSTALL.W641
-rw-r--r--nt/Makefile.in1
-rw-r--r--nt/README.W322
-rw-r--r--nt/addpm.c4
-rw-r--r--nt/cmdproxy.c3
-rw-r--r--nt/ddeclient.c3
-rw-r--r--nt/gnulib-cfg.mk5
-rw-r--r--nt/preprep.c3
-rw-r--r--nt/runemacs.c3
-rw-r--r--oldXMenu/Activate.c20
-rw-r--r--oldXMenu/AddPane.c22
-rw-r--r--oldXMenu/AddSel.c22
-rw-r--r--oldXMenu/ChgPane.c20
-rw-r--r--oldXMenu/ChgSel.c20
-rw-r--r--oldXMenu/Create.c20
-rw-r--r--oldXMenu/DelPane.c20
-rw-r--r--oldXMenu/DelSel.c20
-rw-r--r--oldXMenu/Destroy.c20
-rw-r--r--oldXMenu/Error.c20
-rw-r--r--oldXMenu/EvHand.c20
-rw-r--r--oldXMenu/FindPane.c20
-rw-r--r--oldXMenu/FindSel.c20
-rw-r--r--oldXMenu/InsPane.c20
-rw-r--r--oldXMenu/InsSel.c20
-rw-r--r--oldXMenu/Internal.c20
-rw-r--r--oldXMenu/Locate.c20
-rw-r--r--oldXMenu/Post.c20
-rw-r--r--oldXMenu/Recomp.c20
-rw-r--r--oldXMenu/SetAEQ.c20
-rw-r--r--oldXMenu/SetFrz.c20
-rw-r--r--oldXMenu/SetPane.c20
-rw-r--r--oldXMenu/SetSel.c20
-rw-r--r--oldXMenu/XCrAssoc.c20
-rw-r--r--oldXMenu/XDelAssoc.c20
-rw-r--r--oldXMenu/XDestAssoc.c20
-rw-r--r--oldXMenu/XLookAssoc.c20
-rw-r--r--oldXMenu/XMakeAssoc.c20
-rw-r--r--oldXMenu/XMenu.h20
-rw-r--r--oldXMenu/XMenuInt.h20
-rw-r--r--src/.gdbinit8
-rw-r--r--src/ChangeLog.114
-rw-r--r--src/Makefile.in149
-rw-r--r--src/alloc.c77
-rw-r--r--src/atimer.c47
-rw-r--r--src/bidi.c29
-rw-r--r--src/bignum.c9
-rw-r--r--src/buffer.c78
-rw-r--r--src/buffer.h11
-rw-r--r--src/callint.c33
-rw-r--r--src/callproc.c220
-rw-r--r--src/casefiddle.c57
-rw-r--r--src/character.h2
-rw-r--r--src/charset.c2
-rw-r--r--src/charset.h1
-rw-r--r--src/coding.c21
-rw-r--r--src/comp.c434
-rw-r--r--src/comp.h10
-rw-r--r--src/composite.c27
-rw-r--r--src/composite.h4
-rw-r--r--src/conf_post.h1
-rw-r--r--src/data.c16
-rw-r--r--src/dispextern.h73
-rw-r--r--src/dispnew.c43
-rw-r--r--src/dosfns.c4
-rw-r--r--src/dynlib.c12
-rw-r--r--src/dynlib.h1
-rw-r--r--src/editfns.c3
-rw-r--r--src/emacs-module.h.in13
-rw-r--r--src/emacs.c139
-rw-r--r--src/emacsgtkfixed.c116
-rw-r--r--src/emacsgtkfixed.h9
-rw-r--r--src/eval.c120
-rw-r--r--src/fileio.c18
-rw-r--r--src/filelock.c2
-rw-r--r--src/floatfns.c15
-rw-r--r--src/fns.c21
-rw-r--r--src/font.c181
-rw-r--r--src/font.h13
-rw-r--r--src/frame.c67
-rw-r--r--src/frame.h29
-rw-r--r--src/fringe.c23
-rw-r--r--src/ftcrfont.c81
-rw-r--r--src/ftfont.c6
-rw-r--r--src/ftfont.h7
-rw-r--r--src/gtkutil.c721
-rw-r--r--src/gtkutil.h29
-rw-r--r--src/haiku.c286
-rw-r--r--src/haiku_draw_support.cc488
-rw-r--r--src/haiku_font_support.cc596
-rw-r--r--src/haiku_io.c207
-rw-r--r--src/haiku_select.cc229
-rw-r--r--src/haiku_support.cc2928
-rw-r--r--src/haiku_support.h869
-rw-r--r--src/haikufns.c2449
-rw-r--r--src/haikufont.c1072
-rw-r--r--src/haikugui.h106
-rw-r--r--src/haikuimage.c109
-rw-r--r--src/haikumenu.c656
-rw-r--r--src/haikuselect.c180
-rw-r--r--src/haikuselect.h74
-rw-r--r--src/haikuterm.c3647
-rw-r--r--src/haikuterm.h296
-rw-r--r--src/image.c963
-rw-r--r--src/indent.c1
-rw-r--r--src/intervals.c20
-rw-r--r--src/keyboard.c402
-rw-r--r--src/keyboard.h2
-rw-r--r--src/keymap.c336
-rw-r--r--src/lisp.h147
-rw-r--r--src/lread.c222
-rw-r--r--src/macfont.m44
-rw-r--r--src/menu.c54
-rw-r--r--src/menu.h6
-rw-r--r--src/minibuf.c129
-rw-r--r--src/module-env-28.h4
-rw-r--r--src/module-env-29.h3
-rw-r--r--src/msdos.c104
-rw-r--r--src/msdos.h2
-rw-r--r--src/nsfns.m125
-rw-r--r--src/nsfont.m1215
-rw-r--r--src/nsmenu.m120
-rw-r--r--src/nsselect.m84
-rw-r--r--src/nsterm.h25
-rw-r--r--src/nsterm.m701
-rw-r--r--src/pdumper.c105
-rw-r--r--src/pdumper.h5
-rw-r--r--src/pgtkfns.c4144
-rw-r--r--src/pgtkgui.h119
-rw-r--r--src/pgtkim.c311
-rw-r--r--src/pgtkmenu.c1159
-rw-r--r--src/pgtkselect.c632
-rw-r--r--src/pgtkselect.h33
-rw-r--r--src/pgtkterm.c7115
-rw-r--r--src/pgtkterm.h664
-rw-r--r--src/print.c46
-rw-r--r--src/process.c114
-rw-r--r--src/regex-emacs.c4
-rw-r--r--src/search.c95
-rw-r--r--src/sound.c24
-rw-r--r--src/sqlite.c753
-rw-r--r--src/syntax.c10
-rw-r--r--src/sysdep.c34
-rw-r--r--src/sysstdio.h2
-rw-r--r--src/systhread.h13
-rw-r--r--src/systime.h3
-rw-r--r--src/term.c48
-rw-r--r--src/termchar.h4
-rw-r--r--src/termhooks.h45
-rw-r--r--src/terminal.c4
-rw-r--r--src/thread.h1
-rw-r--r--src/timefns.c78
-rw-r--r--src/unexcw.c6
-rw-r--r--src/verbose.mk.in8
-rw-r--r--src/vm-limit.c2
-rw-r--r--src/w16select.c2
-rw-r--r--src/w32.c100
-rw-r--r--src/w32.h10
-rw-r--r--src/w32fns.c158
-rw-r--r--src/w32font.c41
-rw-r--r--src/w32heap.c42
-rw-r--r--src/w32inevt.c19
-rw-r--r--src/w32proc.c31
-rw-r--r--src/w32term.c186
-rw-r--r--src/window.c68
-rw-r--r--src/window.h2
-rw-r--r--src/xdisp.c1094
-rw-r--r--src/xfaces.c129
-rw-r--r--src/xfns.c104
-rw-r--r--src/xmenu.c12
-rw-r--r--src/xsettings.c54
-rw-r--r--src/xsettings.h15
-rw-r--r--src/xterm.c1836
-rw-r--r--src/xterm.h56
-rw-r--r--src/xwidget.c2260
-rw-r--r--src/xwidget.h46
-rw-r--r--test/Makefile.in38
-rw-r--r--test/README12
-rw-r--r--test/data/image/black.gifbin0 -> 143 bytes
-rw-r--r--test/data/image/black.webpbin0 -> 37780 bytes
-rw-r--r--test/infra/Dockerfile.emba46
-rw-r--r--test/infra/Makefile.in100
-rw-r--r--test/infra/gitlab-ci.yml209
-rw-r--r--test/infra/test-jobs.yml545
-rw-r--r--test/lisp/abbrev-tests.el82
-rw-r--r--test/lisp/ansi-color-tests.el155
-rw-r--r--test/lisp/arc-mode-tests.el2
-rw-r--r--test/lisp/auth-source-pass-tests.el14
-rw-r--r--test/lisp/auth-source-tests.el212
-rw-r--r--test/lisp/autoinsert-tests.el19
-rw-r--r--test/lisp/autorevert-tests.el836
-rw-r--r--test/lisp/bookmark-tests.el18
-rw-r--r--test/lisp/buff-menu-tests.el21
-rw-r--r--test/lisp/button-tests.el1
-rw-r--r--test/lisp/calc/calc-tests.el10
-rw-r--r--test/lisp/calculator-tests.el2
-rw-r--r--test/lisp/calendar/cal-french-tests.el1
-rw-r--r--test/lisp/calendar/icalendar-tests.el151
-rw-r--r--test/lisp/calendar/solar-tests.el4
-rw-r--r--test/lisp/calendar/time-date-tests.el24
-rw-r--r--test/lisp/calendar/todo-mode-tests.el41
-rw-r--r--test/lisp/cedet/semantic-utest-c.el2
-rw-r--r--test/lisp/cedet/semantic-utest-ia.el2
-rw-r--r--test/lisp/cedet/semantic-utest.el7
-rw-r--r--test/lisp/cedet/semantic/bovine/gcc-tests.el8
-rw-r--r--test/lisp/cedet/semantic/fw-tests.el2
-rw-r--r--test/lisp/cedet/srecode/fields-tests.el23
-rw-r--r--test/lisp/comint-tests.el9
-rw-r--r--test/lisp/cus-edit-tests.el2
-rw-r--r--test/lisp/custom-tests.el38
-rw-r--r--test/lisp/dabbrev-tests.el15
-rw-r--r--test/lisp/descr-text-tests.el2
-rw-r--r--test/lisp/dired-aux-tests.el64
-rw-r--r--test/lisp/dired-resources/insert-directory/test_dir/bar0
-rw-r--r--test/lisp/dired-resources/insert-directory/test_dir/foo0
-rw-r--r--test/lisp/dired-resources/insert-directory/test_dir_other/bar0
-rw-r--r--test/lisp/dired-resources/insert-directory/test_dir_other/foo0
-rw-r--r--test/lisp/dired-tests.el441
-rw-r--r--test/lisp/dired-x-tests.el42
-rw-r--r--test/lisp/edmacro-tests.el47
-rw-r--r--test/lisp/electric-tests.el104
-rw-r--r--test/lisp/emacs-lisp/backtrace-tests.el2
-rw-r--r--test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-ignore-substitutions.el17
-rw-r--r--test/lisp/emacs-lisp/bytecomp-tests.el357
-rw-r--r--test/lisp/emacs-lisp/cconv-tests.el158
-rw-r--r--test/lisp/emacs-lisp/check-declare-tests.el96
-rw-r--r--test/lisp/emacs-lisp/checkdoc-tests.el96
-rw-r--r--test/lisp/emacs-lisp/cl-generic-tests.el9
-rw-r--r--test/lisp/emacs-lisp/cl-lib-tests.el28
-rw-r--r--test/lisp/emacs-lisp/cl-macs-tests.el23
-rw-r--r--test/lisp/emacs-lisp/derived-tests.el4
-rw-r--r--test/lisp/emacs-lisp/edebug-tests.el55
-rw-r--r--test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el302
-rw-r--r--test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el6
-rw-r--r--test/lisp/emacs-lisp/eieio-tests/eieio-tests.el370
-rw-r--r--test/lisp/emacs-lisp/ert-tests.el155
-rw-r--r--test/lisp/emacs-lisp/ert-x-tests.el108
-rw-r--r--test/lisp/emacs-lisp/faceup-resources/faceup-test-this-file-directory.el2
-rw-r--r--test/lisp/emacs-lisp/find-func-tests.el2
-rw-r--r--test/lisp/emacs-lisp/generator-tests.el13
-rw-r--r--test/lisp/emacs-lisp/gv-tests.el19
-rw-r--r--test/lisp/emacs-lisp/let-alist-tests.el4
-rw-r--r--test/lisp/emacs-lisp/lisp-mnt-tests.el8
-rw-r--r--test/lisp/emacs-lisp/lisp-tests.el5
-rw-r--r--test/lisp/emacs-lisp/map-tests.el43
-rw-r--r--test/lisp/emacs-lisp/memory-report-tests.el10
-rw-r--r--test/lisp/emacs-lisp/multisession-tests.el201
-rw-r--r--test/lisp/emacs-lisp/nadvice-tests.el2
-rw-r--r--test/lisp/emacs-lisp/package-resources/key.pub31
-rw-r--r--test/lisp/emacs-lisp/package-resources/key.sec46
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin-aux.el12
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin.el21
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin-aux.el16
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin.el30
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-problem-package-1.0/macro-aux.el2
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-problem-package-1.0/macro-problem.el4
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-problem-package-2.0/macro-aux.el4
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-problem-package-2.0/macro-problem.el8
-rw-r--r--test/lisp/emacs-lisp/package-resources/newer-versions/simple-single-1.4.el6
-rw-r--r--test/lisp/emacs-lisp/package-resources/signed/archive-contents.sigbin181 -> 95 bytes
-rw-r--r--test/lisp/emacs-lisp/package-resources/signed/signed-bad-1.0.el6
-rw-r--r--test/lisp/emacs-lisp/package-resources/signed/signed-good-1.0.el6
-rw-r--r--test/lisp/emacs-lisp/package-resources/signed/signed-good-1.0.el.sigbin181 -> 95 bytes
-rw-r--r--test/lisp/emacs-lisp/package-resources/simple-depend-1.0.el2
-rw-r--r--test/lisp/emacs-lisp/package-resources/simple-single-1.3.el6
-rw-r--r--test/lisp/emacs-lisp/package-resources/simple-two-depend-1.1.el2
-rw-r--r--test/lisp/emacs-lisp/package-tests.el178
-rw-r--r--test/lisp/emacs-lisp/pp-resources/code-formats.erts124
-rw-r--r--test/lisp/emacs-lisp/pp-tests.el4
-rw-r--r--test/lisp/emacs-lisp/regexp-opt-tests.el2
-rw-r--r--test/lisp/emacs-lisp/ring-tests.el2
-rw-r--r--test/lisp/emacs-lisp/rx-tests.el4
-rw-r--r--test/lisp/emacs-lisp/seq-tests.el49
-rw-r--r--test/lisp/emacs-lisp/shortdoc-tests.el4
-rw-r--r--test/lisp/emacs-lisp/subr-x-tests.el120
-rw-r--r--test/lisp/emacs-lisp/tabulated-list-tests.el (renamed from test/lisp/emacs-lisp/tabulated-list-test.el)42
-rw-r--r--test/lisp/emacs-lisp/testcover-resources/testcases.el12
-rw-r--r--test/lisp/emacs-lisp/testcover-tests.el108
-rw-r--r--test/lisp/emacs-lisp/timer-tests.el3
-rw-r--r--test/lisp/emacs-lisp/unsafep-tests.el2
-rw-r--r--test/lisp/emulation/viper-tests.el80
-rw-r--r--test/lisp/epg-tests.el77
-rw-r--r--test/lisp/erc/erc-tests.el199
-rw-r--r--test/lisp/erc/erc-track-tests.el2
-rw-r--r--test/lisp/eshell/em-hist-tests.el17
-rw-r--r--test/lisp/eshell/em-ls-tests.el38
-rw-r--r--test/lisp/eshell/eshell-tests.el34
-rw-r--r--test/lisp/faces-resources/faces-test-dark-theme.el2
-rw-r--r--test/lisp/faces-resources/faces-test-light-theme.el2
-rw-r--r--test/lisp/faces-tests.el2
-rw-r--r--test/lisp/ffap-tests.el31
-rw-r--r--test/lisp/filenotify-tests.el33
-rw-r--r--test/lisp/files-tests.el490
-rw-r--r--test/lisp/format-spec-tests.el4
-rw-r--r--test/lisp/gnus/gnus-group-tests.el52
-rw-r--r--test/lisp/gnus/gnus-icalendar-tests.el2
-rw-r--r--test/lisp/gnus/gnus-search-tests.el2
-rw-r--r--test/lisp/gnus/gnus-util-tests.el2
-rw-r--r--test/lisp/gnus/message-tests.el2
-rw-r--r--test/lisp/help-fns-tests.el4
-rw-r--r--test/lisp/help-tests.el138
-rw-r--r--test/lisp/hi-lock-tests.el15
-rw-r--r--test/lisp/htmlfontify-tests.el2
-rw-r--r--test/lisp/ibuffer-tests.el2
-rw-r--r--test/lisp/image-dired-tests.el37
-rw-r--r--test/lisp/image-tests.el64
-rw-r--r--test/lisp/image/exif-tests.el21
-rw-r--r--test/lisp/info-tests.el39
-rw-r--r--test/lisp/info-xref-tests.el82
-rw-r--r--test/lisp/international/ccl-tests.el2
-rw-r--r--test/lisp/international/mule-tests.el2
-rw-r--r--test/lisp/international/ucs-normalize-tests.el148
-rw-r--r--test/lisp/jit-lock-tests.el2
-rw-r--r--test/lisp/kmacro-tests.el2
-rw-r--r--test/lisp/ls-lisp-tests.el36
-rw-r--r--test/lisp/mail/mail-utils-tests.el3
-rw-r--r--test/lisp/mail/rfc6068-tests.el52
-rw-r--r--test/lisp/mail/rmail-tests.el2
-rw-r--r--test/lisp/mail/rmailmm-tests.el2
-rw-r--r--test/lisp/mail/uudecode-tests.el30
-rw-r--r--test/lisp/mh-e/mh-limit-tests.el35
-rw-r--r--test/lisp/mh-e/mh-thread-tests.el131
-rw-r--r--test/lisp/mh-e/mh-utils-tests.el549
-rw-r--r--test/lisp/mh-e/mh-xface-tests.el50
-rwxr-xr-xtest/lisp/mh-e/test-all-mh-variants.sh102
-rw-r--r--test/lisp/net/browse-url-tests.el14
-rw-r--r--test/lisp/net/dbus-tests.el13
-rw-r--r--test/lisp/net/netrc-tests.el2
-rw-r--r--test/lisp/net/network-stream-tests.el2
-rw-r--r--test/lisp/net/puny-tests.el7
-rw-r--r--test/lisp/net/shr-tests.el2
-rw-r--r--test/lisp/net/socks-tests.el6
-rw-r--r--test/lisp/net/tramp-archive-tests.el91
-rw-r--r--test/lisp/net/tramp-tests.el961
-rw-r--r--test/lisp/newcomment-tests.el39
-rw-r--r--test/lisp/obsolete/cl-tests.el9
-rw-r--r--test/lisp/obsolete/rfc2368-tests.el (renamed from test/lisp/mail/rfc2368-tests.el)0
-rw-r--r--test/lisp/org/org-tests.el2
-rw-r--r--test/lisp/paren-tests.el31
-rw-r--r--test/lisp/play/cookie1-tests.el2
-rw-r--r--test/lisp/progmodes/bug-reference-tests.el128
-rw-r--r--test/lisp/progmodes/compile-tests.el3
-rw-r--r--test/lisp/progmodes/cperl-mode-resources/grammar.pl14
-rw-r--r--test/lisp/progmodes/cperl-mode-resources/here-docs.pl2
-rw-r--r--test/lisp/progmodes/cperl-mode-tests.el473
-rw-r--r--test/lisp/progmodes/elisp-mode-resources/elisp-indents.erts88
-rw-r--r--test/lisp/progmodes/elisp-mode-resources/flet.erts353
-rw-r--r--test/lisp/progmodes/elisp-mode-resources/simple-shorthand-test.el40
-rw-r--r--test/lisp/progmodes/elisp-mode-tests.el361
-rw-r--r--test/lisp/progmodes/etags-tests.el33
-rw-r--r--test/lisp/progmodes/flymake-resources/another-problematic-file.c5
-rw-r--r--test/lisp/progmodes/flymake-resources/some-problems.h2
-rw-r--r--test/lisp/progmodes/flymake-tests.el46
-rw-r--r--test/lisp/progmodes/gdb-mi-tests.el4
-rw-r--r--test/lisp/progmodes/opascal-tests.el2
-rw-r--r--test/lisp/progmodes/pascal-tests.el4
-rw-r--r--test/lisp/progmodes/perl-mode-tests.el2
-rw-r--r--test/lisp/progmodes/project-tests.el33
-rw-r--r--test/lisp/progmodes/python-tests.el71
-rw-r--r--test/lisp/progmodes/ruby-mode-tests.el29
-rw-r--r--test/lisp/progmodes/sh-script-tests.el51
-rw-r--r--test/lisp/progmodes/sql-tests.el102
-rw-r--r--test/lisp/progmodes/xref-tests.el34
-rw-r--r--test/lisp/ps-print-tests.el2
-rw-r--r--test/lisp/repeat-tests.el145
-rw-r--r--test/lisp/replace-tests.el11
-rw-r--r--test/lisp/saveplace-tests.el69
-rw-r--r--test/lisp/ses-tests.el6
-rw-r--r--test/lisp/shadowfile-tests.el24
-rw-r--r--test/lisp/shell-tests.el2
-rw-r--r--test/lisp/simple-tests.el2
-rw-r--r--test/lisp/so-long-tests/so-long-tests-helpers.el4
-rw-r--r--test/lisp/so-long-tests/so-long-tests.el6
-rw-r--r--test/lisp/so-long-tests/spelling-tests.el30
-rw-r--r--test/lisp/subr-tests.el291
-rw-r--r--test/lisp/tab-bar-tests.el51
-rw-r--r--test/lisp/tar-mode-tests.el5
-rw-r--r--test/lisp/term-tests.el79
-rw-r--r--test/lisp/term/tty-colors-tests.el2
-rw-r--r--test/lisp/textmodes/dns-mode-tests.el2
-rw-r--r--test/lisp/textmodes/fill-tests.el26
-rw-r--r--test/lisp/textmodes/reftex-tests.el101
-rw-r--r--test/lisp/textmodes/texinfo-resources/fill.erts70
-rw-r--r--test/lisp/textmodes/texinfo-tests.el33
-rw-r--r--test/lisp/thingatpt-tests.el22
-rw-r--r--test/lisp/thumbs-tests.el10
-rw-r--r--test/lisp/time-stamp-tests.el46
-rw-r--r--test/lisp/time-tests.el2
-rw-r--r--test/lisp/timezone-tests.el2
-rw-r--r--test/lisp/url/url-auth-tests.el2
-rw-r--r--test/lisp/url/url-handlers-tests.el (renamed from test/lisp/url/url-handlers-test.el)5
-rw-r--r--test/lisp/url/url-parse-tests.el2
-rw-r--r--test/lisp/vc/add-log-tests.el4
-rw-r--r--test/lisp/vc/diff-mode-tests.el57
-rw-r--r--test/lisp/vc/ediff-ptch-tests.el60
-rw-r--r--test/lisp/vc/smerge-mode-tests.el2
-rw-r--r--test/lisp/vc/vc-bzr-tests.el174
-rw-r--r--test/lisp/vc/vc-git-tests.el67
-rw-r--r--test/lisp/vc/vc-tests.el802
-rw-r--r--test/lisp/wdired-tests.el274
-rw-r--r--test/lisp/whitespace-tests.el2
-rw-r--r--test/lisp/xml-tests.el4
-rw-r--r--test/manual/BidiCharacterTest.txt32
-rw-r--r--test/manual/biditest.el2
-rw-r--r--test/manual/cedet/cedet-utests.el4
-rw-r--r--test/manual/cedet/ede-tests.el2
-rw-r--r--test/manual/cedet/semantic-tests.el6
-rw-r--r--test/manual/cedet/tests/test.el32
-rw-r--r--test/manual/etags/el-src/emacs/lisp/progmodes/etags.el2
-rw-r--r--test/manual/image-size-tests.el2
-rw-r--r--test/manual/image-transforms-tests.el2
-rw-r--r--test/manual/redisplay-testsuite.el2
-rw-r--r--test/misc/test-custom-libs.el4
-rw-r--r--test/src/alloc-tests.el2
-rw-r--r--test/src/buffer-tests.el140
-rw-r--r--test/src/casefiddle-tests.el16
-rw-r--r--test/src/character-tests.el2
-rw-r--r--test/src/charset-tests.el4
-rw-r--r--test/src/coding-tests.el2
-rw-r--r--test/src/comp-resources/comp-test-funcs.el13
-rw-r--r--test/src/comp-tests.el108
-rw-r--r--test/src/data-tests.el69
-rw-r--r--test/src/decompress-tests.el2
-rw-r--r--test/src/editfns-tests.el48
-rw-r--r--test/src/emacs-module-resources/mod-test.c5
-rw-r--r--test/src/emacs-module-tests.el31
-rw-r--r--test/src/emacs-tests.el30
-rw-r--r--test/src/eval-tests.el76
-rw-r--r--test/src/fileio-tests.el19
-rw-r--r--test/src/filelock-tests.el31
-rw-r--r--test/src/floatfns-tests.el66
-rw-r--r--test/src/fns-tests.el79
-rw-r--r--test/src/image-tests.el245
-rw-r--r--test/src/indent-tests.el2
-rw-r--r--test/src/inotify-tests.el36
-rw-r--r--test/src/keymap-tests.el105
-rw-r--r--test/src/lcms-tests.el4
-rw-r--r--test/src/lread-tests.el14
-rw-r--r--test/src/marker-tests.el2
-rw-r--r--test/src/minibuf-tests.el6
-rw-r--r--test/src/process-tests.el58
-rw-r--r--test/src/regex-emacs-tests.el28
-rw-r--r--test/src/search-tests.el2
-rw-r--r--test/src/sqlite-tests.el218
-rw-r--r--test/src/syntax-tests.el6
-rw-r--r--test/src/textprop-tests.el2
-rw-r--r--test/src/thread-tests.el8
-rw-r--r--test/src/timefns-tests.el14
-rw-r--r--test/src/undo-tests.el20
-rw-r--r--test/src/xdisp-tests.el71
-rw-r--r--test/src/xfaces-tests.el4
-rw-r--r--test/src/xml-tests.el2
1856 files changed, 223154 insertions, 46300 deletions
diff --git a/.gitignore b/.gitignore
index 7539e152ba4..9743ccca0cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -70,6 +70,7 @@ lib/ieee754.h
lib/inttypes.h
lib/libgnu.a
lib/limits.h
+lib/malloc/*.gl.h
lib/signal.h
lib/std*.h
!lib/std*.in.h
@@ -148,6 +149,7 @@ src/gl-stamp
core
core.*[0-9]
gmon.out
+native-lisp/
oo/
oo-spd/
src/*.map
@@ -162,6 +164,7 @@ test/manual/etags/CTAGS
test/manual/indent/*.new
test/lisp/gnus/mml-sec-resources/random_seed
test/lisp/play/fortune-resources/fortunes.dat
+test/**/*.xml
# ctags, etags.
TAGS
@@ -185,6 +188,7 @@ ID
# Executables.
*.exe
a.out
+lib-src/be-resources
lib-src/blessmail
lib-src/ctags
lib-src/ebrowse
@@ -206,6 +210,7 @@ nextstep/GNUstep/Emacs.base/Resources/Info-gnustep.plist
src/bootstrap-emacs
src/emacs
src/emacs-[0-9]*
+src/Emacs
src/temacs
src/dmpstruct.h
src/*.pdmp
@@ -217,6 +222,8 @@ etc/charsets/*.map
lisp/international/charprop.el
lisp/international/charscript.el
lisp/international/cp51932.el
+lisp/international/emoji-zwj.el
+lisp/international/emoji-labels.el
lisp/international/eucjp-ms.el
lisp/international/uni-*.el
lisp/language/pinyin.el
@@ -315,3 +322,6 @@ lib-src/seccomp-filter.bpf
lib-src/seccomp-filter.pfc
lib-src/seccomp-filter-exec.bpf
lib-src/seccomp-filter-exec.pfc
+
+# gsettings schema
+/etc/*.gschema.valid
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 3138f4184e6..402c17ddb85 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-# GNU Emacs support for the GitLab protocol for CI
+# GNU Emacs support for the GitLab protocol for CI.
# The presence of this file does not imply any FSF/GNU endorsement of
# any particular service that uses that protocol. Also, it is intended for
diff --git a/CONTRIBUTE b/CONTRIBUTE
index 2d70c4916ca..7c3421ed75a 100644
--- a/CONTRIBUTE
+++ b/CONTRIBUTE
@@ -58,7 +58,7 @@ format and whitespace are not munged in transit by the various mail
agents. To send just one such patch without additional remarks, it is
also possible to use a command like
- git send-email --to=bug-gnu-emacs@gnu.org 0001-DESCRIPTION.patch'.
+ git send-email --to=bug-gnu-emacs@gnu.org 0001-DESCRIPTION.patch
However, we prefer the 'git format-patch' method with attachment, as
doing so delivers patches in the correct and easily-recognizable format
@@ -157,6 +157,14 @@ top-level directory. Most tests are in the directory "test/". From
the "test/" directory, run "make <filename>" to run the tests for
<filename>.el(c). See "test/README" for more information.
+If you're making changes that involve the Emacs build system, please
+test 'out-of-tree' builds as well, i.e.:
+
+ mkdir emacs-build
+ cd emacs-build
+ ../path-to-emacs-sources/configure
+ make
+
** Commit messages
Ordinarily, a change you commit should contain a log entry in its
@@ -177,20 +185,26 @@ ChangeLog file, where they can be corrected. It saves time to get
them right the first time, so here are guidelines for formatting them:
- Start with a single unindented summary line explaining the change;
- do not end this line with a period. If that line starts with a
- semicolon and a space "; ", the commit message will be ignored when
- generating the ChangeLog file. Use this for minor commits that do
- not need separate ChangeLog entries, such as changes in etc/NEWS.
+ do not end this line with a period. If possible, try to keep the
+ summary line to 50 characters or fewer; this is for compatibility
+ with certain Git commands that print that line in width-constrained
+ contexts.
+
+ If the summary line starts with a semicolon and a space "; ", the
+ commit message will be ignored when generating the ChangeLog file.
+ Use this for minor commits that do not need separate ChangeLog
+ entries, such as changes in etc/NEWS.
+
+- After the summary line, there should be an empty line.
-- After the summary line, there should be an empty line, then
- unindented ChangeLog entries.
+- Unindented ChangeLog entries normally come next. However, if the
+ commit couldn't be properly summarized in the brief summary line,
+ you can put a paragraph (after the empty line and before the
+ individual ChangeLog entries) that further describes the commit.
- Limit lines in commit messages to 78 characters, unless they consist
of a single word of at most 140 characters; this is enforced by a
- commit hook. It's nicer to limit the summary line to 50 characters;
- this isn't enforced. If the change can't be summarized so briefly,
- add a paragraph after the empty line and before the individual file
- descriptions.
+ commit hook.
- If only a single file is changed, the summary line can be the normal
file first line (starting with the asterisk). Then there is no
@@ -334,7 +348,9 @@ Documentation fixes (in doc strings, in manuals, in NEWS, and in
comments) should always go to the release branch, if the documentation
to be fixed exists and is relevant to the release-branch codebase.
Doc fixes are always considered "safe" -- even when a release branch
-is in feature freeze, it can still receive doc fixes.
+is in feature freeze, it can still receive doc fixes. However, this
+rule is limited to fixing real problems in the documentation; cleanups
+and stylistic changes are excluded.
When you know that the change will be difficult to merge to the
master (e.g., because the code on master has changed a lot), you can
diff --git a/ChangeLog.1 b/ChangeLog.1
index 82e0ad5c2b8..756dce3e479 100644
--- a/ChangeLog.1
+++ b/ChangeLog.1
@@ -2326,7 +2326,7 @@
2013-07-03 Christoph Egger <christoph@debian.org> (tiny change)
* configure.ac (emacs_broken_SIGIO): Set on gnu-kfreebsd to avoid hang.
- http://bugs.debian.org/712974
+ https://bugs.debian.org/712974
2013-07-02 Paul Eggert <eggert@cs.ucla.edu>
diff --git a/ChangeLog.2 b/ChangeLog.2
index 7b40c54dc64..3e227675e0d 100644
--- a/ChangeLog.2
+++ b/ChangeLog.2
@@ -35670,7 +35670,7 @@
2015-04-08 Artur Malabarba <bruce.connor.am@gmail.com>
* lisp/emacs-lisp/package.el (package-menu-mode): Mode-line notification
- while dowloading information.
+ while downloading information.
* lisp/emacs-lisp/package.el: More conservative `ensure-init-file'
(package--ensure-init-file): Check file contents before visiting.
diff --git a/ChangeLog.3 b/ChangeLog.3
index 8b872a0726e..b149c8295b4 100644
--- a/ChangeLog.3
+++ b/ChangeLog.3
@@ -1,3 +1,88585 @@
+2021-12-01 Juri Linkov <juri@linkov.net>
+
+ * lisp/repeat.el: Use same logic for repeat-check-key and repeat-exit-timeout.
+
+ * lisp/repeat.el (repeat-check-key): Use for repeat-check-key the same logic
+ as is used for repeat-exit-timeout in repeat-post-hook (bug#51390).
+ (repeat-post-hook): Check for repeat-exit-timeout symbol property.
+
+2021-12-01 Juri Linkov <juri@linkov.net>
+
+ * lisp/help.el (help--analyze-key): Prefer posn-set-point over mouse-set-point
+
+ * lisp/help.el (help--analyze-key): Use posn-set-point instead of
+ mouse-set-point that runs the hook mouse-leave-buffer-hook via
+ mouse-minibuffer-check. Using posn-set-point also unnecessitates
+ extra conditions added in bug#51421.
+
+ * lisp/isearch.el (isearch-describe-key, isearch-describe-mode):
+ Add precautions to not call isearch-update when the executed
+ command exited isearch-mode (bug#51173).
+
+2021-12-01 Stefan Kangas <stefan@marxist.se>
+
+ Bump Emacs version to 28.0.90
+
+ * README:
+ * configure.ac:
+ * msdos/sed2v2.inp:
+ * nt/README.W32: Bump Emacs version to 28.0.90.
+
+2021-12-01 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Recognise "struct foo {" as introducing a type declaration
+
+ This fixes bug #52157.
+
+ * lisp/progmodes/cc-engine.el (c-forward-decl-or-cast-1): If such a construct
+ is parsed, set the flag at-type-decl which is part of the function's return
+ value.
+
+2021-12-01 Stefan Kangas <stefan@marxist.se>
+
+ Update authors.el for Emacs 28
+
+ * admin/authors.el (authors-aliases, authors-ignored-files)
+ (authors-renamed-files-alist): Update for Emacs 28.
+
+2021-11-30 Juri Linkov <juri@linkov.net>
+
+ * lisp/repeat.el: Fix long-standing problem when a random key activates map
+
+ * lisp/repeat.el (repeat-check-key): New defcustom (bug#51390).
+ (repeat--command-property): New internal function.
+ (repeat-check-key): New function.
+ (repeat-post-hook): Use repeat--command-property and repeat-check-key.
+
+ * test/lisp/repeat-tests.el (repeat-tests-check-key): New test.
+
+2021-11-30 Juri Linkov <juri@linkov.net>
+
+ * lisp/repeat.el (repeat-keep-prefix): Change default to nil.
+
+ 'repeat-keep-prefix' doesn't yet have sufficient support
+ that covers all cases in bug#51281, so it's disabled now.
+
+2021-11-30 Juri Linkov <juri@linkov.net>
+
+ * test/lisp/repeat-tests.el (repeat-tests-call-b): Test for commit 588caf0b27.
+
+ This tests for 'repeat-map' as a variable instead of a symbol.
+
+2021-11-30 Juri Linkov <juri@linkov.net>
+
+ * src/callint.c (Fcall_interactively): Fix inhibit_mouse_event_check.
+
+ Don't search for the next mouse event with parameters
+ when inhibit-mouse-event-check is non-nil (bug#50067).
+
+2021-11-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix regression in gdb-frame-handler
+
+ * lisp/progmodes/gdb-mi.el (gdb-frame-handler): Protect against
+ nil fullnames (bug#52196).
+
+2021-11-30 Yuga Ego <yet@ego.team> (tiny change)
+
+ Format and index concept 'predicate' in ELisp Intro
+
+ * doc/lispintro/emacs-lisp-intro.texi (Wrong Type of Argument):
+ Add index and format definition (bug#52197).
+
+2021-11-29 Protesilaos Stavrou <info@protesilaos.com>
+
+ Remove problematic characters from modus-themes.org (bug#52126)
+
+ * doc/misc/modus-themes.org
+ (Enable and load, Font configurations for Org and others)
+ (Note on highlight-parentheses.el, Note on god-mode.el): Update links to
+ headings so that they no longer include the removed portions of text.
+
+ (Option for color-coding success state, Option for line highlighting)
+ (Option for line numbers, Option for parenthesis matching)
+ (Advanced customization, Per-theme customization settings)
+ (Case-by-case face specs using the themes' palette)
+ (Face specs at scale using the themes' palette)
+ (Remap face with local value, Cycle through arbitrary colors)
+ (Override colors, Override color saturation)
+ (Font configurations for Org and others, Configure bold and italic faces)
+ (Custom Org user faces, Update Org block delimiter fontification)
+ (Measure color contrast, Load theme depending on time of day)
+ (Backdrop for pdf-tools)
+ (A theme-agnostic hook for theme loading, Note on EWW and Elfeed fonts)
+ (Frequently Asked Questions): Remove parentheses from headings as they
+ can cause problems in the .texi version of the file.
+
+2021-11-29 Andreas Schwab <schwab@linux-m68k.org>
+
+ Avoid undefined behaviour when copying part of structure
+
+ * src/dispnew.c (copy_row_except_pointers): Don't use address of
+ subobject as starting point.
+
+ (cherry picked from commit 6943786b5c1fe76ea05a3a810512bd6777883710)
+
+2021-11-29 Stefan Kangas <stefan@marxist.se>
+
+ * Makefile.in (PREFERRED_BRANCH): Now emacs-28.
+
+2021-11-28 Eli Zaretskii <eliz@gnu.org>
+
+ * src/coding.c (Fdecode_coding_region, Fencode_coding_region): Doc fix.
+
+2021-11-27 Mike Kupfer <mkupfer@alum.berkeley.edu>
+
+ Fix Subject when forwarding message with 2-line From
+
+ * lisp/mh-e/mh-comp.el (mh-forwarded-letter-subject): Collapse
+ two-line From headers into a single line (SF#266). Based on a
+ suggestion from Lester Buck (many thanks!).
+
+2021-11-27 Kyle Meyer <kyle@kyleam.com>
+
+ Update to Org 9.5.1-11-g96d91b
+
+2021-11-27 Eli Zaretskii <eliz@gnu.org>
+
+ * doc/lispref/commands.texi (Click Events): Fix wording (bug#52142).
+
+2021-11-25 Robert Pluim <rpluim@gmail.com>
+
+ Fix pdf generation with Texinfo 6.7
+
+ * doc/lispref/display.texi (Size of Displayed Text): Put @group inside
+ @example (bug#52102).
+
+2021-11-25 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'posn-at-point' near some overlays
+
+ * src/xdisp.c (pos_visible_p): Fix 'posn-at-point' for positions
+ just after a display property that draws a fringe bitmap.
+ (Bug#52097)
+
+2021-11-25 Narendra Joshi <narendraj9@gmail.com> (tiny change)
+
+ * lisp/repeat.el (repeat-post-hook): Add check symbolp rep-map.
+
+2021-11-24 Eli Zaretskii <eliz@gnu.org>
+
+ Revert "Use @pxref when necessary"
+
+ This reverts commit b4f47d2ee2203a9f22bebeb3d09e0fb3fce2f65e.
+ Cleanups should not be done on the release branch: that's
+ unnecessary risk.
+
+2021-11-24 Robert Pluim <rpluim@gmail.com>
+
+ Use @pxref when necessary
+
+ * doc/lispref/customize.texi (Composite Types):
+ * doc/lispref/edebug.texi (Specification List):
+ * doc/lispref/variables.texi (Local Variables):
+ * doc/misc/efaq.texi (Basic keys):
+ (Informational files for Emacs):
+ * doc/misc/flymake.texi (Locating a master file):
+ * doc/misc/gnus.texi (Don't Panic):
+ (Oort Gnus):
+ * doc/misc/htmlfontify.texi (Non-interactive):
+ * doc/misc/mh-e.texi (More About MH-E):
+ * doc/misc/pcl-cvs.texi (Entering PCL-CVS):
+ * doc/misc/tramp.texi (Remote processes):
+ * doc/misc/vhdl-mode.texi (Indentation Calculation):
+ (Custom Indentation Functions): Use @pxref when inside parens.
+
+2021-11-24 Michael Albinus <michael.albinus@gmx.de>
+
+ Backport Tramp fixes, don't merge
+
+ * lisp/net/tramp-sshfs.el (tramp-sshfs-file-name-handler-alist):
+ Use `tramp-handle-file-readable-p'.
+
+ * test/lisp/net/tramp-archive-tests.el
+ (tramp-archive-test02-file-name-dissect): Use `make-tramp-file-name'.
+
+2021-11-23 Takesi Ayanokoji <ayanokoji.takesi@gmail.com> (tiny change)
+
+ Fix typos in documentation
+
+ * doc/lispref/anti.texi:
+ * doc/misc/efaq.texi: Fix typos.
+
+2021-11-22 Eli Zaretskii <eliz@gnu.org>
+
+ Fix '(space :relative-width N)' display spec w/non-ASCII chars
+
+ * src/xdisp.c (produce_stretch_glyph): Use the correct face for
+ non-ASCII characters. Support :relative-width display spec on
+ Lisp strings, not just on buffer text.
+
+2021-11-22 Juri Linkov <juri@linkov.net>
+
+ * lisp/proced.el (proced-sort-header): Fix event positions (bug#1779).
+
+ The logic was copied from 'tabulated-list-col-sort'.
+
+2021-11-20 Kyle Meyer <kyle@kyleam.com>
+
+ Update to Org 9.5-72-gc5d6656
+
+2021-11-20 Eli Zaretskii <eliz@gnu.org>
+
+ Fix mouse handling with several TTY frames on MS-Windows
+
+ * src/w32inevt.c (do_mouse_event): Reset the 'mouse_moved' flag of
+ the selected frame. Without that, this flag might remain set on a
+ TTY frame that is not displayed.
+
+2021-11-20 Eli Zaretskii <eliz@gnu.org>
+
+ Fix temacs invocation from outside of the 'src' directory
+
+ * src/emacs.c (main) [HAVE_NATIVE_COMP]: Recompute the value of
+ native-comp-eln-load-path if about to load loadup in uninitialized
+ Emacs. (Bug#51999)
+
+2021-11-20 martin rudalics <rudalics@gmx.at>
+
+ Fix mouse events on tab bar or tool bar when 'track-mouse' is t
+
+ * lisp/mouse.el (mouse-drag-track):
+ * lisp/mouse-drag.el (mouse-drag-drag): Set 'track-mouse' to some
+ value neither t nor nil.
+ * src/keyboard.c (make_lispy_position): If track_mouse is Qt,
+ report event on tool or tab bar (Bug#51794).
+
+2021-11-20 Po Lu <luangruo@yahoo.com>
+
+ Fix `browse-url-interactive-arg' for certain kinds of events
+
+ * lisp/net/browse-url.el (browse-url-interactive-arg): Don't
+ call `mouse-set-point' unless event is actually a mouse event.
+
+2021-11-19 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/lisp/net/tramp-tests.el (tramp-get-remote-gid): Remove declaration.
+
+2021-11-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Add upward compatibility entry in Tramp (don't merge)
+
+ * lisp/net/tramp.el (tramp-file-name-for-operation):
+ Add `abbreviate-file-name'.
+
+2021-11-18 Juri Linkov <juri@linkov.net>
+
+ Fix sorting of menus in `context-menu-local' (bug#50067).
+
+ * lisp/menu-bar.el (menu-bar-keymap): Don't use `lookup-key'
+ on the `keymap' arg.
+
+ * lisp/mouse.el (context-menu-global): Use `lookup-key global-map'
+ for the `keymap' arg of `menu-bar-keymap'.
+ (context-menu-local): Use `menu-bar-keymap' to sort `keymap'.
+
+2021-11-18 Juri Linkov <juri@linkov.net>
+
+ Fix flyspell-correct-word selected from context menu opened with the keyboard
+
+ * lisp/mouse.el (context-menu-open): Call interactively a command
+ returned by `context-menu-map' such as `flyspell-correct-word' (bug#50067).
+
+ * lisp/textmodes/flyspell.el (flyspell-correct-word): Handle the
+ case when it's called by a key bound to `context-menu-open'.
+ Then it should work the same way as `C-c $' typed on misspelled word
+ where the arg `event' of `flyspell-correct-word-before-point' is nil.
+
+2021-11-18 Robert Pluim <rpluim@gmail.com>
+
+ * lisp/repeat.el (describe-repeat-maps): Print all bound keys (bug#49265).
+
+2021-11-18 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: Use 'mouse-1' for history buttons like for 'add-tab' button
+
+ * lisp/tab-bar.el (tab-bar-mouse-down-1, tab-bar-mouse-1):
+ Handle clicks for 'history-back' and 'history-forward' the same way
+ as 'add-tab' clicks.
+
+2021-11-18 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of window hooks
+
+ * doc/lispref/windows.texi (Window Hooks): Clarify "buffer-local
+ functions". (Bug#51930)
+
+2021-11-18 Eli Zaretskii <eliz@gnu.org>
+
+ Improve doc string of 'highlight-nonselected-windows'
+
+ * src/xdisp.c (syms_of_xdisp) <highlight-nonselected-windows>:
+ Clarify the doc string. (Bug#51927)
+
+2021-11-17 Stefan Kangas <stefan@marxist.se>
+
+ * admin/authors.el (authors-ignored-files): Ignore some NEWS files.
+
+2021-11-16 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-select-tab): Add check for wc-frame (bug#51883).
+
+2021-11-16 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: Doc fixes for commands bound to modifier keys.
+
+ (tab-bar-select-tab-modifiers)
+ (tab-bar-select-tab, tab-bar-switch-to-last-tab): Doc fixes.
+
+2021-11-15 Eli Zaretskii <eliz@gnu.org>
+
+ Fix removal of fringe marks of deleted bookmarks
+
+ * lisp/bookmark.el (bookmark--remove-fringe-mark): The fringe
+ overlay is at BOL, not at POS. (Bug#51233)
+
+2021-11-15 Juri Linkov <juri@linkov.net>
+
+ * lisp/repeat.el (repeat-echo-message): Bind message-log-max to nil.
+
+ Don't insert messages about repeatable keys in the *Messages* buffer.
+
+2021-11-15 Robert Pluim <rpluim@gmail.com>
+
+ * lisp/repeat.el (describe-repeat-maps): Use help-fns--analyze-function.
+
+ Print keys bound to commands in every keymap (bug#49265)
+
+2021-11-15 Juri Linkov <juri@linkov.net>
+
+ * lisp/repeat.el: Detect changes in the minibuffer state (bug#47566)
+
+ (repeat--prev-mb): New internal variable.
+ (repeat-post-hook): Check the property 'repeat-map' on the symbol
+ from 'this-command' in addition to 'real-this-command'. Don't allow
+ repeatable maps in the activated minibuffer or in the minibuffer
+ from another command. Set 'repeat--prev-mb' at the end.
+
+2021-11-15 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid segfaults due to freed face cache
+
+ * src/xfaces.c (face_at_buffer_position): Make sure DEFAULT_FACE
+ is usable. (Bug#51864)
+
+2021-11-15 Stefan Kangas <stefan@marxist.se>
+
+ Doc fix; change recommended file name of custom-file
+
+ * lisp/cus-edit.el (custom-file): Change file name recommendation to
+ match Info node '(emacs) Saving Customizations'.
+
+2021-11-14 Philip Kaludercic <philipk@posteo.net>
+
+ * lisp/net/rcirc.el (rcirc-define-command): Fix interactive-spec generation
+
+ (rcirc-define-command): Wrap interactive spec in a list call.
+
+2021-11-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix `C-h k' in gnus-article-mode (don't merge)
+
+ * lisp/gnus/gnus-art.el (gnus-article-describe-key):
+ (gnus-article-describe-key-briefly): Fix `describe-key' calling
+ convention (bug#51796).
+
+2021-11-14 Daniel Martín <mardani29@yahoo.es>
+
+ Fix semantic-symref-perform-search doc string
+
+ * lisp/cedet/semantic/symref/cscope.el (semantic-symref-perform-search):
+ Fix the docstring to refer to the correct tool (bug#51846).
+
+2021-11-14 Eli Zaretskii <eliz@gnu.org>
+
+ Add more files to be natively-compiled AOT
+
+ * src/Makefile.in (elnlisp): Add emacs-lisp/gv.eln and other
+ missing dependencies of comp.el.
+
+2021-11-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ gnus-summary-line-format doc string clarification
+
+ * lisp/gnus/gnus.el (gnus-summary-line-format): Clarify the Date
+ part of the doc string (bug#51823).
+
+2021-11-13 Alan Mackenzie <acm@muc.de>
+
+ Fix follow-scroll-down in a small buffer which starts slightly scrolled
+
+ This fixes bug #51814.
+
+ * lisp/follow.el (follow-scroll-down): Do away with the optimization of doing
+ vertical-motion over only one window. Instead move over all windows, to
+ checck for being close to point-min, and setting point accordingly.
+
+2021-11-13 Eli Zaretskii <eliz@gnu.org>
+
+ Fix compilation on MS-Windows
+
+ * src/callproc.c (emacs_spawn) <fork_done>: Define the label only
+ if USABLE_POSIX_SPAWN is defined, to avoid a compiler warning.
+
+ (cherry picked from commit a8fc08085110de00ebcbd67b5273a755a5cb8ea1)
+
+2021-11-13 Philipp Stephani <phst@google.com>
+
+ Use posix_spawn if possible.
+
+ posix_spawn is less error-prone than vfork + execve, and can make
+ better use of system-specific enhancements like 'clone' on Linux. Use
+ it if we don't need to configure a pseudoterminal.
+
+ Backported from commit a60053f8368e058229721f1bf1567c2b1676b239.
+ Unlike that commit, only define USABLE_POSIX_SPAWN on macOS, because
+ there posix_spawn is much faster than vfork.
+
+ Don't merge to master.
+
+ * configure.ac (HAVE_SPAWN_H, HAVE_POSIX_SPAWN)
+ (HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)
+ (HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP)
+ (HAVE_POSIX_SPAWNATTR_SETFLAGS, HAVE_DECL_POSIX_SPAWN_SETSID): New
+ configuration variables.
+ * src/callproc.c (USABLE_POSIX_SPAWN): New configuration macro.
+ (emacs_posix_spawn_init_actions)
+ (emacs_posix_spawn_init_attributes, emacs_posix_spawn_init): New
+ helper functions.
+ (emacs_spawn): Use posix_spawn if possible.
+
+ (cherry picked from commit a60053f8368e058229721f1bf1567c2b1676b239)
+
+2021-11-13 Eli Zaretskii <eliz@gnu.org>
+
+ Improve style and comments in font-related sources
+
+ * src/w32font.c (fill_in_logfont): Stylistic changes.
+ * src/font.h (font_property_index, font_select_entity):
+ Add/improve comments.
+
+2021-11-12 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'decode-coding-region'
+
+ * src/coding.c (Fdecode_coding_region): Doc fix.
+
+ * doc/lispref/nonascii.texi (Coding System Basics)
+ (Explicit Encoding): Explain the significance of using 'undecided'
+ in 'decode-coding-*' functions.
+
+2021-11-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with temp buffer killing in package-install-file
+
+ * lisp/emacs-lisp/package.el (package-install-file): Allow killing
+ the temporary buffer without querying (bug#51769).
+
+2021-11-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix Lisp Intro markup error
+
+ * doc/lispintro/emacs-lisp-intro.texi (Insert let): Fix @code
+ markup error (bug#51777).
+
+2021-11-11 Eli Zaretskii <eliz@gnu.org>
+
+ Fix ACL errors with WebDAV volumes on MS-Windows
+
+ * src/w32.c (acl_get_file): Handle ERROR_INVALID_FUNCTION from
+ WebDAV. Patch from Ioannis Kappas <ioannis.kappas@gmail.com>.
+ (Bug#51773)
+
+2021-11-11 Aleksandr Vityazev <avityazev@posteo.org>
+
+ Fix tramp-compat-file-name-concat (Bug#51754)
+
+ * lisp/net/tramp-compat.el: Make `tramp-compat-file-name-concat'
+ work like file-name-concat. (Bug#51754)
+
+2021-11-10 Juri Linkov <juri@linkov.net>
+
+ * lisp/vc/vc-git.el (vc-git-mergebase): More meaningful error message.
+
+ Display a readable error message instead of signaling an error on nil value.
+
+2021-11-10 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ time-stamp: %F is "file name" not "pathname" + other doc
+
+ * lisp/time-stamp.el (time-stamp-format): doc 'file' instead of 'path'.
+ * test/lisp/time-stamp-tests.el (formatz, format-time-offset):
+ Clarify the difference and similarity between these two test helpers.
+
+2021-11-09 Juri Linkov <juri@linkov.net>
+
+ * doc/misc/eww.texi (Advanced): Fix missed variable name eww-retrieve-command.
+
+2021-11-09 Juri Linkov <juri@linkov.net>
+
+ * doc/emacs/windows.texi (Window Convenience): Use @code for windmove.
+
+ This refers to both a command and a user option.
+
+ * etc/NEWS: Add some ---.
+
+2021-11-09 Juri Linkov <juri@linkov.net>
+
+ * doc/emacs/maintaining.texi (Basic VC Editing): Mention Dired buffer.
+
+ * doc/emacs/text.texi (Outline Mode): Replace S-TAB with with S-<TAB>.
+
+ * etc/NEWS: Add some missing +++/--- and move some related items closer.
+
+2021-11-09 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/prog-mode.el (prog-context-menu): Use "Go Back" (bug#38797)
+
+2021-11-09 Stefan Kangas <stefan@marxist.se>
+
+ Revert "Fix localized display of date and time in the NS port"
+
+ This reverts commit 5e05be566b0e13ce0b4e75da663fb051039f0751.
+
+ This was discussed in
+ https://debbugs.gnu.org/cgi/bugreport.cgi?bug=51321#93
+
+2021-11-08 Juri Linkov <juri@linkov.net>
+
+ * lisp/mouse.el (mouse-buffer-menu-mode-groups): Tighten "Version Control".
+
+ Use word boundaries in the "Version Control" regexp to match mode names
+ "Log-Edit", "Log-View", "Git-Log-View", "Change Log", "VC dir",
+ but not "Verilog", "Prolog", "Rlogin" (bug#51337).
+
+2021-11-08 Juri Linkov <juri@linkov.net>
+
+ * doc/emacs/search.texi (Isearch Yank): Add isearch-forward-thing-at-point.
+
+2021-11-07 Alan Mackenzie <acm@muc.de>
+
+ Amend Follow Mode to handle header lines and tab lines correctly
+
+ This fixes bug #51590.
+
+ list/follow.el (follow-scroll-down): Incorporate the height of the tab line
+ into the calculation of the window height.
+ (follow-calc-win-end): Incorporate the pixel heights of the header line and
+ the tab line the calculation of the buffer position of the bottom screen line.
+
+2021-11-07 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/files.el (user-emacs-directory-warning): Clarify docstring.
+
+2021-11-07 Juri Linkov <juri@linkov.net>
+
+ * doc/emacs/frames.texi (Tab Bars): Add text about mouse and tab-bar-format
+
+ Briefly describe mouse commands on the tab bar and tab-bar-format (bug#51444)
+
+2021-11-07 Juri Linkov <juri@linkov.net>
+
+ * doc/emacs/frames.texi (Tab Bars): Describe tab-last.
+
+ 'C-9' and 'M-9' already had kindex, so describe them in the text as well
+ (bug#51444).
+
+2021-11-07 Jim Porter <jporterbugs@gmail.com>
+
+ Add some unit tests for 'abbreviate-file-name'
+
+ * test/lisp/files-tests.el (files-tests-abbreviate-file-name-homedir)
+ (files-tests-abbreviate-file-name-directory-abbrev-alist): New tests.
+
+2021-11-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix compilation MinGW warnings
+
+ * src/w32.h (prepare_standard_handles, reset_standard_handles):
+ Fix prototypes. Reported by Andy Moreton
+ <andrewjmoreton@gmail.com> in
+ https://lists.gnu.org/archive/html/emacs-devel/2021-11/msg00597.html.
+
+2021-11-06 Stefan Kangas <stefan@marxist.se>
+
+ Escape '%' in filenames to fix flymake warnings
+
+ * lisp/progmodes/flymake.el (flymake--log-1): Escape '%' in filenames
+ for 'warning-type-format' so they are not interpreted as a %-sequence
+ by 'format' later. (Bug#51549)
+
+2021-11-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix search string generation in nnimap-make-thread-query
+
+ * lisp/gnus/nnimap.el (nnimap-make-thread-query): Remove text
+ properties before constructing the search string (bug#49926).
+
+2021-11-06 Kyle Meyer <kyle@kyleam.com>
+
+ Update to Org 9.5-68-g77e2ec
+
+2021-11-06 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix dbus-test04-register-method on CentOS (Bug#51369)
+
+ * test/lisp/net/dbus-tests.el (dbus-test04-register-method):
+ Fix problem on CentOS. (Bug#51369)
+
+2021-11-06 Jonas Bernoulli <jonas@bernoul.li>
+
+ * lisp/transient.el: Update to package version v0.3.7-11-g7f5520b3.
+
+2021-11-06 Eli Zaretskii <eliz@gnu.org>
+
+ Clarify "text area of a window" in the documentation
+
+ * src/keyboard.c (Fposn_at_x_y): Clarify that the Y coordinate
+ includes the header-line and the tab-line. (Bug#51590)
+
+ * doc/lispref/windows.texi (Window Sizes, Splitting Windows)
+ (Textual Scrolling, Coordinates and Windows): Fix/remove improper
+ or confusing uses of "text area" of a window.
+
+2021-11-06 Stefan Kangas <stefan@marxist.se>
+
+ Improve docstring of kmacro-set-format
+
+ * lisp/kmacro.el (kmacro-set-format): Improve docstring.
+ (kmacro-insert-counter, kmacro-display-counter)
+ (kmacro-set-counter, kmacro-add-counter): Add cross-references
+ to the info manual.
+
+2021-11-05 Stefan Kangas <stefan@marxist.se>
+
+ Revert "* lisp/wid-edit.el (widget-field): Add subtle border to face."
+
+ This reverts commit 8b024a6ff10f7907445ea60c4db8355638616ed1.
+
+ This lead to some alignment issues. (Bug#51550)
+ Don't merge to master, where we will continue investigating.
+
+2021-11-05 Stefan Kangas <stefan@marxist.se>
+
+ * etc/PROBLEMS: Mention X forwarding slowdowns. (Bug#7092)
+
+2021-11-04 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/custom.el (defgroup): Document the :prefix keyword.
+
+2021-11-04 Thibault Polge <thibault@thb.lt>
+
+ Document ibuffer-auto-mode in ibuffer-mode doc string
+
+ * lisp/ibuffer.el (ibuffer-mode): Mention ibuffer-auto-mode in the
+ ibuffer-mode doc string (bug#51584).
+
+2021-11-04 Juri Linkov <juri@linkov.net>
+
+ * doc/emacs/frames.texi (Tab Bars): Reorder toggle-frame-tab-bar.
+
+2021-11-04 Stefan Kangas <stefan@marxist.se>
+
+ Use current face foreground for SVG icons in customize
+
+ It turns out these few icons were missed when the color and size
+ information was removed from the SVG icons that replaced XPM icons for
+ Customize buffer.
+ * etc/images/down.svg:
+ * etc/images/left.svg:
+ * etc/images/right.svg:
+ * etc/images/up.svg: Don't define foreground; this means they will use
+ the foreground of the currently defined face instead. (Bug#51556)
+
+ (cherry picked from commit 11702a6dd7cb8286f28b7cb986057d2d2c66a914)
+
+2021-11-03 Juri Linkov <juri@linkov.net>
+
+ * doc/emacs/building.texi (Compilation Mode): Add next-error-message-highlight
+
+ The variable 'next-error-message-highlight' already has vindex,
+ so describe it in the text as well (bug#51444).
+
+2021-11-03 Daniel Martín <mardani29@yahoo.es>
+
+ Document a macOS error message when opening Emacs
+
+ * etc/PROBLEMS: Document a potential error message when opening Emacs
+ on macOS for the first time.
+
+2021-11-03 Eli Zaretskii <eliz@gnu.org>
+
+ Fix header-line and tab-line when mode-line-compact is set
+
+ * src/xdisp.c (display_mode_line): Make 'mode-line-compact' apply
+ only to mode lines. (Bug#51558)
+
+2021-11-03 Mattias Engdegård <mattiase@acm.org>
+
+ Add manual section about how to avoid regexp problems
+
+ Help users affected by our NFA engine's stack overflows and occasional
+ poor performance, replacing old text that was more limited in scope.
+
+ * doc/lispref/elisp.texi (Top):
+ * doc/lispref/searching.texi (Regular Expressions): Add menu entries.
+ (Regexp Problems): New node.
+ (Regexp Special):
+ * etc/PROBLEMS: Remove superseded text.
+
+2021-11-03 Phillip Lord <phillip.lord@russet.org.uk>
+
+ Clarify build environment
+
+ * admin/nt/dist-build/README-scripts:
+
+2021-11-03 Phillip Lord <phillip.lord@russet.org.uk>
+
+ Clarify build directory structure
+
+ * admin/nt/dist-build/README-scripts: Clarify build directory structure
+
+2021-11-02 Andrea Corallo <akrl@sdf.org>
+
+ * src/pdumper.c (dump_do_dump_relocation): Add sanity check.
+
+2021-11-01 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/prog-mode.el (prog-context-menu): Use text-mode-context-menu.
+
+2021-11-01 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix bug#51369
+
+ * test/lisp/net/dbus-tests.el (dbus-test04-register-method): Skip on hydra.
+
+2021-11-01 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt arguments of `tramp-make-tramp-file-name'
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handler-mounted-unmounted):
+ * lisp/url/url-tramp.el (url-tramp-convert-url-to-tramp):
+ Use `make-tramp-file-name'.
+
+ * lisp/obsolete/rcompile.el (remote-compile): Pacify byte-compiler.
+
+2021-11-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix typo in describe-map-tree doc string
+
+ * lisp/help.el (describe-map-tree): Fix typo in doc string.
+
+2021-11-01 Ken Brown <kbrown@cornell.edu>
+
+ Drop support for native compilation on 32-bit Cygwin
+
+ * configure.ac (cygwin32-native-compilation): New option.
+ [i686-pc-cygwin]: Don't allow native compilation unless that
+ option is specified. (Bug#50666)
+
+2021-10-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix rendering of title-less <abbr> tags in shr
+
+ * lisp/net/shr.el (shr-tag-abbr): Render <abbr> tags that have no
+ title (bug#51525).
+
+2021-10-31 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid signaling errors in lookup-key
+
+ * src/keymap.c (Flookup_key): Handle KEY vectors where not all
+ components are symbols. (Bug#51527) Do not merge to master.
+
+2021-10-31 Daniel Martín <mardani29@yahoo.es>
+
+ Fix localized display of date and time in the NS port
+
+ * src/nsterm.m (ns_init_locale): If not already set, set LC_ALL to the
+ current locale ID so that dates, currencies, etc. use the settings
+ configured in the operating system. (Bug#51321)
+
+2021-10-31 Eli Zaretskii <eliz@gnu.org>
+
+ Fix display glitches with side-by-side windows on TTY frames
+
+ * src/dispnew.c (adjust_glyph_matrix, prepare_desired_row): Leave
+ room for the border glyph only if the window does actually have
+ the right margin. (Bug#51521)
+
+2021-10-30 Carlos Pita <carlosjosepita@gmail.com>
+
+ Avoid replacing common prefix with ellipsis
+
+ * lisp/progmodes/python.el
+ (python-shell-completion-native-setup): Configure readline not to
+ suppress common prefixes. (Bug#51218)
+
+2021-10-30 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of string truncation APIs
+
+ * doc/lispref/display.texi (Size of Displayed Text):
+ * lisp/international/mule-util.el (truncate-string-to-width):
+ Document caveats of using 'truncate-string-to-width' when
+ character composition is involved.
+
+ * lisp/emacs-lisp/subr-x.el (string-limit):
+ * doc/lispref/strings.texi (Creating Strings): Improve the
+ documentation of 'string-limit'.
+
+2021-10-29 Imran Khan <contact@imrankhan.live> (tiny change)
+
+ * lisp/textmodes/css-mode.el: Fix typo. (Bug#51488)
+
+2021-10-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make message/rfc822 on buttons work again in Gnus
+
+ * lisp/gnus/gnus-art.el (gnus-article-mode): Set
+ mm-inline-message-prepare-function buffer-locally so that it works
+ both when inlining rfc822 and hitting the MIME button (bug#51388).
+ (gnus-mime--inline-message): Factor out into own function.
+ (gnus-mime-display-single): From here.
+
+2021-10-29 Glenn Morris <rgm@gnu.org>
+
+ * lisp/loadup.el: Unbreak build.
+
+2021-10-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move lisp/shorthands.el to lisp/emacs-lisp/shorthands.el
+
+2021-10-29 Michael Albinus <michael.albinus@gmx.de>
+
+ Some Tramp changes, mainly in tramp-tests.el
+
+ * doc/misc/tramp.texi (External packages): Don't use Tramp internals.
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handler-mounted-unmounted):
+ Protect `tramp-make-tramp-file-name' call.
+
+ * lisp/net/tramp.el (tramp-make-tramp-file-name): Set advertised
+ calling conventions.
+
+ * test/lisp/net/tramp-tests.el (tramp-test18-file-attributes):
+ Adapt test.
+ (tramp--test-supports-processes-p): New defun.
+ (tramp-test28-process-file, tramp-test29-start-file-process)
+ (tramp-test30-make-process, tramp-test32-shell-command)
+ (tramp-test32-shell-command-dont-erase-buffer)
+ (tramp-test34-explicit-shell-file-name, tramp-test35-exec-path)
+ (tramp-test44-asynchronous-requests): Use it.
+
+2021-10-29 Gregory Heytings <gregory@heytings.org>
+
+ Make hieroglyphs display correctly with existing fonts
+
+ * etc/HELLO: Remove hieroglyph format control characters.
+
+ * lisp/language/misc-lang.el: Add a rule to compose Egyptian
+ hieroglyphs even without Unicode format control characters.
+
+2021-10-29 Eli Zaretskii <eliz@gnu.org>
+
+ Clarify "default face attributes" in the ELisp manual
+
+ * doc/lispref/display.texi (Defining Faces): Add index entries for
+ face symbol properties.
+ (Attribute Functions): Clarify "default face attribute values" wrt
+ 'face-all-attributes' and 'face-attribute'. (Bug#51465)
+
+2021-10-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `C-u RET' work again
+
+ * lisp/simple.el (newline): Fix regression introduced by
+ d1aacceae9 (bug#51459).
+
+2021-10-28 Jan Synacek <jan.synacek@gmail.com> (tiny change)
+
+ Fix typos in the manual and in a comment
+
+ * lisp/minibuffer.el (completion-pcm--hilit-commonality):
+ * doc/lispintro/emacs-lisp-intro.texi (Mode Line): Fix typos
+ (bug#51434).
+
+2021-10-28 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid assertion violations in 'lookup-key'
+
+ * src/keymap.c (Flookup_key): Don't call ASIZE unless KEY is a
+ vector. This avoids assertion violations when KEY is a string.
+
+2021-10-28 Stefan Kangas <stefan@marxist.se>
+
+ image-dired: Unreverse accidentally reversed menus
+
+ * lisp/image-dired.el (image-dired-thumbnail-mode-map)
+ (image-dired-display-image-mode-map, image-dired-minor-mode-map):
+ In Emacs 26.1 (commits b905454680c7 and bed0373855ea), the menus were
+ converted to use 'easy-menu-define', but they were reversed in the
+ process. Unreverse the menus. (Bug#51446)
+
+2021-10-28 Stefan Kangas <stefan@marxist.se>
+
+ Be more allowing when looking for menu-bar items
+
+ Don't merge to master. This is a safe-for-release fix for Bug#50752.
+
+ * src/keymap.c (lookup_key_1): Factor out function from
+ Flookup_key.
+ (Flookup_key): Be case insensitive when looking for Qmenu_bar
+ items. (Bug#50752)
+
+ * test/src/keymap-tests.el
+ (keymap-lookup-key/mixed-case)
+ (keymap-lookup-key/mixed-case-multibyte): New tests.
+
+2021-10-27 Juri Linkov <juri@linkov.net>
+
+ * lisp/textmodes/text-mode.el (text-mode-context-menu): Rename recently added.
+
+2021-10-27 Robert Pluim <rpluim@gmail.com>
+
+ Allow automatic use of color fonts for emoji on macOS
+
+ * src/macfont.m (macfont_list): Don't exclude color fonts when the
+ fontspec has an 'emoji' script specification.
+
+2021-10-27 Eli Zaretskii <eliz@gnu.org>
+
+ Fix help commands for menu-bar menus
+
+ * lisp/help.el (help--analyze-key): Fix "C-h c" and "C-h k" on
+ menu-bar menu items. (Bug#51421)
+
+2021-10-26 Stefan Kangas <stefan@marxist.se>
+
+ Improve function documentation with text from XDG BDS spec
+
+ * lisp/xdg.el (xdg-config-home, xdg-cache-home, xdg-data-home)
+ (xdg-runtime-dir, xdg-config-dirs, xdg-data-dirs): Copy in the
+ text from the XDG Base Directory Specification to better explain
+ what these functions return.
+
+2021-10-25 Jonas Bernoulli <jonas@bernoul.li>
+
+ * lisp/transient.el: Update to package version 0.3.7.
+
+2021-10-25 Eli Zaretskii <eliz@gnu.org>
+
+ Revert "Fix a typo in emacs-lisp-intro.texi"
+
+ This reverts commit 98eb6d783a482cd7ebca7ec656b0775b82c68e57.
+ I've consulted with Richard Stallman about this, and he says
+ that the original wording, "kinds of atom", is both correct
+ and more elegant writing. So I'm restoring the original text.
+ * doc/lispintro/emacs-lisp-intro.texi (Lisp Atoms): Undo the
+ fix of a "typo" that wasn't a typo. (Bug#51271)
+
+2021-10-25 Robert Pluim <rpluim@gmail.com>
+
+ * doc/lispref/functions.texi (Mapping Functions): Use #' when mapping.
+
+2021-10-25 Miha Rihtaršič <miha@kamnitnik.top>
+
+ Fix issue with interpreting ANSI codes in eshell
+
+ * lisp/eshell/esh-mode.el (eshell-mode): Make window point advance on
+ insertion.
+ (eshell-output-filter): Don't use insert-before-markers (bug#45380).
+
+2021-10-25 Stefan Kangas <stefan@marxist.se>
+
+ image-dired: Doc fix to better explain thumbnail generation
+
+ * doc/emacs/dired.texi (Image-Dired): Improve description by
+ explaining that the generation of thumbnails is asynchronous.
+
+2021-10-25 Stefan Kangas <stefan@marxist.se>
+
+ Clarify two image-dired docstrings
+
+ * lisp/image-dired.el (image-dired-dir): Doc fix; clarify that
+ thumbnails will be saved in "$XDG_CACHE_HOME/thumbnails", as per the
+ Thumbnail Managing Standard.
+ (image-dired-thumb-size): Doc fix; clarify that this option will be
+ ignored when using the Thumbnail Managing Standard.
+
+2021-10-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix flymake example backend conditions in the manual
+
+ * doc/misc/flymake.texi (An annotated example backend): Also react
+ to `signal' process statuses (bug#51380).
+
+2021-10-24 Stefan Kangas <stefan@marxist.se>
+
+ * etc/PROBLEMS: Mention problems with regexp matcher. (Bug#18577)
+
+2021-10-24 Juri Linkov <juri@linkov.net>
+
+ * test/lisp/repeat-tests.el: New file.
+
+2021-10-24 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-move-repeat-map): Fix alias binding of tab-move.
+
+ (tab-bar-move-tab-backward): Put 'repeat-map' symbol property.
+
+2021-10-24 Stefan Kangas <stefan@marxist.se>
+
+ Use restrictive umask when creating image-dired data
+
+ * lisp/image-dired.el (image-dired-dir)
+ (image-dired-sane-db-file): Create thumbnail directory and
+ .image-dired_db with umask 077. This avoids creating world readable
+ copies of private data, and is in fact mandated by the Thumbnail
+ Managing Standard that we aim to support.
+
+2021-10-24 Eli Zaretskii <eliz@gnu.org>
+
+ Fix compilation errors with MinGW64 GCC 11
+
+ * lib-src/ntlib.c (_GL_ATTRIBUTE_MALLOC)
+ (_GL_ATTRIBUTE_DEALLOC_FREE): Define to avoid compilation errors
+ with MinGW64 GCC 11. Suggested by Andy Moreton
+ <andrewjmoreton@gmail.com>. Do not merge to master.
+
+2021-10-24 Ihor Radchenko <yantar92@gmail.com>
+
+ Doc fix for concat
+
+ * src/fns.c (Fconcat): Note that composition values may not remain eq
+ in return value of concat. (Bug#48740)
+
+2021-10-24 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/image-dired.el (image-dired-external-viewer): Support feh.
+
+2021-10-24 Stefan Kangas <stefan@marxist.se>
+
+ Update publicsuffix.txt from upstream
+
+ * etc/publicsuffix.txt: Update from
+ https://publicsuffix.org/list/public_suffix_list.dat
+ dated 2021-10-16 16:33:47 GMT.
+
+2021-10-24 Stefan Kangas <stefan@marxist.se>
+
+ Refer to the info node on keymaps in map-keymap docstring
+
+ * src/keymap.c (Fmap_keymap): Doc fix; add a reference to the Info
+ node '(elisp) Keymaps'. (Bug#30958)
+
+2021-10-23 Stefan Kangas <stefan@marxist.se>
+
+ Clarify abnormal hook documentation
+
+ * doc/lispref/hooks.texi (Standard Hooks):
+ * doc/lispref/modes.texi (Hooks): Clarify wording of "abnormal
+ hook" documentation. (Bug#34588)
+
+2021-10-23 Kyle Meyer <kyle@kyleam.com>
+
+ Update to Org 9.5-59-g52e6f1
+
+2021-10-23 Stefan Kangas <stefan@marxist.se>
+
+ Improve documentation of cl-reduce
+
+ * doc/misc/cl.texi (Mapping over Sequences): Change the
+ explanation of 'cl-reduce' so you don't need to have a major in
+ mathematics to understand it. (Bug#24014)
+
+2021-10-23 Stefan Kangas <stefan@marxist.se>
+
+ Improve documentation of apply-partially
+
+ * doc/lispref/functions.texi (Calling Functions): Improve
+ documentation of 'apply-partially' to be slightly more clear with
+ regards to function arity. (Bug#17623)
+
+2021-10-23 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix typos
+
+ * doc/emacs/cmdargs.texi:
+ * etc/DEBUG:
+ * etc/NEWS: Fix typos.
+
+2021-10-23 Michael Albinus <michael.albinus@gmx.de>
+
+ Revert commit 225ca617b7, and apply another fix
+
+ * lisp/minibuffer.el (read-file-name-default): Revert commit
+ 225ca617b7. (Bug#50976).
+
+ * lisp/shell.el (shell): Remove volume letter for remote shell
+ file name. (Bug#49229)
+
+2021-10-23 Stefan Kangas <stefan@marxist.se>
+
+ Fix documentation of posn-at-x-y
+
+ * doc/lispref/commands.texi (Accessing Mouse): Fix documentation of
+ 'posn-at-x-y' to match docstring. (Bug#15783)
+
+2021-10-22 Robert Pluim <rpluim@gmail.com>
+
+ Improve some NEWS entries
+
+ * etc/NEWS: Improve some NEWS entries.
+
+2021-10-22 Robert Pluim <rpluim@gmail.com>
+
+ Improve documentation of syntax-ppss-context slightly
+
+ * doc/lispref/syntax.texi (Parser State): Document all possible return
+ values from 'syntax-ppss-context'.
+
+2021-10-22 Robert Pluim <rpluim@gmail.com>
+
+ Move some xwidget entries
+
+ * etc/NEWS: Move xwidget entries to correct location.
+
+2021-10-22 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ time-stamp-tests: improvements to test macros
+
+ test/lisp/time-stamp-tests.el: Update macro declarations.
+ (formatz-generate-tests): Don't nconc onto a constant list.
+ Tests now run 12% faster in batch mode.
+
+2021-10-22 Itai Y. Efrat <itai3397@gmail.com>
+
+ Fix rfc6068-parse-mailto-url autoload
+
+ * lisp/net/browse-url.el (rfc6068-parse-mailto-url): Fix autoload
+ cookie (bug#51333).
+
+2021-10-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Regexp-quote github domains in bug-reference
+
+ * lisp/progmodes/bug-reference.el
+ (bug-reference--build-forge-setup-entry): Regexp-quote the domain
+ (bug#51316).
+
+2021-10-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Ensure valid end/beginning lines in message-mark-inserted-region
+
+ * lisp/gnus/message.el (message-mark-inserted-region): Ensure
+ there's a newline before inserting the end line (bug#51324).
+
+2021-10-22 Robert Pluim <rpluim@gmail.com>
+
+ * etc/NEWS: Improve 'repeat-mode' entry.
+
+ * lisp/repeat.el (repeat-keep-prefix): Expand description.
+
+ * lisp/net/eww.el (eww-retrieve-command): Add :tag.
+
+2021-10-22 Stefan Kangas <stefan@marxist.se>
+
+ Add description of cards to etc/refcards/README
+
+ * etc/refcards/README: List all the generated reference cards,
+ including their translations. (Bug#8932)
+
+2021-10-22 Martin Rudalics <rudalics@gmx.at>
+
+ Fix 'calculate-lisp-indent' when "[" starts containing sexp (Bug#51312)
+
+ * lisp/emacs-lisp/lisp-mode.el (calculate-lisp-indent): Handle
+ arbitrary paren syntax after skipping whitespace backwards within
+ containing sexp (Bug#51312).
+
+2021-10-22 Stefan Kangas <stefan@marxist.se>
+
+ Fix typo in doc/emacs/anti.texi
+
+ * doc/emacs/anti.texi (Antinews): Fix typo. (Bug#51325)
+ Reported by Po Lu <luangruo@yahoo.com>.
+
+2021-10-22 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ Update doc of Edebug specification for macros
+
+ doc/lispref/edebug.texi: Update documentation of Edebug specification:
+ - Do not document "0" as a recommended shortcut for non-instrumented
+ arguments; nobody knows about nor uses this, so don't encourage it.
+ - Add an example equivalent to (declare (debug (&rest sexp))).
+
+2021-10-21 Eli Zaretskii <eliz@gnu.org>
+
+ Fix non-interactive behavior of 'kill-region'
+
+ * lisp/simple.el (kill-region): Actually ignore BEG and END when
+ REGION is non-nil. Doc fix. (Bug#51320)
+
+2021-10-21 Juri Linkov <juri@linkov.net>
+
+ * test/lisp/dabbrev-tests.el: Use 'kbd' for readable keys.
+
+ (dabbrev-expand-test, dabbrev-completion-test)
+ (dabbrev-completion-test-with-argument):
+ Use 'kbd' to format keys for 'execute-kbd-macro'.
+ (dabbrev-expand-test): Fix docstring.
+
+2021-10-21 Juri Linkov <juri@linkov.net>
+
+ * lisp/menu-bar.el (menu-bar-keymap): Add optional arg KEYMAP (bug#50067).
+
+ * lisp/mouse.el (context-menu-global): Use 'menu-bar-keymap' with
+ its arg KEYMAP set to 'global-map'.
+
+2021-10-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix todo-mode AOT test failures (bug#51308)
+
+ Fix hi-lock AOT test failures (bug#51308)
+
+2021-10-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix socks test
+
+ * test/lisp/net/socks-tests.el (socks-tests-v4-basic): Fix failure
+ under native-comp (bug#51308).
+
+2021-10-20 Juri Linkov <juri@linkov.net>
+
+ * lisp/help.el (help--analyze-key): Add new arg BUFFER (bug#51173).
+
+ * lisp/help.el (describe-key): Use BUFFER as arg for help--analyze-key.
+ (describe-key-briefly): Change arg UNTRANSLATED deprecated in 27.1
+ to BUFFER.
+
+ * lisp/gnus/gnus-art.el (gnus-article-describe-key)
+ (gnus-article-describe-key-briefly): Call describe-key and
+ describe-key-briefly with first arg as a cons with raw keys,
+ and the BUFFER arg set to the current buffer.
+
+2021-10-20 Juri Linkov <juri@linkov.net>
+
+ Improve docstrings and NEWS item of 'repeat-mode'
+
+ * lisp/repeat.el (repeat-exit-timeout, repeat-echo-function)
+ (repeat-in-progress, repeat-map): Update docstrings.
+
+2021-10-20 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-menu-bar): New command (bug#51247).
+
+ (tab-bar-format): Rename option 'tab-bar-format-menu-global' to
+ 'tab-bar-format-menu-bar'.
+ (tab-bar-format-menu-bar): Rename from 'tab-bar-format-menu-global'.
+
+2021-10-20 Po Lu <luangruo@yahoo.com>
+
+ Display a tab bar item as sunken when appropriate
+
+ When the mouse pointer is pressed on the tab bar, moved out of the tab
+ bar, and moved back in, it would be more appropriate to behave like
+ other programs by displaying the item as sunken.
+
+ * src/xdisp.c (note_tab_bar_highlight): Display item as sunken if the
+ mouse pointer returns to the tab bar down.
+
+2021-10-20 Po Lu <luangruo@yahoo.com>
+
+ Fix tab bar item highlight when a mouse click is dropped
+
+ * src/xdisp.c (note_mouse_highlight): Clear last_tab_bar_item if the
+ movement wasn't made on top of the tab bar.
+
+2021-10-20 Stefan Kangas <stefan@marxist.se>
+
+ Refer to mouse-highlight from make-pointer-invisible docstring
+
+ * src/frame.c (syms_of_frame) <Vmake_pointer_invisible>: Doc fix;
+ add reference to 'mouse-highlight'. (Bug#42889)
+
+2021-10-20 Robert Pluim <rpluim@gmail.com>
+
+ * etc/PROBLEMS: Add hex codepoint for NO-BREAK SPACE
+
+2021-10-20 Robert Pluim <rpluim@gmail.com>
+
+ Describe how to debug fontconfig issues
+
+ * etc/PROBLEMS: Add FC_DEBUG usage pointers.
+
+2021-10-20 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt Tramp tests
+
+ * test/lisp/net/tramp-archive-tests.el (tramp-archive-test45-auto-load):
+ Adapt code snippet.
+
+ * test/lisp/net/tramp-tests.el (tramp-test29-start-file-process)
+ (tramp-test30-make-process): Adapt tests.
+ (tramp--test-supports-set-file-modes-p): Renamed from
+ `tramp--test-supports-file-modes-p'. Adapt all callees.
+ (tramp-test35-exec-path): Use it.
+
+2021-10-20 Jim Porter <jporterbugs@gmail.com>
+
+ Convert ANSI color definitions in themes to use faces (e.g. 'ansi-color-red')
+
+ * etc/themes/dichromacy-theme.el:
+ * etc/themes/leuven-theme.el:
+ * etc/themes/misterioso-theme.el:
+ * etc/themes/tango-theme.el:
+ * etc/themes/tango-dark-theme.el:
+ * etc/themes/wombat-theme.el: Convert ANSI color definitions to
+ use faces.
+
+2021-10-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Revert back to using ESC as viper-ESC-key again"
+
+ This reverts commit 5d522b430bd5ecfb8f082906cd634883dbb68f3e.
+
+ The change led to M-x not working in non-gui Emacsen (bug#51253).
+
+2021-10-19 Alan Third <alan@idiocy.org>
+
+ Fix inset rectangle corners when sides aren't drawn (bug#51251)
+
+ * src/nsterm.m (ns_draw_relief): Make the inner rectangle line up with
+ the outer rectangle's edges where the edges aren't drawn.
+
+2021-10-19 Jan Synacek <jan.synacek@gmail.com> (tiny change)
+
+ Don't use color escape sequences in vc-git-expanded-log-entry
+
+ * lisp/vc/vc-git.el (vc-git-expanded-log-entry): Use '--no-color' flag
+ in git invocation. (Bug#51262)
+
+2021-10-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Code cleanup in tramp-tests.el
+
+ * test/lisp/net/tramp-tests.el (tramp-test29-start-file-process)
+ (tramp-test30-make-process): Extend tests.
+ (tramp--test-out-of-band-p): New defun.
+ (tramp--test-windows-nt-and-out-of-band-p)
+ (tramp-test42-utf8-with-stat, tramp-test42-utf8-with-perl)
+ (tramp-test42-utf8-with-ls): Use it.
+ (tramp--test-windows-nt-or-smb-p): Use `tramp--test-windows-nt-p'.
+
+2021-10-19 Robert Pluim <rpluim@gmail.com>
+
+ * admin/notes/unicode: Refer to Unicode's emoji-style.txt
+
+2021-10-19 Robert Pluim <rpluim@gmail.com>
+
+ Handle VS-16 correctly for non-emoji codepoints
+
+ * admin/unidata/blocks.awk: Remove emoji overrides for codepoints with
+ Emoji_Presentation = No, they're no longer necessary.
+ * lisp/composite.el: Remove #xFE0F (VS-16) from the range handled by
+ `compose-gstring-for-variation-glyph' so it can be handled by
+ `font_range'.
+ * src/composite.c (syms_of_composite): New variable
+ `auto-composition-emoji-eligible-codepoints'.
+ * admin/unidata/emoji-zwj.awk: Generate value for
+ `auto-composition-emoji-eligible-codepoints'. Add
+ `composition-function-table' entries for 'codepoint + U+FE0F' for
+ them.
+ * src/font.c (codepoint_is_emoji_eligible): New function to check if
+ we should try to use the emoji font for a codepoint.
+ (font_range): Use it.
+
+2021-10-19 Tassilo Horn <tsdh@gnu.org>
+
+ Adjust bug-reference-bug-regexp default values to match only at beg of word
+
+ Previously, the "bug 1" in "(debug 1)" has also been highlighted.
+
+ * lisp/progmodes/bug-reference.el (bug-reference-bug-regexp)
+ (bug-reference--setup-from-vc-alist,bug-reference-setup-from-mail-alist)
+ (bug-reference-setup-from-irc-alist): Adjust bug-reference-bug-regexp
+ default values to match only at the beginning of a word.
+
+2021-10-19 Stefan Kangas <stefan@marxist.se>
+
+ Fix a typo in emacs-lisp-intro.texi
+
+ * doc/lispintro/emacs-lisp-intro.texi (Lisp Atoms): Fix typo.
+ Reported by Mor Zahavi <morzahavi@me.com>. (Bug#51271)
+
+2021-10-18 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix some Tramp problems
+
+ * lisp/net/tramp-adb.el (tramp-adb-file-name-handler-alist):
+ Use `tramp-adb-handle-file-executable-p' and
+ `tramp-adb-handle-file-readable-p'.
+ (tramp-adb-handle-file-executable-p)
+ (tramp-adb-handle-file-readable-p): New defuns.
+ (tramp-adb-handle-file-writable-p): Simplify.
+ (tramp-adb-handle-make-process): Handle :filter being t.
+ (tramp-adb-find-test-command): Remove.
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-file-readable-p):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-file-readable-p):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist):
+ Use `tramp-handle-file-readable-p'.
+ (tramp-gvfs-handle-file-executable-p): Do not check whether file
+ exists, this is done in `tramp-check-cached-permissions'.
+ (tramp-gvfs-handle-file-readable-p): Remove.
+
+ * lisp/net/tramp.el (tramp-error): Move binding of `inhibit-message' ...
+ (tramp-signal-hook-function): ... here.
+ (tramp-handle-access-file): Rewrite.
+ (tramp-handle-file-readable-p): New defun.
+ (tramp-handle-make-process): Setting :filter to t works since
+ Emacs 29.1 only.
+
+ * test/lisp/net/tramp-tests.el (tramp-test17-insert-directory)
+ (tramp-test18-file-attributes): Extend tests.
+
+2021-10-18 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt Tramp manual
+
+ * doc/misc/tramp.texi: Use @uref instead of @url.
+ (Frequently Asked Questions): Adapt ELPA references.
+
+2021-10-18 Martin Rudalics <rudalics@gmx.at>
+
+ Further fixes to Elisp manual
+
+ * doc/lispref/frames.texi (Frame Layout): Index "tab bar" instead
+ of "internal tab bar".
+ (Implied Frame Resizing): Remove irritating hyphens.
+ * doc/lispref/windows.texi (Windows and Frames): Remove paragraph
+ relating 'minibuffer-window' to 'window-list'.
+
+2021-10-18 Alan Mackenzie <acm@muc.de>
+
+ * lisp/progmodes/cc-engine.el (c-forward-decl-or-cast-1): check type-start
+
+ Check type-start is non-nil at L659 of the function.
+
+2021-10-18 Juri Linkov <juri@linkov.net>
+
+ Rename tab-bar-drag-maybe to tab-bar--dragging-in-progress
+
+ * lisp/tab-bar.el (tab-bar--event-to-item, tab-bar-mouse-down-1)
+ (tab-bar-mouse-move-tab): Rename tab-bar-drag-maybe to
+ tab-bar--dragging-in-progress.
+
+ * src/xdisp.c (note_mouse_highlight): Rename tab_bar_drag_maybe to
+ tab_bar__dragging_in_progress.
+
+2021-10-18 Mattias Engdegård <mattiase@acm.org>
+
+ Fix xref elisp identifier namespace mistake
+
+ Pressing `M-.` on ALPHA in
+
+ (let ((ALPHA BETA)) ...)
+
+ would incorrectly search for ALPHA as a function rather than a variable.
+
+ * lisp/progmodes/elisp-mode.el (elisp--xref-infer-namespace): Fix logic.
+ * test/lisp/progmodes/elisp-mode-tests.el
+ (elisp-mode-infer-namespace): Add test case.
+
+2021-10-18 Eli Zaretskii <eliz@gnu.org>
+
+ Minor fixes for recent changes in ELisp manual
+
+ * doc/lispref/windows.texi (Basic Windows, Windows and Frames)
+ (Selecting Windows):
+ * doc/lispref/objects.texi (Window Type):
+ * doc/lispref/frames.texi (Input Focus, Frame Layout): Fix
+ wording, punctuation, and indexing.
+
+2021-10-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix example in calc manual
+
+ * doc/misc/calc.texi (Arithmetic Tutorial): Fix sign in the
+ example (bug#51265).
+
+2021-10-18 Martin Rudalics <rudalics@gmx.at>
+
+ Rewrites of Elisp manual including tab-bar and tab-line changes
+
+ * doc/lispref/buffers.texi (Current Buffer, Buffer List): Update
+ references to 'selected-window'.
+ * doc/lispref/elisp.texi (Top): Move up Selecting Windows section
+ in front of Window Sizes section.
+ * doc/lispref/frames.texi (Creating Frames): Say window system
+ instead of windowing system.
+ (Frame Layout): Add Tab Bar to layout.
+ (Layout Parameters): Add 'tab-bar-lines'.
+ (Input Focus): Say window system window instead of window
+ manager window. Fix reference to 'selected-window'.
+ * doc/lispref/objects.texi (Window Type): Minor rewrite.
+ * doc/lispref/windows.texi (Basic Windows): Rewrite. Settle on
+ term 'window system window' for disambiguation with our windows.
+ Move 'selected-window' description to Selecting Windows section.
+ Move schematic of window structure here. Use 'decorations' for
+ objects outside the window body. Say that the areas reserved
+ for continuation and truncation glyphs, vertical dividers and
+ line numbers are part of the window body.
+ (Windows and Frames): Minor rewrite, adding and fixing some
+ cross references. Move live window schematic to 'Basic Windows'
+ section.
+ (Selecting Windows): Move section in front of Window Sizes
+ section. Move description of 'selected-window' here. Move up
+ description of 'frame-selected-window' and
+ 'set-frame-selected-window'. Update and move description of
+ 'window-bump-use-time' here.
+ (Window Sizes): Throughout use the term 'decorations' instead of
+ enumerating them individually. Add 'window-tab-line-height'
+ description.
+ (Resizing Windows): Again use the term 'decorations' instead of
+ enumerating them individually.
+ (Splitting Windows): Minor fix.
+ (Cyclic Window Ordering): Improve descriptions of 'get-lru-window'
+ and 'get-mru-window'. Move 'window-bump-use-time' to Selecting
+ Windows section.
+ (Coordinates and Windows, Window Configurations): Once more use
+ the term 'decorations' instead of enumerating them individually.
+ * src/window.c (Fwindow_bump_use_time): Move after
+ 'window-use-time'. Make it work for live windows only. Make
+ WINDOW argument optional. Update doc-string.
+
+2021-10-17 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: Improve docstrings (bug#51247)
+
+ * lisp/tab-bar.el (tab-bar--key-to-number)
+ (tab-bar--event-to-item, tab-bar--format-tab-group)
+ (tab-bar--current-tab-make): Improve docstrings.
+ (switch-to-buffer-other-tab): Obsolete the arg NORECORD.
+
+2021-10-17 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-mouse-move-tab): Don't drag tab to itself.
+
+2021-10-17 Martin Rudalics <rudalics@gmx.at>
+
+ Add tab-bar-drag-maybe for indication of tab dragging (bug#50993)
+
+ * lisp/tab-bar.el (tab-bar--event-to-item)
+ (tab-bar-mouse-move-tab): Set tab-bar-drag-maybe to nil.
+ (tab-bar-mouse-down-1): Set tab-bar-drag-maybe to t.
+
+ * src/xdisp.c (note_mouse_highlight): Set cursor to 'hand_cursor'
+ when tab_bar_drag_maybe is true.
+ (syms_of_xdisp): New variable tab-bar-drag-maybe.
+
+2021-10-17 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: Add a new tab on [mouse-1] instead of [down-mouse-1]
+
+ * lisp/tab-bar.el (tab-bar-mouse-down-1): Rename from
+ tab-bar-mouse-select-tab. Ignore 'add-tab'.
+ (tab-bar-mouse-1): Rename from tab-bar-mouse-close-tab-from-button.
+ Use binding of 'add-tab'.
+ (tab-bar-map): Rebind [down-mouse-1] from tab-bar-mouse-select-tab to
+ tab-bar-mouse-down-1, and [mouse-1] from tab-bar-mouse-close-tab-from-button
+ to tab-bar-mouse-1 (bug#51246).
+
+2021-10-17 Juri Linkov <juri@linkov.net>
+
+ Add new and fix existing docstrings in tab-bar.el and tab-line.el (bug#51247)
+
+ * lisp/tab-bar.el (tab-bar--key-to-number)
+ (tab-bar--event-to-item, tab-bar--format-tab)
+ (tab-bar--format-tab-group, tab-bar--tab, tab-bar--current-tab)
+ (tab-bar--current-tab-make): Add/fix docstrings.
+
+2021-10-17 Po Lu <luangruo@yahoo.com>
+
+ Add tab bar support to the nextstep port
+
+ * src/nsfns.m (ns_change_tab_bar_height): New function.
+ (ns_set_tab_bar_lines): Check tab bar height and set tab bar
+ accordingly.
+ * src/nsterm.m (ns_clear_under_internal_border): Clear internal border
+ correctly when there is a tab bar.
+ (ns_create_terminal): Add ns_change_tab_bar_height.
+ (mouseDown): Handle tab bar mouse click events.
+
+2021-10-17 Alan Third <alan@idiocy.org>
+
+ Fix potential buffer overflow (bug#50767)
+
+ * src/image.c (svg_load_image): Check how many bytes were actually
+ written to the buffer. Don't check xmalloc return value as xmalloc
+ doesn't return if it fails.
+
+2021-10-17 Eli Zaretskii <eliz@gnu.org>
+
+ Improve doc strings in tab-line.el
+
+ * lisp/tab-line.el (tab-line-tab-name-function)
+ (tab-line-tab-name-truncated-buffer, tab-line-tabs-mode-buffers)
+ (tab-line-tabs-buffer-group-function)
+ (tab-line-tabs-buffer-group-sort-function)
+ (tab-line-tabs-buffer-groups, tab-line-tab-name-format-function)
+ (tab-line-tab-name-format-default, tab-line-format-template)
+ (tab-line-tab-face-inactive-alternating)
+ (tab-line-tab-face-special, tab-line-tab-face-modified)
+ (tab-line-format, tab-line-auto-hscroll, tab-line-hscroll-right)
+ (tab-line-hscroll-left, tab-line-new-tab, tab-line-select-tab)
+ (tab-line-switch-to-prev-tab, tab-line-switch-to-next-tab)
+ (tab-line-close-tab-function, tab-line-close-tab)
+ (tab-line-tab-context-menu, tab-line-context-menu)
+ (tab-line-mode, tab-line-exclude-modes, tab-line-mode--turn-on):
+ Add or fix doc strings.
+
+2021-10-17 Eli Zaretskii <eliz@gnu.org>
+
+ More documentation fixes in tab-bar.el
+
+ * lisp/tab-bar.el (tab-bar-detach-tab, tab-bar-move-window-to-tab)
+ (tab-bar-new-tab-to, tab-bar-new-tab, tab-bar-close-tab-select)
+ (tab-bar-close-last-tab-choice, tab-bar-tab-pre-close-functions)
+ (tab-bar-close-tab, tab-bar-close-tab-by-name)
+ (tab-bar-close-other-tabs, tab-bar-rename-tab)
+ (tab-bar-rename-tab-by-name, tab-bar-move-tab-to-group)
+ (tab-bar-change-tab-group, tab-bar-close-group-tabs)
+ (tab-switcher-next-line, tab-switcher-prev-line)
+ (tab-switcher-unmark, tab-switcher-delete, tab-switcher-select)
+ (tab-bar-get-buffer-tab, display-buffer-in-tab)
+ (display-buffer-in-new-tab, switch-to-buffer-other-tab)
+ (find-file-other-tab, find-file-read-only-other-tab): Doc fixes.
+
+2021-10-17 Eli Zaretskii <eliz@gnu.org>
+
+ Improve doc strings of tab-bar commands
+
+ * lisp/tab-bar.el (tab-bar-mouse-select-tab)
+ (tab-bar-mouse-move-tab, tab-bar-mouse-close-tab-from-button)
+ (tab-bar-mouse-close-tab, tab-bar-mouse-context-menu)
+ (tab-bar-switch-to-next-tab, tab-bar-switch-to-prev-tab)
+ (tab-bar-switch-to-last-tab, tab-bar-switch-to-recent-tab)
+ (tab-bar-move-tab-backward, tab-bar-move-tab)
+ (tab-bar-move-tab-to-frame): Add/fix doc strings.
+
+2021-10-17 Stefan Kangas <stefan@marxist.se>
+
+ Fix a semantic test on some macOS machines
+
+ * test/lisp/cedet/semantic/bovine/gcc-tests.el
+ (semantic-gcc-test-output-parser-this-machine): Fix test on some macOS
+ machines where running "gcc" runs "llvm" instead.
+
+2021-10-16 Kyle Meyer <kyle@kyleam.com>
+
+ Update to Org 9.5-57-g9bc3a2
+
+2021-10-16 Stefan Kangas <stefan@marxist.se>
+
+ Recommend against using uce.el
+
+ * lisp/mail/uce.el: Recommend against its use. (Bug#46472)
+ Do not merge to master.
+
+2021-10-16 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid aborts when a thread is signaled while "waiting for input".
+
+ * src/process.c (kbd_is_ours): New function.
+ (wait_reading_process_output): Set 'waiting_for_input' only if the
+ current thread is monitoring the keyboard descriptor. See also
+ https://lists.gnu.org/archive/html/emacs-devel/2021-10/msg01180.html.
+ (Bug#51229)
+
+2021-10-16 Philipp Stephani <phst@google.com>
+
+ Improve documentation string for 'compilation-error-regexp-alist'.
+
+ * lisp/progmodes/compile.el (compilation-error-regexp-alist): Clarify
+ behavior when TYPE is a cons cell.
+
+2021-10-16 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-trampoline-compile): Fix target dir.
+
+2021-10-16 Eli Zaretskii <eliz@gnu.org>
+
+ Fix removal of fringe indication of bookmarks
+
+ * lisp/bookmark.el (bookmark--remove-fringe-mark): Fix off-by-one
+ error in looking for bookmark-related overlays. (Bug#51233)
+
+2021-10-15 Stefan Kangas <stefan@marxist.se>
+
+ Prefer "graphical displays" to "X terminals" in documentation
+
+ * doc/lispref/objects.texi (Ctl-Char Syntax): Fix incorrect remark;
+ some text terminals can generate ASCII control characters.
+ (Other Char Bits):
+ * lisp/bindings.el:
+ * lisp/gnus/gnus-undo.el (gnus-undo-mode-map): Say "graphical display"
+ and "GUI display" instead of "X terminal"; the latter term is
+ archaic. (Bug#51217)
+
+2021-10-15 Michael Albinus <michael.albinus@gmx.de>
+
+ Precise documentation of file-notify-add-watch
+
+ * doc/lispref/os.texi (File Notifications):
+ * lisp/filenotify.el (file-notify-add-watch): Precise, that
+ watching a directory includes reports on file changes for some
+ backends. (Bug#51146)
+
+2021-10-15 Martin Rudalics <rudalics@gmx.at>
+
+ Fixes to account for windows' tab lines
+
+ * doc/lispref/display.texi (Size of Displayed Text): Fix entry
+ on 'window-text-pixel-size'.
+ * lisp/window.el (window--dump-window): Dump tab-line-height and
+ scroll-bar-height too.
+ (window--min-size-1): Take 'window-tab-line-height' into account.
+ * src/xdisp.c (Fwindow_text_pixel_size): Fix doc-string of
+ 'window-text-pixel-size'. Rename last argument to 'MODE-LINES'.
+
+2021-10-15 Andrea Corallo <akrl@sdf.org>
+
+ Fix `native-compile-target-directory' effectiveness on trampolines
+
+ * lisp/emacs-lisp/comp.el (comp-trampoline-compile): Fix
+ `native-compile-target-directory' effectiveness on trampoline
+ compilation.
+
+2021-10-15 Jan Synacek <jan.synacek@gmail.com>
+
+ Add missing single quotes in the Emacs manual
+
+ * lisp/mwheel.el (mouse-wheel-scroll-amount): Add missing single
+ quotes. (Bug#51223)
+
+2021-10-15 Juri Linkov <juri@linkov.net>
+
+ * lisp/menu-bar.el (yank-menu-length): Fix docstring (bug#51138).
+
+2021-10-14 Michael Albinus <michael.albinus@gmx.de>
+
+ Accept process-filter t in Tramp
+
+ * lisp/net/tramp.el (tramp-handle-make-process):
+ * lisp/net/tramp-adb.el (tramp-adb-handle-make-process):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process): Filter can be t.
+
+ * test/lisp/net/tramp-tests.el (tramp-test29-start-file-process)
+ (tramp-test30-make-process): Test filter equal t.
+
+2021-10-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document the t value for set-process-filter in the manual
+
+ * doc/lispref/processes.texi (Filter Functions): Mention what t
+ means (bug#51177).
+
+2021-10-14 Michael Albinus <michael.albinus@gmx.de>
+
+ * doc/misc/tramp.texi (Frequently Asked Questions): Add reference
+
+ to ELPA Installation node.
+
+2021-10-14 Eli Zaretskii <eliz@gnu.org>
+
+ Fix Help functions for clicks on tool bar and tab bar
+
+ * lisp/mouse.el (mouse-minibuffer-check): Don't assume posn-window
+ returns a window. (Bug#5199)
+
+2021-10-14 Martin Rudalics <rudalics@gmx.at>
+
+ In make_lispy_position fix Bug#50993 in rudimentary fashion
+
+ * src/keyboard.c (make_lispy_position): Do not set posn to
+ tool- or tab-bar when track_mouse is enabled (Bug#50993).
+
+2021-10-14 Dmitry Gutov <dgutov@yandex.ru>
+
+ Mark vc-switch-backend as obsolete
+
+ * etc/NEWS: Mention the change.
+
+ * lisp/vc/vc.el (vc-switch-backend): Mark as obsolete (bug#50344).
+ (vc-transfer-file): Wrap the calls in 'with-suppressed-warnings'.
+
+2021-10-14 Yan <yan@metatem.net> (tiny change)
+
+ Add missing parentheses in the Emacs manual
+
+ * doc/emacs/maintaining.texi (Xref Commands): Add missing
+ parentheses (bug#51195).
+
+2021-10-14 Stefan Kangas <stefan@marxist.se>
+
+ Improve tooltip of mode-line-position again
+
+ * lisp/bindings.el (mode-line-position): Improve tooltip again.
+ This change was discussed in
+ https://lists.gnu.org/r/emacs-devel/2021-10/msg00952.html
+
+2021-10-13 Philip Kaludercic <philipk@posteo.net>
+
+ Use browse-url-button-regexp for rcirc-url-regexp
+
+ * lisp/net/rcirc.el (rcirc-url-regexp): Copy improved regexp from
+ browse-url
+
+2021-10-13 Juri Linkov <juri@linkov.net>
+
+ * lisp/help.el (help--analyze-key): Avoid mouse-set-point for non-mouse events
+
+ (bug#51173)
+
+2021-10-13 Michael Albinus <michael.albinus@gmx.de>
+
+ Tramp doc cleanup
+
+ * doc/misc/tramp.texi (Overview, Bug Reports)
+ (Frequently Asked Questions): Stylistic changes.
+ (Bug Reports): Mention tramp buffers appended to bug report.
+
+2021-10-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make emacs-lisp-byte-compile-and-load load the .elc file again
+
+ * lisp/progmodes/elisp-mode.el (emacs-lisp-byte-compile-and-load):
+ Load the compiled file instead of the source (bug#51180).
+
+2021-10-13 Peter Münster <pm@a16n.net>
+
+ Fix point movement in image-dired
+
+ * lisp/image-dired.el (image-dired-thumb-file-marked-p): Don't
+ move point in associated dired buffer.
+ (image-dired-delete-marked): Revert "Fix deletion of associated image"
+ because it was wrong and introduced another problem (bug#51152).
+
+2021-10-13 Stefan Kangas <stefan@marxist.se>
+
+ Improve shortdoc for vector
+
+ * lisp/emacs-lisp/shortdoc.el (vector): Improve shortdoc with titles.
+ Add mapc. Fix typo where 'seq-reduce' is incorrectly written as
+ 'reduce'.
+
+2021-10-13 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix test bug when calloc returns null
+
+ * test/src/emacs-module-resources/mod-test.c (Fmod_test_userptr_make):
+ Don’t dump core if calloc returns null and signal_errno returns.
+
+2021-10-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify GCC 11 -fanalyzer on x86-64
+
+ * src/buffer.c (fix_overlays_before):
+ Redo slightly to work around GCC bug 102692
+ <https://gcc.gnu.org/bugzilla//show_bug.cgi?id=102692>.
+
+2021-10-12 Gregory Heytings <gregory@heytings.org>
+
+ Improve handling of non-character events in input methods
+
+ * lisp/international/quail.el (quail-add-unread-command-events):
+ Handle non-vector event arguments. Fixes bug#51118.
+
+2021-10-12 Martin Rudalics <rudalics@gmx.at>
+
+ In Fdelete_other_windows_internal fix new total window sizes (Bug#51007)
+
+ * src/window.c (Fdelete_other_windows_internal): Assign the
+ new total sizes of windows _after_ the new window configuration
+ is in place (Bug#51007).
+
+2021-10-12 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ * lisp/mh-e/mh-show.el (mh-junk-whitelist): Custom obsolescence message.
+
+2021-10-11 João Távora <joaotavora@gmail.com>
+
+ Don't apply shorthands to punctuation-only symbols (bug#51089)
+
+ This includes symbols used for arithmetic functions such as -, /=,
+ etc. Using "-" or "/=" is still possible but doing so won't shadow
+ those functions.
+
+ * doc/lispref/symbols.texi (Shorthand, Exceptions): New
+ subsubsection.
+
+ * src/lread.c (read1): Exempt punctionation-only symbols from
+ oblookup_considering_shorthand.
+
+ * test/lisp/progmodes/elisp-mode-tests.el
+ (elisp-dont-shadow-punctuation-only-symbols): Tweak test.
+
+2021-10-11 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/progmodes/python.el: Bump package version to 0.28.
+
+2021-10-11 Stefan Kangas <stefan@marxist.se>
+
+ Fontify "print" and "exec" as functions in python-mode
+
+ This change was first made on master, but on closer consideration it
+ is better to fix this bug already in Emacs 28.1.
+
+ * lisp/progmodes/python.el (python-font-lock-keywords-level-2):
+ Fontify "print" and "exec" as functions, which is the case in
+ Python 3. (Bug#43298) Do not merge to master.
+
+2021-10-11 Juri Linkov <juri@linkov.net>
+
+ Copy parent face attributes to tab-line-tab-current instead of inheriting face
+
+ * lisp/tab-line.el (tab-line-tab-current): Don't inherit face from
+ 'tab-line-tab' to not inherit the face attribute :height from 'tab-line',
+ because :height of mouse-face is added to the base face.
+ Copy here most of the parent face attributes (bug#50798).
+
+2021-10-11 Martin Rudalics <rudalics@gmx.at>
+
+ Another fix for 'ibuffer-shrink-to-fit' (Bug#7218, Bug#51029)
+
+ * lisp/ibuffer.el (ibuffer-shrink-to-fit): Fit window only if its
+ buffer is in 'ibuffer-mode' (Bug#7218, Bug#51029).
+
+2021-10-11 Michael Albinus <michael.albinus@gmx.de>
+
+ Backport: * doc/misc/tramp.texi (Bug Reports): Describe, how to activate ELPA Tramp.
+
+ (cherry picked from commit 978e5339e0d4ef98575096bcf3ec2061ad530f27)
+
+2021-10-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ Work around GCC bug 102671
+
+ This is for --enable-gcc-warnings on GCC 11.2.1.
+ * src/window.c, src/timefns.c: Disable -Wanalyzer-null-dereference.
+
+2021-10-11 Amin Bandali <bandali@gnu.org>
+
+ Release ERC 5.4
+
+ * lisp/erc/erc.el (Version, erc-version): Bump to 5.4.
+ (customize-package-emacs-version-alist): Add entry for 5.4.
+
+2021-10-11 Amin Bandali <bandali@gnu.org>
+
+ * etc/ERC-NEWS: Announce ERC's addition to GNU ELPA.
+
+ * etc/ERC-NEWS: Fix outline level for the recent additions.
+
+2021-10-11 Amin Bandali <bandali@gnu.org>
+
+ Add ERC entries for 'customize-package-emacs-version-alist'
+
+ * lisp/erc/erc.el (customize-package-emacs-version-alist): Add entries
+ for existing ERC versions.
+
+2021-10-11 Dmitry Gutov <dgutov@yandex.ru>
+
+ Expand the full file name
+
+ * lisp/vc/vc-git.el (vc-git--literal-pathspec):
+ Expand the full file name, not just the local part (bug#51112).
+
+2021-10-11 Stefan Kangas <stefan@marxist.se>
+
+ Obsolete XEmacs compat convention in 'erc-button-press-button'
+
+ * lisp/erc/erc-button.el (erc-button-press-button): Advertise new
+ calling convention without XEmacs compatibility.
+
+2021-10-11 F. Jason Park <jp@neverwas.me>
+
+ Backport: Add ERC version to protocol log
+
+ * lisp/erc/erc.el (erc-toggle-debug-irc-protocol): Include the erc
+ version in the debug logs (bug#51107).
+
+ (cherry picked from commit 13411346202f86e950bee076a5d528e98695fbb4)
+
+2021-10-11 Eli Zaretskii <eliz@gnu.org>
+
+ Adapt the recent 'num_processors' change to MS-Windows
+
+ * nt/gnulib-cfg.mk (OMIT_GNULIB_MODULE_nproc): Omit nproc.
+
+ * src/w32.c (num_processors): New function.
+ * src/w32proc.c (Fw32_get_nproc): Remove.
+
+2021-10-11 Stefan Kangas <stefan@marxist.se>
+
+ Minor fix to clarify a sentence in emacs-lisp-intro
+
+ * doc/lispintro/emacs-lisp-intro.texi (Simple Extension): Add the word
+ "that" for clarity. (Bug#43965)
+
+2021-10-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make tty-run-terminal-initialization load the .elc file (if any)
+
+ * lisp/faces.el (tty-run-terminal-initialization):
+ `locate-library' may have found the .el.gz file (bug#51116).
+
+2021-10-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix ert errors when there's a test that binds `debug-on-error'
+
+ * lisp/emacs-lisp/ert.el (ert--run-test-internal): Don't infloop
+ on errors when signalling errors (bug#51131).
+
+2021-10-10 Paul Eggert <eggert@cs.ucla.edu>
+
+ New function num-processors
+
+ This addresses a FIXME comment in lisp/emacs-lisp/comp.el,
+ relating to the number of subsidiary processes used by
+ comp-run-async-workers in native compilation.
+ * admin/merge-gnulib (GNULIB_MODULES): Add nproc.
+ * doc/lispref/processes.texi (Process Information), etc/NEWS:
+ Document num-processors.
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+ * lib/nproc.c, lib/nproc.h, m4/nproc.m4:
+ New files, copied from Gnulib by admin/merge-gnulib.
+ * lisp/emacs-lisp/comp.el (w32-get-nproc): Remove decl.
+ (comp-effective-async-max-jobs): Use num-processors.
+ * src/process.c: Include nproc.h.
+ (Fnum_processors): New function.
+ (syms_of_process): Define ‘all’, ‘current’, ‘num-processors’.
+ * src/w32proc.c (Fw32_get_nproc): Add FIXME comment.
+ * test/src/process-tests.el (process-num-processors): New test.
+
+2021-10-10 Juri Linkov <juri@linkov.net>
+
+ Add symbol property 'save-some-buffers-function' (bug#46374)
+
+ * lisp/files.el (save-some-buffers-root): Put non-nil
+ symbol property 'save-some-buffers-function'.
+ (save-some-buffers): Check pred for the
+ symbol property 'save-some-buffers-function'.
+ (save-some-buffers-default-predicate): Mention
+ symbol property 'save-some-buffers-function'.
+
+2021-10-10 Juri Linkov <juri@linkov.net>
+
+ Keep reading when typed RET in read-char-from-minibuffer and y-or-n-p
+
+ * lisp/subr.el (read-char-from-minibuffer-map):
+ Remap exit-minibuffer to read-char-from-minibuffer-insert-other.
+ (y-or-n-p-map): Remap 'exit' to y-or-n-p-insert-other.
+ (y-or-n-p): Don't mention RET in docstring. (Bug#51101)
+
+2021-10-10 David M. Koppelman <koppel@ece.lsu.edu>
+
+ * lisp/userlock.el (ask-user-about-supersession-threat): Accept 'y' strictly.
+
+ (Bug#51101)
+
+2021-10-10 Eli Zaretskii <eliz@gnu.org>
+
+ Fix point positioning on mouse clicks with non-zero line-height
+
+ * src/xdisp.c (move_it_to): After passing a newline, reset
+ it->override_ascent, like 'display_line' does (in
+ 'append_space_for_newline'). (Bug#51111)
+
+2021-10-10 João Távora <joaotavora@gmail.com>
+
+ Complete shorthands to longhands for symbol-completing tables
+
+ Shorthands aren't symbols, they're text forms that 'read' into
+ symbols. As such, shorthands aren't candidates in these tables of
+ symbols. But in some situations, if no other candidates match the
+ pattern, we can e.g. complete "x-foo" to "xavier-foo" if the shorthand
+
+ (("x-" . "xavier-"))
+
+ is set up in the buffer of origin.
+
+ bug#50959
+
+ * lisp/help-fns.el (help--symbol-completion-table): Report
+ `symbol-help' category.
+
+ * lisp/minibuffer.el (completion-styles-alist): New 'shorthand'
+ style.
+ (completion-category-defaults): Link 'symbol-help' category with
+ 'shorthand' style.
+ (minibuffer--original-buffer): New variable.
+ (completing-read-default): Setup minibuffer--original-buffer.
+ (completion-shorthand-try-completion)
+ (completion-shorthand-all-completions): New helpers.
+
+2021-10-10 João Távora <joaotavora@gmail.com>
+
+ Add new failing test for bug#51089
+
+ * test/lisp/progmodes/elisp-mode-tests.el
+ (elisp-dont-shadow-punctuation-only-symbols): Add new failing test.
+
+2021-10-10 Dmitry Gutov <dgutov@yandex.ru>
+
+ Avoid mapping file names through 'substring'
+
+ * lisp/progmodes/project.el (project--files-in-directory):
+ Avoid mapping file names through 'substring'. Reducing the amount
+ of garbage generated. Better perf by up to 20%.
+ Bump the package version.
+
+2021-10-09 Kyle Meyer <kyle@kyleam.com>
+
+ Update to Org 9.5-46-gb71474
+
+2021-10-09 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ Expanded testing of MH-E with multiple MH variants
+
+ * test/lisp/mh-e/mh-utils-tests.el: Environment variable TEST_MH_PATH
+ controls which installed MH variant to test with. Moved the commentary
+ about testing with different MH variants from above 'with-mh-test-env'
+ definition to "Commentary" section at the top of the file.
+ * test/lisp/mh-e/test-all-mh-variants.sh: New script to test all
+ installed MH variants.
+
+2021-10-09 Philipp Stephani <phst@google.com>
+
+ Fix Seccomp filter for newer GNU/Linux systems (Bug#51073).
+
+ On some systems, process startup calls prctl(PR_CAPBSET_READ) via
+ 'cap_get_bound'. We can just return EINVAL.
+
+ * lib-src/seccomp-filter.c (main): Add a rule for
+ prctl(PR_CAPBSET_READ, ...).
+
+2021-10-09 Michael Albinus <michael.albinus@gmx.de>
+
+ Tramp code cleanup
+
+ * lisp/net/tramp.el (tramp-remote-path): Adapt docstring.
+ (tramp-action-login, tramp-action-password, tramp-action-yesno)
+ (tramp-action-yn, tramp-process-actions): Move let-binding of
+ `enable-recursive-minibuffers' up.
+ (tramp-handle-make-process, tramp-handle-write-region):
+ * lisp/net/tramp-adb.el (tramp-adb-handle-write-region)
+ (tramp-adb-handle-make-process):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process)
+ (tramp-sh-handle-write-region):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-write-region):
+ * lisp/net/tramp-sshfs.el (tramp-sshfs-handle-write-region):
+ Use `string-or-null-p'.
+
+2021-10-09 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix thinko in ls-lisp--insert-directory
+
+ * lisp/ls-lisp.el (ls-lisp--insert-directory): Ensure that
+ SWITCHES is a string.
+
+2021-10-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention that RET means "yes" in y-or-n-p
+
+ * lisp/subr.el (y-or-n-p): Mention that RET also means yes (bug#51101).
+
+2021-10-09 Eli Zaretskii <eliz@gnu.org>
+
+ Rewrite Antinews for Emacs 28
+
+ * doc/lispref/anti.texi (Antinews):
+ * doc/emacs/anti.texi (Antinews): Rewrite for Emacs 28.
+ * doc/lispref/elisp.texi (Top):
+ * doc/emacs/emacs.texi (Top): Update menu accordingly.
+
+2021-10-09 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/bindings.el (mode-line-position): Improve tooltip.
+
+2021-10-09 Dmitry Gutov <dgutov@yandex.ru>
+
+ * lisp/progmodes/xref.el: Bump the version.
+
+2021-10-09 Dmitry Gutov <dgutov@yandex.ru>
+
+ Slight simplificaiton
+
+ * lisp/progmodes/xref.el (xref--insert-xrefs):
+ Compute log only once. Use 'dolist'.
+
+2021-10-08 Eli Zaretskii <eliz@gnu.org>
+
+ Fix doc strings of 2 categories
+
+ * lisp/international/characters.el (?R, ?L): Make the first line
+ of the categories' doc string shorter, to fit into 15 columns.
+
+2021-10-08 Dmitry Gutov <dgutov@yandex.ru>
+
+ (xref--collect-matches-1): Remove some intermediate allocations
+
+ * lisp/progmodes/xref.el: (xref--collect-matches-1):
+ Rewrite to remove some intermediate allocations.
+ Modest performance improvement.
+
+2021-10-08 Arash Esbati <arash@gnu.org>
+
+ Use the correct label in the warning
+
+ * lisp/textmodes/reftex-toc.el (reftex-toc-rename-label): Add
+ missing space in the prompt. Use the new user defined label in
+ the warning (bug#36235).
+
+2021-10-08 Dmitry Gutov <dgutov@yandex.ru>
+
+ Add Emacs 27 compatibility hack
+
+ * lisp/progmodes/xref.el: Add Emacs 27 compatibility hack, for the
+ standalone version of this package.
+
+2021-10-07 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify GCC 10.3 -Wmaybe-uninitialized
+
+ Problem reported by Basil L. Contovounesios (Bug#51075).
+ * src/term.c (encode_terminal_code):
+ Add an UNINIT to pacify GCC 10 bug.
+
+2021-10-07 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-detach, tab-window-detach): New aliases.
+
+ (tab-bar-mouse-context-menu, tab-bar-duplicate-tab):
+ Use word "clone" in help/doc string.
+
+2021-10-07 Eli Zaretskii <eliz@gnu.org>
+
+ Include the refcards in the release tarball
+
+ * make-dist (possibly_non_vc_files): Include *.pdf files, to
+ include the produced refcards in the tarball. This was lost when
+ 'make-dist' was rewritten for Emacs 27.
+
+2021-10-07 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Backport: * lisp/net/tramp-archive.el (tramp-archive-autoload-file-name-handler): Scope
+
+ Fix the scoping of `tramp-archive-enabled`.
+
+ (cherry picked from commit 8d53c23f90aab6e527c61137ae43274c7a36eca7)
+
+2021-10-07 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation and customization of 'blink-matching-paren'
+
+ * lisp/simple.el (blink-matching-paren): Fix the wording of the
+ doc string and the descriptions in the value menu. (Bug#51032)
+
+2021-10-07 Amin Bandali <bandali@gnu.org>
+
+ * lisp/erc/erc.el: Don't error if 'erc-loaddefs' does not exist.
+
+ That autoload file is created as part of the Emacs compilation
+ process, however we would like ERC to be usable if used outside
+ emacs.git (e.g. if installed from GNU ELPA).
+
+2021-10-07 Amin Bandali <bandali@gnu.org>
+
+ Add 'erc-bug' command for reporting ERC bugs
+
+ * etc/ERC-NEWS: Announce the new command, and mention it at the top of
+ the file along with 'report-emacs-bug'.
+ * lisp/erc/erc.el (erc-bug): New command for reporting ERC bugs. It
+ prompts for a subject, and passes it on to 'report-emacs-bug' along
+ with the current ERC version, with the ERC mailing list in Cc.
+
+2021-10-07 Amin Bandali <bandali@gnu.org>
+
+ Add 'erc-version' and use it to display ERC version consistently
+
+ * lisp/erc/erc.el (erc-version): New constant holding the current ERC
+ version, now used in the function with the same name to produce a
+ version string for use across ERC for consistency. Also, add another
+ optional argument, 'bold-erc', which when non-nil, marks the "ERC"
+ portion of the string with the control character for bold display.
+ (erc-quit/part-reason-default): Use the 'erc-version' function for a
+ consistent version string.
+ (erc-cmd-SV): Mention the ERC version number from the 'erc-version'
+ constant.
+ (erc-ctcp-query-VERSION): Use the 'erc-version' function for a
+ consistent version string.
+
+2021-10-07 Amin Bandali <bandali@gnu.org>
+
+ Small tweaks and improvements to etc/ERC-NEWS
+
+ * etc/ERC-NEWS: Small tweaks inspired by etc/NEWS, namely to add a
+ descriptive blurb at the top of the file to explain what it is about
+ and how to report ERC bugs, add a form feed before the section for
+ every release, and set the same Local Variables that etc/NEWS does.
+
+2021-10-07 Amin Bandali <bandali@gnu.org>
+
+ Add NEWS items for changes to ERC since 5.3 to etc/ERC-NEWS
+
+ * etc/ERC-NEWS: copy ERC NEWS items from etc/NEWS, etc/NEWS.27,
+ etc/NEWS.26, etc/NEWS.25, and etc/NEWS.24 to here. Future ERC NEWS
+ are also to be added here. This is in motivated by preparation for
+ addition of ERC to GNU ELPA, along with the ERC manual and NEWS.
+ * etc/NEWS: remove ERC-related entries, and refer the reader to
+ ERC-NEWS instead.
+
+2021-10-06 Juri Linkov <juri@linkov.net>
+
+ Clone the frame window configuration in 'clone-frame'
+
+ * doc/emacs/frames.texi (Creating Frames): Mention the cloned
+ window configuration for clone-frame.
+
+ * lisp/frame.el (clone-frame): Change second arg to 'no-windows'
+ and clone window configuration when it's nil.
+
+ * lisp/tab-bar.el (tab-bar-mouse-context-menu)
+ (tab-bar-detach-tab): Replace "Detach" with "Move" in help/doc strings.
+
+ https://lists.gnu.org/archive/html/emacs-devel/2021-10/msg00408.html
+
+2021-10-06 Eli Zaretskii <eliz@gnu.org>
+
+ * lisp/tool-bar.el (tool-bar-position): Doc fix.
+
+2021-10-06 Philip Kaludercic <philipk@posteo.net>
+
+ * NEWS: Mention rcirc connects to #emacs by default
+
+2021-10-06 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ Refactor mh-utils-tests macro 'with-mh-test-env'
+
+ * test/lisp/mh-e/mh-utils-tests.el (with-mh-test-env): Refactor to
+ reduce the size of the expanded macro.
+ (mh-test-utils-setup): New helper function.
+ (mh-ensure-native-trampolines): Absorbed by mh-test-utils-setup.
+
+2021-10-05 Stefan Kangas <stefan@marxist.se>
+
+ Avoid using variable before it has been initialized
+
+ * lisp/ibuffer.el (ibuffer-shrink-to-fit): Don't try to use
+ ibuffer-auto-mode variable before ibuf-ext.el has been loaded.
+ (Bug#51029)
+
+2021-10-05 Stefan Kangas <stefan@marxist.se>
+
+ Clarify docstring of blink-matching-paren
+
+ * lisp/simple.el (blink-matching-paren): Clarify
+ docstring. (Bug#51032)
+
+2021-10-05 Stefan Kangas <stefan@marxist.se>
+
+ * doc/misc/gnus.texi (Loose Threads): Use regexp-opt in example.
+
+2021-10-05 Dmitry Gutov <dgutov@yandex.ru>
+
+ Bump project.el version
+
+ * lisp/progmodes/project.el: Bump the version.
+
+2021-10-05 Dmitry Gutov <dgutov@yandex.ru>
+
+ Retain compatibility with older project.el projects
+
+ * lisp/progmodes/xref.el (xref--analyze):
+ Retain compatibility with older project.el and its compatible
+ project definitions (for standalone Xref from ELPA).
+
+2021-10-05 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ native-comp-available-p is the definitive test
+
+ * doc/lispref/compile.texi (Native Compilation): Document
+ native-comp-available-p as the way to test for native compilation.
+ * lisp/emacs-lisp/package.el (package--native-compile-async):
+ * test/lisp/mh-e/mh-utils-tests.el (mh-ensure-native-trampolines):
+ Test for native compilation with native-comp-available-p.
+
+ Thank you to Andrea Corallo for reviewing this patch.
+
+2021-10-05 Eli Zaretskii <eliz@gnu.org>
+
+ Minor fix of a recently installed documentation change
+
+ * doc/emacs/search.texi (Lax Search): Don't use ".." inside @samp,
+ it looks confusing, especially in print. (Bug#51020)
+
+2021-10-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix md5 issue in recent Gnulib merge
+
+ When configured --with-native-compilation, Emacs needs md5_stream.
+ Problem reported by Andy Moreton (Bug#50985#23).
+ * admin/merge-gnulib (GNULIB_MODULES): Add crypto/md5,
+ needed for --with-native-compilation.
+ (AVOIDED_MODULES): Avoid crypto/af_alg, since Emacs doesn’t
+ need to bother with kernel-supported cryptography algorithms.
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4:
+ Regenerate by running admin/merge-gnulib.
+ * lib/md5-stream.c: New file, copied from Gnulib.
+
+2021-10-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Tweak recent 'configure' fix
+
+ * configure.ac (gt_TYPE_WINT_T): Omit obsolete and
+ now-overridden definition.
+
+2021-10-05 Stefan Kangas <stefan@marxist.se>
+
+ Document minibuffer-default-prompt-format in manual
+
+ * doc/emacs/mini.texi (Basic Minibuffer): Mention
+ minibuffer-default-prompt-format. (Bug#50935)
+
+2021-10-05 Eli Zaretskii <eliz@gnu.org>
+
+ Backward compatibility option for 'nobreak-char-display'
+
+ * src/xdisp.c (syms_of_xdisp) <nobreak-char-ascii-display>: New
+ variable.
+ (get_next_display_element): If 'nobreak-char-ascii-display' is
+ non-nil, display non-ASCII space and hyphen characters as their
+ ASCII equivalents. (Bug#50983)
+
+ * etc/NEWS:
+ * etc/PROBLEMS: Mention 'nobreak-char-ascii-display'.
+
+2021-10-05 Eli Zaretskii <eliz@gnu.org>
+
+ Unbreak the build after Gnulib update
+
+ * lib/gnulib.mk.in (GNULIBHEADERS_OVERRIDE_WINT_T): Rename from
+ GNULIB_OVERRIDES_WINT_T.
+ * configure.ac (GNULIBHEADERS_OVERRIDE_WINT_T): Define.
+ (Bug#50985)
+
+2021-10-05 Michael Albinus <michael.albinus@gmx.de>
+
+ Check, whether an FUSE mount has been broken in Tramp
+
+ * lisp/net/tramp-fuse.el (tramp-fuse-mount-timeout): New defconst.
+ (tramp-fuse-mounted-p): Use it. Check for a file property instead
+ of a connection property.
+ (tramp-fuse-unmount): Dito.
+
+ * lisp/net/tramp-sshfs.el (tramp-sshfs-maybe-open-connection):
+ Do not trust existence of a process, whether the volume is mounted.
+
+2021-10-05 Augusto Stoffel <arstoffel@gmail.com>
+
+ Disable 'nobreak-char-display' in Eldoc buffers
+
+ * lisp/emacs-lisp/eldoc.el (eldoc--format-doc-buffer): Set
+ 'nobreak-char-display' to nil in Eldoc buffers (bug#50989).
+
+2021-10-05 Miha Rihtaršič <miha@kamnitnik.top>
+
+ Fix small error in comint-send-input
+
+ * lisp/comint.el (comint-send-input): Run
+ comint-output-filter-functions with comint-last-output-start set
+ correctly (bug#51009).
+
+2021-10-05 Daniel Martín <mardani29@yahoo.es>
+
+ Update documentation of search-whitespace-regexp
+
+ * doc/emacs/search.texi (Lax Search): Update the documentation about
+ the default value of search-whitespace-regexp, as it is now
+ independent of the major mode's syntax table (bug#51020).
+
+2021-10-05 Po Lu via <emacs-devel@gnu.org>
+
+ Fix cc-compat.el syntax error
+
+ * lisp/obsolete/cc-compat.el (offsets): Fix syntax error in BOCM
+ style setup.
+
+2021-10-05 Tak Kunihiro <tkk@misasa.okayama-u.ac.jp>
+
+ Mention `seq-uniq' in `delete-dups' documentation
+
+ * doc/lispref/lists.texi (Sets And Lists): Mention `seq-uniq'
+ (bug#50928).
+
+ * lisp/subr.el (delete-dups): Link to `seq-uniq' in doc string.
+
+2021-10-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port recent Gnulib changes to MS-Windows
+
+ * nt/gnulib-cfg.mk (OMIT_GNULIB_MODULE_free-posix)
+ (OMIT_GNULIB_MODULE_malloc-posix)
+ (OMIT_GNULIB_MODULE_realloc-gnu)
+ (OMIT_GNULIB_MODULE_realloc-posix):
+ New macros, since we don’t want these modules on MS-Windows.
+ * src/w32heap.c (heap_alloc, heap_realloc): New functions.
+ (malloc_after_dump, realloc_after_dump, realloc_before_dump):
+ Use them.
+
+2021-10-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ Make the following changes by hand, and run 'admin/merge-gnulib'.
+ * .gitignore: Add lib/malloc/*.gl.h.
+ * admin/merge-gnulib: Copy lib/af_alg.h and lib/save-cwd.h
+ directly from Gnulib, without worrying about Gnulib modules,
+ as these files are special cases.
+ (AVOIDED_MODULES): Remove malloc-posix.
+ * lib/malloc.c, lib/realloc.c, m4/malloc.m4, m4/realloc.m4:
+ * m4/year2038.m4: New files, copied from Gnulib.
+ * lib/malloca.c, lib/malloca.h:
+ * m4/close-stream.m4, m4/glibc21.m4, m4/malloca.m4:
+ Remove. These are either no longer present in Gnulib, or are no
+ longer needed by modules that Emacs uses.
+ * oldXMenu/AddPane.c, oldXMenu/AddSel.c: Include XmenuInt.h first;
+ needed for new Gnulib.
+ * src/xmenu.c: Call emacs_abort, not abort.
+
+2021-10-04 Andrea Corallo <akrl@sdf.org>
+
+ Fix mh tests for native comp builds (bug#50975)
+
+ * test/lisp/mh-e/mh-utils-tests.el (mh-ensure-native-trampolines):
+ New function.
+ (mh-test-utils-setup-with-mocks)
+ (mh-test-utils-setup-with-variant): Use it.
+
+2021-10-04 Andrea Corallo <akrl@sdf.org>
+
+ Fix `batch-native-compile' not to spawn a subprocess
+
+ * lisp/emacs-lisp/comp.el (comp-running-batch-compilation): New var.
+ (comp-final): Use it.
+ (batch-native-compile): Bind `comp-running-batch-compilation' it.
+
+2021-10-04 Ken Brown <kbrown@cornell.edu>
+
+ Fix native-compilation build from tarball on Cygwin
+
+ * src/Makefile.in (../native-lisp) [CYGWIN]: Rebase the *.eln
+ files after they are all created, to avoid fork problems later in
+ the build. (Bug#50666)
+
+2021-10-04 Robert Pluim <rpluim@gmail.com>
+
+ Remove U+FE0F from script-representative-chars
+
+ * lisp/international/fontset.el (script-representative-chars): Remove
+ U+FE0F / VS-16 from the 'emoji' entry. It could cause us to skip
+ fonts that don't have a glyph for it, even though we don't actually
+ need one.
+
+2021-10-04 Robert Pluim <rpluim@gmail.com>
+
+ Fix problem with 'vertical-motion' and emoji
+
+ * src/font.c (font_range): Pass correct position to
+ font_for_char (Bug#51012).
+
+2021-10-04 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/README: Mention :nativecomp tag.
+
+2021-10-04 Gregory Heytings <gregory@heytings.org>
+
+ Avoid exiting when outputting error messages during loadup
+
+ * src/print.c (print_error_message): Don't call
+ 'substitute-command-keys' when it isn't fboundp.
+
+2021-10-04 Robert Pluim <rpluim@gmail.com>
+
+ Remove implemented emoji items
+
+ * etc/TODO: Remove implemented emoji items.
+
+2021-10-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ project.el NEWS tagging
+
+ thing-at-mouse NEWS tagging
+
+2021-10-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention ffap-file-name-with-spaces in the ffap doc strin
+
+ * lisp/ffap.el (find-file-at-point): Mention
+ ffap-file-name-with-spaces in the doc string.
+
+2021-10-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Make info-look search harder for the Python info file"
+
+ This reverts commit 711eb40b9b9e2aabd0e23ec264e8e8f913329d33.
+
+ This leads to loading info-look being excessively slow if the info path is long. It'll be reimplemented in Emacs 29.
+
+2021-10-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Add safety check in x_menu_show
+
+ * src/xmenu.c (x_menu_show): Explicitly check whether save_wv can
+ be null here. Looks like it can be but I am not 100% sure, so
+ play it safe and add a FIXME comment.
+
+2021-10-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Tweak x_connection_closed when I/O error
+
+ * src/xterm.c (x_connection_closed): Don’t dereference dpyinfo
+ in the unlikely case where it is null and ioerror is true.
+ This pacifies gcc 11.2.1 -Wanalyzer-null-dereference.
+
+2021-10-04 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/erc/erc.el (erc-user-mode): Set "+i" by default.
+
+2021-10-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port unused decls to C2x
+
+ * src/conf_post.h (ATTRIBUTE_UNUSED): Remove. All uses replaced
+ by MAYBE_UNUSED, and moved to start as needed for C2x.
+
+2021-10-04 Stefan Kangas <stefan@marxist.se>
+
+ Improve structure of TODO
+
+ * etc/TODO: Various improvements to the document structure according
+ to discussion with the maintainers.
+
+2021-10-04 Stefan Kangas <stefan@marxist.se>
+
+ Don't use some obsolete names in documentation
+
+ * admin/notes/bugtracker: Use non-obsolete name
+ 'mail-dont-reply-to-names'.
+ * admin/notes/multi-tty: Mention new variable name
+ 'x-selection-value'.
+ * doc/lispintro/emacs-lisp-intro.texi (Point and mark)
+ (Point and mark, Design @value{COUNT-WORDS}): Avoid using obsolete
+ name 'count-lines-region'.
+ * doc/lispref/hooks.texi (Standard Hooks): Remove reference to
+ obsolete abnormal hook 'completion-annotate-function'.
+ * doc/misc/efaq.texi (SPC no longer completes file names): Remove
+ reference to obsolete 'minibuffer-local-filename-must-match-map';
+ setting it has no effect.
+ * doc/misc/gnus.texi (NNTP): Remove reference to obsolete variable
+ 'nntp-authinfo-file'.
+ * doc/misc/reftex.texi (Table of Contents, Creating Citations)
+ (Options - Table of Contents, Options - Referencing Labels)
+ (Options - Creating Citations, Options - Index Support)
+ (Options - Index Support, Changes): Don't use obsolete names.
+ * doc/misc/speedbar.texi (Minor Display Modes)
+ (Major Display Modes): Make variable name suggestions more in line
+ with existing non-obsolete variable.
+ * lisp/textmodes/reftex-cite.el (reftex-select-bib-mode-map):
+ * lisp/textmodes/reftex-ref.el (reftex-offer-label-menu): Don't use
+ obsolete variable names.
+ * lisp/progmodes/which-func.el (which-func-mode): Doc fix.
+
+2021-10-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Tweak x_hide_tip for consistency
+
+ * src/xfns.c (x_hide_tip, Fx_show_tip): Be consistent about using
+ !NILP (tip_frame) instead of FRAMEP (tip_frame). The two
+ expressions are logically equivalent since tip_frame is either a
+ frame or nil, !NILP is a bit faster, and making things consistent
+ pacifies gcc 11.2.1 -Wanalyzer-null-dereference.
+
+2021-10-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Remove encode_terminal_code UNINITs
+
+ * src/term.c (encode_terminal_code): Clarify by removing a couple
+ of UNINITs and testing the local variable ‘cmp’ instead of
+ retesting src->u.cmp.automatic. This pacifies gcc 11.2.1
+ -Wanalyzer-null-dereference.
+
+2021-10-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port pdumper.c maybe_unused to C2x
+
+ Port pdumper.c to C2x, and pacify gcc 11.2.1 -Wattributes -Wunused.
+ * src/pdumper.c (dump_tailq_prepend):
+ Omit ATTRIBUTE_UNUSED, since it’s always used.
+ (dump_tailq_append): Remove; unused.
+
+2021-10-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port systhreads.h to C2x
+
+ * src/systhread.h: Put NODISCARD at the start of extern
+ declarations, not at the end. This is needed by C2x.
+ This patch also pacifies gcc 11.2.1 -Wattributes.
+
+2021-10-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify -Wanalyzer-null-argument in lisp_malloc
+
+ * src/alloc.c (lisp_malloc): Document that NBYTES must be
+ positive, and omit a needless runtime check. This pacifies a
+ false alarm with gcc 11.2.1 -Wanalyzer-possible-null-dereference.
+
+2021-10-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify gcc 11.2.1 -Wanalyzer-null-argument
+
+ * src/gtkutil.c (xg_item_label_same_p): Clarify boolean expression
+ to pacify -Wanalyzer-null-argument with GCC 11.2.1 20210728
+ (Red Hat 11.2.1-1).
+
+2021-10-04 João Távora <joaotavora@gmail.com>
+
+ Simplify hack-read-symbol-shorthands again (bug#50946)
+
+ * lisp/loadup.el (load-source-file-function): Don't set twice.
+
+ * lisp/shorthands.el (hack-read-symbol-shorthands): Simplify.
+ (load-with-shorthands-and-code-conversion): Remove.
+
+ * lisp/international/mule.el (load-with-code-conversion): Call
+ hack-read-symbol-shorthands-function. Set up shorthands.
+ (hack-read-symbol-shorthands-function): New variable.
+
+2021-10-03 Eli Zaretskii <eliz@gnu.org>
+
+ Fix recipe for 'native-lisp' directory
+
+ * src/Makefile.in (../native-lisp): If the directory native-lisp
+ exists, do nothing.
+
+2021-10-03 Paul Eggert <eggert@cs.ucla.edu>
+
+ Simplify socket symlink-attack checking
+
+ This is a minor bugfix cleanup (Bug#33847#161).
+ * lib-src/emacsclient.c: Move "#include <acl.h>" to inside
+ "#ifdef SOCKETS_IN_FILE_SYSTEM", which is more accurate
+ and simpler than having a separate "#ifndef WINDOWSNT".
+ (O_PATH): Likewise.
+
+2021-10-03 Alan Mackenzie <acm@muc.de>
+
+ Clarify (elisp) insert-file-contents with BEG or END not on character boundary
+
+ * doc/lispref/files.texi (Reading from files): When the argument BEG or END to
+ insert-file-contents are at a byte position not at a character boundary,
+ clarify that raw bytes get inserted, and how to handle this awkwardness in
+ Lisp. Also clarify that insert-file-contents-literally is intended to insert
+ raw bytes into the buffer. Fix the outdated example that states it inserts
+ 500 characters, when it actually inserts 500 bytes.
+
+2021-10-03 Andreas Schwab <schwab@linux-m68k.org>
+
+ * src/Makefile.in: Simplify conditionals.
+
+2021-10-03 Juri Linkov <juri@linkov.net>
+
+ Move context-menu selection items Defun/List/Symbol to prog-mode (bug#9054)
+
+ * lisp/mouse.el (context-menu-functions):
+ Add context-menu-middle-separator to choices.
+ (context-menu-region): Move Defun/List/Symbol selection items
+ to prog-context-menu.
+
+ * lisp/progmodes/prog-mode.el (prog-context-menu):
+ Move Defun/List/Symbol selection items from context-menu-region.
+ Include text-mode select menu only in strings and comments.
+
+ * lisp/textmodes/text-mode.el (text-mode-menu): New function.
+ (text-mode): Add text-mode-menu to context-menu-functions.
+
+2021-10-03 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-detach-tab): Handle frame selected by make-frame.
+
+ (tab-bar-move-window-to-tab): New command.
+ (tab-bar-new-tab-to): Handle the value 'window' of tab-bar-new-tab-choice.
+ https://lists.gnu.org/archive/html/emacs-devel/2021-09/msg02197.html
+
+2021-10-03 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-line.el (tab-line-format): Add face-modified to the cache key.
+
+ When tab-line-tab-face-functions contains tab-line-tab-face-modified,
+ add 'buffer-modified-p' status to the cache-key, so the cache will expire
+ when the buffer modification status will change.
+ https://lists.gnu.org/archive/html/emacs-devel/2021-10/msg00129.html
+
+2021-10-03 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix unmounting in Tramp
+
+ * doc/misc/tramp.texi (FUSE setup): Add tramp-fuse-unmount-on-cleanup.
+
+ * lisp/net/tramp.el (tramp-file-name-unify): New defun.
+ (tramp-file-name-equal-p):
+ * lisp/net/tramp-cache.el (tramp-get-connection-property)
+ (tramp-set-connection-property, tramp-flush-connection-property)
+ (tramp-flush-connection-properties): Use it.
+
+ * lisp/net/tramp-fuse.el (tramp-fuse-get-fusermount): New defun.
+ (tramp-fuse-mount-points): New defvar.
+ (tramp-fuse-unmount): Use it. Delete VEC from
+ `tramp-fuse-mount-points'. Delete mount point.
+ (tramp-fuse-unmount-on-cleanup): New user option.
+ (tramp-fuse-cleanup, tramp-fuse-cleanup-all): New defuns.
+ (top): Adapt `tramp-fuse-unload-hook',
+ `tramp-cleanup-connection-hook',
+ `tramp-cleanup-all-connections-hook' and `kill-emacs-hook'.
+
+ * lisp/net/tramp-rclone.el (tramp-rclone-maybe-open-connection):
+ * lisp/net/tramp-sshfs.el (tramp-sshfs-maybe-open-connection):
+ Add VEC to `tramp-fuse-mount-points'.
+
+ * test/lisp/net/tramp-tests.el (tramp-fuse-unmount-on-cleanup): Declare.
+ (tramp-test39-make-lock-file-name): Use it.
+
+2021-10-03 Stefan Kangas <stefan@marxist.se>
+
+ * etc/themes/light-blue-theme.el: Add "Maintainer: emacs-devel".
+
+2021-10-03 Eli Zaretskii <eliz@gnu.org>
+
+ Define HAVE_NATIVE_COMP in src/Makefile.in
+
+ * src/Makefile.in (HAVE_NATIVE_COMP): Define. Reported by Ken
+ Brown <kbrown@cornell.edu>.
+
+2021-10-03 João Távora <joaotavora@gmail.com>
+
+ Rename elisp-shorthands to read-symbol-shorthands
+
+ The new name fits better in the family of variables that affect
+ the Lisp reader.
+
+ Suggested-by: Po Lu <luangruo@yahoo.com>
+
+ * doc/lispref/symbols.texi (Shorthands): Mention read-symbol-shorthands
+
+ * lisp/shorthands.el (hack-read-symbol-shorthands)
+ (hack-read-symbol-shorthands)
+ (shorthands-font-lock-shorthands): Use read-symbol-shorthands
+
+ * lisp/progmodes/elisp-mode.el (elisp--completion-local-symbols)
+ (elisp--completion-local-symbols)
+ (elisp-shorthands): Use read-symbol-shorthands
+
+ * src/lread.c:
+ (syms_of_lread): Define Vread_symbol_shorthands
+ (oblookup_considering_shorthand): Use Vread_symbol_shorthands.
+
+ * test/lisp/progmodes/elisp-mode-tests.el (elisp-shorthand-read-buffer):
+ (elisp-shorthand-read-from-string): Use read-symbol-shorthands
+
+ * test/lisp/progmodes/elisp-mode-resources/simple-shorthand-test.el
+ Use new symbol name read-symbol-shorthands.
+
+2021-10-03 João Távora <joaotavora@gmail.com>
+
+ Font-lock shorthands in elisp-mode for quick visual recognition (bug#50959)
+
+ Only the shorthanded prefix is font-locked. This allows the remainder
+ of the font-lock logic to subsist (e.g. for macro-defining symbols).
+
+ * lisp/shorthands.el (cl-lib): Require it when compiling.
+ (elisp-shorthand-font-lock-face): New face.
+ (shorthands--mismatch-from-end): New helper.
+ (shorthands-font-lock-shorthands): New helper.
+
+ * test/lisp/progmodes/elisp-mode-resources/simple-shorthand-test.el:
+ Add some dummy test code.
+
+2021-10-03 Michael Albinus <michael.albinus@gmx.de>
+
+ Suppress superfluous error messages in Tramp
+
+ * lisp/net/tramp-sshfs.el (tramp-sshfs-handle-insert-file-contents):
+ * lisp/net/tramp.el (tramp-handle-insert-file-contents)
+ (tramp-handle-lock-file): Suppress superfluous error message.
+
+2021-10-03 Eli Zaretskii <eliz@gnu.org>
+
+ Fix reading the tail of a file in shorthands.el
+
+ * lisp/shorthands.el (hack-elisp-shorthands): Fix reading past
+ 3000-character limit from EOF. (Bug#50946)
+
+2021-10-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix substitution of pretty quotes in code in easy-mmode
+
+ * lisp/emacs-lisp/easy-mmode.el (easy-mmode--arg-docstring): Adjust.
+ (easy-mmode--mode-docstring): Avoid making quotes into pretty
+ quotes in code (bug#50968).
+
+2021-10-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix agent directory deletion
+
+ * lisp/gnus/gnus-agent.el (gnus-agent-expire-unagentized-dirs):
+ Delete directories in a simpler way that actually works (bug#50986).
+
+2021-10-03 Stefan Kangas <stefan@marxist.se>
+
+ Clarify the purpose of internal--format-docstring-line
+
+ * test/lisp/subr-tests.el (subr-test-internal--format-docstring-line):
+ * lisp/subr.el (internal--format-docstring-line): Make it more clear
+ that this function is not intended for the first line of a docstring.
+ * lisp/emacs-lisp/cl-macs.el (cl-defstruct): Add comment explaining
+ why we use 'internal--format-docstring-line'.
+ Problem pointed out by Stefan Monnier <monnier@iro.umontreal.ca>.
+
+2021-10-02 Juri Linkov <juri@linkov.net>
+
+ * lisp/net/dictionary.el (context-menu-dictionary): Move menu item down.
+
+ Place the dictionary menu item after middle-separator (bug#50552).
+
+2021-10-02 Kyle Meyer <kyle@kyleam.com>
+
+ Update to Org 9.5-30-g10dc9d
+
+ The plan is to cut the Org 9.5.1 release and include it in Emacs 28.1,
+ but in the meantime regularly sync changes from Org's bugfix branch to
+ emacs-28.
+
+ This sync includes files from Org 9.5's new etc/csl/ directory that
+ should have been synced in bf9ec3d91a (Update to Org 9.5, 2021-09-29).
+
+2021-10-02 Glenn Morris <rgm@gnu.org>
+
+ Remove bogus ":safe t" custom properties
+
+ * lisp/org/oc.el (org-cite-global-bibliography)
+ (org-cite-note-rules, org-cite-punctuation-marks):
+ * lisp/org/oc-csl.el (org-cite-csl-locales-dir)
+ (org-cite-csl-styles-dir, org-cite-csl-no-citelinks-backends):
+ * lisp/org/oc-natbib.el (org-cite-natbib-options):
+ * lisp/org/org-keys.el (org-mouse-1-follows-link):
+ Remove bogus ":safe t" properties that would largely need to be
+ replaced by custom predicates.
+
+2021-10-02 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'apropos-compact-layout'
+
+ * lisp/textmodes/fill.el (fill-region-as-paragraph): Fix filling
+ paragraphs that end at EOB without a newline. (Bug#50974)
+
+2021-10-02 Glenn Morris <rgm@gnu.org>
+
+ Remove bogus ":safe nil" custom properties
+
+ * lisp/org/oc.el (org-cite-activate-processor)
+ (org-cite-export-processors, org-cite-follow-processor)
+ (org-cite-insert-processor):
+ * lisp/org/ol.el (org-link-parameters, org-link-frame-setup)
+ (org-link-shell-confirm-function)
+ (org-link-shell-skip-confirm-regexp)
+ (org-link-elisp-confirm-function)
+ (org-link-elisp-skip-confirm-regexp):
+ * lisp/org/org-num.el (org-num-format-function):
+ Remove bogus ":safe nil" that do nothing but propagate a
+ misunderstanding of the safe-local-variable property.
+
+2021-10-02 Glenn Morris <rgm@gnu.org>
+
+ The safe-local-variable property is a function (bug#50944)
+
+ * lisp/org/oc-basic.el (org-cite-basic-sorting-field)
+ (org-cite-basic-author-year-separator)
+ (org-cite-basic-max-key-distance)
+ (org-cite-basic-author-column-end)
+ (org-cite-basic-column-separator)
+ (org-cite-basic-mouse-over-key-face):
+ * lisp/org/oc-biblatex.el (org-cite-biblatex-options):
+ * lisp/org/oc-csl.el (org-cite-csl-link-cites)
+ (org-cite-csl-html-hanging-indent)
+ (org-cite-csl-html-label-width-per-char)
+ (org-cite-csl-latex-hanging-indent):
+ * lisp/org/oc.el (org-cite-adjust-note-numbers):
+ * lisp/org/org-keys.el (org-return-follows-link):
+ * lisp/org/org.el (org-fontify-todo-headline):
+ * lisp/org/ox-html.el (org-html-equation-reference-format)
+ (org-html-wrap-src-lines):
+ * lisp/org/ox-latex.el (org-latex-reference-command)
+ (org-latex-default-quote-environment):
+ * lisp/textmodes/tildify.el (tildify-pattern)
+ (tildify-space-string): Fix :safe property.
+
+2021-10-02 Stefan Kangas <stefan@marxist.se>
+
+ Revert "; * etc/TODO: Move elpa.gnu.org items to the end."
+
+ This reverts commit d73f0e96a7026808c01861f7525a2909279fc00d.
+
+ These items are a priority for the project and should be before other,
+ less prioritized items, according to a private discussion with project
+ co-maintainer Eli Zaretskii <eliz@gnu.org>.
+
+2021-10-02 Stefan Kangas <stefan@marxist.se>
+
+ Revert "* etc/TODO: Rearrange to start with "Simple tasks"."
+
+ This reverts commit 879ef5b19ab1dd90284aef829ef306d56b4e5adb.
+
+ Some of these items are a priority for the project and should be
+ before other, less prioritized items, according to a private
+ discussion with project co-maintainer Eli Zaretskii <eliz@gnu.org>.
+
+2021-10-02 Eli Zaretskii <eliz@gnu.org>
+
+ Fix selection of fonts for Arabic on Posix platforms
+
+ * lisp/international/fontset.el (script-representative-chars): Add
+ U+06C1 to representative-characters for Arabic. (Bug#50951)
+
+2021-10-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix ox-koma-letter compilation warnings
+
+ * lisp/org/ox-koma-letter.el (org-koma-letter-export-block)
+ (org-koma-letter-export-snippet): Fix warning about two unused
+ parameter.
+
+2021-10-02 Eli Zaretskii <eliz@gnu.org>
+
+ Preload paren.el
+
+ * lisp/Makefile.in (COMPILE_FIRST): Add the dependencies of
+ comp.el, so that they are natively-compiled in advance.
+ * lisp/loadup.el ("paren"): Preload paren.el. (Bug#50934)
+
+2021-10-02 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'shift-select-mode'
+
+ * doc/emacs/mark.texi (Shift Selection): Document the 'permanent'
+ value of 'shift-select-mode'. Add index entry for that variable.
+ (Bug#50954)
+
+ * etc/NEWS: Update the entry for 'shift-select-mode'.
+
+2021-10-02 João Távora <joaotavora@gmail.com>
+
+ Simplify shorthand injection (bug#50946)
+
+ * lisp/loadup.el: Load "shorthands" relatively late. Set
+ load-source-file-function to load-with-shorthands-and-code-conversion
+
+ * lisp/international/mule.el (hack-elisp-shorthands)
+ (load-with-shorthands-and-code-conversion): Move to
+ lisp/shorthands.el
+
+ * lisp/shorthands.el: New file.
+
+2021-10-01 Glenn Morris <rgm@gnu.org>
+
+ * doc/lispref/control.texi (pcase Macro): Fix cross-reference.
+
+2021-10-01 Glenn Morris <rgm@gnu.org>
+
+ Fix some custom types
+
+ * lisp/mpc.el (mpc-cover-image-re):
+ * lisp/org/oc-csl.el (org-cite-csl-locales-dir)
+ (org-cite-csl-styles-dir):
+ * lisp/org/org-plot.el (org-plot/preset-plot-types): Fix :type.
+
+2021-10-01 Stefan Kangas <stefan@marxist.se>
+
+ * etc/TODO: Add interactive mode tagging.
+
+ * etc/TODO: Rearrange to start with "Simple tasks".
+
+ * etc/TODO: Remove outdated item. (Bug#50904)
+
+2021-10-01 Stefan Kangas <stefan@marxist.se>
+
+ Rename arguments of ERC's '/whois' and simplify doc string
+
+ * lisp/erc/erc.el (erc-cmd-WHOIS): Rename arguments and reword the doc
+ string to further clarify and simplify.
+
+2021-09-30 Dmitry Gutov <dgutov@yandex.ru>
+
+ Migrate Xref off EIEIO
+
+ To improve performance and flexibility (bug#50777).
+
+ * lisp/progmodes/xref.el (xref-location): Remove.
+ (xref-file-location): Change to cl-struct.
+ (xref-buffer-location, xref-bogus-location): Ditto.
+ (xref-item, xref-match-item): Same.
+ And update all method definitions accordingly.
+ (xref--insert-xrefs): Don't use 'oref', use 'xref-item-location'.
+ (xref--insert-xrefs, xref-show-definitions-completing-read):
+ Instead of 'with-slots', use 'xref-item-summary' and
+ 'xref-item-location'.
+
+ * lisp/progmodes/etags.el (xref-etags-location):
+ Change from EIEIO class into a cl-struct.
+ (xref-etags-apropos-location): Ditto.
+ Update all method definitions.
+
+ * test/lisp/progmodes/elisp-mode-tests.el (xref-elisp-test-run):
+ Avoid using 'oref'.
+
+2021-09-30 Eli Zaretskii <eliz@gnu.org>
+
+ * admin/release-branch.txt: New file.
+
+ * lisp/dired.el (dired-omit-mode): Declare, to avoid compiler warning.
+
+2021-09-30 Eli Zaretskii <eliz@gnu.org>
+
+ Cut the emacs-28 release branch
+
+ * README:
+ * configure.ac:
+ * nt/README.W32:
+ * msdos/sed2v2.inp: Bump Emacs version to 28.0.60.
+
+ * lisp/cus-edit.el (customize-changed-options-previous-release):
+ Update the last released version of Emacs.
+
+2021-09-30 Nikolay Kudryavtsev <nikolay.kudryavtsev@gmail.com>
+
+ Make checkdoc's docstring substitution consistent with other docs
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-this-string-valid-engine):
+ In error text, say "mapvar" instead of "keymap", and "command"
+ instead of "function", to be consistent with the ELisp manual.
+ (Bug#50903)
+
+2021-09-30 Mattias Engdegård <mattiase@acm.org>
+
+ Fix regexp snags in org
+
+ * lisp/org/org-element.el (org-element-citation-key-re):
+ * lisp/org/ox-org.el (org-org-identity):
+ Remove repeated chars in alternatives.
+ * lisp/org/ob-java.el (org-babel-execute:java):
+ Remove superfluous backslash.
+ * lisp/org/ob-java.el (org-babel-java--main-re)
+ (org-babel-java--any-method-re): Remove (0+ space) expressions
+ subsumed by adjacent expressions.
+
+2021-09-30 Mattias Engdegård <mattiase@acm.org>
+
+ org-element: use correct function
+
+ * lisp/org/org-element.el (org-element-headline-parser):
+ Pretty sure this one should be `skip-chars-backward`, not
+ `skip-syntax-backward`, since \t isn't a valid syntax code.
+
+2021-09-30 Mattias Engdegård <mattiase@acm.org>
+
+ Revert "Indent bodies of local function definitions properly in elisp-mode"
+
+ This reverts commit 38037e04cb05cb1f2b604f0b1602d36b0bcf6985.
+
+2021-09-30 Mattias Engdegård <mattiase@acm.org>
+
+ Revert "Fix regressions in cl-flet indentation"
+
+ This reverts commit c42af5aee74f310bdcd63aac96b1c02ec07a1c50.
+
+2021-09-30 Philip Kaludercic <philipk@posteo.net>
+
+ Add rcirc-omit-unless-requested option
+
+ * doc/misc/rcirc.texi (Notices): Update documentation
+ * lisp/net/rcirc.el (rcirc-pending-requests): Add local variable
+ (rcirc-omit-unless-requested): Add user option
+ (rcirc-print): Respect rcirc-omit-unless-requested
+ (rcirc-define-command): Update rcirc-pending-requests
+
+2021-09-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/org/ob-julia.el: Use lexical-binding
+
+ (ess-eval-visibly-p): Declare.
+ (org-babel-julia-assign-elisp): Remove unused vars `header` and
+ `row-names` and corespondingly remove now unused args `colnames-p` and
+ `rownames-p`.
+ (org-babel-variable-assignments:julia): Adjust call to
+ `org-babel-julia-assign-elisp` accordingly.
+ (org-babel-julia-initiate-session): Use `bound-and-true-p`.
+ (org-babel-julia-evaluate-external-process)
+ (org-babel-julia-evaluate-session, org-babel-julia-evaluate):
+ Remove unused arg `row-names-p`.
+ (org-babel-execute:julia): Adjust call to
+ `org-babel-julia-evaluate` accordingly.
+
+2021-09-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/org/ox-koma-letter.el: Use lexical-binding
+
+ And remove redundant `:group` args.
+
+2021-09-30 Eli Zaretskii <eliz@gnu.org>
+
+ Fix a recent change of 'undo-redo' binding
+
+ * lisp/bindings.el (global-map): Fix the binding of 'undo-redo'.
+ (Bug#50911)
+
+2021-09-30 Eli Zaretskii <eliz@gnu.org>
+
+ Merge Org 9.5 from branch 'origin/scratch/org-sync'.
+
+2021-09-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous `newline' patch
+
+ * lisp/simple.el (newline): Signal an error earlier to avoid
+ peculiar behaviour after getting a backtrace (bug#50900).
+
+2021-09-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `newline' check the argument earlier
+
+ * lisp/simple.el (newline): Signal an error earlier to avoid
+ peculiar behaviour after getting a backtrace (bug#50900).
+
+2021-09-30 akater <nuclearspace@gmail.com>
+
+ Fix regressions in cl-flet indentation
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp--local-defform-body-p):
+ Rename (from -p-less form) and fix indentation regression
+ introduced by 38037e04cb05cb1f2b604f0b1602d36b0bcf6985
+ (bug#9622). Also add cl-macrolet cl-flet* cl-symbol-macrolet.
+
+2021-09-30 dickmao <none>
+
+ Fix bootstrap after recent undo-redo change
+
+ * lisp/bindings.el (global-map): Don't use `kbd' here -- it breaks
+ bootstrap (bug#50911).
+
+2021-09-30 Kyle Meyer <kyle@kyleam.com>
+
+ * etc/NEWS: Announce Org update.
+
+ Update to Org 9.5
+
+2021-09-30 Amin Bandali <bandali@gnu.org>
+
+ Add new '/wii' convenience ERC command
+
+ * etc/NEWS: Announce the addition of the command.
+ * lisp/erc/erc.el (erc-cmd-WII): Add '/wii' convenience command which
+ calls the '/whois' command with the given nick as both arguments,
+ which is useful for displaying the whois information for the nick
+ along with idle time, even if the nick is on a different server than
+ the one we are currently connected to.
+
+2021-09-30 Amin Bandali <bandali@gnu.org>
+
+ Restore the previous order of ERC's '/whois' arguments
+
+ * etc/NEWS: Remove unneeded entry.
+ * lisp/erc/erc.el (erc-cmd-WHOIS): Restore the previous order of
+ arguments sent to the server, so that there's no change in the
+ function's behavior. Instead, rename the arguments to be more
+ accurate, and expand upon them in the doc string.
+
+2021-09-30 Stefan Kangas <stefan@marxist.se>
+
+ New command mpc-goto-playing-song
+
+ * lisp/mpc.el (mpc-goto-playing-song): New command to go to the
+ currently playing song.
+ (mpc-mode-map): Bind it to "o".
+
+2021-09-29 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/linum.el: Recommend `display-line-numbers-mode'.
+
+2021-09-29 Dmitry Gutov <dgutov@yandex.ru>
+
+ Add bindings for 'undo-redo'
+
+ * etc/NEWS: Describe the change.
+
+ * lisp/bindings.el (global-map): Add bindings for 'undo-redo'.
+
+ * lisp/simple.el (undo-no-redo): Turn into a user option.
+
+2021-09-29 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-move-tab-to-frame): Delete frame with last tab.
+
+2021-09-29 Adam Porter <adam@alphapapa.net>
+
+ * lisp/tab-bar.el: (tab-bar-detach-tab) New command
+
+ (tab-bar-detach-tab): New command.
+ (tab-bar-mouse-context-menu): Add menu entry.
+
+ With thanks to Matt Beshara <m@mfa.pw> for his feedback.
+ https://lists.gnu.org/archive/html/emacs-devel/2021-09/msg02141.html
+
+2021-09-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak previous message-newline-and-reformat change
+
+ * lisp/gnus/message.el (message-newline-and-reformat): Only search
+ for previous/next cited lines that have space, because it's the
+ space we're trying to find.
+
+2021-09-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Cross reference `dired-do-revert-buffer'
+
+ * lisp/dired-aux.el (dired-do-copy):
+ (dired-do-symlink):
+ (dired-do-hardlink):
+ (dired-do-rename): Mention `dired-do-revert-buffer'.
+
+2021-09-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Do some NEWS taggin
+
+2021-09-29 Stefan Kangas <stefan@marxist.se>
+
+ * etc/TODO: Delete ImageMagick items. (Bug#50891)
+
+2021-09-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `M-q' in message-mode work better
+
+ * lisp/gnus/message.el (message-newline-and-reformat): Fix
+ bug#43299 differently.
+ (message-newline-and-reformat): Revert change for bug#43299. This
+ fixes bug#50842.
+
+2021-09-29 Stefan Kangas <stefan@marxist.se>
+
+ Force volume to an integer divisible by mpc-volume-step
+
+ * lisp/mpc.el (mpc-volume-mouse-set): Force volume to an integer
+ divisible by 'mpc-volume-step'.
+ (mpc-volume-step): Add docstring.
+
+2021-09-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Signal an error in `search-forward-help-for-help'
+
+ * lisp/help.el (search-forward-help-for-help): Error out instead
+ of showing an empty buffer (bug#50881).
+
+2021-09-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a comment about bug#50877 for gnus-set-difference
+
+2021-09-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Obsolete local set difference functions in favor of seq-difference"
+
+ This reverts commit 20f7fa691b7c2859b96550d9ccb326bf394e160d.
+
+ gnus-set-difference is orders of magnitude faster than seq-difference
+ (on these sets), and using seq-difference makes nnimap too
+ slow.
+
+2021-09-29 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/Makefile.in (WRITE_LOG): Add emacs-module-tests as problematic.
+
+2021-09-29 Protesilaos Stavrou <info@protesilaos.com>
+
+ Update modus-themes to version 1.6.0
+
+ * doc/misc/modus-themes.org (Customization Options): Document new user
+ options in code sample.
+ (Option for inhibiting theme reload): Remove trailing space.
+ (Option for mode line presentation): Include new possible value.
+ (Option for Org agenda constructs): Include new symbols for the
+ 'modus-themes-org-agenda' alist.
+ (Control the scale of headings): Document 'modus-themes-scale-small'.
+ (Override color saturation (DIY)): Fix markup for proper texi output.
+ (Custom Org user faces (DIY)): Update code samples.
+ (Full support for packages or face groups): Note names of newly
+ supported packages or face groups.
+ (Indirectly covered packages): Document indirectly supported packages.
+ (Note on highlight-parentheses.el): Provide detailed instructions on
+ how to use 'highlight-parentheses' with the Modus themes.
+ (Note on prism.el): Refine code samples.
+ (What is the best setup for legibility?): Minor rewording.
+ (Sources of the themes): Mention only Emacs28 without explaining that
+ it is the development target---in preparation of the emacs-28 branch
+ cut.
+ (Acknowledgements): Name new contributors to code/ideas. Stephen
+ Gildea's patch was a couple lines long. The others have assigned
+ copyright to the FSF.
+ (Meta): Include another link to the development notes of the themes
+ about 'modus-themes-org-agenda'.
+
+ * etc/themes/modus-operandi-theme.el,
+ etc/themes/modus-vivendi-theme.el: Bump file version.
+
+ * etc/themes/modus-themes.el (modus-themes-operandi-colors)
+ (modus-themes-vivendi-colors): Recalibrate some colour values and add
+ a few new ones.
+ (modus-themes-slanted-constructs): Remove obsolete user option.
+ Superseded by the alias 'modus-themes-italic-constructs'.
+ (modus-themes-org-agenda, modus-themes-mode-line): Update user option.
+ (modus-themes-scale-headings, modus-themes-scale-4): Update doc
+ string.
+ (modus-themes-scale-5): Remove obsolete user option. Superseded by
+ the alias 'modus-themes-scale-title'.
+ (modus-themes-scale-small, modus-themes-tabs-accented): Add new user
+ option.
+ (modus-themes--agenda-date, modus-themes--mode-line-attrs)
+ (modus-themes--tab): Update internal functions.
+ (modus-themes-faces): Update variousface attributes.
+
+ Detailed change log here:
+ <https://protesilaos.com/codelog/2021-09-29-modus-themes-1-6-0/>.
+
+2021-09-29 Philip Kaludercic <philipk@posteo.net>
+
+ Remove rcirc-omit-responses-after-join option
+
+ The implementation does not work as expected and behaves
+ unpredictably.
+
+ * lisp/net/rcirc.el (rcirc-omit-responses-after-join): Remove
+ option
+ (rcirc-joined): Remove variable
+ (rcirc-reconnect): Remove rcirc-joined code
+ (rcirc-get-buffer-create): Remove rcirc-joined code
+ (rcirc-print): Remove rcirc-omit-responses-after-join check
+ * doc/misc/rcirc.texi (Notices): Remove documentation
+ * etc/NEWS: Remove mention
+
+2021-09-29 Stefan Kangas <stefan@marxist.se>
+
+ New user option mpc-cover-image-re
+
+ * lisp/mpc.el (mpc-cover-image-re): New user option.
+ (mpc-format): Find cover image based on regexp given by above new user
+ option. Treat "folder.png" as a valid cover image name.
+
+2021-09-29 Martin Rudalics <rudalics@gmx.at>
+
+ Fix 'window-toggle-side-windows' (Bug#50867)
+
+ * lisp/window.el (window-toggle-side-windows): Bind
+ 'window-combination-resize' to t around 'window-state-put'
+ calls (Bug#50867).
+
+2021-09-29 Michael Albinus <michael.albinus@gmx.de>
+
+ Some inmprovements in emba CI files
+
+ * test/infra/Dockerfile.emba: Remove superfluous "make -j4".
+
+ * test/infra/gitlab-ci.yml (.test-template): Add 'allow_failure' clause.
+ (test-all-inotify): Add 'needs' clause.
+
+2021-09-29 Juri Linkov <juri@linkov.net>
+
+ * lisp/net/dictionary.el (context-menu-dictionary): Add autoload cookie.
+
+ (context-menu-functions): Remove context-menu-dictionary from hook (bug#50552)
+
+2021-09-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak the whitespace before "This is a generic function"
+
+ * lisp/emacs-lisp/cl-generic.el (cl--generic-describe): Make the
+ number of blank lines before this section consistent (whether
+ there's an indented section before it or not).
+
+2021-09-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the max-specpdl-size doc string
+
+ * src/eval.c (syms_of_eval): Mention what "specpdl" means.
+
+2021-09-29 Amin Bandali <bandali@gnu.org>
+
+ Switch the order of ERC's '/whois' arguments sent to the server
+
+ * lisp/erc/erc.el (erc-cmd-WHOIS): Switch the order of 'server' and
+ 'user' arguments sent to the server. Per RFC 1459 and RFC 2812, the
+ optional 'server' argument command comes before the 'user' argument,
+ not after. While at it, update the doc string to explain why one may
+ want to specify the 'server' argument.
+ * etc/NEWS: Announce the change.
+
+2021-09-29 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/mpc.el (mpc-format): Fix printing after last format spec.
+
+2021-09-29 Amin Bandali <bandali@gnu.org>
+
+ Unobsolete erc-compat.el
+
+ * lisp/obsolete/erc-compat.el: Move from here...
+ * lisp/erc/erc-compat.el: ...back to here. ERC will soon be added to
+ GNU ELPA, and erc-compat.el will be used to provide compatibility
+ functions and/or variables for using ERC on older Emacsen.
+ * etc/NEWS: Remove the previously added obsoletion news item.
+
+2021-09-29 Stefan Kangas <stefan@marxist.se>
+
+ * etc/NEWS: Announce Eshell bookmarks.
+
+2021-09-29 Stefan Kangas <stefan@marxist.se>
+
+ Add bookmark.el support to eww
+
+ * lisp/net/eww.el (eww-bookmark-name, eww-bookmark-make-record)
+ (eww-bookmark-jump): New defuns.
+ (eww-mode): Set up bookmark handler.
+
+2021-09-29 Dmitry Gutov <dgutov@yandex.ru>
+
+ Enable show-paren-mode by default
+
+ * etc/NEWS (https): Mention the change.
+
+ * lisp/paren.el (show-paren-mode):
+ Enable by default, as discussed on emacs-devel.
+
+2021-09-29 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/net/eww.el (eww-mode): Show keybindings in docstring.
+
+2021-09-28 Juri Linkov <juri@linkov.net>
+
+ * lisp/mouse.el (context-menu-map): Fix when menu is a command (bug#50851)
+
+ * lisp/help.el (help--analyze-key): Get information at the position
+ of mouse click such as 'C-h k' on a context menu item (bug#50067).
+
+2021-09-28 Stefan Kangas <stefan@marxist.se>
+
+ Add shortdoc for text properties
+
+ * lisp/emacs-lisp/shortdoc.el (text-properties): New shortdoc.
+
+ e for your changes. Lines starting
+
+2021-09-28 Stefan Kangas <stefan@marxist.se>
+
+ Mention describe-symbol in cl-defstruct docstring
+
+ * lisp/emacs-lisp/cl-macs.el (cl-defstruct): Mention 'describe-symbol'
+ in docstring.
+
+2021-09-28 Stefan Kangas <stefan@marxist.se>
+
+ Mention cl-describe-type in cl-defstruct docstring
+
+ * lisp/emacs-lisp/cl-macs.el (cl-defstruct): Mention
+ 'cl-describe-type' in docstring.
+
+2021-09-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/map.el: Restore compatibility with Emacs-26
+
+ Don't use the new `eql` syntax.
+
+2021-09-28 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt tramp-tests.el for macOS
+
+ * test/lisp/net/tramp-tests.el (tramp-test29-start-file-process)
+ (tramp-test30-make-process): Adapt for macOS.
+
+2021-09-28 Stefan Kangas <stefan@marxist.se>
+
+ * doc/man/emacs.1.in: Add --no-x-resources. (Bug#50855)
+
+2021-09-28 Stefan Kangas <stefan@marxist.se>
+
+ Improve coding conventions for error messages
+
+ * doc/lispref/tips.texi (Programming Tips): Clarify coding
+ conventions for error messages to say that an error message can
+ start with a Lisp symbol. (Bug#50658)
+
+2021-09-28 Stefan Kangas <stefan@marxist.se>
+
+ Improve docstrings of ert-resource-{directory,file}
+
+ * lisp/emacs-lisp/ert-x.el (ert-resource-directory)
+ (ert-resource-file): Improve docstrings.
+
+2021-09-28 Stefan Kangas <stefan@marxist.se>
+
+ Signal error on newline in internal--format-docstring-line
+
+ * lisp/subr.el (internal--format-docstring-line): Signal error
+ when trying to fill a line containing a newline.
+
+ * lisp/cedet/semantic/decorate/mode.el
+ (define-semantic-decoration-style):
+ * lisp/emacs-lisp/easy-mmode.el (define-globalized-minor-mode):
+ Don't pass newlines to 'internal--format-docstring-line'.
+
+2021-09-28 Eli Zaretskii <eliz@gnu.org>
+
+ Make the build of source tarball produce *.eln files
+
+ * lisp/emacs-lisp/comp.el (batch-native-compile): Accept an
+ optional argument; if non-nil, place the .eln file as appropriate
+ for building a source tarball.
+
+ * doc/lispref/compile.texi (Native-Compilation Functions):
+ Document the new optional argument of 'batch-native-compile'.
+
+ * lisp/Makefile.in (.PHONY, $(THEFILE)n) [HAVE_NATIVE_COMP]: New
+ targets.
+
+ * src/Makefile.in (%.eln) [HAVE_NATIVE_COMP]: New recipe.
+ (all) [HAVE_NATIVE_COMP]: Add ../native-lisp to prerequisites.
+ (elnlisp) [HAVE_NATIVE_COMP]: New list of *.eln files.
+ (../native-lisp) [HAVE_NATIVE_COMP]: New recipe.
+
+ * src/verbose.mk.in (AM_V_ELN): New macro.
+
+2021-09-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust ispell-look-command type
+
+ * lisp/textmodes/ispell.el (ispell-look-command): Adjust :type
+ after previous change.
+
+2021-09-28 André A. Gomes <andremegafone@gmail.com>
+
+ Fix search of the look program
+
+ * lisp/textmodes/ispell.el (ispell-look-command): Fix logic
+ concerning the existence of the look program (bug#50852) -- search
+ through the executable path.
+ (ispell-look-p): Adjust logic.
+
+2021-09-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use ert-resource-file in the shorthand tests
+
+ Also move to the standard directory naming.
+
+2021-09-28 Stefan Kangas <stefan@marxist.se>
+
+ checkdoc: Allow Lisp symbols to start a message
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-message-text-engine): Allow
+ Lisp symbols to start a message.
+ (checkdoc--error-bad-format-p): New helper function.
+
+ * test/lisp/emacs-lisp/checkdoc-tests.el
+ (checkdoc-test-error-format-is-good)
+ (checkdoc-test-error-format-is-bad): New helper functions.
+ (checkdoc-tests-error-message-bad-format-p)
+ (checkdoc-tests-error-message-bad-format-p/defined-symbols)
+ (checkdoc-tests-error-message-bad-format-p/not-capitalized):
+ New tests.
+
+2021-09-27 Ken Brown <kbrown@cornell.edu>
+
+ Make .eln files executable on Cygwin
+
+ * Makefile.in (INSTALL_ELN): New variable, equal to $(INSTALL) on
+ Cygwin and $(INSTALL_DATA) on other platforms.
+ (install-eln): Use INSTALL_ELN instead of INSTALL_DATA.
+ (Bug#50818)
+
+2021-09-27 Michael Albinus <michael.albinus@gmx.de>
+
+ Simplify `file-notify--rm-descriptor'
+
+ * lisp/filenotify.el (file-notify--rm-descriptor):
+ Use `file-notify-handle-event'.
+
+2021-09-27 Juri Linkov <juri@linkov.net>
+
+ * lisp/mouse.el (context-menu-region): Check for nil for char-after at eobp.
+
+2021-09-27 Mattias Engdegård <mattiase@acm.org>
+
+ * lisp/progmodes/flymake.el (flymake-menu): Don't use obsolete name.
+
+2021-09-27 Alan Third <alan@idiocy.org>
+
+ Fix GNUstep build failure
+
+ * src/nsfns.m (Fns_hide_emacs): NSRunningApplication is only available
+ in GNUstep 0.27 and above.
+
+2021-09-27 Robert Pluim <rpluim@gmail.com>
+
+ Document 'glyphless-char-display-control' changes
+
+ * etc/NEWS: Document 'glyphless-char-display-control' changes for
+ Variation Selectors.
+
+2021-09-27 Robert Pluim <rpluim@gmail.com>
+
+ Try to be consistent about user options in NEWS
+
+ * etc/NEWS: Try to be consistent about calling 'user options' that
+ instead of 'variables'.
+
+2021-09-27 Alan Third <alan@idiocy.org>
+
+ Fix resizing glitches in NS port (bug#50413)
+
+ * src/nsterm.m ([EmacsView resizeWithOldSuperviewSize:]): Use the
+ superview's size instead of trusting the view's size.
+
+2021-09-27 Alan Third <alan@idiocy.org>
+
+ Attempt to debug a graphical glitch on macOS
+
+ * src/nsterm.m (ns_scroll_run):
+ (ns_shift_glyphs_for_insert): Switch to using NSPoint for destination.
+ ([EmacsView copyRect:to:]): Use NSPoint for the destination, always
+ use the view's layer, and log any questionable copy requests.
+
+2021-09-27 Alan Third <alan@idiocy.org>
+
+ Fix NS toolbar again (bug#50534)
+
+ * src/nsmenu.m (free_frame_tool_bar): Remove toolbar.
+ (update_frame_tool_bar_1): New function.
+ (update_frame_tool_bar): Move most of the functionality to
+ update_frame_tool_bar_1.
+ * src/nsterm.h: Definitions of functions and methods.
+ * src/nsterm.m (ns_update_begin):
+ ([EmacsView windowDidEnterFullScreen]):
+ ([EmacsView windowDidExitFullScreen]): We no longer need to reset the
+ toolbar visibility as that's done when we create the new fullscreen
+ window.
+ ([EmacsWindow initWithEmacsFrame:fullscreen:screen:]): Move the check
+ for undecorated frames into createToolbar:.
+ ([EmacsWindow createToolbar:]): Check whether a toolbar should be
+ created, and run the toolbar update immediately.
+
+2021-09-27 Stefan Kangas <stefan@marxist.se>
+
+ Fix automatic filling of docstring in cl-defstruct
+
+ * lisp/emacs-lisp/cl-macs.el (cl-defstruct): Fix bug where a paragraph
+ was filled as if it were a single line, which led to garbled
+ output in the docstring. (Bug#50839)
+
+ * test/lisp/subr-tests.el
+ (subr-test-internal--format-docstring-line): New test.
+
+2021-09-27 Eli Zaretskii <eliz@gnu.org>
+
+ Minor fix in 'w32-find-non-USB-fonts'
+
+ * lisp/term/w32-win.el (w32--filter-USB-scripts): Handle
+ representative characters given as a vector, not a list.
+
+2021-09-27 João Távora <joaotavora@gmail.com>
+
+ * etc/NEWS (Shorthands for Lisp symbols): Reword.
+
+2021-09-27 Robert Pluim <rpluim@gmail.com>
+
+ Enhance font_range to check for emoji composition triggers
+
+ If the codepoint that triggered composition is from the emoji script,
+ use the emoji font to check the string being composed, rather than the
+ font of the first character of the string. This makes e.g.
+
+ "emoji codepoint with Emoji_Presentation = No followed by VS-16 (FE0F)"
+
+ display the emoji version of the glyph for that codepoint.
+
+ * admin/unidata/blocks.awk: Add VS-1 through VS-16 to the emoji
+ script.
+ * src/composite.c (autocmp_chars): Accept additional argument CH for
+ the codepoint that triggered composition, pass it to font_range.
+ (composition_reseat_it, find_automatic_composition): Pass codepoint
+ that triggered composition to autocmp_chars.
+ * src/font.c (font_range): Accept additional argument CH for the
+ triggering codepoint. If the codepoint is from the 'emoji' script,
+ use Vscript_representative_chars to find the font to use for the
+ composition attempt.
+ (syms_of_font): Add Qemoji symbol.
+ * src/font.h: Update font_range prototype for argument CH.
+ * etc/NEWS: Announce change.
+
+2021-09-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix checkdoc-related test failure
+
+ Fix two doc-related test failures
+
+2021-09-27 Michael Albinus <michael.albinus@gmx.de>
+
+ Optimize emba builds
+
+ * test/infra/Dockerfile.emba (emacs-base): Install also
+ libdbus-1-dev and libacl1-dev.
+
+ * test/infra/gitlab-ci.yml (prep-image-base): Comment out. This
+ stage is activated by default in Dockerfile.emba.
+
+2021-09-27 Eli Zaretskii <eliz@gnu.org>
+
+ Minor stylistic fixes of shorthand code in C
+
+ * src/lread.c (oblookup_considering_shorthand): Now static. Move
+ prototype to where it belongs.
+ (read1, Fintern, Fintern_soft, Funintern)
+ (oblookup_considering_shorthand, syms_of_lread): Fix style of
+ braces and indentation, comments, and doc strings.
+
+2021-09-27 Eli Zaretskii <eliz@gnu.org>
+
+ Minor fixes of Lisp doc strings for shorthands feature
+
+ * lisp/progmodes/elisp-mode.el (obarray-cache)
+ (elisp--completion-local-symbols):
+ * lisp/international/mule.el (hack-elisp-shorthands)
+ (load-with-shorthands-and-code-conversion): Doc string fixes.
+
+2021-09-27 Eli Zaretskii <eliz@gnu.org>
+
+ Minor fixes in documentation of shorthands
+
+ * etc/NEWS:
+ * doc/lispref/symbols.texi (Symbol Components, Creating Symbols)
+ (Shorthands): Improve wording, fix indexing and typos.
+
+2021-09-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make comint understand the ccrypt password phrases
+
+ * lisp/comint.el (comint-password-prompt-regexp): Add the ccrypt
+ confirmation phrase (bug#50837).
+
+ * lisp/international/mule-conf.el (password-word-equivalents): Add
+ the ccrypt phrases.
+
+2021-09-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add "passwd" (change password) prompt to comint
+
+ * lisp/comint.el (comint-password-prompt-regexp): Add "passwd" (to
+ change the password) first promp in Debian bullseye.
+
+2021-09-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Note that the Packaging sub-nodes are mostly for maintainers
+
+ * doc/lispref/package.texi (Packaging): Note that the information
+ is mostly for ELPA maintainers (bug#50825).
+
+2021-09-27 dickmao <none>
+
+ Get a `package-test-signed` to work again
+
+ The test signing key succumbed to either expiration or bitrot.
+ I hope I didn't just publish my secret key to the world.
+
+ * test/lisp/emacs-lisp/package-resources/key.pub: Refresh.
+ * test/lisp/emacs-lisp/package-resources/key.sec: Refresh.
+
+2021-09-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move test-cl-flet-indentation to the right file
+
+2021-09-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve describe-char buffer extremely slightly
+
+ * lisp/descr-text.el (describe-char): Add a colon to further
+ signify that we're talking about the following line (bug#50795).
+
+2021-09-27 João Távora <joaotavora@gmail.com>
+
+ Document shorthands in the Elisp manual section on Symbols
+
+ * doc/lispref/symbols.texi (Symbol Components): Mention "Shorthands".
+ (Creating Symbols): Mention shorthands. Correct references to Common
+ Lisp.
+ (Shorthands): New section.
+
+ * etc/NEWS (Shorthands): New entry.
+
+2021-09-27 João Távora <joaotavora@gmail.com>
+
+ Add #_ reader macro to escape shorthand renaming
+
+ * src/lread.c (read1): Add skip_shorthand variable. Add a '#_'
+ case. If skip_shorthand call oblookup instead of
+ oblookup_considering_shorthand.
+
+ * test/lisp/progmodes/elisp-mode-tests.el
+ (elisp-shorthand-escape): New test.
+
+ * test/lisp/progmodes/elisp-resources/simple-shorthand-test.el
+ (#_f-test4---): New fixture function.
+
+2021-09-27 João Távora <joaotavora@gmail.com>
+
+ Consider shorthands in Elisp's elisp-completion-at-point
+
+ Instead of referencing obarray directly, that function has to consider
+ a collection of completions which includes the shorthand versions of
+ some of the symbols. That collection changes from buffer to buffer,
+ depending on the choice of elisp-shorthands.
+
+ To make this process efficient, and avoid needless recalculation of
+ the above collection, a new obarray-specific cache was invented. The
+ Elisp variable obarray-cache is immediately nullified if something
+ touches the obarray.
+
+ * lisp/progmodes/elisp-mode.el : New helper.
+ (elisp-completion-at-point): Use new helpers.
+ (elisp--completion-local-symbols)
+ (elisp--fboundp-considering-shorthands)
+ (elisp--bboundp-considering-shorthands): New helpers
+
+ * src/lread.c (intern_driver): Nullify Qobarray_cache.
+ (syms_of_lread): Add Qobarray_cache.
+
+ * test/lisp/progmodes/elisp-mode-tests.el
+ (elisp-shorthand-completion-at-point): New test.
+
+ * test/lisp/progmodes/elisp-resources/simple-shorthand-test.el
+ (f-test-complete-me): New fixture.
+
+2021-09-27 João Távora <joaotavora@gmail.com>
+
+ Rework Elisp shorthands to only allow only prefix substitution
+
+ This simplification in requirements makes for more complex C code but
+ that code is much less wasteful in Lisp strings than the previous
+ implementation.
+
+ * src/lread.c (read1): Rework.
+ (Fintern): Rework.
+ (Fintern_soft): Rework.
+ (Funintern): Rework.
+ (oblookup_considering_shorthand): Rewrite.
+
+ * test/lisp/progmodes/elisp-mode-tests.el (elisp-shorthand-read-buffer)
+ (elisp-shorthand-read-from-string): Use new format of
+ elisp-shorthands.
+
+ * test/lisp/progmodes/elisp-resources/simple-shorthand-test.el (f-test)
+ (f-test2, f-test3): Use new form of elisp-shorthands.
+
+2021-09-27 João Távora <joaotavora@gmail.com>
+
+ Move most of the shorthand implementation to C code
+
+ It passes the tests designed for the previous Elisp implementation.
+
+ Likely, this isn't the final form of the implementation. For one, the
+ reader is much slower and allocates a Lisp string for every atom read,
+ regardless if its already interned or not. This has the potential to
+ be catastrophic in terms of GC.
+
+ Also rename the main variable to elisp-shorthands, from the
+ repetitive shorthand-shorthands.
+
+ For some reason, I had to put 'hack-elisp-shorthands' and
+ 'load-with-shorthands-and-code-conversion', the new source-file
+ loading functions, in lisp/international/mule.el.
+
+ Otherwise, lisp/loadup.el wouldn't see them, for some reason that I
+ didn't investigate. This should probably be fixed.
+
+ * lisp/shorthand.el: Remove.
+
+ * test/lisp/shorthand-tests.el: Remove.
+
+ * src/lread.c:
+ (read1, Fintern, Fintern_soft, Funintern): Use
+ oblookup_considering_shorthand.
+ (oblookup_considering_shorthand): New helper.
+ (syms_of_lread): Declare elisp-shorthands.
+
+ * lisp/progmodes/elisp-mode.el (elisp-shorthands):
+ Put a safe-local-variable spec.
+
+ * test/lisp/progmodes/elisp-mode-tests.el (elisp-shorthand-read-buffer)
+ (elisp-shorthand-read-from-string)
+ (elisp-shorthand-byte-compile-a-file)
+ (elisp-shorthand-load-a-file): New tests.
+
+ * test/lisp/progmodes/elisp-resources/simple-shorthand-test.el: New file
+
+ * lisp/loadup.el (load-source-file-function): Set to
+ load-with-shorthands-and-code-conversion.
+
+ * lisp/international/mule.el (hack-elisp-shorthands): Move here.
+ (load-with-shorthands-and-code-conversion): And here.
+
+2021-09-27 João Távora <joaotavora@gmail.com>
+
+ First Elisp version of lisp/shorthand.el, failing some tests
+
+ * lisp/shorthand.el: New file
+
+ * test/lisp/shorthand-tests.el: New file
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ Add 'doc-string' declaration to defcalcmodevar
+
+ * lisp/calc/calc.el (defcalcmodevar): Add 'doc-string' declaration.
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ Move two incorrectly named test files
+
+ * test/lisp/emacs-lisp/tabulated-list-test.el: Move from here...
+ * test/lisp/emacs-lisp/tabulated-list-tests.el: ...to here.
+ * test/lisp/url/url-handlers-test.el: Move from here...
+ * test/lisp/url/url-handlers-tests.el: ...to here.
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ checkdoc: Don't add "Commentary" header to test files
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-file-comments-engine):
+ Don't add "Commentary:" header if it looks like a test file.
+
+2021-09-26 Robert Pluim <rpluim@gmail.com>
+
+ Add glyphless-char-display-control for Variation Selectors
+
+ * lisp/international/characters.el (update-glyphless-char-display):
+ (glyphless-char-display-control): Add control knob for U+FE00 through
+ U+FE0F, defaulting to 'thin-space'.
+ * doc/lispref/display.texi (Glyphless Chars): Document it.
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ Explicitly make the rest of erc-compat.el obsolete
+
+ * lisp/obsolete/erc-compat.el (erc-decode-coding-string)
+ (erc-encode-coding-string, erc-set-write-file-functions)
+ (erc-emacs-build-time, erc-replace-match-subexpression-in-string)
+ (erc-member-if, erc-delete-if, erc-remove-if-not, erc-subseq):
+ Explicitly declare obsolete.
+ (erc-define-minor-mode): Make into obsolete function alias for
+ 'define-minor-mode'.
+ (erc-user-emacs-directory): Make into obsolete variable alias for
+ 'user-emacs-directory'.
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ Add fast-path to ert--explain-string-equal
+
+ * lisp/emacs-lisp/ert.el (ert--explain-string-equal): Add fast-path to
+ avoid doing extra work.
+ Problem reported by Mattias Engdegård <mattiase@acm.org>.
+
+2021-09-26 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/infra/gitlab-ci.yml (variables): Set DOCKER_BUILDKIT.
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ Rename "Homepage" field to "Website" in package description
+
+ * lisp/emacs-lisp/package.el (describe-package-1): Rename
+ "Homepage" field to "Website".
+
+ * test/lisp/emacs-lisp/package-tests.el
+ (package-test-describe-package)
+ (package-test-describe-installed-multi-file-package)
+ (package-test-describe-non-installed-package)
+ (package-test-describe-non-installed-multi-file-package): Update tests.
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ Prefer https for other domains than gnu.org in package URL
+
+ * lisp/emacs-lisp/package.el (describe-package-1): Prefer https for
+ some other common domains in the package URL.
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ Add test for lm-website
+
+ * lisp/emacs-lisp/lisp-mnt.el (lm-website): Use rx.
+ * test/lisp/emacs-lisp/lisp-mnt-tests.el
+ (lm--tests-lm-website): New test.
+
+2021-09-26 Mattias Engdegård <mattiase@acm.org>
+
+ Rx documentation touch-ups (bug#46910)
+
+ * doc/lispref/searching.texi (Rx Constructs, Rx Functions):
+ Add clarifications and improve naming of arguments. Add examples
+ illustrating the differences between `rx` and `rx-to-string`.
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ Warn about overly long docstring in lambda
+
+ * lisp/emacs-lisp/bytecomp.el
+ (byte-compile-docstring-length-warn): Warn about overly long
+ docstring in lambda. (Bug#44858)
+
+ (byte-compile--wide-docstring-p): Improve comment.
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ ("warn-wide-docstring-defun.el"): Update to test for the above new
+ warning.
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ Avoid warning about long docstring lines in defcustom
+
+ * lisp/custom.el (defcustom): Avoid warning about long docstring
+ lines. This was caused by the value of the defcustom being treated as
+ docstring due to it being wrapped in a lambda.
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ Fill some auto-generated docstring lines
+
+ * lisp/cedet/mode-local.el (define-mode-local-override):
+ * lisp/cedet/semantic/decorate/mode.el (define-semantic-decoration-style):
+ * lisp/cedet/semantic/idle.el (define-semantic-idle-service):
+ * lisp/emacs-lisp/derived.el (derived-mode-make-docstring):
+ * lisp/emacs-lisp/eieio.el (defclass): Fill auto-generated docstring
+ lines.
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ Avoid false positives in bytecomp docstring width warning
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile--wide-docstring-p):
+ Ignore more function argument lists.
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (bytecomp-tests-byte-compile--wide-docstring-p): New test.
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ Improve filling of generated docstring lines
+
+ * lisp/subr.el (internal--fill-string-single-line): Improve filling to
+ use full width. Fix bug where line was not wrapped correctly.
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ ert: Add basic explainer for string-equal
+
+ * lisp/emacs-lisp/ert.el (ert--explain-string-equal): Add basic
+ explainer for 'string-equal' based on 'ert--explain-equal'.
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ Unbreak ert tests
+
+ * test/lisp/emacs-lisp/tabulated-list-test.el (tabulated-list-print)
+ (tabulated-list-sort): Update tests for recent change.
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ Doc fix: mode name in local variables needs no suffix
+
+ * doc/emacs/custom.texi (Specifying File Variables): Clarify that a
+ mode name does not need the "-mode" suffix. (Bug#50801)
+
+2021-09-26 Stefan Kangas <stefan@marxist.se>
+
+ checkdoc: Library footer must match package.el requirement
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-file-comments-engine):
+ Don't accept footer format unless it matches the requirement in
+ package.el.
+
+2021-09-26 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt Tramp's make-process for macOS.
+
+ * lisp/net/tramp-sh.el (tramp-check-remote-uname): New defun.
+ (tramp-sh-handle-file-ownership-preserved-p)
+ (tramp-sh-handle-make-process, tramp-find-executable)
+ (tramp-find-shell, tramp-get-remote-stat): Use it. (Bug#50748)
+
+ * test/lisp/net/tramp-tests.el (tramp-check-remote-uname): Declare.
+ (tramp-test29-start-file-process, tramp-test30-make-process):
+ Instrument for macOS.
+ (tramp--test-hpux-p): Adapt function.
+ (tramp--test-macos-p): New defun.
+
+2021-09-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Expand the ` doc string slightly
+
+ * lisp/emacs-lisp/backquote.el (backquote): Note that ` is used
+ for other things in some macros (bug#25462).
+
+2021-09-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix rendering non-ASCII text with links
+
+ * lisp/gnus/mm-view.el (mm-text-html-renderer-alist): Add a new
+ form for links.
+ (mm-links-remove-leading-blank): Make obsolete.
+ (mm-inline-wash-with-file):
+ (mm-inline-render-with-file): Make obsolete -- they were awkwardly
+ defined and only used with links.
+ (mm-inline-render-with-links): New function.
+
+2021-09-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new macro with-environment-variables
+
+ * doc/lispref/os.texi (System Environment): Document it.
+
+ * lisp/env.el (with-environment-variables): New macro.
+
+2021-09-25 Stefan Kangas <stefan@marxist.se>
+
+ Revert "; Fix capitalization of F1..F12 keys in docs"
+
+ This reverts commit fe5b20410f68546821e6c87577d7f826167491dc.
+
+ This change was not correct; these are Lisp symbols that should be in
+ lower-case. Problem reported by Mattias Engdegård <mattiase@acm.org>.
+
+2021-09-25 Stefan Kangas <stefan@marxist.se>
+
+ Revert part of previous doc fix
+
+ * lisp/emacs-lisp/derived.el (define-derived-mode): Revert part of
+ previous doc fix. This change made the text confusing. (Bug#17567)
+
+2021-09-25 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-new-tab-to): Use ignore-window-parameters.
+
+ Suggested by Adam Porter <adam@alphapapa.net> in
+ https://lists.gnu.org/archive/html/emacs-devel/2021-09/msg01758.html
+
+2021-09-25 Adam Porter <adam@alphapapa.net>
+
+ * lisp/tab-line.el: Add modified-buffer face
+
+ (tab-line-tab-modified): New face.
+ (tab-line-tab-face-modified): New function.
+ (tab-line-tab-face-functions): Use new function.
+
+ * etc/NEWS: Update.
+
+2021-09-25 Mattias Engdegård <mattiase@acm.org>
+
+ Fix byte-compiler crash for legal dynamic-binding code
+
+ This should really be taken care of by a syntax normalisation step in
+ the frontend, but there is no such step for non-lexbind code yet.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-letX): Tolerate bindingsa
+ without initialising expressions.
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases):
+ Add test cases.
+
+2021-09-25 Mattias Engdegård <mattiase@acm.org>
+
+ Constant-propagate variables bound outside loops
+
+ Previously, variables bound outside `while` loops were not substituted
+ inside even in the absence of mutation. Add the necessary mutation
+ checking inside loops to allow propagation of values and aliased
+ variables.
+
+ * lisp/emacs-lisp/byte-opt.el
+ (byte-optimize--inhibit-outside-loop-constprop): New variable.
+ (byte-optimize-form-code-walker): First traverse each loop without
+ substitution to discover mutation, then without restrictions.
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-test-loop): New.
+ (bytecomp-tests--test-cases): Add test cases.
+
+2021-09-25 Mattias Engdegård <mattiase@acm.org>
+
+ Use ambient lexical-binding value in ert-deftest body (bug#50738)
+
+ * lisp/emacs-lisp/ert.el (ert-deftest):
+ Evaluate the body of `ert-deftest` with the `lexical-binding` value of
+ the source file (or more precisely the value in force when the
+ definition is evaluated), which is what everyone expected, instead of
+ always using dynamic binding which is what they got until now.
+ * test/lisp/emacs-lisp/ert-tests.el
+ (ert-test-deftest-lexical-binding-t): New test.
+
+2021-09-25 Mattias Engdegård <mattiase@acm.org>
+
+ Renege on anonymous &rest (bug#50268, bug#50720)
+
+ Allowing &rest without a variable name following turned out not to be
+ very useful, and it never worked properly. Disallow it.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-check-lambda-list):
+ * src/eval.c (funcall_lambda):
+ Signal error for &rest without variable name.
+ * doc/lispref/functions.texi (Argument List): Adjust manual.
+ * etc/NEWS (file): Announce.
+ * test/src/eval-tests.el (eval-tests--bugs-24912-and-24913):
+ Extend test, also checking with and without lexical binding.
+ (eval-tests-accept-empty-optional-rest): Reduce to...
+ (eval-tests-accept-empty-optional): ...this, again checking
+ with and without lexical binding.
+
+2021-09-25 Stefan Kangas <stefan@marxist.se>
+
+ Clarify define-derived-mode docstring
+
+ * lisp/emacs-lisp/derived.el (define-derived-mode): Doc fixes;
+ correctly mention that the mode name is used in the mode line, clarify
+ argument types, and how the mode hook is named. (Bug17567)
+
+ (derived-mode-hook-name, derived-mode-map-name)
+ (derived-mode-syntax-table-name, derived-mode-abbrev-table-name):
+ Clarify that argument is a symbol.
+
+2021-09-25 Philip Kaludercic <philipk@posteo.net>
+
+ Add myself as rcirc maintainer
+
+ * lisp/net/rcirc.el (rcirc-sentinel): Use process-status
+
+ * doc/misc/rcirc.texi (Using rcirc with bouncers): Remove confusing sentence
+
+ * lisp/net/rcirc.el (rcirc-reconnect): Use rcirc-reconnect-delay
+
+ * lisp/net/rcirc.el (rcirc-reconnect): Set rcirc-joined
+
+2021-09-25 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/isearch.el (isearch-forward-regexp): Doc fix. (Bug22483)
+
+2021-09-25 Stefan Kangas <stefan@marxist.se>
+
+ Minor clarification of define-minor-mode :keymap argument
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Minor doc fix;
+ clarify by saying that ":keymap" should be an "unquoted variable
+ name". (Bug#25505)
+
+2021-09-25 Stefan Kangas <stefan@marxist.se>
+
+ Buttonize functions in curved quotes in ERC
+
+ * lisp/erc/erc-button.el (erc-button-alist): Buttonize Emacs
+ functions in curved quotes. (Bug#49964)
+
+2021-09-25 Stefan Kangas <stefan@marxist.se>
+
+ Extend and improve ERT manual section on running interactively
+
+ * doc/misc/ert.texi (Running Tests Interactively): Format commands in
+ a table, improve indexing, and add several missing
+ commands. (Bug#41829)
+
+2021-09-25 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ Update mh-scan regexp to match mh-note-allowlisted
+
+ lisp/mh-e/mh-scan.el (mh-scan-good-msg-regexp, mh-scan-cmd-note-width):
+ Update to match new value ("A") of mh-note-allowlisted.
+
+2021-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document the new paren-space indentation rule
+
+ * doc/emacs/programs.texi (Lisp Indent): Mention the new
+ paren-space indentation rule.
+
+2021-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Some NEWS tagging
+
+2021-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ 'xref-search-program'-related doc string fixes
+
+ * lisp/progmodes/xref.el (xref-search-program): Mention what this
+ variable controls.
+ (xref-matches-in-files): Mention the variables that controls it.
+
+2021-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document the 'string' thingatpt target
+
+ * doc/lispref/text.texi (Buffer Contents): Mention the 'string'
+ target.
+
+2021-09-25 Eli Zaretskii <eliz@gnu.org>
+
+ Fix cursor motion around some Emoji sequences
+
+ * src/character.h: Add TAG_SPACE and CANCEL_TAG to known Unicode
+ characters values.
+ * src/composite.c (char_composable_p): Recognize TAG characters
+ relevant to Emoji as composable regardless of their General
+ Category. (Bug#39799)
+
+2021-09-25 Eli Zaretskii <eliz@gnu.org>
+
+ Use explicit man-page section in references
+
+ * lisp/dired-aux.el (dired-do-chmod): Use explicit man-page
+ section in the doc string. This avoids inadvertently showing
+ the wrong man page, when several identically-named pages are
+ possible in different sections. E.g., there's also chmod(2).
+
+2021-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ save-some-buffers-root doc string change
+
+ * lisp/files.el (save-some-buffers-root): Improve doc string.
+
+2021-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Do some NEWS tagging
+
+2021-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document redisplay-skip-fontification-on-input
+
+ * doc/emacs/display.texi (Scrolling): Mention
+ redisplay-skip-fontification-on-input.
+
+2021-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new user option ispell-help-timeout
+
+ * lisp/textmodes/ispell.el (ispell-help-timeout): New user option.
+ (ispell-help): Use it.
+
+2021-09-25 Stefan Kangas <stefan@marxist.se>
+
+ Set :type of suggest-key-bindings to natnum
+
+ * lisp/simple.el (suggest-key-bindings): Set :type to
+ natnum. (Bug#15809)
+
+2021-09-25 Stefan Kangas <stefan@marxist.se>
+
+ New :type natnum for defcustom
+
+ * lisp/wid-edit.el (natnum): New widget type. (Bug#15809)
+ * doc/lispref/customize.texi (Simple Types): Document it.
+
+2021-09-25 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/dired-aux.el (dired-do-chmod): Simplify docstring.
+
+2021-09-25 Stefan Kangas <stefan@marxist.se>
+
+ Add support for man page hyperlinks in doc strings
+
+ * lisp/help-mode.el (help-man): New button type.
+ (help-xref-man-regexp): New const.
+ (help-make-xrefs): Use them to allow making man page buttons.
+ * doc/lispref/tips.texi (Documentation Tips): Document the new
+ hyperlink type. (Bug#39215)
+
+2021-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix some instances in the Emacs manual with misleading prefix syntax
+
+ * doc/emacs/msdos.texi (Windows Keyboard):
+ * doc/emacs/misc.texi (Editing Binary Files):
+ * doc/emacs/macos.texi (Mac / GNUstep Events):
+ * doc/emacs/kmacro.texi (Basic Keyboard Macro):
+ * doc/emacs/glossary.texi (Glossary):
+ * doc/emacs/fixit.texi (Spelling): Fix some instances where the
+ syntax seems to imply we're talking about a prefix key (bug#50792).
+
+2021-09-25 Manuel Giraud <manuel@ledu-giraud.fr>
+
+ Make 'C-u C-x v v' handle unregistered files.
+
+ * lisp/vc/vc.el (vc-next-action): Make 'C-u C-x v v' handle
+ unregistered files (bug#50602).
+
+2021-09-25 Daniel Martín <mardani29@yahoo.es>
+
+ Mention the 'r' key in ask-user-about-supersession-help
+
+ * lisp/userlock.el (ask-user-about-supersession-help): Replace "n, and
+ then M-x revert-buffer" in the help message with "r", which does the
+ same thing. (Bug#50780)
+
+2021-09-25 akater <nuclearspace@gmail.com>
+
+ Indent bodies of local function definitions properly in elisp-mode
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-indent-function): Check for
+ local defforms (`cl-flet' and `cl-labels').
+ (lisp--local-defform-body): New auxiliary function (bug#9622).
+
+2021-09-25 Stefan Kangas <stefan@marxist.se>
+
+ Clarify where to find CONTRIBUTE
+
+ * doc/emacs/trouble.texi (Contributing): Say that CONTRIBUTE is
+ found in the development version of Emacs. (Bug#37414)
+
+2021-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use gzip to uncompess .xz files on MacOS
+
+ * lisp/jka-cmpr-hook.el (jka-compr-compression-info-list): Use
+ gzip to uncompess .xz files on MacOS (bug#29235).
+
+2021-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use `temporary-file-directory' in `with-existing-directory'
+
+ * lisp/subr.el (with-existing-directory): Use
+ `temporary-file-directory' over TMPDIR.
+
+2021-09-25 Stefan Kangas <stefan@marxist.se>
+
+ Fix alignment on font size change in tabulated-list-mode
+
+ * lisp/emacs-lisp/tabulated-list.el (tabulated-list-print-col): Fix
+ bug where the columns didn't align correctly when using
+ 'text-scale-mode' to decrease the font size. (Bug#48639)
+
+2021-09-25 Stefan Kangas <stefan@marxist.se>
+
+ Doc fix; cl-random is only pseudo-random
+
+ * lisp/emacs-lisp/cl-extra.el (cl-random): Doc fix; say it's only
+ pseudo-random.
+
+2021-09-24 Stefan Kangas <stefan@marxist.se>
+
+ checkdoc: Don't ask to disambiguate mode names
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-this-string-valid-engine):
+ Don't ask to disambiguate mode names. (Bug#4110)
+
+2021-09-24 Stefan Kangas <stefan@marxist.se>
+
+ Fix recently introduced bug in checkdoc
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-in-abbreviation-p): Fix
+ recently introduced bug where some abbreviations weren't recognized.
+ * test/lisp/emacs-lisp/checkdoc-tests.el
+ (checkdoc-tests-in-abbrevation-p/basic-case): Extend test.
+
+2021-09-24 Stefan Kangas <stefan@marxist.se>
+
+ Revert change to use seq-random-elt in Tramp test
+
+ * test/lisp/net/tramp-tests.el (tramp-test44-asynchronous-requests):
+ Revert change to use seq-random-elt, as Tramp needs to be compatible
+ with Emacs 25, and the function was only added in 26.1.
+
+2021-09-24 Stefan Kangas <stefan@marxist.se>
+
+ checkdoc: Improve wide line warning to decrease false positives
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-this-string-valid-engine):
+ Respect 'byte-compile-docstring-max-column' if it is set. Allow the
+ first line to be three characters longer than the others to account
+ for indentation and the opening string character.
+
+2021-09-24 Stefan Kangas <stefan@marxist.se>
+
+ Use command substitution instead of raw keys in more places
+
+ * admin/authors.el (authors):
+ * lisp/abbrev.el (abbrev-suggest-show-report):
+ * lisp/calc/calc.el (calc-display-trail, calc):
+ * lisp/completion.el (completion-locate-db-error):
+ * lisp/dired-x.el (dired-extra-startup):
+ * lisp/emacs-lisp/package.el (package-install-selected-packages):
+ * lisp/emulation/viper.el (viper-mode):
+ * lisp/facemenu.el (list-colors-display):
+ * lisp/mail/emacsbug.el (report-emacs-bug-hook):
+ * lisp/mail/sendmail.el (mail):
+ * lisp/menu-bar.el (menu-bar-mode):
+ * lisp/org/org.el (org-revert-all-org-buffers):
+ * lisp/progmodes/antlr-mode.el (antlr-help-rules-intro)
+ (antlr-insert-makefile-rules):
+ * lisp/progmodes/gdb-mi.el (gdb--check-interpreter):
+ * lisp/progmodes/xscheme.el (xscheme-process-sentinel):
+ * lisp/ps-print.el (ps-font-info-database):
+ * lisp/recentf.el (recentf-edit-list, recentf-open-files):
+ * lisp/vc/ediff-util.el (ediff-suspend):
+ * lisp/vc/pcvs.el (cvs-mode):
+ * lisp/vc/vc-bzr.el (vc-bzr-dir-extra-headers): Use command
+ substitution.
+
+2021-09-24 Stefan Kangas <stefan@marxist.se>
+
+ Prefer seq-random-elt to nth+random
+
+ * lisp/emacs-lisp/seq.el (seq-random-elt): Autoload.
+ * lisp/avoid.el (mouse-avoidance-random-shape):
+ * lisp/epa-ks.el (epa-ks--query-url):
+ * lisp/erc/erc-networks.el (erc-server-select):
+ * lisp/gnus/gnus-fun.el (gnus--random-face-with-type)
+ (gnus-fun-ppm-change-string):
+ * lisp/net/soap-inspect.el (soap-sample-value-for-xs-simple-type):
+ * lisp/obsolete/landmark.el (landmark-random-move):
+ * lisp/play/mpuz.el (mpuz-build-random-perm):
+ * lisp/play/zone.el (zone-pgm-stress):
+ * lisp/vc/add-log.el (add-change-log-entry):
+ * test/lisp/net/tramp-tests.el
+ (tramp-test44-asynchronous-requests): Prefer seq-random-elt to
+ nth+random.
+
+2021-09-24 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix auto-revert-test05-global-notify
+
+ * test/lisp/autorevert-tests.el (auto-revert-test05-global-notify):
+ Adapt test for killed buffer.
+
+2021-09-24 Robert Pluim <rpluim@gmail.com>
+
+ Generate skin tone compositions from emoji-sequences.txt
+
+ Read skin tone modifier sequences from emoji-sequences.txt and add
+ them to the per-character composition rules derived from
+ emoji-zwj-sequences.txt, rather than adding them as lookback rules for
+ the skin tone modifiers. This avoids an issue with the application of
+ such lookback rules. See Bug#39799,
+ specifically
+ <https://lists.gnu.org/archive/html/bug-gnu-emacs/2021-09/msg01878.html>
+ for more details.
+
+ * admin/unidata/Makefile.in (zwj): Add emoji-sequences.txt as a dependency.
+ * admin/unidata/emoji-zwj.awk: Match RGI_Emoji_ZWJ_Sequence and
+ RGI_Emoji_Modifier_Sequence. Remove manual addition of skin tone
+ composition rules with lookback.
+
+2021-09-24 Robert Pluim <rpluim@gmail.com>
+
+ Add a few more missing emoji overrides
+
+ * admin/unidata/blocks.awk: Add some more emoji overrides.
+
+2021-09-24 Robert Pluim <rpluim@gmail.com>
+
+ Move compose-gstring-for-variation-glyph
+
+ It logically belongs in composite.el, not japanese.el
+
+ * lisp/language/japanese.el (compose-gstring-for-variation-glyph):
+ Remove from here.
+ * lisp/composite.el (compose-gstring-for-variation-glyph): And add here.
+
+2021-09-24 Robert Pluim <rpluim@gmail.com>
+
+ Update provenance comment in charscript.el
+
+ * admin/unidata/blocks.awk: Update comment about sources used to
+ generate charscript.el.
+
+2021-09-24 Juri Linkov <juri@linkov.net>
+
+ * lisp/gnus/mm-uu.el (mm-uu-type-alist): Add markdown-diff/-emacs-sources
+
+ (Bug#50763)
+
+2021-09-24 Juri Linkov <juri@linkov.net>
+
+ New thing-at-point target 'string' used in context-menu-region
+
+ * lisp/mouse.el (context-menu-region): Use separate "List" and "String".
+
+ * lisp/thingatpt.el (string): New target 'string'.
+ (thing-at-point-bounds-of-string-at-point): New function.
+ (thing-at-point-bounds-of-list-at-point): Revert previous commit
+ by removing optional args 'escape-strings' and 'no-syntax-crossing'.
+ (list-or-string): Remove recently added target 'list-or-string'.
+ (thing-at-point-bounds-of-list-or-string-at-point): Remove function.
+ https://lists.gnu.org/archive/html/emacs-devel/2021-09/msg01737.html
+
+2021-09-24 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Pacify recent warnings in ansi-color-tests.el
+
+ * test/lisp/ansi-color-tests.el: Remove invalid package keyword
+ 'ansi', and unused dependency on cl-lib.
+ (yellow, bright-yellow): Replace prefix-less dynvars with
+ corresponding local lexvars.
+ (test-strings): Rename prefix-less dynvar...
+ (ansi-color-tests--strings): ...to this. All users updated.
+ (ansi-color-apply-on-region-test)
+ (ansi-color-apply-on-region-bold-is-bright-test): Simplify.
+ (ansi-color-apply-on-region-preserving-test): Reindent.
+
+2021-09-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add `info-lookup-symbol' to the menu
+
+ * lisp/menu-bar.el (menu-bar-search-documentation-menu): Add entry
+ for `info-lookup-symbol' (bug#50759).
+
+2021-09-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add s Symbol entry in the glossary
+
+ * doc/emacs/glossary.texi (Glossary): Add an entry for Symbol
+ (bug#50760).
+
+2021-09-23 Konstantin Kharlamov <Hi-Angel@yandex.ru>
+
+ Do not count git markers as "deleted lines"
+
+ * lisp/vc/diff-mode.el (diff-fixup-modifs): Skip "end of patch"
+ markers that `git-format-patch` leaves around (bug#50761).
+
+2021-09-23 Miha Rihtaršič <miha@kamnitnik.top>
+
+ Fix problems with 'C-c C-n' in sh-script-mode
+
+ * lisp/progmodes/sh-script.el (sh-shell-process): If a *shell* buffer
+ doesn't exist, 'C-c C-n' creates one and displays it. This patch
+ prevents it from being displayed in the selected window.
+ Additionally, it ensures that the local `sh-shell-process' variable is
+ set in the correct buffer (bug#50765).
+
+2021-09-23 Stefan Kangas <stefan@marxist.se>
+
+ checkdoc: Add abbreviation and simplify
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-in-abbreviation-p): Add
+ abbreviation "a.k.a.". Simplify.
+
+2021-09-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix typo in previous man.el change
+
+ * lisp/man.el (Man-ansi-color-map): Fix typo in last checkin.
+
+2021-09-23 Jim Porter <jporterbugs@gmail.com>
+
+ Add support for "bright" ANSI colors in term-mode
+
+ * lisp/term.el (ansi-term-color-vector): Add new faces.
+ (term-color-black, term-color-red, term-color-green, term-color-yellow)
+ (term-color-blue, term-color-magenta, term-color-cyan, term-color-white):
+ Inherit from 'ansi-color-COLOR'.
+ (term-color-bright-black, term-color-bright-red, term-color-bright-green)
+ (term-color-bright-yellow, term-color-bright-blue)
+ (term-color-bright-magenta, term-color-bright-cyan)
+ (term-color-bright-white): New faces.
+ (term--maybe-brighten-color): New function.
+ (term-handle-colors-array): Handle bright colors.
+ * test/lisp/term-tests.el (term-colors, term-colors-bold-is-bright):
+ New functions.
+
+2021-09-23 Jim Porter <jporterbugs@gmail.com>
+
+ Add support for "bright" ANSI colors in ansi-color
+
+ * lisp/ansi-color.el (ansi-color-bold, ansi-color-faint, ansi-color-italic)
+ (ansi-color-underline, ansi-color-slow-blink, ansi-color-fast-blink)
+ (ansi-color-inverse, ansi-color-red, ansi-color-green, ansi-color-yellow)
+ (ansi-color-blue, ansi-color-magenta, ansi-color-cyan, ansi-color-white)
+ (ansi-color-bright-red, ansi-color-bright-green, ansi-color-bright-yellow)
+ (ansi-color-bright-blue, ansi-color-bright-magenta, ansi-color-bright-cyan)
+ (ansi-color-bright-white): New faces.
+ (ansi-color-basic-faces-vector, ansi-color-normal-colors-vector)
+ (ansi-color-bright-colors-vector): New constants.
+ (ansi-color-faces-vector, ansi-color-names-vector): Make obsolete.
+ (ansi-color-bold-is-bright): New defcustom.
+ (ansi-color--find-face): Sort ANSI codes and check
+ 'ansi-color-bold-is-bright'.
+ (ansi-color-apply-sequence): Support bright ANSI colors.
+ (ansi-color-make-color-map, ansi-color-map, ansi-color-map-update):
+ Make obsolete.
+ (ansi-color-get-face-1): Add BRIGHT parameter.
+ * lisp/man.el (Man-ansi-color-basic-faces-vector): New variable.
+ (Man-ansi-color-map): Make obsolete.
+ (Man-fontify-manpage): Use 'Man-ansi-color-basic-faces-vector' here.
+ * test/lisp/ansi-color-tests.el
+ (ansi-color-apply-on-region-bold-is-bright-test): New function.
+
+2021-09-23 Stefan Kangas <stefan@marxist.se>
+
+ Avoid jumping too far in checkdoc-in-abbreviation-p
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-in-abbreviation-p): Use
+ 'forward-ward' instead of 'forward-sexp' to avoid jumping too far in
+ some situations. (Bug#50731)
+
+ * test/lisp/emacs-lisp/checkdoc-tests.el
+ (checkdoc-tests--abbrev-test): New helper function.
+ (checkdoc-tests-in-abbrevation-p/basic-case): Rename from
+ 'checkdoc-tests-in-abbrevation-p'.
+ (checkdoc-tests-in-abbrevation-p/with-parens)
+ (checkdoc-tests-in-abbrevation-p/with-escaped-parens): Use above new
+ helper function.
+ (checkdoc-tests-in-abbrevation-p/single-char)
+ (checkdoc-tests-in-abbrevation-p/with-em-dash)
+ (checkdoc-tests-in-abbrevation-p/incorrect-abbreviation): New tests.
+
+2021-09-23 Philip Kaludercic <philipk@posteo.net>
+
+ Handle updates flags when setting flags
+
+ * lisp/gnus/nnmaildir.el (nnmaildir--article-set-flags): Handle
+ updated flags more gracefully.
+
+2021-09-23 Dmitry Gutov <dgutov@yandex.ru>
+
+ A bit less overhead when converting hits
+
+ * lisp/progmodes/xref.el (xref--collect-matches):
+ Move 'remote-id' and 'syntax-needed' definitions to the caller
+ function. Bind 'inhibit-modification-hooks' to t (bug#50733).
+
+2021-09-23 Dmitry Gutov <dgutov@yandex.ru>
+
+ More per-match overhead reduction
+
+ * lisp/progmodes/xref.el (xref--show-common-initialize)
+ (xref-revert-buffer): Inhibit modification hooks (bug#50733).
+ (xref--insert-xrefs): Cosmetics (no measurable difference here).
+
+2021-09-23 Dmitry Gutov <dgutov@yandex.ru>
+
+ xref-matches-in-files: Decrease per match and per group overhead
+
+ * lisp/progmodes/xref.el (xref-search-program-alist):
+ Add '--null' argument for slightly faster parsing and probably
+ better behavior with weirder file names.
+ (xref--alistify): Don't accept TEST argument, use 'assoc' instead
+ of 'cl-assoc', use a tash table during sorting (bug#50733).
+
+2021-09-23 Philip Kaludercic <philipk@posteo.net>
+
+ Fix string-distance for two empty strings
+
+ * src/fns.c (Fstring_distance): Avoid using uninitialized memory.
+ * test/src/fns-tests.el (test-string-distance): Add test cases.
+
+2021-09-23 Juri Linkov <juri@linkov.net>
+
+ * lisp/mouse.el (context-menu-region): Use save-excursion for syntax-ppss.
+
+2021-09-23 Juri Linkov <juri@linkov.net>
+
+ New thing-at-point target 'list-or-string' used in context-menu-region
+
+ * lisp/mouse.el (context-menu-region): Rearrange the order to
+ All>Defun>List>Line>Symbol. Show title either "List" or "String"
+ depending on syntax-ppss, then use thing 'list-or-string' (bug#9054).
+
+ * lisp/thingatpt.el (thing-at-point-bounds-of-list-at-point): Add optional
+ args 'escape-strings' and 'no-syntax-crossing' like in 'up-list'.
+ (list-or-string): New target 'list-or-string'.
+ (thing-at-point-bounds-of-list-or-string-at-point): New function.
+
+2021-09-23 Juri Linkov <juri@linkov.net>
+
+ * lisp/outline.el (outline-minor-mode-cycle-filter): New defcustom (bug#50679)
+
+ (outline-minor-mode-cycle--bind): New helper function.
+ (outline-minor-mode-cycle-map): Rename from outline-mode-cycle-map.
+ (outline-mode-map): Revert part of 6458e16f33 to disassociate
+ keymaps outline-mode-map and outline-minor-mode-cycle-map.
+ (outline-font-lock-keywords, outline-minor-mode-highlight-buffer):
+ Use outline-minor-mode-cycle-map instead of outline-mode-cycle-map.
+
+ * lisp/help.el (describe-bindings): Rename outline-mode-cycle-map
+ to outline-minor-mode-cycle-map.
+
+2021-09-23 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/infra/Dockerfile.emba: Do not run 'make -j4 bootstrap'.
+
+2021-09-23 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Tramp's make-process on macOS
+
+ * lisp/net/tramp-sh.el (tramp-get-remote-mknod-or-mkfifo): New defun.
+ (tramp-sh-handle-make-process): Use it. (Bug#50748)
+
+2021-09-23 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp-cmds.el (tramp-cleanup-connection): Remove trace buffer.
+
+2021-09-23 Philip Kaludercic <philipk@posteo.net>
+
+ Add aggregate project discovery and maintenance functions
+
+ * lisp/progmodes/project.el (project-remember-project): Add
+ optional no-write argument.
+ (project-remember-projects-under): Add command.
+ (project-forget-zombie-projects): Add command.
+ (project-forget-projects-under): Add command.
+ * etc/NEWS: Document new commands.
+
+2021-09-23 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix vc-annotate-show-log-revision-at-line
+
+ * lisp/vc/vc-annotate.el (vc-annotate-show-log-revision-at-line):
+ Stop from being affected by 'vc-git-print-log-follow'.
+
+ * lisp/vc/vc-git.el (vc-git-print-log-follow):
+ Mention caveats in a comment.
+
+2021-09-23 Wilson Snyder <wsnyder@wsnyder.org>
+
+ verilog-mode.el: Backout part of recent change showing wrong comment
+
+2021-09-23 Stefan Kangas <stefan@marxist.se>
+
+ Clarify which-function tooltip text
+
+ * lisp/progmodes/which-func.el (which-func-format): Clarify tooltip
+ text.
+
+2021-09-23 Robert Pluim <rpluim@gmail.com>
+
+ Improve NEWS entry for 'ffap-file-name-with-spaces'
+
+ * etc/NEWS: Mention default value of 'ffap-file-name-with-spaces'.
+
+2021-09-23 Martin Rudalics <rudalics@gmx.at>
+
+ ;* lisp/whitespace.el (whitespace-display-window): Add doc-string.
+
+2021-09-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify align-regexp doc string
+
+ * lisp/align.el (align-regexp): Clarify what REGEXP has to
+ contain, and which bits are added automatically interactively
+ (bug#33541).
+
+2021-09-23 Stefan Kangas <stefan@marxist.se>
+
+ Add section to refcard explaining our keybinding notation
+
+ * etc/refcards/refcard.tex (Starting Emacs): Delete section.
+ (Key Binding Notation): New section. (Bug#41403)
+
+2021-09-23 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in emoji-zwj.el
+
+ * admin/unidata/emoji-zwj.awk: Add lexical-binding cookie to
+ generated fie emoji-zwj.el.
+
+2021-09-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Expand the `match-string' doc string
+
+ * lisp/subr.el (match-string): Mention some caveats (bug#34214).
+
+2021-09-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve error messaging from byte-compiling dotted lists
+
+ * lisp/emacs-lisp/cconv.el (cconv-analyze-form): Improve error
+ messaging when byte-compiling dotted lists (bug#35186).
+
+ Test case -- byte-compile the following file:
+
+ ;;; -*- lexical-binding: t -*-
+
+ (defun foo ()
+ (+ 1 2)
+ (a . b))
+
+2021-09-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move 'kdb-macro-redisplay' key binding
+
+ * doc/emacs/kmacro.texi (Basic Keyboard Macro): Adjust.
+
+ * lisp/kmacro.el (kmacro-keymap): Move 'kdb-macro-redisplay' to
+ `C-x C-k d' since upper-case letters are reserved for users (bug#50727).
+
+2021-09-22 Dmitry Gutov <dgutov@yandex.ru>
+
+ Put './' in the project directory completions
+
+ * lisp/progmodes/project.el (project--read-file-cpd-relative):
+ Put './' in the completions set when cpd was in the original
+ (bug#50732).
+
+2021-09-22 Juri Linkov <juri@linkov.net>
+
+ Many improvements for Context Menus (bug#9054)
+
+ * lisp/menu-bar.el (menu-bar-showhide-menu): Add "Context Menus".
+
+ * lisp/mouse.el (context-menu-undo): Add "in Region" to the titles
+ when the region is active.
+ (context-menu-region): Use 'mouse-yank-from-menu' in menu items
+ created from 'yank-menu' for submenu "Paste from Kill Menu".
+ (context-menu-region): Add submenu "Select" with things to mark.
+ (mark-thing-at-mouse, mouse-yank-from-menu): New functions.
+
+ * lisp/thingatpt.el (bounds-of-thing-at-mouse): New function.
+
+ * lisp/progmodes/elisp-mode.el (elisp-context-menu):
+ * lisp/progmodes/prog-mode.el (prog-context-menu):
+ Use full symbol/identifier names in :help strings.
+
+ Suggested by Martin Rudalics <rudalics@gmx.at>
+
+2021-09-22 Eli Zaretskii <eliz@gnu.org>
+
+ Fix build with native compilation but without zlib
+
+ * src/comp.c (comp_hash_source_file): Condition code that requires
+ zlib with HAVE_ZLIB.
+
+ * etc/NEWS: Explain that '--without-compress-install' is necessary
+ when configuring with native compilation but without zlib.
+
+2021-09-22 Wilson Snyder <wsnyder@wsnyder.org>
+
+ verilog-mode.el: Enable lexical binding, and merge from upstream.
+
+ * lisp/progmodes/verilog-mode.el: Enable lexical binding. Templates that
+ used the never-documented `inst' or `submod' variables may need to change
+ to use vl-... variables.
+ (verilog-at-constraint-p): Fix indentation on double curly brackets
+ (#1719) (#1744). Reported by Nikolay Puzanov.
+
+2021-09-22 Mattias Engdegård <mattiase@acm.org>
+
+ Don't rely on lexical-binding being nil in tests
+
+ * test/lisp/button-tests.el (button--help-echo-form):
+ * test/lisp/files-tests.el (files-tests-permanent-local-variables):
+ Remove assumption that `with-temp-buffer` creates a buffer
+ where `lexical-binding` is nil.
+
+2021-09-22 Eli Zaretskii <eliz@gnu.org>
+
+ Doc string fixes in comp.e
+
+ * src/comp.c (Fcomp_el_to_eln_filename)
+ (Fcomp_el_to_eln_rel_filename): Doc fix.
+
+2021-09-22 Eli Zaretskii <eliz@gnu.org>
+
+ Update comments warning about GC-resistant C programming
+
+ * src/eval.c: Remove an outdated comment about protection from GC.
+ * src/buffer.h:
+ * src/lisp.h: Add warnings about using 'char *' pointers to text
+ of Lisp strings and buffer text in code that could GC. Reported by
+ Po Lu <luangruo@yahoo.com>
+
+2021-09-22 Daniel Fleischer <danflscr@gmail.com>
+
+ Native compilation on macOS: libgccjit not found
+
+ * etc/PROBLEMS: Describe the problem with libgccjit setup on
+ macOS. (Bug#50411)
+
+2021-09-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Speed up `replace-match' slightly
+
+ * src/search.c (Freplace_match): Speed up non-literal (but
+ actually literal) common case.
+
+ This makes
+
+ (benchmark-run 1000000
+ (replace-regexp-in-string
+ "a+" "foo"
+ "ogihdipofdhookfdohkfdpokhpokhfdpokfdhpokfdhkdfkhgoadfphokfkhpofdkhkdpokf"))
+
+ about 10% faster.
+
+2021-09-22 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ Migrate MH-E functional tests from SourceForge
+
+ * test/lisp/mh-e/mh-limit-tests.el:
+ * test/lisp/mh-e/mh-utils-tests.el:
+ * test/lisp/mh-e/mh-xface-tests.el:
+ Import the functional tests from src/mh-unit.el.
+
+ mh-unit.el is from the old SourceForge mh-e repository, last changed
+ in 2017. To this are applied unmerged patches Mike Kupfer wrote in
+ 2018 ("Refactor mh-unit into functional and release tests" and
+ "Fix the functional tests").
+
+ All tests have been converted to run under Emacs's ERT framework.
+
+ Some tests for mh-utils use MH programs to examine mail folders.
+ These tests require an MH variant to be installed on the system; for
+ these, added both a mock harness that pretends the needed files and MH
+ programs do exist, and a wrapper that creates the necessary mail files.
+
+ New function 'mh-test-utils-setup-with-variant' bears some resemblance
+ to 'mh-test-folders-set-up' from the original tests. New function
+ 'mh-test-utils-setup-with-mocks' is new functionality for these tests.
+
+2021-09-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Change how thread-first/thread-last indent the first argument
+
+ * lisp/doc-view.el (doc-view--current-cache-dir): Reindent.
+
+ * lisp/emacs-lisp/subr-x.el (thread-first):
+ (thread-last): Change indentation to match examples.
+ (internal--build-binding): Reindent.
+
+ * test/lisp/emacs-lisp/subr-x-tests.el
+ (subr-x-test-thread-first-function-names-are-threaded):
+ (subr-x-test-thread-first-examples):
+ (subr-x-test-thread-last-function-names-are-threaded):
+ (subr-x-test-thread-last-examples): Reindent.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make global-auto-revert-non-file-buffers work better
+
+ * lisp/autorevert.el (global-auto-revert-mode): Always switch on
+ the non-file tracking.
+ (auto-revert--global-possibly-adopt-current-buffer): New function
+ to respect dynamically changing `global-auto-revert-non-file-buffers'.
+
+2021-09-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ (etc-authors-mode--hide-local-variables): Obfuscate more efficiently
+
+2021-09-21 Stefan Kangas <stefan@marxist.se>
+
+ Fix warning in etc-authors-mode.el
+
+ * lisp/textmodes/etc-authors-mode.el
+ (etc-authors-mode--hide-local-variables): Avoid warning.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't quote nil and t in doc strings and comments
+
+ * test/src/minibuf-tests.el (test-try-completion-ignore-case):
+ * test/lisp/url/url-auth-tests.el
+ (url-auth-test-digest-auth-retrieve-cache):
+ * test/lisp/subr-tests.el (subr-tests-add-hook-depth):
+ * test/lisp/so-long-tests/so-long-tests.el
+ (so-long-tests-invisible-buffer-function):
+ * test/lisp/emacs-lisp/tabulated-list-test.el (tabulated-list-sort):
+ * src/xfaces.c:
+ * src/process.c (Finterrupt_process):
+ (syms_of_process):
+ * src/minibuf.c (Fread_from_minibuffer):
+ (Fcompleting_read):
+ (syms_of_minibuf):
+ * src/dispnew.c (syms_of_display):
+ * src/data.c:
+ * lisp/so-long.el (so-long--hack-local-variables):
+ * lisp/progmodes/elisp-mode.el (elisp--xref-find-definitions):
+ (elisp--xref-find-definitions):
+ * lisp/org/ox-html.el (org-html-htmlize-output-type):
+ * lisp/org/org-agenda.el (org-agenda-do-in-region):
+ * lisp/net/tramp.el:
+ * lisp/minibuffer.el (set-minibuffer-message):
+ * lisp/isearch.el (isearch-wrap-pause):
+ (isearch-repeat-on-direction-change):
+ * lisp/emacs-lisp/timer.el (timer):
+ * lisp/emacs-lisp/package.el (package-read-archive-contents):
+ * lisp/emacs-lisp/faceup.el (faceup-next-property-change):
+ * lisp/emacs-lisp/comp.el (comp-func):
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-empty-p):
+ * lisp/emacs-lisp/cl-macs.el (cl-do):
+ (cl-do*):
+ (cl--self-tco):
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-unresolved-functions):
+ (byte-compile-cond-jump-table): Don't quote t and nil.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document isearch-wrap-pause
+
+ * doc/emacs/search.texi (Repeat Isearch): Document
+ `isearch-wrap-pause'.
+
+2021-09-21 Stefan Kangas <stefan@marxist.se>
+
+ New major mode with font-locking for etc/AUTHORS
+
+ * lisp/textmodes/etc-authors-mode.el: New file. (Bug#50674)
+ * etc/AUTHORS (mode): Add "mode: etc-authors" to local variables.
+ * admin/authors.el (authors): Add "mode: etc-authors" to local
+ variables of the generated AUTHORS file.
+
+2021-09-21 Eli Zaretskii <eliz@gnu.org>
+
+ Improve recently added documentation
+
+ * doc/lispref/lists.texi (Building Lists):
+ * lisp/subr.el (ensure-list): Avoid passive tense in documenting
+ 'ensure-list'.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new function `ensure-list'
+
+ * doc/lispref/lists.texi (Building Lists): Document it.
+
+ * lisp/subr.el (ensure-list): New function.
+
+ * lisp/emacs-lisp/shortdoc.el (list): Mention it.
+
+2021-09-21 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix tramp-compat-temporary-file-directory implementation
+
+ * lisp/net/tramp-archive.el
+ (tramp-archive-handle-temporary-file-directory):
+ Use `tramp-compat-temporary-file-directory-function'.
+
+ * lisp/net/tramp-compat.el (tramp-compat-temporary-file-directory):
+ Make it a defconst.
+
+ * lisp/net/tramp.el (tramp-get-debug-buffer, tramp-get-debug-file-name)
+ (tramp-debug-message, tramp-file-name-handler, tramp-parse-file)
+ (tramp-parse-shostkeys-sknownhosts)
+ (tramp-handle-expand-file-name, tramp-handle-make-process)
+ (tramp-local-host-p, tramp-call-process)
+ (tramp-call-process-region, tramp-process-lines)
+ (tramp-read-passwd):
+ * lisp/net/tramp-adb.el (tramp-adb-maybe-open-connection):
+ * lisp/net/tramp-compat.el (tramp-compat-make-temp-name)
+ (tramp-compat-make-temp-file);
+ * lisp/net/tramp-crypt.el (tramp-crypt-file-name-for-operation)
+ (tramp-crypt-maybe-open-connection, tramp-crypt-send-command)
+ (tramp-crypt-do-encrypt-or-decrypt-file-name):
+ * lisp/net/tramp-fuse.el (tramp-fuse-mount-point, tramp-fuse-mounted-p)
+ (tramp-fuse-unmount):
+ * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-out-of-band)
+ (tramp-sh-handle-expand-file-name)
+ (tramp-sh-handle-file-local-copy, )
+ (tramp-sh-handle-write-region, tramp-maybe-open-connection):
+ * lisp/net/tramp-smb.el (tramp-smb-maybe-open-connection): Use it.
+
+2021-09-21 Stefan Kangas <stefan@marxist.se>
+
+ Minor clean-up and fixes in checkdoc
+
+ * lisp/emacs-lisp/checkdoc.el: Minor doc fixes. Remove unnecessary
+ space at the end of 'y-or-n-p' prompts. Move obsolete definitions to
+ the end of the file.
+ (checkdoc-symbol-words, checkdoc-common-verbs-wrong-voice): Add
+ some more common words.
+
+2021-09-21 Stefan Kangas <stefan@marxist.se>
+
+ checkdoc: New defvars to disable some warnings
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc--argument-missing-flag)
+ (checkdoc--disambiguate-symbol-flag)
+ (checkdoc--interactive-docstring-flag): New defvars to disable some
+ warnings. These are intended for use with Emacs itself rather than
+ with third-party libraries.
+ (checkdoc-this-string-valid, checkdoc-this-string-valid-engine):
+ Respect above new variables.
+
+2021-09-21 Stefan Kangas <stefan@marxist.se>
+
+ Add new command 'checkdoc-dired'
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-dired): New command.
+ (checkdoc--dired-skip-lines-re): New constant.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ More NEWS tagging
+
+ Do some NEWS tagging
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document `window-bump-use-time'
+
+ * doc/lispref/windows.texi (Cyclic Window Ordering): Mention
+ window-bump-use-time.
+
+2021-09-21 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: Preserve all existing tab parameters when switching tabs.
+
+ * lisp/tab-bar.el (tab-bar--tab, tab-bar--current-tab-make):
+ Copy other possible tab parameters.
+ https://lists.gnu.org/archive/html/emacs-devel/2021-09/msg01544.html
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document completions-detailed
+
+ * doc/emacs/help.texi (Name Help): Document completions-detailed.
+ * lisp/minibuffer.el (completions-detailed): Give an example in
+ the doc string.
+
+2021-09-21 Michalis V <mvar.40k@gmail.com>
+
+ Make dired-do-compress-to work in inserted subdirectories
+
+ * lisp/dired-aux.el (dired-do-compress-to): Make this work in file
+ in inserted subdirectories (bug#46913).
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Make dired-compress-file query for a directory to uncompress to"
+
+ This reverts commit 7e395a59b025c7f4be49294ad806addf5b1a25c9.
+
+ The behaviour change isn't good for the majority of tar files.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Make recent dired tests check for external executables"
+
+ This reverts commit 98a17f30b8314e40a1edefac3d542d3e105c7bd6.
+
+ Reverting parent commit.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Restore some of the previous behaviour in whitespace-display-window
+
+ * lisp/whitespace.el (whitespace-display-window): Emulate previous
+ behaviour (bug#50716). Code from martin rudalics <rudalics@gmx.at>.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't use `format' on strings without % format directives
+
+ * lisp/vc/ediff-init.el (ediff-BAD-INFO):
+ * lisp/url/url-ldap.el (url-ldap):
+ * lisp/url/url-http.el (url-http--user-agent-default-string):
+ * lisp/textmodes/reftex.el (reftex-access-parse-file):
+ * lisp/textmodes/reftex-index.el (reftex-index-phrases-info):
+ * lisp/textmodes/ispell.el (ispell-create-debug-buffer):
+ * lisp/term.el (serial-read-speed):
+ * lisp/progmodes/verilog-mode.el (verilog-scan-debug):
+ * lisp/progmodes/idlwave.el (idlwave-find-module):
+ * lisp/progmodes/compile.el (compilation-revert-buffer):
+ * lisp/org/org-agenda.el (org-search-view):
+ * lisp/net/telnet.el (telnet-revert-buffer):
+ * lisp/net/soap-inspect.el (soap-sample-value-for-xs-simple-type):
+ * lisp/net/newst-backend.el (newsticker--cache-read):
+ * lisp/mh-e/mh-seq.el (mh-msg-is-in-seq):
+ * lisp/mail/smtpmail.el (smtpmail-via-smtp):
+ * lisp/mail/emacsbug.el (report-emacs-bug):
+ * lisp/jsonrpc.el (jsonrpc-error):
+ * lisp/help-fns.el (describe-variable):
+ * lisp/gnus/mm-decode.el (mm-possibly-verify-or-decrypt):
+ * lisp/gnus/gnus.el (gnus-group-startup-message):
+ (gnus-group-startup-message):
+ * lisp/gnus/gnus-group.el (gnus-group-restart):
+ * lisp/frame.el (make-frame-on-display):
+ * lisp/emulation/viper-ex.el (ex-help):
+ * lisp/calendar/icalendar.el (icalendar--convert-ical-to-diary):
+ (icalendar--add-diary-entry):
+ * lisp/calendar/cal-tex.el (cal-tex-end-document):
+ * lisp/calc/calcalg3.el (math-ninteg-romberg): Don't use `format'
+ on strings that have no % format directives in them.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix usage of `format' in mm-uu-pgp-encrypted-extract
+
+ * lisp/gnus/mm-uu.el (mm-uu-pgp-encrypted-extract): Use
+ `substring' instead of `format' to ensure a fresh string.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix usage of `format' in `article-verify-x-pgp-sig'
+
+ * lisp/gnus/gnus-art.el (article-verify-x-pgp-sig): Use
+ `substring' instead of `format' to ensure a fresh string.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix PGP verification buttons (which would have cached results)
+
+ * lisp/gnus/mm-uu.el (mm-uu-pgp-signed-extract): `format' was used
+ here to guarantee a new, fresh string (since it's destructively
+ modified), but that's apparently not the case any more. Use
+ `substring' instead, which is documented to do this.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't inhibit redisplay in the mml* functions
+
+ * lisp/gnus/mml-smime.el (inhibit-redisplay): Removed.
+ (mml-smime-epg-encrypt):
+ (mml-smime-epg-verify): Don't inhibit.
+
+ * lisp/gnus/mml1991.el (mml1991-epg-sign): Ditto.
+
+ * lisp/gnus/mml2015.el (inhibit-redisplay): Removed
+ (mml2015-epg-decrypt):
+ (mml2015-epg-clear-decrypt):
+ (mml2015-epg-verify):
+ (mml2015-epg-clear-verify):
+ (mml2015-epg-sign):
+ (mml2015-epg-encrypt): Don't bind `inhibit-redisplay', because it
+ makes debugging very odd, and doesn't seem to help much with anything.
+
+2021-09-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/python.el (python-syntax-stringify): Extend
+ comment about last change.
+
+2021-09-21 Robert Pluim <rpluim@gmail.com>
+
+ Fix emoji-zwj.awk dolist
+
+ * admin/unidata/emoji-zwj.awk: Fix typo, the dolist should end
+ after the first set-char-table-range.
+
+2021-09-21 Glenn Morris <rgm@gnu.org>
+
+ Make recent dired tests check for external executables
+
+ * test/lisp/dired-aux-tests.el (dired-test-bug47058-tar)
+ (dired-test-bug47058-zip): Add skip conditions.
+
+2021-09-21 Dmitry Gutov <dgutov@yandex.ru>
+
+ Rename project-remove-known-project to project-forget-project
+
+ * doc/emacs/maintaining.texi (Managing Projects): Ditto.
+
+ * etc/NEWS: Update accordingly.
+
+ * lisp/progmodes/project.el (project-forget-project):
+ Rename from 'project-remove-known-project', for consistency with
+ 'project-remember-project' (discussed in bug#50297).
+
+2021-09-21 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Consistently test alist keys with equal in map.el
+
+ * etc/NEWS: Announce new default behavior of map-elt and map-delete
+ on alists.
+
+ * lisp/emacs-lisp/map.el: Bump to version 3.2.
+ (map-elt): Test alist keys with equal by default. Betray a little
+ bit more information in the docstring on which functions are used
+ for which map types. (Bug#47368)
+ (map-put): Update docstring accordingly.
+ (map--plist-delete): Consistently test plist keys with eq.
+ (map-delete): Consistently test alist keys with equal.
+
+ * test/lisp/emacs-lisp/map-tests.el (test-map-elt-testfn): Update
+ for new map-elt behavior.
+ (test-map-put!-alist, test-map-delete-alist): New tests.
+
+2021-09-21 Robert Pluim <rpluim@gmail.com>
+
+ Remove the emoji script overrides for U+2xxx codepoints
+
+ * admin/unidata/blocks.awk: Remove the overrides for U+261D, U+26F9,
+ U+270C..U+270D, and U+2764. They don't belong in the emoji script.
+
+2021-09-21 Robert Pluim <rpluim@gmail.com>
+
+ Fix the UK flag sequence composition regexp
+
+ * admin/unidata/emoji-zwj.awk: Fix the regexp for UK flags.
+ Thanks to Mattias Engdegård <mattiase@acm.org> and his magic
+ regexp checker.
+
+2021-09-21 Robert Pluim <rpluim@gmail.com>
+
+ Silence byte-compiler warning for network-stream-tests.el
+
+ The api specifically requires a symbol here, so we can't just replace
+ nowait with nil.
+
+ * test/lisp/net/network-stream-tests.el
+ (open-gnutls-stream-old-api-wait): Add explicit value for nowait
+ to silence byte-compiler warning due to Bug#47080.
+
+2021-09-21 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Avoid double argument evaluation in vc-call macro
+
+ * lisp/vc/vc-hooks.el (vc-call): Ensure second argument is evaluated
+ only once (bug#50690).
+ * etc/NEWS (Change Logs and VC): Announce this change in behavior.
+
+2021-09-21 João Távora <joaotavora@gmail.com>
+
+ Make syntax-ppss more accurate for Python triple quotes (bug#49518)
+
+ By putting delimiter syntax on the last character of Python
+ triple-quoted strings, this makes syntax-ppss be more accurate.
+
+ Previously:
+
+ emacs -Q something.py
+ type two single quotes
+ M-: (nth 3 (syntax-ppss))
+ notice how the return value says you're outside a string, correctly
+ type another quote
+ M-: (nth 3 (syntax-ppss))
+ notice how the return value says you're inside a string, correctly
+ backspace the quote just entered
+ M-: (nth 3 (syntax-ppss))
+ notice how the return value says you're inside a string, incorrectly
+
+ With this patch the last step is corrected. This helps things like
+ electric-pair-mode. Also, the test
+ python-syntax-after-python-backspace now passes, again.
+
+ * lisp/progmodes/python.el (python-syntax-stringify): Put
+ delimiter syntax in "inner" of the surrounding triple quotes.
+
+ * test/lisp/progmodes/python-tests.el
+ (python-syntax-after-python-backspace): Passes again.
+
+2021-09-21 João Távora <joaotavora@gmail.com>
+
+ Expand and improve electric-pair-mode and Python testing (bug#49518)
+
+ In python-tests.el, the triple-quote pairing tests are passing
+ incorrectly, i.e. the auto-pairing functionality they purport to guard
+ isn't really working for users trying it interactively. Added a new
+ failing test, soon to be fixed.
+
+ In electric-tests.el, added tests for Python, too.
+
+ * test/lisp/electric-tests.el (define-electric-pair-test): Also run
+ main tests for python-mode. (pair-some-quotes-skip-others): Test
+ another slightly different pairing.
+
+ * test/lisp/progmodes/python-tests.el
+ (python-triple-double-quote-pairing): Rename from
+ python-triple-quote-pairing.
+ (python-triple-single-quote-pairing): New test.
+
+2021-09-21 João Távora <joaotavora@gmail.com>
+
+ Add docstring for 'electric-pair-p-s-i-f' and minor refactor
+
+ Extract the "open newline between pairs behaviour" into its own
+ function, electric-pair-open-newline-between-pairs-psif.
+
+ * lisp/elec-pair.el (electric-pair-post-self-insert-function): Add
+ docstring.
+ (electric-pair-open-newline-between-pairs-psif): New function.
+ (electric-pair-mode): Add/remove electric-pair-open-newline-between-pairs-psif
+
+2021-09-21 João Távora <joaotavora@gmail.com>
+
+ Speed up test/lisp/electric-tests.el when run interactively
+
+ 'blink-paren-function' and its timers could sometimes interfere with
+ the tests and slow them down significantly.
+
+ * test/lisp/electric-tests.el (call-with-saved-electric-modes):
+ Bind blink-paren-function to nil.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix whitespace-report window creation
+
+ * lisp/whitespace.el (whitespace-display-window): Avoid creating
+ many buffers if called many times (bug#50716).
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use `special-mode' for whitespace-report
+
+ * lisp/whitespace.el (whitespace-report-region): Use
+ `special-mode' instead of `fundamental-mode' (bug#50715).
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Inhibit warning in mm-inline-wash-with-file from previous change
+
+ * lisp/gnus/mm-view.el (mm-inline-wash-with-file): Inhibit warning
+ about previous lexical fixup.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problems with non-ASCII non-encoded PGP names
+
+ * lisp/epg.el (epg-signature-to-string): User IDs may be
+ non-encoded, non-ASCII (bug#50706).
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix typo in tex--prettify-symbols-alist
+
+ * lisp/textmodes/tex-mode.el (tex--prettify-symbols-alist): Fix
+ varsigma typo (bug#50710).
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix lexical fallout in mm-inline-wash-with-file
+
+ * lisp/gnus/mm-view.el (mm-inline-wash-with-file): This is only
+ called from the `links' handler, and it passes in `file' expecting
+ that to be dynamically bound. Which is a very, very confusing
+ interface, but make that work again, anyway.
+
+2021-09-21 Michalis V <mvar.40k@gmail.com>
+
+ Make dired-compress-file query for a directory to uncompress to
+
+ * lisp/dired-aux.el (dired-compress-file-suffixes): Specify the
+ directory in the tar targets.
+ (dired-uncompress-file): New function (bug#47058). This asks what
+ directory to uncompress to.
+ (dired-compress-file): Use it.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clear netrc cache in auth-source test
+
+ * test/lisp/auth-source-tests.el
+ (auth-source-test-netrc-create-secret): Clear the netrc cache, too.
+
+2021-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Only search netrc in the netrc tests
+
+ * test/lisp/auth-source-tests.el
+ (auth-source-test-netrc-create-secret): Only search netrc.
+
+2021-09-21 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Remove some last calls to Gnus group name encoding
+
+ This should have been part of cb12a84f2c
+
+ * lisp/gnus/gnus-msg.el (gnus-summary-resend-message-insert-gcc,
+ gnus-inews-do-gcc): Don't encode group names.
+
+2021-09-21 Dmitry Gutov <dgutov@yandex.ru>
+
+ New command: project-find-dir
+
+ * doc/emacs/maintaining.texi (Project File Commands):
+ Mention the new command and update the bindings information.
+
+ * lisp/progmodes/project.el (project-find-dir):
+ New command (bug#43153).
+ (project-prefix-map): Use 'd' as its binding.
+ Move 'project-dired' to 'D'.
+ (project-switch-commands):
+ Replace 'project-dired' with 'project-find-dir'.
+
+2021-09-20 Robert Pluim <rpluim@gmail.com>
+
+ Support for Unicode emoji sequences
+
+ This covers both sequences using Zero-Width-Joiner codepoints and
+ those without. Bug#39799, I hope.
+
+ * .gitignore: Add emoji-zwj.el
+ * admin/notes/unicode: Add emoji-zwj-sequences.txt and
+ emoji-sequences.txt references. Describe how to test after updating
+ to a newer Unicode version.
+ * admin/unidata/Makefile.in (all): add emoji-zwj.el as a dependency.
+ (emoji-zwj.el): Add target plus rules for building.
+ (gen-clean): Add emoji-zwj.el.
+ * admin/unidata/README: Add emoji-zwj-sequences.txt and
+ emoji-sequences.txt references.
+ * admin/unidata/blocks.awk: Force emoji script to be used for certain
+ codepoints that are used by the Unicode sequences.
+ * admin/unidata/emoji-sequences.txt: New file.
+ * admin/unidata/emoji-zwj-sequences.txt: New file.
+ * admin/unidata/emoji-zwj.awk: New file. Derives
+ composition-function-table rules from emoji-zwj-sequences.txt, plus
+ hardcodes some derived manually from emoji-sequences.txt.
+ * etc/NEWS: Announce change.
+ * lisp/international/characters.el: Load the generated emoji-zwj.el
+ * src/Makefile.in (emoji-zwj): New target.
+ (temacs): Add emoji-zwj as a dependency.
+
+2021-09-20 Jonas Bernoulli <jonas@bernoul.li>
+
+ No longer raise error when http authentication failed
+
+ * lisp/url/url-http.el (url-http-handle-authentication): Return t
+ instead of raising an error, instructing the caller to invoke the
+ request specific error handler (bug#50511).
+
+2021-09-20 Robert Pluim <rpluim@gmail.com>
+
+ Add a note about testing out-of-tree builds
+
+ * CONTRIBUTE: Ask contributors to test out-of-tree builds when
+ making build system changes.
+
+2021-09-20 Robert Pluim <rpluim@gmail.com>
+
+ Base emoji script membership on Emoji_Presentation
+
+ The Emoji property describes which codepoints can be displayed as
+ emoji, but Emoji_Presentation governs which are displayed as emoji by
+ default.
+
+ * admin/notes/unicode: Adjust check-emoji-coverage to look in the
+ Emoji_Presentation sections of emoji-data.txt
+ * admin/unidata/blocks.awk: Assign emoji script using the
+ Emoji_Presentation section.
+
+2021-09-20 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix VC repo URL detection in bug-reference-mode
+
+ * lisp/progmodes/bug-reference.el (bug-reference-try-setup-from-vc):
+ Pass file or directory name in question as the first argument to the
+ backend's repository-url implementation (bug#50689). Use when-let
+ and seq-some to flatten nested conditionals.
+
+2021-09-20 Eli Zaretskii <eliz@gnu.org>
+
+ Fix assertion violation with zero-width :box attributes
+
+ * src/xfaces.c (merge_face_ref): Don't allow :box attribute with a
+ zero value. (Bug#50699)
+
+2021-09-20 Michael Albinus <michael.albinus@gmx.de>
+
+ Remove superfluous skip in auth-source-tests.el
+
+ * test/lisp/auth-source-tests.el
+ (auth-source-test-netrc-create-secret): Remove superfluous skip.
+
+2021-09-20 Mattias Engdegård <mattiase@acm.org>
+
+ Dump with `lexical-binding` bound to nil
+
+ * lisp/loadup.el (dump-mode): Temporarily bind `lexical-binding` to
+ nil while dumping. Otherwise, it will be t in Emacs by default
+ and that is not our intention (yet).
+
+2021-09-20 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-new-tab): Add optional arg 'from-number'.
+
+ (tab-bar-mouse-context-menu): Use tab-number as an arg for
+ 'tab-bar-duplicate-tab'.
+ (tab-bar-duplicate-tab): Add optional arg 'from-number'.
+
+2021-09-20 Juri Linkov <juri@linkov.net>
+
+ Add support for url-retrieve-synchronously to eww-retrieve-command (bug#50680)
+
+ * doc/misc/eww.texi (Advanced): Mention url-retrieve-synchronously
+ for eww-retrieve-command.
+
+ * lisp/net/eww.el (eww-retrieve-command): Add choice 'sync' for
+ url-retrieve-synchronously.
+ (eww-retrieve): Use value 'sync' for url-retrieve-synchronously.
+ (eww-isearch-next-buffer): Let-bind eww-retrieve-command to 'sync'.
+
+2021-09-20 Miha Rihtaršič <miha@kamnitnik.top>
+
+ Improve documentation of exiting recursive editing
+
+ * doc/lispref/commands.texi (Recursive Editing): Mention what happens
+ when throwing a string or any other value to 'exit.
+ * src/keyboard.c (Frecursive_edit): Document throwing a function
+ to 'exit (bug#49700).
+
+2021-09-20 Miha Rihtaršič <miha@kamnitnik.top>
+
+ Refactor minibuffer aborting
+
+ * lisp/minibuffer.el (minibuffer-quit-recursive-edit): New optional
+ argument to specify how many levels of recursion to quit.
+
+ * src/eval.c (internal_catch): Remove special handling of 'exit
+ tag (bug#49700).
+ * src/minibuf.c (Fabort_minibuffers): Use
+ minibuffer-quit-recursive-edit to quit multiple levels of minibuffer
+ recursion.
+
+2021-09-20 Philip Kaludercic <philipk@posteo.net>
+
+ Fix dolist-with-progress-reporter behaviour
+
+ * lisp/subr.el (dolist-with-progress-reporter): Use the length of
+ list argument as maximal value the reporter with reach.
+
+2021-09-19 Stefan Kangas <stefan@marxist.se>
+
+ Revert "Flag checkdoc-symbol-words as a :safe variable"
+
+ There was no need for this change, as this variable was already marked
+ as :safe.
+
+ This reverts commit 222a7a1a8afdf6921e5981133c605c2d695e9281.
+
+2021-09-19 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid segfaults due to 'bug-reference-mode'
+
+ * src/xdisp.c (handle_fontified_prop): Set the frame's
+ inhibit_clear_image_cache flag around calls to
+ 'fontification-functions', to avoid Lisp triggering the clearing
+ of image and/or face caches behind redisplay's back. (Big#50571)
+
+2021-09-19 Eli Zaretskii <eliz@gnu.org>
+
+ Fix blocks.awk wrt to Emoji characters
+
+ * admin/unidata/blocks.awk: Fix emoji-data.txt processing for
+ older Awks.
+
+2021-09-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Do not save empty passwords in auth-source-search
+
+ * lisp/auth-source.el (auth-source-netrc-create)
+ (auth-source-secrets-create): Set :save-function only for non
+ empty passwords.
+
+ * lisp/net/tramp.el (tramp-read-passwd): Don't save empty passwords.
+
+ * test/lisp/auth-source-tests.el
+ (auth-source-test-secrets-create-secret): Adapt test.
+ (auth-source-test-netrc-create-secret): New test.
+
+2021-09-19 Stefan Kangas <stefan@marxist.se>
+
+ Be explicit about missing sections in eshell manual
+
+ * doc/misc/eshell.texi (Writing a module, Module testing)
+ (Directory handling, Key rebinding, Smart scrolling)
+ (Terminal emulation): Explicitly say that these sections remain to
+ be written. (Bug#49306)
+
+2021-09-19 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/elisp-mode.el (elisp-context-menu): Improve menu items.
+
+2021-09-19 Ken Brown <kbrown@cornell.edu>
+
+ Fix build with native compilation on Cygwin
+
+ * src/Makefile.in (emacs$(EXEEXT)) [CYGWIN]: Rebase the *.eln
+ files after they are all created, to avoid fork problems later
+ in the build. (Bug#50666)
+
+2021-09-19 Stefan Kangas <stefan@marxist.se>
+
+ Clarify docstring of pcase-exhaustive
+
+ * lisp/emacs-lisp/pcase.el (pcase-exhaustive): Clarify docstring
+ by contrasting with pcase. (Bug#44166)
+
+2021-09-19 Stefan Kangas <stefan@marxist.se>
+
+ Make two unused variables obsolete
+
+ * lisp/progmodes/idlw-help.el (idlwave-help-directory)
+ (idlwave-help-use-hh): Make unused variables obsolete.
+
+2021-09-19 Stefan Kangas <stefan@marxist.se>
+
+ * etc/NEWS: Add section on recent checkdoc changes.
+
+2021-09-19 Mattias Engdegård <mattiase@acm.org>
+
+ Initialise unread buffer
+
+ The reader has an extra 1-char unread buffer that was incorrectly
+ initialised to 0, which means that the first character read would
+ always be NUL. As this is often the code that looks for the
+ lexical-binding cookie, the first loaded source module would be
+ treated as dynamically bound. During bootstrapping this is loadup.el
+ and so its local variables got dumped into the global environment.
+
+ * src/lread.c (unread_char): Initialise to empty.
+ (Fload): Initialise here too just in case.
+
+2021-09-19 Stefan Kangas <stefan@marxist.se>
+
+ checkdoc: Verify format of yes-or-no-p and format-message
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-message-text-next-string):
+ Check also for "yes-or-no-p" and "format-message". Convert regexps to
+ use rx.
+
+2021-09-19 Stefan Kangas <stefan@marxist.se>
+
+ Flag checkdoc-symbol-words as a :safe variable
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-symbol-words): Flag as a safe
+ file local variable.
+
+2021-09-19 Eli Zaretskii <eliz@gnu.org>
+
+ Teach Mail mode to request Disposition Notifications
+
+ * lisp/mail/sendmail.el (mail-insert-disposition-notification-to):
+ New function.
+ (mail-mode-map): Add it to key bindings and menu bar.
+
+2021-09-19 Amin Bandali <bandali@gnu.org>
+
+ Add new '/opme' and '/deopme' convenience ERC commands
+
+ * lisp/erc/erc.el (erc-cmd-OPME, erc-cmd-DEOPME): Add convenience
+ commands for setting and unsetting the operator status on the current
+ nick in the current channel. 'erc-cmd-OPME' relies on ChanServ for
+ obtaining the operator status (see doc string for more details).
+
+ * etc/NEWS: Announce the addition of the commands.
+
+2021-09-19 Stefan Kangas <stefan@marxist.se>
+
+ Revert previous mode-line-modes change to unbreak bootstrap
+
+ * lisp/bindings.el (mode-line-modes): Revert previous change to
+ unbreak bootstrap.
+
+2021-09-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Viper doc string fix
+
+ * lisp/emulation/viper-keym.el (viper-want-ctl-h-help): Fold
+ over-long first line.
+
+2021-09-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix viper-util compilation warning
+
+ * lisp/emulation/viper-util.el (cl-lib): Require for cl-subseq.
+
+2021-09-18 Stefan Kangas <stefan@marxist.se>
+
+ * etc/NEWS: Shorten entry on move to Libera.Chat.
+
+2021-09-18 Stefan Kangas <stefan@marxist.se>
+
+ Use command substitution in checkdoc-recursive-edit
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-recursive-edit): Use command
+ substitution.
+ (checkdoc--help-buffer): New variable. Use it instead of hard-coded
+ string.
+
+2021-09-18 Stefan Kangas <stefan@marxist.se>
+
+ Use command substitution for exit-recursive-edit
+
+ * lisp/bindings.el (mode-line-modes):
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-recursive-edit): Use command
+ substitution for 'exit-recursive-edit'.
+
+2021-09-18 Juri Linkov <juri@linkov.net>
+
+ * lisp/subr.el (string-replace): Add dashes to arg names (bug#50644)
+
+ * lisp/net/tramp-compat.el (tramp-compat-string-replace): Idem.
+ * doc/lispref/searching.texi (Search and Replace): Idem.
+
+2021-09-18 Arthur Miller <arthur.miller@live.com>
+
+ Add new help-enable-symbol-autoload user option
+
+ * lisp/help-fns.el (help-fns--analyze-function): Use it.
+ * lisp/help-fns.el (help-enable-symbol-autoload): New user option.
+ * doc/emacs/help.texi (Name Help): Document it.
+
+2021-09-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention xref-quit-and-pop-marker-stack in the manual
+
+ * doc/emacs/maintaining.texi (Xref Commands): Mention
+ xref-quit-and-pop-marker-stack in the manual.
+
+2021-09-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Do some xwidget NEWS markup (and adjust doc string)
+
+ * lisp/xwidget.el (xwidget-webkit-bookmark-make-record): Mention
+ `xwidget-webkit-bookmark-jump-new-session' in the doc string.
+
+2021-09-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make argument optional in pulse-momentary-highlight-one-line
+
+ * lisp/cedet/pulse.el (pulse-momentary-highlight-one-line): Make
+ POINT optional (bug#50642) so that the function can be used more
+ easily from some hook functions.
+
+2021-09-18 Dan Ports <dan@drkp.net> (tiny change)
+
+ Use the newest gcc installed by Macports
+
+ * configure.ac: There may be more than one gcc version installed
+ in Macports (bug#50649). Use the newest.
+
+2021-09-18 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fontify Libtool macros in autoconf-mode
+
+ * lisp/progmodes/autoconf.el (autoconf-font-lock-keywords): Apply
+ font-lock-keyword-face also to Libtool's LT_* macros (bug#50659).
+
+2021-09-18 Eli Zaretskii <eliz@gnu.org>
+
+ Improve doc strings of a recent commit
+
+ * lisp/emacs-lisp/generator.el (iter-defun):
+ * lisp/emacs-lisp/comp.el (comp-clean-up-stale-eln):
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-lapcode):
+ * lisp/emacs-lisp/autoload.el (autoload-insert-section-header):
+ Include description of arguments in the doc string's first line.
+
+2021-09-18 Mattias Engdegård <mattiase@acm.org>
+
+ Regexp-quote literal symbols when grepping
+
+ `xref-find-references` was unable to find symbols like
+ `backquote-list*-macro`.
+
+ * lisp/cedet/semantic/symref/grep.el
+ (semantic-symref-grep--quote-extended): New function.
+ (semantic-symref-perform-search): Call it.
+
+2021-09-18 Eli Zaretskii <eliz@gnu.org>
+
+ Fix performance degradation in commands that describe key bindings
+
+ * src/keymap.c (syms_of_keymap)
+ <describe-bindings-check-shadowing-in-ranges>: New variable.
+ (describe_vector): Check shadowing of consecutive keys only if
+ 'describe-bindings-check-shadowing-in-ranges' is non-nil. Remove
+ redundant second loop when VECTOR is a char-table. Improve
+ comments. Patch by Stefan Kangas <stefan@marxist.se>. (Bug#45379)
+
+ * test/src/keymap-tests.el
+ (help--describe-vector/bug-9293-one-shadowed-in-range): Adapt the
+ test case for the new variable.
+
+2021-09-18 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/emacs-lisp/checkdoc.el: Doc fix; mention flymake.
+
+ Do interactive mode tagging for checkdoc.el
+
+2021-09-18 Stefan Kangas <stefan@marxist.se>
+
+ checkdoc: Only look for commonly used modifier keys
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-this-string-valid-engine):
+ Search for the modifier key "s-", but not the modifier key "A-".
+ The latter is very uncommon and leads to false positives.
+
+2021-09-18 Michael Albinus <michael.albinus@gmx.de>
+
+ Skip "fast" tests on emba CI
+
+ * test/infra/gitlab-ci.yml (stages): Comment "fast" stage out.
+ (test-fast-inotify): Comment out.
+
+2021-09-18 Stefan Kangas <stefan@marxist.se>
+
+ Add indent declaration to emerge-defvar-local
+
+ * lisp/vc/emerge.el (emerge-defvar-local): Add indent declaration
+ for docstring. Fix wrongly indented callers.
+
+2021-09-18 Stefan Kangas <stefan@marxist.se>
+
+ Make doc argument of emerge-defvar-local optional
+
+ * lisp/vc/emerge.el (emerge-defvar-local): Make doc argument
+ optional.
+
+2021-09-18 Stefan Kangas <stefan@marxist.se>
+
+ Make doc argument of ediff-defvar-local optional
+
+ * lisp/vc/ediff-init.el (ediff-defvar-local): Make DOC argument
+ optional. Update callers passing the empty string to not use it.
+
+2021-09-18 Federico Tedin <federicotedin@gmail.com>
+
+ Check for null bytes in filenames in 'expand-file-name' (bug#49723)
+
+ * src/fileio.c (expand-file-name): Check for null bytes for both
+ NAME and DEFAULT-DIRECTORY arguments. Also check for null bytes
+ in buffer-local default-directory, assuming it is used.
+ * src/coding.c (encode_file_name): Use CHECK_STRING_NULL_BYTES.
+ * src/lisp.h (CHECK_STRING_NULL_BYTES): Add function for checking
+ for null bytes in Lisp strings.
+ * test/src/fileio-tests.el (fileio-test--expand-file-name-null-bytes):
+ Add test for new changes to expand-file-name.
+ * etc/NEWS: Announce changes.
+
+2021-09-18 Amin Bandali <bandali@gnu.org>
+
+ * lisp/erc/erc.el: Add Package-Requires and URL headers.
+
+2021-09-18 Amin Bandali <bandali@gnu.org>
+
+ * etc/NEWS: Announce update of IRC-related references to point to Libera.Chat.
+
+ Also remove the note about freenode subdomain change, as it's not
+ relevant anymore.
+
+2021-09-17 Stefan Kangas <stefan@marxist.se>
+
+ Update refcard to mention iconify before suspend
+
+ * etc/refcards/refcard.tex (section{Leaving Emacs}): Put iconify
+ Emacs ahead of suspend.
+
+2021-09-17 Stefan Kangas <stefan@marxist.se>
+
+ checkdoc: 'y-or-n-p' no longer needs space
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-message-text-engine):
+ Change 'y-or-n-p' check to accept prompt ending with both "? " or "?",
+ that is, it no longer needs the space. (Bug#50621)
+ (checkdoc--fix-y-or-n-p): New helper function.
+ * test/lisp/emacs-lisp/checkdoc-tests.el (checkdoc-tests-fix-y-or-n-p)
+ (checkdoc-tests-fix-y-or-n-p/no-change)
+ (checkdoc-tests-fix-y-or-n-p/with-space): New tests.
+
+2021-09-17 Robert Pluim <rpluim@gmail.com>
+
+ Move emoji fontset addition later
+
+ * lisp/international/fontset.el (setup-default-fontset): Move the
+ fontset addition for emoji script after that for various graphic-like
+ characters, since they overlap, and we want the emoji setting to win.
+
+2021-09-17 Martin Joerg <martin.joerg@gmail.com> (tiny change)
+
+ * lisp/net/tramp-sh.el (tramp-methods) <rsync>: Separate "%c" marker.
+
+2021-09-17 Robert Pluim <rpluim@gmail.com>
+
+ Fix emoji-induced build breakage
+
+ * admin/unidata/blocks.awk: Cater for out-of-tree builds, match
+ the name of the file using regexp rather than exact match.
+
+2021-09-17 Uwe Brauer <oub@mat.ucm.es>
+
+ Replace hex representation by its literal form in pretty tex symbols
+
+ * lisp/textmodes/tex-mode.el (tex--prettify-symbols-alist):
+ Correct error \Bbb{T}, replace hex representation by its literal
+ form (bug#50645).
+
+2021-09-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak how term-emulate-terminal selects windows
+
+ * lisp/term.el (term-emulate-terminal): Don't record the selection
+ of the window here, because we're not doing a user-level window
+ selection, but just selecting the window for internal purposes
+ (bug#41984).
+
+2021-09-17 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/elisp-mode.el (elisp-context-menu): Improve menu items.
+
+2021-09-17 Juri Linkov <juri@linkov.net>
+
+ * lisp/repeat.el (repeat-echo-message): Clear only own added part of message.
+
+ (describe-repeat-maps, repeat-mode): Refer to each other in docstrings.
+
+2021-09-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Stop imenu indexing after a certain number of seconds
+
+ * doc/emacs/programs.texi (Imenu): Document it.
+ * lisp/imenu.el (imenu-max-index-time): New user option.
+ (imenu-default-create-index-function, imenu--generic-function):
+ Use it (bug#18696).
+
+2021-09-17 Manuel Giraud <manuel@ledu-giraud.fr>
+
+ Fix typo in idlwave
+
+ * lisp/progmodes/idlwave.el (idlwave-keyword-abbrev): Fix typo
+ (bug#50638).
+
+2021-09-17 Uwe Brauer <oub@mat.ucm.es>
+
+ Add more symbols to tex--prettify-symbols-alist
+
+ * lisp/textmodes/tex-mode.el (tex--prettify-symbols-alist): Add
+ mathbb, caligraphic letters, fractur, varkappa and
+ \|. (bug#50639).
+
+2021-09-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention that the garbage collection is convervative
+
+ * doc/lispref/internals.texi (Garbage Collection): Mention that
+ we're using a conservative gc (bug#42013).
+
+2021-09-17 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ MH-E: fix check for nmh or Mailutils installation
+
+ * lisp/mh-e/mh-e.el (mh-variant-gnu-mh-info, mh-variant-nmh-info):
+ Run install-mh, not mhparam, to check whether an MH variant is
+ installed on the system. mhparam fails if no user profile is found,
+ so it is not a reliable check of the state of the system as a whole.
+
+ Tested with:
+ nmh 1.4, nmh 1.7.1, GNU Mailutils 2.2, GNU Mailutils 3.7, GNU Mailutils 3.13
+
+2021-09-17 Eli Zaretskii <eliz@gnu.org>
+
+ Fix display of stretch glyphs
+
+ * src/xterm.c (x_draw_stretch_glyph_string):
+ * src/w32term.c (w32_draw_stretch_glyph_string): Fix drawing
+ stretch glyphs when the window is hscrolled. (The original
+ pre-Jan-2021 code was almost correct, except that it used
+ 'window_box_left_offset' instead of 'window_box_left', and didn't
+ restrict the background_width fixup to text-area.) (Bug#50564)
+
+2021-09-17 Robert Pluim <rpluim@gmail.com>
+
+ Split Unicode emoji into their own script
+
+ * admin/notes/unicode: Describe how to update emoji for new Unicode release.
+ * admin/unidata/Makefile.in: Pass emoji-data.txt to
+ blocks.awk script.
+ * admin/unidata/README: Add pointer to emoji-data.txt file.
+ * admin/unidata/blocks.awk: Parse emoji-data.txt, add emoji codepoints
+ to the 'emoji' script (except for the ASCII ones).
+ * admin/unidata/emoji-data.txt: New file.
+ * etc/NEWS: Describe new 'emoji' script.
+ * etc/TODO: Update item about 'emoji' script.
+ * lisp/international/fontset.el (script-representative-chars): Add
+ 'emoji' script.
+ (setup-default-fontset): Add 'emoji' script. Use "Noto Color Emoji"
+ as default font for it.
+
+2021-09-17 Dmitry Gutov <dgutov@yandex.ru>
+
+ xref-matches-in-files: Move sorting to Lisp
+
+ For better compatibility with different systems.
+ Performance is unaffected, except in very pathological cases
+ (~100000 matches), and even then the overhead of 'sort' is comparable.
+
+ * lisp/progmodes/xref.el (xref-search-program-alist):
+ Drop the piping through 'sort'.
+ (xref-matches-in-files): Sort here instead.
+ Do that to both searchers' output as well now.
+
+2021-09-17 Eli Zaretskii <eliz@gnu.org>
+
+ Improve the documentation of a recent change
+
+ * etc/NEWS:
+ * doc/lispref/sequences.texi (Sequence Functions): Improve
+ documentation of 'seq-union'.
+
+2021-09-17 Stefan Kangas <stefan@marxist.se>
+
+ Improve performance of seq-union
+
+ * lisp/emacs-lisp/seq.el (seq-union): Improve performance by using
+ nreverse instead of seq-reverse.
+
+2021-09-17 Stefan Kangas <stefan@marxist.se>
+
+ Make viper-subseq into obsolete alias for cl-subseq
+
+ * lisp/emulation/viper-util.el (viper-subseq): Make into obsolete
+ function alias for 'cl-subseq'. Update callers.
+
+2021-09-17 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/vc/ediff-util.el (ediff-member): Make obsolete.
+
+2021-09-17 Stefan Kangas <stefan@marxist.se>
+
+ Make ediff-set-difference into obsolete alias for seq-difference
+
+ * lisp/vc/ediff-util.el (ediff-set-difference): Make into obsolete
+ function alias for 'seq-difference'.
+ * lisp/vc/ediff-mult.el (ediff-intersect-directories): Update single caller.
+
+2021-09-17 Stefan Kangas <stefan@marxist.se>
+
+ Make ediff-intersection into obsolete alias for seq-intersection
+
+ * lisp/vc/ediff-util.el (ediff-intersection): Make into obsolete
+ function alias for 'seq-intersection'.
+ * lisp/vc/ediff-mult.el (ediff-intersect-directories): Update
+ single caller.
+
+2021-09-17 Stefan Kangas <stefan@marxist.se>
+
+ Make ediff-union into obsolete alias for seq-union
+
+ * lisp/emacs-lisp/seq.el (seq-union): Autoload.
+ * lisp/vc/ediff-util.el (ediff-union): Make into obsolete function
+ alias for 'seq-union'.
+ * lisp/vc/ediff-mult.el (ediff-intersect-directories): Update single
+ caller.
+
+2021-09-17 Stefan Kangas <stefan@marxist.se>
+
+ Add new sequence function 'seq-union'
+
+ * lisp/emacs-lisp/seq.el (seq-union): New function.
+ * doc/lispref/sequences.texi (Sequence Functions):
+ * lisp/emacs-lisp/shortdoc.el (sequence): Document above new
+ function.
+ * test/lisp/emacs-lisp/seq-tests.el (test-seq-union): New test.
+
+2021-09-17 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/allout.el (allout-old-expose-topic): Make obsolete.
+
+2021-09-17 John Cummings <john@rootabega.net> (tiny change)
+
+ Fix disk-free info in 'insert-directory'
+
+ * lisp/files.el (insert-directory): Call 'get-free-disk-space'
+ with the argument FILE, to make sure the reported info is for the
+ correct volume. (Bug#50630)
+
+2021-09-17 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix annoyance in tramp-smb.el
+
+ * lisp/net/tramp-smb.el (tramp-smb-maybe-open-connection):
+ Add "TERM=dumb".
+
+2021-09-17 Olivier Certner <olce.emacs@certner.fr>
+ F. Jason Park <jp@neverwas.me>
+
+ ERC: NickServ: Prompt for password last, overall simplifications (bug#46777)
+
+ When 'erc-prompt-for-nickserv-password' is non-nil, don't ignore the
+ other forms of identification. Instead, process them first, and
+ prompt for the password last. Separate concerns (determination of the
+ nick to use, of the password to use, and actual message sending).
+
+ Note that the user can be interactively prompted for a password on
+ reception of a NickServ request, as before (on
+ 'erc-prompt-for-nickserv-password').
+
+ * lisp/erc/erc-services.el (erc-nickserv-identify): Make the password
+ argument optional (and don't prompt for it interactively). Further,
+ now take the nick to use for identification (interactively, ask for
+ it, defaulting to the current one). Move the actual message sending
+ into the new 'erc-nickserv-send-identify' function, and the password
+ prompting into 'erc-nickserv-get-password'.
+
+ (erc-nickserv-send-identify): New function containing the code for
+ sending the identify message to NickServ, given the nick and password.
+
+ (erc-nickserv-get-password): Try each password source in turn, in the
+ following order: 'erc-nickserv-passwords', auth-source (if
+ 'erc-use-auth-source-for-nickserv-password' is non-nil), and in the
+ end prompt the user interactively (if
+ 'erc-prompt-for-nickserv-password' is non-nil). If one source returns
+ a string, the function returns it, or nil if the string is empty.
+
+ (erc-nickserv-call-identify-function): Declare obsolete, but retain
+ for backward compatibility. Prefer invoking 'erc-nickserv-identify'
+ directly instead.
+
+ (erc-nickserv-identify-autodetect, erc-nickserv-identify-on-connect)
+ (erc-nickserv-identify-on-nick-change): Call 'erc-nickserv-identify'
+ directly ('erc-nickserv-call-identify-function' has been obsoleted).
+ For the last two functions, remove the redundant checks on the
+ NickServ identification flags (additionally, it is doubtful they have
+ any measurable impact on performance).
+
+ * etc/NEWS: Announce the change.
+
+2021-09-17 Amin Bandali <bandali@gnu.org>
+
+ * lisp/erc/erc-button.el (erc-emacswiki-url): Update to shorter address.
+
+2021-09-17 Alfred M. Szmidt <ams@gnu.org>
+
+ * lisp/vc/vc.el: API doc fixes.
+
+2021-09-17 Manuel Giraud <manuel@ledu-giraud.fr>
+
+ Reuse vc-read-backend more
+
+ * lisp/vc/vc.el (vc-read-backend): New optional arguments.
+ (vc-create-repo): Use it here.
+ (vc-switch-backend): And here (bug#50603).
+
+2021-09-16 Stefan Kangas <stefan@marxist.se>
+
+ Docfix: use command substitution for 'universal-argument'
+
+ * lisp/autoarg.el (autoarg-mode):
+ * lisp/bookmark.el (bookmark-set, bookmark-set-no-overwrite)
+ (bookmark-save):
+ * lisp/calendar/todo-mode.el (todo-insert-item)
+ (todo-filter-top-priorities)
+ (todo-filter-top-priorities-multifile):
+ * lisp/dired-x.el (dired-mark-extension, dired-mark-suffix):
+ * lisp/eshell/eshell.el (eshell):
+ * lisp/gnus/gnus-group.el (gnus-group-find-new-groups):
+ * lisp/gnus/gnus-start.el (gnus-find-new-newsgroups):
+ * lisp/gnus/gnus-sum.el (gnus-summary-show-article):
+ * lisp/gnus/gnus.el (gnus-secondary-servers):
+ * lisp/org/org-timer.el (org-timer-set-timer):
+ * lisp/org/ox.el (org-export-dispatch-last-position):
+ * lisp/printing.el (pr-ps-directory-preview)
+ (pr-ps-directory-using-ghostscript, pr-ps-directory-print)
+ (pr-ps-directory-ps-print, pr-ps-buffer-preview)
+ (pr-ps-buffer-using-ghostscript, pr-ps-buffer-print)
+ (pr-ps-buffer-ps-print, pr-despool-preview)
+ (pr-despool-using-ghostscript, pr-despool-print)
+ (pr-despool-ps-print, pr-ps-file-up-ps-print, pr-ps-fast-fire)
+ (pr-txt-fast-fire):
+ * lisp/progmodes/idlwave.el (idlwave-complete):
+ * lisp/progmodes/sh-script.el (sh-set-shell):
+ * lisp/replace.el (occur):
+ * lisp/ses.el (ses--advice-yank):
+ * lisp/simple.el (set-mark-command-repeat-pop):
+ * lisp/sort.el (delete-duplicate-lines):
+ * lisp/strokes.el (strokes-help):
+ * lisp/textmodes/artist.el (artist-mode):
+ * lisp/textmodes/reftex-cite.el (reftex-citation):
+ * lisp/textmodes/reftex-dcr.el (reftex-view-crossref):
+ * lisp/textmodes/reftex-index.el (reftex-index-selection-or-word)
+ (reftex-display-index):
+ * lisp/textmodes/reftex-ref.el (reftex-reference):
+ * lisp/textmodes/reftex-toc.el (reftex-toc):
+ * lisp/textmodes/reftex-vars.el (reftex-cite-prompt-optional-args)
+ (reftex-enable-partial-scans):
+ * lisp/textmodes/texnfo-upd.el (texinfo-master-menu):
+ * lisp/windmove.el (windmove-display-in-direction)
+ (windmove-delete-left, windmove-delete-up)
+ (windmove-delete-right, windmove-delete-down):
+ * lisp/window.el (recenter-window-group, recenter-other-window): Use
+ command substitution for 'universal-argument' instead of raw "C-u".
+
+2021-09-16 Michael Albinus <michael.albinus@gmx.de>
+
+ Tramp code cleanup
+
+ * lisp/net/tramp-sh.el (tramp-methods) <telnet, nc>:
+ Reintroduce "%n" marker.
+ (tramp-maybe-open-connection): Handle it.
+
+ * lisp/net/tramp.el (tramp-prefix-regexp):
+ * lisp/net/tramp-smb.el (tramp-smb-options): Fix docstring.
+
+ * lisp/net/tramp*.el: Fix typos. Remove trailing space from
+ `yes-or-no-p' and `y-or-n-p' prompts.
+
+ * test/lisp/net/tramp-tests.el (tramp--test-telnet-p): New defun.
+ (tramp-test29-start-file-process, tramp-test30-make-process)
+ (tramp-test35-remote-path, tramp-test44-asynchronous-requests):
+ Adapt tests.
+
+2021-09-16 Wilson Snyder <wsnyder@wsnyder.org>
+
+ verilog-mode.el: Merge from upstream: prepare for lexical bindings.
+
+ * lisp/progmodes/verilog-mode.el (verilog-do-indent)
+ (verilog-indent-declaration, verilog-read-always-signals-recurse)
+ (verilog-read-decls): Prepare for lexical bindings.
+
+2021-09-16 Eli Zaretskii <eliz@gnu.org>
+
+ Support '...' quoting in Lisp files
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-el-font-lock-keywords-2):
+ Support quoting 'like this'.
+
+2021-09-16 Augusto Stoffel <arstoffel@gmail.com>
+
+ Make 'compile' respect buffer-local process environment
+
+ * lisp/progmodes/compile.el (compilation-start): Use
+ `process-environment' from original buffer in the compilation
+ process (bug#50607).
+
+2021-09-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Bind `M-o' in html-mode and enriched-mode
+
+ * lisp/textmodes/enriched.el (enriched-mode-map): Actually define
+ the `M-o' face map.
+
+ * lisp/textmodes/sgml-mode.el (html-mode-map): Ditto (bug#50616).
+
+ * lisp/textmodes/sgml-mode.el (html-mode): Adjust doc string.
+
+2021-09-16 Kevin Brubeck Unhammer <unhammer@fsfe.org>
+
+ Allow irc network symbols in erc-autojoin-channels-alist
+
+ * lisp/erc/erc-join.el (erc-autojoin-channels-alist): Explain the
+ extension.
+ (erc-autojoin-server-match): New function.
+ (erc-autojoin-channels): Use it.
+ (erc-autojoin-current-server): New function.
+ (erc-autojoin-add): Use it.
+ (erc-autojoin-remove): Ditto.
+
+ This can be useful when connecting to an IRC proxy like Weechat that
+ relays several networks under the same server. If we just keyed on the
+ server name, we would end up joining a channel on all networks
+ whenever we join one network on that server.
+
+ Networks are simply stored as symbols instead of regexes, since that's
+ how `erc-network' works.
+
+ The `erc-autojoin-add' function will still auto-add servers as strings
+ if the network doesn't have at least one entry in
+ `erc-autojoin-channels-alist'.
+
+2021-09-16 Stefan Kangas <stefan@marxist.se>
+
+ Prefer "website" to "homepage"
+
+ These days, a "home page" is understood to be only "the main web page
+ of a website" or "landing page", whereas a "website" is "a collection
+ of web pages and related content" (Wikipedia).
+
+ * doc/emacs/emacs.texi (Top):
+ * doc/emacs/package.texi (Package Menu):
+ * doc/lispintro/emacs-lisp-intro.texi (Top):
+ * doc/lispref/elisp.texi (Top):
+ * doc/lispref/tips.texi (Documentation Tips):
+ * doc/misc/ede.texi (ede-project):
+ * doc/misc/efaq-w32.texi (More information):
+ * doc/misc/gnus-faq.texi (FAQ 5-7):
+ * doc/misc/gnus.texi (About mairix):
+ * doc/misc/mairix-el.texi (About):
+ * doc/misc/reftex.texi (AUCTeX, Imprint):
+ * lisp/cedet/ede/base.el (ede-project):
+ * lisp/cedet/ede/system.el (ede-web-browse-home):
+ * lisp/emacs-lisp/package.el (package-menu-mode-menu)
+ (package-browse-url):
+ * lisp/erc/erc-button.el (erc-emacswiki-url):
+ * lisp/filesets.el (filesets-goto-homepage):
+ * lisp/net/mairix.el:
+ * lisp/net/webjump.el (webjump-sample-sites):
+ * lisp/obsolete/vc-arch.el:
+ * lisp/progmodes/idlw-shell.el (idlwave-shell-mode):
+ * lisp/progmodes/idlwave.el (idlwave, idlwave-mode):
+ * lisp/textmodes/reftex-vars.el (reftex):
+ Prefer "website" to "home page".
+
+ * doc/lispref/tips.texi (Documentation Tips):
+ Sort the "URL" header comment before "Homepage".
+
+ * lisp/emacs-lisp/lisp-mnt.el
+ (lm-website): Rename from 'lm-homepage'.
+ (lm-homepage): Make into alias for 'lm-website'.
+
+2021-09-16 F. Jason Park <jp@neverwas.me>
+
+ Change the erc debug logging format to be more repeatable
+
+ * lisp/erc/erc.el (erc-debug-irc-protocol): Fix line-ending
+ mismatch between incoming and outgoing logger lines without
+ changing interface. Do this by adding carriage returns to the
+ latter to improve machine readability. Change printed peer labels
+ to most accurately reflect logical endpoints.
+
+ (erc-debug-irc-protocol-time-format): Add new variable to support
+ timestamps in protocol logger output.
+
+ (erc-debug-irc-protocol-version): Add new variable to help tooling
+ track logging format independent of ERC and Emacs versions.
+
+ (erc-toggle-debug-irc-protocol): Add headers to protocol-log buffer
+ to aid future bug-reproduction tools. Clean up overlong lines (bug#50009).
+
+2021-09-16 F. Jason Park <jp@neverwas.me>
+
+ Fix erc nick trimming
+
+ * lisp/erc/erc.el (erc-lurker-maybe-trim): Prevent warning from
+ showing up in third-party code using this function by autoloading
+ rx.el when needed. Remove trailing chars appended for uniquifying
+ purposes when a nick is already taken. Special thanks to Mattias
+ Engdegård for making this more respectable (Bug#50005).
+
+ * test/lisp/erc/erc-tests.el: Add tests for the above and require
+ erc-networks.
+
+2021-09-16 F. Jason Park <jp@neverwas.me>
+
+ Fix mistake in test for erc-ring-previous-command
+
+ * test/lisp/erc/erc-tests.el (erc-ring-previous-command):
+ The variable erc-send-completed-hook was previously set to nil
+ permanently, which would affect other tests (bug#50005).
+
+2021-09-16 Stefan Kangas <stefan@marxist.se>
+
+ Do interactive mode tagging for play/*.el
+
+2021-09-16 Eli Zaretskii <eliz@gnu.org>
+
+ Clarify use of early-init file
+
+ * doc/emacs/custom.texi (Early Init File): Clarify that using the
+ early-init file should be reserved to cases where it is absolutely
+ necessary. (Bug#50491)
+
+2021-09-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify test-completion doc string
+
+ * src/minibuf.c (Ftest_completion): Clarify what it means to be a
+ valid completion (bug#50583).
+
+2021-09-16 Stefan Kangas <stefan@marxist.se>
+
+ Remove references to dead packages
+
+ * etc/themes/manoj-dark-theme.el: Delete references to colortheme and
+ emacs-goodies.
+
+2021-09-16 Stefan Kangas <stefan@marxist.se>
+
+ Make a redundant idlwave variable obsolete
+
+ * lisp/progmodes/idlw-help.el (idlwave-help-browse-url-available):
+ Make obsolete.
+ (idlwave-help-check-locations): Don't use above variable.
+
+2021-09-16 Stefan Kangas <stefan@marxist.se>
+
+ Various minor checkdoc tweaks
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-symbol-words): Add more
+ "good" words that are used a lot in practice, and where using them
+ doesn't really hurt the quality of the documentation.
+ (checkdoc-proper-noun-list): Add "dired", remove "ispell"; the
+ latter should not always be capitalized.
+ (checkdoc-common-verbs-wrong-voice): Add some more common words.
+ Don't check for "matches" as it leads to too many false positives and
+ almost no fixes in practice.
+ (checkdoc-this-string-valid-engine): Clarify comment.
+ (checkdoc-in-abbreviation-p): Ignore some less common or non-standard
+ abbreviations.
+
+2021-09-16 Stefan Kangas <stefan@marxist.se>
+
+ Doc fix for y-or-n-p; trailing space is no longer needed
+
+ * doc/lispref/minibuf.texi (Yes-or-No Queries):
+ * doc/lispref/os.texi (Suspending Emacs):
+ * doc/lispref/tips.texi (Programming Tips):
+ * doc/misc/gnus-faq.texi (FAQ 5-9):
+ * lisp/subr.el (y-or-n-p):
+ * src/fns.c (Fyes_or_no_p): Doc fix to reflect that a trailing space
+ is no longer needed; one is added or removed automatically.
+
+2021-09-16 Stefan Kangas <stefan@marxist.se>
+
+ * doc/misc/pgg.texi: Clarify that its obsolete in the menu entry.
+
+2021-09-15 Stefan Kangas <stefan@marxist.se>
+
+ Remove function obsolete since 22.1
+
+ * lisp/erc/erc-networks.el (erc-current-network): Remove function
+ obsolete since Emacs 22.1.
+
+2021-09-15 Eli Zaretskii <eliz@gnu.org>
+
+ Documentation followup to a recent commit
+
+ * doc/lispref/tips.texi (Documentation Tips): Make the wording of
+ recommendation not to over-use \\[..] more future-proof.
+ (Bug#50599)
+
+2021-09-15 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Evaluate recent isearch-motion lambdas
+
+ * lisp/isearch.el (beginning-of-buffer, end-of-buffer)
+ (scroll-up-command, scroll-down-command): Evaluate the lambdas
+ inside the isearch-motion properties of these commands.
+
+2021-09-15 Stefan Kangas <stefan@marxist.se>
+
+ checkdoc: Don't warn about command substitutions by default
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-max-keyref-before-warn):
+ Add new valid value nil meaning to never warn about too many command
+ substitutions, and use this value as the default. This is no longer a
+ performance problem on modern machines. (Bug#50599)
+ (checkdoc-this-string-valid-engine): Respect above new valid value
+ nil.
+
+2021-09-15 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-line.el: Add context menu bound to down-mouse-3 like on tab bar.
+
+ * lisp/tab-line.el: Bind tab-line down-mouse-3 to tab-line-context-menu.
+ (tab-line-tab-map): Rebind tab-line-select-tab from mouse-1 to down-mouse-1.
+ Bind down-mouse-3 to tab-line-tab-context-menu.
+ (tab-line-add-map): Rebind tab-line-new-tab from mouse-1 to down-mouse-1.
+ (tab-line-left-map, tab-line-right-map): Rebind mouse-1 to down-mouse-1.
+ (tab-line-tab-context-menu, tab-line-context-menu): New functions.
+ (tab-line-hscroll-right, tab-line-hscroll-left)
+ (tab-line-new-tab, tab-line-select-tab)
+ (tab-line-switch-to-prev-tab, tab-line-switch-to-next-tab)
+ (tab-line-close-tab): Rename event args to 'event'.
+
+2021-09-15 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-format): Add new option tab-bar-format-menu-global
+
+ (tab-bar-format-menu-global): New function.
+
+2021-09-15 Juri Linkov <juri@linkov.net>
+
+ Add docstrings to context menu functions, and add middle-separator
+
+ * lisp/mouse.el (context-menu-functions): Add context-menu-middle-separator
+ to default values.
+ (context-menu-middle-separator): New function.
+
+ * lisp/replace.el (occur-context-menu): Use middle-separator.
+
+ * lisp/progmodes/elisp-mode.el (elisp-context-menu):
+ * lisp/progmodes/prog-mode.el (prog-context-menu):
+ Use middle-separator and reorder menu items correspondingly.
+
+2021-09-15 Philip Kaludercic <philipk@posteo.net>
+
+ Merge branch 'feature/rcirc-update'
+
+2021-09-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak python-hideshow-forward-sexp-function warning avoidance
+
+ * lisp/progmodes/python.el
+ (python-hideshow-forward-sexp-function): Avoid compilation warning
+ in a more standard way. Problem reported in
+ https://thedailywtf.com/articles/the-programmer-s-motto-and-other-comments
+
+2021-09-15 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid crashes due to clearing of a frame's face cache
+
+ * src/xfaces.c (clear_face_cache): Don't clear fonts and faces of
+ a frame that is being redisplayed, just because it's time for some
+ routine maintenance. (Bug#50571)
+ * src/xdisp.c (redisplay_internal):
+ * src/frame.h (struct frame) <inhibit_clear_image_cache>: Update
+ commentary of using this struct member.
+
+2021-09-15 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp-sh.el (tramp-methods): <sudo>: Change template. (Bug#50594)
+
+2021-09-15 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid compiler warnings in comp.c on MS-Windows
+
+ * src/comp.c (DEF_DLL_FN, init_gccjit_functions): Don't load and
+ don't define functions/macros if libgccjit doesn't have them, to
+ avoid compiler warnings.
+
+2021-09-15 Mattias Engdegård <mattiase@acm.org>
+
+ Faster grep pattern for identifiers
+
+ * lisp/cedet/semantic/symref/grep.el (semantic-symref-perform-search):
+ Use the `-w` flag instead of wrapping the pattern in regexps that make
+ matching much slower. This speeds up `xref-find-references` by about
+ 3× on macOS.
+
+2021-09-15 Eli Zaretskii <eliz@gnu.org>
+
+ Update Unicode support to Unicode version 14.0.0
+
+ * admin/unidata/copyright.html:
+ * admin/unidata/UnicodeData.txt:
+ * admin/unidata/Blocks.txt:
+ * admin/unidata/BidiBrackets.txt:
+ * admin/unidata/BidiMirroring.txt:
+ * admin/unidata/IVD_Sequences.txt:
+ * admin/unidata/NormalizationTest.txt:
+ * admin/unidata/SpecialCasing.txt:
+ * test/manual/BidiCharacterTest.txt: Updated files from Unicode
+ 14.0.
+
+ * lisp/international/fontset.el (script-representative-chars): Add
+ new scripts.
+ (otf-script-alist): Update from latest version.
+ (setup-default-fontset): Add new scripts.
+ * lisp/international/characters.el: Update syntax and category
+ tables for new characters and scripts.
+ (char-width-table): Update for changes in Unicode 14.0.
+ * lisp/international/mule-cmds.el (ucs-names): Update used and
+ unused ranges per Unicode 14.0.
+
+ * test/lisp/international/ucs-normalize-tests.el
+ (ucs-normalize-tests--failing-lines-part1)
+ (ucs-normalize-tests--failing-lines-part2): Update per the test
+ results.
+
+ * doc/lispref/nonascii.texi (Character Properties): Update Unicode
+ version number.
+
+ * etc/NEWS: Announce support for Unicode 14.0.
+
+ * admin/notes/unicode: Minor copyedits.
+
+2021-09-15 João Távora <joaotavora@gmail.com>
+
+ * doc/misc/flymake.texi: Fix @include docstyle.texi
+
+2021-09-15 Augusto Stoffel <arstoffel@gmail.com>
+
+ Python shell: rearrange printing of newline before output
+
+ * lisp/progmodes/python.el
+ (python-shell-output-filter-in-progress)
+ (python-shell-output-filter-buffer): Move defvars to avoid compiler
+ warnings.
+ (python-shell-eval-setup-code): Don't print a newline in
+ __PYTHON_EL_eval.
+ (python-shell-send-string): Insert newline before output when
+ applicable (bug#50514).
+
+2021-09-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make bookmark fringe marks evaporate
+
+ * lisp/bookmark.el (bookmark--set-fringe-mark): Make the bookmark
+ evaporate when a buffer is erased (like, for instance, when doing
+ `revert-buffer' in a vc buffer).
+
+2021-09-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention `lisp-data-mode' in `emacs-lisp-mode' doc string
+
+ * lisp/progmodes/elisp-mode.el (emacs-lisp-mode): Mention
+ `lisp-data-mode'.
+
+2021-09-15 Juri Linkov <juri@linkov.net>
+
+ Adjust occur-context-menu and elisp-context-menu
+
+ * lisp/progmodes/elisp-mode.el (elisp-context-menu): Add separator
+ only when there is a symbol at mouse click.
+
+ * lisp/replace.el (occur-context-menu): Insert items in the middle
+ of the menu after mark-whole-buffer.
+
+2021-09-15 Philip Kaludercic <philipk@posteo.net>
+
+ Add occur-related context-menu operations (bug#50552)
+
+ * lisp/replace.el (occur-word-at-mouse): Add new command.
+ (occur-symbol-at-mouse): Add new command.
+ (occur-context-menu): Add new function.
+
+2021-09-15 Juri Linkov <juri@linkov.net>
+
+ * lisp/window.el (display-buffer-in-previous-window): Add symbolp (bug#50576)
+
+2021-09-15 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-close-other-tabs): Add arg ‘tab-number’.
+
+ (tab-bar-mouse-context-menu): Bind menu-item "Close other tabs" to
+ tab-bar-close-other-tabs with arg ‘tab-number’.
+
+2021-09-15 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: Rename args to consistent naming convention.
+
+ Use the same naming scheme for function arguments. Use the term "index" when
+ arguments count from 0, and the term "number" when arguments count from 1.
+
+ * lisp/tab-bar.el (tab-bar-select-tab): Rename ‘arg’ to ‘tab-number’.
+ (tab-bar-move-tab-to): Rename ‘from-index’ to ‘from-number’
+ and ‘to-index’ to ‘to-number’.
+ (tab-bar-move-tab-to-frame): Rename ‘from-index’ to ‘from-number’
+ and ‘to-index’ to ‘to-number’.
+ (tab-bar-new-tab-to): Rename ‘to-index’ to ‘tab-number’.
+ (tab-bar-close-tab): Rename ‘arg’ to ‘tab-number’
+ and ‘to-index’ to ‘to-number’.
+ (tab-bar-rename-tab): Rename ‘arg’ to ‘tab-number’.
+ (tab-bar-change-tab-group): Rename ‘arg’ to ‘tab-number’.
+
+2021-09-15 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ * lisp/mh-e/mh-e.el: Simplify file commentary for a native package.
+
+2021-09-15 Dmitry Gutov <dgutov@yandex.ru>
+
+ Localize namespace-filtering code
+
+ To be able to filter results coming from
+ elisp-xref-find-def-functions, and for general ease of
+ understanding.
+
+ * lisp/progmodes/elisp-mode.el (elisp--xref-find-definitions):
+ Undo the previous change.
+ (xref-backend-apropos): Update accordingly.
+ (elisp--xref-filter-definitions): New function.
+ (xref-backend-definitions): Use it to post-filter the results
+ coming from elisp--xref-find-definitions.
+
+ * test/lisp/progmodes/elisp-mode-tests.el (find-defs-minor-defvar-c):
+ New test.
+ (find-defs-defun-defvar-el): Update test.
+
+2021-09-15 Wilson Snyder <wsnyder@wsnyder.org>
+
+ verilog-mode.el: Update verilog-mode from upstream.
+
+ * lisp/progmodes/verilog-mode.el: (verilog-basic-complete-re)
+ (verilog-behavioral-block-beg-re, verilog-defun-keywords)
+ (verilog-defun-level-generate-only-re, verilog-defun-level-re)
+ (verilog-endcomment-reason-re, verilog-indent-re) (verilog-keywords,
+ verilog-no-indent-begin-re) (verilog-set-auto-endcomments): Support
+ Verilog-A `analog` blocks (#1738). Reported by Dan McMahill.
+ (verilog-read-defines): Fix verilog-read-defines to work
+ with SystemVerilog types (#1734). Reported by Shareef Jalloq.
+ (verilog-indent-declaration,
+ verilog-pretty-declarations): Fix leaving extra spaces before tabs on
+ lining up declarations. (#1723) Reported by TAKAI Kousuke.
+ (verilog-auto-inst, verilog-auto-inst-port)
+ (verilog-read-auto-template-middle, verilog-read-sub-decls-line):
+ Support AUTONOHOOKUP to not AUTOWIRE hookup AUTO_TEMPLATE signals. (#1526)
+ Reported by firefoxtc.
+
+2021-09-15 Glenn Morris <rgm@gnu.org>
+
+ * test/Makefile.in (XDG_CONFIG_HOME): Don't export (bug#50577).
+
+2021-09-14 Glenn Morris <rgm@gnu.org>
+
+ * doc/misc/flymake.texi: Avoid xrefs in @copying.
+
+ This isn't really what @copying is for, and doesn't work with
+ makeinfo 4.13.
+
+2021-09-14 Philip Kaludercic <philipk@posteo.net>
+
+ Fix interactive forms for rcirc-define-command
+
+ * lisp/net/rcirc.el (rcirc-define-command): Handle string
+ descriptors correctly.
+
+2021-09-14 Philip Kaludercic <philipk@posteo.net>
+
+ Unset mode-line-process for all buffers on reconnecting
+
+ * lisp/net/rcirc.el (rcirc-sentinel): Add loop over all managed
+ buffers.
+
+2021-09-14 Philip Kaludercic <philipk@posteo.net>
+
+ Restore rcirc-target if possible
+
+ * lisp/net/rcirc.el (rcirc-process-message): Extract target from buffer name
+
+2021-09-14 João Távora <joaotavora@gmail.com>
+
+ Unbreak make bootstrap (don't use cl-defun's &aux parameters)
+
+ * lisp/progmodes/flymake.el (flymake--handle-report): Don't use &aux.
+
+2021-09-14 Philip Kaludercic <philipk@posteo.net>
+
+ Display server buffer after connecting
+
+ * lisp/net/rcirc.el (rcirc-display-server-buffer): Add new option
+ (rcirc): Respect rcirc-display-server-buffer
+
+2021-09-14 Philip Kaludercic <philipk@posteo.net>
+
+ Allow for multiple attempts when reconnecting
+
+ * doc/misc/rcirc.texi (rcirc commands): Mention rcirc-reconnect-attempts
+ * etc/NEWS: Document change
+ (rcirc-connect): Ensure no other process exists
+ (rcirc-reconnect-attempts): Add option
+ (rcirc-failed-attempts): Add local variable
+ (rcirc-reconnection-timer): Add local variable
+ (rcirc-reconnect): Add function
+ (rcirc-sentinel): Manage multiple reconnection attempts
+ (rcirc-process-server-response): Change user for error messages
+ (rcirc-mode): Don't set rcirc-last-connect-time
+ (reconnect): Extract functionality to rcirc-reconnect
+
+2021-09-14 Philip Kaludercic <philipk@posteo.net>
+
+ * doc/misc/rcirc.texi (Hacking and Tweaking): Add missing section
+ to menu.
+
+2021-09-14 Philip Kaludercic <philipk@posteo.net>
+
+ * lisp/net/rcirc.el (rcirc-server-alist): Add #emacs to default server list
+
+ Author:
+
+2021-09-14 Harald Jörg <haj@posteo.de>
+
+ cperl-mode.el: Allow non-ASCII Perl identifiers
+
+ Replace all "A-Z" regexp literals with unicode-aware rx constructs
+ wherever Perl allows non-ASCII identifiers.
+ * lisp/progmodes/cperl-mode.el (cperl-after-sub-regexp)
+ (cperl-after-label. cperl-sniff-for-indent)
+ (cperl-find-pods-heres, cperl-indent-exp)
+ (cperl-fix-line-spacing, cperl-imenu--create-perl-index)
+ (cperl-init-faces, cperl-find-tags):
+ Replace ASCII regex literals by unicode-aware rx constructs.
+ (cperl-init-faces): Eliminate unused lexical `font-lock-anchored'.
+ (cperl-have-help-regexp, cperl-word-at-point-hard): Allow non-ASCII
+ word characters.
+
+ * test/lisp/progmodes/cperl-mode-tests.el
+ (cperl-test-fontify-special-variables): New test for $^T
+ and $^{VARNAME}.
+ (cperl-test-ws-rx cperl-test-ws+-rx),
+ (cperl-test-version-regexp, cperl-test-package-regexp): Skip
+ for perl-mode.
+ (cperl-test-identifier-rx, cperl--test-unicode-setup)
+ (cperl-test-unicode-labels, cperl-test-unicode-sub)
+ (cperl-test-unicode-varname)
+ (cperl-test-unicode-varname-list, cperl-test-unicode-arrays)
+ (cperl-test-unicode-hashes, cperl-test-unicode-hashref)
+ (cperl-test-unicode-proto, cperl-test-unicode-fhs)
+ (cperl-test-unicode-hashkeys, cperl-test-word-at-point):
+ New tests for unicode identifiers.
+ (cperl-test-imenu-index): Add a unicode identifier to the test.
+
+ * test/lisp/progmodes/cperl-mode-resources/grammar.pl: Add a
+ function with non-ASCII name for imenu tests.
+
+2021-09-14 Glenn Morris <rgm@gnu.org>
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-symbol-words): Fix type.
+
+2021-09-14 Alan Third <alan@idiocy.org>
+
+ A further fix for toolbar visibility problems on macOS (bug#50534)
+
+ * src/nsterm.m (ns_update_begin): Ensure the toolbar's visibility is
+ set correctly.
+
+2021-09-14 Eli Zaretskii <eliz@gnu.org>
+
+ Fix recent changes in Flymake manual
+
+ * doc/misc/flymake.texi: Fix typos. Downcase the first word of
+ each index entry, for more reliable sorting.
+ (Starting Flymake, Finding diagnostics, Troubleshooting): Fix
+ typos.
+
+2021-09-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `find-function-source-path' into obsolete alias
+
+ * lisp/finder.el (finder-commentary): Adjust usage.
+
+ * lisp/emacs-lisp/find-func.el (find-function-source-path): Made
+ into obsolete alias (bug#50508).
+ (find-library-source-path): New name.
+ (find-library-name, find-library, find-function-noselect)
+ (find-variable-noselect, find-definition-noselect): Adjust usage
+ and update doc strings.
+
+2021-09-14 João Távora <joaotavora@gmail.com>
+
+ Re-organize and rewrite parts of the Flymake manual
+
+ bug#50244
+
+ * doc/misc/flymake.texi (Starting Flymake): New section.
+ (Finding diagnostics): New section, now contains info previously in
+ "Listing diagnostics"
+ (Mode line status): Renamed from "Mode-line syntax check status"
+ (Troubleshooting): Renamed from "Backend exceptions".
+ (Flymake error types): Tweak phrasing.
+
+2021-09-14 João Távora <joaotavora@gmail.com>
+
+ Add support for project-wide diagnostics in Flymake (bug#50244)
+
+ This is done with two new concepts: "foreign diagnostics" and
+ "list-only diagnostics". The manual has been updated with a
+ description of these new concepts.
+
+ * doc/misc/flymake.texi (Flymake utility functions):
+ Explain creation of foreign diagnostics.
+ (Foreign and list-only diagnostics): New subsection.
+ (Listing diagnostics): New subsection.
+
+ * lisp/progmodes/flymake.el
+ (Version): Bump to 1.2.1
+ (project): Require project.
+ (flymake--diag): Add new slots 'orig-beg' and 'orig-end'. Rename
+ 'buffer' slot to 'locus'.
+ (flymake-make-diagnostic): Rework docstring. Accept stringp
+ LOCUS arg.
+ (flymake-diagnostic-beg, flymake-diagnostic-end)
+ (flymake-diagnostic-buffer): Simplify definition.
+ (flymake--equal-diagnostic-p): New helper
+ (flymake--highlight-line): Rework. Accept FOREIGN arg.
+ (flymake--state): Work docstring. Add new slot 'foreign-diags'
+ (flymake--handle-report): Call
+ flymake--update-diagnostics-listings.
+ (flymake--handle-report): New helper.
+ (flymake--mode): Forward declare.
+ (flymake--handle-report): Rework for foreign diagnostics.
+ (flymake-mode): When turning on, notice any Flymake diagnostics
+ for current buffer. When turning off update diagnostics listings.
+ (flymake-kill-buffer-hook): Turn off flymake explicitly before
+ killing.
+ (flymake--mode-line-counter): Use flymake-diagnostics to collect
+ diagnostics.
+ (flymake-show-diagnostic): Visit buffer of file-specific
+ diagnostic.
+ (flymake--tabulated-entries-1): New helper extracted from
+ flymake--diagnostic-buffer-entries.
+ (flymake--diagnostics-buffer-entries): Rework.
+ (flymake--diagnostics-base-tabulated-list-format): New helper.
+ (flymake--diagnostics-buffer-name): Adjust.
+ (flymake-list-only-diagnostics): New variable.
+ (flymake--project-diagnostic-list-project): New variable.
+ (flymake--clear-list-only-diagnostics): New helper.
+ (flymake-project-diagnostics-mode): New major mode.
+ (flymake--project-diagnostics)
+ (flymake--project-diagnostics-entries)
+ (flymake--project-diagnostics-buffer): New helpers.
+ (flymake-show-project-diagnostics): New command.
+ (flymake--update-diagnostics-listings): New helper.
+ (flymake-show-buffer-diagnostics): Renamed from flymake-diagnostics-buffer.
+
+ * etc/NEWS: Mention change.
+
+2021-09-14 João Távora <joaotavora@gmail.com>
+
+ Bump lisp/progmodes/project.el version to 0.7.1
+
+ Amont other things exposes the new project-buffers generic function to
+ ELPA users.
+
+ * lisp/progmodes/project.el (Version): Bump to 0.7.1
+
+2021-09-14 João Távora <joaotavora@gmail.com>
+
+ Keep and report "foreign" diangnostics in flymake-cc Flymake backend
+
+ This includes diagnostics for .h files that sprang up when checking a
+ c file. Those diagnostics are reported to the Flymake infrastructure
+ which does not (yet) do anything with them.
+
+ This includes a change to the test fixtures, too.
+
+ * lisp/progmodes/flymake-cc.el (flymake-cc--make-diagnostics): Rework
+
+ * test/lisp/progmodes/flymake-resources/another-problematic-file.c:
+ New file.
+
+ * test/lisp/progmodes/flymake-resources/some-problems.h:
+ Add a function declaration..
+
+2021-09-14 João Távora <joaotavora@gmail.com>
+
+ Abbreviate Flymake backend name in flymake-show-diagnostics-buffer
+
+ * lisp/progmodes/flymake.el (flymake--diagnostics-buffer-entries):
+ (flymake-diagnostics-buffer-mode): Report abbreviated backend, too.
+
+2021-09-14 João Távora <joaotavora@gmail.com>
+
+ Unbreak M-x compile-defun of functions using flymake-log
+
+ * lisp/progmodes/flymake.el (flymake-log): Check if compilation unit
+ is indeed a string before treating it as a file name.
+
+2021-09-14 João Távora <joaotavora@gmail.com>
+
+ Refactor some Flymake functions
+
+ * lisp/progmodes/flymake.el (flymake-diagnostic-buffer): New
+ helper.
+ (flymake-diagnostic-beg, flymake-diagnostic-end): Tweak docstring.
+ (flymake--handle-report): Simplify.
+ (flymake--publish-diagnostics): Helper for flymake--handle-report.
+ (flymake--mode-line-counter, flymake-show-diagnostic)
+ (flymake--diagnostics-buffer-entries): Use
+ flymake-diagnostic-buffer, flymake-diagonstic-type,
+ flymake-diagnostic-beg.
+
+2021-09-14 João Távora <joaotavora@gmail.com>
+
+ Rename flymake--backend-state to flymake--state
+
+ The previous name was confusing and akward and dreadful to type and
+ read.
+
+ * lisp/progmodes/flymake.el (flymake--state): Rename from
+ flymake--backend-state.
+ (flymake--with-backend-state): Use flymake--state.
+ (flymake--handle-report): Use flymake--state.
+ (flymake--collect): Use flymake--state.
+ (flymake-running-backends): Use flymake--state.
+ (flymake--disable-backend): Use flymake--state.
+ (flymake--run-backend): Use flymake--state.
+ (flymake-start): Use flymake--state.
+ (flymake-mode): Use flymake--state.
+ (flymake--mode-line-title): Use flymake--state.
+ (flymake--mode-line-exception): Use flymake--state.
+ (flymake--mode-line-counter): Use flymake--state.
+
+2021-09-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Project File Commands manual clarification
+
+ * doc/emacs/maintaining.texi (Project File Commands): Clarify what
+ happens with the file name under point.
+
+2021-09-14 Alan Third <alan@idiocy.org>
+
+ Fix incorrectly appearing toolbar on NS (bug#50534)
+
+ * src/nsmenu.m (update_frame_tool_bar): Ensure both sides of the test
+ are booleans.
+ * src/nsterm.m ([EmacsWindow createToolbar:]): Make the toolbar
+ non-visible initially, in case things get out of sync. Remove call to
+ update_frame_tool_bar: the window isn't yet associated with the view,
+ so it will return immediately.
+
+2021-09-14 Alan Third <alan@idiocy.org>
+
+ Fix libgccjit detection on macOS
+
+ * configure.ac: Combine the Homebrew and MacPorts detection so they
+ will not create nonsense flags if both are installed.
+
+2021-09-14 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: Close tab only on mouse-1, not down-mouse-1 (bug#41343)
+
+ * lisp/tab-bar.el (tab-bar-mouse-select-tab): Don't close the tab
+ when clicked on the close button.
+ (tab-bar-mouse-close-tab-from-button): New function.
+ (tab-bar-map): Bind [mouse-1] to 'tab-bar-mouse-close-tab-from-button'.
+ (tab-bar-mouse-move-tab): Do nothing on non-tab events.
+
+2021-09-14 Stefan Kangas <stefan@marxist.se>
+
+ Add user option to avoid checkdoc warning for unescaped left paren
+
+ * lisp/emacs-lisp/checkdoc.el
+ (checkdoc-column-zero-backslash-before-paren): New user option to
+ avoid warning on unescaped left parenthesis in column zero.
+ (checkdoc-this-string-valid-engine): Respect above new option.
+
+2021-09-14 Stefan Kangas <stefan@marxist.se>
+
+ Minor improvements to checkdoc
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-symbol-words): Add ignored
+ values.
+ (checkdoc-proper-noun-list): Remove XEmacs from list of words to
+ capitalize; there is little need to insist on consistency here.
+ (checkdoc-in-abbreviation-p): Add abbreviation "etc." and sort entries
+ alphabetically.
+
+2021-09-13 Dmitry Gutov <dgutov@yandex.ru>
+
+ Use the term "future history" rather than "default"
+
+ * lisp/progmodes/project.el
+ (project-find-file, project-or-external-find-file):
+ Update docstring.
+ (project--read-file-cpd-relative, project--read-file-absolute)
+ (project--completing-read-strict): Rename DEFAULT to MB-DEFAULT.
+ (project-find-file-in): Rename FILENAME to SUGGESTED-FILENAME.
+
+2021-09-13 Dmitry Gutov <dgutov@yandex.ru>
+
+ Make sure to return some valid project root
+
+ * lisp/progmodes/project.el (project-prompt-project-dir):
+ If the user just pressed RET on prompt, prompt again.
+
+2021-09-13 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/elisp-mode.el (elisp-context-menu): New function (bug#9054)
+
+ (emacs-lisp-mode): Add elisp-context-menu to context-menu-functions.
+
+2021-09-13 Juri Linkov <juri@linkov.net>
+
+ * lisp/isearch.el: Improve 'isearch-allow-motion' feature (bug#50466)
+
+ * lisp/isearch.el: Add recenter to 'isearch-motion' property of
+ 'end-of-buffer' to maximize the number of search hits on the screen.
+ In 'isearch-motion' property of 'scroll-up-command' use 'recenter 0'
+ for the first line of the screen.
+ (isearch-beginning-of-buffer)
+ (isearch-end-of-buffer): Sync logic from 'isearch-allow-motion' part
+ of isearch-pre-command-hook. Direct users to isearch-allow-motion
+ in the docstrings.
+ (isearch-pre-command-hook): Don't override shifted 'isearch-yank-on-move'
+ in 'isearch-allow-motion'.
+
+2021-09-13 Mattias Engdegård <mattiase@acm.org>
+
+ Remove duplication of `find` file pattern arguments
+
+ * lisp/cedet/semantic/symref/grep.el
+ (semantic-symref-derive-find-filepatterns): Avoid including the same
+ pattern twice.
+
+2021-09-13 Andrea Corallo <akrl@sdf.org>
+
+ Clean-up some unnecessary macro usage in comp.c
+
+ * src/comp.c (emit_static_object)
+ (Fcomp_native_driver_options_effective_p, add_driver_options)
+ (Fcomp__compile_ctxt_to_file, Fcomp_libgccjit_version): Clean-up
+ unenecessary 'defined (WINDOWSNT)' usage.
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Continue NEWS tag checking
+
+ Fix typo in previous files.el change
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention unibyte issues in insert-file-contents-literally doc string
+
+ * lisp/files.el (insert-file-contents-literally): Mention possible
+ issues with multibyte buffers (bug#50560).
+
+2021-09-13 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * doc/lispref/variables.texi (named-let): Document TCO
+
+2021-09-13 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix the tests
+
+ * test/lisp/progmodes/xref-tests.el
+ (xref--xref-file-name-display-is-abs)
+ (xref--xref-file-name-display-is-nondirectory)
+ (xref--xref-file-name-display-is-relative-to-project-root):
+ Update for the latest change in xref.el.
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use a fringe mark in bookmark instead of a whole background line
+
+ * lisp/bookmark.el (bookmark-face): Adjust colors.
+ (bookmark-fringe-mark): New bitmap.
+ (bookmark--fontify): Use a fringe instead of marking the whole line.
+ (bookmark--unfontify): Adjust to remove.
+ (bookmark--jump-via): Ditto.
+ (bookmark-set-fringe-mark): Renamed from bookmark-fontify.
+ (bookmark--set-fringe-mark, bookmark--remove-fringe-mark): Renamed
+ from --*fontify. Callers adjusted.
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ NEWS copy edits and tagging
+
+ Correct nroff-mode NEWS entry after `M-o' changes
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention how to disable auto-fill-mode in the auto-fill section
+
+ * doc/lispref/text.texi (Margins): Mention how to disable
+ auto-fill-mode.
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document backtrace-on-error-noninteractive in the --batch section
+
+ * doc/emacs/cmdargs.texi (Initial Options): Mention
+ backtrace-on-error-noninteractive.
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further NEWS tagging updates
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ completions-annotations doc string clarification
+
+ * lisp/minibuffer.el (completions-annotations): Mention that it's
+ not always used.
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Update some more NEWS tagging
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention `benchmark-call' in the manual
+
+ * doc/lispref/debugging.texi (Profiling): Mention `benchmark-call'.
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Update some pcase NEWS tags for already-documented functions
+
+ Update NEWS tagging for string helper functions
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document named-let and update some NEWS tags
+
+ * doc/lispref/variables.texi (Local Variables): Document `named-let'.
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify bookmark-fontify NEWS entry
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ package-menu-execute doc string clarification
+
+ * lisp/emacs-lisp/package.el (package-menu-execute): Say what
+ happens to upgrade-marked packages (bug#50551).
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ * etc/NEWS: Clarify insert-into-buffer (bug#50558).
+
+2021-09-13 Juri Linkov <juri@linkov.net>
+
+ Support mouse events clicked on the tab bar but outside of any tab (bug#41343)
+
+ * lisp/tab-bar.el (tab-bar--key-to-number): Return non-nil non-numeric t
+ when no tab is used. Return nil for current-tab.
+ (tab-bar-mouse-select-tab, tab-bar-mouse-close-tab): Do nothing
+ when tab-bar--key-to-number returns non-nil non-numeric t
+ for click events outside of any tab.
+ (tab-bar-mouse-context-menu): Add context menu when mouse is clicked
+ outside of tabs. Add "Duplicate" alongside with "Close" to the menu
+ used when mouse is clicked on a tab.
+ (toggle-tab-bar-mode-from-frame, toggle-frame-tab-bar): Move code
+ closer to 'tab-bar-show'.
+
+ * src/xdisp.c (handle_tab_bar_click): Return Qtab_bar with empty list
+ when mouse is clicked on the tab bar but outside of any tab.
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Only do multi-isearch in eww if there's next/prev links
+
+ * lisp/net/eww.el (eww-handle-link): Only do multi-isearch if
+ there's a next/prev link in the HTML (bug#50497).
+ (eww-setup-buffer): Clear the function.
+ (eww-mode): Don't set it here.
+
+2021-09-13 Juri Linkov <juri@linkov.net>
+
+ Change value of DEFAULT_TAB_BAR_BUTTON_MARGIN from 4 to 1 (bug#50424)
+
+ * doc/emacs/frames.texi (Tab Bars): Improve documentation.
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix detection of char regions in print-fontset-element
+
+ * lisp/international/mule-diag.el (print-fontset-element): Fix the
+ regexp for "foo .. bar " (bug#50519).
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add some search-whitespace-regexp examples
+
+ * lisp/isearch.el (search-whitespace-regexp): Add some
+ alternatives in the defcustom.
+
+2021-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention get-byte in shortdoc
+
+ * lisp/emacs-lisp/shortdoc.el (buffer): Mention `get-byte' here.
+
+2021-09-13 Tassilo Horn <tsdh@gnu.org>
+
+ bug-reference.el: Adapt default debbugs bug regexp for IRC modes
+
+ * lisp/progmodes/bug-reference.el (bug-reference-setup-from-irc-alist):
+ Adapt regexp so that group 1 defines overlay region.
+
+2021-09-13 Tassilo Horn <tsdh@gnu.org>
+
+ bug-reference.el: Adapt default debbugs bug regexp for mail modes
+
+ * lisp/progmodes/bug-reference.el (bug-reference-setup-from-mail-alist):
+ Adapt regexp so that group 1 defines overlay region.
+
+2021-09-13 Stefan Kangas <stefan@marxist.se>
+
+ Declare unused function cperl-inside-parens-p obsolete
+
+ * lisp/progmodes/cperl-mode.el (cperl-inside-parens-p): Declare
+ unused function obsolete.
+
+2021-09-13 Stefan Kangas <stefan@marxist.se>
+
+ Improve checkdoc abbreviation handling
+
+ * lisp/emacs-lisp/checkdoc.el
+ (checkdoc-in-abbreviation-p): New helper function.
+ (checkdoc-sentencespace-region-engine): Fix handling abbreviations
+ after escaped parenthesis.
+
+ * test/lisp/emacs-lisp/checkdoc-tests.el
+ (checkdoc-tests-in-abbrevation-p)
+ (checkdoc-tests-in-abbrevation-p/with-parens)
+ (checkdoc-tests-in-abbrevation-p/with-escaped-parens): New tests.
+
+2021-09-13 Stefan Kangas <stefan@marxist.se>
+
+ Remove some remaining references to XEmacs
+
+ * lisp/allout.el (allout-overlay-preparations):
+ * lisp/cedet/semantic/decorate/include.el
+ (semantic-decoration-unknown-include-menu)
+ (semantic-decoration-fileless-include-menu):
+ * lisp/cedet/semantic/idle.el (semantic-idle-scheduler-setup-timers):
+ * lisp/vc/ediff-init.el:
+ * lisp/vc/ediff-util.el (ediff-mode): Remove some remaining references
+ to XEmacs.
+
+2021-09-13 Dmitry Gutov <dgutov@yandex.ru>
+
+ Extend xref-file-name-display to elisp and etags definitions
+
+ And all other types of locations (with a looks-like-file-name check).
+
+ * lisp/progmodes/xref.el (xref--group-name-for-display): Extract
+ from xref-buffer-location's implementation of xref-location-group.
+ (xref-file-location): Define trivial reader for the 'file' slot.
+ (xref-location-group): Update docstring.
+ (xref--analyze): Use the new function here, to be able to format
+ group names coming from any location type.
+
+2021-09-12 Amin Bandali <bandali@gnu.org>
+
+ ERC: Use 'string-replace' only on Emacs 28 and later
+
+ * lisp/erc/erc-dcc.el (erc-dcc-unquote-filename):
+ * lisp/erc/erc.el (erc-quit-reason-zippy, erc-part-reason-zippy)
+ (erc-update-mode-line-buffer, erc-message-english-PART): Use
+ 'string-replace' only on Emacs 28 and later, otherwise use
+ 'replace-regexp-in-string' on older Emacsen.
+
+2021-09-12 Amin Bandali <bandali@gnu.org>
+
+ ERC: Use 'string-search' only on Emacs 28 and later
+
+ * lisp/erc/erc-backend.el (erc-parse-server-response):
+ * lisp/erc/erc-dcc.el (erc-dcc-member):
+ * lisp/erc/erc-speedbar.el (erc-speedbar-expand-server)
+ (erc-speedbar-expand-channel, erc-speedbar-expand-user):
+ * lisp/erc/erc.el (erc-send-input): Use 'string-search' only on
+ Emacs 28 and later, otherwise use 'string-match' on older Emacsen.
+
+2021-09-12 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-get-buffer-tab): Use 'remq' instead of 'seq-remove'
+
+2021-09-12 Juri Linkov <juri@linkov.net>
+
+ Allow region-related context menu to be used on selected region with one click
+
+ * lisp/mouse.el (mouse-drag-track): Don't deactivate the mark for
+ the context menu invoked by down-mouse-3.
+
+ https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg01577.html
+
+2021-09-12 Juri Linkov <juri@linkov.net>
+
+ * lisp/thingatpt.el (thing-at-mouse): New function (bug#50256).
+
+ * lisp/net/dictionary.el: Add 'context-menu-dictionary' to
+ 'context-menu-functions'.
+ (dictionary-search-word-at-mouse): New function.
+ (context-menu-dictionary): New function that uses 'thing-at-mouse'.
+ (dictionary-mouse-popup-matching-words): Remove stray 'selected-window'.
+
+ * lisp/textmodes/flyspell.el (flyspell-context-menu): Add '_click' arg.
+
+2021-09-12 Juri Linkov <juri@linkov.net>
+
+ * lisp/mouse.el (context-menu-map): Add 'click' arg to called funs (bug#50256)
+
+ (context-menu-toolbar, context-menu-global, context-menu-local)
+ (context-menu-minor, context-menu-buffers, context-menu-vc)
+ (context-menu-undo, context-menu-region, context-menu-ffap): Add 'click' arg.
+
+ * lisp/dired.el (dired-context-menu):
+ * lisp/help-mode.el (help-mode-context-menu):
+ * lisp/info.el (Info-context-menu):
+ * lisp/net/eww.el (eww-context-menu):
+ * lisp/net/goto-addr.el (goto-address-context-menu):
+ * lisp/progmodes/prog-mode.el (prog-context-menu): Add 'click' arg.
+
+2021-09-12 Eli Zaretskii <eliz@gnu.org>
+
+ Fix quoting style in Lisp comments
+
+ * lisp/textmodes/rst.el:
+ * lisp/progmodes/elisp-mode.el (elisp--xref-find-definitions):
+ * lisp/org/org.el:
+ * lisp/org/org-list.el (org-list-to-generic):
+ * lisp/org/org-compat.el:
+ * lisp/hexl.el (hexl-ascii-region):
+ * lisp/emacs-lisp/lisp-mode.el:
+ * lisp/calendar/calendar.el: In comments, quote 'like this'.
+
+2021-09-12 Juri Linkov <juri@linkov.net>
+
+ * lisp/mouse.el (context-menu-map): Remove duplicate separators (bug#50067).
+
+ * lisp/mouse.el (context-menu-undo, context-menu-region):
+ * lisp/progmodes/prog-mode.el (prog-context-menu):
+ Use 'when' instead of ':visible' that allows to remove duplicate separators
+ created between empty submenus.
+
+2021-09-12 Juri Linkov <juri@linkov.net>
+
+ Use window-point in event-start and event-end (bug#50256)
+
+ * lisp/subr.el (event-start, event-end): Provide window-point
+ as an arg for posn-at-point, and for the constructed list.
+
+ * lisp/help-mode.el (help-mode-context-menu): Remove a kludge
+ that checked if window-buffer is current-buffer.
+
+2021-09-12 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: Improve logic of 'ignore-current-tab'.
+
+ * lisp/tab-bar.el (tab-bar-get-buffer-tab): Prefer the current tab
+ when 'ignore-current-tab' is nil.
+ (display-buffer-in-tab): Use alist entry 'ignore-current-tab'
+ as the third arg of 'tab-bar-get-buffer-tab'. Improve docstring.
+
+ Suggested by Feng Shu <tumashu@163.com>
+ https://lists.gnu.org/archive/html/emacs-devel/2021-09/msg00955.html
+
+2021-09-12 Eli Zaretskii <eliz@gnu.org>
+
+ Minor copyedits in Emacs FAQ
+
+ * doc/misc/efaq.texi (What was XEmacs?, Colors on a TTY): Fix
+ wording and improve the description.
+
+2021-09-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix read-no-blanks-input doc string typo
+
+ * lisp/minibuffer.el (read-no-blanks-input): Fix doc string typo.
+
+2021-09-12 dick r. chiang <dick.r.chiang@gmail.com>
+
+ Fix read-no-blanks-input history argument
+
+ * lisp/minibuffer.el (read-no-blanks-input): Use the
+ `minibuffer-history' symbol, not the value (bug#50535).
+
+2021-09-12 Mattias Engdegård <mattiase@acm.org>
+
+ Infer identifier namespace in elisp xref backend
+
+ Improve the accuracy of `xref-find-definitions` by inferring the
+ likely namespace of the sought identifier from its context.
+ This reduces the number of irrelevant search hits when it is clear
+ what kind of identifier is being looked for (such as showing a
+ variable when the user looks for a function).
+
+ Co-written with Dmitry Gutov.
+
+ * lisp/progmodes/elisp-mode.el (elisp--xref-list-index)
+ (elisp--xref-infer-namespace, xref-backend-identifier-at-point): New.
+ (xref-backend-definitions): Use the buffer position for inferring.
+ (elisp--xref-find-definitions): Use the inferred namespace.
+ (xref-backend-apropos): Adapt call.
+ * test/lisp/progmodes/elisp-mode-tests.el (elisp-mode-test--with-buffer)
+ (elisp-mode-with-buffer, elisp-mode-infer-namespace): New tests.
+
+2021-09-12 Martin Rudalics <rudalics@gmx.at>
+
+ ;* lisp/window.el (switch-to-prev-buffer): Fix typo in doc-string.
+
+2021-09-12 Martin Rudalics <rudalics@gmx.at>
+
+ Improve doc-strings of some buffer display options (Bug#50518)
+
+ * lisp/window.el (pop-up-frame-alist, same-window-buffer-names)
+ (same-window-regexps, pop-up-frames, pop-up-windows): In
+ doc-strings say that these options are maintained for backward
+ compatibility only (Bug#50518).
+
+2021-09-12 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of tab bars in the Emacs manual
+
+ * doc/emacs/frames.texi (Tab Bars): Improve wording, indexing, and
+ cross-references. Make sure each command is mentioned by its name
+ when it is called out by the key sequence. Index entries should
+ precede @item lines in a @table.
+
+2021-09-12 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of some tab-bar features
+
+ * lisp/tab-bar.el (tab-bar-show, toggle-frame-tab-bar): Doc
+ fixes.
+
+ * etc/NEWS: Update the corresponding entries.
+
+2021-09-12 Olivier Certner <olce.emacs@certner.fr>
+
+ ERC: Track: Fix a perceived minor bug in mode line face selection
+
+ * lisp/erc/erc-track.el (erc-track-modified-channels): Fix what is a
+ probable bug when a new insert event happens for a buffer that was not
+ tracked or for which no mode line face was selected: in this case,
+ stop treating the latest buffer's face (first in list) as the previous
+ one, which could be overridden with an older one (in FACES' rest), as
+ if it had happened after.
+
+2021-09-12 Olivier Certner <olce.emacs@certner.fr>
+ Amin Bandali <bandali@gnu.org>
+
+ ERC: Track: Rewrite 'erc-track-find-face' as 'erc-track-select-mode-line-face'
+
+ * lisp/erc/erc-track.el (erc-track-find-face): Declare obsolete and
+ rewrite as 'erc-track-select-mode-line-face', changing the function
+ arguments, so that it is very clear what the current algorithm is.
+ No functional changes. Performance improvements. Clarify the
+ documentation and remove the part on some faces being lists, which
+ clearly does not apply.
+ (erc-track-modified-channels): Replace calls to 'erc-track-find-face'
+ with calls to 'erc-track-select-mode-line-face', preserving the
+ existing behavior.
+ (erc-modified-channels-alist): Change the reference to
+ 'erc-track-select-mode-line-face' in the documentation following the
+ rename.
+ * etc/NEWS: Announce the change.
+
+2021-09-12 Amin Bandali <bandali@gnu.org>
+
+ Merge from origin/emacs-27
+
+ d7f4cc0974 ERC: Track: Clarify documentation on tracked buffers and a...
+ fb1f0dfec9 ERC: Track: Fix documentation of structure of 'erc-modifie...
+ 252a769b11 ; * doc/lispref/files.texi (Changing Files): Fix xref to f...
+ edc93a5ce6 ; Fix grammar in efaq.texi on Emacs vs XEmacs.
+
+ # Conflicts:
+ # doc/misc/efaq.texi
+
+2021-09-12 Olivier Certner <olce.emacs@certner.fr>
+
+ ERC: Track: Clarify documentation on tracked buffers and add references
+
+ * lisp/erc/erc-track.el (erc-modified-channels-alist): Clarify what
+ the list contains. Add references to variables and functions involved
+ in displaying tracked buffers from this list.
+ (erc-make-mode-line-buffer-name): Describe exactly the algorithm, and
+ reference custom variables that influence it.
+
+2021-09-12 Olivier Certner <olce.emacs@certner.fr>
+
+ ERC: Track: Fix documentation of structure of 'erc-modified-channels-alist'
+
+ * lisp/erc/erc-track.el (erc-modified-channels-alist): Fix the
+ docstring: each element is a dotted list where the last cdr is
+ sometimes a proper list, making the element only sometimes a proper
+ list.
+
+2021-09-12 Dmitry Gutov <dgutov@yandex.ru>
+
+ Re-fix bug#16897
+
+ * lisp/vc/vc-git.el (vc-git--file-list-is-rootdir):
+ Extract from 'vc-git-command'.
+ (vc-git--literal-pathspecs): Use it here as well.
+
+2021-09-11 Tassilo Horn <tsdh@gnu.org>
+
+ Refactor bug-reference setup for software forges
+
+ * lisp/progmodes/bug-reference.el (bug-reference-gitea-instances)
+ (bug-reference-gitlab-instances,bug-reference-sourcehut-instances):
+ Delete defvars. Those are replaced with bug-reference-forge-alist.
+ (bug-reference-forge-alist): New variable.
+ (bug-reference--build-forge-setup-entry): New cl-defgeneric with
+ methods for github, gitlab, gitea, and sourcehut instances.
+ (bug-reference--setup-from-vc-alist): Use bug-reference-forge-alist
+ and bug-reference--build-forge-setup-entry.
+ * doc/emacs/maintaining.texi (Bug Reference): Mention that the first
+ group in bug-reference-bug-regexp defines the overlay bounds. Also
+ mention bug-reference-forge-alist in VCS setup section.
+
+2021-09-11 Philip Kaludercic <philipk@posteo.net>
+
+ * NEWS: Remove empty entry
+
+ * NEWS: Mention rcirc changes
+
+2021-09-11 Mattias Engdegård <mattiase@acm.org>
+
+ Fix byte-compilation warnings
+
+ * lisp/calc/calc-graph.el (calc-gnuplot-check-for-errors):
+ * lisp/calendar/holidays.el (list-holidays):
+ Dodge 'save-excursion+set-buffer' warnings that appeared after
+ the progn flattening was introduced.
+
+2021-09-11 Mattias Engdegård <mattiase@acm.org>
+
+ Remove obsolete variable
+
+ * lisp/emacs-lisp/byte-opt.el
+ (byte-optimize--vars-outside-condition): Remove.
+ (byte-optimize-form-code-walker): Remove bindings.
+
+2021-09-11 Mattias Engdegård <mattiase@acm.org>
+
+ Propagate aliased lexical variables in byte compiler
+
+ Replace uses of a variable aliasing another variable with that aliased
+ variable, to allow for variable removal when possible. This also
+ enables opportunities for other optimisations. Example:
+
+ (let ((y x)) (f y)) => (f x)
+
+ The optimisation is only performed if both aliased and aliasing
+ variables are lexically bound. Shadowing bindings are α-renamed when
+ necessary for correctness. Example:
+
+ (let* ((b a) (a EXPR)) (f a b))
+ => (let* ((a{new} EXPR)) (f a{new} a))
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize--aliased-vars): New.
+ (byte-optimize-form-code-walker): Cancel aliasing upon mutation.
+ (byte-optimize--rename-var-body, byte-optimize--rename-var): New.
+ (byte-optimize-let-form): Add the optimisation.
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases):
+ Add relevant test cases.
+
+2021-09-11 Philip Kaludercic <philipk@posteo.net>
+
+ * doc/misc/rcirc.texi: Replace defun-rcirc-command with
+ rcirc-define-command
+
+ * doc/misc/rcirc.texi: Document rcirc-track-abbrevate-flag
+
+ * doc/misc/rcirc.texi: Document rcirc-nick-filter and
+ rcirc-channel-filter
+
+ * doc/misc/rcirc.texi: Document
+ rcirc-track-ignore-server-buffer-flag
+
+ * doc/misc/rcirc.texi: Document rcirc-omit-responses-after-join
+
+2021-09-11 Philip Kaludercic <philipk@posteo.net>
+
+ Rename rcirc-omit-after-reconnect to rcirc-omit-after-connect
+
+ * lisp/net/rcirc.el (rcirc-omit-after-reconnect): Remove variable
+ (rcirc-omit-responses-after-join): Add variable
+ (rcirc-reconncting): Remove variable
+ (rcirc-joined): Add variable
+ (rcirc-get-buffer-create): Set rcirc-joined
+ (rcirc-print): Use rcirc-joined
+ (reconnect): Remove code relating to rcirc-reconncting
+
+2021-09-11 Augusto Stoffel <arstoffel@gmail.com>
+
+ Keep python.el compatible with older Emacsen
+
+ * lisp/progmodes/python.el (python-shell-send-string): Don't assume
+ comint-max-line-length is defined (bug#50503).
+
+2021-09-11 Michael Albinus <michael.albinus@gmx.de>
+
+ Tramp code cleanup
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-make-directory): Simplify.
+
+ * lisp/net/tramp-sh.el (tramp-methods) <telnet, nc>: Don't use
+ "%n" marker.
+
+ * test/lisp/net/tramp-tests.el (tramp-test13-make-directory): Merge with
+ `tramp-test-make-directory-helper' and
+ `tramp-test13-make-directory-with-file-modes'.
+ (tramp-test44-asynchronous-requests): Use always the same
+ operation in timer.
+
+2021-09-11 Augusto Stoffel <arstoffel@gmail.com>
+
+ Allow using 'python-shell-send-file' across machines
+
+ * lisp/progmodes/python.el (python-shell-eval-file-setup-code):
+ Look for a file coding cookie on the Python rather than on the
+ Emacs side, to avoid additional file transfers.
+ (python-shell--save-temp-file): Allow argument to be a buffer.
+ (python-shell-send-file): Address the case where the selected file and
+ the inferior process are on different machines (bug#50516).
+
+2021-09-11 Augusto Stoffel <arstoffel@gmail.com>
+
+ Implement caching for 'python-shell-completion-at-point'
+
+ * lisp/progmodes/python.el (python-shell-completion-at-point): cache
+ results, since computing them involves talking with the inferior
+ process and, potentially, network communications
+ (python-shell--capf-cache): new variable, for cache
+ (python-shell-completion-get-completions)
+ (python-shell-completion-native-get-completions): 'import' argument is
+ not needed anymore.
+ (python-shell-completion-native-setup)
+ (python-shell-completion-native-try): pass the setup code
+ synchronously, to avoid printing a message in the shell (bug#50459).
+
+2021-09-11 Alan Third <alan@idiocy.org>
+
+ Fix display of tab-bar buttons
+
+ * src/xterm.c (x_draw_image_relief):
+ * src/w32term.c (w32_draw_image_relief): Fix the display of
+ tab-bar buttons when mouse pointer moves off the button.
+ (Bug#50424)
+
+2021-09-11 Eli Zaretskii <eliz@gnu.org>
+
+ Document tool-bar and tab-bar mouse events
+
+ * doc/lispref/commands.texi (Click Events): Document the format of
+ POSITION for tab-bar and tool-bar events.
+
+2021-09-11 Eli Zaretskii <eliz@gnu.org>
+
+ Fix tab-bar scrolling for mice that report mouse-wheel events
+
+ * src/keyboard.c (make_lispy_position): Call
+ 'window_from_coordinates' with last 2 arguments non-zero, to have
+ it report on tool-bar and tab-bar positions. Tweak the return
+ value according to the expectations of 'make_lispy_event'.
+ (make_lispy_event): No more need to inject "tab-bar" into a click
+ event on the tab bar: it's already there.
+
+2021-09-11 Tassilo Horn <tsdh@gnu.org>
+
+ bug-reference-bug-regexp now defines a contract for the overlay region
+
+ Formerly, bug-reference-fontify placed the overlay on the complete
+ match of bug-reference-bug-regexp. That made it impossible to encode
+ constraints like "must not match at BOL" in the regexp without messing
+ up fontification. Therefore, now it establishes the contract that
+ subexpression 1 defines the overlay region. Subexpression 2 must
+ still match the part of the bug reference injected into
+ bug-reference-url-format if that's a string. If its a function, the
+ interpretation of subexpressions > 1 is up to the function.
+
+ For backwards compatibility, bug-reference-fontify checks if the
+ bounds of subexpression 2..10 are within the bounds of subexpression
+ 1. If not, or subexpression 1 doesn't even exist/match, we fall back
+ to placing the overlay from (match-beginning 0) to (match-end 0) but
+ issue a warning.
+
+ * lisp/progmodes/bug-reference.el (bug-reference-bug-regexp): Document
+ contract that subexpression 1 defines the overlay region and adapt the
+ default value accordingly.
+ (bug-reference--nonconforming-regexps): New internal variable.
+ (bug-reference--overlay-bounds): New function.
+ (bug-reference-fontify): Place overlay on subexpression 1's bounds if
+ bug-reference-bug-regexp conforms to the documented contract.
+ (bug-reference--setup-from-vc-alist): Adapt regexps to new contract.
+ * doc/emacs/maintaining.texi (Bug Reference): Adapt regexp used in
+ example.
+
+2021-09-11 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/info.el (Info-streamline-headings): Add entry.
+
+2021-09-11 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of Show Paren mode
+
+ * doc/emacs/programs.texi (Matching): Improve wording and
+ indexing. (Bug#29381)
+
+2021-09-11 Eli Zaretskii <eliz@gnu.org>
+
+ Fix restoring from pdumper file on MS-Windows 9X
+
+ * src/pdumper.c (dump_map_file_w32): Use PAGE_WRITECOPY flag when
+ calling CreateFileMapping for DUMP_MEMORY_ACCESS_READWRITE access,
+ as that is required by Windows 9X. (Bug#50453)
+
+2021-09-11 Dmitry Gutov <dgutov@yandex.ru>
+
+ New minor mode 'show-paren-local-mode'
+
+ * lisp/paren.el (show-paren--delete-overlays):
+ New function, extracted from show-paren-mode.
+ (show-paren-local-mode): New minor mode.
+ (show-paren-mode): Update docstring to mention it (bug#29381).
+
+ * doc/emacs/programs.texi (Matching): Update show-paren-mode section.
+
+2021-09-11 Tassilo Horn <tsdh@gnu.org>
+
+ Improve overlay placement performance
+
+ * lisp/progmodes/bug-reference.el (bug-reference--overlays-in): New
+ function.
+ (bug-reference-unfontify): Use it.
+ (bug-reference-fontify): Reuse and move existing overlays instead of
+ deleting all and creating them anew.
+
+2021-09-10 Arthur Miller <arthur.miller@live.com>
+
+ Add support for GCC compiler command-line options
+
+ * lisp/emacs-lisp/comp.el ('native-comp-compiler-options): New option.
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-from-buffer): Add support
+ for new 'native-comp-compiler-options'.
+ * src/comp.c (Fcomp_native_compiler_options_effective_p): New function.
+ (add_compiler_options): New function.
+ (Fcomp__compile_ctxt_to_file): Call 'add_compiler_options'.
+
+2021-09-10 Philip Kaludercic <philipk@posteo.net>
+
+ Merge branch 'master' into feature/rcirc-update
+
+2021-09-10 Philip Kaludercic <philipk@posteo.net>
+
+ Fix double reconnection bug
+
+ * lisp/net/rcirc.el (rcirc-sentinel): Don't reconnect if reconnecting
+ (reconnect): Use delete-process instead of kill-process
+
+2021-09-10 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix test find-defs-defgeneric-el
+
+ * test/lisp/progmodes/elisp-mode-tests.el (find-defs-defgeneric-el):
+ Fix the test. Reported by dick.r.chiang@gmail.com.
+
+2021-09-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert usage of format-prompt in python.el
+
+ * lisp/progmodes/python.el (python-eldoc-at-point): Revert usage
+ of format-prompt in python.el since this is also an ELPA package
+ (and older Emacs versions doesn't have format-prompt).
+
+2021-09-10 Augusto Stoffel <arstoffel@gmail.com>
+
+ Properly encode all strings sent to Python shell
+
+ * lisp/progmodes/python.el: Now depends on Emacs 28.
+ (python-shell-package-enable, python-shell-completion-get-completions)
+ (python-ffap-module-path, python-eldoc--get-doc-at-point): Encode
+ Python strings using 'python-shell--encode-string' instead of triple
+ quotes.
+ (python-shell-completion-string-code, python-eldoc-string-code)
+ (python-ffap-string-code): Remove defcustoms. (bug#50503).
+
+2021-09-10 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ Tramp: honor default file modes in make-directory
+
+ * lisp/net/tramp-sh.el:
+ * lisp/net/tramp-adb.el:
+ * lisp/net/tramp-sudoedit.el:
+ * lisp/net/tramp-gvfs.el: Add support for default file modes to
+ relevant Tramp back ends for make-directory. (Closes: Bug#50410)
+ * test/lisp/net/tramp-tests.el (tramp-test13-make-directory-with-file-modes):
+ New test.
+ * etc/NEWS: Note this enhancement.
+
+ Thanks to Michael Albinus for helping improve this patch.
+
+2021-09-10 Eli Zaretskii <eliz@gnu.org>
+
+ Doc string followup to last change.
+
+ * lisp/progmodes/xref.el (xref-find-apropos): Mention
+ 'tags-apropos-additional-actions' in the doc string.
+ * lisp/progmodes/etags.el (tags-apropos-additional-actions):
+ Mention 'xref-find-apropos' in the doc string.
+
+2021-09-10 Eli Zaretskii <eliz@gnu.org>
+
+ Document 'tags-apropos-additional-actions' with Xref
+
+ * doc/emacs/maintaining.texi (Looking Up Identifiers): Rearrange
+ and reword documentation of 'xref-find-apropos' and
+ 'xref-auto-jump-to-first-definition'. Add the description of
+ 'tags-apropos-additional-actions'. Delete the comment with
+ not-yet implemented features that were available with
+ 'tags-apropos'.
+
+ * etc/NEWS: Augment the wording of 'xref-find-apropos' entry.
+
+2021-09-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further fix for the search-whitespace-regexp change
+
+ * lisp/isearch.el (search-whitespace-regexp): Fix yet another typo
+ in this one-line change (bug#21278).
+
+2021-09-10 Gregory Heytings <gregory@heytings.org>
+
+ New user options to move between isearch matches
+
+ * lisp/isearch.el (isearch-allow-motion,
+ isearch-motion-changes-direction): New user options.
+ (isearch-pre-command-hook): Handle the new options.
+
+ * etc/NEWS: Mention the new user options.
+
+ * doc/emacs/search.texi: Document the new user options.
+
+2021-09-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix typo in previous search-whitespace-regexp change
+
+ * lisp/isearch.el (search-whitespace-regexp): Fix typo in last
+ checkin for this variable.
+
+2021-09-10 Gregory Heytings <gregory@heytings.org>
+
+ Fix behavior of isearch-{beginning,end}-of-buffer
+
+ * lisp/isearch.el (isearch-beginning-of-buffer)
+ (isearch-end-of-buffer): Fix their behavior when
+ isearch-repeat-on-direction-change is non-nil (bug#50466).
+
+2021-09-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Change the default value of search-whitespace-regexp
+
+ * lisp/isearch.el (search-whitespace-regexp): Change the default
+ to always exclude newlines from the set (bug#21278). It used to
+ be mode-dependent whether newlines were included or not, and this
+ was confusing as a user interface.
+
+2021-09-10 Dmitry Gutov <dgutov@yandex.ru>
+
+ * lisp/progmodes/ruby-mode.el (ruby-current-indentation): Tweak obsoletion.
+
+2021-09-10 Dmitry Gutov <dgutov@yandex.ru>
+
+ Support tags-apropos-additional-actions in etags Xref backend
+
+ * lisp/progmodes/etags.el (xref-etags-apropos-location):
+ New class.
+ (xref-location-marker): New method definition.
+ (xref-make-etags-apropos-location): New function.
+ (etags--xref-apropos-additional): New function.
+ (xref-backend-apropos): Use it here.
+
+2021-09-09 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of tab-bar functions and variables
+
+ * etc/NEWS: Improve wording of tab-bar related entries.
+
+ * lisp/tab-bar.el (tab-bar-show, tab-bar-select-tab-modifiers):
+ Improve and clarify the doc strings.
+
+2021-09-09 Eli Zaretskii <eliz@gnu.org>
+
+ Fix a recent change wrt 'comint-max-line-length'
+
+ * lisp/progmodes/python.el (python-shell-send-string): Only heed
+ 'comint-max-line-length' for subprocesses with which we
+ communicate via PTYs. (Bug#49822)
+
+ * lisp/comint.el (comint-max-line-length): Doc fix. Add a value
+ for MS-Windows.
+
+2021-09-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Change ruby-align-chained-calls indentation
+
+ * lisp/progmodes/ruby-mode.el (ruby-smie-rules): Align with the
+ first sibling on the previous line instead of the last (bug#32496).
+
+ That is, before it used to be
+
+ one.two.three
+ .four
+
+ and now it is
+
+ one.two.three
+ .four
+
+2021-09-09 Augusto Stoffel <arstoffel@gmail.com>
+
+ Better treatment of line length limits for the Python inferior
+
+ * lisp/comint.el (comint-max-line-length): New constant reflecting a
+ safe maximum line size that can be sent to an inferior process.
+ * lisp/progmodes/python.el
+ (python-shell-comint-watch-for-first-prompt-output-filter): Send setup
+ code to the inferior process only once and at this stage.
+ (python-shell-eval-setup-code, python-shell-eval-file-setup-code):
+ Move, unchanged, to an earlier point to avoid byte-compiler warnings.
+ (python-shell-send-string-no-output): Revert changes of e32c7d2a8d
+ (python-shell-send-string): Use 'comint-max-line-length' to decide
+ when to resort to temp files.
+ (python-shell-send-string, python-shell-send-file): Don't send setup
+ code each time (bug#49822).
+
+2021-09-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify Gnus vs. font locking in the Gnus manual
+
+ * doc/misc/gnus.texi (Formatting Variables): Explicitly mention
+ that font locking doesn't work in Gnus buffers (bug#50474).
+
+2021-09-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove the "Real meaning of copyleft" node in efaq
+
+ * doc/misc/efaq.texi (Real meaning of copyleft): Remove the
+ section (bug#50446).
+ (Common acronyms): Add a link to the GNU site's page about licenses.
+
+2021-09-09 Juri Linkov <juri@linkov.net>
+
+ Merge branch 'feature/tab-bar-events'
+
+2021-09-08 Michael Albinus <michael.albinus@gmx.de>
+
+ Document restriction of completion styles with remote file names
+
+ * doc/misc/tramp.texi (File name completion): Mention restriction
+ of completion styles.
+
+2021-09-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't ding at the user in pop-mark
+
+ * lisp/simple.el (pop-mark): Don't ding at the user if there's no
+ mark to pop (bug#44375). This function is used (in some
+ circumstances) when the user mouse-1-clicks links (in *Help*
+ buffer, for instance), which will then ding at the user before
+ following the link.
+
+2021-09-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further tweak describe-variable look
+
+ * lisp/help-fns.el (describe-variable): Tweak how long variable
+ values are shown.
+
+2021-09-08 Mattias Engdegård <mattiase@acm.org>
+
+ * etc/NEWS: macOS alternative context menu mouse binding.
+
+2021-09-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous help-fns change
+
+ * lisp/help-fns.el (help-fns--run-describe-functions): Fix the
+ test for whether the function inserted anything.
+
+2021-09-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust test to describe-function changes
+
+ The doc now always ends with an empty line
+
+2021-09-08 Miha Rihtaršič <miha@kamnitnik.top>
+
+ Allow kmacros to end with C-g in minibuffer
+
+ * src/keyboard.c (cmd_error): If a command causes a minibuffer-quit
+ condition, record its key in a keyboard macro (bug#48603).
+
+2021-09-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add support for keypad `=' key in xterm.el
+
+ * lisp/term/xterm.el (xterm-function-map): Add support for keypad
+ = key (bug#16645).
+
+2021-09-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't disable ipython as a native interpreter
+
+ * lisp/progmodes/python.el
+ (python-shell-completion-native-disabled-interpreters): Remove
+ ipython from list, because it apparently works fine these days
+ (bug#50458).
+
+2021-09-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix mail-user-agent defcustom type
+
+ * lisp/simple.el (mail-user-agent): Any symbol can be used as the
+ value (bug#50460).
+
+2021-09-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move the indented *Help* block to after the doc string
+
+ * lisp/help-fns.el (describe-function-1): Move indented admin
+ block to the end (bug#50463).
+ (describe-variable): Ditto (bug#50463).
+
+2021-09-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't output "probably introduced" if we know the answer for sure
+
+ * lisp/help-fns.el (help-fns--customize-variable-version):
+ Factored out from `help-fns--customize-variable' to be able to see
+ whether it outputs anything.
+ (help-fns--run-describe-functions): New function.
+ (help-fns--activated-functions): New internal variable.
+ (describe-variable): Use new function.
+ (describe-face, describe-function-1): Ditto (bug#50463).
+
+2021-09-08 Stefan Kangas <stefan@marxist.se>
+
+ Center Emacs logo above text on the splash screen
+
+ * lisp/startup.el (fancy-splash-head): Center Emacs logo above
+ text on the splash and about screen.
+
+2021-09-08 Dmitry Gutov <dgutov@yandex.ru>
+
+ Have Git backend actions accept nil filenames again
+
+ * lisp/vc/vc-git.el (vc-git--literal-pathspec):
+ Move the nil check to the beginning (bug#50422).
+
+2021-09-07 Harald Jörg <haj@posteo.de>
+
+ cperl-mode.el: Use rx sequences for Perl grammar
+
+ Following advice by Mattias Engdegård, most uses of rx-to-string
+ were eliminated, and rx sequences used instead to define Perl
+ grammar components.
+ * lisp/progmodes/cperl-mode.el: (cperl-block-declaration-p): New
+ function, replaces regexp literals.
+ (cperl-imenu--function-name-regexp-perl): Deleted, use rx
+ sequences to find imenu entries instead.
+ (cperl-indent-line): Use rx components instead of regexp literals.
+ (cperl-sniff-for-indent): use `cperl-block-declaration-p' to
+ increase accuracy, use rx sequence for labels to replace
+ inaccurate regexp literals.
+ (cperl-block-p): Replace inline comment by docstring. Use
+ `cperl-block-declaration-p'.
+ (cperl-after-block-p): Use `cperl-block-declaration-p'.
+ (cperl-after-block-and-statement-beg): Replace inline comment by
+ docstring.
+ (cperl-imenu-package-keywords), (cperl-imenu-sub-keywords),
+ (cperl-imenu-pod-keywords) : New variables to sort imenu
+ entries into categories.
+ (cperl-imenu--create-perl-index): Use rx sequences to collect
+ imenu entries.
+ (cperl-init-faces): Use rx components instead of regexp literals
+ for labels.
+
+ * test/lisp/progmodes/cperl-mode-tests.el: Test rx sequences
+ instead of regexp strings
+
+2021-09-07 Philip Kaludercic <philipk@posteo.net>
+
+ Add rcirc-track-ignore-server-buffer-flag option
+
+ * lisp/net/rcirc.el (rcirc-track-ignore-server-buffer-flag): Add option
+ (rcirc-record-activity): Use rcirc-track-ignore-server-buffer-flag
+
+2021-09-07 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Don't let nndiary.el alter variables when loading file
+
+ * lisp/gnus/nndiary.el (nndiary-open-server): Move the manipulation of
+ `gnus-extra-headers' and `nnmail-extra-headers' into this function: it
+ should only happen if we're actually firing up an nndiary server.
+ Previously, simply attempting to complete a gnus-* prefixed symbol
+ could end up loading this file, and changing the variable values.
+
+2021-09-07 Alan Mackenzie <acm@muc.de>
+
+ Increase jit-lock-chunk-size from 500 to 1500 for performance reasons
+
+ * lisp/jit-lock.el (jit-lock-chunk-size): Increase to 1500.
+
+ See also https://lists.gnu.org/archive/html/emacs-devel/2021-09/msg00540.html.
+
+2021-09-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Encode urls more before using in browse-url
+
+ * lisp/net/browse-url.el (browse-url-default-windows-browser)
+ (browse-url-default-macosx-browser): Encode the URL before using
+ (in case it contains spaces) (bug#50435).
+
+2021-09-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix encoding in browse-url-encode-url
+
+ * lisp/net/browse-url.el (browse-url-url-encode-chars): Document
+ what the argument really is, and simplify the implementation
+ (bug#50435).
+ (browse-url-encode-url): Encode spaces.
+
+2021-09-07 Alex Bochannek <alex@bochannek.com>
+
+ Add a new Gnus command to toggle whether to use fonts in shr
+
+ * doc/misc/gnus.texi (Article Washing): Document it.
+
+ * lisp/gnus/gnus-art.el (gnus-article-toggle-fonts): New command
+ and key binding (bug#50383).
+
+2021-09-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the Info mode line further
+
+ * lisp/info.el (Info-set-mode-line): Improve the Info mode line
+ further (bug#13776).
+
+2021-09-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix a recent documentation change
+
+ * lisp/progmodes/xref.el (xref-auto-jump-to-first-definition)
+ (xref-auto-jump-to-first-xref):
+ * etc/NEWS: Fix wording and typos.
+
+2021-09-07 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 97aa8240d2 (origin/emacs-27) * doc/misc/efaq.texi: Misc copyedits.
+ e1050492d1 * doc/misc/efaq.texi (Reporting bugs): Refer to the Emacs ...
+
+ # Conflicts:
+ # doc/misc/efaq.texi
+
+2021-09-07 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt tramp-test26-file-name-completion
+
+ * test/lisp/net/tramp-tests.el (tramp-test26-file-name-completion):
+ Do not check for default method.
+
+2021-09-07 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of new Xref options
+
+ * lisp/progmodes/xref.el (xref-auto-jump-to-first-definition)
+ (xref-auto-jump-to-first-xref): More accurate description in the
+ doc strings.
+
+ * doc/emacs/maintaining.texi (Looking Up Identifiers)
+ (Identifier Search, List Identifiers, Project File Commands): Fix
+ the documentation of 'xref-auto-jump-to-first-definition' and
+ 'xref-auto-jump-to-first-xref' to be more accurate.
+
+ * etc/NEWS: More accurate wording of the entry about
+ 'xref-auto-jump-to-first-definition' and
+ 'xref-auto-jump-to-first-xref'.
+
+2021-09-07 Michael Albinus <michael.albinus@gmx.de>
+
+ Do not expand default method, user, host in remote file name completion
+
+ * lisp/net/tramp.el (tramp-completion-handle-file-name-all-completions):
+ Do not expand default method, user, host. (Bug#50387)
+ (tramp-get-completion-methods): `partial-method' can be nil.
+
+2021-09-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix display of tab-bar buttons
+
+ * src/xterm.c (x_draw_image_relief):
+ * src/w32term.c (w32_draw_image_relief): Fix calculation of relief
+ thickness for tab-bar buttons.
+
+ * lisp/tab-bar.el (tab-bar--load-buttons)
+ (tab-bar-history-mode): Fix the :margin specification for tab-bar
+ buttons. (Bug#50424)
+
+2021-09-07 Philip Kaludercic <philipk@posteo.net>
+
+ Use fresh symbol for argument list
+
+ * lisp/net/rcirc.el (rcirc-define-command): Use make-symbol instead of gensym
+
+2021-09-07 Philip Kaludercic <philipk@posteo.net>
+
+ Allow /reconnect while connecting
+
+ * lisp/net/rcirc.el (reconnect): Kill previous process and start a new one
+
+2021-09-07 Glenn Morris <rgm@gnu.org>
+
+ * test/lisp/vc/vc-tests.el (vc-test--version-diff): Git env tweak.
+
+2021-09-07 Dmitry Gutov <dgutov@yandex.ru>
+ Jiacai Liu <hello@liujiacai.net>
+
+ Support specifying just one command in project-switch-commands
+
+ * lisp/progmodes/project.el (project-switch-commands):
+ Describe the new possible type of value.
+ (project--switch-project-command):
+ New function, extract from project-switch-project.
+ (project-switch-project): If project-switch-commands's value is a
+ symbol, invoke that command without showing a menu.
+
+2021-09-07 Stefan Kangas <stefan@marxist.se>
+
+ Small FAQ fixes
+
+ * doc/misc/efaq.texi (Colors on a TTY): Remove reference to
+ ancient Emacs version 22.
+ (Finding Emacs on the Internet): Use more current terminology.
+
+2021-09-07 Stefan Kangas <stefan@marxist.se>
+
+ Remove Emacs FAQ maintainer
+
+ * doc/misc/efaq.texi: Remove maintainer Romain Francoise after private
+ communication.
+
+2021-09-07 Stefan Kangas <stefan@marxist.se>
+
+ * etc/NEWS: Some further re-organization.
+
+ * etc/NEWS: Clarify entry about the "*Completions*" buffer.
+
+2021-09-06 Philip Kaludercic <philipk@posteo.net>
+
+ Mention list of capabilities that should be implemented
+
+ * lisp/net/rcirc.el (rcirc-implemented-capabilities): Add comment
+
+2021-09-06 Philip Kaludercic <philipk@posteo.net>
+
+ Implement standard-replies capability
+
+ * lisp/net/rcirc.el (rcirc-implemented-capabilities): Add standard-replies to list
+ (rcirc-response-formats): Add response formats for WARN, FAIL and NOTE
+ (rcirc-handler-FAIL): Add handler
+ (rcirc-handler-WARN): Add handler
+ (rcirc-handler-NOTE): Add handler
+
+2021-09-06 Philip Kaludercic <philipk@posteo.net>
+
+ Connect to server asynchronously
+
+ * lisp/net/rcirc.el (rcirc-connect): Add :nowait option to open-network-stream
+ (rcirc-sentinel): Handle "open\n" events
+
+2021-09-06 Tassilo Horn <tsdh@gnu.org>
+
+ Add possibility to override the default highlighting
+
+ * lisp/progmodes/bug-reference.el (bug-reference-fontify): Highlight
+ 99th group if it exists.
+ (bug-reference-bug-regexp): Document that regexp group 99 can be used
+ to override the default behavior of highlighting the complete match.
+ (bug-reference--run-auto-setup): Use run-hook-with-args-until-success
+ instead of throw/catch.
+
+2021-09-06 Mattias Engdegård <mattiase@acm.org>
+
+ Normalise nested `progn` forms in byte-code optimiser
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-body): Flatten body.
+ This simplifies the source tree and reduces the number of different
+ cases that other optimisations need to take into account.
+
+2021-09-06 Mattias Engdegård <mattiase@acm.org>
+
+ More robust optimisation of `ignore`
+
+ Treat `ignore` as any other function during source-level optimisation,
+ to avoid having its warning-suppression effects cancelled by repeated
+ passes. Instead, define a custom code generation function.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker):
+ Don't treat `ignore' specially here.
+ (side-effect-free-fns): Don't mark `ignore` as side-effect-free
+ or error-free (although it is), since that would allow the optimiser
+ to elide calls.
+ * lisp/emacs-lisp/bytecomp.el (ignore, byte-compile-ignore):
+ Define and register a code-gen function.
+
+2021-09-06 Mattias Engdegård <mattiase@acm.org>
+
+ Optimise `member` and `assoc` (etc) with constant empty list
+
+ * lisp/emacs-lisp/byte-opt.el
+ (byte-optimize-assq): New.
+ (byte-optimize-member, byte-optimize-assoc, byte-optimize-memq):
+ When the list argument is constant nil, the result is always nil.
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases):
+ Add test cases.
+
+2021-09-06 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fixup dired-do-find-regexp-and-replace
+
+ * lisp/dired-aux.el (dired-do-find-regexp-and-replace):
+ Disregard the customized value of xref-auto-jump-to-first-xref
+ (it breaks the xref-query-replace-in-results invocation).
+
+ * lisp/progmodes/xref.el (xref-auto-jump-to-first-xref):
+ Mention the caveat for users or xref distributed through ELPA.
+
+2021-09-06 Michael Albinus <michael.albinus@gmx.de>
+
+ Revert an accidental change in etc/NEWS
+
+2021-09-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make calc-grab-region work with rectangular selects
+
+ * lisp/calc/calc.el (calc-grab-region): Heed `rectangle-mark-mode'
+ (bug#50403).
+
+2021-09-06 martin rudalics <rudalics@gmx.at>
+
+ Restore the debugging window size more reliably
+
+ * lisp/emacs-lisp/debug.el (debug): Restore the debugging window
+ size more reliably (bug#12921).
+
+2021-09-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a tooltip to the comint-mode mode line format
+
+ * lisp/comint.el (comint-mode): Add a tooltip to say what the :run
+ bit means (bug#13776).
+
+2021-09-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the info-mode mode line
+
+ * lisp/info.el (Info-set-mode-line): Add a help echo to help
+ explain what the thing in parentheses is (bug#13776).
+
+2021-09-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Simplify `image-dired-dired-file-marked-p'
+
+ * lisp/image-dired.el (image-dired-dired-file-marked-p): Use
+ `dired-re-mark' instead of open-coding the opposite regexp (bug#14925).
+
+2021-09-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the gnus-group-default-list-level doc string
+
+ * lisp/gnus/gnus-group.el (gnus-group-default-list-level): Improve
+ doc string.
+
+2021-09-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Reset gnus-group-use-permanent-levels when Gnus restarts
+
+ * lisp/gnus/gnus-start.el (gnus-clear-system): Reset
+ `gnus-group-use-permanent-levels' upon Gnus restart (bug#50416).
+
+2021-09-06 Allen Li <darkfeline@felesatra.moe>
+
+ Make `gnus-group-use-permanent-levels' work better
+
+ * lisp/gnus/gnus-group.el (gnus-group-default-level): Removed implicit
+ setting of gnus-group-use-permanent-levels.
+ (gnus-group-list-groups): Set gnus-group-use-permanent-levels
+ explicitly.
+ (gnus-group-get-new-news): Set gnus-group-use-permanent-levels
+ explicitly (bug#50417).
+ (gnus-group-get-new-news): When the user has given a numeric
+ prefix, use that as the list level.
+
+2021-09-06 Juri Linkov <juri@linkov.net>
+
+ * etc/NEWS: Reorder "Isearch and Replace" items
+
+2021-09-06 Eli Zaretskii <eliz@gnu.org>
+
+ * doc/emacs/maintaining.texi (Xref Commands): Fix indexing.
+
+2021-09-06 Stefan Kangas <stefan@marxist.se>
+
+ * etc/NEWS: Improve file organization.
+
+2021-09-06 Stefan Kangas <stefan@marxist.se>
+
+ Improve documentation of save-place-abbreviate-file-names
+
+ * lisp/saveplace.el (save-place-abbreviate-file-names): Document why
+ you might want to enable this option.
+
+2021-09-06 Stefan Kangas <stefan@marxist.se>
+
+ * etc/NEWS: Don't mention a fixed bug.
+
+2021-09-06 Dmitry Gutov <dgutov@yandex.ru>
+
+ project--files-in-directory: Fix handling of ignores
+
+ * lisp/progmodes/project.el (project--files-in-directory):
+ Pass "." as the DIR argument to 'find' because otherwise the ignore
+ expression can match the project root directory name, which we don't
+ want to happen (bug#50240). Fixup the resulting file names at the end
+ with concatenation.
+ Originally I thought it could lead to worse performance, but the
+ results show equal or slightly better timings.
+
+ * lisp/progmodes/xref.el (xref-matches-in-directory):
+ Apply a similar fix.
+ (xref--find-ignores-arguments): Use file-name-as-directory, so
+ that when passed "." replace-match still had the expected effect.
+
+ * test/lisp/progmodes/project-tests.el (project-ignores-bug-50240):
+ New test.
+
+ * test/lisp/progmodes/xref-tests.el
+ (xref-matches-in-directory-filters-with-ignores): New test.
+
+2021-09-06 Dmitry Gutov <dgutov@yandex.ru>
+
+ Try to fix vc-test-git06-version-diff on Hydra
+
+ * test/lisp/vc/vc-tests.el (vc-test--version-diff):
+ Fix Git backend when running in clean environment.
+ (vc-test-git06-version-diff): Unskip on Hydra.
+
+2021-09-06 Glenn Morris <rgm@gnu.org>
+
+ * doc/misc/efaq.texi: Misc copyedits.
+
+ Prefer mailing lists to newgroups.
+ (History of Emacs): Rename from "Status of Emacs".
+ Move XEmacs node here.
+ (Emacs for other operating systems): Merge all the "non-Unix"
+ systems into a single node.
+
+2021-09-05 Glenn Morris <rgm@gnu.org>
+
+ * test/lisp/vc/vc-tests.el (vc-test-git06-version-diff): Skip on hydra.
+
+2021-09-05 Dmitry Gutov <dgutov@yandex.ru>
+
+ * lisp/progmodes/xref.el: Bump the version again.
+
+2021-09-05 Philip Kaludercic <philipk@posteo.net>
+
+ Implement multi-prefix capability
+
+ * lisp/net/rcirc.el (rcirc-implemented-capabilities): Add capability
+ (rcirc-user-nick): Handle multiple prefixes
+
+2021-09-05 Philip Kaludercic <philipk@posteo.net>
+
+ Fix rcirc-track-abbrevate-flag documentation
+
+ * lisp/net/rcirc.el (rcirc-track-abbrevate-flag): Rephrase docstring
+
+2021-09-05 Philip Kaludercic <philipk@posteo.net>
+
+ Store symbols in rcirc-acked-capabilities
+
+ * lisp/net/rcirc.el (rcirc-handler-CAP): Use intern and downcase
+
+2021-09-05 Juri Linkov <juri@linkov.net>
+
+ Improve tab-bar event handling (bug#41343)
+
+ * lisp/tab-bar.el (tab-bar--key-to-number): Rename from tab--key-to-number.
+ (tab-bar--event-to-item): New function from tab-bar-handle-mouse.
+ (tab-bar-mouse-select-tab, tab-bar-mouse-close-tab)
+ (tab-bar-mouse-context-menu, tab-bar-mouse-move-tab):
+ Use tab-bar--event-to-item.
+
+ * src/menu.c (x_popup_menu_1): Handle Qtab_bar in the second list element.
+
+ * src/xdisp.c (tty_get_tab_bar_item): Change arg 'end' to bool 'close_p'.
+ (tty_get_tab_bar_item): Detect if the close button was clicked.
+ (tty_handle_tab_bar_click): Return a list with caption that has
+ text properties.
+
+2021-09-05 Philip Kaludercic <philipk@posteo.net>
+
+ Print value on malformed input
+
+ * lisp/net/rcirc.el (rcirc-define-command): Unquote argument
+
+2021-09-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Autoload cl-struct-slot-info
+
+ * lisp/emacs-lisp/cl-macs.el (cl-struct-slot-info): Autoload
+ (bug#50301).
+
+ * test/lisp/emacs-lisp/memory-report-tests.el: Don't require cl-macs.
+
+2021-09-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the documentation around the read-key/minibuffer prompting
+
+ * lisp/subr.el (read-char-choice-use-read-key): Explain the
+ difference.
+ (read-char-choice): Mention the variables.
+ (y-or-n-p-use-read-key): Explain the difference.
+ (y-or-n-p): Mention the variable (bug#50390).
+
+2021-09-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify completion-list-mode NEWS entry
+
+ * etc/NEWS: Clarify completion-list-mode entry (bug#50394).
+
+2021-09-05 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/xref.el: Fix defcustoms (bug#50067)
+
+ * lisp/progmodes/xref.el (xref-auto-jump-to-first-definition)
+ (xref-auto-jump-to-first-xref, xref-search-program): Fix defcustoms.
+
+2021-09-05 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of new Xref options
+
+ * doc/emacs/maintaining.texi (Looking Up Identifiers):
+ * etc/NEWS: Document the new Xref user options. Move a lost
+ Xref-related entry to the rest of them.
+
+2021-09-05 Augusto Stoffel <arstoffel@gmail.com>
+
+ Fixes for 'python-shell-send-string' and 'python-shell-send-file'
+
+ * lisp/progmodes/python.el (python-shell-send-string): use a temporary
+ file for sufficiently long strings.
+ (python-shell-send-file, python-shell-eval-file-setup-code): Avoid
+ showing "plumbing code" in the traceback (bug#32042).
+
+2021-09-05 Ian W <ian@wahbe.com> (tiny change)
+
+ Fix error handling in 'ispell-init-process'
+
+ * lisp/textmodes/ispell.el (ispell-init-process): When Ispell
+ initialization reports an error, call 'ispell-accept-output' only
+ if the Ispell process is still alive. (Bug#50370)
+
+2021-09-05 Michael Albinus <michael.albinus@gmx.de>
+
+ Cleanup tramp-tests.el
+
+ * test/lisp/net/tramp-tests.el
+ (tramp--test--deftest-direct-async-process): Fix macro declaration.
+ (tramp-test29-start-file-process, tramp-test30-make-process):
+ Do not run connection type test for direct async processes.
+
+2021-09-05 Glenn Morris <rgm@gnu.org>
+
+ * test/lisp/vc/vc-tests.el (vc-test-sccs06-version-diff): Fix it.
+
+2021-09-05 Dmitry Gutov <dgutov@yandex.ru>
+
+ Belated fix
+
+ * lisp/progmodes/xref.el: (xref--show-xref-buffer):
+ Fix support for xref-auto-jump-to-first-xref.
+
+2021-09-05 Dmitry Gutov <dgutov@yandex.ru>
+
+ * lisp/progmodes/xref.el: Bump version.
+
+2021-09-05 Dmitry Gutov <dgutov@yandex.ru>
+
+ Xref: automatic jumping to the first definition or reference
+
+ * lisp/progmodes/xref.el (xref-auto-jump-to-first-definition)
+ (xref-auto-jump-to-first-xref): New user options.
+ Discussed in bug#50067.
+ (xref--show-xrefs, xref--show-defs): Use them here.
+ (xref--auto-jump-first): New function, handles different values.
+ (xref-show-definitions-buffer)
+ (xref-show-definitions-buffer-at-bottom): Use it.
+
+2021-09-05 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix test on machines with Bzr not set up
+
+ * test/lisp/vc/vc-tests.el (vc-test--version-diff):
+ Add EMAIL= to the environment to avoid potential failure.
+
+2021-09-05 Philip Kaludercic <philipk@posteo.net>
+
+ Replace with-current-buffer with buffer-local-value where applicable
+
+ * lisp/net/rcirc.el (rcirc-buffer-process): Use buffer-local-value
+ (rcirc-last-quit-line): Use buffer-local-value
+ (rcirc-bury-buffers): Use buffer-local-value
+ (rcirc-record-activity): Use buffer-local-value
+
+2021-09-05 Matthias Meulien <orontee@gmail.com>
+
+ Add tests for vc-version-diff
+
+ * test/lisp/vc/vc-tests.el (vc-test--version-diff):
+ New function.
+ (vc-test-%s06-version-diff): New family of tests.
+
+2021-09-05 Dmitry Gutov <dgutov@yandex.ru>
+
+ Rename xref-select-and-{goto,show}-xref
+
+ * lisp/progmodes/xref.el (xref-select-and-show-xref):
+ Rename from xref-select-and-goto-xref (bug#35376).
+ Update all references.
+
+2021-09-04 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Avoid segfault in command-modes
+
+ * src/data.c (Fcommand_modes): Check that bytecode object is
+ interactive before accessing its interactive spec to avoid
+ segfaulting (bug#50376).
+
+2021-09-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/timer.el (timer-create): Don't inline it
+
+2021-09-04 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of line truncation and wrapping
+
+ * doc/emacs/display.texi (Line Truncation, Visual Line Mode):
+ * doc/lispref/display.texi (Truncation): Document that turning on
+ line truncation disables wrapping, and vice versa.
+
+ * src/buffer.c (syms_of_buffer) <truncate-lines>:
+ * src/xdisp.c (syms_of_xdisp) <truncate-partial-width-windows>:
+ Warn against turning on when 'visual-line-mode' is in effect.
+ * lisp/simple.el (visual-line-mode): Document that this mode
+ disables line truncation. (Bug#29664)
+
+2021-09-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow killing the diff buffer after `C-x v u'
+
+ * doc/emacs/maintaining.texi (VC Undo): Document this.
+ * lisp/vc/vc.el (vc-revert-show-diff): Allow a `kill' value.
+ (vc-revert): Use it (bug#16902).
+
+2021-09-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve error message in ielm on printing errors
+
+ * lisp/ielm.el (ielm-eval-input): Don't claim that there's a bug
+ on pp -- it may just be something that nests too far (bug#18012).
+
+2021-09-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a customization group link from whitespace-mode
+
+ * lisp/whitespace.el (whitespace-mode): Add a link to the
+ whitespace customization group to see the faces (bug#18296).
+
+2021-09-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add support for customization group hyperlinks in doc strings
+
+ * lisp/help-mode.el (help-customization-group): New button.
+ (help-xref-customization-group-regexp): New const.
+ (help-make-xrefs): Use them to allow making customization group
+ buttons.
+
+2021-09-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make multi-frame `M-x calendar' setup work when `pop-up-frames'
+
+ * lisp/calendar/calendar.el (calendar): Make the calendar frame
+ setup work when pop-up-frames is non-nil (bug#19256).
+
+2021-09-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak hi-lock-mode doc string
+
+ * lisp/hi-lock.el (hi-lock-mode): Tweak the doc string so that
+ running hi-lock-mode in a *Help* buffer showing this help text
+ won't issue an error (bug#20977).
+
+2021-09-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `M-x term' offer completion
+
+ * lisp/term.el (term): Have completion in the prompt (bug#21296).
+
+2021-09-04 Yuchen Pei <hi@ypei.me>
+
+ Add diary-offset to diary-lib.el
+
+ * doc/emacs/calendar.texi: Document the change.
+ * lisp/calendar/diary-lib.el (diary-offset):
+ * test/lisp/calendar/icalendar-tests.el: Add a test (bug#50195).
+
+2021-09-04 Stefan Kangas <stefan@marxist.se>
+
+ * etc/DISTRIB: Refer to gnu.org instead of the deleted file etc/GNU.
+
+2021-09-03 Glenn Morris <rgm@gnu.org>
+
+ * doc/misc/efaq.texi (Reporting bugs): Refer to the Emacs manual.
+
+ That is better than having a separate, outdated text.
+
+2021-09-03 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 0aa0410372 (origin/emacs-27, emacs-27) Fix "Finder" description for m...
+
+2021-09-03 Augusto Stoffel <arstoffel@gmail.com>
+
+ Change Python eval to send directly instead of using temporary files
+
+ * lisp/progmodes/python.el (python-shell-eval-setup-code): New
+ const for setting up eval (bug#49822).
+ (python-shell--encode-string): New function.
+ (python-shell-send-string): Use it to send commands directly
+ instead of writing to a temporary file.
+ (python-shell-send-string-no-output): Adjust sending.
+ (python-shell-send-file): Ditto.
+
+2021-09-03 Theodor Thornhill <theo@thornhill.no>
+
+ Update to CSS Flexible Box Layout Module Level 2
+
+ * lisp/textmodes/css-mode.el (css-property-alist): Update link.
+
+2021-09-03 Theodor Thornhill <theo@thornhill.no>
+
+ Update to CSS Containment Module Level 2
+
+ * lisp/textmodes/css-mode.el (css-property-alist): Update contain,
+ and add content-visibility.
+
+2021-09-03 Theodor Thornhill <theo@thornhill.no>
+
+ Update to CSS Grid Layout Module Level 2
+
+ * lisp/textmodes/css-mode.el (css-property-alist): Update to the
+ newer spec, and add the subgrid keywords.
+
+2021-09-03 Theodor Thornhill <theo@thornhill.no>
+
+ Clean up css-property-alist for alignment
+
+ * lisp/textmodes/css-mode.el (css-property-alist)
+ (css-value-class-alist): Provide new position related entries for
+ use in css-property-alist. Make sure that property-alist reflect
+ the spec: https://www.w3.org/TR/css-align-3/#property-index
+
+2021-09-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix `describe-function' for autoloaded adviced functions
+
+ * lisp/emacs-lisp/nadvice.el (advice--make-single-doc): Factor
+ out.
+ (advice--make-docstring): From here (bug#23523). Also include
+ advices for autoloads.
+
+2021-09-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow gud-mi to edit two executables with the same name
+
+ * lisp/progmodes/gud.el (gud-common-init): Allow editing two
+ executables with the same name (bug#22772).
+
+2021-09-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make recent timer changes more backwards-compatible
+
+ * lisp/emacs-lisp/timer.el (timerp, timer-event-handler): Make
+ backwards-compatible with old .elc files that have their own
+ versions of `timer-create'd structures.
+
+2021-09-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix message in previous toggle-truncate-lines change
+
+ * lisp/simple.el (toggle-truncate-lines): Fix message in previous
+ change.
+
+2021-09-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow not putting pasted text onto the kill ring under xterm
+
+ * lisp/term/xterm.el (xterm-paste): Don't put pasted text onto the
+ kill ring (bug#28868).
+ (xterm-store-paste-on-kill-ring): New user option.
+
+2021-09-03 Eli Zaretskii <eliz@gnu.org>
+
+ * etc/NEWS: Announce recent change in 'toggle-truncate-lines'.
+
+2021-09-03 Stefan Kangas <stefan@marxist.se>
+
+ Sync latest SKK-JISYO.L
+
+ * leim/SKK-DIC/SKK-JISYO.L: Sync to current upstream version.
+
+2021-09-03 Stefan Kangas <stefan@marxist.se>
+
+ Update publicsuffix.txt from upstream
+
+ * etc/publicsuffix.txt: Update from
+ https://publicsuffix.org/list/public_suffix_list.dat
+ dated 2021-09-02 22:13:03 UTC.
+
+2021-09-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make toggle-truncate-lines disable visual-line-mode
+
+ * lisp/simple.el (toggle-truncate-lines): Disable
+ `visual-line-mode' (bug#29664).
+
+2021-09-03 Stefan Kangas <stefan@marxist.se>
+
+ Avoid cl-lib alias for cadadr and friends
+
+ * lisp/edmacro.el (edmacro-fix-menu-commands):
+ * lisp/frameset.el (frameset-move-onscreen):
+ * lisp/htmlfontify.el (hfy-face-at, hfy-merge-adjacent-spans)
+ (hfy-mark-tag-names):
+ * lisp/mail/footnote.el (footnote--make-hole)
+ (footnote-back-to-message):
+ * lisp/net/eudc.el (eudc-get-email, eudc-get-phone):
+ * lisp/net/rcirc.el (rcirc-make-trees, rcirc-handler-333)
+ (rcirc-authenticate):
+ * lisp/play/5x5.el (5x5-draw-grid, 5x5-solver):
+ * lisp/play/decipher.el (decipher-insert-frequency-counts):
+ * lisp/ses.el (ses-relocate-range):
+ * test/lisp/emacs-lisp/edebug-tests.el (edebug-tests-step-into-macro-error)
+ (edebug-tests-error-stepping-into-subr): Avoid using cl-lib aliases
+ for cadadr and friends that now reside in subr.el.
+
+2021-09-03 Stefan Kangas <stefan@marxist.se>
+
+ Move cl-lib tests for caaXr to subr-tests.el
+
+ * test/lisp/emacs-lisp/cl-lib-tests.el (cl-test-caaar)
+ (cl-test-caadr): Move tests using a cl-lib alias from here...
+ * test/lisp/subr-tests.el (subr-test-caaar, subr-test-caadr): ...to
+ here. The functions under test are in subr.el.
+
+2021-09-03 Theodor Thornhill <theo@thornhill.no>
+
+ Add CSS Box Alignment Module Level 3 to css-mode
+
+ * lisp/textmodes/css-mode.el (css-property-alist): Consolidate
+ `align-{contents, items, self}', as well as the corresponding
+ values for `justify-{contents, items, self}' and `place-{contents,
+ items, self}'. Values extracted from the flex part and into its
+ own block (bug#50345).
+
+2021-09-03 Theodor Thornhill <theo@thornhill.no>
+
+ Add selection to css-pseudo-element-ids
+
+ * lisp/textmodes/css-mode.el (css-pseudo-element-ids): Add
+ selection as an element id (bug#50345).
+
+2021-09-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix `revert-buffer' message in `find-file-select'
+
+ * lisp/files.el (find-file-noselect): Refer to revert-buffer-quick
+ here since we're in a file-based buffer.
+
+2021-09-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix memory-report test failure
+
+ * test/lisp/emacs-lisp/memory-report-tests.el: Fix test build failure.
+
+2021-09-03 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix recently broken vc-delete-file with Git
+
+ * lisp/vc/vc-git.el (vc-git-delete-file):
+ Treat FILE as string, not list (bug#50334).
+
+2021-09-03 Glenn Morris <rgm@gnu.org>
+
+ More fixes for recently added vc-rename test
+
+ * test/lisp/vc/vc-tests.el (vc-test-cvs05-rename-file): Skip.
+ (vc-test-sccs05-rename-file): Treat like RCS.
+
+2021-09-02 Tassilo Horn <tsdh@gnu.org>
+
+ Support forges by type rather than by host
+
+ Formerly, bug-reference-setup-from-vc-alist basically had one entry
+ per host (like gitlab.com). Restructure so that it's easy to add new
+ hosts being just an instance of some type of forge such as SourceHut,
+ Gitea, or GitLab.
+
+ While we're at it, add support for gitea.com, salsa.debian.org, and
+ framagit.org, the latter two being GitLab instances.
+
+ * lisp/progmodes/bug-reference.el (bug-reference-gitea-instances)
+ (bug-reference-gitlab-instances,bug-reference-sourcehut-instances):
+ New variables listing online instances of those forges.
+ (bug-reference--setup-from-vc-alist): New function (and variable for
+ caching) using the former three new variables to generate suitable VC
+ auto-setup alist.
+ (bug-reference-try-setup-from-vc): Use both
+ bug-reference-setup-from-vc-alist and
+ bug-reference--setup-from-vc-alist.
+
+2021-09-02 Juri Linkov <juri@linkov.net>
+
+ * lisp/abbrev.el: Improve docstrings of inverse commands (bug#50303)
+
+ * lisp/abbrev.el (add-mode-abbrev, add-global-abbrev)
+ (inverse-add-mode-abbrev, inverse-add-global-abbrev):
+ Add interlinking to opposite commands in docstrings.
+
+2021-09-02 Eli Zaretskii <eliz@gnu.org>
+
+ Fix expansion of non-ASCII $HOME
+
+ * src/fileio.c (Fexpand_file_name): Make the file name multibyte
+ if the value of $HOME is multibyte. (Bug#50266)
+
+2021-09-02 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'clone-frame' on TTY frames
+
+ * src/frame.c (Fmake_terminal_frame): Make a separate copy of the
+ faces for the new frame before calling modify-frame-parameters, as
+ on TTY frames that needs the faces already set up. (Bug#34715)
+
+2021-09-02 Eli Zaretskii <eliz@gnu.org>
+
+ Improve a recent change in 'mule-cmds.el'
+
+ * lisp/international/mule-cmds.el
+ (select-safe-coding-system--format-list): Display codepoints in
+ hex and as characters. Display the ellipsis in a better place.
+ Enlarge the limit to 5 codepoints, as the display is now easier to
+ grasp.
+ (select-safe-coding-system-interactively): Don't use
+ 'select-safe-coding-system--format-list' for "rejected"
+ coding-systems, as those don't come with characters and positions.
+
+2021-09-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the coding system warning prettier
+
+ * lisp/international/mule-cmds.el
+ (select-safe-coding-system--format-list): New function to display
+ the coding system information in a more readable format (bug#31062).
+ (select-safe-coding-system-interactively): Use it.
+
+2021-09-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Reformat up-list and backward-up-list doc strings
+
+ * lisp/emacs-lisp/lisp.el (backward-up-list): Reformat the doc
+ string into several paragraphs (bug#31349).
+ (up-list): Ditto and fix the "start" to be "end".
+
+2021-09-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ isearch*-lax-whitespace doc string improvements
+
+ * lisp/isearch.el (isearch-regexp-lax-whitespace):
+ * lisp/isearch.el (isearch-lax-whitespace): Mention the key binding
+ in the doc string (bug#31790).
+
+2021-09-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix documentation of `dired-do-touch'
+
+ * doc/emacs/dired.texi (Operating on Files): Fix documentation of
+ `dired-do-touch' (bug#50323).
+
+2021-09-02 Yikai Zhao <yikai@z1k.dev>
+
+ memory-report: support calculating size for structures
+
+ * lisp/emacs-lisp/memory-report.el (memory-report--object-size-1): Add
+ support for cl-defstruct types (bug#50301).
+
+2021-09-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up previous ebfn2ps tweak
+
+ * lisp/progmodes/ebnf2ps.el (ebnf-print-buffer): Remove NOOP decode
+ step.
+
+2021-09-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a test for bug#50320 in sh-script
+
+2021-09-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Tweak sh-script-mode indentation further"
+
+ This reverts commit 6392bc37ab3b7eb83465d9b2248d21173373ae73.
+
+ The changes led to errors throughout (bug#50320).
+
+2021-09-02 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ tramp-auto-save-directory: make private
+
+ * lisp/net/tramp.el (tramp-handle-make-auto-save-file-name):
+ chmod 0700 tramp-auto-save-directory when creating
+
+ Thanks to Michael Albinus for reviewing this patch.
+
+2021-09-01 Eli Zaretskii <eliz@gnu.org>
+
+ Fix segfault with invalid key-translation-map binding
+
+ * src/keyboard.c (access_keymap_keyremap): Don't assume an invalid
+ function is specified as a symbol. Reported by Perry E. Metzger
+ <perry@piermont.com>.
+
+2021-09-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Filter out the `name' parameter in clone-frame
+
+ * lisp/frame.el (clone-frame): Filter out the `name' parameter,
+ because two frames shouldn't have the same name and this will
+ lead to a warning.
+
+2021-09-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't have epg bug out on non-existent packages
+
+ * lisp/epg.el (epg--start): We may be called from contexts where
+ the directory doesn't exist, but we need to have an existing
+ directory here for the process (bug#32004).
+
+2021-09-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new macro `with-existing-directory'
+
+ * doc/lispref/files.texi (Testing Accessibility): Document it.
+ * lisp/subr.el (with-existing-directory): New macro (bug#32004).
+
+2021-09-01 Kien Nguyen <kien.n.quang@gmail.com>
+
+ * Add a dll loader entry for gcc_jit_context_new_cast (bug#50315)
+
+ * src/comp.c: Add a dll loader entry for
+ 'gcc_jit_context_new_cast' (bug#50315).
+
+2021-09-01 Drew Adams <drew.adams@oracle.com>
+
+ Add new command `clone-frame'
+
+ * doc/emacs/frames.texi (Creating Frames): Document it.
+
+ * lisp/frame.el (clone-frame): New command and keystroke (bug#34715).
+
+2021-09-01 Glenn Morris <rgm@gnu.org>
+
+ Make set-foreground-color display completions using foreground colors
+
+ * lisp/faces.el (defined-colors-with-face-attributes): Also create
+ colors for foregrounds (bug#33799).
+ (read-color): Also allow varying the foreground color.
+
+ * lisp/frame.el (set-foreground-color): Vary the foreground color.
+
+2021-09-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix (setf (map-elt map key) (my-func))
+
+ * lisp/emacs-lisp/map.el (map-elt): Ensure that the value isn't
+ referenced more than once (bug#50290).
+
+2021-09-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Autoload calc-grab-sum-across and calc-grab-sum-down
+
+ * lisp/calc/calc.el (calc-grab-sum-down):
+ (calc-grab-sum-across): Autoload, since they can be used from
+ outside Calc (bug#50311).
+
+2021-09-01 Miha Rihtaršič <miha@kamnitnik.top>
+
+ In batch mode, avoid killing Emacs with C-g in the minibuffer
+
+ * src/keyboard.c (Fcommand_error_default_function): Don't kill emacs
+ when handling the minibuffer-quit condition (bug#48603).
+
+2021-09-01 Marco Centurion <mcenturion@fing.edu.uy> (tiny change)
+
+ Use "gzip -d" instead of "gunzip"
+
+ * lisp/dired-aux.el (dired-compress-file-suffixes): Use "gzip -d"
+ instead of "gunzip" since we already assume that "gzip" exists on
+ the system (bug#10990).
+
+2021-08-31 Philip Kaludercic <philipk@posteo.net>
+
+ Avoid failing if vc backend doesn't implement ignore-completion-table
+
+ * lisp/progmodes/project.el (project-ignores): Handle
+ vc-not-supported signals.
+
+2021-08-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Rename xref--mouse-2 and adjust documentation
+
+ * doc/emacs/maintaining.texi (Xref Commands): `mouse-1' is bound
+ to `xref-goto-xref', not `mouse-2' (bug#35376).
+ (Xref Commands): Mention what `mouse-2' does.
+
+ * lisp/progmodes/xref.el (xref--button-map): Adjust.
+ (xref-select-and-goto-xref): Rename from xref--mouse-2 (bug#35376).
+
+2021-08-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix point placement after ispell-complete-word
+
+ * lisp/textmodes/ispell.el (ispell-complete-word): Leave point at
+ the end of the inserted word instead of a less than useful amount
+ of distance from the start of the word (bug#37552).
+
+2021-08-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ call-process doc string clarification
+
+ * src/callproc.c (Fcall_process): Explicitly say that "output"
+ means both stdout and stderr (bug#37906).
+
+2021-08-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make calc plotting through gnuplot work on non-X gnuplots
+
+ * lisp/calc/calc-graph.el (calc-graph-plot): Fall back on "dumb"
+ if we don't support the terminal (bug#50237).
+ (calc-gnuplot-command): Say whether the command errored out.
+
+2021-08-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix abnf parsing of <prose> elements
+
+ * lisp/progmodes/ebnf-abn.el (ebnf-abn-lex): Make <prose> parsing
+ work (bug#39663).
+
+2021-08-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make run-at-time try harder to run at integral multiples
+
+ * lisp/emacs-lisp/timer.el (timer): Add new slot integral-multiple.
+ (timerp): Adjust.
+ (timer-event-handler): Recompute the delay if requested
+ (bug#39099).
+ (run-at-time): Mark the timer as recomputable if given a t
+ parameter.
+
+ * src/keyboard.c (decode_timer): Adjust.
+
+2021-08-31 Dmitry Gutov <dgutov@yandex.ru>
+
+ Move the expansion of abbreviated names to vc-git.el
+
+ * lisp/vc/vc-git.el (vc-git--literal-pathspec):
+ Perform the expansion of abbreviated file names here instead
+ (bug#39452).
+
+ * lisp/vc/vc.el (vc-root-diff, vc-print-root-log):
+ Undo the recent change.
+
+2021-08-30 Andreas Schwab <schwab@linux-m68k.org>
+
+ Implement proper type conversion in native compiler
+
+ * src/comp.c (enum cast_kind_of_type): Remove.
+ (comp_t): Add cast_ptr_to_int, cast_int_to_ptr, remove
+ cast_type_sizes, cast_type_kind, cast_type_names, cast_union_fields,
+ cast_union_field_biggest_type.
+ (emit_coerce): Remove check for type size.
+ (struct cast_type): Remove bytes_size.
+ (define_type_punning): New function.
+ (define_cast_from_to): Implement proper type conversion.
+ (define_cast_functions): Adjust. (bug#50230)
+
+2021-08-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ (cperl-test-bug-14343): Make it work for perl-mode
+
+ * test/lisp/progmodes/cperl-mode-tests.el (cperl--tests-heredoc-face):
+ New const.
+ (cperl-test-heredocs, cperl-test-bug-14343): Use it.
+ (cperl-test-identify-no-heredoc): Remove left-over message.
+
+2021-08-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * test/lisp/progmodes/cperl-mode-tests.el: Adjust here-doc tests for perl-mode
+
+ (cperl-test-identify-heredoc, cperl-test-identify-no-heredoc):
+ Tweak tests so they can also be used for perl-mode.
+
+2021-08-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * etc/NEWS: Fix typo
+
+2021-08-30 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'ispell-hunspell-add-multi-dic'
+
+ * lisp/textmodes/ispell.el (ispell-hunspell-add-multi-dic):
+ Explain in the doc string how to call from Lisp. (Bug#50241)
+
+2021-08-30 Eli Zaretskii <eliz@gnu.org>
+
+ Minor improvement in 'get-locale-names' on MS-Windows
+
+ * lisp/international/mule-cmds.el (get-locale-names): Delete
+ duplicate locales from the list returned by the MS-Windows
+ implementation.
+
+2021-08-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix typo in kill-buffer-delete-auto-save-files NEWS entry
+
+2021-08-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make some non-ASCII work in ebnf2ps
+
+ * lisp/progmodes/ebnf2ps.el (ebnf-print-buffer): Make non-ASCII
+ work slightly better (bug#39663).
+
+2021-08-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix typo in previous custom.texi change
+
+ * doc/emacs/custom.texi (Init Syntax): Fix typo in previous change
+ -- it's customize-set-variable.
+
+2021-08-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make epg use rfc6068 for decoding %-encoded strings
+
+ * lisp/epg.el (epg--decode-percent-escape-as-utf-8): Make obsolete
+ and adjust callers.
+ (epg--decode-hexstring): Ditto.
+
+ * lisp/mail/rfc6068.el (rfc6068-unhexify-string): Allow returning
+ non-decoded octets (bug#39689).
+
+2021-08-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make rfc2368 obsolete and add rfc6068
+
+ * lisp/obsolete/rfc2368.el: Moved here and made obsolete.
+
+ * lisp/mail/rfc6068.el (rfc6068-unhexify-string): New file.
+
+2021-08-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Only look for the port command on MacOS
+
+ * configure.ac: Only look for the port command on MacOS (bug#50259).
+
+2021-08-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move vc-branch-p and vc-branch-part from vc.el to vc-rcs.el and rename
+
+ * lisp/vc/vc-rcs.el (vc-rcs-branch-p): Renamed from `vc-branch-p'
+ (old name made into obsolete alias) and moved from vc.el.
+ (vc-rcs-branch-part): Renamed from `vc-branch-part'
+ (old name made into obsolete alias) and moved from vc.el.
+
+2021-08-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix vc test for RCS
+
+ * test/lisp/vc/vc-tests.el (vc-test--rename-file): Fix test for RCS.
+
+2021-08-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention `set-variable' in the Init Syntax Emacs manual node
+
+ * doc/emacs/custom.texi (Init Syntax): Mention set-variable
+ (bug#50248).
+ (Init Examples): Add an example.
+
+2021-08-29 Clément Pit-Claudel <clement.pitclaudel@live.com>
+
+ Change --with-nativecomp to --with-native-compilation in messages
+
+ * configure.ac:
+ * test/infra/Dockerfile.emba:
+ * test/infra/gitlab-ci.yml: Fix mentions of --with-nativecomp
+ (bug#50255).
+
+2021-08-29 Augusto Stoffel <arstoffel@gmail.com>
+
+ Add support for OSC 7 in comint (current directory tracking)
+
+ * lisp/comint.el (comint-osc-directory-tracker, comint-osc-handlers):
+ Define and register a handler for OSC 7.
+ (comint-osc-process-output): Do fewer checks on
+ 'comint-last-output-start'.
+
+2021-08-29 Kévin Le Gouguec <kevin.legouguec@gmail.com>
+
+ Tweak sh-script-mode indentation further
+
+ * lisp/progmodes/sh-script.el (sh-smie--default-backward-token):
+ Allow more parentheses in a token (bug#44592).
+
+2021-08-29 Philipp Stephani <phst@google.com>
+
+ Improve compatibility with musl-libc (Bug#48789)
+
+ * lib-src/seccomp-filter.c (export_filter): Remove use of
+ nonstandard macro TEMP_FAILURE_RETRY.
+
+2021-08-29 Alan Mackenzie <acm@muc.de>
+
+ C++ Mode: handle compound identifiers preceding brace lists correctly
+
+ * lisp/progmodes/cc-engine.el (c-looking-at-or-maybe-in-bracelist): early in
+ function, check alternatively for c-back-over-compound-identifier when doing
+ c-backward-token-2.
+
+2021-08-29 Alan Third <alan@idiocy.org>
+
+ Fix libexec installation on NS (bug#50250)
+
+ * lib-src/Makefile.in (ns_applibexecdir): New variable.
+
+2021-08-29 Eli Zaretskii <eliz@gnu.org>
+
+ Better document obsolescence of 'values'
+
+ * doc/lispref/eval.texi (Eval): Mention that 'values' is obsolete.
+ * etc/NEWS: Add a rationale for obsoleting 'values'.
+
+2021-08-29 Alan Third <alan@idiocy.org>
+
+ Disable the NS app when no frames are left (bug#14619, bug#21357, bug#23586)
+
+ * src/nsfns.m (Fx_create_frame): Enable the app.
+ * src/nsterm.m (ns_delete_terminal): Disable the app.
+
+2021-08-29 Dmitry Gutov <dgutov@yandex.ru>
+
+ Add tests for vc-rename-file
+
+ * test/lisp/vc/vc-tests.el (vc-test--rename-file): New function.
+ (vc-test-%s05-rename-file): New family of tests (bug#39452).
+
+2021-08-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * etc/NEWS: Document the recent xterm.el change for `\e[29~`
+
+2021-08-27 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/flymake.el: Bind mouse-3 to flymake-menu on mode-line.
+
+ * lisp/progmodes/flymake.el (flymake--mode-line-title):
+ Bind [mode-line down-mouse-3] to flymake-menu (bug#50067)
+
+2021-08-27 Juri Linkov <juri@linkov.net>
+
+ Revert part of 3572613550f5d1d0b3392dbc809b32f3989e2981 (bug#39452)
+
+ * lisp/vc/vc-git.el (vc-git-rename-file): Don't use vc-git--literal-pathspecs.
+
+2021-08-27 Dario Gjorgjevski <dario.gjorgjevski@gmail.com>
+
+ Fix shell-script-mode indentation of continuation lines
+
+ * lisp/progmodes/sh-script.el (sh-smie--default-backward-token):
+ Fix indentation of continuation lines (bug#44592).
+
+2021-08-27 Michalis V <mvar.40k@gmail.com>
+
+ Fix completion of extended "..." syntax in eshell
+
+ * lisp/eshell/em-cmpl.el (eshell-complete-parse-arguments): Expand
+ "..." (bug#19626).
+
+2021-08-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't overly truncate tabulated-list headers
+
+ * lisp/emacs-lisp/tabulated-list.el (tabulated-list-init-header):
+ Don't overly truncate headers that are before a right-aligned
+ column (bug#44594).
+ (tabulated-list--available-space): Separated out into own
+ function...
+ (tabulated-list-print-col): ... from here.
+
+2021-08-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix `M-X TAB' completion for commands marked for multiple modes
+
+ * lisp/simple.el (command-completion-using-modes-p): Fix
+ completion over commands that are defined for multiple modes
+ (bug#50228).
+
+2021-08-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Put advice documentation at the end of the displayed doc string
+
+ * lisp/emacs-lisp/nadvice.el (advice--make-docstring): Put the
+ advice things at the end of the documentation (bug#50222). It's
+ important to have the first line of the original documentation
+ remain the first line, because it's used when doing one-line
+ summaries of the function.
+
+2021-08-27 Thierry Volpiatto <thievol@posteo.net>
+
+ Make `eshell-command' also work when asynchronous
+
+ * lisp/eshell/esh-cmd.el (eshell-eval-command): Make asynchronous
+ `eshell-command' work (e.g. `M-x eshell-command RET sleep 10 &')
+ (bug#50209).
+
+2021-08-27 Christophe Troestler <Christophe.Troestler@umons.ac.be> (tiny change)
+
+ lisp/newcomment.el: Uncommenting with whitespace `comment-continue'
+
+ * lisp/newcomment.el (uncomment-region-default-1): Make
+ all-whitespace `comment-continue' work (bug#50226).
+
+2021-08-27 Andrea Corallo <akrl@sdf.org>
+
+ Forward `comp-file-preloaded-p' to async workers
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): Forward
+ `comp-file-preloaded-p' to async workers.
+
+2021-08-27 Juri Linkov <juri@linkov.net>
+
+ Replace flyspell-use-mouse-3-for-menu with context-menu-mode (bug#50067)
+
+ * doc/emacs/fixit.texi (Spelling): Replace mentions of
+ flyspell-use-mouse-3-for-menu with context-menu-mode.
+
+ * lisp/mouse.el (context-menu-map): Use the function from the
+ text property context-menu-function at mouse click event.
+
+ * lisp/textmodes/flyspell.el (flyspell--set-use-mouse-3-for-menu):
+ Remove function.
+ (flyspell-use-mouse-3-for-menu): Remove defcustom added recently in 28.1.
+ (flyspell-context-menu): New function.
+ (flyspell-mode): Don't call flyspell--set-use-mouse-3-for-menu.
+ (flyspell-mode-on): Replace flyspell-use-mouse-3-for-menu
+ with context-menu-mode.
+ (make-flyspell-overlay): When context-menu-mode is non-nil,
+ put overlay context-menu-function with flyspell-context-menu
+ instead of using keymap flyspell-mouse-map.
+
+2021-08-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ python-shell-interpreter doc string clarification
+
+ * lisp/progmodes/python.el (python-shell-interpreter): Note what
+ to do when using ipython3 (bug#44732).
+
+2021-08-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix backtrace when query-about-changed-file nil and file has changed
+
+ * lisp/userlock.el (userlock--check-content-unchanged): Make the
+ assertion more robust -- we may be called here from a different
+ contexts if `query-about-changed-file' is nil.
+
+2021-08-27 Noah Evans <noah@nevans.me> (tiny change)
+
+ Fix recentering issue in `follow-mode'
+
+ * lisp/follow.el (follow-recenter): Make `C-c . C-l' work in
+ windows before the middle one, too (bug#50220).
+
+2021-08-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Enable setting timeclock-workday after switching mode on
+
+ * lisp/calendar/timeclock.el (timeclock--previous-workday): New
+ variable.
+ (timeclock-find-discrep): Use it to flush values when
+ timeclock-workday changes (bug#50216).
+ (timeclock-mode-line-display): Mention `timeclock-workday' setting
+ in doc string.
+
+2021-08-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with symlinks in compile buffers
+
+ * lisp/progmodes/compile.el (compilation-find-file): Avoid
+ `expand-file-name' when computing the file names, because that will
+ reliably give the wrong result when there's symlinks and ".."
+ involved (bug#8035).
+
+2021-08-26 Philip Kaludercic <philipk@posteo.net>
+
+ timeclock.el: Update example configuration
+
+ * lisp/calendar/timeclock.el: Update comments that were no longer
+ correct (bug#50211).
+
+2021-08-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make dired-chmod-program obsolete
+
+ * lisp/dired.el (dired-chmod-program): Make into a defvar and make
+ obsolete (bug#50190).
+
+ * lisp/net/ange-ftp.el (ange-ftp-process-file): Remove usage of
+ dired-chmod-program.
+
+2021-08-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Add support for "bright" ANSI colors in ansi-color"
+
+ This reverts commit c8e3347ec01a9ed6dc8d88c2dbbb3a08497e8eb2.
+
+ Jim Porter's paperwork isn't finalised yet.
+
+2021-08-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Add support for "bright" ANSI colors in term-mode"
+
+ This reverts commit 2b2a103db0c3597c7685d3ffff4bca7f2e4d094e.
+
+ Jim Porter's paperwork isn't finalized yet.
+
+2021-08-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Add missing :version tags to new faces"
+
+ This reverts commit 9759fb596b634db2faf7edcd4fd557a11abe9903.
+
+ Jim Porter's paperwork isn't finalized yet.
+
+2021-08-26 Michael Albinus <michael.albinus@gmx.de>
+
+ Improve robustness of shadowfile.el
+
+ * lisp/shadowfile.el (shadow-site-help): New defconst.
+ (shadow-read-site): Use it.
+ (shadow-make-fullname, shadow-contract-file-name)
+ (shadow-define-literal-group): Handle errors more robust. (Bug#49596)
+
+ * test/lisp/shadowfile-tests.el (shadow-test06-literal-groups):
+ Extend test.
+
+2021-08-26 Tassilo Horn <tsdh@gnu.org>
+
+ Fix docs about the meaning of the Re: in the subject
+
+ * doc/misc/message.texi (Message Headers): Clarify that it comes from
+ the Latin "res" meaning "in the matter of" rather than "in response
+ to" as claimed previously (see RFC-2822).
+
+2021-08-26 Eli Zaretskii <eliz@gnu.org>
+
+ Define a substitute for <menu> on MS-Windows
+
+ * lisp/mouse.el (context-menu-mode-map): On w32, use <apps>
+ in addition to (the mostly non-existent) <menu>.
+
+2021-08-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ Rename arguments for clarity
+
+ * lisp/vc/vc-git.el (vc-git--literal-pathspecs)
+ (vc-git--literal-pathspecs):
+ Rename arguments for clarity (bug#39452).
+
+2021-08-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ Make sure to remove the remote specification before adding :(literal)
+
+ * lisp/vc/vc-git.el (vc-git--literal-pathspec):
+ Make sure to remove the remote specification from the file name
+ (bug#50175, bug#39452).
+
+2021-08-26 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ Fix "Finder" description for multi-file packages
+
+ * lisp/finder.el (finder-compile-keywords): Now that 'version' is
+ set for more files, it is no longer necessary to check that we have
+ a version when picking the file from which to take the description.
+ Doing so caused built-in packages (where the version is known) to have
+ their package description taken from the last .el file that matched the
+ file name pattern, usually the last source file in the sub-directory.
+
+ This bug was introduced in July 2019 and first released in Emacs 27.1.
+
+ Thanks to Michael Albinus for reviewing this patch.
+
+2021-08-26 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/term/xterm.el (xterm-function-map): Map `\e[29~` to `menu`
+
+2021-08-25 Gabriel do Nascimento Ribeiro <gabriel376@hotmail.com>
+
+ Handle nil messages in repeat-echo-message.
+
+ * lisp/repeat.el (repeat-echo-message): Handle cases where
+ 'current-message' is nil (bug#50176).
+
+2021-08-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make thingatpt respect fields
+
+ * lisp/thingatpt.el (thing-at-point): Make thingatpt respect
+ fields (bug#9454).
+
+2021-08-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `set-locale-environment' complete over locale names
+
+ * lisp/international/mule-cmds.el (get-locale-names): New function.
+ (set-locale-environment): Use it to allow completion (bug#9655).
+
+2021-08-25 João Távora <joaotavora@gmail.com>
+
+ Speed up pcm completion styles for patternless special case
+
+ (Bug#48841)
+
+ * lisp/minibuffer.el (completion-flex-all-completions): Skip
+ completion-pcm--hilit-commonality if there's no pattern yet.
+
+2021-08-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Disable xterm selection operators in stterm
+
+ * lisp/term/st.el (xterm-st-extra-capabilities): st doesn't
+ support the xterm selection things (bug#50192).
+
+2021-08-25 Eli Zaretskii <eliz@gnu.org>
+
+ Add missing :version tags to new faces
+
+ * lisp/term.el (term-color-bright-black, term-color-bright-red)
+ (term-color-bright-green, term-color-bright-yellow)
+ (term-color-bright-blue, term-color-bright-magenta)
+ (term-color-bright-cyan, term-color-bright-white): Add :version.
+
+2021-08-25 Jim Porter <jporterbugs@gmail.com>
+
+ Add support for "bright" ANSI colors in term-mode
+
+ * lisp/term.el (ansi-term-color-vector): Add new faces.
+ (term-color-white): Tweak colors.
+ (term-color-bright-black, term-color-bright-red, term-color-bright-green)
+ (term-color-bright-yellow, term-color-bright-blue)
+ (term-color-bright-magenta, term-color-bright-cyan)
+ (term-color-bright-white): New faces.
+ (term--maybe-brighten-color): New function.
+ (term-handle-colors-array): Handle bright colors.
+ * test/lisp/term-tests.el (term-colors, term-colors-bold-is-bright):
+ New functions.
+
+2021-08-25 Jim Porter <jporterbugs@gmail.com>
+
+ Add support for "bright" ANSI colors in ansi-color
+
+ * lisp/ansi-color.el (ansi-bright-color-names-vector): New defcustom.
+ (ansi-color-bold-is-bright): New defcustom.
+ (ansi-color--find-face): Sort ANSI codes and check
+ 'ansi-color-bold-is-bright'.
+ (ansi-color-apply-sequence): Support bright ANSI colors.
+ (ansi-color--fill-color-map): New function.
+ (ansi-color-make-color-map): Add bright ANSI colors.
+ (ansi-color-get-face-1): Add BRIGHT parameter.
+ * test/lisp/ansi-color-tests.el
+ (ansi-color-apply-on-region-bold-is-bright-test): New function.
+
+2021-08-25 Shitikanth Kashyap <shitikanth1@gmail.com> (tiny change)
+
+ tabulated-list-print delete excess lines
+
+ * lisp/emacs-lisp/tabulated-list.el (tabulated-list-print): Ensure
+ that we delete remaining lines if the list has gotten shorter
+ (bug#50194).
+
+2021-08-25 Augusto Stoffel <arstoffel@gmail.com>
+
+ Add support for OSC escape codes in comint
+
+ * doc/emacs/misc.texi (Shell Mode): Document it.
+
+ * lisp/comint.el (comint-osc-handlers, comint-osc--marker): New
+ variables.
+ (comint-osc-process-output): New function.
+ (comint-osc-hyperlink-map): New map.
+ (comint-osc-hyperlink-handler): New function.
+
+2021-08-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up deleting auto-save/killing buffer wrt. `auto-save-visited-mode'
+
+ * src/buffer.c (Fkill_buffer): Respect `auto-save-visited-mode'.
+
+2021-08-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further checks for kill-buffer-delete-auto-save-files
+
+ * src/buffer.c (Fkill_buffer): Check that the auto-save file
+ exists before asking whether to delete it.
+
+2021-08-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up previous conf-mode/tex-mode redirection hacks
+
+ * lisp/textmodes/conf-mode.el (conf-mode):
+ * lisp/textmodes/tex-mode.el (tex--redirect-to-submode): The
+ previous hack to these redirections would disable all local
+ variables. Try to work around this a bit more.
+
+2021-08-24 Michael Albinus <michael.albinus@gmx.de>
+
+ Some precisements in Tramp's connection type handling
+
+ * doc/misc/tramp.texi (Remote processes): Precise connection type
+ handling.
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-make-process):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process):
+ * lisp/net/tramp.el (tramp-handle-make-process):
+ Fix :connection-type handling.
+ (tramp-action-show-and-confirm-message): Pacify byte compiler.
+
+ * lisp/net/tramp-compat.el (tramp-compat-ignore-error): New defmacro.
+
+ * test/lisp/net/tramp-tests.el (tramp-test29-start-file-process)
+ (tramp-test30-make-process): Extend tests.
+
+2021-08-24 Ergus <spacibba@aol.com>
+
+ * lisp/mouse.el (context-menu-mode-map): Bind [menu] to context-menu-open.
+
+ https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg01004.html
+
+2021-08-24 Juri Linkov <juri@linkov.net>
+
+ * lisp/mouse.el (context-menu-buffers): New function (bug#50067).
+
+ (context-menu-functions): Add context-menu-buffers to the choice list.
+
+2021-08-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ Doc that dired-do-chmod no longer follows symlinks
+
+ * doc/emacs/dired.texi (Operating on Files):
+ * etc/NEWS: Document this security precaution.
+
+2021-08-24 Gabriel do Nascimento Ribeiro <gabriel376@hotmail.com>
+
+ Fix to clear echo-area after repeat-exit-timeout.
+
+ * lisp/repeat.el (repeat-echo-message): Use 'string-match-p'
+ to handle cases where echo-area contains other messages (bug#50176).
+
+2021-08-23 Eli Zaretskii <eliz@gnu.org>
+
+ Document 'jit-lock-bounds'
+
+ * doc/lispref/modes.texi (Other Font Lock Variables):
+ * lisp/jit-lock.el (jit-lock-functions, jit-lock-register):
+ Document the return value of the fontification functions.
+
+2021-08-23 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'inhibit-mouse-event-check'
+
+ * etc/NEWS:
+ * src/callint.c (syms_of_callint): Fix wording of the
+ documentation of 'inhibit-mouse-event-check'.
+
+2021-08-23 Mattias Engdegård <mattiase@acm.org>
+
+ Add example of advanced user-defined Rx form to manual
+
+ * doc/lispref/searching.texi (Extending Rx): Add example illustrating
+ how to define a user-defined Rx form that performs computation,
+ from a discussion with Michael Herdeegen (bug#50136).
+ * lisp/emacs-lisp/rx.el (rx): Clarify evaluation time for `eval`.
+
+2021-08-23 Juri Linkov <juri@linkov.net>
+
+ * lisp/mouse.el (context-menu-open): New command bound to [S-f10].
+
+ * doc/emacs/frames.texi (Menu Mouse Clicks): Mention S-F10
+ to pop up the context menu.
+
+ * src/callint.c (Fcall_interactively):
+ Use inhibit_mouse_event_check for the case 'e'.
+ (inhibit-mouse-event-check): New variable.
+
+ https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00733.html
+
+2021-08-23 Glenn Morris <rgm@gnu.org>
+
+ Fix recently added cperl test
+
+ * test/lisp/progmodes/cperl-mode-tests.el
+ (cperl-test-here-doc-missing-end): Fix quote regexp.
+
+2021-08-23 Eli Zaretskii <eliz@gnu.org>
+
+ Improve recently-changed docs
+
+ * src/frame.c (Fnext_frame):
+ * doc/lispref/frames.texi (Finding All Frames): Improve wording
+ and style of the 'next-frame's documentation.
+
+2021-08-23 Eli Zaretskii <eliz@gnu.org>
+
+ Fix doc strings in recent changes.
+
+ * lisp/progmodes/cperl-mode.el (cperl-commentify)
+ (cperl-here-doc-functions, cperl-is-here-doc-p)
+ (cperl-find-pods-heres): Fix wording, style, and punctuation of
+ doc strings.
+
+2021-08-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify the documentation of `next-frame'
+
+ * doc/lispref/frames.texi (Finding All Frames): Clarify what it
+ means to "consider".
+ * src/frame.c (Fnext_frame): Rewrite doc string to say what the
+ parameters actually mean (bug#13339).
+
+2021-08-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new variable 'kill-buffer/delete-auto-save-files'
+
+ * doc/emacs/files.texi (Auto Save Files): Document it.
+ * lisp/cus-start.el (standard): Add customize form.
+
+ * lisp/files.el (delete-auto-save-files): Move definition to C
+ (since it's used in the C layer).
+
+ * src/buffer.c (Fkill_buffer): Use the new variable (and remove
+ the old code that apparently didn't trigger for
+ kill-buffer/delete-auto-save-files.
+ (syms_of_buffer): Add new variable
+ kill-buffer-delete-auto-save-files and move definition of
+ delete-auto-save-files here (bug#21612).
+
+2021-08-23 Michael Albinus <michael.albinus@gmx.de>
+
+ Complete implementation of `copy-directory-create-symlink' in Tramp
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-copy-directory): Fix the case
+ NEWNAME is a directory name with a trailing slash.
+
+ * lisp/net/tramp-smb.el (tramp-smb-handle-copy-directory):
+ Implement `copy-directory-create-symlink'. (Bug#10897)
+
+ * test/lisp/net/tramp-tests.el
+ (tramp--test-ignore-make-symbolic-link-error): Move up.
+ (tramp-test15-copy-directory): Extend test.
+
+2021-08-23 Juri Linkov <juri@linkov.net>
+
+ * lisp/mouse.el (context-menu-toolbar): New function.
+
+ (context-menu-functions): Add context-menu-toolbar to choice.
+ (context-menu-region): Bind "Paste" to mouse-yank-at-click
+ instead of mouse-yank-primary.
+ https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00735.html
+
+2021-08-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify :stderr in the make-process doc string
+
+ * src/process.c (Fmake_process): Elaborate upon what :stderr does
+ (bug#50166).
+
+2021-08-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Update NEWS tagging for modules and parse-time-string
+
+2021-08-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document `dlet'
+
+ * doc/lispref/variables.texi (Local Variables): Document `dlet'.
+
+2021-08-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve byte-compile-warnings doc string
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-warnings): Mention
+ 'byte-compile-docstring-max-column'.
+
+2021-08-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Do command mode markup in xwidget.el
+
+2021-08-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make xwidget-webkit-enable-plugins a defcustom
+
+ * lisp/xwidget.el (xwidget-webkit-enable-plugins): Make into
+ defcustom.
+
+2021-08-23 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix recent parse-partial-sexp argument validation
+
+ * src/syntax.c (parse-partial-sexp): Also handle markers as
+ arguments (bug#49944). Tweak error message to follow conventions in
+ "(elisp) Signaling Errors".
+
+2021-08-22 Andrea Corallo <akrl@sdf.org>
+
+ Set a unique ID for eln files on macOS (bug#45934)
+
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Set gcc's -install_name
+ parameter to the real filename.
+
+2021-08-22 Masahiro Nakamura <tsuucat@icloud.com>
+
+ Set label for NSToolbarItem (bug#50159)
+
+ * src/nsmenu.m (update_frame_tool_bar): Get label text and pass it to ...
+ ([EmacsToolbar addDisplayItemWithImage:idx:tag:labelText:helpText:enabled:]):
+ ... this that sets label for NSToolbarItem.
+ * src/nsterm.h
+ ([EmacsToolbar addDisplayItemWithImage:idx:tag:labelText:helpText:enabled:]):
+ Add labelText argument.
+
+2021-08-22 Michael Albinus <michael.albinus@gmx.de>
+
+ Implement `copy-directory-create-symlink' for remote files
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-copy-directory):
+ Implement `copy-directory-create-symlink'. (Bug#10897)
+
+ * test/lisp/net/tramp-tests.el (tramp-test15-copy-directory):
+ Extend test.
+
+2021-08-22 João Távora <joaotavora@gmail.com>
+
+ Double check completions-group customization variable in Icomplete
+
+ bug#48545
+
+ * lisp/icomplete.el (icomplete--augment): Double check completions-group.
+
+2021-08-22 João Távora <joaotavora@gmail.com>
+
+ Don't mess up grouping in completion-all-sorted-completions
+
+ The default sorting order will mess up the naturally grouped order of
+ the candidates in the table that specified the group-function.
+
+ As seen in xref.el when
+
+ (setq xref-show-definitions-function
+ 'xref-show-definitions-completing-read)
+ (setq completions-group t)
+ M-x fido-mode
+
+ Also partially seen with C-x 8 RET (M-x insert-char) with
+
+ (setq read-char-by-name-sort 'code)
+
+ bug#48545
+
+ * lisp/minibuffer.el (completion-all-sorted-completions): Don't
+ use default sort if there's a group-function in the table.
+
+2021-08-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Fix dired switch (that contain quotes and spaces) parsing"
+
+ This reverts commit 04f723dec944eaa7b5e99373840a8bf920ba5fdd.
+
+ The dired switches are documented to not follow shell syntax, but instead
+ uses a lisp-in-string-form kind of quoting.
+
+2021-08-22 Colin Woodbury <colin@fosskers.ca>
+
+ Don't echo empty string in file-name-with-extension
+
+ * lisp/files.el (file-name-with-extension): Avoid echoing a filename
+ string known to be empty (bug#50149).
+
+2021-08-22 Omar Polo <op@omarpolo.com>
+
+ Avoid using %n in emacsclient
+
+ * lib-src/emacsclient.c (local_sockname): Avoid using %n (bug#50155).
+
+2021-08-22 Michael Albinus <michael.albinus@gmx.de>
+
+ Some adaptions for Tramp's security key detection.
+
+ * lisp/net/tramp.el (tramp-security-key-timeout-regexp): New defcustom.
+ (tramp-action-show-and-confirm-message): Don't use timeout, check
+ for the timeout message of the ssh command.
+
+2021-08-22 Mattias Engdegård <mattiase@acm.org>
+
+ Make Qhide declaration non-target-specific
+
+ * src/xfns.c (syms_of_xfns): Move DEFSYM from here...
+ * src/menu.c (syms_of_menu): ... to here.
+ This fixes the NS build after dd7d966eb40b.
+
+2021-08-22 Ergus <spacibba@aol.com>
+
+ * lisp/mouse.el (context-menu-mode-map): New variable.
+
+ (context-menu--saved-bindings, context-menu--bind-mouse)
+ (context-menu--restore-bindings): Remove.
+ (context-menu-mode): Don't use removed functions.
+
+2021-08-22 Juri Linkov <juri@linkov.net>
+
+ Don't show menu titles with the text property 'hide' (bug#50067)
+
+ * lisp/mouse.el (context-menu-map): Add menu title "Context Menu"
+ propertized with the text property 'hide'.
+
+ * src/menu.c (x_popup_menu_1): Don't show the title with the non-nil
+ text property 'hide' on GTK and NS.
+
+2021-08-22 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'set-keyboard-coding-system'
+
+ * doc/lispref/nonascii.texi (Terminal I/O Encoding):
+ * doc/emacs/mule.texi (Terminal Coding):
+ * lisp/international/mule.el (set-keyboard-coding-system):
+ Document that 'set-keyboard-coding-system' has no effect on modern
+ MS-Windows systems. (Bug#15289)
+
+2021-08-22 Glenn Morris <rgm@gnu.org>
+
+ * test/lisp/international/ucs-normalize-tests.el: Save 30m on hydra.
+
+2021-08-22 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ mh-x-image-url-sane-p: accept "https" URLs
+
+ * lisp/mh-e/mh-xface.el (mh-x-image-url-sane-p): Accept https URLs.
+ * test/lisp/mh-e/mh-xface-tests.el: New file, to test
+ mh-x-image-url-sane-p.
+
+2021-08-21 Glenn Morris <rgm@gnu.org>
+
+ * test/Makefile.in: Turn off hydra verbose logging for electric-tests.
+
+2021-08-21 Glenn Morris <rgm@gnu.org>
+
+ * test/lisp/net/tramp-tests.el: Reduce hydra run time by 1 hour.
+
+ It's just too slow to run these after every commit.
+
+2021-08-21 Glenn Morris <rgm@gnu.org>
+
+ * test/lisp/electric-tests.el: Un-skip c-mode tests on hydra.
+
+2021-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix failures in recent files tests
+
+ * test/lisp/files-tests.el (files-tests-buffer-offer-save)
+ (files-tests-save-buffers-kill-emacs--asks-to-save-buffers):
+ `read-event' is called with arguments.
+
+2021-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify cl-defstruct doc string and manual entry somewhat
+
+ * doc/misc/cl.texi (Structures): Rename the slot "name" in the
+ examples to "first-name", since we're talking about the names of
+ slots a lot here, and having a slot with the name "name" makes the
+ examples somewhat confusing.
+ * lisp/emacs-lisp/cl-macs.el (cl-defstruct): Clarify certain
+ things about slots (bug#14278).
+
+2021-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix perldb doc string
+
+ * lisp/progmodes/gud.el (perldb): Fix doc string (bug#14588).
+
+2021-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify dired-jump doc string
+
+ * lisp/dired.el (dired-jump): Make the doc string say what happens
+ in buffers not visiting files (bug#14733).
+
+2021-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak the comment-start-skip example in the manual
+
+ * doc/emacs/programs.texi (Options for Comments): Tweak the
+ example regexp for comment-start-skip (bug#15006).
+
+2021-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify how to do the `count-words-in-defun' recipe
+
+ * doc/lispintro/emacs-lisp-intro.texi (count-words-in-defun):
+ Clarify the recipe (bug#15069).
+
+2021-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make parse-partial-sexp signal an error if TO is smaller than FROM
+
+ * src/syntax.c (Fparse_partial_sexp): Signal an error if TO is
+ smaller than FROM (bug#49944).
+
+2021-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention problems with synthetic fonts on macOS
+
+ * etc/PROBLEMS: Mention synthetic fonts (bug#18818).
+
+2021-08-21 Alan Third <alan@idiocy.org>
+
+ Fix display bug on macOS (bug#50112)
+
+ * src/nsterm.m ([EmacsLayer initWithColorSpace:]): Use the colorspace
+ setter.
+ ([EmacsLayer setColorSpace:]): Sometimes we seem to get null
+ colorspaces, so set a default in this case.
+ ([EmacsLayer getContext]): Check whether there's been a surface or
+ graphics context allocation failure and log it.
+
+2021-08-21 Alan Third <alan@idiocy.org>
+
+ * configure.ac: Make homebrew check for libgccjit match macports.
+
+2021-08-21 Mattias Engdegård <mattiase@acm.org>
+
+ Remove default "Select" title from NS popup menus (bug#50067)
+
+ * src/menu.c (x_popup_menu_1): Remove default "Select" title.
+ * src/nsmenu.m (ns_menu_show): Allow title to be absent.
+
+2021-08-21 Mattias Engdegård <mattiase@acm.org>
+
+ Use overlay arrow to indicate current *xref* selection
+
+ * lisp/progmodes/xref.el (xref--set-arrow): New function.
+ (xref-show-location-at-point, xref-goto-xref)
+ (xref--next-error-function): Call it.
+ (xref--show-common-initialize): Remove arrow.
+
+2021-08-21 Mattias Engdegård <mattiase@acm.org>
+
+ Add "Find References" to context menu (bug#50067)
+
+ The new entry appears next to "Find Definition" and like it only
+ appears when the context menu was invoked on an identifier.
+
+ * lisp/progmodes/prog-mode.el (prog-context-menu): New menu entry.
+ * lisp/progmodes/xref.el (xref-find-references-at-mouse): New
+ function, analogous to `xref-find-definitions-at-mouse`.
+
+2021-08-21 Mattias Engdegård <mattiase@acm.org>
+
+ Indicate progress while searching for references in xref
+
+ * lisp/progmodes/xref.el (xref-backend-references): Add messages to
+ show the user that something is happening instead of silently freezing
+ during the frequently long synchronous searches for references.
+
+2021-08-21 Mattias Engdegård <mattiase@acm.org>
+
+ Re-type the :location slot in `xref-match-item` to `xref-location`
+
+ * lisp/progmodes/xref.el (xref-match-item): Change type for
+ :location from `xref-file-location`, which was likely a mistake,
+ to `xref-location`. This allows `xref-make-match` to take
+ arguments of any subtype of `xref-location` (bug#50067).
+
+2021-08-21 Mattias Engdegård <mattiase@acm.org>
+
+ Add xref operations to context menu unconditionally
+
+ * lisp/progmodes/prog-mode.el (prog-context-menu):
+ Add xref operations to the context menu even if xref hasn't been
+ loaded yet; the functions involved are autoloaded (bug#50067).
+
+2021-08-21 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Move a macro to before its first use in a file.
+
+ * lisp/progmodes/cc-defs.el (c-benign-error): Move earlier in the file for the
+ benefit of c-tnt-chng-cleanup.
+
+2021-08-21 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of context menus
+
+ * doc/lispref/modes.texi (Major Mode Conventions): Add conventions
+ of setting menu-bar menus and context menus for a major mode.
+ * doc/emacs/frames.texi (Menu Mouse Clicks): Fix description of
+ context menu functionality.
+
+2021-08-21 Eli Zaretskii <eliz@gnu.org>
+
+ Improve doc string of 'M-.'
+
+ * lisp/progmodes/xref.el (xref-find-definitions): Mention 'M-,' in
+ the doc string.
+
+2021-08-21 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'file-preserve-symlinks-on-save'
+
+ * lisp/files.el (file-precious-flag): Mention
+ 'file-preserve-symlinks-on-save' in the doc string.
+
+ * doc/lispref/files.texi (Saving Buffers): Move the description of
+ 'file-preserve-symlinks-on-save' from here...
+ * doc/emacs/files.texi (Customize Save): ...to here. Improve
+ wording.
+
+ * etc/NEWS: Fix wording of 'file-preserve-symlinks-on-save' entry.
+
+2021-08-21 Eli Zaretskii <eliz@gnu.org>
+
+ Fix documentation of 'repeat-mode' changes
+
+ * doc/emacs/basic.texi (Repeating): Fix indexing. Improve
+ wording.
+
+2021-08-21 Eli Zaretskii <eliz@gnu.org>
+
+ Fix documentation of recently-added tests for files.el
+
+ * test/lisp/files-tests.el (files-tests--save-some-buffers)
+ (files-tests-save-some-buffers)
+ (files-tests--with-buffer-offer-save)
+ (files-tests-buffer-offer-save): Doc fixes.
+
+2021-08-21 Eli Zaretskii <eliz@gnu.org>
+
+ * etc/TODO: Entry about markers being non-scalable. (Bug#49127)
+
+2021-08-21 Dmitry Gutov <dgutov@yandex.ru>
+
+ Speed up project--read-project-buffer in remote buffers
+
+ * lisp/progmodes/project.el (project-buffers): New generic function.
+ (project--read-project-buffer): Use it here (bug#49264).
+ (project--buffers-to-kill): And here.
+ (project-buffers): Specialized implementation for vc-project.
+
+2021-08-21 Glenn Morris <rgm@gnu.org>
+
+ * lisp/bindings.el (page-navigation-repeat-map): Fix bootstrap.
+
+2021-08-20 Alan Mackenzie <acm@muc.de>
+
+ Fix c-tentative-buffer-changes to be nestable in c-save-buffer-state
+
+ * lisp/progmodes/cc-defs.el (c-tentative-buffer-changes)
+ (c-tnt-chng-record-state, c-tnt-chng-cleanup): Enhance such that a
+ buffer-undo-list of t is handled specially, so that a nil isn't consed onto
+ it. Thus garbage collection can't later remove the (nil . t) from the end of
+ the buffer-undo-list, causing an infinite loop.
+
+2021-08-20 Davide Masserut <dm@mssdvd.com> (tiny change)
+
+ Mark page navigation commands as repeatable
+
+ * doc/emacs/basic.texi (Repeating): Document page navigation
+ repeatability.
+
+ * lisp/bindings.el (page-navigation-repeat-map): Add new map
+ (bug#50137).
+ * lisp/bindings.el (forward-page):
+ (backward-page): Mark as repeatable.
+
+2021-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document how to get rid of completion on `SPC' and `?'
+
+ * doc/emacs/custom.texi (Minibuffer Maps): Mention how to get rid
+ of completion on `SPC' and `?' (bug#16528).
+
+2021-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix printing of C-@ in `describe-fontset'
+
+ * lisp/international/mule-diag.el (mule--kbd-at): New function
+ (bug#17836).
+ (print-fontset-element): Use it to get multi-key things correct.
+
+2021-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow preserving symlinks with file-precious-flag set
+
+ * doc/lispref/files.texi (Saving Buffers): Document it.
+ * lisp/files.el (file-preserve-symlinks-on-save): New user option
+ (bug#18125).
+ (basic-save-buffer-2): Use it.
+
+2021-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix infinite recursion in mode: tex
+
+ * lisp/textmodes/tex-mode.el (tex--redirect-to-submode): Inhibit
+ recursion when called from file-local variables (bug#50126).
+
+2021-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix infinite recursion of conf-mode
+
+ * lisp/textmodes/conf-mode.el (conf-mode): Inhibit recursion when
+ called from file-local variables (bug#50126).
+
+2021-08-20 Marco Centurion <mcenturion@fing.edu.uy> (tiny change)
+
+ Allow copy-directory to copy the source as a symlink
+
+ * doc/emacs/files.texi (Copying and Naming): Document it.
+
+ * lisp/files.el (copy-directory): Allow copying symbolic links as
+ is (bug#10897).
+ (copy-directory-create-symlink): New user option.
+
+2021-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further tweaks to execute-extended-command
+
+ * lisp/simple.el (execute-extended-command): Move finding the
+ short command to the timer command, too (bug#50042). This further
+ ensures that post-command-hook is run faster.
+
+2021-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove even more waiting from execute-extended-command
+
+ * lisp/simple.el (execute-extended-command): Remove all the
+ waiting from the command and do it all with timers (bug#50042).
+ This ensures that post-command-hook is run immediately also when
+ the command has messaged something.
+
+2021-08-20 Mattias Engdegård <mattiase@acm.org>
+
+ Use C-mouse-1 for context menu on NS
+
+ The Mac platform convention is to use control-left-click for context
+ menus (as a synonym to right-click).
+
+ * lisp/mouse.el (context-menu--old-bindings): Remove.
+ (context-menu--saved-bindings)
+ (context-menu--bind-mouse, context-menu--reset-bindings): New.
+ (context-menu-mode): Use new functions, with C-mouse-1 as extra
+ binding on NS.
+
+2021-08-20 Mattias Engdegård <mattiase@acm.org>
+
+ Fix xref {prev,next}-error target buffer match highlighting extent
+
+ * lisp/progmodes/xref.el (xref--next-error-function):
+ Bind `xref--current-item` during the call to `xref--show-location` so
+ that `xref-pulse-momentarily` finds the match extent.
+
+2021-08-20 Mattias Engdegård <mattiase@acm.org>
+
+ Don't mutate string literal
+
+ * lisp/obsolete/terminal.el (terminal-escape-map): Rewrite loop in a
+ simpler and more robust way.
+
+2021-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak a failing custom test
+
+ * test/lisp/custom-tests.el (custom-tests-require-theme): Fix a
+ native-comp-related test failure.
+
+ In this test, we set load-path to nil, and under native-comp some of
+ the tests want to give a warning:
+
+ Warning (comp): Cannot look-up eln file as no source file was
+ found for /tmp/custom-tests-bfdbkW/custom-tests--d.elc
+
+ But we can't load warning.el after setting load-path to nil, so
+ require it first.
+
+2021-08-20 João Távora <joaotavora@gmail.com>
+
+ Make icomplete-forward-completions O(1) when icomplete-scroll is t
+
+ In particular, this makes the recently added
+ icomplete-vertical-goto-last (bug#49005) be O(n) instead of O(n^2).
+ That used to be almost unbearably slow for large n.
+
+ * lisp/icomplete.el (icomplete-forward-completions): don't call last
+ unless needed.
+
+2021-08-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove more mentions of the removed `M-o' facemenu binding
+
+ * doc/emacs/text.texi (Fill Commands, Fill Commands): Adjust `M-o'
+ mentions.
+
+ * etc/refcards/refcard.tex (section{Formatting}):
+ * etc/refcards/pt-br-refcard.tex (section{Formatando}):
+ * etc/refcards/fr-refcard.tex (section{Formater}): Remove mention
+ of `M-o'.
+
+2021-08-19 Madhu <enometh@net.meer> (tiny change)
+
+ Correctly call completion-in-region in shell.el
+
+ * lisp/shell.el (shell-dynamic-complete-command)
+ (shell-dynamic-complete-environment-variable): Correctly call
+ completion-in-region (bug#50125).
+
+2021-08-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix space at the start of appt mode line element
+
+ * lisp/calendar/appt.el (appt-check): Add space at the end
+ (bug#18164) -- all `global-mode-string' elements should have it
+ there to get an even space distribution.
+
+2021-08-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add ibuffer-saved-filter-groups example to the doc string
+
+ * lisp/ibuf-ext.el (ibuffer-saved-filter-groups): Add an example
+ for this complicated syntax (bug#18694).
+
+2021-08-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix dired switch (that contain quotes and spaces) parsing
+
+ * lisp/files.el (insert-directory): Tokenize shell strings
+ correctly (bug#18875).
+
+2021-08-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix st.el doc string
+
+ * lisp/term/st.el (xterm-st-extra-capabilities): New user option
+ (bug#50119).
+ (terminal-init-st): Use it to avoid a two-second timeout.
+
+2021-08-19 Peter Münster <pm@a16n.net>
+
+ Add support for history of image tags and completion in the minibuffer
+
+ * lisp/image-dired.el (image-dired-tag-history): New variable holding the
+ tag history.
+ (image-dired-tag-files, image-dired-tag-thumbnail, image-dired-delete-tag)
+ (image-dired-tag-thumbnail-remove): Use it for the user input.
+
+2021-08-19 Peter Münster <pm@a16n.net>
+
+ Avoid problems when one tag/file is a substring of another
+
+ * lisp/image-dired.el (image-dired-remove-tag): End of filename is bound
+ by ";" and end of tag is bound by ";" or end of line.
+
+2021-08-19 Peter Münster <pm@a16n.net>
+
+ New placement of newline characters in image-dired-db-file
+
+ It's more usual to have the newline at the end of the line, instead of the
+ beginning. This change avoids missing newline at the end of the file, an
+ empty line at the start and eventually a lot of empty lines when
+ `require-final-newline' is not nil.
+
+ * lisp/image-dired.el (image-dired-write-tags): Insert newline at the end
+ of the line, instead of the beginning.
+ (image-dired-remove-tag): Do not delete empty line at end of buffer.
+
+2021-08-19 Peter Münster <pm@a16n.net>
+
+ Fix deletion of associated image
+
+ * lisp/image-dired.el (image-dired-delete-marked): Treat original images
+ first, because point position is used when there are no marked files.
+
+2021-08-19 Eli Zaretskii <eliz@gnu.org>
+
+ Fix inaccuracies in documentation of 'message-truncate-lines'
+
+ * doc/lispref/display.texi (Echo Area Customization):
+ * src/xdisp.c (syms_of_xdisp): Adjust the documentation of
+ message-truncate-lines to changes that fixed bug#46718.
+
+2021-08-19 Eli Zaretskii <eliz@gnu.org>
+
+ Minor doc fixes in icomplete.el
+
+ * lisp/icomplete.el (icomplete-section): Add :version.
+ (icomplete--augment): Doc fix.
+
+2021-08-19 Eli Zaretskii <eliz@gnu.org>
+
+ Fix errors with hscrolling mini-windows under truncate-lines
+
+ * src/xdisp.c (hscroll_window_tree): Disallow hscroll in
+ mini-windows that display echo-area messages. (Bug#50096)
+
+2021-08-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ stterm doesn't understand all codes that xterm does
+
+ * lisp/term/st.el (xterm-st-extra-capabilities): New user option
+ (bug#50119).
+ (terminal-init-st): Use it to avoid a two-second timeout.
+
+2021-08-19 João Távora <joaotavora@gmail.com>
+
+ Section by 'group-function' in Icomplete and Fido's vertical modes
+
+ (Bug#48545)
+
+ * lisp/icomplete.el (icomplete--augment): Rewrite from icomplete--affixate.
+ (icomplete--render-vertical): Rework.
+ (icomplete--vertical-minibuffer-setup): Separator is hardcoded "\n", no
+ need to set.
+
+2021-08-19 João Távora <joaotavora@gmail.com>
+
+ Improve fix of bug#49888 on no-pattern flex sorting
+
+ This version is functionally equivalent, but doesn't duplicate any
+ code. When nothing "flexy" is happening, it works by simply not doing
+ any metadata adjustments, instead of attempting to synthesize a
+ function to mimic the non-flex case.
+
+ * lisp/minibuffer.el (completion--flex-adjust-metadata): Simplify.
+
+2021-08-19 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix vc-root-diff broken with Git as well
+
+ * lisp/vc/vc.el (vc-root-diff): Fix similar to 35023214031e1 by
+ avoiding the abbreviated directory name in argument (bug#39452).
+
+2021-08-18 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'assoc'
+
+ * doc/lispref/lists.texi (Association Lists):
+ * src/fns.c (Fassoc): Document how TESTFN is called. (Bug#50110)
+
+2021-08-18 Juri Linkov <juri@linkov.net>
+
+ Mouse wheel scrolling on the tab bar
+
+ * lisp/tab-bar.el (tab-bar-map): Bind mouse-4/wheel-up/wheel-left
+ to tab-previous and mouse-5/wheel-down/wheel-right to tab-next.
+ Bind S-mouse-4/wheel-up/wheel-left to tab-bar-move-tab-backward
+ and S-mouse-5/wheel-down/wheel-right to tab-bar-move-tab.
+ (tab-bar-move-tab-backward): New command.
+ (tab-bar-move-repeat-map): Use tab-bar-move-tab-backward
+ instead of lambda.
+
+ * src/xterm.c (handle_one_xevent): Remove restriction
+ to allow clicking mouse-4 and mouse-5.
+
+2021-08-18 Juri Linkov <juri@linkov.net>
+
+ Bind [drag-mouse-1] to tab-bar-mouse-move-tab on tab-bar-map
+
+ * lisp/tab-bar.el (tab-bar-mouse-move-tab): New command.
+ (tab-bar-map): Bind [drag-mouse-1] to tab-bar-mouse-move-tab.
+ (tab-bar-select-tab): Zero or nil arg means the current tab.
+
+ * src/xdisp.c (handle_tab_bar_click): Remove restriction
+ to allow dragging the tab to another tab.
+
+2021-08-18 Juri Linkov <juri@linkov.net>
+
+ Redesign tab-bar event processing (bug#41342, bug#41343)
+
+ Instead of emitting menu-item keys like [tab-1],
+ emit normal mouse events like [mouse-1] and [down-mouse-3]
+ for all mouse clicks issued on the tab-bar.
+
+ * lisp/mouse.el (mouse-posn-property): Handle 'tab-bar' posn-area.
+
+ * lisp/tab-bar.el (tab--key-to-number): New internal function.
+ (tab-bar-handle-mouse): Use tab key to select/close tab.
+ (tab-bar-mouse-select-tab, tab-bar-mouse-close-tab)
+ (tab-bar-mouse-context-menu): New commands.
+ (tab-bar-map): Bind [down-mouse-1] to tab-bar-mouse-select-tab,
+ [down-mouse-2] to tab-bar-mouse-close-tab,
+ [down-mouse-3] to tab-bar-mouse-context-menu.
+ (tab-bar-keymap-cache): Remove.
+ (tab-bar-make-keymap): Don't use cache.
+ (tab-bar--format-tab): Remove default bindings from menu items.
+ (tab-bar-make-keymap-1): Prepend tab-bar-map.
+
+ * src/keyboard.c (make_lispy_event): Append event->arg to position
+ for Qtab_bar.
+
+ * src/term.c (handle_one_term_event): Simplify to set event arg.
+
+ * src/w32inevt.c (do_mouse_event): Set emacs_ev->arg to the value
+ returned from tty_handle_tab_bar_click.
+
+ * src/w32term.c (w32_handle_tab_bar_click): Return value from
+ handle_tab_bar_click.
+ (w32_read_socket): Set tab_bar_key to value returned from
+ w32_handle_tab_bar_click, and set event arg from it.
+
+ * src/xdisp.c (handle_tab_bar_click): Instead of emitting event,
+ return a list with Qtab_bar and tab caption with text properties
+ that contain Qmenu_item with key and binding.
+ (tty_handle_tab_bar_click): Simplify to return a list of Qtab_bar,
+ key and close_p, instead of emitting event.
+
+ * src/xterm.c (handle_one_xevent): Set tab_bar_key to value
+ returned from handle_tab_bar_click, and set event arg from it.
+
+2021-08-18 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/xref.el (xref--collect-matches): Widen temporarily.
+
+2021-08-18 Juri Linkov <juri@linkov.net>
+
+ * lisp/mouse.el: More fixes for context-menu.
+
+ (context-menu-map): Remove menu title "Context Menu" (bug#50067).
+ (context-menu-minor): Reverse sub-menus to display exactly in the same order
+ as on the menu bar.
+
+2021-08-18 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of last change.
+
+ * etc/NEWS: Mention the string value of 'auto-composition-mode'.
+
+ * src/composite.c (syms_of_composite) <auto-composition-mode>: Doc
+ fix.
+
+2021-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Disable auto compositions on the Linux console only
+
+ * lisp/term/linux.el (terminal-init-linux): Disable auto
+ compositions on "linux" consoles (bug#21363).
+
+ * src/composite.c (inhibit_auto_composition): New function to
+ implement this.
+ (composition_compute_stop_pos, composition_adjust_point)
+ (Ffind_composition_internal): Use it.
+ (syms_of_composite): Document it.
+
+ * src/lisp.h: Export tty_type_name.
+
+ * src/term.c (tty_type_name): Factored out.
+ (Ftty_type): Use it.
+
+2021-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add undo-in-region test case for bug#21523
+
+2021-08-18 Eli Zaretskii <eliz@gnu.org>
+
+ Yet another place inside redisplay_window to prevent quitting
+
+ * src/xdisp.c (handle_single_display_spec): Inhibit quitting
+ around the call to lookup_image. (Bug#44448)
+
+2021-08-18 Eli Zaretskii <eliz@gnu.org>
+
+ Fix abort when turning on Hebrew or Arabic input methods
+
+ * src/xdisp.c (face_before_or_after_it_pos): Add the missing
+ initialization of the bidi scan direction. (Bug#50107)
+
+2021-08-18 Peter Münster <pm@a16n.net>
+
+ Add menu bindings to new functions in image-dired.el
+
+ * lisp/image-dired.el (image-dired--with-marked): New macro for
+ cycling over marked thumbnails.
+ (image-dired-tag-thumbnail, image-dired-tag-thumbnail-remove): Can
+ handle now also all marked thumbnails.
+ (image-dired-tag-marked-thumbnails): Remove it, because it's
+ obsoleted by `image-dired-tag-thumbnail' now.
+ (image-dired-delete-marked): Use new macro
+ `image-dired--with-marked', and add command to menu (bug#50000).
+
+2021-08-18 pillule <pillule@riseup.net>
+
+ Fix ediff3 layouts with window-combination-resize non-nil (Bug#49277)
+
+ * lisp/vc/ediff-wind.el (ediff-setup-windows-plain-compare)
+ (ediff-setup-windows-multiframe-compare): Fix three windows
+ layouts produced by ediff3 when 'window-combination-resize'
+ was customized to t and 'even-window-sizes' to nil.
+
+2021-08-18 pillule <pillule@riseup.net>
+
+ Fix behavior when switch-to-prev-buffer-skip is a function (Bug#49275)
+
+ * lisp/window.el (switch-to-prev-buffer)
+ (switch-to-next-buffer): More correctly handle cases where
+ 'switch-to-prev-buffer-skip' is a function.
+
+2021-08-17 Andrea Corallo <akrl@sdf.org>
+
+ Fix `native-compile-target-directory' effectiveness for async compilation.
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): Forward to async
+ workers `native-compile-target-directory'.
+
+2021-08-17 Glenn Morris <rgm@gnu.org>
+
+ * lisp/mouse.el (context-menu-filter-function): Fix type.
+
+2021-08-17 Eli Zaretskii <eliz@gnu.org>
+
+ Another fix for quitting while displaying non-selected windows
+
+ * src/xdisp.c (handle_face_prop, extend_face_to_end_of_line):
+ Inhibit quitting around the call to face_at_pos, to prevent
+ leaking wrong value of point when the user quits while we
+ redisplay a non-selected window. (Bug#44448)
+
+2021-08-17 Glenn Morris <rgm@gnu.org>
+
+ * test/lisp/electric-tests.el: Skip most c-mode tests on hydra.
+
+2021-08-17 Eli Zaretskii <eliz@gnu.org>
+
+ Fix TTY display performance degradation due to many markers
+
+ * src/coding.c (encode_coding_object): Don't assume that
+ src_object == dst_object means src_object is the current buffer.
+ Add the missing commentary that explains the arguments.
+ (Bug#49127)
+
+2021-08-17 Michalis V <mvar.40k@gmail.com>
+
+ Improve `forward-sexp' in *Help* buffers
+
+ * lisp/help-mode.el (help-mode-syntax-table): New variable (bug#39134).
+ (help-make-xrefs): Use it to make picking out symbols in curved
+ quotes work reliably.
+ (help-xref-on-pp): Ditto.
+
+2021-08-17 João Távora <joaotavora@gmail.com>
+
+ Bind <up> and <down> in icomplete-vertical-mode
+
+ Suggested by Ergus <spacibba@aol.com>
+
+ * lisp/icomplete.el (icomplete-vertical-mode-minibuffer-map): Bind
+ <up> and <down>
+
+2021-08-17 João Távora <joaotavora@gmail.com>
+ Simon Lang <simon.lang@outlook.com>
+
+ Jump to first,last completion with M-<, M-> in icomplete-vertical-mode
+
+ (Bug#49005)
+
+
+ * lisp/icomplete.el (icomplete-backward-completions): Return
+ non-nil iff something was stepped. Adjust docstring.
+ (icomplete-forward-completions): Adjust docstring.
+ (icomplete-vertical-goto-first, icomplete-vertical-goto-last): New commands.
+ (icomplete-vertical-mode-minibuffer-map): Bind new commands to M-< and M->.
+
+2021-08-17 Juri Linkov <juri@linkov.net>
+
+ Merge branch 'feature/context-menu'
+
+2021-08-17 Dmitry Gutov <dgutov@yandex.ru>
+
+ ruby-mode imenu: Support methods with modifiers
+
+ * lisp/progmodes/ruby-mode.el (ruby-imenu-create-index-in-block):
+ Support methods with modifiers (visibility or otherwise)
+ (bug#50079).
+
+2021-08-17 Dmitry Gutov <dgutov@yandex.ru>
+
+ vc-git-region-history: Fix to call 'diff' more correctly
+
+ * lisp/vc/vc-git.el (vc-git-region-history):
+ Fix to pass a list to the backend 'diff' command (bug#39452).
+
+2021-08-17 João Távora <joaotavora@gmail.com>
+
+ Make icomplete-vertical-mode take immediate effect (bug#49075)
+
+ * etc/NEWS: Mention change.
+
+ * lisp/icomplete.el (icomplete-vertical-mode):
+ (fido-vertical-mode): Tweak docstring. Turn on
+ icomplete-mode. and fido-mdoe
+
+2021-08-16 Glenn Morris <rgm@gnu.org>
+
+ * test/Makefile.in: Verbose logging for electric-tests on hydra.
+
+2021-08-16 Eli Zaretskii <eliz@gnu.org>
+
+ Plug another hole for longjmp-ing from 'redisplay_window'
+
+ * src/fringe.c (update_window_fringes): Inhibit quitting, so as
+ not to longjmp out of redisplay_window. (Bug#44448)
+
+2021-08-16 Stephen Berman <stephen.berman@gmx.net>
+
+ Add Command Modes to Elisp manual menu and add index entries
+
+ * doc/lispref/commands.texi (Command Modes): Add index entries.
+
+ * doc/lispref/elisp.texi (Top): Add entry for the Command Modes
+ node to the detailed node listing.
+
+2021-08-16 Eli Zaretskii <eliz@gnu.org>
+
+ Fix recent documentation additions
+
+ * doc/lispref/searching.texi (Search and Replace): Document the
+ new functions by @defun.
+
+2021-08-16 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 9664ee182c (origin/emacs-27) C++ Mode: Don't confuse the pointer oper...
+ b3aec9ee48 CC Mode: Fix unstable fontification of doc strings.
+
+ # Conflicts:
+ # lisp/progmodes/cc-fonts.el
+
+2021-08-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make overlays-in treat zero-length overlays at point-max consistently
+
+ * doc/lispref/display.texi (Finding Overlays): Adjust documentation.
+
+ * src/buffer.c (overlays_in): Treat the end of the buffer and the
+ end of the narrowed-to buffer the same (bug#19422).
+ (Foverlays_in): Adjust doc string.
+
+2021-08-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix cursor movement on the Linux console with certain characters
+
+ * lisp/term/linux.el (terminal-init-linux): Switch off
+ auto-compositions, because they confuse cursor movement on the
+ Linux console (bug#21363).
+
+2021-08-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Minor clarification for define-minor-mode :variable
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode):
+ * doc/lispref/modes.texi (Defining Minor Modes): Clarify what the
+ setter function should do (bug#14875).
+
+2021-08-16 Clément Pit-Claudel <clement.pitclaudel@live.com>
+
+ Remove prettification for \par in tex-mode
+
+ * lisp/textmodes/tex-mode.el (tex--prettify-symbols-alist): Remove
+ prettified version of `\par'. Many fonts don't display anything for
+ the character it was mapped to (#x2029 PARAGRAPH SEPARATOR), so
+ enabling prettification makes every `\par' disappear (bug#50073).
+
+2021-08-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new functions to replace strings/regexp in a region
+
+ * doc/lispref/searching.texi (Search and Replace): Document them.
+ * lisp/subr.el (replace-string-in-region)
+ (replace-regexp-in-region): New functions.
+
+ * lisp/emacs-lisp/shortdoc.el (regexp, buffer): Mention them.
+
+2021-08-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't remove `fontified' in nxml--buffer-substring-filter
+
+ * lisp/nxml/nxml-mode.el (nxml--buffer-substring-filter): Removing
+ `fontified' is probably unnecessary (bug#50061).
+
+2021-08-16 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix regressions in the last change
+
+ * lisp/vc/vc-git.el (vc-git-register):
+ Use file names verbatim with 'git update-index', as it only accepts
+ file names, not pathspecs (bug#39452).
+
+ * lisp/vc/vc.el (vc-print-root-log):
+ Expand ROOTDIR, so that vc-git-print-log doesn't receive an
+ abbreviated name. Literal pathspecs don't work with those.
+
+2021-08-15 Alan Mackenzie <acm@muc.de>
+
+ C++ Mode: Don't confuse the pointer operator -> with the type indicating ->
+
+ This fixes bug #47468.
+
+ * lisp/progmodes/cc-engine.el (c-looking-at-inexpr-block): While searching
+ backwards for "->" which is a type indicating operator, disallow also commas.
+
+2021-08-15 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Fix unstable fontification of doc strings.
+
+ Also optimize a loop over several line doc-comments.
+
+ * lisp/progmodes/cc-fonts.el (c-font-lock-doc-comments): New variable
+ comment-mid, used as the starting point for applying c-doc-face-name in a
+ line comments. In block comments, apply this face not from `comment-beg' but
+ from `region-beg', no earlier than the start of the fontification region.
+
+2021-08-15 Juri Linkov <juri@linkov.net>
+
+ Use map-keymap in context-menu-global, context-menu-local, context-menu-minor
+
+2021-08-15 Juri Linkov <juri@linkov.net>
+
+ * lisp/simple.el (shift-select-mode): Add new choice 'permanent' (bug#50038).
+
+ (handle-shift-selection): Handle new choice 'permanent'.
+
+2021-08-15 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-new-button-show): Make variable obsolete.
+
+2021-08-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/nxml/nxml-mode.el (nxml-mode): Use add-function
+
+ This avoids calling the internal function `buffer-substring--filter`
+ from `nxml.el`.
+
+ (nxml--buffer-substring-filter): Adjust accordingly.
+
+2021-08-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Filter out rng-state elements in nxml-mode buffers from the kill ring
+
+ * lisp/nxml/nxml-mode.el (nxml--buffer-substring-filter): Filter
+ out `rng-state' objects (bug#50061).
+ (nxml-mode): Set `filter-buffer-substring-function'.
+
+2021-08-15 João Távora <joaotavora@gmail.com>
+
+ Sort by recency in flex completion style when no flexy stuff happening
+
+ (Bug#49888)
+
+ * lisp/minibuffer.el (completion--flex-adjust-metadata): Fall back
+ to usual alphanumeric, length, recency strategy if no minibuffer
+ input. There is still a bug indicated by the nearby FIXMEs,
+ though.
+
+2021-08-15 Augusto Stoffel <arstoffel@gmail.com>
+
+ Allow evaluating Python code across machines
+
+ * lisp/progmodes/python.el (python-shell-send-string): Ensure that
+ the temporary file is created in the host running the Python
+ process (bug#50057).
+
+2021-08-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Run execute-extended-command key binding suggestion from a timer
+
+ * lisp/simple.el (execute-extended-command): Run the key binding
+ suggestion from a timer instead of in the program flow -- this
+ allows `post-command-hook' to be executed immediately (bug#50042).
+
+2021-08-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make Emacs compile with musl instead of glibc
+
+ * src/alloc.c: musl doesn't have malloc_info (bug#50058).
+
+2021-08-15 Eli Zaretskii <eliz@gnu.org>
+
+ Fix unwarranted point movement after C-g
+
+ When the same buffer is displayed in more than one window,
+ redisplay temporarily moves point to the window-point when it
+ works on non-selected windows. If we allow C-g to quit out of
+ redisplay_window in this situation, point will appear to have
+ moved to the window-point of that non-selected window, which is
+ unwarranted. These changes prevent quitting in strategic places,
+ so that we never quit out of redisplay_window.
+ * src/xdisp.c (run_window_scroll_functions):
+ Prevent quitting while running window-scroll-functions, so that we
+ don't quit out of redisplay_window with temporarily moved point.
+ (redisplay_window): While redisplaying the mode line, prevent
+ quitting, to avoid exiting while point is temporarily moved.
+ (decode_mode_spec): Use safe_call1 instead of call1, to trap any
+ errors instead of letting them throw out of redisplay. (Bug#44448)
+
+2021-08-15 Masahiro Nakamura <tsuucat@icloud.com>
+
+ Mark up commands in shortdoc.el for modes
+
+ * lisp/emacs-lisp/shortdoc.el: Add command mode tagging
+ (bug#50064).
+
+2021-08-15 João Távora <joaotavora@gmail.com>
+
+ Fix bug#50063 when using icomplete-fido-kill with C-x p p
+
+ C-x p p utilizes a completion table "category" which is 'project-file'
+ icomplete-fido-kill only functioned for 'buffer' and 'file', and
+ failed with a non-informative message when something else was used.
+
+ * lisp/icomplete.el (icomplete-fido-kill): Support 'project-file'
+ class. Use cl-case, instead of pcase.
+
+2021-08-15 Wolfgang Scherer <wolfgang.scherer@gmx.de>
+
+ Fix vc-git-state for filenames with wildcards
+
+ * lisp/vc/vc-git.el: (vc-git--literal-pathspec-inner),
+ (vc-git--literal-pathspec), (vc-git--literal-pathspecs) new functions
+ to add ":(literal)" pathspec magic (bug#39452).
+
+ (vc-git-registered), (vc-git-state), (vc-git-dir-status-goto-stage),
+ (vc-git-register), (vc-git-unregister), (vc-git-checkin),
+ (vc-git-find-revision), (vc-git-checkout), (vc-git-revert),
+ (vc-git-conflicted-files), (vc-git-print-log), (vc-git-diff),
+ (vc-git-previous-revision), (vc-git-next-revision),
+ (vc-git-delete-file), (vc-git-rename-file) functions
+ vc-git--literal-pathspec, vc-git--literal-pathspecs applied.
+
+2021-08-15 Dmitry Gutov <dgutov@yandex.ru>
+
+ Revert "Bind the GIT_LITERAL_PATHSPECS environment variable"
+
+ This reverts commit a2d0ff26005c5c10ffe0d84bd8b458a06828be82.
+
+ It was found to break a certain use case, and we decided to go with
+ the other solution (bug#39452).
+
+2021-08-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mark auto-revert-test02-auto-revert-deleted-file as unstable
+
+ * test/lisp/autorevert-tests.el
+ (auto-revert-test02-auto-revert-deleted-file): This tests fails
+ about 30% of the time for me.
+
+2021-08-14 Eli Zaretskii <eliz@gnu.org>
+
+ * src/w32.c (_sys_read_ahead): Pacify a silly compiler warning.
+
+2021-08-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/easymenu.el (easy-menu-do-define): Fix bug#50051
+
+ This corrects the quite confused conversion to closure done in
+ commit a070bd1c8b5213ad469d41dd80d392f924644aed.
+
+2021-08-14 Alan Mackenzie <acm@muc.de>
+
+ * lisp/progmodes/cc-engine.el (c-ml-string-in-end-delim): Rewrite function
+
+2021-08-14 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'random' on MS-Windows when integers are wider than 30 bits
+
+ * src/w32.c (random): Provide more random bits for MS-Windows
+ builds with EMACS_INT that is wider than 32 bits. (Bug#32605)
+
+2021-08-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a test for netrc folding parsing (bug#25769)
+
+2021-08-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Filter out -L foo labels in diff-hunk-file-names
+
+ * lisp/vc/diff-mode.el (diff-hunk-file-names): Filter out "-L foo"
+ labels (bug#10160).
+
+2021-08-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Add macro `seq-setq`."
+
+ This reverts commit a8a3fd8f8e27089ac46bf98e534529ff03f679a5.
+
+ The same patch was applied twice. Remove the second instance.
+
+2021-08-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make lm-crack-address less strict
+
+ * lisp/emacs-lisp/lisp-mnt.el (lm-crack-address): Use
+ mail-header-parse-address-lax (bug#50049).
+
+2021-08-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new functions for lax mail address splitting
+
+ * lisp/emacs-lisp/subr-x.el (string-clean-whitespace): Autoload.
+ * lisp/mail/mail-parse.el (mail-header-parse-addresses-lax)
+ (mail-header-parse-address-lax): New functions.
+
+2021-08-14 Earl Hyatt <okamsn@protonmail.com>
+
+ Add macro `seq-setq`.
+
+ * doc/lispref/sequences.texi (seq-setq): Document this macro.
+
+ * test/lisp/emacs-lisp/seq-tests.el (test-seq-setq):
+ Test this macro (bug#50053).
+
+2021-08-14 Earl Hyatt <okamsn@protonmail.com>
+
+ Add macro `seq-setq`.
+
+ * doc/lispref/sequences.texi (seq-setq): Document this macro.
+
+ * lisp/emacs-lisp/seq.el (seq-setq): New macro.
+
+ * test/lisp/emacs-lisp/seq-tests.el (test-seq-setq):
+ Test this macro (bug#50053).
+
+2021-08-14 Yikai Zhao <i@blahgeek.com> (tiny change)
+
+ Fix memory-report counting of vector/hash table sizes
+
+ * lisp/emacs-lisp/memory-report.el (memory-report--object-size-1):
+ Count element values in vectors and hash tables.
+
+2021-08-14 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix merging of ambiguous nil maps
+
+ * lisp/emacs-lisp/map.el: Bump version to 3.1.
+ (map--merge): New merging subroutine that uses a hash table in place
+ of lists, for both efficiency and avoiding ambiguities (bug#49848).
+ (map-merge): Rewrite in terms of map--merge.
+ (map-merge-with): Ditto. This ensures that FUNCTION is called
+ whenever two keys are merged, even if they are not eql (which could
+ happen until now). It also makes map-merge-with consistent with
+ map-merge, thus achieving greater overall predictability.
+ * etc/NEWS: Announce this weakening of guarantees.
+ * test/lisp/emacs-lisp/map-tests.el (test-map-merge)
+ (test-map-merge-with): Don't depend on specific orderings. Test
+ that nil is correctly merged into a plist.
+
+2021-08-14 Mattias Engdegård <mattiase@acm.org>
+
+ Add font-lock-doc-markup-face (bug#50041)
+
+ This face is intended for mark-up syntax and constructs inside text
+ using font-lock-doc-face; ie, documentation comments and strings in
+ programming modes.
+
+ * lisp/font-lock.el (font-lock-doc-markup-face): New face.
+ * lisp/cus-theme.el (custom-theme--listed-faces): Add it to the list.
+ * doc/lispref/modes.texi (Faces for Font Lock): Document it.
+ * etc/NEWS: Mention it.
+
+2021-08-13 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Fix a bug in yesterday's patch
+
+ * lisp/progmodes/cc-mode.el (c-before-change-check-unbalanced-strings): Check
+ the language has multi-line strings before calling
+ c-ml-string-opener-at-or-around-point.
+
+2021-08-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `debug' reset `inhibit-read-only' while running
+
+ * lisp/emacs-lisp/debug.el (debug): Bind `inhibit-read-only' to
+ nil in case we're in a context that has bound it to t (bug#26947).
+
+2021-08-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust previous diff-changed-unspecified change
+
+ * lisp/vc/diff-mode.el (diff-changed-unspecified): Adjust the
+ definition to Emacs 28 (bug#26969).
+
+2021-08-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new face diff-changed-unspecified
+
+ * lisp/vc/diff-mode.el (diff-changed-unspecified): New face.
+ (diff-font-lock-keywords): Use it (bug#26969).
+
+2021-08-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ permanently-enabled-local-variables doc string clarification
+
+ * lisp/files.el (permanently-enabled-local-variables): Clarify
+ what kind of local variables this refers to.
+
+2021-08-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make info-look search harder for the Python info file
+
+ * lisp/info-look.el (python-mode): Try harder to find the correct
+ info file (bug#31405).
+
+2021-08-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem where an error would change standard-output
+
+ * src/keyboard.c (cmd_error): Don't set
+ standard-output/standard-input (bug#30529). Instead bind them
+ temporarily while handling the error.
+
+2021-08-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Unknown line endings in filepos-to-bufferpos/bufferpos-to-linepos
+
+ * lisp/international/mule-util.el (filepos-to-bufferpos): Give
+ better errors on `exact' with unknown line endings, and guess at
+ Unix if `approximate' (bug#36573).
+ (bufferpos-to-filepos): Ditto.
+
+2021-08-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove :group from defcustoms in image-dired.el
+
+ * lisp/image-dired.el: Remove :group from the defcustoms throughout.
+
+2021-08-13 Peter Münster <pm@a16n.net>
+
+ Don't disable transient mark mode when changing image faces
+
+ * lisp/image-dired.el (image-dired-thumb-update-marks): Keep the
+ mark state when changing faces. (bug#49999).
+
+2021-08-13 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-history-buttons-show): Remove defcustom.
+
+ (tab-bar-format-history): Don't use this recently added variable
+ because now it's possible to customize the option 'tab-bar-format'
+ to remove 'tab-bar-format-history' from it that gives the same result.
+
+2021-08-13 Juri Linkov <juri@linkov.net>
+
+ Add save-some-buffers-root to save-some-buffers-default-predicate (bug#46374)
+
+ * lisp/files.el (save-some-buffers-default-predicate): Add choice
+ 'save-some-buffers-root'.
+ (save-some-buffers-root): New predicate function.
+ (save-some-buffers): Check if 'pred' returns a lexically-bound lambda,
+ then use it as 'pred'.
+
+ Thanks to Tino Calancha <tino.calancha@gmail.com>
+
+2021-08-12 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Enhance C++ Mode raw strings to multi-line strings for any language
+
+ * lisp/progmodes/cc-defs.el (cadar, caddr, cdddr): Add defsubsts for these for
+ when they are missing from the host Emacs.
+ (c-point): Add new `position' 'boll "beginning of logical line".
+ (c-clear-char-properties): Return the position of the lowest removed
+ property.
+
+ * lisp/progmodes/cc-engine.el (c-full-pp-to-literal): Fix for rare case where
+ LIMIT < START in parse-partial-sexp.
+ (c-old-beg-rs, c-old-end-rs, c-raw-string-end-delim-disrupted)
+ (c-raw-string-pos, c-raw-string-in-end-delim, c-depropertize-raw-string)
+ (c-depropertize-raw-strings-in-region, c-before-change-check-raw-strings)
+ (c-propertize-raw-string-id, c-propertize-raw-string-opener): Old functions
+ and variables removed or renamed "raw" -> "ml" and adapted.
+ (c-old-beg-ml, c-old-1-beg-ml, c-old-end-ml, c-beg-pos, c-end-pos)
+ (c-ml-string-end-delim-disrupted, c-depropertize-ml-string-delims)
+ (c-ml-string-delims-around-point,c-position-wrt-ml-delims)
+ (c-before-change-check-ml-strings, c-after-change-unmark-ml-strings)
+ (c-maybe-re-mark-ml-string, c-propertize-ml-string-id)
+ (c-propertize-ml-string-opener, c-depropertize-ml-string)
+ (c-depropertize-ml-strings-in-region): New functions and variables adapted and
+ possibly renamed from "raw" -> "ml".
+ (c-ml-string-make-closer-re, c-ml-string-make-opener-re)
+ (c-c++-make-ml-string-closer-re, c-c++-make-ml-string-opener-re)
+ (c-get-ml-closer, c-ml-string-opener-around-point)
+ (c-ml-string-opener-intersects-region, c-ml-string-opener-at-or-around-point)
+ (c-ml-string-back-to-neutral, c-ml-string-in-end-delim, c-neutralize-pos)
+ (c-neutralized-prop): New functions and variables.
+
+ * lisp/progmodes/cc-fonts.el (c-basic-matchers-before): Replace
+ c-font-lock-raw-strings with c-font-lock-ml-strings.
+ (c-font-lock-ml-strings): New function taking the place of the old
+ c-font-lock-ml-strings.
+
+ * lisp/progmodes/cc-langs.el (c-get-state-before-change-functions): Move
+ c-depropertize-CPP to the second item of the C++ entry, and replace
+ c-before-change-check-raw-strings by c-before-change-check-ml-strings. Add a
+ new entry for Pike Mode.
+ (c-before-font-lock-functions): (Replace c-after-change-unmark-raw-strings by
+ c-after-change-unmark-ml-strings in the C++ entry, and add a new entry for
+ Pike Mode.
+ (c-ml-string-backslash-escapes, c-ml-string-non-punc-skip-chars)
+ (c-ml-string-opener-re, c-ml-string-max-opener-len, c-ml-string-any-closer-re)
+ (c-ml-string-max-closer-len, c-ml-string-max-closer-len-no-leader)
+ (c-ml-string-back-closer-re, c-make-ml-string-closer-re-function)
+ (c-make-ml-string-opener-re-function, c-ml-string-cpp-or-opener-re)
+ (c-cpp-or-ml-match-offset): New c-lang-defconsts and c-land-defvars.
+ (c-multiline-string-start-char): Remove the Pike Mode setting.
+
+ * lisp/progmodes/cc-mode.el (c-depropertize-CPP): Test for general ml strings
+ rather than C++ raw strings.
+ (c-unescaped-nls-in-string-p): Handle languages with ml strings.
+ (c-clear-string-fences): Fix bug with wrong parenthesisation.
+ (c-before-change-check-unbalanced-strings)
+ (c-after-change-mark-abnormal-strings, c-after-change-escape-NL-in-string):
+ Adapt for multi-line strings.
+
+2021-08-12 Michael Albinus <michael.albinus@gmx.de>
+
+ Improve connection type `pipe' for remote processes
+
+ * doc/misc/tramp.texi (Remote processes): New subsection "Remote
+ process connection type".
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-make-process):
+ Use `tramp-process-connection-type' as default connection type.
+ Improve check for `:connection-type'.
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process):
+ Use `tramp-process-connection-type' as default connection type.
+ Improve check for `:connection-type'. Send "stty -icrnl" when
+ connection type is a pipe.
+
+ * lisp/net/tramp.el (tramp-process-connection-type): Allow all
+ possible values.
+ (tramp-handle-make-process): Use `tramp-process-connection-type'
+ as default connection type. Improve check for `:connection-type'.
+
+ * test/lisp/net/tramp-tests.el (tramp-test30-make-process): Extend test.
+
+2021-08-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/lisp-mnt.el (lm-crack-address): Handle multi-addresses
+
+ (lm-authors, lm-maintainers): Adjust accordingly.
+
+2021-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make info-look try to use more recent Python manual
+
+ * lisp/info-look.el: Use the Debian-installed python3.9 manual if
+ it exists (bug#31405).
+
+2021-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further tweak minibuffer-inactive-mode doc string
+
+ * lisp/minibuffer.el (minibuffer-inactive-mode): Mention
+ `minibuffer-exit-hook' (bug#13641).
+
+2021-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve minibuffer-inactive-mode documentation
+
+ * lisp/minibuffer.el (minibuffer-inactive-mode): Clarify when it's
+ used (bug#13641).
+
+2021-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention url-handler-mode in the Emacs manual
+
+ * doc/emacs/misc.texi (Browse-URL): Mention url-handler-mode
+ (bug#30389).
+
+ * lisp/url/url-handlers.el (url-handler-mode): Improve doc string.
+
+2021-08-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/pcase.el (pcase-setq): Align its semantics with `pcase-let`
+
+ * test/lisp/emacs-lisp/pcase-tests.el (pcase-tests-setq): Rename from
+ pcase-setq and adjust accordingly.
+
+2021-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add support for Python mode in info-lookup-symbol
+
+ * lisp/info-look.el (:mode): Add support for Python mode
+ (bug#31405).
+
+2021-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify smie-indent-forward-token doc string
+
+ * lisp/emacs-lisp/smie.el (smie-indent-forward-token): Doc string
+ clarification (bug#31948).
+
+2021-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Change the `region' face in the Wombat theme
+
+ * etc/themes/wombat-theme.el (class): Don't use a foreground in
+ the `region' face because it obscures syntax highlighting (bug#32143).
+
+2021-08-12 Omar Polo <op@omarpolo.com>
+
+ Mention `find-ignore-file' in the vc.el commentary
+
+ * lisp/vc/vc.el: Update documentation in the comments about
+ `find-ignore-file' (bug#50013).
+
+2021-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add XLFD font parsing tests
+
+ * test/src/font-tests.el (font-parse-xlfd-test): Add some tests
+ for XLFD testing (bug#35816).
+
+2021-08-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-macs.el (fixnum, bignum): Fix type definitions
+
+2021-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix bytecomp container test case
+
+ * lisp/startup.el (normal-top-level): Make startup more robust --
+ we may not be allowed to create any directories when running under
+ test mode (bug#48350).
+
+2021-08-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/obsolete/cl.el (labels): Don't quote lambda
+
+ (flet): Don't need `fboundp` any more before calling `symbol-function`.
+
+2021-08-11 Earl Hyatt <okamsn@protonmail.com>
+
+ Add a `pcase-setq' macro
+
+ * doc/lispref/control.texi (Destructuring with pcase Patterns):
+ Document this macro.
+
+ * lisp/emacs-lisp/pcase.el (pcase-setq): New macro. This macro is
+ the 'setq' equivalent of 'pcase-let'.
+
+ * test/lisp/emacs-lisp/pcase-tests.el (pcase-setq): Test this new
+ macro. (bug#49809).
+
+2021-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow using a single anonymous face in enriced-mode
+
+ * lisp/format.el (format-annotate-single-property-change): Allow
+ using a single anonymous face (bug#33682).
+
+2021-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow using XLFD font names with dashes in the family name
+
+ * src/font.c (font_parse_xlfd_1): Rename from font_parse_xlfd to
+ allow calling twice from a wrapper (bug#35816).
+ (font_parse_xlfd): Wrapper function -- first try to parse in the
+ normal way, and then try to guess that the hyphenated bits are in
+ the family name.
+
+2021-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow `tex-buffer' to work on buffers not visiting files
+
+ * lisp/textmodes/tex-mode.el (tex-region): Make `tex-buffer' work
+ again on unsaved files (bug#34082).
+
+2021-08-11 Stephen Berman <stephen.berman@gmx.net>
+
+ Fix URL entry in ffap after previous change
+
+ * lisp/ffap.el (ffap-read-file-or-url): Make URL entry actually
+ work again (bug#50011).
+
+2021-08-11 Peter Münster <pm@a16n.net>
+
+ Add new image-dired commands
+
+ * lisp/image-dired.el (image-dired-delete-marked): Factored out
+ (bug#50000).
+ (image-dired-display-thumbs): From here.
+ (image-dired-tag-marked-thumbnails): New command.
+ (image-dired-delete-marked): Ditto.
+
+2021-08-11 Michael Albinus <michael.albinus@gmx.de>
+
+ Replace some `string-match-p' calls in Tramp
+
+ * lisp/net/tramp.el (tramp-debug-message, tramp-set-completion-function)
+ (tramp-get-completion-methods, tramp-get-completion-user-host):
+ * lisp/net/tramp-adb.el (tramp-adb-handle-make-process):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process)
+ (tramp-open-connection-setup-interactive-shell)
+ (tramp-convert-file-attributes): Use `string-prefix-p'.
+
+ * lisp/net/tramp.el (tramp-dissect-file-name)
+ (tramp-progress-reporter-update, tramp-handle-insert-directory):
+ * lisp/net/tramp-cache.el (tramp-get-hash-table)
+ (tramp-flush-directory-properties):
+ * lisp/net/tramp-cmds.el (tramp-append-tramp-buffers):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-insert-directory)
+ (tramp-call-local-coding-command, tramp-get-inline-coding):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-file-attributes)
+ (tramp-smb-handle-file-name-all-completions)
+ (tramp-smb-handle-file-writable-p)
+ (tramp-smb-handle-insert-directory)
+ (tramp-smb-handle-start-file-process, )
+ (tramp-smb-read-file-entry): Use `tramp-compat-string-search'.
+
+2021-08-11 Rajeev Narang <rajeev+jnk@sivalik.com>
+
+ Make icalendar parse multi-line items correctly
+
+ * lisp/calendar/icalendar.el (icalendar--parse-summary-and-rest):
+ Parse multi-line items correctly (bug#37887).
+
+2021-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix icalendar-import-file prompt
+
+ * lisp/calendar/icalendar.el (icalendar-import-file): Fix prompt.
+
+2021-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make gnus-icalendar-event-from-ical more robust
+
+ * lisp/gnus/gnus-icalendar.el (gnus-icalendar-event-from-ical):
+ Don't bug out on nil UIDs.
+
+2021-08-11 Peter Oliver <git@mavit.org.uk>
+
+ Drop redundant keywords in .desktop files.
+
+ The Freedesktop.org Desktop Entry spec says, “The values [of
+ Keywords]… should not be redundant with the values of Name or
+ GenericName”.
+
+ * etc/emacs.desktop, etc/emacsclient.desktop (Keywords): Remove
+ keywords that are duplicated from the GenericName field.
+
+2021-08-11 Peter Oliver <git@mavit.org.uk>
+
+ Hint that emacsclient.desktop should match a search for “emacsclient”
+
+ This is necessary to get the Gnome desktop to show “Emacs (Client)”
+ when the user searches for “emacsclient”.
+
+ * etc/emacsclient.desktop (Keywords):
+ * etc/emacsclient-mail.desktop (Keywords): Add
+ “emacsclient”.
+
+2021-08-11 Peter Oliver <git@mavit.org.uk>
+
+ Valid quoting in .desktop files
+
+ * etc/emacsclient.desktop, etc/emacsclient-mail.desktop (Exec): Quote
+ according to the rules in the Freedesktop.org Desktop Entry
+ Specification.
+
+2021-08-11 Peter Münster <pm@a16n.net>
+
+ Mark marked images in Image-Dired mode
+
+ * lisp/image-dired.el (image-dired-thumb-update-marks): New
+ function that makes the marks visible in the thumbnail buffer
+ (bug#49988).
+ (image-dired-thumb-margin, image-dired-thumb-mark-color): New user
+ options.
+
+2021-08-11 Peter Münster <pm@a16n.net>
+
+ Let image-dired-mouse-toggle-mark act on active region
+
+ * lisp/image-dired.el (image-dired-mouse-toggle-mark): When region is
+ active, then toggle marks of all images within (bug#49987).
+ (image-dired-mouse-toggle-mark-1): Separated out into function.
+
+2021-08-11 Juri Linkov <juri@linkov.net>
+
+ * lisp/replace.el (perform-replace): Use 'remove-function' (bug#49963).
+
+ Don't let-bind the value of 'isearch-filter-predicate' to protect
+ from changing the global value, since with a buffer-local value
+ it still changes the global value. So after using 'add-function' on the
+ global value of 'isearch-filter-predicate', call 'remove-function' to remove
+ 'region-filter' from the global value in 'unwind-protect'.
+
+2021-08-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use ### for outline headings in shell-script-mode
+
+ * lisp/progmodes/sh-script.el (sh-mode): Use ### for outline headings.
+ This aligns it more with emacs-lisp-mode headings.
+
+2021-08-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add support for outlining in shell-script-mode
+
+ * lisp/progmodes/sh-script.el (sh-mode): Set outline-regexp (bug#49346).
+
+2021-08-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new user option `gnus-topic-prepare-topic'
+
+ * doc/misc/gnus.texi (Topic Variables): Document it.
+ * lisp/gnus/gnus-topic.el (gnus-topic-prepare-topic): New user option.
+ (gnus-topic-prepare-topic): Use it.
+
+2021-08-10 Mattias Engdegård <mattiase@acm.org>
+
+ More robust auto-detect of grep-highlight-matches (bug#49978)
+
+ * lisp/progmodes/grep.el (grep-compute-defaults):
+ Don't require "grep --help" to finish with exit status 0 (BSD grep
+ does not) and check the output in a slightly more robust way.
+
+2021-08-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new command `revert-buffer-quick'
+
+ * doc/emacs/files.texi (Reverting): Document it.
+ * lisp/bindings.el (ctl-x-x-map): Bind `C-x x g' to
+ `revert-buffer-quick' instead.
+
+ * lisp/files.el (revert-buffer-quick-short-answers): New user option.
+ (revert-buffer-quick): New command (bug#49869).
+
+2021-08-10 Benjamin Riefenstahl <b.riefenstahl@turtle-trading.net>
+
+ Fix nnrss-get-namespace-prefix (bug#34685)
+
+ * lisp/gnus/nnrss.el (nnrss-get-namespace-prefix): Use the car of
+ parameter el to match what dom-search expects.
+ * test/lisp/gnus/nnrss-tests.el (test-nnrss-xml): Adjust to what
+ xml-parse-region produces (bug#34685).
+
+2021-08-10 Mattias Engdegård <mattiase@acm.org>
+
+ Tramp string-search and string-replace compatibility functions
+
+ Add a `string-search` compatibility function for use in Tramp with
+ Emacs version prior to 28, and fix the existing `string-replace`
+ compatibility function so that it uses the right semantics.
+
+ * lisp/net/tramp-compat.el (tramp-compat-string-replace):
+ Use case-sensitive matching and literal replacement.
+ (tramp-compat-string-search): New function.
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-file-name-all-completions):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-file-name-all-completions)
+ (tramp-do-copy-or-rename-file-out-of-band)
+ (tramp-sh-handle-make-process, tramp-sh-handle-process-file):
+ * lisp/net/tramp.el (tramp-handle-make-process):
+ Use `tramp-compat-string-search` instead of `string-match-p`.
+
+2021-08-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-generic.el: Try and fix bug#49866
+
+ (cl-generic-generalizers): Remember the specializers that match
+ a given value.
+ (cl--generic-eql-generalizer): Adjust accordingly.
+
+ * test/lisp/emacs-lisp/cl-generic-tests.el (cl-generic-test-01-eql):
+ Add corresponding test.
+
+2021-08-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/package.el (package-buffer-info): Fix typo
+
+2021-08-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/package.el (package-buffer-info): Use lm-maintainers
+
+ Avoid the now obsolete `lm-maintainer`.
+
+2021-08-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make ffap-read-file-or-url put point at the correct place for URLs
+
+ * lisp/ffap.el (ffap-read-file-or-url): Put point at the end of
+ URLs (bug#44822).
+ (ffap--url-file-handler): Remove hack for default dirs.
+
+2021-08-09 dickmao <none>
+
+ Forestall "Selected deleted buffer" in url-http-generic-filter
+
+ * lisp/url/url-http.el (url-http-generic-filter): Check that
+ corresponding buffer is still live before using it (bug#49928).
+
+2021-08-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make xterm-set-window-title more robust
+
+ * lisp/term/xterm.el (xterm-set-window-title): Don't do anything
+ on graphic displays (bug#49932).
+
+2021-08-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix tmm-get-keymap under native-compile
+
+ * lisp/tmm.el (tmm-get-keymap): Make this work under
+ natively-compiled Emacsen (and with lexical binding, too) (bug#49953).
+
+2021-08-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further fixes for package-quickstart-refresh printing
+
+ * lisp/emacs-lisp/package.el (package-quickstart-refresh): Really
+ ensure that the structures aren't shortened (bug#49924).
+
+2021-08-09 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix last commit of tramp.el
+
+2021-08-09 Grégoire Jadi <gjadi@omecha.info>
+
+ Fix freeze on OpenBSD when reading the SECONDARY selection
+
+ * configure.ac (NSIG_MINIMUM): OpenBSD doesn't have a broken SIGIO
+ any more (bug#29170). Backport fix from the current OpenBSD port
+ tree.
+
+2021-08-09 Benjamin Riefenstahl <b.riefenstahl@turtle-trading.net>
+
+ Add test for nnrss
+
+ * test/lisp/gnus/nnrss-tests.el (test-nnrss-xml): New test (bug#34685).
+
+2021-08-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new test for dom-search
+
+2021-08-09 Mattias Engdegård <mattiase@acm.org>
+
+ Fix variable binding in calendar (bug#49945)
+
+ * lisp/calendar/cal-tex.el (cal-tex-week-hours, cal-tex-daily-page):
+ Use `let*` instead of `let`.
+
+2021-08-09 Mattias Engdegård <mattiase@acm.org>
+
+ Use string-search instead of string-match[-p]
+
+ `string-search` is easier to understand, less error-prone, much
+ faster, does not pollute the regexp cache, and does not mutate global
+ state. Use it where applicable and obviously safe (erring on the
+ conservative side).
+
+ * admin/authors.el (authors-canonical-file-name)
+ (authors-scan-change-log):
+ * lisp/apropos.el (apropos-command)
+ (apropos-documentation-property, apropos-symbols-internal):
+ * lisp/arc-mode.el (archive-arc-summarize)
+ (archive-zoo-summarize):
+ * lisp/calc/calc-aent.el (math-read-factor):
+ * lisp/calc/calc-ext.el (math-read-big-expr)
+ (math-format-nice-expr, math-format-number-fancy):
+ * lisp/calc/calc-forms.el (math-read-angle-brackets):
+ * lisp/calc/calc-graph.el (calc-graph-set-range):
+ * lisp/calc/calc-keypd.el (calc-keypad-press):
+ * lisp/calc/calc-lang.el (tex, latex, math-read-big-rec):
+ * lisp/calc/calc-prog.el (calc-fix-token-name)
+ (calc-user-define-permanent, math-define-exp):
+ * lisp/calc/calc.el (calc-record, calcDigit-key)
+ (calc-count-lines):
+ * lisp/calc/calcalg2.el (calc-solve-for, calc-poly-roots)
+ (math-do-integral):
+ * lisp/calc/calcalg3.el (calc-find-root, calc-find-minimum)
+ (calc-get-fit-variables):
+ * lisp/cedet/ede/speedbar.el (ede-tag-expand):
+ * lisp/cedet/semantic/java.el (semantic-java-expand-tag):
+ * lisp/cedet/semantic/sb.el (semantic-sb-show-extra)
+ (semantic-sb-expand-group):
+ * lisp/cedet/semantic/wisent/python.el
+ (semantic-python-instance-variable-p):
+ * lisp/cus-edit.el (get):
+ * lisp/descr-text.el (describe-text-sexp):
+ * lisp/dired-aux.el (dired-compress-file):
+ * lisp/dired-x.el (dired-make-relative-symlink):
+ * lisp/dired.el (dired-glob-regexp):
+ * lisp/dos-fns.el (dos-convert-standard-filename, dos-8+3-filename):
+ * lisp/edmacro.el (edmacro-format-keys):
+ * lisp/emacs-lisp/eieio-opt.el (eieio-sb-expand):
+ * lisp/emacs-lisp/eieio-speedbar.el (eieio-speedbar-object-expand):
+ * lisp/emacs-lisp/lisp-mnt.el (lm-keywords-list):
+ * lisp/emacs-lisp/warnings.el (display-warning):
+ * lisp/emulation/viper-ex.el (viper-ex-read-file-name)
+ (ex-print-display-lines):
+ * lisp/env.el (read-envvar-name, setenv):
+ * lisp/epa-mail.el (epa-mail-encrypt):
+ * lisp/epg.el (epg--start):
+ * lisp/erc/erc-backend.el (erc-parse-server-response):
+ * lisp/erc/erc-dcc.el (erc-dcc-member):
+ * lisp/erc/erc-speedbar.el (erc-speedbar-expand-server)
+ (erc-speedbar-expand-channel, erc-speedbar-expand-user):
+ * lisp/erc/erc.el (erc-send-input):
+ * lisp/eshell/em-glob.el (eshell-glob-entries):
+ * lisp/eshell/esh-proc.el (eshell-needs-pipe-p):
+ * lisp/eshell/esh-util.el (eshell-convert):
+ * lisp/eshell/esh-var.el (eshell-envvar-names):
+ * lisp/faces.el (x-resolve-font-name):
+ * lisp/ffap.el (ffap-file-at-point):
+ * lisp/files.el (wildcard-to-regexp, shell-quote-wildcard-pattern):
+ * lisp/forms.el (forms--update):
+ * lisp/frameset.el (frameset-filter-unshelve-param):
+ * lisp/gnus/gnus-art.el (article-decode-charset):
+ * lisp/gnus/gnus-kill.el (gnus-kill-parse-rn-kill-file):
+ * lisp/gnus/gnus-mlspl.el (gnus-group-split-fancy):
+ * lisp/gnus/gnus-msg.el (gnus-summary-resend-message-insert-gcc)
+ (gnus-inews-insert-gcc):
+ * lisp/gnus/gnus-rfc1843.el (rfc1843-decode-article-body):
+ * lisp/gnus/gnus-search.el (gnus-search-indexed-parse-output)
+ (gnus-search--complete-key-data):
+ * lisp/gnus/gnus-spec.el (gnus-parse-simple-format):
+ * lisp/gnus/gnus-sum.el (gnus-summary-refer-article):
+ * lisp/gnus/gnus-util.el (gnus-extract-address-components)
+ (gnus-newsgroup-directory-form):
+ * lisp/gnus/gnus-uu.el (gnus-uu-grab-view):
+ * lisp/gnus/gnus.el (gnus-group-native-p, gnus-short-group-name):
+ * lisp/gnus/message.el (message-check-news-header-syntax)
+ (message-make-message-id, message-user-mail-address)
+ (message-make-fqdn, message-get-reply-headers, message-followup):
+ * lisp/gnus/mm-decode.el (mm-dissect-buffer):
+ * lisp/gnus/nnheader.el (nnheader-insert):
+ * lisp/gnus/nnimap.el (nnimap-process-quirk)
+ (nnimap-imap-ranges-to-gnus-ranges):
+ * lisp/gnus/nnmaildir.el (nnmaildir--ensure-suffix):
+ * lisp/gnus/nnmairix.el (nnmairix-determine-original-group-from-path):
+ * lisp/gnus/nnrss.el (nnrss-match-macro):
+ * lisp/gnus/nntp.el (nntp-find-group-and-number):
+ * lisp/help-fns.el (help--symbol-completion-table-affixation):
+ * lisp/help.el (help-function-arglist):
+ * lisp/hippie-exp.el (he-concat-directory-file-name):
+ * lisp/htmlfontify.el (hfy-relstub):
+ * lisp/ido.el (ido-make-prompt, ido-complete, ido-copy-current-word)
+ (ido-exhibit):
+ * lisp/image/image-converter.el (image-convert-p):
+ * lisp/info-xref.el (info-xref-docstrings):
+ * lisp/info.el (Info-toc-build, Info-follow-reference)
+ (Info-backward-node, Info-finder-find-node)
+ (Info-speedbar-expand-node):
+ * lisp/international/mule-diag.el (print-fontset-element):
+ * lisp/language/korea-util.el (default-korean-keyboard):
+ * lisp/linum.el (linum-after-change):
+ * lisp/mail/ietf-drums.el (ietf-drums-parse-address):
+ * lisp/mail/mail-utils.el (mail-dont-reply-to):
+ * lisp/mail/rfc2047.el (rfc2047-encode-1, rfc2047-decode-string):
+ * lisp/mail/rfc2231.el (rfc2231-parse-string):
+ * lisp/mail/rmailkwd.el (rmail-set-label):
+ * lisp/mail/rmailsum.el (rmail-header-summary):
+ * lisp/mail/smtpmail.el (smtpmail-maybe-append-domain)
+ (smtpmail-user-mail-address):
+ * lisp/mail/uce.el (uce-reply-to-uce):
+ * lisp/man.el (Man-default-man-entry):
+ * lisp/mh-e/mh-alias.el (mh-alias-gecos-name)
+ (mh-alias-minibuffer-confirm-address):
+ * lisp/mh-e/mh-comp.el (mh-forwarded-letter-subject):
+ * lisp/mh-e/mh-speed.el (mh-speed-parse-flists-output):
+ * lisp/mh-e/mh-utils.el (mh-collect-folder-names-filter)
+ (mh-folder-completion-function):
+ * lisp/minibuffer.el (completion--make-envvar-table)
+ (completion-file-name-table, completion-flex-try-completion)
+ (completion-flex-all-completions):
+ * lisp/mpc.el (mpc--proc-quote-string, mpc-cmd-special-tag-p)
+ (mpc-constraints-tag-lookup):
+ * lisp/net/ange-ftp.el (ange-ftp-send-cmd)
+ (ange-ftp-allow-child-lookup):
+ * lisp/net/mailcap.el (mailcap-mime-types):
+ * lisp/net/mairix.el (mairix-search-thread-this-article):
+ * lisp/net/pop3.el (pop3-open-server):
+ * lisp/net/soap-client.el (soap-decode-xs-complex-type):
+ * lisp/net/socks.el (socks-filter):
+ * lisp/nxml/nxml-outln.el (nxml-highlighted-qname):
+ * lisp/nxml/rng-cmpct.el (rng-c-expand-name, rng-c-expand-datatype):
+ * lisp/nxml/rng-uri.el (rng-uri-file-name-1):
+ * lisp/obsolete/complete.el (partial-completion-mode)
+ (PC-do-completion):
+ * lisp/obsolete/longlines.el (longlines-encode-string):
+ * lisp/obsolete/nnir.el (nnir-compose-result):
+ * lisp/obsolete/terminal.el (te-quote-arg-for-sh):
+ * lisp/obsolete/tpu-edt.el (tpu-check-search-case):
+ * lisp/obsolete/url-ns.el (isPlainHostName):
+ * lisp/pcmpl-unix.el (pcomplete/scp):
+ * lisp/play/dunnet.el (dun-listify-string2, dun-get-path)
+ (dun-unix-parse, dun-doassign, dun-cat, dun-batch-unix-interface):
+ * lisp/progmodes/ebnf2ps.el: (ebnf-eps-header-footer-comment):
+ * lisp/progmodes/gdb-mi.el (gdb-var-delete)
+ (gdb-speedbar-expand-node, gdbmi-bnf-incomplete-record-result):
+ * lisp/progmodes/gud.el (gud-find-expr):
+ * lisp/progmodes/idlw-help.el (idlwave-do-context-help1):
+ * lisp/progmodes/idlw-shell.el (idlwave-shell-mode)
+ (idlwave-shell-filter-hidden-output, idlwave-shell-filter):
+ * lisp/progmodes/idlwave.el (idlwave-skip-label-or-case)
+ (idlwave-routine-info):
+ * lisp/progmodes/octave.el (inferior-octave-completion-at-point):
+ * lisp/progmodes/sh-script.el (sh-add-completer):
+ * lisp/progmodes/sql.el (defun):
+ * lisp/progmodes/xscheme.el (xscheme-process-filter):
+ * lisp/replace.el (query-replace-compile-replacement)
+ (map-query-replace-regexp):
+ * lisp/shell.el (shell--command-completion-data)
+ (shell-environment-variable-completion):
+ * lisp/simple.el (display-message-or-buffer):
+ * lisp/speedbar.el (speedbar-dired, speedbar-tag-file)
+ (speedbar-tag-expand):
+ * lisp/subr.el (split-string-and-unquote):
+ * lisp/tar-mode.el (tar-extract):
+ * lisp/term.el (term-command-hook, serial-read-name):
+ * lisp/textmodes/bibtex.el (bibtex-print-help-message):
+ * lisp/textmodes/ispell.el (ispell-lookup-words, ispell-filter)
+ (ispell-parse-output, ispell-buffer-local-parsing):
+ * lisp/textmodes/reftex-cite.el (reftex-do-citation):
+ * lisp/textmodes/reftex-parse.el (reftex-notice-new):
+ * lisp/textmodes/reftex-ref.el (reftex-show-entry):
+ * lisp/textmodes/reftex.el (reftex-compile-variables):
+ * lisp/textmodes/tex-mode.el (tex-send-command)
+ (tex-start-tex, tex-append):
+ * lisp/thingatpt.el (thing-at-point-url-at-point):
+ * lisp/tmm.el (tmm-add-one-shortcut):
+ * lisp/transient.el (transient-format-key):
+ * lisp/url/url-auth.el (url-basic-auth)
+ (url-digest-auth-directory-id-assoc):
+ * lisp/url/url-news.el (url-news):
+ * lisp/url/url-util.el (url-parse-query-string):
+ * lisp/vc/vc-cvs.el (vc-cvs-parse-entry):
+ * lisp/wid-browse.el (widget-browse-sexp):
+ * lisp/woman.el (woman-parse-colon-path, woman-mini-help)
+ (WoMan-getpage-in-background, woman-negative-vertical-space):
+ * lisp/xml.el:
+ * test/lisp/emacs-lisp/check-declare-tests.el
+ (check-declare-tests-warn):
+ * test/lisp/files-tests.el
+ (files-tests-file-name-non-special-dired-compress-handler):
+ * test/lisp/net/network-stream-tests.el (server-process-filter):
+ * test/src/coding-tests.el (ert-test-unibyte-buffer-dos-eol-decode):
+ Use `string-search` instead of `string-match` and `string-match-p`.
+
+2021-08-08 Alan Third <alan@idiocy.org>
+
+ * src/nsterm.m (max_used_fringe_bitmap): Remove unused variable.
+
+2021-08-08 Tassilo Horn <tsdh@gnu.org>
+
+ Un-obsolete dired-in-this-tree-p and use it again in certain places.
+
+ This reverts parts of b425966b07, and 7b50ed553f, i.e. it reverts the
+ obsoletion of dired-in-this-tree-p and switches some new callers of
+ file-in-directory-p back to using dired-in-this-tree-p.
+
+ It turned out that using file-in-directory-p can be a major
+ performance regression in case you have a dired buffer of a remote
+ directory which has become (almost) inaccessible.
+
+ Any attempt to open a new dired buffer is checking if a buffer for
+ that directory already exists (in terms of dired-buffers-for-dir)
+ which meant that file-in-directory-p was called with the directory of
+ any existing dired buffer including the inaccessible one where the
+ file-truename call in file-in-directory-p could block for seconds or
+ even minutes.
+
+ * lisp/dired.el (dired-in-this-tree-p): Undo obsoletion.
+ (dired-buffers-for-dir): Use dired-in-this-tree-p as before.
+ * lisp/dired-aux.el (dired-kill-tree,dired-tree-down): Une
+ dired-in-this-tree-p as before.
+
+2021-08-08 Mattias Engdegård <mattiase@acm.org>
+
+ Use string-replace instead of replace-regexp-in-string
+
+ `string-replace` is easier to understand, less error-prone, much
+ faster, and results in shorter Lisp and byte code. Use it where
+ applicable and obviously safe (erring on the conservative side).
+
+ * admin/authors.el (authors-scan-change-log):
+ * lisp/autoinsert.el (auto-insert-alist):
+ * lisp/calc/calc-prog.el (calc-edit-macro-combine-alg-ent)
+ (calc-edit-macro-combine-ext-command)
+ (calc-edit-macro-combine-var-name):
+ * lisp/calc/calc-units.el (math-make-unit-string):
+ * lisp/calendar/cal-html.el (cal-html-comment):
+ * lisp/calendar/cal-tex.el (cal-tex-comment):
+ * lisp/calendar/icalendar.el (icalendar--convert-string-for-export)
+ (icalendar--convert-string-for-import):
+ * lisp/calendar/iso8601.el (iso8601--concat-regexps)
+ (iso8601--full-time-match, iso8601--combined-match):
+ * lisp/calendar/time-date.el (format-seconds):
+ * lisp/calendar/todo-mode.el (todo-filter-items-filename):
+ * lisp/cedet/cedet-files.el (cedet-directory-name-to-file-name)
+ (cedet-file-name-to-directory-name):
+ * lisp/comint.el (comint-watch-for-password-prompt):
+ * lisp/dired-aux.el (dired-do-chmod):
+ * lisp/dired-x.el (dired-man):
+ * lisp/dired.el (dired-insert-directory, dired-goto-file-1):
+ * lisp/emacs-lisp/comp.el (comp-c-func-name):
+ * lisp/emacs-lisp/re-builder.el (reb-copy):
+ * lisp/erc/erc-dcc.el (erc-dcc-unquote-filename):
+ * lisp/erc/erc.el (erc-quit-reason-zippy, erc-part-reason-zippy)
+ (erc-update-mode-line-buffer, erc-message-english-PART):
+ * lisp/files.el (make-backup-file-name-1, files--transform-file-name)
+ (read-file-modes):
+ * lisp/fringe.el (fringe-mode):
+ * lisp/gnus/gnus-art.el (gnus-button-handle-info-url):
+ * lisp/gnus/gnus-group.el (gnus-group-completing-read):
+ * lisp/gnus/gnus-icalendar.el (gnus-icalendar-event-from-ical):
+ * lisp/gnus/gnus-mlspl.el (gnus-group-split-fancy):
+ * lisp/gnus/gnus-search.el (gnus-search-query-parse-date)
+ (gnus-search-transform-expression, gnus-search-run-search):
+ * lisp/gnus/gnus-start.el (gnus-dribble-enter):
+ * lisp/gnus/gnus-sum.el (gnus-summary-refer-article):
+ * lisp/gnus/gnus-util.el (gnus-mode-string-quote):
+ * lisp/gnus/message.el (message-put-addresses-in-ecomplete)
+ (message-parse-mailto-url, message-mailto-1):
+ * lisp/gnus/mml-sec.el (mml-secure-epg-sign):
+ * lisp/gnus/mml-smime.el (mml-smime-epg-verify):
+ * lisp/gnus/mml2015.el (mml2015-epg-verify):
+ * lisp/gnus/nnmaildir.el (nnmaildir--system-name)
+ (nnmaildir-request-list, nnmaildir-retrieve-groups)
+ (nnmaildir-request-group, nnmaildir-retrieve-headers):
+ * lisp/gnus/nnrss.el (nnrss-node-text):
+ * lisp/gnus/spam-report.el (spam-report-gmane-internal)
+ (spam-report-user-mail-address):
+ * lisp/ibuffer.el (name):
+ * lisp/image-dired.el (image-dired-pngnq-thumb)
+ (image-dired-pngcrush-thumb, image-dired-optipng-thumb)
+ (image-dired-create-thumb-1):
+ * lisp/info.el (Info-set-mode-line):
+ * lisp/international/mule-cmds.el (describe-language-environment):
+ * lisp/mail/rfc2231.el (rfc2231-parse-string):
+ * lisp/mail/rfc2368.el (rfc2368-parse-mailto-url):
+ * lisp/mail/rmail.el (rmail-insert-inbox-text)
+ (rmail-simplified-subject-regexp):
+ * lisp/mail/rmailout.el (rmail-output-body-to-file):
+ * lisp/mail/undigest.el (rmail-digest-rfc1153):
+ * lisp/man.el (Man-default-man-entry):
+ * lisp/mouse.el (minor-mode-menu-from-indicator):
+ * lisp/mpc.el (mpc--debug):
+ * lisp/net/browse-url.el (browse-url-mail):
+ * lisp/net/eww.el (eww-update-header-line-format):
+ * lisp/net/newst-backend.el (newsticker-save-item):
+ * lisp/net/rcirc.el (rcirc-sentinel):
+ * lisp/net/soap-client.el (soap-decode-date-time):
+ * lisp/nxml/rng-cmpct.el (rng-c-literal-2-re):
+ * lisp/nxml/xmltok.el (let*):
+ * lisp/obsolete/nnir.el (nnir-run-swish-e, nnir-run-hyrex)
+ (nnir-run-find-grep):
+ * lisp/play/dunnet.el (dun-doassign):
+ * lisp/play/handwrite.el (handwrite):
+ * lisp/proced.el (proced-format-args):
+ * lisp/profiler.el (profiler-report-header-line-format):
+ * lisp/progmodes/gdb-mi.el (gdb-mi-quote):
+ * lisp/progmodes/make-mode.el (makefile-bsdmake-rule-action-regex)
+ (makefile-make-font-lock-keywords):
+ * lisp/progmodes/prolog.el (prolog-guess-fill-prefix):
+ * lisp/progmodes/ruby-mode.el (ruby-toggle-string-quotes):
+ * lisp/progmodes/sql.el (sql-remove-tabs-filter, sql-str-literal):
+ * lisp/progmodes/which-func.el (which-func-current):
+ * lisp/replace.el (query-replace-read-from)
+ (occur-engine, replace-quote):
+ * lisp/select.el (xselect--encode-string):
+ * lisp/ses.el (ses-export-tab):
+ * lisp/subr.el (shell-quote-argument):
+ * lisp/term/pc-win.el (msdos-show-help):
+ * lisp/term/w32-win.el (w32--set-selection):
+ * lisp/term/xterm.el (gui-backend-set-selection):
+ * lisp/textmodes/picture.el (picture-tab-search):
+ * lisp/thumbs.el (thumbs-call-setroot-command):
+ * lisp/tooltip.el (tooltip-show-help-non-mode):
+ * lisp/transient.el (transient-format-key):
+ * lisp/url/url-mailto.el (url-mailto):
+ * lisp/vc/log-edit.el (log-edit-changelog-ours-p):
+ * lisp/vc/vc-bzr.el (vc-bzr-status):
+ * lisp/vc/vc-hg.el (vc-hg--glob-to-pcre):
+ * lisp/vc/vc-svn.el (vc-svn-after-dir-status):
+ * lisp/xdg.el (xdg-desktop-strings):
+ * test/lisp/electric-tests.el (defun):
+ * test/lisp/term-tests.el (term-simple-lines):
+ * test/lisp/time-stamp-tests.el (formatz-mod-del-colons):
+ * test/lisp/wdired-tests.el (wdired-test-bug32173-01)
+ (wdired-test-unfinished-edit-01):
+ * test/src/json-tests.el (json-parse-with-custom-null-and-false-objects):
+ Use `string-replace` instead of `replace-regexp-in-string`.
+
+2021-08-08 Eli Zaretskii <eliz@gnu.org>
+
+ Another fix for parse-colon-path
+
+ * test/lisp/files-tests.el (files-tests-bug-21454, files-colon-path):
+ Adapt to change in behavior of 'parse-colon-path'.
+
+ * lisp/files.el (parse-colon-path): Don't expand the directory
+ names: that changes the names in ways this function is not
+ supposed to. (Bug#49918)
+
+2021-08-08 Michael Albinus <michael.albinus@gmx.de>
+
+ Doc update wrt Tramp support of SSH security keys
+
+ * doc/misc/tramp.texi (Frequently Asked Questions): Speak about
+ SSH security keys.
+ (GVFS-based methods, Predefined connection information)
+ (Remote shell setup): Fix typo.
+
+ * etc/NEWS: Precise Tramp's support for SSH security keys. Fix typos.
+
+2021-08-08 Dmitry Gutov <dgutov@yandex.ru>
+
+ project.el: Bump the version
+
+ * lisp/progmodes/project.el: Bump the version.
+
+2021-08-07 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Further fix to filtering Gnus search group names
+
+ * lisp/gnus/gnus-search.el (gnus-search-indexed-parse-output): Group
+ names in the GROUPS argument may be prefixed or not, depending on
+ which server we're searching, so always enforce prefix policy within
+ the function.
+
+2021-08-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix files-tests broken on MS-Windows by a recent change
+
+ * test/lisp/files-tests.el (files-colon-path): Use path-separator, and
+ account for drive letters in absolute file names on MS-Windows. (Bug#49918)
+
+2021-08-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix prin1 problem in package-quickstart-refresh
+
+ * lisp/emacs-lisp/package.el (package-quickstart-refresh): Bind
+ print-length/print-level before using prin1-to-string (bug#49924).
+
+2021-08-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix print-length issue in comp-run-async-workers
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): Bind
+ print-length/print-level to ensure there's no truncation (bug#49922).
+
+2021-08-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `q' in `org-agenda' work even with `debug-on-error' set
+
+ * lisp/org/org-agenda.el (org-agenda-get-restriction-and-command):
+ Using `error' here will trigger users with `debug-on-error' so use
+ `user-error' instead (bug#49920). It would probably be preferable
+ to rewrite this to not use the error system to do control flow.
+
+2021-08-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with relative directories in CDPATH
+
+ * lisp/files.el (parse-colon-path): Allow relative directories
+ (like ".") in CDPATH (bug#49918).
+
+2021-08-07 Tomasz Konojacki <me@xenu.pl> (tiny change)
+
+ perl-mode: fix variable fontification
+
+ * lisp/progmodes/perl-mode.el: Handle variables first to avoid
+ conflicting with keywords. This fixes cases like "$package"
+ (bug#49906).
+
+2021-08-07 Lars Ingebrigtsen <larsi@emkay.local>
+
+ Allow building on MacOS with MacPorts and libgccjit
+
+ * configure.ac: Check for the "port" command (MacPorts).
+ Add the required lib/include directories for nativecomp.
+
+ * src/Makefile.in (LIBGCCJIT_CFLAGS, LIBGCCJIT_LIBS): Split into
+ two parts to allow including -L/-I for MacPorts.
+ (LIBES): Adjust.
+ (EMACS_CFLAGS): Ditto.
+
+2021-08-06 Philip Kaludercic <philipk@posteo.net>
+
+ Add new option rcirc-channel-filter
+
+ * lisp/net/rcirc.el (rcirc-channel-filter): Add option
+ (rcirc-short-buffer-name): Respect rcirc-channel-filter
+ (rcirc-handler-JOIN): Respect rcirc-channel-filter
+ (rcirc-handler-PART): Respect rcirc-channel-filter
+ (rcirc-handler-KICK): Respect rcirc-channel-filter
+ (rcirc-handler-QUIT): Respect rcirc-channel-filter
+ (rcirc-handler-INVITE): Respect rcirc-channel-filter
+
+2021-08-06 Philip Kaludercic <philipk@posteo.net>
+
+ Add new option rcirc-track-abbrevate-flag
+
+ * lisp/net/rcirc.el (rcirc-track-abbrevate-flag): Add option
+ (rcirc-short-buffer-name): Respect rcirc-track-abbrevate-flag
+
+2021-08-06 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ b77f6af24e (origin/emacs-27) ERC right stamps: also use latest buffer...
+
+ # Conflicts:
+ # lisp/erc/erc-stamp.el
+
+2021-08-06 dickmao <none>
+
+ Improve ffap-ido-mode test
+
+ * test/lisp/ffap-tests.el (ffap-ido-mode): Actually test
+ `ido-everywhere' at run time, not compile time (bug#49895).
+
+2021-08-06 dick r. chiang <dick.r.chiang@gmail.com>
+
+ Fix problem with occasional stalls in `url-retrieve-synchronously'
+
+ * lisp/url/url.el (url-retrieve-synchronously): Use
+ `accept-process-output' on a null process. That is the safer, more
+ conventional way of achieving non-blocking sleep-for (bug#49897).
+
+ Also rewrite for greater readability.
+
+2021-08-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention NonGNU in "Package Archives" node in the manual
+
+ * doc/lispref/package.texi (Package Archives): Mention NonGNU, too
+ (bug#49899).
+
+2021-08-06 Dmitry Gutov <dgutov@yandex.ru>
+
+ Add colon-space after prompt
+
+ * lisp/progmodes/project.el (project--completing-read-strict):
+ Fix last change's regression (bug#49865).
+
+2021-08-06 Eli Zaretskii <eliz@gnu.org>
+
+ Fix automatic hscrolling when line numbers are displayed
+
+ * src/xdisp.c (hscroll_window_tree): When line numbers are
+ displayed, account for the the line-number space when calculating
+ the desired X coordinate on the left. (Bug#49891)
+
+2021-08-06 Eli Zaretskii <eliz@gnu.org>
+
+ Improve wording of recently changed documentation
+
+ * src/minibuf.c (syms_of_minibuf):
+ * lisp/minibuffer.el (minibuffer-restore-windows):
+ * lisp/progmodes/etags.el (etags-xref-prefer-current-file):
+ Improve wording of doc strings.
+
+ * etc/NEWS: Improve wording and format of recently added entries.
+
+2021-08-06 Eli Zaretskii <eliz@gnu.org>
+
+ Make sure installed *.eln files have correct permissions
+
+ * Makefile.in (install-eln): Add "umask 022" to ensure the *.eln
+ files are accessible from the user's Emacs session. Suggested by
+ Wilhelm Kirschbaum <wkirschbaum@gmail.com>. (Bug#49864)
+
+2021-08-06 Olivier Certner <olce.emacs@certner.fr>
+
+ ERC right stamps: also use latest buffer's window's width (Bug#44140)
+
+ * lisp/erc/erc-stamp.el (erc-insert-timestamp-right): Use latest
+ buffer's window's width to position the timestamp, if both
+ `erc-timestamp-right-column' and `erc-fill-column' are not set (or
+ `erc-fill-mode' is off). This is what the documentation says, but was
+ not implemented. Also fix the bug of using selected window's width
+ instead of the (or some) window showing the buffer. The latest
+ window's width is saved in `erc-timestamp-last-window-width' and used
+ when the buffer is no more shown. In case the buffer was never shown,
+ which I'm not sure can happen, either use `fill-column' if set, or
+ give up on aligning and just output the timestamp (modulo the kludge)
+ right after message text. While here, fix the off by one calculation
+ of point start when the reference is the window's width.
+
+2021-08-06 Dmitry Gutov <dgutov@yandex.ru>
+
+ Change how project-find-file's completion works
+
+ * lisp/progmodes/project.el (project--completing-read-strict):
+ Allow to choose a non-existent file, with confirmation
+ (bug#49204).
+ Don't use the string at point as a "real" default, and instead
+ only include it in "future history": meaning, it will be inserted
+ on 'M-n' (bug#49865).
+
+2021-08-06 Dmitry Gutov <dgutov@yandex.ru>
+
+ New option etags-xref-prefer-current-file
+
+ * lisp/progmodes/etags.el (etags-xref-prefer-current-file):
+ New user option (bug#2544).
+ (xref-backend-definitions): Use it.
+
+2021-08-06 Dmitry Gutov <dgutov@yandex.ru>
+
+ Provide a default for xref-find-apropos pattern
+
+ * lisp/progmodes/xref.el (xref-find-apropos):
+ Provide a default for the pattern (bug#49731).
+
+2021-08-06 Dmitry Gutov <dgutov@yandex.ru>
+
+ Change the xref-goto-xref error message
+
+ * lisp/progmodes/xref.el (xref-goto-xref):
+ Change the error message (bug#49846).
+
+2021-08-06 Juri Linkov <juri@linkov.net>
+
+ Add function minibuffer-restore-windows (bug#45072)
+
+ * lisp/minibuffer.el (minibuffer-restore-windows): New function
+ that removes the completions buffer. Add it to minibuffer-exit-hook.
+ * src/minibuf.c (read-minibuffer-restore-windows): Mention
+ minibuffer-restore-windows.
+
+2021-08-05 Konstantin Kharlamov <Hi-Angel@yandex.ru>
+
+ Reset mtime of a buffer reverted "delicately"
+
+ * lisp/files.el (revert-buffer-insert-file-contents-delicately):
+ Once buffer is reverted, reset its mtime to that of the file.
+ (Bug#49893)
+
+2021-08-05 Eli Zaretskii <eliz@gnu.org>
+
+ Fix files-tests on non-Posix systems
+
+ * test/lisp/files-tests.el (files-test-auto-save-name-default)
+ (files-test-auto-save-name-transform)
+ (files-test-auto-save-name-unique, files-test-lock-name-default)
+ (files-test-lock-name-unique): Skip the drive letter in absolute
+ file names on MS-Windows/MS-DOS when comparing file names against
+ the expected ones.
+ (files-tests-file-name-non-special--subprocess): Skip test on
+ MS-Windows/MS-DOS.
+
+2021-08-05 Mattias Engdegård <mattiase@acm.org>
+
+ Cease attempts to const-propagate through setq
+
+ The current method of propagating constants through setq was unsound
+ because it relied on each setq form only being traversed at most once
+ during optimisation, which isn't necessarily true in general; it could
+ be made to miscompile code in rare cases.
+
+ Since it was only used in limited circumstances, disabling this
+ optimisation doesn't cost us much.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker):
+ Don't update the known value when traversing `setq`.
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases):
+ Add test case.
+
+2021-08-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix M-n description in refcards
+
+ * etc/refcards/pl-refcard.tex (section{Szukanie przyrostowe}):
+ Ditto (in comments).
+
+ * etc/refcards/refcard.tex (section{Incremental Search}): Fix M-n
+ description (bug#49872).
+
+2021-08-05 Roland Winkler <winkler@gnu.org>
+
+ Add support for the oauth2.el library in nnimap and smtpmail
+
+ * doc/misc/gnus.texi (Customizing the IMAP Connection):
+ * doc/misc/smtpmail.texi (Authentication): Mention it.
+
+ * lisp/gnus/nnimap.el (nnimap-login): Support oauth2.
+
+ * lisp/mail/smtpmail.el (smtpmail-try-auth-method): New function
+ for oauth2.
+
+2021-08-05 Glenn Morris <rgm@gnu.org>
+
+ * lisp/cus-start.el (read-minibuffer-restore-windows): Fix entry.
+
+2021-08-04 Juri Linkov <juri@linkov.net>
+
+ * lisp/vc/smerge-mode.el (smerge-mode-menu): Add menu item for smerge-refine.
+
+2021-08-04 dickmao <none>
+
+ Package archive location needs to be absolute filename
+
+ * lisp/emacs-lisp/package.el (package--with-response-buffer-1):
+ Actually check that URL is absolute (bug#49788).
+
+2021-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new thing-at-point type: existing-filename
+
+ * doc/lispref/text.texi (Buffer Contents): Mention it.
+
+ * lisp/thingatpt.el (thing-at-point-file-at-point): New function.
+ (existing-filename): Register it.
+
+2021-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `M-j' work reliably if `comment-auto-fill-only-comments' is set
+
+ * lisp/simple.el (default-indent-new-line): Force breaking the
+ line when called interactively (bug#49849). (Perhaps the
+ interactive command should be rebound and call this function
+ instead...)
+
+2021-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve `define-globalized-minor-mode' doc strings
+
+ * lisp/emacs-lisp/easy-mmode.el (define-globalized-minor-mode):
+ Copy the description from easy-mmode--arg-docstring (bug#49843).
+
+2021-08-04 dickmao <none>
+
+ ffap ido accommodation
+
+ Now that ffap-file-finder can be ido-find-file, the
+ noninteractive portion of find-file-at-point cannot
+ assume ffap-file-finder always takes an argument
+ (ido-find-file does not).
+
+ * lisp/ffap.el (find-file-at-point): Do not call ffap-file-finder.
+ * test/lisp/ffap-tests.el (ffap-ido-mode): Test it.
+
+2021-08-04 Miha Rihtaršič <miha@kamnitnik.top>
+
+ Use `abort-minibuffers' in delsel
+
+ * lisp/delsel.el (minibuffer-keyboard-quit): Use
+ `abort-minibuffers' (bug#49821).
+
+ Previously, C-g was bound to abort-recursive-edit, now it is bound to
+ abort-minibuffers. However, after requiring delsel, it gets bound to
+ minibuffer-keyboard-quit, which still uses abort-recursive-edit. Use
+ the new function instead.
+
+2021-08-04 martin rudalics <rudalics@gmx.at>
+
+ Add new user option 'read-minibuffer-restore-windows'
+
+ * doc/lispref/minibuf.texi (Text from Minibuffer): Document it
+ (bug#45072).
+
+ * lisp/cus-start.el (standard): Add.
+
+ * src/minibuf.c (syms_of_minibuf): New variable
+ 'read-minibuffer-restore-windows'.
+
+2021-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Update outdated Gnus information
+
+ * doc/misc/gnus.texi (History): Update information.
+
+2021-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix apparent typo in new cl-generic-tests.el test case
+
+2021-08-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-generic.el (cl-generic-generalizers): Don't emit warning
+
+ Also remove "WARNING" annotations after confirming that he code was right.
+
+2021-08-04 akater <nuclearspace@gmail.com>
+
+ Evaluate eql specializers
+
+ * lisp/emacs-lisp/cl-generic.el (cl-generic-generalizers): Evaluate
+ forms that are eql specializers. Provide backward compatibility
+ with a warning.
+
+ * test/lisp/emacs-lisp/cl-generic-tests.el: Add a test.
+ * lisp/emacs-lisp/bindat.el (bindat--type): Adhere to the new rule.
+ * lisp/emacs-lisp/edebug.el (edebug--match-&-spec-op): Adhere to the new rule.
+ * lisp/emacs-lisp/map.el (map-into): Adhere to the new rule.
+ * lisp/emacs-lisp/radix-tree.el (map-into): Adhere to the new rule.
+ * lisp/frame.el (cl-generic-define-context-rewriter): Adhere to the new rule.
+ * lisp/gnus/gnus-search.el
+ (gnus-search-transform-expression): Adhere to the new rule.
+ * lisp/image/image-converter.el
+ (image-converter--probe image-converter--convert): Adhere to the new rule.
+ * lisp/mail/smtpmail.el (smtpmail-try-auth-method): Adhere to the new rule.
+ * lisp/progmodes/elisp-mode.el
+ (xref-backend-definitions)
+ (xref-backend-apropos): Adhere to the new rule.
+ * lisp/progmodes/etags.el (xref-backend-identifier-at-point)
+ (xref-backend-identifier-completion-table)
+ (xref-backend-identifier-completion-ignore-case)
+ (xref-backend-definitions)(xref-backend-apropos): Adhere to the new rule.
+ * test/lisp/emacs-lisp/checkdoc-tests.el
+ (checkdoc-cl-defmethod-with-types-ok)
+ (checkdoc-cl-defmethod-qualified-ok)
+ (checkdoc-cl-defmethod-with-extra-qualifier-ok): Adhere to the new rule.
+
+ * etc/NEWS: Describe the change.
+
+2021-08-03 Michael Albinus <michael.albinus@gmx.de>
+
+ Code cleanup for Tramp's yubikey integration
+
+ * lisp/net/tramp-sh.el (tramp-actions-before-shell)
+ (tramp-actions-copy-out-of-band):
+ Use `tramp-security-key-confirm-regexp'.
+
+ * lisp/net/tramp.el (tramp-security-key-confirm-regexp): Rename from
+ `tramp-yubikey-regexp'. Adapt docstring.
+ (tramp-security-key-confirmed-regexp): New defcustom.
+ (tramp-action-show-and-confirm-message):
+ Redisplay. Use `tramp-security-key-confirmed-regexp'.
+
+2021-08-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ file-name-concat is not error free
+
+ * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Declare
+ file-name-concat as side-effect free.
+
+2021-08-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Declare file-name-concat as side-effect free
+
+ * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Declare
+ file-name-concat as side-effect (and error) free.
+
+2021-08-03 Mattias Engdegård <mattiase@acm.org>
+
+ Remove ineffective expression in verilog-mode
+
+ * lisp/progmodes/verilog-mode.el (verilog-set-auto-endcomments):
+ Remove expression that now elicits a byte-compiler warning.
+
+2021-08-03 Mattias Engdegård <mattiase@acm.org>
+
+ Declare `match-beginning` and `match-end` as side-effect-free
+
+ * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Add functions.
+
+2021-08-03 Phil Sainty <psainty@orcon.net.nz>
+
+ Merge branch 'scratch/so-long'
+
+2021-08-03 Phil Sainty <psainty@orcon.net.nz>
+
+ Make `global-so-long-mode' use `buffer-line-statistics'
+
+ * lisp/so-long.el: (so-long-statistics-excessive-p): New predicate
+ function using `buffer-line-statistics'.
+ (so-long-predicate): Use `so-long-statistics-excessive-p' by default.
+
+ * etc/NEWS: Describe changes.
+
+ * test/lisp/so-long-tests/so-long-tests-helpers.el:
+ * test/lisp/so-long-tests/so-long-tests.el: Update tests.
+ Also improve the existing `so-long-tests-predicate' tests.
+
+2021-08-03 Phil Sainty <psainty@orcon.net.nz>
+
+ Support 'preserved' variables and minor modes in `so-long-mode'
+
+ The default values support preserving the state of `view-mode' when
+ switching to (and reverting from) `so-long-mode' (bug#45084).
+
+ * lisp/so-long.el (so-long-mode-preserved-variables)
+ (so-long-mode-preserved-minor-modes): New user options.
+ (so-long-mode-maintain-preserved-variables)
+ (so-long-mode-maintain-preserved-minor-modes): New functions.
+ (so-long-remember-all, so-long-after-change-major-mode)
+ (so-long-mode-revert): Use them.
+
+ * etc/NEWS: Describe changes.
+
+ * test/lisp/so-long-tests/so-long-tests-helpers.el:
+ * test/lisp/so-long-tests/so-long-tests.el: Update tests.
+
+2021-08-03 Phil Sainty <psainty@orcon.net.nz>
+
+ * lisp/so-long.el (so-long-minor-modes): Additional modes to disable
+
+2021-08-03 Phil Sainty <psainty@orcon.net.nz>
+
+ Make `global-so-long-mode' handle unrecognised file types
+
+ * lisp/so-long.el (so-long-target-modes): Add `fundamental-mode'
+
+ * etc/NEWS: Describe changes.
+
+ This doesn't affect buffers which are simply in `fundamental-mode' by
+ default. It only affects buffers for which `set-auto-mode' has been
+ called (normally via `find-file') without establishing a different
+ major mode.
+
+2021-08-03 Phil Sainty <psainty@orcon.net.nz>
+
+ Increase `so-long-threshold' and `so-long-max-lines' defaults
+
+ * lisp/so-long.el (so-long-threshold, so-long-max-lines): Increase
+ default values to reduce false-positives.
+
+ * etc/NEWS: Describe changes.
+
+ Lines shorter than 10,000 characters shouldn't generally be causing
+ problems, so testing this explicitly will largely eliminate
+ false-positives. We must also increase the maximum number of lines
+ to check, because 'minified' code may still include newlines, and so
+ there may be many lines shorter than the new threshold before we find
+ a line which exceeds it.
+
+ Previously we used a minimum-effort heuristic, testing a very small
+ number of lines against a maximum length which, while not remotely
+ long enough to cause problems, would nevertheless be uncommon in any
+ normal file of programming code (and hence indicative that the file
+ was likely to be minified code).
+
+ Testing indicates that the performance penalty for the larger values
+ should be negligible.
+
+2021-08-03 Jimmy Yuen Ho Wong <wyuenho@gmail.com>
+
+ * Fix error while disassembling native code on macOS
+
+ * lisp/emacs-lisp/disass.el (disassemble-internal): Make sure the
+ regexp that searches for a symbol takes into account of llvm-objdump's
+ output format.
+
+2021-08-03 Juri Linkov <juri@linkov.net>
+
+ Improve handling of context menus for global, local, minor-mode menus
+
+ * lisp/mouse.el (context-menu-global, context-menu-local, context-menu-minor):
+ Better handling of possibly nested menu maps.
+
+2021-08-03 Amin Bandali <bandali@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 75ecce4323 Unbreak ERC's Ibuffer filter (Bug#44100)
+
+2021-08-03 Olivier Certner <olce.emacs@certner.fr>
+
+ Unbreak ERC's Ibuffer filter (Bug#44100)
+
+ * lisp/erc/erc-ibuffer.el (erc-modified): Don't use `length' on dotted
+ lists (and not even to test if there is more than one element, for
+ that matter). Use `cdr' instead.
+
+2021-08-03 Juri Linkov <juri@linkov.net>
+
+ Adjust tab-bar to the new mode-line-misc-info value (bug#49806)
+
+ * lisp/tab-bar.el (tab-bar--define-keys): Adjust to the new
+ default value for `mode-line-misc-info'.
+
+2021-08-02 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ mh-junk: adjust messages for allow/block actions
+
+ * lisp/mh-e/mh-junk.el: Remove messages that get overwritten quickly.
+ Keep messages that give status for slow operations. Add information
+ that might be useful for debugging failures.
+
+2021-08-02 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/mwheel.el: Don't use `custom-initialize-delay`.
+
+ Set up the keybindings when loading the file.
+
+ (mouse-wheel--installed-bindings-alist): Move to beginning.
+ (mouse-wheel-change-button): Don't update bindings when they're not installed.
+ (mouse-wheel--setup-bindings): New function extracted from `mouse-wheel-mode`.
+ (<topleve>): Call it when loading the file.
+ (mouse-wheel-mode): Use the default :initializer.
+
+2021-08-02 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/flymake.el (flymake--mode-line-title): Don't quote lambda
+
+2021-08-01 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/project.el (project-switch-project): Use 'let*' (bug#49635).
+
+ This allows overriding-local-map to have effect on read-key-sequence.
+
+2021-08-01 Juri Linkov <juri@linkov.net>
+
+ * lisp/help-mode.el (help-mode-context-menu): New function.
+
+ (help-mode): Use it.
+
+2021-08-01 Juri Linkov <juri@linkov.net>
+
+ * lisp/emacs-lisp/autoload.el (autoload--make-defs-autoload): Display warning.
+
+ https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00007.html
+
+2021-08-01 Mattias Engdegård <mattiase@acm.org>
+
+ Make dlet work like let, not let*
+
+ Change `dlet` so that it has binding semantics like `let` because that
+ is what a user would expect and it allows a corresponding `dlet*` to
+ be added later should the need arise. Fortunately the change has no
+ effect where it is currently used.
+
+ * lisp/subr.el (dlet): Work like let.
+ * lisp/calendar/cal-bahai.el (calendar-bahai-date-string):
+ * lisp/calendar/cal-coptic.el (calendar-coptic-date-string):
+ * lisp/calendar/cal-dst.el (calendar-time-zone-daylight-rules)
+ (calendar-dst-starts, dst-in-effect):
+ * lisp/calendar/cal-persia.el (calendar-persian-date-string):
+ * lisp/calendar/calendar.el (calendar-dlet, calendar-generate-month)
+ (calendar-update-mode-line, calendar-date-string):
+ * lisp/calendar/diary-lib.el (diary-list-entries-2)
+ (diary-list-entries, diary-mark-entries-1, diary-sexp-entry)
+ (diary-remind, diary-font-lock-date-forms, diary-fancy-date-pattern):
+ * lisp/calendar/holidays.el (holiday-sexp):
+ * lisp/calendar/icalendar.el (icalendar--convert-float-to-ical):
+ * lisp/calendar/solar.el (solar-time-string):
+ * lisp/calendar/todo-mode.el (todo-date-pattern)
+ (todo-edit-item--header, todo-convert-legacy-date-time)
+ (todo-read-date):
+ Rename `calendar-dlet*` to `calendar-dlet` since it uses `dlet`.
+
+2021-08-01 Mattias Engdegård <mattiase@acm.org>
+
+ Indicate selected occur target with fringe arrow
+
+ * lisp/replace.el (occur--set-arrow): New function.
+ (occur-mode-goto-occurrence)
+ (occur-mode-goto-occurrence-other-window)
+ (occur-mode-display-occurrence): Call it.
+ * etc/NEWS: Announce.
+
+2021-08-01 Juri Linkov <juri@linkov.net>
+
+ * lisp/filecache.el: Fix cycling (bug#49761).
+
+ (file-cache-cycle): Refactor from file-cache-minibuffer-complete.
+ (file-cache-minibuffer-complete): Use file-cache-cycle in 2 old places,
+ and in 1 following new place. When last-command is equal to this-command,
+ use file-cache-cycle to continue cycling the previous completion
+ as long as the user continues typing C-TAB.
+ Also when displaying a list of completions, don't try to move point
+ to the common prefix.
+
+2021-08-01 Kévin Le Gouguec <kevin.legouguec@gmail.com>
+
+ Extend Gnus summary highlight faces by default
+
+ * lisp/gnus/gnus.el (gnus-summary-selected):
+ (gnus-summary-normal-ancient):
+ (gnus-summary-normal-undownloaded):
+ (gnus-summary-normal-unread):
+ (gnus-summary-normal-read): Set :extend attribute.
+
+2021-08-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust the fully qualified host name when nothing is set
+
+ * doc/misc/message.texi (News Headers): Adjust index.
+ * lisp/gnus/message.el (message-check-news-header-syntax): Adjust check.
+ (message-make-fqdn): Be less hilarious.
+
+2021-07-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix `u' binding in Gnus Browse mode
+
+ * lisp/gnus/gnus-srvr.el (gnus-browse-mode-map): Bind to
+ `gnus-browse-toggle-subscription-at-point', which is the command.
+
+2021-07-31 Mattias Engdegård <mattiase@acm.org>
+
+ Occur-mode multi-line match property gap filling
+
+ When an occur-mode regexp matches across multiple lines, the spacing
+ prefixes inserted between each did not have the `occur-target`
+ property which is essential for jumping to the corresponding place in
+ the target buffer. This prevented next-error and previous-error
+ from working.
+
+ * lisp/replace.el (occur-engine): Put the `occur-target` property on
+ the continuation prefix to avoid the gap.
+
+2021-07-31 Mattias Engdegård <mattiase@acm.org>
+
+ * etc/NEWS: Mention occur-mode highlight changes.
+
+2021-07-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ C-x 5 5 manual tweak
+
+ * doc/emacs/frames.texi (Creating Frames): Mention
+ other-frame-prefix function name.
+
+2021-07-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Update NEWS tagging for a couple entries
+
+2021-07-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add an index entry for outline-minor-mode-cycle
+
+ * doc/emacs/text.texi (Outline Mode): Document outline-minor-mode-cycle.
+
+2021-07-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document outline-minor-mode-cycle in the manual.
+
+ * doc/emacs/text.texi (Outline Mode): Document outline-minor-mode-cycle.
+
+2021-07-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `ffap-read-file-or-url' work again (to read URLs)
+
+ * lisp/ffap.el (ffap--url-file-handler): New function (bug#44822).
+ (ffap-read-file-or-url): Use it to allow switching between URLs
+ and files.
+
+2021-07-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new user option python-forward-sexp-function
+
+ * lisp/progmodes/python.el (python-forward-sexp-function): New
+ user option (bug#41361).
+ (python-mode): Use it.
+
+2021-07-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust how `replace-match' runs modification hooks
+
+ * src/editfns.c (Fsubst_char_in_region)
+ (Ftranslate_region_internal):
+ * src/cmds.c (internal_self_insert): Update callers.
+ * src/insdel.c (replace_range): Allow inhibiting
+ signal_after_change/update_compositions.
+ * src/lisp.h: Update.
+
+ * src/search.c (Freplace_match): Run the modification hooks at the
+ end instead of before adjusting point (bug#42424).
+
+2021-07-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Extend whitespace-empty to the end of the line
+
+ * lisp/whitespace.el (whitespace-empty): Restore Emacs 26 look by
+ extending the face (bug#42112).
+
+2021-07-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Fix `speedbar-directory-buttons' when using Tramp"
+
+ This reverts commit 5afad3918bc8816b74e8efcff9cc441785446aa6.
+
+ This patch can't possibly be correct, and it breaks the stated interface.
+
+2021-07-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Allow nil initializers in define-minor-mode"
+
+ This reverts commit 02cbb37de73d563149389615ee44741322007108.
+
+ This was mistakenly committed and doesn't really make much sense.
+
+2021-07-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't bind <mouse-2> and RET in *Help* buffers
+
+ * lisp/help-mode.el (help-mode-map): Remove key bindings for RET
+ and <mouse-2> (bug#49784).
+ (help-xref-stack, help-xref-forward-stack, help-xref-stack-item)
+ (help-make-xrefs): Fix doc strings -- these aren't used by
+ `help-follow', but by `help-follow-symbol'.
+ (help-follow-mouse, help-follow): Make obsolete.
+
+2021-07-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow nil initializers in define-minor-mode
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Make the
+ meaning of :initialize nil and a missing :initialize the same.
+
+2021-07-31 Alan Third <alan@idiocy.org>
+
+ Fix some macOS problems
+
+ * src/nsmenu.m (update_frame_tool_bar): Make sure the toolbar isn't
+ displayed when it's not supposed to be.
+ * src/nsterm.m ([EmacsView layoutSublayersOfLayer:]): Reinstate code
+ intended to prevent a crash when running redisplay.
+
+2021-07-31 Alan Third <alan@idiocy.org>
+
+ Move parent frame setting code into EmacsWindow
+
+ * src/nsterm.m (ns_make_frame_visible):
+ (ns_set_parent_frame):
+ ([EmacsWindow initWithEmacsFrame:fullscreen:screen:]): Use new method.
+ ([EmacsWindow setParentChildRelationships]): New method.
+
+2021-07-31 Alan Third <alan@idiocy.org>
+
+ Move NS port toolbar handling to the window
+
+ * src/nsmenu.m (free_frame_tool_bar):
+ (update_frame_tool_bar): Remove wait_for_tool_bar and get the toolbar
+ from the window.
+ * src/nsterm.h (EmacsView): Remove toolbar and wait_for_tool_bar.
+ * src/nsterm.m (ns_update_begin):
+ ([EmacsView windowDidEnterFullScreen]):
+ ([EmacsView windowDidExitFullScreen]): Get the toolbar from the
+ window, not the view.
+ ([EmacsView dealloc]): Remove toolbar from view.
+ ([EmacsView createToolbar:]): Move method to EmacsWindow.
+ ([EmacsView initFrameFromEmacs:]): Don't create toolbar here any more.
+ ([EmacsView toolbar]): Remove method.
+ ([EmacsWindow initWithEmacsFrame:fullscreen:screen:]): Create toolbar here.
+ ([EmacsWindow createToolbar:]): Moved from EmacsView.
+ ([EmacsWindow dealloc]): Make sure we clean up the toolbar after
+ closing the window.
+
+2021-07-31 Alan Third <alan@idiocy.org>
+
+ Fix macOS live resize drawing
+
+ * src/nsterm.m ([EmacsView layout]):
+ ([EmacsView layoutSublayersOfLayer:]): Rename layout to
+ layoutSublayersOfLayer.
+
+2021-07-31 Alan Third <alan@idiocy.org>
+
+ Change NS port resize detection
+
+ * src/nsterm.m ([EmacsView windowDidResize:]): Remove function, it's
+ not performing a useful function any more.
+ ([EmacsView viewDidResize]):
+ ([EmacsView resizeWithOldSuperviewSize:]): Replace viewDidResize with
+ resizeWithOldSuperviewSize.
+ ([EmacsView initFrameFromEmacs:]): Remove the view resize notification
+ as we don't need it any more.
+
+2021-07-31 Alan Third <alan@idiocy.org>
+
+ Tidy up NS port OS window handling
+
+ * src/nsterm.h (EmacsWindow): Move above EmacsView definition and add
+ new method definitions.
+ (EmacsView): Remove redundant bwidth variable, and change NSWindow to
+ EmacsWindow.
+ (EmacsFSWindow): Delete definition.
+ * src/nsterm.m (ns_set_undecorated): Rewrite to work in GNUstep using
+ the new OS window creating methods.
+ ([EmacsView initFrameFromEmacs:]): Move all NSWindow related code to
+ new init method in EmacsWindow, and use said method.
+ ([EmacsView toggleFullScreen:]): Use EmacsWindow instead of NSWindow.
+ ([EmacsWindow initWithEmacsFrame:]):
+ ([EmacsWindow initWithEmacsFrame:fullscreen:screen:]):
+ ([EmacsWindow borderWidth]): New methods.
+ (EmacsFSWindow): Remove implementation.
+
+2021-07-31 Alan Third <alan@idiocy.org>
+
+ Simplify macOS drawing code
+
+ Convert EmacsSurface into a CALayer subclass so we can use the
+ built-in relationships. Also simplify the macOS versioning code.
+ This will result in more warnings on older versions of macOS but makes
+ reading the code easier.
+
+ * configure.ac: Add QuartzCore framework.
+ * src/nsterm.h (NS_DRAW_TO_BUFFER): Remove define and all references.
+ (EmacsSurface, EmacsLayer): Rename EmacsSurface to EmacsLayer and
+ modify the definition to fit the new function.
+ * src/nsterm.m (ns_update_begin):
+ (ns_update_end):
+ (ns_focus):
+ (ns_unfocus): Use the new overridden lockFocus and unlockFocus and
+ simplify the frame management.
+ ([EmacsView dealloc]):
+ ([EmacsView viewDidResize:]):Don't explicitly release surfaces.
+ ([EmacsView initFrameFromEmacs:]): Move the layer code to after the
+ NSWindow has been created as creating the layer now relies on some of
+ it's properties.
+ ([EmacsView makeBackingLayer]): New function.
+ ([EmacsView lockFocus]):
+ ([EmacsView focusOnDrawingBuffer]): Rename to lockFocus.
+ ([EmacsView unlockFocus]):
+ ([EmacsView unfocusDrawingBuffer]): Rename to unlockFocus.
+ ([EmacsView windowDidChangeBackingProperties]): Don't explicitly
+ release surfaces but reset EmacsLayer properties.
+ ([EmacsView layout]):
+ ([EmacsView viewWillDraw]): Rename to layout.
+ ([EmacsView wantsUpdateLayer]): Remove function and change all callers
+ to [EmacsView wantsLayer].
+ (EmacsSurface, EmacsLayer): Rename to EmacsLayer.
+ ([EmacsSurface getSize]):
+ ([EmacsSurface initWithSize:ColorSpace:Scale:]): Remove methods.
+ ([EmacsSurface initWithColorSpace:]):
+ ([EmacsLayer checkDimensions]):
+ ([EmacsLayer releaseSurfaces]):
+ ([EmacsLayer display]): New functions.
+ * src/nsterm.m ([EmacsLayer dealloc]): Use releaseSurfaces.
+ ([EmacsSurface getContext]): Automatically detect frame property
+ changes and clear the cache if required. Use built-in CALayer
+ properties where available.
+ ([EmacsLayer copyContentsTo:]): Use [CALayer contents] as source.
+
+2021-07-31 Eli Zaretskii <eliz@gnu.org>
+
+ * src/fontset.c (check_fontset_name): A better fix for bug#49782.
+
+2021-07-30 Adam Porter <adam@alphapapa.net>
+
+ * lisp/emacs-lisp/cl-macs.el: Add cl-type pattern
+
+ * lisp/emacs-lisp/cl-macs.el:
+ ((pcase-defmacro type)): Add 'cl-type' pattern.
+
+ * test/lisp/emacs-lisp/pcase-tests.el (pcase-tests-cl-type): Add test.
+
+ * doc/lispref/control.texi (pcase Macro): Update manual.
+
+ With thanks to Stefan Monnier and Eli Zaretskii for their guidance.
+
+2021-07-30 Eli Zaretskii <eliz@gnu.org>
+
+ * src/fontset.c (check_fontset_name): Fix last change.
+
+2021-07-30 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid segfault when set-fontset-font is called from non-GUI frames
+
+ * src/fontset.c (check_fontset_name): Avoid crashes if this is
+ called from a non-GUI frame. (Bug#49782)
+
+2021-07-30 Michael Albinus <michael.albinus@gmx.de>
+
+ Change Tramp version to "2.5.2-pre"
+
+ * doc/misc/trampver.texi:
+ * lisp/net/trampver.el: Change version to "2.5.2-pre".
+
+2021-07-30 Dmitry Gutov <dgutov@yandex.ru>
+
+ Make fileloop skip missing files
+
+ * lisp/fileloop.el (fileloop-next-file): If a file doesn't exist,
+ skip to the next one (bug#44979).
+
+2021-07-30 Maxim Nikulin <manikulin@gmail.com> (tiny change)
+
+ Tweak previous mailcap-view-file change
+
+ * lisp/net/mailcap.el (mailcap-view-file): Remove the :noquery t
+ mistakenly added (bug#12972).
+
+2021-07-30 k3tu0isui <k3tu0isui@gmail.com> (tiny change)
+
+ Fix problem when switching between different prolog versions
+
+ * lisp/progmodes/prolog.el (run-prolog): Make switching between
+ different prolog systems work more reliably (bug#45795).
+
+ * lisp/progmodes/prolog.el (prolog-ensure-process): Don't start a
+ new process if one already exists.
+
+2021-07-30 Mattias Engdegård <mattiase@acm.org>
+
+ Simplify lexical let-optimisations
+
+ Ensure in cconv that let-bindings have the normal form (VAR EXPR)
+ where VAR is a valid variable name, so that we don't need to keep
+ re-checking this all the time in the optimiser.
+
+ * lisp/emacs-lisp/byte-opt.el
+ (byte-optimize-enable-variable-constprop)
+ (byte-optimize-warn-eliminated-variable): Remove; these were mainly
+ used for debugging.
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-let-form):
+ Assume normalised let-bindings (with lexical-binding).
+ Stop using the variables removed above.
+ * lisp/emacs-lisp/cconv.el (cconv-convert): Ensure normalised
+ let-bindings. Malformed bindings are dropped after warning.
+
+ remove byte-optimize-warn-eliminated-variable
+
+2021-07-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Ensure that recover-file doesn't leave stale auto-save files behind
+
+ * lisp/files.el (recover-file): Don't leave stale auto-save files
+ behind after crash recovery (bug#11331).
+
+2021-07-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow shell PROMPT strings to have ANSI codes
+
+ * lisp/comint.el (comint-output-filter): Don't overwrite ANSI
+ codes from the prompt command (bug#11883).
+
+2021-07-30 Max Nikulin <manikulin@gmail.com> (tiny change)
+
+ mailcap.el: Avoid xdg-open silent failure
+
+ * lisp/net/mailcap.el (mailcap-view-file): Use 'pipe :connection-type
+ instead of 'pty to prevent killing of background process on handler
+ exit. Avoid regression similar to Bug#44824.
+
+ Problem happens only in some desktop environments where mailcap handler
+ launches actual viewer (as defined in .desktop files and obtained from
+ mimeapps.list) in background. E.g. xdg-open invokes "gio open" or
+ kde-open5 for Gnome or KDE accordingly and these handlers launch e.g.
+ eog or okular in background. As soon as main process exits, temporary
+ terminal session created by `start-process-shell-command' is terminated.
+ As a result background processes receive SIGHUP.
+
+ Previously command were executed with no buffer as well, so the change
+ does not affect "needsterminal" and "copiousoutput" mailcap features,
+ they are not supported as earlier.
+
+ If main process of the handler fails then show a message with exit
+ reason. Output (including error messages) is ignored as before.
+ Gtk applications tend to report significant amount of failed asserts
+ hardly informative for majority of users (bug#12972).
+
+2021-07-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix case insensitivity in `read-file-name'
+
+ * lisp/minibuffer.el (read-file-name-default): Make `read-file-name'
+ actually respect `read-file-name-completion-ignore-case' (bug#14340).
+
+2021-07-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix issue with mml-preview from outside Gnus
+
+ * lisp/gnus/gnus-art.el (gnus-mime-display-alternative): Be more
+ resilient when running from outside Gnus.
+
+2021-07-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Work around long-standing seq.el compilation warning
+
+ * lisp/emacs-lisp/seq.el (seq-contains): When using cl-defgeneric
+ to define an obsolete function, it'll complain about it being
+ obsolete. Suppress that warning. (Should probably be fixed in
+ cl-defgeneric instead.)
+
+2021-07-30 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Remove a redundant let-binding from Ispell
+
+ Recent optimizer changes revealed a case-fold-search binding in
+ Ispell that was made redundant in the revision of 2020-11-03
+ "Simplify ispell-check-version’s use of -vv flag".
+
+ * lisp/textmodes/ispell.el (ispell-check-version): Remove no-op
+ binding of case-fold-search.
+
+2021-07-30 Michael Albinus <michael.albinus@gmx.de>
+
+ * etc/NEWS: Tramp supports authentication via yubikey now. Fix typos.
+
+2021-07-30 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix bug#49773 in Tramp
+
+ * lisp/net/tramp.el (tramp-handle-find-backup-file-name)
+ (tramp-handle-lock-file, tramp-handle-make-auto-save-file-name):
+ Check security hole only if action is in progress. (Bug#49773)
+
+2021-07-30 Mattias Engdegård <mattiase@acm.org>
+
+ Optimise let and let* whose body is constant or the last variable
+
+ Simplify (let ((X1 E1) ... (Xn En)) Xn)
+ => (progn E1 ... En)
+
+ and (let* ((X1 E1) ... (Xn En)) Xn)
+ => (let* ((X1 E1) ... (Xn-1 En-1)) En)
+
+ and similarly the case where the body is a constant, extending a
+ previous optimisation that only applied to the constant nil.
+ This reduces the number of bound variables, shortens the code, and
+ enables further optimisations.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-letX): Rewrite using
+ `pcase` and add the aforementioned transformations.
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases):
+ Add test cases.
+
+2021-07-30 Mattias Engdegård <mattiase@acm.org>
+
+ Move warnings about bad let-bindings from source optimiser to cconv
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-let-form): Move warnings...
+ * lisp/emacs-lisp/cconv.el (cconv-convert): ...here, which is an
+ overall better place (closer to the front-end).
+
+2021-07-30 Mattias Engdegård <mattiase@acm.org>
+
+ Optimise prog1 better
+
+ Rewrite (prog1 CONST FORMS...) => (progn FORMS... CONST)
+ where CONST is a compile-time constant, because putting the value last
+ allows the lapcode peephole pass to do important improvements like
+ branch elimination. Also use progn instead of prog1 for `ignore`.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker):
+ New `prog1` and `ignore` transforms.
+
+2021-07-30 Mattias Engdegård <mattiase@acm.org>
+
+ Elide lexical variables in for-effect context in source optimiser
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker):
+ Remove for-effect uses of lexical variables. We previously relied on
+ this being done by the lapcode peephole optimiser but at source level
+ it enables more optimisation opportunities.
+ Keywords are elided for the same reason.
+
+2021-07-30 Mattias Engdegård <mattiase@acm.org>
+
+ Single source optimiser entry point
+
+ Make the optimiser aware of lexical arguments. Otherwise we cannot
+ know for sure whether a variable is lexical or dynamic during
+ traversal.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-one-form): New optimiser
+ entry point, replacing the recursive byte-optimize-form.
+ * lisp/emacs-lisp/bytecomp.el (byte-optimize-one-form): Autoload.
+ (byte-compile-keep-pending, byte-compile-top-level):
+ Use byte-optimize-one-form.
+
+2021-07-30 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ mh-junk: replace color-based terms with descriptive words
+
+ * lisp/mh-e/*.el: "whitelist" -> "allowlist" and "blacklist" -> "blocklist".
+ * doc/misc/mh-e.texi: update manual to match.
+ * lisp/mh-e/mh-folder.el: Change the binding of
+ 'mh-junk-allowlist' to 'J a'. Add a compatibility binding for the
+ old 'J w'.
+ * lisp/mh-e/mh-scan.el (mh-note-allowlisted): Change char from 'W' to 'A'.
+ * lisp/mh-e/mh-junk.el: Rename 'mh-blacklist-a-msg' to
+ 'mh-junk-blocklist-a-msg', adding the missing "junk-" to the
+ function name.
+
+2021-07-29 Nick Gasson <nick@nickg.me.uk> (tiny change)
+
+ Avoid errors in rmailsum for messages without "From"
+
+ * lisp/mail/rmailsum.el (rmail-header-summary): Be defensive about
+ the presence of the "From" header. (Bug#49770)
+
+2021-07-29 dickmao <none>
+
+ Follow-up toggle-subscription name change
+
+ * doc/misc/gnus.texi (Subscription Commands): Refer to correct function.
+ * lisp/gnus/gnus-group.el (gnus-group-unsubscribe-current-group):
+ Make backwards-compatible.
+ (gnus-group-unsubscribe-group):
+ Make backwards-compatible (bug#49768).
+
+2021-07-29 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix printing of multiple items in one group without line numbers
+
+ * lisp/progmodes/xref.el (xref--insert-xrefs):
+ Fix printing of multiple items in one group without line numbers
+ (mentioned in bug#49731).
+
+2021-07-28 dickmao <none>
+
+ Rename Gnus -unsubscribe-group commands to -toggle-subscription
+
+ * doc/emacs/misc.texi (Gnus Group Buffer): Document change.
+ * doc/misc/gnus.texi (Subscription Commands): Document change.
+ (Browse Foreign Server): Document change.
+ * lisp/gnus/gnus-group.el (gnus-group-mode-map):
+ Unsubscribe is not subscribe.
+ (gnus-group-sub-map): Unsubscribe is not subscribe.
+ (gnus-group-make-menu-bar): Unsubscribe is not subscribe.
+ (gnus-group-tool-bar-gnome): Unsubscribe is not subscribe.
+ (gnus-group-mode): Unsubscribe is not subscribe.
+ (gnus-group-unsubscribe): Refactor.
+ (gnus-group-subscribe): Refactor.
+ (gnus-group-unsubscribe-current-group): Define obsolete alias.
+ (gnus-group-unsubscribe-group): Define obsolete alias.
+ (gnus-group-toggle-subscription-at-point): Refactor.
+ (gnus-group-set-subscription-at-point): Refactor.
+ (gnus-group-toggle-subscription): Refactor.
+ (gnus-group-set-subscription): Refactor.
+ * lisp/gnus/gnus-srvr.el (gnus-browse-mode-map):
+ Unsubscribe is not subscribe.
+ (gnus-browse-make-menu-bar): Unsubscribe is not subscribe.
+ (gnus-browse-mode): Document the change.
+ (gnus-browse-unsubscribe-current-group): Define obsolete alias.
+ (gnus-browse-unsubscribe-group): Define obsolete alias.
+ (gnus-browse-toggle-subscription-at-point): Unsubscribe is not subscribe.
+ (gnus-browse-toggle-subscription): Unsubscribe is not subscribe
+ (bug#49759).
+
+2021-07-28 Juri Linkov <juri@linkov.net>
+
+ Improve :type of defcustom 'context-menu-functions' and add documentation.
+
+ * doc/emacs/frames.texi (Menu Mouse Clicks): Describe context-menu-mode
+ and context-menu-functions instead of suggesting global-set-key.
+ (Menu Bars): Mention context-menu-mode and context-menu-functions.
+
+ * etc/NEWS: Add context-menu-mode and context-menu-functions.
+
+ * lisp/mouse.el (context-menu-functions): Use :type with repeat/function-item.
+ (context-menu-minor, context-menu-undo, context-menu-region)
+ (context-menu-ffap): Improve docstrings displayed for function-item in
+ defcustom of context-menu-functions.
+
+2021-07-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve mode-line-position-column-format manual entry
+
+ * doc/lispref/modes.texi (Mode Line Variables): Mention %C, and
+ don't mention the obsolete column-number-indicator-zero-based
+ variable.
+
+2021-07-28 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/gud.el: Add prefix 'gud-' to repeat-map variables (bug#49632)
+
+ * lisp/progmodes/gud.el (gud-sdb-repeat-map, gud-dbx-repeat-map)
+ (gud-xdb-repeat-map, gud-perldb-repeat-map, gud-pdb-repeat-map)
+ (gud-guiler-repeat-map, gud-jdb-repeat-map): Rename with prefix 'gud-'.
+
+2021-07-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make byte-recompile-directory less brittle
+
+ * lisp/emacs-lisp/bytecomp.el (byte-recompile-directory): Don't
+ interpret files named "~" as $HOME (bug#49758).
+
+2021-07-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve mode-line-position-column-format doc string
+
+ * lisp/bindings.el (mode-line-position-column-format): Improve doc
+ string.
+ (mode-line-position-line-format): Point to
+ `mode-line-position-column-line-format'.
+
+2021-07-28 Kévin Le Gouguec <kevin.legouguec@gmail.com>
+
+ Improve file-name-concat NEWS entry
+
+2021-07-28 Philip Kaludercic <philipk@posteo.net>
+
+ Replace cl-c[ad]+r with regular c[ad]+r
+
+ * lisp/net/rcirc.el (rcirc-make-trees): Replace cl-cdadr with cdadr
+ (rcirc-handler-333): Replace cl-cadddr with cadddr
+ (rcirc-authenticate): Replace cl-cdddr with cdddr
+
+2021-07-28 Michael Albinus <michael.albinus@gmx.de>
+
+ Display yubikey message properly in Tramp
+
+ * lisp/net/tramp.el (tramp-action-show-and-confirm-message):
+ Display message properly.
+
+2021-07-27 Brian Leung <leungbk@mailfence.com>
+
+ Ensure that gud commands for non-GDB debuggers are handled by repeat-mode
+
+ * lisp/progmodes/gud.el (sdb-repeat-map): Define.
+ (sdb): Set repeat-mode property to the symbol corresponding to the
+ repeat map.
+ (dbx-repeat-map): Define.
+ (dbx): Set repeat-mode property to the symbol corresponding to the
+ repeat map.
+ (xdb-repeat-map): Define.
+ (xdb): Set repeat-mode property to the symbol corresponding to the
+ repeat map.
+ (perldb-repeat-map): Define.
+ (perldb): Set repeat-mode property to the symbol corresponding to the
+ repeat map.
+ (pdb-repeat-map): Define.
+ (pdb): Set repeat-mode property to the symbol corresponding to the
+ repeat map.
+ (guiler-repeat-map): Define.
+ (guiler): Set repeat-mode property to the symbol corresponding to the
+ repeat map.
+ (jdb-repeat-map): Define.
+ (jdb): Set repeat-mode property to the symbol corresponding to the
+ repeat map. (Bug#49632)
+
+2021-07-27 Brian Leung <leungbk@mailfence.com>
+
+ Ensure that gud commands for M-x gdb are handled by repeat-mode
+
+ * lisp/progmodes/gud.el (gud-gdb-repeat-map): Rename from
+ gud-repeat-map, and populate at the top-level.
+ (gud-set-repeat-map-property): Introduce this helper function for
+ setting the repeat-map property.
+ (gud-gdb): Use the gud-set-repeat-map-property function to assign the
+ repeat-map property.
+
+ * lisp/progmodes/gdb-mi.el (gdb): Use the gud-set-repeat-map-property
+ function to assign the repeat-map property.
+
+ Because different debugging tools may not support all of the gud-foo
+ functions, we reassign the repeat-map property within the respective
+ commands, as opposed to the top level of the files, to ensure that the
+ repeat-map property is reassigned each time to a symbol corresponding
+ to the active debugging tool. (Bug#49632)
+
+2021-07-27 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-format-global): Use string-trim-right (bug#30056).
+
+2021-07-27 Juri Linkov <juri@linkov.net>
+
+ Add new context-menu options for menus "File At Point" and "Version Control".
+
+ * lisp/mouse.el (context-menu-functions): Add more options.
+ (context-menu-global, context-menu-local): Fix separators.
+ (context-menu-minor): Rewrite to support list of submenus.
+ (context-menu-vc, context-menu-ffap): New functions.
+ (context-menu-undo, context-menu-region): Fix separators.
+
+ * lisp/dired.el (dired-context-menu):
+ * lisp/info.el (Info-context-menu):
+ * lisp/net/goto-addr.el (goto-address-context-menu):
+ * lisp/net/eww.el (eww-context-menu):
+ * lisp/progmodes/prog-mode.el (prog-context-menu): Fix separators.
+
+2021-07-27 Philip Kaludercic <philipk@posteo.net>
+
+ Remove removal of text properties from rcirc-buffer-alist keys
+
+ * lisp/net/rcirc.el (rcirc-mode): Remove set-text-properties call
+
+2021-07-27 Michael Albinus <michael.albinus@gmx.de>
+
+ Mark all autorevert tests as unstable on Cygwin (bug#49665)
+
+ * test/lisp/autorevert-tests.el: Mark all tests as unstable on
+ Cygwin (bug#49665).
+
+2021-07-27 Philip Kaludercic <philipk@posteo.net>
+
+ Fix checkdoc issues
+
+ * lisp/net/rcirc.el (rcirc-finished-sasl): Add period.
+ (rcirc-mode): Expand docstring.
+ (rcirc-handler-900): Document sender and process
+
+2021-07-27 Mattias Engdegård <mattiase@acm.org>
+
+ Fix mistake in switch-case generation of `null` (bug#49746)
+
+ Reported by Gregor Zattler.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile--cond-switch-prefix):
+ Be more careful in the selection of equality.
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases):
+ Add test case.
+
+2021-07-27 Philip Kaludercic <philipk@posteo.net>
+
+ Update rcirc-buffer-alist after receiving NICK
+
+ * lisp/net/rcirc.el (rcirc-handler-NICK): Remove old nick and add new nick
+
+2021-07-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Make revert-buffer preserve buffer-readedness"
+
+ This reverts commit fcae435f598471a2911641412125c5ac4f73559f.
+
+ This leads to problems when reverting from a file that's changed
+ readedness externally.
+
+2021-07-27 Philip Kaludercic <philipk@posteo.net>
+
+ Fix TOPIC command
+
+ * lisp/net/rcirc.el (topic): Add target argument.
+
+2021-07-27 Michael Albinus <michael.albinus@gmx.de>
+
+ Final tweak for Tramp's yubikey detection
+
+ * lisp/net/tramp.el (tramp-yubikey-regexp)
+ (tramp-action-show-and-confirm-message): Expect also "\n".
+
+2021-07-27 Alan Third <alan@idiocy.org>
+
+ Convert fringe bitmaps to vectors on NS port
+
+ Unfortunately *step doesn't support masks for bitmap images so
+ changing the colors of fringe bitmaps is awkward. We can work around
+ this by converting the bitmap into an NSBezierPath and drawing it in
+ the required color.
+
+ * src/nsterm.m (ns_define_fringe_bitmap):
+ (ns_destroy_fringe_bitmap): New functions
+ (ns_draw_fringe_bitmap): Display the NSBezierPath.
+ * src/nsimage.m
+ ([EmacsImage initFromXBM:width:height:fg:bg:reverseBytes:]): Remove
+ variable that's there to allow us to easily modify the XBM colors.
+ ([EmacsImage setXBMColor:]): Remove method.
+
+2021-07-27 Alan Third <alan@idiocy.org>
+
+ Fix NS inset rectangle corners
+
+ * src/nsterm.m (ns_draw_relief): Use a path to draw the mitered
+ corners instead of rectangles.
+
+2021-07-27 Alan Third <alan@idiocy.org>
+
+ Simplify NS sizing and positioning code
+
+ * src/nsterm.m (ns_set_offset): Unify the two branches into one, most
+ of the code is the same.
+ (ns_set_window_size): Use the provided tools to calculate the window
+ size instead of doing it ourselves.
+
+2021-07-27 Alan Third <alan@idiocy.org>
+
+ * src/nsterm.m (ns_set_frame_alpha): Enable alpha on GNUstep.
+
+2021-07-26 Alan Third <alan@idiocy.org>
+
+ Fix image crash on macOS (bug#49688)
+
+ * src/nsimage.m ([EmacsImage allocInitFromFile:]): Use isValid to
+ check whether the image is valid instead of generating a tiff.
+
+2021-07-26 Mattias Engdegård <mattiase@acm.org>
+
+ Adjust grep-mode end-col function return value
+
+ * lisp/progmodes/grep.el (grep-regexp-alist): Adjust the return value
+ from the END-COL function by one since it is now (after fixing
+ bug#49624) inclusive. Found by Juri Linkov.
+
+2021-07-26 Michael Albinus <michael.albinus@gmx.de>
+
+ Some minor improvements for share handling in tramp-gvfs.el
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-connection-mounted-p):
+ Set "share" connection property if the mount spec offers it.
+ (tramp-gvfs-handle-get-remote-uid)
+ (tramp-gvfs-handle-get-remote-gid): Use it.
+
+2021-07-26 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt Tramp for yubikey
+
+ * lisp/net/tramp.el (tramp-yubikey-regexp): Adapt value.
+ (tramp-trace-functions): Adapt docstring.
+ (tramp-process-action-regexp): New defvar.
+ (tramp-action-password, tramp-process-one-action): Use it.
+ (tramp-action-show-and-confirm-message): Rewrite.
+
+2021-07-26 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt tramp-sudoedit.el for better testing
+
+ * doc/misc/tramp.texi (Bug Reports): Revert last change. Mention
+ exception for sudoedit.
+
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-send-command):
+ Let-bind `tramp-cache-read-persistent-data' for better password handling.
+
+2021-07-25 Mattias Engdegård <mattiase@acm.org>
+
+ Describe changes to the occur-mode implementation in NEWS
+
+ * etc/NEWS: Mention change to the `occur-target` property (bug#39121).
+
+2021-07-25 Glenn Morris <rgm@gnu.org>
+
+ Fix recent gdb-mi change
+
+ * lisp/progmodes/gdb-mi.el (gdb-registers-filter-pattern-list):
+ Fix type.
+
+2021-07-25 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ d0625dc553 (origin/emacs-27) ; One more change in back.texi.
+ 06d0a66e57 ; Yet another last-minute change in Emacs manual for printing
+
+2021-07-25 Michael Albinus <michael.albinus@gmx.de>
+
+ Add instructions for Tramp bug reports
+
+ * doc/misc/tramp.texi (Bug Reports): Describe how to use password
+ cache with "emacs -Q".
+
+2021-07-25 Mattias Engdegård <mattiase@acm.org>
+
+ Fix tex-validate-buffer
+
+ * lisp/textmodes/tex-mode.el (tex-validate-buffer):
+ Set `inhibit-read-only` around all modifications of the
+ read-protected *Occur* buffer (bug#19326).
+ Add the `occur-match` property, and adjust the extent of the
+ `occur-target` property, so that next-error and previous-error work
+ correctly (bug#39121).
+
+2021-07-25 Mattias Engdegård <mattiase@acm.org>
+
+ Add back occur-mode-find-occurrence for compatibility (bug#39121)
+
+ * lisp/replace.el (occur-mode-find-occurrence):
+ Put back (an emulation of) the previously removed function.
+ It is used internally in eshell and in some external code.
+
+ Problem found by Basil Contovounesios.
+
+2021-07-25 Eli Zaretskii <eliz@gnu.org>
+
+ Fix compilation of xftfont.c with old fontconfig
+
+ * src/xftfont.c (FC_LCD_FILTER): Define if undefined, for older
+ versions of fontconfig. This was mistakenly deleted 2 years ago.
+ (Bug#49722)
+
+2021-07-25 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix extended attributes for Tramp's sudoedit method (bug#49724)
+
+ * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-do-copy-or-rename-file):
+ Remove compat code for `{set-}file-extended-attributes'.
+ (tramp-sudoedit-handle-write-region): Handle extended attributes.
+ (Bug#49724)
+
+ * test/lisp/net/tramp-tests.el (tramp-test25-file-selinux):
+ Fix test for sudoedit method.
+
+2021-07-25 Kévin Le Gouguec <kevin.legouguec@gmail.com>
+
+ * etc/NEWS: Fix renaming of directory-append.
+
+2021-07-25 Christopher League <league@contrapunctus.net>
+
+ When bookmark is overwritten, unfontify its previous position
+
+ * lisp/bookmark.el (bookmark-store): When the bookmark-fontify option
+ is non-nil, setting or jumping to bookmarks will colorize them using
+ `bookmark-face'. With this change, overwriting a bookmark will remove
+ the fontification at its former position (bug#49725).
+
+2021-07-25 Michael Albinus <michael.albinus@gmx.de>
+
+ Use `file-name-concat' in Tramp
+
+ * lisp/net/tramp-compat.el (tramp-compat-file-name-concat):
+ New defalias.
+
+ * lisp/net/tramp.el (tramp-handle-expand-file-name):
+ * lisp/net/tramp-adb.el
+ (tramp-adb-handle-directory-files-and-attributes):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-expand-file-name):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-expand-file-name):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-expand-file-name):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-expand-file-name):
+ Use it.
+
+2021-07-25 Mattias Engdegård <mattiase@acm.org>
+
+ Don't squash markers in occur-edit-mode
+
+ * lisp/replace.el (occur-after-change-function): Instead of replacing
+ the whole line being edited, use shrink-wrapping to replace the
+ smallest interval encompassing the change. That way, we avoid
+ disturbing markers (such as occur highlighting locations) in the line;
+ they would otherwise all be forced to the beginning.
+
+2021-07-25 Mattias Engdegård <mattiase@acm.org>
+
+ Keep track of match extents in occur-mode (bug#39121)
+
+ Use the `occur-target` text property to keep track of the extents of
+ all matches on each line instead of just the start of the first match.
+ Doing so allows us to highlight all matches when jumping to a matching
+ line instead of just the first one, and it works in a more principled
+ way. It also removes compatibility problems that were introduced with
+ occur-highlight-regexp.
+
+ For compatibility with code that populate their own occur-mode
+ buffers, we still accept `occur-target` properties with a single
+ marker as value.
+
+ * lisp/replace.el (occur-highlight-regexp, occur-highlight-overlay):
+ Remove.
+ (occur-highlight-overlays): New.
+ (occur--targets-start): New.
+ * lisp/replace.el (occur-after-change-function):
+ (occur-mode-find-occurrence): Replace with...
+ (occur-mode--find-occurrences): ...this function that returns the
+ whole `occur-target` property value.
+ (occur-mode-goto-occurrence, occur-mode-goto-occurrence-other-window)
+ (occur-goto-locus-delete-o, occur-mode-display-occurrence)
+ (occur-engine): Adjust to new property format.
+ (occur--highlight-occurrence): Replace with...
+ (occur--highlight-occurrences): ...this function that takes
+ the `occur-target` property value as argument.
+ (occur-1): Don't use `occur-highlight-regexp`.
+ * test/lisp/replace-tests.el (occur-highlight-occurrence):
+ Adapt to new property format.
+
+2021-07-25 Arthur Miller <arthur.miller@live.com> (tiny change)
+
+ Support '--group-directories-first' in ls-lisp.el
+
+ * lisp/ls-lisp.el (ls-lisp--sanitize-switches): New function.
+ (ls-lisp--insert-directory): Support '--group-directories-first'.
+ Call 'ls-lisp--sanitize-switches' to convert long options to short
+ forms and remove unsupported long options. Update the doc string.
+
+2021-07-25 Peter Feigl <peter.feigl@nexoid.at>
+
+ Add commands to move to next/previous column in tabulated-list-mode
+
+ * lisp/emacs-lisp/tabulated-list.el (tabulated-list-mode-map): Add
+ keybindings M-left and M-right.
+ (tabulated-list-previous-column tabulated-list-next-column): Implement
+ commands (bug#44711).
+
+2021-07-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Rename directory-append to file-name-concat
+
+ * src/fileio.c (Ffile_name_concat):
+ * lisp/files.el (move-file-to-trash):
+ * lisp/emacs-lisp/shortdoc.el (file-name):
+ * doc/lispref/files.texi (Directory Names): Rename
+ `directory-append' to `file-name-concat'.
+
+2021-07-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow empty elements in directory-append
+
+ * doc/lispref/files.texi (Directory Names): Document it.
+ * src/fileio.c (Fdirectory_append): Allow empty elements.
+
+2021-07-24 Mattias Engdegård <mattiase@acm.org>
+
+ Disable delay and ding in replace-tests
+
+ * test/lisp/replace-tests.el (replace-tests-with-undo):
+ When testing the "U" (undo all changes) option, the code will delay
+ and ding which is obnoxious in an automated test.
+ Disabling that makes the test quiet and about 150 times faster.
+
+2021-07-24 Yuan Fu <casouri@gmail.com>
+
+ Add filter to GDB's register buffer
+
+ * lisp/progmodes/gdb-mi.el (gdb-registers-enable-filter)
+ (gdb-registers-filter-pattern-list): New custom options.
+ (gdb-header-click-event-handler, gdb-registers-toggle-filter): New
+ functions.
+ (gdb-header-click-event-handler): Only add a register if it passes the
+ filter.
+ (gdb-registers-mode-map): New keybinding for toggling the filter.
+ (gdb-registers-header): New buttons on the header line for the
+ filter (bug#39179).
+
+2021-07-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Really convert to multibyte in Fdirectory_append
+
+ * src/fileio.c (Fdirectory_append): Fix check for whether we need
+ to convert to multibyte.
+ (Fdirectory_append):
+
+2021-07-24 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix last commit in tramp.el
+
+2021-07-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix Fdirectory_append check for whether strings have to be converted
+
+ * src/coding.c (string_ascii_p): Make it non-static.
+
+ * src/fileio.c (Fdirectory_append): Fix check for whether we need
+ to convert to multibyte.
+
+ * src/fns.c (string_ascii_p): Remove copy.
+
+ * src/lisp.h: Declare string_ascii_p.
+
+2021-07-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Set the normal-erase-is-backspace variable from Customize
+
+ * lisp/simple.el (normal-erase-is-backspace): Always set the
+ variable so that Customize is up-to-date (bug#49593).
+
+2021-07-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak Fdirectory_append slightly
+
+ * src/fileio.c (Fdirectory_append): Make the xfree condition more
+ robust.
+
+2021-07-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve directory-append manual entry
+
+ * doc/lispref/files.texi (Directory Names): Mention zero-length
+ restriction.
+
+2021-07-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak Fdirectory_append for efficiency
+
+ * src/fileio.c (Fdirectory_append): Make slightly more efficient.
+
+2021-07-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Extend directory-append to take an arbitrary number of components
+
+ * doc/lispref/files.texi (Directory Names): Document it.
+ * lisp/emacs-lisp/shortdoc.el (file-name): Add new example.
+
+ * src/fileio.c (Fdirectory_append): Change the function to take an
+ arbitrary number of components.
+
+2021-07-24 Philip Kaludercic <philipk@posteo.net>
+
+ Ensure that rcirc-buffer-alist has no text properties
+
+ * lisp/net/rcirc.el (rcirc-mode): Remove text properties from
+ rcirc-buffer-alist keys
+
+2021-07-24 Michael Albinus <michael.albinus@gmx.de>
+
+ Add Tramp support for yubikey (bug#49714)
+
+ * lisp/net/tramp.el (tramp-yubikey-regexp): New defcustom.
+ (tramp-action-show-and-confirm-message): New defun.
+
+ * lisp/net/tramp-sh.el (tramp-actions-before-shell)
+ (tramp-actions-copy-out-of-band): Add `tramp-yubikey-regexp' action.
+
+2021-07-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust tab-bar to the new mode-line-misc-info value
+
+ * lisp/tab-bar.el (tab-bar--define-keys): Adjust to the new
+ default value for `mode-line-misc-info'.
+
+2021-07-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove duplicated NEWS entries
+
+2021-07-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make 's' in *Help* work for Lisp-defined variables again
+
+ * lisp/help-fns.el (describe-variable): Make the `s' command work
+ for Lisp-defined variables again (bug#39121).
+
+2021-07-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem when moving files called ~ to the trash
+
+ * lisp/files.el (move-file-to-trash): Construct the trash file
+ name safely (bug#49711). This makes (move-file-to-trash "/tmp/~")
+ etc work.
+
+2021-07-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new function `directory-append'
+
+ * doc/lispref/files.texi (Directory Names): Document it, and
+ remove the concat-based file concatenation description.
+ * lisp/emacs-lisp/shortdoc.el (file-name): Add. And add more
+ expand-file-name examples.
+
+ * src/fileio.c (Fdirectory_append): New function.
+
+2021-07-24 Philip Kaludercic <philipk@posteo.net>
+
+ Generate no message when activating rcirc-omit-mode
+
+ * lisp/net/rcirc.el (rcirc-omit-mode): Remove (message ...) expressions
+
+2021-07-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the test for auto-mode-alist from .dir-local.el stricter
+
+ * lisp/files.el (set-auto-mode--dir-local-valid-p): New function.
+ (set-auto-mode--apply-alist): Use it as a stricter test.
+
+2021-07-23 Eli Zaretskii <eliz@gnu.org>
+
+ Improve recently added documentation
+
+ * etc/NEWS: Improve wording of a recently added entry.
+
+ * doc/misc/smtpmail.texi (Queued delivery): Fix typo.
+
+2021-07-23 Alex Bochannek <alex@bochannek.com>
+
+ Fix bug#49699
+
+ * lisp/net/tramp-sh.el (tramp-scp-strict-file-name-checking):
+ Adapt check for macOS. (Bug#49699)
+
+2021-07-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix typo in set-auto-mode--apply-alist
+
+ * lisp/files.el (set-auto-mode--apply-alist): Fix typo in
+ ad5faa424a5 (bug#49712).
+
+2021-07-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow storing SMTP variables when queueing mail
+
+ * doc/misc/smtpmail.texi (Queued delivery): Document it (bug#49709).
+
+ * lisp/gnus/message.el (message-multi-smtp-send-mail): Store
+ variables.
+
+ * lisp/mail/smtpmail.el (smtpmail-queue-mail): Mention it.
+ (smtpmail-store-queue-variables): New variable.
+ (smtpmail-send-it): Store SMTP variables if requested.
+ (smtpmail-send-queued-mail): Restore variables.
+
+2021-07-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix do-auto-fill thinko introduced earlier today
+
+ * lisp/simple.el (do-auto-fill): `current-fill-column' returns nil
+ to signal that we should fill.
+
+2021-07-23 Tom Tromey <tom@tromey.com>
+
+ Add auto-mode-alist functionality to .dir-locals.el
+
+ * doc/emacs/custom.texi (Directory Variables): Document
+ auto-mode-alist in .dir-locals.el (Bug#18721)
+ * doc/emacs/modes.texi (Choosing Modes): Update.
+ * lisp/files.el (set-auto-mode--apply-alist): New function,
+ from set-auto-mode.
+ (set-auto-mode): Check directory locals for auto-mode-alist.
+ (dir-locals-collect-variables): Add "predicate" parameter.
+ (hack-dir-local--get-variables): New function, from
+ hack-dir-local-variables.
+ (hack-dir-local-variables): Call hack-dir-local--get-variables.
+ * test/lisp/files-resources/.dir-locals.el: New file.
+ * test/lisp/files-resources/whatever.quux: New file.
+ * test/lisp/files-tests.el (files-tests-data-dir): New variable.
+ (files-test-dir-locals-auto-mode-alist): New test.
+
+2021-07-23 Jean Forget <J2N-FORGET@orange.fr>
+
+ Add more support for the French Revolutionary Calendar
+
+ * lisp/calendar/cal-french.el (calendar-french-feasts-array): New
+ variable (bug#19174).
+ (calendar-french-trim-feast): New function.
+ (calendar-french-date-string, calendar-french-goto-date):
+ (calendar-french-goto-date): Use them.
+
+ http://datetime.mongueurs.net/Histoire/s-c/01-g.en.html
+ https://metacpan.org/pod/DateTime::Calendar::FrenchRevolutionary#Internet
+
+2021-07-23 Mattias Engdegård <mattiase@acm.org>
+
+ Off-by-one error in compilation rule end-column function (bug#49624)
+
+ * lisp/progmodes/compile.el (compilation-error-properties):
+ When the end-column parameter of a compilation message rule
+ (in compilation-error-regexp-alist[-alist]) is a function, treat its
+ return value as if it were matched by the regexp, which is how it is
+ documented to work, and how all other parameters work.
+
+2021-07-23 Mattias Engdegård <mattiase@acm.org>
+
+ Warn about arity errors in inlining calls (bug#12299)
+
+ Wrong number of arguments in inlining function calls (to `defsubst` or
+ explicitly using `inline`) did not result in warnings, or in very
+ cryptic ones.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand): Add calls
+ to `byte-compile--check-arity-bytecode`.
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-emit-callargs-warn)
+ (byte-compile--check-arity-bytecode): New functions.
+ (byte-compile-callargs-warn): Use factored-out function.
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-callargs-defsubst.el:
+ * test/lisp/emacs-lisp/bytecomp-tests.el ("warn-callargs-defsubst.el"):
+ New test case.
+
+2021-07-23 F. Jason Park <jp@neverwas.me>
+
+ Remove text props from callback args in erc-button
+
+ * lisp/erc/erc-button.el (erc-button-add-buttons-1): Remove text
+ properties from strings stored in `erc-data' and passed to
+ `erc-callback'
+ (both text properties themselves) (bug#49704). This reduces
+ memory usage in erc buffers (which are long-lived and can become
+ very large).
+
+2021-07-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ declare-function doc string clarification about FILE
+
+ * lisp/subr.el (declare-function): Mention that FILE can be nil
+ (bug#21466).
+
+2021-07-23 Stefan Kangas <stefan@marxist.se>
+
+ Make nil value of fill-column obsolete
+
+ * lisp/textmodes/fill.el (current-fill-column): Make nil value of
+ 'fill-column' obsolete. (Bug#22847)
+ (current-fill-column--has-warned): New variable to track warning.
+ * lisp/simple.el (do-auto-fill): Remove handling of nil return value
+ from 'current-fill-column'.
+ * etc/NEWS: Announce obsoletion of this usage.
+
+2021-07-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust time-tests.el to bug#30056
+
+ * test/lisp/time-tests.el (time-tests-display-time-update): Adjust
+ test (bug#30056).
+
+2021-07-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move mode-line NEWS items to a common section
+
+2021-07-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ 'global-mode-string' elements should have a space at the end
+
+ * lisp/time.el (display-time-string-forms):
+ * lisp/battery.el (battery-mode-line-format): Add a space to the
+ end (bug#30056).
+ * lisp/bindings.el (mode-line-misc-info): Remove space from end.
+ This will make the default format have one space before the
+ line-of-dashes (instead of two) on terminals.
+
+2021-07-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix an rcirc merge problem
+
+ * lisp/net/rcirc.el (rcirc-get-server-method)
+ (rcirc-get-server-password): Remove double definition after merge.
+
+2021-07-23 Eli Zaretskii <eliz@gnu.org>
+
+ MS-Windows followup to recent emacsclient changes
+
+ * nt/gnulib-cfg.mk (OMIT_GNULIB_MODULE_file-has-acl): Set to true
+ to avoid compiling file-has-acl.c on MS-Windows.
+
+2021-07-23 Paul Eggert <eggert@cs.ucla.edu>
+
+ Redo emacsclient socket symlink-attack checking
+
+ * admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
+ * lib/file-has-acl.c: New file, copied from Gnulib.
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+ * lib-src/emacsclient.c: Include acl.h, for file_has_acl.
+ (O_PATH): Default to O_SEARCH, which is good enough here.
+ (union local_sockaddr): New type.
+ (socket_status): Remove, replacing with ...
+ (connect_socket): New function. All callers changed.
+ This function checks for ownership and permissions issues with the
+ parent directory of the socket file, instead of checking the
+ owner of the socket (which does not help security).
+ (socknamesize): Move to file scope.
+ (local_sockname): New arg S. No need to pass socknamesize.
+ UID arg is now uid_t. All callers changed. Get file descriptor
+ of parent directory of socket, to foil some symlink attacks.
+ Do not follow symlinks to that directory.
+ (set_local_socket): Create the socket here instead of on
+ each attempt to connect it. Fall back from XDG_RUNTIME_DIR
+ to /tmp only if the former fails due to ENOENT. Adjust
+ permission-failure diagnostic to match changed behavior.
+
+ This addresses Bug#33847, which complained about emacsclient in a
+ safer XDG environment not connecting to an Emacs server running in
+ a less-safe environment outside XDG. The patch fixes a
+ longstanding issue with emacsclient permission checking.
+ It’s ineffective to look at the permission of the socket file
+ itself; on some platforms, these permissions are ignored anyway.
+ What matters are the permissions on the parent directory of the
+ socket file, as these are what make symlink attacks possible.
+ Change the permissions check accordingly, and also refuse to
+ follow symlinks to that parent directory. These changes make it
+ OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
+ traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
+ universally sticky nowadays.
+
+2021-07-23 Philip Kaludercic <philipk@posteo.net>
+
+ Merge branch 'feature/rcirc-update'
+
+2021-07-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make erc recognize `foo*' as a function Lisp symbol
+
+ * lisp/erc/erc-button.el (erc-button-alist): Add some more chars
+ to the `foo' button regexp (bug#49690).
+
+2021-07-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make supersession warnings work again
+
+ * src/filelock.c (lock_file): Fix thinko in lock_file in 2ad34bcea4e
+ (bug#49701).
+
+2021-07-22 Eli Zaretskii <eliz@gnu.org>
+
+ Fix display of line/wrap-prefix when there's a display property at BOL
+
+ * src/xdisp.c (get_line_prefix_it_property): New function.
+ (handle_line_prefix): Call 'get_line_prefix_it_property' instead
+ of 'get_it_property', to examine also the property of the buffer
+ text underlying the display or overlay string. (Bug#49695)
+
+2021-07-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make revert-buffer preserve buffer-readedness
+
+ * lisp/files.el (revert-buffer): Preserve buffer-readedness
+ (bug#35166).
+
+2021-07-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ `term-char-mode' doc string clarification
+
+ * lisp/term.el (term-char-mode): Document behaviour (bug#49186).
+
+2021-07-22 Dmitry Gutov <dgutov@yandex.ru>
+
+ Bind the GIT_LITERAL_PATHSPECS environment variable
+
+ * lisp/vc/vc-git.el (vc-git-command):
+ (vc-git--call): Ensure that git interprets file names literally
+ (bug#39452).
+
+2021-07-22 Sergey Organov <sorganov@gmail.com> (tiny change)
+
+ Avoid failing in desktop-clear due to killed buffers
+
+ * lisp/desktop.el (desktop-clear): check that buffer is not already
+ killed before attempting to kill it. A buffer might become killed as
+ part of regular operation as a side-effect of killing another buffer,
+ and then attempt to kill it again causes error (bug#49692).
+
+2021-07-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove the (value) bits from cus-start Customize strings
+
+ * lisp/cus-start.el (standard): Don't mention the Lisp values in
+ the choice strings, because that's just confusing in the Customize
+ interface (bug#49687).
+
+2021-07-22 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid byte-compilation warning
+
+ * test/src/buffer-tests.el (buffer-tests-inhibit-buffer-hooks):
+ Avoid byte-compiler warning. (Bug#49667)
+
+2021-07-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move generalized variable specs from cl-lib.el to gv.el
+
+ * lisp/emacs-lisp/cl-lib.el: Move all the generalized variable
+ specifications from cl-lib.el...
+ * lisp/emacs-lisp/gv.el: ... to gv.el. This will make things like
+ `(setf (getenv "FOO") "BAR")' work without requiring anything,
+ since `setf' lives in gv.el (bug#49651).
+
+2021-07-21 Yan Gajdos <yan@gajdos.info> (tiny change)
+
+ Make vc-git-mode-line-string more robust
+
+ * lisp/vc/vc-git.el (vc-git-mode-line-string): Make function more
+ robust (bug#49683). It could previously error out under certain
+ conditions, like moving directories in and out of the
+ VC-controlled tree.
+
+2021-07-21 Illia Ostapyshyn <ilya.ostapyshyn@gmail.com> (tiny change)
+
+ * lisp/cus-start.el: Add mode-line-compact to Customize
+
+ * lisp/cus-start.el (standard): Make `mode-line-compact' into a
+ user option (bug#49687).
+
+2021-07-21 Juri Linkov <juri@linkov.net>
+
+ Improve docstring of context-menu-functions and add eww-context-menu
+
+ * lisp/mouse.el (context-menu-functions): Explain function args in docstring.
+
+ * lisp/net/eww.el (eww-context-menu): New function.
+ (eww-mode): Add it to context-menu-functions.
+
+ * lisp/info.el (Info-context-menu): Move history items higher.
+
+ * lisp/progmodes/prog-mode.el (prog-context-menu): Add menu items
+ in the middle of the menu after the region menu items.
+
+2021-07-21 Juri Linkov <juri@linkov.net>
+
+ Change the order of context-menu-functions and add more context menus.
+
+ * lisp/mouse.el (context-menu-functions): Update default list.
+ (context-menu-overriding-function): Remove variable.
+ (context-menu-map): Reverse the order.
+ (context-menu-global, context-menu-local, context-menu-minor): New functions.
+ (context-menu-undo, context-menu-region): Add separators.
+ Use define-key-after instead of bindings--define-key.
+ (context-menu-entry): New variable.
+ (context-menu-mode): Use it.
+
+ * lisp/dired.el (dired-context-menu): New function.
+ (dired-mode): Add it to context-menu-functions.
+
+ * lisp/info.el (Info-context-menu): Reorder.
+
+ * lisp/net/goto-addr.el (goto-address-at-mouse):
+ Rename from goto-address-at-click.
+ (goto-address-context-menu): Use goto-address-at-mouse.
+
+ * lisp/progmodes/prog-mode.el (prog-context-menu): New function.
+ (prog-mode): Add it to context-menu-functions.
+
+2021-07-21 Logan Perkins <logan@lp-programming.com>
+
+ Make input of multi-key inputs in different emacsclients more logical
+
+ * src/keyboard.c (read_key_sequence): Don't continue the input of
+ multi-key commands in one emacsclient in another (bug#39687).
+
+2021-07-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/eval.c (signal_quit_p): Fix the usual int/Lisp_Object mixup
+
+2021-07-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/macroexp.el (macroexp-warn-and-return): Add arg `category`
+
+ Use it to obey `byte-compile-warnings`.
+
+ (macroexp--warn-wrap): Add arg `category`.
+ (macroexp-macroexpand, macroexp--expand-all): Use it.
+
+ * lisp/emacs-lisp/cconv.el (cconv--convert-funcbody, cconv-convert):
+ Mark the warnings as `lexical`.
+
+ * lisp/emacs-lisp/eieio-core.el (eieio-oref, eieio-oref-default)
+ (eieio-oset-default):
+ * lisp/emacs-lisp/eieio.el (defclass): Adjust to new calling convention.
+
+2021-07-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `C-g' after `M-x' not give a backtrace unless required
+
+ * src/eval.c (signal_quit_p): New function.
+ (maybe_call_debugger): React to all `quit' signals (bug#49675).
+
+ * src/keyboard.c (cmd_error_internal, menu_item_eval_property_1):
+ Ditto.
+
+2021-07-21 Jashank Jeremy <jashank@rulingia.com.au>
+
+ Speed up by storing frame faces in hash tables instead of alists
+
+ * src/frame.h (struct frame): Add face_hash_table, remove face_alist.
+ (fset_face_hash_table): New function.
+ (fset_face_alist): Remove.
+ * src/frame.c (make_frame): Initialize f->face_hash_table.
+ (Fmake_terminal_frame): Update to work with hash tables instead of
+ alists.
+ * src/xfaces.c (lface_from_face_name_no_resolve):
+ (Finternal_make_lisp_face):
+ (update_face_from_frame_parameter): Update to work with hash tables
+ instead of alists.
+ (Fframe_face_hash_table): New function.
+ (Fframe_face_alist): Move to faces.el as frame-face-alist.
+ (syms_of_xfaces): Add frame_face_hash_table.
+
+ * lisp/progmodes/elisp-mode.el (elisp--eval-defun-1):
+ * lisp/frame.el (frame-set-background-mode): Update to work with hash
+ tables instead of alists.
+ * lisp/faces.el (face-new-frame-defaults): Mark obsolete.
+ (face-list): Update to use face--new-frame-defaults.
+ (frame-face-alist): Moved here from src/xfaces.c.
+ (x-create-frame-with-faces): Update to handle subtle semantic change
+ to how frame faces propagate, which otherwise breaks frame creation
+ with reverse video enabled (bug#41200).
+
+ Reworked from a patch by Clément Pit-Claudel <clement.pitclaudel@live.com>.
+
+2021-07-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * doc/lispref/display.texi (Overlay Properties): Tweak further
+
+ The "character after point" is not as important as point itself
+
+2021-07-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some "is"es from previous json checkin
+
+ * lisp/subr.el (json-available-p):
+ * doc/lispref/text.texi (Parsing JSON): Fix typo in last check-in.
+
+2021-07-21 Stefan Kangas <stefan@marxist.se>
+
+ Factor out char_table_ref_simple for readability
+
+ * src/chartab.c (char_table_ref_simple): New function...
+ (sub_char_table_ref_and_range, char_table_ref_and_range):
+ ...factored out from here. (bug#45550).
+
+2021-07-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix final test for invalid base64url chars
+
+ * src/fns.c (base64_decode_1): Fix test for invalid base64url
+ (bug#45562). Noted by Andreas Schwab.
+
+2021-07-21 Pankaj Jangid <pankaj@codeisgreat.org>
+
+ Fixed a typo in Gnus manual
+
+ * doc/misc/gnus.texi (Washing Mail): Fixed typo
+
+2021-07-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix bug-reference.el compilation warning
+
+ * lisp/progmodes/bug-reference.el (bug-reference-mode): Silence a
+ compilation warning (bug#49677).
+
+2021-07-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Restore evaluation logic in dired-guess-default
+
+ * lisp/dired-x.el (dired-guess-default): Restore the `eval' bits
+ also removed in a previous commit (bug#48071).
+
+2021-07-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix dired-guess-default logic after previous change
+
+ * lisp/dired-x.el (dired-guess-default): Restore previous logic --
+ require matches for all files (bug#48071).
+
+2021-07-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add json-available-p
+
+ * doc/lispref/text.texi (Parsing JSON): Document it.
+ * lisp/subr.el (json-available-p): New function (bug#49660).
+
+2021-07-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention rear-advance in relation to the keymap overlay property
+
+ * doc/lispref/display.texi (Overlay Properties): Mention the
+ effect of REAR-ADVANCE (bug#459).
+
+2021-07-21 Mattias Engdegård <mattiase@acm.org>
+
+ Fix mistake in `quote` optimiser
+
+ Found by Pip Cet.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-quote): Fix mistake that
+ made this optimiser ineffective at removing quoting of nil, t, and
+ keywords. The only obvious consequence is that we no longer need...
+ (byte-optimize-form): ...a 'nil => nil normalising step here; remove.
+ (byte-optimize-form-code-walker): Make the compiler warn about (quote).
+
+2021-07-20 Juri Linkov <juri@linkov.net>
+
+ Add new mode context-menu-mode and use it in info.el and goto-addr.el
+
+ * lisp/mouse.el (context-menu-functions): New defcustom.
+ (context-menu-overriding-function): New function.
+ (context-menu-filter-function): New defcustom.
+ (context-menu-map): New function.
+ (context-menu-undo, context-menu-region): New menu functions.
+ (context-menu-mode): New mode.
+
+ * lisp/info.el (Info-context-menu): New function.
+ (Info-mode): Add Info-context-menu to context-menu-functions.
+
+ * lisp/net/goto-addr.el (goto-address-context-menu): New function.
+ (goto-address-at-click): New command.
+ (goto-address-mode): Add goto-address-context-menu to context-menu-functions.
+
+2021-07-20 Juri Linkov <juri@linkov.net>
+
+ * lisp/button.el (button-map): Bind [follow-link] to 'mouse-face' (bug#49626)
+
+2021-07-20 Mattias Engdegård <mattiase@acm.org>
+
+ Strength-reduce (eq X nil) to (not X)
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-eq): New optimisation,
+ which results in better test and branch code generation where it
+ applies.
+
+2021-07-20 Mattias Engdegård <mattiase@acm.org>
+
+ Count (not X) as a switch condition
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile--cond-switch-prefix):
+ Treat (not VAR) and (null VAR) as (eq VAR nil) when computing the
+ extent of switch ops.
+
+2021-07-20 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/shadowfile.el (shadow-homedir): Add slash.
+
+ (shadow-contract-file-name): Use it. Bug#49596.
+
+2021-07-20 Eli Zaretskii <eliz@gnu.org>
+
+ Fix documentation of a recent changeset
+
+ * lisp/autorevert.el (auto-revert-mode):
+ * lisp/files.el (revert-buffer): Doc fix. (Bug#49661)
+
+2021-07-20 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Bug#49636
+
+ * test/lisp/net/tramp-tests.el (tramp-test39-make-lock-file-name):
+ Let-bind `auto-save-default'. (Bug#49636)
+
+2021-07-20 Konstantin Kharlamov <Hi-Angel@yandex.ru>
+
+ Improve auto-revert-mode and revert-buffer doc strings
+
+ * lisp/autorevert.el (auto-revert-mode):
+ * lisp/files.el (revert-buffer): Mention that there is
+ revert-buffer-with-fine-grain that is better suited for markers
+ preservation (bug#49661).
+
+2021-07-20 jakanakaevangeli <jakanakaevangeli@chiru.no>
+
+ Make `kill-all-local-variables' also remove lambda from hooks
+
+ * src/buffer.c (reset_buffer_local_variables): Also remove
+ non-symbol elements from hook variables (bug#46407).
+
+2021-07-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make dired-guess-default return all matching programs
+
+ * lisp/dired-x.el (dired-guess-default): Return all matching
+ programs (bug#48071).
+
+2021-07-20 Ioannis Kappas <ioannis.kappas@gmail.com>
+
+ Allow installing packages with DOS line endings
+
+ * lisp/emacs-lisp/package.el (package-install-from-buffer): Allow
+ installing files with different line ending conventions (Unix, DOS
+ and Macos) (bug#48137).
+
+2021-07-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Signal an error in json.c function if not available
+
+ * src/json.c (Fjson_serialize, Fjson_insert)
+ (Fjson_parse_string, Fjson_parse_buffer, syms_of_json): Signal
+ `json-unavailable' if jansson isn't available (bug#48228).
+
+2021-07-20 Miha Rihtaršič <miha@kamnitnik.top>
+
+ Quit minibuffers without aborting kmacros
+
+ * doc/lispref/commands.texi (Quitting): Document `minibuffer-quit'
+ (Recursive Editing): Document throwing of function values to `exit'.
+
+ * doc/lispref/errors.texi (Standard Errors): Document
+ `minibuffer-quit'
+
+ * lisp/minibuffer.el (minibuffer-quit-recursive-edit): New function.
+
+ * lisp/simple.el (minibuffer-error-function): Do not abort keyboard
+ macro execution if is minibuffer-quit is signaled (bug#48603).
+ * src/data.c (syms_of_data): New error symbol `minibuffer-quit'
+
+ * src/keyboard.c (recursive_edit_1): Implement throwing of function
+ values to `exit`. In that case, the function will be called without
+ arguments before returning from the command loop.
+ (cmd_error):
+ (Fcommand_error_default_function): Do not abort keyboard macro
+ execution if minibuffer-quit is signaled.
+ (command_loop_2): New argument HANDLERS.
+
+ * src/macros.c (Fexecute_kbd_macro): Use command_loop_2 instead of
+ command_loop_1.
+
+ * src/minibuf.c (Fabort_minibuffers): Use it.
+
+2021-07-20 Kenichi Handa <handa@gnu.org>
+
+ Fix problem with certain fonts in ftfont_shape_by_flt
+
+ * src/ftfont.c (ftfont_shape_by_flt): Fix problem with unusual OTF
+ tables in fonts (bug#49066).
+
+2021-07-20 Earl Hyatt <okamsn@protonmail.com>
+
+ Add commands 'kill-matching-lines' and 'copy-matching-lines'
+
+ * doc/emacs/search.texi: Document these additions.
+ * lisp/replace.el:
+ Add the commands 'kill-matching-lines' and 'copy-matching-lines'.
+
+ 'kill-matching-lines' is like 'flush-lines', but adds the lines to the
+ kill ring as a single string, keeping line endings.
+ 'copy-matching-lines' is like 'kill-matching-lines', but only copies
+ those lines instead of killing them.
+
+2021-07-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak example in Function Indirection node in the lispref manual
+
+ * doc/lispref/eval.texi (Function Indirection): Make example more
+ robust (bug#49647). Suggested by Scott Marks
+ <scott.c.marks@gmail.com>.
+
+2021-07-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Put command line file names and mouse dragging onto 'file-name-history'
+
+ * lisp/dnd.el (dnd-open-local-file): Add file to history.
+ * lisp/files.el (file-name-history--add): New function (bug#12915).
+
+ * lisp/startup.el (command-line-1): Add file to history.
+
+2021-07-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention `overlays-in' in the `overlays-at' doc string
+
+ * src/buffer.c (Foverlays_at): Mention `overlays-in' in the doc
+ string (bug#459).
+
+2021-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make wdired work better in narrowed-to buffers
+
+ * lisp/wdired.el (wdired--before-change-fn):
+ (wdired--restore-properties): Widen before doing anything so that
+ we get all the changed bits (bug#49124).
+
+2021-07-19 Ivan Sokolov <ivan-p-sokolov@ya.ru>
+
+ Add function for filtering ANSI sequences when compiling
+
+ * lisp/ansi-color.el (ansi-color-for-compilation-mode): New user
+ option (bug#49609).
+ (ansi-color-compilation-filter): New function.
+
+2021-07-19 Eli Zaretskii <eliz@gnu.org>
+
+ Fix typos in a recent change
+
+ * src/buffer.c (Fmake_indirect_buffer): Fix a typo in a recent
+ change.
+
+ * doc/lispref/buffers.texi (Indirect Buffers): Fix punctuation.
+
+2021-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the `s' command in *Help* work for Lisp variables defined in C
+
+ * lisp/help-fns.el (describe-variable): Store the type.
+ * lisp/help-mode.el (help-view-source): Use the type. This fixes
+ the problem when looking for a variable defined in a C file.
+
+2021-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add inhibit-buffer-hooks to `make-indirect-buffer'
+
+ * doc/lispref/buffers.texi (Indirect Buffers): Document it (bug#49160).
+
+ * src/buffer.c (Fmake_indirect_buffer): Allow controlling whether
+ to inhibit buffer hooks.
+
+2021-07-19 dickmao <none>
+
+ Make make-indirect-buffer inherit inhibit-buffer-hook from base buffer
+
+ * src/buffer.c (Fmake_indirect_buffer):
+ Match base buffer's inhibit-buffer-hooks.
+ * test/src/buffer-tests.el (buffer-tests-inhibit-buffer-hooks-indirect):
+ Add a test (bug#49160).
+
+2021-07-19 Eli Zaretskii <eliz@gnu.org>
+
+ Document recent changes in 'comint-delete-output' (bug#1496)
+
+ * doc/emacs/misc.texi (Shell Mode): Document the new optional
+ behavior of 'C-c C-o'.
+
+ * etc/NEWS: Call out the new behavior of 'C-c C-o'.
+
+2021-07-19 Gabriel do Nascimento Ribeiro <gabriel376@hotmail.com>
+
+ Use 'remember-buffer' in remember.el doc strings.
+
+ * lisp/textmodes/remember.el (remember-initial-contents)
+ (remember-before-remember-hook, remember-destroy): Refer to
+ `remember-buffer'.
+
+ * lisp/textmodes/remember.el (remember-buffer): Make into
+ defcustom (bug#49373).
+
+2021-07-19 Gabriel do Nascimento Ribeiro <gabriel376@hotmail.com>
+
+ Use 'remember-buffer' in remember.el doc strings.
+
+ * lisp/textmodes/remember.el (remember-initial-contents)
+ (remember-before-remember-hook, remember-destroy): Refer to
+ `remember-buffer'.
+
+ * lisp/textmodes/remember.el (remember-buffer): Make into
+ defcustom (bug#49373).
+
+2021-07-19 Madhu <enometh@meer.net> (tiny change)
+
+ Propagate asynchronousness correctly when using proxies in url.el
+
+ * lisp/url/url.el (url-retrieve-internal): Propagate
+ asynchronousness correctly when using a proxy (bug#49570).
+
+2021-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix infloop in woman-file-name
+
+ * lisp/woman.el (woman-file-name): Fix infloop for non-existent
+ manual page (bug#414).
+
+2021-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow comint-delete-output to save the output on the kill ring
+
+ * lisp/comint.el (comint-delete-output): Allow saving the output
+ to the kill ring (bug#1496).
+
+2021-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix documentation of mouse-leave-buffer-hook
+
+ * doc/lispref/hooks.texi (Standard Hooks): Ditto.
+
+ * src/callint.c (syms_of_callint): Document the actual usage of
+ `mouse-leave-buffer-hook' (bug#2932).
+
+2021-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use make-separator-line in shortdoc
+
+ * lisp/simple.el (separator-line): Tweak definition to not be so
+ overwhelming.
+
+ * lisp/emacs-lisp/shortdoc.el (shortdoc-separator): Removed.
+ (shortdoc-display-group): Use make-separator-line.
+
+2021-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new function for separator lines
+
+ * lisp/help-fns.el (describe-symbol): Use it.
+
+ * lisp/help.el (describe-key): Use it.
+
+ * lisp/simple.el (separator-line): New face.
+ (make-separator-line): New function (bug#49630).
+
+2021-07-18 Eli Zaretskii <eliz@gnu.org>
+
+ Fix documentation of a recent changeset (bug#5003)
+
+ * lisp/files.el (safe-local-variable-values)
+ (ignored-local-variable-values): Doc fix.
+ (ignored-local-variable-values): Add :version tag.
+
+ * doc/emacs/custom.texi (Safe File Variables): Mention
+ 'ignored-local-variable-values'.
+ * doc/lispref/variables.texi (File Local Variables): Fix wording.
+
+ * etc/NEWS: Improve wording of the 'ignored-local-variable-values'
+ entry.
+
+2021-07-18 Mattias Engdegård <mattiase@acm.org>
+
+ Count compile errors when FILE is a function
+
+ * lisp/progmodes/compile.el (compilation-parse-errors):
+ Don't omit messages from the error count when FILE is a function
+ rather than a regexp match number.
+
+2021-07-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify event-convert-list doc string
+
+ * src/keyboard.c (Fevent_convert_list): Clarify that the base type
+ returned isn't always the same (bug#7631).
+
+2021-07-18 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ Add doc string to time-stamp-tests that didn't have one
+
+ * test/lisp/time-stamp-tests.el (formatz-generate-tests,
+ formatz-%z-spotcheck): Add doc strings to tests.
+
+2021-07-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow ignoring local variable values permanently
+
+ * doc/lispref/variables.texi (File Local Variables): Document it.
+
+ * lisp/files.el (ignored-local-variable-values): New user option
+ (bug#5003).
+ (hack-local-variables-confirm): Allow ignoring permanently.
+ (hack-local-variables-filter): Ignore the permanently ignored
+ variables.
+
+2021-07-18 Michael Albinus <michael.albinus@gmx.de>
+
+ Make remote file locks more robust
+
+ * lisp/net/tramp.el (tramp-handle-write-region):
+ * lisp/net/tramp-adb.el (tramp-adb-handle-write-region):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-write-region):
+ * lisp/net/tramp-sshfs.el (tramp-sshfs-handle-write-region):
+ Make file locks more robust.
+
+ * test/lisp/net/tramp-tests.el (tramp-test39-make-lock-file-name):
+ Rename and extend.
+
+2021-07-18 Naofumi Yasufuku <naofumi@yasufuku.dev> (tiny change)
+
+ Make remote file locks more robust. (Bug#49621)
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-write-region): Make file
+ locks more robust. (Bug#49621)
+
+2021-07-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Maintain a list of terminal buffers in the menu
+
+ * lisp/term.el (term--update-term-menu): New function (bug#5641).
+ (term-mode): Use it to list terminal buffers.
+
+2021-07-18 Eli Zaretskii <eliz@gnu.org>
+
+ Fix display of mode-line with bidi formatting controls
+
+ * src/xdisp.c (face_before_or_after_it_pos): Reimplement the bidi
+ iteration to find the character after the current in visual order.
+ (Bug#49562)
+
+2021-07-18 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix problem in `shadow-define-literal-group' (Bug#49596)
+
+ * lisp/shadowfile.el (shadow-make-fullname): HOST can also be a
+ remote file name. Bug#49596.
+
+ * test/lisp/shadowfile-tests.el (auth-source-save-behavior)
+ (tramp-cache-read-persistent-data, tramp-persistency-file-name):
+ Set them globally.
+ (shadow-test06-literal-groups): Extend test.
+
+2021-07-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make indent-tabs-mode into a regular mode instead of just a variable
+
+ * lisp/simple.el (indent-tabs-mode): Make into a minor mode (bug#6276).
+
+2021-07-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't shorten comment padding if the padding isn't spaces
+
+ * lisp/newcomment.el (comment-padright): Don't shorten non-space
+ padding (bug#6822).
+ (comment-padleft): Ditto.
+
+2021-07-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix an unlikely `copyright-find-copyright' problem
+
+ * lisp/emacs-lisp/copyright.el (copyright-find-copyright): Make
+ the copyright matcher more robust (bug#7179).
+
+2021-07-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous grep-file-at-point change
+
+ * lisp/progmodes/grep.el (grep-file-at-point): Fix previous change.
+
+2021-07-17 Lennart Borgman <lennart.borgman@gmail.com>
+
+ Add new function 'grep-file-at-point'
+
+ * lisp/progmodes/grep.el (grep-file-at-point): New function to
+ return the file name at point (bug#8252).
+
+2021-07-17 Karthik Chikmagalur <karthikchikmagalur@gmail.com> (tiny change)
+
+ Enhance pcomplete support for xargs
+
+ * lisp/pcmpl-unix.el (pcomplete/xargs): Add support for completing xargs
+ options, including the ability to distinguish them from the command
+ xargs runs (bug#49603).
+
+2021-07-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make 'n'/'p' work again in shortdoc after previous changes
+
+ * lisp/emacs-lisp/shortdoc.el (shortdoc--goto-section): Adjust to
+ changes in how the text properties are inserted in 22a5482ab6
+ (bug#49605). Also make into a regular function.
+
+2021-07-16 akater <nuclearspace@gmail.com>
+
+ EIEIO: Prevent excessive evaluation of :initform
+
+ * lisp/emacs-lisp/eieio.el (initialize-instance):
+ Do not evaluate initform of a slot when initarg for the slot is provided,
+ according to the following sections of CLHS:
+ - Object Creation and Initialization
+ - Initialization Arguments
+ - Defaulting of Initialization Arguments
+ - Rules for Initialization Arguments
+
+ * test/lisp/emacs-lisp/eieio-tests/eieio-tests.el:
+ Add corresponding tests
+ Fix a typo
+
+2021-07-16 Mattias Engdegård <mattiase@acm.org>
+
+ Define revert-buffer-function for *Memory Report*
+
+ * lisp/emacs-lisp/memory-report.el (memory-report):
+ Allow the memory report buffer to be updated by pressing 'g'.
+
+2021-07-16 Michael Albinus <michael.albinus@gmx.de>
+
+ Add lock-file-mode
+
+ * doc/emacs/files.texi (Interlocking):
+ * doc/lispref/files.texi (File Locks):
+ * etc/NEWS: Add lock-file-mode.
+
+ * lisp/files.el (lock-file-name-transforms)
+ (remote-file-name-inhibit-locks): Move down.
+ (lock-file-mode): New minor mode.
+
+2021-07-16 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 7ac411ae2c (origin/emacs-27) ; * src/data.c (Fcar, Fcdr): Doc fix.
+ 0d9e1826f7 One more minor update of the Emacs manual for 19th printing
+ 92616d30e0 ; Fix let-alist Texinfo markup
+ c13acf8e34 ; * doc/emacs/mule.texi (International Chars): Mention 'de...
+
+2021-07-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify emacsclient Options node in the Emacs manual
+
+ * doc/emacs/misc.texi (emacsclient Options): Don't claim that
+ emacsclient searches for a socket name (bug#13319).
+
+2021-07-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new user option 'query-about-changed-file'
+
+ * doc/emacs/files.texi (Visiting): Document it.
+ * lisp/files.el (query-about-changed-file): New user option (bug#10775).
+ (find-file-noselect): Use it.
+
+2021-07-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix lock-file-name-transforms build problem
+
+ * lisp/files.el (lock-file-name-transforms): Remove
+ custom-initialize-delay to fix build problem (bug#49507).
+
+2021-07-16 Eli Zaretskii <eliz@gnu.org>
+
+ Fix wording in a recent ELisp manual change
+
+ * doc/lispref/tips.texi (Coding Conventions): Fix wording in a
+ recent change. (Bug#21440)
+
+2021-07-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow hiding variables in Customize
+
+ * lisp/cus-edit.el (custom-toggle-hide-variable): Allow closing an
+ option even if there are unsaved changes (bug#11655).
+
+2021-07-16 Remington Furman <remington@remcycles.net> (tiny change)
+
+ Make `number-at-point' work for more hex numbers
+
+ * lisp/thingatpt.el (number-at-point): Rewrite to actually catch
+ the hex numbers (bug#49588).
+
+2021-07-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify -unload-feature in Coding Conventions
+
+ * doc/lispref/tips.texi (Coding Conventions): Clarify when an
+ unload function is useful (bug#21440).
+
+2021-07-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a couple more shell-tests-split-string tests
+
+2021-07-15 Glenn Morris <rgm@gnu.org>
+
+ Improve recent jka-compr-compression-info-list change
+
+ * lisp/jka-cmpr-hook.el (jka-compr-compression-info-list):
+ Document previous change, and fix :type.
+
+2021-07-15 Tassilo Horn <tsdh@gnu.org>
+
+ Add bug-reference support for Codeberg projects
+
+ * lisp/progmodes/bug-reference.el (bug-reference-setup-from-vc-alist):
+ Add support for codeberg.org bug and pull request references.
+ * doc/emacs/maintaining.texi (Bug Reference): Mention that bug and
+ pull request references for codeberg projects are supported.
+
+2021-07-15 Tassilo Horn <tsdh@gnu.org>
+
+ Add support for sourcehut to bug-reference.el
+
+ * lisp/progmodes/bug-reference.el (bug-reference-setup-from-vc-alist):
+ Add support for bug references like #17 and ~user/project#19 for
+ sourcehut (sr.ht).
+ * doc/emacs/maintaining.texi (Bug Reference): Document sourcehut
+ support.
+
+2021-07-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add more car/cdr examples to shortdoc
+
+ * lisp/emacs-lisp/shortdoc.el (list): Add more car/cdr examples.
+
+2021-07-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the shortdoc link action in *Help* buffers
+
+ * lisp/emacs-lisp/shortdoc.el (shortdoc-display-group): Allow
+ taking an optional parameter to place point on a specific function.
+ (shortdoc--display-function): Go to the function in question in
+ the shortdoc buffer.
+
+2021-07-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new user option to abbreviate file names in save-place
+
+ * lisp/saveplace.el (save-place-abbreviate-file-names): New user
+ option (bug#13286).
+ (save-place-to-alist): Use it.
+
+2021-07-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow restoring the original order in 'tabulated-list-mode'
+
+ * lisp/emacs-lisp/tabulated-list.el (tabulated-list-sort): Allow
+ restoring the original order (bug#13411).
+ (tabulated-list--sort-by-column-name): Store the original order.
+ (tabulated-list--original-order): New buffer-local variable.
+
+2021-07-15 Protesilaos Stavrou <info@protesilaos.com>
+
+ Update modus-themes to version 1.5.0
+
+ * doc/misc/modus-themes.org (Enable and load): Include internal link.
+ (Sample configuration for use-package): Update code sample.
+ (Customization Options): Update references to customization options.
+ (Option for more italic constructs): Document new variable, as an
+ alias of the deprecated 'modus-themes-slanted-constructs'.
+
+ (Option for syntax highlighting, Option for links)
+ (Option for command prompt styles, Option for mode line presentation)
+ (Option for language checkers)
+ (Option for line highlighting (hl-line-mode))
+ (Option for parenthesis matching (show-paren-mode))
+ (Option for active region, Option for the headings' overall style):
+ Update documentation to describe new possible values, expressed as a
+ list of symbols.
+
+ (Option for Org agenda constructs): Document new user option.
+
+ (Control the scale of headings): Update symbol of variable.
+
+ (Remap face with local value (DIY), Backdrop for pdf-tools (DIY)):
+ Tweak text of internal reference.
+
+ (Font configurations for Org and others (DIY)): Add internal link and
+ document how to configure the 'bold' and 'italic' faces.
+
+ (Custom Org user faces (DIY)): Minor corrections or changes to single
+ words.
+
+ (Full support for packages or face groups): Include new items.
+
+ (Notes on individual packages): Add notes on Avy hints, the colour of
+ days in 'M-x calendar', and underlines in 'compilation-mode' buffers.
+
+ (What is the best setup for legibility?): Remove single word.
+ (Acknowledgements): Update list of contributors.
+
+ * etc/themes/modus-themes.el (modus-themes-faces)
+ (modus-themes-operandi-colors, modus-themes-vivendi-colors)
+ (modus-themes-subtle-red, modus-themes-subtle-green)
+ (modus-themes-subtle-yellow, modus-themes-subtle-blue)
+ (modus-themes-subtle-magenta, modus-themes-subtle-cyan)
+ (modus-themes-subtle-neutral, modus-themes-intense-red)
+ (modus-themes-intense-green, modus-themes-intense-yellow)
+ (modus-themes-intense-blue, modus-themes-intense-magenta)
+ (modus-themes-intense-cyan, modus-themes-intense-neutral)
+ (modus-themes-refine-red, modus-themes-refine-green)
+ (modus-themes-refine-yellow, modus-themes-refine-blue)
+ (modus-themes-refine-magenta, modus-themes-refine-cyan)
+ (modus-themes-active-red, modus-themes-active-green)
+ (modus-themes-active-yellow, modus-themes-active-blue)
+ (modus-themes-active-magenta, modus-themes-active-cyan)
+ (modus-themes-fringe-red, modus-themes-fringe-green)
+ (modus-themes-fringe-yellow, modus-themes-fringe-blue)
+ (modus-themes-fringe-magenta, modus-themes-fringe-cyan)
+ (modus-themes-nuanced-red, modus-themes-nuanced-green)
+ (modus-themes-nuanced-yellow, modus-themes-nuanced-blue)
+ (modus-themes-nuanced-magenta, modus-themes-nuanced-cyan)
+ (modus-themes-special-cold, modus-themes-special-mild)
+ (modus-themes-special-warm, modus-themes-special-calm)
+ (modus-themes-diff-added, modus-themes-diff-changed)
+ (modus-themes-diff-removed, modus-themes-diff-refine-added)
+ (modus-themes-diff-refine-changed, modus-themes-diff-refine-removed)
+ (modus-themes-diff-focus-added, modus-themes-diff-focus-changed)
+ (modus-themes-diff-focus-removed, modus-themes-diff-heading)
+ (modus-themes-pseudo-header, modus-themes-mark-alt)
+ (modus-themes-mark-del, modus-themes-mark-sel, modus-themes-mark-symbol)
+ (modus-themes-heading-1, modus-themes-heading-2, modus-themes-heading-3)
+ (modus-themes-heading-4, modus-themes-heading-5, modus-themes-heading-6)
+ (modus-themes-heading-7, modus-themes-heading-8, modus-themes-hl-line)
+ (modus-themes-bold, modus-themes-slant, modus-themes-variable-pitch)
+ (modus-themes-graph-red-0, modus-themes-graph-red-1)
+ (modus-themes-graph-green-0, modus-themes-graph-green-1)
+ (modus-themes-graph-yellow-0, modus-themes-graph-yellow-1)
+ (modus-themes-graph-blue-0, modus-themes-graph-blue-1)
+ (modus-themes-graph-magenta-0, modus-themes-graph-magenta-1)
+ (modus-themes-graph-cyan-0, modus-themes-graph-cyan-1)
+ (modus-themes-lang-note, modus-themes-lang-warning)
+ (modus-themes-lang-error, modus-themes-reset-soft)
+ (modus-themes-reset-hard, modus-themes-key-binding)
+ (modus-themes-search-success, modus-themes-search-success-modeline)
+ (modus-themes-search-success-lazy): Add new ':group' specification for
+ custom faces.
+
+ (modus-themes-operandi-color-overrides)
+ (modus-themes-vivendi-color-overrides, modus-themes-bold-constructs)
+ (modus-themes-variable-pitch-headings, modus-themes-variable-pitch-ui)
+ (modus-themes-no-mixed-fonts, modus-themes-fringes)
+ (modus-themes-scale-headings, modus-themes-scale-1, modus-themes-scale-2)
+ (modus-themes-scale-3, modus-themes-scale-4, modus-themes-scale-title)
+ (modus-themes-org-blocks, modus-themes-completions)
+ (modus-themes-success-deuteranopia, modus-themes-mail-citations)
+ (modus-themes-subtle-line-numbers, modus-themes-intense-hl-line): Add
+ custom setter.
+
+ (modus-themes-scale-5, modus-themes-scale-title): Deprecate variable
+ and replace it with alias 'modus-themes-scale-title'.
+
+ (modus-themes-slanted-constructs, modus-themes-italic-constructs):
+ Deprecate variable and replace it with alias
+ 'modus-themes-italic-constructs'.
+
+ (modus-themes-org-habit, modus-themes-org-agenda): Deprecate variable
+ and make its functionality a part of 'modus-themes-org-agenda'.
+
+ (modus-themes-headings, modus-themes-mode-line, modus-themes-diffs)
+ (modus-themes-prompts, modus-themes-paren-match, modus-themes-syntax)
+ (modus-themes-links, modus-themes-region, modus-themes-lang-checkers)
+ (modus-themes-org-blocks): Make user options accept a value as a list
+ of properties.
+
+ (modus-themes--mixed-fonts, modus-themes--slant)
+ (modus-themes--fixed-pitch, modus-themes--lang-check)
+ (modus-themes--prompt, modus-themes--paren)
+ (modus-themes--syntax-foreground, modus-themes--syntax-extra)
+ (modus-themes--syntax-string, modus-themes--syntax-docstring)
+ (modus-themes--syntax-comment, modus-themes--heading-p)
+ (modus-themes--heading, modus-themes--org-habit)
+ (modus-themes--mode-line-attrs, modus-themes--link-color)
+ (modus-themes--link, modus-themes--region, modus-themes--hl-line):
+ Update internal functions to parse new values for user options.
+
+ * etc/themes/modus-operandi-theme.el,
+ etc/themes/modus-vivendi-theme.el: Bump version number.
+
+ A detailed change log is provided here (no javascript required):
+ <https://protesilaos.com/codelog/2021-07-15-modus-themes-1-5-0/>.
+
+2021-07-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Autoload `split-string-shell-command'
+
+ * lisp/shell.el (split-string-shell-command): Autoload.
+
+2021-07-15 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'shell-tests-split-string' on MS-Windows
+
+ * test/lisp/shell-tests.el (shell-tests-split-string): Skip test
+ that always fails on MS-Windows/MS-DOS.
+
+2021-07-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the `window-end' doc string
+
+ * src/window.c (Fwindow_end): Be more explicit about what the
+ position is (bug#13429).
+
+2021-07-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention more split-string-* functions in shortdoc
+
+ * lisp/emacs-lisp/shortdoc.el (string): Mention
+ split-string-and-unquote and split-string-shell-command.
+
+2021-07-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow using spaces in `inferior-lisp' command names
+
+ * lisp/progmodes/inf-lisp.el (inferior-lisp): Allow using spaces
+ in the command names (by splitting using shell syntax) (bug#16005).
+
+2021-07-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Rename shell-split-string to split-string-shell-command
+
+ * lisp/shell.el (split-string-shell-command):
+ * doc/lispref/processes.texi (Shell Arguments): Rename from
+ shell-split-string.
+
+2021-07-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new function 'shell-split-string'
+
+ * doc/lispref/processes.texi (Shell Arguments): Document it.
+ * lisp/shell.el (shell-split-string): New function.
+
+2021-07-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify overriding-local-map doc string
+
+ * src/keyboard.c (syms_of_keyboard): Clarify
+ `overriding-local-map' vs. text properties/overlays (bug#16312).
+
+2021-07-15 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify gcc -Woverflow more clearly
+
+ * src/alloc.c (mark_maybe_pointer): Make it clearer that ANDing
+ with UINTPTR_MAX is intended. Omit a now-unnecessary cast.
+
+2021-07-14 Michael Albinus <michael.albinus@gmx.de>
+
+ Preserve backward compatibility in Tramp
+
+ * lisp/net/tramp-crypt.el (tramp-crypt-handle-lock-file)
+ (tramp-crypt-handle-unlock-file): Preserve backward compatibility.
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-write-region): Do not
+ create lock file twice.
+
+ * lisp/net/tramp.el (tramp-handle-make-lock-file-name): Move lock
+ file security check ...
+ (tramp-handle-lock-file): ... here.
+ (tramp-handle-unlock-file): Preserve backward compatibility.
+
+ * test/lisp/net/tramp-tests.el (lock-file-name-transforms)
+ (remote-file-name-inhibit-locks): Declare.
+ (tramp-allow-unsafe-temporary-files): Set to t.
+ (tramp-test37-make-auto-save-file-name)
+ (tramp-test38-find-backup-file-name): Move binding of
+ `tramp-allow-unsafe-temporary-files' up.
+ (tramp-test39-lock-file): Bind `tramp-allow-unsafe-temporary-files'.
+ Preserve backward compatibility. Extend test.
+
+2021-07-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fontify the signature separator in Message mode
+
+ * lisp/gnus/message.el (message-signature-separator): New face
+ (bug#17757).
+ (message-font-lock-keywords): Add it to the signature, and ensure
+ that the trailing space isn't removed when hitting RET.
+ (message--match-signature): New helper function.
+
+2021-07-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify backward-delete-char-untabify doc string
+
+ * lisp/simple.el (backward-delete-char-untabify): Mention the
+ effect of Transient Mark mode (bug#17263).
+
+2021-07-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ * etc/NEWS: Add back a missing apostrophe.
+
+2021-07-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ switch-to-buffer-other-frame doc string improvement
+
+ * lisp/window.el (switch-to-buffer-other-frame): Document that we
+ don't always display the buffer in a different frame (bug#17719).
+
+2021-07-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix hilit-chg highlighting of characters where text has been removed
+
+ * lisp/hilit-chg.el (hilit-chg-set-face-on-change): Remove
+ highlighting from characters that are just highlighted because of
+ something that has been previously deleted (bug#17784).
+
+2021-07-14 Eli Zaretskii <eliz@gnu.org>
+
+ Fix deprecation warnings from libtiff
+
+ * src/image.c (UINT32) [TIFFLIB_VERSION >= 20210416]: Define to
+ use stdint.h type for recent libtiff versions. Reported by Andy
+ Moreton <andrewjmoreton@gmail.com>.
+
+2021-07-14 Michael Albinus <michael.albinus@gmx.de>
+
+ * etc/NEWS (insert-into-buffer'): Fix thinko.
+
+2021-07-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `apropos-library' also work for libraries without symbols
+
+ * lisp/apropos.el (apropos--preamble): Factor out (bug#17832)...
+ (apropos-print-doc): ... from here.
+ (apropos-library): Use it to display the apropos buffer even if it
+ has no symbols of its own.
+
+2021-07-14 Juri Linkov <juri@linkov.net>
+
+ Revert e0619995594d1686afd0493391417d6f900d632c that added save-match-data.
+
+ * lisp/isearch.el (isearch-filter-predicate): Mention precautions against
+ clobbering the match data in docstring (bug#49534).
+
+2021-07-14 Juri Linkov <juri@linkov.net>
+
+ * lisp/isearch.el: Add save-match-data for funcall isearch-filter-predicate.
+
+ * lisp/isearch.el (isearch-search): Add save-match-data before
+ funcall isearch-filter-predicate.
+ (isearch-lazy-highlight-search): Add save-match-data before
+ funcall isearch-filter-predicate.
+ (Bug#49534)
+
+2021-07-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a better interactive spec to `facemenu-add-face'
+
+ * lisp/facemenu.el (facemenu-add-face): Use `read-face-name'
+ (bug#18369) by copying over the interactive spec from
+ facemenu-set-face.
+
+2021-07-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make jka-compr-insert-file-contents slightly more efficient
+
+ * lisp/jka-compr.el (jka-compr-insert-file-contents): Make more
+ efficient by using `insert-into-buffer'.
+
+2021-07-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new function 'insert-into-buffer'
+
+ * doc/lispref/text.texi (Insertion): Document it.
+ * lisp/subr.el (insert-into-buffer): New function.
+
+2021-07-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fall back on zlib-decompress-region if gzip doesn't exist
+
+ * lisp/jka-cmpr-hook.el (jka-compr-info-uncompress-function): New
+ function (bug#18823).
+ (jka-compr-compression-info-list): Expand info with decompression
+ function.
+
+ * lisp/jka-compr.el (jka-compr-insert-file-contents): Fall back on
+ internal decompression function if external doesn't exist.
+
+2021-07-13 Daniel Martín <mardani29@yahoo.es>
+
+ Fix dired-number-of-marked-files when there are no marked files
+
+ * lisp/dired.el (dired-number-of-marked-files): Fix if expression so
+ that the else part is evaluated correctly.
+
+2021-07-13 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * doc/lispref/modes.texi (Multiline Font Lock): Tweak last change
+
+2021-07-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow not updating Customize settings in set-frame-font
+
+ * lisp/frame.el (set-frame-font): Allow not updating the
+ Customization settings (bug#19298).
+
+2021-07-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document the syntax-multilne text property
+
+ * doc/lispref/modes.texi (Multiline Font Lock): Document the
+ syntax-multiline text property (bug#20436).
+
+2021-07-13 Juri Linkov <juri@linkov.net>
+
+ Support Isearch filter predicates with empty search hits (bug#49534)
+
+ * lisp/isearch.el (isearch-search): Move (= (match-beginning 0) (match-end 0))
+ and (bobp)/(eobp) outside the call to isearch-filter-predicate.
+ Use forward-char 1/-1 on empty matches only when going to retry search.
+ (isearch-lazy-highlight-search): Remove (= (point) bound),
+ but leave (= (match-beginning 0) (match-end 0)) since empty matches
+ make no sense in lazy-highlighting.
+
+2021-07-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make 'tex-validate-buffer' work again
+
+ * lisp/textmodes/tex-mode.el (tex-validate-buffer): The *Occur*
+ buffer is read-only, so inhibit that before inserting things into
+ it (bug#19326).
+
+2021-07-13 Michael Albinus <michael.albinus@gmx.de>
+
+ Add remote-file-name-inhibit-locks
+
+ * doc/emacs/files.texi (Interlocking):
+ * doc/lispref/files.texi (File Locks):
+ * doc/misc/tramp.texi (Auto-save File Lock and Backup):
+ Add remote-file-name-inhibit-locks.
+
+ * etc/NEWS: New user option 'remote-file-name-inhibit-locks'.
+
+ * lisp/files.el (remote-file-name-inhibit-locks): New defcustom.
+
+ * lisp/net/tramp-adb.el (tramp-adb-file-name-handler-alist):
+ * lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist):
+ * lisp/net/tramp-rclone.el (tramp-rclone-file-name-handler-alist):
+ * lisp/net/tramp-sh.el (tramp-sh-file-name-handler-alist):
+ * lisp/net/tramp-smb.el (tramp-smb-file-name-handler-alist):
+ * lisp/net/tramp-sshfs.el (tramp-sshfs-file-name-handler-alist):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-file-name-handler-alist):
+ Use `tramp-handle-make-lock-file-name'.
+
+ * lisp/net/tramp.el (tramp-allow-unsafe-temporary-files): Fix docstring.
+ (tramp-handle-make-lock-file-name): New defun.
+
+ * test/lisp/net/tramp-tests.el (tramp-test39-lock-file): Extend test.
+
+2021-07-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new user option to avoid piling on Dired buffers
+
+ * doc/emacs/dired.texi (Dired Visiting): Document it.
+
+ * lisp/dired.el (dired-kill-when-opening-new-dired-buffer): New
+ user option (bug#20598).
+ (dired-up-directory, dired-find-file): Use it.
+ (dired--find-possibly-alternative-file): New convenience command
+ to respect the user option.
+
+2021-07-13 Mattias Engdegård <mattiase@acm.org>
+
+ Block TLS handshake until TCP connection established
+
+ If a TLS handshake is attempted before the completion of an
+ asynchronous TCP connection has been ascertained, our local state will
+ not be set up correctly for further progress and the sentinel "open"
+ event will never be sent. This can occur if sufficient time passes
+ after the initiation of an async TCP connection so that by the time
+ `wait_reading_process_output` is called, the connection has already
+ been established on the TCP level.
+
+ This somewhat timing-sensitive bug has plagued HTTPS connections on
+ some platforms, notably macOS, for a long time (bug#49449).
+
+ * src/process.c (wait_reading_process_output): Gate the TLS handshake
+ by the NON_BLOCKING_CONNECT_FD flag. The flag will be cleared as soon
+ as the TCP socket is found to be writable.
+ * test/src/process-tests.el (process-async-https-with-delay):
+ New test.
+
+2021-07-13 Ken Brown <kbrown@cornell.edu>
+
+ Fix portability issue with make-serial-process
+
+ * src/sysdep.c (struct speed_struct): New struct.
+ (speeds): New static array of struct speed_struct.
+ (convert_speed): New static function to convert a numerical baud
+ rate (e.g., 9600) to a Bnnn constant defined in termios.h (e.g.,
+ B9600).
+ (serial_configure): Use convert_speed to make the call to cfsetspeed
+ compliant with its advertised API. (Bug#49524)
+
+2021-07-13 Eli Zaretskii <eliz@gnu.org>
+
+ One more minor update of the Emacs manual for 19th printing
+
+ * doc/emacs/back.texi:
+ * doc/emacs/book-spine.texi:
+ * doc/emacs/emacs.texi: Last round of minor copyedits for 19th ed.
+
+2021-07-12 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix a problem with tramp-*-process-file
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-process-file):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-process-file):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-process-file):
+ * lisp/net/tramp-sshfs.el (tramp-sshfs-handle-process-file):
+ Use `(expand-file-name default-directory)'.
+
+2021-07-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port test module to glibc 2.33
+
+ * test/Makefile.in (REPLACE_FREE, FREE_SOURCE_0, FREE_SOURCE_1):
+ New macros.
+ ($(test_module)): Improve accuracy of test as to whether free.c
+ should be compiled; glibc 2.33 does not need it compiled and the
+ compilation breaks if you try, if you build with
+ --enable-gcc-warnings.
+
+2021-07-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify gcc 11.1.1 -Wclobbered
+
+ * src/eval.c (Fprogn, internal_lisp_condition_case):
+ Add CACHEABLE to work around more instances of -Wclobbered bug.
+
+2021-07-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify gcc 11.1.1 -Wanalyzer-possible-null-dereference
+
+ * oldXMenu/Create.c (XMenuCreate):
+ * oldXMenu/Internal.c (_XMRecomputePane, _XMRecomputeSelection):
+ * oldXMenu/XMakeAssoc.c (XMakeAssoc):
+ * test/src/emacs-module-resources/mod-test.c (Fmod_test_userptr_make):
+ Don’t assume that malloc and calloc succeed.
+
+2021-07-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify gcc 11.1.1 -Wanalyzer-null-argument
+
+ * lib-src/etags.c (regexp): Omit member force_explicit_name,
+ since it’s always true. All uses removed. This lets us
+ remove calls to strlen (name) where GCC isn’t smart enough
+ to deduce that name must be nonnull.
+ * lib-src/movemail.c (main): Fix bug that could cause
+ link (tempname, NULL) to be called.
+ * src/emacs.c (argmatch): Break check into two ‘if’s,
+ since GCC doesn’t seem to be smart enough to check the single ‘if’.
+ * src/gtkutil.c (xg_update_menu_item): Fix bug where strcmp
+ could be given a NULL arg.
+ * src/xfont.c (xfont_list_family): Use nonnull value for dummy
+ initial value.
+
+2021-07-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify gcc -Woverflow more nicely
+
+ * src/alloc.c (mark_maybe_pointer): Simplify pacification
+ of gcc -Woverflow (unknown GCC version).
+
+2021-07-12 Juri Linkov <juri@linkov.net>
+
+ * lisp/textmodes/enriched.el: Require 'facemenu' (bug#49466)
+
+2021-07-11 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Further tweaks to gnus-search-query-expand-key
+
+ * lisp/gnus/gnus-search.el (gnus-search-query-expand-key): It's
+ possible that KEY could be partially completed (ie no longer string=
+ to COMP), but not all the way. Use a more accurate test. Add
+ docstring.
+
+2021-07-11 Michael Albinus <michael.albinus@gmx.de>
+
+ Use `auto-save-file-name-p' in tramp-*-write-region
+
+ * lisp/net/tramp.el (tramp-handle-write-region):
+ * lisp/net/tramp-adb.el (tramp-adb-handle-write-region):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-write-region):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-write-region):
+ * lisp/net/tramp-sshfs.el (tramp-sshfs-handle-write-region):
+ Use `auto-save-file-name-p'.
+
+2021-07-11 Eli Zaretskii <eliz@gnu.org>
+
+ Fix compilation of the --with-wide-int configuration
+
+ * src/alloc.c (mark_maybe_pointer): Fix a recent change for
+ WIDE_EMACS_INT builds. (Bug#49261)
+
+2021-07-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify GCC 11.1.1 20210531 (Red Hat 11.1.1-3)
+
+ * src/image.c (xpm_load_image):
+ * src/xfns.c (x_icon):
+ Rework to pacify gcc -Wmaybe-uninitialized.
+
+2021-07-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ Make pdumper-marking pickier
+
+ Prevent some false-positives in conservative GC marking.
+ This doesn’t fix any correctness bugs; it’s merely to
+ reclaim some memory instead of keeping it unnecessarily.
+ * src/alloc.c (mark_maybe_pointer): New arg SYMBOL_ONLY.
+ All callers changed. Check that the pointer’s tag, if any,
+ matches the pdumper-reported type.
+
+2021-07-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix pdumper-related GC bug
+
+ * src/alloc.c (mark_maybe_pointer): Also mark pointers
+ to pdumper objects, even when the pointers are tagged.
+ Add a FIXME saying why this isn’t enough.
+
+2021-07-11 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Rewrite gnus-search-query-expand-key
+
+ * lisp/gnus/gnus-search.el (gnus-search-query-expand-key): There was a
+ misunderstanding about how completion-all-completion works (if the
+ test string can't be completed, the whole table is returned). Simplify
+ to use try-completion.
+ * test/lisp/gnus/gnus-search-tests.el (gnus-s-expand-keyword): Ensure
+ that an unknown/uncompletable keyword is returned unmolested.
+
+2021-07-11 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Rework gnus-search-indexed-parse-output
+
+ * lisp/gnus/gnus-search.el (gnus-search-indexed-parse-output): Be more
+ careful about matching filesystem paths to Gnus group names; make
+ absolutely sure that we only return valid article numbers.
+
+2021-07-11 Matthew White <mehw.is.me@inventati.org>
+
+ * src/buffer.c (kill-buffer): Fix a typo.
+
+ * src/buffer.c (Fkill_buffer): Fix typo in comment.
+
+2021-07-10 Filipp Gunbin <fgunbin@fastmail.fm>
+
+ doc/lispref/text.texi (Substitution): Add subst-char-in-string
+
+ * doc/lispref/text.texi (Substitution): Document
+ subst-char-in-string (bug#49420).
+
+2021-07-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make package-menu-filter-by-status work as documented
+
+ * lisp/emacs-lisp/package.el (package-menu-filter-by-status): Work
+ as documented (bug#49474).
+
+2021-07-09 Ken Brown <kbrown@cornell.edu>
+
+ Skip a process test on Cygwin to avoid hang
+
+ * test/src/process-tests.el
+ (process-tests/fd-setsize-no-crash/make-network-process): Skip
+ test on Cygwin to avoid hang due to connect/accept handshake.
+ (Bug#49496)
+
+2021-07-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/facemenu.el: Preload the C-mouse-2 menu binding
+
+2021-07-09 Michael Albinus <michael.albinus@gmx.de>
+
+ Further cleanup for file locks
+
+ * doc/misc/tramp.texi (Top, Configuration): Adapt node name for
+ file locks.
+ (Auto-save File Lock and Backup): Rename node name and section
+ title. Add file-lock to @cindex. Describe file locks.
+
+ * lisp/dired.el (dired-trivial-filenames): Add lock files.
+ (dired-font-lock-keywords): Move files suffixed with
+ `completion-ignored-extensions' up. Add lock files to these checks.
+
+ * lisp/net/tramp.el (tramp-get-lock-file, tramp-handle-unlock-file):
+ Use `when-let'
+ (tramp-lock-file-info-regexp): Rename from
+ `tramp-lock-file-contents-regexp'.
+ (tramp-handle-file-locked-p, tramp-handle-lock-file): Adapt callees.
+ (tramp-handle-lock-file): Set file modes of lockname.
+
+ * src/buffer.c (Frestore_buffer_modified_p):
+ * src/fileio.c (write_region):
+ * src/insdel.c (prepare_to_modify_buffer_1): Call Flock_file.
+
+ * src/filelock.c (Qmake_lock_file_name): Declare symbol.
+ (make_lock_file_name): Use it. Don't check Fboundp, it doesn't
+ work for interned symbols.
+ (lock_file): Return a Lisp_Object. Don't check create_lockfiles.
+ Remove MSDOS version of the function.
+ (Flock_file): Check create_lockfiles.
+ (Flock_buffer): Call Flock_file.
+
+ * src/lisp.h (lock_file): Remove.
+
+ * test/lisp/shadowfile-tests.el (shadow-test08-shadow-todo)
+ (shadow-test09-shadow-copy-files): Let-bind `create-lockfiles'.
+
+ * test/lisp/net/tramp-tests.el (create-lockfiles): Don't set it
+ globally.
+ (tramp-test39-lock-file): Check also for `set-visited-file-name'.
+
+2021-07-09 Eli Zaretskii <eliz@gnu.org>
+
+ Partially restore the lost C-mouse-2 drop-down menu
+
+ This allows to pop up the Text Properties menu once facemenu is
+ loaded. It still doesn't allow C-mouse-2 clicks without manually
+ loading facemenu; FIXME.
+ * lisp/facemenu.el (global-map) <C-down-mouse-2>: Add back the
+ removed binding. (Bug#49466)
+
+2021-07-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/outline.el (outline-mode-cycle-map): Don't bind `tab`.
+
+ Since it would take precedence over bindings for TAB in higher
+ precedence maps.
+
+2021-07-08 Michael Albinus <michael.albinus@gmx.de>
+
+ * doc/lispref/files.texi (Magic File Names): Add make-lock-file-name.
+
+2021-07-08 Michael Albinus <michael.albinus@gmx.de>
+
+ Code cleanup wrt file locks
+
+ * lisp/files.el (make-lock-file-name): Fix docstring.
+
+ * lisp/net/tramp-adb.el (tramp-adb-file-name-handler-alist):
+ * lisp/net/tramp-archive.el (tramp-archive-file-name-handler-alist):
+ * lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist):
+ * lisp/net/tramp-rclone.el (tramp-rclone-file-name-handler-alist):
+ * lisp/net/tramp-sh.el (tramp-sh-file-name-handler-alist):
+ * lisp/net/tramp-smb.el (tramp-smb-file-name-handler-alist):
+ * lisp/net/tramp-sshfs.el (tramp-sshfs-file-name-handler-alist):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-file-name-handler-alist):
+ Add `make-lock-file-name'.
+
+ * lisp/net/tramp.el (tramp-file-name-for-operation):
+ Add `make-lock-file-name'.
+ (tramp-handle-unlock-file): Call `userlock--handle-unlock-error'
+ in case of error.
+
+ * src/buffer.c (Frestore_buffer_modified_p):
+ * src/editfns.c (Freplace_buffer_contents):
+ * src/fileio.c (Finsert_file_contents, write_region): Call Funlock_file.
+
+ * src/filelock.c (unlock_file): Rename from unlock_file_body.
+ Remove the other declarations of unlock_file. Move file name
+ handler check to ...
+ (Funlock_file): ... here. Adapt argument numbers. Call
+ unlock_file wrapped by internal_condition_case.
+ (Flock_file): Adapt argument numbers.
+ (unlock_all_files, Funlock_buffer, unlock_buffer): Call Funlock_file.
+
+ * src/lisp.h (unlock_file): Remove.
+
+2021-07-08 Juri Linkov <juri@linkov.net>
+
+ Don't turn mouse-1 into mouse-2 when clicking on the tab-line (bug#49247)
+
+ * lisp/tab-line.el (tab-line-tab-name-format-default): For 'tab-line-tab-map'
+ add the property 'follow-link' with the value 'ignore'.
+
+2021-07-08 pillule <pillule@riseup.net>
+
+ Use display-buffer with re-builder (bug#49069)
+
+ * lisp/emacs-lisp/re-builder.el (re-builder): Uses 'display-buffer'
+ with 'display-buffer-in-direction' to display the reb-buffer. This
+ allow user-customizations and using it on not splitables windows.
+ Add a dedication to its window so killing this buffer quit the window.
+
+2021-07-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make desktop-kill more robust
+
+ * lisp/desktop.el (desktop-kill): Allow exiting Emacs even if we
+ can't delete the desktop file (bug#20762).
+
+2021-07-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow inhibiting inserting #! in sh-set-shell
+
+ * lisp/progmodes/sh-script.el (sh-set-shell): Allow inhibiting
+ inserting the #! line (bug#20959).
+
+2021-07-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Avoid making backup files in ediff when `make-backup-files' is nil
+
+ * lisp/vc/ediff-util.el (ediff-arrange-autosave-in-merge-jobs):
+ Don't make backup files when `make-backup-files' is nil (bug#21599).
+
+2021-07-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make ido-mode override ffap-file-finder
+
+ * lisp/ffap.el: Autoload so that we can override in ido (bug#21980).
+
+ * lisp/ido.el (ido-everywhere): Override ffap-file-finder.
+
+2021-07-08 Michael Albinus <michael.albinus@gmx.de>
+
+ Some further adaptions wrt Tramp file name locks
+
+ * lisp/files.el (files--transform-file-name): Rename from
+ `auto-save--transform-file-name'. Wrap with `save-match-data'.
+ (make-auto-save-file-name): Use it.
+ (make-lock-file-name): Use it. Call file name handler.
+
+ * lisp/net/tramp.el (tramp-handle-write-region):
+ * lisp/net/tramp-adb.el (tramp-adb-handle-write-region):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-write-region):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-write-region):
+ Suppress file lock for temporary file.
+
+ * lisp/net/tramp-compat.el (tramp-compat-make-lock-file-name):
+ New defalias.
+
+ * lisp/net/tramp.el (tramp-get-lock-file)
+ (tramp-handle-lock-file, tramp-handle-unlock-file): Use it.
+ (tramp-make-lock-name): Remove.
+
+ * test/lisp/filenotify-tests.el (file-notify-test03-events-remote):
+ Tag it :unstable temporarily.
+
+2021-07-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Exclude term-mode from hi-lock global modes
+
+ * lisp/hi-lock.el (hi-lock-exclude-modes): Exclude term-mode so
+ that `C-x' works in terminal buffers (bug#22620).
+
+2021-07-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix font-lock of Makefile variables at the start of lines
+
+ * lisp/progmodes/make-mode.el (makefile-var-use-regex): Match
+ variables at the beginning of lines correctly (bug#23266). Change
+ suggested by Anders Lindgren <andlind@gmail.com>.
+
+2021-07-08 N. Jackson <nljlistbox2@gmail.com>
+
+ Mention what happens with timers when the computer is asleep
+
+ * doc/lispref/os.texi (Timers): Explain what happens if the
+ computer is a asleep when the timer is scheduled (bug#23929).
+
+2021-07-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make make_lock_file_name more robust
+
+ * src/filelock.c (make_lock_file_name): Protect against the
+ make-lock-file-name not being defined.
+ (lock_file, unlock_file_body, Ffile_locked_p): Return early if not
+ defined.
+
+2021-07-07 Eli Zaretskii <eliz@gnu.org>
+
+ * lisp/faces.el: Fix a typo.
+
+2021-07-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change
+
+ * lisp/faces.el (tty-menu-enabled-face, tty-menu-disabled-face):
+ Define for monochrome displays.
+
+2021-07-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new user option lock-file-name-transforms
+
+ * doc/emacs/files.texi (Interlocking): Mention
+ lock-file-name-transforms.
+
+ * doc/lispref/files.texi (File Locks): Document
+ lock-file-name-transforms.
+
+ * doc/misc/efaq.texi (Not writing files to the current directory):
+ Mention all the three variables needed to not having Emacs writing
+ files to the current directory in one place.
+
+ * lisp/files.el (lock-file-name-transforms): New user option (bug#49261).
+ (make-auto-save-file-name): Factor out the main logic...
+ (auto-save--transform-file-name): ... to this new function.
+ (make-lock-file-name): New function that also calls the
+ factored-out function.
+
+ * src/filelock.c: Remove MAKE_LOCK_NAME and fill_in_lock_file_name.
+ (make_lock_file_name): New utility function that calls out to Lisp
+ to heed `lock-file-name-transforms'.
+ (lock_file): Use it. Also remove likely buggy call to
+ dostounix_filename.
+ (unlock_file_body, Ffile_locked_p): Also use make_lock_file_name.
+
+2021-07-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix tty menus on monochrome displays
+
+ * lisp/faces.el (tty-menu-selected-face): Make sure the selected
+ menu item stands out even without colors.
+
+2021-07-07 Michael Albinus <michael.albinus@gmx.de>
+
+ Implement file locks for remote files (Bug#49261)
+
+ * doc/lispref/files.texi (Magic File Names): Add file-locked-p,
+ lock-file and unlock-file.
+
+ * etc/NEWS: Tramp supports file locks now.
+
+ * lisp/net/tramp-adb.el (tramp-adb-file-name-handler-alist):
+ Add `file-locked-p', `lock-file' and `unlock-file'.
+ (tramp-adb-handle-write-region): Handle LOCKNAME.
+
+ * lisp/net/tramp-archive.el (tramp-archive-file-name-handler-alist):
+ Add `file-locked-p', `lock-file' and `unlock-file'.
+
+ * lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist):
+ Add `file-locked-p', `lock-file' and `unlock-file'.
+ (tramp-crypt-handle-file-locked-p, tramp-crypt-handle-lock-file)
+ (tramp-crypt-handle-unlock-file): New defun.
+
+ * lisp/net/tramp-fuse.el (tramp-fuse-mounted-p): Simplify.
+ (tramp-fuse-unmount): New defun.
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist):
+ Add `file-locked-p', `lock-file' and `unlock-file'.
+ (tramp-gvfs-maybe-open-connection): Set "lock-pid" connection property.
+
+ * lisp/net/tramp-rclone.el (tramp-rclone-file-name-handler-alist):
+ Add `file-locked-p', `lock-file' and `unlock-file'.
+ (tramp-rclone-maybe-open-connection): Set "lock-pid" connection property.
+
+ * lisp/net/tramp-sh.el (tramp-sh-file-name-handler-alist):
+ Add `file-locked-p', `lock-file' and `unlock-file'.
+ (tramp-sh-handle-write-region): Handle LOCKNAME.
+
+ * lisp/net/tramp-smb.el (tramp-smb-file-name-handler-alist):
+ Add `file-locked-p', `lock-file' and `unlock-file'.
+ (tramp-smb-handle-copy-directory): Use `sleep-for'.
+ (tramp-smb-handle-write-region): Handle LOCKNAME.
+
+ * lisp/net/tramp-sshfs.el (tramp-sshfs-file-name-handler-alist):
+ Add `file-locked-p', `lock-file' and `unlock-file'.
+ (tramp-sshfs-handle-write-region): Handle LOCKNAME.
+ (tramp-sshfs-maybe-open-connection): Set "lock-pid" connection property.
+
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-file-name-handler-alist):
+ Add `file-locked-p', `lock-file' and `unlock-file'.
+ (tramp-sudoedit-maybe-open-connection):
+ Set "lock-pid" connection property.
+
+ * lisp/net/tramp.el (tramp-file-name-for-operation):
+ Add `file-locked-p', `lock-file' and `unlock-file'.
+ (tramp-make-lock-name, tramp-get-lock-file, tramp-get-lock-pid)
+ (tramp-handle-file-locked-p, tramp-handle-lock-file)
+ (tramp-handle-unlock-file): New defuns.
+ (tramp-lock-file-contents-regexp): New regexp.
+ (tramp-handle-write-region): Handle LOCKNAME.
+
+ * src/filelock.c (lock_file, unlock_file_body, Ffile_locked_p):
+ Call handler if exists.
+ (Flock_file, Funlock_file): New defuns.
+ (Qlock_file, Qunlock_file, Qfile_locked_p): Declare symbols.
+ (Slock_file, Sunlock_file): Declare subroutines.
+
+ * test/lisp/net/tramp-archive-tests.el
+ (tramp-archive-test40-make-nearby-temp-file)
+ (tramp-archive-test43-file-system-info): Rename.
+
+ * test/lisp/net/tramp-tests.el (top): Set `create-lockfiles' to nil.
+ (tramp--test-fuse-p): New defun.
+ (tramp-test14-delete-directory): Use it.
+ (tramp-test39-lock-file): New test.
+ (tramp-test40-make-nearby-temp-file)
+ (tramp-test41-special-characters)
+ (tramp-test41-special-characters-with-stat)
+ (tramp-test41-special-characters-with-perl)
+ (tramp-test41-special-characters-with-ls, tramp-test42-utf8)
+ (tramp-test42-utf8-with-stat, tramp-test42-utf8-with-perl)
+ (tramp-test42-utf8-with-ls, tramp-test43-file-system-info)
+ (tramp-test44-asynchronous-requests, tramp-test45-auto-load)
+ (tramp-test45-delay-load, tramp-test45-recursive-load)
+ (tramp-test45-remote-load-path, tramp-test46-unload): Rename.
+ (tramp--test-special-characters, tramp--test-utf8)
+ (tramp--test-asynchronous-requests-timeout): Modify docstring.
+
+2021-07-07 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ fbf1cb2bf2 (origin/emacs-27) Fix overfull hbox in Emacs manual
+ fda60094a2 Minor copyedits of Emacs manual
+
+ # Conflicts:
+ # doc/emacs/display.texi
+
+2021-07-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make previous empty-body warning disabling more robust
+
+ * lisp/emacs-lisp/macroexp.el (macroexp--expand-all):
+ `byte-compile-warning-enabled-p' may not be defined here.
+
+2021-07-06 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Avoid invalid regexp in wide docstring check
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile--wide-docstring-p):
+ Avoid constructing an invalid regexp during byte-compilation by
+ limiting the number of columns to the current RE_DUP_MAX of 65535.
+ This protects against pathological values of fill-column, for
+ example (bug#49426).
+
+2021-07-06 Juri Linkov <juri@linkov.net>
+
+ * lisp/repeat.el (describe-repeat-maps): Rename from `describe-repeat'.
+
+ Fix text strings (bug#49265).
+
+2021-07-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `M-x clipboard-yank' work reliably
+
+ * lisp/menu-bar.el (clipboard-yank): Make the command work
+ consistently (bug#27442).
+
+ * lisp/select.el (gui-selection-value): Try to explain why the
+ logic is the way it is.
+
+2021-07-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Explain what ( . c) means to the Emacs Lisp reader
+
+ * doc/lispref/objects.texi (Dotted Pair Notation): Explain what
+ ( . c) means to the Lisp reader (bug#24875).
+
+2021-07-06 Eli Zaretskii <eliz@gnu.org>
+
+ Fix right-margin display on TTY frames
+
+ * src/dispnew.c (prepare_desired_row, adjust_glyph_matrix): Adjust
+ the glyph pointer of the right-margin area for all windows but the
+ rightmost ones on TTY frames, to account for the border glyph.
+ (Bug#48257)
+
+2021-07-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Warn when wrapping index matches with `,' after `i' in Info
+
+ * lisp/info.el (Info--current-index-alternative): New internal
+ variable.
+ (Info-warn-on-index-alternatives-wrap): New user option (bug#24282).
+ (Info-index-next): Use the new user option.
+
+2021-07-06 Protesilaos Stavrou <info@protesilaos.com>
+
+ Add faces for shr heading elements (bug#49433)
+
+ * etc/NEWS: Document new faces.
+ * lisp/net/shr.el (shr-h1, shr-h2, shr-h3, shr-h4, shr-h5, shr-h6):
+ Define new faces.
+ (shr-tag-h1): Remove inclusion of 'variable-pitch' face. Fix
+ bug#49433 by applying a new face directly.
+ (shr-tag-h2, shr-tag-h3, shr-tag-h4, shr-tag-h5, shr-tag-h6): Apply
+ new faces.
+
+2021-07-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make gnus-gcc-externalize-attachments work again
+
+ * lisp/gnus/gnus-msg.el (gnus-inews-do-gcc): Allow externalizing
+ parts again by defeating the cache (bug#49436).
+
+2021-07-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow inhibiting warnings about unused variables and empty bodies
+
+ * lisp/emacs-lisp/cconv.el (cconv--warn-unused-msg): Allow
+ inhibiting warnings about unbound variables (bug#26486).
+
+ * lisp/emacs-lisp/macroexp.el (macroexp--expand-all): Allow
+ inhibiting warnings about empty bodies.
+
+2021-07-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow using `mm-inline-message' from other mail clients than Gnus
+
+ * lisp/gnus/mm-view.el (mm-inline-message-prepare-function): New
+ variable (bug#49380).
+ (mm-inline-message): Use it to separate out the Gnus-specific code.
+ * lisp/gnus/gnus-art.el (gnus-mime-display-single): ... which has
+ been moved here.
+
+2021-07-06 Eli Zaretskii <eliz@gnu.org>
+
+ Fix overfull hbox in Emacs manual
+
+ * doc/emacs/display.texi (Displaying Boundaries): Fix overfull
+ hbox.
+
+2021-07-06 Eli Zaretskii <eliz@gnu.org>
+
+ Minor copyedits of Emacs manual
+
+ * doc/emacs/book-spine.texi: Fix the author attribution.
+ (Bug#49405)
+ * doc/emacs/back.texi: Update text.
+
+2021-07-06 Philip Kaludercic <philipk@posteo.net>
+
+ Add query command removed in 4ff1f66b12
+
+ * lisp/net/rcirc.el (query): Readd accidentally removed command
+
+2021-07-06 Philip Kaludercic <philipk@posteo.net>
+
+ Fix issues with argument parsing in rcirc-define-command
+
+ * lisp/net/rcirc.el (rcirc-define-command): Fix issues
+
+2021-07-06 Dmitry Gutov <dgutov@yandex.ru>
+
+ (xref--insert-xrefs): Fix printing of line numbers
+
+ * lisp/progmodes/xref.el (xref--insert-xrefs):
+ Fix printing of line numbers when we have multiple files with
+ (e.g.) single match on the same line.
+
+2021-07-05 Stephen Leake <stephen_leake@stephe-leake.org>
+
+ * lisp/progmodes/bug-reference.el: Refer to info manual node
+
+2021-07-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Support reverting in Customize buffers
+
+ * lisp/cus-edit.el (custom--revert-buffer): New function (bug#26871).
+ (Custom-mode): Set up reversion.
+ (custom--invocation-options): New variable.
+ (custom-buffer-create-internal): Set it.
+
+2021-07-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Count zero-length matches in `count-matches' correctly
+
+ * lisp/replace.el (how-many): Count zero-length matches correctly
+ (bug#27359).
+
+2021-07-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Propagate :safe properties when autoloading defcustoms
+
+ * lisp/emacs-lisp/autoload.el (make-autoload): Propagate the :safe
+ property to the loaddefs file (bug#28104).
+
+2021-07-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `bookmark--unfontify' more robust
+
+ * lisp/bookmark.el (bookmark--unfontify): Don't bug out if there's
+ no fontification recorded (bug#49341).
+
+2021-07-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ `image-save' doc string clarification
+
+ * lisp/image.el (image-save): Clarify what's being saved
+ (bug#49347).
+
+2021-07-05 Michael Albinus <michael.albinus@gmx.de>
+
+ Don't use LOCKNAME for temp files in Tramp (Bug#49406)
+
+ * lisp/net/tramp.el (tramp-handle-write-region):
+ * lisp/net/tramp-adb.el (tramp-adb-handle-write-region):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-write-region):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-write-region):
+ * lisp/net/tramp-sshfs.el (tramp-sshfs-handle-write-region):
+ Don't use LOCKNAME for temp file. (Bug#49406)
+
+ * test/lisp/shadowfile-tests.el (password-cache-expiry):
+ Set `shadow-debug' also on emba.
+
+2021-07-05 Martin Rudalics <rudalics@gmx.at>
+
+ Show hand cursor when dragging frame (Bug#49247)
+
+ * src/xdisp.c (note_mode_line_or_margin_highlight): Show hand
+ cursor when dragging frame with mode, tab or header line.
+ (syms_of_xdisp): Define Qdrag_with_mode_line,
+ Qdrag_with_header_line and Qdrag_with_tab_line.
+
+2021-07-05 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix newly introduced error in tramp-tests.el (Bug#49406)
+
+ * test/lisp/net/tramp-tests.el (tramp--test-check-files):
+ Filter out empty strings. (Bug#49406)
+
+2021-07-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Ignore .dir-locals-2.el files more
+
+ * lisp/emacs-lisp/shadow.el (load-path-shadows-find):
+ * lisp/emacs-lisp/bytecomp.el (byte-recompile-directory): Ignore
+ .dir-locals-2.el, too (bug#23257).
+
+2021-07-04 Jim Porter <jporterbugs@gmail.com>
+
+ Ensure 'call-process' interprets INFILE as a local path
+
+ * src/callproc.c (get_current_directory): Rename from
+ 'encode_current_directory' and add boolean ENCODE flag.
+ (Fcall_process): Interpret INFILE relative to the working directory
+ from which PROGRAM is run, not 'default-directory'.
+ (call_process): Use 'get_current_directory'.
+ * src/process.c (Fmake_process): Use 'get_current_directory'.
+ * src/process.h (get_current_directory): Rename decl from
+ 'encode_current_directory'.
+ * src/sysdep.c (sys_subshell): Use 'get_current_directory' (bug#49283).
+
+2021-07-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust eshell and ps-print to not use emacs-kill-hook
+
+ * lisp/ps-print.el (ps-kill-emacs-check):
+
+ * lisp/eshell/em-dirs.el (eshell-dirs-initialize)
+ (eshell-save-some-last-dir): Don't use `emacs-kill-hook' (bug#28943).
+
+ * lisp/eshell/em-hist.el (eshell-hist-initialize)
+ (eshell-save-some-history):
+
+2021-07-04 Eli Zaretskii <eliz@gnu.org>
+
+ * lisp/url/url-util.el (url-unhex-string): Doc fix.
+
+2021-07-04 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid deprecation warnings with Texinfo 6.8
+
+ * doc/lispref/functions.texi (Function Safety):
+ * doc/misc/srecode.texi (Parts of SRecode):
+ * doc/misc/wisent.texi (Wisent Semantic, Wisent Lex):
+ * doc/misc/pcl-cvs.texi (Editing files):
+ * doc/misc/bovine.texi (top, Starting Rules)
+ (Bovine Grammar Rules, How Lexical Tokens Match)
+ (Optional Lambda Expression):
+ * doc/emacs/msdos.texi (Windows Keyboard):
+ * doc/emacs/buffers.texi (Several Buffers):
+ * doc/emacs/text.texi (Text): Avoid using @inforef, which is
+ deprecated.
+
+2021-07-04 Alan Third <alan@idiocy.org>
+
+ Fix crash in GNUstep font coverage check
+
+ * src/nsfont.m (ns_charset_covers): Check coverage more accurately and
+ don't automatically assume the buffer is 8192 bytes long.
+
+2021-07-04 Alan Third <alan@idiocy.org>
+
+ Remove unused variables
+
+ * src/nsterm.m ([EmacsView keyDown:]): Remove ns_fake_keydown as
+ there's no code that ever sets it to YES.
+
+2021-07-04 Alan Third <alan@idiocy.org>
+
+ Fix thread memory management under NS
+
+ * src/thread.c (run_thread): Allocate an autorelease pool so that any
+ autoreleased Objective C objects are correctly released.
+
+2021-07-04 Amin Bandali <bandali@gnu.org>
+
+ Update a few more IRC-related references to point to Libera.Chat
+
+2021-07-04 Amin Bandali <bandali@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 348b2aed0c Update IRC-related references to point to Libera.Chat
+ b0e725e2fe Fix typo in c-macro-expand docstring
+
+ # Conflicts:
+ # doc/misc/erc.texi
+ # doc/misc/gnus-faq.texi
+ # doc/misc/rcirc.texi
+ # etc/NEWS
+ # lisp/erc/erc-services.el
+ # lisp/erc/erc.el
+ # lisp/ldefs-boot.el
+ # lisp/net/rcirc.el
+
+2021-07-04 Amin Bandali <bandali@gnu.org>
+
+ Merge from origin/emacs-27
+
+ d898d3c73a ; * doc/emacs/back.texi: Fix a typo.
+ de52dbd4ad Update doc/emacs/ for a new printing of the Emacs Manual book
+
+2021-07-04 Amin Bandali <bandali@gnu.org>
+
+ Update IRC-related references to point to Libera.Chat
+
+ Per GNU and FSF's announcements [0, 1] of moving official IRC channels
+ to the Libera.Chat IRC network, as well as several Emacs-related
+ channels following suit [2], update IRC-related references to reflect
+ the migration.
+
+ [0]: https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00005.html
+ [1]: https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00007.html
+ [2]: https://lists.gnu.org/archive/html/info-gnu-emacs/2021-06/msg00000.html
+
+2021-07-04 Dmitry Gutov <dgutov@yandex.ru>
+
+ Speed up fido-mode
+
+ * lisp/icomplete.el (icomplete-completions): Speed up fido-mode (bug#48841).
+
+2021-07-03 Daniel Martín <mardani29@yahoo.es>
+
+ Fix typo in c-macro-expand docstring
+
+ * lisp/progmodes/cmacexp.el (c-macro-expand): Fix typo. (Bug#49356)
+
+2021-07-03 Christopher League <league@contrapunctus.net>
+
+ Retain documentation string when customizing theme
+
+ * lisp/cus-theme.el (customize-create-theme): When editing an existing
+ theme, load its doc string into the description widget, instead of
+ replacing it with a date stamp (Bug#49274).
+
+2021-07-02 Philip Kaludercic <philipk@posteo.net>
+
+ * lisp/net/rcirc.el (rcirc-define-command): Mention name of malformed command
+
+ Author:
+
+2021-07-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't have desktop-save-mode query on `M-x kill-emacs'
+
+ * lisp/desktop.el (noninteractive): Prompting functions should not
+ be added to `kill-emacs-hook' (bug#28943).
+ (desktop-kill): Return t so that it can be used from
+ `kill-emacs-query-functions'.
+
+2021-07-02 Michael Albinus <michael.albinus@gmx.de>
+
+ Implement another fix for bug#49229
+
+ * lisp/minibuffer.el (read-file-name-default): Respect remote files.
+ (Bug#49229)
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-expand-file-name):
+ Handle special file names on MS Windows.
+
+ * lisp/net/tramp.el (tramp-file-name-handler): Revert patch.
+ (Bug#49229)
+
+2021-07-02 Peter Oliver <git@mavit.org.uk>
+
+ Hide emacs-mail.desktop, emacsclient-mail.desktop from menus
+
+ These are intended for use as mailto: URL handlers, not for launching
+ directly, so we can reduce clutter by hiding them from a desktop
+ environment’s menus.
+
+ * etc/emacs-mail.desktop, etc/emacsclient-mail.desktop: NoDisplay=true
+
+2021-07-02 Peter Oliver <git@mavit.org.uk>
+
+ Install emacs-mail.desktop and emacsclient-mail.desktop
+
+ * Makefile.in (install-etc): Install emacs-mail.desktop and
+ emacsclient-mail.desktop
+
+2021-07-02 Peter Oliver <git@mavit.org.uk>
+
+ Provide an emacsclient-mail.desktop
+
+ We provide both an emacs.desktop and an emacsclient.desktop, so for
+ consistency let’s do the same with mail.
+
+ * etc/emacs-mail.desktop: Extract suggestions for using emacsclient
+ from comments to create emacsclient-mail.desktop.
+ * etc/emacsclient-mail.desktop: Send mail using an existing Emacs
+ rather than starting a new one.
+
+2021-07-02 Tino Calancha <tino.calancha@gmail.com>
+
+ lisp/auth-source-pass.el: Keep legitimate spaces inside data
+
+ Users should be able to store a field as follows:
+ message: remember: Destroy the image and you will break the enemy
+
+ and later, recover the message untouched, i.e.:
+ "remember: Destroy the image and you will break the enemy"
+
+ * lisp/auth-source-pass.el (auth-source-pass--parse-data): Preserve
+ inner spaces at data.
+ * test/lisp/auth-source-pass-tests.el
+ (auth-source-pass-parse-with-colons-in-data): Add test.
+
+2021-07-02 Iku Iwasa <iku.iwasa@gmail.com>
+
+ lisp/auth-source-pass.el: Support multiple hosts in search spec
+
+ * lisp/auth-source-pass.el (auth-source-pass-search): Accept a list of
+ strings for argument HOST.
+ (auth-source-pass--build-result): Rename argument HOST to HOSTS. Also
+ return value "host" from entry if it exists.
+ (auth-source-pass--find-match): Rename argument HOST to HOSTS. Iterate
+ over each host in HOSTS.
+ * test/lisp/auth-source-pass-tests.el: Add corresponding tests
+
+2021-07-02 Jim Porter <jporterbugs@gmail.com>
+
+ Don't pass 'null-device' to 'call-process' in ispell
+
+ * lisp/textmodes/ispell.el (ispell-find-hunspell-dictionaries):
+ Replace 'null-device' with nil (bug#49283). This allows running a
+ local ispell process when editing a buffer editing a file via Tramp.
+
+2021-07-02 Martin Rudalics <rudalics@gmx.at>
+
+ New frame parameter 'drag-with-tab-line' (Bug#49247)
+
+ The new frame parameter 'drag-with-tab-line' allows to move
+ frames by dragging their topmost windows' tab line with the
+ mouse thus achieving a behavior similar to that provided by
+ the 'drag-with-header-line' parameter.
+
+ * lisp/mouse.el (mouse-drag-tab-line): New function.
+ (mouse-drag-frame-resize, mouse-drag-frame-move)
+ ([tab-line down-mouse-1]): Handle tab line dragging in various
+ keymaps.
+ * doc/lispref/frames.texi (Mouse Dragging Parameters): Describe
+ new parameter 'drag-with-tab-line'.
+ * etc/NEWS: Add entry for 'drag-with-tab-line'.
+
+2021-07-02 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix a problem of cus-start.el for remote default directories
+
+ * lisp/cus-start.el: Bind `default-directory' to "/" when calling
+ `shell-command-to-string' for a local value on DARWIN.
+
+2021-07-01 Alan Third <alan@idiocy.org>
+
+ Fix NS self contained eln location (bug#49271)
+
+ * Makefile.in:
+ * configure.ac: Change eln file install location to
+ Contents/Frameworks.
+ * src/comp.c (hash_native_abi): Replace dots with underscores in the
+ eln install location as the macOS code-signing tool won't sign the
+ files if the parent directories have dots.
+
+2021-07-01 Alan Third <alan@idiocy.org>
+
+ Fix NS native comp search path (bug#49270)
+
+ * configure.ac (NS_SELF_CONTAINED): We need to make lispdirrel the
+ same as lispdir when building a self contained app bundle as they're
+ both relative paths.
+
+2021-07-01 Jonas Bernoulli <jonas@bernoul.li>
+
+ * lisp/transient.el: Update to package version 0.3.6.
+
+2021-07-01 Mattias Engdegård <mattiase@acm.org>
+
+ Update describe-prefix-binding manual text
+
+ * doc/emacs/help.texi (Misc Help): `ESC ?` isn't unbound any more.
+
+2021-07-01 Michael Albinus <michael.albinus@gmx.de>
+
+ Handle test environment variables
+
+ * lisp/emacs-lisp/ert.el (ert-summarize-tests-batch-and-exit):
+ Check also for EMACS_EMBA_CI.
+
+ * test/README (SELECTOR): Mention EMACS_TEST_VERBOSE.
+
+ * test/infra/gitlab-ci.yml (variables): Set EMACS_TEST_VERBOSE.
+
+2021-07-01 Peter Oliver <git@mavit.org.uk>
+
+ Fix copy/paste error in emacsclient.desktop
+
+ * etc/emacsclient.desktop: new-instance should read new-window.
+
+2021-07-01 Eli Zaretskii <eliz@gnu.org>
+
+ Update doc/emacs/ for a new printing of the Emacs Manual book
+
+ * doc/emacs/book-spine.texi: New file: the printed book spine.
+ * doc/emacs/back.texi: New file: the backcover text for the
+ printed book.
+ * doc/emacs/emacs.texi: Update ISBN.
+
+2021-07-01 Michael Albinus <michael.albinus@gmx.de>
+
+ Doc cleanup
+
+ * doc/lispref/files.texi (File Locks, Changing Files)
+ (File Name Components, File Name Expansion, Magic File Names):
+ * lisp/files.el (locate-dominating-stop-dir-regexp)
+ (auto-mode-alist, set-auto-mode, file-name-with-extension)
+ (backup-directory-alist, wildcard-to-regexp)
+ (save-buffers-kill-terminal): Doc fixes.
+
+ * etc/NEWS: Fix typos.
+
+2021-06-30 Jonas Bernoulli <jonas@bernoul.li>
+
+ In files that use allout use it for all headings
+
+ * lisp/allout.el: Don't prefix regular comments with three
+ semicolons.
+ * lisp/icomplete.el: Use allout syntax for all headings.
+ * lisp/net/eudc.el: Use allout syntax for all headings.
+
+2021-06-30 Jonas Bernoulli <jonas@bernoul.li>
+
+ * lisp/comint.el: Prefix headings with enough semicolons.
+
+ Outline headings must begin with three or more semicolons.
+
+2021-06-30 Jonas Bernoulli <jonas@bernoul.li>
+
+ Improve consistency of outline headings in dired libraries
+
+ * lisp/dired-aux.el: Improve consistency of outline headings.
+ * lisp/dired-x.el: Improve consistency of outline headings.
+ * lisp/dired.el: Improve consistency of outline headings.
+
+ - Use three semicolons at beginning of headings because that already
+ is the dominant number of semicolons for headings in these files.
+ - Prefix each heading with a ^L instead of randomly omitting it in
+ front of some.
+ - Always prefix the line with the ^L with a completely empty line.
+ - Begin headings with a capital letter.
+ - Do not update complete headings.
+ - Do not end headings with a period.
+ - Remove a handful of section end markers.
+ - Address further inconsistencies.
+
+2021-06-30 Jonas Bernoulli <jonas@bernoul.li>
+
+ Cleanup whitespace and comments in dired libraries
+
+ * lisp/dired-aux.el: Cleanup whitespace and comments.
+ * lisp/dired-x.el: Cleanup whitespace and comments.
+ * lisp/dired.el: Cleanup whitespace and comments.
+
+2021-06-30 Jonas Bernoulli <jonas@bernoul.li>
+
+ Add new function lm-maintainers (bug#48592)
+
+ * doc/lispref/tips.texi (Library Headers): Improve wording.
+ * lisp/emacs-lisp/lisp-mnt.el (lm-maintainers): New function.
+ (lm-maintainer): Make obsolete in favor of lm-maintainer.
+ (lm-verify): Use lm-maintainers.
+ (lm-report-bug): Use lm-maintainers.
+
+2021-06-30 Jonas Bernoulli <jonas@bernoul.li>
+
+ * lisp/emacs-lisp/lisp-mnt.el (lm-crack-address): Right-trim name.
+
+ The addresses might be aligned in which case we have to trim the
+ extra whitespace at the end of the names.
+
+2021-06-30 João Távora <joaotavora@gmail.com>
+
+ Adjust docstring of lisp-mode (bug#49278)
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-mode): Mention that this mode is
+ primarily for Common Lisp.
+
+2021-06-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new user option to transform kill ring contents
+
+ * doc/emacs/killing.texi (Kill Options): Document it.
+ * lisp/simple.el (kill-new): Use it.
+ (kill-transform-function): New user option (bug#29013).
+
+2021-06-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the minor mode doc strings say that they're minor modes
+
+ * lisp/emacs-lisp/easy-mmode.el (easy-mmode--arg-docstring):
+ Mention that this is a minor mode (bug#20462).
+
+2021-06-30 Peter Oliver <git@mavit.org.uk>
+
+ From .desktop files, reuse a frame or start a new Emacs as required
+
+ * doc/emacs/misc.texi: (Using Emacs as a Server) Explain
+ emacsclient.desktop.
+ * etc/NEWS: (Emacs Server): Explain emacsclient.desktop.
+ * etc/emacs-mail.desktop:
+ * etc/emacsclient.desktop: Automatically try to
+ reuse an existing frame, open a new frame, or start a new Emacs
+ daemon. Add actions for specific behaviours (bug#49195).
+
+2021-06-30 Peter Oliver <git@mavit.org.uk>
+
+ Revert more of a partially reverted emacsclient.desktop patch
+
+ * etc/emacsclient.desktop: Undo setting of StartupWMClass=Emacsd, since
+ this relies on a change to etc/emacs.service which was also undone. See
+ bug#37847 for more explanation (bug#49259).
+
+2021-06-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem when creating an .authinfo entry with an existing machine name
+
+ * lisp/auth-source.el (auth-source-netrc-create): Don't return the
+ incorrect data if there's a matching host entry but the wrong user
+ name (bug#49289).
+
+2021-06-30 Colin Woodbury <colin@fosskers.ca>
+
+ Add new function file-name-with-extension
+
+ * doc/lispref/files.texi (File Name Components): Document it.
+ * lisp/emacs-lisp/shortdoc.el (file-name): Ditto.
+
+ * lisp/files.el (file-name-with-extension): New function.
+
+2021-06-29 Alan Third <alan@idiocy.org>
+
+ Fix NS port built with gcc
+
+ * src/nsterm.m (ns_relocate): The NSArray shorthand notation doesn't
+ work in GCC.
+
+2021-06-29 Juri Linkov <juri@linkov.net>
+
+ * lisp/repeat.el (describe-repeat): New command (bug#49265).
+
+2021-06-29 Michael Albinus <michael.albinus@gmx.de>
+
+ Sync with Tramp 2.5.1
+
+ * doc/misc/trampver.texi:
+ * lisp/net/trampver.el: Change version to "2.5.1".
+
+ * lisp/net/tramp.el (tramp-handle-write-region):
+ * lisp/net/tramp-adb.el (tramp-adb-handle-write-region):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-write-region): Call
+ local `write-region' directly.
+
+ * test/lisp/net/tramp-tests.el (tramp--test-utf8): Adapt test for
+ MS Windows.
+
+2021-06-29 Alex McGrath <amk@amk.ie>
+
+ Fix SASL joining channels after auth
+
+ Send CAP END after authentication has been successful
+
+2021-06-29 Martin Rudalics <rudalics@gmx.at>
+
+ In read_minibuf_unwind don't try to select dead window (Bug#49248)
+
+ * src/minibuf.c (read_minibuf_unwind): Don't try to select dead
+ window (Bug#49248).
+
+2021-06-28 Alex McGrath <alexmcgraak@arista.com>
+
+ Fix SASL on rcirc-update
+
+2021-06-28 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ ef5f3d5ee7 (origin/emacs-27) C++ Mode: Handle new keywords static_cas...
+
+2021-06-28 Reuben Thomas <rrt@sc3d.org>
+
+ * lisp/textmodes/ispell.el: Fix finding dictionaries for Enchant.
+
+ (ispell-find-enchant-dictionaries):
+
+ I originally copied this code from the equivalent code for
+ Aspell. Unfortunately it was wrong for the case of Enchant: it should
+ find only dictionaries that Enchant knows about, and not merge in
+ `ispell-dictionary-base-alist' or add a default element, as these
+ are dealt with in `ispell-set-spellchecker-params'.
+
+ This caused a bug where the correct `-d' argument would not be added
+ to the invocation of enchant, leading to the process not being
+ correctly started.
+
+2021-06-28 Reuben Thomas <rrt@sc3d.org>
+
+ * lisp/textmodes/ispell.el: Check process is live before interacting.
+
+ Check that `ispell-process' is live before trying to read from or
+ write to it. This avoids a hang if the process has died.
+
+2021-06-28 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix bug#49229 in shell.el
+
+ * lisp/shell.el (shell): Ensure, that a remote shell is remote.
+ (Bug#49229)
+
+2021-06-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/files.el (hack-one-local-variable): Allow `add-function` in `eval:`
+
+ (Bug#49163)
+
+2021-06-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/textmodes/flyspell.el: Fix bug#49104
+
+ (flyspell--prev-meta-tab-binding): Delete var.
+ (flyspell-prog-mode): Don't set it.
+ (flyspell-auto-correct-word): Lookup the "next" command dynamically.
+
+2021-06-27 Alan Mackenzie <acm@muc.de>
+
+ C++ Mode: Handle new keywords static_cast, etc., wrt angle brackets
+
+ * lisp/progmodes/cc-langs.el (c-<>-arglist-kwds): Add const_cast,
+ dynamic_cast, reinterpret_cast and static_cast into this lang const.
+
+ * lisp/progmodes/cc-engine.el (c-clear-<-pair-props, c-clear->-pair-props)
+ (c-clear-<-pair-props-if-match-after, c-clear->-pair-props-if-match-before)
+ (c-forward-<>-arglist-recur):
+ Invalidate caches with c-trunctate-lit-pos-cache.
+ (c-forward-<>-arglist-recur): If in a matching <...> expression, the < has a
+ syntax-table property, but the > not, remove that property.
+
+2021-06-26 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/minibuffer.el (completion-in-region--single-word): Simplify
+
+ Remove redundant args `collection` and `predicate` which were always
+ equal to `minibuffer-completion-table` and
+ `minibuffer-completion-predicate` anyway.
+
+ (minibuffer-complete-word):
+ * lisp/emacs-lisp/crm.el (crm-complete-word): Simplify accordingly.
+
+2021-06-26 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/minibuffer.el (minibuffer--completion-prompt-end): Rename
+
+2021-06-26 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-macs.el: Fix test regression
+
+ (cl--alist-to-plist): New function.
+ (cl-struct-slot-info): Use it.
+
+2021-06-26 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Tramp bug#49229
+
+ * lisp/net/tramp.el (tramp-file-name-handler): Drop possible
+ volume letter when `expand-file-name' is called with a local
+ absolute file name as first argument. (Bug#49229)
+
+2021-06-26 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/minibuffer.el (completion--prompt-end): New function (bug#30668)
+
+ (minibuffer-complete, minibuffer-force-complete-and-exit)
+ (minibuffer-force-complete, minibuffer-complete-and-exit)
+ (minibuffer-complete-word, minibuffer-completion-help): Use it.
+
+2021-06-26 Alan Third <alan@idiocy.org>
+
+ Fix NS self-contained build configuration
+
+ * configure.ac: When rebuilding epaths.h for NS check that we're
+ actually doing an NS build first.
+
+2021-06-26 Alan Third <alan@idiocy.org>
+
+ Fix NS native compilation builds
+
+ * Makefile.in (ns_applibexecdir):
+ (ns_applibdir):
+ (ns_appdir): New variables.
+ (.PHONY): Include new rule.
+ (epaths-force-ns-self-contained): Remove the app bundle directory from
+ all paths.
+ * configure.ac (NS_SELF_CONTAINED): Set the default site-lisp
+ directory instead of hard-coding it in the ObjC code, and use the new
+ epaths generating make rule.
+ * src/callproc.c (init_callproc_1):
+ (init_callproc): Remove all the NS specific code as the special cases
+ are now handled by decode_env_path.
+ * src/emacs.c (load_pdump):
+ (decode_env_path): Use ns_relocate to find the correct directory after
+ relocation.
+ * src/lread.c (load_path_default): Remove all the NS specific code as
+ the special cases are now handled by decode_env_path.
+ * src/nsterm.h: Update function definitions.
+ * src/nsterm.m (ns_etc_directory):
+ (ns_exec_path):
+ (ns_load_path): Remove functions that are no longer needed.
+ (ns_relocate): New function to calculate paths within the NS app
+ bundle.
+ * nextstep/Makefile.in (ns_applibexecdir): New variable, and update
+ anything relying on the libexec location.
+
+2021-06-26 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Small improvements to handling of IMAP mark search
+
+ * lisp/gnus/gnus-search.el (gnus-search-imap-handle-flag): Use a
+ KEYWORD search for any mark starting with a "$", so
+ "mark:$hasattachment" goes through as "KEYWORD $hasattachment".
+
+2021-06-25 Mattias Engdegård <mattiase@acm.org>
+
+ Print newlines as \n instead of \12 in ERT results
+
+ This makes test errors unquestionably more readable. The change also
+ makes FF print as \f; other controls still use octal escapes.
+
+ * lisp/emacs-lisp/ert.el (ert--pp-with-indentation-and-newline):
+ Run `pp` with `pp-escape-newlines` set to `t`.
+
+2021-06-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make (find-face-definition 'default) work more reliably
+
+ * lisp/emacs-lisp/find-func.el (find-function--defface): New
+ function (bug#30230).
+ (find-function-regexp-alist): Use it to skip past definitions
+ inside comments and strings.
+
+2021-06-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix the name of the sorted minor mode map after previous change
+
+ * lisp/bindings.el (mode-line-major-mode-keymap): Change the name
+ of the minor mode menu items.
+
+2021-06-25 Eli Zaretskii <eliz@gnu.org>
+
+ Fix race conditions between Lisp threads in GTK builds
+
+ * src/xgselect.c (release_select_lock, acquire_select_lock)
+ [GCC >= 4.7.0]: Use '__atomic' builtins to prevent races between
+ threads in accessing 'threads_holding_glib_lock'. Reported by
+ <dick.r.chiang@gmail.com>. (Bug#36609)
+
+2021-06-25 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Tramp bug#49178
+
+ * lisp/net/tramp.el (tramp-handle-find-backup-file-name)
+ (tramp-handle-make-auto-save-file-name): Adapt checks. (Bug#49178)
+
+2021-06-25 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar--define-keys): Fix global-mode-string (bug#49215)
+
+2021-06-25 Stephen Berman <stephen.berman@gmx.net>
+
+ Prevent Org mode from mistakenly changing Calendar keymap
+
+ * lisp/org/org-compat.el (org--setup-calendar-bindings): Fix logic
+ in test of 'org-agenda-diary-file' (bug#48199).
+
+2021-06-25 Eli Zaretskii <eliz@gnu.org>
+
+ Fix syntax-category of some punctuation characters
+
+ * lisp/textmodes/text-mode.el (text-mode-syntax-table): Don't
+ modify the global syntax-table just because we load text-mode.el.
+ This happens at loadup time, and then affects the default syntax
+ in all modes, not just in text-mode and its derivatives.
+ (Bug#49214)
+
+2021-06-24 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/bindings.el (bindings--sort-menu-keymap): Add "menu" in its name
+
+ (bindings--menu-item-string): Use `pcase`.
+
+2021-06-24 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-preloaded.el: Fix the format of props in slot-descs
+
+ (cl--plist-remove): Remove.
+ (cl--plist-to-alist): New function.
+ (cl-struct-define): Use it to convert slots's properties to the
+ format expected by `cl-slot-descriptor`.
+
+ * lisp/emacs-lisp/cl-extra.el (cl--describe-class-slots): Revert last
+ changes, not needed any more.
+
+2021-06-24 Alex McGrath <amk@amk.ie>
+
+ Add SASL authentication to rcirc
+
+ * lisp/net/rcirc.el (rcirc-handler-AUTHENTICATE): New function
+ (bug#48601).
+ (rcirc-authenticate):
+ (rcirc-connect): Support sasl.
+ (rcirc-get-server-password, rcirc-get-server-method): New functions.
+ (rcirc-authinfo): Document it.
+
+2021-06-24 Mattias Engdegård <mattiase@acm.org>
+
+ Don't call ERT explainer on error
+
+ * lisp/emacs-lisp/ert.el (ert--expand-should-1): If the predicate form
+ signals an error, don't call an explainer because the arguments passed
+ (the error and error argument, respectively) do not make any sense to
+ the explainer at all.
+
+2021-06-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Attempt to make defclass documentation more legible
+
+ * lisp/emacs-lisp/cl-extra.el (cl--print-table): Attempt to make
+ defclass documentation more readable (bug#30998).
+ (cl--describe-class-slots): Ditto.
+
+2021-06-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix printing of defclass documentation slots again
+
+ * lisp/emacs-lisp/cl-extra.el (cl--describe-class-slots): Fix
+ printing defclass slots, and retain printing of defstruct slots
+ (bug#30998 and bug#46662).
+
+2021-06-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow `C-u M-x dig' to ask for a query type
+
+ * lisp/net/dig.el (dig): Allow prompting for a query type
+ (bug#31810).
+
+2021-06-24 Alex McGrath <amk@amk.ie>
+
+ Add SASL authentication to rcirc
+
+ * lisp/net/rcirc.el (rcirc-handler-AUTHENTICATE): New function
+ (bug#48601).
+ (rcirc-authenticate):
+ (rcirc-connect): Support sasl.
+ (rcirc-get-server-password, rcirc-get-server-method): New functions.
+ (rcirc-authinfo): Document it.
+
+2021-06-24 E. Choroba <choroba@matfyz.cz>
+
+ Fix highlighting in cperl-mode for "for /regex/"
+
+ * lisp/progmodes/cperl-mode.el (cperl-find-pods-heres): Fix
+ highlighting of regexp in "print for /./;" (bug#49192).
+
+2021-06-24 Jim Porter <jporterbugs@gmail.com>
+
+ Ignore file-missing errors during diff-refined font-locking
+
+ * lisp/vc/diff-mode.el (diff--font-lock-refined): Ignore file-missing
+ errors (bug#49197).
+
+2021-06-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify the help in the package buffers
+
+ * lisp/emacs-lisp/package.el (package--quick-help-keys): Clarify
+ marking help (bug#40457).
+
+2021-06-24 Jim Porter <jporterbugs@gmail.com>
+
+ Sort the items in 'mode-line-mode-menu' before displaying the menu
+
+ * lisp/bindings.el (bindings--menu-item-string, bindings--sort-keymap):
+ New functions.
+ (mode-line-major-mode-keymap, mode-line-minor-mode-keymap):
+ Sort 'mode-line-mode-menu'.
+
+2021-06-23 Saroj Thirumalai <emacs_bugs.saroj@thirumalai.com> (tiny change)
+
+ * lisp/printing.el (pr-global-menubar): Fix duplicate menu problem.
+
+ In Emacs 27.1 Print menu items were moved to a submenu of the File menu.
+ The Printing package (lisp/printing.el) replaces the Print menu (via the
+ function: pr-global-menubar). The latter needs to be updated to reflect the
+ changes; otherwise, a second Print (sub)menu is created at the end of the
+ File menu.
+
+2021-06-23 Mauro Aranda <maurooaranda@gmail.com>
+
+ Fix defvar->defcustom conversion in ethio-util.el
+
+ * lisp/language/ethio-util.el (ethio-primary-language)
+ (ethio-secondary-language): Don't quote the const.
+ (ethio-use-three-dot-question, ethio-quote-vowel-always)
+ (ethio-W-sixth-always, ethio-numeric-reduction)
+ (ethio-java-save-lowercase): Really make them defcustom.
+
+2021-06-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make ethio-* variables into user options
+
+ * lisp/language/ethio-util.el (ethiopic): New group.
+ (ethio-primary-language, ethio-secondary-language)
+ (ethio-use-colon-for-colon, ethio-use-three-dot-question)
+ (ethio-quote-vowel-always, ethio-W-sixth-always)
+ (ethio-numeric-reduction, ethio-java-save-lowercase): Make into
+ user options (bug#33024).
+
+2021-06-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Sort the items in 'mode-line-mode-menu' before displaying the menu"
+
+ This reverts commit d4d6d8f335165e2bda8942b4acd45e5bab613b70.
+
+ This approach doesn't work on certain types of keymaps, so it should be implemented in a different way.
+
+2021-06-23 Jim Porter <jporterbugs@gmail.com>
+
+ Sort the items in 'mode-line-mode-menu' before displaying the menu
+
+ * lisp/bindings.el (bindings--menu-item-string, bindings--sort-keymap):
+ New functions.
+ (mode-line-major-mode-keymap, mode-line-minor-mode-keymap):
+ Sort 'mode-line-mode-menu'.
+
+2021-06-23 dickmao <none>
+
+ Clean up code in `message-replace-header'
+
+ * lisp/gnus/message.el (message-replace-header): Elide redundancy
+ (bug#49180).
+
+2021-06-23 dickmao <none>
+
+ Fix message-replace-header after recent change
+
+ * lisp/gnus/message.el (message-replace-header): Restore else
+ branch removed by mistake in 989de3b824 (bug#49179).
+
+2021-06-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Give feedback to the user in dired-do-find-regexp
+
+ * lisp/dired-aux.el (dired-do-find-regexp): Give some feedback to
+ the user (bug#35352).
+
+2021-06-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make minor mode docstrings say what the mode "variable" is
+
+ * lisp/emacs-lisp/easy-mmode.el (easy-mmode--arg-docstring): Add
+ the mode variable (bug#36500).
+ (easy-mmode--mode-docstring):
+ (define-minor-mode): Pass in the getter.
+
+2021-06-22 Protesilaos Stavrou <info@protesilaos.com>
+
+ Use named face for apropos-button
+
+ * etc/NEWS: Document new face.
+ * lisp/apropos.el (apropos-button): Define new face.
+ (apropos-face): Specify face instead of hardcoding
+ attributes (bug#49162).
+
+2021-06-22 Peter Oliver <git@mavit.org.uk>
+
+ If the daemon’s TTY is our only frame, create a new frame
+
+ * lisp/server.el (server-process-filter): If there won't be a
+ current frame to use, fall back to trying to create a new one
+ (bug#11033).
+
+2021-06-22 Peter Oliver <git@mavit.org.uk>
+
+ Advertise support for Startup Notification when built with GTK
+
+ * etc/emacsclient.desktop, etc/emacsclient.desktop: Specify
+ StartupNotify=true.
+ * configure.ac (USE_STARTUP_NOTIFICATION): New variable, yes iff
+ HAVE_GTK.
+ * Makefile.in (install-etc): Remove StartupNotify=true from
+ etc/*.desktop unless USE_STARTUP_NOTIFICATION (bug#48783).
+
+2021-06-22 Utkarsh Singh <utkarsh190601@gmail.com>
+
+ Make tex-compile-commands heed tex-start-options
+
+ * lisp/textmodes/tex-mode.el (tex-compile-commands): Respect
+ `tex-start-options' (bug#49018).
+
+2021-06-22 Eli Zaretskii <eliz@gnu.org>
+
+ Fix "make -j install"
+
+ * Makefile.in (install-eln): Depend on 'lisp', so that people
+ could say "make -j install" without a separate "make" step.
+ (Bug#49099)
+
+2021-06-22 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ time-stamp: add principled, expressive %z
+
+ * lisp/time-stamp.el (time-stamp-formatz-from-parsed-options): New
+ function for time zone offset formatting ("%z" variants).
+
+ * test/lisp/time-stamp-tests.el (formatz*): New unit tests to cover
+ the new implementation of %5z.
+
+2021-06-21 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix shortdoc-add-function section creation
+
+ * lisp/emacs-lisp/shortdoc.el (shortdoc-add-function): Use nconc to
+ actually append a new section to the list of groups while avoiding a
+ previous OBOE. Push a new group to the front of shortdoc--groups
+ without copying it, just like define-short-documentation-group does.
+ (buffer): Fix copypasta in unlock-buffer example.
+
+ * test/lisp/emacs-lisp/shortdoc-tests.el (shortdoc-examples): Also
+ check that :no-value forms demonstrate the right function.
+
+ * doc/lispref/help.texi (Documentation Groups): Clarify that @dots
+ in the define-short-documentation-group arglist refer to whole
+ key-value pairs. Fix typo in :eg-result-string description.
+
+2021-06-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ NEWS for tool bar "X" in *Help* buffers change (bug#49139)
+
+2021-06-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix prompting for large files when loading literally
+
+ * lisp/files.el (find-file-noselect): Don't include "literally" in
+ the "large file" prompt if we're gonna load literally anyway
+ (bug#49144).
+
+2021-06-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make find-file-literally ignore local variables again
+
+ * lisp/files.el (find-file-noselect-1): Re-inhibit local variables
+ when loading a file literally (bug#49143). This was broken by
+ 5bedbe6b1d.
+
+2021-06-21 Alex Bochannek <alex@bochannek.com>
+
+ Refactor gnus-article-sort-by-*
+
+ * lisp/gnus/gnus-sum.el (gnus-article-sort-extract-extra): New
+ function (bug#49081).
+ (gnus-article-sort-by-recipient): Use it.
+ (gnus-article-sort-by-newsgroups): Ditto.
+
+2021-06-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further fixes for bound-and-true-p doc string
+
+ * lisp/bindings.el (bound-and-true-p): Improve doc string.
+
+2021-06-21 Andrea Corallo <akrl@sdf.org>
+
+ Do not attempt to write .elc files when not necessary (bug#49118)
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-file): Do not attempt to
+ write .elc files when not necessary.
+
+2021-06-21 Philip Kaludercic <philipk@posteo.net>
+
+ Query encryption using yes-or-no-p
+
+ * lisp/net/rcirc.el (rcirc-prompt-for-encryption): Replace completing-read
+ prompt with yes-or-no-p
+
+2021-06-20 Alan Third <alan@idiocy.org>
+
+ Fix GNUstep menu update crashes
+
+ * src/nsmenu.m (ns_update_menubar): close the submenus before modifying them.
+ ([EmacsMenu close]): Make sure to close all submenus.
+
+2021-06-20 Alan Third <alan@idiocy.org>
+
+ Fix GNUstep build warnings
+
+ * src/nsterm.h ([EmacsWindow orderedIndex]):
+ * src/nsterm.m ([EmacsWindow orderedIndex]): Implement orderedIndex
+ for use under GNUstep.
+ * src/nsmenu.m (free_frame_menubar):
+ (ns_update_menubar):
+ ([EmacsMenu addSubmenuWithTitle:]):
+ ([EmacsMenu addItemWithWidgetValue:attributes:]): Cast return values
+ to correct types.
+ ([EmacsMenu fillWithWidgetValue:]): Move variable definition inside
+ relevant #ifdef block.
+ ([EmacsMenu menuWillOpen:]):
+ ([EmacsMenu menuDidClose:]):
+ ([EmacsMenu confinementRectForMenu:onScreen:]):
+ ([EmacsMenu menu:willHighlightItem:]): New functions to silence build
+ warnings.
+ * src/nsfont.m (nsfont_open): Remove pointless fabs call.
+
+2021-06-20 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt tests in tramp-archive-tests.el
+
+ * test/lisp/net/tramp-archive-tests.el
+ (tramp-archive-test05-expand-file-name)
+ (tramp-archive-test06-directory-file-name): Adapt tests.
+
+2021-06-20 Grant Shangreaux <grant@churls.world>
+
+ Add input methods for Lakota
+
+ The White Hat and Suggested Lakota Orthography are represented here
+ by three different input modes: A prefix and postfix mode for the SLO,
+ and a postfix mode for the White Hat orthography.
+ * lisp/leim/quail/latin-post.el (lakota-slo-postfix)
+ (lakota-white-hat-postfix):
+ * lisp/leim/quail/latin-pre.el (lakota-slo-prefix): New input methods.
+ * etc/HELLO: Call out the additions.
+
+2021-06-20 Juri Linkov <juri@linkov.net>
+
+ Add new convenience command for *Help*
+
+ * doc/emacs/help.texi (Help Mode): Document it (bug#36767).
+
+ * lisp/help-mode.el (help-mode-map): Add 'c'.
+ (help-mode-menu): Add help-customize.
+ (help-customize): New command.
+
+2021-06-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix error in tramp-archive.el
+
+ * lisp/net/tramp-archive.el (tramp-archive-file-name-handler):
+ Archive must exist. (Bug#49030, Bug#49043)
+
+ * test/lisp/net/tramp-archive-tests.el
+ (tramp-archive-test06-directory-file-name): Tag it :unstable temporarily.
+
+2021-06-19 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 7722b510aa (origin/emacs-27) Another improvement in documentation of ...
+ 8d5c70d73a Improve documentation of profiler
+ 0ffef0b46b Document 'ispell-program-name'
+ 7be610f911 Fix documentation of 'face-extend-p'
+
+ # Conflicts:
+ # doc/lispref/debugging.texi
+
+2021-06-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use file-truename on files loaded with "emacs -l"
+
+ * lisp/startup.el (command-line-1): When loading a file, use the
+ truename so that eval-after-load works more reliably (bug#49009).
+ Change suggested by ctarbide@tuta.io.
+
+2021-06-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve bound-and-true-p doc string
+
+ * lisp/bindings.el (bound-and-true-p): Improve doc string (bug#49116).
+
+2021-06-19 dickmao <none>
+
+ De-obfuscate gnutls_handshake loop
+
+ * src/gnutls.c (gnutls_try_handshake): Rewrite the handshake loop
+ for greater clarity (bug#49055).
+
+2021-06-19 Alex Bochannek <alex@bochannek.com>
+
+ New Gnus Summary buffer sort options for extra headers
+
+ * lisp/gnus/gnus-sum.el (gnus-article-sort-functions)
+ (gnus-thread-sort-functions, gnus-subthread-sort-functions)
+ (gnus-summary-mode-map, gnus-summary-make-menu-bar)
+ (gnus-article-sort-by-newsgroups)
+ (gnus-summary-sort-by-newsgroups, gnus-summary-sort-by-extra):
+ Sort by Newsgroups extra header. Prompt for header name for other
+ extra headers.
+
+ * doc/misc/gnus.texi (Summary Sorting): Document new sort functions
+
+ * etc/NEWS: New Gnus Summary buffer sort feature (bug#49081).
+
+2021-06-19 Eli Zaretskii <eliz@gnu.org>
+
+ Another improvement in documentation of "memory" profiler
+
+ * lisp/profiler.el (profiler-start): Fix the doc string to better
+ explain what is "memory" profiler.
+
+2021-06-19 Łukasz Stelmach <stlman@poczta.fm>
+
+ Allow `message-replace-header' to take a list of AFTERs
+
+ * lisp/gnus/message.el (message-replace-header): Facilitate
+ capability of message-position-on-field to accept multiple headers
+ as AFTERS argument and make possible to mimic behavioir of
+ message-goto-* functions with message-replace-header in case the
+ header does not exist (bug#49070).
+
+2021-06-19 Alex Bochannek <alex@bochannek.com>
+
+ Add support for displaying total number of groups in subgroups in Gnus
+
+ * lisp/gnus/gnus-topic.el (gnus-topic-line-format)
+ (gnus-topic-line-format-alist, gnus-topic-prepare-topic)
+ (gnus-topic-insert-topic-line, )
+ (gnus-topic-display-missing-topic, )
+ (gnus-topic-update-topic-line):
+ Provide number of groups in subtopics for topic line display and
+ add 'G' element to be used for 'gnus-topic-line-format' variable
+
+ * doc/misc/gnus.texi (Topic Variables):
+ Document 'G' element for 'gnus-topic-line-format' variable (bug#49068).
+
+2021-06-19 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of profiler
+
+ * doc/lispref/debugging.texi (Profiling): Stop misleading users
+ about what "memory" profiling really is.
+
+2021-06-19 Jim Porter <jporterbugs@gmail.com>
+
+ Improve to selsel doc strings
+
+ * lisp/delsel.el (delete-active-region): Document interactive behavior.
+ * lisp/delsel.el (delete-selection-repeat-replace-region):
+ Use "\\[universal-argument]" instead of literal "C-u" in docstring.
+
+2021-06-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Revert "Add `file-name-set-extension'"
+
+ This reverts commit 4f1a5e456e35930e8d0713b990bd7b14923cfe97.
+
+2021-06-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Add `file-name-set-extension'
+
+ * lisp/files.el (file-name-with-extension): New defun.
+
+ * test/lisp/files-tests.el (files-tests-file-name-with-extension-good)
+ (files-tests-file-name-with-extension-bad): New tests.
+
+2021-06-19 Philip Kaludercic <philipk@posteo.net>
+
+ Use add-to-list instead of manually modifying minor-mode-alist
+
+2021-06-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Handle case remote uid is 0 in some Tramp related tests
+
+ * test/lisp/filenotify-tests.el:
+ * test/lisp/shadowfile-tests.el:
+ Set `tramp-allow-unsafe-temporary-files' to t.
+
+2021-06-18 Mattias Engdegård <mattiase@acm.org>
+
+ Fix Morse for non-ASCII letters
+
+ * lisp/play/morse.el (morse-code): Downcase letters in the table
+ because they must match downcased input.
+
+2021-06-18 Eli Zaretskii <eliz@gnu.org>
+
+ Improve and update the 'etags' test suite
+
+ * lib-src/etags.c (mercury_pr): Remove redundant comment.
+
+ * test/manual/etags/merc-src/accumulator.m: Add more complex
+ declarations.
+ * test/manual/etags/ETAGS.good_1:
+ * test/manual/etags/ETAGS.good_2:
+ * test/manual/etags/ETAGS.good_3:
+ * test/manual/etags/ETAGS.good_4:
+ * test/manual/etags/ETAGS.good_5:
+ * test/manual/etags/ETAGS.good_6:
+ * test/manual/etags/CTAGS.good: Adapt to latest changes in 'etags'
+ and the test suite. (Bug#47408)
+
+2021-06-18 Fabrice Nicol <fabrnicol@gmail.com>
+
+ Fix Mercury support, notably qualified procedures.
+
+ Correct the previous fix (did not correctly handle qualified types).
+ Also fix the following issues:
+ - remove module name (+ dot) from tags, as prefixing module name is
+ often inconsistent in code and may cause tags to be too specific.
+ - now tag 0-arity predicates and functions (':- func foo_14.')
+ - now tag one-word declarations (':- interface.')
+
+ * lib-src/etags.c (mercury_pr): Pass the correct NAME and NAMELEN
+ arguments to 'make_tag'.
+ (mercury_decl): Return more information about the declaration or
+ definition it finds. This allows mercury_pr to be smarter.
+ (Bug#47408)
+
+2021-06-18 Philipp Stephani <phst@google.com>
+
+ Update SCSS test file syntax.
+
+ According to
+ https://sass-lang.com/documentation/breaking-changes/slash-div, the
+ slash operator should be replaced by 'math.div'.
+
+ Fixed using the migration tool mentioned at
+ https://sass-lang.com/documentation/breaking-changes/slash-div#automatic-migration.
+
+ * test/manual/indent/scss-mode.scss: Remove slash operator.
+
+2021-06-18 Arash Esbati <arash@gnu.org>
+
+ Use \footref when referencing a footnote label
+
+ * lisp/textmodes/reftex-vars.el (reftex-label-alist-builtin): Use
+ \footref as `reference-format' for \footnote macro.
+
+2021-06-18 Arash Esbati <arash@gnu.org>
+
+ Support new LaTeX kernel macro \footref
+
+ * lisp/textmodes/reftex-vars.el (reftex-ref-style-alist): Add
+ entry for \footref macro which is part of LaTeX kernel 2021-06-01.
+
+2021-06-17 Juri Linkov <juri@linkov.net>
+
+ * lisp/help-fns.el (help--symbol-class): Concat chars for all namespaces.
+
+ Since Emacs Lisp is more than Lisp-2, separately output letters
+ for each namespace: functions, variables, faces, classes.
+ Use non-letter characters for additional properties
+ such as advice, obsolete, local.
+ (help--symbol-completion-table-affixation): Use format "%-4s".
+ https://lists.gnu.org/archive/html/emacs-devel/2021-06/msg00524.html
+
+2021-06-17 Juri Linkov <juri@linkov.net>
+
+ Fix display-buffer-override-next-command for no-select case (bug#49057)
+
+ * lisp/window.el (display-buffer-override-next-command):
+ Separate 'postfun' from 'clearfun', so 'clearfun' resets
+ 'display-buffer-overriding-action', whereas 'postfun' calls
+ 'post-function' that can select the right window in 'post-command-hook'.
+
+ * lisp/windmove.el (windmove-display-no-select): Add new choice 'ignore'.
+ Improve docstring.
+ (windmove-display-in-direction): Use new value 'ignore' of
+ 'windmove-display-no-select'. Improve docstring.
+ (windmove-display-left, windmove-display-up)
+ (windmove-display-right, windmove-display-down): Mention
+ 'windmove-display-no-select' in docstrings.
+
+2021-06-16 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-generic.el: Fix bug#49053 and bug#47454
+
+ (cl-generic-define-method): Shorten the time window where the symbol is
+ defined to `dummy`.
+
+2021-06-16 Mattias Engdegård <mattiase@acm.org>
+
+ Eliminate some GCC warnings
+
+ * src/doprnt.c (exprintf, evxprintf):
+ * src/lisp.h (exprintf, evxprintf): Don't use a pointer-to-const type
+ for the `nonheapbuf` argument: although it is never dereferenced, GCC
+ will warn when passing a pointer to uninitialised memory otherwise.
+ * src/fns.c (sort_vector_copy, realize_face, realize_gui_face)
+ (realize_tty_face): Use the same signatures in the prototypes as in
+ the actual function definitions.
+
+2021-06-16 Glenn Morris <rgm@gnu.org>
+
+ * lisp/simple.el (save-interprogram-paste-before-kill): Fix type.
+
+2021-06-16 Mattias Engdegård <mattiase@acm.org>
+
+ * src/xdisp.c (gui_draw_bottom_divider): Fix misleading indentation.
+
+2021-06-16 Mattias Engdegård <mattiase@acm.org>
+
+ Remove outdated advise from manual
+
+ * doc/lispref/modes.texi (Search-based Fontification):
+ Remove paragraph that has been unnecessary and confusing ever since
+ regexp-opt stopped using capturing brackets more than 21 years ago.
+
+2021-06-16 Pip Cet <pipcet@gmail.com>
+
+ Prepare pdumper dump file in memory, write it in one go (Bug#46881)
+
+ * src/pdumper.c (struct dump_context): Add buf, buf_size, max_offset fields.
+ (dump_grow_buffer): New function.
+ (dump_write): Use memcpy, not an actual emacs_write.
+ (dump_seek): Keep track of maximum seen offset. Don't actually seek.
+ (Fdump_emacs_portable): Write out the file contents when done.
+
+2021-06-16 Philip Kaludercic <philipk@posteo.net>
+
+ Force mode line update after modifying activity string
+
+ * lisp/net/rcirc.el (rcirc-update-activity-string): Call force-mode-line-update
+
+2021-06-16 pillule <pillule@riseup.net>
+
+ User option to choose a function triggered by windmove-create (bug#48917)
+
+ * lisp/windmove.el (windmove-create-window): Add a defcustom choice.
+ (windmove-do-window-select): Trigger custom functions, update the docstring.
+
+2021-06-16 pillule <pillule@riseup.net>
+
+ User option to select 'no-other-window' with windmove (bug#48916)
+
+ * lisp/windmove.el (windmove-wrap-around): Remove superfluous :group tag.
+ (windmove-create-window): Remove superfluous :group tag.
+ (windmove-window-distance-delta): Remove superfluous :group tag.
+ (windmove-allow-all-windows): Add new user option to allow the commands
+ of windmove to target windows with the 'no-other-window parameter.
+ (windmove-find-other-window): Use windmove-allow-all-windows.
+ (windmove-display-no-select): Remove superfluous :group tag.
+ (windmove-display-in-direction): Use windmove-allow-all-windows.
+ (windmove-delete-in-direction): Use windmove-allow-all-windows.
+ (windmove-swap-states-in-direction): Use windmove-allow-all-windows.
+ (windmove-default-keybindings): Remove superfluous :group tag.
+ (windmove-display-default-keybindings): Remove superfluous :group tag.
+ (windmove-delete-default-keybindings): Remove superfluous :group tag.
+ (windmove-swap-states-default-keybindings): Remove superfluous :group tag.
+
+2021-06-15 Philip Kaludercic <philipk@posteo.net>
+
+ Fix edge case with single argument for rcirc-define-command
+
+ * lisp/net/rcirc.el (rcirc-define-command): Update regular expression generator
+
+2021-06-15 Philip Kaludercic <philipk@posteo.net>
+
+ Fix argument parser for rcirc-define-command with string input
+
+ * lisp/net/rcirc.el (rcirc-define-command): Require at least one space between
+ arguments
+
+2021-06-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make help-view-source more robust
+
+ * lisp/help-mode.el (help-view-source): Check the right thing to
+ see if we can jump to the source file.
+
+2021-06-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new convenience commands for *Help*
+
+ * doc/emacs/help.texi (Help Mode): Document it (bug#36767).
+
+ * lisp/help-fns.el (help-fns-function-description-header)
+ (describe-variable, describe-face, describe-keymap)
+ (describe-mode): Add the required data.
+
+ * lisp/help-mode.el (help-mode-map): Add 'i' and 's'.
+ (help-mode--current-data): New variable.
+ (help-mode): Make it local.
+ (help-view-source, help-goto-info): New commands.
+
+2021-06-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify (interactive "K") in the manual
+
+ * doc/lispref/commands.texi (Interactive Codes): Clarify
+ (interactive "K") (bug#37146).
+
+2021-06-15 Philip Kaludercic <philipk@posteo.net>
+
+ Check if server buffer is live
+
+ * lisp/net/rcirc.el (with-rcirc-server-buffer): Use live-buffer-p
+ (rcirc-buffer-nick): Use with-rcirc-server-buffer
+ (rcirc-switch-to-server-buffer): Use with-rcirc-server-buffer
+
+2021-06-15 Eli Zaretskii <eliz@gnu.org>
+
+ Document 'ispell-program-name'
+
+ * doc/emacs/fixit.texi (Spelling): Document
+ 'ispell-program-name'. (Bug#49039)
+
+2021-06-15 Julian Scheid <jscheid@protonmail.com>
+
+ Allow ERT tests to output the failure reasons, too
+
+ * lisp/emacs-lisp/ert.el (ert-reason-for-test-result): New function.
+ (ert-run-tests-batch): Output failure or skip reason (bug#47071).
+
+2021-06-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new function syntax-class-to-char
+
+ * doc/lispref/syntax.texi (Syntax Table Internals): Document it.
+ * src/syntax.c (Fsyntax_class_to_char): New function (bug#37452).
+
+2021-06-15 Jared Finder <jared@finder.org>
+
+ Fix dragging dividers in terminal Emacs when there's margins
+
+ * lisp/mouse.el (mouse-drag-line): Do the right thing in the
+ presence of margins (bug#41156).
+ (mouse-drag-line): Bind left-margin/right-margin in the map, too.
+
+2021-06-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document `completions-format'
+
+ * doc/emacs/mini.texi (Completion Options): Document
+ `completions-format'.
+
+ * lisp/simple.el (completion-list-mode): Mention in (bug#49003).
+
+2021-06-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix false positives in docstring width warning with (fn...) constructs.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile--wide-docstring-p):
+ Don't consider the function signature when determining whether the
+ doc string is too wide (bug#49007). (The signature is folded
+ later when displaying help.)
+
+2021-06-15 Philip Kaludercic <philipk@posteo.net>
+
+ Improve message markup
+
+ * lisp/net/rcirc.el (rcirc-markup-text-functions): Add rcirc-color-attributes,
+ rcirc-remove-markup-codes
+ (rcirc-markup-attributes): Recognize strike-through and monospace,
+ don't remove control codes
+ (rcirc-color-attributes): Recognize mIRC color codes
+ (rcirc-remove-markup-codes): Add function
+ (rcirc-monospace-text): Add face
+
+2021-06-15 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ mh-junk need not support SpamAssassin 2.20 from 2003
+
+ * lisp/mh-e/mh-junk.el (mh-spamassassin-*list): Remove support
+ for SpamAssassin 2.20. (SpamAssassin 3.0 was released in 2004.)
+ This change updates both the flags for sa-learn and the comments
+ about how the current version works.
+
+ This change reverts part of a change made in 2003 that added
+ support for what was even then an "old version of spamassassin."
+
+2021-06-14 Philip Kaludercic <philipk@posteo.net>
+
+ Fix construction of interactive specification in rcirc-define-command
+
+ * lisp/net/rcirc.el (rcirc-define-command): Ensure that only one argument is passed.
+
+2021-06-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove unused variable from sgml-mode test
+
+ * test/lisp/textmodes/sgml-mode-tests.el (sgml-test-brackets):
+ Remove unused variable.
+
+2021-06-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Get fractional seconds in iso8601 parsing right
+
+ * lisp/calendar/iso8601.el (iso8601-parse-time): Get fractional
+ times (with leading zeroes in the fraction part) right (bug#49017).
+ Fix based on a patch by "J.P." <jp@neverwas.me>.
+
+2021-06-14 Andrea Corallo <akrl@sdf.org>
+
+ Do not produce .elc temporary file when unnecessary (bug#48978)
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-file): Produce .elc
+ temporary files only when non native compiling or when native
+ compiling but `byte+native-compile' is non nil.
+
+2021-06-14 Stephen Berman <stephen.berman@gmx.net>
+
+ Fix problem in HTML with bracketed characters
+
+ * lisp/textmodes/sgml-mode.el (sgml-tag-syntax-table): Use bracket
+ syntax for all Unicode bracket characters (bug#43941).
+
+2021-06-14 Andrea Corallo <akrl@sdf.org>
+
+ ;* lisp/emacs-lisp/bytecomp.el (byte-native-compiling): Typo fix.
+
+ * lisp/emacs-lisp/bytecomp.el (byte+native-compile): Update docstring.
+
+2021-06-14 Philip Kaludercic <philipk@posteo.net>
+
+ Rename set-rcirc-{encode,decode}-coding-system
+
+ * lisp/net/rcirc.el (set-rcirc-decode-coding-system): Deprecate command
+ (rcirc-set-decode-coding-system): New command
+ (set-rcirc-encode-coding-system): Deprecate command
+ (rcirc-set-encode-coding-system): New command
+
+2021-06-14 Philip Kaludercic <philipk@posteo.net>
+
+ Preserve order of completion during cycling
+
+ * lisp/net/rcirc.el (rcirc-completion-at-point): Specify cycle-sort-function
+
+2021-06-14 Michael Albinus <michael.albinus@gmx.de>
+
+ Handle sensitive auto-save or backup remote files (Bug#45245)
+
+ * doc/misc/tramp.texi (Auto-save and Backup):
+ Describe tramp-allow-unsafe-temporary-files.
+ (Ad-hoc multi-hops): Use proper format.
+
+ * etc/NEWS: Mention confirmation for writing sensitive auto-save
+ or backup remote files to the local temporary directory..
+
+ * lisp/net/tramp-cache.el (tramp-dump-connection-properties):
+ Strengthen test.
+
+ * lisp/net/tramp.el (tramp-allow-unsafe-temporary-files): New defcustom.
+ (tramp-handle-find-backup-file-name)
+ (tramp-handle-make-auto-save-file-name): Don't expose sensible
+ auto-save or backup files on local temporary directory. (Bug#45245)
+
+ * test/lisp/net/tramp-tests.el (tramp--test-always): New defalias.
+ (tramp-test10-write-region, tramp-test21-file-links)
+ (tramp--test--deftest-direct-async-process): Use it.
+ (tramp-test37-make-auto-save-file-name)
+ (tramp-test38-find-backup-file-name): Extend tests.
+
+2021-06-14 pillule <pillule@riseup.net>
+
+ Improve handling of dedicated flag for side windows (Bug#48493)
+
+ * doc/lispref/windows.texi (Buffers and Windows): Mention the
+ special handling of side windows and add a reference.
+ (Buffer Display Action Alists): Say explicitly that
+ `display-buffer-in-side-window' is dedicating to side by default.
+ (Dedicated Windows): Add case (4) and explain its meaning, add
+ a reference.
+ (Displaying Buffers in Side Windows): Move the paragraph about
+ `switch-to-(prev|next)-buffer' into a new item to emphasize the
+ special meaning of dedication for side windows.
+ * lisp/window.el (set-window-buffer-start-and-point): Restore
+ side dedication.
+ (switch-to-prev-buffer, switch-to-next-buffer): Correct return
+ value that should be nil instead of the same buffer in case of
+ no change.
+ (delete-windows-on): Restore side dedication.
+ (replace-buffer-in-windows): Update the docstring, restore side
+ dedication.
+ (quit-restore-window): Rearrange the logic so that strongly
+ dedicated windows are eventually deleted first. Restore the
+ side dedication. In the final case try to
+ `switch-to-prev-buffer' before deleting a window (Bug#48367).
+
+2021-06-14 Philip Kaludercic <philipk@posteo.net>
+
+ Add mouse properties to activity string
+
+ * lisp/net/rcirc.el (rcirc-activity-string): Allow clicking on string
+
+2021-06-13 Philip Kaludercic <philipk@posteo.net>
+
+ Update activity string after switching to next active buffer
+
+ * lisp/net/rcirc.el (rcirc-next-active-buffer): Call rcirc-update-activity-string
+
+2021-06-13 Eli Zaretskii <eliz@gnu.org>
+
+ Fix documentation of 'face-extend-p'
+
+ * doc/lispref/display.texi (Attribute Functions): Fix description
+ of 'face-extend-p'. (Bug#48936)
+
+2021-06-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous pulse.el fix
+
+ * lisp/cedet/pulse.el (pulse-reset-face): Fix up previous
+ pulse-reset-face change -- reset back to the start face
+ (bug#48936).
+
+2021-06-13 dickmao <dick.r.chiang@gmail.com>
+
+ Avoid an infinite loop in mml-expand-html-into-multipart-related
+
+ * lisp/gnus/mml.el (mml-expand-html-into-multipart-related):
+ Skip images with empty filename parts (bug#49001).
+
+2021-06-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Reset the pulse face more fully in pulse-reset-face
+
+ * lisp/cedet/pulse.el (pulse-reset-face): Reset the :extend to nil
+ if there's no face given (bug#48936).
+
+2021-06-13 Eli Zaretskii <eliz@gnu.org>
+
+ Fix wording of recently added documentation
+
+ * etc/NEWS:
+ * lisp/simple.el (save-interprogram-paste-before-kill): Fix
+ wording of a recently added documentation. (Bug#41168)
+
+2021-06-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fsubstitute_in_file_name doc string clarification
+
+ * src/fileio.c (Fsubstitute_in_file_name): Mention that undefined
+ variables aren't replaced (as opposed to what happens in a shell
+ substitution) (bug#40949).
+
+2021-06-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow save-interprogram-paste-before-kill to be a number
+
+ * doc/emacs/killing.texi (Clipboard): Document it.
+ * lisp/simple.el (save-interprogram-paste-before-kill): Extend
+ range (bug#41168).
+ (kill-new): Implement it (bug#41168).
+
+2021-06-13 Juri Linkov <juri@linkov.net>
+
+ * doc/emacs/windows.texi (Change Window): Add pxref to (elisp)Deleting Windows
+
+ (Bug#47300)
+
+2021-06-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ EIEIO: Promote the CLOS behavior over the EIEIO-specific behavior
+
+ Change docs to advertize `slot-value` rather than `oref`.
+ Change the implementation of `:initform` to better match the CLOS semantics,
+ while preserving the EIEIO semantics, but warn when encountering cases
+ where the two diverge.
+ Demote the mostly unused special semantics of `oref-default`
+ on non-class allocated slots.
+
+ * doc/misc/eieio.texi (Quick Start): Use `slot-value`.
+ (Accessing Slots): Move `slot-value` before `oref`.
+ Fix paren-typo in example (reported by pillule <pillule@riseup.net>).
+ (Introspection): Remove mention of `class-slot-initarg`.
+
+ * lisp/transient.el (transient--parse-group, transient--parse-suffix):
+ Don't use `oref-default` to get the default value.
+ (transient-lisp-variable): Init forms are evaluated.
+
+ * lisp/emacs-lisp/eieio.el (defclass): Warn about inapplicable
+ `:initarg` and about uses of init forms that are ambiguous.
+ (oref): Don't advertize the deprecated use of initargs as slot names.
+ (oref-default): Don't advertize the deprecated case where it returns the
+ initform's value.
+ (initialize-instance): Use `macroexp-const-p`.
+ * lisp/emacs-lisp/eieio-core.el (eieio--unbound): Rename from
+ `eieio-unbound`.
+ (eieio--unbound-form): New var.
+ (eieio--slot-override): Use it.
+ (eieio-defclass-internal): Use it. Change `init` so it should always
+ be evaluated.
+ (eieio--known-class-slot-names): New var.
+ (eieio--eval-default-p): Rename from `eieio-eval-default-p`.
+ (eieio--perform-slot-validation-for-default): Use `macroexp-const-p` to
+ decide whether to skip the test.
+ (eieio--add-new-slot): Register slot in `eieio--known-class-slot-names`
+ when applicable.
+ (eieio-oref-default, eieio-oset-default): Add warning for unknown slots
+ and slots not known to be allocated to the class.
+ (eieio-default-eval-maybe): Delete function. Use just `eval` instead.
+ (eieio-declare-slots): Allow slots to specify their allocation class.
+
+ * lisp/cedet/srecode/insert.el (point): Declare the slot instead of
+ moving the class definition before the slot's first use.
+ (srecode-template-inserter-point, srecode-insert-fcn):
+ Use nil instead of unbound for the `point` slot.
+
+ * lisp/cedet/srecode/compile.el (srecode-template-inserter):
+ Declare the `key` slot that all children should have.
+
+ * lisp/emacs-lisp/eieio-speedbar.el (eieio-speedbar)
+ (eieio-speedbar-directory-button, eieio-speedbar-file-button):
+ * lisp/emacs-lisp/eieio-custom.el (eieio-widget-test-class):
+ * lisp/emacs-lisp/chart.el (chart-bar):
+ * lisp/cedet/semantic/ede-grammar.el (semantic-ede-proj-target-grammar):
+ * lisp/cedet/semantic/db.el (semanticdb-project-database):
+ * lisp/cedet/semantic/db-javascript.el (semanticdb-table-javascript)
+ (semanticdb-project-database-javascript):
+ * lisp/cedet/semantic/db-el.el (semanticdb-table-emacs-lisp)
+ (semanticdb-project-database-emacs-lisp):
+ * lisp/cedet/semantic/db-ebrowse.el (semanticdb-table-ebrowse)
+ (semanticdb-project-database-ebrowse):
+ * lisp/cedet/ede/proj.el (ede-proj-project):
+ * lisp/cedet/ede/proj-obj.el (ede-proj-target-makefile-objectcode):
+ * lisp/cedet/ede/generic.el (ede-generic-project):
+ * lisp/cedet/ede/config.el (ede-project-with-config):
+ * lisp/cedet/ede/base.el (ede-target, ede-project):
+ * lisp/auth-source.el (auth-source-backend): Init forms are evaluated,
+ so quote them accordingly.
+
+2021-06-12 Robert Pluim <rpluim@gmail.com>
+
+ Make `window-system-for-display' work for ipv6, too
+
+ * lisp/term/x-win.el (display-format-alist): Also work for ipv6
+ (bug#42045).
+
+2021-06-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify some browse-url doc strings
+
+ * lisp/net/browse-url.el (browse-url-of-file)
+ (browse-url-of-buffer, browse-url-of-region, browse-url)
+ (browse-url-at-point, browse-url-at-mouse): Clarify doc strings
+ (bug#42432).
+
+2021-06-12 Tassilo Horn <tsdh@gnu.org>
+
+ Use file-in-directory-p instead of obsolete dired-in-this-tree-p
+
+ * lisp/dired-aux.el (dired-rename-subdir,dired-rename-subdir-1)
+ (dired-insert-subdir,dired-insert-subdir-validate)
+ (dired-kill-tree,dired-tree-down): Use file-in-directory-p instead of
+ obsolete dired-in-this-tree-p.
+
+2021-06-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix double (recursive) load of fortran.el
+
+ * lisp/progmodes/fortran.el (fortran-menu): Move menu creation to
+ the end to avoid a recursive load (bug#43116).
+
+2021-06-12 Alex Bochannek <alex@bochannek.com>
+
+ Mention nov-is-evil/nnvirtual combination in the Gnus manual
+
+ * doc/misc/gnus.texi (To From Newsgroups): Mention using separate
+ select methods for different values (bug#48801).
+
+2021-06-12 Matt Beshara <m@mfa.pw>
+
+ Add ability to bring only the selected frame to the front (bug#48865)
+
+ Causes ‘ns-hide-emacs’ to layer the selected frame in front of every other
+ application’s windows, and give that frame keyboard focus, when called with
+ 'activate-front.
+
+ * src/nsfns.m (Fns_hide_emacs): Allow activating only selected frame.
+
+2021-06-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/benchmark.el (benchmark-elapse): Tweak
+
+2021-06-11 Martin Rudalics <rudalics@gmx.at>
+
+ Rename/rewrite recently added option and function in window.el
+
+ * lisp/window.el (window-at-x-y): Rename from `window-at-pos'.
+ Fix doc-string.
+ (delete-window-choose-selected): Rename from
+ `delete-window-set-selected'. Fix doc-string.
+ (delete-window): Adjust to above renaming.
+ * doc/emacs/windows.texi (Change Window): Mention new option
+ `delete-window-choose-selected'.
+ * etc/NEWS:
+ * doc/lispref/windows.texi (Deleting Windows): Follow up on
+ above renamings.
+
+2021-06-11 Dmitry Gutov <dgutov@yandex.ru>
+
+ Simplify vc-git-log-switches's usage; change default value to nil
+
+ * lisp/vc/vc-git.el (vc-git-log-switches):
+ Do not mention or allow the value 't' anymore
+ (https://lists.gnu.org/archive/html/emacs-devel/2021-06/msg00452.html).
+ (vc-git-print-log): Use 'vc-git-log-switches' directly.
+
+2021-06-10 Philip Kaludercic <philipk@posteo.net>
+
+ Preserve incoming order of messages with same timestamp
+
+ * lisp/net/rcirc.el (rcirc-print): Emulate time-less-or-equal-p
+
+2021-06-10 Philip Kaludercic <philipk@posteo.net>
+
+ Allow hiding certain message types after reconnecting
+
+ * lisp/net/rcirc.el (rcirc-omit-after-reconnect): Add new user option
+ (rcirc-reconncting): Add new variable
+ (rcirc-print): Check if message should be omitted
+ (reconnect): Mark buffers as freshly reconnected
+
+2021-06-10 Philip Kaludercic <philipk@posteo.net>
+
+ Use defvar-local instead of setq-local where applicable
+
+2021-06-10 Philip Kaludercic <philipk@posteo.net>
+
+ Allow for optional arguments using rcirc-define-command
+
+ * lisp/net/rcirc.el (rcirc-define-command): Handle &optional arguments
+
+2021-06-10 Philip Kaludercic <philipk@posteo.net>
+
+ Fix prompt doubling when reconnecting
+
+ * lisp/net/rcirc.el (rcirc-connect): Check if rcirc-mode is already active
+ (rcirc-get-buffer-create): Check if rcirc-mode is already active
+
+2021-06-10 Philip Kaludercic <philipk@posteo.net>
+
+ Allow filtering how nicks are presented
+
+ * lisp/net/rcirc.el (rcirc-nick-filter): Add new option
+ (rcirc-completion-at-point): Use rcirc-nick-filter
+ (rcirc-format-response-string): Use rcirc-nick-filter
+ (rcirc-sort-nicknames-join): Use rcirc-nick-filter
+
+2021-06-10 Philip Kaludercic <philipk@posteo.net>
+
+ Implement invite-notify capability
+
+ * lisp/net/rcirc.el (rcirc-implemented-capabilities): Add invite-notify
+ (rcirc-handler-INVITE): Handle invite notifications
+
+2021-06-10 Philip Kaludercic <philipk@posteo.net>
+
+ Add TAGMSG handler
+
+ * lisp/net/rcirc.el (rcirc-handler-TAGMSG): Add new message handler
+
+2021-06-10 Philip Kaludercic <philipk@posteo.net>
+
+ Implement message-ids extension
+
+ * lisp/net/rcirc.el (rcirc-implemented-capabilities): Add to list of
+ implemented extensions
+ (rcirc-print): Insert property denoting message ID
+
+2021-06-10 Philip Kaludercic <philipk@posteo.net>
+
+ Implement batch extension
+
+ * lisp/net/rcirc.el (rcirc-implemented-capabilities): Add batch extension
+ (rcirc-supported-batch-types): Add new variable
+ (rcirc-batch-attributes): Add new variable
+ (rcirc-batched-messages): Add new variable
+ (rcirc-process-server-response-1): Handle messages with batch tag
+ (rcirc-handler-BATCH): Add batch dispatcher
+
+2021-06-10 Philip Kaludercic <philipk@posteo.net>
+
+ Implement server-time extension
+
+ * lisp/net/rcirc.el (rcirc-implemented-capabilities): Add new capability
+ (rcirc-print): Insert messages in the right position
+ (rcirc-log): Use right time value
+ (rcirc-markup-timestamp): Use right time value
+
+2021-06-10 Philip Kaludercic <philipk@posteo.net>
+
+ Create framework for IRCv3 support
+
+ * lisp/net/rcirc.el (rcirc-implemented-capabilities): Add new variable
+ (rcirc-requested-capabilities): Add new variable
+ (rcirc-acked-capabilities): Add new variable
+ (rcirc-connect): Request capabilities from rcirc-implemented-capabilities
+ (rcirc-process-regexp): Extend rcirc-process-regexp with tag support
+ (rcirc-tag-regexp): Add new tokenizer for tags
+ (rcirc-message-tags): Add new variable
+ (rcirc-get-tag): Add new function
+ (rcirc-process-server-response-1): Parse message-tags
+ (rcirc-handler-CAP): Add new handler for capability requests
+
+2021-06-10 Philip Kaludercic <philipk@posteo.net>
+
+ Replace defun-rcirc-command with rcirc-define-command
+
+ * lisp/net/rcirc.el (defun-rcirc-command): Remove old macro
+ (rcirc-define-command): Create new macro
+
+2021-06-10 Eli Zaretskii <eliz@gnu.org>
+
+ Support mercury in 'ctags' as well
+
+ The previous lack of support was due to incorrect calls to 'make_tag'
+ in 'mercury_pr', which caused 'pfnote' to refrain from adding Mercury
+ tags to the list of recorded tags.
+
+ * lib-src/etags.c (mercury_pr): Pass the correct NAME and NAMELEN
+ arguments to 'make_tag'.
+
+ * test/manual/etags/CTAGS.good: Adjust to the above change.
+
+2021-06-10 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'M-y'
+
+ * doc/emacs/killing.texi (Yanking): Mention that TTY frames can
+ also support yanking from the clipboard.
+ (Earlier Kills): Finalize the documentation of the new behavior
+ of the lone 'M-y'. (Bug#48478)
+
+2021-06-10 Martin Rudalics <rudalics@gmx.at>
+
+ Provide new option `delete-window-set-selected' (Bug#47300)
+
+ When `delete-window' deletes its frame's selected window, this new
+ option allows to choose another window as replacement.
+
+ * lisp/window.el (get-lru-window, get-mru-window)
+ (get-largest-window): New optional argument NO-OTHER.
+ (window-at-pos): New function.
+ (delete-window-set-selected): New option.
+ (delete-window): Handle `delete-window-set-selected'.
+ * src/window.c (Fdelete_window_internal): Set the selected
+ window of WINDOW's frame to the first window on that frame and
+ let `delete-window' choose a more suitable window instead.
+ * doc/lispref/windows.texi (Deleting Windows): Describe new
+ option `delete-window-set-selected'.
+ (Cyclic Window Ordering): Describe new NO-OTHER argument for
+ `get-lru-window', `get-mru-window' and `get-largest-window'.
+ * etc/NEWS: Mention `delete-window-set-selected' and the NO-OTHER
+ argument.
+
+2021-06-09 Alan Third <alan@idiocy.org>
+
+ Remove pause on fullscreening in NS (bug#48406)
+
+ * src/nsterm.m (ns_make_frame_visible):
+ (ns_set_parent_frame):
+ ([EmacsView windowWillEnterFullScreen:]):
+ ([EmacsView windowDidEnterFullScreen:]):
+ ([EmacsView windowWillExitFullScreen:]):
+ ([EmacsView initFrameFromEmacs:]): Remove references to
+ in_fullscreen_transition.
+ ([EmacsView toggleFullScreen:]): Remove calls to removed methods.
+ ([EmacsView inFullScreenTransition]):
+ ([EmacsView waitFullScreenTransition]): Remove Methods.
+ * src/nsterm.h (EmacsView): Remove definitions of removed methods, and
+ the in_fullscreen_transition variable.
+
+2021-06-09 Glenn Morris <rgm@gnu.org>
+
+ * lib/Makefile.in (Makefile): Fix typo.
+
+2021-06-09 Philip Kaludercic <philipk@posteo.net>
+
+ Remove custom rcirc-completion implementation
+
+ * lisp/net/rcirc.el (rcirc-completion-at-point): Improve completion suggestions
+ (rcirc-completions): Remove variable
+ (rcirc-completion-start): Remove variable
+ (rcirc-complete): Remove function
+ (rcirc-mode-map): Bind TAB to completion-at-point
+ (rcirc-mode): Use cycling for completion
+
+2021-06-09 Philip Kaludercic <philipk@posteo.net>
+
+ Recognize quoted commands in rcirc-process-input-line
+
+ * lisp/net/rcirc.el (rcirc-process-input-line): Check for quoted commands
+ (rcirc-process-command): Don't check for quoted commands
+
+2021-06-09 Philip Kaludercic <philipk@posteo.net>
+
+ Integrate formatting into rcirc-send-string
+
+ * lisp/net/rcirc.el (rcirc-connect): Use new syntax
+ (rcirc-send-string): Allow for more arguments
+ (rcirc-send-privmsg): Use new syntax
+ (rcirc-send-ctcp): Use new syntax
+ (rcirc-send-message): Use new syntax
+ (rcirc-clean-up-buffer): Use new syntax
+ (join): Use new syntax
+ (invite): Use new syntax
+ (part): Use new syntax
+ (quit): Use new syntax
+ (nick): Use new syntax
+ (names): Use new syntax
+ (topic): Use new syntax
+ (whois): Use new syntax
+ (mode): Use new syntax
+ (list): Use new syntax
+ (oper): Use new syntax
+ (kick): Use new syntax
+ (rcirc-handler-PING): Use new syntax
+ (rcirc-handler-ctcp-VERSION): Use new syntax
+ (rcirc-handler-ctcp-ACTION): Use new syntax
+ (rcirc-handler-ctcp-TIME): Use new syntax
+
+2021-06-09 Philip Kaludercic <philipk@posteo.net>
+
+ Fix checkdoc complaints and related issues
+
+2021-06-09 Philip Kaludercic <philipk@posteo.net>
+
+ Use auth-source for user-passwords
+
+ * (rcirc): Use auth-source is no password was specified
+
+2021-06-09 Philip Kaludercic <philipk@posteo.net>
+
+ Default to libera instead of freenode
+
+ * lisp/net/rcirc.el (rcirc-server-alist): Update default value
+
+2021-06-09 Alan Third <alan@idiocy.org>
+
+ Fix image filename encoding issues (bug#48902)
+
+ * src/image.c (image_find_image_fd): Don't return an encoded filename
+ string.
+ * src/nsfns.m: ([NSString stringWithLispString:]): Clarify usage
+ comment.
+ * src/nsimage.m ([EmacsImage allocInitFromFile:]): No need to encode
+ the filename when converting to NSString.
+
+2021-06-09 Michael Albinus <michael.albinus@gmx.de>
+
+ * etc/NEWS: New user option 'shell-has-auto-cd'.
+
+2021-06-09 Jason Kim <jason.kim@revtera.com> (tiny change)
+
+ Handle auto-cd in shell-mode
+
+ * lisp/shell.el (shell-has-auto-cd): New defcustom.
+ (shell-directory-tracker): Handle implicit "cd".
+
+2021-06-09 Utkarsh Singh <utkarsh190601@gmail.com> (tiny change)
+
+ New user option for Git log switches
+
+ * lisp/vc/vc-git.el (vc-git-diff-switches): New defcustom.
+ (vc-git-print-log): Use it.
+
+ * etc/NEWS: Announce the new option.
+
+2021-06-08 Juri Linkov <juri@linkov.net>
+
+ * lisp/simple.el (yank-from-kill-ring): Add edited string to the kill-ring.
+
+ (Bug#48478)
+
+2021-06-08 Juri Linkov <juri@linkov.net>
+
+ Sync overlay code in minibuffer-message and set-minibuffer-message (bug#48669)
+
+ * lisp/minibuffer.el (minibuffer-message): Copy more overlay positioning code
+ from set-minibuffer-message.
+ (minibuffer--message-overlay-pos): Mention both minibuffer-message and
+ set-minibuffer-message in the docstring.
+ (set-minibuffer-message): Use 'cursor t' instead of 1.
+
+2021-06-08 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 37f4457994 (origin/emacs-27) ; Fix typo in dynamic module functions d...
+ f7d4bbceee ; * src/composite.h: Improve comments for LGSTRING and LGL...
+
+2021-06-08 Alex Bochannek <alex@bochannek.com>
+
+ Change the Gnus default to use `#' to toggle the process mark
+
+ * doc/misc/gnus.texi (Marking Groups, Topic Commands):
+ (Setting Process Marks, Pick and Read): Document the new default.
+ * lisp/gnus/gnus-group.el (gnus-group-make-menu-bar): Update menu.
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-make-menu-bar): Update menu.
+
+ * lisp/gnus/gnus-topic.el (gnus-topic-make-menu-bar): Update menu.
+
+ * lisp/gnus/gnus.el (gnus-process-mark-toggle): Change default.
+
+2021-06-08 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ MH-E: do not look for MH variants in relative directories
+
+ * lisp/mh-e/mh-e.el (mh-variants): Do not examine relative directories
+ in exec-path (e.g., "."); these won't have MH installed. Also,
+ file-chase-links is not robust with relative names: you cannot pass it
+ a relative name that is a symlink.
+
+2021-06-08 Stefan Kangas <stefan@marxist.se>
+
+ Fix an example in ERC docs
+
+ * doc/misc/erc.texi (Connecting):
+ * lisp/erc/erc.el (erc, erc-tls): Fix example to use J. Random Hacker
+ instead of Harry S. Truman.
+
+2021-06-08 Stefan Kangas <stefan@marxist.se>
+
+ * doc/man/emacs.1.in: Minor fixes.
+
+2021-06-08 Alan Third <alan@idiocy.org>
+
+ Revert "src/nsterm.m: fix window tabbing on macOS"
+
+ This reverts commit 2207f9adccc0411b7ad73a3703f16250d7f8e139.
+
+2021-06-07 Michael Albinus <michael.albinus@gmx.de>
+
+ Improve support of remote files in browse-url.el
+
+ * etc/NEWS: Mention support of remote file browsing.
+
+ * lisp/net/browse-url.el (browse-url-of-buffer): Revert last change.
+ (browse-url-of-file): Use temporary file in case of remote file.
+ (Bug#48397)
+
+2021-06-07 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix rgrep abbreviation
+
+ * lisp/progmodes/grep.el (grep-mode-font-lock-keywords):
+ Update for the last change in grep-find-template (bug#48471).
+
+2021-06-07 Eli Zaretskii <eliz@gnu.org>
+
+ * src/xdisp.c (Fwindow_text_pixel_size): Plug memory leak. (Bug#48884)
+
+2021-06-07 Michael Albinus <michael.albinus@gmx.de>
+
+ Support remote file names in `browse-url-of-buffer'
+
+ * lisp/net/browse-url.el (browse-url-of-buffer): Use temporary
+ file in case of remote `file-name'. (Bug#48397)
+
+2021-06-07 Dmitry Gutov <dgutov@yandex.ru>
+
+ Support old BSD find and "root dir symlink" better
+
+ * lisp/progmodes/grep.el (grep-compute-defaults):
+ Add '-H' to grep-find-template (bug#48471).
+
+ * lisp/cedet/semantic/symref/grep.el (semantic-symref-perform-search):
+ Pass the root directory name without the trailing slash.
+
+ * lisp/progmodes/xref.el (xref-matches-in-directory): Ditto.
+
+ * test/lisp/progmodes/xref-tests.el (xref--xref-file-name-display-is-abs)
+ (xref--xref-file-name-display-is-relative-to-project-root):
+ Make tests more strict again.
+
+2021-06-06 Dmitry Gutov <dgutov@yandex.ru>
+
+ completion-pcm--hilit-commonality: Reuse the match-data cons cells
+
+ * lisp/minibuffer.el (completion-pcm--hilit-commonality): Reuse
+ the match-data cons cells for better performance (bug#48841).
+
+2021-06-06 Eli Zaretskii <eliz@gnu.org>
+
+ Fix a problem with restarting 'tags-search'
+
+ * lisp/progmodes/etags.el (tags-search, tags-query-replace): Link
+ to 'fileloop-continue' instead of 'tags-loop-continue', for
+ continuing TAGS-based search/replace commands.
+
+ * lisp/fileloop.el (fileloop-continue): Reset
+ 'switch-to-buffer-preserve-window-point' to nil when switching to
+ another buffer, so as to make sure a new search always restarts
+ from point-min in each buffer it searches. (Bug#48628)
+
+2021-06-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify boolean widget prompt
+
+ * lisp/wid-edit.el (widget-boolean-prompt-value): Clarify prompt
+ (bug#43593).
+
+2021-06-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify file reversion prompt
+
+ * lisp/files.el (revert-buffer--default): Clarify prompt when the
+ buffer is modified (bug#43884).
+
+2021-06-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `so-long' restore `view-mode'
+
+ * lisp/so-long.el (so-long): Make the `v' command in Dired work
+ more reliably (bug#45084).
+
+2021-06-06 Sebastian Urban <mrsebastianurban@gmail.com> (tiny change)
+
+ Minor copyedits in the Emacs user manual
+
+ * doc/emacs/fixit.texi (Spelling): Move TeX hyphenation directives
+ from here...
+ * doc/emacs/docstyle.texi: ...to here.
+ * doc/emacs/display.texi (Displaying Boundaries, Text Display):
+ Minor stylistic changes. (Bug#48654)
+
+2021-06-06 Eli Zaretskii <eliz@gnu.org>
+
+ Minor fixes for last change
+
+ * test/manual/etags/ETAGS.good_1:
+ * test/manual/etags/ETAGS.good_2:
+ * test/manual/etags/ETAGS.good_3:
+ * test/manual/etags/ETAGS.good_4:
+ * test/manual/etags/ETAGS.good_5:
+ * test/manual/etags/ETAGS.good_6: Adapt to added Mercury support.
+
+ * lib-src/etags.c (find_entries, test_objc_is_mercury):
+ * etc/NEWS: Fix punctuation and typos in last change.
+
+2021-06-06 Fabrice Nicol <fabrnicol@gmail.com>
+
+ Add support for Mercury (https://mercurylang.org) in 'etags'
+
+ Tag declarations starting lines with ':-'.
+ By default, all declarations are tagged. Optionally, first
+ predicate or functions in clauses can be tagged as in Prolog
+ support using '--declarations'. (Bug#47408).
+ * lib-src/etags.c (test_objc_is_mercury, Mercury_functions)
+ (mercury_skip_comment, mercury_decl, mercury_pr):
+ Implement Mercury support. As Mercury and Objective-C have
+ the same file extension .m, a heuristic test tries to detect
+ the language.
+
+ * doc/man/etags.1: Document the change. Add Mercury-specific
+ behavior for '--declarations'. This option tags first
+ predicates or functions in clauses in addition to declarations.
+
+2021-06-06 Paul W. Rankin <pwr@bydasein.com>
+
+ src/nsterm.m: fix window tabbing on macOS
+
+ * src/nsterm.m: remove NSWindowTabbingModeDisallowed to respect
+ system-wide preferences
+ * etc/NEWS: add mention of native tab support in macOS and where
+ to specify system-wide setting
+
+2021-06-06 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp.el (tramp-error): Make it a defun.
+
+2021-06-05 João Távora <joaotavora@gmail.com>
+
+ Consider environment vars in Fido's directory-aware RET binding
+
+ (Bug#48782)
+
+ * lisp/icomplete.el (icomplete-fido-ret): Consider environment
+ variables in dir expansion.
+
+2021-06-05 Alex Bochannek <alex@bochannek.com>
+
+ Fix Gnus summary exclusion when everything matches
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-limit-to-recipient):
+ * lisp/gnus/gnus-sum.el (gnus-summary-limit-to-subject):
+ (gnus-summary-limit-to-address, gnus-summary-limit-to-extra):
+ Don't claim that there aren't any matches when everything matches
+ an exclusion (bug#48834).
+
+2021-06-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/keyboard.c (read_decoded_event_from_main_queue): Fix paren typo
+
+ * lisp/mpc.el (mpc-intersection): Fix commit 1760029b0927242
+
+2021-06-05 Eli Zaretskii <eliz@gnu.org>
+
+ Document the last change
+
+ * doc/lispref/os.texi (Input Modes): Document the changes in the
+ values of the META flag.
+
+ * etc/NEWS: Call out the change in input-meta-mode.
+
+2021-06-05 Max Mikhanosha <max.mikhanosha@protonmail.com>
+
+ Support terminal emulators that encode the Meta modifier as 8th bit
+
+ See discussion starting at
+
+ https://lists.gnu.org/archive/html/emacs-devel/2021-06/msg00034.html
+
+ for the details.
+ * src/keyboard.c (read_decoded_event_from_main_queue): For
+ raw-text encoed input, if Meta bit is encoded, apply the Meta
+ modifier to single-byte characters that have the 0x80 bit set.
+ For input encoded otherwise, if the Meta bit is encoded, remove
+ the 0x80 bit after decoding the characters.
+ (tty_read_avail_input): Reset the 0x80 bit only if Meta bit is not
+ encoded.
+ (Fset_input_meta_mode): Support 'encoded' as the value of META.
+ (Fset_input_mode): Document 'encoded' for META.
+ (Fcurrent_input_mode): Support and document 'encoded' as the value
+ of META.
+ (syms_of_keyboard): DEFSYM 'encoded'.
+
+2021-06-05 Eli Zaretskii <eliz@gnu.org>
+
+ Fix slow operation of 'string-width'
+
+ * src/composite.c (find_automatic_composition): Accept one
+ additional argument BACKLIM; don't look back in buffer or string
+ farther than that. Add an assertion for BACKLIM.
+ (composition_adjust_point, Ffind_composition_internal): Callers
+ adjusted.
+ * src/composite.h (find_automatic_composition): Adjust prototype.
+ * src/character.c (lisp_string_width): Call
+ 'find_automatic_composition' with the value of BACKLIM equal to POS,
+ to avoid costly and unnecessary search back in the string, since
+ those previous characters were already checked for automatic
+ compositions. (Bug#48734) (Bug#48839)
+
+2021-06-05 Eli Zaretskii <eliz@gnu.org>
+
+ Some additions to the TeX input method
+
+ * lisp/leim/quail/latin-ltx.el (latin-ltx--define-rules): Add some
+ rules from Unicode Technical Note 28 "UnicodeMath" v3.1.
+
+2021-06-05 Dmitry Gutov <dgutov@yandex.ru>
+
+ Make icomplete less blinky and more responsive
+
+ * lisp/icomplete.el (icomplete-pre-command-hook, icomplete-tidy):
+ Remove, update the callers
+ (https://lists.gnu.org/archive/html/emacs-devel/2021-06/msg00111.html).
+ (icomplete-compute-delay): Change the default to 150ms.
+ (icomplete-max-delay-chars): Change the default to 2.
+
+2021-06-04 Tassilo Horn <tsdh@gnu.org>
+
+ Ask if dir and subdir dired buffers be killed when deleting dir
+
+ Previously, when you've had dired buffers
+
+ ~/foo/
+ ~/foo/bar/
+ ~/foo/bar/baz/
+
+ and then deleted ~/foo/, dired (with dired-clean-up-buffers-too set to
+ non-nil) would only ask to delete the dired buffer of ~/foo/. Now it
+ will offer to delete all three buffers.
+
+ * lisp/dired.el (dired-buffers-for-dir): Add optional argument SUBDIRS
+ which makes the function return also dired buffers showing a subdir of
+ DIR.
+ (dired-in-this-tree-p): Make obsolete in favor of file-in-directory-p
+ which actually does what the name suggest whereas dired-in-this-tree-p
+ is just string-matching on filenames which will fail with symlinks
+ filenames including ./ or ../.
+
+2021-06-04 Eli Zaretskii <eliz@gnu.org>
+
+ Fix documentation of a recent change.
+
+ * etc/NEWS:
+ * doc/emacs/misc.texi (Invoking emacsclient): Fix a recent change.
+ (Bug#11358)
+
+2021-06-04 Stephen Berman <stephen.berman@gmx.net>
+
+ Fix placement of point in Dired deletion operations
+
+ * lisp/dired.el (dired-do-flagged-delete, dired-do-delete): Use
+ point-marker instead of point to record each file name position.
+ Clean up the markers before returning.
+ (dired-internal-do-deletions): Move to the file name marker, and
+ then move point to the file name to visually emphasize which file
+ is being operated on (bug#48805).
+
+2021-06-04 Harald Hanche-Olsen <harald.hanche-olsen@ntnu.no> (tiny change)
+
+ Add a new `server-edit-abort' command
+
+ * doc/emacs/misc.texi (Invoking emacsclient): Document it (bug#11358).
+
+ * lisp/server.el (server-edit): Mention it in the doc string.
+ (server-edit-abort): New command.
+
+2021-06-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Make the `i' command in Info-mode remove duplicate matches"
+
+ This reverts commit 089e0c4c55dcf72f9cf2f6f04b8a52fc7355499c.
+
+ There were no duplicate entries -- there were two entries
+ for different things that referred to the same line.
+
+2021-06-04 Eli Zaretskii <eliz@gnu.org>
+
+ Fix documentation of recent 'windmove' changes
+
+ * lisp/windmove.el (windmove-default-keybindings)
+ (windmove-display-default-keybindings)
+ (windmove-delete-default-keybindings)
+ (windmove-swap-states-default-keybindings): Improve doc strings.
+ (Bug#41438)
+
+ * etc/NEWS: Fix a typo in the 'windmove' entry.
+
+2021-06-03 Juri Linkov <juri@linkov.net>
+
+ * lisp/simple.el (read-from-kill-ring): Fix the case of 'M-y M-p' (bug#48478)
+
+ Don't use offsets for read-from-kill-ring-history when kill-ring-yank-pointer
+ points to the last element of kill-ring.
+
+2021-06-03 Juri Linkov <juri@linkov.net>
+
+ * lisp/help-fns.el (help--symbol-class): New function.
+
+ Refactored from help--symbol-completion-table-affixation.
+ https://lists.gnu.org/archive/html/emacs-devel/2021-06/msg00066.html
+
+2021-06-03 Juri Linkov <juri@linkov.net>
+
+ * etc/NEWS: Add windmove keybindings (bug#41438)
+
+2021-06-03 Philip Kaludercic <philipk@posteo.net>
+
+ Add user options for default windmove commands (bug#41438)
+
+ * lisp/windmove.el (windmove--default-keybindings-type): Add type.
+ (windmove-default-keybindings): Add user option.
+ (windmove-display-default-keybindings): Add user option.
+ (windmove-delete-default-keybindings): Add user option.
+ (windmove-swap-states-default-keybindings): Add user option.
+
+2021-06-03 Philip Kaludercic <philipk@posteo.net>
+
+ Improve windmove-*-default-keybindings functions (bug#41438)
+
+ * lisp/windmove.el (windmove-mode-map): Add special map for windmove commands.
+ (windmove-mode): Add minor mode for activating windmove-mode-map.
+ (windmove-install-defaults): Add general function for manipulating
+ windmove-mode-map.
+ (windmove-default-keybindings): Use windmove-install-defaults.
+ (windmove-display-default-keybindings): Use windmove-install-defaults.
+ (windmove-delete-default-keybindings): Use windmove-install-defaults.
+ (windmove-swap-states-default-keybindings): Use windmove-install-defaults.
+
+2021-06-03 Mattias Engdegård <mattiase@acm.org>
+
+ Constant-propagate (function SYMBOL)
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize--substitutable-p):
+ Consider #'SYMBOL a constant for compile-time propagation purposes.
+
+2021-06-03 Mattias Engdegård <mattiase@acm.org>
+
+ Optimise (cons X nil) to (list X)
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-cons): New function.
+
+2021-06-03 Eli Zaretskii <eliz@gnu.org>
+
+ Fix fill-column-indicator on TTY frames
+
+ * src/xdisp.c (extend_face_to_end_of_line): Fix calculation of
+ fill-column-indicator on TTY frames. Suggested by Jimmy Aguilar
+ Mena <spacibba@aol.com>.
+
+2021-06-03 Eli Zaretskii <eliz@gnu.org>
+
+ More accurate highlighting of mis-spellings in Flyspell
+
+ * lisp/textmodes/flyspell.el (flyspell-word): Highlight only the
+ misspelled word, not any extra characters after it. (Bug#5575)
+
+2021-06-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the `i' command in Info-mode remove duplicate matches
+
+ * lisp/info.el (Info-index): Weed out duplicate matched
+ (bug#3692).
+
+2021-06-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up previous hideif change to avoid a compilation warning
+
+ * lisp/progmodes/hideif.el
+ (hide-ifdef-expand-reinclusion-protection): Move to avoid a
+ compilation warning.
+
+2021-06-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ fringe-mode doc clarifications
+
+ * lisp/fringe.el (fringe-mode):
+ (fringe-mode): Note that this variable and command have nothing to
+ do with modes (bug#6931).
+
+2021-06-03 Luke Lee <luke.yx.lee@gmail.com>
+
+ * lisp/progmodes/hideif.el: Fix initial version for new variables
+
+ (hide-ifdef-verbose, hide-ifdef-evalulate-enter-hook)
+ (hide-ifdef-evalulate-leave-hook): Fix initial version to 28.1.
+ (hide-ifdef-expand-reinclusion-protection): Obsolete since 28.1,
+ rename to `hide-ifdef-expand-reinclusion-guard' instead.
+
+2021-06-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with empty command histories in eshell and `erase'
+
+ * lisp/eshell/em-hist.el (eshell-add-input-to-history): Protect
+ against an empty ring (bug#48770).
+
+2021-06-03 Eli Zaretskii <eliz@gnu.org>
+
+ * configure.ac: Clarify "smoke test" error message. (Bug#48804)
+
+2021-06-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Cross-reference the message/error control variables
+
+ * src/keyboard.c (syms_of_keyboard): Mention set-message-function
+ in the command-error-function doc string...
+
+ * src/xdisp.c (syms_of_xdisp): ... and vice versa (bug#13752).
+
+2021-06-03 Eli Zaretskii <eliz@gnu.org>
+
+ * configure.ac: Improve error messages about libgccjit.
+
+2021-06-02 Tassilo Horn <tsdh@gnu.org>
+
+ Allow opening buttonized URL with secondary browser in rcirc
+
+ * lisp/net/browse-url.el (browse-url-button-open-url): Add autoload
+ cookie.
+ * lisp/net/rcirc.el (rcirc-markup-urls): Use
+ `browse-url-button-open-url' instead of just `browse-url' in order to
+ be able to use the secondary browser by giving a prefix arg.
+
+2021-06-02 Eli Zaretskii <eliz@gnu.org>
+
+ Fix a typo in 'produce_glyphless_glyph'
+
+ * src/xdisp.c (produce_glyphless_glyph): Initialize lower_xoff.
+ Remove workaround for lack of its initialization. (Bug#8215)
+
+2021-06-02 Luke Lee <luke.yx.lee@gmail.com>
+
+ * lisp/progmodes/hideif.el: update for new C++ standards and extensions
+
+ Matching gcc/clang behavior on stringification including keeping the same
+ number of white spaces. C++11, C++14, C++17 and GCC literals extension are
+ supported. Preprocessing time floating point operation supported but limited
+ to Emacs internal representation which is C data type "double". Also support
+ some frequently used keywords like __LINE__, __TIME__, __DATE__ and so on.
+
+ (hif-clear-all-ifdef-defined, hif-show-all, hif-after-revert-function)
+ (hide-ifdef-define, hide-ifdefs, show-ifdefs): interactive behavior changes,
+ mainly to allow operation within the marked region.
+ (hif-eval, hif-__LINE__, hif-__FILE__, hif-__COUNTER__, hif-__cplusplus)
+ (hif-__DATE__, hif-__TIME__, hif-__STDC__, hif-__STDC_VERSION__)
+ (hif-__STDC_HOST__, hif-__FILE__, hif-full-match, hif-is-number, hif-is-float)
+ (hif-delete-char-in-string, hif-string-to-decfloat, hif-string-to-hexfloat)
+ (hif-strtok, hif-is-white, hif-backward-comment, hif-split-signed-token)
+ (hif-keep-single, hif-display-macro): new functions.
+ (hide-ifdef-verbose, hide-ifdef-evalulate-enter-hook)
+ (hide-ifdef-evalulate-leave-hook, hide-ifdef-evaluator, hif-predefine-alist)
+ (hif-numtype-suffix-regexp, hif-bin-regexp, hif-hex-regexp, hif-oct-regexp)
+ (hif-dec-regexp, hif-decfloat-regexp, hif-hexfloat-regexp)
+ (hif-unicode-prefix-regexp, hif-verbose-define-count): new constants or
+ variables.
+ (hif-macroref-regexp, hif-token-alist, hif-token-regexp)
+ (hif-string-literal-regexp): modified constants for faster regexp processing.
+ (hide-ifdef-expand-reinclusion-guard): renamed from
+ `hide-ifdef-expand-reinclusion-protection' to match commonly used term.
+ (hif-lookup, hif-defined, hif-string-to-number, hif-tokenize, hif-nextoken)
+ (hif-if-valid-identifier-p, hif-define-operator, hif-expand-token-list)
+ (hif-parse-exp, hif-math, hif-factor, hif-get-argument-list, hif-stringify)
+ (hif-token-concat, hif-mathify, hif-comma, hif-token-stringification)
+ (hif-token-concatenation, hif-macro-supply-arguments, hif-evaluate-macro)
+ (hif-find-define, hif-add-new-defines, hide-ifdef-guts, hif-undefine-symbol)
+ (hide-ifdef-set-define-alist, hide-ifdef-use-define-alist): modified functions
+ for new internal data representation, mainly for stringification and white
+ space preservation. Also better error handling to report source line number
+ and more informative error messages.
+
+2021-06-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix ibuffer auto-shrinking windows
+
+ * lisp/ibuffer.el (ibuffer-shrink-to-fit): Don't shrink all
+ windows, just the ibuffer one (bug#7218).
+
+2021-06-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move point in dired buffers when handling a list of files
+
+ * lisp/dired-aux.el (dired-create-files): Advance point to the
+ current file (bug#8015).
+
+2021-06-02 Alex Bochannek <alex@bochannek.com>
+
+ Add new user option to Gnus to allow `#' to toggle
+
+ * doc/misc/gnus.texi (Marking Groups, Setting Process Marks):
+ Mention the new variable.
+
+ * lisp/gnus/gnus-group.el (gnus-group-make-menu-bar): Update menu.
+ (gnus-group-mark-group): Support the variable.
+ (gnus-group-mark-update): New command.
+ (gnus-group-unmark-group, gnus-group-mark-region): Pass in new
+ parameter.
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-make-menu-bar): Update menu.
+ (gnus-summary-mark-as-processable): Use the variable.
+
+ * lisp/gnus/gnus-topic.el (gnus-topic-mark-topic): (bug#48683).
+
+ * lisp/gnus/gnus-topic.el (gnus-topic-mark-topic): Use the variable.
+
+ * lisp/gnus/gnus.el (gnus-process-mark-toggle): New user option.
+
+2021-06-01 Alan Third <alan@idiocy.org>
+
+ Improve performance of NS port's display on macOS
+
+ * src/nsterm.h: Update EmacsSurface definition.
+ * src/nsterm.m ([EmacsView focusOnDrawingBuffer]): Don't change the
+ CGContext's settings directly.
+ ([EmacsView unfocusDrawingBuffer]): Don't release the context here.
+ (CACHE_MAX_SIZE): Add maximum cache size.
+ ([EmacsView updateLayer]): Send a request for getContext, which will
+ copy the buffer and create the context if it doesn't already exist, to
+ the NS run loop.
+ ([EmacsSurface initWithSize:ColorSpace:Scale:]): Add the scale factor
+ and if there's already a CGContext available, reuse it.
+ ([EmacsSurface dealloc]): No longer need to release lastSurface
+ separately.
+ ([EmacsSurface getContext]): Don't create more surfaces than we have
+ spaces for in the cache.
+ ([EmacsSurface releaseContext]): If there's no context don't try to
+ release it and put currentSurface back on the cache instead of
+ lastSurface.
+ ([EmacsSurface copyContentsTo:]): Don't try to copy if the source and
+ destination are actually the same surface.
+
+2021-06-01 Andrea Corallo <akrl@sdf.org>
+
+ Add `native-compile-target-directory' (bug#48743)
+
+ * lisp/emacs-lisp/comp.el (native-compile-target-directory): New
+ variable.
+ (comp-spill-lap-function): Make use of.
+
+2021-06-01 Andrea Corallo <akrl@sdf.org>
+
+ Rename batch-byte-native-compile-for-bootstrap (bug#48743)
+
+ * lisp/Makefile.in : Rename `batch-byte-native-compile-for-bootstrap'
+ -> `batch-byte+native-compile.
+ * lisp/emacs-lisp/bytecomp.el (byte+native-compile)
+ (byte-compile-file): Rename
+ `batch-byte-native-compile-for-bootstrap' ->
+ `batch-byte+native-compile + `byte-native-for-bootstrap' ->
+ `byte+native-compile'.
+ * lisp/emacs-lisp/comp.el (comp-spill-lap-function, comp-final)
+ (batch-native-compile, batch-byte+native-compile): Likewise.
+ * lisp/emacs-lisp/bytecomp.el (byte+native-compile)
+ (byte-compile-file): Likewise.
+ * test/src/comp-tests.el (comp-tests-bootstrap): Rename
+ `byte-native-for-bootstrap' -> `byte+native-compile'.
+
+2021-06-01 Glenn Morris <rgm@gnu.org>
+
+ Remove unnecessary function declaration in isearch
+
+ * lisp/isearch.el (multi-isearch-switch-buffer):
+ Remove unnecessary declaration (after ldefs-boot update).
+
+2021-06-01 Andreas Schwab <schwab@linux-m68k.org>
+
+ Avoid hang in nnimap-keepalive
+
+ * lisp/gnus/nnimap.el (nnimap-keepalive): Make interruptible.
+
+2021-06-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/gnus-art.el: Don't sneak dynbound code via quoting
+
+ Make sure we don't accidentally quote lambdas by embedding them within
+ quoted data.
+
+ (gnus-visible-headers, gnus-emphasis-alist)
+ (gnus-mime-display-alternative, gnus-article-describe-bindings):
+ Unquote lambdas.
+
+2021-06-01 João Távora <joaotavora@gmail.com>
+
+ Add annotation capability to icomplete-vertical-mode
+
+ Co-authored-by Daniel Mendler <mail@daniel-mendler.de>
+
+ * lisp/icomplete.el (icomplete--affixate): New helper.
+ (icomplete--render-vertical): Use it. Rework.
+ (icomplete-completions): Pass md to icomplete--render-vertical.
+
+2021-06-01 João Távora <joaotavora@gmail.com>
+
+ Improve icomplete-vertical-mode and fido-vertical-mode
+
+ This mode is intended to be used with Icomplete ('M-x icomplete-mode')
+ or Fido ('M-x fido-mode'), to display the list of completions
+ candidates vertically instead of horizontally. When used with
+ Icomplete, completions are rotated and selection kept at the top.
+ When used with Fido, completions scroll like a typical dropdown
+ widget.
+
+ If the dropdown behaviour is desired for Icomplete (instead of
+ rotation), icomplete-scroll can be adjusted separately by the user.
+
+ * etc/NEWS (icomplete-vertical-mode): Reword.
+
+ * lisp/icomplete.el (simple): Require it.
+ (icomplete-selected-match): New face.
+ (icomplete-scroll): New user-visible var.
+ (icomplete-forward-completions): Rework.
+ (icomplete-backward-completions): Rework.
+ (icomplete--fido-mode-setup): Prefer icomplete-scroll according to
+ icomplete-vertical mode.
+ (icomplete-minibuffer-setup): Initialize icomplete--scrolled-completions.
+ (fido-vertical-mode): An alias for icomplete-vertical-mode.
+ (icomplete-exhibit): Init icomplete--scrolled-past. Adjust overlay.
+ (icomplete--render-vertical): New helper.
+ (icomplete--sorted-completions): If cache is stale, also
+ invalidate icomplete--scrolled-past.
+ (icomplete-completions): Rework. Mostly reformat.
+
+ * lisp/simple.el (max-mini-window-lines): New helper.
+ (display-message-or-buffer): Use it.
+
+2021-06-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow packages to change the hl-line overlay priority
+
+ * lisp/hl-line.el (hl-line-overlay-priority): New variable
+ (bug#11509).
+ (hl-line-make-overlay): Use it.
+
+2021-06-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with `format-alist' marking all the text in the buffer
+
+ * lisp/format.el (format-decode-run-method): Use it to avoid
+ marking the entire buffer (bug#11691).
+
+ * lisp/simple.el (shell-command-on-region): Allow replacing text
+ without activating the mark.
+
+2021-06-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document `with-selected-frame'
+
+ * doc/lispref/windows.texi (Selecting Windows): Document
+ `with-selected-frame' (bug#12075).
+
+2021-06-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Obsolete `global-whitespace-newline-mode'
+
+ * lisp/whitespace.el (global-whitespace-newline-mode): Make
+ obsolete since it doesn't work correctly, and seems superfluous
+ (bug#12496).
+
+2021-06-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new command `mailcap-view-file'
+
+ * doc/misc/emacs-mime.texi (mailcap): Document it (bug#12972).
+
+ * lisp/net/mailcap.el (mailcap-view-file): New command.
+
+2021-06-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix documentation of literal `face' syntax in font-lock section
+
+ * doc/lispref/modes.texi (Search-based Fontification): Fix
+ the literal `(0 (face ...))' syntax documentation (bug#13917).
+
+2021-06-01 Philip Kaludercic <philipk@posteo.net>
+
+ Improve random selection of keyservers
+
+ * lisp/epa-ks.el (epa-keyserver): Interpret a list as a pool.
+ (epa-ks--query-url): Add new auxiliary function.
+ (epa-ks--fetch-key): Use epa-ks--query-url.
+ (epa-search-keys): Use epa-ks--query-url.
+
+2021-05-31 Juri Linkov <juri@linkov.net>
+
+ * lisp/isearch.el (lazy-highlight-buffer-max-at-a-time): Change from 20 to 200
+
+ Suggested by Augusto Stoffel <arstoffel@gmail.com> in bug#48581
+
+2021-05-31 Andrea Corallo <akrl@sdf.org>
+
+ Make *Async-native-compile-log* buffer read-only (bug#48763)
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): Make
+ "*Async-native-compile-log*" read-only.
+
+2021-05-31 Alan Mackenzie <acm@muc.de>
+
+ Make frames record when their selected window was the mini-window
+
+ When a frame in this state is selected again by Fselect_frame (but not by
+ Fselect_window), the mini-window rather than the frame's currently selected
+ window, is chosen for selection, should there still be an active minibuffer in
+ it.
+
+ This fixes bug #48674.
+
+ * src/frame.h (struct frame): Add new boolean field select_mini_window_flag.
+
+ * src/frame.c (make_frame): Initialize select_mini_window_flag to false.
+ (do_switch_frame): Set the new flag appropriately for the old frame, and
+ process the new frame's setting of this flag, before setting it to false.
+
+ * src/window.c (select_window): Set f->select_mini_window_flag to false.
+ (Fset_frame_selected_window, Fdelete_other_windows_internal)
+ (Fdelete_window_internal): Add comments clarifying that there is no clearing
+ of f->select_mini_window_flag in these functions.
+
+2021-05-31 Glenn Morris <rgm@gnu.org>
+
+ * src/keyboard.c (make_lispy_event): Fix previous.
+
+2021-05-31 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 5dfa5e26dd (origin/emacs-27) Improve documentation of regexp ranges
+
+2021-05-31 Alan Mackenzie <acm@muc.de>
+
+ Correct mouse handling when window origin changes between down and up events
+
+ Do this by using frame relative positions rather than window relative ones,
+ which gave rise to spurious drag events when the origin of the window changed
+ between the mouse down and up events. This fixes bug #48409.
+
+ * src/keyboard.c (frame_relative_event_pos): New static variable.
+ (make_lispy_event): Record frame relative position of down event. When the up
+ event is in the same position, "move" this event into the window of the down
+ event when this window (typically a mini-window) is no longer under the mouse.
+ Call make_lispy_position a second time to generate this changed event.
+ (syms_of_keyboard): Declare Qwindow_edges. static_pro
+ frame_relative_event_pos.
+
+2021-05-31 Colin Woodbury <colin@fosskers.ca> (tiny change)
+
+ Remove spurious @example from the elisp manual
+
+ * doc/lispref/macros.texi (Defining Macros): Remove spurious extra
+ pair of @example/@end example.
+
+2021-05-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove messaging in ediff-make-diff2-buffer
+
+ * lisp/vc/ediff-diff.el (ediff-make-diff2-buffer): Remove message
+ that's often misleading when diffing buffers (that may be unsaved)
+ (bug#13091).
+
+2021-05-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Put ELP results in a special-mode buffer
+
+ * lisp/emacs-lisp/elp.el (elp-results): Make `q' work in ELP
+ results buffer (bug#14104).
+ (elp-results-mode): Define as an empty special mode derivation.
+
+2021-05-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `menu-bar-select-buffer' obsolete
+
+ * lisp/menu-bar.el (menu-bar-select-buffer): Make obsolete (bug#15651).
+
+ * lisp/msb.el (msb--select-buffer): Move function here and rename.
+ (msb--make-keymap-menu): Use it.
+
+2021-05-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Move menu-bar-select-buffer to msb.el"
+
+ This reverts commit 253e52478c355dc29052c0d21013b8d06b473880.
+
+ This is to be fixed in a different way in the next patch.
+
+2021-05-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use buffer-local-boundp in describe-variable
+
+ * lisp/help-fns.el (describe-variable): Use `buffer-local-boundp'.
+
+2021-05-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new convenience function `buffer-local-boundp'
+
+ * doc/lispref/variables.texi (Creating Buffer-Local): Document it.
+ * lisp/subr.el (buffer-local-boundp): New function.
+
+ * src/data.c (Flocal_variable_p): Mention it.
+
+2021-05-31 Daniel Mendler <mail@daniel-mendler.de>
+
+ Speed up `describe-variable' completion predicate
+
+ * lisp/help-fns.el (describe-variable): Do not switch to the original
+ buffer in the predicate (bug#48738).
+
+2021-05-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix error in xdg-mime-apps-files when XDG_CURRENT_DESKTOP is defined
+
+ * lisp/xdg.el (xdg-mime-apps-files): Don't bug out when
+ XDG_CURRENT_DESKTOP is bound (bug#48748).
+
+2021-05-30 Philipp Stephani <phst@google.com>
+
+ Document that the 'syntax-propertize-function' may move point.
+
+ The functions generated by 'syntax-propertize-rules' don't use
+ 'save-excursion', but 'syntax-propertize' does, so we might as well
+ document that the 'syntax-propertize-function' may move point.
+
+ * doc/lispref/syntax.texi (Syntax Properties): Document that the
+ 'syntax-propertize-function' may move point.
+
+2021-05-30 Philipp Stephani <phst@google.com>
+
+ Give 'syntax-propertize-wholelines' a docstring.
+
+ This function is generally useful.
+
+ * lisp/emacs-lisp/syntax.el (syntax-propertize-wholelines): Add
+ docstring.
+
+2021-05-30 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ time-stamp: fix minor bug when parsing option combos
+
+ * lisp/time-stamp.el (time-stamp-string-preprocess): Handle digit
+ options correctly to avoid overcounting colon options.
+
+ * test/lisp/time-stamp-tests.el (time-stamp-format-time-zone-offset):
+ Add a new test case that would have caught the option-parsing error.
+
+2021-05-30 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ time-stamp: refactor time-stamp-string-preprocess
+
+ * lisp/time-stamp.el (time-stamp-string-preprocess): Reduce lifetime of
+ some loop-local variables to be less error-prone.
+
+2021-05-30 Mauro Aranda <maurooaranda@gmail.com>
+
+ Do not reset settings when disabling a theme
+
+ * lisp/custom.el (disable-theme): Don't call custom-push-theme, since
+ that resets the theme settings and it isn't useful: we only need to
+ remove the theme setting from the themed variable or face. This fixes
+ a regression when "toggling" themes, introduced while fixing Bug#34027.
+ (Bug#48736)
+
+2021-05-30 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of regexp ranges
+
+ * doc/lispref/searching.texi (Regexp Special): Document the effect
+ of using octal escapes in regexp ranges. (Bug#17758)
+
+2021-05-30 Eli Zaretskii <eliz@gnu.org>
+
+ Don't account for character compositions in 'format' and friends
+
+ 'lisp_string_width' is called from 'format' and 'format-message',
+ which can be called both very early into Emacs initialization and in
+ other contexts where using the font backend is impossible or
+ undesirable. So this commit changes 'lisp_string_width' to try
+ accounting for automatic compositions only when explicitly requested,
+ and only 'string-width' does that; 'format' and 'format-message'
+ don't.
+ * src/character.c (lisp_string_width): Accept an additional
+ argument AUTO_COMP; attempt accounting for auto-compositions only
+ if that argument is non-zero. (Bug#48732)
+ * src/editfns.c (styled_format):
+ * src/character.c (Fstring_width): Callers of 'lisp_string_width'
+ adjusted.
+
+2021-05-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify that `symbol-file' only works for symbols in Lisp files
+
+ * lisp/subr.el (symbol-file): Mention help-C-file-name in the doc
+ string (bug#14932).
+
+2021-05-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow help-C-file-name to work on symbols designating subrs
+
+ * lisp/help-fns.el (help-C-file-name): Allow working on symbols
+ designating subrs (bug#14932).
+
+2021-05-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix kmacro-view-ring-2nd doc string
+
+ * lisp/kmacro.el (kmacro-view-ring-2nd): Fix doc string (bug#15020).
+
+2021-05-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move menu-bar-select-buffer to msb.el
+
+ * lisp/menu-bar.el (menu-bar-select-buffer): Move from
+ here... (bug#15651).
+ * lisp/msb.el (menu-bar-select-buffer): ... to here (which is the
+ only usage in-tree in Emacs).
+
+2021-05-30 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ time-stamp: improve unit-test coverage
+
+ * test/lisp/time-stamp-tests.el (time-stamp-format-year-4digit,
+ time-stamp-format-ignored-modifiers): Improve coverage with more cases.
+ (time-stamp-format-multiple-conversions): New test.
+
+2021-05-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ `minibuffer-exit-hook' doc string clarification
+
+ * src/minibuf.c (syms_of_minibuf): `minibuffer-exit-hook' is run
+ in the minubuffer usually, so don't claim that it's run after
+ (bug#16524).
+
+2021-05-30 Daniel Martín <mardani29@yahoo.es>
+
+ Add a new documentation group for overlays
+
+ * lisp/emacs-lisp/shortdoc.el (overlay): Add documentation group for
+ buffer overlays(bug#48730).
+
+2021-05-30 Daniel Martín <mardani29@yahoo.es>
+
+ Improve the documentation of documentation groups
+
+ * doc/lispref/help.texi (Documentation Groups): Fix typos and add an
+ example.
+ * lisp/emacs-lisp/shortdoc.el (define-short-documentation-group): Add
+ :no-eval* and :result-string keywords to the docstring. (Bug#48730)
+
+2021-05-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak octave continuation indentation
+
+ * lisp/progmodes/octave.el (octave-smie-rules): Further tweak
+ continuation indentation (bug#17955).
+
+2021-05-30 Eli Zaretskii <eliz@gnu.org>
+
+ Clarify indent-line-function doc string
+
+ * lisp/indent.el (indent-line-function): Clarify by avoiding
+ specifics (bug#20846).
+
+2021-05-29 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/mpc.el (mpc-format): Fix inf-loop in constructed predicate
+
+2021-05-29 Andreas Schwab <schwab@linux-m68k.org>
+
+ * lisp/wdired.el (wdired-normalize-filename): Sync with
+ dired-get-filename. (Bug#48659)
+
+2021-05-29 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/electric.el: Do auto-indent inside strings and comments by default
+
+ This fixes bug#20846 where it transpired that there is no good reason
+ to shy away from auto-indenting inside comments and strings.
+
+ (electric-indent-post-self-insert-function): Don't check syntax-ppss.
+
+2021-05-29 Keith David Bershatsky <esq@lawlist.com>
+
+ Improve tex fontification of quoted strings
+
+ * lisp/textmodes/tex-mode.el (tex-font-lock-keywords-2): Fontify
+ ``text like this'' that has an apostrophe correctly (bug#16881).
+
+2021-05-29 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change
+
+ * lisp/international/quail.el (quail-add-unread-command-events):
+ Fix wording of the doc string. Move the rationale for the
+ function out of the doc string and into a comment.
+
+2021-05-29 Gregory Heytings <gregory@heytings.org>
+
+ Fix key recording bug when an input method is activated
+
+ * lisp/international/quail.el (quail-add-unread-command-events):
+ New function.
+ (quail-start-translation, quail-start-conversion)
+ (quail-update-translation, quail-next-translation)
+ (quail-prev-translation, quail-next-translation-block)
+ (quail-prev-translation-block, quail-minibuffer-message): Use
+ 'quail-add-unread-command-events' (and partly revert commit
+ 03e3440dbb). (Bug#48042)
+
+ * lisp/subr.el (inhibit--record-char): Now obsolete.
+
+ * lisp/term/xterm.el (xterm--init): New function, with most of the
+ code of former 'terminal-init-xterm'.
+ (terminal-init-xterm): Clear the lossage after terminal
+ initialization (see Bug#44908).
+ (xterm--read-event-for-query): Do not use 'inhibit--record-char'
+ anymore (revert commit 3e6525d69f).
+
+ * src/keyboard.c (syms_of_keyboard): Remove 'inhibit--record-char'
+ (partly revert 03e3440dbb).
+ (record_char, syms_of_keyboard_for_pdumper): Do not use
+ 'inhibit_record_char anymore'.
+
+2021-05-29 Mattias Engdegård <mattiase@acm.org>
+
+ Fix shortdoc examples
+
+ Make sure that each example in shortdoc actually contains the function
+ it illustrates, and add a test for it.
+
+ * lisp/emacs-lisp/shortdoc.el (string, list, buffer, number):
+ Use the right functions in examples for string-version-lessp,
+ lax-plist-put, point-min and ffloor.
+ * test/lisp/emacs-lisp/shortdoc-tests.el: New test file.
+
+2021-05-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add lambda to the pretty Ruby symbols list
+
+ * lisp/progmodes/ruby-mode.el (ruby--prettify-symbols-alist): Add
+ lambda (bug#48681).
+
+2021-05-29 William Denton <wtd@pobox.com>
+
+ Add pretty symbols to ruby-mode
+
+ * lisp/progmodes/ruby-mode.el (ruby--prettify-symbols-alist): Add
+ pretty symbols (bug#48681).
+ (ruby-mode): Use them.
+
+2021-05-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention the recent floating point reader changes in NEWS
+
+ * etc/NEWS: Mention the floating point reader changes (bug#48678).
+
+2021-05-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the dired-guess-shell-alist-user doc string
+
+ * lisp/dired-x.el (dired-guess-shell-alist-user): Document how
+ REGEXP is used (bug#17251).
+
+2021-05-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix folding of non-ASCII lines when printing to Postscript
+
+ * lisp/ps-mule.el (ps-mule-plot-string): Fix folding of non-ASCII
+ Latin-1 lines (bug#17758).
+
+2021-05-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve Octave indentation after continuation lines
+
+ * lisp/progmodes/octave.el (octave-smie-rules): Indent
+ continuation lines better (bug#17955).
+
+2021-05-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the file-accessible-directory-p doc strin
+
+ * src/fileio.c (Ffile_accessible_directory_p): Don't use the
+ phrase "directory name spec", which isn't defined (bug#18201).
+
+2021-05-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix point movement in morse-region and nato-region
+
+ * lisp/play/morse.el (morse-region):
+ (nato-region): Leave point after the translated region
+ (bug#18717).
+
+2021-05-29 Peter Oliver <p.d.oliver@mavit.org.uk> (tiny change)
+
+ Rename emacs.appdata.xml to emacs.metainfo.xml and add more data
+
+ * Makefile.in: Replace "appdata" with "metainfo".
+
+ This is the name currently recommended by the spec at
+ <https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html>.
+
+ * etc/emacs.metainfo.xml: Populate more fields, based on those
+ available in
+ https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html
+ (bug#48662).
+
+2021-05-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Continue checking the same line when hitting SPC in ispell"
+
+ This reverts commit 390044f854fa103020ffca00eb1fe0e16805ad72.
+
+ This breaks the `a' command, so it should be fixed in a different way.
+
+2021-05-28 Juri Linkov <juri@linkov.net>
+
+ * lisp/outline.el (outline-font-lock-keywords): Fix highlight case (bug#48707)
+
+2021-05-28 Utkarsh Singh <utkarsh190601@gmail.com> (tiny change)
+
+ * lisp/outline.el (outline-minor-mode-highlight): Fix safe-local-variable.
+
+2021-05-28 Eli Zaretskii <eliz@gnu.org>
+
+ Another stability fix in 'lisp_string_width'
+
+ * src/character.c (lisp_string_width): Compute C pointer to data
+ of STRING immediately before using it, since STRING could be
+ relocated by GC triggered by processing compositions. (Bug#48711)
+
+2021-05-28 Eli Zaretskii <eliz@gnu.org>
+
+ Attempt to fix segfaults caused by changes in 'lisp_string_width'
+
+ * src/character.c (lisp_string_width): Validate the value of TO
+ argument before passing it to 'composition_gstring_width'.
+ (Bug#48711)
+
+2021-05-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve previous frames.texi change
+
+ * doc/emacs/frames.texi (Fonts): Use conf names instead of path
+ names (bug#19568).
+
+2021-05-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Specify which Gsetting font names are used in the manual
+
+ * doc/emacs/frames.texi (Fonts): Explicitly say what Gsettings
+ names are used (bug#19568).
+
+2021-05-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous admin/emake change
+
+2021-05-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust admin/emake filters
+
+ Recent changes have made etc/doc always be regenerated, so it's no
+ longer interesting. And all "git pull"s will make
+
+ INFO Scraping files for cal-loaddefs.el...
+ INFO Scraping files for cal-loaddefs.el...done
+
+ etc be output, so filter them, too.
+
+2021-05-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Continue checking the same line when hitting SPC in ispell
+
+ * lisp/textmodes/ispell.el (ispell-process-line): Continue
+ checking the same line when hitting SPC (bug#20543).
+
+2021-05-28 Daniel Martín <mardani29@yahoo.es>
+
+ Fix looking-at-p example in shortdoc.el
+
+ * lisp/emacs-lisp/shortdoc.el (regexp): Use `looking-at-p' instead of
+ `looking-at' (bug#48709).
+
+2021-05-28 Alex Bochannek <alex@bochannek.com>
+
+ Mention the -e switch in an ange-ftp doc string
+
+ * lisp/net/ange-ftp.el (ange-ftp-ftp-program-args): Mention the -e
+ switch (bug#48494).
+
+2021-05-28 Alex Bochannek <alex@bochannek.com>
+
+ Fix nnimap lexical conversion problem
+
+ * lisp/gnus/nnimap.el (nnimap-process-expiry-targets): Fix problem
+ introduced when converting to lexical binding -- `set' alters the
+ dynamic value (bug#48577).
+
+2021-05-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand): Silence warnings
+
+ (byte-optimize--lexvars): Move before first use instead of using `dlet`
+ on that first use.
+
+2021-05-27 Ingo Lohmar <ingo.lohmar@posteo.net>
+
+ * lisp/progmodes/sql.el: Turn `sql-*-statement-starters' to defvars.
+
+ These variables hold information on the SQL standard and
+ product-specific additions and should not be user-customizable.
+
+2021-05-27 Eli Zaretskii <eliz@gnu.org>
+
+ * src/character.c (lisp_string_width): Fix a typo in recent change.
+
+2021-05-27 Eli Zaretskii <eliz@gnu.org>
+
+ Fix resolution of symlinks during dumping
+
+ * src/comp.c (Fcomp_el_to_eln_rel_filename): Don't use
+ 'file-truename', as it is only available once files.el is loaded,
+ which doesn't work during dumping, until loadup loads files.el.
+ Instead, use 'realpath'. (Bug#48578)
+ * src/w32.c (realpath): New function.
+ * src/w32.h (realpath): Add prototype.
+
+ * nt/mingw-cfg.site (ac_cv_func_realpath)
+ (gl_cv_func_realpath_works): Define to "yes", as this function is
+ now implemented in w32.c.
+
+2021-05-27 Eli Zaretskii <eliz@gnu.org>
+
+ * src/character.c (lisp_string_width): Fix last change.
+
+2021-05-27 Mattias Engdegård <mattiase@acm.org>
+
+ Fix lexing of numbers with trailing decimal point and exponent
+
+ Numbers with a trailing dot and an exponent were incorrectly read as
+ integers (with the exponent ignored) instead of the floats they should
+ be. For example, 1.e6 was read as the integer 1, not 1000000.0 as
+ every sane person would agree was meant. (Bug#48678)
+
+ Numbers with a trailing dot but no exponent are still read as
+ integers.
+
+ * src/lread.c (string_to_number): Fix float lexing.
+ * test/src/lread-tests.el (lread-float): Add test.
+ * doc/lispref/numbers.texi (Float Basics): Clarify syntax.
+
+2021-05-27 Mattias Engdegård <mattiase@acm.org>
+
+ Don't propagate lexical variables into inlined functions
+
+ Functions compiled when inlined (thus from inside the optimiser)
+ mustn't retain the lexical environment of the caller or there will be
+ tears. See discussion at
+ https://lists.gnu.org/archive/html/emacs-devel/2021-05/msg01227.html .
+
+ Bug found by Stefan Monnier.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand):
+ Bind byte-optimize--lexvars to nil when re-entering the compiler
+ recursively.
+ * test/lisp/emacs-lisp/bytecomp-resources/bc-test-alpha.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/bc-test-beta.el: New files.
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-defsubst): New test.
+
+2021-05-27 Philipp Stephani <phst@google.com>
+
+ * src/character.c (lisp_string_width): Add missing type checks.
+
+2021-05-27 Eli Zaretskii <eliz@gnu.org>
+
+ A better fix for 'string-width'
+
+ * src/character.c (lisp_string_width): Compute the width when
+ automatic compositions can happen more accurately, by using the
+ pixel widths of the grapheme clusters, divided by the default
+ face's font width. Disregard the current state of
+ 'auto-composition-mode', for consistency with 'current-column' .
+
+2021-05-27 Deneb Meketa <deneb@pixar.com> (tiny change)
+
+ Fix filling of overlong first lines in Python doc strings
+
+ * lisp/progmodes/python.el (python-fill-string): Fill overlong
+ first lines correctly (bug#20860).
+
+2021-05-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the prompting in read-directory-name
+
+ * lisp/dired-x.el (dired-virtual): Improve doc string and use
+ `read-directory-name' (bug#20993).
+
+2021-05-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix ediff message parsing in non-English locales
+
+ * lisp/vc/ediff-diff.el (ediff-exec-process): Run diff in the C
+ locale to enable parsing the messages (bug#21387).
+
+2021-05-27 Juri Linkov <juri@linkov.net>
+
+ * lisp/vc/diff-mode.el (diff-hunk-text): Test-driven fix for newlines.
+
+ * lisp/vc/diff-mode.el (diff-hunk-text): Fix handling of newlines
+ to cover all test cases according to new test.
+
+ * test/lisp/vc/diff-mode-tests.el (diff-mode-test-hunk-text-no-newline):
+ New test to cover cases with no newline at end of file.
+
+2021-05-26 Alex Bochannek <alex@bochannek.com>
+
+ Remove the base64 Face header repadding in Gnus
+
+ * lisp/gnus/gnus-fun.el (gnus-convert-face-to-png): Remove call.
+
+ * lisp/gnus/gnus-util.el (gnus-base64-repad): Remove.
+
+2021-05-26 Karl Fogel <kfogel@red-bean.com>
+
+ Improve some doc strings in bookmark.el
+
+ * lisp/bookmark.el (bookmark-bmenu-load): Describe prefix argument
+ behavior. Refer to related functions for more information.
+ (bookmark-bmenu-save): Likewise refer to related functions.
+
+ As discussed in this thread:
+
+ https://lists.gnu.org/archive/html/emacs-devel/2021-05/msg00389.html
+
+ From: Karl Fogel
+ To: Eli Zaretskii
+ Cc: Matthias Meulien, Drew Adams, Lars Ingebrigtsen,
+ Stefan Monnier, Emacs Devel
+ Subject: Re: [External] : Re: [PATCH] When deleting in bookmark menu,
+ prompt for confirmation.
+ Date: Sun, 09 May 2021 13:37:52 -0500
+ Message-ID: <87h7jboirj.fsf@red-bean.com>
+
+2021-05-26 Eli Zaretskii <eliz@gnu.org>
+
+ Make 'string-width' auto-composition aware
+
+ * src/composite.c (find_automatic_composition): Now extern.
+ (char_composable_p): Don't assume 'unicode-category-table' is
+ always available.
+ * src/composite.h (find_automatic_composition): Add prototype.
+ * src/character.c (lisp_string_width): Support automatic
+ compositions; call 'find_automatic_composition' when
+ 'auto-composition-mode' is ON.
+
+2021-05-26 Filipp Gunbin <fgunbin@fastmail.fm>
+
+ * src/sysdep.c (system_process_attributes): Fix misspelled Qttname for FreeBSD
+
+2021-05-26 Filipp Gunbin <fgunbin@fastmail.fm>
+
+ Improve system_process_attributes on macOS (Bug#48548)
+
+ * src/sysdep.c (system_process_attributes): Fix misprint in 'tty' attr
+ - should be 'ttname' instead. Change 'utime', 'stime', 'time',
+ 'majflt' attrs to obtain them from proc_pid_rusage, as sysctl call
+ used before doesn't give correct values; remove 'minflt' because it's
+ not available. Obtain 'vsize' / 'rss' / 'thcount' from proc_pidinfo.
+ Use sysctl with KERN_PROCARGS2 to obtain args: value contains both
+ argc and argv, so argv can be reliably cut out.
+
+2021-05-26 Protesilaos Stavrou <info@protesilaos.com>
+
+ Remove modus-themes.org build date (bug#48661)
+
+ * doc/misc/modus-themes.org: Delete Org macro of the current export date.
+
+ This makes the manual reproducible between Emacs builds.
+
+2021-05-25 Juri Linkov <juri@linkov.net>
+
+ * lisp/international/mule-cmds.el (mule--ucs-names-group): Better char check.
+
+2021-05-25 Tassilo Horn <tsdh@gnu.org>
+
+ Make the Alacritty terminal an alias of xterm-256color
+
+ * lisp/faces.el (term-file-aliases): Make the Alacritty terminal
+ an alias of xterm-256color (bug#48439).
+
+2021-05-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make hs-set-up-overlay into user option
+
+ * lisp/progmodes/hideshow.el (hs-set-up-overlay): Make into
+ defcustom (bug#48513).
+
+2021-05-25 Stephen Leake <stephen_leake@stephe-leake.org>
+
+ Restore `ff-find-other-file' buffer selection logic
+
+ * lisp/find-file.el (ff-find-other-file): Restore selection of
+ buffer changed by previous change (bug#48535).
+
+2021-05-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix font and indentation of call-with-port in scheme-mode
+
+ * lisp/progmodes/scheme.el (scheme-font-lock-keywords-2): Add
+ call-with-port (bug#48544).
+ (call-with-port): Indent correctly.
+
+2021-05-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Handle syntactically invalid .dir-locals.el files better
+
+ * lisp/files.el (dir-locals-read-from-dir): Handle syntactically
+ invalid .dir-locals.el files more gently (bug#48568). Give a
+ message instead of bugging out later.
+
+2021-05-25 Protesilaos Stavrou <info@protesilaos.com>
+
+ Update modus-themes to version 1.4.0
+
+ * doc/misc/modus-themes.org:
+ (Overview): Document good support for cases with red-green color
+ deficiency (deuteranopia).
+ (Customization Options): Add code block with sample configuration.
+ (Option for mode line presentation): Document new values.
+ (Option for completion framework aesthetics): Reword statements.
+ (Option for mail citations): Include new customization.
+ (Option for line highlighting (hl-line-mode)): Change description
+ of possible value.
+ (Option for diff buffer looks): Update the meaning of 'fg-only',
+ which now is an alias for 'fg-only-deuteranopia'.
+ (Option for org-mode block styles): Rename possible values.
+ (Cycle through arbitrary colors (DIY)): Include code samples for
+ demo case.
+ (Override colors (DIY)): Use correct symbol.
+ (Override color saturation (DIY)): Show how to combine manual and
+ automatic color overrides.
+ (Update Org block delimiter fontification (DIY)): Provide example.
+ (Load theme depending on time of day): Include missing "DIY" label.
+ (Full support for packages or face groups): Update list with
+ additions, removals.
+ (Indirectly covered packages): Update list.
+ (Notes for individual packages)
+ (Note on dimmer.el)
+ (Note on display-fill-column-indicator-mode)
+ (Note on mmm-mode.el background colors)
+ (Note on prism.el)
+ (Note on ERC escaped color sequences)
+ (Note on powerline or spaceline)
+ (Note on Helm grep)
+ (Note on EWW and Elfeed fonts (SHR fonts)): Stylistic change to
+ the heading.
+ (Note on inline Latex in Org buffers)
+ (Note on god-mode.el): Add note.
+ (Frequently Asked Questions (FAQ)): Include new section.
+ (Acknowledgements): Update list of contributors (bug#48647).
+ * etc/themes/modus-operandi-theme.el: Bump version number.
+
+ * etc/themes/modus-themes.el: Add new defcustom forms and update
+ existing ones, edit doc strings, remove old obsolete aliases,
+ tweak internal functions, refine face specifications.
+
+ * etc/themes/modus-vivendi-theme.el: Bump version number.
+
+2021-05-25 Gregory Heytings <gregory@heytings.org>
+
+ Do not switch to other window when minibuffer is selected
+
+ * lisp/window.el (handle-select-window): Do not silently switch to
+ other window when minibuffer is selected and
+ mouse-autoselect-window is t (Bug#47969).
+
+2021-05-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Restore `dired-do-create-files' return value
+
+ * lisp/dired-aux.el (dired-do-create-files): Preserve the return
+ value from `dired-create-files', which is apparently an
+ undocumented feature used by dired-aux-tests.el (dired-test-bug30624).
+
+2021-05-25 Eli Zaretskii <eliz@gnu.org>
+
+ Fix documentation of a recent change
+
+ * src/process.c (syms_of_process) <process-prioritize-lower-fds>:
+ Doc fix.
+
+ * etc/NEWS: Reword the entry for 'process-prioritize-lower-fds'.
+
+2021-05-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Update help-tests.el after minibuffer map change
+
+2021-05-25 Miha Rihtaršič <miha@kamnitnik.top>
+
+ Try to not prioritise reading from lower file descriptors
+
+ * src/process.c (wait_reading_process_output): When looping through
+ fds, continue from where we left off.
+ (syms_of_process): Vprocess_prioritize_lower_fds: New variable
+ (bug#48118).
+
+2021-05-25 Glenn Morris <rgm@gnu.org>
+
+ * doc/misc/cc-mode.texi: Remove hand-written node pointers (bug#48402).
+
+2021-05-25 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/byte-opt.el: Make the build more reproducible
+
+ (byte-compile-inline-expand): When inlining code from another file,
+ always inline the byte-code version of the function.
+ (byte-optimize--pcase): Simplify edebug spec.
+
+2021-05-25 Philipp Stephani <phst@google.com>
+
+ Allow years in a copyright range to be separated by en dashes.
+
+ * lisp/emacs-lisp/copyright.el (copyright-regexp)
+ (copyright-years-regexp, copyright-update-year)
+ (copyright-fix-years): Also include en dash.
+
+ * test/lisp/emacs-lisp/copyright-tests.el (copyright-tests--data): New
+ test cases.
+
+2021-05-25 Jonas Bernoulli <jonas@bernoul.li>
+
+ * lisp/transient.el: Update to package version 0.3.4.
+
+2021-05-25 Gregory Heytings <gregory@heytings.org>
+
+ Further improvements to completion-list-mode-map
+
+ * doc/emacs/mini.texi (Completion Commands): Mention the change,
+ and mention the 'n' and 'p' keys bound to 'next-completion' and
+ 'previous-completion'. (bug#47699).
+ * lisp/minibuffer.el (minibuffer-local-completion-map): Change the
+ M-g key to M-g M-c.
+
+ * lisp/simple.el (completion-list-mode-map): Change the M-g key to
+ M-g M-c.
+ (read-expression-map): Bind M-g M-c to
+ read-expression-switch-to-completions.
+ (read-expression-switch-to-completions): New function.
+
+2021-05-25 Gregory Heytings <gregory@heytings.org>
+
+ Improve completion-list-mode-map
+
+ * doc/emacs/mini.texi (Completion Commands): Mention it.
+
+ * lisp/minibuffer.el (minibuffer-local-completion-map): Add the M-g key
+ for switch-to-completion (bug#47699).
+
+ * lisp/simple.el (completion-list-mode-map): Make special-mode-map its
+ parent, unbind the 'g' revert key, add the 'n' and 'p' keys for
+ next-completion and previous-completion, and the M-g key for
+ switch-to-minibuffer.
+ (switch-to-minibuffer): New function.
+
+2021-05-25 Gregory Heytings <gregory@heytings.org>
+
+ Use correct face when pulsing in CEDET
+
+ * lisp/cedet/pulse.el (pulse-momentary-highlight-overlay): Use
+ pulse-highlight-face, not pulse-highlight-start-face (bug#47810).
+
+2021-05-25 Gregory Heytings <gregory@heytings.org>
+
+ Consider all user-defined bitmaps in gui_init_fringe()
+
+ * src/fringe.c (gui_init_fringe): Consider user-defined bitmaps
+ that override default ones (bug#47832).
+
+2021-05-25 Gregory Heytings <gregory@heytings.org>
+
+ Fix infloop in Modula-2 mode
+
+ * lisp/progmodes/modula2.el (m2-smie-refine-colon): Stop looping
+ when point does not move with forward-sexp (Bug#48011).
+
+2021-05-25 Amin Bandali <bandali@gnu.org>
+
+ * lisp/erc/erc-services.el: Fix newly-added Libera.Chat entry (bug#48529).
+
+2021-05-25 Gregory Heytings <gregory@heytings.org>
+
+ Fix bug when moving directories to trash
+
+ * lisp/files.el (move-file-to-trash): Pass the correct dir-flag to
+ make-temp-file so that a directory is created when a directory is
+ being trashed (Bug#47960).
+
+2021-05-24 Corwin Brust <corwin@bru.st> (tiny change)
+
+ Add Libera.chat to `erc-nickserv-alist'
+
+ * lisp/erc/erc-services.el (erc-nickserv-alist): Add support for
+ the Libera chat.
+
+2021-05-24 Glenn Morris <rgm@gnu.org>
+
+ Tweak c-mode bug reporting address
+
+ * lisp/progmodes/cc-mode.el (c-mode-help-address):
+ Switch to bug-gnu-emacs. This is an alias for the previous
+ submit@debbugs address, except that if no Package header can be found,
+ as often seems to happen for cc-mode reports, debbugs will assign
+ the report to the "emacs" package rather than to "debbugs.gnu.org".
+
+2021-05-23 Philipp Stephani <phst@google.com>
+
+ Fix find invocation for macOS (Bug#48471).
+
+ * lisp/progmodes/project.el (project--files-in-directory): Instead of
+ appending a slash (which doesn't work well with macOS find), remove
+ trailing slash and pass -H instead.
+
+2021-05-23 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt tramp-archive-autoload-file-name-handler
+
+ * lisp/net/tramp-archive.el (tramp-archive-autoload-file-name-handler):
+ Bind `default-directory' to safe value.
+
+2021-05-22 Juri Linkov <juri@linkov.net>
+
+ * src/editfns.c (Finsert_char): Add docstring reference to read-char-by-name.
+
+2021-05-22 Tassilo Horn <tsdh@gnu.org>
+
+ Document bug-reference setup for 3rd-party packages
+
+ * doc/emacs/maintaining.texi (Bug Reference): Add section explaining
+ adding support for third-party packages.
+ * lisp/progmodes/bug-reference.el (bug-reference-maybe-setup-from-vc)
+ (bug-reference-maybe-setup-from-mail)
+ (bug-reference-maybe-setup-from-irc): Rename from
+ bug-reference--maybe-setup-from-*, i.e., un-privatize them because
+ they are advertised in the docs now.
+
+2021-05-22 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 30e5d93ee1 (origin/emacs-27) Improve documentation of display tables
+ 8804ac857b * src/buffer.c (syms_of_buffer) <ctl-arrow>: Doc fix. (Bu...
+
+2021-05-22 Glenn Morris <rgm@gnu.org>
+
+ * doc/emacs/maintaining.texi (Bug Reference): Fix cross refs.
+
+ "First argument to cross-reference may not be empty." (makeinfo 4).
+
+2021-05-22 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix bug#48476
+
+ * lisp/net/tramp-archive.el (tramp-archive-autoload-file-name-handler):
+ Add implementation.
+
+ * lisp/net/tramp-integration.el (tramp-rename-files)
+ (tramp-rename-these-files): Declare them.
+
+ * lisp/net/tramp.el (tramp-autoload-file-name-handler):
+ Load tramp-archive.el if needed. (Bug#48476)
+
+ * test/lisp/net/tramp-archive-tests.el (tramp-archive-test45-auto-load):
+ Extend test.
+
+ Use #' syntax for function symbols.
+
+2021-05-22 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/subr-x.el (if-let*, if-let): Use looser Edebug spec
+
+ This makes the same spec work both for `if-let` and `when-let`.
+
+ (when-let*, and-let*, when-let): Simplify accordingly.
+
+2021-05-22 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix native-comp-async-report-warnings-errors :type
+
+ * doc/lispref/compile.texi (Native-Compilation Variables): Document
+ 'silent' alternative of native-comp-async-report-warnings-errors.
+ * lisp/emacs-lisp/comp.el
+ (native-comp-async-report-warnings-errors): Fix quoting in
+ :type expression (bug#48586).
+
+2021-05-22 Philipp Stephani <phst@google.com>
+
+ Give 'when-let' and 'when-let*' their own Edebug specification.
+
+ The Edebug specification of 'if-let' and 'if-let*' doesn't work if the
+ body is empty. While that's a pathological case, it's not wrong per
+ se, and could arguably happen due to macro expansion.
+
+ * lisp/emacs-lisp/subr-x.el (when-let*, when-let): Don't reuse Edebug
+ specification from 'if-let*' and 'if-let'.
+
+2021-05-22 Philipp Stephani <phst@google.com>
+
+ * lisp/emacs-lisp/cl-macs.el (cl-loop): Add missing 'when' to spec
+
+2021-05-21 Tassilo Horn <tsdh@gnu.org>
+
+ Add documentation about bug-reference auto-setup.
+
+ * doc/emacs/maintaining.texi (Bug Reference): Add documentation about
+ the automatic setup.
+ * lisp/progmodes/bug-reference.el
+ (bug-reference-setup-from-irc-alist): Remove doubling in docstring.
+
+2021-05-21 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Robustify parsing of gnus-search search results
+
+ * lisp/gnus/gnus-search.el (gnus-search-indexed-parse-output): Look
+ for a "process finished" tag, and don't choke on mis-parsed lines.
+
+2021-05-21 Juri Linkov <juri@linkov.net>
+
+ * lisp/dired-aux.el (dired-do-revert-buffer): New defcustom (bug#48456).
+
+ (dired-do-create-files): Use it.
+
+2021-05-21 Juri Linkov <juri@linkov.net>
+
+ * lisp/simple.el (yank-from-kill-ring): Fix kill-ring-yank-pointer (bug#48478)
+
+2021-05-21 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt native-comp entries in gitlab-ci.yml
+
+ * test/infra/gitlab-ci.yml (stages): New stages native-comp-images
+ and native-comp.
+ (build-native-bootstrap-speed0): Simplify.
+ (build-native-bootstrap-speed1, build-native-bootstrap-speed2):
+ Deactivate temporarily.
+
+ * test/infra/gitlab-ci.yml (.build-template): Add 'needs:' clause.
+ (.native-comp-template): New template.
+ (build-native-bootstrap-speed0): Use it.
+
+2021-05-21 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid byte-compiler warning during bootstrap
+
+ * lisp/isearch.el (multi-isearch-switch-buffer): Avoid
+ byte-compiler warning.
+
+2021-05-21 Michael Albinus <michael.albinus@gmx.de>
+
+ Rearrange nativecomp tests for EMBA
+
+ * test/infra/Dockerfile.emba (emacs-native-comp-speed0):
+ Add recipe.
+
+ * test/infra/gitlab-ci.yml (stages): New stages native-comp-images
+ and native-comp.
+ (build-native-bootstrap-speed0): Simplify.
+ (build-native-bootstrap-speed1, build-native-bootstrap-speed2):
+ Deactivate temporarily.
+
+2021-05-21 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of display tables
+
+ * doc/lispref/display.texi (Display Tables): Add a cross-reference
+ to the next section.
+
+2021-05-21 Andrea Corallo <akrl@sdf.org>
+
+ Fix ahead-of-time native compilation for out-of-tree builds (bug#48497)
+
+ * src/comp.c (Fcomp_el_to_eln_rel_filename): Expand
+ 'PATH_DUMPLOADSEARCH' while computing 'loadsearch_re_list'.
+
+2021-05-21 Eli Zaretskii <eliz@gnu.org>
+
+ * src/buffer.c (syms_of_buffer) <ctl-arrow>: Doc fix. (Bug#48539)
+
+2021-05-20 Juri Linkov <juri@linkov.net>
+
+ * lisp/help.el (describe-bindings-outline): New defcustom (bug#45147).
+
+ (describe-bindings): Use describe-bindings-outline.
+ (describe-bindings-internal): Remove function obsolete since 24.4.
+
+2021-05-20 Juri Linkov <juri@linkov.net>
+
+ * lisp/vc/diff-mode.el (diff-hunk-text): Handle better "\ No newline at end".
+
+2021-05-20 Juri Linkov <juri@linkov.net>
+
+ Fix off-by-one inconsistency of 'M-y C-y' (bug#48478).
+
+ * lisp/simple.el (read-from-kill-ring): Increment kill-ring-yank-pointer by 1.
+ (yank-from-kill-ring): Don't increment kill-ring-yank-pointer by 1.
+
+2021-05-20 Juri Linkov <juri@linkov.net>
+
+ * lisp/international/mule-cmds.el: Use group-function in read-char-by-name.
+
+ (mule--ucs-names-group): Simplify for using by group-function.
+ (read-char-by-name-group): Remove defcustom
+ obsoleted by completions-group.
+ (read-char-by-name): Mention completions-group and
+ completions-group-sort in docstring. Use group-function when
+ completions-group is non-nil.
+ https://lists.gnu.org/archive/html/emacs-devel/2021-05/msg00791.html
+
+2021-05-20 Daniel Mendler <mail@daniel-mendler.de>
+
+ (minibuffer-completion-help): Add group sorting
+
+ Sort the groups as returned by the `group-function` of the completion
+ table depending on the value of the customizable variable
+ `completions-group-sort`. By default `completions-group-sort` is set
+ to nil. The variable can be set to the symbol `alphabetical` in order
+ to configure alphabetical sorting. Furthermore, a custom sorting
+ function can be used as value of `completions-group-sort`.
+
+ * lisp/minibuffer.el (completions-group-sort): New variable.
+ (minibuffer--group-by): Add SORT-FUN argument.
+ (minibuffer-completion-help): Pass `completions-group-sort` to
+ `minibuffer--group-by`.
+
+2021-05-20 Daniel Mendler <mail@daniel-mendler.de>
+
+ (completion--insert-vertical): Separate groups completely
+
+ Insert the candidates vertically within the groups, but keep the
+ groups separate using the full width group separators.
+
+ * lisp/minibuffer.el (completion--insert-vertical): Adjust
+ grouping.
+
+2021-05-20 Daniel Mendler <mail@daniel-mendler.de>
+
+ (minibuffer-completion-help): Do not check `completions-group` centrally
+
+ The guard variable `completions-group` should be checked in each
+ completion table individually. The guard variable
+ `completions-detailed` variable is used in the same way.
+
+ * lisp/minibuffer.el (minibuffer-completion-help): Remove check of
+ `completions-group`.
+
+2021-05-20 Daniel Mendler <mail@daniel-mendler.de>
+
+ (completion--insert-strings): Split function; Full group title support
+
+ Split `completion--insert-strings` into a function per completions
+ format in order to increase readability and extensibility. This
+ change eases the addition of more formats. Add support for group
+ titles to the vertical and horizontal formatting functions.
+
+ * lisp/minibuffer.el (completion--insert): Add new function.
+ (completion--insert-vertical, completion--insert-horizontal,
+ completion--insert-one-column): Extract function from
+ `completion--insert-strings`. Use new function `completion--insert`.
+ (completion--insert-strings): Use new insertion functions.
+
+2021-05-20 Daniel Mendler <mail@daniel-mendler.de>
+
+ (completing-read): Add `group-function` to the completion metadata
+
+ A completion table can specify a `group-function` in its metadata.
+ The group function takes two arguments, a completion candidate and a
+ transform argument. The group function is used to group the
+ candidates after sorting and to enhance the completion UI with group
+ titles.
+
+ If the transform argument is nil, the function must return the title
+ of the group to which the completion candidate belongs. The function
+ may also return nil if the candidate does not belong to a group.
+
+ If the transform argument is non-nil, the function must return the
+ transformed candidate. For example, the transformation allows to
+ remove a redundant part of the candidate, which is then displayed in
+ the title.
+
+ The grouping functionality is guarded by the customizable variable
+ `completions-group` and turned off by default for the *Completions*
+ buffer.
+
+ The specific form of the `group-function` has been chosen in order to
+ allow allocation-free grouping. This is important for completion UIs,
+ which continuously update the displayed set of candidates (Icomplete,
+ Vertico, Ivy, etc.). Only when the transform argument is non-nil the
+ candidate transformation is performed, which may involve a string
+ allocation as done in the function `xref--completing-read-group`.
+
+ The function `xref-show-definitions-completing-read` makes use of the
+ `group-function`, by moving the file name prefix to the title. If
+ grouping is enabled, the *Completions* are displayed as
+ "linenum:summary" instead of "file:linenum:summary". This way the
+ *Completions* buffer resembles the *Occur* buffer.
+
+ * doc/lispref/minibuf.texi: Add documentation.
+
+ * lisp/minibuffer.el (completion-metadata): Describe the
+ `group-function` in the docstring.
+ (completions-group): Add guard variable, off by default.
+ (completions-group-format): Add variable defining the format string
+ for the group titles.
+ (completions-group-title): Add face used by `completions-group-format`
+ for the group titles.
+ (completions-group-separator): Add face used by
+ `completions-group-format` for the group separator lines.
+ (minibuffer--group-by): New grouping function.
+ (minibuffer-completion-help): Use it.
+ (display-completion-list): Add optional GROUP-FUN argument.
+ (completion--insert-strings): Add optional GROUP-FUN argument. Insert
+ group titles if `completions-format` is `one-column`. Transform each
+ candidate with the GROUP-FUN. Attach the untransformed candidate to
+ the property `completion--string`.
+
+ * lisp/simple.el (choose-completion): Retrieve the untransformed
+ completion candidate from the property `completion--string`.
+
+ * lisp/progmodes/xref.el:
+ (xref--completing-read-group): New grouping function.
+ (xref-show-definitions-completing-read): Use it.
+
+2021-05-20 Michael Albinus <michael.albinus@gmx.de>
+
+ * doc/emacs/maintaining.texi (Bug Reference): Add debbugs-browse-mode.
+
+2021-05-20 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'etags' tests
+
+ * test/manual/etags/README: New file. (Bug#46055)
+
+ * test/README: Mention separate README files for tests in the
+ 'manual' subdirectory
+
+2021-05-20 Eli Zaretskii <eliz@gnu.org>
+
+ Fix arg-out-of-range errors in 'line-number-at-pos'
+
+ * src/fns.c (Fline_number_at_pos): Pass character position to
+ args_out_of_range. Suggested by Andreas Schwab
+ <schwab@linux-m68k.org>. Call args_out_of_range_3 to show both
+ ends of the accessible portion.
+
+2021-05-20 Eli Zaretskii <eliz@gnu.org>
+
+ Make sure gmalloc's hybrid_free preserves errno
+
+ * src/gmalloc.c (hybrid_free_1): New function, with the body of
+ the previous 'hybrid_free'.
+ (hybrid_free): Call 'hybrid_free_1' while preserving the value of
+ 'errno'. Suggested by Paul Eggert <eggert@cs.ucla.edu>.
+
+2021-05-20 Eli Zaretskii <eliz@gnu.org>
+
+ Clean up the fix for unexec build on GNU/Linux
+
+ * src/conf_post.h [HYBRID_MALLOC || DARWIN_OS && HAVE_UNEXEC]:
+ Include <stdlib.h> here, before redirecting 'malloc' and friends
+ to their hybrid_* and unexec_* equivalents. #undef malloc and
+ friends before redefining. Provide prototypes for the
+ replacements. Suggested by Paul Eggert <eggert@cs.ucla.edu>.
+ * src/gmalloc.c [HYBRID_MALLOC]: Remove declarations of 'malloc'
+ and friends, as they are now redundant: we include <stdlib.h> in
+ conf_post.h before redefining 'malloc' etc., and that provides
+ prototypes from system headers.
+
+ * configure.ac (HYBRID_MALLOC): Remove kludge to avoid replacement
+ of 'free' by Gnulib. (Bug#36649)
+
+2021-05-19 Tassilo Horn <tsdh@gnu.org>
+
+ Add a section about bug-reference-mode.
+
+ * doc/emacs/maintaining.texi (Maintaining): Add a section about
+ bug-reference-mode.
+ * doc/emacs/emacs.texi (Top): Link to the new section about
+ bug-reference-mode.
+
+2021-05-19 Juri Linkov <juri@linkov.net>
+
+ * lisp/simple.el (yank-from-kill-ring-rotate): New defcustom (bug#48478).
+
+ (read-from-kill-ring, yank-from-kill-ring): Use it.
+
+2021-05-19 Eli Zaretskii <eliz@gnu.org>
+
+ Fix rare failures in 'window-default-font-height'
+
+ * lisp/window.el (window-default-font-height): Avoid signaling an
+ error when a client TTY frame happens to have an X-style 'display'
+ parameter. (Bug#48408)
+
+2021-05-19 Eli Zaretskii <eliz@gnu.org>
+
+ * lisp/startup.el (command-line-1): Avoid byte-compiler warning.
+
+2021-05-19 Glenn Morris <rgm@gnu.org>
+
+ Fix custom type of recent dired-aux additions
+
+ * lisp/dired-aux.el (dired-compress-file-default-suffix)
+ (dired-compress-directory-default-suffix): Fix :type.
+
+2021-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/kmacro.el (kmacro-lambda-form): Fix bug#48523
+
+ Re-add `counter` and `format` arguments, since they are used in
+ `insert-kbd-macro`.
+
+2021-05-19 Eli Zaretskii <eliz@gnu.org>
+
+ Fix the unexec build on GNU/Linux
+
+ The unexec build on GNU/Linux must use HYBRID_MALLOC (gmalloc.c) and
+ sheap.c. This was inadvertently disabled because a configure-time
+ test for 'sbrk' was moved as side effect of an unrelated change.
+
+ * configure.ac: Test for 'sbrk' before using the result in the
+ decision about SYSTEM_MALLOC and HYBRID_MALLOC.
+ (HYBRID_MALLOC): Prevent Gnulib from redirecting 'free' to its
+ replacement 'rpl_free'.
+
+ * lib/Makefile.in (not_emacs_OBJECTS): Add mallooc/%.o and free.o.
+
+2021-05-19 Ingo Lohmar <ingo.lohmar@posteo.net>
+
+ * lisp/progmodes/sql.el: `sql-postgres-statement-starters' defcustom
+
+ Recognize common table expression as statement start in Postgres.
+
+2021-05-19 Mauro Aranda <maurooaranda@gmail.com>
+
+ Lift restriction for finding theme summary line
+
+ * lisp/cus-theme.el (custom-theme-summary): Don't limit the file to
+ having the deftheme form as the very first form, rather look for the
+ deftheme form explicitly.
+
+2021-05-19 Martin Rudalics <rudalics@gmx.at>
+
+ Fix recently introduced misbehavior of `quit-restore-window' (Bug#48493)
+
+ * lisp/window.el (quit-restore-window): Unconditionally call
+ `switch-to-prev-buffer' (Bug#48493).
+
+2021-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/js.el (js--make-framework-matcher): Use a closure
+
+2021-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/gud.el (gud-tooltip-tips): Use proper closures
+
+ Also prefer #' to quote function names.
+
+ (jdb): Fix $ => \'.
+
+2021-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/org/org-timer.el (org-timer--run-countdown-timer): Use closures
+
+2021-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/org/org-mouse.el: Make use of lexical scoping
+
+ (org-mouse-todo-menu): Simplify by eta-reduction.
+ (org-mouse-popup-global-menu): Remove redundant `eval`.
+ (org-mouse-keyword-menu, org-mouse-keyword-replace-menu)
+ (org-mouse-tag-menu, org-mouse-match-closure): Use proper closures.
+
+2021-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/org/org-colview.el (org-columns-map): Use proper closures
+
+ Also prefer #' to quote function names.
+
+ (org-columns-map): Use derived-mode-p.
+
+2021-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/org/org-clock.el (org-clock-get-table-data): Use proper closures
+
+ Also, prefer #' to quote function names
+
+2021-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/net/sieve-manage.el (sieve-sasl-auth): Use proper closures
+
+ * lisp/net/shr.el (shr-image-displayer): Use proper closures
+
+2021-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/net/imap.el (imap-mailbox-close): Use proper closures
+
+ Also, remove redundant `:group` args, and prefer #' to quote function names
+
+2021-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/net/eudc.el (eudc-menu): Use proper closures
+
+2021-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/net/browse-url.el: Avoid `(lambda ..)
+
+ (browse-url-netscape, browse-url-mozilla, browse-url-galeon)
+ (browse-url-epiphany, browse-url-elinks): Use proper closures.
+
+2021-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/misearch.el (multi-isearch-push-state): Use proper closures
+
+2021-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/menu-bar.el: Avoid `(lambda
+
+ (menu-bar-buffer-vector, menu-bar-update-buffers): Use proper closures.
+
+2021-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/info.el (Info-isearch-push-state): Use proper closures
+
+ * lisp/imenu.el (imenu--create-keymap): Use proper closures
+
+ * lisp/find-dired.el (find-dired): Use a proper closure
+
+ * lisp/facemenu.el (facemenu-add-new-face): Use `:documentation`
+
+2021-05-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/eshell/em-pred.el: Take advantage of lexical scoping
+
+ Also remove redundant `:group` arguments.
+
+ (eshell-parse-modifiers): Make sure we pass a function value.
+ (eshell-parse-arg-modifier, eshell-parse-modifiers)
+ (eshell-add-pred-func, eshell-pred-user-or-group)
+ (eshell-pred-file-time, eshell-pred-file-type, eshell-pred-file-mode)
+ (eshell-pred-file-links, eshell-pred-file-size)
+ (eshell-pred-substitute, eshell-include-members, eshell-join-members)
+ (eshell-split-members): Use proper closures.
+
+2021-05-18 Juri Linkov <juri@linkov.net>
+
+ * doc/emacs/basic.texi (Repeating): Document repeat-exit-timeout (bug#48472).
+
+2021-05-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/eieio-core.el (eieio-defclass-internal): Use a closure
+
+2021-05-18 Juri Linkov <juri@linkov.net>
+
+ * lisp/repeat.el (repeat-exit-timeout): New defcustom (bug#48472).
+
+ (repeat-exit-timer): New variable.
+ (repeat-post-hook): Run idle timer with an "exit function"
+ returned from set-transient-map.
+ Suggested by Gustavo Barros <gusbrs.2016@gmail.com>.
+
+ (repeat-echo-message): Remove own previous message when input arg is nil.
+
+ * lisp/window.el (display-buffer-override-next-command): Return exitfun.
+
+2021-05-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/calendar/cal-menu.el (cal-menu-holidays-menu): Use a proper closure
+
+2021-05-18 Juri Linkov <juri@linkov.net>
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-outline-level): Fix imprecise numbers.
+
+ (lisp-outline-level): Return right levels starting from 1 instead of 5.
+ Suggested by Howard Melman <hmelman@gmail.com> in bug#46878.
+
+2021-05-18 Juri Linkov <juri@linkov.net>
+
+ * lisp/simple.el (read-from-kill-ring): Add new arg PROMPT (bug#48478).
+
+ * lisp/simple.el (yank-pop, yank-from-kill-ring):
+ * lisp/isearch.el (isearch-yank-from-kill-ring):
+ Use arg PROMPT in the call read-from-kill-ring.
+
+2021-05-18 Philipp Stephani <phst@google.com>
+
+ Recreate symptom of Bug#42701.
+
+ The fix to Bug#48489 (commit 9676d41b8301b84e07717e633059a3f2b5c4c9d8)
+ has masked the symptom of Bug#42701 for 'if-let'. Create a helper
+ macro that still exemplifies the bug.
+
+ * test/lisp/emacs-lisp/edebug-tests.el
+ (edebug-tests--duplicate-symbol-backtrack): New helper macro.
+ (edebug-tests-duplicate-symbol-backtrack): Use it instead of 'if-let'.
+
+2021-05-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix some regressions introduced by the previous dired-aux change
+
+ * lisp/dired-aux.el (dired-compress-file): Check that the file
+ we're compressing exists. Also work outside the current directory.
+
+2021-05-18 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Look for ElDoc buffer in all visible frames
+
+ * lisp/emacs-lisp/eldoc.el (eldoc--echo-area-prefer-doc-buffer-p):
+ Look for a window displaying the ElDoc documentation buffer in all
+ visible frames, as promised by the user option
+ eldoc-echo-area-prefer-doc-buffer (bug#48278).
+
+2021-05-18 Miha Rihtaršič <miha@kamnitnik.top>
+
+ Fix problem with focusing in `C-o' in ibuffer in some circumstances
+
+ * lisp/ibuffer.el (ibuffer-visit-buffer-other-window-noselect):
+ Use display-buffer instead of pop-to-buffer and selecting the old
+ window. `pop-to-buffer' focuses the new frame, but
+ `select-window' usually fails to focus the original frame. This
+ simple patch fixes that (bug#48218).
+
+2021-05-18 Gong Qijian <gongqijian@gmail.com> (tiny change)
+
+ Fix `custom-delayed-init-variables' problem when re-dumping emacs
+
+ * lisp/startup.el (command-line): Don't bug out on redumping Emacs
+ (bug#48492).
+
+2021-05-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/kmacro.el: Fix test cases broken by last change
+
+ (kmacro-lambda-form): Remove unused args `counter` and `format`.
+ Arrange to be able to extract `mac` from the function.
+ (kmacro-extract-lambda): Use this new extraction instead of digging
+ into the guts of a function's code.
+
+2021-05-18 Alexandr Vityazev <avityazev@posteo.org> (tiny change)
+
+ Fix the length= shortdoc example
+
+ * lisp/emacs-lisp/shortdoc.el (list): Fix the length= example
+ (bug#48495).
+
+2021-05-18 Eli Zaretskii <eliz@gnu.org>
+
+ Revert "* lisp/bookmark.el: make bookmark-fontify nil default value"
+
+ This reverts commit ed8c3303f945fbd2c16ece0e87d041c75ae05ff9.
+
+2021-05-18 Mattias Engdegård <mattiase@acm.org>
+
+ Fix pcase 'rx' patterns with a single named submatch (bug#48477)
+
+ pcase 'rx' patterns with a single named submatch, like
+
+ (rx (let x "a"))
+
+ would always succeed because of an over-optimistic transformation.
+ Patterns with 0 or more than 1 named submatches were not affected.
+
+ Reported by Philipp Stephani.
+
+ * lisp/emacs-lisp/rx.el (rx--pcase-macroexpander):
+ Special case for a single named submatch.
+ * test/lisp/emacs-lisp/rx-tests.el (rx-pcase): Add tests.
+
+2021-05-18 Paul W. Rankin <pwr@bydasein.com>
+
+ * lisp/bookmark.el: make bookmark-fontify nil default value
+
+2021-05-18 Philipp Stephani <phst@google.com>
+
+ * lisp/emacs-lisp/subr-x.el (if-let): Swap &or branches (Bug#48489)
+
+2021-05-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/kmacro.el: Avoid the dynbound dialect of ELisp
+
+ (kmacro-call-macro, kmacro-lambda-form): Use proper closures.
+ (kmacro-keymap): Prefer #' top quote function names.
+
+2021-05-18 Dmitry Gutov <dgutov@yandex.ru>
+
+ Visually truncate excessively long lines in Xref
+
+ * lisp/progmodes/xref.el (xref-truncation-width): New option.
+ (xref--apply-truncation): New function.
+ (xref--insert-xrefs): Use it (bug#46859).
+
+2021-05-17 Eli Zaretskii <eliz@gnu.org>
+
+ Fix the etags test suite
+
+ * test/manual/etags/ETAGS.good_2:
+ * test/manual/etags/ETAGS.good_3:
+ * test/manual/etags/ETAGS.good_4:
+ * test/manual/etags/ETAGS.good_5:
+ * test/manual/etags/ETAGS.good_6:
+ * test/manual/etags/CTAGS.good: Adjust to addition test.rs.
+
+2021-05-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add an etags test for Rust (bug#46055)
+
+2021-05-17 Eli Zaretskii <eliz@gnu.org>
+
+ Update the etags/ctags test files
+
+ * test/manual/etags/ETAGS.good_1:
+ * test/manual/etags/ETAGS.good_2:
+ * test/manual/etags/ETAGS.good_3:
+ * test/manual/etags/ETAGS.good_4:
+ * test/manual/etags/ETAGS.good_5:
+ * test/manual/etags/ETAGS.good_6:
+ * test/manual/etags/CTAGS.good: Adjust to current codebase.
+
+2021-05-17 Sun Lin <sunlin7@yahoo.com>
+
+ Allow specifying the default archive types to compress to in Dired
+
+ * lisp/dired-aux.el (dired-compress-file-default-suffix):
+ (dired-compress-directory-default-suffix): New user options
+ (bug#47119).
+ (dired-compress-file-alist): New variable.
+
+ * lisp/dired-aux.el (dired-compress-file): Use them.
+ (dired-compress-file-suffixes): Remove the directory item.
+
+2021-05-17 Pierre-Antoine Rouby <contact@parouby.fr>
+
+ Add support for Rust in etags
+
+ * lib-src/etags.c (Rust_functions): New function to make tags for rust
+ files.
+ (Rust_help, Rust_suffixes): New constant.
+ * doc/emacs/maintaining.texi (Tag Syntax): Add Rust item.
+ * doc/man/etags.1: Add Rust (bug#46055).
+
+2021-05-17 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid crashes in condition-case
+
+ * src/eval.c (internal_lisp_condition_case): Don't take XCAR
+ without making sure the value is a cons cell. (Bug#48479)
+
+2021-05-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention *-nov-is-evil in the Extra Headers Gnus manual section
+
+ * doc/misc/gnus.texi (To From Newsgroups): Mention nov-is-evil.
+
+2021-05-17 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of new behavior of 'M-y'
+
+ * lisp/minibuffer.el (minibuffer-local-map): Switch the order of
+ '\r' and '\n' bindings.
+ * lisp/simple.el (yank-pop, read-from-kill-ring)
+ (yank-from-kill-ring): Doc fixes.
+
+ * doc/emacs/search.texi (Isearch Yank):
+ * doc/emacs/killing.texi (Yanking): Improve the description of the
+ new functionality of 'M-y'.
+ * doc/lispref/text.texi (Yank Commands): Remove inaccurate
+ description of 'M-y' in Isearch.
+
+ * etc/NEWS: Improve the wording of 'M-y' entry.
+
+2021-05-17 Philipp Stephani <phst@google.com>
+
+ Add a unit test to reproduce Bug#48471.
+
+ * test/lisp/progmodes/project-tests.el (project-tests--trivial)
+ (project-root, project-ignores): New test project type.
+ (project-ignores): New unit test.
+
+2021-05-17 Philipp Stephani <phst@google.com>
+
+ Fix a few Edebug specifications where code is wrapped in lambdas.
+
+ As the Info node `(elisp) Specification List' explains, it is not
+ correct to use `body' or t for a piece of code that the macro wraps in
+ a `lambda' form. These should use `def-body' instead.
+
+ * lisp/info-xref.el (info-xref-with-file):
+ * lisp/subr.el (subr--with-wrapper-hook-no-warnings, track-mouse)
+ (combine-change-calls, with-eval-after-load):
+ * lisp/emacs-lisp/bytecomp.el (displaying-byte-compile-warnings):
+ * lisp/emacs-lisp/cl-macs.el (cl-do-symbols, cl-progv):
+ * lisp/emacs-lisp/ert-x.el (ert-with-test-buffer):
+ * lisp/emacs-lisp/gv.el (gv-letplace):
+ * lisp/emacs-lisp/nadvice.el (define-advice):
+ * lisp/emacs-lisp/thunk.el (thunk-delay):
+ * lisp/vc/vc-dispatcher.el (vc-run-delayed): Use 'def-body' instead of
+ t or 'body' where applicable.
+
+ * lisp/emacs-lisp/package.el (package--with-response-buffer): Remove
+ evaluation of the body altogether. I have no idea how to write it
+ correctly in this case.
+
+2021-05-16 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Add a 'silent option for native-comp-async-report-warnings-errors
+
+ * lisp/emacs-lisp/comp.el (native-comp-async-report-warnings-errors):
+ Set to 'silent to log warnings, but not pop up the *Warnings* buffer.
+ * lisp/emacs-lisp/comp.el (comp-accept-and-process-async-output):
+ Check value.
+
+2021-05-16 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Use condition-case-unless-debug in nnselect-run
+
+ * lisp/gnus/nnselect.el (nnselect-run): This is confusing for users,
+ make it more yielding to common debugging strategies.
+
+2021-05-16 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Fix function signature for gnus-search-indexed-parse-output
+
+ * lisp/gnus/gnus-search.el (gnus-search-indexed-parse-output): Generic
+ function arg list didn't match the method arglist, which made for
+ confusing function help.
+
+2021-05-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ mouse-wheel-progressive-speed doc string clarification
+
+ * lisp/mwheel.el (mouse-wheel-progressive-speed): Doc string
+ improvement (bug#45322).
+
+2021-05-16 Ingo Lohmar <ingo.lohmar@posteo.net>
+
+ prepend newline in sqli buffer
+
+ (sql-remove-continuation-prompt, sql-send-string): Move newline
+ insertion.
+
+ Previously, the preoutput filter `sql-remove-continuation-prompt'
+ inserted a leading newline in the interactive SQL buffer if it decided
+ that is has to remove continuation prompts and that it had found all
+ it was looking for.
+
+ 1) This filter function was a doubtful place to do that (arguably, its
+ name does not suggest any action like this).
+ 2) The behavior worked inconsistently, eg, when sending a single-line
+ "SELECT" statement, because it only ran when the filter function
+ needed to remove any prompts (for example, not when sending a
+ region without newlines).
+
+ This can lead to misaligned table headers, which explains why
+ emacswiki and stackoverflow both present several fixes to this
+ behavior.
+
+2021-05-16 Tassilo Horn <tsdh@gnu.org>
+
+ Add bug-reference-mode-force-auto-setup
+
+ * lisp/progmodes/bug-reference.el
+ (bug-reference-try-setup-from-rmail): Match the Rmail mbox filename
+ against GROUP-REGEXP in bug-reference-setup-from-mail-alist.
+ (bug-reference-mode-force-auto-setup): New function which forces
+ auto-setup even if bug-reference-bug-regexp and
+ bug-reference-url-format are already set.
+
+2021-05-16 Dario Gjorgjevski <dario.gjorgjevski+git@gmail.com>
+
+ Add more completion tests
+
+ * test/lisp/minibuffer-tests.el (completion--pcm-score)
+ (completion--pcm-first-difference-pos): New helpers.
+ (completion-pcm-test-1, completion-pcm-test-2)
+ (completion-pcm-test-3, completion-pcm-test-4)
+ (completion-pcm-test-5, completion-pcm-test-6)
+ (completion-substring-test-1, completion-substring-test-2)
+ (completion-substring-test-3, completion-substring-test-4)
+ (completion-flex-test-1, completion-flex-test-2)
+ (completion-flex-test-3): New tests (bug#42149)
+
+2021-05-16 Sebastian Urban <mrsebastianurban@gmail.com> (tiny change)
+
+ Improve some quotation quoting in the Emacs manual
+
+ * doc/emacs/text.texi (Quotation Marks, Quotation Marks):
+ * doc/emacs/display.texi (Text Display): Fix some issues when
+ quoting quote marks and the like (bug#35885).
+
+ * doc/emacs/emacs.texi: Switch on double-sided printing headings.
+
+2021-05-16 Noam Postavsky <npostavs@gmail.com>
+
+ Remove unreliable test for match data clobbering
+
+ * src/search.c (Freplace_match): Don't test for change in search_regs
+ start and end, this is unreliable if change hooks modify text earlier
+ in the buffer (bug#35264).
+
+2021-05-16 Philipp Stephani <phst@google.com>
+
+ Optimize calls to 'eql', 'memql' and similar for fixnums.
+
+ It's good practice to compare integers using 'eql' because two bignum
+ objects representing the same integer might not be 'eq'. However,
+ 'eql' is slower and doesn't have its own byte code. Therefore,
+ replace it with 'eq' if one argument is guaranteed to be a fixnum on
+ all platforms.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize--fixnump): New helper
+ function.
+ (byte-optimize-equal, byte-optimize-member, byte-optimize-assoc): Use
+ it to optimize 'eql' etc. to 'eq' if it will always compare fixnums.
+
+2021-05-16 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix handling of stderr buffer in Tramp's make-process (Bug#47861)
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process):
+ Reimplement stderr buffer handling. (Bug#47861)
+ (tramp-maybe-open-connection): Improve traces.
+
+ * test/lisp/net/tramp-tests.el (tramp-test30-make-process):
+ Rework for stderr buffer.
+
+2021-05-16 Tassilo Horn <tsdh@gnu.org>
+
+ Bug reference auto-setup for Rmail
+
+ * lisp/progmodes/bug-reference.el
+ (bug-reference-try-setup-from-rmail): New function setting up
+ `bug-reference-mode' from the current Rmail message.
+
+2021-05-15 Dmitry Gutov <dgutov@yandex.ru>
+
+ Update CSS completion tests
+
+ * test/lisp/textmodes/css-mode-tests.el (css-test-complete-pseudo-class)
+ (css-test-complete-pseudo-element): Update the tests for recent changes.
+
+2021-05-15 Tassilo Horn <tsdh@gnu.org>
+
+ Refactor bug-reference setup functions into a defvar
+
+ * lisp/progmodes/bug-reference.el
+ (bug-reference-auto-setup-functions): New defvar so that other
+ packages can add their own auto-setup functions to it.
+ * lisp/progmodes/bug-reference.el (bug-reference--run-auto-setup): Use
+ the new variable instead of hard-coding the 4 functions we've had
+ already.
+
+2021-05-15 Eli Zaretskii <eliz@gnu.org>
+
+ Fix segfaults when byte-compiling with native-compilation
+
+ * src/emacs.c (main): Call 'set_initial_minibuffer_mode' before
+ entering recursive-exit.
+ * src/minibuf.c (init_minibuf_once_for_pdumper): Don't call
+ 'set_minibuffer_mode' here...
+ (set_initial_minibuffer_mode): ... set it in this new function.
+ (Bug#48446)
+ * src/lisp.h: Add prototype for 'set_initial_minibuffer_mode'.
+
+2021-05-15 Alan Mackenzie <acm@muc.de>
+
+ Miscellaneous corrections to src/minibuf.c for bug #48337
+
+ * src/minibuf.c (read_minibuf): Call get_minibuffer before incrementing
+ minibuf_level, in case a hook function calls Factive_minibuffer_window.
+ (init_minibuf_once_for_pdumper): Create *Minibuf-0* here (moved from
+ init_minibuf_once), and set its mode, so that clicking in the mini-window
+ immediately after start up works (thanks, Eli Z.).
+
+2021-05-15 Eli Zaretskii <eliz@gnu.org>
+
+ Fix launching net-utils on MS-Windows
+
+ * lisp/net/net-utils.el (net-utils-run-simple): Bind
+ coding-system-for-read around the code which starts the process.
+ (Bug#48375)
+
+2021-05-15 pillule <pillule@riseup.net> (tiny change)
+
+ Fix `quit-restore-window' when all previous buffers got killed (Bug#48367)
+
+ * lisp/window.el (quit-restore-window): Simplify calculation of
+ WINDOW's previous buffer. Avoid that killing WINDOW's previous
+ buffers results in a state where `quit-window' has no more
+ effect, by simply deleting WINDOW in that case (Bug#48367).
+
+2021-05-15 Daniel Semyonov <cmstr@dsemy.com> (tiny change)
+
+ Mairix: use 'mairix-search-options' as documented
+
+ * lisp/net/mairix.el (mairix-call-mairix): Append
+ 'mairix-search-options' to the arguments passed to mairix.
+
+2021-05-15 Daniel Semyonov <cmstr@dsemy.com> (tiny change)
+
+ Mairix: autoload main interactive functions
+
+ * lisp/net/mairix.el (mairix-search, mairix-use-saved-search)
+ (mairix-edit-saved-searches-customize, mairix-search-from-this-article)
+ (mairix-search-thread-this-article, mairix-widget-search-based-on-article)
+ (mairix-edit-saved-searches, mairix-widget-search, mairix-update-database):
+ Add magic autoload comment.
+
+2021-05-15 Eli Zaretskii <eliz@gnu.org>
+
+ Improve doc string of 'log-edit-generate-changelog-from-diff'
+
+ * lisp/vc/log-edit.el (log-edit-generate-changelog-from-diff):
+ Improve the doc string. (Bug#48269)
+
+2021-05-15 Martin Rudalics <rudalics@gmx.at>
+
+ Have X builds handle VisibilityNotify events (Bug#48268, Bug#48413)
+
+ * src/xterm.c (handle_one_xevent): Handle VisibilityNotify
+ events (Bug#48268, Bug#48413).
+
+2021-05-15 Dmitry Gutov <dgutov@yandex.ru>
+
+ Add :company-kind support to nxml-mode completion
+
+ * lisp/nxml/rng-nxml.el (rng-complete-tag)
+ (rng-complete-attribute-name, rng-complete-attribute-value):
+ Support :company-kind.
+
+2021-05-15 Dmitry Gutov <dgutov@yandex.ru>
+
+ Add :company-kind support to sh-mode completion
+
+ * lisp/progmodes/sh-script.el (sh--completion-keywords):
+ New variable.
+ (sh--cmd-completion-table): Extracted from here.
+ (sh-completion-at-point-function): Add :company-kind.
+
+2021-05-15 Dmitry Gutov <dgutov@yandex.ru>
+
+ Include colons in the completion strings
+
+ * lisp/textmodes/css-mode.el
+ (css--complete-pseudo-element-or-class):
+ Include colons in the completion strings. That's simply the nicer
+ behavior (e.g. someone typing : will see pseudo-elements in
+ completions as well), and by the standards, the colons are part of
+ their names anyway (of pseudo-elements and classes).
+
+2021-05-15 Dmitry Gutov <dgutov@yandex.ru>
+
+ Add :company-kind support to css-mode completion
+
+ * lisp/textmodes/css-mode.el (css--complete-pseudo-element-or-class)
+ (css--complete-property-value, css-completion-at-point)
+ (css--complete-at-rule): Add :company-kind properties, to annotate
+ completions with kinds returned in each case.
+
+2021-05-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the M-x obsoletion check more robust
+
+ * lisp/simple.el (read-extended-command): Make the obsoletion
+ check more robust.
+
+2021-05-14 Alan Mackenzie <acm@muc.de>
+
+ Various detailed fixes to minibuf.c, etc., to fix bug #48337
+
+ Also fix some unsafe coding.
+
+ * lisp/window.el (push-window-buffer-onto-prev): New function, extracted from
+ (record-window-buffer): Refactor by extracting the above, and removing the now
+ redundant parameter DO-MINIBUF.
+
+ * src/minibuf.c (zip_minibuffer_stacks, read_minibuf): Replace calls to
+ get_minibuffer (0) by nth_minibuffer (0). Replace calls to
+ Qrecord_window_buffer by calls to Qpush_window_buffer_onto_prev.
+ (Factive_minibuffer_window, read_minibuf_unwind): Call abort_emacs should an
+ "impossible" null value be returned by nth_minibuffer.
+ (read_minibuf): Move the get_minibuffer_call to just after the incrementation
+ of minibuf_level as a precaution against a missing buffer in
+ Vminibuffer_list.
+ (nth_minibuffer): Replace XCAR by Fcar, to allow (car nil) to work.
+ (init_minibuf_once): Create the inactive buffer *Minibuf-0*.
+ (syms_of_minibuf): New DEFSYM, Qpush_window_buffer_onto_prev.
+
+ * src/window.c (restore_window_configuration): Replace some XCARs and XCDRs
+ by Fcar_safe and Fcdr_safe.
+
+2021-05-13 Glenn Morris <rgm@gnu.org>
+
+ * doc/misc/calc.texi: Remove most hand-written node pointers.
+
+ The complex, conditional node layout makes this one of the very
+ few cases that can't be done entirely automatically.
+
+2021-05-13 Glenn Morris <rgm@gnu.org>
+
+ Remove more hand-written node pointers in doc/misc
+
+ * doc/misc/ede.texi, doc/misc/mh-e.texi, doc/misc/reftex.texi:
+ * doc/misc/todo-mode.texi: Remove hand-written node pointers.
+
+2021-05-13 Glenn Morris <rgm@gnu.org>
+
+ * doc/misc/epa.texi: Remove hand-written node pointers.
+
+2021-05-13 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ bcd92b5708 (origin/emacs-27) Improve documentation of Hexl mode
+ c233f4eccd ; * etc/NEWS: Fix decoded-time-set-defaults typo.
+ 4c3abb3dd1 Fix compilation errors with latest w32 API headers
+ 127f1f330b Improve doc strings in log-edit.el
+ e36183ff46 ; * etc/TODO (etc/DOC): Update the todo entries.
+
+ # Conflicts:
+ # etc/NEWS
+
+2021-05-13 Glenn Morris <rgm@gnu.org>
+
+ * doc/misc/epa.texi: Fix @nodes in previous change.
+
+2021-05-13 Michael Albinus <michael.albinus@gmx.de>
+
+ Improve Tramp traces
+
+ * lisp/net/tramp-cmds.el (tramp-list-tramp-buffers):
+ List also trace buffers.
+
+ * lisp/net/tramp.el (tramp-buffer-name):
+ Add `tramp-suppress-trace' property.
+ (tramp-get-debug-file-name): Fix docstring.
+ (tramp-trace-buffer-name): New defun.
+ (tramp-trace-functions): New defvar.
+ (tramp-debug-message): Obey also `tramp-trace-functions'.
+
+ * test/lisp/net/tramp-tests.el (tramp--test-instrument-test-case):
+ Handle trace buffer accordingly.
+
+2021-05-13 dickmao <none>
+
+ Process sentinels need to work under X and commandline
+
+ * src/process.c (add_non_keyboard_read_fd): Make this a public function.
+ (add_process_read_fd): Fold old, static add_non_keyboard_read_fd guts
+ into here.
+ * src/xsmfns.c (ice_conn_watch_CB): Call add_non_keyboard_read_fd
+ (bug#43834).
+
+2021-05-13 Eli Zaretskii <eliz@gnu.org>
+
+ Fix vertical cursor motion across tall text or small images
+
+ 'line-move-partial' should in general leave it to the display
+ engine to scroll or recenter the window due to vertical motion of
+ the cursor. The only purpose of this function is to produce
+ vscroll suitable for scrolling across large (relatively to the
+ window's height) images, where moving by display lines is not
+ appropriate.
+
+ * src/xdisp.c (Fdisplay__line_is_continued_p): New primitive.
+
+ * lisp/simple.el (line-move-partial): Call
+ 'display--line-is-continued-p' to decide whether to leave it to
+ redisplay to scroll the window as appropriate. (Bug#48170)
+
+2021-05-13 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix bug#48349 in file-name-non-special
+
+ * lisp/files.el (file-name-non-special): Use Tramp file name
+ handler only in case of `copy-file', 'rename-file' and
+ `copy-directory'. (Bug#48349)
+
+2021-05-13 Stefan Kangas <stefan@marxist.se>
+
+ Document `package-quickstart' in the user manual
+
+ * doc/emacs/package.texi (Package Installation): Document
+ `package-quickstart' (bug#44748).
+
+2021-05-13 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ Make searching for files faster under Windows
+
+ * src/lread.c (openp): Use faccessat to check that a file exists
+ before opening it on Windows (bug#41646). This speeds up
+ searching for files.
+
+2021-05-13 Stefan Kangas <stefan@marxist.se>
+
+ Don't consider obsolete commands for completion in some cases
+
+ * lisp/simple.el (read-extended-command): Exclude obsolete commands
+ that are either lacking a 'current-name' or were obsoleted in a
+ previous major version (bug#43300).
+
+ (There's been some back and forth here. Obsolete commands used to be
+ treated normally for completion, and then they were removed. Then
+ they were put back again, but annotated with what they were
+ obsoleting. There was some pushback on this change, so this latest
+ changes is a compromise between the last two states.)
+
+2021-05-13 Radon Rosborough <radon.neon@gmail.com>
+
+ Use an explicit line width of 1 on hollow cursors under X
+
+ * src/xterm.c (x_draw_hollow_cursor): Specify a line width of
+ 1 explicitly to avoid problems on some X implementations (bug#42452).
+
+2021-05-13 Eli Zaretskii <eliz@gnu.org>
+
+ * src/image.c (xpm_image_p): Avoid another compiler warning.
+
+ * src/image.c: Avoid compiler warnings in Cairo builds without XPM.
+
+2021-05-12 Tom Gillespie <tgbugs@gmail.com>
+
+ Fix evaluation order for hack-local-variables
+
+ * lisp/files.el (hack-local-variables): Fix the ordering which
+ local variables are evaluated by `hack-local-variables' so that
+ prop-line local variables are evaluated first. There is a hidden
+ nreverse lurking in `hack-local-variables-apply' which means that
+ the prop line variables must come second in order to be evaluated
+ before the end of file variables.
+
+2021-05-12 Philip K <philipk@posteo.net>
+
+ Don't mark interactive commands as internal functions
+
+ * lisp/epa-ks.el (epa-ks-search-mode-map): Rename commands from
+ "--" to "-" throughout.
+
+2021-05-12 Eli Zaretskii <eliz@gnu.org>
+
+ Improve doc strings and prompt in epa-ks.el
+
+ * lisp/epa-ks.el (epa-ks--mark-key-to-fetch, epa-ks--fetch-key)
+ (epa-search-keys): Doc fixes.
+ (epa-ks-do-key-to-fetch): Better wording for the fetch prompt.
+
+2021-05-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Even further `text-property-search-forward' clarifications
+
+ * lisp/emacs-lisp/text-property-search.el
+ (text-property-search-forward): Further doc string clarifications.
+
+2021-05-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Update email address in epa-ks.el
+
+2021-05-12 Philip K <philipk@posteo.net>
+
+ All a GPG key server client
+
+ * lisp/epa-ks.el (epa-keyserver): New file (bug#39886).
+ * doc/misc/epa.texi (Quick start): Mention it.
+ (Querying a key server): Document it.
+
+2021-05-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix `uniquify-managed' unbounded growth
+
+ * lisp/uniquify.el (uniquify-rationalize-file-buffer-names):
+ Protect against exponential `uniquify-managed' growth when
+ reverting several (more than two) buffers that have the same file
+ name (bug#36877).
+
+2021-05-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further corrections for the text-property-search doc strings
+
+ * lisp/emacs-lisp/text-property-search.el
+ (text-property-search-forward): Correct doc string.
+ (text-property-search-backward): Ditto.
+
+2021-05-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak indentation of #foo in js-mode
+
+ * lisp/progmodes/js.el (js--proper-indentation): Indent #define
+ (etc) to column 0, but otherwise indent #foo normally (bug#47488).
+
+2021-05-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove unused variable in rmail.el
+
+ * lisp/mail/rmail.el (rmail-reply): Remove unused lexical variable
+ introduced in previous patch.
+
+2021-05-12 Eli Zaretskii <eliz@gnu.org>
+
+ Fix the tests for 'string-limit'
+
+ * test/lisp/emacs-lisp/subr-x-tests.el (subr-string-limit-coding):
+ Fix the expected results of string-limit when encoding with
+ UTF-16. Add tests for UTF-8 with BOM. (Bug#48324)
+
+ * lisp/emacs-lisp/subr-x.el (string-limit): Add FIXME comment
+ about the current implementation, which is faulty by design.
+
+2021-05-12 Jim Porter <jporterbugs@gmail.com>
+
+ Abbreviate rgrep command on MS Windows (bug#48302)
+
+ * lisp/progmodes/grep.el (grep-mode-font-lock-keywords):
+ Adapt regexp to match MS Windows-style shell-quoting.
+
+ * test/lisp/progmodes/grep-tests.el: New file.
+
+2021-05-12 Martin Rudalics <rudalics@gmx.at>
+
+ Handle Bug#24526 without breaking Emacs on tiling WMs (Bug#48268)
+
+ Since tiling window managers may react allergically to resize
+ requests immediately following MapNotify events on X, make sure
+ that such requests are issued only when a new frame should not
+ become visible and a size has been explicitly requested for it.
+
+ * lisp/faces.el (x-create-frame-with-faces): Mark frame as
+ 'was-invisible' if it should be initially invisible or iconified
+ and has its size specified explicitly.
+ * src/frame.c (make_frame): Initialize new frame's was_invisible
+ flag.
+ (Fframe__set_was_invisible): New internal function.
+ * src/frame.h (struct frame): Specify size of new_size_p slot.
+ New flag was_invisible.
+ * src/w32fns.c (Fx_create_frame)
+ * src/nsfns.m (Fx_create_frame)
+ * src/xfns.c (Fx_create_frame): Set new frame's was_invisible
+ flag.
+ * src/xterm.c (handle_one_xevent): Call xg_frame_set_char_size
+ after a PropertyNotify or MapNotify event only if F's
+ was_invisible flag was set.
+
+2021-05-12 Richard Stallman <rms@gnu.org>
+
+ Avoid querying in a noninteractive Emacs.
+
+ * lisp/mail/sendmail.el (mail-send): In noninteractive Emacs,
+ don't ask about combining header fields.
+
+2021-05-12 Richard Stallman <rms@gnu.org>
+
+ Handle empty string as mail-header-separator
+
+ * lisp/mail/sendmail.el (mail-mode):
+ (mail-sendmail-undelimit-header): Handle mail-header-separator empty.
+ (mail-send): Search for mail-header-separator as entire contents of line.
+
+2021-05-12 Richard Stallman <rms@gnu.org>
+
+ Handle multi-line FROM.
+
+ * lisp/mail/rmailsum.el (rmail-header-summary): Handle multi-line FROM.
+
+2021-05-12 Richard Stallman <rms@gnu.org>
+
+ Little improvements in rmail.el. Recognize encryped override headers.
+
+ * lisp/mail/rmail.el (rmail-simplified-subject): Delete `[External] :'.
+ (rmail-reply): In encrypted message, search for other header fields
+ inside the encrypted part, and use them instead of the real header.
+ (rmail-epa-decrypt): Don't set MIME unless it's Rmail mode.
+
+2021-05-12 Richard Stallman <rms@gnu.org>
+
+ Use rfc822-goto-eoh rather that mail-header-separator.
+
+ * lisp/epa-mail.el (epa-mail-sign)
+ (epa-mail-default-recipients, epa-mail-encrypt):
+ Use rfc822-goto-eoh, not mail-header-separator.
+ (epa-mail-default-recipients): Assume epa-mail-aliases
+ elements are lower case, search case-independently.
+
+2021-05-11 Eli Zaretskii <eliz@gnu.org>
+
+ Move the Text Properties menu back to Edit
+
+ * lisp/textmodes/enriched.el (enriched-mode): Don't add "Text
+ Properties" sub-menu to Text mode menu.
+ * lisp/facemenu.el (menu-bar-edit-menu): Add "Text Properties"
+ sub-menu back to the Edit menu.
+
+2021-05-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove purecopy throughout facemenu.el (since it's not preloaded)
+
+2021-05-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move facemenu to enriched mode
+
+ * lisp/menu-bar.el (menu-bar-edit-menu): Move from here...
+
+ * lisp/textmodes/enriched.el (enriched-mode): ... to here.
+
+2021-05-11 Tassilo Horn <tsdh@gnu.org>
+
+ Fix dired confirm message asking to kill buffers of deleted dir (bug#48301)
+
+ * lisp/dired.el (dired-clean-up-after-deletion): Fix dired
+ confirmation message asking to kill buffers of deleted dir in the case
+ where `dired-listing-switches' contain -p (bug#48301).
+
+2021-05-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/font-lock.el: Fix `font-lock-comment-end-skip` fallback (bug#34088)
+
+ (font-lock-fontify-syntactically-region): Use `comment-end-skip` as
+ fallback for `font-lock-comment-end-skip`, as is done for
+ `font-lock-comment-start-skip` (and as the name suggests).
+
+ * lisp/progmodes/opascal.el (opascal-mode): Revert last change,
+ made unnecessary.
+
+2021-05-11 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of Hexl mode
+
+ * doc/emacs/misc.texi (Editing Binary Files): Explain that Hexl can
+ also be used for editing text, including non-ASCII text.
+
+2021-05-11 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-deferred-compilation
+
+ * lisp/progmodes/elisp-mode.el
+ (emacs-lisp-native-compile-and-load): Rename
+ comp-deferred-compilation -> native-comp-deferred-compilation.
+ * src/comp.c (maybe_defer_native_compilation, syms_of_comp):
+ Likewise.
+
+2021-05-11 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-deferred-compilation-deny-list
+
+ * lisp/emacs-lisp/comp.el (native-comp-deferred-compilation-deny-list)
+ (native-compile-async-skip-p): Rename
+ comp-deferred-compilation-deny-list ->
+ native-comp-deferred-compilation-deny-list.
+
+2021-05-11 Eli Zaretskii <eliz@gnu.org>
+
+ Mention native compilation in the user manual
+
+ * doc/emacs/building.texi (Lisp Libraries): Mention native
+ compilation.
+
+2021-05-11 Stefan Kangas <stefankangas@gmail.com>
+
+ Fix exiting Emacs when savehist-file not writable
+
+ * lisp/savehist.el (savehist-save): Show warning when 'savehist-file'
+ is not writable. (Bug#34093)
+ (savehist--has-given-file-warning): New variable.
+
+2021-05-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix comment end delimiter fontification in OPascal mode
+
+ * lisp/progmodes/opascal.el (opascal-mode): Fontify the ending
+ brace with `font-lock-comment-delimiter-face' correctly (bug#34088).
+
+2021-05-11 Eli Zaretskii <eliz@gnu.org>
+
+ Fix assertions in nth_minibuffer
+
+ * src/minibuf.c (nth_minibuffer): Avoid assertion violation when
+ DEPTHth minibuffer doesn't exist. (Bug#48337)
+
+2021-05-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ `text-property-search-forward' doc string improvement
+
+ * lisp/emacs-lisp/text-property-search.el
+ (text-property-search-forward): Correct and clarify the doc string
+ (bug#48317).
+
+2021-05-11 Eli Zaretskii <eliz@gnu.org>
+
+ Fix Hexl handling of coding-systems with BOM
+
+ * lisp/international/mule-cmds.el (encode-coding-char): If
+ CODING-SYSTEM produces BOM, remove the BOM bytes from the produced
+ byte sequence. (Bug#48324)
+
+ * lisp/hexl.el (hexl-mode): Use bufferpos-to-filepos to convert
+ point to offset into the original file.
+ (hexl-mode-exit, hexl-maybe-dehexlify-buffer): Use
+ filepos-to-bufferpos to restore point in the original buffer.
+ (hexl-mode, hexl-insert-multibyte-char)
+ (hexl-self-insert-command, hexl-insert-hex-char)
+ (hexl-insert-decimal-char, hexl-insert-octal-char)
+ (hexl-find-file): Enhance the doc strings, mainly explaining the
+ complications of inserting multibyte characters.
+ (hexl-insert-multibyte-char): Don't treat CH as unibyte if the
+ coding-system isn't ASCII-compatible. Don't treat null bytes as
+ multibyte.
+
+2021-05-11 Glenn Morris <rgm@gnu.org>
+
+ * doc/misc/erc.texi (Connecting): Fix cross reference.
+
+2021-05-11 Amin Bandali <bandali@gnu.org>
+
+ Tweak documentation relating to 'erc-tls'
+
+ * doc/misc/erc.texi (Connecting): Add a reference to the auth manual.
+ * etc/NEWS: Remove the verbose, detailed example of client certificate
+ specification and refer to the ERC manual instead.
+ * lisp/erc/erc.el (erc-tls): Fix leftover path example in docstring.
+
+2021-05-10 Glenn Morris <rgm@gnu.org>
+
+ * lib/Makefile.in (maintainer-clean): Fully ignore rmdir errors.
+
+2021-05-10 Glenn Morris <rgm@gnu.org>
+
+ * Makefile.in: Simplify maintainer-clean.
+
+ (maintainer_clean_dirs): Remove.
+ (maintainer-clean): Don't duplicate clean by running bootstrap-clean,
+ which can lead to issues with parallel clean.
+
+2021-05-10 Glenn Morris <rgm@gnu.org>
+
+ * test/src/emacs-module-tests.el (mod-test-file): Unbreak out-of-tree.
+
+ * test/Makefile.in (clean): Remove generated mml-sec file.
+
+2021-05-10 Glenn Morris <rgm@gnu.org>
+
+ Always include the test/ directory in tarfiles
+
+ In hindsight, it's hard to see why not including it was ever an option.
+ * make-dist: Always include the test/ directory.
+ (with_tests): Remove.
+ (--tests, --no-tests): Make these options no-ops.
+ * Makefile.in (mostlyclean_dirs, maintainer_clean_dirs): Add "test".
+ (mostlyclean, clean, distclean, maintainer-clean):
+ Remove special-casing for "test".
+ ($(CHECK_TARGETS)): Simplify.
+
+2021-05-10 Michael Albinus <michael.albinus@gmx.de>
+
+ Extend meaning of UNIQUIFY `auto-save-file-name-transforms'. (Bug#47493)
+
+ * doc/lispref/backups.texi (Auto-Saving): Explain UNIQUIFY being a
+ secure hash in auto-save-file-name-transforms.
+
+ * etc/NEWS: Mention change in `auto-save-file-name-transforms'.
+
+ * lisp/files.el (auto-save-file-name-transforms): Adapt docstring.
+ (make-auto-save-file-name): Care, if UNIQ is a secure hash symbol.
+
+2021-05-10 Mauro Aranda <maurooaranda@gmail.com>
+
+ Avoid saving session customizations in the custom-file
+
+ * lisp/custom.el (custom-theme-recalc-variable): Only stash theme
+ settings for void variables.
+ (custom-declare-variable): After initializing a variable, unstash a
+ theme setting, if present.
+ (disable-theme): When disabling a theme, maybe unstash a theme
+ setting.
+
+ * test/lisp/custom-resources/custom--test-theme.el: Add two settings
+ for testing the fix.
+
+2021-05-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Always heed the `lexical-binding' local variable
+
+ * doc/lispref/variables.texi (File Local Variables): Document
+ `permanently-enabled-local-variables'.
+
+ * lisp/files.el (enable-local-variables): Mention the new variable.
+ (set-auto-mode): Always call `hack-local-variables'.
+ (hack-local-variables): Factor out the variable gathering into its
+ own function, and respect the new variable (bug#47843).
+ (hack-local-variables--find-variables): Factored out from
+ `hack-local-variables'.
+ (permanently-enabled-local-variables): New variable.
+
+2021-05-10 Glenn Morris <rgm@gnu.org>
+
+ * lib-src/Makefile.in (clean): Tidy up seccomp-filter files.
+
+ * test/Makefile.in (SUBDIRS, subdir_template): Fix out-of-tree.
+
+2021-05-10 Glenn Morris <rgm@gnu.org>
+
+ Small fixes for out-of-tree clean rules.
+
+ * Makefile.in (top_maintainer_clean, extraclean): Fix out-of-tree.
+
+2021-05-10 Glenn Morris <rgm@gnu.org>
+
+ Small fixes for Makefile clean rules
+
+ * Makefile.in (maintainer-clean): Move some items from extraclean.
+ (extraclean): doc/emacs already deletes emacsver.texi.
+
+2021-05-10 Glenn Morris <rgm@gnu.org>
+
+ Base the "extraclean" Make rule on "maintainer-clean"
+
+ * Makefile.in (FIND_DELETE): New, set by configure.
+ (extraclean_dirs): Remove.
+ (extraclean): Make it just a small variation on maintainer-clean.
+ * admin/charsets/Makefile.in (extraclean):
+ * admin/grammars/Makefile.in (extraclean):
+ * admin/unidata/Makefile.in (extraclean):
+ * leim/Makefile.in (extraclean):
+ * lib-src/Makefile.in (extraclean):
+ * lisp/Makefile.in (extraclean):
+ * lwlib/Makefile.in (extraclean):
+ * nt/Makefile.in (extraclean):
+ * src/Makefile.in (extraclean): Remove target.
+ * lib/Makefile.in (extraclean): Merge into maintainer-clean.
+
+2021-05-09 Juri Linkov <juri@linkov.net>
+
+ * lisp/misearch.el (multi-isearch-switch-buffer): New function.
+
+ * lisp/isearch.el (isearch-search-string):
+ * lisp/misearch.el (multi-isearch-wrap, multi-isearch-pop-state): Use it.
+
+ https://lists.gnu.org/archive/html/emacs-devel/2021-05/msg00309.html
+
+2021-05-09 Michael Albinus <michael.albinus@gmx.de>
+
+ Cleanups for Tramp out-of-band methods on MS Windows
+
+ * doc/misc/tramp.texi (Frequently Asked Questions):
+ tramp-use-ssh-controlmaster-options is nil on MS Windows.
+
+ * lisp/net/tramp.el (tramp-unquote-shell-quote-argument): Revert previous
+ change, it worked (not as expected but) properly.
+
+ * test/lisp/net/tramp-tests.el (tramp-test17-dired-with-wildcards):
+ Don't skip on MS Windows.
+ (tramp--test-windows-nt-and-scp-p): Remove.
+ (tramp--test-special-characters): Skip for out-of-band methods on
+ MS Windows, sometimes.
+
+2021-05-09 Andreas Schwab <schwab@linux-m68k.org>
+
+ Make autoloads-force work in build directory
+
+ * lisp/Makefile.in (autoloads-force): Remove $(lisp)/loaddefs.el,
+ not loaddefs.el.
+
+2021-05-09 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Default to 1970 in decoded-time-set-defaults
+
+ * lisp/calendar/time-date.el (decoded-time-set-defaults): Set an
+ unspecified year field to 1970, as promised in the docstring, and to
+ ensure it's representable on all systems (bug#48298).
+
+2021-05-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Reintroduce autoloads for edebug-all-defs/edebug-all-forms
+
+ * lisp/emacs-lisp/edebug.el (edebug-all-defs, edebug-all-forms):
+ Reintroduce ;;;###autoload of these user options that were removed
+ in bae2cfe63c, because this leads to errors in a common (and
+ recommended) use case (bug#47516).
+
+2021-05-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix indentation of lines starting with # in js-mode
+
+ * lisp/progmodes/js.el (js--proper-indentation): # is not like in
+ C -- it doesn't have to appear on the beginning of the line
+ (bug#47488).
+
+2021-05-09 Eli Zaretskii <eliz@gnu.org>
+
+ Fix compilation errors with latest w32 API headers
+
+ * src/w32common.h: Rename OS_* to OS_SUBTYPE__*, as w32 API
+ headers started defining OS_NT, which breaks the use of the
+ enumeration. All users changed. (Bug#48303)
+
+2021-05-08 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Tiny fixes to recent native compilation docs
+
+ For discussion, see the following thread:
+ https://lists.gnu.org/r/emacs-devel/2021-05/msg00347.html
+
+ * doc/lispref/compile.texi (Native Compilation): Fix grammar in @ref
+ online label.
+ (Native-Compilation Functions): Consistently unhyphenate
+ 'sub-process'. Fix grammar.
+ (Native-Compilation Variables): Fix @cindex entry.
+
+2021-05-08 Eli Zaretskii <eliz@gnu.org>
+
+ Document native-compilation
+
+ * doc/lispref/loading.texi (How Programs Do Loading)
+ (Library Search): Update for native-compilation features.
+ * doc/lispref/compile.texi (Native Compilation)
+ (Native-Compilation Functions, Native-Compilation Variables): New
+ chapter and sections.
+ * doc/lispref/elisp.texi (Top): Update the top-level menus.
+
+ * etc/NEWS: Add a reference to the ELisp manual.
+
+2021-05-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't delete socket on server exit if it was passed in
+
+ * lisp/server.el (server-sentinel): Don't delete the socket if it
+ was passed in to Emacs (bug#47511).
+
+2021-05-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove dead URL in isearchb.el comments
+
+ * lisp/isearchb.el: Remove dead URL in comments (bug#47514).
+
+2021-05-08 Alan Mackenzie <acm@muc.de>
+
+ Prevent the selected window being a dead mini-window when switching frames
+
+ This fixes bug #48249 and also a situation where, with recursive minibuffers
+ enabled and minibuffer-follows-selected-frame t, switching frames when a
+ minibuffer was open would leave the mini-window selected on the old frame.
+
+ * lisp/window.el (record-window-buffer): Add extra parameter DO-MINIBUF, and
+ amend the code such that minibuffers only get processed when that parameter is
+ non-nil.
+
+ * src/minibuf.c (zip_minibuffer_stacks, read_minibuf): Call
+ Qrecord_window_buffer with the new argument set to Qt.
+ (move_minibuffers_onto_frame): Set the selected window on the old frame when
+ this would otherwise remain the mini-window.
+
+2021-05-08 dalanicolai <dalanicolai@gmail.com> (tiny change)
+
+ Mention that Emacs is usually case-insensitive in a couple of places
+
+ * doc/lispref/searching.texi (Regular Expressions): Mention
+ `case-fold-search'.
+
+ * lisp/emacs-lisp/re-builder.el (re-builder): Mention case
+ sensitivity toggles (bug#47534).
+
+2021-05-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Fix moving directories with the same name to trash"
+
+ This reverts commit f618cc5bc83d3822759c5bb85d15320651ca2431.
+
+ This patch doesn't cover some corner cases, I think.
+
+2021-05-08 Codruț Constantin Gușoi <mail@codrut.pro> (tiny change)
+
+ Fix moving directories with the same name to trash
+
+ * lisp/files.el (move-file-to-trash): Allow moving several
+ directories with the same name to Trash (bug#48280).
+
+2021-05-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/nnoo.el (defvoo, deffoo): Add `doc-string` property
+
+2021-05-08 Jim Porter <jporterbugs@gmail.com>
+
+ Ensure `<menu-bar> <edit> <clear>' handles rectangular regions
+
+ * lisp/delsel.el (delete-active-region): Autoload it and make it interactive.
+ * lisp/menu-bar.el (menu-bar-edit-menu): Bind "Clear" to
+ `delete-active-region'.
+
+2021-05-07 Philipp Stephani <phst@google.com>
+
+ Don't use symbolic links in the test resource directory.
+
+ This doesn't work on Windows. Instead, use the EMACS_TEST_DIRECTORY
+ environment variable to find the BPF files.
+
+ * test/src/emacs-tests.el (emacs-tests--lib-src): New constant.
+ (emacs-tests/seccomp/allows-stdout)
+ (emacs-tests/seccomp/forbids-subprocess)
+ (emacs-tests/bwrap/allows-stdout): Use it.
+
+2021-05-07 Michael Albinus <michael.albinus@gmx.de>
+
+ Tramp: Fix file name quoting on MS Windows
+
+ * lisp/net/tramp-sh.el (tramp-make-copy-program-file-name):
+ Use `tramp-unquote-shell-quote-argument'.
+
+ * lisp/net/tramp.el (tramp-unquote-shell-quote-argument):
+ Adapt for MS Windows.
+
+ * test/lisp/net/tramp-tests.el (tramp--test-special-characters):
+ Adapt for MS Windows.
+
+2021-05-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix a recent change in rmc.el
+
+ * lisp/emacs-lisp/rmc.el (read-multiple-choice): Doc fix. Improve
+ the message when entering recursive-edit.
+
+2021-05-07 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix some annoyances wrt file-name-non-special
+
+ * lisp/files.el (file-name-non-special): Do not expand `file-truename'.
+
+ * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-out-of-band):
+ Use local `default-directory' for `start-process'.
+
+2021-05-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ `mail-envelope-from' doc clarification
+
+ * lisp/mail/sendmail.el (mail-envelope-from): Note that the buffer
+ should be narrowed before calling (bug#47616).
+
+2021-05-07 Michael Albinus <michael.albinus@gmx.de>
+
+ Tune Tramp traces
+
+ * doc/misc/tramp.texi (Traces and Profiles): Describe call traces.
+
+ * lisp/net/tramp-compat.el: Add `tramp-suppress-trace' property for all
+ functions.
+
+ * lisp/net/tramp.el (tramp-verbose): Adapt docstring.
+ (tramp-file-name-method, tramp-file-name-user)
+ (tramp-file-name-domain, tramp-file-name-host)
+ (tramp-file-name-port, tramp-file-name-localname)
+ (tramp-file-name-hop, tramp-file-name-user-domain)
+ (tramp-file-name-host-port, tramp-file-name-port-or-default)
+ (tramp-tramp-file-p, tramp-find-method, tramp-find-user)
+ (tramp-find-host, tramp-dissect-file-name)
+ (tramp-dissect-hop-name, tramp-debug-buffer-name)
+ (tramp-debug-outline-level, tramp-get-debug-buffer)
+ (tramp-get-debug-file-name, tramp-read-passwd)
+ (tramp-clear-passwd): Add `tramp-suppress-trace' property.
+ (tramp-debug-message): Activate call traces.
+
+ * test/lisp/net/tramp-tests.el (tramp--test-instrument-test-case): Simplify.
+
+2021-05-07 Eli Zaretskii <eliz@gnu.org>
+
+ Improve doc strings in log-edit.el
+
+ * lisp/vc/log-edit.el (log-edit-new-comment-index)
+ (log-edit-maximum-comment-ring-size, log-edit-previous-comment)
+ (log-edit-next-comment, log-edit-comment-search-backward)
+ (log-edit-comment-search-forward)
+ (log-edit-comment-to-change-log)
+ (log-edit-header-contents-regexp, log-edit-font-lock-gnu-style)
+ (log-edit, log-edit-mode, log-edit-fill-entry, log-edit-done)
+ (log-edit-kill-buffer, log-edit-insert-message-template)
+ (log-edit-insert-cvs-template, log-edit-insert-cvs-rcstemplate)
+ (log-edit-rewrite-fixes, log-edit-add-to-changelog)
+ (log-edit-generate-changelog-from-diff)
+ (log-edit-insert-changelog, log-edit-narrow-changelog)
+ (log-edit-changelog-entry, log-edit-changelog-insert-entries)
+ (log-edit-extract-headers): Enhance and reword doc strings.
+
+2021-05-06 Jim Porter <jporterbugs@gmail.com>
+
+ Shell-quote the directory when finding a project's files
+
+ * lisp/progmodes/project.el (project--files-in-directory):
+ Shell-quote the directory (bug48247).
+
+2021-05-06 Dmitry Gutov <dgutov@yandex.ru>
+
+ project--buffer-list: Tighten the check
+
+ * lisp/progmodes/project.el (project--buffer-list): Tighten the
+ check to speed up in the presence of multiple Tramp sessions, too.
+ (https://lists.gnu.org/archive/html/emacs-devel/2021-05/msg00152.html)
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-eln-load-path → native-comp-eln-load-path
+
+ * src/comp.c (Fcomp_el_to_eln_filename): Rename comp-eln-load-path →
+ native-comp-eln-load-path.
+ * src/lread.c (maybe_swap_for_eln): Likewise.
+ * lisp/startup.el (native-comp-eln-load-path)
+ (normal-top-level): Likewise.
+ * lisp/emacs-lisp/comp.el (comp-spill-lap-function, comp-final)
+ (comp-eln-load-path-eff, comp-trampoline-compile)
+ (comp-clean-up-stale-eln, comp-run-async-workers)
+ (comp-lookup-eln, batch-byte-native-compile-for-bootstrap): Likewise.
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-warning-on-missing-source
+
+ * src/lread.c (maybe_swap_for_eln): Rename
+ comp-warning-on-missing-source →
+ native-comp-warning-on-missing-source.
+ * src/comp.c (syms_of_comp): Likewise.
+ * lisp/emacs-lisp/comp.el (native-comp-warning-on-missing-source):
+ Likewise.
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-native-driver-options → native-comp-driver-options
+
+ * src/comp.c (add_driver_options, syms_of_comp): Rename
+ comp-native-driver-options → native-comp-driver-options.
+ * lisp/emacs-lisp/comp.el (native-comp-driver-options)
+ (comp-ctxt, comp-spill-lap-function, comp-final)
+ (comp-run-async-workers): Likewise.
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-from-buffer): Likewise.
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-async-query-on-exit → native-comp-async-query-on-exit
+
+ * lisp/emacs-lisp/comp.el (native-comp-async-query-on-exit)
+ (comp-run-async-workers): Rename comp-async-query-on-exit →
+ native-comp-async-query-on-exit.
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-async-report-warnings-errors
+
+ * lisp/emacs-lisp/comp.el (native-comp-async-report-warnings-errors)
+ (comp-accept-and-process-async-output): Rename
+ comp-async-report-warnings-errors →
+ native-comp-async-report-warnings-errors.
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-async-env-modifier-form → native-comp-async-env-modifier-form
+
+ * lisp/emacs-lisp/comp.el (native-comp-async-env-modifier-form)
+ (comp-final, comp-run-async-workers): Rename
+ comp-async-env-modifier-form → native-comp-async-env-modifier-form.
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-async-all-done-hook → native-comp-async-all-done-hook
+
+ * lisp/emacs-lisp/comp.el (native-comp-async-all-done-hook)
+ (comp-run-async-workers): Rename comp-async-all-done-hook →
+ native-comp-async-all-done-hook.
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-async-cu-done-functions → native-comp-async-cu-done-functions
+
+ * lisp/emacs-lisp/comp.el (native-comp-async-cu-done-functions)
+ (comp-run-async-workers): Rename comp-async-cu-done-functions →
+ native-comp-async-cu-done-functions.
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-async-jobs-number → native-comp-async-jobs-number
+
+ * lisp/emacs-lisp/comp.el (native-comp-async-jobs-number)
+ (comp-effective-async-max-jobs, native--compile-async)
+ (native-compile-async): Rename comp-async-jobs-number →
+ native-comp-async-jobs-number.
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-never-optimize-functions → native-comp-never-optimize-functions
+
+ * lisp/emacs-lisp/nadvice.el (advice--add-function): Rename
+ comp-never-optimize-functions → native-comp-never-optimize-functions.
+ * lisp/emacs-lisp/comp.el (native-comp-never-optimize-functions)
+ (comp-subr-trampoline-install, comp-call-optim-form-call): Likewise.
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-bootstrap-deny-list → native-comp-bootstrap-deny-list
+
+ * lisp/emacs-lisp/comp.el (native-comp-bootstrap-deny-list)
+ (batch-native-compile): Rename comp-bootstrap-deny-list →
+ native-comp-bootstrap-deny-list.
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-always-compile → native-comp-always-compile
+
+ * lisp/emacs-lisp/comp.el (native-comp-always-compile)
+ (comp-run-async-workers): comp-always-compile →
+ native-comp-always-compile.
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-verbose -> native-comp-verbose
+
+ * lisp/emacs-lisp/comp.el (native-comp-verbose, comp-log)
+ (comp-log-func, comp-final, comp-run-async-workers): Rename
+ comp-verbose -> native-comp-verbose.
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-debug -> native-comp-debug
+
+ * src/comp.c (emit_ctxt_code, syms_of_comp): Rename comp-debug ->
+ native-comp-debug.
+ * lisp/emacs-lisp/comp.el (native-comp-debug, comp-ctxt)
+ (comp-spill-lap-function, comp-run-async-workers): Likewise.
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-from-buffer): Likewise.
+ * test/src/comp-tests.el (comp-tests-bootstrap): Likewise.
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-speed -> native-comp-speed
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-from-buffer): Rename
+ comp-speed -> native-comp-speed.
+ * lisp/emacs-lisp/comp.el (native-comp-speed, comp-ctxt, comp-func,
+ comp-spill-lap-function, comp-trampoline-compile,
+ comp-run-async-workers): Likewise.
+ * src/comp.c (emit_ctxt_code, load_comp_unit, syms_of_comp): Likewise.
+ * test/src/comp-tests.el (comp-tests-tco, comp-tests-fw-prop-1)
+ (comp-tests-check-ret-type-spec, comp-tests-pure): Likewise.
+
+2021-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-limple-mode -> native-comp-limple-mode
+
+ * lisp/emacs-lisp/comp.el (comp-limple-lock-keywords): Doc update.
+ (native-comp-limple-mode, comp-log-to-buffer): Rename comp-limple-mode
+ -> native-comp-limple-mode.
+
+2021-05-06 Michael Albinus <michael.albinus@gmx.de>
+
+ In Tramp, use scp "-T" argument if available
+
+ * lisp/net/tramp-sh.el (tramp-scp-strict-file-name-checking): New defvar.
+ (tramp-scp-strict-file-name-checking): New defun.
+ (tramp-do-copy-or-rename-file-out-of-band): Use it.
+ (tramp-methods) <scp, scpx>: Use "%x".
+ (tramp-make-copy-program-file-name): Use local quoting.
+ (tramp-sh-handle-make-process): Don't call
+ `tramp-maybe-open-connection', this happens implicitly by
+ `tramp-send-command'.
+
+ * lisp/net/tramp.el (tramp-methods): Adapt docstring.
+
+ * test/lisp/net/tramp-tests.el (tramp-test40-special-characters)
+ (tramp-test40-special-characters-with-stat)
+ (tramp-test40-special-characters-with-perl)
+ (tramp-test40-special-characters-with-ls): Don't skip for
+ `tramp--test-windows-nt-and-scp-p'.
+
+2021-05-06 Stefan Kangas <stefan@marxist.se>
+
+ Improve formatting in text-quoting-style docstring
+
+ * src/doc.c (syms_of_doc) <text-quoting-style>: Doc fix; improve
+ formatting for readability.
+
+2021-05-06 Stefan Kangas <stefan@marxist.se>
+
+ Remove another variable alias obsolete since Emacs 23
+
+ * lisp/menu-bar.el (menu-bar-files-menu): Delete variable alias for
+ `menu-bar-file-menu'.
+ * etc/NEWS: Announce its deletion.
+
+2021-05-06 Mattias Engdegård <mattiase@acm.org>
+
+ Don't fail image-tests if JPEG format isn't compiled in
+
+ * test/lisp/image-tests.el (image-type/from-filename):
+ Make jpeg test conditional. Test pbm (always present).
+
+2021-05-06 Mattias Engdegård <mattiase@acm.org>
+
+ Tidy file-matching regexps and remove some ineffective backslashes
+
+ * lisp/emacs-lisp/package.el (package--delete-directory):
+ * lisp/net/tramp-cmds.el (tramp-recompile-elpa):
+ Escape dot; replace $ with \'.
+ * lisp/help.el (help-for-help):
+ * lisp/transient.el (transient-font-lock-keywords):
+ Remove useless backslashes.
+
+2021-05-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make (setf (map-elt ...)) return the value in the alist/plist cases
+
+ * lisp/emacs-lisp/map.el (map-elt): Return the value in the list
+ case (which can signal a `map-not-inplace' error.
+ (map-elt): Return the value in the list case, too (bug#47572).
+
+2021-05-06 Matt Armstrong <matt@rfc20.org>
+
+ Add tests for `map-elt'
+
+ * test/lisp/emacs-lisp/map-tests.el: Add (failing) tests for `map-elt'
+ (bug#47572).
+
+2021-05-06 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix bug#47625 in dired
+
+ * lisp/dired-aux.el (dired-create-files): Check, that
+ `dired-do-symlink' does not create symlinks on different hosts.
+ (Bug#47625)
+
+2021-05-06 Alan Mackenzie <acm@muc.de>
+
+ Fix wrong handling of minibuffers when frames get iconified/made invisible
+
+ This should fix bug #47766.
+
+ * lisp/window.el (window-deletable-p): Add a quote where it was missing from
+ minibuffer-follows-selected-frame.
+
+ * src/frame.c (check_minibuf_window): Delete the function.
+ (delete_frame): In place of calling check_minibuf_window, call
+ move_minibuffers_onto_frame, possibly to move minibuffers onto the new current
+ frame.
+ (Fmake_frame_invisible, Ficonify_frame): Remove calls to check_minibuf_window.
+
+ * src/minibuf.c (Factive_minibuffer_window): Search the frames for the active
+ minibuffer rather than just assuming minibuf_window has been correctly
+ updated.
+
+2021-05-06 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Eliminate bad interpretation of ?foo?
+
+ * lisp/progmodes/cperl-mode.el (cperl-find-pods-heres): Delete
+ ?? from the allowed bare regexp delimiters.
+ (cperl-short-docs): Delete ?...? from the documentation.
+
+ * test/lisp/progmodes/cperl-mode-tests.el (cperl-bug-47598):
+ Add tests for good, bad, and ambiguous use of ? as regex
+ delimiter (bug#47598).
+
+2021-05-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Only look at the headers when computing the envelope from address
+
+ * lisp/mail/smtpmail.el (smtpmail-send-it)
+ (smtpmail-send-queued-mail, smtpmail-via-smtp):
+ * lisp/mail/sendmail.el (sendmail-send-it): Only look at the
+ headers when computing the envelope from (bug#47616).
+
+2021-05-06 Dmitrii Kuragin <dkuragin@ya.ru> (tiny change)
+
+ Fix ispell program comparison
+
+ * lisp/textmodes/ispell.el (ispell-set-spellchecker-params):
+ Compare strings with `equal', not `eq' (since the identity of the
+ string may change) (bug#48246).
+
+2021-05-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make Info completion more robust
+
+ * lisp/info.el (Info-build-node-completions): Don't signal an
+ error if there are no nodes in the file we're computing
+ completions over (bug#47771).
+
+2021-05-06 Daniel Martín <mardani29@yahoo.es>
+
+ Add a help option to the open large files prompt
+
+ * lisp/files.el (files--ask-user-about-large-file-help-text): New
+ function that returns information about opening large files in
+ Emacs. (Bug#45412)
+ (files--ask-user-about-large-file): Use read-multiple-choice to
+ display the available actions.
+ * etc/NEWS: Advertise the new feature.
+
+2021-05-06 Daniel Martín <mardani29@yahoo.es>
+
+ Extend read-multiple-choice to support free-form help descriptions
+
+ * lisp/emacs-lisp/rmc.el (read-multiple-choice): Add a new argument to
+ override the default help description in `read-multiple-choice'. Use
+ the `help-char' variable instead of ?\C-h. Also support the `edit'
+ action from `query-replace-map', so that help links can be visited by
+ entering a recursive edit.
+
+2021-05-05 Karl Fogel <kfogel@red-bean.com>
+
+ New option to confirm deletion in bookmark menu
+
+ * lisp/bookmark.el (bookmark-menu-confirm-deletion): New defcustom.
+ (bookmark-delete-all): Add comment explaining why we don't use the new
+ confirmation formula here.
+ (bookmark-bmenu-execute-deletions): Conditionally confirm deletion.
+ Note that the bulk of the code diff here is just reindentation of an
+ otherwise unchanged `let' expression.
+
+ * etc/NEWS: Announce the new option.
+
+ Thanks to Lars Ingebrigtsen and Eli Zaretskii for review, and thanks
+ to Oliver Taylor for suggesting the option in the first place:
+
+ https://lists.gnu.org/archive/html/emacs-humanities/2021-02/msg00022.html
+ From: Oliver Taylor
+ Subject: Re: [emacs-humanities] Extending Emacs Bookmarks to Work with EWW
+ To: Karl Fogel
+ Cc: Stefan Kangas, Emacs-humanities mailing list
+ Date: Wed, 3 Feb 2021 20:21:59 -0800
+ Message-Id: <936D47EA-4D11-452B-8303-971B6386877B@me.com>
+
+2021-05-05 Andrea Corallo <akrl@sdf.org>
+
+ Rename feature `nativecomp' into `native-compile'
+
+ * test/src/comp-tests.el : Rename feature `nativecomp' into
+ `native-compile'.
+ * test/lisp/help-fns-tests.el (help-fns-test-lisp-defun): Likewise.
+ * src/comp.c (syms_of_comp): Likewise.
+ * lisp/startup.el (normal-top-level): Likewise.
+ * lisp/loadup.el: Likewise.
+ * lisp/help.el (help-function-arglist): Likewise.
+ * lisp/emacs-lisp/package.el (package--native-compile-async)
+ (package--delete-directory): Likewise.
+ * lisp/emacs-lisp/nadvice.el (advice--add-function): Likewise.
+ * lisp/emacs-lisp/comp.el (comp-ensure-native-compiler): Likewise.
+ * lisp/emacs-lisp/advice.el (ad-add-advice): Likewise.
+
+2021-05-05 Martin Rudalics <rudalics@gmx.at>
+
+ Fix setting of 'width' and 'height' frame parameters
+
+ * src/frame.c (Fframe_parameters): Fix bogus setting of 'height'
+ and 'width' parameters.
+
+2021-05-05 Andrea Corallo <akrl@sdf.org>
+
+ * test/lisp/help-fns-tests.el (help-fns-test-lisp-defsubst): Fix (bug#48221).
+
+2021-05-05 Kazuhiro Ito <kzhr@d1.dion.ne.jp>
+
+ Tweak how some Japanese punctuation chars are translated to ASCII
+
+ * lisp/language/japan-util.el (japanese-symbol-table): Tweak
+ Japanese punctuation character translation (bug#47767).
+
+2021-05-05 Andrea Corallo <akrl@sdf.org>
+
+ Better identify native compiler presence in two tests.
+
+ * test/lisp/help-fns-tests.el (help-fns-test-lisp-defun)
+ (help-fns-test-lisp-defsubst): Better identify native-comp
+ presence.
+
+2021-05-05 Daniel Mendler <mail@daniel-mendler.de>
+
+ Don't bug out in `Info-goto-node' completion
+
+ * lisp/info.el (Info-read-node-name-1): Don't bug out in the
+ middle of completion, but return nil instead (and issue a message)
+ (bug#47771).
+
+2021-05-05 Boruch Baum <boruch_baum@gmx.com>
+
+ Fix error in ses.el when setting the current row
+
+ * lisp/ses.el (ses-jump, ses-list-local-printers)
+ (ses-list-named-cells): Use `user-error' for user errors.
+ (ses-set-header-row): Function `ses-set-header-row' was
+ determining the current row based upon variable `ses--curcell',
+ but that variable is NIL until one begins an operation on a cell
+ (eg. keybindings '=', '"'), so navigating to a row was
+ insufficient to select that row, and further generated an ERROR
+ because the code was not expecting a NIL value for variable
+ `ses--curcell' (bug#47784).
+
+2021-05-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow `C-x C-k l' to work even if `C-h l' is unbound
+
+ * lisp/kmacro.el (kmacro-edit-lossage): `view-lossage' may be
+ bound to a different key than `C-h l' (bug#47785).
+
+2021-05-05 Matt Beshara <m@mfa.pw>
+
+ Remove unnecessary call to message in js.el
+
+ * lisp/progmodes/js.el (js--end-of-defun-nested): Remove debugging
+ message left over (bug#48234).
+
+2021-05-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use @defmac on eval-{and,when}-compile
+
+ * doc/lispref/compile.texi (Eval During Compile): Use @defmac
+ instead of @defspec on two macros (bug#47862).
+
+2021-05-05 Martin Rudalics <rudalics@gmx.at>
+
+ Fix two GTK3 event handling issues
+
+ * src/xterm.c (handle_one_xevent): For GTK3 PropertyNotify and
+ MapNotify events explicitly request the stored frame sizes when
+ the frame changes from iconified to a non-hidden state
+ (Bug#24526). For Expose events do not change the frame's
+ visibility or iconified state. For FocusIn events on GTK3 do
+ not apply the fix for Bug#42655. The latter two changes are to
+ avoid that plain invisible frames get reported as iconified.
+
+2021-05-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the ELC+ELN lines line up with the other lines
+
+2021-05-05 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Add new defvoo nnimap-keepalive-intervals to Gnus nnimap servers
+
+ * lisp/gnus/nnimap.el (nnimap-keepalive-intervals): New per-server
+ config for customizing when keepalive commands are sent.
+ (nnimap-keepalive, nnimap-open-connection-1): Consult in these
+ places. Additionally, use nnimap-streaming -> t when sending the
+ keepalive NOOP, so we don't wait for the response.
+ * doc/misc/gnus.texi (Customizing the IMAP Connection): Document.
+
+2021-05-04 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Remove unused lexical variables in cc-defs.el
+
+ * lisp/progmodes/cc-defs.el (c-sc-scan-lists-no-category+1+1)
+ (c-sc-scan-lists-no-category+1-1, c-sc-scan-lists-no-category-1+1)
+ (c-sc-scan-lists-no-category-1-1): Remove unused lexical variable
+ 'here' to pacify byte-compilation warnings in cc-engine.el.
+
+2021-05-04 Andrea Corallo <akrl@sdf.org>
+
+ Do not try to load unexistent eln file if async compilation was skipped
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): Don't try to
+ load if the eln file was not produced.
+
+2021-05-04 Eli Zaretskii <eliz@gnu.org>
+
+ Fix infloop in lsp-mode
+
+ * src/indent.c (line_number_display_width): Make sure the selected
+ window's buffer is current before using display code on it:
+ redisplay assumes that the window's buffer is current at all
+ times. Reported by Evgeny Kurnevsky via lsp-mode's issue 1621,
+ https://github.com/emacs-lsp/lsp-mode/issues/1621.
+
+2021-05-04 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 40228fffd7 (origin/emacs-27) Fix code for newline-and-indent in skele...
+ 56c4c8ef32 * lisp/jka-compr.el (jka-compr-uninstall): Fix function re...
+
+2021-05-04 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 101a049f55 Improve doc string of 'tab-width'.
+ 43c154404e * lisp/emacs-lisp/elp.el: Doc fixes.
+ 1984213f62 * lisp/emacs-lisp/pp.el: Doc fixes.
+ 6486c9dc73 * admin/make-tarball.txt: Note to update more files on web...
+
+2021-05-04 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Remove as of recently unused GDK macro
+
+ Its only use was removed in the recent change of 2021-04-27 "Major
+ rewrite of adjust_frame_size", announced in the following thread:
+ https://lists.gnu.org/r/emacs-devel/2021-04/msg01162.html
+
+ * src/gtkutil.c [USE_GTK && !HAVE_GTK3] (gdk_window_get_geometry):
+ Remove unused macro to pacify -Wunused-macros build warning.
+
+2021-05-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix inconsistent behaviour in find-file-noselect when using nowarn
+
+ * lisp/files.el (after-find-file): Behave the same in when
+ warning/not warning (bug#47850). This fixes this test case:
+ (switch-to-buffer (find-file-noselect "non-existing-dir/test.el" t))
+ which would leave the buffer read-only.
+
+2021-05-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow TAB to go to a key in EPA key buffers
+
+ * lisp/epa.el (epa--insert-keys): Allow TAB to go to the keys
+ (bug#47876).
+
+2021-05-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix doc marker for previous bookmark NEWS change
+
+2021-05-04 Boruch Baum <boruch_baum@gmx.com>
+
+ Fontify lines when setting a bookmark
+
+ * lisp/bookmark.el (bookmark-fontify): New user option (bug#48179).
+ (bookmark-face): New face.
+ (bookmark--fontify, bookmark--unfontify): New functions.
+ (bookmark-set-internal, bookmark--jump-via, bookmark-delete): Use
+ them.
+
+2021-05-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Ensure updating the animated image in all windows
+
+ * lisp/image.el (image-show-frame): Simplify the window update --
+ pass in the buffer, which is a noop if the buffer isn't displayed.
+
+2021-05-04 Martin Rudalics <rudalics@gmx.at>
+
+ Fix a problem with x_set_tab_bar_lines (Bug#46827)
+
+ * src/xfns.c (x_set_tab_bar_lines): Call
+ x_change_tab_bar_height only if the number of tab bar lines
+ changed from or to zero (Bug#46827).
+ * src/xterm.c (x_make_frame_visible): Make frame_size_history
+ update less noisy by doing it only if the frame wasn't visible
+ before.
+
+2021-05-03 Philip K <philipk@posteo.net>
+
+ project--buffer-list: Avoid Tramp buffers when possible
+
+ * lisp/progmodes/project.el (project--buffer-list): Add
+ file-remote-p check.
+
+2021-05-03 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix unquoting of file names in subprocesses (Bug#48177)
+
+ * lisp/files.el (file-name-non-special):
+ Improve handling of inhibit-file-name-handlers.
+
+ * src/callproc.c (Fcall_process, call_process): Unquote infile,
+ error_file and output_file. (Bug#48177)
+
+ * test/lisp/files-tests.el (files-tests-file-name-non-special--subprocess)
+ (files-tests-file-name-non-special-file-name-all-completions)
+ (files-tests-file-name-non-special-file-name-completion): Adapt tests.
+
+2021-05-03 Alan Third <alan@idiocy.org>
+ martin rudalics <rudalics@gmx.at>
+
+ Fix incorrect resizing behaviour on macOS (bug#48157, bug#48162)
+
+ * src/nsterm.m ([EmacsView viewDidResize:]): The drawing buffer can be
+ resized independently of Emacs's idea of the frame size.
+
+2021-05-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ ediff shouldn't alter the kill ring when copying a diff
+
+ * lisp/vc/ediff-util.el (ediff-copy-diff, ediff-pop-diff): Don't
+ alter the kill ring (bug#47881).
+
+2021-05-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Speed up animation of non-displayed buffers
+
+ * lisp/image.el (image-show-frame): Don't force an update if the
+ buffer with the animation isn't in a window (bug#47895). Also
+ just update the window in question.
+
+2021-05-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Speed up animation of non-displayed images
+
+ * lisp/image.el (image-animate): Only compute the animation data
+ once -- this avoids recomputing the image on every iteration when
+ the image is not displayed (bug#47895).
+
+2021-05-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Note that function symbols are preferred in `add-hook'
+
+ * lisp/subr.el (add-hook): Note that FUNCTION should preferably be
+ a symbol (bug#47992).
+
+2021-05-03 Steve Purcell <steve@sanityinc.com>
+
+ ruby-mode.el: puts and printf do not require args
+
+ * lisp/progmodes/ruby-mode.el (ruby-font-lock-keywords): puts and
+ printf can be called without arguments, so the font locking of
+ "bare" calls to either is incorrect. The fix is to font-lock them
+ as for other kernel methods which accepts zero or more arguments
+ (bug#48180).
+
+2021-05-03 Lele Gaifax <lele@metapensiero.it>
+
+ Align TUTORIAL.it to the English version
+
+ * etc/tutorials/TUTORIAL.it: Reference 'describe-command' to replicate
+ recent change. Add also a space before '<Invio>' in several places,
+ mimicking the usage of <Return> in the English version (bug#48183).
+
+2021-05-02 Philipp Stephani <phst@google.com>
+
+ Fix code for newline-and-indent in skeleton language.
+
+ The code for this is the symbol 'n', which is usually spelled as '\n'
+ here, not the character ?\n.
+
+ * doc/misc/autotype.texi (Skeleton Language): Fix item for
+ newline-and-indent.
+
+2021-05-02 Martin Rudalics <rudalics@gmx.at>
+
+ Add two changes announced but not included in previous commit
+
+ * src/frame.c (adjust_frame_size): Remove extra
+ inhibit_horizontal/_vertical checks. Improve the implied
+ resize check when INHIBIT equals 2.
+
+2021-05-02 Stefan Kangas <stefan@marxist.se>
+
+ * etc/tutorials/TUTORIAL.sv: Adjust to latest change in TUTORIAL.
+
+ * etc/tutorials/TUTORIAL.es: Adjust to latest change in TUTORIAL.
+
+2021-05-02 Alan Mackenzie <acm@muc.de>
+
+ * lisp/progmodes/cc-defs.el (c-save-buffer-state): Amend debug
+ spec, t to let*.
+
+ This should solve part of bug #48100.
+
+2021-05-02 Eli Zaretskii <eliz@gnu.org>
+
+ * etc/tutorials/TUTORIAL.he: Adjust to latest change in TUTORIAL.
+
+2021-05-02 Stefan Kangas <stefan@marxist.se>
+
+ Add new help command 'describe-command'
+
+ * lisp/help-fns.el (describe-command): New command.
+ (help-fns--describe-function-or-command-prompt): New helper
+ function to prompt for a function or function. (Bug#46627)
+ (describe-function): Use above new helper function.
+
+ * lisp/help.el (help-map): Bind above new command to `C-h x'.
+ (help-for-help): Add this new command to the help summary.
+ * lisp/menu-bar.el (menu-bar-describe-menu): Add the new command to
+ the help menu.
+
+ * doc/emacs/help.texi (Help Summary, Name Help): Document
+ 'describe-command', and update documentation on 'describe-function'.
+ * etc/tutorials/TUTORIAL: Change reference from 'describe-function' to
+ 'describe-command'.
+
+2021-05-02 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/apropos.el (apropos-value, apropos-local-value): Tweak for lexbind
+
+ Don't skip symbols for the nowadays lexically scoped local vars.
+
+2021-05-02 Alan Third <alan@idiocy.org>
+
+ Fix crash when resizing GNUstep builds
+
+ The toolkit can send far too many resize notifications, so be more
+ careful when we take action after receiving one.
+
+ * src/nsfns.m (ns_set_tool_bar_lines): Remove unneeded NSTRACE.
+ * src/nsterm.m ([EmacsView viewDidResize:]): Don't report resizes to
+ Emacs when the same change has already been reported and delayed.
+
+2021-05-02 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/help-macro.el: Doc fix.
+
+2021-05-02 Stefan Kangas <stefan@marxist.se>
+
+ Bind S-SPC to scroll-down in help-for-help
+
+ * lisp/help-macro.el (make-help-screen): Bind S-SPC to
+ scroll-down. Thanks to Dmitry Gutov <dgutov@yandex.ru>.
+
+2021-05-02 Stefan Kangas <stefan@marxist.se>
+
+ Minor doc fixes in simple.el
+
+ * lisp/simple.el (next-error-move-function)
+ (next-error-found-function, next-error-found)
+ (previous-error-no-select, eval-expression-get-print-arguments)
+ (undo-adjust-elt, undo-adjust-beg-end): Minor doc fixes.
+
+2021-05-02 Nikolay Kudryavtsev <nikolay.kudryavtsev@gmail.com>
+
+ Don't use pdumper-stats with unexec
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-refresh-preloaded): Check if
+ pdumper-stats is bound before using it.
+
+2021-05-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Inhibit lines in doc-view-mode
+
+ * lisp/doc-view.el (doc-view-mode): Inhibit line number modes
+ (bug#47974). Change suggested by Gregory Heytings.
+
+2021-05-02 Eric Skoglund <eric@pagefault.se>
+
+ Add newline and tab matching documentation to query-replace-regexp
+
+ * lisp/replace.el: Add \n and \t matching information to
+ query-replace-regexp docstring (bug#47981).
+
+2021-05-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak filtering some more
+
+ This should get the ./temacs continuation lines right.
+
+2021-05-02 Martin Rudalics <rudalics@gmx.at>
+
+ Make adjust_frame_size set up frame's new_width/_height too (Bug#17120)
+
+ The purpose of this change is to have implied frame size changes
+ pick up sizes requested by previous explicit size changes not
+ only after they have been confirmed by the WM but already when
+ they are initially passed to adjust_frame_size (Bug#17120).
+
+ * src/dispextern.h (delayed_size_change): Remove extern.
+ * src/dispnew.c (delayed_size_change): Make static again.
+ (do_pending_window_change): Call change_frame_size only if F's
+ new_size_p flag is set.
+ (change_frame_size_1): Set/reset F's new_size_p flag
+ * src/frame.c (adjust_frame_size): Remove extra
+ inhibit_horizontal/_vertical checks. Improve the implied
+ resizes check with INHIBIT equals 2. Set F's new_width and
+ new_height and reset F's new_size_p flag when we run
+ set_window_size_hook with INHIBIT 0 or 1.
+ * src/frame.h (struct frame): New bit slot new_size_p.
+ * src/gtkutil.c (xg_frame_resized): Use F's new_size_p flag
+ instead of delayed_size_change to decide whether to call
+ change_frame_size.
+ (xg_frame_set_char_size): Call frame_size_history_extra before
+ waiting for the ConfigureNotify event.
+ * src/xterm.c (handle_one_xevent): Use F's new_size_p flag
+ instead of delayed_size_change to decide whether to call
+ change_frame_size.
+
+2021-05-02 Boruch Baum <boruch_baum@gmx.com>
+
+ Suppress false positives in apropos-value
+
+ * lisp/apropos.el (apropos-value): Skip more apropos-internal
+ variables (bug#48063).
+ (apropos-value-internal): Skip the first value in the history
+ values, which always contains the match.
+
+2021-05-02 Philipp Stephani <phst@google.com>
+
+ * lisp/jka-compr.el (jka-compr-uninstall): Fix function reference.
+
+2021-05-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/simple.el (newline): Make the hook function remove itself
+
+ (copy-region-as-kill, kill-ring-save): Simplify interactive spec.
+
+2021-05-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/minibuffer.el (completing-read-default): Fix bug#45474
+
+ Set `minibuffer-completion-*` variables buffer-locally instead of using
+ a global let-binding. This should also help make completion work
+ correctly when multiple minibuffers are simultaneously active.
+
+2021-05-01 Alan Third <alan@idiocy.org>
+
+ Fix infinite loop on GNUstep when toolbar updated
+
+ * src/nsterm.m ([EmacsView viewDidResize:]): Use Emacs's existing
+ knowledge of the frame size to decide whether to resize or not.
+
+2021-05-01 Alan Third <alan@idiocy.org>
+
+ Fix NS build warnings
+
+ * src/nsfns.m (Fx_create_frame): Remove unused variables.
+
+2021-05-01 Jim Porter <jporterbugs@gmail.com>
+
+ Fix GUD overlay arrows in gdb-mi when debugging over Tramp
+
+ * lisp/progmodes/gdb-mi.el (gdb-frame-handler): Use local part of
+ file name when setting `gud-last-frame'.
+
+2021-04-30 Stefan Kangas <stefan@marxist.se>
+
+ Advertise PgUp/PgDn instead of SPC/DEL in help-for-help
+
+ * lisp/help-macro.el (make-help-screen):
+ * lisp/help.el (help-for-help): Advertise PgUp/PgDn instead of
+ SPC/DEL.
+
+2021-04-30 Mattias Engdegård <mattiase@acm.org>
+
+ Don't signal scan-error in interactive sexp-based commands
+
+ This takes care of unfinished business from df0f32f04850 (bug#43489).
+
+ * lisp/emacs-lisp/lisp.el (end-of-defun, mark-defun):
+ * lisp/reposition.el (reposition-window):
+ * lisp/simple.el (transpose-sexps): Convert nasty-looking scan-error
+ into a human-readable message.
+
+2021-04-30 Eli Zaretskii <eliz@gnu.org>
+
+ Fix the unexec build on MS-Windows
+
+ * src/buffer.c (init_buffer) [USE_MMAP_FOR_BUFFERS]: If dumped
+ with unexec, be sure to map new memory also for the " prin1"
+ buffer. For the reasons and discussion, see
+ https://lists.gnu.org/archive/html/emacs-devel/2021-04/msg01401.html.
+
+2021-04-30 Eli Zaretskii <eliz@gnu.org>
+
+ Improve doc string of 'tab-width'.
+
+ * src/buffer.c (syms_of_buffer) <tab-width>: Clarify doc string.
+ (Bug#48058)
+
+2021-04-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Alter `gnus-article-show-images' to re-display with images installed
+
+ * lisp/gnus/gnus-art.el (gnus-article-show-images): Reselect to
+ display HTML images.
+
+2021-04-30 Eli Zaretskii <eliz@gnu.org>
+
+ Improve support for 'display-line-numbers-width-start'
+
+ * lisp/display-line-numbers.el (display-line-numbers-width-start):
+ Allow the value to be a number. (Bug#48095)
+ (display-line-numbers-mode): Handle
+ 'display-line-numbers-width-start' whose value is a number.
+
+2021-04-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/doc.c (Fsnarf_documentation): Fix bug#48019
+
+ Don't presume that `custom-delayed-init-variables` holds a list.
+
+2021-04-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/mail/supercite.el (sc-select-attribution): Fix lexical conversion
+
+ Mark `citation` and `attribution` as dynamically scoped around
+ `sc-attribs-postselect-hook`, as documented in the function's docstring.
+
+2021-04-29 Andrea Corallo <akrl@sdf.org>
+
+ Improve `comp-normalize-valset' reproducibility (bug#48021)
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-normalize-valset): Make
+ it more reproducible.
+
+2021-04-29 Glenn Morris <rgm@gnu.org>
+
+ Automatically generate texinfo.el internal autoloads
+
+ * lisp/textmodes/texinfo.el: Replace manual autoloads.
+ * lisp/textmodes/makeinfo.el (makeinfo-region, makeinfo-buffer)
+ (makeinfo-recenter-compilation-buffer):
+ * lisp/textmodes/texnfo-upd.el (texinfo-make-menu)
+ (texinfo-all-menus-update, texinfo-start-menu-description)
+ (texinfo-indent-menu-description, texinfo-master-menu)
+ (texinfo-update-node, texinfo-every-node-update)
+ (texinfo-sequential-node-update, texinfo-insert-node-lines)
+ (texinfo-multiple-files-update):
+ Add autoload cookies, and set generated-autoload-file.
+
+2021-04-29 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/emacs-lisp/elp.el: Doc fixes.
+
+2021-04-29 Michael Albinus <michael.albinus@gmx.de>
+
+ Some Tramp corrections, Bug#48067
+
+ * doc/misc/tramp.texi (Frequently Asked Questions): Rephrase GNU
+ ELPA warnings.
+
+ * lisp/net/tramp-sh.el (tramp-sh-gio-monitor-process-filter):
+ Improve handling of gio warning. (Bug#48067)
+
+2021-04-29 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/emacs-lisp/pp.el: Doc fixes.
+
+ * lisp/emacs-lisp/shortdoc.el: Doc fixes.
+
+2021-04-29 Dmitry Gutov <dgutov@yandex.ru>
+
+ * lisp/progmodes/project.el: Also bump version.
+
+ * lisp/progmodes/xref.el: Bump version.
+
+2021-04-28 Juri Linkov <juri@linkov.net>
+
+ * lisp/window.el (window--state-put-2): Set next/prev-buffers even to nil.
+
+ When next-buffers or prev-buffers are nil, still use set-window-next-buffers
+ or set-window-prev-buffers to set next/prev-buffers to nil. (Bug#46904)
+
+2021-04-28 Andrea Corallo <akrl@sdf.org>
+
+ Add a note related to native compilation and Dynamic Binding
+
+ * doc/lispref/variables.texi (Dynamic Binding): Add a note
+ related to native compilation.
+
+2021-04-28 Michael Albinus <michael.albinus@gmx.de>
+
+ Tramp code cleanup
+
+ * lisp/net/tramp-archive.el (tramp-archive-handle-insert-file-contents):
+ Code cleanup.
+
+ * lisp/net/tramp.el: Reload `tramp-compat' when we reload
+ `tramp-autoloads'.
+ (with-tramp-file-property, with-tramp-connection-property):
+ Use `tramp-cache-undefined'.
+ (tramp-autoload-file-name-handler): Do not load tramp-compat.el.
+ (tramp-handle-insert-file-contents): Code cleanup.
+
+2021-04-28 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix gio warning in Tramp
+
+ * lisp/net/tramp-sh.el (tramp-sh-gio-monitor-process-filter):
+ Improve handling of gio warning. (Bug#48067)
+
+2021-04-28 Eli Zaretskii <eliz@gnu.org>
+
+ Doc fixes in avl-tree.el
+
+ * lisp/emacs-lisp/avl-tree.el (avl-tree--root)
+ (avl-tree--dir-to-sign, avl-tree--sign-to-dir)
+ (avl-tree--del-balance, avl-tree--enter-balance)
+ (avl-tree--do-copy, avl-tree--stack-repopulate, avl-tree-empty)
+ (avl-tree-delete, avl-tree-member, avl-tree-member-p)
+ (avl-tree-map, avl-tree-mapc, avl-tree-mapf, avl-tree-mapcar)
+ (avl-tree-copy, avl-tree-clear, avl-tree-stack)
+ (avl-tree-stack-first): Fix doc strings to be less verbose and to
+ have the first line a complete sentence.
+
+2021-04-28 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/emacs-lisp/avl-tree.el: Minor doc fixes.
+
+ * admin/make-tarball.txt: Note to update more files on web page.
+
+2021-04-28 Michael Albinus <michael.albinus@gmx.de>
+
+ Improve add-log-current-defun-header-regexp
+
+ * lisp/vc/add-log.el (add-log-current-defun-header-regexp):
+ Allow digits. Require at least one letter. (Bug#48037)
+
+2021-04-28 Peter Oliver <p.d.oliver@mavit.org.uk>
+
+ Add tests
+
+ * test/lisp/progmodes/ruby-mode-tests.el (ruby-with-temp-file): New helper.
+ (ruby--set-encoding-when-ascii, ruby--set-encoding-when-utf8)
+ (ruby--set-encoding-when-latin-15): Tests for the previous commit (bug#48043).
+
+2021-04-28 Dmitry Gutov <dgutov@yandex.ru>
+
+ Don't add magic comment to Ruby files for utf-8 encoding
+
+ * lisp/progmodes/ruby-mode.el (ruby-encoding-map):
+ Add entry for utf-8 (bug#48043).
+ (ruby--detect-encoding): Don't convert to string too early, so
+ that returning nil is meaningful.
+ (ruby-mode-set-encoding): Convert to string here.
+
+2021-04-27 Andrea Corallo <akrl@sdf.org>
+
+ Clean-up temporary eln test-suite directory when exiting (bug#48060)
+
+ * lisp/startup.el (normal-top-level): Remove eln test-suite temp
+ dir when exiting.
+
+2021-04-27 Andrea Corallo <akrl@sdf.org>
+
+ Have `comp-cstr-intersection-no-mem' intersect pos neg value sets
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-intersection-no-mem):
+ intersect pos and neg value sets
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Add two tests and fix some
+ test number.
+
+2021-04-27 Stefan Kangas <stefan@marxist.se>
+
+ Avoid missing whitespace in help-for-help
+
+ * lisp/help.el (help--for-help-make-commands): Avoid missing
+ whitespace before description of command.
+ Problem reported by Dmitry Gutov <dgutov@yandex.ru>.
+
+2021-04-27 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix loading problem in Tramp
+
+ * lisp/net/tramp.el (tramp-autoload-file-name-handler): Load also
+ tramp-compat.el.
+
+2021-04-27 Daniel Mendler <mail@daniel-mendler.de>
+
+ (affixation-function): Allow only three-element list elements
+
+ Restrict the definition of the `affixation-function`. The function
+ must return a list of three element lists. Since the
+ `affixation-function` is part of the widely used `completing-read` API
+ a simplification is helpful for both authors of completion UIs and
+ authors of completion tables.
+
+ * doc/lispref/minibuf.texi: Update documentation.
+ * lisp/minibuffer.el: Update documentation.
+ * lisp/simple.el (read-extended-command--affixation):
+ Return three-element lists.
+
+ https://lists.gnu.org/archive/html/emacs-devel/2021-04/msg01193.html
+
+2021-04-27 Mattias Engdegård <mattiase@acm.org>
+
+ Calc: control digits after decimal point (bug#47302)
+
+ Calc normally displays a trailing decimal point for floats with no
+ fractional part, like '12.'. Some uses require at least one digit
+ after the point; add the governing variable calc-digit-after-point.
+
+ * lisp/calc/calc.el (calc-digit-after-point): New variable.
+ (math-format-number): Use it.
+ * test/lisp/calc/calc-tests.el (calc-display-digit-after-point):
+ New test.
+
+2021-04-27 Martin Rudalics <rudalics@gmx.at>
+
+ Major rewrite of adjust_frame_size
+
+ Have adjust_frame_size pass native frame sizes to backends
+ instead of text sizes. Expand frame size history management.
+ Drop PIXELWISE argument from change_frame_size and convert
+ native to text sizes only when calling adjust_frame_size. Use
+ convention in arguments that -1 instead of 0 means that no size
+ change is required. When adjusting frame sizes pick up delayed
+ size changes (Bug#46827).
+
+ * lisp/frame.el (frame-notice-user-settings, make-frame): Don't
+ set frame size history.
+ (frame--size-history): Rewrite doc-string. Handle new formats
+ of `frame-size-history' entries.
+ * src/dispextern.h (delayed_size_change): Extern it.
+ (change_frame_size): Drop last argument from extern.
+ * src/dispnew.c (delayed_size_change): Make it global.
+ (handle_window_change_signal): Reformat. Drop last argument
+ from change_frame_size call.
+ (do_pending_window_change, init_display_interactive): Drop last
+ argument from change_frame_size call.
+ (change_frame_size_1): NEW_WIDTH and NEW_HEIGHT now specify
+ native sizes. Drop last argument PIXELWISE. Queue a change
+ when it either differs from F's current pixel sizes or F's
+ previously queued sizes. Inject frame_size_history_extra call
+ when queuing. Adopt convention that for queued sizes -1 means
+ that no size change is required. Convert from native to text
+ sizes when calling adjust_frame_size.
+ (change_frame_size): Drop last argument PIXELWISE and drop it
+ also in change_frame_size_1 calls.
+ * src/frame.c (frame_size_history_add): Remove.
+ (frame_inhibit_resize): Remove call to frame_size_history_add.
+ (set_menu_bar_lines, set_tab_bar_lines): Simplify. Drop last
+ argument from change_frame_size call.
+ (frame_windows_min_size): No more static.
+ (keep_ratio): Minor rewrite using macros.
+ (frame_size_history_adjust, frame_size_history_plain)
+ (frame_size_history_extra): New functions.
+ (adjust_frame_size): Major rewrite. Adopt new convention that
+ negative values for new sizes mean no change. Pick up delayed
+ size changes from F's new_width and new_height slots
+ (Bug#46827). Call set_window_size_hook with native instead of
+ text sizes. Do not sanitize window sizes any more. Call
+ frame_size_history_adjust instead of frame_size_history_add.
+ Always set F's resized_p slot to true.
+ (make_frame): Initialize new_width and new_height slots to -1.
+ Simplify setup of initial sizes and an adjust_frame_size call.
+ (Fframe_parameters): Drop processing F's new_pixelwise slot.
+ (check_frame_pixels): Reorder to make declarations appear first.
+ (Fset_frame_height, Fset_frame_width, Fset_frame_size): Pass
+ explicit width and height values to adjust_frame_size instead of
+ -1.
+ (gui_set_frame_parameters): Minor rewrite making sure that
+ explicit sizes and the corresponding parameter are passed to
+ adjust_frame_size. Remove frame_size_history_add call.
+ (gui_figure_window_size): Drop last two arguments. Simplify
+ assignment of initial size. Set new_height and new_width slots
+ to -1. Use adjust_frame_size to set sizes instead of returning
+ them to caller.
+ (syms_of_frame): Drop symbols used by frame size history; these
+ are now built on-the-fly. Also drop some menu bar related
+ symbols in favor of Qmenu_bar_lines.
+ * src/frame.h (struct frame): Remove new_pixelwise.
+ (SET_FRAME_COLS, SET_FRAME_LINES, SET_FRAME_WIDTH)
+ (SET_FRAME_HEIGHT): Remove macros.
+ (frame_size_history_add): Remove externs.
+ (frame_windows_min_size, frame_size_history_plain)
+ (frame_size_history_extra): Add externs.
+ (FRAME_WINDOWS_WIDTH, FRAME_WINDOWS_HEIGHT): Rename to
+ FRAME_INNER_WIDTH and FRAME_INNER_HEIGHT.
+ (gui_figure_window_size): Drop last two arguments from
+ extern.
+ * src/gtkutil.c (xg_frame_resized): Rename arguments to WIDTH
+ and HEIGHT. Consult delayed_size_change to handle case where
+ WIDTH and HEIGHT do not match F's new_width and new_height
+ values. Call change_frame_size with native sizes and without
+ PIXELWISE argument. Instead of frame_size_history_add call
+ frame_size_history_extra.
+ (xg_frame_set_char_size): WIDTH and HEIGHT are native sizes now;
+ fix adjust_frame_size call accordingly. Instead of
+ frame_size_history_add call frame_size_history_extra.
+ (style_changed_cb): Call xg_frame_set_char_size with native
+ instead of text sizes.
+ (tb_size_cb): Remove frame_size_history_add call. Call
+ adjust_frame_size with INHIBIT 5.
+ (free_frame_tool_bar, xg_change_toolbar_position): Remove
+ frame_size_history_add call.
+ (update_frame_tool_bar): Call adjust_frame_size with INHIBIT 2
+ and let it handle frame_inhibit_implied_resize and
+ fullheight/-width. Remove frame_size_history_add call.
+ * src/keyboard.c (Fsuspend_emacs): Call change_frame_size with
+ native sizes.
+ * src/nsfns.m (ns_set_tool_bar_lines): Call adjust_frame_size
+ with INHIBIT 2 and let it handle frame_inhibit_implied_resize
+ and fullheight/-width. Remove frame_size_history_add call.
+ (Fx_create_frame): Drop two last arguments in
+ gui_figure_window_size call. Do not SET_FRAME_WIDTH and
+ SET_FRAME_HEIGHT, the adjust_frame_size in
+ gui_figure_window_size did that already.
+ * src/nsterm.m (ns_set_window_size): Drop PIXELWISE argument and
+ its processing; WIDTH and HEIGHT represent native pixel sizes
+ now. Call change_frame_size with native sizes. Remove call to
+ frame_size_history_add.
+ ([EmacsView viewDidResize:]): Call change_frame_size with native
+ sizes.
+ * src/term.c (Fresume_tty): Call change_frame_size with native
+ sizes.
+ * src/termhooks.h (*set_window_size_hook): Drop last argument
+ PIXELWISE.
+ * src/w32fns.c (w32_change_tab_bar_height)
+ (w32_change_tool_bar_height): Fix handling of these in the initial
+ phase before they have been resized at least once.
+ (Fx_create_frame, w32_create_tip_frame): Drop two last arguments
+ in gui_figure_window_size call. Do not SET_FRAME_WIDTH and
+ SET_FRAME_HEIGHT (or SET_FRAME_COLS and SET_FRAME_LINES), the
+ adjust_frame_size in gui_figure_window_size did that already.
+ * src/w32inevt.c (resize_event, maybe_generate_resize_event):
+ Pass native sizes to change_frame_size.
+ * src/w32term.c (w32_read_socket): When WM_WINDOWPOSCHANGED pass
+ native sizes to change_frame_size.
+ (w32_new_font): Recalculate FRAME_TAB_BAR_HEIGHT. Simplify
+ code.
+ (w32fullscreen_hook): Call change_frame_size with native sizes.
+ (w32_set_window_size): Drop argument PIXELWISE and its
+ processing; WIDTH and HEIGHT are native sizes now. Remove
+ frame_size_history_add calls. Pass native sizes to
+ change_frame_size.
+ * src/widget.c (set_frame_size): Set width and height of widget
+ directly. Call frame_size_history_plain instead of
+ frame_size_history_add.
+ (update_from_various_frame_slots): Call
+ frame_size_history_extra.
+ (EmacsFrameRealize): Call frame_size_history_plain.
+ (EmacsFrameResize): Call change_frame_size with native sizes.
+ Call frame_size_history_extra instead of frame_size_history_add.
+ (EmacsFrameSetCharSize): Call frame_size_history_extra. Drop
+ PIXELWISE argument in x_set_window_size call and specify pixels.
+ (pixel_to_text_size): Remove function.
+ * src/xdisp.c (resize_mini_window): Replace FRAME_WINDOWS_HEIGHT
+ with FRAME_INNER_HEIGHT.
+ (redisplay_tab_bar): Don't set tab_bar_redisplayed when we did
+ not redisplay it.
+ (redisplay_tool_bar): Don't call it for external tool bar.
+ Don't set tool_bar_redisplayed when we did not redisplay it.
+ (redisplay_window): When the tool bar is external call
+ update_frame_tool_bar directly.
+ * src/xfns.c (x_set_menu_bar_lines): Call adjust_frame_size only
+ if number of menu bar lines changed and fix 6th argument.
+ (x_change_tab_bar_height, x_change_tool_bar_height): Fix
+ handling of these in the initial phase before they have been
+ resized at least once.
+ (Fx_create_frame, x_create_tip_frame): Drop two last arguments
+ in gui_figure_window_size call. Do not SET_FRAME_WIDTH and
+ SET_FRAME_HEIGHT (or SET_FRAME_COLS and SET_FRAME_LINES), the
+ adjust_frame_size in gui_figure_window_size did that already.
+ * src/xmenu.c (update_frame_menubar): Fix 6th arg of
+ adjust_frame_size call.
+ (free_frame_menubar): For Motif frames fix fullscreen and
+ `frame-inhibit-implied-resize' handling. Fix 6th arg of
+ adjust_frame_size calls.
+ * src/xterm.c (x_net_wm_state): Remove call to
+ frame_size_history_add.
+ (handle_one_xevent): For PropertyNotify and UnmapNotify events
+ add frame_size_history_plain calls. For MapNotify and
+ ConfigureNotify events add a frame_size_history_extra call. For
+ ConfigureNotify events also handle delayed size changes and call
+ change_frame_size with native sizes.
+ (x_new_font): Recalculate FRAME_TAB_BAR_HEIGHT. Simplify code.
+ (x_handle_net_wm_state): Remove frame_size_history_add call.
+ (x_check_fullscreen): Remove frame_size_history_add call. Call
+ change_frame_size with native height.
+ (x_set_window_size_1): WIDTH and HEIGHT are now native. Remove
+ some frame_size_history_add calls and add frame_size_history_extra
+ calls instead. If the frame is not visible call adjust_frame_size
+ directly instead of calling change_frame_size.
+ (x_set_window_size): Drop PIXELWISE argument. WIDTH and HEIGHT
+ represent native sizes now.
+ (x_make_frame_visible, x_make_frame_invisible): Call
+ frame_size_history_plain.
+ * src/xterm.h (x_set_window_size): Drop last argument from
+ extern declaration.
+
+2021-04-27 Glenn Morris <rgm@gnu.org>
+
+ Doc fixes for comp.el
+
+ * lisp/emacs-lisp/comp.el (comp-deferred-compilation-deny-list)
+ (comp-bootstrap-deny-list, comp-pred-to-cstr, make-comp-mvar)
+ (comp-mvar-used-p, comp-async-compilation): Doc fixes.
+
+2021-04-27 Glenn Morris <rgm@gnu.org>
+
+ Fix some custom types in comp.el
+
+ * lisp/emacs-lisp/comp.el (comp-deferred-compilation-deny-list)
+ (comp-bootstrap-deny-list, comp-never-optimize-functions)
+ (comp-async-env-modifier-form, comp-native-driver-options):
+ Fix :type (`list' on its own isn't even a valid type).
+
+2021-04-27 Amin Bandali <bandali@gnu.org>
+
+ * lisp/erc/erc.el: Add past maintainer Michael Olson to Contributors.
+
+2021-04-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix compilation warnings in non-toolkit builds
+
+ * src/xterm.c (x_create_toolkit_scroll_bar)
+ (x_create_horizontal_toolkit_scroll_bar): String constants for
+ XtSetArg are defined as const strings (in
+ /usr/include/X11/Xaw3d/ThreeD.h, for instance), but the argument
+ in XtSetArg is defined as either a const char* or a regular char*
+ in /usr/include/X11/Intrinsic.h. Cast the argument to String
+ (which should be correct on all platforms, hopefully) to avoid a
+ compilation warning (bug#47452).
+
+2021-04-27 Stefan Kangas <stefan@marxist.se>
+
+ Rename abnormal hook to comp-async-cu-done-functions
+
+ * lisp/emacs-lisp/comp.el (comp-async-cu-done-functions): Rename
+ from 'comp-async-cu-done-hook' to reflect that it is an abnormal
+ hook. Doc fix and update single caller.
+
+2021-04-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix failing subr test
+
+ * test/lisp/subr-tests.el (subr-tests-bug22027): Fix mocked
+ signature of `read-string' (bug#48022).
+
+2021-04-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix failing auth-source test
+
+ * test/lisp/auth-source-tests.el
+ (auth-source-test-secrets-create-secret): Fix test failing because
+ the mocked `read-string' had the wrong interface.
+
+2021-04-27 Adam Sjøgren <asjo@koldfront.dk>
+
+ Ensure that we get an X-Draft-From headers
+
+ * lisp/gnus/gnus-msg.el (gnus-setup-message): Ensure that we get an
+ X-Draft-From headers (bug#48049).
+
+2021-04-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/package.el: Fix use of `find-library-name`
+
+ That function caused a warning for a good reason.
+ Don't just declare it and hope it will be available.
+
+ (package--list-of-conflicts): Require `find-func` explicitly before
+ declaring the function. Also don't ignore all errors but only
+ the `file-error`s which will be emitted by `find-library-name`
+ in normal circumstances.
+
+ * lisp/emacs-lisp/find-func.el (find-library-name): Signal a `file-error`
+ Instead of a generic `error`.
+
+2021-04-26 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-ctxt): Initialize it.
+
+2021-04-26 Andrea Corallo <akrl@sdf.org>
+
+ Rework where `comp-ctxt' is defined.
+
+ * test/lisp/emacs-lisp/comp-cstr-tests.el (comp-ctxt): Remove
+ `comp-ctxt' definition.
+ * lisp/emacs-lisp/comp.el (comp-ctxt): Likewise.
+ * lisp/emacs-lisp/comp-cstr.el (comp-ctxt): Define it here.
+
+2021-04-26 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el: Make it loadable in vanilla builds (bug#48021).
+
+ * lisp/emacs-lisp/comp.el (comp-known-type-specifiers): Fix string-search.
+
+2021-04-26 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Small tweaks to gnus-registry reindexing messaging
+
+ * lisp/gnus/gnus-registry.el (gnus-registry-fixup-registry): Use
+ `seq-set-equal-p' so we don't care about list element ordering. Don't
+ show messages within `registry-reindex' if we aren't at gnus-verbose
+ level 9.
+
+2021-04-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous emake adjustment
+
+2021-04-26 Andrea Corallo <akrl@sdf.org>
+
+ Make use of `ert-resource-file' `ert-resource-directory' in comp-tests
+
+ * test/src/comp-resources/comp-test-pure.el: Rename.
+ * test/src/comp-resources/comp-test-funcs.el: Likewise.
+ * test/src/comp-resources/comp-test-funcs-dyn.el: Likewise.
+ * test/src/comp-resources/comp-test-45603.el: Likewise.
+ * test/src/comp-tests.el (comp-test-src, comp-test-dyn-src): Use
+ `ert-resource-file'.
+ (comp-tests-bootstrap): Use ert-resource-directory.
+ (comp-tests-45603-1, comp-tests-pure): Use `ert-resource-file'.
+
+2021-04-26 Andrea Corallo <akrl@sdf.org>
+
+ Use `expand-file-name' in place of `concat' in comp-tests.el
+
+ * test/src/comp-tests.el (comp-test-src,
+ comp-test-dyn-src) (comp-tests-bootstrap, comp-tests-pure,
+ comp-test-src): Use `expand-file-name' in place of `concat'.
+
+2021-04-26 Andrea Corallo <akrl@sdf.org>
+
+ Move native compiler test data into proper directory (bug#48031)
+
+ * test/src/comp-tests-resources/comp-test-45603.el: Rename.
+ * test/src/comp-tests-resources/comp-test-funcs-dyn.el: Likewise.
+ * test/src/comp-tests-resources/comp-test-funcs.el: Likewise.
+ * test/src/comp-tests-resources/comp-test-pure.el: Likewise.
+ * test/src/comp-tests.el (comp-test-directory): Update.
+
+2021-04-26 Andrea Corallo <akrl@sdf.org>
+
+ * test/src/comp-tests.el: Fix it for non native compiled build (bug#48031).
+
+2021-04-26 Andrea Corallo <akrl@sdf.org>
+
+ Fix comp-cstr tests for vanilla build (bug#48021)
+
+ * test/lisp/emacs-lisp/comp-cstr-tests.el (comp-ctxt): Fix tests
+ for vanilla build (bug#48021)
+
+2021-04-26 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-accept-and-process-async-output): Fix regexp.
+
+2021-04-26 Michael Albinus <michael.albinus@gmx.de>
+
+ Some rearrangement in gitlab-ci.yml
+
+ * test/infra/gitlab-ci.yml (test-filenotify-gio, test-gnustep):
+ Add 'needs:' clause.
+ (build-native-bootstrap-speed0, build-native-bootstrap-speed1)
+ (build-native-bootstrap-speed2): Rename from 'test-*'. Do not use
+ '--without-makeinfo'.
+
+2021-04-26 Dario Gjorgjevski <dario.gjorgjevski+git@gmail.com>
+
+ Fix typo in tramp-get-remote-gid
+
+ * lisp/net/tramp.el (tramp-get-remote-gid): Pass the correct
+ operation to find-file-name-handler. (Bug#48026)
+
+2021-04-26 Stefan Kangas <stefan@marxist.se>
+
+ * src/editfns.c (Fpropertize): Doc fix; reference Info manual.
+
+2021-04-25 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/url/url-proxy.el (url-find-proxy-for-url): Minor simplification
+
+2021-04-25 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/startup.el (comp-eln-load-path): Silence a warning.
+
+2021-04-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Hack around problems in Turkish environments in url-proxy
+
+ * lisp/url/url-proxy.el (url-find-proxy-for-url): Work around a
+ problem in Turkish language environments (where a downcased I is
+ ?ı (bug#44604).
+
+2021-04-25 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/emacs-lisp/comp.el (no-native-compile): Minor doc fixes.
+
+ * lisp/help-macro.el: Remove stale Change Log.
+
+2021-04-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust regexp to extra native-comp lines
+
+2021-04-25 Andrea Corallo <akrl@sdf.org>
+
+ Merge branch 'feature/native-comp' into into trunk
+
+2021-04-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert window/winner changes (Revert 0454bfd3313)
+
+ See bug#23621 for an explanation.
+
+2021-04-25 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Get proper search limits in c-font-lock-cut-off-declarators
+
+ * lisp/progmodes/cc-fonts.el (c-font-lock-cut-off-declarators): Instead of
+ using a crude 2,000 characters back limit for backward searching, which is
+ erroneous when that point is in a literal, use the already calculated
+ c-determine-limit result.
+
+2021-04-25 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 7d5b973959 (origin/emacs-27) * doc/misc/cl.texi (For Clauses): Minor ...
+ 4570781f8d ; * doc/lispref/files.texi (Directory Names): Add missing ...
+ 1b52fd538d Minor update for make-tarball.txt
+ 8efb8491b2 * doc/misc/cl.texi (Iteration Clauses): fix `never' clause...
+ 0873134682 ; Fix Texinfo in last change to minibuf.texi.
+ cad8913c89 Improve filling-related documentation
+ 2b7eed23eb ; * doc/lispref/keymaps.texi (Easy Menu): Fix typo.
+ 47fc92cefc Fix reference to "yanking" in the main Emacs manual
+ 1789dcdb35 Improve documentation of 'map-y-or-n-p'
+
+2021-04-25 Stefan Kangas <stefan@marxist.se>
+
+ Add more scroll key bindings to make-help-screen
+
+ * lisp/help-macro.el (make-help-screen): Add bindings to scroll on
+ <PageUp>, <PageDown>, <up>, <down>.
+
+2021-04-25 Gregory Heytings <gregory@heytings.org> (tiny change)
+
+ Fix the handling of the Delete key in help screens.
+
+ * lisp/help-macro.el (make-help-screen): Handle the Delete key
+ in help screens as in Emacs 23 and earlier.
+
+2021-04-25 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/ses.el: Doc fixes.
+
+2021-04-25 Stefan Kangas <stefan@marxist.se>
+
+ Don't hard-code face of "Install" button
+
+ * lisp/emacs-lisp/package.el (package-make-button): Use the
+ 'custom-button' face for the "Install" button. (Bug#47944)
+
+2021-04-25 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant #' before lambda in printing.el
+
+ * lisp/printing.el (pr-menu-create, pr-eval-setting-alist)
+ (pr-complete-alist, pr-file-list, pr-ps-file-list)
+ (pr-insert-section-1, pr-insert-section-2)
+ (pr-insert-section-4, pr-insert-section-5, pr-choice-alist)
+ Remove redundant #' before lambda.
+
+2021-04-25 Stefan Kangas <stefan@marxist.se>
+
+ * src/keyboard.c (Flossage_size): Improve prompt.
+
+2021-04-25 Stefan Kangas <stefan@marxist.se>
+
+ Show correct lossage size in help-for-help
+
+ * lisp/help.el (help-for-help): Show correct lossage size. Add
+ trailing newline.
+ Suggested by Gregory Heytings <gregory@heytings.org>.
+
+2021-04-25 Štěpán Němec <stepnem@gmail.com>
+
+ * doc/lispref/macros.texi (Eval During Expansion): Copy edit.
+
+2021-04-25 Daniel Mendler <mail@daniel-mendler.de>
+
+ (completion-all-sorted-completions): Fix history use with boundaries
+
+ Preprocess the history (and the default) through the new function
+ `minibuffer--sort-preprocess-history` to filter out the completion
+ base for completion tables with boundaries (in particular the file
+ completion table).
+
+ * lisp/minibuffer.el (minibuffer--sort-preprocess-history_: New function.
+ (completion-all-sorted-completions): Use it.
+ * test/lisp/minibuffer-tests.el (completion-all-sorted-completions):
+ Add tests for various combinations of with/without history/base/default.
+
+2021-04-24 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/project.el: Use project-prefixed-buffer-name in more places.
+
+ (project-shell, project-eshell): Use project-prefixed-buffer-name (bug#47975).
+ (project-compilation-buffer-name-function): Add :version tag.
+
+2021-04-24 Philipp Stephani <phst@google.com>
+
+ * doc/misc/cl.texi (For Clauses): Minor copyedits.
+
+2021-04-24 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/mpc.el: Avoid (implicit) `eval`; prefer #' to quote function names
+
+ (mpc-format): Compose functions instead of constructing
+ source-code expressions at run time.
+ Rename `mpc-pred` property to `mpc--uptodate-p`.
+ (mpc-status-buffer-refresh): Adjust to the new property name.
+
+2021-04-24 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/svg.el: Fix typo in sample code; add minor optimization
+
+ (svg--elliptical-arc-command, svg--moveto-command)
+ (svg--lineto-command): Use `mapcan`.
+
+2021-04-24 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * doc/lispref/macros.texi (Eval During Expansion): Fix fixme
+
+2021-04-24 Glenn Morris <rgm@gnu.org>
+
+ Simlify top-level Makefile since admin is always included
+
+ * Makefile.in (clean_dirs, distclean_dirs, maintainer_clean_dirs):
+ Add admin directories.
+ (clean, distclean, bootstrap-clean, maintainer-clean): Simplify.
+ (maybeclean_dirs): Remove - this dates to when admin/ was not
+ included in tar files.
+
+2021-04-24 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/help.el (help--for-help-make-sections): Fix typo.
+
+2021-04-24 Stefan Kangas <stefan@marxist.se>
+
+ Redesign and improve the help-for-help (C-h C-h) command
+
+ * lisp/help.el (help-for-help): Redesign help screen; add sections,
+ rearrange and reword.
+ (help-for-help-header): New face.
+ (help--for-help-make-commands, help--for-help-make-sections): New
+ functions.
+ (help-for-help-buffer-name): New variable.
+
+ * lisp/help-macro.el (make-help-screen): New optional argument
+ BUFFER-NAME. Fontify keys.
+
+ This change was discussed in:
+ https://lists.gnu.org/r/emacs-devel/2021-02/msg01695.html
+ https://lists.gnu.org/r/emacs-devel/2021-03/msg00670.html
+ https://lists.gnu.org/r/emacs-devel/2021-04/msg00292.html
+
+2021-04-24 Eli Zaretskii <eliz@gnu.org>
+
+ Improve detection of pdumper file and *.eln files
+
+ * src/emacs.c (load_pdump_find_executable): Resolve symlinks even
+ if argv[0] includes leading directories. (Bug#46790)
+
+2021-04-24 Eli Zaretskii <eliz@gnu.org>
+
+ Minor update for make-tarball.txt
+
+ * admin/make-tarball.txt (UPDATING THE EMACS WEB PAGES AFTER A
+ RELEASE): Update and enhance the section to make it easier to find
+ the banner and verify the updated pages are in place.
+
+2021-04-24 Jorge P. de Morais Neto <jorge+git@disroot.org> (tiny change)
+
+ * doc/misc/cl.texi (Iteration Clauses): fix `never' clause typo
+
+ This fixes bug#47962.
+
+2021-04-24 Eli Zaretskii <eliz@gnu.org>
+
+ Obsolete the TAB binding in *xref* buffers
+
+ * doc/emacs/maintaining.texi (Xref Commands): Remove the
+ description of the TAB binding. Enhance the description of the
+ RET binding. (Bug#44611)
+
+ * etc/NEWS: Announce the obsolescence of TAB binding in XREF.
+
+ * lisp/progmodes/xref.el (xref-goto-xref): Improve doc string.
+
+2021-04-24 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/rot13.el: Improve documentation. (Bug#47970)
+
+2021-04-24 Eli Zaretskii <eliz@gnu.org>
+
+ Improve diagnostics of loading *.eln files
+
+ * src/pdumper.c (dump_do_dump_relocation): Improve diagnostics
+ when loading preloaded *.eln files fails. (Bug#46790)
+
+2021-04-24 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/subr.el (remove-hook): Improve last change
+
+ Don't put a `hook--depth-alist` property if there isn't one already.
+
+2021-04-24 Amin Bandali <bandali@gnu.org>
+
+ Fix thinko introduced in the last ERC patch (bug#47788)
+
+ * lisp/erc/erc-backend.el (erc-open-network-stream): Need to use apply
+ to call open-network-stream with the supplied arguments because of the
+ plist p of arguments. Thanks to neverwas for pointing it out.
+
+2021-04-23 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/files.el (minibuffer-with-setup-hook): Fix bug#46326
+
+2021-04-23 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/subr.el (add-hook): Try and fix bug#46326
+
+ Use `eq` indexing on `hook--depth-alist`.
+
+ (remove-hook): Remove old entries from `hook--depth-alist`.
+
+2021-04-23 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp-cmds.el (tramp-recompile-elpa-command-completion-p):
+
+ Check, whether Tramp has a package description.
+
+2021-04-23 Juri Linkov <juri@linkov.net>
+
+ * lisp/wdired.el (wdired--before-change-fn): Wrap body in save-match-data.
+
+ Suggested by Michael Heerdegen <michael_heerdegen@web.de> (bug#14013)
+
+2021-04-23 Eli Zaretskii <eliz@gnu.org>
+
+ Fix a recent change in minibuf.texi
+
+ * doc/lispref/minibuf.texi (Basic Completion)
+ (Programmed Completion): Improve wording, punctuation, and markup
+ of a recently-added text.
+
+2021-04-23 Stefan Kangas <stefan@marxist.se>
+
+ * etc/NEWS: 'world-clock-mode' is no longer interactive.
+
+2021-04-23 Philipp Stephani <phst@google.com>
+
+ Expand documentation on nontrivial completion boundaries.
+
+ The interplay between nontrivial completion boundaries and the other
+ completion functions is somewhat subtle, so it deserves a bit more
+ explanation.
+
+ * doc/lispref/minibuf.texi (Basic Completion)
+ (Programmed Completion): Add a few more remarks about nontrivial
+ completion boundaries.
+
+2021-04-23 Philipp Stephani <phst@google.com>
+
+ Fix small bug in 'completion-table-subvert'.
+
+ Even for a trivial underlying completion table (where the 'boundaries'
+ action returns nil), we need to provide nontrivial boundaries so that
+ they match the behavior of 'all-completions'.
+
+ * lisp/minibuffer.el (completion-table-subvert): Return boundaries
+ even for trivial underlying completion table.
+ * test/lisp/minibuffer-tests.el (completion-table-subvert-test):
+ Amend unit test to also test boundaries. While there, also test
+ the other completion functions.
+
+2021-04-23 Eli Zaretskii <eliz@gnu.org>
+
+ Revert "Remove the binding for xref-quit-and-goto-xref"
+
+ This reverts commit 522c34f0e80f60969861b0dc34bc7105249f9994.
+
+ Making changes to which there was an explicit disagreement
+ and a long discussion is unacceptable. (Bug#44611)
+
+2021-04-23 Dmitry Gutov <dgutov@yandex.ru>
+
+ Misc changes
+
+ * lisp/progmodes/project.el (project-shell, project-eshell):
+ Simplify.
+ (project-switch-commands, project-switch-use-entire-map):
+ Add :group keywords (to fix misattribution to project-vc).
+
+2021-04-23 Amin Bandali <bandali@gnu.org>
+
+ Add support for using a TLS client certificate with 'erc-tls' (bug#47788)
+
+ * lisp/erc/erc-backend.el (erc-session-client-certificate): New
+ buffer-local variable storing the TLS client certificate used for the
+ current connection.
+ (erc-open-network-stream): Use open-network-stream instead of
+ make-network-process, and pass any additional arguments to it.
+ (erc-server-connect): Add an optional client-certificate argument
+ that if present is passed with the :client-certificate keyword as part
+ of the arguments to erc-server-connect-function.
+ * lisp/erc/erc.el (erc-open): Add new optional client-certificate
+ argument, set it as erc-session-client-certificate, and pass it along
+ to erc-server-connect.
+ (erc): Clarify documentation string with respect to the full-name
+ argument.
+ (erc-tls): Add new client-certificate keyword argument and pass it in
+ the direct call to erc-open (instead of going through erc).
+ (erc-open-tls-stream): Pass any additional arguments (such as
+ :client-certificate) to open-network-stream. Also allow overriding
+ :nowait if desired.
+
+ * doc/misc/erc.texi: Add documentation for erc-tls, including the new
+ :client-certificate argument.
+
+ * etc/NEWS: Announce the change.
+
+2021-04-23 Ivan Sokolov <ivan-p-sokolov@ya.ru> (tiny change)
+
+ Introduce project-compilation-buffer-name-function
+
+ * lisp/progmodes/project.el (project-compilation-buffer-name-function):
+ New option.
+ (project-compile): Use it.
+ (project-prefixed-buffer-name): New function.
+
+2021-04-22 Dmitry Gutov <dgutov@yandex.ru>
+
+ * lisp/progmodes/xref.el: Remove the "still experimental" note.
+
+2021-04-22 Dmitry Gutov <dgutov@yandex.ru>
+
+ Remove the binding for xref-quit-and-goto-xref
+
+ * lisp/progmodes/xref.el (xref--xref-buffer-mode-map):
+ Remove the binding for xref-quit-and-goto-xref (bug#44611).
+
+ * doc/emacs/maintaining.texi (Xref Commands): Update.
+
+2021-04-22 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/time.el (world-clock-mode): Make non-interactive.
+
+2021-04-22 Stefan Kangas <stefan@marxist.se>
+
+ Minor improvements to world-clock
+
+ * lisp/time.el (world-clock-mode-map): New variable. Bind 'n' and
+ 'p' to 'next-line' and 'previous-line'.
+ (world-clock-update): Preserve point.
+
+2021-04-22 Eli Zaretskii <eliz@gnu.org>
+
+ Fix MS-Windows link switches for unexec
+
+ * configure.ac (LD_SWITCH_SYSTEM_TEMACS) [mingw32]: Disable ASLR
+ when linking for unexec. Reported by Nikolay Kudryavtsev
+ <nikolay.kudryavtsev@gmail.com>.
+
+2021-04-22 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/progmodes/which-func.el: Doc fixes.
+
+2021-04-22 Dmitry Gutov <dgutov@yandex.ru>
+
+ Move part of the fix from project to xref
+
+ * lisp/progmodes/project.el (project--find-regexp-in-files):
+ Don't unquote file names here.
+
+ * lisp/progmodes/xref.el (xref-matches-in-files): Do it here.
+ And only if the first element in the list is quoted (bug#47799).
+
+2021-04-22 Philipp Stephani <phst@google.com>
+
+ Ensure that argument to 'verify' is a constant expression.
+
+ Casting NULL is not a constant expression (Bug#47951).
+
+ * lib-src/seccomp-filter.c (main): Turn check for null pointer
+ representation into a runtime assertion.
+
+2021-04-22 Utkarsh Singh <utkarsh190601@gmail.com> (tiny change)
+
+ * lisp/window.el (display-buffer): Doc fix. (Bug#47950)
+
+2021-04-22 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Fix unload+reload of files using `custom-initialize-delay` (bug#47072)
+
+ * lisp/custom.el (custom-initialize-delay): Don't delay if
+ `custom-delayed-init-variables` has already been processed.
+ * lisp/startup.el (command-line): Mark `custom-delayed-init-variables`
+ as processed.
+
+2021-04-22 Alan Mackenzie <acm@muc.de>
+
+ Fix unclean "can't happen" error handling in read_minibuf_unwind
+
+ Also fix a bug where, with minibuffer-follows-selected-frame neither nil nor
+ t, a minibuffer could appear in two frames at the same time.
+
+ * src/window.c (Fset_window_configuration): Add a new &optional parameter
+ DONT-SET-MINIWINDOW, which inhibits the minibuffer from being restored from
+ the supplied window configuration.
+ (restore_window_configuration): Enhance to match the above.
+
+ * src/minibuf.c (read_minibuf): Enhance the argument list to the
+ restore_window_configuration calls to match the above. In the main case,
+ restoring the minibuffer is inhibited.
+ (read_minibuf_unwind): Should the frame with the expired minibuffer not be
+ found ("can't happen"), unwind the stacked data nevertheless, rather than just
+ exiting.
+
+ * src/keyboard.c (read_char_help_form_unwind): Amend a call of
+ Fset_window_configuration.
+
+ * doc/lispref/windows.texi (Window Configurations): Document the new form of
+ set-window-configuration.
+
+ * etc/NEWS (Lisp Changes in Emacs 28.1): Amend the entry for
+ set-window-configuration.
+
+2021-04-22 Eli Zaretskii <eliz@gnu.org>
+
+ Fix Isearch hscrolling in a corner case
+
+ * lisp/isearch.el (isearch-update): When we start hscrolled,
+ consider also the case that point ends up being to the left of the
+ hscrolled window's edge. (Bug#46316)
+
+2021-04-22 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'window-text-pixel-size' when there's after-string at EOB
+
+ * src/xdisp.c (move_it_to): Fix logic of reaching TO_CHARPOS when
+ there's a display or overlay string(s) at EOB. (Bug#47860)
+
+2021-04-22 Andrea Corallo <akrl@sdf.org>
+
+ Improve a native compiler test
+
+ * test/src/comp-tests.el (comp-test-47868-1): Improve
+ testcase.
+ * test/src/comp-resources/comp-test-funcs.el (comp-test-47868-3-f)
+ (comp-test-47868-4-f): New functions.
+
+2021-04-22 Stefan Kangas <stefan@marxist.se>
+
+ Avoid lowering gc-cons-threshold
+
+ * lisp/cedet/semantic/wisent/comp.el (wisent--compile-grammar):
+ * lisp/international/mule-cmds.el (ucs-names):
+ * lisp/progmodes/ebrowse.el (ebrowse-read):
+ * test/src/coding-tests.el (benchmark-decoder): Avoid lowering
+ gc-cons-treshold.
+
+2021-04-22 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/strokes.el: Doc fix; update URL.
+
+2021-04-22 Dmitry Gutov <dgutov@yandex.ru>
+
+ Use khaki1 as 'match' background
+
+ * lisp/replace.el (match): Use khaki1 as the background color for
+ light backgrounds (bug#47574).
+
+2021-04-21 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/emacs-lisp/package.el (package-archives): Bump :version.
+
+ * lisp/emacs-lisp/package.el: Doc fix.
+
+2021-04-21 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-imm-equal-test): Style fix.
+
+2021-04-21 Philip K <philipk@posteo.net>
+
+ Make outline commands repeatable (bug#47878)
+
+ * lisp/outline.el (outline-navigation-repeat-map): Add new map.
+ (outline-editing-repeat-map): Add new map.
+
+2021-04-21 Mattias Engdegård <mattiase@acm.org>
+
+ Don't erroneously declare `mark` as error-free
+
+ * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns)
+ (side-effect-and-error-free-fns):
+ `mark` is side-effect-free but not error-free.
+
+2021-04-21 Juri Linkov <juri@linkov.net>
+
+ * lisp/isearch.el (isearch-forward-thing-at-point): New command (bug#39512).
+
+ (search-map): Bind "M-s M-." to isearch-forward-thing-at-point.
+ (isearch-forward-thing-at-point): New defcustom.
+
+2021-04-21 Juri Linkov <juri@linkov.net>
+
+ * lisp/thingatpt.el (region): Put property bounds-of-thing-at-point, bug#39512
+
+2021-04-21 Philipp Stephani <phst@google.com>
+
+ Remove a self-reference from the Emacs Lisp manual.
+
+ * doc/lispref/minibuf.texi (Programmed Completion): Remove
+ self-reference.
+
+2021-04-21 Stefan Kangas <stefan@marxist.se>
+
+ Improve error message for missing Info manual
+
+ * lisp/info.el (Info-find-file): Improve error message for missing
+ Info manual. (Bug#46236)
+ Fix suggested by Eli Zaretskii <eliz@gnu.org>.
+
+2021-04-21 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (batch-byte-native-compile-for-bootstrap): Fix typo.
+
+2021-04-21 Andrea Corallo <akrl@sdf.org>
+
+ Fix native compiler string hash consing strategy (bug#47868)
+
+ * test/src/comp-tests.el (comp-test-47868-1): Add new test.
+ * test/src/comp-resources/comp-test-funcs.el (comp-test-47868-1-f)
+ (comp-test-47868-2-f): New functions.
+ * lisp/emacs-lisp/comp.el (comp-imm-equal-test): Define new hash
+ tanble test.
+ (comp-data-container): Use it.
+ (comp-final, comp-run-async-workers): have comp required before
+ reading dumped hashes so that `comp-imm-equal-test' is defined.
+
+2021-04-21 Andrea Corallo <akrl@sdf.org>
+
+ Introduce `sxhash-equal-including-properties'.
+
+ * src/fns.c (collect_interval): Move it upwards.
+ (Fsxhash_equal_including_properties): New function.
+ (syms_of_fns): Register `sxhash-equal-including-properties'.
+ * etc/NEWS: Add 'sxhash-equal-including-properties'.
+
+2021-04-21 Philip K <philipk@posteo.net>
+
+ sgml-mode: Only set sgml-xml-mode if guessed to be an XML file
+
+ * lisp/textmodes/sgml-mode.el (sgml-mode): Don't override
+ sgml-xml-mode if the result of the guess is used as the buffer local
+ value. (Bug#47877)
+
+2021-04-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Fix bug#47925
+
+ In order to correctly detect the case of the "new style" with an empty body,
+ remove the old optional arguments `init-value`, `lighter`, and `keymap`,
+ so we can distinguish the "nil arg" from the "absent arg" cases.
+
+2021-04-20 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Avoid abbrev expansion in variable names
+
+ * lisp/progmodes/cperl-mode.el (cperl-electric-else): Don't expand
+ scalar variables like '$continue' as keywords. (Bug#47902)
+ * test/lisp/progmodes/cperl-mode-tests.el
+ (cperl-test-hyperactive-electric-else): Verify that keywords are
+ expanded but variable names aren't.
+
+2021-04-20 Juri Linkov <juri@linkov.net>
+
+ * lisp/wdired.el (wdired--self-insert): Put symbol property delete-selection.
+
+ * lisp/isearch.el (isearch-post-command-hook): Revert ff796823e5 (bug#47894).
+
+2021-04-20 Jonas Bernoulli <jonas@bernoul.li>
+
+ Add new library transient.el
+
+ * lisp/transient.el: New file.
+
+2021-04-20 Eli Zaretskii <eliz@gnu.org>
+
+ Fix Rmail-MIME size estimations
+
+ The quoted-printable estimation was obviously wrong: the size becomes
+ smaller when decoded, not larger...
+ * lisp/mail/rmailmm.el (rmail-mime-set-bulk-data): Fix estimations
+ of decoded MIME attachment.
+
+2021-04-20 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/minibuf.c (Fread_no_blanks_input): Move to `minibuffer.el`
+
+ * src/keymap.c (syms_of_keymap):
+ * lisp/minibuffer.el (minibuffer-local-ns-map): Move declaration
+ to initialization.
+ (read-no-blanks-input): Move from `minibuf.c`.
+
+2021-04-20 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/minibuffer.el (minibuffer-mode-map): Make it an alias
+
+ Avoid creating this "dummy" keymap by making it an alias of
+ the parent keymap of all minibuffer keymaps.
+
+2021-04-20 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/minibuf.c (read_minibuf): Change multibyte more safely
+
+ We used to `bset_enable_multibyte_characters` while the buffer is not
+ empty, putting the buffer temporarily in an inconsistent state.
+
+ Further simplifications along the way: Prefer re-using local var `histvar`
+ and let `insert` do the unibyte<->multibyte conversion if needed.
+
+2021-04-20 Eli Zaretskii <eliz@gnu.org>
+
+ Improve filling-related documentation
+
+ * doc/emacs/text.texi (Auto Fill, Fill Commands): Mention special
+ line-breaking rules for CJK characters and the kinsoku rules.
+ (Bug#47856)
+
+ * lisp/textmodes/fill.el
+ (fill-separate-heterogeneous-words-with-space): Doc fix.
+
+2021-04-20 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix localization problem in Tramp
+
+ * lisp/net/tramp-sh.el (tramp-get-remote-stat): Use localized
+ quotation characters for check.
+
+2021-04-20 Alan Mackenzie <acm@muc.de>
+
+ Fix bug #47781: (window-list-1 nil t) wrongly returned nil.
+
+ * src/window.c (candidate_window_p): In the WINDOW_P (all_frames) branch of
+ the conditional, insert "EQ (minibuf, Qt)" in the requisite place.
+
+2021-04-20 Alan Mackenzie <acm@muc.de>
+
+ Introduce and use minibuffer-mode. This fixes bug #47150
+
+ * lisp/minibuffer.el (minibuffer-mode): New derived mode.
+
+ * src/minibuf.c (syms_of_minibuf): New DEFSYMs Qminibuffer_mode,
+ Qminibuffer_inactive_mode, Qminibuffer_completing_file_name,
+ Qselect_frame_set_input_focus, Qadd_to_history.
+ (read_minibuf, set_minibuffer_mode, read_minibuf_unwind): Use the new DEFSYMs
+ in place of continual interning.
+ (set_minibuffer_mode): Put an active minibuffer into minibuffer-mode rather
+ than fundamental-mode.
+
+ * doc/emacs/mini.texi (Minibuffer Edit): Mention minibuffer-mode.
+
+ * doc/lispref/minibuf.texi (Intro to Minibuffers): Add a paragraph about
+ minibuffer-mode.
+
+ * etc/NEWS (Incompatible Lisp Changes in Emacs 28.1): Add an entry.
+
+2021-04-20 Daniel Mendler <mail@daniel-mendler.de>
+
+ (completion-all-sorted-completions): Additional alphabetical sorting
+
+ Even in the cases where it does not make much visible difference,
+ it brings the benefit of making the result deterministic.
+
+ * lisp/minibuffer.el (minibuffer--sort-by-length-alpha): New function.
+ (minibuffer--sort-by-position): New function extracted from
+ `completion-all-sorted-completions`.
+ (completion-all-sorted-completions): Use use them.
+
+2021-04-19 Daniel Mendler <mail@daniel-mendler.de>
+
+ minibuffer.el: Use completion--message instead of minibuffer-message
+
+ * lisp/minibuffer.el: Use completion--message consistently for the messages
+ "Incomplete", "Sole completion" and "No completions".
+
+2021-04-19 Philipp Stephani <phst@google.com>
+
+ Seccomp filter: deal with arch_prctl(ARCH_CET_STATUS, ...).
+
+ The dynamic loader of GNU libc 2.28 uses this system call to
+ initialize CPU information, see
+ https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86/cpu-features.c;hb=glibc-2.28#l28.
+ Simulating an older kernel by returning EINVAL should be the most
+ harmless rule here.
+
+ The ARCH_CET_STATUS symbol isn't yet exposed by the kernel headers;
+ see the FIXME at the top of
+ https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86/include/asm/prctl.h;hb=glibc-2.28.
+
+ * lib-src/seccomp-filter.c (ARCH_CET_STATUS): Define if not
+ already present. Inline the value because there doesn't seem to
+ be a header file exporting this constant yet.
+ (main): Make ARCH_CET_STATUS subfunction of arch_prctl return EINVAL.
+
+2021-04-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/minibuffer.el (completion-all-sorted-completions): Fix last change
+
+2021-04-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/minibuffer.el (minibuffer--sort-by-key): New function
+
+ (completion-all-sorted-completions): Use it.
+
+2021-04-19 Daniel Mendler <mail@daniel-mendler.de>
+
+ completion-all-sorted-completions: Fix sorting performance bug
+
+ * lisp/minibuffer.el (completion-all-sorted-completions): Use hash
+ table for sorting by history position, O(m+n*log(n)) instead of
+ O(m*n*log(n)) with history length `m` and candidate length `n`.
+
+2021-04-19 Daniel Mendler <mail@daniel-mendler.de>
+
+ completing-read: If HIST is the symbol `t', history is not recorded.
+
+ * lisp/minibuffer.el (completion-all-sorted-completions): Check if
+ `minibuffer-history-variable` is `t`
+ * src/minibuf.c (completing-read): Update docstring
+ * doc/lispref/minibuf.texi: Update documentation of
+ `read-from-minibuffer` and `completing-read`
+
+2021-04-19 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into native-comp
+
+2021-04-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Add Tramp recompilation
+
+ * doc/misc/tramp.texi (Frequently Asked Questions): Refer to GNU
+ ELPA Tramp README.
+
+ * lisp/net/tramp-cmds.el (tramp-recompile-elpa-command-completion-p)
+ (tramp-recompile-elpa): New defuns. Add property `completion-predicate'.
+
+2021-04-19 Stefan Kangas <stefan@marxist.se>
+
+ Don't hard-code "~/.emacs.d/" in two more places
+
+ * lisp/gnus/gnus-group.el (gnus-read-ephemeral-bug-group):
+ * lisp/progmodes/js.el (js-js-tmpdir): Don't hard-code
+ "~/.emacs.d/".
+
+2021-04-19 Philip K <philipk@posteo.net>
+
+ Don't hard-code "~/.emacs.d/" in rcirc.el
+
+ * lisp/net/rcirc.el (rcirc-log-directory): Use
+ locate-user-emacs-file. (Bug#47880)
+
+2021-04-18 Philipp Stephani <phst@google.com>
+
+ Factor out a helper macro to create a temporary directory.
+
+ This is a useful abstraction, and saves a few levels of indentation in
+ the test body.
+
+ * test/lisp/progmodes/project-tests.el
+ (project-tests--with-temporary-directory): New helper macro.
+ (project/quoted-directory): Use it.
+
+2021-04-18 Philipp Stephani <phst@google.com>
+
+ Add quoted filename support to 'project-find-regexp' (Bug#47799).
+
+ This is only a band-aid; it would be better to fix xref.el to work
+ with quoted filenames as well.
+
+ * lisp/progmodes/project.el (project--find-regexp-in-files): Unquote
+ filenames before passing them to 'xref-matches-in-files'.
+ * test/lisp/progmodes/project-tests.el (project/quoted-directory):
+ Also test 'project-find-regexp'.
+
+2021-04-18 Philipp Stephani <phst@google.com>
+
+ Extend project test so that 'project-current' works.
+
+ * test/lisp/progmodes/project-tests.el (project/quoted-directory):
+ Verify that 'project-current' returns the right project.
+
+2021-04-18 Philipp Stephani <phst@google.com>
+
+ Skip a unit test that requires an external program if necessary.
+
+ * test/lisp/progmodes/project-tests.el (project/quoted-directory):
+ Skip if the 'find' program isn't available. The 'project-files'
+ function uses 'find' to obtain the list of project files.
+
+2021-04-18 Eli Zaretskii <eliz@gnu.org>
+
+ * src/emacs.c (main): Add back the call to init_callproc_1. (bug#47872)
+
+2021-04-18 Protesilaos Stavrou <info@protesilaos.com>
+
+ Update modus-themes to version 1.3.2
+
+ * doc/misc/modus-themes.org (COPYING): Reword to match the phrasing of
+ other manuals that are distributed with Emacs.
+
+ (Install from the archives)
+ (Sample configuration for use-package)
+ (Option for more bold constructs)
+ (Option for more slanted constructs)
+ (Option for syntax highlighting)
+ (Option for no font mixing)
+ (Option for links)
+ (Option for command prompt styles)
+ (Option for completion framework aesthetics)
+ (Option for fringe visibility)
+ (Option for language checkers)
+ (Option for org-habit graph styles)
+ (Option for line numbers (display-line-numbers-mode))
+ (Option for parenthesis matching (show-paren-mode))
+ (Option for diff buffer looks)
+ (Option for scaled headings)
+ (Option for variable-pitch font in UI elements)
+ (Option for variable-pitch font in headings)
+ (Case-by-case face specs using the themes' palette (DIY))
+ (Face specs at scale using the themes' palette (DIY))
+ (Font configurations for Org and others (DIY))
+ (Load theme depending on time of day): Minor markup changes for better
+ texi output.
+
+ (Option for mode line presentation): Document new possible values for
+ 'modus-themes-mode-line'.
+
+ (Option for line highlighting (hl-line-mode)): Document new
+ 'modus-themes-hl-line' variable, which supersedes
+ 'modus-themes-intense-hl-line'.
+
+ (Option for active region): Document new possible values for
+ 'modus-themes-region'.
+
+ (Option for org-mode block styles): Cite variables that affect
+ fontification.
+
+ (Option for the headings' overall style): Include the option of a
+ per-level nil value.
+
+ (Remap face with local value (DIY))
+ (Override colors (DIY)): Add sections.
+
+ (Full support for packages or face groups): Document newly supported packages
+
+ (Note for dimmer.el)
+ (Note for EWW and Elfeed fonts (SHR fonts)): Add notes.
+
+ (Acknowledgements): Add names of new contributors.
+
+ (GNU Free Documentation License): Add tags for html export.
+
+ * etc/themes/modus-operandi-theme.el (File)
+ * etc/themes/modus-vivendi-theme.el (File): Update to version 1.3.1
+
+ * etc/themes/modus-themes.el (modus-themes-operandi-colors)
+ (modus-themes-vivendi-colors)
+ (modus-theme-subtle-red)
+ (modus-themes-subtle-red)
+ (modus-theme-subtle-green)
+ (modus-themes-subtle-green)
+ (modus-theme-subtle-yellow)
+ (modus-themes-subtle-yellow)
+ (modus-theme-subtle-blue)
+ (modus-themes-subtle-blue)
+ (modus-theme-subtle-magenta)
+ (modus-themes-subtle-magenta)
+ (modus-theme-subtle-cyan)
+ (modus-themes-subtle-cyan)
+ (modus-theme-subtle-neutral)
+ (modus-themes-subtle-neutral)
+ (modus-theme-intense-red)
+ (modus-themes-intense-red)
+ (modus-theme-intense-green)
+ (modus-themes-intense-green)
+ (modus-theme-intense-yellow)
+ (modus-themes-intense-yellow)
+ (modus-theme-intense-blue)
+ (modus-themes-intense-blue)
+ (modus-theme-intense-magenta)
+ (modus-themes-intense-magenta)
+ (modus-theme-intense-cyan)
+ (modus-themes-intense-cyan)
+ (modus-theme-intense-neutral)
+ (modus-themes-intense-neutral)
+ (modus-theme-refine-red)
+ (modus-themes-refine-red)
+ (modus-theme-refine-green)
+ (modus-themes-refine-green)
+ (modus-theme-refine-yellow)
+ (modus-themes-refine-yellow)
+ (modus-theme-refine-blue)
+ (modus-themes-refine-blue)
+ (modus-theme-refine-magenta)
+ (modus-themes-refine-magenta)
+ (modus-theme-refine-cyan)
+ (modus-themes-refine-cyan)
+ (modus-theme-active-red)
+ (modus-themes-active-red)
+ (modus-theme-active-green)
+ (modus-themes-active-green)
+ (modus-theme-active-yellow)
+ (modus-themes-active-yellow)
+ (modus-theme-active-blue)
+ (modus-themes-active-blue)
+ (modus-theme-active-magenta)
+ (modus-themes-active-magenta)
+ (modus-theme-active-cyan)
+ (modus-themes-active-cyan)
+ (modus-theme-fringe-red)
+ (modus-themes-fringe-red)
+ (modus-theme-fringe-green)
+ (modus-themes-fringe-green)
+ (modus-theme-fringe-yellow)
+ (modus-themes-fringe-yellow)
+ (modus-theme-fringe-blue)
+ (modus-themes-fringe-blue)
+ (modus-theme-fringe-magenta)
+ (modus-themes-fringe-magenta)
+ (modus-theme-fringe-cyan)
+ (modus-themes-fringe-cyan)
+ (modus-theme-nuanced-red)
+ (modus-theme-nuanced-green)
+ (modus-theme-nuanced-yellow)
+ (modus-theme-nuanced-blue)
+ (modus-theme-nuanced-magenta)
+ (modus-theme-nuanced-cyan)
+ (modus-theme-special-cold)
+ (modus-theme-special-mild)
+ (modus-theme-special-warm)
+ (modus-theme-special-calm)
+ (modus-theme-diff-added)
+ (modus-theme-diff-changed)
+ (modus-theme-diff-removed)
+ (modus-theme-diff-refine-added)
+ (modus-theme-diff-refine-changed)
+ (modus-theme-diff-refine-removed)
+ (modus-theme-diff-focus-added)
+ (modus-theme-diff-focus-changed)
+ (modus-theme-diff-focus-removed)
+ (modus-theme-diff-heading)
+ (modus-theme-pseudo-header)
+ (modus-theme-mark-alt)
+ (modus-theme-mark-del)
+ (modus-theme-mark-sel)
+ (modus-theme-mark-symbol)
+ (modus-theme-heading-1)
+ (modus-theme-heading-2)
+ (modus-theme-heading-3)
+ (modus-theme-heading-4)
+ (modus-theme-heading-5)
+ (modus-theme-heading-6)
+ (modus-theme-heading-7)
+ (modus-theme-heading-8)
+ (modus-theme-hl-line)
+ (modus-theme-bold)
+ (modus-theme-slant)
+ (modus-theme-variable-pitch)
+ (modus-theme-graph-red-0)
+ (modus-theme-graph-red-1)
+ (modus-theme-graph-green-0)
+ (modus-theme-graph-green-1)
+ (modus-theme-graph-yellow-0)
+ (modus-theme-graph-yellow-1)
+ (modus-theme-graph-blue-0)
+ (modus-theme-graph-blue-1)
+ (modus-theme-graph-magenta-0)
+ (modus-theme-graph-magenta-1)
+ (modus-theme-graph-cyan-0)
+ (modus-theme-graph-cyan-1)
+ (modus-theme-lang-note)
+ (modus-theme-lang-warning)
+ (modus-theme-lang-error): Rename all internal faces.
+
+ (modus-themes-headings)
+ (modus-themes-fringes)
+ (modus-themes-lang-checkers)
+ (modus-themes-org-blocks)
+ (modus-themes-org-habit)
+ (modus-themes-mode-line)
+ (modus-themes-diffs)
+ (modus-themes-completions)
+ (modus-themes-prompts)
+ (modus-themes-intense-hl-line)
+ (modus-themes-hl-line)
+ (modus-themes-paren-match)
+ (modus-themes-syntax)
+ (modus-themes-links)
+ (modus-themes-region): Update defcustom.
+
+ (modus-themes--fringe):
+ (modus-themes--headings-choice):
+ (modus-themes--prompt):
+ (modus-themes--org-block-delim):
+ (modus-themes--mode-line-attrs):
+ (modus-themes--link):
+ (modus-themes--region):
+ (modus-themes--hl-line): Adjustments to internal functions.
+
+ (modus-themes-faces): Update faces.
+ (modus-themes-custom-variables): Update custom variables.
+
+2021-04-18 Eli Zaretskii <eliz@gnu.org>
+
+ * src/comp.c (fixup_eln_load_path): Simplify code.
+
+2021-04-18 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change
+
+ * src/emacs.c (load_pdump_find_executable): Fix the value of
+ CANDIDATE_SIZE when the final candidate is a symlink.
+
+2021-04-18 Philipp Stephani <phst@google.com>
+
+ Fix Seccomp filter on CentOS 8.3 (Bug#47828).
+
+ * lib-src/seccomp-filter.c (main): mmap: Also allow MAP_SHARED.
+
+2021-04-18 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/misearch.el (multi-isearch-pop-state): Doc fix.
+
+2021-04-18 Martin Rudalics <rudalics@gmx.at>
+
+ Avoid selecting tooltip windows and frames (Bug#47207)
+
+ * src/frame.c (do_switch_frame): Don't switch to a tooltip frame.
+ (Fselect_frame): Do not select a tooltip frame.
+ * src/w32fns.c (Fx_show_tip):
+ * src/xfns.c (Fx_show_tip): Set the tooltip window's
+ `no-other-window' parameter so `other-window' will skip it.
+ * src/window.c (select_window): Do not select a tooltip window.
+ (candidate_window_p): Make sure MINIBUF is live.
+ (decode_next_window_args): Make sure that W's frame's minibuffer
+ window is live before including it.
+ (Qno_other_window): New symbol.
+
+2021-04-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/debug.el (debug): Fix (bug#47588)
+
+ Don't bind `load-read-function` to nil but to its actual default value.
+ Actually, I'm not sure it's worth the trouble rebinding this var, but
+ if we do, then we should bind it to a valid value rather than to nil.
+
+ * lisp/emacs-lisp/edebug.el (edebug--eval-defun): Re-install our advice
+ if needed.
+
+2021-04-17 Philipp Stephani <phst@google.com>
+
+ Attempt to print some debugging information on Seccomp failures.
+
+ Try to search the audit log as well as recent core dumps.
+
+ * test/src/emacs-tests.el (emacs-tests--seccomp-debug): New helper
+ function.
+ (emacs-tests/seccomp/allows-stdout)
+ (emacs-tests/seccomp/forbids-subprocess)
+ (emacs-tests/bwrap/allows-stdout): Use it.
+
+2021-04-17 Eli Zaretskii <eliz@gnu.org>
+
+ * src/emacs.c (load_pdump): Fix unconditional references to strip_suffix.
+
+2021-04-17 Michael Albinus <michael.albinus@gmx.de>
+
+ Make stderr in Tramp's make-process more robust
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process): Wrap about
+ error in inserting stderr file.
+
+ * lisp/net/tramp.el (tramp-handle-make-process): Fix docstring.
+
+2021-04-17 Eli Zaretskii <eliz@gnu.org>
+
+ * src/emacs.c (load_pdump): Fix compilation on picky-complier platforms.
+
+2021-04-17 Daniel Martín <mardani29@yahoo.es>
+
+ Fix reference to "yanking" in the main Emacs manual
+
+ * doc/emacs/emacs.texi (Top): Yanking is alternatively known as
+ pasting, not copying. (Bug#47839).
+
+2021-04-17 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Tweak further
+
+ Suggested by Lars Ingebrigtsen <larsi@gnus.org>.
+
+2021-04-17 Eli Zaretskii <eliz@gnu.org>
+
+ Fix loading *.eln files when Emacs is installed via symlinks
+
+ * src/emacs.c (real_filename, set_invocation_vars)
+ (init_vars_for_load): Functions deleted; callers adjusted.
+ (init_cmdargs): Put back all the code which was extracted into
+ set_invocation_vars.
+ (load_pdump_find_executable): Make sure the return value has any
+ symlinks in it expanded.
+ (load_pdump): Accept only 2 arguments, not 3. Determine both the
+ file name of the Emacs executable and of the dump file in
+ synchronized manner, so that if we decided to look for the dump
+ file in its hardcoded installation directory, the directory of the
+ Emacs executable will also be where we expect it to be installed.
+ Pass only 2 arguments to pdumper_load. (Bug#47800) (Bug#44128)
+ * src/pdumper.c (dump_do_dump_relocation): Use emacs_execdir
+ instead of Vinvocation_directory to produce absolute file names of
+ *.eln files that are recorded in the pdumper file. Pass the full
+ .eln file name to fixup_eln_load_path.
+ (pdumper_set_emacs_execdir) [HAVE_NATIVE_COMP]: New function.
+ (pdumper_load) [HAVE_NATIVE_COMP]: Call pdumper_set_emacs_execdir.
+ * src/comp.c (fixup_eln_load_path): Use Fsubstring_no_properties
+ instead of Fsubstring. No need to cons a file name, as the caller
+ already did that. Use explicit const string to avoid "magic"
+ values.
+
+ * lisp/startup.el (normal-top-level): Use expand-file-name instead
+ of concat. Decode comp-eln-load-path and expand-file-name its
+ members.
+
+2021-04-17 Alan Third <alan@idiocy.org>
+
+ Fix :scale's affect on :width and :height (bug#47819)
+
+ * src/image.c (compute_image_size): Multiply width and height values
+ by scale.
+
+2021-04-17 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'map-y-or-n-p'
+
+ * lisp/emacs-lisp/map-ynp.el (map-y-or-n-p): Doc fix. (Bug#47833)
+
+ * doc/lispref/minibuf.texi (Multiple Queries): Fix the wording in
+ the description of 'map-y-or-n-p'.
+
+2021-04-17 Martin Rudalics <rudalics@gmx.at>
+
+ Don't allow quitting while rebuilding Vwindow_list (Bug#47244)
+
+ * src/window.c (window_list, next_window, window_list_1): Don't
+ allow quitting in Fnconc and Fmemq (Bug#47244).
+
+2021-04-17 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Improve `C-h f` output
+
+ Suggested by Michael Heerdegen <michael_heerdegen@web.de>.
+
+2021-04-17 Stefan Kangas <stefan@marxist.se>
+
+ Cleanup in em-extra.el
+
+ * lisp/eshell/em-xtra.el (cl-lib): Require.
+ (pcomplete, compile): Remove unnecessary requires.
+ (eshell/substitute, eshell/count, eshell/mismatch, eshell/union)
+ (eshell/intersection, eshell/set-difference)
+ (eshell/set-exclusive-or): Use cl-lib. Doc fixes.
+ (eshell/ff, eshell/gf, eshell/expr): Quote function symbols as such.
+ (eshell/expr): Assume 'calc-eval' is always available.
+
+2021-04-16 Alan Mackenzie <acm@muc.de>
+
+ Check minibuffer windows are live windows, rather than assuming it
+
+ This partly fixes bug #47207.
+
+ * src/minibuf.c (choose_minibuf_frame, move_minibuffers_onto_frame)
+ (read_minibuf (twice), read_minibuf_unwind): Before using a frame's
+ ->minibuffer_window field, check it is valid with WINDOW_LIVE_P.
+ (choose_minibuf_frame): Remove the emacs_abort for a null minibuffer.
+
+2021-04-16 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ eedad01b4b (origin/emacs-27) Fix typos in manuals
+ 24d214652e Fix description of momentary message display
+
+2021-04-16 Ashish SHUKLA <ashish@FreeBSD.org>
+
+ * lisp/emacs-lisp/comp.el (comp-effective-async-max-jobs): Handle BSD.
+
+2021-04-16 Robert Pluim <rpluim@gmail.com>
+
+ Improve docstring of 'frame-scale-factor'
+
+ * src/frame.c (Fframe_scale_factor): Explain what happens when the
+ FRAME argument is nil.
+
+2021-04-16 Dmitry Gutov <dgutov@yandex.ru>
+
+ Improve quoting of directory names in project/xref
+
+ * lisp/progmodes/project.el (project--files-in-directory):
+ Quote LOCALDIR a bit earlier, to affect
+ xref--find-ignores-arguments as well (bug#47799).
+
+ * lisp/progmodes/xref.el (xref-matches-in-directory):
+ Quote the dir passed to xref--rgrep-command.
+
+2021-04-16 Dmitry Gutov <dgutov@yandex.ru>
+
+ project--files-in-directory: Handle errors reported by 'find'
+
+ * lisp/progmodes/project.el (project--files-in-directory):
+ Handle errors reported by 'find' (bug#47799).
+
+2021-04-15 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'garbage-collect-maybe'
+
+ * src/alloc.c (Fgarbage_collect_maybe): No longer interactive.
+ (Bug#47805)
+
+2021-04-15 Alan Third <alan@idiocy.org>
+
+ Allow use of em in image spec sizes
+
+ * src/image.c (image_get_dimension): New function.
+ (compute_image_size): Use image_get_dimension to set the sizes, and
+ pass in the image struct instead of just the spec.
+ (image_set_transform):
+ (imagemagick_load_image):
+ (svg_load_image): Use the image instead of the spec in compute_image_size.
+ (syms_of_image): Add 'em' as a symbol.
+
+2021-04-15 Philipp Stephani <phst@google.com>
+
+ Improve project support for quoted directory names (Bug#47799)
+
+ * lisp/progmodes/project.el (project--files-in-directory): Unquote
+ directory name before passing it to 'find'.
+ (project--remote-file-names): Requote local filenames if the original
+ directory is quoted.
+ * test/lisp/progmodes/project-tests.el (project/quoted-directory): New
+ unit test.
+
+2021-04-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/bindat.el: Allow non-fixed size of `strz`
+
+ (bindat--unpack-strz): Allow `len` to be nil.
+ (bindat--pack-strz): New function.
+ (bindat--type) <strz>: Make `len` arg optional.
+ (bindat-type): Adjust debug spec and docstring accordingly.
+
+ * doc/lispref/processes.texi (Bindat Types): Adjust accordingly.
+
+2021-04-15 Mattias Engdegård <mattiase@acm.org>
+
+ Add condition-case success handler (bug#47677)
+
+ Allow a condition-case handler on the form (:success BODY) to be
+ specified as the success continuation of the protected form, with
+ the specified variable bound to its result.
+
+ * src/eval.c (Fcondition_case): Update the doc string.
+ (internal_lisp_condition_case): Implement in interpreter.
+ (syms_of_eval): Defsym :success.
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-condition-case):
+ Implement in byte-compiler.
+ * lisp/emacs-lisp/cl-macs.el (cl--self-tco): Allow self-TCO
+ from success handler.
+ * doc/lispref/control.texi (Handling Errors): Update manual.
+ * etc/NEWS: Announce.
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases)
+ (bytecomp-condition-case-success):
+ * test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs--labels):
+ Add test cases.
+
+2021-04-15 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Put debug specs inside declare forms. Add missing debug specs.
+
+ * lisp/progmodes/cc-bytecomp.el, lisp/progmodes/cc-cmds.el,
+ lisp/progmodes/cc-defs.el, lisp/progmodes/cc-engine.el,
+ lisp/progmodes/cc-fonts.el, lisp/progmodes/cc-langs.el,
+ lisp/progmodes/cc-mode.el: Change the explicit def-edebug-spec for many macros
+ into a (declare (debug ...) ..) form. Add such forms to macros which were
+ previously lacking def-edebug-spec forms.
+
+2021-04-14 Andrea Corallo <akrl@sdf.org>
+
+ * configure.ac: Revert prev commit and fix native-comp NetBSD build.
+
+2021-04-14 Juri Linkov <juri@linkov.net>
+
+ repeat-echo-mode-line-string doesn't need risky-local-variable to keep props
+
+ (bug#47566)
+
+2021-04-14 Filipp Gunbin <fgunbin@fastmail.fm>
+
+ Java Mode: Change the syntax of character @ to prefix syntax
+
+ lisp/progmodes/cc-langs.el (c-make-mode-syntax-table): Change the syntax of @
+ as indicated.
+
+2021-04-14 Juri Linkov <juri@linkov.net>
+
+ * lisp/isearch.el (isearch-mouse-2): Let-bind isearch-mode to nil (bug#47755)
+
+2021-04-14 Juri Linkov <juri@linkov.net>
+
+ Don't error out when selection data is unavailable (bug#47642)
+
+ * src/xselect.c (x_get_window_property_as_lisp_data):
+ Display a message and return nil when data is not available.
+
+2021-04-14 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/gud.el (gud-repeat-map): New variable (bug#47688).
+
+ (gud-gdb): Populate gud-repeat-map with repeating keys.
+
+2021-04-14 Juri Linkov <juri@linkov.net>
+
+ * lisp/repeat.el: Add option to indicate repeat-mode in mode-line (bug#47566)
+
+ * lisp/repeat.el (repeat-echo-function): Rename from repeat-mode-echo.
+ Add choice repeat-echo-mode-line.
+ (repeat-in-progress): New variable.
+ (repeat-post-hook): Call repeat-echo-function with nil arg
+ at the end of repeating sequence.
+ (repeat-echo-message-string): New function with body from repeat-post-hook.
+ (repeat-echo-message): Rename from repeat-mode-message.
+ (repeat-echo-mode-line-string): New variable.
+ (repeat-echo-mode-line): New function.
+
+2021-04-14 Andrea Corallo <akrl@sdf.org>
+
+ * configure.ac: Fix native-comp FreeBSD build.
+
+2021-04-14 Eli Zaretskii <eliz@gnu.org>
+
+ Fix MS-Windows build following last change
+
+ * src/emacs.c (real_filename) [WINDOWSNT]: Fix off-by-one error
+ when allocating storage for a file name.
+
+2021-04-14 Andrea Corallo <akrl@sdf.org>
+
+ Fix native-comp startup for symliked binary (bug#44128)
+
+ * src/emacs.c (real_filename): New function.
+ (set_invocation_vars, load_pdump): Make use of.
+
+2021-04-14 Michael Albinus <michael.albinus@gmx.de>
+
+ Rearrange argument handling in Tramp scp calls.
+
+ * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-out-of-band):
+ Use `start-process' instead of `start-process-shell-command'.
+ (tramp-make-copy-program-file-name): Do not quote `localname'.
+
+ * test/lisp/net/tramp-tests.el (tramp-method-out-of-band-p): Declare.
+ (tramp--test-windows-nt-and-batch-p)
+ (tramp--test-windows-nt-and-pscp-psftp-p): Remove, and also all callees.
+ (tramp--test-windows-nt-and-out-of-band-p)
+ (tramp--test-windows-nt-and-scp-p): New defuns.
+ (tramp-test17-dired-with-wildcards)
+ (tramp-test40-special-characters)
+ (tramp-test40-special-characters-with-stat)
+ (tramp-test40-special-characters-with-perl)
+ (tramp-test40-special-characters-with-ls, tramp-test41-utf8)
+ (tramp-test41-utf8-with-stat, tramp-test41-utf8-with-perl)
+ (tramp-test41-utf8-with-ls): Use them.
+
+2021-04-14 Eli Zaretskii <eliz@gnu.org>
+
+ Add two optional arguments to 'string-width'
+
+ * src/character.c (Fstring_width, lisp_string_width): Accept two
+ optional arguments FROM and TO, to indicate the substring to be
+ considered.
+ (Fstring_width): Add caveats in the doc string about display
+ features ignored by the function. (Bug#47712)
+ * src/character.h (lisp_string_width): Update prototype.
+ * src/editfns.c (styled_format): Adjust call of lisp_string_width
+ to its changed signature.
+
+ * test/src/character-tests.el (character-test-string-width): New
+ file with tests for 'string-width'.
+
+ * doc/lispref/display.texi (Size of Displayed Text): Document
+ caveats of using 'string-width'.
+
+ * etc/NEWS: Announce the change.
+
+2021-04-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/xdisp.c (wset_update_mode_line): Move from `src/window.c`
+
+ Move that function next to its siblings. Also simplify it, since
+ after careful analysis it is now clear that the frame's title's update
+ is already handled elsewhere (in `prepare_menu_bars` and `redisplay_window`)
+ so we just need to make sure the `redisplay` bit is set.
+
+ * src/window.c (wset_update_mode_line): Move to `src/xdisp.c`.
+ * src/window.h (wset_update_mode_line): Declare.
+
+2021-04-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/nxml/xmltok.el (xmltok-defregexp): Don't quote lambda
+
+ * lisp/emacs-lisp/eieio-core.el (list-of): Don't quote lambda
+
+2021-04-13 Filipp Gunbin <fgunbin@fastmail.fm>
+
+ * doc/lispref/keymaps.texi (Translation Keymaps): Fix small misprint
+
+ * doc/lispref/processes.texi: Fix small misprint
+
+2021-04-13 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Improvements to message-syntax-checks docs and options
+
+ * doc/misc/message.texi: Move the manual entry from the "News Headers"
+ section to the "Message Headers" section, as it is generally
+ applicable, not just to News.
+ * lisp/gnus/message.el (message-syntax-checks): Add an explicit alist
+ type specifying the valid options; point to the manual for more
+ information.
+
+2021-04-13 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/textmodes/two-column.el: Address FIXME
+
+ (2C-associate-buffer): Move minibuffer interactive to the `interactive` spec.
+
+2021-04-13 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/textmodes/paragraphs.el (multiple-lines): Remove mistaken declaration
+
+ (forward-paragraph): Remove unused var `multiple-lines`.
+
+2021-04-13 Eli Zaretskii <eliz@gnu.org>
+
+ Resurrect mouse-highlight of close buttons on tab-bar
+
+ * src/w32term.c (w32_draw_image_relief): Support tab-bar drawing
+ with relief as xterm.c does.
+
+ * src/xdisp.c (handle_tab_bar_click): Access the mouse-highlight
+ info. Call show_mouse_face to show the button in the pressed or
+ the released state, according to value of DOWN_P.
+ (note_tab_bar_highlight): Function added back.
+ (note_mouse_highlight): Call note_tab_bar_highlight when the mouse
+ pointer is in the tab-bar window.
+ (show_mouse_face): Return immediately if mouse_face_window is not
+ set up in HLINFO. This avoids rare assertion violations.
+
+2021-04-13 Eli Zaretskii <eliz@gnu.org>
+
+ Fix typos in manuals
+
+ * doc/misc/eshell.texi (Completion):
+ * doc/lispref/objects.texi (Mutability): Fix typos. (Bug#47738)
+
+2021-04-13 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into native-comp
+
+2021-04-13 Andrea Corallo <akrl@sdf.org>
+
+ Fix two comp-cstr tests
+
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Fix test 53 70.
+
+2021-04-13 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-union-1-no-mem): (not null) => t.
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-normalize-valset): Remove duplicates.
+
+2021-04-13 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/comint.el: Add `font-lock-face` to `rear-nonsticky`
+
+ (comint--prompt-rear-nonsticky): New const.
+ (comint-send-input, comint-output-filter): Use it.
+
+2021-04-13 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Don't version-control generated file `grammat-wy.el`
+
+ This file is needed for CEDET's bootstrap, tho, so we now keep a copy of it
+ under version control in `gram-wy-boot.el`, very much like we do with
+ the `ldefs-boot.el` copy of `loaddefs.el`.
+
+ * lisp/cedet/semantic/grm-wy-boot.el: Rename from
+ `lisp/cedet/semantic/grammar-wy.el`.
+
+ * lisp/cedet/semantic/grammar.el: Load `grm-wy-boot.el` if
+ `grammar-wy.el` hasn't been generated yet.
+
+ * admin/update_autogen: Also refresh `grm-wy-boot.el`.
+
+ * admin/grammars/Makefile.in (WISENT): Add `grammar-wy.el` to the
+ generated files.
+
+ * .gitignore: Add `grammar-wy.el`.
+
+2021-04-13 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/minibuffer.el (completion-table-with-quoting): Fix bug#47678
+
+2021-04-12 Wilson Snyder <wsnyder@wsnyder.org>
+
+ * lisp/progmodes/verilog-mode.el (vl-memory): Add missing defvar.
+
+2021-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/smie.el: Fix URL. Remove redundant `:group` args
+
+ (smie-indent-forward-token): Improve error message.
+ (smie--funcall): New function.
+ (smie-indent-calculate): Use it.
+
+2021-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/memory-report.el (memory-report--object-size-1): Simplify
+
+ * lisp/emacs-lisp/float-sup.el (pi): Actually mark it as obsolete
+
+ * lisp/emacs-lisp/edebug.el (edebug--frame): Move docstring where it belongs
+
+2021-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/vt-control.el: Avoid `called-interactively-p`
+
+ (vt-keypad-on, vt-keypad-off): Use the `tell` arg instead.
+ (vt-numlock): Add `tell` arg.
+
+2021-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/files.el (file-modes-number-to-symbolic): Add `filetype` arg.
+
+ * lisp/tar-mode.el (tar-header-block-summarize): Use it.
+ (tar-grind-file-mode): Declare obsolete.
+
+2021-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/frame.el (delete-other-frames): Add universal prefix `iconify` arg
+
+ (frame--current-backround-mode): New function,
+ extracted from `frame-set-background-mode`. Use `color-dark-p`.
+ (frame-set-background-mode): Use it.
+
+2021-04-12 Juri Linkov <juri@linkov.net>
+
+ * lisp/repeat.el (repeat-mode-echo): New defcustom.
+
+ (repeat-post-hook): Use it.
+ (repeat-mode-message): New function (bug#47566).
+ (repeat-post-hook): Use real-this-command instead of this-command
+ to handle e.g. rectangle-exchange-point-and-mark remapped to
+ exchange-point-and-mark (bug#47688).
+
+2021-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/dynamic-setting.el: Add missing footer
+
+ * lisp/comint.el (comint-strip-ctrl-m): Avoid `called-interactively-p`
+
+2021-04-12 Glenn Morris <rgm@gnu.org>
+
+ * lisp/strokes.el (strokes-mode): Fix typo in previous.
+
+2021-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ (define-minor-mode): Warn about use of pre-Emacs-21 style args
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode):
+ Use `advertised-calling-convention` to avoid promoting the old
+ style arguments. Emit a wanring when old-style arguments are used.
+ Massage the docstring accordingly.
+ * doc/lispref/modes.texi (Defining Minor Modes): Document the keyword
+ arguments rather than the old-style positional arguments.
+
+2021-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/vhdl-mode.el: Add note about XEmacs compatibility
+
+2021-04-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust verilog-mode to changes in the completion framework
+
+ * lisp/progmodes/verilog-mode.el (verilog-func-completion): Don't
+ bug out on `C-M-i' (which expects no point movement) (bug#47652).
+ (verilog-declaration-end): There may be no semicolons; don't bug out.
+
+2021-04-12 Shitikanth Kashyap <shitikanth1@gmail.com> (tiny change)
+
+ Fix python-shell-switch-to-shell redisplay bug
+
+ * lisp/progmodes/python.el (python-shell-switch-to-shell):
+ Redisplay the switched-to window faster (bug#47679).
+
+2021-04-12 Ralph Schleicher <rs@ralph-schleicher.de>
+
+ Add command in eww to toggle images
+
+ * lisp/net/eww.el (eww-toggle-images): New function.
+ (eww-mode-map): Add key binding and menu entry.
+ * lisp/net/shr.el (shr-inhibit-images): Make it customizable.
+ * doc/misc/eww.texi (Basics): Document eww-toggle-images.
+ Fix index entries for shr-use-fonts and shr-use-colors.
+ (Advanced): Document shr-inhibit-images
+ (bug#47705).
+
+2021-04-12 Junya Takahashi <jutakat@gmail.com> (tiny change)
+
+ Fix args-out-of-range error in epa-file-insert-file-contents
+
+ * lisp/epa-file.el (epa-file-insert-file-contents): Don't bug out
+ on a region that's longer than the file (bug#47718).
+
+2021-04-12 Philipp Stephani <phst@google.com>
+
+ * lib-src/seccomp-filter.c: Add missing headers.
+
+2021-04-12 Philipp Stephani <phst@google.com>
+
+ Generate Seccomp filters only if we have the necessary constants.
+
+ If we're missing SECCOMP_SET_MODE_FILTER, the seccomp-filter build
+ fails. Reuse the existing HAVE_SECCOMP configuration variable, which
+ checks for these macros.
+
+ * configure.ac (HAVE_SECCOMP): Substitute in Makefile.in.
+ * lib-src/Makefile.in (HAVE_SECCOMP): New variable.
+ (SECCOMP_FILTER): Define only if HAVE_SECCOMP.
+
+2021-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/**/*.el: Avoid positional args to `define-minor-mode`
+
+ Back in Emacs-21.1, `define-minor-mode` grew keywords arguments to
+ replace its old positional arguments. Let's make sure we don't use
+ the old-style any more.
+
+ * lisp/org/ox-beamer.el (org-beamer-mode-map): Move initialization
+ into declaration.
+ (org-beamer-mode):
+ * lisp/textmodes/tildify.el (tildify-mode):
+ * lisp/textmodes/sgml-mode.el (html-autoview-mode):
+ * lisp/textmodes/rst.el (rst-minor-mode):
+ * lisp/textmodes/remember.el (remember-notes-mode):
+ * lisp/textmodes/ispell.el (ispell-minor-mode):
+ * lisp/tar-mode.el (tar-subfile-mode):
+ * lisp/strokes.el (strokes-mode):
+ * lisp/so-long.el (so-long-minor-mode):
+ * lisp/shell.el (shell-dirtrack-mode):
+ * lisp/scroll-all.el (scroll-all-mode):
+ * lisp/ruler-mode.el (ruler-mode):
+ * lisp/rect.el (rectangle-mark-mode):
+ * lisp/progmodes/sh-script.el (sh-electric-here-document-mode):
+ * lisp/outline.el (outline-minor-mode):
+ * lisp/org/org.el (org-cdlatex-mode):
+ * lisp/org/org-table.el (org-table-header-line-mode)
+ (org-table-follow-field-mode, orgtbl-mode):
+ * lisp/org/org-src.el (org-src-mode):
+ * lisp/org/org-list.el (org-list-checkbox-radio-mode):
+ * lisp/org/org-indent.el (org-indent-mode):
+ * lisp/org/org-capture.el (org-capture-mode):
+ * lisp/obsolete/pc-select.el (pc-selection-mode):
+ * lisp/obsolete/iswitchb.el (iswitchb-mode):
+ * lisp/net/rcirc.el (rcirc-omit-mode, rcirc-multiline-minor-mode)
+ (rcirc-track-minor-mode):
+ * lisp/net/goto-addr.el (goto-address-mode, goto-address-prog-mode):
+ * lisp/image-mode.el (image-minor-mode):
+ * lisp/ibuf-ext.el (ibuffer-auto-mode):
+ * lisp/gnus/gnus-cite.el (gnus-message-citation-mode):
+ * lisp/font-core.el (font-lock-mode):
+ * lisp/erc/erc.el (define-erc-module):
+ * lisp/erc/erc-track.el (erc-track-minor-mode):
+ * lisp/erc/erc-fill.el (erc-fill-mode):
+ * lisp/epa-mail.el (epa-mail-mode):
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-minor-mode):
+ * lisp/dirtrack.el (dirtrack-mode, dirtrack-debug-mode):
+ * lisp/dired-aux.el (dired-isearch-filenames-mode):
+ * lisp/cedet/semantic/idle.el (semantic-idle-scheduler-mode):
+ * lisp/cedet/semantic/decorate/mode.el (semantic-decoration-mode):
+ * lisp/autoarg.el (autoarg-mode, autoarg-kp-mode):
+ * lisp/vc/pcvs.el (cvs-minor-mode):
+ Avoid old-style positional args to `define-minor-mode`.
+
+2021-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/message.el: Give non-nil defaults for function vars
+
+ Also prefer #' to quote functions.
+
+ (message-send-rename-function, message-reply-to-function)
+ (message-wide-reply-to-function, message-followup-to-function):
+ Use a non-nil default value so it can be used with `add-function`.
+ (message-do-send-housekeeping): Tweak accordingly.
+ (message-get-reply-headers): Simplify by η-reduction.
+
+2021-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/eshell/esh-util.el: Require `seq`
+
+ Also remove redundant `:group` args and tweak comment
+
+2021-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/eshell/esh-proc.el (eshell-kill-process-function): Use `remove-hook`
+
+ Also remove redundant `:group` args
+
+2021-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/mail/rmailmm.el (rmail-mime): Simplify interactive spec
+
+ * lisp/progmodes/sql.el (sql-mode-ansi-font-lock-keywords): Fix declaration
+
+2021-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/vc/log-edit.el (log-edit-diff-function): Give non-nil default
+
+ (log-edit-show-diff): Simplify accordingly.
+
+2021-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/bug-reference.el: Avoid old-style `define-minor-mode`
+
+ (bug-reference-mode, bug-reference-prog-mode): Remove redundant args.
+
+2021-04-11 Philipp Stephani <phst@google.com>
+
+ * src/emacs.c (load_seccomp): Consistently check for nonzero result
+
+2021-04-11 Philipp Stephani <phst@google.com>
+
+ Add a variant of the Seccomp filter file that allows 'execve'.
+
+ This is useful when starting Emacs with a Seccomp filter enabled,
+ e.g. using 'bwrap'.
+
+ * lib-src/seccomp-filter.c (main): Generate new Seccomp files.
+
+ * lib-src/Makefile.in (all)
+ (seccomp-filter.bpf seccomp-filter.pfc seccomp-filter-exec.bpf
+ seccomp-filter-exec.pfc): Generate new Seccomp files.
+
+ * .gitignore: Ignore new Seccomp files.
+
+ * test/src/emacs-tests.el (emacs-tests/bwrap/allows-stdout): New unit
+ test.
+
+2021-04-11 Philipp Stephani <phst@google.com>
+
+ * lib-src/seccomp-filter.c (main): Also allow O_NOFOLLOW.
+
+2021-04-11 Philipp Stephani <phst@google.com>
+
+ Don't attempt to generate Seccomp filter file in Linux < 4.14.
+
+ Only Linux 4.14 and later contain the required support for
+ SECCOMP_RET_KILL_PROCESS.
+
+ * lib-src/Makefile.in (SECCOMP_FILTER): Define only if we run at least
+ Linux 4.14.
+
+2021-04-11 Philipp Stephani <phst@google.com>
+
+ Seccomp filter: allow reading the current time (Bug#47708).
+
+ * lib-src/seccomp-filter.c (main): Allow reading the current time.
+
+2021-04-11 Andreas Schwab <schwab@linux-m68k.org>
+
+ Fix check for timer_getoverrun
+
+ * configure.ac (timer_getoverrun): Move check after gnulib checks
+ and use $LIB_TIMER_TIME during check.
+
+2021-04-11 Philipp Stephani <phst@google.com>
+
+ Use pkg-config to check for libseccomp.
+
+ We need at list version 2.4.0 of libseccomp for seccomp-filter.c to
+ build cleanly.
+
+ * configure.ac: Use pkg-config to check for libseccomp.
+ * lib-src/Makefile.in (HAVE_LIBSECCOMP, LIBSECCOMP_LIBS)
+ (LIBSECCOMP_CFLAGS): New variables.
+ (SECCOMP_FILTER, seccomp-filter$(EXEEXT)): Use them.
+
+2021-04-11 Philipp Stephani <phst@google.com>
+
+ Remove SCMP_FLTATR_CTL_LOG attribute from Seccomp filter.
+
+ Whether or not we log failing syscalls isn't security-critical, and we
+ shouldn't care.
+
+ * lib-src/seccomp-filter.c (main): Remove log attribute.
+
+2021-04-11 Philipp Stephani <phst@google.com>
+
+ Only attempt to generate seccomp filter files on x86-64 systems.
+
+ The seccomp filters are always architecture-specific, and
+ seccomp-filter.c right now only supports x86-64.
+
+ * lib-src/Makefile.in (SECCOMP_FILTER): New variable.
+ (DONT_INSTALL, all, seccomp-filter$(EXEEXT)): Use it.
+
+2021-04-11 Philipp Stephani <phst@google.com>
+
+ * lib-src/seccomp-filter.c: Print trailing newline.
+
+2021-04-11 Stefan Kangas <stefan@marxist.se>
+
+ * doc/lispref/elisp.texi (Top): Add missing entry.
+
+2021-04-11 Eli Barzilay <eli@barzilay.org>
+
+ Fix calculator-string-to-number yet again (bug#47694)
+
+ * lisp/calculator.el (calculator-string-to-number):
+ The last bugfix changed the code to just blindly replace ".e". This
+ has some minor problems like making "-." parse as 0.0 instead of -0.0,
+ and ".1.e1" is parsed as 1 instead of 0.1. Instead, replace the first
+ "." that is followed by a non-digit with ".0". Since this has had
+ several problems over the years, add some tests too. (Also, restore
+ the original if-indentation style.)
+
+2021-04-11 Mattias Engdegård <mattiase@acm.org>
+
+ Fix typo in cconv
+
+ * lisp/emacs-lisp/cconv.el (cconv-convert): Typo.
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases):
+ Add test case.
+
+2021-04-11 Philipp Stephani <phst@google.com>
+
+ Add another check for the required header <linux/filter.h>.
+
+ * configure.ac: Also check for <linux/filter.h>.
+ * src/emacs.c (SECCOMP_USABLE): Also check for <linux/filter.h>.
+
+2021-04-11 Philipp Stephani <phst@google.com>
+
+ Also check for needed seccomp macros.
+
+ It looks like these are not available on some versions of GNU/Linux,
+ breaking the build.
+
+ * configure.ac: Also check for needed seccomp macros.
+ * src/emacs.c (SECCOMP_USABLE): New macro.
+ (usage_message, main, standard_args): Use it.
+
+2021-04-11 Eli Zaretskii <eliz@gnu.org>
+
+ Fix handling of mouse clicks on tab-bar buttons
+
+ * src/xdisp.c (note_mouse_highlight): Don't attempt to highlight
+ tab-bar buttons.
+ (note_tab_bar_highlight): Function deleted: it had no effect on
+ display of tab-bar buttons.
+ (tab_bar_item_info): Mention all arguments in the commentary.
+ (get_tab_bar_item): Don't pay attention to mouse-highlight
+ information; instead, compare the button's index with the one
+ recorded in f->last_tab_bar_item.
+ (handle_tab_bar_click): Don't attempt to show tab-bar buttons in
+ pressed or released state: that isn't supported. Determine
+ whether to generate a tab-bar button click based on DOWN_P
+ argument, not on mouse-highlight, which has no effect on tab-bar
+ display. (Bug#47581)
+
+2021-04-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/net/shr.el (shr-insert-document): Explain why bidi-display-reordering
+
+2021-04-11 Gregory Heytings <gregory@heytings.org>
+ João Távora <joaotavora@gmail.com>
+
+ Add new icomplete-vertical-mode
+
+
+ * lisp/icomplete.el (icomplete-completions): Consider icomplete-vertical-mode.
+ (icomplete-vertical-mode-minibuffer-map): New map.
+ (icomplete--vertical-minibuffer-setup): New helper.
+ (icomplete-vertical-mode): New minor mode.
+
+ * doc/emacs/buffers.texi (Icomplete): Mention icomplete-vertical-mode.
+
+ * etc/NEWS: Mention icomplete-vertical-mode
+
+2021-04-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/misearch.el (multi-isearch-read-buffers): Fix last change
+
+ These are not buffers but buffer names.
+
+2021-04-10 Philipp Stephani <phst@google.com>
+
+ * src/emacs.c (read_full): Add a few assertions.
+
+2021-04-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cus-dep.el: Use lexical-binding
+
+2021-04-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/misearch.el: Use lexical-binding
+
+ (multi-isearch-read-buffers, multi-isearch-read-files):
+ Replace `add-to-list` with `cl-pushnew` for use on a local variable.
+
+2021-04-10 Philipp Stephani <phst@google.com>
+
+ * src/emacs.c (load_seccomp): Add a useful assertion.
+
+ * src/emacs.c (load_seccomp): Fix condition.
+
+2021-04-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/ps-bdf.el: Use lexical-binding
+
+ * lisp/informat.el: Use lexical-binding
+
+ * lisp/loadup.el: Use lexical-binding
+
+2021-04-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/jka-compr.el: Use lexical-binding
+
+ Prefer #' to quote function names.
+
+2021-04-10 Philipp Stephani <phst@google.com>
+
+ * etc/NEWS: Extend paragraph about &define form and backtracking
+
+2021-04-10 Alan Mackenzie <acm@muc.de>
+
+ Convert CC Mode to lexical binding in Emacs
+
+ lisp/progmodes/cc-align.el, lisp/progmodes/cc-awk.el,
+ lisp/progmodes/cc-bytecomp.el, lisp/progmodes/cc-cmds.el,
+ lisp/progmodes/cc-defs.el, lisp/progmodes/cc-engine.el,
+ lisp/progmodes/cc-fonts.el, lisp/progmodes/cc-guess.el,
+ lisp/progmodes/cc-langs.el, lisp/progmodes/cc-menus.el,
+ lisp/progmodes/cc-mode.el, lisp/progmodes/cc-styles.el,
+ lisp/progmodes/cc-subword.el, lisp/progmodes/cc-vars.el: Mark these files with
+ a `lexical-binding' setting in line 1.
+
+ lisp/progmodes/cc-align.el, lisp/progmodes/cc-engine.el,
+ lisp/progmodes/cc-vars.el (c-syntactic-context, c-syntactic-element): Declare
+ these as special variables.
+
+ lisp/progmodes/cc-bytecomp.el (cc-bytecomp-debug-msg): prefix the parameter
+ ARGS with a _, and remove an `ignore' call.
+
+ lisp/progmodes/cc-cmds.el (c-where-wrt-brace-construct): Remove `kluge-start',
+ an unused variable.
+ (c-while-widening-to-decl-block): Add an extra parameter, which suppresses
+ the generation of a setting of variable `where'.
+ (c-defun-name-and-limits): Remove variable `where' from the function and use
+ the new argument to the previous macro.
+
+ lisp/progmodes/cc-engine.el (c-cache-to-parse-ps-state): Remove two unneeded
+ variables, `last' and `intermediate'.
+
+ lisp/progmodes/cc-fonts.el (c-font-lock-c++-using): Remove unused variable.
+
+ lisp/progmodes/cc-langs.el (c-vsemi-status-unknown-p-fn): Replace the doc
+ string with the more precise one from stand-alone CC Mode.
+
+ lisp/progmodes/cc-styles.el (c-set-offset): Give the `ignored' parameter a
+ leading _.
+
+2021-04-10 Philipp Stephani <phst@google.com>
+
+ Add a helper binary to create a basic Secure Computing filter.
+
+ The binary uses the 'seccomp' helper library. The library isn't
+ needed to load the generated Secure Computing filter.
+
+ * configure.ac: Check for 'seccomp' header and library.
+
+ * lib-src/seccomp-filter.c: New helper binary to generate a generic
+ Secure Computing filter for GNU/Linux.
+
+ * lib-src/Makefile.in (DONT_INSTALL): Add 'seccomp-filter' helper
+ binary if possible.
+ (all): Add Secure Computing filter file if possible.
+ (seccomp-filter$(EXEEXT)): Compile helper binary.
+ (seccomp-filter.bpf seccomp-filter.pfc): Generate filter files.
+
+ * test/src/emacs-tests.el (emacs-tests/seccomp/allows-stdout)
+ (emacs-tests/seccomp/forbids-subprocess): New unit tests.
+
+ * test/Makefile.in (src/emacs-tests.log): Add dependency on the helper
+ binary.
+
+2021-04-10 Philipp Stephani <phst@google.com>
+
+ * src/emacs.c (load_seccomp): Fix condition.
+
+2021-04-10 Philipp Stephani <phst@google.com>
+
+ Read file in a loop if necessary.
+
+ This allows for short reads from 'emacs_read'.
+
+ * src/emacs.c (read_full): New helper function.
+ (load_seccomp): Use it.
+
+2021-04-10 Philipp Stephani <phst@google.com>
+
+ Add support for --seccomp command-line option.
+
+ When passing this option on GNU/Linux, Emacs installs a Secure
+ Computing kernel system call filter. See Bug#45198.
+
+ * configure.ac: Check for seccomp header.
+
+ * src/emacs.c (usage_message): Document --seccomp option.
+ (emacs_seccomp): New wrapper for 'seccomp' syscall.
+ (load_seccomp, maybe_load_seccomp): New helper functions.
+ (main): Potentially load seccomp filters during startup.
+ (standard_args): Add --seccomp option.
+
+ * lisp/startup.el (command-line): Detect and ignore --seccomp option.
+
+ * test/src/emacs-tests.el (emacs-tests/seccomp/absent-file)
+ (emacs-tests/seccomp/empty-file)
+ (emacs-tests/seccomp/file-too-large)
+ (emacs-tests/seccomp/invalid-file-size): New unit tests.
+ (emacs-tests--with-temp-file): New helper macro.
+
+ * etc/NEWS: Document new --seccomp option.
+
+2021-04-10 Philipp Stephani <phst@google.com>
+
+ Edebug: Disable backtracking when hitting a &define keyword.
+
+ Edebug doesn't deal well with backtracking out of definitions, see
+ Bug#41988. Rather than trying to support this rare situation (e.g. by
+ implementing a multipass parser), prevent it by adding an implicit
+ gate.
+
+ * lisp/emacs-lisp/edebug.el (edebug--match-&-spec-op): Disable
+ backtracking when hitting a &define keyword.
+
+ * test/lisp/emacs-lisp/edebug-tests.el
+ (edebug-tests-duplicate-&define): New unit test.
+ (edebug-tests--duplicate-&define): New helper macro.
+
+ * doc/lispref/edebug.texi (Backtracking): Mention &define in the list
+ of constructs that disable backtracking.
+
+ * etc/NEWS: Document new behavior.
+
+2021-04-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/nnagent.el: Fix spurious empty line at BOB
+
+2021-04-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/edmacro.el: Use lexical-binding
+
+ (edmacro-finish-edit, edmacro-parse-keys): Use `match-string`.
+
+2021-04-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/files-x.el: Use lexical-binding
+
+2021-04-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/ps-mule.el: Use lexical-binding
+
+ (ps-mule-encode-header-string, ps-mule-begin-job): Use `pcase`.
+
+2021-04-10 Gregory Heytings <gregory@heytings.org>
+
+ Autoload list-colors-display.
+
+ * lisp/facemenu.el (list-colors-display): Autoload, it is mentioned
+ in (info "(emacs)Colors for Faces"), and to be generally available.
+
+2021-04-10 Michael Albinus <michael.albinus@gmx.de>
+
+ Tramp: fix location of files on W32
+
+ * lisp/net/tramp.el:
+ * lisp/net/tramp-sh.el: Use (eq system-type 'windows-nt) where appropriate.
+ (tramp-completion-function-alist-ssh): Fix location of files on W32.
+
+2021-04-10 Jim Porter <jporterbugs@gmail.com> (tiny change)
+
+ Further fix of hostname completion on MS Windows
+
+ * lisp/net/tramp.el (tramp-completion-file-name-regexp-simplified)
+ (tramp-completion-file-name-regexp-separate): Fix W32 hostname/method
+ completion for simplified and separate syntaxes (same as the previous change
+ to default syntax).
+
+2021-04-10 Eli Zaretskii <eliz@gnu.org>
+
+ Fix description of momentary message display
+
+ * doc/emacs/mini.texi (Basic Minibuffer): Update the description
+ of momentary message display while minibuffer is active.
+ (Bug#47689)
+
+2021-04-10 João Távora <joaotavora@gmail.com>
+
+ Fail earlier if stale Flymake report functions called
+
+ If a Flymake backend calls a "stale" report function,
+ flymake--handle-report might be called for a backend function that is
+ no longer in the flymake--backend-state hash table. This patch makes
+ that erroneous situation slightly more explicit.
+
+ * lisp/progmodes/flymake.el (flymake--handle-report): Improve
+ error reporting.
+
+2021-04-10 Dmitry Gutov <dgutov@yandex.ru>
+
+ Don't stop when before space or closing paren
+
+ * lisp/progmodes/elisp-mode.el (elisp-completion-at-point):
+ Don't stop when before space or closing paren (bug#47665).
+
+2021-04-09 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: fix c-where-wrt-brace-construct to cope with class declarations
+
+ Make the function correctly recognize a brace block preceded by an
+ introductory line without a parameter list.
+
+ * lisp/progmodes/cc-cmds.el (c-where-wrt-brace-contruct): Reintroduce the use
+ of c-beginning-of-decl-1, which was removed some weeks ago, in place of a
+ c-syntactic-skip-backward. Reformulate the code generally.
+
+2021-04-09 Mattias Engdegård <mattiase@acm.org>
+
+ Fix condition-case optimiser bug
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Don't
+ perform incorrect optimisations when a condition-case variable shadows
+ another lexical variable.
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases):
+ New test case.
+
+2021-04-09 Mattias Engdegård <mattiase@acm.org>
+
+ Better compiler warning tests
+
+ These changes allow all bytecomp-tests to be run interactively.
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp--with-warning-test)
+ (bytecomp--define-warning-file-test): Interpret any space in the
+ pattern as arbitrary whitespace to tolerate line breaks.
+ Don't abuse the expected-failure mechanism when checking
+ for the expected absence of a warning.
+ (bytecomp/*.el): Rewrite patterns to work with line breaks
+ in the middle.
+
+2021-04-09 Mattias Engdegård <mattiase@acm.org>
+
+ Clean up bytecomp-tests.el
+
+ Now all test cases are run with both lexical and dynamic binding
+ where applicable, comparing interpreted against compiled results.
+ Previously, almost all tests were only run with dynamic binding
+ which was definitely not intended.
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (byte-opt-testsuite-arith-data): Rename to bytecomp-tests--test-cases.
+ (bytecomp-check-1, bytecomp-explain-1, bytecomp-tests)
+ (bytecomp-lexbind-tests, bytecomp-lexbind-check-1)
+ (bytecomp-lexbind-explain-1): Remove.
+ (bytecomp-tests--eval-interpreted, bytecomp-tests--eval-compiled)
+ (bytecomp-tests-lexbind, bytecomp-tests-dynbind)
+ (bytecomp-tests--test-cases-lexbind-only): New.
+
+2021-04-09 Stefan Kangas <stefan@marxist.se>
+
+ Make refer-every into obsolete alias for seq-every-p
+
+ * lisp/textmodes/refer.el (refer-every): Make into obsolete
+ function alias for seq-every-p. Update single caller.
+
+2021-04-09 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant #' before lambda in ibuf-*.el
+
+ * lisp/ibuf-ext.el (ibuffer-included-in-filters-p)
+ (ibuffer-included-in-filter-p-1, ibuffer-do-kill-lines)
+ (ibuffer-jump-to-buffer, ibuffer-mark-on-buffer)
+ (ibuffer-mark-by-name-regexp, ibuffer-mark-by-mode-regexp)
+ (ibuffer-mark-by-content-regexp, ibuffer-mark-by-mode)
+ (ibuffer-mark-modified-buffers, ibuffer-mark-unsaved-buffers)
+ (ibuffer-mark-dissociated-buffers, ibuffer-mark-help-buffers)
+ (ibuffer-mark-compressed-file-buffers, ibuffer-mark-old-buffers)
+ (ibuffer-mark-special-buffers, ibuffer-mark-read-only-buffers)
+ (ibuffer-mark-dired-buffers, ibuffer-do-occur):
+ * lisp/ibuf-macs.el (ibuffer-save-marks, define-ibuffer-sorter)
+ (define-ibuffer-op): Remove redundant #' before lambda.
+
+2021-04-09 Stefan Kangas <stefan@marxist.se>
+
+ Don't preserve window-line in tabulated-list-print
+
+ * lisp/emacs-lisp/tabulated-list.el (tabulated-list-print): Don't
+ try to preserve window-line. (Bug#42747)
+
+2021-04-09 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in winner.el
+
+ * lisp/winner.el: Use lexical-binding. Remove redundant :group
+ args.
+ (winner-set, winner-mode-map): Quote function symbols as such.
+
+2021-04-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Merge branch 'vhdl-mode-lexbind' into trunk
+
+2021-04-09 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in cmuscheme.el
+
+ * lisp/cmuscheme.el: Use lexical-binding. Doc fixes. Remove
+ redundant :group args. Quote function symbols as such.
+
+2021-04-09 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/progmodes/cmacexp.el: Use lexical-binding.
+
+2021-04-09 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in foldout.el
+
+ * lisp/foldout.el: Use lexical-binding. Doc and formatting fixes.
+ Quote function symbols as such.
+
+2021-04-09 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in loadhist.el and add tests
+
+ * lisp/loadhist.el: Use lexical-binding.
+ * test/lisp/loadhist-tests.el: New file.
+
+2021-04-09 Mattias Engdegård <mattiase@acm.org>
+
+ Self-TCO in `condition-case` error handlers
+
+ * lisp/emacs-lisp/cl-macs.el (cl--self-tco): Recognise
+ `condition-case` handlers as being in the tail position.
+ * test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs--labels):
+ Extend test.
+
+2021-04-09 Jim Porter <jporterbugs@gmail.com> (tiny change)
+
+ Fix hostname completion on MS Windows
+
+ * lisp/net/tramp.el (tramp-completion-file-name-regexp-default):
+ Handle volume letter being added to paths for file name completion on W32
+ systems. This fixes hostname (and method) autocomplete on W32.
+
+2021-04-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * test/lisp/shadowfile-tests.el: Fix recent test failures
+
+ (shadow--tests-cleanup): `shadow-hashtable` is now a hash table (duh!).
+
+2021-04-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/vhdl-mode.el: Use lexical-binding
+
+ Use #' to quote function names to get better compiler diagnostics.
+ Wrap some lines to avoid arguments "hidden" in positions that are easy
+ to misread.
+ Prefix unused arguments with a semi-colon to silence compiler warnings.
+ Fix a few comments that used ;;; even though they were not headings.
+
+ (vhdl-emacs-21): Delete variable.
+ Replace all uses with (not (featurep 'xemacs)) instead since `vhdl-mode`
+ has been incompatible with Emacs<21 for more than 10 years already.
+ (vhdl-prepare-search-1): Add Edebug declaration.
+ (vhdl-prepare-search-2): Add Edebug declaration and use
+ `with-syntax-table`.
+ (vhdl-visit-file): Add Edebug and indentation declaration.
+ Move the bulk of the code to a function for easier debugging.
+ (vhdl--visit-file): New function extracted from `vhdl-visit-file`.
+ Be careful not to modify syntax tables in unrelated buffers.
+ (vhdl-speedbar-refresh): Remove unused var `pos`.
+ (vhdl-backward-sexp): Remove unused var `last-forward`.
+ (vhdl-electric-tab, vhdl-minibuffer-tab, vhdl-line-expand):
+ Rename arg to avoid conflict with the `prefix-arg`
+ global variable.
+ (vhdl-align-region-1): Remove unused var `indent`.
+ (vhdl-character-to-event): Actually give a body to that poor function.
+ (vhdl-template-context): Remove unused vars `entity-exists` and `string`.
+ (vhdl-template-group): Remove unused var `start`.
+ (vhdl-template-argument-list): Remove unused var `start`.
+ (vhdl-port-paste-context-clause): Remove unused var `margin`.
+ (vhdl-port-paste-testbench): Remove unused var `source-buffer`.
+ (vhdl-hs-minor-mode): Declare function `hs-hide-all`.
+ (vhdl-get-hierarchy): Rename arguments `ent-alist`, `conf-alist`, and
+ `conf-key` and bind those dynamically scoped var via `let` instead
+ since arguments can't be dynamically scoped.
+ (vhdl-speedbar-insert-hierarchy, vhdl-compose-configuration-architecture):
+ Same thing with arguments `ent-alist` and `conf-alist`.
+ (vhdl-cache-version): Declare variable.
+ (speedbar-expand-line, speedbar-edit-line): Declare functions.
+ (vhdl-speedbar-update-current-unit): Declare before first use.
+ (vhdl-compose-new-component): Remove unused var `project`.
+ (lazy-lock-minimum-size): Declare variable.
+ (vhdl-submit-bug-report): Declare variable `reporter-prompt-for-summary-p`.
+
+2021-04-09 Stefan Kangas <stefan@marxist.se>
+
+ Revert "Load all generic-x.el modes unconditionally"
+
+ This reverts commit 0161c9df6edc02db6bd8871b00df522dd0699157.
+
+2021-04-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/shadowfile.el: Use lexical-binding
+
+ Delete redundant `:group` args.
+
+ (shadow-hashtable): Make it an actual hash-table.
+ (shadow-shadows-of, shadow-invalidate-hashtable): Adjust accordingly.
+ (shadow-insert-var): Strength-reduce `eval` to `symbol-value`.
+ (shadow--save-buffers-kill-emacs): New function extracted from
+ `shadow-save-buffers-kill-emacs`.
+ (shadow-save-buffers-kill-emacs): Use it and use `save-buffers-kill-emacs`.
+ (shadow-initialize, shadowfile-unload-function):
+ Use `advice-add/remove` rather than override `save-buffers-kill-emacs`
+ with `defalias`.
+
+2021-04-09 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant #' before lambda in {calendar,erc,mh-e}/*.el
+
+ * lisp/calendar/icalendar.el (icalendar--get-most-recent-observance):
+ * lisp/calendar/parse-time.el (parse-time-rules):
+ * lisp/erc/erc-dcc.el (pcomplete/erc-mode/DCC):
+ * lisp/erc/erc-track.el (erc-modified-channels-display):
+ * lisp/erc/erc.el (erc-toggle-debug-irc-protocol)
+ (erc-cmd-IGNORE, erc-cmd-JOIN, erc-default-server-handler)
+ (erc-banlist-update):
+ * lisp/mh-e/mh-search.el (mh-search, mh-mairix-convert-to-sop*)
+ (mh-index-create-sequences):
+ * lisp/mh-e/mh-thread.el (mh-toggle-threads, mh-thread-generate)
+ (mh-thread-prune-containers, mh-thread-sort-containers):
+ * lisp/mh-e/mh-utils.el (mh-sub-folders): Remove redundant #' before
+ lambda.
+
+2021-04-08 Gregory Heytings <gregory@heytings.org>
+
+ Terminate isearch when point has moved to another buffer
+
+ * lisp/isearch.el (isearch-post-command-hook): Terminate isearch
+ when the command just executed has moved point to another buffer.
+ https://lists.gnu.org/archive/html/emacs-devel/2021-04/msg00309.html
+
+2021-04-08 Gregory Heytings <gregory@heytings.org>
+
+ User option to move to another match when changing direction in isearch.
+
+ * lisp/isearch.el (isearch-direction-change-changes-match):
+ New user option (bug#47599).
+ (isearch-repeat): Use the new option.
+ (isearch-repeat-forward, isearch-repeat-backward): Adapt to the
+ new option.
+
+ * etc/NEWS: Mention the new user option.
+
+ * doc/emacs/search.texi: Document the new user option.
+
+2021-04-08 Juri Linkov <juri@linkov.net>
+
+ * lisp/repeat.el (repeat-post-hook): Check for prefix-arg.
+
+ This is instead of checking for a list of argument-related commands
+ that set prefix-arg anyway.
+
+2021-04-08 Juri Linkov <juri@linkov.net>
+
+ * lisp/repeat.el (repeat-post-hook): Skip repeating in minibuffer (bug#47566).
+
+ (repeat-map)<defvar>: Add docstring.
+
+2021-04-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/vhdl-mode.el: Use progress-reporter
+
+ This was actually prompted by a backward compatibility problem
+ (because of the use of Emacs-27's `time-convert`). The new code
+ seems to work fine in Emacs-25.
+ It also fixes a minor bug that made the echo area messages of
+ `vhdl-indent-region` compete with those of `indent-region`.
+
+ (vhdl-progress-info): Delete variable.
+ (vhdl--progress-reporter): New var to replace it.
+ (vhdl-update-progress-info): Delete function.
+ (vhdl-indent-line): Call progress-reporter-update instead.
+ (vhdl-indent-region): Make it an obsolete alias of `indent-region`.
+ Change all users.
+ (vhdl-align-region-groups, vhdl-align-region, vhdl-fix-case-region-1):
+ Use `make-progress-reporter` and `progress-reporter-update`.
+
+2021-04-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/array.el: Use lexical-binding
+
+2021-04-08 Michael Albinus <michael.albinus@gmx.de>
+
+ * doc/misc/tramp.texi (Frequently Asked Questions): New item about recentf.
+
+2021-04-08 Michael Albinus <michael.albinus@gmx.de>
+
+ Revert use of powershell in Tramp, there are collateral damages
+
+ * lisp/net/tramp-sh.el (tramp-methods) <sshx, scpx>: Fix quoting
+ for MS Windows.
+ (tramp-connection-properties): Don't set "encoding-shell".
+ (tramp-actions-before-shell): Remove `tramp-no-job-control-regexp'.
+ (tramp-maybe-open-connection): Revert changes for "encoding-shell".
+
+ * lisp/net/tramp.el (tramp-no-job-control-regexp): Remove.
+
+2021-04-07 Alan Third <alan@idiocy.org>
+
+ Remove hardcoded gcc version
+
+ * configure.ac: Use 'find' to find the brew installed libgccjit libs
+ instead of a hardcoded path.
+
+2021-04-07 Juri Linkov <juri@linkov.net>
+
+ Don't set isearch-success in isearch-wrap functions
+
+ * lisp/comint.el (comint-history-isearch-wrap):
+ * lisp/simple.el (minibuffer-history-isearch-wrap):
+ Don't set isearch-success to t, so isearch-repeat won't skip the
+ beginning of the wrapped match with (forward-char (if isearch-forward 1 -1)).
+
+2021-04-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix crash on MS-Windows caused by recent changes
+
+ * src/pdumper.c (dump_do_dump_relocation): Don't use
+ expand-file-name, as this crashes on MS-Windows. Use
+ file_access_p instead of emacs_fopen.
+
+2021-04-07 Andrea Corallo <akrl@sdf.org>
+
+ Improve some docstring in comp.el
+
+ * lisp/emacs-lisp/comp.el (comp--native-compile)
+ (batch-native-compile, batch-byte-native-compile-for-bootstrap):
+ Improve docstring.
+
+2021-04-07 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 2f5f30671a (origin/emacs-27) Fix broken links in autorevert.el
+ 673c02f6d0 * lisp/international/ja-dic-cnv.el (skkdic-convert): Doc fix.
+
+2021-04-07 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 3ec93bb7c2 Improve doc strings in replace.el
+
+2021-04-07 Stefan Kangas <stefan@marxist.se>
+
+ Clarify obsoletion messages for easy-menu-{add,remove}
+
+ * lisp/emacs-lisp/easymenu.el (easy-menu-remove, easy-menu-add):
+ Clarify obsoletion messages.
+
+2021-04-07 Stefan Kangas <stefan@marxist.se>
+
+ Update whois-server-tld
+
+ * lisp/net/net-utils.el (whois-server-tld): Update and add some
+ missing entries.
+
+2021-04-07 Andrea Corallo <akrl@sdf.org>
+
+ Move gitlab-ci native-comp tests into '/test/infra/gitlab-ci.yml'
+
+ * .gitlab-ci.yml: Fix incorrect b8d3ae78c5 merge.
+ * test/infra/gitlab-ci.yml (test-native-bootstrap-speed0)
+ (test-native-bootstrap-speed1, test-native-bootstrap-speed2): Move
+ from .gitlab-ci.yml.
+
+2021-04-07 Mattias Engdegård <mattiase@acm.org>
+
+ Fix mistakes in bytecomp-tests
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (byte-opt-testsuite-arith-data): Fix typos and avoid errors that made
+ the tests less powerful than intended.
+
+2021-04-07 Alan Third <alan@idiocy.org>
+
+ Fix install with NS app bundle
+
+ * configure.ac: Set up CFLAGS and LDFLAGS to find a Homebrew
+ installation of libgccjit.
+ * Makefile.in (ELN_DESTDIR): Set to the app bundle resource dir when
+ required.
+ (install-eln): macOS install doesn't support the -D flag, so make the
+ directories separately.
+
+2021-04-07 Andrea Corallo <akrl@sdf.org>
+
+ Makefile.in (BIN_DESTDIR, src): Fix 'BIN_DESTDIR' on MacOS.
+
+2021-04-07 Dmitry Gutov <dgutov@yandex.ru>
+
+ Add explicit support for C-g or ESC ESC ESC after keymap prompt
+
+ * lisp/progmodes/project.el (project-switch-project):
+ Add explicit support for C-g or ESC ESC ESC after keymap prompt
+ (bug#47620).
+
+2021-04-07 Dario Gjorgjevski <dario.gjorgjevski+git@gmail.com>
+
+ Allow complex key bindings in project-switch-project
+
+ * lisp/progmodes/project.el (project-switch-project): Replace
+ read-event with an overriding local map and read-key-sequence to allow
+ for complex key bindings to be read (bug#47620).
+
+2021-04-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/find-file.el: Make the commands oblivious to mouse/non-mouse
+
+ (ff-find-other-file): Add `event` argument.
+ (ff-find-other-file-other-window): Rename from
+ `ff-mouse-find-other-file-other-window` and use this new argument.
+ (ff-mouse-find-other-file, ff-mouse-find-other-file-other-window):
+ Make them obsolete aliases.
+ (ff-upcase-p): Remove unused `start` and `end` arguments and
+ simplify accordingly.
+
+2021-04-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/find-file.el: Use lexical-binding
+
+ Remove unused `:group` args. Prefer #' to quote function.
+
+ (ff-special-constructs, ff-find-the-other-file, ff-get-file-name)
+ (ff-list-replace-env-vars, ff-cc-hh-converter): Use `match-string`.
+ (modula2-other-file-alist): Tighten regexps.
+ (ff-get-other-file, ff-find-other-file): Use dynamic scoping.
+ (ff-find-the-other-file): Minor simplification.
+ (ff-other-file-name): Delete unused function.
+ (ff-string-match): Don't let-bind `case-fold-search` if not needed.
+ (ff-basename): Make it an obsolete alias for `file-name-nondirectory`.
+ (ff-switch-file): Minor simplification.
+ (ff-list-replace-env-vars): Use [:alnum:].
+ (ff-upcase-p): Use [:upper:]
+ (ff-cc-hh-converter): Use [:upper:] and [:lower:].
+
+2021-04-06 Andrea Corallo <akrl@sdf.org>
+
+ * .gitlab-ci.yml: Move native-comp tests into 'slow' stage.
+
+2021-04-06 Juri Linkov <juri@linkov.net>
+
+ * lisp/isearch.el (isearch-wrap-pause): New defcustom (bug#47599).
+
+ (isearch-repeat): Use it.
+ (isearch-search): Don't ding when isearch-wrap-pause is no-ding.
+
+2021-04-06 Andrea Corallo <akrl@sdf.org>
+
+ * src/pdumper.c (dump_do_dump_relocation): Use `expand-file-name'.
+
+2021-04-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/ps-mode.el: Use lexical-binding
+
+ And prefer #' to quote function names.
+
+2021-04-06 Damien Cassou <damien@cassou.me>
+
+ Fix broken links in autorevert.el
+
+ * lisp/autorevert.el (global-auto-revert-non-file-buffers):
+ Fix broken links. (Bug#47621)
+
+2021-04-06 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Bug#47601 in Tramp
+
+ * lisp/net/tramp-sh.el (tramp-sh-file-name-handler-alist):
+ Use `tramp-handle-file-newer-than-file-p'. (Bug#47601)
+ (tramp-sh-handle-file-newer-than-file-p, tramp-run-test2): Remove.
+
+2021-04-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/msb.el: Use lexical-binding
+
+ Remove redundant `:group` args.
+ (msb--add-to-menu): Strength-reduce `eval` to `symbol-value` and use `push`.
+ (msb--create-sort-item): Strength-reduce `eval` to `symbol-value`.
+ (msb-menu-bar-update-buffers): Replace `(lambda...) with a proper closure.
+
+2021-04-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/hippie-exp.el: Use lexical-binding
+
+ Remove redundant `:group` args.
+ (make-hippie-expand-function): Turn it into a function returning
+ a closure.
+ (try-expand-all-abbrevs): Strength-reduce `eval` to `symbol-value`
+ and use `abbrev-table-p` rather than `vectorp`.
+
+2021-04-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/comint.el: Fix understickiness of non-comint properties
+
+ When a third party package adds properties to the prompt they don't
+ necessarily want to be `read-nonsticky` (e.g. for the `cursor-intangible`
+ property), so replace the catchall `rear-nonsticky t` with an
+ actual list of the properties that we want to be `rear-nonsticky`.
+
+ (comint-send-input, comint-output-filter): Don't mark
+ all properties as non-sticky.
+
+2021-04-05 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: Add repeat-map keymaps.
+
+ * lisp/tab-bar.el (tab-bar-switch-repeat-map): New keymap used for
+ 'tab-next' and 'tab-previous'.
+ (tab-bar-move-repeat-map): New keymap used for 'tab-move'.
+ https://lists.gnu.org/archive/html/emacs-devel/2021-03/msg01103.html
+
+2021-04-05 Juri Linkov <juri@linkov.net>
+
+ * lisp/repeat.el (repeat-keep-prefix): New defcustom.
+
+ * lisp/repeat.el (repeat-map): New autoloaded global variable.
+ (repeat-post-hook): Use 'repeat-map' when non-nil
+ and reset it to nil afterwards.
+ (repeat-post-hook): Keep the current prefix when
+ 'repeat-keep-prefix' is non-nil.
+
+ * lisp/window.el (other-window-repeat-map): Add "O" that sets
+ 'repeat-map' to 'other-window-repeat-map' before calling
+ '(other-window -1)'.
+
+ https://lists.gnu.org/archive/html/emacs-devel/2021-03/msg01387.html
+
+2021-04-05 Juri Linkov <juri@linkov.net>
+
+ * lisp/repeat.el (repeat-post-hook): Fix key lookup.
+
+ * lisp/repeat.el (repeat-post-hook): Rename let-bound repeat-map to rep-map.
+ Define let-bound prefix-command-p. Use lookup-key with
+ this-single-command-keys instead of last-command-event.
+ Don't show message when typing prefix keys.
+ https://lists.gnu.org/archive/html/emacs-devel/2021-04/msg00083.html
+
+2021-04-05 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into native-comp
+
+2021-04-05 Andrea Corallo <akrl@sdf.org>
+
+ Introduce `comp-file-preloaded-p'
+
+ * src/comp.c (syms_of_comp): Define `comp-file-preloaded-p'.
+ (Fcomp_el_to_eln_filename): Account for `comp-file-preloaded-p'.
+
+2021-04-05 Michael Albinus <michael.albinus@gmx.de>
+
+ Use powershell for Tramp on MS Windows
+
+ * lisp/net/tramp-sh.el (tramp-use-ssh-controlmaster-options):
+ Nil on MS Windows.
+ (tramp-connection-properties): Add "encoding-shell".
+ (tramp-maybe-open-connection): Use it. Change exit handling.
+ (tramp-actions-before-shell): Add `tramp-no-job-control-regexp'.
+
+ * lisp/net/tramp.el (tramp-methods): Adapt docstring.
+ (tramp-no-job-control-regexp): New defcustom.
+ (tramp-get-debug-buffer): Set coding system.
+
+2021-04-05 Dario Gjorgjevski <dario.gjorgjevski+git@gmail.com>
+
+ Do not search the global keymap in project--keymap-prompt
+
+ * lisp/progmodes/project.el: (project--keymap-prompt) Pass
+ project--keymap-prompt as a list to where-is-internal so that the
+ global keymap is not searched at all (bug#47501).
+
+2021-04-05 Lin Sun <lin.sun@zoom.us>
+
+ Don't call `image-toggle-display-text' when toggling
+
+ *lisp/image-mode.el (image-mode-to-text): Do not call the
+ image-toggle-display-text twice when toggle image display (bug#47521).
+
+2021-04-05 Utkarsh Singh <utkarsh190601@gmail.com> (tiny change)
+
+ Fix cd to directories called "eshell" in eshell
+
+ * lisp/eshell/em-script.el (eshell-script-initialize): Allow
+ changing directory to directories called "eshell" (bug#47547).
+
+2021-04-05 Glenn Morris <rgm@gnu.org>
+
+ * lisp/international/ja-dic-cnv.el (skkdic-convert): Doc fix.
+
+2021-04-05 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant #' before lambda in calc/*.el
+
+ * lisp/calc/calc-alg.el (math-defsimplify):
+ * lisp/calc/calc-ext.el (math-defintegral, math-defintegral-2):
+ * lisp/calc/calc-prog.el (math-do-arg-check): Remove redundant #'
+ before lambda.
+
+2021-04-05 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/shadowfile.el (cl-lib): Revert removing require.
+
+ * lisp/pcomplete.el: Remove aliases commented out for 20 years.
+
+2021-04-05 Stefan Kangas <stefan@marxist.se>
+
+ Remove local uniquify functions in favour of seq-uniq
+
+ * lisp/emacs-lisp/seq.el (seq-uniq): Add autoload cookie.
+ * lisp/pcomplete.el: (pcomplete-uniquify-list): Use seq-uniq.
+ * lisp/eshell/esh-util.el (eshell-uniqify-list)
+ (eshell-uniquify-list):
+ * lisp/nxml/rng-util.el (rng-uniquify-equal):
+ * lisp/progmodes/idlwave.el (idlwave-uniquify):
+ * lisp/textmodes/artist.el (artist-uniq): Make into obsolete
+ function aliases for seq-uniq. Update callers.
+ * lisp/nxml/rng-util.el (rng-uniquify-eq): Make obsolete in favor
+ of seq-uniq. Update callers.
+
+2021-04-05 Stefan Kangas <stefan@marxist.se>
+
+ Obsolete local set difference functions in favor of seq-difference
+
+ * lisp/emacs-lisp/seq.el (seq-difference): Add autoload cookie.
+ * lisp/gnus/gnus-range.el (gnus-set-difference):
+ * lisp/gnus/spam.el (spam-set-difference): Make obsolete in favor
+ of seq-difference. Update callers.
+
+2021-04-05 Stefan Kangas <stefan@marxist.se>
+
+ Obsolete local list functions in shadowfile.el
+
+ * lisp/shadowfile.el (shadow-union): Make obsolete in favour of
+ cl-union. Update callers.
+ (shadow-find): Make into obsolete function alias for seq-find.
+ Update callers.
+ (cl-lib): Remove unnecessary require.
+
+2021-04-05 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/infra/Dockerfile.emba (emacs-gnustep): Do not run parallel make.
+
+2021-04-05 Stefan Kangas <stefan@marxist.se>
+
+ Remove code commented out since 1995 from ediff-util.el
+
+ * lisp/vc/ediff-util.el (ediff-load-hook): Remove code commented out
+ since the file was added in 1995.
+
+2021-04-05 Stefan Kangas <stefan@marxist.se>
+
+ Replace local intersection functions with seq-intersection
+
+ * lisp/doc-view.el (doc-view-intersection):
+ * lisp/gnus/gnus-range.el (gnus-intersection):
+ * lisp/htmlfontify.el (hfy-interq):
+ * lisp/loadhist.el (file-set-intersect):
+ * lisp/mail/smtpmail.el (smtpmail-intersection): Make obsolete in
+ favor of seq-intersection. Update all callers.
+
+ * lisp/url/url-dav.el (url-intersection): Redefine as obsolete
+ function alias for seq-intersection. Update callers.
+
+ * lisp/mpc.el (mpc-intersection, mpc-cmd-list, mpc-reorder):
+ Use seq-intersection.
+
+2021-04-05 Stefan Kangas <stefan@marxist.se>
+
+ Make ediff-copy-list alias obsolete
+
+ * lisp/vc/ediff-mult.el (ediff-intersect-directories)
+ (ediff-get-directory-files-under-revision): Don't use above
+ obsolete alias.
+ * lisp/vc/ediff-util.el (ediff-copy-list): Make alias obsolete.
+
+2021-04-05 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/htmlfontify.el (hfy-triplet-regex): Use rx.
+
+ * etc/NEWS: Add entry for new SVG icons in customize.
+
+2021-04-05 Glenn Morris <rgm@gnu.org>
+
+ * doc/misc/Makefile.in (echo-sources): Make it not the first target.
+
+2021-04-05 Glenn Morris <rgm@gnu.org>
+
+ Regenerate texi-from-org if ox-texinfo.el changes
+
+ * doc/misc/Makefile.in (top_srcdir): New, set by configure.
+ (emacs): Set load-prefer-newer.
+ (org_template): Make output depend on ox-texinfo.el.
+
+2021-04-05 Glenn Morris <rgm@gnu.org>
+
+ Regenerate semantic grammars if the generating code changes
+
+ * admin/grammars/Makefile.in (emacs): Set load-prefer-newer.
+ (grammar_bovine, grammar_wisent): New variables.
+ (${bovinedir}/%-by.el, ${bovinedir}/scm-by.el)
+ (${cedetdir}/semantic/%-wy.el, ${wisentdir}/%-wy.el)
+ (${wisentdir}/javat-wy.el, ${cedetdir}/srecode/srt-wy.el):
+ Depend on the source file for the generating function.
+ * lisp/cedet/semantic/bovine/grammar.el (bovine--make-parser-1):
+ * lisp/cedet/semantic/wisent/grammar.el (wisent--make-parser-1):
+ Force generation of the output file. The previous "is the output
+ newer than the input" failed to account for changes in the
+ generation code itself. Force so we can let make figure it out.
+
+2021-04-04 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (fixup_eln_load_path): Fix parameter name.
+
+ * src/comp.c (Fcomp_el_to_eln_filename): Fix doc.
+
+ * lisp/emacs-lisp/comp.el (comp-clean-up-stale-eln): Clean-up all .eln dirs.
+
+2021-04-04 Andrea Corallo <akrl@sdf.org>
+
+ Output native compiled preloaded files into the 'preloaded' subfolder
+
+ * src/comp.c (fixup_eln_load_path): Account the fact that the
+ file can be dumped in the 'preloaded' subfolder.
+ * lisp/loadup.el: Likewise.
+ * src/lread.c (maybe_swap_for_eln1): New function.
+ (maybe_swap_for_eln): Handle 'preloaded' subfolder.
+ * src/Makefile.in (LISP_PRELOADED): Export preloaded files.
+
+2021-04-04 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Don't reposition the window when writing messages
+
+ * lisp/progmodes/cperl-mode.el (cperl-find-pods-heres): Avoid
+ printing messages while point is off-screen (Bug#47549).
+
+2021-04-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify the doc string of insert-image
+
+ * lisp/image.el (insert-image): Mention the effect of a whitespace
+ image (bug#47240).
+
+2021-04-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Work around issue with (setq Man-notify-method 'aggressive)
+
+ * lisp/man.el (Man-bgproc-sentinel): Check that the window still
+ exists before trying to select it (bug#38164).
+
+2021-04-04 Glenn Morris <rgm@gnu.org>
+
+ Make maintainer-clean delete generated files, as per standards
+
+ These are generated files that were once kept in the repository.
+ When they were removed from the repository, as a half-way measure
+ they were only deleted by "extraclean", but this was never
+ necessary and was not a proper use of that rule.
+ * admin/charsets/Makefile.in (gen-clean): New phony target.
+ (maintainer-clean): Delete generated files.
+ * admin/grammars/Makefile.in (gen-clean): New phony target.
+ (maintainer-clean): Delete generated files.
+ * admin/unidata/Makefile.in (gen-clean): New phony target.
+ (maintainer-clean): Delete generated files.
+ * leim/Makefile.in (gen-clean): New phony target.
+ (maintainer-clean): Delete generated files.
+ * GNUmakefile: Doc fix.
+
+2021-04-04 Alan Third <alan@idiocy.org>
+
+ Work around librsvg bug (bug#47074)
+
+ Librsvg <= 2.40 has restrictions on how certain numbers can be run
+ together in path elements which do not match the SVG spec.
+
+ * etc/images/checkbox-mixed.svg:
+ * etc/images/checked.svg:
+ * etc/images/radio-checked.svg:
+ * etc/images/unchecked.svg: Separate problem numbers.
+ * etc/images/radio-mixed.svg: Separate problem numbers and color and
+ font-weight data.
+
+2021-04-04 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/lisp/filenotify-tests.el (file-notify--test-timeout):
+
+ Change timing on emba.
+
+2021-04-04 Eli Zaretskii <eliz@gnu.org>
+
+ Fix MS-Windows build
+
+ * src/image.c: (init_svg_functions) [WINDOWSNT]: Define and load
+ rsvg_handle_set_stylesheet from the DLL for librsvg > 2.48.
+ (lookup_image): Use xmalloc.
+
+2021-04-04 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in hilit-chg.el
+
+ * lisp/hilit-chg.el: Use lexical-binding. Remove redundant :group
+ args. Doc and formatting fixes.
+ (highlight-changes-mode, highlight-changes-visible-mode):
+ Use keyword arguments.
+ (hilit-chg-display-changes, highlight-changes-rotate-faces):
+ Quote function symbols as such.
+ (hilit-x, hilit-y, hilit-e): Define variables on top-level to
+ silence the byte-compiler.
+ (highlight-markup-buffers): Improve message format.
+
+2021-04-04 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant #' before lambda in tests
+
+ * test/lisp/electric-tests.el (save-electric-modes)
+ (inhibit-in-mismatched-string-inside-ruby-comments)
+ (inhibit-in-mismatched-string-inside-c-comments, js-mode-braces)
+ (js-mode-braces-with-layout)
+ (js-mode-braces-with-layout-and-indent, autowrapping-1)
+ (autowrapping-2, autowrapping-3, autowrapping-4, autowrapping-5)
+ (autowrapping-6, autowrapping-7):
+ * test/lisp/progmodes/xref-tests.el
+ (xref--xref-file-name-display-is-relative-to-project-root):
+ * test/src/thread-tests.el (threads-signal-early)
+ (threads-signal-main-thread): Remove redundant #' before lambda.
+
+2021-04-04 Alan Third <alan@idiocy.org>
+
+ Fix warnings in image.c
+
+ * src/image.c (svg_load_image): Fix types and move declaration of
+ 'css' to the top of the function.
+
+2021-04-04 Eli Zaretskii <eliz@gnu.org>
+
+ Fix unexec compilation
+
+ * src/pdumper.c (thaw_hash_tables): Now conditioned by
+ HAVE_PDUMPER.
+ (init_pdumper_once): No-op unless HAVE_PDUMPER. Reported by
+ Nikolay Kudryavtsev <nikolay.kudryavtsev@gmail.com>.
+
+2021-04-04 Eli Zaretskii <eliz@gnu.org>
+
+ Fix recent changes regarding frame-scale-factor
+
+ * src/frame.c (Fframe_scale_factor): Make more robust and avoid
+ compiler warning while at that. Doc fix.
+
+2021-04-04 İ. Göktuğ Kayaalp <self@gkayaalp.com>
+
+ Fix build error in frame.h on non-NS
+
+ * src/frame.h (FRAME_SCALE_FACTOR): Fix syntax of macro in
+ previous change.
+
+2021-04-04 Alan Third <alan@idiocy.org>
+
+ Make new SVG widgets match character height (bug#47074)
+
+ * etc/images/checkbox-mixed.svg:
+ * etc/images/checked.svg:
+ * etc/images/radio-checked.svg:
+ * etc/images/radio-mixed.svg:
+ * etc/images/radio.svg:
+ * etc/images/unchecked.svg: Use viewBox and set height to 1em.
+
+2021-04-04 Alan Third <alan@idiocy.org>
+
+ Set CSS for SVG files
+
+ * src/dispextern.h (struct image): Add font details required for the CSS.
+ * src/image.c (free_image): Free the font family string.
+ (search_image_cache):
+ (uncache_image): Make image caching understand the font details.
+ (lookup_image): Handle the font details when generating the image and
+ looking up the cache.
+ (svg_css_length_to_pixels): Handle 'em' when we know the font size.
+ (svg_load_image): Generate the CSS and apply it to the SVG.
+ (enum svg_keyword_index):
+ (svg_format):
+ (syms_of_image): Add ':css' attribute.
+ * doc/lispref/display.texi (SVG Images): Add details of new svg image
+ attributes.
+
+2021-04-04 Alan Third <alan@idiocy.org>
+
+ Fix NSTRACE failure
+
+ * src/nsterm.m ([EmacsSurface getContext]): Remove unneeded '@' symbol.
+
+2021-04-04 Alan Third <alan@idiocy.org>
+
+ Implement frame-scale-factor
+
+ * src/frame.c (Fframe_scale_factor): New function.
+ (syms_of_frame): Add frame-scale-factor.
+ * src/frame.h: Add FRAME_SCALE_FACTOR.
+ * src/image.c: Move FRAME_SCALE_FACTOR to frame.h.
+
+2021-04-03 Stefan Kangas <stefan@marxist.se>
+
+ Add SVG icons for customize buffers
+
+ * etc/images/checkbox-mixed.svg:
+ * etc/images/checked.svg:
+ * etc/images/down.svg:
+ * etc/images/left.svg:
+ * etc/images/radio-checked.svg:
+ * etc/images/radio-mixed.svg:
+ * etc/images/radio.svg:
+ * etc/images/right.svg:
+ * etc/images/unchecked.svg:
+ * etc/images/up.svg: New files from the Adwaita Icon Theme (made by
+ the GNOME project). The background color was changed from gray to
+ none to use the same colors as the current face instead. (Bug#47074)
+ * etc/images/README: Add license information for the above new files.
+ * lisp/wid-edit.el (widget-image-conversion): Prefer SVG if it exists.
+ (radio-button): Rename radio buttons to "radio-checked" and
+ "radio". These files did not exist before.
+
+2021-04-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/vcursor.el: Use lexical-binding
+
+ Remove redundant `:group` args.
+ (vcursor): Remove unused var declaration.
+
+2021-04-03 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-insert-directory):
+
+ Fix code finding //DIRED//.
+
+2021-04-03 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/lisp/filenotify-tests.el (file-notify--test-timeout): Change timing.
+
+2021-04-03 Eli Zaretskii <eliz@gnu.org>
+
+ Improve doc strings in replace.el
+
+ * lisp/replace.el (occur, list-matching-lines-prefix-face)
+ (list-matching-lines-jump-to-current-line): Doc fixes.
+
+2021-04-03 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/pixel-scroll.el: Use lexical-binding.
+
+2021-04-03 Stefan Kangas <stefan@marxist.se>
+
+ Replace two functions with seq-subseq
+
+ * lisp/emacs-lisp/seq.el (seq-subseq): Add autoload cookie.
+ * lisp/eshell/esh-util.el (eshell-sublist): Redefine using seq-subseq
+ and make obsolete. Update callers.
+ * lisp/wid-edit.el (widget-sublist): Redefine as obsolete function
+ alias for seq-subseq. Update callers.
+
+2021-04-03 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant #' before lambda in eshell/*.el
+
+ * lisp/eshell/em-dirs.el (eshell-dirs-initialize):
+ * lisp/eshell/em-pred.el (eshell-predicate-alist)
+ (eshell-modifier-alist):
+ * lisp/eshell/em-script.el (eshell-script-initialize):
+ * lisp/eshell/eshell.el (eshell-command): Remove redundant #' before
+ lambda.
+
+2021-04-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/simula.el: Use lexical-binding
+
+ (simula-tab-always-indent): Mark as obsolete.
+ (simula-mode-map): Don't bind TAB.
+ (simula-indent-command): Mark as obsolete.
+ (hilit-set-mode-patterns): Remove obsolete support for hilit19.
+ (simula-mode-syntax-table): Move initialization code into the declaration.
+
+2021-04-03 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in recentf.el
+
+ * lisp/recentf.el: Use lexical-binding. Doc fix.
+ (recentf-save-file): Strength reduce 'eval' to 'symbol-value'.
+ (recentf-trunc-list): Make into obsolete function alias for
+ 'seq-take'. Update callers.
+ (recentf-show-file-shortcuts-flag): Doc fix.
+ (recentf-menu-elements, recentf-make-menu-items)
+ (recentf-make-menu-item, recentf-dialog-mode-map)
+ (recentf-dialog, recentf-open-files-item)
+ (recentf-open-files-items, recentf-open-files)
+ (recentf-load-list): Quote function symbols as such.
+ (recentf-relative-filter, recentf-file-name-nondir): Remove
+ redundant #' before lambda.
+
+2021-04-03 Stefan Kangas <stefan@marxist.se>
+
+ Remove references to very old versions of Emacs from eintr
+
+ * doc/lispintro/emacs-lisp-intro.texi (Making Errors)
+ (Void Function, Void Variable, Wrong Type of Argument, debug)
+ (debug-on-entry): Remove commented out references to Emacs 20 or
+ earlier.
+ * doc/lispintro/emacs-lisp-intro.texi (what-line)
+ (print-elements-of-list, debug, X Axis Tic Marks): Don't call version
+ 22 or earlier a "recent" version of Emacs.
+
+2021-04-02 Stefan Kangas <stefan@marxist.se>
+
+ * doc/misc/woman.texi (Introduction): Remove reference to old Emacs.
+
+2021-04-02 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant #' before lambda in textmodes/*.el
+
+ * lisp/textmodes/fill.el:
+ * lisp/textmodes/ispell.el (ispell-find-enchant-dictionaries):
+ * lisp/textmodes/rst.el (rst-re, rst-Ado-position)
+ (rst-Hdr-member-ado, rst-mode-abbrev-table)
+ (rst-preferred-adornments, rst-new-preferred-hdr)
+ (rst-classify-adornment, rst-ttl-at-point, rst-hdr-hierarchy)
+ (rst-all-ttls-with-level, rst-get-previous-hdr)
+ (rst-adjust-region, rst-preferred-bullets, rst-find-begs)
+ (rst-straighten-bullets-region, rst-stn-containing-point)
+ (rst-toc-update, rst-forward-section, rst-shift-region)
+ (rst-enumerate-region, rst-bullet-list-region)
+ (rst-line-block-region, rst-forward-indented-block): Remove redundant #'
+ before lambda.
+
+2021-04-02 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * doc/misc/reftex.texi: Remove outdated instructions
+
+ (Building and Installing, Installation with make)
+ (Installation by Hand, Loading @RefTeX{}): Delete sections.
+ (Entering @RefTeX{} Mode): Merge into its parent.
+ (AUCTeX): Point to GNU ELPA for installation.
+ (Problems and Work-Arounds): Remove XEmacs-specific item.
+
+2021-04-02 Arash Esbati <arash@gnu.org>
+
+ Delete XEmacs-only definition
+
+ * lisp/textmodes/reftex-vars.el (reftex-label-regexps): Remove
+ XEmacs compat code.
+
+2021-04-02 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/xref.el: Change xref-file-name-display and xref-match face.
+
+ * lisp/progmodes/xref.el (xref-file-name-display): Change the default value
+ to 'project-relative' (bug#47012).
+ (xref-match)<face>: Inherit from 'match'.
+
+2021-04-02 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix C-u project-find-regexp's default dir
+
+ * lisp/progmodes/project.el (project-find-regexp):
+ Default read-directory-name to the current default-directory when
+ called with C-u (bug#47012).
+
+2021-04-02 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/cfengine.el: Use lexical-binding
+
+2021-04-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/dcl-mode.el: Clarify what is meant by DCL
+
+2021-04-01 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.h (unload_comp_unit): Define for vanilla build (warning removal).
+
+2021-04-01 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant #' before lambda in {mail,net,url}/*.el
+
+ * lisp/mail/mail-extr.el:
+ * lisp/mail/rmail.el (rmail-start-mail):
+ * lisp/net/gnutls.el (gnutls-boot-parameters):
+ * lisp/net/imap.el (imap-starttls-open):
+ * lisp/net/pop3.el (pop3-list):
+ * lisp/url/url-cookie.el (url-cookie-save-interval):
+ * lisp/url/url-history.el (url-history-save-interval)
+ (url-history-track):
+ * lisp/url/url-mailto.el (url-mailto): Remove redundant #' before lambda.
+
+2021-04-01 Andrea Corallo <akrl@sdf.org>
+
+ Issue a warning when eln look-up fails due to missing .el source file.
+
+ * lisp/emacs-lisp/comp.el (comp-warning-on-missing-source): New
+ customize.
+ * src/lread.c (maybe_swap_for_eln): Issue a warning when eln
+ look-up fails due to missing .el source file.
+ * src/comp.c (syms_of_comp): Define
+ 'Qcomp_warning_on_missing_source'.
+
+2021-04-01 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in executable.el and add tests
+
+ * lisp/progmodes/executable.el: Use lexical-binding.
+ * test/lisp/progmodes/executable-tests.el: New file.
+
+2021-04-01 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant #' before lambda in progmodes/*.el
+
+ * lisp/progmodes/cc-styles.el (c-set-offset):
+ * lisp/progmodes/ebnf-yac.el (ebnf-yac-token-table):
+ * lisp/progmodes/ebnf2ps.el (ebnf-format-float, ebnf-map-name):
+ * lisp/progmodes/grep.el (lgrep, rgrep-default-command):
+ * lisp/progmodes/inf-lisp.el:
+ * lisp/progmodes/octave.el (octave-lookfor):
+ * lisp/progmodes/python.el (python-pdbtrack-tracking-finish): Remove
+ redundant #' before lambda.
+
+2021-04-01 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant #' before lambda in international/*.el
+
+ * lisp/international/characters.el:
+ (use-cjk-char-width-table, update-glyphless-char-display):
+ * lisp/international/fontset.el (build-default-fontset-data)
+ (generate-fontset-menu):
+ * lisp/international/latin1-disp.el (latin1-display-reset):
+ * lisp/international/mule-cmds.el
+ (select-safe-coding-system-interactively):
+ * lisp/international/mule-diag.el (sort-listed-character-sets)
+ (font-show-log):
+ * lisp/international/mule.el (char-displayable-p):
+ * lisp/international/quail.el (quail-keyboard-layout-type)
+ (quail-update-translation, quail-find-key):
+ * lisp/international/titdic-cnv.el (tsang-quick-converter)
+ (ziranma-converter): Remove redundant #' before lambda.
+
+2021-04-01 Eli Zaretskii <eliz@gnu.org>
+
+ GNUmakefile: Fix last change.
+
+2021-04-01 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'extraclean' targets
+
+ * GNUmakefile: Add description of 'extraclean'.
+
+ * Makefile.in (extraclean_dirs): Add lwlib.
+
+ * lwlib/Makefile.in (clean mostlyclean extraclean): Add
+ 'extraclean' target.
+
+ * lisp/Makefile.in (extraclean): Remove ${loaddefs}, not just
+ ${LOADDEFS}. Delete all backup and autosave files.
+
+2021-04-01 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in epg-config.el and add tests
+
+ * lisp/epg-config.el: Use lexical-binding.
+ (epg-find-configuration): Improve error message.
+ * test/lisp/epg-config-tests.el: New file.
+
+2021-04-01 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in isearchb.el
+
+ * lisp/isearchb.el: Use lexical-binding. Remove redundant :group
+ args.
+
+2021-04-01 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant #' before lambda in Gnus
+
+ * lisp/gnus/gnus-group.el (gnus-group-list-cached)
+ (gnus-group-list-dormant, gnus-group-list-ticked):
+ * lisp/gnus/gnus-registry.el (gnus-registry-remove-extra-data):
+ * lisp/gnus/gnus-score.el (gnus-score-edit-file-at-point):
+ * lisp/gnus/gnus-sum.el (gnus-fetch-headers):
+ * lisp/gnus/mm-partial.el (mm-inline-partial):
+ * lisp/gnus/nnselect.el (nnselect-uncompress-artlist)
+ (numbers-by-group, nnselect-request-expire-articles)
+ (nnselect-request-update-info, nnselect-request-thread):
+ * lisp/gnus/nnvirtual.el (nnvirtual-request-expire-articles):
+ * lisp/gnus/spam-stat.el (spam-stat-score-buffer): Remove redundant #'
+ before lambda.
+
+2021-04-01 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in avoid.el
+
+ * lisp/avoid.el: Use lexical-binding. Remove redundant :group args.
+ (mouse-avoidance-fancy): Quote function symbol as such.
+
+2021-04-01 Stefan Kangas <stefan@marxist.se>
+
+ Use emacs-version instead of obsolete version variables
+
+ * lisp/calendar/icalendar.el (icalendar-version):
+ * lisp/dframe.el (dframe-version):
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-version):
+ * lisp/emulation/edt.el (edt-version):
+ * lisp/international/mule.el (mule-version):
+ * lisp/linum.el (linum-version):
+ * lisp/play/bubbles.el (bubbles-version):
+ * lisp/textmodes/remember.el (remember-version):
+ * lisp/url/url-vars.el (url-version):
+ * lisp/woman.el (woman-version): Use emacs-version instead of obsolete
+ version variables.
+
+2021-04-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/strokes.el: Use lexical-binding. Remove redundant `:group` args
+
+ (strokes-char-table): Move initialization into declaration.
+
+2021-04-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/forms.el: Use lexical-binding. Remove redundant `:group` args
+
+ (forms--process-format-list, forms--debug): Strength-reduce `eval`
+ to `symbol-value`.
+
+2021-04-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/dcl-mode.el: Use lexical-binding
+
+ (dcl-guess-option-value, dcl-save-local-variable)
+ (dcl-save-nondefault-options): Strength-reduce `eval` to `symbol-value`.
+
+2021-03-31 Eli Zaretskii <eliz@gnu.org>
+
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Fix debug level 1.
+
+2021-03-31 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp-sh.el (tramp-sh-gio-monitor-process-filter):
+
+ Make assumption for emba.
+
+2021-03-31 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-final): Clean-up temporary file.
+
+2021-03-31 Andrea Corallo <akrl@sdf.org>
+
+ Rework native compilation `comp-debug' (bug#46495)
+
+ * lisp/emacs-lisp/comp.el (comp-debug): Update docstring and
+ move default on Windows systems from 0 to 1.
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Tweak debug
+ levels.
+
+2021-03-31 Andrea Corallo <akrl@sdf.org>
+
+ Do not defer compilation when bytecode is explicitly requested (bug#46617)
+
+ * src/comp.c (maybe_defer_native_compilation): Check if the file
+ is registered in 'V_comp_no_native_file_h'.
+ (syms_of_comp): 'V_comp_no_native_file_h' new global.
+ * src/lread.c (maybe_swap_for_eln): Register files in
+ 'V_comp_no_native_file_h'.
+ * lisp/faces.el (tty-run-terminal-initialization): Do not
+ explicitly load .elc file to not exclude .eln being loaded in
+ place.
+
+2021-03-31 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in progmodes/inf-lisp.el
+
+ * lisp/progmodes/inf-lisp.el: Use lexical-binding. Doc fixes.
+ (inferior-lisp-mode-map, lisp-mode-map)
+ (inferior-lisp-install-letter-bindings): Quote function symbols as such.
+ (inferior-lisp-menu, lisp-compile-string, lisp-eval-string)
+ (lisp-show-variable-documentation): Doc fixes.
+
+2021-03-31 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into native-comp
+
+ * lisp/emacs-lisp/comp.el (comp-debug): Fix docstring.
+
+2021-03-31 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in scroll-all.el
+
+ * lisp/scroll-all.el: Use lexical-binding.
+ (scroll-all-scroll-down-all, scroll-all-scroll-up-all)
+ (scroll-all-page-down-all, scroll-all-page-up-all)
+ (scroll-all-beginning-of-buffer-all)
+ (scroll-all-end-of-buffer-all): Doc fixes.
+
+2021-03-31 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/dynamic-setting.el: Use lexical-binding.
+
+2021-03-31 Luke Lee <luke.lee@synaptics.com>
+
+ Fix incorrect regular expression for more general text replacements.
+
+ * lisp/progmodes/hideif.el (hif-evaluate-macro): fix regexp to trim
+ off leading/trailing spaces, but not within.
+
+2021-03-31 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in chistory.el
+
+ * lisp/chistory.el: Use lexical-binding. Remove redundant :group
+ args.
+ (command-history-mode-map): Quote function symbols as such.
+
+2021-03-31 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/ebuff-menu.el: Use lexical-binding.
+
+2021-03-31 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in double.el
+
+ * lisp/double.el: Use lexical-binding. Remove redundant :group
+ args.
+
+2021-03-31 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in dirtrack.el
+
+ * lisp/dirtrack.el: Use lexical-binding. Remove redundant group
+ args.
+
+2021-03-31 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/progmodes/cwarn.el: Use lexical-binding.
+
+2021-03-30 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant #' before lambda in cedet
+
+ * lisp/cedet/mode-local.el (mode-local-map-mode-buffers)
+ (mode-local--activate-bindings, mode-local--deactivate-bindings)
+ (setq-mode-local, describe-mode-local-bindings-in-mode):
+ * lisp/cedet/semantic.el (semantic-repeat-parse-whole-stream):
+ * lisp/cedet/semantic/bovine/c.el (semantic-c-describe-environment):
+ * lisp/cedet/semantic/db-ebrowse.el
+ (semanticdb-ebrowse-get-ebrowse-structure):
+ * lisp/cedet/semantic/db-global.el
+ (semanticdb-enable-gnu-global-databases):
+ * lisp/cedet/semantic/edit.el (semantic-changes-in-region):
+ * lisp/cedet/semantic/fw.el (semantic-install-function-overrides):
+ * lisp/cedet/semantic/grammar.el (semantic-grammar-ASSOC)
+ (semantic-grammar-tag-symbols, semantic-grammar-keywords)
+ (semantic--grammar-macros-regexp-1)
+ (semantic-format-tag-summarize):
+ * lisp/cedet/semantic/idle.el (semantic-idle-core-handler)
+ (semantic-idle-work-core-handler):
+ * lisp/cedet/semantic/imenu.el (semantic-imenu-semanticdb-hook):
+ * lisp/cedet/semantic/java.el (semantic-java-doc-keywords-map)
+ (semantic-java-doc-setup):
+ * lisp/cedet/semantic/lex-spp.el (semantic-lex-spp-save-table)
+ (semantic-lex-spp-macros):
+ * lisp/cedet/semantic/lex.el (semantic-lex-map-symbols)
+ (semantic-lex-keywords, semantic-lex-types):
+ * lisp/cedet/semantic/util-modes.el
+ (semantic-toggle-minor-mode-globally):
+ * lisp/cedet/semantic/wisent/comp.el (wisent-defcontext)
+ (wisent-automaton-lisp-form):
+ * lisp/cedet/semantic/wisent/grammar.el (wisent-grammar-assocs)
+ (wisent-grammar-terminals): Remove redundant #' before lambda.
+
+2021-03-30 Stefan Kangas <stefan@marxist.se>
+
+ Delete Emacs 19 compat code in foldout.el
+
+ * lisp/foldout.el (foldout-hide-flag):
+ (foldout-show-flag): Delete Emacs 19 compat code and make obsolete.
+ (foldout-exit-fold): Don't use above obsolete variable.
+
+2021-03-30 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in lpr.el and add rudimentary tests
+
+ * lisp/lpr.el: Use lexical-binding. Remove redundant :group args.
+ (print-region-function): Declare MS-Windows specific function.
+ * test/lisp/lpr-tests.el: New file.
+
+2021-03-30 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in echistory.el
+
+ * lisp/echistory.el: Use lexical-binding.
+ (electric-history-map): Quote function symbols as such.
+ (Electric-history-undefined): Use command substitutions.
+
+2021-03-30 Stefan Kangas <stefan@marxist.se>
+
+ Delete empty "History" sections
+
+ * lisp/bs.el:
+ * lisp/calendar/timeclock.el:
+ * lisp/cedet/semantic/bovine/grammar.el:
+ * lisp/cedet/semantic/grammar.el:
+ * lisp/cedet/semantic/wisent.el:
+ * lisp/cedet/semantic/wisent/comp.el:
+ * lisp/cedet/semantic/wisent/java-tags.el:
+ * lisp/cedet/semantic/wisent/wisent.el:
+ * lisp/erc/erc.el:
+ * lisp/net/newst-treeview.el:
+ * lisp/recentf.el:
+ * lisp/ruler-mode.el:
+ * lisp/textmodes/remember.el:
+ * lisp/thumbs.el:
+ * lisp/tree-widget.el:
+ * lisp/vc/vc-hg.el: Delete empty "History" sections.
+
+ * lisp/cedet/semantic/grammar.el
+ (semantic-grammar-header-template): Don't add "History" section to
+ generated file.
+
+2021-03-30 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in follow.el
+
+ * lisp/follow.el: Use lexical-binding.
+ (follow-mode-map, follow-debug-message): Quote function symbols as
+ such.
+ (follow-pos-visible-in-window-p): Remove unused variable 'last'.
+ (follow-move-to-window-line): Remove unused variable 'middle-window'.
+
+2021-03-30 Mattias Engdegard <mattiase@acm.org>
+
+ lisp/progmodes/verilog-mode.el internal code cleanup.
+
+ * lisp/progmodes/verilog-mode.el (verilog-at-close-struct-p):
+ Internal code cleanup.
+
+2021-03-30 Arash Esbati <arash@gnu.org>
+
+ * lisp/textmodes/reftex-auc.el: Improve the external function declarations
+
+ (LaTeX-add-bibitems): Move declaration closer to the others.
+ Fix those declarations to refer to the right file.
+
+2021-03-30 Dmitry Gutov <dgutov@yandex.ru>
+
+ Provide information to show icons with Elisp completions
+
+ * lisp/progmodes/elisp-mode.el (elisp--company-kind): New function.
+ (elisp-completion-at-point): Use it. And a couple of anonymous
+ :company-kind functions too.
+
+2021-03-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ lisp/progmodes/verilog-mode.el: Prepare for lexical-binding.
+
+ * lisp/progmodes/verilog-mode.el: Activate lexical-binding.
+ Insert newlines to avoid some situations where arguments were easy
+ to misunderstand.
+ (verilog-set-compile-command): Strength-reduce `eval` to `symbol-value`.
+ (verilog-error-regexp-add-emacs): Replace `mapcar` => `mapc` since
+ the result is not used.
+ (verilog-surelint-off): Remove always-nil var `dir`.
+ (verilog-do-indent): Minor simplification of the code.
+ (verilog-pred): Delete var. It was always nil.
+ (verilog-flag): Delete var; pass the corresponding data via
+ explicit arguments instead.
+ (verilog-keyword-completion): Use `dolist`.
+ (verilog-completion-response): Rename to `verilog--complete-with-action`.
+ Change calling convention to match that of `complete-with-action`.
+ Use `complete-with-action` instead when available.
+ Adjust all callers.
+ (verilog-completion, verilog-comp-defun): Change arg names so they
+ don't collide with dynamically scoped vars, and let-bind `verilog-str`
+ explicitly instead. Use `with-current-buffer`.
+ (verilog-batch-execute-func): Use `with-current-buffer`.
+ (verilog-complete-word): Don't convert the completion list into
+ a completion alist, since lists work just as well.
+ (verilog-showscopes): Use `with-current-buffer`.
+ (verilog-symbol-detick, verilog-symbol-detick-text)
+ (verilog-signals-matching-enum): Strength-reduce `eval` to `symbol-value`.
+ (verilog--insert-indent): Rename from `verilog--insert-indent`.
+ Add `indent-pt` argument.
+ (verilog-insert-indent): New macro wrapper to provide the old
+ calling convention.
+ (verilog-auto-assign-modport, verilog-auto-inout-modport):
+ Remove always-nil var `direction-re`.
+ (verilog--auto-inst-first): Rename from `verilog-auto-inst-first`.
+ Add `indent-pt` argument.
+ (verilog-auto-inst-port): Adjust call accordingly.
+
+2021-03-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/verilog-mode.el: Use #' where appropriate.
+
+2021-03-30 Wilson Snyder <wsnyder@wsnyder.org>
+
+ lisp/progmodes/verilog-mode.el: Fix indentation of enum.
+
+ * lisp/progmodes/verilog-mode.el (verilog-at-close-struct-p): Fix
+ indentation of enum with multiple objects. Reported by punzik. (#1716).
+
+2021-03-29 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/completion.el: Activate lexical-binding
+
+ Remove redundant `:group` arguments.
+
+ (list-all-completions-1): Merge into `list-all-completions` and
+ then delete.
+ (list-all-completions-by-hash-bucket-1): Use `push`. Merge into
+ `list-all-completions-by-hash-bucket` and then delete.
+ (completions-list-return-value): Delete variable, not used any more.
+
+2021-03-29 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/woman.el: Activate lexical-binding. Require `cl-lib`
+
+ (woman-mode, woman2-roff-buffer): Use `cl-letf`.
+ (woman-request): Move declaration before first use.
+ (woman0-macro): Rename arg to not shadow the dynamically scoped var.
+ (woman-set-arg): Strength-reduce `eval` to `symbol-value`.
+
+2021-03-29 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/project.el (project-regexp-history-variable): New variable.
+
+ (project--read-regexp): Use it as HISTORY arg of 'read-regexp' with
+ 'grep-regexp-history' default (bug#47012).
+
+2021-03-29 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/allout*.el: Use lexical-binding
+
+ * lisp/allout.el: Activate lexical-binding.
+ (allout-setup-menubar): Delete "complex no-op" function.
+ (allout-mode): Delete call to it.
+ (allout-hotspot-key-handler): Delete XEmacs-only code.
+ (allout-copy-exposed-to-buffer): Remove always-nil var `start-list`.
+
+ * lisp/allout-widgets.el: Activate lexical-binding.
+ (allout-item-icon-keymap): Use `ignore`.
+ (allout-widgets-exposure-change-processor): Use `cl-callf` instead of
+ relying on dynamic binding to apply some code to two different variables.
+
+2021-03-29 Alan Mackenzie <acm@muc.de>
+
+ Fix an infinite loop in C++ Mode redisplay. This was bug #47191.
+
+ * lisp/progmodes/cc-defs.el (c-forward-syntactic-ws, c-backward-syntactic-ws):
+ When point is on the wrong side of a supplied search limit, leave point
+ unmoved rather than setting it to that limit.
+
+ * lisp/progmodes/cc-engine.el (c-forward-name): After scanning a template
+ argument list (which is not itself subject to a search limit) recalculate the
+ search limit starting from the end point, since these argument lists can
+ legitimately be long. At each of the scanning loops, check point hasn't gone
+ past the limit.
+
+2021-03-29 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 8a92030f6a (origin/emacs-27) Fix hang in autorevert-tests.el
+
+ # Conflicts:
+ # test/lisp/autorevert-tests.el
+
+2021-03-29 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ bcc4cc3362 Doc fixes for 'face-foreground' and 'face-background'.
+ bf6442fafd ; * admin/make-tarball.txt: Minor addition to the Web page...
+ 38b127d32e * admin/admin.el (set-version): Handle malformed NEWS markup.
+ 0d7e2a993e admin.el fix for bug#47394
+ fdec444758 ; * etc/NEWS: Fix typo.
+ 1e6ca2765f ; * admin/make-tarball.txt: Another minor addition.
+
+ # Conflicts:
+ # etc/NEWS
+
+2021-03-29 Michael Albinus <michael.albinus@gmx.de>
+
+ Some Tramp doc clarifications
+
+ * doc/misc/tramp.texi (Remote shell setup): Explain meaning of
+ `tramp-sh-extra-args' for bash.
+ (Frequently Asked Questions): New item about unloading / reloading Tramp.
+
+2021-03-29 Eli Zaretskii <eliz@gnu.org>
+
+ Protect add-variable-watcher from incorrect usage
+
+ * src/data.c (Fadd_variable_watcher): Avoid crashes if SYMBOL
+ isn't. (Bug#47462)
+
+2021-03-29 Michael Albinus <michael.albinus@gmx.de>
+
+ Optimize test jobs for emba
+
+ * test/infra/gitlab-ci.yml (.test-template): Do not run fast and
+ normal test jobs when scheduled.
+
+2021-03-29 Stefan Kangas <stefan@marxist.se>
+
+ Doc fixes in follow.el
+
+ * lisp/follow.el:
+ (follow-pos-visible-in-window-p, follow-adjust-window)
+ (follow-prev-buffer, follow-internal-force-redisplay):
+ Minor doc fixes.
+
+2021-03-29 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/infra/gitlab-ci.yml (test-filenotify-gio): Use *.log for make_params.
+
+2021-03-28 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix hang in autorevert-tests.el
+
+ * test/lisp/autorevert-tests.el (auto-revert--wait-for-revert):
+ Apply more robust check, whether file notification is used.
+
+2021-03-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix a dbus.el byte compilation warning
+
+ * lisp/net/dbus.el (dbus-register-monitor): Silence a
+ byte-compilation warning on systems without dbus.
+
+2021-03-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use a 64KB page size for pdump
+
+ * src/pdumper.c (dump_get_page_size): Use a 64KB page size on all
+ architectures, as this many vary between systems (bug#47125).
+
+2021-03-28 Michael Albinus <michael.albinus@gmx.de>
+
+ * admin/notes/emba: Explain job types and artifacts.
+
+2021-03-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Clarify dired-do-shell-command doc string"
+
+ This reverts commit cf607c262e15c873961fdfcced254e6f8e82f8d7.
+
+ The doc string already explains this.
+
+ (cherry picked from commit 01cf0eb75786834b7a0ee5be34be53f6e8e14c11)
+
+2021-03-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Clarify dired-do-shell-command doc string"
+
+ This reverts commit cf607c262e15c873961fdfcced254e6f8e82f8d7.
+
+ The doc string already explains this.
+
+2021-03-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify dired-do-shell-command doc string
+
+ * lisp/dired-aux.el (dired-do-shell-command): Mention what happens
+ to FILE-LIST (bug#47432).
+
+ (cherry picked from commit cf607c262e15c873961fdfcced254e6f8e82f8d7)
+
+2021-03-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify dired-do-shell-command doc string
+
+ * lisp/dired-aux.el (dired-do-shell-command): Mention what happens
+ to FILE-LIST (bug#47432).
+
+2021-03-28 Eli Zaretskii <eliz@gnu.org>
+
+ Doc fixes for 'face-foreground' and 'face-background'.
+
+ * lisp/faces.el (face-foreground, face-background): Clarify how a
+ face specified in INHERIT arg is used. (Bug#47437)
+
+2021-03-28 pillule <pillule@riseup.net> (tiny change)
+
+ compilation-goto-locus does not handle right display-buffer
+
+ * lisp/progmodes/compile.el (compilation-goto-locus): Pop to the
+ source buffer if the match buffer is the selected window (bug#47414).
+
+2021-03-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify the doc string of plist-memeber and plist-put
+
+ * src/fns.c (Fplist_member):
+ (Fplist_put): Clarify what comparison function is used for PROP
+ (bug#47426) and don't claim that PROP has to be a symbol.
+
+2021-03-28 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid errors in pulse.el for some face customizations
+
+ * lisp/cedet/pulse.el (pulse-momentary-highlight-overlay): Make
+ sure 'face-background' always returns a color name. Suggested by
+ Ingo Lohmar <ingo.lohmar@posteo.net> in bug#47437.
+
+2021-03-28 Michael Albinus <michael.albinus@gmx.de>
+
+ Make artifacts working on emba (hopefully)
+
+ * test/infra/gitlab-ci.yml (.job-template): Use proper docker name.
+ (.test-template): Adapt artifacts path.
+
+2021-03-27 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Demote read-extended-command-predicate errors
+
+ For discussion, see the following thread:
+ https://lists.gnu.org/r/emacs-devel/2021-03/msg00682.html
+
+ * lisp/simple.el (read-extended-command): Demote errors when calling
+ read-extended-command-predicate so M-x completion doesn't break.
+
+2021-03-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/wdired.el (wdired--self-insert): Fix thinko
+
+2021-03-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/wdired.el: Fix minor regressions and simplify a bit
+
+ Use `wdired--current-column` more consistently to avoid mayhem when it
+ doesn't return the same result as `current-column`.
+
+ (wdired-get-filename): Fix the unprocessed case.
+ (wdired-finish-edit): Don't force processing all the lines.
+ (wdired--col-perm): Remove, redundant with `wdired--perm-beg`.
+ (wdired-change-to-wdired-mode): Don't error in empty directory.
+ (wdired--set-permission-bounds): Set `wdired--perm-beg` when we can't
+ find permissions. Move `wdired--perm-beg` 1 char further (like
+ `wdired--col-perm`). Use `wdired--current-column`.
+ (wdired--point-at-perms-p): Fix when `wdired--perm-beg` is nil.
+ (wdired--self-insert): Lookup the keymap to know command to call.
+ (wdired--before-change-fn): Just use `point` instead of `beg`.
+ Use `with-silent-modifications` here rather than in each of the
+ `wdired--preprocess-*` functions.
+ (wdired--preprocess-files): Presume we're at BOL and within
+ `with-silent-modifications`. Fix application of `read-only`.
+ (wdired-abort-changes): Don't use `with-silent-modifications` since
+ we're really modifying the buffer.
+ (wdired--preprocess-symlinks): Presume we're at BOL and within
+ `with-silent-modifications`.
+ (wdired--preprocess-perms): Presume we're at BOL and within
+ `with-silent-modifications`.
+ (wdired-set-bit): Add `char` argument. Use `wdired--current-column`.
+ Copy previous text properties rather than duplicating the code of
+ `wdired--preprocess-perms`.
+ (wdired-toggle-bit): Delegate to `wdired-set-bit`.
+
+2021-03-27 Arthur Miller <arthur.miller@live.com>
+
+ * lisp/wdired.el: Apply text properties lazily
+
+ Entering wdired was taking time proportional to the size of the directory,
+ making it inconvenient to quickly enter wdired just to rename one or two
+ files in a large directory.
+
+ (wdired-mode-map): Rebind `self-insert-command`.
+ (wdired--perm-beg, wdired--perm-end): New vars.
+ (wdired--col-perm, wdired--old-content, wdired--old-point)
+ (wdired--old-marks): Rename vars, using "--" rather than "-".
+ All users updated.
+ (wdired--before-change-fn): New function.
+ (wdired-change-to-wdired-mode): Use it `before-change-functions`
+ instead of eagerly putting the various text properties here.
+ (wdired--set-permission-bounds, wdired--current-column)
+ (wdired--point-at-perms-p, wdired--line-preprocessed-p):
+ New auxiliary functions.
+ (wdired--self-insert): New command.
+ (wdired--preprocess-files, wdired--preprocess-symlinks)
+ (wdired--preprocess-perms): Add "--" to the name. Make it operate only
+ on the current line. Use `with-silent-modifications`.
+ (wdired-abort-changes): Use `with-silent-modifications`.
+
+2021-03-27 Michael Albinus <michael.albinus@gmx.de>
+
+ Keep *.log files on emba
+
+ * test/infra/gitlab-ci.yml (.test-template): New template.
+ (test-fast-inotify, test-lisp-inotify, test-lisp-net-inotify)
+ (test-filenotify-gio, test-gnustep, test-all-inotify): Use it.
+
+2021-03-27 Eli Zaretskii <eliz@gnu.org>
+
+ Fix lisp/files-tests on MS-Windows
+
+ * test/lisp/files-tests.el (files-colon-path)
+ (files-tests-bug-21454): Adapt to MS-DOS/Windows, where
+ parse-colon-path needs and absolute file name with a drive letter.
+ (files-tests-file-name-non-special-get-file-buffer): Forcefully
+ delete the file's buffer if it happens to exist.
+
+2021-03-27 Matt Armstrong <matt@rfc20.org>
+
+ File unlock errors now issue warnings (Bug#46397)
+
+ The primary idea is to allow `kill-buffer' and `kill-emacs' to
+ complete even if Emacs has trouble unlocking the buffer's file.
+
+ * lisp/userlock.el (userlock--handle-unlock-error): New function, call
+ `display-error'.
+ * src/filelock.c (unlock_file_body): New function, do what
+ 'unlock_file' used to.
+ (unlock_file_handle_error): New function, call
+ `userlock--handle-unlock-error' with the captured error.
+ (unlock_file): Handle `file-error' conditions by calling the handler
+ defined above.
+ * test/src/filelock-tests.el (filelock-tests-kill-buffer-spoiled):
+ (filelock-tests-unlock-spoiled): Modify to test new behavior.
+
+2021-03-27 Matt Armstrong <matt@rfc20.org>
+
+ Add test coverage for src/filelock.c (Bug#46397)
+
+ * test/src/filelock-tests.el: New file.
+
+2021-03-27 Kenichi Handa <handa@gnu.org>
+
+ Fix encoding by ISO-2022-JP
+
+ * src/coding.c (encode_coding): Reset the CODING_MODE_LAST_BLOCK
+ flag for all iterations but the last one. (Bug#46933)
+
+2021-03-26 Michael Albinus <michael.albinus@gmx.de>
+
+ Improve remote file notifications
+
+ * lisp/net/tramp-sh.el (tramp-get-remote-gio-file-monitor): Remove it.
+ (tramp-sh-handle-file-notify-add-watch): Do not call it.
+ (tramp-sh-gio-monitor-process-filter): Read monitor name.
+
+ * test/lisp/filenotify-tests.el (file-notify--test-read-event)
+ (file-notify--test-timeout): Change timings.
+ (file-notify--test-monitor): Read remote monitor name more reliably.
+ (file-notify-test02-rm-watch): Retrieve remote monitor name in time.
+ (file-notify--test-event-actions): New defun.
+ (file-notify--test-with-actions-explainer): Use it.
+ (file-notify--test-with-actions-check): Use it. Dump traces in
+ case of debug.
+ (file-notify--test-with-actions): Don't stop while debugging.
+ (file-notify-test03-events, file-notify-test04-autorevert)
+ (file-notify-test05-file-validity)
+ (file-notify-test07-many-events, file-notify-test08-backup)
+ (file-notify-test09-watched-file-in-watched-dir): Adapt tests.
+
+2021-03-26 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Address some --without-x byte-compilation warnings
+
+ These came to light in the contexts of bug#29713 and bug#47234.
+
+ * lisp/emulation/edt-mapper.el (edt-xserver):
+ * lisp/emulation/edt.el (edt-xserver):
+ * lisp/gnus/gnus-util.el (gnus-rescale-image):
+ * lisp/gnus/nnimap.el (nnimap-map-port):
+ * lisp/term/w32-win.el:
+ * lisp/image.el (image--get-imagemagick-and-warn):
+ * lisp/frame.el (frame-notice-user-settings): Declare functions that
+ are known to be present at runtime in GUI builds.
+ (make-frame-on-display): Signal more informative error when called
+ interactively in a non-GUI build (bug#29713).
+ * lisp/international/mule-diag.el (describe-font):
+ * lisp/org/org-macs.el (org--string-from-props): Pacify warnings
+ about unknown functions in non-GUI bilds.
+ * lisp/mh-e/mh-mime.el (mh-small-image-p): Avoid eliminating fboundp
+ check in non-GUI builds, to pacify unused lexical variable warning.
+ * lisp/net/newst-plainview.el (newsticker--plainview-tool-bar-map):
+ * lisp/net/newst-treeview.el (newsticker-treeview-tool-bar-map):
+ Declare tool-bar-map as a special variable in non-GUI builds.
+
+2021-03-26 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/obsolete/tpu-extras.el: Avoid defadvice
+
+ (tpu--respect-bottom-scroll-margin): New function, extracted from
+ `newline`s defadvice.
+ (newline, newline-and-indent, do-auto-fill): Delete defadvice.
+ (tpu-set-scroll-margins): Use advice-add instead of
+ `ad-enable-advice`+`ad-activate`.
+ Use an explicit arg instead of `called-interactively-p`.
+
+2021-03-26 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/mh-e/: Take advice-remove of the newly enabled lexical-binding
+
+ * lisp/mh-e/mh-mime.el (mh-mm-inline-message):
+ * lisp/mh-e/mh-inc.el (mh-inc-spool-generator): Replace `(lambda...)
+ with a proper closure.
+
+2021-03-26 Andrea Corallo <akrl@sdf.org>
+
+ Prevent stale eln loading checking file timestamp before load (bug#46617)
+
+ * src/lread.c (maybe_swap_for_eln): Add file timestamp check.
+ (openp): Update 'maybe_swap_for_eln' call sites.
+
+2021-03-25 Glenn Morris <rgm@gnu.org>
+
+ * admin/admin.el (set-version): Handle malformed NEWS markup.
+
+2021-03-25 Glenn Morris <rgm@gnu.org>
+
+ admin.el fix for bug#47394
+
+ * admin/admin.el (manual-html-fix-index-2): Handle Texinfo 6.7.
+
+2021-03-25 Spencer Baugh <sbaugh@catern.com>
+
+ Assert not local-variable-p after setq in let_default binding
+
+ Breaking this is a likely way to break this test, so this saves a bit
+ of time in debugging.
+
+ * test/src/data-tests.el (data-tests--let-buffer-local):
+ Add assertion to test.
+
+2021-03-25 Spencer Baugh <sbaugh@catern.com>
+
+ Add a test for let-binding unwinding
+
+ Bindings in other buffers are not un-set when we unwind a let-binding
+ which set the default value. There doesn't seem to be an existing
+ test which covers this, so here's one.
+
+ * test/src/data-tests.el (data-tests--let-buffer-local-no-unwind-other-buffers):
+ Add test for let-binding unwinding behavior
+
+2021-03-25 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/htmlfontify.el: Fix misuses of `nconc`
+
+ (hfy-face-to-style-i): `this` is not known to be fresh.
+ (hfy--size-to-int): Rename from `hfy--size-to-int` and return just the
+ integer without wrapping it in a list.
+ (hfy-flatten-style): Avoid O(n²) problems. Use `float`.
+
+2021-03-25 Bill Wohler <wohler@newt.com>
+
+ Remove XEmacs support in lexical-binding
+
+ * lisp/mh-e/mh-alias.el (mh-alias-insert-file): Remove reference to
+ remove-specifier.
+
+2021-03-25 Mark A. Hershberger <mah@nichework.com>
+
+ Update rnc to use Open Document's Relax-NG schema to version 1.3
+
+ * etc/schema/OpenDocument-schema-v1.3+libreoffice.rnc:
+ * etc/schema/OpenDocument-schema-v1.3.rnc: New files.
+ * etc/schema/schemas.xml: Use the LibreOffice Relax-NG files since
+ they include a hack to support 1.2.
+
+ rng source:
+ https://raw.githubusercontent.com/freedesktop/libreoffice-core/master/
+ schema/libreoffice/OpenDocument-schema-v1.3%2Blibreoffice.rng
+ translation to rnc with trang:
+ trang -I rng -O rnc OpenDocument-schema-v1.3+libreoffice.rng \
+ OpenDocument-schema-v1.3+libreoffice.rnc
+
+2021-03-25 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into native-comp
+
+2021-03-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ Merge from origin/emacs-27
+
+ 291a421c2e * admin/make-tarball.txt: Improve and expand the instructi...
+ 0e4795fc98 Fix preeditarea reporting wrong spot.
+
+2021-03-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ Merge from origin/emacs-27
+
+ deef5efafb ; * ChangeLog.3: Update with the log of the last change.
+ bd991e3c9b Fix frame-inner-height in non-GUI builds
+
+2021-03-25 Eli Zaretskii <eliz@gnu.org>
+
+ * admin/make-tarball.txt: Improve and expand the instructions.
+
+2021-03-25 Amos Bird <amosbird@gmail.com>
+
+ Fix preeditarea reporting wrong spot.
+
+ This patch adjust the x position of preeditarea with both left fringe
+ and left margin, which prevents IME preedit box (such as fcitx) from
+ placing at the wrong position in GUI emacs.
+ * src/xfns.c (xic_set_preeditarea): Adjust X for left margin width.
+ (Bug#47377)
+
+2021-03-25 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt Tramp file notification support
+
+ * lisp/net/tramp-integration.el (tramp-use-ssh-controlmaster-options):
+ Declare it.
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-file-notify-add-watch):
+ Remove "gvfs-monitor-dir".
+ (tramp-sh-gvfs-monitor-dir-process-filter)
+ (tramp-get-remote-gvfs-monitor-dir): Remove.
+ (tramp-get-remote-gio-file-monitor): Support also cygwin, and
+ GFamDirectoryMonitor, GPollFileMonitor.
+
+2021-03-25 Glenn Morris <rgm@gnu.org>
+
+ * doc/emacs/maintaining.texi (Managing Projects): Fixes and copyedits.
+
+2021-03-25 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix typo
+
+ * lisp/progmodes/project.el (project-remove-known-project):
+ Fix typo (bug#47287).
+
+2021-03-25 Theodor Thornhill <theo@thornhill.no>
+
+ Add command project-remove-known-project
+
+ * etc/NEWS: Mention the new command.
+
+ * lisp/progmodes/project.el (project--remove-from-project-list): Add
+ new argument, report-message, used to signal various messages when
+ removal has happened.
+
+ * lisp/progmodes/project.el (project-remove-known-project): New
+ command that removes the selected directory from the project-list-file.
+
+ * lisp/progmodes/project.el (project-current): Add the report message.
+
+ * doc/emacs/maintaining.texi: Add information about the new command to
+ the manual.
+
+2021-03-24 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * list/progmodes/idl*.el: Use lexical-binding
+
+ * lisp/progmodes/idlw-complete-structtag.el: Use lexical-binding.
+
+ * lisp/progmodes/idlw-help.el: Use lexical-binding.
+ Delete redundant `:group` arguments.
+ (idlwave-query-class, idlwave-force-class-query, idlw-help-name)
+ (idlw-help-kwd, idlw-help-link): Declare vars.
+ (idlwave-highlight-linked-completions): Remove unused var `class`.
+ (idlwave-help-find-in-doc-header): Remove unused var `header-re`.
+
+ * lisp/progmodes/idlw-shell.el (idlwave-shell-input-mode-magic):
+ Remove XEmacs-only code.
+ (idlwave-shell-filter, idlwave-shell-scan-for-state):
+ Use `functionp` since a function can also satisfy `listp`.
+ (idlwave-shell--mouse-examine): Rename from `idlwave-shell-mouse-examine`.
+ Make it a function, and simplify for Emacs≥22. Simplify calling convention
+ since all callers always immediately `funcall`d the result.
+ Update all callers.
+ (idlwave-default-mouse-track-event-is-with-button): Use `always`.
+ (idlwave-shell-filter-bp): Simplify a tiny bit.
+
+ * lisp/progmodes/idlw-toolbar.el: Use lexical-binding.
+ (idlwave-toolbar-add, idlwave-toolbar-remove)
+ (idlwave-toolbar-add-everywhere, idlwave-toolbar-remove-everywhere)
+ (idlwave-toolbar-toggle): Remove XEmacs-only code.
+
+ * lisp/progmodes/idlwave.el: Use lexical-binding.
+ (idlwave--dlet): New macro.
+ (<toplevel>): Use it.
+ (idlwave-keyword-abbrev): Turn it into a function.
+ (idlwave-code-abbrev): Delete macro.
+ (idlwave-mode-abbrev-table): Use `:enable-function` instead.
+ (idlwave-with-special-syntax): Delete macro; use `with-syntax-table`
+ instead in all callers.
+ (idlwave-action-and-binding): Use `alist-get` and replace `(lambda...)
+ with a proper closure. Change all callers to prefer passing a function
+ in the `cmd` argument.
+ (idlwave-fill-function): Delete constant var.
+ Replace its uses with its value (the symbol `auto-fill-function`).
+ (idlwave-mode): Set `normal-auto-fill-function` instead of the
+ cumbersome use of `idlwave-fill-function`. Tighten a regexp.
+ Don't set `imenu-create-index-function` to the value it should already have.
+ (idlwave-auto-fill-mode): Make it an obsolete alias for `auto-fill-mode`.
+ (idlwave-modify-abbrev): Rename from `idlwave-check-abbrev`.
+ Don't check `idlwave-quoted` since `:enable-function` did it for us already.
+ (idlwave--command-function): Rename from `idlwave-command-hook`
+ and make it hold a function rather than an expression.
+ (idlwave-command-hook, idlwave-modify-abbrev): Adjust accordingly.
+ (idlwave-show-begin-check): Don't check `idlwave-quoted` since
+ `:enable-function` did it for us already.
+ (idlwave-do-action): Use `functionp` since a function can also satisfy `listp`
+ (idlwave-new-sintern-type): Make it a macro, so we don't need to
+ `declare-function` for the functions it defines.
+ (idlwave--class-selector, idlwave--type-selector)
+ (idlwave--method-selector, idlwave--super-classes): Rename those vars
+ by adding the `idlwave--` prefix. Adjust all uses.
+ (idlwave-complete-functions): Rename from `idlwave-complete-special`.
+ (idlwave-call-special): Declare obsolete. Change all callers to use
+ `run-hook-with-args-until-success` instead.
+ (idlwave-complete-filename): Use `dlet`.
+ (idlwave-rinfo-assq-any-class): Remove unused var `class`.
+ (idlwave-determine-class-functions): Rename from
+ `idlwave-determine-class-special`; fix docstring since the functions
+ are called with only one argument.
+ (idlwave--complete-after-success-function): Rename from
+ `idlwave-complete-after-success-form` and make it hold a function.
+ Adjust all users.
+ (idlwave--complete-after-success-force-function): Rename from
+ `idlwave-complete-after-success-form-force` and make it hold a function.
+ Adjust all users.
+ (idlwave-attach-classes): Remove always-t variable `do-dots`.
+ (idlwave-local-value): Use `local-variable-p` and `buffer-local-value`
+ to avoid `with-current-buffer`.
+ (idlwave-default-choose-completion): Comment out (unused and calls
+ a function that doesn't exist).
+ (idlwave-shell-filter-sysvars): Remove unused vars `type`, `name`, and `class`
+ (idlwave-fix-module-if-obj_new): Remove unused var `name`.
+ (idlwave-fix-keywords): Bind `idlwave--super-classes` via `let` than
+ via the function's argument.
+ (idlwave-twin-class, idlwave-twin-name): Move before first use.
+ (idlwave-study-twins): Remove stealth/redundant `type` variable.
+ (idlwave-routine-entry-compare-twins): Remove unused var `type`.
+ (idlwave-path-alist-add-flag): Avoid `add-to-list` on a local var.
+ (idlwave-list-abbrevs): Simplify a tiny bit.
+
+2021-03-24 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-tab-post-change-group-functions): New hook.
+
+ (tab-bar-change-tab-group): Run it.
+ (tab-bar-move-tab-to-group): New command for new hook.
+
+2021-03-24 Alan Mackenzie <acm@muc.de>
+
+ Improve failure reporting in test/lisp/electric-tests.el
+
+ In particular, on a failure, output the test's doc string to
+ electric-tests.log, along with all the other failure information.
+ Fixes bug #47320.
+
+ * test/lisp/electric-tests.el (electric-pair-test-for) New
+ parameter doc-string. On a test failure, output the doc-string
+ parameter with message.
+ (electric-pair-define-test-form): Set the new variable doc-string to the
+ generated doc string, and pass this as argument to both ert-deftest and
+ electric-pair-test-for.
+
+2021-03-24 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/auth-source-pass.el (auth-source): Silence spurious warning
+
+2021-03-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous format-prompt change: The default can be a symbol
+
+ * lisp/minibuffer.el (format-prompt): The default can also be a
+ symbol.
+
+2021-03-24 Harald Jörg <haj@posteo.de>
+
+ perl-mode: Fix regexps for fontification
+
+ * test/lisp/progmodes/cperl-mode-tests.el
+ (cperl-test-fontify-declarations): New test to ensure consistency
+ between perl-mode.el and cperl-mode.el (bug#47345).
+ * lisp/progmodes/perl-mode.el (perl-font-lock-keywords-1): pick
+ correct capture groups for "use Pack::Age;"
+ Fontify all components of "Pack::Age", not just "Pack"
+ (perl-font-lock-keywords-2): Use keyword-face for declarators
+
+2021-03-24 Andrea Corallo <akrl@sdf.org>
+
+ Improve two native compiler related docstrings.
+
+ * lisp/emacs-lisp/comp.el (comp-eln-load-path-eff): Improve docstring.
+ * src/comp.c (comp-eln-load-path): Likewise.
+
+2021-03-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Remove font-lock toggle from font-lock-update"
+
+ This reverts commit 23995414fec483287e7fb9c9a279483319f9fc54.
+
+ The subject is under discussion.
+
+2021-03-24 Paul W. Rankin <pwr@bydasein.com>
+
+ Remove font-lock toggle from font-lock-update
+
+ * lisp/font-lock.el (font-lock-update): Remove call to
+ font-lock-unfontify-region and font-lock-mode toggle with ARG; this
+ did not perform what original author intended
+
+2021-03-24 Andrea Corallo <akrl@sdf.org>
+
+ * src/lread.c (maybe_swap_for_eln): Fix eln filename (bug#bug#47337).
+
+2021-03-24 Dmitry Gutov <dgutov@yandex.ru>
+
+ xref.el: Keep Emacs 26 compatibility
+
+ * lisp/progmodes/xref.el (xref--read-identifier)
+ (xref-find-definitions, xref-find-definitions-other-window)
+ (xref-find-definitions-other-frame, xref-find-references):
+ Undo the latest change for Emacs 26 compatibility (bug#47286).
+
+2021-03-24 Gabriel do Nascimento Ribeiro <gabriel.nascimento@nubank.com.br>
+
+ Add optional FORMAT argument to 'emacs-init-time'
+
+ * lisp/time.el (emacs-init-time): Add optional FORMAT argument
+ (bug#47306).
+
+2021-03-24 Gabriel do Nascimento Ribeiro <gabriel.nascimento@nubank.com.br>
+
+ Replace "(default %s)" with 'format-prompt'
+
+ * lisp/cmuscheme.el (scheme-load-file, scheme-compile-file):
+ * lisp/comint.el (comint-get-source):
+ * lisp/emulation/viper-cmd.el (viper-quote-region, viper-kill-buffer)
+ (viper-query-replace, viper-read-string-with-history):
+ * lisp/eshell/esh-mode.el (eshell-find-tag):
+ * lisp/gnus/gnus-sum.el (gnus-articles-to-read)
+ (gnus-summary-search-article-forward)
+ (gnus-summary-search-article-backward):
+ * lisp/international/mule-cmds.el (set-input-method, toggle-input-method)
+ (describe-input-method, set-language-environment)
+ (describe-language-environment):
+ * lisp/mh-e/mh-gnus.el (mh-mml-minibuffer-read-disposition):
+ * lisp/mh-e/mh-letter.el (mh-insert-letter):
+ * lisp/mh-e/mh-mime.el (mh-display-with-external-viewer)
+ (mh-mime-save-parts, mh-mh-forward-message)
+ (mh-mml-query-cryptographic-method, mh-minibuffer-read-type):
+ * lisp/mh-e/mh-seq.el (mh-read-seq, mh-read-range):
+ * lisp/mh-e/mh-utils.el (mh-prompt-for-folder):
+ * lisp/progmodes/etags.el (find-tag-tag):
+ (find-tag-noselect, find-tag, find-tag-other-window)
+ (find-tag-other-frame, find-tag-regexp):
+ * lisp/progmodes/idlwave.el (idlwave-find-module):
+ * lisp/progmodes/inf-lisp.el (lisp-load-file, lisp-compile-file):
+ * lisp/progmodes/tcl.el (tcl-load-file, tcl-restart-with-file):
+ * lisp/progmodes/xref.el (xref--read-identifier):
+ (xref-find-definitions, xref-find-definitions-other-window)
+ (xref-find-definitions-other-frame, xref-find-references):
+ * lisp/ses.el (ses-read-printer):
+ (ses-read-cell-printer, ses-read-column-printer)
+ (ses-read-default-printer, ses-define-local-printer):
+ * lisp/subr.el (read-number):
+ * lisp/term.el (term-get-source):
+ * src/minibuf.c (read-buffer): Remove prompt suffix and
+ use 'format-prompt'.
+ * lisp/minibuffer.el (format-prompt): Ignore DEFAULT empty strings
+ (bug#47286).
+
+2021-03-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with filling with a computed fill prefix
+
+ * lisp/textmodes/fill.el (fill-region-as-paragraph): Fix problem
+ when filling text with a computed fill prefix (bug#47338).
+
+2021-03-24 Stefan Kangas <stefan@marxist.se>
+
+ Convert many more links to use HTTPS
+
+2021-03-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move string-trim functions to subr.el
+
+ * doc/lispref/strings.texi (Creating Strings): Document them.
+
+ * lisp/faces.el: Don't require subr-x, because that leads to build
+ errors.
+
+ * lisp/subr.el (string-trim, string-trim-right)
+ (string-trim-left): Move here from subr-x.el.
+
+ * lisp/emacs-lisp/shortdoc.el (string): Adjust.
+
+2021-03-24 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in iimage.el
+
+ * lisp/iimage.el: Use lexical-binding. Remove redundant :group args.
+
+2021-03-24 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/talk.el: Use lexical-binding.
+
+2021-03-24 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in two trivial org-mode files
+
+ This change has already been made on org-mode's master branch.
+
+ * lisp/org/org-install.el:
+ * lisp/org/org-version.el: Use lexical-binding.
+
+2021-03-24 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/help-at-pt.el: Use lexical-binding.
+
+ * lisp/progmodes/simula.el (hilit-set-mode-patterns): Use regexp-opt.
+
+ * lisp/progmodes/modula2.el: Use lexical-binding.
+
+2021-03-24 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in view.el
+
+ * lisp/view.el: Use lexical-binding. Remove redundant :group args.
+
+2021-03-24 Stefan Kangas <stefan@marxist.se>
+
+ Delete some commented out defgroups
+
+ * lisp/eshell/esh-opt.el:
+ * lisp/international/ccl.el:
+ * lisp/pcmpl-linux.el:
+ * lisp/shell.el:
+ * lisp/url/url-news.el: Delete some commented out defgroups.
+
+2021-03-24 Stefan Kangas <stefan@marxist.se>
+
+ Doc fixes in view.el
+
+ * lisp/view.el:
+ (view-try-extend-at-buffer-end, kill-buffer-if-not-modified)
+ (view-buffer, view-buffer-other-window, view-buffer-other-frame)
+ (view-page-size-default, view-set-half-page-size-default)
+ (view-really-at-end, view-end-message)
+ (view-search-no-match-lines): Doc fixes.
+
+2021-03-24 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/master.el: Use lexical-binding.
+
+2021-03-24 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in ruler-mode.el
+
+ * lisp/ruler-mode.el: Use lexical-binding. Remove redundant
+ :group args.
+
+2021-03-24 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/ebnf-*.el: Use lexical-binding
+
+ * lisp/progmodes/ebnf-abn.el:
+ * lisp/progmodes/ebnf-bnf.el:
+ * lisp/progmodes/ebnf-dtd.el:
+ * lisp/progmodes/ebnf-ebx.el:
+ * lisp/progmodes/ebnf-iso.el:
+ * lisp/progmodes/ebnf-otz.el:
+ * lisp/progmodes/ebnf-yac.el: Enable lexical-binding.
+ * lisp/progmodes/ebnf2ps.el (ebnf-apply-style1)
+ (ebnf-insert-ebnf-prologue): Use lexical-binding.
+
+2021-03-23 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/mh-e: Enable lexical-binding in all the files
+
+ * lisp/mh-e/mh-alias.el: Use lexical-binding.
+ (mh-alias-insert-file): Completion tables can be mere lists of strings.
+
+ * lisp/mh-e/mh-mime.el: Use lexical-binding.
+ (mh-mm-inline-message): Remove always-nil var `visible-headers`.
+
+ * lisp/mh-e/mh-search.el: Use lexical-binding.
+ (mh-search-folder): Remove unused var `pick-folder`.
+
+ * lisp/mh-e/mh-show.el: Use lexical-binding.
+ (mh-display-msg): Remove always-nil var `visible-headers`.
+
+ * lisp/mh-e/mh-utils.el: Use lexical-binding.
+ (completion-root-regexp): Always declare var.
+
+ * lisp/mh-e/mh-buffers.el: Use lexical-binding.
+ * lisp/mh-e/mh-comp.el: Use lexical-binding.
+ * lisp/mh-e/mh-folder.el: Use lexical-binding.
+ * lisp/mh-e/mh-funcs.el: Use lexical-binding.
+ * lisp/mh-e/mh-gnus.el: Use lexical-binding.
+ * lisp/mh-e/mh-identity.el: Use lexical-binding.
+ * lisp/mh-e/mh-inc.el: Use lexical-binding.
+ * lisp/mh-e/mh-junk.el: Use lexical-binding.
+ * lisp/mh-e/mh-letter.el: Use lexical-binding.
+ * lisp/mh-e/mh-limit.el: Use lexical-binding.
+ * lisp/mh-e/mh-print.el: Use lexical-binding.
+ * lisp/mh-e/mh-scan.el: Use lexical-binding.
+ * lisp/mh-e/mh-seq.el: Use lexical-binding.
+ * lisp/mh-e/mh-speed.el: Use lexical-binding.
+ * lisp/mh-e/mh-thread.el: Use lexical-binding.
+ * lisp/mh-e/mh-tool-bar.el: Use lexical-binding.
+ * lisp/mh-e/mh-xface.el: Use lexical-binding.
+
+2021-03-23 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/wdired.el: Fix typo in last change.
+
+ Reported by Michael Heerdegen <michael_heerdegen@web.de>.
+
+ (wdired-change-to-wdired-mode, wdired-change-to-dired-mode):
+ The `(local FOO)` form takes an expression, so the var needs to be quoted.
+
+2021-03-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention `C-o' in the `RET' doc string
+
+ * lisp/simple.el (newline-and-indent): Mention `C-o' in the doc
+ string.
+
+2021-03-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous face.el change
+
+ * lisp/faces.el (require): Fix compilation warning from previous
+ face.el change.
+
+2021-03-22 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-new-tab-group): Set default to t.
+
+ (tab-bar-tabs, tab-bar-select-tab, tab-bar-new-tab-to):
+ Use tab-bar--current-tab-make instead of tab-bar--current-tab.
+ (tab-bar--tab): Add arg 'frame' to tab-bar--current-tab-find.
+ (tab-bar--current-tab, tab-bar--current-tab-make): Move most of body
+ from the former to the latter, thus reverting tab-bar--current-tab
+ to its previous behavior.
+ https://lists.gnu.org/archive/html/emacs-devel/2021-03/msg00959.html
+
+2021-03-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use read-color in read-face-attribute for color attributes
+
+ * lisp/faces.el (read-face-attribute): Use read-color when
+ prompting for a color (bug#47316).
+
+2021-03-22 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/files-x.el (connection-local-criteria-for-default-directory):
+
+ Add optional argument APPLICATION.
+
+2021-03-22 Stefan Kangas <stefan@marxist.se>
+
+ Remove unnecessary requires of rx
+
+ * lisp/cedet/semantic/wisent/python.el (rx):
+ * test/src/process-tests.el (rx): Remove unnecessary requires.
+
+2021-03-22 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in notifications.el
+
+ * lisp/notifications.el: Use lexical-binding.
+ (notifications-notify): Prefer 'push' to 'add-to-list'.
+
+2021-03-21 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-lookup-eln): Add autoload cookie.
+
+ * lisp/emacs-lisp/comp.el (comp-lookup-eln): Add new function.
+
+2021-03-21 Andrea Corallo <akrl@sdf.org>
+
+ Prevent unnecessary multiple .el hashing in 'maybe_swap_for_eln'
+
+ * src/comp.c (Fcomp_el_to_eln_rel_filename): New function.
+ (Fcomp_el_to_eln_filename): Make use of.
+ (syms_of_comp): Register 'Scomp_el_to_eln_rel_filename'.
+ * src/lread.c (maybe_swap_for_eln): Make use of
+ 'Fcomp_el_to_eln_rel_filename' to hash prevent unnecessary
+ multiple hashing.
+
+2021-03-21 Alan Mackenzie <acm@muc.de>
+
+ Prevent open minibuffers getting lost when their frame gets deleted
+
+ This happened with minibuffer-follows-selected-frame set to t.
+
+ * doc/emacs/mini.texi (Basic Minibuffer): State where a command's action takes
+ place when a minibuffer's frame has been deleted.
+
+ * lisp/window.el (window--before-delete-windows, record-window-buffer): Take
+ into account that minibuffers are now recorded on w->prev_buffers field.
+
+ * src/fns.c (merge_c): New version of `merge' taking a C function, rather than
+ a Lisp function as the comparison function.
+
+ * src/frame.c (do_switch_frame): Pass arguments sf and for_deletion to
+ move_minibuffers_onnto_frame.
+
+ * src/lisp.h (top level): Declare merge_c and
+ move_minibuffers_onto_selected_frame.
+
+ * src/minibuf.c (MB_frame): New Lisp_Object recording the minibuffer's frame.
+ (choose_minibuf_frame): Remove all code except that which sets minibuf_window
+ to the current frame's minibuffer.
+ (minibuffer_ent_greater): New comparison function, passed to merge_c.
+ (zip_minibuffer_stacks): New function.
+ (move_minibuffers_onto_frame): Renamed from `move_minibuffer_onto_frame' given
+ two arguments, the old frame and for_deletion, and simplified. Minibuffers
+ are now stacked in the mini-window's ->prev_buffers field.
+ (read_minibuf): Several detailed amendments.
+ (exp_MB_frame): New Lisp_Object, the expired minibuffer's frame.
+ (read_minibuf_unwind): Search for the expired minibuffer's frame, rather than
+ taking it from (unreliable) variables. Switch temporarily to this frame for
+ tidying up operations.
+ (minibuffer_unwind): New function which pops a stacked minibuffer.
+ (syms_of_minibuf): Call staticpro for the two new Lisp variables.
+
+ * src/window.c (Fset_window_configuration): Don't record minibuffers with
+ record-window-buffer.
+
+ * src/xdisp.c (gui_consider_frame_title): Remove redundant Fselect_window,
+ which caused an unwanted frame switch. Amend the arguments to
+ format_mode_line_unwind_data to match.
+
+2021-03-21 Andrea Corallo <akrl@sdf.org>
+
+ Add a tmp dir to `comp-eln-load-path' when running the testsuite.
+
+ * lisp/startup.el (normal-top-level): Tweak `comp-eln-load-path'
+ adding a temp directory when running the testsuite.
+
+2021-03-21 Glenn Morris <rgm@gnu.org>
+
+ * lisp/thumbs.el (thumbs-conversion-program): Simplify.
+
+ /usr/bin is (normally) always in PATH, and this need not be absolute,
+ so the executable-find is unnecessary.
+
+2021-03-21 Stefan Kangas <stefan@marxist.se>
+
+ Actually use lexical-binding in wid-browse.el
+
+ * lisp/wid-browse.el: Use lexical-binding. I apparently forgot to
+ commit the lexical-binding cookie in my previous attempt.
+
+2021-03-21 Andrea Corallo <akrl@sdf.org>
+
+ Revert "* lisp/emacs-lisp/comp.el (comp-clean-up-stale-eln): Clean-up all..."
+
+ This reverts commit be22cda7be9e77e67f224f6f07cca9dd44aaa078.
+
+ Older binaries might still need those .eln if they where preloaded.
+
+2021-03-21 Theodor Thornhill <theo@thornhill.no>
+
+ Use pop-to-buffer-same-window for shell
+
+ * lisp/progmodes/project.el (project-shell): Behave the same way as
+ 'M-x project-eshell'.
+ * lisp/shell.el (shell): Behave the same way as 'M-x eshell'.
+ * etc/NEWS: Add news entry describing the change.
+ * lisp/tutorial.el: Use lexical-binding.
+
+2021-03-21 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-clean-up-stale-eln): Clean-up all .eln dirs.
+
+2021-03-21 Zhiwei Chen <chenzhiwei03@kuaishou.com> (tiny change)
+
+ Allow hide-ifdef-guts to work in buffers not visiting files
+
+ * lisp/progmodes/hideif.el (hide-ifdef-guts): Allow working in
+ buffers not visiting files (bug#47279).
+
+2021-03-21 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/tutorial.el: Use lexical-binding.
+
+2021-03-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet/semantic/ia.el (semantic-ia-complete-symbol): Simplify
+
+ Cut the `semantic-ia-get-completions-deprecated` middle man.
+
+2021-03-20 Stefan Kangas <stefan@marxist.se>
+
+ Remove support for Syndic8.com, defunct since 2013
+
+ * lisp/gnus/nnrss.el (nnrss-discover-feed)
+ (nnrss-find-rss-via-syndic8): Remove support for Syndic8.com, as
+ the site was shut down in 2013.
+
+2021-03-20 Toby Cubitt <toby@dr-qubit.org>
+
+ Fix cl-progv binding order
+
+ * lisp/emacs-lisp/cl-macs.el (cl-progv): Bind variables in the
+ correct order (bug#47272).
+
+2021-03-20 Gregory Heytings <gregory@heytings.org>
+
+ * etc/NEWS: Small corrections for the new command 'font-lock-update'
+
+2021-03-20 Stefan Kangas <stefan@marxist.se>
+
+ Remove Gnus specific .dir-locals.el
+
+ * lisp/gnus/.dir-locals.el: Delete file. The only variable it set was
+ 'show-trailing-whitespace', but this should be up to the individual
+ developer. (Bug#47278)
+
+2021-03-20 Stefan Kangas <stefan@marxist.se>
+
+ Prefer https and fix broken links in ERC
+
+ * lisp/erc/erc-button.el (erc-button-rfc-url)
+ (erc-button-search-url): Prefer https.
+ * lisp/erc/erc-capab.el:
+ * lisp/erc/erc.el (erc-cmd-MODE): Fix broken links.
+
+2021-03-20 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/thumbs.el (thumbs-show-from-dir): Improve prompt.
+
+2021-03-20 Eli Zaretskii <eliz@gnu.org>
+
+ Fix args-out-of-range error in format.el
+
+ * lisp/format.el (format-deannotate-region): Ignore todo items
+ with FROM > TO. (Bug#47277)
+
+2021-03-20 Paul Eggert <eggert@cs.ucla.edu>
+
+ Don’t convert pointer to bool
+
+ Without this patch, Oracle Studio 12.6 complains about converting
+ pointer to bool.
+ * src/editfns.c (styled_format): Use !!.
+
+2021-03-20 Stefan Kangas <stefan@marxist.se>
+
+ Assume something more recent than X11R6
+
+ * lisp/bindings.el:
+ * lisp/menu-bar.el:
+ * lisp/printing.el:
+ * lisp/thumbs.el (thumbs-conversion-program): Assume we have something
+ more recent than X11R6.
+
+2021-03-20 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in thumbs.el
+
+ * lisp/thumbs.el: Use lexical-binding. Remove redundant :group args.
+ * test/lisp/thumbs-tests.el: New file.
+
+2021-03-20 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/novice.el: Use lexical-binding.
+
+2021-03-20 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/wdired.el: Use lexical-binding
+
+ Remove redundant `:group` args.
+
+ (wdired-change-to-wdired-mode): Use `add-function` to modify
+ `revert-buffer-function`.
+ (wdired-change-to-dired-mode): Adjust accordingly.
+ (wdired-do-renames): Make sure to bind `dired-backup-overwrite` dynamically.
+
+2021-03-20 Stefan Kangas <stefan@marxist.se>
+
+ Don't tag mouse command as mode exclusive
+
+ * lisp/finder.el (finder-mouse-select): Don't tag for finder-mode.
+
+2021-03-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/bytecomp.el: Remember location of unresolved calls
+
+ I've gotten tired of seeing the "function foo not known to be defined"
+ warning without any line number information. So this patch adds as
+ line number the position of the first use of that function in the file
+ (well, approximately, as usual).
+
+ (byte-compile-unresolved-functions): Add POSITIONs in the alist.
+ (byte-compile-function-warn): Store the current position in
+ `byte-compile-unresolved-functions`.
+ (byte-compile-arglist-warn): Adjust accordingly.
+ (byte-compile-print-syms): Delete unused function.
+ (byte-compile-warn-about-unresolved-functions): Use the stored position
+ to give more precise warnings.
+
+2021-03-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/pcase.el (pcase-compile-patterns): New function (bug#47261)
+
+ Extracted from `pcase--expand`.
+ (pcase--expand): Use it.
+
+2021-03-19 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into native-comp
+
+2021-03-19 Eli Zaretskii <eliz@gnu.org>
+
+ Improve the docs of a recent change in mb-depth.el
+
+ * lisp/mb-depth.el (minibuffer-depth-indicator-function): Improve
+ the wording of the doc string and of the label used for the
+ default value. (Bug#47252)
+
+2021-03-19 Andrea Corallo <akrl@sdf.org>
+
+ Do not load native code when `load' is explicitly called on a .elc file
+
+ * src/lread.c (Fload): Do not load native code when `load' is
+ explicitly called on a .elc file.
+ (Flocate_file_internal): Update 'openp' call sites.
+ (maybe_swap_for_eln): Add new 'no_native' parameter.
+ (openp): Likewise + update 'maybe_swap_for_eln' and 'openp' call
+ sites.
+ * src/lisp.h: Update 'openp' signature.
+ * src/w32proc.c (sys_spawnve): Update 'openp' call sites.
+ * src/w32.c (check_windows_init_file): Likewise.
+ * src/sound.c (Fplay_sound_internal): Likewise.
+ * src/process.c (Fmake_process): Likewise.
+ * src/image.c (image_create_bitmap_from_file)
+ (image_find_image_fd): Likewise.
+ * src/emacs.c (set_invocation_vars): Likewise.
+ * src/charset.c (load_charset_map_from_file): Likewise.
+ * src/callproc.c (call_process): Likewise.
+
+2021-03-19 Mauro Aranda <maurooaranda@gmail.com>
+
+ Fix :type of recently introduced defcustom
+
+ * lisp/mb-depth.el (minibuffer-depth-indicator-function): The option
+ can be nil, so add nil as a choice. (Bug#47252)
+
+2021-03-19 Gabriel do Nascimento Ribeiro <gabriel.nascimento@nubank.com.br>
+
+ Make minibuffer-depth-indicator-function a defcustom
+
+ * lisp/mb-depth.el (minibuffer-depth-indicator-function): Make
+ into a user option (bug#47252).
+
+2021-03-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Warn the user if we can't find pkg-config
+
+ * configure.ac (WITH_IFAVAILABLE): Warn the user if we can't find
+ a usable pkg-config (bug#47159).
+
+2021-03-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a note to NEWS as to how to restore the facemenu
+
+2021-03-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Fix copyright lines mistakenly treated as outline headers
+
+ * lisp/emacs-lisp/generator.el:
+ * test/lisp/cedet/semantic-utest.el:
+ * test/lisp/cedet/semantic/format-tests.el:
+ * test/lisp/cedet/semantic/fw-tests.el:
+ * test/lisp/cedet/semantic/bovine/gcc-tests.el:
+ * test/lisp/cedet/semantic/format-resources/test-fmt.el:
+ * test/manual/cedet/semantic-tests.el:
+ * lisp/obsolete/inversion.el: Use only 2 semi-colons before "Copyright".
+
+2021-03-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ lisp/erc: Use lexical-binding
+
+ Also remove various redundant `:group` arguments.
+
+ * lisp/erc/erc-backend.el (define-erc-response-handler): Move `declare`
+ after the docstring.
+
+ * lisp/erc/erc-capab.el: Use lexical-binding.
+ (erc-capab-identify-activate): Simplify with `member`.
+
+ * lisp/erc/erc-dcc.el (erc-dcc): Move before erc-dcc-mode definition,
+ which refers to it.
+ (erc-dcc-chat-accept): Remove unused vars `nick` and `buffer`.
+
+ * lisp/erc/erc-imenu.el: Use lexical-binding.
+ (erc-create-imenu-index): Remove unused var `prev-pos`.
+
+ * lisp/erc/erc-match.el: Use lexical-binding.
+ (erc-match-message): Remove unused var `old-pt`.
+ (erc-match-message): Strength-reduce `eval` to `symbol-value`.
+
+ * lisp/erc/erc-page.el: Use lexical-binding.
+ (erc-page): Move Custom group before `erg-page-mode` which refers to it.
+
+ * lisp/erc/erc-replace.el: Use lexical-binding.
+ (erc-replace-insert): Use `functionp`.
+
+ * lisp/erc/erc-status-sidebar.el: Use lexical-binding.
+ (erc-status-sidebar-open): Remove unused var `sidebar-window`.
+
+ * lisp/erc/erc.el: Fix header to use the customary 3 semi-colons.
+ (erc-fill-column): Declare variable.
+
+ * lisp/erc/erc-autoaway.el: Use lexical-binding.
+ * lisp/erc/erc-ezbounce.el: Use lexical-binding.
+ * lisp/erc/erc-fill.el: Use lexical-binding.
+ * lisp/erc/erc-goodies.el: Use lexical-binding.
+ * lisp/erc/erc-ibuffer.el: Use lexical-binding.
+ * lisp/erc/erc-identd.el: Use lexical-binding.
+ * lisp/erc/erc-join.el: Use lexical-binding.
+ * lisp/erc/erc-lang.el: Use lexical-binding.
+ * lisp/erc/erc-log.el: Use lexical-binding.
+ * lisp/erc/erc-menu.el: Use lexical-binding.
+ * lisp/erc/erc-netsplit.el: Use lexical-binding.
+ * lisp/erc/erc-networks.el: Use lexical-binding.
+ * lisp/erc/erc-pcomplete.el: Use lexical-binding.
+ * lisp/erc/erc-ring.el: Use lexical-binding.
+ * lisp/erc/erc-speedbar.el: Use lexical-binding.
+ * lisp/erc/erc-spelling.el: Use lexical-binding.
+ * lisp/erc/erc-truncate.el: Use lexical-binding.
+ * lisp/erc/erc-xdcc.el: Use lexical-binding.
+
+2021-03-19 Stefan Kangas <stefan@marxist.se>
+
+ Do interactive mode tagging for finder.el
+
+2021-03-19 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in finder.el
+
+ * lisp/finder.el: Use lexical-binding.
+ (finder-mode-map, finder-compile-keywords): Remove unused lexical
+ variables.
+
+2021-03-19 Stefan Kangas <stefan@marxist.se>
+
+ Fix a warning due to not preloading facemenu.el
+
+ * test/src/undo-tests.el (facemenu): Require.
+
+2021-03-18 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/faces.el (help-key-binding): Tweak background.
+
+2021-03-18 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix frame-inner-height in non-GUI builds
+
+ Include tab bar in frame's inner height in non-GUI builds that don't
+ define tab-bar-height. This is consistent with the inclusion of the
+ menu bar in the calculated height. It is also consistent with TTY
+ frames of GUI builds, for which tab-bar-height is always zero
+ anyway (bug#47234). Fix suggested by Eli Zaretskii <eliz@gnu.org>.
+
+ * lisp/frame.el (frame-inner-height): Don't assume tab-bar-height is
+ defined in builds --without-x.
+
+2021-03-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-macs.el (cl--self-tco): Optimize the "return nil" case
+
+2021-03-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * test/lisp/progmodes/cperl-mode-tests.el: Silence warnings
+
+ (cperl-test-bug-47112): Actually obey the major-mode for the test.
+
+2021-03-18 Juri Linkov <juri@linkov.net>
+
+ * lisp/newcomment.el: Allow 'comment-continue' with whitespace (bug#47167)
+
+ * lisp/newcomment.el (comment-region-default-1): Still use 'comment-continue'
+ as a string with whitespace even when 'comment-padright' returns nil.
+
+2021-03-18 Juri Linkov <juri@linkov.net>
+
+ * lisp/simple.el (next-error-quit-window): New function (bug#44611).
+
+ (next-error-found-function): Add it as a choice.
+
+2021-03-18 Glenn Morris <rgm@gnu.org>
+
+ * admin/make-tarball.txt: Be kind to people merging branches.
+
+2021-03-18 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ d5b160d7cc (tag: emacs-27.2-rc1, origin/emacs-27) Prepare the Emacs 2...
+ 216bd67a4f ; * admin/make-tarball.txt: Advise to remove stale subdire...
+
+ # Conflicts:
+ # ChangeLog.3
+ # README
+ # configure.ac
+ # etc/AUTHORS
+ # etc/NEWS
+ # lisp/ldefs-boot.el
+ # msdos/sed2v2.inp
+ # nt/README.W32
+
+2021-03-18 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ a7f95d5244 Remove duplicate @table item from ELisp manual
+ be1b3512f7 Fix reference to 'diff-font-lock-syntax' in diff-mode docu...
+
+2021-03-18 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ f60eb988f6 Fix typos and omissions for (elisp)Button Buffer Commands
+ 876b95bf90 Teach Rmail about NBSP in "Re:"
+
+ # Conflicts:
+ # lisp/mail/rmail.el
+
+2021-03-18 Eli Zaretskii <eliz@gnu.org>
+
+ Prepare the Emacs 27.2 release.
+
+ * etc/HISTORY: Update for Emacs 27.2.
+
+ * README:
+ * configure.ac:
+ * nt/README.W32:
+ * msdos/sed2v2.inp: Set version to 27.2
+
+2021-03-18 Mattias Engdegård <mattiase@acm.org>
+
+ Optimise tail calls in `and` and `or` forms in `cl-labels` functions
+
+ * lisp/emacs-lisp/cl-macs.el (cl--self-tco): Handle `and` and `or`.
+ * test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs--labels):
+ Add test cases.
+
+2021-03-18 Michael Albinus <michael.albinus@gmx.de>
+
+ Extend handled events in 'while-no-input-ignore-events' (Bug#47205)
+
+ * etc/NEWS: Mention changes to 'while-no-input-ignore-events'.
+
+ * src/keyboard.c (kbd_buffer_store_buffered_event): Handle also
+ Qfile_notify and Qdbus_event as ignore_event. (Bug#47205)
+
+2021-03-18 Stefan Kangas <stefan@marxist.se>
+
+ Add comint-password-prompt-regexp test for "zip -e ..."
+
+ * test/lisp/comint-tests.el (comint-testsuite-password-strings):
+ Add test for "zip -e ...". (Bug#47209)
+
+2021-03-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Compute chart-face-list dynamically
+
+ * lisp/emacs-lisp/chart.el (chart-face-list): Allow a function as
+ the value (bug#47133) so that we can compute the faces dynamically
+ on different displays.
+ (chart--face-list): New function.
+ (chart-draw-data): Use it.
+
+2021-03-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document that `buffer-string' retains text properties
+
+ * doc/lispref/text.texi (Buffer Contents): Mention text properties
+ in the `buffer-string' documentation.
+ * src/editfns.c (Fbuffer_string): Mention text properties in the
+ doc string (bug#47220).
+
+ (cherry picked from commit 60af754170f22f5d25510af069ed0ebfec95f992)
+
+2021-03-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix breaking undo-test
+
+2021-03-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make "not found" message in dictionary less misleading
+
+ * lisp/net/dictionary.el (dictionary-do-search): Don't say there
+ are more words when there aren't (bug#47056).
+
+2021-03-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make memory-report work with buffer-local unbound vars
+
+ * lisp/emacs-lisp/memory-report.el (memory-report--buffer-data):
+ Protect against buffer-local unbound variables (bug#47057).
+
+2021-03-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix sorting in speedbar sub-groups
+
+ * lisp/speedbar.el (speedbar-prefix-group-tag-hierarchy): Sort
+ entries in sub-groups (bug#47073).
+
+2021-03-18 Gabriel do Nascimento Ribeiro <gabriel.nascimento@nubank.com.br>
+
+ lisp/cedet/pulse.el: Use color.el
+
+ * lisp/cedet/pulse.el: (pulse-int-to-hex): Remove function.
+ (pulse-color-values-to-hex): Remove function.
+ (pulse-lighten-highlight): Remove function.
+ (pulse-momentary-iteration): Add variable.
+ (pulse-momentary-highlight-overlay): Use color-gradient from color.el.
+ (pulse-tick): Receive colors and update overlay background (bug#47083).
+
+2021-03-18 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Don't interpret y_ as start of y// function.
+
+ * lisp/progmodes/cperl-mode.el (cperl-find-pods-heres): Avoid
+ treating underscores as word-terminators.
+
+ * test/lisp/progmodes/cperl-mode-tests.el
+ (cperl-test-bug-47112): Test case for that bug (bug#47112).
+
+2021-03-18 Gabriel do Nascimento Ribeiro <gabriel.nascimento@nubank.com.br>
+
+ Fix uniquify-trailing-separator-p + uniquify-strip-common-suffix
+
+ (uniquify-item): New slot 'original-dirname'.
+ (uniquify-rationalize-file-buffer-names): Use new slot.
+ (uniquify-rationalize): Use new slot.
+ (uniquify-get-proposed-name): New optional argument 'original-dirname'
+ to properly add a trailing separator when the corresponding user option
+ is set and the dirname is an existing directory (bug#47132).
+
+2021-03-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem of trashing files to an inconsistent trash directory
+
+ * lisp/files.el (move-file-to-trash): Allow moving files to trash
+ even if there's a file in trash with the same name (but no entry
+ in info) (bug#47135).
+
+2021-03-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Autoload 'mouse-wheel-mode'
+
+ * lisp/mwheel.el (mouse-wheel-mode): Autoload, since the mode can
+ be used (but isn't preloaded) when there isn't any window system
+ (bug#47162).
+
+2021-03-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Recognise "Verify password" as a password prompt
+
+ * lisp/comint.el (comint-password-prompt-regexp): Also react to
+ "Verify password" (output by "zip -e") (bug#47209).
+
+2021-03-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document that `buffer-string' retains text properties
+
+ * doc/lispref/text.texi (Buffer Contents): Mention text properties
+ in the `buffer-string' documentation.
+ * src/editfns.c (Fbuffer_string): Mention text properties in the
+ doc string (bug#47220).
+
+2021-03-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't pre-load facemenu
+
+ * lisp/facemenu.el (facemenu-add-face-function): Move to avoid a
+ compilation warning.
+ (facemenu-color-alist): Made obsolete.
+
+ * lisp/faces.el (read-color): Don't use it.
+
+ * lisp/loadup.el ("emacs-lisp/syntax"): Don't load facemenu.
+
+ * lisp/wid-edit.el (color): Don't use facemenu-color-alist.
+ (widget-color--choose-action): Require facemenu.
+ (widget-color-action): Ditto.
+
+ * lisp/progmodes/cperl-mode.el (facemenu): Require.
+
+ * lisp/textmodes/sgml-mode.el (facemenu): Require.
+
+2021-03-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Unbind `M-o' and add new `C-x x f' binding
+
+ * doc/lispref/modes.texi (Other Font Lock Variables):
+ `font-lock-fontify-block' is no longer bound.
+ * lisp/bindings.el (ctl-x-x-map): Bind `font-lock-update'.
+
+ * lisp/font-lock.el (font-lock-update): New command written by
+ Gregory Heytings <gregory@heytings.org>.
+
+ * lisp/loadup.el: Remove transitional experimental code.
+
+2021-03-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/textmodes: Use lexical-binding
+
+ * lisp/textmodes/enriched.el: Use lexical-binding.
+ (enriched-mode): Use `delete-dups` to avoid `add-to-list` on
+ a local variable.
+
+ * lisp/textmodes/makeinfo.el: Use lexical-binding.
+ (makeinfo-region): Remove unused var `filename-or-header`.
+
+ * lisp/textmodes/refbib.el: Use lexical-binding.
+ (r2b-put-field): Remove unused var `multi-line`.
+ (r2b-barf-output): Remove unused var `match`.
+
+ * lisp/textmodes/refer.el: Use lexical-binding.
+ (refer-find-entry-internal): Remove unused vars `old-buffer` and `found`.
+
+ * lisp/textmodes/reftex-auc.el: Use lexical-binding.
+ (LaTeX-add-bibitems): Declare function.
+ (reftex-plug-into-AUCTeX): Use `add-function` and `advice-add` so we
+ can properly unplug.
+
+ * lisp/textmodes/reftex-cite.el: Use lexical-binding.
+ (reftex-create-bibtex-file): Remove unused var `file`.
+ (reftex--found-list): Declare var.
+ (reftex-offer-bib-menu): Rename local var to `reftex--found-list`.
+
+ * lisp/textmodes/reftex-dcr.el: Use lexical-binding.
+ (reftex-use-itimer-in-xemacs): Delete XEmacs-only var.
+ (reftex-toggle-auto-view-crossref): Delete XEmacs-only code.
+ (reftex-start-itimer-once): Delete XEmacs-only function.
+
+ * lisp/textmodes/reftex-global.el: Use lexical-binding.
+ (reftex-isearch-push-state-function): Use a closure instead of `(lambda).
+
+ * lisp/textmodes/reftex-index.el: Use lexical-binding.
+ (mark-active, transient-mark-mode): Delete var declarations.
+ (reftex-index-mode-map): Remove XEmacs-only code.
+ Use `mapc` so we can use closures instead of hand-built lambdas.
+ (reftex-index-next, reftex-index-previous): Tweak interactive spec to
+ remove unused prefix arg and mark it as a motion command.
+ (reftex-index-phrases-font-lock-keywords)
+ (reftex-index-phrases-font-lock-keywords): Move initialization into
+ declaration.
+ (reftex-index-initialize-phrases-buffer, reftex-index-phrases-mode)
+ reftex-index-phrases-apply-to-region: Remove XEmacs-only code.
+ (TeX-master): Remove redundant declaration.
+ (reftex--chars-first): Rename dynvar from `chars-first`. Adjust all uses.
+
+ * lisp/textmodes/reftex-parse.el: Use lexical-binding.
+
+ * lisp/textmodes/reftex-ref.el: Use lexical-binding.
+ (reftex-label): Remove always-nil var `text`.
+ (reftex-refstyle): Declare before first use.
+ (<toplevel>): Use closures rather than `eval` when building commands from
+ `reftex-ref-style-alist`.
+
+ * lisp/textmodes/reftex-sel.el: Use lexical-binding.
+ (reftex-select-label-mode-map, reftex-select-bib-mode-map):
+ Use `mapc` so we can use closures instead of hand-built lambdas.
+ (reftex-select-label-mode, reftex-select-bib-mode): Remove XEmacs-only code.
+ (reftex-select-data, reftex-select-prompt, reftex-refstyle):
+ Move declaration before first use.
+ (reftex--found-list, reftex--cb-flag, reftex--last-data)
+ (reftex--call-back, reftex--help-string): Move declaration before use,
+ and rename by adding `reftext--` prefix. Adjust all uses in this file.
+ For `reftex--found-list` adjust corresponding uses in `reftex-cite.el`.
+ (reftex-select-item): Explicitly let-bind them.
+ Remove XEmacs-only code.
+
+ * lisp/textmodes/reftex-toc.el: Use lexical-binding.
+ (reftex-toc-mode-map, reftex-toc-mode, reftex-toc-restore-region)
+ (reftex-toc-next, reftex-toc-previous, reftex-toc-next-heading)
+ (reftex-toc-previous-heading, reftex-toggle-auto-toc-recenter
+ (reftex-make-separate-toc-frame): Remove XEmacs-only code.
+
+ * lisp/textmodes/reftex-vars.el: Use lexical-binding.
+
+ * lisp/textmodes/reftex.el: Use lexical-binding.
+ (reftex-mode-map, reftex-mode, reftex-fontify-select-label-buffer)
+ (reftex-verified-face): Remove XEmacs-only code.
+ (reftex-region-active-p, reftex-overlay-put, reftex-move-overlay)
+ (reftex-make-overlay, reftex-get-buffer-visiting, reftex-delete-overlay):
+ Redefine as obsolete aliases. Replace all callers.
+ (current-message): Remove XEmacs-only definition.
+
+ * lisp/textmodes/remember.el: Use lexical-binding.
+
+ * lisp/textmodes/table.el (<toplevel>): Use closures rather than `(lambda)
+ to build commands.
+
+ * lisp/textmodes/texinfmt.el: Use lexical-binding.
+ (texinfo-example-start): Declare var.
+ (texinfo-format-region, texinfo-format-buffer-1): Remove unused var
+ `last-input-buffer`.
+ (texinfo-format-scan): Use `dlet` to bind `whitespace-silent`.
+ (texinfo-optional-braces-discard, texinfo-format-parse-line-args)
+ (texinfo-format-parse-args): Remove unused var `start`.
+ (texinfo-multitable-widths): Remove unused var `start-of-templates`.
+ (texinfo-multitable-item): Strength-reduce `eval` to `symbol-value`.
+ (texinfo-alias): Remove unused vars `start` and `args`.
+ (texinfo-defun-type symbol-property): Change the car to help the type
+ symbol rather than an expression returning it.
+ (texinfo-format-deffn): Remove corresponding `eval`.
+ (texinfo-clear): Remove unused var `value`.
+ (texinfo-format-ifeq): Remove unused var `end`.
+
+ * lisp/textmodes/texinfo.el: Use lexical-binding.
+ (tex-show-print-queue): Declare function.
+
+ * lisp/textmodes/texnfo-upd.el: Use lexical-binding.
+ (texinfo-start-menu-description): Remove unused var `end`.
+ (texinfo-insert-node-lines): Remove unused var `beginning-marker`.
+ (texinfo-multiple-files-update): Remove unused vars `next-node-name`
+ and `previous-node-name`.
+
+ * lisp/textmodes/two-column.el: Use lexical-binding.
+
+2021-03-18 Dmitry Gutov <dgutov@yandex.ru>
+
+ Leave signaling the exact error to cl-generic's internals
+
+ * lisp/progmodes/project.el (project-root): Extract default
+ definition to a new method, predicated on a context
+ (https://lists.gnu.org/archive/html/emacs-devel/2021-03/msg00771.html).
+
+2021-03-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/benchmark.el (benchmark-call): New function
+
+ (benchmark-run, benchmark-run-compiled, benchmark): Use it.
+ (benchmark--adaptive): New internal function.
+
+2021-03-17 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-line.el: Face cleanup.
+
+2021-03-17 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: New faces and face options.
+
+ * lisp/tab-bar.el (tab-bar-tab-group-current)
+ (tab-bar-tab-group-inactive, tab-bar-tab-ungrouped): New deffaces.
+ (tab-bar-tab-face-function): New defcustom.
+ (tab-bar-tab-face-default): New function.
+ (tab-bar-tab-name-format-default): Use it.
+ (tab-bar-tab-group-format-default): Use tab-bar-tab-group-inactive face.
+ (tab-bar-tab-group-face-function): New defcustom.
+ (tab-bar-tab-group-face-default): New function.
+ (tab-bar--format-tab-group): Add new arg 'current-p'.
+ (tab-bar-format-tabs-groups): Prepend current group name before first tab.
+ Override tab-bar-tab-face-function with tab-bar-tab-group-face-function.
+
+2021-03-17 Dmitry Gutov <dgutov@yandex.ru>
+
+ Stop project-root from going into infinite recursion
+
+ * lisp/progmodes/project.el (project--within-roots-fallback):
+ New variable.
+ (project-root, project-roots): Use it (bug#47168).
+
+2021-03-17 Fabrice Bauzac <noon@mykolab.com>
+
+ Remove duplicate @table item from ELisp manual
+
+ * doc/lispref/objects.texi (Special Read Syntax): Remove duplicate
+ item "#@N" from the table of Special Read Syntax. (Bug#47200)
+
+2021-03-16 Juri Linkov <juri@linkov.net>
+
+ New commands xref-next-line-no-show and xref-prev-line-no-show (bug#44611)
+
+ * lisp/progmodes/xref.el (xref-next-line-no-show)
+ (xref-prev-line-no-show): New commands.
+ (xref-next-line, xref-prev-line): Use them.
+
+2021-03-16 Juri Linkov <juri@linkov.net>
+
+ Minor fixes
+
+ * lisp/frame.el (set-frame-property--interactive): Remove '(point)'
+ that makes no sense as the default value. (Bug#9970)
+
+ * lisp/simple.el (next-error-found-function): Move defcustom
+ closer to function 'next-error-found' where it's used.
+
+2021-03-16 Andrea Corallo <akrl@sdf.org>
+
+ Fix `no-byte-compile' native compilation interaction (bug#47169)
+
+ * lisp/emacs-lisp/comp.el (comp-spill-lap-function): Throw
+ no-native-compile when `byte-native-qualities' are null.
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-from-buffer): No need
+ to consider `no-byte-compile'.
+
+2021-03-16 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-select-tab): Support negative arg.
+
+2021-03-16 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: Simplify internal functions.
+
+ * lisp/tab-bar.el (tab-bar-tabs-set): New function.
+ (tab-bar-tabs): Use tab-bar--current-tab-find and tab-bar-tabs-set.
+ (tab-bar--tab): Use tab-bar--current-tab-find.
+ (tab-bar--current-tab): Remove unused line (assq 'current-tab ...)
+ because there is no current-tab when it's called. Remove unused arg 'frame'.
+ (tab-bar--current-tab-find): Simplify.
+ (tab-bar-move-tab-to, tab-bar-move-tab-to-frame)
+ (tab-bar-new-tab-to, tab-bar-close-tab)
+ (tab-bar-close-other-tabs, tab-bar-undo-close-tab)
+ (tab-switcher-delete-from-list): Use tab-bar-tabs-set
+ instead of set-frame-parameter.
+ (tab-bar-close-group-tabs): Simplify using tab-bar--current-tab-find
+ without arg.
+
+2021-03-16 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix problem of image-tests.el on emba
+
+ * test/README: Mention $EMACS_TEST_DIRECTORY.
+
+ * test/lisp/image-tests.el (image-tests--emacs-images-directory):
+ Use `data-directory', for runs w/o of make.
+ (image-type/from-filename): Check for `image-load-path'.
+
+2021-03-16 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix problem in Tramp running two async processes in parallel
+
+ * lisp/net/tramp-integration.el
+ (tramp-compile-disable-ssh-controlmaster-options): New defun. Add
+ it to `compilation-mode-hook'. (Bug#45518)
+
+ * lisp/progmodes/compile.el (compilation-get-file-structure):
+ Revert commit 4ce5646d59, it isn't needed.
+
+2021-03-16 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * etc/themes/modus-themes.el: Bump version for GNU ELPA release
+
+ (News:): New section.
+
+2021-03-16 Andrea Corallo <akrl@sdf.org>
+
+ Have `no-byte-compile' implies also `no-native-compile'.
+
+ * lisp/emacs-lisp/comp.el (no-native-compile): Update doctring.
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-from-buffer): when
+ `no-byte-compile' is set to non-nil it overrides this.
+
+2021-03-16 Daniel Martín <mardani29@yahoo.es>
+
+ Add minibuffer input support to commands that set the frame size
+
+ * lisp/frame.el (set-frame-property--interactive): Internal function to
+ produce the interactive form of `set-frame-width' and
+ `set-frame-height'. Offer the current size as default. (Bug#9970)
+ * src/frame.c (Fset_frame_height): Modify to call
+ `set-frame-property--interactive'.
+ (Fset_frame_width): Modify to call `set-frame-property--interactive'.
+ * doc/lispref/frames.texi (Frame Size): Update the manuals.
+ * etc/NEWS: Advertise the change (bug#9970).
+
+2021-03-15 Eli Zaretskii <eliz@gnu.org>
+
+ * lisp/emacs-lisp/byte-opt.el: Fix native re-compilation (bug#47161).
+
+2021-03-15 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-new-tab-group): New defcustom.
+
+ (tab-bar--current-tab, tab-bar-new-tab-to, tab-bar-duplicate-tab): Use it.
+
+2021-03-15 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-tab-group-format-function): New defcustom.
+
+ (tab-bar-tab-group-default): New function.
+ (tab-bar-tab-group-format-default, tab-bar-format-tabs-groups)
+ (tab-bar-change-tab-group, tab-bar-close-group-tabs): Use it.
+
+2021-03-15 Glenn Morris <rgm@gnu.org>
+
+ * CONTRIBUTE: Refer to gnulib for request-assign.future.
+
+ The vast majority of the exchanges on this topic are "please send me
+ the form; ok I sent you the form", and there's no need to involve a
+ mailing list for that.
+
+2021-03-15 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/bytecomp.el: Fix native re-compilation (bug#47161).
+
+2021-03-15 Eli Zaretskii <eliz@gnu.org>
+
+ Prefer expand-file-name to concat in native-compilation code
+
+ * lisp/emacs-lisp/comp.el (comp-eln-load-path-eff):
+ * src/comp.c (Fcomp_el_to_eln_filename)
+ (eln_load_path_final_clean_up): Prefer expand-file-name to concat.
+ (Bug#43725)
+
+2021-03-15 Protesilaos Stavrou <info@protesilaos.com>
+
+ Make the `kbd` macro work in both Emacs-26 and Emacs-28
+
+ This is so that elpa.gnu.org's Emacs-26 can successfully build the
+ Info version of it for the GNU ELPA package.
+
+2021-03-15 Michael Albinus <michael.albinus@gmx.de>
+
+ Improve command completion in tramp-crypt.el
+
+ * lisp/net/tramp-crypt.el (tramp-crypt-command-completion-p):
+ Rename from `tramp-crypt-enabled-p'. Handle
+ `tramp-crypt-remove-directory' special.
+
+2021-03-15 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/textmodes/refill.el: Use lexical-binding.
+
+2021-03-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet: Convert remaining files to lexical-binding
+
+ Remove a few more redundant `:group` args.
+ Make use of lexical scoping to replace `(lambda...) with proper closures.
+
+ * lisp/cedet/ede/custom.el (ede-project-sort-targets-list):
+ Use `dotimes` and replace `(lambda..) with closures.
+
+ * lisp/cedet/ede/proj-comp.el (proj-comp-insert-variable-once):
+ * lisp/cedet/ede/pmake.el (ede-pmake-insert-variable-once):
+ Remove unused var `addcr`.
+
+ * lisp/cedet/semantic/complete.el: Use lexical-binding.
+ (semantic-displayer-show-request): Remove unused var `typing-count`.
+ Use `equal` instead of `stringp+string=`.
+
+ * lisp/cedet/semantic/db-ebrowse.el: Use lexical-binding.
+ (semanticdb-create-ebrowse-database): Remove unused vars `mma` and `regexp`.
+ (semanticdb-ebrowse-strip-trees): Remove unused var `class` and `filename`.
+ (semanticdb-ebrowse-add-globals-to-table): Remove unused var `fname`.
+
+ * lisp/cedet/semantic/db-find.el: Use lexical-binding.
+ (semanticdb-find-adebug-insert-scanned-tag-cons): Remove always-nil var
+ `tip`.
+
+ * lisp/cedet/semantic/db-global.el: Use lexical-binding.
+ (semanticdb-enable-gnu-global-databases): Access local var
+ `semantic--ih` by sticking its value in the code passed to `eval`
+ rather than by dynamic scoping.
+
+ * lisp/cedet/semantic/db-typecache.el: Use lexical-binding.
+ (semanticdb-db-typecache-dump): Remove unused var `junk`.
+
+ * lisp/cedet/semantic/debug.el: Use lexical-binding.
+
+ * lisp/cedet/semantic/dep.el: Use lexical-binding.
+ (semantic-add-system-include): Avoid `add-to-list` on a local variable.
+ Access local var `value` by sticking its value in the code passed to
+ `eval` rather than by dynamic scoping.
+ (semantic-remove-system-include): Don't use `delete` on a list received
+ from elsewhere.
+ Access local var `value` by sticking its value in the code passed to
+ `eval` rather than by dynamic scoping.
+ (semantic-reset-system-include): Simplify a bit.
+
+ * lisp/cedet/semantic/ede-grammar.el: Use lexical-binding.
+ (project-compile-target): Remove unused vars `csrc` and `cb`.
+ Use `cl-incf`. Remove apparently unneeded `with-no-warnings`.
+
+ * lisp/cedet/semantic/edit.el: Use lexical-binding.
+ (semantic-edits-change-over-tags): Remove unused var `inner-start`.
+ (semantic-edits-incremental-parser-1): Silence warnings about
+ intentionally unused var `last-cond`.
+
+ * lisp/cedet/semantic/fw.el: Use lexical-binding.
+ (recentf-exclude, semantic-init-hook, ede-auto-add-method)
+ (flymake-start-syntax-check-on-find-file, auto-insert): Declare vars.
+
+ * lisp/cedet/semantic/ia-sb.el: Use lexical-binding.
+ (semantic-ia-sb-key-map): Move initialization into declaration.
+ (semantic-ia-sb-more-buttons): Remove unused var `idx`.
+ (semantic-ia-sb-line-path): Simplify `if` -> `or`.
+
+ * lisp/cedet/semantic/idle.el (semantic-idle-breadcrumbs--tag-function):
+ Make it a function returning a closure.
+
+ * lisp/cedet/semantic/senator.el: Use lexical-binding.
+ (senator-search-set-tag-class-filter): Replace `(lambda..) with a closure.
+
+ * lisp/cedet/semantic/sort.el: Use lexical-binding.
+ (semanticdb-search-system-databases): Declare var.
+ (semantic-tag-external-member-children-default): Replace `(lambda..)
+ with a closure.
+
+ * lisp/cedet/semantic/tag-ls.el: Use lexical-binding.
+ (semantic-tag-protection-default, semantic-tag-abstract-p-default):
+ Simplify with `member`.
+
+ * lisp/cedet/semantic/util.el: Use lexical-binding.
+ (semantic-something-to-tag-table): Declare function
+ `semanticdb-abstract-table--eieio-childp` called via `cl-typep`.
+
+ * lisp/cedet/semantic/bovine/scm.el (semantic-default-scheme-setup):
+ Remove duplicate setting of `imenu-create-index-function`.
+
+ * lisp/cedet/semantic/decorate/mode.el (semantic-decoration-build-style-menu):
+ Replace `(lambda..) with a closure.
+
+ * lisp/cedet/srecode/cpp.el (srecode-semantic-apply-tag-to-dict):
+ Remove always-t variable `member`.
+
+ * lisp/cedet/srecode/mode.el (srecode-minor-mode-templates-menu):
+ Replace `(lambda..) with a closure. Use `push`.
+
+ * lisp/cedet/semantic/chart.el: Use lexical-binding.
+ * lisp/cedet/semantic/db-debug.el: Use lexical-binding.
+ * lisp/cedet/semantic/db-el.el: Use lexical-binding.
+ * lisp/cedet/semantic/db-file.el: Use lexical-binding.
+ * lisp/cedet/semantic/db-javascript.el: Use lexical-binding.
+ * lisp/cedet/semantic/db-mode.el: Use lexical-binding.
+ * lisp/cedet/semantic/db-ref.el: Use lexical-binding.
+ * lisp/cedet/semantic/decorate.el: Use lexical-binding.
+ * lisp/cedet/semantic/doc.el: Use lexical-binding.
+ * lisp/cedet/semantic/find.el: Use lexical-binding.
+ * lisp/cedet/semantic/format.el: Use lexical-binding.
+ * lisp/cedet/semantic/html.el: Use lexical-binding.
+ * lisp/cedet/semantic/ia.el: Use lexical-binding.
+ * lisp/cedet/semantic/imenu.el: Use lexical-binding.
+ * lisp/cedet/semantic/java.el: Use lexical-binding.
+ * lisp/cedet/semantic/mru-bookmark.el: Use lexical-binding.
+ * lisp/cedet/semantic/symref.el: Use lexical-binding.
+ * lisp/cedet/semantic/tag-file.el: Use lexical-binding.
+ * lisp/cedet/semantic/tag-write.el: Use lexical-binding.
+ * lisp/cedet/semantic/texi.el: Use lexical-binding.
+ * lisp/cedet/semantic/util-modes.el: Use lexical-binding.
+
+2021-03-15 Gabriel do Nascimento Ribeiro <gabriel.nascimento@nubank.com.br>
+
+ Init archive and add noconfirm to 'package-install-selected-packages'
+
+ * lisp/emacs-lisp/package.el (package-install-selected-packages):
+ Add call to 'package--archives-initialize' and add optional argument
+ NOCONFIRM to skip user confirmation when installing packages. (Bug#47124)
+
+2021-03-15 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/vc/ediff-vers.el: Remove XEmacs compat code.
+
+2021-03-15 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in expand.el
+
+ * lisp/expand.el: Use lexical-binding. Remove redundant :group args.
+
+2021-03-15 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/help-macro.el: Use lexical-binding.
+
+2021-03-15 Stefan Kangas <stefan@marxist.se>
+
+ Add three new tests for image.el
+
+ * test/lisp/image-tests.el (image-find-image)
+ (image-type-from-file-name, image-type/from-filename): New tests.
+
+2021-03-15 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/wid-edit.el (widget-field): Add subtle border to face.
+
+2021-03-14 Andrea Corallo <akrl@sdf.org>
+
+ Fix some entry in `comp-known-type-specifiers' (bug#46847)
+
+ * lisp/emacs-lisp/comp.el (comp-known-type-specifiers): Some
+ fix.
+ * test/src/comp-tests.el (comp-tests-46670-1): Update test.
+
+2021-03-14 Pip Cet <pipcet@gmail.com>
+
+ Don't call setjmp through a function pointer on Windows (bug#47067)
+
+ * src/comp.c (ABI_VERSION): Bump.
+ (emit_setjmp): Call setjmp directly.
+ (declare_runtime_imported_funcs): Remove setjmp.
+ (helper_link_table): Remove entry for setjmp.
+
+2021-03-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Revert "* lisp/calendar/appt.el (appt-activate): Set the local `write-file-functions`"
+
+ This reverts commit 587a97bcb23bc6ea429ab790efa03f2260a9bca8.
+ We really do want to affect the global part of the hook.
+ Reported by Gabriel <gabriel376@hotmail.com>.
+
+2021-03-14 Eli Zaretskii <eliz@gnu.org>
+
+ Fix hang due to failure to clean up *.eln.old files at exit
+
+ * src/comp.c (eln_load_path_final_clean_up): Call
+ internal_delete_file, not Fdelete_file, to ignore any errors.
+ (Bug#46972)
+
+2021-03-14 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: Tab groups can be displayed with tab-bar-format-tabs-groups
+
+ * lisp/tab-bar.el (tab-bar-format): Turn defvar into defcustom.
+ Add :options and force-mode-line-update in :set.
+ (tab-bar--format-tab): New function refactored from tab-bar-format-tabs.
+ (tab-bar-format-tabs): Move most of code to tab-bar--format-tab and call it.
+ (tab-bar-tab-group-format-function): New defcustom.
+ (tab-bar-tab-group-format-default): New function.
+ (tab-bar--format-tab-group, tab-bar-format-tabs-groups): New functions.
+ (tab-bar-format-align-right, tab-bar-format-global): Shorten id.
+ (tab-bar-change-tab-group): Add refs to tab-bar-format in docstring.
+
+2021-03-14 Gabriel do Nascimento Ribeiro <gabriel.nascimento@nubank.com.br>
+
+ * lisp/tab-line.el: Update docstring of 'tab-line-tabs-function' (bug#47117)
+
+ (tab-line-tabs-function): Mention 'tab-line-tabs-buffer-groups'
+ in the docstring.
+ (tab-line-tabs-buffer-groups): Add docstring.
+
+2021-03-14 Gabriel do Nascimento Ribeiro <gabriel.nascimento@nubank.com.br>
+
+ * lisp/tab-line.el: Add face for group-tab (bug#47118)
+
+ (tab-line-tab-face-functions): Add choice for 'tab-line-tab-face-group'.
+ (tab-line-tab-group): New face.
+ (tab-line-tabs-buffer-groups): Set alist key 'group-tab' for group tabs.
+ (tab-line-tab-face-group): New function to set face for group tabs.
+
+2021-03-14 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp-crypt.el (tramp-crypt-add-directory):
+
+ Don't autoload setting property `completion-predicate'.
+
+2021-03-14 Daniel Martín <mardani29@yahoo.es>
+
+ Fix reference to 'diff-font-lock-syntax' in diff-mode documentation
+
+ * doc/emacs/files.texi (Diff Mode): Add the omitted name of the
+ variable. (Bug#47129)
+
+2021-03-14 Alan Third <alan@idiocy.org>
+
+ Fix buffer overflow in xbm_scan (bug#47094)
+
+ * src/image.c (xbm_scan): Ensure reading a string doesn't overflow the
+ buffer.
+
+ (cherry picked from commit ebc3b25409dd614c1814a0643960452683e37aa3)
+
+2021-03-13 Alan Third <alan@idiocy.org>
+
+ Fix buffer overflow in xbm_scan (bug#47094)
+
+ * src/image.c (xbm_scan): Ensure reading a string doesn't overflow the
+ buffer.
+
+2021-03-13 Juri Linkov <juri@linkov.net>
+
+ Separate values 'override' and 'append' in 'outline-minor-mode-highlight'
+
+ * lisp/outline.el (outline-font-lock-keywords): Handle 'override' and 'append'
+ separately.
+ (outline-minor-mode-highlight): Separate values 'override' and 'append'.
+ (outline-minor-mode-highlight-buffer): Go to match-beginning
+ before checking '(point)'.
+
+2021-03-13 Stefan Kangas <stefan@marxist.se>
+
+ Add help-key-binding styling to wombat theme
+
+ * etc/themes/wombat-theme.el (help-key-binding): Add face
+ definition.
+
+2021-03-13 Eli Zaretskii <eliz@gnu.org>
+
+ Fix rare redisplay glitches when image has been removed from display
+
+ * src/dispnew.c (update_window): Make sure all glyph rows below
+ the last visible one are marked as invalid, even when the loop
+ which "updates the rest of the lines" didn't examine the last
+ visible row. (Bug#47093)
+
+2021-03-13 Stefan Kangas <stefan@marxist.se>
+
+ Adjust colors of help-key-binding face for readability
+
+ * lisp/faces.el (help-key-binding): Adjust colors for improved
+ readability, and use a flat :box for highlighting (with negative
+ :line-width height to avoid any vertical resizing of the minibuffer).
+
+ This was discussed in:
+ https://lists.gnu.org/r/emacs-devel/2021-03/msg00535.html
+
+2021-03-13 Michael Albinus <michael.albinus@gmx.de>
+
+ Remove ;;;###tramp-autoload cookie from Tramp defcustoms (Bug#47063)
+
+ * lisp/net/tramp-crypt.el (tramp-crypt-enabled-p): New defun.
+ (tramp-crypt-add-directory, tramp-crypt-remove-directory):
+ Add property `completion-predicate'.
+
+ * lisp/net/tramp-sh.el (tramp-terminal-type, tramp-remote-path)
+ (tramp-remote-process-environment): Remove. Move them to ...
+
+ * lisp/net/tramp.el: ... here.
+
+2021-03-13 Eli Zaretskii <eliz@gnu.org>
+
+ Extend support for faces in Enriched mode
+
+ * lisp/textmodes/enriched.el (enriched-face-ans): Support faces
+ with bold and italic attributes. (Bug#46507)
+
+2021-03-13 Matt Armstrong <matt@rfc20.org>
+
+ Fix typos and omissions for (elisp)Button Buffer Commands
+
+ * doc/lispref/display.texi (Button Buffer Commands): Minor
+ typo and omission fixes `backward-button' and
+ `forward-button'. (Bug#47051)
+
+2021-03-13 Eli Zaretskii <eliz@gnu.org>
+
+ Teach Rmail about NBSP in "Re:"
+
+ * lisp/mail/rmail.el (rmail-simplified-subject)
+ (rmail-reply-regexp): Allow NBSP in "RE:" prefixes.
+
+2021-03-12 Andrea Corallo <akrl@sdf.org>
+
+ Fix circular dependency when loading a modified comp.el (bug#47049)
+
+ * lisp/emacs-lisp/comp.el (comp-subr-trampoline-install): Move it
+ before other functional code.
+
+2021-03-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/keyboard.c (parse_solitary_modifier): Accept `click` modifier
+
+2021-03-12 Yuan Fu <casouri@gmail.com>
+
+ Fix simple-tests--undo*
+
+ * test/lisp/simple-tests.el (simple-tests--undo-in-region,
+ simple-tests--undo-equiv-table): Re-enable in batch mode.
+ Enable 'transient-mark-mode' in temp buffer.
+
+2021-03-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/filesets.el: Address byte-compiler warning
+
+ (filesets-run-cmd): Let-bind `filesets--files`.
+ (filesets-cmd-isearch-getargs): Use it.
+
+2021-03-12 Glenn Morris <rgm@gnu.org>
+
+ * lisp/tooltip.el (tooltip): Restore group that was not "redundant".
+
+2021-03-12 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 02a5cfce47 (origin/emacs-27) * lisp/mouse.el: Fix mouse-1-clock-follo...
+ c881e990e3 * lisp/emacs-lisp/gv.el (edebug-after): Don't run the gett...
+
+2021-03-12 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ fc83f37951 Fix initialization of 'while-no-input-ignore-events'
+ 8f603da44c Update documentation of reading passwords
+
+2021-03-12 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 2c5f215419 Avoid crashes in Mew due to corrupted tool-bar label
+ 7a23915618 * lisp/tooltip.el (tooltip): Doc fix for GTK.
+ c4bbe02cc4 * lisp/help.el (help-for-help-internal): Doc fix; use impe...
+
+ # Conflicts:
+ # lisp/help.el
+ # lisp/tooltip.el
+
+2021-03-12 Glenn Morris <rgm@gnu.org>
+
+ Skip recent undo tests in batch mode for now
+
+ * test/lisp/simple-tests.el (simple-tests--undo-in-region):
+ Split into separate test. Skip in batch mode for now.
+ (simple-tests--undo-equiv-table): Skip in batch mode for now.
+
+2021-03-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet/{*.el,ede/*.el}: Use lexical-binding
+
+ Remove a few redundant `:group` arguments as well.
+
+ * lisp/cedet/ede.el: Use lexical-binding.
+ Don't load `ede/files` at compile-time.
+ (ede-speedbar): Declare function.
+ (ede-load-project-file): Allow `rootreturn` to be a reference rather
+ than a symbol.
+ (ede-initialize-state-current-buffer): Pass `ROOT` as a reference
+ rather than a symbol to `ede-directory-get-open-project` and
+ `ede-load-project-file` so we don't need to make it dynamically scoped.
+ (ede-flush-deleted-projects): Avoid `add-to-list` on a local var.
+
+ * lisp/cedet/ede/files.el: Use lexical-binding.
+ (ede-directory-get-open-project): Allow `rootreturn` to be a reference
+ rather than a symbol.
+ (ede-project-root-directory): Remove unused var `root`.
+ (ede-expand-filename-impl): Remove unused vars `path` and `proj`.
+
+ * lisp/cedet/cedet-idutils.el: Use lexical-binding.
+ (cedet-idutils-search): Remove always-nil variable `scopeflags`.
+
+ * lisp/cedet/data-debug.el: Use lexical-binding.
+ (data-debug-insert-overlay-button, data-debug-insert-overlay-list-button)
+ (data-debug-insert-buffer-button, data-debug-insert-buffer-list-button)
+ (data-debug-insert-process-button): Remove always-nil variable `tip`.
+ (data-debug-insert-ring-button): Remove unused var `ringthing`.
+ (data-debug-insert-widget-properties): Remove unused var `type`.
+
+ * lisp/cedet/semantic.el: Use lexical-binding.
+ (semantic-mode): Strength-reduce `eval` to `symbol-value`.
+
+ * lisp/cedet/ede/custom.el: Use lexical-binding.
+ (ede-project-sort-targets): Remove unused vars `count`, `current`, and
+ `order`.
+
+ * lisp/cedet/ede/pconf.el: Use lexical-binding.
+ (ede-proj-configure-synchronize): Remove unused var `add-missing`.
+
+ * lisp/cedet/ede/pmake.el (ede-proj-makefile-garbage-patterns):
+ Simplify via η-reduction.
+ (ede-proj-makefile-dependencies): Use `seq-some` rather than `eval+or`.
+
+ * lisp/cedet/ede/proj-elisp.el: Use lexical-binding.
+ (project-compile-target): Remove unused var `elc`.
+ (ede-update-version-in-source): Remove unused var `match`.
+ (project-compile-target): Declare function `cedet-update-autoloads`
+ from file we don't have.
+
+ * lisp/cedet/cedet-cscope.el: Use lexical-binding.
+ * lisp/cedet/cedet-files.el: Use lexical-binding.
+ * lisp/cedet/cedet-global.el: Use lexical-binding.
+ * lisp/cedet/cedet.el: Use lexical-binding.
+ * lisp/cedet/ede/auto.el: Use lexical-binding.
+ * lisp/cedet/ede/autoconf-edit.el: Use lexical-binding.
+ * lisp/cedet/ede/config.el: Use lexical-binding.
+ * lisp/cedet/ede/cpp-root.el: Use lexical-binding.
+ * lisp/cedet/ede/detect.el: Use lexical-binding.
+ * lisp/cedet/ede/generic.el: Use lexical-binding.
+ * lisp/cedet/ede/linux.el: Use lexical-binding.
+ * lisp/cedet/ede/locate.el: Use lexical-binding.
+ * lisp/cedet/ede/makefile-edit.el: Use lexical-binding.
+ * lisp/cedet/ede/proj-info.el: Use lexical-binding.
+ * lisp/cedet/ede/proj-obj.el: Use lexical-binding.
+ * lisp/cedet/ede/proj-prog.el: Use lexical-binding.
+ * lisp/cedet/ede/proj-shared.el: Use lexical-binding.
+ * lisp/cedet/ede/proj.el: Use lexical-binding.
+ * lisp/cedet/ede/shell.el: Use lexical-binding.
+ * lisp/cedet/ede/simple.el: Use lexical-binding.
+ * lisp/cedet/ede/source.el: Use lexical-binding.
+ * lisp/cedet/ede/speedbar.el: Use lexical-binding.
+ * lisp/cedet/ede/util.el: Use lexical-binding.
+
+2021-03-12 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into native-comp
+
+2021-03-12 Michael Albinus <michael.albinus@gmx.de>
+
+ Tramp sshfs fixes
+
+ * doc/misc/tramp.texi (FUSE setup): Fix typo.
+
+ * lisp/net/tramp-sshfs.el (tramp-sshfs-handle-set-file-modes):
+ Use `tramp-compat-set-file-modes'.
+
+ * test/lisp/net/tramp-tests.el
+ (tramp-test43-asynchronous-requests): Don't run for tramp-sshfs.
+
+2021-03-12 Andrea Corallo <akrl@sdf.org>
+
+ Implement `no-native-compile' (bug#46983)
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-from-buffer): Capture
+ `no-native-compile'.
+ * lisp/emacs-lisp/comp.el (no-native-compile): Define new
+ variable.
+ (comp-spill-lap-function): Throw when `no-native-compile' was
+ captured non-nil.
+ (comp--native-compile): Catch `no-native-compile' if necessary and
+ return nil in case.
+
+2021-03-12 Robert Pluim <rpluim@gmail.com>
+
+ Document how to create a branch for Git/Mercurial
+
+ * doc/emacs/maintaining.texi (Creating Branches): Add instructions
+ for git/Mercurial.
+
+2021-03-12 Andrea Corallo <akrl@sdf.org>
+
+ Fix error reporting for async native compilation (bug#47024)
+
+ * lisp/emacs-lisp/comp.el (comp--native-compile): During async
+ compilation if we catch an error print it in a parsable way so we
+ can report it to the user.
+
+2021-03-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cconv.el (cconv--analyze-use): Simplify (doh!)
+
+2021-03-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cconv.el (cconv--analyze-use): Tune down the warning
+
+ Don't warn for always-nil bindings if the binding is made explicit.
+ Fixes bug#47080.
+
+2021-03-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/syntax.el (syntax-propertize-rules): Use `macroexp-let2`
+
+ This also silences the recently introduced compilation warning.
+
+2021-03-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Rename to image--transform-smoothing in image-mode.el
+
+ * lisp/image-mode.el (image--transform-smoothing): Rename from
+ image-transform-smoothing.
+ (image-transform-properties, image-transform-reset): Adjust usage.
+
+2021-03-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new `image-transform-smoothing' user option
+
+ * doc/lispref/display.texi (Image Descriptors): Document it.
+ * lisp/image.el (image-transform-smoothing): New user option.
+ (create-image): Use it.
+ (image--default-smoothing): New function.
+
+2021-03-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix compilation warning in python-wy.el after lexical rewrite
+
+ * admin/grammars/python.wy: Require semantic/tag.
+
+ In end of data:
+ cedet/semantic/wisent/python-wy.el:862:1: Warning: the function
+ `semantic-tag-name' might not be defined at runtime.
+
+2021-03-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make byte-compiled uses of `define-minor-mode' more compatible
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Be more
+ defensive about accessing minor mode variables.
+
+2021-03-11 Yuan Fu <casouri@gmail.com>
+
+ Map redo records for undo in region to 'undo-in-region
+
+ * lisp/simple.el (undo-equiv-table): Add explanation for
+ undo-in-region, undo to the beginning of undo list and null undo.
+ (undo): If equiv is 'undo-in-region, empty or t, set pending-undo-list
+ to t. If the redo is undo-in-region, map buffer-undo-list to
+ 'undo-in-region instead of t, if it is an identity mapping, map to
+ 'empty.
+ (undo-make-selective-list): Only continue when ulist is a proper list.
+ * test/lisp/simple-tests.el (simple-tests--undo): Add test for
+ undo-only in region.
+ (simple-tests--sans-leading-nil): New helper function.
+ (simple-tests--undo-equiv-table): New test for 'undo-equiv-table'.
+
+2021-03-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/mail/: Use lexical-binding
+
+ Remove some redundant `:group` args as well.
+
+ * lisp/mail/supercite.el: Use lexical-binding.
+ (completer-disable): Declare var.
+ (sc-set-variable): Don't rely on dynbind to access `help` variable.
+
+ * lisp/mail/mail-extr.el: Use lexical-binding.
+ (mail-extract-address-components): Avoid use of dynamic scoping to
+ refer to local vars.
+
+ * lisp/mail/mailabbrev.el: Use lexical-binding.
+ (mail-abbrev-make-syntax-table): Rename `_` variable to `syntax-_`.
+
+ * lisp/mail/mailheader.el: Use lexical-binding.
+ (headers): Don't declare as dynbound globally.
+ (mail-header-set, mail-header-merge): Declare `headers` as dynbound
+ locally, instead. Mark those functions as obsolete.
+ (mail-header-format): Use `alist-get` instead of `mail-header`.
+
+ * lisp/mail/binhex.el (binhex-decode-region-external): Remove always-nil
+ var `firstline`.
+
+ * lisp/mail/emacsbug.el: Use lexical-binding.
+ (report-emacs-bug): Remove always-nil var `message-end-point`.
+
+ * lisp/mail/rmail-spam-filter.el: Use lexical-binding.
+ (bbdb/mail_auto_create_p): Declare variable.
+
+ * lisp/mail/rmail.el (rmail-get-new-mail): Remove always-nil var
+ `delete-files`.
+
+ * lisp/mail/rmailout.el: Use lexical-binding.
+ (rmail-output-read-file-name): Remove unused var `err`.
+ (rmail-convert-to-babyl-format): Remove unused var `count`.
+ (rmail-output-as-mbox): Remove unused vars `from` and `date`.
+
+ * lisp/mail/rmailsort.el: Use lexical-binding.
+ (rmail-sort-messages): Remove unused var `msginfo`.
+
+ * lisp/mail/rfc822.el: Use lexical-binding.
+ * lisp/mail/rmailedit.el: Use lexical-binding.
+ * lisp/mail/mailclient.el: Use lexical-binding.
+ * lisp/mail/blessmail.el: Use lexical-binding.
+ * lisp/mail/mail-hist.el: Use lexical-binding.
+ * lisp/mail/rmailkwd.el: Use lexical-binding.
+ * lisp/mail/rmailmsc.el: Use lexical-binding.
+ * lisp/mail/uce.el: Use lexical-binding.
+ * lisp/mail/unrmail.el: Use lexical-binding.
+
+2021-03-11 Juri Linkov <juri@linkov.net>
+
+ Update docstrings of 'delete'/'remove' to interlink each other (bug#47054)
+
+ * lisp/subr.el (remove): Add xref to 'delete'.
+ * src/fns.c (Fdelete): Add xref to 'remove'.
+
+2021-03-11 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar--current-tab-find): New function.
+
+ (tab-bar-close-other-tabs, tab-bar-close-group-tabs): Use it.
+ (tab-bar--history-pre-change): Rename from
+ 'tab-bar-history--pre-change' to follow naming convention.
+ (tab-bar-history-mode): Use renamed 'tab-bar--history-pre-change'.
+
+2021-03-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ On MS-Windows, fflush stderr after newline
+
+ Problem reported by Ioannis Kappas (Bug#46388).
+ * src/sysdep.c (errputc) [WINDOWSNT]: Flush stderr after newline.
+
+2021-03-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/outline.el (outline-font-lock-keywords): Simplify
+
+ The `laxmatch` part of `font-lock-keywords` is just a boolean.
+
+2021-03-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp: Remove yet more always-nil variables
+
+ * lisp/align.el (align-region):
+ Remove always-nil variable `group-c`.
+ * lisp/ido.el (ido-make-prompt): Remove always-nil variable `prefix`.
+
+ * lisp/xdg.el (xdg-mime-collect-associations):
+ Remove always-nil variable `end`.
+
+ * lisp/calc/calc-yank.el (calc-edit):
+ Remove always-nil variable `flag`.
+
+ * lisp/calendar/todo-mode.el (todo-edit-item--header):
+ Remove always-nil variable `dayname`.
+ (todo-show-categories-table):
+ Remove always-nil variable `sortkey`.
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-ispell-docstring-engine):
+ Remove always-nil variable `err`.
+
+ * lisp/emacs-lisp/tcover-ses.el: Remove always-nil variable `pause`.
+
+ * lisp/eshell/em-ls.el (eshell-ls-files):
+ Remove always-nil variable `ignore`.
+
+ * lisp/net/ange-ftp.el (ange-ftp-copy-file-internal): Remove always-nil
+ variable `temp2`.
+
+ * lisp/progmodes/cperl-mode.el (cperl-tags-hier-init): Remove
+ always-nil variables `l1`, `l2`, `l3`.
+ (cperl-tags-treeify): Remove always-nil variable `l1`.
+
+ * lisp/progmodes/ebrowse.el (ebrowse-tags-read-member+class-name):
+ Remove always-nil variable `class`.
+
+ * lisp/textmodes/artist.el (artist-draw-ellipse-with-0-height):
+ Remove always-nil variable `fill-info`.
+
+ * lisp/textmodes/flyspell.el (flyspell-emacs-popup):
+ Remove always-nil variable `show-affix-info`.
+
+ * lisp/textmodes/rst.el (rst-Ado):
+ Remove always-nil variable `char`.
+
+ * lisp/vc/vc.el (vc-diff-build-argument-list-internal):
+ Remove always-nil variable `rev2-default`.
+
+2021-03-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet: Remove always-nil variables
+
+ * lisp/cedet/ede/pmake.el (ede-proj-makefile-insert-variables):
+ Remove always-nil variable `conf-done`.
+
+ * lisp/cedet/ede/project-am.el: Use ref instead of dynbound var.
+ (project-rescan): Pass the ref.
+ (project-am-expand-subdirlist): Use it.
+
+ * lisp/cedet/semantic/idle.el (semantic-idle-work-core-handler):
+ Fix misuse of the wrong `errbuf `variable.
+
+ * lisp/cedet/semantic/scope.el (semantic-analyze-scoped-type-parts):
+ Remove always-nil variable `extmeth`.
+
+ * lisp/cedet/semantic/wisent/comp.el (wisent-context-name)
+ (wisent-context-bindings): Make them into functions.
+ (wisent-with-context): Use `dlet`.
+
+2021-03-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emulation/edt.el (edt-with-position): Don't bind `left`
+
+ (edt-find-forward, edt-find-next-forward, edt-sentence-forward)
+ (edt-paragraph-forward): Adjust accordingly.
+
+2021-03-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/vc/pcvs-parse.el: Fix lexical-binding breakage
+
+ (cvs-parse-table, cvs-parse-merge, cvs-parse-status, cvs-parse-commit):
+ Declare vars set by `cvs-match` as dynamic.
+
+2021-03-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/ses.el (ses-set-cell): Use `macroexp-let2`
+
+ (ses--\,@); Rename from `ses--metaprogramming`.
+
+2021-03-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/obsolete/iswitchb.el: Remove dead code
+
+ (most-len, most-is-exact): Delete vars.
+ (iswitchb-output-completion): Delete function.
+ (iswitchb-completions): Delete dead code consequence of `most` being nil.
+
+2021-03-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/org/: Delete some always-nil variables
+
+ * lisp/org/ob-lilypond.el (org-babel-lilypond-compile-lilyfile):
+ Remove always-nil variable `arg-2`.
+
+ * lisp/org/ol-gnus.el (org-gnus-store-link):
+ Remove always-nil variables `newsgroup` and `xarchive`.
+
+ * lisp/org/ol.el (org-store-link):
+ Remove always-nil variable `description`.
+
+ * lisp/org/org-clock.el (org-clock-special-range):
+ Remove always-nil variables `m1` and `m`.
+
+ * lisp/org/org-crypt.el (org--matcher-tags-todo-only): Declare var.
+
+ * lisp/org/org-protocol.el (org-protocol-open-source):
+ Remove always-nil variable `result`.
+
+ * lisp/org/ox-odt.el (org-odt-format-label):
+ Remove always-nil variable `short-caption`.
+ (org-odt-link--inline-formula):
+ Remove always-nil variables `width` and `height`.
+
+ * lisp/org/ox.el (org-export--missing-definitions):
+ Remove always-nil variable `seen`.
+
+2021-03-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cconv.el (cconv--analyze-use): Warn never-initialized vars
+
+ (byte-compile-not-lexical-var-p): Remove Emacs<24 compatibility.
+
+2021-03-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Re-fix previous Info-fontify-node change
+
+ * lisp/info.el (Info-fontify-node): Re-fix previous fix here
+ (bug#34661) by fixing an off-by-one error in the `looking-back'.
+
+2021-03-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/mouse.el: Fix mouse-1-clock-follows-mouse = double
+
+ This functionality was broken by commit 3d5e31eceb9dc1fb62b2b2,
+ the problem being that we end up considering as distinct the events
+ `down-double-mouse-1` and `double-down-mouse-1`.
+
+ Reported by Eyal Soha <eyalsoha@gmail.com>
+
+ (mouse--click-1-maybe-follows-link): Make sure the last element of
+ the list passed to `event-convert-list` is indeed a "basic" event.
+
+2021-03-11 Michael Albinus <michael.albinus@gmx.de>
+
+ Add remote processes to Tramp sshfs method
+
+ * doc/misc/tramp.texi (FUSE setup): Method sshfs supports also
+ remote processes.
+
+ * lisp/net/tramp-cache.el (tramp-get-file-property)
+ (tramp-set-file-property): Move setting of
+ `tramp-cache-unload-hook' out of function.
+
+ * lisp/net/tramp.el (tramp-expand-args): New defun.
+ (tramp-handle-make-process):
+ * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-out-of-band)
+ (tramp-maybe-open-connection):
+ * lisp/net/tramp-sshfs.el (tramp-sshfs-maybe-open-connection):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-send-command): Use it.
+
+ * lisp/net/tramp-sshfs.el (tramp-methods) <sshfs>:
+ Adapt `tramp-mount-args'. Add `tramp-login-args',
+ `tramp-direct-async', `tramp-remote-shell',
+ `tramp-remote-shell-login' and `tramp-remote-shell-args'.
+ (tramp-connection-properties): Set "direct-async-process" fir sshfs.
+ (tramp-sshfs-file-name-handler-alist): Add `exec-path',
+ `make-process', `process-file', `set-file-modes', `shell-command',
+ `start-file-process', `tramp-get-remote-gid',
+ `tramp-get-remote-uid' and `tramp-set-file-uid-gid'.
+ (tramp-sshfs-handle-exec-path, tramp-sshfs-handle-process-file)
+ (tramp-sshfs-handle-set-file-modes): New defuns.
+
+ * test/lisp/net/tramp-tests.el (tramp-test20-file-modes)
+ (tramp-test28-process-file, tramp-test29-start-file-process)
+ (tramp-test30-make-process, tramp-test32-shell-command)
+ (tramp-test32-shell-command-dont-erase-buffer)
+ (tramp-test34-explicit-shell-file-name, tramp-test35-exec-path)
+ (tramp-test43-asynchronous-requests): Run also for tramp-sshfs.
+ (tramp--test-shell-file-name): New defun.
+ (tramp-test28-process-file)
+ (tramp-test34-explicit-shell-file-name)
+ (tramp-test43-asynchronous-requests): Use it.
+ (tramp-test40-special-characters-with-stat)
+ (tramp-test40-special-characters-with-perl)
+ (tramp-test40-special-characters-with-ls)
+ (tramp-test41-utf8-with-stat, tramp-test41-utf8-with-perl)
+ (tramp-test41-utf8-with-ls): Remove superfluous skip.
+
+2021-03-11 Petteri Hintsanen <petterih@iki.fi>
+
+ Make tags tables from Texinfo sources
+
+ * doc/misc/Makefile.in (ETAGS, texifiles): New variables.
+ (TAGS, tags, FORCE, ${ETAGS}): New targets.
+ (bootstrap-clean maintainer-clean): Delete TAGS.
+ * doc/lispref/Makefile.in (ETAGS, texifiles): New variables.
+ (TAGS, tags, FORCE, ${ETAGS}): New targets.
+ (bootstrap-clean maintainer-clean): Delete TAGS.
+ * doc/lispintro/Makefile.in (ETAGS, texifiles): New variables.
+ (TAGS, tags, FORCE, ${ETAGS}): New targets.
+ (bootstrap-clean maintainer-clean): Delete TAGS.
+ * doc/emacs/Makefile.in (ETAGS, texifiles): New variables.
+ (TAGS, tags, FORCE, ${ETAGS}): New targets.
+ (bootstrap-clean maintainer-clean): Delete TAGS.
+ * Makefile.in (TAGS tags): Make tags in doc/emacs, doc/lispintro,
+ doc/lispref and doc/misc.
+
+2021-03-11 Philipp Stephani <phst@google.com>
+
+ * src/image.c (image_set_transform): Don't use ! for Lisp object.
+
+ * src/image.c (FRAME_SCALE_FACTOR): Define only when needed.
+
+2021-03-11 Eli Zaretskii <eliz@gnu.org>
+
+ Fix wording of a recently added documentation
+
+ * etc/NEWS:
+ * doc/lispref/display.texi (Image Descriptors): Fix wording of the
+ description of :transform-smoothing.
+
+2021-03-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/nnmh.el (nnmh-newsgroup-articles): Declare var
+
+ Reported by Barry Fishman <barry@ecubist.org>.
+
+ Along the way, I checked other variables which are similarly let-bound
+ to nil and then read with any intervening assignment, which found
+ another similar case of missing `defvar`s plus a bit of dead code.
+
+ * lisp/gnus/gnus-kill.el (gnus-apply-kill-file-internal):
+ Remove constant nil var `beg`.
+ * lisp/gnus/gnus-search.el (gnus-search-query-parse-kv):
+ Remove constant nil var `return`.
+ * lisp/gnus/gnus-start.el (gnus-ask-server-for-new-groups):
+ Remove constant nil var `group`.
+ (gnus-killed-assoc, gnus-marked-assoc, gnus-newsrc-assoc): Declare vars.
+ * lisp/gnus/gnus-sum.el (gnus-compute-read-articles):
+ Remove constant nil var `first`.
+ * lisp/gnus/nnbabyl.el (nnbabyl-request-accept-article):
+ Remove constant nil var `beg`.
+ * lisp/gnus/nnfolder.el (nnfolder-possibly-change-group):
+ Remove constant nil var `inf`.
+ * lisp/gnus/nnrss.el (nnrss-request-article):
+ Remove constant nil var `err`.
+
+2021-03-10 Alan Third <alan@idiocy.org>
+
+ Enable selectable image smoothing (bug#38394)
+
+ * lisp/doc-view.el (doc-view-insert-image): Always use smoothing in
+ docview.
+ * lisp/image-mode.el (image-transform-smoothing): New variable.
+ (image-mode-map): Add smoothing binding.
+ (image-transform-properties): Apply smoothing when requested.
+ (image-transform-set-smoothing): New function.
+ (image-transform-reset): Reset smoothing.
+ * src/image.c (image_set_transform): Use new :transform-smoothing
+ attribute.
+ (syms_of_image): Add :transform-smoothing attribute.
+ * doc/lispref/display.texi (Image Descriptors): Document new
+ :transform-smoothing property.
+
+2021-03-10 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-close-group-tabs): New command.
+
+ (tab-close-group): New alias.
+ (tab-bar-close-other-tabs): Rewrite to fix old bug where regardless of
+ the returned value from tab-bar-tab-prevent-close-functions,
+ only one tab was retained.
+
+2021-03-10 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: 'C-x t G' (tab-group) assigns a group name to the tab.
+
+ * lisp/tab-bar.el (tab-bar--tab, tab-bar--current-tab): Add tab group if any.
+ (tab-bar-change-tab-group): New command.
+ (display-buffer-in-new-tab): Handle tab-group alist entry.
+ (tab-group): New alias.
+ (tab-prefix-map): Bind "G" to 'tab-group'.
+
+2021-03-10 Kévin Le Gouguec <kevin.legouguec@gmail.com>
+
+ Highlight the entire summary line for selected articles
+
+ * lisp/gnus/gnus-sum.el (gnus-highlight-selected-summary):
+ Highlight the entire summary line (bug#47026).
+
+2021-03-10 Stefan Kangas <stefan@marxist.se>
+
+ Remove Emacs 19 workaround from cperl-mode.el
+
+ * lisp/progmodes/cperl-mode.el (cperl-make-indent): Remove Emacs 19
+ workaround.
+
+2021-03-10 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/loadup.el: Don't load pcase on native builds (bug#47025).
+
+2021-03-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix byte-compilation warning in benchmark-run
+
+ * lisp/emacs-lisp/benchmark.el (benchmark-run): Avoid a
+ byte-compilation warning about an empty let body (bug#46819).
+
+2021-03-10 Andrea Corallo <akrl@sdf.org>
+
+ Fix truncated warnings (bug#47024)
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): Bind
+ `warning-fill-column' to `most-positive-fixnum'.
+
+2021-03-10 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/files.el (cd): Improve error message.
+
+2021-03-10 Mattias Engdegård <mattiase@acm.org>
+
+ Mark string predicates side-effect-free
+
+ * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Add string>,
+ string-greaterp, string-empty-p, string-prefix-p, string-suffix-p
+ and string-blank-p, all recently marked pure.
+
+2021-03-10 Stefan Kangas <stefan@marxist.se>
+
+ Remove several references to Emacs 22 and earlier
+
+ * admin/charsets/mapfiles/README:
+ * doc/emacs/custom.texi (Saving Customizations):
+ * doc/lispintro/emacs-lisp-intro.texi (Simple Extension):
+ * doc/misc/efaq-w32.texi (Location of init file):
+ * doc/misc/gnus-faq.texi (FAQ 1-3):
+ * doc/misc/gnus.texi (Top, Various, Image Enhancements):
+ * lisp/erc/erc-menu.el (menu):
+ * lisp/progmodes/cfengine.el (cfengine-fill-paragraph):
+ Remove some references to Emacs 22 and earlier.
+
+ * doc/lispref/buffers.texi:
+ * doc/lispref/eval.texi:
+ * doc/lispref/files.texi:
+ * doc/lispref/keymaps.texi:
+ * doc/lispref/loading.texi:
+ * doc/lispref/minibuf.texi:
+ * doc/lispref/positions.texi:
+ * doc/lispref/variables.texi: Remove comments about "Emacs 19
+ specific" features.
+
+2021-03-10 Stefan Kangas <stefan@marxist.se>
+
+ Fix duplicate ":" in ert-find-test-other-window prompt
+
+ * lisp/emacs-lisp/ert.el (ert-find-test-other-window): Don't insert
+ duplicate ":" in prompt.
+
+2021-03-10 Stefan Kangas <stefan@marxist.se>
+
+ Do mode tagging in ert.el
+
+2021-03-10 Stefan Kangas <stefan@marxist.se>
+
+ Use proper command substitutions in some docstrings
+
+ * lisp/arc-mode.el (archive-mode):
+ * lisp/ibuffer.el (ibuffer):
+ * lisp/tar-mode.el (tar-mode):
+ * lisp/textmodes/table.el (table-insert): Use substitute-command-keys
+ instead of hardcoded keys in some docstrings.
+
+2021-03-10 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/userlock.el: Use lexical-binding.
+
+2021-03-10 Stefan Kangas <stefan@marxist.se>
+
+ Use 'help-key-binding' face in userlock.el
+
+ * lisp/userlock.el (userlock--fontify-key): New function.
+ (ask-user-about-lock, ask-user-about-lock-help,
+ (ask-user-about-supersession-threat)
+ (ask-user-about-supersession-help): Add face 'help-key-binding' to
+ displayed keys.
+
+2021-03-10 Dmitry Gutov <dgutov@yandex.ru>
+
+ (project-switch-commands): Remove the ###autoload instruction
+
+ * lisp/progmodes/project.el (project-switch-commands):
+ Remove the ###autoload instruction. It's unnecessary and can
+ cause surprises in some circumstances (bug#46986).
+
+2021-03-10 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/help.el (help--describe-translation): Fix typo.
+
+2021-03-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/mail/rmailmm.el: Use `cl-defstruct` and `lexical-binding`
+
+ Remove redundant `:group` args.
+ (rmail-mime-entity): Make it a `cl-defstruct`.
+ (rmail-mime-entity-set-truncated): Mark as obsolete.
+ (rmail-mime-display): New `cl-defstruct`.
+ (rmail-mime-shown-mode, rmail-mime-hidden-mode, rmail-mime-raw-mode)
+ (rmail-mime-toggle-hidden, rmail-mime-update-tagline)
+ (rmail-mime-text-handler, rmail-mime-bulk-handler)
+ (rmail-mime-process-multipart, rmail-mime-handle, rmail-mime-process)
+ (rmail-mime-parse, rmail-mime-insert, rmail-show-mime): Adjust accordingly.
+ (rmail-mime-toggle-raw): Apply de Morgan.
+ (rmail-mime-insert-text): Remove unused var `tagline`.
+ (rmail-mime-insert-image): Remove unused var `content-type`.
+ (shr-inhibit-images, shr-width): Declare vars.
+ (rmail-mime-insert-multipart): Remove unused vars `tagline` and `body`.
+ (rmail-mime-insert): Remove unused var `tagline`.
+ (rmail-search-mime-message): Remove unused var `body-end`.
+
+2021-03-09 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port alternate signal stack to upcoming glibc 2.34
+
+ * src/sysdep.c (sigsegv_stack): Increase size to 64 KiB and align
+ it to max_align_t. This copies from Gnulib’s c-stack.c, and works
+ around a portability bug in draft glibc 2.34, which no longer
+ defines SIGSTKSZ when _GNU_SOURCE is defined.
+
+2021-03-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/buffer.c (Fbuffer_swap_text): Swap `mark-active` as well
+
+ This avoids undesirable situations where `mark-active` is set even
+ though the `mark` isn't.
+
+2021-03-09 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-select-tab): Set window-state-put WINDOW arg to nil
+
+ WINDOW arg nil will always create a new window regardless of the value
+ returned by 'frame-root-window' that is nondeterministic - it returns
+ an internal window when there are more than 1 window on the frame/tab,
+ otherwise it returns a live window that was reused between different tabs
+ (bug#46904)
+ (tab-prefix-map): Bind "u" to 'tab-undo'.
+
+2021-03-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cconv.el: Don't confuse a string for a docstring
+
+ (cconv--convert-funcbody): Check there's something after a docstring.
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-string-vs-docstring):
+ New corresponding test.
+
+2021-03-09 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (ABI_VERSION): Bump following-up 380ba045c4.
+
+ * test/src/comp-resources/comp-test-funcs.el
+ (comp-test-46670-1-f): Remove a warning.
+
+ Merge commit '9cbdf20316' into native-comp
+
+2021-03-09 Pip Cet <pipcet@gmail.com>
+
+ * Fix comp unit type decl in eln files to fix GC crash (bug#46256)
+
+ * src/comp.c (emit_ctxt_code): Allocate comp_unit as a Lisp_Object,
+ not a pointer to pointer to Lisp_Object.
+
+2021-03-09 Pip Cet <pipcet@gmail.com>
+
+ Zero stale pointer when unloading comp units (bug#46256)
+
+ * src/alloc.c (cleanup_vector): Call unload_comp_unit.
+ * src/comp.c (unload_comp_unit): New function.
+
+2021-03-09 Konstantin Kharlamov <Hi-Angel@yandex.ru>
+
+ smerge-vc-next-conflict: Move to conflict markers more reliably
+
+ * lisp/vc/smerge-mode.el (smerge-vc-next-conflict): Search for a
+ conflict marker if call to (vc-find-conflicted-file) haven't resulted in
+ a jump to one. And remove `buffer` variable that becomes unused.
+
+2021-03-09 Dmitry Gutov <dgutov@yandex.ru>
+
+ Strip text properties from the default string
+
+ * lisp/progmodes/project.el (project--read-regexp):
+ Strip text properties from the default string (bug#47012).
+
+2021-03-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make semantic/idle not move point after last change
+
+ * lisp/cedet/semantic/idle.el (semantic--eldoc-info): Don't move
+ point (bug#46999).
+
+2021-03-08 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/xref.el (xref-after-update-hook): New defcustom (bug#46992).
+
+ (xref--insert-xrefs): Use run-hooks on it.
+
+2021-03-08 Juri Linkov <juri@linkov.net>
+
+ * lisp/faces.el (help-argument-name): Use grey background, not foreground
+
+ https://lists.gnu.org/archive/html/emacs-devel/2021-03/msg00402.html
+
+2021-03-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/net/*.el: Use lexical-binding
+
+ Also remove some redundant `:group` arguments.
+
+ * lisp/net/eudc-export.el: Use lexical-binding.
+ (eudc-create-bbdb-record): Use `cl-progv` and `apply` to avoid `eval`.
+
+ * lisp/net/eudc-hotlist.el: Use lexical-binding.
+
+ * lisp/net/eudc.el (eudc-print-attribute-value): Use `funcall` to avoid
+ `eval`.
+
+ * lisp/net/eudcb-bbdb.el: Use lexical-binding.
+ (eudc-bbdb-filter-non-matching-record): Use `funcall` to avoid `eval`.
+ Move `bbdb-val` binding to avoid `setq`.
+ Use `seq-some` instead of `eval+or`.
+ (eudc-bbdb-format-record-as-result): Use `dolist` and `pcase`.
+ Use `funcall` to avoid `eval`.
+ (eudc-bbdb-query-internal): Simplify a bit.
+
+ * lisp/net/eudcb-ldap.el: Use lexical-binding.
+ (eudc-ldap-get-host-parameter): Use `defalias` to avoid `eval-and-compile`.
+
+ * lisp/net/telnet.el: Use lexical-binding.
+ * lisp/net/quickurl.el: Use lexical-binding.
+ * lisp/net/newst-ticker.el: Use lexical-binding.
+ * lisp/net/newst-reader.el: Use lexical-binding.
+ * lisp/net/goto-addr.el: Use lexical-binding.
+ * lisp/net/gnutls.el: Use lexical-binding.
+ * lisp/net/eudcb-macos-contacts.el: Use lexical-binding.
+ * lisp/net/eudcb-mab.el: Use lexical-binding.
+
+ * lisp/net/net-utils.el: Use lexical-binding.
+ (finger): Remove unused var `found`.
+
+ * lisp/net/network-stream.el (open-protocol-stream): Remove redundant
+ `defalias`.
+
+ * lisp/net/newst-plainview.el: Use lexical-binding.
+ (newsticker-hide-entry, newsticker-show-entry): Remove unused var
+ `is-invisible`.
+ (w3m-fill-column, w3-maximum-line-length): Declare vars.
+
+ * lisp/net/tramp.el (tramp-compute-multi-hops):
+ * lisp/net/tramp-compat.el (tramp-compat-temporary-file-directory):
+ * lisp/net/tramp-cmds.el (tramp-default-rename-file):
+ * lisp/net/webjump.el (webjump): Don't forget lexical-binding for `eval`.
+
+2021-03-08 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix handling of `tramp-cache-{g,s}et-count-*'
+
+ * lisp/net/tramp-cache.el (tramp-get-file-property)
+ (tramp-set-file-property): Fix handling of `tramp-cache-{g,s}et-count-*'.
+
+2021-03-08 Philipp Stephani <phst@google.com>
+
+ Fix structure of condition object in nested 'ert-fail'.
+
+ See the test 'ert-test-fail' for the expected structure.
+
+ * lisp/emacs-lisp/ert.el (ert--should-signal-hook): Condition list
+ should be (SYMBOL . DATA), not (SYMBOL DATA).
+ * test/lisp/emacs-lisp/ert-tests.el (ert-test-fail-inside-should): Fix
+ unit test.
+
+2021-03-08 Simen Heggestøyl <simenheg@gmail.com>
+
+ Use `pop-to-buffer-same-window' in `project-eshell'
+
+ * lisp/progmodes/project.el (project-eshell): Use
+ `pop-to-buffer-same-window' instead of `pop-to-buffer' to match the
+ behavior of `M-x eshell'.
+
+2021-03-08 Mauro Aranda <maurooaranda@gmail.com>
+
+ Make checkdoc--next-docstring use the doc-string-elt property
+
+ This follows from a fix for Bug#46918 and a discussion to use
+ doc-string-elt:
+ https://lists.gnu.org/archive/html/emacs-devel/2021-03/msg00232.html
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc--next-docstring): Check for a
+ non-nil doc-string-elt property, instead of hard-coding the
+ supported symbols. Use that property to position point at the
+ doc-string.
+
+2021-03-08 Michael Albinus <michael.albinus@gmx.de>
+
+ Add Tramp sshfs method
+
+ * doc/misc/tramp.texi (Top, Configuration): Insert sections 'FUSE-based
+ methods' and 'FUSE setup' in menu.
+ (Quick Start Guide): Fix @anchors. Add doas. Extend section
+ 'Using @command{rclone}' to 'Using @acronym{FUSE}-based methods'.
+ (External methods): Remove rclone paragraph.
+ (FUSE-based methods, FUSE setup): New nodes.
+ (Predefined connection information): Mention "mount-point".
+
+ * etc/NEWS: Mention Tramp sshfs method.
+ Fix typos and other oddities.
+
+ * lisp/net/tramp-fuse.el: New file.
+
+ * lisp/net/tramp-rclone.el (tramp-fuse): Require.
+ (tramp-rclone-file-name-handler-alist): Replace `tramp-rclone-handle-*'
+ by `tramp-fuse-handle-*' where appropriate.
+ (tramp-rclone-handle-delete-directory)
+ (tramp-rclone-handle-delete-file)
+ (tramp-rclone-handle-directory-files)
+ (tramp-rclone-handle-file-attributes)
+ (tramp-rclone-handle-file-executable-p)
+ (tramp-rclone-handle-file-name-all-completions)
+ (tramp-rclone-handle-file-readable-p)
+ (tramp-rclone-handle-insert-directory)
+ (tramp-rclone-handle-insert-file-contents)
+ (tramp-rclone-handle-make-directory, tramp-rclone-mount-point)
+ (tramp-rclone-mounted-p, tramp-rclone-local-file-name):
+ Remove. Functionality moved to tramp-fuse.el.
+ (tramp-rclone-remote-file-name)
+ (tramp-rclone-maybe-open-connection): Use `tramp-fuse-*' functions.
+
+ * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-out-of-band):
+ Simplify check.
+
+ * lisp/net/tramp-sshfs.el: New file.
+
+ * lisp/net/tramp.el: Remove TODO item.
+
+ * test/lisp/net/tramp-tests.el (tramp--test-sshfs-p): New defun.
+ (tramp-test14-delete-directory): Use it.
+
+2021-03-08 Stefan Kangas <stefan@marxist.se>
+
+ Delete two more items obsoleted in Emacs 23.1
+
+ * lisp/calendar/icalendar.el
+ (icalendar--datetime-to-noneuropean-date): Remove alias obsolete since
+ * lisp/obsolete/nnir.el (nnir-swish-e-index-file):
+ Delete items obsolete since Emacs 23.1.
+
+2021-03-08 Stefan Kangas <stefan@marxist.se>
+
+ Normalize version specifiers for make-obsolete and friends
+
+ * lisp/auth-source.el (auth-source-forget-user-or-password)
+ (auth-source-user-or-password, auth-source-hide-passwords):
+ * lisp/calendar/icalendar.el (icalendar--datetime-to-noneuropean-date):
+ * lisp/cedet/semantic/db-el.el (semanticdb-elisp-sym-function-arglist):
+ * lisp/emacs-lisp/debug.el (debugger-insert-backtrace):
+ * lisp/obsolete/nnir.el (nnir-swish-e-index-file):
+ * lisp/obsolete/starttls.el (starttls-any-program-available):
+ Normalize version specifiers for make-obsolete and friends.
+
+2021-03-08 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/help-mode.el (help-mode-tool-bar-map): Fix tooltips.
+
+2021-03-08 Stefan Kangas <stefan@marxist.se>
+
+ Add new face 'help-key-binding' for keybindings in help
+
+ * lisp/faces.el (help-key-binding): New face.
+ * lisp/help.el
+ (help-for-help): Rename from 'help-for-help-internal'. Use
+ 'substitute-command-keys' syntax.
+ (help): Make into alias for 'help-for-help'.
+ (help-for-help-internal): Make into obsolete alias for
+ 'help-for-help'.
+ (help--key-description-fontified): New function to add the
+ 'help-key-binding' face.
+ (help-key-description, substitute-command-keys)
+ (describe-map-tree, help--describe-command)
+ (help--describe-translation, describe-map):
+ * lisp/help-fns.el (help-fns--key-bindings, describe-mode):
+ Use above new function.
+ * lisp/isearch.el (isearch-help-for-help-internal): Use
+ `substitute-command-keys' syntax.
+ * lisp/help-macro.el (make-help-screen): Use
+ 'substitute-command-keys' and 'help--key-description-fontified'.
+ Simplify.
+ * src/keymap.c (describe_key_maybe_fontify): New function to add
+ the 'help-key-binding' face to keybindings.
+ (describe_vector): Use above new keybinding.
+ (syms_of_keymap) <Qfont_lock_face, Qhelp_key_binding>: New
+ DEFSYMs.
+ (fontify_key_properties): New static variable.
+ * lisp/tooltip.el (tooltip-show): Avoid overriding faces in
+ specified tooltip text.
+ * test/lisp/help-tests.el (with-substitute-command-keys-test):
+ Don't test for text properties.
+ (help-tests-substitute-command-keys/add-key-face)
+ (help-tests-substitute-command-keys/add-key-face-listing):
+ New tests.
+
+2021-03-08 Dmitry Gutov <dgutov@yandex.ru>
+
+ Speed up xref rendering for matches on very long lines
+
+ * lisp/progmodes/xref.el (xref--insert-xrefs): Cut up the current
+ line into pieces here for multiple matches's summaries, so that
+ xref--insert-xrefs can do less work (bug#46859).
+ (xref--insert-xrefs): Do less work.
+ (xref--outdated-p):
+ Update accordingly to how the summary creation logic changed.
+ (xref--buf-pairs-iterator): Update to the new calling convention.
+ (xref-location-column): Effectively rename back to
+ xref-file-location-column since the generic version is now unused.
+
+ * test/lisp/progmodes/xref-tests.el
+ (xref-matches-in-directory-finds-two-matches-on-the-same-line)
+ (xref-matches-in-directory-finds-an-empty-line-regexp-match):
+ Adjust to the xref-location-column change.
+ (xref-matches-in-files-trims-summary-for-matches-on-same-line):
+ New test.
+
+ * test/lisp/progmodes/xref-resources/file1.txt:
+ Change contents slightly to test the new xref--outdated-p code.
+
+2021-03-08 Dmitry Gutov <dgutov@yandex.ru>
+
+ Xref test improvements
+
+ * test/lisp/progmodes/xref-tests.el
+ (xref--xref-file-name-display-is-abs):
+ Fix not to rely on the default value.
+ (xref-matches-in-files-includes-matches-from-all-the-files):
+ New test.
+
+2021-03-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/net/tramp-cache.el: Fix misuse of bound-and-true-p
+
+ (tramp-get-file-property, tramp-set-file-property): Check the var's
+ value rather than its name.
+
+2021-03-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/net/ange-ftp.el: Fix problem pointed out by compiler warning
+
+ (ange-ftp-fix-name-for-bs2000): Remove redundant `boundp` test.
+
+2021-03-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/erc/erc.el: Fix problem pointed out by compiler warning
+
+ [ Also use `read-string` instead of `read-from-minibuffer`. ]
+
+ (erc-part-from-channel): Comment out improbable
+ reference to the formal argument from within the interactive spec.
+
+2021-03-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet/semantic/fw.el (semantic-find-file-noselect): Fix warning
+
+ Remove ugly hack trying to warn the user about some unknown problem,
+ and which stopped working in 2013 when files.el started using
+ lexical-binding.
+
+2021-03-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/skeleton.el (skeleton-read): Silence compiler warning
+
+2021-03-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet/semantic/bovine.el: Fix recent regression
+
+ The conversion to `lexical-binding` introduced a regression because
+ `bovine/c.el` relied on inspecting the local variable `lse` in one of
+ its callers.
+
+ (semantic-bovinate-stream): Bind `lse` dynamically, because of
+ `semantic-parse-region-c-mode`.
+ (semantic-bovinate-nonterminal-check-map): Rename from
+ `semantic-bovinate-nonterminal-check-obarray` to hold some other kind
+ of table.
+ (semantic-bovinate-nonterminal-check): Use a hash-table instead of an obarray.
+
+ * lisp/cedet/semantic/bovine/c.el (semantic-parse-region-c-mode):
+ Declare use of `lse` via dynamic scoping.
+
+ * test/lisp/cedet/semantic-utest-c.el
+ (semantic-test-c-preprocessor-simulation): Re-enable test.
+
+2021-03-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/bytecomp.el: Warn about unprefixed vars in `boundp`
+
+ (byte-compile--check-prefixed-var): New fun,
+ extracted from `byte-compile--declare-var`.
+ (byte-compile--declare-var): Use it.
+ (byte-compile-maybe-guarded): Use it as well.
+
+2021-03-07 Andrea Corallo <akrl@sdf.org>
+
+ Handle `comp-native-driver-options' both as file-local both as global
+
+ * src/comp.c (add_driver_options): Throw an error if
+ `comp-native-driver-options' is set globally but
+ 'gcc_jit_context_add_driver_option' is not available, ignore for
+ the file-local case.
+
+2021-03-07 Andrea Corallo <akrl@sdf.org>
+
+ Use `length=' and family where possible in native comp code
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-intersect-typesets)
+ (comp-cstr-imm): Use Use `length=' and family where possible.
+ * lisp/emacs-lisp/comp.el (comp-add-cond-cstrs-target-block)
+ (comp-compute-dominator-frontiers)
+ (batch-byte-native-compile-for-bootstrap): Likewise.
+
+2021-03-07 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (w32-get-nproc): Suppress warning declaring it.
+
+ For non Windows system.
+
+2021-03-07 Andrea Corallo <akrl@sdf.org>
+
+ Allow for `comp-native-driver-options' to work as a file-local variable.
+
+2021-03-07 Juri Linkov <juri@linkov.net>
+
+ Remove outline-cycle-minor-mode and outline-cycle-highlight-minor-mode
+
+ * lisp/outline.el (outline-font-lock-keywords): Use OVERRIDE or
+ LAXMATCH depending on outline-minor-mode-highlight in outline-minor-mode.
+ (outline-minor-mode-cycle, outline-minor-mode-highlight): Promote
+ defvar to defcustom.
+ (outline-minor-mode-highlight-buffer): Don't override existing faces.
+ (outline-cycle-minor-mode, outline-cycle-highlight-minor-mode):
+ Remove minor modes.
+
+ * etc/compilation.txt:
+ * etc/grep.txt: Enable outline-minor-mode-cycle and
+ outline-minor-mode-highlight with outline-minor-mode.
+ https://lists.gnu.org/archive/html/emacs-devel/2021-03/msg00144.html
+
+2021-03-07 Andrea Corallo <akrl@sdf.org>
+
+ Work around GCC PR99126 on all libgccjit < 11
+
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Work around GCC
+ PR99126 on all libgccjit < 11.
+
+2021-03-07 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/infra/Dockerfile.emba: Install texinfo.
+
+2021-03-07 Glenn Morris <rgm@gnu.org>
+
+ Tag a semantic test that seems to hang recently
+
+ * test/lisp/cedet/semantic-utest-c.el
+ (semantic-test-c-preprocessor-simulation): Mark as unstable.
+
+2021-03-07 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix string-replace error data
+
+ * lisp/subr.el (string-replace): Signal an error with data that is a
+ list, and whose contents are consistent with other uses of
+ wrong-length-argument.
+ * test/lisp/subr-tests.el (string-replace): Test for this.
+ (subr-test-define-prefix-command): Pacify byte-compiler warnings.
+
+2021-03-07 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid aborts in native-comp subprocesses when exiting Emacs on Windows
+
+ * src/w32.c (shutdown_handler): Clear the message stack when being
+ shut down in noninteractive mode, to avoid aborting in
+ shut_down_emacs when a native-compilation subprocess is killed
+ because the parent Emacs exits.
+
+2021-03-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix encoding of file names in comp.c
+
+ * src/comp.c (Fcomp__compile_ctxt_to_file) [WINDOWSNT]: Fix
+ encoding of file names passed to libgccjit.
+
+2021-03-07 Eli Zaretskii <eliz@gnu.org>
+
+ Use MS-Windows system APIs to get number of processors
+
+ * lisp/emacs-lisp/comp.el: Use 'w32-get-nproc' instead of the
+ environment variable NUMBER_OF_PROCESSORS.
+
+ * src/w32proc.c (Fw32_get_nproc): New primitive.
+ * src/w32.c (w32_get_nproc): New function.
+ (sample_system_load): Call w32_get_nproc to initialize the number
+ of processors on this system.
+ * src/w32.h (w32_get_nproc): Add prototype.
+
+2021-03-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix libgccjit PROGNAME on MS-Windows
+
+ * src/comp.c [WINDOWSNT]: Import gcc_jit_context_set_str_option.
+ (init_gccjit_functions): Load gcc_jit_context_set_str_option.
+ (gcc_jit_context_set_str_option) [WINDOWSNT]: New macro.
+ (Fcomp__compile_ctxt_to_file) [WINDOWSNT]: Pass the actual name of
+ the libgccjit DLL to the library, to be used as PROGNAME.
+
+2021-03-07 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/infra/Dockerfile.emba: Touch "info/emacs".
+
+2021-03-07 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt Dockerfile.emba according to recent configure changes
+
+ * test/infra/Dockerfile.emba: Remove "--without-makeinfo" from
+ configure. Add "lisp" to make.
+
+2021-03-07 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet/semantic/wisent: Use lexical-binding
+
+ * lisp/cedet/semantic/wisent/comp.el: lexical-binding.
+ (wisent-defcontext): Make sure the vars are also dynbound in the files
+ that `require` us.
+ (wisent-state-actions, wisent-automaton-lisp-form): Use `obarray-make`.
+ (wisent--compile-grammar): Rename from `wisent-compile-grammar`.
+ (wisent-compile-grammar): Redefine as an obsolete function.
+ (wisent-automaton-lisp-form): Avoid variable `state`.
+
+ * lisp/cedet/semantic/grammar.el: Use lexical-binding.
+ (semantic-grammar-require-form): New var.
+ (semantic-grammar-header): Use it to provide new element `require-form`.
+ (semantic-grammar-header-template): Use it.
+
+ * lisp/cedet/semantic/wisent.el (wisent-compiled-grammar): New macro.
+
+ * lisp/cedet/semantic/wisent/grammar.el (wisent-grammar-parsetable-builder):
+ Use it in the generated code instead of the `wisent-compile-grammar` function.
+ (wisent-grammar-mode): Set `semantic-grammar-require-form` so
+ the generated ELisp files require `semantic/wisent` rather than
+ `semantic/bovine`.
+
+ * lisp/cedet/semantic/wisent/wisent.el: Use lexical-binding.
+ * lisp/cedet/semantic/wisent/java-tags.el: Use lexical-binding.
+ * lisp/cedet/semantic/wisent/python.el: Use lexical-binding.
+ * lisp/cedet/semantic/wisent/javascript.el: Use lexical-binding.
+ (semantic-ctxt-current-symbol): Remove unused var `symlist`.
+
+ * admin/grammars/python.wy (wisent-python-EXPANDING-block):
+ Declare dynbound var.
+
+ * lisp/cedet/semantic/grammar-wy.el: Regenerate.
+
+2021-03-07 Stefan Kangas <stefan@marxist.se>
+
+ Remove additional items obsolete since Emacs 22/23
+
+ * lisp/speedbar.el (speedbar-update-speed)
+ (speedbar-navigating-speed): Remove variables obsolete since Emacs 23.
+ (speedbar-dir-follow, speedbar-directory-buttons-follow): Don't use
+ above removed variables.
+
+ * lisp/erc/erc.el (erc-announced-server-name, erc-process)
+ (erc-default-coding-system, erc-send-command): Remove variables and
+ functions obsolete since Emacs 22.
+
+2021-03-07 Stefan Kangas <stefan@marxist.se>
+
+ Remove some items obsolete since Emacs 22/23 from Gnus
+
+ * lisp/gnus/gnus-art.el (gnus-article-hide-pgp-hook)
+ (gnus-treat-strip-pgp, gnus-treat-display-xface):
+ * lisp/gnus/gnus-msg.el (gnus-inews-mark-gcc-as-read):
+ * lisp/gnus/gnus-start.el (nnmail-spool-file):
+ * lisp/gnus/nnmail.el (nnmail-spool-file)
+ (nnmail-fix-eudora-headers): Remove items obsolete since 22.1.
+ * lisp/gnus/gnus-art.el (gnus-treat-display-x-face):
+ * lisp/gnus/gnus-msg.el (gnus-inews-do-gcc): Don't use above obsolete symbols.
+ * doc/misc/gnus.texi (Washing Mail, Not Reading Mail): Don't refer to
+ above obsolete variables.
+
+ * lisp/gnus/gnus.el (gnus-local-domain, gnus-carpal):
+ * lisp/gnus/nnimap.el (nnimap-split-rule):
+ * lisp/gnus/nntp.el (nntp-authinfo-file): Fix obsolete variable
+ version format.
+
+2021-03-07 Stefan Kangas <stefan@marxist.se>
+
+ Remove some references to Emacs 21
+
+ * lisp/erc/erc-track.el (erc-track-position-in-mode-line):
+ * lisp/erc/erc.el (erc-header-line-format):
+ * lisp/ibuffer.el (ibuffer-mode):
+ * lisp/ruler-mode.el: Remove some references to Emacs 21.
+
+2021-03-07 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/mouse-drag.el: Use lexical-binding.
+
+ * lisp/mouse-copy.el: Use lexical-binding.
+
+2021-03-07 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet/semantic/bovine/*.el: Use lexical-binding
+
+ * lisp/cedet/semantic/bovine/c.el: Use lexical-binding.
+ (semantic-lex-cpp-define): Remove unused var `name`.
+ (semantic-c-do-lex-if): Remove unused var `pt`.
+ (semantic-analyze-tag-references): Remove unused var `refs`.
+ (semantic-c-dereference-namespace): Remove unused vars `tmp` and
+ `usingname`.
+ (semantic-c-dereference-namespace-alias): Remove unused var `newtype`.
+ (semantic-c-check-type-namespace-using): Remove unused vars `tmp` and
+ `shortname`.
+ (semanticdb-find-table-for-include): Remove unused var `prefix`.
+ (semantic-default-c-setup, semantic-c-describe-environment):
+ Use `derived-mode-p`.
+
+ * lisp/cedet/semantic/bovine/debug.el: Use lexical-binding.
+
+ * lisp/cedet/semantic/bovine/make.el: Use lexical-binding.
+
+ * lisp/cedet/semantic/bovine/scm.el: Use lexical-binding.
+
+ * lisp/cedet/semantic/lex.el (define-lex-analyzer): Define the var (and
+ the function) in a single step.
+
+2021-03-07 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/obsolete/inversion.el: Use lexical-binding
+
+2021-03-07 Glenn Morris <rgm@gnu.org>
+
+ * admin/admin.el (make-manuals-dist-output-variables): Update.
+
+2021-03-07 Glenn Morris <rgm@gnu.org>
+
+ Simplify silent-rules build machinery
+
+ * src/verbose.mk.in: New file.
+ * configure.ac (AM_V, AM_DEFAULT_V): Remove output variables.
+ (src/verbose.mk): New output file.
+ * Makefile.in, admin/charsets/Makefile.in:
+ * admin/grammars/Makefile.in, admin/unidata/Makefile.in:
+ * doc/emacs/Makefile.in, doc/lispintro/Makefile.in:
+ * doc/lispref/Makefile.in, doc/misc/Makefile.in, leim/Makefile.in:
+ * lib-src/Makefile.in, lib/Makefile.in, lisp/Makefile.in:
+ * lwlib/Makefile.in, nt/Makefile.in, oldXMenu/Makefile.in:
+ * src/Makefile.in, src/verbose.mk.in, test/Makefile.in:
+ Include src/verbose.mk rather than repeatedly defining AM_V_at etc.
+
+2021-03-06 Andrea Corallo <akrl@sdf.org>
+
+ Fix `comp-cstr-intersection-no-hashcons' for negated result cstr
+
+ * lisp/emacs-lisp/comp-cstr.el
+ (comp-cstr-intersection-no-hashcons): When negated and
+ necessary relax dst to t.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add a test.
+
+2021-03-06 Pip Cet <pipcet@gmail.com>
+
+ Fix miscompilation of funcall forms in some cases (bug#46974)
+
+ * lisp/emacs-lisp/comp.el (comp-call-optim-func): Call
+ comp-cstr-imm-vld-p before relying on comp-cstr-imm to return the
+ right value.
+
+2021-03-06 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-add-cond-cstrs-simple): Suppress warning.
+
+2021-03-06 Andrea Corallo <akrl@sdf.org>
+
+ Fix `=' propagation to handle -0.0 0.0 case
+
+ * lisp/emacs-lisp/comp-cstr.el
+ (comp-cstr-intersection-homogeneous): Fix indent + use `memql'.
+ (comp-cstr-=): Handle 0.0 -0.0 idiosyncrasy
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add two
+ tests and fix enumeration.
+
+2021-03-06 Glenn Morris <rgm@gnu.org>
+
+ * src/Makefile.in (base_obj): Remove GMP_OBJ, undefined since 202007.
+
+2021-03-06 Glenn Morris <rgm@gnu.org>
+
+ Don't pass implicit flags to sub-makes
+
+ * Makefile.in (info_misc, uninstall, texi_misc):
+ Don't pass any implicit make flags to sub-makes.
+ Ref https://lists.gnu.org/r/help-make/2021-03/msg00007.html
+
+2021-03-06 Glenn Morris <rgm@gnu.org>
+
+ Remove the --without-makeinfo configure option (bug#46837)
+
+ * configure.ac (--without-makeinfo): Remove option.
+ (HAVE_MAKEINFO): Remove output variable.
+
+ * Makefile.in (HAVE_MAKEINFO): Remove.
+ (info_misc): Remove HAVE_MAKEINFO check.
+ (info-real): Remove target.
+ (info): Simplify.
+
+2021-03-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet/srecode/compile.el: Fix last change
+
+ (srecode-compile-inserter): Call `make-instance` properly.
+
+2021-03-06 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Speed up json.el encoding
+
+ This replaces most json-encode-* functions with similar
+ json--print-* counterparts that insert into the current buffer
+ instead of returning a string (bug#46761).
+
+ Some unused but useful json-encode-* functions are kept for backward
+ compatibility and as a public API, and the rest are deprecated.
+
+ * etc/NEWS: Announce obsoletions.
+
+ * lisp/json.el: Document organization of library. Make subsection
+ headings more consistent.
+ (json--encoding-current-indentation): Rename...
+ (json--print-indentation-prefix): ...to this, to reflect new use.
+ (json--encode-stringlike, json--encode-alist): Rename...
+ (json--print-stringlike, json--print-alist): ...to these,
+ respectively, and encode argument into current buffer instead. All
+ callers changed.
+
+ (json--print-string, json--print-unordered-map, json--print-array)
+ (json--print): New functions.
+ (json-encode-string, json-encode-plist, json-encode-array)
+ (json-encode): Use them, respectively.
+
+ (json-encode-number, json-encode-hash-table): Mark as obsolete
+ aliases of json-encode.
+ (json-encode-key, json-encode-list): Mark as obsolete in preference
+ for json-encode.
+
+ (json--print-indentation-depth, json--print-keyval-separator): New
+ variables.
+ (json--with-output-to-string): New macro.
+ (json--print-indentation, json--print-keyword, json--print-key)
+ (json--print-pair, json--print-map, json--print-list): New
+ functions.
+
+ (json--with-indentation): Use json--print-indentation-depth to avoid
+ unnecessary string allocation.
+ (json-encoding-default-indentation, json-pretty-print-max-secs):
+ Clarify docstrings.
+ (json--escape, json--long-string-threshold, json--string-buffer):
+ Remove; no longer used.
+
+ * lisp/progmodes/js.el (js--js-encode-value): Replace
+ json-encode-string and json-encode-number with json-encode.
+ (js-eval-defun): Use json--print-list to avoid
+ json-encode-list->insert roundtrip.
+
+ * test/lisp/json-tests.el (test-json-encode-number)
+ (test-json-encode-hash-table, test-json-encode-hash-table-pretty)
+ (test-json-encode-hash-table-lisp-style)
+ (test-json-encode-hash-table-sort, test-json-encode-list): Replace
+ uses of obsolete functions with the equivalent use of json-encode.
+ (test-json-encode-key): Suppress obsoletion warnings.
+ (test-json-encode-string): Check that text properties are stripped.
+
+2021-03-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/bindat.el (bindat-struct): Fix Edebug def
+
+2021-03-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emulation/: Use lexical-binding
+
+ * lisp/emulation/cua-base.el: Use lexical-binding.
+ Remove redundant `:group` arguments.
+ (cua-mode): Don't use `:require` since the autoload on `define-minor-mode`
+ takes care of loading the mode when custom-setting it.
+
+ * lisp/emulation/cua-gmrk.el: Use lexical-binding.
+ (cua--copy-rectangle-to-global-mark): Remove unused var `src-buf`.
+
+ * lisp/emulation/edt-mapper.el: Use lexical-binding.
+
+ * lisp/emulation/edt.el: Use lexical-binding.
+ Remove redundant `:group` arguments.
+ (edt-with-position): Allow `top`, `left`, and `far` to be left unused
+ in `body`.
+
+ * lisp/emulation/keypad.el: Use lexical-binding.
+
+ * lisp/emulation/viper-cmd.el: Move `provide` to the end.
+ (viper-read-string-with-history): Strength reduce `eval` to `symbol-value`.
+
+ * lisp/emulation/viper-ex.el: Use lexical-binding.
+ Remove redundant `:group` arguments.
+ Move `provide` to the end.
+
+ * lisp/emulation/viper-init.el: Use lexical-binding.
+
+ * lisp/emulation/viper-keym.el (viper-toggle-key): Use `dolist`.
+ (viper-insert-diehard-map): Use `string`.
+ (viper-modify-major-mode): Use `alist-get` and `setf`.
+
+ * lisp/emulation/viper-macs.el (viper-ex-work-buf):
+ Move `provide` to the end.
+ (viper-record-kbd-macro): Strength reduce `eval` to `symbol-value`.
+ (viper-describe-kbd-macros): Return value is not significant.
+ (viper-keyseq-is-a-possible-macro): Use `seq-some`.
+ (viper-common-seq-prefix): Use `seq-every-p`.
+
+ * lisp/emulation/viper-mous.el: Use lexical-binding.
+ Remove redundant `:group` arguments.
+ Move `provide` to the end.
+ (viper-remember-current-frame): Accept arbitrary ignored args.
+ (viper-parse-mouse-key): Strength reduce `eval` to `symbol-value`.
+ Remove unused var `key-spec`.
+ (viper-bind-mouse-search-key, viper-bind-mouse-insert-key):
+ Apply de Morgan.
+
+ * lisp/emulation/viper-util.el: Move `provide` to the end.
+ (viper-move-marker-locally, viper-push-onto-ring, viper-save-setting):
+ Strength reduce `eval` to `symbol-value`.
+ (viper-event-vector-p, viper-char-symbol-sequence-p, viper-char-array-p):
+ Use `seq-every-p`.
+
+ * lisp/emulation/viper.el (viper-non-hook-settings): Eta-reduce use of
+ `viper-remember-current-frame`.
+
+2021-03-06 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Various map.el improvements
+
+ * lisp/emacs-lisp/seq.el (seq-do-indexed): Return nil as per doc.
+
+ * lisp/emacs-lisp/map.el: Require Emacs >= 26 due to dependence on
+ 5-arg alist-get. Bump package to version 3.0. Fix other
+ headers. (Bug#46754)
+ (map--plist-p): Detect list starting with nil as plist, not alist.
+ (map-elt, map-filter, map-apply, map--make-pcase-bindings)
+ (map--make-pcase-patterns): Simplify.
+ (map-let, map-put, map-nested-elt, mapp): Update docstring for plist
+ support.
+ (map-delete): Fix OBOE on arrays. Split into cl-defmethods.
+ (map-values, map-values-apply): Specialize for arrays.
+ (map-pairs, map-keys-apply, map-put!): Improve docstring.
+ (map-length): Clarify docstring w.r.t. duplicate keys. Split into
+ cl-defmethods. Optimize default implementation.
+ (map-copy): Use copy-alist on alists. Split into cl-defmethods.
+ (map-contains-key): Add plist support. Clarify docstring
+ w.r.t. optional argument. Simplify default implementation.
+ (map-some, map-every-p, map-merge, map-merge-with, map--into-hash):
+ Don't use map-apply for side effects.
+ (map-into): Preserve plist ordering. Improve docstrings.
+ (map-insert): Add hash-table and array support.
+ (map-inplace): Remove unused error symbol.
+ (map-do): Return nil as per doc.
+
+ * etc/NEWS: Announce new user-visible behavior.
+
+ * test/lisp/emacs-lisp/map-tests.el: Prefer should-not
+ over (should (not ...)) in general.
+ (with-maps-do): Fix docstring.
+ (with-empty-maps-do): New macro.
+ (test-map-elt-default, test-mapp, test-map-keys, test-map-values)
+ (test-map-pairs, test-map-length, test-map-copy, test-map-apply)
+ (test-map-do, test-map-keys-apply, test-map-values-apply)
+ (test-map-filter, test-map-remove, test-map-empty-p)
+ (test-map-contains-key, test-map-some, test-map-every-p):
+ Use it.
+
+ (test-map-plist-p, test-map-put!-new-keys, test-map-insert-empty)
+ (test-map-insert, test-map-delete-empty, test-map-copy-alist)
+ (test-map-contains-key-testfn, test-map-into-hash-test)
+ (test-map-into-empty, test-map-merge, test-map-merge-empty):
+ New tests.
+
+ (test-map-elt): Test array key that is within bounds but not fixnum.
+ (test-map-put!): Use map--plist-p. Remove redundant tests.
+ (test-map-put-alist-new-key): Don't modify list literal.
+ (test-map-put-testfn-alist, test-map-put-return-value): Silence
+ obsoletion warnings.
+ (test-map-delete): Check for OBOE on arrays.
+ (test-map-delete-return-value): Remove test made redundant by
+ test-map-delete.
+ (test-map-nested-elt, test-map-into): Test plists too.
+
+2021-03-06 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Fix calculation of c-parse-state when there're macros with braces
+
+ This fixes bug #46951.
+
+ * lisp/progmodes/cc-engine.el (c-append-lower-brace-pair-to-state-cache):
+ Ensure the starting point for backward scanning is not within a macro which
+ doesn't contain HERE.
+
+2021-03-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/flymake.el (flymake-log): Push the right code
+
+ * lisp/progmodes/flymake.el (flymake-log): Simplify
+
+2021-03-06 Eli Zaretskii <eliz@gnu.org>
+
+ Revert "Fix Makefile subshell output when run in parallel"
+
+ This reverts commit 117505454ce04c0c0ce2c2b4058823cf764fc2eb.
+ It breaks the build for versions of GNU Make that don't support -O.
+
+2021-03-06 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix Makefile subshell output when run in parallel
+
+ For discussion, see the following thread:
+ https://lists.gnu.org/r/emacs-devel/2021-03/msg00255.html
+
+ * Makefile.in (texi_misc): Avoid interspersing parallel Make output
+ with that from subshell.
+
+2021-03-06 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Pacify some semantic-tag-make-plist warnings
+
+ * lisp/cedet/semantic/tag.el (semantic-tag-make-plist): Define
+ before its first use to pacify some recent "may not be defined at
+ runtime" warnings after turning on lexical-binding.
+
+2021-03-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove mention of using defun- and defvar- as prefixes
+
+ * doc/lispref/tips.texi (Coding Conventions): Remove mention of
+ using defun- and defvar- as prefixes, as this is something that we
+ rarely do in Emacs (bug#46899).
+
+2021-03-06 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of Bindat
+
+ * doc/lispref/processes.texi (Bindat Types, Bindat Functions)
+ (Bindat Computed Types): Improve wording and add indexing.
+
+ * etc/NEWS: Add a pointer to the ELisp manual for "Bindat".
+
+2021-03-06 Protesilaos Stavrou <info@protesilaos.com>
+
+ Pull Modus themes version 1.2.3 from upstream
+
+ This syncs with the following upstream revision:
+
+ Update to version 1.2.3
+ 0a36239 2021-03-05 19:43:30 +0200
+ https://gitlab.com/protesilaos/modus-themes/-/commit/0a36239baf908585cdf32c6188eb86713d9bf6c6
+
+ For discussion, see bug#45068 and the following upstream issue:
+ https://gitlab.com/protesilaos/modus-themes/-/issues/162
+
+ * doc/misc/modus-themes.org:
+ * etc/themes/modus-operandi-theme.el:
+ * etc/themes/modus-themes.el:
+ * etc/themes/modus-vivendi-theme.el: Update to version 1.2.3.
+
+2021-03-06 Protesilaos Stavrou <info@protesilaos.com>
+
+ Update Modus themes to their version 1.2.0
+
+ * doc/misc/modus-themes.org: Add new version of the manual, with
+ changes to markup and references to the latest state of the project.
+
+ * etc/themes/modus-vivendi-theme.el:
+ * etc/themes/modus-operandi-theme.el: Provide updated version of each
+ theme, which expands the contents of 'modus-themes.el' (bug#45068).
+
+ * etc/themes/modus-themes.el: Add new supportive file. This is where
+ theme data, functions, and face definitions are defined.
+
+2021-03-06 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Conditionally use macroexp-file-name in Flymake
+
+ * lisp/progmodes/flymake.el (flymake-log): Reinstate Emacs 26
+ support by conditionally using macroexp-file-name which is new in
+ Emacs 28 (bug#46957).
+
+2021-03-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * * lisp/cedet/semantic: Use lexical-binding in the generated grammars
+
+ * admin/grammars/c.by (typesimple): Bind `semantic-c-classname` dynamically.
+
+ * lisp/cedet/semantic/bovine.el: Use lexical-binding.
+ (semantic-lambda): Silence warnings if the `vals` arg is not used.
+
+ * lisp/cedet/semantic/grammar-wy.el: Re-generate.
+
+ * lisp/cedet/semantic/bovine/grammar.el: Use lexical-binding.
+ (bovine-grammar-expand-action): Silence warnings if some of the
+ `vals`, `start`, or `end` args is not used.
+ (bovine--make-parser-1): Use lexical-binding in the generated files.
+
+ * lisp/cedet/semantic/wisent/grammar.el: Use lexical-binding.
+ (wisent--make-parser-1): Use lexical-binding in the generated files.
+
+2021-03-06 Stefan Kangas <stefan@marxist.se>
+
+ Add some new tests for keymap.c
+
+ * test/src/keymap-tests.el (keymap-define-key/undefined)
+ (keymap-define-key/keyboard-macro, keymap-define-key/lambda)
+ (keymap-define-key/keymap, keymap-define-key/menu-item)
+ (keymap-lookup-key/list-of-keymaps, keymap-lookup-key/too-long):
+ New tests.
+ (keymap-lookup-key): Extend test slightly.
+
+2021-03-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet/srecode/*.el: Use lexical-binding
+
+ * lisp/cedet/srecode/compile.el (srecode-compile-inserter):
+ Use `make-instance` instead of the class name-as-function.
+
+ * lisp/cedet/srecode/fields.el (srecode-field-behind-hook):
+ Remove unused var `field`.
+
+ * lisp/cedet/srecode/find.el (srecode-load-tables-for-mode): Simplify.
+
+ * lisp/cedet/srecode/getset.el (srecode-semantic-selected-tag): Declare var.
+
+ * lisp/cedet/srecode/mode.el (srecode-minor-mode): Mark references to
+ non-existing `srecode-m3-items` function.
+
+ * lisp/cedet/srecode/srt-mode.el (srecode-parse-this-macro): Remove
+ unused var `raw`.
+
+2021-03-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Bindat: new macro-expansion based data layout language
+
+ Thorough redesign of the Bindat system, which makes it possible
+ to define new Bindat type forms, define recursive types, control
+ the values returned when unpacking, freely mix arbitrary computations
+ with type definitions, as well as support for arbitrary sized
+ integers.
+
+ This also reverts the recent addition of the `bindat-spec` macro and
+ the support for 64bit integers in the old Bindat language since that
+ is now considered obsolete anyway.
+
+ * doc/lispref/processes.texi (Bindat Types): Rename from `Bindat Spec`
+ and rewrite for the new sublanguage.
+ (Bindat Functions): Adjust to the new terminology.
+ (Bindat Computed Types): New node.
+
+ * lisp/emacs-lisp/bindat.el (bindat--type): New type.
+ (bindat--unpack-u64, bindat--unpack-u64r): Delete functions.
+ (bindat--unpack-item, bindat--pack-item, bindat--fixed-length-alist):
+ Revert addition of support for 64bit integers.
+ (bindat--unpack-group, bindat--length-group, bindat--pack-group):
+ Handle the new `bindat--type` values.
+ (bindat-spec): Revert addition of this macro.
+ (bindat--unpack-uint, bindat--unpack-uintr, bindat--pack-uint)
+ (bindat--pack-uintr): New functions.
+ (bindat-type, bindat-defmacro, bindat--pcase): New macros.
+ (bindat-type): New Edebug elem.
+ (bindat--type): New generic function.
+ (bindat--primitives): New constant.
+ (bindat--macroenv, bindat--op): New vars.
+ (bindat--make-docstring, bindat--fun, bindat--makefun, bindat--toplevel):
+ New functions.
+
+ * test/lisp/emacs-lisp/bindat-tests.el: Use `bindat-type`.
+ (ip): New Bindat type.
+ (header-bindat-spec, data-bindat-spec, packet-bindat-spec): Adjust to
+ new `bindat-type` macro.
+ (bindat-test-unpack): Simplify now that the order of fields is preserved.
+ (bindat-test--int-websocket-type, bindat-test--LEB128): New consts.
+ (bindat-test--pack-val, bindat-test--sint, bindat-test--recursive):
+ New tests.
+
+2021-03-05 Mattias Engdegård <mattiase@acm.org>
+
+ Make lambda-lifting work again
+
+ * lisp/emacs-lisp/cconv.el (cconv--analyze-use): Fix typo.
+ * test/lisp/emacs-lisp/cconv-tests.el (cconv-convert-lambda-lifted):
+ Add test case.
+
+2021-03-05 Tassilo Horn <tsdh@gnu.org>
+
+ Improve rcirc-authenticated-hook docstring
+
+ * lisp/net/rcirc.el (rcirc-authenticated-hook): Improve docstring.
+
+2021-03-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/bindat.el: Minor refactoring
+
+ (bindat--unpack-str, bindat--unpack-strz, bindat--unpack-bits):
+ New functions, extracted from `bindat--unpack-item`.
+ (bindat--unpack-item): Use them.
+ (bindat--align): New function.
+ (bindat--unpack-group, bindat--length-group, bindat--pack-group): Use it.
+ (bindat-get-field): Allow integers to index both lists (as returned by
+ `repeat`) and vectors (as returned by `vec`).
+ (bindat--pack-str, bindat--pack-bits): New functions, extracted from
+ `bindat--pack-item`.
+ (bindat--pack-item): Use them.
+
+ * test/lisp/emacs-lisp/bindat-tests.el (struct-bindat): Place the fields
+ in the order in which they appear in the structs.
+
+2021-03-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/gv.el (edebug-after): Don't run the getter in the setter
+
+ This fixes bug#46573 which was introduced by commit
+ d79cf638f278e50c22feb53d6ba556f5ce9d7853.
+ The new code is a middle ground, which makes sure the instrumentation
+ point is used (so the coverage checker won't have ghost unreachable
+ instrumentation points) yet without artificially running the getter
+ when we only need to run the setter.
+
+2021-03-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/fns.c (Frandom): Handle bignum `limit`s
+
+ (ccall2, get_random_bignum): New functions.
+
+2021-03-05 Michael Albinus <michael.albinus@gmx.de>
+
+ Declare some completion predicates
+
+ * lisp/filenotify.el (file-notify-handle-event):
+ * lisp/net/dbus.el (dbus-handle-event): Declare `completion-predicate'.
+
+2021-03-05 Masahiro Nakamura <tsuucat@icloud.com>
+
+ * doc/misc/tramp.texi (Remote shell setup): Fix reference.
+
+ * doc/misc/tramp.texi (Remote shell setup): Fix reference. (Do not merge)
+
+2021-03-05 Eli Zaretskii <eliz@gnu.org>
+
+ Fix some unsafe uses of SSDATA in comp.c
+
+ * src/comp.c (comp_hash_source_file)
+ (Fcomp__compile_ctxt_to_file, Fnative_elisp_load): Encode file
+ names before passing them to library APIs.
+ (Fcomp__compile_ctxt_to_file): use emacs_fopen instead of fopen.
+ (declare_lex_function): Avoid keeping a 'char *' pointer around
+ while calling Lisp, which could trigger GC, which could relocate
+ string data.
+
+2021-03-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the documentation of :extra in cl-defmethod
+
+ * doc/lispref/functions.texi (Generic Functions): Improve
+ documentation of :extra (bug#46917).
+
+ * lisp/emacs-lisp/cl-generic.el (cl-defmethod): Ditto.
+
+2021-03-05 Mauro Aranda <maurooaranda@gmail.com>
+
+ Fix qualifiers order for loadhist-unload-element in elp.el
+
+ * lisp/emacs-lisp/elp.el (loadhist-unload-element): The :extra
+ qualifier is expected to come before the other qualifiers, so do
+ that (bug#46917).
+
+2021-03-05 Stephen Berman <stephen.berman@gmx.net>
+
+ Restrict the version guesser to top-level headings
+
+ * lisp/help-fns.el (help-fns--first-release): Restrict the version
+ guesser to top-level section -- looking in all headings leads to
+ false positives (bug#46889).
+
+2021-03-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Actually fill the correct paragraph in `lisp-fill-paragraph'
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-fill-paragraph): Fix previous
+ change here by actually filling the correct paragraph (bug#28937).
+
+2021-03-05 Eli Zaretskii <eliz@gnu.org>
+
+ Fix initialization of 'while-no-input-ignore-events'
+
+ * src/keyboard.c (syms_of_keyboard_for_pdumper): Don't reset
+ 'while-no-input-ignore-events' after loading the dump file.
+ (Bug#46940)
+
+2021-03-05 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Don't override load-path in require-theme
+
+ * lisp/custom.el (require-theme): Open-code 'require' error, because
+ binding load-path can prevent other libraries from loading on error,
+ such as debug.el, which gives a misleading error. (Bug#45068)
+
+2021-03-05 Andrea Corallo <akrl@sdf.org>
+
+ Harden `comp-abi-hash' computation
+
+ Account for subr arity in `comp-abi-hash' computation as that's part
+ of the ABI exposed to .eln files.
+
+ * src/comp.c (Fcomp__subr_signature): New support function.
+ (hash_native_abi): Make use of.
+ (syms_of_comp): Register 'Scomp__subr_signature'.
+
+2021-03-05 Pip Cet <pipcet@gmail.com>
+
+ Don't ignore lexically-bound variables in a defvar (bug#46912)
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Walk
+ the value form of a defvar.
+
+2021-03-05 Glenn Morris <rgm@gnu.org>
+
+ * Makefile.in: Ensure non-info forms of doc/misc have an Emacs binary.
+
+2021-03-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-generic.el: Make `doc-string` prop work with qualifiers
+
+ (cl--defmethod-doc-pos): New function.
+ (cl-defmethod): Use it.
+
+2021-03-04 Andrea Corallo <akrl@sdf.org>
+
+ Makefile.in (ELN_DESTDIR): Remove unnecessary double quoting.
+
+2021-03-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a command in package mode for opening home pages directly
+
+ * doc/emacs/package.texi (Package Menu): Document it.
+ * lisp/emacs-lisp/package.el (package-browse-url): New command and
+ keystroke (bug#46927).
+
+2021-03-04 Eli Zaretskii <eliz@gnu.org>
+
+ Fix typos and doc strings in native-compilation files
+
+ * lisp/emacs-lisp/comp.el (comp-speed, comp-debug, comp-verbose)
+ (comp-always-compile, comp-deferred-compilation-deny-list)
+ (comp-bootstrap-deny-list, comp-never-optimize-functions)
+ (comp-async-jobs-number, comp-async-cu-done-hook)
+ (comp-async-all-done-hook, comp-async-env-modifier-form)
+ (comp-pass, comp-native-compiling, comp-post-pass-hooks)
+ (comp-known-predicate-p, comp-pred-to-cstr)
+ (comp-symbol-values-optimizable, comp-limple-assignments)
+ (comp-limple-calls, comp-limple-branches, comp-block)
+ (comp-vec--verify-idx, comp-vec-aref, comp-vec-append)
+ (comp-vec-prepend, comp-block-preds)
+ (comp-ensure-native-compiler, comp-log, comp-log-func)
+ (comp-loop-insn-in-block, comp-byte-frame-size)
+ (comp-add-func-to-ctxt, comp-spill-lap-function, comp-spill-lap)
+ (comp-lap-fall-through-p, comp-new-frame, comp-emit-set-call)
+ (comp-copy-slot, comp-latch-make-fill, comp-emit-cond-jump)
+ (comp-body-eff, comp-op-case, comp-prepare-args-for-top-level)
+ (comp-limplify-top-level, comp-negate-arithm-cmp-fun)
+ (comp-emit-assume, comp-cond-cstrs-target-mvar)
+ (comp-function-foldable-p, comp-function-call-maybe-fold)
+ (comp-form-tco-call-seq, comp-clean-up-stale-eln)
+ (comp-delete-or-replace-file, comp--native-compile)
+ (native--compile-async, native-compile)
+ (batch-byte-native-compile-for-bootstrap): Fix typos, wording, and
+ punctuation in doc strings.
+ * lisp/loadup.el: Fix typos.
+
+ * src/lread.c (syms_of_lread): Doc fix.
+
+2021-03-04 Eli Zaretskii <eliz@gnu.org>
+
+ Update documentation of reading passwords
+
+ * doc/emacs/mini.texi (Passwords): Update to match the modified
+ implementation. (Bug#46902) Add indexing.
+
+2021-03-04 Mauro Aranda <maurooaranda@gmail.com>
+
+ Make checkdoc work with qualified methods
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc--next-docstring): Handle
+ cl-defmethod in a case of its own. Check for the presence of
+ qualifiers, and skip them accordingly until the docstring.
+
+ * test/lisp/emacs-lisp/checkdoc-tests.el (checkdoc-cl-defmethod-qualified-ok)
+ (checkdoc-cl-defmethod-with-extra-qualifier-ok)
+ (checkdoc-cl-defmethod-with-extra-and-nil-args-ok): Add tests for the fix.
+
+2021-03-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add "of" as a keyword in js-mode
+
+ * lisp/progmodes/js.el (js--keyword-re): Add the "of" of "for
+ ... of" in ECMAScript 2018 (bug#46924).
+
+2021-03-04 Matt Armstrong <matt@mdeb>
+
+ Call the set_buffer_overlays_ setters
+
+ * src/buffer.c (Fkill_buffer): Call set_buffer_overlays_before and
+ set_buffer_overlays_after instead of setting the fields directly
+ (bug#46914).
+
+2021-03-04 Glenn Morris <rgm@gnu.org>
+
+ Generate info/dir directly from any org sources
+
+ * Makefile.in (texi_misc): New variable.
+ (srcdir_doc_info_dir_inputs): Use texi_misc.
+ (${srcdir}/info/dir): No longer depend on info-real.
+
+2021-03-04 Glenn Morris <rgm@gnu.org>
+
+ * doc/misc/Makefile.in (echo-sources): New phony target.
+
+ * build-aux/make-info-dir: Handle .org input files.
+
+2021-03-04 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Decouple require-theme from load-theme
+
+ * lisp/custom.el (require-theme): Refashion after 'require', as a
+ function for loading only named features. Do not call
+ load-theme (bug#45068).
+ * etc/NEWS: Update its announcement accordingly.
+ * doc/lispref/customize.texi (Custom Themes): Document it.
+
+ * etc/themes/modus-operandi-theme.el:
+ * etc/themes/modus-vivendi-theme.el: Remove redundant calls to
+ 'provide'.
+
+ * test/lisp/custom-tests.el (custom-tests--with-temp-dir): New
+ macro.
+ (custom-theme--load-path): Use it.
+ (custom-tests-require-theme): New test.
+
+2021-03-04 Mauro Aranda <maurooaranda@gmail.com>
+
+ Remove copy-pasto from image-dired.el
+
+ * lisp/image-dired.el (image-dired-dired-edit-comment-and-tags):
+ Remove reference to widget-example-repeat.
+
+2021-03-04 Mauro Aranda <maurooaranda@gmail.com>
+
+ Remove duplicated tests in checkdoc-tests.el
+
+ * test/lisp/emacs-lisp/checkdoc-tests.el (checkdoc-cl-defmethod-ok)
+ (checkdoc-cl-defmethod-with-types-ok, checkdoc-cl-defun-with-key-ok)
+ (checkdoc-cl-defun-with-allow-other-keys-ok)
+ (checkdoc-cl-defun-with-default-optional-value-ok)
+ (checkdoc-cl-defun-with-destructuring-ok): This tests were duplicated,
+ so keep one copy of them. Checked by diffing two files with the
+ suspected tests, and supported by the fact that running occur with the
+ regexp "^(ert-deftest" reported 14 matches, while the tests being run
+ were 8.
+
+2021-03-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make radio checkboxes work in eww
+
+ * lisp/net/eww.el (eww-toggle-checkbox): Actually update the
+ :checked values in the form.
+
+2021-03-04 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (hash_native_abi): Account for `system-configuraton-options'.
+
+2021-03-04 Glenn Morris <rgm@gnu.org>
+
+ Fix a doc/misc clean rule
+
+ * doc/misc/Makefile.in (TEXI_FROM_ORG): New variable.
+ (orgclean): Fix rule.
+
+2021-03-04 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix pcase dontcare pattern in cl--sm-macroexpand
+
+ For discussion, see the following thread:
+ https://lists.gnu.org/r/emacs-devel/2021-03/msg00119.html
+
+ * lisp/emacs-lisp/cl-macs.el (cl--sm-macroexpand): Fix recently
+ uncovered use of old name for pcase--dontcare.
+
+2021-03-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/pcase.el (pcase-defmacro): Fix `pcase-tests-macro`
+
+ * lisp/emacs-lisp/radix-tree.el (radix-tree-leaf): Simplify accordingly.
+
+2021-03-03 Ulf Jasper <ulf.jasper@web.de>
+
+ Preserve group structure on opml import and export.
+
+ * lisp/net/newst-backend.el (newsticker--raw-url-list-defaults),
+ (newsticker-url-list-defaults),
+ (newsticker--get-news-by-url),
+ (newsticker--sentinel-work),
+ (newsticker--parse-atom-0.3),
+ (newsticker--decode-rfc822-date),
+ (newsticker--image-download-by-wget),
+ (newsticker--image-save),
+ (newsticker--image-download-by-url),
+ (newsticker--cache-save),
+ (newsticker--stat-num-items): Fix indentation.
+ (newsticker-opml-export): Preserve group structure on export.
+ (newsticker--opml-insert-elt),
+ (newsticker--opml-insert-group),
+ (newsticker--opml-insert-feed): New.
+ (newsticker--opml-import-outlines):
+ (newsticker-opml-import): Preserve group structure on import. (Fixes
+ fourth issue in Bug#41376.)
+
+2021-03-03 Pip Cet <pipcet@gmail.com>
+
+ Don't call _setjmp through a function pointer (Bug#46824)
+
+ * src/comp.c (helper_link_table): Don't include SETJMP except on Windows.
+ (emit_setjmp): Don't use function pointers except on Windows.
+ (declare_runtime_imported_funcs): Don't import SETJMP at runtime.
+ (ABI_VERSION): Bump.
+ * test/src/comp-tests.el (46824-1): New test.
+ * test/src/comp-resources/comp-test-funcs.el
+ (comp-test-46824-1-f): New function.
+
+2021-03-03 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (return_nil): Make it not a nested function.
+
+2021-03-03 Andrea Corallo <akrl@sdf.org>
+
+ Fix two compiler ICEs dealing with nan and infinity
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-=): Don't crash when
+ truncate fails.
+ * test/src/comp-test-funcs.el (comp-test-=-nan): Add two functions
+ to be compiled.
+
+2021-03-03 Juri Linkov <juri@linkov.net>
+
+ New mode outline-cycle-minor-mode with Orgmode-like TAB cycling on headings
+
+ * lisp/outline.el (outline-mode-cycle-map): New keymap from outline-mode-map.
+ (outline-mode-map): Inherit from outline-mode-cycle-map.
+ (outline-font-lock-keywords): Append keymap and face depending on
+ 'outline-minor-mode-cycle' and 'outline-minor-mode-highlight'.
+ (outline-minor-mode-cycle, outline-minor-mode-highlight): New variables.
+ (outline-minor-mode-highlight-buffer): New function.
+ (outline-minor-mode): Handle 'outline-minor-mode-cycle' and
+ 'outline-minor-mode-highlight'.
+ (outline-cycle-minor-mode, outline-cycle-highlight-minor-mode):
+ New minor modes (bug#45147).
+
+ * etc/compilation.txt:
+ * etc/grep.txt:
+ Enable outline-cycle-highlight-minor-mode.
+
+2021-03-03 Stefan Kangas <stefan@marxist.se>
+
+ Make inversion.el obsolete (Bug#46841)
+
+ * lisp/cedet/inversion.el:
+ * test/lisp/cedet/inversion-tests.el: Move from here...
+ * lisp/obsolete/inversion.el:
+ * test/lisp/obsolete/inversion-tests.el: ...to here.
+
+ * lisp/cedet/cedet.el (cedet-version): Make obsolete.
+ * lisp/cedet/cedet-cscope.el (cedet-cscope-version-check):
+ * lisp/cedet/cedet-global.el (cedet-gnu-global-version-check):
+ * lisp/cedet/cedet-idutils.el (cedet-idutils-version-check):
+ * lisp/cedet/ede/make.el (ede-make-check-version): Use 'version<'
+ instead of 'inversion-check-version'.
+ * lisp/cedet/semantic/db-file.el (semanticdb-load-database): Don't
+ use 'inversion-test'.
+ * lisp/cedet/semantic/ede-grammar.el
+ (ede-proj-makefile-insert-variables): Don't add inversion to
+ loadpath.
+ * lisp/speedbar.el: Remove stale comment.
+
+2021-03-03 Eli Zaretskii <eliz@gnu.org>
+
+ Fix compilation warnings in --with-wide-int build on Windows
+
+ * src/comp.c (emit_rvalue_from_emacs_uint)
+ (emit_rvalue_from_lisp_word_tag): Fix comparison of unsigned
+ values.
+ (gcc_jit_context_new_rvalue_from_ptr): Define only if
+ LISP_WORDS_ARE_POINTERS, to avoid compilation warning.
+ (init_gccjit_functions): Load gcc_jit_context_new_rvalue_from_ptr
+ only if LISP_WORDS_ARE_POINTERS.
+
+2021-03-03 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid aborting on MS-Windows at startup
+
+ * src/emacs.c (set_invocation_vars) [WINDOWSNT]: If argv0 is not
+ an absolute file name, obtain the absolute file name of the Emacs
+ executable from 'w32_my_exename'.
+
+2021-03-03 Eli Zaretskii <eliz@gnu.org>
+
+ Improve NEWS entries about native-compilation
+
+ * etc/NEWS: Add an entry about native-compilation. Improve
+ wording of the entry about 'package-native-compile'.
+
+2021-03-03 Alan Mackenzie <acm@muc.de>
+
+ C++ Mode: Handle "if constexpr (...)" with a simple statement correctly
+
+ * lisp/progmodes/cc-engine.el (c-beginning-of-statement-1): Add a check and
+ handling for c-block-stmt-hangon-key in the main loop.
+
+2021-03-02 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/pcase.el (pcase--u1): Fix typo
+
+2021-03-02 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Fix analysis of brace lists, particularly in C++ Mode
+
+ Fix some alignment functionality in cc-align.el.
+
+ * lisp/progmodes/cc-align.el (c-lineup-arglist-intro-after-paren): Align the
+ next line under the previous entry rather than one to the right of the paren.
+ (c-lineup-2nd-brace-entry-in-arglist): Take the anchor point from the
+ brace-list-entry element, not the brace-list-intro one.
+
+ * lisp/progmodes/cc-engine.el (c-looking-at-decl-block): Use
+ c-looking-at-statement-block to test whether "struct A {" begins a brace list
+ or a struct declaration.
+ (c-looking-at-or-maybe-in-bracelist): Several detailed amendments, correctly
+ to recognize brace lists.
+ (c-looking-at-statement-block): No longer search for commas, as they are not
+ reliable indicators of a brace list. Search now for a restricted set of
+ keywords, since some can appear in brace lists in C++ mode.
+
+ * lisp/progmodes/cc-langs.el (c-stmt-block-only-keywords)
+ (c-stmt-block-only-keywords-regexp): New lang consts/vars.
+ (c-pre-id-bracelist-kwds): New lang const.
+ (c-pre-id-bracelist-key): Derive now from the above.
+ (c-pre-brace-non-bracelist-key): New lang const/var.
+
+2021-03-02 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: Minor stylistic fixes.
+
+ (tab-bar-select-tab-modifiers): Use tab-bar--undefine-keys and
+ tab-bar--define-keys instead of turning tab-bar-mode on/off.
+
+2021-03-02 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/trace.el (trace-values): Work outside of traced function
+
+2021-03-02 Andrea Corallo <akrl@sdf.org>
+
+ Fix = propagation semantic for constrained inputs
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr): Synthesize
+ `comp-cstr-shallow-copy'.
+ (comp-cstr-=): Relax inputs before intersecting them.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add three
+ tests.
+
+2021-03-02 Dmitry Gutov <dgutov@yandex.ru>
+
+ (ruby-find-library-file): Also recognize 'gem' statements
+
+ * lisp/progmodes/ruby-mode.el (ruby-find-library-file):
+ Also recognize 'gem' statements.
+
+2021-03-02 Pip Cet <pipcet@gmail.com>
+
+ Compile closures that modify their bound vars correctly (Bug#46834)
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile--reify-function): Don't
+ move let bindings into the lambda. Don't reverse list of
+ bindings. (byte-compile): Evaluate the return value if it was
+ previously reified.
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-reify-function):
+ Add tests.
+
+2021-03-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the dired-do-kill-lines doc string
+
+ * lisp/dired-aux.el (dired-do-kill-lines): Document the FMT
+ parameter (bug#46867).
+
+2021-03-02 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/pcase.el: Bind all the vars in `or` patterns
+
+ Improve the handling of `or` patterns where not all sub-patterns bind the
+ same set of variables. This used to be "unsupported" and behaved in
+ somewhat unpredictable ways.
+
+ (pcase--expand): Rewrite.
+ (pcase-codegen): Delete.
+
+ * doc/lispref/control.texi (pcase Macro): Adjust accordingly.
+ Also remove the warning about "at least two" sub patterns.
+ These work fine, AFAICT, and if not we should fix it.
+
+ * test/lisp/emacs-lisp/pcase-tests.el (pcase-tests-or-vars): New test.
+
+2021-03-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous completion-pcm--optimize-pattern fix
+
+ * lisp/minibuffer.el (completion-pcm--optimize-pattern): Re-fix
+ previous change.
+
+2021-03-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix warning in completion-pcm--optimize-pattern
+
+ * lisp/minibuffer.el (completion-pcm--optimize-pattern): Remove
+ unused variable.
+
+2021-03-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make easymenu downcase the menu symbol for greater backwards compat
+
+ * lisp/cmuscheme.el (map): Revert previous fix.
+
+ * lisp/woman.el (woman-dired-define-keys): Ditto.
+
+ * lisp/emacs-lisp/easymenu.el (easy-menu-do-define): Downcase the
+ menu name for greater backwards compatibility.
+
+2021-03-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/pcase.el: Fix bug#46786
+
+ Revert commit a218c9861573b5ec4979ff2662f5c0343397e3ff, but in order
+ to avoid the spurious warnings that this commit tried to squash,
+ keep track of the vars used during the match so as to add
+ corresponding annotations to explicitly silence the spurious warnings.
+
+ To do this, we change the VARS used in `pcase-u` (and throughout
+ the pcase code): they used to hold elements of the form (NAME . VAL)
+ and now they hold elements of the form (NAME VAL . USED).
+
+ (pcase--expand): Bind all vars instead of only those found via fgrep.
+ (pcase-codegen): Silence "unused var" warnings for those vars that have
+ already been referenced during the match itself.
+ (pcase--funcall, pcase--eval): Record the vars that are used.
+ (pcase--u1): Record the vars that are used via non-linear patterns.
+
+ * lisp/textmodes/mhtml-mode.el (mhtml-forward):
+ * lisp/vc/diff-mode.el (diff-goto-source): Silence newly
+ discovered warnings.
+
+ * test/lisp/emacs-lisp/pcase-tests.el (pcase-tests-bug46786): New test.
+
+2021-03-01 Mattias Engdegård <mattiase@acm.org>
+
+ Fix multiple Calc defmath errors (bug#46750)
+
+ Fix incorrect variable scoping in `let*`, `for` and `foreach`.
+ Fix loop variable value in `foreach` (should be element, not tail).
+ Fix function quoting, as in ('cons x y) -- didn't work at all.
+
+ Reported by Stephan Neuhaus.
+
+ * lisp/calc/calc-prog.el (math-define-exp, math-handle-foreach):
+ * test/lisp/calc/calc-tests.el: (var-g, test1, test2, test3, test4)
+ (test5, test6, test7, calc-defmath): Test various defmath forms.
+
+2021-03-01 Mattias Engdegård <mattiase@acm.org>
+
+ Remove references to old bignums from Calc manual
+
+ * doc/misc/calc.texi: Remove references to the old Calc representation
+ of big integers, outdated references to fixnums, an any text and
+ examples that only made sense at the time.
+
+2021-03-01 Mattias Engdegård <mattiase@acm.org>
+
+ * lisp/calc/calc-ext.el (math-equal-int): Work for bignums.
+
+2021-03-01 Juri Linkov <juri@linkov.net>
+
+ * lisp/isearch.el: Minor doc fix.
+
+ * lisp/tab-bar.el (tab-bar--define-keys): Add check for tab-bar-format-global.
+
+2021-03-01 Protesilaos Stavrou <info@protesilaos.com>
+
+ Add 'require-theme' function
+
+ * etc/NEWS: Document new function.
+ * lisp/custom.el (require-theme): Add function.
+
+ This follows from the discussion on bug#45068 where it became apparent
+ that there was no equivalent mechanism to 'require' that read through
+ the 'custom-theme-load-path'.
+
+2021-03-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix woman.el menu alteration code
+
+ * lisp/woman.el (woman-dired-define-keys): Fix naming of menu
+ after dired menu changes.
+
+2021-03-01 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Amend C-M-a/e to handle lambda function in C++ arglist
+
+ * lisp/progmodes/cc-cmds.el (c-where-wrt-brace-construct): Reformulate latter
+ part such that the least enclosing braces and parentheses are used when
+ determining containment in such. c-beginning-of-decl-1 has been superseded
+ by list movement and syntactic whitespace movement.
+ (c-backward-to-nth-BOF-{): Work on least enclosing parens rather than parens
+ at any level when moving back to an opening brace.
+ (c-forward-to-nth-EOF-\;-or-}): Work on least enclosing parens, as above.
+ Move the correction of point when in a "function trailer" to after the main
+ loop, correcting a minor bug.
+
+2021-03-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/pcase.el (pcase--split-pred): Re-fix bug#14773
+
+ Adjust to calling convention of `macroexp--fgrep`.
+
+2021-03-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Fix misuses of `byte-compile-macro-environment`
+
+ These seem to be left overs from Emacs<24 when `macroexpand-all` was
+ implemented in the CL library and hence the macros's evaluation
+ environment could come from different places depending on the
+ circumstance (either `byte-compile-macro-environment`, or
+ `cl-macro-environment`, or ...).
+
+ `byte-compile-macro-environment` contains definitions which expand to
+ code that is only understood by the rest of the byte-compiler,
+ so using it for code which isn't being byte-compiled leads to errors
+ such as references to non-existing function
+ `internal--with-suppressed-warnings`.
+
+ * lisp/emacs-lisp/cl-extra.el (cl-prettyexpand): Remove left-over
+ binding from when `macroexpand-all` was implemented in the CL library.
+
+ * lisp/emacs-lisp/ert.el (ert--expand-should-1):
+ * lisp/emacs-lisp/cl-macs.el (cl--compile-time-too): Properly preserve the
+ macroexpand-all-environment.
+ (cl--macroexp-fboundp): Pay attention to `cl-macrolet` macros as well.
+
+2021-03-01 Andrea Corallo <akrl@sdf.org>
+
+ Fix `eql' `equal' propagation of non hash consed values (bug#46843)
+
+ Extend assumes allowing the following form:
+
+ (assume dst (and-nhc src1 src2))
+
+ `and-nhc' assume operator allow for constraining correctly
+ intersections where non hash consed values are not propagated as
+ values but rather promoted to their types.
+
+ * lisp/emacs-lisp/comp-cstr.el
+ (comp-cstr-intersection-no-hashcons): New function.
+ * lisp/emacs-lisp/comp.el (comp-emit-assume): Logic update to emit
+ `and-nhc' operator (implemented in fwprop by
+ `comp-cstr-intersection-no-hashcons').
+ (comp-add-cond-cstrs): Map `eq' to `and' assume operator and
+ `equal' `eql' into `and-nhc'.
+ (comp-fwprop-insn): Update to handle `and-nhc'.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add two
+ tests covering `eql' and `equal' propagation of non hash consed
+ values.
+
+2021-03-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/eval.c (init_eval_once): Bump max_specpdl_size (bug46818)
+
+ Further testing seems to confirm my suspicion that the increase in the
+ specpdl comes from the recent change to `pcase--if`.
+
+ * lisp/international/mule-cmds.el (update-leim-list-file): Revert workaround.
+
+2021-03-01 Matt Armstrong <matt@rfc20.org>
+
+ Clean up obsolete comment
+
+ * src/marker.c (unchain_marker): Clean up obsolete comment
+ (bug#46836).
+
+ Commit cf3164523b (* src/alloc.c: Avoid O(N²) complexity when
+ unchaining markers (bug#24548)., 2018-03-23) removed the call from GC
+ into unchain_marker, so there is no need to warn about it.
+
+2021-03-01 F. Jason Park <jp@neverwas.me>
+
+ Fix Bootstring skew parameter in puny.el
+
+ * lisp/net/puny.el: change puny-skew to match value given in RFC3492.
+ * test/lisp/net/puny-tests.el (puny-test-encode-domain)
+ (puny-test-decode-domain): add regression case for popular
+ domain. (bug#46838).
+
+2021-03-01 Stefan Kangas <stefan@marxist.se>
+
+ Convert various menus to easymenu
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-mode-map): Move menu from
+ here...
+ (lisp-mode-menu): ...to here, and convert to easymenu.
+
+ * lisp/progmodes/elisp-mode.el (lisp-interaction-mode-map): Move
+ menu definition from here...
+ (lisp-interaction-mode-menu): ...to here, and convert to easymenu.
+
+ * lisp/replace.el (occur-menu-map): Convert to easymenu.
+
+2021-03-01 Glenn Morris <rgm@gnu.org>
+
+ Improve admin.el's Makefile in standalone manual tarfiles
+
+ * admin/admin.el (make-manuals-dist-output-variables):
+ Fix abs_top_builddir. Add EMACS.
+ (make-manuals-dist--1): Respect case when replacing output variables.
+
+2021-03-01 Glenn Morris <rgm@gnu.org>
+
+ info/dir needs generated texi files to exist
+
+ * Makefile.in (misc-info): Depend on lisp.
+ (${srcdir}/info/dir): Depend on info-real.
+ (info): Simplify.
+
+2021-03-01 Glenn Morris <rgm@gnu.org>
+
+ Make generation of texi from org overwrite output
+
+ * doc/misc/Makefile.in (org_template): Don't delete output.
+ * lisp/org/ox-texinfo.el (org-texinfo-export-to-texinfo-batch):
+ Overwrite existing output.
+
+2021-02-28 Andrea Corallo <akrl@sdf.org>
+
+ Don't treat '=' as simple equality emitting constraints (bug#46812)
+
+ Extend assumes allowing the following form
+
+ (assume dst (= src1 src2))
+
+ to capture '=' semanting during fwprop handling float integer
+ conversions.
+
+ * lisp/emacs-lisp/comp.el (comp-equality-fun-p): Don't treat '=' as
+ simple equality.
+ (comp-arithm-cmp-fun-p, comp-negate-arithm-cmp-fun)
+ (comp-reverse-arithm-fun): Rename and add '=' '!='.
+ (comp-emit-assume, comp-add-cond-cstrs, comp-fwprop-insn): Update
+ for new function nameing and to handle '='.
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-=): New function.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add a bunch
+ of '=' specific tests.
+
+2021-02-28 Andrea Corallo <akrl@sdf.org>
+
+ Migrate and rename a bunch of functions from comp.el to comp-cstr.el
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-imm-vld-p)
+ (comp-cstr-imm, comp-cstr-fixnum-p, comp-cstr-symbol-p)
+ (comp-cstr-cons-p): Move and rename from 'comp.el'.
+ * lisp/emacs-lisp/comp.el (comp-mvar-type-hint-match-p)
+ (make-comp-mvar, comp-emit-assume, comp-fwprop-prologue)
+ (comp-function-foldable-p, comp-function-call-maybe-fold)
+ (comp-fwprop-call, comp-fwprop-insn, comp-call-optim-func)
+ (comp-compute-function-type): Update for renamed functions.
+ * src/comp.c (emit_mvar_rval): Likewise.
+ * test/src/comp-tests.el (comp-tests-mentioned-p-1)
+ (comp-tests-cond-rw-checker-val): Likewise.
+
+2021-02-28 Glenn Morris <rgm@gnu.org>
+
+ * doc/misc/modus-themes.org: Add copying markup. (Bug#45141)
+
+2021-02-28 Glenn Morris <rgm@gnu.org>
+
+ Update admins make-manuals for new output variable
+
+ * admin/admin.el (make-manuals-dist-output-variables):
+ Add abs_top_builddir.
+
+2021-02-28 Stefan Kangas <stefan@marxist.se>
+
+ Convert dired menus to easymenu
+
+ * lisp/dired.el (dired-mode-map): Move menus from here...
+ (dired-mode-subdir-menu, dired-mode-immediate-menu)
+ (dired-mode-regexp-menu, dired-mode-mark-menu)
+ (dired-mode-operate-menu): ...to here, and convert to easymenu.
+
+2021-02-28 Stefan Kangas <stefan@marxist.se>
+
+ Convert hi-lock-menu to easymenu
+
+ * lisp/hi-lock.el (hi-lock-menu): Convert to easymenu.
+
+2021-02-28 Alan Mackenzie <acm@muc.de>
+
+ Combine and reconcile two conflicting entries in NEWS on goto-line-history
+
+ * etc/NEWS: Amend.
+
+ * doc/lispref/minibuf.texi (Minibuffer History): Amend the entry about
+ goto-line-history, which is now buffer local only after being so customized.
+
+2021-02-28 Mattias Engdegård <mattiase@acm.org>
+
+ Declare more string predicates as pure
+
+ * lisp/emacs-lisp/byte-opt.el (pure-fns): Treat string>,
+ string-greaterp, string-empty-p, string-blank-p, string-prefix-p and
+ string-suffix-p as pure functions in the compiler.
+
+2021-02-28 Stefan Kangas <stefan@marxist.se>
+
+ Convert ibuffer menus to easymenu
+
+ * lisp/ibuffer.el (ibuffer-mode-map): Move menu from here...
+ (ibuffer-mode-mark-menu, ibuffer-mode-view-menu): ...to here.
+ Convert to easymenu.
+ (ibuffer-mode--groups-menu-definition): New function. Fix bug where
+ "Kill filter by group named" and "Yank last killed filter group
+ before" was overwritten and never shown in the menu.
+ (ibuffer-mode-groups-popup): Convert to easymenu.
+ (ibuffer-mode-operate-menu): Rename from 'ibuffer-mode-operate-map'
+ and update uses. Convert to easymenu.
+ (ibuffer-mode-operate-map): Make into obsolete alias for above
+ renamed variable.
+
+2021-02-28 Michael Albinus <michael.albinus@gmx.de>
+
+ Add `completion-predicate' to some Tramp commands
+
+ * lisp/net/tramp-cmds.el (tramp-cleanup-this-connection)
+ (tramp-rename-these-files): Add property `completion-predicate'.
+
+ * lisp/net/tramp.el (tramp-command-completion-p): New defun.
+
+2021-02-28 Kapuze Martin <m.s.p@posteo.de> (tiny change)
+
+ Enable Python type hints and non-trivial base classes in wisent
+
+ * admin/grammars/python.wy: Enable understanding Python type hints
+ and non-trivial base classes (bug#46817).
+
+2021-02-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust cmuscheme.el menu bar after previous scheme.el change
+
+ * lisp/cmuscheme.el (map): Adjust the keymap lookup after recent
+ scheme.el change (bug#46820).
+
+2021-02-28 Mattias Engdegård <mattiase@acm.org>
+
+ Fix pcase 'rx' pattern match-data bug
+
+ The pcase 'rx' pattern would in some cases allow the match data to be
+ clobbered before it is read. For example:
+
+ (pcase "PQR"
+ ((and (rx (let a nonl)) (rx ?z)) (list 'one a))
+ ((rx (let b ?Q)) (list 'two b)))
+
+ The above returned (two "P") instead of the correct (two "Q").
+ This occurred because the calls to string-match and match-string were
+ presented as separate patterns to pcase, which would interleave them
+ with other patterns.
+
+ As a remedy, combine string matching and match-data extraction into a
+ single pcase pattern. This introduces a slight inefficiency for two
+ or more submatches as they are grouped into a list structure which
+ then has to be destructured.
+
+ Found by Stefan Monnier. See discussion at
+ https://lists.gnu.org/archive/html/emacs-devel/2021-02/msg02010.html
+
+ * lisp/emacs-lisp/rx.el (rx--reduce-right): New helper.
+ (rx [pcase macro]): Combine string-match and match-string calls into a
+ single pcase pattern.
+ * test/lisp/emacs-lisp/rx-tests.el (rx-pcase): Add test cases.
+
+2021-02-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/international/mule-cmds.el: Try and fix bug#46818
+
+ (update-leim-list-file): Reduce stack/pdl use.
+
+2021-02-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/macroexp.el: Rewrite the code warning about '(lambda ...)
+
+ (macroexp--expand-all): Use `pcase--dontcare` so pcase generates
+ slightly better code. Don't hardcode which functions takes function
+ arguments; rely on a new `funarg-positions` symbol property instead.
+
+2021-02-28 Stefan Kangas <stefan@marxist.se>
+
+ Convert text-mode menu to easymenu
+
+ * lisp/textmodes/text-mode.el (text-mode-map): Move menu
+ definition from here...
+ (text-mode-menu): ...to here, and convert to easymenu.
+
+2021-02-28 Stefan Kangas <stefan@marxist.se>
+
+ Convert isearch menu to easymenu
+
+ * lisp/isearch.el (isearch-menu-bar-yank-map)
+ (isearch-menu-bar-map, isearch-mode-map): Move menu definition
+ from here...
+ (isearch-menu-bar-map): ...to here, and convert to easymenu.
+
+ * lisp/loadup.el ("emacs-lisp/easymenu"): Move before isearch.el.
+
+2021-02-28 Stefan Kangas <stefan@marxist.se>
+
+ Checkdoc fixes in isearch.el
+
+ * lisp/isearch.el (isearch--set-state, isearch-yank-pop-only)
+ (isearch-search-and-update, isearch-complete-edit, isearch-search):
+ Minor doc fixes.
+
+2021-02-27 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: Support displaying global-mode-string in the tab bar.
+
+ * lisp/tab-bar.el (tab-bar--define-keys): Update global-mode-string
+ in mode-line-misc-info with condition to disable global-mode-string
+ in the mode line.
+ (tab-bar-format): New variable.
+ (tab-bar-format-history, tab-bar-format-add-tab)
+ (tab-bar-format-tabs): New functions with body from
+ 'tab-bar-make-keymap-1'.
+ (tab-bar-format-align-right, tab-bar-format-global): New functions for
+ 'tab-bar-format' list.
+ (tab-bar-format-list): New utility function.
+ (tab-bar-make-keymap-1): Just call 'tab-bar-format-list'.
+ https://lists.gnu.org/archive/html/emacs-devel/2020-11/msg01210.html
+
+2021-02-27 Juri Linkov <juri@linkov.net>
+
+ * lisp/subr.el (read-char-choice-with-read-key): New function.
+
+ * lisp/subr.el (read-char-choice): Move most of the function body to
+ 'read-char-choice-with-read-key'.
+ (read-char-choice-with-read-key): New function with body from
+ 'read-char-choice'.
+
+2021-02-27 Stefan Kangas <stefan@marxist.se>
+
+ Convert Buffer-menu-mode menu to easymenu
+
+ * lisp/buff-menu.el (Buffer-menu-mode-map): Move menu
+ definition from here...
+ (Buffer-menu-mode-menu): ...to here, and convert to easymenu.
+
+2021-02-27 Stefan Kangas <stefan@marxist.se>
+
+ Minor fixes after preloading easymenu
+
+ * lisp/cedet/ede/dired.el:
+ * lisp/dired-x.el:
+ * lisp/filesets.el:
+ * lisp/follow.el:
+ * lisp/gnus/gnus-registry.el:
+ * lisp/net/eudc.el:
+ * lisp/printing.el:
+ * lisp/recentf.el:
+ * lisp/speedbar.el: Remove redundant require of easymenu; it is now
+ preloaded.
+ * lisp/org/org.el:
+ * lisp/progmodes/antlr-mode.el:
+ * lisp/progmodes/vhdl-mode.el:
+ * lisp/textmodes/reftex.el: Don't require easymenu in Emacs 28 or
+ later.
+
+ * etc/NEWS: Announce that 'easymenu' is now preloaded.
+
+2021-02-27 Glenn Morris <rgm@gnu.org>
+
+ Fix doc/misc Makefile for out-of-tree with relative path
+
+ * doc/misc/Makefile.in (org_template): Fix for relative srcdir.
+
+2021-02-27 Glenn Morris <rgm@gnu.org>
+
+ Improve Makefile treatment of org sources in doc/misc
+
+ * doc/misc/Makefile.in (ORG_SETUP): New variable.
+ (ORG_SRC): Use wildcard rather than hard-coding.
+ (org_template): Adjust for input containing $srcdir and suffix.
+ (org_setup_template): New template.
+
+2021-02-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/bytecomp.el: Fix minor regression introduced by pdump
+
+ After `rm **/*.elc; make` we'd sometimes get loads and loads of unnecessary
+ "Reloading ...".
+
+ (byte-compile-refresh-preloaded): Don't reload files that are more
+ recent than `temacs` but older than the `.pdmp` file.
+
+2021-02-27 Stefan Kangas <stefan@marxist.se>
+
+ Don't require overlay; that's only needed in XEmacs
+
+ * lisp/allout.el:
+ * lisp/net/eudc.el:
+ * lisp/org/org.el: Don't require overlay; that's only needed in
+ XEmacs.
+
+2021-02-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cconv.el: Fix uncaught brain farts in last change
+
+ (cconv--convert-funcbody, cconv-convert): Use `macroexp--warn-wrap` properly.
+
+2021-02-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add sexp navigation commands to elisp-mode
+
+ * lisp/progmodes/elisp-mode.el (emacs-lisp-mode-menu): Add some
+ navigation commands (bug#24774).
+
+2021-02-27 Stefan Kangas <stefan@marxist.se>
+
+ Convert emacs-lisp-mode menu to easy-menu-define
+
+ * lisp/loadup.el: Preload easymenu.
+
+ * lisp/progmodes/elisp-mode.el (emacs-lisp-mode-map): Convert menu to
+ use easy-menu-define (bug#24774).
+
+2021-02-27 Matt Armstrong <matt@rfc20.org>
+
+ Remove unnecessary unlock-buffer calls
+
+ * lisp/files.el (revert-buffer-insert-file-contents--default-function):
+ Remove vestigial call to `unlock-buffer'.
+ * lisp/simple.el (primitive-undo): Assume unlock-buffer is always
+ bound. (Bug#46701)
+
+2021-02-27 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid crashes in Mew due to corrupted tool-bar label
+
+ * src/gtkutil.c (update_frame_tool_bar): Don't keep around a
+ 'char *' pointer to a Lisp string's contents when calling Lisp,
+ because that could relocate string data; keep the Lisp string
+ itself instead. This avoids crashes in Mew. (Bug#46791)
+
+2021-02-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Compute grep defaults earlier
+
+ * lisp/progmodes/grep.el (grep): Always compute the defaults
+ (bug#46801).
+ (grep-highlight-matches): Clarify that it's not just used
+ interactively.
+
+2021-02-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Change defcustom types of two non-standard hooks
+
+ * lisp/erc/erc.el (erc-before-connect, erc-after-connect): Change
+ type from 'hook to 'function (bug#34657).
+
+2021-02-27 F. Jason Park <jp@neverwas.me>
+
+ Accept string argument in erc-add-to-input-ring
+
+ * lisp/erc/erc-ring.el: (erc-add-to-input-ring)
+ (erc-previous-command): Use existing API to grab input.
+ * test/lisp/erc/erc-tests.el: (erc-ring-previous-command)
+ See (bug#46339).
+
+2021-02-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add generated .texi files to .gitignore
+
+2021-02-27 Glenn Morris <rgm@gnu.org>
+
+ Fixes for doc/misc org source files
+
+ * doc/misc/org-setup.org: Fix "version" file lookup. Add copyright.
+ * doc/misc/modus-themes.org: Fix up doclicense include.
+ * doc/misc/org.org: Remove non-working and unused "modification-time".
+ Fix up doclicense include. Adjust setupfile inclusion.
+
+2021-02-27 Glenn Morris <rgm@gnu.org>
+
+ Distribute the real source for some doc/misc manuals (bug#45143)
+
+ * doc/misc/modus-themes.texi, doc/misc/org.texi:
+ Remove generated files from repository.
+ * doc/misc/Makefile.in: Add rules for building .texi from .org.
+ (ORG_SRC, abs_top_builddir, EMACS, emacs):
+ New variables.
+ (org_template): New template.
+ (orgclean): New phony target.
+ * Makefile.in (info): Depend on lisp.
+ * lisp/org/ox-texinfo.el (org-texinfo-export-to-texinfo-batch):
+ New function.
+ * doc/misc/org.org, doc/misc/org-setup.org: New files.
+ Import from https://code.orgmode.org d8e8a97a14.
+
+2021-02-27 Protesilaos Stavrou <info@protesilaos.com>
+
+ Import org source file for modus-themes manual
+
+ * doc/misc/modus-themes.org: New file.
+ Import from https://gitlab.com/protesilaos/modus-themes 515180ac.
+
+2021-02-27 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in progmodes/icon.el
+
+ * lisp/progmodes/icon.el: Use lexical-binding.
+ (electric-icon-brace): Very minor cleanup.
+
+2021-02-27 Stefan Kangas <stefan@marxist.se>
+
+ Convert change-log-mode menu to easy-menu-define
+
+ * lisp/vc/add-log.el (change-log-mode-map): Move menu from here...
+ (change-log-mode-menu): ...to here; convert to easy-menu-define.
+
+2021-02-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cconv.el: Improve line-nb info of unused var warnings
+
+ Instead of warning about unused vars during the analysis phase of
+ closure conversion, do it in the actual closure conversion by
+ annotating the code with "unused" warnings, so that the warnings
+ get emitted later by the bytecomp phase, like all other warnings,
+ at which point the line-number info is a bit less imprecise.
+
+ Take advantage of this change to wrap the expressions of unused
+ let-bound vars inside (ignore ...) so the byte-compiler can better
+ optimize them away.
+
+ Finally, promote `macroexp--warn-and-return` to "official" status
+ by removing its "--" marker.
+
+ (cconv-captured+mutated, cconv-lambda-candidates): Remove vars.
+ (cconv-var-classification): New var to replace them.
+ (cconv-warnings-only): Delete function.
+ (cconv--warn-unused-msg, cconv--var-classification): New functions.
+ (cconv--convert-funcbody): Add warnings for unused args.
+ (cconv-convert): Add warnings for unused vars in `let` and `condition-case`.
+ (cconv--analyze-use): Don't emit an "unused var" warning any more,
+ but instead remember the fact in `cconv-var-classification`.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-force-lexical-warnings):
+ Remove variable.
+ (byte-compile-preprocess): Remove corresponding case.
+
+ * lisp/emacs-lisp/pcase.el (pcase--if): Don't throw away `test` effects.
+ (\`):
+ * lisp/emacs-lisp/cl-macs.el (cl--do-arglist): Use `car-safe` instead
+ of `car`, so it can more easily be removed by the optimizer if the
+ result is not used.
+
+ * lisp/emacs-lisp/macroexp.el (macroexp--warn-wrap): New function.
+ (macroexp-warn-and-return): Rename from `macroexp--warn-and-return`.
+
+2021-02-26 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ lisp/vc/*.el: Use lexical-bindings in all the files
+
+ Also remove some redundant `:group` arguments.
+
+ * lisp/vc/vc.el (vc-ignore): Autoload.
+
+ * lisp/vc/pcvs-util.el (cvs-every, cvs-union, cvs-map): Delete functions.
+ * lisp/vc/cvs-status.el: Require `cl-lib` at runtime.
+ (cvs-tree-tags-insert): Use `cl-mapcar` and `cl-every` instead.
+ * lisp/vc/pcvs.el: Require `cl-lib` at runtime.
+ (cvs-do-removal): Use `cl-every` instead.
+
+ * lisp/vc/ediff-init.el: Require `ediff-util` (for `ediff-cleanup-mess`
+ and `ediff-default-suspend-function`).
+
+ * lisp/vc/pcvs-info.el (cvs-fileinfo<): Remove unused vars `subtypea`
+ and `subtypeb`.
+
+ * lisp/vc/vc-git.el:
+ * lisp/vc/vc-bzr.el: Require `vc-dispatcher` at runtime for
+ `vc-do-async-command`.
+
+2021-02-26 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet/semantic/idle.el: Fix compilation warning
+
+ (eldoc-last-message): Remove var declaration.
+ (eldoc-message): Remove function declaration.
+ (semantic--eldoc-info): Rename from semantic-idle-summary-idle-function.
+ Make it usable on `eldoc-documentation-functions`.
+ (semantic-idle-summary-mode): Use `eldoc-mode`.
+ (semantic-idle-summary-refresh-echo-area): Delete function.
+
+2021-02-26 Andrea Corallo <akrl@sdf.org>
+
+ Canonicalize filenames on Windows before hashing (bug#46256)
+
+ * src/comp.c (Fcomp_el_to_eln_filename): On Windowns
+ canonicalize filenames before hashing.
+
+2021-02-26 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet/semantic/analyze*.el: Use lexical-binding
+
+ * lisp/cedet/semantic/analyze.el: Use lexical-binding.
+ Rename the dynbound var `prefixtypes` to `semantic--prefixtypes`.
+ (semantic--prefixtypes): Declare var.
+
+ * lisp/cedet/semantic/analyze/complete.el: Use lexical-binding.
+ (semantic--prefixtypes): Declare var.
+ (semantic-analyze-possible-completions-default): Remove unused var `any`.
+ Rename `prefixtypes` to `semantic--prefixtypes`.
+
+ * lisp/cedet/semantic/analyze/debug.el: Use lexical-binding.
+ (semantic-analyzer-debug-global-symbol): Remove no-op use of `prefixtypes`.
+
+ * lisp/cedet/semantic/analyze/refs.el:
+ * lisp/cedet/semantic/analyze/fcn.el: Use lexical-binding.
+
+2021-02-26 Andrea Corallo <akrl@sdf.org>
+
+ Change native compiler configure flag into '--with-native-compilation'
+
+ * configure.ac: Rename configure nativecomp flags into
+ --with-native-compilation.
+
+2021-02-26 Andrea Corallo <akrl@sdf.org>
+
+ Interactive tag native compilation function in emacs-lisp-mode
+
+ * lisp/progmodes/elisp-mode.el
+ (emacs-lisp-native-compile-and-load): Tag it for `emacs-lisp-mode'.
+
+2021-02-26 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into native-comp
+
+2021-02-26 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Tramp manual
+
+ * doc/misc/tramp.texi (External methods): Mention "about-args".
+ (Remote shell setup): Use sshx.
+
+2021-02-26 Stefan Kangas <stefan@marxist.se>
+
+ Make some defcustom types stricter in comp.el
+
+ * lisp/emacs-lisp/comp.el (comp-speed, comp-debug, comp-verbose)
+ (comp-async-jobs-number, comp-async-env-modifier-form): Use stricter
+ types.
+
+2021-02-26 Stefan Kangas <stefan@marxist.se>
+
+ Add :version tags to defcustoms in comp.el
+
+ * lisp/emacs-lisp/comp.el (comp-speed, comp-debug, comp-verbose)
+ (comp-never-optimize-functions, comp-async-jobs-number)
+ (comp-async-cu-done-hook, comp-async-all-done-hook)
+ (comp-async-env-modifier-form)
+ (comp-async-report-warnings-errors, comp-native-driver-options)
+ (comp-libgccjit-reproducer): Add :version tags.
+
+2021-02-26 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/progmodes/dcl-mode.el: Minor doc fixes.
+
+2021-02-26 Stefan Kangas <stefan@marxist.se>
+
+ Convert some more progmode menus to easy-menu-define
+
+ * lisp/progmodes/dcl-mode.el (dcl-mode-map):
+ * lisp/progmodes/icon.el (icon-mode-map):
+ * lisp/progmodes/scheme.el (scheme-mode-map):
+ Move menu definitions from here...
+ * lisp/progmodes/dcl-mode.el (dcl-mode-menu):
+ * lisp/progmodes/icon.el (icon-mode-menu)
+ * lisp/progmodes/scheme.el (scheme-mode-menu):
+ ...to here, and use easy-menu-define.
+
+ * lisp/progmodes/icon.el
+ (icon-mode-map, icon-mode-syntax-table): Simplify.
+
+2021-02-26 Stefan Kangas <stefan@marxist.se>
+
+ Convert simula-mode menu to easy-menu-define
+
+ * lisp/progmodes/simula.el (simula-mode-map): Move menu definition
+ from here...
+ (simula-mode-menu): ...to here, and use easy-menu-define.
+ (simula-popup-menu): Declare unused function obsolete.
+
+2021-02-26 Stefan Kangas <stefan@marxist.se>
+
+ Fix syntax highlighting of easy-menu-define docstrings
+
+ * lisp/emacs-lisp/easymenu.el (easy-menu-define): Add doc-string
+ declaration for correct syntax highlighting.
+
+2021-02-26 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant requires of easymenu
+
+ * lisp/allout.el:
+ * lisp/emacs-lisp/edebug.el:
+ * lisp/emacs-lisp/ert.el:
+ * lisp/erc/erc-menu.el:
+ * lisp/help-mode.el:
+ * lisp/net/dictionary.el:
+ * lisp/nxml/rng-nxml.el:
+ * lisp/progmodes/ebrowse.el:
+ * lisp/progmodes/meta-mode.el:
+ * lisp/progmodes/prolog.el:
+ * lisp/progmodes/ps-mode.el:
+ * lisp/progmodes/vera-mode.el:
+ * lisp/wid-browse.el: Remove redundant require of easymenu. We only
+ use the autoloaded macro 'easy-menu-define' here.
+
+2021-02-26 Stefan Kangas <stefan@marxist.se>
+
+ Remove check for missing easymenu from cperl-mode.el
+
+ * lisp/progmodes/cperl-mode.el (cperl-menu): Don't wrap definition
+ in condition-case; easymenu always exists in Emacs.
+ (easymenu): Remove redundant require.
+
+2021-02-26 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change
+
+ * lisp/emacs-lisp/comp.el (comp-async-report-warnings-errors):
+ Improve wording of the doc string.
+
+2021-02-26 Andrea Corallo <akrl@sdf.org>
+
+ Improve `comp-async-report-warnings-errors' docstring
+
+ * lisp/emacs-lisp/comp.el (comp-async-report-warnings-errors):
+ Improve docstring.
+
+2021-02-26 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of last change
+
+ * lisp/emacs-lisp/comp.el (comp-async-query-on-exit)
+ (comp-async-report-warnings-errors): Improve wording.
+
+2021-02-26 Andrea Corallo <akrl@sdf.org>
+
+ Add `comp-async-query-on-exit' customize.
+
+ * lisp/emacs-lisp/comp.el (comp-async-query-on-exit): New customize.
+ (comp-run-async-workers): Make use of.
+
+2021-02-26 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Function-quote completion property of declare form
+
+ For discussion, see the following thread:
+ https://lists.gnu.org/r/emacs-devel/2021-02/msg01666.html
+
+ * lisp/emacs-lisp/byte-run.el (byte-run--set-completion): Quote with
+ 'function' for syntactical consistency with other declare form
+ properties. This allows writing (declare (completion foo)) instead
+ of (declare (completion 'foo)).
+ * lisp/emacs-lisp/easymenu.el (easy-menu-do-define):
+ * lisp/gnus/gnus-sum.el (gnus-summary-make-menu-bar): Prefer
+ function-put over put for function symbols.
+ * lisp/subr.el (ignore, undefined): Remove #'-quoting from declare
+ form; it is no longer needed.
+
+2021-02-26 Mattias Engdegård <mattiase@acm.org>
+
+ Fix pcase rx pattern bugs
+
+ Two unrelated bugs: A missing type check caused an error in rx
+ patterns for non-string match targets, and rx patterns did not work at
+ all in pcase-let or pcase-let*.
+
+ Second bug reported by Basil Contovounesios and Ag Ibragimov; fixes
+ proposed by Stefan Monnier. Discussion and explanation in thread at
+ https://lists.gnu.org/archive/html/emacs-devel/2021-02/msg01924.html
+
+ * lisp/emacs-lisp/rx.el (rx): Add (pred stringp) to avoid type errors,
+ and replace the `pred` clause for the actual match with something that
+ works with pcase-let(*) without being optimised away.
+ * test/lisp/emacs-lisp/rx-tests.el (rx-pcase): Add test cases.
+
+2021-02-26 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/tooltip.el (tooltip): Doc fix for GTK.
+
+2021-02-25 Andrea Corallo <akrl@sdf.org>
+
+ Fix some comp-vec logic
+
+ * lisp/emacs-lisp/comp.el (comp-vec-length, comp-vec-append)
+ (comp-vec-prepend): Fix logic.
+ (comp-vec-aref): Fix indentation.
+
+2021-02-25 Andrea Corallo <akrl@sdf.org>
+
+ Fix two docstrings in comp.el
+
+ * lisp/emacs-lisp/comp.el (comp-new-frame,
+ comp-maybe-add-vmvar): Fix docstring.
+
+2021-02-25 Eli Zaretskii <eliz@gnu.org>
+
+ Fix documentation of a recent change
+
+ * src/fns.c (Fyes_or_no_p): Don't use braces around one-line
+ block.
+ (syms_of_fns) <use-short-answers>: Improve the wording of the doc
+ string.
+ * etc/NEWS: Improve wording of the entry about 'use-short-answers'.
+
+2021-02-25 Juri Linkov <juri@linkov.net>
+
+ New variable 'use-short-answers' to use 'y-or-n-p' instead of 'yes-or-no-p'
+
+ * lisp/cus-start.el: Add use-short-answers.
+
+ * lisp/emacs-lisp/map-ynp.el (read-answer): Handle use-short-answers.
+ (read-answer-short): Add use-short-answers to docstring.
+
+ * src/fns.c (Fyes_or_no_p): Call y-or-n-p if use_short_answers is true.
+ (syms_of_fns): Add DEFVAR_BOOL use-short-answers (bug#46594).
+
+2021-02-25 Alan Third <alan@idiocy.org>
+
+ Fix freeze on older macOS's (bug#46687)
+
+ * src/nsterm.m ([EmacsView windowDidChangeBackingProperties:]):
+ ([EmacsView viewWillDraw]): Only run this code when actually drawing
+ to an offscreen bitmap.
+
+2021-02-25 Robert Pluim <rpluim@gmail.com>
+
+ Re-enable network-stream-tests.el :nowait t tests
+
+ After the fix for Bug#46709, these no longer fail in the absence of a
+ working Internet connection
+
+ * test/lisp/net/network-stream-tests.el (internet-is-working): Remove
+ defvar, it's no longer needed in this file.
+
+ * test/lisp/net/network-stream-tests.el
+ (connect-to-tls-ipv4-nowait):
+ (connect-to-tls-ipv6-nowait):
+ (open-network-stream-tls-nowait):
+ (open-gnutls-stream-new-api-nowait):
+ (open-gnutls-stream-old-api-nowait): Remove check for internet-is-working.
+
+2021-02-25 Robert Pluim <rpluim@gmail.com>
+
+ Don't crash if gnutls_handshake fails
+
+ In some situations involving Internet access not being fully
+ functional, gnutls_handshake returns a fatal error, which we were
+ ignoring, causing us to call gnutls_handshake again. Now we check for
+ the error and return it to the caller.
+
+ * src/gnutls.c (gnutls_try_handshake): Return immediately if
+ gnutls_handshake returns a fatal error (Bug#46709).
+
+2021-02-25 Robert Pluim <rpluim@gmail.com>
+
+ * Specify 'ipv4 when testing ipv4 in network-stream-tests.el
+
+ * test/lisp/net/network-stream-tests.el
+ (connect-to-tls-ipv4-nowait): Specify :family 'ipv4.
+
+2021-02-25 Stefan Kangas <stefan@marxist.se>
+
+ Convert epa-key-list-mode menu to easy-menu-define
+
+ * lisp/epa.el (epa-key-list-mode-map): Move menu from here...
+ (epa-key-list-mode-menu): ...to here, and convert to easy-menu-define.
+
+2021-02-25 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Remove last remaining external uses of `edebug-form-spec`
+
+ * lisp/emacs-lisp/gv.el (gv-place): Use `def-edebug-elem-spec`.
+
+ * lisp/obsolete/erc-compat.el (erc-define-minor-mode): Remove redundant
+ `edebug-form-spec`.
+
+2021-02-25 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * test/lisp/emacs-lisp/macroexp-tests.el (macroexp--tests-file-name): Add case
+
+ Add use of `macroexp-file-name` from a macro called from within
+ a function, which works thanks to eager-macroexpansion (so the macro
+ is expanded which the file is being loaded rather than only later
+ when the function is called).
+
+ * test/lisp/emacs-lisp/macroexp-resources/m1.el
+ (macroexp--m1-tests-file-name): New function.
+
+2021-02-25 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * test/lisp/emacs-lisp/macroexp-tests.el (macroexp--tests-file-name): New test
+
+ * test/lisp/emacs-lisp/macroexp-resources/m1.el:
+ * test/lisp/emacs-lisp/macroexp-resources/m2.el: New files.
+
+2021-02-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Include a "make check-maybe" in the admin/emake script
+
+2021-02-24 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/macroexp.el (macroexp-file-name): Work in `eval-buffer`
+
+ Rely on `current-load-list` instead of `load-file-name`.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-close-variables):
+ Change the var we override accordingly.
+
+2021-02-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve quail-update-leim-list-file error messaging
+
+ * lisp/international/quail.el (quail-update-leim-list-file): Give
+ a better error message.
+
+2021-02-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix warning generated by indian.el + quail.el
+
+ * lisp/leim/quail/indian.el (quail-define-indian-trans-package):
+ Reintroduce kludge to fix automatic detection by Quail.
+
+2021-02-24 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: Move aliases down closer to keybindings.
+
+2021-02-24 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-switch): New defalias to 'tab-bar-switch-to-tab'.
+
+ (tab-prefix-map): Bind "O" to 'tab-previous'.
+
+2021-02-24 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/macroexp.el (macroexp-file-name): New function.
+
+ Yes, finally: a function that tells you the name of the file where
+ the code is located. Finding this name is non-trivial in practice,
+ as evidenced by the "4 shift/reduce conflicts" warning when compiling
+ CEDET's python.el, because its `wisent-source` got it wrong in that
+ case, thinking the grammar came from `python.el` instead of
+ `python-wy.el`.
+
+ While at it, also made `macroexp-compiling-p` public, since it's
+ useful at various places.
+
+ (macroexp-compiling-p): Rename from `macroexp--compiling-p`.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-close-variables):
+ Bind `load-file-name` to nil so we can distinguish a load that calls
+ the byte compiler from a byte compilation which causes a load.
+
+ * lisp/cedet/semantic/wisent/python.el (wisent-python--expected-conflicts):
+ Remove; it was just a workaround.
+ * lisp/subr.el (do-after-load-evaluation): Avoid `byte-compile--` vars.
+ * lisp/cedet/semantic/fw.el (semantic-alias-obsolete):
+ Use `macroexp-compiling-p` and `macroexp-file-name`.
+ * lisp/cedet/semantic/wisent/comp.el (wisent-source): Use `macroexp-file-name`
+ (wisent-total-conflicts): Tighten regexp.
+ * lisp/emacs-lisp/cl-lib.el (cl--compiling-file): Delete function
+ and variable. Use `macroexp-compiling-p` instead.
+ * lisp/progmodes/flymake.el (flymake-log):
+ * lisp/emacs-lisp/package.el (package-get-version):
+ * lisp/emacs-lisp/ert-x.el (ert-resource-directory):
+ Use `macroexp-file-name`.
+
+2021-02-24 Ulf Jasper <ulf.jasper@web.de>
+
+ Add options to use feed names from newticker-url-list
+
+ * lisp/net/newst-treeview.el
+ (newsticker-treeview-use-feed-name-from-url-list-in-treeview): New.
+ (newsticker-treeview-use-feed-name-from-url-list-in-itemview): New.
+ (newsticker--treeview-item-show): Show feed name from
+ newsticker-url-list if wanted.
+ (newsticker--treeview-propertize-tag): Add argument 'tooltip'.
+ (newsticker--treeview-tree-get-tag): Usefeed name from
+ newsticker-url-list if wanted. (Fixes third issue in
+ Bug#41376.)
+
+2021-02-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix wisent/python.el grammar warning
+
+ * lisp/cedet/semantic/wisent/python.el: Fix warning about
+ shift/reduce conflicts in the Python grammar.
+
+2021-02-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix warning generated by indian.el + quail.el
+
+ * lisp/leim/quail/indian.el (quail-define-indian-trans-package):
+ Reintroduce kludge to fix automatic detection by Quail.
+
+2021-02-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove the "Documentation:" line from the variable help
+
+ * lisp/help-fns.el (describe-variable): Remove the
+ "Documentation:" line (bug#46702). This makes the help text more
+ compact and seems easier to read, too.
+
+2021-02-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix Calc menu item for vector dot products
+
+ * lisp/calc/calc-menu.el (calc-vectors-menu): Use the correct
+ function `calc-times' instead of the non-existent `calc-mult'
+ function (bug#46710).
+
+2021-02-24 Doug Davis <ddavis@ddavis.io>
+
+ Interactive tag byte compilation functions in emacs-lisp-mode
+
+ * lisp/progmodes/elisp-mode.el (emacs-lisp-byte-compile)
+ (emacs-lisp-byte-compile-and-load): Add interactive tagging
+ (bug#46721).
+
+2021-02-24 Miha Rihtaršič <miha@kamnitnik.top> (tiny change)
+
+ Run all functions in `prefix-command-echo-keystrokes-functions'
+
+ * lisp/simple.el (internal-echo-keystrokes-prefix): Really run all
+ functions in `prefix-command-echo-keystrokes-functions' (bug#46727).
+
+2021-02-24 Protesilaos Stavrou <info@protesilaos.com>
+
+ Use named faces in shortdoc
+
+ * lisp/emacs-lisp/shortdoc.el (shortdoc-heading): Define new face
+ for headings.
+ (shortdoc-display-group): Apply new heading face.
+ (shortdoc--display-function): Use existing face for section text.
+ * etc/NEWS: Document new face (bug#46748).
+
+2021-02-24 Utkarsh Singh <utkarsh190601@gmail.com> (tiny change)
+
+ Use sh-mode for PKGBUILD files
+
+ * lisp/files.el (auto-mode-alist): Use sh-mode for PKGBUILD files
+ (bug#46660).
+
+2021-02-24 Eli Zaretskii <eliz@gnu.org>
+
+ Fix dangerous code in xdisp.c
+
+ * src/xdisp.c (move_it_to, display_line): Make sure ZV_BYTE is
+ greater than 1 before fetching previous byte.
+
+2021-02-24 Eli Zaretskii <eliz@gnu.org>
+
+ Better support for 'truncate-line' non-nil in the mini-window
+
+ * src/xdisp.c (resize_mini_window): Resize the mini-window
+ when multi-line text is displayed under truncate-lines
+ non-nil in the minibuffer. (Bug#46718)
+
+2021-02-24 Protesilaos Stavrou <info@protesilaos.com>
+
+ Specify the Emacs version of new vc-dir faces
+
+ * vc-dir.el (vc-dir-header)
+ (vc-dir-header-value)
+ (vc-dir-directory)
+ (vc-dir-file)
+ (vc-dir-mark-indicator)
+ (vc-dir-status-warning)
+ (vc-dir-status-edited)
+ (vc-dir-status-up-to-date)
+ (vc-dir-status-ignored): Add version 28.1. (Bug#46745)
+
+2021-02-24 Andrea Corallo <akrl@sdf.org>
+
+ Fix async compilation and paramenter naming
+
+ * lisp/emacs-lisp/comp.el (native--compile-async)
+ (native-compile-async): Fix broken parameter renaming.
+
+2021-02-23 Andrea Corallo <akrl@sdf.org>
+
+ Do not emit assumptions referencing clobbered mvars (bug#46670)
+
+ * lisp/emacs-lisp/comp.el (comp-func): Add `vframe-size' slot.
+ (comp-new-frame): Add `vsize' parameter.
+ (comp-limplify-top-level, comp-limplify-function): Update for new
+ `comp-new-frame'.
+ (comp-maybe-add-vmvar): New function.
+ (comp-add-cond-cstrs): Logic update to emit assumptions not
+ referencing clobbered variables.
+ (comp-place-phis, comp-ssa, comp-ssa-rename-insn)
+ (comp-ssa-rename): Update rename logic to rename also negative
+ slots.
+ (comp-fwprop-insn): Update to handle `(assume mvar mvar)' form.
+ * test/src/comp-tests.el (46670-1): Add testcase.
+ * test/src/comp-test-funcs.el (comp-test-46670-1-f)
+ (comp-test-46670-2-f): New functions.
+
+2021-02-23 Andrea Corallo <akrl@sdf.org>
+
+ Move ssa rename from vector to comp-vec
+
+ * lisp/emacs-lisp/comp.el (comp-block): Updated `final-frame' slot
+ type.
+ (comp-limplify): Updated `frame' slot type.
+ (comp-slot-n, comp-new-frame, comp-place-phis, comp-ssa)
+ (comp-ssa-rename-insn, comp-ssa-rename, comp-finalize-phis): Use
+ `comp-vec'.
+
+2021-02-23 Andrea Corallo <akrl@sdf.org>
+
+ Add a simple growable vector like type
+
+ * lisp/emacs-lisp/comp.el (comp-vec): Define struct.
+ (comp-vec-copy, comp-vec-length, comp-vec--verify-idx)
+ (comp-vec-aref, comp-vec-append, comp-vec-prepend): New functions.
+
+2021-02-23 Juri Linkov <juri@linkov.net>
+
+ Small fixes
+
+ * lisp/emacs-lisp/seq.el (seq-contains): Move the ‘declare’ form
+ after the docstring.
+ * lisp/misc.el (copy-from-above-command): Fix whitespace regexp.
+
+2021-02-23 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-line.el (tab-line-tab-name-format-function): New defcustom.
+
+ (tab-line-tab-name-format-default): New function as the default value.
+ (tab-line-format-template): Funcall tab-line-tab-name-format-function.
+ This is like recently added tab-bar-tab-name-format-function.
+
+2021-02-23 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-prefix-map): Bind "n" to 'tab-duplicate'.
+
+ (tab-bar-separator): New function.
+ (tab-bar-make-keymap-1): Use it.
+
+2021-02-23 Ulf Jasper <ulf.jasper@web.de>
+
+ Leave other windows unchanged, use search instead of re-search
+
+ * lisp/net/newst-backend.el (newsticker-customize-feed): Leave other
+ windws unchanged. Use search instead of re-search.
+
+2021-02-23 Ulf Jasper <ulf.jasper@web.de>
+
+ Fix invalid interactive-statement
+
+ * lisp/net/newst-backend.el (newsticker-customize): Fix invalid
+ interactive-statement.
+
+2021-02-23 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * test/: Use lexical-binding the few remaining files
+
+ * test/manual/biditest.el: Use lexical-binding.
+ (biditest-generate-testfile): Remove unused var `levels`.
+
+ * test/manual/image-circular-tests.el: Use lexical-binding.
+
+ * test/manual/image-size-tests.el: Use lexical-binding.
+ (image-size-tests): Check `fboundp` before calling `imagemagick-types`.
+
+ * test/manual/redisplay-testsuite.el: Use lexical-binding.
+
+ * test/manual/cedet/cedet-utests.el: Use lexical-binding.
+ Use `with-current-buffer`.
+ (cedet-utest): Test `fboundp` i.s.o `featurep` to silence warning.
+ (srecode-map-save-file): Declare var.
+ (pulse-test): Test `fboundp` before calling `pulse-available-p`.
+ Declare `pulse-momentary-highlight-overlay` since it's not autoloaded.
+
+ * test/manual/cedet/semantic-tests.el: Use lexical-binding.
+ Use `with-current-buffer`.
+ (semanticdb-ebrowse-dump): Remove unused var `ab`.
+ (semanticdb-test-gnu-global): Don't use obsolete "name" arg to constructor.
+ (cedet-utest-directory): Declare var.
+
+2021-02-23 Ulf Jasper <ulf.jasper@web.de>
+
+ Add command for customizing current newsticker feed
+
+ * lisp/net/newst-backend.el (newsticker-customize-feed): New.
+ (newsticker--insert-bytes): Add documentation string.
+ (newsticker--decode-iso8601-date): Fix documentation string.
+ * lisp/net/newst-treeview.el (newsticker-treeview-customize-current-feed):
+ New.
+ (newsticker-treeview-mode-map): Add key for new command
+ 'newsticker-treeview-customize-current-feed'. (Fixes second issue in
+ Bug#41376.)
+
+2021-02-23 Robert Pluim <rpluim@gmail.com>
+
+ * doc/misc/tramp.texi: Grammar/style fixes
+
+ * doc/misc/tramp.texi (Overview):
+ (Obtaining @value{tramp}):
+ (Quick Start Guide):
+ (Configuration):
+ (Connection types):
+ (Inline methods):
+ (External methods):
+ (Password handling):
+ (Predefined connection information):
+ (Remote shell setup):
+ (Remote processes):
+ (Frequently Asked Questions):
+ (External packages):
+ (Traces and Profiles): Grammar/style fixes.
+
+2021-02-23 Robert Pluim <rpluim@gmail.com>
+
+ * lisp/net/dictionary-connection.el: Grammar fixes
+
+ * lisp/net/dictionary-connection.el: Grammar fix
+ (dictionary-connection-open): Use active voice.
+ (dictionary-connection-status): Reword and improve formatting.
+
+2021-02-23 Robert Pluim <rpluim@gmail.com>
+
+ Make message-mailto work for emacsclient
+
+ * doc/misc/message.texi (System Mailer Setup): Add index entry.
+ Mention option to use emacsclient.
+
+ * etc/NEWS: Mention emacsclient option for 'mailto:' handling.
+
+ * etc/emacs-mail.desktop: Add example using emacsclient.
+
+ * lisp/gnus/message.el (message-mailto): Add optional url argument
+ so we can call it from emacsclient.
+
+2021-02-23 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Fix bug in "state cache" invalidation function.
+
+ * lisp/progmodes/cc-engine.el (c-invalidate-state-cache-1): Rewrite part of
+ it, following the code in c-parse-state-1, to get a proper setting of
+ c-state-cache-good-pos.
+
+2021-02-23 Stefan Kangas <stefan@marxist.se>
+
+ Convert some more menus to easy-menu-define
+
+ * lisp/tar-mode.el (tar-mode-map):
+ * lisp/textmodes/sgml-mode.el (sgml-mode-map, html-mode-map):
+ * lisp/wdired.el (wdired-mode-map): Move menus from here...
+
+ * lisp/tar-mode.el (tar-mode-immediate-menu, tar-mode-mark-menu)
+ * lisp/textmodes/sgml-mode.el (sgml-mode-menu, html-mode-menu):
+ * lisp/wdired.el (wdired-mode-menu): ...to here, and convert to
+ easy-menu-define.
+
+2021-02-23 Stefan Kangas <stefan@marxist.se>
+
+ Improve easymenu.el Commentary section
+
+ * lisp/emacs-lisp/easymenu.el: Improve Commentary section.
+
+2021-02-22 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/antlr-mode.el: Fix bootstrap failure
+
+ (antlr-mode): Remove compatibility code with older CC-mode.
+ This somehow appears to fix the error:
+
+ In antlr-mode:
+ progmodes/antlr-mode.el:2426:20: Error: `c-init-language-vars' defined
+ after use in (c-init-language-vars) (missing `require' of a library
+ file?)
+ progmodes/antlr-mode.el:2427:26: Warning: c-init-language-vars called
+ with 0 arguments, but requires 1
+
+ No idea what caused the error to appear after the previous patch either.
+
+2021-02-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Do mode tagging in decipher.el
+
+ Do mode tagging in bubbles.el
+
+2021-02-22 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/obsolete: Use lexical-binding
+
+ Use lexical-binding in all the lisp/obsolete/*.el files.
+ While at it, removed redundant :group arguments and used #' to quote
+ functions. Commented out the key bindings which the #' revealed
+ to lead to non-existing commands, and replaced those revealed to be obsolete.
+
+ * lisp/obsolete/cl-compat.el: Use cl-lib.
+
+ * lisp/obsolete/cust-print.el: Assume `defalias` exists.
+ (with-custom-print): Use `declare`.
+
+ * lisp/obsolete/iswitchb.el (iswitchb-init-XEmacs-trick)
+ (iswitchb-xemacs-backspacekey): Remove functions.
+
+ * lisp/obsolete/landmark.el (landmark, landmark-nslify-wts):
+ Prefer `apply` to `eval`.
+
+ * lisp/obsolete/longlines.el (longlines-mode): Don't use `add-to-list`
+ on a hook.
+
+ * lisp/obsolete/pgg-gpg.el (pgg-gpg-process-region): Use `clear-string`.
+
+ * lisp/obsolete/pgg-pgp.el (pgg-pgp-encrypt-region): Remove oddly
+ unused var `passphrase`.
+ (pgg-pgp-verify-region): Declare var `jam-zcat-filename-list`.
+
+ * lisp/obsolete/pgg-pgp5.el (pgg-pgp5-encrypt-region): Remove oddly
+ unused var `passphrase`.
+ (pgg-pgp5-verify-region): Declare var `jam-zcat-filename-list`.
+
+ * lisp/obsolete/pgg.el: Remove some XEmacs compatibility code.
+ (pgg-run-at-time, pgg-cancel-timer, pgg-clear-string): Remove functions.
+ Use their core equivalent instead.
+
+ * lisp/obsolete/rcompile.el (remote-compile): Remove unused vars `l`,
+ `l-host`, `l-user`, and `localname`.
+
+ * lisp/obsolete/starttls.el (starttls-any-program-available):
+ Use `define-obsolete-function-alias`.
+
+ * lisp/obsolete/tls.el (tls-format-message): Delete function, use
+ `format-message` instead.
+
+ * lisp/obsolete/url-ns.el (url-ns-prefs): Use `with-current-buffer`
+ and `dlet`.
+
+ * lisp/obsolete/vip.el (vip-escape-to-emacs): Remove unused var `key`.
+ (vip-command-argument, vip-read-string, ex-delete, ex-line): Remove
+ unused var `conditions`.
+ (ex-map): Use a closure instead of `eval`.
+ (ex-set): Make it an alias of `set-variable`.
+ (ex-substitute): Remove unused var `cont`.
+
+ * lisp/obsolete/abbrevlist.el:
+ * lisp/obsolete/bruce.el:
+ * lisp/obsolete/cc-compat.el:
+ * lisp/obsolete/cl-compat.el:
+ * lisp/obsolete/cl.el:
+ * lisp/obsolete/complete.el:
+ * lisp/obsolete/crisp.el:
+ * lisp/obsolete/cust-print.el:
+ * lisp/obsolete/erc-compat.el:
+ * lisp/obsolete/erc-hecomplete.el:
+ * lisp/obsolete/eudcb-ph.el:
+ * lisp/obsolete/fast-lock.el:
+ * lisp/obsolete/gs.el:
+ * lisp/obsolete/gulp.el:
+ * lisp/obsolete/html2text.el:
+ * lisp/obsolete/info-edit.el:
+ * lisp/obsolete/iswitchb.el:
+ * lisp/obsolete/landmark.el:
+ * lisp/obsolete/lazy-lock.el:
+ * lisp/obsolete/longlines.el:
+ * lisp/obsolete/mailpost.el:
+ * lisp/obsolete/mantemp.el:
+ * lisp/obsolete/meese.el:
+ * lisp/obsolete/messcompat.el:
+ * lisp/obsolete/metamail.el:
+ * lisp/obsolete/mouse-sel.el:
+ * lisp/obsolete/nnir.el:
+ * lisp/obsolete/old-emacs-lock.el:
+ * lisp/obsolete/otodo-mode.el:
+ * lisp/obsolete/patcomp.el:
+ * lisp/obsolete/pc-mode.el:
+ * lisp/obsolete/pc-select.el:
+ * lisp/obsolete/pgg-def.el:
+ * lisp/obsolete/pgg-gpg.el:
+ * lisp/obsolete/pgg-parse.el:
+ * lisp/obsolete/pgg-pgp.el:
+ * lisp/obsolete/pgg-pgp5.el:
+ * lisp/obsolete/pgg.el:
+ * lisp/obsolete/rcompile.el:
+ * lisp/obsolete/s-region.el:
+ * lisp/obsolete/sb-image.el:
+ * lisp/obsolete/sregex.el:
+ * lisp/obsolete/starttls.el:
+ * lisp/obsolete/sup-mouse.el:
+ * lisp/obsolete/terminal.el:
+ * lisp/obsolete/tls.el:
+ * lisp/obsolete/tpu-edt.el:
+ * lisp/obsolete/tpu-extras.el:
+ * lisp/obsolete/tpu-mapper.el:
+ * lisp/obsolete/url-ns.el:
+ * lisp/obsolete/vc-arch.el:
+ * lisp/obsolete/vi.el:
+ * lisp/obsolete/vip.el:
+ * lisp/obsolete/ws-mode.el:
+ * lisp/obsolete/yow.el: Use lexical-binding.
+
+2021-02-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention the problems with newlines in Dired
+
+ * doc/emacs/dired.texi (Dired Enter): Mention newlines and what to
+ do about them.
+
+ * lisp/dired.el (dired-listing-switches): Mention newlines
+ (bug#46705).
+
+2021-02-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Buttonize function values in help (and add a blank line)
+
+ * lisp/help-fns.el (describe-variable): Add a newline for better
+ readability (bug#46702). This also has the side effect of
+ buttonizing `function-references-like-this' in the "Its value is"
+ part.
+
+ * lisp/help-mode.el (help-make-xrefs): Adjust comments.
+
+2021-02-22 Andrea Corallo <akrl@sdf.org>
+
+ Revert "* configure.ac: Rename configure nativecomp flags..."
+
+ This reverts commit f6c5f0dd5c8167b6f8f724f42632a4b8808efe7a.
+
+ Reason for this is that I overlooked few other suggestions and this
+ change has to be discussed before a final decision is taken.
+
+2021-02-22 Andrea Corallo <akrl@sdf.org>
+
+ Some clean-up in comp.el
+
+ * lisp/emacs-lisp/comp.el (comp-func): Remove 'array-h'.
+ (comp-spill-lap-function, comp-intern-func-in-ctxt)
+ (comp-spill-lap-function, comp-addr-to-bb-name): Update
+ accordingly.
+
+2021-02-22 Andrea Corallo <akrl@sdf.org>
+
+ * configure.ac: Rename configure nativecomp flags into --with-native-comp.
+
+ Configure now with '--with-native-comp'!
+
+2021-02-22 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/antlr-mode.el: Remove XEmacs compatibility
+
+ (cond-emacs-xemacs, cond-emacs-xemacs-macfn, defunx, ignore-errors-x):
+ Remove those functions and macros. Replace every use with the result
+ of their use.
+ (antlr-default-directory): Remove function, use the `default-directory`
+ variable instead.
+ (antlr-read-shell-command): Remove function, use
+ `read-shell-command` instead.
+ (antlr-with-displaying-help-buffer): Remove function, by inlining it at
+ its only call site.
+ (antlr-end-of-rule, antlr-beginning-of-rule, antlr-end-of-body)
+ (antlr-beginning-of-body): Mark them as movement commands.
+
+2021-02-22 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: 'C-x t N' bound to tab-new-to supports a negative argument
+
+ * lisp/tab-bar.el (tab-bar-new-tab-to): Negative TO-INDEX counts
+ tabs from the end of the tab bar.
+ (tab-bar-new-tab): Fix docstring to add reference to
+ 'tab-bar-new-tab-to'.
+ (tab-prefix-map): Bind "N" to tab-new-to.
+
+2021-02-22 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: 'C-x t M' bound to tab-move-to supports a negative argument
+
+ * lisp/tab-bar.el (tab-bar-move-tab-to): Negative TO-INDEX counts
+ tabs from the end of the tab bar.
+ (tab-bar-move-tab): Fix docstring to add reference to tab-bar-move-tab-to.
+ (tab-prefix-map): Bind "M" to tab-move-to.
+
+2021-02-22 Juri Linkov <juri@linkov.net>
+
+ 'Mod-9' bound to 'tab-last' now switches to the last tab like in web browsers
+
+ * lisp/tab-bar.el (tab-bar--define-keys): Rebind 0 from
+ tab-bar-switch-to-recent-tab to its alias tab-recent.
+ Bind 9 to tab-last.
+ (tab-bar-switch-to-last-tab): New command.
+ (tab-last): New alias to tab-bar-switch-to-last-tab.
+ (tab-bar-switch-to-tab, tab-bar-undo-close-tab): Fix docstrings to
+ avoid mentioning the term "last" for "most recently used" meaning.
+
+2021-02-22 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar--undefine-keys): New function from tab-bar-mode.
+
+2021-02-22 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Prefer `declare` over a `put` of `list-indent-function`.
+
+ While at it, I enabled lexical-binding in the affected files.
+
+ * lisp/cedet/semantic/sb.el: Enable lexical-binding.
+ (semantic-sb-with-tag-buffer): Use `declare`.
+
+ * lisp/cedet/semantic/bovine/el.el: Enable lexical-binding.
+ (semantic-elisp-setup-form-parser): Use `declare`.
+
+ * lisp/emacs-lisp/ert.el:
+ * lisp/emacs-lisp/ert-x.el: Remove redundant `put`.
+
+ * lisp/emulation/cua-rect.el: Enable lexical-binding.
+ (cua--rectangle-operation, cua--rectangle-aux-replace): Use `declare`.
+
+ * lisp/mh-e/mh-acros.el: Enable lexical-binding.
+ (mh-do-in-gnu-emacs, mh-do-in-xemacs, mh-funcall-if-exists, defun-mh)
+ (defmacro-mh, with-mh-folder-updating, mh-in-show-buffer)
+ (mh-do-at-event-location, mh-iterate-on-messages-in-region)
+ (mh-iterate-on-range): Use `declare`.
+
+ * lisp/mh-e/mh-compat.el: Enable lexical-binding.
+ (mh-flet): Use `declare`.
+
+ * lisp/mh-e/mh-e.el: Enable lexical-binding.
+ (defgroup-mh, defcustom-mh, defface-mh): Use `declare`.
+
+ * lisp/net/sieve.el: Enable lexical-binding. Remove redundant :group args.
+ (sieve-activate, sieve-remove, sieve-edit-script): Remove unused arg
+ from the interactive spec.
+ (sieve-deactivate-all): Remove unused var `name`.
+ (sieve-change-region): Use `declare`.
+
+ * lisp/obsolete/fast-lock.el: Enable lexical-binding.
+ Remove redundant :group args. Remove XEmacs compat code.
+ (save-buffer-state): Remove macro.
+ (fast-lock-add-properties): Use `with-silent-modifications` instead.
+
+ * lisp/obsolete/lazy-lock.el: Enable lexical-binding.
+ Remove redundant :group args.
+ (do-while): Use `declare`.
+ (save-buffer-state): Remove macro.
+ (lazy-lock-fontify-rest-after-change, lazy-lock-defer-line-after-change)
+ (lazy-lock-defer-rest-after-change, lazy-lock-after-fontify-buffer)
+ (lazy-lock-after-unfontify-buffer, lazy-lock-fontify-region):
+ Use `with-silent-modifications` instead.
+
+ * lisp/obsolete/pgg.el: Enable lexical-binding. Remove XEmacs compat code.
+ (pgg-save-coding-system, pgg-as-lbt, pgg-process-when-success):
+ Use `declare`.
+ (pgg-add-passphrase-to-cache): Remove unused var `new-timer`.
+ (pgg-decrypt-region): Remove unused var `buf`.
+
+ * lisp/org/org-agenda.el (org-let, org-let2): Move from org-macs and
+ use `declare`.
+
+ * lisp/org/org-macs.el (org-let, org-let2): Move these functions that
+ are inherently harmful to your karma to the only package that uses them.
+ (org-scroll): Use `pcase` to avoid `eval` and use more readable syntax
+ for those integers standing for events.
+
+ * lisp/progmodes/antlr-mode.el: Enable lexical-binding.
+ (save-buffer-state-x): Use `declare` and `with-silent-modifications`.
+
+ * lisp/international/mule-util.el (with-coding-priority):
+ * lisp/cedet/ede/proj-comp.el (proj-comp-insert-variable-once):
+ * lisp/org/org-element.el (org-element-map):
+ * test/lisp/emacs-lisp/bytecomp-tests.el (test-byte-comp-compile-and-load):
+ * test/lisp/emacs-lisp/generator-tests.el (cps-testcase): Use `declare`.
+
+2021-02-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix ANSI coloring problem in large outputs in eshell
+
+ * lisp/ansi-color.el (ansi-color-apply-on-region): Ensure that we
+ fontize from where we left off, and don't skip to the end of the
+ region (bug#46332).
+
+2021-02-22 Julian Scheid <julians37@gmail.com>
+
+ cl-extra: Fix docstring retrieval
+
+ * lisp/emacs-lisp/cl-extra.el (cl--describe-class-slots): Fix
+ docstring retrieval (bug#46662).
+
+2021-02-22 Robert Pluim <rpluim@gmail.com>
+
+ Skip tests that require Internet when there's no Internet
+
+ Bug#46641
+
+ The network-stream-tests actually work fine when the local machine has
+ no IP at all, but cause a crash in the GnuTLS library when there is an
+ IP configured but the interface is down.
+
+ * test/lisp/net/network-stream-tests.el (internet-is-working): New
+ defvar, checks if we can resolve "google.com".
+ (connect-to-tls-ipv4-nowait, connect-to-tls-ipv6-nowait)
+ (open-network-stream-tls-nowait, open-gnutls-stream-new-api-nowait)
+ (open-gnutls-stream-old-api-nowait): Use it to check for working
+ Internet access.
+
+ * test/src/process-tests.el (internet-is-working): New defvar, checks
+ if we can resolve "google.com".
+ (lookup-family-specification, lookup-unicode-domains)
+ (unibyte-domain-name, lookup-google, non-existent-lookup-failure): Use
+ it to check for working Internet access.
+
+2021-02-22 Robert Pluim <rpluim@gmail.com>
+
+ Fix hang when running dns-query with no working internet
+
+ * lisp/net/dns.el (dns-set-servers): reduce the timeout and retry
+ count when using 'nslookup' for "localhost".
+ (dns-query): Check to see if we actually managed to initiate a dns
+ request before starting a busy-wait for the result.
+
+2021-02-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Simplify comint-watch-for-password-prompt
+
+ * lisp/comint.el (comint-watch-for-password-prompt): Simplify by
+ using `string-trim'.
+
+2021-02-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix prompt for the `M-S-x' command
+
+ * lisp/simple.el (read-extended-command): Further kludge the
+ hard-coded "M-x" prompt for the new `M-S-x' command.
+
+2021-02-22 Andrea Corallo <akrl@sdf.org>
+
+ Don't use paths to indicate filenames
+
+ * lisp/emacs-lisp/comp.el (native--compile-async)
+ (native-compile-async): Replace `paths' argname with `files'.
+
+2021-02-22 Andrea Corallo <akrl@sdf.org>
+
+ Fix union constraint for mixed pos/neg constraints
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-union-1-no-mem): Fix neg
+ type shadowing pos values.
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Add testcase.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Fix testcase.
+
+2021-02-22 Stefan Kangas <stefan@marxist.se>
+
+ Prefer mailing lists to newsgroups in FAQ
+
+ * doc/misc/efaq.texi (Real meaning of copyleft)
+ (Guidelines for mailing list postings, Mailing list archives)
+ (Packages that do not come with Emacs): Prefer mailing lists to
+ newsgroups. (Bug#46633)
+
+2021-02-22 Stefan Kangas <stefan@marxist.se>
+
+ Improve wrong number of args error message in propertize
+
+ * src/editfns.c (Fpropertize): Improve error message.
+ (syms_of_editfns) <Qpropertize>: New DEFSYM.
+ * test/src/editfns-tests.el
+ (propertize/error-wrong-number-of-args): New test.
+
+2021-02-22 Mattias Engdegård <mattiase@acm.org>
+
+ Fix compilation of closures with nontrivial doc strings
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-make-closure):
+ Use the supplied doc string if it's a literal; fall back to the old
+ slow way of building a closure otherwise.
+
+2021-02-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up previous conf-mode.el and nroff-mode.el change slightly
+
+ * lisp/textmodes/conf-mode.el (conf-mode-map): Remove variable now
+ unused.
+
+ * lisp/textmodes/nroff-mode.el (nroff-mode-map): Remove variable
+ now unused.
+
+2021-02-22 Glenn Morris <rgm@gnu.org>
+
+ * test/misc/test-custom-libs.el (test-custom-libs): Skip on hydra.
+
+ * test/misc/test-custom-noloads.el (custom-test-load): Unstable.
+
+2021-02-22 Stefan Kangas <stefan@marxist.se>
+
+ Convert some textmodes menus to easy-menu-define
+
+ * lisp/textmodes/artist.el (artist-menu-map): Convert menu definition
+ to easy-menu-define.
+
+ * lisp/textmodes/conf-mode.el (conf-mode-map):
+ * lisp/textmodes/nroff-mode.el (nroff-mode-map): Move menu
+ definition from here...
+ * lisp/textmodes/conf-mode.el (conf-mode-menu):
+ * lisp/textmodes/nroff-mode.el (nroff-mode-menu): ...to here, and
+ convert to use easy-menu-define.
+
+2021-02-21 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-spill-lap): Fix doc string.
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2021-02-21 Mattias Engdegård <mattiase@acm.org>
+
+ Faster, more compact, and readable closure creation
+
+ Simplify closure creation by calling a single function at run time
+ instead of putting it together from small pieces. This is faster
+ (by about a factor 2), takes less space on disk and in memory, and
+ makes internal functions somewhat readable in disassembly listings again.
+
+ This is done by creating a prototype function at compile-time whose
+ closure variables are placeholder values V0, V1... which can be seen
+ in the disassembly. The prototype is then cloned at run time using
+ the new make-closure function that replaces the placeholders with
+ the actual closure variables.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-make-closure):
+ Generate call to make-closure from a prototype function.
+ * src/alloc.c (Fmake_closure): New function.
+ (syms_of_alloc): Defsubr it.
+ * src/data.c (syms_of_data): Defsym byte-code-function-p.
+
+2021-02-21 Stefan Kangas <stefan@marxist.se>
+
+ Run admin/cus-tests.el tests from test suite
+
+ * test/Makefile.in (SUBDIRS): Run tests in new directory "misc",
+ intended for tests not belonging to any one file.
+ * test/misc/test-custom-deps.el:
+ * test/misc/test-custom-libs.el:
+ * test/misc/test-custom-noloads.el:
+ * test/misc/test-custom-opts.el: New files.
+ * test/lisp/custom-tests.el (custom--test-local-option): Move test to
+ above new file test-custom-opts.el.
+
+ * admin/cus-test.el: Document running tests from regular test suite.
+ * test/file-organization.org (Test Files): Document new test directory
+ "misc" for tests not belonging to any one file.
+
+2021-02-21 Stefan Kangas <stefan@marxist.se>
+
+ Fix interactive mode tagging for man and woman
+
+ * lisp/man.el (man-common): New mode inheriting special-mode.
+ (Man-mode):
+ * lisp/woman.el (woman-mode): Inherit from man-common.
+
+ * lisp/man.el (man-follow, Man-update-manpage)
+ (Man-fontify-manpage, Man-cleanup-manpage, Man-next-section)
+ (Man-previous-section, Man-goto-section)
+ (Man-goto-see-also-section, Man-follow-manual-reference)
+ (Man-kill, Man-goto-page, Man-next-manpage)
+ (Man-previous-manpage): Change interactive mode tag to man-common.
+
+ This was discussed in:
+ https://lists.gnu.org/r/emacs-devel/2021-02/msg01619.html
+
+2021-02-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Declare that `ignore' and `undefined' shouldn't be completed over
+
+ * lisp/subr.el (ignore, undefined): Declare that these shouldn't
+ be completed over.
+
+2021-02-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use `undefined' instead of `ignore' in wdired
+
+ * lisp/wdired.el (wdired-mode-map): Use `undefined' here instead
+ of `ignore' to give the user more feedback.
+
+2021-02-21 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix json.el encoding of confusable object keys
+
+ * lisp/json.el (json-encode-string): Clarify commentary.
+ (json--encode-stringlike): New function that covers a subset of
+ json-encode.
+ (json-encode-key): Use it for more efficient encoding and
+ validation, and to avoid mishandling confusable keys like boolean
+ symbols (bug#42545).
+ (json-encode-array): Make it clearer that argument can be a list.
+ (json-encode): Reuse json-encode-keyword and json--encode-stringlike
+ for a subset of the dispatch logic.
+ (json-pretty-print): Ensure confusable keys like ":a" survive a
+ decoding/encoding roundtrip (bug#24252, bug#45032).
+
+ * test/lisp/json-tests.el (test-json-encode-string)
+ (test-json-encode-hash-table, test-json-encode-alist)
+ (test-json-encode-plist, test-json-pretty-print-object): Test
+ encoding of confusable keys.
+
+2021-02-21 Stefan Kangas <stefan@marxist.se>
+
+ Make unused variable menu-bar-handwrite-map obsolete
+
+ * lisp/play/handwrite.el (menu-bar-handwrite-map): Make unused
+ variable obsolete.
+
+2021-02-21 Stefan Kangas <stefan@marxist.se>
+
+ Convert bubbles menu to easy-menu-define
+
+ * lisp/play/bubbles.el (bubbles-game-theme-menu)
+ (bubbles-graphics-theme-menu, bubbles-menu, bubbles-mode-map):
+ Move menu definition from here...
+ (bubbles-menu): ...to here, and convert to easy-menu-define.
+
+2021-02-21 Stefan Kangas <stefan@marxist.se>
+
+ * etc/NEWS.19: Add entry for 'easy-menu-define'.
+
+2021-02-21 Stefan Kangas <stefan@marxist.se>
+
+ Convert some progmodes menus to easy-menu-define
+
+ * lisp/progmodes/asm-mode.el (asm-mode-map):
+ * lisp/progmodes/grep.el (grep-mode-map):
+ * lisp/progmodes/m4-mode.el (m4-mode-map):
+ * lisp/progmodes/sh-script.el (sh-mode-map): Move menu definition from here...
+ * lisp/progmodes/asm-mode.el (asm-mode-menu):
+ * lisp/progmodes/grep.el (grep-menu-map):
+ * lisp/progmodes/m4-mode.el (m4-mode-menu):
+ * lisp/progmodes/sh-script.el (sh-mode-menu): ...to here, and rewrite
+ using easy-menu-define.
+
+2021-02-21 Michael Albinus <michael.albinus@gmx.de>
+
+ Clarification of password handling in Tramp manual
+
+ * doc/misc/tramp.texi (Password handling): Describe, how to
+ suppress `auth-sources' for Tramp.
+ (Remote shell setup, Remote processes)
+ (Cleanup remote connections, Frequently Asked Questions):
+ Handle reference to Emacs manual.
+
+2021-02-20 Alan Third <alan@idiocy.org>
+
+ Fix memory leak
+
+ * src/nsterm.m ([EmacsSurface dealloc]): Release will remove all
+ objects and free the memory.
+
+2021-02-20 Stefan Kangas <stefan@marxist.se>
+
+ Convert makefile-mode menu to easy-menu-define
+
+ * lisp/progmodes/make-mode.el (makefile-mode-map): Move menu
+ definition from here...
+ (makefile-mode-menu): ...to here, and rewrite using easy-menu-define.
+
+2021-02-20 F. Jason Park <jp@neverwas.me>
+
+ Mute noisy test fixture for socks.el
+
+ * test/lisp/net/socks-tests.el:
+ (socks-tests-perform-hello-world-http-request): Bind
+ 'inhibit-message' non-nil when in batch mode.
+ (Bug#46342)
+
+2021-02-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Change command-completion-using-modes-p to defun
+
+ * lisp/simple.el (command-completion-using-modes-p): Change into a
+ defun for now because of a build problem.
+
+2021-02-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention `M-S-x' in the Emacs manual.
+
+ * doc/emacs/m-x.texi (M-x): Mention `M-S-x' in the Emacs manual.
+
+2021-02-20 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/help.el (help-for-help-internal): Doc fix; use imperative.
+
+2021-02-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new command for mode-specific commands
+
+ * doc/lispref/commands.texi (Interactive Call): Document it.
+ * lisp/simple.el (command-completion-using-modes-p): Refactored
+ out into its own function for reuse...
+ (command-completion-default-include-p): ... from here.
+ (execute-extended-command-for-buffer): New command and keystroke
+ (`M-S-x').
+
+2021-02-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Change how (declare (modes store the data
+
+ * lisp/emacs-lisp/byte-run.el (byte-run--set-modes): Change from
+ being a predicate to storing the modes. This allows using the
+ modes for positive command discovery, too.
+ * src/data.c (Fcommand_modes): Look at the `command-modes' symbol
+ property, too.
+
+2021-02-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add the `always' function
+
+ * doc/lispref/functions.texi (Calling Functions): Document it.
+ * lisp/subr.el (always): New function.
+
+ * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Mark it as
+ side effect free.
+
+2021-02-20 F. Jason Park <jp@neverwas.me>
+
+ Use raw bytes for SOCKS 4 IP addresses
+
+ * lisp/net/socks.el: (socks--open-network-stream, socks-send-command):
+ * test/lisp/net/socks-tests.el: (socks-tests-v4-basic): (Bug#46342).
+
+2021-02-20 F. Jason Park <jp@neverwas.me>
+
+ Add more auth-related tests for socks.el
+
+ * test/lisp/net/socks-tests.el (auth-registration-and-suite-offer)
+ (filter-response-parsing-v4, filter-response-parsing-v5): Assert
+ auth-method selection wrangling and socks-filter parsing.
+ (v5-auth-user-pass, v5-auth-user-pass-blank, v5-auth-none): Show prep
+ and execution of the SOCKS connect command and proxying of an HTTP
+ request; simplify fake server. (Bug#46342)
+
+2021-02-20 Stefan Kangas <stefan@marxist.se>
+
+ Convert re-builder menu to easy-menu-define
+
+ * lisp/emacs-lisp/re-builder.el (reb-mode-map): Move menu
+ definition from here...
+ (reb-mode-menu): ...to here, and rewrite using easy-menu-define.
+
+2021-02-20 Stefan Kangas <stefan@marxist.se>
+
+ Convert finder menu to easy-menu-define
+
+ * lisp/finder.el (finder-mode-map): Move menu definition from
+ here...
+ (finder-mode-menu): ...to here, and rewrite using
+ easy-menu-define.
+
+2021-02-20 Stefan Kangas <stefan@marxist.se>
+
+ Add toolbar for help-mode
+
+ * lisp/help-mode.el (help-mode): Add toolbar.
+ (help-mode-tool-bar-map): New variable.
+ (help-mode-menu): Disable forward/backward items when stack is empty.
+
+ (help-bookmark-make-record, help-bookmark-jump): Minor doc fixes.
+
+2021-02-20 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/woman.el: Doc fix; remove redundant setup info.
+
+2021-02-19 Thomas Fitzsimmons <fitzsim@fitzsim.org>
+
+ * lisp/url/url-http.el (url-http): Fix docstring typo.
+
+2021-02-19 Thomas Fitzsimmons <fitzsim@fitzsim.org>
+
+ ntlm-tests: Remove missing dependency warnings
+
+ * test/lisp/net/ntlm-tests.el: Remove warnings about dependencies
+ not being present.
+
+2021-02-19 Thomas Fitzsimmons <fitzsim@fitzsim.org>
+ Michael Albinus <michael.albinus@gmx.de>
+
+ ntlm-tests: Skip tests if dependencies are too old
+
+ * test/lisp/net/ntlm-tests.el (ntlm-tests--dependencies-present):
+ Add version and functionality checks.
+
+2021-02-19 Andrea Corallo <akrl@sdf.org>
+
+ Work around bug#46495 (GCC PR99126)
+
+ * src/comp.c (gcc_jit_context_add_command_line_option): Import for
+ dynamic load.
+ (Fcomp__compile_ctxt_to_file): Disable GCC "isolate-paths" on GCC
+ 10.
+
+2021-02-19 Andrea Corallo <akrl@sdf.org>
+
+ Remove unnecessary function 'emit_rvalue_from_unsigned_long_long'
+
+ * src/comp.c (emit_rvalue_from_unsigned_long_long): Remove
+ function.
+ (emit_rvalue_from_emacs_uint, emit_rvalue_from_lisp_word_tag)
+ (emit_rvalue_from_lisp_word): Make use of
+ 'emit_rvalue_from_long_long'.
+
+2021-02-19 Andrea Corallo <akrl@sdf.org>
+
+ Pacify GCC warning on non wide-int configurations
+
+ * src/comp.c (emit_rvalue_from_emacs_uint)
+ (emit_rvalue_from_lisp_word_tag): Pacify GCC warning.
+ (emit_rvalue_from_unsigned_long_long): Define it only when
+ necessary.
+
+2021-02-19 Alan Third <alan@idiocy.org>
+
+ Fix frame contents scaling bug on macOS (bug#46155)
+
+ Discussion in bug#46406.
+
+ * src/nsterm.m ([EmacsView focusOnDrawingBuffer:]): Set the scale
+ factor for the backing layer.
+
+2021-02-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/bytecomp.el: Don't warn for repeated _ args
+
+ (byte-compile-check-lambda-list): Skip warnings of repeated arg for
+ those that are declared as unused anyway.
+
+2021-02-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * test/lisp/emacs-lisp/edebug-tests.el: Adjust to new `edebug-eval-defun`.
+
+ (edebug-tests-trivial-backquote): Adjust to the way `eval-defun`
+ outputs its result.
+ (edebug-tests-cl-macrolet): Adjust to the fact that now macro expansion
+ takes place during the `eval-defun` even when Edebugging.
+
+2021-02-19 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 8e8b46ef81 (origin/emacs-27) More accurate documentation of the "r" i...
+ dcb2015a5b Mention the GNU Kind Communications Guidelines in the FAQ
+ 9882e63eea ; * CONTRIBUTE: Another wording change regarding tiny chan...
+ 850f18ef23 Allow newlines in password prompts again in comint
+ c977370dd7 Avoid point movement when visiting image files
+ da64a257a4 ; * CONTRIBUTE: Yet another clarification of significant c...
+ d03f2a6ee9 Avoid assertion violation in callproc.c
+ dcc00bbb19 ; * CONTRIBUTE: Clarify the "15-lines" rule a bit more.
+
+2021-02-19 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 4712c75ab8 Clarify when activate-mark-hook is run
+ abedf3a865 Fix language-environment and font selection on MS-Windows
+ 8b8708eadd Fix example in Sequence Functions node in the manual
+
+2021-02-19 Ulf Jasper <ulf.jasper@web.de>
+
+ Enable newsticker--group-shift-feed-(up|down) to move groups as well
+
+ Fix broken newsticker--group-shift-group-(up-down).
+
+ * lisp/net/newst-treeview.el (newsticker-treeview-jump): Change prompt
+ string.
+ (newsticker--group-shift): Move the group when a group is currently
+ selected. Fix error when explicitly shifting a group. (Fixes first
+ issue in Bug#41376.)
+
+2021-02-19 Eli Zaretskii <eliz@gnu.org>
+
+ More accurate documentation of the "r" interactive spec
+
+ * doc/lispref/commands.texi (Interactive Codes): Describe the
+ effect of 'mark-even-if-inactive'.
+
+2021-02-19 Mattias Engdegård <mattiase@acm.org>
+
+ Fix regexp mistakes
+
+ * lisp/progmodes/cperl-mode.el (cperl--package-regexp):
+ Avoid double repetition; cperl--ws-or-comment-regexp is already
+ repeated with 1+.
+ * test/lisp/textmodes/dns-mode-tests.el
+ (dns-mode-tests-dns-mode-soa-increment-serial): Escape literal '$'.
+ * test/lisp/emacs-lisp/rx-tests.el (rx-regexp): Modify test to not
+ trigger a linting warning while retaining its testing power.
+
+2021-02-19 Stefan Kangas <stefan@marxist.se>
+
+ Mention the GNU Kind Communications Guidelines in the FAQ
+
+ * doc/misc/efaq.texi (Guidelines for newsgroup postings): Mention
+ the GNU Kind Communications Guidelines.
+
+2021-02-19 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/calculator.el: Minor doc fix. Remove redundant :group args.
+
+2021-02-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Tramp bug#46625
+
+ * test/lisp/net/tramp-tests.el (tramp-test33-environment-variables):
+ Adapt test. (Bug#46625)
+
+2021-02-19 Stefan Kangas <stefan@marxist.se>
+
+ Do interactive mode tagging for snake.el
+
+ Do interactive mode tagging for tetris.el
+
+ Do interactive mode tagging for man.el
+
+ Do interactive mode tagging for package.el
+
+2021-02-19 Thomas Fitzsimmons <fitzsim@fitzsim.org>
+
+ Implement NTLM server for ntlm.el testing
+
+ * test/Makefile.in
+ (GNU_ELPA_DIRECTORY, elpa_dependencies, elpa_els, elpa_opts): New
+ variables.
+ (EMACSOPT, ert_opts): Add elpa_opts.
+ * test/README: Document GNU_ELPA_DIRECTORY make variable.
+ * test/lisp/net/ntlm-tests.el: Fix checkdoc-reported issues.
+ (ntlm-tests-message, ntlm-server-build-type-2, ntlm-server-hash)
+ (ntlm-server-check-authorization, ntlm-server-do-token)
+ (ntlm-server-filter, ntlm-server-handler, ntlm-server-start)
+ (ntlm-server-stop, ntlm-tests--url-retrieve-internal-around)
+ (ntlm-tests--authenticate)
+ (ntlm-tests--start-server-authenticate-stop-server): New
+ functions.
+ (ntlm-tests--username-oem, ntlm-tests--username-unicode)
+ (ntlm-tests--client-supports-unicode, ntlm-tests--challenge)
+ (ntlm-tests--result-buffer, ntlm-tests--successful-result): New
+ variables.
+ (ntlm-authentication)
+ (ntlm-authentication-old-compatibility-level): New tests.
+ * test/lisp/net/ntlm-resources/authinfo: New file. (Bug#43566)
+
+2021-02-18 Andrea Corallo <akrl@sdf.org>
+
+ * src/pdumper.c (dump_do_dump_relocation): Use emacs_fopen + ENCODE_FILE.
+
+ * src/emacs.c (syms_of_emacs): Add a FIXME for Windows native-comp.
+
+2021-02-18 Andrea Corallo <akrl@sdf.org>
+
+ Add a bunch of assertions for fixnums coming from Lisp later used as int
+
+ * src/comp.c (emit_limple_insn, declare_lex_function)
+ (compile_function, Fcomp__compile_ctxt_to_file): Add some
+ assertion.
+
+2021-02-18 Andrea Corallo <akrl@sdf.org>
+
+ Add assertion guarding against emitting a relocation array overflow
+
+ * src/comp.c (reloc_array_t): New type.
+ (comp_t, imm_reloc_t): Make use of 'reloc_array_t'.
+ (obj_to_reloc): Add an assertion not to overflow relocation
+ arrays.
+ (emit_lisp_obj_reloc_lval, emit_limple_insn)
+ (declare_imported_data_relocs): Make use of 'reloc_array_t'.
+
+2021-02-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/bindat.el: Tweak example in comment
+
+ Suggested by Kim Storm <storm@cua.dk>.
+
+2021-02-18 Mattias Engdegård <mattiase@acm.org>
+
+ Fix typos
+
+ * doc/lispref/display.texi (Size of Displayed Text):
+ * doc/lispref/windows.texi (Buffer Display Action Functions):
+ * etc/NEWS:
+ * etc/ORG-NEWS (Org-Attach has been refactored and extended):
+ * lisp/battery.el (display-battery-mode, battery--upower-subsribe):
+ * lisp/calendar/parse-time.el:
+ * lisp/dired-x.el:
+ * lisp/emacs-lisp/chart.el (chart-sequece, chart-bar-quickie):
+ * lisp/emacs-lisp/eldoc.el (eldoc-echo-area-use-multiline-p)
+ (eldoc-documentation-strategy):
+ * lisp/emacs-lisp/pcase.el (pcase--split-pred, pcase--u1):
+ * lisp/gnus/gnus-search.el (gnus-search-expandable-keys)
+ (gnus-search-parse-query, gnus-search-query-return-string)
+ (gnus-search-imap, gnus-search-imap-search-command)
+ (gnus-search-transform-expression):
+ * lisp/gnus/nnselect.el:
+ * lisp/isearch.el (isearch-lazy-count-format):
+ * lisp/mh-e/mh-show.el (mh-show-msg):
+ * lisp/net/dictionary-connection.el (dictionary-connection-open):
+ * lisp/net/dictionary.el (dictionary-default-popup-strategy)
+ (dictionary, dictionary-split-string, dictionary-do-select-dictionary)
+ (dictionary-display-dictionarys, dictionary-search)
+ (dictionary-tooltip-mode):
+ * lisp/net/eudcb-macos-contacts.el (eudc-macos-contacts-set-server):
+ * lisp/net/mailcap.el (mailcap-mime-data):
+ * lisp/net/tramp-smb.el (tramp-smb-maybe-open-connection):
+ * lisp/nxml/nxml-mode.el (nxml-mode):
+ * lisp/progmodes/cc-engine.el:
+ * lisp/progmodes/cperl-mode.el (cperl-mode)
+ (cperl-fontify-syntaxically):
+ * lisp/progmodes/flymake.el (flymake-diagnostic-functions):
+ * lisp/progmodes/verilog-mode.el (verilog--supressed-warnings)
+ (verilog-preprocess):
+ * lisp/simple.el (self-insert-uses-region-functions):
+ * lisp/textmodes/bibtex.el (bibtex-copy-summary-as-kill):
+ * lisp/textmodes/texnfo-upd.el (texinfo-insert-master-menu-list):
+ * src/dispnew.c:
+ * src/font.c (Ffont_get):
+ * src/indent.c (compute_motion):
+ * src/process.c (init_process_emacs):
+ * src/w32fns.c (deliver_wm_chars):
+ * test/lisp/jsonrpc-tests.el (deferred-action-complex-tests):
+ Fix typos in documentation, comments, and internal identifiers.
+
+2021-02-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/edebug.el (eval-defun): Simplify
+
+ (edebug-all-defs, edebug-all-forms): Don't autoload since the problem
+ it was working around has been fixed a while back.
+ (edebug--eval-defun): Rename from `edebug-eval-defun` and simplify by
+ making it an `:around` advice.
+ (edebug-install-read-eval-functions)
+ (edebug-uninstall-read-eval-functions): Adjust accordingly.
+ (edebug-eval-defun): Redefine as an obsolete wrapper.
+
+ * lisp/progmodes/elisp-mode.el (elisp--eval-defun):
+ Use `load-read-function` so it obeys `edebug-all-(defs|forms)`.
+ (elisp--eval-defun): Fix recent regression introduced with
+ `elisp--eval-defun-result`.
+
+2021-02-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Do interactive mode tagging for python.el navigation functions."
+
+ This reverts commit 546f552e7b2439b482c7d28222fb88761a9c876a.
+
+ This is a "core package", so can't use the new syntax.
+
+2021-02-18 Ryan Prior <rprior@protonmail.com> (tiny change)
+
+ Allow newlines in password prompts again in comint
+
+ * lisp/comint.el (comint-password-prompt-regexp): Match all
+ whitespace (including newline) at the end of the passphrase, not
+ just space and \t (bug#46609).
+ (comint-watch-for-password-prompt): Remove trailing newlines from
+ the prompt (bug#46609).
+
+2021-02-18 Doug Davis <ddavis@ddavis.io> (tiny change)
+
+ Do interactive mode tagging for python.el navigation functions.
+
+ * lisp/progmodes/python.el (navigation functions): Add python-mode to
+ `interactive' declarations for mode-specific commands (bug#46610).
+
+2021-02-18 Mattias Engdegård <mattiase@acm.org>
+
+ Fix rx `regexp` form with deprecated syntax
+
+ The argument of the rx `regexp` form is assumed to evaluate to a valid
+ regexp, but certain kinds of deprecated but still accepted usage were
+ not handled correctly, such as unescaped literal (special) characters:
+ (rx "a" (regexp "*")) => "a*" which is wrong.
+ Handle these cases; there is no extra trouble.
+
+ * lisp/emacs-lisp/rx.el (rx--translate-regexp): Force bracketing
+ of single special characters.
+ * test/lisp/emacs-lisp/rx-tests.el (rx-regexp): Add test case.
+
+2021-02-18 Dmitry Gutov <dgutov@yandex.ru>
+
+ Move 'project-try-ede' to the back of 'project-find-functions'
+
+ * lisp/cedet/ede.el (project-find-functions):
+ Move 'project-try-ede' further back, so that 'project-try-vc' has
+ priority (bug46202).
+
+2021-02-18 Dmitry Gutov <dgutov@yandex.ru>
+
+ Present C source files as absolute file names too when possible
+
+ * lisp/progmodes/elisp-mode.el (xref-location-group):
+ Present C source files as absolute file names too when possible
+ (bug#46514).
+
+2021-02-17 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix recent Command Modes changes in Elisp manual
+
+ * doc/lispref/commands.texi (Command Modes): Fix typos and grammar.
+ Cross-reference the 'declare' form node.
+
+2021-02-17 Matt Armstrong <matt@rfc20.org>
+
+ doc/lispref/commands.texi (Command Modes): Fix typo.
+
+ * doc/lispref/commands.texi (Command Modes): Fix typo.
+
+2021-02-17 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into native-comp
+
+2021-02-17 Alan Mackenzie <acm@muc.de>
+
+ Make goto-line-history buffer local only when so customized
+
+ * lisp/simple.el (goto-line-history-local): New customizable option.
+ (goto-line-history): Define this simply with defvar, not defvar-local.
+ (goto-line-read-args): Handle goto-line-history-local, and changes to it.
+
+ * doc/emacs/basic.texi (Moving Point): Add a paragraph about
+ goto-line-history-local.
+
+ * etc/NEWS: Add an item under "Editing Changes in Emacs 28.1".
+
+2021-02-17 Andrea Corallo <akrl@sdf.org>
+
+ Fix inverted logic in constraint comparison (bug#46540)
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr->, comp-cstr->=)
+ (comp-cstr-<, comp-cstr-<=): Fix inverted logic.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add
+ three integer constrain tests.
+
+2021-02-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust the edebug spec for `interactive'
+
+ * lisp/emacs-lisp/edebug.el: Adjust the edebug spec for
+ `interactive' for the new syntax.
+
+2021-02-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make unused `Buffer-menu-sort' alias obsolete
+
+ * lisp/buff-menu.el (Buffer-menu-sort): Make unused alias obsolete.
+ * test/lisp/progmodes/elisp-mode-tests.el
+ (find-defs-defalias-defun-el): Adjust test to use an alias that's
+ not obsolete.
+
+2021-02-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mark up commands in buff-menu.el for modes
+
+2021-02-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Explicate on how to tag commands with modes
+
+ * doc/lispref/commands.texi (Command Modes): New node.
+ (Using Interactive): Move the `modes' text to the new node.
+
+2021-02-17 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Clean-up unused variable.
+
+2021-02-17 Juri Linkov <juri@linkov.net>
+
+ New transient mode 'repeat-mode' to allow shorter key sequences (bug#46515)
+
+ * doc/emacs/basic.texi (Repeating): Document repeat-mode.
+
+ * lisp/repeat.el (repeat-exit-key): New defcustom.
+ (repeat-mode): New global minor mode.
+ (repeat-post-hook): New function.
+
+ * lisp/bindings.el (undo-repeat-map): New variable.
+ (undo): Put 'repeat-map' property with
+ 'undo-repeat-map'.
+ (next-error-repeat-map): New variable.
+ (next-error, previous-error): Put 'repeat-map' property with
+ 'next-error-repeat-map'.
+
+ * lisp/window.el (other-window-repeat-map): New variable.
+ (other-window): Put 'repeat-map' property with
+ 'other-window-repeat-map'.
+ (resize-window-repeat-map): New variable.
+ (enlarge-window, enlarge-window-horizontally)
+ (shrink-window-horizontally, shrink-window): Put 'repeat-map'
+ property with 'resize-window-repeat-map'.
+
+2021-02-17 Juri Linkov <juri@linkov.net>
+
+ New command 'tab-duplicate' like in web browsers
+
+2021-02-17 Michael Albinus <michael.albinus@gmx.de>
+
+ Further Tramp code cleanup
+
+ * doc/misc/tramp.texi (Predefined connection information):
+ Mention "about-args".
+
+ * lisp/net/tramp-cmds.el (tramp-version): Adapt docstring.
+
+ * lisp/net/tramp.el (tramp-handle-expand-file-name):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-expand-file-name):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-expand-file-name)
+ * lisp/net/tramp-smb.el (tramp-smb-handle-expand-file-name):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-expand-file-name):
+ Handle local "/..".
+
+ * lisp/net/tramp-rclone.el (tramp-methods) <rclone>:
+ Adapt `tramp-mount-args'.
+ (tramp-rclone-flush-directory-cache): Remove.
+ (tramp-rclone-do-copy-or-rename-file)
+ (tramp-rclone-handle-delete-directory)
+ (tramp-rclone-handle-delete-file)
+ (tramp-rclone-handle-make-directory): Don't use that function.
+ (tramp-rclone-maybe-open-connection): Fix use of `tramp-mount-args'.
+
+ * lisp/net/trampver.el (tramp-inside-emacs): New defun.
+ * lisp/net/tramp.el (tramp-handle-make-process):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process)
+ (tramp-sh-handle-process-file, tramp-open-shell): Use it.
+ (tramp-get-env-with-u-option): Remove.
+
+ * test/lisp/net/tramp-tests.el (tramp-test05-expand-file-name-top):
+ New test.
+
+2021-02-17 Eli Zaretskii <eliz@gnu.org>
+
+ Disable filtering of commands in M-x completion
+
+ This makes the default behavior like it was before:
+ M-x completion doesn't filter out any commands. To
+ have commands filtered based on their relevance to the
+ current buffer's modes, customize the option
+ 'read-extended-command-predicate' to call
+ 'command-completion-default-include-p'.
+ * doc/lispref/commands.texi (Interactive Call):
+ * doc/emacs/m-x.texi (M-x): Update the description of
+ 'read-extended-command-predicate' and improve wording.
+
+ * etc/NEWS: Update the entry about
+ 'read-extended-command-predicate'.
+
+ * lisp/simple.el (read-extended-command-predicate): Change default
+ value to nil. Update doc string. Add :group.
+ (read-extended-command): Handle nil as meaning to apply
+ no-filtering.
+
+2021-02-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix recently introduced bug in `byte-compile-lambda'
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-lambda): Fix recently
+ introduced error when compiling non-lexical commands (bug#46589).
+
+2021-02-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify 'read-extended-command-predicate' in NEWS
+
+2021-02-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Change name for the completion-* predicates
+
+ * lisp/simple.el (command-completion-default-include-p)
+ (command-completion-with-modes-p, command-completion-button-p):
+ Rename from completion-*.
+ (read-extended-command-predicate): Adjust default predicate.
+
+ * lisp/emacs-lisp/byte-run.el (byte-run--set-modes): Adjust
+ predicate name.
+
+2021-02-17 Glenn Morris <rgm@gnu.org>
+
+ * configure.ac: Replace obsolete AC_CHECK_HEADER usage. (Bug#46578)
+
+ * configure.ac: Replace obsolete AC_TRY_LINK with AC_LINK_IFELSE.
+
+2021-02-17 Glenn Morris <rgm@gnu.org>
+
+ Remove TIME_WITH_SYS_TIME, unused for a long time
+
+ * configure.ac (AC_HEADER_TIME): Remove. (Bug#46578)
+
+2021-02-17 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Improve detection of index entries for imenu
+
+ * lisp/progmodes/cperl-mode.el
+ (cperl-imenu-addback): Customization variable deleted. This
+ variable has been declared obsolete in 1998.
+ (cperl--basic-identifier-regexp) and many other variables:
+ defining regular expressions for basic Perl constructs.
+ (cperl-imenu--create-perl-index): This function has been
+ completely rewritten, keeping only some parts of the output
+ formatting. It now recognizes a lot more package and
+ subroutine declarations which came since Perl 5.14: Packages
+ with a version and/or a block attached, lexical subroutines,
+ declarations with a newline between the keyword "package" and
+ the package name, and several more. This version also
+ correctly separates subroutine names from attributes, does no
+ longer support "unnamed" packages (which don't exist in Perl),
+ and doesn't fall for false positives like stuff that looks
+ like a declaration in a multiline string.
+ (cperl-tags-hier-init): Eliminate call to
+ `cperl-imenu-addback` (which actually was commented out in
+ 1997)
+
+ * test/lisp/progmodes/cperl-mode-tests.el
+ (cperl-test--validate-regexp) and six other new tests for the
+ new regular expressions and the index creation.
+
+ * test/lisp/progmodes/cperl-mode-resources/grammar.pl: New
+ file showcasing different syntax variations for package and
+ sub declarations (bug#46574).
+
+2021-02-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't move point in `exif-parse-buffer'
+
+ * lisp/image/exif.el (exif-parse-buffer): Don't move point
+ (bug#46552).
+
+2021-02-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix edebug spec for minibuffer-with-setup-hook
+
+ * lisp/files.el (minibuffer-with-setup-hook): Instrument the
+ :append form for edebug (bug#46531).
+
+2021-02-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify Gnus Agent expiry quirks
+
+ * doc/misc/gnus.texi (Agent Expiry): Mention that the last article
+ won't be expired (bug#46533).
+
+2021-02-16 Andrea Corallo <akrl@sdf.org>
+
+ Clean-up some signal related dead-code
+
+ * src/comp.c (restore_sigmask): Remove function.
+ (Fcomp__compile_ctxt_to_file): Remove some dead-code.
+
+2021-02-16 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (check_comp_unit_relocs): Prefer ptrdiff_t to EMACS_INT.
+
+2021-02-16 Andrea Corallo <akrl@sdf.org>
+
+ Better long range check
+
+ * src/comp.c (emit_rvalue_from_emacs_uint)
+ (emit_rvalue_from_emacs_int, emit_rvalue_from_lisp_word_tag)
+ (emit_rvalue_from_lisp_word): Better long range check.
+
+2021-02-16 Andrea Corallo <akrl@sdf.org>
+
+ Sanitize frame slot access in final
+
+ * src/comp.c (comp_t): Add 'frame_size' field.
+ (emit_mvar_lval): Add sanity check on frame element access.
+ (compile_function): Initialize 'comp.frame_size' and
+ 'comp.frame_size'.
+
+2021-02-16 Glenn Morris <rgm@gnu.org>
+
+ thumbs.el: avoid creating thumbs directory on loading library
+
+ * lisp/thumbs.el (thumbs-cleanup-thumbsdir):
+ Don't create the thumbs directory if it does not exist.
+
+2021-02-16 Glenn Morris <rgm@gnu.org>
+
+ * admin/cus-test.el (cus-test-load-libs): Quieten loading.
+
+ * admin/cus-test.el (cus-test-get-lisp-files): Ignore loaddefs files.
+
+2021-02-16 Bastian Beranek <bastian.beischer@rwth-aachen.de>
+
+ * lisp/tab-bar.el: Fix behavior of toggle-frame-tab-bar (bug #46299)
+
+ (toggle-frame-tab-bar): Add frame parameter to protect tab bar state.
+ (tab-bar--update-tab-bar-lines): Check parameter.
+
+2021-02-16 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Pacify unused function warning in xfns.c with GTK2
+
+ * src/xfns.c (x_get_net_workarea, x_get_monitor_for_frame)
+ (x_make_monitor_attribute_list, x_get_monitor_attributes_fallback):
+ [HAVE_XINERAMA] (x_get_monitor_attributes_xinerama)
+ [HAVE_XRANDR] (x_get_monitor_attributes_xrandr)
+ (x_get_monitor_attributes): Fix #ifdefs around definitions to avoid
+ unused function warnings regardless of GTK use (bug#46509).
+ [HAVE_XRANDR] (x_get_monitor_attributes_xrandr): Undefine
+ RANDR13_LIBRARY after it's been used.
+
+2021-02-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Fix problem of point movement in image-mode"
+
+ This reverts commit 7c7377288a125ef47f2b422cf131f044a3b418e1.
+
+ This is fixed differently in Emacs 27.
+
+2021-02-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem of point movement in image-mode
+
+ * lisp/image-mode.el (image-mode): Switch disable-point-adjustment
+ on, otherwise `C-c C-c' will move point around oddly.
+ (image-toggle-display): Ensure that point is on the image (bug#46552).
+
+2021-02-16 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid point movement when visiting image files
+
+ * lisp/image-mode.el (image-toggle-display-image): Preserve point
+ around the call to exif-parse-buffer, to prevent it from moving
+ into the image data. (Bug#46552)
+
+2021-02-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Do interactive mode tagging for info.el
+
+2021-02-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't resize images in image-mode if we have a rotation
+
+ * lisp/image-mode.el (image-fit-to-window): Don't resize of we
+ have a manually rotated imaged (and explain the resizing logic a
+ bit).
+
+2021-02-16 Konstantin Kharlamov <Hi-Angel@yandex.ru>
+
+ make smerge-vc-next-conflict wrap around
+
+ * lisp/vc/smerge-mode.el:
+ (smerge-vc-next-conflict): While searching for conflict markers,
+ wrap search around if current file is the last one with conflicts
+ (bug#46538).
+
+2021-02-16 Stefan Kangas <stefan@marxist.se>
+
+ Do `interactive' mode tagging in gomoku.el
+
+ * lisp/play/gomoku.el: Do `interactive' mode tagging.
+
+2021-02-16 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/play/gomoku.el: Minor doc fixes; formatting.
+
+2021-02-16 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/bindat.el: Add 64bit int support
+
+ (bindat--unpack-u64, bindat--unpack-u64r, bindat--pack-u64)
+ (bindat--pack-u64r): New functions.
+ (bindat--unpack-item, bindat--pack-item): Use them.
+ (bindat--fixed-length-alist): Add new types.
+
+2021-02-16 Stefan Kangas <stefan@marxist.se>
+
+ Fix admin/check-doc-strings for new DEFUN format
+
+ * admin/check-doc-strings: Various fixes, including for the new DEFUN
+ format. The script still produces a ton of false positives, however.
+
+2021-02-16 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/bindat.el: Clarify when field labels are optional
+
+ The fixes the doc and the Edebug spec, as well as a subtle issue in
+ the code where a field whose name is (eval 'fill) was mistakenly
+ considered as an anonymous field of type `fill`.
+
+ (bindat--unpack-item, bindat--unpack-group, bindat--length-group)
+ (bindat--pack-item, bindat--pack-group): Use dotimes, dolist, and pcase.
+ (bindat--item-aux): New edebug elem.
+ (bindat-item): Use it to fix the handling of optional fields.
+ (bindat-format-vector): Use `mapconcat`.
+
+2021-02-16 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/bindat.el (bindat-spec): New macro.
+
+ It's basically an alias for `quote`, but it offers the advantage of
+ providing Edebug support and opens the possibility of compiling
+ the bindat spec to ELisp code.
+
+ * doc/lispref/processes.texi (Bindat Spec): Document `bindat-spec`.
+ (Bindat Functions): Tweak a few things to adjust to the state of the code.
+
+ * test/lisp/emacs-lisp/bindat-tests.el: Use it.
+
+ * test/lisp/emacs-lisp/edebug-tests.el (edebug-tests--read): New function.
+ (edebug-tests--&rest-behavior): New test.
+
+2021-02-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/macroexp.el (macroexp--expand-all): Warn on empty let bodies
+
+2021-02-15 Ulf Jasper <ulf.jasper@web.de>
+
+ Display yearly ical events from first year on. Fix Bug#23100.
+
+ Convert yearly rrule starting in year x into diary-anniversary entry
+ for year x-1 when importing an icalendar. Correspondingly convert
+ diary-anniversary for year x into yearly rrule starting in year x+1.
+
+ *
+ test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-american:
+ *
+ test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-european:
+ *
+ test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-iso:
+ *
+ test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-american:
+ *
+ test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-european:
+ *
+ test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-iso:
+ *
+ test/lisp/calendar/icalendar-tests.el (icalendar-convert-anniversary-to-ical):
+ Match new diary-anniversary/yearly-rrule behaviour.
+
+ * lisp/calendar/icalendar.el (icalendar--datestring-to-isodate): Add
+ year-shift option. (icalendar--convert-anniversary-to-ical): Shift
+ the year as diary-anniversary is not displayed in the initial year.
+ (icalendar--convert-recurring-to-diary): Shift the year as
+ diary-anniversary is not displayed in the initial year. (Bug#23100)
+
+2021-02-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/calc/calc-sel.el (calc-replace-sub-formula): Fix typo
+
+ Reported by Sébastien Miquel <sebastien.miquel@posteo.eu>
+
+2021-02-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/bindat.el: Expose the `struct` variable (bug#46534)
+
+ (bindat--unpack-group, bindat--length-group, bindat--pack-group):
+ Mark it as dynamically scoped.
+
+2021-02-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow overriding declared predicates, too
+
+ * lisp/simple.el (completion-default-include-p): Rename and move
+ the checking for an explicit predicate down here...
+ (read-extended-command): ... from here.
+ (read-extended-command-predicate): Adjust default value.
+
+2021-02-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Do `interactive' mode tagging in the remaining lisp/gnus files
+
+2021-02-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new variable `global-minor-modes'
+
+ * doc/lispref/modes.texi (Minor Modes): Document it.
+ * lisp/simple.el (global-minor-modes): New variable.
+ (completion-in-mode-p): Use it.
+ (completion-with-modes-p): Use it.
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Support it.
+
+2021-02-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Rename minor-modes to local-minor-modes
+
+ * doc/lispref/modes.texi (Minor Modes): Update documentation.
+ * lisp/simple.el (completion-with-modes-p): Change usage.
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Change usage.
+
+ * src/buffer.c: Rename from minor_modes to local_minor_modes
+ throughout.
+ (syms_of_buffer): Rename minor-modes to local-minor-modes.
+
+ * src/buffer.h (struct buffer): Rename minor_modes_.
+
+ * src/pdumper.c (dump_buffer): Update hash and usage.
+
+2021-02-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/edebug.el (edebug-&optional, edebug-&rest): Remove vars
+
+ According to my tests, `edebug-&optional` never has any effect.
+ And `edebug-&rest` can be replaced with a closure.
+
+ (edebug-&rest-wrapper): Remove function.
+ (edebug--match-&-spec-op): Use a closure to remember the `specs`.
+
+2021-02-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/byte-run.el (compiler-macro): Make it Edebuggable
+
+ * lisp/emacs-lisp/gv.el (gc-expander, gv-setter): Reuse the spec of
+ `compiler-macro`.
+
+2021-02-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the button completion predicate be more useful
+
+ * lisp/simple.el (completion-button-p): Rework from
+ `completion-at-point-p'.
+
+ * lisp/net/shr.el (shr-show-alt-text): It should be possible to
+ complete to commands that aren't bound to a key.
+
+2021-02-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Speed up completion-in-mode-p in the common case
+
+ * lisp/simple.el (completion-in-mode-p): Make predicate more
+ efficient in the common one-mode case.
+
+2021-02-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix two syntax errors in Specification List
+
+ * doc/lispref/edebug.texi (Specification List): Add a couple of
+ missing @s.
+
+2021-02-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Edebug: Generalize `&lookup`, use it for `cl-macrolet` and `cl-generic`
+
+ This allows the use of (declare (debug ...)) in the lexical macros
+ defined with `cl-macrolet`. It also fixes the names used by Edebug
+ for the methods of `cl-generic` so it doesn't need to use gensym
+ and so they don't include the formal arg names any more.
+
+ * lisp/emacs-lisp/edebug.el (edebug--match-&-spec-op):
+ Rename from `edebug--handle-&-spec-op`.
+ (edebug--match-&-spec-op <&interpose>): Rename from `&lookup` and
+ generalize so it can let-bind dynamic variables around the rest of the parse.
+ (edebug-lexical-macro-ctx): Rename from `edebug--cl-macrolet-defs` and
+ make it into an alist.
+ (edebug-list-form-args): Use the specs from `edebug-lexical-macro-ctx`
+ when available.
+ (edebug--current-cl-macrolet-defs): Delete var.
+ (edebug-match-cl-macrolet-expr, edebug-match-cl-macrolet-name)
+ (edebug-match-cl-macrolet-body): Delete functions.
+ (def-declarations): Use new `&interpose`.
+ (edebug--match-declare-arg): Rename from `edebug--get-declare-spec` and
+ adjust to new calling convention.
+
+ * lisp/subr.el (def-edebug-elem-spec): Fix docstring.
+ (eval-after-load): Use `declare`.
+
+ * lisp/emacs-lisp/cl-generic.el: Fix Edebug names so we don't need
+ gensym any more and we only include the specializers but not the formal
+ arg names.
+ (cl--generic-edebug-name): New var.
+ (cl--generic-edebug-remember-name, cl--generic-edebug-make-name): New funs.
+ (cl-defgeneric, cl-defmethod): Use them.
+
+ * lisp/emacs-lisp/cl-macs.el: Add support for `debug` declarations in
+ `cl-macrolet`.
+ (cl-declarations-or-string):
+ Fix use of `lambda-doc` and allow use of `declare`.
+ (edebug-lexical-macro-ctx): Declare var.
+ (cl--edebug-macrolet-interposer): New function.
+ (cl-macrolet): Use it to pass the right `lexical-macro-ctx` to the body.
+
+ * lisp/emacs-lisp/pcase.el (pcase-PAT): Use new `&interpose`.
+ (pcase--edebug-match-pat-args): Rename from `pcase--get-edebug-spec` and
+ adjust to new calling convention.
+
+ * test/lisp/emacs-lisp/cl-generic-tests.el (cl-defgeneric/edebug/method):
+ Adjust to the new names.
+
+ * test/lisp/emacs-lisp/edebug-tests.el (edebug-cl-defmethod-qualifier)
+ (edebug-tests-cl-flet): Adjust to the new names.
+
+ * doc/lispref/edebug.texi (Specification List): Document &interpose.
+
+2021-02-15 Stefan Kangas <stefan@marxist.se>
+
+ Avoid asking repeatedly about reloading bookmarks file
+
+ * lisp/bookmark.el (bookmark-maybe-load-default-file): Reload watched
+ bookmarks file only if its mtime has changed since the last query.
+ This avoids asking repeatedly about reloading the bookmarks file if
+ the user has already said "no" to a previous query.
+ (bookmark--watch-file-already-queried-p): New function.
+ (bookmark--watch-already-asked-mtime): New variable.
+
+2021-02-14 Stefan Kangas <stefan@marxist.se>
+
+ Mark up bookmark.el for correct modes
+
+ * lisp/bookmark.el: Mark up all commands with applicable modes.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a comment to `read-extended-command'
+
+ * lisp/simple.el (read-extended-command): Add a comment.
+
+2021-02-14 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/startup.el (normal-top-level): Use `path-separator' in place of ":".
+
+2021-02-14 Eli Zaretskii <eliz@gnu.org>
+
+ * src/xdisp.c (move_it_to): Fix last change. (Bug#46316)
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a possible completion predicate for buttons
+
+ * lisp/simple.el (completion-at-point-p): New predicate.
+
+ * lisp/net/shr.el (shr-show-alt-text): Mark up as a button.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make completion-with-modes-p work with minor modes, too
+
+ * lisp/simple.el (completion-with-modes-p): Work with minor modes,
+ too.
+
+2021-02-14 Andrea Corallo <akrl@sdf.org>
+
+ Revert "* src/comp.c (define_jmp_buf): Use 'jmp_buf' instead of 'sys_jmp_buf'."
+
+ This reverts commit bebec46bcbf0e52460b08234c067d7a2cb0f2246.
+
+ Looking at the git history I realize now the use of 'sys_jmp_buf' was
+ intentional.
+
+2021-02-14 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (define_jmp_buf): Use 'jmp_buf' instead of 'sys_jmp_buf'.
+
+ * src/comp.c (load_comp_unit): Fix 'data_ephemeral_vec' shadowing decl.
+
+2021-02-14 Bastian Beranek <bastian.beischer@rwth-aachen.de>
+
+ Fix showing and hiding of tab-bar on new frames (bug#46299)
+
+ * lisp/tab-bar.el (tab-bar--update-tab-bar-lines)
+ (tab-bar--tab-bar-lines-for-frame):
+ New functions to update value of tab-bar-lines in frames.
+ (tab-bar-mode, tab-bar-new-tab-to, tab-bar-close-tab)
+ (tab-bar-close-other-tab, tab-bar-show :set):
+ Use new function.
+ (tab-bar-select-tab-modifiers :set):
+ Work around visual glitch.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Do command markup in blackbox.el
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix byte-run--set-modes call signature
+
+ * lisp/emacs-lisp/byte-run.el (byte-run--set-modes): We take a
+ list of modes, not a single one (and fix the quoting).
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix missing ' in NEWS
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Also mention `M-o M-o' removal
+
+ * lisp/loadup.el (facemenu-keymap-restore): Also restore `M-o M-o'.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't update `minor-modes' in global modes
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): There's no
+ point in setting the buffer-local `minor-modes' in global modes.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mark up 5x5 for interactive mode
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with the newly introduces `minor-modes' variable
+
+ * lisp/help-fns.el (describe-mode): Apparently buffer-local
+ variables take precedence over lexically bound variables?
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Do `interactive' mode markup in all Gnus files
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Really fix the syntax problem in define-minor-mode
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Fix
+ interactive extension in previous change.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous define-minor-mode change
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Fix
+ interactive extension in previous change.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mark up eww.el for correct modes
+
+ * lisp/net/eww.el: Mark up all commands with applicable modes.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `C-h m' list unbound commands applicable for the mode
+
+ * lisp/help-fns.el (help-fns--list-local-commands): New function.
+ (describe-mode): Use it.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow define-minor-mode to take an :interactive keyword
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Allow
+ specifying the :interactive state and the modes.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix dumping of buffers after minor_modes was added
+
+ * src/pdumper.c (dump_buffer): Set minor_modes to nil before dumping.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert the bit about command_modes in previous patch set
+
+ * src/data.c (Fcommand_modes): Remove the subr bit -- it's not
+ necessary since it can just use a predicate.
+ * src/lisp.h (GCALIGNED_STRUCT): Remove command_modes.
+
+ * src/lread.c (defsubr): Remove command_modes.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add 'read-extended-command-predicate'
+
+ * doc/emacs/m-x.texi (M-x): Document it.
+ * doc/lispref/commands.texi (Interactive Call): Document it further.
+
+ * lisp/simple.el (read-extended-command-predicate): New user option.
+ (read-extended-command-predicate): Use it.
+ (completion-in-mode-p): New function (the default predicate).
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mark easy-menu-do-define menus as "not interesting"
+
+ * lisp/emacs-lisp/easymenu.el (easy-menu-do-define): Mark menu
+ keymaps as "not interesting" when doing completion.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new 'declare' forms for command completion predicates
+
+ * doc/lispref/functions.texi (Declare Form): Document the new
+ `completion' and `modes' declarations.
+ * lisp/simple.el (completion-with-modes-p): New helper functions.
+
+ * lisp/emacs-lisp/byte-run.el (byte-run--set-completion)
+ (byte-run--set-modes):
+ (defun-declarations-alist): New declarations for `completion' and
+ `modes'.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Extend the syntax of `interactive' to list applicable modes
+
+ * doc/lispref/commands.texi (Using Interactive): Document the
+ extended `interactive' form.
+ * doc/lispref/loading.texi (Autoload): Document list-of-modes
+ form.
+
+ * lisp/emacs-lisp/autoload.el (make-autoload): Pick the list of
+ modes from `interactive' out of the functions.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-lambda): Allow for the
+ extended `interactive' form.
+
+ * src/callint.c (Finteractive): Document the extended form.
+
+ * src/data.c (Finteractive_form): Return the interactive form in
+ the old format (even when there's an extended `interactive') to
+ avoid having other parts of Emacs be aware of this.
+ (Fcommand_modes): New defun.
+
+ * src/emacs-module.c (GCALIGNED_STRUCT): Allow for modules to
+ return command modes.
+
+ * src/lisp.h: New function module_function_command_modes.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix how `shell-mode' avoids being called interactively
+
+ * lisp/shell.el (shell-mode): Make noninteractive instead of
+ erroring out after being called.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Introduce an :interactive keyword for `defined-derived-mode'
+
+ * doc/lispref/modes.texi (Derived Modes): Document it.
+ * lisp/emacs-lisp/derived.el (define-derived-mode): Introduce a
+ new :interactive keyword.
+
+2021-02-14 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant :group args from textmodes/*.el
+
+ * lisp/textmodes/enriched.el:
+ * lisp/textmodes/ispell.el:
+ * lisp/textmodes/makeinfo.el:
+ * lisp/textmodes/paragraphs.el:
+ * lisp/textmodes/picture.el:
+ * lisp/textmodes/refbib.el:
+ * lisp/textmodes/refer.el:
+ * lisp/textmodes/remember.el:
+ * lisp/textmodes/texinfo.el:
+ * lisp/textmodes/tildify.el:
+ * lisp/textmodes/two-column.el: Remove redundant :group args.
+
+2021-02-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new buffer-local variable `minor-modes'
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Keep
+ `minor-modes' updated.
+ * src/buffer.c (bset_minor_modes, Fmake_indirect_buffer)
+ (reset_buffer, init_buffer_once): Initialise `minor-modes'.
+ (syms_of_buffer): Add `minor-modes' as a new permanently-local
+ variable.
+
+ * src/buffer.h (struct buffer): Add minor_modes_.
+
+2021-02-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/edebug.el (edebug-make-enter-wrapper): Reinstate.
+
+ Removed by accident.
+
+2021-02-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/edebug.el: Fix `called-interactively-p`
+
+ And get rid of the old special-case handling of `interactive-p`, which
+ is now redundant.
+
+ (edebug--called-interactively-skip): Fix lexical-binding case,
+ and adjust to some formerly missed call patterns.
+ (edebug-def-interactive, edebug-interactive-p): Remove vars.
+ (edebug-interactive-p-name, edebug-wrap-def-body)
+ (edebug-make-enter-wrapper): Remove functions.
+ (edebug-list-form): Don't special-case `interactive-p`.
+
+2021-02-13 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/edebug.el (edebug-match-lambda-expr): Delete function
+
+ (lambda-expr): Define with `def-edebug-elem-spec` instead.
+ (edebug--handle-&-spec-op): Remove left over code.
+ (interactive): Re-add mistakenly removed spec elem.
+
+ * doc/lispref/edebug.texi (Specification List): Remove `function-form`.
+
+2021-02-13 Alan Third <alan@idiocy.org>
+
+ Fix flicker when resizing NS frame programmatically (bug#46155)
+
+
+ * src/nsterm.m ([EmacsView viewWillDraw]): New function.
+ ([EmacsView viewDidResize:]): We now have to mark the frame for
+ display on resize.
+ ([EmacsView initFrameFromEmacs:]): Retain frame contents on resize.
+ ([EmacsView updateLayer]): Don't update the layer if the frame is
+ still garbaged.
+
+2021-02-13 Alan Third <alan@idiocy.org>
+
+ Remove aliasing on SVG images under scaled NS frames
+
+ * src/image.c (FRAME_SCALE_FACTOR): New #define for getting frame
+ scale factor.
+ (image_set_transform):
+ (svg_load_image): Use FRAME_SCALE_FACTOR.
+ * src/nsterm.m (ns_frame_scale_factor): Get the scale factor for an NS
+ frame.
+
+2021-02-13 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/edebug.el (edebug--handle-&-spec-op <&name>): New method
+
+ (edebug--concat-name): New function.
+ (edebug-match-name, edebug-match-cl-generic-method-qualifier)
+ (edebug-match-cl-generic-method-args): Delete functions.
+
+ * doc/lispref/edebug.texi (Specification List): Document it.
+
+ * lisp/emacs-lisp/cl-generic.el (cl-defgeneric): Use `&name`.
+ (cl-generic--method-qualifier-p): New predicate.
+ (cl-defmethod): Use it and `&name`.
+ * lisp/emacs-lisp/cl-macs.el (cl-defun, cl-iter-defun, cl-flet):
+ * lisp/emacs-lisp/eieio-compat.el (defmethod):
+ * lisp/emacs-lisp/gv.el (gv-define-setter):
+ * lisp/emacs-lisp/ert.el (ert-deftest): Use `&name`.
+ * lisp/erc/erc-backend.el (define-erc-response-handler): Use `declare`
+ and `&name`.
+
+2021-02-13 Philipp Stephani <phst@google.com>
+
+ * etc/NEWS: Document new JSON behavior.
+
+2021-02-13 Augusto Stoffel <arstoffel@gmail.com> (tiny change)
+
+ Small correction to `isearch-lazy-highlight-buffer-update'
+
+ The value of point is now read after a potential change of buffer.
+ * lisp/isearch.el (isearch-lazy-highlight-buffer-update): Move call
+ to `point' after `select-window'.
+
+2021-02-13 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ (backtrace-goto-source-functions): Make it a normal abnormal hook
+
+ * lisp/emacs-lisp/backtrace.el (backtrace-goto-source-functions):
+ Don't mark it as buffer-local any more.
+ (backtrace-goto-source): Use `run-hook-with-args-until-success`.
+
+ * lisp/emacs-lisp/edebug.el (edebug-pop-to-backtrace): Clarify that the
+ hook is only intended to be modified buffer-locally.
+
+2021-02-13 Eli Zaretskii <eliz@gnu.org>
+
+ Fix I-search at EOB when long lines are truncated
+
+ * src/xdisp.c (move_it_to): Fix logic when TO_CHARPOS is at the
+ end of an hscrolled line which ends at EOB. (Bug#46316)
+
+2021-02-13 Philipp Stephani <phst@google.com>
+
+ Pass 'struct json_configuration' as const where possible.
+
+ The JSON serialization and parsing functions don't need to modify
+ these structures.
+
+ * src/json.c (lisp_to_json_nonscalar_1, lisp_to_json_nonscalar)
+ (lisp_to_json, json_to_lisp): Mark configuration object parameter as
+ const.
+
+2021-02-13 Philipp Stephani <phst@google.com>
+
+ Allow any JSON value at the top level (Bug#42994).
+
+ Newer standards like RFC 8259, which obsoletes the earlier RFC 4627,
+ now allow any top-level value unconditionally, so Emacs should too.
+
+ * src/json.c (Fjson_serialize, Fjson_insert): Pass JSON_ENCODE_ANY to
+ allow serialization of any JSON value. Call 'lisp_to_json' instead of
+ 'lisp_to_json_toplevel'. Remove obsolete comments
+ (neither JSON_DECODE_ANY nor JSON_ALLOW_NUL are allowed here). Reword
+ documentation strings.
+ (Fjson_parse_string, Fjson_parse_buffer): Pass JSON_DECODE_ANY to
+ allow deserialization of any JSON value. Reword documentation
+ strings.
+ (lisp_to_json_nonscalar, lisp_to_json_nonscalar_1): Rename from
+ "toplevel" to avoid confusion.
+ (lisp_to_json): Adapt caller.
+ * test/src/json-tests.el (json-serialize/roundtrip-scalars): New unit
+ test.
+ * doc/lispref/text.texi (Parsing JSON): Update documentation.
+
+2021-02-13 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Remove stale comments from gnus-msg.el
+
+ * lisp/gnus/gnus-msg.el (gnus-group-mail, gnus-group-news)
+ (gnus-summary-mail-other-window, gnus-summary-news-other-window):
+ Remove stale comments about let-binding gnus-newsgroup-name, as they
+ should have been addressed (bug#37871#38).
+
+2021-02-13 Eli Zaretskii <eliz@gnu.org>
+
+ Fix vertical cursor motion among many images
+
+ * src/xdisp.c (move_it_in_display_line_to): Consider it
+ MOVE_POS_MATCH_OR_ZV if we are just after an image, stretch, or
+ display string, and the position matches exactly. This is needed
+ when one image follows another at TO_CHARPOS. (Bug#46464)
+
+2021-02-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ add-minor-mode doc string clarification
+
+ * lisp/subr.el (add-minor-mode): Clarify that this function isn't
+ only about XEmacs compat stuff.
+
+2021-02-13 Stefan Kangas <stefan@marxist.se>
+
+ Delete 20 year old comment in executable.el
+
+ * lisp/progmodes/executable.el (executable-insert): Delete 20 year old
+ comment.
+
+2021-02-13 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant :group args in progmodes/*.el
+
+ * lisp/progmodes/bug-reference.el:
+ * lisp/progmodes/cfengine.el:
+ * lisp/progmodes/cmacexp.el:
+ * lisp/progmodes/cpp.el:
+ * lisp/progmodes/cwarn.el:
+ * lisp/progmodes/dcl-mode.el:
+ * lisp/progmodes/executable.el:
+ * lisp/progmodes/flymake.el:
+ * lisp/progmodes/gud.el:
+ * lisp/progmodes/hideshow.el:
+ * lisp/progmodes/icon.el:
+ * lisp/progmodes/inf-lisp.el:
+ * lisp/progmodes/js.el:
+ * lisp/progmodes/ld-script.el:
+ * lisp/progmodes/make-mode.el:
+ * lisp/progmodes/modula2.el:
+ * lisp/progmodes/pascal.el:
+ * lisp/progmodes/perl-mode.el:
+ * lisp/progmodes/prog-mode.el:
+ * lisp/progmodes/simula.el:
+ * lisp/progmodes/xscheme.el: Remove redundant :group args.
+
+2021-02-13 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Edebug: Make it possible to debug `gv-expander`s in `declare`
+
+ Arrange for declarations to be able to specify their own specs via
+ the `edebug-declaration-spec` property.
+
+ * lisp/emacs-lisp/edebug.el: (edebug--get-declare-spec): New function.
+ (def-declarations): New spec element.
+ (defun, defmacro): Use it in their spec.
+
+ * lisp/emacs-lisp/gv.el (gv-expander, gv-setter):
+ Set `edebug-declaration-spec`.
+
+ * test/lisp/emacs-lisp/edebug-tests.el (edebug-tests-gv-expander): New test.
+
+ * test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el
+ (edebug-test-code-use-gv-expander): New test case.
+
+2021-02-13 Stefan Kangas <stefan@marxist.se>
+
+ Comment out mysterious code from cperl-mode.el
+
+ * lisp/progmodes/cperl-mode.el: Comment out mysterious code referring
+ to some unknown variable 'edit-var-mode-alist'. No one seems to know
+ what it is used for, so comment it out and see if anyone complains
+ before Emacs 28.1 or 28.2.
+
+2021-02-13 Stefan Kangas <stefan@marxist.se>
+
+ Remove outdated documentation from cperl-mode.el
+
+ * lisp/progmodes/cperl-mode.el (cperl-tips, cperl-problems)
+ (cperl-praise, cperl-speed, cperl-mode): Doc fixes; remove references
+ to very old versions of Emacs and other "Emaxen".
+ (cperl-problems-old-emaxen): Make obsolete and remove information on
+ Emacs 20.3 and older.
+
+2021-02-13 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Edebug: Overload `edebug-form-spec` even less
+
+ The `edebug-form-spec` symbol property was used both to map forms's
+ head symbol to the corresponding spec, and to map spec element names
+ to their expansion.
+
+ This lead to name conflicts which break instrumentation of examples such as
+
+ (cl-flet ((gate (x) x)) (gate 4))
+
+ because of the Edebug spec element `gate`.
+ So introduce a new symbol property `edebug-elem-spec`.
+
+ * lisp/subr.el (def-edebug-elem-spec): New function.
+
+ * lisp/emacs-lisp/edebug.el (edebug--get-elem-spec): New function.
+ (edebug-match-symbol): Use it.
+ (Core Edebug elems): Put them on `edebug-elem-spec` instead of
+ `edebug-form-spec`.
+ (ELisp special forms): Set their `edebug-form-spec` via dolist.
+ (Other non-core Edebug elems): Use `def-edebug-elem-spec`.
+ (edebug-\`): Use `declare`.
+
+ * lisp/emacs-lisp/pcase.el (pcase-PAT, pcase-FUN, pcase-QPAT):
+ * lisp/skeleton.el (skeleton-edebug-spec):
+ * lisp/emacs-lisp/cl-macs.el: Use `def-edebug-elem-spec`.
+
+ * test/lisp/emacs-lisp/edebug-tests.el
+ (edebug-tests--conflicting-internal-names): New test.
+ * test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el
+ (edebug-test-code-cl-flet1): New test case.
+
+ * doc/lispref/edebug.texi (Specification List): Add `def-edebug-elem-spec`.
+ (Specification Examples): Use it.
+
+ * doc/lispref/loading.texi (Hooks for Loading): Avoid the use of
+ `def-edebug-spec` in example (better use `debug` declaration).
+
+2021-02-13 Stefan Kangas <stefan@marxist.se>
+
+ Remove XEmacs and Emacs 21 compat code from cperl-mode
+
+ * lisp/progmodes/cperl-mode.el (cperl-mode): Remove XEmacs and
+ Emacs 21 compat code.
+ (cperl-compilation-error-regexp-list): New variable.
+ (cperl-compilation-error-regexp-alist): Make obsolete.
+
+2021-02-12 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix ElDoc setup for eval-expression
+
+ * lisp/emacs-lisp/eldoc.el (eldoc--eval-expression-setup): Don't set
+ global value of eldoc-documentation-strategy (bug#44886).
+
+2021-02-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Use `declare` instead of `def-edebug-spec` in most places
+
+ * lisp/speedbar.el: Use lexical-binding.
+ (speedbar-with-writable): Use `declare`.
+
+ * lisp/subr.el (def-edebug-spec): Use `declare`.
+
+ * lisp/cedet/ede/base.el: Use lexical-binding.
+ (ede-with-projectfile): Use `declare`.
+ (recentf-exclude): Declare var.
+
+ * lisp/cedet/ede/pmake.el: Use lexical-binding.
+ (ede-pmake-insert-variable-shared, ede-pmake-insert-variable-once):
+ Use `declare`.
+
+ * lisp/cedet/ede/proj-comp.el: Use lexical-binding.
+ (ede-compiler-begin-unique, ede-compiler-only-once)
+ (ede-linker-begin-unique, ede-linker-only-once): Use `declare`.
+
+ * lisp/cedet/semantic/ctxt.el: Use lexical-binding.
+ (semantic-with-buffer-narrowed-to-context)
+ (semantic-with-buffer-narrowed-to-command): Use `declare`.
+ (semantic--progress-reporter): Declare var.
+ (semantic-ctxt-end-of-symbol-default): Remove unused var `fieldsep`.
+
+ * lisp/cedet/semantic/lex-spp.el: Use lexical-binding.
+ (define-lex-spp-macro-declaration-analyzer)
+ (define-lex-spp-include-analyzer, semantic-lex-with-macro-used)
+ (define-lex-spp-macro-undeclaration-analyzer): Use `declare`.
+ (semantic-lex-spp-symbol-remove): Rename arg to avoid colliding with
+ dynamic variable `obarray`.
+ (semantic-lex-spp-symbol-pop): Remove unused var `oldvalue`.
+ (semantic-lex-spp-lex-text-string): Remove unused var `analyzer`.
+
+ * lisp/cedet/semantic/lex.el (define-lex)
+ (semantic-lex-unterminated-syntax-protection, define-lex-analyzer)
+ (define-lex-regex-analyzer, define-lex-block-analyzer)
+ (semantic-lex-catch-errors): Use `declare`.
+
+ * lisp/cedet/semantic/tag.el: Use lexical-binding.
+ (semantic-with-buffer-narrowed-to-current-tag)
+ (semantic-with-buffer-narrowed-to-tag): Use `declare`.
+
+ * lisp/cedet/semantic/wisent.el: Use lexical-binding.
+ (define-wisent-lexer): Use `declare`.
+
+ * lisp/emacs-lisp/cl-lib.el (cl-pushnew): The arg to :test can be any
+ form not just function form.
+
+ * lisp/org/ob-comint.el (org-babel-comint-in-buffer)
+ (org-babel-comint-with-output): Use `declare`.
+
+ * lisp/org/ob-core.el (org-babel-map-src-blocks): Use `declare`.
+ (org-babel-result-cond): Simplify edebug spec.
+
+ * lisp/org/org-clock.el (org-with-clock-position, org-with-clock):
+ * lisp/org/org-agenda.el (org-agenda-with-point-at-orig-entry):
+ * lisp/org/ob-tangle.el (org-babel-with-temp-filebuffer): Use `declare`.
+
+ * lisp/textmodes/rst.el (push): Remove redundant edebug spec.
+
+ * lisp/vc/pcvs-parse.el: Use lexical-binding.
+ (cvs-parse-buffer): Rename arg to avoid dynbound conflict.
+ (cvs-or): Use `declare`.
+
+2021-02-12 Mattias Engdegård <mattiase@acm.org>
+
+ Simplify expression in byte-code decompiler
+
+ * lisp/emacs-lisp/byte-opt.el (byte-decompile-bytecode-1):
+ Replace roundabout expression with what it essentially does.
+
+2021-02-12 Mattias Engdegård <mattiase@acm.org>
+
+ byte-opt.el: More concise expression
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker):
+ Refactor `setq` clause.
+
+2021-02-12 Mattias Engdegård <mattiase@acm.org>
+
+ Avoid traversing dead `if` branches in bytecode optimiser
+
+ There is no point in traversing conditional branches that are
+ statically known never to be executed. This saves some optimisation
+ effort, but more importantly prevents variable assignments and
+ references in those branches from blocking effective constant
+ propagation.
+
+ Also attempt to traverse as much as possible in an unconditional
+ context, which enables constant-propagation through (linear)
+ assignments.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-form):
+ Rewrite the (tail) recursion into an explicit loop. Normalise a
+ return value of (quote nil) to nil, for easier subsequent
+ optimisations.
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Don't
+ traverse dead `if` branches. Use unconditional traversion context
+ when possible.
+
+2021-02-12 Mattias Engdegård <mattiase@acm.org>
+
+ Don't inline tramp-debug-message
+
+ * lisp/net/tramp.el (tramp-debug-message): Change defsubst into defun.
+ Until now the byte-compiler hasn't been clever enough to inline this
+ function but this is about to change; the code expansion is
+ unnecessary and makes compiler improvements more difficult to gauge.
+
+2021-02-12 Stefan Kangas <stefan@marxist.se>
+
+ Use regexp-opt for font lock defaults in meta-mode.el
+
+ * lisp/progmodes/meta-mode.el: Remove redundant :group args.
+
+ (meta-font-lock-keywords): Use regexp-opt.
+
+2021-02-12 Stefan Kangas <stefan@marxist.se>
+
+ Minor cleanups in scheme.el
+
+ * lisp/progmodes/scheme.el: Remove redundant :group args.
+ (dsssl-font-lock-keywords): Use regexp-opt.
+
+2021-02-12 Stefan Kangas <stefan@marxist.se>
+
+ Add font locking for many missing macros in m4-mode
+
+ * lisp/progmodes/m4-mode.el (m4--macro-list): New variable.
+ (m4-font-lock-keywords): Use regexp-opt and add many missing macros
+ sourced from the M4 manual.
+
+2021-02-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/edebug.el (edebug--handle-&-spec-op) <&lookup>: New method
+
+ * doc/lispref/edebug.texi (Specification List): Document it.
+
+ * lisp/emacs-lisp/pcase.el (pcase-PAT): Use it.
+ (pcase-MACRO): Remove Edebug element.
+ (pcase--get-edebug-spec): New function.
+ (pcase--edebug-match-macro): Remove function.
+
+2021-02-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-macs.el (cl-flet): Fix edebug spec
+
+2021-02-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/edebug.el: Misc cleanups.
+
+ Move all definitions under the `edebug-` prefix.
+
+ (edebug-get-spec): Rename from `get-edebug-spec`.
+ (edebug-move-cursor): Use `cl-callf`.
+ (edebug-spec-p): Remove unused function.
+ (def-edebug-spec, edebug-spec-list, edebug-spec): Remove unused specs
+ (nothing in there gets instrumented anyway).
+ (edebug-tracing): Use `declare`.
+ (edebug-cancel-on-entry): Rename from `cancel-edebug-on-entry`.
+ (edebug-global-prefix): Rename from `global-edebug-prefix`.
+ (edebug-global-map): Rename from `global-edebug-map`.
+
+ * lisp/emacs-lisp/pcase.el (pcase-PAT): Remove `let`.
+ (let): Use `declare` instead.
+ (pcase--edebug-match-macro): Use new name `edebug-get-spec`.
+
+2021-02-12 Robert Pluim <rpluim@gmail.com>
+
+ Remove Motif support
+
+ * configure.ac: Remove support for configuring --with-x-toolkit=motif
+
+ * etc/NEWS: Mention removal of Motif support.
+
+2021-02-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow minor modes to specify major modes they're useful in
+
+2021-02-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/gv.el (gv-place): Simplify
+
+2021-02-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet/semantic/symref/: Use lexical-binding
+
+ * lisp/cedet/semantic/symref/cscope.el:
+ * lisp/cedet/semantic/symref/filter.el:
+ * lisp/cedet/semantic/symref/global.el:
+ * lisp/cedet/semantic/symref/grep.el:
+ * lisp/cedet/semantic/symref/idutils.el:
+ * lisp/cedet/semantic/symref/list.el: Use lexical-binding.
+
+2021-02-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet/semantic/decorate/: Use lexical-binding in all files
+
+ * lisp/cedet/semantic/decorate/include.el
+ (semantic-decoration-fileless-include-describe): Remove unused var `mm`.
+ * lisp/cedet/semantic/decorate/mode.el: Use lexical-binding.
+
+2021-02-11 Alan Mackenzie <acm@muc.de>
+
+ Make recursive minibuffers and recursive edits work together
+
+ * lisp/minibuffer.el (exit-minibuffer): When in a minibuffer, throw an error
+ should the command loop nesting level be wrong.
+
+ * src/lisp.h (minibuffer_quit_level): declare as an extern.
+ (command_loop_level): Move definition from src/window.h
+
+ * src/window.h (command_loop_level): move definition to src/lisp.h.
+
+ * src/eval.c (minibuffer_quit_level): Move this variable to file level from
+ being a static inside internal_catch.
+ (internal_catch): Simplify the logic.
+
+ * src/minibuf.c (Vcommand_loop_level_list): New variable.
+ (move_minibuffer_onto_frame): Set the major mode of *Minibuf-0*.
+ (Fminibuffer_innermost_command_loop_p): New primitive.
+ (Fabort_minibuffers): Check the command loop level before throwing t to 'exit,
+ and set minibuffer_quit_level too.
+ (read_minibuf): New variable calling_window.
+ Before stacking up minibuffers on the current mini-window, check that the
+ mini-window is not the current one.
+ Do not call choose_minibuf_frame from read_minibuf's unwinding process.
+ Bind calling_frame and calling_window over the recursive edit.
+ Set the new minibuffer's major mode directly.
+ Remove the switching away from the minibuffer after the recursive edit.
+ (get_minibuffer): Record the command loop level in new variable
+ Vcommand_loop_level_list. No longer set the major mode of a returned
+ minibuffer.
+ (minibuf_c_loop_level): New function.
+ (read_minibuf_unwind): New variables calling_frame, calling_window are unbound
+ from the binding stack. Remove old variable `window', which could not be set
+ reliably to the expired mini-window.
+ The expired minibuffer is determined as the nth in the list, rather than the
+ contents of the current or previous mini-window.
+ Switch the current window away from the mini-window here (moved from
+ read_minibuf).
+
+2021-02-11 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in erc-sound.el
+
+ * lisp/erc/erc-sound.el: Use lexical-binding. Remove redundant :group
+ args.
+
+2021-02-11 Stefan Kangas <stefan@marxist.se>
+
+ Drop XEmacs and SXEmacs support from EDE
+
+ * lisp/cedet/ede/emacs.el (ede-emacs-version): Drop XEmacs and
+ SXEmacs support from EDE.
+
+2021-02-11 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in various ede files
+
+ * lisp/cedet/ede/dired.el:
+ * lisp/cedet/ede/emacs.el:
+ * lisp/cedet/ede/make.el:
+ * lisp/cedet/ede/proj-archive.el:
+ * lisp/cedet/ede/proj-aux.el:
+ * lisp/cedet/ede/proj-misc.el:
+ * lisp/cedet/ede/proj-scheme.el:
+ * lisp/cedet/ede/srecode.el:
+ * lisp/cedet/ede/system.el: Use lexical-binding.
+
+2021-02-11 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-trampoline-compile): Default to speed 1.
+
+2021-02-11 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in wid-browse.el
+
+ * lisp/wid-browse.el: Use lexical-binding.
+ (widget-browse-mode): Use define-derived-mode.
+ (widget-browse-mode-hook): Remove redundant :group arg.
+ (widget-browse-action, widget-browse-value-create): Doc fixes.
+
+2021-02-11 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/ps-samp.el: Use lexical-binding.
+
+2021-02-11 Stefan Kangas <stefan@marxist.se>
+
+ Fix two Emacs version references in misc manuals
+
+ * doc/misc/forms.texi: Fix reference to Emacs version.
+ * doc/misc/remember.texi: Fix version reference to indicate Emacs
+ version instead of version of remember. The corresponding version
+ variable and header have been marked obsolete.
+
+2021-02-11 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix Octave double-quoted string line continuations
+
+ * lisp/progmodes/octave.el (octave-string-continuation-marker): New
+ defconst after octave-continuation-string.
+ (octave-continuation-string): Mention it in docstring.
+ (octave-maybe-insert-continuation-string): Mark unused function as
+ obsolete.
+ (octave-help-function): Simplify action.
+ (octave--indent-new-comment-line): Insert
+ octave-string-continuation-marker instead of
+ octave-continuation-string within double-quoted strings (bug#46420).
+ (octave-indent-new-comment-line):
+ * etc/NEWS: Describe new behavior.
+
+2021-02-11 Andrii Kolomoiets <andreyk.mad@gmail.com>
+
+ Use frame monitor in frame_float
+
+ * src/frame.c (frame_float): Use frame monitor attributes instead
+ of attributes of the main monitor (bug#46406).
+
+2021-02-11 Stefan Kangas <stefan@marxist.se>
+
+ Avoid having erc in irrelevant finder categories
+
+ * lisp/erc/erc-backend.el:
+ * lisp/erc/erc-button.el:
+ * lisp/erc/erc-dcc.el:
+ * lisp/erc/erc-identd.el:
+ * lisp/erc/erc-join.el:
+ * lisp/erc/erc-lang.el:
+ * lisp/erc/erc-log.el:
+ * lisp/erc/erc-match.el:
+ * lisp/erc/erc-menu.el:
+ * lisp/erc/erc-pcomplete.el:
+ * lisp/erc/erc-replace.el:
+ * lisp/erc/erc-spelling.el:
+ * lisp/erc/erc-stamp.el:
+ * lisp/erc/erc-track.el:
+ * lisp/erc/erc-xdcc.el: Remove irrelevant entries in Keywords header.
+
+2021-02-11 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/progmodes/cperl-mode.el (cperl-init-faces): Use regexp-opt.
+
+2021-02-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/play/decipher.el: Use lexical-binding
+
+ (decipher-mode-syntax-table): Move initialization into declaration.
+ (decipher-mode, decipher-stats-mode): Use `define-derived-mode`.
+ (decipher-stats-buffer): Use `buffer-local-value`.
+
+2021-02-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/leim/quail: Use lexical-binding
+
+ * lisp/leim/quail/hangul.el:
+ * lisp/leim/quail/indian.el:
+ * lisp/leim/quail/ipa.el:
+ * lisp/leim/quail/japanese.el:
+ * lisp/leim/quail/lao.el:
+ * lisp/leim/quail/latin-ltx.el:
+ * lisp/leim/quail/lrt.el:
+ * lisp/leim/quail/sisheng.el:
+ * lisp/leim/quail/thai.el:
+ * lisp/leim/quail/tibetan.el: Use lexical-binding.
+ * lisp/leim/quail/uni-input.el (ucs-input-method): Remove unused var `str`.
+
+2021-02-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/leim/quail: Use lexical-binding
+
+ * lisp/leim/quail/hangul.el:
+ * lisp/leim/quail/indian.el:
+ * lisp/leim/quail/ipa.el:
+ * lisp/leim/quail/japanese.el:
+ * lisp/leim/quail/lao.el:
+ * lisp/leim/quail/latin-ltx.el:
+ * lisp/leim/quail/lrt.el:
+ * lisp/leim/quail/sisheng.el:
+ * lisp/leim/quail/thai.el:
+ * lisp/leim/quail/tibetan.el: Use lexical-binding.
+ * lisp/leim/quail/uni-input.el (ucs-input-method): Remove unused var `str`.
+
+2021-02-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/subr.el (combine-change-calls-1): Don't presume integer args
+
+ This avoids problems where the `after-change-functions` end up called
+ with the new length rather than the old length.
+
+2021-02-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/macroexp.el (macroexp--fgrep): Break cycles
+
+ * test/lisp/emacs-lisp/macroexp-tests.el: New file.
+
+2021-02-10 Andrea Corallo <akrl@sdf.org>
+
+ Add late load pdumper hooks so these can call into Lisp
+
+ * src/pdumper.h (pdumper_do_now_and_after_late_load): New function.
+ * src/pdumper.c (dump_late_hooks, nr_dump_late_hooks): New static
+ variables.
+ (dump_metadata_for_pdumper): Add support for late load hooks.
+ (pdumper_do_now_and_after_late_load_impl): New functions.
+ (pdumper_load): Add support for late load hooks.
+ * src/window.c (init_window_once): Register
+ 'init_window_once_for_pdumper' to be executed after late load.
+
+2021-02-10 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2021-02-10 Juri Linkov <juri@linkov.net>
+
+ Fix ediff even/odd faces to increase their contrast and readability
+
+ * lisp/vc/ediff-init.el (ediff-even-diff-A, ediff-even-diff-B)
+ (ediff-even-diff-C, ediff-even-diff-Ancestor, ediff-odd-diff-A)
+ (ediff-odd-diff-B, ediff-odd-diff-C): Add :distant-foreground
+ "Black" for light background. For dark background
+ add :distant-foreground "White", and use darker shades of grey
+ for background colors (bug#46396).
+
+2021-02-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix build problem with previous facemenu change
+
+ * lisp/facemenu.el (facemenu-add-face-function): Move to avoid a
+ warning.
+ (list-colors-display): Autoload.
+
+2021-02-10 Paul Eggert <eggert@cs.ucla.edu>
+
+ Simplify and speed up after-find-file
+
+ Use newer primitives like file-accessible-directory-p to simplify
+ and speed up longstanding code in after-find-file.
+ * lisp/files.el (after-find-file):
+ Prefer file-exists-p + file-symlink-p to file-attributes +
+ file-symlink-p + file-chase-links + file-exists-p.
+ Prefer file-accessible-directory-p to directory-file-name +
+ file-attributes.
+ Prefer file-directory-p to file-name-directory + file-exists-p.
+
+2021-02-10 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix file lock issue (Bug#46397)
+
+ * src/filelock.c (current_lock_owner):
+ Also treat ENOTDIR as meaning the lock file does not exist.
+
+2021-02-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove the 'M-o' ('facemap-keymap') binding experimentally
+
+ * doc/lispref/maps.texi (Standard Keymaps):
+ * doc/lispref/keymaps.texi (Prefix Keys): Remove mentions.
+
+ * etc/facemenu-removal.txt: New temporary file.
+
+ * lisp/loadup.el: Don't load facemenu.el.
+ (removed-facemenu-command): New command.
+ (facemenu-keymap-restore): New function.
+
+ * lisp/textmodes/text-mode.el (center-paragraph): Remove binding.
+ (center-line): Remove binding.
+
+2021-02-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/edebug.el: Tweak last change
+
+ Use generic functions i.s.o `edebug--spec-op-function`.
+
+ <toplevel>: No need to register the &foo and :foo handler any more.
+ (edebug--handle-&-spec-op, edebug--handle-:-spec-op): New generic functions.
+ (edebug-match-specs): Use them.
+ (edebug--get-spec-op): Remove function.
+ (edebug-match-&optional, edebug-match-&rest, edebug-match-&or)
+ (edebug-match-&not, edebug-match-&key, edebug-match-&error)
+ (edebug-match-&define): Turn functions into methods of
+ `edebug--handle-&-spec-op`.
+ (edebug-match-:name, edebug-match-:unique): Turn functions into methods of
+ `edebug--handle-:-spec-op`.
+
+2021-02-10 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid assertion violation in callproc.c
+
+ * src/callproc.c (call_process): Avoid assertion violation when
+ DESTINATION is a cons cell '(:file . "FOO")'. (Bug#46426)
+
+2021-02-10 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in dns-mode.el
+
+ * lisp/textmodes/dns-mode.el: Use lexical-binding. Remove
+ redundant :group args.
+ * test/lisp/textmodes/dns-mode-tests.el
+ (dns-mode-tests-dns-mode-soa-increment-serial): New test.
+
+2021-02-10 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in mail-utils.el and add tests
+
+ * lisp/mail/mail-utils.el: Use lexical-binding.
+ * test/lisp/mail/mail-utils-tests.el: New file.
+
+2021-02-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/edebug.el: Don't overload `edebug-form-spec`.
+
+ The `edebug-form-spec` symbol property was used to store two different things:
+ the handlers for spec elements like `body` and the handlers for
+ spec operators like `&or`. But these two sets use different calling
+ conventions, so they're fundamentally incompatible.
+
+ So, move the handlers to spec operators to the new property
+ `edebug--spec-op-function`. This unbreaks Edebugging of:
+
+ (cl-flet ((f (&rest x) x)) 3)
+
+ * lisp/emacs-lisp/edebug.el <toplevel>: Split the alist of built in
+ spec elements into normal spec element and spec ops.
+ (edebug--get-spec-op): New function.
+ (edebug-match-specs): Use it.
+ (edebug-match-:name): Rename from `edebug-match-colon-name`.
+
+2021-02-10 Eli Zaretskii <eliz@gnu.org>
+
+ Bump FACE_CACHE_BUCKETS_SIZE to 1009
+
+ * src/xfaces.c (FACE_CACHE_BUCKETS_SIZE): Make it 1009, a prime
+ number, per the comment. Reported by Win Treese <treese@acm.org>.
+
+2021-02-10 Mattias Engdegård <mattiase@acm.org>
+
+ Fix local defvar scoping error (bug#46387)
+
+ This bug was introduced by the lexical variable constant propagation
+ mechanism. It was discovered by Michael Heerdegen.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-let-form)
+ (byte-optimize-body): Let the effects of a local defvar declaration be
+ scoped by let and let*, not any arbitrary Lisp expression body (such
+ as progn).
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--get-vars)
+ (bytecomp-local-defvar): New test.
+
+2021-02-10 Stefan Kangas <stefan@marxist.se>
+
+ Minor cleanup in imenu.el
+
+ * lisp/imenu.el: Doc fix; these examples have been removed. Remove
+ redundant :group args.
+
+2021-02-10 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in snmp-mode.el
+
+ * lisp/net/snmp-mode.el: Use lexical-binding. Remove redundant :group
+ args. Doc fix; remove outdated information.
+ (snmp-mode, snmpv2-mode): Add FIXME to use define-derived-mode.
+
+2021-02-10 Stefan Kangas <stefan@marxist.se>
+
+ Declare empty macro imenu-progress-menu obsolete
+
+ * lisp/imenu.el: Remove commented out code.
+ (imenu-progress-message): Declare macro obsolete.
+
+ * lisp/erc/erc-imenu.el (erc-create-imenu-index):
+ * lisp/net/snmp-mode.el (snmp-mode-imenu-create-index):
+ * lisp/progmodes/antlr-mode.el (antlr-imenu-create-index-function):
+ Don't use or mention above obsolete macro.
+
+2021-02-10 Protesilaos Stavrou <info@protesilaos.com>
+
+ Update NEWS entry for vc-dir faces
+
+ * NEWS: Remove reference to specific backend, as it now applies to all
+ of them. Update name of 'vc-dir-status-ignored'.
+
+ This follows from the discussion in bug#46358.
+
+2021-02-10 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/cedet/semantic/bovine/gcc.el: Use lexical-binding.
+
+2021-02-10 Stefan Kangas <stefan@marxist.se>
+
+ Move cedet test resource files to follow our conventions
+
+ * test/lisp/cedet/semantic-utest-ia.el (ert, ert-x): Require.
+ (cedet-utest-directory, semantic-utest-test-directory): Remove
+ variables.
+ (semantic-utest-ia-doublens.cpp, semantic-utest-ia-subclass.cpp)
+ (semantic-utest-ia-typedefs.cpp, semantic-utest-ia-struct.cpp)
+ (semantic-utest-ia-templates.cpp, semantic-utest-ia-using.cpp)
+ (semantic-utest-ia-nsp.cpp, semantic-utest-ia-localvars.cpp)
+ (semantic-utest-ia-namespace.cpp)
+ (semantic-utest-ia-sppcomplete.c, semantic-utest-ia-varnames.c)
+ (semantic-utest-ia-javacomp.java)
+ (semantic-utest-ia-varnames.java, semantic-utest-ia-wisent.wy)
+ (semantic-utest-ia-texi, semantic-utest-ia-make)
+ (semantic-utest-ia-srecoder): Use 'ert-resource-file'. Don't
+ check if file exists; we can assume that it does.
+
+ * test/manual/cedet/tests/testjavacomp.java:
+ * test/manual/cedet/tests/testlocalvars.cpp:
+ * test/manual/cedet/tests/testnsp.cpp:
+ * test/manual/cedet/tests/testsppcomplete.c:
+ * test/manual/cedet/tests/teststruct.cpp:
+ * test/manual/cedet/tests/testsubclass.cpp:
+ * test/manual/cedet/tests/testsubclass.hh:
+ * test/manual/cedet/tests/testtemplates.cpp:
+ * test/manual/cedet/tests/testtypedefs.cpp:
+ * test/manual/cedet/tests/testusing.cpp:
+ * test/manual/cedet/tests/testusing.hh:
+ * test/manual/cedet/tests/testvarnames.c:
+ * test/manual/cedet/tests/testvarnames.java:
+ * test/manual/cedet/tests/testwisent.wy: Move from here...
+ * test/lisp/cedet/semantic-utest-ia-resources/testjavacomp.java:
+ * test/lisp/cedet/semantic-utest-ia-resources/testlocalvars.cpp:
+ * test/lisp/cedet/semantic-utest-ia-resources/testnsp.cpp:
+ * test/lisp/cedet/semantic-utest-ia-resources/testsppcomplete.c:
+ * test/lisp/cedet/semantic-utest-ia-resources/teststruct.cpp:
+ * test/lisp/cedet/semantic-utest-ia-resources/testsubclass.cpp:
+ * test/lisp/cedet/semantic-utest-ia-resources/testsubclass.hh:
+ * test/lisp/cedet/semantic-utest-ia-resources/testtemplates.cpp:
+ * test/lisp/cedet/semantic-utest-ia-resources/testtypedefs.cpp:
+ * test/lisp/cedet/semantic-utest-ia-resources/testusing.cpp:
+ * test/lisp/cedet/semantic-utest-ia-resources/testusing.hh:
+ * test/lisp/cedet/semantic-utest-ia-resources/testvarnames.c:
+ * test/lisp/cedet/semantic-utest-ia-resources/testvarnames.java:
+ * test/lisp/cedet/semantic-utest-ia-resources/testwisent.wy:
+ ...to here.
+
+2021-02-10 Stefan Kangas <stefan@marxist.se>
+
+ Convert tests for srecode/fields.el to ert
+
+ * test/manual/cedet/srecode-tests.el: Move from here...
+ * test/lisp/cedet/srecode/fields-tests.el: ...to here.
+ (srecode-field-utest-impl): Convert test to ert. Silence
+ byte-compiler.
+
+ * test/manual/cedet/cedet-utests.el (cedet-utest-libs): Don't
+ list the above moved file.
+
+2021-02-10 Stefan Kangas <stefan@marxist.se>
+
+ Make texinfmt-version variable obsolete
+
+ * lisp/textmodes/texinfmt.el (texinfmt-version): Make variable and
+ command obsolete in favour of 'emacs-version'.
+ (texinfo-format-region, texinfo-format-buffer-1): Use
+ 'emacs-version' instead of above obsolete variable.
+
+2021-02-10 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in bib-mode.el
+
+ * lisp/textmodes/bib-mode.el: Use lexical-binding. Remove
+ redundant :group args.
+
+2021-02-10 Stefan Kangas <stefan@marxist.se>
+
+ Move semantic/format.el tests to follow our conventions
+
+ * test/lisp/cedet/semantic-utest-fmt.el: Move from here...
+ * test/lisp/cedet/semantic/format-tests.el: ...to here.
+ (ert, ert-x): Require.
+ (semantic-fmt-utest-file-list): Use ert-resource-file.
+ * test/manual/cedet/tests/test-fmt.cpp:
+ * test/manual/cedet/tests/test-fmt.el: Move from here...
+ * test/lisp/cedet/semantic/format-resources/test-fmt.cpp:
+ * test/lisp/cedet/semantic/format-resources/test-fmt.el: ...to here.
+
+2021-02-10 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in some test files
+
+ * test/manual/cedet/ede-tests.el:
+ * test/manual/cedet/srecode-tests.el:
+ * test/manual/cedet/tests/test.el: Use lexical-binding.
+
+ * test/manual/etags/el-src/TAGTEST.EL: Add lexical-binding cookie.
+ * test/manual/etags/ETAGS.good_1: Update expected result for the
+ above change.
+
+2021-02-10 Stefan Kangas <stefan@marxist.se>
+
+ Change default semantic-lex-analyzer to semantic-lex
+
+ * lisp/cedet/semantic/lex.el (semantic-lex-analyzer): Change default
+ to semantic-lex, since semantic-flex was obsolete and has been
+ removed.
+
+2021-02-10 Stefan Kangas <stefan@marxist.se>
+
+ Convert many manual cedet tests to ert
+
+ * test/manual/cedet/cedet-utests.el
+ (cedet-files-utest): Move test from here...
+ * test/lisp/cedet/cedet-files-tests.el: ...to this new file.
+
+ * test/manual/cedet/srecode-tests.el
+ (srecode-document-function-comment-extract-test): Move test from
+ here...
+ * test/lisp/cedet/srecode/document-tests.el: ...to this new file.
+
+ * test/manual/cedet/cedet-utests.el
+ (inversion-unit-test): Move test from here...
+ * test/lisp/cedet/inversion-tests.el: ...to this new file.
+
+ * test/manual/cedet/semantic-tests.el
+ (semantic-gcc-test-output-parser): Move test from here...
+ * test/lisp/cedet/semantic/bovine/gcc-tests.el: ...to this new file.
+
+ * test/manual/cedet/semantic-tests.el
+ (semantic-test-data-cache): Move test from here...
+ * test/lisp/cedet/semantic/fw-tests.el: ...to this new file.
+
+2021-02-10 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in almost all of play/*.el
+
+ * lisp/play/5x5.el: Use lexical-binding.
+ (5x5-draw-grid-end, 5x5-draw-grid, 5x5-solver)
+ (5x5-solve-suggest): Silence byte-compiler.
+
+ * lisp/play/cookie1.el: Use lexical-binding.
+ (cookie-shuffle-vector, cookie-apropos): Silence byte-compiler.
+
+ * lisp/play/zone.el: Use lexical-binding.
+ (zone): Convert lambda to proper lexical closure.
+ (zone-replace-char, zone-fill-out-screen): Silence byte-compiler.
+
+ * lisp/play/blackbox.el:
+ * lisp/play/doctor.el:
+ * lisp/play/gametree.el:
+ * lisp/play/hanoi.el: Use lexical-binding.
+
+ * test/lisp/play/cookie1-resources/cookies:
+ * test/lisp/play/cookie1-tests.el: New files.
+
+2021-02-10 Protesilaos Stavrou <info@protesilaos.com>
+
+ Refine use of vc-dir faces; apply to all backends
+
+ * lisp/vc/vc-dir.el (vc-default-dir-printer): Add check for the
+ "ignored" status and make 'vc-dir-status-edited' the default face.
+ Also extend condition for more states that qualify as "warnings".
+
+ (vc-dir-ignored, vc-dir-status-ignored): Rename face for consistency.
+
+ * lisp/vc/vc-git.el (vc-git-dir-printer): Use the
+ 'vc-dir-status-edited' as the default for the Git backend. And
+ reference the renamed face. Also stop treating the empty stash
+ differently from other header values.
+
+ * lisp/vc/vc-bzr.el (vc-bzr-dir-extra-headers): Implement new faces.
+ * lisp/vc/vc-cvs.el (vc-cvs-dir-extra-headers): Same.
+ * lisp/vc/vc-hg.el (vc-hg-dir-extra-headers): Same.
+ * lisp/vc/vc-svn.el (vc-svn-dir-extra-headers): Same.
+
+ This follows from the discussion in bug#46358.
+
+2021-02-09 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Tiny simplification to read-char-by-name
+
+ * lisp/international/mule-cmds.el (mule--ucs-names-sort-by-code):
+ Sort with car-less-than-car instead of slower lambda.
+ (mule--ucs-names-affixation): Just stick character into a list to
+ avoid trip through format and char-to-string.
+ (read-char-by-name): Quote function symbols as such.
+
+2021-02-09 Eli Zaretskii <eliz@gnu.org>
+
+ Fix syntax category of some characters
+
+ * lisp/international/characters.el (modify-syntax-entry): Fix
+ syntax of numerical subscripts and superscripts. (Bug#46240)
+
+2021-02-09 Juri Linkov <juri@linkov.net>
+
+ * lisp/net/dictionary.el: Dictionary improvements (bug#45262)
+
+ * lisp/net/dictionary.el (dictionary-link-dictionary): New defcustom.
+ (dictionary-mark-reference): Use dictionary-link-dictionary.
+ (dictionary-post-buffer-hook): New defcustom.
+ (dictionary-post-buffer): Run dictionary-post-buffer-hook.
+ (dictionary-mode-map): Bind 'S-SPC' to scroll-down-command.
+ (dictionary-search-default): Use possibly multi-word data at point.
+
+2021-02-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Use lexical-binding in a few more scattered files
+
+ * lisp/registry.el: Use lexical-binding.
+ (registry-reindex): Remove unused var `values`.
+
+ * lisp/cedet/pulse.el: Use lexical-binding.
+
+ * lisp/cedet/semantic/idle.el: Use lexical-binding.
+ (semantic-idle-core-handler): Remove unused var `safe`.
+ (ede-auto-add-method): Declare var.
+ (define-semantic-idle-service): Use `declare`. Remove unused var `setup`.
+ (pulse-flag): Declare var.
+
+ * lisp/net/ldap.el: Use lexical-binding.
+ (ldap-search-internal): Remove unused var `proc`.
+
+ * lisp/net/mairix.el: Use lexical-binding.
+ Remove redundant `:group` args.
+ (mairix-widget-create-query): Remove unnused var `allwidgets`.
+
+2021-02-09 Juri Linkov <juri@linkov.net>
+
+ New options read-char-by-name-sort and read-char-by-name-group (bug#46240)
+
+ * lisp/international/mule-cmds.el (mule--ucs-names-sort-by-code)
+ (mule--ucs-names-group): New functions.
+ (read-char-by-name-sort, read-char-by-name-group): New defcustoms.
+ (read-char-by-name): Use them.
+
+2021-02-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet/{semantic/scope.el,ede/project-am.el}: Use lexical-scoping
+
+ * lisp/cedet/ede/project-am.el: Remove redundant `:group` args.
+ (recentf-exclude): Declare variable.
+ (project-am--with-makefile-current): New function extracted from
+ `project-am-with-makefile-current`. Use `with-current-buffer` and
+ `unwind-protect`.
+ (project-am-with-makefile-current): Use `declare` and
+ `project-am--with-makefile-current`.
+ (project-am-with-config-current): Use `declare` and `with-temp-buffer`.
+ (project-am-extract-shell-variable): Turn it into a `defun`; the use of
+ `defmacro` appears to have been a plain mistake.
+
+2021-02-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize--pcase): New macro
+
+ (byte-optimize-form-code-walker): Use it.
+
+2021-02-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/macroexp.el: Break cycle with bytecomp/byte-opt
+
+ The recent change in macroexp triggered a cyclic dependency error
+ during eager macroexpansion when neither `bytecomp` nor `byte-opt` had
+ been byte-compiled yet. This fixes it by moving the offending
+ function to macroexp.el.
+
+ * lisp/emacs-lisp/macroexp.el (macroexp--unfold-lambda): Move from
+ byte-opt.el and rename.
+ (macroexp--expand-all): Use it.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-compile-unfold-lambda): Move to
+ macroexp.el.
+ (byte-compile-inline-expand, byte-optimize-form-code-walker):
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-form):
+ Use `macroexp--unfold-lambda` instead.
+
+2021-02-09 Stefan Kangas <stefan@marxist.se>
+
+ Remove some dead, commented out code from lisp-mode.el
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-data-mode-syntax-table):
+ Remove code commented out since 2005.
+
+2021-02-09 Stefan Kangas <stefan@marxist.se>
+
+ Load all generic-x.el modes unconditionally
+
+ * lisp/generic-x.el: Load all modes unconditionally.
+ (generic-default-modes, generic-mswindows-modes)
+ (generic-unix-modes, generic-other-modes)
+ (generic-extras-enable-list): Make obsolete.
+ Ref: https://lists.gnu.org/r/emacs-devel/2021-01/msg01403.html
+
+2021-02-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Note that the `values' variable is now obsolete
+
+ * src/lread.c (syms_of_lread): Note that it's obsolete in the doc
+ string (because we can't mark it as obsolete "properly" yet,
+ because that leads to compilation warnings when somebody
+ (let (values) ... values).
+
+2021-02-09 Alan Mackenzie <acm@muc.de>
+
+ Allow exit-minibuffer to be called from Lisp code. Fixes bug #46373
+
+ * lisp/minibuffer.el (exit-minibuffer): Throw the error "Not in most nested
+ minibuffer" only when the current buffer is a minibuffer (thus the command
+ came directly from a key binding).
+
+ * doc/lispref/minibuf.texi (Minibuffer Commands): Change the documentation
+ accordingly.
+
+2021-02-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make pcomplete-ignore-case obsolete
+
+ * lisp/pcomplete.el (pcomplete-completions-at-point)
+ (pcomplete-stub, pcomplete--entries, pcomplete-insert-entry):
+ * lisp/eshell/em-cmpl.el (eshell-cmpl-initialize):
+ * lisp/eshell/em-cmpl.el (eshell-cmpl-ignore-case):
+ * lisp/erc/erc-pcomplete.el (pcomplete-erc-setup): Use
+ `completion-ignore-case' instead (bug#23117).
+
+ * lisp/pcomplete.el (pcomplete-ignore-case): Make obsolete.
+
+2021-02-09 Matt Armstrong <matt@rfc20.org>
+
+ Preserve leading whitespace in `lm-commentary'.
+
+ * lisp/emacs-lisp/lisp-mnt.el (lm-commentary): Preserve leading
+ whitespace (bug#46364).
+
+2021-02-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move all usages of `values' to `values--store-value'
+
+ * lisp/simple.el (eval-expression):
+ * lisp/progmodes/elisp-mode.el (eval-last-sexp):
+ * lisp/emacs-lisp/pp.el (pp-eval-expression):
+ * lisp/emacs-lisp/edebug.el (edebug-eval-expression):
+ * lisp/emacs-lisp/pp.el (pp-eval-expression):
+ * lisp/emacs-lisp/edebug.el (edebug-eval-expression):
+ * lisp/cedet/data-debug.el (data-debug-eval-expression): Use it
+ instead of pushing to `values' directly (bug#22066).
+
+ * lisp/subr.el (values--store-value): New function.
+
+2021-02-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't use `values' in elisp--eval-defun
+
+ * lisp/progmodes/elisp-mode.el (elisp--eval-defun): Don't use
+ `values', since it's being deprecated (bug#22066).
+
+2021-02-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Finish customize-changed-options/customize-changed fix up
+
+ * doc/emacs/custom.texi (Specific Customization): Fix
+ customize-changed/customize-changed-options documentation.
+ * lisp/cus-dep.el (custom-make-dependencies): Adjust doc string
+ (bug#23085).
+
+ * lisp/menu-bar.el (menu-bar-custom-menu): Adjust menu options.
+
+2021-02-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix count-lines problem in non-ASCII buffers
+
+ * src/fns.c (Fline_number_at_pos): Get the correct start position
+ in non-ASCII buffers (bug#22763).
+
+2021-02-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/gnus-topic.el: Fix a backward incompatibility
+
+ (gnus-topic-insert-topic-line): Make the vars used in
+ `gnus-topic-line-format-spec` dynamically scoped since it seems
+ that they're sometimes accessed from functions called by
+ `gnus-topic-line-format-spec` :-(
+
+ * lisp/gnus/gnus-util.el (gnus--\,@): Move macro to here...
+ * lisp/gnus/gnus-art.el (gnus--\,@): .. from here.
+
+ * lisp/gnus/gnus.el (gnus-method-to-server): Apply DeMorgan.
+
+2021-02-08 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Run Gnus group names through regexp-quote when matching results
+
+ * lisp/gnus/gnus-search.el (gnus-search-indexed-parse-output): Be more
+ careful about making sure group names will match search results
+ correctly.
+
+2021-02-08 Eli Zaretskii <eliz@gnu.org>
+
+ Fix scrolling past tall images
+
+ * src/xdisp.c (try_window): Don't try checking the margins if the
+ window is vscrolled, as that could cause unnecessary recentering
+ when tall images are displayed. (Bug#46320)
+
+2021-02-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/indent.el (beginning-of-line-text): Mark it as a movement command
+
+ So that combining it with `shift` selects the text, as usual, in case
+ you have it bound for example to `C-a` in a mode like `enriched-mode`.
+
+2021-02-08 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/avoid.el: Doc fixes.
+
+2021-02-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Record the value of `C-x C-e' in `values'
+
+ * lisp/progmodes/elisp-mode.el (eval-last-sexp): Record the value
+ in `values' (bug#22066) since we're messaging it.
+
+2021-02-08 Protesilaos Stavrou <info@protesilaos.com>
+
+ Add vc-dir faces; also apply them to vc-git
+
+ * etc/NEWS: Document the new faces.
+
+ * lisp/vc/vc-dir.el (vc-dir-header, vc-dir-header-value)
+ (vc-dir-directory, vc-dir-file, vc-dir-mark-indicator)
+ (vc-dir-status-warning, vc-dir-status-edited, vc-dir-status-up-to-date)
+ (vc-dir-ignored): Add new faces.
+
+ * lisp/vc/vc-git.el (vc-git-permissions-as-string, vc-git-dir-printer)
+ (vc-git-dir-extra-headers): Apply new faces (bug#46358).
+
+2021-02-08 Sean Whitton <spwhitton@spwhitton.name>
+
+ Bind clone-buffer to C-x x n
+
+ * lisp/bindings.el (ctl-x-x-map): Bind clone-buffer.
+ * etc/NEWS: Document the change (bug#46369).
+
+2021-02-08 Anticrisis <anticrisisg@gmail.com> (tiny change)
+
+ Fix tcl-mode indentation of namespaced code
+
+ * lisp/progmodes/tcl.el (tcl-calculate-indent): Fix indentation
+ when using namespaces (bug#44834).
+ (tcl-beginning-of-defun-function): Remove. This partially reverts
+ cd5bb4bf3dbad8941d25823f398b595b8f0edbb9.
+
+2021-02-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify "changes" in CONTRIBUTE
+
+ * CONTRIBUTE: Clarify that "changes" doesn't include removing code
+ (bug#44834).
+
+2021-02-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `C-a' in enriched-mode behave more line in other modes
+
+ * lisp/textmodes/enriched.el (enriched-mode-map): Don't rebind
+ beginning-or-line, because it makes `C-S-a' not mark the region,
+ and it doesn't allow actually moving to the beginning of the line
+ if the line starts with characters in `adaptive-fill-regexp'
+ (bug#22554).
+
+2021-02-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix noninteractive gnus-article-press-button
+
+ * lisp/gnus/gnus-art.el (gnus-article-press-button): Make the `b'
+ summary mode command work again.
+
+2021-02-08 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in a few more places
+
+ * lisp/calc/calc-embed.el (calc-embedded-make-info):
+ * lisp/calc/calcalg2.el (calcFunc-integ):
+ * lisp/comint.el (comint-mode):
+ * lisp/epa.el (epa--list-keys, epa--show-key):
+ * lisp/epg.el (epg--start):
+ * lisp/vc/ediff-util.el (ediff-activate-mark): Prefer setq-local.
+
+2021-02-08 Stefan Kangas <stefan@marxist.se>
+
+ Add tests for count-lines
+
+ * test/lisp/simple-tests.el (simple-test-count-lines)
+ (simple-test-count-lines/ignore-invisible-lines): Add tests.
+
+2021-02-07 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Fix namazu search result parsing in gnus-search
+
+ * lisp/gnus/gnus-search.el (gnus-search-indexed-extract): This method
+ is documented to leave point at the end of the extracted search
+ result. The namazu implementation wasn't doing that.
+
+2021-02-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify when activate-mark-hook is run
+
+ * doc/lispref/markers.texi (The Mark):
+ * lisp/simple.el (activate-mark-hook): Clarify when the hook is
+ run (bug#23444).
+
+2021-02-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use `line-number-at-pos' in `count-lines'
+
+ * lisp/simple.el (count-lines): Use `line-number-at-pos', which
+ should be faster.
+
+2021-02-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix language-environment and font selection on MS-Windows
+
+ These changes improve setting the language-environment and font
+ selection when MS-Windows returns useless "ZZZ" as the "language
+ name", which then disrupts all the setup of the locale-dependent
+ stuff, and in particular font selection.
+ * lisp/w32-fns.el (w32-charset-info-alist): Add an element for
+ "iso8859-5", in case LANG is set to something unusable, like
+ "ZZZ". This allows fonts capable of displaying Cyrillic
+ characters to be used even when language preferences are screwed.
+
+ * src/w32.c (init_environment): If GetLocaleInfo returns "ZZZ" as
+ the "language name" for LOCALE_USER_DEFAULT, try again with locale
+ ID based on what GetUserDefaultUILanguage returns. (Bug#39286)
+
+2021-02-07 Tino Calancha <ccalancha@suse.com>
+
+ Add command to recenter errors from Occur/Grep buffers
+
+ To scroll up/down the current displayed occurrence/error
+ without abandon the Occur/Grep buffer.
+
+ Add also a command 'recenter-other-window' to recenter
+ the other window from any kind of buffer.
+
+ * lisp/window.el (recenter-other-window): New command.
+ Bind recenter-other-window to S-M-C-l (Bug#46119).
+
+ * lisp/simple.el (recenter-current-error): New command.
+ * lisp/progmodes/grep.el (grep-mode-map):
+ Delete bidings for n and p.
+
+ * lisp/progmodes/compile.el (compilation-minor-mode-map):
+ Move here the n and p bindings.
+ Bind `recenter-current-error' to l.
+ * lisp/replace.el (occur-mode-map):
+ Same.
+
+ * doc/emacs/windows.texi (Other Window):
+ * doc/emacs/display.texi (Recentering):
+ Document recenter-other-window.
+
+ * etc/NEWS (Changes in Specialized Modes and Packages in Emacs 28.1):
+ Announce the changes.
+
+2021-02-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow Fline_number_at_pos being called with a marker
+
+ * src/fns.c (Fline_number_at_pos): Also allow being called with a
+ marker (since the Lisp function allowed that).
+
+2021-02-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move line-number-at-pos to C
+
+ * doc/lispref/positions.texi (Text Lines): Revert previous change.
+
+ * lisp/simple.el (line-number-at-pos): Remove definition.
+
+ * lisp/simple.el (count-lines): Revert back to using
+ `forward-line', because there seems to be a disagreement on how
+ lines should be counted in a region...
+
+ * src/fns.c (Fline_number_at_pos): Rename from
+ Fline_number_at_position and adjust parameter list.
+
+2021-02-07 Stefan Kangas <stefan@marxist.se>
+
+ Minor doc fixes in dictionary-connection.el
+
+ * lisp/net/dictionary-connection.el:
+ (dictionary-connection-p, dictionary-connection-read-to-point):
+ Minor doc fixes to adhere to our conventions.
+
+2021-02-07 Stefan Kangas <stefan@marxist.se>
+
+ Fix copyright and license statement in dictionary*.el
+
+ * lisp/net/dictionary-connection.el:
+ * lisp/net/dictionary.el: Add copyright statement and fix license
+ statement.
+
+2021-02-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new function 'line-number-at-position'
+
+ * doc/lispref/positions.texi (Text Lines): Document it.
+
+ * lisp/simple.el (count-lines): Use it.
+ (line-number-at-pos): Ditto.
+
+ * src/fns.c (Fline_number_at_position): New function (bug#22763).
+
+2021-02-07 Stefan Kangas <stefan@marxist.se>
+
+ Various doc fixes in dictionary.el
+
+ * lisp/net/dictionary.el (dictionary-set-server-var)
+ (dictionary-server, dictionary-port)
+ (dictionary-default-dictionary)
+ (dictionary-default-popup-strategy, dictionary-proxy-server)
+ (dictionary-proxy-port, dictionary-description-open-delimiter)
+ (dictionary-description-close-delimiter)
+ (dictionary-window-configuration, dictionary-selected-window)
+ (dictionary-position-stack, dictionary-data-stack)
+ (dictionary-positions, dictionary-current-data)
+ (dictionary-connection, dictionary-instances)
+ (dictionary-color-support, dictionary-word-history)
+ (dictionary-mode, dictionary, dictionary-check-connection)
+ (dictionary-mode-p, dictionary-send-command)
+ (dictionary-read-reply-and-split, dictionary-check-reply)
+ (dictionary-check-initial-reply, dictionary-store-state)
+ (dictionary-store-positions, dictionary-new-search)
+ (dictionary-new-search-internal, dictionary-do-search)
+ (dictionary-display-search-result)
+ (dictionary-display-word-definition)
+ (dictionary-special-dictionary, dictionary-set-strategy)
+ (dictionary-tooltip-dictionary, dictionary-switch-tooltip-mode)
+ (dictionary-tooltip-mode, global-dictionary-tooltip-mode): Doc fixes
+ to adhere to our conventions.
+
+2021-02-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Fix inferior octave single-quote font lock"
+
+ This reverts commit 9e68413c7f0a7f71e1cee923ace7282d14c2e686.
+
+ This patch led to bug#46327:
+
+ x = [2 2]'
+ disp(x)
+
+ Which meant that the transpose operator was interpreted
+ as the start of a string.
+
+2021-02-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Reverse customize-changed and customize-changed-options aliasing
+
+ * lisp/cus-edit.el (customize-changed): Rename from
+ customize-changed-options (bug#23085), since the old name doesn't
+ reflect what it does: It's not just about user options, but also
+ faces and the like.
+ (customize-changed-options): Make into an obsolete alias.
+
+2021-02-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify that #s(hash-table ...) doesn't always create a new hash table
+
+ * doc/lispref/hash.texi (Creating Hash): Note that the printed
+ representation doesn't necessarily create a new table (bug#23417).
+
+ * doc/lispref/lists.texi (Rearrangement): Link to Self-Evaluating
+ Forms to further expand upon immutability.
+
+2021-02-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add more commands to the new `C-x x' keymap
+
+ * doc/emacs/killing.texi (Accumulating Text):
+ * doc/emacs/display.texi (Line Truncation):
+ * doc/emacs/buffers.texi (Misc Buffer): Document it.
+
+ * lisp/bindings.el (ctl-x-x-map): Add new bindings for
+ rename-buffer, rename-uniquely, insert-buffer and
+ toggle-truncate-lines.
+
+2021-02-07 Sean Whitton <spwhitton@spwhitton.name>
+
+ Move 'revert-buffer' global binding to 'C-x g g'
+
+ * lisp/bindings.el: Define ctl-x-g-map and bind 'revert-buffer' to
+ 'C-x x g' globally.
+ * doc/emacs/files.texi: Replace 'C-x g' with 'C-x x g'.
+ * etc/NEWS: Document the change (bug#46300).
+
+2021-02-07 Petteri Hintsanen <petterih@iki.fi>
+
+ Fix example in Sequence Functions node in the manual
+
+ * doc/lispref/sequences.texi (Sequence Functions): Fix the result
+ from the example.
+
+2021-02-06 Dmitry Gutov <dgutov@yandex.ru>
+
+ Revert "Fix the previous change"
+
+ This reverts commit fc37dc298f27025823fad2d944e11cc7ee6a058d.
+
+ That change was only needed in the release branch.
+
+2021-02-06 Mattias Engdegård <mattiase@acm.org>
+
+ Fix spurious warnings from unwise condition order in inlined code
+
+ These are both conditions having the form (and A B) where A is
+ side-effect-free and B may be known to be nil at compile time.
+ The compiler will then warn about A being useless and thrown away.
+ The fix is to test B first.
+
+ * lisp/gnus/gnus.el (gnus-method-to-server):
+ Test `(not no-enter-cache)` first.
+ (gnus-server-get-method): Test `group` first.
+
+2021-02-06 Mattias Engdegård <mattiase@acm.org>
+
+ Constprop of lexical variables
+
+ Lexical variables bound to a constant value (symbol, number or string)
+ are substituted at their point of use and the variable then eliminated
+ if possible. Example:
+
+ (let ((x (+ 2 3))) (f x)) => (f 5)
+
+ This reduces code size, eliminates stack operations, and enables
+ further optimisations. The implementation is conservative, and is
+ strongly curtailed by the presence of variable mutation, conditions
+ and loops.
+
+ * lisp/emacs-lisp/byte-opt.el
+ (byte-optimize-enable-variable-constprop)
+ (byte-optimize-warn-eliminated-variable): New constants.
+ (byte-optimize--lexvars, byte-optimize--vars-outside-condition)
+ (byte-optimize--vars-outside-loop, byte-optimize--dynamic-vars):
+ New dynamic variables.
+ (byte-optimize--substitutable-p, byte-optimize-let-form):
+ New functions.
+ (byte-optimize-form-code-walker): Adapt clauses for variable
+ constprop, and add clauses for 'setq' and 'defvar'.
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-test-var)
+ (bytecomp-test-get-var, bytecomp-test-identity)
+ (byte-opt-testsuite-arith-data): Add test cases.
+
+2021-02-06 Ioannis Kappas <ioannis.kappas@gmail.com> (tiny change)
+
+ New test for src/process.c on MS-Windows
+
+ * test/src/process-tests.el (process-sentinel-interrupt-event):
+ New test. (Bug#46284)
+
+2021-02-06 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Fix TEXT check in gnus-search IMAP search
+
+ * lisp/gnus/gnus-search.el (gnus-search-run-search): It's a string,
+ not a buffer!
+
+2021-02-06 Martin Rudalics <rudalics@gmx.at>
+
+ Permit zero value for 'child-frame-border-width' parameter (Bug#46184)
+
+ * doc/lispref/frames.texi (Layout Parameters): Update entry on
+ 'child-frame-border-width' parameter.
+ * src/frame.c (make_frame): Init child_frame_border_width to -1.
+ (Fframe_child_frame_border_width): Return internal border width if
+ child frame border width parameter is nil.
+ (gui_report_frame_params): Report nil as child frame border
+ width parameter if the frame value is negative.
+ * src/frame.h (FRAME_INTERNAL_BORDER_WIDTH): Return value of
+ child frame border width only if it is not negative.
+ * src/xfns.c (Fx_create_frame): Default child frame border to -1
+ when recording it in its frame slot via gui_default_parameter.
+ * src/nsfns.m (ns_set_child_frame_border_width): Handle nil ARG.
+ (Fx_create_frame): Default child frame border width parameter to
+ nil.
+ * src/w32fns.c (w32_set_child_frame_border_width): Handle nil ARG.
+ (Fx_create_frame): Default child frame border width parameter to
+ nil.
+ * src/xfns.c (x_set_child_frame_border_width): Handle nil ARG.
+ (Fx_create_frame): Default child frame border width parameter to
+ nil.
+
+2021-02-06 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 8ad48a0bdd (origin/emacs-27) Improve doc string of 'text-scale-adjust'
+ 7a25ff767d Clarify the indent-rigidly doc string
+ 6c5ddf0e0b Fix two small tab bar issues
+ c71e08eba9 Fix last change in syntax.texi
+
+ # Conflicts:
+ # lisp/indent.el
+
+2021-02-06 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 8c27af3ff4 Clarify how transient indentation modes are exited in the ...
+ fc37dc298f Fix the previous change
+
+2021-02-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous change in testcover.el
+
+ * lisp/emacs-lisp/testcover.el
+ (testcover-analyze-coverage-edebug-after): The wrapper macro is
+ called `1value', not `testcover-1value'.
+
+2021-02-06 Eli Zaretskii <eliz@gnu.org>
+
+ Support file names with whitespace in Nroff mode
+
+ * lisp/textmodes/nroff-mode.el (nroff-view): Quote argument of
+ 'Man-getpage-in-background' to support file names with special
+ characters. (Bug#46051)
+
+2021-02-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak provided-mode-derived-p doc string
+
+ * lisp/subr.el (provided-mode-derived-p): Remove detail about "or
+ their aliases", since that seems self-evident (bug#46331) (and
+ derived-mode-p works the same, and doesn't have the bit in
+ question).
+
+2021-02-06 Eli Zaretskii <eliz@gnu.org>
+
+ Improve doc string of 'text-scale-adjust'
+
+ * lisp/face-remap.el (text-scale-adjust): Clarify that "default
+ face height" refers to the 'default' face. (Bug#25168)
+
+2021-02-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Warn in message.el when sending encryptable mail
+
+ * lisp/gnus/message.el (message-send): Query if it looks like
+ encryption was intended, but is not going to happen.
+
+ * lisp/gnus/mml-sec.el (mml-secure-is-encrypted-p): Allow saying
+ whether there's any <#secure tags present (bug#24411).
+
+2021-02-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Rename the `1value' symbol in testcover.el
+
+ * lisp/emacs-lisp/testcover.el: Rename the symbol `1value'
+ throughout the file to `testcover-1value' to allow using the
+ variable in code that's to be tested (bug#25471).
+
+2021-02-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow provided-mode-derived-p to work on aliases
+
+ * lisp/subr.el (provided-mode-derived-p): Allow this to work on
+ modes that are aliases of other modes (bug#46331). For instance:
+ (provided-mode-derived-p 'javascript-mode 'prog-mode)
+
+2021-02-06 Michael Albinus <michael.albinus@gmx.de>
+
+ Modernize use of prompts in auth-source.el
+
+ * lisp/auth-source.el (auth-source-search): Adapt docstring
+ (auth-source-format-prompt): Remove trailing ": ".
+ (auth-source-netrc-create, auth-source-secrets-create)
+ (auth-source-plstore-create): Adapt prompts. Use `format-prompt'.
+ Do not ask interactively if `auth-source-save-behavior' is nil.
+
+2021-02-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify the indent-rigidly doc string
+
+ * lisp/indent.el (indent-rigidly): Clarify exiting the transient
+ mode (bug#46296).
+
+2021-02-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem when ~/.mailcap had several entries for a MIME type
+
+ * lisp/net/mailcap.el (mailcap-mime-info): Use all the matching
+ entries from ~/.mailcap, not just the first (bug#46318).
+
+2021-02-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Avoid a compilation warning in iter-do
+
+ * lisp/emacs-lisp/generator.el (iter-do): Avoid a compilation
+ warning on using variables marked for not using (bug#31641).
+ Eg. (iter-do (_ i))
+
+2021-02-06 Eli Zaretskii <eliz@gnu.org>
+
+ Fix copying text properties in 'format'
+
+ * src/editfns.c (styled_format): Fix accounting for text
+ properties that come from the format string. (Bug#46317)
+
+ * test/src/editfns-tests.el (format-properties): Add new tests for
+ bug#46317.
+
+2021-02-06 Martin Rudalics <rudalics@gmx.at>
+
+ Fix two small tab bar issues
+
+ * lisp/cus-start.el (frame-inhibit-implied-resize): Update version tag.
+ * lisp/frame.el (frame-inner-height): Do not count in tab bar.
+
+2021-02-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/pcase.el (let): Reimplement as a pcase macro
+
+ (pcase--macroexpand, pcase--u1): Remove handling of `let` from
+ `pcase`s core.
+
+2021-02-05 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'C-d' on the first line in Rmail summary buffer
+
+ * lisp/mail/rmailsum.el (rmail-summary-delete-forward): Fix
+ deleting backward past the beginning of the summary buffer.
+ (Bug#46325)
+
+2021-02-05 Michael Albinus <michael.albinus@gmx.de>
+
+ Add command 'dbus-monitor'
+
+ * doc/misc/dbus.texi: (Monitoring Messages): Document 'dbus-monitor'.
+
+ * etc/NEWS: Mention 'dbus-monitor' but 'dbus-register-monitor'.
+ Fix typos and other oddities.
+
+ * lisp/net/dbus.el (dbus-monitor): New command.
+
+ * test/lisp/net/dbus-tests.el (dbus--test-register-service): Extend test.
+
+2021-02-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't hard-code ignored functions in `indent-according-to-mode'
+
+ * lisp/indent.el (indent-line-ignored-functions): New variable
+ (bug#26945).
+ (indent-according-to-mode): Use it.
+
+2021-02-05 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change in 'window-text-pixel-size'
+
+ * src/xdisp.c (Fwindow_text_pixel_size): Fix last change: preserve
+ the original Y coordinate after start_display, instead of zeroing
+ it out. Reported by martin rudalics <rudalics@gmx.at>.
+
+2021-02-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fontize more automatic variables in makefile-gmake-mode
+
+ * lisp/progmodes/make-mode.el (makefile-gmake-font-lock-keywords):
+ Fontize the $ in more automatic variables (bug#27842).
+
+2021-02-05 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change in syntax.texi
+
+ * doc/lispref/syntax.texi (Syntax Properties): Fix wording in last
+ change. (Bug#46274)
+
+2021-02-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Correct the lispref manual about flushing ppss info
+
+ * doc/lispref/syntax.texi (Syntax Properties): Correct the
+ information about flushing the state by copying the text from the
+ doc string (bug#46274).
+
+ (cherry picked from commit ff701ce2b261acce1dfcd1fe137268d87d5eab35)
+
+2021-02-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify how transient indentation modes are exited in the manual
+
+ * doc/emacs/indent.texi (Indentation Commands): Clarify that the
+ other keys don't just exit the transient mode, but are also
+ handled as normally (bug#46296).
+
+2021-02-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Protect against killed buffers in term-emulate-terminal
+
+ * lisp/term.el (term-emulate-terminal): Ensure that the buffer is
+ still alive before selecting it (bug#46323). This avoids an error
+ when saying `C-x k' in an ansi-term buffer.
+
+2021-02-05 Sean Whitton <spwhitton@spwhitton.name>
+
+ Fix repeating complex commands
+
+ * lisp/repeat.el (repeat): Fix repeating complex commands
+ (bug#46290). This makes `M-: date RET C-x z' work again (like in
+ Emacs 21, apparently).
+
+2021-02-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make octave-send-region deactivate the region
+
+ * lisp/progmodes/octave.el (octave-send-region): Deactivate mark
+ after sending the region (bug#32282), since this is how these commands
+ usually work.
+
+2021-02-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Correct the lispref manual about flushing ppss info
+
+ * doc/lispref/syntax.texi (Syntax Properties): Correct the
+ information about flushing the state by copying the text from the
+ doc string (bug#46274).
+
+2021-02-05 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/emacs-lisp/checkdoc.el: Doc fix; don't mention built-ins.
+
+2021-02-05 Stefan Kangas <stefan@marxist.se>
+
+ Remove some unnecessary references to Emacs 18
+
+ * lisp/progmodes/cmacexp.el:
+ * lisp/progmodes/f90.el:
+ * lisp/shell.el: Doc fix; don't mention Emacs 18.
+
+2021-02-05 Stefan Kangas <stefan@marxist.se>
+
+ Remove Emacs 19 compat code from dcl-mode.el
+
+ * lisp/progmodes/dcl-mode.el: Doc fix.
+ (dcl-mode-map, dcl-mode): Remove compat code for Emacs 19.
+
+2021-02-05 Stefan Kangas <stefan@marxist.se>
+
+ Remove Emacs 20 compat code for header-line-format
+
+ * lisp/cedet/semantic/util-modes.el (semantic-stickyfunc-mode):
+ * lisp/erc/erc.el (erc-update-mode-line-buffer):
+ * lisp/ibuffer.el (ibuffer-use-header-line): Remove Emacs 20 compat
+ code; header-line-format is always defined starting with Emacs 21.
+
+2021-02-05 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/color.el: Remove Emacs 23.2 compat code.
+
+ * lisp/textmodes/rst.el (rst-directive): Remove XEmacs compat code.
+
+2021-02-05 Stefan Kangas <stefan@marxist.se>
+
+ Assume font-lock-mode variable is not void
+
+ * lisp/align.el (align-rules-list):
+ * lisp/cedet/semantic/idle.el
+ (semantic-idle-summary-useful-context-p):
+ * lisp/org/org-table.el (org-table-edit-field):
+ * lisp/org/org.el (org-restart-font-lock):
+ * lisp/progmodes/antlr-mode.el (antlr-language-option-extra):
+ * lisp/progmodes/idlwave.el (idlwave-choose):
+ * lisp/progmodes/sql.el (sql-product-font-lock):
+ * lisp/progmodes/verilog-mode.el
+ (verilog-save-font-no-change-functions, verilog-preprocess):
+ * lisp/vc/cvs-status.el:
+ * lisp/vc/smerge-mode.el (smerge-mode):
+ * lisp/woman.el (woman-decode-buffer): Assume font-lock-mode variable
+ is not void; it is preloaded.
+
+2021-02-05 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix the previous change
+
+ * lisp/progmodes/project.el (project-find-regexp):
+ Fix the previous change (project-root is not defined in this version).
+ (project-or-external-find-regexp): Same.
+
+2021-02-04 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: eliminate dead code
+
+ * lisp/progmodes/cperl-mode.el (cperl-update-syntaxification):
+ Eliminate check for `syntax-propertize-rules` (always true)
+ and eliminate unused first parameter.
+ (cperl-mode): Eliminate obsolete `font-lock-syntactic-keywords`,
+ Eliminate check for `syntax-propertize-rules` (always true).
+ (cperl-fontify-syntaxically): Eliminate call to
+ no-longer-existing function `edebug-backtrace` (bug#46302).
+
+2021-02-04 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid overwriting minibuffer prompt by keystrokes echo
+
+ * src/lread.c (Fread_char, Fread_event, Fread_char_exclusive):
+ Call cancel_echoing to make sure the prompt is not obscured by
+ keystrokes echo. (Bug#46243)
+
+2021-02-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Deactivate region in `C-c C-r' in python-mode
+
+ * lisp/progmodes/python.el (python-shell-send-region): Deactivate
+ mark after executing (bug#28789). This is how this command worked
+ in Emacs 24, apparently.
+
+2021-02-04 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'window-text-pixel-size' for short spans of text
+
+ * src/xdisp.c (Fwindow_text_pixel_size): Support the use case
+ where FROM and TO belong to the same screen line. Reported by
+ Yuan Fu <casouri@gmail.com>.
+
+2021-02-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve filling of Emacs Lisp doc strings
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-fill-paragraph): When filling
+ a Lisp string, try to avoid filling bits that follow it
+ (bug#28937).
+
+2021-02-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow a :variable keyword in define-globalized-minor-mode
+
+ * doc/lispref/modes.texi (Defining Minor Modes): Document it.
+ * lisp/emacs-lisp/easy-mmode.el (define-globalized-minor-mode):
+ Allow specifying a :variable to be used if the underlying mode has
+ a divergent variable to store the state (bug#29081).
+
+2021-02-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous ibuffer patch
+
+ * lisp/ibuffer.el (ibuffer-last-sorting-mode): Restore variable
+ removed by mistake in previous change.
+
+2021-02-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the recency sorting stable when we have inverted sorting
+
+ * lisp/ibuffer.el (recency): Remove.
+ (recency): New macro function so that sorting by recency is
+ stable when inverted sorting is switched on (bug#30129).
+
+2021-02-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Tweak how ibuffer-invert-sorting updates the buffer"
+
+ This reverts commit b8b3263eab688b97530a7bf7d565b084df56ea08.
+
+ This doesn't fix other instances of ibuffer-redisplay
+
+2021-02-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak how ibuffer-invert-sorting updates the buffer
+
+ * lisp/ibuf-ext.el (ibuffer-invert-sorting): Enable calling this
+ function repeatedly with more predictable results (bug#30129).
+
+2021-02-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't ask the user to make a bug report on missing arglists
+
+ * lisp/help-fns.el (help-fns--signature): Don't ask the user to
+ make a bug report (bug#30223) because the symbol may very well be
+ one that the user has defined themselves.
+ (help-fns-function-description-header): Ditto.
+
+2021-02-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify the "Sentinels" node in the lispref manual
+
+ * doc/lispref/processes.texi (Sentinels): Mention "run" and that
+ the strings can be anything (bug#30461).
+
+2021-02-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow eshell to have an "erasedups"-like history
+
+ * lisp/eshell/em-hist.el (eshell-add-input-to-history): Use the
+ new value (bug#30466).
+ (eshell-hist-ignoredups): Allow "erasedups"-like value.
+
+2021-02-04 Robert Pluim <rpluim@gmail.com>
+
+ Update description of 'tramp-crypt-remove-directory'
+
+ * doc/misc/tramp.texi (Keeping files encrypted): Correct name of
+ function to use to indicate files should no longer be encrypted,
+ and update its description.
+
+2021-02-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Be stricter when going back to the previous node in Info-find-node-2
+
+ * lisp/info.el (Info-find-node-2): When going back to the previous
+ node, be strict (bug#31137) since we have the exact node name.
+
+2021-02-04 Juri Linkov <juri@linkov.net>
+
+ * lisp/replace.el (occur-rename-buffer): Check for overlay (bug#46268).
+
+ (occur-1): Don't use occur--garbage-collect-revert-args
+ when reverting the Occur buffer with same bufs.
+
+2021-02-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix epg filtering out keys that contain revoked IDs
+
+ * lisp/epg.el (epg--filter-revoked-keys): Only filter out the
+ revoked user ids, not the entire key that contains revoked user
+ ids (bug#46138).
+
+2021-02-04 Stefan Kangas <stefan@marxist.se>
+
+ Don't set removed variable facemenu-unlisted-faces
+
+ * lisp/vc/ediff-init.el (ediff-hide-face): Redefine as obsolete
+ function alias for 'ignore'; the variable 'facemenu-unlisted-faces'
+ was removed in Emacs 22. Remove all calls.
+
+ * lisp/mh-e/mh-e.el: Add comment saying that the variable
+ 'facemenu-unlisted-faces' is removed.
+
+2021-02-04 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/man.el (Man-notify-method): Remove Emacs 19.28 compat code.
+
+2021-02-04 Stefan Kangas <stefan@marxist.se>
+
+ Use require instead of boundp+load-library in double.el
+
+ * lisp/double.el (isearch): Use require instead of
+ boundp+load-library.
+
+2021-02-04 Stefan Kangas <stefan@marxist.se>
+
+ Remove some unnecessary references to Emacs 19
+
+ * lisp/emacs-lisp/elp.el:
+ * lisp/mouse-copy.el:
+ * lisp/mouse-drag.el:
+ * lisp/progmodes/simula.el (simula-mode-map):
+ * lisp/term.el (term-matching-input-from-input-string):
+ * lisp/vcursor.el: Doc fix; don't mention Emacs 19.
+
+2021-02-04 Stefan Kangas <stefan@marxist.se>
+
+ Remove XEmacs compat code from edebug.el
+
+ * lisp/emacs-lisp/edebug.el (edebug-window-live-p, edebug-mark):
+ Make obsolete. Update callers.
+
+2021-02-04 Dmitry Gutov <dgutov@yandex.ru>
+
+ Bind default-directory to the project root
+
+ * lisp/progmodes/project.el (project-find-regexp):
+ Bind default-directory to the project root, to save this value
+ in the resulting buffer (esp. if the project selector was used,
+ (https://lists.gnu.org/archive/html/emacs-devel/2021-02/msg00140.html).
+ (project-or-external-find-regexp): Same.
+
+2021-02-03 Andrea Corallo <akrl@sdf.org>
+
+ Remove `system-configuration' from eln filename
+
+ * src/comp.c (hash_native_abi): Remove `system-configuration'
+ from eln filename. Add `system-configuration' and
+ `emacs-version' into `comp-abi-hash'.
+
+2021-02-03 Andrea Corallo <akrl@sdf.org>
+
+ Short eln filename hashes
+
+ * src/comp.c (HASH_LENGTH): New macro.
+ (comp_hash_string, comp_hash_source_file): Trim the hash before
+ returning.
+
+2021-02-03 Michael Albinus <michael.albinus@gmx.de>
+
+ Tramp code cleanup
+
+ * lisp/net/tramp.el (tramp-signal-hook-function)
+ (tramp-handle-access-file, tramp-handle-copy-directory)
+ (tramp-handle-directory-files, tramp-handle-file-local-copy)
+ (tramp-handle-insert-file-contents, tramp-handle-load):
+ * lisp/net/tramp-adb.el (tramp-adb-handle-directory-files-and-attributes)
+ (tramp-adb-handle-make-directory)
+ (tramp-adb-handle-file-local-copy, tramp-adb-handle-copy-file)
+ (tramp-adb-handle-rename-file):
+ * lisp/net/tramp-crypt.el (tramp-crypt-do-copy-or-rename-file)
+ (tramp-crypt-handle-directory-files)
+ (tramp-crypt-handle-make-directory):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-dbus-event-error)
+ (tramp-gvfs-do-copy-or-rename-file)
+ (tramp-gvfs-handle-make-directory):
+ * lisp/net/tramp-rclone.el (tramp-rclone-do-copy-or-rename-file)
+ (tramp-rclone-handle-directory-files):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-symbolic-link)
+ (tramp-sh-handle-directory-files-and-attributes)
+ (tramp-sh-handle-file-name-all-completions)
+ (tramp-sh-handle-copy-directory, tramp-do-copy-or-rename-file)
+ (tramp-sh-handle-make-directory)
+ (tramp-sh-handle-file-local-copy)
+ (tramp-sh-inotifywait-process-filter):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-copy-directory)
+ (tramp-smb-handle-copy-file, tramp-smb-handle-directory-files)
+ (tramp-smb-handle-file-local-copy)
+ (tramp-smb-handle-make-directory, tramp-smb-handle-rename-file):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-do-copy-or-rename-file):
+ Unify error report.
+
+ * lisp/net/tramp-adb.el (tramp-adb-file-name-handler): Sync args
+ with other `tramp-*-file-name-handler'.
+
+ * lisp/net/tramp-compat.el (tramp-error): Declare.
+ (tramp-compat-file-missing): New defsubst.
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-do-copy-or-rename-file):
+ Handle volatile files.
+ (tramp-gvfs-set-attribute): New defun.
+ (tramp-gvfs-handle-set-file-modes)
+ (tramp-gvfs-handle-set-file-times)
+ (tramp-gvfs-handle-set-file-uid-gid): Use it.
+
+ * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file):
+ Use `msg-operation'.
+
+ * lisp/net/tramp-smb.el (tramp-smb-handle-insert-directory):
+ Remove superfluous `format:
+ (tramp-smb-maybe-open-connection): Simplify loop.
+
+ * lisp/net/tramp.el (tramp-handle-file-truename): Drop volume letter from
+ symlinked files.
+
+ * test/lisp/net/tramp-tests.el (tramp--test-gdrive-p): New defun.
+ (tramp--test-nextcloud-p): Remove.
+ (tramp-test40-special-characters-with-ls): Do not skip on MS Windows.
+ (tramp-test41-utf8): Skip if needed.
+
+2021-02-03 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 7355209f53 (origin/emacs-27) * lisp/window.el (recenter-top-bottom): ...
+ dc78f8a4ea (emacs-27) url-http.el: Special-case NTLM authentication
+ 85b0137858 * lisp/isearch.el (isearch-lazy-highlight): Fix defcustom ...
+ cbeda21083 Sync latest SKK-JISYO.L
+
+2021-02-03 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 9c75434173 Fix build failure on macOS 10.7 (bug#46036)
+ ca44ea18ef Improve documentation of auto-resize-tool/tab-bars
+
+2021-02-03 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 74a71c41e0 (tag: emacs-27.1.91) Update files for 27.1.91 pretest
+
+ # Conflicts:
+ # ChangeLog.3
+ # etc/AUTHORS
+ # lisp/ldefs-boot.el
+
+2021-02-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make backslash characters no longer escape in `f90-mode'
+
+ * lisp/progmodes/f90.el (f90-backslash-not-special): Make obsolete
+ (bug#32766).
+ (f90-mode-syntax-table): Make the backslash be a normal
+ (non-escape) character, which is the default since about 2007 (and
+ F2K): https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34203
+
+2021-02-03 Wilson Snyder <wsnyder@wsnyder.org>
+
+ Update lisp/progmodes/verilog-mode.el
+
+ * lisp/progmodes/verilog-mode.el: Cleanup compile-time warning
+ suppression. Use underscore for unused arguments and other style
+ cleanups. Use '# for function references. By Stefan Monnier.
+ (verilog-auto-reset, verilog-sig-tieoff):
+ Fix AUTORESET '0 (#1714). Reported by Paul Adams.
+ (verilog-simplify-range-expression):
+ Fix AUTOWIRE simplifying X/Y where there is a remainder (#1712).
+ Reported by Joachim Lechner.
+ (verilog-read-sub-decls-expr):
+ Fix multiplication in multidimensional AUTOINST output (#1698).
+ Reported by alanamckee.
+ (verilog-at-constraint-p, verilog-at-streaming-op-p, verilog-streaming-op-re):
+ Add streaming operator support (#1692) (#1516),
+ (verilog-auto-assign-modport, verilog-auto-inout-modport):
+ Support adding prefix to AUTOASSIGNMODPORT and AUTOINOUTMODPORT (#1690).
+ (verilog-signals-matching-dir-re):
+ Fix error when matching regexp with 2D packed memory.
+ Reported by Chris DeMarco.
+ (verilog-declaration-core-re): Allow parameter
+ declaration statements to align like any other declaration (#1683).
+ Suggested by Vinam Arora.
+ (verilog-auto-inout, verilog-auto-inout-in)
+ (verilog-auto-inout-module, verilog-auto-input, verilog-auto-inst)
+ (verilog-auto-inst-param, verilog-auto-output-every)
+ (verilog-signals-matching-regexp)
+ (verilog-signals-not-matching-regexp):
+ When "?!" is at the front of a signal-matching regexp, invert it.
+ (verilog-declaration-varname-matcher)
+ (verilog-highlight-max-lookahead, verilog-mode)
+ (verilog-single-declaration-end) (verilog-font-lock-keywords-1):
+ Improve syntax highlighting in declaration statements, and support
+ multi-line declarations, #1681. Reported by Vinam Arora.
+
+2021-02-02 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Prevent "const" inside an identifier being recognized as the keyword
+
+ This fixes bug #45560.
+
+ * lisp/progmodes/cc-engine.el (c-forward-declarator)
+ (c-forward-decl-or-cast-1): Amend certain regexp match numbers on account of
+ the change below. Surround some looking-at calls with save-match-data.
+
+ * lisp/progmodes/cc-langs.el (c-type-decl-prefix-keywords-key): New lang
+ const.
+ (c-type-decl-prefix-key): Reformulate to match operators and keywords
+ separately, using the new lang const (above).
+
+2021-02-02 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/gnus-art.el: Fix misuse of `standard-value`.
+
+ * lisp/custom.el (custom--standard-value): New function.
+
+ * lisp/gnus/gnus-art.el: (gnus-article-browse-html-parts)
+ (gnus-article-browse-html-article):
+ * lisp/dired-aux.el (dired-do-find-regexp-and-replace):
+ * lisp/emacs-lisp/package-x.el (package-upload-buffer-internal):
+ * lisp/startup.el (command-line): Use it.
+
+2021-02-02 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/gnus-group.el: Fix a regression due to lexical scoping
+
+ (gnus-group-highlight): Improve docstring.
+ (gnus-group-update-eval-form): Add `group` and `method` to the vars
+ provided to `eval`.
+
+2021-02-02 Eli Zaretskii <eliz@gnu.org>
+
+ * lisp/window.el (recenter-top-bottom): Clarify doc string.
+
+2021-02-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Handle errors in `comint-strip-ctrl-m' in some cases
+
+ * lisp/comint.el (comint-strip-ctrl-m): Don't signal errors when
+ used noninteractively (bug#33115).
+
+2021-02-02 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-mode): Also set `comment-end-skip`
+
+2021-02-02 chuntaro <chuntaro@sakura-games.jp> (tiny change)
+
+ Fix |# fontification in lisp-mode
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-mode): Give the |# the
+ correct (font-lock-comment-delimited-face) face (bug#39820).
+
+2021-02-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Have `dired-mode' refer to Customize instead of listing some variables
+
+ * lisp/dired.el (dired-mode): Punt to Customize instead of listing
+ some of the dired variables (bug#46239).
+
+2021-02-02 Stefan Kangas <stefan@marxist.se>
+
+ Prefer defvar-local in remaining libraries
+
+ * lisp/align.el (align-mode-rules-list)
+ (align-mode-exclude-rules-list):
+ * lisp/bookmark.el (bookmark-current-bookmark)
+ (bookmark-annotation-name)
+ (bookmark--annotation-from-bookmark-list):
+ * lisp/calc/calc-embed.el (calc-embedded-all-active)
+ (calc-embedded-some-active):
+ * lisp/comint.el (comint-password-function):
+ * lisp/completion.el (completion-syntax-table):
+ * lisp/dframe.el (dframe-track-mouse-function)
+ (dframe-help-echo-function, dframe-mouse-click-function)
+ (dframe-mouse-position-function, dframe-timer)
+ (dframe-attached-frame, dframe-controlled):
+ * lisp/ehelp.el (electric-help-orig-major-mode):
+ * lisp/eshell/esh-util.el (eshell-path-env):
+ * lisp/expand.el (expand-pos, expand-index, expand-point):
+ * lisp/face-remap.el (text-scale-mode-remapping)
+ (text-scale-mode-lighter, text-scale-mode-amount)
+ (text-scale-remap-header-line, buffer-face-mode-remapping):
+ * lisp/ffap.el (ffap-menu-alist):
+ * lisp/files-x.el (connection-local-variables-alist):
+ * lisp/foldout.el (foldout-fold-list, foldout-mode-line-string):
+ * lisp/follow.el (follow-start-end-invalid):
+ * lisp/forms.el (forms--mode-setup):
+ * lisp/gnus/message.el (message-cross-post-old-target)
+ (message-options):
+ * lisp/help-mode.el (help-xref-stack, help-xref-forward-stack)
+ (help-xref-stack-item, help-xref-stack-forward-item):
+ * lisp/hexl.el (hexl-mode--old-var-vals, hexl-ascii-overlay):
+ * lisp/hilit-chg.el (hilit-chg-string):
+ * lisp/ido.el (ido-eoinput):
+ * lisp/imenu.el (imenu-generic-expression)
+ (imenu-create-index-function, imenu-default-goto-function)
+ (imenu-prev-index-position-function)
+ (imenu-extract-index-name-function, imenu-name-lookup-function)
+ (imenu-syntax-alist, imenu-case-fold-search):
+ * lisp/jka-compr.el (jka-compr-really-do-compress):
+ * lisp/language/ethio-util.el (ethio-prefer-ascii-space):
+ * lisp/leim/quail/hangul.el (hangul-input-method-help-text):
+ * lisp/leim/quail/japanese.el (quail-japanese-package-saved):
+ * lisp/linum.el (linum-overlays, linum-available):
+ * lisp/man.el (Man-original-frame, Man-arguments, Man--sections)
+ (Man--refpages, Man-page-list, Man-current-page)
+ (Man-page-mode-string):
+ * lisp/pcomplete.el (pcomplete-current-completions)
+ (pcomplete-last-completion-length)
+ (pcomplete-last-completion-stub, pcomplete-last-completion-raw)
+ (pcomplete-last-window-config, pcomplete-window-restore-timer):
+ * lisp/reveal.el (reveal-open-spots, reveal-last-tick):
+ * lisp/ruler-mode.el (ruler-mode):
+ * lisp/scroll-lock.el (scroll-lock-preserve-screen-pos-save):
+ * lisp/server.el (server-buffer-clients, server-existing-buffer):
+ * lisp/tab-line.el (tab-line-exclude):
+ * lisp/tar-mode.el (tar-data-buffer, tar-data-swapped):
+ * lisp/thumbs.el (thumbs-current-tmp-filename)
+ (thumbs-current-image-filename, thumbs-extra-images)
+ (thumbs-image-num, thumbs-buffer, thumbs-marked-list):
+ * lisp/tutorial.el (tutorial--point-before-chkeys)
+ (tutorial--point-after-chkeys, tutorial--lang):
+ * lisp/url/url-vars.el (url-current-object)
+ (url-current-mime-headers, url-current-lastloc):
+ * lisp/view.el (view-mode, view-old-buffer-read-only)
+ (view-old-Helper-return-blurb, view-page-size)
+ (view-half-page-size, view-last-regexp, view-return-to-alist)
+ (view-exit-action, view-overlay):
+ * lisp/wid-edit.el (widget-global-map, widget-field-new)
+ (widget-field-list, widget-field-last, widget-field-was):
+ * lisp/woman.el (woman-imenu-done): Prefer defvar-local.
+
+2021-02-02 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant :group args in play/*.el
+
+ * lisp/play/bubbles.el:
+ * lisp/play/cookie1.el:
+ * lisp/play/decipher.el:
+ * lisp/play/dunnet.el:
+ * lisp/play/gametree.el:
+ * lisp/play/gomoku.el:
+ * lisp/play/hanoi.el: Remove redundant :group args.
+
+2021-02-02 Sean Whitton <spwhitton@spwhitton.name>
+
+ Bind 'revert-buffer' to 'C-x g' globally
+
+ * lisp/bindings.el: Bind 'revert-buffer' to 'C-x g' globally.
+ * doc/emacs/files.texi: Replace 'M-x revert-buffer' with 'C-x g'.
+ * etc/NEWS: Document the change (bug#46151).
+
+2021-02-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up invalid_syntax error signalling
+
+ * src/lread.c (invalid_syntax_lisp): Instead of putting the
+ line/column in a string, signal an error containing the numbers as
+ data. This allows for easier post-processing and is how other
+ similar errors (like (forward-sexp 1)) do it.
+
+2021-02-02 Dmitry Gutov <dgutov@yandex.ru>
+
+ ruby-syntax-propertize: Fix certain cases following ::
+
+ * lisp/progmodes/ruby-mode.el (ruby-syntax-propertize):
+ Make sure to backtrack if the "symbols with special characters"
+ rule is aborted because of preceding colon.
+
+2021-02-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make syntax errors say the line/column they appear at
+
+ * src/lisp.h: Add count_lines prototype.
+ * src/lread.c (invalid_syntax_lisp): New function (bug#36970).
+ (invalid_syntax): Extend function to take a readcharfun parameter.
+ (read_emacs_mule_char, character_name_to_code): Pass in.
+ (read_escape, invalid_radix_integer, read1): Ditto.
+
+ * src/xdisp.c (count_lines): Add a more succinct shim over
+ display_count_lines.
+
+2021-02-01 Stefan Kangas <stefan@marxist.se>
+
+ * test/src/minibuf-tests.el (test-inhibit-interaction): Fix test.
+
+2021-02-01 Stefan Kangas <stefan@marxist.se>
+
+ Remove another variable obsolete since Emacs 23.2
+
+ * src/keymap.c (syms_of_keymap, Fdefine_key):
+ * lisp/subr.el (define-key-rebound-commands): Remove variable obsolete
+ since Emacs 23.2.
+
+2021-02-01 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/hi-lock.el (hi-lock-mode): Doc fix; don't mention Emacs 21.
+
+2021-02-01 Stefan Kangas <stefan@marxist.se>
+
+ Make XEmacs compat alias obsolete in allout-widgets.el
+
+ * lisp/allout-widgets.el (allout-frame-property): Redefine compat
+ alias as obsolete function alias for 'frame-parameter'.
+ (allout-fetch-icon-image): Update caller.
+
+2021-02-01 Stefan Kangas <stefan@marxist.se>
+
+ Redefine two functions as regular defuns
+
+ * lisp/dframe.el (dframe-popup-kludge, dframe-mouse-event-p):
+ Redefine as regular defun.
+
+2021-02-01 Stefan Kangas <stefan@marxist.se>
+
+ Make two eshell aliases obsolete
+
+ * lisp/eshell/esh-util.el (eshell-user-name): Redefine as obsolete
+ function alias for 'user-login-name'.
+ (eshell-copy-tree): Redefine as obsolete function alias for
+ 'copy-tree'.
+ * lisp/eshell/esh-cmd.el (eshell-do-eval): Don't use above
+ obsolete alias.
+
+2021-02-01 Stefan Kangas <stefan@marxist.se>
+
+ Add cross-references to defvar-local
+
+ * src/data.c (Fmake_variable_buffer_local):
+ * src/eval.c (Fdefvar): Add cross-references to 'defvar-local'.
+
+2021-02-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix indentation of non-comment HTML with -- in it
+
+ * lisp/textmodes/sgml-mode.el (sgml-comment-indent-new-line): Only
+ indent as if we're in a comment if syntax-ppss says that we're in
+ a comment (bug#36227).
+
+2021-02-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/eshell/em-cmpl.el (eshell--complete-commands-list): Fix last fix
+
+ Complete `*firef` to `*firefox` rather than to `firefox`.
+
+2021-02-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/eshell/em-cmpl.el: Try and fix bug#41423
+
+ (eshell--complete-commands-list): Rename from `eshell-complete-commands-list`.
+ Return a (dynamic) completion table rather than a list of completions.
+ Use `dolist` and `push`.
+
+2021-02-01 Thomas Fitzsimmons <fitzsim@fitzsim.org>
+
+ url-http.el: Special-case NTLM authentication
+
+ * lisp/url/url-http.el (url-http-handle-authentication): Do not
+ signal an error on NTLM authorization strings. (Bug#43566)
+
+2021-02-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * admin/*.el: Use lexical-binding
+
+ * admin/admin.el: Use lexical-binding.
+ (manual-misc-manuals): Pass a limit to `looking-back`.
+ (reminder-for-release-blocking-bugs): Don't use `_` for a real variable.
+
+ * admin/authors.el: Use lexical-binding.
+ (authors-disambiguate-file-name): Remove unused var `parent`.
+
+ * admin/cus-test.el:
+ * admin/find-gc.el:
+ * admin/gitmerge.el: Use lexical-binding.
+
+2021-01-31 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Merge remote-tracking branch 'origin/scratch/lexical-gnus' into trunk
+
+2021-01-31 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/gnus-group.el: Defvar all the `gnus-tmp-*` vars
+
+ These were collected via
+
+ sed -n -e 's/.*\(gnus-tmp-[^ ()]*\).*/(defvar \1)/p' \
+ lisp/gnus/gnus-group.el
+
+2021-01-31 Juri Linkov <juri@linkov.net>
+
+ * lisp/isearch.el (isearch-lazy-highlight): Fix defcustom type (bug#46208)
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Prefer defvar-local in preloaded files
+
+ * lisp/abbrev.el:
+ * lisp/bindings.el (mode-line-mule-info, mode-line-modified)
+ (mode-line-remote, mode-line-process)
+ (mode-line-buffer-identification):
+ * lisp/buff-menu.el (Buffer-menu-files-only):
+ * lisp/files.el (buffer-file-number, buffer-file-read-only)
+ (local-write-file-hooks, write-contents-functions)
+ (file-local-variables-alist, dir-local-variables-alist)
+ (save-buffer-coding-system, buffer-save-without-query):
+ * lisp/font-core.el (font-lock-defaults):
+ * lisp/font-lock.el (font-lock-keywords-case-fold-search)
+ (font-lock-syntactically-fontified)
+ (font-lock-extend-after-change-region-function)
+ (font-lock-extend-region-functions, font-lock-major-mode):
+ * lisp/menu-bar.el (list-buffers-directory):
+ * lisp/simple.el (next-error--message-highlight-overlay)
+ (next-error-buffer, next-error-function)
+ (next-error-move-function, goto-line-history)
+ (minibuffer-default-add-done, undo-extra-outer-limit):
+ * lisp/tab-bar.el (tab-switcher-column):
+ * lisp/term/ns-win.el (ns-select-overlay):
+ * lisp/window.el (window-size-fixed, window-area-factor)
+ (window-group-start-function, window-group-end-function)
+ (set-window-group-start-function)
+ (recenter-window-group-function)
+ (pos-visible-in-window-group-p-function)
+ (selected-window-group-function)
+ (move-to-window-group-line-function): Prefer defvar-local.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Prefer defvar-local in mail/*.el
+
+ * lisp/mail/emacsbug.el (report-emacs-bug-send-command)
+ (report-emacs-bug-send-hook):
+ * lisp/mail/reporter.el (reporter-initial-text):
+ * lisp/mail/supercite.el (sc-mail-info, sc-attributions):
+ * lisp/mail/rmail.el (rmail-buffer-swapped, rmail-view-buffer):
+ Prefer defvar-local.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Prefer defvar-local in progmodes/*.el
+
+ This skips libraries that might want compatibility with Emacs 24.2.
+
+ * lisp/progmodes/compile.el (compilation-auto-jump-to-next)
+ (compilation--previous-directory-cache, compilation--parsed)
+ (compilation-gcpro):
+ * lisp/progmodes/cpp.el (cpp-overlay-list, cpp-edit-buffer)
+ (cpp-parse-symbols, cpp-edit-symbols):
+ * lisp/progmodes/ebnf2ps.el (ebnf-eps-upper-x, ebnf-eps-upper-y)
+ (ebnf-eps-prod-width, ebnf-eps-max-height, ebnf-eps-max-width):
+ * lisp/progmodes/f90.el (f90-cache-position):
+ * lisp/progmodes/gud.el (gud-marker-acc):
+ * lisp/progmodes/js.el (js--quick-match-re)
+ (js--quick-match-re-func, js--cache-end, js--last-parse-pos)
+ (js--state-at-last-parse-pos, js--tmp-location):
+ * lisp/progmodes/octave.el (inferior-octave-directory-tracker-resync):
+ * lisp/progmodes/sh-script.el (sh-header-marker): Prefer defvar-local.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Prefer defvar-local in textmodes/*.el
+
+ This skips libraries that might want compatibility with Emacs 24.2.
+
+ * lisp/textmodes/artist.el (artist-curr-go)
+ (artist-line-char-set, artist-line-char, artist-fill-char-set)
+ (artist-fill-char, artist-erase-char, artist-default-fill-char)
+ (artist-draw-region-min-y, artist-draw-region-max-y)
+ (artist-borderless-shapes):
+ * lisp/textmodes/css-mode.el (css--at-ids, css--bang-ids)
+ (css--nested-selectors-allowed):
+ * lisp/textmodes/enriched.el (enriched-old-bindings):
+ * lisp/textmodes/flyspell.el (flyspell-generic-check-word-predicate)
+ (flyspell-consider-dash-as-word-delimiter-flag)
+ (flyspell-dash-dictionary, flyspell-dash-local-dictionary)
+ (flyspell-word-cache-start, flyspell-word-cache-end)
+ (flyspell-word-cache-word, flyspell-word-cache-result)
+ (flyspell-changes, flyspell-auto-correct-pos)
+ (flyspell-auto-correct-region, flyspell-auto-correct-ring)
+ (flyspell-auto-correct-word):
+ * lisp/textmodes/ispell.el (ispell-local-dictionary-overridden)
+ (ispell-local-pdict, ispell-buffer-session-localwords):
+ * lisp/textmodes/refill.el (refill-ignorable-overlay)
+ (refill-doit):
+ * lisp/textmodes/sgml-mode.el (html--buffer-classes-cache)
+ (html--buffer-ids-cache):
+ * lisp/textmodes/table.el (table-mode-indicator):
+ * lisp/textmodes/tex-mode.el (tex-send-command-modified-tick):
+ * lisp/textmodes/two-column.el (2C-autoscroll-start, 2C-mode):
+ Prefer defvar-local.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Prefer defvar-local in cedet
+
+ * lisp/cedet/ede.el (ede-object-root-project)
+ (ede-object-project, ede-object):
+ * lisp/cedet/mode-local.el (mode-local-symbol-table):
+ * lisp/cedet/semantic.el (semantic--parse-table)
+ (semantic-symbol->name-assoc-list)
+ (semantic-symbol->name-assoc-list-for-type-parts)
+ (semantic-case-fold, semantic--buffer-cache)
+ (semantic-unmatched-syntax-cache)
+ (semantic-unmatched-syntax-cache-check, semantic-parser-name)
+ (semantic--completion-cache, semantic-parse-tree-state)
+ (semantic-init-mode-hook, semantic-parser-warnings):
+ * lisp/cedet/semantic/bovine.el
+ (semantic-bovinate-nonterminal-check-obarray):
+ * lisp/cedet/semantic/complete.el (semantic-collector-per-buffer-list):
+ * lisp/cedet/semantic/ctxt.el (semantic-command-separation-character)
+ (semantic-function-argument-separation-character):
+ * lisp/cedet/semantic/db-find.el (semanticdb-find-lost-includes)
+ (semanticdb-find-scanned-include-tags):
+ * lisp/cedet/semantic/db.el (semanticdb-new-database-class)
+ (semanticdb-default-find-index-class)
+ (semanticdb-current-database, semanticdb-current-table)
+ (semanticdb-project-system-databases)
+ (semanticdb-out-of-buffer-create-table-fcn):
+ * lisp/cedet/semantic/debug.el (semantic-debug-parser-source)
+ (semantic-debug-parser-class)
+ (semantic-debug-parser-debugger-source):
+ * lisp/cedet/semantic/dep.el (semantic-dependency-include-path)
+ (semantic-dependency-system-include-path):
+ * lisp/cedet/semantic/format.el (semantic-function-argument-separator)
+ (semantic-format-parent-separator):
+ * lisp/cedet/semantic/fw.el (semantic-new-buffer-fcn-was-run):
+ * lisp/cedet/semantic/grammar.el (semantic-grammar-macros)
+ (semantic--grammar-macros-regexp-1)
+ (semantic--grammar-macros-regexp-2):
+ * lisp/cedet/semantic/idle.el (semantic-idle-scheduler-mode):
+ * lisp/cedet/semantic/imenu.el (semantic-imenu-expandable-tag-classes):
+ * lisp/cedet/semantic/lex-spp.el
+ (semantic-lex-spp-macro-symbol-obarray)
+ (semantic-lex-spp-project-macro-symbol-obarray)
+ (semantic-lex-spp-dynamic-macro-symbol-obarray)
+ (semantic-lex-spp-dynamic-macro-symbol-obarray-stack):
+ * lisp/cedet/semantic/lex.el (semantic-flex-keywords-obarray)
+ (semantic-lex-types-obarray, semantic-lex-analyzer)
+ (semantic-lex-syntax-modifications, semantic-lex-syntax-table)
+ (semantic-lex-comment-regex, semantic-lex-number-expression)
+ (semantic-lex-depth, semantic-flex-extensions)
+ (semantic-flex-syntax-modifications, semantic-ignore-comments)
+ (semantic-flex-enable-newlines, semantic-flex-enable-whitespace)
+ (semantic-flex-enable-bol, semantic-number-expression)
+ (semantic-flex-depth):
+ * lisp/cedet/semantic/senator.el (senator-isearch-semantic-mode):
+ * lisp/cedet/semantic/sort.el
+ (semantic-orphaned-member-metaparent-type):
+ * lisp/cedet/semantic/tag.el (semantic-tag-expand-function):
+ * lisp/cedet/semantic/util-modes.el (semantic-show-parser-state-string)
+ (semantic-stickyfunc-sticky-classes)
+ (semantic-highlight-func-ct-overlay):
+ * lisp/cedet/semantic/util.el
+ (semantic-type-relation-separator-character)
+ (semantic-equivalent-major-modes):
+ * lisp/cedet/semantic/wisent.el (wisent-error-function)
+ (wisent-lexer-function): Prefer defvar-local.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Prefer defvar-local in net/*.el
+
+ * lisp/net/browse-url.el (browse-url-temp-file-name):
+ * lisp/net/rcirc.el (rcirc-ignore-buffer-activity-flag)
+ (rcirc-low-priority-flag, rcirc-parent-buffer)
+ (rcirc-activity-types, rcirc-last-sender):
+ * lisp/net/soap-inspect.el (soap-inspect-previous-items)
+ (soap-inspect-current-item):
+ * lisp/net/telnet.el (telnet-remote-echoes)
+ (telnet-interrupt-string, telnet-count): Prefer defvar-local.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Prefer defvar-local in vc/*.el
+
+ * lisp/vc/ediff-diff.el (ediff-whitespace, ediff-word-1)
+ (ediff-word-2, ediff-word-3, ediff-word-4):
+ * lisp/vc/ediff-init.el (ediff-defvar-local):
+ * lisp/vc/smerge-mode.el (smerge-check-cache):
+ * lisp/vc/vc-bzr.el (vc-bzr-annotation-table):
+ * lisp/vc/vc-dispatcher.el (vc-mode-line-hook): Prefer defvar-local.
+
+2021-01-31 Philipp Stephani <phst@google.com>
+
+ * etc/MACHINES: Document that we support AArch64 with macOS.
+
+2021-01-31 Alan Mackenzie <acm@muc.de>
+
+ Minimise the time Vminibuffer_list is in an inconsistent state (src/minibuf.c)
+
+ src/minibuf.c (get_minibuffer): Move the XSETCAR which writes the new
+ minibuffer into Vminibuffer_list to immediately after the MB's creation, so
+ that the list is in a consistent state before calling fundamental-mode or
+ minibuffer-inactive-mode.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Prefer defvar-local in international/*.el
+
+ * lisp/international/mule-cmds.el (current-input-method)
+ (current-input-method-title, current-transient-input-method)
+ (previous-transient-input-method, input-method-history)
+ (deactivate-current-input-method-function)
+ (describe-current-input-method-function):
+ * lisp/international/mule.el (buffer-file-coding-system-explicit):
+ * lisp/international/quail.el (quail-current-package)
+ (quail-guidance-str, quail-overlay, quail-conv-overlay)
+ (quail-current-key, quail-current-str)
+ (quail-current-translations, quail-current-data):
+ * lisp/international/robin.el (robin-mode)
+ (robin-current-package-name): Prefer defvar-local in
+ international/*.el.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Prefer defvar-local in nxml/*.el
+
+ * lisp/nxml/rng-cmpct.el (rng-c-current-token)
+ (rng-c-escape-positions, rng-c-file-name):
+ * lisp/nxml/rng-pttrn.el (rng-current-schema):
+ * lisp/nxml/rng-valid.el (rng-validate-timer)
+ (rng-validate-quick-timer, rng-error-count, rng-message-overlay)
+ (rng-message-overlay-inhibit-point, rng-message-overlay-current)
+ (rng-validate-up-to-date-end, rng-conditional-up-to-date-start)
+ (rng-conditional-up-to-date-end, rng-dtd): Prefer defvar-local.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Prefer defvar-local in emacs-lisp/*.el
+
+ * lisp/emacs-lisp/chart.el (chart-local-object):
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode)
+ (define-globalized-minor-mode):
+ * lisp/emacs-lisp/edebug.el:
+ * lisp/emacs-lisp/generic.el (generic-font-lock-keywords):
+ * lisp/emacs-lisp/re-builder.el (reb-regexp, reb-regexp-src)
+ (reb-overlays):
+ * lisp/emacs-lisp/syntax.el
+ (syntax-propertize-extend-region-functions): Prefer defvar-local.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Prefer defvar-local in allout
+
+ * lisp/allout.el (allout-just-did-undo, allout-mode)
+ (allout-layout, allout-regexp, allout-bullets-string)
+ (allout-bullets-string-len, allout-depth-specific-regexp)
+ (allout-depth-one-regexp, allout-line-boundary-regexp)
+ (allout-bob-regexp, allout-header-subtraction)
+ (allout-plain-bullets-string-len, allout-mode-prior-settings)
+ (allout-outside-normal-auto-fill-function)
+ (allout-encryption-plaintext-sanitization-regexps)
+ (allout-encryption-ciphertext-rejection-regexps)
+ (allout-explicitly-deactivated, allout-recent-prefix-beginning)
+ (allout-recent-prefix-end, allout-recent-depth)
+ (allout-recent-end-of-subtree, allout-post-goto-bullet)
+ (allout-command-counter, allout-this-command-hid-text):
+ * lisp/allout-widgets.el (allout-widgets-mode)
+ (allout-widgets-tally, allout-widgets-mode-inhibit)
+ (allout-inhibit-body-modification-hook)
+ (allout-widgets-changes-record)
+ (allout-widgets-undo-exposure-record)
+ (allout-escaped-prefix-regexp, allout-item-icon-keymap)
+ (allout-item-body-keymap, allout-cue-span-keymap)
+ (allout-widgets-last-decoration-timing)
+ (allout-container-item-widget): Prefer defvar-local.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Prefer defvar-local in cua
+
+ * lisp/emulation/cua-base.el (cua-inhibit-cua-keys)
+ (cua--status-string):
+ * lisp/emulation/cua-rect.el (cua--rectangle)
+ (cua--rectangle-overlays): Prefer defvar-local.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Obsolete viper-deflocalvar for defvar-local
+
+ * lisp/emulation/viper-init.el (viper-deflocalvar): Make obsolete.
+ Use defvar-local.
+
+ * lisp/emulation/viper-cmd.el (viper--undo-change-group-handle):
+ * lisp/emulation/viper-init.el (viper-vi-intercept-minor-mode)
+ (viper-vi-basic-minor-mode, viper-vi-local-user-minor-mode)
+ (viper-vi-global-user-minor-mode)
+ (viper-vi-state-modifier-minor-mode)
+ (viper-vi-diehard-minor-mode, viper-vi-kbd-minor-mode)
+ (viper-insert-intercept-minor-mode)
+ (viper-insert-basic-minor-mode)
+ (viper-insert-local-user-minor-mode)
+ (viper-insert-global-user-minor-mode)
+ (viper-insert-state-modifier-minor-mode)
+ (viper-insert-diehard-minor-mode, viper-insert-kbd-minor-mode)
+ (viper-replace-minor-mode, viper-emacs-intercept-minor-mode)
+ (viper-emacs-local-user-minor-mode)
+ (viper-emacs-global-user-minor-mode, viper-emacs-kbd-minor-mode)
+ (viper-emacs-state-modifier-minor-mode)
+ (viper-vi-minibuffer-minor-mode)
+ (viper-insert-minibuffer-minor-mode)
+ (viper-automatic-iso-accents, viper-special-input-method)
+ (viper-intermediate-command, viper-began-as-replace)
+ (viper-replace-overlay, viper-last-posn-in-replace-region)
+ (viper-last-posn-while-in-insert-state)
+ (viper-sitting-in-replace, viper-replace-chars-to-delete)
+ (viper-replace-region-chars-deleted, viper-current-state)
+ (viper-cted, viper-current-indent, viper-preserve-indent)
+ (viper-auto-indent, viper-electric-mode, viper-insert-point)
+ (viper-pre-command-point, viper-com-point)
+ (viper-ex-style-motion, viper-ex-style-editing)
+ (viper-ESC-moves-cursor-back, viper-delete-backwards-in-replace)
+ (viper-related-files-and-buffers-ring)
+ (viper-local-search-start-marker, viper-search-overlay)
+ (viper-last-jump, viper-last-jump-ignore)
+ (viper-minibuffer-current-face, viper-minibuffer-overlay):
+ * lisp/emulation/viper-keym.el (viper-vi-local-user-map)
+ (viper-insert-local-user-map, viper-emacs-local-user-map)
+ (viper--key-maps, viper-need-new-vi-local-map)
+ (viper-need-new-insert-local-map)
+ (viper-need-new-emacs-local-map):
+ * lisp/emulation/viper-mous.el (viper-mouse-click-search-noerror)
+ (viper-mouse-click-search-limit):
+ * lisp/emulation/viper-util.el (viper-non-word-characters)
+ (viper-ALPHA-char-class):
+ * lisp/emulation/viper.el: Use defvar-local instead of now obsolete
+ macro viper-deflocalvar.
+
+2021-01-31 Alan Mackenzie <acm@muc.de>
+
+ Don't attempt to display input method guidance in expired minibuffers
+
+ This caused infinite waits in circumstances involving setting an input method
+ in a global minor mode. This commit fixes bug #45792.
+
+ * lisp/international/quail.el (quail-show-guidance): Test the major mode is
+ not minibuffer-inactive-mode before proceding with the function.
+
+2021-01-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ execute-kbd-macro doc string clarification
+
+ * src/macros.c (Fexecute_kbd_macro): Mention that the buffer is
+ (potentially) changed (bug#37396).
+
+2021-01-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make operating-system-release obsolete
+
+ * lisp/subr.el (operating-system-release): Make obsolete
+ (bug#39940). There are no in-tree usages any more, and the data
+ doesn't seem all that interesting on its own.
+
+2021-01-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Doc string improvements around `default-korean-keyboard'
+
+ * lisp/language/korea-util.el (default-korean-keyboard): Mention
+ "Hangul" here for easier discoverability.
+ (toggle-korean-input-method, quail-hangul-switch-symbol-ksc)
+ (quail-hangul-switch-hanja): Mention the variable.
+
+2021-01-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Improve fontifying of #| ... |# in `lisp-mode'"
+
+ This reverts commit 1275dc4711af77c9c223063dcd149d782d497463.
+
+ Setting comment-end isn't the correct thing to do -- it makes M-; insert that string.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Prefer defvar-local in play/*.el
+
+ * lisp/play/5x5.el
+ (5x5-grid, 5x5-x-pos, 5x5-y-pos, 5x5-moves, 5x5-cracking):
+ * lisp/play/decipher.el (decipher-alphabet)
+ (decipher-stats-buffer, decipher-undo-list-size)
+ (decipher-undo-list):
+ * lisp/play/gamegrid.el (gamegrid-use-glyphs)
+ (gamegrid-use-color, gamegrid-font, gamegrid-face)
+ (gamegrid-display-options, gamegrid-buffer-width)
+ (gamegrid-buffer-height, gamegrid-blank, gamegrid-timer)
+ (gamegrid-display-mode, gamegrid-display-table)
+ (gamegrid-face-table, gamegrid-buffer-start)
+ (gamegrid-score-file-length):
+ * lisp/play/snake.el (snake-length, snake-velocity-x)
+ (snake-velocity-y, snake-positions, snake-score, snake-paused)
+ (snake-moved-p, snake-velocity-queue):
+ * lisp/play/tetris.el (tetris-shape, tetris-rot)
+ (tetris-next-shape, tetris-n-shapes, tetris-n-rows)
+ (tetris-score, tetris-pos-x, tetris-pos-y, tetris-paused):
+ Prefer defvar-local.
+
+ * lisp/play/5x5.el (5x5-defvar-local): Make obsolete.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant defvar for artist-mode
+
+ * lisp/textmodes/artist.el (artist-mode): Remove redundant
+ defvar; it is defined by define-minor-mode.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Prefer defvar-local in erc
+
+ * lisp/erc/erc-backend.el (erc-server-current-nick)
+ (erc-server-process, erc-session-server, erc-session-connector)
+ (erc-session-port, erc-server-announced-name)
+ (erc-server-version, erc-server-parameters)
+ (erc-server-connected, erc-server-reconnect-count)
+ (erc-server-quitting, erc-server-reconnecting)
+ (erc-server-timed-out, erc-server-banned)
+ (erc-server-error-occurred, erc-server-lines-sent)
+ (erc-server-last-peers, erc-server-last-sent-time)
+ (erc-server-last-ping-time, erc-server-last-received-time)
+ (erc-server-lag, erc-server-filter-data, erc-server-duplicates)
+ (erc-server-processing-p, erc-server-flood-last-message)
+ (erc-server-flood-queue, erc-server-flood-timer)
+ (erc-server-ping-handler):
+ * lisp/erc/erc-capab.el (erc-capab-identify-activated)
+ (erc-capab-identify-sent):
+ * lisp/erc/erc-dcc.el (erc-dcc-byte-count, erc-dcc-entry-data)
+ (erc-dcc-file-name):
+ * lisp/erc/erc-ezbounce.el (erc-ezb-session-list):
+ * lisp/erc/erc-join.el (erc--autojoin-timer):
+ * lisp/erc/erc-netsplit.el (erc-netsplit-list):
+ * lisp/erc/erc-networks.el (erc-network):
+ * lisp/erc/erc-notify.el (erc-last-ison, erc-last-ison-time):
+ * lisp/erc/erc-ring.el (erc-input-ring, erc-input-ring-index):
+ * lisp/erc/erc-stamp.el (erc-timestamp-last-inserted)
+ (erc-timestamp-last-inserted-left)
+ (erc-timestamp-last-inserted-right):
+ * lisp/erc/erc.el (erc-session-password, erc-channel-users)
+ (erc-server-users, erc-channel-topic, erc-channel-modes)
+ (erc-insert-marker, erc-input-marker, erc-last-saved-position)
+ (erc-dbuf, erc-active-buffer, erc-default-recipients)
+ (erc-session-user-full-name, erc-channel-user-limit)
+ (erc-channel-key, erc-invitation, erc-channel-list)
+ (erc-bad-nick, erc-logged-in, erc-default-nicks)
+ (erc-nick-change-attempt-count, erc-send-input-line-function)
+ (erc-channel-new-member-names, erc-channel-banlist)
+ (erc-current-message-catalog): Prefer defvar-local.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant requires of 'derived'
+
+ * lisp/net/newst-backend.el (derived):
+ * lisp/net/newst-plainview.el (derived):
+ * lisp/play/gametree.el (derived):
+ * lisp/textmodes/less-css-mode.el (derived): Remove redundant require;
+ 'define-derived-mode' is autoloaded.
+
+2021-01-31 Stefan Kangas <stefan@marxist.se>
+
+ Sync latest SKK-JISYO.L
+
+ * leim/SKK-DIC/SKK-JISYO.L: Sync to current upstream version.
+
+2021-01-31 Dmitry Gutov <dgutov@yandex.ru>
+
+ Recompute mode-lines when marking conflicts resolved
+
+ * lisp/vc/vc.el (vc-mark-resolved):
+ Recompute the mode lines of the affected files.
+
+2021-01-31 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus: Use closures now that we activated `lexical-binding`
+
+ * lisp/gnus/nnml.el (nnml-request-accept-article):
+ * lisp/gnus/nnmairix.el (nnmairix-request-marks):
+ * lisp/gnus/nnmail.el (nnmail-get-new-mail-1):
+ * lisp/gnus/mm-view.el (mm-inline-image)
+ (mm-inline-text-html-render-with-w3m, mm-inline-text)
+ (mm-insert-inline, mm-inline-message):
+ * lisp/gnus/mm-partial.el (mm-inline-partial):
+ * lisp/gnus/mm-archive.el (mm-archive-dissect-and-inline):
+ * lisp/gnus/gnus-util.el (gnus-create-info-command):
+ * lisp/gnus/gnus-topic.el (gnus-topic-edit-parameters)
+ (gnus-topic-sort-topics-1):
+ * lisp/gnus/gnus-sum.el (gnus-summary-edit-article):
+ * lisp/gnus/gnus-srvr.el (gnus-server-edit-server):
+ * lisp/gnus/gnus-msg.el (gnus-inews-make-draft)
+ (gnus-inews-add-send-actions, gnus-summary-cancel-article)
+ (gnus-summary-supersede-article, gnus-summary-resend-message)
+ (gnus-configure-posting-styles):
+ * lisp/gnus/gnus-kill.el (gnus-execute):
+ * lisp/gnus/gnus-html.el (gnus-html-wash-images):
+ * lisp/gnus/gnus-group.el (gnus-group-edit-group)
+ (gnus-group-nnimap-edit-acl):
+ * lisp/gnus/gnus-draft.el (gnus-draft-edit-message, gnus-draft-setup):
+ * lisp/gnus/gnus-art.el (gnus-article-edit-part)
+ (gnus-mm-display-part, gnus-article-edit):
+ * lisp/gnus/gnus-agent.el (gnus-category-edit-predicate)
+ (gnus-category-edit-score, gnus-category-edit-groups):
+ Use closures instead of `(lambda ...).
+
+ * lisp/gnus/nnoo.el (noo--defalias): New function.
+ (nnoo-import-1, nnoo-define-skeleton-1): Use it to avoid `eval`.
+
+2021-01-31 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus: Use lexical-binding in all the files
+
+ * lisp/gnus/gnus-group.el (features): Use `dlet`.
+ (gnus-tmp-level, gnus-tmp-marked, gnus-tmp-group): Declare vars.
+ (gnus-group-insert-group-line): Bind dynbound vars via `let` rather
+ than as formal args. Bind `number` as dynbound.
+ (gnus-visual, gnus-score-find-score-files-function)
+ (gnus-home-score-file, gnus-apply-kill-hook)
+ (gnus-summary-expunge-below): Declare vars.
+ (gnus-group-restart, gnus-group-list-plus): Fix `interactive` spec
+ since the arg is unused.
+
+ * lisp/gnus/mail-source.el (mail-source-bind, mail-source-bind-common):
+ Use `dlet` and suppress the warnings about the non-prefixed dynbound vars.
+ (mail-source-set-1): Remove unused var `auth-info`.
+ (mail-source-call-script): Remove unused var `background`.
+ (mail-source-fetch-pop, mail-source-check-pop): Bind pop3 vars with `dlet`.
+
+ * lisp/gnus/gnus-int.el (mail-source-plugged, gnus-inhibit-demon):
+ Declare vars.
+ (gnus-server-opened, gnus-status-message)
+ (gnus-open-server, gnus-close-server, gnus-request-list)
+ (gnus-finish-retrieve-group-infos, gnus-retrieve-group-data-early)
+ (gnus-request-list-newsgroups, gnus-request-newgroups)
+ (gnus-request-regenerate, gnus-request-compact, gnus-request-group)
+ (gnus-retrieve-groups, gnus-request-post, gnus-request-expunge-group)
+ (gnus-request-scan, gnus-request-update-info, gnus-request-marks)
+ (gnus-request-accept-article, gnus-request-create-group)
+ (gnus-asynchronous-p, gnus-remove-denial):
+ Bind `gnus-command-method` via `let` rather than as formal args.
+
+ * lisp/gnus/gnus-topic.el (gnus-topic-insert-topic-line):
+ Pass documented vars to eval for `gnus-topic-line-format-spec`.
+
+ * lisp/gnus/message.el (message-yank-original): Use `cl-progv` rather
+ than `eval` to bind the vars from `message-cite-style`.
+
+ * lisp/gnus/mml.el (mml-parse-1): Use `apply` instead of `eval`.
+ (gnus-newsgroup-name, gnus-displaying-mime, gnus-newsgroup-name)
+ (gnus-article-prepare-hook, gnus-newsgroup-charset)
+ (gnus-original-article-buffer, gnus-message-buffer)
+ (message-this-is-news, message-this-is-mail): Declare vars.
+
+ * lisp/gnus/deuglify.el (gnus-outlook-rearrange-article): Remove unused
+ var `cite-marks`.
+ * lisp/gnus/gnus-art.el (ansi-color-context-region): Declare var.
+ (gnus-mime-display-attachment-buttons-in-header): Move declaration
+ before first use.
+ (gnus-mime-display-alternative): Remove unused var `from`.
+ * lisp/gnus/gnus-bookmark.el (gnus-bookmark-bmenu-list): Remove unused
+ var `start` `end`.
+ * lisp/gnus/gnus-cache.el (gnus-article-decode-hook)
+ (nnml-generate-active-function): Declare var.
+ * lisp/gnus/gnus-cite.el (gnus-message-citation-mode): Remove unused
+ var `keywords`.
+ * lisp/gnus/gnus-cloud.el (gnus-cloud-encode-data): Remove unused var
+ `cipher`.
+ (gnus-cloud-ensure-cloud-group): Remove unused var `method`.
+ * lisp/gnus/gnus-delay.el (gnus-delay-article): Remove unused var `days`.
+ * lisp/gnus/gnus-html.el (gnus-html-wash-images): Remove unused vars
+ `tag`, `string`, and `images`.
+ (gnus-html-wash-tags): Remove unused vars `string` and `images`.
+ * lisp/gnus/gnus-msg.el (gnus-msg-mail): Remove unused var `group-name`.
+ (gnus-group-mail, gnus-group-news, gnus-summary-mail-other-window)
+ (gnus-summary-news-other-window):
+ Remove unused vars `group` and `buffer`.
+ (gnus-configure-posting-styles): Remove unused vars `style` and `attribute`.
+ * lisp/gnus/gnus-picon.el (gnus-picon-find-face): Remove unused vars
+ `database`, `directory`, and `instance`.
+ (gnus-picon-transform-newsgroups): Remove unused var `point`.
+ * lisp/gnus/gnus-range.el (gnus-range-difference): Remove unused var `safe`.
+ * lisp/gnus/gnus-score.el (gnus-score-load-file): Remove unused var
+ `score-fn`.
+ * lisp/gnus/gnus-sum.el (message-options-set-recipient): Declare var.
+ * lisp/gnus/gnus-undo.el (gnus-undo): Fix docstring lie.
+ * lisp/gnus/gnus-util.el (print-string-length)
+ (iswitchb-make-buflist-hook): Declare vars.
+ (gnus-emacs-version): Remove unused var `codename`.
+ (gnus-rename-file): Remove unused vars `old-name` and `new-name`.
+ * lisp/gnus/gnus-uu.el (gnus-uu-yenc-article): Remove unused var
+ `start-char`.
+ (gnus-asynchronous): Declare var.
+ * lisp/gnus/mm-partial.el (gnus-displaying-mime): Declare var.
+ (mm-inline-partial): Remove unused var `buffer`.
+ * lisp/gnus/mm-view.el (w3m-force-redisplay, w3m-safe-url-regexp)
+ (gnus-displaying-mime, gnus-original-article-buffer)
+ (gnus-article-prepare-hook): Declare vars.
+ * lisp/gnus/mml-smime.el (mml-smime-epg-encrypt): Remove unused var
+ `boundary`.
+ (mml-smime-epg-verify): Remove unused vars `plain` and `signature-file`.
+ * lisp/gnus/mml1991.el (pgg-text-mode): Declare var.
+ * lisp/gnus/mml2015.el (pgg-text-mode): Declare var.
+ (mml2015-pgg-decrypt): Remove unused var `result`.
+ (mml2015-epg-key-image-to-string): Remove unused var `error`.
+ (mml2015-epg-decrypt): Remove unused var `result`.
+ (mml2015-epg-verify): Remove unused vars `plain` and `signature-file`.
+ * lisp/gnus/nnbabyl.el (nnml-current-directory): Declare var.
+ * lisp/gnus/nndiary.el (nndiary-files): Move declaration before first use.
+ * lisp/gnus/nnfolder.el (nnfolder-request-accept-article):
+ Remove unused var `buf`.
+ * lisp/gnus/nnmail.el (nnmail-parse-active): Remove unused var `err`.
+ * lisp/gnus/nnmairix.el (nnmairix-request-group): Remove unused var `args`.
+ (nnmairix-request-create-group): Remove unused var `info`.
+ (nnmairix-request-list): Remove unused var `folder`.
+ (nnmairix-request-set-mark): Remove unused var `propto`.
+ (nnmairix-request-set-mark): Remove unused vars `number` and `method`.
+ (nnmairix-close-group): Remove unused var `method`.
+ (nnmairix-create-search-group-from-message): Remove unused var `cq`.
+ (nnmairix-create-server-and-default-group): Remove unused var `create`.
+ (nnmairix-purge-old-groups): Remove unused var `folder`.
+ (nnmairix-remove-tick-mark-original-article, nnmairix-get-valid-servers):
+ Remove unused var `cur`.
+ (nnmairix-replace-group-and-numbers): Remove unused var `header`.
+ (nnmairix-goto-original-article): Remove unused var `rval`.
+ (nnmairix-widget-create-query): Remove unused var `allwidgets`.
+ * lisp/gnus/nnmbox.el (nnml-current-directory): Declare var.
+ * lisp/gnus/nnmh.el (nnmh-toplev): Move declaration before first use.
+ (nnmh-request-list-1): Remove unused var `rdir`.
+ * lisp/gnus/nnml.el (nnml-generate-nov-file): Remove unused var `file`.
+ * lisp/gnus/nnrss.el (nnrss-request-article): Remove unused var `post`.
+ (nnrss-request-article): Remove unused var `fn`.
+ (nnrss-check-group): Remove unused var `rdf-ns`.
+ * lisp/gnus/nnweb.el (nnweb-request-article): Remove unused var `active`.
+ (nnweb-google-parse-1): Remove unused var `Score`.
+ * lisp/gnus/spam-stat.el (spam-stat-error-holder): Remove var.
+ (spam-stat-buffer-words-with-scores): Remove unused var `word`.
+ (spam-stat-score-buffer): Remove unused var `spam-stat-error-holder`.
+ (spam-stat-split-fancy): Use `err` instead of `spam-stat-error-holder`.
+ * lisp/gnus/spam-wash.el (spam-wash): Remove unused var `handle`.
+ * lisp/gnus/spam.el (spam-copy-or-move-routine): Remove unused vars
+ `article` and `mark`.
+ (spam-register-routine): Remove unused var `article`.
+ (spam-log-undo-registration): Remove unused var `found`.
+ (spam-ifile-register-with-ifile): Remove unused var `parameters`.
+ (spam-check-stat): Remove unused vars `category` and `return`.
+ (spam-parse-list): Remove unused var `found`.
+ (spam-filelist-register-routine): Remove unused var `from`.
+
+2021-01-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus: Misc simplifications found during conversion to lexical
+
+ * lisp/gnus/nnoo.el (noo-import-1, nnoo-define-skeleton-1): Use `dolist`.
+ (noo-map-functions, nnoo-define-basics): Directly emit the code rather than
+ going through an intermediate function; this also avoids the use of `eval`.
+ (noo-map-functions-1, nnoo-define-basics-1): Delete functions,
+ folded into their corresponding macro.
+
+ * lisp/gnus/gmm-utils.el (gmm-tool-bar-from-list): Demote `eval` to
+ `symbol-value`.
+
+ * lisp/gnus/gnus-art.el (gnus-button-handle-describe-key): Avoid `eval`
+ since `kbd` is a function nowadays.
+ (gnus-treat-part-number): Rename from `part-number`.
+ (gnus-treat-total-parts): Rename from `total-parts`.
+ (gnus-treat-article, gnus-treat-predicate): Adjust accordingly.
+
+ * lisp/gnus/gnus-cache.el (gnus-agent-load-alist): Use `declare-function`.
+
+ * lisp/gnus/gnus-group.el (gnus-cache-active-hashtb): Use `defvar`.
+ (gnus-group-iterate): Make it a normal function since lexical scoping
+ avoids the risk of name capture anyway.
+ (gnus-group-delete-articles): Actually use the `oldp` arg.
+
+ * lisp/gnus/gnus-html.el (gnus-html-wash-images): Fix debug message so
+ it's emitted after the `url` var it prints is actually initialized.
+ And avoid `setq` while we're at it.
+
+ * lisp/gnus/gnus-msg.el (gnus-group-mail, gnus-group-news)
+ (gnus-summary-mail-other-window, gnus-summary-news-other-window):
+ Merge `let`s using `let*`.
+
+ * lisp/gnus/gnus-spec.el (gnus-update-format-specifications):
+ Tighten the scope of `buffer`, and tighten a regexp.
+ (gnus-parse-simple-format): Reduce code duplication.
+
+ * lisp/gnus/gnus-start.el (gnus-child-mode): Don't `defvar` it since we
+ never use that variable and accordingly don't define it as a minor mode.
+
+ * lisp/gnus/gnus-util.el (gnus-byte-compile): Simplify so it obeys
+ `gnus-use-byte-compile` not just on the first call.
+ (iswitchb-minibuffer-setup): Declare.
+
+ * lisp/gnus/mail-source.el (mail-source-bind-1)
+ (mail-source-bind-common-1): Use `mapcar`.
+ (mail-source-set-common-1): Use `dolist`.
+ (display-time-event-handler): Declare.
+
+ * lisp/gnus/mml-smime.el (mml-smime-epg-verify): Reduce code duplication.
+
+ * lisp/gnus/mml.el (mml-parse-1): Reduce code duplication.
+
+ * lisp/gnus/mml2015.el (mml2015-epg-verify): Reduce code duplication.
+
+ * lisp/gnus/nnmail.el (nnmail-get-split-group): Tighten regexp.
+ (nnmail-split-it): Reduce code duplication.
+
+ * lisp/gnus/nnweb.el (nnweb-request-article): Avoid `setq`.
+
+ * lisp/gnus/spam.el (BBDB): Use the `noerror` arg of `require`, and
+ define all the functions for BBDB regardless if the require succeeded.
+ (spam-exists-in-BBDB-p): Don't inline, not worth it.
+
+2021-01-30 Alan Third <alan@idiocy.org>
+
+ Fix build failure on macOS 10.7 (bug#46036)
+
+ * src/nsfns.m (ns_set_represented_filename): Define the NSNumber in a
+ more compatible manner.
+
+2021-01-30 Alan Mackenzie <acm@muc.de>
+
+ With minibuffer-follows-selected-frame `hybrid', preserve recursive Mbuffers
+
+ ...when enable-recursive-minibuffers is non-nil, and several minibuffers are
+ activated from different frames. Also set the major mode of a reused active
+ minibuffer to `fundamental-mode' - up till now it's been
+ minibuffer-inactive-mode.
+
+ * src/minibuf.c (read_minibuf): with the indicated settings of variables,
+ "stack up" all containing minibuffers on the mini-window of the current
+ frame. Delete another, now superfluous such stacking up.
+ (set_minibuffer_mode): New function.
+ (get_minibuffer): Call the above new function (twice), in place of inline
+ code, ensuring active minibuffers are never left in minibuffer-inactive-mode.
+
+2021-01-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus: Remove redundant `:group` args
+
+ * lisp/gnus/spam-stat.el:
+ * lisp/gnus/spam-report.el:
+ * lisp/gnus/smime.el:
+ * lisp/gnus/nnrss.el:
+ * lisp/gnus/nnmairix.el:
+ * lisp/gnus/nnimap.el:
+ * lisp/gnus/nndiary.el:
+ * lisp/gnus/mm-url.el:
+ * lisp/gnus/mail-source.el:
+ * lisp/gnus/gnus-win.el:
+ * lisp/gnus/gnus-topic.el:
+ * lisp/gnus/gnus-sieve.el:
+ * lisp/gnus/gnus-search.el:
+ * lisp/gnus/gnus-registry.el:
+ * lisp/gnus/gnus-notifications.el:
+ * lisp/gnus/gnus-gravatar.el:
+ * lisp/gnus/gnus-eform.el:
+ * lisp/gnus/gnus-dup.el:
+ * lisp/gnus/gnus-diary.el:
+ * lisp/gnus/gnus-demon.el:
+ * lisp/gnus/gnus-delay.el:
+ * lisp/gnus/gnus-cloud.el:
+ * lisp/gnus/gnus-cite.el:
+ * lisp/gnus/gnus-bookmark.el:
+ * lisp/gnus/gmm-utils.el:
+ * lisp/gnus/deuglify.el:
+ * lisp/gnus/canlock.el: Remove redundant `:group` arguments
+
+2021-01-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus: Demote some macros and defsubsts, plus a fix
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-thread-level)
+ (gnus-summary-article-mark): Turn macros into `defsubst`.
+
+ * lisp/gnus/mail-source.el (mail-source-bind-common): Actually use its arg.
+
+ * lisp/gnus/nntp.el (nntp-copy-to-buffer): Turn macro into a `defsubst`.
+ (nntp-wait-for, nntp-retrieve-data, nntp-send-command): Don't inline
+ those, it's not worth it.
+
+2021-01-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus: Use `with-current-buffer` at a few more places
+
+ * lisp/gnus/nnmbox.el (nnmbox-request-scan, nnmbox-read-mbox):
+ * lisp/gnus/nnmairix.el (nnmairix-create-search-group):
+ * lisp/gnus/nnfolder.el (nnfolder-existing-articles):
+ * lisp/gnus/nndraft.el (nndraft-auto-save-file-name):
+ * lisp/gnus/nndoc.el (nndoc-request-article):
+ * lisp/gnus/nnbabyl.el (nnbabyl-read-mbox):
+ * lisp/gnus/gnus-score.el (gnus-score-body):
+ * lisp/gnus/gnus-start.el (gnus-dribble-enter)
+ (gnus-dribble-eval-file, gnus-ask-server-for-new-groups)
+ (gnus-read-newsrc-file, gnus-read-descriptions-file):
+ * lisp/gnus/gnus-spec.el (gnus-update-format-specifications):
+ * lisp/gnus/gnus-draft.el (gnus-draft-edit-message):
+ * lisp/gnus/gnus-art.el (gnus-request-article-this-buffer)
+ (gnus-article-edit-exit): Use `with-current-buffer`.
+
+2021-01-30 Eli Zaretskii <eliz@gnu.org>
+
+ Fix NS build broken by a recent change
+
+ * src/nsmenu.m (set_frame_menubar, Fns_reset_menu): Adapt to
+ recent changes in set_frame_menubar. (Bug#45759)
+
+2021-01-30 Juri Linkov <juri@linkov.net>
+
+ Allow the caller to specify own face on suffix in annotation-function
+
+ * lisp/minibuffer.el (completion--insert-strings):
+ Don't add 'completions-annotations' face when the caller
+ specified own face in annotation-function.
+ Remove no-op code for 'unless prefix' branch.
+ (completion-metadata, completion-extra-properties):
+ Update docs of affixation-function.
+ Suggested by Clemens <clemera@posteo.net> (bug#45780)
+
+ * test/lisp/minibuffer-tests.el: Rename package name from
+ completion-tests.el to minibuffer-tests.el.
+ Add new test completion--insert-strings-faces.
+
+ * doc/lispref/minibuf.texi (Completion Variables)
+ (Programmed Completion): Update descriptions of
+ annotation-function and affixation-function.
+
+2021-01-30 Augusto Stoffel <arstoffel@gmail.com> (tiny change)
+
+ Reduce flicker in Isearch mode
+
+ Lazy highlighting now happens immediately when the search string is at
+ least as long as the value of the new custom variable
+ `lazy-highlight-no-delay-length`. Also avoid updating the lazy
+ count in the echo area too often.
+ * lisp/isearch.el (lazy-highlight-no-delay-length): New defcustom.
+ (lazy-lazy-count-format): Avoid a momentarily incorrect
+ count when reversing search direction.
+ (isearch-lazy-highlight-new-loop): Avoid a call to
+ `isearch-message` that is quickly succeed by a second echo area
+ update, thus causing flicker.
+ (isearch-lazy-highlight-new-loop):
+ Start lazy highlight immediately if appropriate.
+ * etc/NEWS: Announce the change.
+ * doc/emacs/search.texi: Document `lazy-highlight-no-delay-length'.
+
+2021-01-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/gnus-msg.el: Remove empty `unwind-protect`s
+
+ (gnus-msg-mail, gnus-group-mail)
+ (gnus-group-news, gnus-summary-mail-other-window)
+ (gnus-summary-news-other-window): Remove empty `unwind-protect`.
+
+2021-01-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/mm-encode.el (mm-default-file-type): New name
+
+ Rename from misleading `mm-default-file-encoding`.
+ (mm-default-file-encoding): Redefine as obsolete alias.
+
+ * lisp/mail/sendmail.el (mail-add-attachment):
+ * lisp/mh-e/mh-mime.el (mh-minibuffer-read-type):
+ * lisp/gnus/gnus-art.el (gnus-mime-view-part-as-type-internal):
+ * lisp/gnus/gnus-dired.el (gnus-dired-attach):
+ * lisp/gnus/mml.el (mml-generate-mime-1, mml-minibuffer-read-type)
+ (mml-attach-file): Use the new name.
+
+2021-01-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus: Quote functions with #'
+
+ To get better warnings, try and use #' to quote function names.
+
+ * lisp/gnus/canlock.el:
+ * lisp/gnus/deuglify.el:
+ * lisp/gnus/gmm-utils.el:
+ * lisp/gnus/gnus-agent.el:
+ * lisp/gnus/gnus-art.el:
+ * lisp/gnus/gnus-bookmark.el:
+ * lisp/gnus/gnus-cache.el:
+ * lisp/gnus/gnus-cite.el:
+ * lisp/gnus/gnus-cus.el:
+ * lisp/gnus/gnus-delay.el:
+ * lisp/gnus/gnus-diary.el:
+ * lisp/gnus/gnus-dired.el:
+ * lisp/gnus/gnus-draft.el:
+ * lisp/gnus/gnus-fun.el:
+ * lisp/gnus/gnus-group.el:
+ * lisp/gnus/gnus-html.el:
+ * lisp/gnus/gnus-int.el:
+ * lisp/gnus/gnus-kill.el:
+ * lisp/gnus/gnus-mlspl.el:
+ * lisp/gnus/gnus-msg.el:
+ * lisp/gnus/gnus-notifications.el:
+ * lisp/gnus/gnus-picon.el:
+ * lisp/gnus/gnus-registry.el:
+ * lisp/gnus/gnus-rfc1843.el:
+ * lisp/gnus/gnus-salt.el:
+ * lisp/gnus/gnus-score.el:
+ * lisp/gnus/gnus-search.el:
+ * lisp/gnus/gnus-sieve.el:
+ * lisp/gnus/gnus-srvr.el:
+ * lisp/gnus/gnus-start.el:
+ * lisp/gnus/gnus-topic.el:
+ * lisp/gnus/gnus-undo.el:
+ * lisp/gnus/gnus-util.el:
+ * lisp/gnus/gnus-uu.el:
+ * lisp/gnus/gnus.el:
+ * lisp/gnus/mail-source.el:
+ * lisp/gnus/message.el:
+ * lisp/gnus/mm-archive.el:
+ * lisp/gnus/mm-decode.el:
+ * lisp/gnus/mm-url.el:
+ * lisp/gnus/mm-util.el:
+ * lisp/gnus/mm-view.el:
+ * lisp/gnus/mml-sec.el:
+ * lisp/gnus/mml-smime.el:
+ * lisp/gnus/mml.el:
+ * lisp/gnus/nnagent.el:
+ * lisp/gnus/nndiary.el:
+ * lisp/gnus/nndoc.el:
+ * lisp/gnus/nndraft.el:
+ * lisp/gnus/nnfolder.el:
+ * lisp/gnus/nnheader.el:
+ * lisp/gnus/nnmail.el:
+ * lisp/gnus/nnmaildir.el:
+ * lisp/gnus/nnmairix.el:
+ * lisp/gnus/nnmh.el:
+ * lisp/gnus/nnml.el:
+ * lisp/gnus/nnrss.el:
+ * lisp/gnus/nnselect.el:
+ * lisp/gnus/nnspool.el:
+ * lisp/gnus/nnvirtual.el:
+ * lisp/gnus/nnweb.el:
+ * lisp/gnus/smiley.el:
+ * lisp/gnus/smime.el:
+ * lisp/gnus/spam-report.el:
+ * lisp/gnus/spam-stat.el:
+ * lisp/gnus/spam-wash.el:
+ * lisp/gnus/spam.el:
+
+2021-01-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/gnus-art.el: Add `event` args and operate at its position.
+
+ (gnus-mime-save-part-and-strip)
+ (gnus-mime-delete-part, gnus-mime-save-part, gnus-mime-pipe-part)
+ (gnus-mime-view-part, gnus-mime-view-part-as-type)
+ (gnus-mime-copy-part, gnus-mime-print-part, gnus-mime-inline-part)
+ (gnus-mime-view-part-as-charset, gnus-mime-view-part-externally)
+ (gnus-mime-view-part-internally, gnus-article-press-button):
+ Add `event` arg and operate at its position.
+
+2021-01-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus: Use `declare`.
+
+ * lisp/gnus/nnoo.el (defvoo, deffoo, nnoo-declare, nnoo-import)
+ (nnoo-map-functions):
+ * lisp/gnus/nnmaildir.el (nnmaildir--with-nntp-buffer)
+ (nnmaildir--with-work-buffer, nnmaildir--with-nov-buffer)
+ (nnmaildir--with-move-buffer, nnmaildir--condcase):
+ * lisp/gnus/mm-decode.el (mm-with-part):
+ * lisp/gnus/gnus-msg.el (gnus-setup-message):
+ * lisp/gnus/gnus-agent.el (gnus-agent-with-fetch, gnus-agent-while-plugged):
+ * lisp/gnus/mail-source.el (mail-source-set-1, mail-source-value):
+ Use `declare`.
+
+ * lisp/gnus/gnus-util.el (gnus-define-keys): Use `declare`, and also
+ don't quote `keymap` if it's a variable name.
+ (gnus-define-keys-1): Reject the case where `keymap` is a variable name.
+ (gnus-eval-in-buffer-window, gnus-define-keys-safe)
+ (gnus-define-keymap, gnus-atomic-progn, gnus-with-output-to-file)
+ (gnus-parse-without-error): Use `declare`.
+ (gnus-atomic-progn-assign, gnus-atomic-setq): Delete macros.
+
+ * lisp/gnus/gnus-undo.el (gnus-undo-register): Drop indent and edebug spec
+ since they're not really appropriate for a function.
+
+ * lisp/gnus/gnus-art.el (gnus--\,@): New macro.
+ Use it at top-level to construct the `gnus-article-FOO` => `article-FOO`
+ wrapper functions.
+ (gnus-with-article-headers, gnus-with-article-buffer): Use `declare`.
+
+2021-01-30 Stefan Kangas <stefan@marxist.se>
+
+ Remove unused argument from set_frame_menubar (Bug#45759)
+
+ * src/w32menu.c (set_frame_menubar):
+ * src/xmenu.c (set_frame_menubar): Remove unused argument.
+ All callers updated.
+
+2021-01-30 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of auto-resize-tool/tab-bars
+
+ * src/xdisp.c (syms_of_xdisp) <auto-resize-tool-bars>
+ <auto-resize-tab-bars>: Doc fix. (Bug#46178)
+
+2021-01-30 Dmitry Gutov <dgutov@yandex.ru>
+
+ Also highlight 'conflict' with the warning face
+
+ * lisp/vc/vc-git.el (vc-git-dir-printer):
+ Also highlight 'conflict' with the warning face, like
+ vc-default-dir-printer does already.
+
+2021-01-30 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into native-comp
+
+2021-01-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ auth-source-search doc string fix
+
+ * lisp/auth-source.el (auth-source-search): Fix example (bug#36286).
+
+2021-01-30 Jared Finder <jared@finder.org>
+
+ * lisp/tab-line.el (tab-line-new-tab): Use tty menus when supported.
+
+2021-01-30 Eli Zaretskii <eliz@gnu.org>
+
+ New Rmail option 'rmail-show-message-set-modified'
+
+ * lisp/mail/rmail.el (rmail-show-message-set-modified): New
+ option.
+ (rmail-show-message-1): If 'rmail-show-message-set-modified' is
+ non-nil, don't reset the buffer's modified state. (Bug#45941)
+
+ * etc/NEWS: Announce the new option.
+
+2021-01-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix vc-hg-rename-file on file names like ~/foo/bar
+
+ * lisp/vc/vc-hg.el (vc-hg-rename-file): Use absolute file names,
+ because hg doesn't like getting file names like "~/foo/bar"
+ (bug#36932).
+
+2021-01-30 Jeff Spencer <jeffspencerd@gmail.com> (tiny change)
+
+ Fix interaction between two dired cleanup variables
+
+ * lisp/dired.el (dired-clean-up-after-deletion): Kill the buffers
+ if you have `dired-clean-up-buffers-too' set and
+ `dired-clean-confirm-killing-deleted-buffers' nil (bug#38037).
+
+2021-01-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve :foreground description in the manual
+
+ * doc/lispref/frames.texi (Font and Color Parameters): Make the
+ description less confusing (bug#38710).
+
+2021-01-30 Mauro Aranda <maurooaranda@gmail.com>
+
+ Add source to sgml-empty-tags
+
+ * lisp/textmodes/sgml-mode.el (html-mode): Add "source" as an empty
+ tag to fix indentation when this element is present (bug#46181).
+
+2021-01-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ rmail-summary-mark-deleted optional argument fix
+
+ * lisp/mail/rmailsum.el (rmail-summary-mark-deleted): Argument N
+ is optional, so don't assume that it's a number (bug#39076).
+
+2021-01-30 Dmitry Gutov <dgutov@yandex.ru>
+
+ vc-dir-mode-map: Remove the mouse-2 binding
+
+ * lisp/vc/vc-dir.el (vc-dir-mode-map):
+ Remove the mouse-2 binding (bug#13692).
+ (vc-dir-mode): Update the docstring accordingly.
+ (vc-dir-status-mouse-map): New variable.
+ (vc-default-dir-printer): Use it on the state buttons.
+
+ * lisp/vc/vc-git.el (vc-git-dir-printer): Same.
+
+2021-01-30 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in mpuz.el
+
+ * lisp/play/mpuz.el: Use lexical-binding. Remove redundant :group
+ args.
+ (mpuz-switch-to-window): Minor cleanup.
+
+2021-01-30 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in handwrite.el
+
+ * lisp/play/handwrite.el: Use lexical-binding. Remove redundant
+ :group args. Minor cleanups.
+
+ (handwrite): Minor cleanups.
+ (handwrite-set-pagenumber-off, handwrite-set-pagenumber-on): Make
+ comments into docstrings.
+
+2021-01-29 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * test/lisp/electric-tests.el: Fix switch to lexical-binding.
+
+ (define-electric-pair-test): Don't presume that function values are
+ self-evaluating.
+
+2021-01-29 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in sasl.el and add tests
+
+ * lisp/net/sasl.el:
+ * lisp/net/sasl-digest.el:
+ * lisp/net/sasl-cram.el:
+ * lisp/net/sasl-ntlm.el: Use lexical-binding.
+
+ * test/lisp/net/sasl-tests.el:
+ * test/lisp/net/sasl-cram-tests.el: New files.
+
+2021-01-29 Dmitry Gutov <dgutov@yandex.ru>
+
+ (xref-revert-buffer): Also 'erase-buffer' when handling a user-error
+
+ * lisp/progmodes/xref.el (xref-revert-buffer):
+ Also 'erase-buffer' when handling a user-error (bug#46042).
+
+ (cherry picked from commit e86b30d6fd04070b86560774ec82392dbe24ca1e)
+
+2021-01-29 Dmitry Gutov <dgutov@yandex.ru>
+
+ (xref-revert-buffer): Also 'erase-buffer' when handling a user-error
+
+ * lisp/progmodes/xref.el (xref-revert-buffer):
+ Also 'erase-buffer' when handling a user-error (bug#46042).
+
+2021-01-29 Eli Zaretskii <eliz@gnu.org>
+
+ Update files for 27.1.91 pretest
+
+ * ChangeLog.3:
+ * etc/AUTHORS
+ * lisp/ldefs-boot.el: Update.
+
+2021-01-29 Eli Zaretskii <eliz@gnu.org>
+
+ Support 'operating-system-release' on MS-Windows
+
+ * src/w32fns.c (w32_version_string) [WINDOWSNT]: New function.
+ * src/w32common.h (w32_version_string) [WINDOWSNT]: Add prototype.
+ * src/editfns.c (init_editfns) [WINDOWSNT]: Produce a non-nil
+ string with the OS version.
+
+2021-01-29 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/lisp/net/tramp-tests.el (tramp--test-special-characters):
+
+ Adapt test for docker.
+
+2021-01-29 Juri Linkov <juri@linkov.net>
+
+ Use save-mark-and-excursion in query-replace-read-args (bug#45617)
+
+2021-01-29 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Bug#45518 in compile.el
+
+ * lisp/progmodes/compile.el (compilation-get-file-structure):
+ Avoid call of `file-truename' for remote files. (Bug#45518)
+
+2021-01-29 Eli Zaretskii <eliz@gnu.org>
+
+ Improve doc string of 'operating-system-release'
+
+ * src/editfns.c (syms_of_editfns) <operating-system-release>: Doc
+ fix. (Bug#39940)
+
+2021-01-29 Sean Whitton <spwhitton@spwhitton.name>
+
+ Fix previous commit regarding revert-buffer-function
+
+ * lisp/simple.el (shell-command, shell-command-on-region): Set
+ revert-buffer-function buffer-locally, not globally. Also, avoid an
+ unnecessary call to (current-buffer) by taking advantage of the
+ closure (bug#46151).
+
+2021-01-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Describe pointer shapes in the manual
+
+ * doc/lispref/frames.texi (Pointer Shape): Describe what the
+ typical pointer shapes are (and add `nhdrag') (bug#39246).
+
+2021-01-29 Marco Wahl <marcowahlsoft@gmail.com>
+
+ Add a command for redisplay during keyboard macros
+
+ * doc/emacs/kmacro.texi (Basic Keyboard Macro): Document it
+ (bug#39252).
+
+ * lisp/kmacro.el (kdb-macro-redisplay): New function.
+ (kmacro-keymap): Bind it.
+
+2021-01-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve fontifying of #| ... |# in `lisp-mode'
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-mode): Fontify the end
+ delimiter in #| ... |# correctly (bug#39820).
+
+2021-01-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ operating-system-release doc string improvement
+
+ * src/editfns.c (syms_of_editfns): Be more precise about what
+ `operating-system-release' is (bug#39940).
+
+2021-01-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ flymake-diagnostic-beg/end doc string and error reporting improvement
+
+ * lisp/progmodes/flymake.el (flymake-diagnostic-beg):
+ (flymake-diagnostic-end): Improve doc string and error reporting
+ (bug#39971).
+
+2021-01-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix position in empty buffers in checkdoc-file-comments-engine
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-file-comments-engine):
+ Don't give invalid positions on empty buffers (bug#39987).
+
+2021-01-29 Sean Whitton <spwhitton@spwhitton.name>
+
+ Set revert-buffer-function in shell command output buffers
+
+ * lisp/simple.el (shell-command, shell-command-on-region): Set
+ revert-buffer-function in shell command output buffers
+ (bug#46151).
+
+2021-01-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention using buffer-list-update-hook in recentf-mode
+
+ * lisp/recentf.el (recentf-mode): Mention using
+ `buffer-list-update-hook' (bug#46153).
+
+2021-01-29 Stefan Kangas <stefan@marxist.se>
+
+ Remove Emacs 21 compat code from sasl.el
+
+ * lisp/net/sasl.el (sasl-read-passphrase): Remove compat code;
+ 'read-passwd' is preloaded since Emacs 22.
+
+2021-01-29 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/flow-ctrl.el: Use lexical-binding.
+
+ * lisp/flow-ctrl.el (enable-flow-control): Minor cleanup.
+
+2021-01-29 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in find-cmd.el and add tests
+
+ * lisp/find-cmd.el: Use lexical-binding.
+ * test/lisp/find-cmd-tests.el: New file.
+
+2021-01-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Slight gravatar.el code clean up
+
+ * lisp/image/gravatar.el (gravatar--service-libravatar): Clean the
+ code up slightly.
+
+2021-01-29 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Merge branch 'master' of git+ssh://git.sv.gnu.org/srv/git/emacs into trunk
+
+2021-01-28 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in nroff-mode.el
+
+ * lisp/textmodes/nroff-mode.el: Use lexical-binding. Remove
+ redundant :group args.
+
+2021-01-28 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/progmodes/bat-mode.el: Use lexical-binding.
+
+2021-01-28 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in generic-x.el
+
+ * lisp/generic-x.el: Use lexical-binding. Remove redundant :groups.
+ (generic-rul-mode-setup-function): Prefer setq-local.
+
+2021-01-28 Stefan Kangas <stefan@marxist.se>
+
+ Define compat alias obsolete
+
+ * lisp/generic-x.el (generic-mode-ini-file-find-file-hook): Define
+ compat alias introduced after rename in 22.1 obsolete.
+
+2021-01-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Use lexical-binding in all of `lisp/emacs-lisp`
+
+ * lisp/emacs-lisp/bindat.el: Use lexical-binding.
+ (bindat--unpack-group, bindat--length-group, bindat--pack-group):
+ Declare `last` and `tag` as dyn-scoped.
+ (bindat-unpack, bindat-pack): Bind `bindat-raw` and `bindat-idx` via
+ `let` rather than via the formal arglist.
+
+ * lisp/emacs-lisp/package-x.el:
+ * lisp/emacs-lisp/generic.el:
+ * lisp/emacs-lisp/eieio-opt.el:
+ * lisp/emacs-lisp/derived.el:
+ * lisp/emacs-lisp/crm.el: Use lexical-binding.
+
+ * lisp/emacs-lisp/helper.el: Use lexical-binding.
+ (Helper-help-map): Move initialization into declaration.
+
+ * lisp/emacs-lisp/regi.el: Use lexical-binding.
+ (regi-interpret): Remove unused var `tstart`.
+ Declare `curframe`, `curentry` and `curline` as dyn-scoped.
+
+ * lisp/emacs-lisp/shadow.el: Use lexical-binding.
+ (load-path-shadows-find): Remove unused var `file`.
+ Tighten a regexp, use `push`.
+
+ * lisp/emacs-lisp/tcover-ses.el: Use lexical-binding. Require `ses`.
+ Remove correspondingly redundant declarations.
+ (ses--curcell-overlay): Declare.
+ (ses-exercise): Use `dlet` and use a properly-prefixed var name.
+ Fix name of `curcell-overlay` variable.
+
+ * lisp/emacs-lisp/unsafep.el: Use lexical-binding.
+ (unsafep): Bind `unsafep-vars` via `let` rather than via the formal arglist.
+
+2021-01-28 Juri Linkov <juri@linkov.net>
+
+ Use isearch-tmm-menubar when tmm-menubar is called in isearch-mode (bug#43966)
+
+ * lisp/isearch.el (isearch-menu-bar-commands): Add tmm-menubar to defaults.
+ (isearch-mode-map): Remove remapping of tmm-menubar to isearch-tmm-menubar.
+
+ * lisp/tmm.el (tmm-menubar): Call isearch-tmm-menubar in isearch-mode.
+
+2021-01-28 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/wdired.el: Minor doc fixes.
+
+2021-01-28 Stefan Kangas <stefan@marxist.se>
+
+ Avoid recommending Google
+
+ * doc/misc/org.texi (Link Abbreviations):
+ * lisp/net/webjump.el (webjump-sample-sites):
+ * lisp/org/ol.el (org-link-shell-confirm-function)
+ (org-link-elisp-confirm-function):
+ * lisp/org/org.el (org-highlight-links):
+ * lisp/wdired.el: Avoid recommending Google.
+
+ squash! Avoid recommending Google
+
+2021-01-28 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/leim/quail/viqr.el: Use lexical-binding.
+
+ * lisp/leim/quail/compose.el: Use lexical-binding.
+
+ * lisp/ezimage.el: Use lexical-binding.
+
+2021-01-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/fns.c (hash_string): Fix bug#46111
+
+ Use `memcpy` instead of an unaligned memory access. On x86 at least,
+ GCC turns this `memcpy` into a single `mov`, so it's about as fast.
+
+2021-01-28 Stefan Kangas <stefan@marxist.se>
+
+ Add cross-reference to with-eval-after-load
+
+ * lisp/subr.el (eval-after-load): Doc fix; add cross-reference to
+ 'with-eval-after-load'.
+
+2021-01-28 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/generic-x.el (hosts-generic-mode): Support IPv6 addresses.
+
+2021-01-28 Stefan Kangas <stefan@marxist.se>
+
+ Add missing file systems to etc-fstab-generic-mode
+
+ * lisp/generic-x.el (etc-fstab-generic-mode): Add entries for missing
+ file systems.
+
+2021-01-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * test/Makefile.in (emacs): Use the C locale
+
+ This fixes spurious test failures in my environment for
+ `diff-mode-test-font-lock-syntax-one-line` (where my `diff` otherwise
+ returns "No newline at end of file" in French) and for
+ various tests in `emacs-module-tests` because errors signal
+ "Abandon" instead of "Abort".
+
+2021-01-28 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/ange-ftp.el (ange-ftp-ls): Handle several "--dired" switches.
+
+2021-01-28 Michael Albinus <michael.albinus@gmx.de>
+
+ Simplify auto-revert buffer list by watch descriptor (Bug#44639)
+
+ * lisp/autorevert.el (auto-revert--buffer-by-watch-descriptor):
+ Rename from `auto-revert--buffers-by-watch-descriptor'. Make it
+ an assoc list.
+ (auto-revert-notify-rm-watch, auto-revert-notify-add-watch)
+ (auto-revert-notify-handler): Adapt accordingly. Based on a
+ patch provided by Spencer Baugh <sbaugh@catern.com>. (Bug#44639)
+
+2021-01-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Use lexical-binding in lisp/{term,nxml,language}
+
+ * test/lisp/electric-tests.el:
+ * lisp/term/w32console.el:
+ * lisp/nxml/rng-util.el:
+ * leim/leim-ext.el: Use lexical-binding.
+
+ * lisp/international/titdic-cnv.el (tit-process-header)
+ (miscdic-convert):
+ * lisp/international/mule-cmds.el (leim-list-header):
+ * lisp/international/ja-dic-cnv.el (skkdic-convert):
+ Use lexical-binding in the generated file.
+
+2021-01-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Protect against bad results from libravatar
+
+ * lisp/image/gravatar.el (gravatar--service-libravatar): Don't
+ have (gravatar-retrieve "foobar@zjp.codes" 'ignore) (which returns
+ a CNAME) bug out.
+
+2021-01-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix numerical `comment-padding' value
+
+ * lisp/newcomment.el (comment-padright): Allow using a number for
+ `comment-padding', like the doc string says (bug#40056).
+
+2021-01-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the default `whitespace-enable-predicate' use `derived-mode-p'
+
+ * lisp/whitespace.el (whitespace-enable-predicate): Use
+ `derived-mode-p' to check modes instead of `eq' (bug#40481).
+
+2021-01-28 Mattias M <mattias@marka.ee> (tiny change)
+
+ Fix fill-paragraph in asm-mode
+
+ * lisp/progmodes/asm-mode.el: The value of fill-prefix ought to be nil
+ not "\t" so that fill-context-prefix can do its thing. In fact,
+ fill-prefix does not have to be set at all because asm-mode derives
+ from prog-mode and fill-prefix is set in simple.el.
+
+ * test/lisp/progmodes/asm-mode-tests.el: Add relevant test (bug#41064).
+
+2021-01-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow commenting out white space lines in latex-mode
+
+ * lisp/newcomment.el (comment-region-default-1): Allow commenting
+ out whitespace-only regions (bug#41793).
+
+ * lisp/textmodes/tex-mode.el (latex--comment-region): Use it.
+ (latex-mode): Set a comment style shim.
+
+2021-01-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix Gnus icalendar button navigation
+
+ * lisp/gnus/gnus-icalendar.el (gnus-icalendar-insert-button): Mark
+ buttons correctly for TAB navigation (bug#46135).
+
+2021-01-28 Harald Jörg <haj@posteo.de>
+
+ perl-mode.el: Eliminate keywords which are not in Perl.
+
+ * lisp/progmodes/perl-mode.el (perl-imenu-generic-expression):
+ Remove keywords which are not part of Perl.
+ (perl-font-lock-keywords-2): Remove keywords which are not part of
+ Perl (bug#46024). (These keywords are part of Raku; aka. Perl 6.)
+
+2021-01-28 João Távora <joaotavora@gmail.com>
+
+ Allow project/xref packages to be used in Emacs 26.1
+
+ * lisp/progmodes/project.el: Change Package-Requires to Emacs 26.1
+ (bug#44671).
+
+ * lisp/progmodes/xref.el: Ditto.
+
+2021-01-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/macroexp.el (macroexp-if): Fix typo
+
+2021-01-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/pcase.el (pcase--split-pred): Handle `memq` pred.
+
+ Improve handling of the `member` tests generated from (or 'a 'b 'c).
+ This will expand
+
+ (pcase EXP ((and (or 1 2 3) (guard (FOO))) EXP1) (1 EXP2) (6 EXP3))
+
+ to
+
+ (cond ((memql '(3 2 1) EXP)
+ (cond ((FOO) EXP1) ((eql EXP 1) EXP2)))
+ ((eql EXP 6) EXP3))
+
+ rather than to
+
+ (cond ((memql '(3 2 1) EXP)
+ (cond ((FOO) EXP1) ((eql EXP 1) EXP2) ((eql EXP 6) EXP3)))
+ ((eql EXP 1) EXP2)
+ ((eql EXP 6) EXP3))
+
+2021-01-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/macroexp.el (macroexp--expand-all): Perform β-reduction
+
+ Also, in `funcall` macroexpand the function before checking to see if
+ we can remove the `funcall`.
+
+ (macroexp-if): Trim trailing `nil` in the generated code while we're at it.
+
+2021-01-27 Juri Linkov <juri@linkov.net>
+
+ * lisp/replace.el (query-replace-read-from-suggestions): New function.
+
+ (query-replace-read-from): Use it instead of hard-coded '(car search-ring)'.
+ (read-regexp-suggestions): Add the active region (bug#41692).
+
+2021-01-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ * admin/notes/unicode: titdic-cnv.el is now utf-8.
+
+2021-01-27 Juri Linkov <juri@linkov.net>
+
+ Support multi-line prompt and contents in previous-line-or-history-element.
+
+ * lisp/simple.el (previous-line-or-history-element): Move to the
+ beginning of minibuffer contents if there is editable minibuffer contents
+ on the same line after moving point to the prompt (bug#46033).
+ Fix minimal old-column from 0 to 1 to put point at the beginning of
+ minibuffer contents after going to the previous history element.
+
+2021-01-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/international/titdic-cnv.el (tsang-quick-converter): Simplify
+
+ Merge branches which only differed in the `charset` property of the
+ strings they intended to return, since that info gets lost later
+ on anyway.
+
+2021-01-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/international/titdic-cnv.el: Revert to utf-8 encoding
+
+ While it's true that using the iso-2022-jp encoding on the file does
+ allow Emacs to render the two strings differently, this only applies to
+ the source file. The .elc files all use `utf-8-emacs` encoding anyway,
+ so that info is lost. And the difference is even lost before we write
+ the .elc file because when Emacs byte-compiles that code the
+ byte-compiler considers those two strings as "equal" and emits only one
+ string in the byte-code (so the two branches return `eq` strings).
+
+ So, I think using `iso-2022-jp` is a bad idea here: it gives the
+ illusion that the the `charset` info exists, even it will be lost.
+ Eli discussed it with Handa-san a year ago, and they arrived at the
+ conclusion that the charset information is indeed no longer important.
+
+2021-01-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Use lexical-binding in of all lisp/language
+
+ * lisp/international/titdic-cnv.el (pinyin-convert):
+ Enable lexical-binding in the generated file(s).
+
+ * lisp/language/ethio-util.el: Use lexical-binding.
+ (ethio-tex-to-fidel-buffer): Use `inhibit-read-only`. Remove unused
+ vars `p` and `ch`.
+
+ * lisp/language/hanja-util.el: Use lexical-binding.
+
+ * lisp/language/ind-util.el: Use lexical-binding.
+ (indian-translate-region): Actually use the `from` and `to` arguments.
+ (<toplevel>): Use `dlet`. Remove unused var `current-repertory`.
+ (indian-2-column-to-ucs-region): Remove unused var `pos`.
+
+ * lisp/language/japan-util.el: Use lexical-binding.
+ (japanese-katakana-region, japanese-hiragana-region)
+ (japanese-zenkaku-region): Remove unused var `next`.
+
+ * lisp/language/korea-util.el: Use lexical-binding.
+
+ * lisp/language/lao-util.el: Use lexical-binding.
+ (lao-composition-function): Remove unused var `glyph`.
+
+ * lisp/language/thai-util.el: Use lexical-binding.
+ (thai-composition-function): Remove unused var `glyph`.
+
+ * lisp/language/thai-word.el: Use lexical-binding.
+ (thai-forward-word): Remove unused var `tail`.
+
+ * lisp/language/tibet-util.el: Use lexical-binding.
+ (tibetan-add-components): Remove unused var `tmp`.
+ (tibetan-compose-region): Remove unused vars `str`, `result`, `chars`.
+
+ * lisp/language/viet-util.el:
+ * lisp/language/tv-util.el:
+ * lisp/language/cyril-util.el:
+ * lisp/language/china-util.el: Use lexical-binding.
+
+2021-01-27 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 3443a1c698 Fix last change
+
+2021-01-27 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 3f610177ad Avoid sending systemd shutdown notifications if non-daemon
+ 009df5cb3c * src/cmds.c (Fforward_line): Doc fix. (Bug#46027)
+ ee1c54ebc0 Improve documentation of sendmail.el defcustom's
+
+2021-01-27 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ b58fd1eab9 ; * lisp/language/cham.el: Fix copy-paste mistake in comment.
+
+2021-01-27 Eli Zaretskii <eliz@gnu.org>
+
+ Fix display of stretches of whitespace in the display margins
+
+ * src/xdisp.c (produce_stretch_glyph): Truncate the stretch glyph
+ due to line wrap only when drawing in the text area.
+ * src/xterm.c (x_draw_stretch_glyph_string):
+ * src/w32term.c (w32_draw_stretch_glyph_string): Fix the
+ adjustment of the stretch X and width so that stretch glyphs could
+ be drawn in the left margin. Reported by Paul W. Rankin
+ <pwr@bydasein.com>.
+
+2021-01-27 Michael Albinus <michael.albinus@gmx.de>
+
+ Some Tramp fixes
+
+ * doc/misc/tramp.texi (GVFS-based methods): Ban sftp RemoteCommand
+ option.
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-copy-file)
+ (tramp-adb-handle-rename-file): Avoid calling jka-compr when
+ writing the target file.
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-file-ownership-preserved-p):
+ Skip GROUP test on *BSD machines.
+
+ * test/lisp/net/tramp-tests.el (tramp-test17-insert-directory-one-file):
+ Skip for tamp-crypt.el.
+ (tramp--test-sh-no-ls--dired-p): Ignore errors.
+
+2021-01-27 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/dbus.el (dbus-monitor-handler): Disable buffer undo.
+
+2021-01-27 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'read-regexp' and friends
+
+ * doc/emacs/glossary.texi (Glossary): Add "Tag" to the Glossary.
+ * doc/emacs/maintaining.texi (Xref): Mention that identifiers are
+ also known as "tags".
+
+ * lisp/replace.el (read-regexp, read-regexp-suggestions): Improve
+ wording of doc strings. (Bug#46088) (Bug#46089)
+
+ (cherry picked from commit 49eb03d6c8a181fd46adbbcf1f0a976d0a9efa87)
+
+2021-01-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ read-regexp-suggestions doc string improvement
+
+ * lisp/replace.el (read-regexp-suggestions): Add a link to the
+ manual to explain what a tag is (bug#46089).
+
+ (cherry picked from commit f9cc2d48246fe8370e9286866e6115ba8e2acf44)
+
+2021-01-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Try to improve the read-regexp doc string
+
+ * lisp/replace.el (read-regexp): Attempt to clarify the semantics
+ (bug#46088).
+
+ (cherry picked from commit eded2a7ad7d456a417354a2797c18e9a578414d7)
+
+2021-01-27 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'read-regexp' and friends
+
+ * doc/emacs/glossary.texi (Glossary): Add "Tag" to the Glossary.
+ * doc/emacs/maintaining.texi (Xref): Mention that identifiers are
+ also known as "tags".
+
+ * lisp/replace.el (read-regexp, read-regexp-suggestions): Improve
+ wording of doc strings. (Bug#46088) (Bug#46089)
+
+2021-01-27 Juri Linkov <juri@linkov.net>
+
+ * lisp/subr.el (empty-history): Move defvar to functions where it's used.
+
+2021-01-27 Juri Linkov <juri@linkov.net>
+
+ Support variable name for previous-window in display-buffer-in-previous-window
+
+ * lisp/window.el (display-buffer-in-previous-window): Support the value of
+ 'previous-window' entry as a symbol for variable name (bug#45688).
+
+2021-01-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix indentation in sieve-mode
+
+ * lisp/net/sieve-mode.el (sieve-mode-indent-function): New function.
+ (sieve-mode): Don't inherit from C mode, because the syntax
+ doesn't really resemble C mode that much (except being curly braced).
+
+2021-01-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix setting of line/point style in calc gnuplot
+
+ * lisp/calc/calc-graph.el (calc-graph-set-styles): Modern gnuplot
+ requires "ls" before the line style and "ps" before the point
+ style (bug#46070).
+
+2021-01-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ read-regexp-suggestions doc string improvement
+
+ * lisp/replace.el (read-regexp-suggestions): Add a link to the
+ manual to explain what a tag is (bug#46089).
+
+2021-01-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Try to improve the read-regexp doc string
+
+ * lisp/replace.el (read-regexp): Attempt to clarify the semantics
+ (bug#46088).
+
+2021-01-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Use lexical-binding in all of `lisp/url`
+
+ * lisp/url/url-dav.el: Use lexical-binding.
+ (url-dav-process-DAV:prop): Remove unused var `handler-func`.
+ (url-dav-lock-resource): Remove unused var `child-url`.
+ (url-dav-active-locks): Remove unused var `properties`.
+ (url-dav-delete-directory): Remove unused var `props`.
+ (url-dav-file-name-completion): Remove unused var `result`.
+
+ * lisp/url/url-expand.el (url-expand-file-name): Use \s
+
+ * lisp/url/url-file.el (url-file): Improve regexp.
+
+ * lisp/url/url-gw.el: Use lexical-binding.
+ (url-open-stream): Remove unused var `cur-retries`, `retry`, `errobj`.
+
+ * lisp/url/url-imap.el: Use lexical-binding.
+ (imap-username, imap-password): Declare.
+
+ * lisp/url/url-mailto.el: Use lexical-binding.
+ (url-mailto): Remove unused var `func`. Use `push`.
+
+ * lisp/url/url-news.el: Use lexical-binding.
+ (url-news): Remove unused var `article-brackets`.
+
+ * lisp/url/url-cid.el:
+ * lisp/url/url-cache.el:
+ * lisp/url/url-about.el:
+ * lisp/url/url-tramp.el:
+ * lisp/url/url-proxy.el:
+ * lisp/url/url-privacy.el:
+ * lisp/url/url-nfs.el:
+ * lisp/url/url-ldap.el:
+ * lisp/url/url-misc.el:
+ * lisp/url/url-methods.el: Use lexical-binding.
+
+2021-01-26 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/sh-script.el (sh-smie-sh-rules): Tweak indent of new `for`
+
+ The new `for (TEST) { BODY }` syntax introduces various challenges.
+ This patch just fixes a trivial subcase.
+
+2021-01-26 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Revert "Allow gnus-retrieve-headers to return headers directly"
+
+ This reverts commit 20add1cd22f9775a4475148b300cf2a4de4bd54a. This
+ needs more work before it's ready to merge.
+
+2021-01-26 Eli Zaretskii <eliz@gnu.org>
+
+ Fix typos and punctuation
+
+ * src/w32fns.c:
+ * src/frame.h:
+ * doc/lispref/frames.texi (Frame Layout):
+ * etc/NEWS: Fix typos and punctuation in recent changes.
+
+2021-01-26 Martin Rudalics <rudalics@gmx.at>
+
+ Fix typo in last change of FRAME_INTERNAL_BORDER_WIDTH
+
+ * src/frame.h (FRAME_INTERNAL_BORDER_WIDTH): Fix typo in last
+ change.
+
+2021-01-26 Alexander Miller <alexanderm@web.de>
+
+ Add distinct controls for child frames' borders (Bug#45620)
+
+ The background of the 'child-frame-border' face instead of the
+ 'internal-border' face now controls the color of child frames'
+ borders.
+
+ The 'child-frame-border-width' frame parameter is now used for the
+ width of child frames' borders instead of internal-border-width',
+ though we still fall back on using the latter if the former is not
+ set.
+
+ * doc/lispref/frames.texi (Frame Layout): Mention
+ 'child-frame-border' and 'child-frame-border-width'.
+ (Layout Parameters): Mention 'child-frame-border-width'.
+ * etc/NEWS: Mention new face 'child-frame-border' and frame
+ parameter 'child-frame-border-width'.
+ * lisp/faces.el (child-frame-border): New face.
+ * src/dispextern.h (enum face_id): Add CHILD_FRAME_BORDER_FACE_ID.
+ * src/frame.c (Fframe_child_frame_border_width): New function.
+ (gui_report_frame_params): Add entry for Qchild_frame_border_width.
+ * src/frame.h (struct frame): New slot child_frame_border_width.
+ (FRAME_CHILD_FRAME_BORDER_WIDTH): New inlined function.
+ * src/nsfns.m (ns_set_child_frame_border_width): New function.
+ (Fx_create_frame): Handle Qchild_frame_border_width parameter.
+ (ns_frame_parm_handlers): Add ns_set_child_frame_border_width.
+ * src/nsterm.m (ns_clear_under_internal_border): Handle
+ CHILD_FRAME_BORDER_FACE_ID.
+ * src/w32fns.c (w32_clear_under_internal_border): Handle
+ CHILD_FRAME_BORDER_FACE_ID.
+ (w32_set_internal_border_width): New function.
+ (Fx_create_frame): Handle Qchild_frame_border_width parameter.
+ (w32_frame_parm_handlers): Add w32_set_child_frame_border_width.
+ * src/xfaces.c (lookup_basic_face, realize_basic_faces): Handle
+ CHILD_FRAME_BORDER_FACE_ID.
+ * src/xfns.c (x_set_child_frame_border_width): New function.
+ (Fx_create_frame): Handle Qchild_frame_border_width parameter.
+ (x_frame_parm_handlers): Add x_set_child_frame_border_width.
+ * src/xterm.c (x_clear_under_internal_border)
+ (x_after_update_window_line): Handle CHILD_FRAME_BORDER_FACE_ID.
+
+2021-01-26 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Use `lexical-binding` in all `lisp/international` files
+
+ * lisp/startup.el (keyboard-type): Make obsolete and lex-bound.
+
+ * admin/unidata/unidata-gen.el (unidata-gen-file)
+ (unidata-gen-charprop): Mark the generated files to use lexical binding.
+
+ * lisp/international/isearch-x.el: Use lexical-binding.
+ (junk-hist): Declare locally.
+
+ * lisp/international/iso-cvt.el:
+ * lisp/international/utf-7.el:
+ * lisp/international/robin.el:
+ * lisp/international/ogonek.el:
+ * lisp/international/latin1-disp.el:
+ * lisp/international/kkc.el:
+ * lisp/international/kinsoku.el:
+ * lisp/international/ja-dic-utl.el: Use lexical-binding.
+
+ * lisp/international/ja-dic-cnv.el: Use lexical-binding.
+ (skkdic-breakup-string): Remove unused var `kana-len`.
+
+ * lisp/international/latexenc.el: Use lexical-binding.
+ (tex-start-of-header): Declare.
+
+ * lisp/international/mule-diag.el: Use lexical-binding.
+ (list-character-sets): Remove unused var `pos`.
+ (list-character-sets-1): Remove unused vars `tail` and `charset`.
+ (list-charset-chars): Remove unused vars `chars` and `plane`.
+ (describe-coding-system): Remove unused var `extra-spec`.
+ (mule--print-opened): New var.
+ (print-fontset): Bind it.
+ (print-fontset-element): Use it instead of `print-opened`.
+
+ * lisp/international/quail.el: Use lexical-binding.
+ (quail-start-translation, quail-start-conversion):
+ Remove unused var `generated-events`.
+ (quail-help-insert-keymap-description): Use local dynbound var `the-keymap`.
+
+2021-01-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make subdirs . nil in dir-locals in ~/ work
+
+ * lisp/files.el (dir-locals-collect-variables): Compare directory
+ names after expanding. This makes a (subdirs . nil) in ~/ work as
+ expected (bug#17205).
+
+ Test case:
+
+ ((nil . ((a . "hallo")
+ (subdirs . nil))))
+
+ in ~/
+
+2021-01-25 Juri Linkov <juri@linkov.net>
+
+ Don't move point to the prompt in previous-line-or-history-element (bug#46033)
+
+ * lisp/simple.el (previous-line-or-history-element):
+ Avoid moving point to the prompt.
+
+2021-01-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fontify special forms and macros the same
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp--el-match-keyword): Handle
+ special forms and macros the same way (bug#43265). This makes
+ things like (setq a '(if a b)) be fontified correctly (i.e., not
+ fontified as a keyword).
+
+2021-01-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Rewrite lisp--el-funcall-position-p to be inverse of the -not function
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp--el-funcall-position-p):
+ Rename and rewrite to return the inverse value. Non-inverted
+ predicate functions are easier to reason about.
+ (lisp--el-non-funcall-position-p): Make obsolete.
+
+2021-01-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix macro fontification in `condition-case' handler bodies
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp--el-non-funcall-position-p):
+ Fontify macros in the BODY of HANDLERS in `condition-case'
+ correctly (bug#43265).
+
+2021-01-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak `condition-case' keyword highlights
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp--el-non-funcall-position-p):
+ Tweak `condition-case' position check to skip the VAR form.
+
+2021-01-24 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into native-comp
+
+2021-01-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add some elisp-mode font lock tests
+
+2021-01-24 Michael Albinus <michael.albinus@gmx.de>
+
+ Make Tramp's insert-directory more robust
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-insert-directory):
+ Use `tramp-sh--quoting-style-options'.
+
+ * test/lisp/net/tramp-tests.el (tramp--test-hpux-p, tramp--test-ksh-p):
+ Remove superfluous nil.
+ (tramp--test-sh-no-ls--dired-p): New defun.
+ (tramp--test-special-characters): Use it.
+
+2021-01-24 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Fix insertion logic of newly subscribed Gnus groups
+
+ * lisp/gnus/gnus-start.el (gnus-subscribe-newsgroup): This was a
+ misunderstanding of the next/previous argument: no group should ever
+ be inserted before "dummy.group".
+ (gnus-group-change-level): Make it clearer that PREVIOUS can be
+ nil. In fact none of this code would error on a nil value, but it
+ _looks_ like nil is unexpected.
+
+2021-01-24 Philipp Stephani <phst@google.com>
+
+ Add more assertions to recently-added process test.
+
+ * test/src/process-tests.el (process-tests/multiple-threads-waiting):
+ Also check that 'thread-join' and 'thread-last-error' return the
+ expected errors.
+
+2021-01-24 Dmitry Gutov <dgutov@yandex.ru>
+
+ Erase the buffer only after fetching the new contents
+
+ * lisp/progmodes/xref.el (xref-revert-buffer):
+ Erase the buffer only after fetching the new contents (bug#46042).
+
+ (cherry picked from commit 5821dee0949b2913c07970d6e4b8bb8e8a35f036)
+
+2021-01-24 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix recently uncovered 'make check' failures
+
+ For discussion, see the following thread:
+ https://lists.gnu.org/r/emacs-devel/2021-01/msg01111.html
+
+ * test/lisp/autorevert-tests.el
+ (auto-revert-test07-auto-revert-several-buffers):
+ * test/lisp/emacs-lisp/seq-tests.el (test-seq-do-indexed)
+ (test-seq-random-elt-take-all): Fix errors from using add-to-list on
+ lexical variables.
+ * test/lisp/emacs-lisp/cl-lib-tests.el
+ (cl-lib-defstruct-record): Expect test to succeed when byte-compiled
+ following change of 2021-01-23 'Fix missing file&line info in
+ "Unknown defun property" warnings'.
+ (cl-lib-tests--dummy-function): Remove; no longer needed.
+ (old-struct): Silence byte-compiler warning about unused lexical
+ variable.
+
+2021-01-24 Jean Louis <bugs@gnu.support>
+
+ Add support for dired compressing .lz/.lzo files
+
+ * lisp/dired-aux.el (dired-compress-files-alist): Add support for
+ .lz/.lzo files (bug#44901).
+
+2021-01-23 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Properly initialize gnus-search-namazu-index-directory
+
+ * lisp/gnus/gnus-search.el (gnus-search-namazu): We were missing the
+ appropriate :initform on this slot definition (Bug#46047).
+
+2021-01-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make (subdirs . nil) in .dir-locals.el work
+
+ * lisp/files.el (dir-locals-collect-variables): Don't
+ destructively modify the cached structure (bug#17205), because
+ that means that (subdirs . nil) doesn't work.
+
+2021-01-23 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Fix missing file&line info in "Unknown defun property" warnings
+
+ * lisp/emacs-lisp/byte-run.el (defmacro, defun): Use
+ `macroexp--warn-and-return` rather than `message`.
+
+ * lisp/emacs-lisp/macroexp.el: Fix `macroexp--compiling-p`.
+ (macroexp--warn-and-return): Don't try and detect repetition on forms
+ like `nil`.
+ (macroexp-macroexpand): Don't forget to bind `macroexpand-all-environment`.
+
+2021-01-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Provide a (thing-at-point 'url) in eww buffers
+
+ * lisp/net/eww.el (eww-mode): Allow (thing-at-point 'url) to work
+ in eww buffers.
+ (eww--url-at-point): New function.
+
+2021-01-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a mechanism for buffer-local thing-at-points
+
+ * doc/lispref/text.texi (Buffer Contents): Document it.
+
+ * lisp/thingatpt.el (thing-at-point-provider-alist): New variable.
+ (thing-at-point): Use it.
+
+2021-01-23 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib by running admin/merge-gnulib
+
+2021-01-23 Gabriel do Nascimento Ribeiro <gabriel.nascimento@nubank.com.br>
+
+ Use single post-command-hook on hl-line modes
+
+ * lisp/hl-line.el (hl-line-mode, global-hl-line-mode): Ensure
+ that 'maybe-unhighlight' is called after line is highlighted.
+ (Bug#45946)
+ (hl-line-unhighlight, global-hl-line-unhighlight): Set overlay
+ variable to nil after overlay is deleted.
+
+2021-01-23 Philipp Stephani <phst@google.com>
+
+ Add a unit test testing interaction between threads and processes.
+
+ This unit test tests that we can call 'accept-process-output' in
+ parallel from multiple threads.
+
+ * test/src/process-tests.el (process-tests/multiple-threads-waiting):
+ New unit test.
+
+2021-01-23 Philipp Stephani <phst@google.com>
+
+ Avoid a few compilation warnings in Objective-C code.
+
+ * src/nsfns.m (Fns_frame_restack): Remove unused variable 'flag'.
+
+ * src/nsmenu.m (ns_update_menubar): Remove unused variable 'pool'.
+
+ * src/nsterm.m (focus_view, hide_bell): Define conditionally.
+ (ns_update_end): Define variable 'view' conditionally.
+ (ns_redraw_scroll_bars): Don't define unused function.
+ (copyRect): Don't perform arithmetic on 'void' pointers.
+ (nswindow_orderedIndex_sort): Make static.
+
+2021-01-23 Philipp Stephani <phst@google.com>
+
+ * .clang-format: Fix base style.
+
+2021-01-23 Philipp Stephani <phst@google.com>
+
+ Add a FIXME comment to improve the SIGCHLD race condition handling.
+
+ * src/process.c: Add FIXME comment describing how we could avoid the
+ self-pipe on modern Unix-like systems.
+
+2021-01-23 Philipp Stephani <phst@google.com>
+
+ Mark both ends of self-pipe a nonblocking.
+
+ While no deadlocks caused by the blocking write end have been reported
+ yet, marking both ends nonblocking is consistent and also recommended
+ in the GNU/Linux manpage of 'select'.
+
+ * src/process.c (child_signal_init): Mark write end of self-pipe as
+ nonblocking.
+
+2021-01-23 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix failed autorevert test on emba
+
+ * test/lisp/autorevert-tests.el (auto-revert-test05-global-notify):
+ Check, whether buffer is alive.
+
+2021-01-23 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/infra/gitlab-ci.yml (.job-template): Check also for test/lib-src/*.el.
+
+2021-01-23 Eli Zaretskii <eliz@gnu.org>
+
+ Clean up the recently added self-pipe mechanism for WINDOWSNT
+
+ * src/process.c (child_signal_init, child_signal_read)
+ (child_signal_notify): #ifdef away on WINDOWSNT.
+
+2021-01-23 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change
+
+ * doc/lispref/text.texi (Undo): Add a cross-reference to the
+ description of 'undo-amalgamate-change-group'.
+ (Atomic Changes): Expand and improve the description of
+ 'undo-amalgamate-change-group'. (Bug#42303)
+
+2021-01-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention undo-amalgamate-change-group in the lispref manual
+
+ * doc/lispref/text.texi (Atomic Changes): Mention
+ undo-amalgamate-change-group (bug#42303).
+
+ (cherry picked from commit ba25a82855a2c03c25fec83f3056c166b692e94f)
+
+2021-01-23 Dmitry Gutov <dgutov@yandex.ru>
+
+ Erase the buffer only after fetching the new contents
+
+ * lisp/progmodes/xref.el (xref-revert-buffer):
+ Erase the buffer only after fetching the new contents (bug#46042).
+
+2021-01-22 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/simple.el (newline-and-indent): Disable `electric-indent-mode`
+
+ With `electric-indent-mode` enabled, `newline-and-indent` ends up indenting
+ 3 times: once for the original line and twice on the new line.
+ `reindent-then-newline-and-indent` is even worse, indenting twice
+ both lines.
+ None of those commands should be affected by `electric-indent-mode`
+ since they even explicitly say in their name when and how they do
+ indentation.
+
+ (reindent-then-newline-and-indent): Temporarily disable
+ `electric-indent-mode` as well.
+
+2021-01-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention undo-amalgamate-change-group in the lispref manual
+
+ * doc/lispref/text.texi (Atomic Changes): Mention
+ undo-amalgamate-change-group (bug#42303).
+
+2021-01-22 Paul Eggert <eggert@cs.ucla.edu>
+
+ Work around __has_attribute bug in clang 3.4
+
+ * src/conf_post.h (HAS_ATTRIBUTE):
+ * src/emacs-module.h.in (EMACS_ATTRIBUTE_NONNULL):
+ Port to clang 3.4 and earlier.
+
+2021-01-22 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib by running admin/merge-gnulib
+
+2021-01-22 Paul Eggert <eggert@cs.ucla.edu>
+
+ Prepare for update from Gnulib
+
+ * configure.ac: Also create lib/malloc and lib/deps/malloc
+ if the dynarray module is in use, as Gnulib regex will
+ start needing it due to recent glibc changes.
+
+2021-01-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up previous mh-speed.el ignored variable change
+
+ * lisp/mh-e/mh-speed.el (mh-speed-toggle, mh-speed-view): Mark the
+ ignored parameter with _ instead of using the Common Lispish
+ (declare (ignore args)) (which Emacs Lisp doesn't really support),
+ except by accident.
+
+2021-01-22 Keith David Bershatsky <esq@lawlist.com>
+
+ Add more isearch-related bindings to ns-win.el
+
+ * lisp/term/ns-win.el (minibuffer-local-isearch-map): Add more
+ bindings to mirror bindings in isearch.el (bug#15667).
+
+2021-01-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make nnml handle invalid non-ASCII headers more consistently
+
+ * lisp/gnus/nnml.el (nnml--encode-headers): New function to
+ RFC2047-encode invalid Subject/From headers (bug#45925). This
+ will make them be displayed more consistently in the Summary
+ buffer (but still "wrong" sometimes, since there's not that much
+ we can guess at at this stage, charset wise).
+ (nnml-parse-head): Use it.
+
+2021-01-22 Michael Albinus <michael.albinus@gmx.de>
+
+ Use RemoteCommand option for Tramp's sshx and scpx methods
+
+ * doc/misc/tramp.texi (Inline methods) <sshx>:
+ (External methods) <scpx>: Adapt call sequence.
+ (Remote shell setup): Mention, that sshx and scpx overwrite
+ RemoteCommand.
+ (Remote processes): Restriction: direct asynchronous processes
+ cannot be used when RemoteCommand is in use.
+ `tramp-remote-process-environment' is not ignored any longer.
+
+ * lisp/net/tramp-sh.el (tramp-methods) <sshx, scpx>: Handle login
+ shell via RemoteCommand. Remove `tramp-direct-async' parameter.
+ (tramp-maybe-open-connection): Add "-i" to login.
+
+ * lisp/net/tramp-smb.el (tramp-smb-errors):
+ Add "NT_STATUS_NOT_SUPPORTED".
+ (tramp-smb-handle-insert-directory): Fix point moving error.
+
+ * test/lisp/net/tramp-tests.el (tramp-test34-explicit-shell-file-name):
+ Use `get-buffer-process' where appropriate.
+
+2021-01-22 Mattias Engdegård <mattiase@acm.org>
+
+ Calc: use big brackets around function arguments
+
+ * lisp/calc/calccomp.el (math-compose-expr): Use big brackets around
+ arguments in Big mode, so that expressions like sin(a/b) look a bit
+ better.
+
+2021-01-22 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid sending systemd shutdown notifications if non-daemon
+
+ * src/emacs.c (Fkill_emacs): Send the shutdown notification only
+ in daemon mode. (Bug#46022)
+
+2021-01-22 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change for DOS_NT systems
+
+ * src/term.c (tty_draw_row_with_mouse_face)
+ (tty_write_glyphs_with_face): Don't define on MSDOS and WINDOWSNT,
+ as those have their own implementations of that.
+
+2021-01-22 João Távora <joaotavora@gmail.com>
+
+ Enable TTY mouse-face support when built without GPM support
+
+ * src/term.c (tty_write_glyphs_with_face): Move definition out of
+ ifdef block.
+ * src/xdisp.c (draw_row_with_mouse_face): Now called
+ unconditionally on all platforms.
+
+2021-01-22 Glenn Morris <rgm@gnu.org>
+
+ * lisp/textmodes/remember.el (remember-text-format-function): Fix type.
+
+2021-01-22 Eli Zaretskii <eliz@gnu.org>
+
+ * src/cmds.c (Fforward_line): Doc fix. (Bug#46027)
+
+2021-01-22 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of sendmail.el defcustom's
+
+ * lisp/mail/sendmail.el (mail-archive-file-name)
+ (mail-default-reply-to, mail-self-blind, mail-default-headers):
+ Say in the doc string that 'message-default-mail-headers' shall be
+ customized when using 'message-mode' for email composition.
+ (Bug#46029)
+
+2021-01-21 Ted Zlatanov <tzz@lifelogs.com>
+
+ * test/infra/gitlab-ci.yml: Copy newer files to image to build less often.
+
+2021-01-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Fix spurious "Lexical argument shadows the dynamic variable" due to inlining
+
+ Before this patch doing:
+
+ rm lisp/calendar/calendar.elc
+ make lisp/calendar/cal-hebrew.elc
+
+ would spew out lots of spurious such warnings about a `date` argument,
+ pointing to code which has no `date` argument in sight. This was
+ because that code had calls to inlinable functions (taking a `date`
+ argument) defined in `calendar.el`, and while `date` is a normal
+ lexical var at the site of those functions' definitions, it was
+ declared as dynbound at the call site.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand):
+ Don't impose our local context onto the inlined function.
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el: Add matching test.
+
+2021-01-21 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/net/webjump.el: Add Maintainer: emacs-devel.
+
+ Ref: https://lists.gnu.org/r/emacs-devel/2021-01/msg01019.html
+
+2021-01-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't have type-break-mode signal errors on corrupted files
+
+ * lisp/type-break.el (type-break-get-previous-time):
+ (type-break-get-previous-count): Signal a warning instead of an
+ error (bug#38246). type-break will still continue to work even if
+ the database can't be loaded after a restart, but this allows
+ Emacs to be started.
+
+2021-01-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix message.el build warning from previous change
+
+ * lisp/gnus/message.el (subr-x): Fix build warning from previous
+ commit.
+
+2021-01-21 Ted Zlatanov <tzz@lifelogs.com>
+
+ * test/infra/gitlab-ci.yml: Revert to always building.
+
+2021-01-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add dired support for compressing .pax files
+
+ * lisp/dired-aux.el (dired-compress-files-alist): Add support for
+ compressing .pax files (bug#40135).
+
+2021-01-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak previous message-forward-included-mime-headers change
+
+ * lisp/gnus/message.el (message-forward-included-mime-headers):
+ Should probably not include Content-Transfer-Encoding, because we
+ will re-encode anyway.
+
+2021-01-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make Message respect header removal instructions more
+
+ * doc/misc/message.texi (Forwarding): Document it.
+
+ * lisp/gnus/message.el (message-forward-ignored-headers): Improve
+ documentation.
+ (message-forward-included-headers): Ditto.
+ (message-forward-included-mime-headers): New user option.
+ (message-remove-ignored-headers): Use it to preserve the necessary
+ MIME headers.
+ (message-forward-make-body): Remove headers when forwarding as
+ MIME, too.
+
+2021-01-21 Eli Zaretskii <eliz@gnu.org>
+
+ A better fix for 'kill-visual-line'
+
+ * lisp/simple.el (kill-visual-line): Use the 6th element of the
+ return value of 'posn-at-point', which provides the coordinates in
+ terms or row and column, and is thus more reliable for deciding
+ whether we moved to the next screen line. (Bug#45837)
+
+2021-01-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix thinko in previous footnote.el change
+
+ * lisp/mail/footnote.el (footnote--regenerate-alist): Don't error
+ out when there's no footnotes.
+
+2021-01-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Use `lexical-binding` in all the cal-*.el files
+
+ * lisp/calendar/cal-bahai.el: Use lexical-binding.
+ (calendar-bahai-date-string): Use `calendar-dlet*`.
+
+ * lisp/calendar/cal-china.el: Use lexical-binding.
+ (calendar-chinese-zodiac-sign-on-or-after)
+ (calendar-chinese-new-moon-on-or-after): Declare `year`.
+ (calendar-chinese-from-absolute-for-diary)
+ (calendar-chinese-to-absolute-for-diary)
+ (calendar-chinese-mark-date-pattern): Avoid dynbound var `date` as
+ function argument.
+
+ * lisp/calendar/cal-coptic.el: Use lexical-binding.
+ (calendar-coptic-date-string): Use `calendar-dlet*`.
+ (calendar-ethiopic-to-absolute, calendar-ethiopic-from-absolute)
+ (calendar-ethiopic-date-string, calendar-ethiopic-goto-date):
+ Avoid dynbound var `date` as function argument.
+
+ * lisp/calendar/cal-french.el: Use lexical-binding.
+
+ * lisp/calendar/cal-hebrew.el: Use lexical-binding.
+ (holiday-hebrew-hanukkah): Don't use the third form in `dotimes`.
+
+ * lisp/calendar/cal-islam.el: Use lexical-binding.
+ (calendar-islamic-to-absolute): Comment out unused vars `month` and `day`.
+
+ * lisp/calendar/cal-move.el:
+ * lisp/calendar/cal-mayan.el:
+ * lisp/calendar/cal-iso.el: Use lexical-binding.
+
+ * lisp/calendar/cal-persia.el: Use lexical-binding.
+ (calendar-persian-date-string): Use `calendar-dlet*`.
+
+ * lisp/calendar/cal-html.el: Use lexical-binding.
+ (cal-html-insert-minical): Comment out unused var `date`.
+ (cal-html-cursor-month, cal-html-cursor-year): Mark `event` arg as unused.
+
+ * lisp/calendar/cal-menu.el: Use lexical-binding.
+ (diary-list-include-blanks): Declare var.
+
+ * lisp/calendar/cal-x.el: Use lexical-binding.
+
+ * lisp/calendar/cal-tex.el: Use lexical-binding.
+ (diary-list-include-blanks): Declare var.
+ (cal-tex-insert-days, cal-tex-cursor-week-iso, cal-tex-week-hours)
+ (cal-tex-weekly-common, cal-tex-cursor-filofax-2week)
+ (cal-tex-cursor-filofax-daily, cal-tex-daily-page): Declare `date`
+ as dynbound for the benefit of `cal-tex-daily-string`.
+
+2021-01-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Use `calendar-read-sexp` instead of the now obsolete `calendar-read`
+
+ * lisp/calendar/diary-lib.el (diary-insert-cyclic-entry):
+ * lisp/calendar/cal-persia.el (calendar-persian-read-date):
+ * lisp/calendar/cal-move.el (calendar-goto-day-of-year):
+ * lisp/calendar/cal-mayan.el (calendar-mayan-read-haab-date)
+ (calendar-mayan-read-tzolkin-date):
+ * lisp/calendar/cal-julian.el (calendar-julian-goto-date)
+ (calendar-astro-goto-day-number):
+ * lisp/calendar/cal-iso.el (calendar-iso-read-date):
+ * lisp/calendar/cal-islam.el (calendar-islamic-read-date):
+ * lisp/calendar/cal-hebrew.el (calendar-hebrew-read-date)
+ (calendar-hebrew-list-yahrzeits):
+ * lisp/calendar/cal-french.el (calendar-french-goto-date):
+ * lisp/calendar/cal-coptic.el (calendar-coptic-read-date):
+ * lisp/calendar/cal-china.el (calendar-chinese-goto-date):
+ * lisp/calendar/cal-bahai.el (calendar-bahai-read-date):
+ * lisp/calendar/holidays.el (list-holidays): Use `calendar-read-sexp`.
+
+2021-01-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/calendar/cal-french.el (calendar-french-accents-p): Obsolete function
+
+ Always assume accented letters can be used
+
+ (calendar-french-month-name-array)
+ (calendar-french-special-days-array): Use the accented names.
+ (calendar-french-multibyte-month-name-array)
+ (calendar-french-multibyte-special-days-array): Make those vars
+ obsolete aliases.
+ (calendar-french-month-name-array, calendar-french-day-name-array)
+ (calendar-french-special-days-array): Mark functions as obsolete.
+ (calendar-french-date-string, calendar-french-goto-date): Always use
+ the text with accents.
+
+2021-01-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/calendar/calendar.el (calendar-read-sexp): New function
+
+ (calendar-read): Mark as obsolete.
+ (calendar-read-date): Use it. Add `default-date` argument.
+ Provide defaults for the month and day (fixes bug#32105).
+
+2021-01-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile--declare-var): Fix warning
+
+ Make sure the "declared after first use" is under the control of
+ the `lexical` option.
+
+2021-01-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix recent remember-diary-extract-entries change
+
+ * lisp/textmodes/remember.el (remember-diary-extract-entries): Use
+ `remember-diary-file' over `diary-file'.
+
+2021-01-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ checkdoc-spellcheck-documentation-flag doc string improvement
+
+ * lisp/emacs-lisp/checkdoc.el
+ (checkdoc-spellcheck-documentation-flag): Mention
+ `ispell-kill-ispell' (bug#6221).
+
+2021-01-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Always send Lisp words to checkdoc-ispell-init"
+
+ This reverts commit 93141d581330d94e7eec9f114def2bec15f87866.
+
+ This would make checkdoc words be used in other flyspell
+ buffers.
+
+2021-01-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Always send Lisp words to checkdoc-ispell-init
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-ispell-init): Always send
+ the Lisp words to the process (bug#6221). This allows an existing
+ ispell process to be correctly initialised.
+
+2021-01-20 Juri Linkov <juri@linkov.net>
+
+ Move the ‘declare’ form before the interactive spec in 10 functions.
+
+ * lisp/emacs-lisp/package.el (package-menu-hide-package):
+ * lisp/font-lock.el (font-lock-debug-fontify):
+ * lisp/image.el (image-jpeg-p):
+ * lisp/mail/flow-fill.el (fill-flowed-test):
+ * lisp/mh-e/mh-speed.el (mh-speed-toggle, mh-speed-view):
+ * lisp/progmodes/project.el (project-async-shell-command)
+ (project-shell-command, project-compile):
+ * lisp/progmodes/sh-script.el (sh-assignment):
+ Fix special forms to follow in this order: docstring, declare, interactive.
+
+2021-01-20 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/subr-x.el (named-let): New macro
+
+2021-01-20 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-lapcode): Add 2 new opts
+
+ This introduces two new optimizations. They're designed for code like
+
+ (while
+ (let (...)
+ (if ... (progn blabla t) (progn blabla nil)))
+ ...)
+
+ and they allow the elimination of the test internal to `while` since
+ we can immediately know when we return `t` or `nil` what the result
+ of the test will be.
+
+ `cl-labels` tends to generate this kind of code when it applies the
+ tail-call optimization.
+
+2021-01-20 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-lapcode): Move some opts.
+
+ This moves two optimizations from the final pass to the main loop.
+ Both may enable further optimizations (and the second can be applied
+ repeatedly but "from the end", so the loop in the final pass only gets
+ to apply it once).
+
+2021-01-20 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-lapcode): Re-indent
+
+2021-01-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix footnote-mode problem when reopening an old file
+
+ * lisp/mail/footnote.el (footnote--regenerate-alist): New function
+ (bug#7258).
+ (footnote-mode): Use it to restore footnotes after opening an old
+ file with footnotes.
+
+2021-01-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ cua-toggle-global-mark doc string clarification
+
+ * lisp/emulation/cua-gmrk.el (cua-toggle-global-mark): Clarify
+ that also inserted characters are affected (bug#8083).
+
+2021-01-20 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix environment handling in tramp-handle-make-process
+
+ * lisp/net/tramp.el (tramp-test-message): Add `tramp-suppress-trace' property.
+ (tramp-handle-make-process): Handle also 'tramp-remote-process-environment'.
+
+2021-01-20 Gabriel do Nascimento Ribeiro <gabriel.nascimento@nubank.com.br>
+
+ Respect remember-save-after-remembering on remember-diary-extract-entries
+
+ * lisp/textmodes/remember.el (remember-diary-extract-entries):
+ Save automatically if `remember-save-after-remembering' is non-nil
+ (bug#45811).
+
+2021-01-20 Gabriel do Nascimento Ribeiro <gabriel376@hotmail.com>
+
+ Add option remember-text-format-function
+
+ * lisp/textmodes/remember.el (remember-text-format-function): New
+ variable (bug#45809).
+ (remember-append-to-file): Use it.
+
+2021-01-20 Gabriel do Nascimento Ribeiro <gabriel.nascimento@nubank.com.br>
+
+ Add option remember-diary-regexp
+
+ * lisp/textmodes/remember.el (remember-diary-extract-entries): Use
+ it (bug#45808).
+ (remember-diary-regexp): New variable.
+
+2021-01-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak tty-find-type to allow TERM=screen.xterm
+
+ * lisp/faces.el (tty-find-type): Allow TERM=screen.xterm to find
+ term/screen.el (bug#45824).
+
+2021-01-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make symbol-at-point return nil if there's no symbols in the buffer
+
+ * lisp/thingatpt.el (thing-at-point--beginning-of-symbol): Special
+ op that errors out when there's no symbols in the buffer before
+ point (bug#14234).
+ (symbol): Use it.
+
+2021-01-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add tests for symbol-at-point (bug#14234)
+
+2021-01-20 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Don't let `maybe_quit` prevent resetting `consing_until_gc` (bug#43389)
+
+ * src/alloc.c (garbage_collect): Postpone `unblock_input` a bit.
+ * src/window.c (window_parameter): Avoid `maybe_quit`.
+
+2021-01-20 Fabrice Bauzac <noon@mykolab.com> (tiny change)
+
+ Sort Ibuffer filename/process column as displayed
+
+ * lisp/ibuf-ext.el (ibuffer-do-sort-by-filename/process): Use the
+ same function for sorting and for displaying the
+ filename/process (Bug#45800).
+
+2021-01-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Make `symbol-at-point' work in buffers with no symbols"
+
+ This reverts commit 40a5df81434ce02fba01779256b50976fb74da4f.
+
+ This fails when a point is after a symbol, and there's
+ nothing else in the buffer.
+
+2021-01-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't add Content-Type when ceasing an rmail edit
+
+ * lisp/mail/rmailedit.el (rmail-cease-edit): Take an optional
+ parameter to avoid altering the message (bug#13327).
+ (rmail-abort-edit): Use it.
+
+2021-01-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `symbol-at-point' work in buffers with no symbols
+
+ * lisp/thingatpt.el (thing-at-point--end-of-symbol): New function
+ (bug#14234).
+ (symbol): Use it instead of `forward-symbol', because the latter
+ will move to the end of the buffer even if there is no symbol
+ there. Instead error out like `forward-sexp' and friends.
+
+2021-01-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up example in the Modifying Menus node in the lispref manual
+
+ * doc/lispref/keymaps.texi (Modifying Menus): Make the second
+ example more regular (bug#14257).
+
+2021-01-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention that the mouse will switch on transient-mark-mode in manual
+
+ * doc/lispref/markers.texi (The Mark): Mention that the mouse will
+ enable the `(only)' transient mark mode (bug#14945).
+
+2021-01-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make sh-mode use `auto-mode-interpreter-regexp'
+
+ * lisp/progmodes/sh-script.el (sh-mode): Use
+ `auto-mode-interpreter-regexp' instead of open-coding the value
+ (bug#17158).
+
+2021-01-20 Nick Drozd <nicholasdrozd@gmail.com>
+
+ test/lisp/replace-tests.el: Add nested match group test
+
+ * test/lisp/replace-tests.el (replace-regexp-bug45973): Add test
+ (bug#45973).
+
+2021-01-19 Andrea Corallo <akrl@sdf.org>
+
+ Do not add unnecessary arg constraints (bug#45812 bug#45705 bug#45751).
+
+ These have the effect of bloating the IR for no effect killing compile
+ time. The typical cases for that are extremely long backuoted lists.
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-t): New var.
+ * lisp/emacs-lisp/comp.el (comp-add-call-cstr): No need to add
+ arg call constraints if this is t.
+
+2021-01-19 Philipp Stephani <phst@google.com>
+
+ Make child signal read pipe non-blocking.
+
+ Otherwise Emacs might hang when trying to read the pipe twice in a
+ row. This is consistent with the other file descriptors we pass to
+ 'pselect'.
+
+ * src/process.c (child_signal_init): Make read end of pipe
+ non-blocking.
+
+2021-01-19 Dmitry Gutov <dgutov@yandex.ru>
+
+ Declare some project commands interactive-only
+
+ * lisp/progmodes/project.el (project-async-shell-command)
+ (project-shell-command, project-compile):
+ Declare interactive-only (bug#45765).
+
+2021-01-19 Juri Linkov <juri@linkov.net>
+
+ * lisp/help-fns.el: Move defvar keymap-name-history closer to where it's used.
+
+2021-01-19 Juri Linkov <juri@linkov.net>
+
+ Better check for nil in search-/query-replace-highlight-submatches (bug#45973)
+
+ * lisp/isearch.el (isearch-highlight):
+ * lisp/replace.el (replace-highlight):
+ Use integer-or-marker-p to check matches.
+
+2021-01-19 Ted Zlatanov <tzz@lifelogs.com>
+
+ * test/infra/gitlab-ci.yml: Bootstrap only from web, schedule, or C-related.
+
+2021-01-19 Mattias Engdegård <mattiase@acm.org>
+
+ Calc: use Unicode brackets in Big mode when available (bug#45917)
+
+ * lisp/calc/calccomp.el (math--big-bracket-alist)
+ (math--big-bracket, math--comp-bracket, math--comp-round-bracket):
+ New.
+ (math-compose-expr, math-compose-log, math-compose-log10)
+ (math-compose-choose, math-compose-integ, math-compose-sum)
+ (math-compose-prod): Use big brackets when available.
+
+2021-01-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * etc/NEWS.19: Add entry for `indent-line-to`
+
+ * lisp/version.el (emacs-major-version, emacs-minor-version):
+ Remove redundant version info already displayed by `C-h o`.
+
+2021-01-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Some Tramp fixes, resulting from test campaign
+
+ * doc/misc/tramp.texi (Remote shell setup): Clarifications for
+ `tramp-actions-before-shell' example.
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-insert-directory): Do not expand
+ FILENAME explicitly.
+ (tramp-open-shell): Add "-i" for interactive shells.
+
+ * test/lisp/net/tramp-tests.el (tramp-test07-file-exists-p)
+ (tramp-test14-delete-directory)
+ (tramp-test43-asynchronous-requests): Skip for MS windows.
+
+2021-01-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/startup.el: Fix bug#45857, bug#30994, and bug#45913.
+
+ (command-line): Don't re-evaluate the `custom-delayed-init-variables`
+ a second time after reading the `early-init.el` file.
+ (x-apply-session-resources): Set `blink-cursor-mode` rather than
+ `no-blinking-cursor`.
+
+ * lisp/frame.el (blink-cursor-start): Turn `blink-cursor-mode` off
+ if `blink-cursor-mode` was set to nil.
+ (blink-cursor-mode): Default to it being enabled regardless of
+ `window-system`.
+
+ * lisp/custom.el (custom-initialize-delay): Fox docstring now that
+ autoload.el preserves the `:initialize` info.
+
+2021-01-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Only show "2x entries" i vc log buffers if needed
+
+ * lisp/vc/vc.el (vc-print-log-setup-buttons): Only show the "more"
+ buttons if we got more or equal to the number of entries we asked
+ for (bug#18959).
+
+2021-01-19 Mattias Engdegård <mattiase@acm.org>
+
+ Parse square root sign in embedded Calc mode
+
+ * lisp/calc/calc-lang.el (math-read-big-rec): Recognise √ since it may
+ be used in Big mode.
+
+2021-01-19 Mattias Engdegård <mattiase@acm.org>
+
+ Missing dynamic variable declarations in Calc
+
+ * lisp/calc/calc-embed.el (calc-embedded-set-modes): Prevent
+ the-language and the-display-just from being lexically bound here,
+ because they may be assigned using 'set'.
+
+2021-01-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix slow abbrev expansion in `message-mode' in some circumstances
+
+ * lisp/gnus/message.el (message--syntax-propertize): Use the
+ correct Message mode syntax table to avoid having
+ `message-cite-prefix-regexp' trigger very heavy backtracing when
+ called from an abbrev context (which defines "_" as a word
+ constituent) (bug#45944).
+
+2021-01-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't stop Gnus startup on password failures
+
+ * lisp/gnus/nntp.el (nntp-send-authinfo): Don't signal an
+ `nntp-authinfo-rejected' error, because that will stop Gnus
+ startup (bug#45855). Instead signal an error that will be caught
+ higher up.
+
+2021-01-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Handle also test/lib-src directory
+
+ * test/Makefile.in (SUBDIRS): Add lib-src.
+
+ * test/README: Add predefined selectors.
+
+ * test/file-organization.org: Mention test/lib-src directory.
+
+2021-01-19 Mauro Aranda <maurooaranda@gmail.com>
+
+ Fix list-colors-print handling of callback arg
+
+ * lisp/facemenu.el (list-colors-print): Keeping
+ backward-compatibility, don't fail when passed a closure object as
+ CALLBACK. (Bug#45831)
+
+2021-01-19 Mauro Aranda <maurooaranda@gmail.com>
+
+ Add test for the widget-color-match function (Bug#45829)
+
+ * test/lisp/wid-edit-tests.el (widget-test-color-match): New test.
+
+2021-01-19 Drew Adams <drew.adams@oracle.com>
+
+ Tweaks to the color widget (Bug#45829)
+
+ * lisp/wid-edit.el (widget-color-match, widget-color-validate): New
+ functions.
+ (color): Use the new functions. Base size on longest defined color
+ name, defaulting to the longest RGB hex string.
+
+2021-01-19 Protesilaos Stavrou <info@protesilaos.com>
+
+ Add 'perl-non-scalar-variable' face to perl-mode
+
+ * etc/NEWS: Document the new face (bug#45840).
+ * lisp/progmodes/perl-mode.el (perl-non-scalar-variable): Define new
+ face.
+ (perl-font-lock-keywords-2): Apply 'perl-non-scalar-variable' face.
+
+2021-01-19 James N. V. Cash <james.nvc@gmail.com> (tiny change)
+
+ Define keymap-name-history
+
+ * lisp/help-fns.el (keymap-name-history): Define the history
+ variable (bug#45879). This avoids problems in other completing
+ systems like Helm.
+
+2021-01-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Actually make the calc trail window dedicated
+
+ * lisp/calc/calc.el (calc-trail-display): Actually make the trail
+ window dedicated (bug#45928).
+
+2021-01-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't infloop in comint-redirect-results-list-from-process
+
+ * lisp/comint.el (comint-redirect-results-list-from-process):
+ Ensure forward progress (bug#45950).
+
+2021-01-19 Lucas Werkmeister <mail@lucaswerkmeister.de>
+
+ Mark the various nxml flags as safa
+
+ * lisp/nxml/nxml-mode.el (nxml-char-ref-display-glyph-flag)
+ (nxml-sexp-element-flag, nxml-slash-auto-complete-flag)
+ (nxml-child-indent, nxml-attribute-indent)
+ (nxml-bind-meta-tab-to-complete-flag)
+ (nxml-prefer-utf-16-to-utf-8-flag)
+ (nxml-prefer-utf-16-little-to-big-endian-flag)
+ (nxml-default-buffer-file-coding-system)
+ (nxml-auto-insert-xml-declaration-flag): Add :safe to allow easier
+ cusomization (bug#45969).
+
+2021-01-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "* .gitignore: add src/fingerprint.c"
+
+ This reverts commit 2644353cbc65927a6a0a76d68e00d017771cdd03.
+
+ The src/fingerprint.c file is no longer generated, and the spelling of the obsolete function was correct.
+
+2021-01-19 Dmitry Gutov <dgutov@yandex.ru>
+
+ Make sure the new window is not too tall
+
+ * lisp/progmodes/xref.el (xref-show-definitions-buffer-at-bottom):
+ Make sure the new window is not too tall (bug#45945).
+
+2021-01-18 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ time-stamp-tests now pass in more locales
+
+ Update time-stamp-tests to use format-time-string to generate the date
+ words (month, day of week, AM/PM) instead of hard-coding English. Now
+ the tests pass in locales other than "C" and US English.
+
+ Expand the test coverage of modifier characters.
+
+2021-01-18 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Allow gnus-retrieve-headers to return headers directly
+
+ Previously, all Gnus backends returned header information by writing
+ nov lines into the nntp-server-buffer, which was later parsed. This
+ commit allows the backends to return their header information as a
+ list of already-parsed headers, though so far none of the backends
+ actually do that. The agent, cache, cloud etc. now operate on parsed
+ headers rather than nov text, ie. they use gnus-fetch-headers instead
+ of gnus-retrieve-headers.
+
+ * lisp/gnus/gnus-sum.el (gnus-fetch-headers): Handle the case in which
+ gnus-retrieve-headers returns headers directly.
+ * lisp/gnus/nnvirtual.el (nnvirtual-retrieve-headers): Use
+ gnus-fetch-headers rather than gnus-retrieve-headers to get headers,
+ meaning we're operating on already-parsed headers.
+ (nnvirtual-convert-headers): Remove now-unnecessary function.
+ (nnvirtual-update-xref-header): Rewrite to operate on parsed header.
+ * lisp/gnus/gnus-cloud.el (gnus-cloud-available-chunks): Use
+ gnus-fetch-headers instead of gnus-retrieve-headers.
+ * lisp/gnus/gnus-cache.el (gnus-cache-retrieve-headers): Use
+ gnus-fetch-headers.
+ (gnus-cache-braid-nov, gnus-cache-braid-heads): Delete unnecessary
+ functions -- we now do this work on a list of parsed headers.
+ * lisp/gnus/gnus-agent.el (gnus-agent-retrieve-headers): Use
+ gnus-fetch-headers.
+ (gnus-agent-braid-nov): Remove unnecessary function.
+ (gnus-agent-fetch-headers): Use gnus-fetch-headers.
+
+2021-01-18 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix ibuffer-mark-by-file-name-regexp abbreviations
+
+ * lisp/ibuffer.el (ibuffer--abbreviate-file-name): New function.
+ (filename): Use it.
+ * lisp/ibuf-ext.el (ibuffer-mark-by-file-name-regexp): Prefer
+ read-regexp over read-string for reading regexps. Determine file
+ name using ibuffer-buffer-file-name for consistency. Abbreviate
+ file name using ibuffer-directory-abbrev-alist (bug#18859).
+
+2021-01-18 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Use format-prompt in read-regexp.
+
+ * lisp/replace.el (read-regexp): Use format-prompt (bug#12443).
+
+2021-01-18 Eric Ludlam <ericludlam@gmail.com>
+
+ * lisp/cedet/ede/proj.el: Enable Project files to load
+
+ (ede-proj-target-makefile): Give more precise type for its `rules` slot.
+
+ * lisp/cedet/ede/base.el (ede-target-list): Don't define.
+ (ede-project): Use `list-of` instead.
+
+2021-01-18 Eli Zaretskii <eliz@gnu.org>
+
+ Fix recent changes for Cham script
+
+ * lisp/language/cham.el ("Cham"): Fix sample-text.
+ * lisp/leim/quail/cham.el: Really install this new file.
+
+2021-01-18 Aaron Jensen <aaronjensen@gmail.com>
+
+ * test/src/xdisp-tests.el: Fix tests to work in batch mode
+
+ (xdisp-tests--window-text-pixel-size)
+ (xdisp-tests--window-text-pixel-size-leading-space)
+ (xdisp-tests--window-text-pixel-size-trailing-space): Fix tests.
+ (Bug#45748)
+
+2021-01-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't double up keys in epa--list-keys
+
+ * lisp/epa.el (epa--list-keys): Delete the list keys before
+ redisplaying (bug#44134).
+
+2021-01-18 Stephen Berman <stephen.berman@gmx.net>
+
+ Fix problem with `epa-list-keys' bugging out
+
+ * lisp/epa.el (epa--list-keys): Partially revert 517285f7cae which
+ removed the wrong property (bug#44134).
+
+2021-01-18 Mattias Engdegård <mattiase@acm.org>
+
+ Avoid macOS NSFilenamesPboardType warning (bug#33035)
+
+ * src/nsterm.h (NS_USE_NSPasteboardTypeFileURL): New #define.
+ * src/nsterm.m (ns_term_init):
+ ([EmacsView performDragOperation:]):
+ * src/nsselect.m (ns_string_to_symbol):
+ (nxatoms_of_nsselect):
+ NSFilenamesPboardType was deprecated in macOS 10.14; use
+ NSPasteboardTypeFileURL instead when available.
+
+2021-01-18 Philipp Stephani <phst@google.com>
+
+ Replace Unix commands with Emacs in process tests.
+
+ That way, the tests only depend on Emacs, and not on utilities that
+ might not be available during test time.
+
+ * test/src/process-tests.el (process-tests--eval)
+ (process-tests--emacs-command, process-tests--emacs-binary)
+ (process-tests--dump-file)
+ (process-tests--usable-file-for-reinvoke): New helper functions.
+ (process-tests/sentinel-called)
+ (process-tests/sentinel-with-multiple-processes): Use them.
+
+2021-01-17 Andrea Corallo <akrl@sdf.org>
+
+ Run dead code removal always before fwprop, optim bootstrap time (~20% less)
+
+ * lisp/emacs-lisp/comp.el (comp-passes): Remove `comp-dead-code'.
+ (comp-fwprop): Call `comp-dead-code'.
+ (comp-dead-code): Remove fake arg.
+
+2021-01-17 Andrea Corallo <akrl@sdf.org>
+
+ Introduce `comp-fwprop-max-insns-scan' as heuristic threshold
+
+ * lisp/emacs-lisp/comp.el (comp-fwprop-max-insns-scan): New
+ constant.
+ (comp-fwprop*): Give-up when `comp-fwprop-max-insns-scan' is
+ exceeded.
+
+2021-01-17 Andrea Corallo <akrl@sdf.org>
+
+ Make `comp-enable-subr-trampolines' effective for advices (bug#45854)
+
+ * src/comp.c: Copyright update.
+ (syms_of_comp): Update `comp-enable-subr-trampolines' doc.
+ * lisp/emacs-lisp/comp.el (comp-subr-trampoline-install): Check
+ for `comp-enable-subr-trampolines'.
+
+2021-01-17 Eli Zaretskii <eliz@gnu.org>
+
+ Improve support for the Cham script and languages
+
+ * etc/NEWS: Announce the new 'cham' input method.
+ * etc/HELLO: Fix the order of letters in the Cham greeting.
+ Remove redundant newlines (reported by Ulrich Mueller
+ <ulm@gentoo.org>).
+
+ * lisp/language/cham.el ("Cham"): Add input-method entry.
+ * lisp/leim/quail/cham.el: New file.
+ * lisp/international/fontset.el (setup-default-fontset): Add an
+ entry for Cham.
+
+2021-01-17 Ted Zlatanov <tzz@lifelogs.com>
+
+ * test/infra/gitlab-ci.yml: Merge test-template into job-template.
+
+2021-01-17 Philipp Stephani <phst@google.com>
+
+ Ensure that sentinels are called during 'accept-process-output'.
+
+ When we're trying to notify a process about a status change, we need
+ to ignore the SIGCHLD pipe temporarily, otherwise the code would
+ likely not run into the timeout case that's necessary for a status
+ change to happen.
+
+ * src/process.c (wait_reading_process_output): Ignore the SIGCHLD pipe
+ when notifying a process about a status change.
+ * test/src/process-tests.el (process-tests/sentinel-called)
+ (process-tests/sentinel-with-multiple-processes): New unit tests.
+
+2021-01-17 Michael Albinus <michael.albinus@gmx.de>
+
+ Add new targets to test/Makefile
+
+ * test/Makefile.in (SUBDIRS): New variable.
+ (subdir_template): New template.
+ (top) Create new check-<dirname> targets.
+
+ * test/README: Document them.
+
+ * test/infra/gitlab-ci.yml (test-lisp-net-inotify): Rename.
+
+2021-01-17 Philipp Stephani <phst@google.com>
+
+ Add a bit more clarification around standard error processes.
+
+ * doc/lispref/processes.texi (Asynchronous Processes): Document
+ how to obtain the standard error process that Emacs creates.
+ (Accepting Output): Add an example how to wait for standard error in
+ case Emacs has created a standard error process.
+
+2021-01-16 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Use pcase
+
+2021-01-16 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/pcase.el: Add support for `not` to `pred`
+
+ (pcase--split-pred, pcase--funcall): Adjust for `not`.
+ (pcase--get-macroexpander): New function.
+ (pcase--edebug-match-macro, pcase--make-docstring)
+ (pcase--macroexpand): Use it.
+
+ * lisp/emacs-lisp/radix-tree.el (radix-tree-leaf): Use it!
+
+ * doc/lispref/control.texi (The @code{pcase} macro): Document it.
+
+ * lisp/emacs-lisp/ert.el (ert--explain-equal-rec): Remove redundant test.
+
+2021-01-16 Philipp Stephani <phst@google.com>
+
+ Don't crash if no asynchronous process has been created yet.
+
+ * src/process.c (wait_reading_process_output): Allow
+ child_signal_read_fd < 0.
+
+2021-01-16 Philipp Stephani <phst@google.com>
+
+ Fix deadlock when receiving SIGCHLD during 'pselect'.
+
+ If we receive and handle a SIGCHLD signal for a process while waiting
+ for that process, 'pselect' might never return. Instead, we have to
+ explicitly 'pselect' that the process status has changed. We do this
+ by writing to a pipe in the SIGCHLD handler and having
+ 'wait_reading_process_output' select on it.
+
+ * src/process.c (child_signal_init): New helper function to create a
+ pipe for SIGCHLD notifications.
+ (child_signal_read, child_signal_notify): New helper functions to
+ read from/write to the child signal pipe.
+ (create_process): Initialize the child signal pipe on first use.
+ (handle_child_signal): Notify waiters that a process status has
+ changed.
+ (wait_reading_process_output): Make sure that we also catch
+ SIGCHLD/process status changes.
+
+ * test/src/process-tests.el
+ (process-tests/fd-setsize-no-crash/make-process): Remove workaround,
+ which is no longer needed.
+
+2021-01-16 Eli Zaretskii <eliz@gnu.org>
+
+ Fix Rmail summary for more than 99,999 messages
+
+ * lisp/mail/rmailsum.el (rmail-summary-font-lock-keywords): Don't
+ assume there will be less than 100,000 messages in an mbox file.
+ (Bug#45912)
+
+2021-01-16 Eli Zaretskii <eliz@gnu.org>
+
+ Fix two tests
+
+ * test/lisp/progmodes/elisp-mode-tests.el (xref-elisp-test-run):
+ Make sure file names can be compared as strings, by running them
+ through 'file-truename'. Reported by Vin Shelton
+ <acs@alumni.princeton.edu>.
+ * test/lisp/emacs-lisp/bytecomp-tests.el ("warn-obsolete-hook.el")
+ ("warn-obsolete-variable.el"): Use [^z-a] to match a newline as
+ well. Reported by Vin Shelton <acs@alumni.princeton.edu>.
+
+2021-01-16 Ted Zlatanov <tzz@lifelogs.com>
+
+ test/infra/gitlab-ci.yml: run only for tags and some branches
+
+2021-01-16 Eli Zaretskii <eliz@gnu.org>
+
+ Improve support for Cham script
+
+ * lisp/language/cham.el ("Cham"): Expand the entry.
+
+ * etc/HELLO: Add entry for Cham.
+
+2021-01-16 Ted Zlatanov <tzz@lifelogs.com>
+
+ EMBA container build improvements for Emacs build testing.
+
+ * test/infra/gitlab-ci.yml: Moved from .gitlab-ci.yml. Use the
+ EMBA container registry with a different login token storage file
+ for each commit. Split test stages into prep, build, fast tests,
+ normal tests, platform tests, and slow (everything) and use
+ templates where possible.
+
+ * .gitlab-ci.yml: Include test/infra/gitlab-ci.yml and move all
+ content there.
+
+2021-01-16 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change
+
+ * src/frame.c (Fset_mouse_position, Fset_mouse_pixel_position):
+ Don't compile the FRAME_MSDOS_P case on platforms other than
+ MSDOS, as that will never happen there.
+
+2021-01-16 Jared Finder <jared@finder.org>
+
+ Make mouse-related calls be more consistent on all frame types
+
+ * src/frame.c (Fset_mouse_position, Fset_mouse_pixel_position): Call
+ Fselect_frame and appropriate mouse_moveto function on all non-GUI
+ frame types, independent of #ifdef's.
+ * src/term.c (init_tty): Initialize mouse_face_window for all
+ non-GUI frame types.
+ (term_mouse_moveto) [HAVE_GPM]: Make available even if
+ HAVE_WINDOW_SYSTEM is defined.
+ * src/xdisp.c (try_window_id): Call gui_clear_window_mouse_face
+ in all cases.
+
+2021-01-16 Philip Brown <pdbrown.git@gmail.com> (tiny change)
+
+ * Set `backtrace-line-length' in async worker processes
+
+ Philip Brown <pdbrown.git@gmail.com>
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): Set
+ backtrace-line-length in async worker processes.
+
+2021-01-16 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into native-comp
+
+2021-01-16 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/frame.el Don't activate `blink-cursor-idle-timer` needlessly.
+
+ (blink-cursor-mode): Use `blink-cursor-check` rather than
+ `blink-cursor--start-idle-timer` so we check for the presence of
+ a frame where the cursor can be blinked before activating the idle timer.
+
+2021-01-16 Kévin Le Gouguec <kevin.legouguec@gmail.com>
+
+ Change default-directory before prompting in project-compile
+
+ This causes command completion to work from the project root, letting
+ users complete top-level folders, make targets, etc (bug#45765).
+
+ * lisp/progmodes/project.el (project-compile): Simplify using
+ call-interactively, as done with project(-async)-shell-command.
+
+2021-01-16 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/dispnew.c (sit_for): Return nil when interrupted by process output
+
+ Before adbb4eacc2a984c0fc0b65ec761368fd9067d6c5,
+ `read_and_dispose_of_process_output` called
+ `record_asynch_buffer_change` which added "artificial" input events
+ (in the form of BUFFER_SWITCH_EVENTs), causing sit_for to return
+ Qnil when interrupted by process output. Without those BUFFER_SWITCH_EVENTs,
+ sit_for now tends to return Qt when interrupted by process output
+ making `read_char` believe that we've waited the whole timeout,
+ As consequence incoming process output tended to cause premature
+ auto-saving of files (sometimes right after almost every key press).
+
+ This patch recovers the previous behavior, which is not ideal
+ (incoming process output can delay auto-save indefinitely), but has
+ been good enough for many years.
+
+2021-01-15 Phillip Lord <phillip.lord@russet.org.uk>
+
+ Remove support for 32 bit build
+
+ * admin/nt/dist-build/README-scripts: Update
+ * admin/nt/dist-build/README-windows-binaries: Update
+ * admin/nt/dist-build/build-zips.sh: Remove 32 bit and fix paths
+ * admin/nt/dist-build/build-dep-zips.py: Remove 32 bit and update
+ paths
+ * admin/nt/dist-build/emacs.nsi: Remove 32 bit and fix paths
+
+2021-01-15 Phillip Lord <phillip.lord@russet.org.uk>
+
+ Update dependency capture
+
+ * admin/nt/dist-build/build-dep-zips.py: Use ntldd to directly
+ determine DLL dependencies
+
+2021-01-15 Stephen Leake <stephen_leake@stephe-leake.org>
+
+ * .gitignore: add src/fingerprint.c
+
+ * lisp/dired-x.el (dired-file-name-at-point): Fix spelling in obsolete
+ message.
+
+2021-01-15 Aaron Jensen <aaronjensen@gmail.com>
+
+ Fix 'window-text-pixel-size' when there are leading/trailing spaces
+
+ First, scan to find the first non-whitespace character and then
+ backtrack to find the beginning of the line. The previous
+ algorithm always started on the non-whitespace character during
+ the backtrack, causing it to stop immediately and not actually
+ find the beginning of the line. The same applies to the end of
+ line calculation.
+ * src/xdisp.c: (Fwindow_text_pixel_size): Fix off by one error.
+ (Bug#45748)
+
+ * test/src/xdisp-tests.el (xdisp-tests--window-text-pixel-size)
+ (xdisp-tests--window-text-pixel-size-leading-space)
+ (xdisp-tests--window-text-pixel-size-trailing-space): New tests.
+
+2021-01-15 Jared Finder <jared@finder.org>
+
+ Make libraries works with xterm-mouse-mode.
+
+ Change calls from 'read-event' to 'read-key' in libraries expecting
+ mouse events. Do this only when 'xterm-mouse-mode' is enabled. That
+ way those libraries read decoded mouse events instead of the
+ underlying escape sequence. Add a parameter to 'read-key' that avoids
+ running any of the unbound fallbacks in 'read-key-sequence' so the
+ libraries can read mouse button-down events.
+
+ For backward compatibility purposes, the above logic is contained in a
+ new internal-only function: 'read--potential-mouse-event'.
+
+ * doc/lispref/commands.texi (Reading One Event): Document new
+ parameter to 'read-key'. Mention that non-character events on
+ terminals need 'read-key'.
+ * lisp/subr.el (read-key-full-map): Add new keymap used by 'read-key'.
+ (read-key): Add new parameter 'fallbacks-disabled' to prevent running
+ any of the unbound fallbacks normally run by 'read-key-sequence'.
+ (read--potential-mouse-event): Add new function that calls 'read-key'
+ or 'read-event' depending on if 'xterm-mouse-mode' is set.
+ * lisp/foldout.el (foldout-mouse-swallow-events):
+ * lisp/isearch.el (isearch-pre-command-hook):
+ * lisp/mouse-drag.el (mouse-drag-throw, mouse-drag-drag):
+ * lisp/mouse.el (mouse-drag-secondary):
+ * lisp/ruler-mode.el (ruler-mode-mouse-grab-any-column)
+ (ruler-mode-mouse-drag-any-column-iteration):
+ * lisp/strokes.el (strokes-read-stroke, strokes-read-complex-stroke):
+ * lisp/textmodes/artist.el (artist-mouse-draw-continously)
+ (artist-mouse-draw-poly, artist-mouse-draw-2points):
+ * lisp/vc/ediff-wind.el (ediff-get-window-by-clicking):
+ * lisp/wid-edit.el (widget-button--check-and-call-button)
+ (widget-button-click): Call 'read--potential-mouse-event' instead of
+ 'read-event'.
+ * lisp/wid-edit.el (widget-key-sequence-read-event): Call 'read-key'
+ with 'fallbacks-disabled' set instead of 'read-event'. Unlike above
+ changes, this is unconditionally applied so it works for function
+ keys too. Apply 'local-function-key-map' instead of
+ 'function-key-map' as that contains the full terminal translations.
+ * lisp/vc/ediff.el (ediff-windows): Use 'display-mouse-p' to check if
+ a mouse is available.
+ * src/lread.c (Fread_event): Recommend 'read-key' in docstring for
+ 'read-event' for non-character events.
+
+2021-01-15 Michael Albinus <michael.albinus@gmx.de>
+
+ Some Tramp adaptions, mainly direct async processes
+
+ * doc/misc/tramp.texi (Firewalls, Remote processes)
+ (Frequently Asked Questions): Add @vindex.
+ (Predefined connection information): Precise precondition or direct
+ async processes.
+ (Remote shell setup): Ban ssh RemoteCommand option.
+ (Frequently Asked Questions): Adapt quoting.
+
+ * doc/misc/trampver.texi:
+ * lisp/net/trampver.el: Change version to "2.5.1-pre".
+
+ * lisp/net/tramp-adb.el (tramp-methods) <adb>: Add `tramp-direct-async'
+ parameter.
+ (tramp-adb-handle-make-process): Adapt docstring.
+
+ * lisp/net/tramp-sh.el (tramp-methods) <scp, scpx, rsync, ssh, sshx>:
+ Add `tramp-direct-async' parameter.
+ (tramp-sh-handle-insert-directory): Simplify merkers.
+ (tramp-sh-handle-make-process): Adapt docstring.
+
+ * lisp/net/tramp.el (tramp-methods): Adapt docstring.
+ (tramp-debug-message): Suppress lockfiles.
+ (tramp-test-message): New defun.
+ (tramp-direct-async-process-p): Check also for `tramp-direct-async'.
+ (tramp-handle-make-process): Do not check for `tramp-direct-async-args'.
+
+ * test/lisp/net/tramp-tests.el (all): Replace `string-match' by
+ `string-match-p'.
+ (dired-copy-dereference): Declare.
+ (tramp-test-temporary-file-directory):
+ Remove `tramp-direct-async-args` for mock method.
+ (tramp-test15-copy-directory, tramp-test40-special-characters)
+ (tramp-test40-special-characters-with-stat)
+ (tramp-test40-special-characters-with-perl)
+ (tramp-test40-special-characters-with-ls, tramp-test41-utf8)
+ (tramp-test41-utf8-with-stat, tramp-test41-utf8-with-perl)
+ (tramp-test41-utf8-with-ls): Skip for tramp-rclone.el.
+ (tramp--test--deftest-direct-async-process): Do not skip for mock
+ method.
+ (tramp-test32-shell-command): Adapt test for direct async processes.
+ (tramp-test36-vc-registered, tramp--test-hpux-p, tramp--test-ksh-p):
+ Use `tramp-test-vec'.
+
+2021-01-15 Glenn Morris <rgm@gnu.org>
+
+ * lisp/emacs-lisp/seq.el (seq-concatenate): Unautoload (merge fix).
+
+ gitmerge-skip-regexp does not handle line breaks.
+
+2021-01-15 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'kill-visual-line'
+
+ * lisp/simple.el (kill-whole-line): Mention in the doc string that
+ this option affects 'kill-visual-line' as well.
+ (kill-visual-line): Improve the doc string. Delete the character
+ at which the line was wrapped under 'visual-line-mode'. Don't
+ indiscriminately delete whitespace following the wrap point.
+ (Bug#45837)
+
+2021-01-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/startup.el (command-line): Remove redundant set of no-blinking-cursor
+
+ This is redundant because this was set based on "X" resources under
+ (memq window-system '(x w32 ns)) but the exact same resources and
+ values are tested in `x-apply-session-resources` which is also used for
+ those 3 window systems.
+
+2021-01-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/startup.el (command-line): Remove redundant set of no-blinking-cursor
+
+ This was set when (or noninteractive emacs-basic-display), but
+ the code that sets `emacs-basic-display` also sets `no-blinking-cursor`
+ and `blink-cursor-mode`s value already tests `noninteractive`
+ alongside `no-blinking-cursor`.
+
+2021-01-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Fix marking "delayed-initialization" vars as dynamically scoped
+
+ We used to mark those vars as dynbound in `custom-reevaluate-setting`
+ which forced us to bind `current-load-list` around it to avoid having
+ the vars be associated with the wrong file. Move this marking to
+ `custom-initialize-delay` so we don't need this workaround.
+
+ * lisp/custom.el (custom-initialize-delay): Mark the var as dynamic.
+ (custom-reevaluate-setting): Don't use `defvar` here.
+
+ * lisp/startup.el (command-line): Don't let-bind `current-load-list`
+ around calls to `custom-reevaluate-setting`.
+
+2021-01-14 Andrea Corallo <akrl@sdf.org>
+
+ Normalize `comp-eln-load-path' entries for trampoline comp (bug#43475)
+
+ * lisp/emacs-lisp/comp.el (comp-eln-load-path-eff): New function.
+ (comp-trampoline-search, comp-trampoline-compile)
+ (comp-clean-up-stale-eln): Update to use normalized
+ `comp-eln-load-path-eff'.
+
+2021-01-14 Andrea Corallo <akrl@sdf.org>
+
+ Introduce native compilation time reports
+
+ * lisp/emacs-lisp/comp.el (comp-log-time-report): New special
+ variable.
+ (comp--native-compile): Rework to log time reports.
+
+2021-01-14 Juri Linkov <juri@linkov.net>
+
+ * lisp/info.el (Info-search): Don't deactivate mark when landed in same node
+
+ (bug#45839)
+
+2021-01-14 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 488204cdc6 (origin/emacs-27) Remove one of recently added warnings ab...
+ 55bc1560ac Fix assertion failure in window_box_height (Bug#45737)
+ 27743e9e70 Fix cl-concatenate inlining
+ 32a3758c84 Fix infloop in 'pixel-scroll-mode'
+ 74d18957b8 Fix inhibiting the default.el loading in user init file
+
+2021-01-14 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 149d64bbb2 * doc/misc/tramp.texi (Quick Start Guide): Fix thinko.
+ 97747e6fb9 Tell people how to remove fontconfig customizations
+ 33d0c603c6 ; * doc/lispref/modes.texi (SMIE Indentation Example): Fix...
+ 03080b5545 Remove extraneous closing paren
+
+2021-01-14 Ted Zlatanov <tzz@lifelogs.com>
+
+ EMBA infrastructure improvements for Emacs build testing.
+
+ * .gitlab-ci.yml: Use job templates and rules. Split tests into
+ fast/normal/slow. Make Docker images for each tested platform
+ (inotify, filenotify-gio, gnustep). Increase timeout.
+ * test/Makefile.in (check-lisp, check-net): Add new testing
+ targets.
+ * test/README: Document them.
+ * test/file-organization.org: Mention test/infra.
+ * test/infra/Dockerfile.emba: Add special Docker recipes for EMBA
+ testing.
+
+2021-01-13 Juri Linkov <juri@linkov.net>
+
+ Remove one of recently added warnings abound binding keys in Isearch maps
+
+ * lisp/isearch.el (minibuffer-local-isearch-map): Remove comments
+ which warn against wantonly rebinding unbound keys from
+ irrelevant keymap.
+ https://lists.gnu.org/archive/html/emacs-devel/2021-01/msg00259.html
+
+2021-01-13 Juri Linkov <juri@linkov.net>
+
+ * lisp/isearch.el: C-s C-u M-y reads a string from the kill-ring minibuffer
+
+ * lisp/isearch.el (isearch-yank-from-kill-ring): New command
+ with code moved from isearch-yank-pop.
+ (isearch-yank-pop): Use isearch-yank-from-kill-ring.
+ (isearch-yank-pop-only): Add optional arg, and call
+ isearch-yank-from-kill-ring when the prefix arg is C-u.
+ https://lists.gnu.org/archive/html/emacs-devel/2021-01/msg00089.html
+
+2021-01-13 Stefan Kangas <stefan@marxist.se>
+
+ Lift {global,local}-key-binding to Lisp
+
+ * lisp/subr.el (local-key-binding, global-key-binding): New defuns.
+ * src/keymap.c (Flocal_key_binding, Fglobal_key_binding): Remove DEFUNs.
+ (syms_of_keymap): Remove defsubrs for above DEFUNs.
+ * test/lisp/subr-tests.el (subr-test-local-key-binding)
+ (subr-test-global-key-binding): New tests.
+
+2021-01-13 Stefan Kangas <stefan@marxist.se>
+
+ Prefer skip-unless in more tests
+
+ * test/lisp/emacs-lisp/timer-tests.el (timer-tests-debug-timer-check):
+ * test/src/decompress-tests.el (zlib--decompress):
+ * test/src/xml-tests.el (libxml-tests): Prefer skip-unless.
+
+2021-01-13 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'visual-line-mode' when 'word-wrap-by-category' is in effect
+
+ * src/xdisp.c (move_it_in_display_line_to): Don't reset
+ next_may_wrap after saving a potential wrap point. This fixes the
+ case where several characters in a row can serve as a wrap point.
+ (Bug#45837)
+
+2021-01-13 Stefan Kangas <stefan@marxist.se>
+
+ Use skip-unless instead of if+message in test
+
+ * test/lisp/cedet/semantic-utest.el (semantic-utest-Javascript):
+ Use skip-unless instead of if+message.
+
+2021-01-13 Stefan Kangas <stefan@marxist.se>
+
+ Remove some XEmacs compat code from tests
+
+ * test/lisp/cedet/srecode-utest-getset.el
+ (srecode-utest-getset-output):
+ * test/lisp/cedet/srecode-utest-template.el
+ (srecode-utest-template-output): Remove XEmacs compat code.
+
+2021-01-13 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/calc/calc.el: Remove some XEmacs compat code.
+
+2021-01-13 Mattias Engdegård <mattiase@acm.org>
+
+ Stabilise lunar-phase-list test (bug#45818)
+
+ The test reference data was produced with accidental interference from
+ the system daylight saving in effect at the time. Prevent that
+ from occurring again and correct the data.
+
+ * test/lisp/calendar/lunar-tests.el (with-lunar-test):
+ Switch to UTC and make sure daylight saving adjustment is disabled.
+ Use normal time presentation for maintainability.
+ * test/lisp/calendar/lunar-tests.el (lunar-test-phase): Adjust to UTC.
+ (lunar-test-phase-list): Adjust to UTC with correct times.
+ Enable the test by removing its :unstable mark.
+
+2021-01-12 Mattias Engdegård <mattiase@acm.org>
+
+ Fix Indian time zone test when run by Irishmen (bug#45818)
+
+ * test/lisp/calendar/solar-tests.el (solar-sunrise-sunset):
+ Inhibit any attempt by confused calendar code to apply daylight saving
+ correction when Irish time zone settings are in effect. It's not
+ entirely clear why this is needed but may be related to the fact that
+ 'IST' stands for both Irish and Indian Standard Time, and that Ireland
+ uses reversed daylight saving in winter.
+
+2021-01-12 Omar Polo <op@omarpolo.com>
+
+ * configure.ac: Fix native-comp OpenBSD build.
+
+2021-01-12 Robert Pluim <rpluim@gmail.com>
+
+ Only run IPv6 tests if we have an IPv6 address
+
+ * test/src/process-tests.el (ipv6-is-available): New function for
+ checking whether we have a globally routable IPv6 prefix assigned.
+ (lookup-family-specification): Use 'ipv6-is-available' to check for
+ IPv6. Use 'localhost' instead of 'google.com' to test
+ 'network-lookup-address-info' API.
+ (lookup-google): Use 'ipv6-is-available' to check for
+ IPv6.
+
+ * test/lisp/net/nsm-tests.el (nsm-ipv6-is-available): Rename to
+ 'ipv6-is-available', make identical to the one in
+ test/src/process-tests.el.
+
+2021-01-12 Robert Pluim <rpluim@gmail.com>
+
+ Fix nsm-should-check for "google.com" failure
+
+ * lisp/net/nsm.el (nsm-should-check): Extract the mask from
+ 'network-interface-list' rather than the broadcast
+ address (Bug#45798).
+
+2021-01-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new function 'buffer-line-statistics'
+
+ * src/fns.c (Fbuffer_line_statistics): New function.
+
+2021-01-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new variable `inhibit-interaction'
+
+ * doc/lispref/elisp.texi (Top): Add a link.
+ * doc/lispref/errors.texi (Standard Errors): Mention the new error.
+
+ * doc/lispref/minibuf.texi (Minibuffers): Add a link.
+ (Inhibiting Interaction): New node.
+
+ * src/data.c (syms_of_data): Define the `inhibited-interaction' error.
+
+ * src/lisp.h: Export the barfing function.
+
+ * src/lread.c (Fread_char, Fread_event, Fread_char_exclusive):
+ Barf if inhibited.
+
+ * src/minibuf.c (barf_if_interaction_inhibited): New function.
+ (Fread_from_minibuffer, Fread_no_blanks_input): Barf if inhibited.
+ (syms_of_minibuf): Define the `inhibit-interaction' variable.
+
+2021-01-12 Glenn Morris <rgm@gnu.org>
+
+ Update substitute-command-keys tests, again
+
+ * test/lisp/help-tests.el (help-tests-substitute-command-keys/keymaps)
+ (help-tests-substitute-command-keys/keymap-change):
+ Update following recent minibuffer changes.
+
+2021-01-12 Brian Leung <leungbk@mailfence.com>
+
+ comint-read-input-ring: Simplify last commit
+
+ * lisp/comint.el (comint-read-input-ring): It is not necessary to use
+ `goto-char' again since we have already moved point to the desired
+ location (bug#45797).
+
+2021-01-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/eieio-base.el: Silence warnings in last change
+
+ (eieio-persistent-make-instance): Quote the `eieio-named` class name.
+ (eieio-named): Move before `eieio-persistent`.
+
+2021-01-11 Eric Ludlam <zappo@gnu.org>
+
+ cedet/ede/auto.el:
+
+ (ede-calc-fromconfig): New method. Support functions in addition to
+ string matchers.
+ (ede-dirmatch-installed, ede-do-dirmatch):
+ Use `ede-calc-fromconfig' to do conversion.
+ Author: Eric Ludlam <zappo@gnu.org>
+
+2021-01-11 Eric Ludlam <zappo@gnu.org>
+
+ eieio-base.el:
+
+ (eieio-persistent-make-instance): Save the backward compatible 'name'
+ of objects saved in the file, and if the newly loaded class inherits
+ from 'eieio-named', restore the name of the object.
+ Author: Eric Ludlam <zappo@gnu.org>
+
+2021-01-11 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Fix possible prepending of "TEXT" to IMAP searches
+
+ * lisp/gnus/gnus-search.el (gnus-search-imap-search-keys): Add missing
+ keys "old", "new", "or" and "not".
+ (gnus-search-run-search): In addition, don't touch the query if it
+ starts with a parenthesis. Consider just getting rid of this
+ convenience altogether.
+
+2021-01-11 Stephen Leake <stephen_leake@stephe-leake.org>
+
+ * admin/notes/elpa: Update to match recent Gnu ELPA changes
+
+2021-01-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mark previous erc-services change as not needing documentation
+
+2021-01-11 Brian Leung <leungbk@mailfence.com>
+
+ Make comint-read-input-ring skip uninteresting text in .zsh_history
+
+ * lisp/comint.el (comint-read-input-ring): Simplify (bug#45606).
+ * lisp/shell.el (shell-mode): Add "~/.zsh_history".
+ * lisp/comint.el (comint-read-input-ring): Bind
+ `comint-input-ring-file-prefix' in anticipation of a buffer switch.
+ * lisp/comint.el (comint-read-input-ring): Skip the separator.
+
+ Because re-search-backward moves point to the beginning of the match,
+ and since we don't want the separator appearing in the output, we skip
+ over it.
+
+ This is required to properly detect instances of the value that zsh
+ uses for `comint-input-ring-file-prefix'; if the
+ `comint-input-ring-file-prefix' is ':potato', the subsequent
+ invocation `looking-at' sees '\n:potato' for all entries after the one
+ at the very beginning of the history file.
+
+2021-01-11 Anticrisis <anticrisisg@gmail.com> (tiny change)
+
+ Add a failing test for bug#44834
+
+ * test/lisp/progmodes/tcl-tests.el (tcl-mode-namespace-indent-2):
+ New, failing test (bug#44834).
+ (tcl-mode-function-name-2):
+ (tcl-mode-function-name-3): Fix names of the tests so that they're
+ actually run.
+
+2021-01-11 Leon Vack <dev@lgcl.de>
+
+ Support using auth-source for NickServ passwords in ERC
+
+ * lisp/erc/erc-services.el (erc-nickserv-passwords): Document that
+ the passwords are only used when erc-prompt-for-nickserv-password
+ is nil.
+ (erc-use-auth-source-for-nickserv-password): New customizable
+ variable to enable checking auth-source for NickServ passwords.
+ (etc-nickserv-get-password): New function to handle the lookup
+ of the NickServ password from both auth-source and the
+ erc-nickserv-passwords variable.
+ (erc-nickserv-call-identify-function): Use new
+ erc-nickserv-get-password function to lookup NickServ passwords.
+ (erc-nickserv-identify-autodetect)
+ (erc-nickserv-identify-on-connect)
+ (erc-nickserv-identify-on-nick-change): Call
+ erc-nickserv-call-identify-function when
+ erc-use-auth-source-for-nickserv-password is set.
+ * etc/NEWS: Document change (bug#45340).
+
+2021-01-11 Alexandre Duret-Lutz <adl@lrde.epita.fr> (tiny change)
+
+ Fix problem with non-ASCII characters in nnmaildir
+
+ * lisp/gnus/nnmaildir.el (nnmaildir-request-article): Enable
+ multipart 8bit-content-transfer-encoded files to be displayed
+ correctly by reading as `raw-text' instead of having Emacs
+ (incorrectly) decode the files (bug#44307).
+
+2021-01-11 Pedro Andres Aranda Gutierrez <paaguti@gmail.com>
+
+ Add `flat-button' to custom-face-attributes
+
+ * lisp/cus-face.el (custom-face-attributes): Add `flat-button'
+ (bug#45769).
+
+2021-01-11 Robert Pluim <rpluim@gmail.com>
+
+ * configure.ac: Alphabetize emacs_config_features
+
+2021-01-11 Robert Pluim <rpluim@gmail.com>
+
+ Ensure HAVE_GMP is reflected in emacs_config_features
+
+ * configure.ac: Move HAVE_GMP setting before emacs_config_features
+ setting (Bug#45771).
+
+2021-01-10 Dmitry Gutov <dgutov@yandex.ru>
+
+ New command xref-quit-and-pop-marker-stack
+
+ * lisp/progmodes/xref.el (xref-quit-and-pop-marker-stack):
+ New command.
+ (xref--xref-buffer-mode-map): Binding for it.
+
+2021-01-10 Phillip Lord <phillip.lord@russet.org.uk>
+
+ Allow evaluation of tests from local source repository
+
+ * etc/w32-feature.el (w32-feature-load-tests): Add new command
+
+2021-01-10 Philipp Stephani <phst@google.com>
+
+ Fix build breakage if Lisp_Object is not a primitive type.
+
+ * src/minibuf.c (choose_minibuf_frame): Don't compare Lisp_Objects
+ with '!='. Use 'EQ' instead.
+
+2021-01-10 Philipp Stephani <phst@google.com>
+
+ Add functions to open a file without quitting.
+
+ In some situations, e.g. when the Lisp machinery isn't available, we
+ can't quit. Don't check the quit flags in such situations, in case
+ they contain garbage.
+
+ * src/sysdep.c (emacs_open_noquit, emacs_openat_noquit): New variants
+ of 'emacs_open' and 'emacs_openat' that don't check the quit flags.
+
+ * src/emacs.c (main, Fdaemon_initialized):
+ * src/pdumper.c (pdumper_load):
+ * src/w32term.c (w32_initialize):
+ * src/buffer.c (mmap_init):
+ * src/callproc.c (emacs_spawn): Use them where we can't quit.
+
+2021-01-10 Alan Mackenzie <acm@muc.de>
+
+ Fix incompleteness in the implementation of minibuffer-follows-selected-frame
+
+ In particular, add a new value to the variable, and fix several bugs apparent
+ with the implementation up till now.
+
+ * doc/emacs/mini.texi (Basic Minibuffer): Add a description of the new
+ non-nil, non-t value of minibuffer-follows-selected-frame.
+
+ * doc/emacs/trouble.texi (Quitting): Add a description of how C-g handles
+ recursive minibuffers when typed in one which isn't the most nested.
+
+ * doc/lispref/minibuf.texi (Intro to Minibuffers): Add an @dfn for "active
+ minibuffer".
+ (Minibuffer Commands): Document that exit-minibuffer throws an error when not
+ invoked from the innermost Minibuffer.
+ (Recursive Mini): Amend the description of the visibility of outer level
+ minibuffers.
+ (Minibuffer Misc): In the description of the minibuffer hooks, replace "the
+ minibuffer" with "a minibuffer".
+
+ * etc/NEWS (Entry announcing minibuffer-follows-selected-frame): Add a
+ description of the new non-nil, non-t value.
+
+ * lisp/cus-start.el (top level): make the customize entry for
+ minibuffer-follows-selected-frame a choice between three entries.
+
+ * lisp/minibuffer.el (exit-minibuffer): throw an error when we're not in the
+ most nested minibuffer.
+ (top level): Bind C-g to abort-minibuffers in minibuffer-local-map.
+
+ * lisp/window.el (window-deletable-p): return the symbol `frame' when (amongst
+ other things) minibuffer-follows-selected-frame is t.
+
+ * src/eval.c (internal_catch): Add a mechanism to (throw 'exit t) repeatedly
+ when the throw currently being processed doesn't terminate the current
+ minibuffer.
+
+ * src/lisp.h (this_minibuffer_depth): New extern declaration
+ (minibuf_level): extern declaration moved here from window.h.
+
+ * src/minibuf.c (minibuffer_follows_frame, minibuf_stays_put)
+ (minibuf_moves_frame_when_opened): New and amended functions to query the
+ value of minibuffer-follows-selected-frame.
+ (choose_minibuf_frame): check (minibuf > 1) in place of (minibufer > 0) at a
+ particular place. At another place, check that an alleged frame is so and is
+ live. Before selecting a non-miniwindow on a different frame, ensure it
+ really is a different frame.
+ (move_minibuffer_onto_frame): Stack up all recursive minibuffers on the target
+ frame. Check the minibuf_window isn't in the old frame before setting that
+ frame's miniwindow to an inactive minibuffer.
+ (Finnermost_minibuffer_p, Fabort_minibuffers): New primitives.
+ (this_minibuffer_depth): New function.
+ (read_minibuf): Record the calling frame in a variable, and switch back to it
+ after the recursive edit has terminated normally, using
+ select-frame-set-input-focus. Stack up all the recursive minibuffers on the
+ miniwindow where a new minibuffer is being opened. After the recursive edit,
+ switch the selected window away from the expired minibuffer's window.
+ (nth_minibuffer): New function.
+ (minibuffer-follows-selected-frame): Change from a DEFVAR_BOOL to a
+ DEFVAR_LISP.
+
+ * src/window.c (decode_next_window_args): Set *minibuf to w's mini-window's
+ content when that content is a minibuffer.
+
+ * src/window.h (minibuf_level) Declaration moved from here to lisp.h.
+
+2021-01-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Respect message-forward-ignored-headers more
+
+ * lisp/gnus/message.el (message-forward-ignored-headers): Clarify
+ doc string once again.
+ (message-forward-make-body-mime): Remove headers when not
+ encrypted (bug#45631).
+ (message-forward-make-body): Pass in correct values.
+
+2021-01-10 Glenn Morris <rgm@gnu.org>
+
+ Default python-shell-interpreter to python3
+
+ * lisp/progmodes/python.el (python-shell-interpreter): Default to
+ python3 (bug#45655).
+
+2021-01-10 David Edmondson <dme@dme.org>
+
+ Fix example in the Gnus manual
+
+ * doc/misc/gnus.texi (Score Variables): In the example showing how to
+ use a list of functions for gnus-score-find-score-files-find-function,
+ return a list of strings from the lambda rather than trying to call
+ the string as a function (bug#45673).
+
+2021-01-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Specify precedence in .authinfo files
+
+ * doc/misc/auth.texi (Help for users): Mention placing more
+ specific entries first (bug#45711).
+
+2021-01-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve fill-region-as-paragraph when there's a fill prefix
+
+ * lisp/textmodes/fill.el (fill-region-as-paragraph): Try to
+ improve how line breaks are set on unbreakable text with a fill
+ prefix area that has spaces within (bug#45720).
+
+2021-01-10 k3tu0isui <k3tu0isui@gmail.com> (tiny change)
+
+ Make font locking work in mercury-mode
+
+ * lisp/progmodes/prolog.el (prolog-font-lock-keywords): Work in
+ all modes derived from prolog-mode (bug#45747).
+ (mercury-mode): Set up variables based on the Prolog system (bug#45747).
+
+2021-01-10 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Hyperlink symbol names without word syntax in Help
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-el-font-lock-keywords-2)
+ (lisp-cl-font-lock-keywords-2): Allow single-character symbol names.
+ * lisp/help-mode.el (help-xref-symbol-regexp): Also match symbol
+ names starting with symbol syntax (bug#6601, bug#24309).
+ * test/lisp/help-mode-tests.el (help-mode-tests-xref-button): Test
+ hyperlink creation for function names without symbol syntax.
+
+2021-01-10 Omar Polo <op@omarpolo.com>
+
+ Add support for 'process-attributes' on OpenBSD
+
+ * src/sysdep.c (make_lisp_timeval):
+ (system_process_attributes): Implement for OpenBSD (bug#45729).
+
+2021-01-10 Pedro Andres Aranda Gutierrez <paaguti@gmail.com> (tiny change)
+
+ Add support for flat buttons
+
+ * src/xfaces.c (Finternal_set_lisp_face_attribute):
+ (realize_gui_face): Add support for `flat-button' (bug#45735).
+
+2021-01-10 Daniel Martín <mardani29@yahoo.es>
+
+ Minor shortdoc link improvements
+
+ * lisp/emacs-lisp/shortdoc.el (shortdoc--display-function): Use
+ describe-function as a fallback link when a function is not documented
+ in any Info manual. Also make the link respond to mouse-1, like the
+ rest of *Help* links, and add a proper help-echo property.
+ * lisp/help-fns.el (help-fns--mention-shortdoc-groups): Same link
+ improvement as described before, this time for the shortdoc groups
+ (bug#45750).
+
+2021-01-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a link to the manual from the defcustom doc string
+
+ * lisp/custom.el (defcustom): Add a link to the manual for the
+ :type element.
+
+2021-01-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert recent mm-with-part change
+
+ * lisp/gnus/mm-decode.el (mm-with-part): Revert
+ 23a887e426f81033b0de2f4c93a8525cb31c28da -- this is the wrong
+ place to handle this peculiarity.
+
+2021-01-10 Michael Albinus <michael.albinus@gmx.de>
+
+ Rework parts of Tramp's insert-directory, bug#45691
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-insert-directory): Fix some
+ unibyte/multibyte inconsistencies. (Bug#45691)
+
+ * test/lisp/net/tramp-tests.el (tramp-test17-insert-directory-one-file):
+ New test.
+
+2021-01-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add more mm-decode tests
+
+2021-01-10 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/subr.el (global-map): Doc fix; add cross-reference.
+
+2021-01-10 F. Jason Park <jp@neverwas.me>
+
+ Create new test file for socks.el
+
+ * test/lisp/net/socks-tests.el (socks-tests-auth-filter-url-http): Add
+ SOCKS5 authentication test and fake server (bug#45162).
+
+2021-01-10 Martin Rudalics <rudalics@gmx.at>
+
+ Fix assertion failure in window_box_height (Bug#45737)
+
+ * lisp/window.el (window-sizable): Don't try to grow a mini window
+ when the root window's minimum height is already larger than its
+ actual height (Bug#45737).
+
+2021-01-10 Philipp Stephani <phst@google.com>
+
+ Increase probability that a process test succeeds.
+
+ * test/src/process-tests.el
+ (process-tests/fd-setsize-no-crash/make-process): Work around
+ potential Emacs bug.
+
+2021-01-10 Philipp Stephani <phst@google.com>
+
+ Remove a pointless check for WCOREDUMPED.
+
+ WCOREDUMPED can only be used if the process was killed.
+
+ * src/process.c (status_convert): Don't check WCOREDUMPED if
+ WIFEXITED.
+
+2021-01-10 Tassilo Horn <tsdh@gnu.org>
+
+ Support keyval style beamer frame labels
+
+ * lisp/textmodes/reftex-vars.el (reftex-label-regexps): Support keyval
+ style beamer frame labels.
+
+2021-01-10 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Remove reference to gnus-bug-create-help-buffer
+
+ * lisp/gnus/gnus-win.el (gnus-buffer-configuration): Variable no
+ longer exists.
+
+2021-01-09 Philipp Stephani <phst@google.com>
+
+ Don't unblock SIGCHLD too early.
+
+ We first need to register the received process ID so that
+ 'handle_child_signal' checks it. Otherwise we might never call
+ 'waitpid' for these processes, risking deadlock.
+
+ * src/callproc.c (call_process):
+ * src/process.c (create_process): Don't unblock SIGCHLD before
+ registering the process ID to wait for.
+
+ * src/callproc.c (emacs_spawn): Accept a signal set from the caller.
+
+2021-01-09 João Távora <joaotavora@gmail.com>
+
+ Count Flymake diagnostics in modeline by severity, not type
+
+ Originally reported in https://github.com/joaotavora/eglot/issues/588
+ by Pankaj Jangid.
+
+ * lisp/progmodes/flymake.el (flymake--mode-line-counter): Count
+ diagnostics by severity level, not by type.
+ (Version): Bump to 1.1.1
+
+2021-01-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-macs.el (cl--self-tco): Fix build of gnus-agent.el
+
+ Don't burp on "naked" variable let bindings.
+
+2021-01-09 Andrea Corallo <akrl@sdf.org>
+
+ Improve `comp-libgccjit-reproducer'
+
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Better libgccjit
+ reproducer file name.
+ * lisp/emacs-lisp/comp.el (comp-libgccjit-reproducer): Doc update.
+ (comp-final, comp-run-async-workers): Pass
+ `comp-libgccjit-reproducer' setting to child workers.
+
+2021-01-09 Eli Zaretskii <eliz@gnu.org>
+
+ Fix cl-concatenate use in macros
+
+ * lisp/emacs-lisp/cl-macs.el (inline): Remove cl-concatenate.
+ (Bug#45610)
+
+2021-01-09 Eli Zaretskii <eliz@gnu.org>
+
+ Fix cl-concatenate inlining
+
+ * lisp/emacs-lisp/seq.el (seq-concatenate): Auto-load it. Do not
+ merge to master. (Bug#45610)
+
+2021-01-09 Andrea Corallo <akrl@sdf.org>
+
+ Add new customize `comp-libgccjit-reproducer'
+
+ * lisp/emacs-lisp/comp.el (comp-libgccjit-reproducer): New customize.
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Use
+ `comp-libgccjit-reproducer' for dumping repoducer.
+ (syms_of_comp): Define 'Qcomp_libgccjit_reproducer'.
+
+2021-01-09 Tak Kunihiro <tkk@misasa.okayama-u.ac.jp>
+
+ Fix infloop in 'pixel-scroll-mode'
+
+ * lisp/pixel-scroll.el (pixel-scroll-up, pixel-scroll-down): Avoid
+ inflooping when 'vertical-motion' doesn't move. (Bug#45628)
+
+2021-01-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-macs.el: Optimize self-calls in tail position
+
+ Implement a limited form of tail-call optimization for the special
+ case of recursive functions defined with `cl-labels`. Only self-recursion
+ is optimized, no attempt is made to handle more complex cases such a mutual
+ recursion.
+
+ The main benefit is to reduce the use of the stack, tho in my limited
+ tests, this can also improve performance (about half of the way to
+ a hand-written `while` loop).
+
+ (cl--self-tco): New function.
+ (cl-labels): Use it.
+
+ * lisp/subr.el (letrec): Optimize single-binding corner case.
+
+ * test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs--labels): Add tests
+ to check that TCO is working.
+
+2021-01-09 Dmitry Gutov <dgutov@yandex.ru>
+
+ Make sure default-directory relates to the originating buffer
+
+ * lisp/progmodes/xref.el (xref--show-xref-buffer):
+ Pick up default-directory value from the caller
+ (https://lists.gnu.org/archive/html/emacs-devel/2021-01/msg00551.html).
+ (xref-show-definitions-buffer-at-bottom): Same.
+
+2021-01-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/subr.el (letrec): Optimize some non-recursive bindings
+
+ * lisp/emacs-lisp/macroexp.el (macroexp--fgrep): Look inside bytecode
+ objects as well.
+
+ * test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs--labels):
+ * test/lisp/subr-tests.el (subr--tests-letrec): New tests.
+
+2021-01-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-generic.el (cl--generic-lambda): Fix last change
+
+2021-01-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/macroexp.el (macroexp--fgrep): Rename from `pcase--fgrep`
+
+ * lisp/emacs-lisp/cl-generic.el (cl--generic-fgrep): Delete.
+ (cl--generic-lambda): Use `macroexp--pacse` instead.
+
+ * lisp/emacs-lisp/pcase.el (pcase--fgrep): Rename to `macroexp--fgrep`.
+
+2021-01-08 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2021-01-08 Stefan Kangas <stefan@marxist.se>
+
+ Merge recently added kbd tests
+
+ * test/lisp/subr-tests.el (subr--kbd): Merge test...
+ (subr-test-kbd): ...with this one. Fix thinko in my previous commit.
+ Thanks to Mattias Engdegård <mattiase@acm.org>.
+
+2021-01-08 Stefan Kangas <stefan@marxist.se>
+
+ Lift define-prefix-command to Lisp
+
+ * lisp/subr.el (define-prefix-command): New defun.
+ * src/keymap.c (Fdefine_prefix_command): Remove DEFUN.
+ (syms_of_keymap): Remove defsubr for Fdefine_prefix_command.
+ * test/lisp/subr-tests.el (subr-test-define-prefix-command): New
+ test.
+
+2021-01-08 Stefan Kangas <stefan@marxist.se>
+
+ * test/lisp/subr-tests.el (subr-test-kbd): New test.
+
+2021-01-08 Stefan Kangas <stefan@marxist.se>
+
+ Remove unused DEFSYM
+
+ * src/minibuf.c (syms_of_minibuf) <Qhistory_length>: Remove unused
+ DEFSYM.
+
+2021-01-08 Eli Zaretskii <eliz@gnu.org>
+
+ Fix syntax of space characters
+
+ * lisp/international/characters.el (tbl): Give all the space
+ characters whose Unicode General Category is Zs the 'space'
+ syntax. (Bug#45660)
+
+2021-01-08 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/lisp/net/tramp-tests.el (tramp-test31-interrupt-process):
+
+ Tag it :unstable on hydra.
+
+2021-01-08 Eli Zaretskii <eliz@gnu.org>
+
+ Fix inhibiting the default.el loading in user init file
+
+ * lisp/startup.el (startup--load-user-init-file): Test the value
+ of 'inhibit-default-init', not just the LOAD-DEFAULTS argument,
+ because loading the user's init file could have set the value of
+ the former.
+ (command-line): Call 'startup--load-user-init-file' with last arg
+ t: there's no longer any need to test the value of
+ 'inhibit-default-init' here, as it will be tested by the called
+ function. (Bug#45708)
+
+2021-01-07 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-known-type-specifiers): Fix typo.
+
+2021-01-07 Andrea Corallo <akrl@sdf.org>
+
+ Add a type specifier test
+
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Add testcase.
+
+2021-01-07 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el: Improve tab-bar-show (bug#45556)
+
+ * lisp/tab-bar.el (tab-bar-show): Change :set lambda to update all frames.
+ Improve docstring.
+
+2021-01-07 Juri Linkov <juri@linkov.net>
+
+ * lisp/mb-depth.el (minibuffer-depth-indicator): Add :group 'minibuffer'.
+
+2021-01-07 Stefan Kangas <stefan@marxist.se>
+
+ Remove an outdated comment
+
+ * lisp/subr.el: Remove comment to reflect recent change in the
+ definition of global-map, esc-map and ctl-x-map.
+
+2021-01-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further display-buffer doc changes
+
+ * lisp/window.el (display-buffer): `display-buffer-alist' is
+ apparently the variable the user should be directed towards.
+
+2021-01-07 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/lisp/filenotify-tests.el (file-notify-test07-many-events-remote):
+
+ Mark it as unstable also on emba.
+
+2021-01-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a display-buffer window selection function that's more like XEmacs
+
+ * doc/lispref/windows.texi (Buffer Display Action Functions):
+ Document it.
+ * lisp/window.el (display-buffer--action-function-custom-type): Add.
+ (display-buffer): Mention it.
+ (display-buffer-use-least-recent-window): New function (bug#45688).
+
+ * src/window.c (Fwindow_bump_use_time): New function.
+
+2021-01-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix typo in last display-buffer doc string change
+
+ * lisp/window.el (display-buffer): Fix typo in last doc string change.
+
+2021-01-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Edit the display-buffer doc string slightly
+
+ * lisp/window.el (display-buffer): Reword the start of the doc
+ string (bug#45688).
+
+2021-01-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add work-around for nnmaildir encoding problem
+
+ * lisp/gnus/mm-decode.el (mm-with-part): Fix problem with
+ multipart 8bit encoded posts from nnmaildir (bug#44307).
+
+2021-01-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add tests for mm-decode.el
+
+2021-01-07 F. Jason Park <jp@neverwas.me>
+
+ Clear socks protocol scratch after authentication
+
+ * lisp/net/socks.el (socks-open-connection): Fix incomplete patch
+ titled "Append incremental message segments in socks-filter," which
+ addressed chunk ordering but neglected to zero out the work area
+ following successful username/password authentication (bug#45162).
+
+2021-01-07 Andreas Schwab <schwab@linux-m68k.org>
+
+ Fix quoting problem in pop3-uidl-save
+
+ * lisp/net/pop3.el (pop3-uidl-save): Quote strings properly
+ (bug#43896).
+
+2021-01-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert mark-paragraph change and add tests
+
+ * lisp/textmodes/paragraphs.el (mark-paragraph): Revert
+ eb090f65ceb0ae8a90829e911694348583135ba5 (bug#45318). This restores
+ the behaviour from Emacs 27 -- further work is needed on this patch.
+
+2021-01-07 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/Makefile.in (WRITE_LOG): Mark also problematic tests for emba.
+
+2021-01-07 Glenn Morris <rgm@gnu.org>
+
+ Update a substitute-command-keys test
+
+ * test/lisp/help-tests.el (help-tests-substitute-command-keys/keymaps):
+ Update for "Pretty-print keys without <> around modifiers" change.
+
+2021-01-06 Daniel Martín <mardani29@yahoo.es>
+
+ Fix some failing tests in BSD systems
+
+ * test/lisp/progmodes/xref-tests.el
+ (xref--xref-file-name-display-is-abs)
+ (xref--xref-file-name-display-is-relative-to-project-root):
+ Accommodate some older versions of BSD find
+ (https://lists.gnu.org/archive/html/emacs-devel/2021-01/msg00156.html).
+
+2021-01-06 Dmitry Gutov <dgutov@yandex.ru>
+
+ Proof some searches and file listings against symlinks
+
+ * lisp/progmodes/project.el (project--files-in-directory):
+ Make sure the directory includes the trailing slash in case it's
+ a symlink, discussed in
+ https://lists.gnu.org/archive/html/emacs-devel/2021-01/msg00345.html.
+
+ * lisp/progmodes/xref.el (xref-matches-in-directory): Same.
+
+ * lisp/cedet/semantic/symref/grep.el (semantic-symref-perform-search):
+ Same.
+
+2021-01-06 Gabriel do Nascimento Ribeiro <gabriel376@hotmail.com> (tiny change)
+
+ * lisp/mb-depth.el (minibuffer-depth-indicator): New face.
+
+ (minibuffer-depth-setup): Use new face and add a single space between
+ the depth indicator and the minibuffer prompt.
+ https://lists.gnu.org/archive/html/emacs-devel/2020-12/msg00230.html
+
+2021-01-06 Andrea Corallo <akrl@sdf.org>
+
+ Fix bug#45603
+
+ Reported and reduced by Mauricio Collares.
+
+ * lisp/emacs-lisp/comp.el (comp-final): Fix coding system for the
+ tmp file used to pass data the child processes.
+ * test/src/comp-tests.el (45603-1): New testcase
+ * test/src/comp-resources/comp-test-45603.el: New File.
+
+2021-01-06 Michael Heerdegen <michael_heerdegen@web.de>
+
+ Fix obsolete variable warnings about class names
+
+ * lisp/emacs-lisp/eieio-core.el (eieio-defclass-autoload): Try to make
+ the wording of the warning about the obsoleted variable less confusing.
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-check-variable): Don't
+ warn for lexical variables (Bug#39169). Fix spurious `or'.
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (bytecomp/warn-obsolete-variable-bound\.el): New test.
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-obsolete-variable-bound.el:
+ New file.
+
+2021-01-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/play/dunnet.el: Run the game when loaded via `--batch -l dunnet`
+
+ (dun--batch): Rename from `dun-batch` and don't autoload.
+ (dunnet): Delegate to `dun--batch` when in batch mode.
+
+2021-01-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/package.el (package-activate-all): Another tweak
+
+ `package-quickstart.el` files presume `package-activated-list`
+ is a bound variable, so make sure this is the case even when `package.el` is
+ not yet loaded.
+
+2021-01-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/autoload.el: Improve last change
+
+ It turns out there were other places that used `custom-initialize-delay`
+ on autoloaded variables and used various hacks to make it work with
+ `autoload.el`. The new code makes those hacks unneeded.
+ Also, there's no point trying to "optimize" those rare cases anyway,
+ so I simplified the `autoload.el` code for those cases.
+
+ (make-autoload): For non-trivial cases,
+ just include the whole `defcustom` instead of trying to mimic it.
+
+ * lisp/mail/rmail.el (rmail-spool-directory): Remove hacks.
+ * lisp/info.el (Info-default-directory-list): Remove `progn` hack.
+
+ * lisp/custom.el (custom-declare-variable)
+ (custom-handle-all-keywords): Don't use pseudo-group `nil`.
+
+2021-01-05 Alan Third <alan@idiocy.org>
+
+ Prevent stack overflow in GNUstep menu code
+
+ * src/nsmenu.m (ns_update_menubar): Always do a deep update for
+ GNUstep.
+ ([EmacsMenu menuNeedsUpdate:]): Don't update the menu as it should
+ always have had a deep update.
+
+2021-01-05 Juri Linkov <juri@linkov.net>
+
+ * lisp/subr.el (remove-hook): Add default value (bug#45393)
+
+2021-01-05 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (tab-bar-tab-name-format-function): New defcustom.
+
+ (tab-bar-tab-name-format-default): New function as the default value.
+ (tab-bar-make-keymap-1): Funcall tab-bar-tab-name-format-function.
+
+2021-01-05 Juri Linkov <juri@linkov.net>
+
+ * lisp/tab-bar.el (toggle-frame-tab-bar): New command (bug#45556)
+
+2021-01-05 James N. V. Cash <james.nvc@gmail.com> (tiny change)
+
+ Refactor tab-bar-mode to -define-keys and -load-buttons (bug#42052)
+
+ * lisp/tab-bar.el (tab-bar--define-keys, tab-bar--load-buttons):
+ Move some code here from 'tab-bar-mode'.
+ (tab-bar-new-tab-to): Call tab-bar--load-buttons and tab-bar--define-keys.
+
+2021-01-05 Eli Zaretskii <eliz@gnu.org>
+
+ Fix process-tests on MS-Windows
+
+ It was again broken by recent changes.
+ * test/src/process-tests.el
+ (process-tests/fd-setsize-no-crash/make-serial-process): Skip test
+ on MS-Windows.
+
+2021-01-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/package.el: Load package-quickstart without package.el
+
+ Speed up startup when `package-quickstart` is in use by making it possible
+ to load the quickstart file without having to load `package.el` at all.
+
+ (package-user-dir, package-directory-list, package-quickstart-file):
+ Preload those variables.
+ (package--get-activatable-pkg): New fun, extracted from `package-activate`.
+ (package-activate): Use it.
+ (package--activate-all): New function, extracted from
+ `package-activate-all`.
+ (package-activate-all): Use it and make the function preloaded.
+ (package--archives-initialize): New function.
+ (package-install): Use it.
+ (list-packages): Avoid `switch-to-buffer`.
+ (package-get-descriptor): New function.
+
+ * lisp/startup.el (command-line): Simplify the code now that
+ package-user-dir and package-directory-list are preloaded.
+
+ * lisp/emacs-lisp/autoload.el (make-autoload): Add support for
+ `:initialize #'custom-initialize-delay` in `defcustom`.
+
+2021-01-05 Michael Albinus <michael.albinus@gmx.de>
+
+ * doc/misc/tramp.texi (Quick Start Guide): Fix thinko.
+
+2021-01-05 Robert Pluim <rpluim@gmail.com>
+
+ Tell people how to remove fontconfig customizations
+
+2021-01-05 Mattias Engdegård <mattiase@acm.org>
+
+ ruby-mode: eliminate redundant regexp branch
+
+ * lisp/progmodes/ruby-mode.el (ruby-add-log-current-method):
+ Since ruby-operator-re matches dot, don't include both in regexp.
+ This pacifies relint.
+
+2021-01-05 Mattias Engdegård <mattiase@acm.org>
+
+ Pretty-print keys without <> around modifiers (bug#45536)
+
+ Be consistent when pretty-printing keys: put modifiers outside <>,
+ thus the more logical C-M-<return> instead of <C-M-return>.
+
+ * src/keymap.c (Fsingle_key_description):
+ Skip modifier prefix before adding <>.
+ * doc/lispref/help.texi (Describing Characters): Update example.
+ * doc/lispref/debugging.texi (Backtraces):
+ * doc/lispref/minibuf.texi (Text from Minibuffer):
+ Use @kbd instead of @key.
+ * etc/NEWS: Announce the change.
+ * test/src/keymap-tests.el (keymap--key-description):
+ * test/lisp/subr-tests.el (subr--kbd): New tests.
+
+2021-01-05 Mattias Engdegård <mattiase@acm.org>
+
+ * lisp/filesets.el (filesets-external-viewers): Tighten regexp.
+
+2021-01-05 Harald Jörg <haj@posteo.de>
+
+ perl-mode: Display here-docs as strings instead of comments
+
+ * lisp/progmodes/perl-mode.el
+ (perl-syntax-propertize-function): Handle HERE doc starter
+ lines ending in a comment.
+ (perl-heredoc): New face for HERE docs, inheriting from
+ font-lock-string-face.
+ (perl-font-lock-syntactic-face-function): Apply the new face
+ to HERE docs (Bug#23461).
+
+ * test/lisp/progmodes/cperl-mode-tests.el
+ (cperl-test--run-bug-10483): Skip for Perl mode. The test
+ explicitly calls a function of CPerl mode.
+
+2021-01-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/subr.el (esc-map): Initialize inside declaration
+
+ * src/commands.h (meta_map):
+ * src/keymap.c (meta_map): Delete variable.
+ (syms_of_keymap): Don't initialize esc-map here.
+ (initial_define_key):
+ * src/keymap.h (initial_define_key): Delete function.
+
+ * src/keyboard.c (keys_of_keyboard): Don't initialize esc-map here.
+
+ * src/window.h (keys_of_window):
+ * src/window.c (keys_of_window): Delete function.
+ * src/lisp.h (keys_of_casefiddle):
+ * src/casefiddle.c (keys_of_casefiddle): Delete function.
+ * src/emacs.c (main): Don't call them.
+
+2021-01-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/subr.el (ctl-x-map): Initialize inside the declaration.
+
+ * src/command.h (control_x_map):
+ * src/keymap.c (control_x_map): Delete variable.
+ (syms_of_keymap):
+ * src/keyboard.c (keys_of_keyboard):
+ * src/casefiddle.c (keys_of_casefiddle):
+ * src/window.c (keys_of_window): Move initialization of ctl-x-map to
+ subr.el.
+
+ * src/lisp.h (syms_of_buffer):
+ * src/buffer.c (keys_of_buffer): Delete function.
+ * src/emacs.c (main): Don't call it.
+
+2021-01-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/subr.el (global-map): Initialize inside declaration.
+
+ * src/commands.h (global_map):
+ * src/keymap.c (global_map): Delete variable.
+ (syms_of_keymap): Don't initialize global_map here.
+ (keys_of_keymap): Delete function.
+ * src/lisp.h (keys_of_cmds):
+ * src/cmds.c (keys_of_cmds): Delete function.
+ * src/emacs.c (main): Don't call them.
+
+ * src/window.c (keys_of_window): Don't initialize global_map here.
+ * src/keyboard.c (keys_of_keyboard): Don't initialize global_map here.
+
+2021-01-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Use lexical-binding in the remaining preloaded files
+
+ * lisp/widget.el:
+ * lisp/w32-fns.el:
+ * lisp/textmodes/fill.el:
+ * lisp/term/common-win.el:
+ * lisp/scroll-bar.el:
+ * lisp/rfn-eshadow.el:
+ * lisp/menu-bar.el:
+ * lisp/language/tibetan.el:
+ * lisp/language/thai.el:
+ * lisp/language/misc-lang.el:
+ * lisp/language/lao.el:
+ * lisp/language/korean.el:
+ * lisp/language/japanese.el:
+ * lisp/language/indian.el:
+ * lisp/language/hebrew.el:
+ * lisp/language/european.el:
+ * lisp/language/ethiopic.el:
+ * lisp/language/english.el:
+ * lisp/language/cyrillic.el:
+ * lisp/language/chinese.el:
+ * lisp/jka-cmpr-hook.el:
+ * lisp/international/ucs-normalize.el:
+ * lisp/international/mule.el:
+ * lisp/international/mule-conf.el:
+ * lisp/international/iso-transl.el:
+ * lisp/international/fontset.el:
+ * lisp/international/characters.el:
+ * lisp/format.el:
+ * lisp/facemenu.el:
+ * lisp/electric.el:
+ * lisp/dos-w32.el:
+ * lisp/dos-fns.el:
+ * lisp/disp-table.el:
+ * lisp/cus-face.el:
+ * lisp/composite.el:
+ * lisp/bindings.el:
+ * admin/unidata/blocks.awk:
+ * admin/charsets/eucjp-ms.awk:
+ * admin/charsets/cp51932.awk: Use `lexical-binding`.
+
+2021-01-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/filesets.el: Use lexical-binding
+
+ Remove redundant `:group` args. Require cl-lib and seq.
+ Fix various O(n²) bug and flag a few remaining ones.
+
+ (filesets-external-viewers): Simplify regexps. Use \' instead of $.
+ Remove useless :constraint-flag properties.
+ (filesets-convert-path-list): η-reduce.
+ (filesets-eviewer-constraint-p): Mark :constraint-flag as obsolete.
+ (filesets-spawn-external-viewer): Can't use `run-hooks` on
+ lexical variable.
+ (filesets-filter-list): Fix O(n²) bug.
+ (filesets-ormap): Simplify.
+ (filesets-some, filesets-member, filesets-sublist): Make them
+ obsolete aliases.
+ (filesets-reset-fileset): Simplify.
+ (filesets-directory-files): Use `push`.
+ (filesets-spawn-external-viewer): Use `mapconcat` to fix O(n²) bug.
+ (filesets-cmd-get-args): Use `mapcan` to fix O(n²) bug.
+ (filesets-run-cmd): Use `mapconcat` and `mapcan` to fix O(n²) bugs.
+ (filesets-ingroup-collect-finder): Use dynamic scoping.
+ (filesets-ingroup-collect-files): Use `nreverse` to fix O(n²) bug.
+ (filesets-ingroup-collect-build-menu): Use `mapcan` to fix O(n²) bug.
+
+2021-01-04 Andrea Corallo <akrl@sdf.org>
+
+ * test/src/comp-tests.el (cond-rw-1, not-cons, 45576): Rename three tests.
+
+2021-01-04 Andrea Corallo <akrl@sdf.org>
+
+ Fix a type specifier test
+
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Fix a testcase.
+
+2021-01-04 Andrea Corallo <akrl@sdf.org>
+
+ Fix type inference for bug#45635
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-union-1-no-mem): Fix
+ missing mixed pos neg handling.
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Add a test.
+ * test/src/comp-tests.el (45635): New testcase.
+ * test/src/comp-test-funcs.el (comp-test-45635-f): New function.
+
+2021-01-04 Philipp Stephani <phst@google.com>
+
+ Make a process tests a bit more robust.
+
+ * test/src/process-tests.el
+ (process-tests/fd-setsize-no-crash/make-process): Allow for processes
+ to fail before 'exec'.
+
+2021-01-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/cedet/srecode/semantic.el: Use lexical-binding
+
+ (srecode-semantic-insert-tag): Can't use `run-hook-with-args` on
+ lexical variable.
+
+2021-01-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/mail/reporter.el: Use lexical-binding
+
+ (reporter--run-functions): New function.
+ (reporter-dump-state): Use it and simplify the code.
+
+2021-01-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/erc/erc.el (erc-process-input-line): Undo confused last change
+
+2021-01-04 Dmitry Gutov <dgutov@yandex.ru>
+
+ ruby-add-log-current-method: Support methods with symbolic names
+
+ * lisp/progmodes/ruby-mode.el (ruby-add-log-current-method):
+ Support methods with symbolic names.
+
+2021-01-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Do not assume Xrender merely because Cairo
+
+ Problem reported by Andrea Corallo in:
+ https://lists.gnu.org/r/emacs-devel/2021-01/msg00225.html
+ * src/xterm.c (x_term_init) [USE_CAIRO && !HAVE_XRENDER]:
+ Do not call XRenderQueryExtension.
+
+2021-01-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix broken build on AIX 7.2
+
+ Without this fix, the build on AIX 7.2 with xlc fails in the ‘CCLD
+ temacs’ step with the diagnostic ‘ld: 0711-317 ERROR: Undefined
+ symbol: BC’. This is because -lcurses does not define BC etc.
+ * configure.ac: When building terminfo.o, define
+ TERMINFO_DEFINES_BC if the library defines BC etc.
+ * src/terminfo.c (UP, BC, PC): Define depending on
+ TERMINFO_DEFINES_BC, not on TERMINFO.
+
+ (cherry picked from commit 632917461a7c1893a83979a3873b51d4da3b8a42)
+
+2021-01-04 Simen Heggestøyl <simenheg@gmail.com>
+
+ Remove extraneous closing paren
+
+ * doc/lispref/modes.texi (SMIE Indentation Example): Remove extraneous
+ closing paren.
+
+2021-01-04 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 99cc0045eb (origin/emacs-27) Update two user option names in the Widg...
+
+2021-01-04 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 2e09efdb68 Revert previous patch which was installed into wrong branch.
+
+2021-01-04 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ a7c2793efe Fix last change
+
+2021-01-04 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 90c782e92e Merge branch 'emacs-27' of git.savannah.gnu.org:/srv/git/e...
+
+2021-01-04 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 7384ec6416 Add warning comments abound binding keys in Isearch maps
+
+2021-01-04 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix error in tramp-sh-handle-insert-directory
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-insert-directory): Let buffer be
+ unibyte when applying numbers returned with the ls --dired option.
+ Reported by Justus Piater <Justus-dev@Piater.name>.
+
+ * test/lisp/net/tramp-tests.el (tramp--test-check-files): Extend test.
+
+2021-01-04 Mauro Aranda <maurooaranda@gmail.com>
+
+ Update two user option names in the Widget manual
+
+ * doc/misc/widget.texi (Basic Types): The user options
+ widget-glyph-directory and widget-glyph-enable were renamed long ago
+ to widget-image-directory and widget-image-enable, but the manual
+ kept calling them by their old names. Update the names.
+
+2021-01-04 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix build for --enable-checking=structs
+
+ The last change to lisp.h only added comments in Lisp_String, so the
+ portable dumper need not be changed.
+
+ * src/pdumper.c (dump_string): Update hash for Lisp_String.
+
+2021-01-04 Mauro Aranda <maurooaranda@gmail.com>
+
+ Don't skip widgets when moving backward
+
+ * lisp/wid-edit.el (widget-move): Remove code that caused
+ widget-backward to skip an immediate previous widget when moving
+ backward from the start of a widget. (Bug#45623)
+
+ * test/lisp/wid-edit-tests.el (widget-test-widget-backward): New test.
+
+2021-01-04 Amin Bandali <bandali@gnu.org>
+
+ Fix off-by-one error in mode-line-compact code
+
+ * src/xdisp.c (display_mode_line): Fix off-by-one error that would
+ chop off the final non-space character when compacting (bug#45646).
+
+2021-01-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix computation of Lines in nnmaildir
+
+ * lisp/gnus/nnmaildir.el (nnmaildir--update-nov): Lines is -1 if
+ it's not present; not 0 (probably) (bug#45650).
+
+2021-01-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/print.c (print_vectorlike): Use `HASH_TABLE_SIZE`
+
+2021-01-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/xdisp.c (syms_of_xdisp): New var redisplay-skip-fontification-on-input
+
+ (handle_fontified_prop): Use it.
+
+ * src/keyboard.h (input_was_pending): Declare.
+ * src/keyboard.c (input_was_pending): Make non-static.
+
+2021-01-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/erc/erc.el: Use `run-hook-with-args` for `erc-pre-send-functions`
+
+ (erc-process-input-line): A function can be `listp`.
+ (erc-send-input): Use `run-hook-with-args` for `erc-pre-send-functions`.
+ (erc-display-command): Comment out, unused.
+
+2021-01-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/calc/calc-yank.el (calc-edit-mode): Make it into a proper major mode
+
+ Also make `calc-edit-handler` hold a function instead of an expression.
+
+ (calc-original-buffer, calc-return-buffer, calc-one-window)
+ (calc-edit-handler, calc-restore-trail, calc-allow-ret)
+ (calc-edit-top): Give them a default value.
+ (calc--edit-mode): New function extracted from old `calc-edit-mode`.
+ (calc-edit-return, calc-edit-finish): Don't need to test `boundp` any more.
+ (calc-edit-finish): Allow `calc-edit-handler` to be a function.
+
+ (calc-edit, calc-alg-edit):
+
+ * lisp/calc/calc-prog.el (calc-edit-user-syntax, calc-user-define-edit):
+ * lisp/calc/calc-embed.el (calc-embedded-edit):
+ * lisp/calc/calc-sel.el (calc-edit-selection):
+ * lisp/calc/calc-store.el (calc-edit-variable):
+ Use `calc--edit-mode` and make first arg into a function.
+
+ * lisp/calc/calc-ext.el (calc-init-extensions): Autoload `calc--edit-mode`
+ instead of `calc-edit-mode`.
+
+2021-01-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * Makefile.in (test/%): New target
+
+ * lisp/calendar/appt.el (appt-activate): Set the local `write-file-functions`
+
+2021-01-04 Mark Oteiza <mvoteiza@udel.edu>
+
+ Fix last change in json.el
+
+ * lisp/json.el (json-encode-array): Include optimization for lists.
+
+2021-01-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/arc-mode.el (tar-grind-file-mode): Remove left over autoload
+
+ * doc/lispref/syntax.texi (Syntax Class Table): Clarify `@`
+
+2021-01-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * admin/last-chance.el (last-chance): Use `grep`s return value
+
+ (compilation-finish-functions): Only set it buffer-locally.
+
+2021-01-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/buffer.c (Fset_buffer_multibyte): Remove dead code
+
+2021-01-03 Mark Oteiza <mvoteiza@udel.edu>
+
+ Remove unnecessary dependency on seq library
+
+ * lisp/json.el: Remove require declaration.
+ (json-encode-array): Just use length and /=.
+
+2021-01-03 Phillip Lord <phillip.lord@russet.org.uk>
+
+ Remove relative paths for consistency
+
+ * admin/nt/dist-build/build-zips.sh: Remove Paths
+
+2021-01-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/byte-run.el (make-obsolete): Make `when` mandatory
+
+ (define-obsolete-function-alias, make-obsolete-variable)
+ (define-obsolete-variable-alias): Adjust similarly.
+
+2021-01-03 Paul Eggert <eggert@cs.ucla.edu>
+
+ Mention -lcurses problem on AIX
+
+ * etc/PROBLEMS: Describe problem with Emacs 27 and -lcurses.
+ Do not merge to master.
+
+2021-01-03 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix broken build on AIX 7.2
+
+ Without this fix, the build on AIX 7.2 with xlc fails in the ‘CCLD
+ temacs’ step with the diagnostic ‘ld: 0711-317 ERROR: Undefined
+ symbol: BC’. This is because -lcurses does not define BC etc.
+ * configure.ac: When building terminfo.o, define
+ TERMINFO_DEFINES_BC if the library defines BC etc.
+ * src/terminfo.c (UP, BC, PC): Define depending on
+ TERMINFO_DEFINES_BC, not on TERMINFO.
+
+2021-01-03 Paul Eggert <eggert@cs.ucla.edu>
+
+ Revert previous patch which was installed into wrong branch.
+
+2021-01-03 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix broken build on AIX 7.2
+
+ Without this fix, the build on AIX 7.2 with xlc fails in the ‘CCLD
+ temacs’ step with the diagnostic ‘ld: 0711-317 ERROR: Undefined
+ symbol: BC’. This is because -lcurses does not define BC etc.
+ * configure.ac: When building terminfo.o, define
+ TERMINFO_DEFINES_BC if the library defines BC etc.
+ * src/terminfo.c (UP, BC, PC): Define depending on
+ TERMINFO_DEFINES_BC, not on TERMINFO.
+
+2021-01-03 Alan Third <alan@idiocy.org>
+
+ Fix child frame restacking on NS (bug#41422)
+
+ * src/nsfns.m (Fns_frame_restack): Use new restackWindow method.
+ * src/nsterm.m ([EmacsWindow orderFront:]):
+ ([EmacsWindow makeKeyAndOrderFront:]):
+ (nswindow_orderedIndex_sort):
+ ([EmacsWindow orderBack:]):
+ ([EmacsWindow restackWindow:above:]): Override superclass methods to
+ handle child windows the way we want.
+
+2021-01-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/xref.el (xref--show-defs-buffer-at-bottom): Fix missing arg
+
+2021-01-02 Alan Third <alan@idiocy.org>
+
+ Fix crash when using menus and tramp on NS
+
+
+ * src/nsterm.m (ns_select): Don't drain outerpool in this function.
+
+2021-01-02 Alan Third <alan@idiocy.org>
+
+ Fix NS toolbar image release crash (bug#43973)
+
+ The toolbar fails to make a proper copy of EmacsImage objects, so
+ releasing the copy incorrectly released instance variables from the
+ original objects.
+
+ * src/nsimage.m ([EmacsImage copyWithZone:]): New function to enable
+ correct copying of EmacsImage.
+
+2021-01-02 Roland Winkler <winkler@gnu.org>
+
+ bibtex-mode: Extend widget bibtex-entry-alist
+
+2021-01-02 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Reposition call to set-buffer-modified-p in sieve-upload
+
+ * lisp/net/sieve.el (sieve-upload): It's meant to affect the script
+ buffer, not sieve-buffer, so needs to be outside the call to
+ with-current-buffer.
+
+2021-01-02 Dmitry Gutov <dgutov@yandex.ru>
+
+ xref--show-pos-in-buf: Don't set other-window-scroll-buffer
+
+ * lisp/progmodes/xref.el (xref--show-pos-in-buf):
+ Don't set other-window-scroll-buffer (bug#45581).
+
+2021-01-02 Mattias Engdegård <mattiase@acm.org>
+
+ Fix backslash mistakes in doc strings in C code
+
+ These were found by an instrumented version of make-docfile.
+
+ * src/gnutls.c (Fgnutls_available_p):
+ * src/keymap.c (Fkey_description):
+ * src/xdisp.c (syms_of_xdisp):
+
+2021-01-02 Mauro Aranda <maurooaranda@gmail.com>
+
+ Fix Quit button in dictionary buffer
+
+ * lisp/net/dictionary.el (dictionay-close): Changing the arity of the
+ function in cc5f2803785c5dc785f09a292313cf799e8d29bb was a mistake.
+ Restore it, but mark the argument as unused to avoid a
+ wrong-number-of-arguments error when using the Quit button.
+
+2021-01-02 Philipp Stephani <phst@google.com>
+
+ Avoid printing stacktraces when it probably wouldn't work anyway.
+
+ * src/eval.c (signal_or_quit): Don't try to call the debugger if it's
+ inhibited or we are about to dump or bootstrap. In those cases the
+ debugger probably wouldn't work anyway.
+
+2021-01-02 Philipp Stephani <phst@google.com>
+
+ Make a process test faster.
+
+ The test 'process-tests/fd-setsize-no-crash/make-process' used to call
+ 'sleep' to ensure that enough processes are live to trigger a
+ FD_SETSIZE overflow. However, we can just call 'cat' instead and
+ close standard input when done. That way, we only wait as long as
+ needed.
+
+ * test/src/process-tests.el
+ (process-tests/fd-setsize-no-crash/make-process): Invoke 'cat' instead
+ of 'sleep'. Close standard input to exit the 'cat' processes.
+
+2021-01-02 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-known-predicates): Some more tweaking.
+
+2021-01-02 Philipp Stephani <phst@google.com>
+
+ Simplify TTY allocation.
+
+ The 'process-tty-name' already provides the TTY name, we don't have
+ interrogate the TTY host.
+
+ * test/src/process-tests.el
+ (process-tests/fd-setsize-no-crash/make-serial-process): Use
+ 'process-tty-name' instead of having the TTY host print its TTY
+ name. Check whether TTY names are unique.
+ (process-tests--new-pty, process-tests--with-temp-file): Remove;
+ no longer used.
+
+2021-01-02 Andrea Corallo <akrl@sdf.org>
+
+ Fix `functionp' constraining (bug#45576)
+
+ * lisp/emacs-lisp/comp.el (comp-known-predicates)
+ (comp-known-predicates-h): New constants.
+ (comp-known-predicate-p, comp-pred-to-cstr): New functions.
+ * lisp/emacs-lisp/cl-macs.el (cl-deftype-satisfies): Don't define.
+ * test/src/comp-tests.el (comp-test-45576): New testcase.
+ * test/src/comp-test-funcs.el (comp-test-45576-f): New function.
+
+2021-01-02 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change in characters.el
+
+ * lisp/international/characters.el: Adjust syntax of more
+ characters to follow that of Unicode properties. (Bug#44974)
+
+2021-01-02 Andrea Corallo <akrl@sdf.org>
+
+ Rename `dom' slot into `idom' in `comp-block' struct
+
+ * lisp/emacs-lisp/comp.el (comp-block): Rename dom `slot' into
+ `idom'.
+ (comp-clean-ssa, comp-compute-dominator-tree)
+ (comp-compute-dominator-frontiers, comp-dom-tree-walker)
+ (comp-remove-unreachable-blocks): Update accordingly.
+
+2021-01-02 Eli Zaretskii <eliz@gnu.org>
+
+ Fix syntax of symbol and punctuation characters
+
+ * lisp/international/characters.el: Adjust syntax of punctuation
+ and symbol charcaters to follow that of Unicode properties.
+ (Bug#44974)
+
+2021-01-02 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2021-01-02 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change
+
+ * doc/lispref/strings.texi (Creating Strings): Improve wording of
+ last change. (Bug#45516)
+
+2021-01-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a reference between the Strings node and Search/Replace
+
+ * doc/lispref/strings.texi (Creating Strings): Mention
+ string-replace/replace-regexp-in-string (bug#45516).
+
+ (cherry picked from commit b9359d4183a1a6923122d3aa12b922ab89693354)
+
+2021-01-02 Dmitry Gutov <dgutov@yandex.ru>
+
+ ruby-smie-rules: Avoid one case of infinite recursion
+
+ * lisp/progmodes/ruby-mode.el (ruby-smie-rules):
+ Avoid one case of infinite recursion (bug#29107).
+
+2021-01-01 Alan Third <alan@idiocy.org>
+
+ Fix GNUstep warnings
+
+ * src/nsterm.h: EmacsSurface is only required if NS_DRAW_TO_BUFFER is
+ defined.
+ * src/nsterm.m (ns_judge_scroll_bars): Remove unused variable.
+ * src/nsmenu.m (update_frame_tool_bar):
+ (ns_update_menubar): Remove unused variables.
+
+2021-01-01 Alan Third <alan@idiocy.org>
+
+ Improve drawing performance on macOS
+
+ * configure.ac: Require IOSurface framework.
+ * src/nsterm.h: New EmacsSurface class and update EmacsView
+ definitions.
+ * src/nsterm.m (ns_update_end):
+ (ns_unfocus): Use new unfocusDrawingBuffer method.
+ (ns_draw_window_cursor): Move ns_focus to before we set colors.
+ ([EmacsView dealloc]):
+ ([EmacsView viewDidResize:]): Handle new EmacsSurface class.
+ ([EmacsView initFrameFromEmacs:]): Remove reference to old method.
+ ([EmacsView createDrawingBuffer]): Remove method.
+ ([EmacsView focusOnDrawingBuffer]):
+ ([EmacsView windowDidChangeBackingProperties:]): Use new EmacsSurface
+ class.
+ ([EmacsView unfocusDrawingBuffer]): New method.
+ ([EmacsView copyRect:to:]): Get information from the context instead
+ of direct from the IOSurface.
+ ([EmacsView updateLayer]): Use new EmacsSurface class.
+ ([EmacsView copyRect:to:]): Use memcpy to copy bits around instead of
+ using NS image functions.
+ ([EmacsSurface initWithSize:ColorSpace:]):
+ ([EmacsSurface dealloc]):
+ ([EmacsSurface getSize]):
+ ([EmacsSurface getContext]):
+ ([EmacsSurface releaseContext]):
+ ([EmacsSurface getSurface]):
+ ([EmacsSurface copyContentsTo:]): New class and methods.
+
+2021-01-01 Roland Winkler <winkler@gnu.org>
+
+ bibtex-mode: Handle biblatex field aliases (bug#44976)
+
+ * lisp/textmodes/bibtex.el (bibtex-biblatex-entry-alist): Define
+ field aliases.
+ (bibtex-vec-incr): Remove.
+ (bibtex-format-entry, bibtex-validate): Check for field aliases.
+ (bibtex--skip-field-aliases): New function.
+ (bibtex-field-list): Use it.
+
+2021-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix CCL_MOD typo
+
+ * src/ccl.c (ccl_driver): Fix typo that disabled the
+ checks for undefined behavior with integer remainder.
+ Problem caught by Oracle Studio 12.6.
+
+2021-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Add overflow check for INPUT_EVENT_POS_MIN
+
+ * src/keyboard.c (INPUT_EVENT_POS_MIN): Don’t assume (-1 -
+ INPUT_EVENT_POS_MAX) fits into ptrdiff_t. This fixes a
+ purely-theoretical problem that cannot occur on two’s-complement
+ arithmetic. The Solaris 10 compiler still complains incorrectly,
+ but oh well.
+
+2021-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port to Solaris 10
+
+ * configure.ac: Instead of AC_CHECK_HEADER, use AC_COMPILE_IFELSE
+ with X11/Intrinsic.h when checking for X11/extensions/Xrender.h.
+ This suppresses a bogus "report a bug to bug-gnu-emacs" diagnostic
+ from 'configure' in Solaris 10.
+ (SETUP_SLAVE_PTY): Adjust to recent renaming of forkin to
+ std_in in callproc.c. Needed on Solaris and Unixware.
+ * lib-src/Makefile.in (LIB_GETRANDOM, LIBS_ETAGS): New vars,
+ needed because on Solaris 10 the Gnulib tempname module now needs
+ the -lrt library for clock_gettime. Throw in the LIB_GETRANDOM
+ stuff too while we’re at it; from getrandom.m4 it seems to be
+ needed for MingW.
+ (LIBS_MOVE, etags_libs): Use them.
+ * src/callproc.c [SETUP_SLAVE_PTY]: Include sys/stream.h
+ and sys/stropts.h, for SETUP_SLAVE_PTY’s definiens.
+ * src/process.c [NEED_BSDTTY]: Don’t include bsdtty.h; hasn’t been
+ needed in years.
+ [USG5_4]: Don’t include sys/stream.h or sys/stropts.h; these
+ directives havbe been moved to callproc.c because the only use of
+ SETUP_SLAVE_PTY is there now.
+
+2021-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ New file scratch_buffer_dupfree.c
+
+ * lib/malloc/scratch_buffer_dupfree.c: New file, from Gnulib
+ (originally from glibc 2.33 code).
+ This is needed on macOS and some other platforms;
+ I forgot to commit it in the most recent Gnulib update.
+
+2021-01-01 Andrea Corallo <akrl@sdf.org>
+
+ Add `throw' to non returning functions
+
+ * lisp/emacs-lisp/comp.el (comp-known-type-specifiers): Add throw.
+
+2021-01-01 Dmitry Gutov <dgutov@yandex.ru>
+
+ xref-show-definitions-completing-read: Default to the first location
+
+ * lisp/progmodes/xref.el (xref-show-definitions-completing-read):
+ Default to the first location.
+
+2021-01-01 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-compute-dominator-tree): Fix.
+
+2021-01-01 Andrea Corallo <akrl@sdf.org>
+
+ Clean unreachable block using dominance tree to handle circularities
+
+ With this commit unreachable basic blocks are pruned automatically by
+ comp-ssa relying on dominance analysis. This solves the issue of
+ unreachable cluster of basic blocks referencing each other.
+
+ * lisp/emacs-lisp/comp.el (comp-block-lap): New `no-ret' slot.
+ (comp-compute-dominator-tree): Update.
+ (comp-remove-unreachable-blocks): New functions.
+ (comp-ssa): Update to call `comp-remove-unreachable-blocks'.
+ (comp-clean-orphan-blocks): Delete.
+ (comp-rewrite-non-locals): Update and simplify.
+
+2021-01-01 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Fix hash table iteration.
+
+2021-01-01 Andrea Corallo <akrl@sdf.org>
+
+ Introduce 'unreachable' LIMPLE operator
+
+ Introduce 'unreachable' as LIMPLE operator so we can handle correctly
+ in the CFG functions throwing values or signaling errors.
+
+ * src/comp.c (retrive_block): Better error diagnostic.
+ (emit_limple_insn): Add `unreachable'.
+ (compile_function): Fix block iteration.
+ (syms_of_comp): Define 'Qunreachable'.
+ * lisp/emacs-lisp/comp.el (comp-block): New variable.
+ (comp-block-lap): Add `non-ret-insn' slot.
+ (comp-branch-op-p): New predicate.
+ (comp-limple-lock-keywords): Color `unreachable' as red.
+ (comp-compute-edges): Add `unreachable'.
+ (comp-fwprop-call): Store non returning function call.
+ (comp-fwprop*): Update.
+ (comp-clean-orphan-blocks, comp-rewrite-non-locals): New functions.
+ (comp-fwprop): Call `comp-rewrite-non-locals'.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add two
+ tests.
+ * test/src/comp-test-funcs.el (comp-test-non-local-1)
+ (comp-test-non-local-2, comp-test-non-local-3)
+ (comp-test-non-local-4): New functions.
+
+2021-01-01 Eli Zaretskii <eliz@gnu.org>
+
+ Add warning comments abound binding keys in Isearch maps
+
+ * lisp/isearch.el (isearch-mode-map)
+ (minibuffer-local-isearch-map): Add comments which warn against
+ wantonly rebinding unbound keys.
+
+2021-01-01 Philipp Stephani <phst@google.com>
+
+ Fix a compilation warning.
+
+ ruby-mode uses 'cl-evenp' at runtime, so cl-lib must be available at
+ runtime as well.
+
+ * lisp/progmodes/ruby-mode.el (cl-lib): Require at runtime as well.
+
+2021-01-01 Andrea Corallo <akrl@sdf.org>
+
+ Fix two predicates for missing negation handling
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-empty-p)
+ (comp-cstr-null-p): Fix missing negation handling.
+
+2021-01-01 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-limple-lock-keywords): Color returns as red.
+
+2021-01-01 Andrea Corallo <akrl@sdf.org>
+
+ Add `comp-insert-insn'
+
+ * lisp/emacs-lisp/comp.el (comp-insert-insn): New inline.
+ (comp-emit-call-cstr): Split logic and call `comp-insert-insn'.
+
+2021-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Remove stray copy of image-tests.el
+
+ * test/manual/image-circular-tests.el: Remove a stray copy of
+ image-tests.el that was appended to this file. Found by its
+ duplicate copyright notice.
+
+2021-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib by running admin/merge-gnulib.
+
+2021-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Merge from origin/emacs-27
+
+ 33d159c36f Fix copyright years by hand
+
+2021-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Merge from origin/emacs-27
+
+ 74a77ef299 Improve documentation of 'network-lookup-address-info'
+ c6d5555646 Display messages sent using ERC's /say
+ c156723769 Fix Rmail summary display when From: header is malformed
+
+2021-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update copyright year to 2021
+
+ Run "TZ=UTC0 admin/update-copyright".
+
+2021-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix some mistaken shell delinting
+
+ * admin/merge-gnulib, admin/update-copyright, make-dist:
+ Revert recent mistaken changes that were put in merely to
+ pacify a shellcheck linter.
+
+2021-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix copyright years by hand
+
+ These are dates that admin/update-copyright did not update.
+
+2021-01-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert recent add-to-ordered-list changes
+
+ * doc/lispref/lists.texi (List Variables): Revert.
+
+ * lisp/subr.el (add-to-ordered-list): Revert recent changes
+ because the semantics are too muddled.
+
+2020-12-31 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: increment version numbers to 5.35 due to standalone release
+
+ * doc/misc/cc-mode.texi. Increment the mode to 5.35, twice.
+
+ * lisp/progmodes/cc-defs.el. Increment the mode to "5.35.1".
+
+2020-12-31 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'network-lookup-address-info'
+
+ * src/process.c (Fnetwork_lookup_address_info):
+ * doc/lispref/processes.texi (Misc Network): Document the error
+ message emitted by 'network-lookup-address-info' when it fails.
+
+2020-12-31 Dmitry Gutov <dgutov@yandex.ru>
+
+ ruby-mode: Optimize expression expansion too
+
+ This speeds up syntax-propertize almost 2x.
+
+ * lisp/progmodes/ruby-mode.el (ruby-syntax-propertize):
+ Optimize expression expansion too.
+ (ruby-syntax-propertize-expansion, ruby-font-lock-keywords)
+ (ruby-expression-expansion-re): Update to match.
+
+2020-12-31 Dmitry Gutov <dgutov@yandex.ru>
+
+ ruby-syntax-propertize: Optimize two rules a little
+
+ * lisp/progmodes/ruby-mode.el (ruby-syntax-propertize):
+ Optimize two rules a little.
+
+2020-12-31 Dmitry Gutov <dgutov@yandex.ru>
+
+ ruby-mode: Recognize setter symbols
+
+ * lisp/progmodes/ruby-mode.el (ruby-syntax-propertize):
+ Add a rule for setter symbols (bug#42846).
+ (ruby-font-lock-keywords): Remove dead code, left over from before
+ commit 26f9c507.
+
+ * lisp/progmodes/ruby-mode.el (ruby-smie--bosp):
+ Handle '=' being part of a symbol (bug#42846).
+
+ * test/lisp/progmodes/ruby-mode-resources/ruby.rb:
+ Add corresponding indentation examples.
+
+2020-12-31 João Távora <joaotavora@gmail.com>
+
+ Fix type declaration of two Flymake customization variables
+
+ * lisp/progmodes/flymake.el (flymake-mode-line-format)
+ (flymake-mode-line-counter-format): Fix type declaration.
+
+2020-12-31 Eli Zaretskii <eliz@gnu.org>
+
+ Fix process-tests on MS-Windows
+
+ * test/src/process-tests.el (process-tests--fd-setsize-test): On
+ MS-Windows start the pipe processes in the "stopped" condition.
+
+2020-12-31 João Távora <joaotavora@gmail.com>
+
+ Must explicitly create unpropertized strings in mode-line
+
+ Otherwise, an innocent string like " " will mysteriously
+ pickup properties from some other minor mode.
+
+ Making this a separate commit in hopes of raising attention to this
+ possible bug.
+
+ * lisp/progmodes/flymake.el (flymake--mode-line-counter): Must
+ explicily create a new string unpropertized string
+
+2020-12-31 João Távora <joaotavora@gmail.com>
+
+ Make Flymake mode-line indicator customizable (bug#33740)
+
+ * lisp/progmodes/flymake.el (flymake-mode): Use
+ flymake-mode-line-format.
+ (flymake--mode-line-format): Remove.
+ (flymake-mode-line-counter-format, flymake-mode-line-format): New
+ defcustom.
+ (flymake-mode-line-title, flymake-mode-line-exception)
+ (flymake-mode-line-counters, flymake-error-counter)
+ (flymake-warning-counter, flymake-note-counter): New variables.
+ (flymake--mode-line-title, flymake--mode-line-exception)
+ (flymake--mode-line-counters, flymake--mode-line-counter): New
+ helpers.
+
+ * doc/misc/flymake.texi (Customizable variables): Mention
+ flymake-mode-line-format and flymake-mode-line-counter-format
+
+ * etc/NEWS: Mention Flymake's customizable mode-line.
+
+2020-12-31 João Távora <joaotavora@gmail.com>
+
+ Protect elisp-flymake-checkdoc against boundless diagnostics
+
+ These would be the kind of "This file needs a ;;Code section" and
+ such.
+
+ * lisp/progmodes/elisp-mode.el (elisp-flymake-checkdoc): Resist
+ checkdoc diagnostics with no end position.
+
+2020-12-31 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/src/process-tests.el: Let timeouts fail the tests. Fix some docstrings
+
+2020-12-31 Alan Mackenzie <acm@muc.de>
+
+ CC Mode. Fix AWK Mode fontification bug, remove some unused variables
+
+ * lisp/progmodes/cc-awk.el (awk-font-lock-keywords): Replace a hard use of
+ c-preprocessor-face-name by an `eval' expression which evaluates it.
+
+ * lisp/progmodes/cc-engine.el (c-in-knr-argdecl, c-laomib-put-cache)
+ (c-laomib-fix-elt): Remove unused bound variables.
+
+2020-12-31 Philipp Stephani <phst@google.com>
+
+ Unbreak process tests if 'errno' is not installed.
+
+ * test/src/process-tests.el (process-tests--EMFILE-message): Don't
+ signal an error if the 'errno' binary is unavailable.
+
+2020-12-31 Stefan Kangas <stefan@marxist.se>
+
+ Fix some shellcheck linter warnings
+
+ * admin/diff-tar-files:
+ * admin/merge-gnulib:
+ * admin/merge-pkg-config:
+ * admin/update-copyright:
+ * build-aux/git-hooks/prepare-commit-msg:
+ * make-dist: Fix some shellcheck linter warnings.
+
+2020-12-31 Stefan Kangas <stefan@marxist.se>
+
+ Minor cleanup in doc.c
+
+ * src/doc.c (get_doc_string, Fdocumentation)
+ (Fdocumentation_property, store_function_docstring):
+ Minor cleanup.
+
+2020-12-31 Stefan Kangas <stefan@marxist.se>
+
+ Add lexical-binding cookie to autoload files
+
+ * build-aux/update-subdirs:
+ * lisp/emacs-lisp/autoload.el (autoload-rubric): Add lexical-binding
+ cookie to generated files (bug#44854).
+
+2020-12-31 Daniel Martín <mardani29@yahoo.es>
+
+ Fix duplicated entry in gnus-mime-action-alist
+
+ * lisp/gnus/gnus-art.el (gnus-mime-action-alist): Remove duplicated
+ "toggle display" entry and call the appropriate function for the "view
+ as charset" action (bug#45561).
+
+2020-12-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow add-to-ordered-list to use a test predicate
+
+ * doc/lispref/lists.texi (List Variables): Update manual.
+
+ * lisp/subr.el (add-to-ordered-list): Allow using a test
+ predicate, and make slightly more efficient (bug#45539).
+
+2020-12-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add test for add-to-ordered-list
+
+2020-12-31 Daniel Martín <mardani29@yahoo.es>
+
+ Add some tests to find-func.el
+
+2020-12-31 Philipp Stephani <phst@google.com>
+
+ Minor improvements to FD_SETSIZE overflow checks.
+
+ * src/process.c (Fmake_serial_process): Add port to error data.
+ (connect_network_socket): Add an explanatory comment.
+
+2020-12-31 Philipp Stephani <phst@google.com>
+
+ Manually limit file descriptors that we select on to FD_SETSIZE.
+
+ This works even if another thread or process resets the resource limit
+ for open file descriptors, e.g., using 'prlimit' on GNU/Linux.
+
+ * src/process.c (create_process, create_pty, Fmake_pipe_process)
+ (Fmake_serial_process, connect_network_socket)
+ (server_accept_connection): Limit file descriptors to FD_SETSIZE.
+ * test/src/process-tests.el (process-tests--with-raised-rlimit): New
+ helper macro.
+ (process-tests--fd-setsize-test): Rename from
+ 'process-tests--with-many-pipes'. Increase resource limit during test
+ if possible.
+ (process-tests/fd-setsize-no-crash/make-process)
+ (process-tests/fd-setsize-no-crash/make-pipe-process)
+ (process-tests/fd-setsize-no-crash/make-network-process)
+ (process-tests--new-pty): Rename callers.
+
+2020-12-31 Philipp Stephani <phst@google.com>
+
+ Fix a potential unit test breakage on GNU/Linux.
+
+ * test/src/process-tests.el
+ (process-tests/fd-setsize-no-crash/make-process): Allow special exit
+ codes that can happen if terminal setup fails in the child process.
+
+2020-12-30 Philipp Stephani <phst@google.com>
+
+ Fix an incorrect Edebug specification.
+
+ * test/src/process-tests.el (process-tests--with-many-pipes): Fix
+ incorrect Edebug specification.
+
+2020-12-30 Philipp Stephani <phst@google.com>
+
+ Consistently check for FD_SETSIZE overflow.
+
+ Previously this was only checked in a few places. Now assert that
+ file descriptors are within the expected range whenever we'd otherwise
+ introduce undefined behavior.
+
+ * src/process.c (add_read_fd, add_process_read_fd, delete_read_fd)
+ (recompute_max_desc, delete_write_fd, compute_input_wait_mask)
+ (compute_non_process_wait_mask, compute_non_keyboard_wait_mask)
+ (compute_write_mask, clear_waiting_thread_info)
+ (update_processes_for_thread_death, Fset_process_thread)
+ (create_process, create_pty, Fmake_pipe_process)
+ (Fprocess_datagram_address, Fset_process_datagram_address)
+ (Fmake_serial_process, finish_after_tls_connection)
+ (connect_network_socket, deactivate_process)
+ (server_accept_connection, wait_reading_process_output)
+ (read_process_output, read_and_dispose_of_process_output)
+ (send_process, Fcontinue_process, Fprocess_send_eof)
+ (Fprocess_filter_multibyte_p, keyboard_bit_set)
+ (add_timer_wait_descriptor, setup_process_coding_systems): Add
+ assertions to document and check that file descriptors are within the
+ expected range when used as file descriptor set elements or array
+ subscripts.
+
+2020-12-30 Philipp Stephani <phst@google.com>
+
+ Extend and overhaul FD_SETSIZE overflow tests.
+
+ Instead of trying to generate the right number of processes,
+ pre-create lots of unused pipe processes until creation fails. Extend
+ the tests to the 'pty' connection type and other kinds of process
+ objects.
+
+ * test/src/process-tests.el (process-tests--ignore-EMFILE)
+ (process-tests--with-buffers, process-tests--with-processes)
+ (process-tests--with-many-pipes, process-tests--with-temp-file)
+ (process-tests--with-temp-directory): New helper macros.
+ (process-tests/fd-setsize-no-crash/make-process): Renamed from
+ 'process-tests/fd-setsize-no-crash'. Fail on timeout. Also test the
+ 'pty' connection type. Pre-create lots of pipe processes so we reach
+ the FD_SETSIZE limit faster. Ignore EMFILE more precisely, if
+ possible.
+ (process-tests/fd-setsize-no-crash/make-pipe-process)
+ (process-tests/fd-setsize-no-crash/make-network-process)
+ (process-tests/fd-setsize-no-crash/make-serial-process): New tests
+ that test FD_SETSIZE limits for other kinds of processes.
+ (process-tests--EMFILE-message): New helper function and cache
+ variable.
+ (process-tests--new-pty): New helper function.
+
+2020-12-30 Philipp Stephani <phst@google.com>
+
+ * src/nsterm.m (ns_select): Fix off-by-one error, and add assertion
+
+2020-12-30 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: correct the handling of empty strings
+
+ In particular, have the macro cache invalidated after its last use in
+ c-before-change.
+
+ * lisp/progmodes/cc-langs.el (c-get-state-before-change-functions): Remove
+ c-invalidate-macro-cache from the entries it's in, moving it to....
+
+ * lisp/progmodes/cc-mode.el (c-before-change): Call c-invalidate-macro-cache
+ directly from the functions, after the call to c-invalidate-state-cache.
+
+2020-12-30 Alan Third <alan@idiocy.org>
+
+ Fix Help menu on macOS
+
+ * src/nsmenu.m (ns_update_menubar): Make sure to reset the help menu
+ when we move it to another submenu.
+
+2020-12-30 Andrea Corallo <akrl@sdf.org>
+
+ Order function types in aphabetical order
+
+ * lisp/emacs-lisp/comp.el (comp-known-type-specifiers): Reorder in
+ aphabetical order and comment.
+
+2020-12-30 Andrea Corallo <akrl@sdf.org>
+
+ Add more function type specifiers
+
+ * lisp/emacs-lisp/comp.el (comp-known-type-specifiers): Add more
+ type specifiers.
+
+2020-12-30 Mattias Engdegård <mattiase@acm.org>
+
+ Use standard key symbols in NS menu entries
+
+ * src/nsmenu.m (skipspc): Remove.
+ (key_symbols, prettify_key): New.
+ ([EmacsMenu fillWithWidgetValue:]): Call prettify_key.
+
+2020-12-30 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant 'function's around lambda in align.el
+
+ * lisp/align.el (align-rules-list, align-exclude-rules-list)
+ (align-vhdl-rules-list, align-highlight-rule): Remove redundant
+ 'function's around lambda.
+
+2020-12-30 Dmitry Gutov <dgutov@yandex.ru>
+ Tobias Rittweiler <trittweiler@gmail.com>
+
+ Add 'project-relative' as value for 'xref-file-name-display'
+
+ * lisp/progmodes/xref.el (xref-file-name-display): Document new value.
+ (xref-location-group ((l xref-file-location))): Handle the new value.
+ (xref--project-root): Extract from the default method of
+ 'xref-backend-references' so it can be used in above's new code.
+ Also fix an old bug in the "backward compat" branch.
+
+ * lisp/progmodes/xref.el (xref--project-root-memo): New variable.
+
+ * test/lisp/progmodes/xref-tests.el: Add test cases for the three
+ possible settings of 'xref-file-name-display'.
+
+2020-12-30 Stefan Kangas <stefan@marxist.se>
+
+ Fix some over-wide docstrings
+
+ * lisp/cedet/semantic/analyze/refs.el
+ (semantic-analyze-refs-proto)
+ (semantic-analyze-refs-impl):
+ * lisp/cedet/semantic/symref.el
+ (semantic-symref-hit-to-tag-via-buffer):
+ * lisp/emacs-lisp/chart.el (chart-axis-draw):
+ * lisp/emacs-lisp/cl-macs.el (cl-defstruct, cl-loop):
+ * lisp/emacs-lisp/eieio-core.el (eieio--add-new-slot):
+ * lisp/eshell/em-unix.el (eshell/info):
+ * lisp/gnus/deuglify.el (gnus-outlook-rearrange-article):
+ * lisp/gnus/gnus-agent.el (gnus-agent-read-article-number):
+ * lisp/gnus/gnus-util.el (gnus-put-overlay-excluding-newlines)
+ (gnus-put-text-property-excluding-newlines):
+ * lisp/gnus/message.el (message-sort-headers):
+ * lisp/gnus/nntp.el (nntp-with-open-group)
+ (nntp-with-open-group-function):
+ * lisp/gnus/nnvirtual.el (nnvirtual-create-mapping):
+ * lisp/mail/feedmail.el (feedmail-fiddle-list-of-fiddle-plexes)
+ (feedmail-queue-reminder, feedmail-mail-send-hook-splitter):
+ * lisp/net/dictionary.el (dictionary-do-matching):
+ * lisp/obsolete/longlines.el (longlines-auto-wrap):
+ * lisp/org/ob-sql.el (org-babel-sql-dbstring-vertica):
+ * lisp/org/ol-bbdb.el (org-bbdb-date-list):
+ * lisp/progmodes/cc-cmds.el (c-mark-function):
+ * lisp/progmodes/cperl-mode.el (cperl-add-tags-recurse)
+ (cperl-add-tags-recurse-noxs-fullpath)
+ (cperl-add-tags-recurse-noxs):
+ * lisp/progmodes/etags.el (tags-search):
+ * lisp/progmodes/verilog-mode.el (verilog-delete-auto-buffer)
+ (verilog-auto-re-search-do, verilog-expand-vector-internal):
+ * lisp/textmodes/reftex-parse.el (reftex-init-section-numbers):
+ * lisp/textmodes/reftex-toc.el
+ (reftex-toc-load-all-files-for-promotion):
+ * lisp/textmodes/sgml-mode.el (html-mode):
+ * lisp/textmodes/table.el (table--transcoord-cache-to-table)
+ (table--transcoord-table-to-cache, table--remove-eol-spaces)
+ (table--region-in-cell-p, table-goto-bottom-right-corner)
+ (table-split-cell-horizontally):
+ * lisp/url/url-handlers.el (url-insert):
+ * lisp/vc/ediff-util.el (ediff-inferior-compare-regions): Fix doc
+ strings to not exceed 80-column limits. (Bug#44858)
+
+2020-12-30 Mattias Engdegård <mattiase@acm.org>
+
+ Plug NS memory leaks (bug#45502)
+
+ * src/nsmenu.m ([EmacsMenu addItemWithWidgetValue:attributes:]):
+ Mark allocated and owned objects for autorelease.
+
+2020-12-30 Juri Linkov <juri@linkov.net>
+
+ Add variables read-char-choice-use-read-key and y-or-n-p-use-read-key
+
+ * lisp/subr.el (read-char-choice-use-read-key): New variable.
+ (read-char-choice): Use read-char-from-minibuffer when
+ read-char-choice-use-read-key is nil.
+ (y-or-n-p-use-read-key): New variable.
+ (y-or-n-p): Restore old code that calls read-key to use it when
+ y-or-n-p-use-read-key is non-nil.
+
+ * lisp/dired-aux.el (dired--no-subst-ask, dired-query):
+ * lisp/files.el (files--ask-user-about-large-file)
+ (hack-local-variables-confirm):
+ * lisp/userlock.el (ask-user-about-supersession-threat):
+ * lisp/wid-edit.el (widget-choose): Revert to use read-char-choice
+ instead of read-char-from-minibuffer.
+
+ https://lists.gnu.org/archive/html/emacs-devel/2020-12/msg01919.html
+
+2020-12-30 Michael Albinus <michael.albinus@gmx.de>
+
+ * src/dbusbind.c (XD_BASIC_DBUS_TYPE): Fix error in declaration.
+
+2020-12-30 Juri Linkov <juri@linkov.net>
+
+ In Isearch bind 'C-s M-y' to isearch-yank-pop-only with old code (bug#45483)
+
+ * lisp/isearch.el (isearch-menu-bar-yank-map, isearch-mode-map):
+ (isearch-forward): Use isearch-yank-pop-only instead of isearch-yank-pop.
+ (isearch-yank-pop): Mention isearch-yank-pop-only.
+ (isearch-yank-pop-only): New command with old body from Emacs 27.
+
+2020-12-30 Stefan Kangas <stefan@marxist.se>
+
+ Minor cleanup in keymap.c
+
+ * src/keymap.c (get_keymap, keymap_parent, Fset_keymap_parent)
+ (store_in_keymap, Fdefine_key, Flookup_key, define_as_prefix)
+ (silly_event_symbol_error, current_minor_maps)
+ (Fcurrent_active_maps, Fkey_binding, Flocal_key_binding)
+ (Fminor_mode_key_binding, Fdefine_prefix_command)
+ (Faccessible_keymaps, Fdescribe_buffer_bindings)
+ (describe_vector, Fwhere_is_internal): Minor cleanup.
+
+2020-12-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Also count symbol plists in memory-report
+
+ * lisp/emacs-lisp/memory-report.el (memory-report--symbol-plist):
+ New function.
+ (memory-report): Use it.
+
+2020-12-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Switch add-to-ordered-list to eql"
+
+ This reverts commit b4fd857ead728a06380250c5336c1ab94a7c2f7a.
+
+ I misunderstood the purposed of the function.
+
+2020-12-30 Stefan Kangas <stefan@marxist.se>
+
+ Add some char-table tests
+
+ * test/src/chartab-tests.el (chartab-test-char-table-p)
+ (chartab-test-char-table-subtype)
+ (chartab-test-char-table-parent)
+ (chartab-test-char-table-extra-slot): New tests.
+
+2020-12-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Switch add-to-ordered-list to eql
+
+ * doc/lispref/lists.texi (List Variables): Update documentation.
+
+ * lisp/subr.el (add-to-ordered-list): Switch to eql (bug#45539).
+
+2020-12-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the `long' computation of `mode-line-compact'
+
+ * src/xdisp.c (display_mode_line): Compute `long' based on total
+ window width, and use the passed-in window instead of the selected
+ window.
+
+2020-12-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add caveat about the `long' `mode-line-compact' setting
+
+ * doc/lispref/modes.texi (Mode Line Basics): Elaborate on the
+ `long' setting.
+
+2020-12-30 Tobias Rittweiler <trittweiler@gmail.com>
+
+ Minor refactoring of xref-tests
+
+ * test/lisp/progmodes/xref-tests.el (xref-tests-data-dir):
+ Rename to 'xref-tests--data-dir'.
+ (xref-tests--matches-in-data-dir, xref-tests--locations-in-data-dir):
+ New functions. Factored out from test cases and updated usage sites
+ to use them.
+
+2020-12-29 Alan Third <alan@idiocy.org>
+
+ Don't calculate macOS menu data for GNUstep (bug#45502)
+
+ * src/nsmenu.m ([EmacsMenu fillWithWidgetValue:]): #ifdef out code
+ that has no effect on GNUstep and autorelease alloc'd objects.
+
+2020-12-29 Artem Loenko <artyom.loenko@mac.com>
+
+ * src/Makefile.in (DO_CODESIGN): Fix architecture for Apple Silicon
+
+2020-12-29 Juri Linkov <juri@linkov.net>
+
+ Use explicit "--color=auto" in grep mode to support both GNU grep and ripgrep
+
+ * lisp/progmodes/grep.el (grep-highlight-matches):
+ (grep-compute-defaults, grep-expand-template):
+ Use "--color=auto" instead of "--color" (bug#44983).
+
+2020-12-29 Juri Linkov <juri@linkov.net>
+
+ * lisp/x-dnd.el (x-dnd-get-drop-x-y): Add safer check for top/left (bug#45277)
+
+2020-12-29 Eli Zaretskii <eliz@gnu.org>
+
+ A better fix for process-tests on MS-Windows
+
+ * src/w32.c (pipe2): When forcibly closing pipe handles due to
+ overflow of FD_SETSIZE, set the handles to -1, to avoid assertion
+ violations in emacs_close.
+
+ * test/src/process-tests.el (process-tests/fd-setsize-no-crash):
+ No need to skip this test anymore.
+
+2020-12-29 Eli Zaretskii <eliz@gnu.org>
+
+ Fix process-tests on MS-Windows
+
+ * test/src/process-tests.el (process-tests/fd-setsize-no-crash):
+ Skip this test on windows-nt systems, as we cannot use more than
+ FD_SETSIZE file descriptors there: if we try, we crash.
+
+2020-12-29 Dmitry Gutov <dgutov@yandex.ru>
+
+ xref-show-definitions-completing-read: Tune up completion
+
+ * lisp/minibuffer.el (completion-category-defaults)
+ Use 'substring' completion style for 'xref-location' category by
+ default.
+
+ * lisp/progmodes/xref.el (xref-show-definitions-completing-read):
+ Assign the 'xref-location' category to the completions. Pass
+ REQUIRE-MATCH=t.
+
+2020-12-29 Michael Albinus <michael.albinus@gmx.de>
+
+ Instrument process-tests.el for timeouts on emba
+
+2020-12-29 Philipp Stephani <phst@google.com>
+
+ Add a regression test for Bug#24325.
+
+ * test/src/process-tests.el (process-tests/fd-setsize-no-crash): New
+ unit test.
+
+2020-12-29 Andrea Corallo <akrl@sdf.org>
+
+ Fix missing negation handling in a bunch of predicates
+
+ * lisp/emacs-lisp/comp.el (comp-mvar-fixnum-p)
+ (comp-mvar-symbol-p, comp-mvar-cons-p): Consider neg slot.
+ * test/src/comp-tests.el (comp-test-not-cons): New test.
+ * test/src/comp-test-funcs.el (comp-test-not-cons-f): New
+ function.
+
+2020-12-29 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr): Better `comp-value-to-cstr'.
+
+2020-12-29 Andrea Corallo <akrl@sdf.org>
+
+ Constrain mvars under compare and branch with built-in predicates
+
+ * lisp/emacs-lisp/comp.el (comp-emit-assume): Update.
+ (comp-known-predicate-p): New function.
+ (comp-add-cond-cstrs): Extend to pattern match predicate calls.
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-null-p)
+ (comp-pred-to-cstr): New function.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add a
+ number of tests and fix comments.
+
+2020-12-29 Mattias Engdegård <mattiase@acm.org>
+
+ More readable keys in NS menu entries (bug#45502)
+
+ Each menu entry now has the key binding in a right-aligned column, as
+ an attempt to improve readability. Previously the keys were given in
+ brackets immediately following the menu string.
+
+ * src/nsmenu.m ([EmacsMenu parseKeyEquiv:]): Remove.
+ (skipspc): New helper function.
+ ([EmacsMenu addItemWithWidgetValue:]): Add attributes argument.
+ Use attributed title string. Don't special-case Super bindings.
+ ([EmacsMenu fillWithWidgetValue:]): Compute maximum width. Prepare
+ attributes for title.
+
+2020-12-29 Michael Albinus <michael.albinus@gmx.de>
+
+ Sync with Tramp 2.5.0
+
+ * doc/misc/trampver.texi:
+ * lisp/net/trampver.el: Change version to "2.5.0".
+
+ * test/lisp/net/tramp-tests.el
+ (tramp--test--deftest-direct-async-process): Check, that
+ `make-process' supports file name handlers. Suppress
+ `internal-default-process-sentinel'.
+ (tramp--test-async-shell-command): Set `proc' proper.
+ (tramp-test32-shell-command-direct-async): Tag it :unstable.
+
+2020-12-29 João Távora <joaotavora@gmail.com>
+
+ Revert "Allow the flymake mode line indicator to be customized"
+
+ This reverts commit 37049ee78c4576d340781179317e6cbaaf73b6c3.
+
+ It's not ready to be used, contains some fundamental errors.
+
+ See bug#33740.
+
+2020-12-29 Andrea Corallo <akrl@sdf.org>
+
+ Define `cl-satisfies-deftype' mapping predicate -> type
+
+ * lisp/emacs-lisp/cl-macs.el (cl-satisfies-deftype): Define symbol
+ property as reverse of `cl-deftype-satisfies'.
+
+2020-12-29 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr): Better `comp-type-to-cstr'.
+
+2020-12-29 Alan Third <alan@idiocy.org>
+
+ Fix crash in NS menu code
+
+ * src/nsmenu.m (ns_update_menubar): When the menu generation code was
+ copied from xmenu.c the fix for waiting_for_input was lost. Reinstate
+ it.
+
+2020-12-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add some tests for align.el
+
+2020-12-29 Glenn Morris <rgm@gnu.org>
+
+ * src/xdisp.c (display_mode_line): I guess FALSE should be false.
+
+2020-12-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert the previous display_string change
+
+ * src/xdisp.c (display_string): Revert adding the additional
+ ignore_text_properties parameter -- it was already covered by the
+ other mix of parameters.
+
+2020-12-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix compact mode line text properties
+
+ * src/xdisp.c (display_mode_line): Display the compact mode
+ correctly (with text properties) (bug#45520).
+
+2020-12-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a parameter to display_string to allow not ignoring text props
+
+ * src/xdisp.c (display_string): Add a parameter to allow not
+ ignoring text properties (bug#45520). Adjust callers throughout
+ xdisp.c.
+
+2020-12-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Introduce new variable mode-line-compact
+
+ * doc/lispref/modes.texi (Mode Line Basics): Document it (bug#34476).
+
+ * src/xdisp.c (display_mode_line): Use it.
+ (syms_of_xdisp): New variable mode-line-compact.
+
+2020-12-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow the flymake mode line indicator to be customized
+
+ * doc/misc/flymake.texi (Customizable variables): Mention it.
+
+ * lisp/progmodes/flymake.el (flymake-mode-line-indicator-format):
+ New variable (bug#33740).
+ (flymake--mode-line-format): Use it.
+
+2020-12-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a SPLIT parameter to `format-spec'
+
+ * doc/lispref/strings.texi (Custom Format Strings): Document it.
+
+ * lisp/format-spec.el (format-spec): Add an optional parameter to
+ return a list of strings (bug#33740).
+
+2020-12-29 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Reword a long docstring in cc-langs.el
+
+ * lisp/progmodes/cc-langs.el (c-vsemi-status-unknown-p-fn): Reword
+ docstring to fit within 80 columns and silence the corresponding
+ byte-compiler warning (bug#44858).
+
+2020-12-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a reference between the Strings node and Search/Replace
+
+ * doc/lispref/strings.texi (Creating Strings): Mention
+ string-replace/replace-regexp-in-string (bug#45516).
+
+2020-12-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow mixing attributes and comments in the diary file
+
+ * lisp/calendar/diary-lib.el (diary-face-attrs): The attributes
+ don't have to be at the end of the line -- there may be ##warntime
+ or other comments (bug#19965).
+
+2020-12-29 João Távora <joaotavora@gmail.com>
+
+ Robustify completion match scoring for optimized patterns
+
+ (Bug#42149)
+
+ The function completion-pcm--hilit-commonality, which propertizes and
+ scores a previously confirmed match, expected its PATTERN argument to
+ match the strings of COMPLETIONS entirely (i.e. up to the string's
+ very end). But sometimes the ending wildcard, represented by the
+ 'any' atom in PATTERN, is optimized away by
+ completion-pcm--optimize-pattern. Although this is mostly benign in
+ terms of highlighting commonality, it leads to incorrect score values.
+
+ In this change, we ensure that completion-pcm--hilit-commonality is
+ aware of this exception and isn't affected by it. We also document
+ the function a bit better and simplify its workings.
+
+ Originally reported by Dario Gjorgjevski <dario.gjorgjevski@gmail.com>
+
+ * lisp/minibuffer.el (completion-pcm--hilit-commonality):
+ Simplify. Add docstring.
+
+ * lisp/minibuffer.el (completion-pcm--hilit-commonality): Add
+ docstring
+
+2020-12-28 Amin Bandali <bandali@gnu.org>
+
+ Display messages sent using ERC's /say
+
+ * lisp/erc/erc.el (erc-cmd-SAY): Call `erc-display-msg' to display the
+ user's message in the buffer, just like other [non-command] messages.
+
+ https://lists.gnu.org/r/help-gnu-emacs/2020-12/msg00066.html
+
+2020-12-28 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Add newish AWK Mode facilities, as used in gawk-4.
+
+ * lisp/progmodes/cc-awk.el (c-awk-font-lock-invalid-namespace-separators):
+ New function.
+ (c-awk-context-expand-fl-region): New function.
+ (awk-font-lock-keywords): Enhance handling of function declarations to include
+ :: tokens. Fontify new system variable names FPAT, FUNCTAB, PREC, ROUNDMODE,
+ SYNTAB. Fontify new keywords BEGINFILE and ENDFILE. Fontify new system
+ functions asorti, dcngettext, isarray, patsplit, typeof. Fontify the new
+ directives @include, @load, @namespace. Call
+ c-awk-font-lock-invalid-namespace-separators as a matcher.
+
+ * lisp/progmodes/cc-fonts.el (top level): No longer require 'cc-awk.
+
+ * lisp/progmodes/cc-langs.el (c-before-context-fontification-functions): Give
+ AWK the value c-awk-context-expand-fl-region rather than nil.
+
+ * lisp/progmodes/cc-mode.el (top level): Declare awk-mode-syntax-table as a
+ variable.
+
+2020-12-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/minibuffer.el: Avoid consecutive `any` in completion patterns
+
+ (completion-pcm--optimize-pattern): Turn multiple consecutive
+ occurrences of `any` into just a single one.
+ Suggested by Dario Gjorgjevski <dario.gjorgjevski@gmail.com>.
+
+2020-12-28 Glenn Morris <rgm@gnu.org>
+
+ Fix package tests for tetris no longer existing as a package
+
+ * test/lisp/emacs-lisp/package-tests.el
+ (package-test-list-filter-by-name, package-test-list-clear-filter):
+ Use ansi-color instead of tetris, which no longer has a version:.
+
+2020-12-28 Alan Third <alan@idiocy.org>
+
+ Fix crash in NS menu code
+
+ * src/nsmenu.m (ns_update_menubar): Don't assume that the top level
+ menus are correct when populating the submenus.
+ (free_frame_menubar): Clear the menu.
+ ([EmacsMenu removeAllItems]): Actually remove all menu items.
+
+2020-12-28 Andrea Corallo <akrl@sdf.org>
+
+ Store function type and expose it with `subr-type'
+
+ * src/lisp.h (struct Lisp_Subr): Add 'type' field.
+ (SUBR_TYPE): New inline accessor.
+ * src/pdumper.c (dump_subr): Update for 'type' field.
+ * src/data.c (Fsubr_type): New primitive.
+ (syms_of_data): Update.
+ * src/comp.c (ABI_VERSION): Bump new ABI version.
+ (make_subr): Set type.
+ (Fcomp__register_lambda, Fcomp__register_subr)
+ (Fcomp__late_register_subr): Receive and pass subr type to
+ 'make_subr'.
+ * src/alloc.c (mark_object): Mark subr type.
+ * lisp/emacs-lisp/comp.el (comp-func): Change slot type into mvar.
+ (comp-emit-for-top-level, comp-emit-lambda-for-top-level): Pass
+ type mvar to subr register functions.
+ (comp-compute-function-type): Fix-up subr type mvars.
+ * test/src/comp-tests.el (comp-tests-check-ret-type-spec): Use
+ `subr-type'.
+
+2020-12-28 Andrea Corallo <akrl@sdf.org>
+
+ Reorder subr register function arguments to make some room
+
+ * src/comp.c (Fcomp__register_lambda, Fcomp__register_subr)
+ (Fcomp__late_register_subr): Use a rest arg to pass 'doc_idx' and
+ 'intspec' parameters.
+ * lisp/emacs-lisp/comp.el (comp-emit-for-top-level)
+ (comp-emit-lambda-for-top-level): Update.
+
+2020-12-28 Andrea Corallo <akrl@sdf.org>
+
+ Propagate function calls also when hiddend under funcall
+
+ * lisp/emacs-lisp/comp.el (comp-fwprop-call): Propagate functions
+ also when called under `funcall'.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add a test.
+
+2020-12-28 Andrea Corallo <akrl@sdf.org>
+
+ Compute function type for native compiled functions
+
+ * lisp/emacs-lisp/comp.el (comp-func): `type' rename from
+ `ret-type-specifier'.
+ (comp-args-to-lambda-list): New function.
+ (comp-compute-function-type): New function from
+ `comp-ret-type-spec'.
+ (comp-final): Update.
+ * test/src/comp-tests.el (comp-tests-check-ret-type-spec): Update.
+
+2020-12-28 Andrea Corallo <akrl@sdf.org>
+
+ Improve some slot type into comp.el
+
+ * lisp/emacs-lisp/comp.el (comp-args-base, comp-args)
+ (comp-nargs, comp-func): Fix the type of some slots.
+
+2020-12-28 Stefan Kangas <stefan@marxist.se>
+
+ Minor cleanups in tetris.el
+
+ * lisp/play/tetris.el: Remove redundant :group args.
+ (tetris-get-tick-period): Drop unnecessary check.
+ (tetris): Stylistic doc fixes.
+
+2020-12-28 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/ps-print.el (ps-message-log-max): Remove XEmacs compat code.
+
+2020-12-28 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant 'function's around lambda in vhdl-mode.el
+
+ * lisp/progmodes/vhdl-mode.el (fboundp, vhdl-sort-alist, lambda)
+ (vhdl-create-mode-menu, vhdl-set-offset, vhdl-set-style)
+ (vhdl-regress-line, vhdl-align-inline-comment-region-1)
+ (vhdl-resolve-paths, vhdl-generate-makefile-1)
+ (vhdl-submit-bug-report): Remove redundant 'function's around lambda.
+
+2020-12-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix too-long feedmail-sendmail-f-doesnt-sell-me-out doc string
+
+ * lisp/mail/feedmail.el (feedmail-sendmail-f-doesnt-sell-me-out):
+ Fold the example SMTP header using continuation folding.
+
+2020-12-28 Stefan Kangas <stefan@marxist.se>
+
+ Fill some auto-generated docstrings
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode)
+ (define-globalized-minor-mode): Fill auto-generated documentation
+ strings. (Bug#44858)
+ * lisp/subr.el (internal--fill-string-single-line)
+ (internal--format-docstring-line): New functions.
+
+2020-12-28 Stefan Kangas <stefan@marxist.se>
+
+ Make byte-compiler warn about wide docstrings
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile--wide-docstring-p):
+ (byte-compile-docstring-length-warn): New defuns.
+ (byte-compile-docstring-max-column): New defcustom.
+ (byte-compile--wide-docstring-substitution-len): New variable.
+ (byte-compile-warning-types, byte-compile-warnings): New value
+ 'docstrings'.
+ (byte-compile-file-form-autoload, byte-compile-file-form-defvar):
+ (byte-compile-file-form-defvar-function, byte-compile-lambda):
+ (byte-compile-defvar, byte-compile-file-form-defalias): Warn about too
+ wide docstrings. (Bug#44858)
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (bytecomp-warn-wide-docstring/defconst)
+ (bytecomp-warn-wide-docstring/defvar): New tests.
+ (bytecomp--define-warning-file-test): New macro.
+ (bytecomp/warn-wide-docstring-autoload\.el)
+ (bytecomp/warn-wide-docstring-custom-declare-variable\.el)
+ (bytecomp/warn-wide-docstring-defalias\.el)
+ (bytecomp/warn-wide-docstring-defconst\.el)
+ (bytecomp/warn-wide-docstring-define-abbrev-table\.el)
+ (bytecomp/warn-wide-docstring-define-obsolete-function-alias\.el)
+ (bytecomp/warn-wide-docstring-define-obsolete-variable-alias\.el)
+ (bytecomp/warn-wide-docstring-defun\.el)
+ (bytecomp/warn-wide-docstring-defvar\.el)
+ (bytecomp/warn-wide-docstring-defvaralias\.el)
+ (bytecomp/warn-wide-docstring-ignore-fill-column\.el)
+ (bytecomp/warn-wide-docstring-ignore-override\.el)
+ (bytecomp/warn-wide-docstring-ignore\.el)
+ (bytecomp/warn-wide-docstring-multiline-first\.el)
+ (bytecomp/warn-wide-docstring-multiline\.el): New tests.
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-autoload.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-custom-declare-variable.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-defalias.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-defconst.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-define-abbrev-table.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-define-obsolete-function-alias.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-define-obsolete-variable-alias.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-defun.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-defvar.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-defvaralias.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-ignore-fill-column.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-ignore-override.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-ignore.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-multiline-first.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-multiline.el:
+ New files.
+
+2020-12-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make octave-send-region be asynchronous
+
+ * lisp/progmodes/octave.el (octave-send-region): Send things
+ asynchronously to the inferior process (bug#24492).
+
+2020-12-28 Yichao Yu <yyc1992@gmail.com>
+
+ Make XIM to work with non-CJK locales
+
+ * src/xfns.c (best_xim_style): Don't rely on supported_xim_styles
+ (bug#10867).
+
+ * src/xterm.c (x_draw_window_cursor): Adjust to modern input styles.
+ (xim_instantiate_callback): Ditto.
+
+2020-12-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix background mode on Gnome 3.38 terminals
+
+ * lisp/term/xterm.el (xterm--version-handler): Adjust to Gnome
+ 3.38 (bug#43891).
+
+2020-12-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix alignment of Java String[] and the like
+
+ * lisp/align.el (align-rules-list): Allow aligning Java String[] etc
+ (bug#19385).
+
+ Test case:
+
+ class X
+ {
+ String field1;
+ String[] field2;
+ int field3;
+ int[] field4;
+ X field5;
+ X[] field6;
+ }
+
+2020-12-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document the text property limitations in mode lines
+
+ * doc/lispref/modes.texi (Properties in Mode, Mode Line Basics):
+ Mention the special text property limitations.
+
+2020-12-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow remember-notes to use the *scratch* buffer
+
+ * lisp/textmodes/remember.el (remember-notes): Allow the
+ remember-notes buffer to use the *scratch* buffer (as documented)
+ (bug#20740).
+
+2020-12-28 Dmitry Gutov <dgutov@yandex.ru>
+
+ Rename and document the built-in xref-show-definitions-function's
+
+ * lisp/progmodes/xref.el (xref-show-definitions-buffer): Rename
+ from 'xref--show-defs-buffer'.
+ (xref-show-definitions-buffer-at-bottom): Rename from
+ 'xref--show-defs-buffer-at-bottom'.
+
+2020-12-28 Tim Landscheidt <tim@tim-landscheidt.de> (tiny change)
+
+ Do not output two spaces for non-autoloaded ieieo constructor functions
+
+ * lisp/emacs-lisp/eieio-opt.el (eieio-help-constructor): Amend
+ format to avoid two spaces for non-autoloaded object constructor
+ functions (bug#45454).
+
+2020-12-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/package.el (package-archives): Add NonGNU ELPA
+
+2020-12-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/textmodes/rst.el (rst-mode): Don't touch global hook
+
+ (rst-re): η-reduce.
+
+2020-12-27 Andrea Corallo <akrl@sdf.org>
+
+ Add 1+ 1- integer range propagation support
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-one): New special var.
+ * lisp/emacs-lisp/comp.el (comp-fwprop-call): Propagate integer
+ ranges on +1 -1.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add two tests.
+
+2020-12-27 Andrea Corallo <akrl@sdf.org>
+
+ Add sum/subtraction integer range propagation support
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-range-+, comp-range--): New
+ functions.
+ (comp-cstr-set-range-for-arithm): New macro.
+ (comp-cstr-add-2, comp-cstr-sub-2, comp-cstr-add, comp-cstr-sub):
+ New function.
+ * lisp/emacs-lisp/comp.el (comp-fwprop-call): Wire-up + - integer
+ range propagation.
+
+2020-12-27 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-set-cmp-range): Improve.
+
+2020-12-27 Andrea Corallo <akrl@sdf.org>
+
+ Add comp-cstr-greatest-in-range comp-cstr-smallest-in-range
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-smallest-in-range)
+ (comp-cstr-greatest-in-range): New function.
+ (comp-cstr->, comp-cstr->=, comp-cstr-<, comp-cstr-<=): Make use of.
+
+2020-12-27 Andrea Corallo <akrl@sdf.org>
+
+ Don't require trailing backslashes in `comp-eln-load-path' (bug#45462)
+
+ * src/comp.c (Fcomp_el_to_eln_filename): Don't require
+ trailing backslashes in comp-eln-load-path.
+
+2020-12-27 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-12-27 Alan Third <alan@idiocy.org>
+
+ Remove NS menu synthesized events (bug#44333)
+
+ Remove the frame tracking stuff as it's not used for anything, and
+ move the update tracking into the EmacsMenu class.
+
+ * src/nsmenu.m (ns_update_menubar): Copy the parsing code from xmenu.c
+ and rework the NS specific code around to update the existing menus
+ instead of rebuilding them completely.
+ (ns_activate_menubar):
+ ([EmacsMenu trackingNotification:]):
+ ([EmacsMenu menuWillOpen:]):
+ ([EmacsMenu menuDidClose:]): Remove unused functions.
+ ([EmacsMenu menuNeedsUpdate:]): Remove menu tracking code and add code
+ to check whether an update is required.
+ ([EmacsMenu fillWithWidgetValue:]):
+ ([EmacsMenu addSubmenuWithTitle:]):
+ ([EmacsMenu initWithTitle:]): Remove references to frame.
+ ([EmacsMenu setFrame:]): Remove method.
+ ([EmacsMenu clear]): Rename to removeAllItems.
+ ([EmacsMenu removeAllItems]): Use built-in removeAllItems, if
+ available.
+ (syms_of_nsmenu): Remove tracking code.
+ * src/nsterm.m (ns_check_menu_open):
+ (ns_check_pending_open_menu):
+ (ns_create_terminal): Remove unused functions.
+ (ns_term_init): Get rid of menu tracking.
+ * src/nsterm.h (EmacsMenu): Remove frame, add needsUpdate and update
+ method definitions.
+
+2020-12-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up length_internal with degenerate length inputs
+
+ * src/fns.c (length_internal): Protect against edge conditions.
+
+2020-12-27 Daniel Martín <mardani29@yahoo.es>
+
+ Improve "find definition" in *Help* buffers
+
+ * lisp/emacs-lisp/find-func.el (find-function-search-for-symbol): If
+ our regexp algorithm could not find a location for the symbol
+ definition, resort to find-function--search-by-expanding-macros.
+ * test/lisp/emacs-lisp/find-func-tests.el: Add a automatic test for a
+ function and variable generated by a macro.
+ * etc/NEWS: Advertise the improved functionality (bug#45443).
+
+2020-12-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new predicates for sequence lengths
+
+ * doc/lispref/sequences.texi (Sequence Functions): Document them.
+ * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Mark them as
+ side-effect-free.
+
+ * lisp/emacs-lisp/shortdoc.el (list): Mention them.
+
+ * src/fns.c (Flength): Mention them in the doc string.
+ (length_internal): New function.
+ (Flength_less, Flength_greater, Flength_equal): New defuns.
+ (syms_of_fns): Sym them.
+
+2020-12-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the edebug-form-data doc string
+
+ * lisp/emacs-lisp/edebug.el (edebug-form-data): Doc string
+ clarification (bug#42776).
+
+2020-12-26 Andrea Corallo <akrl@sdf.org>
+
+ Fix `byte-compile-file' for native compilation (bug#45442)
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-file): Fix logic for
+ native compilation.
+
+2020-12-26 Andrea Corallo <akrl@sdf.org>
+
+ Fix missing float handling into `comp-cstr-set-cmp-range'
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-set-cmp-range): Add
+ float handling.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Update results.
+
+2020-12-26 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/forms.el (forms--run-functions): New function
+
+ (forms--intuit-from-file, forms-save-buffer): Use it.
+ (forms-mode): Use it to fix regression.
+ Remove always-true test. Fix incorrect uses of `fboundp`.
+ (forms--iif-hook): Use `add-hook`.
+ (forms--iif-post-command-hook): Use `remove-hook` and fix typo.
+ (forms--debug): Use `mapconcat`.
+
+2020-12-26 Eli Zaretskii <eliz@gnu.org>
+
+ Fix test/src/process-tests on MS-Windows
+
+ * src/process.c (network_lookup_address_info_1) [WINDOWSNT]:
+ Initialize winsock.
+
+2020-12-26 Michael Albinus <michael.albinus@gmx.de>
+
+ Rename Tramp method "media" to "mtp" (Bug#45402)
+
+ * doc/misc/tramp.texi (Quick Start Guide, GVFS-based methods):
+ Rename "media" to "mtp". (Bug#45402)
+
+ * etc/NEWS: Rename Tramp method "media" to "mtp". Fix typos.
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-methods, tramp-media-methods)
+ (tramp-gvfs-activation-uri)
+ (tramp-gvfs-handler-volumeadded-volumeremoved)
+ (tramp-get-media-devices, top): Rename "media" to "mtp". (Bug#45402)
+
+2020-12-26 Andrea Corallo <akrl@sdf.org>
+
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add two more test.
+
+2020-12-26 Andrea Corallo <akrl@sdf.org>
+
+ Remove unnecessary lhs rename in `comp-ssa-rename-insn'
+
+ * lisp/emacs-lisp/comp.el (comp-ssa-rename-insn): No point to
+ rename lhs as it's being replaced.
+
+2020-12-26 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-known-type-specifiers): Add two functions.
+
+2020-12-26 Eli Zaretskii <eliz@gnu.org>
+
+ Fix Rmail summary display when From: header is malformed
+
+ * lisp/mail/rmailsum.el (rmail-header-summary): Remove newlines
+ from the "From:" value, to avoid producing corrupted summary
+ display.
+
+2020-12-26 Andrea Corallo <akrl@sdf.org>
+
+ Enable integer range narrowing under compare and branch
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-set-cmp-range)
+ (comp-cstr->, comp-cstr->=, comp-cstr-<, comp-cstr-<=): New
+ functions.
+ * lisp/emacs-lisp/comp.el (comp-equality-fun-p)
+ (comp-range-cmp-fun-p): New functions.
+ (comp-collect-rhs): Use `comp-assign-op-p' in place of
+ `comp-set-op-p'.
+ (comp-negate-range-cmp-fun, comp-reverse-cmp-fun): New functions.
+ (comp-emit-assume): Rework to be able to emit also comparison
+ assumption.
+ (comp-add-cond-cstrs-simple): Update for new `comp-emit-assume'.
+ (comp-add-cond-cstrs-simple): Update to emit range assumption.
+ (comp-fwprop-insn): Execute range assumptions.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add tests.
+
+2020-12-26 emacs-f <emacs-f@media.mit.edu> (tiny change)
+
+ Avoid missing email messages due to rmail-spam-filter
+
+ * lisp/mail/rmail-spam-filter.el (rsf--rmail-last-seen-message):
+ New function.
+ (rmail-spam-filter, rmail-get-new-mail-filter-spam): Call
+ 'rsf--rmail-last-seen-message' instead of
+ 'rmail-first-unseen-message'. (Bug#45128)
+
+2020-12-26 Zajcev Evgeny <zevlg@yandex.ru>
+
+ Improvements for `:base-uri' svg image property
+
+ * src/image.c (svg_load): Use ENCODE_FILE for `:base-uri'
+
+ * doc/lispref/display.texi (SVG Images): Add more documentation for
+ `:base-uri'
+
+2020-12-26 Eli Zaretskii <eliz@gnu.org>
+
+ Fix messages with plural forms in todo-mode.el
+
+ * lisp/calendar/todo-mode.el (todo-move-item, todo-item-undone)
+ (todo-category-completions): Use 'ngettext' instead of hard-coding
+ plural forms by hand.
+
+2020-12-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix issues with lib/malloc out-of-dir builds
+
+ Problem reported by Mattias Engdegård in:
+ https://lists.gnu.org/r/emacs-devel/2020-12/msg01626.html
+ * configure.ac: If the scratch_buffer module is enabled, create
+ lib/malloc and (if doing dependencies) lib/deps/malloc.
+ * lib/Makefile.in (DEPFLAGS) [AUTO_DEPEND]: No longer any need to
+ squash lib dependencies into a single directory.
+ (clean): Also remove */*.o and $(DEPDIR)/*/*.d, to clean out
+ malloc/*.o and deps/malloc/*.d. Just remove *.d files in
+ dependencies so that rm does not complain about not being able to
+ remove deps/malloc.
+ (extraclean): Also remove malloc, if it is empty.
+
+2020-12-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Kill the scdaemon after doing the mml-sec tests
+
+ * test/lisp/gnus/mml-sec-tests.el (mml-sec-test--kill-gpg-agent):
+ Kill the scdaemon, too (bug#43358).
+
+2020-12-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix infloop in memory-report
+
+ * lisp/emacs-lisp/memory-report.el (memory-report--object-size-1):
+ Fix infloop on circular lists.
+
+2020-12-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix package reloading problems on systems with symlinks
+
+ * lisp/emacs-lisp/package.el (package--files-load-history): We're
+ comparing the truenames, so ensure that we've using that
+ everywhere. This fixes problems when there's symlinks in the paths.
+
+2020-12-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Refactor package--list-loaded-files for easier debuggability
+
+ * lisp/emacs-lisp/package.el (package--files-load-history)
+ (package--list-of-conflicts): Factor out from...
+ (package--list-loaded-files): ... this function for easier
+ debuggability.
+
+2020-12-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Disable some semantic tests on systems without g++
+
+ * test/lisp/cedet/semantic-utest-ia.el: Disable g++ tests on
+ systems without g++.
+
+2020-12-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Skip some mml tests that rely on CMS if that's not installed
+
+2020-12-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix gpg-agent killing in mml-sec-tests
+
+ * test/lisp/gnus/mml-sec-tests.el (mml-sec-test--kill-gpg-agent):
+ Identify the gpg-agent more successfully after the resource dir
+ makeover.
+
+2020-12-25 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ b242bbb073 (origin/emacs-27) ; lisp/org/org.el: Fix Version header.
+ e0fc939c5f Add more details to the "word processor" section
+ fda9b3e83a * src/Makefile.in (DO_CODESIGN): Fix expected architecture...
+
+2020-12-25 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 5d46593568 Support build of Emacs on ARM Macos machines
+ 7f8793e5f1 Update to Org 9.4.4
+ 7b3367a0b5 * lisp/so-long.el: Decrease use of passive voice.
+ a90836c638 * doc/misc/efaq.texi (New in Emacs 27): Add section.
+ 711fe70dd8 * doc/misc/efaq.texi (Latest version of Emacs): Bump version.
+ 52b30834fb * lisp/face-remap.el (face-remap-set-base): Doc fix. (Bug...
+ b3fe0ac62e Correct argument order in comment
+
+2020-12-25 Michael Albinus <michael.albinus@gmx.de>
+
+ Tag another Tramp test :unstable on emba
+
+ * test/lisp/net/tramp-tests.el (tramp-test31-interrupt-process)
+ (tramp-test43-asynchronous-requests): Tag them :unstable on emba.
+
+2020-12-25 Michael Albinus <michael.albinus@gmx.de>
+
+ Tag Tramp test :unstable
+
+ * test/lisp/net/tramp-tests.el (tramp-test31-interrupt-process):
+ Tag it :unstable on emba.
+
+2020-12-25 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change
+
+ * lisp/international/mule-conf.el (ebcdic-int1, cp256, cp273)
+ (ebcdic-be, cp274, ebcdic-br, cp275, ebcdic-cp-dk, ebcdic-cp-no)
+ (cp277, ebcdic-cp-fi, ebcdic-cp-se, cp278, ebcdic-cp-it, cp280)
+ (ebcdic-jp-e, cp281, ebcdic-cp-es, cp284, ebcdic-cp-gb, cp285)
+ (ebcdic-jp-kana, cp290, ebcdic-cp-fr, cp297): Remove charset
+ aliases, they are not really needed.
+
+ * lisp/language/english.el (ibm275): Move from here...
+ * lisp/language/european.el (ibm275): ...to here.
+
+2020-12-25 Timo Myyrä <timo.myyra@bittivirhe.fi>
+
+ Add support for more EBCDIC code pages IBM2XX
+
+ There was already charset file present in etc/charsets for IBM2XX
+ character sets but there wasn't definitions for them in Emacs.
+ Add character set and coding system definitions for them.
+ * lisp/language/japanese.el (ibm281, ibm290):
+ * lisp/language/european.el (ibm256, ibm273, ibm274, ibm277)
+ (ibm278, ibm280, ibm284, ibm285, ibm297):
+ * lisp/language/english.el (ibm275): New coding systems.
+ * lisp/international/mule-conf.el (ibm256, ibm273, ibm274)
+ (ibm275, ibm277, ibm278, ibm280, ibm281, ibm284, ibm285, ibm290)
+ (ibm297): New charsets.
+
+2020-12-25 Eli Zaretskii <eliz@gnu.org>
+
+ Don't compile Gnulib's 'free' on MinGW
+
+ * nt/mingw-cfg.site (gl_cv_func_free_preserves_errno): Set to
+ "yes" to avoid compiling Gnulib's free.c in the MinGW build.
+
+2020-12-25 Eli Zaretskii <eliz@gnu.org>
+
+ Revert "Import posix_spawn from Gnulib."
+
+ This reverts commit 3ba34141da77a24c251ee6530f3f72a366fe556e.
+ It breaks the MinGW build and should be first tested on a
+ branch.
+
+2020-12-25 Eli Zaretskii <eliz@gnu.org>
+
+ Revert "Use posix_spawn if possible."
+
+ This reverts commit 2c79a8f9210db01c86b0e5f236adeb0509519d30.
+ It breaks the MinGW build in too many ways, and should be
+ first tested on a branch.
+
+2020-12-25 Philipp Stephani <phst@google.com>
+
+ Use posix_spawn if possible.
+
+ posix_spawn is less error-prone than vfork + execve, and can make
+ better use of system-specific enhancements like 'clone' on Linux. Use
+ it if we don't need to configure a pseudoterminal.
+
+ * src/Makefile.in (LIB_POSIX_SPAWN): New variable.
+ (LIBES): Use it.
+
+ * src/callproc.c (emacs_spawn): Use posix_spawn on Unix-like system if
+ we don't need to set up a pseudoterminal.
+
+2020-12-25 Philipp Stephani <phst@google.com>
+
+ Import posix_spawn from Gnulib.
+
+ posix_spawn is less error-prone than vfork + exec, and can make use of
+ system-specific optimizations like `clone' on Linux. Import Gnulib
+ replacement so that we can use recent additions like
+ `posix_spawn_file_actions_addchdir'.
+
+ The only manual change are to admin/merge-gnulib and .gitignore. All
+ other changes are due to rerunning merge-gnulib.
+
+ * admin/merge-gnulib (GNULIB_MODULES): Add posix_spawn-related
+ modules.
+ * .gitignore: Add new generated files.
+
+2020-12-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update Gnulib.
+
+ All changes in this commit are autogenerated by running
+ admin/merge-gnulib.
+
+2020-12-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ Adjust test_module to recent Gnulib changes
+
+ * test/Makefile.in ($(test_module)): Also compile lib/free.c
+ if it is needed to define rpl_free.
+
+2020-12-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ Adjust to recent Gnulib changes
+
+ The latest Gnulib merge brought in free-posix, which causes 'free'
+ to preserve errno. This lets us simplify some Emacs code that
+ calls 'free'.
+ * admin/merge-gnulib (GNULIB_MODULES): Add free-posix.
+ This module is pulled in by canonicalize-lgpl anyway,
+ so we might as well rely on it.
+ * lib-src/emacsclient.c (get_current_dir_name):
+ Sync better with src/sysdep.c.
+ * lib-src/etags.c (process_file_name, etags_mktmp):
+ * lib-src/update-game-score.c (unlock_file):
+ * src/fileio.c (file_accessible_directory_p):
+ * src/sysdep.c (get_current_dir_name_or_unreachable):
+ Simplify by assuming that 'free' preserves errno.
+ * src/alloc.c (malloc_unblock_input):
+ Preserve errno, so that xfree preserves errno.
+ * src/sysdep.c (get_current_dir_name_or_unreachable):
+ Simplify by using strdup instead of malloc+memcpy.
+ No need for realloc (and the old code leaked memory anyway on
+ failure); just use free+malloc.
+
+2020-12-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify gcc 10.2 -Wanalyzer-null-argument in gtkutil.c
+
+ * src/gtkutil.c (xg_item_label_same_p): Simplify. Without this
+ simplification, GCC (Ubuntu 10.2.0-13ubuntu1)
+ -Wanalyzer-null-argument complains about use of NULL where
+ non-null expected as argument of strcmp.
+
+2020-12-25 Andrea Corallo <akrl@sdf.org>
+
+ Don't emit byte op-code annotations in LIMPLE to optimize for compile-time
+
+ Saves 10~15% in bootstrap time.
+
+ * lisp/emacs-lisp/comp.el (comp-op-case): Don't emit op-code
+ annotaitons.
+ (comp-limplify-lap-inst, comp-add-cond-cstrs-simple)
+ (comp-add-cond-cstrs, comp-tco-func): Update accordingly.
+
+2020-12-25 Eli Zaretskii <eliz@gnu.org>
+
+ Add more details to the "word processor" section
+
+ * etc/TODO (Emacs as word processor): Add more details based on
+ recent discussions.
+
+2020-12-25 E. Choroba <choroba@matfyz.cz> (tiny change)
+
+ cperl-mode: Correctly syntax highlight index/value array slices
+
+ * lisp/progmodes/cperl-mode.el (cperl-init-faces): %array[0, 1]
+ should use the array face, not the hash one (bug#45373).
+
+2020-12-25 Thibault Polge <thibault@thb.lt>
+
+ Make `remove-hook' interactive
+
+ * lisp/subr.el (remove-hook): Make `remove-hook' interactive
+ (bug#45393).
+
+2020-12-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow `string-limit' to work on encoded strings
+
+ * doc/lispref/strings.texi (Creating Strings): Document it.
+
+ * lisp/emacs-lisp/subr-x.el (string-limit): Allow limiting on
+ encoded strings.
+
+2020-12-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove `string-slice' -- it's not very well defined
+
+ * doc/lispref/strings.texi (Creating Strings): Ditto.
+
+ * lisp/emacs-lisp/subr-x.el (string-slice): Remove.
+
+2020-12-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Unbreak the build on *BSD and Macos after previous gnulib merge
+
+ * lib/Makefile.in (DEPFLAGS): Unbreak build on BSD derivatives by
+ writing all deps files into a single directory (instead of
+ deps/malloc/*.c).
+
+2020-12-24 Eli Zaretskii <eliz@gnu.org>
+
+ Fix the MinGW build broken by Gnulib update
+
+ * nt/mingw-cfg.site (gl_cv_func_readlink_trailing_slash)
+ (gl_cv_func_readlink_truncate): Define to "yes" to avoid compiling
+ readlink.c.
+
+2020-12-24 Eli Zaretskii <eliz@gnu.org>
+
+ Unbreak the MinGW build broken by recent changes in callproc.c
+
+ * src/w32.h (set_process_dir):
+ * src/w32proc.c (set_process_dir): Change the argument to 'const
+ char *'.
+ * src/lisp.h (make_environment_block):
+ * src/callproc.c (make_environment_block): Now returns 'char **'.
+ (exec_failed) [DOS_NT]: Remove unused function.
+ * src/callproc.c (child_setup): NEW_ARGV and ENV are now 'char **'.
+ Making them 'const' breaks the MinGW build and is not needed for
+ other platforms.
+ * src/callproc.c (emacs_spawn): ARGV and ENVP arguments are now
+ 'char *', for the same reason.
+ * src/process.c (create_process): Adapt to above changes.
+
+2020-12-24 Philipp Stephani <phst@google.com>
+
+ Update Gnulib.
+
+ All changes in this commit are autogenerated by running
+ admin/merge-gnulib.
+
+2020-12-24 Philipp Stephani <phst@google.com>
+
+ Ensure that Gnulib objects in subdirectories are built correctly.
+
+ * lib/Makefile.in (.c.o): Add missing -o option.
+
+2020-12-24 Andrea Corallo <akrl@sdf.org>
+
+ Memoize `comp-subtype-p'
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-subtype-p): Memoize.
+ (comp-cstr-ctxt): Add `subtype-p-mem' slot.
+
+2020-12-24 Andrea Corallo <akrl@sdf.org>
+
+ Constrain only mvars that are actually used
+
+ * lisp/emacs-lisp/comp.el (comp-mvar-used-p, comp-collect-mvars)
+ (comp-collect-rhs): New functions.
+ (comp-add-cond-cstrs-simple, comp-add-cond-cstrs): Update logic.
+ (comp-add-cstrs): Call `comp-collect-rhs' before doing anything
+ else.
+
+2020-12-24 Andrea Corallo <akrl@sdf.org>
+
+ Use `comp-assign-op-p' into dead code elimination pass
+
+ * lisp/emacs-lisp/comp.el (comp-dead-assignments-func): Use
+ `comp-assign-op-p' in place of `comp-set-op-p'.
+
+2020-12-24 Andrea Corallo <akrl@sdf.org>
+
+ Fix logic for constraining block with multiple predecessors
+
+ * lisp/emacs-lisp/comp.el (comp-limple-lock-keywords)
+ (comp-add-cond-cstrs-target-block): Logic update.
+
+2020-12-24 Andrea Corallo <akrl@sdf.org>
+
+ Symplify (not t) => nil and (not nil) => t
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-negation): Symplify (not
+ t) => nil and (not nil) => t.
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Add two tests.
+
+2020-12-24 Andrea Corallo <akrl@sdf.org>
+
+ Extend cstrs pass to match `unless' like code
+
+ * lisp/emacs-lisp/comp.el (comp-emit-assume): Add assertion.
+ (comp-add-new-block-between): Fix two typos.
+ (comp-add-cond-cstrs-target-block): Fix typo.
+ (comp-add-cond-cstrs-simple): Logic update.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add a test.
+
+2020-12-24 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-limplify-lap-inst): Opencode byte-not.
+
+2020-12-24 Andrea Corallo <akrl@sdf.org>
+
+ Extend cstrs pass to match `when' like code
+
+ * lisp/emacs-lisp/comp.el (comp-emit-assume): Better parameter names.
+ (comp-add-cond-cstrs-simple): New function.
+ (comp-add-cond-cstrs): Rename assume-target -> block-target.
+ (comp-add-cstrs): Call `comp-add-cond-cstrs-simple'.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add test.
+
+2020-12-24 Philipp Stephani <phst@google.com>
+
+ Centralize subprocess creation in a single function.
+
+ Getting the vfork + execve combination right isn't easy, and the code
+ was partially duplicated between callproc.c and process.c. Centralize
+ the spawn operation in a single function that deals with the nasty
+ details. Going forward, we should be able to use posix_spawn from
+ either libc or Gnulib (or CreateProcessW on Windows) in the non-pty
+ case.
+
+ * src/callproc.c (emacs_spawn): New function to start an asynchronous
+ subprocess. Merge code from 'call_process' and 'create_process' into
+ this function.
+ (call_process): Use new 'emacs_spawn' function.
+ (child_setup): Make static, since there are no users outside this
+ compilation unit left.
+ (CHILD_SETUP_TYPE): Move from header file, since there are no users
+ outside this compilation unit left.
+
+ * src/process.c (create_process): Use new 'emacs_spawn' function.
+
+2020-12-24 Andrea Corallo <akrl@sdf.org>
+
+ Invert basic block argument order in LIMPLE cond-jump
+
+ * lisp/emacs-lisp/comp.el (comp-emit-cond-jump)
+ (comp-emit-switch, comp-emit-narg-prologue, comp-add-cond-cstrs):
+ Invert basic block argument order in LIMPLE cond-jump.
+ * src/comp.c (emit_limple_insn): Likewise.
+
+2020-12-24 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: introduce a new cache for brace structures. This fixes bug #45248
+
+ Also fix three infinite loops. The new cache accelerates backward searches
+ for struct beginnings in c-looking-at-or-maybe-in-bracelist.
+
+ * lisp/progmodes/cc-engine.el (c-beginning-of-statement-1): In the final loop
+ over unary operators, add a check (> (point) lim) to avoid certain infinite
+ loops.
+ (c-beginning-of-decl-1): In the first loop add a similar check on point and
+ lim.
+ (c-laomib-loop): New function extracted from
+ c-looking-at-or-maybe-in-bracelist.
+ (c-laomib-cache): New buffer local variable.
+ (c-laomib-get-cache, c-laomib-put-cache, c-laomib-fix-elt)
+ (c-laomib-invalidate-cache): New functions which implement the cache.
+ (c-looking-at-or-maybe-in-bracelist): Replace two invocations of
+ c-go-up-list-backwards with calls to c-parse-state. Extract the new function
+ c-laomib-loop. Insert code which calls c-laomib-loop minimally, with the help
+ of the new cache.
+
+ * lisp/progmodes/cc-mode.el (c-basic-common-init): Initialise the new cach
+ (at mode start).
+ (c-before-change): Invalidate the new cache.
+ (c-fl-decl-start): Add an extra check (> (point) bod-lim) to prevent looping.
+ Determine the enclosing brace to pass as arguments to
+ c-looking-at-or-maybe-in-bracelist.
+
+2020-12-24 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/dispnew.c (sit_for): Fix bug#45292
+
+ When reading, prefer staying in the selected-window over preserving
+ the current-buffer.
+
+2020-12-24 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/lisp-mnt.el (lm-section-end): Stop at the right heading
+
+ `lisp-outline-level` assumes the match-data is that set by
+ `outline-regexp`.
+
+2020-12-23 TEC <tec@tecosaur.com>
+
+ authinfo-mode: add option to not hide any elements (and add font-lock)
+
+ * lisp/auth-source.el (authinfo-hide-elements): New user option.
+ (authinfo--keywords): New variable.
+ (authinfo-mode): Use it.
+ (authinfo--hide-passwords): Use doc-face instead of warning for
+ the passwords.
+ (authinfo--toggle-display): Ditto.
+
+2020-12-23 Adam Porter <adam@alphapapa.net>
+
+ * lisp/tab-line.el: New options, faces, and functions
+
+ * lisp/tab-line.el:
+ (tab-line-tab-face-functions): New option.
+ (tab-line-tab-inactive-alternate): New face.
+ (tab-line-tab-special): New face.
+ (tab-line-tab-face-inactive-alternating): New function.
+ (tab-line-tab-face-special): New function.
+ (tab-line-format-template): Use them.
+
+ * etc/NEWS: Update.
+
+ With thanks to Juri Linkov and Eli Zaretskii for their guidance.
+
+2020-12-23 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-12-23 Philipp Stephani <phst@google.com>
+
+ * src/Makefile.in (DO_CODESIGN): Fix expected architecture name.
+
+2020-12-23 Philipp Stephani <phst@google.com>
+
+ Declare argument vector as char *const *.
+
+ This matches the signature of execve.
+
+ * src/callproc.c (child_setup): Declare NEW_ARGV as char *const *.
+
+2020-12-23 Philipp Stephani <phst@google.com>
+
+ * .clang-format (ColumnLimit): Fix line length.
+
+2020-12-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Support build of Emacs on ARM Macos machines
+
+ * configure.ac: Add support for aarch64-* on Macos (i.e., 64-bit
+ ARM) (bug#43369).
+
+2020-12-23 Philipp Stephani <phst@google.com>
+
+ Pass C string pointer to current directory to 'child_setup'.
+
+ This avoids the impression that 'child_setup' could do anything
+ Lisp-related.
+
+ * src/callproc.c (child_setup): Pass C pointer to current directory
+ name.
+ (call_process): Adapt callers.
+
+ * src/process.c (create_process): Adapt callers.
+
+2020-12-23 Andrea Corallo <akrl@sdf.org>
+
+ Negate only values while constraining variables (bug#45376)
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-value-negation): New
+ function.
+ * lisp/emacs-lisp/comp.el (comp-fwprop-insn): Use
+ `comp-cstr-value-negation'.
+ * test/src/comp-test-funcs.el (comp-test-45376-1-f): Rename.
+ (comp-test-45376-2-f): New function.
+ * test/src/comp-tests.el (bug-45376-1): Rename test.
+ (bug-45376-2): Add test.
+
+2020-12-23 Andrea Corallo <akrl@sdf.org>
+
+ Fix non range cstr union operation
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-union-homogeneous): Add
+ range parameter and handle the non range case.
+ (comp-cstr-union-1-no-mem, comp-cstr-intersection-no-mem): Update
+ `comp-cstr-union-homogeneous' call sites.
+
+2020-12-23 Philipp Stephani <phst@google.com>
+
+ Allocate environment block before forking.
+
+ While 'child_setup' carefully avoids calls to async-signal-unsafe
+ functions like 'malloc', it seems simpler and less brittle to use
+ normal allocation outside the critical section between 'fork' and
+ 'exec'.
+
+ * src/callproc.c (make_environment_block): New function to create the
+ environment block for subprocesses. Code largely extracted from
+ 'child_setup' and adapted to use 'xmalloc' instead of 'alloca'.
+ (child_setup): Remove environment block allocation in favor of
+ passing the environment block as command-line argument.
+ (call_process): Adapt to new calling convention.
+
+ * src/process.c (create_process): Adapt to new calling convention.
+
+2020-12-23 Andrea Corallo <akrl@sdf.org>
+
+ Follow cstr basic blocks to perform latch recognition
+
+ * lisp/emacs-lisp/comp.el (comp-fwprop-insn): Fix latch
+ recognition.
+
+2020-12-23 Philipp Stephani <phst@google.com>
+
+ Reject filenames containing NUL bytes.
+
+ Such filenames are dangerous, as Emacs would silently only use the
+ part up to the first NUL byte. Reject them explicitly instead.
+
+ * src/coding.c (encode_file_name_1): New helper function.
+ (encode_file_name): Check that encoded filename doesn't contain a
+ NUL byte.
+ (syms_of_coding): Define 'filenamep' symbol.
+
+ * test/src/fileio-tests.el (fileio-tests/null-character): New unit
+ test.
+
+ * etc/NEWS: Document change.
+
+2020-12-23 Philipp Stephani <phst@google.com>
+
+ Remove an unused parameter from 'child_setup' function.
+
+ * src/callproc.c (child_setup): Remove unused SET_PGRP parameter.
+
+ * src/callproc.c (call_process):
+ * src/process.c (create_process): Fix all callers.
+
+2020-12-23 Andrea Corallo <akrl@sdf.org>
+
+ Make input constraints into memoization hash immutable (bug#45376)
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-union-1)
+ (comp-cstr-intersection): Copy input before soting it into the
+ memoization hash table.
+
+2020-12-23 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-copy): Tweak for perf.
+
+2020-12-23 Juri Linkov <juri@linkov.net>
+
+ Show image as text when trying to search/replace in image buffer (bug#25905)
+
+ * lisp/image-mode.el (image-mode-isearch-filter): New function.
+ (image-mode--setup-mode): Use it to add it as :before-while to
+ isearch-filter-predicate.
+
+2020-12-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the string-limit doc string
+
+ * lisp/emacs-lisp/subr-x.el (string-limit): Mention
+ truncate-string-to-width in the doc string.
+
+2020-12-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow string-slice to take zero-length matches
+
+ * lisp/emacs-lisp/subr-x.el (string-slice): Allow zero-length
+ matches. Code adapted from s.el by Magnar Sveen.
+
+2020-12-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert recent server.el frame-focus changes
+
+ * lisp/server.el (server-switch-buffer, server-execute): Revert
+ 9cef8fc8cdb5e6e18c9cf617eed3808d67ca340e and
+ c5f2eb56c0164e87abc881955552e0b718921186. This change led to
+ regressions in non-new-frame circumstances.
+
+2020-12-23 Łukasz Stelmach <stlman@poczta.fm>
+
+ Handle gracefully href="" in base tags in shr
+
+ * net/shr.el (shr-tag-base): shr-parse-base can't handle empty
+ strings gracefully. Don't call it unless href is a non-empty
+ string (bug#45355).
+
+2020-12-23 Stefan Kangas <stefan@marxist.se>
+
+ Fix use of obsolete 'emergency' warning level
+
+ * src/alloc.c (display_malloc_warning): Use new style ':emergency'
+ warning level instead of obsolete 'emergency'.
+
+2020-12-23 Zajcev Evgeny <zevlg@yandex.ru>
+
+ Fix use of obsolete 'error' warning level
+
+ * src/fileio.c (auto_save_error): Use new style ':error' warning level
+ instead of obsolete 'error'.
+
+2020-12-23 Alan Third <alan@idiocy.org>
+
+ Use new NSString lisp methods
+
+ * src/nsfont.m (ns_otf_to_script):
+ (ns_registry_to_script):
+ (ns_get_req_script): Use NSString conversion methods.
+ * src/nsimage.m ([EmacsImage allocInitFromFile:]): Use NSString
+ conversion methods.
+ * src/nsmenu.m (ns_menu_show): Use NSString conversion methods.
+ * src/nsselect.m (symbol_to_nsstring):
+ (ns_string_to_pasteboard_internal): Use NSString conversion methods.
+ * src/nsterm.m (ns_term_init):
+ ([EmacsView initFrameFromEmacs:]): Use NSString conversion methods.
+ * src/nsxwidget.m (nsxwidget_webkit_uri):
+ (nsxwidget_webkit_title):
+ (js_to_lisp): Use NSString conversion methods.
+ (build_string_with_nsstr): Functionality replaced by NSString
+ extensions.
+
+2020-12-22 Liāu, Kiong-Gē 廖宮毅 <gongyi.liao@gmail.com> (tiny change)
+
+ Fix --with-nativecomp Windows build (bug#45303)
+
+ Liāu, Kiong-Gē 廖宮毅 <gongyi.liao@gmail.com>
+
+ * src/comp.c (eln_load_path_final_clean_up): Fix argument order.
+ * nt/mingw-cfg.site (ac_cv_func_strsignal): Force
+ `ac_cv_func_strsignal' to no.
+
+2020-12-22 Alan Mackenzie <acm@muc.de>
+
+ Align the word "Function" in profiler's headers over the actual functions
+
+ * lisp/profiler.el (profiler-report-render-calltree-1): Replace two
+ occurrences of "Function" with " Function".
+
+2020-12-22 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Ensure that Gnus servers are open(able) before searching them
+
+ * lisp/gnus/gnus-search.el (gnus-search-run-search): Imap servers need
+ to be opened (made into the "current server") before we manipulate the
+ nnimap-buffer.
+ (gnus-search-run-search): Sneakily fix regexp.
+ (gnus-search-indexed-parse-output): We need to pass the server name in
+ here, otherwise nnmaildir won't know how to make this the "current
+ server".
+
+2020-12-22 Alan Mackenzie <acm@muc.de>
+
+ Align profiler's header-line-format to column 0, to work correctly on tty's
+
+ * lisp/profiler.el (profiler-report-header-line-format): Propertize the first
+ space with 'display '(space :align-to 0).
+
+2020-12-22 Alan Mackenzie <acm@muc.de>
+
+ Re-order the items in `profiler-report' output.
+
+ Putting the usage figures first on the line will eliminate the truncation of
+ function names.
+
+ lisp/profiler.el (profiler-version): Change to "28.1".
+ (profiler-format): Enhance, so that a width of zero means print the string
+ without padding or truncation.
+ (profiler-report-cpu-line-format, profiler-report-memory-line-format): Amend
+ for the new layout. The number of places for the cpu samples has been reduced
+ from 19 to 12 (enough for ~30 years at 1,000 samples per second).
+ (profiler-report-line-format, profiler-report-describe-entry): Amend for the
+ new order of arguments to profiler-format.
+
+ etc/NEWS (Specialized Modes): Add an entry documenting this change.
+
+ doc/lispref/debugging.texi (Profiling): Describe the new ordering of the items
+ in place of the old ordering.
+
+2020-12-22 Michael Albinus <michael.albinus@gmx.de>
+
+ Reorganize Tramp header lines
+
+ * lisp/net/tramp.el: Move header lines Version, Package-Requires,
+ Package-Type and URL ...
+ * lisp/net/trampver.el: ... here.
+
+2020-12-22 Bastien Guerry <bzg@gnu.org>
+
+ Update to Org 9.4.4
+
+2020-12-22 Daniel Martín <mardani29@yahoo.es>
+
+ Fix wdired-get-filename when ls -F marks symlinks
+
+ * lisp/wdired.el (wdired-get-filename): In some systems like BSD or
+ macOS, "ls -F" marks symlinks with a trailing "@". Add logic
+ accounting for this so that wdired-get-filename returns the correct
+ filename. This change also fixes test "wdired-test-bug34915" on macOS
+ and BSD systems (bug#34915).
+
+2020-12-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make string-pad take an optional START parameter
+
+ * lisp/emacs-lisp/subr-x.el (string-pad): Alter the calling
+ convention.
+
+2020-12-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Change the string-limit parameter semantics
+
+ * lisp/emacs-lisp/subr-x.el (string-limit): Alter the calling
+ convention.
+
+2020-12-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further string-clean-whitespace tweaks
+
+ * lisp/emacs-lisp/subr-x.el (string-clean-whitespace): Put \r
+ back, which was mistakenly removed.
+
+2020-12-22 Dmitry Gutov <dgutov@yandex.ru>
+
+ (ruby-mode-set-encoding): Use 'save-restriction'
+
+ * lisp/progmodes/ruby-mode.el (ruby-mode-set-encoding):
+ Use 'save-restriction' (bug#45349).
+
+2020-12-21 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Tiny string-clean-whitespace simplification
+
+ * lisp/emacs-lisp/subr-x.el (string-clean-whitespace): Streamline by
+ treating replacement string as being literal and having fixed case.
+
+2020-12-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make string-chop-newline more efficient
+
+ * lisp/emacs-lisp/subr-x.el (string-chop-newline): Make more
+ efficient.
+
+2020-12-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make string-clean-whitespace work on non-ASCII whitespace, too
+
+ * lisp/emacs-lisp/subr-x.el (string-clean-whitespace): Also clean
+ up non-ASCII whitespace.
+
+2020-12-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add try-completion to the string shortdoc
+
+ * lisp/emacs-lisp/shortdoc.el (string): Mention try-completion here.
+
+2020-12-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add string-chop-newline
+
+ * doc/lispref/strings.texi (Creating Strings): Document it.
+ * lisp/emacs-lisp/subr-x.el (string-chop-newline): Add new function.
+
+2020-12-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix shorter-than-length case for string-limit
+
+ * lisp/emacs-lisp/subr-x.el (string-limit): Fix
+ shorter-than-length case.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Fix a test in auth-source-tests.el
+
+ * test/lisp/auth-source-tests.el
+ (auth-source-test-secrets-create-secret): Redefine `read-string'
+ respecting the original number of arguments.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Fix a bunch of known type specifiers
+
+ * lisp/emacs-lisp/comp.el (comp-known-type-specifiers): Fixes for:
+ =, string-search, substring.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Fix `comp-add-call-cstr' and add a test
+
+ * lisp/emacs-lisp/comp.el (comp-add-call-cstr): Fix it.
+ * test/src/comp-tests.el (assume-in-loop-1): New test.
+ * test/src/comp-test-funcs.el (comp-test-assume-in-loop-1-f): New
+ function.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Fix value type inference for doubly negate constraints
+
+ * lisp/emacs-lisp/comp.el (comp-fwprop-insn): Do not propagate in
+ case of double negation.
+ * test/src/comp-test-funcs.el (comp-test-assume-double-neg-f):
+ New function.
+ * test/src/comp-tests.el (assume-double-neg): New test.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Fix native compiler tests when they are bytecompiled
+
+ * test/lisp/emacs-lisp/comp-cstr-tests.el (comp-cstr-test-ts)
+ (comp-cstr-typespec-test, comp-cstr-typespec-tests-alist): Eval
+ also at compile time.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests)
+ (comp-tests-define-type-spec-test): Likewise.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Simplify correctly (or (integer 1 1) (not (integer 1 1))) as t
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-union-1-no-mem): Logic
+ update.
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Add a test.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Guarantee fwprop convergence and termination
+
+ * lisp/emacs-lisp/comp.el (comp-emit-call-cstr): Have new-mvar as
+ LHS *and* RHS when constraining in and to ensure monotonicity and
+ fwprop convergence.
+ (comp-fwprop): Raise a warning for debug reasons in case fwprop
+ does not converge within 100 iterations.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Allow for overlapping src and dst in cstr set operations
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-union-1-no-mem)
+ (comp-cstr-union-1, comp-cstr-intersection-no-mem)
+ (comp-cstr-intersection): Logic update.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Symplify type specifier (not t) as nil
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-intersection-no-mem):
+ Add logic.
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Add two tests.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Enhance type inference constraining function arguments
+
+ * lisp/emacs-lisp/comp.el: Add some commentary.
+ (comp-cond-cstrs-target-mvar): Rename and update docstring.
+ (comp-add-cond-cstrs): Update to use
+ `comp-cond-cstrs-target-mvar'.
+ (comp-emit-call-cstr, comp-lambda-list-gen, comp-add-call-cstr):
+ New functions.
+ (comp-add-cstrs): Call `comp-add-call-cstr'.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Update two
+ type specifier tests.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Allow for modifying insn-cell inside `comp-loop-insn-in-block'
+
+ * lisp/emacs-lisp/comp.el (comp-loop-insn-in-block): Update.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-cond-cstr into comp-add-cstrs
+
+ * lisp/emacs-lisp/comp.el (comp-add-cond-cstrs-target-mvar)
+ (comp-add-cond-cstrs, comp-add-cstrs): Rename comp-cond-cstr
+ -> comp-add-cstrs.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Two minors in comp.el
+
+ * lisp/emacs-lisp/comp.el (comp-known-func-cstr-h)
+ (comp-ret-type-spec): Style.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Add a type specifier test to comp-cstr-tests.el
+
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Add a test.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Enumerate and split type specifier tests in comp-tests.el to ease debug
+
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Enumerate.
+ (comp-tests-define-type-spec-test): New function.
+ (comp-tests-define-type-spec-tests): New macro to expand tests.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Improve constraint simplification logic in comp-cstr.el
+
+ * lisp/emacs-lisp/comp-cstr.el (with-comp-cstr-accessors):
+ Simplify.
+ (comp-cstr-empty-p): New Funchion.
+ (comp-split-pos-neg): Minor.
+ (comp-normalize-typeset): Logic update.
+ (comp-union-typesets): Minor.
+ (comp-intersect-two-typesets): New functio.
+ (comp-intersect-typesets): Logic update.
+ (comp-range-union, comp-range-intersection): Minor.
+ (comp-cstr-union-homogeneous, comp-cstr-union-1-no-mem)
+ (comp-cstr-intersection-homogeneous)
+ (comp-cstr-intersection-no-mem, comp-cstr-negation)
+ (comp-type-spec-to-cstr, comp-cstr-to-type-spec): Logic update.
+
+ * lisp/emacs-lisp/comp-cstr.el (with-comp-cstr-accessors): Simplify.
+
+2020-12-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Rename slice-string to string-slice
+
+ * lisp/emacs-lisp/subr-x.el (string-slice): Rename from slice-string.
+ * doc/lispref/strings.texi (Creating Strings): Ditto.
+
+2020-12-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add `string-pad'
+
+ * doc/lispref/strings.texi (Creating Strings): Document it.
+ * lisp/emacs-lisp/shortdoc.el (string): Add example.
+
+ * lisp/emacs-lisp/subr-x.el (string-pad): New function.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Fix a number of type specifier simplification tests
+
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Fix a number of tests.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Improve comp-fwprop pass
+
+ Wire-up comp-cstr.el routines in fwprop and constraint mvars also on
+ the else side of branches.
+
+ * lisp/emacs-lisp/comp.el (comp-emit-assume)
+ (comp-cond-cstr-target-mvar, comp-cond-cstr-func)
+ (comp-fwprop-insn): Logic update.
+ (comp-mvar-value-vld-p, comp-mvar-propagate, comp-fwprop-call):
+ Handle neg slot.
+
+2020-12-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Beef up the Emacs string utility set a bit
+
+ * doc/lispref/strings.texi (Modifying Strings): Document them.
+ * lisp/emacs-lisp/shortdoc.el (string): Add examples.
+
+ * lisp/emacs-lisp/subr-x.el (string-clean-whitespace)
+ (string-fill, string-limit, string-lines, slice-string): New
+ functions.
+
+2020-12-21 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/so-long.el: Decrease use of passive voice.
+
+ Suggested by Richard Stallman <rms@gnu.org>.
+
+2020-12-21 Eli Zaretskii <eliz@gnu.org>
+
+ Fix frame creation on X when tool bar is disabled
+
+ * src/xterm.c (handle_one_xevent): Restrict the fix for bug#44002
+ to situations when we are asked by the WM to create a window with
+ bogus 1x1 dimensions. (Bug#44794)
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Add mvar pretty print support when dumping LIMPLE
+
+ * lisp/emacs-lisp/comp.el (comp-prettyformat-mvar)
+ (comp-prettyformat-insn): New function.
+ (comp-log-func): Update to use `comp-prettyformat-insn'.
+ (comp-finalize-phis): Change LIMPLE phi format to ease
+ `comp-prettyformat-insn' destructuring.
+
+2020-12-21 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix permission problem in Tramp's copy-file
+
+ * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-directly):
+ Take care of PRESERVE-UID-GID.
+
+2020-12-21 Stefan Kangas <stefan@marxist.se>
+
+ * doc/misc/efaq.texi (New in Emacs 27): Add section.
+
+2020-12-21 Stefan Kangas <stefan@marxist.se>
+
+ Drop XEmacs support for EDE ELisp projects
+
+ * lisp/cedet/ede/proj-elisp.el (ede-proj-target-elisp): Remove
+ XEmacs support.
+ (ede-xemacs-compiler): Make obsolete.
+
+2020-12-21 Stefan Kangas <stefan@marxist.se>
+
+ * doc/misc/efaq.texi (Latest version of Emacs): Bump version.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ Fix Windows build link-time zlib error (bug#45303)
+
+ * src/lisp.h (md5_gz_stream): Declare.
+ * src/comp.c (accumulate_and_process_md5)
+ (final_process_md5, md5_gz_stream): Remove.
+ * src/decompress.c (accumulate_and_process_md5)
+ (final_process_md5, md5_gz_stream): Move from comp.c.
+
+2020-12-21 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (eln_load_path_final_clean_up): Fix call arg order (bug#45303).
+
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Fix sigmask store/restore.
+
+2020-12-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with entering Gnus groups when Gnus isn't running
+
+ * lisp/gnus/gnus-sum.el (gnus-update-summary-mark-positions):
+ Don't bug out when Gnus isn't running (bug#45330).
+
+2020-12-21 Dario Gjorgjevski <dario.gjorgjevski@gmail.com>
+
+ Make python-mode fontify more assignment statements
+
+ * lisp/progmodes/python.el (python-font-lock-assignment-matcher): New
+ function to match assignment statements.
+ (python-rx): Add `assignment-target' and `grouped-assignment-target'.
+ (python-font-lock-keywords-maximum-decoration): Add new matchers
+ (bug#45341).
+
+2020-12-21 Dmitry Gutov <dgutov@yandex.ru>
+
+ Generic-ify xref-location-column
+
+ * lisp/progmodes/xref.el (xref-location-column):
+ Create a generic from xref-file-location-column, to use in the
+ common rendering code (bug#36967).
+ (xref--insert-xrefs): Update accordingly.
+
+ * test/lisp/progmodes/xref-tests.el
+ (xref-matches-in-directory-finds-two-matches-on-the-same-line)
+ (xref-matches-in-directory-finds-an-empty-line-regexp-match):
+ Ditto.
+
+2020-12-21 Juri Linkov <juri@linkov.net>
+
+ De-duplicate lines in Xref buffers
+
+ * lisp/progmodes/xref.el (xref--insert-xrefs):
+ Render matches coming from the same line together (bug#36967).
+ (xref--item-at-point): Account for the above.
+
+2020-12-21 Philipp Stephani <phst@google.com>
+
+ Unbreak build after commit 1a0a11f7d2d1dbecb9f754b1e129d50e489058e6.
+
+ The commit only changed a comment in 'struct buffer', so the portable
+ dumper doesn't need to be adapted.
+
+ * src/pdumper.c (dump_buffer): Update hash for 'struct buffer'.
+
+2020-12-20 Alan Third <alan@idiocy.org>
+
+ Fix image cache lookup
+
+ * src/image.c (lookup_image): ignore_colors should be false as we want
+ to search for images with matching colors.
+
+2020-12-20 Alan Third <alan@idiocy.org>
+
+ Remove unnecessary string conversion
+
+ * src/nsfns.m (ns_set_represented_filename): NSString can load List
+ strings directly now.
+
+2020-12-20 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-12-20 Andrea Corallo <akrl@sdf.org>
+
+ Have native compiler always preserve multibyte strings (bug#45342)
+
+ * lisp/emacs-lisp/comp.el (comp-final): Escape multibyte string
+ when offloading compilation to child process.
+ * test/src/comp-test-funcs.el (comp-test-45342-f): New function
+ * test/src/comp-tests.el (bug-45342): New test
+
+2020-12-20 Juri Linkov <juri@linkov.net>
+
+ * lisp/simple.el (goto-line-read-args): Use number-at-point (bug#45199)
+
+ * lisp/subr.el (goto-char--read-natnum-interactive): Add the value of
+ point to the end of default values, and move function slightly higher.
+
+2020-12-20 Andrea Corallo <akrl@sdf.org>
+
+ Fix missing 'gcc_jit_type_get_const' macro definition (bug#45303).
+
+ * src/comp.c (gcc_jit_type_get_pointer): Define macro.
+
+2020-12-20 Michael Albinus <michael.albinus@gmx.de>
+
+ Improve make-process in Tramp
+
+ * doc/misc/tramp.texi (Remote processes): Remove INSIDE_EMACS
+ restriction.
+ (Frequently Asked Questions, External packages): Add indices.
+
+ * etc/NEWS: 'start-process-shell-command' and
+ 'start-file-process-shell-command' do not support the old calling
+ conventions any longer.
+
+ * lisp/subr.el (start-process-shell-command)
+ (start-file-process-shell-command): Remove old calling conventions.
+
+ * lisp/net/tramp-compat.el (remote-file-error): Remove, it isn't
+ necessary.
+
+ * lisp/net/tramp.el (tramp-handle-make-process): Remove special shell
+ handling. Support environment variables.
+
+ * test/lisp/net/tramp-tests.el
+ (tramp--test--deftest-direct-async-process): Skip for mock method.
+ (tramp--test-async-shell-command): Suppress `shell-command-sentinel'.
+ (tramp-test32-shell-command, tramp-test33-environment-variables):
+ Adapt tests.
+ (tramp-test32-shell-command-direct-async)
+ (tramp-test33-environment-variables-direct-async): New tests.
+
+2020-12-20 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Inhibit buffer hooks in temporary buffers
+
+ Give get-buffer-create an optional argument to inhibit buffer hooks
+ in internal or temporary buffers for efficiency (bug#34765).
+
+ * etc/NEWS: Announce new parameter of get-buffer-create and
+ generate-new-buffer, and that with-temp-buffer and with-temp-file
+ now inhibit buffer hooks.
+
+ * doc/lispref/buffers.texi (Buffer Names): Fix typo.
+ (Creating Buffers): Document new parameter of get-buffer-create and
+ generate-new-buffer.
+ (Buffer List, Killing Buffers): Document when buffer hooks are
+ inhibited.
+ (Current Buffer):
+ * doc/lispref/files.texi (Writing to Files): Document that
+ with-temp-buffer and with-temp-file inhibit buffer hooks.
+ * doc/lispref/internals.texi (Buffer Internals): Document
+ inhibit_buffer_hooks flag. Remove stale comment.
+ * doc/misc/gnus-faq.texi (FAQ 5-8):
+ * lisp/simple.el (shell-command-on-region): Fix indentation.
+
+ * lisp/files.el (kill-buffer-hook): Document when hook is inhibited.
+ (create-file-buffer):
+ * lisp/gnus/gnus-uu.el (gnus-uu-unshar-article):
+ * lisp/international/mule.el (load-with-code-conversion):
+ * lisp/mh-e/mh-xface.el (mh-x-image-url-fetch-image):
+ * lisp/net/imap.el (imap-open):
+ * lisp/net/mailcap.el (mailcap-maybe-eval):
+ * lisp/progmodes/flymake-proc.el
+ (flymake-proc--read-file-to-temp-buffer)
+ (flymake-proc--copy-buffer-to-temp-buffer): Simplify.
+
+ * lisp/subr.el (generate-new-buffer): Forward new optional argument
+ to inhibit buffer hooks to get-buffer-create.
+ (with-temp-file, with-temp-buffer, with-output-to-string):
+ * lisp/json.el (json-encode-string): Inhibit buffer hooks in buffer
+ used.
+
+ * src/buffer.c (run_buffer_list_update_hook): New helper function.
+ (Fget_buffer_create): Use it. Add optional argument to set
+ inhibit_buffer_hooks flag instead of comparing the buffer name to
+ Vcode_conversion_workbuf_name. All callers changed.
+ (Fmake_indirect_buffer, Frename_buffer, Fbury_buffer_internal)
+ (record_buffer): Use run_buffer_list_update_hook.
+ (Fkill_buffer): Document when buffer hooks are inhibited. Use
+ run_buffer_list_update_hook.
+ (init_buffer_once): Inhibit buffer hooks in Vprin1_to_string_buffer.
+ (Vkill_buffer_query_functions, Vbuffer_list_update_hook): Document
+ when hooks are inhibited.
+ * src/buffer.h (struct buffer): Update inhibit_buffer_hooks
+ commentary.
+ * src/coding.h (Vcode_conversion_workbuf_name):
+ * src/coding.c (Vcode_conversion_workbuf_name): Make static again
+ since it is no longer needed in src/buffer.c.
+ (code_conversion_restore, code_conversion_save, syms_of_coding):
+ Prefer boolean over integer constants.
+ * src/fileio.c (Finsert_file_contents): Inhibit buffer hooks in
+ " *code-converting-work*" buffer.
+ * src/window.c (Fselect_window): Fix grammar. Mention
+ window-selection-change-functions alongside buffer-list-update-hook.
+
+ * test/src/buffer-tests.el: Fix requires.
+ (buffer-tests-inhibit-buffer-hooks): New test.
+
+2020-12-20 Mattias Engdegård <mattiase@acm.org>
+
+ image-cache-size improvements
+
+ Implement for non-Cairo X11 and NS. Count masks as well, and
+ XImage objects on X11.
+
+ * src/image.c (image_size_in_bytes): New.
+ (image_frame_cache_size): Use image_size_in_bytes.
+ * src/nsterm.h:
+ * src/nsimage.m (ns_image_size_in_bytes, [EmacsImage sizeInBytes]):
+ New function and method.
+ * src/w32gui.h:
+ * src/w32term.c (w32_image_size): Update signature.
+
+2020-12-20 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Fix default value of gnus-registry-register-all: should be t
+
+ * lisp/gnus/gnus-registry.el (gnus-registry-register-all): This was
+ meant to default to t; only an oversight during code review left it as
+ nil.
+
+2020-12-19 Dmitry Gutov <dgutov@yandex.ru> (tiny change)
+
+ Jamie Beardslee <beardsleejamie@gmail.com>
+
+ * lisp/progmodes/project.el (project-execute-extended-command):
+ New command.
+ (project-prefix-map): Binding for it.
+
+2020-12-19 Andrea Corallo <akrl@sdf.org>
+
+ Add 'internal_condition_case_5' (bug#45303).
+
+ * src/lisp.h (internal_condition_case_4)
+ (internal_condition_case_5): Declare.
+ * src/eval.c (internal_condition_case_5): New function.
+ * src/comp.c (eln_load_path_final_clean_up): Use
+ 'internal_condition_case_5'.
+
+2020-12-19 Juri Linkov <juri@linkov.net>
+
+ * lisp/image-mode.el: Use one timer and lock for slow remote calls (bug#45256)
+
+ * lisp/image-mode.el (image-auto-resize-timer): New variable.
+ (image--window-state-change): Cancel previous timer and
+ remember new timer in image-auto-resize-timer.
+ (image--window-state-change): New variable.
+ (image-fit-to-window): When image-fit-to-window-lock is nil,
+ call image-toggle-display-image ignoring 'remote-file-error'.
+
+2020-12-19 Juri Linkov <juri@linkov.net>
+
+ No need to set isearch-input-method-function in isearch-transient-input-method
+
+2020-12-19 Andrea Corallo <akrl@sdf.org>
+
+ Add 'gcc_jit_type_get_const' to Windows dynamic load machinery (bug#45303).
+
+ * src/comp.c: Add 'gcc_jit_type_get_const' to windows dynamic
+ load machinery.
+
+2020-12-19 Stefan Kangas <stefan@marxist.se>
+
+ Convert apropos-internal from C to Lisp (Bug#44529)
+
+ This runs insignificantly faster in C, and is already fast enough on
+ reasonably modern hardware. We might as well lift it to Lisp.
+ This benchmark can be used to verify:
+
+ (benchmark-run 10 (apropos-command "test"))
+ => (0.12032415399999999 2 0.014772391999999995) ; C
+ => (0.13513192100000002 2 0.017216643000000004) ; Lisp
+
+ * lisp/subr.el (apropos-internal): New defun, converted from C.
+ * src/keymap.c (Fapropos_internal): Remove defun.
+ (apropos_accum): Remove function.
+ (apropos_predicate, apropos_accumulate): Remove variables.
+ (syms_of_keymap): Remove defsubr for Fapropos_internal, and
+ definitions of the above variables.
+ * test/src/keymap-tests.el (keymap-apropos-internal)
+ (keymap-apropos-internal/predicate): Move tests from here...
+ * test/lisp/subr-tests.el (apropos-apropos-internal)
+ (apropos-apropos-internal/predicate): ...to here.
+
+2020-12-19 Eli Zaretskii <eliz@gnu.org>
+
+ * lisp/face-remap.el (face-remap-set-base): Doc fix. (Bug#45264)
+
+2020-12-19 Vasilij Schneidermann <mail@vasilij.de>
+
+ Correct argument order in comment
+
+ * etc/ETAGS.EBNF (position): Correct comment.
+
+2020-12-19 Stefan Kangas <stefan@marxist.se>
+
+ Shorten some over-wide docstrings in functions and macros
+
+ * lisp/allout-widgets.el (allout-widgets-tally-string):
+ * lisp/array.el (array-mode):
+ * lisp/calc/calc-units.el (calc-spn):
+ * lisp/cedet/ede/generic.el (ede-generic-new-autoloader):
+ * lisp/cedet/semantic/analyze.el (semantic-analyze-find-tag-sequence-default)
+ (semantic-analyze-find-tag-sequence):
+ * lisp/cedet/semantic/bovine/c.el (semantic-c-evaluate-symbol-for-hideif):
+ * lisp/cedet/semantic/bovine/make.el (semantic-lex-make-command):
+ * lisp/cedet/semantic/db-typecache.el (semanticdb-typecache-include-tags):
+ * lisp/cedet/semantic/doc.el (semantic-documentation-for-tag):
+ * lisp/cedet/semantic/tag-ls.el (semantic--tag-attribute-similar-p):
+ * lisp/emacs-lisp/advice.el (ad-map-arglists):
+ * lisp/emacs-lisp/bytecomp.el (byte-constant2)
+ (byte-save-restriction, byte-catch-OBSOLETE, byte-unwind-protect):
+ * lisp/emacs-lisp/cl-generic.el (cl-generic-combine-methods):
+ * lisp/emacs-lisp/seq.el (seq-partition, seq-set-equal-p)
+ (seq-filter):
+ * lisp/faces.el (face-attribute-specified-or, face-equal):
+ * lisp/info.el (Info-prev-reference-or-link)
+ (Info-next-reference-or-link):
+ * lisp/isearch.el (with-isearch-suspended):
+ * lisp/kmacro.el (kmacro-step-edit-macro, kmacro-set-counter):
+ * lisp/org/org-agenda.el (org-agenda-filter-by-category):
+ * lisp/ses.el (ses-cell-symbol):
+ * lisp/w32-fns.el (w32-shell-dos-semantics): Shorten doc strings to
+ not exceed 80-column limits. (Bug#44858)
+
+2020-12-19 Stefan Kangas <stefan@marxist.se>
+
+ Shorten over-wide docstrings in variables
+
+ * lisp/cedet/semantic/util-modes.el (semantic-highlight-func-popup-menu):
+ * lisp/emacs-lisp/elint.el (elint-top-form-logged):
+ * lisp/erc/erc-dcc.el (erc-dcc-list):
+ * lisp/expand.el (expand-pos):
+ * lisp/font-lock.el (cpp-font-lock-keywords-source-depth):
+ * lisp/gnus/gnus-sum.el (gnus-sort-gathered-threads-function):
+ * lisp/gnus/message.el (message-cite-style-thunderbird):
+ * lisp/gnus/nnmh.el (nnmh-be-safe):
+ * lisp/gnus/nntp.el (nntp-open-telnet-envuser):
+ * lisp/international/mule-cmds.el (current-transient-input-method):
+ * lisp/net/tramp.el (tramp-file-name-structure):
+ * lisp/org/ob-R.el (org-babel-R-write-object-command):
+ * lisp/org/org-attach.el (org-attach-after-change-hook):
+ * lisp/org/org.el (org-stamp-time-of-day-regexp):
+ * lisp/progmodes/elisp-mode.el (elisp-xref-find-def-functions):
+ * lisp/progmodes/ruby-mode.el (ruby-block-mid-re):
+ * lisp/progmodes/verilog-mode.el (verilog-cache-enabled):
+ * lisp/term.el (term-scroll-end):
+ * lisp/textmodes/table.el (table-command-remap-alist)
+ (table-inhibit-auto-fill-paragraph, table-command-remap-alist):
+ * lisp/vc/ediff-diff.el (ediff-ignore-similar-regions):
+ * lisp/vc/ediff-wind.el (ediff-mouse-pixel-threshold):
+ * lisp/vc/smerge-mode.el (smerge-refine-ignore-whitespace):
+ * lisp/vc/vc.el (vc-log-short-style):
+ * lisp/view.el (view-exit-action): Shorten doc strings to not exceed
+ 80-column limits. (Bug#44858)
+
+2020-12-19 Stefan Kangas <stefan@marxist.se>
+
+ Shorten over-wide docstrings in defcustoms
+
+ * lisp/calc/calc.el (calc-embedded-announce-formula-alist)
+ (calc-embedded-open-formula, calc-embedded-close-formula)
+ (calc-matrix-mode):
+ * lisp/cedet/semantic/imenu.el (semantic-imenu-sort-bucket-function):
+ * lisp/emacs-lisp/find-func.el (find-feature-regexp):
+ * lisp/emulation/cua-base.el (cua-paste-pop-rotate-temporarily):
+ * lisp/emulation/viper-init.el (viper-fast-keyseq-timeout)
+ (viper-related-files-and-buffers-ring):
+ * lisp/emulation/viper-keym.el (viper-want-ctl-h-help):
+ * lisp/gnus/gnus-art.el (gnus-article-banner-alist):
+ * lisp/gnus/gnus-group.el (gnus-keep-same-level):
+ * lisp/gnus/gnus-score.el (gnus-adaptive-word-length-limit):
+ * lisp/gnus/gnus-sum.el (gnus-inhibit-user-auto-expire):
+ * lisp/gnus/gnus-uu.el (gnus-uu-ignore-files-by-type)
+ (gnus-uu-do-not-unpack-archives)
+ (gnus-uu-unmark-articles-not-decoded)
+ (gnus-uu-correct-stripped-uucode, gnus-uu-save-in-digest)
+ (gnus-uu-post-include-before-composing):
+ * lisp/gnus/gnus.el (gnus-use-long-file-name)
+ (gnus-install-group-spam-parameters):
+ * lisp/gnus/message.el (message-cite-style):
+ * lisp/gnus/nnmail.el
+ (nnmail-split-fancy-with-parent-ignore-groups)
+ (nnmail-cache-ignore-groups):
+ * lisp/ido.el (ido-rewrite-file-prompt-functions):
+ * lisp/mail/feedmail.el (feedmail-fiddle-plex-user-list)
+ (feedmail-spray-address-fiddle-plex-list):
+ * lisp/mh-e/mh-e.el (mh-annotate-msg-hook):
+ * lisp/net/imap.el (imap-process-connection-type):
+ * lisp/net/rcirc.el (rcirc-omit-threshold):
+ * lisp/net/tramp-sh.el (tramp-copy-size-limit):
+ * lisp/nxml/nxml-mode.el (nxml-default-buffer-file-coding-system):
+ * lisp/obsolete/landmark.el (landmark-max-stall-time):
+ * lisp/obsolete/tls.el (tls-checktrust):
+ * lisp/org/org-indent.el
+ (org-indent-mode-turns-off-org-adapt-indentation)
+ (org-indent-mode-turns-on-hiding-stars):
+ * lisp/org/org-protocol.el (org-protocol-project-alist):
+ * lisp/progmodes/cc-vars.el (c-doc-comment-style):
+ * lisp/progmodes/cperl-mode.el (cperl-indent-subs-specially):
+ * lisp/progmodes/flymake-proc.el (flymake-proc-allowed-file-name-masks):
+ * lisp/progmodes/hideif.el (hide-ifdef-expand-reinclusion-protection):
+ * lisp/simple.el (minibuffer-history-case-insensitive-variables):
+ * lisp/tab-bar.el (tab-bar-close-last-tab-choice):
+ * lisp/textmodes/reftex-vars.el
+ (reftex-special-environment-functions):
+ * lisp/vc/ediff-init.el (ediff-startup-hook, ediff-cleanup-hook)
+ (ediff-metachars):
+ * lisp/vc/ediff-merg.el (ediff-show-clashes-only):
+ * lisp/vc/ediff-mult.el (ediff-default-filtering-regexp): Shorten doc
+ strings to not exceed 80-column limits. (Bug#44858)
+
+2020-12-19 Mattias Engdegård <mattiase@acm.org>
+
+ Correct units and spacing in memory-report
+
+ * lisp/emacs-lisp/memory-report.el (memory-report--format):
+ Use IEC unit prefixes and a space before.
+
+2020-12-19 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Set indent-tabs-mode for c-mode in .dir-locals.el
+
+ * .dir-locals.el (c-mode): Enforce existing indent-tabs-mode
+ policy. (Bug#34765)
+
+2020-12-19 Eli Zaretskii <eliz@gnu.org>
+
+ Fix over-wide doc strings
+
+ * lisp/vc/ediff-init.el (ediff-before-flag-bol)
+ (ediff-after-flag-eol, ediff-before-flag-mol):
+ * lisp/org/org-ctags.el (org-ctags-open-link-functions):
+ * lisp/mail/feedmail.el (feedmail-sendmail-f-doesnt-sell-me-out):
+ * lisp/language/ethio-util.el (ethio-use-three-dot-question)
+ (ethio-quote-vowel-always, ethio-W-sixth-always):
+ * lisp/gnus/nnvirtual.el (nnvirtual-mapping-table)
+ (nnvirtual-mapping-offsets, nnvirtual-mapping-reads)
+ (nnvirtual-mapping-marks, nnvirtual-info-installed):
+ * lisp/gnus/gnus.el (charset):
+ * lisp/gnus/deuglify.el (gnus-outlook-deuglify-unwrap-stop-chars)
+ (gnus-outlook-deuglify-no-wrap-chars)
+ (gnus-outlook-deuglify-attrib-cut-regexp): Fix doc strings to not
+ exceed 80-column limits. (Bug#44858)
+
+2020-12-19 Andrea Corallo <akrl@sdf.org>
+
+ Clean-up 'internal_condition_case_4' orphan declaration (bug#45303).
+
+ * src/lisp.h (internal_condition_case_4): Declaration remove.
+
+2020-12-19 Andrea Corallo <akrl@sdf.org>
+
+ Move diagnostic pragmas out of namespace-scope (bug#45303).
+
+ Pragmas in GCC don't work reliably within function:
+ <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92696>
+
+ * src/comp.c (emit_static_object)
+ (Fcomp_native_driver_options_effective_p)
+ (Fcomp_libgccjit_version): Move pragmas out of name-scope.
+
+2020-12-19 Andrea Corallo <akrl@sdf.org>
+
+ Fix Windows libgccjit library name (bug#45303).
+
+ * lisp/term/w32-win.el (dynamic-library-alist): Fix Windows
+ libgccjit library name.
+ * src/emacs.c (syms_of_emacs): Likewise.
+
+2020-12-19 Roland Winkler <winkler@gnu.org>
+
+ bibtex-mode: Permit user-defined schemes for sorting entries.
+
+ * lisp/textmodes/bibtex.el (bibtex-maintain-sorted-entries):
+ New allowed value (INDEX-FUN PREDICATE).
+ (bibtex-entry-index, bibtex-lessp): Use it.
+ (bibtex-init-sort): Rename from bibtex-init-sort-entry-class-alist.
+
+2020-12-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/package.el (package-quickstart-refresh): Fix last change
+
+ Actually allow byte-compiling the file.
+ Reported by Basil L. Contovounesios <contovob@tcd.ie>.
+
+2020-12-18 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 48b9c47805 Minor fixes in authors.el and in tarball-making instructions
+ d7a4ceaa1e ; Add a new item to TODO
+ 64fe805b19 Improve documentation of 'query-replace'
+ 7cacf5da47 Update to Org 9.4.3
+
+ # Conflicts:
+ # admin/authors.el
+
+2020-12-18 João Távora <joaotavora@gmail.com>
+
+ Document that flymake-diag-region saves match data
+
+ The typical use of this function (which is parsing compiler diagnostic
+ messages), lends itself too easily to one the problems in bug#29193.
+ Make it a friendlier API.
+
+ * doc/misc/flymake.texi (Flymake utility functions): Document that
+ flymake-diag-region saves match data.
+
+ * lisp/progmodes/flymake.el (flymake-diag-region): Document that
+ this saves match data.
+
+2020-12-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/package.el: Byte compile the quickstart file
+
+ Earlier tests had found problems when byte-compiling the file,
+ but later investigations indicated the problem was not
+ directly related. The performance difference is appreciable.
+
+ (package-quickstart-refresh): Byte compile the file.
+ (package-activate-all): Load byte-compiled version if available.
+ (package--quickstart-maybe-refresh): Delete the byte-compiled file as well.
+
+2020-12-18 Eli Zaretskii <eliz@gnu.org>
+
+ Minor fixes in authors.el and in tarball-making instructions
+
+ * admin/authors.el (authors): Make the error message more helpful.
+ (authors-ignored-files, authors-renamed-files-alist): Update.
+
+2020-12-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/which-func.el (which-func-update): Bind `non-essential`
+
+2020-12-18 Mattias Engdegård <mattiase@acm.org>
+
+ Follow good regexp practice
+
+ These were found by relint 1.19.
+
+ * lisp/help-fns.el (help-fns--first-release): Use string-end instead
+ of line-end when matching a file name.
+ * lisp/org/ob-core.el (org-babel--string-to-number): Put hyphen last
+ in alternative.
+ * lisp/org/org-agenda.el (org-agenda-filter): Escape '+' correctly.
+
+2020-12-18 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp.el (tramp-handle-make-process): Handle shell commands.
+
+2020-12-18 João Távora <joaotavora@gmail.com>
+
+ Save match data in flymake-diag-region (bug#29193)
+
+ * lisp/progmodes/flymake.el (flymake-diag-region): Move
+ save-match-data up.
+
+2020-12-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous frame-focus server.el change
+
+ * lisp/server.el (server-execute): Always give Emacs focus,
+ whether we open a new frame or not.
+
+2020-12-18 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Fix regexp in IMAP search-string preparation
+
+ * lisp/gnus/gnus-search.el (gnus-search-run-search): This was failing
+ to catch all of X-GM-RAW.
+
+2020-12-18 Dmitry Gutov <dgutov@yandex.ru>
+
+ flymake-diag-region: Fix the recent test breakage
+
+ * lisp/progmodes/flymake.el (flymake-diag-region):
+ Make sure to save the match data (bug#29193).
+
+2020-12-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/org/org-refile.el (org-copy): Fix missing obsoletion version
+
+2020-12-17 Andrea Corallo <akrl@sdf.org>
+
+ Makefile.in (w32locallisppath): Add PATH_REL_LOADSEARCH (bug#45303).
+
+ * nt/epaths.nt (PATH_REL_LOADSEARCH): Define macro (bug#45303).
+
+2020-12-17 Michael Albinus <michael.albinus@gmx.de>
+
+ Some minor Tramp changes
+
+ * doc/lispref/os.texi (Timers): Speak about `remote-file-error'.
+
+ * doc/misc/tramp.texi (Frequently Asked Questions): Speak about
+ `remote-file-error'.
+ (External packages): New subsection "Timers".
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-make-process):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process): Adapt error
+ function. Handle coding.
+
+ * lisp/net/tramp.el (tramp-handle-make-process): Adapt error function.
+
+2020-12-17 Stefan Kangas <stefan@marxist.se>
+
+ Remove incorrect comment from erc-goodies.el
+
+ * lisp/erc/erc-goodies.el (erc-move-to-prompt-setup): Remove incorrect
+ comment; the XEmacs compat code has been removed.
+
+2020-12-17 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Fix my two most common causes of all windows/frames redisplay
+
+ * src/buffer.c (Fkill_all_local_variables): Only redisplay the buffer.
+ * src/window.c (set_window_scroll_bars): Only redisplay the window.
+
+2020-12-17 Zajcev Evgeny <zevlg@yandex.ru>
+
+ Make "Invalid modifier in string" ordinary invalid-read-syntax error
+
+ * src/lread.c (read1): Raise "Invalid modifier in string" error as
+ `invalid-read-syntax'. This fixes raise of unhandled error in
+ `elisp--local-variables'
+
+2020-12-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix fallback use of write-file in ido-mode
+
+ * lisp/ido.el (ido-file-internal): Make `write-file' respect the
+ directory we've navigated to (bug#28513).
+
+2020-12-17 Philipp Stephani <phst@google.com>
+
+ Ensure that byte compilation works for relative files (Bug#45287).
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-file): Don’t fail if
+ target filename doesn’t contain a directory name.
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (bytecomp-tests--target-file-no-directory): New unit test.
+
+2020-12-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Default the init file to init.el, not init
+
+ * lisp/startup.el (startup--load-user-init-file): Make the default
+ init file be "init.el", not "init" (bug#45197).
+
+2020-12-16 Pankaj Jangid <pankaj@codeisgreat.org>
+
+ Fix resetting of gnus-pick-line-number
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-read-group-1): Move setting
+ gnus-pick-line-number from here (bug#45269)...
+ (gnus-summary-prepare): To here. This ensures that the number is
+ reset when regenerating the buffer, for instance when limiting it.
+
+2020-12-16 Juri Linkov <juri@linkov.net>
+
+ Don't show minibuffer keybindings for suggestions in read-extended-command
+
+ * lisp/simple.el (read-extended-command): Use 'affixation-function'
+ instead of 'annotation-function'. (Bug#45035)
+ (read-extended-command--affixation): New function created from
+ 'read-extended-command--annotation'.
+
+2020-12-16 Juri Linkov <juri@linkov.net>
+
+ Give affixation-function higher priority over annotation-function (bug#45234)
+
+ * doc/lispref/minibuf.texi (Completion Variables)
+ (Programmed Completion): Describe precedence rules
+ of affixation-function and annotation-function.
+
+ * lisp/minibuffer.el (completion-metadata)
+ (completion-extra-properties): Describe precedence rules
+ of affixation-function and annotation-function.
+ (minibuffer-completion-help): First try to apply
+ affixation-function, if there is no such function,
+ try annotation-function.
+
+2020-12-16 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'query-replace'
+
+ * doc/emacs/search.texi (Query Replace): Add 'E' to the list of
+ characters one can type at 'query-replace' prompt. (Bug#45273)
+
+2020-12-16 Bastien Guerry <bzg@gnu.org>
+
+ Update to Org 9.4.3
+
+ Fix #45259
+
+2020-12-16 Harald Jörg <haj@posteo.de>
+
+ CPerl-mode: don't treat <<>> as starting a here-doc
+
+ * lisp/progmodes/cperl-mode.el (cperl-find-pods-heres): Detect
+ the "<<>>" operator (Bug#42455).
+
+ * test/lisp/progmodes/cperl-mode-tests.el
+ (cperl-test-bug-45255): Verify that <<>> does not start a
+ HERE-doc.
+
+2020-12-16 E. Choroba <choroba@matfyz.cz>
+
+ Update short docs in cperl-mode
+
+ * lisp/progmodes/cperl-mode.el (cperl-short-docs):
+ Update with some missing entries. (Bug#45254)
+
+2020-12-16 Dmitry Gutov <dgutov@yandex.ru>
+
+ (flymake-diag-region): Fall back to (end-of-thing 'symbol)
+
+ * lisp/progmodes/flymake.el (flymake-diag-region):
+ Fall back to (end-of-thing 'symbol) (bug#29193).
+
+2020-12-15 Eli Zaretskii <eliz@gnu.org>
+
+ Fix C-n/C-p when a line starts with an image
+
+ * src/xdisp.c (move_it_to): Handle the case where the second call
+ to move_it_in_display_line_to under MOVE_TO_Y takes us farther
+ from TO_CHARPOS than the first call. This fixes values returned
+ by pos-visible-in-window-p and posn-at-point when the screen line
+ starts with invisible text followed by an image. (Bug#9092)
+
+2020-12-15 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 668f0a7f84 Fix point location when completing in gdb-mi.el
+ 2dbc95063b Update to Org 9.4.2
+ f22856a5c5 Update to Org 9.4.1
+
+ # Conflicts:
+ # doc/misc/org.texi
+ # lisp/org/ob-core.el
+ # lisp/org/ob-ruby.el
+ # lisp/org/ob-screen.el
+ # lisp/org/ol-gnus.el
+ # lisp/org/ol.el
+ # lisp/org/org.el
+
+2020-12-15 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 62a6934af9 Fix crash when using XRender and restoring image from X (b...
+ de032d41c6 Bind k to image-kill-buffer in doc-view-mode-map.
+
+2020-12-15 Eli Zaretskii <eliz@gnu.org>
+
+ Fix setting breakpoints in "M-x gdb" when a source file is missing
+
+ * lisp/progmodes/gdb-mi.el (gdb-get-location): Fix control flow
+ logic when "fullname" is not found. Unquote and unescape the full
+ file name by calling gdb-mi--c-string-from-string. FLAG is a
+ string, not a character. (Bug#15051)
+
+2020-12-15 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Optimize for scrolling large buffers containing few braces
+
+ This fixes bug #25706. It particularly pertains to .h files which contain
+ only macro definitions. Many of these files are to be found, for example, in
+ the driver sections of the Linux kernel.
+
+ * lisp/progmodes/cc-engine.el (c-beginning-of-statement-1, c-on-identifier)
+ (c-syntactic-skip-backward, c-find-decl-prefix-search, c-find-decl-spots)
+ (c-forward-name, c-back-over-list-of-member-inits)
+ (c-back-over-member-initializers, c-looking-at-inexpr-block)
+ (c-guess-basic-syntax): Give search limits to, or amend existing ones to
+ c-backward-syntactic-ws, c-forward-syntactic-ws, c-backward-token-2,
+ c-beginning-of-statement-1.
+ (c-determine-limit-no-macro): New function.
+ (c-determine-limit-get-base): Remove unlimited invocation of
+ c-backward-syntactic-ws.
+ (c-determine-limit): Exclude movement between two different macros. Use new
+ function c-determine-limit-no-macro.
+ (c-back-over-list-of-member-inits): New parameter `limit'.
+
+ * lisp/progmodes/cc-fonts.el (c-font-lock-complex-decl-prepare)
+ (c-font-lock-declarations, c-font-lock-c++-using): Give search limits to, or
+ amend existing ones to c-backward-syntactic-ws, c-beginning-of-decl-1.
+
+ * lisp/progmodes/cc-mode.el (c-unfind-coalesced-tokens, c-before-changer)
+ (c-fl-decl-end): Give search limits to, or amend existing ones to
+ c-backward-syntactic-ws, c-forward-syntactic-ws, skip-chars-backward,
+ skip-chars-forward.
+
+2020-12-15 Michael Albinus <michael.albinus@gmx.de>
+
+ Revert last change in tramp-maybe-open-connection)
+
+ * lisp/net/tramp-sh.el (tramp-maybe-open-connection): Revert last change,
+ it causes trouble.
+
+2020-12-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix electric pairs in rst-mode
+
+ * lisp/textmodes/rst.el (rst-mode-syntax-table): Mark pairs in the
+ syntax table (bug#23413).
+ (rst-mode): Instead of setting electric-pair-pairs.
+
+2020-12-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Bind current-minibuffer-command to this-command
+
+ * src/callint.c (Fcall_interactively): Bind
+ current-minibuffer-command to this-command, as documented (bug#45177).
+
+2020-12-14 Glenn Morris <rgm@gnu.org>
+
+ * doc/lispref/errors.texi (Standard Errors): Fix xref.
+
+ Though I am not sure "report a bug" is helpful.
+
+2020-12-14 Glenn Morris <rgm@gnu.org>
+
+ * doc/emacs/indent.texi (Indent Convenience): Fix use of @xref.
+
+2020-12-14 Glenn Morris <rgm@gnu.org>
+
+ Tiny fix for lispref/variables.texi
+
+ * doc/lispref/variables.texi (Converting to Lexical Binding):
+ @strong{Note...} produces a spurious cross-reference in Info;
+ reword to avoid that.
+
+2020-12-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/gv.el (error): Allow it as a place
+
+2020-12-14 Alan Mackenzie <acm@muc.de>
+
+ Optimise c-font-lock-<>-arglists, particularly for buffers with few <..> pairs
+
+ * lisp/progmodes/cc-fonts.el (c-font-lock-<>-arglists): In place of a regexp
+ search for a complicated and slow regexp, search simply for "<" outside of
+ literals together with add hoc testing of other requirements for a <...>
+ match.
+
+ * lisp/progmodes/cc-langs.el (c-nonsymbol-key): New c-lang-defvar from the
+ c-lang-const.
+
+2020-12-14 Alan Third <alan@idiocy.org>
+
+ Fix error with fn key in NS port (bug#44533)
+
+ * src/nsterm.m ([EmacsView keyDown:]): Move the correction for fn key
+ handling to before the modifiers are calculated.
+
+ (cherry picked from commit 7970610d48701a949ce443c94c71eac47d044197)
+
+2020-12-14 Alan Mackenzie <acm@muc.de>
+
+ Optimise c-parse-state for large buffers with few (if any) braces.
+
+ * lisp/progmodes/cc-engine.el (c-get-fallback-scan-pos): Search a maximum of
+ 50,000 characters back for the two BODs. Return nil if we dont' find them.
+ (c-parse-state-get-strategy): For strategy `forward', always use the position
+ `good-pos' for `start-point', even when there's a change of current macro.
+ Deal with a possible return value of nil from c-get-fallback-scan-pos (as
+ above).
+ (c-invalidate-state-cache-1): For `c-state-cache-good-pos', instead of
+ sometimes using the minimum scan pos (leading to extensive scanning of the
+ entire buffer) use a point close to `here'.
+
+2020-12-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add some admin/emake comments
+
+2020-12-14 Gregory Heytings <ghe@sdf.org>
+
+ Make the emake error messages red
+
+ * admin/emake: Colorize error messages.
+
+2020-12-14 Michael Albinus <michael.albinus@gmx.de>
+
+ Add 'remote-file-error' for Tramp
+
+ * doc/lispref/errors.texi (Standard Errors): Add 'remote-file-error'.
+
+ * etc/NEWS: Mention 'remote-file-error'.
+
+ * lisp/net/ange-ftp.el (ftp-error): Add error condition
+ `remote-file-error'.
+
+ * lisp/net/tramp-cmds.el (tramp-cleanup-all-connections): Do not set
+ `tramp-locked'.
+
+ * lisp/net/tramp-compat.el (remote-file-error): Define if it
+ doesn't exist.
+
+ * lisp/net/tramp-sh.el (tramp-timeout-session): Check for "locked"
+ property.
+ (tramp-maybe-open-connection): Simplify.
+
+ * lisp/net/tramp.el (tramp-locked, tramp-locker): Remove them.
+ (tramp-file-name-handler): Do not set them.
+ (with-tramp-locked-connection): New defmacro.
+ (tramp-accept-process-output, tramp-send-string): Use it.
+
+ * src/fileio.c (Qremote_file_error): New error symbol.
+
+ * test/lisp/net/tramp-tests.el (tramp-test43-asynchronous-requests):
+ Adapt test. Remove :unstable tag.
+
+2020-12-14 Eli Zaretskii <eliz@gnu.org>
+
+ Improve accuracy of scrolling commands
+
+ * src/xdisp.c (move_it_vertically_backward): Don't rely on
+ line_bottom_y for accurate calculation of the next screen line's Y
+ coordinate: it doesn't work when the current screen line was not
+ yet traversed. Instead, record the previous Y coordinate and
+ reseat there if overshoot is detected.
+ * src/window.c (window_scroll_pixel_based): Calculate the new
+ window-start point more accurately when screen lines have uneven
+ height. (Bug#8355)
+
+2020-12-14 Stefan Kangas <stefan@marxist.se>
+
+ Make XEmacs entry in the FAQ more contemporary
+
+ * doc/misc/efaq.texi (Difference between Emacs and XEmacs): Make
+ XEmacs entry in the FAQ more contemporary. Remove part about re-using
+ XEmacs code; this is not likely to be relevant these days and in any
+ case is not a frequently asked question. (Bug#45235)
+
+2020-12-14 Eli Zaretskii <eliz@gnu.org>
+
+ Fix point location when completing in gdb-mi.el
+
+ * lisp/progmodes/gdb-mi.el (def-gdb-auto-update-handler): Don't
+ force window-start position, so that redisplay doesn't move point
+ when popping completion window below the GUD one. (Bug#45052)
+
+2020-12-14 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Fix logic of gnus-search-imap-handle-date
+
+ * lisp/gnus/gnus-search.el (gnus-search-imap-handle-date): Just
+ rewrite this whole ridiculous function.
+
+2020-12-14 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/play/5x5.el: Fix typo. Remove redundant :group args.
+
+2020-12-14 Tim Ruffing <crypto@timruffing.de> (tiny change)
+
+ * etc/emacs.service:
+
+ * etc/emacs.service (ExecStart): Make Emacs exit from systemd work
+ better (bug#45181).
+
+ The problem here is the exit code 15, which emacs will return *only* if
+ it has received SIGTERM. I believe what's happening here is that
+ emacsclient will call kill-emacs but not wait until the emacs server
+ has properly shut down. However, it's supposed to wait for the shutdown
+ as an "ExecStop" command according to "man systemd.service". So since
+ the process is still alive when emacsclient comes back, systemd will
+ still issue SIGTERM, making emacs return 15 (maybe after calling kill-
+ emacs again?!).
+
+2020-12-14 Robert Thorpe <rt@robertthorpeconsulting.com> (tiny change)
+
+ Mention how to handle user names with @ in rmail
+
+ * doc/emacs/rmail.texi (Remote Mailboxes): Mention how to work
+ around the problem with user names like foo@example.com (bug#16946).
+
+2020-12-14 Daniel Martín <mardani29@yahoo.es>
+
+ Make goto-char offer the number at point as default
+
+ * lisp/subr.el (read-natnum-interactive): New function to read natural
+ numbers for interactive functions.
+ * src/editfns.c (Fgoto_char): Call read-natnum-interactive from the
+ interactive definition of goto-char to offer the number at point as
+ default. Also expand the docstring to document this new interactive
+ behavior.
+ * doc/emacs/basic.texi (Moving Point): Expand the Emacs manual to
+ document this new behavior.
+ * etc/NEWS: And announce it (bug#45199).
+
+2020-12-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tool bar documentation clarification: Mention forcing updates
+
+ * doc/lispref/keymaps.texi (Tool Bar): Document that flipping the
+ status of a tool bar item doesn't necessarily update the visuals
+ (bug#42957).
+
+2020-12-14 Tomas Nordin <tomasn@posteo.net> (tiny change)
+
+ Fix narrow-to-defun in python-mode
+
+ * lisp/progmodes/python.el (python-nav--beginning-of-defun): Make
+ narrow-to-defun work better in classes (bug#40563).
+
+2020-12-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new recursively bound `current-minibuffer-command' variable
+
+ * doc/lispref/commands.texi (Command Loop Info): Document it
+ (bug#45177).
+
+ * src/callint.c (Fcall_interactively): Bind it.
+
+ * src/keyboard.c (syms_of_keyboard): Define
+ current-minibuffer-command.
+
+2020-12-14 Ulrich Ölmann <u.oelmann@pengutronix.de> (tiny change)
+
+ Add a DirectoryMode to the Emacs Server example
+
+ * doc/emacs/misc.texi (Emacs Server): Update example
+
+ * doc/emacs/misc.texi (Emacs Server): The socket containing directory
+ is per default created with permissions 0755 by the socket-unit.
+ However this is considered unsafe since commit [1], so enhance unit
+ example with systemd configuration directive `DirectoryMode=' to
+ create it with safe permissions, see
+ https://www.freedesktop.org/software/systemd/man/systemd.socket.html#DirectoryMode=
+
+ [1] 2003-04-12 "(server-socket-name): Use new safe location for socket."
+
+2020-12-14 Stefan Kangas <stefan@marxist.se>
+
+ Update value of frame-title-format in FAQ
+
+ * doc/misc/efaq.texi (Displaying the current file name in the
+ titlebar): Fix default value of frame-title-format.
+
+2020-12-14 Stefan Kangas <stefan@marxist.se>
+
+ Don't recommend setnu and wb-line-number
+
+ * doc/misc/efaq.texi (Displaying the current line or column): Remove
+ reference to third-party alternatives to display-line-numbers-mode.
+
+2020-12-14 Stefan Kangas <stefan@marxist.se>
+
+ Remove more references to old versions from FAQ
+
+ * doc/misc/efaq.texi (Learning how to do something)
+ (Installing Emacs, Emacs for GNUstep, Emacs for macOS): Remove more
+ references to Emacs 22 and older from FAQ.
+
+2020-12-14 Stefan Kangas <stefan@marxist.se>
+
+ Make XEmacs compat variable warning-level-aliases obsolete
+
+ * lisp/emacs-lisp/warnings.el (warning-level-aliases): Make obsolete.
+ (display-warning): Warn when using one of the warning levels defined
+ in above obsolete variable. (Bug#44849)
+ * lisp/url/url-proxy.el (url-find-proxy-for-url): Replace obsolete
+ warning type 'critical with :error.
+
+2020-12-14 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq to set+quote
+
+ * lisp/cedet/semantic/senator.el (senator-lazy-highlight-update):
+ * lisp/emulation/edt.el (edt-find, edt-restore-key)
+ (edt-remember):
+ * lisp/eshell/em-ls.el (eshell-ls--insert-directory):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-write-region):
+ * lisp/progmodes/hideif.el (hide-ifdef-mode):
+ * test/lisp/url/url-future-tests.el (url-future-tests): Prefer setq to
+ set+quote.
+
+2020-12-14 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/bookmark.el: Doc fix.
+
+2020-12-14 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Merge branch 'feature/integration-of-dictionary-el'
+
+ b6227446d9 Importing dictionary module
+ 658ec3ccee Renamed connection.el
+ e2ebffdd62 Renamed link.el
+ 723906c444 Removed some compatibility parts in dictionary
+ 5dc17d73b0 Add :version tag to defcustom statement
+ 49c250b388 Don't check coding-system-list for existence
+ 99a7e918c8 Don't check for existence of defface
+ 1773b9b687 Dictionary now uses button
+ 329b6a0210 Adding details page for dictionary
+ 837505075c Fix dictionary tooltip mode
+ 2f1e4fbc42 Support nil value for dictionary-server
+ 91ff1c8f7c Move placement of dictionary-tooltip-mouse-event
+ 28fe134971 Remove text property from empty line
+ 7ca331a4f9 Add history of search words to read-string
+ d5a4da25b0 * lisp/net/dictionary.el: Remove remnants of package
+ cc5f280378 * lisp/net/dictionary.el: Add lexical-binding:t
+ 09952ce434 Removed useless check for popup-menu
+ 81ebe86d8d Show error message when asking to match for nothing
+ 0044a2e888 * lisp/net/dictionary-connection.el: Add lexical-binding:t
+ f58443780c * lisp/net/dictionary-connection.el: Remove obsolete Version
+ 54a3964e29 Update GPL version
+ a557a103cc * lisp/net/dictionary-connection.el: Prefer defsubst
+ ffa7d6671d * lisp/net/dictionary.el: Prefer defsubst over defmacro
+ 4deb8618e4 * lisp/net/dictionary.el (dictionary-mode): Use setq-local
+ d30618cbc1 * lisp/net/dictionary.el (dictionary-tooltip-mode): Use ...
+ a25a12ddaf Use when where else case returns nil
+ 89e9c1686e * lisp/net/dictionary.el (dictionary-display-more-info): ...
+ d466231c3e A number of docstring fixes
+ b18217eb87 A number of docstring fixes
+ ca0de4d1e0 * etc/NEWS: Add entry for dictionary.el
+ 62d14e10f9 * lisp/net/dictionary.el (dictionary-pre-buffer): Unify casing
+
+2020-12-14 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ * lisp/net/dictionary.el (dictionary-pre-buffer): Unify casing
+
+ Let all the buttons begins with an upper-case character and the rest of
+ the text is lower-case.
+
+2020-12-14 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ * etc/NEWS: Add entry for dictionary.el
+
+2020-12-14 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ A number of docstring fixes
+
+ * lisp/net/dictionary-connection.el (dictionary-connection-p,
+ dictionary-connection-read-point, dictionary-connection-process,
+ dictionary-connection-buffer, dictionary-connection-set-read-point,
+ dictionary-connection-set-process, dictionary-connection-set-buffer,
+ dictionary-connection-create-data, dictionary-connection-open,
+ dictionary-connection-status, dictionary-connection-close,
+ dictionary-connection-send, dictionary-connection-send-crlf,
+ dictionary-connection-read, dictionary-connection-read-crlf,
+ dictionary-connection-read-to-point): Fix docstring
+
+2020-12-14 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ A number of docstring fixes
+
+ * lisp/net/dictionary.el (dictionary-set-server-var, dictionary-mode,
+ dictionary, dictionary-new-buffer, dictionary-reply-code,
+ dictionary-reply, dictionary-reply-list, dictionary-open-server,
+ dictionary-check-connection, dictionary-mode-p, dictionary-close,
+ dictionary-read-reply, dictionary-split-string,
+ dictionary-read-reply-and-split, dictionary-read-answer,
+ dictionary-check-reply, dictionary-coding-system,
+ dictionary-decode-charset, dictionary-encode-charset,
+ dictionary-check-initial-reply, dictionary-store-state,
+ dictionary-restore-state, dictionary-new-search,
+ dictionary-new-search-internal, dictionary-do-search,
+ dictionary-pre-buffer, dictionary-post-buffer,
+ dictionary-display-search-result, dictionary-display-word-entry,
+ dictionary-display-word-definition, dictionary-mark-reference,
+ dictionary-select-dictionary, dictionary-display-dictionarys,
+ dictionary-display-dictionary-line, dictionary-set-dictionary,
+ dictionary-special-dictionary, dictionary-display-more-info,
+ dictionary-select-strategy, dictionary-do-select-strategy,
+ dictionary-display-strategies, dictionary-display-strategy-line,
+ dictionary-set-strategy, dictionary-new-matching,
+ dictionary-do-matching, dictionary-display-only-match-result,
+ dictionary-display-match-result, dictionary-display-match-result,
+ dictionary-display-match-lines, dictionary-search,
+ dictionary-previous, dictionary-help, dictionary-match-words,
+ dictionary-mouse-popup-matching-words,
+ dictionary-popup-matching-words, dictionary-tooltip-mode,
+ dictionary-tooltip-mouse-event): Fix docstring
+
+ The following kind of changes were made:
+
+ - finish first line with a full stop (.)
+ - mention parameter in upper-case whenever possible (considering the
+ length constraints)
+
+2020-12-14 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ * lisp/net/dictionary.el (dictionary-display-more-info): Spelling fix
+
+ Fix the spelling in the error message for non-existing dictionary.
+
+2020-12-14 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Use when where else case returns nil
+
+ * lisp/net/dictionary-connection.el (dictionary-connection-status,
+ dictionary-connection-close): Instead of returning nil in the else case
+ of the if just use when.
+
+ Was suggested by Stefan Kangas.
+
+2020-12-14 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ * lisp/net/dictionary.el (dictionary-tooltip-mode): Use setq-local
+
+ * lisp/net/dictionary.el (dictionary-mode): Use setq-local
+
+ * lisp/net/dictionary.el: Prefer defsubst over defmacro
+
+2020-12-14 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ * lisp/net/dictionary-connection.el: Prefer defsubst
+
+ Use defsubst instead of defmacro here. It was suggested by Stefan
+ Kangas to replace the defmacro here and, looking at the lispref,
+ defsubst seems to be a suitable replacement providing the same
+ benefit of inlining functionality as the defmacro.
+
+2020-12-14 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Update GPL version
+
+ * lisp/net/dictionary.el: Use GPL version 3 or later
+ * lisp/net/dictionary-connection.el: Use GPL version 3 or later
+
+2020-12-14 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ * lisp/net/dictionary-connection.el: Remove obsolete Version
+
+ * lisp/net/dictionary-connection.el: Add lexical-binding:t
+
+2020-12-14 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Show error message when asking to match for nothing
+
+ * lisp/net/dictionary.el (dictionary-popup-matching-words): Show error
+ if neither the parameter nor the word at point are defined
+
+ This avoids an error later on when the nil value is used as string
+ within dictionary-encode-charset.
+
+2020-12-14 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Removed useless check for popup-menu
+
+ * lisp/net/dictionary.el (dictionary-popup-matching-words): No need to
+ check for popup-menu, the code is part of Emacs now and the function
+ should always be there
+
+2020-12-14 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ * lisp/net/dictionary.el: Add lexical-binding:t
+
+ Fixing all the issues found by this. A number of unused variables were
+ reported here.
+
+2020-12-14 Gabriel do Nascimento Ribeiro <gabriel.nascimento@nubank.com.br>
+
+ New option tab-bar-history-buttons-show
+
+ * lisp/tab-bar.el (tab-bar-history-buttons-show): If true,
+ show back and forward buttons when tab-bar-history-mode
+ is enabled. (Bug#45227)
+
+ Copyright-paperwork-exempt: yes
+
+2020-12-14 Juri Linkov <juri@linkov.net>
+
+ Allow creating a new tab for tab-switcher from the minibuffer (bug#45072)
+
+ * lisp/tab-bar.el (tab-switcher): Simplify by let-binding
+ tab-bar-new-tab-choice to t before calling tab-bar-new-tab
+ that handles the case when it's called in the active minibuffer.
+
+2020-12-14 Juri Linkov <juri@linkov.net>
+
+ Don't show matches with no input for nil icomplete-show-matches-on-no-input
+
+ * lisp/icomplete.el (icomplete-show-matches-on-no-input): Fix docstring.
+ (icomplete--initial-input): New internal variable.
+ (icomplete-minibuffer-setup): Set buffer-local
+ icomplete--initial-input to icomplete--field-string.
+ (icomplete-ret, icomplete-force-complete-and-exit)
+ (icomplete--sorted-completions, icomplete-exhibit):
+ Compare icomplete--initial-input with icomplete--field-string
+ to detect no input. (Bug#19031)
+
+ etc/NEWS: Remove duplicate entry.
+
+2020-12-14 João Távora <joaotavora@gmail.com>
+
+ Inhibit quit in ElDoc timer functions (bug#45117)
+
+ The point of un-inhibiting it was to make ElDoc backends interruptible
+ with any input (as in while-no-input), since that should in principle
+ invalidate the need of the current ElDoc processing. But that
+ strategy is dangerous for backends that perform complex
+ synchronization with external processes. Better let each backend
+ decide for itself it needs this eager interruptive behavior, like is
+ presumably the case with the Octave backend.
+
+ This reverts a part of
+
+ commit 12e922156c86a26fa4bb2cb9e7d2b3fd639e4707
+ Author: Stefan Monnier <monnier@iro.umontreal.ca>
+ Date: Tue Dec 4 18:15:44 2018 -0500
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-print-current-symbol-info):
+
+ * lisp/progmodes/octave.el (octave-eldoc-function-signatures): Use
+ while-no-input.
+
+2020-12-13 Bastien Guerry <bzg@gnu.org>
+
+ Update to Org 9.4.2
+
+ Mostly fixing compiler warnings.
+
+2020-12-13 Dmitry Gutov <dgutov@yandex.ru>
+ Philip K. <philipk@posteo.net>
+
+ Remove the duplication from project-switch-commands's config
+
+ Based on an older patch by Philip K (https://debbugs.gnu.org/41890#127).
+
+ * lisp/progmodes/project.el: (project-switch-commands): Change to
+ 'defcustom', alter the value format, add :type.
+ (project-switch-use-entire-map): New option.
+ (project--keymap-prompt, project-switch-project):
+ Update accordingly, while keeping compatibility with user-defined
+ values in the previous format (for some transition period).
+
+2020-12-13 Philipp Stephani <phst@google.com>
+
+ Byte compilation: handle case where the output file is a mountpoint.
+
+ See Bug#44631. While testing for a readonly output directory has
+ slightly different semantics, in practice they should cover cases
+ where Emacs is sandboxed and can only write to the destination file,
+ not its directory.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-file): Handle the case
+ where the output directory is not writable.
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (bytecomp-tests--not-writable-directory)
+ (bytecomp-tests--dest-mountpoint): New unit tests.
+
+2020-12-13 Mauro Aranda <maurooaranda@gmail.com>
+
+ Stop dropping the tag when creating the custom-variable widget
+
+ * lisp/cus-edit.el (custom-variable-value-create): Obey the specified
+ tag format when creating the variable tag, but stop dropping the tag
+ format for the variable's type widget, since the tag can be used to
+ give useful information to the user about the variable. (Bug#35133)
+
+2020-12-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make dired-toggle-read-only query on read-only directories
+
+ * lisp/dired.el (dired-toggle-read-only): Query instead of
+ erroring out immediately (bug#29412).
+
+2020-12-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify Extended Menu Items a bit more
+
+ * doc/lispref/keymaps.texi (Extended Menu Items): Expand a bit
+ more on how submenus are formed (bug#26428).
+
+2020-12-13 Bastien Guerry <bzg@gnu.org>
+
+ Update to Org 9.4.1
+
+2020-12-13 Andrea Corallo <akrl@sdf.org>
+
+ Fix `memory-report' for '--without-x' builds
+
+ * lisp/emacs-lisp/memory-report.el
+ (memory-report--image-cache): Don't call `image-cache-size' if
+ unbound.
+
+2020-12-13 Dmitry Gutov <dgutov@yandex.ru>
+
+ Bump project.el version
+
+ * lisp/progmodes/project.el: Bump the version.
+
+2020-12-13 Andrii Kolomoiets <andreyk.mad@gmail.com>
+
+ vc-create-tag: use vc-revision-history variable
+
+ * lisp/vc/vc.el (vc-create-tag): Use 'vc-revision-history' variable.
+
+2020-12-13 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix test failure
+
+ * test/lisp/vc/vc-tests.el (vc-test--working-revision):
+ Accept working revision -1, expected for older Hg (bug#36534).
+
+2020-12-13 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/bytecomp.el: Allow a nil destination file
+
+ (byte-compile--default-dest-file): New function, extracted from
+ byte-compile-dest-file.
+ (byte-compile-dest-file): Use it.
+ (byte-compile-dest-file-function): Give it a non-nil default value.
+ (byte-recompile-file, byte-compile-file): Handle a nil return value
+ from `byte-compile-dest-file`.
+
+ * lisp/progmodes/elisp-mode.el (elisp-flymake--batch-compile-for-flymake):
+ Tell the compiler not to write the result, instead of writing it to
+ a dummy temp file.
+
+2020-12-13 Andrea Corallo <akrl@sdf.org>
+
+ Allow for adding constraints targeting blocks with multiple predecessors
+
+ This commit remove the limitaiton we had not being able to add
+ constraints derived from conditional branches to basic blocks with
+ multiple predecessors. When this condition is verified we add a new
+ dedicated basic block to hold the constraints.
+
+ * lisp/emacs-lisp/comp.el (comp-block, comp-edge): Better slot
+ type specifiers.
+ (comp-block-cstr): New struct specializing `comp-block'.
+ (make-comp-edge): New function.
+ (comp-func): Better test function + doc for `blocks' slot.
+ (comp-limple-lock-keywords): Update possible basic block names.
+ (comp-emit-assume): Receive directly the block instead of its name.
+ (comp-add-new-block-beetween): New function.
+ (comp-cond-cstr-target-block): Logic update and use
+ `comp-add-new-block-beetween'.
+ (comp-cond-cstr-func): Make use of the latter.
+ (comp-compute-edges): Make use of `make-comp-edge'.
+
+2020-12-13 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-cond-rw -> comp-cond-cstr
+
+ * lisp/emacs-lisp/comp.el (comp-passes)
+ (comp-cond-cstr-target-slot, comp-cond-cstr-func)
+ (comp-cond-cstr): Rename pass from cond-rw to cond-cstr.
+
+2020-12-13 Andrea Corallo <akrl@sdf.org>
+
+ Memoize `comp-cstr-intersection'
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-ctxt): Add new slot
+ `intersection-mem'.
+ (comp-cstr-intersection-homogeneous): Fix non local exit target.
+ (comp-cstr-intersection-no-mem): Rename from
+ `comp-cstr-intersection'.
+ (comp-cstr-intersection): New function.
+
+2020-12-13 Andrea Corallo <akrl@sdf.org>
+
+ Add initial negated non-negegated intersection support
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-range-intersection): Cosmetic.
+ (comp-cstr-intersection-homogeneous): Rename from
+ `comp-cstr-intersection'.
+ (comp-cstr-intersection): New function.
+
+2020-12-13 Alan Third <alan@idiocy.org>
+
+ Fix assertion on SVG load failure
+
+ * src/image.c (svg_load_image): Move setting DPI to after rsvg_handle
+ error checking.
+
+2020-12-12 Stefan Kangas <stefan@marxist.se>
+
+ Remove references to Emacs before version 22 from FAQ
+
+ * doc/misc/efaq.texi (Escape sequences in shell output): Remove
+ reference to versions before Emacs 21.
+ (Basic editing, Latest version of Emacs)
+ (Turning on abbrevs by default, Going to a line by number)
+ (Security risks with Emacs): Remove references to versions before
+ Emacs 22.
+
+2020-12-12 Philipp Stephani <phst@google.com>
+
+ Document and enforce some properties for strings created by modules.
+
+ When creating multibyte or unibyte strings, we should guarantee the
+ following invariants:
+
+ - When creating empty strings, a NULL data pointer should be allowed.
+ This often arises in practice if the string length isn't known in
+ advance, and we don't want to unnecessarily trigger undefined
+ behavior. Since functions like memcpy might not accept NULL
+ pointers, use the canonical empty string objects in this case.
+
+ - Nonzero strings should be guaranteed to be unique and mutable.
+ These are the same guarantees expected from Lisp functions such as
+ 'make-string' or 'unibyte-string'. On the other hand, empty strings
+ might not be unique.
+
+ * src/emacs-module.c (module_make_string)
+ (module_make_unibyte_string): Correctly handle empty strings.
+
+ * test/src/emacs-module-resources/mod-test.c (Fmod_test_make_string):
+ New test function.
+ (emacs_module_init): Expose it.
+
+ * test/src/emacs-module-tests.el (mod-test-make-string/empty)
+ (mod-test-make-string/nonempty): New unit tests.
+
+ * doc/lispref/internals.texi (Module Values): Document properties and
+ corner cases for strings.
+
+2020-12-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix BSD .include etc syntax in Makefiles
+
+ * lisp/progmodes/make-mode.el (makefile-bsdmake-statements): Fix
+ the BSD conditional syntax (bug#24000).
+ (makefile-make-font-lock-keywords): Allow calling without keywords.
+ (makefile-bsdmake-font-lock-keywords): Add the conditional syntax.
+
+ Makefile inclusion, conditional structures and for loops reminiscent of
+ the C programming language are provided in make. All such structures are
+ identified by a line beginning with a single dot (`.') character.
+ Whitespace characters may follow this dot, e.g.,
+
+ .include <file>
+ and
+ . include <file>
+
+ are identical constructs
+
+2020-12-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Bind `C-c C-d' to rmail-epa-decrypt in rmail
+
+ * doc/emacs/rmail.texi (Rmail Display): Mention the key
+ binding (bug#25411).
+
+ * lisp/mail/rmail.el (rmail-mode-map): Bind C-c C-d to
+ rmail-epa-decrypt.
+ (rmail-mode): Mention it.
+ (rmail-epa-decrypt): Don't mark a mail as decrypted unless we're
+ replacing it.
+
+ * lisp/mail/rmailsum.el (rmail-summary-mode-map): Bind C-c C-d.
+ (rmail-summary-epa-decrypt): New command.
+
+2020-12-12 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ New option gnus-registry-register-all
+
+ * lisp/gnus/gnus-registry.el (gnus-registry-register-all): If nil,
+ the registry won't automatically create new entries for all seen
+ messages. Defaults to t to preserve previous behavior.
+ (gnus-registry-handle-action): Don't automatically create entries; if
+ one doesn't exist, don't handle anything.
+ (gnus-registry-register-message-ids): Only register if this option is
+ t.
+ (gnus-registry-get-or-make-entry): Add optional no-create argument.
+ (gnus-registry-get-id-key): This "get" operation should only create an
+ entry if this option is t.
+ * doc/misc/gnus.texi: Documentation and news.
+
+2020-12-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/package.el (package-buffer-info): Improve error message
+
+ (package-strip-rcs-id): Return canonicalized version string.
+
+2020-12-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/fns.c (hash_string): Tweak the code further
+
+ Merge the two main branches; remove the `max` test and thus reduce
+ the "most steps" to 8 as written
+
+2020-12-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/vc/log-edit.el: Keep separator line thin even with line-numbers
+
+ (log-edit-font-lock-keywords): Disable line-number display on
+ the thin separator line.
+ (log-edit-mode): Adjust `font-lock-extra-managed-props` accordingly.
+ (log-edit-changelog-entries): Don't use a nil buffer-local
+ `change-log-default-name`.
+
+2020-12-12 Eli Zaretskii <eliz@gnu.org>
+
+ Followup to recent changes in keyboard.c
+
+ * src/keyboard.c (prev_kbd_event): Now defined only if HAVE_X11.
+
+ * lisp/subr.el (while-no-input-ignore-events): Remove
+ 'buffer-switch': no longer used or defined. (Bug#5803)
+
+2020-12-12 Andrea Corallo <akrl@sdf.org>
+
+ Normalize cstrs for cache hint effectiveness and test stability
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-normalize-valset)
+ (comp-union-valsets, comp-intersection-valsets)
+ (comp-normalize-typeset): New functions.
+ (comp-union-typesets, comp-intersect-typesets)
+ (comp-cstr-union-homogeneous-no-range, comp-cstr-union-1-no-mem):
+ Update to return normalized results.
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Normalize expected type specifiers.
+
+2020-12-12 Andrea Corallo <akrl@sdf.org>
+
+ Add `comp-split-pos-neg' function
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-split-pos-neg): New function.
+ (comp-cstr-union-1-no-mem): Update to call `comp-split-pos-neg'.
+
+2020-12-12 Andrea Corallo <akrl@sdf.org>
+
+ Enumerate type specifier tests to ease debugging
+
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Enumerate tests.
+
+ Acked-by: Andrea Corallo <akrl@sdf.org>
+
+2020-12-12 Andrea Corallo <akrl@sdf.org>
+
+ Code rework add `comp-cstrs-homogeneous'
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstrs-homogeneous): New
+ function.
+ (comp-cstr-union-1-no-mem): Make use of.
+
+2020-12-12 Andrea Corallo <akrl@sdf.org>
+
+ * test/src/comp-tests.el (comp-tests-bootstrap): Temp fix bootstrap test.
+
+2020-12-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some unused process.c variables
+
+ * src/process.c (wait_reading_process_output): Remove some
+ variables that are unused after the previous patch.
+
+2020-12-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ New variable `redisplay_adhoc_scroll_in_resize_mini_windows`
+
+ * src/xdisp.c (syms_of_xdisp): Define it.
+ (resize_mini_window): Obey it.
+
+2020-12-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/keyboard.c: Fix bug#5803.
+
+ A long time ago, `read_key_sequence` used to read the keymaps at the
+ start, so if something happened between this start and the moment
+ the user actually hits a key, `read_key_sequence` could end up using
+ the wrong keymaps. To work around this problem, the code used
+ `record_asynch_buffer_change` to try and trigger `read_key_sequence`
+ to re-read the keymaps in some known cases.
+
+ Several years ago, `read_key_sequence` was changed so as to read the keymaps
+ only once the user hits a key, making this machinery now redundant
+ (and also harmful apparently in bug#5803 because it introduces
+ "spurious" events).
+
+ So we here remove `record_asynch_buffer_change` and the
+ `BUFFER_SWITCH_EVENT` and `Qbuffer_switch` pseudo-events it generated.
+
+ * src/termhooks.h (enum event_kind): Delete `BUFFER_SWITCH_EVENT`.
+ * src/keyboard.c: (record_asynch_buffer_change): Delete function.
+ (syms_of_keyboard): Delete `Qbuffer_switch`.
+ (force_auto_save_soon, readable_events)
+ (kbd_buffer_store_buffered_event, kbd_buffer_get_event)
+ (make_lispy_event):
+ * src/xterm.c (handle_one_xevent):
+ * src/w32term.c (w32_read_socket):
+ * src/process.c (wait_reading_process_output)
+ (read_and_dispose_of_process_output, exec_sentinel): Simplify accordingly.
+
+2020-12-12 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Handle several K&R parameters per declaration
+
+ This fixes bug #45160.
+
+ * lisp/progmodes/cc-engine.el (c-in-knr-argdecl): Reformulate the latter part
+ of this function using c-do-declarators.
+
+2020-12-12 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-12-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Alter the "Redundant pcase patter" warning message
+
+ * lisp/emacs-lisp/pcase.el (pcase--expand): Make the "Redundant
+ pcase pattern" warning less vague (bug#31350).
+
+2020-12-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make elint load `require'd packages
+
+ * lisp/emacs-lisp/elint.el (elint-require-form): New function to
+ load files that are `require'd (bug#27006).
+ (elint-special-forms): Add function.
+
+2020-12-12 Zajcev Evgeny <zevlg@yandex.ru>
+
+ Explicitly specify svg base_uri using `:base-uri' image property
+
+ * src/image.c (svg_load): Check `:base-uri' image property to
+ explicitly set base_uri for images embedded into SVG
+ (enum svg_keyword_index):
+ (svg_format): Add :base-uri.
+ * lisp/svg.el (svg-embed-base-uri-image): New function to embed images
+ located relative to images `:base-uri'
+
+2020-12-12 Alan Third <alan@idiocy.org>
+
+ Revert "Explicitly specify svg base_uri using `:base-uri' image property"
+
+ This reverts commit a8e2143a5c03785742464406306fda7fce6caf04.
+
+ I applied the incorrect version of the patch.
+
+2020-12-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Offer to save tutorial position on Emacs exit
+
+ * lisp/tutorial.el (tutorial--buffer): New variable (bug#27998).
+ (tutorial--save-on-kill): Use it.
+ (help-with-tutorial): Set it and add new function to
+ kill-emacs-query-functions.
+
+2020-12-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Update Info-toc-build parsing
+
+ * lisp/info.el (Info-toc-build): Update to understand EMDASH
+ instead of a hyphen in the detailed node listing (bug#28074).
+
+2020-12-12 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in python.el
+
+ * lisp/progmodes/python.el: Require Emacs 24.2 instead of 24.1.
+ (python-indent-guess-indent-offset)
+ (python-shell-font-lock-with-font-lock-buffer)
+ (python-shell-font-lock-turn-on)
+ (python-shell-font-lock-turn-off, python-shell-font-lock-toggle)
+ (python-shell-comint-watch-for-first-prompt-output-filter)
+ (inferior-python-mode, python-shell-completion-native-turn-off)
+ (python-shell-completion-native-turn-on)
+ (python-pdbtrack-comint-output-filter-function, python-mode):
+ Prefer setq-local.
+
+2020-12-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Preserve point in dired buffers in dired-*-find-file* commands
+
+ * lisp/dired.el (dired--find-file): New function (bug#28949).
+ (dired-find-file): Use it.
+ (dired-mouse-find-file): Ditto.
+ (dired-find-file-other-window): Ditto.
+
+2020-12-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make dired-toggle-read-only check whether the directory is writable
+
+ * lisp/dired.el (dired-toggle-read-only): Check that the directory
+ is writable (bug#29412).
+
+2020-12-12 Eli Zaretskii <eliz@gnu.org>
+
+ Unbreak the MS-Windows build broken by recent changes
+
+ * src/image.c (rsvg_handle_set_dpi_x_y) [WINDOWSNT]: DEF_DLL_FN it.
+ (init_svg_functions): LOAD_DLL_FN rsvg_handle_set_dpi_x_y.
+ <rsvg_handle_set_dpi_x_y>: Define as a macro
+
+2020-12-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve the documentation of marker handling when reverting
+
+ * doc/lispref/backups.texi (Reverting): Mention markers from
+ non-file sources (bug#30028).
+
+ * lisp/files.el (revert-buffer): Mention what happens with markers
+ (bug#30028).
+
+ * src/fileio.c (Finsert_file_contents): Say a bit more about what
+ markers are restored (bug#30028).
+
+2020-12-12 Eli Zaretskii <eliz@gnu.org>
+
+ Improve support for 'memory-report' on MS-Windows
+
+ * src/w32term.c (w32_image_size): New function.
+ * src/image.c (image_frame_cache_size) [HAVE_NTGUI]: Support
+ reporting the size of frame image cache.
+ (image_frame_cache_size, Fimage_cache_size): The total size is
+ now of the type 'size_t', not 'int'.
+
+2020-12-12 Pankaj Jangid <pankaj@codeisgreat.org>
+
+ Allow customizing the Gnus summary thread indicators
+
+ * doc/misc/gnus.texi (Summary Buffer Lines): Document them.
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-prepare-threads): Use them.
+
+ * lisp/gnus/gnus-sum.el (gnus-sum-opening-bracket)
+ (gnus-sum-closing-bracket, gnus-sum-opening-bracket-adopted)
+ (gnus-sum-closing-bracket-adopted): New variables.
+
+2020-12-12 Alan Third <alan@idiocy.org>
+
+ Improve some NS drawing code
+
+ * src/nsterm.m (ns_update_end): There's no need to schedule a redraw
+ if nothing has been changed.
+ (ns_set_vertical_scroll_bar):
+ (ns_set_horizontal_scroll_bar): Fix the logic for clearing under the
+ scrollbars.
+ (ns_clear_under_internal_border): No need to clip, the default
+ clipping rectangle will be fine.
+
+2020-12-12 Alan Third <alan@idiocy.org>
+
+ Use real DPI when rendering SVGs (bug#45124)
+
+ * src/image.c (svg_css_length_to_pixels): Pass in a DPI value instead
+ of using a hard coded value.
+ (svg_load_image): Set the DPI on the rsvg_handle, and pass it to
+ svg_css_length_to_pixels.
+
+2020-12-12 Zajcev Evgeny <zevlg@yandex.ru>
+
+ Explicitly specify svg base_uri using `:base-uri' image property
+
+ * src/image.c (svg_load): Check `:base-uri' image property to
+ explicitly set base_uri for images embedded into SVG
+
+2020-12-12 Alan Third <alan@idiocy.org>
+
+ Fix crash when using XRender and restoring image from X (bug#44930)
+
+ * src/dispextern.h (struct image): Add original dimension elements.
+ * src/image.c (image_set_transform): Store the original dimensions.
+ (image_get_x_image): If we're using transforms use the original
+ dimensions with XGetImage.
+
+2020-12-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/thunk.el (thunk-let*): Don't modify `bindings`
+
+2020-12-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/play/dunnet.el: Make it so loading the file is harmless
+
+ Move comments into docstrings while at it.
+
+ (dun-batch): New function.
+
+2020-12-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix copyright line
+
+2020-12-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ button-buttonize doc string clarification
+
+ * lisp/button.el (button-buttonize): Clarify what happens when
+ DATA isn't present.
+
+2020-12-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix image-cache-size crash
+
+ * src/image.c (image_frame_cache_size): Ensure that img->pixmap is
+ in use before trying to access it.
+
+2020-12-11 Stefan Kangas <stefan@marxist.se>
+
+ * src/fns.c (Fbuffer_hash): Doc fix. (Bug#45178)
+
+2020-12-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Also sort the totals section by size
+
+ * lisp/emacs-lisp/memory-report.el (memory-report): Sort the
+ totals by size, too.
+
+2020-12-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak memory-report--format
+
+ * lisp/emacs-lisp/memory-report.el (memory-report--format): Make
+ everything line up, even when there's "1023.4kB".
+
+2020-12-11 F. Jason Park <jp@neverwas.me> (tiny change)
+
+ Append incremental message segments in socks-filter
+
+ * lisp/net/socks.el (socks-filter): Preserve the order data arrive
+ instead of semi-reversing it (bug#45162).
+
+2020-12-11 Pankaj Jangid <pankaj@codeisgreat.org>
+
+ docstring: If FRAME is nil, it defaults to selected frame.
+
+ * src/frame.c (Fset_frame_size): Clarify what a nil FRAME
+ parameter means (bug#45170).
+
+2020-12-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify fortran-beginning-of-subprogram doc string after change
+
+ * lisp/progmodes/fortran.el (fortran-beginning-of-subprogram):
+ Clarify doc string (bug#33208).
+
+2020-12-11 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/progmodes/python.el: Bump version.
+
+2020-12-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix compilation of image.c on non-Cairo systems
+
+ * src/image.c (image_frame_cache_size): pixmap->width etc is only
+ defined on Cairo. Return 0 for now on other systems.
+
+2020-12-11 Roland Winkler <winkler@gnu.org>
+
+ bibtex-autokey-get-year: Follow iso8601
+
+ * lisp/textmodes/bibtex.el (bibtex-autokey-get-year): Follow
+ iso8601 (bug#36252).
+
+2020-12-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix object-interval tests
+
+ * test/src/fns-tests.el (object-intervals): Fix tests.
+
+2020-12-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix parsing error in exif
+
+ * lisp/image/exif.el (exif--parse-exif-chunk): The offset is a
+ four-byte number. Reported by Alan Light <lightalan@gmail.com>.
+
+2020-12-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new command `memory-report'
+
+ * doc/lispref/internals.texi (Garbage Collection): Document it.
+ * lisp/emacs-lisp/memory-report.el: New package.
+
+2020-12-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new function `object-intervals'
+
+ * doc/lispref/text.texi (Examining Properties): Document it.
+ * src/fns.c (Fobject_intervals): New defun.
+ (collect_interval): New function.
+
+2020-12-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new function 'image-cache-size'
+
+ * src/image.c (Fimage_cache_size): New defun.
+ (image_frame_cache_size): New function.
+
+2020-12-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new function `button-buttonize'
+
+ * doc/lispref/display.texi (Manipulating Buttons): Document it.
+
+ * lisp/button.el (button-buttonize): Implement it.
+
+2020-12-11 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/battery.el (battery--upower-devices): Protect the D-Bus call.
+
+ (Bug#45163)
+
+2020-12-11 Tassilo Horn <tsdh@gnu.org>
+
+ Bind k to image-kill-buffer in doc-view-mode-map.
+
+ * lisp/doc-view.el (doc-view-mode-map): Bind k to image-kill-buffer.
+ The binding k -> doc-view-kill-proc-and-buffer has been removed in
+ 2015 and the function been made an obsolete function alias to
+ image-kill-buffer (bug#45157).
+
+2020-12-11 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix quoting in gnus-buffer-configuration
+
+ * lisp/gnus/gnus-win.el (gnus-buffer-configuration): Include
+ shell-command-buffer-name value rather than symbol in pipe
+ configuration. (Bug#39138, bug#45154)
+
+2020-12-11 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Be more graceful about handling Gnus search errors
+
+ One search may be applied to several servers: don't let one server's
+ error derail the whole process.
+
+ * lisp/gnus/gnus-search.el (gnus-search-config-error): Define new
+ error.
+ (gnus-search-run-search, gnus-search-server-to-engine): Raise this
+ specific error as appropriate.
+ (gnus-search-run-query): Catch this error and effectively demote it.
+
+2020-12-10 Stefan Kangas <stefan@marxist.se>
+
+ Remove some ancient Emacs compat code from cperl-mode
+
+ This variable has this value by default since Emacs 19.34.
+
+ * lisp/progmodes/cperl-mode.el (cperl-mode): Remove some compat code.
+
+2020-12-10 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in cperl-mode.el
+
+ * lisp/progmodes/cperl-mode.el (cperl-mode, cperl-info-buffer)
+ (cperl-setup-tmp-buf, cperl-emulate-lazy-lock): Prefer setq-local.
+
+2020-12-10 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in bibtex-style.el
+
+ * lisp/textmodes/bibtex-style.el (bibtex-style-mode): Prefer
+ setq-local.
+
+2020-12-10 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid segfaults in pos_visible_p
+
+ * src/xdisp.c (pos_visible_p): Don't try accessing the glyphs
+ produced by iterator whose glyph_row was set to NULL; instead,
+ record the X coordinate before the display string when moving past
+ it, and use the recorded coordinate if needed. (Bug#45156)
+
+2020-12-10 Mattias Engdegård <mattiase@acm.org>
+
+ Fupcase no longer maps ?ß to itself (bug#11309)
+
+ * test/src/casefiddle-tests.el (casefiddle-tests-char-casing):
+ (upcase ?ß) now returns ?ẞ (U+7838), partly for technical reasons but
+ the previous behaviour was arbitrary and arguably less useful.
+ Correct upcasing of ß is normally SS, which is what Fupcase returns if
+ given a string, or (for special purposes) ẞ.
+
+2020-12-10 Juri Linkov <juri@linkov.net>
+
+ Allow creating a new tab from the minibuffer (bug#45072)
+
+ * lisp/tab-bar.el (tab-bar-new-tab-to): Select the original window
+ when selected window is the minibuffer.
+
+2020-12-10 Dmitry Gutov <dgutov@yandex.ru> (tiny change)
+
+ Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
+
+ * lisp/vc/vc-hg.el (vc-hg-working-revision):
+ Use 'hg log -T' instead of 'hg parent' (bug#36534).
+
+2020-12-09 Stefan Kangas <stefan@marxist.se>
+
+ Fix thinko in my previous commit
+
+ * lisp/pcomplete.el (pcomplete-comint-setup): Fix thinko in my
+ previous commit. This was not a quoted symbol but a variable, and
+ therefore cannot use setq-local.
+
+2020-12-09 Dmitry Gutov <dgutov@yandex.ru>
+
+ * lisp/progmodes/xref.el: Bump the version.
+
+2020-12-09 Dmitry Gutov <dgutov@yandex.ru>
+
+ Allow specifying the project to switch to programmatically
+
+ * lisp/progmodes/project.el (project-switch-project):
+ Allow specifying the project to switch to programmatically
+ (bug#45134).
+
+2020-12-09 Dmitry Gutov <dgutov@yandex.ru>
+
+ Add missing defcustom keywords to new variables
+
+ * lisp/progmodes/xref.el (xref-search-program-alist)
+ (xref-search-program): Add :version and :package-version.
+
+2020-12-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify `scroll-preserve-screen-position' doc string
+
+ * src/window.c (syms_of_window): Clarify the doc string (bug#7910).
+
+2020-12-09 Juri Linkov <juri@linkov.net>
+
+ Remove isearch-input-method-local-p and always set buffer-local input-method
+
+ * lisp/isearch.el (isearch-input-method-local-p): Remove defvar.
+ (isearch-mode): Don't set isearch-input-method-local-p.
+ Set buffer-local input-method-function to nil.
+ (isearch-done): When isearch-input-method-function is still non-nil,
+ set the buffer-local value of input-method-function. (Bug#45005)
+
+ * lisp/international/isearch-x.el (isearch-toggle-specified-input-method)
+ (isearch-toggle-input-method, isearch-transient-input-method):
+ Don't set isearch-input-method-local-p to t. Set buffer-local
+ input-method-function to nil.
+
+ * lisp/language/korea-util.el (isearch-toggle-korean-input-method)
+ (isearch-hangul-switch-symbol-ksc, isearch-hangul-switch-hanja):
+ Don't set isearch-input-method-local-p to t. Set buffer-local
+ input-method-function to nil.
+
+2020-12-09 Juri Linkov <juri@linkov.net>
+
+ Support highlighting of ripgrep output (bug#44983)
+
+ * etc/grep.txt: Add ripgrep samples.
+
+ * lisp/progmodes/grep.el (grep-match-regexp): Highlight ripgrep matches too.
+ (grep-regexp-alist): Remove $ to highlight ripgrep binary file matches.
+
+2020-12-09 Mattias Engdegård <mattiase@acm.org>
+
+ Stricter gradle-kotlin message pattern
+
+ * lisp/progmodes/compile.el (compilation-error-regexp-alist-alist):
+ Rule 'gradle-kotlin': don't be more forgiving than necessary; we know
+ exactly what the output looks like (see
+ https://github.com/JetBrains/kotlin/commit/\
+ ffe8ae3840d7b9bdc82170c8181031f05ced68bd) and there is no reason to
+ risk mismatches or expensive backtracking (bug#18109). Recognise
+ 'info' level messages. Convert to rx.
+
+2020-12-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Include the keymap in the gud-mode doc string
+
+ * lisp/progmodes/gud.el (gud-mode): Add the gud keymap to the end
+ of the doc string for easier access (bug#31406).
+
+2020-12-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ `pdb' doc string clarification
+
+ * lisp/progmodes/gud.el (pdb): Mention that this command is for
+ debugging Python scripts.
+
+2020-12-09 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ c0b3e38d7c Update publicsuffix.txt from upstream
+ 3fe6cea6e0 * lisp/vc/vc.el: Update args of backend API calls in the h...
+
+2020-12-09 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 32090a3de4 Improve documentation of streams in batch mode
+ 34feded008 Support ks_c_5601-1987 encoding
+ da00a6f317 Fix Xaw widget text disappearing when built with cairo (bu...
+ 6916e7954a Improve documentation of 'ps-print-color-p'
+ 6663b2f211 ; * lisp/simple.el (move-beginning-of-line): Doc fix.
+ a4dd03ebe9 ; * src/charset.c (Fmap_charset_chars): Doc fix.
+ d86cc3ffcb ; * src/chartab.c, src/lisp.h: Fix typos in comments.
+
+2020-12-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix mark-defun in fortran-mode
+
+ * lisp/progmodes/fortran.el (fortran-beginning-of-subprogram):
+ Make mark-defun work (bug#33208).
+
+2020-12-09 Eli Zaretskii <eliz@gnu.org>
+
+ Improve predictability of 'scroll-preserve-screen-position'
+
+ * src/window.c (window_scroll_pixel_based): Compute the new
+ window-start more precisely when 'scroll-preserve-screen-position'
+ is non-nil. (Bug#8355)
+
+2020-12-09 Eli Zaretskii <eliz@gnu.org>
+
+ Update docs of 'defvar' and 'defface'
+
+ * doc/lispref/display.texi (Defining Faces):
+ * doc/lispref/variables.texi (Defining Variables): Update the
+ descriptions of 'defvar' and 'defface' per recent changes in
+ 'eval-last-sexp'. (Bug#45125)
+
+2020-12-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix info mode fontification of built-in (*note Built-ins::)
+
+ * lisp/info.el (Info-fontify-node): Don't interpret things like
+ "built-in" as being the word "in" (bug#34661).
+
+2020-12-09 Serge Tupchii <serge.tupchii@protonmail.com> (tiny change)
+
+ Fix crash (segfault) in etags on generating tags for Erlang files
+
+ * lib-src/etags.c: Set allocated and lastlen to zero, after
+ freeing last ptr in Erlang_functions to prevent dereferencing NULL
+ pointer (bug#45122).
+
+
+ (cherry picked from commit 2d8f0364fcd1d5dad2b82dd3a9af870b03854547)
+
+2020-12-09 Mattias Engdegård <mattiase@acm.org>
+
+ Recognise ß properly as a lower-case letter (bug#11309)
+
+ ß was incorrectly treated as a caseless character and thus not matched
+ by the regexp [[:lower:]] (or, in case-folding mode, [[:upper:]]).
+ The reason is that the upcase table maps it to itself, which can be
+ remedied by mapping it to ẞ (U+7838) instead. Doing so does not
+ affect upcasing since the special-uppercase property maps it to SS.
+
+ * lisp/international/characters.el (tbl): Map ß to ẞ in the upcase
+ table.
+ * test/src/regex-emacs-tests.el (regexp-eszett): Uncomment previously
+ failing tests. Add checks to make sure that case transformations
+ remain valid.
+
+2020-12-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ cl-pushnew manual clarification
+
+ * doc/misc/cl.texi (Modify Macros): Don't claim that cl-pushnew
+ uses eql.
+ (Lists as Sets): Mention that eql is the default comparison function.
+
+2020-12-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ cl-defmethod doc string clarification
+
+ * lisp/emacs-lisp/cl-generic.el (cl-defmethod): Clarify the doc
+ string, and give an example (bug#42322).
+
+2020-12-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify the default-boundp doc string
+
+ * src/data.c (Fdefault_boundp): Doc string clarification (bug#44141).
+
+2020-12-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make ediff offer to create files it's inferring
+
+ * lisp/vc/ediff-ptch.el (ediff-fixup-patch-map): Offer to create
+ the inferred file name (if it doesn't exist) (bug#8009). This allows
+ applying a patch that creates a file.
+
+2020-12-09 Michael Albinus <michael.albinus@gmx.de>
+
+ Improve tests for gio file notifications
+
+ * .gitlab-ci.yml (test-filenotify-gio): Call "make -k".
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-file-notify-add-watch):
+ Set connection property "gio-file-monitor".
+
+ * lisp/net/tramp-sh.el (tramp-get-remote-gio-file-monitor): New defun.
+ (tramp-sh-handle-file-notify-add-watch): Use it.
+
+ * test/lisp/filenotify-tests.el (file-notify--test-read-event): Simplify.
+ (file-notify--test-monitor): Handle also remote "gio monitor".
+ (file-notify-test03-events, file-notify-test04-autorevert)
+ (file-notify-test05-file-validity, file-notify-test08-backup)
+ (file-notify-test09-watched-file-in-watched-dir):
+ Handle GKqueueFileMonitor.
+
+2020-12-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Filter revoked keys when saving files
+
+ * lisp/epa-file.el (epa-file-write-region): Use it to select a
+ non-revoked key (bug#22359).
+
+ * lisp/epg.el (epg--filter-revoked-keys): New function.
+
+2020-12-09 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in most files
+
+ * lisp/apropos.el (apropos-print):
+ * lisp/buff-menu.el (Buffer-menu-mode):
+ * lisp/calc/calc.el (calc-trail-buffer):
+ * lisp/chistory.el (command-history-mode):
+ * lisp/dabbrev.el:
+ * lisp/dframe.el (dframe-frame-mode):
+ * lisp/doc-view.el (doc-view-presentation-mode):
+ * lisp/ebuff-menu.el (electric-buffer-menu-mode)
+ (electric-buffer-update-highlight):
+ * lisp/edmacro.el (edit-kbd-macro):
+ * lisp/face-remap.el (buffer-face-set, buffer-face-toggle):
+ * lisp/files.el:
+ (find-file-noselect-1, hack-local-variables-confirm)
+ (set-visited-file-name, revert-buffer--default):
+ * lisp/filesets.el (filesets-spawn-external-viewer):
+ * lisp/find-dired.el (find-dired):
+ * lisp/find-lisp.el (find-lisp-find-dired-internal):
+ * lisp/finder.el (finder-mode):
+ * lisp/font-core.el (font-lock-default-function):
+ * lisp/format.el (format-annotate-function):
+ * lisp/help-fns.el (describe-variable):
+ * lisp/help-mode.el (help-mode):
+ * lisp/icomplete.el (icomplete-minibuffer-setup)
+ (icomplete--in-region-setup):
+ * lisp/ido.el (ido-completion-help, ido-tidy):
+ * lisp/international/robin.el (robin-activate):
+ * lisp/leim/quail/hangul.el (hangul-input-method-activate):
+ * lisp/leim/quail/uni-input.el (ucs-input-activate):
+ * lisp/man.el (Man-mode):
+ * lisp/master.el (master-set-slave):
+ * lisp/minibuffer.el (minibuffer-completion-help)
+ (read-file-name-default):
+ * lisp/outline.el (outline-minor-mode):
+ * lisp/pcomplete.el (pcomplete-comint-setup):
+ * lisp/proced.el (proced-mode):
+ * lisp/recentf.el (recentf-edit-list, recentf-open-files-items):
+ * lisp/replace.el (occur-1):
+ * lisp/reveal.el (reveal-mode):
+ * lisp/ruler-mode.el (ruler--save-header-line-format):
+ * lisp/scroll-lock.el (scroll-lock-mode):
+ * lisp/startup.el (normal-top-level, normal-splash-screen):
+ * lisp/strokes.el (strokes-list-strokes):
+ * lisp/thumbs.el (thumbs-insert-image, thumbs-show-thumbs-list):
+ * lisp/tree-widget.el (tree-widget-set-theme):
+ * lisp/window.el (read-buffer-to-switch):
+ * lisp/xwidget.el (xwidget-webkit-begin-edit-textarea): Prefer
+ setq-local.
+
+2020-12-09 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in dired extensions
+
+ * lisp/dired-aux.el (dired-diff, dired-compare-directories)
+ (dired-do-create-files, dired-isearch-filenames):
+ * lisp/dired-x.el (dired-virtual, dired-vm):
+ * lisp/wdired.el (wdired-change-to-wdired-mode)
+ (wdired-change-to-dired-mode, wdired-preprocess-perms):
+
+2020-12-09 Stefan Kangas <stefan@marxist.se>
+
+ Update publicsuffix.txt from upstream
+
+ * etc/publicsuffix.txt: Update from
+ https://publicsuffix.org/list/public_suffix_list.dat
+ dated 2020-11-30 21:57:25 UTC.
+
+2020-12-09 Mattias Engdegård <mattiase@acm.org>
+
+ Fix [:upper:] and [:lower:] for Unicode characters (bug#11309)
+
+ * src/regex-emacs.c (execute_charset): Add canon_table argument to
+ allow expression of a correct predicate for [:upper:] and [:lower:].
+ (mutually_exclusive_p, re_match_2_internal): Pass extra argument.
+ * test/src/regex-emacs-tests.el (regexp-case-fold, regexp-eszett):
+ New tests. Parts of regexp-eszett still fail and are commented out.
+
+2020-12-09 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in some remaining progmodes
+
+ * lisp/progmodes/dcl-mode.el (dcl-mode):
+ * lisp/progmodes/hideif.el (hide-ifdef-mode)
+ (hide-ifdef-toggle-shadowing):
+ * lisp/progmodes/ps-mode.el (ps-mode, ps-run-mode):
+ * lisp/progmodes/xscheme.el (xscheme-start)
+ (local-set-scheme-interaction-buffer, scheme-interaction-mode):
+ Prefer setq-local.
+
+2020-12-09 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in gdb-mi.el
+
+ * lisp/progmodes/gdb-mi.el (gdb--check-interpreter, gdb)
+ (gdb-init-buffer, gdb-get-buffer-create, gdb-threads-mode)
+ (gdb-memory-mode, gdb-disassembly-mode, gdb-frames-mode): Prefer setq-local.
+
+2020-12-09 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in etags.el
+
+ * lisp/progmodes/etags.el (initialize-new-tags-table)
+ (etags-recognize-tags-table, tags-recognize-empty-tags-table):
+ Prefer setq-local.
+
+2020-12-09 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in cfengine.el
+
+ * lisp/progmodes/cfengine.el (cfengine-common-settings)
+ (cfengine3-mode, cfengine2-mode): Prefer setq-local.
+
+2020-12-09 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in sql.el
+
+ * lisp/progmodes/sql.el (sql--oracle-show-reserved-words)
+ (sql-product-font-lock, sql-list-all, sql-mode)
+ (sql-interactive-mode, sql-product-interactive): Prefer
+ setq-local.
+
+2020-12-09 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in font-lock.el
+
+ * lisp/font-lock.el:
+ (font-lock-add-keywords, font-lock-turn-on-thing-lock)
+ (font-lock-fontify-syntactic-keywords-region)
+ (font-lock-set-defaults): Prefer setq-local.
+
+2020-12-09 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/progmodes/sql.el: Remove redundant URL.
+
+2020-12-09 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Make abbrev-tests.el more deterministic
+
+ * test/lisp/abbrev-tests.el (abbrev--table-symbols-test): Don't rely
+ on order of symbols in obarray.
+
+2020-12-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make uncache_image slightly more efficient
+
+ * src/image.c (uncache_image): Extremely minor speed-up: Only
+ compute the hash once.
+
+2020-12-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/fns.c: Remove left over include
+
+2020-12-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Restore Emacs 27 image cache semantics
+
+ * src/image.c (equal_lists): Remove.
+ (search_image_cache): Use Fequal instead of equal_lists.
+ Benchmarking shows no measurable time difference, and this
+ restores the cache semantics from Emacs 27 (where file names
+ didn't have to be EQ for the cache to be used).
+
+2020-12-09 João Távora <joaotavora@gmail.com>
+
+ Remove interactive spec from internal eldoc--format-doc-buffer
+
+ Per bug#43609.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc--format-doc-buffer): Remove
+ useless interactive spec.
+
+2020-12-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/fns.c (hash_string): Speed up on large strings
+
+2020-12-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ term.el comment update
+
+ * lisp/term.el: Fix wrong command name in the comments (bug#7041).
+
+2020-12-08 Serge Tupchii <serge.tupchii@protonmail.com> (tiny change)
+
+ Fix crash (segfault) in etags on generating tags for Erlang files
+
+ * lib-src/etags.c: Set allocated and lastlen to zero, after
+ freeing last ptr in Erlang_functions to prevent dereferencing NULL
+ pointer (bug#45122).
+
+2020-12-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make rcirc nick renaming heed nickname max lengths
+
+ * lisp/net/rcirc.el (rcirc-server-parameters): New variable (bug#6795).
+ (rcirc-connect): Set it.
+ (rcirc-handler-433): Use the length from the server.
+ (rcirc-handler-005): Collect server data.
+ (rcirc-server-parameter-value): New utility function.
+ (rcirc--make-new-nick): New function.
+
+2020-12-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make hexl scrolling commands work more like the normal ones
+
+ * lisp/hexl.el (hexl-scroll-down):
+ (hexl-scroll-up): Heed `next-screen-context-lines' (bug#7031).
+
+2020-12-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix scrolling in hexl-mode when ruler-mode is on
+
+ * lisp/hexl.el (hexl-scroll-down):
+ (hexl-scroll-up): Take ruler-mode into account when computing the
+ number of lines (bug#7031). These commands would previously jump
+ one line too many by default, skipping one line.
+
+2020-12-08 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'backtrace-on-error-noninteractive'
+
+ * src/eval.c (syms_of_eval) <backtrace-on-error-noninteractive>:
+ Format the doc string according to conventions.
+
+ * etc/NEWS: Improve formatting and wording of the entry describing
+ 'backtrace-on-error-noninteractive.
+
+2020-12-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the history traversal functions in coming more regular
+
+ * lisp/comint.el (comint-previous-matching-input): Allow restoring
+ the input on wraps (bug#7885).
+ (comint-previous-matching-input-from-input): Restore input on wraps.
+
+2020-12-08 Boruch Baum <boruch_baum@gmx.com>
+
+ Make table-fixed-width-mode work again
+
+ * lisp/textmodes/table.el (table--update-cell): Make
+ table-fixed-width-mode work (bug#18183).
+
+2020-12-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use the proper face for the Gnus mode line id
+
+ * lisp/gnus/gnus-sum.el (gnus-set-mode-line):
+ * lisp/gnus/gnus-group.el (gnus-group-set-mode-line): Use the
+ mode-line-buffer-id face on the buffer id.
+
+2020-12-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Simplify gnus-mode-line-buffer-identification
+
+ * lisp/gnus/gnus.el (gnus-mode-line-image-cache): Remove.
+ (gnus-mode-line-buffer-identification): Use the find-image cache.
+
+2020-12-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Cache toolbar icon data paths
+
+ * lisp/image.el (find-image): Add an optional CACHE parameter.
+ (find-image--cache): New variable.
+
+ * lisp/tool-bar.el (tool-bar--image-expression): Use cached data
+ to avoid looking up the image files on each refresh.
+
+2020-12-08 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in grep.el
+
+ * lisp/progmodes/grep.el (grep-process-setup, grep-mode): Prefer
+ setq-local.
+
+2020-12-08 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in meta-mode.el
+
+ * lisp/progmodes/meta-mode.el (meta-common-mode, metafont-mode)
+ (metapost-mode): Prefer setq-local.
+
+2020-12-08 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in compile.el
+
+ * lisp/progmodes/compile.el (compile-command, compilation-start)
+ (compilation-mode, compilation-setup, compilation-filter)
+ (compilation-forget-errors): Prefer setq-local.
+
+2020-12-08 Stefan Kangas <stefan@marxist.se>
+
+ * admin/nt/dist-build/build-dep-zips.py: Remove unused import.
+
+2020-12-08 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in tests
+
+ * test/lisp/allout-tests.el (allout-test-resumption-prior-value-resumed)
+ (allout-test-resumption-multiple-holds)
+ (allout-test-resumption-unbinding):
+ * test/lisp/emacs-lisp/faceup-resources/faceup-test-mode.el
+ (faceup-test-mode):
+ * test/lisp/epg-tests.el (with-epg-tests):
+ * test/src/data-tests.el (binding-test-buffer-A): Prefer setq-local.
+
+2020-12-08 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in term.el
+
+ * lisp/term.el (term-mode, term-exec, term-emulate-terminal)
+ (term-process-pager): Prefer setq-local.
+
+2020-12-08 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in shell.el
+
+ * lisp/shell.el (shell-completion-vars, shell-mode): Prefer
+ setq-local.
+
+2020-12-08 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in speedbar.el
+
+ * lisp/speedbar.el (speedbar-frame-mode, speedbar-mode)
+ (speedbar-add-localized-speedbar-support): Prefer setq-local.
+
+2020-12-08 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in newcomment.el
+
+ * lisp/newcomment.el (comment-inline-offset)
+ (comment-normalize-vars): Prefer setq-local.
+
+2020-12-08 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/locate.el (locate, locate-mode): Prefer setq-local.
+
+ * lisp/array.el (array-mode): Prefer setq-local.
+
+2020-12-08 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in simple.el
+
+ * lisp/simple.el (read-extended-command, goto-history-element)
+ (minibuffer-history-isearch-setup, read-shell-command)
+ (visual-line-mode, completion-setup-function, read-only-mode)
+ (visible-mode): Prefer setq-local.
+
+2020-12-07 Philipp Stephani <phst@google.com>
+
+ Fix bug in how ERT invokes its debugger.
+
+ The debugger needs to receive a list of the error symbol and data;
+ cf. the documentation of the `debugger' variable. This bug manifested
+ itself in ERT forms such as (should (integerp (ert-fail "Boo"))),
+ which resulted in an incorrect condition object. Note that forms such
+ as (should (ert-fail "Boo")) weren't affected because they wouldn't
+ use the `ert--should-signal-hook'.
+
+ * lisp/emacs-lisp/ert.el (ert--should-signal-hook): Call debugger
+ with the right arguments.
+
+ * test/lisp/emacs-lisp/ert-tests.el (ert-test-fail-inside-should):
+ Add unit test.
+
+2020-12-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Avoid problems when calling desktop-read twice
+
+ * lisp/desktop.el (desktop-read): Don't reload the desktop file if
+ it's already been loaded, because the later query may lead to
+ desktop-dirname being set to nil (bug#9765).
+
+2020-12-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make previous Fkill_emacs change safer
+
+ * src/emacs.c (Fkill_emacs): Don't run `kill-emacs-hook' if it's nil.
+
+2020-12-07 Daniel Martín <mardani29@yahoo.es>
+
+ Add commands xref-next-group and xref-prev-group
+
+ * lisp/progmodes/xref.el (xref-next-group): New command that navigates
+ to the first item of the next xref group (typically a file).
+ (xref-prev-group): New command that navigates
+ to the first item of the next xref group (typically a file).
+ (xref--xref-buffer-mode-map): Bound the new commands to 'N' and 'P',
+ respectively.
+ * doc/emacs/maintaining.texi (Xref Commands): Document the new
+ commands in the Emacs manual.
+ * etc/NEWS: Announce them (bug#45089).
+
+2020-12-07 Alyssa Ross <hi@alyssa.is> (tiny change)
+
+ Only use the comint environment in comint-derived modes
+
+ * lisp/progmodes/compile.el (compilation-start): Only use the
+ comint environment in comint-derived modes (bug#45095).
+
+2020-12-07 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in calendar/*.el
+
+ * lisp/calendar/calendar.el (calendar-mode):
+ * lisp/calendar/diary-lib.el (diary-list-entries, diary-mode):
+ (diary-fancy-display-mode): Prefer setq-local.
+
+2020-12-07 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in gnus/*.el
+
+ * lisp/gnus/gnus-agent.el (gnus-agent-mode)
+ (gnus-agent-get-undownloaded-list, gnus-agent-open-history):
+ * lisp/gnus/gnus-art.el (gnus-article-setup-highlight-words)
+ (gnus-article-mode, gnus-article-setup-buffer, defsubst)
+ (gnus-article-describe-bindings, gnus-article-edit-mode):
+ * lisp/gnus/gnus-cus.el (gnus-custom-mode, gnus-group-customize)
+ (gnus-score-customize, gnus-agent-customize-category):
+ * lisp/gnus/gnus-group.el (gnus-group-make-tool-bar):
+ * lisp/gnus/gnus-msg.el (gnus-setup-message)
+ (gnus-summary-news-other-window, gnus-configure-posting-styles):
+ * lisp/gnus/gnus-salt.el (gnus-pick-mode, gnus-binary-mode):
+ * lisp/gnus/gnus-score.el (gnus-score-edit-current-scores)
+ (gnus-score-edit-file):
+ * lisp/gnus/gnus-srvr.el (gnus-server-mode):
+ * lisp/gnus/gnus-start.el (gnus-no-server-1)
+ (gnus-dribble-read-file, gnus-save-newsrc-file)
+ (gnus-gnus-to-newsrc-format):
+ * lisp/gnus/gnus-sum.el (gnus-summary-make-tool-bar)
+ (gnus-summary-mode, gnus-summary-setup-buffer)
+ (gnus-select-newsgroup, gnus-summary-edit-article)
+ (gnus-summary-setup-default-charset):
+ * lisp/gnus/gnus-topic.el (gnus-topic-mode):
+ * lisp/gnus/gnus-undo.el (gnus-undo-mode):
+ * lisp/gnus/gnus.el (gnus-simplify-mode-line):
+ * lisp/gnus/message.el (message-cite-reply-position)
+ (message-cite-style, message-mode, message-setup-fill-variables):
+ * lisp/gnus/mm-view.el (mm-display-inline-fontify):
+ * lisp/gnus/mml.el (mml-mode):
+ * lisp/gnus/nndiary.el (nndiary-open-nov):
+ * lisp/gnus/nnfolder.el (nnfolder-save-buffer)
+ (nnfolder-open-nov):
+ * lisp/gnus/nnheader.el (nnheader-init-server-buffer):
+ * lisp/gnus/nnimap.el (nnimap-make-process-buffer):
+ * lisp/gnus/nnml.el (nnml-get-nov-buffer): Prefer setq-local.
+
+2020-12-07 Andrea Corallo <akrl@sdf.org>
+
+ Spawn a sub-process for running GCC also in batch mode (bug#45056)
+
+ * lisp/emacs-lisp/comp.el (comp-async-compilation): New variable.
+ (comp-final): Always run the C side of the compilation as a
+ sub-process unless during bootstrap or async compilation.
+ (comp-run-async-workers): Set `comp-async-compilation'.
+
+2020-12-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Insert skeletons at the correct point
+
+ * lisp/skeleton.el (skeleton-read): Don't insert the skeleton at
+ an arbitrary point if the user moves around (bug#17752).
+
+2020-12-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow shutting down Emacs even if there are errors in kill-emacs-hook
+
+ * lisp/subr.el (run-hook-query-error-with-timeout): New function
+ (bug#28542).
+
+ * src/emacs.c (Fkill_emacs): Use it to allow exiting Emacs even if
+ there are errors in kill-emacs-hook.
+ (syms_of_emacs): Define the symbol.
+
+2020-12-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Ensure that new emacsclient frames has focus
+
+ * lisp/server.el (server-execute): Focus the frame here...
+ (server-switch-buffer): Instead of here (bug#15469). This ensures
+ that the frame has focus if Emacs is querying the user about
+ something when opening a file (for instance "Revert from file?").
+
+2020-12-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow inhibiting the instructions on how to close emacsclient frames
+
+ * doc/emacs/misc.texi (Invoking emacsclient): Document it.
+ * lisp/server.el (server-client-instructions): New variable.
+ (server-execute): Use it.
+
+2020-12-07 Illia Ostapyshyn <ilya.ostapyshyn@gmail.com> (tiny change)
+
+ Allow using newer versions of Gnuplot from calc again
+
+ * lisp/calc/calc-graph.el (calc-graph-plot): Don't use the "time"
+ abbreviation for "timestamp" (bug#39232) -- it's no longer valid
+ after
+ https://github.com/gnuplot/gnuplot/commit/b979b5371bc1c18bf8f5bd756e7c1fb54dafd8cc
+
+2020-12-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix file name quoting problems in tex-mode
+
+ * lisp/textmodes/tex-mode.el (tex--quote-spec): New function
+ (bug#14286).
+ (tex-format-cmd): Use it.
+ (tex-compile): Don't quote the file names, because we're using
+ `file-exists-p' and friends on the results later, and that fails
+ on systems where everything is quoted, and on file names that need
+ quoting.
+
+2020-12-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify icomplete-show-matches-on-no-input doc string
+
+ * lisp/icomplete.el (icomplete-show-matches-on-no-input): Clarify
+ doc string (bug#19031), suggested by Andrii Kolomoiets.
+
+2020-12-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Clarify icomplete-show-matches-on-no-input doc string"
+
+ This reverts commit f352c57972d24464a42ea3e65dc8ac07d8e0517c.
+
+ The new explanation of what icomplete does is wrong.
+
+2020-12-07 Mattias Engdegård <mattiase@acm.org>
+
+ Calc: simplify integer log2 and power of 2
+
+ We have bignums and fast primitives now; no caches are needed.
+
+ * lisp/calc/calc-bin.el (math-power-of-2-cache)
+ (math-big-power-of-2-cache): Remove.
+ (math-power-of-2, math-integer-log2): Simplify.
+ (calcFunc-ash): Don't call math-power-of-2 with negative argument.
+
+2020-12-07 Mattias Engdegård <mattiase@acm.org>
+
+ * doc/misc/calc.texi (Predefined Units): Prune outdated kg text.
+
+2020-12-07 Philipp Stephani <phst@google.com>
+
+ Unbreak a few unit tests that rely on lack of backtraces
+
+ * test/lisp/emacs-lisp/gv-tests.el (gv-dont-define-expander-in-file)
+ (gv-dont-define-expander-other-file):
+ * test/lisp/emacs-lisp/edebug-tests.el (edebug-tests-with-default-config):
+ Suppress backtraces in batch mode to unbreak unit tests.
+
+2020-12-07 Philipp Stephani <phst@google.com>
+
+ Add new variable to selectively suppress backtraces in batch mode.
+
+ * src/eval.c (syms_of_eval): Define new variable
+ 'backtrace-on-error-noninteractive' to selectively enable backtrace
+ printing in batch mode.
+ (signal_or_quit): Use it.
+
+ * etc/NEWS: Document new variable.
+
+ * test/src/eval-tests.el (eval-tests/backtrace-in-batch-mode/inhibit):
+ New unit test.
+
+2020-12-07 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/ielm.el (inferior-emacs-lisp-mode): Prefer setq-local.
+
+ * lisp/ibuffer.el (ibuffer, ibuffer-mode): Prefer setq-local.
+
+2020-12-07 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in whitespace.el
+
+ * lisp/whitespace.el (whitespace-turn-on, whitespace-color-on): Prefer
+ setq-local.
+
+2020-12-07 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in tar-mode.el
+
+ * lisp/tar-mode.el (tar-summarize-buffer, tar-mode, tar-extract):
+ Prefer setq-local.
+
+2020-12-07 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in tcl.el
+
+ * lisp/progmodes/tcl.el (tcl-mode, inferior-tcl-mode, inferior-tcl):
+ (tcl-auto-fill-mode, tcl-guess-application): Prefer setq-local.
+
+2020-12-07 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp.el (tramp-read-passwd): Use connection-local `auth-sources'.
+
+ * lisp/net/tramp-adb.el (tramp-adb-maybe-open-connection):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-maybe-open-connection):
+ * lisp/net/tramp-sh.el (tramp-maybe-open-connection):
+ * lisp/net/tramp-smb.el (tramp-smb-maybe-open-connection):
+ Move setting of connection-local variables up.
+
+2020-12-07 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/lisp-mode.el: Give paren syntax to [...] in lisp-data-mode
+
+ (lisp-data-mode-syntax-table): Rename from lisp--mode-syntax-table.
+ Adjust all users. Set [...] to have paren syntax.
+ (lisp-data-mode): Don't set `lisp-syntax` arg any more
+
+ * lisp/progmodes/elisp-mode.el (emacs-lisp-mode-syntax-table):
+ Don't bother setting [...] to have paren syntax any more.
+
+ * lisp/progmodes/inf-lisp.el (inferior-lisp-mode): Don't use
+ `lisp-syntax` arg of lisp-mode-variables any more.
+
+2020-12-06 Mattias Engdegård <mattiase@acm.org>
+
+ Remove Calc bignum remnants
+
+ * lisp/calc/calc-macs.el (Math-natnum-lessp):
+ * lisp/calc/calc-ext.el (math-norm-bignum, math-compare-bignum):
+ * lisp/calc/calc-math.el (math-zerop-bignum)
+ (math-scale-bignum-digit-size): Remove.
+
+ * lisp/calc/calc-bin.el (math-integer-log2, calcFunc-rot, math-clip):
+ * lisp/calc/calc-comb.el (math-prime-test, calcFunc-prfac)
+ (calcFunc-totient, calcFunc-moebius):
+ * lisp/calc/calc-ext.el (math-gcd):
+ * lisp/calc/calc-funcs.el (calcFunc-betaB):
+ * lisp/calc/calc-math.el (math-nth-root-int-iter, calcFunc-ilog):
+ Replace Math-natnum-lessp with <.
+
+2020-12-06 Juri Linkov <juri@linkov.net>
+
+ * lisp/vc/vc-git.el: Update args of backend API calls in the header comments
+
+ https://lists.gnu.org/archive/html/emacs-devel/2020-12/msg00283.html
+
+2020-12-06 Juri Linkov <juri@linkov.net>
+
+ * lisp/vc/vc.el: Update args of backend API calls in the header comments
+
+ https://lists.gnu.org/archive/html/emacs-devel/2020-12/msg00283.html
+
+2020-12-06 Juri Linkov <juri@linkov.net>
+
+ Handle calling read-char-from-minibuffer and y-or-n-p from pre-command-hook
+
+ * lisp/subr.el (read-char-from-minibuffer-insert-char)
+ (read-char-from-minibuffer-insert-other, y-or-n-p-insert-y)
+ (y-or-n-p-insert-n, y-or-n-p-insert-other):
+ Check for 'minibufferp' before executing the body.
+ (read-char-from-minibuffer, y-or-n-p): Let-bind this-command
+ before calling read-from-minibuffer. (Bug#45029)
+
+2020-12-06 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-12-06 Andrea Corallo <akrl@sdf.org>
+
+ Unify common fallback exit point in `comp-cstr-union-1-no-mem'.
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-union-1-no-mem): Define
+ a local function `give-up' as a common fall-back exit point.
+
+2020-12-06 Andrea Corallo <akrl@sdf.org>
+
+ Couple of `comp-cstr-union-1-no-mem' improvements for mixed neg pos union
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-union-1-no-mem):
+ Generalize disjoint pos types vs neg values conditions.
+ (comp-cstr-union-1-no-mem): Do not propagate ranges when we are
+ already returning integer as generic type.
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Add corresponding tests.
+
+2020-12-06 Philipp Stephani <phst@google.com>
+
+ Print a backtrace on unhandled errors in batch mode (Bug#44942).
+
+ * src/eval.c (signal_or_quit): Print a backtrace in batch mode if no
+ error handler was found.
+
+ * test/src/eval-tests.el (eval-tests/backtrace-in-batch-mode)
+ (eval-tests/backtrace-in-batch-mode/demoted-errors): New unit tests.
+
+ * etc/NEWS: Document change.
+
+2020-12-06 Eli Zaretskii <eliz@gnu.org>
+
+ Improve error message text of "C-x C-SPC"
+
+ * lisp/simple.el (pop-global-mark): Mention the buffer name in the
+ error message. Suggested by T.V Raman <raman@google.com>.
+
+2020-12-06 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of streams in batch mode
+
+ * doc/lispref/os.texi (Batch Mode):
+ * doc/lispref/streams.texi (Input Streams, Output Streams): Better
+ documentation of I/O streams in batch mode, with more
+ cross-references.
+
+2020-12-06 Michael Albinus <michael.albinus@gmx.de>
+
+ Make Tramp scripts more unique and robust
+
+ * lisp/net/tramp-sh.el (tramp-uudecode, tramp-perl-file-truename)
+ (tramp-perl-file-name-all-completions)
+ (tramp-perl-file-attributes)
+ (tramp-perl-directory-files-and-attributes)
+ (tramp-perl-encode-with-module, tramp-perl-decode-with-module)
+ (tramp-perl-encode, tramp-perl-decode, tramp-perl-pack)
+ (tramp-perl-unpack, tramp-hexdump-encode, tramp-awk-encode)
+ (tramp-hexdump-awk-encode, tramp-od-encode, tramp-od-awk-encode)
+ (tramp-awk-decode): Use format specifiers supported by
+ `tramp-expand-script'. Adapt docstring.
+ (tramp-vc-registered-read-file-names): Adapt docstring.
+ (tramp-sh-handle-file-local-copy): Let-bind local `default-directory'.
+ (tramp-expand-script): New defun.
+ (tramp-maybe-send-script, tramp-find-inline-encoding): Use it.
+ (tramp-local-coding-commands): Simplify.
+
+2020-12-06 Mattias Engdegård <mattiase@acm.org>
+
+ Unicode integrals in Calc
+
+ * lisp/calc/calccomp.el (math-compose-integ): Use Unicode integral
+ signs when available instead of a crude ASCII approximation, with a
+ shorter stem to save space.
+
+2020-12-06 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Avoid modifying nnimap user option in spam.el
+
+ * lisp/gnus/nnimap.el (nnimap--split-download-body): New variable.
+ (nnimap-fetch-inbox): Use it in conjunction with
+ nnimap-split-download-body.
+ * lisp/gnus/spam.el: Don't load nnimap.el at compile time for a
+ dynamic variable.
+ (spam-setup-widening): Rather than unconditionally set user option
+ nnimap-split-download-body, set nnimap--split-download-body to a
+ unique non-nil value only if the variable was nil (bug#44981).
+ (spam-teardown-widening): New function that undoes this if
+ nnimap--split-download-body still holds the unique value.
+ (spam-unload-hook): Call spam-teardown-widening to revert any change
+ to the value of nnimap--split-download-body.
+
+2020-12-06 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in several progmodes
+
+ * lisp/progmodes/executable.el (executable-interpret):
+ * lisp/progmodes/f90.el (f90-mode):
+ * lisp/progmodes/flymake-cc.el (flymake-cc--make-diagnostics):
+ * lisp/progmodes/fortran.el (fortran-mode):
+ * lisp/progmodes/gud.el (gud-gdb, sdb, dbx, xdb, perldb, pdb)
+ (jdb, gud-mode, gud-common-init, gdb-script-mode)
+ (gud-tooltip-activate-mouse-motions):
+ * lisp/progmodes/hideshow.el (hs-minor-mode):
+ * lisp/progmodes/icon.el (icon-mode):
+ * lisp/progmodes/ld-script.el (ld-script-mode):
+ * lisp/progmodes/mixal-mode.el (mixal-mode):
+ * lisp/progmodes/modula2.el (m2-mode):
+ * lisp/progmodes/simula.el (simula-mode):
+ * lisp/progmodes/subword.el (subword-setup-buffer):
+ * lisp/progmodes/which-func.el (which-function): Prefer setq-local.
+
+2020-12-06 Eli Zaretskii <eliz@gnu.org>
+
+ Support ks_c_5601-1987 encoding
+
+ * lisp/language/korean.el (ks_c_5601-1987): Define as an alias for
+ 'korean-iso-8bit. (It is sometimes used in email messages.)
+
+2020-12-06 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in emulation/*.el
+
+ * lisp/emulation/edt.el (edt-select-mode):
+ * lisp/emulation/viper-cmd.el (viper-refresh-mode-line):
+ (viper-minibuffer-setup-sentinel):
+ * lisp/emulation/viper.el (viper-comint-mode-hook): Prefer setq-local.
+
+2020-12-06 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in url/*.el
+
+ * lisp/url/url-cookie.el (url-cookie-write-file):
+ * lisp/url/url-http.el (url-http-parse-headers):
+ * lisp/url/url-util.el (url-extract-mime-headers): Prefer setq-local.
+
+2020-12-06 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ Fix Xaw widget text disappearing when built with cairo (bug#43418)
+
+ * lwlib/lwlib-utils.c (crxft_font_open_name): Use FcFontMatch to
+ get a pattern to pass to cairo_ft_font_face_create_for_pattern.
+
+2020-12-05 Andrea Corallo <akrl@sdf.org>
+
+ Memoize `comp-cstr-union-1'
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr): Do not synthesize the
+ copier.
+ (comp-cstr-ctxt): Add `union-1-mem-no-range' `union-1-mem-range'
+ slots.
+ (comp-cstr-copy): New function.
+ (comp-cstr-union-1-no-mem): Rename from `comp-cstr-union-1'.
+ (comp-cstr-union-1): New function.
+
+2020-12-05 Andrea Corallo <akrl@sdf.org>
+
+ More improvements to `comp-cstr-union-1' for mixed positive/negative cases
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-union-1): Better handle
+ mixed positive/negated cases.
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Add a number of tests.
+
+2020-12-05 Andrea Corallo <akrl@sdf.org>
+
+ Fix `comp-cstr-to-type-spec'
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-star-or-num-p): New predicate.
+ (comp-type-spec-to-cstr): Make use of.
+ (comp-cstr-to-type-spec): Output correctly type specifiers
+ as (not (or integer ...
+
+2020-12-05 Andrea Corallo <akrl@sdf.org>
+
+ Fix union of homogeneously negated input constraints
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-union-1): Fix logic.
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Add a couple of tests.
+
+2020-12-05 Andrea Corallo <akrl@sdf.org>
+
+ Add `with-comp-cstr-accessors' macro.
+
+ * lisp/emacs-lisp/comp-cstr.el (with-comp-cstr-accessors): New macro.
+ (comp-cstr-union-1): Make use of `with-comp-cstr-accessors'.
+
+2020-12-05 Andrea Corallo <akrl@sdf.org>
+
+ Initial support for union of negated constraints
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-range-negation): New
+ function.
+ (comp-cstr-union-homogeneous-no-range): Rename from
+ `comp-cstr-union-no-range'.
+ (comp-cstr-union-homogeneous): Rename from `comp-cstr-union'.
+ (comp-cstr-union-1): New function.
+ (comp-cstr-union-no-range, comp-cstr-union): Rewrite in function
+ of `comp-cstr-union-1'.
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Add a bunch of tests.
+
+2020-12-05 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr-union-no-range): Cosmetic.
+
+2020-12-05 Andrea Corallo <akrl@sdf.org>
+
+ Initial constraint negation support
+
+ * lisp/emacs-lisp/comp-cstr.el (comp-cstr): Add `neg' slot.
+ (comp-range-negation, comp-cstr-negation)
+ (comp-cstr-negation-make): New functions.
+ (comp-type-spec-to-cstr): Enable `not` in type specifiers.
+ (comp-cstr-to-type-spec): Update logic to handle negation.
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Add a test.
+
+2020-12-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/perl-mode.el: Fix handling of s'foo'bar'
+
+ (perl-syntax-propertize-function): Don't put a syntax-property
+ on regexp-op delimiters if they're already handled correctly
+ by the normal syntax tables.
+ (perl-syntax-propertize-special-constructs): Mark the middle
+ quote of s'foo'bar' as punctuation.
+
+ * test/manual/indent/perl.perl: Add new test cases.
+
+2020-12-05 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in play/*.el
+
+ * lisp/play/decipher.el (decipher-mode):
+ * lisp/play/doctor.el (make-doctor-variables):
+ * lisp/play/dunnet.el (dun-mode):
+ * lisp/play/gomoku.el (gomoku-mode): Prefer setq-local.
+
+2020-12-05 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix last change to shell-command
+
+ * lisp/simple.el: Specify comint-term-environment arglist in
+ function declaration.
+ (shell-command): Load shell.el before calling
+ comint-term-environment; otherwise it is undefined. Allow
+ async-shell-command-width to take precedence over the COLUMNS value
+ returned by comint-term-environment. (Bug#45034)
+
+2020-12-05 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'ps-print-color-p'
+
+ * doc/emacs/misc.texi (PostScript Variables): Improve and clarify
+ the description of 'ps-print-color-p'. (Bug#44962)
+
+2020-12-05 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in mail/*.el
+
+ * lisp/mail/emacsbug.el (report-emacs-bug):
+ * lisp/mail/rfc822.el (rfc822-addresses):
+ * lisp/mail/rmail.el (rmail-perm-variables, rmail-show-message-1):
+ * lisp/mail/rmailedit.el (rmail-edit-mode):
+ (rmail-edit-current-message, rmail-cease-edit):
+ * lisp/mail/rmailsum.el (rmail-new-summary-1, rmail-summary-mode):
+ (rmail-summary-update-highlight):
+ * lisp/mail/sendmail.el (mail-mode): Prefer setq-local.
+
+2020-12-05 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in vc/*.el
+
+ * lisp/vc/add-log.el (find-change-log, change-log-mode):
+ * lisp/vc/cvs-status.el (cvs-status-mode):
+ * lisp/vc/diff-mode.el (diff-restrict-view, diff-find-file-name):
+ (diff-mode, diff-setup-whitespace, diff-apply-hunk):
+ * lisp/vc/diff.el (diff-no-select):
+ * lisp/vc/ediff-util.el (ediff-setup):
+ * lisp/vc/log-edit.el (log-edit, log-edit-mode):
+ * lisp/vc/log-view.el (log-view-mode):
+ * lisp/vc/pcvs.el (cvs-temp-buffer, cvs-make-cvs-buffer):
+ (cvs-update-filter, cvs-mode, cvs-mode-commit)
+ (cvs-mode-edit-log, cvs-vc-command-advice):
+ * lisp/vc/smerge-mode.el (smerge-match-conflict):
+ (smerge-ediff, smerge-mode):
+ * lisp/vc/vc-annotate.el (vc-annotate-mode):
+ (vc-annotate, vc-annotate-display):
+ * lisp/vc/vc-bzr.el (vc-bzr-log-view-mode):
+ * lisp/vc/vc-dir.el (vc-dir-mode):
+ * lisp/vc/vc-dispatcher.el (vc-setup-buffer):
+ (vc-compilation-mode, vc-start-logentry):
+ * lisp/vc/vc-git.el (vc-git-log-view-mode):
+ * lisp/vc/vc-hg.el (vc-hg-log-view-mode):
+ * lisp/vc/vc-hooks.el (vc-refresh-state):
+ * lisp/vc/vc-mtn.el (vc-mtn-log-view-mode):
+ * lisp/vc/vc-svn.el (vc-svn-log-view-mode):
+ * lisp/vc/vc.el (vc-register, vc-diff-internal):
+ (vc-find-revision-save, vc-find-revision-no-save):
+ (vc-log-internal-common, vc-region-history): Prefer setq-local.
+
+2020-12-05 Dmitry Gutov <dgutov@yandex.ru>
+
+ Always show the summary
+
+ * lisp/progmodes/xref.el (xref--show-defs-minibuffer):
+ Always show the summary (at least for now).
+
+2020-12-05 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fontify the group and the line number
+
+ * lisp/progmodes/xref.el (xref--show-defs-minibuffer):
+ Fontify the group and the line number.
+
+2020-12-05 Dmitry Gutov <dgutov@yandex.ru>
+
+ Hide the common parent directory, if any
+
+ * lisp/progmodes/xref.el (xref--show-defs-minibuffer):
+ Hide the common parent directory, if any.
+
+2020-12-05 William Xu <william.xwl@gmail.com>
+
+ xref--show-defs-minibuffer: new "show definitions" UI
+
+ * lisp/progmodes/xref.el (xref--show-defs-minibuffer):
+ New function to use as xref-show-definitions-function
+ (https://lists.gnu.org/archive/html/emacs-devel/2020-11/msg00824.html).
+
+2020-12-04 Andrea Corallo <akrl@sdf.org>
+
+ Do not compile `comp-cstr.el` in vanilla builds
+
+ * lisp/Makefile.in (compile-targets): Filter out 'comp-cstr.elc'
+ in vanilla builds.
+
+2020-12-04 Andrea Corallo <akrl@sdf.org>
+
+ Vanilla build warning clean-up
+
+ * lisp/emacs-lisp/disass.el (native-comp-unit-file)
+ (subr-native-comp-unit): Declare function.
+ * lisp/progmodes/elisp-mode.el (native-compile): Likewise.
+ * lisp/emacs-lisp/package.el (comp-el-to-eln-filename): Likewise.
+ * lisp/startup.el (normal-top-level): Silence warning.
+ * src/data.c (syms_of_data): 'Ssubr_native_lambda_list' is always
+ defined.
+ * src/pdumper.c (dump_cold_native_subr): Move under ifdefs.
+ (dump_drain_cold_data): Add ifdefs.
+
+2020-12-04 Andrea Corallo <akrl@sdf.org>
+
+ Fix `load-history' causing a number of spurious compiler warnings
+
+ * src/comp.c (Fcomp__register_subr): Fix missing entry into
+ `load-history' indicating that the loaded function was already an
+ autoload.
+
+2020-12-04 Spencer Baugh <sbaugh@catern.com>
+
+ * src/alloc.c (Fgarbage_collect_maybe): New function
+
+2020-12-04 Dmitry Gutov <dgutov@yandex.ru>
+
+ Improve docstrings
+
+ * lisp/progmodes/xref.el (xref-search-program-alist)
+ (xref-search-program): Improve docstrings.
+
+2020-12-04 Roland Winkler <winkler@gnu.org>
+
+ * lisp/textmodes/bibtex.el: Use user-error.
+
+2020-12-04 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in emacs-lisp/*.el
+
+ * lisp/emacs-lisp/chart.el (chart-mode):
+ * lisp/emacs-lisp/copyright.el (copyright-update):
+ * lisp/emacs-lisp/eieio-custom.el (eieio-customize-object):
+ * lisp/emacs-lisp/elint.el (elint-update-env, elint-init-form):
+ * lisp/emacs-lisp/ert.el (ert--results-update-ewoc-hf):
+ (ert--setup-results-buffer):
+ * lisp/emacs-lisp/lisp-mode.el (lisp-mode-variables):
+ * lisp/emacs-lisp/pp.el (pp-display-expression):
+ * lisp/emacs-lisp/re-builder.el (reb-mode, reb-restart-font-lock):
+ * lisp/emacs-lisp/shadow.el (load-path-shadows-mode):
+ * lisp/emacs-lisp/smie.el (smie-setup):
+ * lisp/emacs-lisp/syntax.el (syntax-propertize):
+ * lisp/emacs-lisp/trace.el (trace-make-advice): Prefer setq-local.
+
+2020-12-04 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in net/*.el
+
+ * lisp/net/ange-ftp.el (ange-ftp-process-handle-line):
+ (internal-ange-ftp-mode):
+ * lisp/net/imap.el (imap-fetch-safe):
+ * lisp/net/net-utils.el (net-utils-mode):
+ (nslookup-mode, network-connection-mode-setup):
+ * lisp/net/newst-plainview.el (newsticker-mode):
+ (newsticker-buffer-update):
+ * lisp/net/newst-treeview.el (newsticker--treeview-item-show):
+ (newsticker-treeview-mode):
+ * lisp/net/rlogin.el (rlogin):
+ * lisp/net/secrets.el (secrets-mode):
+ * lisp/net/sieve-mode.el (sieve-mode):
+ * lisp/net/sieve.el (sieve-setup-buffer, sieve-open-server):
+ * lisp/net/snmp-mode.el (snmp-common-mode, snmp-mode, snmpv2-mode):
+ * lisp/net/telnet.el (telnet-mode):
+ * lisp/net/tramp.el (tramp-get-debug-buffer): Prefer setq-local.
+
+2020-12-04 Mattias Engdegård <mattiase@acm.org>
+
+ Speed up match-substitute-replacement
+
+ * lisp/subr.el (match-substitute-replacement): Use match-data--translate.
+ * src/search.c (Fmatch_data__translate): Remove string restriction.
+ * test/lisp/subr-tests.el (subr-match-substitute-replacement): New test.
+
+2020-12-04 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in cedet
+
+ * lisp/cedet/data-debug.el (data-debug-mode):
+ * lisp/cedet/ede/custom.el (ede-customize-project):
+ * lisp/cedet/ede/project-am.el (project-am-load-makefile):
+ * lisp/cedet/mode-local.el (mode-local--activate-bindings):
+ * lisp/cedet/semantic.el (semantic--set-buffer-cache):
+ * lisp/cedet/semantic/analyze/debug.el
+ (semantic-analyzer-debug-add-buttons):
+ * lisp/cedet/semantic/grammar.el (semantic-grammar-mode):
+ * lisp/cedet/semantic/senator.el (senator-search-set-tag-class-filter):
+ (senator-isearch-mode-hook):
+ * lisp/cedet/semantic/symref/list.el
+ (semantic-symref-produce-list-on-results)
+ (semantic-symref-results-mode):
+ * lisp/cedet/semantic/util-modes.el (semantic-stickyfunc-mode):
+ * lisp/cedet/semantic/wisent/python.el (wisent-python-default-setup):
+ * lisp/cedet/srecode/srt-mode.el (srecode-template-mode):
+ Prefer setq-local.
+
+2020-12-04 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in most of textmodes/*.el
+
+ * lisp/textmodes/artist.el (artist-mode-init):
+ * lisp/textmodes/bibtex.el (bibtex-mode):
+ * lisp/textmodes/dns-mode.el (dns-mode):
+ * lisp/textmodes/enriched.el (enriched-mode):
+ * lisp/textmodes/ispell.el (ispell-buffer-local-parsing):
+ * lisp/textmodes/nroff-mode.el (nroff-mode):
+ * lisp/textmodes/picture.el (picture-mode):
+ * lisp/textmodes/refill.el (refill-mode):
+ * lisp/textmodes/two-column.el (2C-split): Prefer setq-local.
+
+2020-12-04 Eli Zaretskii <eliz@gnu.org>
+
+ Don't abort when terminated by SIGINT in -batch
+
+ * src/xdisp.c (clear_message_stack): New function.
+ * src/emacs.c (terminate_due_to_signal): Call clear_message_stack
+ when we are being shut down by SIGINT under -batch.
+ * src/lisp.h (clear_message_stack): Add prototype.
+
+2020-12-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make custom-data saving atomic
+
+ * lisp/cus-edit.el (custom-save-all): Do the custom saves as an
+ atomic change group, to avoid writing invalid data if something
+ goes wrong (or the user hits `C-g') in the middle (bug#18633).
+
+2020-12-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow viper-save-setting to save numerical settings
+
+ * lisp/emulation/viper-util.el (viper-save-setting): Allow saving
+ numerical settings (bug#18928).
+
+2020-12-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify icomplete-show-matches-on-no-input doc string
+
+ * lisp/icomplete.el (icomplete-show-matches-on-no-input): Clarify
+ the meaning of the variable (bug#19031).
+
+2020-12-04 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in erc
+
+ * lisp/erc/erc-goodies.el (erc-imenu-setup):
+ * lisp/erc/erc-list.el (erc-list-install-322-handler, erc-cmd-LIST):
+ * lisp/erc/erc-pcomplete.el (pcomplete-erc-setup):
+ * lisp/erc/erc.el (erc-mode, erc-update-mode-line-buffer):
+ Prefer setq-local.
+
+2020-12-04 Alyssa Ross <hi@alyssa.is> (tiny change)
+
+ Make shell-command use comint settings
+
+ * lisp/simple.el (shell-command): Use the term environment from
+ comint, so that comint settings are used for commands like
+ `async-shell-command', too (bug#45034).
+
+2020-12-04 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/eshell/esh-mode.el (eshell-mode): Remove XEmacs compat code.
+
+2020-12-04 Stefan Kangas <stefan@marxist.se>
+
+ Prefer setq-local in eshell
+
+ * lisp/eshell/em-cmpl.el (eshell-cmpl-initialize):
+ * lisp/eshell/em-dirs.el (eshell-dirs-initialize):
+ * lisp/eshell/em-glob.el (eshell-glob-initialize, eshell-glob-regexp):
+ * lisp/eshell/em-hist.el (eshell-hist-initialize):
+ * lisp/eshell/em-prompt.el (eshell-prompt-initialize):
+ * lisp/eshell/em-rebind.el (eshell-rebind-initialize)
+ (eshell-setup-input-keymap):
+ * lisp/eshell/em-script.el (eshell-script-initialize):
+ * lisp/eshell/em-smart.el (eshell-smart-initialize):
+ * lisp/eshell/em-term.el (eshell-term-initialize, eshell-exec-visual):
+ * lisp/eshell/em-tramp.el (eshell-tramp-initialize):
+ * lisp/eshell/em-unix.el (eshell-unix-initialize, eshell/diff):
+ * lisp/eshell/esh-arg.el (eshell-arg-initialize):
+ * lisp/eshell/esh-cmd.el (eshell-cmd-initialize):
+ * lisp/eshell/esh-io.el (eshell-get-target):
+ * lisp/eshell/esh-mode.el (eshell-mode):
+ * lisp/eshell/esh-var.el (eshell-var-initialize): Prefer setq-local.
+
+2020-12-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Preload iso-trans.el
+
+ * lisp/loadup.el ("international/iso-transl"): Load by default so
+ that we get `Alt-' bindings (bug#21310).
+
+ * lisp/international/iso-transl.el: Remove autoloads and some
+ comments.
+
+2020-12-04 Dmitry Gutov <dgutov@yandex.ru>
+
+ Support using ripgrep in project-find-regexp and friends
+
+ Performance results vary here. Some projects and search terms
+ don't see much of a change, but for some (including Emacs sources
+ checkout and case-insensitive search) the switch to ripgrep shows
+ ~2-3x speed improvement. Another piece of anecdata here:
+ https://lists.gnu.org/archive/html/emacs-devel/2020-06/msg00802.html
+
+ * lisp/progmodes/xref.el (xref-search-program-alist)
+ (xref-search-program): New user options.
+ (xref-matches-in-files): Use them.
+
+2020-12-04 Andrea Corallo <akrl@sdf.org>
+
+ Reduce (half) the number of loads emitted for calling into C code
+
+ As after each function call GCC clobbers the pointer to the function
+ relocation table. This commit modify the code generation to create a
+ local copy of it for each function. This reduces the average number
+ of loads for each function call into C from two to one.
+
+ * src/comp.c (comp_t): Add 'func_relocs_ptr_type' and
+ 'func_relocs_local' fields.
+ (emit_call): Use the local func_relocs pointer when possible.
+ (emit_ctxt_code): Fill 'comp.func_relocs_ptr_type'.
+ (compile_function): Declare 'func_relocs_ptr_local'.
+ (compile_function): Assign 'func_relocs_ptr_local' from the global
+ value in each function prologue.
+
+2020-12-03 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Restore nnimap-split-download-body as a customization option
+
+ * lisp/gnus/nnimap.el (nnimap-split-download-body): And add an
+ obsolete alias for `nnimap-split-download-body-default'.
+ (nnimap-fetch-inbox): Check the value of the option, not the variable.
+ * doc/misc/gnus.texi (Client-Side IMAP Splitting): Move the primary
+ documentation of this option to this section.
+
+2020-12-03 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Define explicit-shell-file-name only in shell.el
+
+ For discussion, see the following thread:
+ https://lists.gnu.org/r/emacs-devel/2020-04/msg00880.html
+
+ * doc/emacs/cmdargs.texi (General Variables): Mention
+ shell-file-name in relation to SHELL.
+ * doc/emacs/misc.texi (Interactive Shell): Move index entry for
+ SHELL environment variable from here, where it is not mentioned...
+ (Single Shell): ...to here, where it is discussed along with
+ shell-file-name.
+ * lisp/dired.el (dired-insert-directory): Use shell-file-name
+ instead of explicit-shell-file-name when a shell is implicitly
+ requested.
+ * lisp/obsolete/terminal.el (explicit-shell-file-name):
+ * lisp/term.el (explicit-shell-file-name): Remove duplicate
+ defcustoms and load lisp/shell.el instead. (Bug#40679)
+ * lisp/shell.el (explicit-shell-file-name): Clarify docstring.
+ (shell): Simplify.
+
+2020-12-03 Stefan Kangas <stefan@marxist.se>
+
+ Add tests for several byte-compiler warnings
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (bytecomp/warn-autoload-not-on-top-level\.el)
+ (bytecomp/warn-callargs\.el)
+ (bytecomp/warn-defcustom-nogroup\.el)
+ (bytecomp/warn-defcustom-notype\.el)
+ (bytecomp/warn-defvar-lacks-prefix\.el)
+ (bytecomp/warn-format\.el)
+ (bytecomp/warn-lambda-malformed-interactive-spec\.el)
+ (bytecomp/warn-make-variable-buffer-local\.el)
+ (bytecomp/warn-redefine-defun-as-macro\.el)
+ (bytecomp/warn-redefine-defun\.el)
+ (bytecomp/warn-redefine-macro-as-defun\.el)
+ (bytecomp/warn-save-excursion\.el)
+ (bytecomp/warn-variable-let-bind-constant\.el)
+ (bytecomp/warn-variable-let-bind-nonvariable\.el)
+ (bytecomp/warn-variable-set-constant\.el)
+ (bytecomp/warn-variable-set-nonvariable\.el): New tests.
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-autoload-not-on-top-level.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-callargs.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-defcustom-nogroup.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-defcustom-notype.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-defvar-lacks-prefix.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-format.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-lambda-malformed-interactive-spec.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-make-variable-buffer-local.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-redefine-defun-as-macro.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-redefine-defun.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-redefine-macro-as-defun.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-save-excursion.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-variable-let-bind-constant.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-variable-let-bind-nonvariable.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-variable-set-constant.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-variable-set-nonvariable.el:
+ * test/lisp/emacs-lisp/bytecomp-tests.el: New files.
+
+2020-12-03 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Avoid spamming view-mode-enter help message
+
+ By default, entering view-mode echoes a usage message. This is
+ particularly helpful with non-nil view-read-only, to notify the user
+ that view-mode has been enabled. It is less useful and more spammy,
+ however, if view-mode is (possibly inadvertently) entered from some
+ non-interactive code running in the background, such as when a major
+ mode is enabled in a temporary buffer for text formatting
+ purposes (bug#44629).
+
+ * lisp/jsonrpc.el (jsonrpc-events-buffer, initialize-instance): Use
+ buffer-read-only in place of read-only-mode for non-interactive use.
+ * lisp/view.el (view-mode-enter): Inhibit help message if either
+ view-inhibit-help-message is non-nil, or view-mode-enter was called
+ from an interactive command. Suggested by João Távora
+ <joaotavora@gmail.com>.
+
+2020-12-03 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix auto-revert-test07-auto-revert-several-buffers
+
+ * test/lisp/autorevert-tests.el
+ (auto-revert-test07-auto-revert-several-buffers): Adapt times values.
+
+2020-12-03 Spencer Baugh <sbaugh@catern.com>
+
+ Improve performance of auto-revert-notify-add-watch
+
+ * lisp/autorevert.el (auto-revert-notify-add-watch):
+ Do not search for buffers registered with the same file name, this
+ is not necessary. (Bug#44638)
+
+2020-12-03 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant requires of 'help'
+
+ * lisp/emacs-lisp/advice.el (ad-read-advised-function):
+ * lisp/emacs-lisp/ert.el:
+ * lisp/facemenu.el: Don't require 'help'; it is preloaded since
+ version 18.59.
+
+2020-12-03 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant requires of 'button'
+
+ * lisp/apropos.el:
+ * lisp/emacs-lisp/cl-print.el:
+ * lisp/emacs-lisp/debug.el:
+ * lisp/emacs-lisp/ert.el:
+ * lisp/emacs-lisp/shadow.el:
+ * lisp/facemenu.el:
+ * lisp/help-mode.el:
+ * lisp/man.el:
+ * lisp/progmodes/etags.el:
+ * lisp/textmodes/bibtex.el:
+ * lisp/woman.el: Don't require 'button'; it is preloaded since version
+ 23.1.
+
+2020-12-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix "grep foo bar" in eshell
+
+ * lisp/eshell/em-unix.el (eshell-grep): Use the -H switch so that
+ we always get the file name, so that `M-x next-error' and friends
+ work (bug#22330).
+
+2020-12-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't make grep arguments invisible in eshell
+
+ * lisp/eshell/em-unix.el (eshell-grep): There doesn't seem to be
+ any reason why parts of the command should be invisible, so don't
+ do that.
+
+2020-12-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Recompute error positions in python-shell-send-region
+
+ * lisp/progmodes/python.el (python-shell-send-region): Recompute
+ line positions when evaluating (bug#22934).
+
+2020-12-03 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove redundant requires of 'custom'
+
+ * lisp/emacs-lisp/eieio-custom.el:
+ * lisp/htmlfontify.el:
+ * lisp/mwheel.el:
+ * lisp/net/eudc-vars.el:
+ * lisp/net/ldap.el:
+ * lisp/net/tramp-ftp.el:
+ * lisp/net/tramp-gvfs.el:
+ * lisp/progmodes/cwarn.el:
+ * lisp/progmodes/sql.el:
+ * lisp/savehist.el:
+ * lisp/textmodes/reftex.el:
+ * lisp/wid-browse.el: Don't require 'custom'; it is preloaded since
+ version 20.1.
+
+2020-12-03 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove redundant requires of 'font-core'
+
+ * lisp/ibuffer.el:
+ * test/lisp/erc/erc-track-tests.el: Don't require 'font-core'; it is
+ preloaded since version 22.1.
+
+2020-12-03 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove redundant requires of 'font-lock'
+
+ * lisp/cedet/data-debug.el:
+ * lisp/hi-lock.el:
+ * lisp/htmlfontify.el:
+ * lisp/org/org.el:
+ * lisp/progmodes/cperl-mode.el:
+ * lisp/progmodes/cwarn.el: Don't require 'font-lock'; it is preloaded
+ since version 22.1.
+
+2020-12-02 Roland Winkler <winkler@gnu.org>
+
+ bibtex-autokey-get-year: Allow both a year or date field.
+
+ * lisp/textmodes/bibtex.el (bibtex-text-in-field): Allow arg field
+ to be a list of fields.
+ (bibtex-autokey-get-year): Look for year and date field. Allow
+ the extended date format used by biblatex.
+
+2020-12-02 Roland Winkler <winkler@gnu.org>
+
+ bibtex-mode: do not fail when local variables are disabled
+
+ * lisp/textmodes/bibtex.el (bibtex-mode): Check if
+ enable-local-variables is non-nil (bug#37957).
+
+2020-12-02 Roland Winkler <winkler@gnu.org>
+
+ Allow bibtex-contline-indentation as file-local variable.
+
+ * lisp/textmodes/bibtex.el (bibtex-contline-indentation)
+ (bibtex-comment-start, bibtex-entry-offset, bibtex-text-indentation):
+ Add :safe attribute.
+ (bibtex-mode): Allow these variables as file-local variables
+ (bug#44618 and bug#44647).
+
+2020-12-02 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant requires of faces
+
+ * lisp/htmlfontify.el:
+ * lisp/term/ns-win.el:
+ * lisp/term/w32-win.el:
+ * lisp/term/x-win.el:
+ * test/lisp/faces-tests.el: Don't require 'faces'; it is preloaded
+ since version 19.34.
+
+2020-12-02 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant requires of env
+
+ * lisp/eshell/esh-var.el:
+ * lisp/man.el: Don't require 'env'; it is preloaded since version
+ 20.1.
+
+2020-12-02 Roland Winkler <winkler@gnu.org>
+
+ Allow bibtex-unify-case-function as file-local variable
+
+ * lisp/textmodes/bibtex.el (bibtex-unify-case-function):
+ Renamed from bibtex-unify-case-convert. Add :safe attribute.
+ * etc/NEWS: Update accordingly.
+
+2020-12-02 Michael Albinus <michael.albinus@gmx.de>
+
+ Add test to autorevert-tests.el
+
+ * test/lisp/autorevert-tests.el (auto-revert--wait-for-revert):
+ Handle `auto-revert--messages' being nil.
+ (auto-revert-test07-auto-revert-several-buffers): New test.
+
+2020-12-02 Stefan Kangas <stefan@marxist.se>
+
+ Improve sectioning in bytecomp-tests.el
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el: Add section comments.
+ (test-eager-load-macro-expansion)
+ (test-eager-load-macro-expansion-eval-and-compile): Move definitions.
+
+2020-12-02 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/play/dunnet.el: Remove Emacs 18 compat code.
+
+2020-12-02 Stefan Kangas <stefan@marxist.se>
+
+ Make variable cperl-version obsolete
+
+ * lisp/progmodes/cperl-mode.el (cperl-menu): Remove CPerl version
+ menu entry.
+ (cperl-version): Make obsolete.
+
+2020-12-02 Stefan Kangas <stefan@marxist.se>
+
+ Remove some Emacs 19 compat code from cperl-mode
+
+ * lisp/progmodes/cperl-mode.el
+ (cperl-put-do-not-fontify): Remove Emacs 19 compat code.
+ (cperl-do-not-fontify): Make obsolete.
+
+2020-12-02 Stefan Kangas <stefan@marxist.se>
+
+ Remove some references to fast-lock and lazy-lock
+
+ * lisp/htmlfontify.el (hfy-copy-and-fontify-file):
+ * lisp/progmodes/antlr-mode.el: Remove some references to obsolete
+ libraries fast-lock and lazy-lock.
+
+2020-12-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix alignment of declaractions of arrays
+
+ * lisp/align.el (align-rules-list): Align variable declarations
+ like char *foo[], too (bug#23370).
+
+2020-12-02 Michael Albinus <michael.albinus@gmx.de>
+
+ * INSTALL: Add the installation command of development packages for FreeBSD.
+
+ Recipe contributed by Joseph Mingrone <jrm@ftfl.ca>.
+
+2020-12-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add tests for xsd-regexp
+
+2020-12-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix xsdre-range-list-to-char-alternative problem with {P}
+
+ * lisp/nxml/xsd-regexp.el (xsdre-range-list-to-char-alternative):
+ Make (string-match (xsdre-translate "\\p{P}") "a-b") work
+ (bug#24093) -- the "forbidden" characters don't have to be the
+ first elements in a range.
+
+2020-12-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix the message-fetch-field doc string
+
+ * lisp/gnus/message.el (message-fetch-field): Improve the doc
+ string (bug#44991).
+
+2020-12-02 Stefan Kangas <stefan@marxist.se>
+
+ Remove specific byte-compiler warnings for cl.el
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-warning-types)
+ (byte-compile-warnings, byte-compile-cl-file-p)
+ (byte-compile-eval, byte-compile-eval-before-compile)
+ (byte-compile-arglist-warn, byte-compile-find-cl-functions)
+ (byte-compile-cl-warn, displaying-byte-compile-warnings)
+ (byte-compile-file-form-require, byte-compile-form): Remove all
+ specific cl.el warnings, as that library is now obsolete. The
+ regular obsoletion warnings are sufficiently discouraging.
+ * lisp/emacs-lisp/advice.el (ad-compile-function): Don't try to
+ silence the now removed warning.
+ * doc/lispref/tips.texi (Coding Conventions):
+ * doc/misc/cl.texi (Organization): Make recommendation to not use
+ cl.el and cl-compat.el stronger.
+ * lisp/obsolete/cl.el: Make alias help say that they are obsolete.
+ * lisp/obsolete/cl-compat.el (build-klist, safe-idiv)
+ (pair-with-newsyms): Silence byte-compiler.
+
+2020-12-02 Dmitry Gutov <dgutov@yandex.ru>
+
+ Improve .gitignore and project-vc-ignores handling
+
+ * lisp/progmodes/project.el (project-ignores):
+ Convert .gitignore entries more faithfully.
+ (project--vc-list-files): Convert "our" ignore entries to
+ "proper" globs, which is what Git pathspec requires.
+
+2020-12-02 Dmitry Gutov <dgutov@yandex.ru>
+
+ Use project--value-in-dir
+
+ * lisp/progmodes/project.el (project-files):
+ Use 'project--value-in-dir'. To have any changes in
+ 'project-vc-ignores' take effect immediately.
+
+2020-12-01 Juri Linkov <juri@linkov.net>
+
+ Fix documentation of window-in-direction arg MINIBUF (bug#44932)
+
+ * doc/lispref/windows.texi (Windows and Frames): Rename MINI arg
+ of window-in-direction to MINIBUF. Explain the non-nil non-t value.
+
+2020-12-01 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 749e4b7e0b Reset xref-show-xrefs-function temporarily
+ 3e6525d69f Don't show in 'view-lossage' responses to xterm feature qu...
+ 9fbff9c35c ; * src/buffer.c: Fix comment describing 'buffer_defaults'.
+
+2020-12-01 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 9939c435c1 Return the correct suffix in eww-make-unique-file-name
+ 17fa17be3d Save bookmarks by using `write-file' (bug#12507)
+ 2cdf1fd261 Fix filing messages when 'rmail-output-reset-deleted-flag'...
+ a72db8ab8b Make file copying in tramp-gvfs more robust
+ f31cacd1ff Revert "Fix incorrect handling of module runtime and envir...
+ cdc632fbe6 Fix incorrect handling of module runtime and environment p...
+ c9160bda78 CC Mode: Fix error in cache handling. This fixes bug #43481
+
+2020-12-01 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/arc-mode.el (archive-get-descr): Use default mode if needed.
+
+2020-12-01 Michael Albinus <michael.albinus@gmx.de>
+
+ Allow Tramp to mirror traces to a file
+
+ * doc/misc/tramp.texi (Traces and Profiles): Add `tramp-debug-to-file'.
+
+ * lisp/net/tramp-adb.el (tramp-adb-parse-device-names)
+ (tramp-adb-get-device):
+ * lisp/net/tramp-cmds.el (tramp-rename-files):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-monitor-process-filter)
+ (tramp-gvfs-handler-volumeadded-volumeremoved)
+ (tramp-get-media-devices):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-file-notify-add-watch)
+ (tramp-sh-gio-monitor-process-filter)
+ (tramp-sh-gvfs-monitor-dir-process-filter)
+ (tramp-sh-inotifywait-process-filter, tramp-maybe-send-script)
+ (tramp-find-inline-encoding):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-copy-directory)
+ (tramp-smb-handle-file-acl, tramp-smb-handle-set-file-acl):
+ Use `tramp-compat-string-replace'.
+
+ * lisp/net/tramp-compat.el (tramp-compat-string-replace): New defalias.
+
+ * lisp/net/tramp.el (tramp-debug-to-file): New defcustom.
+ (tramp-get-debug-buffer): Simplify.
+ (tramp-get-debug-file-name): New defun.
+ (tramp-debug-message): Write debug file if indicated.
+
+2020-12-01 Michael Albinus <michael.albinus@gmx.de>
+
+ * etc/NEWS: Add user option 'tramp-debug-to-file'.
+
+2020-12-01 Stefan Kangas <stefan@marxist.se>
+
+ Fix byte-compiler warning for failed uses of lexical vars
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-form): Fix byte-compiler
+ warning for failed uses of lexical vars. (Bug#44980)
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (bytecomp--define-warning-file-test): Don't prefix tests with
+ 'warn'.
+ (bytecomp/error-lexical-var-with-add-hook\.el)
+ (bytecomp/error-lexical-var-with-remove-hook\.el)
+ (bytecomp/error-lexical-var-with-run-hook-with-args-until-failure\.el)
+ (bytecomp/error-lexical-var-with-run-hook-with-args-until-success\.el)
+ (bytecomp/error-lexical-var-with-run-hook-with-args\.el)
+ (bytecomp/error-lexical-var-with-symbol-value\.el): New tests.
+ * test/lisp/emacs-lisp/bytecomp-resources/error-lexical-var-with-symbol-value.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/error-lexical-var-with-run-hook-with-args.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/error-lexical-var-with-run-hook-with-args-until-success.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/error-lexical-var-with-run-hook-with-args-until-failure.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/error-lexical-var-with-remove-hook.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/error-lexical-var-with-add-hook.el:
+ New files.
+
+2020-12-01 Zajcev Evgeny <zevlg@yandex.ru>
+
+ Fix use of 'switch-to-buffer-preserve-window-point'
+
+ * lisp/window.el (switch-to-buffer): Respect buffer local value
+ of 'switch-to-buffer-preserve-window-point' variable.
+
+2020-12-01 Stefan Kangas <stefan@marxist.se>
+
+ Add tests for some byte-compiler warnings
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (bytecomp-warn/warn-interactive-only\.el)
+ (bytecomp-warn/warn-obsolete-defun\.el)
+ (bytecomp-warn/warn-obsolete-hook\.el)
+ (bytecomp-warn/warn-obsolete-variable-same-file\.el)
+ (bytecomp-warn/warn-obsolete-variable\.el): New tests.
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-interactive-only.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-obsolete-defun.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-obsolete-hook.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-obsolete-variable-same-file.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-obsolete-variable.el:
+ New files.
+
+2020-12-01 Dmitry Gutov <dgutov@yandex.ru>
+
+ Reset xref-show-xrefs-function temporarily
+
+ * lisp/dired-aux.el (dired-do-find-regexp-and-replace):
+ Make sure xref-show-xrefs-function has the necessary value (bug#44905).
+
+2020-12-01 Andrea Corallo <akrl@sdf.org>
+
+ Fix `comp-mvar-symbol-p' and `comp-mvar-cons-p' (bug#44968)
+
+ * lisp/emacs-lisp/comp.el (comp-mvar-symbol-p): As all slots into
+ a `comp-cstr' are in or fix this logic.
+ (comp-mvar-cons-p): Likewise.
+ * test/src/comp-tests.el (bug-44968): New testcase.
+ * test/src/comp-test-funcs.el (comp-test-44968-f): New test
+ function.
+
+2020-11-30 Stefan Kangas <stefan@marxist.se>
+
+ Decrease code duplication in byte-compiler free-vars warning
+
+ * lisp/emacs-lisp/bytecomp.el
+ (byte-compile-free-vars-warn): New defun extracted from...
+ (byte-compile-variable-ref, byte-compile-variable-set): ...here.
+
+2020-11-30 Stefan Kangas <stefan@marxist.se>
+
+ Test byte-compiler free variable warning
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el (ert-x): Require.
+ (bytecomp--define-warning-file-test): New macro.
+ (bytecomp-warn/warn-free-setq\.el)
+ (bytecomp-warn/warn-free-variable-reference\.el): New tests.
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-free-setq.el:
+ * test/lisp/emacs-lisp/bytecomp-resources/warn-free-variable-reference.el:
+ New files.
+
+2020-11-30 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/so-long.el: Doc fix to reduce use of passive voice.
+
+2020-11-30 Eli Zaretskii <eliz@gnu.org>
+
+ Don't show in 'view-lossage' responses to xterm feature queries
+
+ * lisp/term/xterm.el (xterm--read-event-for-query): Prevent
+ recording the characters read as the xterm response to a query,
+ so as not to show them in 'view-lossage'. (Bug#44908)
+
+2020-11-30 Michael Albinus <michael.albinus@gmx.de>
+
+ Some adaptions to tramp-tests.el
+
+ * test/lisp/net/tramp-tests.el (tramp-test-vec): Check for remote
+ `tramp-test-temporary-file-directory'.
+ (tramp-test11-copy-file, tramp-test12-rename-file):
+ Do not skip for tramp-gvfs.el.
+ (tramp--test-sh-p): Use `tramp-test-vec'.
+
+2020-11-30 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt Tramp versions
+
+ * doc/misc/tramp.texi (Obtaining @value{tramp}):
+ (Remote shell setup, Remote processes, Archive file names):
+ * lisp/net/trampver.el (customize-package-emacs-version-alist):
+ Adapt Tramp versions.
+
+2020-11-30 Dmitry Gutov <dgutov@yandex.ru>
+
+ Improve docstrings
+
+ * lisp/progmodes/project.el (project-find-file)
+ (project-or-external-find-file): More accurate docstrings (bug#44588).
+
+2020-11-29 Philipp Stephani <phst@google.com>
+
+ Fix double-free bug when finalizing module runtimes.
+
+ * src/emacs-module.c (finalize_runtime_unwind): Don't finalize initial
+ environment twice.
+
+ * test/src/emacs-module-resources/mod-test.c (emacs_module_init):
+ Allocate lots of values during module initialization to trigger the
+ bug.
+
+2020-11-29 Juri Linkov <juri@linkov.net>
+
+ * lisp/simple.el (read-from-kill-ring): Call current-kill to prefill kill-ring
+
+2020-11-29 Juri Linkov <juri@linkov.net>
+
+ Fix MINIBUF 'nomini' arg for windmove/window-in-direction (bug#44932)
+
+ * lisp/windmove.el (windmove-display-in-direction)
+ (windmove-delete-in-direction, windmove-swap-states-in-direction):
+ Add 'nomini' as MINIBUF arg of window-in-direction.
+
+ * lisp/window.el (window-in-direction): Rename arg MINI to MINIBUF.
+ Update docstring from walk-window-tree.
+ Send MINIBUF arg to walk-window-tree unchanged.
+
+2020-11-29 Alan Third <alan@idiocy.org>
+
+ Allow doprint to handle multibyte chars in format (bug#44349)
+
+ * src/doprnt.c (doprnt): Handle the case where fmtchar is the start of
+ a multibyte character.
+
+2020-11-29 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-11-29 Protesilaos Stavrou <info@protesilaos.com>
+
+ Make log-view-commit-body less intrusive
+
+ * lisp/vc/log-view.el (log-view-commit-body): Inherit from
+ font-lock-comment-face. This makes expanded commit messages in
+ log-view look the same as they did prior to commit 1f0b929430 (consult
+ bug#44424) (bug#44937).
+
+2020-11-29 Akira Kyle <akira@akirakyle.com>
+
+ Return the correct suffix in eww-make-unique-file-name
+
+ * lisp/net/eww.el (eww-make-unique-file-name): Return the correct
+ suffix (bug#44936).
+
+2020-11-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ frame-position doc string clarificaton
+
+ * src/frame.c (Fframe_position): Mention that the values are
+ system-dependent (bug#32977).
+
+2020-11-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ garbage-collect doc string clarification
+
+ * src/alloc.c (Fgarbage_collect): Mention that calling this
+ function is not guaranteed to collect all the garbage (bug#34404).
+
+2020-11-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak eww-use-browse-url doc string
+
+ * lisp/net/eww.el (eww-use-browse-url): Tweak doc string wording.
+
+2020-11-29 Karl Fogel <kfogel@red-bean.com>
+
+ Save bookmarks by using `write-file' (bug#12507)
+
+ Go back to using `write-file' to save bookmarks, instead of using
+ `write-region'. This means numbered backups of the bookmark file may
+ get made again, depending on the value of `bookmark-version-control'.
+
+ Thanks especially to Drew Adams and Eli Zaretskii for their
+ persistence in tracking down information relevant to this change.
+
+2020-11-28 Eli Zaretskii <eliz@gnu.org>
+
+ Fix filing messages when 'rmail-output-reset-deleted-flag' is non-nil
+
+ * lisp/mail/rmailout.el (rmail-output): Fix off-by-one error in
+ deciding when to advance to the next message under non-nil
+ 'rmail-output-reset-deleted-flag'. (Bug#44839)
+
+2020-11-28 Lele Gaifax <lele@metapensiero.it>
+
+ Update TUTORIAL.it
+
+ * etc/tutorials/TUTORIAL.it: Follow changes made to TUTORIAL in the
+ last year
+
+2020-11-28 Michael Albinus <michael.albinus@gmx.de>
+
+ Make file copying in tramp-gvfs more robust
+
+ * test/lisp/net/tramp-tests.el (tramp-test11-copy-file)
+ (tramp-test12-rename-file): Do not skip for tramp-gvfs.el.
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-do-copy-or-rename-file):
+ Add sanity checks.
+
+2020-11-28 Mattias Engdegård <mattiase@acm.org>
+
+ * etc/tutorials/TUTORIAL.sv: General copy-editing.
+
+2020-11-28 Eli Zaretskii <eliz@gnu.org>
+
+ Revert "Fix incorrect handling of module runtime and environment pointers."
+
+ This reverts commit cdc632fbe6e149318147a98cccf1b7af191f2ce8.
+ Those changes are too significant and non-trivial to be
+ suitable for a release branch at this time.
+
+2020-11-27 Andrea Corallo <akrl@sdf.org>
+
+ Add intersection support into comp-cstr.el
+
+2020-11-27 Andrea Corallo <akrl@sdf.org>
+
+ Synthesize as const primitive function pointers and its container struct.
+
+ * src/comp.c (declare_imported_func): Make const function pointer
+ to primitive functions.
+ (emit_ctxt_code): Make struct 'comp.func_relocs' const.
+
+2020-11-27 Philipp Stephani <phst@google.com>
+
+ Fix incorrect handling of module runtime and environment pointers.
+
+ We used to store module runtime and environment pointers in the static
+ lists Vmodule_runtimes and Vmodule_environments. However, this is
+ incorrect because these objects have to be kept per-thread. With this
+ naive approach, interleaving module function calls in separate threads
+ leads to environments being removed in the wrong order, which in turn
+ can cause local module values to be incorrectly garbage-collected.
+
+ Instead, turn Vmodule_runtimes and Vmodule_environments into
+ hashtables keyed by the thread objects. The fix is relatively
+ localized and should therefore be safe enough for the release branch.
+
+ Module assertions now have to walk the pointer list for the current
+ thread, which is more correct since they now only find environments
+ for the current thread.
+
+ Also add a unit test that exemplifies the problem. It interleaves two
+ module calls in two threads so that the first call ends while the
+ second one is still active. Without this change, this test triggers
+ an assertion failure.
+
+ * src/emacs-module.c (Fmodule_load, initialize_environment)
+ (finalize_environment, finalize_runtime_unwind): Store runtime and
+ environment pointers in per-thread lists.
+ (syms_of_module): Initialize runtimes and environments hashtables.
+ (module_assert_runtime, module_assert_env, value_to_lisp): Consider
+ only objects for the current thread.
+ (module_gc_hash_table_size, module_hash_push, module_hash_pop): New
+ generic hashtable helper functions.
+ (module_objects, module_push_pointer, module_pop_pointer): New helper
+ functions to main thread-specific lists of runtime and environment
+ pointers.
+ (mark_modules): Mark all environments in all threads.
+
+ * test/data/emacs-module/mod-test.c (Fmod_test_funcall): New test
+ function.
+ (emacs_module_init): Bind it.
+
+ * test/src/emacs-module-tests.el (emacs-module-tests--variable): New
+ helper type to guard access to state in a thread-safe way.
+ (emacs-module-tests--wait-for-variable)
+ (emacs-module-tests--change-variable): New helper functions.
+ (emacs-module-tests/interleaved-threads): New unit test.
+
+2020-11-27 Mattias Engdegård <mattiase@acm.org>
+
+ Use correct glyph in title when resizing NS frames
+
+ * src/nsterm.m ([EmacsView windowWillResize:toSize:]): Use ×, not x.
+
+2020-11-27 Philipp Stephani <phst@google.com>
+
+ Fix incorrect handling of module runtime and environment pointers.
+
+ We used to store module runtime and environment pointers in the static
+ lists Vmodule_runtimes and Vmodule_environments. However, this is
+ incorrect because these objects have to be kept per-thread. With this
+ naive approach, interleaving module function calls in separate threads
+ leads to environments being removed in the wrong order, which in turn
+ can cause local module values to be incorrectly garbage-collected.
+ The fix isn't completely trivial: specbinding the lists wouldn't work
+ either, because then the garbage collector wouldn't find the
+ environments in other threads than the current ones, again leading to
+ objects being garbage-collected incorrectly. While introducing custom
+ pseudovector types would fix this, it's simpler to put the runtime and
+ environment pointers into the specbinding list as new specbinding
+ kinds. This works since we need to unwind them anyway, and we only
+ ever treat the lists as a stack. The thread switching machinery
+ ensures that the specbinding lists are thread-local, and that all
+ elements of the specbinding lists in all threads are marked during
+ garbage collection.
+
+ Module assertions now have to walk the specbinding list for the
+ current thread, which is more correct since they now only find
+ environments for the current thread. As a result, we can now remove
+ the faulty Vmodule_runtimes and Vmodule_environments variables
+ entirely.
+
+ Also add a unit test that exemplifies the problem. It interleaves two
+ module calls in two threads so that the first call ends while the
+ second one is still active. Without this change, this test triggers
+ an assertion failure.
+
+ * src/lisp.h (enum specbind_tag): Add new tags for module runtimes and
+ environments.
+
+ * src/eval.c (record_unwind_protect_module): New function to record a
+ module object in the specpdl list.
+ (do_one_unbind): Unwind module objects.
+ (backtrace_eval_unrewind, default_toplevel_binding, lexbound_p)
+ (Fbacktrace__locals): Deal with new specbinding types.
+ (mark_specpdl): Mark module environments as needed.
+
+ * src/alloc.c (garbage_collect): Remove call to 'mark-modules'.
+ Garbage collection of module values is now handled as part of marking
+ the specpdl of each thread.
+
+ * src/emacs-module.c (Fmodule_load, funcall_module): Use specpdl to
+ record module runtimes and environments.
+ (module_assert_runtime, module_assert_env, value_to_lisp): Walk
+ through specpdl list instead of list variables.
+ (mark_module_environment): Rename from 'mark_modules'. Don't attempt
+ to walk though current thread's environments only, since that would
+ miss other threads.
+ (initialize_environment, finalize_environment): Don't change
+ Vmodule_environments variable; environments are now in the specpdl
+ list.
+ (finalize_environment_unwind, finalize_runtime_unwind): Make 'extern'
+ since do_one_unbind now calls them.
+ (finalize_runtime_unwind): Don't change Vmodule_runtimes variable;
+ runtimes are now in the specpdl list.
+ (syms_of_module): Remove Vmodule_runtimes and Vmodule_environments.
+
+ * test/data/emacs-module/mod-test.c (Fmod_test_funcall): New test
+ function.
+ (emacs_module_init): Bind it.
+
+ * test/src/emacs-module-tests.el (emacs-module-tests--variable): New
+ helper type to guard access to state in a thread-safe way.
+ (emacs-module-tests--wait-for-variable)
+ (emacs-module-tests--change-variable): New helper functions.
+ (emacs-module-tests/interleaved-threads): New unit test.
+
+2020-11-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/subr.el (activate-change-group): Refine fix for bug#33341
+
+2020-11-27 Mattias Engdegård <mattiase@acm.org>
+
+ Make the 'cucumber' compilation pattern work without 'omake'
+
+ When 'omake' is included in compilation-error-regexp-alist, which it
+ still is by default, then all other rules are modified to match with
+ an extra leading 6 spaces as well. The 'cucumber' pattern relied on
+ this in order to work as intended.
+
+ * lisp/progmodes/compile.el (compilation-error-regexp-alist-alist):
+ Extend the 'cucumber' pattern so that it works even when 'omake'
+ is not included. Move it below the 'gnu' rule so that it doesn't
+ match anything else.
+
+2020-11-27 Mattias Engdegård <mattiase@acm.org>
+
+ Update TUTORIAL.de and TUTORIAL.fr
+
+ * etc/tutorials/TUTORIAL.de:
+ * etc/tutorials/TUTORIAL.fr: Follow recent changes in TUTORIAL.
+
+2020-11-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/subr.el (activate-change-group): Fix bug#33341
+
+2020-11-27 Stefan Kangas <stefankangas@gmail.com>
+
+ Update TUTORIAL.es
+
+ * etc/tutorials/TUTORIAL.es: A followup to recent changes in
+ TUTORIAL.
+
+2020-11-27 Stefan Kangas <stefankangas@gmail.com>
+
+ Update TUTORIAL.sv
+
+ * etc/tutorials/TUTORIAL.sv: A followup to recent changes in
+ TUTORIAL. Minor tweaks for grammar and style.
+
+2020-11-27 Juri Linkov <juri@linkov.net>
+
+ Add completion-tab-width to align prefix chars with names in read-char-by-name
+
+ * lisp/international/mule-cmds.el (mule--ucs-names-affixation):
+ Replace mule--ucs-names-annotation to display chars in prefixes
+ that implements two FIXME items.
+ (read-char-by-name): Let-bind completion-tab-width to 4.
+ Use affixation-function instead of annotation-function.
+
+ * lisp/minibuffer.el (completion-tab-width): New variable.
+ (completion--insert-strings): Align colwidth to tab positions
+ when completion-tab-width is non-nil.
+
+ * lisp/simple.el (completion-setup-function): Set tab-width to
+ completion-tab-width when completion-tab-width is non-nil.
+
+ https://lists.gnu.org/archive/html/emacs-devel/2020-11/msg01263.html
+
+2020-11-27 Juri Linkov <juri@linkov.net>
+
+ * lisp/simple.el (read-from-kill-ring): Use frame-text-cols, not frame-width.
+
+2020-11-27 Eli Zaretskii <eliz@gnu.org>
+
+ Update TUTORIAL.he
+
+ * etc/tutorials/TUTORIAL.he: A followup to recent changes in
+ TUTORIAL.
+
+2020-11-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up previous server exit directory deletion
+
+ * lisp/server.el (server-start): Only delete the server directory
+ if it's in /tmp (bug#44644).
+
+2020-11-26 Andrea Corallo <akrl@sdf.org>
+
+ Move some tests from comp-tests.el to comp-cstr-tests.el
+
+ * test/lisp/emacs-lisp/comp-cstr-tests.el
+ (comp-cstr-typespec-tests-alist): Add tests covering what was in:
+ `range-simple-union', `union-types', `destructure-type-spec'.
+ * test/src/comp-tests.el (range-simple-intersection, union-types)
+ (destructure-type-spec): Remove tests.
+
+2020-11-26 Andrea Corallo <akrl@sdf.org>
+
+ Add comp-cstr.el and comp-cstr-tests.el
+
+ As the constraint logic of the compiler is not trivial and largely
+ independent from the rest of the code move it into comp-cstr.el to
+ ease separation and maintainability.
+
+ This commit improve the conversion type
+ specifier -> constraint for generality.
+
+ Lastly this should help with bootstrap time as comp.el compilation
+ unit is slimmed down.
+
+ * lisp/emacs-lisp/comp-cstr.el: New file.
+ (comp--typeof-types, comp--all-builtin-types): Move from comp.el.
+ (comp-cstr, comp-cstr-f): Same + rename.
+ (comp-cstr-ctxt): New struct.
+ (comp-supertypes, comp-common-supertype-2)
+ (comp-common-supertype, comp-subtype-p, comp-union-typesets)
+ (comp-range-1+, comp-range-1-, comp-range-<, comp-range-union)
+ (comp-range-intersection): Move from comp.el.
+ (comp-cstr-union-no-range, comp-cstr-union): Move from comp.el and
+ rename.
+ (comp-cstr-union-make): New function.
+ (comp-type-spec-to-cstr, comp-cstr-to-type-spec): Move from
+ comp.el, rename it and rework it.
+
+ * lisp/emacs-lisp/comp.el (comp-known-func-cstr-h): Rework.
+ (comp-ctxt): Remove two fields and include `comp-cstr-ctxt'.
+ (comp-mvar, comp-fwprop-call): Update for `comp-cstr' being
+ renamed.
+ (comp-fwprop-insn): Use `comp-cstr-union-no-range' or
+ `comp-cstr-union'.
+ (comp-ret-type-spec): Use `comp-cstr-union' and rework.
+
+ * test/lisp/emacs-lisp/comp-cstr-tests.el: New file.
+ (comp-cstr-test-ts, comp-cstr-typespec-test): New functions.
+ (comp-cstr-typespec-tests-alist): New defconst to generate tests
+ on.
+ (comp-cstr-generate-tests): New macro.
+
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Update.
+ (ret-type-spec): Initialize constraint context.
+
+2020-11-26 Dario Gjorgjevski <dario.gjorgjevski@gmail.com>
+
+ Fix modification check when custom-form is `lisp'
+
+ * lisp/cus-edit.el (custom-variable-modified-p): Quote the value when
+ custom form is 'lisp (or 'mismatch) prior to comparing in order to
+ accommodate `custom-variable-value-create' (bug#44852).
+
+2020-11-26 Mattias Engdegård <mattiase@acm.org>
+
+ Remove keyboard anachronisms from tutorial
+
+ * etc/tutorials/TUTORIAL: Don't keep referring to EDIT as if it were a
+ common name for the Meta key; since a few decades back it's labelled
+ Alt (or Option or ⌥ but those keys usually also have 'alt' engraved on
+ them). Similarly, CTL is practically extinct and not worth
+ mentioning.
+
+2020-11-26 Mattias Engdegård <mattiase@acm.org>
+
+ Fix replace-regexp-in-string substring match data translation
+
+ For certain patterns, re-matching the same regexp on the matched
+ substring does not produce correctly translated match data
+ (bug#15107 and bug#44861).
+
+ Using a new builtin function also improves performance since the
+ number of calls to string-match is halved.
+
+ Reported by Kevin Ryde and Shigeru Fukaya.
+
+ * lisp/subr.el (replace-regexp-in-string): Translate the match data
+ using match-data--translate instead of trusting a call to string-match
+ on the matched string to do the job.
+ * test/lisp/subr-tests.el (subr-replace-regexp-in-string):
+ Add test cases.
+ * src/search.c (Fmatch_data__translate): New internal function.
+ (syms_of_search): Register it as a subroutine.
+
+2020-11-26 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Fix error in cache handling. This fixes bug #43481
+
+ * lisp/progmodes/cc-engine.el (c-full-pp-to-literal): Handle correctly END
+ being before HERE by using parse-partial-sexp to get the end of the literal
+ containing HERE.
+
+2020-11-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Keep point in the *eldoc* buffer in eldoc-display-in-echo-area
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-display-in-echo-area): Use
+ 'save-excursion' to keep point position in *eldoc* buffer.
+ Suggested by Andrii Kolomoiets <andreyk.mad@gmail.com>.
+
+2020-11-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow following symlinks when recompiling directories
+
+ * doc/lispref/compile.texi (Compilation Functions): Document it.
+ * lisp/emacs-lisp/bytecomp.el (byte-recompile-directory): Allow
+ following symlinks (bug#10292).
+
+2020-11-26 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/files.el (auto-mode-alist): Add entry for "archive-contents".
+
+2020-11-26 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Add "replied" -> "answered" for gnus-search imap searches
+
+ * lisp/gnus/gnus-search.el (gnus-search-imap-handle-flag): This allows
+ "mark:A" to be translated into "ANSWERED" and "-mark:A" to be
+ translated into "UNANSWERED".
+
+2020-11-26 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Assume default imap TEXT search even when not using parsed queries
+
+ This behavior both better matches the previous nnir behavior, reducing
+ confusion for new users, and matches behavior when using parsed
+ queries.
+
+ * lisp/gnus/gnus-search.el (gnus-search-imap-search-keys): Make sure
+ this variable contains all known IMAP search keys.
+ (gnus-search-run-search): If the search query doesn't start with a
+ known search key, prepend "TEXT " to the query.
+
+2020-11-25 Michael Albinus <michael.albinus@gmx.de>
+
+ Use null-device where appropriate
+
+ * lisp/filesets.el (filesets-select-command):
+ * lisp/shell.el (shell-mode):
+ * lisp/term.el (term-exec-1):
+ * lisp/wdired.el (wdired-do-symlink-changes):
+ * lisp/cedet/ede/pmake.el (ede-proj-makefile-create):
+ * lisp/eshell/esh-io.el (eshell-set-output-handle):
+ * lisp/gnus/gnus-fun.el (gnus-grab-cam-x-face):
+ * lisp/gnus/mml2015.el (mml2015-epg-key-image):
+ * lisp/gnus/smime.el (smime-noverify-region):
+ * lisp/org/ob-picolisp.el (org-babel-execute:picolisp):
+ * lisp/org/ob-screen.el (org-babel-prep-session:screen)
+ (org-babel-prep-session:screen):
+ * lisp/play/fortune.el (fortune-quiet-strfile-options):
+ * lisp/progmodes/cperl-mode.el (cperl-pod2man-build-command):
+ * lisp/progmodes/sh-script.el (sh-tmp-file):
+ * lisp/vc/diff-mode.el (diff-add-log-current-defuns)
+ (diff--font-lock-prettify):
+ * lisp/vc/ediff-mult.el (ediff-patch-file-form-meta):
+ * lisp/vc/ediff-ptch.el (ediff-map-patch-buffer)
+ (ediff-fixup-patch-map, ediff-dispatch-file-patching-job):
+ * lisp/vc/vc.el (vc-diff-internal): Use null-device or (null-device),
+ respectively. (Bug#3736)
+
+2020-11-25 Juri Linkov <juri@linkov.net>
+
+ * lisp/minibuffer.el (completions-format): Add new value 'one-column'.
+
+ * lisp/minibuffer.el (completion--insert-strings): Support 'one-column'.
+
+ * lisp/simple.el (read-from-kill-ring): Truncate strings at frame-width.
+
+2020-11-25 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ (defvar): Detect defining a variable currently lexically bound
+
+ * src/eval.c (lexbound_p): New function.
+ (Finternal__define_uninitialized_variable): Use it.
+
+2020-11-25 Mattias Engdegård <mattiase@acm.org>
+
+ Add tests for replace-regexp-in-string
+
+ * test/lisp/subr-tests.el (subr-replace-regexp-in-string): New.
+
+2020-11-25 Mattias Engdegård <mattiase@acm.org>
+
+ * doc/lispref/searching.texi (Rx Constructs): Group numbering fix
+
+2020-11-25 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/lisp/net/tramp-tests.el (tramp-test29-start-file-process):
+
+ Use `tramp--test-windows-nt-p'.
+
+2020-11-25 Michael Albinus <michael.albinus@gmx.de>
+
+ Merge from origin/emacs-27
+
+ 6442cdc0e4 Revert extra focus redirection in do_switch_frame (Bug#24803)
+ fc4379f1ae Minor cleanup of tramp-tests.el on MS Windows
+ dea3d6aa18 Fix handling of defcustom :local tag
+
+2020-11-25 Michael Albinus <michael.albinus@gmx.de>
+
+ Merge from origin/emacs-27
+
+ f425a774c2 Fix display artifacts when 'display' properties cover newl...
+
+2020-11-25 Martin Rudalics <rudalics@gmx.at>
+
+ Revert extra focus redirection in do_switch_frame (Bug#24803)
+
+ * src/frame.c (do_switch_frame): Do not also redirect frame
+ focus when FRAME has its minibuffer window on the selected
+ frame which was intended to fix Bug#24500. It may cause
+ Bug#24803 and lead to a nasty state where no active cursor is
+ shown on any frame, see
+ https://lists.gnu.org/archive/html/emacs-devel/2020-11/msg01137.html.
+
+2020-11-25 Juri Linkov <juri@linkov.net>
+
+ Add 'completions-detailed' to add prefix/suffix with 'affixation-function'
+
+ * doc/lispref/minibuf.texi (Completion Variables)
+ (Programmed Completion): Add affixation-function.
+
+ * lisp/help-fns.el (help--symbol-completion-table-affixation): New function.
+ (help--symbol-completion-table): Set affixation-function when
+ completions-detailed is non-nil.
+
+ * lisp/minibuffer.el (completion-metadata): Add affixation-function
+ to docstring.
+ (completions-annotations): Inherit from shadow with italic.
+ (completions-detailed): New defcustom.
+ (completion--insert-strings): Count string-width on all strings in
+ completion list. Insert prefix and suffix.
+ (completion-extra-properties): Add affixation-function to docstring.
+ (minibuffer-completion-help): Call affixation-function.
+ (minibuffer-default-prompt-format): Move down closer to its use.
+
+ https://lists.gnu.org/archive/html/emacs-devel/2020-11/msg00613.html
+
+2020-11-25 Michael Albinus <michael.albinus@gmx.de>
+
+ Minor cleanup of tramp-tests.el on MS Windows
+
+ * test/lisp/net/tramp-tests.el (tramp-test29-start-file-process):
+ Do not test remote pty on MS Windows.
+
+2020-11-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move code in face-remap.el to avoid a compilation warning
+
+ * lisp/face-remap.el (text-scale--refresh): Move code to avoid
+ compilation warning.
+
+ In text-scale--refresh:
+ face-remap.el:241:14: Warning: reference to free variable ‘text-scale-mode’
+
+2020-11-25 Stefan Kangas <stefan@marxist.se>
+
+ Make text-scale-mode optionally adjust the header line
+
+ * lisp/face-remap.el
+ (text-scale-remap-header-line-face): New buffer local variable.
+ (text-scale-mode): Adjust header line if above variable is non-nil.
+ (face-remap--clear-remappings, face-remap--remap-face): New defuns.
+ * lisp/face-remap.el: Arrange to watch text-scale-mode-remapping.
+ (text-scale--refresh): New function.
+
+ * lisp/emacs-lisp/tabulated-list.el (tabulated-list-mode): Use
+ text-scale-remap-header-line. (Bug#41852)
+
+2020-11-24 Juri Linkov <juri@linkov.net>
+
+ Yank items selected from kill-ring using completion and minibuffer history
+
+ * doc/emacs/killing.texi (Earlier Kills): Document standalone M-y.
+
+ * doc/emacs/search.texi (Isearch Yank): Explain standalone M-y.
+
+ * doc/lispref/text.texi (Yank Commands): Soften the wording of
+ yank after another yank.
+
+ * lisp/delsel.el: Put 'yank' property on yank-pop and yank-from-kill-ring.
+
+ * lisp/isearch.el (isearch-yank-pop): Use with-isearch-suspended
+ and read-from-kill-ring to read a string from the kill-ring and
+ append it to the search string.
+
+ * lisp/simple.el (yank-pop): Call yank-from-kill-ring and
+ read-from-kill-ring when last-command is not 'yank' instead of
+ signaling an error. Remove "*" from interactive spec. Update docstring.
+ (read-from-kill-ring): New function.
+ (yank-from-kill-ring): New command.
+
+ https://lists.gnu.org/archive/html/emacs-devel/2020-11/msg00801.html
+
+2020-11-24 Stefan Kangas <stefan@marxist.se>
+
+ * build-aux/update-subdirs: Use lexical-binding in subdirs.el.
+
+2020-11-24 Philipp Stephani <phst@google.com>
+
+ Add a (broken) unit test to exemplify Bug#11218.
+
+ * test/lisp/emacs-lisp/ert-tests.el
+ (ert-test-with-demoted-errors): New (broken) unit test.
+
+2020-11-24 Stefan Kangas <stefan@marxist.se>
+
+ Remove XEmacs compat code from idlw-help.el
+
+ * lisp/progmodes/idlw-help.el (idlwave-do-context-help)
+ (idlwave-help-show-help-frame): Remove XEmacs compat code.
+
+2020-11-24 Stefan Kangas <stefan@marxist.se>
+
+ Make XEmacs compat aliases easy-menu-{add,remove} obsolete
+
+ * lisp/emacs-lisp/easymenu.el (easy-menu-remove, easy-menu-add):
+ Make XEmacs compat aliases obsolete.
+ * lisp/allout.el (allout-setup-menubar):
+ * lisp/cus-edit.el (Custom-mode):
+ * lisp/gnus/gnus-art.el (gnus-article-edit-mode):
+ * lisp/gnus/message.el (message-mode):
+ * lisp/net/sieve.el (sieve-manage-mode):
+ * lisp/org/org-agenda.el (org-agenda-mode):
+ * lisp/org/org-table.el (org-table-edit-formulas, orgtbl-mode):
+ * lisp/org/org.el:
+ * lisp/progmodes/cperl-mode.el (cperl-mode):
+ * lisp/progmodes/hideshow.el (hs-minor-mode):
+ * lisp/progmodes/idlw-help.el (idlwave-help-mode):
+ * lisp/progmodes/idlw-shell.el (idlwave-shell-mode):
+ * lisp/progmodes/idlwave.el (idlwave-mode):
+ * lisp/progmodes/meta-mode.el (meta-common-mode):
+ * lisp/progmodes/octave.el (octave-mode):
+ * lisp/progmodes/prolog.el (prolog-menu):
+ * lisp/progmodes/tcl.el (tcl-mode):
+ * lisp/speedbar.el (speedbar-reconfigure-keymaps):
+ * lisp/term.el (term-mode, term-char-mode, term-process-pager):
+ * lisp/textmodes/dns-mode.el (dns-mode):
+ * lisp/wid-browse.el (widget-browse-mode): Don't call above
+ obsolete aliases.
+ * lisp/cedet/semantic/grammar.el (semantic-grammar-setup-menu-xemacs):
+ * lisp/mh-e/mh-folder.el (mh-folder-mode):
+ * lisp/mh-e/mh-identity.el (mh-identity-add-menu):
+ * lisp/mh-e/mh-letter.el (mh-letter-mode):
+ * lisp/mh-e/mh-search.el (mh-search-mode):
+ * lisp/mh-e/mh-show.el (mh-show-mode):
+ * lisp/obsolete/otodo-mode.el (todo-mode):
+ * lisp/progmodes/antlr-mode.el (antlr-mode):
+ * lisp/progmodes/cc-mode.el (c-mode, c++-mode, objc-mode)
+ (java-mode, idl-mode, pike-mode):
+ * lisp/progmodes/sql.el (sql-mode, sql-interactive-mode):
+ * lisp/progmodes/vhdl-mode.el (vhdl-update-mode-menu)
+ (vhdl-add-source-files-menu, vhdl-mode):
+ * lisp/textmodes/reftex-index.el (reftex-index-mode)
+ (reftex-index-phrases-mode):
+ * lisp/textmodes/reftex-toc.el (reftex-toc-mode):
+ * lisp/textmodes/reftex.el (reftex-mode): Only call above obsolete
+ aliases in XEmacs.
+
+ * lisp/progmodes/prolog.el (prolog-inferior-menu):
+ * lisp/erc/erc-menu.el (erc-menu-add, erc-menu-remove): Don't call
+ above obsolete aliases. Make obsolete.
+ * lisp/erc/erc-menu.el (menu, erc-menu-add, erc-menu-remove):
+ * lisp/progmodes/prolog.el (prolog-inferior-mode): Adjust callers.
+ * lisp/speedbar.el (speedbar-previous-menu): Make obsolete.
+ (Bug#44731)
+
+2020-11-24 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix handling of defcustom :local tag
+
+ For discussion, see the following emacs-devel thread:
+ https://lists.gnu.org/r/emacs-devel/2020-11/msg00734.html
+
+ * lisp/custom.el (custom-declare-variable): Delay call to
+ make-variable-buffer-local until after user option has been
+ initialized with a value. Otherwise the user option may be
+ initialized to nil.
+ * test/lisp/custom-tests.el (custom--test-local-option)
+ (custom--test-permanent-option): New :local user options.
+ (custom-test-local-option): New test for defcustom :local keyword.
+
+2020-11-24 Eli Zaretskii <eliz@gnu.org>
+
+ Fix display artifacts when 'display' properties cover newlines
+
+ * src/xdisp.c (pos_visible_p): Set glyph_row of scratch iterators
+ to NULL, to avoid producing glyphs while we figure out the layout.
+ (Bug#44826)
+
+2020-11-24 Mauro Aranda <maurooaranda@gmail.com>
+
+ Fix menu binding for files in fileset
+
+ * lisp/filesets.el (filesets-remake-shortcut): We want the callback of
+ the menu item, not a list that contains the callback. (Bug#44764)
+
+2020-11-24 Mauro Aranda <maurooaranda@gmail.com>
+
+ Fix matching of inline choices for the choice widget
+
+ A choice widget should be able to match either no inline values or
+ inline values, upon request. (Bug#44579)
+
+ * lisp/wid-edit.el (choice): New property, :inline-bubbles-p. A
+ predicate that returns non-nil if the choice widget can act as an
+ inline widget. Document it.
+ (widget-choice-inline-bubbles-p): New function, for the
+ :inline-bubbles-p property of the choice widget.
+ (widget-inline-p): New function. Use the :inline-bubbles-p property
+ of the widget, if any.
+ (widget-match-inline): Use the above to see if the widget can act like
+ an inline widget. Document it.
+ (widget-choice-value-create): Account for the case of a choice widget
+ that has inline members.
+ (widget-checklist-add-item, widget-editable-list-value-create)
+ (widget-group-value-create): Use widget-inline-p rather than just
+ checking for a non-nil :inline property, allowing these functions to
+ pass the complete information to widgets like the choice widget to
+ create their values.
+
+ * test/lisp/wid-edit-tests.el (widget-test-choice-match-no-inline)
+ (widget-test-choice-match-all-inline)
+ widget-test-choice-match-some-inline): New tests, to check that choice
+ widgets can match its choices, inline or not.
+ (widget-test-inline-p): New test, for the new function
+ widget-inline-p.
+ (widget-test-repeat-can-handle-choice)
+ (widget-test-repeat-can-handle-inlinable-choice)
+ (widget-test-list-can-handle-choice)
+ (widget-test-list-can-handle-inlinable-choice)
+ (widget-test-option-can-handle-choice)
+ (widget-test-option-can-handle-inlinable-choice): New tests. This
+ grouping widgets need to be able to create a choice widget regardless
+ if it has inline choices or not.
+
+2020-11-24 Drew Adams <drew.adams@oracle.com>
+
+ Fix finding filelist for :tree fileset (Bug#976)
+
+ * lisp/filesets.el (filesets-files-under): New function, used to get
+ all files for a :tree fileset.
+ (filesets-get-filelist): Use it. Look for the directory and the
+ pattern in the right place inside entry.
+
+2020-11-24 Mattias Engdegård <mattiase@acm.org>
+
+ Autoload the 'rx' pcase macroexpander (bug#44807)
+
+ * lisp/emacs-lisp/rx.el (rx--pcase-macroexpander]): Autoload.
+
+2020-11-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow controlling whether SPC in Gnus goes to the next article
+
+ * doc/misc/gnus.texi (Summary Maneuvering): Document it.
+ * lisp/gnus/gnus-sum.el (gnus-paging-select-next): New variable.
+ (gnus-summary-prev-page, gnus-summary-next-page): Use it.
+
+2020-11-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the `C' command work on marked files
+
+ * lisp/arc-mode.el (archive-copy-file): Make the `C' command work
+ on marked files (bug#44753).
+
+2020-11-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a user option to control how links are followed in eww
+
+ * doc/misc/eww.texi (Advanced): Document it (bug#44783).
+
+ * lisp/net/eww.el (eww-use-browse-url): New variable.
+ (eww-follow-link): Use it.
+
+2020-11-24 Itai Seggev <is+apple@cs.hmc.edu> (tiny change)
+
+ Codesign the executable on recene MacOS systems
+
+ * src/Makefile.in (temacs$(EXEEXT)): Codesign the executable on
+ recent (ARM) MacOS systems (bug#43878). Without this, building
+ Emacs fails.
+
+2020-11-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Delete the emacs-server directory upon Emacs exit
+
+ * lisp/server.el (server-start): Delete the server directory upon
+ Emacs exit (bug#44644). This fixes the problem of /tmp/emacs0
+ directories being left behind when running an Emacs server as root.
+
+2020-11-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak the face of unknown backend indicators in flymake
+
+ * lisp/progmodes/flymake.el (flymake--mode-line-format): Don't put
+ a face on the the "?" unknown backend indicator, because that
+ looks odd in inactive windows (bug#44689).
+
+2020-11-24 Paul W. Rankin <pwr@skeletons.cc>
+
+ Handle outline overlays better when cycling in outline.el
+
+ * lisp/outline.el (outline--cycle-state): Only consider outline
+ overlays that are on outline headings; when subtree end is
+ point-max, return overlay-end +1 because final subtree overlay
+ only reaches point-max -1 (bug#41198).
+ (outline-cycle-buffer): Check that buffer has top-level headings
+ before calling outline-hide-sublevels 1 thus preventing
+ disconcerting buffer state of content reduced to single "..."
+
+2020-11-23 Andrea Corallo <akrl@sdf.org>
+
+ Add SELECTOR parameter to `native-compile-async' (bug#44813)
+
+ * lisp/emacs-lisp/comp.el (native-compile-async-skip-p): New function
+ ripping out logic from `native--compile-async' and accounting for
+ SELECTOR.
+ (native--compile-async): Add SELECTOR parameter, make use of
+ `native-compile-async-skip-p' and move it with other private
+ functions.
+ (native-compile-async): Add SELECTOR parameter.
+
+2020-11-23 Andrea Corallo <akrl@sdf.org>
+
+ Rename two native compiler customize
+
+ * lisp/emacs-lisp/comp.el (comp-deferred-compilation-deny-list):
+ Rename from `comp-deferred-compilation-black-list'.
+ * lisp/emacs-lisp/comp.el (native--compile-async): Update to use
+ `comp-deferred-compilation-deny-list'.
+ (comp-bootstrap-deny-list): Rename.
+ (batch-native-compile): Update to use `comp-bootstrap-deny-list'.
+
+2020-11-23 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt files-x-tests.el according to recent Tramp changes
+
+ * test/lisp/files-x-tests.el (tramp-connection-local-default-profile):
+ Don't declare.
+ (tramp-connection-local-default-shell-variables)
+ (tramp-connection-local-default-system-variables): Declare.
+ (files-x-test-with-connection-local-variables): Use them.
+
+2020-11-23 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 3ceee39819 Fix Bug#44481
+
+2020-11-23 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 86cbc9d216 Make ignoring modifiers on IME input optional
+ 32b97bb9e0 Ignore modifiers when processing WM_IME_CHAR messages
+ f641ef1a07 Improve documentation of 'font-spec'
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-11-23 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ e66502fec1 ; * doc/misc/eshell.texi (Input/Output): Fix typo.
+
+2020-11-23 Alan Mackenzie <acm@muc.de>
+
+ minibuffer code: restore original frame after using minibuffer-only frame, etc
+
+ * src/minibuf.c (read_minibuf): In the record_unwind_protect for the second
+ restore_window_configuration (separate minibuffer frame case) arrange for the
+ future switching back to the original frame by Fset_window_configuration.
+
+2020-11-23 Mattias Engdegård <mattiase@acm.org>
+
+ Fix 'See @xref{...}' (bug#44811)
+
+ Reported by 황병희.
+
+ * doc/lispref/edebug.texi (Printing in Edebug):
+ * doc/misc/ebrowse.texi (Marking Classes):
+ * doc/misc/gnus.texi (Ma Gnus):
+ * doc/misc/tramp.texi (Remote shell setup):
+ Don't stutter (@xref expands to 'See ...').
+
+2020-11-23 Stefan Kangas <stefan@marxist.se>
+
+ Remove Emacs 19 and 20 compat code from table.el
+
+ * lisp/textmodes/table.el:
+ (table-recognize-cell, table--make-cell-map)
+ (*table--present-cell-popup-menu, table--update-cell)
+ (table--update-cell-widened, table--update-cell-heightened)
+ (table--cell-insert-char, table--warn-incompatibility): Remove
+ Emacs 19 and 20 compat code.
+ * lisp/textmodes/table.el (table-disable-menu)
+ (table--set-timer, table--get-last-command): Declare obsolete.
+
+2020-11-23 Stefan Kangas <stefankangas@gmail.com>
+
+ Sync latest SKK-JISYO.L
+
+ * leim/SKK-DIC/SKK-JISYO.L: Sync to current upstream version.
+
+ (cherry picked from commit 6a5f9700846551a7f3795e257356dbab865116f4)
+
+2020-11-23 Stefan Kangas <stefan@marxist.se>
+
+ Update publicsuffix.txt from upstream
+
+ * etc/publicsuffix.txt: Update from
+ https://publicsuffix.org/list/public_suffix_list.dat
+ dated 2020-10-09 08:23:34 UTC.
+
+ (cherry picked from commit 5b13afab0a903ead8363482529019d4fb80ec4b4)
+
+2020-11-23 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in most runtime leim lisp files
+
+ * lisp/leim/quail/arabic.el:
+ * lisp/leim/quail/croatian.el:
+ * lisp/leim/quail/cyril-jis.el:
+ * lisp/leim/quail/cyrillic.el:
+ * lisp/leim/quail/czech.el:
+ * lisp/leim/quail/ethiopic.el:
+ * lisp/leim/quail/georgian.el:
+ * lisp/leim/quail/greek.el:
+ * lisp/leim/quail/hanja-jis.el:
+ * lisp/leim/quail/hanja.el:
+ * lisp/leim/quail/hanja3.el:
+ * lisp/leim/quail/hebrew.el:
+ * lisp/leim/quail/ipa-praat.el:
+ * lisp/leim/quail/latin-alt.el:
+ * lisp/leim/quail/latin-post.el:
+ * lisp/leim/quail/latin-pre.el:
+ * lisp/leim/quail/persian.el:
+ * lisp/leim/quail/programmer-dvorak.el:
+ * lisp/leim/quail/py-punct.el:
+ * lisp/leim/quail/pypunct-b5.el:
+ * lisp/leim/quail/rfc1345.el:
+ * lisp/leim/quail/sami.el:
+ * lisp/leim/quail/sgml-input.el:
+ * lisp/leim/quail/slovak.el:
+ * lisp/leim/quail/symbol-ksc.el:
+ * lisp/leim/quail/tamil-dvorak.el:
+ * lisp/leim/quail/vntelex.el:
+ * lisp/leim/quail/vnvni.el:
+ * lisp/leim/quail/welsh.el: Use lexical-binding.
+
+2020-11-23 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Small fixes to gnus-search output parsing of indexed engines
+
+ * lisp/gnus/gnus-search.el (gnus-search-indexed-parse-output): When
+ filtering for desired groups, accept any of [.\/] as potential segment
+ delimiters. Later on, filesystem path separators will be interpreted
+ as dots (".") when constructing group names. Also, make sure we use
+ `expand-file-name' on the prefix, and just use `string-remove-prefix'
+ to get rid of it.
+
+2020-11-22 Philipp Stephani <phst@google.com>
+
+ Unbreak compilation with CHECK_STRUCTS.
+
+ Commit 3963aea4f4a22da0c1fb8ca8ca80b59c58373811 modified the ‘buffer’
+ structure, but didn’t adapt the hash.
+
+ * src/pdumper.c (dump_buffer): Update buffer hash.
+
+2020-11-22 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-11-22 Michael Albinus <michael.albinus@gmx.de>
+
+ Replace /dev/null by remote null-device in Tramp.
+
+ * lisp/net/tramp-adb.el (tramp-adb-get-ls-command)
+ (tramp-adb-handle-set-file-times, tramp-adb-handle-process-file):
+ Use `tramp-get-remote-null-device'.
+
+ * lisp/net/tramp-compat.el (tramp-tramp-file-p): Declare.
+ (tramp-compat-null-device): New defalias.
+
+ * lisp/net/tramp-sh.el (tramp-methods) <telnet, nc>:
+ (tramp-perl-encode-with-module, tramp-perl-decode-with-module)
+ (tramp-perl-encode, tramp-perl-decode, tramp-awk-decode):
+ Use "%n" marker.
+ (tramp-do-directory-files-and-attributes-with-stat)
+ (tramp-sh-handle-file-name-all-completions)
+ (tramp-do-copy-or-rename-file-out-of-band)
+ (tramp-sh-handle-insert-directory, tramp-sh-handle-process-file)
+ (tramp-set-remote-path, tramp-open-connection-setup-interactive-shell)
+ (tramp-find-inline-encoding, tramp-send-command-and-check)
+ (tramp-get-remote-path, tramp-get-ls-command, tramp-get-ls-command-with)
+ (tramp-get-remote-awk, tramp-get-remote-hexdump, tramp-get-remote-od)
+ (tramp-get-env-with-u-option): Use `tramp-get-remote-null-device'.
+ (tramp-remote-coding-commands, tramp-call-local-coding-command):
+ Adapt docstring.
+
+ * lisp/net/tramp-smb.el (tramp-smb-conf): Use `null-device'.
+ (tramp-smb-handle-file-acl): Use `tramp-get-remote-null-device'.
+
+ * lisp/net/tramp.el (tramp-methods): Adapt docstring.
+ (tramp-get-remote-null-device): New defun.
+ (tramp-interrupt-process): Use it.
+
+2020-11-22 Stefan Kangas <stefan@marxist.se>
+
+ Test for byte-compiler warning "variable lacks prefix"
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (bytecomp--with-warning-test): New macro.
+ (bytecomp-warn-wrong-args, bytecomp-warn-wrong-args-subr):
+ Use above new macro.
+ (bytecomp-warn-variable-lacks-prefix): New test.
+
+2020-11-22 Stefan Kangas <stefan@marxist.se>
+
+ Test interactive-only spec of with-suppressed-warnings
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (bytecomp-test--with-suppressed-warnings): Test suppressing warning
+ with interactive-only.
+
+2020-11-22 Stefan Kangas <stefan@marxist.se>
+
+ Say which command shadows a key binding
+
+ * src/keymap.c (describe_vector): Say which command shadows this
+ binding. (Bug#9293)
+ * test/src/keymap-tests.el
+ (help--describe-vector/bug-9293-one-shadowed-in-range): Adapt
+ test.
+
+2020-11-22 Stefan Kangas <stefan@marxist.se>
+
+ Don't shadow bindings by the same command
+
+ * src/keymap.c (describe_vector): Do not say binding is shadowed if
+ the other key binding points to the same command. (Bug#9293)
+ * test/src/keymap-tests.el
+ (help--describe-vector/bug-9293-same-command-does-not-shadow): New
+ test.
+
+2020-11-22 Stefan Kangas <stefan@marxist.se>
+
+ Don't show key ranges if shadowed by different commands
+
+ * src/keymap.c (describe_vector): Make sure found consecutive keys
+ are either not shadowed or, if they are, that they are shadowed by
+ the same command. (Bug#9293)
+ * test/src/keymap-tests.el
+ (help--describe-vector/bug-9293-one-shadowed-in-range): New test.
+
+2020-11-21 Juri Linkov <juri@linkov.net>
+
+ Handle help-form in y-or-n-p and use this in find-file-noselect (bug#5423)
+
+ * doc/lispref/help.texi (Help Functions): Mention help-form for
+ read-char-from-minibuffer and y-or-n-p.
+
+ * doc/lispref/minibuf.texi (Yes-or-No Queries): Mention help-form
+ for y-or-n-p.
+ (Multiple Queries): Mention help-form for read-char-from-minibuffer.
+
+ * lisp/files.el (find-file-noselect): Let-bind multi-line help text
+ to help-form for y-or-n-p.
+
+ * lisp/subr.el (read-char-choice): Mention help-form in docstring.
+ (read-char-from-minibuffer): Mention help-form in docstring.
+ (y-or-n-p-map): Remove handling of 'help'.
+ (y-or-n-p): Mention help-form in docstring.
+ When help-form is non-nil: add help-char to 'prompt', and bind
+ help-char to help-form-show in composed-keymap.
+
+2020-11-21 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Bug#44481
+
+ * lisp/net/tramp.el (tramp-system-name): New defconst.
+ (tramp-default-host, tramp-restricted-shell-hosts-alist)
+ (tramp-local-host-regexp):
+ * lisp/net/tramp-sh.el (tramp-maybe-open-connection): Use it. (Bug#44481)
+
+2020-11-21 Michael Albinus <michael.albinus@gmx.de>
+
+ Handle connection-local null-device and path-separator variables
+
+ * doc/lispref/os.texi (System Environment): Add `path-separator'
+ function and `null-device' variable and function.
+
+ * etc/NEWS: Mention 'null-device' and 'path-separator'. Fix typos.
+
+ * lisp/files-x.el (path-separator, null-device): New defuns. (Bug#3736)
+
+ * lisp/net/tramp-adb.el
+ (tramp-adb-connection-local-default-shell-variables): Rename from
+ `tramp-adb-connection-local-default-profile'.
+
+ * lisp/net/tramp-integration.el
+ (tramp-connection-local-default-system-variables): New defvar.
+ Add it to connection-local profiles.
+ (tramp-connection-local-default-shell-variables): Rename from
+ `tramp-connection-local-default-profile'.
+
+ * lisp/progmodes/grep.el (grep-hello-file): New defun.
+ (grep-compute-defaults): Use `null-device' function for remote
+ case. Handle remote `hello-file'. Use `process-file-shell-command'.
+ (grep,grep-expand-keywords, lgrep): Use `null-device' function for
+ remote case.
+
+2020-11-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Minor Edebug manual keystroke clarifications
+
+ * doc/lispref/edebug.texi (Edebug Misc): Also mention the `a'
+ binding to abort (bug#44697). Also fix `d' function reference, and
+ add `P' reference.
+
+ (cherry picked from commit b613f25f97abf756101eaa2af90689a19c0b3350)
+
+2020-11-21 Jared Finder <jared@finder.org>
+
+ Migrate usage of GPM_CLICK_EVENT to MOUSE_CLICK_EVENT.
+
+ * src/termhooks.h (enum event_kind):
+ * src/term.c (term_mouse_click, handle_one_term_event):
+ * src/keyboard.c (discard_mouse_events, make_lispy_event): Migrate
+ usage of GPM_CLICK_EVENT to MOUSE_CLICK_EVENT.
+
+2020-11-21 Eli Zaretskii <eliz@gnu.org>
+
+ Make ignoring modifiers on IME input optional
+
+ By default, ignore modifier keys on IME input, but add
+ a variable to get back old behavior.
+ * src/w32fns.c (syms_of_w32fns): New variable
+ w32-ignore-modifiers-on-IME-input.
+ (w32_wnd_proc): Use it to ignore modifier keys when IME input is
+ used. (Bug#44641)
+
+ * etc/NEWS: Announce the change and the new variable.
+
+2020-11-21 Masahiro Nakamura <tsuucat@icloud.com>
+
+ Ignore modifiers when processing WM_IME_CHAR messages
+
+ * src/w32fns.c (w32_wnd_proc): Ignore modifiers when processing
+ WM_IME_CHAR messages.
+
+2020-11-21 Stefan Kangas <stefan@marxist.se>
+
+ Make load argument of native-compile-async internal
+
+ * lisp/emacs-lisp/comp.el (native--compile-async): New defun extracted
+ from native-compile-async.
+ (native-compile-async): Remove load argument and use above new defun.
+ * src/comp.c (maybe_defer_native_compilation): Use above new
+ defun. (Bug#44676)
+
+2020-11-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/package.el (package-strip-rcs-id): Don't ignore errors
+
+ Ignoring errors here just postpones the error and replaces a clear
+ "invalid version syntax" with a confusing "package lacks a version".
+
+2020-11-20 Mauro Aranda <maurooaranda@gmail.com>
+
+ Use cl-letf instead of unwind-protect in a test
+
+ * test/lisp/cus-edit-tests.el (cus-edit-tests-customize-saved/show-obsolete):
+ Good use case for cl-letf, so use it.
+ Suggested by Stefan Monnier <monnier@iro.umontreal.ca> in:
+ https://lists.gnu.org/archive/html/emacs-devel/2020-11/msg00914.html
+
+2020-11-20 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * test/manual/indent/tcl.tcl: Add string interpolation case
+
+2020-11-20 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Don't optimize away `eval` when its lexical context is different
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-file-form-eval):
+ Obey lexical-binding.
+
+2020-11-20 Mauro Aranda <maurooaranda@gmail.com>
+
+ Take care of a FIXME in cus-edit-tests.el
+
+ * test/lisp/cus-edit-tests.el (cus-edit-tests-customize-saved/show-obsolete):
+ Add a fake saved-value property, to be able check that the obsolete
+ option is present in the Customize buffer. Expect the test to pass
+ now.
+
+2020-11-20 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/emacs-lisp/comp.el (native-compile-async): Doc fix.
+
+2020-11-20 Stefan Kangas <stefan@marxist.se>
+
+ Support native compilation of packages on install
+
+ * lisp/emacs-lisp/package.el (package-unpack)
+ (package--native-compile): Native compile packages on install, if the
+ feature is available. (Bug#44676)
+ (package-native-compile): New defcustom.
+
+2020-11-20 Stefan Kangas <stefan@marxist.se>
+
+ compile-async: Don't error out on deferred compilation after load
+
+ * lisp/emacs-lisp/comp.el (native-compile-async): Update
+ comp-files-queue when deferred compilation is requested. (Bug#44676)
+
+2020-11-20 Stefan Kangas <stefan@marxist.se>
+
+ Don't quote lambda in idlwave.el
+
+ * lisp/progmodes/idlwave.el (idlwave-keyword-abbrev): Don't quote
+ lambda.
+
+2020-11-20 Stefan Kangas <stefan@marxist.se>
+
+ Remove remaining XEmacs compat code from erc-log.el
+
+ * lisp/erc/erc-log.el (erc-save-buffer-in-logs): Remove XEmacs
+ compat code.
+
+2020-11-20 Stefan Kangas <stefan@marxist.se>
+
+ Don't set XEmacs only properties start-open and end-open
+
+ * lisp/epa.el (epa-sign-region, epa-encrypt-region):
+ * lisp/erc/erc.el (erc-display-prompt):
+ * lisp/gnus/message.el (message-forward-make-body-mime):
+ * lisp/net/eudc-bob.el (eudc-bob-display-jpeg)
+ (eudc-bob-display-audio, eudc-bob-display-generic-binary):
+ * lisp/url/url-http.el
+ (url-http-chunked-encoding-after-change-function): Don't set XEmacs
+ only properties start-open and end-open.
+
+2020-11-20 Stefan Kangas <stefan@marxist.se>
+
+ Remove XEmacs compat code from idlw-shell.el
+
+ * lisp/progmodes/idlw-shell.el:
+ (idlwave-shell-use-toolbar): Doc fix.
+ (idlwave-default-mouse-track-event-is-with-button): Declare obsolete.
+ (idlwave-shell-update-bp-overlays): Remove XEmacs compat code.
+
+2020-11-20 Stefan Kangas <stefan@marxist.se>
+
+ Remove some XEmacs compat code from ediff-wind.el
+
+ * lisp/vc/ediff-wind.el (ediff-window)
+ (ediff-compute-toolbar-width): Remove some XEmacs compat code.
+
+2020-11-20 Stefan Kangas <stefan@marxist.se>
+
+ Remove Emacs 20 compat code from org.el
+
+ * lisp/org/org.el (org-org-menu, org-create-customize-menu):
+ Remove Emacs 20 compat code.
+
+2020-11-20 Stefan Kangas <stefan@marxist.se>
+
+ Remove Emacs 20 compat code from idlwave.el
+
+ * lisp/progmodes/idlwave.el (idlwave-indent-line)
+ (idlwave-toggle-comment-region, idlwave-reset-sintern)
+ (idlwave-unit-name, idlwave-mode-menu-def)
+ (idlwave-create-customize-menu): Remove Emacs 20 compat code.
+
+2020-11-20 Stefan Kangas <stefan@marxist.se>
+
+ Properly mark obsolete semantic functions as such
+
+ * lisp/cedet/semantic/ia.el (semantic-ia-get-completions)
+ (semantic-ia-get-completions-deprecated): Make obsolete.
+
+2020-11-20 Stefan Kangas <stefan@marxist.se>
+
+ Mark compat alias in cus-face.el obsolete
+
+ * lisp/cus-face.el (custom-facep): Mark compat alias obsolete.
+ * lisp/cus-dep.el (custom-make-dependencies):
+ * lisp/cus-edit.el (customize-changed-options)
+ (custom-unsaved-options, customize-saved, customize-apropos)
+ (custom-save-faces): Adjust callers.
+
+2020-11-20 Eli Zaretskii <eliz@gnu.org>
+
+ Fix compilation on MS-Windows with librsvg > 2.46.0
+
+ * src/image.c (rsvg_handle_get_dimensions, init_svg_functions):
+ Make 'rsvg_handle_get_dimensions' available and defined for all
+ versions of librsvg. (Bug#44655)
+
+2020-11-20 Stefan Kangas <stefan@marxist.se>
+
+ Hide obsolete options in most customize commands
+
+ * lisp/cus-edit.el (custom--filter-obsolete-variables): New defun.
+ * lisp/cus-edit.el (customize-changed-options)
+ (customize-apropos, custom-group-value-create): Hide obsolete user
+ options. (Bug#44598)
+ * test/lisp/cus-edit-tests.el: New file.
+
+2020-11-20 João Tãvora <joaotavora@gmail.com>
+
+ Revert unintended part of last change to jsonrpc-request
+
+ While playing around with the timing in this function, I left
+ this change that could freeze the function on some platforms.
+
+ * lisp/jsonrpc.el (jsonrpc-request): Use accept-process-output.
+ (Version): Bump to 1.0.14
+
+2020-11-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move semantic/tag obsolete variables to avoid a warning
+
+ * lisp/cedet/semantic/tag.el (semantic-token-version): Move to
+ avoid a compilation warning.
+
+2020-11-20 João Távora <joaotavora@gmail.com>
+
+ Fix default timeout handling in jsonrpc-request
+
+ * lisp/jsonrpc.el (jsonrpc-request): Use default timeout if not passed.
+ (Version): Bump to 1.0.13
+
+2020-11-20 Andrea Corallo <akrl@sdf.org>
+
+ Add 'EMACSNATIVELOADPATH' env variable support (bug#44726)
+
+ * lisp/startup.el (normal-top-level): Read 'EMACSNATIVELOADPATH'
+ and add entries too `comp-eln-load-path'.
+ * lisp/mail/emacsbug.el (report-emacs-bug): Dump
+ also 'EMACSNATIVELOADPATH'.
+
+2020-11-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Avoid a compilation warning about an ambiguous else
+
+ * src/data.c (set_internal): Avoid compilation warning.
+
+ data.c:1443:9: error: suggest explicit braces to avoid ambiguous ‘else’
+ 1443 | if (idx > 0 && bindflag == SET_INTERNAL_SET
+ | ^
+
+2020-11-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/data.c (set_internal): Fix bug#44733
+
+ Set the default value when `set` encounters a PER_BUFFER variable
+ which has been let-bound globally, to match the behavior seen with
+ `make-variable-buffer-local`.
+
+ * test/src/data-tests.el (binding-test--let-buffer-local):
+ Add corresponding test.
+ (data-tests--set-default-per-buffer): Add tentative test for the
+ performance problem encountered in bug#41029.
+
+2020-11-19 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ * lisp/net/dictionary.el: Remove remnants of package
+
+ Version and package dependencies are not useful when included into
+ Emacs.
+
+2020-11-19 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'font-spec'
+
+ * doc/lispref/display.texi (Low-Level Font):
+ * src/font.c (Ffont_spec): Document 'font-spec' keys that are
+ supported, but were undocumented.
+
+2020-11-19 Stefan Kangas <stefan@marxist.se>
+
+ Remove some XEmacs compat code from filesets.el
+
+ * lisp/filesets.el (filesets-init): Remove some XEmacs compat code.
+ (filesets-error): Declare obsolete.
+ (filesets-directory-files, filesets-get-selection)
+ (filesets-spawn-external-viewer, filesets-get-filelist)
+ (filesets-open, filesets-close, filesets-get-menu-epilog)
+ (filesets-ingroup-collect-files, filesets-build-ingroup-submenu)
+ (filesets-update-pre010505): Adjust callers.
+
+2020-11-19 Stefan Kangas <stefan@marxist.se>
+
+ Remove some compat code from ffap.el
+
+ * lisp/ffap.el (ffap-mouse-event, ffap-event-buffer): Make obsolete.
+ (ffap-menu-ask, ffap-at-mouse): Adjust callers.
+
+2020-11-19 Stefan Kangas <stefan@marxist.se>
+
+ Declare some compat aliases obsolete
+
+ * lisp/cedet/semantic/tag.el (semantic-token-version)
+ (semantic-token-incompatible-version):
+ * lisp/emulation/edt.el (edt-bind-standard-key): Make compat
+ aliases obsolete.
+
+2020-11-19 Stefan Kangas <stefan@marxist.se>
+
+ Remove some compat code from url.el
+
+ * lisp/url/url.el (url-warn): Make into obsolete alias for
+ display-warning.
+ * lisp/url/url-auth.el (url-register-auth-scheme):
+ * lisp/url/url-news.el (url-news-open-host):
+ * lisp/url/url-proxy.el (url-find-proxy-for-url): Adjust callers.
+
+2020-11-19 Stefan Kangas <stefan@marxist.se>
+
+ Remove some compat code for old versions and XEmacs
+
+ * lisp/ibuf-ext.el (ibuffer-old-saved-filters-warning)
+ (ibuffer-maybe-save-stuff): Assume customize-save-variable is
+ bound; it is autoloaded.
+ * lisp/cedet/semantic/symref/grep.el (semantic-symref-perform-search):
+ * lisp/password-cache.el (password-cache-remove):
+ * lisp/cedet/semantic/bovine/el.el (semantic-dependency-tag-file):
+ Remove Emacs 21 compat code.
+ * lisp/cedet/semantic/sort.el (semantic-string-lessp-ci):
+ Remove Emacs 20 compat code.
+ * test/lisp/cedet/semantic-utest.el (semantic-utest-temp-directory):
+ * lisp/mail/supercite.el (sc-ask): Remove XEmacs compat code.
+ * lisp/progmodes/idlw-shell.el (idlwave-shell-mode):
+ * lisp/progmodes/idlwave.el (idlwave-mode): Remove commented out
+ compat code.
+
+2020-11-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/buffer.h (struct buffer): Remove unused field `minor_modes`
+
+ * src/buffer.c (bset_minor_modes): Remove function.
+ (reset_buffer_local_variables, init_buffer_once): Don't set `minor_modes`.
+
+2020-11-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Use decoding implementation from `insert-directory' in Tramp
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-insert-directory):
+ Use decoding implementation from `insert-directory', it is more robust.
+
+2020-11-19 Mattias Engdegård <mattiase@acm.org>
+
+ More string-search optimisations
+
+ All-ASCII strings cannot have substrings with non-ASCII characters in
+ them; use this fact to avoid searching entirely.
+
+ * src/fns.c (Fstring_search): For multibyte non-ASCII needle and
+ unibyte haystack, don't check if the haystack is all-ASCII; it's a
+ waste of time. For multibyte non-ASCII needle and multibyte
+ all-ASCII haystack, fail immediately.
+ * test/src/fns-tests.el (string-search): Add more test cases.
+
+2020-11-19 Alan Mackenzie <acm@muc.de>
+
+ * etc/NEWS: Restore entries accidentally removed by previous commit.
+
+2020-11-19 Alan Mackenzie <acm@muc.de>
+
+ In attempted recursive minibuffer use, display error message in correct frame
+
+ This was problematic when minibuffer-follows-selected-frame was non-nil.
+ Introduce a new parameter DONT-SET-FRAME to set-window-configuration.
+
+ * doc/lispref/windows.texi (Window Configurations): Describe the new &optional
+ parameter to set-window-configuration.
+
+ * etc/NEWS (Lisp Changes): Note the new parameter to set-window-configuration.
+
+ * src/keyboard.c (read_char_help_form_unwind): Add a new Qnil argument to the
+ call of Fset_window_configuration.
+
+ * src/minibuf.c (read_minibuf): Cons up a Qt with the window configuration in
+ the argument to record_unwind_protect for the window configuration (twice).
+
+ * src/window.c (Fset_window_configuration): Add the new &optional parameter
+ and document it in the doc string. At the final do_switch_frame operation,
+ restore the original frame when DONT-SET-FRAME is non-nil.
+ (restore_window_configuration): Handle the new parameter when the supplied
+ argument is a cons.
+
+2020-11-19 Matthias Meulien <orontee@gmail.com>
+
+ Add history of search words to read-string
+
+ Remove text property from empty line
+
+2020-11-19 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Move placement of dictionary-tooltip-mouse-event
+
+ * lisp/net/dictionary.el (dictionary-tooltip-mouse-event): Place
+ variable before dictionary-display-tooltip to avoid warning about use of
+ free variable when compiling dictionary-display-tooltip
+
+2020-11-19 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Support nil value for dictionary-server
+
+ * lisp/net/dictionary.el (dictionary-server): Support choice to select
+ the dictionary server to use.
+ * lisp/net/dictionary.el (dictionary-check-connection): Support nil
+ value for dictionary-server.
+
+ This nil value is the new default value of that variable. When
+ opening a new connection and dictionary-server is nil the code
+ behaves the following way:
+
+ - it will first try to connect to a dictd server running on localhost
+ - if that fails, it queries the user if the alternative
+ server (dict.org) should be consulted
+ - if the user agrees, the connection is made to dict.org
+
+ This allows the default value of dictionary-server not to connect
+ a remote server by default. The user is always able to select a
+ different server by customizing the variable dictionary-search.
+
+2020-11-19 Stefan Kangas <stefan@marxist.se>
+
+ Remove outdated comment about Emacs 20 from viper.el
+
+ * lisp/emulation/viper-util.el (viper-chars-in-region): Remove
+ outdated comment.
+
+2020-11-19 Stefan Kangas <stefan@marxist.se>
+
+ Add new variable cperl-tags-file-name
+
+ * lisp/progmodes/cperl-mode.el (cperl-tags-file-name): New variable.
+ (cperl-write-tags): Use above new variable instead of hardcoding
+ filename "TAGS". (Bug#8802)
+
+2020-11-19 Stefan Kangas <stefan@marxist.se>
+
+ Declare XEmacs compat function in inversion.el obsolete
+
+ * lisp/cedet/inversion.el (inversion-require-emacs): Declare obsolete.
+
+2020-11-19 Stefan Kangas <stefan@marxist.se>
+
+ Assume font-lock is provided; it's preloaded since 22.1
+
+ * lisp/cedet/semantic/format.el (semantic--format-colorize-text):
+ * lisp/eshell/em-ls.el (eshell-ls--insert-directory):
+ * lisp/net/dig.el (dig-mode):
+ * lisp/progmodes/cperl-mode.el (cperl-pod-here-fontify):
+ * lisp/progmodes/idlw-help.el (idlwave-help-fontify):
+ * lisp/progmodes/idlwave.el (idlwave-completion-fontify-classes):
+ Don't check for feature 'font-lock; it has been preloaded since 22.1.
+ * lisp/cedet/semantic/format.el (font-lock):
+ * lisp/epa.el (font-lock):
+ * lisp/erc/erc.el (font-lock):
+ * lisp/generic-x.el (font-lock):
+ * lisp/net/sieve-mode.el (font-lock):
+ * lisp/progmodes/prolog.el (font-lock):
+ * lisp/textmodes/rst.el (font-lock): Remove unnecessary require.
+
+2020-11-19 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/progmodes/cperl-mode.el: Doc fix.
+
+2020-11-19 Stefan Kangas <stefan@marxist.se>
+
+ Remove unnecessary load from idlwave
+
+ * lisp/progmodes/idlw-shell.el:
+ * lisp/progmodes/idlwave.el: Remove unnecessary load; easy-menu-define
+ is autoloaded.
+
+2020-11-19 Stefan Kangas <stefan@marxist.se>
+
+ Make compat alias add-submenu obsolete
+
+ * lisp/emacs-lisp/easymenu.el (add-submenu): Make compat alias
+ obsolete.
+ * lisp/filesets.el (filesets-build-menu-now): Don't use above
+ obsolete alias.
+ (filesets-menu-path, filesets-menu-before)
+ (filesets-menu-in-menu): Doc fix.
+
+2020-11-19 Alan Third <alan@idiocy.org>
+
+ Fix SVG display again (bug#44655)
+
+ * src/image.c (svg_load_image): Fall back to
+ rsvg_handle_get_dimensions if we can't calculate the size of the
+ image.
+
+2020-11-18 Protesilaos Stavrou <info@protesilaos.com>
+
+ Clarify that 'diff-error' is part of Emacs 28.1
+
+ * lisp/vc/diff-mode.el (diff-error): Add :version tag (bug#44727).
+
+2020-11-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further doc fixes for dotimes about RESULT
+
+ * lisp/subr.el (dotimes): Be even more explicit about RESULT
+ (bug#16206).
+
+ (cherry picked from commit 5b0d8d0f288fd505ca90bd30df709a5e7ab540d6)
+
+2020-11-18 Andrea Corallo <akrl@sdf.org>
+
+ Fix eln file hasing for symlink paths (bug#44701)
+
+ * src/comp.c (Fcomp_el_to_eln_filename): Call `file-truename'
+ in place of `expand-file-name' when available.
+
+2020-11-18 Jonas Bernoulli <jonas@bernoul.li>
+
+ Revert "[WIP] Add and improve section headings"
+
+ This reverts commit 007a5a677573ab628426a0605eb38f8e68fe1953.
+
+2020-11-18 Jonas Bernoulli <jonas@bernoul.li>
+
+ Revert "[TODO] Remove noisy anti-noise feature"
+
+ This reverts commit c36b4eed2d76f0e804d27d35dd6281f858639f94.
+
+2020-11-18 Jonas Bernoulli <jonas@bernoul.li>
+
+ [TODO] Remove noisy anti-noise feature
+
+ [WIP] Add and improve section headings
+
+2020-11-18 Mattias Engdegård <mattiase@acm.org>
+
+ Turn gdb-wait-for-pending into a plain function
+
+ This avoids unnecessary body duplication in expansion and macro
+ recursion (causing macro-expansions at runtime), making it clearer
+ what is going on.
+
+ * lisp/progmodes/gdb-mi.el (gdb-wait-for-pending): Make it a function,
+ remove lambda quoting, η-reduce and simplify.
+ (gdb-thread-exited, gdb-thread-selected): Adapt callers.
+
+2020-11-18 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Don't make bibtex-unify-case-convert buffer-local
+
+ The :local tag does not currently work as intended (it results in a
+ default value of bibtex-unify-case-convert of nil rather than
+ identity), and no other bibtex.el user option is automatically
+ buffer-local, so revert this recent change.
+
+ For discussion, see the following emacs-devel thread:
+ https://lists.gnu.org/r/emacs-devel/2020-11/msg00734.html
+
+ * lisp/textmodes/bibtex.el (bibtex-unify-case-convert): Don't make
+ automatically buffer-local for consistency with other user options,
+ and because the :local tag doesn't have the intended results.
+
+2020-11-18 Michael Albinus <michael.albinus@gmx.de>
+
+ Preserve `dired-filename' text properties in Tramp
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-insert-directory):
+ Restore `dired-filename' text property, which has been destroyed
+ by `decode-coding-region'. (Bug#44682)
+
+2020-11-17 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant 'function's around lambdas
+
+ * lisp/allout.el (allout-latex-verb-quote):
+ * lisp/edmacro.el (edmacro-format-keys):
+ * lisp/ffap.el (ffap-all-subdirs-loop)
+ (ffap-kpathsea-expand-path, ffap-menu-rescan):
+ * lisp/files.el (save-buffers-kill-emacs):
+ * lisp/find-lisp.el (find-lisp-find-dired-internal)
+ (find-lisp-insert-directory):
+ * lisp/gnus/gnus-agent.el (gnus-agent-expire-unagentized-dirs):
+ * lisp/gnus/nnmairix.el (nnmairix-create-message-line-for-search)
+ (nnmairix-widget-get-values)
+ (nnmairix-widget-make-query-from-widgets)
+ (nnmairix-widget-build-editable-fields):
+ * lisp/international/mule-cmds.el (sort-coding-systems):
+ * lisp/international/mule-diag.el (list-character-sets-1):
+ * lisp/international/quail.el (quail-insert-decode-map):
+ * lisp/mail/reporter.el (reporter-dump-state):
+ * lisp/mail/supercite.el (sc-attribs-filter-namelist):
+ * lisp/pcmpl-gnu.el (pcmpl-gnu-zipped-files)
+ (pcmpl-gnu-bzipped-files):
+ * lisp/progmodes/cperl-mode.el (cperl-find-tags)
+ (cperl-write-tags, cperl-tags-hier-init, cperl-tags-treeify)
+ (cperl-menu-to-keymap, cperl-pod-spell):
+ * lisp/progmodes/gdb-mi.el (gdb-parent-mode):
+ * lisp/progmodes/make-mode.el (makefile-browser-fill):
+ * lisp/simple.el (transpose-lines):
+ * lisp/term.el:
+ * lisp/term/w32-win.el (w32-find-non-USB-fonts):
+ * lisp/textmodes/table.el (table--generate-source-scan-lines): Remove
+ redundant 'function's around lambdas.
+
+2020-11-17 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant 'function's around lambdas in mh/*.el
+
+ * lisp/mh-e/mh-alias.el (mh-alias-tstamp, mh-alias-filenames)
+ (mh-alias-address-to-alias):
+ * lisp/mh-e/mh-comp.el (mh-edit-again, mh-redistribute):
+ * lisp/mh-e/mh-identity.el (mh-identity-make-menu):
+ * lisp/mh-e/mh-utils.el (mh-help): Remove redundant 'function's around
+ lambdas.
+
+2020-11-17 Alan Mackenzie <acm@muc.de>
+
+ Enhance syntax-tests.el to test nestable comments (Lisp style)
+
+ Also add some tests for braces and parse-partial-sexp amongst Lisp style
+ comments.
+
+ * test/src/syntax-tests.el (\;-in, \;-out): Add syntax for { and }.
+ (top-level): Add new tests for Lisp style comments.
+ (\#|-in, \#|-out): New functions.
+ (top-level): Add new tests for nested Lisp style comments, and mixtures of
+ nested comments with "ordinary" comments.
+
+ * test/src/syntax-resources/syntax-comments.txt (top-level): Add new test
+ fragments for #|...|#, etc.
+
+2020-11-17 Stefan Kangas <stefan@marxist.se>
+
+ Don't quote lambdas with 'function' in calc/*.el
+
+ * lisp/calc/calc-aent.el (calc-do-quick-calc)
+ (calc-do-calc-eval, math-build-parse-table):
+ * lisp/calc/calc-alg.el (math-polynomial-base):
+ * lisp/calc/calc-alg.el (math-is-poly-rec):
+ * lisp/calc/calc-arith.el (calcFunc-scf):
+ * lisp/calc/calc-arith.el (math-ceiling, math-round):
+ * lisp/calc/calc-arith.el (math-trunc-fancy, math-floor-fancy):
+ * lisp/calc/calc-ext.el (calc-init-extensions, calc-reset)
+ (calc-refresh-top, calc-z-prefix-help, calc-binary-op-fancy)
+ (calc-unary-op-fancy):
+ * lisp/calc/calc-forms.el (math-make-mod):
+ * lisp/calc/calc-frac.el (calcFunc-frac):
+ * lisp/calc/calc-funcs.el (calcFunc-euler):
+ * lisp/calc/calc-help.el (calc-full-help):
+ * lisp/calc/calc-lang.el (c, pascal, fortran, tex, latex, eqn)
+ (yacas, maxima, giac, math, maple):
+ * lisp/calc/calc-macs.el (calc-wrapper, calc-slow-wrapper):
+ * lisp/calc/calc-map.el (calc-get-operator, calcFunc-mapeqr)
+ (calcFunc-reducea, calcFunc-rreducea, calcFunc-reduced)
+ (calcFunc-rreduced, calcFunc-outer):
+ * lisp/calc/calc-misc.el (another-calc, calc-do-handle-whys):
+ * lisp/calc/calc-mode.el (calc-save-modes):
+ * lisp/calc/calc-mtx.el (math-col-matrix, math-mul-mat-vec):
+ * lisp/calc/calc-poly.el (math-sort-terms, math-poly-div-list)
+ (math-mul-list, math-sort-poly-base-list)
+ (math-partial-fractions):
+ * lisp/calc/calc-prog.el (calc-user-define-formula):
+ * lisp/calc/calc-rewr.el (math-rewrite, math-compile-patterns)
+ (math-compile-rewrites, math-parse-schedule)
+ (math-rwcomp-pattern):
+ * lisp/calc/calc-store.el (calc-var-name-map, calc-let)
+ (calc-permanent-variable, calc-insert-variables):
+ * lisp/calc/calc-stuff.el (calc-flush-caches, calcFunc-pclean)
+ (calcFunc-pfrac):
+ * lisp/calc/calc-units.el (math-build-units-table)
+ (math-decompose-units):
+ * lisp/calc/calc-vec.el (calcFunc-mrow, math-mat-col)
+ (calcFunc-mcol, math-mat-less-col, math-mimic-ident):
+ * lisp/calc/calc-yank.el (calc-edit):
+ * lisp/calc/calc.el
+ (calc-mode-var-list-restore-default-values)
+ (calc-mode-var-list-restore-saved-values, calc-mode, calc-quit):
+ * lisp/calc/calccomp.el (math-compose-expr)
+ (math-compose-matrix, math-vector-to-string): Don't quote lambdas with
+ 'function'.
+
+2020-11-17 Stefan Kangas <stefan@marxist.se>
+
+ Add command to filter package menu by name or description
+
+ * lisp/emacs-lisp/package.el (package-menu-filter-by-description):
+ (package-menu-filter-by-name-or-description): New commands to filter
+ the package menu. (Bug#44699)
+ (package-menu-mode-map): Bind the above new commands.
+ (package-menu-mode-menu): Add new commands to the menu.
+ * doc/emacs/package.texi (Package Menu): Document new commands.
+
+2020-11-17 Stefan Kangas <stefan@marxist.se>
+
+ Don't quote lambdas with function macro in generic-x.el
+
+ * lisp/generic-x.el (apache-conf-generic-mode, ini-generic-mode)
+ (reg-generic-mode, mailagent-rules-generic-mode)
+ (vrml-generic-mode, java-properties-generic-mode)
+ (alias-generic-mode, ansible-inventory-generic-mode)
+ (inetd-conf-generic-mode, etc-services-generic-mode)
+ (etc-passwd-generic-mode, etc-fstab-generic-mode)
+ (spice-generic-mode, astap-generic-mode): Don't quote lambdas with
+ function macro.
+
+2020-11-17 Stefan Kangas <stefan@marxist.se>
+
+ Test that substitute-command-keys preserves text properties
+
+ * test/lisp/help-tests.el
+ (help-substitute-command-keys/preserves-text-properties): New test.
+ (Bug#17052)
+
+2020-11-17 Harald Jörg <haj@posteo.de>
+
+ perl-mode and cperl-mode: Recognize regex after "return"
+
+ * lisp/progmodes/cperl-mode.el (cperl-find-pods-heres): Add
+ "return" to the keywords which start a regex.
+
+ * lisp/progmodes/perl-mode.el (defconst): Add "return" to
+ 'perl--syntax-exp-intro-keywords' (Bug#26850).
+
+ * test/lisp/progmodes/cperl-mode-tests.el (cperl-test-bug-28650):
+ New test (bug#26850).
+
+2020-11-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Minor Edebug manual keystroke clarifications
+
+ * doc/lispref/edebug.texi (Edebug Misc): Also mention the `a'
+ binding to abort (bug#44697). Also fix `d' function reference, and
+ add `P' reference.
+
+2020-11-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the handwrite.el PS valid again
+
+ * lisp/play/handwrite.el (handwrite): Make the PS valid
+ (bug#44648). Suggested by Omar Antolín <omar.antolin@gmail.com>.
+
+2020-11-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix gnus-mime-display-alternative button natigation
+
+ * lisp/gnus/gnus-art.el (gnus-mime-display-alternative): Mark the
+ buttons correctly so that TAB can find them (bug#44690).
+
+2020-11-16 Ruthra Kumar <ruthrab@gmail.com>
+
+ Use 'eshell-find-alias-function' instead of fboundp
+
+ * lisp/eshell/esh-cmd.el (eshell-invoke-directly): Fix problem
+ with (require 'em-tramp) making password prompting from "sudo
+ bash" no longer work (bug#43772).
+
+2020-11-16 Francesco Potortì <pot@gnu.org>
+
+ Add new user option bibtex-unify-case-convert
+
+ * lisp/textmodes/bibtex.el (bibtex-unify-case-convert): New
+ variable (bug#44614).
+ (bibtex-format-entry): Use it (bug#44614).
+
+2020-11-16 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in time-stamp.el
+
+ * lisp/time-stamp.el: Use lexical-binding. Remove redundant :group
+ args.
+
+2020-11-16 Stefan Kangas <stefan@marxist.se>
+
+ Don't quote lambdas in net/*.el
+
+ * lisp/net/eudc-export.el (eudc-create-bbdb-record):
+ * lisp/net/eudc.el (eudc-print-attribute-value)
+ (eudc-display-records, eudc-process-form)
+ (eudc-filter-duplicate-attributes, eudc-filter-partial-records)
+ (eudc-add-field-to-records, eudc-query-with-words)
+ (eudc-query-form, eudc-menu):
+ * lisp/net/eudcb-bbdb.el (eudc-bbdb-extract-phones)
+ (eudc-bbdb-query-internal):
+ * lisp/net/mairix.el (mairix-widget-make-query-from-widgets)
+ (mairix-widget-build-editable-fields, mairix-widget-get-values):
+ Don't quote lambdas.
+
+2020-11-16 Stefan Kangas <stefan@marxist.se>
+
+ Don't quote lambdas in emacs-lisp/*.el
+
+ * lisp/emacs-lisp/cl-seq.el (cl--parsing-keywords, cl-sort):
+ * lisp/emacs-lisp/cl-macs.el (cl-typecase):
+ * lisp/emacs-lisp/cl-extra.el (cl-some, cl-every)
+ (cl--map-keymap-recursively):
+ * lisp/emacs-lisp/advice.el (ad-insert-argument-access-forms):
+ * lisp/emacs-lisp/edebug.el (edebug-sort-alist)
+ (edebug-set-windows):
+ * lisp/emacs-lisp/pp.el (pp-display-expression):
+ * lisp/emacs-lisp/regi.el (regi-interpret): Don't quote lambdas.
+
+2020-11-16 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 75723ec212 (origin/emacs-27) ; * lisp/emacs-lisp/benchmark.el (benchm...
+ 53e2a612ad ; * lib-src/make-fingerprint.c: Update commentary.
+ 286c632772 Reformat argument commentary in etags.c
+ 4ec740866a Make the invocation of combine-change-calls in comment-reg...
+ 66bcec8838 * lisp/progmodes/cc-langs.el (c-<>-notable-chars-re): Fix ...
+ 03eeab469e ; Update the expected result files in test/manual/etags.
+ d875a22bc6 Update the various INSTALL files
+
+ # Conflicts:
+ # INSTALL
+
+2020-11-16 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 19da602991 Fix input method translation near read-only text
+ 5aabf2cc7f Fix display of truncated R2L lines on TTY frames
+ daff3bda10 Avoid crashes when a reversed glyph row starts with a comp...
+ b697bb91a1 ; * .gitignore: src/fingerprint.c not generated since 2019...
+
+2020-11-16 Stefan Kangas <stefan@marxist.se>
+
+ Don't quote lambdas in calc/calcalg{2,3}.el
+
+ * lisp/calc/calcalg2.el (calcFunc-inv\', calcFunc-sqrt\')
+ (calcFunc-deg\', calcFunc-rad\', calcFunc-ln\')
+ (calcFunc-log10\', calcFunc-lnp1\', calcFunc-log\')
+ (calcFunc-log\'2, calcFunc-exp\', calcFunc-expm1\')
+ (calcFunc-sin\', calcFunc-cos\', calcFunc-tan\', calcFunc-sec\')
+ (calcFunc-csc\', calcFunc-cot\', calcFunc-arcsin\')
+ (calcFunc-arccos\', calcFunc-arctan\', calcFunc-sinh\')
+ (calcFunc-cosh\', calcFunc-tanh\', calcFunc-sech\')
+ (calcFunc-csch\', calcFunc-coth\', calcFunc-arcsinh\')
+ (calcFunc-arccosh\', calcFunc-arctanh\', calcFunc-bern\'2)
+ (calcFunc-euler\'2, calcFunc-gammag\'2, calcFunc-gammaG\'2)
+ (calcFunc-gammaP\'2, calcFunc-gammaQ\'2, calcFunc-betaB\')
+ (calcFunc-betaI\', calcFunc-erf\', calcFunc-erfc\')
+ (calcFunc-besJ\'2, calcFunc-besY\'2, calcFunc-sum)
+ (calcFunc-prod, calcFunc-integ, calcFunc-if, calcFunc-subscr)
+ (math-do-integral, calcFunc-integ, math-decompose-poly)
+ (math-solve-system-rec, math-solve-system-subst, math-solve-for)
+ (calcFunc-inv, calcFunc-sqrt, calcFunc-conj, calcFunc-abs)
+ (calcFunc-deg, calcFunc-rad, calcFunc-ln, calcFunc-log10)
+ (calcFunc-lnp1, calcFunc-exp, calcFunc-expm1, calcFunc-sin)
+ (calcFunc-cos, calcFunc-tan, calcFunc-arcsin, calcFunc-arccos)
+ (calcFunc-arctan, calcFunc-sinh, calcFunc-cosh, calcFunc-tanh)
+ (calcFunc-arcsinh, calcFunc-arccosh, calcFunc-arctanh):
+ * lisp/calc/calcalg3.el (calc-get-fit-variables)
+ (calcFunc-polint, calcFunc-ratint, math-all-vars-but): Don't quote
+ lambdas.
+
+2020-11-16 Stefan Kangas <stefan@marxist.se>
+
+ Various doc fixes for comp.el and comp.c
+
+ * lisp/emacs-lisp/comp.el: Remove redundant :group args.
+ (comp-async-cu-done-hook, comp-async-all-done-hook)
+ (comp-async-env-modifier-form, comp-dry-run)
+ (comp-ensure-native-compiler, comp-func-ret-typeset)
+ (comp-func-ret-range, comp-limple-lock-keywords)
+ (comp-make-curr-block):
+ * src/comp.c (Fcomp_el_to_eln_filename, Fcomp__init_ctxt)
+ (Fcomp_native_driver_options_effective_p)
+ (Fcomp__compile_ctxt_to_file, Fcomp_libgccjit_version)
+ (Fcomp__register_lambda, Fcomp__register_subr)
+ (Fcomp__late_register_subr, Fnative_elisp_load, syms_of_comp): Doc fixes.
+
+2020-11-16 Andrea Corallo <akrl@sdf.org>
+
+ Fix nativecomp cond-rw pass
+
+ * lisp/emacs-lisp/comp.el (comp-mvar-symbol-p): Improve it.
+ (comp-cond-rw-func): Fix logic for multiple predecessor on target
+ block.
+ * test/src/comp-tests.el (comp-test-cond-rw-1): New test.
+ * test/src/comp-test-funcs.el (comp-test-cond-rw-1-1-f)
+ (comp-test-cond-rw-1-2-f): New functions.
+
+2020-11-16 Stefan Kangas <stefan@marxist.se>
+
+ Don't quote lambdas in eshell/*.el
+
+ * lisp/eshell/em-basic.el (eshell-echo):
+ * lisp/eshell/em-cmpl.el (eshell-command-completion-function)
+ (eshell-default-completion-function, eshell-cmpl-initialize)
+ (eshell-complete-parse-arguments, eshell-complete-commands-list):
+ * lisp/eshell/em-dirs.el (eshell-complete-user-reference):
+ * lisp/eshell/em-hist.el (eshell-hist-unload-hook)
+ (eshell-hist-initialize):
+ * lisp/eshell/em-ls.el (eshell-ls-sort-entries):
+ * lisp/eshell/em-pred.el (eshell-modifier-alist)
+ (eshell-display-predicate-help, eshell-display-modifier-help)
+ (eshell-pred-substitute, eshell-split-members):
+ * lisp/eshell/em-prompt.el (eshell-prompt-function):
+ * lisp/eshell/em-smart.el (eshell-smart-unload-hook)
+ (eshell-smart-initialize, eshell-refresh-windows):
+ * lisp/eshell/em-unix.el (eshell-shuffle-files):
+ * lisp/eshell/esh-arg.el (eshell-parse-argument-hook):
+ * lisp/eshell/esh-cmd.el (eshell-cmd-initialize)
+ (eshell-parse-command):
+ * lisp/eshell/esh-mode.el (eshell-preinput-scroll-to-bottom)
+ (eshell-postoutput-scroll-to-bottom):
+ * lisp/eshell/esh-module.el (eshell-modules-list):
+ * lisp/eshell/esh-proc.el (eshell-read-process-name)
+ (eshell-round-robin-kill):
+ * lisp/eshell/esh-var.el (eshell-envvar-names)
+ (eshell-variables-list): Don't quote lambdas.
+
+2020-11-15 Juri Linkov <juri@linkov.net>
+
+ New user options 'copy-region-blink-delay' and 'delete-pair-blink-delay'
+
+ * lisp/emacs-lisp/lisp.el (delete-pair-blink-delay): New defcustom.
+ (delete-pair): Use it. (Bug#4136)
+
+ * lisp/simple.el (copy-region-blink-delay): New defcustom.
+ (indicate-copied-region): Use it. (Bug#42865)
+ Thanks to Sean Whitton <spwhitton@spwhitton.name>.
+ (indicate-copied-region): Use 'query-replace-descr' not to show
+ newlines literally. Use "Copied text" instead of misleading
+ "Saved text" (bug#42865).
+
+2020-11-15 Andrea Corallo <akrl@sdf.org>
+
+ Improve `comp-fwprop-call'
+
+ * lisp/emacs-lisp/comp.el (comp-function-call-maybe-fold):
+ Document return value.
+ (comp-fwprop-call): Simplify and improve.
+
+2020-11-15 Andrea Corallo <akrl@sdf.org>
+
+ Add more type specifiers
+
+ * lisp/emacs-lisp/comp.el (comp-known-type-specifiers): Add more
+ pure functions.
+
+2020-11-15 Eli Zaretskii <eliz@gnu.org>
+
+ Reformat argument commentary in etags.c
+
+ * lib-src/etags.c (pfnote, consider_token, C_entries): Resurrect
+ original format of comments to function arguments.
+
+2020-11-15 Mattias Engdegård <mattiase@acm.org>
+
+ Reformat comment for 'gnu' compilation rule
+
+ * lisp/progmodes/compile.el (compilation-error-regexp-alist-alist):
+ The comments above the regexp for the 'gnu' rule contained
+ references to the previous string regexp, which has been difficult
+ to follow ever since the translation to rx. Move the comments
+ to their proper places, and add some guiding notes.
+
+2020-11-15 Alan Mackenzie <acm@muc.de>
+
+ Make the invocation of combine-change-calls in comment-region valid
+
+ This fixes bug #44581. The problem was that whitespace outside of the (BEG
+ END) region was being deleted, and this made the invocation of
+ combine-change-calls with (BEG END) invalid.
+
+ * lisp/newcomment.el (comment-region-default): Amend the second argument to
+ combine-change-calls.
+
+2020-11-15 Alan Mackenzie <acm@muc.de>
+
+ * lisp/progmodes/cc-langs.el (c-<>-notable-chars-re): Fix wrong '-' in regexp
+
+2020-11-15 Stefan Kangas <stefan@marxist.se>
+
+ Make initial frame match frame-title-format
+
+ * src/xterm.c (x_term_init):
+ * src/w32term.c (w32_initialize_display_info): Sync initial frame
+ title with new value of Vframe_title_format.
+ Problem reported by Angelo Graziosi <angelo.g0@libero.it>.
+
+2020-11-15 Stefan Kangas <stefan@marxist.se>
+
+ Run menu-item :filter function before showing binding
+
+ * lisp/help.el (describe-map): Fix running `menu-item' :filter
+ functions. This fixes a mistake in the previous conversion of this
+ defun from the old C function describe_map. See the discussion in
+ Bug#39149.
+ * test/src/keymap-tests.el
+ (keymap---get-keyelt/runs-menu-item-filter)
+ (describe-buffer-bindings/menu-item-filter-show-binding)
+ (describe-buffer-bindings/menu-item-filter-hide-binding):
+ New tests.
+ (keymap-tests--test-menu-item-filter): New defun.
+
+2020-11-14 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Handle negation of search keys in gnus-search minibuffer completion
+
+ * lisp/gnus/gnus-search.el (gnus-search-get-active): Keys might start
+ with a leading "-": check for that and ignore it.
+
+2020-11-14 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into dev
+
+2020-11-14 Andrea Corallo <akrl@sdf.org>
+
+ Add `comp-constraint-to-type-spec' and better handle boolean type spec
+
+ * lisp/emacs-lisp/comp.el (comp-constraint-to-type-spec): New
+ function splitting out code from comp-ret-type-spec + better
+ handle boolean type specifier.
+ (comp-ret-type-spec): Rework to leverage
+ `comp-constraint-to-type-spec'.
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add a
+ testcase.
+
+2020-11-14 Andrea Corallo <akrl@sdf.org>
+
+ Handle correctly quoting in *Native-compile-Log* buffer
+
+ * lisp/emacs-lisp/comp.el (comp-log): Add `quoted' parameter and
+ pass it to `comp-log-to-buffer'.
+ (comp-log-to-buffer): Add `quoted' parameter and leverage `prin1'
+ or `princ' accordingly.
+
+2020-11-14 Andrea Corallo <akrl@sdf.org>
+
+ Split logic into comp-fwprop-call and improve it
+
+ * lisp/emacs-lisp/comp.el (comp-func-ret-valset)
+ (comp-fwprop-call): New functions.
+ (comp-fwprop-insn): Remove code duplicaiton and call
+ `comp-fwprop-call'.
+
+2020-11-14 Andrea Corallo <akrl@sdf.org>
+
+ Fix debug symbol emission
+
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Now that we do not
+ rely anymore on globlal variables move logic in from
+ 'Fcomp__init_ctxt' so comp.debug is already set correctly.
+
+2020-11-14 Andrea Corallo <akrl@sdf.org>
+
+ Add a number of type specifiers for pure function
+
+ * lisp/emacs-lisp/comp.el (comp-known-type-specifiers): Add 60
+ pure function type specifiers.
+
+2020-11-14 Andrea Corallo <akrl@sdf.org>
+
+ Characterize functions in terms of type specifiers
+
+ * lisp/emacs-lisp/comp.el (comp-known-type-specifiers): New const
+ in place of `comp-known-ret-types' and `comp-known-ret-ranges'.
+ (comp-constraint): New struct to separate the constraint side of
+ an mvar.
+ (comp-constraint-f): Analogous for functions.
+ (comp-mvar): Rework and include `comp-constraint'.
+ (comp-type-spec-to-constraint): New function.
+ (comp-known-constraints-h): New const.
+ (comp-func-ret-typeset, comp-func-ret-range): Rework.
+ (comp-fwprop-insn): Fix.
+ * test/src/comp-tests.el (destructure-type-spec): New testcase.
+
+2020-11-14 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/xref.el (xref-goto-xref): Prefix arg quits the *xref* buffer.
+
+ (bug#44611)
+
+2020-11-14 Juri Linkov <juri@linkov.net>
+
+ * lisp/org/ob-ruby.el (org-babel-ruby-initiate-session): Use :ruby header arg.
+
+ Allow specification of ruby command using the :ruby header arg.
+ https://lists.gnu.org/archive/html/emacs-orgmode/2020-11/msg00166.html
+
+2020-11-14 Daniel Lenski <dlenski@gmail.com> (tiny change)
+
+ Fix `speedbar-directory-buttons' when using Tramp
+
+ * lisp/speedbar.el (speedbar-directory-buttons): Make speedbar
+ work with directories accessed via Tramp (bug#44622).
+
+2020-11-14 Stefan Kangas <stefan@marxist.se>
+
+ Don't quote lambdas in several places
+
+ * lisp/align.el (align-highlight-rule):
+ * lisp/bookmark.el (bookmark-maybe-sort-alist):
+ * lisp/emacs-lisp/advice.el (ad-read-advice-name)
+ (ad-retrieve-args-form, ad-make-hook-form, defadvice)
+ (ad-with-originals):
+ * lisp/foldout.el (foldout-inhibit-key-bindings):
+ * lisp/gnus/gnus-bookmark.el (gnus-bookmark-maybe-sort-alist):
+ * lisp/mail/rfc822.el (rfc822-addresses-1):
+ * lisp/net/eudcb-ldap.el (eudc-ldap-cleanup-record-simple):
+ * lisp/net/net-utils.el (network-connection-to-service):
+ * lisp/net/socks.el (socks-build-auth-list):
+ * lisp/org/ox-odt.el (org-odt--image-size):
+ * lisp/pcomplete.el (pcomplete-command-completion-function)
+ (pcomplete-default-completion-function, pcomplete-opt):
+ * lisp/progmodes/cperl-mode.el (cperl-highlight-charclass)
+ (cperl-tags-hier-init, cperl-tags-treeify)
+ (cperl-next-interpolated-REx, cperl-time-fontification):
+ * lisp/shadowfile.el (shadow-copy-files, shadow-shadows-of-1)
+ (shadow-save-buffers-kill-emacs):
+ * lisp/strokes.el (strokes-renormalize-to-grid):
+ * lisp/tempo.el (tempo-insert, tempo-forward-mark)
+ (tempo-backward-mark):
+ * lisp/textmodes/artist.el (artist-submit-bug-report):
+ * lisp/textmodes/ispell.el (ispell-complete-word):
+ * lisp/url/url-auth.el (url-get-authentication):
+ * lisp/url/url-cache.el (url-cache-create-filename-human-readable):
+ * lisp/vcursor.el (vcursor-find-window):
+ * test/lisp/textmodes/reftex-tests.el
+ (reftex-parse-bibtex-entry-test): Don't quote lambdas.
+
+2020-11-14 Akira Kyle <akira@akirakyle.com> (tiny change)
+
+ Work around glib messing with signal handlers more than it should
+
+ * src/process.c (init_process_emacs): force glib's g_unix_signal
+ handler into lib_child_handler where it should belong.
+
+2020-11-14 Pablo Barbáchano <pablob@amazon.com>
+
+ Add an option to preserve ANSI sequences
+
+ * lisp/ansi-color.el: Add an option to preserve the ANSI sequences.
+ * test/lisp/ansi-color-tests.el: Add tests (bug#44589).
+
+2020-11-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ project-or-external-find-file doc string fix
+
+ * lisp/progmodes/project.el (project-or-external-find-file): Doc
+ string fix -- it's not "recognizing" file names (bug#44588).
+
+2020-11-14 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in fortune.el and add tests
+
+ * lisp/play/fortune.el: Use lexical-binding. Remove redundant
+ :group args.
+ (fortune-in-buffer): Quote function symbol as such.
+ * test/lisp/play/fortune-resources/fortunes:
+ * test/lisp/play/fortune-tests.el: New files.
+ * .gitignore: Ignore generated file fortunes.dat.
+
+2020-11-14 Eli Zaretskii <eliz@gnu.org>
+
+ Update the various INSTALL files
+
+ * nt/INSTALL.W64:
+ * nt/INSTALL:
+ * INSTALL: Update the installation information, in particular the
+ fact that HarfBuzz is now preferred as the shaping library.
+
+2020-11-14 Eli Zaretskii <eliz@gnu.org>
+
+ Fix input method translation near read-only text
+
+ * lisp/international/quail.el (quail-input-method): Don't disable
+ input method when the character after point has the read-only
+ property. Suggested by Evgeny Zajcev <lg.zevlg@gmail.com>
+ (Bug#44466)
+
+ * doc/emacs/mule.texi (Input Methods): Document that input methods
+ are inhibited in read-only text.
+
+2020-11-14 Eli Zaretskii <eliz@gnu.org>
+
+ Make Calc windows dedicated by default
+
+ * lisp/calc/calc.el (calc-make-windows-dedicated): New defcustom.
+ (calc, calc-trail-display): Set Calc windows dedicated if
+ calc-make-windows-dedicated is non-nil. Patch by Boruch Baum
+ <boruch_baum@gmx.com>. (Bug#44108)
+
+ * etc/NEWS (Calc): Announce the new behavior.
+
+2020-11-14 Eli Zaretskii <eliz@gnu.org>
+
+ Make 'prefer-utf-8' heed inhibit-*-detection variables
+
+ * lisp/international/mule-conf.el (prefer-utf-8): Inhibit
+ detection of null bytes and ISO escape sequences if the respective
+ inhibit-*-detection variables say so. (Bug#44486)
+
+2020-11-14 Jared Finder <jared@finder.org>
+
+ * lisp/faces.el (mode-line-highlight): Use :box only when supported.
+
+2020-11-14 Philipp Stephani <phst@google.com>
+
+ Capitalize portable dump messages.
+
+ We capitalize all other messages during the dump, so capitalize the
+ "dump mode" and "dumping fingerprint" ones as well for consistency.
+
+ * src/pdumper.c (Fdump_emacs_portable): Capitalize fingerprint message
+ prefix.
+
+ * lisp/loadup.el: Capitalize "dump mode" message.
+
+2020-11-14 Jared Finder <jared@finder.org>
+
+ Face-changing text properties and help-echo now work with xterm-mouse.
+
+ * src/dispnew.c (update_mouse_position): New function for mouse
+ movement logic in 'handle_one_term_event' that can be shared across
+ different mouse backends.
+ (display--update-for-mouse-movement): New lisp function, call it.
+ * lisp/xt-mouse.el (xterm-mouse--handle-mouse-movement): New function
+ that calls 'display--update-for-mouse-movement'.
+ (xterm-mouse-translate-1): Call it.
+ * src/term.c (handle_one_term_event): Inline logic from
+ 'term_mouse_movement' and call 'update_mouse_position'.
+ (term_mouse_movement): Delete.
+
+2020-11-14 Eli Zaretskii <eliz@gnu.org>
+
+ Fix display of truncated R2L lines on TTY frames
+
+ * src/xdisp.c (extend_face_to_end_of_line): Use a while-loop, not
+ a do-while loop, to avoid appending an extra glyph at the end of a
+ line that is one character shorter than the window-width. This is
+ needed to fix display of reversed glyph rows that are almost as
+ wide as the window, because append_space_for_newline already added
+ one space glyph.
+
+2020-11-14 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid crashes when a reversed glyph row starts with a composition
+
+ * src/dispnew.c (build_frame_matrix_from_leaf_window): Add an
+ assertion to prevent us from overwriting non-char glyphs with the
+ vertical border glyph.
+ * src/xdisp.c (extend_face_to_end_of_line): Account for one glyph
+ possibly inserted by append_space_for_newline. (Bug#44506)
+ Remove a kludgey correction for an off-by-one error in column
+ counting, which is no longer needed.
+
+2020-11-14 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Save instantiated gnus-search engines in an alist
+
+ So we aren't re-instantiating (and potentially configuring) them with
+ every search.
+
+ * lisp/gnus/gnus-search.el (gnus-search-engine-instance-alist): New
+ variable holding server->engine mapping.
+ (gnus-search-server-to-engine): See if we've already instantiated this
+ server. If so, return it. If not, instantiate it and save in the above
+ variable.
+ (gnus-search-shutdown): Shutdown function clearing the above alist.
+
+2020-11-14 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Make sure Gnus search groups search topics recursively
+
+ * lisp/gnus/gnus-group.el (gnus-group-make-search-group,
+ gnus-group-read-ephemeral-search-group): If a search is initiated from
+ a topic line, make sure we get all the groups under that topic (and
+ under sub-topics).
+
+2020-11-13 Mattias Engdegård <mattiase@acm.org>
+
+ Simplify quick-check composition regexps
+
+ * lisp/international/ucs-normalize.el
+ (quick-check-composition-list-to-regexp): Don't add an explicit
+ pattern for U+1161..U+1175 and U+11a8..U+11c2 since these are already
+ part of `combining-chars'.
+
+2020-11-13 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ a3d316bbb7 (origin/emacs-27) Update information about refcards
+ f43e9ad524 Avoid crashes in the daemon due to user interaction
+
+2020-11-13 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ ac1a2b2160 Add more doc-view requirements
+ 109eb1e7e2 Fix undefined behavior when fetching glyphs from the displ...
+
+ # Conflicts:
+ # lisp/doc-view.el
+
+2020-11-13 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 75384bd155 Update the doc-view header line
+ 13ab70c80e Avoid breaking Arabic shaping in 'window-text-pixel-size'
+ e693d97e50 doc-view.el comment clarification
+ 968e85a2ce Update erc documentation about C-c C-b
+
+2020-11-13 Alan Third <alan@idiocy.org>
+
+ Fix error with fn key in NS port (bug#44533)
+
+ * src/nsterm.m ([EmacsView keyDown:]): Move the correction for fn key
+ handling to before the modifiers are calculated.
+
+2020-11-13 Michael Albinus <michael.albinus@gmx.de>
+
+ Some minor Tramp fixes, resulting from test campaign
+
+ * lisp/net/tramp.el (tramp-handle-write-region):
+ * lisp/net/tramp-adb.el (tramp-adb-handle-write-region):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-write-region):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-write-region): Use `current-time'
+ if needed.
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-gio-mapping):
+ (tramp-gvfs-do-copy-or-rename-file): Remove "gvfs-rename", it is
+ not trustworthy.
+
+ * test/lisp/net/tramp-tests.el (tramp-test07-file-exists-p): Check also for
+ symlinked files in trash.
+ (tramp-test20-file-modes): Revert last change, it was a thinko.
+
+2020-11-13 Eli Zaretskii <eliz@gnu.org>
+
+ Update information about refcards
+
+ * admin/release-process (refcards):
+ * admin/make-tarball.txt (refcards): Update information about
+ generating refcards and required TeX/LaTeX packages.
+
+2020-11-12 Andrea Corallo <akrl@sdf.org>
+
+ Add copy insn testcase
+
+ * test/src/comp-tests.el (copy-insn): New testcase.
+ * test/src/comp-test-funcs.el (comp-test-copy-insn-f): New
+ function.
+
+2020-11-12 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-mvar-value-vld-p): Fix logic.
+
+2020-11-12 Andrea Corallo <akrl@sdf.org>
+
+ Memoize `comp-common-supertype'
+
+ * lisp/emacs-lisp/comp.el (comp-ctxt): Add `common-supertype-mem'
+ slot.
+ (comp-common-supertype): Memoize.
+
+2020-11-12 Andrea Corallo <akrl@sdf.org>
+
+ Add few more type specifier tests
+
+ * test/src/comp-tests.el (comp-tests-type-spec-tests): Add three
+ tests and uncomment one.
+
+2020-11-12 Andrea Corallo <akrl@sdf.org>
+
+ Rework `comp-ret-type-spec' in terms of `comp-phi'
+
+ * lisp/emacs-lisp/comp.el (comp-ret-type-spec): Use `comp-func'
+ not to duplicate logic plus add null type specifier support and
+ some comments.
+
+2020-11-12 Andrea Corallo <akrl@sdf.org>
+
+ Move phi function code into dedicated function and improve it
+
+ * lisp/emacs-lisp/comp.el (comp-phi): New function moving logic
+ from `comp-fwprop-insn'.
+
+2020-11-12 Stefan Kangas <stefan@marxist.se>
+
+ Don't quote lambdas in several places
+
+ * lisp/allout-widgets.el (allout-widgets-adjusting-message)
+ (allout-widgets-exposure-change-processor)
+ (allout-widgets-count-buttons-in-region):
+ * lisp/ansi-color.el (ansi-color-make-color-map):
+ * lisp/case-table.el (describe-buffer-case-table):
+ * lisp/emacs-lisp/byte-opt.el (byte-decompile-bytecode-1):
+ * lisp/gnus/gnus-agent.el (gnus-agent-regenerate-group):
+ * lisp/gnus/nnir.el (nnir-run-swish++, nnir-run-swish-e)
+ (nnir-run-hyrex, nnir-run-namazu):
+ * lisp/hippie-exp.el (make-hippie-expand-function)
+ (try-complete-lisp-symbol, try-complete-lisp-symbol-partially)
+ (try-expand-all-abbrevs):
+ * lisp/international/mule-cmds.el (sort-coding-systems)
+ (select-safe-coding-system, select-message-coding-system)
+ (read-language-name, encoded-string-description):
+ * lisp/international/quail.el (quail-keyseq-translate)
+ (quail-get-translations, quail-build-decode-map)
+ (quail-insert-decode-map):
+ * lisp/jka-compr.el (jka-compr-uninstall):
+ * lisp/locate.el (locate-in-alternate-database):
+ * lisp/mail/mailabbrev.el (mail-resolve-all-aliases-1)
+ (mail-abbrev-make-syntax-table):
+ * lisp/mh-e/mh-seq.el (mh-read-folder-sequences):
+ * lisp/net/eudcb-ldap.el (eudc-ldap-simple-query-internal):
+ * lisp/progmodes/make-mode.el (makefile-query-targets)
+ (makefile-prompt-for-gmake-funargs):
+ * lisp/shadowfile.el (shadow-cancel, shadow-shadows-of):
+ * lisp/sort.el (sort-pages, sort-fields, sort-regexp-fields):
+ * lisp/subr.el (listify-key-sequence):
+ * lisp/term/wyse50.el (terminal-init-wyse50):
+ * lisp/textmodes/ispell.el (ispell-help)
+ (ispell-begin-tex-skip-regexp):
+ * lisp/textmodes/page-ext.el (pages-sort-region):
+ * lisp/textmodes/refer.el (refer-find-entry-in-file):
+ * lisp/url/url-expand.el (url-expand-file-name): Don't quote lambdas.
+
+2020-11-12 Juri Linkov <juri@linkov.net>
+
+ Add help-char to the cache key in read-char-from-minibuffer as well
+
+ It's highly unlikely that help-char will be changed from its default value 8,
+ but formally there is a dependence on help-char.
+
+2020-11-12 Robert Pluim <rpluim@gmail.com>
+
+ Emit required version when Harfbuzz is not found but Cairo is
+
+ * configure.ac: Define harfbuzz_required_ver with required
+ harfbuzz version, and put it in the warning message emitted when
+ Cairo is found but not HarfBuzz.
+
+2020-11-12 Mattias Engdegård <mattiase@acm.org>
+
+ vhdl-mode: remove minor obstacle to static checking
+
+ * lisp/progmodes/vhdl-mode.el (vhdl-directive-keywords-regexp):
+ Remove unnecessary global variable.
+ (vhdl-words-init): Remove assignment.
+ (vhdl-font-lock-init): Inline expression. Use regexp-opt.
+
+2020-11-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove mention of `edebug-on-signal' from a doc string
+
+ * lisp/emacs-lisp/edebug.el (edebug-mode): Don't mention
+ non-existent user option (bug#44577).
+
+2020-11-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify project-find-file doc string
+
+ * lisp/progmodes/project.el (project-find-file): Don't say
+ anything about recognizing file names, as that may lead the user
+ to think that it'll check whether the string at point is an
+ existing file (bug#44588).
+
+2020-11-12 Juri Linkov <juri@linkov.net>
+
+ Add help-form to the cache key in read-char-from-minibuffer
+
+2020-11-12 Stefan Kangas <stefan@marxist.se>
+
+ * test/lisp/help-fns-tests.el: Silence byte-compiler.
+
+ * test/lisp/hfy-cmap-resources/rgb.txt: Add comment line.
+
+2020-11-12 Stefan Kangas <stefan@marxist.se>
+
+ Remove redundant installation instructions
+
+ * lisp/net/newsticker.el:
+ * lisp/net/sieve-mode.el:
+ * lisp/play/bubbles.el:
+ * lisp/play/handwrite.el:
+ * lisp/progmodes/python.el:
+ * lisp/progmodes/ruby-mode.el:
+ * lisp/whitespace.el: Remove redundant installation instructions.
+ These packages are distributed with Emacs and/or GNU ELPA.
+ * lisp/calendar/timeclock.el:
+ * lisp/ehelp.el:
+ * lisp/emacs-lisp/checkdoc.el:
+ * lisp/filesets.el:
+ * lisp/mail/reporter.el:
+ * lisp/net/rfc2104.el:
+ * lisp/net/webjump.el:
+ * lisp/pixel-scroll.el: Remove redundant recommendation to call
+ require before using autoloaded functions.
+ * lisp/tar-mode.el: Remove reference to package uncompress, removed in
+ Emacs 23.
+
+2020-11-12 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/progmodes/ruby-mode.el (auto-mode-alist): Add Brewfile.
+
+2020-11-12 Stefan Kangas <stefan@marxist.se>
+
+ Fix mistake in describe-buffer-bindings
+
+ * src/keymap.c (Fdescribe_buffer_bindings): Fix a call in
+ describe-buffer-bindings. This fixes a mistake in my previous commit
+ to prefer the Lisp version of describe-map-tree (8a1441310aa1), where
+ 0 was accidentally converted to Qt in two places.
+
+2020-11-12 Juri Linkov <juri@linkov.net>
+
+ Use cache with help-char in read-char-from-minibuffer unless help-form is nil
+
+2020-11-12 Andrea Corallo <akrl@sdf.org>
+
+ Nativecomp testsuite rework for derived return type specifiers
+
+ As we have derived return type specifiers as some test for them. Also
+ rewrite some propagation related test using return type specifiers too
+ as it's way more convenient.
+
+ * test/src/comp-tests.el (fw-prop-1): Nit rename.
+ (comp-tests-check-ret-type-spec): New function.
+ (comp-tests-type-spec-tests): New variable.
+ (comp-tests-cond-rw-0-var) Remove variable.
+ (cond-rw-0, cond-rw-1, cond-rw-2, cond-rw-3, cond-rw-4, cond-rw-5)
+ Remove tests as now covered by `comp-tests-check-ret-type-spec'.
+
+2020-11-12 Andrea Corallo <akrl@sdf.org>
+
+ Add nativecomp derived return type specifier computation support
+
+ * lisp/emacs-lisp/comp.el (comp-post-pass-hooks): Nit.
+ (comp-func): Add `ret-type-specifier' slot.
+ (comp-ret-type-spec): New function.
+ (comp-final): Call `comp-ret-type-spec'.
+
+2020-11-12 Andrea Corallo <akrl@sdf.org>
+
+ Unline some functions to optimize bootstrap time
+
+ * lisp/emacs-lisp/comp.el (comp-mvar-value-vld-p)
+ (comp-mvar-value, comp-mvar-fixnum-p, comp-set-op-p)
+ (comp-assign-op-p, comp-call-op-p, comp-type-hint-p)
+ (comp-func-ret-typeset, comp-function-pure-p)
+ (comp-alloc-class-to-container, comp-lex-byte-func-p)
+ (comp-lap-eob-p, comp-lap-fall-through-p, comp-emit)
+ (comp-emit-set-call, comp-mvar-propagate)
+ (comp-function-foldable-p, comp-function-call-maybe-fold)
+ (comp-trampoline-filename): Uninline functions.
+
+2020-11-12 Andrea Corallo <akrl@sdf.org>
+
+ Add to elisp-mode `emacs-lisp-native-compile-and-load'
+
+ * lisp/progmodes/elisp-mode.el
+ (emacs-lisp--before-compile-buffer): New function.
+ (emacs-lisp-byte-compile-and-load): Use the previous.
+ (emacs-lisp-native-compile-and-load): New function.
+
+2020-11-12 Andrea Corallo <akrl@sdf.org>
+
+ Fix limple-mode for new type and range limple semantic
+
+ * lisp/emacs-lisp/comp.el (comp-limple-branches, comp-limple-ops):
+ New variables.
+ (comp-limple-lock-keywords): Update value.
+
+2020-11-12 Andrea Corallo <akrl@sdf.org>
+
+ Add a nativecomp testcase
+
+ Having this while re-debugging the bootstrap would have saved few hours
+ of debug so let's add it.
+
+ * test/src/comp-tests.el (and-3): Add test.
+ * test/src/comp-test-funcs.el (comp-test-and-3-var): New var.
+ (comp-test-and-3-f): New function.
+
+2020-11-12 Andrea Corallo <akrl@sdf.org>
+
+ Add initial nativecomp typeset and range propagation support
+
+ This commit add an initial support for a better type propagation and
+ integer range propagation.
+
+ Each mvar can be now characterized by a set of types, a set of values
+ and an integral range.
+
+ * lisp/emacs-lisp/comp.el (comp-known-ret-types): Store into
+ typeset and remove fixnum.
+ (comp-known-ret-ranges, comp-type-predicates): New variables.
+ (comp-ctxt): Remove supertype-memoize slot and add
+ union-typesets-mem.
+ (comp-mvar): Remove const-vld, constant, type slots. Add typeset,
+ valset, range slots.
+ (comp-mvar-value-vld-p, comp-mvar-value, comp-mvar-fixnum-p)
+ (comp-mvar-symbol-p, comp-mvar-cons-p)
+ (comp-mvar-type-hint-match-p, comp-func-ret-typeset)
+ (comp-func-ret-range): New functions.
+ (make-comp-mvar, make-comp-ssa-mvar): Update logic.
+ (comp--typeof-types): New variable.
+ (comp-supertypes, comp-common-supertype): Logic update.
+ (comp-subtype-p, comp-union-typesets, comp-range-1+)
+ (comp-range-1-, comp-range-<, comp-range-union)
+ (comp-range-intersection): New functions.
+ (comp-fwprop-prologue, comp-mvar-propagate)
+ (comp-function-foldable-p, comp-function-call-maybe-fold)
+ (comp-fwprop-insn, comp-call-optim-func, comp-finalize-relocs):
+ Logic update.
+
+ * src/comp.c (emit_mvar_rval, emit_call_with_type_hint)
+ (emit_call2_with_type_hint): Logic update.
+
+ * lisp/emacs-lisp/cl-preloaded.el (cl--typeof-types): Undo the add
+ of fixnum and bignum as unnecessary.
+
+ * test/src/comp-tests.el
+ (comp-tests-mentioned-p-1, comp-tests-cond-rw-checker-val)
+ (comp-tests-cond-rw-checker-type, cond-rw-1, cond-rw-2)
+ (cond-rw-3, cond-rw-4, cond-rw-5): Update for new type interface.
+ (range-simple-union, range-simple-intersection): New integer range
+ tests.
+ (union-types): New union type test.
+
+2020-11-12 Andrea Corallo <akrl@sdf.org>
+
+ Rename two nativecomp functions
+
+ * lisp/emacs-lisp/comp.el (comp-function-foldable-p): Rename from
+ comp-function-optimizable-p.
+ (comp-function-call-maybe-fold): Same from
+ comp-function-call-maybe-fold.
+
+2020-11-11 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid crashes in the daemon due to user interaction
+
+ * src/minibuf.c (read_minibuf): Avoid crashes in the daemon if the
+ init file invokes some kind of minibuffer interaction, by not
+ updating the selected frame if it's the initial frame.
+ (Bug#44583)
+
+2020-11-11 Juri Linkov <juri@linkov.net>
+
+ In dired-query use read-char-from-minibuffer with bound help-char (bug#42708)
+
+ * lisp/dired-aux.el (dired-query): Replace read-char-choice call
+ with read-char-from-minibuffer.
+
+ * lisp/subr.el (read-char-choice): Restore the previous version
+ that uses read-key.
+ (read-char-from-minibuffer): Bind help-char to help-form-show
+ when help-form is non-nil.
+
+2020-11-11 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Remove unused "internal" gnus-search variables
+
+ * lisp/gnus/gnus-search.el (gnus-search-memo-query,
+ gnus-search-memo-server): No longer needed.
+
+2020-11-11 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Fix defgeneric name of gnus-search-index(ed)-extract
+
+ * lisp/gnus/gnus-search.el (gnus-search-indexed-extract): Had the
+ wrong name on the generic.
+
+2020-11-11 Michael Albinus <michael.albinus@gmx.de>
+
+ Some minor changes to Tramp, do not merge with master
+
+ * lisp/net/tramp.el (tramp-handle-directory-files)
+ (tramp-handle-directory-files-and-attributes):
+ * lisp/net/tramp-adb.el
+ (tramp-adb-handle-directory-files-and-attributes):
+ * lisp/net/tramp-rclone.el (tramp-rclone-handle-directory-files):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-directory-files-and-attributes):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-directory-files): Add _COUNT.
+ Make the functions forward compatible.
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-enabled):
+ Increase `max-specpdl-size' temporarily.
+
+ * test/lisp/net/tramp-tests.el (tramp--test-share-p): New defun.
+ (tramp-test05-expand-file-name-relative): Use it.
+
+2020-11-11 Dario Gjorgjevski <dario.gjorgjevski@gmail.com>
+
+ Fix python-font-lock-keywords-maximum-decoration performance regression
+
+ * lisp/progmodes/python.el
+ (python-font-lock-keywords-maximum-decoration): `symbol-name'
+ should not be quantified by a `+' as it is redundant and performs
+ very badly (bug#44572).
+
+2020-11-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove mention of global-cedet-m3-minor-mode
+
+ * lisp/cedet/semantic.el (semantic-submode-list):
+ (semantic-default-submodes): Remove mention of
+ global-cedet-m3-minor-mode, which no longer exists, apparently
+ (bug#44565).
+
+2020-11-11 Dario Gjorgjevski <dario.gjorgjevski@gmail.com>
+
+ Fix font lock of assignments with type hints in Python
+
+ * lisp/progmodes/python.el
+ (python-font-lock-keywords-maximum-decoration): Fix regular
+ expressions for font lock of assignments with type hints (bug#44568).
+
+ The font lock of assignments with type hints in Python is rather bad.
+ Consider the following example:
+
+ from typing import Mapping, Tuple, Sequence
+ var1: int = 5
+ var2: Mapping[int, int] = {10: 1024}
+ var3: Mapping[Tuple[int, int], int] = {(2, 5): 32}
+ var4: Sequence[Sequence[int]] = [[1], [1, 2], [1, 2, 3]]
+ var5: Sequence[Mapping[str, Sequence[str]]] = [
+ {
+ 'red': ['scarlet', 'vermilion', 'ruby'],
+ 'green': ['emerald green', 'aqua']
+ },
+ {
+ 'sword': ['cutlass', 'rapier']
+ }
+ ]
+
+ As things stand right now, only ‘var1’ would be highlighted. To make
+ things worse, the ‘Mapping’ type hint of ‘var2’ would also be
+ highlighted, which is entirely incorrect.
+
+ This commit makes all of ‘var1’ through ‘var5’ be highlighted
+ correctly.
+
+2020-11-11 Harald Jörg <haj@posteo.de>
+
+ Cleanup of the test file for cperl-mode
+
+ * test/lisp/progmodes/cperl-mode-tests.el
+ (cperl--run-test-cases): New macro, factored out from various
+ indentation / rewriting tests. Contains documentation of the
+ format used by the cperl-mode-resources files.
+ (cperl-test-bug-19709): Replace 'next-line' by 'forward-line'.
+ (cperl-test-indent-exp),
+ (cperl-test-indent-styles),
+ (cperl-test-bug-30393): Use the new macro.
+ (cperl-test-bug-19709): Make fit for Emacs 26.
+ (cperl-test-indent-styles): Skip for Perl mode (bug#44561).
+
+2020-11-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/server.el: Refactor frame creation functions
+
+ (server--create-frame): New function, extracted from
+ `server-create-dumb-terminal-frame`.
+ (server-create-window-system-frame, server-create-tty-frame):
+ (server-create-dumb-terminal-frame): Use it.
+
+2020-11-11 Eliza Velasquez <exv@google.com>
+
+ * lisp/server.el: Fix frame creation on dumb terminals (bug#25547)
+
+ (server-create-dumb-terminal-frame): New function.
+ (server-process-filter): Use it.
+ (server-delete-client): Don't delete tty terminal when it's not
+ exclusive to this client.
+
+2020-11-10 Juri Linkov <juri@linkov.net>
+
+ Don't set file name variable in org-element-parse-secondary-string (bug#44524)
+
+ * lisp/org/org-element.el (org-element-parse-secondary-string):
+ Don't set buffer-local variables buffer-file-name and buffer-file-truename
+ in temporary buffer.
+
+2020-11-10 Juri Linkov <juri@linkov.net>
+
+ * lisp/leim/quail/compose.el ("iso-transl"): New input method.
+
+ * doc/emacs/basic.texi (Inserting Text):
+ Mention transient input method "iso-transl".
+
+ * lisp/leim/quail/latin-ltx.el: Use same Keywords as in other quail files.
+
+2020-11-10 Eli Zaretskii <eliz@gnu.org>
+
+ New debugging command 'malloc-info'
+
+ * src/alloc.c (Fmalloc_info) [GNU_LINUX]: New command.
+ (syms_of_alloc): Defsubr it. (Bug#43389)
+
+2020-11-10 Dmitry Gutov <dgutov@yandex.ru>
+
+ Clear the vc-state cache when returning nil
+
+ * lisp/vc/vc-hg.el (vc-hg-registered):
+ Clear the vc-state cache when returning nil.
+
+2020-11-10 Tom Fitzhenry <tomfitzhenry@google.com>
+
+ Remove extra process call from vc-hg-registered
+
+ Prefer vc-state to benefit from its caching (bug#44534)
+
+ This same technique is used in vc-git.el,
+ per commit 2018-06-28 "Remove extra process call from vc-git-find-file-hook"
+ 93c41ce6aa64b14fc9bd7bdd0d909915a79191cd.
+
+ * lisp/vc/vc-hg.el (vc-hg-registered): Use vc-state rather than vc-hg-state.
+
+2020-11-10 Eli Zaretskii <eliz@gnu.org>
+
+ Fix a recent change in image.c for MS-Windows
+
+ * src/image.c: Fix DEF_DLL_FN of
+ rsvg_handle_get_intrinsic_dimensions. Reported by Andy Moreton
+ <andrewjmoreton@gmail.com>.
+
+2020-11-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add more doc-view requirements
+
+ * lisp/doc-view.el: Add more requirements.
+
+2020-11-10 Steven Allen <steven@stebalien.com>
+
+ Only use nbutlast when we actually want to modify the original list
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-dbus-byte-array-to-string):
+ Don't modify the byte array.
+ * lisp/net/tramp-integration.el (tramp-eshell-directory-change):
+ Don't modify the underlying exec-path.
+
+2020-11-10 Andrew G Cohen <cohen@andy.bu.edu>
+
+ Remove ephemeral group on error or null result
+
+ * lisp/gnus/nnselect.el (nnselect-request-group): If an ephemeral
+ group is empty, there is nothing to see, so remove the group.
+ (nnselect-run): Catch and return an empty artlist on error.
+
+2020-11-09 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: fix many compiler warnings which would appear with lexical binding
+
+ * lisp/progmodes/cc-align.el (three places) prefix langelem with a _.
+
+ * lisp/progmodes/cc-cmds.el:
+ * lisp/progmodes/cc-engine.el: Remove superfluous local variables.
+
+ * lisp/progmodes/cc-defs.el (c-will-be-unescaped): Remove unused parameter
+ end.
+ * lisp/progmodes/cc-engine.el (c-looking-at-decl-block): Remove unused
+ parameter containing-sexp.
+ (c-looking-at-special-brace-list); Remove unused parameter lim.
+ (c-add-class-syntax): Remove unused parameter paren-state.
+
+2020-11-09 Philipp Stephani <phst@google.com>
+
+ Fix undefined behavior when fetching glyphs from the display vector.
+
+ You can trigger this rather obscure bug by enabling selective display
+ if the second glyph in its display vector has an invalid face. For
+ example, evaluate
+
+ (set-display-table-slot standard-display-table
+ 'selective-display [?A (?B . invalid)])
+
+ and then enable selective display.
+
+ * src/xdisp.c (next_element_from_display_vector): Check whether next
+ glyph code is valid before accessing it.
+
+2020-11-09 Stefan Kangas <stefan@marxist.se>
+
+ Add test for substitute-command-keys with command remap
+
+ * test/lisp/help-tests.el (help-tests-remap-map): New variable.
+ (help-tests-substitute-command-keys/remap): New test.
+ (help-tests-substitute-command-keys/keymaps)
+ (help-tests-substitute-command-keys/undefined-map): Fix indentation.
+
+2020-11-09 Brian Leung <leungbk@mailfence.com> (tiny change)
+
+ shortdoc: prefer seq-contains-p over seq-contains
+
+ * lisp/emacs-lisp/shortdoc.el (sequence): use seq-contains-p instead
+ of seq-contains, which is obsolete as of 27.1. (Bug#44536)
+
+2020-11-09 Stefan Kangas <stefan@marxist.se>
+
+ Simplify getting value of text-quoting-style (Bug#44471)
+
+ * src/doc.c (text_quoting_style): Remove function by merging it...
+ (Ftext_quoting_style): ...here. Rename from Fget_quoting_style.
+ (syms_of_doc): Update defsubr for Ftext_quoting_style.
+ * src/lisp.h (enum text_quoting_style): Remove enum.
+ * src/doprnt.c (doprnt):
+ * src/editfns.c (styled_format):
+ * lisp/help.el (substitute-command-keys): Update callers to use
+ text-quoting-style.
+
+2020-11-09 Philipp Stephani <phst@google.com>
+
+ * lisp/disp-table.el (make-glyph-code): Remove obsolete comment.
+
+2020-11-09 Mattias Engdegård <mattiase@acm.org>
+
+ Better warning suppression in rx-tests
+
+ * test/lisp/emacs-lisp/rx-tests.el (rx-compat): Use with-no-warnings
+ instead of with-suppressed-warnings which complains when running
+ the test interactively.
+
+2020-11-09 Mattias Engdegård <mattiase@acm.org>
+
+ Fix pcase rx form snag with '?' and '??' (bug#44532)
+
+ This is a regression from Emacs 26.
+ Reported by Phillip Stephani.
+
+ * lisp/emacs-lisp/rx.el (rx--pcase-transform): Process ? and ?? correctly.
+ * test/lisp/emacs-lisp/rx-tests.el (rx-pcase): Add test case.
+
+2020-11-09 Alan Third <alan@idiocy.org>
+
+ Fix css length calculations
+
+ * src/image.c (svg_css_length_to_pixels): Put in missing breaks where
+ necessary.
+
+2020-11-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the SHOW parameter work again in `run-python'
+
+ * lisp/progmodes/python.el (run-python): Make the SHOW parameter
+ work again after the fix for 31398 (bug#44421).
+
+2020-11-09 Protesilaos Stavrou <info@protesilaos.com>
+
+ Use a separate face for expanded log-view bodies
+
+ * lisp/vc/log-view.el (log-view-commit-body): Define new face.
+ (log-view-toggle-entry-display): Implement 'log-view-commit-body'
+ face (bug#44424).
+
+2020-11-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify Lisp warning about elements following other expressions
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-fdefs): Clarify warning in
+ help text (bug#44482).
+
+2020-11-09 Eli Zaretskii <eliz@gnu.org>
+
+ Fix compilation of image.c on MS-Windows
+
+ This is a followup to last change in image.c.
+ * src/image.c (rsvg_handle_get_intrinsic_dimensions): Define to
+ call fn_rsvg_handle_get_intrinsic_dimensions.
+ (svg_css_length_to_pixels): Compile only for librsvg >= 2.46.0, as
+ RsvgLength type was not defined before.
+
+2020-11-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Update the doc-view header line
+
+2020-11-09 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid breaking Arabic shaping in 'window-text-pixel-size'
+
+ * src/xdisp.c (CHAR_COMPOSED_P): If the bidi_p flag is not set,
+ pass -1 to composition_reseat_it, so that the shaping engine will
+ figure out the directionality of the text. This is important,
+ e.g., when using move_it_* functions in some context that is not
+ redisplay, such as 'window-text-pixel-size'. (Bug#44521)
+
+2020-11-09 Alan Third <alan@idiocy.org>
+
+ Fix crash in ns_mouse_position (bug#44313)
+
+ * src/nsterm.m (ns_destroy_window): Close the window before freeing
+ the frame resources so we don't end up accessing the frame struct
+ after it's been freed.
+
+2020-11-09 Andrii Kolomoiets <andreyk.mad@gmail.com>
+
+ NS: Make s-<left/right> to move to beginning/end of line
+
+ * lisp/term/ns-win.el: Bind 's-<left>' to 'move-beginning-of-line';
+ bind 's-<right>' to 'move-end-of-line'.
+ * etc/NEWS: Mention new bindings.
+
+2020-11-09 Alan Third <alan@idiocy.org>
+
+ Calculate SVG image sizes more accurately (bug#44206)
+
+ * src/image.c (svg_css_length_to_pixels): New function.
+ (svg_load_image): Try more methods to work out the image size.
+
+2020-11-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ doc-view.el comment clarification
+
+ * lisp/doc-view.el: Make the commentary mention that it's not
+ limited to a narrow range of file formats (bug#44504).
+
+2020-11-09 Daniel Martín <mardani29@yahoo.es>
+
+ Update erc documentation about C-c C-b
+
+ * doc/misc/erc.texi (Keystroke Summary): C-c C-b runs
+ erc-switch-to-buffer, which is implemented in terms of
+ read-buffer (bug#44498).
+
+2020-11-09 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Indentation of ')' follows customisation
+
+ * lisp/progmodes/cperl-mode.el (cperl-style-alist): Add
+ cperl-close-paren-offset to the settings for PBP style.
+
+ * test/lisp/progmodes/cperl-mode-tests.el (cperl-bug19709):
+ New test to verify correct indentation of closing parentheses (Bug#19709).
+
+ * test/lisp/progmodes/cperl-mode-resources/cperl-bug-19709.pl:
+ New test case with code from the bug report.
+
+ * test/lisp/progmodes/cperl-mode-resources/cperl-indent-styles.pl:
+ Add a new test clause for cperl-close-paren-offset.
+
+2020-11-09 Akira Kyle <akira@akirakyle.com> (tiny change)
+
+ Fix xwidget's webkitgtk widget overriding of Emacs SIGCHLD handler
+
+ * src/xwidget.c (make-xwidget): Save and restore Emacs SIGCHLD signal
+ handler since glib doesn't (but should) do this.
+
+2020-11-09 Stefan Kangas <stefan@marxist.se>
+
+ Remove test for return value of set-keymap-parent
+
+ * test/src/keymap-tests.el
+ (keymap-keymap-set-parent/returns-parent): Remove test for the return
+ value of set-keymap-parent. It is not clear that returning the value
+ is a very good idea.
+ Problem pointed out by Stefan Monnier <monnier@iro.umontreal.ca>.
+
+2020-11-09 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Add more protections to gnus-search query parsing
+
+ * lisp/gnus/gnus-group.el (gnus-group-make-search-group,
+ gnus-group-read-ephemeral-search-group): If the query is coming in via
+ the old 'nnir-query-spec key, we know not to parse it.
+ * lisp/gnus/gnus-search.el (gnus-search-make-query-string): Check if
+ the query was sent in as '(query "query"), and not '(query . "query).
+ (gnus-search-imap-search-keys): Add x-gm-raw to imap search keys.
+ (gnus-search-prepare-query): If we know this query should be raw,
+ don't even try parsing it, as it probably won't work.
+
+2020-11-08 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-fwprop-insn): Fix phi function.
+
+2020-11-08 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/project.el: Don't truncate the saved project list.
+
+ * lisp/progmodes/project.el (project--write-project-list):
+ Let-bind print-length and print-level to nil to not truncate the
+ saved project list with unreadable ellipsis.
+
+2020-11-08 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Another backwards-compatibility fix for gnus-search
+
+ * lisp/gnus/gnus-search.el (gnus-search-server-to-engine): Because of
+ the way we've set up the obsolete variable alias for
+ `nnir-method-default-engines', we may end up with its value in
+ `gnus-search-default-engines'. Make the check for "old style" values
+ general, so we catch them no matter where they came from.
+
+2020-11-08 Alan Mackenzie <acm@muc.de>
+
+ Don't set the selected window to the miniwindow on a frame change.
+
+ Intended to fix bug #44502.
+
+ * src/minibuf.c (move_minibuffer_onto_frame): Remove the lines of code which
+ set the selected window to the minibuffer.
+
+2020-11-08 Dmitry Gutov <dgutov@yandex.ru>
+
+ Doc fix
+
+ * lisp/vc/vc.el (vc-deduce-fileset): Doc fix (bug#44420).
+
+2020-11-08 Dmitry Gutov <dgutov@yandex.ru>
+
+ Mention which exact file is already registered
+
+ * lisp/vc/vc.el (vc-register):
+ Mention which exact file is already registered (bug#44420).
+
+2020-11-07 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-common-supertype-2): Fix null intersection
+
+2020-11-07 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ f5d7fb3a2d (origin/emacs-27) Fix 'uudecode-decode-region-internal' in...
+ d4242177da Fix 'send-string-to-terminal' writing very long strings
+ 9da0f4026c * lisp/subr.el (read-char-from-minibuffer): Doc fix. (Bug...
+ 9899f74e4e Merge branch 'emacs-27' of git.savannah.gnu.org:/srv/git/e...
+ a6fcba783e Fix documentation of 'windmove-swap-states-default-keybind...
+ f4acd7a924 Split windows evenly when 'min-margins' parameter was set ...
+
+2020-11-07 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 53933cdf5c ; * lisp/international/mule.el (define-coding-system): Doc...
+ e90ffcf759 * src/w32fns.c (Fw32_register_hot_key): Doc fix. (Bug#44456)
+ 89740e9cb5 Prevent redisplay from moving point behind user's back
+ 5932df7435 Document that the :match function for a widget takes an ex...
+ 1b7ab9d0ac Don't render XML declaration of an HTML document (bug#44348)
+
+ # Conflicts:
+ # lisp/international/mule.el
+
+2020-11-07 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Various fixes and backward compatibility for gnus-search
+
+ * lisp/gnus/gnus-group.el (gnus-group-make-search-group,
+ gnus-group-read-ephemeral-search-group): Check for and accept the old
+ nnir-* spec keys.
+ * lisp/gnus/gnus-search.el (shared-initialize): Use
+ generate-new-buffer instead of doing it ourselves.
+ (gnus-search-server-to-engine): Raise an informative error explicitly
+ if we can't find a search engine, rather than letting it fall through
+ to something less helpful.
+ (gnus-search-make-spec): Add `gnus-search--complete-key-data' to
+ `completion-at-point-functions' locally, not globally.
+
+2020-11-07 Andrea Corallo <akrl@sdf.org>
+
+ Allow for manually bumbing new native compiler ABI versions
+
+ * src/comp.c (ABI_VERSION): Define macro.
+ (hash_native_abi): Include ABI_VERSION in the hashing.
+ (syms_of_comp): Tweak docstring.
+
+2020-11-07 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-11-07 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/lisp-mode.el: Avoid false-positive "hidden arg" in strings
+
+ (lisp--match-hidden-arg): Don't misfire in strings and comments.
+
+ Reported by: Andrii Kolomoiets <andreyk.mad@gmail.com>
+
+2020-11-07 Mauro Aranda <maurooaranda@gmail.com>
+
+ Add test for recent change in enable-theme
+
+ * test/lisp/custom-tests.el (custom-test-enable-theme-keeps-settings):
+ Enabling a theme should not change the theme settings, so test for
+ that. See
+ https://lists.gnu.org/archive/html/emacs-devel/2020-11/msg00232.html
+
+2020-11-07 Andrea Corallo <akrl@sdf.org>
+
+ Fix non native compiled build
+
+ * lisp/emacs-lisp/advice.el (ad-add-advice): Do not try to
+ install trampolines in vanilla builds.
+
+2020-11-07 Andrea Corallo <akrl@sdf.org>
+
+ Allow for native compilation qualities to be specified per input file
+
+ * lisp/emacs-lisp/bytecomp.el (byte-native-qualities): Define
+ variable.
+ (byte-compile-from-buffer): Spill compilation qualities.
+ * lisp/emacs-lisp/comp.el (comp-speed, comp-debug): Make
+ them file local variables.
+ (comp-ctxt): Add `speed' and `debug' slots.
+ (comp-spill-speed, comp-spill-lap-function): Make use of these.
+ (comp-spill-lap-function): Spill qualities from
+ `byte-native-qualities'.
+ (comp-limplify-top-level): Do not use `comp-speed' but ctxt value
+ unstead.
+ (comp-final): Do not propagate qualities as they are already
+ in the `comp-ctxt'.
+ (comp--native-compile): Close on `byte-native-qualities'.
+ * src/comp.c (comp_t): Add 'speed' and 'debug' fields.
+ (emit_comment, emit_mvar_rval, emit_static_object)
+ (emit_ctxt_code, Fcomp__init_ctxt): Use these instead of the
+ global variables.
+ (Fcomp__compile_ctxt_to_file): Set comp.speed and comp.debug and
+ use them.
+
+2020-11-07 Eli Zaretskii <eliz@gnu.org>
+
+ Don't leave lock files after 'replace-buffer-contents'
+
+ * src/editfns.c (Freplace_buffer_contents): Unlock the buffer's
+ file if no changes have been made. (Bug#44303)
+
+2020-11-07 Andrea Corallo <akrl@sdf.org>
+
+ Handle type hierarchy in native compiler forward propagation
+
+ * lisp/emacs-lisp/cl-preloaded.el (cl--typeof-types): Add fixnum
+ and bignum.
+ * lisp/emacs-lisp/comp.el (comp-ctxt): Add `supertype-memoize'
+ slot.
+ (comp-supertypes, comp-common-supertype-2)
+ (comp-common-supertype): New functions.
+ (comp-fwprop-insn): Make use of `comp-common-supertype' to
+ identify the common supertype to be propagated.
+
+2020-11-07 Kazuhiro Ito <kzhr@d1.dion.ne.jp> (tiny change)
+
+ Fix 'uudecode-decode-region-internal' in multibyte buffers
+
+ * lisp/mail/uudecode.el (uudecode-decode-region-internal): Fix
+ inserting the decoded string into a multibyte buffer. Optimize by
+ working with characters, not strings. (Bug#44411)
+
+2020-11-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'send-string-to-terminal' writing very long strings
+
+ * src/dispnew.c (Fsend_string_to_terminal): Prevent partial writes
+ by blocking SIGIO while 'fwrite' runs. (Bug#44320)
+
+2020-11-07 Eli Zaretskii <eliz@gnu.org>
+
+ * lisp/subr.el (read-char-from-minibuffer): Doc fix. (Bug#44451)
+
+2020-11-07 Earl Hyatt <ej32u@protonmail.com>
+
+ Fix documentation of 'windmove-swap-states-default-keybindings'
+
+ * doc/emacs/windows.texi (Window Convenience): Fix description of
+ 'windmove-swap-states-default-keybindings' and related index
+ entry. (Bug#44441)
+
+2020-11-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix scrolling problems with misc-fixed fonts under Cairo
+
+ * src/ftcrfont.c (ftcrfont_glyph_extents): Avoid rounding up the
+ glyph ascent to a higher value than needed due to floating-point
+ roundoff errors. (Bug#44284)
+
+2020-11-07 Martin Rudalics <rudalics@gmx.at>
+
+ Split windows evenly when 'min-margins' parameter was set (Bug#44483)
+
+ * lisp/window.el (split-window): Make new window inherit any
+ 'min-margins' parameter from WINDOW so that horizontal splits
+ reliably produce windows of same width (Bug#44483).
+
+2020-11-07 Stefan Kangas <stefan@marxist.se>
+
+ Delete outdated comment about C rewrite in apropos.el
+
+ Maybe it made sense to rewrite apropos.el in C for speed in 1991, but
+ today the speed increase would not outweigh the maintenance burden.
+
+ * lisp/apropos.el: Delete outdated comment.
+
+2020-11-07 Stefan Kangas <stefan@marxist.se>
+
+ Add some more tests for keymap.c
+
+ * test/src/keymap-tests.el (keymap-make-keymap)
+ (keymap-make-sparse-keymap, keymap-keymapp)
+ (keymap-keymap-parent, keymap-keymap-set-parent/returns-parent)
+ (keymap-copy-keymap/is-equal, keymap-copy-keymap/is-not-eq)
+ (keymap-lookup-key, keymap-apropos-internal)
+ (keymap-apropos-internal/predicate): New tests.
+ (keymap-tests--make-keymap-test): New defun.
+
+2020-11-06 Mattias Engdegård <mattiase@acm.org>
+
+ Rectify skip-set argument
+
+ * lisp/gnus/gnus-search.el (gnus-search-query-end-of-input):
+ Remove brackets that don't belong. Found by relint.
+
+2020-11-06 Mattias Engdegård <mattiase@acm.org>
+
+ Fix javac message parsing column number off-by-one
+
+ * lisp/progmodes/compile.el (compilation-error-regexp-alist-alist):
+ 'javac': Column numbers are 1-based by default; remove subtraction and
+ η-reduce. Translate regexp to rx (mechanised).
+ * test/lisp/progmodes/compile-tests.el (compile-tests--test-regexps-data):
+ Adapt 'javac' test cases to the change.
+
+2020-11-06 Glenn Morris <rgm@gnu.org>
+
+ Fix --enable-check-lisp-object-type build
+
+ * src/print.c (syms_of_print) <print-integers-as-characters>:
+ Fix type.
+
+2020-11-06 Mattias Engdegård <mattiase@acm.org>
+
+ Update gdb-mi-tests
+
+ * test/lisp/progmodes/gdb-mi-tests.el (gdb-mi-parse-value):
+ Make test pass after the change in gdb-mi-decode-strings default value.
+
+2020-11-06 Mattias Engdegård <mattiase@acm.org>
+
+ * lisp/gnus/gnus-search.el (gnus-search-contact-tables): Fix type.
+
+ A more precise type is desirable but at it is now correct ('list' is not).
+
+2020-11-06 Mattias Engdegård <mattiase@acm.org>
+
+ Change the default value of gdb-mi-decode-strings to t (bug#44173)
+
+ This is likely to be a more commonly wanted default value today.
+
+ * lisp/progmodes/gdb-mi.el (gdb-mi-decode-strings): Change default.
+ * doc/emacs/building.texi (Source Buffers): Update manual.
+ * etc/NEWS: Announce.
+
+2020-11-06 Mattias Engdegård <mattiase@acm.org>
+
+ Reduce integer-output-format to print-integers-as-characters
+
+ The variable now only controls whether characters are printed, not
+ the radix. Control chars are printed in human-readable syntax
+ only when special escapes such as ?\n are available. Spaces,
+ formatting and combining chars are excluded (bug#44155).
+ Done in collaboration with Juri Linkov.
+
+ * src/character.c (graphic_base_p):
+ * src/print.c (named_escape): New functions.
+ (print_object): Change semantics as described above.
+ (syms_of_print): Rename integer-output-format. Update doc string.
+ * doc/lispref/streams.texi (Output Variables):
+ * etc/NEWS:
+ * test/src/print-tests.el (print-integers-as-characters):
+ Rename and update according to new semantics. The test now passes.
+
+2020-11-06 Mauro Aranda <maurooaranda@gmail.com>
+
+ Go back to not using custom-push-theme when enabling a theme
+
+ * lisp/custom.el (enable-theme): Relying on custom-push-theme to
+ handle theme settings and prior user settings was a mistake. The
+ theme settings haven't changed between loading the theme and enabling
+ it, so we don't need all of what custom-push-theme does. However, we
+ still need to save a user setting outside of Customize, in order to be
+ able to get back to it, so do that in enable-theme itself.
+
+2020-11-06 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of a recent change
+
+ * doc/emacs/mule.texi (Select Input Method): Add an @anchor.
+ * doc/emacs/search.texi (Special Isearch): Add cross-reference and
+ improve wording.
+
+2020-11-06 Juri Linkov <juri@linkov.net>
+
+ Support transient input methods in Isearch mode (bug#44266)
+
+ * doc/emacs/mule.texi (Select Input Method): Rename
+ transient-input-method to activate-transient-input-method.
+
+ * doc/emacs/search.texi (Special Isearch):
+ Document isearch-transient-input-method.
+
+ * lisp/international/isearch-x.el (isearch-transient-input-method):
+ New function.
+ (isearch-process-search-multibyte-characters):
+ Call 'deactivate-transient-input-method' after 'read-string'.
+
+ * lisp/international/mule-cmds.el (mule-menu-keymap): Remove
+ duplicate menu item 'describe-input-method'. Add new menu item
+ 'activate-transient-input-method'.
+ (default-transient-input-method): Rename from transient-input-method.
+ (current-transient-input-method)
+ (previous-transient-input-method): New buffer-local variables.
+ (deactivate-input-method): Don't add
+ current-transient-input-method to input-method-history.
+ (toggle-input-method): Call deactivate-transient-input-method
+ when current-transient-input-method is non-nil.
+ (activate-transient-input-method): Rename from transient-input-method.
+ (deactivate-transient-input-method): New function with body from
+ renamed function transient-input-method.
+
+ * lisp/isearch.el (isearch-menu-bar-map): Add new menu item
+ 'isearch-transient-input-method'.
+ (isearch-mode-map): Bind 'C-x \' to isearch-transient-input-method.
+ (isearch-forward): Add isearch-transient-input-method to docstring.
+ (isearch-message-prefix): Use shorter string for narrowed buffer.
+
+2020-11-06 Stefan Kangas <stefan@marxist.se>
+
+ Add more tests for where-is-internal
+
+ * test/src/keymap-tests.el (keymap-where-is-internal)
+ (keymap-where-is-internal/firstonly-t)
+ (keymap-where-is-internal/menu-item)
+ (keymap-where-is-internal/advertised-binding)
+ (keymap-where-is-internal/advertised-binding-respect-remap)
+ (keymap-where-is-internal/remap)
+ (keymap-where-is-internal/shadowed): New tests.
+ (keymap-where-is-internal/preferred-modifier-is-a-string):
+ Rename from keymap-where-is-internal-test.
+
+2020-11-06 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Fixes and improvements to gnus-search
+
+ * lisp/gnus/gnus-search.el (gnus-search-default-engines): Change type
+ from a list of two-element lists, to alist. This matches nnir's old
+ option type, and should make transition easier.
+ (nnir-imap-default-search-key): Note that variable is obsolete.
+ (gnus-search-transform-expression): Interpret the "attachment" key as
+ "body" in imap searches. Allow specifying larger/smaller message size
+ values in KB or MB units.
+ (gnus-search-server-to-engine): Fix error in this function, and
+ clarify somewhat.
+
+2020-11-05 Katsumi Yamaoka <yamaoka@jpl.org>
+
+ * doc/misc/gnus.texi (Selection Groups): Delete excessive paren
+
+2020-11-05 Mauro Aranda <maurooaranda@gmail.com>
+
+ Enable/disable buttons, tool bar and menu items in Custom buffer (Bug#14398)
+
+ * lisp/cus-edit.el (custom-reset-extended-menu): Keymap menu for the
+ Revert... menu button.
+ (custom-reset-menu): Keep for backward compatibility, but default to
+ nil, so we prefer the keymap menu instead.
+ (custom-reset): Pass the new keymap menu to widget-choose.
+
+ (custom-commands): Add an element to each list item, to manage its
+ enable/disable state. Add docstring.
+ (custom-command-buttons): New variable, to hold the buttons that act
+ on all options in a Custom buffer.
+ (custom-buffer-create-internal): When creating the command buttons,
+ add the optional :notify function to enable/disable them. Add the
+ buttons to the new variable custom-command-buttons.
+ (customize-menu-create): Notify the command buttons after creating the
+ Custom buffer, so they are correctly enabled/disabled.
+ (custom-redraw-magic, custom-notify): Notify the command buttons and
+ update the tool bar when changing a widget to the modified state.
+
+2020-11-05 Andrea Corallo <akrl@sdf.org>
+
+ A native compiler forward propagation fix
+
+ * lisp/emacs-lisp/comp.el (comp-fwprop-insn): Fix `comp-mvar'
+ `const-vld' slot left unset while propagating in phis.
+
+2020-11-05 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix coding system in eww-display-pdf
+
+ * lisp/net/eww.el (eww-display-pdf): Make *eww pdf* buffer unibyte
+ before populating it to avoid conversions. The binding for
+ coding-system-for-write is then no longer necessary, and can be
+ delegated to the viewer invoked by mailcap-view-mime. Suggested by
+ Stefan Monnier <monnier@iro.umontreal.ca>. (Bug#44338)
+
+2020-11-05 Philipp Stephani <phst@google.com>
+
+ * src/minibuf.c (move_minibuffer_onto_frame): Fix comparison
+
+2020-11-05 Alan Mackenzie <acm@muc.de>
+
+ Allow minibuffer to stay in its original frame. Tidy up this area.
+
+ * doc/emacs/mini.texi (Basic Minibuffer): Add an entry for
+ minibuffer-follows-selected-frame.
+
+ * doc/lispref/minibuf.texi (Minibuffer Misc): Describe the new parameter to
+ minibufferp, LIVE.
+
+ * etc/NEWS: Add an entry describing the new minibuffer strategy.
+
+ * lisp/cus-start.el (minibuffer-prompt-properties--setter): Add an entry for
+ minibuffer-follows-selected-frame.
+
+ * lisp/minibuffer.el (minibuffer-message): Check for the current buffer being
+ an _active_ minibuffer rather than merely a minibuffer.
+
+ * src/frame.c (do_switch_frame): Call move_minibuffer_onto_frame.
+
+ * src/lisp.h (Top level): Add prototypes for move_minibuffer_onto_frame and
+ is_minibuffer.
+
+ * src/minibuf.c (minibuf_follows_frame): New function which ignores local and
+ let-bound values of minibuffer-follows-selected-frame.
+ (choose_minibuf_frame): Reformulate this function to reuse a minibuffer window
+ where possible, and to ensure no other frame has its minibuffer current, but
+ only when `minibuffer-follows-selected-frame'.
+ (move_minibuffer_onto_frame): New function.
+ (live_minibuffer_p): New function.
+ (Fminibufferp): Add a new &optional parameter LIVE. Reformulate, possibly
+ calling live_minibuffer_p.
+ (read_minibuf): move the incrementation of minibuf_level to before the call of
+ choose_minibuf_frame. Empty the miniwindows of frames without an active
+ minibuffer, rather than of all but the current frame.
+ (is_minibuffer): New function.
+ (read_minibuf_unwind): Note the miniwindow being restored and resize all other
+ miniwindows to zero size.
+ (minibuffer-follows-selected-frame): New configuration variable.
+
+ * src/window.c (candidate_window_p): In some scenarios, check the miniwindow
+ holds an active minibuffer.
+
+ * src/xdisp.c (get_window_cursor_type): Suppress the cursor for non-active
+ miniwindows, regardless of minibuf_level.
+
+2020-11-05 Eli Zaretskii <eliz@gnu.org>
+
+ * src/w32fns.c (Fw32_register_hot_key): Doc fix. (Bug#44456)
+
+2020-11-05 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Improve eww support for externally viewed PDFs
+
+ The *eww pdf* buffer is only needed when viewing PDFs within Emacs,
+ e.g., with doc-view-mode. External PDF viewers are called with a
+ temporary file, so the buffer is not needed in that case. What's
+ more, mailcap-view-mime erased the buffer and left it in
+ fundamental-mode until now, so the user was left staring at a
+ useless, empty buffer. To make things even worse, external viewers
+ were invoked synchronously until now, so the user could not browse
+ the PDF file and use Emacs simultaneously.
+
+ * lisp/net/mailcap.el (mailcap--async-shell): New function.
+ (mailcap-view-mime): Use it to invoke external viewers
+ asynchronously. Mention erasure of current buffer in that case in
+ docstring. Add a period between the temporary file name and its
+ extension.
+
+ * lisp/net/eww.el (eww-display-pdf): Simplify using
+ insert-buffer-substring. Fix coding-system-for-write for a stream
+ of raw bytes. Pop to *eww pdf* buffer only if it is used for
+ displaying a document; otherwise kill it. (bug#44338)
+
+2020-11-05 Michael Albinus <michael.albinus@gmx.de>
+
+ Still fixes for Tramp directory-files-*
+
+ * lisp/net/tramp.el (tramp-handle-directory-files):
+ * lisp/net/tramp-adb.el
+ (tramp-adb-handle-directory-files-and-attributes): Fix COUNT.
+
+ * lisp/net/tramp-crypt.el (tramp-crypt-handle-directory-files):
+ Implement COUNT.
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-dbus-byte-array-to-string):
+ * lisp/net/tramp-integration.el (tramp-eshell-directory-change):
+ Use `nbutlast'.
+
+ * lisp/net/tramp-rclone.el (tramp-rclone-handle-delete-directory)
+ (tramp-rclone-handle-delete-file): Reorder cache flushing.
+ (tramp-rclone-handle-directory-files):
+ Use `tramp-compat-directory-files'.
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-directory-files-and-attributes):
+ Fix NOSORT and COUNT.
+
+ * lisp/net/tramp-smb.el (tramp-smb-handle-directory-files): Fix NOSORT.
+
+ * test/lisp/net/tramp-tests.el (tramp--test-share-p): New defun.
+ (tramp-test05-expand-file-name-relative): Use it.
+ (tramp-test16-directory-files)
+ (tramp-test19-directory-files-and-attributes): Strengthen test.
+ (tramp-test20-file-modes): Simplify check.
+
+2020-11-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Let pdf-view-mode take precedence over doc-view-mode
+
+ * lisp/net/mailcap.el (mailcap-mime-data): Note the order, and let
+ pdf-view-mode take precedence, since it's an optional package
+ (bug#44338).
+
+2020-11-05 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Sync biblatex entries and fields with v3.15
+
+ * lisp/textmodes/bibtex.el (bibtex-BibTeX-entry-alist): Fix
+ abbreviation of PhD.
+ (bibtex-biblatex-entry-alist, bibtex-biblatex-field-alist): Sync
+ standard entry and field types with those described in the biblatex
+ v3.15 manual of 2020-08-19 (bug#44322).
+
+2020-11-04 Stephen Berman <stephen.berman@gmx.net>
+
+ Improve display of tabulated list header line labels (bug#44068)
+
+ * lisp/emacs-lisp/tabulated-list.el (tabulated-list-init-header):
+ Ensure sort indicator appears after the label of any selected
+ sortable column that is wide enough and enable label truncation
+ when narrowing a column.
+
+ * lisp/emacs-lisp/timer-list.el (timer-list-mode): Improve column
+ alignment.
+ (timer-list--function-predicate): Correct typo in doc string.
+
+2020-11-04 Eli Zaretskii <eliz@gnu.org>
+
+ Prevent redisplay from moving point behind user's back
+
+ * src/bidi.c (bidi_at_paragraph_end, bidi_find_paragraph_start):
+ Bind inhibit-quit to a non-nil value around calls to
+ fast_looking_at, to prevent breaking out of redisplay_window,
+ which temporarily moves point in buffers shown in non-selected
+ windows. (Bug#44448)
+
+2020-11-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/term.c (handle_one_term_event): Simplify.
+
+ Remove the `hold_quit` argument which was never used.
+ Streamline the control flow.
+ Thanks to Jared Finder <jared@finder.org> for pointing it out.
+
+ * src/keyboard.c (tty_read_avail_input): Simplify accordingly.
+
+2020-11-04 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Avoid use of eieio-oset-default
+
+ * lisp/gnus/gnus-search.el: Replace with an :initform tag on the slot
+ definition. `symbol-value' is necessary, otherwise the defclass macro
+ will treat the option as a quoted symbol.
+
+2020-11-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/lisp-mode.el: Fix missing highlight of "hidden" string arg
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-el-font-lock-keywords-2)
+ (lisp-cl-font-lock-keywords-2): Highlight "hidden arg" even if it
+ already has another face.
+
+2020-11-04 Manuel Uberti <manuel.uberti@inventati.org> (tiny change)
+
+ * lisp/progmodes/project.el (project--files-in-directory): Fix formatting
+
+2020-11-04 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in mule-charsets.el
+
+ * admin/charsets/mule-charsets.el: Use lexical-binding.
+ (mule-charsets-header): Rename from 'header' to silence byte-compiler.
+
+2020-11-04 Reuben Thomas <rrt@sc3d.org>
+
+ Remove unused variable in ispell.el (thanks, Stefan Kangas)
+
+ * lisp/textmodes/ispell.el (ispell-check-version): Remove unused
+ variable `speller'.
+
+2020-11-04 Stefan Kangas <stefan@marxist.se>
+
+ Fix warnings in url-irc.el
+
+ * lisp/url/url-irc.el (zenirc-server-alist, zenirc-buffer-name):
+ Declare to fix warnings.
+ (url-irc-rcirc): Silence warning by adding missing password argument
+ to rcirc-connect.
+
+2020-11-04 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/obsolete/nnir.el: Add "Obsolete-since" header.
+
+ * lisp/cedet/srecode.el: Use lexical-binding.
+
+2020-11-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Fix misuses of `make-local-variable` on hooks
+
+ * lisp/vc/smerge-mode.el (smerge-ediff):
+ * lisp/progmodes/python.el (python-pdbtrack-setup-tracking):
+ * lisp/net/tramp-smb.el (tramp-smb-call-winexe):
+ * lisp/net/secrets.el (secrets-mode):
+ * lisp/mail/rmail.el (rmail-variables):
+ * lisp/ielm.el (inferior-emacs-lisp-mode):
+ * lisp/erc/erc-log.el (erc-log-setup-logging): Use `add-hook`.
+
+ * lisp/eshell/em-unix.el (eshell/diff):
+ * lisp/eshell/em-hist.el (eshell-hist-initialize): Don't
+ `make-local-variable` on hooks.
+
+2020-11-04 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Remove gmane search engine
+
+ Remove the gnus-search-gmane class and all associated methods. If
+ search functionality is ever resurrected, then revert this commit.
+
+ * lisp/gnus/gnus-search.el: Delete code, and remove from default value
+ of `gnus-search-default-engines'.
+
+2020-11-04 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Move nnir.el to lisp/obsolete
+
+ * lisp/obsolete/nnir.el: This is no longer used, but users might still
+ be requiring it.
+
+2020-11-04 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ New gnus-search library
+
+ This library provides a fundamental reworking of the search
+ functionality previously found in nnir.el. It uses class-based search
+ engines to interface with external searching facilities, and a parsed
+ search query syntax that can search multiple engines.
+
+ * lisp/gnus/gnus-search.el: New library containing search
+ functionality for Gnus.
+ * doc/misc/gnus.texi: Document.
+ * lisp/gnus/gnus-group.el (gnus-group-make-search-group,
+ gnus-group-read-ephemeral-search-group): Remove references to nnir,
+ change meaning of prefix argument, change values of nnselect-function
+ and nnselect-args.
+ * lisp/gnus/nnselect.el: Replace references to nnir
+ (nnselect-request-article): Use gnus-search functions, and search
+ criteria.
+ (nnselect-request-thread, nnselect-search-thread): Use gnus-search
+ thread search.
+ (gnus-summary-make-search-group): Switch to use gnus-search function
+ and arguments.
+ * test/lisp/gnus/gnus-search-tests.el: Tests for new
+ functionality.
+
+2020-11-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/tcl.el: Use lexical-binding
+
+ Remove redundant `:group` args.
+
+2020-11-03 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change
+
+ * lisp/mwheel.el (mwheel-scroll): Don't use passive tense in doc
+ string.
+
+2020-11-03 Juri Linkov <juri@linkov.net>
+
+ Horizontal mouse wheel scrolling amount (bug#43568)
+
+ * lisp/mwheel.el (mouse-wheel-scroll-amount-horizontal): New defcustom.
+ (mwheel-scroll): Use it.
+
+ * doc/emacs/frames.texi (Mouse Commands): Update doc about horizontal
+ scrolling step.
+
+2020-11-03 Michael Albinus <michael.albinus@gmx.de>
+
+ Some Tramp fixes for directory-files-* and delete-*
+
+ * lisp/files.el (delete-directory): Simplify check for trash.
+
+ * lisp/net/ange-ftp.el (ange-ftp-delete-file): Implement TRASH.
+
+ * lisp/net/tramp-compat.el (tramp-compat-directory-files)
+ (tramp-compat-directory-files-and-attributes)
+ (tramp-compat-directory-empty-p): New defaliases.
+
+ * lisp/net/tramp.el (tramp-handle-directory-files-and-attributes)
+ (tramp-skeleton-delete-directory):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-delete-directory): Use them.
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-directory-files-and-attributes):
+ Implement COUNT.
+
+ * test/lisp/net/tramp-tests.el (tramp-test14-delete-directory):
+ Do not run trash test for ange-ftp.
+ (tramp-test16-directory-files)
+ (tramp-test19-directory-files-and-attributes): Check COUNT argument.
+
+2020-11-03 Reuben Thomas <rrt@sc3d.org>
+
+ Factor out some common code in ispell.el
+
+ * lisp/textmodes/ispell.el (ispell-with-safe-default-directory): Add
+ macro.
+ (ispell-call-process, ispell-call-process-region): Use it.
+
+2020-11-03 Reuben Thomas <rrt@sc3d.org>
+
+ Simplify ispell-check-version’s use of -vv flag
+
+ * lisp/textmodes/ispell.el (ispell-check-version): All supported spell
+ checker programs accept -vv, including aspell for many years, so use
+ it.
+
+2020-11-03 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Fix indentation for Emacs 26
+
+ * lisp/progmodes/cperl-mode.el (cperl-mode): Add a fix
+ which is only required for Emacs versions older than 27.
+
+ * test/lisp/progmodes/cperl-mode-tests.el (cperl-bug30393):
+ Add a test to verify correct indentation (bug#30393).
+
+2020-11-03 Mauro Aranda <maurooaranda@gmail.com>
+
+ Fix customizing user options of type face
+
+ * lisp/cus-edit.el (face): Move the %f escape after the tag, because
+ otherwise customizing a face user option doesn't work:
+ custom-variable-value-create thinks that everything up until the first
+ ":" is part of the tag, and the item widget doesn't know how to handle
+ the %f escape.
+
+2020-11-03 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in some url-*.el files
+
+ * lisp/url/url-dired.el:
+ * lisp/url/url-ftp.el:
+ * lisp/url/url-irc.el: Use lexical-binding.
+
+2020-11-03 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in solitaire.el
+
+ * lisp/play/solitaire.el: Use lexical-binding. Remove redundant
+ :group args.
+
+2020-11-03 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in some of emulation/edt*.el
+
+ * lisp/emulation/edt-vt100.el:
+ * lisp/emulation/edt-pc.el:
+ * lisp/emulation/edt-lk201.el: Use lexical-binding.
+
+2020-11-03 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in pcmpl-rpm.el
+
+ * lisp/pcmpl-rpm.el: Use lexical-binding. Remove redundant :group
+ args.
+ (pcmpl-rpm-packages): Quote function symbol as such.
+
+2020-11-03 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in pcmpl-cvs.el
+
+ * lisp/pcmpl-cvs.el: Use lexical-binding.
+ (executable): Remove unnecessary require.
+ (pcmpl-cvs-binary): Remove redundant :group arg.
+ (pcmpl-cvs-tags): Quote function symbol as such.
+
+2020-11-03 Stefan Kangas <stefan@marxist.se>
+
+ Fix exiting the finder-commentary buffer
+
+ * lisp/finder.el (finder-exit): Fix exiting the finder-commentary
+ buffer. (Bug#44384)
+ (finder-buffer): New defconst.
+ (finder-list-keywords): Use above new defconst.
+
+2020-11-03 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Skip a test for older Emacsen (preparing for ELPA)
+
+ * test/lisp/progmodes/cperl-mode-tests.el (cperl-bug37127):
+ Skip this test for older Emacsen. The bug has been fixed
+ in Emacs, but outside of CPerl mode, and therefore will not
+ be available for older versions via ELPA.
+
+2020-11-03 Stefan Kangas <stefan@marxist.se>
+
+ Improve ert-resource-directory docstring
+
+ * lisp/emacs-lisp/ert-x.el (ert-resource-directory): Improve
+ docstring.
+
+2020-11-02 Reuben Thomas <rrt@sc3d.org>
+
+ Fix previous patch to ispell.el
+
+ * lisp/textmodes/ispell.el (ispell--call-enchant-lsmod):
+ with-current-buffer and with-output-to-string need to be the other
+ way around.
+
+2020-11-02 Reuben Thomas <rrt@sc3d.org>
+
+ Fix previous code change to `ispell--call-enchant-lsmod'
+
+ * lisp/textmodes/ispell.el (ispell--call-enchant-lsmod): Restore the
+ use of with-current-buffer, to avoid enchant-lsmod’s output being
+ dumped into the current buffer.
+
+2020-11-02 Eli Zaretskii <eliz@gnu.org>
+
+ Explain last change
+
+ * lisp/textmodes/ispell.el (ispell--call-enchant-lsmod): Explain
+ the workaround with discarding stderr. (Bug#44318)
+
+2020-11-02 Reuben Thomas <rrt@sc3d.org>
+
+ Make ispell.el ignore warnings from enchant-lsmod (closes #44318)
+
+ * lisp/textmodes/ispell.el (ispell--call-enchant-lsmod): Don’t capture
+ stderr. Also remove unnecessary with-current-buffer wrapper.
+
+2020-11-02 Mattias Engdegård <mattiase@acm.org>
+
+ Add missing argument to directory_files_internal calls
+
+ * src/kqueue.c (kqueue_compare_dir_list, Fkqueue_add_watch):
+ Pass the new seventh argument.
+
+2020-11-02 Eli Zaretskii <eliz@gnu.org>
+
+ Fix a recent change in dired.c
+
+ * src/dired.c (directory_files_internal): Fix type of integer
+ variables to avoid overflow in 32-bit builds --with-wide-int.
+
+2020-11-02 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of a recent commit
+
+ * lisp/international/mule-cmds.el (transient-input-method): Doc
+ fix. Add :version tag.
+ (transient-input-method): Doc fix.
+
+ * etc/NEWS:
+ * doc/emacs/mule.texi (Select Input Method): Fix wording of the
+ last change.
+
+2020-11-02 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 4e6104ea0b ; * src/xdisp.c (display_string): Fix a typo in a comment.
+ 7162228815 Improve indexing of check-declare
+ d218b28ab5 ; * lisp/autoinsert.el (auto-insert-alist): Fix texinfo URL.
+
+2020-11-02 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 1fc9de4b81 Improve reproducibility of generated -pkg.el files
+ da6234e2df Make sure pixel sizes are zero when setting window size fo...
+ 2d15296db1 Fix failure of 'emacs --daemon' on Cygwin
+ 8abce5b0c6 CC Mode: Only recognize foo (*bar) as a function pointer w...
+ 85d1d8d768 Fix NEWS entry for fix of Bug#44080
+ 2443b15a91 * src/buffer.c (syms_of_buffer) <fill-column>: Improve doc...
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-11-02 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix some glitches in recent directory-files-* changes
+
+ * doc/lispref/files.texi (Contents of Directories):
+ Fix description of directory-files, directory-empty-p and
+ directory-files-and-attributes.
+
+ * etc/NEWS: Fix entry for directory-files-and-attributes. Fix typos.
+
+ * lisp/dired.el (directory-empty-p): Move function from here ...
+
+ * lisp/files.el (directory-empty-p): ... to here.
+
+ * lisp/net/ange-ftp.el (ange-ftp-directory-files): Call `nreverse' later.
+
+ * lisp/net/tramp.el (tramp-handle-directory-files):
+ * lisp/net/tramp-adb.el
+ (tramp-adb-handle-directory-files-and-attributes): Do not call
+ `nreverse'.
+
+ * src/dired.c (Fdirectory_files)
+ (Fdirectory_files_and_attributes): Fix docstrings.
+
+ * test/src/dired-tests.el: Removed. Tests moved to
+ test/lisp/dired-tests.el.
+
+ * test/lisp/dired-tests.el (dired-test-bug27899): Tag it :unstable.
+ (dired-test-directory-files)
+ (dired-test-directory-files-and-attributes): New tests.
+
+2020-11-02 João Távora <joaotavora@gmail.com>
+
+ Fix Elisp's elisp--documentation-one-liner (bug#43609)
+
+ To be backward compatible, this function must return nil when there is
+ a symbol at point but no documentation for it. Before this fixed it
+ returned the string "<symbol-name>: nil".
+
+ * lisp/progmodes/elisp-mode.el (elisp--documentation-one-liner):
+ Check callback actually produced non-nil doc.
+
+2020-11-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix mouse-1 on [Show] buttons in the *Help* buffer
+
+ * lisp/descr-text.el (describe-text-sexp): Add a `follow-link' so
+ that the [Show] buttons work correctly with mouse-1 (bug#44340).
+
+2020-11-02 Yasuhiro KIMURA <yasu@utahime.org> (tiny change)
+
+ Recover the contents of the schemas.xml file
+
+ * etc/schema/schemas.xml: Recover the file, which was apparently
+ (mostly) removed by mistake by commit 165f738382 (bug#42851).
+
+2020-11-02 Mauro Aranda <maurooaranda@gmail.com>
+
+ Document that the :match function for a widget takes an external value
+
+ * doc/misc/widget.texi (Basic Types): Document what an external value
+ is. Document that a :match function expects the value to be in the
+ external format. (Bug#8717)
+
+2020-11-02 Stephen Berman <Stephen.Berman@gmx.net>
+
+ Don't render XML declaration of an HTML document (bug#44348)
+
+ * lisp/net/eww.el (eww--preprocess-html): Prevent converting the
+ left angle bracket in the sequence "<?" to an HTML entity.
+
+2020-11-02 Arthur Miller <arthur.miller@live.com>
+
+ Add directory-empty-p and new argument COUNT for directory-files-*
+
+ * doc/lispref/files.texi (Contents of Directories): Mention COUNT
+ argument of directory-files. Add directory-empty-p.
+
+ * etc/NEWS: Mention directory-empty-p and directory-files changes.
+
+ * lisp/dired.el (directory-empty-p): New defun.
+
+ * lisp/net/ange-ftp.el (ange-ftp-directory-files)
+ (ange-ftp-directory-files-and-attributes):
+ * lisp/net/tramp.el (tramp-handle-directory-files)
+ (tramp-handle-directory-files-and-attributes):
+ * lisp/net/tramp-adb.el
+ (tramp-adb-handle-directory-files-and-attributes):
+ * lisp/net/tramp-rclone.el (tramp-rclone-handle-directory-files):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-directory-files-and-attributes):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-directory-files): Add new COUNT
+ argument.
+
+ * src/dired.c (directory_files_internal): Implement new
+ RETURN_COUNT argument.
+ (Fdirectory_files, Fdirectory_files_and_attributes): Add new COUNT
+ argument.
+
+ * src/lisp.h (directory_files_internal): Add RETURN_COUNT to declaration.
+
+ * src/sysdep.c (list_system_processes): Add Qnil to
+ directory_files_internal call.
+
+ * test/src/dired-tests.el (directory-files-and-attributes-tests):
+ New file.
+
+2020-11-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Partially revert previous define-minor-mode change
+
+ * lisp/emacs-lisp/easy-mmode.el (easy-mmode--arg-docstring):
+ Only document the values we want to support, not the ones we
+ actually support.
+ (define-minor-mode): Partially revert to previous behaviour.
+
+2020-11-01 Stefan Kangas <stefan@marxist.se>
+
+ Fix mistake in Lisp conversion of describe-map-tree
+
+ * lisp/help.el (describe-map-tree): Fix mistake in conversion to Lisp
+ from the C function describe_map_tree; make the condition match the
+ now removed C code. (Bug#44360)
+
+2020-11-01 Juri Linkov <juri@linkov.net>
+
+ Transient input methods bound to 'C-x \' (bug#44266)
+
+ * lisp/international/mule-cmds.el (ctl-x-map): Bind 'C-x \' to
+ 'transient-input-method'.
+ (input-method-function): New defcustom.
+ (transient-input-method): New command.
+
+ * doc/emacs/mule.texi (Select Input Method): Document transient-input-method.
+
+2020-11-01 Juri Linkov <juri@linkov.net>
+
+ * lisp/leim/quail/compose.el: New input method (bug#44267).
+
+2020-11-01 Juri Linkov <juri@linkov.net>
+
+ Show nobreak-space face for more blank characters in describe-char.
+
+ * lisp/descr-text.el (describe-char): Handle more non-ASCII whitespace
+ characters added in f018cffca0098ad1b82c51730a6d6cf146e3c488 (bug#44236)
+
+2020-11-01 Stefan Kangas <stefan@marxist.se>
+
+ Improve indexing of check-declare
+
+ * doc/lispref/functions.texi (Declaring Functions): Improve indexing.
+
+2020-11-01 Stefan Kangas <stefan@marxist.se>
+
+ Don't auto-insert "@c file ends here" in .texi files
+
+ * lisp/autoinsert.el (auto-insert-alist): Don't insert "@c file ends
+ here" at the end of new .texi files.
+
+2020-11-01 Stefan Kangas <stefan@marxist.se>
+
+ Don't bind standard-output in substitute-command-keys
+
+ This fixes a regression with regards to the old C version of
+ substitute-command-keys.
+
+ * lisp/help.el (substitute-command-keys): Don't bind standard-output.
+ See Bug#39149.
+ * test/lisp/help-tests.el
+ (help-tests--was-in-buffer): New variable.
+ (help-substitute-command-keys/menu-filter-in-correct-buffer): New
+ test.
+
+2020-11-01 Glenn Morris <rgm@gnu.org>
+
+ * lisp/emacs-lisp/easy-mmode.el (easy-mmode--arg-docstring): Doc typo.
+
+2020-11-01 Mattias Engdegård <mattiase@acm.org>
+
+ Add missing side-effect-free and error-free properties
+
+ Any function that is pure is also side-effect-free and some are also
+ error-free. Right now these have to be declared separately.
+
+ * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Add
+ bool-vector-count-consecutive, bool-vector-count-population,
+ bool-vector-subsetp, copysign, isnan, lax-plist-get, ldexp, memql,
+ regexp-opt and string-to-syntax.
+ (side-effect-and-error-free-fns): Add type-of.
+ * lisp/subr.el (kbd, string-replace): Declare side-effect-free.
+
+2020-11-01 Mattias Engdegård <mattiase@acm.org>
+
+ * lisp/emacs-lisp/byte-opt.el (pure-fns): Fix typos.
+
+2020-11-01 Stefan Kangas <stefan@marxist.se>
+
+ Insert describe-map-tree header into original buffer
+
+ * lisp/help.el (describe-map-tree): Insert header into the original
+ buffer, not in standard-output.
+ * test/src/keymap-tests.el
+ (describe-buffer-bindings/header-in-current-buffer)
+ (describe-buffer-bindings/returns-nil): New tests.
+ Ref: https://debbugs.gnu.org/39149#31
+
+2020-11-01 Andrea Corallo <akrl@sdf.org>
+
+ Fix 'comp-call-optim pass' for anonymous lambdas
+
+ * lisp/emacs-lisp/comp.el (comp-call-optim-func): Remove anonymous
+ lambdas gate.
+ (comp-call-optim-form-call): Add the correct missing condition.
+
+2020-11-01 Andrea Corallo <akrl@sdf.org>
+
+ * test/src/comp-tests.el (compile-forms): Fix missing lexical binding.
+
+2020-11-01 Andrea Corallo <akrl@sdf.org>
+
+ Add some 'cond-rw' pass related tests
+
+ * test/src/comp-tests.el (comp-tests-cond-rw-checked-function):
+ Declare var.
+ (comp-tests-cond-rw-checker-val): New function.
+ (comp-tests-cond-rw-checker-type): Declare var.
+ (comp-tests-cond-rw-checker-type): New function.
+ (comp-tests-cond-rw-0-var): Declare var.
+ (comp-tests-cond-rw-0, comp-tests-cond-rw-1, comp-tests-cond-rw-2)
+ (comp-tests-cond-rw-3, comp-tests-cond-rw-4)
+ (comp-tests-cond-rw-5): New testcases.
+
+2020-11-01 Andrea Corallo <akrl@sdf.org>
+
+ Add new cond-rw pass to have forward propagation track cond branches
+
+ Add a new pass to rewrite conditional branches. This is introducing
+ and placing a new LIMPLE operator 'assume' in use by fwprop to
+ propagate conditional branch test information on target basic blocks.
+
+ * lisp/emacs-lisp/comp.el (comp-passes): Add `comp-cond-rw'.
+ (comp-limple-assignments): Add `assume' operator.
+ (comp-emit-assume, comp-cond-rw-target-slot, comp-cond-rw-func)
+ (comp-cond-rw): Add new functions.
+ (comp-fwprop-insn): Update to pattern match `assume' insns.
+ * src/comp.c (emit_limple_insn): Add for `assume'.
+ (syms_of_comp): Define 'Qassume' symbol.
+
+2020-11-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make minor mode ARG work as documented
+
+ * lisp/emacs-lisp/easy-mmode.el (easy-mmode--arg-docstring):
+ Clarify when minor modes are switched on/off when called from lisp
+ (bug#44341).
+ (define-minor-mode): Make calls from Lisp switch the mode on/off
+ as documented.
+
+2020-11-01 Andrea Corallo <akrl@sdf.org>
+
+ Rework some native compiler test infrastructure
+
+ * test/src/comp-tests.el (comp-tests-map-checker): New function
+ returning a list holding checker results.
+ (comp-tests-tco-checker, comp-tests-fw-prop-checker-1)
+ (comp-tests-pure-checker-1, comp-tests-pure-checker-2): Make use
+ of `comp-tests-map-checker'.
+
+2020-11-01 Mauro Aranda <maurooaranda@gmail.com>
+
+ Fix saving a face setting with Customize
+
+ * lisp/cus-edit.el (custom-face-save): Make sure we back up into the
+ :shown-value property what the user has edited so far, if we are going
+ to recreate the custom-face widget. (Bug#44331)
+
+2020-11-01 Yasuhiro KIMURA <yasu@utahime.org> (tiny change)
+
+ Recover the contents of the schemas.xml file
+
+ * etc/schema/schemas.xml: Recover the file, which was apparently
+ (mostly) removed by mistake by commit 165f738382 (bug#42851).
+
+2020-11-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Doc string clarification for cl-some
+
+ * lisp/emacs-lisp/cl-extra.el (cl-some): Clarify the return value
+ (bug#44330).
+
+2020-11-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ custom-theme-set-variables more resilient against removed libraries
+
+ * lisp/custom.el (custom-theme-set-variables): Don't bug out on
+ settings that require a library that has been removed (bug#38843).
+
+2020-11-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention non-ASCII C-c LETTER bindings in the lispref manual
+
+ * doc/lispref/tips.texi (Key Binding Conventions): Mention
+ non-ASCII C-c LETTER (bug#15917).
+
+2020-11-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention the C-c LETTER keybinding convention
+
+ * doc/emacs/custom.texi (Keymaps): Reintroduce the text about C-c
+ LETTER (bug#15917), and clarify.
+
+2020-11-01 Michael Albinus <michael.albinus@gmx.de>
+
+ Trash remote files to local trash (Bug#44216)
+
+ * doc/misc/tramp.texi (Frequently Asked Questions): Add trashing.
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-delete-directory)
+ (tramp-adb-handle-delete-file):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-delete-directory)
+ (tramp-gvfs-handle-delete-file):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-delete-directory)
+ (tramp-sh-handle-delete-file):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-delete-directory)
+ (tramp-smb-handle-delete-file):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-delete-directory)
+ (tramp-sudoedit-handle-delete-file): Implement local trash. (Bug#44216)
+
+ * lisp/net/tramp-crypt.el (tramp-crypt-handle-delete-directory)
+ (tramp-crypt-handle-delete-file): Do not trash.
+
+ * lisp/net/tramp.el (tramp-skeleton-delete-directory): New defmacro.
+
+ * test/lisp/net/tramp-tests.el (tramp-test07-file-exists-p)
+ (tramp-test14-delete-directory): Add trashing.
+
+2020-11-01 Michael Albinus <michael.albinus@gmx.de>
+
+ * etc/NEWS: Add trashing of remote files. Fix typos.
+
+2020-11-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix error message in feedmail
+
+ * lisp/mail/feedmail.el (feedmail-buffer-to-smtpmail): Remove
+ superfluous %s in insert string
+
+2020-11-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix a segfault in the new svg code
+
+ * src/image.c (svg_load_image): Don't pass in a NULL for the
+ logical rect, because that will sometimes segfault.
+
+2020-10-31 Juri Linkov <juri@linkov.net>
+
+ New variable integer-output-format to print integers as characters (bug#44155)
+
+ * doc/lispref/streams.texi (Output Variables): Add integer-output-format.
+
+ * src/print.c (print_object): In case of Lisp_Int, print integers
+ as characters when Vinteger_output_format is Qt, and in hex format
+ when Vinteger_output_format is 16.
+ (Vinteger_output_format): New variable.
+
+ * test/src/print-tests.el (print-integer-output-format): New test.
+
+2020-10-31 Mauro Aranda <maurooaranda@gmail.com>
+
+ Give the scroll-bar face a non-trivial spec
+
+ * lisp/faces.el (scroll-bar): Give it a non-trivial spec, so when
+ resetting it to its face-defface-spec, we effectively reset it.
+ (Bug#13476)
+
+2020-10-31 Juri Linkov <juri@linkov.net>
+
+ Improve goto-line in regard to narrowed buffers (bug#44294)
+
+ * lisp/simple.el (goto-line): Rewrite to first find the position
+ of the line where to go, then later don't widen the buffer
+ when the found position is still inside narrowed part of buffer.
+
+ * lisp/isearch.el (isearch-message-prefix): Warn about narrowed buffer
+ in case of no more matches found.
+
+2020-10-31 Juri Linkov <juri@linkov.net>
+
+ Reimplement commit 46b3db5579e57b9daf16667914205adc99d3f104 (bug#44294)
+
+ * lisp/progmodes/etags.el (etags-goto-tag-location): Revert change from
+ commit 46b3db5579e57b9daf16667914205adc99d3f104.
+ (xref-location-marker): Use the same change as was made in elisp-mode.el in
+ commit 46b3db5579e57b9daf16667914205adc99d3f104 to widen before going
+ to the found position.
+
+2020-10-31 Stefan Kangas <stefan@marxist.se>
+
+ * test/README: Document TEST_BACKTRACE_LINE_LENGTH.
+
+2020-10-31 Amin Bandali <bandali@gnu.org>
+
+ Replace irc.freenode.net with chat.freenode.net
+
+ chat.freenode.net has been the preferred address for connecting to the
+ freenode IRC network for years now. Replace the occurrences of
+ irc.freenode.net with chat.freenode.net.
+
+2020-10-31 Mattias Engdegård <mattiase@acm.org>
+
+ Fix eshell glob modifiers
+
+ Modified globbing such as *.txt(W) for all world-writable files ending
+ in .txt apparently never worked correctly.
+
+ * lisp/eshell/em-pred.el (eshell-predicate-alist): Use correct
+ elisp syntax for octal constants.
+ (eshell-pred-file-mode): Return a boolean, not a number.
+
+2020-10-31 Andreas Schwab <schwab@linux-m68k.org>
+
+ wdired: fix error handling of set-file-modes
+
+ * lisp/wdired.el (wdired-perms-to-number): Return decimal number.
+ (wdired-do-perm-changes): Handle error from set-file-modes.
+ (wdired-finish-edit): Remove `rename' from error message.
+ (Bug#44343)
+
+2020-10-31 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-10-31 Eli Zaretskii <eliz@gnu.org>
+
+ * etc/HELLO: Enlarge tab-width to account for "tofu".
+
+2020-10-31 Mattias Engdegård <mattiase@acm.org>
+
+ 'assoc' is not side-effect-free; constprop its pure subset
+
+ Since a supplied test function can do anything, assoc is not
+ side-effect-free (bug#44018). However, with only two arguments it is
+ pure and should be optimised accordingly.
+
+ * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Remove 'assoc'.
+ (byte-optimize-assoc): Constant-propagate through 2-arg assoc calls.
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (byte-opt-testsuite-arith-data): Add test cases.
+
+2020-10-31 Eli Zaretskii <eliz@gnu.org>
+
+ Improve support for displaying Javanese script
+
+ * lisp/international/fontset.el (setup-default-fontset)
+ (script-representative-chars): Add Javanese entries.
+
+ * etc/HELLO: Fix the Javanese text. See
+ https://omniglot.com/language/phrases/javanese.php for the
+ source.
+
+2020-10-31 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/xdisp.c (syms_of_xdisp) <"scroll-minibuffer-conservatively">: New var
+
+ Fix bug#44070, which causes the minibuffer display to jump upon minor edit
+
+ (redisplay_window): Obey it.
+ * lisp/simple.el (end-of-buffer): Obey it.
+
+ * test/src/xdisp-tests.el (xdisp-tests--in-minibuffer): New macro,
+ extracted from `xdisp-tests--minibuffer-resizing`.
+ (xdisp-tests--minibuffer-resizing): Use it.
+ (xdisp-tests--minibuffer-scroll): New test.
+
+2020-10-31 Mattias Engdegård <mattiase@acm.org>
+
+ Trim and explain set of safe forms for 'unsafep' (bug#44018)
+
+ * lisp/emacs-lisp/unsafep.el:
+ Add comment explaining the policy for which forms can be considered
+ 'safe' in the sense of unsafep. Remove ones that didn't make the cut:
+
+ play-sound-file (large attack surface)
+ catch, throw (alter program flow, inject data)
+ replace-regexp-in-string (execute arbitrary code)
+ error, signal (deceptive messages)
+
+ * test/lisp/emacs-lisp/unsafep-tests.el (unsafep-tests--unsafe):
+ Add test cases.
+ * etc/NEWS: Announce the change.
+
+2020-10-31 Mattias Engdegård <mattiase@acm.org>
+
+ Parse GDB/MI results directly instead of going via JSON (bug#44173)
+
+ Translating GDB/MI into JSON is an unnecessary and fragile detour
+ that made it hard to deal with octal escapes in strings correctly.
+ Parse GDB/MI directly instead.
+
+ * lisp/progmodes/gdb-mi.el (gdb-mi-decode-strings): Adjust doc string.
+ (gdb-mi-decode, gud-gdbmi-marker-filter): Remove gdb-mi-decode.
+ (gdb-jsonify-buffer): Remove.
+ (gdb-mi--parse-tuple-or-list, gdb-mi--parse-c-string)
+ (gdb-mi--parse-value, gdb-mi--parse-result-or-value)
+ (gdb-mi--parse-results, gdb-mi--fix-key, gdb-mi--extend-fullname)
+ (gdb-mi--c-string-from-string): New functions.
+ (gdb-json-read-buffer, gdb-json-string, gdb-json-partial-output):
+ Rename to gdb-mi--read-buffer, gdb-mi--from-string and
+ gdb-mi--partial-output respectively. Remove useless FIX-LIST
+ argument. FIX-KEY is now a symbol, not a string. All callers updated.
+ (gdb-tooltip-print, gdbmi-bnf-log-stream-output, gdb-internals)
+ (gdb-console, gdb-done-or-error, gdb-get-source-file-list)
+ (gdb-get-prompt, gdb-get-source-file):
+ Use gdb-mi--c-string-from-string instead of 'read'.
+ * test/lisp/progmodes/gdb-mi-tests.el: New file.
+
+2020-10-31 Eli Zaretskii <eliz@gnu.org>
+
+ * etc/HELLO: Add Egyptian Hieroglyphs.
+
+2020-10-31 Eli Zaretskii <eliz@gnu.org>
+
+ Support prettified display of fractional numbers
+
+ * lisp/composite.el (composition-function-table): Define an entry
+ for U+2044 FRACTION SLASH, for prettier display of fractional
+ numbers.
+
+2020-10-31 Michael Albinus <michael.albinus@gmx.de>
+
+ Check also for "DragonFly" remote systems in Tramp
+
+ * lisp/net/tramp-sh.el (tramp-open-connection-setup-interactive-shell):
+ Check also for "DragonFly".
+
+2020-10-31 Eli Zaretskii <eliz@gnu.org>
+
+ Speed up ls-lisp
+
+ This speeds up Dired by 25% in large directories.
+ * lisp/ls-lisp.el (ls-lisp--time-locale): New defvar.
+ (ls-lisp-format-time): calculate the locale for formatting times
+ only once and cache the value in 'ls-lisp--time-locale'.
+ (Bug#44273)
+
+2020-10-31 Eli Zaretskii <eliz@gnu.org>
+
+ * doc/lispref/commands.texi (Key Sequence Input): Fix indexing.
+
+2020-10-31 Jared Finder <jared@finder.org>
+
+ Updating docs with all special window prefix keys.
+
+ * doc/lispref/commands.texi (Key Sequence Input): Add documentation for
+ missing special window areas. Explicitly call out window or frame.
+
+2020-10-31 Jared Finder <jared@finder.org>
+
+ Fix unit tests broken by changes to xt-mouse.el
+
+ * test/lisp/xt-mouse-tests.el (xt-mouse-tracking-basic)
+ (xt-mouse-tracking-utf-8): Update expected escape sequence.
+
+2020-10-31 Eli Zaretskii <eliz@gnu.org>
+
+ Revert "Temporarily mark two failing tests"
+
+ This reverts commit a8426f46726d94cdf21c0e6b3c85c0afe0064784.
+ A proper fix for the test is about to be installed shortly.
+
+2020-10-31 Thien-Thi Nguyen <ttn@gnu.org>
+
+ Make hideshow.el work with Mhtml mode
+
+ Suggested by Ian Williams <norbekian9@gmail.com>.
+
+ * lisp/textmodes/mhtml-mode.el: Require ‘pcase’ when compiling.
+ (mhtml-forward): New func.
+ * lisp/progmodes/hideshow.el (hs-special-modes-alist):
+ Add entry for ‘mhtml-mode’.
+
+2020-10-31 Glenn Morris <rgm@gnu.org>
+
+ Improve reproducibility of generated -pkg.el files
+
+ * lisp/emacs-lisp/package.el (package-generate-description-file):
+ Don't include the full name of the source file in the header,
+ since that varies non-reproducibly according to the build directory.
+ https://bugs.debian.org/972861
+ Note that elpa.gnu.org's admin/archive-contents.el does this by hand
+ and already only includes the nondirectory part.
+
+2020-10-30 João Távora <joaotavora@gmail.com>
+
+ Shoosh byte-compilation warning in lisp/emacs-lisp/eldoc.el
+
+ Per bug#43609, elisp-eldoc-documentation-function is again in master,
+ but since it's now officially obsoleted, this backward compatibility
+ shim in eldoc--eval-expression-setup shouldn't unnecessarily trigger
+ warnings in master's code.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc--eval-expression-setup): Shoosh
+ by-compilation warning.
+
+2020-10-30 João Távora <joaotavora@gmail.com>
+
+ Don't make ElDoc doc buffer visible in buffer list by default
+
+ (Bug#44334)
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-doc-buffer): No longer take
+ INTERACTIVE arg. Show buffer if invisible.
+ (eldoc--format-doc-buffer): Don't change buffer visibility.
+ (eldoc-display-in-buffer): Show buffer if invisible if by calling
+ eldoc-doc-buffer.
+
+2020-10-30 João Távora <joaotavora@gmail.com>
+
+ Bring back elisp-eldoc-documentation-function, marked obsolete
+
+ (Bug#43609)
+
+ It's not useful for ElDoc's eldoc-mode mechanism in Elisp, and nothing
+ in Emacs uses it, but it wasn't strictly marked internal, so it's best
+ to bring it back.
+
+ * lisp/progmodes/elisp-mode.el (elisp--documentation-one-liner):
+ New helper.
+ (elisp-eldoc-documentation-function): New function, with
+ obsoletion warning.
+
+2020-10-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/simple.el (blink-matching-open): Fix bug#37127
+
+ Don't call `syntax-propertize` from within narrowing
+
+ * lisp/progmodes/cperl-mode.el (cperl-forward-re): Revert last patch,
+ since it is now redundant.
+
+ * test/lisp/progmodes/cperl-mode-tests.el (cperl-bug37127):
+ Remove unused var; fix test so it really catches the previous bug;
+ tweak the code to use mode-agnostic commands so it also works in `perl-mode`.
+
+2020-10-30 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Bug#44289
+
+ * lisp/files.el (directory-listing-before-filename-regexp):
+ Support DD-MMM-YYYY format. (Bug#44289)
+
+2020-10-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak previous python-mode region fix
+
+ * lisp/progmodes/python.el (python-shell-buffer-substring): Tweak
+ the previous fix for bug#39398 to behave somewhat more like it
+ used to.
+
+2020-10-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Adjust python tests after fix for bug#39398"
+
+ This reverts commit c6fb23873a594b6a4fc57fa107869a2e82159d07.
+
+ The code is tweaked to be more backwards-compatible.
+
+2020-10-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix copying symbolic links in eshell
+
+ * lisp/eshell/em-unix.el (eshell-shuffle-files): Don't bug out
+ when copying symbolic links (bug#38577).
+
+2020-10-30 Dima Kogan <dima@secretsauce.net>
+
+ Add a new command to regenerate a hunk in diff-mode
+
+ * lisp/vc/diff-mode.el (diff-refresh-hunk): New function (bug#44312).
+ (diff-mode-map): Bind C-c C-l.
+
+2020-10-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix fontifying of ::= in Makefiles
+
+ * lisp/progmodes/make-mode.el (makefile-match-dependency): Don't
+ fontify the POSIX immediate assignment operator ::= as a
+ dependency (bug#44319).
+
+2020-10-30 Harald Jörg <haj@posteo.de>
+
+ Suppress a misleading message when closing a paren in a regex
+
+ * lisp/progmodes/cperl-mode.el (cperl-forward-re): Suppress an
+ error message about "End of string/RE not found" when we are
+ at the end of a narrowed buffer where the end of a RE is
+ temporarily unavailable (Bug#37127).
+
+ * test/lisp/progmodes/cperl-mode-tests.el (cperl-bug37127):
+ Add a test to verify that the message is suppressed when
+ inappropriate, but appears when the RE *is* incomplete.
+
+2020-10-30 Stefan Kangas <stefan@marxist.se>
+
+ Clarify point position after text-property-search
+
+ * lisp/emacs-lisp/text-property-search.el
+ (text-property-search-forward, text-property-search-backward): Doc fix
+ to clarify placement of point after search.
+ * test/lisp/emacs-lisp/text-property-search-tests.el
+ (text-property-search--pos-test): New defun.
+ (text-property-search-forward-point-at-beginning)
+ (text-property-search-backward-point-at-end): New test.
+
+2020-10-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak the gdb-mi error message
+
+ * lisp/progmodes/gdb-mi.el (gdb--check-interpreter): Make the
+ error message less misleading (bug#40279).
+
+2020-10-30 Neil Roberts <bpeeluk@yahoo.co.uk>
+
+ Use nobreak-space on all non-ASCII whitespace characters
+
+ * doc/emacs/display.texi (Text Display): Document it.
+
+ * src/xdisp.c (get_next_display_element): Use blankp to test whether
+ to use the nobreak_space face (bug#44236).
+
+2020-10-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make list-timers do sub-second times
+
+ * lisp/emacs-lisp/timer-list.el (list-timers): Do sub-second times
+ (bug#39956).
+
+2020-10-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ `format-time' can now do sub-second times
+
+ * doc/lispref/os.texi (Time Parsing): Document it.
+
+ * lisp/calendar/time-date.el (format-seconds): Allow formatting
+ sub-second times.
+
+2020-10-30 Stefan Kangas <stefan@marxist.se>
+
+ Add shortdoc navigation commands
+
+ * lisp/emacs-lisp/shortdoc.el (text-property-search): Require.
+ (shortdoc-mode): New major mode.
+ (shortdoc-mode-map): New variable.
+ (shortdoc--goto-section): New macro.
+ (shortdoc-next, shortdoc-previous, shortdoc-next-section)
+ (shortdoc-previous-section): New commands.
+ (shortdoc-display-group): Use new shortdoc-models. Propertize
+ section header.
+ (shortdoc--display-function): Propertize function header.
+
+2020-10-30 Hugh Daschbach <hdasch@fastmail.com>
+
+ * test/lisp/net/dbus-tests.el (dbus-test09-get-managed-objects): Expand test.
+
+2020-10-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/mail/binhex.el (binhex-char-int): Add missing release
+
+2020-10-30 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Remove Debbugs 'thanks' from submit-emacs-patch
+
+ * lisp/mail/emacsbug.el (submit-emacs-patch): Remove unneeded
+ 'thanks' following Debbugs pseudo-header, which leaves other
+ pseudo-headers entered by the user unprocessed (bug#44322).
+
+2020-10-30 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Modify only local send hook in submit-emacs-patch
+
+ * lisp/mail/emacsbug.el (submit-emacs-patch): Don't modify global
+ message-send-hook.
+
+2020-10-29 Noah Friedman <friedman@splode.com>
+
+ Make sure pixel sizes are zero when setting window size for ptys.
+
+ * sysdep.c (set_window_size): Initialize data to zero to avoid
+ passing any garbage from the stack to ioctl.
+
+2020-10-29 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Make timeout test more robust
+
+ * test/lisp/progmodes/cperl-mode-tests.el
+ (cperl-mode-test-bug-10483): Increase the timeout to 2 seconds
+ and mark the test as expensive. Also, suppress it for Emacs
+ versions below 28, where the test times out though the function
+ works in manual tests. (Bug#44317)
+
+2020-10-29 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Simplify some bibtex.el variable definitions
+
+ * lisp/textmodes/bibtex.el (bibtex-include-OPTkey)
+ (bibtex-user-optional-fields, bibtex-BibTeX-entry-alist)
+ (bibtex-biblatex-entry-alist, bibtex-generate-url-list): Use :risky
+ tag instead of risky-local-variable property.
+
+ (bibtex-entry-format, bibtex-maintain-sorted-entries)
+ (bibtex-sort-entry-class, bibtex-dialect)
+ (bibtex-autokey-name-case-convert-function): Use :safe tag instead
+ of safe-local-variable property.
+
+ (bibtex-autokey-name-case-convert-function): Let custom function
+ default to 'identity', not 'ignore'.
+
+ (bibtex-strings, bibtex-reference-keys): Define with defvar-local
+ instead of defvar+make-variable-buffer-local.
+
+2020-10-29 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/reposition.el: Use lexical-binding.
+
+2020-10-29 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/tcl.el: Better match Tcl string formation rules (bug#39277)
+
+ (tcl--word-delimiters): New const.
+ (tcl--syntax-of-quote): New function.
+ (tcl-syntax-propertize-function): Use them.
+ (tcl-mode): Enable `syntax-propertize-multiline`.
+
+ * test/manual/indent/tcl.tcl: New file.
+
+2020-10-29 Michael Albinus <michael.albinus@gmx.de>
+
+ Handle several children of PATH in dbus-managed-objects-handler
+
+ * lisp/net/dbus.el (dbus-managed-objects-handler): Handle several
+ children of PATH. (Bug#44298)
+
+ * src/dbusbind.c (xd_signature, xd_append_arg): Check object path.
+
+ * test/lisp/net/dbus-tests.el (dbus-test09-get-managed-objects):
+ Tag it :expensive-test. Remove superfluous check.
+
+2020-10-29 Stefan Kangas <stefan@marxist.se>
+
+ Fix CUA Mode menu entry to be less confusing
+
+ Note that the old text was incorrect; shift-selection is controlled by
+ the variable shift-select-mode.
+
+ * lisp/menu-bar.el (menu-bar-options-menu): Make CUA Mode menu entry
+ less confusing when cua-enable-cua-keys is nil. (Bug#43322)
+
+2020-10-29 Ken Brown <kbrown@cornell.edu>
+
+ Fix failure of 'emacs --daemon' on Cygwin
+
+ * src/emacs.c (DAEMON_MUST_EXEC): Define unconditionally on
+ Cygwin, not just if HAVE_NTGUI is defined. This fixes the failure
+ of 'emacs --daemon' to start on the non-w32 Cygwin builds.
+ (Bug#44285)
+
+2020-10-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak previous article-treat-ansi-sequences fix
+
+ * lisp/gnus/gnus-art.el (article-treat-ansi-sequences): Redo the
+ previous fix to avoid a compilation warning (bug#44299).
+
+2020-10-29 Hugh Daschbach <hdasch@fastmail.com>
+
+ * test/lisp/net/dbus-tests.el (dbus-test09-get-managed-objects): New test.
+
+2020-10-29 Andreas Schwab <schwab@linux-m68k.org>
+
+ Don't spill ansi-color across parts in articles
+
+ * lisp/gnus/gnus-art.el (article-treat-ansi-sequences): Reset
+ ansi-color-context-region. (Bug#44299)
+
+2020-10-29 Juri Linkov <juri@linkov.net>
+
+ * lisp/bindings.el (narrow-map): Bind C-x n g to goto-line-relative (bug#9917)
+
+2020-10-29 Juri Linkov <juri@linkov.net>
+
+ Widen buffer before going to point found by xref-find-definitions (bug#44294)
+
+ * lisp/progmodes/elisp-mode.el (xref-location-marker): Widen before going
+ to the found position.
+
+ * lisp/progmodes/etags.el (etags-goto-tag-location): Rerun after removing
+ narrowing.
+
+ * lisp/simple.el (goto-line-read-args): Use buffer-narrowed-p.
+
+2020-10-28 Stefan Kangas <stefan@marxist.se>
+
+ Run substitute-command-keys on shortdoc section headings
+
+ * lisp/emacs-lisp/shortdoc.el (shortdoc-display-group): Run
+ substitute-command-keys on section headings before displaying.
+
+2020-10-28 Stefan Kangas <stefan@marxist.se>
+
+ Extend the regexp shortdoc group
+
+ * lisp/emacs-lisp/shortdoc.el (regexp): New section "Match Data"; add
+ save-match-data. New section "The `rx' Structured Regexp Notation".
+
+2020-10-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document all parameters on `indent-relative'
+
+ * doc/lispref/text.texi (Relative Indent): Mention the FIRST-ONLY
+ parameter (bug#39330).
+
+2020-10-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Disable mml-sec-tests on MacOS
+
+ * test/lisp/gnus/mml-sec-tests.el (test-conf): Disable tests on
+ MacOS (bug#44259).
+
+2020-10-28 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Only recognize foo (*bar) as a function pointer when followed by (
+
+ * lisp/progmodes/cc-engine.el (c-forward-over-decl-or-cast-1): (after CASE 2)
+ test variables got-suffix-after-parens and at-decl-end before invoking
+ c-fdoc-shift-type-backward.
+
+2020-10-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Display times in a more human-readable way in list-timers
+
+ * lisp/emacs-lisp/timer-list.el (list-timers): Format the
+ intervals in a more human-readable way (bug#39956).
+
+2020-10-28 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/net/hmac-def.el: Use lexical-binding.
+
+2020-10-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust python tests after fix for bug#39398
+
+2020-10-28 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/net/eudc-vars.el: Use lexical-binding.
+
+2020-10-28 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in netrc.el and add tests
+
+ * lisp/net/netrc.el: Use lexical-binding.
+ (netrc-file): Remove redundant :group arg.
+ * test/lisp/net/netrc-resources/authinfo:
+ * test/lisp/net/netrc-resources/services:
+ * test/lisp/net/netrc-tests.el: New files.
+
+2020-10-28 Stefan Kangas <stefan@marxist.se>
+
+ Warn against using the MD4 hash function
+
+ * lisp/md4.el (md4): Warn against using it, since its security is
+ non-existent and it has been declared obsolete. It should probably
+ only be used by our NTLM support. Point users to secure-hash instead.
+
+2020-10-28 Dmitry Gutov <dgutov@yandex.ru>
+
+ css--complete-property-value: Limit the backward search
+
+ * lisp/textmodes/css-mode.el (css--complete-property-value):
+ Don't search back when ppss-innermost-start is nil (bug#44214).
+
+2020-10-28 Stefan Kangas <stefan@marxist.se>
+
+ Remove Emacs 20 compat code from ede/files.el
+
+ * lisp/cedet/ede/files.el (ede--put-inode-dir-hash)
+ (ede--get-inode-dir-hash, ede-project-directory-remove-hash)
+ (ede--directory-project-from-hash)
+ (ede--directory-project-add-description-to-hash): Remove Emacs 20
+ compat code.
+
+2020-10-28 Stefan Kangas <stefan@marxist.se>
+
+ Remove some compat code from feedmail.el
+
+ * lisp/mail/feedmail.el (feedmail-message-action-help-blat)
+ (feedmail-run-the-queue, feedmail-queue-send-edit-prompt-inner)
+ (feedmail-send-it-immediately): Remove compat code for XEmacs,
+ Emacs 19 and 20.
+
+2020-10-27 Stefan Kangas <stefan@marxist.se>
+
+ Remove some Emacs 20 compat code from speedbar.el
+
+ * lisp/speedbar.el (speedbar-easymenu-definition-trailer): Remove
+ Emacs 20 compat code.
+
+2020-10-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak how `C-c C-r' computes the region in python-mode
+
+ * lisp/progmodes/python.el (python-shell-buffer-substring): Don't
+ extend the region to the start of the line (bug#39398), but allow
+ sending the actual region as marked.
+
+2020-10-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make gnus-output-to-rmail appending work better
+
+ * lisp/gnus/gnus-util.el (gnus-output-to-rmail): Ensure we have a
+ blank line before the next line when using mbox format (bug#39580).
+
+2020-10-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix intermittent rmail-summary-delete-forward problem
+
+ * lisp/mail/rmailsum.el (rmail-summary-delete-forward):
+ `rmail-delete-message' may apparently clear
+ `rmail-current-message' sometimes, so save the message number
+ before deleting (bug#39612).
+
+2020-10-27 Mattias Engdegård <mattiase@acm.org>
+
+ gdb-mi: use lexical lambdas
+
+ * lisp/progmodes/gdb-mi.el (gdb-tooltip-print-1, gud-watch)
+ (gdb-var-list-children, gdb-edit-value)
+ (gdb-bind-function-to-buffer, gdb-place-breakpoints)
+ (gdb-preempt-existing-or-display-buffer):
+ Expose lambdas to the compiler as lexical closures instead of building
+ them the old-fashioned way. Remove #' before lambda.
+
+2020-10-27 Mattias Engdegård <mattiase@acm.org>
+
+ Remove unused function in gdb-mi.el
+
+ * lisp/progmodes/gdb-mi.el (gdb-var-evaluate-expression-handler):
+ Remove. (It was left behind in an old code reorganisation.)
+
+2020-10-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Fontify strings in {} better in tcl-mode"
+
+ This reverts commit 7f32224dc324b0ee0f1b512c8d8b19aeb80141c1.
+
+ The changes led to things like
+
+ proc foo5 () {
+ return 6
+ }
+
+ being fontified as a string, which is wrong.
+
+2020-10-27 Mauro Aranda <maurooaranda@gmail.com>
+
+ Small fix to the new link for inherited faces in Customize
+
+ * lisp/cus-edit.el (cus--face-link): Link to the current value of the
+ widget, rather than to the widget's value upon creation (bug#44154).
+
+2020-10-27 Clemens Radermacher <clemens.radermacher@posteo.de>
+
+ Fix NEWS entry for fix of Bug#44080
+
+2020-10-27 Eli Zaretskii <eliz@gnu.org>
+
+ * src/buffer.c (syms_of_buffer) <fill-column>: Improve doc string.
+
+2020-10-27 Mattias Engdegård <mattiase@acm.org>
+
+ gdb-mi: Don't use bindat for field access
+
+ Replace uses of bindat-get-field with a simpler accessor,
+ since nothing here uses the bindat machinery in any way.
+
+ * lisp/progmodes/gdb-mi.el (gdb-mi--field): New.
+ (gdb-get-many-fields): Remove.
+ (gdb-var-create-handler, gdb-var-list-children-handler)
+ (gdb-var-update-handler, gdb-current-buffer-frame)
+ (gdb-update-gud-running, gdb-thread-exited, gdb-thread-selected)
+ (gdb-running, gdb-stopped, gdb-breakpoints-list-handler-custom)
+ (gdb-place-breakpoints, gdb-thread-list-handler-custom)
+ (def-gdb-thread-buffer-simple-command, gdb-select-thread)
+ (def-gdb-thread-buffer-gud-command, gdb-read-memory-custom)
+ (gdb-invalidate-disassembly, gdb-disassembly-handler-custom)
+ (gdb-disassembly-place-breakpoints, gdb-toggle-breakpoint)
+ (gdb-delete-breakpoint, gdb-goto-breakpoint, gdb-frame-location)
+ (gdb-stack-list-frames-custom, gdb-select-frame)
+ (gdb-edit-locals-value, gdb-locals-handler-custom)
+ (gdb-registers-handler-custom, gdb-changed-registers-handler)
+ (gdb-register-names-handler, gdb-frame-handler):
+ Use gdb-mi--field.
+
+2020-10-27 Glenn Morris <rgm@gnu.org>
+
+ Temporarily mark two failing tests
+
+ * test/lisp/xt-mouse-tests.el (xt-mouse-tracking-basic)
+ (xt-mouse-tracking-utf-8): Currently failing.
+
+2020-10-27 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ e0de9f3295 (origin/emacs-27) Don't skip empty lines when fitting mini...
+ a4ec03fa9b ; * etc/tutorials/TUTORIAL.de: Fix grammar (Bug#44246)
+ 20c02e628c Improve documentation of display-fill-column-indicator
+ e2005f1f2a * INSTALL: Mention efaq.texi for installation of intlfonts.
+ 71661b2872 Use WebKit sandboxing
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-10-27 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ c847d5998f Merge branch 'emacs-27' of git.sv.gnu.org:/srv/git/emacs i...
+
+2020-10-27 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 8b87ea6844 Recommend lexical-binding in Coding Conventions
+ e29cace60a Avoid rare crashes while producing line numbers
+
+2020-10-27 Simen Heggestøyl <simenheg@gmail.com>
+
+ Complete property values in multi-line CSS declarations
+
+ * lisp/textmodes/css-mode.el (css--complete-property-value): Complete
+ property values even when preceded by a newline (bug#44214).
+
+2020-10-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix history problem in `M-x shell' when started twice
+
+ * lisp/comint.el (comint-input-ring-file-name): Avoid having this
+ variable being killed on mode restart while the other ring
+ variables aren't (bug#39667). This would mean that `M-x
+ shell'/`C-d'/`M-x shell' didn't save commands entered after the
+ second `M-x shell'.
+
+2020-10-27 Mattias Engdegård <mattiase@acm.org>
+
+ ERT: escape control characters in pretty-printed error output
+
+ * lisp/emacs-lisp/ert.el (ert--pp-with-indentation-and-newline):
+ Escape control characters which would otherwise be blasted directly to
+ the terminal (when running noninteractively) with unpleasant results.
+
+2020-10-27 Mattias Engdegård <mattiase@acm.org>
+
+ Fix sunrise and sunset calculation (bug#44237)
+
+ * lisp/calendar/solar.el (solar-moment): Use initial values for binary
+ search that won't end the loop prematurely and yield incorrect
+ answers.
+ * test/lisp/calendar/solar-tests.el: New file.
+
+2020-10-27 Mattias Engdegård <mattiase@acm.org>
+
+ Don't rely on bignums in ntlm.el
+
+ Since ntlm.el is distributed as a separate package in GNU ELPA and
+ should be able to run on older Emacs versions without bignums,
+ we cannot make use of them here. See discussion at
+ https://lists.gnu.org/archive/html/emacs-devel/2020-10/msg01665.html.
+ Instead, we add a small poor man's bignum implementation.
+
+ * lisp/net/ntlm.el (ntlm--bignat-of-int, ntlm--bignat-add)
+ (ntlm--bignat-shift-left, ntlm--bignat-mul-byte, ntlm--bignat-mul)
+ (ntlm--bignat-of-string, ntlm--bignat-of-digits)
+ (ntlm--bignat-to-int64): New.
+ (ntlm--time-to-timestamp): Use the ntlm--bignat- functions instead
+ of Lisp integers.
+ * test/lisp/net/ntlm-tests.el: New file.
+
+2020-10-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make edit-abbrevs parsing less brittle
+
+ * lisp/abbrev.el (define-abbrevs): Make the parsing less brittle
+ -- allow more blank lines (bug#42611).
+
+2020-10-27 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/net/sieve-mode.el: Use lexical-binding.
+
+2020-10-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a link to inherited faces in Customize
+
+ * lisp/cus-edit.el (cus--face-link): New function (bug#44154).
+ (face): Use the function to format the link.
+
+2020-10-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't do compilation-transform-file-match-alist if there's no file name
+
+ * lisp/progmodes/compile.el (compilation-error-properties): There
+ may not be a file name (bug#40111). In that case, don't do the
+ `compilation-transform-file-match-alist' thing.
+
+2020-10-27 Clemens Radermacher <clemens.radermacher@posteo.de>
+
+ Don't skip empty lines when fitting mini frame to buffer (Bug#44080)
+
+ * lisp/window.el (fit-mini-frame-to-buffer,
+ window--resize-mini-frame, fit-frame-to-buffer,
+ fit-frame-to-buffer-1): By default, fit a mini frame without skipping its
+ buffer's leading or trailing empty lines.
+ * src/frame.c (resize-mini-frames): Update doc-string.
+ * lisp/cus-start.el (resize-mini-frames): Update for customize.
+ * doc/lispref/minibuf.texi (resize-mini-frames): Update description.
+
+2020-10-27 Paul Pogonyshev <pogonyshev@gmail.com>
+
+ Don't leak result of nested byte-compilation to outer level
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-file): Bind
+ `byte-compiler-error-flag' instead of setting it (bug#41065).
+ This fixes a problem of "leaking" the flag when compiling
+ something that then compiles something that errors out (i.e., an
+ "inner" compile).
+
+2020-10-27 mvar <mvar.40k@gmail.com> (tiny change)
+
+ Fontify strings in {} better in tcl-mode
+
+ * lisp/progmodes/tcl.el (tcl-syntax-propertize-function):
+ Propertize {} forms after commands as strings (bug#39277).
+ (tcl-set-font-lock-keywords): Fontify as strings. This allows
+ things like puts {"foo} to be fontified correctly.
+
+2020-10-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ `g' in *Help* doesn't require confirmation
+
+ * lisp/help-mode.el (help-mode-revert-buffer): Don't require
+ confirmation before reverting (bug#44202). This mimics how most
+ other non-file reverting functions work.
+
+2020-10-27 Nicolas Graner <nicolas@graner.name>
+
+ Define backtab in text fields in eww
+
+ * lisp/net/eww.el (eww-text-map):
+ (eww-textarea-map): Define backtab, as in the main mode map
+ (bug#44247).
+
+2020-10-27 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/mail/mail-prsvr.el: Use lexical-binding.
+
+ * lisp/mail/mail-parse.el: Use lexical-binding.
+
+2020-10-27 Stefan Kangas <stefan@marxist.se>
+
+ Allow pcomplete/gzip to complete on files in subdirectories
+
+ * lisp/pcmpl-gnu.el (pcmpl-gnu-zipped-files): Allow "gzip" to complete
+ on files in subdirectories. (Bug#30271)
+
+2020-10-27 Boruch Baum <boruch_baum@gmx.com>
+
+ Add some missing docstrings in cua-rect.el
+
+ * lisp/emulation/cua-rect.el (cua--rectangle)
+ (cua--last-rectangle, cua--restored-rectangle)
+ (cua--rectangle-overlays, cua--rectangle-operation)
+ (cua--tabify-start, cua--tabify-start, cua--insert-rectangle):
+ Add docstrings, in several cases by converting existing
+ comments. (Bug#30085)
+ (cua--last-killed-rectangle): Update comment.
+
+2020-10-27 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in tool-bar.el
+
+ * lisp/tool-bar.el: Use lexical-binding.
+ (tool-bar-add-item, tool-bar-add-item-from-menu): Quote function
+ symbols as such.
+
+2020-10-27 Stefan Kangas <stefan@marxist.se>
+
+ Don't use obsolete variable write-contents-hooks
+
+ * lisp/mh-e/mh-show.el (mh-display-msg):
+ * lisp/textmodes/rst.el: Don't use obsolete variable
+ write-contents-hooks.
+ Problem reported by Stefan Monnier <monnier@iro.umontreal.ca>.
+
+2020-10-27 Stefan Kangas <stefan@marxist.se>
+
+ Remove XEmacs compat code from hashcash.el
+
+ * lisp/mail/hashcash.el (hashcash-point-at-bol)
+ (hashcash-point-at-eol): Make obsolete.
+ (hashcash-token-substring): Don't use the above now obsolete aliases.
+
+2020-10-26 Stephen Berman <stephen.berman@gmx.net>
+
+ Fix an unbound variable in html skeletons
+
+ * lisp/skeleton.el (skeleton-internal-list): Fix an unbound
+ variable in html skeletons (bug#44157).
+
+2020-10-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ vc-git-root: Remove unnecessary caching
+
+ * lisp/vc/vc-git.el (vc-git-root): Simplify (bug#42966).
+
+2020-10-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make vc-responsible-backend choose the most specific backend
+
+ * lisp/vc/vc.el (vc-responsible-backend): Search through all the
+ VC backends instead of the first one, and choose the one that's
+ most specific (bug#42966).
+
+2020-10-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix time-test error on machines with mail
+
+ * test/lisp/time-tests.el (time-tests-display-time-update): There
+ may be mail on the machine (bug#44241).
+
+2020-10-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the -modes variable autoloaded
+
+ * lisp/emacs-lisp/easy-mmode.el (define-globalized-minor-mode):
+ Make the -modes variable be autoloaded.
+
+2020-10-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak where global-display-fill-column-indicator-modes is on
+
+ * lisp/display-fill-column-indicator.el
+ (global-display-fill-column-indicator-mode): Don't switch on in
+ special-mode buffers (bug#44232).
+
+2020-10-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Implement a :predicate parameter for globalized minor modes
+
+ * doc/lispref/modes.texi (Defining Minor Modes): Describe the new
+ :predicate keyword (bug#44232).
+
+ * lisp/emacs-lisp/easy-mmode.el (define-globalized-minor-mode):
+ Allow a new :predicate keyword.
+ (easy-mmode--globalized-predicate-p): New function.
+
+2020-10-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make delete-selection-helper more resilient
+
+ * lisp/delsel.el (delete-selection-helper): Don't bug out on `C-g'
+ (bug#40357).
+
+2020-10-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak how shortdocs are displayed
+
+ * lisp/emacs-lisp/shortdoc.el (shortdoc-example): Removed.
+ (shortdoc-section): Remove colors.
+ (shortdoc-separator): New face.
+ (shortdoc-display-group, shortdoc--display-function): Don't use
+ background colours, because that makes things harder to read.
+ Separate with a horizontal line instead.
+
+2020-10-26 Andrea Corallo <akrl@sdf.org>
+
+ Make native compiler tollerant to redefined primitives (bug#44221).
+
+ * lisp/emacs-lisp/comp.el (comp-emit-set-call-subr): Rework based
+ on the fact that the subr can now be redefined.
+ * test/src/comp-tests.el (primitive-redefine-compile-44221):
+ New testcase.
+
+2020-10-26 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid segfaults due to using fonts that were closed
+
+ * src/composite.c (composition_gstring_cache_clear_font): New
+ function.
+ * src/composite.h (composition_gstring_cache_clear_font): Add
+ prototype.
+ * src/font.c (font_clear_cache): When we are about to close a
+ font, remove from the gstring cache any lgstring that uses this
+ font. (Bug#42943)
+
+2020-10-26 Mattias Engdegård <mattiase@acm.org>
+
+ Revert "Don't consider play-sound-file to be a 'safe' function (bug#44018)"
+
+ This reverts commit cdb3c9d662c772ce25ea4d803eccd2c9e6a6ae99.
+
+2020-10-26 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of display-fill-column-indicator
+
+ * lisp/display-fill-column-indicator.el
+ (display-fill-column-indicator-mode): Mention the globalized
+ version in the doc string.
+
+ * doc/emacs/display.texi (Displaying Boundaries): Improve and
+ clarify the documentation of display-fill-column-indicator.
+ Suggest using the minor mode as the primary means for turning the
+ feature on.
+
+ * src/xdisp.c (syms_of_xdisp) <display-fill-column-indicator>
+ <display-fill-column-indicator-character>: Doc fix. (Bug#44226)
+
+2020-10-26 Mattias Engdegård <mattiase@acm.org>
+
+ Don't consider play-sound-file to be a 'safe' function (bug#44018)
+
+ While there are currently no known security holes in play-sound-file,
+ the attack surface is considerable and historically audio file
+ processing has had more than its share of security problems; the
+ benefit to risk ratio is low.
+
+ * lisp/emacs-lisp/unsafep.el: Don't mark play-sound-file as safe.
+
+2020-10-25 Andrea Corallo <akrl@sdf.org>
+
+ Fix defsubst effectiveness (bug#44209)
+
+ * lisp/emacs-lisp/byte-run.el (defsubst): Fix macro definition.
+ * test/src/comp-tests.el (comp-test-defsubst): New testcase.
+ * test/src/comp-test-funcs.el (comp-test-defsubst-f): New
+ function.
+
+2020-10-25 Andrea Corallo <akrl@sdf.org>
+
+ Fix a function for native compilation in cc-bytecomp.el
+
+ * lisp/progmodes/cc-bytecomp.el
+ (cc-bytecomp-compiling-or-loading): Update for native compilation.
+
+2020-10-25 Stefan Kangas <stefan@marxist.se>
+
+ Add section "Replacing Match" to the regexp shortdoc group
+
+ * lisp/emacs-lisp/shortdoc.el (regexp): New section "Replacing Match".
+
+2020-10-25 Stefan Kangas <stefan@marxist.se>
+
+ Remove some Emacs 19 compat code and references
+
+ * lisp/progmodes/sql.el:
+ * lisp/mh-e/mh-show.el (mh-display-msg): Remove Emacs 19 compat code.
+ * lisp/emacs-lisp/edebug.el (edebug-mark-marker): Make into
+ obsolete alias for mark-marker.
+ (edebug--display-1, edebug-bounce-point)
+ (edebug-outside-excursion): Adjust callers.
+ * lisp/net/snmp-mode.el:
+ * lisp/forms.el: Remove references to Emacs 19.
+ (forms-use-text-properties): Doc fix.
+
+2020-10-25 Eli Zaretskii <eliz@gnu.org>
+
+ Improve support for shaping Egyptian Hieroglyphs
+
+ * src/composite.c (composition_gstring_lookup_cache): Renamed from
+ gstring_lookup_cache and made external. All callers changed.
+ * src/composite.h (composition_gstring_lookup_cache): Add
+ prototype.
+ * src/font.c (Ffont_shape_gstring): Call
+ composition_gstring_lookup_cache and return the cached composition
+ if it is already in the cache.
+
+ * lisp/language/misc-lang.el (egyptian-shape-grouping): New
+ function.
+ (composition-function-table): Use egyptian-shape-grouping in
+ setting up compositions for Egyptian Hieroglyphs. Fix the
+ composition setup for horizontal and vertical joiners.
+
+2020-10-25 Andrea Corallo <akrl@sdf.org>
+
+ Fix ELC+ELN vs ELC prefix while building non AoT native compiled files
+
+ * lisp/Makefile.in (am__v_ELC_0): Set it correctly when
+ NATIVE_DISABLED is 1.
+
+2020-10-25 Mattias Engdegård <mattiase@acm.org>
+
+ Better file name in dynvars-check example
+
+ * doc/lispref/variables.texi (Converting to Lexical Binding):
+ Don't suggest an aggregate file name that matches the glob used when
+ generating it.
+
+2020-10-25 Andrea Corallo <akrl@sdf.org>
+
+ Report warnings and errors from native asynchronous compilation (bug#44168)
+
+ * lisp/emacs-lisp/comp.el (comp-last-scanned-async-output): New
+ buffer local variable.
+ (comp-accept-and-process-async-output): New function.
+ (comp-run-async-workers): Use
+ `comp-accept-and-process-async-output'.
+
+2020-10-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix syntax error in message-add-openpgp-header
+
+ * lisp/gnus/message.el (message-add-openpgp-header): Remove
+ redundant (and syntactically wrong) check.
+
+2020-10-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem when replacing the final char in checkdoc
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-autofix-ask-replace):
+ Ensure that the end-of-doc-string marker is really at the end,
+ even if we replace the final " char in the string (bug#44201).
+
+2020-10-25 Michael Albinus <michael.albinus@gmx.de>
+
+ * INSTALL: Mention efaq.texi for installation of intlfonts.
+
+2020-10-25 Andrea Corallo <akrl@sdf.org>
+
+ Fix `comp-dry-run' effectiveness
+
+ * lisp/emacs-lisp/comp.el (comp-compile-ctxt-to-file): Remove
+ `comp-dry-run' guard.
+ (comp-final): And move it here so is effective for interactive
+ sessions and non.
+
+2020-10-25 Philipp Stephani <phst@google.com>
+
+ Revert commit 1f44a776729adf9c6468a76f8310616fde62eeaa for XRef.
+
+ XRef supports Emacs versions back to Emacs 26.3, so it can’t use newer
+ functions such as ‘ert-resource-directory’.
+
+ * test/lisp/progmodes/xref-tests.el (xref-tests-data-dir): Don’t use
+ ‘ert-resource-directory’
+
+2020-10-25 Philipp Stephani <phst@google.com>
+
+ Revert commit 1f44a776729adf9c6468a76f8310616fde62eeaa for Flymake.
+
+ Flymake supports all Emacs versions back to 26.1, so it can’t use
+ ‘ert-resource-file’.
+
+ * test/lisp/progmodes/flymake-tests.el (flymake-tests-data-directory):
+ Recreate.
+ (flymake-tests--call-with-fixture): Stop using ‘ert-resource-file’.
+
+2020-10-25 Paul Eggert <eggert@cs.ucla.edu> (tiny change)
+ Qiantan Hong <qhong@mit.edu>
+
+ Use WebKit sandboxing
+
+ * src/xwidget.c (Fmake_xwidget): Enable sandboxing if WebKit 2.26
+ or later. Do this early, as required for sandboxing (Bug#43071).
+
+2020-10-25 Stefan Kangas <stefan@marxist.se>
+
+ Add shortdoc group for alist
+
+ * lisp/emacs-lisp/shortdoc.el (alist): New shortdoc group.
+
+2020-10-25 Stefan Kangas <stefan@marxist.se>
+
+ Add shortdoc group for hash-table
+
+ * lisp/emacs-lisp/shortdoc.el (hash-table): New shortdoc group.
+
+2020-10-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ Minor doprnt cleanup: remove memchr call
+
+ * src/doprnt.c (doprnt): Remove unnecessary call to memchr.
+
+2020-10-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ Rename doprnt_nul to doprnt_non_null_end
+
+ * src/doprnt.c (doprnt_non_null_end): Rename from doprnt_nul,
+ as the old name was misleading (left over from a previous proposal).
+ Caller changed.
+
+2020-10-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ Improve doprnt performance
+
+ This patch implements some of my suggestions in Bug#8545,
+ with further changes suggested by Eli Zaretskii (Bug#43439).
+ * src/doprnt.c: Improve comments.
+ (SIZE_BOUND_EXTRA): Now at top level, for parse_format_integer.
+ (parse_format_integer): New static function, containing some of
+ the old doprnt. Fix a bug that caused doprnt to infloop on
+ formats like "%10s" that Emacs does not use. We could simplify
+ doprnt further if we dropped support for these never-used formats.
+ (doprnt_nul): New function.
+ (doprnt): Use it. Change doprnt API to exit when either it finds NUL
+ or reaches the character specified by FORMAT_END. In the typical case
+ where FORMAT_END is null, take just one pass over FORMAT, not two.
+ Assume C99 to make code clearer. Do not use malloc or alloca to
+ allocate a copy of the format FMTCPY; instead, use a small fixed-size
+ array FMTSTAR, and use '*' in that array to represent width and
+ precision, passing them as separate int arguments. Use eassume to
+ pacify GCC in switch statements.
+
+2020-10-24 Mauro Aranda <maurooaranda@gmail.com>
+
+ Warn about a bad default value in restricted-sexp widget
+
+ * lisp/wid-edit.el (restricted-sexp widget): New :value-to-external
+ function. If value is not in the internal format, then we might be
+ dealing with a bad default value for the widget, so display a warning
+ about that (bug#25152).
+
+2020-10-24 João Távora <joaotavora@gmail.com>
+
+ Rework semantics of eldoc-echo-are-use-multiline-p
+
+ Per bug#43543. Now uses logical lines, not visual lines.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-echo-area-use-multiline-p): Rework
+ semantics.
+ (eldoc--echo-area-substring): New helper.
+ (eldoc--echo-area-prefer-doc-buffer-p): New helper.
+ (eldoc-display-in-echo-area): Rework using new helpers.
+
+2020-10-24 João Távora <joaotavora@gmail.com>
+
+ Rename ElDoc user option controlling display of truncation notice
+
+ The new name makes it consistent with other variables controlling the
+ display of ElDoc documentation in the echo area.
+
+ Per bug#43543.
+
+ * etc/NEWS (Eldoc): Rename eldoc-display-truncation-message to
+ eldoc-echo-area-display-truncation-message.
+
+ * lisp/emacs-lisp/eldoc.el
+ (eldoc-echo-area-display-truncation-message): Rename from
+ eldoc-display-truncation-message.
+ (eldoc-display-in-echo-area): Use new variable name.
+
+2020-10-24 João Távora <joaotavora@gmail.com>
+
+ Rework eldoc-echo-area-prefer-doc-buffer (bug#42532)
+
+ * lisp/emacs-lisp/eldoc.el:
+ (eldoc-echo-area-prefer-doc-buffer): Rename from
+ eldoc-echo-area-prefer-doc-buffer
+ (eldoc-display-in-echo-area): Rework to honour
+ eldoc-echo-area-prefer-doc-buffer.
+
+2020-10-24 João Távora <joaotavora@gmail.com>
+
+ Introduce eldoc-display-functions
+
+ See bug#43609.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc--request-state): Add comment.
+ (eldoc--last-request-state): No longer buffer-local.
+ (eldoc--request-docs-p): Delete.
+ (eldoc-display-functions): New user variable.
+ (eldoc--doc-buffer-docs): New variable.
+ (eldoc-display-message-p): Rework.
+ (eldoc--format-doc-buffer): Rework from eldoc--handle-docs.
+ (eldoc-display-in-echo-area, eldoc-display-in-buffer): New
+ user-visible function.
+ (eldoc--invoke-strategy): Take INTERACTIVE arg.
+ Invoke eldoc-display-in-buffer
+ (eldoc-print-current-symbol-info): Simplify.
+ (Version): Bump to 1.11.0
+
+ * etc/NEWS: Mention eldoc-display-functions.
+
+2020-10-24 Stefan Kangas <stefan@marxist.se>
+
+ Re-introduce variable for world clock timer
+
+ * lisp/time.el (world-clock--timer): New variable.
+ (world-clock): Save timer to above variable when it is started.
+ (world-clock-cancel-timer): Delete timer saved in variable instead of
+ searching for the function name.
+
+2020-10-24 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in several language support libraries
+
+ * lisp/language/burmese.el:
+ * lisp/language/cham.el:
+ * lisp/language/czech.el:
+ * lisp/language/georgian.el:
+ * lisp/language/greek.el:
+ * lisp/language/khmer.el:
+ * lisp/language/romanian.el:
+ * lisp/language/sinhala.el:
+ * lisp/language/slovak.el:
+ * lisp/language/tai-viet.el:
+ * lisp/language/vietnamese.el: Use lexical-binding.
+
+2020-10-24 Michael Albinus <michael.albinus@gmx.de>
+
+ Accept nil COMMAND in tramp-sh-handle-make-process (Bug#44151)
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process): Accept nil
+ COMMAND. (Bug#44151)
+
+ * test/lisp/net/tramp-tests.el (tramp-test29-start-file-process):
+ Extend test.
+
+2020-10-24 Stefan Kangas <stefan@marxist.se>
+
+ Revert "Use lexical-binding in bindat.el"
+
+ This reverts commit a497b8e4a41e3223089654da4b36d0fdd51ce555.
+
+ This conversion to lexical-binding broke the eval specification,
+ documented in the ELisp manual. We will probably want to add tests
+ for that before we can confidently convert this to lexical-binding.
+ Problem reported by Mattias Engdegård <mattiase@acm.org>.
+
+2020-10-24 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in most term libraries
+
+ * lisp/term/AT386.el:
+ * lisp/term/internal.el:
+ * lisp/term/iris-ansi.el:
+ * lisp/term/lk201.el:
+ * lisp/term/news.el:
+ * lisp/term/rxvt.el:
+ * lisp/term/sun.el:
+ * lisp/term/tvi970.el:
+ * lisp/term/wyse50.el: Use lexical-binding.
+
+2020-10-24 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in copyright.el and add tests
+
+ * lisp/emacs-lisp/copyright.el: Use lexical-binding. Remove
+ redundant :group args.
+ * test/lisp/emacs-lisp/copyright-tests.el: New file.
+
+2020-10-24 Stefan Kangas <stefan@marxist.se>
+
+ * test/manual/image-transforms-tests.el: Use lexical-binding.
+
+2020-10-24 Stefan Kangas <stefan@marxist.se>
+
+ Move faces.el test data to follow our conventions
+
+ * test/lisp/faces-tests.el (ert-x): Require.
+ (faces--test-data-dir): Remove variable.
+ (faces--test-extend-with-themes): Use ert-resource-directory.
+ * test/lisp/faces-resources/*: Moved from test/data/themes/*.
+
+2020-10-24 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix tramp-sh-handle-make-process; don't merge with master
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process): Accept nil
+ COMMAND. (Bug#44151)
+
+ * test/lisp/net/tramp-tests.el (tramp-test29-start-file-process):
+ Extend test.
+
+2020-10-24 Jared Finder <jared@finder.org>
+
+ Fix a bug where the wrong menu would be triggered by mouse
+
+ For layouts such as the following, clicking the "l" in Tools with the
+ right window focused would trigger the File menu, not the Tools menu.
+ This is because the event would have window coordinate (1 . 0).
+ Similarly, clicking the "p" in Help would trigger the Edit menu.
+
+ Example Emacs frame:
+ +--------------------------------------------------------+
+ |File Edit Options Buffers Tools Help |
+ |;; This buffer is for text$|;; This buffer is for text $|
+ |;; To create a file, visit$|;; To create a file, visit $|
+ | | |
+ | | |
+ |-UUU:----F1 *scratch* |-UUU:----F1 *scratch* |
+ | |
+ +--------------------------------------------------------+
+ * lisp/menu-bar.el (menu-bar-open-mouse): Reject clicks not on
+ the menu bar.
+ *lisp/xt-mouse.el (xterm-mouse-event): Pass the current frame to
+ 'posn-at-x-y', to make the effect consistent with other mouse-handling
+ features.
+
+2020-10-24 Jared Finder <jared@finder.org>
+
+ Enable TTY menus with xterm-mouse-mode
+
+ * lisp/tmm.el: No need to bind 'tmm-menubar-mouse' to mouse clicks
+ on the menu bar.
+ * lisp/menu-bar.el (global-map): Bind 'menu-bar-open-mouse' to
+ mouse click on menu bar. This is needed in xt-mouse.
+
+ * etc/NEWS: Announce TTY menu support in xterm-mouse-mode.
+
+2020-10-24 Jared Finder <jared@finder.org>
+
+ Make TTY menus work with xterm-mouse-mode
+
+ * src/term.c (mouse_get_xy): Call 'mouse_position' passing it the
+ value of 'tty-menu-calls-mouse-position-function' as the
+ argument.
+ (syms_of_term) <tty-menu-calls-mouse-position-function>: New
+ DEFVAR_BOOL.
+ * src/frame.c (mouse_position): New function, with most of the
+ code from Fmouse_position, but call 'mouse-position-function' only
+ if called with non-zero argument.
+ (Fmouse_position): Call 'mouse_position' to do the job.
+
+ * lisp/xt-mouse.el (xterm-mouse-translate-1): Respect
+ 'track-mouse'.
+ (xterm-mouse-mode): Set 'tty-menu-calls-mouse-position-function'
+ when setting 'mouse-position-function'.
+ (xterm-mouse-tracking-enable-sequence): Use SET_ANY_EVENT_MOUSE
+ (0x1003) so that mouse movement can be reported even if no buttons
+ are pressed. Doc fix.
+ * lisp/menu-bar.el (menu-bar-define-mouse-key): New function.
+ (tty-menu-navigation-map): Call it.
+
+ * doc/lispref/frames.texi (Mouse Position): Document
+ 'tty-menu-calls-mouse-position-function'.
+
+ * etc/NEWS: Announce 'tty-menu-calls-mouse-position-function'.
+
+2020-10-24 Jared Finder <jared@finder.org>
+
+ Adding mouse controls to menu-bar.el.
+
+ * lisp/isearch.el (tmm-menubar-keymap): Remove declare-function.
+ * lisp/menu-bar.el (menu-bar-open-mouse, menu-bar-keymap)
+ (menu-bar-current-active-maps, menu-bar-item-at-x): New functions.
+ *lisp.tmm.el (tmm-menubar-keymap, tmm-get-keybind): Functions
+ deleted.
+ (tmm-menubar): Call 'menu-bar-item-at-x'.
+
+2020-10-24 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change in image.c for MS-Windows
+
+ * src/image.c [LIBRSVG_CHECK_VERSION (2, 46, 0)]: Define
+ prototype for rsvg_handle_get_geometry_for_layer.
+ (init_svg_functions) [LIBRSVG_CHECK_VERSION (2, 46, 0)]: Load
+ rsvg_handle_get_geometry_for_layer from the DLL, instead of
+ rsvg_handle_get_dimensions.
+ (rsvg_handle_get_geometry_for_layer) [LIBRSVG_CHECK_VERSION (2, 46, 0)]:
+ Define macro. (Bug#44065)
+
+2020-10-24 Stefan Kangas <stefan@marxist.se>
+
+ Fix a broken unsafep test
+
+ * test/lisp/emacs-lisp/unsafep-tests.el
+ (test-unsafep/message): Fix test case.
+
+ (unsafep-tests--safe): Rename from testcover-unsafep-safe.
+ (unsafep-tests--unsafe): Rename from testcover-unsafep-unsafe.
+ (test-unsafep/safe, test-unsafep/unsafe): Doc fix. Adjust usage
+ of above renamed variables.
+
+2020-10-24 Stefan Kangas <stefan@marxist.se>
+
+ Move epg.el test data to follow our conventions
+
+ * test/lisp/epg-tests.el (ert-x): Require.
+ (epg-tests-data-directory): Remove variable.
+ (with-epg-tests): Use ert-resource-file.
+ * test/lisp/epg-resources/*: Moved from test/data/epg/.
+
+2020-10-24 Stefan Kangas <stefan@marxist.se>
+
+ Move shr.el test data to follow our conventions
+
+ * test/lisp/net/shr-tests.el (ert, ert-x): Require.
+ (shr-tests--datadir): Remove variable.
+ (shr-test, rendering): Use ert-resource-directory.
+ * test/lisp/net/shr-resources/*: Move from test/data/shr/.
+
+2020-10-24 Stefan Kangas <stefan@marxist.se>
+
+ Move mml-sec.el test data to follow our conventions
+
+ * test/lisp/gnus/mml-sec-tests.el (ert-x): Require.
+ (mml-secure-test-fixture, mml-sec-test--kill-gpg-agent):
+ Use ert-resource-directory.
+ * test/lisp/gnus/mml-sec-resources/*: Moved from test/data/mml-sec/.
+ * .gitignore: Update location of moved file "random_seed".
+
+2020-10-23 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-10-23 Stefan Kangas <stefan@marxist.se>
+
+ Move more test data to follow our conventions
+
+ * test/data/minibuffer-test-cttq$tion: Move from here...
+ * test/lisp/minibuffer-resources/data/minibuffer-test-cttq$tion:
+ ...to here.
+ * test/lisp/minibuffer-resources/lisp/cedet/semantic-utest-c.test:
+ * test/lisp/minibuffer-resources/lisp/cedet/semantic-utest.test:
+ New files.
+ * test/lisp/minibuffer-tests.el (ert, ert-x): Require.
+ (completion-table-test-quoting): Use ert-resource-directory.
+
+ * test/data/net/cert.pem:
+ * test/data/net/key.pem: Move from here...
+ * test/lisp/net/network-stream-resources/cert.pem:
+ * test/lisp/net/network-stream-resources/key.pem: ...to here.
+ * test/lisp/net/network-stream-tests.el (ert, ert-x): Require.
+ (network-stream-tests--datadir): Remove variable.
+ (make-tls-server): Use ert-resource-file.
+
+ * test/data/vc/diff-mode/hello_emacs.c:
+ * test/data/vc/diff-mode/hello_emacs_1.c:
+ * test/data/vc/diff-mode/hello_world.c:
+ * test/data/vc/diff-mode/hello_world_1.c: Move from here...
+ * test/lisp/vc/diff-mode-resources/hello_emacs.c:
+ * test/lisp/vc/diff-mode-resources/hello_emacs_1.c:
+ * test/lisp/vc/diff-mode-resources/hello_world.c:
+ * test/lisp/vc/diff-mode-resources/hello_world_1.c: ...to here.
+ * test/lisp/vc/diff-mode-tests.el (ert, ert-x): Require.
+ (diff-mode-tests--datadir): Remove variable.
+ (diff-mode-test-font-lock-syntax-one-line)
+ (diff-mode-test-font-lock): Use ert-resource-directory.
+
+ * test/data/xdg/l10n.desktop:
+ * test/data/xdg/malformed.desktop:
+ * test/data/xdg/mimeapps.list:
+ * test/data/xdg/mimeinfo.cache:
+ * test/data/xdg/test.desktop: Move from here...
+ * test/lisp/xdg-resources/l10n.desktop:
+ * test/lisp/xdg-resources/malformed.desktop:
+ * test/lisp/xdg-resources/mimeapps.list:
+ * test/lisp/xdg-resources/mimeinfo.cache:
+ * test/lisp/xdg-resources/test.desktop: ...to here.
+ * test/lisp/xdg-tests.el (ert-x): Require.
+ (xdg-tests-data-dir): Remove variable.
+ (xdg-desktop-parsing, xdg-mime-associations): Use ert-resource-file.
+
+2020-10-23 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix error in tramp-sh-handle-make-process
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process): Don't use heredoc
+ script whent the argument contains a string.
+
+2020-10-23 Stefan Kangas <stefan@marxist.se>
+
+ Move some test data to follow our conventions
+
+ * test/data/emacs-module/mod-test.c: Move from here...
+ * test/src/emacs-module-resources/mod-test.c: ...to here.
+ * test/src/emacs-module-tests.el (ert-x): Require.
+ (mod-test-file, module/describe-function-1):
+ * test/Makefile.in (test_module_dir): Adjust for move.
+
+ * test/data/files-bug18141.el.gz: Move from here...
+ * test/lisp/files-resources/files-bug18141.el.gz: ... to here.
+ * test/lisp/files-tests.el (ert-x): Require.
+ (files-test-bug-18141-file): Use ert-resource-file.
+
+ * test/data/mailcap/mime.types: Move from here...
+ * test/lisp/net/mailcap-resources/mime.types: ...to here.
+ * test/lisp/net/mailcap-tests.el (ert-x): Require.
+ (mailcap-tests-path): Use ert-resource-file.
+
+ * test/data/somelib.el:
+ * test/data/somelib2.el: Move from here...
+ * test/src/lread-resources/somelib.el:
+ * test/src/lread-resources/somelib2.el: ...to here.
+ * test/src/lread-tests.el (ert, ert-x): Require.
+ (lread-test-bug26837): Use ert-resource-directory.
+
+ * test/data/syntax-comments.txt: Move from here....
+ * test/src/syntax-resources/syntax-comments.txt: ...to here.
+ * test/src/syntax-tests.el (ert-x): Require.
+ (syntax-comments, syntax-br-comments, syntax-pps-comments):
+ Use ert-resource-file.
+
+ * test/data/xref/file1.txt:
+ * test/data/xref/file2.txt: Move from here...
+ * test/lisp/progmodes/xref-resources/file1.txt:
+ * test/lisp/progmodes/xref-resources/file2.txt: ...to here.
+ * test/lisp/progmodes/xref-tests.el (ert, ert-x): Require.
+ (xref-tests-data-dir): Use ert-resource-directory.
+
+2020-10-23 Eli Zaretskii <eliz@gnu.org>
+
+ Set up composition-function-table for Egyptian
+
+ * lisp/language/misc-lang.el (composition-function-table): Set up
+ for Egyptian Hieroglyphs.
+
+2020-10-23 Eli Zaretskii <eliz@gnu.org>
+
+ Remove most of charset markup from etc/HELLO
+
+ For the reasons, see the discussion that started in
+ https://lists.gnu.org/archive/html/emacs-devel/2018-12/msg00407.html
+ and its conclusion in
+ https://lists.gnu.org/archive/html/emacs-devel/2019-01/msg00144.html.
+ The only markup left is in the preamble, just to show the example
+ of this facility.
+
+2020-10-23 Olivier Certner <ocert.dev@free.fr> (tiny change)
+
+ ERC: Fix ERC's IBuffer format "crash" on killed server buffer
+
+ * lisp/erc/erc-ibuffer.el (erc-server-name): Fix a crash when
+ displaying (or updating) an IBuffer buffer using ERC's first IBuffer
+ format. This happens when one ERC buffer has its associated server
+ buffer killed, e.g., voluntarily or automatically after server
+ disconnection when `erc-kill-server-buffer-on-quit' is set to t. The
+ culprit is the "Server" column, which returns nil in this case.
+ Display "(closed)" instead (bug#44156).
+
+2020-10-23 Ruthra Kumar <ruthrab@gmail.com>
+
+ Add support for squashfs files in archive mode
+
+ * lisp/arc-mode.el (archive-squashfs-extract): New variable
+ (bug#43827).
+ (archive-find-type): Identify squashfs.
+ (archive-squashfs-summarize, archive-squashfs-extract-by-stdout):
+ New functions to parse/extract squashfs.
+
+ * lisp/files.el (auto-mode-alist): Add squashfs.
+
+2020-10-23 Ulf Jasper <ulf.jasper@web.de>
+
+ Move icalendar test data to test/lisp/calendar/icalendar-resources
+
+ * test/lisp/calendar/icalendar-tests.el (ert-x): Required for
+ 'ert-resource-file'.
+ (icalendar-tests--data-dir): Removed.
+ (icalendar-tests--get-file-contents): Use 'ert-resource-file' for
+ finding test data files.
+ * test/data/icalendar/*: Moved to test/lisp/calendar/icalendar-resources/.
+ * test/lisp/calendar/icalendar-resources/*: Moved from test/data/icalendar.
+
+2020-10-23 Stefan Kangas <stefan@marxist.se>
+
+ Clean up temporary files after package tests
+
+ * test/lisp/emacs-lisp/package-tests.el (with-package-test): Remove
+ temporary files after test. (Bug#43359)
+
+2020-10-23 Mattias Engdegård <mattiase@acm.org>
+
+ Use lexical binding in ffap.el
+
+ * lisp/ffap.el (ffap-search-backward-file-end): Remove binding for
+ variable shadowing an optional (and never used) argument.
+ (ffap--gopher-var-on-line): Remove unused variable.
+
+2020-10-23 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/emacs-lisp/pcase.el: Add "extensions" to keyword header.
+
+ Merge branch 'scratch/substitute-command-keys'
+
+2020-10-22 Juri Linkov <juri@linkov.net>
+
+ * etc/HELLO: Use JavaScript for Javanese script (bug#43887)
+
+2020-10-22 Alan Third <alan@idiocy.org>
+
+ Fix SVG image dimension calculations (bug#44065)
+
+ * src/image.c (svg_load_image): Calculate the image size by using the
+ viewBox size and applying it to the image.
+ * etc/PROBLEMS: Describe the problem with librsvg 2.45 and below.
+
+2020-10-22 Alan Third <alan@idiocy.org>
+
+ Fix crash when no face is defined (bug#44058, bug#43973)
+
+ * src/nsterm.m (ns_clear_under_internal_border): If face is null,
+ don't try drawing anything.
+
+2020-10-22 Stefan Kangas <stefan@marxist.se>
+
+ Remove incorrect use of decode-coding-string
+
+ * test/lisp/emacs-lisp/bindat-tests.el
+ (bindat-test-pack/multibyte-string-fails)
+ (bindat-test-unpack/multibyte-string-fails): Don't use
+ decode-coding-string.
+ Problem pointed out by Stefan Monnier <monnier@iro.umontreal.ca>.
+
+2020-10-22 Stefan Kangas <stefan@marxist.se>
+
+ Recommend lexical-binding in Coding Conventions
+
+ * doc/lispref/tips.texi (Coding Conventions, Library Headers):
+ Recommend using lexical-binding.
+
+2020-10-22 Andreas Schwab <schwab@linux-m68k.org>
+
+ eww: don't add keymap to <a> without href
+
+ * lisp/net/eww.el (eww-tag-a): Only add keymap if the href
+ attribute is present. (Bug#44147)
+
+2020-10-22 Stefan Kangas <stefan@marxist.se>
+
+ Add missed file needed by time-tests.el
+
+ * test/lisp/time-resources/non-empty: New file. This file is needed
+ by time-tests.el but was missed when it was committed.
+
+2020-10-22 Mattias Engdegård <mattiase@acm.org>
+
+ Remove useless uses of bindat-get-field
+
+ * lisp/progmodes/gdb-mi.el (gdb-var-list-children-handler)
+ (gdb-edit-register-value): bindat-get-field with a single argument is
+ identity; remove.
+
+2020-10-22 Stefan Kangas <stefan@marxist.se>
+
+ Add tests for perl-mode.el
+
+ * test/lisp/progmodes/perl-mode-tests.el: New file.
+
+2020-10-22 Ulf Jasper <ulf.jasper@web.de>
+
+ Move test data for icalendar tests to separate files.
+
+ * test/lisp/calendar/icalendar-tests.el
+ (icalendar-tests--data-dir, icalendar-tests--get-file-contents):
+ New.
+ (icalendar-tests--test-import, icalendar-tests--do-test-import):
+ Read input and expected results from files.
+ (icalendar-import-non-recurring, icalendar-import-rrule)
+ (icalendar-import-duration, icalendar-import-bug-6766)
+ (icalendar-import-bug-24199, icalendar-import-bug-33277)
+ (icalendar-import-multiple-vcalendars, icalendar-import-with-uid)
+ (icalendar-import-with-timezone, icalendar-real-world): Move test
+ data (input and expected result) to separate files.
+
+ * test/calendar/icalendar/*
+ New files containing test data for icalendar tests.
+
+2020-10-22 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in time-date.el and expand tests
+
+ * lisp/calendar/time-date.el: Use lexical-binding.
+ * test/lisp/calendar/time-date-tests.el
+ (test-obsolete-with-decoded-time-value)
+ (test-obsolete-encode-time-value, test-format-seconds)
+ (test-days-to-time, test-seconds-to-string): New tests.
+ (test-days-in-month, test-time-since, test-time-decoded-period):
+ Expand test with a few more values.
+
+2020-10-22 Mauro Aranda <maurooaranda@gmail.com>
+
+ Make State button interaction less confusing
+
+ * lisp/cus-edit.el (custom-variable-current-value): New function.
+ (custom-variable-backup-value): Use it.
+ (custom-variable-set, custom-variable-mark-to-reset-standard): Check
+ that old value is different than the new one. If it is, make a
+ backup. This way, we avoid offering the Set to Backup Value
+ unnecessarily.
+ (custom-variable-reset-saved): Reset the variable-comment property for
+ the variable, to help custom-variable-state be more correct. Also
+ check if we should backup old value.
+ (custom-variable-state): If a variable was set to the standard value,
+ say its state is standard rather than set, which is more correct.
+ Getting the right variable state is important for menu options to be
+ enabled/disabled, and for displaying the right message to the user
+ (bug#12864).
+
+2020-10-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use HTTP instead of Tramp for the ffap rfc path (and also fix it)
+
+ * lisp/ffap.el (ffap-rfc-path): Use an URL instead of an FTP tramp
+ file, since that's more widely supported (bug#41663).
+
+2020-10-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Comment JSX lines using JSX syntax
+
+ * lisp/progmodes/js.el (js-jsx--comment-region): New function
+ (bug#41696).
+ (js-jsx-mode): Use it.
+
+2020-10-22 Stefan Kangas <stefan@marxist.se>
+
+ Test for error with multibyte strings in bindat.el
+
+ * test/lisp/emacs-lisp/bindat-tests.el
+ (bindat-test-pack/multibyte-string-fails)
+ (bindat-test-unpack/multibyte-string-fails): New tests.
+
+2020-10-22 Mauro Aranda <maurooaranda@gmail.com>
+
+ Pretty print restricted sexp values too
+
+ * lisp/wid-edit.el (restricted-sexp widget): Use
+ widget-sexp-value-to-internal to pretty print the widget's value, when
+ it is a valid one (bug#7524).
+
+2020-10-22 Stefan Kangas <stefan@marxist.se>
+
+ Remove reference HP-UX 8.0 and 9.x bug from FAQ
+
+ * doc/misc/efaq.texi (Meta key does not work in xterm): Remove section
+ about a bug on HP-UX 8.0 and 9.x. Support for these platforms were
+ removed in 23.1.
+
+2020-10-22 Stefan Kangas <stefan@marxist.se>
+
+ Remove two references to Emacs 21 from the FAQ
+
+ * doc/misc/efaq.texi (Turning on syntax highlighting): Remove some
+ references to Emacs 21 and older.
+
+2020-10-22 Mauro Aranda <maurooaranda@gmail.com>
+
+ Allow moving members of editable-list widget, via delete+insert
+
+ * etc/NEWS (Widget): Announce the feature (bug#6419).
+ * lisp/wid-edit.el (widget-editable-list-delete-at): Save into a new
+ widget property, :last-deleted, the WIDGET to be deleted. Add
+ docstring.
+ (widget-editable-list-insert-before): If there is a recently deleted
+ child for the editable list, insert that one, instead of a new default
+ widget. Add docstring.
+ (insert-button widget): Make :help-echo a function to avoid the
+ help-echo string become too long.
+ (delete-button widget): Tweak the :help-echo string, to document this
+ behavior.
+
+ * test/lisp/wid-edit-tests.el (widget-test-moving-editable-list-item):
+ Test the feature.
+
+2020-10-22 Pip Cet <pipcet@gmail.com>
+
+ Handle Cairo errors in ftcrfont_open
+
+ * src/ftcrfont.c (ftcrfont_open): Handle Cairo errors (bug#41627).
+
+2020-10-22 Mattias Engdegård <mattiase@acm.org>
+
+ Use lexical binding in fortran.el
+
+ * lisp/progmodes/fortran.el: Use lexical binding.
+ (fortran-make-syntax-propertize-function): Hoist use of lexical
+ variable to outside the 'eval' call.
+
+2020-10-22 Mattias Engdegård <mattiase@acm.org>
+
+ * lisp/progmodes/cpp.el: Use lexical binding.
+
+2020-10-22 Werner Lemberg <wl@gnu.org>
+
+ Update TUTORIAL.de
+
+ This also includes the minor fix for bug #44123.
+
+2020-10-21 Štěpán Němec <stepnem@gmail.com>
+
+ unload-feature: Correct doc string to match info manual and reality
+
+ 'unload-feature' doesn't try to "undo any additions the library has
+ made" to hooks, it tries to remove functions defined by the library
+ from hooks, no matter how they got there.
+
+ * lisp/loadhist.el (unload-feature): Correct the doc string.
+ * doc/lispref/loading.texi (Unloading): Clarify, fix typo.
+
+2020-10-21 Štěpán Němec <stepnem@gmail.com>
+
+ unload-feature: Handle local hooks (bug#5293)
+
+ Buffer-local hooks were introduced in
+
+ 1994-09-30T20:47:13+00:00!rms@gnu.org
+ 0e4d378b32 (add-hook): Initialize default value and local value.
+
+ but 'unload-feature' has not been updated to handle them.
+
+ * lisp/loadhist.el (unload-feature): Handle local hooks (bug#5293).
+
+2020-10-21 Štěpán Němec <stepnem@gmail.com>
+
+ unload-feature: Improve logic (don't repeat computation)
+
+ * lisp/loadhist.el (unload-feature): Don't do the same computation twice.
+
+2020-10-21 Mattias Engdegård <mattiase@acm.org>
+
+ Convert artist.el to lexical binding
+
+ * lisp/textmodes/artist.el (artist-system, (artist-flood-fill):
+ Remove binding of the obsolete variables binary-process-input,
+ binary-process-output and input-queue.
+ (artist-down-mouse-1): Fix mistyped 'echo-keystrokes'; bind it to 0.
+ (artist-fill-rect, artist-fill-square, artist-pen-set-arrow-points)
+ (artist-spray-clear-circle, artist-spray-set-radius)
+ (artist-draw-ellipse-with-0-height, artist-fill-ellipse)
+ (artist-ff-is-topmost-line, artist-ff-is-bottommost-line)
+ (artist-set-arrow-points-for-2points, artist-key-undraw-continously)
+ (artist-key-undraw-poly, artist-key-undraw-1point)
+ (artist-key-undraw-2points, artist-key-do-continously-1point)
+ (artist-key-set-point-1point, artist-shift-has-changed)
+ (artist-mouse-draw-continously, artist-mouse-draw-1point)
+ (artist-submit-bug-report): Suppress warnings about unused parameters
+ which are there for function signature commonality. Remove unused
+ variables.
+
+2020-10-21 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid rare crashes while producing line numbers
+
+ * src/xdisp.c (maybe_produce_line_number): Prevent freeing of
+ realized faces for as long as we are using lnum_face_id and
+ current_lnum_face_id for producing glyphs. (Bug#44111)
+
+2020-10-21 Stefan Kangas <stefan@marxist.se>
+
+ Tweak two time.el tests
+
+ * test/lisp/time-tests.el (time-tests-display-time-update--load)
+ (time-tests-display-time-update): Tweak tests.
+
+2020-10-21 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/time.el: Use lexical-binding.
+
+2020-10-21 Stefan Kangas <stefan@marxist.se>
+
+ Add tests for time.el
+
+ * lisp/time.el (display-time-update--load)
+ (display-time-update--mail): Extract from...
+ (display-time-update): ...here.
+ * test/lisp/time-tests.el: New file.
+
+2020-10-21 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in bindat.el
+
+ * lisp/emacs-lisp/bindat.el: Use lexical-binding.
+ (bindat-raw, bindat-idx, bindat-unpack, bindat-pack): Adjust for
+ lexical-binding.
+ (bindat--unpack-group, bindat--length-group): Fix byte-compiler
+ warning about unused variables last and vlen.
+ (bindat--unpack-group, bindat--length-group, bindat--pack-group)
+ (bindat-format-vector): Quote function symbols as such.
+
+2020-10-21 Stefan Kangas <stefan@marxist.se>
+
+ Remove some compat code from uudecode.el and binhex.el
+
+ * lisp/mail/uudecode.el (uudecode-char-int): Make obsolete.
+ (uudecode-decode-region-internal): Adjust callers.
+ * lisp/mail/binhex.el (binhex-char-int): Make obsolete.
+ (binhex-string-big-endian, binhex-string-little-endian)
+ (binhex-header): Adjust callers.
+
+2020-10-21 Stefan Kangas <stefan@marxist.se>
+
+ Declare old compat aliases in tcl.el obsolete
+
+ * lisp/progmodes/tcl.el (tcl-uncomment-region)
+ (tcl-indent-for-comment, add-log-tcl-defun, indent-tcl-exp)
+ (calculate-tcl-indent, tcl-beginning-of-defun, tcl-end-of-defun)
+ (tcl-mark-defun, tcl-mark): Make obsolete.
+
+2020-10-21 Stefan Kangas <stefan@marxist.se>
+
+ Add some top level domains
+
+ * lisp/mail/mail-extr.el (mail-extr-all-top-level-domains): Add
+ some geographic domains.
+
+2020-10-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Add emoji to etc/HELLO"
+
+ This reverts commit a1fcdeec25be87e8f97ac5c14e6fbf6a4d1eb2d4.
+
+ There was already an emoji in there.
+
+2020-10-21 Stefan Kangas <stefan@marxist.se>
+
+ * test/lisp/vc/vc-bzr-tests.el: Use lexical-binding.
+
+2020-10-21 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in files-x-tests.el
+
+ * test/lisp/files-x-tests.el: Use lexical-binding.
+ (remote-null-device): Declare.
+
+2020-10-21 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in iso-ascii.el
+
+ * lisp/international/iso-ascii.el: Use lexical-binding. Remove
+ redundant :group args.
+
+2020-10-21 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in hfy-cmap.el and add tests
+
+ * lisp/hfy-cmap.el: Use lexical-binding.
+ (hfy-cmap--parse-buffer): Extract from...
+ (htmlfontify-load-rgb-file): ...here.
+
+ * test/lisp/hfy-cmap-resources/rgb.txt:
+ * test/lisp/hfy-cmap-tests.el: New files.
+
+2020-10-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add emoji to etc/HELLO
+
+2020-10-21 Michael Albinus <michael.albinus@gmx.de>
+
+ * etc/HELLO: Keep Javanese System.out.println("");
+
+2020-10-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/outline.el: Use lexical-binding
+
+ Remove redundant `group` arguments.
+ (outline-level): Move before first use.
+ (outline-mode): Use `setq-local`.
+ (outline-isearch-open-invisible-function): Give it a non-nil default.
+
+2020-10-20 Andrea Corallo <akrl@sdf.org>
+
+ Sanitize eln filename when native compiling single functions
+
+ * lisp/emacs-lisp/comp.el (comp-spill-lap-function): Fix
+ temporary eln name generation.
+
+ * test/src/comp-tests.el (free-fun-silly-name): New testcase.
+
+2020-10-20 Andrea Corallo <akrl@sdf.org>
+
+ Have `native-compile' do not expose `with-late-load' parameter
+
+ This is really for internal use only by deferred compilation.
+
+ * lisp/emacs-lisp/comp.el (comp-trampoline-compile)
+ (comp-run-async-workers): Make use of `comp--native-compile'.
+ (comp--native-compile): New function.
+ (native-compile, batch-native-compile): Make use of
+ `comp--native-compile'.
+
+2020-10-20 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in m4-mode.el
+
+ * lisp/progmodes/m4-mode.el: Use lexical-binding. Remove redundant
+ :group args.
+ * lisp/progmodes/m4-mode.el (m4-m4-buffer, m4-m4-region): Quote
+ function symbols as such.
+
+2020-10-20 Stefan Kangas <stefan@marxist.se>
+
+ Make more load-hooks obsolete (Bug#21563)
+
+ * lisp/progmodes/dcl-mode.el (dcl-mode):
+ * lisp/progmodes/idlw-complete-structtag.el: Recommend
+ with-eval-after-load instead of load-hooks.
+ * lisp/calc/calc-ext.el (calc-ext-load-hook):
+ * lisp/emacs-lisp/bytecomp.el (bytecomp-load-hook):
+ * lisp/emacs-lisp/cl-extra.el (cl-extra-load-hook):
+ * lisp/emacs-lisp/cl-macs.el (cl-macs-load-hook):
+ * lisp/emacs-lisp/cl-seq.el (cl-seq-load-hook):
+ * lisp/gnus/message.el (message-load-hook):
+ * lisp/gnus/nnheader.el (nnheader-load-hook):
+ * lisp/gnus/nnmail.el (nnmail-load-hook):
+ * lisp/progmodes/dcl-mode.el (dcl-mode-load-hook):
+ * lisp/textmodes/tex-mode.el (tex-mode-load-hook):
+ * lisp/whitespace.el (whitespace-load-hook): Obsolete for
+ with-eval-after-load. Note that these variables are never declared,
+ but the byte-compiler will still warn about them if used.
+
+2020-10-20 Stefan Kangas <stefan@marxist.se>
+
+ byte-compile-file: Make optional LOAD argument obsolete
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-file): Declare optional
+ LOAD argument obsolete. Adjust callers. (Bug#38072)
+ (byte-recompile-file): Declare optional LOAD argument obsolete.
+ * doc/lispref/compile.texi (Compilation Functions): Update
+ documentation to reflect above obsoletion.
+ * etc/NEWS: Announce above obsoletion.
+
+2020-10-20 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Simplify regexp in last change to woman.el
+
+ * lisp/woman.el (woman-decode-region): Use simpler character
+ alternative instead of alternation.
+
+2020-10-20 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Simplify syntax of shortdoc face specs
+
+ * lisp/emacs-lisp/shortdoc.el: Remove unused dependency.
+ (shortdoc-section, shortdoc-example): Use newer (DISPLAY . PLIST)
+ face spec syntax.
+
+2020-10-20 Stefan Kangas <stefan@marxist.se>
+
+ Tweak test data for signed package installation
+
+ * test/lisp/emacs-lisp/package-resources/signed/signed-bad-1.0.el:
+ * test/lisp/emacs-lisp/package-resources/signed/signed-good-1.0.el:
+ Use lexical-binding.
+ * test/lisp/emacs-lisp/package-resources/signed/update-signatures.sh:
+ New file.
+ * test/lisp/emacs-lisp/package-resources/key.pub:
+ * test/lisp/emacs-lisp/package-resources/key.sec: Add new key.
+ * test/lisp/emacs-lisp/package-resources/signed/signed-good-1.0.el.sig:
+ * test/lisp/emacs-lisp/package-resources/signed/archive-contents.sig:
+ Update signatures using new key.
+
+2020-10-20 Mattias Engdegård <mattiase@acm.org>
+
+ * lisp/textmodes/picture.el: Use lexical binding.
+
+2020-10-20 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid assertion violations in malformed Unicode escapes
+
+ * src/lread.c (read_escape): Produce better diagnostic for
+ malformed \u Unicode escapes, while avoiding assertion violation
+ when READCHAR returns -1 because the input is exhausted.
+ (Bug#44084)
+
+2020-10-20 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/language/utf-8-lang.el: Use lexical-binding.
+
+2020-10-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak the documentation for define-obsolete-variable-alias
+
+ * doc/lispref/variables.texi (Variable Aliases): Actually describe
+ the macro parameters (bug#44088).
+
+ * lisp/emacs-lisp/byte-run.el (define-obsolete-variable-alias):
+ Ditto (bug#44088).
+
+2020-10-20 Masahiro Nakamura <tsuucat@icloud.com>
+
+ Fix some mpc.el updating quirks
+
+ * lisp/mpc.el (mpc-songs-jump-to): Update the status buffer.
+
+ * lisp/mpc.el (mpc-stop): M-x mpc-stop clears playlist queue. So
+ updating *MPC-Songs* buffer is useful.
+
+ * lisp/mpc.el (mpc-cmd-delete): I noticed M-x mpc-playlist-delete
+ always messages “Deleted 1 songs” even if playlist queue has more
+ than one songs. This is because mpc-cmd-delete’s sort modifies
+ songs-poss by side effect. Using copy-sequence fixes this (bug#44093).
+ * lisp/mpc.el (mpc-cmd-move): Ditto.
+
+2020-10-20 Jim Blandy <jimb@red-bean.com>
+
+ Man highlighting: Don't occasionally bold entire sections.
+
+ * lisp/ansi-color.el (ansi-color-apply-on-region): Always save a
+ restart position in ansi-color-context-region if the region ends with
+ highlighting active.
+
+2020-10-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Preserve all `eval' elements from both .dir-locals files
+
+ * lisp/files.el (dir-locals-read-from-dir): Preserve all `eval'
+ elements from both .dir-locals files (bug#44066).
+
+2020-10-20 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/image-file.el: Use lexical-binding.
+
+2020-10-20 Stefan Kangas <stefan@marxist.se>
+
+ Make a bookmark test more robust
+
+ * test/lisp/bookmark-tests.el (bookmark-tests-insert-annotation):
+ Make test more robust by not being timing dependent.
+
+2020-10-19 Stefan Kangas <stefan@marxist.se>
+
+ Add command package-menu-filter-upgradable
+
+ * lisp/emacs-lisp/package.el (package-menu-filter-upgradable):
+ New command. (Bug#41436)
+ (package-menu-mode-map): Bind the new command.
+ * doc/emacs/package.texi (Package Menu): Document the new command.
+
+2020-10-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/python.el: Bump version to release the f-string support
+
+2020-10-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/mail/rfc2231.el (rfc2231-decode-encoded-string): Fix match data error
+
+ Get (match-string 3 string) earlier, in case `mm-charset-to-coding-system`
+ clobbers the match data.
+ Also, check that `string-match` succeeded before using its match data.
+
+2020-10-19 Protesilaos Stavrou <info@protesilaos.com>
+
+ Fix documentation of the Modus Themes (Bug#43944)
+
+ * doc/misc/modus-themes.texi (Installation): Remove reference to MELPA.
+ (Top)
+ (Install from the archives, GNU Guix)
+ (Load at a given time or at sunset/sunrise)
+ (Configure options prior to loading, Command prompts)
+ (Headings' font, Will NOT be supported): Fix spelling, wording,
+ markup.
+ (Acknowledgements): Spell contributor's surname correctly.
+
+2020-10-19 Stefan Kangas <stefan@marxist.se>
+
+ Make auto-revert-mode tests run faster
+
+ * test/lisp/autorevert-tests.el (auto-revert--timeout): Make into
+ defun and shorten timeout by a factor 10.
+ (auto-revert--wait-for-revert): Cut timeouts in half.
+ (with-auto-revert-test): New macro to set timeout to 0.1.
+ (auto-revert-tests--write-file): New defun.
+ (auto-revert-test00-auto-revert-mode)
+ (auto-revert-test01-auto-revert-several-files)
+ (auto-revert-test02-auto-revert-deleted-file)
+ (auto-revert-test03-auto-revert-tail-mode)
+ (auto-revert-test04-auto-revert-mode-dired)
+ (auto-revert-test05-global-notify)
+ (auto-revert-test06-write-file): Adapt test to run faster. Remove
+ :expensive-test marks.
+
+ This was discussed in:
+ https://lists.gnu.org/r/emacs-devel/2020-10/msg01233.html
+
+2020-10-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Further clarification of directory-files* doc
+
+ * doc/lispref/files.texi (Contents of Directories):
+ Precise description of MATCH-REGEXP of directory-files. Add
+ directory-files-no-dot-files-regexp.
+
+ * lisp/files.el (directory-files-no-dot-files-regexp): Revert last fix.
+
+ * src/dired.c (Fdirectory_files)
+ (Fdirectory_files_and_attributes): Fix wording in docstring.
+
+2020-10-19 Mattias Engdegård <mattiase@acm.org>
+
+ Keep track of matching rules in compilation-mode
+
+ When matching messages in compilation-mode, keep track of the rule
+ employed for each match. This facilitates debugging and allows us to
+ verify that each test case really exercises the rule that we expect it
+ to.
+
+ Naturally this uncovered several test cases that didn't check what the
+ author thought they did; the rules affixed to
+ compile-tests--test-regexps-data are those actually used, so that the
+ tests still pass.
+
+ * lisp/progmodes/compile.el (compilation--message): Add 'rule' slot.
+ (compilation-directory-properties, compilation-error-properties)
+ (compilation-internal-error-properties, compilation-parse-errors)
+ (compilation--compat-parse-errors): Set the rule slot.
+ * test/lisp/progmodes/compile-tests.el (compile-tests--test-regexps-data)
+ (compile-tests--grep-regexp-testcases)
+ (compile-tests--grep-regexp-tricky-testcases): Add rules to test cases.
+ (compile--test-error-line): Check that the rule matches what we expect.
+ (compile-test-grep-regexps): Adapt to test case format.
+ Remove now superfluous ert-info.
+
+2020-10-19 Mattias Engdegård <mattiase@acm.org>
+
+ Hoist some loop-invariant variable bindings in compile.el
+
+ * lisp/progmodes/compile.el (compilation-parse-errors):
+ Hoist the binding of case-fold-search and a memq call out of
+ the loop, eliminating a minor but unnecessary quadratic term.
+
+2020-10-19 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/info.el: Remove redundant :group args.
+
+2020-10-19 Stefan Kangas <stefan@marxist.se>
+
+ Improve Info-streamline-headings defaults
+
+ * lisp/info.el (Info-streamline-headings): Improve defaults. These
+ produce somewhat more consistent results on my system, and seems
+ slightly more in line with current GNU practices. For example, gcc
+ uses the "Software development" heading instead of "Programming".
+
+2020-10-19 dickmao <none>
+
+ `ffap-gopher-at-point' interminable without newlines
+
+ * lisp/ffap.el (ffap-gopher-at-point): Stop when we get to the end
+ of the buffer.
+ * test/lisp/ffap-tests.el (ffap-test-no-newlines): Ensure
+ termination for corner case (bug#44048).
+
+2020-10-19 Robert Pluim <rpluim@gmail.com>
+
+ Explain difference between Unicode and Emacs scripts
+
+ * doc/lispref/nonascii.texi (Character Properties): Document that
+ Emacs' scripts and Unicode's scripts do not necessarily
+ correspond.
+
+2020-10-19 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Delete a misleading comment, add tests for verification
+
+ * lisp/progmodes/cperl-mode.el: Delete a comment which explains a
+ bug which has been fixed a long time ago (bug#44073).
+ * test/lisp/progmodes/cperl-mode-tests.el
+ (cperl-mode-fontify-punct-vars): Add regression tests to verify
+ that fontification of punctuation variables doesn't start strings.
+
+2020-10-19 Yuan Fu <casouri@gmail.com>
+
+ Handle "Before first headings" error in outline-cycle
+
+ * lisp/outline.el (outline-before-first-heading): New error.
+ (outline-back-to-heading): Signal the new error.
+ (outline-cycle): Ignore the error.
+ (outline-cycle-buffer): Simply pass 1 to 'outline-hide-sublevels'
+ (bug#41130).
+
+2020-10-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Ffunction doc string clarification
+
+ * src/eval.c (Ffunction): Mention that `function' isn't quite like
+ `quote' in non-bytecompile circumstances, too (bug#41864).
+
+2020-10-19 Michael Albinus <michael.albinus@gmx.de>
+
+ * src/dired.c (Fdirectory_files, Fdirectory_files_and_attributes):
+
+ Adapt docstring.
+
+2020-10-19 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/files.el (directory-files-no-dot-files-regexp): Adapt docstring.
+
+2020-10-18 Juri Linkov <juri@linkov.net>
+
+ Add new choice 'keep' to next-error-message-highlight (bug#32676)
+
+ * lisp/simple.el (next-error-message-highlight): Add new choice 'keep'.
+ (next-error-message-highlight): Don't delete overlay when option is 'keep'.
+
+2020-10-18 Juri Linkov <juri@linkov.net>
+
+ * etc/HELLO: Add Belarusian and use Javanese script for Javanese (bug#43887)
+
+2020-10-18 Stefan Kangas <stefan@marxist.se>
+
+ Add "Old-" prefix to "Version" header in more cases
+
+ These version numbers are historical accidents and not relevant today.
+ Ref: https://lists.gnu.org/r/emacs-devel/2020-03/msg00080.html
+
+2020-10-18 Stefan Kangas <stefan@marxist.se>
+
+ Prefer Lisp version of describer in help--describe-vector
+
+ * src/keymap.c (Fhelp__describe_vector):
+ * lisp/help.el (describe-map): Use Lisp versions of describe_command
+ and describe_translation.
+ * src/keymap.c (describe_command, describe_translation): Remove.
+ (describe_vector_basic): New function.
+
+2020-10-18 Stefan Kangas <stefan@marxist.se>
+
+ Remove C version of substitute-command-keys
+
+ * src/doc.c (Fsubstitute_command_keys_old): Remove.
+ (syms_of_doc): Remove defsubr for Fsubstitute_command_keys_old.
+ * src/keymap.c (describe_map, describe_map_tree)
+ (describe_map_compare, describe_map_elt): Remove.
+ * src/keymap.h: Remove 'describe_map_tree'.
+ * test/lisp/help-tests.el (with-substitute-command-keys-test)
+ (help-tests-substitute-command-keys/compare)
+ (help-tests-substitute-command-keys/compare-all):
+ Don't test the C version of 'substitute-command-keys' removed
+ above.
+
+2020-10-18 Stefan Kangas <stefan@marxist.se>
+
+ Prefer Lisp version of describe-map-tree
+
+ This is a prerequisite to remove the old C functions, and gives a
+ measured 3 ms slowdown on my machine, from 0.27s to 0.30s per call to
+ describe-buffer-bindings (average over 50 calls).
+
+ * src/keymap.c (Fdescribe_buffer_bindings): Call Lisp function
+ describe-map-tree instead of C function describe_map_tree.
+
+2020-10-18 Stefan Kangas <stefan@marxist.se>
+
+ Improve substitute-command-keys performance
+
+ The previous conversion of describe_vector from C to Lisp for the
+ keymap and char table case lead to an unacceptable performance hit.
+ Moving back to the C version, as we do here, makes this function
+ around 50 times faster.
+
+ The Lisp version of `substitute-command-keys' was benchmarked using
+ the form `(documentation 'dired-mode)', which now takes less than 8 ms
+ on my machine. This is around 16 times slower than the previous C
+ version.
+
+ Thanks to Stefan Monnier for helpful pointers on benchmarking.
+
+ * src/keymap.c (Fhelp__describe_vector): New defun to expose
+ describe_vector to Lisp for keymaps and char tables.
+ (syms_of_keymap): New defsubr for Fhelp__describe_vector.
+ * lisp/help.el (describe-map): Use above defun instead of Lisp
+ version.
+ (help--describe-vector): Remove defun; keep it commented out for now.
+
+2020-10-18 Stefan Kangas <stefankangas@gmail.com>
+
+ Translate describe_vector to Lisp
+
+ * lisp/help.el (help--describe-vector): New Lisp implementation of
+ describe_vector.
+ * src/keymap.c (Fdescribe_vector_internal): Remove defun.
+ (syms_of_keymap): Remove defsubr for Fdescribe_vector_internal.
+
+2020-10-18 Stefan Kangas <stefankangas@gmail.com>
+
+ Translate describe_map to Lisp
+
+ Third step in converting substitute-command-keys to Lisp.
+
+ * lisp/help.el (describe-map): New Lisp version of describe_map.
+ (help--describe-map-compare, help--describe-translation)
+ (help--describe-command, help--shadow-lookup): New helper
+ functions for describe-map.
+ (help--keymaps-seen, help--previous-description-column): New
+ variables.
+ * src/keymap.c
+ (Fkeymap__get_keyelt): New defun to expose get_keyelt to Lisp.
+ (Fdescribe_map_tree_old, Fdescribe_map): Remove defuns.
+ (Fdescribe_vector_internal): New defun to expose describe_vector to
+ Lisp in a way usable by describe-map.
+ (syms_of_keymap): New defsubrs for Fkeymap__get_keyelt and
+ Fdescribe_vector_internal. Remove defsubrs for Fdescribe_map_tree_old
+ and Fdescribe_map. Remove 'help--keymaps-seen'.
+
+ * test/lisp/help-tests.el
+ (help-tests-substitute-command-keys/shadow): Extend test.
+ (help-tests-substitute-command-keys/test-mode)
+ (help-tests-substitute-command-keys/compare-all)
+ (help-tests-describe-map-tree/no-menu-t)
+ (help-tests-describe-map-tree/no-menu-nil)
+ (help-tests-describe-map-tree/mention-shadow-t)
+ (help-tests-describe-map-tree/mention-shadow-nil)
+ (help-tests-describe-map-tree/partial-t)
+ (help-tests-describe-map-tree/partial-nil): New tests.
+
+2020-10-18 Stefan Kangas <stefan@marxist.se>
+
+ Translate describe_map_tree to Lisp
+
+ This is the second step in converting substitute-command-keys to Lisp.
+
+ * lisp/help.el (describe-map-tree): New Lisp version of
+ describe_map_tree.
+ (substitute-command-keys): Update to use above function.
+ * src/keymap.c (Fdescribe_map): New defun to expose describe_map to
+ Lisp.
+ * src/keymap.c (syms_of_keymap): New variable 'help--keymaps-seen'; a
+ temporary kludge planned for removal. New defsubr for Fdescribe_map.
+
+2020-10-18 Stefan Kangas <stefankangas@gmail.com>
+
+ Add new Lisp implementation of substitute-command-keys
+
+ This is only the first step towards a full Lisp implementation, and
+ does not remove the old C code. On the contrary, it is partly based
+ on using the old C code, which is to be replaced in steps. This also
+ makes it easy to test that it produces the same output as the old.
+
+ * src/doc.c (Fsubstitute_command_keys_old): Rename from
+ Fsubstitute_command_keys.
+ (Fget_quoting_style): New defun to expose text_quoting_style to Lisp.
+ (syms_of_doc): Expose above symbols.
+ * lisp/help.el (substitute-command-keys): New Lisp version of
+ substitute-command-keys. (Bug#8951)
+
+ * src/keymap.c
+ (Fdescribe_map_tree): New defun to expose describe_map_tree to Lisp.
+ (syms_of_keymap): New defsubr for Fdescribe_map_tree.
+
+ * src/keyboard.c (help_echo_substitute_command_keys):
+ * src/doc.c (Fdocumentation, Fdocumentation_property):
+ * src/print.c (print_error_message):
+ * src/syntax.c (Finternal_describe_syntax_value): Fix calls to use new
+ Lisp implementation of substitute-command-keys.
+
+ * test/src/doc-tests.el: Remove file.
+ * test/lisp/help-tests.el: Add tests for substitute-command-keys
+ copied from above file.
+
+2020-10-18 Mattias Engdegård <mattiase@acm.org>
+
+ Strengthen js-mode indentation tests
+
+ Test not only that the indentation engine is idempotent but that it
+ will indent a file to the expected shape from scratch.
+
+ * test/lisp/progmodes/js-tests.el (js-tests--remove-indentation): New.
+ (js-deftest-indent): Extend test.
+
+2020-10-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix a misleading comment in Freplace_match
+
+ * src/search.c (Freplace_match): Fix a misleading comment
+ (bug#42424).
+
+2020-10-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document the new smiley value
+
+ * doc/misc/gnus.texi (Smileys): Document the emoji smiley value.
+
+2020-10-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up smiley emoji application to make it reversible
+
+ * lisp/gnus/smiley.el (smiley-region): Use text properties for the
+ emojis instead of rewriting the message.
+
+2020-10-18 Adam Sjøgren <asjo@koldfront.dk>
+
+ Add support for emojis i smiley.el
+
+ * lisp/gnus/smiley.el (smiley-style): Add emoji
+ tag.
+ (smiley-emoji-regexp-alist): New defcustom.
+ (smiley-update-cache, smiley-region): Support emoji (non-image)
+ replacement (bug#43889).
+
+2020-10-18 Stefan Kangas <stefan@marxist.se>
+
+ Make nxml-newline-and-indent argument optional
+
+ * lisp/nxml/nxml-mode.el (nxml-newline-and-indent): Make argument
+ optional to conform to 'comment-line-break-function'. (Bug#40193)
+
+2020-10-18 Stefan Kangas <stefan@marxist.se>
+
+ Minor improvements to emacsclient man page
+
+ * doc/man/emacsclient.1: Make flag descriptions into full sentences to
+ be more consistent.
+
+2020-10-18 Stefan Kangas <stefan@marxist.se>
+
+ Convert manual js indent tests to unit tests
+
+ * test/lisp/progmodes/js-tests.el (ert-x): Require.
+ (js-deftest-indent): New macro. Use it to define tests for indenting
+ the below files.
+
+ * test/manual/indent/js-chain.js:
+ * test/manual/indent/js-indent-align-list-continuation-nil.js:
+ * test/manual/indent/js-indent-init-dynamic.js:
+ * test/manual/indent/js-indent-init-t.js:
+ * test/manual/indent/js.js:
+ * test/manual/indent/jsx-align-gt-with-lt.jsx:
+ * test/manual/indent/jsx-comment-string.jsx:
+ * test/manual/indent/jsx-indent-level.jsx:
+ * test/manual/indent/jsx-quote.jsx:
+ * test/manual/indent/jsx-self-closing.jsx:
+ * test/manual/indent/jsx-unclosed-1.jsx:
+ * test/manual/indent/jsx-unclosed-2.jsx:
+ * test/manual/indent/jsx.jsx: Move from here...
+ * test/lisp/progmodes/js-resources/js-chain.js:
+ * test/lisp/progmodes/js-resources/js-indent-align-list-continuation-nil.js:
+ * test/lisp/progmodes/js-resources/js-indent-init-dynamic.js:
+ * test/lisp/progmodes/js-resources/js-indent-init-t.js:
+ * test/lisp/progmodes/js-resources/js.js:
+ * test/lisp/progmodes/js-resources/jsx-align-gt-with-lt.jsx:
+ * test/lisp/progmodes/js-resources/jsx-comment-string.jsx:
+ * test/lisp/progmodes/js-resources/jsx-indent-level.jsx:
+ * test/lisp/progmodes/js-resources/jsx-quote.jsx:
+ * test/lisp/progmodes/js-resources/jsx-self-closing.jsx:
+ * test/lisp/progmodes/js-resources/jsx-unclosed-1.jsx:
+ * test/lisp/progmodes/js-resources/jsx-unclosed-2.jsx:
+ * test/lisp/progmodes/js-resources/jsx.jsx: ...to here.
+
+2020-10-18 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/progmodes/ld-script.el: Use lexical-binding.
+
+ * lisp/progmodes/mixal-mode.el: Fix typos.
+
+2020-10-18 Jose A Ortega Ruiz <jao@gnu.org>
+
+ Set jao@gnu.org as maintainer of mixal-mode.el
+
+ * lisp/progmodes/mixal-mode.el: Set jao@gnu.org as maintainer of
+ mixal-mode.el. (Bug#44037)
+
+2020-10-18 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in mixal-mode.el
+
+ * lisp/progmodes/mixal-mode.el: Use lexical-binding. (Bug#44037)
+
+2020-10-17 Juri Linkov <juri@linkov.net>
+
+ Extend next-error-message face to the edge of the window (bug#32676)
+
+ * lisp/simple.el (next-error-message): Add ':extend t' to this face.
+ (next-error-message-highlight): Put overlay over the newline as well.
+
+2020-10-17 J. Scott Berg <jsberg-bnl@outlook.com> (tiny change)
+
+ Fix bad dimensions of initial frame on VcXsrv
+
+ * src/xterm.c (handle_one_xevent) [USE_GTK]: Don't obey
+ ConfigureNotify events if the frame is not visible. (Bug#44002)
+
+2020-10-17 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 18c0e20bea (origin/emacs-27) Improve documentation of 'Info-hide-note...
+
+2020-10-17 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 65078e0a76 * lisp/info.el (Info-hide-note-references): Doc fix. (Bug...
+ 30305b543d Make lisp/progmodes/js.el dependent on CC Mode in the Make...
+ c37b2a9b42 Yet another fix for 'set-minibuffer-message'
+ 72dd911981 Fix posn-at-x-y in builds --without-x
+ ace25f2066 Clarify the seq-reduce documentation
+ 7d598e281d Make tramp-completion-reread-directory-timeout obsolete (B...
+ 2c31ce18ea Fix 'message' when there's active minibuffer on another frame
+
+ # Conflicts:
+ # doc/misc/tramp.texi
+ # etc/NEWS
+
+2020-10-17 Mattias Engdegård <mattiase@acm.org>
+
+ * etc/NEWS: Mention new lexical binding conversion aid.
+
+2020-10-17 Protesilaos Stavrou <info@protesilaos.com>
+
+ Update Modus themes' NEWS entry
+
+ * etc/NEWS: Reword entry about new 'modus-operandi' and
+ 'modus-vivendi' themes. Include reference to their manual.
+
+2020-10-17 Jose A. Ortega Ruiz <jao@gnu.org>
+
+ mixal-mode: add missed instructions
+
+ Synchronises with latest released GNU MDK 1.2.11
+
+ * lisp/progmodes/mixal-mode.el (mixal-operation-codes-alist):
+ Add missed instructions: SLB,SRB,JAE,JAO,JXE,JXO.
+
+2020-10-17 Stefan Kangas <stefan@marxist.se>
+
+ Base bookmark-bmenu-mode on tabulated-list-mode (Bug#39293)
+
+ Rewriting bookmark-bmenu-mode to be based on 'tabulated-list-mode'
+ allows us to greatly simplify the code in several cases. In addition,
+ we get some features for free, such as sorting by column.
+
+ The only functional step backwards is that we no longer support the
+ optional "inline" header line, a bookmark.el-specific feature to have
+ a header without using 'header-line-format'. This feature is believed
+ to be not very useful or widely used.
+
+ * lisp/bookmark.el (tabulated-list): Require.
+ (bookmark-bmenu-mode): Inherit from 'tabulated-list-mode' instead of
+ 'special-mode' and make the necessary changes to support that.
+ (bookmark-bmenu-mode-map): Inherit from 'tabulated-list-mode-map'
+ instead of 'special-mode-map'. Remove now duplicate key bindings.
+ (bookmark-bmenu--revert): New function to show the bookmark list using
+ 'tabulated-list-mode'.
+ (bookmark-bmenu-list): Simplify by using above new function.
+ (bookmark-bmenu-bookmark): Adapt to 'tabulated-list-mode'.
+ (bookmark-bmenu--name-predicate)
+ (bookmark-bmenu--file-predicate): New functions used by
+ 'tabulated-list-mode' to sort.
+
+ (bookmark-bmenu-set-header): Redefine as obsolete function alias for
+ 'tabulated-list-init-header'.
+ (bookmark-bmenu-toggle-filenames, bookmark-bmenu-show-filenames)
+ (bookmark-bmenu-hide-filenames, bookmark-bmenu-mark)
+ (bookmark-bmenu-mark-all, bookmark-bmenu-unmark-all)
+ (bookmark-bmenu-delete-all, bookmark-bmenu-unmark)
+ (bookmark-bmenu-delete, bookmark-bmenu-delete-backwards): Simplify now
+ that we can depend on 'tabulated-list-mode' to do more work.
+
+ (bookmark-bmenu-use-header-line)
+ (bookmark-bmenu-inline-header-height): Declare variables relating to
+ the now unsupported "inline" header obsolete.
+ (bookmark-bmenu-ensure-position)
+ (bookmark-bmenu-execute-deletions): Remove code to handle "inline" header.
+
+ * test/lisp/bookmark-tests.el
+ (bookmark-test-bmenu-edit-annotation/show-annotation)
+ (bookmark-test-bmenu-unmark, bookmark-test-bmenu-mark): Update tests
+ for minor changes when using 'tabulated-list-mode'.
+
+2020-10-17 Mattias Engdegård <mattiase@acm.org>
+
+ Add aid for finding missing dynamic variable declarations
+
+ Find lexical use of variables that are dynamically declared in other
+ files by recording 'defvar' declarations in files that can be read
+ in by the compiler in a second compilation. This is particularly
+ useful when converting code to use lexical-binding.
+
+ The facility is controlled by setting environment variables:
+
+ EMACS_GENERATE_DYNVARS -- set to non-empty to generate a .dynvars file
+ corresponding to each .elc.
+ EMACS_DYNVARS_FILE -- set to the name of a .dynvars file to use
+ as defvar information during compilation,
+ enabling the new warnings.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile--known-dynamic-vars)
+ (byte-compile--seen-defvars): New variables.
+ (byte-compile-warning-types): Add lexical-dynamic warning.
+ (byte-compile--load-dynvars, byte-compile--warn-lexical-dynamic):
+ New functions.
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-file, byte-compile--declare-var)
+ (byte-compile-lambda, byte-compile-bind): Add dynamic variable loads,
+ dumps and checks.
+ * doc/lispref/variables.texi (Converting to Lexical Binding): Document.
+
+2020-10-17 Stefan Kangas <stefan@marxist.se>
+
+ * test/lisp/mail/rfc822-tests.el: New file.
+
+ * lisp/url/url-vars.el: Use lexical-binding.
+
+2020-10-17 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'Info-hide-note-references' in info.texi
+
+ * doc/misc/info.texi (Help-Xref): Improve the wording.
+ (Emacs Info Variables): Update the documentation of
+ 'Info-hide-note-references'. (Bug#44043)
+
+2020-10-17 Pierre Neidhardt <mail@ambrevar.xyz>
+
+ New shell-mode command to narrow to the command under point
+
+ * lisp/shell.el (shell--prompt-end-position)
+ (shell--prompt-begin-position): Helper functions.
+
+ * lisp/shell.el (shell-narrow-to-prompt): New command and
+ keystroke (bug#41784).
+
+2020-10-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make woman ignore the new groff kerning operators
+
+ * lisp/woman.el (woman-decode-region): Ignore the new groff
+ kerning operators (bug#42219).
+
+2020-10-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix `browse-url-of-dired'
+
+ * lisp/net/browse-url.el (browse-url-emacs): Make the
+ `browse-url-of-dired' command work again after the browse-emacs
+ changes (bug#42429).
+
+2020-10-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Avoid infloop in which-function-mode when a vc file has changed
+
+ * lisp/vc/diff-mode.el (diff-find-source-location): Avoid warnings
+ when called from which-function-mode and the file has changed
+ (bug#42818).
+
+2020-10-17 Stefan Kangas <stefan@marxist.se>
+
+ * admin/release-process: Add note to update files from upstream.
+
+ (cherry picked from commit 86dd9d12aa5a273da2efd4ce8c6e35ae343f1494)
+
+2020-10-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix narrow-to-defun in f90-mode
+
+ * lisp/progmodes/f90.el (f90-beginning-of-subprogram): Make
+ narrow-to-defun work better (bug#44042).
+
+2020-10-17 Eli Zaretskii <eliz@gnu.org>
+
+ * lisp/info.el (Info-hide-note-references): Doc fix. (Bug#44043)
+
+2020-10-17 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-10-17 Stefan Kangas <stefan@marxist.se>
+
+ * admin/release-process: Add note to update files from upstream.
+
+2020-10-16 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * doc/lispref/variables.texi (Converting to Lexical Binding): New section
+
+ Extract it from `Using Lexical Binding` and extend it a bit.
+
+2020-10-16 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/python.el: Teach f-strings to `font-lock`
+
+ (python--f-string-p, python--font-lock-f-strings): New functions.
+ (python-font-lock-keywords-maximum-decoration): Use them.
+
+2020-10-16 Alan Mackenzie <acm@muc.de>
+
+ Make lisp/progmodes/js.el dependent on CC Mode in the Makefile.
+
+ This will prevent version mismatches between compile time and runtime
+ versions. This fixes bug #43037.
+
+ * lisp/Makefile.in: Make js.el dependent on cc-{defs,engine,mode}.elc.
+
+2020-10-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ indent-rigidly doc string clarification
+
+ * lisp/indent.el (indent-rigidly): Note that the command
+ deactivates the mark (bug#42842).
+
+2020-10-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make erc expand the final abbrev
+
+ * lisp/erc/erc.el (erc-send-current-line): Expand abbrevs at the
+ end of lines (bug#42854).
+
+2020-10-16 Michael Albinus <michael.albinus@gmx.de>
+
+ Make last change in tramp-archive-tests.el backward compatible
+
+ * test/lisp/net/tramp-archive-tests.el (ert-resource-directory-format)
+ (ert-resource-directory-trim-left-regexp)
+ (ert-resource-directory-trim-right-regexp, ert-resource-directory)
+ (ert-resource-file): Define if they don't exist.
+
+2020-10-16 Eli Zaretskii <eliz@gnu.org>
+
+ Fix documentation of Modus Themes
+
+ * doc/misc/modus-themes.texi (Install from the archives)
+ (No mixed fonts): Remove references to MELPA.
+ (How do the themes look like)
+ (Enable and load, Load automatically)
+ (Configure options prior to loading, Customisation Options)
+ (No mixed fonts, Command prompts, Mode line, Completion UIs)
+ (Fringes, Line highlighting, Matching parentheses, Diffs)
+ (Org mode blocks, Heading styles, Tweak colors (DIY))
+ (Org user faces (DIY), Supported packages)
+ (Will NOT be supported, Note for ERC escaped color sequences)
+ (Note on shr colors, Note for Helm grep)
+ (Note on vc-annotate-background-mode, Sources of the themes): Fix
+ spelling, wording, and markup.
+
+2020-10-16 Eli Zaretskii <eliz@gnu.org>
+
+ Revert "* doc/emacs/ack.texi (Acknowledgments): Remove now deleted files."
+
+ This reverts commit 731a26bb50aabeb2c0512f0e45b3cda76029a590.
+
+ We don't support rewriting history!
+ People who contributed to Emacs development should have their
+ contributions remain acknowledged forever, even if the files
+ to which they contributed are deleted at some point.
+
+2020-10-16 Eli Zaretskii <eliz@gnu.org>
+
+ Fix file-name problems in several tests
+
+ * test/lisp/saveplace-tests.el
+ (saveplace-test-forget-unreadable-files): Use file-truename, to
+ avoid false negatives when file names are not 'equal' as strings,
+ but point to the same file.
+ * test/lisp/emacs-lisp/edebug-tests.el (edebug-tests-with-normal-env)
+ (edebug-tests-run-macro):
+ * test/lisp/emacs-lisp/testcover-tests.el
+ (testcover-tests-markup-region, testcover-tests-run-test-case):
+ Bind find-file-suppress-same-file-warnings to a non-nil value, to
+ avoid warnings about "same-file-names", at least on MS-Windows,
+ due to 8+3 aliases.
+
+2020-10-16 Stefan Kangas <stefan@marxist.se>
+
+ Remove some Emacs 19 compat code
+
+ * lisp/type-break.el (type-break-time-stamp): Remove Emacs 19
+ compat code.
+
+2020-10-16 Stefan Kangas <stefan@marxist.se>
+
+ Remove some references to Emacs 18 and 19
+
+ * doc/misc/forms.texi (Modifying Forms Contents, Error Messages):
+ * lisp/arc-mode.el:
+ * lisp/emacs-lisp/edebug.el (edebug-temp-display-freq-count):
+ * lisp/type-break.el: Remove some references to Emacs 18 and 19.
+
+2020-10-16 Stefan Kangas <stefan@marxist.se>
+
+ * doc/emacs/ack.texi (Acknowledgments): Remove now deleted files.
+
+ This is in line with an ack.texi comment that says to "Remove things
+ that are no longer distributed." Most files in this list were removed
+ many years ago.
+
+2020-10-16 Stefan Kangas <stefan@marxist.se>
+
+ Fix building modus-themes Info manual
+
+ * doc/misc/Makefile.in (INFO_COMMON): Add modus-themes.
+ * doc/misc/modus-themes.texi: Adapt to fit Emacs conventions.
+
+2020-10-16 Protesilaos Stavrou <info@protesilaos.com>
+
+ Update modus-operandi, modus-vivendi to 0.13.0
+
+ * etc/themes/modus-operandi-theme.el: Update to version 0.13.0.
+
+ * etc/themes/modus-vivendi-theme.el: Update to version 0.13.0.
+
+ * doc/misc/modus-themes.texi: Include new texinfo documentation for
+ modus-operandi and modus-vivendi themes. (Bug#43944)
+
+2020-10-16 Mattias Engdegård <mattiase@acm.org>
+
+ * lisp/emacs-lisp/backquote.el: Use lexical binding.
+
+2020-10-16 Stefan Kangas <stefan@marxist.se>
+
+ Use new resource directory macros in tests (Bug#43792)
+
+ * test/lisp/bookmark-tests.el (bookmark-tests-data-dir):
+ * test/lisp/calendar/todo-mode-tests.el (todo-test-data-dir):
+ * test/lisp/net/dbus-tests.el (dbus--tests-dir):
+ * test/lisp/emacs-lisp/edebug-tests.el
+ (edebug-tests-sample-code-file):
+ * test/lisp/emacs-lisp/package-tests.el
+ (package-test-fake-contents-file):
+ * test/lisp/emacs-lisp/shadow-tests.el (shadow-tests-data-directory):
+ * test/lisp/emacs-lisp/testcover-tests.el
+ (testcover-tests-file-dir, testcover-tests-test-cases):
+ * test/lisp/mail/uudecode-tests.el (uudecode-tests-data-dir):
+ * test/lisp/net/tramp-archive-tests.el
+ (tramp-archive-test-resource-directory):
+ * test/lisp/pcmpl-linux-tests.el (pcmpl-linux-tests-data-dir):
+ * test/lisp/progmodes/cperl-mode-tests.el
+ (cperl-mode-tests-data-directory):
+ * test/lisp/progmodes/flymake-tests.el
+ (flymake-tests-data-directory):
+ * test/lisp/progmodes/ruby-mode-tests.el (ruby-mode-tests-data-dir):
+ * test/lisp/saveplace-tests.el (saveplace-tests-dir):
+ * test/lisp/textmodes/css-mode-tests.el (css-mode-tests-data-dir):
+ Remove.
+
+ * test/lisp/bookmark-tests.el (bookmark-tests-bookmark-file)
+ (bookmark-tests-example-file, bookmark-tests-bookmark-file-list):
+ * test/lisp/calendar/todo-mode-tests.el (todo-test-file-1)
+ (todo-test-archive-1, with-todo-test, todo-test--add-file):
+ * test/lisp/custom-tests.el (custom--test-theme-variables):
+ * test/lisp/net/dbus-tests.el (dbus--test-introspect):
+ * test/lisp/emacs-lisp/edebug-tests.el (edebug-tests-setup-code-file):
+ * test/lisp/emacs-lisp/package-tests.el (package-test-data-dir)
+ (package-test-desc-from-buffer, package-test-install-single)
+ (package-test-macro-compilation)
+ (package-test-install-prioritized)
+ (package-test-install-multifile, package-test-update-archives)
+ (package-test-update-archives-async)
+ (package-test-update-archives/ignore-nil-entry)
+ (package-test-signed, package-x-test-upload-buffer)
+ (package-x-test-upload-new-version):
+ * test/lisp/emacs-lisp/shadow-tests.el (shadow-case-insensitive):
+ * test/lisp/emacs-lisp/testcover-tests.el
+ (testcover-tests-build-test-cases):
+ * test/lisp/mail/uudecode-tests.el (uudecode-tests-encoded-str)
+ (uudecode-tests-decoded-str):
+ * test/lisp/net/tramp-archive-tests.el
+ (tramp-archive-test-file-archive)
+ (tramp-archive-test-directory):
+ * test/lisp/pcmpl-linux-tests.el (pcmpl-linux-test-fs-types)
+ (pcmpl-linux-test-mounted-directories):
+ * test/lisp/progmodes/cperl-mode-tests.el (cperl-mode-test-bug-10483)
+ (cperl-mode-test-indent-styles):
+ * test/lisp/progmodes/flymake-tests.el
+ (flymake-tests--call-with-fixture):
+ * test/lisp/progmodes/ruby-mode-tests.el
+ (ruby--indent/converted-from-manual-test):
+ * test/lisp/saveplace-tests.el
+ (saveplace-test-save-place-to-alist/dir)
+ (saveplace-test-load-alist-from-file):
+ * test/lisp/textmodes/css-mode-tests.el (css-mode-test-indent): Adjust
+ to use new resource directory macros.
+
+2020-10-16 Stefan Kangas <stefan@marxist.se>
+
+ Add ert macros to get resource file names (Bug#43792)
+
+ * lisp/emacs-lisp/ert-x.el (subr-x): Require.
+ (ert-resource-dir, ert-resource-file): New macros to get the file name
+ of the resource directory belonging to a test.
+ (ert-resource-dir-format, ert-resource-dir-trim-left-regexp)
+ (ert-resource-dir-trim-right-regexp): New variables.
+
+2020-10-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous gnus-icalendar sanitization
+
+ * lisp/gnus/gnus-icalendar.el (gnus-icalendar-event-from-ical):
+ Fix previous change -- respect nil values passed in.
+
+2020-10-16 Stephen Berman <stephen.berman@gmx.net>
+
+ Adjust some tests so that they work in symlinked environs
+
+ * test/lisp/help-fns-tests.el (help-fns-test-lisp-macro)
+ (help-fns-test-lisp-defsubst):
+ * test/lisp/emacs-lisp/cl-generic-tests.el
+ (cl-generic-tests--method-files--finds-methods): Adjust test so
+ that they work in a symlinked environment (bug#43004).
+ (cl-generic-tests--method-files--finds-methods): Use file-truename
+ so that this works in a symlinked environment (bug#43004).
+
+2020-10-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Sanitize ical data in gnus-icalendar-event-from-ical
+
+ * lisp/gnus/gnus-icalendar.el (gnus-icalendar-event-from-ical):
+ Sanitise the data before passing it on to the constructor. This
+ avoids backtraces on icals with extra, unknown slots (bug#43057).
+
+2020-10-16 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Substitute command keys in button help-echo values
+
+ * lisp/button.el (button--help-echo): Pass resulting string through
+ substitute-command-keys for consistency with show-help-function.
+ * test/lisp/button-tests.el (button-tests--map): New test keymap.
+ (button--help-echo-string, button--help-echo-form)
+ (button--help-echo-function): Use it to test command key
+ substitution in help-echo strings (bug#43070).
+
+2020-10-16 Eli Zaretskii <eliz@gnu.org>
+
+ Yet another fix for 'set-minibuffer-message'
+
+ * lisp/minibuffer.el (set-minibuffer-message): Handle the case of
+ separate minibuffer-only frame. Suggested by Gregory Heytings
+ <ghe@sdf.org>.
+
+2020-10-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make package-install-from-buffer maybe refresh the quickstart file
+
+ * lisp/emacs-lisp/package.el (package-install-from-buffer):
+ Refresh the quickstart file (bug#43237). This makes this command
+ more consistent with package-install.
+
+2020-10-16 Eli Zaretskii <eliz@gnu.org>
+
+ Fix posn-at-x-y in builds --without-x
+
+ * src/keyboard.c (make_lispy_position): Don't exclude the
+ window_or_frame = frame case from TTY-only builds. Reported by
+ Jared Finder <jared@finder.org>.
+
+ * doc/lispref/commands.texi (Click Events): Document the format of
+ POSITION in click events on the frame's internal border.
+
+2020-10-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ diff-update-on-the-fly doc string clarification
+
+ * lisp/vc/diff-mode.el (diff-update-on-the-fly): Mention what the
+ nil value does (bug#43297).
+
+2020-10-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Restore vc-revision-other-window buffer-changing behaviour
+
+ * lisp/vc/vc.el (vc-revision-other-window): This function used to
+ change the current buffer, but this was changed in the previous
+ patch for indirect buffer support. Ensure that it still does
+ this, because this is what the callers expect (bug#44026).
+
+2020-10-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Doc string clarification for keep-lines
+
+ * lisp/replace.el (keep-lines): Note that REND isn't optional if
+ RSTART is given (bug#44021).
+
+2020-10-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new variable to control Gnus Agent caching
+
+ * doc/misc/gnus.texi (Agent Variables): Document it.
+
+ * lisp/gnus/gnus-art.el (gnus-request-article-this-buffer): Ditto.
+
+ * lisp/gnus/gnus-async.el (gnus-async-article-callback): Use it.
+
+ * lisp/gnus/gnus.el (gnus-agent-eagerly-store-articles): New variable.
+
+ Includes work from Madhu <enometh@meer.net>.
+
+2020-10-16 Richard M Stallman <rms@gnu.org>
+
+ Add way to prevent asking "increase specpdl size?"
+
+ * net/shr.el (shr-offer-extend-specpdl): New option, default t.
+ (shr-descend): If shr-offer-extend-specpdl is nil, don't even ask
+ whether to extend the specpdl, just signal error.
+
+2020-10-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/warnings.el (display-warning): Don't be so negative
+
+2020-10-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't display the warning buttons in bytecomp buffers
+
+ * lisp/emacs-lisp/warnings.el (display-warning): Don't do the
+ buttons in bytecomp buffers.
+
+2020-10-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make hi-lock-face-buffer more resilient
+
+ * lisp/hi-lock.el (hi-lock-face-buffer): If given a face name a
+ string, convert it to a symbol first, as later usage of this
+ expects a symbol and not a string (bug#43339).
+
+2020-10-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add some references to the microdocs in the comments in cperl-mode
+
+ * lisp/progmodes/cperl-mode.el: Tell the people reading the
+ comments how to read the docs explicitly (bug#1621).
+
+2020-10-15 David Engster <deng@randomsample.de>
+
+ Search harder for file name matches in *compilation* buffers
+
+ * lisp/progmodes/compile.el (compilation-find-file): Use it (bug#14411).
+ (compilation-search-all-directories): New variable.
+
+2020-10-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `C-x C-e' work more like `C-M-x' on defvar etc
+
+ * doc/emacs/building.texi (Lisp Eval): Document it.
+
+ * lisp/emacs-lisp/pp.el (pp-eval-last-sexp): Ditto.
+
+ * lisp/progmodes/elisp-mode.el (elisp--eval-last-sexp): Work more
+ like `eval-defun': Re-evaluate defvar/defcustom/defface forms.
+
+2020-10-15 Stefan Kangas <stefankangas@gmail.com>
+
+ * doc/misc/efaq.texi: Remove reference to FTP.
+
+2020-10-15 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove some references to "in Emacs 21 or later"
+
+ * doc/misc/efaq.texi (Colors on a TTY, Disabling backups)
+ (Errors with init files, Backspace invokes help)
+ (Backspace invokes help): Remove some references to "in Emacs 21 or
+ later". Now everyone can be assumed to use at least that version.
+
+2020-10-15 Stefan Kangas <stefankangas@gmail.com>
+
+ Move emacsclient.1 file history further down
+
+ * doc/man/emacsclient.1: Move file history further down; it doesn't
+ need to be prominently displayed in the introductory paragraph.
+
+2020-10-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix undefined function in project-compile
+
+ * lisp/progmodes/project.el (project-compile): Require compile.el
+ before using functions from the file (bug#44009).
+
+2020-10-15 Andrea Corallo <akrl@sdf.org>
+
+ Do not check eln timestamp as superseded by source hashing (bug#43532)
+
+ * src/lread.c (maybe_swap_for_eln): Remove eln file timestamp
+ check given is now unnecessary.
+ (openp): Update for new 'maybe_swap_for_eln' signature.
+
+2020-10-15 Mattias Engdegård <mattiase@acm.org>
+
+ Remove dynamic declaration of 'save-match-data-internal'
+
+ * lisp/subr.el: Remove defvar which has no relevance today; it can
+ very well be a lexical variable.
+
+2020-10-15 Jeff Walsh <fejfighter@gmail.com>
+
+ Fix segfault in xwidget when there is no title
+
+ * src/xwidget.c (Fxwidget_webkit_title): Pass empty string when no
+ title is returned (bug#43989).
+
+2020-10-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify the seq-reduce documentation
+
+ * doc/lispref/sequences.texi (Sequence Functions): Ditto.
+
+ * lisp/emacs-lisp/seq.el (seq-reduce): Clarify the order of the
+ arguments (bug#43995).
+
+2020-10-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with next-error-message-highlight in *Occur*
+
+ * lisp/simple.el (next-error-message-highlight): This function is
+ called directly, so clean up the code a bit (bug#32676).
+ (next-error-found): Pass in the error buffer.
+
+2020-10-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix NEWS item for C-h R
+
+2020-10-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make Gnus more liberal when interpreting Face headers again
+
+ * lisp/gnus/gnus-fun.el (gnus-convert-face-to-png): Do it.
+
+ * lisp/gnus/gnus-util.el (gnus-base64-repad): Allow not checking
+ anything, but just repadding.
+
+2020-10-15 Richard M Stallman <rms@gnu.org>
+
+ Clarify wording
+
+ Clarify doc string of line-to-top-of-window.
+
+2020-10-15 Richard M Stallman <rms@gnu.org>
+
+ Handle retrying of MIME failure messages
+
+ * lisp/mail/rmail.el (rmail-retry-failure): Handle retrying of
+ MIME failure messages.
+
+2020-10-15 Richard M Stallman <rms@gnu.org>
+
+ Handle encrypting mime parts
+
+ * lisp/epa-mail.el (epa-mail-encrypt): Insert any encoded mime
+ parts that are queued up to insert before sending the message.
+
+2020-10-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/calc: Fix a few issues introduced by lexical scoping
+
+ Fix a few places I missed, where we incorrectly used lexical scoping on a var
+ that needed dynamic scoping.
+ These were detected thanks to a bit of footwork by Mattias Engdegård!
+
+ * lisp/calc/calc-ext.el (math-read-big-lines): Declare as dynbound.
+ (math-read-big-bigp): Bind it inside a `let`.
+ * lisp/calc/calc-graph.el (math-arglist): Declare as dynbound.
+ * lisp/calc/calc-map.el (math-arglist): Declare as dynbound.
+ * lisp/calc/calc-misc.el (math-trunc-prec): Declare as dynbound.
+ (math-trunc): Bind it inside a `let`.
+ (math-floor-prec): Declare as dynbound.
+ (math-floor): Bind it inside a `let`.
+ * lisp/calc/calc-nlfit.el (calc-curve-varnames, calc-curve-coefnames):
+ Declare as dynbound.
+ * lisp/calc/calc-sel.el (math-comp-sel-tag): Declare as dynbound.
+ * lisp/calc/calcsel2.el (calc-sel-reselect): Declare as dynbound.
+
+2020-10-14 Andreas Schwab <schwab@linux-m68k.org>
+
+ Fix layout of custom-face-edit widget
+
+ * lisp/cus-edit.el (custom-face-edit): Add :format to group
+ widget. (Bug#43977)
+
+2020-10-14 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-10-14 Andrea Corallo <akrl@sdf.org>
+
+ Use form native compilation in `comp-trampoline-compile'
+
+ * lisp/emacs-lisp/comp.el (comp-trampoline-sym): Remove function.
+ (comp-trampoline-filename): As we are introducing an ABI change in
+ the eln trampoline format change the trampoline filename to
+ disambiguate.
+ (comp-trampoline-search): Rename from `comp-search-trampoline'
+ and return directly the trampoline.
+ (comp-trampoline-compile): Rework to use native form compilation
+ in place of un-evaluating a function and return directly the
+ trampoline.
+ (comp-subr-trampoline-install): Update for
+ `comp-trampoline-search' and `comp-trampoline-compile' new
+ interfaces.
+ * src/comp.c (Fcomp__install_trampoline): Store the trampoline
+ itself as value in `comp-installed-trampolines-h'.
+ (syms_of_comp): Doc update `comp-installed-trampolines-h'.
+
+2020-10-14 Andrea Corallo <akrl@sdf.org>
+
+ Add a test to verify form native compilation.
+
+ * test/src/comp-tests.el (comp-deftest): Fix typo.
+ (compile-forms): New test.
+
+2020-10-14 Andrea Corallo <akrl@sdf.org>
+
+ Rework `native-compile' interface so it can return compiled functions
+
+ * lisp/emacs-lisp/comp.el (native-compile): Return the compiled
+ function when the input is a symbol or a form.
+ * test/src/comp-tests.el (free-fun, tco, fw-prop): Update tests
+ for new `native-compile' interface.
+
+2020-10-14 Andrea Corallo <akrl@sdf.org>
+
+ Have `native-elisp-load' return the last registerd function
+
+ * lisp/emacs-lisp/comp.el (comp-emit-for-top-level): Synthesize
+ 'top_level_run' so it returns the last value returned by
+ `comp--register-subr'.
+ * src/comp.c (load_comp_unit): Return what 'top_level_run'
+ returns.
+ (Fnative_elisp_load): Return what 'load_comp_unit' returns.
+ * src/comp.h (load_comp_unit): Update signature.
+
+2020-10-14 Andrea Corallo <akrl@sdf.org>
+
+ Allow for lambda forms as native compilation input
+
+ * lisp/emacs-lisp/comp.el (comp-spill-lap-function): Add new
+ specialized method for compiling a lambda form.
+
+2020-10-14 Andrea Corallo <akrl@sdf.org>
+
+ Move context output computation in `comp-spill-lap-function'
+
+ * lisp/emacs-lisp/comp.el (comp-spill-lap-function): Move
+ output filename computation here.
+ (native-compile): From here.
+
+2020-10-14 Juri Linkov <juri@linkov.net>
+
+ Highlight regexp sub-expressions in query-replace
+
+ * lisp/replace.el (query-replace-highlight-submatches): New defcustom.
+ (replace-submatches-overlays): New variable.
+ (replace-highlight): Use query-replace-highlight-submatches.
+ (replace-dehighlight): Use query-replace-highlight-submatches.
+
+ * doc/emacs/search.texi (Query Replace):
+ Add documentation for query-replace-highlight-submatches.
+
+ Suggested by Drew Adams <drew.adams@oracle.com> in bug#43702.
+
+2020-10-14 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/grep.el: More fixes for 'lgrep' (bug#23590)
+
+ * lisp/progmodes/grep.el (grep-expand-template): Add new arg 'more-opts'.
+ (grep-use-directories-skip): New variable.
+ (lgrep): Set 'grep-use-directories-skip' to the result of 'grep-probe'.
+ Use "--directories=skip" when 'grep-use-directories-skip' is t.
+
+2020-10-14 Ernesto Alfonso <erjoalgo@gmail.com>
+
+ Add option to highlight the 'next-error' error message
+
+ * lisp/simple.el (next-error-message-highlight):
+ (next-error-message): New faces (bug#32676).
+ (next-error--message-highlight-overlay): New internal variable.
+ (next-error-message-highlight): New function.
+ (next-error-found): Call the function.
+
+2020-10-14 Alex Branham <alex.branham@gmail.com>
+
+ Add a new variable tab-first-completion
+
+ * doc/emacs/indent.texi (Indent Convenience): Mention it.
+
+ * doc/lispref/text.texi (Mode-Specific Indent): Document it.
+
+ * lisp/indent.el (tab-first-completion): New variable (bug#34787).
+ (indent-for-tab-command): Use it.
+
+2020-10-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Rename dired-filename-at-point to avoid confusion
+
+ * lisp/dired-x.el (dired-x-guess-filename-at-point): Rename (bug#43961).
+ (dired-filename-at-point): Made into an obsolete alias, since the name
+ can be confused with the unrelated dired-file-name-at-point function.
+
+2020-10-14 Philipp Klaus Krause <pkk@spth.de> (tiny change)
+
+ Mark the return value from strerror as a constant
+
+ * src/emacs.c (main): Mark the return from strerror as a constant,
+ since it shouldn't be changed (bug#43982).
+
+ * lib-src/movemail.c (pfatal_and_delete): Ditto.
+
+2020-10-14 Masahiro Nakamura <tsuucat@icloud.com>
+
+ Improve package install/delete button action
+
+ * lisp/emacs-lisp/package.el (package-install-button-action)
+ (package-delete-button-action): Run describe-package instead of
+ revert-buffer in order to use newer package-desc (bug#43983).
+
+2020-10-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix name of the module .h files in the comments
+
+ * src/emacs-module.c: Fix the name of the .h file in the comments.
+
+2020-10-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Move the new module unibyte function to the correct module-env.h file
+
+ * src/module-env-28.h: Moved here from the -25.h file.
+
+2020-10-13 Mattias Engdegård <mattiase@acm.org>
+
+ * etc/NEWS (Calc): Note new precedence of '/' in TeX input mode.
+
+2020-10-13 Paul Eggert <eggert@cs.ucla.edu>
+
+ nnimap MODSEQ cleanup
+
+ * lisp/gnus/nnimap.el (nnimap-parse-flags):
+ Remove old hack that deletes MODSEQ entries in the buffer, as
+ Emacs now has bignums and so won't misparse MODSEQs (Bug#38938).
+
+2020-10-13 Paul Eggert <eggert@cs.ucla.edu>
+
+ eql doc improvements
+
+ * doc/lispref/numbers.texi (Comparison of Numbers):
+ Copy some useful text from eql help string.
+ * src/fns.c (Feql): In doc string, say that eql also compares
+ integers by value.
+
+2020-10-13 Eli Zaretskii <eliz@gnu.org>
+
+ Fix documentation of Outline cycling commands
+
+ * lisp/outline.el (outline-mode-map): Fix wording of a comment.
+
+ * doc/emacs/text.texi (Outline Visibility): Fix wording and markup
+ of a recently added paragraph. Improve indexing.
+
+ * etc/NEWS: Fix whitespace of a recently added entry.
+
+2020-10-13 Eli Zaretskii <eliz@gnu.org>
+
+ * etc/NEWS: Mention 'make_unibyte_string'; reformat modules entries.
+
+2020-10-13 Mattias Engdegård <mattiase@acm.org>
+
+ Calc: allow infinite binary word size (bug#43764)
+
+ Setting the word size ("b w") to 0 removes the word size clipping for
+ all bit operations (effectively as if a word size of -∞ had been set).
+ Rotation is disallowed; logical and arithmetic shifts behave
+ identically.
+
+ After a suggestion by Vincent Belaïche.
+
+ * lisp/calc/calc-bin.el (calc-word-size, math-binary-arg)
+ (math-binary-modulo-args, calcFunc-lsh, calcFunc-ash, calcFunc-rot)
+ (math-clip, math-format-twos-complement): Allow a word size of 0,
+ meaning -∞.
+ * test/lisp/calc/calc-tests.el
+ (calc-tests--not, calc-tests--and, calc-tests--or, calc-tests--xor)
+ (calc-tests--diff): New functions.
+ (calc-tests--clip, calc-tests--rot, calc-shift-binary): Extend to
+ cover word size 0.
+ (calc-bit-ops): New test.
+ * doc/misc/calc.texi (Binary Functions): Update manual.
+ * etc/NEWS: Announce the change.
+
+2020-10-13 Mattias Engdegård <mattiase@acm.org>
+
+ Calc: revert to old precedence of '/' in (La)TeX input mode
+
+ Make the '/' precedence higher than that of '+' and '-' again,
+ partially reverting fda9b316f84 (bug#43902).
+
+ * lisp/calc/calc-lang.el (tex): Change precedence of '/'.
+ * test/lisp/calc/calc-tests.el (calc-latex-input): New test.
+
+2020-10-13 Mattias Engdegård <mattiase@acm.org>
+
+ Calc: make tests less chatty
+
+ * test/lisp/calc/calc-tests.el (calc-extract-units, calc-convert-units)
+ (calc-matrix-determinant, calc-choose): Remove "Working..." messages.
+ (calc-tests--check-choose, calc-tests--explain-choose): Eliminate.
+
+2020-10-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow creating unibyte strings from Emacs modules
+
+ * doc/lispref/internals.texi (Module Values): Document
+ make_unibyte_string (bug#34873).
+
+ * src/emacs-module.c (module_make_unibyte_string): New function.
+ (initialize_environment): Export it.
+
+ * src/module-env-25.h: Define it.
+
+ * test/data/emacs-module/mod-test.c (Fmod_test_return_unibyte):
+ Test it.
+
+ * test/src/emacs-module-tests.el (module/unibyte): Test it.
+
+2020-10-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Partially revert previous patch to emacs.service
+
+ * etc/emacs.service (ExecStop): Partially revert previous patch
+ for bug#37847, since: "This appears to break packages that rely on
+ `invocation-name' to be executable."
+
+2020-10-13 Yuan Fu <casouri@gmail.com>
+
+ Add cycling commands to outline
+
+ * lisp/outline.el (outline--cycle-state, outline-has-subheading-p)
+ (outline-cycle, outline-cycle-buffer): New functions.
+ (outline-mode-map): Add key bindings for the two new commands.
+ (outline--cycle-buffer-state): New variable.
+ * doc/emacs/text.texi (Outline Visibility): Add 'outline-cycle' and
+ 'outline-cycle-buffer'.
+ * etc/NEWS (Outline): Record the change (bug#41130).
+
+2020-10-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make read-char-choice less modal
+
+ * lisp/subr.el (read-char-choice): Use `read-char-from-minibuffer'
+ here (bug#42708) so that we're not as modal (and users can copy
+ the help buffer, if they should so want).
+
+2020-10-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make diary fontify headers correctly (if the date has been customized)
+
+ * lisp/calendar/diary-lib.el (diary-fancy-display): Insert the
+ heading with the correct face, so that it doesn't have to be
+ re-matched later (which is generally impossible) (bug#13072).
+ (diary-fancy-date-pattern, diary-fancy-date-matcher): Make obsolete.
+ (diary-fancy-font-lock-keywords): Don't use.
+ (diary-fancy-font-lock-fontify-region-function): Don't use.
+
+2020-10-13 Mauro Aranda <maurooaranda@gmail.com>
+
+ Don't bind sort-fold-case when saving the custom-file
+
+ * lisp/cus-edit.el (custom-save-variables, custom-save-faces): These
+ functions sort a list, not buffer text, so they don't need
+ to use sort-fold-case at all. Remove the let-binding for
+ sort-fold-case (bug#43919).
+
+2020-10-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Have header-line-highlight inherit from mode-line-highlight
+
+ * lisp/faces.el (header-line-highlight): Inherit from
+ mode-line-highlight instead of highlight (bug#43926). This is
+ consistent with header-line inheriting from mode-line.
+
+2020-10-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ message-insert-signature doc fix
+
+ * lisp/gnus/message.el (message-insert-signature): Clarify what
+ FORCE means.
+
+2020-10-13 Boruch Baum <boruch_baum@gmx.com>
+
+ Add a keybinding to the help menu to display manuals
+
+ * lisp/help.el (help-for-help-internal): Add a keybinding to
+ prompt for and display a manual (bug#43956).
+
+2020-10-12 Juri Linkov <juri@linkov.net>
+
+ * lisp/isearch.el (isearch-search): Set isearch-match-data in the right place.
+
+2020-10-12 Brian Leung <leungbk@mailfence.com>
+
+ Fix some compilation warnings in non nativecomp build (bug#43892)
+
+ * lisp/emacs-lisp/advice.el (comp-subr-trampoline-install):
+ Declare function.
+ * lisp/emacs-lisp/find-func.el (comp-eln-to-el-h): Declare
+ variable.
+ * lisp/emacs-lisp/nadvice.el (comp-subr-trampoline-install):
+ Declare function.
+ * lisp/files.el (comp-eln-to-el-h): Declare variable.
+ * lisp/help.el (subr-native-lambda-list): Declare function.
+
+2020-10-12 Andrea Corallo <akrl@sdf.org>
+
+ Revert "Fix some compilation warnings in non nativecomp build (bug#43892)"
+
+ This reverts commit 6606ec8e313bf48a1ac7b63c52bfeb64c4257107.
+
+2020-10-12 Andrea Corallo <akrl@sdf.org>
+
+ Fix some compilation warnings in non nativecomp build (bug#43892)
+
+ * lisp/emacs-lisp/advice.el (comp-subr-trampoline-install):
+ Declare function.
+ * lisp/emacs-lisp/find-func.el (comp-eln-to-el-h): Declare
+ variable.
+ * lisp/emacs-lisp/nadvice.el (comp-subr-trampoline-install):
+ Declare function.
+ * lisp/files.el (comp-eln-to-el-h): Declare variable.
+ * lisp/help.el (subr-native-lambda-list): Declare function.
+
+2020-10-12 Stefan Kangas <stefan@marxist.se>
+
+ Fix man page title lines and timestamps
+
+ * doc/man/ebrowse.1:
+ * doc/man/emacs.1.in:
+ * doc/man/emacsclient.1:
+ * doc/man/etags.1: Update date to match last significant change. Set
+ file local variable time-stamp-pattern. Fix title line to match the
+ recommendations in "man man-pages".
+ Ref: https://lists.gnu.org/r/emacs-devel/2020-09/msg01002.html
+
+2020-10-12 Michael Albinus <michael.albinus@gmx.de>
+
+ Make tramp-completion-reread-directory-timeout obsolete (Bug#43932)
+
+ * doc/misc/tramp.texi (File name completion, Frequently Asked Questions):
+ Remove `tramp-completion-reread-directory-timeout'. (Bug#43932)
+
+ * etc/NEWS: Mention tramp-completion-reread-directory-timeout as obsolete.
+
+ * lisp/net/tramp.el (tramp-completion-reread-directory-timeout):
+ Make it obsolete.
+
+2020-10-12 Hugh Daschbach <hdasch@fastmail.com>
+
+ Add interface arg to D-Bus PropertiesChanged signal.
+
+ * lisp/net/dbus.el (dbus-register-property, dbus-property-handler):
+ Fix signal generation. (Bug#43936)
+
+ * test/lisp/net/dbus-tests.el (dbus-test06-register-property-emits-signal):
+ Fix test.
+
+2020-10-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/proced.el: Fix behavior with variable-pitch `header-line` face
+
+ Also, use lexical-scoping. Remove redundant `:group` args.
+ (proced-process-alist, proced-header-line): Use `defvar-local`
+ (proced-header-line): Put :align-to on spaces to improve result with
+ variable-pitch header-line face.
+ (proced-filter, proced-format): Use a closure instead of `(lambda ...).
+
+2020-10-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a reference to the shortdoc command in the Emacs manual
+
+ * doc/emacs/help.texi (Name Help): Mention shortdoc.
+
+2020-10-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a shortdoc menu entry
+
+ * lisp/menu-bar.el (menu-bar-describe-menu): Add a shortdoc menu
+ entry.
+
+2020-10-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix error in file shortdoc group
+
+ * lisp/emacs-lisp/shortdoc.el (number): Add some more numeric
+ stuff (and clean up some arglists).
+
+2020-10-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/hexl.el: Fix behavior with variable-pitch `header-line` face
+
+ (hexl-ascii-region): Don't inherit from the `header-line`.
+ (hexl-font-lock-keywords): Fix text alignment.
+ (hexl-mode): Set `font-lock-extra-managed-props` accordingly.
+
+2020-10-11 Alan Third <alan@idiocy.org>
+
+ Fix GNUstep build
+
+ Fix mistakes made when removing Cocoa code from nsfont.m.
+
+ * src/nsfont.m (nsfont_draw): Remove spurious #ifdef.
+ (ns_uni_to_glyphs): The #if/#endif was removed from this code, but the
+ code itself not removed. Remove it now.
+
+2020-10-11 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/tooltip.el: Remove redundant :group args.
+
+ * lisp/tooltip.el: Use lexical-binding.
+
+2020-10-11 Gregory Heytings <ghe@sdf.org> (tiny change)
+
+ Fix 'message' when there's active minibuffer on another frame
+
+ * lisp/minibuffer.el (set-minibuffer-message): Don't reuse the
+ active minibuffer for displaying messages unless the active
+ minibuffer is on the same frame as the selected window.
+
+2020-10-11 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of shortdoc features
+
+ * lisp/help-fns.el (help-fns-describe-function-functions): Doc
+ fix.
+ * lisp/emacs-lisp/shortdoc.el (define-short-documentation-group)
+ (shortdoc-display-group, shortdoc-add-function): Doc fixes.
+
+ * doc/lispref/help.texi (Documentation Groups): Improve the
+ recently-added documentation and the indexing.
+
+2020-10-11 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/url/url-domsuf.el: Use lexical-binding.
+
+2020-10-11 Stefan Kangas <stefan@marxist.se>
+
+ Convert url-domsuf.el tests to ert
+
+ * lisp/url/url-domsuf.el: Move commented out tests from here...
+ * test/lisp/url/url-domsuf-tests.el: ...to this new file.
+
+2020-10-11 Stefan Kangas <stefan@marxist.se>
+
+ Update publicsuffix.txt from upstream
+
+ * etc/publicsuffix.txt: Update from
+ https://publicsuffix.org/list/public_suffix_list.dat
+ dated 2020-10-09 08:23:34 UTC.
+
+2020-10-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add more numeric shortdocs
+
+ * lisp/emacs-lisp/shortdoc.el (shortdoc-section)
+ (shortdoc-example): Lighten up colours on light backgrounds.
+
+2020-10-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak shortdoc colours on light backgrounds
+
+ * lisp/emacs-lisp/shortdoc.el (shortdoc-section)
+ (shortdoc-example): Lighten up colours on light backgrounds.
+
+2020-10-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Autoload shortdoc command and adjust NEWS
+
+ * lisp/emacs-lisp/shortdoc.el (shortdoc-display-group): Autoload.
+
+2020-10-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use Unicode arrows in shortdoc results
+
+ * lisp/emacs-lisp/shortdoc.el (shortdoc--display-function): Use
+ Unicode arrows if possible.
+
+2020-10-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't boldify the flyspell language indicator in the mode line
+
+ * lisp/textmodes/flyspell.el (flyspell-mode): Don't boldify the
+ language part -- it draws too much attention in the minor mode list.
+
+2020-10-11 Stephen Berman <stephen.berman@gmx.net>
+
+ Allow killing files with C-k in wdired if -F is used
+
+ * lisp/wdired.el (wdired-change-to-wdired-mode): Add hook to
+ restore properties.
+ (wdired-change-to-wdired-mode): Adjust check for symlinks.
+ (wdired-preprocess-files): Fix parsing when using the -F flag.
+ (wdired-get-filename): Fix parsing of symlinks when using the -F flag.
+ (wdired--restore-properties): Renamed, and restore more properties
+ (bug#18475).
+
+2020-10-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add support for displaying short documentation for function groups
+
+ * doc/lispref/help.texi (Documentation Groups): Document it.
+
+ * lisp/help-fns.el (help-fns--mention-shortdoc-groups): Output
+ references to the shortdocs.
+
+ * lisp/emacs-lisp/shortdoc.el: New file.
+
+2020-10-11 Juri Linkov <juri@linkov.net>
+
+ Make C-w worth in isearch when at the last match in the buffer
+
+ * lisp/isearch.el (isearch-yank-internal): Make C-w work when at
+ the last match in the buffer (bug#22118).
+
+2020-10-11 Noam Postavsky <npostavs@users.sourceforge.net>
+
+ Clarify how to set single-function hooks
+
+ * doc/lispref/modes.texi (Hooks): Clarify the difference between
+ normal hooks and single-function "hooks" (bug#25581).
+
+2020-10-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix link in previous display.texi change
+
+ * doc/lispref/display.texi (Fontsets): Link to the correct node in
+ the Elisp manual, not in the Emacs manual.
+
+2020-10-11 Robert Weiner <rsw@gnu.org>
+
+ Make posn-set-point work on frame events
+
+ * lisp/subr.el (event-start): Mention the frame part of the events.
+ (posn-window): Ditto.
+ (posn-set-point): Make this work if the event is a frame event
+ (bug#28621).
+
+2020-10-11 Robert Pluim <rpluim@gmail.com>
+
+ Fix the documentation of char-displayable-p
+
+ * doc/lispref/display.texi (Fontsets): Make the documentation of
+ char-displayable-p less incorrect (bug#35230).
+
+2020-10-10 Rasmus <rasmus@gmx.us>
+
+ gnus-icalendar.el: Fix bug in gnus-icalendar-identities
+
+ * lisp/gnus/gnus-icalendar.el (gnus-icalendar-event--find-attendee):
+ (gnus-icalendar-identities) `gnus-ignored-from-addresses' and
+ `message-alternative-emails' may be functions. This is not
+ supported by `gnus-icalendar-event--find-attendee' (bug#43908).
+
+2020-10-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/calc/: Use lexical scoping in all the files
+
+ Includes the following pervasive changes:
+ - Move some defvars earlier in the file so they cover earlier let-bindings
+ - Change dynamically scoped `calc-FOO` or `math-FOO` function arguments
+ to just FOO and then let-bind the `calc-FOO` or `math-FOO` variable
+ explicitly in the body of the function. In some cases, the
+ beginning of the function was changed to refer to FOO so as to delay
+ the binding to a nearby `let` when I could ensure that it did
+ not make a difference.
+ - Add an underscore in front of unused vars or comment them out altogether.
+ - Replace unused `err` arg to `condition-case` with nil.
+
+ Plus the additional itemized changes below.
+
+ * lisp/calc/calc-map.el (calcFunc-reducer):
+ * lisp/calc/calc-arith.el (math-setup-declarations):
+ * lisp/calc/calc-help.el (calc-full-help, calc-help-index-entries)
+ (calc-full-help): Use `ignore-errors`.
+
+ * lisp/calc/calc-embed.el (calc-embedded-modes-change):
+ Declare `the-language` and `the-display-just` as dynamically scoped.
+
+ * lisp/calc/calc-forms.el (math-setup-year-holidays): Use `dolist`.
+
+ * lisp/calc/calc-graph.el (calc-graph-set-styles): Use `symbol-value`
+ rather than `eval.`
+ (calc-graph-delete-temps, calc-graph-set-styles): Use ignore-errors.
+
+ * lisp/calc/calc-macs.el (calc-with-trail-buffer): Add artificial use
+ of `save-buf` to silence compiler warnings in all the cases where
+ `body` doesn't make use of it.
+
+ * lisp/calc/calc-math.el (math-largest-emacs-expt)
+ (math-smallest-emacs-expt, math-use-emacs-fn): Use ignore-errors.
+
+ * lisp/calc/calc-mode.el (calc-total-algebraic-mode): Remove "P" from
+ interactive spec since it's not used anyway.
+
+ * lisp/calc/calc-rewr.el (calc-match): Simplify.
+
+ * lisp/calc/calc.el (calc-buffer): Give it a global nil value,
+ so it's automatically declared dynbound in any file that requires `calc`.
+ (calcDigit-nondigit): Adjust accordingly.
+
+ * lisp/calc/calcalg2.el (calcFunc-table): Declare `var-dummy` as dynbound.
+ (math-scan-for-limits): Comment out dead code.
+
+ * lisp/calc/calcalg3.el (math-general-fit): Declare `var-YVAL` and
+ `var-YVALX` as dynbound.
+
+2020-10-10 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/help.el (help-function-arglist): Fix non nativecomp builds (bug#43914)
+
+2020-10-10 Andrea Corallo <akrl@sdf.org>
+
+ As edges are indexed store them in an hash table
+
+ * lisp/emacs-lisp/comp.el (comp-edge): Update doc for 'number'
+ slot.
+ (comp-func): Rename 'edges' slot into 'edges-h'.
+ (comp-log-edges): Update logic for edges in an hash table.
+ (comp-clean-ssa, comp-compute-edges): Likewise.
+
+2020-10-10 Andrea Corallo <akrl@sdf.org>
+
+ Add into phi l-value args basic block names
+
+ * lisp/emacs-lisp/comp.el (comp-ssa-rename-insn): Clean-up a
+ leftover space.
+ (comp-finalize-phis): Cons the blasic block name providing the
+ mvar together with the mvar itself while forming the phi.
+ (comp-fwprop-insn): Destructure correctly the phi.
+
+2020-10-10 Andrea Corallo <akrl@sdf.org>
+
+ Provide feature nativecomp and make use of it
+
+ * lisp/emacs-lisp/comp.el (comp-ensure-native-compiler): Use
+ `featurep' to identify if the native compiler is available.
+ * lisp/emacs-lisp/nadvice.el (advice--add-function): Likewise.
+ * lisp/emacs-lisp/package.el (package--delete-directory): Likewise.
+ * lisp/loadup.el: Likewise.
+ * src/comp.c (syms_of_comp): Provide feature nativecomp.
+
+2020-10-10 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-func): Fix doc for blocks slot.
+
+2020-10-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Doc tweak
+
+ Try and clarify the meaning of `init-value`.
+
+2020-10-10 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ c00606171f (origin/emacs-27) A better fix for bug#43886
+ 3196fd44c3 Avoid crashes when a theme is loaded with one frame suspended
+ 0407b15500 Removed an incorrectly placed extra word in the semantic docs
+ 040dcbe53e Fix current-line hscrolling when overlays change
+ c56eeba2ce Extend tests for shell-command-dont-erase-buffer
+
+2020-10-10 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ b6704d58e8 ; * src/xdisp.c (Fwindow_text_pixel_size): Doc fix.
+
+2020-10-10 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ acc9b46153 Fix merging of region face for non-ASCII characters
+ c2a13969e4 Make drag and drop on NS open all URLs (bug#43470)
+
+2020-10-10 Andrea Corallo <akrl@sdf.org>
+
+ Fix LIMPLE latch block name coloring in "*Native-compile-Log*"
+
+ * lisp/emacs-lisp/comp.el (comp-limple-lock-keywords): Fix
+ latch block name coloring.
+
+2020-10-10 Brian Leung <leungbk@mailfence.com>
+
+ Various typo fixes in native compiler related files
+
+ * lisp/emacs-lisp/comp.el (native-compiler-error-dyn-func)
+ (comp-func, comp-func-l)
+ (comp-func-d, comp-ensure-native-compiler, comp-type-hint-p)
+ (comp-func-unique-in-cu-p, comp-alloc-class-to-container)
+ (comp-limple-mode, comp-loop-insn-in-block)
+ (comp-lex-byte-func-p, comp-c-func-name, comp-decrypt-arg-list)
+ (comp-spill-lap-function, comp-intern-func-in-ctxt)
+ (comp-spill-lap-function, comp-spill-lap, comp-emit-handler)
+ (comp-prepare-args-for-top-level): Various typo fixes.
+ * src/comp.c (Fcomp_el_to_eln_filename): Fix typo in error
+ message.
+
+2020-10-10 Mattias Engdegård <mattiase@acm.org>
+
+ Improve coverage of Calc bit shift test
+
+ * test/lisp/calc/calc-tests.el (calc-tests--rsh, calc-tests--rash)
+ (calc-shift-binary): Test with negative word sizes.
+
+2020-10-10 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-10-10 Andrea Corallo <akrl@sdf.org>
+
+ Fix failure when compiling a trampoline with no eln-cache dir (bug#43875)
+
+ * lisp/emacs-lisp/comp.el (comp-trampoline-compile): Try to create
+ the eln-cache dir if this is not existing, if fails to do that
+ move on to the next one.
+
+2020-10-10 Andrew Whatson <whatson@gmail.com>
+
+ * Fix typo name plus make error homogeneous in `comp-trampoline-compile'
+
+ * lisp/emacs-lisp/comp.el (comp-trampoline-compile): Fix typo
+ renaming `comp-tampoline-compile' -> `comp-trampoline-compile'.
+ Change error to be consistent.
+ (comp-subr-trampoline-install): Use `comp-trampoline-compile'.
+
+2020-10-10 Eli Zaretskii <eliz@gnu.org>
+
+ A better fix for bug#43886
+
+ * src/xfaces.c (load_color2, Fcolor_distance): Revert last change.
+ * src/term.c (clear_tty_hooks): Don't clear defined_color_hook.
+
+2020-10-10 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Fix dictionary tooltip mode
+
+ * lisp/net/dictionary.el (dictionary-tooltip-mode): Add mouse movement
+ binding and use tooltip-functions instead of tooltip-hook
+
+ There were some changes in Emacs since testing it the last time. I had
+ to add keybinding for mouse movement and enable track-mouse to get the
+ mode working again.
+
+2020-10-09 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid crashes when a theme is loaded with one frame suspended
+
+ * src/xfaces.c (load_color2, Fcolor_distance): Don't try to call
+ the frame's defined_color_hook if the frame is suspended.
+ (Bug#43886)
+
+2020-10-09 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Adding details page for dictionary
+
+ * lisp/net/dictionary.el (dictionary-display-dictionary-line):
+ Allow getting more details on a dictionary by clicking the
+ "(Details)" link.
+
+ I had the functionality to query the dictionary information but no
+ mechanism to invoke it. So just add a button after the short
+ description of the dictionary to get more information.
+
+2020-10-09 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Dictionary now uses button
+
+ * lisp/net/dictionary-link.el: Removed now obsolete file
+ * lisp/net/dictionary.el: Use insert-button and make-button
+ * lisp/net/dictionary.el (dictionary-mode-map): Now defined using defvar
+
+ I had to add a conversion function as parameter for the button 'action
+ as I need to be able to pass nil data to my function. This is not
+ possible with the regular button 'action function and the 'button-data
+ value.
+
+ The functionality of searching a link in all dictionaries has been
+ removed for now. It might appear again once I have an idea how to
+ implement it.
+
+2020-10-09 Eli Zaretskii <eliz@gnu.org>
+
+ Add Euro Sign to Latin language input methods
+
+ * lisp/leim/quail/latin-post.el ("danish-postfix")
+ ("finnish-postfix", "french-postfix", "german-postfix")
+ ("icelandic-postfix", "italian-postfix", "norwegian-postfix")
+ ("scandinavian-postfix", "spanish-postfix", "swedish-postfix"):
+ Add "E=" for the Euro Sign. (Bug#43866)
+
+2020-10-09 Mattias Engdegård <mattiase@acm.org>
+
+ Calc: fix arithmetic right shift sign bit detection
+
+ Arithmetic right shift didn't compute the bit to shift in correctly.
+ For example, #x600000000 right-shifted 8 steps (with 32 bit word size)
+ resulted in #xff000000 rather than 0. (Bug#43764)
+
+ * lisp/calc/calc-bin.el (calcFunc-ash): Fix condition.
+ * test/lisp/calc/calc-tests.el (calc-tests--clip, calc-tests--lsh)
+ (calc-tests--rsh, calc-tests--ash, calc-tests--rash, calc-tests--rot):
+ New.
+ (calc-shift-binary): New test.
+
+2020-10-09 Nick Gasson <nick@nickg.me.uk> (tiny change)
+
+ Match OpenBSD doas password prompt in comint
+
+ * lisp/comint.el (comint-password-prompt-regexp): match OpenBSD doas
+ password prompt. OpenBSD 5.8 replaced sudo with doas in the base
+ install.
+
+ * test/lisp/comint-tests.el (comint-testsuite-password-strings): test
+ that the doas password prompt is matched (bug#43846).
+
+2020-10-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ message-signature doc fix
+
+ * lisp/gnus/message.el (message-signature): Mention
+ message-signature-insert-empty-line (bug#43853).
+
+2020-10-09 Pankaj Jangid <pankaj.jangid@gmail.com> (tiny change)
+
+ Removed an incorrectly placed extra word in the semantic docs
+
+ * doc/misc/semantic.texi (Parser code): Copy edit (bug#43861).
+
+2020-10-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify define-minor-mode hooks
+
+ * doc/lispref/modes.texi (Defining Minor Modes): Note that the
+ code (and the hook) is run both when the mode is enabled and
+ disabled (bug#43868).
+
+2020-10-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Don't eagerly store articles in the Agent by default"
+
+ This reverts commit def34a20766ea5179afd5e5ed090a2b86fcccb5e.
+
+ This made storing articles in the Agent very slow.
+
+2020-10-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Only skip directories in lgrep, not the other grep commands
+
+ * lisp/progmodes/grep.el (lgrep): Do the directory ignores here
+ (bug#23590).
+ (grep-compute-defaults): ... instead of here, because this would
+ affect all grep commands, not just lgrep.
+
+2020-10-08 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Don't check for existence of defface
+
+ * lisp/net/dictionary.el: defface has been available in Emacs for quite
+ some time now. No need to check it before using it.
+
+2020-10-08 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Don't check coding-system-list for existence
+
+ * lisp/net/dictionary.el (dictionary-coding-systems-for-dictionaries):
+ Don't check for coding-system-list before using it. It check no longer
+ be necessary.
+
+2020-10-08 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Add :version tag to defcustom statement
+
+ * lisp/net/dictionary.el: Add :version tag to all defcustom statements
+
+ Suggested-By: Robert Pluim <rpluim@gmail.com>
+
+2020-10-08 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Move the handling of keyword auto into type handling for C++.
+
+ This should allow auto, const, static, ... to be in any order.
+
+ * lisp/progmodes/cc-engine.el (c-forward-type): New return value 'no-id for
+ when auto precludes the parsing of a type identifier. Adapt processing for
+ this.
+ (c-forward-decl-or-cast-1): Use the new facility from c-forward-type.
+
+ * lisp/progmodes/cc-langs.el (c-type-modifier-prefix-kwds): Insert the value
+ of c-no-type-kwds into the value.
+ (c-no-type-kwds, c-no-type-key): New lang consts/vars, basically "auto".
+ (c-typeless-decl-kwds, c-modifier-kwds): Remove "auto" from the C++ value.
+
+2020-10-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/ftcrfont.c (ftcrfont_open): Initialize the `max_width` field
+
+ On a 32bit build, Emacs can otherwise crash with a !FIXNUM_OVERFLOW_P
+ assertion in `Ffont_info` by simply doing `emacs -Q` and then `C-s`.
+
+ * src/font.c: Try and detect uninitialized `max_width` fields.
+ (font_make_object): Set max_width to a silly value.
+ (Ffont_info): Check the value is not silly any more.
+
+2020-10-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/doc-view.el: Fix "can't resize root window" error
+
+ (doc-view-fit-window-to-page): Change approach to detect when the
+ frame needs to be resized.
+
+2020-10-08 Eli Zaretskii <eliz@gnu.org>
+
+ Fix current-line hscrolling when overlays change
+
+ * src/xdisp.c (redisplay_internal): Disable "optimization 1" when
+ auto-hscrolling current line and we're redisplaying the selected
+ window. (Bug#43835)
+
+2020-10-08 Michael Albinus <michael.albinus@gmx.de>
+
+ Extend tests for shell-command-dont-erase-buffer
+
+ * test/lisp/simple-tests.el
+ (simple-tests-shell-command-dont-erase-buffer): Extend test.
+
+ * test/lisp/net/tramp-tests.el
+ (tramp-test32-shell-command-dont-erase-buffer): Adapt test. Tag
+ it :unstable.
+
+2020-10-08 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Removed some compatibility parts in dictionary
+
+ * lisp/net/dictionary.el: Use cl-lib, remove defface and defgroup
+ checks, remove xemacs-related code.
+ * lisp/net/dictionary-link.el: Remove xemacs-related code.
+
+2020-10-08 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Renamed link.el
+
+ * lisp/net/link.el: Renamed to connection-link.el, also prefixing
+ all functions with "dictionary-" prefix
+ * lisp/net/dictionary.el: Adapt to renamed functions
+
+2020-10-08 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Renamed connection.el
+
+ * lisp/net/connection.el: Renamed to dictionary-connection.el, also
+ prefixing all functions with "dictionary-" prefix
+ * lisp/net/dictionary.el: Adapt to renamed functions
+
+2020-10-08 Torsten Hilbrich <torsten.hilbrich@gmx.net>
+
+ Importing dictionary module
+
+ * lisp/net: Adding files connection.el, link.el, dictionary.el,
+ imported from https://github.com/myrkr/dictionary-el.git
+
+2020-10-08 Dmitry Gutov <dgutov@yandex.ru>
+
+ Mention two more functions in the commentary
+
+ * lisp/progmodes/project.el:
+ Mention two more functions in the commentary (bug#43595).
+
+2020-10-07 Andrea Corallo <akrl@sdf.org>
+
+ Fix failure when eln-cache is removed (introduced by 4a1bb46260)
+
+ * src/comp.c (make_directory_wrapper, make_directory_wrapper_1):
+ New functions.
+ (Fcomp_el_to_eln_filename): If base_dir is not
+ specified and we are searching across `comp-load-path' try to
+ create a directory if does not exists.
+
+2020-10-07 Andrea Corallo <akrl@sdf.org>
+
+ Fix some nits in comp.el
+
+ * lisp/emacs-lisp/comp.el (comp-spill-lap-function): Use
+ `cl-defmethod' where correct in place of `cl-defgeneric'.
+ (comp-tampoline-compile): Add missing #.
+
+2020-10-07 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'isearch-group-N' faces
+
+ * etc/NEWS:
+ * doc/emacs/search.texi (Search Customizations): Improve and
+ clarify the wording of the 'isearch-group-N' faces description.
+
+ * lisp/isearch.el (search-highlight-submatches): Doc fix.
+
+2020-10-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change in frame.el.
+
+ * lisp/frame.el (frame-set-background-mode): Fix last change: yet
+ another place where FRAME was not taken into account, using the
+ selected frame instead. (Bug#43837)
+
+2020-10-07 Hong Xu <hong@hong.me>
+
+ Clarify what ``chrooted environment means'' for TRAMP
+
+ * doc/misc/tramp.texi (Frequently Asked Questions): Clarify what
+ ``chrooted environment means'' for TRAMP (bug#43839).
+
+2020-10-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix face recalculation when frame's background mode changes
+
+ * lisp/frame.el (frame-set-background-mode): Use the FRAME
+ argument instead of the selected frame, when calling
+ 'face-spec-match-p'. (Bug#43837)
+
+2020-10-07 Andrea Corallo <akrl@sdf.org>
+
+ Do use echo area for async compilation started/finished messages
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers)
+ (native-compile-async): Do not write into the echo area.
+
+2020-10-07 Andrea Corallo <akrl@sdf.org>
+
+ Better libgccjit related error messaging during configure
+
+ * configure.ac: Distinguish the case when libgccjit is missing,
+ its headers are missing, or libgccjit is broken. Message the user
+ based on that.
+
+2020-10-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove mention of the obsolete cust-print.el from the manual
+
+ * doc/lispref/edebug.texi (Printing in Edebug): Remove mention of
+ the obsolete cust-print.el (bug#37956) and adjust the text a bit.
+
+2020-10-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Update documentation on this-command-keys to reflect new behavior
+
+ * doc/lispref/commands.texi (Command Loop Info):
+ `this-command-keys' does not include the C-u any more, so remove
+ that from the description and the example
+ (bug#22107).
+
+ * src/keyboard.c (Fthis_single_command_keys): Don't say that
+ `this-command-keys' returns the C-u prefix (bug#22111).
+
+2020-10-07 Alex Gramiak <agrambot@gmail.com>
+
+ Default the grep commands to skip directories
+
+ * lisp/progmodes/grep.el (grep-compute-defaults): Skip directories
+ (bug#23590).
+
+2020-10-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make artist-mode work when display-line-numbers-mode is on
+
+ * lisp/textmodes/artist.el (artist--adjust-x): New function.
+ (artist-mouse-draw-continously, artist-mouse-draw-poly)
+ (artist-mouse-draw-1point, artist-mouse-draw-2points): Use it to
+ take `display-line-numbers-mode' widths into account.
+
+2020-10-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove reference to outdated Gnus variable from the manual
+
+ * doc/misc/gnus.texi (Startup Variables): Remove reference to
+ gnus-use-backend-marks, which was removed in 2011 (bug#43833).
+
+2020-10-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ alist-get doc string further clarification
+
+ * lisp/subr.el (alist-get): Mention generalized variables again
+ for easier cross-referencing (bug#43836).
+
+2020-10-07 Hong Xu <hong@hong.me>
+
+ Clarify what ``chrooted environment means'' for TRAMP
+
+ * doc/misc/tramp.texi (Frequently Asked Questions): Clarify what
+ ``chrooted environment means'' for TRAMP (bug#43839).
+
+2020-10-07 Mauro Aranda <maurooaranda@gmail.com>
+
+ Make the State button in Custom use extended menus
+
+ * lisp/cus-edit.el (custom-actioned-widget): New variable.
+ Dynamically hold the widget for which to show the menu.
+ (custom-variable-extended-menu, custom-face-extended-menu)
+ (custom-group-extended-menu): Keymap menus for the State menu. Use
+ custom-actioned-widget for the :enable and :selected forms. Make
+ related items radio buttons. (Bug#4787)
+ (custom-variable-menu, custom-face-menu, custom-group-menu): Keep for
+ backward compatibility, but default to nil, so we prefer the keymap
+ menus instead.
+ (custom-variable-action, custom-face-action, custom-group-action):
+ Pass the keymap menu to widget-choose when the simplified menus
+ are nil.
+
+2020-10-07 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * test/lisp/progmodes/ruby-mode-tests.el: Fix obsolete warnings
+
+2020-10-06 Juri Linkov <juri@linkov.net>
+
+ Add match-data to isearch state and repeat faces to highlight group matches
+
+ * lisp/isearch.el (isearch-match-data): New variable.
+ (isearch-mode): Set isearch-match-data to nil.
+ (isearch-update): Call isearch-highlight with isearch-match-data.
+ (isearch--state): Add isearch-match-data.
+ (isearch--set-state): Restore isearch-match-data.
+ (with-isearch-suspended): Preserve isearch-match-data.
+ (isearch-search): Set isearch-match-data to integers.
+ (isearch-group-1): Rename from isearch-group-odd and adjust colors.
+ (isearch-group-2): Rename from isearch-group-even and adjust colors.
+ (isearch-highlight): Add optional arg 'match-data'.
+ Rewrite search-highlight-submatches part to recycle faces.
+
+ * doc/emacs/search.texi (Search Customizations): Amend the
+ documentation for isearch-group faces.
+
+ (bug#6227, bug#43702)
+
+2020-10-06 Alan Third <alan@idiocy.org>
+
+ Fix crash when creating new NS frame (bug#43812)
+
+ * src/nsterm.m (ns_clear_under_internal_border): Check the frame is
+ live.
+
+2020-10-06 Juri Linkov <juri@linkov.net>
+
+ Add check for bound and true 'ido-everywhere' in multi-occur--prompt
+
+ * lisp/replace.el (multi-occur--prompt): Check if 'ido-everywhere' is
+ bound and true (bug#41633).
+
+2020-10-06 Juri Linkov <juri@linkov.net>
+
+ Fix args of truncate-string-to-width in ibuffer-compile-make-substring-form
+
+ * lisp/ibuffer.el (ibuffer-compile-make-substring-form): Fix args of
+ truncate-string-to-width call (bug#41250)
+
+2020-10-06 Andrea Corallo <akrl@sdf.org>
+
+ Native compiling do not target a directory with no write permission
+
+ * src/comp.c (Fcomp_el_to_eln_filename): Check for write
+ permission while choosing the output directory in
+ `comp-eln-load-path'.
+
+2020-10-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/international/mule.el (define-coding-system): Revert accidental change
+
+ This was accidentally included in a9f147af716aa026ec7778202901c4cb4bd5487d
+ "Use the full name of the null byte/character, not its abbreviation".
+
+2020-10-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/international/mule-util.el: Revert bug#41250 workaround
+
+ (truncate-string-ellipsis): Use the '…' character itself since it
+ should work now and is more readable.
+
+2020-10-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/international/ja-dic-cnv.el: Attempt to fix bug#41250
+
+ (skkdic-convert): Only bind `coding-system-for-read` where needed.
+
+2020-10-06 Mattias Engdegård <mattiase@acm.org>
+
+ Suppress obsoletion warning in test of obsolete rx function
+
+ * test/lisp/emacs-lisp/rx-tests.el (rx-compat): Add byte-compilation
+ warning suppression.
+
+2020-10-06 Mattias Engdegård <mattiase@acm.org>
+
+ Fix last change
+
+ * lisp/international/mule-util.el (truncate-string-ellipsis):
+ Use Unicode hex escapes instead of named escapes here, because \N{...}
+ is not available during bootstrapping. (Bug#41250)
+
+2020-10-06 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change
+
+ * lisp/international/mule-util.el (truncate-string-ellipsis): Add
+ a FIXME comment that explains the last change. (Bug#41250)
+
+2020-10-06 Juri Linkov <juri@linkov.net>
+
+ Don't use the character '…' literally in mule-util.el (bug#41250)
+
+ * lisp/international/mule-util.el (truncate-string-ellipsis):
+ Replace the character '…' with its Unicode name.
+
+2020-10-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix animate test that somehow changed recently
+
+2020-10-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix mule-util-tests after recent truncation changes
+
+ * test/lisp/international/mule-util-tests.el: Fix truncation checks.
+
+2020-10-06 Daniel Martín <mardani29@yahoo.es>
+
+ Add missing full stop in MS-DOS processes documentation
+
+ * doc/emacs/msdos-xtra.texi (MS-DOS Processes): Minor copy edig
+ (bug#43820).
+
+2020-10-06 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Fix a test to ensure cperl-mode is active
+
+ * test/lisp/progmodes/cperl-mode-tests.el
+ (cperl-mode-test-indent-exp): Make sure that cperl-mode is active
+ for testing 'cperl-indent-exp', also skip this test under
+ perl-mode.
+
+ * test/lisp/progmodes/cperl-mode-resources/cperl-indent-exp.pl:
+ Eliminate dependency on unrelated customizable variables (bug#10483).
+
+2020-10-05 Andrea Corallo <akrl@sdf.org>
+
+ Fix a test in test/lisp/subr-tests.el
+
+ * test/lisp/subr-tests.el (subr-tests-bug22027): Redefine
+ `read-string' with a lambda with the same number of arguments.
+
+2020-10-05 Andrea Corallo <akrl@sdf.org>
+
+ Add a test for primitive redefinition
+
+ * test/src/comp-tests.el (primitive-redefine): New test.
+ * test/src/comp-test-funcs.el (comp-test-primitive-redefine-f):
+ New function.
+
+2020-10-05 Andrea Corallo <akrl@sdf.org>
+
+ Make primitive redefinition effective through trampoline synthesis
+
+ * lisp/loadup.el (dump-mode): Set `comp-enable-subr-trampolines'
+ when finished bootstrap.
+ * src/data.c (Ffset): Call `comp-enable-subr-trampolines' when
+ redefining a subr.
+ * src/comp.c (syms_of_comp): Define `comp-subr-trampoline-install'
+ symbol.
+ (syms_of_comp): Define `comp-enable-subr-trampolines' variable.
+
+2020-10-05 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-subr-safe-advice -> comp-subr-trampoline-install
+
+2020-10-05 Andrea Corallo <akrl@sdf.org>
+
+ Revert "Use `advice-flet' in place of `cl-letf' to avoid primitive...
+
+ This reverts commit 825e85b393a3d78ba43176ecc5bc1a9595d0fbea.
+
+2020-10-05 Andrea Corallo <akrl@sdf.org>
+
+ Revert "Add `advice-flet' macro"
+
+ This reverts commit d07d7ab1a0e321ced62ebe5dd9db27eb7e93430e.
+
+2020-10-05 Andreas Schwab <schwab@linux-m68k.org>
+
+ Use the full name of the null byte/character, not its abbreviation
+
+ * lisp/subr.el (inhibit-nul-byte-detection): Make it an obsolete alias.
+ * src/coding.c (setup_coding_system): Use original name.
+ (detect_coding): Rename nul_byte_found => null_byte_found.
+ (detect_coding_system): Use original name.
+ Rename nul_byte_found => null_byte_found.
+ (Fdefine_coding_system_internal): Use original name.
+ (syms_of_coding): Rename inhibit-nul-byte-detection to
+ inhibit-null-byte-detection.
+ * src/w16select.c (get_clipboard_data): Rename nul_char to null_char.
+ * src/json.c (check_string_without_embedded_nulls): Rename from
+ check_string_without_embedded_nuls.
+ (Fjson_parse_string): Adjust accordingly.
+ * src/coding.h (enum define_coding_undecided_arg_index)
+ (enum coding_attr_index): Rename ...nul_byte... to ...null_byte....
+ * lisp/info.el (info-insert-file-contents, Info-insert-dir):
+ * lisp/international/mule.el (define-coding-system):
+ * lisp/vc/vc-git.el (vc-git--call):
+ * doc/lispref/nonascii.texi (Lisp and Coding Systems): Use original name.
+
+2020-10-05 Michael Albinus <michael.albinus@gmx.de>
+
+ * src/dbusbind.c (xd_signature): Better type check for array elements.
+
+ * test/lisp/net/dbus-tests.el (dbus-test01-compound-types): Extend test.
+
+2020-10-05 Eli Zaretskii <eliz@gnu.org>
+
+ Fix merging of region face for non-ASCII characters
+
+ * src/xdisp.c (extend_face_to_end_of_line): Restore the correct
+ original face used by the iterator on this line, not the ASCII
+ face. (Bug#43363)
+
+2020-10-05 Jared Finder <jared@finder.org>
+
+ Sort items in tmm properly, and allow clicking the final item
+
+ * lisp/tmm.el (tmm-menubar-keymap): Sort the final items properly.
+ (tmm-menubar): Allow clicking the final menu item (bug#43756).
+
+2020-10-05 Juri Linkov <juri@linkov.net>
+
+ Use … in Gnus mode lines (when shortening them)
+
+ * lisp/gnus/gnus-sum.el (gnus-set-mode-line): Defer ellipsis
+ creation to `truncate-string-to-width' (bug#41250). This uses …
+ by default.
+
+2020-10-05 Andrea Corallo <akrl@sdf.org>
+
+ * configure.ac (lispdirrel): Fix value for MacOS build.
+
+2020-10-05 Nathan Moreau <nathan.moreau@m4x.org>
+
+ Improve support for using vc commands in indirect buffers
+
+ * lisp/vc/vc.el (vc-deduce-fileset-1): New defun.
+ (vc-deduce-fileset): Adapt.
+ (vc-maybe-buffer-sync): New defun.
+ (vc-diff): Adapt.
+ (vc-ediff): Adapt.
+ (vc-root-diff): Adapt.
+ (vc-revision-other-window): Adapt (bug#40967).
+
+2020-10-05 Eli Zaretskii <eliz@gnu.org>
+
+ Fix the documentation parts of a recent commit
+
+ * lisp/international/mule-util.el (truncate-string-ellipsis): Doc
+ fix.
+
+ * doc/lispref/display.texi (Size of Displayed Text): Improve
+ wording and accuracy of the documentation of
+ 'truncate-string-to-width'. Document the function
+ 'truncate-string-ellipsis'.
+
+ * etc/NEWS: Improve the wording of the entry for
+ 'truncate-string-to-width'.
+
+2020-10-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/xdisp.c (syms_of_xdisp): New var `redisplay_skip_initial_frame`.
+
+ This makes it possible to run most of the redisplay code (tho not the
+ actual drawing since there's nowhere to draw) even when there's no
+ real frame at hand, as is the case in batch mode.
+ This makes `xdisp-tests--minibuffer-resizing` work even in batch.
+
+ (redisplay_internal): Obey it.
+ (init_xdisp): Set `echo_area_window` even in noninteractive mode.
+ * src/dispnew.c (update_frame): Skip the initial frame.
+ * src/frame.c (make_frame): Use 80x25 as the default initial size.
+
+ * test/src/xdisp-tests.el (xdisp-tests--minibuffer-resizing):
+ Use the new var and fix use of `executing-kbd-macro`.
+
+2020-10-04 Andrea Corallo <akrl@sdf.org>
+
+ * configure.ac : Fix typo for MacOS nativecomp introduced by afb765ab3c
+
+2020-10-04 Juri Linkov <juri@linkov.net>
+
+ Use '…' for ellipsis in truncate-string-to-width by default (bug#41250)
+
+ * lisp/international/mule-util.el (truncate-string-ellipsis):
+ Change the default value to nil.
+ (truncate-string-ellipsis): New function.
+ (truncate-string-to-width): Use the value returned from the
+ function 'truncate-string-ellipsis'.
+
+ * lisp/tab-bar.el (tab-bar-tab-name-truncated):
+ * lisp/tab-line.el (tab-line-tab-name-ellipsis):
+ Take advantage of the improvement of the ellipsis default value
+ in truncate-string-to-width and truncate-string-ellipsis.
+
+ * doc/lispref/display.texi (Size of Displayed Text):
+ Improve description of truncate-string-ellipsis.
+
+2020-10-04 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-10-04 Andrea Corallo <akrl@sdf.org>
+
+ Make filename hashing compatible with self contained builds (bug#43532)
+
+ * Makefile.in (lispdirrel): Add replace template.
+ (epaths-force): Form correctly 'PATH_REL_LOADSEARCH' into epath.h
+ * configure.ac (lispdirrel): Define variable (relative path of the
+ lisp files from the installation directory).
+ * src/comp.c (Fcomp_el_to_eln_filename): Update algorithm not to
+ rely on 'PATH_DUMPLOADSEARCH' but on 'PATH_REL_LOADSEARCH'.
+ * src/epaths.in (PATH_REL_LOADSEARCH): Add macro template.
+
+2020-10-04 Andrea Corallo <akrl@sdf.org>
+
+ * configure.ac: Better HAVE_NATIVE_COMP description
+
+2020-10-04 Andrea Corallo <akrl@sdf.org>
+
+ Fix function description message for native compiled lisp functions
+
+ * lisp/help-fns.el (help-fns-function-description-header): Fix
+ message.
+
+2020-10-04 Andrea Corallo <akrl@sdf.org>
+
+ Fix two tests in help-fns-tests.el for native code
+
+ * test/lisp/help-fns-tests.el (help-fns-test-lisp-defun)
+ (help-fns-test-lisp-defsubst): Fix description string
+ for native compiled functions.
+
+2020-10-04 Michael Albinus <michael.albinus@gmx.de>
+
+ Make dbus-unregister-object work for monitors
+
+ * doc/misc/dbus.texi (Monitoring Messages): Rename from
+ "Monitoring Events".
+ (Register Objects, Monitoring Messages):
+ Mention returned object.
+
+ * lisp/net/dbus.el (dbus-unregister-object): Adapt docstring.
+ (dbus-unregister-object): Delete monitor if needed.
+ (dbus-register-monitor): Return proper object.
+
+ * src/dbusbind.c (dbus-registered-objects-table): Adapt docstring.
+
+ * test/lisp/net/dbus-tests.el (dbus--test-signal-handler):
+ Adapt docstring.
+ (dbus-test08-register-monitor): New test.
+
+2020-10-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make update-file-autoloads respect generated-autoload-file
+
+ * lisp/emacs-lisp/autoload.el (update-file-autoloads): Make
+ update-file-autoloads respect `generated-autoload-file', as
+ documented.
+
+2020-10-03 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid segfaults in lookup_image when faces were freed
+
+ * src/image.c (lookup_image): Make sure the frame's face cache
+ exists and has at least the basic faces. If FACE_ID is not a
+ basic face, and is no longer cached, fall back on the 'default'
+ face. (Bug#43700)
+
+2020-10-03 Mauro Aranda <maurooaranda@gmail.com>
+
+ Support extended menus in widget-choose
+
+ * doc/misc/widget.texi (Utilities): Document widget-choose.
+
+ * etc/NEWS: Document the feature (bug#4787).
+ * lisp/wid-edit.el (widget--simplify-menu): New function, to convert
+ extended menus into simplified menus when using the menu to prompt
+ through the minibuffer.
+ (widget-choose): Accept a keymap menu. When not using x-popup-menu,
+ simplify the menu with widget--simplify-menu. Document the changes in
+ the docstring.
+
+2020-10-03 Alan Third <alan@idiocy.org>
+ Daniel Martín <mardani29@yahoo.es>
+
+ Make drag and drop on NS open all URLs (bug#43470)
+
+ * lisp/term/ns-win.el (ns-drag-n-drop): Merge generic and copy
+ actions.
+
+2020-10-02 Alan Mackenzie <acm@muc.de>
+
+ Enhance syntax-tests.el to test comments in parse-partial-sexp
+
+ This now tests the interface between parse-partial-sexp and the low level
+ comment function in syntax.c
+
+ * test/src/syntax-tests.el (syntax-comments-midpoint): New function.
+ (syntax-pps-comments): New macro.
+ (top level): Two new syntax-br-comments tests and five new syntax-pps-comments
+ tests.
+
+ * test/data/syntax-comments.txt (top level): Amend some test fragments and add
+ some more.
+
+2020-10-02 Mattias Engdegård <mattiase@acm.org>
+
+ Calc: fix formatting and parsing Unix time (bug#43759)
+
+ The number of days from epoch to Jan 1, 1970 that was used in parsing
+ and formatting Unix time was incorrect. The previous fix
+ (in e368697ce36) was incomplete.
+
+ Reported by Vincent Belaïche.
+
+ * lisp/calc/calc-forms.el (math-unix-epoch): New constant.
+ (math-format-date-part, math-parse-standard-date, calcFunc-unixtime):
+ Use math-unix-epoch instead of a constant that is sometimes wrong.
+ * test/lisp/calc/calc-tests.el (calc-unix-date): New test.
+
+2020-10-02 Andrea Corallo <akrl@sdf.org>
+
+ Use `advice-flet' in place of `cl-letf' to avoid primitive redefinition
+
+ * test/lisp/time-stamp-tests.el (with-time-stamp-system-name): Use
+ `advice-flet' to advice primitive avoiding redefinition.
+
+ * test/lisp/tempo-tests.el (tempo-p-element-test)
+ (tempo-P-element-test, tempo-r-element-test)
+ (tempo-s-element-test, tempo-r>-element-test): Likewise.
+
+ * test/lisp/subr-tests.el (subr-tests-bug22027): Likewise.
+
+ * test/lisp/shadowfile-tests.el (shadow-test00-clusters)
+ (shadow-test01-sites, shadow-test06-literal-groups)
+ (shadow-test07-regexp-groups): Likewise.
+
+ * test/lisp/replace-tests.el (replace-tests-with-undo): Likewise.
+
+ * test/lisp/play/dissociate-tests.el
+ (dissociate-tests-dissociated-press): Likewise.
+
+ * test/lisp/net/tramp-tests.el (tramp-test10-write-region)
+ (tramp-test21-file-links): Likewise.
+
+ * test/lisp/kmacro-tests.el (kmacro-tests-call-macro-hint-and-repeat)
+ (kmacro-tests-repeat-on-last-key)
+ (kmacro-tests-repeat-view-and-run)
+ (kmacro-tests-bind-to-key-with-key-sequence-in-use): Likewise.
+
+ * test/lisp/files-tests.el (files-tests-read-file-in-~): Likewise.
+
+ * test/lisp/emacs-lisp/rmc-tests.el (test-read-multiple-choice):
+ Likewise.
+
+ * test/lisp/bookmark-tests.el (bookmark-test-bmenu-locate):
+ Likewise.
+
+ * test/lisp/abbrev-tests.el
+ (inverse-add-abbrev-skips-trailing-nonword)
+ (inverse-add-abbrev-skips-trailing-nonword/positive-arg)
+ (inverse-add-abbrev-skips-trailing-nonword/negative-arg): Likewise.
+
+2020-10-02 Andrea Corallo <akrl@sdf.org>
+
+ Add `advice-flet' macro
+
+ The testsuite does large use of primitive redefinition, to avoid that
+ we define `advice-flet' to use instead as an easy `cl-letf'
+ replacement.
+
+ * lisp/emacs-lisp/nadvice.el (advice-flet): New macro.
+
+2020-10-02 Alan Mackenzie <acm@muc.de>
+
+ Enhance syntax-tests.el to test comments in scan-lists
+
+ This now tests the interface between scan_lists and the comment functions.
+
+ * test/src/syntax-tests.el (syntax-br-comments): New macro.
+ ({-in, ;-in, /*-in): Set parse-sexp-ignore-comments to t.
+ (top level): Add 15 tests for comments inside brace lists.
+
+ * test/data/syntax-comments.txt (top level): Amend some test fragments.
+
+2020-10-02 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 78eacf31e8 ; Fix many typos in symbols in docs and comments
+ d5d12707d6 * doc/misc/flymake.texi (Using Flymake): Fix a typo. (Bug...
+
+ # Conflicts:
+ # lisp/allout.el
+ # lisp/progmodes/ebrowse.el
+
+2020-10-02 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 41dcbeccf3 Make aliases introduced in previous patch obsolete
+ 4997032c05 Restore some public debugging functions removed in Emacs 27
+
+2020-10-02 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 2af6b3147d Clarification in Tramp manual
+ 8fbaca7d41 Check Emacs version used for Tramp compilation
+ 90e5549f02 Don't signal an error when saving files on WdebDAV volumes
+ 6f73cc3579 ; * lisp/net/eww.el (eww-search-words): Doc fix.
+ ce0842a165 * lisp/hi-lock.el (hi-lock-find-patterns): Autoload it. (...
+
+2020-10-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix electric-buffer-list buffer selection
+
+ * lisp/ebuff-menu.el (electric-buffer-list): Ensure that point is
+ restored, which isn't always the case if
+ global-display-line-numbers-mode (bug#43755). This enables
+ selecting buffers again.
+
+2020-10-02 Andrea Corallo <akrl@sdf.org>
+
+ When advising search in `comp-eln-load-path' the first writable dir
+
+ * lisp/emacs-lisp/comp.el (comp-tampoline-compile): Do not crash
+ if we can't write in the first entry in `comp-eln-load-path' but
+ search for another one.
+
+2020-10-02 Andrea Corallo <akrl@sdf.org>
+
+ Fix 'incoherent dumped eln file' error when DUMP-METHOD=pbootstrap
+
+ * src/Makefile.in ($(bootstrap_pdmp)): Add missing --bin-dest
+ --eln-dest flags.
+
+2020-10-02 Andrea Corallo <akrl@sdf.org>
+
+ * src/pdumper.c (dump_do_dump_relocation): Better error for incoherent eln.
+
+2020-10-02 Eli Zaretskii <eliz@gnu.org>
+
+ * doc/misc/flymake.texi (Using Flymake): Fix a typo. (Bug#43758)
+
+2020-10-02 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ CC Mode: Convert the handling of c-special-indent-hook to standard usage
+
+ * lisp/progmodes/cc-styles.el (c-set-style): Use kill-local-variable rather
+ than copying the hook's global value to the local binding.
+ (c-make-styles-buffer-local): Remove redundant make-variable-buffer-local.
+
+2020-10-02 Robert Pluim <rpluim@gmail.com>
+
+ Don't error if no GPG signing key configured
+
+ * lisp/gnus/mml-sec.el (mml-secure-epg-sign): Partially revert
+ "Make mml-secure-epg-sign bug out if we can't find an identity".
+ It causes signing to fail for people who have not set up
+ mml-secure-{smime,openpgp}-sign-with-sender, which is a regression
+ from Emacs-26 (Bug#40118). In such a situation gpg will use its
+ default key.
+
+ Do not merge to master. On master Emacs will query the user.
+
+2020-10-02 Mattias Engdegård <mattiase@acm.org>
+
+ Calc: fix business days calculation (bug43677)
+
+ The calculation of business days was broken in 2012 (probably
+ 310e60d9454fe2 or thereabouts) when the date representation changed
+ epoch so that Jan 1, 1 AD became day number 1 instead of 0. Repair
+ this, along with an unrelated bug that prevented arbitrary holiday
+ weekdays from working.
+
+ Reported by Aaron Zeng.
+
+ * lisp/calc/calc-forms.el (math-to-business-day)
+ (math-from-business-day): Correct calculation of weekdays using Calc's
+ current (Rata Die) chronology. Modify loop condition to cope with odd
+ sets of holiday weekdays.
+ * test/lisp/calc/calc-tests.el (calc-business-days): New test.
+
+2020-10-02 Andrea Corallo <akrl@sdf.org>
+
+ Clean-up testsuite for vanilla builds
+
+ Tag all native compiler tests and skip them in vanilla builds
+
+ * test/Makefile.in (SELECTOR_DEFAULT, SELECTOR_EXPENSIVE)
+ (SELECTOR_ALL): Define selectors for vanilla or nativecomp builds.
+ * test/src/comp-tests.el: Do not native compile test files on
+ vanilla.
+ (comp-deftest): New macro to define tests tagging as :nativecomp.
+
+2020-10-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix electric-buffer-list buffer selection
+
+ * lisp/ebuff-menu.el (electric-buffer-list): Ensure that point is
+ restored, which isn't always the case if
+ global-display-line-numbers-mode (bug#43755). This enables
+ selecting buffers again.
+
+2020-10-02 Dmitry Gutov <dgutov@yandex.ru>
+
+ Make xref work better on variables in shell-script-mode
+
+ * lisp/progmodes/sh-script.el (sh-mode-syntax-table): Classify "/"
+ as punctuation so that `M-.' on $foo/bar works on the $foo part
+ (bug#25585).
+
+2020-10-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `C-c C-e' in Python buffers work
+
+ * lisp/progmodes/python.el (python-shell-send-statement): Don't
+ send a cookie, because that leads to the naked expression not
+ being evaled (bug#43450).
+ (python-shell-send-region): Allow not sending a cookie.
+ (python-shell-buffer-substring): Ditto.
+
+2020-10-02 Per Starbäck <per@starback.se>
+
+ python-shell-send-defun doesn't find the (whole) definition
+
+ * lisp/progmodes/python.el (python-shell-send-defun): Fix C-M-x
+ for definitions like @property\ndef bar(): (bug#37828).
+
+2020-10-02 Robert Pluim <rpluim@gmail.com>
+
+ Make setting verify-hostname-error not make connections fail
+
+ * lisp/net/gnutls.el (gnutls-boot-parameters): If
+ verify-hostname-error was set, this would make verify-error a
+ non-proper list (bug#38602).
+
+2020-10-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Stop using a dynamically bound 'generated-autoload-file' variable
+
+ * doc/lispref/loading.texi (Autoload): Document change of name
+ (bug#39823).
+
+ * lisp/emacs-lisp/autoload.el (autoload-find-generated-file): Pass
+ the file name in.
+ (autoload-generated-file): Ditto.
+ (autoload-file-load-name): Ditto.
+ (generate-file-autoloads): Ditto.
+ (autoload--setup-output): Ditto.
+ (autoload-generate-file-autoloads): Ditto, and alter doc string to
+ reflect when `generated-autoload-file' is heeded.
+ (update-file-autoloads): Pass outfile in to functions.
+ (autoload-find-destination): Ditto.
+ (update-directory-autoloads): Make into an obsolete shim around
+ `make-directory-autoloads'.
+ (make-directory-autoloads): Renamed from
+ `update-directory-autoloads' with new semantics.
+ (batch-update-autoloads): Adjust caller.
+
+ * lisp/emacs-lisp/package.el (package-generate-autoloads): Adjust
+ caller.
+
+2020-10-02 Shohei YOSHIDA <syohex@gmail.com>
+
+ Fix --with-json message
+
+ * configure.ac (WIDE_EMACS_INT): Fix --with-json help message
+ (bug#43754).
+
+2020-10-02 Trevor Murphy <trevormurphy@google.com>
+
+ Fix check for derived modes in display-buffer-reuse-mode-window
+
+ * lisp/window.el (display-buffer-reuse-mode-window): Make the
+ check for derived modes actually work (bug#38677).
+
+2020-10-01 Tino Calancha <tino.calancha@gmail.com>
+
+ Fix wdired-do-perm-changes when over Tramp
+
+ * lisp/wdired.el (wdired-do-perm-changes) Use set-file-modes
+ instead of external program (bug#39284). This fixes the problem
+ of passing the wrong argument to the external chmod.
+
+2020-10-01 Tino Calancha <tino.calancha@gmail.com>
+
+ Fix bug in wdired-get-filename
+
+ * lisp/wdired.el (wdired-get-filename): Acknowledge the first
+ argument (bug#39280).
+ * test/lisp/wdired-tests.el (wdired-test-bug39280): Add test.
+
+2020-10-01 Alan Mackenzie <acm@muc.de>
+
+ Enhance syntax-tests.el to test some comment character handling.
+
+ * test/src/syntax-tests.el: Add a new section testing some aspects
+ of comment handling in syntax.c. This needs further enhancement.
+ It uses ....
+
+ * test/data/syntax-comments.txt: A new test file.
+
+2020-10-01 Juri Linkov <juri@linkov.net>
+
+ Use new faces isearch-group-odd and isearch-group-even (bug#43702)
+
+ * lisp/isearch.el (isearch-group-odd, isearch-group-even): New faces
+ instead of isearch-group-1 .. isearch-group-9.
+ (isearch-highlight): Use new faces.
+
+2020-10-01 Allen Li <darkfeline@felesatra.moe>
+
+ Make recentf daily cleanup repeat
+
+ * lisp/recentf.el (recentf-auto-cleanup): Fix wording.
+ * lisp/recentf.el (recentf-auto-cleanup): Make timer repeat,
+ update docstring.
+ * etc/NEWS: Update news (bug#39638).
+
+2020-10-01 Michael R. Mauger <michael@mauger.com>
+
+ * lisp/progmodes/sql.el (sql-add-product): Re-correct argument
+ spec. Previous change was due to my mistake; I have
+ resolved back to the prior behavior (Bug#39960).
+ * test/lisp/progmodes/sql-tests.el (sql-test-add-product): Added
+ test to insure I don't make the same mistake again.
+
+2020-10-01 Boruch Baum <boruch_baum@gmx.com>
+
+ command-execute doc string clarification
+
+ * lisp/simple.el (command-execute): Doc string clarification
+ (bug#43749).
+
+2020-10-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make aliases introduced in previous patch obsolete
+
+ * lisp/emacs-lisp/debug.el (debugger-toggle-locals):
+ (debug-help-follow): Make reinstated aliases obsolete.
+
+2020-10-01 Gemini Lasswell <gazally@runbox.com>
+
+ Restore some public debugging functions removed in Emacs 27
+
+ * lisp/emacs-lisp/backtrace.el (backtrace--to-string): New function.
+ (backtrace-to-string): Use it. Fix whitespace (bug#40728).
+ * lisp/emacs-lisp/debug.el (debugger-insert-backtrace): New function.
+ Mark it as obsolete.
+ (debugger-toggle-locals, debug-help-follow): New aliases.
+
+2020-10-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix loading WSDL data again
+
+ * lisp/net/soap-client.el (soap-make-wsdl): Change the WSDL
+ namespace back again.
+
+2020-10-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix restoring data in visual-line-mode
+
+ * lisp/simple.el (visual-line-mode): Only save values once, even
+ if the mode is switched on twice (bug#43730). This makes both
+ previously set local values for variables like truncate-lines, as
+ well as default values for truncate-lines restorable.
+
+ * lisp/emulation/cua-base.el (cua-mode): Ditto.
+
+2020-10-01 Andrea Corallo <akrl@sdf.org>
+
+ * test/src/comp-tests.el (comp-tests-bootstrap): Tag it as expensive.
+
+2020-10-01 Stefan Kangas <stefan@marxist.se>
+
+ Silence byte-compiler in two tests
+
+ * test/lisp/obsolete/cl-tests.el (require):
+ * test/lisp/simple-tests.el (simple-test-count-words-bug-41761):
+ Silence byte-compiler.
+
+2020-10-01 Stefan Kangas <stefan@marxist.se>
+
+ Remove some obsolete URLs
+
+ * lisp/net/newst-backend.el (newsticker--raw-url-list-defaults):
+ Remove some obsolete URLs.
+
+2020-10-01 Stefan Kangas <stefan@marxist.se>
+
+ Don't quote lambdas in several places
+
+ * admin/find-gc.el (find-gc-unsafe):
+ * lisp/align.el (align-rules-list):
+ * lisp/comint.el (comint-arguments):
+ * lisp/double.el (isearch-mode-map):
+ * lisp/ehelp.el (electric-help-command-loop):
+ * lisp/emacs-lisp/cl-macs.el (cl-defstruct):
+ * lisp/emulation/cua-rect.el (cua--copy-rectangle-as-kill)
+ (cua-copy-rectangle-as-text):
+ * lisp/eshell/esh-var.el (eshell-parse-variable-ref):
+ * lisp/hexl.el (hexl-insert-multibyte-char):
+ * lisp/international/titdic-cnv.el (tsang-quick-converter)
+ (ziranma-converter):
+ * lisp/language/tibet-util.el (tibetan-decompose-precomposition-alist):
+ * lisp/mail/mailalias.el (mail-get-names):
+ * lisp/mh-e/mh-e.el (mh-auto-fields-list, mh-identity-default):
+ * lisp/mouse.el (mouse-buffer-menu-map, mouse-buffer-menu-alist):
+ * lisp/play/gametree.el (gametree-make-heading-function):
+ * lisp/shell.el (shell--command-completion-data):
+ * lisp/talk.el (talk-update-buffers):
+ * lisp/tempo.el (tempo-insert-template, tempo-is-user-element)
+ (tempo-build-collection):
+ * lisp/term.el (term-input-filter, term-pager-help):
+ * lisp/textmodes/table.el (table-delete-column):
+ * lisp/url/url-cache.el (url-cache-create-filename-human-readable):
+ * lisp/textmodes/tex-mode.el (latex-imenu-create-index): Don't quote
+ lambdas.
+
+2020-10-01 Stefan Kangas <stefan@marxist.se>
+
+ Don't recommend quoting lambdas
+
+ * doc/misc/calc.texi (Symbolic Lisp Functions):
+ * doc/misc/cl.texi (Obsolete Lexical Binding):
+ * lisp/master.el:
+ * lisp/progmodes/sql.el (sql-interactive-mode):
+ * lisp/textmodes/flyspell.el (flyspell-mode):
+ * lisp/textmodes/ispell.el (ispell-message):
+ * lisp/textmodes/table.el: Doc fixes; don't recommend quoting
+ lambdas.
+
+2020-10-01 Michael Albinus <michael.albinus@gmx.de>
+
+ Clarification in Tramp manual
+
+ * doc/misc/tramp.texi: Harmonize "Git" spelling.
+ (Frequently Asked Questions): Describe Emacs version mismatch.
+
+2020-10-01 Michael Albinus <michael.albinus@gmx.de>
+
+ Check Emacs version used for Tramp compilation
+
+ * lisp/net/tramp-compat.el (tramp-compat-emacs-compiled-version):
+ New defconst. Raise a warning, when it is not equal to the Emacs
+ version.
+
+2020-10-01 Michael Albinus <michael.albinus@gmx.de>
+
+ Use Fkeywordp in dbusbind.c, again
+
+ * src/dbusbind.c (XD_KEYWORDP): New macro.
+ (XD_DBUS_TYPE_P, Fdbus__init_bus, xd_read_queued_messages): Use it.
+
+2020-10-01 Michael Albinus <michael.albinus@gmx.de>
+
+ Revert last change in dbusbind.c
+
+ * src/dbusbind.c (XD_DBUS_TYPE_P, Fdbus__init_bus)
+ (xd_read_queued_messages): Revert last change. (Bug#43724)
+
+2020-10-01 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-c-func-name): Add autoload cookie.
+
+2020-10-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove mml-sec-test that assumes the first signature
+
+ This is no longer supported; the user is asked for what signature to
+ use.
+
+2020-10-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make mml-sec-tests not hang waiting for input
+
+ * lisp/gnus/mml-sec.el (mml-secure-epg-sign): Only query if we're
+ running interactively. This makes a test not hang.
+
+2020-10-01 Pip Cet <pipcet@gmail.com>
+
+ Don't optimize away star patterns in minibuffer file name completion
+
+ * lisp/minibuffer.el (completion-pcm--optimize-pattern): Keep
+ 'star in the pattern (bug#41705).
+
+2020-10-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix the end-of-query prompt in multi-occur and multi-isearch when fido
+
+ * lisp/misearch.el (multi-isearch-read-buffers): Ditto.
+
+ * lisp/replace.el (multi-occur--prompt): New function (bug#41633).
+ (multi-occur): Use it.
+
+2020-10-01 Alex Bochannek <alex@bochannek.com>
+
+ Make gnus-base64-repad a bit stricter again
+
+ * lisp/gnus/gnus-util.el (gnus-base64-repad): Make the code a bit
+ stricter again.
+
+2020-10-01 Robert Pluim <rpluim@gmail.com>
+
+ Query for the signer when sending signed mail (with unknown signer)
+
+ * lisp/gnus/mml-sec.el (mml-secure-sender-sign-query): New
+ function (bug#40118).
+ (mml-secure-epg-sign): Use it to determine the signer (bug#40118).
+
+ * lisp/gnus/mml-sec.el
+ (mml-secure-allow-signing-with-unknown-recipient): Remove.
+
+2020-10-01 martin rudalics <rudalics@gmx.at>
+
+ Fix segfault in some cases when restoring a selected window
+
+ * src/xdisp.c (restore_selected_window): Fix the more grave
+ problems caused by a function deleting the previously selected
+ frame or window (bug#39977).
+
+2020-10-01 Boruch Baum <boruch_baum@gmx.com>
+
+ Split auto-revert-buffers into several functions
+
+ * lisp/autorevert.el (auto-revert--buffer-candidates)
+ (auto-revert-buffer): Refactor out...
+ (auto-revert-buffers): ... from here.
+
+2020-10-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up previous window excursion patch in epa--select-keys
+
+ * lisp/epa.el (epa--select-keys): Use save-window-excursion
+ instead of open-coding the macro.
+
+2020-10-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/term.el: Make C-/ undo in a nested Emacs subprocess
+
+ (term-send-C-_): New function.
+ (term-raw-map): Use it for `C-/`, as is done in xterm and friends.
+
+2020-10-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * doc/emacs/basic.texi (Basic Undo): Explain the C-/ situation in xterm
+
+ AFAICT, in ttys you can send a `C-_` to Emacs either by pressing
+ `C-/` (e.g. xterm, uxterm, rxvt, xfce4-terminal, gnome-terminal)
+ or by pressing `C--` (e.g. rxvt, Linux console).
+
+2020-10-01 Richard M Stallman <rms@gnu.org>
+
+ When recipient has no public key, make offer to skip it optional.
+
+ * lisp/epa-mail.el (epa-mail-offer-skip): New option.
+ (epa-mail-encrypt): If epa-mail-offer-skip is nil,
+ don't offer to skip a keyless recipient, just cause error.
+
+2020-10-01 Richard M Stallman <rms@gnu.org>
+
+ Clarify previous undo keys change
+
+ Clarify which terminals allow C-/ and which make C-_ easy to type.
+
+2020-09-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further doc fixes for dotimes about RESULT
+
+ * lisp/subr.el (dotimes): Be even more explicit about RESULT
+ (bug#16206).
+
+2020-09-30 Eli Zaretskii <eliz@gnu.org>
+
+ Minor documentation copyedits
+
+ * etc/NEWS:
+ * doc/emacs/dired.texi (Dired Enter): Fix wording, punctuation,
+ and typos in doc of 'dired-switches-in-mode-line'.
+
+2020-09-30 Vladimir Nikishkin <lockywolf@gmail.com> (tiny change)
+
+ Fix problem with parsing . as a symbol in bovine
+
+ * lisp/cedet/semantic/bovine/scm.el (semantic-lex-scheme-symbol):
+ Symbols do not have to start with a word-constituent character
+ (bug#40034). In particular, symbols like : and . are valid.
+
+2020-09-30 Drew Adams <drew.adams@oracle.com>
+
+ Allow controlling the Dired switches shown in the mode line
+
+ * doc/emacs/dired.texi (Dired Enter): Document it (bug#41250).
+
+ * lisp/dired.el (dired-switches-in-mode-line): New variable (bug#41250).
+ (dired-sort-set-mode-line): Use it.
+
+2020-09-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem of having the wrong window selected after saving foo.gpg
+
+ * lisp/epa.el (epa--select-keys): Restore the window configuration
+ after selecting the key to use (bug#43703). This also ensures
+ that the buffer we were editing ends up as the current buffer
+ after saving it, instead of selecting a different window.
+
+2020-09-30 Andrea Corallo <akrl@sdf.org>
+
+ Improve some docstring in src/comp.c
+
+ * src/comp.c (Fcomp_el_to_eln_filename)
+ (Fcomp__compile_ctxt_to_file): Improve docstring.
+ (Fcomp__compile_ctxt_to_file): Rename 'file_name' -> 'filename'.
+ (Fnative_comp_available_p): Improve docstring.
+
+2020-09-30 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'move-to-column' when invisible text follows a TAB
+
+ * src/indent.c (scan_for_column): Accept 2 more arguments, and
+ report through them the position corresponding to PREVCOL. All
+ callers changed.
+ (Fmove_to_column): Use the prev_col's position to test for a TAB
+ instead of assuming that the TAB is just before point (which is
+ false when there's invisible text around). (Bug#43587)
+
+ * test/src/indent-tests.el: New file.
+
+2020-09-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify the "Forgot to expand macro" message
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-form): Make the
+ define-after-use warning for macros clearer (bug#43678).
+
+2020-09-30 Andrea Corallo <akrl@sdf.org>
+
+ * .gitlab-ci.yml: Uncomment some testing to align with master.
+
+2020-09-30 Eli Zaretskii <eliz@gnu.org>
+
+ Minor fixes of recent changes
+
+ * lisp/emacs-lisp/generic.el (define-generic-mode): Fix typos.
+
+ * etc/NEWS: Adjust an entry due to recent changes.
+
+2020-09-30 Michael Albinus <michael.albinus@gmx.de>
+
+ Stricter checks for D-Bus compound types.
+
+ * src/dbusbind.c (XD_DBUS_TYPE_P, Fdbus__init_bus)
+ (xd_read_queued_messages): Use Fkeywordp instead of SYMBOLP.
+ (xd_signature): Stricter checks for compound types.
+
+ * test/lisp/net/dbus-tests.el (dbus-test01-compound-types): Extend test.
+
+2020-09-30 Michael Albinus <michael.albinus@gmx.de>
+
+ Minor code cleanup in dbus-tests.el
+
+ * test/lisp/net/dbus-tests.el (dbus--tests-dir): Make it a defconst.
+ (dbus--test-method-reentry-handler): Mark args as unused.
+ (dbus-test04-method-reentry): Tag it :expensive-test. Fix typo.
+ (dbus-test06-property-types): Remove duplicate test.
+ (dbus--test-introspect): Use `insert-file-contents-literally'.
+ (dbus--test-validate-property): Mark expected-annotations as unused.
+ (dbus--test-validate-m-or-s): Remove superfluous le-clause.
+
+2020-09-30 Hugh Daschbach <hdasch@fastmail.com>
+
+ Add D-Bus method-call reentrant test
+
+ * test/lisp/net/dbus-tests.el (dbus--tests-method-reentry-handler):
+ New defun.
+ (dbus-test04-method-reentry): New test. (Bug#43251)
+
+2020-09-30 Hugh Daschbach <hdasch@fastmail.com>
+
+ * test/lisp/net/dbus-tests.el: Add timeout tests.
+
+ (dbus-test04-call-method-timeout, dbus-test07-introspection-timeout):
+ New tests.
+
+2020-09-30 Hugh Daschbach <hdasch@fastmail.com>
+
+ Add D-Bus introspection tests
+
+ * lisp/net/dbus.el (dbus-annotation-deprecated): New defconst.
+
+ * test/lisp/net/dbus-tests.el (dbus--tests-dir): New defvar.
+ (dbus--test-introspect, dbus--test-validate-interface)
+ (dbus--test-validate-annotations, dbus--test-validate-property)
+ (dbus--test-validate-m-or-s, dbus--test-validate-signal)
+ (dbus--test-validate-method): New defuns.
+ (dbus-test07-introspection): New test.
+
+ * test/lisp/net/dbus-resources/org.gnu.Emacs.TestDBus.xml:
+ New test data.
+
+2020-09-30 Hugh Daschbach <hdasch@fastmail.com>
+
+ * test/lisp/net/dbus-tests.el: Add property tests. (Bug#43252)
+
+ (dbus--test-run-property-test, dbus--test-property): New defuns.
+ (dbus-test06-property-types): New test for property registration,
+ set, get.
+
+2020-09-30 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into clean-up
+
+2020-09-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Don't have C-x = bug out in a "C" locale with non-ASCII chars
+
+ * lisp/simple.el (what-cursor-position): Ensure that we always
+ have a coding system here, even if the locale is "C" (bug#40702).
+
+2020-09-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix whitespace regexp in gnus-base64-repad
+
+ * lisp/gnus/gnus-util.el (gnus-base64-repad): Fix the whitespace
+ regexp.
+
+2020-09-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix gnus-base64-repad test failures
+
+2020-09-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-macs.el (hash-table): Define the type's typep test
+
+2020-09-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix isearch-group-* colours on low-colour displays
+
+ * lisp/isearch.el (isearch-group-1): On low-colour displays, just
+ use the normal isearch colour (bug#43702).
+ (isearch-group-2 etc): Ditto.
+
+2020-09-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ define-generic-mode doc string fix
+
+ * lisp/emacs-lisp/generic.el (define-generic-mode): Say what a
+ generic mode is (bug#43713).
+
+2020-09-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Give better error feedback on wrong password in .gpg files
+
+ * lisp/epa-file.el (epa-file--find-file-not-found-function): Do a
+ user-error when there's a wrong password (bug#43704).
+ (epa--wrong-password-p): New function.
+ (epa-file-insert-file-contents): Use it, and stash the error away
+ for later signalling.
+
+ * lisp/emacs-lisp/subr-x.el (if-let): Autoload.
+
+2020-09-30 Thomas Fitzsimmons <fitzsim@fitzsim.org>
+
+ soap-client: Bump version to 3.2.0
+
+ * lisp/net/soap-client.el: Bump version to 3.2.0.
+
+2020-09-30 Thomas Fitzsimmons <fitzsim@fitzsim.org>
+
+ soap-client: Remove FIXME comment
+
+ * lisp/net/soap-client.el (soap-encode-attributes): Remove
+ cl-defmethod FIXME comment; continue supporting Emacs 24.1.
+
+2020-09-30 Thomas Fitzsimmons <fitzsim@fitzsim.org>
+ Paul Eggert <eggert@cs.ucla.edu>
+
+ soap-client: Update soap-decode-date-time
+
+ * lisp/net/soap-client.el (soap-decode-date-time): Add support for
+ Emacs versions that support fractional seconds. Make DATATYPE
+ optional. Remove FIXME comment.
+
+2020-09-29 Michael Albinus <michael.albinus@gmx.de>
+
+ More strict D-Bus type checking
+
+ * lisp/net/dbus.el (dbus-register-monitor): Register proper key.
+ (dbus-monitor-handler): Adapt docstring. Use grave text-quoting-style.
+
+ * src/dbusbind.c (xd_signature, xd_append_arg): More strict tests.
+ (syms_of_dbusbind): Adapt docstring.
+
+ * test/lisp/net/dbus-tests.el (dbus-test01-basic-types): Extend test.
+
+2020-09-29 Eli Zaretskii <eliz@gnu.org>
+
+ Don't signal an error when saving files on WdebDAV volumes
+
+ * src/w32.c (acl_get_file): If get_file_security raises the
+ ERROR_ACCESS_DENIED error, treat that like unsupported ACLs.
+
+2020-09-29 Andrea Corallo <akrl@sdf.org>
+
+ Some clean-up in comp.el
+
+ * lisp/emacs-lisp/comp.el (comp-emit-cond-jump, comp-emit-switch)
+ (comp-limplify-block, comp-compute-edges)
+ (comp-ssa-rename, comp-fwprop*, comp-effective-async-max-jobs)
+ (comp-run-async-workers): Respect max 80 columns.
+ (batch-byte-native-compile-for-bootstrap): Improve doc + remove
+ some now unnecessary error handling.
+
+2020-09-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix emacsclient -c foo.txt behaviour with many frames
+
+ * lisp/server.el (server-execute): Pass in whether we opened a new
+ frame or not (bug#43645).
+ (server-switch-buffer): Use this to switch to the requested buffer
+ in the new frame if we have "emacsclient -c foo.txt", and retain
+ the old behaviour if it's "emacsclient foo.txt".
+
+2020-09-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make M-x compile skip the header when looking for errors etc
+
+ * lisp/progmodes/compile.el (compilation--ensure-parse): Skip the
+ header when parsing (bug#43651).
+ (compilation-start): Mark the end.
+
+2020-09-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix space parsing in gnus-base64-repad
+
+ * lisp/gnus/gnus-util.el (gnus-base64-repad): Get the separator
+ regexp right -- there will often be spaces around the newlines.
+
+2020-09-29 Mattias Engdegård <mattiase@acm.org>
+
+ * lisp/gnus/smime.el (smime-openssl-program): Allow nil value.
+
+2020-09-29 Mattias Engdegård <mattiase@acm.org>
+
+ Fix custom-tests with non-GNU grep
+
+ * admin/cus-test.el (cus-test-get-lisp-files): Add path argument required
+ by standard grep (BSD, for instance).
+
+2020-09-29 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/eval.c (Fapply): Simplify last change
+
+2020-09-28 Andrea Corallo <akrl@sdf.org>
+
+ Rename in docstrings "non nil" into "non-nil"
+
+ * lisp/emacs-lisp/comp.el: Rename non nil -> non-nil in doc.
+
+ * src/comp.c: Likewise.
+
+2020-09-28 Andrea Corallo <akrl@sdf.org>
+
+ * src/lisp.h: Remove a newline diff left over master.
+
+2020-09-29 Andrea Corallo <akrl@sdf.org>
+
+ Clean-up some now unnecessary diff against master
+
+ * lisp/emacs-lisp/autoload.el (update-directory-autoloads):
+ .eln files have been moved so remove the '.eln' match.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-refresh-preloaded):
+ Likewise.
+
+ * lisp/emacs-lisp/find-func.el (find-library-suffixes): Clean-up
+ as '.eln' is no more in `load-suffixes'.
+
+ * lisp/help-fns.el (find-lisp-object-file-name): Clean-up as
+ `symbol-file' will return the '.elc' file.
+
+ * src/lread.c (Fget_load_suffixes): Remove logic as '.eln' is not
+ anymore in load-suffixes.
+ (openp): Two spaces.
+
+2020-09-28 Michael Albinus <michael.albinus@gmx.de>
+
+ Improve D-Bus monitor
+
+ * lisp/net/dbus.el (dbus-monitor-method-call)
+ (dbus-monitor-method-return, dbus-monitor-error)
+ (dbus-monitor-signal): New defconsts.
+ (dbus-monitor-goto-serial): New defun.
+ (dbus-monitor-handler): Use them. Add timestamp. Make also links
+ between D-Bus messages with the same serial.
+
+2020-09-28 Earl <ej32u@protonmail.com>
+
+ Suggest region contents in highlight-regexp when region active
+
+ * lisp/hi-lock.el (hi-lock-face-buffer): Use the region in the
+ prompt if the region is active in transient-mark-mode (bug#43641).
+
+2020-09-28 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Add compatibility for Emacs 26.1
+
+ * lisp/progmodes/cperl-mode.el (cperl--time-convert): New
+ compatibility helper for time-convert (available in Emacs
+ 27.1)
+ (cperl--format-prompt): New compatibility helper for
+ format-prompt (available in Emacs 28)
+ (cperl-info-on-command): use cperl--format-prompt
+ (cperl-perldoc): use cperl--format-prompt
+ (cperl-time-fontification): use cperl--time-convert (bug#43652)
+
+2020-09-28 Alex Bochannek <alex@bochannek.com>
+
+ Repad the Face header in Gnus
+
+ * lisp/gnus/gnus-fun.el (gnus-convert-face-to-png): Use it.
+
+ * lisp/gnus/gnus-util.el (gnus-base64-repad): New function (bug#43441).
+
+2020-09-28 Jan Tatarik <jan.tatarik@gmail.com>
+
+ Fix Gnus parsing of weekly recurring icalendar events
+
+ * lisp/gnus/gnus-icalendar.el
+ (gnus-icalendar-event:recurring-interval): Fix parsing of weekly
+ recurring events (bug#43669).
+
+ Example: in the absence of explicit INTERVAL value in the calendar
+ event, a weekly event with occurrences scheduled for Mondays and
+ Wednesdays should receive the default recurring interval of "1" and the
+ org mode timestamp repeater should be "+1w".
+
+ Due to a bug in the current code we receive "WEEKLY" and "+WEEKLYw"
+ instead. The patch fixes the issue.
+
+2020-09-28 Eli Zaretskii <eliz@gnu.org>
+
+ * lisp/hi-lock.el (hi-lock-find-patterns): Autoload it. (Bug#43670)
+
+2020-09-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Fix pcomplete completion of things like `xargs` and `sudo` (bug#16197)
+
+ * lisp/pcmpl-unix.el (pcomplete/xargs): Don't `pcomplete-this` around
+ `pcomplete-command-completion-function`.
+ (pcomplete/sudo): Make it an alias for `pcomplete/xargs`.
+
+ * lisp/shell.el (shell-command-completion-function): Return the
+ names from `exec-path` when the command name has no `/`.
+
+2020-09-27 Michael Albinus <michael.albinus@gmx.de>
+
+ Document D-Bus monitoring
+
+ * doc/misc/dbus.texi: Replace "symbol" by "keyword" where appropriate.
+ (Alternative Buses): Adapt dbus-init-bus description.
+ (Errors and Events): Adapt dbus-event structure. New defuns
+ dbus-event-destination-name, dbus-event-handler and dbus-event-arguments.
+ (Monitoring Events): New node.
+
+ * lisp/net/dbus.el: Replace "symbol" by "keyword" where appropriate.
+ (cl-lib): Require.
+ (dbus-register-monitor): Adapt the argument list.
+ (dbus-monitor-handler): Extend.
+ (dbus-init-bus): Adapt docstring.
+
+ * test/lisp/net/dbus-tests.el (dbus-test01-compound-types):
+ Skip if needed. Extend test.
+
+2020-09-27 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 0b78785a9b (origin/emacs-27) Minor copyedits in the Emacs user manual
+ 0dfc6fdc1f Followup to a recent change in menu-bar.el
+ 767713682c Enable "Continue Tags Search" menu item only when it can b...
+ 4bb7532163 Fix soap-client URL
+
+2020-09-27 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ f31c6792ab Fix support for Zip64 zip files
+ ba635a19fb * lisp/hi-lock.el (hi-lock-auto-select-face): Doc fix. (B...
+ cc8fef2bdd Avoid infinite recursion with 'relative' line numbers display
+ 395f10cb98 ; Fix more trivial typos
+ bf4accb65e ; Fix some trivial typos
+
+ # Conflicts:
+ # etc/NEWS
+ # lisp/arc-mode.el
+
+2020-09-27 Pip Cet <pipcet@gmail.com>
+
+ Fix more single-byte accesses caused by bytepos/charpos confusion
+
+ * src/cmds.c (internal_self_insert): Use FETCH_BYTE, not
+ FETCH_CHAR, for a decremented byte position (bug#41520).
+
+ * src/xdisp.c (Fwindow_text_pixel_size, trailing_whitespace_p): Ditto.
+
+2020-09-27 Pip Cet <pipcet@gmail.com>
+
+ Handle single-argument `apply' consistently (bug#40968)
+
+ * src/eval.c (Fapply): Handle (apply nil) without crashing.
+ Document single-argument form.
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-apply): Don't attempt
+ to optimize single-argument apply.
+ * doc/lispref/functions.texi (Calling Functions): Document
+ single-argument apply. Provide example (bug#40968).
+
+2020-09-27 Pip Cet <pipcet@gmail.com>
+
+ Avoid 1s sleep-for before sending the startfile to a comint process
+
+ * lisp/comint.el (comint-exec): Simplify startup file code.
+ (Bug#41640).
+
+2020-09-27 Simon Lang <Simon.lang@outlook.com>
+
+ Add a new grep-match-regexp variable
+
+ * doc/emacs/building.texi (Grep Searching): Document it.
+
+ * lisp/progmodes/grep.el (grep-match-regexp): New variable (bug#41766).
+ (grep-filter): Use it.
+
+2020-09-27 Mattias Engdegård <mattiase@acm.org>
+
+ Minor string-search optimisations (bug#43598)
+
+ * src/fns.c (Fstring_search): Perform cheap all-ASCII checks before more
+ expensive ones. Use a faster loop when searching for non-ASCII
+ non-raw bytes.
+ * test/src/fns-tests.el (string-search): Add more test cases.
+
+2020-09-27 Mattias Engdegård <mattiase@acm.org>
+
+ Improve accuracy in string-replace description (bug#43598)
+
+ * doc/lispref/searching.texi (Search and Replace): More careful
+ description; string-replace does not necessarily return a copy.
+
+2020-09-27 Eli Zaretskii <eliz@gnu.org>
+
+ Minor copyedits in the Emacs user manual
+
+ * doc/emacs/emacs.texi (Top): Remove "real-time" from the Emacs
+ description; add "advanced", to be consistent with what we say in
+ the Introduction section. (Bug#43633)
+
+2020-09-27 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of the 'abbrev-suggest' feature
+
+ * lisp/abbrev.el (abbrev-suggest, abbrev-suggest-hint-threshold)
+ (abbrev-suggest-show-report): Improve wording of the doc strings.
+
+ * doc/emacs/abbrevs.texi (Abbrevs Suggestions): Fix the typo in
+ the node name. Improve wording.
+ * doc/emacs/emacs.texi (Top): Add the new node in the @detailmenu
+ section.
+
+ * etc/NEWS: Improve wording of the NEWS entry for
+ 'abbrev-suggest'.
+
+2020-09-27 Eli Zaretskii <eliz@gnu.org>
+
+ Improve display of raw bytes in the echo-area
+
+ * src/print.c (print_object): When printing a unibyte string,
+ convert non-ASCII bytes to their character code, before sending
+ them to 'printchar'. (Bug#43632)
+
+2020-09-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix searching for multibyte needles in unibyte haystacks
+
+ * src/fns.c (Fstring_search): Make this work better when searching
+ unibyte haystacks for multibyte needles (bug#43598).
+
+2020-09-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make dired-replace-in-string obsolete
+
+ * lisp/dired.el (dired-insert-directory):
+ * lisp/dired-aux.el (dired-rename-subdir, dired-rename-subdir-2)
+ (dired-insert-subdir): Adjust callers.
+
+ * lisp/dired.el (dired-replace-in-string): Make obsolete.
+
+2020-09-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add tiny optimization for string-search
+
+ * src/fns.c (Fstring_search): Add tiny optimization for needles
+ that are longer than the haystack (bug#43598).
+
+2020-09-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Rename replace-in-string to string-replace
+
+ * doc/lispref/searching.texi (Search and Replace): Update.
+ * lisp/bindings.el (mode-line-position): Update callers.
+
+ * lisp/subr.el (string-replace): Rename from replace-in-string
+ since that clashes with XEmacs' replace-in-string which is
+ equivalent to the Emacs replace-regexp-in-string (bug#43598).
+
+2020-09-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix gnus-faq example
+
+ * doc/misc/gnus-faq.texi (FAQ 6-2): replace-in-string was the XEmacs
+ name for the function.
+
+2020-09-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Slight replace-in-string optimization
+
+ * lisp/subr.el (replace-in-string): Optimize to return the
+ original string if nothing was replaced (bug#43598).
+
+2020-09-26 Mathias Dahl <mathias.dahl@gmail.com>
+
+ Abbrev suggestions helps users remember to use defined abbrevs
+
+ * lisp/abbrev.el (abbrev-suggest): New defcustom.
+ (abbrev-suggest-hint-threshold): New defcustom.
+ (abbrev--suggest-get-active-tables-including-parents): New defun.
+ (abbrev--suggest-get-active-abbrev-expansions): New defun.
+ (abbrev--suggest-count-words): New defun.
+ (abbrev--suggest-get-previous-words): New defun.
+ (abbrev--suggest-above-threshold): New defun.
+ (abbrev--suggest-saved-recommendations): New defvar.
+ (abbrev--suggest-inform-user): New defun.
+ (abbrev--suggest-shortest-abbrev): New defun.
+ (abbrev--suggest-maybe-suggest): New defun.
+ (abbrev--suggest-get-totals): New defun.
+ (abbrev-suggest-show-report): New defun.
+ (expand-abbrev): If the previous word was not an abbrev, maybe
+ suggest an abbrev to the user.
+ * doc/emacs/abbrevs.texi (Abbrev suggestions): New section.
+ * etc/NEWS: Announce abbrev suggestions.
+
+2020-09-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix the patch tagging in submit-emacs-patch
+
+ * lisp/mail/emacsbug.el (submit-emacs-patch): Put the tags in the
+ debbugs pseudo-headers because X-Debbugs-Tags is not a thing that
+ exists.
+
+2020-09-26 Eli Zaretskii <eliz@gnu.org>
+
+ Followup to a recent change in menu-bar.el
+
+ * lisp/fileloop.el (fileloop--operate-function): Mention in a
+ comment that menu-bar.el relies on the default value.
+
+2020-09-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ message-add-action doc string fix
+
+ * lisp/gnus/message.el (message-add-action): Document types.
+
+2020-09-26 Mauro Aranda <maurooaranda@gmail.com>
+
+ Display some character widget values in a more user-friendly way
+
+ * lisp/wid-edit.el (widget-character--escape-sequences-alist): New
+ variable.
+ (widget-character--change-character-display): New function. Use the new
+ variable.
+ (widget-character-notify): New function, to keep track of the changes
+ in the character widget, and display characters like tab,
+ newline and spaces better.
+ (character widget): Use widget-character-notify as the notify
+ function. Use widget-character--change-character-display for the
+ internal representation of value (bug#15925).
+
+2020-09-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make macroexpand of `push' slightly less confusing
+
+ * lisp/subr.el (push): Use a symbol with a different name to make
+ macroexpand look slightly less confusing (bug#43601).
+
+2020-09-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix defcustom types of some variables defined in C
+
+ * lisp/cus-start.el (standard): Fix the defcustom type of a number
+ of variables defined in C (bug#43611).
+
+2020-09-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix mouse highlighting in Customize buffers
+
+ * lisp/wid-edit.el (widget-button-click): Remove a
+ newly-introduced check that made mouse highlights no longer work
+ (bug#43612). It's unclear what the check was trying to fix.
+
+2020-09-26 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Delete conditional code where conditions evaluate to nil
+
+ * lisp/progmodes/cperl-mode.el (cperl-force-face): This
+ macro's single effect is now inlined, and the macro is gone.
+ (cperl-problems): The reference to choose-color.el, which
+ is no longer available for download, is deleted.
+ (no function): A list of unnecessary empty variable
+ definitions is gone. They were needed for Emacs v19 and
+ below.
+ (cperl-init-faces-weak): This function does no longer do
+ anything and is therefore deleted.
+ (cperl-init-faces): Some bodies of conditional code is deleted
+ because as of today the conditions evaluate to constants. The
+ face cperl-nonoverridable-face is no longer available as
+ variable and needs to be doubly-quoted in one place (bug#43622).
+
+2020-09-26 Andrea Corallo <akrl@sdf.org>
+
+ Always set 'Vexec_path' before 'Vinvocation_directory' (bug#43137)
+
+ Do this as depending on the OS if argv0 is not populated 'Vexec_path'
+ is used to infer 'Vinvocation_directory'.
+
+ * src/pdumper.c (pdumper_load): Invoke 'init_vars_for_load' instead
+ of 'set_invocation_vars'.
+
+ * src/lisp.h: Extern 'init_vars_for_load' instead of
+ 'set_invocation_vars' .
+
+ * src/emacs.c (set_invocation_vars): Make it static and remove
+ double invocation guard.
+ (init_vars_for_load): Wrap 'init_callproc_1' and 'set_invocation_vars'
+ calls + add double invocation guard.
+ (init_cmdargs): Move out 'set_invocation_vars' invocation.
+ (main): Call 'init_vars_for_load' instead of 'init_callproc_1'.
+
+2020-09-26 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/cl-macs.el (cl--optimize): Add a FIXME.
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-09-26 Stefan Kangas <stefankangas@gmail.com>
+
+ Silence some byte-compiler warnings
+
+ * test/lisp/arc-mode-tests.el (arc-mode-test-archive-int-to-mode):
+ * test/lisp/custom-tests.el (cus-test-opts):
+ * test/lisp/help-fns-tests.el (foo-test-map)
+ (help-fns-test--describe-keymap-foo):
+ * test/src/fns-tests.el (w32-collate-ignore-punctuation)
+ (fns-tests-func-arity): Silence byte-compiler warnings.
+
+2020-09-26 Stefan Kangas <stefankangas@gmail.com>
+
+ Repurpose libxml test for obsolete argument
+
+ * test/src/xml-tests.el (libxml-tests): Move half this test for the
+ recently obsoleted fourth argument to libxml-parse-xml-region...
+ * test/lisp/xml-tests.el (xml-tests--remove-comments): ...to a new
+ test here for xml-remove-comments.
+
+ * test/src/xml-tests.el (libxml-tests--data-comments-discarded):
+ Move test data from here...
+ * test/lisp/xml-tests.el (xml-tests--data-with-comments): ...to here.
+
+2020-09-26 Michael Albinus <michael.albinus@gmx.de>
+
+ * etc/NEWS: Add new D-Bus monitor functionality. Fix typos.
+
+2020-09-26 Michael Albinus <michael.albinus@gmx.de>
+
+ Add D-Bus monitor
+
+ * lisp/net/dbus.el (dbus-interface-monitoring): New defconst.
+ (dbus-call-method, dbus-call-method-asynchronously)
+ (dbus-send-signal, dbus-method-return-internal)
+ (dbus-method-error-internal, dbus-check-arguments): Accept also
+ :system-private and :session-private.
+ (dbus-check-event, dbus-event-path-name)
+ (dbus-event-interface-name)
+ (dbus-event-member-name, dbus-property-handler)
+ (dbus-handle-bus-disconnect): Adapt according to new structure.
+ (dbus-handle-event): Handle also monitor events.
+ (dbus-event-destination-name, dbus-event-handler)
+ (dbus-event-arguments, dbus-register-monitor, dbus-monitor-handler):
+ New defuns.
+
+ * src/dbusbind.c (XD_DBUS_VALIDATE_BUS_ADDRESS, xd_remove_watch)
+ (Fdbus__init_bus): Accept also :system-private and :session-private.
+ (xd_read_message_1): Add destination and error_name to
+ dbus-event. Handle monitor events.
+ (syms_of_dbusbind): Declare QCsystem_private, QCsession_private
+ and QCmonitor.
+ (dbus-registered-objects-table): Fix docstring.
+
+2020-09-26 Eli Zaretskii <eliz@gnu.org>
+
+ Enable "Continue Tags Search" menu item only when it can be used
+
+ * lisp/menu-bar.el (menu-bar-search-menu) <tags-continue>: Enable
+ only when there was a previous tags search. (Bug#43569)
+ (menu-bar-replace-menu) <tags-repl-continue>: Enable only when
+ there was a previous tags-replace.
+
+2020-09-26 Stefan Kangas <stefankangas@gmail.com>
+
+ Fix byte-compiler warning in CEDET
+
+ * lisp/cedet/semantic/lex.el (semantic-lex-catch-errors): Fix
+ byte-compiler warning by removing obsolete variable.
+
+2020-09-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix soap-client URL
+
+ * lisp/net/soap-client.el (soap-create-envelope):
+ Fix URL that I broke in 2019-09-23T06:53:30Z!eggert@cs.ucla.edu.
+ Problem reported by Thomas Fitzsimmons.
+
+2020-09-26 Thomas Fitzsimmons <fitzsim@fitzsim.org>
+
+ soap-client.el: Prevent some invalid encoding warnings
+
+ * lisp/net/soap-client.el (soap-encode-xs-complex-type): Do not
+ warn about missing non-nillable slot if type itself is optional.
+
+2020-09-25 Glenn Morris <rgm@gnu.org>
+
+ Fix out-of-tree make check
+
+ * test/lisp/custom-tests.el (custom-test-admin-cus-test): New const.
+ (check-for-wrong-custom-types): Use it.
+
+2020-09-25 Alan Third <alan@idiocy.org>
+
+ Tidy up NS color handling
+
+ * src/nsimage.m (COLORSPACE_NAME): New macro to find the current
+ colorspace.
+ ([EmacsImage initFromXBM:width:height:fg:bg:reverseBytes:]):
+ ([EmacsImage initForXPMWithDepth:width:height:]): Use the current
+ colorspace.
+ * src/nsterm.h (NSAppKitVersionNumber10_7):
+ (NSAppKitVersionNumber10_10): Define for macOS version checks.
+ * src/nsterm.m ([NSColor colorForEmacsRed:green:blue:alpha:]): Tidy up
+ the version checking.
+ ([NSColor colorUsingDefaultColorSpace]): Tidy the version checking and
+ use [NSColor colorUsingColorSpace:] with GNUstep.
+
+2020-09-25 Alan Third <alan@idiocy.org>
+
+ Remove obsolete macOS support for NS font backend
+
+ The ns font backend is has been disabled on macOS for a long time and
+ doesn't work correctly even if re-enabled.
+
+ * src/nsfont.m:
+ (ns_char_width):
+ (ns_ascii_average_width):
+ (ns_get_covering_families):
+ (nsfont_open):
+ (nsfont_close):
+ (nsfont_draw):
+ (ns_uni_to_glyphs):
+ (ns_glyph_metrics):
+ (EmacsGlyphStorage): Remove all Cocoa only code.
+ * src/nsterm.h (EmacsGlyphStorage): Remove.
+ (struct nsfont_info): Make GNUstep only.
+ * src/nsterm.m (ns_compute_glyph_string_overhangs): Remove GNUstep
+ only code from Cocoa builds.
+
+2020-09-25 Alan Third <alan@idiocy.org>
+
+ Implement internal border colors on NS (bug#41071)
+
+ * src/nsterm.m (ns_clear_under_internal_border): New function.
+ (ns_after_update_window_line): Use the correct background color.
+ (ns_redisplay_interface): Add ns_clear_under_internal_border.
+
+2020-09-25 Mattias Engdegård <mattiase@acm.org>
+
+ string-search robustness and documentation improvement (bug#43598)
+
+ * src/fns.c (Fstring_search): Check START-POS argument range.
+ Simplify logic. Improve doc string.
+ * test/src/fns-tests.el (string-search): Add test cases.
+ * doc/lispref/strings.texi (Text Comparison): Elaborate.
+ * lisp/emacs-lisp/byte-opt.el (pure-fns): Mark string-search as pure.
+
+2020-09-25 Eli Zaretskii <eliz@gnu.org>
+
+ Fix support for Zip64 zip files
+
+ * lisp/arc-mode.el (archive-zip-summarize): Fix detection of Zip64
+ central directory. Support 64-bit file size field used by Zip64.
+ (Bug#43597)
+
+2020-09-25 Noam Postavsky <npostavs@gmail.com>
+
+ * CONTRIBUTE: Don't recommend action stamps
+
+ * CONTRIBUTE: Remove mention of the "action stamp" thing (bug#20609).
+
+2020-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Partially revert previous prolog.el cleanup
+
+ * lisp/progmodes/prolog.el (prolog-font-lock-keywords): Partially
+ revert previous patch -- we want the prolog-warning-face symbol,
+ not its value.
+
+2020-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix defcustom type in sql.el for sql-postgres-login-params
+
+ * lisp/progmodes/sql.el (sql-login-params): Fix defcustom type to
+ match sql-postgres-login-params value.
+
+2020-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix a defcustom type in gdb-mi.el
+
+ * lisp/progmodes/gdb-mi.el (gdb-display-source-buffer-action): Fix
+ defcustom type to match the value.
+
+2020-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix defcustom type in whitespace.el
+
+ * lisp/whitespace.el (whitespace-space-after-tab-regexp)
+ (whitespace-indentation-regexp): The first string here isn't a
+ regexp, it's a string (that's expanded with format to be a regexp).
+
+2020-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix the defcustom type fix in python.el
+
+ * lisp/progmodes/python.el (python-pdbtrack-exit-command): Fix
+ defcustom type (bug#30990).
+
+2020-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix some defcustom types
+
+ * lisp/whitespace.el (whitespace-style):
+ * lisp/gnus/message.el (message-screenshot-command):
+ * lisp/progmodes/compile.el (compilation-transform-file-match-alist):
+ * lisp/progmodes/gdb-mi.el (gdb-default-window-configuration-file):
+ * lisp/progmodes/python.el (python-pdbtrack-exit-command): Fix the
+ defcustom types.
+ * lisp/progmodes/sql.el (sql-password-wallet): Fix the value.
+
+2020-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add an expensive test for defcustom types
+
+ * admin/cus-test.el (cus-test-opts): Return the tests.
+
+ * test/lisp/custom-tests.el (check-for-wrong-custom-types): Test
+ custom types (bug#30990).
+
+2020-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mark string-search as being side effect free
+
+ * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Add
+ string-search.
+
+2020-09-25 Noam Postavsky <npostavs@users.sourceforge.net>
+
+ Make the Man completion code work better if man -k fails
+
+ * lisp/man.el (Man-completion-table): Check the return code for
+ "man -k" and assume it failed if there's a non-zero exit code
+ (bug#16722).
+
+2020-09-25 Tino Calancha <tino.calancha@gmail.com>
+
+ Use the char history in zap-up-to-char
+
+ * lisp/misc.el (zap-up-to-char): Use read-char-from-minibuffer
+ (bug#39154).
+
+2020-09-25 Mattias Engdegård <mattiase@acm.org>
+
+ Fix replace-in-string infloop with empty pattern string (bug#43598)
+
+ * lisp/subr.el (replace-in-string): Raise an error if FROMSTRING is
+ empty.
+ * test/lisp/subr-tests.el (replace-in-string): Add test case.
+
+2020-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak updating the process mark in set-process-buffer
+
+ * src/process.c (Fset_process_buffer): Only update the process
+ mark if we actually change the buffer.
+
+2020-09-25 Eli Zaretskii <eliz@gnu.org>
+
+ * lisp/hi-lock.el (hi-lock-auto-select-face): Doc fix. (Bug#43600)
+
+2020-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove more compat code from prolog.el
+
+ * lisp/progmodes/prolog.el (prolog-font-lock-keywords): Remove
+ compat test for a face that's always defined.
+
+2020-09-25 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid infinite recursion with 'relative' line numbers display
+
+ * src/xdisp.c (display_count_lines_visually): Bind
+ 'display-line-numbers' to 'relative' around 'start_display' as
+ well, since that can invoke 'move_it_to' internally, thus
+ causing infinite recursion. (Bug#43589)
+
+2020-09-25 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/ruby-mode.el (ruby-use-smie): Declare obsolete
+
+ (ruby-mode-map, ruby-mode-menu): Don't use ruby-for/backward-sexp any more.
+ (ruby-mode-variables): Always setup SMIE navigation.
+ Still obey `ruby-use-smie` for indentation.
+ (ruby-forward-sexp, ruby-backward-sexp): Mark as obsolete.
+
+2020-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some XEmacs compat code from prolog.el
+
+ * lisp/progmodes/prolog.el (prolog-replace-in-string): Remove XEmacs
+ compat code and make obsolete.
+ (prolog-guess-fill-prefix): Adjust callers.
+ (prolog-uncomment-region): Make obsolete.
+ (prolog-mode-syntax-table): syntax-propertize-rules is always defined.
+ (prolog-syntax-propertize-function): Ditto.
+ (prolog-face-name-p): Make into obsolete alias.
+ (prolog-font-lock-keywords): Adjust callers.
+
+2020-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clean up replace-in-string slightly
+
+ * lisp/subr.el (replace-in-string): Clean up previous fix slightly.
+
+2020-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous replace-in-string rewrite
+
+ * lisp/subr.el (replace-in-string): Fix logic errors in previous
+ patch.
+
+2020-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix replace-in-string multibyteness problems with string-search
+
+ * lisp/subr.el (replace-in-string): Simplify by using the new
+ string-search function (bug#43598).
+
+2020-09-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new function 'string-search'
+
+ * doc/lispref/strings.texi (Text Comparison): Document it.
+ * src/fns.c (Fstring_search): New function.
+
+2020-09-25 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/help-fns.el (help-fns--first-release): Use etc/NEWS as well
+
+2020-09-24 Glenn Morris <rgm@gnu.org>
+
+ Update a failing lisp test
+
+ * test/lisp/emacs-lisp/lisp-tests.el (up-list-no-cross-string):
+ Update for recent "Don't signal scan-error" change.
+
+2020-09-24 Juri Linkov <juri@linkov.net>
+
+ Horizontal scrolling for mouse wheel with Shift modifier (bug#43568)
+
+ * lisp/mwheel.el (mouse-wheel-scroll-amount): Change 'shift' default value
+ from 5 to 'hscroll'. Add new option "Scroll horizontally" for 'hscroll'.
+ (mwheel-scroll): Handle value 'hscroll' and call mwheel-scroll-left-function
+ or mwheel-scroll-right-function.
+
+ * doc/emacs/frames.texi (Mouse Commands): Update for horizontal scrolling
+ with Shift modifier.
+
+2020-09-24 Theodor Thornhill <theo@thornhill.no>
+
+ Set mwheel default scroll value to 1 (bug#43380)
+
+ * lisp/mwheel.el (mouse-wheel-scroll-amount): Change default value 5 to 1
+ and shift default value from 1 to 5.
+ Default value is changed as discussed in etc/TODO.
+
+2020-09-24 Juri Linkov <juri@linkov.net>
+
+ * lisp/simple.el (goto-line-read-args): More relevant default line number.
+
+2020-09-24 Glenn Morris <rgm@gnu.org>
+
+ Add skip condition for some dbus tests
+
+ * test/lisp/net/dbus-tests.el (dbus-test01-type-conversion)
+ (dbus-test01-basic-types): Add skip for hydra.nixos.org failures.
+
+2020-09-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make set-process-buffer also update the process mark
+
+ * src/process.c (Fset_process_buffer): Update the process mark
+ (bug#43573).
+
+2020-09-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Refactor process mark setting
+
+ * src/process.c (update_process_mark): Make into its own function.
+ (Fmake_process, Fmake_pipe_process, Fmake_serial_process)
+ (connect_network_socket): Use it.
+
+2020-09-24 dickmao <none>
+
+ Add sanity check for Gnus groups that belong to no topic
+
+ * lisp/gnus/gnus-topic.el (gnus-topic-change-level): Do not change
+ gnus-topic-alist when group is outside "topology" (bug#43582).
+
+2020-09-24 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change in resize_mini_window
+
+ * src/xdisp.c (resize_mini_window): Prevent recentering the
+ mini-window once its start position is computed. (Bug#43572)
+
+2020-09-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix recent simple.el compilation warning
+
+ * lisp/simple.el (goto-line-relative): Suppress byte compilation
+ warning about goto-line.
+
+2020-09-24 Michael Albinus <michael.albinus@gmx.de>
+
+ Minor Tramp cleanup
+
+ * doc/misc/tramp.texi: Some stylistic changes.
+ (Frequently Asked Questions): Mention ProxyCommand and ProxyJump.
+
+ * lisp/net/tramp-sh.el (tramp-use-ssh-controlmaster-options):
+ Fix docstring.
+
+2020-09-24 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp--subr-safe-advice -> comp-subr-safe-advice
+
+ * lisp/emacs-lisp/comp.el (comp-subr-safe-advice): Rename
+ comp--subr-safe-advice -> comp-subr-safe-advice.
+ * lisp/emacs-lisp/nadvice.el (advice--add-function): Likewise.
+ * lisp/emacs-lisp/advice.el (ad-add-advice): Likewise.
+
+2020-09-24 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-body-eff): Improve style.
+
+2020-09-24 Andrea Corallo <akrl@sdf.org>
+
+ Do not install a subr trampoline twice
+
+ * src/comp.c (syms_of_comp): Define and initialize
+ 'Vcomp_installed_trampolines_h'.
+ (Fcomp__install_trampoline): Fill 'Vcomp_installed_trampolines_h'
+ * lisp/emacs-lisp/comp.el (comp--subr-safe-advice): Make use of
+ `comp-installed-trampolines-h' to guard against installing a
+ trampoline twice.
+
+2020-09-24 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-never-optimize-functions): Clean-up.
+
+2020-09-24 Andrea Corallo <akrl@sdf.org>
+
+ Add a test for primitive advicing effectiveness
+
+ * test/src/comp-test-funcs.el (comp-test-primitive-advice-f): New
+ function.
+ * test/src/comp-tests.el (comp-test-primitive-advice): New test.
+
+2020-09-24 Andrea Corallo <akrl@sdf.org>
+
+ Call `comp--subr-safe-advice' from the advice machinery
+
+ * lisp/emacs-lisp/nadvice.el (advice--add-function): Call
+ `comp--subr-safe-advice' when necessary.
+
+ * lisp/emacs-lisp/advice.el (ad-add-advice): Likewhise.
+
+2020-09-24 Andrea Corallo <akrl@sdf.org>
+
+ Add `comp--subr-safe-advice' entry point
+
+ Add a Lisp side entry-point to be called to make primitive adivicing
+ effective.
+
+ * lisp/emacs-lisp/comp.el (comp-trampoline-sym)
+ (comp-trampoline-filename): New substs.
+ (comp-make-lambda-list-from-subr, comp-search-trampoline)
+ (comp-tampoline-compile): New functions
+
+2020-09-24 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Write Gnus active files with quotes around group names
+
+ * lisp/gnus/gnus-util.el (gnus-write-active-file): In case of group
+ names with spaces in them (see Bug#42823). Names are later read with
+ `read', so this should be quite robust.
+
+2020-09-23 Juri Linkov <juri@linkov.net>
+
+ New command goto-line-relative (bug#5042, bug#9917)
+
+ * lisp/simple.el (goto-line-read-args): New function with code from goto-line.
+ (goto-line): New arg RELATIVE. Also use 'widen-automatically' to
+ leave all lines accessible in the narrowed buffer.
+ (goto-line-relative): New command.
+
+ * lisp/info.el (Info-mode-map): Remap 'goto-line' to 'goto-line-relative'.
+
+ * doc/emacs/basic.texi (Moving Point):
+ * doc/emacs/display.texi (Optional Mode Line): Mention goto-line-relative.
+
+2020-09-23 Andrea Corallo <akrl@sdf.org>
+
+ Add `comp--install-trampoline' machinery
+
+ * src/comp.c (Fcomp__install_trampoline): New function to
+ install a subr trampoline into the function relocation table.
+ Once this is done any call from native compiled Lisp to the
+ related primitive will go through the `funcall' trampoline
+ making advicing effective.
+
+2020-09-23 Andrea Corallo <akrl@sdf.org>
+
+ Make CHECK_SUBR public
+
+ * src/data.c (CHECK_SUBR): Move from here to...
+ * src/lisp.h (CHECK_SUBR): ...to here.
+
+2020-09-23 Stefan Kangas <stefan@marxist.se>
+
+ Remove TODO to convert files to unit tests
+
+ * test/lisp/textmodes/css-mode-tests.el:
+ * test/lisp/progmodes/ruby-mode-tests.el: Remove TODO to convert test
+ files into unit tests. The files are still useful for debugging.
+ Ref: https://lists.gnu.org/r/emacs-devel/2020-09/msg01906.html
+
+2020-09-23 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-final): Log when interactively invoked.
+
+ * lisp/emacs-lisp/comp.el (native-compile): Add OUTPUT parameter.
+
+2020-09-23 Stefan Kangas <stefan@marxist.se>
+
+ Convert some completion.el tests to ERT
+
+ * test/lisp/completion-tests.el: New file.
+ * lisp/completion.el: Move commented out tests to completion-tests.el.
+
+2020-09-23 Stefan Kangas <stefan@marxist.se>
+
+ Convert allout unit tests to ERT
+
+ * test/lisp/allout-tests.el: New file.
+ * lisp/allout.el (allout-run-unit-tests-on-load)
+ (allout-run-unit-tests): Remove.
+ (allout-tests-obliterate-variable)
+ (allout-tests-globally-unbound, allout-tests-globally-true)
+ (allout-tests-locally-true, allout-test-resumptions): Move to
+ allout-tests.el
+
+ * test/lisp/allout-widgets-tests.el: New file.
+ * lisp/allout-widgets.el (allout-widgets-run-unit-tests-on-load)
+ (allout-widgets-run-unit-tests): Remove.
+ (allout-test-range-overlaps): Move to allout-widgets-tests.el.
+
+2020-09-23 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/repeat.el: Remove obsolete comment.
+
+2020-09-23 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/lisp/net/dbus-tests.el (dbus-test01-basic-types): Adapt test.
+
+2020-09-23 Mattias Engdegård <mattiase@acm.org>
+
+ Don't signal scan-error when moving by sexp interactively
+
+ * lisp/emacs-lisp/lisp.el (forward-sexp, backward-sexp, forward-list)
+ (backward-list, down-list, up-list, mark-sexp, kill-sexp)
+ (backward-kill-sexp): Remove unsightly scan-error when running
+ interactively and no further movement by sexp can be made (bug#43489).
+
+2020-09-23 Mauro Aranda <maurooaranda@gmail.com>
+
+ Allow the newline character in the character widget (Bug#15925)
+
+ * lisp/wid-edit.el (widget-specify-field): Extend check for adding the
+ boundary overlay. Plus, a minor comment indentation fix.
+ (character widget): Tweak the valid-regexp to allow the newline
+ character.
+
+ * test/lisp/wid-edit-tests.el (widget-test-character-widget-value)
+ (widget-test-editable-field-widget-value): New tests (bug#15925).
+
+2020-09-23 Andrew G Cohen <cohen@andy.bu.edu>
+
+ Improve mark handling in gnus nnselect
+
+ * lisp/gnus/nnselect.el (numbers-by-group,
+ nnselect-request-update-info, nnselect-push-info): Handle all three
+ mark types ('tuple, 'range, 'list) and general speedups.
+
+2020-09-23 Alan Mackenzie <acm@muc.de>
+
+ Handle escaped comment enders correctly in syntax.c, fixing bug #43558
+
+ This fixes forward-comment, scan-lists, and parse-partial-sexp.
+
+ * src/syntax.c (forw_comment): Detect and skip an escaped comment ender
+ (e.g. \*/ in C) when comment-end-can-be-escaped is non-nil.
+
+2020-09-23 Andrew G Cohen <cohen@andy.bu.edu>
+
+ Run gnus-parse-headers-hook when retrieving nnselect headers
+
+ * lisp/gnus/nnselect.el (nnselect-retrieve-headers): Run the
+ gnus-parse-headers-hook when retrieving headers in nnselect, just like
+ in a real group.
+
+2020-09-23 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ test/src/xdisp-tests.el: New file
+
+2020-09-23 Andrew G Cohen <cohen@andy.bu.edu>
+
+ Use gnus-extra-headers in nnselect header parsing
+
+ * lisp/gnus/nnselect.el (nnselect-retrieve-headers): Bind
+ nnmail-extra-headers to gnus-extra-headers before parsing retrieved
+ headers.
+
+2020-09-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Ensure that the game directory exists before trying to write to it
+
+ * lisp/play/gamegrid.el (gamegrid-add-score-insecure): Make the
+ directory if it doesn't exist (bug#37836).
+
+2020-09-22 martin rudalics <rudalics@gmx.at>
+
+ Make delete-pair only delete pairs that are part of insert-pair-alist
+
+ * lisp/emacs-lisp/lisp.el (delete-pair): Only delete pairs that
+ are part of `insert-pair-alist' (bug#4136).
+
+2020-09-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix off-by-one error in eldoc--handle-docs
+
+ * lisp/emacs-lisp/eldoc.el (eldoc--handle-docs): We have one extra
+ line to use if we don't show the truncation message (bug#43543).
+
+2020-09-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Speed up shr-insert slightly
+
+ * lisp/net/shr.el (shr-insert): Speed up regularising spaces --
+ the vast majority of the spaces are already OK, so transforming
+ " " to " " just takes time.
+
+2020-09-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix filling problem in shr due to zero-width id tagging
+
+ * lisp/net/shr.el (shr-descend): Fix problem with filling lines
+ that have a zero-width ID tag at the start.
+
+2020-09-22 Eli Zaretskii <eliz@gnu.org>
+
+ Fix cursor display in mini-window under icomplete-mode
+
+ * src/xdisp.c (resize_mini_window): When we show only part of the
+ mini-window's contents, make sure the window-start position is at
+ the beginning of a screen line. (Bug#43519)
+
+2020-09-22 Andrea Corallo <akrl@sdf.org>
+
+ Fix MacOS Emacs.app installation (bug#43532)
+
+ * src/comp.c (Fcomp_el_to_eln_filename): Adapt the filename
+ hashing algorithm to allow for producing a MacOS self-contained
+ Emacs.app.
+
+2020-09-22 David Reitter <david.reitter@gmail.com>
+
+ Fix font-panel on NS (bug#43480)
+
+ * lisp/term/ns-win.el (ns-respond-to-change-font): Set the font using
+ customize.
+
+2020-09-22 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove broken compat code from EDE
+
+ * lisp/cedet/ede/detect.el: Remove broken Emacs 24.1 compat code.
+ This would never have worked, since the fallback library is missing.
+
+2020-09-22 Stefan Kangas <stefan@marxist.se>
+
+ Fix shellcheck warning
+
+ * build-aux/update-subdirs: Fix issue indicated by the shellcheck
+ linter (warning SC2046).
+
+2020-09-22 Stefan Kangas <stefan@marxist.se>
+
+ Support shellcheck in compilation-mode
+
+ * lisp/progmodes/compile.el
+ (compilation-error-regexp-alist-alist): Add shellcheck regexp.
+ * test/lisp/progmodes/compile-tests.el
+ (compile-tests--test-regexps-data):
+ (compile-test-error-regexps): Add test for shellcheck.
+ * etc/compilation.txt: Add shellcheck example.
+ * etc/NEWS: Announce the change.
+
+ foo
+
+2020-09-22 Stefan Kangas <stefan@marxist.se>
+
+ Remove Emacs 23 compat code from cedet
+
+ * lisp/cedet/ede/proj-elisp.el (project-compile-target):
+ * lisp/cedet/semantic/bovine/grammar.el (bovine-grammar-expand-form):
+ * lisp/cedet/semantic/ede-grammar.el (project-compile-target):
+ Remove Emacs 23 compat code.
+
+2020-09-22 Stefan Kangas <stefan@marxist.se>
+
+ Remove some Emacs 20 compat code
+
+ * lisp/apropos.el (apropos-local-value):
+ * lisp/progmodes/antlr-mode.el (antlr-mode-menu):
+ * lisp/progmodes/idlwave.el (idlwave-attach-classes):
+ * lisp/textmodes/artist.el (artist-replace-chars): Remove Emacs 20
+ compat code.
+
+2020-09-22 Stefan Kangas <stefan@marxist.se>
+
+ Remove some unnecessary compat code
+
+ * test/lisp/emacs-lisp/ert-x-tests.el (ert-test-describe-test):
+ * test/lisp/wdired-tests.el (wdired-test-unfinished-edit-01):
+ Remove unnecessary compat code; these tests should never need to run
+ on older versions of Emacs.
+
+2020-09-22 Stefan Kangas <stefan@marxist.se>
+
+ Fix thinko in dired-change-marks
+
+ * lisp/dired.el (dired-change-marks): Fix my previous broken attempt
+ to declare advertised-calling-convention.
+
+2020-09-21 Andrea Corallo <akrl@sdf.org>
+
+ Make use of use of `subr-primitive-p' in `find-function-library'
+
+ * lisp/emacs-lisp/find-func.el (find-function-library): Use
+ `subr-primitive-p'.
+
+2020-09-21 Andrea Corallo <akrl@sdf.org>
+
+ Sandbox synchronous libgccjit invocation on interactive sessions
+
+ Avoid unnecessary memory fragmentation/leakeage
+
+ * lisp/emacs-lisp/comp.el (comp-final1): New function.
+ (comp-final): Invoke `comp-final1' in a child process if in an
+ interactive session or directly otherwise.
+
+2020-09-21 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-09-21 Stefan Kangas <stefankangas@gmail.com>
+
+ Move several completions from eshell to pcomplete (Bug#10585)
+
+ * lisp/eshell/em-unix.el (eshell-complete-hostname)
+ (pcomplete/ftp, pcomplete/ncftp, pcomplete/ping)
+ (pcomplete/rlogin, pcomplete/telnet, pcomplete/rsh):
+ Move from here...
+ * lisp/pcmpl-unix.el (pcmpl-unix-complete-hostname)
+ (pcomplete/ftp, pcomplete/ncftp, pcomplete/ping)
+ (pcomplete/rlogin, pcomplete/telnet, pcomplete/rsh):
+ ...to here. Make old names into aliases.
+
+ * lisp/eshell/esh-util.el (eshell-hosts-file)
+ (eshell-host-names, eshell-host-timestamp)
+ (eshell-read-hosts-file, eshell-read-hosts)
+ (eshell-read-host-names): Move from here...
+ * lisp/pcomplete.el (pcomplete-hosts-file)
+ (pcomplete--host-name-cache)
+ (pcomplete--host-name-cache-timestamp)
+ (pcomplete-read-hosts-file, pcomplete-read-hosts)
+ (pcomplete-read-host-names): ...to here. Make old names into
+ aliases.
+
+ * lisp/eshell/em-unix.el (eshell-complete-host-reference): Update
+ caller.
+
+2020-09-21 Stefan Kangas <stefankangas@gmail.com>
+
+ Move pcomplete/bcc32 from eshell to pcmpl-x (Bug#10585)
+
+ * lisp/eshell/em-xtra.el (pcomplete/bcc32, pcomplete/bcc): Move
+ from here...
+ * lisp/pcmpl-x.el (pcomplete/bcc32, pcomplete/bcc): ...to here.
+
+2020-09-21 Stefan Kangas <stefan@marxist.se>
+
+ Convert a manual test for nxml-mode to unit test
+
+ * test/manual/indent/nxml.xml: Delete file.
+ * test/lisp/nxml/nxml-mode-tests.el
+ (nxml-mode-test-comment-bug-17264): New test based on deleted file.
+
+2020-09-21 Stefan Kangas <stefan@marxist.se>
+
+ Convert manual indent test for ruby-mode into unit test
+
+ * test/manual/indent/ruby.rb: Move from here...
+ * test/lisp/progmodes/ruby-mode-resources/ruby.rb: ...to here.
+
+ * test/lisp/progmodes/ruby-mode-tests.el
+ (ruby-mode-tests-data-dir): New variable.
+ (ruby--indent/converted-from-manual-test): New test.
+
+2020-09-21 Stefan Kangas <stefan@marxist.se>
+
+ Convert manual indent test for scheme-mode into unit test
+
+ * test/manual/indent/scheme.scm: Delete file.
+ * test/lisp/progmodes/scheme-tests.el: New file with unit test for
+ scheme-mode based on deleted file.
+
+2020-09-21 Stefan Kangas <stefan@marxist.se>
+
+ Convert manual indent test for ps-mode into unit test
+
+ * test/manual/indent/ps-mode.ps: Delete file.
+ * test/lisp/progmodes/ps-mode-tests.el (ps-mode-test-indent):
+ New unit test based on deleted file.
+
+2020-09-21 Sam Steingold <sds@gnu.org>
+
+ (json-encode-string): Strip properties to fix bug#43549
+
+2020-09-21 Lin Sun <lin.sun@zoom.us>
+
+ Fix problem with ede-mode bugging out on non-existent files
+
+ * lisp/cedet/ede/emacs.el: Check whether the directory exists in
+ ede-emacs-find-in-directories before using it (bug#43547).
+
+2020-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix recent change to window-max-chars-per-line
+
+ * lisp/window.el (window-max-chars-per-line):
+ line-number-display-width can return a floating point number, but
+ we want an integer (bug#43548).
+
+2020-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Doc string fix for gnus-summary-hide-thread
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-hide-thread): Remove text
+ from doc string apparently copy-pasted from the function above.
+
+2020-09-21 dickmao <none>
+
+ Remove a misleading message in gnus-summary-hide-thread
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-hide-thread):
+ Jump past invisible thread instead of begging off with an out-of-band
+ diagnostic (bug#43538).
+
+2020-09-21 Stefan Kangas <stefan@marxist.se>
+
+ Convert manual indent test for opascal-mode into unit test
+
+ * test/manual/indent/opascal.pas: Delete file.
+ * test/lisp/progmodes/opascal-tests.el: New file with unit test for
+ oposcal-mode based on deleted file.
+
+2020-09-21 Stefan Kangas <stefan@marxist.se>
+
+ Convert manual indent test for lisp-mode into unit test
+
+ * test/manual/indent/lisp.lisp: Delete file.
+ * test/lisp/emacs-lisp/lisp-mode-tests.el (lisp-indent-defun):
+ New unit test based on deleted file.
+
+2020-09-21 Stefan Kangas <stefan@marxist.se>
+
+ Convert manual indent test for elisp-mode into unit test
+
+ * test/manual/indent/elisp.el: Delete file.
+ * test/lisp/progmodes/elisp-mode-tests.el (elisp-indent-basic):
+ New unit test based on deleted file.
+
+2020-09-21 Stephen Berman <stephen.berman@gmx.net>
+
+ Fix check in `newline' for blank lines
+
+ * lisp/simple.el (newline): Clarify doc string and fix check for
+ blank lines (bug#13810).
+
+2020-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix line width in M-x term on -nw with line numbers
+
+ * lisp/window.el (window-max-chars-per-line): Make the line width
+ more correct in the presence of display-line-numbers-mode (bug#34513).
+
+2020-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add more isearch submatch faces
+
+ * doc/emacs/search.texi (Search Customizations): Adjust
+ documentation.
+ * lisp/isearch.el (search-highlight-submatches): Be a boolean.
+ (isearch-group-{6-9}): New faces.
+ (isearch-highlight): Use the variable as a boolean.
+
+2020-09-21 Juri Linkov <juri@linkov.net>
+
+ Tweak how Man selects the previous window on failure
+
+ * lisp/man.el (Man-bgproc-sentinel): Ensure that we select the
+ correct previous window (bug#38164).
+
+2020-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow disabling the verbose eldoc truncation message
+
+ * doc/emacs/programs.texi (Lisp Doc): Document it.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-display-truncation-message): New
+ variable (bug#43543).
+ (eldoc--handle-docs): Use it.
+
+2020-09-21 Nicolas Graner <nicolas.graner@universite-paris-saclay.fr> (tiny change)
+
+ Fix default value in checkboxes in eww
+
+ * lisp/net/eww.el (eww-submit): Checked checkboxes need a default
+ value (bug#43542).
+
+2020-09-21 Michael Albinus <michael.albinus@gmx.de>
+
+ Add D-Bus tests
+
+ * doc/misc/dbus.texi (Type Conversion): Precise basic type values.
+
+ * lisp/net/dbus.el (dbus-register-property): Send signal directly.
+
+ * src/dbusbind.c (xd_signature): Accept non-nil objects for
+ DBUS_TYPE_BOOLEAN.
+
+ * test/lisp/net/dbus-tests.el (dbus-test01-basic-types)
+ (dbus-test01-compound-types): New tests.
+
+2020-09-21 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 02a31c9632 (origin/emacs-27) Minor improvement in the ELisp manual's ...
+ f750def778 Mention in PROBLEMS the problems with fonts and Uniscribe
+ 082d8a21b1 Minor copyedits in 'line-height' documentation
+ 5b23393bcc ; * src/frame.c (syms_of_frame) <make-pointer-invisible>: ...
+
+2020-09-21 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ df04f3e755 Fix a rare segfault in syntax.c
+ fd1fe1e1ec Add doc to syntax-propertize-function saying it must do a ...
+ fcd599bbea Minor copyedits of doc of 'with-silent-modifications'
+ 759399cdb1 Improve documentation of 'max-mini-window-height'
+ 3223302aa2 Use modern constant names for the NS pasteboard
+ 985703d380 Fix doc string of 'toggle-menu-bar-mode-from-frame'
+ 184a4977c7 Make vc-bzr tests work with brz 3.1 (bug#43314)
+
+ # Conflicts:
+ # lisp/emacs-lisp/syntax.el
+ # src/syntax.c
+
+2020-09-21 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 694acda5f2 Fix compilation on TERMINFO platforms with GCC 10
+ f3373901e5 Fix the font-lock-debug-fontify NEWS entry
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix infloop when folding difficult headers in Message
+
+ * lisp/mail/rfc2047.el (rfc2047-fold-field): Return the end point.
+ * lisp/gnus/message.el (message--fold-long-headers): Use that to
+ reliably achieve progress.
+
+2020-09-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow not selecting messages in Gnus before resending
+
+ * lisp/gnus/gnus-msg.el (gnus-summary-resend-message): Allow not
+ selecting messages. This is faster when resending huge spam messages.
+
+2020-09-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make xterm-mouse-event check whether the click event is valid
+
+ * lisp/xt-mouse.el (xterm-mouse-event): Defensively check against
+ a situation that shouldn't happen (but does) (bug#17378).
+
+2020-09-20 Alan Mackenzie <acm@muc.de>
+
+ C++ Mode: Modernize the fontification of "using"
+
+ Since "using" is now used in three distinct ways in C++, write a special
+ function to handle these rather than attempting to adapt the old regular
+ expressions.
+
+ * lisp/progmodes/cc-fonts.el (c-font-lock-declarators): Amend to allow the
+ argument TYPES to be a face. This face is given to the declarator being
+ processed.
+ (c-font-lock-single-decl): Make an argument to c-font-lock-declarators nil or
+ t, not merely nil or non-nil.
+ (c-complex-decl-matchers): Include c-font-lock-c++-using in the C++ value of
+ this variable.
+ (c-font-lock-c++-using): New function.
+
+ * lisp/progmodes/cc-langs.el (c-using-kwds, c-using-key): New lang
+ consts/vars.
+ (c-modifier-kwds): Remove "using" from the C++ value.
+
+2020-09-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Restore the previous minimum-width specs in the line/column mode lines
+
+ * lisp/bindings.el (mode-line-position-line-format)
+ (mode-line-position-column-format)
+ (mode-line-position-column-line-format, mode-line-position):
+ Restore the previous min-width specs (bug#28648).
+
+2020-09-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make (let ((:key 'foo)) :key) signal an error in lexical elisp, too
+
+ * src/lread.c (intern_sym): Mark keywords as special (bug#38872).
+
+2020-09-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix typo in dbus.texi
+
+ * doc/misc/dbus.texi (Type Conversion): Remove spurious { character.
+
+2020-09-20 Michael Albinus <michael.albinus@gmx.de>
+
+ Make D-Bus properties type safe
+
+ * doc/misc/dbus.texi (Properties and Annotations):
+ Precise dbus-get-property and dbus-set-property.
+ (Type Conversion): Explain :byte and :boolean type conversion.
+ (Errors and Events): dbus-ignore-errors returns nil when there is
+ a D-Bus error. Remove dbus-show-dbus-errors.
+
+ * etc/NEWS: Some D-Bus relevant changes.
+
+ * lisp/net/dbus.el (dbus-show-dbus-errors): Remove.
+ (dbus-ignore-errors): Replay implementation without that variable.
+ (dbus-check-arguments): New defun.
+ (dbus-list-activatable-names, dbus-list-names)
+ (dbus-list-queued-owners, dbus-get-name-owner, dbus-introspect)
+ (dbus-get-all-properties, dbus-get-all-managed-objects): Don't debug.
+ (dbus-get-property, dbus-set-property): Propagate errors.
+ (dbus-register-property): Check for valid VALUE.
+ (dbus-property-handler): Simplify.
+
+ * src/dbusbind.c (Fdbus_message_internal): Adapt docstring.
+ Handle DBUS_MESSAGE_TYPE_INVALID.
+
+ * test/lisp/net/dbus-tests.el (dbus-show-dbus-errors): Don't declare.
+ (dbus-test06-register-property)
+ (dbus-test06-register-property-emits-signal): Adapt tests.
+
+2020-09-20 Eli Zaretskii <eliz@gnu.org>
+
+ Minor improvement in the ELisp manual's Introduction
+
+ * doc/lispref/intro.texi (Printing Notation): Clarify what
+ "execute code" means in this context. (Bug#43463)
+
+2020-09-20 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of a recently-added feature
+
+ * lisp/isearch.el (search-highlight-submatches): Improve the doc
+ string.
+
+ * doc/emacs/search.texi (Search Customizations): Improve the
+ documentation of 'search-highlight-submatches'.
+
+ * etc/NEWS: Minor change of the entry for
+ 'search-highlight-submatches'.
+
+2020-09-20 Juri Linkov <juri@jurta.org>
+
+ Highlight regexp sub-expressions
+
+ * doc/emacs/search.texi (Search Customizations): Document it.
+
+ * lisp/isearch.el (search-highlight-submatches): New variable.
+ (isearch-group-1, isearch-group-2, isearch-group-3)
+ (isearch-group-4, isearch-group-5): New faces.
+ (isearch-highlight): Use them.
+ (isearch-dehighlight): Ditto (bug#6227).
+
+2020-09-20 Kévin Le Gouguec <kevin.legouguec@gmail.com>
+
+ Tweak dired warning about "wildcard" characters
+
+ * lisp/dired-aux.el (dired-isolated-string-re): Use explicitly
+ numbered groups.
+ (dired--star-or-qmark-p): Add START parameter. Make sure to
+ return the first isolated match.
+ (dired--need-confirm-positions, dired--mark-positions)
+ (dired--highlight-no-subst-chars, dired--no-subst-explain)
+ (dired--no-subst-ask, dired--no-subst-confirm): New functions.
+ (dired-do-shell-command): Use them (bug#28969, bug#35564).
+
+ * test/lisp/dired-aux-tests.el (dired-test-bug27496): Adapt to
+ new prompt.
+ (dired-test--check-highlighting): New test helper.
+ (dired-test-highlight-metachar): New tests.
+
+2020-09-20 Eli Zaretskii <eliz@gnu.org>
+
+ Mention in PROBLEMS the problems with fonts and Uniscribe
+
+ * etc/PROBLEMS: Mention font-related problems with Uniscribe on
+ MS-Windows. (Bug#39340)
+
+2020-09-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix bug out when indenting inserted images in shr
+
+ * lisp/net/shr.el (shr-fill-line): We may not have a
+ shr-indentation text property here. In that case, default to the
+ dynamically bound value.
+
+2020-09-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove code checked in to lread.c by mistake
+
+ * src/lread.c (intern_sym): Remove code under development
+ inadvertently checked in.
+
+2020-09-20 dickmao <dick.r.chiang@gmail.com>
+
+ Terminate `comint-password-function' tests
+
+ * test/lisp/comint-tests.el (comint-test-no-password-function)
+ (comint-test-password-function-with-value)
+ (comint-test-password-function-with-nil): refactor
+ (comint-tests/test-password-function): actually test
+ `comint-send-invisible' and inhibit inadvertent interactive query
+ (bug#38825).
+
+2020-09-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak a hash table print test
+
+2020-09-20 Pip Cet <pipcet@gmail.com>
+
+ Fix printing of hash tables with removed elements
+
+ * src/print.c (print_vectorlike): Keep track of the actual number
+ of elements printed rather than attempting to use hash bucket
+ indices (bug#38892).
+
+2020-09-20 Dmitry Gutov <dgutov@yandex.ru>
+
+ Don't have vc-git-stash-list bug out on the .git directory
+
+ * lisp/vc/vc-git.el (vc-git-stash-list): Don't bug out when
+ running on the .git directory itself (bug#39285).
+
+2020-09-20 Earl <ej32u@protonmail.com>
+
+ Add new tab command `C-x t C-r'
+
+ * doc/emacs/misc.texi (FFAP): Document new commands (bug#43503).
+
+ * lisp/ffap.el (ffap-read-only-other-tab): New command.
+
+ * lisp/tab-bar.el (find-file-read-only-other-tab): New command and
+ keystroke.
+
+2020-09-20 Noam Postavsky <npostavs@gmail.com>
+
+ Fix slow python-mode inserts when there's a lot of strings
+
+ * lisp/progmodes/python.el (python-info-docstring-p): Doing more
+ than two repetitions here doesn't improve indentation (bug#39598).
+
+2020-09-20 Mauro Aranda <maurooaranda@gmail.com>
+
+ New command: revert-buffer-with-fine-grain
+
+ * doc/emacs/files.texi (Reverting): Document the new command and the
+ new variable.
+
+ * etc/NEWS: Mention the new command and the new variable.
+
+ * lisp/files.el (revert-buffer-with-fine-grain): New command. Revert
+ a buffer trying to be non-destructive, by using replace-buffer-contents.
+ (revert-buffer-insert-file-contents-delicately): New function, alternative
+ to revert-buffer-insert-file-contents-function--default-function.
+ (revert-buffer-with-fine-grain-max-seconds): New variable. Passed as
+ argument MAX-SECS of replace-buffer-contents.
+
+ * test/lisp/files-tests.el (files-tests-lao files-tests-tzu): Helper
+ variables, taken from diffutils manual, to test reverting a buffer.
+ (files-tests-revert-buffer)
+ (files-tests-revert-buffer-with-fine-grain): New tests (bug#18).
+
+2020-09-20 Nick Roberts <nickrob@snap.net.nz>
+
+ Make a gud error message more informative
+
+ * lisp/progmodes/gud.el (gud-jdb-marker-filter): Make the error
+ message more informative (bug#1282).
+
+2020-09-20 Peder O. Klingenberg <peder@klingenberg.no>
+
+ Extend process-lines to allow exit status handling
+
+ * lisp/subr.el (process-lines-handling-status): Extension of the
+ old process-lines, with more flexible handling of the exit status.
+ (process-lines): Old API implemented using the new function.
+ (process-lines-ignore-status): Another use of the new function -
+ return the output lines regardless of the exit status (bug#1321).
+
+2020-09-19 Eli Zaretskii <eliz@gnu.org>
+
+ Minor copyedits in 'line-height' documentation
+
+ * doc/lispref/display.texi (Line Height): Describe the possible
+ values of the 'line-height' property in a more consistent format.
+
+2020-09-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new variable 'gnus-global-groups'
+
+ * doc/misc/gnus.texi (HTML): Document it.
+
+ * lisp/gnus/gnus-art.el (gnus-global-groups): New variable.
+ (gnus-block-private-groups): Use it.
+
+2020-09-19 bug-gnu-emacs@gnu.org <bug-gnu-emacs@gnu.org>
+
+ Honor make-pointer-invisible on macOS
+
+ * src/nsterm.m ([EmacsView keyDown:]): Call
+ [NSCursor setHiddenUntilMouseMoves:] with the correct argument, depending on
+ variable make-pointer-invisible.
+
+2020-09-19 Gregor Zattler <telegraph@gmx.net>
+
+ * doc/misc/eww.texi: Document the `w' key's double function
+
+ * doc/misc/eww.texi (Basics): Describe what the `w' command does
+ in eww (bug#43517).
+
+2020-09-19 Gregor Zattler <telegraph@gmx.net>
+
+ * doc/misc/eww.texi: Document the `w' key's double function
+
+ * doc/misc/eww.texi (Basics): Describe what the `w' command does
+ in eww (bug#43517).
+
+2020-09-19 Daniel Martín <mardani29@yahoo.es>
+
+ Put files in mhtml-mode when they have <!DOCTYPE, case-insensitive
+
+ * lisp/files.el (magic-fallback-mode-alist): Match "DOCTYPE" in a
+ case-insensitive way before putting files in mhtml-mode. See
+ https://html.spec.whatwg.org/multipage/syntax.html#the-doctype for the
+ standard reference.
+ * test/lisp/files-tests.el (files-test-magic-mode-alist-doctype): Add
+ a test (bug#43511).
+
+2020-09-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with spurious extra paragraphs in shr
+
+ * lisp/net/shr.el (shr-ensure-paragraph): Don't regard <div
+ id=foo></div> (empty placeholders) as occupying any space (bug#43510).
+
+2020-09-19 Eli Zaretskii <eliz@gnu.org>
+
+ Fix a rare segfault in syntax.c
+
+ * src/syntax.c (Fforward_comment): Prevent the loop for COUNT < 0
+ from going outside the valid range of character/byte positions.
+ (Bug#43499)
+
+ * doc/lispref/syntax.texi (Syntax Class Table): Mention the
+ "comment-fence" and "string-fence" as alternative names of 2
+ syntax classes.
+
+2020-09-19 Alan Mackenzie <acm@muc.de>
+
+ Add doc to syntax-propertize-function saying it must do a 100% job
+
+ and cannot be combined with other ways of applying syntax-table text
+ properties.
+
+ * lisp/emacs-lisp/syntax.el (syntax-propertize-function): Amend doc string.
+
+ * doc/lispref/syntax.texi (Syntax Properties): Amend the description of the
+ variable.
+
+2020-09-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ * lisp/menu-bar.el (menu-bar-showhide-fringe-menu): Adjust caller.
+ (menu-bar-search-options-menu): Ditto.
+ (menu-bar-options-menu): Ditto.
+ (menu-bar-options-menu): Ditto.
+
+ * lisp/progmodes/gdb-mi.el (menu): Ditto.
+
+ * lisp/emacs-lisp/find-func.el (find-function-regexp): Add
+ menu-bar-make-toggle-command.
+
+ * lisp/menu-bar.el (menu-bar-make-toggle): Compatibility wrapper.
+
+2020-09-19 Drew Adams <drew.adams@oracle.com>
+
+ * lisp/menu-bar.el (menu-bar-make-toggle-command): Add doc string
+ and allow setting all keywords (bug#17954).
+
+2020-09-19 Lennart Borgman <lennart.borgman@gmail.com>
+
+ Allow reveal mode to not automatically re-hide revealed text
+
+ * lisp/reveal.el (reveal-hide-revealed): New command (bug#7101).
+ (reveal-auto-hide): New defcustom.
+ (reveal-post-command): Use it.
+
+2020-09-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow customizing hooks defined via define-minor-mode
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Allow using
+ Customize on the hooks (bug#10773).
+
+2020-09-19 Alex Bochannek <alex@bochannek.com>
+
+ Fix gnus-summary-catchup-from-here edge case
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-catchup-from-here): Make the
+ command work in the final line in the buffer, too (bug#43496).
+
+2020-09-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document Gnus body matching quirks
+
+ * doc/misc/gnus.texi (Summary Score Commands): Document body
+ match quirks (bug#43502).
+
+2020-09-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Display the language in the Flyspell mode line
+
+ * lisp/textmodes/flyspell.el (flyspell-mode): Display the language
+ in the mode line (bug#14957).
+
+2020-09-19 Eli Zaretskii <eliz@gnu.org>
+
+ Minor copyedits of doc of 'with-silent-modifications'
+
+ * doc/lispref/text.texi (Changing Properties):
+ * doc/lispref/buffers.texi (Buffer Modification): Improve
+ documentation and indexing of 'with-silent-modifications'.
+
+2020-09-18 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of 'max-mini-window-height'
+
+ * src/xdisp.c (syms_of_xdisp):
+ * doc/lispref/minibuf.texi (Minibuffer Windows): More accurate
+ wording in the documentation of 'max-mini-window-height', to
+ clarify the meaning of an integer value.
+
+2020-09-18 Daniel Martín <mardani29@yahoo.es>
+
+ Use modern constant names for the NS pasteboard
+
+ Use the same pasteboard constant names defined in
+ ns_drag_types. (Bug#43470).
+
+ * src/nsterm.m: Rename NSURLPboardType to NSPasteboardTypeURL,
+ NSStringPboardType to NSPasteboardTypeString, and
+ NSTabularTextPboardType to NSPasteboardTypeTabularText
+
+2020-09-18 Stefan Kangas <stefan@marxist.se>
+
+ Fix typo in project-kill-buffers
+
+ * lisp/progmodes/project.el (project-kill-buffers): Fix typo.
+ Reported by Manuel Uberti <manuel.uberti@inventati.org>
+
+2020-09-18 Andrii Kolomoiets <andreyk.mad@gmail.com>
+
+ Save and restore point in ewoc-invalidate
+
+ * lisp/emacs-lisp/ewoc.el (ewoc--refresh-node): Save and restore point line
+ and column offset.
+ (eowc-map) (ewoc--invalidate) (ewoc-set-hf): Don't use save-excursion
+ * lisp/vc/vc-dir.el (vc-dir-update): Don't save/restore point on calling
+ 'ewoc-invalidate'.
+
+2020-09-18 Adam Sjøgren <asjo@koldfront.dk>
+
+ Make emacs-uptime insert at point with prefix arg
+
+ * lisp/time.el (emacs-uptime): Insert at point when called with prefix
+ argument. (Bug#20112)
+
+2020-09-18 Stefan Kangas <stefan@marxist.se>
+
+ Doc fix in directory-free-space-program
+
+ * lisp/files.el (directory-free-space-program): Doc fix; there is no
+ need to repeat that its obsolete here since it will be shown by
+ customize, describe-variable, etc. automatically.
+
+2020-09-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix the defcustom type of eww-retrieve-command
+
+ * lisp/net/eww.el (eww-retrieve-command): The type is a list of
+ strings.
+
+2020-09-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use a widget for the face link in Customize buffers
+
+ * doc/lispref/customize.texi (Common Keywords): Document it.
+
+ * lisp/cus-edit.el (custom-face-value-create): Use a widget
+ instead of a button so that TAB works (bug#20664).
+
+ * lisp/wid-edit.el (face-link): New widget.
+ (widget-face-link-action): New action.
+
+2020-09-18 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix error in D-Bus test
+
+ * test/lisp/net/dbus-tests.el (dbus-test04-register-method):
+ Do not check for error message text.
+ (dbus--test-signal-handler): Fix docstring.
+ (dbus--test-timeout-handler): New defun.
+ (dbus-test05-register-signal)
+ (dbus-test06-register-property-emits-signal): Use it.
+
+2020-09-18 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/progmodes/cperl-mode.el (cperl-set-style): Fix docstring.
+
+2020-09-18 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix typo, reported by Manuel Uberti
+
+ * lisp/progmodes/project.el (project-kill-buffer-conditions):
+ Fix typo.
+
+2020-09-18 Eli Zaretskii <eliz@gnu.org>
+
+ Minor cleanup of last change
+
+ * src/termchar.h (struct tty_display_info):
+ * src/term.c (turn_on_face, tty_capable_p): Reformat new code.
+
+2020-09-18 Mike Hamrick <mikeh@muppetlabs.com>
+
+ TTY Support for ECMA-48 strike-through graphic rendition
+
+ * src/term.c: Support strike-through in capable terminals.
+ (no_color_bit): Replace unused NC_INVIS with
+ NC_STRIKE_THROUGH.
+ (turn_on_face): Output via TS_enter_strike_through_mode
+ if available.
+ (turn_off_face): Handle strike-through case.
+ (tty_capable_p, init_tty): Support strike-through.
+ * src/termchar.h (struct tty_display_info): Add field for
+ strike-through.
+ * src/xfaces.c (tty_supports_face_attributes_p, realize_tty_face):
+ Handle strike-through case.
+ * src/dispextern.h: Add TTY_CAP_STRIKE_THROUGH definition.
+ (struct face): Add field tty_strike_through_p.
+
+2020-09-18 James N. V. Cash <james.cash@occasionallycogent.com> (tiny change)
+
+ * lisp/tab-bar.el (tab-bar-new-tab-to): Fix tabs not reappearing (bug#42052)
+
+2020-09-18 Eli Zaretskii <eliz@gnu.org>
+
+ Update TUTORIAL.he
+
+ * etc/tutorials/TUTORIAL.he: Adapt to latest changes in the
+ English TUTORIAL.
+
+2020-09-18 Richard Stallman <rms@gnu.org>
+
+ Document easy ways of typing undo key on TTY frames
+
+ * doc/emacs/basic.texi (Basic Undo): Document the easiest way to
+ type the undo key.
+
+ * etc/tutorials/TUTORIAL: Describe typing C-_ without the Shift
+ key.
+
+2020-09-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Make delete-pair only delete pairs that are part of insert-pair-alist"
+
+ This reverts commit 82de8ecc080d91dd05f2432d2d07feb2955aeec4.
+
+ This patch breaks doing `M-x delete-pair' on "foo" in text-mode.
+
+2020-09-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove mention of C-u M-. from the refcards
+
+ The "find next tags" command no longer exists, as the machinery has
+ been replaced by xref.
+
+2020-09-17 Mauro Aranda <maurooaranda@gmail.com>
+
+ Fix recent change in wid-edit
+
+ * lisp/wid-edit.el (widget-button--check-and-call-button): Record the
+ ending position of event, because we might need it when
+ the :mouse-down-action function returns non-nil (bug#20664).
+
+2020-09-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Doc string typo fix for mode-line-position-column-format
+
+ * lisp/bindings.el (mode-line-position-column-format): Fix typo in
+ doc string.
+
+2020-09-17 Oleh Krehel <ohwoeowho@gmail.com>
+
+ Make face names clickable in Customize buffers
+
+ * lisp/cus-edit.el (custom-face-value-create): Make the face name
+ a clickable button (bug#20664).
+
+2020-09-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Refactor a very long wid-edit function and add additional checking
+
+ * lisp/wid-edit.el (widget-button--check-and-call-button): Factor
+ out a too-long condition/call...
+ (widget-button-click): From here.
+
+2020-09-17 Juri Linkov <juri@linkov.net>
+
+ Allow binding keys in `query-replace-map'
+
+ * lisp/replace.el (perform-replace): Allow binding keys in
+ `query-replace-map' (bug#20687).
+
+2020-09-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up previous autoload-find-generated-file change
+
+ * lisp/emacs-lisp/autoload.el (autoload-find-generated-file): Use
+ the correct name for find-file-hook.
+
+2020-09-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make package install not bug out on weird stuff in find-file-hooks
+
+ * lisp/emacs-lisp/autoload.el (autoload-find-generated-file):
+ Users may have read-only-mode in find-file-hooks (bug#43460) so
+ just disable all the hooks here.
+
+2020-09-17 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Add new value "PBP" for 'cperl-set-style'
+
+ * lisp/progmodes/cperl-mode.el (cperl-style-alist)
+ (cperl-set-style): Add indentation style recommended by Damian Conway's
+ book "Perl Best Practices".
+
+ * test/lisp/progmodes/cperl-mode-tests.el
+ (cperl-mode-test-indent-styles): Add a test to verify indentation
+ and unraveling of conditionals (bug#43457).
+
+2020-09-17 Eli Zaretskii <eliz@gnu.org>
+
+ Fix documentation of a recent change
+
+ * src/keyboard.c (update_recent_keys): Fix commentary.
+ (Flossage_size): Fix doc string.
+
+ * etc/NEWS: Move and fix wording of the recently added entry.
+
+2020-09-17 Masahiro Nakamura <tsuucat@icloud.com>
+
+ etc/refcards/refcard.tex: Fix some grouping regexps
+
+ * etc/refcards/refcard.tex (section{Regular Expressions}): Fix the
+ shy/numbered grouping examples (bug#43429).
+
+2020-09-17 Michael Albinus <michael.albinus@gmx.de>
+
+ Work on D-Bus properties etc
+
+ * lisp/net/dbus.el (seq, subr-x): Require.
+ (dbus-error-disconnected, dbus-error-service-unknown): New defconst.
+ (dbus-set-property, dbus-register-property): Use `keywordp'. Fix
+ proper value sending a signal.
+
+ * test/lisp/net/dbus-tests.el (dbus-test04-register-method):
+ Extend test.
+ (dbus--test-signal-received): New defvar.
+ (dbus--test-signal-handler): New defun.
+ (dbus-test05-register-signal)
+ (dbus-test06-register-property-emits-signal): New tests.
+ (dbus-test06-register-property)
+ (dbus-test06-register-property-several-paths): Rename tests.
+
+2020-09-17 Alex Bochannek <alex@bochannek.com>
+
+ Allow user-defined scoring in Gnus
+
+ * lisp/gnus/gnus-score.el (gnus-score-func): New function (bug#43413).
+ * doc/misc/gnus.texi (Score File Format): Document it.
+
+2020-09-17 martin rudalics <rudalics@gmx.at>
+
+ Make delete-pair only delete pairs that are part of insert-pair-alist
+
+ * lisp/emacs-lisp/lisp.el (delete-pair): Only delete pairs that
+ are part of `insert-pair-alist' (bug#4136).
+
+2020-09-17 Tino Calancha <ccalancha@suse.com>
+
+ Give Lisp control on the lossage size
+
+ Add a command 'lossage-size' to set the maximum
+ number or recorded keystrokes (Bug#38796).
+
+ * src/keyboard.c (lossage_limit):
+ Static variable with the current lossage size limit.
+ (MIN_NUM_RECENT_KEYS): Renamed from NUM_RECENT_KEYS.
+ Set it as 100 and use it as the minimum value for lossage_limit.
+ Keep the same default for the vector size as before (300).
+ (lossage-size): New command.
+ (update_recent_keys): Helper function.
+ (command_loop_1)
+ (record_char)
+ (recent-keys)
+ (syms_of_keyboard): Use lossage_limit as the vector size.
+
+ * lisp/help.el (view-lossage): Mention the new command in the docstring.
+ * etc/NEWS (Changes in Emacs 28.1): Announce this change.
+ * doc/emacs/help.texi (Misc Help): Update manual.
+ * test/src/keyboard-tests.el (keyboard-lossage-size): Add test.
+
+2020-09-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up previous change for column/line spec mechanism in the mode line
+
+ * lisp/bindings.el (column-number-indicator-zero-based): Make
+ obsolete (bug#28648).
+ (mode-line-position-column-line-format): New variable.
+ (mode-line-position--column-line-properties): New const.
+ (mode-line-position): Use it.
+
+2020-09-17 Andreas Schwab <schwab@linux-m68k.org>
+
+ Remove pointless use of intern
+
+ * lisp/mwheel.el (mouse-wheel-left-event)
+ (mouse-wheel-right-event): Replace use of intern with quoted
+ symbol.
+ * lisp/profiler.el (profiler-calltree-build-unified): Likewise.
+ * lisp/vc/ediff-util.el (ediff-debug-info): Likewise.
+
+2020-09-16 Eli Zaretskii <eliz@gnu.org>
+
+ Fix doc string of 'toggle-menu-bar-mode-from-frame'
+
+ * lisp/menu-bar.el (toggle-menu-bar-mode-from-frame): Improve the
+ wording of the doc string. (Bug#43383)
+
+2020-09-16 Michael Albinus <michael.albinus@gmx.de>
+
+ D-Bus: keep type information in D-Bus events
+
+ * doc/misc/dbus.texi (Errors and Events):
+ * etc/NEWS: D-Bus events keep the type information of their arguments.
+
+ * lisp/net/dbus.el (dbus-check-event): Fix docstring.
+ (dbus-delete-types, dbus-flatten-types): New defuns.
+ (dbus-handle-event, dbus-register-property, dbus-property-handler):
+ Handle type information.
+ (dbus-set-property): Fix thinko.
+
+ * src/dbusbind.c (XD_BASIC_DBUS_TYPE): Simplify.
+ (xd_dbus_type_to_symbol): New function.
+ (xd_retrieve_arg): Return type information for the arguments.
+ (xd_read_message_1): Return type information for the error name.
+ (dbus-registered-objects-table): Fix docstring.
+
+2020-09-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with previous dired.el change
+
+ * lisp/dired.el (dired-get-filename): dired-current-directory
+ can't be called before the dired buffer has been set up.
+ (add-hook 'dired-mode-hook 'dired-sort-toggle) calls
+ dired-get-filename in a way that exposes this problem, so avoid
+ it.
+
+2020-09-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak previous report-emacs-bug-hook change
+
+ * lisp/mail/emacsbug.el (report-emacs-bug-hook): Add to the hook
+ locally so sending stuff from Message afterwards won't trigger the
+ same question.
+
+2020-09-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make sgml-validate not bug out from buffers not visiting a file
+
+ * lisp/textmodes/sgml-mode.el (sgml-validate): Don't bug out when
+ running from a buffer that's not visiting a file (bug#22906).
+
+2020-09-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use a square root character in calc displays
+
+ * lisp/calc/calccomp.el (math-compose-sqrt): Use a square root
+ character, if possible (bug#22919). Suggested by Zephyr Pellerin
+ <zephyr.pellerin@gmail.com>.
+
+2020-09-15 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid aborts in display_mode_element
+
+ * src/xdisp.c (display_mode_element): Use parse_str_as_multibyte,
+ not multibyte_chars_in_text, to determine whether mode-line spec
+ shall be displayed as a multibyte or unibyte string. We cannot
+ use multibyte_chars_in_text here because it aborts when it finds
+ raw bytes in the spec string. (Bug#43409)
+
+2020-09-15 Robert Pluim <rpluim@gmail.com>
+
+ Stop querying for fonts as soon as a match is found
+
+ Scanning through fonts can be very slow, especially with the 'x' font
+ backend, and the result is almost always not used. Stop looking for a
+ font as soon as one is found rather than scanning all the backends.
+
+ * src/font.c (font_list_entities): Stop scanning through the font
+ backends as soon as we find a match unless
+ 'query-all-font-backends is set (Bug#43177).
+ (syms_of_font): New variable 'query-all-font-backends', default
+ false.
+
+2020-09-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up previous replace-in-string commit
+
+ * lisp/subr.el (replace-in-string): Fix thinko in implementation.
+
+2020-09-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow controlling the look of the line/column indicators
+
+ * doc/lispref/modes.texi (Mode Line Variables): Document them.
+
+ * lisp/bindings.el (mode-line-position-line-format): New variable
+ (bug#28648).
+ (mode-line-position-column-format): Ditto.
+ (mode-line-position): Use them.
+
+ * lisp/simple.el (column-number-mode): Mention them.
+ (line-number-mode): Ditto.
+
+2020-09-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new, simple `replace-in-string' function
+
+ * lisp/subr.el (replace-in-string): New, side-effect-free function.
+
+ * doc/lispref/searching.texi (Search and Replace): Document it.
+
+2020-09-15 Stefan Kangas <stefankangas@gmail.com>
+
+ * lisp/window.el: Add provide statement
+
+ * lisp/window.el (window): Put a `provide' form to help with the
+ popular `use-package' external package (bug#37053).
+
+2020-09-15 Eli Zaretskii <eliz@gnu.org>
+
+ Fix MS-Windows compilation of Gnulib with old versions of MinGW
+
+ * nt/inc/ms-w32.h (_WIN32_WINNT_WIN2K, _WIN32_WINNT_WINXP)
+ (_WIN32_WINNT_WS03, _WIN32_WINNT_VISTA, _WIN32_WINNT_WIN7,
+ _WIN32_WINNT_WIN8, _WIN32_WINNT_WINBLUE, _WIN32_WINNT_WIN10)
+ [__MINGW32__]: Define if any of these is not defined. Reported by
+ martin rudalics <rudalics@gmx.at>.
+
+2020-09-15 Jimmy Aguilar Mena <spacibba@aol.com>
+
+ Merge branch 'feature/uniquify-as-function' into master
+
+ Document use of uniquify-buffer-name-style as a function.
+
+2020-09-15 Jimmy Aguilar Mena <spacibba@aol.com>
+
+ Enable uniquify-buffer-name-style to be a function.
+
+ * lisp/uniquify.el (uniquify-buffer-name-style) : Add "Other" custom
+ option
+ (uniquify-get-proposed-name) : Add condition for when
+ uniquify-buffer-name-style is a function.
+
+2020-09-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix mailclient-send-it after recent browse-url rewrite
+
+ * lisp/mail/mailclient.el (mailclient-send-it): Make this function
+ work again after the browse-url machinery was changed to use
+ browse-url-default-handlers instead.
+
+2020-09-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix regression in non-querying about mail addresses in "emacs -Q"
+
+ * lisp/mail/emacsbug.el (report-emacs-bug-hook): Don't query about
+ the mail address if using an external mailer (bug#43386).
+
+2020-09-15 Daniel Martín <mardani29@yahoo.es>
+
+ Check that the buffer in diff-buffer-with-file is visiting a file
+
+ * lisp/vc/diff.el (diff-buffer-with-file): Signal a specific error
+ when the buffer passed to diff-buffer-with-file is not visiting a
+ file (bug#43401).
+
+2020-09-15 Andrea Corallo <akrl@sdf.org>
+
+ Better error handling after calling 'gcc_jit_context_compile_to_file'
+
+ Typically errors are catched in 'compile_function' but in case
+ libgccjit throw an error only afterwards while compiling the whole
+ compilation unit we have to report it correctly.
+
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Catch libgccjit
+ errors after calling 'gcc_jit_context_compile_to_file'.
+
+2020-09-14 Andrea Corallo <akrl@sdf.org>
+
+ * test/src/comp-tests.el (comp-tests-bootstrap): Print compilation time.
+
+2020-09-14 Andrea Corallo <akrl@sdf.org>
+
+ Fix free function compilation load process.
+
+ * lisp/emacs-lisp/comp.el (comp-clean-up-stale-eln): Do not crash
+ if the eln filename is not canonical (tmp file or manual load).
+
+2020-09-14 Andrea Corallo <akrl@sdf.org>
+
+ Add gv-setters for compiler hints
+
+ * lisp/emacs-lisp/comp.el (comp-hint-fixnum, comp-hint-cons): Add
+ gv-setters so type hinted expressions can be used as places.
+ Read we can now have like: '(cl-incf (cl-the fixnum x))'.
+
+2020-09-14 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-sp): Better style gv-setter declaration.
+
+2020-09-14 Andrea Corallo <akrl@sdf.org>
+
+ Remove type check emission from type hints low level primitives
+
+ These have to be emitted by higher level primitives as `cl-the'.
+
+ * lisp/emacs-lisp/comp.el (comp-hint-fixnum, comp-hint-cons): Do
+ not emit type checks.
+
+2020-09-14 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/cl-macs.el: Define fixnum and bignum.
+
+ Define fixnum so `cl-typep' recognize it and the type check emitted by
+ `cl-the' is effective.
+
+2020-09-14 Andrea Corallo <akrl@sdf.org>
+
+ Add 'cl-optimize' as function declaration
+
+ * lisp/emacs-lisp/cl-macs.el: Register cl-optimize into
+ `defun-declarations-alist' and `macro-declarations-alist'.
+ (cl--optimize): New function to serve 'cl-optimize' declaration.
+
+2020-09-14 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/cl-macs.el (cl-the): Emit compiler hints when native.
+
+2020-09-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * test/lisp/emacs-lisp/find-func-tests.el: New file (for bug#43393)
+
+ * lisp/emacs-lisp/ert-x.el (ert-simulate-keys): New macro.
+
+ * test/lisp/international/mule-tests.el
+ (mule-cmds--test-universal-coding-system-argument): Use it and enable
+ the test also in batch mode.
+
+2020-09-14 Kevin Ryde <user42@zip.com.au>
+
+ Tweak the `C-x v =' command when done from a diff buffer
+
+ * lisp/vc/vc.el (vc-diff): Offer to save the relevant buffer(s)
+ when doing `C-x v =' from a diff buffer (bug#5773).
+
+2020-09-14 Pip Cet <pipcet@gmail.com>
+
+ Don't retry reading after receiving EINVAL
+
+ * src/process.c (wait_reading_process_output): Don't retry reading
+ from an fd after an unknown error (bug#6074).
+
+2020-09-14 Stephen Berman <stephen.berman@gmx.net>
+
+ Fix problem of marking files with hidden subdirs
+
+ * lisp/dired.el (dired-unhide-subdir):
+ (dired-subdir-hidden-p):
+ (dired-subdir-min): Moved from subr-x.
+ (dired-get-filename): Get the correct filename when directories
+ are hidden (bug#8484).
+
+2020-09-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow preserving (some) text properties from completion tables
+
+ * doc/lispref/minibuf.texi (Text from Minibuffer): Document it.
+
+ * lisp/minibuffer.el (completion--replace): Preserve text
+ properties on completed items (bug#43218).
+
+2020-09-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow hitting RET on info node names with multiple whitespace chars
+
+ * lisp/info.el (info--node-canonicalize-whitespace): New function
+ (bug#10784).
+ (Info-extract-menu-node-name): Use it.
+ (Info-find-node): Use it.
+
+2020-09-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Fix completion in `read-library-name'"
+
+ This reverts commit ed44217d3245ddc8f2cf75c9499d5bb37848cfd7.
+
+ This commit broke the use case of `M-x load-library RET o/or TAB' to
+ expand to org/org.
+
+2020-09-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further fixups in minibuffer-default--in-prompt-regexps
+
+ * lisp/minibuf-eldef.el (minibuffer-default--in-prompt-regexps):
+ Really allow shortening the default prompt format to [foo] (if
+ requested) (bug#12443).
+
+2020-09-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Support build of Emacs on ARM Macos machines
+
+ * configure.ac: Add support for aarch64-* on Macos (i.e., 64-bit
+ ARM) (bug#43369).
+
+2020-09-14 Mattias Engdegård <mattiase@acm.org>
+
+ Calc: fix binomial coefficients for negative arguments (bug#16999)
+
+ For some values outside integers 0≤k≤n, (n choose k) gave wrong
+ results, entered infinite recursion or used unreasonably amounts of
+ stack space. This change fixes that and extends the function to all
+ integer arguments using the definitions from M. J. Kronenburg
+ (https://arxiv.org/abs/1105.3689).
+
+ * lisp/calc/calc-comb.el (calcFunc-choose):
+ Fix sign error to prevent infinite recursion and extend function to
+ handle all integer arguments.
+ (math-choose-iter, math-choose-float-iter): Rewrite in iterative form;
+ no TCO in elisp yet.
+ * test/lisp/calc/calc-tests.el (calc-tests--fac, calc-tests--choose)
+ (calc-tests--check-choose, calc-tests--explain-choose)
+ (calc-tests--calc-to-number): New helper functions.
+ (calc-choose): New test.
+
+2020-09-14 Mattias Engdegård <mattiase@acm.org>
+
+ * lisp/simple.el (undo-redo): Rephrase error message.
+
+2020-09-14 Glenn Morris <rgm@gnu.org>
+
+ Fix builds without modules
+
+ * src/data.c (Finteractive_form):
+ * src/eval.c (Fcommandp): Fix builds without modules.
+
+2020-09-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up report-emacs-bug action on invalid From headers
+
+ * lisp/mail/emacsbug.el (report-emacs-bug-hook): Move point to the
+ From header if the user has to edit the From header.
+
+2020-09-14 akater <nuclearspace@gmail.com> (tiny change)
+
+ Fix compilation-mode-map doc string
+
+ * lisp/progmodes/compile.el (compilation-mode-map): Remove mention of
+ compilation-minor-mode-map (bug#43382).
+
+ As the comment in the body says:
+
+ ;; Don't inherit from compilation-minor-mode-map,
+ ;; because that introduces a menu bar item we don't want.
+ ;; That confuses C-down-mouse-3.
+
+ and the map actually inherits from special-mode-map.
+
+2020-09-13 Philipp Stephani <phst@google.com>
+
+ Add facility to make module functions interactive (Bug#23486).
+
+ * src/module-env-28.h: Add field for 'make_interactive' function.
+
+ * src/emacs-module.c (Lisp_Module_Function): Add new field holding the
+ interactive form.
+ (allocate_module_function): Adapt to structure layout change.
+ (module_make_interactive, module_function_interactive_form): New
+ functions.
+ (initialize_environment): Use them.
+
+ * src/eval.c (Fcommandp):
+ * src/data.c (Finteractive_form): Also handle interactive module
+ functions.
+
+ * test/data/emacs-module/mod-test.c (Fmod_test_identity): New test
+ function.
+ (emacs_module_init): Create two interactive module test functions.
+
+ * test/src/emacs-module-tests.el (module/interactive/return-t)
+ (module/interactive/return-t-int, module/interactive/identity):
+ New unit tests.
+
+ * doc/lispref/internals.texi (Module Functions): Document new
+ function. Rework paragraph about wrapping module functions, as the
+ example no longer applies.
+
+ * etc/NEWS: Document new facility.
+
+2020-09-13 Reuben Thomas <rrt@sc3d.org>
+
+ Escape ampersand in table.el LaTeX output
+
+ * lisp/textmodes/table.el (table--generate-source-scan-lines): Add
+ ampersand '&' to the list of characters to escape in LaTeX output.
+
+2020-09-13 Andrea Corallo <akrl@sdf.org>
+
+ Fix defsbust declare effectiveness introduced by 80d7f710 (Bug#43280).
+
+ * lisp/emacs-lisp/byte-run.el (defsubst): Do not add a speed
+ declaration as this breaks a pre existing ones if present but
+ rather calls directly `byte-run--set-speed'.
+
+2020-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further fixups of the variable-pitch eww header line change
+
+ * lisp/net/eww.el (eww-update-header-line-format): Protect against
+ :url not being set.
+
+2020-09-13 Stefan Kangas <stefan@marxist.se>
+
+ Improve wording of cua-mode menu entry
+
+ * lisp/menu-bar.el (menu-bar-options-menu): Improve wording of the
+ cua-mode menu entry. (Bug#43323)
+
+2020-09-13 Stefan Kangas <stefan@marxist.se>
+
+ Improve frame-title-format and icon-title-format
+
+ * src/xdisp.c (syms_of_xdisp): Replace 'invocation-name' with the text
+ "%b - GNU Emacs" and replace "@" with " at ". (Bug#41147)
+ * etc/NEWS: Announce the above change.
+
+2020-09-13 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-09-13 Eli Zaretskii <eliz@gnu.org>
+
+ Fix punctuation in EWW manual
+
+ * doc/misc/eww.texi (Advanced): Fix punctuation of a recent
+ change.
+
+2020-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make diff--refine-hunk bug out less on broken patches
+
+ * lisp/vc/diff-mode.el (diff--refine-hunk): Don't bug out on
+ broken patches where we can't find the middle.
+
+2020-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the eww header work again even if the title is nil
+
+ * lisp/net/eww.el (eww-update-header-line-format): Don't bug out
+ if the title isn't set at all.
+
+2020-09-13 Dario Gjorgjevski <dario.gjorgjevski@gmail.com>
+
+ Make ERC desktop notifications lenient to invalid XML characters
+
+ * lisp/xml.el (xml-invalid-characters-re): New constant.
+
+ * lisp/erc/erc-desktop-notifications.el
+ (erc-notifications-notify): Strip IRC control codes and invalid
+ XML characters before notifying (bug#43328).
+
+2020-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't eagerly store articles in the Agent by default
+
+ * lisp/gnus/gnus-agent.el (gnus-agent-store-article): Made
+ obsolete.
+
+ * lisp/gnus/gnus-art.el (gnus-request-article-this-buffer): Don't
+ call it.
+
+ * lisp/gnus/gnus-async.el (gnus-async-article-callback): Ditto
+ (bug#43356).
+
+ This partially reverts f3b146e943cd733fb716c75048f24b73826e5f30, which
+ in was response to what appears to be an erroneous feature-request -
+ bug#8502.
+
+ Instead this should be done instead:
+
+ “If I read an article while plugged, do they get entered into the
+ Agent?”
+
+ *No*. If you want this behavior, add
+ ‘gnus-agent-fetch-selected-article’ to
+ ‘gnus-select-article-hook’.
+
+2020-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Kill gpg-agents started by mml-sec-tests (bug#43358)
+
+2020-09-13 Brian Leung <leungbk@mailfence.com> (tiny change)
+
+ Update .gitignore with ccls files
+
+ * .gitignore: Ignore files used by ccls, a language server for C
+ (bug#43365).
+
+2020-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Doc string clarification in file-directory-p
+
+ * src/fileio.c (Ffile_directory_p): Mention that "" is a special
+ case (bug#43375).
+
+2020-09-13 Kiso Katsuyuki <katsuyuki2388@gmail.com> (tiny change)
+
+ Clarify when tab-line-switch-cycling is used
+
+ * lisp/tab-line.el (tab-line-switch-cycling): Clarify when the
+ variable is used.
+
+2020-09-13 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/time.el (display-time-world): Make obsolete.
+
+2020-09-13 Stefan Kangas <stefan@marxist.se>
+
+ Make M-x show what aliases point to (Bug#43300)
+
+ * lisp/simple.el (read-extended-command--annotation): Show an
+ annotation for aliases saying what it points to.
+
+2020-09-13 Stefan Kangas <stefan@marxist.se>
+
+ Make M-x show obsolete commands (Bug#43300)
+
+ * lisp/simple.el (read-extended-command): Don't hide obsolete
+ commands.
+ (read-extended-command--annotation): Show an annotation for obsolete
+ commands that says what their new name is.
+
+2020-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Use format-prompt in read-file-name calls that have a default"
+
+ This reverts commit de4f347901adffd07bc9bff028dc073fb3c6df33.
+
+ read-file-name already displays a long path when given a default
+ (like INITIAL in many other prompting functions), so using
+ format-prompt here is superfluous.
+
+2020-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `ascii' a coding system alias for `us-ascii'
+
+ * lisp/international/mule-conf.el (ascii): Define `ascii' as a
+ coding system alias to `us-ascii' (bug#43351).
+
+2020-09-13 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix a conversion failure in tramp-archive-tests (Bug#43353)
+
+ * test/lisp/net/tramp-archive-tests.el
+ (tramp-archive-test-file-archive-hexlified): New defun.
+ (tramp-archive-test02-file-name-dissect): Use it. (Bug#43353)
+
+2020-09-13 Glenn Morris <rgm@gnu.org>
+
+ Don't force LC_ALL=C upon make check (bug#43353)
+
+ * test/Makefile.in (TEST_LOCALE): Remove.
+ (emacs): Don't force LC_ALL=C, since it causes problems with
+ non-ascii directories. This mirrors a 7-year old lisp/Makefile change.
+
+2020-09-13 Glenn Morris <rgm@gnu.org>
+
+ Mark some diff tests as failing in nonascii directories
+
+ * test/lisp/vc/diff-mode-tests.el (diff-mode-test-font-lock)
+ (diff-mode-test-font-lock-syntax-one-line):
+ Expect failure in non-ascii directories.
+
+2020-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clean up eww error buffer
+
+ * lisp/net/eww.el (eww-retrieve): Clean up error buffer after exiting.
+
+2020-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up example code from previous eww.texi commit
+
+ * doc/misc/eww.texi (Advanced): Simplify example command (and
+ "--virtual-time-budget=3000" makes Chromium unstable).
+
+2020-09-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a way to use an external command to download HTML in eww
+
+ * doc/misc/eww.texi (Advanced): Document it.
+
+ * lisp/net/eww.el (eww-retrieve): New function.
+ (eww-reload): Use it.
+ (eww): Ditto.
+ (eww-retrieve-command): New variable.
+
+2020-09-12 Glenn Morris <rgm@gnu.org>
+
+ Adapt some tests for Emacs's excitingly variable quoting format
+
+ * test/lisp/subr-tests.el (subr-test-version-parsing):
+ * test/lisp/emacs-lisp/gv-tests.el (gv-dont-define-expander-other-file):
+ * test/src/callint-tests.el (call-interactively/incomplete-multibyte-sequence):
+ * test/src/emacs-module-tests.el (module/describe-function-1):
+ Don't fail if curly quotes are in use, as they can be if LC_ALL != C.
+
+2020-09-12 Michael Albinus <michael.albinus@gmx.de>
+
+ Cleanup in dbus.el, dbus-tests.el
+
+ * lisp/net/dbus.el (dbus-error-no-reply): New defconst.
+ (dbus-call-method): Use it.
+ (dbus-call-method-asynchronously, dbus-register-signal): Fix docstring.
+ (dbus-unregister-object): Obey :serial entries in
+ `dbus-registered-objects-table'.
+
+ * test/lisp/net/dbus-tests.el (dbus-test04-register-method)
+ (dbus-test05-register-property): Extend tests.
+
+2020-09-12 Glenn Morris <rgm@gnu.org>
+
+ Make vc-bzr tests work with brz 3.1 (bug#43314)
+
+ * test/lisp/vc/vc-bzr-tests.el (vc-bzr-test-bug9726)
+ (vc-bzr-test-bug9781, vc-bzr-test-faulty-bzr-autoloads):
+ Make them work with brz 3.1.
+
+2020-09-12 Alan Mackenzie <acm@muc.de>
+
+ C++ Mode: handle __attribute__,etc. inside constructor argument lists
+
+ This corrects both the fontification and indentation of these things, fixing
+ bug #42270.
+
+ * lisp/progmodes/cc-engine.el (c-do-declarators): Skip over "hangon keys" and
+ noise macros whilst scanning a putative C++ function.
+ (c-forward-decl-or-cast-1): When checking for typeless functions, skip over
+ "hangon keys" and noise macros.
+
+ * lisp/progmodes/cc-mode.el (c-fl-decl-end): Deal with certain invalid
+ "nested declarators" by scanning over them with a recursive call of
+ c-fl-decl-end.
+
+ * lisp/progmodes/cc-vars.el (c-noise-macro-names)
+ (c-noise-macro-with-parens-names): State in the doc strings that if either of
+ these is a regexp, it must have a submatch 1 which matches the noise macro
+ exactly.
+
+2020-09-12 Glenn Morris <rgm@gnu.org>
+
+ Small Texinfo markup fixes
+
+ * doc/misc/dbus.texi (Register Objects):
+ * doc/misc/gnus.texi (Searching): Texinfo markup fixes.
+
+2020-09-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix compilation warning in cl-font-lock
+
+ * lisp/progmodes/cl-font-lock.el (cl-font-lock-built-in-mode): Put
+ in the tools group to avoid a compilation warning.
+
+2020-09-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix compilation warning in obsolete/complete.el
+
+ * lisp/obsolete/complete.el (completion-base-size): Avoid
+ compilation warning.
+
+2020-09-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix compilation warning in cl-lib.el
+
+ * lisp/emacs-lisp/cl-lib.el (cl-old-struct-compat-mode): Put the
+ minor mode in the tools group (to avoid a compilation warning).
+
+2020-09-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ dired-omit-mode may not be defined in dired-jump
+
+ * lisp/dired.el (dired-jump): dired-omit-mode is in dired-x, so it
+ may not be defined in dired.
+
+2020-09-12 Alex Bochannek <alex@bochannek.com>
+
+ Support scoring on article age interactively in Gnus
+
+ * lisp/gnus/gnus-score.el (gnus-summary-score-entry): Support
+ scoring on article age in interactive scoring (bug#43270).
+
+2020-09-12 Glenn Morris <rgm@gnu.org>
+
+ Default Emacs to UTF-8 instead of Latin-1
+
+ * doc/emacs/mule.texi (File Name Coding): Document it.
+
+ * lisp/international/mule-cmds.el (reset-language-environment):
+ Default to utf-8 instead of latin-1.
+
+ * lisp/mail/sendmail.el (default-sendmail-coding-system): Ditto.
+
+ * lisp/mh-e/mh-comp.el (mh-send-letter): Ditto.
+
+2020-09-12 Martin Rudalics <rudalics@gmx.at>
+
+ Fix toggle-frame-fullscreen on w32 builds
+
+ * src/w32term.c (w32_read_socket): Set 'fullscreen' to 'maximized'
+ if Windows sends SIZE_MAXIMIZED and either the top or the left of
+ the frame is outside the screen. (Bug#25542)
+
+2020-09-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further diff-no-select doc string clarification
+
+ * lisp/vc/diff.el (diff-no-select): Doc string clarification.
+
+2020-09-12 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid unneeded recentering when header-line is used
+
+ * src/xdisp.c (try_window): Account for header-line height only in
+ the scroll-margin at the window's top, but not at its bottom.
+ (Bug#42653)
+
+2020-09-12 Eli Zaretskii <eliz@gnu.org>
+
+ Fix compilation on TERMINFO platforms with GCC 10
+
+ * src/terminfo.c [TERMINFO]: Don't redefine UP, BC, and CP, as
+ that could cause linking errors due to multiple definitions.
+ (Bug#43195)
+
+2020-09-12 Stefan Kangas <stefan@marxist.se>
+
+ Move dired-jump from dired-x to dired (Bug#21981)
+
+ * lisp/dired-x.el (dired-bind-jump): Change into defvar and make
+ obsolete.
+ (dired-extra-startup): Doc fix.
+ (dired-jump, dired-jump-other-window): Move from here...
+ * lisp/dired.el (dired-jump, dired-jump-other-window): ...to here.
+
+ * lisp/bindings.el (ctl-x-map, ctl-x-4-map): Bind 'C-j' to
+ 'dired-jump' and 'dired-jump-other-window'.
+
+ * doc/misc/dired-x.texi (Features, Installation)
+ (Miscellaneous Commands): Remove documentation of 'dired-jump'.
+ * doc/emacs/dired.texi (Dired Enter): Document 'dired-jump' and
+ dired-jump-other-window.
+ * etc/NEWS: Announce the above changes.
+
+ * test/lisp/dired-tests.el (dired-autoload): Adjust test.
+
+2020-09-11 Stefan Kangas <stefan@marxist.se>
+
+ Add some eshell completion patterns
+
+ * lisp/eshell/em-cmpl.el (eshell-command-completions-alist):
+ Add 'gunzip', 'bunzip2' and 'unxz'.
+
+2020-09-11 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove cedet items obsolete since 23.2
+
+ * lisp/cedet/semantic.el (semantic-toplevel-bovine-table)
+ (semantic-toplevel-bovine-cache)
+ (semantic-before-toplevel-bovination-hook)
+ (semantic-after-toplevel-bovinate-hook, semantic-init-hooks)
+ (semantic-init-mode-hooks, semantic-init-db-hooks)
+ (semantic-bovination-working-type, semantic-bovinate-toplevel)
+ (semantic-bovinate-region-until-error)
+ (semantic-bovinate-from-nonterminal-full):
+ * lisp/cedet/semantic/db-mode.el (semanticdb-mode-hooks):
+ * lisp/cedet/semantic/decorate/mode.el
+ (semantic-decorate-pending-decoration-hooks):
+ * lisp/cedet/semantic/edit.el
+ (semantic-edits-incremental-reparse-failed-hooks):
+ * lisp/cedet/semantic/fw.el (define-mode-overload-implementation):
+ * lisp/cedet/semantic/idle.el
+ (semantic-before-idle-scheduler-reparse-hooks)
+ (semantic-after-idle-scheduler-reparse-hooks):
+ (semantic-eldoc-current-symbol-info)
+ * lisp/cedet/semantic/imenu.el (semantic-imenu-expand-type-parts)
+ (semantic-imenu-bucketize-type-parts)
+ (semantic-imenu-expandable-token):
+ * lisp/cedet/semantic/java.el
+ (semantic-java-prototype-nonterminal):
+ * lisp/cedet/semantic/lex.el (semantic-flex-token-start)
+ (semantic-flex-token-end, semantic-flex-token-text)
+ (semantic-flex-make-keyword-table, semantic-flex-keyword-p)
+ (semantic-flex-keyword-put, semantic-flex-keyword-get)
+ (semantic-flex-map-keywords, semantic-flex-keywords)
+ (semantic-flex-buffer, semantic-flex-list, semantic-flex):
+ * lisp/cedet/semantic/tag-file.el (semantic-find-nonterminal)
+ (semantic-find-dependency):
+ * lisp/cedet/semantic/tag-ls.el (semantic-nonterminal-full-name)
+ (semantic-nonterminal-protection, semantic-nonterminal-abstract)
+ (semantic-nonterminal-leaf):
+ * lisp/cedet/semantic/tag.el (semantic-token-type-parent)
+ (semantic-tag-make-assoc-list, semantic-expand-nonterminal):
+ * lisp/cedet/semantic/util.el (semantic-file-token-stream)
+ (semantic-something-to-stream):
+ * lisp/cedet/semantic/wisent.el (wisent-lex-make-token-table):
+ Delete many items obsolete since Emacs 23.2.
+ * lisp/cedet/semantic.el (semantic--set-buffer-cache)
+ (semantic-fetch-tags): Don't run removed hooks
+ 'semantic-after-toplevel-bovinate-hook' and
+ 'semantic-before-toplevel-bovination-hook'.
+ * lisp/cedet/semantic/bovine/el.el: Remove reference to obsolete
+ variable 'define-mode-overload-implementation'.
+ * lisp/cedet/semantic/doc.el (semantic-doc-snarf-comment-for-tag):
+ Don't bind removed variable 'semantic-ignore-comments'.
+ * lisp/cedet/semantic/fw.el (semantic-overload-symbol-from-function)
+ (semantic-alias-obsolete, semantic-varalias-obsolete): Declare
+ obsolete in favor of standard Emacs 'define-obsolete-*-alias'.
+ * lisp/cedet/semantic/grammar.el (semantic-grammar-ASSOC): Don't
+ use obsolete names.
+ * lisp/cedet/semantic/tag-ls.el (semantic-tag-full-package)
+ (semantic-tag-full-name): Doc fixes.
+ * lisp/cedet/semantic/util.el (semantic-describe-buffer): Don't bind
+ removed variable 'semantic-after-toplevel-bovinate-hook'.
+ * lisp/cedet/semantic/lex.el (semantic-flex-tokens)
+ (semantic-flex-unterminated-syntax-end-function)
+ (semantic-flex-extensions, semantic-flex-syntax-modifications)
+ (semantic-ignore-comments, semantic-flex-enable-newlines)
+ (semantic-flex-enable-whitespace, semantic-flex-enable-bol)
+ (semantic-number-expression, semantic-flex-depth): Make unused
+ variables obsolete.
+
+2020-09-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Guard against faulty flow-filled emails
+
+ * lisp/mail/flow-fill.el (fill-flowed): Don't bug out if there's a
+ space at the end of the buffer. This is probably not allowed in
+ the flow-fill specification, but has been observed in the wild.
+
+2020-09-11 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Fix minor bugs in the string handling functions
+
+ These sometimes gave rise to the tail of a buffer being "stringed out".
+
+ * lisp/progmodes/cc-defs.el (c-will-be-unescaped): New macro.
+
+ * lisp/progmodes/cc-mode.el (c-before-change-check-unbalanced-strings)
+ (c-after-change-mark-abnormal-strings): Fix bugs in the handling of string
+ fence syntax-table text properties.
+
+2020-09-11 Eli Zaretskii <eliz@gnu.org>
+
+ Improve help-echo of Undo and Redo menu items
+
+ * lisp/menu-bar.el (undo-redo, undo): Improve the wording of
+ help-echo strings.
+
+2020-09-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak previous mailcap patch (for external viewers)
+
+ * lisp/net/mailcap.el (mailcap-view-mime): Delete contents of the
+ buffer in the external case, too.
+
+2020-09-11 Michael Albinus <michael.albinus@gmx.de>
+
+ D-Bus: Implement other compound types of properties
+
+ * doc/misc/dbus.texi (Errors and Events):
+ * etc/NEWS: Mention dbus-show-dbus-errors.
+
+ * lisp/net/dbus.el (dbus-compound-types): New defconst.
+ (dbus): New defgroup.
+ (dbus-show-dbus-errors): New defcustom.
+ (dbus-ignore-errors): Use it.
+ (dbus-set-property): Simplify.
+ (dbus-property-handler): Implement other compound types of properties.
+
+ * test/lisp/net/dbus-tests.el (dbus--test-register-service)
+ (dbus-test05-register-property): Extend tests.
+
+2020-09-11 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (emit_static_object): Make use of ARRAYELTS.
+
+2020-09-11 Andrea Corallo <akrl@sdf.org>
+
+ Make use of new 'gcc_jit_global_set_initializer' entry point
+
+ Use this brand new entry point to avoid the current workaround and its
+ load-time memcpys.
+
+ * src/comp.c (gcc_jit_global_set_initializer): Add to the dynamic
+ load machinery.
+ (static_obj_t): Remove const qualifier from the data field.
+ (emit_static_object): Make use of 'gcc_jit_global_set_initializer'
+ when available.
+ (load_static_obj): Use the blob for loading if that was emitted.
+
+2020-09-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up eldef shortening of the minibuffer
+
+ * lisp/minibuf-eldef.el (minibuffer-default--in-prompt-regexps):
+ Don't include the ": " bit in the portion to be replaced
+ (bug#12443).
+
+2020-09-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Improve diff-no-select doc string
+
+ * lisp/vc/diff.el (diff-no-select): Improve the doc string somewhat.
+
+2020-09-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix viewing PDFs from eww with external viewers
+
+ * lisp/net/mailcap.el (mailcap-view-mime): Most MIME viewers can't
+ take input on stdin (and in any case, "-" is not how many of them
+ designate stdin) (bug#43318). So rewrite to put the data on a
+ file and feed the file name to the viewer.
+
+2020-09-11 Mattias Engdegård <mattiase@acm.org>
+
+ Calc: regularise test names
+
+ * test/lisp/calc/calc-tests.el (calc-remove-units, calc-extract-units)
+ (calc-convert-units, calc-bug-23889, calc-trig, calc-format-radix)
+ (calc-calendar, calc-solve-linear-system):
+ Use a uniform naming convention (calc- prefix) to simplify test running.
+
+2020-09-11 Mattias Engdegård <mattiase@acm.org>
+
+ Simplify big integer constants in Calc
+
+ * lisp/calc/calc-comb.el (math-small-factorial-table):
+ * lisp/calc/calc-funcs.el (math-bernoulli-b-cache):
+ * lisp/calc/calc.el (math-2-word-size, math-half-2-word-size):
+ No need for math-read-number-simple.
+
+2020-09-11 Mattias Engdegård <mattiase@acm.org>
+
+ Fix calc tests when running noninteractively
+
+ This error was introduced in 8e1376a39125c3ffc0484077b502444d853eca79.
+
+ * lisp/calc/calc.el (calc--header-line): Prevent size from being negative.
+
+2020-09-11 Andrea Corallo <akrl@sdf.org>
+
+ Update gitlab CI yml file
+
+ * .gitlab-ci.yml (test-native-bootstrap-speed0)
+ (test-native-bootstrap-speed1, test-native-bootstrap-speed2):
+ Update for new make invocation.
+
+2020-09-11 Andrea Corallo <akrl@sdf.org>
+
+ By default when building native compile only what's part of the dump image
+
+ To Ahead of Time compile the whole Emacs distro define NATIVE_FULL_AOT
+ when invoking make ex: 'make NATIVE_FULL_AOT=1'.
+
+ * lisp/Makefile.in (NATIVE_SKIP_NONDUMP): New variable.
+ (compile-main): Use it + rename NATIVE_DISABLE -> NATIVE_DISABLED.
+ * lisp/emacs-lisp/comp.el
+ (batch-byte-native-compile-for-bootstrap): Rename NATIVE_DISABLE
+ -> NATIVE_DISABLED.
+
+2020-09-11 Eli Zaretskii <eliz@gnu.org>
+
+ * lisp/simple.el (undo-redo): Doc fix.
+
+2020-09-11 Andrew G Cohen <cohen@andy.bu.edu>
+
+ Allow an info structure as argument for gnus-group-get-parameter
+
+ * lisp/gnus/gnus.el (gnus-group-get-parameter): Allow the group
+ argument to be either a group name or a group info structure. This is
+ then parallel to gnus-group-set-parameter.
+
+2020-09-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/loadup.el ("button"): Move to after loaddefs.el
+
+2020-09-11 Andrew G Cohen <cohen@andy.bu.edu>
+
+ Clean up group-finding in Gnus nnir search
+
+ This is part of removing code from nnir.el that isn't related to
+ searching backends and therefore belongs somewhere else.
+
+ * lisp/gnus/gnus-group.el (gnus-group-make-search-group)
+ (gnus-group-read-ephemeral-search-group): Put the logic for
+ determining the groups to search here, rather than in nnir. Improve
+ documentation.
+ * lisp/gnus/gnus-int.el (gnus-server-get-active): Renamed from
+ 'nnir-get-active.
+ * lisp/gnus/nnir.el (nnir-run-imap, nnir-run-find-grep): Use it.
+ (nnir-get-active): Remove.
+ (nnir-make-specs): Make obsolete.
+ * lisp/gnus/nnselect.el (nnselect-group-server): Make obsolete in
+ favor of 'gnus-group-server.
+
+2020-09-11 Andrew G Cohen <cohen@andy.bu.edu>
+
+ Allow editing articles in Gnus nnselect groups
+
+ * lisp/gnus/nnselect.el (nnselect-request-replace-article): New function.
+
+2020-09-11 Elad Lahav <elahav@qnx.com> (tiny change)
+
+ Fix QNX build
+
+ * configure.ac: The __NO_EXT_QNX flag is no longer needed, and is
+ masking the declaration of memset_s() (bug#43234).
+
+2020-09-10 Boruch Baum <boruch_baum@gmx.com>
+
+ Use a header line in calc mode instead of a regular in-buffer line
+
+ * lisp/calc/calc.el (calc-trail-here): Use a header line.
+ (calc--header-line): New function.
+ (calc-trail-mode): Use a header line.
+
+2020-09-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak how `M-RET' in Message mode fills paragraphs
+
+ * lisp/gnus/message.el (message-newline-and-reformat): Pick up any
+ longer white-space prefix before starting to fill (bug#43299).
+ This fixes the problem of hitting M-RET on a line that's just ">".
+
+2020-09-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Doc fix for diff-no-select
+
+ * lisp/vc/diff.el (diff-no-select): Document the BUF argument
+ (bug#43307).
+
+2020-09-10 Caio Henrique <caiohcs0@gmail.com> (tiny change)
+
+ Add a "Redo" entry to the menu
+
+ * lisp/menu-bar.el (menu-bar-edit-menu): Add "Redo" under "Undo"
+ in the Edit menu (bug#43315).
+
+2020-09-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix the font-lock-debug-fontify NEWS entry
+
+ * etc/NEWS: Fix the name of `font-lock-debug-fontify' (bug#43319).
+
+2020-09-10 Stefan Kangas <stefan@marxist.se>
+
+ * lisp/textmodes/artist.el: Remove obsolete comments.
+
+2020-09-10 Stefan Kangas <stefan@marxist.se>
+
+ Convert indent test for css-mode into automatic test
+
+ * test/lisp/textmodes/css-mode-tests.el (css-mode-test-indent): New
+ test.
+ (css-mode-tests-data-dir): New variable.
+ * test/manual/indent/css-mode.css: Move from here...
+ * test/lisp/textmodes/css-mode-resources/test-indent.css: ...to here.
+
+2020-09-10 Stefan Kangas <stefan@marxist.se>
+
+ Mark some tests as expensive
+
+ * test/lisp/autorevert-tests.el
+ (auto-revert-test00-auto-revert-mode)
+ (auto-revert-test03-auto-revert-tail-mode)
+ (auto-revert-test04-auto-revert-mode-dired):
+ * test/lisp/cedet/semantic-utest-c.el
+ (semantic-test-c-preprocessor-simulation):
+ * test/lisp/cedet/srecode-utest-getset.el
+ (srecode-utest-getset-output):
+ * test/lisp/emacs-lisp/cl-seq-tests.el (cl-seq-test-bug24264):
+ * test/lisp/emacs-lisp/package-tests.el
+ (package-test-update-archives-async):
+ * test/lisp/filenotify-tests.el (file-notify-test03-events)
+ (file-notify-test04-autorevert)
+ (file-notify-test05-file-validity, file-notify-test08-backup):
+ * test/lisp/net/gnutls-tests.el (test-gnutls-005-aead-ciphers):
+ * test/lisp/shadowfile-tests.el (shadow-test00-clusters)
+ (shadow-test09-shadow-copy-files):
+
+2020-09-10 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in mml-sec-tests.el
+
+ * test/lisp/gnus/mml-sec-tests.el: Use lexical-binding.
+ (mml-secure-test-mail-fixture)
+ (mml-secure-test-en-decrypt-with-passphrase): Fix warnings.
+
+2020-09-10 Stefan Kangas <stefan@marxist.se>
+
+ * test/lisp/org/org-tests.el: Use lexical-binding.
+
+2020-09-10 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in url-future-tests.el
+
+ * test/lisp/url/url-future-tests.el: Use lexical-binding.
+ (url-future-tests--saver): New variable.
+ (url-future-tests): Use new variable.
+
+2020-09-10 Stefan Kangas <stefan@marxist.se>
+
+ Use lexical-binding in semantic-utest-c.el
+
+ * test/lisp/cedet/semantic-utest-c.el: Use lexical-binding.
+ (semantic-test-gcc-output-parser): Fix warning.
+
+2020-09-10 Michael Albinus <michael.albinus@gmx.de>
+
+ Implement D-Bus properties with compound type.
+
+ * lisp/net/dbus.el (dbus-set-property): Fix thinko.
+ (dbus-register-property, dbus-property-handler): Support compound
+ properties.
+
+ * src/dbusbind.c (dbus-registered-objects-table): Fix docstring.
+
+ * test/lisp/net/dbus-tests.el (dbus--test-interface): Make it
+ different to `dbus--test-service'.
+ (dbus-test05-register-property)
+ (dbus-test05-register-property-several-paths): Adapt tests.
+
+2020-09-10 Nick Savage <nick@nicksavage.ca> (tiny change)
+
+ Open describe-function NEWS links in view-mode
+
+ * lisp/help-mode.el (help-news): Open describe-function NEWS links in
+ view-mode (Bug#39912)
+
+2020-09-10 Alex Bochannek <alex@bochannek.com> (tiny change)
+
+ Fix up < and > "date" scoring rules in Gnus
+
+ * lisp/gnus/gnus-score.el (gnus-score-date): The previous < and >
+ "date" scoring rules (added in the previous patch) had reversed
+ logic (bug#43270).
+
+2020-09-10 Mauro Aranda <maurooaranda@gmail.com>
+
+ Fix :match function for the file widget
+
+ * lisp/wid-edit.el (file widget): Return nil if value is not a
+ string (bug#25678).
+
+2020-09-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert back to using ESC as viper-ESC-key again
+
+ * lisp/emulation/viper-keym.el (viper-ESC-key): Revert back to
+ using ESC instead of `escape' (bug#18182). This allows using
+ `C-[' again on terminals for ESC. The key should be mapped back
+ to `escape' by `function-key-map'.
+
+2020-09-10 Andrew G Cohen <cohen@andy.bu.edu>
+
+ Fix new summary-line after editing an article in Gnus
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-edit-article-done): Strip ^M
+ from the ends of lines after saving an edited article. Otherwise the
+ new header isn't always parsed properly, resulting in an incorrect
+ subject line in the summary buffer.
+
+2020-09-10 Andrea Corallo <akrl@sdf.org>
+
+ Guard against trying to rename files into eln sys directory
+
+ * src/comp.c (file_in_eln_sys_dir): New function.
+ (Fnative_elisp_load): Make use of.
+
+2020-09-10 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-09-10 Andrea Corallo <akrl@sdf.org>
+
+ Fix rename file error when reloading the same file from an sys eln dir.
+
+ * src/comp.c (Fnative_elisp_load): Don't rename files we don't
+ have the permission for.
+
+2020-09-10 Andrea Corallo <akrl@sdf.org>
+
+ Revert "* src/comp.c (Fcomp__compile_ctxt_to_file): Don't cleanup caches at bootstrap."
+
+ This reverts commit 15acd27d1c0de8b56bab61daa0a8fcd4fef0fdc4.
+
+2020-09-10 Amin Bandali <bandali@gnu.org>
+
+ Set `generated-autoload-file' in erc-status-sidebar.el
+
+ * lisp/erc/erc-status-sidebar.el: Set `generated-autoload-file' to
+ ERC's dedicated "erc-loaddefs.el", since we don't need this file's
+ autoloaded functions to be available before ERC itself is loaded.
+
+2020-09-09 Kiso Katsuyuki <katsuyuki2388@gmail.com> (tiny change)
+
+ Introduce a new variable tab-line-switch-cycling
+
+ If it is set t, enable cycling tab switch. Default is nil.
+
+2020-09-09 Kiso Katsuyuki <katsuyuki2388@gmail.com> (tiny change)
+
+ Suppress errors of tab-line-switch functions
+
+ Target errors occurs when tab-line-switch-to-prev-tab or
+ tab-line-switch-to-next-tab is invoked in a buffer which is not in
+ tabs
+
+2020-09-09 João Távora <joaotavora@gmail.com>
+
+ Fix up fix for bug#19032
+
+ * lisp/icomplete.el (icomplete-ret): Call
+ minibuffer-icomplete-and-exit, not minibuffer-exit.
+
+2020-09-09 Stefan Kangas <stefan@marxist.se>
+
+ Minor clean ups and doc fixes in find-dired
+
+ * lisp/find-dired.el (find-ls-option, find-dired): Doc fixes.
+ (find-dired, kill-find): Minor clean ups.
+
+2020-09-09 Stefan Kangas <stefankangas@gmail.com>
+
+ Make flyspell-prog-text-faces into defcustom
+
+ * lisp/textmodes/flyspell.el (flyspell-prog-text-faces):
+ Make into defcustom. (Bug#32136)
+
+2020-09-09 Naoya Yamashita <conao3@gmail.com>
+
+ Add gv-define-expander for plist-get
+
+ It is necessary to make plist-get as a generalized variable, and this
+ definition allows user to use setf and other useful functions on
+ plist-get.
+
+ * lisp/emacs-lisp/gv.el: Add gv-define-expander for plist-get
+
+ * test/lisp/emacs-lisp/gv-tests.el: Add new tests for plist-get
+
+2020-09-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/dnd.el: Use lexical-binding. Remove redundant :group
+
+ (dnd--unescape-uri): Mark it internal, but don't mark it inlinable.
+
+ * lisp/cus-edit.el (dnd): Move the group to dnd.el.
+
+2020-09-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ (define-minor-mode): Don't compute a default :group (bug#41145)
+
+ * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Rely on the
+ `defcustom`s own defaulting for the :group.
+
+ * lisp/display-fill-column-indicator.el
+ (global-display-fill-column-indicator-mode): Remove now redundant :group.
+
+ * lisp/cus-dep.el (custom--get-def): New function.
+ (custom-make-dependencies): Use it.
+
+2020-09-09 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt Tramp doc
+
+ * doc/misc/tramp.texi (Remote shell setup):
+ Mention password-word-equivalents.
+
+ * lisp/net/tramp.el (tramp-password-prompt-regexp): Fix docstring.
+
+2020-09-09 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 366a97c980 (origin/emacs-27) Avoid crashes when trying to load bad GI...
+ 7938713105 C++ Mode: handle comma separated brace initializers.
+ 2b95300cf8 * lisp/display-fill-column-indicator.el: Fix bug#41145
+
+2020-09-09 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 9b35b0c99c ; * lisp/man.el (Man-mode): Fix formatting.
+ abca75d2e9 ; Fix typos; change "Emacs-Lisp" to "Emacs Lisp"
+
+2020-09-09 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 302f71e55d Fix help message with help-window-select
+ 0fb3fc92b3 Remove obsolete "Wide Characters" section of Gnus manual
+
+2020-09-09 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix thinko in dbus.el
+
+ * doc/misc/dbus.texi (Register Objects): Rename from "Receiving
+ Method Calls". Add reference to D-Bus API Design document.
+
+ * lisp/net/dbus.el (dbus-managed-objects-handler): Fix thinko.
+
+ * test/lisp/net/dbus-tests.el (dbus-test05-register-property)
+ (dbus-test05-register-property-several-paths): Extend tests.
+
+2020-09-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add the (hopefully) correct debbugs header for patches
+
+ * lisp/mail/emacsbug.el (submit-emacs-patch): Mark the submission
+ as a patch.
+
+2020-09-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Implement a new `submit-emacs-patch' command
+
+ * doc/emacs/trouble.texi (Checklist): Mention the new command.
+
+ * doc/lispref/intro.texi (Caveats): Ditto.
+
+ * lisp/mail/emacsbug.el (emacs-bug--system-description): Factor
+ out into own function.
+ (report-emacs-bug): ... from here.
+ (submit-emacs-patch): New command.
+
+2020-09-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the button navigation commands available via a minor mode
+
+ * lisp/button.el (button-mode): New minor mode.
+
+ * doc/lispref/display.texi (Button Buffer Commands): Mention it.
+
+2020-09-09 Andrew G Cohen <cohen@andy.bu.edu>
+
+ Make Gnus cache work with nnselect
+
+ * lisp/gnus/gnus-cache.el (gnus-cache-possibly-enter-article)
+ (gnus-cache-possibly-remove-articles)
+ (gnus-cache-possibly-remove-article): Use originating article info for
+ nnselect groups.
+
+2020-09-09 Andrew G Cohen <cohen@andy.bu.edu>
+
+ Add Gnus function to make a persistent group from a search result
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-make-group-from-search): New
+ command (bound to C-c C-p in summary buffers).
+ * doc/misc/gnus.texi (What is nnir?): Document it. Correct previous
+ errors.
+ * etc/NEWS (Gnus): Mention it.
+
+2020-09-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow DEFAULT in format-prompt to be a list
+
+ * doc/lispref/minibuf.texi (Text from Minibuffer): Document it.
+
+ * lisp/minibuffer.el (format-prompt): Allow DEFAULT to be a list
+ (and use the first element). This is how many of the prompting
+ functions interpret their default parameters.
+
+2020-09-08 Win Treese <treese@acm.org>
+
+ Fix crash from clicking on menu bar (bug#34762, bug#26982)
+
+ * src/nsmenu.m (ns_update_menubar): Remove extraneous use of
+ autorelease pool.
+
+2020-09-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Use format-prompt in calls to read-from-minibuffer with default value"
+
+ This reverts commit 1921d2176bb9127d2483a1c8a470abfc3f4eec33.
+
+ The DEFAULT-VALUE here isn't really a default value (since READ is nil), so
+ don't say there's a default.
+
+2020-09-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Doc string update for tramp-password-prompt-regexp
+
+ * lisp/net/tramp.el (tramp-password-prompt-regexp): Mention
+ password-word-equivalents in the doc string.
+
+2020-09-08 Daniel Martín <mardani29@yahoo.es>
+
+ Use mouse-wheel-up-event in mwheel-tests.el
+
+ Enabling mouse-wheel-mode binds two different mouse events, depending
+ on the operating system. The correct way to check for those events is
+ by checking mouse-wheel-up-event, as explained in the ELisp manual.
+
+ * test/lisp/mwheel-tests.el (mwheel-test-enable/disable): Check
+ mouse-wheel-up-event instead of mouse-4 to make the test work
+ irrespective of the platform it's running.
+
+2020-09-08 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid crashes when trying to load bad GIF files
+
+ * src/image.c (gif_load): Handle the case when GifErrorString
+ returns NULL. (Bug#43281)
+
+2020-09-08 Glenn Morris <rgm@gnu.org>
+
+ Skip failing cperl test on hydra
+
+ * test/lisp/progmodes/cperl-mode-tests.el (cperl-mode-test-bug-10483):
+ Skip on hydra.nixos.org.
+
+2020-09-08 Michael Albinus <michael.albinus@gmx.de>
+
+ * etc/NEWS: Add D-Bus changes.
+
+2020-09-08 Michael Albinus <michael.albinus@gmx.de>
+
+ Implement typed D-Bus properties (Bug#43252)
+
+ * doc/misc/dbus.texi (Properties and Annotations)
+ (Receiving Method Call): Document optional type symbol in
+ `dbus-set-property' and `dbus-register-property'.
+
+ * lisp/net/dbus.el (dbus-error-unknown-interface)
+ (dbus-error-unknown-method, dbus-error-unknown-object)
+ (dbus-error-unknown-property): New defconsts.
+ (dbus-peer-handler): Improve error handling.
+ (dbus-introspect-get-signature): Handle also properties.
+ (dbus-set-property, dbus-register-property): Allow optional TYPE
+ symbol for VALUE. (Bug#43252)
+ (dbus-property-handler): Implement property types. Improve error
+ handling.
+
+ * src/dbusbind.c (dbus-message-internal, dbus-registered-objects-table):
+ Fix docstring.
+
+ * test/lisp/net/dbus-tests.el (dbus-test05-register-property):
+ Extend test.
+ (dbus-test05-register-property-several-paths): New test.
+
+2020-09-08 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Don't cleanup caches at bootstrap.
+
+2020-09-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Explain in the tab-always-indent doc how to make TAB insert a TAB"
+
+ This reverts commit 4b2371631167e509668b6268334e324fdd2f0327.
+
+ overriding-terminal-local-map should apparently not be used for minor stuff like this.
+
+2020-09-08 Alex Bochannek <alex@bochannek.com>
+
+ Introduce a new Gnus scoring method (for article age)
+
+ * doc/misc/gnus.texi (Score File Format): Document it.
+
+ * lisp/gnus/gnus-score.el (gnus-score-check-syntax): Add support
+ for the new date methods < and > (bug#43270).
+ (gnus-score-date): Allow scoring on dates by age.
+
+2020-09-08 João Távora <joaotavora@gmail.com>
+
+ Change icomplete-show-matches-on-no-input behaviour for Icomplete only
+
+ (Bug#19032), bug#43120
+
+ Previous fixes to bug#19032 introduced bugs in Fido mode. This fix
+ relies on a new command bound to RET.
+
+ * etc/NEWS (Miscellaneous): Mention icomplete-show-matches-on-no-input.
+
+ * lisp/icomplete.el (icomplete-show-matches-on-no-input): Add comment.
+ (icomplete-minibuffer-map): Rebind minibuffer-complete-and-exit to
+ icomplete-ret.
+ (icomplete-ret): New command.
+
+2020-09-08 João Távora <joaotavora@gmail.com>
+
+ Revert two commits for bug#19032
+
+ This reverts:
+
+ - commit 585fe00557489e49188b6a301f001ef01ff15dcb, which is titled
+ "Fix up previous icomplete-show-matches-on-no-input change"
+
+ - commit 1b8d369c381b5a63e40529d0d95dfa75d94b8e09, which is titled
+ "Change icomplete-show-matches-on-no-input behavior".
+
+ A simpler, less intrusive fix follows shortly after this commit.
+
+2020-09-08 Amin Bandali <bandali@gnu.org>
+
+ * etc/NEWS: Mention the new erc-status-sidebar.el
+
+ * lisp/erc/erc-status-sidebar.el: Fix header and make small tweaks
+
+2020-09-08 Andrew Barbarello <andrew.barbarello@outlook.com>
+
+ * lisp/erc/erc-status-sidebar.el: New file
+
+ Taken from commit 87210a3ccc16a86e6b5992744b68daabed3b2d11
+ of https://github.com/drewbarbs/erc-status-sidebar.
+
+2020-09-08 Andrea Corallo <akrl@sdf.org>
+
+ Name temp eln files as .eln.tmp so we can't clean-up them mistakenly.
+
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Postfix temporary eln
+ files as .eln.tmp.
+
+2020-09-07 Andrea Corallo <akrl@sdf.org>
+
+ Do not crash compilation if user eln-cache wasn't already created.
+
+ * lisp/emacs-lisp/comp.el (comp-clean-up-stale-eln): Guard
+ against calling `directory-files' on non existent directories.
+
+2020-09-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use format-prompt in read-file-name calls that have a default
+
+ * lisp/xwidget.el (xwidget-webkit-save-as-file):
+ * lisp/vc/vc.el (vc-backend-for-registration, vc-delete-file)
+ (vc-rename-file):
+ * lisp/vc/ediff-ptch.el (ediff-prompt-for-patch-file):
+ * lisp/vc/diff-mode.el (diff-tell-file-name):
+ * lisp/progmodes/etags.el (visit-tags-table)
+ (visit-tags-table-buffer):
+ * lisp/misearch.el (multi-isearch-read-files):
+ * lisp/mail/rmailmm.el (rmail-mime-save):
+ * lisp/help-fns.el (doc-file-to-man, doc-file-to-info):
+ * lisp/gnus/gnus-bookmark.el (gnus-bookmark-load):
+ * lisp/files.el (write-file, basic-save-buffer):
+ * lisp/dired.el (dired-read-dir-and-switches):
+ * lisp/bookmark.el (bookmark-save, bookmark-load):
+ * lisp/abbrev.el (write-abbrev-file, abbrev-edit-save-to-file):
+ Use format-prompt in read-file-name calls that have a default.
+
+2020-09-07 Reuben Thomas <rrt@sc3d.org>
+
+ Fix Enchant dictionary finding routine
+
+ * lisp/textmodes/ispell.el (ispell-find-enchant-dictionaries): Don’t
+ pass `buffer-string' to enchant-lsmod. Remove zero-length substrings
+ from the split output of `enchant-lsmod`, as the output ends with a
+ separator. Pass the current language to
+ `ispell--get-extra-word-characters', so we get the result for the
+ current language, not the default language. (Patch from Jorge P. de
+ Morais Neto.)
+
+2020-09-07 Juri Linkov <juri@linkov.net>
+
+ * lisp/char-fold.el (char-fold-to-regexp): Handle lax-whitespace (bug#38539)
+
+2020-09-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix test failure in custom--test-theme-variables
+
+ * test/lisp/custom-tests.el (custom--test-theme-variables): "make
+ check" in the main directory didn't work because the path was
+ wrong. Use EMACS_TEST_DIRECTORY to find the test directory
+ instead.
+
+2020-09-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Require ert in the cperl tests, since it's reloading itself
+
+2020-09-07 Viktor Slavkovikj <zhtvk@gmx.com> (tiny change)
+
+ Use auth-source for passwords in rmail
+
+ * lisp/mail/rmail.el (rmail-get-remote-password): Use auth-source for
+ passwords (bug#24274).
+ (rmail-parse-url): Pass in user/host.
+
+2020-09-07 Daniel Martín <mardani29@yahoo.es> (tiny change)
+
+ Add support for horizontal scrolling in tab-line
+
+ * lisp/tab-line.el ([tab-line wheel-left]): Bind left and right tab
+ line scrolling to the 'wheel-left' and 'wheel-right' mouse events.
+ ([tab-line S-wheel-right]): Analogous change for the functions that
+ switch tabs.
+ * etc/NEWS: Announce the new feature (bug#43224).
+
+2020-09-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Show the status of signed + encrypted S/MIME messages in Gnus
+
+ * lisp/gnus/mm-decode.el (mm-possibly-verify-or-decrypt): Use the
+ data to tell the caller (i.e., Gnus) something about the
+ validation of signed + encrypted S/MIME messages.
+
+ * lisp/gnus/mm-view.el (mm-view-pkcs7-verify): Pass along details
+ about whether we could validate the signature or not (bug#42637).
+
+2020-09-07 João Távora <joaotavora@gmail.com>
+
+ Better explain behaviour of icomplete--sorted-completions
+
+ * lisp/icomplete.el (icomplete--sorted-completions): Overhaul comment
+
+2020-09-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove debugging code inadvertently checked in
+
+ * lisp/gnus/gnus-fun.el (gnus-face-from-file): Remove debugging
+ code inadvertently checked in.
+
+2020-09-07 Andrew G Cohen <cohen@andy.bu.edu>
+
+ Add aliases for recent Gnus nnselect changes
+
+ * lisp/org/ol-gnus.el (org-gnus-store-link): Change 'nnir to
+ 'nnselect.
+ * lisp/gnus/gnus-group.el: Define obsolete function alias for
+ 'gnus-group-make-nnir-group to
+ 'gnus-group-read-ephemeral-search-group.
+ * lisp/gnus/gnus-sum.el: Define obsolete variable alias for
+ 'gnus-refer-thread-use-nnir to 'gnus-refer-thread-use-search.
+ * lisp/gnus/nnselect.el: Define obsolete variable alias for
+ 'nnir-retrieve-headers-override-function to
+ 'nnselect-retrieve-headers-override-function.
+ * lisp/gnus/nnir.el: Restore definition of 'nnir-summary-line-format
+ and mark obsolete.
+
+2020-09-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use variable-pitch fonts in the eww headers
+
+ * lisp/net/eww.el (eww--limit-string-pixelwise)
+ (eww--pixel-column): New functions.
+ (eww-update-header-line-format): Use variable pitch fonts in the
+ header line.
+
+2020-09-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add edebug form to subr--with-wrapper-hook-no-warnings
+
+ * lisp/subr.el (subr--with-wrapper-hook-no-warnings): Add a debug
+ form to allow edebugging some stuff.
+
+2020-09-07 Reuben Thomas <rrt@sc3d.org>
+
+ Add enchant-2 to list of default spelling checker programs
+
+ * lisp/textmodes/ispell.el (ispell-program-name): Check `enchant-2',
+ as it is likely to be a suitable version.
+
+2020-09-07 Philip K <philipk@posteo.net>
+
+ Allow CSS completion with multiple rules on one line
+
+ * lisp/textmodes/css-mode.el (css--complete-property-value): Check
+ for semi-colon when completing property values (bug#43242).
+
+2020-09-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use format-prompt in some read-string calls
+
+ * lisp/progmodes/prolog.el (prolog-help-on-predicate):
+ * lisp/cmuscheme.el (scheme-trace-procedure):
+ * lisp/calendar/todo-mode.el (todo-convert-legacy-files): Use
+ format-prompt in some read-string calls (that have default values).
+
+ * lisp/printing.el (pr-interactive-regexp): No need to use "" as
+ the default value, because that's the default default value.
+ (pr-interactive-n-up): Use read-number instead of read-string and
+ then parsing the string.
+
+2020-09-06 dickmao <none>
+
+ Make list-processes--refresh work for pipe processes, too
+
+ * lisp/simple.el (list-processes--refresh): Don't bug out in the
+ presence of a `pipe' process (bug#43202).
+
+2020-09-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use format-prompt in calls to read-from-minibuffer with default value
+
+ * lisp/tab-bar.el (tab-bar-rename-tab)
+ (tab-bar-rename-tab-by-name):
+ * lisp/simple.el (next-matching-history-element): Use
+ format-prompt in calls to read-from-minibuffer with at default
+ value.
+
+2020-09-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use format-prompt in read-string calls (that have default values)
+
+ * lisp/vc/vc-annotate.el (vc-annotate):
+ * lisp/vc/log-edit.el (log-edit-comment-search-backward)
+ (log-edit-comment-search-forward):
+ * lisp/textmodes/rst.el (rst-insert-list-new-item):
+ * lisp/server.el (server-force-delete):
+ * lisp/mpc.el (mpc):
+ * lisp/frame.el (set-frame-name):
+ * lisp/emulation/cua-rect.el (cua-sequence-rectangle):
+ * lisp/cedet/semantic/symref/list.el (semantic-symref-regexp):
+ * lisp/calendar/todo-mode.el (todo-read-time): Use `format-prompt'
+ in `read-string' calls that have defaults.
+
+2020-09-06 Stefan Kangas <stefankangas@gmail.com>
+
+ Add autoload cookie to eshell-bookmark-jump
+
+ * lisp/eshell/esh-mode.el (eshell-bookmark-jump): Add autoload
+ cookie, so we can jump to bookmarks before having used eshell.
+ Problem noted by Stefan Monnier.
+
+2020-09-06 Michael Albinus <michael.albinus@gmx.de>
+
+ More work on D-Bus error messages
+
+ * lisp/net/dbus.el (dbus-get-property): Adapt docstring.
+ (dbus-set-property): Handle case of `:write' access type.
+ (dbus-get-other-registered-properties): Rename from
+ `dbus-get-other-registered-property'.
+ (dbus-property-handler): Fix thinkos.
+
+ * src/dbusbind.c (xd_read_message_1): Add error_name to event args
+ in case of DBUS_MESSAGE_TYPE_ERROR.
+
+ * test/lisp/net/dbus-tests.el (dbus--test-enabled-session-bus)
+ (dbus--test-enabled-system-bus): Make them defconst.
+ (dbus--test-service, dbus--test-path, dbus--test-interface):
+ New defconst. Replace all occurrences of `dbus-service-emacs' by
+ `dbus--test-service'.
+ (dbus--test-method-handler): New defun.
+ (dbus-test04-register-method, dbus-test05-register-property): New tests.
+
+2020-09-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use format-prompt in calls to completing-read with a default value
+
+ * lisp/textmodes/rst.el (rst-insert-list-new-item):
+ * lisp/tab-bar.el (tab-bar-switch-to-tab):
+ * lisp/profiler.el (profiler-start):
+ * lisp/frame.el (set-frame-font):
+ * lisp/erc/erc.el (erc-join-channel):
+ * lisp/emacs-lock.el (emacs-lock--set-mode):
+ * lisp/emacs-lisp/elp.el (elp-set-master):
+ * lisp/emacs-lisp/checkdoc.el ()
+ (checkdoc-this-string-valid-engine):
+ * lisp/calendar/todo-mode.el (todo-find-filtered-items-file):
+ * lisp/calendar/calendar.el (calendar-set-date-style): Use
+ `format-prompt' in calls to completing-read that has a default
+ value, but didn't mention that in the prompt.
+
+2020-09-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use a popup menu for <select>s in eww
+
+ * lisp/net/eww.el (eww-change-select): Use a popup menu for the
+ select (bug#43218).
+ (eww--form-items): New utility function.
+ (eww-select-map): Allow using a mouse to click on select buttons.
+
+2020-09-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Disable display-warning buttons when doing batch compiles
+
+ * lisp/emacs-lisp/warnings.el (display-warning): Don't output the
+ buttons when we're not interactive (bug#43244).
+
+2020-09-06 Andrea Corallo <akrl@sdf.org>
+
+ * src/data.c (subr-native-lambda-list): Defined it unconditionally (bug#43255)
+
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Rename a variable.
+
+2020-09-06 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (Fnative_elisp_load): Make recompilation always effective.
+
+ When loading a file if in this session there was ever a file loaded
+ with that name rename it before loading it to make sure we always get
+ a new handle from the standard library.
+
+2020-09-06 Andrea Corallo <akrl@sdf.org>
+
+ Rework eln deletion strategy for new eln-cache folder structure
+
+ When recompiling remove the corresponding stale elns found in the
+ `comp-eln-load-path'.
+
+ When removing a package remove the corresponding elns too.
+
+ On Windows both of these are performed only when possible, when it's
+ not the file is renamed as .eln.old and a last attempt to remove this
+ is performed closing the Emacs session. When a file being deleted was
+ loaded by multiple Emacs sessions the last one being closed should
+ delete it.
+
+ * lisp/emacs-lisp/comp.el (comp-clean-up-stale-eln): New function.
+ (comp-delete-or-replace-file): Rename from
+ `comp--replace-output-file' and update so it can be used for
+ replacing or deleting shared libs safely.
+
+ * lisp/emacs-lisp/package.el (package--delete-directory): When
+ native compiled just call `comp-clean-up-stale-eln' for each
+ eln file we want to clean-up.
+
+ * src/alloc.c (cleanup_vector): Call directly the dynlib_close.
+
+ * src/comp.c (syms_of_comp): Update for comp_u->cfile removal.
+ Make 'all_loaded_comp_units_h' key-value weak as now the key will
+ be the filename.
+ (load_comp_unit): Register the compilation unit only when the load
+ is fully completed.
+ (register_native_comp_unit): Make the key of
+ all_loaded_comp_units_h the load filename.
+ (eln_load_path_final_clean_up): New function.
+ (dispose_comp_unit)
+ (finish_delayed_disposal_of_comp_units)
+ (dispose_all_remaining_comp_units)
+ (clean_package_user_dir_of_old_comp_units): Remove.
+ (Fcomp__compile_ctxt_to_file): Update for
+ `comp--replace-output-file' -> `comp-delete-or-replace-file'
+ rename.
+
+ * src/comp.h (dispose_comp_unit)
+ (finish_delayed_disposal_of_comp_units)
+ (dispose_all_remaining_comp_units)
+ (clean_package_user_dir_of_old_comp_units): Remove.
+ (eln_load_path_final_clean_up): Add.
+ (struct Lisp_Native_Comp_Unit): Remove cfile field.
+
+ * src/emacs.c (Fkill_emacs): Call 'eln_load_path_final_clean_up'.
+
+ * src/pdumper.c (dump_do_dump_relocation): Do not set comp_u->cfile.
+
+2020-09-06 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix formatting of recent Gnus nnselect changes
+
+ * doc/misc/gnus.texi (Finding the Parent, Selection Groups)
+ (Searching, Basic Usage): Heed sentence-end-double-space. Fix
+ formatting of prose and examples.
+ * etc/NEWS: Fix typo.
+ * lisp/gnus/gnus-srvr.el: Remove disabled autoload.
+ * lisp/gnus/gnus-cloud.el (gnus-cloud-available-chunks):
+ * lisp/gnus/gnus-group.el (gnus-group-read-ephemeral-search-group):
+ * lisp/gnus/gnus-sum.el (gnus-refer-thread-use-search)
+ (gnus-summary-refer-thread):
+ * lisp/gnus/gnus.el (gnus-kill-ephemeral-group):
+ * lisp/gnus/nnheader.el (nnheader-head-make-header)
+ (nnheader-parse-head):
+ * lisp/gnus/nnir.el:
+ (nnir-hyrex-remove-prefix, nnir-run-notmuch):
+ * lisp/gnus/nnselect.el: Fix formatting/indentation of commentary,
+ docstring, and/or code.
+
+2020-09-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use `format-prompt' when prompting with default values
+
+ * lisp/woman.el (woman-file-name):
+ * lisp/wid-edit.el (widget-file-prompt-value)
+ (widget-coding-system-prompt-value):
+ * lisp/w32-fns.el (w32-set-system-coding-system):
+ * lisp/vc/vc.el (vc-print-root-log):
+ * lisp/vc/vc-annotate.el (vc-annotate):
+ * lisp/vc/emerge.el (emerge-read-file-name):
+ * lisp/vc/ediff.el (ediff-directories)
+ (ediff-directory-revisions, ediff-directories3)
+ (ediff-merge-directories, )
+ (ediff-merge-directories-with-ancestor)
+ (ediff-merge-directory-revisions)
+ (ediff-merge-directory-revisions-with-ancestor)
+ (ediff-merge-revisions, ediff-merge-revisions-with-ancestor)
+ (ediff-revision):
+ * lisp/vc/ediff-util.el (ediff-toggle-regexp-match):
+ * lisp/vc/ediff-mult.el (ediff-filegroup-action):
+ * lisp/vc/add-log.el (prompt-for-change-log-name):
+ * lisp/textmodes/table.el (table-insert-row-column)
+ (table-span-cell, table-split-cell-horizontally)
+ (table-split-cell, table-justify, table-generate-source)
+ (table-insert-sequence, table-capture)
+ (table--read-from-minibuffer, table--query-justification):
+ * lisp/textmodes/sgml-mode.el (sgml-tag, sgml-tag-help):
+ * lisp/textmodes/reftex-ref.el (reftex-goto-label):
+ * lisp/textmodes/refer.el (refer-get-bib-files):
+ * lisp/textmodes/css-mode.el (css-lookup-symbol):
+ * lisp/term.el (serial-read-name, serial-read-speed):
+ * lisp/speedbar.el (speedbar-change-initial-expansion-list):
+ * lisp/simple.el (previous-matching-history-element)
+ (set-variable):
+ * lisp/ses.el (ses-read-cell, ses-set-column-width):
+ * lisp/replace.el (query-replace-read-from)
+ (occur-read-primary-args):
+ * lisp/rect.el (string-rectangle, string-insert-rectangle):
+ * lisp/progmodes/tcl.el (tcl-help-on-word):
+ * lisp/progmodes/sh-script.el (sh-set-shell):
+ * lisp/progmodes/python.el (python-eldoc-at-point):
+ * lisp/progmodes/octave.el (octave-completing-read)
+ (octave-update-function-file-comment, octave-insert-defun):
+ * lisp/progmodes/inf-lisp.el (lisp-symprompt):
+ * lisp/progmodes/cperl-mode.el (cperl-info-on-command)
+ (cperl-perldoc):
+ * lisp/progmodes/compile.el (compilation-find-file):
+ * lisp/net/rcirc.el (rcirc-prompt-for-encryption):
+ * lisp/net/eww.el (eww):
+ * lisp/net/browse-url.el (browse-url-with-browser-kind):
+ * lisp/man.el (man):
+ * lisp/mail/sendmail.el (sendmail-query-user-about-smtp):
+ * lisp/mail/mailalias.el (build-mail-aliases):
+ * lisp/mail/mailabbrev.el (merge-mail-abbrevs)
+ (rebuild-mail-abbrevs):
+ * lisp/locate.el (locate-prompt-for-search-string):
+ * lisp/isearch.el (isearch-occur):
+ * lisp/international/ogonek.el (ogonek-read-encoding)
+ (ogonek-read-prefix):
+ * lisp/international/mule.el (read-buffer-file-coding-system)
+ (set-terminal-coding-system, set-keyboard-coding-system)
+ (set-next-selection-coding-system, recode-region):
+ * lisp/international/mule-cmds.el ()
+ (universal-coding-system-argument, search-unencodable-char)
+ (select-safe-coding-system-interactively):
+ * lisp/info.el (Info-search, Info-search-backward, Info-menu):
+ * lisp/info-look.el (info-lookup-interactive-arguments):
+ * lisp/imenu.el (imenu--completion-buffer):
+ * lisp/ibuf-ext.el (mode, used-mode, ibuffer-mark-by-mode):
+ * lisp/hi-lock.el (hi-lock-unface-buffer)
+ (hi-lock-read-face-name):
+ * lisp/help.el (view-emacs-news, where-is):
+ * lisp/help-fns.el (describe-variable, describe-symbol)
+ (describe-keymap):
+ * lisp/gnus/mm-decode.el (mm-save-part):
+ * lisp/gnus/gnus-sum.el (gnus-summary-browse-url):
+ * lisp/gnus/gnus-group.el (gnus-group--read-bug-ids)
+ (gnus-group-set-current-level):
+ * lisp/frame.el (make-frame-on-monitor)
+ (close-display-connection, select-frame-by-name):
+ * lisp/format.el (format-encode-buffer, format-encode-region):
+ * lisp/files.el (recode-file-name):
+ * lisp/files-x.el (read-file-local-variable)
+ (read-file-local-variable-value, )
+ (read-file-local-variable-mode):
+ * lisp/ffap.el (ffap-menu-ask):
+ * lisp/faces.el (face-read-string):
+ * lisp/facemenu.el (facemenu-set-charset):
+ * lisp/erc/erc-dcc.el (erc-dcc-do-GET-command):
+ * lisp/emulation/edt-mapper.el (edt-mapper):
+ * lisp/emacs-lisp/trace.el (trace--read-args)
+ (trace-function-foreground, trace-function-background):
+ * lisp/emacs-lisp/smie.el (smie-config-set-indent):
+ * lisp/emacs-lisp/re-builder.el (reb-change-syntax):
+ * lisp/emacs-lisp/package.el (describe-package):
+ * lisp/emacs-lisp/find-func.el (read-library-name)
+ (find-function-read):
+ * lisp/emacs-lisp/ert.el (ert-read-test-name)
+ (ert-run-tests-interactively):
+ * lisp/emacs-lisp/disass.el (disassemble):
+ * lisp/emacs-lisp/debug.el (debug-on-entry)
+ (debug-on-variable-change):
+ * lisp/emacs-lisp/advice.el (ad-read-advised-function)
+ (ad-read-advice-class, ad-read-advice-name, ad-read-regexp):
+ * lisp/dired-x.el (dired--mark-suffix-interactive-spec):
+ * lisp/dired-aux.el (dired-diff):
+ * lisp/cus-edit.el (custom-variable-prompt, customize-mode)
+ (customize-changed-options):
+ * lisp/completion.el (interactive-completion-string-reader):
+ * lisp/calendar/timeclock.el (timeclock-ask-for-project):
+ * lisp/calc/calcalg3.el (calc-get-fit-variables):
+ * lisp/calc/calc-store.el (calc-edit-variable):
+ * lisp/calc/calc-bin.el (calc-word-size):
+ * lisp/bookmark.el (bookmark-set-internal):
+ * lisp/abbrev.el (read-abbrev-file): Use `format-prompt' for
+ prompting (bug#12443).
+
+2020-09-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make C-h S in Customize buffers work more reliably
+
+ * lisp/cus-edit.el (custom-unlispify-menu-entry): Put a property
+ on the returned string so that we can determine what the symbol
+ was after the fact.
+
+ * lisp/info-look.el (info-lookup-guess-default*): Allow lambda
+ forms as rules.
+ (:mode): Use the stored symbol.
+ (info-lookup-guess-custom-symbol): No longer used; mark as
+ obsolete (bug#41905).
+
+2020-09-06 João Távora <joaotavora@gmail.com>
+
+ Don't resort Icomplete candidates when default already on top
+
+ (Bug#43222)
+
+ Icomplete mode re-sorts candidates, bubbling the default to top if
+ it's found somewhere down the list. This is done according to two
+ criteria: exact match and prefix match. Before this fix, it didn't
+ take into account the possibility that the exact match for the default
+ would already be on top, and would incorrectly bubble a prefixing
+ completion down the list to the top. This commit fixes that.
+
+ * lisp/icomplete.el (icomplete--sorted-completions):
+ Rework. Recomment.
+
+2020-09-06 Andrea Corallo <akrl@sdf.org>
+
+ Makefile.in (ELN_DESTDIR): Add ${version}/ to it.
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-09-06 Thomas Fitzsimmons <fitzsim@fitzsim.org>
+
+ EUDC: Reword macOS Contacts back end overview
+
+ * doc/misc/eudc.texi (macOS Contacts): Shorten section.
+
+2020-09-06 Thomas Fitzsimmons <fitzsim@fitzsim.org>
+
+ EUDC: Fix a minor formatting issue
+
+ * lisp/net/eudcb-macos-contacts.el
+ (eudc-macos-contacts-query-internal): Move result to its own line
+ to eliminate a lisp-mode warning.
+
+2020-09-06 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-09-05 verify: avoid __builtin_assume
+ 2020-08-30 strerrorname_np: New module
+ 2020-08-26 include_next, stdint, time_rz: Change configure message
+ * lib/gnulib.mk.in: Regenerate.
+ * lib/string.in.h, lib/verify.h, m4/include_next.m4, m4/stdint.m4:
+ * m4/string_h.m4, m4/time_rz.m4: Copy from Gnulib.
+
+2020-09-06 Stefan Kangas <stefankangas@gmail.com>
+
+ * lisp/svg.el: Bump package version to 1.1.
+
+2020-09-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix eww-change-select defaults in a different way
+
+ * lisp/net/eww.el (eww-change-select): Fix bug#43218 in a more
+ safe way than the previous version.
+
+2020-09-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up previous icomplete-show-matches-on-no-input change
+
+ * lisp/icomplete.el (icomplete-completions): Ensure that the
+ default value is cleared (bug#43120).
+
+2020-09-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Reinstall recent GC-related changes
+
+ The report that they broke macOS was a false alarm, as the
+ previous commit was also broken (Bug#43152#62).
+ * src/alloc.c (live_string_holding, live_cons_holding)
+ (live_symbol_holding):
+ Count only pointers that point to a struct component,
+ or are a tagged pointer to the start of the struct.
+ Exception: for non-bool-vector pseudovectors,
+ count any pointer past the header, since it’s too much
+ of a pain to write code for every pseudovector.
+ (live_float_holding, live_vector_pointer):
+ New functions, which are similar about counting pointers.
+ (live_float_p, live_large_vector_holding)
+ (live_small_vector_pointer, mark_maybe_pointer): Use them.
+ (mark_maybe_object, mark_maybe_objects): Remove,
+ and remove all callers; mark_maybe_pointer now suffices.
+ (mark_objects): New function.
+ * src/alloc.c (mark_vectorlike, mark_face_cache):
+ * src/eval.c (mark_specpdl):
+ * src/fringe.c (mark_fringe_data):
+ * src/keyboard.c (mark_kboards):
+ Simplify by using mark_objects.
+ * src/lisp.h (SAFE_ALLOCA_LISP_EXTRA):
+ Clear any Lisp_Object arrays large enough to not fit into the stack,
+ so that GC need not worry about whether they contain objects.
+
+2020-09-05 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt tramp-test30-make-process
+
+ * test/lisp/net/tramp-tests.el (tramp-list-tramp-buffers)
+ (tramp-time-diff): Don't declare.
+ (tramp-test30-make-process): Adapt test.
+
+2020-09-05 Michael Albinus <michael.albinus@gmx.de>
+
+ Minor improvements in Tramp error reporting
+
+ * lisp/net/tramp-cmds.el (tramp-bug):
+ Handle `tramp-suppress-trace' property.
+ (tramp-reporter-dump-variable): Improve variable dump.
+
+ * lisp/net/tramp.el (tramp--startup-hook, tramp-password-save-function):
+ Add `tramp-suppress-trace' property.
+
+2020-09-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Display name with with spaces, but keep symbol name underneath"
+
+ This reverts commit e0c77bb62c1c950a82ea0517646d989dc5c1fe27.
+
+ We can't use a string with a display string here, anyway, because
+ it's used in other contexts.
+
+2020-09-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "info-lookup-symbol: Fix the suggested default value in Custom buffers"
+
+ This reverts commit ccae4ea6990580e7489e7c9f958b4a094b32b8b8.
+
+ We can't use a string with a display string here, anyway, because
+ it's used in other contexts.
+
+2020-09-05 Mauro Aranda <maurooaranda@gmail.com>
+
+ info-lookup-symbol: Fix the suggested default value in Custom buffers
+
+ * lisp/info-look.el (info-lookup-maybe-add-help 'Custom-mode): Don't
+ pass info-lookup-guess-custom-symbol as the :parse-rule, since we
+ don't need it anymore. (Bug#41905)
+ (info-lookup-guess-custom-symbol): Now unused, mark as obsolete.
+ (info-lookup-interactive-arguments): Get rid of text properties before
+ passing the default value to completing-read.
+
+2020-09-05 Lucas Werkmeister <mail@lucaswerkmeister.de>
+
+ Mark sgml-basic-offset as safe for integers
+
+ * lisp/textmodes/sgml-mode.el (sgml-basic-offset):
+ Add :safe. (Bug#43215)
+
+2020-09-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Explain in the tab-always-indent doc how to make TAB insert a TAB
+
+ * lisp/indent.el (tab-always-indent): Mention how to make TAB
+ insert a TAB character always (bug#37183).
+
+2020-09-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix default value in selects in eww
+
+ * lisp/net/eww.el (eww-change-select): Make hitting RET with an
+ empty string use a default (bug#43218).
+
+2020-09-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix <optgroup> in selects in eww
+
+ * lisp/net/eww.el (eww-tag-select): Use all the options. This
+ fixes the problem with <optgroup> elements that wrap them (bug#43217).
+
+2020-09-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak how cperl-mode fontifies hashes and arrays
+
+ * lisp/progmodes/cperl-mode.el (cperl-init-faces): Fontify hashes
+ and arrays (%foo and @foo) before the keywords, since the keyword
+ regexps are "wider" and the hash/array regexp just match those two
+ things (bug#22867).
+
+2020-09-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Protect compilation-auto-jump against code killing the buffer
+
+ * lisp/progmodes/compile.el (compilation-auto-jump): Something may
+ have killed the buffer before the timer fired (bug#24585).
+
+2020-09-05 Mauro Aranda <maurooaranda@gmail.com>
+
+ Improve call to widget-create-child-and-convert in cus-edit
+
+ * lisp/cus-edit.el (custom-variable-value-create): Pass tag as the
+ :tag property value (bug#41905).
+
+2020-09-05 ej-32u <ej32u@protonmail.com> (tiny change)
+
+ Display name with with spaces, but keep symbol name underneath
+
+ * lisp/cus-edit.el (custom-unlispify-menu-entry): Display the
+ pretty name, but keep the real symbol name as the value (bug#41905).
+
+2020-09-05 Mauro Aranda <maurooaranda@gmail.com>
+
+ Preserve user customizations after disabling a theme
+
+ * lisp/custom.el (enable-theme): Since we are enabling the theme, bind
+ custom--inhibit-theme-enable to nil. Then rely on custom-push-theme
+ to do the right thing with the theme settings and prior user settings,
+ instead of manipulating the property here. This way, when disabling a
+ theme, we restore user preferences, even when the values were changed
+ outside of customize.
+ (disable-theme): Call custom-push-theme instead of handling theme
+ settings directly.
+ (custom-push-theme): Avoid another instance of Bug#28904: we don't
+ need the changed theme when the value recorded for it is going to be
+ the same as the recorded for the user theme.
+
+ * test/lisp/custom-tests.el (custom--test-theme-variables): Get rid of
+ a portion of the test that will always fail, because the user theme
+ has priority over every other theme. Expect the test to pass now that
+ we preserve user customizations after disabling a theme (bug#34027).
+
+2020-09-05 Andrew G Cohen <cohen@andy.bu.edu>
+
+ Introduce nnselect backend for gnus
+
+ This new backend allows gnus to handle arbitrary sets of messages
+ spanning multiple groups, even when these groups are from different
+ backends and different servers. All gnus glue is removed from
+ nnir (leaving only the backend search functions) and gnus
+ search-related processing is done through nnselect. In appropriate
+ places 'nnir' has been replaced by 'nnselect' or 'search'.
+
+ * etc/NEWS: Document the change.
+ * doc/misc/gnus.texi: New documentation for nnselect and update
+ searching and thread-referral sections.
+ * lisp/gnus/nnselect.el: New file.
+ * lisp/gnus/nnir.el: Remove all gnus glue, leaving only searching
+ capability. Improve documentation strings.
+ * lisp/gnus/gnus-group.el (gnus-group-read-ephemeral-search-group,
+ gnus-group-make-search-group): New functions.
+ * lisp/gnus/gnus-msg.el (gnus-setup-message, gnus-group-news,
+ gnus-summary-news-other-window): Update to work for nnselect. Fix
+ gnus-newsgroup-name wrangling.
+ *lisp/gnus/gnus-registry.el
+ (gnus-registry-action,gnus-registry-ignore-group-p): Make work from nnselect.
+ * lisp/gnus/nnheader.el (nnheader-parse-head, nnheader-parse-nov):
+ Rework and consolidate header parsing.
+ * lisp/gnus/gnus-agent.el (gnus-agent-regenerate-group):
+ * lisp/gnus/gnus-cache.el (gnus-possibly-enter-article):
+ * lisp/gnus/gnus-cloud.el (gnus-cloud-available-chunks):
+ * lisp/gnus/gnus-msg.el (gnus-inews-yank-articles):
+ * lisp/gnus/gnus-sum.el (gnus-get-newsgroup-headers):
+ * lisp/gnus/nndiary.el (nndiary-parse-head):
+ * lisp/gnus/nnfolder.el (nnfolder-parse-head):
+ * lisp/gnus/nnmaildir.el (nnmaildir--update-nov):
+ * lisp/gnus/nnml.el (nnml-parse-head):
+ * lisp/gnus/nnspool.el (nnspool-insert-nov-head):
+ Use new header parsing.
+ * lisp/gnus/gnus-start.el (gnus-read-active-for-groups): Rescan on
+ activation by default.
+ * lisp/gnus/gnus-sum.el (gnus-summary-line-format-alist): New specs
+ for virtual groups.
+ (gnus-article-sort-by-rsv, gnus-thread-sort-by-rsv): New functions to
+ allow sorting by search RSV.
+
+2020-09-04 Andrii Kolomoiets <andreyk.mad@gmail.com>
+
+ Don't move point in vc-dir on vc-register/vc-checkin (bug#43188)
+
+ * lisp/vc/vc-dir.el (vc-dir-update):
+ Save and restore point on 'ewoc-invalidate'.
+ * lisp/vc/vc-dispatcher.el (vc-finish-logentry):
+ Don't call 'vc-dir-move-to-goal-column'.
+ * lisp/vc/vc.el (vc-register): Don't call 'vc-dir-move-to-goal-column'.
+
+2020-09-04 Alan Mackenzie <acm@muc.de>
+
+ C++ Mode: handle comma separated brace initializers.
+
+ This includes both indentation and fontification.
+
+ * lisp/progmodes/cc-engine.el (c-do-declarators): Handle brace initializers
+ without = correctly.
+ (c-looking-at-or-maybe-in-bracelist): Use c-do-declarators with a simple
+ inline function to check that after-type-id-pos points to the start of a
+ declarator.
+
+ * lisp/progmodes/cc-langs.el (c-recognize-bare-brace-inits): New lang
+ const/variable.
+
+2020-09-04 Andrea Corallo <akrl@sdf.org>
+
+ Rename and move eln system directory
+
+ Rename eln sys directory into 'native-lisp' and move it from
+ "$(DESTDIR)${libexecdir}/emacs/${version}/${configuration}/" to
+ "$(DESTDIR)${libdir}/emacs/".
+
+ Add to the directory name used to disambiguate the eln compatibility
+ the Emacs version to have it more user friendly.
+
+ * Makefile.in (clean, install-eln): Rename eln-cache into
+ native-lisp.
+ (ELN_DESTDIR): Move from
+ '$(DESTDIR)${libexecdir}/emacs/${version}/${configuration}/' to
+ '$(DESTDIR)${libdir}/emacs/'.
+
+ * lisp/loadup.el: Update for comp-native-path-postfix ->
+ comp-native-version-dir rename.
+
+ * src/comp.c (syms_of_comp): Rename eln-cache -> native-lisp.
+ (syms_of_comp, Fcomp_el_to_eln_filename): Rename
+ comp-native-path-postfix -> comp-native-version-dir.
+ (hash_native_abi): Rework and add emacs-version to
+ comp-native-version-dir.
+
+2020-09-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous manual mis-merge of dired-aux
+
+ * lisp/dired-aux.el (dired-rename-file): Fix manual mis-merge of
+ previous patch.
+
+2020-09-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up previous LAMDA->LAMBDA patch
+
+ * lisp/international/mule-cmds.el (ucs-names): Ensure we're only
+ matching LAMDA as a word. Noted by Stefan Monnier.
+
+2020-09-04 Mauro Aranda <maurooaranda@gmail.com>
+
+ Do not remove unbound variables or faces when modifying a custom-theme
+
+ * lisp/cus-theme.el (custom-theme-write-variables
+ custom-theme-write-faces): Remove check for a bound symbol or for a
+ face name, so saving a theme does not remove not yet defined variables
+ or faces (bug#24727).
+
+2020-09-04 Michael Albinus <michael.albinus@gmx.de>
+
+ * etc/NEWS: Add changes for D-Bus; fix typos.
+
+2020-09-04 Michael Albinus <michael.albinus@gmx.de>
+
+ Extend dbus.el by error messages, and :write access type
+
+ * doc/misc/dbus.texi (Receiving Method Calls): Describe how to
+ produce D-Bus error messages.
+ (Receiving Method Calls): Support :write access type.
+
+ * lisp/net/dbus.el (dbus-error-dbus, dbus-error-failed)
+ (dbus-error-access-denied, dbus-error-invalid-args)
+ (dbus-error-property-read-only): New defconsts.
+ (dbus-method-error-internal): Add arg ERROR-NAME.
+ (dbus-register-method): Adapt docstring.
+ (dbus-handle-event): Handle error messages returned from the handler.
+ (dbus-get-this-registered-property)
+ (dbus-get-other-registered-property): New defuns.
+ (dbus-register-property): Support :write access type.
+ (dbus-property-handler): Submit proper D-Bus error messages.
+ Handle several paths at the same interface.
+
+ * src/dbusbind.c (Fdbus_message_internal): Improve handling of
+ DBUS_MESSAGE_TYPE_ERROR.
+
+2020-09-04 Mauro Aranda <maurooaranda@gmail.com>
+
+ Document :type-error property for customization types
+
+ * doc/lispref/customize.texi (Type Keywords): Document :type-error, so
+ Lisp programs can display a more correct message when the value of a
+ user option doesn't match its type (bug#23975).
+
+2020-09-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/display-fill-column-indicator.el: Fix bug#41145
+
+ (global-display-fill-column-indicator-mode): Specify the implicit
+ defustom's group explicitly.
+
+ * lisp/cus-dep.el (custom-make-dependencies): Also look at
+ define(-globalized)-minor-mode since it can also define custom vars.
+
+2020-09-04 Michael Albinus <michael.albinus@gmx.de>
+
+ Backport recent change in tramp-tests.el from master, don't merge
+
+ * test/lisp/net/tramp-tests.el (tramp-test05-expand-file-name):
+ No need to expect different results in Emacs 28 and later.
+
+2020-09-04 Noam Postavsky <npostavs@gmail.com>
+
+ Allow "lambda" spelling for ucs-insert
+
+ * lisp/international/mule-cmds.el (ucs-names): Add a "LAMBDA"
+ completion variant for every "LAMDA" name (bug#30513).
+
+2020-09-04 Robert Pluim <rpluim@gmail.com>
+
+ Show log suppression buttons in display-warning buffer
+
+ * etc/NEWS: Describe 'display-warning' button change (bug#30757).
+ * lisp/emacs-lisp/warnings.el (warning-suppress-warning):
+ Define button.
+ (warning-suppress-action): New function.
+ (warning-suppress-log-warning): Define button.
+ (warning-suppress-log-action): New function.
+ (display-warning): Show buttons to allow permanent
+ modification of warning-suppress-types and
+ warning-suppress-log-types per warning.
+
+2020-09-04 Tino Calancha <tino.calancha@gmail.com>
+
+ wdired-do-renames: Speed up for long Emacs sessions
+
+ `dired-rename-file' calls unconditionally `dired-rename-subdir'.
+ The second function performs performs a loop on all the Emacs
+ buffers; this step is only needed if FILE is a directory (bug#32899).
+
+ In a long lived Emacs session, this can make a difference
+ when renaming a bunch of files with `wdired'.
+ For instance, in my 40 days old Emacs session, with ~ 700 buffers,
+ this patch increases the speed to rename 2000 files a factor ~ 15.
+
+ * lisp/dired-aux.el (dired-rename-file): Call `dired-rename-subdir'
+ if FILE is a directory. Add docstring.
+ (dired-rename-subdir, dired-remove-entry)
+ (dired-remove-file): Add docstring.
+
+ (dired-remove-entry): Move definition into `dired.el'.
+
+ * lisp/wdired.el (wdired-do-renames): Use a progress-reporter.
+
+ * lisp/dired.el (dired-delete-entry):
+ Use `dired-remove-entry'. Add docstring.
+
+ (dired-buffers-for-dir, dired-fun-in-all-buffers):
+ Change comment into docstring.
+ (dired-fun-in-all-buffers): Prefer `when' and `push' here.
+
+2020-09-04 Harald Jörg <haj@posteo.de>
+
+ Fix infloop when indenting in cperl-mode
+
+ * lisp/progmodes/cperl-mode.el (cperl-indent-exp): Fix (Bug#10483)
+ Perl expressions (e.g. function calls) ending in ")" without
+ statement terminator on the same line no longer loop endlessly.
+
+2020-09-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous buffer name fixup in save-some-buffers
+
+ * lisp/files.el (save-some-buffers): Get the file name for the
+ correct buffer in the buffer name check (bug#43192).
+
+2020-09-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't display the Gnus splash on gnus-read-ephemeral-emacs-bug-group
+
+ * lisp/gnus/gnus.el: Don't display the Gnus splash at load time
+ (bug#43123).
+
+2020-09-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/mail/mspools.el: Use lexical-scoping. Autoload `mspools-show`.
+
+ (mspools-mode-map): Remove bindings made redundant by `special-mode-map`.
+ (mspools-show): Autoload. Use `erase-buffer`.
+ (mspools-visit-spool): Use `inhibit-read-only`; simplify a bit.
+ (mspools-get-spool-files): Avoid `setq`. Use `pcase-dolist`.
+ (mspools-revert-buffer): Make (unused) args optional.
+ (mspools-help, mspools-show-again, mspools-quit): Declare obsolete.
+
+2020-09-04 João Távora <joaotavora@gmail.com>
+
+ Fix ElDoc's eldoc-documentation-enthusiast strategy
+
+ As soon as we get a response from any of the user functions/sources in
+ eldoc-documentation-functions, we must make sure to call the
+ display-doc local function, just like in the other strategies.
+
+ That is even if that response produced nil, meaning that there's no
+ doc coming from that source. Failure to do so when none of the
+ sources produced non-nil would keep stale documentation displaying.
+
+ First reported in https://github.com/joaotavora/eglot/issues/503
+
+ * lisp/emacs-lisp/eldoc.el (eldoc--invoke-strategy): Fix
+ :enthusiast strategy.
+ (Version): Bump to 1.10.0
+
+2020-09-03 Harald Jörg <haj@posteo.de>
+
+ Fix freeze in cperl-mode when editing a regexp
+
+ * lisp/progmodes/cperl-mode.el (cperl-forward-group-in-re): Make
+ sure that an error is reported back to the caller (Bug#16368).
+
+ * test/lisp/progmodes/cperl-mode-tests.el (cperl-mode-test-bug-16368):
+ Tests for balanced (no error) and unbalanced (caught exception)
+ cases of `cperl-forward-group-in-re'.
+
+2020-09-03 Alan Third <alan@idiocy.org>
+
+ * configure.ac (GNU_OBJC_CFLAGS): Check ObjC defaults to C99. (bug#43167)
+
+ * src/image.c (svg_load_image): Use xmalloc and xfree. (bug#43135)
+
+2020-09-03 Paul Eggert <eggert@cs.ucla.edu>
+
+ Revert recent GC-related changes (Bug#43152)
+
+ * src/alloc.c (live_string_holding, live_cons_holding)
+ (live_symbol_holding, live_large_vector_holding)
+ (live_small_vector_holding):
+ Go back to old approach of treating every would-be pointer to any
+ byte in the object (though not to just past the object end) as
+ addressing the object.
+ (live_float_p): Require that the would-be float point
+ to the start of the Lisp_Float, and not anywhere else.
+ (live_vector_pointer, live_float_holding, mark_objects):
+ Remove. All uses removed.
+ (mark_maybe_object, mark_maybe_objects):
+ Bring back these functions.
+ * src/lisp.h (SAFE_ALLOCA_LISP_EXTRA): Do not clear the
+ new slots, as they're now checked via mark_maybe_objects,
+ not via mark_objects.
+
+2020-09-03 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'expand-file-name' for remote files
+
+ This reverts most of commit 14fb657ba82da346d36f05f88da26f1c5498b798
+ and its followup fixes, and instead fixes the original bugs in a
+ different manner that doesn't affect any unrelated use cases. As
+ part of this, the code which caused 'expand-file-name' to enforce
+ a trailing slash on expanded directories is removed, as this kind
+ of semantic processing is outside of 'expand-file-name's scope.
+ * src/fileio.c (Fexpand_file_name): If expanding default_directory
+ yields a remote file name, call its handlers. (Bug#26911)
+ (Bug#34834)
+
+ * doc/lispref/files.texi (File Name Expansion): Remove the
+ requirement that expanding a directory name yields a directory
+ name, i.e. that the expansion must end in a slash.
+
+ * etc/NEWS: Remove the announcement of the changed behavior of
+ 'expand-file-name' wrt trailing slashes.
+
+ * test/src/fileio-tests.el (fileio-tests--HOME-trailing-slash)
+ (fileio-tests--expand-file-name-trailing-slash): Remove tests.
+ * test/lisp/net/tramp-tests.el (tramp-test05-expand-file-name): No
+ need to expect different results in Emacs 28 and later.
+
+2020-09-03 Stefan Kangas <stefankangas@gmail.com>
+
+ Fix my previous change to cancel world-clock timer
+
+ * lisp/time.el (subr-x): Require when compiling.
+ (world-clock): Set 'kill-buffer-hook' buffer locally only.
+ (world-clock-update): Break out timer cancellation from here...
+ (world-clock-cancel-timer): ...to here, and don't rely on variable to
+ find the timer to cancel.
+ (world-clock-timer): Delete now superfluous variable.
+
+2020-09-03 Eli Zaretskii <eliz@gnu.org>
+
+ Fix vertical cursor motion when 'visual-line-mode' is in effect
+
+ * src/xdisp.c (move_it_in_display_line_to): Fix a logic error made
+ as part of introducing the 'word-wrap-by-category' feature; that
+ error brought back bug#8155.
+
+2020-09-03 João Távora <joaotavora@gmail.com>
+
+ Unbreak project.el, the GNU Elpa package, for Emacs 26.3
+
+ (Bug#43164)
+
+ * lisp/progmodes/project.el: Bump to 0.5.2
+ (bound-and-true-p): Check that tab-prefix-map is bound before binding.
+
+2020-09-03 Stefan Kangas <stefankangas@gmail.com>
+
+ * lisp/eshell/esh-mode.el: Remove redundant :group args.
+
+2020-09-03 Stefan Kangas <stefankangas@gmail.com>
+
+ Support bookmarking Eshell buffers
+
+ * lisp/eshell/esh-mode.el (eshell-bookmark-name)
+ (eshell-bookmark-make-record, eshell-bookmark-jump): New defuns.
+ (eshell-mode): Set up bookmark handler.
+
+2020-09-03 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix bug in dbus.el; do not merge with master
+
+ * lisp/net/dbus.el (dbus-register-property)
+ (dbus-property-handler): Handle properties of the same interface
+ at different object paths properly. (Bug#43146)
+
+2020-09-03 Stefan Kangas <stefankangas@gmail.com>
+
+ Cancel timer when world-clock buffer is killed
+
+ * lisp/time.el (world-clock-timer): New variable.
+ (world-clock-cancel-timer): New defun.
+ (world-clock): Add 'world-clock-cancel-timer' to 'kill-buffer-hook'.
+
+2020-09-02 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in mwheel.el
+
+2020-09-02 Stefan Kangas <stefankangas@gmail.com>
+
+ Simplify mwheel-mode by using alist instead of two variables
+
+ * lisp/mwheel.el (mouse-wheel--remove-bindings): Update call
+ signature to take no arguments. Doc fix.
+ (mouse-wheel--add-binding): Break out from...
+ (mouse-wheel-mode): ...here. Simplify by using above functions.
+ (mouse-wheel--installed-bindings-alist): New variable.
+ (mwheel-installed-bindings): Make obsolete.
+ (mwheel-installed-text-scale-bindings): Make obsolete.
+ * test/lisp/mwheel-tests.el (mwheel-test-enable/disable):
+ New test.
+
+2020-09-02 Stefan Kangas <stefankangas@gmail.com>
+
+ Fix binding mouse wheel with modifiers in buffer area
+
+ * test/lisp/mwheel-tests.el (mwheel-test--create-scroll-keys): Fix
+ binding mouse wheel with modifiers in buffer area, while ignoring them
+ for fringes, margins, etc. My previous change mistakenly ignored all
+ modifiers in `mouse-wheel-scroll-amount'.
+ * lisp/mwheel.el (mouse-wheel--create-scroll-keys): Fix test to
+ reflect the above.
+
+2020-09-02 Ulf Jasper <ulf.jasper@web.de>
+
+ Apply icalendar.el patch by Thomas Plass <thunk2@arcor.de>. Fix bug#34315.
+
+ * lisp/calendar/icalendar.el (icalendar--convert-tz-offset): No DST
+ when RDATE is present.
+ * lisp/calendar/icalendar.el (icalendar--parse-vtimezone): Use
+ `icalendar--get-most-recent-observance'.
+ * (icalendar--get-most-recent-observance): New.
+ * (icalendar--decode-isodatetime): Add parameters source-zone, result-zone.
+ * (icalendar--decode-isoduration): Fix decoding days.
+ * test/lisp/calendar/icalendar-tests.el (icalendar--decode-isoduration):
+ Add testcases.
+
+2020-09-02 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix bug in dbus.el
+
+ * lisp/net/dbus.el (dbus-register-property)
+ (dbus-property-handler): Handle properties of the same interface
+ at different object paths properly. (Bug#43146)
+
+2020-09-02 Ulf Jasper <ulf.jasper@web.de>
+
+ Add unit tests for icalendar.el
+
+ * test/lisp/calendar/icalendar-tests.el (icalendar--parse-vtimezone,
+ icalendar--decode-isodatetime): Add testcases.
+ * test/lisp/calendar/icalendar-tests.el (icalendar--convert-tz-offset,
+ icalendar--decode-isoduration): New.
+
+2020-09-02 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Handle different IMAP server responses to COPY and MOVE
+
+ * lisp/gnus/nnimap.el (nnimap-request-move-article): Need to examine
+ different parts of the result.
+
+2020-09-02 Stefan Kangas <stefankangas@gmail.com>
+
+ Fix OBOE in flyspell-check-previous-highlighted-word
+
+ * lisp/textmodes/flyspell.el
+ (flyspell-check-previous-highlighted-word): Fix off-by-one error when
+ word is at (point-min). (Bug#39898)
+
+ Suggested by OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>.
+
+2020-09-02 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in pcmpl-unix.el
+
+ * lisp/pcmpl-unix.el: Use lexical-binding.
+ (pcmpl-ssh-known-hosts, pcmpl-ssh-config-hosts, pcmpl-ssh-hosts):
+ Adjust for lexical-binding.
+
+2020-09-02 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in pcmpl-linux.el and add tests
+
+ * lisp/pcmpl-linux.el: Use lexical-binding.
+ (pcmpl-linux-fs-modules-path-format)
+ (pcmpl-linux-mtab-file): New constants.
+ (pcmpl-linux-fs-types, pcmpl-linux-mounted-directories): Use above
+ new constants.
+ * test/lisp/pcmpl-linux-resources/fs/ext4/.keep:
+ * test/lisp/pcmpl-linux-resources/mtab:
+ * test/lisp/pcmpl-linux-tests.el: New files.
+
+2020-09-01 Andrea Corallo <akrl@sdf.org>
+
+ Fix `load-filename' for installed instance (bug#43089)
+
+ * src/lread.c (parent_directory): Remove function as now
+ unnecessary.
+ (compute_found_effective): New function.
+ (Fload): Make use of 'compute_found_effective' and fix
+ `load-filename' computation.
+
+2020-09-01 Robert Pluim <rpluim@gmail.com>
+
+ Strip carriage returns from received password prompts (comint)
+
+ * lisp/comint.el (comint-password-prompt-regexp): Strip carriage
+ returns from the received prompt before matching. (Bug#43003)
+
+2020-09-01 Mauro Aranda <maurooaranda@gmail.com>
+
+ Improve documentation for custom :options
+
+ * doc/lispref/customize.texi (Variable Definitions):
+ Mention that re-evaluating a defcustom form doesn't reset custom
+ options (bug#30101).
+
+2020-09-01 Robert Pluim <rpluim@gmail.com>
+
+ Document 'smtp-auth' in auth-source info
+
+ * doc/misc/auth.texi (Help for users): Mention 'smtp-auth' key,
+ add cross-reference to smtpmail.info.
+ * doc/misc/smtpmail.texi (Authentication): Fix markup.
+
+2020-09-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention C-c C-w in the signature section of the Message manual
+
+ * doc/misc/message.texi (Insertion Variables): Mention the C-c C-w
+ command (bug#43136). Text suggested by Dan Jacobson.
+
+2020-09-01 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove spurious @ character in smtpmail.texi
+
+ * doc/misc/smtpmail.texi (Authentication): Remove a presumably
+ spurious @ character.
+
+2020-09-01 Stefan Kangas <stefankangas@gmail.com>
+
+ Fix help message with help-window-select
+
+ * lisp/help.el (help-print-return-message):
+ (help-window-display-message): Recommend 'scroll-up-command' instead
+ of 'scroll-up' when 'help-window-select' is non-nil. (Bug#43122)
+
+2020-09-01 Andrea Corallo <akrl@sdf.org>
+
+ Rework native compiled lisp/d lambda list accessor
+
+ * lisp/help.el (help-function-arglist): Logic update for new
+ 'Fsubr_native_lambda_list'.
+ * src/data.c (Fsubr_native_dyn_p): Remove.
+ (Fsubr_native_lambda_list): Return t when the input is not a
+ compiled lisp/d subr.
+ (syms_of_data): Update for 'Fsubr_native_dyn_p' removal.
+
+2020-08-31 Andrea Corallo <akrl@sdf.org>
+
+ * src/lread.c (Fload): Fix for manual eln load.
+
+2020-08-31 Andrea Corallo <akrl@sdf.org>
+
+ Fix describe function arglist for native compiled lisp/d (bug#42572)
+
+ * lisp/help.el (help-function-arglist): Handle the case of native
+ compiled lisp/d.
+
+ * src/data.c (syms_of_data): Register new subrs.
+ (Fsubr_native_dyn_p, Fsubr_native_lambda_list): New primitives.
+
+ * test/src/comp-tests.el (comp-tests-dynamic-help-arglist): New test.
+
+2020-08-31 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in pong.el
+
+ * lisp/play/pong.el: Use lexical-binding.
+ Remove redundant :group args.
+
+2020-08-31 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Remove obsolete "Wide Characters" section of Gnus manual
+
+ * doc/misc/gnus.texi: This hasn't been valid since 2016.
+
+2020-08-31 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ f20169399d (origin/emacs-27) Fix typo in Introduction to Emacs Lisp
+ 7605060d51 Update Elisp Manual reference to which-function-mode
+ 29708cbde7 Some precisions to bug handling
+ dddc971f0e CC Mode: Fix processing for when c-multiline-string-start-...
+ 4a73fb9668 Fix description of %-constructs in 'mode-line-format'
+
+2020-08-31 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ da4840af12 Adapt reminder-for-release-blocking-bugs
+
+2020-08-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make quoted-printable-encode-region work in multibyte buffers
+
+ * lisp/mail/qp.el (quoted-printable-encode-region): If we're in a
+ multibyte buffer (that has been encoded with some coding system),
+ then get-byte will get the correct byte value.
+
+2020-08-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new function dom-print
+
+ * doc/lispref/text.texi (Document Object Model): Document it.
+
+ * lisp/dom.el (dom-print): New function.
+
+2020-08-31 Stefan Kangas <stefankangas@gmail.com>
+
+ * lisp/dired-x.el (dired-omit-mode): Add autoload cookie.
+
+2020-08-31 Michael Albinus <michael.albinus@gmx.de>
+
+ * .gitlab-ci.yml (test-all): Add lib/*.{h,c}.
+
+2020-08-31 Stefan Kangas <stefankangas@gmail.com>
+
+ Fix minibuffer default of ephemeral debbugs group
+
+ * lisp/gnus/gnus-group.el (gnus-group--read-bug-ids): Don't read
+ number in "bug-123" as a negative bug ID; they are always positive.
+
+2020-08-31 Stefan Kangas <stefankangas@gmail.com>
+
+ Fix typo in Introduction to Emacs Lisp
+
+ * doc/lispintro/emacs-lisp-intro.texi (type-of-animal in detail):
+ Remove extraneous parenthesis.
+
+2020-08-31 Alan Third <alan@idiocy.org>
+
+ * .gitlab-ci.yml (test-all): Change .m to .c for standard C files.
+
+2020-08-31 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/alloc.c (live_symbol_holding): Pacify gcc -Wlogical-op.
+
+ * src/lisp.h (lisp_h_XPL, XPL): Remove; unused.
+
+2020-08-31 Paul Eggert <eggert@cs.ucla.edu>
+
+ Use mark_objects elsewhere too
+
+ * src/alloc.c (mark_vectorlike, mark_face_cache):
+ * src/eval.c (mark_specpdl):
+ * src/fringe.c (mark_fringe_data):
+ * src/keyboard.c (mark_kboards):
+ Use mark_objects instead of doing it by hand.
+
+2020-08-31 Paul Eggert <eggert@cs.ucla.edu>
+
+ Remove mark_maybe_object
+
+ * src/alloc.c (mark_maybe_object, mark_maybe_objects): Remove.
+ (mark_objects): New function.
+ * src/eval.c (mark_specpdl): Use mark_objects instead of
+ mark_maybe_objects, since the array now has only valid Lisp objects.
+ * src/lisp.h (SAFE_ALLOCA_LISP_EXTRA): When allocating a large
+ array, clear it so that it contains only valid Lisp objects. This
+ is simpler and safer, and does not hurt performance significantly
+ on my usual benchmark as the code is executed so rarely.
+
+2020-08-31 Paul Eggert <eggert@cs.ucla.edu>
+
+ Avoid some false matches in mark_maybe_pointer
+
+ This lets Emacs avoid marking some garbage as if it were in use.
+ On one test platform (RHEL 7.8, Intel Xeon Silver 4116) it
+ sped up ‘cd lisp; make compile-always’ by a bit over 1%.
+ * src/alloc.c (live_string_holding, live_cons_holding)
+ (live_symbol_holding, live_large_vector_holding)
+ (live_small_vector_holding):
+ Count only pointers that point to a struct component,
+ or are a tagged pointer to the start of the struct.
+ Exception: for non-bool-vector pseudovectors,
+ count any pointer past the header, since it’s too much
+ of a pain to write code for every pseudovector.
+ (live_vector_pointer): New function.
+
+2020-08-31 Paul Eggert <eggert@cs.ucla.edu>
+
+ Omit no-longer-needed stack mark_maybe_object
+
+ * src/alloc.c (mark_memory): Do not bother using mark_maybe_object
+ on the stack, since mark_maybe_pointer now marks everything that
+ mark_maybe_object would.
+
+2020-08-31 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix GC bug with Lisp floats and --with-wide-int
+
+ On --with-wide-int platforms where Lisp_Object can be
+ put into non-adjacent registers, mark_maybe_pointer failed
+ to mark a float whose only reference was as a tagged pointer.
+ * src/alloc.c (live_float_holding): New function,
+ a generalization of the old live_float_p.
+ (live_float_p): Use it.
+ (mark_maybe_pointer): Use live_float_holding, not live_float_p.
+
+2020-08-31 Stefan Kangas <stefankangas@gmail.com>
+
+ Update Elisp Manual reference to which-function-mode
+
+ * doc/lispref/modes.texi (Mode Line Top, Mode Line Variables)
+ Don't refer to obsolete alias for 'which-function-mode'.
+ (Bug#13716)
+
+2020-08-30 Stefan Kangas <stefankangas@gmail.com>
+
+ Bind 'n' and 'p' in compilation-mode-map
+
+ * lisp/progmodes/compile.el (compilation-mode-map): Bind
+ '(next|previous)-error-no-select' to 'n' and 'p'. (Bug#41844)
+
+2020-08-30 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in life.el and add tests
+
+ * lisp/play/life.el: Use lexical-binding.
+ (life--tick): Extract from...
+ (life): ...here.
+ (life--max-width, life--max-height): New variables.
+ (life-mode, life-setup): Use above variables.
+
+ * test/lisp/play/life-tests.el: New file.
+
+2020-08-30 Stefan Kangas <stefankangas@gmail.com>
+
+ Various life.el improvements
+
+ * lisp/play/life.el (life): New defgroup.
+ (life-step-time): New defcustom (lower default from 1 to 0.5).
+ (life): Use above new variable. Make prefix arguments set step time
+ in tenths of a second instead of whole seconds.
+ (life-expand-plane-if-needed): Rename argument to step-time.
+
+ (life-setup): Fix running `M-x life' with existing buffer.
+
+ (life-patterns): Add three more classic patterns.
+
+2020-08-30 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove some XEmacs compat code from gamegrid.el
+
+ * lisp/play/gamegrid.el (gamegrid-setup-face): Remove XEmacs
+ compat code.
+
+2020-08-30 Stefan Kangas <stefankangas@gmail.com>
+
+ * lisp/play/tetris.el: Use lexical-binding.
+
+2020-08-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak background colours in shr when there's indentation
+
+ * lisp/net/shr.el (shr-fill-line): Get the background colour right
+ for the indentation, too.
+
+2020-08-30 Mauro Aranda <maurooaranda@gmail.com>
+
+ Respect :must-match for file types in customization buffers
+
+ * lisp/wid-edit.el (file widget): Add a :match and a :validate
+ function to the 'file widget, to be able to check if the widget
+ value is an existent file, when required (bug#25678).
+
+2020-08-30 João Távora <joaotavora@gmail.com>
+
+ Place flymake-eldoc-function at the end of eldoc-documentation-functions
+
+ Having it placed in the beginning of that hook meant it was mostly
+ impossible to track the args to a function call while writing it from
+ scratch, since most compilers issue a diagnostic about incorrect
+ number of arguments.
+
+ See bug#43103.
+
+ * lisp/progmodes/flymake.el (flymake-mode): Lower priority of
+ flymake-eldoc-function.
+
+2020-08-30 Michael Albinus <michael.albinus@gmx.de>
+
+ Some precisions to bug handling
+
+ * admin/admin.el (reminder-for-release-blocking-bugs): Add date to subject.
+
+ * admin/notes/bug-triage:
+ * admin/notes/bugtracker: Minor precisions.
+
+2020-08-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make format-prompt interpret a nil default value as "no default"
+
+ * doc/lispref/minibuf.texi (Text from Minibuffer): Document it.
+
+ * lisp/help-fns.el (describe-function): Adjust the caller.
+
+ * lisp/minibuffer.el (format-prompt): Interpret a nil default
+ value as "no default".
+
+2020-08-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix compilation warning in snake.el
+
+ * lisp/play/snake.el (snake-reset-game): Avoid warning about
+ unused variable.
+
+2020-08-30 Michael Albinus <michael.albinus@gmx.de>
+
+ * .gitlab-ci.yml (test-all): Run only when needed.
+
+2020-08-30 Andrea Corallo <akrl@sdf.org>
+
+ Store raw documentation during native compilation (bug#42974)
+
+ * lisp/emacs-lisp/comp.el (comp-spill-lap-function)
+ (comp-intern-func-in-ctxt): Use raw documentation.
+
+2020-08-30 Stefan Kangas <stefankangas@gmail.com>
+
+ Convert manual rmailmm tests to ert
+
+ * test/manual/rmailmm.el: Move from here...
+ * test/lisp/mail/rmailmm-tests.el: ...to here, and convert to ert.
+
+2020-08-29 Stefan Kangas <stefankangas@gmail.com>
+
+ Convert unsafep tests to ert
+
+ * lisp/emacs-lisp/tcover-unsafep.el: Move from here...
+ * test/lisp/emacs-lisp/unsafep-tests.el: ...to here, and convert to
+ use ert instead of tcover.
+
+2020-08-29 Stefan Kangas <stefankangas@gmail.com>
+
+ * lisp/play/snake.el: Use lexical-binding.
+
+2020-08-29 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in more tests
+
+ * test/lib-src/emacsclient-tests.el:
+ * test/lisp/emacs-lisp/hierarchy-tests.el:
+ * test/lisp/eshell/eshell-tests.el:
+ * test/lisp/gnus/gnus-util-tests.el:
+ * test/lisp/progmodes/js-tests.el:
+ * test/lisp/textmodes/bibtex-tests.el:
+ * test/src/editfns-tests.el:
+ * test/src/fns-tests.el: Use lexical-binding.
+
+ * test/lisp/emacs-lisp/hierarchy-tests.el
+ (hierarchy-leafs-includes-lonely-roots):
+ * test/src/editfns-tests.el (transpose-test-get-byte-positions):
+ * test/src/fns-tests.el (fns-tests-func-arity):
+ Adjust for lexical-binding.
+
+2020-08-29 Paul Eggert <eggert@cs.ucla.edu>
+
+ Mark failing fileio test on MS-Windows
+
+ * test/src/fileio-tests.el (fileio-tests--HOME-trailing-slash):
+ Expect failure on MS-Windows.
+
+2020-08-29 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Fix processing for when c-multiline-string-start-char is a character
+
+ * lisp/progmodes/cc-mode.el (c-pps-to-string-delim)
+ (c-multiline-string-check-final-quote): Replace c-clear-char-property by
+ c-clear-syn-tab.
+ (c-multiline-string-check-final-quote): Replace c-put-char-property by
+ c-put-syn-tab.
+
+2020-08-29 Alan Third <alan@idiocy.org>
+
+ Run GNUstep build test more often
+
+ * .gitlab-ci.yml (test-gnustep): Include more files that may affect
+ the GNUstep build.
+
+2020-08-29 Stefan Kangas <stefankangas@gmail.com>
+
+ * lisp/mail/mspools.el: Remove redundant :group args.
+
+2020-08-29 Andrea Corallo <akrl@sdf.org>
+
+ * test/src/comp-tests.el (comp-tests-doc): Update test.
+
+ * lisp/startup.el (command-line): Clean-up logic for new .eln disposition.
+
+2020-08-29 Andrea Corallo <akrl@sdf.org>
+
+ Have .elc files in `load-history' when loading native code (bug#43089)
+
+ * src/lread.c (Fload): Add the corresponding .elc file to
+ `load-history' when loading native code.
+
+ * lisp/subr.el (eval-after-load): Use `load-file-name' instead of
+ `load-true-file-name'.
+
+2020-08-29 João Távora <joaotavora@gmail.com>
+
+ Prevent ElDoc blinking when eldoc-documentation-enthusiast is used
+
+ This eldoc-documentation-strategy function didn't always obey protocol
+ since it returned nil sometimes, which the eldoc engine took it as a
+ hint for the "old" protocol to clear the echo area.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-documentation-enthusiast):
+ Return t.
+ (Version): Bump to 1.9.0
+
+2020-08-29 Andrea Corallo <akrl@sdf.org>
+
+ Back using `load-file-name' when reading '#$' (bug#42961)
+
+ * src/lread.c (read1, read_list): Use again load-file-name when
+ reading '#$'.
+ (syms_of_lread): Update `load-file-name' doc.
+
+2020-08-29 Ulrich Müller <ulm@gentoo.org>
+
+ Delete duplicate definition for koi8-u coding system
+
+ * lisp/language/cyrillic.el (koi8-u): Delete duplicate definition.
+
+2020-08-29 Mattias Engdegård <mattiase@acm.org>
+
+ * test/lisp/emacs-lisp/rx-tests.el: Improve test coverage.
+
+2020-08-29 Andrea Corallo <akrl@sdf.org>
+
+ * src/lread.c (Fload): Bind load-file-name to the .elc filename.
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-08-29 Eli Zaretskii <eliz@gnu.org>
+
+ Fix description of %-constructs in 'mode-line-format'
+
+ * doc/lispref/modes.texi (%-Constructs): Document %@ and remove
+ %M, which is no longer supported. (Bug#43092)
+
+2020-08-29 Paul Eggert <eggert@cs.ucla.edu>
+
+ Revert recent expand-file-name changes if DOS_NT
+
+ * src/fileio.c (Fexpand_file_name): Restore pre-August-26
+ behavior, if DOS_NT. This should fix the recently-introduced
+ expand-file-name bugs on DOS_NT (Bug#26911).
+
+2020-08-29 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/fileio.c (Fexpand_file_name): Omit unnecessary assignment.
+
+2020-08-29 Andrew G Cohen <cohen@andy.bu.edu>
+
+ Allow direct choice of smtp authentication method
+
+ * lisp/mail/smtpmail.el (smtpmail-try-auth-methods): Let the
+ authorization credentials have an entry with key :smtp-auth containing
+ a preferred authentication mechanism.
+
+2020-08-28 Alan Third <alan@idiocy.org>
+
+ Fix Objective-C C99 build problem
+
+ * configure.ac (NS_IMPL_GNUSTEP): GCC appears to need to be told to
+ use C99 when compiling Objective-C.
+
+2020-08-28 Alan Third <alan@idiocy.org>
+
+ Add GNUstep build to Gitlab CI/CD
+
+ * .gitlab-ci.yml (test-gnustep): New test target.
+
+2020-08-28 Daniel Martín <mardani29@yahoo.es>
+
+ Add support for parsing column numbers in Visual Studio messages
+
+ * lisp/progmodes/compile.el (compilation-error-regexp-alist-alist):
+ Extend regular expression to match optional column numbers.
+ *
+ test/lisp/progmodes/compile-tests.el (compile-tests--test-regexps-data):
+ Add a test.
+ * test/lisp/progmodes/compile-tests.el (compile-test-error-regexps):
+ Update the total number of compilation errors in a test.
+ * etc/compilation.txt: Update compilation.txt with the newly supported
+ message format.
+ * etc/NEWS: Advertise the feature.
+
+2020-08-28 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Bug#43052
+
+ * test/lisp/net/tramp-tests.el (tramp-test04-substitute-in-file-name):
+ Make user name unique. (Bug#43052)
+
+2020-08-28 Stefan Kangas <stefankangas@gmail.com>
+
+ Add commands to run shell commands in project root
+
+ * lisp/progmodes/project.el (project-async-shell-command)
+ (project-shell-command): New commands to run 'async-shell-command'
+ and 'shell-command' in project's root directory.
+ (project-prefix-map): Bind commands to '!' and '&'.
+ * doc/emacs/maintaining.texi (Project File Commands): Document the
+ new commands.
+ * etc/NEWS: Announce the new commands.
+
+2020-08-28 Stefan Kangas <stefankangas@gmail.com>
+
+ Make XEmacs compat aliases obsolete in warnings.el
+
+ * lisp/emacs-lisp/warnings.el (display-warning-minimum-level)
+ (log-warning-minimum-level): Make XEmacs compat aliases into obsolete
+ aliases for 'warning-minimum-level' and 'warning-minimum-log-level'.
+
+2020-08-28 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in warnings.el and add tests
+
+ * lisp/emacs-lisp/warnings.el: Use lexical-binding.
+ Remove redundant :group args.
+
+ * test/lisp/emacs-lisp/warnings-tests.el: New file.
+
+2020-08-28 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ New eieio-persistent-make-instance generic function
+
+ This allows override of the read process for eieio-persistent objects,
+ providing the possibility of matching read/write customization for
+ eieio-persistent subclasses.
+
+ * lisp/emacs-lisp/eieio-base.el (eieio-persistent-make-instance): New
+ generic function for constructing instances from object data written
+ to disk. Previously known as eieio-persistent-convert-list-to-object.
+
+2020-08-28 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Remove redundant slot validation in eieio-persistent-read
+
+ Actual object creation (in `make-instance') will later run all slot
+ values through cl-typep, which does a better job of validation. This
+ validation is redundant, and slows the read process down.
+
+ * lisp/emacs-lisp/eieio-base.el (eieio-persistent-fix-value): Rename
+ from `eieio-persistent-validate/fix-slot-value', as we no longer
+ validate, and we don't care about the slot definition.
+ (eieio-persistent-slot-type-is-class-p): Delete function.
+ (eieio-persistent-convert-list-to-object): Still call
+ `eieio--full-class-object', to trigger an autoload if necessary, but
+ discard the return value.
+
+2020-08-28 Harald Jörg <haj@posteo.de>
+
+ Fix indent-region for identifiers with underscores in cperl-mode
+
+ * lisp/progmodes/cperl-mode.el (cperl-fix-line-spacing): Fix Bug#18985.
+ Hash keys or function names starting with a Perl keyword followed
+ by an underscore (as in "for_me" are no longer split into two words
+ by M-x indent-region.
+
+2020-08-28 Stefan Kangas <stefankangas@gmail.com>
+
+ * lisp/mwheel.el: Improve package description.
+
+2020-08-28 Mattias Engdegård <mattiase@acm.org>
+
+ * test/src/fileio-tests.el: Preserve HOME when a test fails
+
+2020-08-28 Eli Zaretskii <eliz@gnu.org>
+
+ Fix most of fileio-tests on MS-Windows
+
+ * test/src/fileio-tests.el (fileio-tests--HOME-trailing-slash)
+ (fileio-tests--expand-file-name-trailing-slash): Account for drive
+ letters in MS-Windows/MS-DOS file names. (Bug#26911)
+
+2020-08-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix recently-introduced expand-file-name bug
+
+ The bug was that (expand-file-name "~") returned something
+ like "/home/eggert/" instead of "/home/eggert".
+ Problem reported by Mattias Engdegård (Bug#26911#27).
+ * src/fileio.c (Fexpand_file_name): When concatenating NEWDIR to
+ NM, instead of stripping trailing slashes from NEWDIR (which can
+ turn non-symlinks into symlinks), strip leading slashes from NM.
+ This also simplifies the code by removing no-longer-needed DOS_NT
+ special-casing. Also, remove an unnecessary ‘target[length] = 0;’
+ as that byte will be overwritten by the next memcpy anyway.
+ * test/src/fileio-tests.el (fileio-tests--HOME-trailing-slash):
+ New test.
+
+2020-08-27 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Set Gnus server 'closed status in gnus-close-server
+
+ * lisp/gnus/gnus-int.el (gnus-close-server): Set 'closed status here.
+ * lisp/gnus/gnus-group.el (gnus-group-suspend): Not here.
+
+2020-08-27 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Switch Gnus D-Bus signal from :session to :system
+
+ * lisp/gnus/gnus-dbus.el (gnus-dbus-register-sleep-signal): Apparently
+ this needs to be :system -- perhaps because PrepareForSleep is a
+ system-level event?
+
+2020-08-27 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt tramp-tests
+
+ * test/lisp/net/tramp-tests.el (tramp-test05-expand-file-name)
+ (tramp-test05-expand-file-name-relative): Adapt tests.
+
+2020-08-27 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt tramp-tests.el, don't merge with master
+
+ * test/lisp/net/tramp-tests.el (tramp-test05-expand-file-name)
+ (tramp-test05-expand-file-name-relative): Adapt tests.
+ (tramp--test-emacs28-p): New defun.
+
+2020-08-27 Mauro Aranda <maurooaranda@gmail.com>
+
+ Keep the user theme in sync when marking a variable as set
+
+ * lisp/custom.el (customize-mark-as-set): Keep the user theme in sync
+ even if the new value of the variable is the saved-value or the
+ standard-value. If we don't do this, custom themes might end up
+ stepping over the user preferences in a session (bug#28904).
+
+2020-08-27 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make minibuf-eldef respect minibuffer-default-prompt-format
+
+ * lisp/minibuf-eldef.el (minibuffer-default--in-prompt-regexps):
+ Take minibuffer-default-prompt-format into account.
+
+2020-08-27 Stefan Kangas <stefankangas@gmail.com>
+
+ Substitute command keys in display-local-help
+
+ * lisp/help-at-pt.el (display-local-help): Pass 'help-echo' property
+ through 'substitute-command-keys' before displaying to be consistent
+ with tooltips. (Bug#37628)
+
+ This was discussed in:
+ https://lists.gnu.org/archive/html/emacs-devel/2019-10/msg00090.html
+
+2020-08-27 Stephen Berman <stephen.berman@gmx.net>
+
+ Prevent spurious tabs by RET in todo-edit-mode (bug#43068)
+
+ * lisp/calendar/todo-mode.el (todo-key-bindings-t)
+ (todo-edit-mode-map): Remove remapping of `newline' to
+ `newline-and-indent'.
+ (todo-modes-set-1): Remove local setting of `indent-line-function'.
+ (todo-edit-mode): Locally set `indent-line-function' to `todo-indent'.
+
+ * test/lisp/calendar/todo-mode-tests.el (todo-test-move-item05):
+ Prevent interactive test failure. (Until the addition of testcat4
+ to todo-test-1.todo, the test passed by chance, since testcat3 is
+ empty and has no archived items.)
+ (todo-test-edit-item-date-month): Refer to bug number.
+ (todo-test-multiline-item-indentation-1)
+ (todo-test-multiline-item-indentation-2)
+ (todo-test-multiline-item-indentation-3): New tests.
+
+ * test/lisp/calendar/todo-mode-resources/todo-test-1.todo: Remove
+ spurious tabs from testcat1.
+
+2020-08-27 Stefan Kangas <stefankangas@gmail.com>
+
+ Minor clean up in flyspell.el
+
+ * lisp/textmodes/flyspell.el (flyspell-buffers): Declare obsolete.
+ (flyspell--prev-meta-tab-binding): Doc fix.
+
+2020-08-27 Tino Calancha <tino.calancha@gmail.com>
+
+ dired: Show broken/circular links w/ different face
+
+ * lisp/dired.el (dired-broken-symlink): New face.
+ (dired-font-lock-keywords):
+ Use it for broken/circular links (Bug#39145).
+
+ * etc/NEWS (Changes in Specialized Modes and Packages in Emacs 28.1):
+ Announce this change.
+
+2020-08-27 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt reminder-for-release-blocking-bugs
+
+ * admin/admin.el (reminder-for-release-blocking-bugs):
+ Require `debbugs-gnu' also in `interactive' form.
+
+ * admin/release-process: Rename RELEASE-CRITICAL to RELEASE-BLOCKING.
+ Adapt Emacs version. Describe `reminder-for-release-blocking-bugs'.
+
+2020-08-27 Stefan Kangas <stefankangas@gmail.com>
+
+ Only show flyspell welcome message interactively
+
+ * lisp/textmodes/flyspell.el (flyspell-mode): Only show welcome
+ message when called interactively. (Bug#43065)
+
+2020-08-27 Stefan Kangas <stefankangas@gmail.com>
+
+ Add ASTEC-X issue to PROBLEMS
+
+ * etc/PROBLEMS: Mention problem with multiple monitors on proprietary
+ X Server ASTEC-X. (Bug#36779)
+
+2020-08-27 Stefan Kangas <stefankangas@gmail.com>
+
+ Fix flyspell welcome message
+
+ * lisp/textmodes/flyspell.el (flyspell-mode, flyspell-mode-on):
+ Fix showing welcome message when `flyspell-issue-welcome-flag' and
+ `flyspell-issue-message-flag' are both non-nil. (Bug#43065)
+
+2020-08-27 Andrew G Cohen <cohen@andy.bu.edu>
+
+ Allow a function for the :secret in a plstore
+
+ * lisp/auth-source.el (auth-source-plstore-search): If the :secret
+ value is a function, call it on plist to obtain the real password.
+
+2020-08-27 Stefan Kangas <stefankangas@gmail.com>
+
+ Refer to correct mouse button in flyspell message
+
+ * lisp/textmodes/flyspell.el (make-flyspell-overlay)
+ (flyspell-mode-on): Refer to mouse-3 in help messages when the
+ variable 'flyspell-use-mouse-3-for-menu' is non-nil. (Bug#11680)
+
+2020-08-27 Stefan Kangas <stefankangas@gmail.com>
+
+ Signal error on Hunspell installation problem
+
+ * lisp/textmodes/ispell.el (ispell-find-hunspell-dictionaries):
+ Signal user-error when Hunspell warns that it "Can't open affix or
+ dictionary files", and propagate this message. (Bug#25825)
+
+2020-08-27 Protesilaos Stavrou <info@protesilaos.com>
+
+ Add themes modus-operandi and modus-vivendi
+
+ * etc/themes/modus-operandi-theme.el:
+ * etc/themes/modus-vivendi-theme.el: New themes. (Bug#43019)
+
+2020-08-27 Stefan Kangas <stefankangas@gmail.com>
+
+ Sort Info index completions alphabetically
+
+ * lisp/info.el (Info-complete-menu-item): Sort the list of completions
+ alphabetically using 'nreverse'. This makes no difference for Emacs
+ but helps third-party completion frameworks such as Ivy. (Bug#38614)
+
+ Suggested by Howard Melman <hmelman@gmail.com>.
+
+2020-08-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ Unbreak dired-do-find-regexp in Emacs 26
+
+ * lisp/progmodes/xref.el (xref--show-xrefs):
+ Support the old convention (bug#42967).
+
+2020-08-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ Unbreak xref-goto-xref in Emacs 26
+
+ * lisp/progmodes/xref.el (xref-goto-xref):
+ Call next-error-found only if it's defined (bug#42981).
+
+2020-08-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix expand-file-name symlink-to-dir bug
+
+ Problem reported by Yegor Timoshenko (Bug#26911),
+ and I ran into it myself recently in normal-top-level.
+ * doc/lispref/files.texi (File Name Expansion), etc/NEWS: Mention this.
+ * src/fileio.c (Fexpand_file_name): Expand "/a/b/." to "/a/b/" not
+ "/a/b", to avoid misinterpreting a symlink "/a/b". Similarly,
+ expand "/a/b/c/.." to "/a/b/" not "/a/b".
+ * test/lisp/net/tramp-tests.el (tramp-test05-expand-file-name):
+ Adjust to match new behavior.
+ (tramp-test05-expand-file-name-relative): This test now succeeds,
+ at least on Fedora 31.
+ * test/src/fileio-tests.el:
+ (fileio-tests--expand-file-name-trailing-slash) New test.
+
+2020-08-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix PWD startup checking with symlinks
+
+ * lisp/startup.el (normal-top-level): Do not put "." after "/";
+ it’s not needed and with current file-name-as-directory it does
+ the wrong thing if PWD is a symlink.
+
+2020-08-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ * lisp/files.el (insert-directory): Simplify (if ... X X) to X.
+
+2020-08-26 Andrea Corallo <akrl@sdf.org>
+
+ Merge branch 'add_driver_option' into HEAD
+
+2020-08-26 Andrea Corallo <akrl@sdf.org>
+
+ Init gcc_jit_context_add_driver_option as optional
+
+ * src/comp.c (init_gccjit_functions): Use LOAD_DLL_FN_OPT to init
+ 'gcc_jit_context_add_driver_option' as this is optional.
+
+2020-08-26 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-native-driver-options-available-p
+
+ * src/comp.c (Fcomp_native_driver_options_effective_p)
+ Rename plus better doc.
+ (add_driver_options, syms_of_comp): Rename
+ `comp-native-driver-options-available-p' into
+ comp-native-driver-options-effective-p.
+
+2020-08-26 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (add_driver_options): Fix missing condition + clean-up pragma
+
+2020-08-26 Andreas Fuchs <asf@boinkor.net>
+
+ * Add 'comp-native-driver-options-available-p'
+
+ * src/comp.c (comp-native-driver-options-available-p): New
+ function that returns t if driver options can be used.
+
+2020-08-26 Andrea Corallo <akrl@sdf.org>
+
+ Improve 'add_driver_options'
+
+ * src/comp.c (add_driver_options): Use
+ load_gccjit_if_necessary and FOR_EACH_TAIL + GNU style.
+
+2020-08-26 Andreas Fuchs <asf@boinkor.net>
+
+ Fix windows NT handling for [...]_add_driver_options
+
+ * src/comp.c (add_driver_options): Instead of conditionalizing on
+ the wrong preprocessor flag, now use the right one:
+ 'LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option'. Also perform
+ the driver-option-adding step on win NT, but only if the function
+ is non-NULL. Make the function declaration for add_driver_options
+ non-old-style.
+
+2020-08-26 Andreas Fuchs <asf@boinkor.net>
+
+ Set native driver options in async compiles, also
+
+ Ensure the variable is set to the value that was customized in the
+ parent process in child compilation processes, also.
+
+2020-08-26 Stefan Kangas <stefankangas@gmail.com>
+
+ Sync latest SKK-JISYO.L
+
+ * leim/SKK-DIC/SKK-JISYO.L: Sync to current upstream version.
+
+2020-08-26 leo <gnu_lists@halloleo.hailmail.net> (tiny change)
+
+ Allow disabling double buffering at build time
+
+ * configure.ac: Allow disabling double buffering (bug#32032).
+
+2020-08-26 Robert Pluim <rpluim@gmail.com>
+
+ Allow directories to be called .el in -add-subdirs-to-load-path
+
+ * lisp/startup.el (normal-top-level-add-subdirs-to-load-path):
+ Allow the directories to be called "<foo>.el" (bug#32266).
+
+2020-08-26 Glenn Morris <rgm@gnu.org>
+
+ Fix doc-view problem with file names with spaces in them
+
+ * lisp/doc-view.el (doc-view-get-bounding-box): Don't bug out on
+ file names with spaces in them (bug#33344).
+
+2020-08-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use format-prompt a couple of places
+
+ * lisp/ps-print.el (ps-print-preprint):
+ * lisp/help-fns.el (describe-function): Use `format-prompt'
+ (bug#12443).
+
+2020-08-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Implement a way to customize "default" values
+
+ * doc/lispref/minibuf.texi (Text from Minibuffer): Document them.
+
+ * lisp/minibuffer.el (format-prompt): New function (bug#12443).
+ (minibuffer-default-prompt-format): New variable.
+
+2020-08-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the epa key display slightly more informative
+
+ * lisp/epa.el (epa--button-key-text): Say what the validity
+ characters output by GPG mean (bug#34726).
+
+2020-08-26 Štěpán Němec <stepnem@gmail.com>
+
+ Document ispell comment/string checking commands in the user manual
+
+ * doc/emacs/fixit.texi (Spelling): Mention
+ 'ispell-comments-and-strings' and 'ispell-comment-or-string-at-point'.
+ (bug#6411)
+
+2020-08-26 Štěpán Němec <stepnem@gmail.com>
+
+ ispell: Commands to check comments or strings at point or in region
+
+ * lisp/textmodes/ispell.el (ispell-comments-and-strings): Accept START
+ and END arguments, defaulting to active region in interactive calls.
+ (ispell-comment-or-string-at-point): New command. (bug#6411)
+
+2020-08-26 Noam Postavsky <npostavs@gmail.com>
+
+ Don't recommend redefining auto-save filename functions
+
+ * doc/lispref/backups.texi (Auto-Saving): Document
+ auto-save-file-name-transforms.
+ * lisp/files.el (make-auto-save-file-name)
+ (auto-save-file-name-p): Remove suggestion to redefine for
+ customization (bug#34911).
+
+2020-08-26 Phil Sainty <psainty@orcon.net.nz>
+
+ term.el: Use correct exit status in suggested dir-tracking functions
+
+ * lisp/term.el: Make some of the examples better (bug#43055).
+
+2020-08-26 Brian Leung <leungbk@mailfence.com> (tiny change)
+
+ eshell: Remove unnecessary check in em-hist
+
+ * lisp/eshell/em-hist.el
+ (eshell-previous-matching-input-string-position): Both before and
+ within the while loop, n is always smaller than n (bug#43056).
+
+2020-08-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove side-effect-free markup for assoc-default
+
+ * lisp/subr.el (assoc-default): assoc-default isn't
+ side-effect-free, because it takes a :test parameter that can do
+ anything (bug#37943).
+
+2020-08-26 Mattias Engdegård <mattiase@acm.org>
+
+ Fix lexical misunderstandings in gnus-icalendar-tests.el (bug#39782)
+
+ * test/lisp/gnus/gnus-icalendar-tests.el:
+ (icalendar-tests--get-ical-event): Remove unused function accidentally
+ copy-pasted from icalendar-tests.el.
+ (gnus-icalendar-parse, gnus-icalendary-byday):
+ Remove unintended initial newlines.
+ Duplicate comma-escaping backslashes so that they have intended
+ effects, conforming to RFC 5545.
+ Remove ineffective comma-escaping backslashes where not intended.
+
+2020-08-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ regex-emacs: copy less when reallocating
+
+ * src/regex-emacs.c (GROW_FAIL_STACK): Copy just the
+ occupied stack slots, as the rest are garbage.
+
+2020-08-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ regex-emacs: fix leak on memory allocation failure
+
+ * src/regex-emacs.c (ENSURE_FAIL_STACK): If the failure
+ stack cannot be grown, free locally-allocated storage
+ before returning.
+
+2020-08-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ regex-emacs: subscript-check register numbers
+
+ * src/regex-emacs.c (PUSH_FAILURE_REG, POP_FAILURE_REG_OR_COUNT)
+ (re_match_2_internal): Add some easserts for subscript checking.
+
+2020-08-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ regex-emacs: omit regstart tests and regend set
+
+ * src/regex-emacs.c (PUSH_FAILURE_REG, POP_FAILURE_REG_OR_COUNT)
+ (re_match_2_internal): Add some assertions that regstart
+ is set whenever regend is.
+ (re_match_2_internal): Omit two unnecessary REG_UNSET (regstart ...)s
+ and one unnecessary assignment to regend.
+
+2020-08-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ regex-emacs omit allocation of 3 slots
+
+ * src/regex-emacs.c (re_match_2_internal): Avoid
+ unnecessary allocation of REGEND[0], BEST_REGSTART[0],
+ BEST_REGEND[0].
+
+2020-08-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ regex-emacs omit POS runtime check
+
+ * src/regex-emacs.c (re_match_2_internal): Replace unnecessary
+ runtime check of POS with some eassumes.
+
+2020-08-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix gpg2-related test failures on RHEL 7.8
+
+ * test/lisp/gnus/mml-sec-tests.el (test-conf)
+ (mml-secure-en-decrypt-passphrase-no-cache-openpgp-todo)
+ (mml-secure-run-tests-with-gpg2):
+ Use epg-find-configuration instead of the obsolescent
+ epg-configuration. This fixes test failures on RHEL 7.8,
+ where ‘gpg’ and ‘gpg2’ are both 2.0.22.
+
+2020-08-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ mml-secure-en-decrypt-sign-1-2-double is unstable
+
+ * test/lisp/gnus/mml-sec-tests.el:
+ (mml-secure-en-decrypt-sign-1-2-double): Mark this as unstable.
+
+2020-08-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-08-25 verify: Avoid warnings when assume(0) is used
+ * lib/verify.h: Copy from Gnulib.
+
+2020-08-26 Stefan Kangas <stefankangas@gmail.com>
+
+ Add package prefix to jsonrpc defconst
+
+ * lisp/jsonrpc.el (jsonrpc-default-request-timeout): Rename from
+ 'jrpc-default-request-timeout'.
+ (jrpc-default-request-timeout): Make into obsolete variable alias
+ for 'jsonrpc-default-request-timeout'. (Bug#40054)
+
+2020-08-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ Omit "V" at the start of DEFVAR_BOOL vars
+
+ Problem noted by Stefan Monnier in:
+ https://lists.gnu.org/r/emacs-devel/2020-08/msg00846.html
+ * src/font.c (xft_ignore_color_fonts):
+ * src/syntax.c (comment_end_can_be_escaped):
+ * src/xdisp.c (word_wrap_by_category, display_fill_column_indicator):
+ Rename these DEFVAR_BOOL variables to avoid the initial "V"
+ that wrongly suggests that they are Lisp_Object variables.
+ All uses changed.
+
+2020-08-25 Daniel Colascione <dancol@dancol.org>
+
+ Add undefine keyword to make-mode
+
+ * lisp/progmodes/make-mode.el (makefile-gmake-statements): Add
+ "undefine" to the list of gmake keywords
+
+2020-08-25 Stefan Kangas <stefankangas@gmail.com>
+
+ Add "Delete" submenu to Dired "Operate" menu
+
+ * lisp/dired.el (dired-mode-map): Add "Delete" submenu to "Operate"
+ menu with an entry for 'dired-do-flagged-delete'. (Bug#41524)
+
+2020-08-25 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Add basic D-Bus integration to Gnus
+
+ * lisp/gnus/gnus-dbus.el: New library, registering a signal that
+ closes all Gnus servers when the system is going to sleep.
+ * lisp/gnus/gnus-start.el: Check new option
+ `gnus-dbus-close-on-sleep', and register the appropriate D-Bus signal
+ if it is non-nil.
+ * lisp/gnus/gnus.el: New gnus-dbus customization group.
+ * doc/misc/gnus.texi: Document.
+
+2020-08-25 Štěpán Němec <stepnem@gmail.com>
+
+ Preserve setf semantics in 'substring', 'cons', 'logand' expanders
+
+ * doc/lispref/variables.texi (Adding Generalized Variables): Fix example.
+ * lisp/emacs-lisp/cl-lib.el (substring)
+ * lisp/emacs-lisp/gv.el (cons, logand): Return the value being
+ assigned, as specified for 'setf'. (bug#35546)
+
+2020-08-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak the file/buffer comparison from previous save-some-buffers change
+
+ * lisp/files.el (save-some-buffers): Relax the "similarity" regexp
+ from the previous regexp: Don't show both file and buffer names if
+ the file is /tmp/foo and the buffer name is foo<zot>.
+
+2020-08-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with folded Gcc headers in Gnus
+
+ * lisp/gnus/gnus-msg.el (gnus-inews-do-gcc): Tokenize the gcc
+ header properly (there may be newlines and tabs in the separators)
+ (bug#43036).
+
+2020-08-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Possibly mention both file and buffer names in save-some-buffers
+
+ * lisp/files.el (save-some-buffers): If the file and buffer names
+ are dissimilar, mention both their names (bug#8399).
+
+2020-08-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't bug out in gnus-icalendar when there no recurring event
+
+ * lisp/gnus/gnus-icalendar.el
+ (gnus-icalendar-event:recurring-days): Fix previous patch
+ (bug#43038) -- don't bug out when there's no recurring event.
+
+2020-08-25 Michael Albinus <michael.albinus@gmx.de>
+
+ * admin/admin.el (reminder-for-release-blocking-bugs): New command.
+
+2020-08-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ remove-overlays doc clarification
+
+ * lisp/subr.el (remove-overlays): Doc fix (bug#13648).
+
+2020-08-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Doc fix for copy-directory
+
+ * lisp/files.el (copy-directory): PARENTS is no longer the last
+ argument.
+
+2020-08-25 Michael Albinus <michael.albinus@gmx.de>
+
+ Merge from origin/emacs-27
+
+ 44104a607a Fix error in GMP test
+ e26e63444d Add Feature testing for Windows binaries
+ 4e2caef384 ; * src/character.c (str_as_multibyte): Fix the commentary.
+ d3a4ce8420 Revert "; * etc/NEWS: Remove temporary note on documentati...
+ 16f00e36dc * admin/admin.el (set-version): Trap yet another NEWS error.
+ 121be3e118 ; * etc/NEWS: Remove temporary note on documentation. (Bu...
+ 5fcb97dabd Fix cond jump table compilation (bug#42919)
+
+2020-08-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Extend background colours in shr
+
+ * lisp/net/shr.el (shr-colorize-region): Extend backgrounds to the
+ end (bug#43031). This avoid ragged edges to the right when, for
+ instance, the <body> has a bgcolor.
+ (shr-face-background): Ditto.
+
+2020-08-25 Stephen Berman <stephen.berman@gmx.net>
+
+ Tweak how "u" works in Info buffers when scroll-conservatively is set
+
+ * lisp/info.el (Info-up): If scroll-conservatively is non-zero and
+ less than 101, display as much of the superior node above the
+ target line as possible (Bug#13690).
+
+2020-08-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make shadowing warning in describe_map less confusing
+
+ * src/keymap.c (describe_map): A binding may be shadowed by
+ something else than a mode (bug#14086) (just a `define-key'
+ works), so don't say that it's a mode that shadows it.
+
+2020-08-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert previous hideshow commit
+
+ Hideshow has defaults that are overridden if we look for derived modes
+ in hs-special-modes-alist. For instance, in lisp-interaction-mode
+ we'll choose a lookup based on parent modes, and that overrides the
+ default (bug#43032).
+
+ This reverts a415179b56f022f50138f55d231070e3d1b00697.
+
+2020-08-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ * lib/diffseq.h, m4/inttypes.m4: Copy from Gnulib.
+ * m4/gnulib-comp.m4: Regenerate.
+
+2020-08-24 Phillip Lord <phillip.lord@russet.org.uk>
+
+ Fix error in GMP test
+
+ * etc/w32-feature.el: Update to use system-configuration-features for
+ GMP test.
+
+2020-08-24 Phillip Lord <phillip.lord@russet.org.uk>
+
+ Add Feature testing for Windows binaries
+
+ * etc/w32-feature.el: New file
+
+2020-08-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ replace-buffer-contents cleanups
+
+ * src/editfns.c (NOTE_DELETE, NOTE_INSERT): Avoid unnecessary parens.
+ (Freplace_buffer_contents): Check args before returning results.
+ Avoid integer overflow when computing too_expensive, and work even
+ if MAX-COSTS is bignum. Call alloca and/or malloc just once, not
+ three times.
+ (set_bit, bit_is_set): Simplify micro-optimization by using eassume.
+
+2020-08-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix replace-region-contents performance bug
+
+ * src/editfns.c (rbc_quitcounter): Remove; the quitcounter
+ is now part of the context.
+ (EXTRA_CONTEXT_FIELDS): Remove unused member early_abort_tests.
+ Add jmp, quitcounter.
+ (Freplace_buffer_contents): Use setjmp/longjmp to recover from
+ a compareseq that runs too long. Omit unnecessary rarely_quit
+ call.
+ (buffer_chars_equal): Occasionally check for early abort and
+ longjmp out if so (Bug#43016).
+
+2020-08-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify sorting order by file-backup-file-names
+
+ * doc/lispref/backups.texi (Backup Names): Ditto.
+
+ * lisp/files.el (file-backup-file-names): Clarify sorting order.
+
+2020-08-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Rewrite the epa key interface to use buttons instead of widgets
+
+ * lisp/epa.el (epa-font-lock-keywords): Removed.
+ (epa-key-list-mode-map): Bind tab/backtab to button navigation.
+ (epa-key): Remove widget.
+ (epa--button-key-text): Return the propertized text instead of
+ return a widget text.
+ (epa-key-list-mode): Don't use font locking; everything is output
+ as it should be.
+ (epa--insert-keys): Rewrite to just output the data instead of
+ widgetising.
+ (epa--select-keys): Insert buttons instead of widgets.
+
+2020-08-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix error when loading a new, non-existent foo.gpg file
+
+ * lisp/epa-file.el (epa-file-insert-file-contents): Propagate the
+ correct error upwards (bug introduced by fixing bug#3829, and
+ messing up where the `when' form ended).
+ Reported by "Herbert J. Skuhra" <herbert@gojira.at>.
+
+2020-08-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document file-backup-file-names
+
+ * doc/lispref/backups.texi (Backup Names): Document
+ file-backup-file-names.
+
+2020-08-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Extend the default value in dired-diff to all the backup files
+
+ * lisp/dired-aux.el (dired-diff): When diffing files with backup
+ files, put all the backup files into the defaults so that they can
+ be reached with `M-n' from `read-file-name' (bug#24089).
+
+2020-08-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new function 'file-backup-file-names'
+
+ * lisp/files.el (file-backup-file-names): New function (bug#24089).
+ (file-newest-backup): Use it.
+
+2020-08-24 Noam Postavsky <npostavs@users.sourceforge.net>
+
+ Fix inferior octave single-quote font lock
+
+ * lisp/progmodes/octave.el (octave-mode-syntax-table): Fix
+ fontification of single quotes in inferior octave mode (bug#25517).
+
+ It looks like the problem is that octave-mode-syntax-table sets single
+ quotes as punctuation even though GNU Octave's manual says single quotes
+ are string syntax [1].
+
+ [1]:
+ https://www.gnu.org/software/octave/doc/interpreter/String-Objects.html
+
+2020-08-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Have gnutls_symmetric cache the results from Fgnutls_ciphers
+
+ * src/gnutls.c (gnutls_symmetric): Cache the results from
+ Fgnutls_ciphers, since that function isn't very fast (bug#42998).
+ (syms_of_gnutls): Initialize cache variable.
+
+2020-08-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Explain what C-h t means in the preface
+
+ * doc/emacs/emacs.texi (Top): Explain what C-h t means (since this
+ section is for people who haven't even used the tutorial) (bug#42982).
+
+2020-08-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Change how #:uninterned symbols are font-locked in Lisp mode
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-fdefs): Font-lock
+ #:uninterned symbols as a single entity instead of #: and
+ uninterned separately (bug#43001).
+
+2020-08-24 Michael Albinus <michael.albinus@gmx.de>
+
+ Add sanity check in tramp-sh-get-signal-strings
+
+ * lisp/net/tramp-sh.el (tramp-sh-get-signal-strings): Add sanity check.
+
+ * test/lisp/net/tramp-tests.el (tramp-test28-process-file):
+ Remove instrumentation.
+ (tramp--test--deftest-direct-async-process): Adapt docstring.
+ (tramp--test-windows-nt-p, tramp--test-windows-nt-and-batch-p):
+ Rename from `tramp--test-windows-nt', `tramp--test-windows-nt-and-batch'.
+
+2020-08-24 Stefan Kangas <stefankangas@gmail.com>
+
+ Avoid some uses of obsolete function interactive-p
+
+ * doc/lispref/help.texi (Accessing Documentation):
+ * lisp/cedet/data-debug.el:
+ * lisp/emacs-lisp/edebug.el (edebug-wrap-def-body):
+ * lisp/simple.el (append-next-kill):
+ * test/manual/cedet/cedet-utests.el (cedet-utest, pulse-test):
+ * test/manual/cedet/semantic-tests.el (semantic-lex-spp-write-utest)
+ (semantic-symref-test-count-hits-in-tag): Use 'called-interactively-p'
+ instead of obsolete function 'interactive-p'.
+
+2020-08-24 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove many items obsolete since Emacs 23.2 and 23.3
+
+ * lisp/allout.el (allout-init):
+ * lisp/emacs-lisp/shadow.el (shadows-compare-text-p):
+ * lisp/ffap.el (ffap-version):
+ * lisp/filecache.el (file-cache-choose-completion):
+ * lisp/help.el (print-help-return-message):
+ * lisp/image-mode.el (image-mode-maybe):
+ * lisp/imenu.el (imenu-example--name-and-position):
+ * lisp/international/mule-cmds.el (princ-list):
+ * lisp/mail/rmail.el (rmail-highlight-face):
+ * lisp/minibuffer.el (read-file-name-predicate):
+ * lisp/mouse.el (mouse-choose-completion):
+ * lisp/progmodes/cc-cmds.el (c-forward-into-nomenclature):
+ * lisp/progmodes/xscheme.el
+ (advertised-xscheme-send-previous-expression):
+ * lisp/simple.el (completion-base-size)
+ (choose-completion-delete-max-match, exchange-dot-and-mark):
+ * lisp/subr.el (eval-next-after-load):
+ * lisp/term.el (term-dynamic-simple-complete):
+ Remove items, obsolete since Emacs 23.2 and 23.3.
+ * doc/misc/cc-mode.texi (Movement Commands): Doc fix.
+ * doc/lispref/help.texi (Accessing Documentation):
+ * lisp/emacs-lisp/edebug.el (edebug-wrap-def-body):
+ * lisp/comint.el (comint-dynamic-list-completions):
+ * lisp/progmodes/idlwave.el (idlwave-make-modified-completion-map-xemacs)
+ (idlwave-make-modified-completion-map-emacs)
+ (idlwave-choose-completion):
+ * lisp/progmodes/vhdl-mode.el:
+ * lisp/term.el (term-dynamic-list-completions):
+ Remove references to 'mouse-choose-completion'.
+ * lisp/image-mode.el (image-mode-to-text):
+ Remove reference to 'image-mode-maybe'.
+ * lisp/mail/rmail.el (rmail-highlight-headers):
+ Use 'rmail-highlight' face instead of 'rmail-highlight-face'.
+ * lisp/progmodes/antlr-mode.el (antlr-mode-map, antlr-mode-menu):
+ Remove reference to 'c-forward-into-nomenclature'.
+ * lisp/simple.el (choose-completion, choose-completion-string)
+ (completion-list-mode, completion-setup-function): Don't use
+ 'completion-base-size'.
+
+ This was discussed in
+ https://lists.gnu.org/archive/html/emacs-devel/2020-08/msg00400.html
+
+2020-08-24 Asher Gordon <AsDaGo@posteo.net> (tiny change)
+
+ Quote other suspicious characters in mml-insert-tag.
+
+ * lisp/gnus/mml.el (mml-insert-tag): Ensure that the characters
+ "[]<>=" are quoted correctly (bug#43009).
+
+2020-08-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ Simplify by using Gnulib sigdescr_np module
+
+ Inspired by a straightforward patch by Bruno Haible.
+ * admin/merge-gnulib (GNULIB_MODULES): Add sigdescr_np.
+ * configure.ac: Do not check for sys_siglist or __sys_siglist.
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+ * lib/sigdescr_np.c, m4/sigdescr_np.m4: New files, copied from Gnulib.
+ * src/sysdep.c (sys_siglist, sys_siglist_entries): Remove.
+ (init_signals): Do not initialize sys_siglist.
+ (safe_strsignal): Use sigdescr_np instead of sys_siglist.
+
+2020-08-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-08-23 intprops: be consistent about +X vs X+0
+ 2020-08-23 intprops: fix INT_MULTIPLY_WRAPV bit-field bug
+ 2020-08-23 verify: Make assume work on bit field expressions
+ 2020-08-23 libc-config: Improve comments
+ 2020-08-22 verify: Do use __builtin_assume on clang
+ 2020-08-22 sig2str: Add more signals
+ 2020-08-21 sigdescr_np: New module
+ * lib/cdefs.h, lib/intprops.h, lib/sig2str.c, lib/string.in.h:
+ * lib/verify.h, m4/string_h.m4: Copy from Gnulib.
+ * lib/gnulib.mk.in: Regenerate.
+
+2020-08-23 Eli Zaretskii <eliz@gnu.org>
+
+ Fix more compilation warnings in xdisp.c
+
+ * src/xdisp.c (display_mode_element, decode_mode_spec_coding):
+ Avoid compilation warnings.
+
+2020-08-23 Eli Zaretskii <eliz@gnu.org>
+
+ Fix a compilation warning in xdisp.c
+
+ * src/xdisp.c (gui_consider_frame_title): Fix compilation warning.
+ Reported by Lars Ingebrigtsen <larsi@gnus.org>.
+
+2020-08-23 Eli Zaretskii <eliz@gnu.org>
+
+ Improve handling of coding-system mnemonic indicators
+
+ This fixes assertion violations when the mnemonic is
+ given as a string, and allows non-ASCII characters be
+ used as mode-line mnemonic of a coding-system.
+ * src/xdisp.c (decode_mode_spec_coding): Handle multibyte
+ characters as coding-system's mnemonic.
+ (display_mode_element): If decode_mode_spec returns a multibyte
+ string, display it as multibyte.
+ * src/coding.c (Fdefine_coding_system_internal)
+ (Fcoding_system_put): If :mnemonic is a string, use its first
+ character. This avoids assertion violations if someone uses a
+ string as the mnemonic of a coding-system.
+
+2020-08-23 Mattias Engdegård <mattiase@acm.org>
+
+ Always make a multibyte string for the frame title (bug#42904)
+
+ * src/xdisp.c (gui_consider_frame_title): Multibyte-encode any raw
+ bytes in the title, and then pass a multibyte string to the back-end
+ for use as a frame title. This cuts down a little on the rubbish
+ shown when raw bytes sneak in by mistake (as part of the buffer name,
+ for instance).
+
+2020-08-23 Eli Zaretskii <eliz@gnu.org>
+
+ Fix image display on w32 as followup to recent changes
+
+ The new code calls 'malloc' and 'free', so we can no longer
+ * src/image.c (struct image_type): Rename 'load' to 'load_img' and
+ 'free' to 'free_img'. All callers changed.
+ (free_image) [WINDOWSNT]: Don't #undef 'free'.
+
+2020-08-23 Alan Third <alan@idiocy.org>
+
+ Silence compiler warning (bug#40845)
+
+ * src/image.c (lookup_image): Don't allow face to be NULL.
+
+2020-08-23 Alan Third <alan@idiocy.org>
+
+ Set basic SVG attributes (bug#40845)
+
+ * test/manual/image-transforms-tests.el: Replace hard-coded colors
+ with defaults.
+ * src/dispextern.h (struct image):
+ * src/image.c (search_image_cache):
+ (xbm_load_image):
+ (xbm_load):
+ (pbm_load): Rename from frame to face where relevant.
+ (svg_load_image): Parse the image to find out the size, then wrap it
+ in another SVG to set a new size and colors, etc.
+ (lookup_image): Use the face colors instead of the frame colors.
+ (search_image_cache): Add ability to ignore the face colors.
+ (uncache_image): Uncache all copies of the image that share the spec,
+ even if the face colors don't match.
+ * etc/NEWS: Describe the changes.
+
+2020-08-23 Michael Albinus <michael.albinus@gmx.de>
+
+ Rework direct async processes in Tramp
+
+ * doc/misc/tramp.texi (Remote processes): Precise restrictions for direct
+ async processes.
+
+ * lisp/net/tramp.el (tramp-methods): Adapt docstring.
+ (tramp-direct-async-process-p): Make it more precise.
+ (tramp-handle-make-process): Rewrite, based on `make-process'.
+
+ * test/lisp/net/tramp-tests.el (tramp-test-temporary-file-directory):
+ Add `tramp-direct-async-args` for mock method.
+ (tramp-test29-start-file-process, tramp-test30-make-process):
+ Use weaker regexp checking "foo".
+ (tramp-test30-make-process): Do not check stderr for direct async processes.
+ (tramp--test--deftest-direct-async-process): New defmacro.
+ (tramp-test29-start-file-process-direct-async)
+ (tramp-test30-make-process-direct-async): New tests.
+
+2020-08-23 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (native-compile): Fix free function compilation.
+
+2020-08-23 Andrea Corallo <akrl@sdf.org>
+
+ A cc-mode fix to be compiled correctly once installed
+
+ * lisp/progmodes/cc-bytecomp.el (cc-bytecomp-load): If cc-mode
+ is not compiled during the initial build (read
+ NATIVE_FAST_BOOT) it will be when already in el.gz form.
+
+2020-08-23 Andrea Corallo <akrl@sdf.org>
+
+ Rework eln hash filename strategy
+
+ Generate eln filename hashing also the source file content in the form:
+
+ /absolute/path/filename.el + content ->
+ eln-cache/filename-path_hash-content_hash.eln
+
+ * src/lread.c (maybe_swap_for_eln): Always call
+ Fcomp_el_to_eln_filename on an existing source file.
+
+ * src/comp.c (md5.h, sysstdio.h, zlib.h): New include.
+ (comp_hash_string): Use md5 instead of sha512.
+ (MD5_BLOCKSIZE): New macro.
+ (accumulate_and_process_md5, final_process_md5, md5_gz_stream)
+ (comp_hash_source_file): New functions.
+ (Fcomp_el_to_eln_filename): Rework for hasing using also source
+ file content.
+
+ * src/lread.c (maybe_swap_for_eln): Rename el_name -> src_name as
+ this can be also a have .el.gz extension.
+
+2020-08-23 Andrea Corallo <akrl@sdf.org>
+
+ Import lib/af_alg.h from gnulib
+
+ * lib/af_alg.h: New file.
+
+2020-08-23 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-08-23 Eli Zaretskii <eliz@gnu.org>
+
+ Minor fixes for last change
+
+ * lisp/international/kinsoku.el (kinsoku): Provide 'kinsoku'.
+ * lisp/cus-start.el (standard): Use 'require' instead of 'load.
+
+ * etc/NEWS:
+ * doc/emacs/display.texi (Visual Line Mode): Improve wording and
+ markup of last change.
+
+2020-08-23 Yuan Fu <casouri@gmail.com>
+
+ Improve word wrapping for CJK characters
+
+ Note about the change around line 9257 and 23372:
+
+ Before, the test for whitespace checks for can_wrap_before and
+ can_wrap_after simutaniously. Now we separate these two checks, and
+ the logic needs to change a little bit. However, when we don't enable
+ the new wrapping feature, 'can_wrap_after' is equivalent to
+ 'IT_DISPLAYING_WHITESPACE' and 'can_wrap_before' is equivalent to
+ '!IT_DISPLAYING_WHITESPACE'. And the new logic is equivalent with the
+ old one in that case.
+
+ Old logic:
+
+ if (whitespace) /* Which means can wrap after && can't wrap
+ before. */
+ may_wrap = true;
+
+ else if (may_wrap) /* aka (!whitespace && may_wrap)
+ (set wrap point) * aka (can't wrap after && can wrap before
+ may_wrap = false * && may_wrap)
+ */
+
+ New logic:
+
+ if (can_wrap_after)
+ next_may_wrap = true
+ else
+ next_may_wrap = false;
+
+ if (may_wrap && can_wrap_before)
+ (set wrap point)
+
+ /* Update may_wrap. */
+ may_wrap = next_may_wrap;
+
+ * src/xdisp.c (it_char_has_category, char_can_wrap_before)
+ (char_can_wrap_after): New functions.
+ (move_it_in_display_line_to, display_line): Replace calls to
+ 'IT_DISPLAYING_WHITESPACE' with either 'char_can_wrap_before' or
+ 'char_can_wrap_after'.
+ (word-wrap-by-category): New variable.
+
+ * lisp/cus-start.el (minibuffer-prompt-properties--setter): Add
+ 'word-wrap-by-category' as a customizable variable.
+
+ * doc/emacs/display.texi (Visual Line Mode): Add a paragraph about the
+ new 'word-wrap-by-category' feature.
+ * etc/NEWS: Announce the change.
+
+2020-08-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Bind the time zone so that the tests work everywhere
+
+ Use lexical-binding and remove compat code
+
+2020-08-22 Eli Zaretskii <eliz@gnu.org>
+
+ Fix documentation of a recent change in Dired
+
+ * etc/NEWS:
+ * doc/emacs/dired.texi (Dired Enter): Fix the text describing
+ 'dired-maybe-use-globstar'.
+
+ * lisp/dired.el (dired-maybe-use-globstar): Add :version.
+
+2020-08-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify inline-letevals in the manual
+
+ * doc/lispref/functions.texi (Inline Functions): Try to clarify
+ what inline-letevals really does, and how it differs from `let'
+ (bug#31052).
+
+2020-08-22 Tino Calancha <tino.calancha@gmail.com>
+
+ Handle globstar in dired
+
+ Allow user to enable globstar when the shell support
+ it and disable it by default (e.g. bash).
+ * lisp/dired.el (dired-maybe-use-globstar): New user option.
+ (dired-enable-globstar-in-shell): New variable.
+ (dired-insert-directory): if `dired-maybe-use-globstar' is
+ non-nil and the shell supports globstar, then enable it.
+
+ * doc/emacs/dired.texi: Document feature.
+
+2020-08-22 Alan Third <alan@idiocy.org>
+
+ Fix NS build failure
+
+ * src/thread.c: xgselect isn't used with NS, even when HAVE_GLIB is
+ defined.
+
+2020-08-22 Alan Third <alan@idiocy.org>
+
+ Extend NSString further and use the new methods
+
+ * src/nsfns.m (ns_set_icon_name):
+ (ns_set_name):
+ (ns_set_represented_filename):
+ (ns_implicitly_set_icon_type):
+ (ns_set_icon_type):
+ (ns_appkit_version_str):
+ (Fx_create_frame):
+ (Fns_read_file_name):
+ (Fns_get_resource):
+ (Fns_set_resource):
+ (Fns_list_colors):
+ (Fns_perform_service):
+ (ns_do_applescript): Use the new NSString methods.
+ ([NSString stringWithLispString:]): Fix the surrogate algorithm.
+ ([NSString lispString]): New method.
+ * src/nsterm.h (NSString): Add new method.
+ * src/nsterm.m ([EmacsApp openFile:]):
+ ([EmacsApp requestService:userData:error:]):
+ ([EmacsApp fulfillService:withArg:]):
+ ([EmacsView changeFont:]):
+ ([EmacsView setMarkedText:selectedRange:]):
+ ([EmacsView initFrameFromEmacs:]):
+ ([EmacsView performDragOperation:]):
+ ([EmacsView performDragOperation:]):
+ ([EmacsView performDragOperation:]):
+ ([EmacsWindow accessibilityAttributeValue:]): Use the new NSString
+ methods.
+
+2020-08-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Doc string (and defcustom type) fix for grep-find-command
+
+ * lisp/progmodes/grep.el (grep-find-command): Add the cons type to
+ the defcustom, and document it (bug#36113). (It has always been a
+ valid value for the variable.)
+
+2020-08-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ nndoc minor clean-up
+
+ * lisp/gnus/nndoc.el (nndoc-possibly-change-buffer): Erase the
+ buffer before changing multibyteness.
+
+2020-08-22 Jan Tatarik <jan.tatarik@gmail.com>
+
+ gnus-icalendar does not understand multiple repeating days
+
+ * lisp/gnus/gnus-icalendar.el
+ (gnus-icalendar-event:recurring-days): New function (bug#39782).
+ (gnus-icalendar-event:org-timestamp): New function.
+ (gnus-icalendar--find-day): Use them.
+ (gnus-icalendar-event--org-timestamp): Ditto.
+
+2020-08-22 Dmitry Gutov <dgutov@yandex.ru>
+
+ Make ruby-parse-partial more stable
+
+ * lisp/progmodes/ruby-mode.el (ruby-parse-partial):
+ Don't call ruby-deep-indent-paren-p (bug#42841).
+
+2020-08-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Restrict the range of image formats to be converted
+
+ * lisp/image/image-converter.el (image-converter--filter-formats):
+ New function.
+ (image-converter): Mention this in the doc string.
+
+2020-08-22 Stefan Kangas <stefankangas@gmail.com>
+
+ Bind mwheel-scroll on more parts of frame's display
+
+ * lisp/mwheel.el (mouse-wheel-mode): Bind unmodified 'mwheel-scroll'
+ on scroll bars, fringes, margins, header and mode line. (Bug#5557)
+ (mouse-wheel--create-scroll-keys): New helper function for
+ 'mouse-wheel-mode'.
+ * test/lisp/mwheel-tests.el: New file.
+
+2020-08-21 Stephen Berman <stephen.berman@gmx.net>
+
+ Fix several todo-mode.el editing bugs (bug#42976)
+
+ * lisp/calendar/todo-mode.el (todo-insert-item--basic): Ensure the
+ target todo file is in todo-mode.
+ (todo-edit-item--text): When editing a done item comment, prevent
+ clobbering match data on finishing the edit.
+ (todo-edit-item--header): Ensure that decrementing the month of
+ the date header works for intervals greater than a year, and when
+ incrementing or decrementing the month crosses one or more years,
+ adjust the year as needed.
+ (todo-read-category): If we're outside of todo-mode and there is a
+ current todo file, use it; otherwise, use the default todo file.
+
+ * test/lisp/calendar/todo-mode-tests.el
+ (todo-test-edit-item-date-month): New test.
+
+ * test/lisp/calendar/todo-mode-resources/todo-test-1.todo: Modify
+ to accommodate new test.
+
+2020-08-21 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-08-20 sigabbrev_np: New module
+ 2020-08-20 stdalign: Fix 32-bit test failures clang versions < 8
+ 2020-08-17 careadlinkat: speedup for GCC 10 with GCC_LINT
+ 2020-08-17 Assume autoconf >= 2.64
+ * build-aux/config.guess, build-aux/config.sub, lib/careadlinkat.c:
+ * lib/stdalign.in.h, lib/string.in.h, m4/std-gnu11.m4, m4/string_h.m4:
+ Copy from Gnulib.
+ * lib/gnulib.mk.in: Regenerate.
+
+2020-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Minor mode doc string clarification
+
+ * lisp/emacs-lisp/easy-mmode.el (easy-mmode--arg-docstring):
+ Clarify that the minor mode hook is called both when enabling and
+ disabling the mode (bug#34073).
+
+2020-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fread_variable doc string clarification
+
+ * src/minibuf.c (Fread_variable): Doc string clarification (bug#38886).
+
+2020-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ help-at-pt-display-when-idle doc string clarification
+
+ * lisp/help-at-pt.el (help-at-pt-display-when-idle): Clarify when
+ kbd-help is useful (bug#39295).
+
+2020-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention `exec-path' in some process related doc strings
+
+ * src/callproc.c (Fcall_process_region):
+ (Fcall_process):
+ * src/process.c (Fmake_process): Mention `exec-path' in the doc
+ strings (bug#42704).
+
+2020-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Highlight error messages from diff in diff-mode
+
+ * lisp/vc/diff-mode.el (diff-error): New face (bug#2739).
+ (diff-font-lock-keywords): Use it to highlight lines like "diff: "
+ which are error messages from diff (for instance, when a file
+ doesn't exist).
+
+2020-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with 8bit content-transfer-encoding in nndoc mbox files
+
+ * lisp/gnus/nndoc.el (nndoc-possibly-change-buffer): If we're
+ reading an mbox file, it may contain messages that use
+ content-transfer-encoding 8bit, which means that we have to treat
+ the file as a sequence of byte (bug#42951). This avoids
+ double-decoding -- once by Emacs when inserting the mbox into the
+ buffer, and once by Gnus when displaying the articles.
+
+2020-08-21 Noam Postavsky <npostavs@gmail.com>
+
+ Clarify docs about line movement
+
+ * doc/lispref/positions.texi (Text Lines, Screen Lines): Add index
+ entries.
+ * lisp/simple.el (move-beginning-of-line): Remove incorrect mention of
+ images, and reference beginning-of-visual-line.
+ * src/editfns.c (Fline_beginning_position): Reference
+ `vertical-motion' (bug#35899).
+
+2020-08-21 Pip Cet <pipcet@gmail.com>
+
+ Fix lock failures in xg_select
+
+ * src/xgselect.c (release_select_lock, acquire_select_lock):
+ Introduce.
+ (xg_select): Use `acquire_select_lock', `release_select_lock'.
+ * src/thread.c (release_select_lock): Introduce for non-GLib builds.
+ (really_call_select): Call `release_select_lock'. Simplify by
+ ensuring acquisition of the lock always succeeds (bug#36609).
+
+2020-08-21 Pip Cet <pipcet@gmail.com>
+
+ Fix return value for CCL opcode lookup-integer
+
+ * src/ccl.c (ccl_driver): Fix LookupIntConstTbl return value.
+ * test/lisp/international/ccl-tests.el (ccl-hash-table): Add test.
+ * lisp/international/ccl.el (ccl-embed-data): Don't pass non-numbers
+ to `ccl-fixnum' (bug#36740).
+
+2020-08-21 Tobias Zawada <i_inbox@tn-home.de>
+
+ Make hs-special-modes-alist also work for modes derived from those modes
+
+ * lisp/progmodes/hideshow.el (hs-grok-mode-type): Also set up
+ hideshow variables based on hs-special-modes-alist in derived
+ modes (bug#39354).
+
+2020-08-21 Kevin Ryde <user42_kevin@yahoo.com.au>
+
+ Have ispell add new LocalWords lines after any such existing lines
+
+ * lisp/textmodes/ispell.el (ispell-add-per-file-word-list): Add
+ new LocalWords line just after existing such lines. Good to keep
+ words together or if deliberately placed somewhere special
+ (bug#20486).
+
+2020-08-21 Christophe Troestler <Christophe.Troestler@umons.ac.be> (tiny change)
+
+ Fix displaying inline ical attachments with no charset
+
+ * lisp/gnus/gnus-icalendar.el
+ (gnus-icalendar-with-decoded-handle): Check whether there is a
+ charset before using it (bug#40290).
+
+2020-08-21 Gregory Heytings <ghe@sdf.org> (tiny change)
+
+ Tweak completion of Makefile targets
+
+ * lisp/pcmpl-gnu.el (pcmpl-gnu-make-targets): Require that target
+ names not be preceded by a TAG character (bug#42411).
+
+2020-08-21 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove some compat code from cperl-mode
+
+ * lisp/progmodes/cperl-mode.el (cperl-use-syntax-table-text-property)
+ (cperl-syntaxify-by-font-lock, cperl-mode-map, cperl-mode)
+ (cperl-windowed-init, cperl-init-faces, cperl-write-tags): Remove
+ some XEmacs and <21 compat code.
+
+2020-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make image cache lookups work again after previous patch
+
+ * src/image.c (search_image_cache): Fix reversed logic in previous
+ patch.
+
+2020-08-21 Juri Linkov <juri@linkov.net>
+
+ * lisp/simple.el (previous-line-or-history-element): Handle logical lines.
+
+ When 'line-move-visual' is nil, use 'end-of-line' to move point to the end
+ of the first logical line (bug#42862)
+
+ Thanks to Michael Welsh Duggan <mwd@md5i.com>.
+
+2020-08-21 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix off-by-one error in decoded-time-add (with months)
+
+ * lisp/calendar/time-date.el (decoded-time-add): Fix month
+ addition, which was off-by-one.
+
+2020-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with non-ASCII characters in ediff error messages
+
+ * lisp/vc/ediff-diff.el (ediff-prepare-error-list): Decode the
+ data from diff before displaying (bug#5050). This fixes a problem
+ with displaying raw bytes in the error messages in non-ASCII locales.
+
+2020-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make image-mode give better feedback when the buffer is empty
+
+ * lisp/image-mode.el (image-mode): Give a less confusing message
+ if we don't have any image data (bug#16062). Also leave the
+ buffer in fundamental mode.
+
+2020-08-20 Mattias Engdegård <mattiase@acm.org>
+
+ Fix NS crash on invalid frame title string (bug#42904)
+
+ Instead of blindly assuming that all Emacs strings are valid UTF-8,
+ which they are not, use a more careful conversion going via UTF-16
+ which is what NSString uses internally. Unpaired surrogates will
+ still go through to the NSString objects, but the NS libs handle them
+ gracefully.
+
+ * src/nsterm.h (EmacsString): New category.
+ * src/nsfns.m (all_nonzero_ascii): New helper function.
+ ([NSString stringWithLispString:]): New method.
+ (ns_set_name_internal): Use new conversion method.
+
+2020-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix compilation warning in vc-cvs from previous change
+
+ * lisp/vc/vc-cvs.el (log-edit-extract-headers): Fix compilation
+ warning.
+
+2020-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix message.el compilation warning
+
+ * lisp/gnus/message.el (smtpmail-stream-type): Fix compilation
+ warning from last change.
+
+2020-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow specifying the TLS port in X-Message-SMTP-Method
+
+ * lisp/gnus/message.el (message-multi-smtp-send-mail): If the user
+ has specified the TLS SMTP port, then force a TLS connection
+ (bug#38066).
+
+2020-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't message the hunk status when just going to it
+
+ * lisp/vc/diff-mode.el (diff-goto-source): Don't output a status
+ about the hunk just when jumping to it (bug#38370). This would
+ output "Hunk already applied" when browsing diffs.
+
+2020-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new way to encode unprintable characters in Message: url-encode
+
+ * lisp/gnus/message.el (message-fix-before-sending): Add a new
+ conversion method for invalid characters -- URL-encoding (bug#38955).
+
+2020-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with unprintable characters in Message headers
+
+ * lisp/gnus/message.el (message-fix-before-sending): Remove
+ unprintable characters from the entire buffer, not just the body
+ (bug#38955).
+
+2020-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix interactive spec of message-beginning-of-line
+
+ * lisp/gnus/message.el (message-beginning-of-line): Fix problem
+ with C-S-a getting translated to C-a in message-mode (bug#39545).
+
+2020-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove the "Summary: " but from cvs checkins
+
+ * lisp/vc/vc-cvs.el (vc-cvs-checkin): Remove the "Summary:" bit
+ from the comment (bug#40506).
+
+2020-08-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ message-sendmail-f-is-evil doc string fix
+
+ * lisp/gnus/message.el (message-sendmail-f-is-evil): Make doc
+ string less confusing by removing a joke (bug#41096).
+
+2020-08-20 Noah Swainland <noah@distinctly.pink>
+
+ Add global-goto-address-mode
+
+ * doc/emacs/misc.texi (Goto Address mode): Document it.
+
+ * lisp/net/goto-addr.el (global-goto-address-mode)
+ (goto-addr-mode--turn-on): New functions (bug#42937).
+
+2020-08-20 Andrea Corallo <akrl@sdf.org>
+
+ Revert "Fix native code uneffective loads after recompilation" (bug#42944)
+
+ This reverts commit 8a931a97b8dd19a38d6f719f810280a07ba76438.
+
+ This introduced bug#42944.
+
+2020-08-20 Stefan Kangas <stefankangas@gmail.com>
+
+ Revert "; * etc/NEWS: Remove temporary note on documentation. (Bug#42917)"
+
+ This reverts commit 121be3e1181e609734fc4cc9d2d54cf7eec18ab2.
+
+2020-08-19 Glenn Morris <rgm@gnu.org>
+
+ * admin/admin.el (set-version): Trap yet another NEWS error.
+
+2020-08-19 Stefan Kangas <stefankangas@gmail.com>
+
+ Fix minor issues after recent world-clock rename
+
+ * lisp/time.el (world-clock-mode): Set 'revert-buffer-function'
+ buffer-locally rather than globally.
+ (display-time-world): Unobsolete alias for 'world-clock'. Some users
+ might be used to the old name.
+
+2020-08-19 Andreas Fuchs <asf@boinkor.net>
+
+ Pass driver options to libgccjit where supported
+
+ Add a customizable variable for driver options (such as linker flags)
+ to pass to libgccjit (Bug #42761).
+
+ * lisp/emacs-lisp/comp.el (comp-native-driver-options): New
+ customization variable.
+ * src/comp.c: Use comp-native-driver-options to set libgccjit's driver
+ options, if supported on the library's ABI version.
+
+2020-08-19 Andrea Corallo <akrl@sdf.org>
+
+ Fix native code uneffective loads after recompilation
+
+ 'dlopen' can return the same handle if two shared with the same
+ filename are loaded in two different times (even if the first was
+ deleted!). To prevent this scenario the last modification time of the
+ source file is included in the hashing algorithm.
+
+ * src/comp.c (Fcomp_el_to_eln_filename): Update hashing algo to
+ include the source last modification date.
+ * src/lread.c (maybe_swap_for_eln): Do not check for eln newer
+ then elc as this is now unnecessary.
+
+2020-08-19 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-08-19 Noah Friedman <friedman@splode.com>
+
+ Make shell-resync-dirs handle whitespace in directory names
+
+ * lisp/shell.el (shell-resync-dirs): Correctly handle
+ whitespace in directory names (bug#23324).
+
+2020-08-19 Juri Linkov <juri@jurta.org>
+
+ Allow searching interactively over completions in `M-x'
+
+ * lisp/simple.el (read-extended-command): Allow doing interactive
+ searches over the completions (bug#12490). This restores the
+ behaviour from Emacs 23 that was lost in Emacs 24.
+
+2020-08-19 Grégoire Jadi <gregoire.jadi@univ-nantes.fr>
+
+ Ensure `bibtex-set-dialect' is executed in bibtex buffers
+
+ * lisp/textmodes/bibtex.el (bibtex-mode): Call `bibtex-set-dialect'.
+ * test/automated/bibtex-tests.el: Add regression tests (bug#21764).
+
+2020-08-19 Robert Weiner <rswgnu@gmail.com>
+
+ Make etags-list-tags work with Exuberant ctags
+
+ * lisp/progmodes/etags.el (etags-list-tags): Make the function
+ work with Exuberant ctags (bug#23400).
+
+2020-08-19 Mattias Engdegård <mattiase@acm.org>
+
+ Fix cond jump table compilation (bug#42919)
+
+ This bug affected compilation of
+
+ (cond ((member '(some list) variable) ...) ...)
+
+ While equal is symmetric, member is not; in the latter case the
+ arguments must be a variable and a constant list, in that order.
+
+ Reported by Ikumi Keita.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile--cond-switch-prefix):
+ Don't treat equality and member predicates in the same way; only
+ the former are symmetric in their arguments.
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (byte-opt-testsuite-arith-data): Add test cases.
+
+2020-08-19 Anders Lindgren <andlind@gmail.com>
+
+ Fix #'(lambda ...) font locking
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp--el-non-funcall-position-p):
+ Fontize #'(lambda ...) better (bug#23465).
+
+2020-08-19 Doug Gilmore <dougjgilmore@gmail.com>
+
+ Fix a segfault in daemon mode Emacs when detaching an X session
+
+ * src/xterm.c (x_uncatch_errors): Add a sanity check for
+ x_error_message (bug#23939).
+
+2020-08-19 Mattias Engdegård <mattiase@acm.org>
+
+ Distinguish errors in bytecomp-tests
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-check-1)
+ (test-byte-opt-arithmetic, bytecomp-lexbind-check-1)
+ (bytecomp-lexbind-explain-1):
+ When comparing interpreted with compiled results, don't consider all
+ errors to be equal; take the error type into account. (The error
+ arguments may differ, but there may be good reasons for that.)
+
+2020-08-19 Mattias Engdegård <mattiase@acm.org>
+
+ Make bytecomp-tests re-runnable
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (test-byte-comp-macro-expand-lexical-override): Remove functions
+ before testing so that the test can be run twice without failing.
+
+2020-08-19 Tino Calancha <tino.calancha@gmail.com>
+
+ Make thingatpt recognise files names with @ in them
+
+ * lisp/thingatpt.el (thing-at-point-file-name-chars): Add @
+ (Bug#24606).
+
+2020-08-19 Tom Tromey <tom@tromey.com>
+
+ Add a variable to control VC completion over branch names
+
+ * lisp/vc/vc-git.el (vc-git-revision-complete-only-branches): New
+ variable (bug#25710).
+ (vc-git-revision-table): Use it.
+
+2020-08-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Better check for multi-hops when calling direct async processes
+
+ * lisp/net/tramp-sh.el (tramp-multi-hop-p, tramp-compute-multi-hops):
+ Move them from here ...
+
+ * lisp/net/tramp.el (tramp-multi-hop-p, tramp-compute-multi-hops): ... here.
+ (tramp-direct-async-process-p): Use `tramp-compute-multi-hops'.
+
+2020-08-19 Carlos Pita <carlosjosepita@gmail.com>
+
+ Don't override python font locking in comint
+
+ * lisp/comint.el (comint-highlight-input): New variable (bug#32344).
+ (comint-send-input): Use it.
+
+ * lisp/progmodes/python.el (inferior-python-mode): Set it.
+
+2020-08-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Signal an end-of-file error upon errors when reading from stdin
+
+ * src/minibuf.c (read_minibuf_noninteractive): Signal an
+ `end-of-file' error when reading from stdin instead of a general
+ error (bug#34123). This makes it easier to write code that
+ recovers from this situation.
+
+ Suggested by Noam Postavsky <npostavs@gmail.com>.
+
+2020-08-19 Noam Postavsky <npostavs@users.sourceforge.net>
+
+ Let ido-everywhere turn on ido-mode
+
+ * lisp/ido.el (ido-everywhere): Turn on ido-mode, if it's not already
+ on. Otherwise, having ido-everywhere enabled messes all file and
+ buffer reading interactive commands (bug#34292).
+
+2020-08-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix the [ command in speedbar mode
+
+ * lisp/speedbar.el (speedbar-expand-line-descendants): Expand only
+ the current line -- not all subsequent lines in the speedbar
+ buffer (bug#35014).
+
+2020-08-19 Sebastian Urban <mrsebastianurban@gmail.com>
+
+ Fix a page-break in the middle of a keystroke in basic.texi
+
+ * doc/emacs/basic.texi (Inserting Text): Avoid having the C-x 8 ]
+ keystroke broken over two pages in the PDF version (bug#35885).
+
+2020-08-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from viper-cmd.el
+
+2020-08-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from ispell.el
+
+ * lisp/textmodes/ispell.el (ispell): transient-mark-mode and
+ mark-active are always bound, so remove the check.
+
+2020-08-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from erc
+
+ * lisp/erc/erc.el (erc-mode): next-line-add-newlines is always
+ defined, so remove the check.
+
+2020-08-18 Alan Third <alan@idiocy.org>
+
+ Get rid of build-time checks around NS tabbar code (bug#33118)
+
+ * src/nsterm.m ([EmacsView initFrameFromEmacs:]): Get rid of version
+ checks.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from viper-*.el
+
+ * lisp/emulation/viper-util.el (viper-check-minibuffer-overlay):
+ * lisp/emulation/viper-cmd.el (viper-minibuffer-standard-hook)
+ (viper-minibuffer-real-start, viper-submit-report): No need to
+ check whether minibuffer-prompt-end is defined.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from descr-text.el
+
+ * lisp/descr-text.el (describe-text-properties-1): button.el is
+ pre-loaded, so remove check for it.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from viper-cmd.el
+
+ * lisp/emulation/viper-cmd.el (viper-next-line-at-bol): No need to
+ check for button-at.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from ps-print.el
+
+ * lisp/ps-print.el: Don't make a face-list alias.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from forms.el
+
+ * lisp/forms.el (forms-mode): make-face always exists.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from smiley.el
+
+ * lisp/gnus/smiley.el (smiley-style): face-attribute is always defined.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from chart.el
+
+ * lisp/emacs-lisp/chart.el (chart-face-list):
+ set-face-background-pixmap is always defined.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from htmlfontify.el
+
+ * lisp/htmlfontify.el (hfy-color-vals): color-values is always
+ defined.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from ps files
+
+ * lisp/ps-def.el (ps-color-device): Ditto.
+
+ * lisp/ps-print.el (ps-color-scale): Make into an obsolete alias.
+ (ps-begin-job): Adjust caller.
+
+ * lisp/progmodes/ebnf2ps.el (ebnf-generate-eps, ebnf-generate): Ditto.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from woman.el
+
+ * lisp/woman.el (woman-fontify): Don't check for functions always
+ defined.
+
+2020-08-18 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Replace last uses of idlwave-get-buffer-visiting
+
+ * lisp/progmodes/idlw-help.el (idlwave-help-with-source):
+ * lisp/progmodes/idlw-shell.el (idlwave-shell-set-bp-in-module)
+ (idlwave-shell-delete-temp-files, idlwave-shell-save-and-action):
+ Replace last occurrences of deprecated idlwave-get-buffer-visiting
+ with now-equivalent find-buffer-visiting.
+
+2020-08-18 Stefan Kangas <stefankangas@gmail.com>
+
+ * lisp/vt-control.el: Use lexical-binding.
+
+2020-08-18 Philip K <philipk@posteo.net>
+
+ Fix Libravatar federation handling
+
+ * lisp/image/gravatar.el (gravatar--service-libravatar): Implement
+ correct algorithm (bug#40354).
+
+2020-08-18 Philip K <philipk@posteo.net>
+
+ Fix Libravatar federation handling
+
+ * lisp/image/gravatar.el (gravatar--service-libravatar): Implement
+ correct algorithm (bug#40354).
+
+2020-08-18 Robert Pluim <rpluim@gmail.com>
+
+ Fix truncated command names in process-attributes under Macos
+
+ * src/sysdep.c (system_process_attributes): Fix truncation of
+ command names in process-attributes under Macos (bug#36287).
+
+2020-08-18 Stefan Kangas <stefankangas@gmail.com>
+
+ Rearrange and clean up code in time.el (Bug#40863)
+
+ * lisp/time.el (world-clock, zoneinfo-style-world-list)
+ (legacy-style-world-list, world-clock-list)
+ (time--display-world-list, world-clock-time-format)
+ (world-clock-timer-enable, world-clock-timer-second): Move definitions
+ closer to 'world-clock' code. Remove redundant :group args.
+
+ (display-time-mail-file, display-time-mail-directory)
+ (display-time-mail-function)
+ (display-time-default-load-average)
+ (display-time-load-average-threshold, display-time-day-and-date)
+ (display-time-interval, display-time-24hr-format)
+ (display-time-hook, display-time-mail-face)
+ (display-time-use-mail-icon, display-time-mail-string)
+ (display-time-format, display-time-string-forms): Remove redundant
+ :group args.
+
+2020-08-18 Stefan Kangas <stefankangas@gmail.com>
+
+ Rename 'display-time-world' to 'world-clock' (Bug#40863)
+
+ * lisp/time.el (world-clock-list, world-clock-time-format)
+ (world-clock-buffer-name, world-clock-timer-enable)
+ (world-clock-timer-second, world-clock-label, world-clock-mode)
+ (world-clock-display, world-clock, world-clock-update): Rename
+ from 'display-time-world-*' and update all uses.
+
+ (world-clock): New defgroup.
+ (zoneinfo-style-world-list, legacy-style-world-list): Use :group
+ 'world-clock'.
+
+ (display-time-world-list, display-time-world-time-format)
+ (display-time-world-buffer-name)
+ (display-time-world-timer-enable)
+ (display-time-world-timer-second): Make into obsolete variable
+ aliases for the new names.
+
+ * lisp/time.el (display-time-world-mode)
+ (display-time-world-display, display-time-world)
+ (display-time-world-timer): Make into obsolete function aliases
+ for the new names.
+
+ * etc/NEWS: Announce the above changes.
+
+2020-08-18 Stefan Kangas <stefankangas@gmail.com>
+
+ Improve display-time-world UI (Bug#40863)
+
+ * lisp/time.el (display-time-world-mode): Set 'revert-buffer-function'
+ to 'display-time-world-timer'.
+
+ (display-time-world-label): New face.
+ (display-time-world-display): Use the new face. Move point to new
+ buffer on creation and resize.
+
+2020-08-18 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove the "Recent message" section from the bug reports
+
+ * lisp/mail/emacsbug.el (report-emacs-bug): Don't include "Recent
+ messages" since it has privacy implications. Problem reported by
+ Lars Ingebrigtsen in:
+ https://lists.gnu.org/archive/html/emacs-devel/2019-11/msg01099.html
+ (bug#39185).
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ srecode-utest-project test should now work on Hydra, hopefully
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix a big in the srecore test setup
+
+ * test/lisp/cedet/srecode-utest-template.el
+ (srecode-utest-project): Set the current directory in the project
+ so that we'll find it later (bug#42533). The in-project directory
+ is /tmp, which is not actually what it is on many machines that
+ have the temporary directory somewhere else.
+
+2020-08-18 Stefan Kangas <stefankangas@gmail.com>
+
+ * lisp/savehist.el: Doc fix.
+
+2020-08-18 Pip Cet <pipcet@gmail.com>
+
+ Fix minor bugs in image.c
+
+ * test/lisp/image-tests.el (image-test-circular-specs): New file.
+ * src/image.c (parse_image_spec): Return failure for circular lists.
+ (valid_image_p): Don't look at odd-numbered list elements expecting to
+ find a property name.
+ (image_spec_value): Handle circular lists.
+ (equal_lists): Introduce.
+ (search_image_cache): Use `equal_lists' (bug#36403).
+
+2020-08-18 Philip K <philipk@posteo.net>
+
+ Fix issues with OpenPGP header
+
+ * doc/misc/message.texi (OpenPGP Header): Mention correct hook
+ * lisp/gnus/message.el (message-openpgp-header): Improve customize type
+ (message-add-openpgp-header): Insert header into correct buffer
+ (bug#42913).
+
+2020-08-18 Kalle Olavi Niemitalo <kon@iki.fi> (tiny change)
+
+ Fix buffer overflow in x-send-client-message
+
+ * src/xselect.c (x_fill_property_data): Add parameter NELEMENTS_MAX.
+ * src/xterm.h (x_fill_property_data): Update prototype.
+ * src/xselect.c (Fx_send_client_event): Update call. This fixes
+ a buffer overflow in event.xclient.data.
+ * src/xfns.c (Fx_change_window_property): Update call (bug#23482).
+
+2020-08-18 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 362ca83a3b (origin/emacs-27) Let Emacs start even if curdir is inacce...
+ dd989c0ea0 * etc/NEWS: Mention GnuPG 2.0 through 2.1.5 issue (Bug#428...
+ 4542b750cc Fix bug with ~/Emacs file not being read at init
+ 9b403d624e ; Fix last change
+ 6bff65a626 ; * doc/lispref/sequences.texi (Sequence Functions): Typo ...
+ 3c4edfd85e Prevent from frozen frame after `C-z' in Lucid builds
+ 98e8241992 Document the 'flex' completion style
+ 19fa8b7ca3 Note that Emacs needs systemd support if systemd is used t...
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-08-18 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ cf0ee6f49b ; spelling fixes
+ 16f4f26632 Fix startup working dir bug on NeXTSTEP
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Implement a cache for all types of gravatars
+
+ * lisp/image/gravatar.el (gravatar-automatic-caching): Made obsolete.
+ (gravatar-cache-ttl): Ditto.
+ (gravatar--cache): New variable to cache gravatars in-memory.
+ (gravatar-retrieve): Maintain the cache.
+ (gravatar--prune-cache): Remove old entries.
+ (gravatar-retrieved): Remove use of the old-style cache (bug#40355).
+
+2020-08-18 Clément Pit-Claudel <clement.pitclaudel@live.com>
+
+ Fix ert ability to peek inside structures when comparing unequal values
+
+ * lisp/emacs-lisp/ert.el (ert--explain-equal-rec): Treat records
+ as arrays (bug#40562). Also add support for cl-structs.
+
+2020-08-18 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove reference to Emacs Lisp List from FAQ
+
+ * doc/misc/efaq.texi (Packages that do not come with Emacs): Remove
+ reference to Emacs Lisp List. (Bug#41681)
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add NEWS entry for the count-lines change
+
+2020-08-18 Jen-Chieh Shen <jcs090218@gmail.com>
+
+ Add optional ALL-FRAMES arfument to count-windows
+
+ * lisp/window.el (count-windows): Allow counting the windows on
+ all frames (bug#42872).
+
+2020-08-18 Stefan Kangas <stefankangas@gmail.com>
+
+ Rename new option to flyspell-use-mouse-3-for-menu
+
+ * lisp/textmodes/flyspell.el (flyspell-use-mouse-3-for-menu): Rename
+ from 'flyspell-correct-on-mouse-3'. The previous name did not make it
+ clear that it's about opening a menu. (Bug#11680)
+ (flyspell--set-use-mouse-3-for-menu): Rename from
+ 'flyspell--set-correct-on-mouse-3'. Bind menu to 'down-mouse-3'
+ instead of 'mouse-3' to be more in line with user expectations.
+ (flyspell-mode): Use the above new names.
+ * doc/emacs/fixit.texi (Spelling):
+ * etc/NEWS: Update documentation to use the new name.
+
+ Suggested by Stefan Monnier <monnier@iro.umontreal.ca>.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Trim titles in eww so that the host from the URL is visible
+
+ * lisp/net/eww.el (eww-update-header-line-format): Trim the line
+ of the title so that the host bit of the URL is visible (bug#42898).
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from esh-io.el
+
+ * lisp/eshell/esh-io.el (eshell-set-output-handle): Remove check
+ for null-device, which is always bound.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from ediff
+
+ * lisp/vc/ediff-init.el (ediff-convert-standard-filename): Make
+ obsolete.
+ * lisp/vc/ediff-util.el (ediff-setup): Adjust callers.
+ (ediff-make-temp-file): Ditto.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from ede/make.el and semantic/dep.el
+
+ * lisp/cedet/ede/make.el (ede--find-executable): Make obsolete.
+ (ede-make-command): Adjust caller.
+
+ * lisp/cedet/semantic/dep.el
+ (semantic--dependency-find-file-on-path): Make obsolete.
+ (semantic-dependency-find-file-on-path): Adjust callers.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from python.el
+
+ * lisp/progmodes/python.el: Remove some compat function definitions.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from binhex.el and uudecode.el
+
+ * lisp/mail/binhex.el (binhex-temporary-file-directory): Make obsolete.
+ (binhex-decode-region-external): Adjust usage.
+
+ * lisp/mail/uudecode.el (uudecode-temporary-file-directory): Make
+ obsolete.
+ (uudecode-decode-region-external): Adjust usage.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from ispell.el
+
+ * lisp/textmodes/ispell.el (ispell-check-version): Remove check
+ for temporary-file-directory, which is always defined.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from uudecode.el
+
+ * lisp/mail/uudecode.el (uudecode-decode-region-external): Remove
+ check for make-temp-file, which is always defined.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from ediff-util.el
+
+ * lisp/vc/ediff-util.el (ediff-minibuffer-with-setup-hook): Make
+ into an obsolete macro.
+ (ediff-read-file-name): Adjust caller.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove XEmacs compat code from idlwave.el
+
+ idlwave.el: (idlwave-comment-line-start-skip, idlwave-mode-map)
+ (idlwave-mode, idlwave-get-buffer-visiting)
+ (idlwave-find-file-noselect, idlwave-complete-in-buffer)
+ (idlwave-attach-classes, idlwave-popup-select)
+ (idlwave-split-menu-emacs, idlwave-display-completion-list)
+ (idlwave-default-choose-completion)
+ (idlwave-display-completion-list-emacs)
+ (idlwave-display-completion-list-1)
+ (idlwave-make-modified-completion-map-emacs)
+ (idlwave-class-file-or-buffer, idlwave-rinfo-mouse-map)
+ (idlwave-display-calling-sequence)
+ (idlwave-insert-source-location)
+ (idlwave-list-load-path-shadows, idlwave-edit-in-idlde): Remove
+ XEmacs compat code.
+
+2020-08-18 Andrew Whatson <whatson@gmail.com>
+
+ * Fix async compilation `comp-eln-load-path' effectiveness (bug#42909)
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): Forward
+ `comp-eln-load-path' to async workers.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from window.el
+
+ * lisp/window.el (window-fixed-size-p): Remove check for
+ window-size-fixed, which is always defined.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from idlwave.el
+
+ * lisp/progmodes/idlwave.el (idlwave-one-key-select): Remove check
+ from fit-window-to-buffer, which always exists.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove come compat code from rmailedit.el
+
+ * lisp/mail/rmailedit.el (rmail-edit-mode): Remove check for
+ mode-line-modified, which is always defined.
+
+2020-08-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from erc-track.el
+
+ * lisp/erc/erc-track.el (erc-track-remove-from-mode-line)
+ (erc-track-add-to-mode-line): Remove check for mode-line-modes,
+ which is always bound.
+
+2020-08-18 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix glitch uncovered by gcc -fsanitize=undefined
+
+ * src/ccl.c (ccl_driver): Defend against signed integer
+ overflow (Bug#42660). Perhaps some of this is unnecessary,
+ but it is safe and ccl.c is low-priority these days.
+
+2020-08-18 Paul Eggert <eggert@cs.ucla.edu>
+
+ Let Emacs start even if curdir is inaccessible
+
+ * lisp/startup.el (normal-top-level): Also delete PWD if
+ file-attributes fails for either $PWD or default-directory,
+ instead of failing out of the top level.
+ This fixes a regression from Emacs 26 (Bug#42903).
+
+2020-08-18 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-08-17 verify: avoid __built_assume on Clang
+ 2020-08-17 libc-config: avoid Clang’s __diagnose_if__
+ * lib/cdefs.h, lib/verify.h: Copy from Gnulib.
+
+2020-08-17 Eli Zaretskii <eliz@gnu.org>
+
+ Don't use -Wsuggest-attribute=malloc by default
+
+ * configure.ac: Move -Wsuggest-attribute=malloc to the set used
+ only under --enable-gcc-warnings.
+
+2020-08-17 Eli Zaretskii <eliz@gnu.org>
+
+ Fix assertion violation in pdumper.c
+
+ * src/pdumper.c (pdumper_find_object_type_impl): When checking
+ last_mark_bits, require the offset to be less than
+ discardable_start, not cold_start. This fixes a typo introduced in
+ 2020-08-14T21:33:21Z!eggert@cs.ucla.edu (Bug#42832).
+
+2020-08-17 Andrea Corallo <akrl@sdf.org>
+
+ Improve eln filename hashing
+
+ Make eln filename hashing logic insensitive to the installation
+ process.
+
+ * src/comp.c (epaths.h): New include to have PATH_DUMPLOADSEARCH,
+ PATH_LOADSEARCH definitions.
+ (loadsearch_re_list): New static var.
+ (Fcomp_el_to_eln_filename): Update logic to have the eln hashing
+ insensitive to the installation process.
+ (syms_of_comp): GC protect 'loadsearch_re_list'.
+
+2020-08-17 Andrea Corallo <akrl@sdf.org>
+
+ * test/src/comp-tests.el (comp-tests-bootstrap): Fix test for new eln setup.
+
+2020-08-17 Andrea Corallo <akrl@sdf.org>
+
+ Introduce `load-no-native'
+
+ Given load loads automatically a .eln in place of a .elc we need a way
+ to force the .elc load in the case we really want it.
+
+ * src/lread.c (syms_of_lread): Define `load-no-native'.
+ (maybe_swap_for_eln): Make use of.
+
+2020-08-17 Andrea Corallo <akrl@sdf.org>
+
+ Remove a false permission related error while native compiling
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-file): Do not crash if
+ native compiling we have no permission to create the .elc
+ file. We are not creating it.
+
+2020-08-17 Andrea Corallo <akrl@sdf.org>
+
+ Allow for native compiling .el.gz files
+
+ This is needed for installed instances compiled with NATIVE_FAST_BOOT
+
+ * src/comp.c (maybe_defer_native_compilation): Search for .el.gz
+ too as a source if the .el is not found.
+ (Fcomp_el_to_eln_filename): Remove the .gz in case to
+ generate the hash.
+
+ * lisp/emacs-lisp/comp.el (comp-valid-source-re): New defconst.
+ (comp-run-async-workers, native-compile-async): Make use of
+ `comp-valid-source-re'.
+
+2020-08-17 Andrea Corallo <akrl@sdf.org>
+
+ Make install target functional for new eln-cache directory arrangement
+
+ * src/comp.h (fixup_eln_load_path): New extern.
+
+ * src/comp.c (fixup_eln_load_path): New function.
+
+ * src/pdumper.c (dump_do_dump_relocation): Update to make use of
+ 'fixup_eln_load_path'.
+
+ * lisp/loadup.el: Update to store in the compilation unit the
+ correct eln-cache installed path. Rename --lisp-dest -> --eln-dest
+ and.
+
+ * Makefile.in: Pass the eln destination directory to
+ src/Makefile. Rename LISP_DESTDIR -> ELN_DESTDIR.
+ (ELN_DESTDIR): Define.
+ (install-eln): New target.
+ (install): Add install-eln as prerequisite.
+
+ * src/Makefile.in: Rename --lisp-dest -> --eln-dest and
+ LISP_DESTDIR -> ELN_DESTDIR.
+
+2020-08-17 Andrea Corallo <akrl@sdf.org>
+
+ Deferred compilation must always compile despite source file timestamp
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): Always compile
+ if load is set.
+
+2020-08-17 Andrea Corallo <akrl@sdf.org>
+
+ Do not fail if more then one level of directories has to be created
+
+ * lisp/emacs-lisp/comp.el (native-compile-async): Call
+ make-directory if necessary.
+
+2020-08-17 Andrea Corallo <akrl@sdf.org>
+
+ Prevent recursive load
+
+ Prevent autoload to kicks in while running `native-compile-async'.
+ Autoload cannot be used safely by functions serving deferred
+ compilation as a circular load can be triggered if the dependency is
+ not native compiled already.
+
+ * lisp/emacs-lisp/comp.el (warnings): Add require.
+
+2020-08-17 Andrea Corallo <akrl@sdf.org>
+
+ Some Makefile updates and clean-up
+
+ * Makefile.in (clean): Remove 'eln-cache' folder.
+
+ * lisp/Makefile.in (.SUFFIXES): Remove .eln.
+ (native-compile-clean): Target remove.
+ (compile-always, bootstrap-clean): Remove 'native-compile-clean'
+ prerequisite.
+
+ * src/Makefile.in (%.eln): Remove rule.
+
+2020-08-17 Andrea Corallo <akrl@sdf.org>
+
+ Make comp-deferred-compilation a simple global and set it on by default
+
+ * src/comp.c (comp_deferred_compilation): Doc update and set it to
+ true by default.
+
+ * lisp/emacs-lisp/comp.el (comp-deferred-compilation): Remove
+ customize.
+
+2020-08-17 Andrea Corallo <akrl@sdf.org>
+
+ Move eln files into dedicated cache directories
+
+ When loading a elc file search for a corresponding eln one into
+ `comp-eln-load-path' directories and load it if available.
+ `comp-eln-load-path' contains by default two directory (user and
+ system one).
+
+ * src/pdumper.c (dump_do_dump_relocation): While resurrecting from
+ load set eln cache sys dir in `Vcomp_eln_load_path'.
+
+ * src/lread.c (maybe_swap_for_eln): New function.
+ (Fload): Clean-up some now unnecessary code going
+ back to the master one.
+ (Fload): Make use of Vcomp_eln_to_el_h for the reverse file
+ look-up.
+ (openp_add_middle_dir_to_suffixes)
+ (openp_max_middledir_and_suffix_len, openp_fill_filename_buffer):
+ Remove functions.
+ (openp): As for Fload revert code modifications.
+ (openp): When a .elc file is being loaded check if a corresponding
+ eln can be loaded in place.
+
+ * src/comp.c (ELN_FILENAME_HASH_LEN): New macro.
+ (comp_hash_string): New function.
+ (hash_native_abi): Make use of 'comp_hash_string'.
+ (hash_native_abi): Change `comp-native-path-postfix' format.
+ (Fcomp_el_to_eln_filename): New function.
+ (Fcomp__compile_ctxt_to_file): Have file_name as a input.
+ (Vcomp_eln_to_el_h, Vcomp_eln_load_path): New global variables.
+
+ * lisp/startup.el (normal-top-level): Add user eln cache directory
+ in `comp-eln-load-path'.
+
+ * lisp/help-fns.el (find-lisp-object-file-name): Reverse look-up
+ files using `comp-eln-to-el-h'.
+
+ * lisp/files.el (locate-file): Likewise.
+
+ * lisp/emacs-lisp/find-func.el (find-library-name): Likewise.
+
+ * lisp/emacs-lisp/comp.el (comp-output-directory)
+ (comp-output-base-filename, comp-output-filename): Remove function.
+ (comp-compile-ctxt-to-file): Create parent directories if
+ necessary.
+ (comp-run-async-workers, native-compile, native-compile-async):
+ Make use `comp-el-to-eln-filename'.
+
+2020-08-17 Paul Eggert <eggert@cs.ucla.edu>
+
+ * etc/NEWS: Mention GnuPG 2.0 through 2.1.5 issue (Bug#42845).
+
+2020-08-17 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove some obsolete items from PROBLEMS
+
+ * etc/PROBLEMS: Remove some obsolete items.
+
+2020-08-17 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove more XEmacs compat code from viper
+
+ * lisp/emulation/viper-util.el (viper-sit-for-short)
+ (viper-last-command-char): Make obsolete.
+ (viper-fast-keysequence-p):
+ * lisp/emulation/viper-cmd.el (viper-escape-to-emacs)
+ (viper-digit-argument, viper-command-argument, viper-undo)
+ (viper-exit-minibuffer):
+ * lisp/emulation/viper-mous.el (viper-multiclick-p):
+ Adjust callers.
+
+2020-08-17 Robert Pluim <rpluim@gmail.com>
+
+ Fix bug with ~/Emacs file not being read at init
+
+ * src/xrdb.c (get_user_app): Put "/" between homedir
+ and %L or %N (Bug#42827).
+
+2020-08-16 Paul Eggert <eggert@cs.ucla.edu>
+
+ Simplify format_time_string
+
+ * src/timefns.c (emacs_nmemftime, format_time_string):
+ Simplify on the basis of recent nstrftime changes.
+ Propagate nstrftime errno.
+
+2020-08-16 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-08-16 time_rz: remove unused functions
+ 2020-08-16 time_rz: fix issues with mktime_z failures
+ 2020-08-16 nstrftime: Guide inlining also on clang
+ 2020-08-16 intprops: Avoid bogus warning on clang
+ 2020-08-16 libc-config: Enable __REDIRECT macro also on clang
+ 2020-08-16 regex: Use initializer shorthand syntax also with clang
+ 2020-08-16 regex: Use space optimization also with clang
+ 2020-08-16 Use _Static_assert and static_assert when present on clang
+ 2020-08-16 Use 'throw ()' for optimization in C++ mode also on clang
+ 2020-08-16 stdio: Don't break attribute 'scanf' on clang
+ 2020-08-16 Fix "warning: 'format' attribute ...: rpl_printf"
+ 2020-08-16 Fix "warning: attribute declaration must precede definition"
+ 2020-08-16 Fix undesired warnings
+ 2020-08-16 Don't use Autoconf quadrigraphsxo
+ 2020-08-16 Fix quoting of AC_LANG_PROGRAM arguments
+ 2020-08-16 Assume autoconf >= 2.64
+ 2020-08-15 nstrftime: be more predictable about errno
+ 2020-08-15 canonicalize: Fix autoconf test on MSVC/clang
+ 2020-08-15 Support compiling without -loldnames on native Windows
+ 2020-08-14 mktime, mktime-internal: Remove obsolete code
+ 2020-08-14 Assume tzset exists
+ * lib/c++defs.h, lib/canonicalize-lgpl.c, lib/cdefs.h, lib/dup2.c:
+ * lib/fcntl.in.h, lib/getopt-cdefs.in.h, lib/intprops.h, lib/md5.h:
+ * lib/mktime.c, lib/nstrftime.c, lib/open.c, lib/regcomp.c:
+ * lib/regex_internal.h, lib/stdio.in.h, lib/stdlib.in.h:
+ * lib/strftime.h, lib/string.in.h, lib/sys_select.in.h:
+ * lib/sys_stat.in.h, lib/sys_time.in.h, lib/time.in.h, lib/time_rz.c:
+ * lib/unistd.in.h, lib/verify.h, m4/00gnulib.m4:
+ * m4/absolute-header.m4, m4/alloca.m4, m4/canonicalize.m4, m4/dup2.m4:
+ * m4/fchmodat.m4, m4/fcntl.m4, m4/fdopendir.m4, m4/fpending.m4:
+ * m4/futimens.m4, m4/getdtablesize.m4, m4/getloadavg.m4:
+ * m4/gnulib-common.m4, m4/include_next.m4, m4/largefile.m4:
+ * m4/manywarnings.m4, m4/mktime.m4, m4/nstrftime.m4, m4/open-slash.m4:
+ * m4/pselect.m4, m4/pthread_sigmask.m4, m4/time_h.m4, m4/utimens.m4:
+ * m4/utimensat.m4, m4/utimes.m4, m4/warnings.m4:
+ Copy from Gnulib.
+ * lib/gnulib.mk.in: Regenerate.
+
+2020-08-16 Jonas Bernoulli <jonas@bernoul.li>
+
+ Allow overriding read--expression-try-read bindings
+
+ * lisp/simple.el (read--expression): No longer bind
+ read--expression-try-read here.
+ * lisp/simple.el (read-expression-map): Bind
+ read--expression-try-read here (bug#42893).
+
+ This new specialized command was recently added in [1: 4a6dd13fa4].
+ It reestablishes the bindings every time `read--expression' is
+ invoked, which is wrong because it makes it impossible for users
+ to remove these bindings.
+
+ 1: 4a6dd13fa42c87175ac72e1980f31cac56582db3
+ Change 'M-:' to not error out on incomplete expressions.
+
+2020-08-16 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Implement list-system-processes on OpenBSD
+
+ * src/sysdep.c: Implement list-system-processes on OpenBSD:
+ (bug#13881). Based on a patch by Jérémie Courrèges-Anglas.
+
+2020-08-16 João Távora <joaotavora@gmail.com>
+
+ Don't let docless variables hide function signature
+
+ In Elisp mode, ElDoc will try the variable's docstring first, then the
+ function signature. If the former doesn't have one, don't hide the
+ latter.
+
+ * lisp/progmodes/elisp-mode.el (elisp-eldoc-var-docstring): If no
+ symbol docstring, don't declare any.
+
+2020-08-16 Stefan Kangas <stefankangas@gmail.com>
+
+ Add new option flyspell-correct-on-mouse-3
+
+ * lisp/textmodes/flyspell.el
+ (flyspell-correct-on-mouse-3): New option to bind
+ 'flyspell-correct-word' to 'mouse-3'.
+ (flyspell--set-correct-on-mouse-3): New function to update option.
+ (flyspell-mode): Update 'flyspell-mouse-map' if above option is
+ set.
+ * doc/emacs/fixit.texi (Spelling): Mention the new option.
+ * etc/NEWS: Announce the new option.
+
+2020-08-16 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove redundant :group args from flyspell.el
+
+ * lisp/textmodes/flyspell.el: Remove redundant :group args.
+
+2020-08-16 Stefan Kangas <stefankangas@gmail.com>
+
+ Mark XEmacs compat alias as obsolete
+
+ * lisp/subr.el (user-original-login-name): Mark as obsolete. This
+ XEmacs compat alias was obsoleted even by XEmacs, so there is no point
+ in keeping it around.
+
+2020-08-16 Steven Allen <steven@stebalien.com>
+
+ Set the current buffer in esh-mode before running filter functions
+
+ * lisp/eshell/esh-mode.el: (eshell-output-filter): Match
+ current-buffer behavior of comint-output-filter (bug#42870).
+
+ This change (a) sets the current buffer to the process-buffer when
+ invoking preoutput filter functions and (b) only invokes them when the
+ process-buffer is live. Otherwise, the preoutput filter functions be
+ invoked in whatever buffer happens to be focused, breaking hooks that
+ read buffer-local variables.
+
+2020-08-16 Mattias Engdegård <mattiase@acm.org>
+
+ Stop using calc for ntlm time computation
+
+ * lisp/net/ntlm.el: Don't require calc.
+ (ntlm-compute-timestamp): Use plain arithmetic instead of calc.
+ (ntlm--time-to-timestamp): New helper function.
+
+2020-08-16 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/net/eudc-bob.el (eudc-bob-pipe-object-to-external-program): Simplify
+
+ Use `with-temp-buffer`.
+
+2020-08-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/net/eudc-bob.el: Use lexical-binding; Misc simplifications
+
+ (eudc-bob-generic-keymap, eudc-bob-image-keymap)
+ (eudc-bob-sound-keymap, eudc-bob-url-keymap, eudc-bob-mail-keymap):
+ Move initialization into declaration. Use RET rather than `return`.
+ (eudc-jump-to-event): Delete; use `mouse-set-point` instead.
+ (eudc-bob-save-object): Rewrite using `write-region`.
+ (eudc-bob-popup-menu): Use `popup-menu`.
+
+2020-08-15 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix recently-introduced Fdelete bug
+
+ Problem reported by Pip Cet in:
+ https://lists.gnu.org/r/emacs-devel/2020-08/msg00444.html
+ * src/fns.c (Fdelete): Fix correctness bug via a simpler (though more
+ memory-intensive) approach. It’s probably not worth optimizing
+ the memory usage yere.
+ * test/src/fns-tests.el (test-vector-delete): Add test for the bug.
+
+2020-08-15 Andrea Corallo <akrl@sdf.org>
+
+ Remove a warning for conventional build
+
+ * src/lread.c (parent_directory): Add ATTRIBUTE_UNUSED.
+
+2020-08-15 Paul Eggert <eggert@cs.ucla.edu>
+
+ Minimize ‘equal’ calls in (delete x vector)
+
+ * src/fns.c (Fdelete): When deleting from a vector, call Fequal
+ only once per vector element. This is faster when Fequal is slow,
+ and avoids the need to preinitialize the vector result. Finish
+ when the result is exhausted, not when the input is exhausted;
+ the two are equivalent but the former may be faster.
+ * test/src/fns-tests.el (test-vector-delete): New test.
+
+2020-08-15 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fdelete speed tweak for strings
+
+ * src/fns.c (Fdelete): Hoist FIXNUMP out of a loop,
+ and turn it into CHARACTERP.
+
+2020-08-15 Paul Eggert <eggert@cs.ucla.edu>
+
+ Prefer Fvector to make_uninit_vector
+
+ Fvector is less error-prone than make_uninit_vector, as it
+ avoids the possibility of a GC crash due to an uninitialized
+ vector. So prefer Fvector to make_uninit_vector when this is
+ easy (and when there's no significant performance difference).
+ Inspired by a suggestion by Pip Cet in:
+ https://lists.gnu.org/r/emacs-devel/2020-08/msg00313.html
+ * src/ccl.c (Fregister_ccl_program):
+ * src/ccl.c (Fregister_ccl_program):
+ * src/charset.c (Fdefine_charset_internal):
+ * src/font.c (Fquery_font, Ffont_info, syms_of_font):
+ * src/fontset.c (font_def_new, Fset_fontset_font):
+ * src/ftfont.c (ftfont_shape_by_flt):
+ * src/hbfont.c (hbfont_shape):
+ * src/macfont.m (macfont_shape):
+ * src/search.c (Fnewline_cache_check):
+ * src/xfaces.c (Fx_family_fonts):
+ * src/xfns.c (Fx_window_property_attributes):
+ Prefer Fvector to make_uninit_vector when either is easy.
+ * src/fontset.c (font_def_new): Now a function with one less
+ arg instead of a do-while macro, and renamed from FONT_DEF_NEW.
+ All uses changed.
+
+2020-08-15 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix GC bugs related to uninitialized vectors
+
+ Avoid problems if GC occurs while initializing a vector.
+ Problem with Fdelete reported by Pip Cet in:
+ https://lists.gnu.org/r/emacs-devel/2020-08/msg00313.html
+ I looked for similar problems elsewhere and found quite a few.
+ * src/coding.c (make_subsidiaries):
+ * src/composite.c (syms_of_composite):
+ * src/font.c (build_style_table, Ffont_get_glyphs):
+ * src/nsselect.m (clean_local_selection_data):
+ * src/nsxwidget.m (js_to_lisp):
+ * src/syntax.c (init_syntax_once):
+ * src/window.c (Fcurrent_window_configuration):
+ * src/xselect.c (selection_data_to_lisp_data)
+ (clean_local_selection_data):
+ Use make_nil_vector instead of make_uninit_vector.
+ * src/fns.c (Fdelete):
+ * src/xwidget.c (webkit_js_to_lisp):
+ Use allocate_nil_vector instead of allocate_vector.
+ * src/search.c (Fnewline_cache_check):
+ Use make_vector instead of make_uninit_vector.
+
+2020-08-15 Roland Kaufmann <rlndkfmn+emacs@gmail.com> (tiny change)
+
+ Allow build configuration on Apple ARM devices (bug#41994)
+
+ * configure.ac: Add arm as a port target for Darwin.
+
+2020-08-15 Tino Calancha <tino.calancha@gmail.com>
+
+ Prevent from frozen frame after `C-z' in Lucid builds
+
+ Some WMs (e.g. mutter in Gnome Shell) don't unmap iconized windows,
+ thus we won't get a MapNotify when deconifying them.
+ Check if we are deconifying a window elsewhere (Bug#42655).
+
+ - src/xterm.c (handle_one_xevent):
+ Check for window deconify when receiving a FocusIn signal.
+
+2020-08-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new variable term-set-terminal-size (not setting LINES/COLUMNS)
+
+ * lisp/term.el (term-set-terminal-size): New variable (bug#37564).
+ (term-exec-1): Use it. Based on a patch from Matthew Leach
+ <matthew@mattleach.net>.
+
+2020-08-15 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make Gnus stop clobbering the M-s search prefix key binding
+
+ * doc/emacs/misc.texi (Gnus Summary Buffer): Ditto.
+
+ * doc/misc/gnus.texi (Searching for Articles): Document moved M-s
+ (bug#39706).
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-mode-map): Move
+ gnus-summary-search-article-forward to M-s M-s, and add M-s M-r
+ for gnus-summary-search-article-backward.
+
+2020-08-15 Steven Allen <steven@stebalien.com>
+
+ Fix thinko in setting url-portspec
+
+ * lisp/url/url-expand.el (url-default-expander): Set
+ `url-portspec' (bug#42869).
+
+2020-08-15 Dario Gjorgjevski <dario.gjorgjevski+git@gmail.com>
+
+ Tweak how ido handles killing virtual buffers
+
+ * lisp/ido.el (ido-buffer-internal): Handle killing of virtual buffers
+ as a special case.
+ (ido-visit-buffer): Document the special case (bug#38294).
+
+2020-08-15 Eli Zaretskii <eliz@gnu.org>
+
+ Don't wrap lines at NBSP when nobreak-char-display is t
+
+ * src/xdisp.c (get_next_display_element): When
+ nobreak-char-display is t, display NBSP and non-ASCII hyphens as
+ themselves, not as their ASCII counterparts, just with the
+ nobreak-space/nobreak-hyphen face. (Bug#42811)
+
+2020-08-15 Jari Aalto <jari.aalto@cante.net>
+
+ Add support for ffap guessing at file names containing spaces
+
+ * lisp/ffap.el (ffap-file-name-with-spaces): New variable (bug#8439).
+ (ffap-search-backward-file-end, ffap-search-forward-file-end)
+ (ffap-dir-separator-near-point): New functions.
+ (ffap-string-at-point): Use the variable and the new functions to
+ guess at files containing strings.
+
+2020-08-15 Eli Zaretskii <eliz@gnu.org>
+
+ Document the 'flex' completion style
+
+ * doc/emacs/mini.texi (Completion Styles): Document the 'flex'
+ completion style. (Bug#42763)
+
+2020-08-15 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify Apple clang 11 __builtin_assume
+
+ Problem reported by Mattias Engdegård in:
+ https://lists.gnu.org/r/emacs-devel/2020-08/msg00300.html
+ * src/lisp.h (bool_vector_bitref, bool_vector_set):
+ Use eassert instead of eassume for bool_vector_size checks.
+
+2020-08-15 Amin Bandali <bandali@gnu.org>
+
+ Add `message' to erc-match.el highlight types
+
+ * lisp/erc/erc-match.el (erc-current-nick-highlight-type,
+ erc-pal-highlight-type, erc-fool-highlight-type,
+ erc-keyword-highlight-type, erc-dangerous-host-highlight-type): Add
+ `message' type for highlighting the entire message but not the
+ sender's nick.
+ (erc-match-message): Check for the new `message' highlight type and
+ propertize the message (not including the nick) accordingly.
+ * etc/NEWS: Announce the addition of the `message' highlight type.
+
+2020-08-15 Paul Eggert <eggert@cs.ucla.edu>
+ Pip Cet <pipcet@gmail.com>
+
+ Fix bus error on Debian bullseye
+
+ Problem reported by Lars Ingebrigtsen, and problem diagnosis
+ and most of this patch by Pip Cet (Bug#42832).
+ * src/pdumper.c (dump_bitsets_init): Rename from dump_bitset_init.
+ All callers changed. Initialize two bitsets with a single malloc
+ call.
+ (struct pdumper_loaded_dump_private): New member last_mark_bits.
+ (pdumper_find_object_type_impl): Return PDUMPER_NO_OBJECT if
+ the last_mark_bits’ bit is clear.
+ (pdumper_set_marked_impl): Assert that the last_mark_bits’
+ bit is set.
+ (pdumper_clear_marks_impl): Save mark_bits into
+ last_mark_bits before clearing mark_bits.
+
+2020-08-14 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove XEmacs compat code from mwheel.el
+
+ * lisp/mwheel.el (mwheel-event-button, mwheel-event-window):
+ Remove XEmacs compat code.
+
+2020-08-14 Noam Postavsky <npostavs@gmail.com>
+
+ Make configure say so if we have "--with-json" but no jansson support
+
+ * configure.ac (OPTION_DEFAULT_IFAVAILABLE): New macro. Use it to
+ define the --with-json option. Add with_json and HAVE_JSON to the
+ 'MISSING' checks (bug#39953).
+
+2020-08-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mop up project-kill-buffers-ignores renaming
+
+ * doc/emacs/maintaining.texi (Project Buffer Commands): Update
+ project-kill-buffers-ignores that was renamed recently
+ (bug#41868) (in 2ab66c9f9be923350f123fdea05b5b3ce8283d8a).
+
+2020-08-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Note that Emacs needs systemd support if systemd is used to stop/start
+
+ * etc/NEWS: Note that Emacs needs to be built with systemd support
+ systemd is used to stop/start Emacs (bug#42242). Change suggested by
+ Bhavin Gandhi <bhavin7392@gmail.com>
+
+2020-08-14 Yuan Fu <casouri@gmail.com>
+
+ Add two new commands for centering doc-view images
+
+ * lisp/doc-view.el (doc-view-mode-map): Add binding for centering
+ commands.
+ (doc-view-center-page-horizontally, doc-view-center-page-vertically):
+ New functions (bug#42272).
+
+2020-08-14 Gregory Heytings <ghe@sdf.org> (tiny change)
+
+ Fix visual fringe glitch in diff-mode
+
+ * lisp/vc/diff-mode.el (diff--font-lock-prettify): Fix problems
+ with visual gaps in the fringes when changing font size (bug#42300).
+
+2020-08-14 Stefan Kangas <stefankangas@gmail.com>
+
+ Comment to postpone deletion of c-subword-mode
+
+ * lisp/progmodes/subword.el (c-subword-mode): Clarify that this
+ obsolete function alias should not be removed just yet. There is a
+ copy of this definition in cc-cmds.el, obsolete since 24.3, and it is
+ better to delete both at the same time.
+
+2020-08-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/perl-mode.el (perl--syntax-exp-intro-regexp): Bug#42168
+
+ * test/lisp/progmodes/cperl-mode-tests.el: Adjust for `perl-mode`.
+ (cperl-test-ppss): Rename from `cperl-test-face` and change return value.
+ (cperl-mode-test-bug-42168): Test the `syntax-ppss` state rather than
+ the font-lock faces, so it works for both `perl-mode` and `cperl-mode`.
+
+2020-08-14 Mauro Aranda <maurooaranda@gmail.com>
+
+ Make sure we only act on edited widgets in Custom-save
+
+ * lisp/cus-edit.el (Custom-save): Only act on edited widgets in the
+ buffer. If we attempt to redraw all widgets, we confuse
+ custom-variable-modified-p, or we end up drawing State buttons for
+ all options, including the hidden ones (bug#42801).
+
+2020-08-14 Jonas Bernoulli <jonas@bernoul.li>
+
+ Parse the whole buffer at once in compile.el
+
+ * lisp/progmodes/compile.el (compilation-next-single-property-change):
+ Parse whole buffer at once (bug#42806).
+
+ Also remove the comment that mentioned that it is an option to do it
+ in one go as we now actually start doing. As the existence of that
+ comment suggested, there is not really a reason to process the buffer
+ in small chunks. On the contrary, processing the output in arbitrary
+ units can result in certain constructs not being recognized because
+ they begin in one arbitrary chunk, while ending in another.
+
+2020-08-14 Dmitry Gutov <dgutov@yandex.ru>
+
+ Unbreak project-find-regexp in Emacs 26.3 (bug#42765)
+
+ * lisp/progmodes/project.el: Depend on xref. Bump the version.
+
+ * lisp/progmodes/xref.el: Remove 'project' from the list of
+ dependencies. Depending on Emacs 26.3 already ensures that some
+ version is available. Bump the version.
+ (xref--process-file-region): Move from project.el with a rename.
+ Update the sole caller.
+ (xref-backend-references): Make compatible with old project.el.
+ Update the docstring.
+
+2020-08-14 Ferdinand Pieper <git@pie.tf>
+
+ Fix flow filling for flowing multiple flowed lines
+
+ * lisp/mail/flow-fill.el (fill-flowed): Loop until all flowed lines
+ are collected.
+ * test/lisp/mail/flow-fill-tests.el
+ (fill-flow-tests-fill-flowed-decode): Also test for multiple
+ flowed lines (bug#42855).
+
+2020-08-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * doc/lispref/searching.texi (Regexp Special): Tweak wording
+
+2020-08-14 Yuan Fu <casouri@gmail.com>
+
+ Allow doc-view.el to rescale without imagemagick support
+
+ * lisp/doc-view.el (doc-view-mode-p, doc-view-enlarge)
+ (doc-view-scale-reset, doc-view-insert-image): Remove checks for
+ imagemagick (bug#42272) -- Emacs can rescale images without imagemagick.
+
+2020-08-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Change icomplete-show-matches-on-no-input behavior
+
+ * lisp/icomplete.el (icomplete-show-matches-on-no-input): Doc fix.
+ (icomplete-completions): Set completion-content-when-empty.
+
+ * lisp/minibuffer.el (completion-content-when-empty): New variable.
+ (completion--complete-and-exit): Use it (bug#19032).
+
+ Based on a patch by Matthew Leach <matthew@mattleach.net>.
+
+2020-08-14 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove Emacs 22 compat code from semantic
+
+ * lisp/cedet/semantic/bovine/c.el (semantic-c-end-of-macro):
+ Make into obsolete function alias for 'c-end-of-macro'.
+ (semantic-lex-cpp-define, semantic-lex-c-macrobits):
+ * lisp/cedet/semantic/lex-spp.el (semantic-lex-spp-paren-or-list):
+ Adjust callers.
+
+2020-08-14 Stefan Kangas <stefankangas@gmail.com>
+
+ Make Emacs 20 compat code in derived.el obsolete
+
+ * lisp/emacs-lisp/derived.el (derived-mode-setup-function-name):
+ Declare obsolete. This was for compatibility with Emacs 20 or older.
+
+2020-08-14 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove many items obsolete since Emacs 23.1
+
+ Emacs 23.1 was five major releases and over a decade ago.
+ This list can be reviewed before to the next release, but for now
+ hopefully this motivates any needed external updates.
+ Ref: https://lists.gnu.org/archive/html/emacs-devel/2020-05/msg02198.html
+
+ * lisp/abbrev.el (pre-abbrev-expand-hook):
+ * lisp/bookmark.el (bookmark-read-annotation-text-func)
+ (bookmark-jump-noselect):
+ * lisp/buff-menu.el (buffer-menu-mode-hook):
+ * lisp/cus-edit.el (custom-mode-hook, custom-mode):
+ * lisp/dirtrack.el (dirtrack-debug-toggle, dirtrack-debug):
+ * lisp/emacs-lisp/crm.el (crm-minibuffer-complete)
+ (crm-minibuffer-completion-help)
+ (crm-minibuffer-complete-and-exit):
+ * lisp/emacs-lisp/easymenu.el
+ (easy-menu-precalculate-equivalent-keybindings):
+ * lisp/emacs-lisp/lisp-mode.el (lisp-mode-auto-fill):
+ * lisp/epa.el (epa-display-verify-result):
+ * lisp/epg.el (epg-passphrase-callback-function):
+ * lisp/eshell/eshell.el (eshell-report-bug):
+ * lisp/ffap.el (ffap-bug, ffap-submit-bug):
+ * lisp/files.el (locate-file-completion):
+ * lisp/hi-lock.el (hi-lock-face-history, hi-lock-regexp-history):
+ * lisp/hilit-chg.el (highlight-changes-initial-state)
+ (highlight-changes-active-string)
+ (highlight-changes-passive-string, global-highlight-changes):
+ * lisp/international/mule-cmds.el (nonascii-insert-offset)
+ (nonascii-translation-table):
+ * lisp/international/mule-diag.el (non-iso-charset-alist):
+ * lisp/international/mule-util.el (detect-coding-with-priority):
+ * lisp/international/mule.el (charset-id, charset-bytes)
+ (charset-list, char-valid-p, generic-char-p)
+ (char-coding-system-table, make-coding-system)
+ (set-coding-priority)
+ * lisp/mail/rmail.el (rmail-message-filter):
+ * lisp/minibuffer.el (complete-in-turn, dynamic-completion-table)
+ (completion-common-substring)
+ (minibuffer-local-must-match-filename-map):
+ * lisp/mouse.el (mouse-major-mode-menu, mouse-popup-menubar)
+ (mouse-popup-menubar-stuff):
+ * lisp/net/newst-treeview.el (newsticker-groups-filename):
+ * lisp/obsolete/tpu-edt.el (tpu-have-ispell, GOLD-map):
+ * lisp/password-cache.el (password-read-and-add):
+ * lisp/shell.el (shell-dirtrack-toggle):
+ * lisp/subr.el (forward-point, redisplay-end-trigger-functions)
+ (process-filter-multibyte-p, set-process-filter-multibyte):
+ * lisp/t-mouse.el (t-mouse-mode):
+ * lisp/term/w32-win.el (w32-focus-frame, w32-select-font):
+ * lisp/textmodes/ispell.el (ispell-aspell-supports-utf8):
+ * lisp/textmodes/remember.el (remember-buffer):
+ * lisp/tooltip.el (tooltip-hook):
+ * lisp/url/url-util.el (url-generate-unique-filename):
+ * lisp/url/url-vars.el (url-temporary-directory):
+ * lisp/vc/vc-hooks.el (vc-workfile-version)
+ (vc-default-working-revision):
+ * lisp/vc/vc-mtn.el (vc-mtn-command):
+ * lisp/vc/vc.el (vc-revert-buffer):
+ * lisp/vcursor.el (vcursor-toggle-vcursor-map):
+ Remove items, obsolete since Emacs 23.1.
+ * lisp/abbrev.el (expand-abbrev):
+ * lisp/epg.el (epg-context): Change
+ 'epg-passphrase-callback-function' call to 'epa-' alternative.
+ * lisp/eshell/em-rebind.el (eshell-cannot-leave-input-list): Don't
+ refer to removed function 'forward-point'.
+ * test/manual/etags/c-src/abbrev.c (Fexpand_abbrev):
+ (syms_of_abbrev): Don't run removed hook 'pre-abbrev-expand-hook'.
+ * lisp/international/mule.el (transform-make-coding-system-args):
+ Declare obsolete.
+ * lisp/progmodes/idlwave.el:
+ Update reference to removed function 'char-valid-p'.
+ * lisp/gnus/mml2015.el (epg-encrypt-string):
+ * lisp/gnus/mml1991.el (epg-make-context):
+ * lisp/gnus/mml-smime.el (autoload):
+ Remove autoload of removed 'epg-passphrase-callback-function'.
+ * lisp/minibuffer.el (completion-extra-properties):
+ Remove support for `completion-common-substring'.
+ * lisp/obsolete/tpu-edt.el (tpu-toggle-overwrite-mode)
+ Remove support for removed `spell' package.
+ * src/coding.c (syms_of_coding):
+ * doc/misc/efaq.texi:
+ * doc/emacs/frames.texi (Menu Mouse Clicks):
+ * doc/misc/url.texi (Customization): Doc fixes.
+
+2020-08-14 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Preserve the face foreground in Info-fontify-node"
+
+ This reverts commit 1bed252ae9109493133a0cc3e9aad9e9a5ddde37.
+
+ Juri Linkov says:
+
+ This patch breaks Info fontification, please revert it.
+ Here is what I said in the message sent later with another patch at
+ https://debbugs.gnu.org/14645#14
+
+ Using the text property `face' instead of `font-lock-face'
+ might break something, so a better patch below removes
+ the text properties `face info-index-match' from the Info buffer
+
+2020-08-14 Stefan Kangas <stefankangas@gmail.com>
+
+ Add test for Bug#41761
+
+ * test/lisp/simple-tests.el (simple-test-count-words-bug-41761):
+ New test.
+
+2020-08-14 Daniel Koning <dk@danielkoning.com> (tiny change)
+
+ Don't stop at field boundaries when counting words (Bug#41761)
+
+ * lisp/simple.el (count-words): Ensure that `forward-word-strictly'
+ moves point from one field to the next during the word-counting loop.
+
+2020-08-14 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Highlight '{$a++ / $b}' correctly
+
+ * lisp/progmodes/cperl-mode.el (cperl-find-pods-heres):
+ Recognize {$a++ / $b} correctly as division. (Bug#42168)
+ * test/lisp/progmodes/cperl-mode-tests.el: New file with test
+ verifying the fix.
+
+2020-08-14 Andrea Corallo <akrl@sdf.org>
+
+ Fix excessive echo area usage
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): Use
+ `with-temp-file' to fill temp-file.
+
+2020-08-14 Andrea Corallo <akrl@sdf.org>
+
+ * src/pdumper.c (dump_do_dump_relocation): Improve error messages.
+
+2020-08-14 Stefan Kangas <stefankangas@gmail.com>
+
+ Make erc-compat.el obsolete
+
+ * lisp/erc/erc-compat.el: Move from here...
+ * lisp/obsolete/erc-compat.el: ...to here.
+ * lisp/erc/erc-backend.el:
+ * lisp/erc/erc-pcomplete.el:
+ * lisp/erc/erc-stamp.el:
+ * lisp/erc/erc-track.el:
+ * lisp/erc/erc.el: Don't require 'erc-compat'.
+
+ * lisp/erc/erc-backend.el (erc-decode-string-from-target):
+ * lisp/erc/erc-dcc.el (pcomplete/erc-mode/DCC):
+ * lisp/erc/erc-fill.el (erc-fill-mode):
+ * lisp/erc/erc-goodies.el (erc-controls-interpret):
+ * lisp/erc/erc-log.el (erc-log-setup-logging):
+ * lisp/erc/erc-notify.el (erc-notify-QUIT):
+ * lisp/erc/erc.el (erc-startup-file-list, define-erc-module)
+ (erc-canonicalize-server-name, erc-cmd-SV, erc-banlist-update)
+ (erc-group-list, erc-seconds-to-string): Adjust callers.
+ * lisp/erc/erc.el: Require cl-lib and format-spec.
+
+ * etc/NEWS: Add entry announcing erc-compat.el being marked as
+ obsolete.
+
+2020-08-14 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-08-13 sys_random: Work around an uClibc bug
+ * lib/sys_random.in.h, m4/getrandom.m4, m4/sys_random_h.m4:
+ Copy from Gnulib.
+
+2020-08-14 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix startup working dir bug on NeXTSTEP
+
+ * src/emacs.c (main) [NS_IMPL_COCOA]: Update emacs_wd
+ after a NS GUI chdirs successfully (Bug#42836).
+
+2020-08-13 Stefan Kangas <stefankangas@gmail.com>
+
+ Add tests for cl-{incf,decf}
+
+ * test/lisp/emacs-lisp/cl-lib-tests.el (cl-lib-test-incf)
+ (cl-lib-test-decf): New tests.
+
+2020-08-13 Alan Third <alan@idiocy.org>
+
+ Fix slow down when moving between monitors (bug#42834)
+
+ * src/nsterm.m ([EmacsView windowDidChangeBackingProperties:]):
+ Recreate the buffer every time.
+
+2020-08-13 Tobias Zawada <i_inbox@tn-home.de> (tiny change)
+
+ Handle nil load-path element in read-library-name
+
+ * lisp/emacs-lisp/find-func.el (read-library-name): Fix handling of
+ nil 'load-path' element. (Bug#41998)
+
+2020-08-13 Glenn Morris <rgm@gnu.org>
+
+ Update a paragraphs test
+
+ * test/lisp/textmodes/paragraphs-tests.el
+ (paragraphs-tests-mark-paragraph): Update for recent change.
+
+2020-08-13 Glenn Morris <rgm@gnu.org>
+
+ Update a compile test
+
+ * test/lisp/progmodes/compile-tests.el (compile-test-error-regexps):
+ Update info/warning count for recent compile.el change.
+
+2020-08-13 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 69568674b3 (origin/emacs-27) Improve documentation of function argume...
+ 1c0bc1ccd8 Improve documentation of special events
+
+2020-08-13 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 63f614d76c Fix comint-redirect-results-list regexp usage (Bug#42662)
+
+2020-08-13 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 86d8d76aa3 (tag: emacs-27.1-rc2, tag: emacs-27.1) ; lisp/ldefs-boot.e...
+ a6634197da * etc/HISTORY: Update the Emacs 27.1 release date.
+ a68b3f761a ; Update ChangeLog.3
+ 7cc85e7b51 ; Update etc/AUTHORS
+ 1ca4da054b ; * etc/NEWS: fix some quoting
+ 5578febcd4 ; * lisp/so-long.el: Documentation
+ fa20e443c8 lisp/so-long.el: Improve support for major mode hooks
+
+ # Conflicts:
+ # etc/AUTHORS
+ # etc/NEWS
+
+2020-08-13 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of function argument lists
+
+ * doc/lispref/functions.texi (Lambda Components)
+ (Defining Functions): Add a cross-reference to "Argument List".
+ (Argument List): Improve the section name. (Bug#42750)
+
+2020-08-13 Eli Zaretskii <eliz@gnu.org>
+
+ Improve documentation of special events
+
+ * doc/lispref/commands.texi (Misc Events): Explain how to bind
+ special events to commands.
+
+2020-08-13 Eli Zaretskii <eliz@gnu.org>
+
+ Fix face merging at EOL when inherited face specifies :extend
+
+ * src/xfaces.c (merge_face_ref): Handle correctly faces that
+ inherit from another, and in addition specify :extend.
+ (Bug#42552)
+
+ (cherry picked from commit 39c90f8dfabe158ad7ac9243aa9b9dedb9409e19)
+
+2020-08-13 Eli Zaretskii <eliz@gnu.org>
+
+ Fix face extension past EOL in overlay strings
+
+ * src/xdisp.c (face_at_pos): Pass ATTR_FILTER to
+ face_for_overlay_string.
+ * src/xfaces.c (face_for_overlay_string): Accept an additional
+ argument ATTR_INDEX and pass it to merge_face_ref for merging the
+ face at POS. This ensures a face from buffer text will not be
+ merged unless it specifies the :extend attribute. (Bug#42552)
+ * src/dispextern.h (face_for_overlay_string): Adjust prototype.
+
+ (cherry picked from commit 35564bea4d73bc266743216599d01d644aed6fd8)
+
+2020-08-13 Juri Linkov <juri@jurta.org>
+
+ Preserve the face foreground in Info-fontify-node
+
+ * lisp/info.el (Info-fontify-node): Preserve the face foreground.
+ Previously `Info-index' added the `info-index-match' face to the
+ strings of the found index entries. Later
+ `Info-virtual-index-find-node' inserts strings to the Info buffer.
+ And finally `Info-fontify-node' puts the `font-lock-face' property
+ with `info-xref' on links. The `face info-index-match' takes
+ precedence over `font-lock-face info-xref' (bug#14645).
+
+2020-08-13 Ryan Crum <ryan@ryancrum.org>
+
+ Add a new variable to not recenter term on all input
+
+ * lisp/term.el (term-scroll-snap-to-bottom): New variable (bug#15744).
+ * lisp/term.el (term-emulate-terminal): Use it.
+
+2020-08-13 Andrea Corallo <akrl@sdf.org>
+
+ * src/pdumper.c (dump_cold_native_subr): Clean-up *IMPLICIT_CONVERSION macros.
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-08-13 Dima Kogan <dima@secretsauce.net>
+
+ gcc-include compilation lines are now INFO, instead of WARNING
+
+ * lisp/progmodes/compile.el
+ (compilation-error-regexp-alist-alist): Prior to this patch the
+ line that contains "from a.h:1:0," was seen as INFO and the line
+ that contains "from a.c:1:" was seen as a WARNING. This patch
+ makes them both INFO (bug#17826).
+
+2020-08-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Ensure that server-socket-dir doesn't have "//" in the path
+
+ * lisp/server.el (server-socket-dir): Use expand-file-name to
+ avoid "//" in the path name (if either XDG_RUNTIME_DIR or TMPDIR
+ ends in a slash) (bug#18658).
+
+2020-08-13 H. Dieter Wilhelm <dieter@duenenhof-wilhelm.de>
+
+ Handle negative prefix arguments to mark-paragraph correctly
+
+ * lisp/textmodes/paragraphs.el (mark-paragraph): Handle negative
+ arguments correctly (bug#18847). This makes `M- M-h M-h' do the
+ correct thing with expanding the region (like other marking
+ commands) backwards. Also fix problem at the end of the buffer,
+ where the numbers of paragraphs left in the buffer is less than
+ ARG, then paragraphs would also be marked *before* the current
+ paragraph. Also clarify the doc string.
+
+2020-08-13 Jonas Bernoulli <jonas@bernoul.li>
+
+ Update section heading conventions for libraries
+
+ * doc/lispref/tips.texi (Comment Tips): Update information on section
+ headings to reflect common usage.
+
+ Previously the tips stated that if the code is split up into multiple
+ sections, then that should be done by splitting up the ";;; Code:"
+ section into multiple sub-sections.
+
+ However about half the libraries in Emacs instead use multiple
+ top-level sections. We update the tips (aka conventions) to allow
+ this common usage, but because it is awkward if there is a section
+ named "Code", which contains only some of the code instead of all of
+ it, we now recommend that that section should be empty in this case.
+
+ We cannot just give up on the "Code:" section/heading because that is
+ an old convention that is followed be nearly every library and because
+ it is likely that there are some utilities out there that depend on
+ its presence.
+
+ This was discussed in
+ https://lists.gnu.org/archive/html/emacs-devel/2020-07/msg00444.html
+ https://lists.gnu.org/archive/html/emacs-devel/2020-08/msg00001.html
+
+2020-08-13 Jonas Bernoulli <jonas@bernoul.li>
+
+ * lisp/font-lock.el: No longer use headings as end of section markers.
+
+ Each section ends right before the following section begins and IMO
+ that means that it is unnecessary to mark the end of sections.
+
+ For users of `outline-minor-mode' the old end-of-section markers were
+ a distraction. They made it much harder to parse the overview outline
+ state because each section heading was followed by a end-of-section
+ marker that was formatted as a section heading. Because of this I
+ wanted to remove the end-of-section markers.
+
+ But as Eli pointed out these sections are long and not everyone uses
+ `outline-minor-mode'.
+
+ So instead of removing them, I am turning the end-of-section markers
+ into regular comments (beginning with just two semicolons) instead of
+ section headings (beginning with tree semicolons). That way users of
+ `outline-minor-mode' won't be distracted by them and others can still
+ benefit from the markers as before.
+
+2020-08-13 Jonas Bernoulli <jonas@bernoul.li>
+
+ * lisp/font-lock.el: Split the Commentary into subsections.
+
+ The "Commentary" was already split into multiple sections, but
+ these sections where on the same level as "Commentary" itself,
+ which is less convenient for users of `outline-minor-mode'.
+
+2020-08-13 Jonas Bernoulli <jonas@bernoul.li>
+
+ * lisp/net/imap.el: Use proper outline headings
+
+ This library already used section headings but it used just two
+ instead of three semicolons, making them indistinguishable from
+ plain comments. One heading is new.
+
+2020-08-13 Jonas Bernoulli <jonas@bernoul.li>
+
+ * lisp/obsolete/longlines.el: Use proper outline headings.
+
+ This library already used section headings but it used just two
+ instead of three semicolons, making them indistinguishable from
+ plain comments. One heading is new.
+
+2020-08-13 Jonas Bernoulli <jonas@bernoul.li>
+
+ * test/src/emacs-module-tests.el: Use proper outline headings.
+
+ This library already used section headings but it used just two
+ instead of three semicolons, making them indistinguishable from
+ plain comments.
+
+2020-08-13 Jonas Bernoulli <jonas@bernoul.li>
+
+ * lisp/mail/smtpmail.el: Use outline headings.
+
+2020-08-13 Jonas Bernoulli <jonas@bernoul.li>
+
+ * lisp/progmodes/compile.el: Remove unnecessary comments.
+
+ These comments are unnecessary because the doc-strings that follow
+ already cover the same ground, while being more concise. These
+ comments were also prefixed with too many semicolons, causing them
+ to be treated as outline headings.
+
+2020-08-13 Jonas Bernoulli <jonas@bernoul.li>
+
+ Merge two conditions and fix indentation
+
+ The motivation behind this change is that the indentation of some
+ lines was outright wrong. If we address that issue, then we might
+ as well also address the issue that some code is needlessly nested
+ an additional level. That we can fix by merging the conditions.
+
+ By doing these two changes in on commit we have to change the fewest
+ lines. Even though we are moving to using just spaces for indentation
+ of the modified lines, other lines in the same function are left alone
+ and continue to us tabs+spaces for indentation. That is not "wrong",
+ but just the style we are slowly migrating away from when touching
+ lines for other reasons.
+
+ Discussed in bug#42397.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-minibuffer-message): Merge two
+ conditions and fix indentation.
+
+2020-08-13 Jonas Bernoulli <jonas@bernoul.li>
+
+ Split EasyPG libraries into outline sections
+
+ * lisp/epa-dired.el:
+ lisp/epa-file.el:
+ lisp/epa-hook.el:
+ lisp/epa-mail.el:
+ lisp/epa.el:
+ lisp/epg-config.el:
+ lisp/epg.el: Split into outline sections.
+ * lisp/epg.el (epg-error): Move definition.
+
+2020-08-13 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't output emacsclient warning if both -a and --quiet
+
+ * lib-src/emacsclient.c (set_local_socket): Don't output the
+ warning if both -a and --quiet are specified (bug#16117).
+ Inspired by a patch from Scott Turner <srt19170@gmail.com>.
+
+2020-08-13 Emilio Lopes <eclig@gmx.net>
+
+ Notify the user if we errors when querying for registered git files
+
+ * lisp/vc/vc-git.el (vc-git-registered): Notify the user when
+ something fails here (bug#18481).
+
+2020-08-13 Paul Eggert <eggert@cs.ucla.edu>
+
+ mml-secure-en-decrypt-sign-2 is unstable
+
+ * test/lisp/gnus/mml-sec-tests.el (mml-secure-en-decrypt-sign-2):
+ Mark as unstable (Bug#42720).
+
+2020-08-13 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove Emacs 22 compat code from dns.el
+
+ * lisp/net/dns.el (dns-servers-up-to-date-p, dns-set-servers):
+ Remove check for function that is always there.
+
+2020-08-13 Stefan Kangas <stefankangas@gmail.com>
+
+ Declare semantic XEmacs compat code obsolete
+
+ * lisp/cedet/semantic/grammar.el
+ (semantic-grammar-setup-menu-xemacs): Declare obsolete.
+
+2020-08-13 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove XEmacs compat code from allout-widgets.el
+
+ * lisp/allout-widgets.el
+ (allout-widgets-item-image-properties-xemacs)
+ (allout-item-widget, allout-fetch-icon-image)
+ (allout-widgets-copy-list): Remove XEmacs compat code.
+
+2020-08-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/net/mailcap.el (mailcap-mime-data): Remove long-forgotten `ee`
+
+ It referred apparently to the "Electric Eyes" image viewer:
+ https://archive.org/details/tucows_31588_Electric_Eyes
+
+2020-08-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ Stop using Gnulib inttypes module
+
+ It wasn’t needed for MinGW after all, no other platform
+ seems to need it, and it slows down ‘configure’.
+ * admin/merge-gnulib (GNULIB_MODULES): Remove inttypes.
+ * m4/gnulib-comp.m4: Regenerate.
+
+2020-08-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-08-12 stdint: port intptr_t to more-recent MinGW
+ 2020-08-11 Use __restrict also on clang
+ 2020-08-11 Use flexible array syntax also on clang
+ 2020-08-11 fcntl: On native Windows, use _setmode, not setmode
+ * lib/binary-io.h, lib/cdefs.h, lib/fcntl.c, lib/regex.h:
+ * lib/stdint.in.h: Copy from Gnulib.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from mm-util.el
+
+ * lisp/gnus/mm-util.el (mm-charset-to-coding-system): Remove the
+ non-mule case, because it's always false.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Simplify the computation of mm-mime-mule-charset-alist
+
+ * lisp/gnus/mm-util.el (mm-mime-mule-charset-alist): For
+ compatibility with XEmacs, mm-mime-mule-charset-alist was first
+ set to a list of hard-coded entries, and then overwritten on Emacs
+ from `coding-system-list'. Remove the hard-coded values and
+ simplify the code.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from eudc-bob.el
+
+ * lisp/net/eudc-bob.el (eudc-bob-save-object)
+ (eudc-bob-pipe-object-to-external-program): Remove checks for
+ functions that are always defined in Emacs.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from url-handlers.el
+
+ * lisp/url/url-handlers.el (url-insert-buffer-contents): Remove
+ check for function that's always defined in Emacs.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from gnus.el
+
+ * lisp/gnus/gnus.el: Remove a check for a function that is always
+ defined.
+
+2020-08-12 Amin Bandali <bandali@gnu.org>
+
+ Add support for italic text in ERC
+
+ * lisp/erc/erc-goodies.el (erc-italic-face): New face for italic text.
+ (erc-controls-interpret), (erc-controls-highlight): Add `italicp'.
+ (erc-controls-remove-regexp),
+ (erc-controls-highlight-regexp): Handle C-] for italic.
+ (erc-controls-propertize): Add `italicp' argument and use it to
+ conditionally propertize text with the new `erc-italic-face'.
+ * etc/NEWS: Announce italic text support.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from viper-cmd.el
+
+ * lisp/emulation/viper-cmd.el (viper-register-to-point):
+ frame-configuration-p is always available in Emacs now.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from viper*.el
+
+ * lisp/emulation/viper.el (viper-go-away, viper-set-hooks)
+ (viper-non-hook-settings, viper-mode):
+ * lisp/emulation/viper-cmd.el (viper-normalize-minor-mode-map-alist)
+ (viper-harness-minor-mode): Remove a bunch of checks to do (or
+ not do) things based on whether add-to-ordered-list is fbound and
+ emulation-mode-map-alists is bound, because in Emacs now, these
+ are always true.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mark some unused defaliases in semantic/fw.el obsolete
+
+ * lisp/cedet/semantic/fw.el (semantic-run-mode-hooks)
+ (semantic-subst-char-in-string): Make two unused defaliases obsolete.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from epa.el
+
+ * lisp/epa.el (epa--derived-mode-p, epa-import-keys): Make
+ defalias obsolete, and adjust a comment.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from bubbles.el
+
+ * lisp/play/bubbles.el (bubbles--remove-overlays): Make into an
+ obsolete alias.
+ (bubbles--initialize, bubbles--show-images): Adjust callers.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix a check for whether Emacs can play sounds in eudc-bob
+
+ * lisp/net/eudc-bob.el (eudc-bob-sound-menu)
+ (eudc-bob-play-sound-at-point): Check for play-sound-internal
+ instead of play-sound, because the latter is always defined.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from allout.el
+
+ * lisp/allout.el (allout-numbered-bullet)
+ (allout-file-xref-bullet): string-or-null-p is always defined.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from allout*.el
+
+ * lisp/allout-widgets.el (allout-widgets-mode-inhibit): Ditto.
+
+ * lisp/allout.el (allout-use-hanging-indents)
+ (allout-show-bodies, allout-old-style-prefixes)
+ (allout-stylish-prefixes): `booleanp' is always defined.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from prolog.el
+
+ * lisp/progmodes/prolog.el (match-string): Remove alias to
+ function that always exists.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from idlwave.el
+
+ * lisp/progmodes/idlwave.el: Remove some checks for functions that
+ always exist.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove some compat code from ediff-init.el
+
+ * lisp/vc/ediff-init.el (subst-char-in-string, format-message):
+ Remove aliases to functions that always exist.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Check make-process to determine if we support multi-processing
+
+ * lisp/eshell/esh-proc.el (eshell-gather-process-output):
+ * lisp/comint.el (make-comint-in-buffer): Check that make-process
+ exists instead of start-file-process (which always exists).
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Remove compat code from esh-proc.el"
+
+ This reverts commit 97c4d941daffba1635bd738fae9c4ff36e5ad0cf.
+
+ We still have Emacs builds on systems with no multi-tasking.
+
+2020-08-12 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Remove compat code from comint.el"
+
+ This reverts commit 4d00db5538dc0ef47cf1cdf425b895d04145fe9e.
+
+ We still have Emacs builds on systems with no multi-taskin.
+
+2020-08-12 Tino Calancha <tino.calancha@gmail.com>
+
+ Do not truncate /foo//bar to /bar/ in parse-colon-path
+
+ * lisp/files.el (parse-colon-path): Use substitute-env-vars and
+ expand-file-name instead of substitute-in-file-name (Bug#21454).
+
+2020-08-12 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove Emacs 23 compat code from checkdoc.el
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-run-hooks): Redefine as
+ obsolete function alias for 'run-hook-with-args-until-success'.
+ (checkdoc-this-string-valid-engine)
+ (checkdoc-file-comments-engine): Adjust callers.
+
+2020-08-12 Stefan Kangas <stefankangas@gmail.com>
+
+ Minor cleanup in ps-def.el
+
+ * lisp/ps-def.el (ps-frame-parameter): Make alias obsolete.
+ * lisp/ps-print.el (ps-begin-job): Adjust caller.
+
+2020-08-12 Phil Sainty <psainty@orcon.net.nz>
+
+ Fix comint-redirect-results-list regexp usage (Bug#42662)
+
+ * lisp/comint.el (comint-redirect-results-list-from-process):
+ Don't treat the literal string argument COMMAND as a regexp.
+
+2020-08-12 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ Fix monospace font calculations on macOS
+
+ * src/macfont.m (macfont_monospace_width_multiplier): New function
+ to compute the width for monospace fonts (bug#24582).
+ (macfont_glyph_extents): Fix monospace glyph computation.
+ (macfont_shape): Ditto.
+
+2020-08-12 Mingde Matthew Zeng <matthewzmd@gmail.com>
+
+ Fix erc-reuse-buffers behavior
+
+ * lisp/erc/erc.el (erc-generate-new-buffer-name): Fixes behavior 1,
+ also determines if the '#channel/server' buffer already exists
+ and will reuse that buffer when joining on the same
+ server. Additionally when creating a new buffer with
+ '#channel/serverB', the existing buffer '#channel' on 'severA' will be
+ renamed to '#channel/serverA' for the sake of consistency (bug#40121).
+
+ * lisp/erc/erc-join.el (erc-autojoin-channels): The logic is
+ simplified ensuring that when autojoining channels specified in
+ erc-autojoin-channels-alist, if there exists an erc buffer with the
+ same channel name but a different server, it will create a new buffer
+ to join the channel. The current logic is very weak that will skip
+ joining same channel on different servers altogether.
+
+ By the definition of erc-reuse-buffers, if non-nil it should create a
+ new buffer when joining channels with same names on different
+ servers. The current behavior of erc-reuse-buffers is:
+ 1. when non-nil, it will always reuse the same channel buffer,
+ resulting in server A's channel gets reconnected to the channel with
+ the same name of server B.
+ 2. when nil, the buffer-name of the joined channel is
+ '#channel/server'. However if one tries to '/join #channel' from the
+ server buffer, it creates a new empty buffer with buffer-name
+ '#channel', instead of opening the already-joined channel buffer.
+
+2020-08-12 Michael Albinus <michael.albinus@gmx.de>
+
+ Implement Tramp direct async processes fallback for multi-hops
+
+ * doc/misc/tramp.texi (Remote processes): Precise restrictions for direct
+ async processes.
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-make-process):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process):
+ Use `tramp-direct-async-process-p'.
+
+ * lisp/net/tramp.el (tramp-direct-async-process-p): New defun.
+ (tramp-handle-make-process): Adapt handling of :stderr. Simplify.
+
+2020-08-12 Sungbin Jo <pcr910303@icloud.com>
+ Jaesup Kwak <veshboo@gmail.com>
+
+ Add utility functions and new xwidget commands
+
+
+ * lisp/xwidget.el (xwidget-webkit-callback): Add case for
+ 'response-callback' event.
+ (xwidget-webkit-download-dir): New variable.
+ (xwidget-webkit-save-as-file): New function.
+ * src/nsxwidget.m (XwWebView::decidePolicyForNavigationResponse):
+ Store download event.
+ * src/xwidget.c src/xwidget.h (store_xwidget_download_callback_event):
+ New function.
+
+2020-08-12 Sungbin Jo <pcr910303@icloud.com>
+ Jaesup Kwak <veshboo@gmail.com>
+
+ Add utility functions and new xwidget commands
+
+
+ * etc/NEWS: Announce new functions and options.
+ * lisp/xwidget.el (xwidget): New defgroup.
+ (xwidget-webkit-mode-map): Add new keybindings.
+ (xwidget-webkit-scroll-up, xwidget-webkit-scroll-down)
+ (xwidget-webkit-scroll-forward, xwidget-webkit-scroll-backward):
+ Add optional argument to specify specific amounts to scroll down.
+ (xwidget-webkit-scroll-up-line, xwidget-webkit-scroll-down-line): New
+ functions.
+ (xwidget-webkit-scroll-bottom): Fix function to scroll to the bottom
+ of the document.
+ (xwidget-webkit-callback): Use new function to update buffer title
+ even when Javascript is disabled.
+ (xwidget-webkit-bookmark-jump-new-session): New variable.
+ (xwidget-webkit-bookmark-make-record): Modify to use xwidget-webkit to
+ open bookmark that is created in xwidget-webkit.
+ (xwidget-webkit-insert-string): Fix Javascript snippet to not throw
+ Javascript exceptions.
+ (xwidget-webkit-inside-pixel-width)
+ (xwidget-window-inside-pixel-height): New functions.
+ (xwidget-webkit-adjust-size-to-window): Use new functions.
+ (xwidget-webkit-new-session): Insert invisible URL instead of an empty
+ string to achieve better default behavior.
+ (xwidget-webkit-back, xwidget-webkit-forward, xwidget-webkit-reload)
+ (xwidget-webkit-current-url): Use new functions to enable scrolling
+ even when Javascript is disabled.
+ (xwidget-webkit-copy-selection-as-kill): Remove unnecessary lambda.
+ * src/nsxwidget.h src/nsxwidget.m (nsxwidget_webkit_uri)
+ (nsxwidget_webkit_title, nsxwidget_webkit_goto_history): Add new
+ functions.
+ * src/xwidget.c (Fxwidget_webkit_uri, Fxwidget_webkit_title)
+ (Fxwidget_webkit_goto_history): Add new functions.
+ (syms_of_xwidget): Define new functions.
+
+2020-08-12 Glenn Morris <rgm@gnu.org>
+
+ Tweak recent solar.el change
+
+ * lisp/calendar/solar.el (sunrise-sunset, solar-equinoxes-solstices):
+ Use +0000 for "numeric" UTC, not +0100.
+
+2020-08-12 Glenn Morris <rgm@gnu.org>
+
+ Rename recent calendar user option
+
+ * lisp/calendar/calendar.el (calendar-time-zone-style):
+ Rename from calendar-use-numeric-time-zones.
+ * lisp/calendar/cal-dst.el (calendar-standard-time-zone-name)
+ (calendar-daylight-time-zone-name):
+ * lisp/calendar/solar.el (sunrise-sunset, solar-equinoxes-solstices):
+ Use new variable name.
+ * doc/emacs/calendar.texi (Sunrise/Sunset): Update.
+
+2020-08-12 Sungbin Jo <pcr910303@icloud.com>
+ Jaesup Kwak <veshboo@gmail.com>
+
+ Add xwidget support for macOS
+
+
+ * configure.ac: Allow '--with-xwidgets' for "${NS_IMPL_COCOA}".
+ * etc/NEWS: Mention new feature.
+ * etc/TODO: Remove done TODO to implement xwidget in NeXTstep port.
+ * lisp/xwidget.el (xwidget-webkit-clone-and-split-below)
+ (xwidget-webkit-clone-and-split-right): New procedures.
+ (xwidget-webkit-callback): Remove call to
+ 'xwidget-webkit-adjust-size-to-window' as adjusting xwidget size is
+ handled in 'x_draw_xwidget_glyph_string'.
+ (xwidget-webkit-enable-plugins): New variable.
+ * nextstep/templates/Info.plist.in: Add 'NSAppTransportSecurity'.
+ * src/Makefile.in: Add nsxwidget.o for compilation.
+ * src/emacs.c (main): Move conditional call to 'syms_of_xwidget'.
+ * src/nsterm.m (ns_draw_glyph_string): Add case for 'XWIDGET_GLYPH'.
+ (note_mouse_movement mouseMoved): Make it easy to resize window by
+ dragging mode-line or vertical separator adjacent to large glyph.
+ * src/nsxwidget.h src/nsxwidget.m: Newly added files, xwidget webkit
+ backend for macOS Cocoa.
+ * src/xwidget.c (Fmake_xwidget, xwidget_init_view)
+ (x_draw_xwidget_glyph_string, xwidget_is_web_view)
+ (Fxwidget_webkit_goto_uri, Fxwidget_webkit_zoom, Fxwidget_resize)
+ (Fxwidget_size_request, Fdelete_xwidget_view, xwidget_end_redisplay)
+ (kill_buffer_xwidgets): Add macOS Cocoa specific functions and code
+ with 'NS_IMPL_COCOA' and guard GTK specific functions and code with
+ 'USE_GTK'.
+ (x_draw_xwidget_glyph_string): Handle adjusting xwidget size.
+ * src/xwidget.h (xwidget, xwidget_view): Add macOS Cocoa specific
+ fields with 'NS_IMPL_COCOA' and guard GTK specific fields with
+ USE_GTK.
+
+2020-08-12 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove comment on Burma / Myanmar (Bug#42788)
+
+ * lisp/language/burmese.el: Remove comment on Burma / Myanmar.
+
+2020-08-12 Stefan Kangas <stefankangas@gmail.com>
+
+ Avoid ambiguity about what st refers to
+
+ * lisp/term/st.el: Add link to website.
+
+2020-08-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ Don’t warn about integer conversion in pdumper.c
+
+ Problem reported by Juanma Barranquero in:
+ https://lists.gnu.org/r/emacs-devel/2020-08/msg00279.html
+ and a similar glitch was reported by Eli Zaretskii (Bug#36597#67).
+ * src/pdumper.c: Remove -Wconversion pragma.
+ (ALLOW_IMPLICIT_CONVERSION, DISALLOW_IMPLICIT_CONVERSION):
+ Remove. All uses removed. Although -Wconversion may have
+ been helpful when writing pdumper.c it is now causing more
+ trouble than it’s worth here (just as in the rest of Emacs).
+ (dump_read_all): Avoid no-longer-necessary use of ‘size_t’
+ rather than ‘int’.
+
+2020-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove compat code from autoload.el
+
+ * lisp/emacs-lisp/autoload.el (autoload--make-defs-autoload):
+ register-definition-prefixes is in subr.el, so it shouldn't be
+ necessary to check whether it's defined.
+
+2020-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove compat code from comint.el
+
+ * lisp/comint.el (make-comint-in-buffer): `start-file-process' is
+ always defined, so remove test.
+
+2020-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove compat code from esh-proc.el
+
+ * lisp/eshell/esh-proc.el (eshell-gather-process-output):
+ `start-file-process' is always defined, so remove the code that
+ deals with Emacs versions that doesn't have it.
+
+2020-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove compat code from allout.el
+
+ * lisp/allout.el: (allout-process-exposed): Make
+ allout-region-active-p an obsolete alias, and adjust callers.
+
+2020-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove compat code in prolog.el
+
+ * lisp/progmodes/prolog.el (use-region-p): Remove compat code.
+
+2020-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Slight allout.el clean-up
+
+ * lisp/allout.el (allout-end-of-line, allout-mark-active-p): Make
+ allout-mark-active-p obsolete, and adjust callers.
+
+2020-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Minor idlwave clean up
+
+ * lisp/progmodes/idlw-shell.el (idlwave-shell-mouse-examine)
+ (idlwave-shell-print): Adjust callers.
+
+ * lisp/progmodes/idlwave.el (idlwave-region-active-p): Make into
+ obsolete alias.
+
+2020-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Slight gnus-util clean-up
+
+ * lisp/gnus/gnus-util.el (gnus-message-with-timestamp-1):
+ messages-buffer is always defined.
+
+2020-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Slight cleanup in calc-yank
+
+ * lisp/calc/calc-yank.el (calc-yank): Remove compat code.
+
+2020-08-11 Philipp Stephani <phst@google.com>
+
+ Unbreak build with --enable-checking=all
+
+ Commit 16a16645f524c62f7906036b0e383e4247b58de7 has only changed a
+ comment in ‘struct Lisp_Hash_Table’, so the portable dumper doesn’t
+ need to be adapted.
+
+ * src/pdumper.c (dump_hash_table): Update hash code for ‘struct
+ Lisp_Hash_Table’.
+
+2020-08-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ Use Gnulib inttypes module
+
+ Needed for platforms like MinGW that don’t support C99 PRIdPTR.
+ * admin/merge-gnulib (GNULIB_MODULES): Add inttypes.
+ * m4/gnulib-comp.m4: Regenerate.
+
+2020-08-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-08-11 Use expression statements also on clang
+ 2020-08-10 Use many __attribute__s with clang
+ 2020-08-09 Use attribute __aligned__ with clang
+ 2020-08-09 Use __alignof__ with clang
+ 2020-08-09 ignore-value: Simplify on clang
+ 2020-08-09 Use __typeof__ with clang
+ 2020-08-09 intprops: Fix typo in comment
+ 2020-08-09 Silence warnings from clang 10 with -Wimplicit-fallthrough
+ 2020-08-09 count-one-bits: Use __builtin_popcount{,l,ll} on clang
+ 2020-08-09 string: Fix build error in C++ mode with clang
+ 2020-08-09 Add ability to emit user-defined diagnostics with clang
+ 2020-08-07 alloca: No need to compile alloca.c with clang
+ 2020-08-06 Use __builtin_assume with clang
+ * lib/alloca.in.h, lib/arg-nonnull.h, lib/c++defs.h, lib/cdefs.h:
+ * lib/count-one-bits.h, lib/dirent.in.h, lib/ignore-value.h:
+ * lib/intprops.h, lib/malloca.h, lib/regex_internal.h:
+ * lib/stdalign.in.h, lib/stddef.in.h, lib/stdio.in.h:
+ * lib/stdlib.in.h, lib/string.in.h, lib/verify.h, lib/warn-on-use.h:
+ * m4/gnulib-common.m4, m4/stddef_h.m4, m4/stdint.m4:
+ Copy from Gnulib.
+
+2020-08-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ Prefer make_nil_vector to make-vector with nil
+
+ * src/pdumper.c (hash_table_thaw): Pacify -Wconversion so
+ we can use make_nil_vector again.
+ * src/timefns.c (syms_of_timefns): Prefer make_nil_vector
+ to make_vector with Qnil.
+
+2020-08-11 Eli Zaretskii <eliz@gnu.org>
+
+ Fix MinGW build broken by recent pdumper changes.
+
+ * src/pdumper.c (hash_table_thaw): Use Fmake_vector. Suggested by
+ Pip Cet <pipcet@gmail.com>.
+ (dump_trace): Declare ATTRIBUTE_FORMAT_PRINTF, not
+ ATTRIBUTE_FORMAT((__printf__), so that we pick the right attribute
+ for MinGW.
+
+2020-08-11 Bastian Beischer <bastian.beischer@rwth-aachen.de> (tiny change)
+
+ Make mouse-2 respect select-enable-primary etc
+
+ * lisp/calc/calc-yank.el (calc-yank-internal): Factor out into its
+ own function (bug#23629).
+ (calc-yank): Factored out from here.
+ (calc-yank-mouse-primary): New command to
+
+2020-08-11 Robert Weiner <rsw@gnu.org>
+
+ Allow count-lines to ignore invisible lines
+
+ * doc/lispref/positions.texi (Text Lines): Document it (bug#23675).
+
+ * lisp/simple.el (count-lines): Add an optional parameter to
+ ignore invisible lines (bug#23675).
+
+2020-08-11 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp.el: Make last change backward compatible.
+
+2020-08-11 Eli Zaretskii <eliz@gnu.org>
+
+ Fix face merging at EOL when inherited face specifies :extend
+
+ * src/xfaces.c (merge_face_ref): Handle correctly faces that
+ inherit from another, and in addition specify :extend.
+ (Bug#42552)
+
+2020-08-11 Robert Weiner <rsw@gnu.org>
+
+ Add new commands for environment movement in .texi files
+
+ * lisp/textmodes/texinfo.el (texinfo-mode-map): New keystrokes for
+ environment movement commands (bug#23985).
+
+2020-08-11 Puneeth Chaganti <punchagan@muse-amuse.in>
+
+ Allow specifying the callback in new xwidget sessions
+
+ * lisp/xwidget.el (xwidget-webkit-new-session): Optional callback
+ arg (bug#24019).
+ (xwidget-event-handler): Respect the 'callback parameter.
+
+2020-08-11 Noam Postavsky <npostavs@gmail.com>
+
+ Fix (end-of-defun N) for N >= 2
+
+ * lisp/emacs-lisp/lisp.el (end-of-defun): Only skip to next line when
+ after end of defun when ARG is 1 or less.
+ * test/lisp/emacs-lisp/lisp-tests.el (end-of-defun-twice): New
+ test (bug#24427).
+
+2020-08-11 Tino Calancha <tino.calancha@gmail.com>
+
+ Change the Calc text input method to insert at point
+
+ * lisp/calc/calc.el (calcDigit-delchar): New command to delete chars
+ forward in the calc minibuffer.
+ (calc-digit-map): Bind calcDigit-delchar to '\C-d'.
+ (calcDigit-key): Do not go to (point-max) in calc minibuffer
+ before insert a digit (Bug#24612).
+
+2020-08-11 Alexander Gramiak <agrambot@gmail.com>
+
+ Only search for a variable when instructed
+
+ * lisp/help-fns.el (find-lisp-object-file-name): Check for 'defvar
+ argument before searching for an internal variable (Bug#24697).
+ * test/lisp/help-fns-tests.el: New tests.
+
+2020-08-11 Kaushal Modi <kaushal.modi@gmail.com>
+
+ Allow Dired to dereference symbolic links when copying
+
+ * doc/emacs/dired.texi (Operating on Files): Mention the new
+ defcustom (bug#25075).
+ * lisp/dired-aux.el (dired-do-copy): Invert the value of
+ `dired-copy-dereference' in lexical scope when prefix argument is
+ '(4). Update function documentation for the new defcustom.
+
+ * lisp/dired-aux.el (dired-copy-file): Use `dired-copy-dereference' as
+ the `dereference' argument to `dired-copy-file-recursive'.
+
+ * lisp/dired-aux.el (dired-copy-file-recursive): Add new optional
+ argument `dereference'.
+
+ * lisp/dired.el (dired-copy-dereference): New defcustom, defaults to
+ nil.
+
+2020-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mark further mml-sec-tests as unstable
+
+ * test/lisp/gnus/mml-sec-tests.el (mml-secure-en-decrypt-sign-3):
+ (mml-secure-en-decrypt-sign-1-3-double): These tests are unstable
+ on Ubuntu (bug#42803).
+
+2020-08-11 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Further tweaks to the user manual about shell-command-buffer-name
+
+ * doc/emacs/misc.texi (Single Shell): Reintroduce the actual
+ buffer names in the user manual (bug#39138), but keep the
+ references to the variables. It's easier for people reading the
+ user manual to deal with actual names.
+
+2020-08-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ pdumper avoid listing hash table contents
+
+ * src/pdumper.c (hash_table_contents): Create a vector directly,
+ instead of creating a list and then converting that to a vector.
+
+2020-08-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ pdumper speed tweeks for hash tables
+
+ * src/pdumper.c (dump_queue_empty_p): Avoid unnecessary call
+ to Fhash_table_count on a known hash table.
+ (dump_hash_table_list): !NILP, not CONSP.
+ (hash_table_freeze, hash_table_thaw): ASIZE, not Flength, on vectors.
+ Initialize in same order as struct.
+ (hash_table_thaw): make_nil_vector, not Fmake_vector with nil.
+
+2020-08-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ In pdumper, simplify INT_MAX computation
+
+ * src/pdumper.c (dump_read_all): Avoid unnecessary cast.
+ Also, round down to page size, as sysdep.c does.
+ Also, don’t assume INT_MAX <= UINT_MAX (!).
+
+2020-08-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ Don’t needlessly convert to ‘unsigned’ in pdumper
+
+ * src/pdumper.c (PRIdDUMP_OFF): New macro.
+ (EMACS_INT_XDIGITS): New constant.
+ (struct dump_context): Use dump_off for relocation counts.
+ All uses changed.
+ (dump_queue_enqueue, dump_queue_dequeue, Fdump_emacs_portable):
+ Don’t assume counts fit in ‘unsigned’ or ‘unsigned long’.
+ Use EMACS_INT_XDIGITS instead of assuming it’s 16.
+
+2020-08-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/pdumper.c (pdumper_load): XSETVECTOR -> make_lisp_ptr.
+
+ * src/fns.c (hash_table_rehash): Help the compiler a bit.
+
+2020-08-11 Pip Cet <pipcet@gmail.com>
+
+ Rehash hash tables eagerly after loading a dump
+
+ This simplifies code, and helps performance in some cases (Bug#36597).
+ * src/lisp.h (hash_rehash_needed_p): Remove. All uses removed.
+ (hash_rehash_if_needed): Remove. All uses removed.
+ (struct Lisp_Hash_Table): Remove comment about rehashing hash tables.
+ * src/pdumper.c (thaw_hash_tables): New function.
+ (hash_table_thaw): New function.
+ (hash_table_freeze): New function.
+ (dump_hash_table): Simplify.
+ (dump_hash_table_list): New function.
+ (hash_table_contents): New function.
+ (Fdump_emacs_portable): Handle hash tables by eager rehashing.
+ (pdumper_load): Restore hash tables.
+ (init_pdumper_once): New function.
+
+2020-08-11 Stefan Kangas <stefankangas@gmail.com>
+
+ Fix \epsilon and \varepsilon in TeX input method
+
+ * lisp/leim/quail/latin-ltx.el: Add correct \epsilon and \varepsilon
+ characters to TeX input method. (Bug#26060)
+
+2020-08-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix fontification of outdated TeX form
+
+ * lisp/textmodes/tex-mode.el (tex-font-lock-keywords-2): End the
+ expression before the terminating $ in constructions like $\it
+ identifiername$
+ (bug#28277). This avoids italicising the final $ character.
+
+ This fixes the final $ of the final test case here:
+
+ $foo$
+ \textit{foo}
+ {\it foo}
+ $\mathit{identifiername}$
+ $\textit{identifiername}$
+ ${\it identifiername}$
+ $\it identifiername$
+
+2020-08-10 Stefan Kangas <stefankangas@gmail.com>
+
+ Add new command apropos-function (Bug#41021)
+
+ * lisp/apropos.el (apropos-function): New command.
+ * etc/NEWS: Announce it.
+
+2020-08-10 Charles A. Roelli <charles@aurox.ch>
+
+ Change 'M-:' to not error out on incomplete expressions
+
+ * lisp/simple.el (read--expression-try-read): New function to read
+ a Lisp expression from the minibuffer (bug#30697). This will not
+ (as before) signal an error on incomplete expressions, but allow
+ users to continue editing it.
+ (read--expression): Use it (and add a doc string).
+
+2020-08-10 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with /- incorrectly starting a comment in SQL mode
+
+ * lisp/progmodes/sql.el (sql-mode): Move all the syntax setup
+ stuff here (bug#35646). Add handling of -* and /- from Kristian
+ Hole <kristian@hole.priv.no>.
+
+2020-08-10 Stefan Kangas <stefankangas@gmail.com>
+
+ Add term/st.el (Bug#33182)
+
+ This is a copy of term/konsole.el with konsole -> st.
+ * lisp/term/st.el: New file.
+
+2020-08-10 Matthew Bauer <mjbauer95@gmail.com>
+
+ Add zsh extended_history handling for comint.el input ring
+
+ * lisp/comint.el (comint-input-ring-file-prefix): New variable
+ (bug#36034).
+ (comint-read-input-ring): Use it.
+
+ * lisp/shell.el (shell-mode): Set it.
+
+2020-08-10 Stefan Kangas <stefankangas@gmail.com>
+
+ * lisp/vt100-led.el: Use lexical-binding.
+
+2020-08-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Revert "Indent python multiline strings to start and previous levels"
+
+ This reverts commit b78583cde7d8aaa1fa19c20975c03d689c78baef.
+
+ The multi-line string indentation was incorrect after applying this patch.
+
+2020-08-09 Matthew White <mehw.is.me@inventati.org>
+
+ Add ability to mark/unmark/delete all bookmarks
+
+ Thanks to Karl Fogel for pre-commit review.
+
+ * lisp/bookmark.el (bookmark-delete-all): New function to delete all
+ bookmarks.
+ (bookmark-bmenu-mark-all): New function to mark all bookmarks in the
+ bookmark list buffer.
+ (bookmark-bmenu-unmark-all): New function to unmark all bookmarks in
+ the bookmark list buffer.
+ (bookmark-bmenu-delete-all): New function to mark for deletion all
+ bookmarks in the bookmark list buffer.
+ (bookmark-map): Map "D" to `bookmark-delete-all'.
+ (bookmark-bmenu-mode-map): New mapping for "M" to
+ `bookmark-bmenu-mark-all'.
+ (bookmark-bmenu-mode-map): New mapping for "U" to
+ `bookmark-bmenu-unmark-all'.
+ (bookmark-bmenu-mode-map): New mapping for "D" to
+ `bookmark-bmenu-delete-all'.
+ (bookmark-bmenu-mark-all): New bookmark menu to
+ `bookmark-delete-all'.
+ (easy-menu-define): New bookmark menu to `bookmark-bmenu-mark-all'.
+ (easy-menu-define): New bookmark menu to
+ `bookmark-bmenu-unmark-all'.
+ (easy-menu-define): New bookmark menu to
+ `bookmark-bmenu-delete-all'.
+ (bookmark-bmenu-select): Update docstring to include a reference to
+ `bookmark-bmenu-mark-all'.
+ (bookmark-bmenu-mode): Update docstring. Add/Update description:
+ `bookmark-bmenu-mark-all', `bookmark-bmenu-delete-all',
+ `bookmark-bmenu-execute-deletions', and `bookmark-bmenu-unmark-all'.
+ * test/lisp/bookmark-resources/test-list.bmk: New bookmark file to
+ test a list of bookmarks.
+ * test/lisp/bookmark-tests.el (bookmark-tests-bookmark-file-list): New
+ reference to the bookmark file used for testing a list of bookmarks.
+ (bookmark-tests-bookmark-list-0, bookmark-tests-bookmark-list-1,
+ bookmark-tests-bookmark-list-2): New cached values for testing a
+ list of bookmark.
+ (bookmark-tests-cache-timestamp-list): New variable to set
+ `bookmark-bookmarks-timestamp'.
+ (with-bookmark-test-list): New macro environment to test a list of
+ bookmarks.
+ (with-bookmark-test-file-list): New macro environment to test a list
+ of bookmarks with example.txt.
+ (with-bookmark-bmenu-test-list): New macro environment to test
+ functions about a list of bookmarks from `bookmark-bmenu-list'.
+ (bookmark-tests-all-names-list, bookmark-tests-get-bookmark-list,
+ bookmark-tests-get-bookmark-record-list): New functions to test the
+ records of the list of bookmarks.
+ (bookmark-tests-make-record-list): New function to test the creation
+ of a record from example.txt with a list of bookmarks loaded.
+ (bookmark-tests-delete-all): New function to test
+ `bookmark-delete-all'.
+ (bookmark-test-bmenu-any-marks-list): New function to test
+ `bookmark-bmenu-any-marks' with a list of bookmarks.
+ (bookmark-test-bmenu-mark-all): New function to test
+ `bookmark-bmenu-mark-all'.
+ (bookmark-test-bmenu-unmark-all): New function to test
+ `bookmark-bmenu-unmark-all'.
+ (bookmark-test-bmenu-delete-all): New function to test
+ `bookmark-bmenu-delete-all'.
+
+2020-08-09 Wolfgang Scherer <wolfgang.scherer@gmx.de>
+
+ Use one src status -a call for vc-src-dir-status-files
+
+ lisp/vc/vc-src.el: (vc-src--parse-state) new function.
+ (vc-src-state) use vc-src--parse-state.
+ (vc-src-dir-status-files) use recursive calls to `src status -a' (bug#39502).
+
+2020-08-09 Kristian Hole <kristian@hole.priv.no> (tiny change)
+
+ Adds backslash as escape character to mysql syntax-alist
+
+ * lisp/progmodes/sql.el (sql-product-alist): The \ character is an
+ escape character in mysql (bug#37459).
+ (sql-mode): Changes the example from the incorrect use of
+ punctuation rule, to the escape character rule.
+
+2020-08-09 Carlos Pita <carlosjosepita@gmail.com>
+
+ Indent python multiline strings to start and previous levels
+
+ * lisp/progmodes/python.el (python-indent--calculate-indentation):
+ Add an additional indentation point to match indentation of
+ previous line in a multiline string. Then Tab iterates between 0,
+ the start indentation level and the previous line level
+ (bug#37726).
+
+2020-08-09 Philipp Stephani <phst@google.com>
+
+ * src/json.c (lisp_to_json): Simplify.
+
+2020-08-09 Stefan Kangas <stefankangas@gmail.com>
+
+ Revert obsoletion of manual-entry
+
+ Ref: https://lists.gnu.org/archive/html/emacs-devel/2020-08/msg00167.html
+
+ * lisp/man.el (manual-entry): Revert obsoletion of this alias.
+
+2020-08-09 Eli Zaretskii <eliz@gnu.org>
+
+ Fix recently added documentation bits
+
+ * lisp/simple.el (async-shell-command-buffer)
+ (async-shell-command, shell-command, shell-command-on-region):
+ * lisp/dired-aux.el (dired-do-async-shell-command)
+ (dired-do-shell-command):
+ * doc/misc/tramp.texi (Remote processes):
+ * doc/emacs/misc.texi (Single Shell):
+ * etc/NEWS: Fix wording and punctuation of recently added
+ documentation.
+
+2020-08-09 Carlos Pita <carlosjosepita@gmail.com>
+
+ Improve client/daemon xdg/systemd experience
+
+ * Makefile.in: Add emacsclient.desktop generation.
+ * etc/emacsclient.desktop: Add file, use emacsd as StartupWMClass.
+ * etc/emacs.service: Run with name emacsd (bug#37847).
+
+2020-08-09 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/bytecomp.el: Guard against double native compilation.
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-08-09 Damien Cassou <damien@cassou.me>
+
+ Add the new library hierarchy.el
+
+ * lisp/emacs-lisp/hierarchy.el: New file.
+
+2020-08-09 Andrii Kolomoiets <andreyk.mad@gmail.com>
+
+ vc-hg: use 'hg summary' to populate vc-dir headers
+
+ * lisp/vc/vc-hg.el (vc-hg-dir-extra-headers): Use 'hg summary' command.
+ (vc-hg-dir-extra-header): Remove unused function.
+ * etc/NEWS: Mention changes to vc-hg.el (bug#38387).
+
+2020-08-09 Andrii Kolomoiets <andreyk.mad@gmail.com>
+
+ vc-hg-create-tag: Possibility to create a branch
+
+ * lisp/vc/vc-hg.el (vc-hg-create-bookmark): New user option.
+ (vc-hg-create-tag): Use it (bug#38425).
+
+2020-08-09 Tino Calancha <tino.calancha@gmail.com>
+
+ Add constants for shell command output buffer names
+
+ Buffers `*Shell Command Output*' and `*Async Shell Command*'
+ have been around since a long time; used across several libraries,
+ they are de facto output buffers for shell commands.
+
+ * lisp/simple.el (shell-command-buffer-name)
+ (shell-command-buffer-name-async): New variables.
+ * lisp/dired-aux.el
+ * lisp/gnus/gnus-sum.el
+ * lisp/gnus/gnus-win.el
+ * lisp/ibuf-ext.el
+ * lisp/net/tramp.el: Use them.
+
+ * etc/NEWS (Changes in Emacs 28.1): Announce this change.
+
+ * doc/emacs/misc.texi (Single Shell)
+ * doc/misc/tramp.texi (Remote processes):
+ Update manual (bug#39138).
+
+2020-08-09 Jorge P. de Morais Neto <jorge+list@disroot.org> (tiny change)
+
+ TUTORIAL: "buffer" vs "file" consistency; capitalize Dired
+
+ * etc/tutorials/TUTORIAL: For consistency with C-x s ("save some
+ buffers") and for accuracy, describe C-x C-s as "Save buffer to
+ file"), and then C-x s as "Save some buffers to their files"
+ (bug#39359). Also capitalize "Dired".
+
+2020-08-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make solar commands in Calendar less beepy
+
+ * lisp/calendar/solar.el (solar-setup): Remove a (beep) that's
+ been in this code since 1992 (bug#42774).
+
+2020-08-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a command line (and MIME handler) function to start eww
+
+ * lisp/net/eww.el (eww-browse): New command (bug#42768) to be used
+ from the command line.
+
+ * doc/misc/eww.texi (Command Line): Document it.
+
+2020-08-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Doc string fix for message-mailto
+
+ * lisp/gnus/message.el (message-mailto): Doc string fix.
+
+2020-08-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Slight code clean-up in message-mailto
+
+ * lisp/gnus/message.el (message-mailto): Clean up code slightly.
+
+2020-08-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a variable to allow displaying numeric time zones
+
+ * lisp/calendar/calendar.el (calendar-use-numeric-time-zones): New
+ variable.
+
+ * doc/emacs/calendar.texi (Sunrise/Sunset): Document it (bug#33149).
+
+ * lisp/calendar/cal-dst.el (calendar-standard-time-zone-name): Use it.
+ (calendar-daylight-time-zone-name): Ditto.
+
+ * lisp/calendar/solar.el (sunrise-sunset): Adjust usage.
+ (solar-equinoxes-solstices): Ditto.
+
+2020-08-09 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove superfluous code from the previous '' sql string fix
+
+ * lisp/progmodes/sql.el (sql-mode): Remove setting that's now
+ superfluous from previous check-in.
+
+2020-08-09 Juri Linkov <juri@linkov.net>
+
+ * lisp/custom.el (custom-add-choice): Fix previous commit.
+
+2020-08-08 Glenn Morris <rgm@gnu.org>
+
+ * lisp/outline.el (outline-minor-mode-prefix): Fix compilation.
+
+2020-08-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document the OpenPGP header
+
+ * doc/misc/message.texi (Using the OpenPGP Header): Document the
+ OpenPGP header (bug#39964).
+
+2020-08-08 Philip K <philip.kaludercic@fau.de>
+
+ Add support for the OpenPGP header to Emacs
+
+ * lisp/gnus/message.el (message-openpgp-header): New variable
+ (bug#39964).
+ (messasge-add-openpgp-header): New function to use it.
+
+2020-08-08 Florian v. Savigny <f.savigny@mailbox.org>
+
+ Handle '' in strings in SQL Mode
+
+ * lisp/progmodes/sql.el
+ (sql--syntax-propertize-escaped-apostrophe): Handle '' in strings
+ (bug#40231).
+ (sql-mode): Use it.
+
+2020-08-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Modernise a code example in os.texi
+
+ * doc/lispref/os.texi (Session Management): Use
+ with-current-buffer in the example instead of save+switch (bug#40341).
+
+2020-08-08 Bruno Félix Rezende Ribeiro <oitofelix@gnu.org> (tiny change)
+
+ * doc/lispref/os.texi (Session Management): Make example homoiconic
+
+ * doc/lispref/os.texi (Session Management): Don't insert Lisp as
+ strings, but use format (bug#40341).
+
+2020-08-08 Fabrice Niessen <fniessen@pirilampo.org>
+
+ Update Leuven-theme
+
+ * etc/themes/leuven-theme.el (class): Update theme (bug#40759).
+
+2020-08-08 Philip K <philip@warpmail.net>
+
+ Use write-region when saving recentf file
+
+ * lisp/recentf.el (recentf-save-list): Don't generate backups for
+ recentf files (bug#41060).
+
+2020-08-08 Philip K <philip@warpmail.net>
+
+ outline-minor-mode-prefix is a key sequence, not a string
+
+ * lisp/outline.el (outline-minor-mode-prefix): Fix the type (bug#41072).
+
+2020-08-08 Philip K <philip@warpmail.net>
+
+ Make Customize changes to outline-minor-mode-prefix happen immediately
+
+ * lisp/outline.el (outline-minor-mode-prefix): Update the key map
+ after changing the value in Customize (bug#41073).
+
+2020-08-08 Matthias Meulien <orontee@gmail.com>
+
+ lisp/bookmark.el: Customize choice to show bookmark list in a new tab
+
+ * lisp/bookmark.el (bookmark-bmenu-get-buffer): Add as a choice
+ for new-tab targets (bug#41225).
+
+2020-08-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new utility function custom-add-choice
+
+ * lisp/custom.el (custom-add-choice): New function (bug#41225).
+
+2020-08-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix up previous list-buffers patch to work when there's no buffer
+
+ * lisp/buff-menu.el (Buffer-menu--dynamic-name-width): Use apply
+ #'max instead of seq-max since the list may be empty.
+
+2020-08-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mark an mml-sec test as unstable
+
+ * test/lisp/gnus/mml-sec-tests.el
+ (mml-secure-en-decrypt-sign-1-1-single): Mark the test as unstable
+ (bug#42720). It sometimes fails on some systems (Fedora?) when
+ run with "-j5", so there may be a race condition in the code somewhere.
+
+2020-08-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak how whitespace-mode marks the end of the buffer
+
+ * lisp/whitespace.el (whitespace-missing-newline-at-eof): Change
+ the colours to not be as angry.
+ (whitespace-color-on): Don't mark the end of the buffer if point
+ is there.
+
+2020-08-08 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the name column in 'list-buffers' have a dynamic width
+
+ * lisp/buff-menu.el (Buffer-menu--dynamic-name-width): New
+ function (bug#30692).
+ (Buffer-menu-name-width): Default to using it.
+ (list-buffers--refresh): Call it.
+
+ * lisp/emacs-lisp/seq.el (seq-max): Add autoload cookie.
+
+2020-08-08 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in saveplace.el and add tests
+
+ * lisp/saveplace.el: Use lexical-binding.
+ (save-place-to-alist): Doc fix.
+ * test/lisp/saveplace-tests.el:
+ * test/lisp/saveplace-resources/saveplace: New files.
+
+2020-08-07 Stefan Kangas <stefankangas@gmail.com>
+
+ * lisp/scroll-lock.el: Use lexical-binding.
+
+2020-08-07 Simen Heggestøyl <simenheg@gmail.com>
+
+ Use lexical-binding in browse-url.el and add tests
+
+ * lisp/net/browse-url.el: Turn on lexical-binding.
+ (browse-url--mailto, browse-url--man, browse-url--browser): Use
+ imperative form in docstrings.
+ (browse-url-delete-temp-file): Turn comment into a proper docstring.
+
+ * test/lisp/net/browse-url-tests.el: New file with tests for
+ browse-url.el.
+
+2020-08-07 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove support for Mosaic from browse-url
+
+ * lisp/net/browse-url.el (browse-url-mosaic-program)
+ (browse-url-mosaic-arguments, browse-url-mosaic-pidfile)
+ (browse-url-CCI-port, browse-url-CCI-host)
+ (browse-url-default-browser, browse-url-mosaic, browse-url-cci):
+ Remove support for the Mosaic browser, which saw its last release in
+ 1997, or 23 years ago.
+
+ * etc/NEWS: Announce its removal.
+
+2020-08-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix fontification of %d in strings in cperl-mode
+
+ * lisp/progmodes/cperl-mode.el (cperl-init-faces): Don't fontify
+ directives like %d in strings as hashes (bug#22867).
+
+2020-08-07 Stefan Kangas <stefankangas@gmail.com>
+
+ Make more erc function aliases obsolete
+
+ * lisp/erc/erc-compat.el (erc-propertize, erc-view-mode-enter)
+ (erc-function-arglist, erc-delete-dups)
+ (erc-replace-regexp-in-string): Make these aliases obsolete.
+
+ * lisp/erc/erc-capab.el (erc-capab-identify-add-prefix)
+ (erc-capab-identify-remove/set-identified-flag):
+ * lisp/erc/erc-dcc.el (erc-dcc-chat-parse-output)
+ (erc-dcc-unquote-filename, pcomplete/erc-mode/DCC):
+ * lisp/erc/erc-list.el (erc-list-menu-mode, erc-list-button)
+ (erc-list-make-string):
+ * lisp/erc/erc-log.el (erc-log-standardize-name):
+ * lisp/erc/erc-match.el (erc-log-matches-make-buffer):
+ * lisp/erc/erc-networks.el (erc-server-select):
+ * lisp/erc/erc.el (erc-message-english-PART)
+ (erc-update-mode-line-buffer, erc-format-my-nick)
+ (erc-format-@nick, erc-get-user-mode-prefix, erc-display-prompt)
+ (erc-part-reason-zippy, erc-quit-reason-zippy, erc-get-arglist)
+ (erc-toggle-debug-irc-protocol, erc-log-irc-protocol)
+ (erc-migrate-modules): Adjust callers.
+
+2020-08-07 Stephen Leake <stephen_leake@stephe-leake.org>
+
+ * lisp/files.el (auto-mode-alist): delete ada-mode; now in GNU ELPA only
+
+2020-08-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add some documentation for widget-describe and button-describe
+
+ * doc/emacs/help.texi (Key Help): Document button-describe and
+ widget-describe.
+
+ * lisp/button.el (push-button): Mention button-describe.
+
+ * lisp/cus-edit.el (Custom-newline): Mention widget-describe (bug#139).
+
+2020-08-07 Mauro Aranda <maurooaranda@gmail.com>
+
+ Add new commands to describe buttons and widgets
+
+ * lisp/help-fns.el (describe-widget-functions): New variable, used by
+ describe-widget.
+ (describe-widget): New command, to display information about a widget.
+ * lisp/button.el (button-describe): New command, for describing a button.
+ (button--describe): Helper function for button-describe.
+ * lisp/wid-edit.el (widget-describe): New command, for describing a
+ widget.
+ (widget--resolve-parent-action): Helper function, to allow
+ widget-describe to display more useful information (bug#139).
+
+2020-08-07 Eli Zaretskii <eliz@gnu.org>
+
+ Fix documentation of 'missing-newline-at-eof'
+
+ * doc/emacs/display.texi (Useless Whitespace):
+ * etc/NEWS (missing-newline-at-eof): Improve wording and
+ punctuation.
+
+2020-08-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Buffer-menu-select doc string clarification
+
+ * lisp/buff-menu.el (Buffer-menu-select): Document that it removed
+ the marks (bug#6491).
+
+2020-08-07 Peder O. Klingenberg <peder@klingenberg.no>
+
+ * lisp/play/snake.el (snake-null-map): Quit on `q'. (Bug#42731)
+
+2020-08-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new command to copy a file from zip files
+
+ * lisp/arc-mode.el (archive-copy-file): New command, keystroke and
+ menu bar entry (bug#26192).
+ (archive-extract): Refactored out code from here...
+ (archive--extract-file): ... to here for use in archive-copy-file.
+
+2020-08-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow ffap to do the right thing with 'https://gnu.org'
+
+ * lisp/thingatpt.el (thing-at-point-bounds-of-url-at-point): Don't
+ include trailing ' in the URL, because it's more likely to be a
+ punctuation character (bug#29410).
+
+2020-08-07 Mattias Engdegård <mattiase@acm.org>
+
+ Clean up and improve compilation of arithmetic (bug#42597)
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-associative-math)
+ (byte-optimize-min-max): Transform 3-arg min/max call into two 2-arg
+ calls, which is faster.
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-associative): Rename to...
+ (byte-compile-variadic-numeric): ...this function and simplify,
+ fixing incorrect comments. The 3-arg strength reduction is now
+ always done in the optimisers and is no longer needed here.
+ (byte-compile-min-max): New function.
+ (byte-compile-minus): Simplify, remove incorrect comment, and use
+ byte-compile-variadic-numeric.
+ (byte-compile-quo): Simplify and fix comment.
+
+2020-08-07 Mattias Engdegård <mattiase@acm.org>
+
+ Fix byte-compilation of (+ -0.0) (bug#42597)
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-associative):
+ Translate numerical identity expressions, such as (+ x) and (* x),
+ into (* x 1) since the previous translation (+ x 0) gets it wrong
+ for x = -0.0.
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (byte-opt-testsuite-arith-data): Add test cases.
+
+2020-08-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add missing "this is documented" marker to previous checkin
+
+2020-08-07 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make whitespace-mode highlight missing newlines at the end of buffers
+
+ * lisp/whitespace.el (whitespace-missing-newline-at-eof): New face
+ (bug#34952).
+ (whitespace-report-region): Add a test for
+ end-of-buffer-without-newline.
+ (whitespace-color-on): Ditto.
+
+ * doc/emacs/display.texi (Useless Whitespace): Document it.
+
+2020-08-07 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify gcc -Wunused-variable
+
+ * src/frame.c (Fset_mouse_position, Fset_mouse_pixel_position)
+ (Fset_frame_position): Always use xval, yval. Simplify #if nesting.
+
+2020-08-07 Juri Linkov <juri@linkov.net>
+
+ * lisp/hi-lock.el (hi-lock-set-pattern): Display warning on narrow (bug#42609)
+
+2020-08-07 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/skeleton.el: Use lexical-binding
+
+ (skeleton-proxy-new): Use `use-region`.
+
+2020-08-07 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-08-06 libgmp: add <gmp/gmp.h> support
+ 2020-08-06 Consider that clang defines __OPTIMIZE__ like GCC does
+ 2020-08-06 Use __builtin_expect with clang everywhere
+ 2020-08-05 Use __builtin_clz{,l,ll} with clang, also on Windows
+ 2020-08-05 Use __builtin_ctz{,l,ll} and __builtin_ffs{,l,ll} with clang
+ 2020-07-31 _GL_CMP: Improve documentation
+ 2020-07-30 alloca, largefile: sync with Autoconf master
+ * lib/c++defs.h, lib/cdefs.h, lib/count-leading-zeros.h:
+ * lib/count-trailing-zeros.h, m4/alloca.m4, m4/gnulib-common.m4:
+ * m4/largefile.m4, m4/libgmp.m4:
+ Copy from Gnulib.
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+
+2020-08-06 Tassilo Horn <tsdh@gnu.org>
+
+ Show A C hint only if partial fetches are enabled.
+
+ * lisp/gnus/gnus-art.el (gnus-insert-mime-button): Show A C hint for
+ downloading the complete message only if partial fetches are enabled.
+
+2020-08-06 Tassilo Horn <tsdh@gnu.org>
+
+ Show A C hint for loading complete message only in nnimap groups.
+
+ * lisp/gnus/gnus-art.el (gnus-insert-mime-button): Show A C hint for
+ loading complete message only in nnimap groups.
+
+2020-08-06 Kévin Le Gouguec <kevin.legouguec@gmail.com>
+
+ Fix the mailto: examples in the manual and in NEWS
+
+ * doc/misc/message.texi (System Mailer Setup): Fix mailto: examples.
+
+2020-08-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix broken desktop file
+
+ Looks like I pasted in the data twice...
+
+2020-08-06 Philip K <philipk@posteo.net>
+
+ Remove usages of assoc-delete-all in project.el
+
+ assoc-delete-all is not available for users who have installed
+ project.el via ELPA on older Emacs versions (bug#42668).
+
+ * lisp/progmodes/project.el
+ (project-remember-project, project--remove-from-project-list):
+ Replace assoc-delete-all with equivalent alternatives.
+
+2020-08-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweat how MML specifies the encoding of binary data
+
+ * lisp/gnus/mml.el (mml-parse-1): Use `data-encoding' to be
+ slightly less confusing than `content-transfer-encoding'.
+
+ * doc/misc/emacs-mime.texi (MML Definition): Document it.
+
+ * lisp/gnus/message.el (message-insert-screenshot): Adjust usage.
+
+2020-08-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Change how Mail-Copies-To: never is handled in Message
+
+ * lisp/gnus/message.el (message-get-reply-headers): Change how
+ Mail-Copies-To: never is handled (bug#37591). When that header is
+ present, put all the remaining recipients in the To header,
+ instead of picking an arbitrary recipient to have in the To
+ header, and the rest in the Cc header.
+
+2020-08-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add a new HTML skeleton for relative (file) URLs
+
+ * lisp/textmodes/sgml-mode.el (html-href-anchor-file): New
+ skeleton and keystroke (bug#37644).
+
+2020-08-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make it possible to use Message as a mailto: desktop handler
+
+ * doc/misc/message.texi (System Mailer Setup): Document the usage.
+
+ * lisp/gnus/gnus-art.el (gnus-url-mailto): Move most of the code
+ here to 'message-mailto-1' (bug#38314).
+
+ * lisp/gnus/message.el (message-parse-mailto-url): Mark as obsolete.
+ (message-parse-mailto-url): Rewritten slightly from the above.
+ (message-mailto): New command.
+ (message-mailto-1): New function.
+
+2020-08-06 Nick Helm <nick@tenpoint.co.nz>
+
+ Signal an error in dired when moving to a directory that doesn't exist
+
+ * lisp/dired-aux.el (dired-do-create-files): Give an error when
+ apparently moving to a directory name, and that directory doesn't
+ exist (bug#38707).
+
+2020-08-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make 'n'/'p' in image mode buffers respect dired sorting
+
+ The commands now also now work on archive and tar mode parent buffers.
+
+ * doc/emacs/files.texi (Image Mode): Document it.
+
+ * lisp/arc-mode.el (archive-goto-file): New function (bug#38647).
+ (archive-next-file-displayer): Ditto.
+
+ * lisp/image-mode.el (image-next-file): Reimplement to work on
+ displayed dired buffers and the like. This means that `n' and `p'
+ now works on the displayed ordering in the dired buffer, so if
+ you've reversed the sorting, `n' picks the right "next" file.
+ (image-mode--directory-buffers): New function.
+ (image-mode--next-file): Ditto.
+
+ * lisp/tar-mode.el (tar-goto-file): New function.
+ (tar-next-file-displayer): Ditto.
+
+2020-08-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mark two cconv tests as :unstable
+
+ * test/lisp/emacs-lisp/cconv-tests.el
+ (cconv-tests-cl-iter-defun-:documentation): Mark as unstable
+ (bug#42723).
+ (cconv-tests-iter-defun-:documentation): Ditto.
+
+2020-08-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak the autoloads scrape output slightly
+
+ * lisp/emacs-lisp/autoload.el (batch-update-autoloads--summary):
+ Output " ..." at the end of the non-concluding lines to signify
+ that the output continues.
+
+2020-08-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the loaddefs scraping compilation output look more regular
+
+ * lisp/Makefile.in ($(lisp)/loaddefs.el): Don't output the
+ directories here.
+
+ * lisp/emacs-lisp/autoload.el (batch-update-autoloads--summary):
+ New function.
+ (batch-update-autoloads): Use it to output the directories we're
+ scraping.
+
+ This changes the compilation output from:
+
+ Directories for loaddefs: . ./calc ./calendar ./cedet ./cedet/ede
+ ./cedet/semantic ./cedet/semantic/analyze ./cedet/semantic/bovine
+ ./cedet/semantic/decorate ./cedet/semantic/symref ./cedet/semantic/wisent
+ ./cedet/srecode ./emacs-lisp ./emulation ./erc ./eshell ./gnus ./image
+ ./international ./language ./leim ./leim/ja-dic ./leim/quail ./mail ./mh-e
+ ./net ./nxml ./org ./play ./progmodes ./textmodes ./url ./vc
+
+ (but all on one long line)
+
+ To:
+
+ SCRAPE . ./calc ./calendar ./cedet ./cedet/ede ./cedet/semantic
+ SCRAPE ./cedet/semantic/analyze ./cedet/semantic/bovine
+ SCRAPE ./cedet/semantic/decorate ./cedet/semantic/symref
+ SCRAPE ./cedet/semantic/wisent ./cedet/srecode ./emacs-lisp ./emulation
+ SCRAPE ./erc ./eshell ./gnus ./image ./international ./language ./leim
+ SCRAPE ./leim/ja-dic ./leim/quail ./mail ./mh-e ./net ./nxml ./org ./play
+ SCRAPE ./progmodes ./textmodes ./url ./vc
+
+ Compilation output with very long lines can be mistaken for errors
+ when they scroll by fast in the compilation output. Making it look
+ more like normal informational output avoids this confusion.
+
+2020-08-06 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make 'byte-compile-info*' functions more logical
+
+ * lisp/emacs-lisp/byte-run.el (byte-compile-info): New function
+ that's more flexible that replaces 'byte-compile-info-string' and
+ 'byte-compile-info-message'.
+ (byte-compile-info-string): Make obsolete.
+ (byte-compile-info-message): Ditto.
+
+ * lisp/international/ja-dic-cnv.el (skkdic-convert-okuri-ari)
+ (skkdic-convert-postfix, skkdic-convert-prefix)
+ (skkdic-collect-okuri-nasi, skkdic-set-okuri-nasi):
+ * lisp/finder.el (finder-compile-keywords):
+ * lisp/cus-dep.el (custom-make-dependencies): Adjust callers to
+ use the new function.
+
+2020-08-06 Paul Eggert <eggert@cs.ucla.edu>
+
+ Simplify Solaris port
+
+ This should avoid some configuration confusion as exemplified
+ by Jeffrey Walton’s recent bug report (Bug#42675).
+ * configure.ac (opsys): Simplify Solaris configuration by
+ not worrying about Solaris 9 and earlier, as they are no
+ longer supported by the Solaris developers. This should
+ support Walton’s ‘./configure --build=x86_64-sun-solaris’.
+ Instead of bothering with ‘opsys=sol2-6’ and ‘opsys=sol2-10’,
+ just use ‘opsys=solaris’. All uses changed.
+ (emacs_check_sunpro_c): Remove unused var.
+ * doc/misc/tramp.texi (Remote programs):
+ * etc/MACHINES, etc/PROBLEMS:
+ Modernize PATH for Oracle Developer Studio.
+ * etc/PROBLEMS: Move Solaris-related problems to legacy area,
+ except those that are still relevant.
+
+2020-08-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Skip epg tests if gpg isn't installed
+
+ Split sometimes-failing test into three tests to ease debugging
+
+2020-08-05 Christophe Troestler <Christophe.Troestler@umons.ac.be> (tiny change)
+
+ Enable replying to an ical event even when not an attendee
+
+ * lisp/gnus/gnus-icalendar.el
+ (gnus-icalendar-event--build-reply-event-body): Display a warning
+ instead of barfing when user is missing from attendee list.
+
+ When the user identity is not present in the attendee list, an error
+ is triggered making replying to such an event impossible (the reply
+ message not being even composed). This replaces it with a warning.
+ This is necessary because one may receive events that the organizer
+ did not set up well and it is up to the user to decide whether or not
+ to reply to them (bug#41723).
+
+2020-08-05 Harald Jörg <haj@posteo.de>
+
+ cperl-mode.el: Correctly terminate HERE-docs
+
+ * lisp/progmodes/cperl-mode.el (cperl-find-pods-heres): cperl-mode
+ in the master branch wrongly uses the first occurrence of "HERE"
+ to terminate the string, resulting in badly fontified / indented
+ code which follows (bug#42251).
+
+2020-08-05 Philip K <philip@warpmail.net>
+
+ Wrap skeleton logic in atomic-change-group
+
+ * lisp/skeleton.el (define-skeleton): Use an atomic change group
+ so that if the user `C-g's in the middle of it, we're not left
+ with half a skeleton in the buffer (bug#42311).
+
+2020-08-05 Harald Jörg <haj@posteo.de> (tiny change)
+
+ cperl-mode: Fix bad parameter construction in cperl-etags
+
+ * lisp/progmodes/cperl-mode.el (cperl-etags): This fails with
+ (wrong-type-argument stringp cperl-sub-regexp). The error came
+ with incorporating Jonathan Rockway's work (bug#42355).
+
+2020-08-05 Harald Jörg <haj@posteo.de>
+
+ cperl-mode: Workaround for failure of cperl-write-tags
+
+ * lisp/progmodes/cperl-mode.el (cperl-mode): Accommodate recent
+ changes in etags (bug#42356).
+
+2020-08-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix max-width/height for Message screenshots
+
+ * lisp/gnus/message.el (message-insert-screenshot):
+ :max-width/height apparently has to be integers.
+
+2020-08-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ mouse-drag-copy-region doc string clarification
+
+ * lisp/mouse.el (mouse-drag-copy-region): Clarify that the
+ variable only applies to selections in Emacs (bug#41856).
+
+2020-08-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention C-y in the manual for yanking the primary selection
+
+ * doc/emacs/killing.texi (Primary Selection): Mention C-y here for
+ yanking the primary selection (bug#41857).
+
+2020-08-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak the Message screenshot insertion
+
+ * lisp/gnus/message.el (message-insert-screenshot): Force scaling
+ to 1, since the screenshot image will already be suitable for
+ displaying directly (it's the same resolution).
+
+2020-08-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Implement a screenshot command for Message mode
+
+ * doc/misc/message.texi (MIME): Document it.
+
+ * lisp/gnus/message.el (message-screenshot-command): New variable.
+ (message-mode-map): New keystroke and menu item. Also add
+ mml-attach-file to the menu.
+ (message-insert-screenshot): New command.
+
+ * lisp/gnus/mml.el (mml-parse-1): Allow having
+ content-transfer-encoding already in the part, so that we can have
+ inline base64-encoded binaries in the Message buffers.
+
+2020-08-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fontize $(...) slightly better in bash mode
+
+ * lisp/progmodes/sh-script.el (sh-font-lock-keywords-var): Fontize
+ $(...) slightly better (bug#42417). Instead of just fontizing the
+ first word in the expression, fontize until the closing
+ parenthesis. This doesn't work well if you have nested $(...)
+ expressions.
+
+2020-08-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention undo in the doc string of dired-do-kill-lines
+
+ * lisp/dired-aux.el (dired-do-kill-lines): Mention that this can
+ be undone (bug#42707).
+
+2020-08-05 Kevin Brubeck Unhammer <unhammer@fsfe.org>
+
+ Further fix for erc-generate-new-buffer-name
+
+ * lisp/erc/erc.el (erc-generate-new-buffer-name): Fix buffer name
+ generation when there's two networks on the same
+ server:port (bug#40121).
+
+2020-08-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the erc /ignore command prompt for a timeout
+
+ * lisp/erc/erc.el (erc--unignore-user): Separate into own function
+ (bug#40137).
+ (erc-cmd-IGNORE): Ask if the user wants a timeout.
+ (erc--read-time-period): New function.
+
+2020-08-05 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new function decoded-time-period
+
+ * lisp/calendar/time-date.el (decoded-time-period): New function.
+
+2020-08-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/x-dnd.el: Use lexical-scoping
+
+2020-08-05 Juri Linkov <juri@linkov.net>
+
+ * lisp/generic-x.el (ansible-inventory-generic-mode): Fix filename (bug#42703)
+
+2020-08-04 Alan Third <alan@idiocy.org>
+
+ Don't smooth images when scaling up (bug#38394)
+
+ * src/image.c (image_set_transform [HAVE_XRENDER]): Use different filter
+ when scaling up vs scaling down.
+ * src/nsimage.m (ns_image_set_smoothing):
+ ([EmacsImage setSmoothing:]): New functions.
+ * src/nsterm.h: Add definitions.
+ * src/nsterm.m (ns_dumpglyphs_image): Disable smoothing if requested.
+
+2020-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ When decrypting non-decrypted files, make epa show the raw files
+
+ * lisp/epa-file.el (epa-file-insert-file-contents): When trying to
+ decrypt a non-decrypted file, just show the bytes from the file
+ instead (bug#3829).
+
+2020-08-04 Nicolas Petton <nicolas@petton.fr>
+
+ * etc/HISTORY: Update the Emacs 27.1 release date.
+
+2020-08-04 Arik Mitschang <arik.mitschang@gmail.com> (tiny change)
+
+ Add options for mode modern ciphers in smime-encrypt-cipher
+
+ * lisp/gnus/smime.el (smime-encrypt-cipher): Add support for more
+ modern ciphers (bug#8474).
+
+2020-08-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Drop support for -fcheck-pointer-bounds
+
+ GCC has removed the -fcheck-pointer bounds option, and the Linux
+ kernel has also removed support for Intel MPX, so there’s no point
+ to keeping this debugging option within Emacs.
+ * src/bytecode.c (BYTE_CODE_THREADED):
+ * src/lisp.h (DEFINE_LISP_SYMBOL, XSYMBOL, make_lisp_symbol):
+ Assume __CHKP__ is not defined.
+ * src/ptr-bounds.h: Remove. All uses of ptr_bounds_clip,
+ ptr_bounds_copy, ptr_bounds_init, ptr_bounds_set removed.
+
+2020-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Ignore test/data/mml-sec/random_seed
+
+ The file is generated when mml-sec-tests is run.
+
+2020-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Remove mistakenly checked-in random_seed file
+
+2020-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Tweak mml-sec test that sometimes fails
+
+ * test/lisp/gnus/mml-sec-tests.el
+ (mml-first-secure-en-decrypt-sign-1): mml-secure-en-decrypt-sign-1
+ fail sometimes, on some machines, unless it's the first test. I'm
+ guessing there's a race condition somewhere in the test, but put
+ it first now to avoid build reports.
+
+2020-08-04 Jens Lechtenbörger <jens.lechtenboerger@fsfe.org>
+
+ Add tests for mml-sec.el
+
+2020-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix two mml-sec minor bugs revealed by new test harness
+
+ * lisp/gnus/mml-sec.el
+ (mml-secure-allow-signing-with-unknown-recipient): New variable
+ (bug#18393) (but this should probably be fixed in a different way).
+ (mml-secure-epg-sign): Use it.
+ (mml-secure-check-user-id): Protect against recipients that aren't
+ email addresses, like "No recipient".
+
+2020-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add test file lost when merged from Gnus in 2016
+
+2020-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mark unused Gnus util function as obsolete
+
+ * lisp/gnus/gnus-util.el (gnus-test-list): Mark utility function
+ as obsolete -- there are no in-tree usage.
+
+2020-08-04 Stefan Kangas <stefankangas@gmail.com>
+
+ Add new cconv-tests (Bug#28557)
+
+ These tests are all written by Gemini Lasswell <gazally@runbox.com>.
+
+ * test/lisp/emacs-lisp/cconv-tests.el
+ (top-level): Add two commented out tests which the byte-compiler
+ can't handle.
+ (cconv-tests-lambda-:documentation)
+ (cconv-tests-pcase-lambda-:documentation)
+ (cconv-tests-defun-:documentation)
+ (cconv-tests-cl-defun-:documentation)
+ (cconv-tests-function-:documentation)
+ (cconv-tests-cl-defgeneric-literal-:documentation)
+ (cconv-tests-defsubst-:documentation)
+ (cconv-tests-cl-defsubst-:documentation): New tests.
+ (cconv-tests-cl-iter-defun-:documentation)
+ (cconv-tests-iter-defun-:documentation)
+ (cconv-tests-iter-lambda-:documentation)
+ (cconv-tests-cl-function-:documentation)
+ (cconv-tests-cl-defgeneric-:documentation): New failing tests.
+
+2020-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix viewing encrypted+signed messages from Outlook
+
+ * lisp/gnus/mm-decode.el (mm-possibly-verify-or-decrypt): Fix
+ problem with CRLF-encoded encrypted+signed parts (bug#42637).
+
+2020-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix previous network stream test
+
+ * test/lisp/net/network-stream-tests.el
+ (network-test--resolve-system-name): There's only one ipv6
+ localhost address.
+
+2020-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make a network-stream test more robust
+
+ * test/lisp/net/network-stream-tests.el
+ (network-test--resolve-system-name): New function.
+ (echo-server-with-dns): Skip test if (system-name) doesn't look
+ like it's going to resolve (bug#42535).
+
+2020-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mark the end of file names correctly on Macos in wdired
+
+ * lisp/wdired.el (wdired--restore-dired-filename-prop): Fix
+ problem with finding the end of the name on Macos.
+
+2020-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix debugging code checked in from wdired-tests
+
+2020-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix svn tests on Macos
+
+ * test/lisp/vc/vc-tests.el (vc-test--svn-enabled): Macos machines
+ may have a dummy svn program that helpfully just outputs "There's
+ no svn program here", so also test for the svnadmin program
+ (bug#42536).
+
+2020-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ dired-ls-F-marks-symlinks should be set under Macos
+
+ * lisp/dired.el (dired-ls-F-marks-symlinks): Not that this should
+ be set under Macos (bug#42537).
+
+2020-08-04 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix wdired test for Macos
+
+ * test/lisp/wdired-tests.el (wdired-test-bug34915): Macos adds "@"
+ to the end of symlinks (bug#42537).
+
+2020-08-04 Michael Albinus <michael.albinus@gmx.de>
+
+ * etc/NEWS: Add Tramp support of direct asynchronous process invocation.
+
+2020-08-04 Michael Albinus <michael.albinus@gmx.de>
+
+ Add Tramp support of direct asynchronous process invocation
+
+ * doc/misc/tramp.texi (Predefined connection information):
+ Add "direct-async-process".
+ (Remote processes): New subsection "Improving performance of
+ asynchronous remote processes".
+
+ * lisp/net/tramp-adb.el (tramp-methods) <adb>: Add `tramp-login-program'
+ and `tramp-login-args'.
+ (tramp-adb-handle-make-process): Use `tramp-handle-make-process'.
+ (tramp-adb-maybe-open-connection): Add "set +o vi +o emacs" command.
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process):
+ Use `tramp-handle-make-process'.
+ (tramp-sh-file-name-handler-p, tramp-multi-hop-p): New defuns.
+ (tramp-compute-multi-hops): Use `tramp-multi-hop-p'.
+
+ * lisp/net/tramp.el (tramp-dissect-file-name, tramp-dissect-hop-name):
+ Use `tramp-multi-hop-p'.
+ (tramp-handle-insert-file-contents, tramp-local-host-p):
+ Use `tramp-sh-file-name-handler-p'.
+ (tramp-handle-make-process): New defun.
+
+ * test/README: Add another example how to use SELECTOR.
+
+ * test/lisp/net/tramp-tests.el (tramp-test03-file-name-method-rules):
+ Adapt test.
+ (tramp--test-sh-p): Use `tramp-sh-file-name-handler-p'.
+
+2020-08-04 Theodor Thornhill <theo@thornhill.no>
+
+ Add sass @use rule to css-mode
+
+ * lisp/textmodes/css-mode.el (scss-at-ids): Add 'use' to scss-at-ids
+ for autocompletion (bug#42700).
+
+2020-08-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Use void * for pointers in with_echo_area_buffer
+
+ * src/xdisp.c (with_echo_area_buffer): Pass void * instead of
+ ptrdiff_t, since the values are typically pointers and this ports
+ better to (mostly-theoretical) hosts where ptrdiff_t is narrower
+ than intptr_t. All uses changed.
+
+2020-08-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Ignore another memory leak
+
+ * src/pdumper.c (dump_mmap_contiguous_heap):
+ Ignore the heap control block when checking for leaks.
+
+2020-08-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Simplify use of __lsan_ignore_object
+
+ * configure.ac: Use AC_CHECK_FUNCS_ONCE for __lsan_ignore_object.
+ * src/buffer.c, src/data.c, src/emacs-module.c, src/regex-emacs.c:
+ * src/search.c: Use __lsan_ignore_object unconditionally, and don’t
+ include sanitizer/lsan_interface.h.
+ * src/lisp.h (__lsan_ignore_object): Provide a dummy in the
+ typical case where leak sanitization is not available.
+
+2020-08-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Simplify pointer computation in mark_maybe_object
+
+ * src/alloc.c (mark_maybe_object):
+ Use simpler way to avoid -fsanitize=undefined false alarms,
+ by converting the word tag to intptr_t first.
+ Omit now-unnecessary runtime overflow check.
+ (mark_memory): Work even if UINTPTR_MAX <= INT_MAX (!).
+
+2020-08-03 Philipp Stephani <phst@google.com>
+
+ Avoid duplicate Edebug symbols when backtracking (Bug#42701)
+
+ When Edebug backtracks, it nevertheless generates definitions for the
+ non-matching branches, see Bug#41988 and Bug#42701. This should be
+ fixed eventually (probably by deferring the definition until a branch
+ is known to match), but for now add a band-aid to avoid these
+ duplicate symbols, at least for anonymous forms.
+
+ * lisp/emacs-lisp/edebug.el (edebug-make-enter-wrapper): Regenerate
+ anonymous names.
+
+ * test/lisp/emacs-lisp/edebug-tests.el
+ (edebug-tests-duplicate-symbol-backtrack): New regression test.
+
+2020-08-03 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 8576297b2a (origin/emacs-27) ; lisp/so-long.el: Prevent potential err...
+ 986c12b20f ; * lisp/so-long.el: Byte-compilation bug fix
+ 19f8f36f11 ; * lisp/so-long.el (so-long-variable-overrides): Improve doc
+ 83bc4ad369 ; * so-long.el: Documentation and spelling
+ 72c5f71cd4 Avoid segfaults if XIM is set but not xim_styles
+ f54ddb0198 (emacs-27) ; * test/lisp/emacs-lisp/generator-tests.el: St...
+
+ # Conflicts:
+ # test/lisp/emacs-lisp/generator-tests.el
+
+2020-08-03 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ e12d1fbc15 ; ChangeLog.3 and etc/AUTHORS fixes
+ 748f0d4bc6 * admin/authors.el (authors-aliases): Remove a faulty regexp.
+
+ # Conflicts:
+ # etc/AUTHORS
+
+2020-08-03 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change in 'try_window'
+
+ * src/xdisp.c (try_window): Don't modify the logic when EOB is in
+ the viewport. (Bug#42653)
+
+2020-08-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make `n'/`p' in image-mode also find externally converted images
+
+ * lisp/image-file.el (image-file-name-regexp): Use it to make
+ `n'/`p' in image mode work (bug#39994).
+
+ * lisp/image/image-converter.el
+ (image-converter-file-name-extensions): New variable to keep track
+ of all suffixes.
+ (image-convert-p): Update.
+ (image-converter--find-converter): Set.
+
+2020-08-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with viewing .webp files from .zip buffers
+
+ * lisp/image-mode.el (image-toggle-display-image): Make it
+ possible to view images (via external formatters, like webp) from
+ zip files (and other archive modes) (bug#39994).
+
+2020-08-03 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust error message in image-mode
+
+ * lisp/image-mode.el (image-mode): Even when
+ `image-user-external-converter' is on, we may get
+ `unknown-image-type' (bug#39994). Adjust the error message in
+ that case.
+
+2020-08-03 Derek Zhou <derek@3qin.us>
+
+ Fix problem where TLS connections would sometimes hang
+
+ * src/process.c (wait_reading_process_output): Before the select,
+ check every interesting gnutls stream for available data in the
+ buffer. If some of them hit, and either there is no wait_proc or
+ the wait_proc is one of the gnutls streams with new data, set the
+ select timeout to 0 after the select, and merge the gnutls buffer
+ status into the select returns (bug#40665). This fixes a problem
+ where TLS connections would sometimes hang.
+
+2020-08-02 Philipp Stephani <phst@google.com>
+
+ Improve Edebug symbols for inlined secondary methods (Bug#42671)
+
+ * lisp/emacs-lisp/cl-generic.el (cl-defgeneric): Include qualifiers in
+ Edebug symbol name.
+
+ * test/lisp/emacs-lisp/cl-generic-tests.el
+ (cl-defgeneric/edebug/method): Adapt unit test.
+
+2020-08-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ If gnus-visual is nil, don't fontify patches and the like
+
+ * doc/misc/emacs-mime.texi (Display Customization): Document it.
+
+ * lisp/gnus/gnus-art.el (gnus-mime-display-single): Bind it.
+
+ * lisp/gnus/mm-view.el (mm-inline-font-lock): New variable (bug#38421).
+ (mm-display-inline-fontify): Use it.
+
+2020-08-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Document that :width/:height in XBM images are peculiar
+
+ * doc/lispref/display.texi (XBM Images): Note the peculiarities of
+ :width/:height in XBM images (bug#39735).
+
+2020-08-02 Philipp Stephani <phst@google.com>
+
+ Add a workaround for Bug#42672
+
+ * lisp/emacs-lisp/cl-generic.el (cl-defgeneric): Work around Bug#42672
+ by uniquifying inline method names.
+
+ * test/lisp/emacs-lisp/cl-generic-tests.el
+ (cl-defgeneric/edebug/method): New regression test.
+
+2020-08-02 Andrea Corallo <akrl@sdf.org>
+
+ Fix defsubst missing inline Bug#42664
+
+ * lisp/emacs-lisp/byte-run.el (defsubst): Do not native compile
+ defsubsts to have them always effective.
+
+2020-08-02 Philipp Stephani <phst@google.com>
+
+ Avoid duplicate Edebug symbols when using ‘cl-flet’ (Bug#41989)
+
+ * lisp/emacs-lisp/edebug.el (edebug-match-:unique): Add a new
+ ‘:unique’ specifier to generate unique names.
+
+ * lisp/emacs-lisp/cl-macs.el (cl-flet): Use it. This requires
+ inlining the ‘cl-defun’ specification.
+
+ * test/lisp/emacs-lisp/edebug-tests.el (edebug-tests-cl-flet): New
+ unit test.
+
+ * doc/lispref/edebug.texi (Specification List): Document new ‘:unique’
+ construct.
+
+2020-08-02 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-08-02 Eli Zaretskii <eliz@gnu.org>
+
+ Re-enable scroll-margin when cursor-motion optimization is disabled
+
+ * src/xdisp.c (try_window): Fix logic of disabling margins when
+ cursor is close to BOB or EOB. Account for header-line, if any,
+ when computing the scroll margin in pixels. (Bug#42653)
+
+2020-08-02 Philipp Stephani <phst@google.com>
+
+ * src/alloc.c (mark_maybe_object): Avoid signed integer overflow
+
+2020-08-02 Philipp Stephani <phst@google.com>
+
+ Don’t generate duplicate symbols for secondary CL methods (Bug#42671)
+
+ * lisp/emacs-lisp/edebug.el
+ (edebug-match-cl-generic-method-qualifier): Add matcher for
+ ‘cl-defmethod’ qualifier.
+
+ * lisp/emacs-lisp/cl-generic.el (cl-defmethod): Use it.
+
+ * test/lisp/emacs-lisp/edebug-tests.el
+ (edebug-cl-defmethod-qualifier): New unit test.
+
+2020-08-02 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change in alloc.c.
+
+ * src/alloc.c (mark_maybe_object) [WIDE_EMACS_INT]: Avoid compiler
+ warning about 'overflow' being unused.
+
+2020-08-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make the "All" setting for large-newsgroup-initial in Gnus work
+
+ * lisp/gnus/gnus-sum.el (gnus-articles-to-read): Use it.
+ (gnus-summary-insert-old-articles): Ditto.
+
+ * lisp/gnus/gnus.el (large-newsgroup-initial): Make the "All"
+ setting work by using a special symbol, instead of nil which is
+ indistinguishable from not being present (bug#38466).
+
+2020-08-02 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Tramp portability issues
+
+ * lisp/net/tramp-sh.el (tramp-set-remote-path): Replace "echo -n" by
+ "printf", it isn't portable.
+
+ * test/lisp/net/tramp-tests.el (tramp-test33-environment-variables)
+ (tramp-test33-environment-variables-and-port-numbers): Do not use
+ "echo -n", it isn't portable.
+ (tramp--test-utf8): Filter out not displayable characters.
+
+2020-08-02 Philipp Stephani <phst@google.com>
+
+ * src/alloc.c (mark_memory): Avoid signed integer overflow
+
+2020-08-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Signal an error in the user clicks "cancel" when signing in epg
+
+ * lisp/epg.el (epg-sign-string): If the user clicks "cancel" on
+ the pinentry, then we don't have an error from gpg(sm), but
+ instead nothing (bug#39058). Signal an error in that case.
+
+2020-08-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix erc bug when there's two channels with the same name
+
+ * lisp/erc/erc.el (erc-generate-new-buffer-name): Fix logic when
+ there's two channels with the same name from two different servers
+ (bug#40121).
+
+2020-08-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Try to fix mailcap parsing again to respect Emacs defaults
+
+ * lisp/net/mailcap.el (mailcap--computed-mime-data): New variable.
+ (mailcap-parse-mailcaps): Don't delete Emacs-distributed fallback
+ values (bug#40247).
+ (mailcap-add-mailcap-entry): Extend to allow working on different
+ variables.
+ (mailcap-add): Store data in mailcap-user-mime-data, since it
+ should be heeded first.
+
+2020-08-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make some erc function aliases obsolete
+
+ * lisp/erc/erc-networks.el (erc-current-network):
+ * lisp/erc/erc-join.el (erc-autojoin-channels-delayed):
+ * lisp/erc/erc-backend.el (erc-server-setup-periodical-ping)
+ (erc-server-send-ping, erc-server-send-queue):
+ * lisp/erc/erc-autoaway.el (erc-autoaway-reestablish-idletimer)
+ (autoaway): Adjust callers.
+
+ * lisp/erc/erc-compat.el (erc-with-selected-window)
+ (erc-cancel-timer, erc-make-obsolete)
+ (erc-make-obsolete-variable): Make these aliases obsolete.
+
+2020-08-02 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix race condition in erc-server-send-queue vs quitting erc
+
+ * lisp/erc/erc-backend.el (erc-server-send-queue): Check that the
+ buffer is live before using it (bug#40418). This fixes a rare
+ problem when the queue is non-empty when `erc-quit-server' is run.
+
+2020-08-01 Philipp Stephani <phst@google.com>
+
+ * src/alloc.c (mark_maybe_object): Make overflow check conditional.
+
+2020-08-01 Philipp Stephani <phst@google.com>
+
+ Improve offset calculation in wide int builds
+
+ * src/alloc.c (mark_maybe_object): Make sure that OFFSET isn’t widened
+ during subtraction.
+
+2020-08-01 Philipp Stephani <phst@google.com>
+
+ * src/alloc.c (resize_string_data): Adjust string bytes (Bug#42540)
+
+2020-08-01 Alan Third <alan@idiocy.org>
+
+ Recreate macOS color list if it is corrupt
+
+ * src/nsterm.m (ns_term_init): Generate the color list if there are
+ less colors in the existing file than in rgb.txt.
+
+2020-08-01 Michael Albinus <michael.albinus@gmx.de>
+
+ Implement alternative for Tramp's signal return string
+
+ * lisp/net/tramp-adb.el (process-file-return-signal-string): Declare.
+ (tramp-adb-get-signal-strings): New defun.
+ (tramp-adb-handle-process-file): Use it.
+
+ * lisp/net/tramp-sh.el (process-file-return-signal-string): Declare.
+ (tramp-sh-get-signal-strings): New defun.
+ (tramp-sh-handle-process-file): Use it.
+
+ * lisp/net/tramp.el (tramp-get-signal-strings): Remove function.
+
+ * test/lisp/net/tramp-tests.el (tramp-test28-process-file):
+ Accept alternative signal return string.
+
+2020-08-01 Philipp Stephani <phst@google.com>
+
+ Use a more precise check for '__lsan_ignore_object'
+
+ * configure.ac: Add check for __lsan_ignore_object.
+
+ * src/buffer.c (enlarge_buffer_text):
+ * src/data.c (make_blv):
+ * src/emacs-module.c (Fmodule_load, initialize_environment):
+ * src/regex-emacs.c (regex_compile):
+ * src/search.c (newline_cache_on_off): Use new configuration macro.
+
+2020-08-01 Philipp Stephani <phst@google.com>
+
+ Suppress sanitizer errors about pointer arithmetic in a few places
+
+ We perform weird pointer arithmetic due to the layout of Lisp_Objects
+ holding symbols. ASan/UBSan warns about that (Bug#42530). Suppress
+ the warnings by performing the arithmetic on integer types and casting
+ back to pointers.
+
+ * src/alloc.c (mark_maybe_object, mark_memory): Temporarily cast
+ pointer to 'intptr_t'.
+
+2020-08-01 Philipp Stephani <phst@google.com>
+
+ Suppress leak sanitizer in a few more places
+
+ * src/regex-emacs.c (regex_compile):
+ src/search.c (newline_cache_on_off): Suppress leak sanitizer.
+
+2020-08-01 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change
+
+ * src/emacs-module.c (initialize_environment): Call
+ __lsan_ignore_object only if HAVE_SANITIZER_LSAN_INTERFACE_H is
+ undefined. This fixes compilation on systems that don't have
+ __lsan_* functions.
+
+2020-08-01 Philipp Stephani <phst@google.com>
+
+ Suppress leak detector in some cases
+
+ We intentionally leak some objects. Prevent the ASan leak detector
+ from raising false alarms in these cases.
+
+ * configure.ac: Search for lsan_interface.h header.
+
+ * src/data.c (make_blv): Allow leaking of buffer-local values.
+
+ * src/buffer.c (enlarge_buffer_text): Allow leaking of buffer text.
+
+ * src/emacs-module.c (Fmodule_load, initialize_environment): Allow
+ intentional leak of runtime and environment objects if module
+ assertions are enabled.
+
+2020-08-01 Philipp Stephani <phst@google.com>
+
+ * test/data/emacs-module/mod-test.c (Fmod_test_string_a_to_b): Fix leak
+
+2020-07-31 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/byte-opt.el: Minor simplifications
+
+ (byte-optimize-form-code-walker): Use `byte-optimize-form` after
+ inlining, so optimizations are also applied to the top level call.
+ Simplify the code for `pure` functions using `byte-optimize-constant-args`.
+ (byte-optimize-all-constp): Remove, not used any more.
+ (byte-optimize-1+, byte-optimize-1-): Remove, they are redundant
+ with the `pure` annotation.
+
+2020-07-31 Stefan Kangas <stefankangas@gmail.com>
+
+ Declare some ancient compat aliases obsolete (Bug#41328)
+
+ * lisp/comint.el (comint-read-noecho):
+ * lisp/emacs-lisp/edebug.el (edebug-all-defuns):
+ * lisp/man.el (manual-entry):
+ * lisp/vc/log-edit.el (vc-log-mode-map, vc-log-entry-mode): Declare
+ ancient backwards-compatibility aliases and functions obsolete. The
+ oldest in this list was added in 1992, and the most recent in 2004.
+
+ * lisp/net/telnet.el (telnet-initial-filter): Don't use
+ `comint-read-noecho'.
+
+2020-07-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Minor dns.el clean up
+
+ * lisp/net/dns.el (dns-query-asynchronous, dns-query): Adjust some
+ parameter names to not end with "p", as these are not predicates.
+
+2020-07-31 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make gravatar-build-url respect dynamically bound variables again
+
+ * lisp/image/gravatar.el (gravatar-build-url): Compute
+ query-string first, so that dynamically bound values of
+ `gravatar-rating' (etc.) are respected, instead of computing it
+ when the callback happens.
+
+2020-07-30 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-07-30 work around some Oracle Studio attribute bugs
+ 2020-07-29 fsusage, regex, stat-size: remove Cray support
+ 2020-07-26 inttypes: remove support for AIX 4
+ 2020-07-26 gettimeofday: remove workaround for Mac OS X 10.0
+ 2020-07-26 don't require gl_LOCALTIME_BUFFER_DEFAULTS
+ 2020-07-26 alloca: remove Cray-2 and Cray Y-MP support
+ 2020-07-26 libgmp: remove dependency on havelib
+ 2020-07-26 libgmp: remove HAVE_GMP, LIB_GMP
+ 2020-07-25 multiarch: prepare for x86_64+arm64 universal in macOS 11
+ 2020-07-25 sigprocmask: small autoconf macro improvement
+ 2020-07-25 small autoconf macro improvements
+ 2020-07-24 timespec: remove dependence on ‘verify’
+ 2020-07-24 optimize a few more three-valued comparisons
+ 2020-07-24 fix _GL_CMP parenthesization typo
+ 2020-07-23 optimize three-valued comparison between integers
+ 2020-07-24 doc: update for Mac OS X 10.13
+ 2020-07-23 fchmodat, lchmod: use /proc on Cygwin
+ 2020-07-21 inttypes: fix PRI*PTR and SCN*PTR on 64-bit native Windows
+ 2020-07-12 libgmp: avoid warning when --without-libgmp is used
+ 2020-07-12 libgmp: link to the correct shared library
+ * lib/mini-gmp-gnulib.c: Ignore -Wsuggest-attribute=malloc only for
+ * build-aux/config.guess, build-aux/config.sub:
+ * build-aux/install-sh, doc/misc/texinfo.tex, lib/c-strcasecmp.c:
+ * lib/c-strncasecmp.c, lib/fchmodat.c, lib/fsusage.c:
+ * lib/gettimeofday.c, lib/inttypes.in.h, lib/lchmod.c:
+ * lib/mini-gmp-gnulib.c, lib/nstrftime.c, lib/regex.h, lib/timespec.h:
+ * m4/alloca.m4, m4/getgroups.m4, m4/gettimeofday.m4:
+ * m4/gnulib-common.m4, m4/inttypes.m4, m4/libgmp.m4, m4/mktime.m4:
+ * m4/multiarch.m4:
+ Copy from Gnulib.
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+ * src/Makefile.in, test/Makefile.in (LIBGMP):
+ Rename from LIB_GMP for compatibility with Gnulib.
+ All uses changed.
+
+2020-07-30 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port to Oracle Studio 12.6 (sparc)
+
+ * src/alloc.c (__builtin_unwind_init) [!HAVE___BUILTIN_UNWIND_INIT]:
+ Move from here ...
+ * src/lisp.h: ... to here, since flush_stack_call_func uses it.
+ * src/pdumper.c (dump_off_from_lisp): Avoid ‘return n;;’ to pacify
+ Oracle Studio.
+
+2020-07-30 Eli Zaretskii <eliz@gnu.org>
+
+ Fix face extension past EOL in overlay strings
+
+ * src/xdisp.c (face_at_pos): Pass ATTR_FILTER to
+ face_for_overlay_string.
+ * src/xfaces.c (face_for_overlay_string): Accept an additional
+ argument ATTR_INDEX and pass it to merge_face_ref for merging the
+ face at POS. This ensures a face from buffer text will not be
+ merged unless it specifies the :extend attribute. (Bug#42552)
+ * src/dispextern.h (face_for_overlay_string): Adjust prototype.
+
+2020-07-30 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Tramp bug#42538
+
+ * lisp/net/tramp-sh.el (tramp-set-remote-path): Send the command
+ in several chunks if it is too large. (Bug#42538)
+
+2020-07-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make libravatar lookups asynchronous
+
+ * lisp/gnus/gnus-gravatar.el (gnus-gravatar-insert): Fix check for
+ repeated gravatars, which is now easier to trigger now that things
+ are more asynchronous.
+
+ * lisp/image/gravatar.el (gravatar--service-libravatar): Fetch the
+ data asynchronously (bug#40676).
+ (gravatar-service-alist): Adjust all providers so they are
+ asynchronous.
+ (gravatar-build-url): Adjust caller to be asynchronous.
+ (gravatar-retrieve): Ditto.
+ (gravatar-retrieve-synchronously): Ditto.
+
+2020-07-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add the new function dns-query-asynchronous
+
+ * lisp/net/dns.el (dns-query-asynchronous): New function.
+ (dns--lookup, dns--filter): New internal functions.
+ (dns-query): Reimplement on top of dns-query-asynchronous.
+
+2020-07-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use lexical binding in dns.el
+
+ * lisp/net/dns.el: Use lexical-binding.
+ (dns-write-bytes, dns-read): Adjust for lexical-binding.
+
+2020-07-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Small dns.el code cleanup
+
+ * lisp/net/dns.el (dns-query): Clean up code slightly by removing
+ a macro and moving the code into the function itself.
+
+2020-07-30 Glenn Morris <rgm@gnu.org>
+
+ * admin/gitmerge.el (gitmerge-resolve): Discard AUTHORS conflicts.
+
+2020-07-29 Glenn Morris <rgm@gnu.org>
+
+ Update a gravatar test
+
+ * test/lisp/image/gravatar-tests.el (gravatar-build-url):
+ Update for recent change in default gravatar-service.
+
+2020-07-29 Mattias Engdegård <mattiase@acm.org>
+
+ Preserve match data in 'kbd'
+
+ * lisp/subr.el (kbd): Preserve match data since this function is
+ declared pure (see discussion in bug#42147).
+
+2020-07-29 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ d024fc141b (origin/emacs-27) * doc/lispref/symbols.texi (Definitions)...
+ d78e0f3cd5 ; lisp/ldefs-boot.el: Update.
+ 27877e7bcf (tag: emacs-27.1-rc1) * etc/HISTORY: Add Emacs 27.1 release...
+
+2020-07-29 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 1fc742b63e ; Update ChangeLog.3
+ 4c7f6217da * etc/AUTHORS: Update.
+ 24391f517a Update authors.el
+ 56f958807c * etc/NEWS: Remove temporary markup.
+ 73a2f51043 Add another test for global module references
+
+ # Conflicts:
+ # etc/AUTHORS
+ # etc/NEWS
+
+2020-07-29 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 4b3085a7fe Fix last change
+ efdd4632c9 Fix Arabic shaping when column-number-mode is in effect
+ d5acc50941 Fix description of kmacro-* commands in the user manual
+
+2020-07-29 Michael Albinus <michael.albinus@gmx.de>
+
+ * etc/NEWS: Fix typos.
+
+2020-07-29 Michael Albinus <michael.albinus@gmx.de>
+
+ Tramp doc edit
+
+ * doc/misc/tramp.texi: Use it.
+
+ * doc/misc/trampver.texi: Declare @trampurl.
+
+2020-07-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't default to librgravatar, since there are security implications
+
+ * lisp/image/gravatar.el (gravatar-service): Change the default
+ from libravatar, since that has privacy concerns (bug#40676).
+
+2020-07-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Use a new method to determine when to auto-stop image animations
+
+ * lisp/image.el (image-animate-timeout): Make the animation
+ auto-stop use a decaying average to determine when to stop
+ (bug#40685). The default stop condition will probably require
+ some tweaking -- the current default may be too aggressive.
+
+2020-07-29 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make eww use the XDG download directory
+
+ * lisp/net/eww.el (erc--download-directory): New function (bug#41030).
+ (eww-download-directory): Use it.
+ (eww-download): Use it.
+ (eww-download-callback): Adjust parameters.
+
+2020-07-29 Philip K <philip@warpmail.net>
+
+ Make the erc-header-line default to header-line
+
+ * lisp/erc/erc.el (erc-header-line): Inherit from header-line (the
+ old values were very similar in light mode, but very different
+ in dark mode) (bug#41095).
+
+2020-07-29 Juri Linkov <juri@linkov.net>
+
+ * lisp/vc/vc-git.el (vc-git-log-view-mode): Font-lock AuthorDate (bug#40248)
+
+ Highlight "AuthorDate" in log-view-font-lock-keywords
+ when [format] pretty = fuller.
+
+2020-07-29 Philip K <philip@warpmail.net>
+
+ Replace project-kill-buffers-ignores with project-kill-buffer-conditions
+
+ * lisp/progmodes/project.el (project-kill-buffer-conditions):
+ Replace the project-kill-buffers-ignores user option.
+ (project--kill-buffer-check): New function.
+ (project--buffers-to-kill): New function.
+ (project-kill-buffers): Use them. Add the NO-CONFIRM argument.
+
+2020-07-28 Nicolas Petton <nicolas@petton.fr>
+
+ Revert "* etc/NEWS.27: Remove temporary markup."
+
+ This reverts commit c270104e503cf0435a5ae40c5d0e430f4ef4bfb0.
+
+2020-07-28 Nicolas Petton <nicolas@petton.fr>
+
+ * etc/NEWS.27: Remove temporary markup.
+
+ * etc/AUTHORS: Update.
+
+2020-07-28 Nicolas Petton <nicolas@petton.fr>
+
+ Update authors.el
+
+ * admin/authors.el (authors-aliases): Add author aliases.
+ (authors-ignored-files):
+ (authors-valid-file-names):
+ (authors-renamed-files-alist): Update file lists.
+
+2020-07-28 Mattias Engdegård <mattiase@acm.org>
+
+ Simplify and streamline optimizer clauses
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker):
+ Remove clause for 'with-output-to-temp-buffer', since it is a
+ macro and will have been expanded before reaching this point.
+ Move clauses for 'lambda' and 'closure' to avoid splitting
+ a cond jump table.
+
+2020-07-28 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix uses of deprecated SELinux security_context_t
+
+ SELinux has used 'char *' in place of its typedef
+ 'security_context_t' since 2014 (v2.3) because the latter was
+ inconvenient to use when paired with the 'const' qualifier. The
+ typedef has been kept around for compatibility with legacy callers,
+ but it is deprecated in SELinux v3.1. See the following URL for the
+ relevant announcement:
+ https://lore.kernel.org/selinux/20200710162034.GC1768200@localhost.localdomain/
+
+ * src/fileio.c (Fcopy_file, Ffile_selinux_context)
+ (Fset_file_selinux_context) [HAVE_LIBSELINUX]: Replace deprecated
+ 'security_context_t' typedef with the equivalent 'char *'.
+
+2020-07-28 Michael Albinus <michael.albinus@gmx.de>
+
+ Apply simpler fix for Tramp bug#39399
+
+ * lisp/net/tramp-sh.el (tramp-open-shell): Remove "~/.editrc" editing.
+ (tramp-open-connection-setup-interactive-shell): Move up "set +o
+ vi +o emacs" command. (Bug#39399)
+
+2020-07-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix thinko in previous nnmail.el patch
+
+ * lisp/gnus/nnmail.el (nnmail-check-duplication): Fix thinko in
+ previous patch -- group-art is a list of pairs, not a pair.
+
+2020-07-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with new-mail-mark in Gnus with non-unique names
+
+ * lisp/gnus/gnus-group.el (gnus-group-new-mail): Call with Gnus
+ group name.
+ (gnus-group-catchup): Ditto.
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-exit): Ditto.
+
+ * lisp/gnus/nnimap.el (nnimap-update-info): Store Gnus group name.
+
+ * lisp/gnus/nnmail.el (nnmail-check-duplication): Store unique
+ Gnus names in the history instead of backend-specific (possibly
+ duplicated) group names (bug#41842).
+
+2020-07-28 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ * doc/misc/gnus.texi: Add introductory section to Gnus manual
+
+ "Don't Panic: Your first 20 minutes with Gnus."
+
+2020-07-27 João Távora <joaotavora@gmail.com>
+
+ Make newer ElDoc versions are compatible with Emacs < 28
+
+ (Bug#42563)
+
+ For some time, Eldoc has has some Elisp-specific code that shouldn't
+ live there, but in elisp-mode.el. This can be fixed in Emacs master,
+ but since ElDoc is distributed in GNU Elpa and is meant to work with
+ Emacs 26 and 27, this means that that elisp-specific code must still
+ be distributed with eldoc.el and kept up to date.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc--eval-expression-setup): Ensure
+ implementation is compatible with Emacs < 28.
+ (Version): Bump to 1.8
+
+2020-07-27 João Távora <joaotavora@gmail.com>
+
+ Bring back ElDoc's eldoc-display-message-p, but obsolete it
+
+ Like others, this is an implementation detail that third parties could
+ be relying on. Better not remove it outright just now, since its
+ implementation is very simple anyway.
+
+ * lisp/emacs-lisp/eldoc.el (Version): Bump to 1.7.0
+ (eldoc-display-message-p): Bring back, but obsolete.
+
+2020-07-27 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix argument reference
+
+ * lisp/progmodes/project.el
+ (project-display-buffer-other-frame): Fix argument reference.
+
+2020-07-27 Dmitry Gutov <dgutov@yandex.ru>
+
+ Move project--value-in-dir to a different section
+
+ * lisp/progmodes/project.el (project--value-in-dir):
+ Move closer to its uses.
+
+2020-07-27 Dmitry Gutov <dgutov@yandex.ru>
+
+ Bind switch-to-buffer-obey-display-actions to t
+
+ * lisp/progmodes/project.el (project--other-place-command):
+ Bind switch-to-buffer-obey-display-actions to t, so that
+ project-other-window-command and friends can affect
+ project-switch-to-buffer.
+
+2020-07-27 Sean Whitton <spwhitton@spwhitton.name>
+
+ Add project other place commands
+
+ * lisp/progmodes/project.el (project-other-window-map,
+ project-other-frame-map, project--other-place-command,
+ project-other-window-command, project-other-frame-command,
+ project-other-tab-command): Add these functions and maps.
+ * lisp/progmodes/project.el: Bind project-other-window-command to C-x
+ 4 p, project-other-frame-command to C-x 5 p and
+ project-other-tab-command to C-x t p (bug#42210).
+
+2020-07-27 Sean Whitton <spwhitton@spwhitton.name>
+
+ Add project-display-buffer and project-display-buffer-other-frame
+
+ * lisp/progmodes/project.el (project-display-buffer,
+ project-display-buffer-other-frame): Add commands.
+
+2020-07-27 Sean Whitton <spwhitton@spwhitton.name>
+
+ Factor out project--read-project-buffer from project-switch-buffer
+
+ * lisp/progmodes/project.el (project--read-project-buffer): New
+ function extracted from project-switch-buffer.
+ * lisp/progmodes/project.el (project-switch-buffer): Instead of
+ unconditionally reading a project buffer from the user, add
+ buffer-or-name argument, and populate it using
+ project--read-project-buffer when called interactively. Update
+ docstring.
+
+2020-07-26 Philipp Stephani <phst@google.com>
+
+ Small refactoring to simplify the interface of internal function.
+
+ * src/emacs-module.c (allocate_emacs_value): Remove STORAGE parameter.
+ (lisp_to_value): Adapt caller.
+
+2020-07-26 João Távora <joaotavora@gmail.com>
+
+ Correct order or eldoc-documentation-functions in Elisp mode
+
+ (Bug#42531)
+
+ * lisp/progmodes/elisp-mode.el (emacs-lisp-mode): Reverse order of
+ eldoc-documentation-functions.
+
+2020-07-26 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savahnna/master' into HEAD
+
+2020-07-26 Andrea Corallo <akrl@sdf.org>
+
+ Add NATIVE_COMP to `system-configuration-features'
+
+ * configure.ac (emacs_config_features): Add NATIVE_COMP
+
+2020-07-26 Andrea Corallo <akrl@sdf.org>
+
+ Add `comp-ensure-native-compiler' guarding entry points
+
+ * lisp/emacs-lisp/comp.el (comp-ensure-native-compiler): New function.
+ (native-compile, batch-native-compile)
+ (batch-byte-native-compile-for-bootstrap, native-compile-async):
+ Make use of `comp-ensure-native-compiler'.
+
+2020-07-25 Philipp Stephani <phst@google.com>
+
+ Make checking for liveness of global values more precise.
+
+ We can't just use a hash lookup because a global and a local reference
+ might refer to the same Lisp object.
+
+ * src/emacs-module.c (module_free_global_ref): More precise check for
+ global liveness.
+
+ * test/data/emacs-module/mod-test.c (Fmod_test_globref_invalid_free):
+ New test module function.
+ (emacs_module_init): Export it.
+
+ * test/src/emacs-module-tests.el
+ (module--test-assertions--globref-invalid-free): New unit test.
+
+2020-07-25 Philipp Stephani <phst@google.com>
+
+ Fix subtle bug when checking liveness of module values.
+
+ We can't simply look up the Lisp object in the global reference table
+ because an invalid local and a valid global reference might refer to
+ the same object. Instead, we have to test the address of the global
+ reference against the stored references.
+
+ * src/emacs-module.c (module_global_reference_p): New helper function.
+ (value_to_lisp): Use it.
+
+ * test/data/emacs-module/mod-test.c
+ (Fmod_test_invalid_store_copy): New test module function.
+ (emacs_module_init): Export it.
+
+ * test/src/emacs-module-tests.el
+ (module--test-assertions--load-non-live-object-with-global-copy):
+ New unit test.
+
+2020-07-25 Mattias Engdegård <mattiase@acm.org>
+
+ Optimise 3-arg +, - and *
+
+ Turn (+ a b c) into (+ (+ a b) c), and do the same for - and *.
+ The 2-arg operations have their own bytecode which results in a 1.5×
+ speed-up. Furthermore, the transform enables other optimisations; for
+ example, (+ a 1 b) -> (+ (1+ a) b).
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-plus, byte-optimize-minus)
+ (byte-optimize-multiply): Transform (OP a b c) into (OP (OP a b) c).
+
+2020-07-25 Eli Zaretskii <eliz@gnu.org>
+
+ Update and improve documentation of project.el commands
+
+ * doc/emacs/custom.texi (Prefix Keymaps): Document
+ 'project-prefix-map'.
+ * doc/emacs/maintaining.texi (Project File Commands)
+ (Switching Projects): Describe key bindings for the commands
+ described in the sections. Document 'project-list-file'.
+ (Project Buffer Commands): New section.
+ * doc/emacs/emacs.texi (Top): Add Project sections to the detailed
+ menu.
+
+ * etc/NEWS: Add entries for project.el, and mark documented entries as
+ appropriate.
+
+2020-07-25 Eli Zaretskii <eliz@gnu.org>
+
+ Fix display of man pages after killing the 'man' process
+
+ * lisp/man.el (Man-bgproc-filter, Man-bgproc-sentinel): Use
+ 'buffer-live-p' instead of just testing the buffer's name.
+ (Bug#42160)
+
+2020-07-25 Dmitry Gutov <dgutov@yandex.ru>
+
+ project-remember-project: New public function
+
+ * lisp/progmodes/project.el (project-remember-project):
+ Rename from project--add-to-project-list-front (bug#42332).
+ And autoload it.
+
+2020-07-24 Juri Linkov <juri@linkov.net>
+
+ * lisp/vc/vc-git.el (vc-git-log-view-mode): Fix commit regexp (bug#40248)
+
+ The regexp 'log-view-message-re' should match e.g. "commit 123456789",
+ not "CommitDate".
+
+2020-07-23 Tassilo Horn <tsdh@gnu.org>
+
+ Don't call undefined function elisp-eldoc-documentation-function (bug#42493)
+
+ * lisp/ielm.el (inferior-emacs-lisp-mode): Add
+ `elisp-eldoc-var-docstring' and `elisp-eldoc-funcall' as
+ `eldoc-documentation-functions' instead of the undefined
+ elisp-eldoc-documentation-function (bug#42493).
+
+2020-07-23 Tassilo Horn <tsdh@gnu.org>
+
+ bug-reference auto-setup for IRC, implementation for ERC
+
+ * lisp/progmodes/bug-reference.el (bug-reference-setup-from-irc-alist):
+ Change SERVER-REGEXP to NETWORK-REGEXP in docstring.
+ * lisp/progmodes/bug-reference.el (bug-reference--maybe-setup-from-irc):
+ Change semantics from requiring a match of channel OR server to
+ requiring a match of both (if both are configured).
+ * lisp/progmodes/bug-reference.el (bug-reference-try-setup-from-erc):
+ New defun doing the auto-setup for ERC.
+ (bug-reference--run-auto-setup): Run bug-reference-try-setup-from-erc.
+ * etc/NEWS: Extend entry describing bug-reference auto-setup.
+
+2020-07-23 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix viewing of encrypted S/MIME messages
+
+ * lisp/gnus/mm-decode.el (mm-possibly-verify-or-decrypt): Don't
+ add a content-type header if there already is one (bug#41659).
+
+2020-07-23 Philipp Stephani <phst@google.com>
+
+ Fix memory leak for global module objects (Bug#42482).
+
+ Instead of storing the global values in a global 'emacs_value_storage'
+ object, store them as hash values alongside the reference counts.
+ That way the garbage collector takes care of cleaning them up.
+
+ * src/emacs-module.c (global_storage): Remove.
+ (struct module_global_reference): New pseudovector type.
+ (XMODULE_GLOBAL_REFERENCE): New helper function.
+ (module_make_global_ref, module_free_global_ref): Use
+ 'module_global_reference' struct for global reference values.
+ (value_to_lisp, module_handle_nonlocal_exit): Adapt to deletion of
+ 'global_storage'.
+
+2020-07-23 João Távora <joaotavora@gmail.com>
+
+ Don't needlessly request docs from ElDoc functions
+
+ (Bug#42421)
+
+ Do this conservatively for now: if the ElDoc helper buffer (as
+ returned by eldoc--doc-buffer) is visible and showing documentation
+ for the very same "situation" (as computed by the the new
+ eldoc--request-state helper), don't request that documentation from
+ sources again.
+
+ Before this change, not only was that request inefficient but if the
+ user invoked scroll-other-window to see more of the helper buffer,
+ that would eventually cause it to be reformatted and unexpectedly
+ recentered.
+
+ Later on, when a customizable list of documentation "sinks" is offered
+ to the user, say, something like eldoc-display-functions, this process
+ must be consolidated. In those circumstances, as soon as one of those
+ sinks signals that it doesn't have up-to-date documentation for the
+ state computed by eldoc--request-state, documentation will have to be
+ requested anew from eldoc-documentation-functions via
+ eldoc--invoke-strategy.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc--request-docs-p): Rework from
+ eglot-display-message-p.
+ (eldoc--last-request-state): New variable.
+ (eldoc--request-state): New helper.
+ (eldoc--handle-docs): Memorize state of request in doc buffer.
+ (eldoc-print-current-symbol-info): Pass a token to
+ eldoc--request-docs-p.
+ (Version): Bump to 1.6.0
+
+2020-07-22 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 4db3235fd8 Run custom-magic-reset in the customize buffer
+ 3c9c3f04de ; spelling fix
+
+2020-07-22 Mattias Engdegård <mattiase@acm.org>
+
+ Calc: fix interval entry snag (bug#42438)
+
+ * lisp/calc/calc.el (calcDigit-key): Don't signal a 'Bad format' error
+ when entering '..' after pushing an incomplete interval.
+
+ Reported by Allen Li.
+
+2020-07-20 Ken Manheimer <ken.manheimer@gmail.com>
+
+ Rectify allout-widgets region undecoration so item at start is not missed.
+
+ * lisp/allout-widgets.el (allout-widgets-undecorate-region):
+ Reorganize the loop so an item at the start is not skipped.
+
+2020-07-20 Ken Manheimer <ken.manheimer@gmail.com>
+
+ Resolve missing button-region keymap bindings.
+
+ * lisp/allout-widgets.el (allout-item-icon-keymap,
+ allout-item-body-keymap, allout-cue-span-keymap, allout-widgets-mode):
+ Inherit from both (current-local-map) and (current-global-map). This
+ provides for missing global bindings when inheriting from
+ just (current-local-map), eg Esc-<.
+
+2020-07-20 Ken Manheimer <ken.manheimer@gmail.com>
+
+ Provide missing let definition to prevent background void-variable error.
+
+ * lisp/allout-widgets.el (allout-widgets-exposure-change-processor)
+ Let-declare handled-conceal, for reference through `(symbol-value)'
+ within the let body. (Because the error happens in an
+ after-change-functions hook, so it is caught and reported as a message
+ by allout-widgets-hook-error-handler.)
+
+2020-07-20 Ken Manheimer <ken.manheimer@gmail.com>
+
+ Don't let item decoration be disrupted by too-shallow items.
+
+ * lisp/allout-widgets.el (allout-decorate-item-and-context): Check for
+ parent-position having value before using it.
+
+ Also, shift local emacs vars topic deeper so it doesn't constitute
+ an instance of that particular aberrant case.
+
+2020-07-20 Ken Manheimer <ken.manheimer@gmail.com>
+
+ Fix allout-widgets-mode handling of edits to item cue, fixing (bug#11312)
+
+ * lisp/allout-widgets.el (allout-decorate-item-cue): Properly decorate
+ item cue span.
+ (allout-setup-text-properties): use allout-graphics-modification-handler
+ as allout-cue-span-category modification hook.
+
+2020-07-20 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ cd93debc60 (origin/emacs-27) Merge branch 'emacs-27' of git.savannah....
+ 2c0c613ec5 Document prefix arg effects for 'epa-mail-{sign,encrypt}'
+ 551123e0b2 * etc/NEWS: Correct description of :client-certificate change
+ 05c4329cf5 Revert "Fix filename completion in shell mode buffers"
+ de68572742 Improve documentation of 'bookmark-bmenu-mode'
+ fd85e70be7 Update systems using GnuTLS certificate files
+ 0d4ba1c2b2 Improve documentation of 'kill-emacs'
+ b3bbd4fd00 Improve documentation of 'display-raw-bytes-as-hex'
+ f50d79af6b Correct descriptions of init file
+ e325d2638c Fix interrupt-process on MS-Windows
+ d24e56a5e4 Revert "* doc/misc/flymake.texi (An annotated example back...
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-07-20 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix problem with Tramp progress reporter
+
+ * lisp/net/tramp.el (with-tramp-progress-reporter): Do not span a
+ new progress reporter if there's already another one.
+
+2020-07-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make xwidget-webkit-browse-url slightly more DWIM
+
+ * lisp/xwidget.el (xwidget-webkit-browse-url): Prepend "https" to
+ URLs that don't have a protocol (bug#31369).
+
+2020-07-20 Mattias Engdegård <mattiase@acm.org>
+
+ Suppress relint false positive in gnus-start.el
+
+ * lisp/gnus/gnus-start.el (gnus-active-to-gnus-format):
+ Add suppressive comment. Prepending "^to\\.\\|" is redundant when
+ 'gnus-ignored-newsgroups' already matches that pattern, but adding
+ logic here is not worth the trouble.
+
+2020-07-20 Dmitry Gutov <dgutov@yandex.ru>
+
+ project.el: Add more docs and two new key bindings
+
+ * lisp/progmodes/project.el:
+ Add a longer description of the package and how to use it.
+ (project-prefix-map): Add entries for
+ 'project-or-external-find-file' and
+ 'project-or-external-find-regexp'.
+
+2020-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Only kill url-retrieve-synchronously connections when we have a timeout
+
+ * lisp/url/url.el (url-retrieve-synchronously): Only kill the
+ connections when we have a timeout (bug#34607).
+
+2020-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make timeouts work more reliably in url-retrieve-synchronously
+
+ * lisp/url/url.el (url-retrieve-synchronously): Ensure that the
+ processes have been killed on timeouts before returning the buffer
+ (bug#34607).
+
+2020-07-19 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-07-19 Daniele Nicolodi <daniele@grinta.net> (tiny change)
+
+ url-http: Fix handling of redirect locations
+
+ * lisp/url/url-http.el (url-http-parse-headers): Parse redirect
+ URIs more like other web browsers (bug#42382).
+
+ RFC 7231 the Location header is defined to carry a URI-reference.
+ According to RFC 3986 it should be percent-encoded and thus should not
+ contain spaces. However, there are HTTP server implementation (notably
+ nginx) that do not do that. This makes Emacs url-http.el behave like
+ most other HTTP client implementatios. Also remove the stripping of
+ angle bracket quotes as they are not valid according to the RFCs.
+
+2020-07-19 Satoshi Nakagawa <ghnacker@gmail.com> (tiny change)
+
+ Support Proxy-Authorization in HTTPS CONNECT proxies
+
+ * lisp/url/url-http.el (url-https-proxy-connect): Support CONNECT
+ with Proxy-Authorization header (bug#42422).
+
+2020-07-19 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp-adb.el (tramp-adb-prompt): Further simplification.
+
+ Suggested by Mattias Engdegård <mattiase@acm.org>.
+
+2020-07-19 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Complete over the MIME types in gnus-summary-save-parts
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-save-parts): Allow
+ completing over the parts in the first article in the list of the
+ process-marked articles (bug#39543).
+
+2020-07-19 Štěpán Němec <stepnem@gmail.com>
+
+ gnus-button-alist: Prefer URL links to Elisp library links
+
+ * lisp/gnus/gnus-art.el (gnus-button-alist): Move the URL clauses
+ higher up the list before library link setup to prevent URLs ending in
+ ".el" from failing to be recognized (and invalid library links being
+ created instead) (bug#39781).
+
+2020-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Do window configuration change before killing Gnus buffers on exit
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-exit): Do window
+ configuration changes before killing off the summary buffer, so
+ that the window conf machinery can return to a group-only
+ configuration (bug#40069).
+
+2020-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow adjusting the `W Q' Gnus summary command interactively
+
+ * doc/misc/gnus.texi (Article Washing): Document it.
+
+ * lisp/gnus/gnus-art.el (article-fill-long-lines): Take a numeric
+ prefix as the fill width (bug#38698).
+
+2020-07-19 Alan Mackenzie <acm@muc.de>
+
+ Remove redundant code from c-font-lock-fontify-region
+
+ * lisp/progmodes/cc-mode.el (c-font-lock-fontify-region): Remove variables
+ string-fence-beg and lim, and the code used to calculate them.
+
+2020-07-19 Philipp Stephani <phst@google.com>
+
+ Add missing 'require'.
+
+ * lisp/progmodes/project.el: Require seq.el explicitly as
+ 'seq-every-p' isn't autoloaded in Emacs 26.3.
+
+2020-07-19 Kévin Le Gouguec <kevin.legouguec@gmail.com>
+
+ Simplify dummy root subject before comparing it to the current article
+
+ * lisp/gnus/gnus-sum.el (gnus-summary-prepare-threads): Simplify both
+ the dummy root and the following article before comparing them,
+ otherwise both the former and the latter might display the thread's
+ subject even when gnus-summary-line-format contains "%s" (bug#40520).
+
+2020-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix C-c C-f in the Gnus article buffer
+
+ * lisp/gnus/gnus-art.el (gnus-article-mode-map): Make the C-c C-f
+ command work in the article buffer, too (bug#40548).
+
+2020-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Mention the Emacs bug tracker in the bug reporting doc strings
+
+ * lisp/gnus/gnus-msg.el (gnus-bug): Mention the Emacs bug tracker.
+
+ * lisp/mail/emacsbug.el (report-emacs-bug): Link directly to the
+ Emacs portion of the bug reports (bug#41109).
+
+2020-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Doc fix for article-fill-long-lines
+
+ * lisp/gnus/gnus-art.el (article-fill-long-lines): Mention that it
+ also respects `fill-column' (bug#41534).
+
+2020-07-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Allow open-network-stream to use different TLS capability commands
+
+ * doc/lispref/processes.texi (Network): Document non-string
+ capability command.
+ * lisp/gnus/nntp.el (nntp-open-connection): Use HELP for Typhoon
+ and CAPABILITIES for everything else (bug#41960).
+
+ * lisp/net/network-stream.el (open-network-stream): Document
+ function variety of :capability-command.
+ (network-stream-open-starttls): Use it.
+ (network-stream-open-tls): Ditto.
+ (network-stream-open-shell): Ditto.
+ (network-stream--capability-command): New helper function.
+
+2020-07-19 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Narrow to headers in gnus-registry before getting data
+
+ * lisp/gnus/gnus-registry.el (gnus-registry-spool-action): Narrow
+ to the headers before getting data from them (bug#42029).
+
+2020-07-19 João Távora <joaotavora@gmail.com>
+
+ Fix ElDoc bugs around eldoc-echo-area-use-multiline-p.
+
+ If the value is 'truncate-sym-name-if-fit and the single docstring
+ doesn't fit in the echo area even when the symbol name is elided, that
+ step shouldn't be attempted. Also if the value is nil, really ensure
+ that only the first line is shown.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc--handle-docs): Rework
+ 'truncate-sym-name-if-fit case of eldoc-echo-area-use-multiline-p.
+
+2020-07-19 Juri Linkov <juri@linkov.net>
+
+ * lisp/window.el (display-buffer-override-next-command): Add ECHO arg.
+
+ * lisp/frame.el (other-frame-prefix):
+ * lisp/tab-bar.el (other-tab-prefix):
+ * lisp/windmove.el (windmove-display-in-direction):
+ * lisp/window.el (other-window-prefix, same-window-prefix):
+ Use new ECHO arg of display-buffer-override-next-command.
+
+ https://lists.gnu.org/archive/html/emacs-devel/2020-06/msg00819.html
+
+2020-07-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't have shr kill random buffers on network failures
+
+ * lisp/url/url-queue.el (url-queue-callback-function): Don't kill
+ off random buffers on HTTP failures (bug#40976).
+
+2020-07-18 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make eww-open-file work with Tramp file names
+
+ * lisp/net/eww.el (eww-open-file): Allow opening non-local Tramp
+ files (bug#40425).
+ (eww): Adjust calling convention to allow passing in data directly
+ via a buffer.
+
+2020-07-18 Eli Zaretskii <eliz@gnu.org>
+
+ Fix documentation of a recent change in shr.el
+
+ * lisp/net/shr.el (shr-max-width, shr-width): Fix typo and wording
+ of the doc strings.
+
+ * etc/NEWS: Fix the wording of the 'shr-max-width's entry, and
+ move it to the SHR section.
+
+2020-07-17 Tassilo Horn <tsdh@gnu.org>
+
+ bug-reference auto-setup for IRC, implementation for rcirc
+
+ * lisp/progmodes/bug-reference.el (bug-reference-setup-from-irc-alist):
+ New defvar for configuring bug regexp and URL based on IRC channel and
+ server names.
+ (bug-reference--maybe-setup-from-irc): New defun doing the setup given
+ channel and server.
+ (bug-reference-try-setup-from-rcirc): New defun calling the above for
+ rcirc buffers.
+ (bug-reference--run-auto-setup): Enable the auto-setup for rcirc.
+ * etc/NEWS: Extend entry describing bug-reference auto-setup.
+
+2020-07-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix NOT-CURRENT behaviour in text-property-search-backward
+
+ * lisp/emacs-lisp/text-property-search.el
+ (text-property-search-backward): Fix inconsistent behaviour of
+ S-TAB in eww (and other callers that use the NOT-CURRENT
+ behaviour) when there are adjacent elements
+ (bug#39239).
+
+2020-07-17 Xu Chunyang <xuchunyang56@gmail.com>
+
+ Fix <textarea> default texts in eww
+
+ * lisp/net/eww.el (eww-tag-textarea): <textarea> default text
+ comes from the contents, not a value attribute (bug#39867).
+
+2020-07-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't message complete GIF data upon errors
+
+ * src/image.c (gif_load): When unable to parse a GIF specified
+ via a data attribute, don't message the complete binary, because
+ that's not useful (bug#40850).
+
+2020-07-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add support for a shr-max-width variable
+
+ * doc/misc/eww.texi (Advanced): Document it.
+
+ * lisp/net/shr.el (shr-max-width): Add new variable (bug#40909).
+ (shr-insert-document): Use it.
+
+2020-07-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Clarify shr width computation
+
+ * lisp/net/shr.el (shr-insert-document): Clarify width
+ computation: shr-width was checked again in the `else' part where
+ we already knew it was nil.
+
+2020-07-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make old aliases to gnus-child* commands work before Gnus is loaded
+
+ * lisp/gnus/gnus.el (gnus-slave-no-server, gnus-slave): Mark as
+ obsolete in a way that still lets them be used as interactive
+ commands before Gnus is loaded.
+ * lisp/gnus/gnus-agent.el (gnus-slave-unplugged): Ditto (bug#42401).
+
+2020-07-17 Stefan Kangas <stefankangas@gmail.com>
+
+ Show eww bookmarks buffer only if it's not empty
+
+ * lisp/net/eww.el (eww-list-bookmarks): Don't show buffer if there
+ are no bookmarks. (Bug#41385)
+ (eww-bookmark-prepare): Move signalling an error if there are no
+ bookmarks from here...
+ (eww-read-bookmarks): ...to here. Add new argument `error-out' to
+ control this.
+ (eww-next-bookmark, eww-previous-bookmark): Call
+ `eww-read-bookmarks'.
+
+2020-07-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problems with not rendering shr tables with rowspan
+
+ * lisp/net/shr.el (shr-max-columns): When rowspans were in effect,
+ columns would go missing from subsequent lines (bug#42194).
+
+2020-07-17 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Adjust naming convention for dependent Gnus sessions
+
+ * doc/misc/gnus.texi (Child Gnusae): Rename node from "Slave
+ Gnusae" and adjust wording. Also remove at least one joke.
+
+ * lisp/gnus/gnus-start.el (gnus-no-server-1, gnus-1)
+ (gnus-setup-news, gnus-save-newsrc-file): Adjust parameter names.
+ (gnus-child-mode): Rename and add alias.
+ (gnus-child-save-newsrc): Rename.
+ (gnus-parent-read-child-newsrc): Ditto.
+
+ * lisp/gnus/gnus-group.el (gnus-group-mode)
+ (gnus-group-get-new-news): Ditto.
+
+ * lisp/gnus/gnus-agent.el (gnus-child-unplugged): Rename function
+ from gnus-slave-unplugged (and add the latter as an obsolete alias).
+
+ * lisp/gnus/gnus.el (gnus-other-frame-function): Adjust function
+ names in the defcustom to new naming scheme.
+ (gnus-other-frame-resume-function): Ditto.
+ (gnus): Adjust parameter names.
+
+2020-07-16 Tassilo Horn <tsdh@gnu.org>
+
+ Add tramp and orgmode to bug-reference-setup-from-mail-alist.
+
+ Also add a TODO that I should implement something similar for
+ IRC (rcirc/ERC).
+
+ * lisp/progmodes/bug-reference.el (bug-reference-setup-from-mail-alist):
+ Auto-setup also with groups matching orgmode and tramp.
+
+2020-07-16 Juri Linkov <juri@linkov.net>
+
+ Use describe-char-padded-string for composed character names in "C-u C-x ="
+
+ * lisp/descr-text.el (describe-char): Use describe-char-padded-string
+ for displaying Unicode names of composed characters on GUI frames.
+ (Bug#42256)
+
+2020-07-15 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savahnna/master' into HEAD
+
+2020-07-15 Andrea Corallo <akrl@sdf.org>
+
+ Add a testcase for bug#42360
+
+ * test/src/comp-tests.el (comp-test-42360): New testcase.
+
+ * test/src/comp-test-funcs.el (comp-test-42360-f): New function.
+
+2020-07-15 Andrea Corallo <akrl@sdf.org>
+
+ Fix bug#42360
+
+ * src/comp.c (compile_function): Allocate function frame as array
+ if non local exits are present to retain correct Elisp semantic.
+ (emit_limple_call_ref): Directly use the frame array for ref calls
+ to have GCC spills into it before calling.
+
+2020-07-15 Tassilo Horn <tsdh@gnu.org>
+
+ ;Fix eldoc regression bug#42365
+
+2020-07-15 Jonas Bernoulli <jonas@bernoul.li>
+
+ * lisp/epa.el (epa-show-key): New command.
+
+ Users can move in `epa-key-list-mode' buffers using either
+ `next-line'/`previous-line' or `widget-forward'/`widget-backward'.
+ When using the first set of commands, then the cursor stays in the
+ current column and that normally is the first column. The key
+ widgets do not begin until the third character of their respective
+ lines.
+
+ All `epa' commands work regardless of whether the cursor is on the
+ widget or before them. The `epa-show-key' command did not exist until
+ now because the `widget-button-press' already performs its task. But
+ because the widgets don't span complete lines we actually need this
+ command too.
+
+2020-07-15 Jonas Bernoulli <jonas@bernoul.li>
+
+ epa-key-list-mode-map: Use widget-keymap as parent keymap
+
+ Normally when one keymap is to be treated as the parent of another,
+ then that relationship is setup once at the time when the child is
+ being defined, i.e. at birth. For some reason, this was not done
+ here; instead `widget-keymap' is set as `epa-key-list-mode-map'
+ parent every time the former is setup to be used as the local map.
+
+ This appears to be a mistake. A few other keymaps use `widget-keymap'
+ as their parent and in those cases the relationship is established
+ just once. `epa-key-list-mode-map' is the only exception and because
+ there is absolutely no indication that that is justified, we remove
+ this inconsistency.
+
+ * lisp/epa.el (epa-key-list-mode-map): Set the parent of this keymap
+ while defining it.
+ * lisp/epa.el (epa--list-keys): Do not set the parent of the local
+ keymap here.
+
+2020-07-15 Jonas Bernoulli <jonas@bernoul.li>
+
+ Cosmetic changes to epa libraries
+
+ These changes make the code more readable.
+
+ * lisp/epa-dired.el (epa-dired-do-decrypt, epa-dired-do-verify)
+ (epa-dired-do-sign, epa-dired-do-encrypt): Use dolist instead
+ of while.
+ * lisp/epa-file.el (epa-file-passphrase-callback-function):
+ Set just one variable per setq call.
+
+2020-07-15 Jonas Bernoulli <jonas@bernoul.li>
+
+ Drop unnecessary backward compatibility aliases
+
+ We can assume that `encode-coding-string' and `decode-coding-string'
+ are available; they were added in 1997.
+
+ * lisp/epa-file.el (epa-file--encode-coding-string)
+ (epa-file--decode-coding-string): Remove aliases for
+ encode-coding-string and decode-coding-string.
+ * lisp/epa-file.el (epa-file-write-region): Use encode-coding-string
+ instead of removed epa-file--encode-coding-string.
+
+2020-07-15 Jonas Bernoulli <jonas@bernoul.li>
+
+ Improve and add doc-strings
+
+ * lisp/epa-file.el (epa-file-select-keys):
+ lisp/epa-hook.el (epa-file-name-regexp):
+ lisp/epa.el (epa-exit-buffer): Improve doc-string.
+ * lisp/epa-hook.el (epa-file-name-regexp-update): Add doc-string.
+
+2020-07-15 Jonas Bernoulli <jonas@bernoul.li>
+
+ * lisp/epg-config.el (epg-config--make-gpg-configuration): Fix indentation.
+
+2020-07-15 Jonas Bernoulli <jonas@bernoul.li>
+
+ Add all epa faces to epa-faces Custom group
+
+ `epa-validity-face-alist' isn't actually a face but belongs
+ in that group anyway.
+
+ * lisp/epa.el (epa-field-name, epa-field-body)
+ (epa-validity-face-alist): Add to epa-faces Custom group.
+
+2020-07-15 Jonas Bernoulli <jonas@bernoul.li>
+
+ * lisp/epa.el (epa-faces): Move definition.
+
+ Previously option `epa-mail-aliases' was the only option that was
+ defined right after the group `epa-faces' and right before all the
+ faces. Now it is defined with all the other options and thus before
+ the definition of the `epa-faces' group, which it does not belong to.
+
+2020-07-15 Andrea Corallo <akrl@sdf.org>
+
+ Add a simple major mode for coloring LIMPLE in the log buffer
+
+ * lisp/emacs-lisp/comp.el (comp-limple-lock-keywords): New const.
+ (comp-limple-mode): New major mode.
+ (comp-log-to-buffer): Enable `comp-limple-mode' in the log buffer.
+
+2020-07-15 Juri Linkov <juri@linkov.net>
+
+ Improve display of composed character names in "C-u C-x =" on GUI frames
+
+ * lisp/descr-text.el (describe-char): On GUI frames, display the
+ Unicode names of really composed characters only (Bug#42256)
+
+2020-07-14 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Consistently stylize eldoc as ElDoc in more prose
+
+ This fixes new occurrences of "Eldoc" since emacs-27.
+
+ * doc/lispref/modes.texi (Major Mode Conventions):
+ * etc/NEWS:
+ * lisp/descr-text.el (describe-char-eldoc):
+ * lisp/emacs-lisp/eldoc.el (eldoc-echo-area-use-multiline-p)
+ (eldoc-prefer-doc-buffer, eldoc--documentation-strategy-defcustom):
+ Consistently capitalize eldoc as ElDoc rather than Eldoc in
+ documentation and commentary.
+
+2020-07-14 Juri Linkov <juri@linkov.net>
+
+ Improve documentation of "C-u C-x ="
+
+ * doc/emacs/mule.texi (International Chars): Update the
+ composition information displayed by "C-u C-x =". (Bug#42256)
+
+2020-07-13 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savahnna/master' into HEAD
+
+2020-07-13 Andrea Corallo <akrl@sdf.org>
+
+ Rename `comp-propagate' into `fw-prop'
+
+ * lisp/emacs-lisp/comp.el (comp-passes): Rename `comp-propagate'
+ -> `comp-fwprop'.
+ (comp-fwprop-prologue): Rename from `comp-propagate-prologue'.
+ (comp-fwprop-insn): Rename from `comp-fwprop-insn'.
+ (comp-propagate*): Rename from `comp-propagate*' and update.
+ (comp-fwprop): Rename from `comp-propagate' and update.
+
+2020-07-13 Andrea Corallo <akrl@sdf.org>
+
+ Clean-up now unnecessary backward propagation in comp.el
+
+ * lisp/emacs-lisp/comp.el (comp-passes): Invoke 'comp-propagate'
+ instead of 'comp-propagate-alloc'.
+ (comp-mvar): Remove unnecessary `array-idx' slot.
+ (comp-propagate-prologue): Remove.
+ (comp-propagate-prologue): Remove `backward' parameter and
+ backward propagation logic.
+ (comp-propagate1): Remove and move logic into `comp-propagate'.
+ (comp-propagate-alloc): Remove pass.
+
+2020-07-13 Andrea Corallo <akrl@sdf.org>
+
+ Rework frame allocation strategy
+
+ All frame slots are now simple automatic variables given the array
+ allocation and fill is done in 'emit_limple_call_ref'.
+
+ * src/comp.c (comp_t): Remove 'f_frame' 'arrays' slots, add
+ 'frame'.
+ (emit_mvar_lval): Simplify to make use of 'comp.frame'.
+ (compile_function): Clean-up and add comp.frame initialization.
+
+2020-07-13 Andrea Corallo <akrl@sdf.org>
+
+ Rework the backend to allocate arument arrays for call by references
+
+ * src/comp.c (comp_t): Add 'zero' field.
+ (emit_limple_call_ref): Allocate an array to host the parameters
+ and generate the code moving values into.
+ (Fcomp__init_ctxt): Initialize comp.zero.
+
+2020-07-13 Juri Linkov <juri@linkov.net>
+
+ Display "C-u C-x =" composed character names on GUI frames as well
+
+ * lisp/descr-text.el (describe-char): On GUI frames, display the
+ Unicode names of the composed characters like they are displayed
+ on TTY frames. (Bug#42256)
+
+2020-07-12 Eli Zaretskii <eliz@gnu.org>
+
+ ;* lisp/progmodes/project.el (project-current): Doc fix.
+
+2020-07-12 James N. V. Cash <james.nvc@gmail.com> (tiny change)
+
+ Fix a typo in eldoc.el
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-documentation-functions): Fix a
+ typo. (Bug#42310)
+
+2020-07-12 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last doc changes in project.el
+
+ * lisp/progmodes/project.el (project-find-functions)
+ (project-current): Add back information which was recently
+ removed.
+
+2020-07-12 João Távora <joaotavora@gmail.com>
+
+ Sort out ElDoc backward compatibility of eldoc-documentation-function
+
+ As explained previously, we can't simply make
+ eldoc-documentation-function an variable alias for
+ eldoc-documentation-strategy, because ElDoc is pre-loaded in Emacs <
+ 28, where it holds at least one buffer-local binding. So if eldoc.el
+ is loaded in those versions, we do the variable alias binding in
+ reverse. We do this using a macro
+ eldoc--documentation-strategy-defcustom to at load time in which
+ direction to make the variable alias.
+
+ * lisp/emacs-lisp/eldoc.el
+ (eldoc--documentation-strategy-defcustom): Helper macro.
+ (eldoc-documentation-strategy, eldoc-documentation-function): Use it.
+ (Version): Bump to 1.5.0
+
+2020-07-12 Michael Albinus <michael.albinus@gmx.de>
+
+ More Tramp code cleanup
+
+ * lisp/net/tramp.el (tramp-process-actions):
+ * lisp/net/tramp-adb.el (tramp-adb-handle-file-system-info)
+ (tramp-adb-handle-set-file-times)
+ (tramp-adb-maybe-open-connection):
+ * lisp/net/tramp-cmds.el (tramp-rename-files, tramp-rename-these-files)
+ (tramp-reporter-dump-variable):
+ * lisp/net/tramp-sh.el (tramp-do-file-attributes-with-stat)
+ (tramp-sh-handle-file-selinux-context)
+ (tramp-do-directory-files-and-attributes-with-stat)
+ (tramp-sh-handle-file-name-all-completions)
+ (tramp-sh-handle-write-region)
+ (tramp-sh-handle-file-notify-add-watch)
+ (tramp-sh-gvfs-monitor-dir-process-filter)
+ (tramp-sh-inotifywait-process-filter)
+ (tramp-sh-handle-file-system-info, tramp-find-executable)
+ (tramp-open-shell, tramp-find-shell):
+ * lisp/net/tramp-smb.el (tramp-smb-do-file-attributes-with-stat)
+ (tramp-smb-handle-file-system-info):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-file-selinux-context)
+ (tramp-sudoedit-handle-file-system-info): Remove superfluous
+ `eval-when-compile', `concat' creates the string during byte
+ compilation. Reported by Mattias Engdegård <mattiase@acm.org>.
+
+ * lisp/net/tramp-adb.el (tramp-adb-prompt): Simplify.
+ (tramp-adb-send-command):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-dbus-string-to-byte-array):
+ Use `string-match-p'.
+
+ * lisp/net/tramp-sh.el (tramp-sunos-unames): New defconst.
+ (tramp-find-executable, tramp-find-shell, tramp-get-remote-stat): Use it.
+
+2020-07-12 Dmitry Gutov <dgutov@yandex.ru>
+
+ project-kill-buffers: Update the docstring too
+
+ * lisp/progmodes/project.el (project-kill-buffers):
+ Copy a sentence over from project-switch-to-buffer.
+
+2020-07-12 Dmitry Gutov <dgutov@yandex.ru>
+
+ More docstring updates in project.el
+
+ * lisp/progmodes/project.el (project-find-functions)
+ (project-current, project-switch-to-buffer):
+ More docstring updates.
+
+2020-07-11 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ c04b92104c Add commentary in gtkutil.c
+ 6290850dac Consistently stylize eldoc as ElDoc in prose
+ 136e931189 Improve documentation of "C-u C-x ="
+ 1f52771fd3 Mention floating rounding issues
+ c892ae65b4 Repair global-auto-revert-ignore-modes (bug#42271)
+ 3a446a02fb ; * src/xdisp.c (decode_mode_spec): Fix commentary.
+ 79f381b4a6 One more improvement of left/right-fringe display spec docs
+ 1279bdb072 Another clarification of left/right-fringe display spec
+
+ # Conflicts:
+ # doc/emacs/programs.texi
+
+2020-07-11 Mattias Engdegård <mattiase@acm.org>
+
+ Correct 'concat' manual entry (bug#42296)
+
+ * doc/lispref/strings.texi (Creating Strings): 'concat' does not
+ necessarily return a newly allocated string. This has been the case
+ at least since 1997 (Emacs 20.3).
+
+2020-07-11 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix multibyte chars of file names in tramp-adb.el
+
+ * lisp/net/tramp-adb.el (tramp-adb-execute-adb-command): Revert return
+ value meaning. Insert the result into the connection buffer.
+ (tramp-adb-handle-file-local-copy)
+ (tramp-adb-handle-write-region, tramp-adb-handle-copy-file)
+ (tramp-adb-get-device): Adapt calls.
+ (tramp-adb-send-command): Use "adb shell ..." in case the command
+ contains multibyte chars.
+
+ * test/lisp/net/tramp-tests.el (tramp--test-utf8): Extend test.
+
+2020-07-11 Eli Zaretskii <eliz@gnu.org>
+
+ Another minor improvement of project.el doc strings
+
+ * lisp/progmodes/project.el (project-find-functions)
+ (project-current, project-switch-to-buffer): Doc fix.
+ (project-current): Rename the argument DIR to DIRECTORY.
+
+2020-07-11 Andrea Corallo <akrl@sdf.org>
+
+ * doc/misc/flymake.texi (An annotated example backend): Typo fix.
+
+2020-07-11 Dmitry Gutov <dgutov@yandex.ru>
+
+ project-switch-to-buffer: Reword the docstring
+
+ * lisp/progmodes/project.el (project-switch-to-buffer):
+ Reword the docstring, copying the style from project-kill-buffers.
+
+2020-07-10 João Távora <joaotavora@gmail.com>
+
+ Fix placement of Eldoc docs during eval-expression (bug#42309)
+
+ * lisp/emacs-lisp/eldoc.el (eldoc--handle-docs): Rework.
+
+2020-07-10 João Távora <joaotavora@gmail.com>
+
+ Revert "Fix Eldoc problem when loading on Emacs 26.3"
+
+ This reverts commit 9ade7ea7b77ec40c16deb4dff139ce7127a703e2.
+
+ * lisp/emacs-lisp/eldoc.el (Version): Bump to 1.4.0
+
+2020-07-10 Michael Albinus <michael.albinus@gmx.de>
+
+ Tramp code cleanup
+
+ * lisp/net/tramp.el (tramp-shell-prompt-pattern)
+ (tramp-wrong-passwd-regexp, tramp-method-regexp-alist)
+ (tramp-domain-regexp, tramp-host-regexp, tramp-ipv6-regexp)
+ (tramp-port-regexp, tramp-debug-outline-regexp)
+ (tramp-drop-volume-letter, tramp-parse-shostkeys)
+ (tramp-handle-file-name-case-insensitive-p):
+ * lisp/net/tramp-adb.el (tramp-adb-send-command-and-check):
+ * lisp/net/tramp-ftp.el (tramp-ftp-enable-ange-ftp):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-monitor-process-filter):
+ * lisp/net/tramp-sh.el (tramp-display-escape-sequence-regexp)
+ (tramp-device-escape-sequence-regexp):
+ * lisp/net/tramp-smb.el (tramp-smb-do-file-attributes-with-stat)
+ (tramp-smb-handle-set-file-acl, tramp-smb-read-file-entry):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-file-selinux-context):
+ Use character classes in regexp.
+
+ * lisp/net/tramp-adb.el (tramp-adb-ls-date-year-regexp)
+ (tramp-adb-ls-date-time-regexp): New defconst.
+ (tramp-adb-ls-date-regexp, tramp-adb-ls-toolbox-regexp)
+ (tramp-adb-sh-fix-ls-output): Use them.
+ (tramp-adb-handle-set-file-times, tramp-adb-maybe-open-connection):
+ Apply `eval-when-compile' on constant concat data.
+ (tramp-do-parse-file-attributes-with-ls):
+ Suppress `signal-hook-function'.
+ (tramp-adb--gnu-switches-to-ash): Remove unused function.
+ (tramp-adb-handle-set-file-modes): Qhote argument.
+ (tramp-adb-maybe-open-connection): Set file property rather than flush.
+
+ * lisp/net/tramp-cmds.el (tramp-rename-these-files):
+ Apply `eval-when-compile' on constant concat data.
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-file-attributes)
+ (tramp-gvfs-file-attributes-with-gvfs-ls-regexp): Embed them in
+ `eval-and-compile'.
+ (tramp-gvfs-get-directory-attributes): Apply `eval-when-compile'
+ on constant concat data.
+
+2020-07-10 João Távora <joaotavora@gmail.com>
+
+ Fix byte compilation warning in Eldoc
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-documentation-function): Pass nil as
+ second argument.
+
+2020-07-10 João Távora <joaotavora@gmail.com>
+
+ Fix Eldoc problem when loading on Emacs 26.3
+
+ When defining the obsolete variable alias for old
+ eldoc-documentation-function (which now points to the newer
+ eldoc-documentation-strategy), one gets the error "don't know how to
+ make a localized vareiable an alias". I'm not sure, but I suspect
+ this is because Eldoc is preloaded in Emacs 26.3 and the
+ eldoc-documentation-function variable is already set locally by some
+ Elisp buffer.
+
+ Uninterning the symbol shortly before defining the alias seems to fix
+ it.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-documentation-function):
+ Unintern on load.
+ (Version): Bump to 1.3.0
+
+2020-07-10 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix out-of-source ‘make check’ emacs-module-tests
+
+ Problem reported by Koki Fukuda in:
+ https://lists.gnu.org/r/emacs-devel/2020-07/msg00169.html
+ * test/Makefile.in (MODULE_CFLAGS):
+ Include from the same directories included from in ../src.
+ * test/src/emacs-module-tests.el (module/describe-function-1):
+ Strip path to source directory.
+
+2020-07-10 Paul Eggert <eggert@cs.ucla.edu>
+
+ Use Gnulib libgmp module
+
+ Instead of doing GMP by hand, use the Gnulib libgmp module.
+ * .gitignore: Add lib/gmp.h.
+ * admin/merge-gnulib (GNULIB_MODULES): Add libgmp.
+ * configure.ac (GMP_LIB, GMP_OBJ): Remove. Gnulib uses the name
+ LIB_GMP, so all uses changed. All uses of GMP_OBJ removed.
+ (HAVE_GMP): Set this from Gnulib’s variables.
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+ * lib/mini-gmp-gnulib.c, lib/mini-gmp.c, lib/mini-gmp.h, m4/libgmp.m4:
+ New files, copied from Gnulib.
+ * src/bignum.h, test/data/emacs-module/mod-test.c:
+ Include gmp.h unconditionally.
+ * src/mini-gmp-emacs.c, src/mini-gmp.c, src/mini-gmp.h:
+ Remove. This moves these files from src to lib, and
+ updates them to the current GMP version.
+ * test/Makefile.in (GMP_H): New macro.
+ ($(test_module)): Use it to decide whether to compile
+ mini-gmp-gnulib.c too.
+
+2020-07-10 Paul Eggert <eggert@cs.ucla.edu>
+
+ Speed up GCC 10.1 compilation in default Git builds
+
+ * configure.ac (nw): GCC 10.1 introduced warnings enabled by -fanalyzer
+ that slow down compilation considerably. Generate these warnings only
+ if --enable-gcc-warnings is explicitly given. Also, do not bother to
+ eliminate warnings that Gnulib’s revised manywarnings module no longer
+ generates.
+
+2020-07-10 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-07-07 dup2: remove support for some very old platforms
+ 2020-07-07 memchr: remove support for some very old platforms
+ 2020-07-04 getumask: new module
+ 2020-07-03 getrandom: fix compilation error on native Windows
+ 2020-07-03 lchmod: simplify after 2020-02-22 change
+ 2020-07-01 manywarnings: improve port to GCC 10.1
+ 2020-06-28 getrandom: fix compilation errors on older versions of mingw
+ 2020-06-29 alloca-opt: fix warning on mingw
+ * lib/alloca.in.h, lib/dup2.c, lib/getrandom.c, lib/string.in.h:
+ * lib/sys_stat.in.h, lib/unistd.in.h, m4/dup2.m4, m4/getrandom.m4:
+ * m4/lchmod.m4, m4/manywarnings.m4, m4/string_h.m4, m4/sys_stat_h.m4:
+ * m4/unistd_h.m4: Copy from Gnulib.
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+
+2020-07-09 Alexander Adolf <alexander.adolf@condition-alpha.com>
+
+ EUDC: Add macOS Contacts backend
+
+ * lisp/net/eudcb-macos-contacts.el: New file.
+ * doc/misc/eudc.texi (macOS Contacts): New section.
+ (macOS Contacts Configuration): Likewise.
+ * etc/NEWS: Mention new macOS Contacts backend.
+
+2020-07-09 Eli Zaretskii <eliz@gnu.org>
+
+ Improve display of compositions by "C-u C-x ="
+
+ * lisp/descr-text.el (describe-char): On TTY frames, display the
+ Unicode names of the composed characters as well. (Bug#42256)
+
+2020-07-09 João Távora <joaotavora@gmail.com>
+
+ Unbreak M-x eldoc
+
+ The command should always invoke Eldoc when called interactively,
+ instead of going through the usual checks, which are performed to
+ avoid interference with other commands.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-print-current-symbol-info): Rework.
+ (Version): Bump to 1.2.0
+
+2020-07-09 João Távora <joaotavora@gmail.com>
+
+ Prevent infloop in Eldoc message truncation algorithm
+
+ The truncation algorithm still has a long way to go for very narrow
+ frame sizes. It should become a generic mechanism that would allows
+ one to truncate a string so that fits in N possibly truncated screen
+ lines of a full-width window.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-handle-docs): Tweak
+
+2020-07-09 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into wip2
+
+2020-07-09 Andrea Corallo <akrl@sdf.org>
+
+ Disable ipa-pure in comp-tests-tco
+
+ * test/src/comp-tests.el (comp-tests-tco): Disable ipa-pure to
+ check effectively for tail recursion elimination.
+
+2020-07-09 Andrea Corallo <akrl@sdf.org>
+
+ Add `comp-disabled-passes'
+
+ * lisp/emacs-lisp/comp.el (comp-disabled-passes): New special
+ variable.
+ (native-compile): Make use of `comp-disabled-passes'.
+
+2020-07-09 Andrea Corallo <akrl@sdf.org>
+
+ ;* test/src/comp-test-funcs-dyn.el: Fix comment header.
+
+2020-07-09 Andrea Corallo <akrl@sdf.org>
+
+ Add some tests for pure function optimization
+
+ * test/src/comp-tests.el (comp-tests-fw-prop): Fix docstring.
+ (comp-tests-pure-checker-1, comp-tests-pure-checker-2): New
+ functions.
+ (comp-tests-pure): New test testing for pure function
+ optimization.
+
+2020-07-09 Andrea Corallo <akrl@sdf.org>
+
+ Optimize pure functions defined by the compilation environment
+
+ * lisp/emacs-lisp/comp.el (comp-apply-in-env): New macro.
+ (comp-function-call-maybe-remove): Update to make use of
+ `comp-apply-in-env'.
+
+2020-07-09 Andrea Corallo <akrl@sdf.org>
+
+ Introduce a new pass ipa-pure
+
+ Add a simple pass to infer pure functions not explicitly declared as
+ such. Use this information only during compilation (speed 3) to
+ optimize out function calls whe possible.
+
+2020-07-09 Andrea Corallo <akrl@sdf.org>
+
+ Add `comp-call-op-p'
+
+ * lisp/emacs-lisp/comp.el (comp-call-op-p): New predicate.
+ (comp-limple-insn-call-p): Make use of.
+
+2020-07-09 Andrea Corallo <akrl@sdf.org>
+
+ * test/src/comp-test-funcs.el (comp-tests-aref-aset-f) : Fix UB.
+
+2020-07-09 Andrea Corallo <akrl@sdf.org>
+
+ Define `comp-symbol-func-to-fun'
+
+ * lisp/emacs-lisp/comp.el (comp-symbol-func-to-fun): New function.
+ (comp-func-in-unit): Make use of the `comp-symbol-func-to-fun'.
+
+2020-07-09 Andrea Corallo <akrl@sdf.org>
+
+ Add a test targeting forward propagation
+
+ * test/src/comp-tests.el (comp-tests-fw-prop-checker-1): New
+ function.
+ (comp-tests-fw-prop): New test.
+
+2020-07-09 João Távora <joaotavora@gmail.com>
+
+ Bump Flymake version
+
+ * lisp/progmodes/flymake.el (Version): Bump to 1.0.9.
+
+2020-07-09 Glenn Morris <rgm@gnu.org>
+
+ Update tests for recent changes
+
+ * test/lisp/descr-text-tests.el (descr-text-test-desc):
+ Update for recent change to describe-char-eldoc.
+ * test/lisp/progmodes/elisp-mode-tests.el
+ (elisp--highlight-function-argument-indexed)
+ (elisp--highlight-function-argument-keyed-1)
+ (elisp--highlight-function-argument-keyed-2):
+ Update for recent change to elisp--highlight-function-argument.
+
+2020-07-09 Glenn Morris <rgm@gnu.org>
+
+ * lisp/progmodes/cc-engine.el (c-at-expression-start-p): Fix message.
+
+2020-07-08 João Távora <joaotavora@gmail.com>
+
+ Shoosh warnings about obsolete eldoc-documentation-function
+
+ * lisp/progmodes/cfengine.el (cfengine3-mode): Remove mention to
+ obsolete eldoc-documentation-function.
+
+ * lisp/progmodes/python.el (python-mode): Use with-no-warnings.
+
+2020-07-08 Andrea Corallo <akrl@sdf.org>
+
+ Rework some test logic for generality
+
+ * test/src/comp-tests.el (comp-tests-make-insn-checker): New
+ function splitting logic from `comp-tests-tco-checker' to have it
+ more general.
+ (comp-tests-tco-checker): Make use of
+ `comp-tests-make-insn-checker'.
+
+2020-07-08 Andrea Corallo <akrl@sdf.org>
+
+ Clean-up some const folding logic and add `comp-function-pure-p'
+
+ * lisp/emacs-lisp/comp.el (comp-function-pure-p): New predicate.
+ (comp-function-call-maybe-remove): Update to use the
+ `comp-function-pure-p'.
+
+2020-07-08 Mattias Engdegård <mattiase@acm.org>
+
+ Special-case symbol and fixnum keys in member, assoc and rassoc
+
+ * src/fns.c (Fmember, Fassoc, Frassoc): Delegate to the cheaper Fmemq,
+ Fassq and Frassq for arguments of the appropriate types.
+ (eq_comparable_value): New function.
+
+2020-07-08 João Távora <joaotavora@gmail.com>
+
+ Improve Eldoc docstrings
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-documentation-strategy): Improve
+ docstring.
+ (eldoc--make-callback): Improve docstring.
+ (eldoc--invoke-strategy): New helper function.
+ (eldoc-print-current-symbol-info): Call eldoc--invoke-strategy.
+ (eldoc-documentation-functions): Improve docstring.
+
+2020-07-08 João Távora <joaotavora@gmail.com>
+
+ Change version scheme of two Eldoc obsolete specs
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-documentation-function)
+ (eldoc-message): Obsolete spec uses eldoc-1.1.0.
+
+2020-07-08 João Távora <joaotavora@gmail.com>
+
+ Adjust describe-char-eldoc to new eldoc-documentation-functions protocol
+
+ * lisp/descr-text.el (describe-char-eldoc): Adjust to new
+ eldoc-documentation-functions protocol.
+
+2020-07-08 João Távora <joaotavora@gmail.com>
+
+ Adjust Eldoc documentation after Eli's review
+
+ * etc/NEWS (Eldoc): Adjust paragraphs.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-prefer-doc-buffer): Adjust
+ docstring.
+ (eldoc--enthusiasm-curbing-timer, eldoc-documentation-strategy)
+ (eldoc-documentation-functions): Adjust docstring.
+ (eldoc--handle-docs): Adjust comments.
+ (eldoc--documentation-compose-1): New helper.
+ (eldoc-documentation-compose)
+ (eldoc-documentation-compose-eagerly): Use it.
+ (eldoc-print-current-symbol-info): Adjust comments.
+
+2020-07-08 João Távora <joaotavora@gmail.com>
+
+ Make more parts of Emacs use new Eldoc capabilities
+
+ Elisp-mode was doing a lot of work that can now be delegated to Eldoc.
+ Flymake uses the new Eldoc functionality, too, installing a global
+ documentation function that may report on diagnostics under point.
+
+ CEDET's grammar.el was left as the only user of an Eldoc-internal
+ function. That function was moved to grammar.el. That file is still,
+ somewhat reprehensibly, using an internal function of elisp-mode.el,
+ but this was left unchanged.
+
+ In other situations, eldoc-documentation-functions is used or
+ recommended.
+
+ The only other places where the obsolete eldoc-documentation-function
+ is still used is in libraries which are presumably meant to remain
+ compatible with previous Emacs versions.
+
+ * lisp/progmodes/elisp-mode.el (elisp-eldoc-funcall)
+ (elisp-eldoc-var-docstring): New functions.
+ (emacs-lisp-mode): Put two elements in
+ eldoc-documentation-functions.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc--eval-expression-setup): Setup
+ new Elisp eldoc-documentation-functions.
+
+ * lisp/progmodes/flymake.el (flymake-mode): Use
+ flymake-eldoc-function.
+ (flymake-eldoc-function): New function.
+ (Package-Requires): Require eldoc 1.1.0
+
+ * lisp/descr-text.el (describe-char-eldoc): Recommend
+ eldoc-documentation-functions.
+
+ * lisp/progmodes/cfengine.el (cfengine3-documentation-function):
+ Recommend eldoc-documentation-functions
+
+ * lisp/progmodes/octave.el (inferior-octave-mode): Use
+ eldoc-documentation-functions.
+
+ * lisp/cedet/semantic/grammar.el (semantic--docstring-format-sym-doc):
+ New function.
+ (semantic-grammar-eldoc-get-macro-docstring): Adjust.
+
+2020-07-08 João Távora <joaotavora@gmail.com>
+
+ * lisp/emacs-lisp/eldoc.el (Version): Bump to 1.1.0
+
+2020-07-08 João Távora <joaotavora@gmail.com>
+
+ New M-x eldoc for on-demand and interactive documentation requests
+
+ The function eldoc is just an alias for
+ eldoc-print-current-symbol-info, which is made interactive.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-print-current-symbol-info): Now an
+ interactive function.
+ (eldoc): Alias to eldoc-print-current-symbol-info.
+
+2020-07-08 João Távora <joaotavora@gmail.com>
+
+ Better handle asynchronous Eldoc sources
+
+ This is a backward compatible redesign of significant parts of the
+ eldoc.el library.
+
+ Previously, Eldoc clients (major/minor modes setting its documentation
+ gathering variables) needed to directly call eldoc-message, an
+ internal function, to display the docstring to the user. When more
+ asynchronous sources are involved, this is hard to do or even breaks
+ down.
+
+ Now, an Eldoc backend may return any non-nil, non-string value and
+ call a callback afterwards. This restores power to Eldoc over how
+ (and crucially also when) to display the docstrings to the user.
+
+ Among other things, this fixes so called "doc blinking", or the very
+ short-lived display of a lower priority Eldoc message. This would
+ happen if a particular producer of documentation finishes shortly
+ before a higher priority one, like in the LSP engine Eglot as reported
+ by Andrii Kolomoiets <andreyk.mad@gmail.com> and Dmitry Gutov
+ <dgutov@yandex.ru>.
+
+ Gathering docstrings is now delegated to the variable
+ eldoc-documentation-strategy, which is the new name for the
+ now-obsolete eldoc-documentation-function, and still accepts the
+ so-called "old protocol". Examples of the new strategies enabled are
+ codified in functions such as eldoc-documentation-enthusiast,
+ eldoc-documentation-compose-eagerly, along with the existing
+ eldoc-documentation-compose and eldoc-documentation-default.
+
+ The work of displaying and formatting docstrings is shifted almost
+ fully to Eldoc itself and is delegated to the internal function
+ eldoc--handle-docs. Among other improvements, it handles most of
+ eldoc-echo-area-use-multiline-p and outputs documentation to a
+ temporary *eldoc* buffer.
+
+ The manual and NEWS are updated to mention the new Eldoc features.
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-documentation-functions):
+ Overhaul docstring.
+ (eldoc-documentation-compose, eldoc-documentation-default): Handle
+ non-nil, non-string values of elements of
+ eldoc-documentation-functions. Use eldoc--handle-multiline.
+ (eldoc-print-current-symbol-info): Honour non-nil, non-string
+ values returned by eldoc-documentation-callback.
+ (eldoc--make-callback): Now also a function.
+ (eldoc-documentation-default, eldoc-documentation-compose): Tweak docstring.
+ (eldoc-documentation-enthusiast, eldoc-documentation-compose-eagerly):
+ New functions.
+ (eldoc-echo-area-use-multiline-p): Add new semantics.
+ (eldoc--handle-docs): Handle some of eldoc-echo-area-use-multiline-p.
+ (eldoc-doc-buffer): New command.
+ (eldoc-prefer-doc-buffer): New defcustom.
+ (eldoc--enthusiasm-curbing-timer): New variable.
+ (eldoc-documentation-strategy): Rename from eldoc-documentation-function.
+ (eldoc--supported-p): Use eldoc-documentation-strategy
+ (eldoc-highlight-function-argument)
+ (eldoc-argument-case, global-eldoc-mode)
+ (turn-on-eldoc-mode): Mention eldoc-documentation-strategy.
+ (eldoc-message-function): Mention eldoc--message.
+ (eldoc-message): Made obsolete.
+ (eldoc--message): New helper.
+
+ * lisp/hexl.el (hexl-print-current-point-info): Adjust to new
+ eldoc-documentation-functions protocol.
+
+ * lisp/progmodes/cfengine.el (cfengine3-documentation-function):
+ Adjust to new eldoc-documentation-functions protocol.
+
+ * lisp/progmodes/elisp-mode.el
+ (elisp-eldoc-documentation-function): Adjust to new
+ eldoc-documentation-functions protocol.
+
+ * lisp/progmodes/octave.el (octave-eldoc-function): Adjust to new
+ eldoc-documentation-functions protocol.
+
+ * lisp/progmodes/python.el (python-eldoc-function): Adjust to new
+ eldoc-documentation-functions protocol.
+
+ (eldoc-print-current-symbol-info): Rework with cl-labels.
+
+ * doc/emacs/programs.texi (Lisp Doc): Mention
+ eldoc-documentation-strategy.
+
+ * doc/lispref/modes.texi (Major Mode Conventions): Mention
+ eldoc-documentation-functions.
+
+ * etc/NEWS: Mention eldoc-documentation-strategy.
+
+2020-07-07 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-07-07 Mattias Engdegård <mattiase@acm.org>
+
+ Optimise assoc and rassoc with symbol key to assq and rassq
+
+ This is the same transformation made for member to memq.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-assoc): New function.
+ (assoc, rassoc): Set the byte-optimizer property.
+
+2020-07-07 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 71fc003860 (origin/emacs-27) Avoid infloop in 'format-mode-line'
+ 247dcb4b1b Clarify the documentation of 'left/right-fringe' display spec
+ d453cee177 Minor improvement in ELisp manual
+ 3c778c443c * doc/misc/tramp.texi (Customizing Methods): Fix typo.
+
+2020-07-07 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 59e768d64a Fix undefined behavior in json.c (Bug#42113)
+ cce00bef03 Fix ACTION argument of 'display-buffer' call in gud.el
+ 0121db2702 * src/keyboard.c (Fclear_this_command_keys): Doc fix.
+ b9abf5ceb2 Improve do string of 'man'
+ b87fc938a0 ; * src/xdisp.c (pos_visible_p): Yet another minor fix for...
+
+2020-07-07 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-macs.el (cl-deftype-satisfies): Add `keyword`
+
+2020-07-06 Mattias Engdegård <mattiase@acm.org>
+
+ Simplify byte-code optimisation of pure functions
+
+ Most pure functions need no explicit optimisation; we can do away with
+ almost all uses of byte-optimize-predicate (now renamed to
+ byte-optimize-constant-args, since it is not just for predicates).
+ Also remove some superfluous arity warnings.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-identity, byte-optimize-memq)
+ (byte-optimize-nth, byte-optimize-nthcdr):
+ Remove arity warnings and simplify.
+ * lisp/emacs-lisp/byte-opt.el (<, >, <=, >=, not, null, consp, listp)
+ (symbolp, stringp, string<, string-lessp, proper-list-p, logand)
+ (logior, logxor, lognot, car, cdr, car-safe, cdr-safe):
+ Remove superfluous byte-optimizer property.
+ (byte-optimize-predicate): Rename to byte-optimize-constant-args.
+ All uses changed.
+
+2020-07-06 Mattias Engdegård <mattiase@acm.org>
+
+ Mark more functions pure (bug#42147)
+
+ Extend the list of 'pure' functions to many predicates and numerical
+ functions that we are reasonably confident will give portable results.
+ Also include various list and array accessors, because our use of purity
+ in the byte compiler isn't affected by the mutability of arguments.
+
+ * lisp/emacs-lisp/byte-opt.el: Update example in comment.
+ (pure-fns): Add many functions.
+ (byte-optimize-form-code-walker) Don't signal errors during evaluation
+ of calls to pure functions with constant arguments at compile time,
+ since such calls are not necessarily reachable.
+
+2020-07-05 Dmitry Gutov <dgutov@yandex.ru>
+
+ * lisp/progmodes/project.el: Bump the version.
+
+2020-07-05 Dmitry Gutov <dgutov@yandex.ru>
+
+ project-switch-to-buffer: Don't filter based on default-directory
+
+ * lisp/progmodes/project.el (project-switch-to-buffer):
+ Don't filter based on default-directory
+ (https://lists.gnu.org/archive/html/emacs-devel/2020-07/msg00075.html).
+ (project-switch-to-buffer): Ditto.
+
+2020-07-05 Wilson Snyder <wsnyder@wsnyder.org>
+
+ Verilog-Mode collected updates.
+
+ * lisp/progmodes/verilog-mode.el (verilog-auto-inst): Support regexp of
+ what AUTOINST I/O to include, issue #1682. Reported by Mrainy.
+ (verilog-font-lock-keywords-1): Fix highlighting module names with no
+ following (, issue #1679. Reported by Vinam Arora.
+ (verilog-font-lock-keywords) Adds syntax highlighting for identifiers in
+ declaration statements, #1678.
+ (verilog-calculate-indent, verilog-inject-arg)
+ (verilog-keywords, verilog-showscopes): Support AMS
+ connectmodule/endconnectmodule, #1665. Reported by Dan McMahill.
+
+2020-07-05 Mattias Engdegård <mattiase@acm.org>
+
+ Don't confuse errors with nil in bytecomp-tests.el
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-check-1)
+ (bytecomp-explain-1, test-byte-opt-arithmetic, bytecomp-lexbind-check-1)
+ (bytecomp-lexbind-explain-1):
+ If an expression raises an error when evaluated, don't treat it as if
+ it had succeeded with the value nil; use 'bytecomp-check-error' as the
+ result instead.
+
+2020-07-05 Mattias Engdegård <mattiase@acm.org>
+
+ Relax portable number check in byte compiler (bug#42147)
+
+ With bignums, the set of representable integers is no longer
+ platform-dependent, and since we use nothing but IEEE754 64-bit
+ floats, all numbers are now portable. Take advantage of this fact
+ to simplify constant-folding in the byte compiler, allowing it to
+ be applied more widely.
+
+ * lisp/emacs-lisp/byte-opt.el (byte-opt--portable-max)
+ (byte-opt--portable-min, byte-opt--portable-numberp): Remove.
+ (byte-opt--arith-reduce, byte-optimize-minus, byte-optimize-1+)
+ (byte-optimize-1-): Simplify: any number will do, and if N is a
+ number, then so are -N, N+1 and N-1.
+
+2020-07-04 Alan Mackenzie <acm@muc.de>
+
+ Remove long obsolete c-looking-at-bos. Make c-at-expression-start-p obsolete
+
+ * lisp/progmodes/cc-engine.el (c-looking-at-bos): Remove.
+ (c-at-expression-start-p): Make obsolete, with no alternative function.
+
+2020-07-04 Andrea Corallo <akrl@sdf.org>
+
+ Relax constant folding rules
+
+ * lisp/emacs-lisp/comp.el (comp-function-optimizable-p): No need to
+ check for operands or result to be fixnums.
+
+2020-07-04 Alan Mackenzie <acm@muc.de>
+
+ Fix filling in js-mode and mhtml-mode (js-mode parts), fixing bug #41897
+
+ * lisp/progmodes/js.el (js-mode): Use "\\(?:" in the value of
+ comment-start-skip rather than "\\(", fixing the second half of bug #41952.
+ Call c-foreign-init-lit-pos-cache and install c-foreign-truncate-lit-pos-cache
+ on before-change-functions, to connect up correctly with CC Mode's filling
+ mechanism.
+
+ * lisp/textmodes/mhtml-mode.el (mhtml--crucial-variable-prefix): Add prefixes
+ "adaptive-fill-", "fill-", "normal-auto-fill-function" and "paragraph-" to
+ pull in variables crucial to filling.
+ (mhtml-syntax-propertize): Read the current submode from the piece of text
+ being propertized rather than one character before it, and do so before
+ erasing the submode text-property.
+ (mhtml-mode): Set the js-mode value of auto-fill-function to js-do-auto-fill.
+ Correctly initialize and use CC Mode's filling facilities, as above.
+
+2020-07-04 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Fix wrong value of comment-start-skip, fixing half of bug #41952
+
+ Also add functions to enable correct use of CC Mode's filling functionality
+ from major modes which don't initialize CC Mode fully. These modes are
+ currently js-mode and mhtml-mode.
+
+ * lisp/progmodes/cc-langs.el (comment-start-skip): Replace "\\(" by "\\(?:" so
+ that (match-end 1) isn't falsely taken to be the start of the comment.
+
+ * lisp/progmodes/cc-engine.el (c-foreign-truncate-lit-pos-cache)
+ (c-foreign-init-lit-pos-cache): New functions.
+
+2020-07-04 Daniel Koning <dk@danielkoning.com> (tiny change)
+
+ Use 'emacs-lisp-mode-syntax-table' for reading Lisp expressions
+
+ * lisp/simple.el (read--expression): Set syntax table to
+ 'emacs-lisp-mode-syntax-table' when reading a Lisp expression
+ from the minibuffer. (Bug#41781)
+
+2020-07-02 Andrea Corallo <akrl@sdf.org>
+
+ Fix missing tail recursion elimination
+
+ * lisp/emacs-lisp/comp.el (comp-tco-func): Fix tail recursion
+ elimination given now functions in LIMPLE are expressed with
+ the C name.
+
+2020-07-02 Andrea Corallo <akrl@sdf.org>
+
+ Add a test to verify tail recursion elimination
+
+ * test/src/comp-tests.el (comp-tests-tco): Compile a recursive
+ functions at speed 3 and verify the tail recursion elimination.
+ (comp-tests-tco-checker, comp-tests-mentioned-p)
+ (comp-tests-mentioned-p-1): New support functions.
+
+2020-07-02 Andrea Corallo <akrl@sdf.org>
+
+ Rework `comp-c-func-name' arguments
+
+ * lisp/emacs-lisp/comp.el (comp-c-func-name): Add FIRST argument
+ to ignore the compiler context and return the first name.
+
+ * lisp/emacs-lisp/disass.el (disassemble-internal): Update the
+ `comp-c-func-name' call.
+
+2020-07-02 Andrea Corallo <akrl@sdf.org>
+
+ Add to possibility to write per pass specific tests
+
+ * lisp/emacs-lisp/comp.el (comp-post-pass-hooks): New special
+ variable.
+ (native-compile): Run what is registered in
+ `comp-post-pass-hooks'.
+
+2020-07-02 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savahnna/master' into HEAD
+
+2020-07-02 Alan Mackenzie <acm@muc.de>
+
+ * lisp/progmodes/cc-mode.el (c-or-c++-mode--regexp): Change WS to [ \t] in it
+
+2020-07-02 Phillip Lord <phillip.lord@russet.org.uk>
+
+ Remove Emacs-27 reference
+
+ * admin/nt/dist-build/README-windows-binaries:
+
+2020-07-02 Juri Linkov <juri@linkov.net>
+
+ Revert feature added in bfd96e995d using project directories in vc (bug#41821)
+
+2020-07-01 YASUOKA Masahiko <yasuoka@yasuoka.net> (tiny change)
+
+ Support pty's on OpenBSD
+
+ * configure.ac (PTY_TTY_NAME_SPRINTF): OpenBSD has posix_openpt
+ nowadays. (Bug#42059)
+
+2020-06-30 Juri Linkov <juri@linkov.net>
+
+ Bind 'C-x 4 1' to 'same-window-prefix' and document new commands (bug#41691)
+
+ * lisp/window.el (ctl-x-4-map): Bind 'C-x 4 1' to 'same-window-prefix'.
+
+ * doc/emacs/windows.texi (Pop Up Window): Add 'C-x 4 4' and 'C-x 4 1'.
+ * doc/emacs/frames.texi (Creating Frames): Add 'C-x 5 5'.
+ (Tab Bars): Add 'C-x t t'.
+
+2020-06-30 Andrea Corallo <akrl@sdf.org>
+
+ Add a test for lambda list containing uninterned symbols
+
+ * test/src/comp-resources/comp-test-funcs-dyn.el
+ (comp-tests-cl-uninterned-arg-parse-f): New function.
+
+ * test/src/comp-tests.el (comp-tests-cl-uninterned-arg-parse-f):
+ New test.
+
+2020-06-30 Andrea Corallo <akrl@sdf.org>
+
+ Fix lambda-list relocation class
+
+ Lambda-lists must stay in the same relocation class of the object
+ referenced by code to respect uninterned symbols.
+
+ * lisp/emacs-lisp/comp.el (comp-prepare-args-for-top-level): Break
+ the original function in a generic specializing for
+ dynamic/lexical functions. When allocating the lambda-list for
+ dynamic functions do that in the default relocation class.
+ (comp-emit-for-top-level): Make use of the new
+ `comp-prepare-args-for-top-level'.
+ (comp-emit-lambda-for-top-level): Likewise.
+
+2020-06-30 James N. V. Cash <james.nvc@gmail.com> (tiny change)
+
+ Subject: Frame-local tab-bar for numeric value of tab-bar-show (bug#42052)
+
+ * lisp/tab-bar.el (tab-bar-new-tab-to): Set frame parameter
+ tab-bar-lines to 1 when tab-bar-show is the same as number of tabs.
+ (tab-bar-close-tab, tab-bar-close-other-tabs): Set frame parameter
+ tab-bar-lines to 0 when tab-bar-show is the same as number of tabs.
+
+2020-06-29 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: optimize for repeated simple operations.
+
+ Do this by recognising that unterminated strings in a buffer are typically
+ going to be few and close together. Also optimize code for C++ attributes.
+
+ * lisp/progmodes/cc-defs.el (c-previous-single-property-change): New macro.
+ (c-put-syn-tab, c-clear-syn-tab): Turned from macros into functions, and moved
+ to cc-mode.el.
+ (c-clear-syn-tab-properties): Amended to use c-min/max-syn-tab-mkr.
+ (c-with-extended-string-fences): Removed.
+
+ * lisp/progmodes/cc-engine.el (c-enclosing-c++-attribute): Rewritten for
+ speed.
+ (c-slow-enclosing-c++-attribute): Removed.
+ (c-semi-pp-to-literal): Remove a superfluous call to
+ c-with-extended-string-fences.
+
+ * lisp/progmodes/cc-mode.el (c-min-syn-tab-mkr, c-max-syn-tab-mkr): two new
+ marker variables which bound the region occupied by positions with
+ c-fl-syn-tab text properties.
+ (c-basic-common-init): Initialize these two variables.
+ (c-fl-syn-tab-region): Removed.
+ (c-put-syn-tab, c-clear-syn-tab): Functions moved from cc-defs.el.
+ (c-clear-string-fences): Amended to use the new scheme.
+ (c-restore-string-fences): Now takes no arguments; amended to use the new
+ scheme.
+ (c-font-lock-fontify-region): Amended to use the new scheme.
+
+2020-06-29 Paul Eggert <eggert@cs.ucla.edu>
+
+ * test/src/fns-tests.el (test-secure-hash): Test getrandom format.
+
+2020-06-29 Andrea Corallo <akrl@sdf.org>
+
+ Revert "* src/comp.c (Fcomp__register_subr): Remove code duplication using Fdefalias."
+
+ This reverts commit 6c7f615ae59b636efe5012f761a25acfd956480d.
+
+2020-06-28 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib.
+
+ This incorporates:
+ 2020-06-28 getrandom: do not depend on ‘open’ on mingw
+ 2020-06-28 getrandom: fix compilation errors on older versions of mingw
+ * build-aux/config.sub, lib/getrandom.c, m4/getrandom.m4:
+ Copy from Gnulib
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+
+2020-06-28 Andrea Corallo <akrl@sdf.org>
+
+ Do not skip native compilation for leim subfolder during bootstrap
+
+ * lisp/emacs-lisp/comp.el (comp-bootstrap-black-list): Remove
+ "^leim/".
+
+2020-06-28 Andrea Corallo <akrl@sdf.org>
+
+ Enable deferred compilation for dynamic scoped code
+
+ * src/comp.c (maybe_defer_native_compilation): Trigger for dynamic
+ code and add a comment.
+
+2020-06-28 Eli Zaretskii <eliz@gnu.org>
+
+ MS-Windows fixes as followup to import of Gnulib 'getrandom'
+
+ * nt/mingw-cfg.site (gl_cv_lib_assume_bcrypt): Set to "no" to
+ disable linking against bcrypt.dll. (Bug#42095)
+
+ * src/gnutls.c (gnutls_rnd) [WINDOWSNT]: Don't define a function
+ pointer, and don't load it from GnuTLS DLL.
+ (w32_gnutls_rnd) [WINDOWSNT]: Delete unused function.
+ * src/fns.c (gnutls_rnd) [WINDOWSNT]: Don't redirect to
+ w32_gnutls_rnd.
+
+2020-06-28 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into uninterned
+
+ * src/comp.c (Fcomp__register_subr): Remove code duplication using Fdefalias.
+
+2020-06-28 Andrea Corallo <akrl@sdf.org>
+
+ Add a test to verify CL macro expansion in dynamic scope
+
+ * test/src/comp-tests.el (comp-tests-cl-macro-exp): New test.
+
+ * test/src/comp-resources/comp-test-funcs-dyn.el: Require
+ `cl-lib'.
+ (comp-tests-cl-macro-exp-f): New function.
+
+2020-06-28 Andrea Corallo <akrl@sdf.org>
+
+ Setup correctly the printer while dumping objs in native CU (bug#42088)
+
+ * src/comp.c (emit_static_object): Bind a bunch of special
+ variables to setup `prin1-to-string' as
+ `byte-compile-output-file-form' does. This to preserve
+ uninterned symbols.
+
+2020-06-28 Timo Myyrä <timo.myyra@bittivirhe.fi>
+
+ Add thread-naming support for OpenBSD
+
+ OpenBSD has pthread_set_name_np; FreeBSD appears to have both
+ this call and pthread_setname_np (the latter call is used in preference).
+
+ * configure.ac: Detect pthread_set_name_np.
+ * src/systhread.c:
+ Include <pthread_np.h> and call pthread_set_name_np if available.
+
+2020-06-27 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+ src/comp.c (Fcomp__register_subr): Handle advice activation (bug#42038).
+
+2020-06-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ Use getrandom syscall for nonces
+
+ * admin/merge-gnulib (GNULIB_MODULES): Add getrandom.
+ * doc/lispref/text.texi (Format of GnuTLS Cryptography Inputs):
+ Don’t say that iv-auto uses GNUTLS_RND_NONCE. Also, don’t say
+ that it returns the IV’s actual value, as it never has done that.
+ * src/fns.c, src/sysdep.c: Include sys/random.h, for getrandom.
+ * src/fns.c (Fsecure_hash_algorithms): Use getrandom so that this
+ function does not depend on HAVE_GNUTLS3.
+ * src/sysdep.c: Do not include <gnutls/crypto.h>.
+ (random_seed) [HAVE_LRAND48]: Can be long int now.
+ (init_random) [!WINDOWSNT]: Use getrandom syscall instead
+ of opening /dev/urandom, as this works even on GNU/Linux
+ hosts that lack /dev/urandom. Don’t bother with gnutls_rnd
+ as it’s not needed now that we have getrandom.
+
+2020-06-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-06-27 getloadavg: don’t depend on fopen-gnu
+ 2020-06-25 c-dtoastr, c-ldtoastr: new modules
+ 2020-06-01 getloadavg: fix double-increment bug
+ 2020-06-01 tempname: use getrandom, not getentropy
+ 2020-05-31 tempname: merge from glibc and coreutils
+ 2020-05-31 getentropy: work around a macOS and Solaris problem
+ 2020-05-31 fnmatch: merge from glibc
+ 2020-05-30 unistd: remove conflicting declaration of getrandom
+ 2020-05-30 don't assume that UNICODE is not defined
+ 2020-05-29 fix compilation error on native Windows
+ 2020-05-28 avoid dynamic loading of Windows API functions when possible
+ 2020-05-28 at-internal: make more robust in multithreaded applications
+ 2020-05-28 getloadavg: make more robust in multithreaded applications
+ 2020-05-27 getloadavg: make more robust in multithreaded applications
+ 2020-05-26 count-one-bits: fix MSVC specific code
+ 2020-05-25 getentropy, getrandom: new modules
+ 2020-05-24 open, openat: really support O_CLOEXEC
+ 2020-05-23 verify: document ‘assume’ better
+ 2020-05-21 regex: configure better with "clang -fsanitize=leak"
+ 2020-05-21 memmem: configure better with "clang -fsanitize=undefined"
+ 2020-05-19 ftoastr: fix ifndef typo
+ * build-aux/config.guess, build-aux/config.sub, doc/misc/texinfo.tex:
+ * lib/count-one-bits.h, lib/ftoastr.c, lib/ftoastr.h:
+ * lib/getloadavg.c, lib/gettimeofday.c, lib/libc-config.h:
+ * lib/open.c, lib/openat-proc.c, lib/tempname.c, lib/tempname.h:
+ * lib/unistd.in.h, lib/verify.h, m4/memmem.m4, m4/regex.m4:
+ * m4/unistd_h.m4:
+ Update from Gnulib.
+ * lib/getrandom.c, lib/sys_random.in.h:
+ * m4/getrandom.m4, m4/sys_random_h.m4:
+ New files, copied from Gnulib.
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+
+2020-06-26 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 5280e118c0 (origin/emacs-27) ; * src/xdisp.c (pos_visible_p): Fix las...
+ bb1a9481c9 Fix posn-at-point at beginning of a display string
+ 0c4b033670 Improve documentation of Info node movement commands
+ 632b0119e1 Add Jansson dependency to Windows Build
+ dbfcdab837 Unbreak 'reverse-region'
+ c37de84845 Fix typos and markup in fill column indicator docs
+ f61bff3ee9 ; * CONTRIBUTE: Clarify the preferences for patch formatting.
+ 368e140660 Avoid crashes in 'defconst'
+ 11e3413cff Fix text about Lisp archives in the Emacs FQ
+ 4c81724675 Don't use 'cl' functions in ELisp manual's examples
+
+2020-06-26 Eli Zaretskii <eliz@gnu.org>
+
+ Fix byte-compilation warning in project.el
+
+ * lisp/emacs-lisp/seq.el (seq-every-p): Autoload it. This fixes
+ byte-compilation warning in project.el.
+
+2020-06-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ vc-known-roots: Actually update
+
+ * lisp/vc/vc-hooks.el (vc-known-roots):
+ Actually update for the change in 733921edfe (bug#41821).
+
+2020-06-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ project--read-project-list: Add structure verification
+
+ * lisp/progmodes/project.el (project--list): Update docstring.
+ (project--read-project-list): Add structure verification.
+
+2020-06-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ project-known-roots: Rename and improve
+
+ * lisp/progmodes/project.el (project-known-project-roots):
+ Rename from 'project-known-roots'. Update the docstring. Make
+ sure the returned value is a list of strings. Update the caller
+ (bug#41821).
+
+2020-06-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ Rename project-kill-buffers-{skip-conditions,ignores}
+
+ * lisp/progmodes/project.el (project-kill-buffers-ignores):
+ Rename from project-kill-buffers-skip-conditions (bug#41868).
+ Update both references.
+ Add a :package-version attribute.
+
+2020-06-25 Tassilo Horn <tsdh@gnu.org>
+
+ Add NEWS entry for bug-reference auto-setup.
+
+ * etc/NEWS: Add entry for bug-reference auto-setup.
+
+2020-06-25 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change
+
+ * lisp/menu-bar.el (menu-bar-describe-menu): Improve the wording
+ and the help-echo of the new list-recent-keystrokes Help menu
+ item. (Bug#41933)
+
+ * etc/NEWS: Call out the new menu item.
+
+2020-06-25 Tino Calancha <tino.calancha@gmail.com>
+
+ Add help menu entry for view-lossage
+
+ * lisp/menu-bar.el (menu-bar-describe-menu):
+ Add an entry for view-lossage (Bug#41933).
+
+2020-06-25 Alan Mackenzie <acm@muc.de>
+
+ CC Mode. Fix an off by one error. Fixes bug #41809
+
+ * lisp/progmodes/cc-engine.el (c-full-pp-to-literal): Change > to >= (twice).
+
+2020-06-25 Juri Linkov <juri@linkov.net>
+
+ Push action to list of functions in display-buffer-override-next-command
+
+ * lisp/window.el (display-buffer-override-next-command):
+ Push action to 'car' of 'display-buffer-overriding-action'
+ and in exitfun remove action from 'car'.
+ https://lists.gnu.org/archive/html/emacs-devel/2020-06/msg00803.html
+
+2020-06-24 Alan Mackenzie <acm@muc.de>
+
+ Make switch work in AWK Mode. Fixes bug #41923
+
+ lisp/progmodes/cc-langs.el (c-block-stmt-2-kwds): Insert "switch" into the AWK
+ Mode entry.
+ (c-case-kwds): Remove the special entry for AWK Mode.
+
+2020-06-24 Juri Linkov <juri@linkov.net>
+
+ M-n in read-directory-name of vc commands gets project dirs (bug#41821)
+
+ * lisp/progmodes/project.el (project-known-roots): New autoloaded function.
+
+ * lisp/vc/vc-hooks.el (vc-known-roots): New function.
+
+ * lisp/vc/vc.el (vc-root-diff, vc-print-root-log):
+ * lisp/vc/vc-dir.el (vc-dir): Use 'vc-known-roots' for default
+ values for read-directory-name.
+
+2020-06-24 Juri Linkov <juri@linkov.net>
+
+ More not-state-changing vc commands can be used from non-file buffers
+
+ * lisp/vc/vc.el (vc-deduce-fileset): Instead of checking for
+ log-view-mode, check for '(not buffer-file-name)' before trying to
+ get the backend for default-directory. Remove the branch that
+ checks for '(not buffer-file-name)' and signals the error because
+ vc-responsible-backend used in previous condition already signals
+ its error. (Bug#41974)
+
+2020-06-23 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix problem in tramp-smb.el
+
+ * lisp/net/tramp-smb.el (tramp-smb-handle-directory-files):
+ Use `directory-file-name'.
+
+ * test/lisp/net/tramp-tests.el (trace): Require it.
+ (tramp--test-instrument-test-case): Print also function traces.
+ (tramp--test-smb-p): New defun.
+ (tramp-test03-file-name-method-rules)
+ (tramp-test05-expand-file-name-relative)
+ (tramp-test21-file-links, tramp--test-windows-nt-or-smb-p)
+ (tramp--test-check-files): Use it.
+
+2020-06-23 David Edmondson <dme@dme.org>
+
+ Fix gnus-cloud-download-all-data return value
+
+ * lisp/gnus/gnus-cloud.el (gnus-cloud-download-data): Return the
+ result of calling `gnus-cloud-update-all' when UPDATE is t, as per the
+ documented behaviour. (Bug#40280)
+
+2020-06-23 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/gnus/gnus.el (gnus): Fix a check to handle native compilation.
+
+2020-06-22 Eli Zaretskii <eliz@gnu.org>
+
+ Minor improvements as followup to recent RGB string-parsing change
+
+ * src/xfaces.c (Finternal_color_values_from_color_spec): Rename to...
+ (Fcolor_values_from_color_spec): ...this. Callers changed.
+ Rename the argument to SPEC and improve the doc string.
+ (parse_color_spec, parse_float_color_comp, parse_hex_color_comp):
+ Improve commentary.
+ (parse_color_spec): Rename the argument S to SPEC.
+
+ * etc/NEWS: Mention 'color-values-from-color-spec'.
+
+2020-06-22 Dmitry Gutov <dgutov@yandex.ru>
+
+ project-switch-to-buffer: Improve Ido compatibility
+
+ * lisp/progmodes/project.el (project-switch-to-buffer):
+ Check that the entry contains a non-nil CDR.
+
+2020-06-22 Dmitry Gutov <dgutov@yandex.ru>
+
+ project-switch-to-buffer: Do not require matching input
+
+ * lisp/progmodes/project.el (project-switch-to-buffer):
+ Do not require matching input, to allow creating buffers as well
+ (bug#41879).
+
+2020-06-22 Mattias Engdegård <mattiase@acm.org>
+
+ Accept lexical lambda in auto-insert-alist
+
+ This bug was exposed by a previous removal of quoting around lambda
+ expressions in autoinsert-tests.el (1ecd350f38ee), which caused some
+ of those tests to fail.
+
+ * lisp/autoinsert.el (auto-insert): Cope with lexical closures.
+
+2020-06-22 Mattias Engdegård <mattiase@acm.org>
+
+ Fix spurious error in beginning-of-defun in pascal-mode (bug#41740)
+
+ * lisp/progmodes/pascal.el (pascal-beg-of-defun):
+ Ignore errors in forward-sexp.
+ * test/lisp/progmodes/pascal-tests.el (pascal-beg-of-defun): New test.
+
+2020-06-22 Mattias Engdegård <mattiase@acm.org>
+
+ Preserve point in pascal-mode completion (bug#41740)
+
+ Failure to do so caused errors in several cases.
+ Reported by Shinichi Sakata.
+
+ * lisp/progmodes/pascal.el (pascal-type-completion)
+ (pascal-completion): Wrap code that may move point in save-excursion.
+ * test/lisp/progmodes/pascal-tests.el: New file.
+
+2020-06-22 Juri Linkov <juri@linkov.net>
+
+ Fix display-buffer-override-next-command to call action only once (bug#39722)
+
+ * lisp/vc/vc-dir.el (vc-dir-bookmark-jump): Don't use save-window-excursion.
+
+ * lisp/window.el (display-buffer-override-next-command): Reset
+ display-buffer-overriding-action after the first buffer display action.
+
+ * lisp/tab-bar.el (switch-to-buffer-other-tab): Don't reuse frame tabs.
+ (other-tab-prefix): Don't reuse frame tabs.
+
+2020-06-22 Juri Linkov <juri@linkov.net>
+
+ New commands other-window-prefix (C-x 4 4) and other-frame-prefix (C-x 5 5)
+
+ * lisp/window.el (other-window-prefix, same-window-prefix): New commands.
+ (ctl-x-4-map): Bind 'C-x 4 4' to 'other-window-prefix'. (Bug#41691)
+
+ * lisp/frame.el (other-frame-prefix): New command.
+ (ctl-x-5-map): Bind 'C-x 5 5' to 'other-frame-prefix'.
+
+2020-06-22 Theodor Thornhill <theo@thornhill.no>
+
+ Forward declare eshell-buffer-name in project-eshell
+
+ * lisp/progmodes/project.el: Forward declare 'eshell-buffer-name' so
+ that 'project-eshell' can use dynamically scoping with it.
+
+2020-06-22 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savahnna/master' into dev
+
+2020-06-22 Andrea Corallo <akrl@sdf.org>
+
+ Two `load-history' eln related fixes.
+
+ * src/lread.c (Fload): Fix `load-history' filling for elns non in
+ root lisp-dir.
+
+ * lisp/startup.el (command-line): Fix `load-history' fixup
+ algorithm for eln files.
+
+2020-06-22 Andrea Corallo <akrl@sdf.org>
+
+ ;* src/comp.c (define_maybe_gc_or_quit): Fix a comment.
+
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Confine gcc optim level in [0, 3].
+
+2020-06-22 Andrea Corallo <akrl@sdf.org>
+
+ Handle correctly pure delaration specifier.
+
+ * lisp/emacs-lisp/comp.el (comp-func): New slot 'pure'.
+ (comp-spill-decl-spec): New function.
+ (comp-spill-speed): Rework to use the later.
+ (comp-spill-lap-function, comp-intern-func-in-ctxt): Spill pure
+ decl value.
+ (comp-function-optimizable-p): Check in the compiler env too if
+ pure.
+
+2020-06-22 Andrea Corallo <akrl@sdf.org>
+
+ Add a func-arity test for dynamic functions
+
+ * test/src/comp-tests.el (comp-tests-dynamic-arity): New test.
+
+2020-06-22 Andrea Corallo <akrl@sdf.org>
+
+ Do not native compile two functions to allow cc-mode hack
+
+ * lisp/progmodes/cc-langs.el (c-populate-syntax-table): Declare
+ with speed -1.
+
+ * lisp/progmodes/cc-bytecomp.el
+ (cc-bytecomp-compiling-or-loading): Declare with speed -1.
+
+2020-06-22 Andrea Corallo <akrl@sdf.org>
+
+ Add a test for speed -1
+
+ * test/src/comp-tests.el (comp-test-speed--1): New test
+
+ * test/src/comp-test-funcs.el (comp-test-speed--1-f): New
+ function.
+
+2020-06-22 Andrea Corallo <akrl@sdf.org>
+
+ Allow per function speed declaration
+
+ * src/comp.c (COMP_SPEED): Rename.
+ (comp_t): Add 'func_speed' field.
+ (emit_mvar_lval, compile_function): Update for per function speed.
+ (Fcomp__compile_ctxt_to_file): COMP_SPEED renamed.
+
+ * lisp/emacs-lisp/comp.el (comp-speed): Doc update.
+ (comp-func): New 'speed' slot.
+ (comp-spill-speed): New function.
+ (comp-spill-lap-function, comp-intern-func-in-ctxt): Fill 'speed'
+ slot.
+ (comp-spill-lap-function): Gate -1 speed functions for native
+ compilation and emit bytecode instead.
+ (comp-spill-lap): Close over `byte-to-native-plist-environment'.
+ (comp-latch-make-fill): Update for per function speed.
+ (comp-limplify-top-level): Fill speed.
+ (comp-propagate1, comp-call-optim-form-call, comp-call-optim)
+ (comp-dead-code, comp-tco, comp-remove-type-hints): Update for per
+ function speed.
+
+2020-06-22 Andrea Corallo <akrl@sdf.org>
+
+ Execute top level forms in the right lex/dyn scope.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-to-native-top-level): Add
+ 'lexical' slot.
+ (byte-compile-output-file-form): Update for new slot.
+ (byte-compile-file-form-defmumble): Capture scope.
+
+ * lisp/emacs-lisp/comp.el (comp-emit-for-top-level): Specify
+ execution scope.
+
+2020-06-22 Andrea Corallo <andcor03@e112547.nice.arm.com>
+
+ Add some testing for dynamic scope
+
+ * test/src/comp-test-funcs-dyn.el: New file.
+
+ * test/src/comp-tests.el (comp-tests-dynamic-ffuncall): Add
+ new tests.
+
+2020-06-21 Mattias Engdegård <mattiase@acm.org>
+
+ Consolidate #RGB string parsers
+
+ Use a single parser of color strings in the #RGB, rgb:R/G/B and
+ rgbi:R/G/B formats, replacing four existing ones. Previously,
+ error-checking was spotty, handling of the rgbi: format not always
+ present, and normalization of the result was sometimes incorrect.
+
+ * src/dispextern.h: New prototype.
+ * src/xfaces.c (parse_hex_color_comp, parse_float_color_comp)
+ (parse_color_spec, Finternal-color_values_from_color_spec): New functions.
+ * test/src/xfaces-tests.el (xfaces-internal-color-values-from-color-spec):
+ New test.
+ * lisp/term/tty-colors.el (tty-color-standard-values):
+ Use internal-color-values-from-color-spec, replacing old parser.
+ * src/nsterm.m (ns_get_color):
+ * src/w32fns.c (x_to_w32_color):
+ * src/xterm.c (x_parse_color): Use parse_color_spec, replacing old
+ parsers.
+ (HEX_COLOR_NAME_LENGTH): Remove #define.
+
+2020-06-21 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Revert last change in benchmark.el
+
+ For discussion, see the following thread:
+ https://lists.gnu.org/archive/html/emacs-devel/2020-06/msg00791.html
+
+ * lisp/emacs-lisp/benchmark.el (benchmark-run-compiled): Revert to
+ giving byte-compile a form rather than a closure.
+
+2020-06-21 Eli Zaretskii <eliz@gnu.org>
+
+ Improve doc strings of 'project-shell' and 'project-eshell'
+
+ * lisp/progmodes/project.el (project-shell, project-eshell): Doc
+ fixes.
+
+2020-06-21 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Replace some uses of cl-mapcan with mapcan
+
+ * lisp/progmodes/project.el (project-files, project-files):
+ * lisp/progmodes/xref.el (xref-backend-references)
+ (xref--convert-hits):
+ * test/lisp/emacs-lisp/package-tests.el
+ (package-test-strip-version): Replace cl-mapcan with equivalent
+ calls to mapcan.
+
+2020-06-21 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix remaining problems with tramp-crypt.el
+
+ * lisp/net/tramp-compat.el (tramp-compat-make-temp-file):
+ Simplify implementation.
+
+ * lisp/net/tramp-crypt.el (tramp-crypt-handle-delete-file)
+ (tramp-crypt-handle-file-attributes, tramp-crypt-handle-file-system-info)
+ (tramp-crypt-handle-make-directory): Let-bind `tramp-crypt-enabled' to nil.
+
+ * lisp/net/tramp.el (tramp-file-name-for-operation): Fix for operations
+ with two arguments.
+ (tramp-handle-load): Suppress `signal-hook-function' when NOERROR
+ is non-nil.
+
+ * test/lisp/net/tramp-tests.el (tramp-test41-utf8)
+ (tramp-test41-utf8-with-stat, tramp-test41-utf8-with-perl)
+ (tramp-test41-utf8-with-ls): Skip if needed.
+
+2020-06-21 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Evaluate some unnecessarily quoted lambdas
+
+ * lisp/cedet/semantic/complete.el
+ (semantic-displayer-tooltip-max-tags):
+ * lisp/emacs-lisp/benchmark.el (benchmark-run-compiled):
+ * lisp/emacs-lisp/package.el (package--default-summary)
+ (package-menu-filter-by-version):
+ * lisp/eshell/em-pred.el (eshell-pred-file-time):
+ * lisp/progmodes/verilog-mode.el (verilog-auto-lineup)
+ (verilog-auto-reset-widths, verilog-auto-arg-format)
+ (verilog-auto-inst-vector, verilog-auto-inst-template-numbers):
+ * lisp/textmodes/bibtex.el (bibtex-dialect):
+ * test/lisp/autoinsert-tests.el
+ (autoinsert-tests-define-auto-insert-before)
+ (autoinsert-tests-define-auto-insert-after): Remove some unnecessary
+ quoting around anonymous functions.
+
+2020-06-21 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Silence some warnings in tests
+
+ * test/lisp/emacs-lisp/package-tests.el
+ (package-test-suffix-matches): Evaluate lambda.
+ (package-test-list-filter-marked):
+ * test/lisp/vc/vc-tests.el
+ (vc-test--run-maybe-unsupported-function):
+ * test/src/undo-tests.el (undo-test-skip-invalidated-markers):
+ Silence "unused local variable" warnings.
+ * test/lisp/imenu-tests.el (imenu-simple-scan-deftest): Fix
+ docstring. Don't shadow global major-mode.
+
+2020-06-21 Theodor Thornhill <theo@thornhill.no>
+
+ Pop to an existing Eshell buffer by default
+
+ * lisp/progmodes/project.el (project-shell): Improve docstring to
+ include information about an implementation detail.
+
+ * lisp/progmodes/project.el (project-eshell): Modelled after
+ 'project-shell', change default behavior such that we don't create too
+ many eshell buffers by default. Use universal argument to create
+ subsequent buffers.
+
+2020-06-20 Philipp Stephani <phst@google.com>
+
+ Fix a byte-compile warning.
+
+ * lisp/gnus/gnus-cloud.el (gnus-cloud-download-data): Don't use
+ 'mapcar' or effect.
+
+2020-06-20 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change for bug#41619
+
+ * lisp/progmodes/python.el (python-shell-virtualenv-root): Fix
+ last change. (Bug#41619)
+
+2020-06-20 Eli Zaretskii <eliz@gnu.org>
+
+ Documentation followup to the last change
+
+ * doc/emacs/cmdargs.texi (General Variables):
+ * etc/NEWS: Document the COLORTERM environment variable.
+ (Bug#41846)
+
+2020-06-20 Jan Beich <jbeich@FreeBSD.org> (tiny change)
+
+ Add fallback for 24-bit terminal color via COLORTERM=truecolor
+
+ * src/term.c (init_tty): When COLORTERM=truecolor is defined,
+ override setaf/setab/colors terminfo capabilities with 24-bit
+ color support.
+
+ * doc/misc/efaq.texi (Colors on a TTY): Mention the possibility to
+ enable 24-bit color via the COLORTERM environment variable.
+
+ (Bug#41846)
+
+2020-06-20 Eli Zaretskii <eliz@gnu.org>
+
+ Revert "Don't mention non-GNU package archives."
+
+ This reverts commit 5daa7a5fd4aced33a2ae016bde5bb37d1d95edf6.
+ A proper fix will be committed to the emacs-27 branch, and
+ will be later merged to master.
+
+2020-06-20 Andrew Burgess <andrew.burgess@embecosm.com> (tiny change)
+
+ Fix bug with deactivation of mark in 'cua-cancel'
+
+ * lisp/emulation/cua-base.el (cua-cancel): Use 'deactivate-mark'
+ instead of setting 'mark-active' directly.
+
+2020-06-20 Theodor Thornhill <theo@thornhill.no>
+
+ project-shell: Pop to an existing shell buffer by default
+
+ * lisp/progmodes/project.el (project-shell):
+ Pop to an existing shell buffer by default.
+ If there's none, or if universal argument is used, open a subsequent
+ shell buffer and jump to it. Prefix shell buffer name with the base
+ name of project root directory. (Bug#41858)
+
+2020-06-19 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change in doc strings of project.el
+
+ * lisp/progmodes/project.el (project-switch-to-buffer): More accurate
+ doc string.
+
+2020-06-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix various problems in Tramp
+
+ * lisp/net/tramp-compat.el (tramp-temp-name-prefix): Declare.
+ (tramp-compat-make-temp-name):
+ * lisp/net/tramp.el (tramp-make-tramp-temp-name): New defuns.
+
+ * lisp/net/tramp.el (tramp-make-tramp-temp-file):
+ * lisp/net/tramp-sh.el (tramp-find-inline-encoding)
+ (tramp-maybe-open-connection, tramp-get-remote-touch)
+ (tramp-get-remote-chmod-h):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-copy-directory): Use them.
+
+ * lisp/net/tramp-sh.el (tramp-do-file-attributes-with-stat):
+ Simplify shell command. Suppress errors (interpret as nil).
+ (tramp-sh-handle-make-process): Do not visit with
+ `insert-file-contents'. Delete tmp file only if exists.
+ (tramp-send-command-and-read): Suppress `signal-hook-function'
+ when reading expression.
+
+2020-06-19 Eli Zaretskii <eliz@gnu.org>
+
+ Improve doc strings of project.el
+
+ * lisp/progmodes/project.el (project-dired, project-shell)
+ (project-eshell, project-switch-to-buffer, project-kill-buffers)
+ (project-list-file, project--read-project-list)
+ (project--ensure-read-project-list, project--write-project-list)
+ (project--add-to-project-list-front)
+ (project--remove-from-project-list, project-prompt-project-dir)
+ (project-switch-commands, project-switch-project): Fix wording and
+ formatting of doc strings.
+
+2020-06-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix newly introduced errors in Tramp
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-unload-hook):
+ Remove `tramp-gvfs-dbus-event-error' from `dbus-event-error-functions'.
+
+ * lisp/net/tramp.el (tramp-autoload-file-name-handler): Revert patch.
+
+2020-06-19 Andrea Corallo <akrl@sdf.org>
+
+ Add native compiler dynamic scope support
+
+ Add an initial implementation to support dynamic scope. Arg
+ parsing/binding it's done using the existing code in use for
+ bytecode (no ad-hoc code is synthetized for that).
+
+ * src/lisp.h (struct Lisp_Subr): Add lambda_list field.
+ (SUBR_NATIVE_COMPILED_DYNP): New inliner.
+
+ * src/alloc.c (mark_object): Update for Add lambda_list field.
+
+ * src/eval.c (eval_sub, Ffuncall, funcall_lambda): Handle native
+ compiled dynamic scope
+
+ * src/comp.c (declare_lex_function): Rename from declare_function
+ and rework.
+ (declare_function): New function.
+ (make_subr): Handle daynamic scope
+
+ * src/pdumper.c (dump_subr): Update for lambda_list field.
+
+ * lisp/emacs-lisp/comp.el (comp-func): Remove args slot.
+ (comp-func-l, comp-func-d): New classes deriving from `comp-func'.
+ (comp-spill-lap-function): Rework.
+ (comp-prepare-args-for-top-level): New function.
+ (comp-emit-for-top-level, comp-emit-lambda-for-top-level): Make
+ use of `comp-prepare-args-for-top-level'.
+ (comp-limplify-top-level): Use `comp-func-l'.
+ (comp-limplify-function): Emit arg prologue only for dynamic
+ scoped functions.
+ (comp-call-optim-form-call): Use `comp-func-l'.
+ (comp-call-optim, comp-tco): Do not optimize dynamic scoped code.
+
+2020-06-19 Andrii Kolomoiets <andreyk.mad@gmail.com>
+
+ project-switch-to-buffer: Use the "other buffer" as default
+
+ * lisp/progmodes/project.el
+ (project-switch-to-buffer): Pass the "other buffer" as DEF to
+ read-buffer if it belongs to the current project (bug#41879).
+
+2020-06-18 Paul Eggert <eggert@cs.ucla.edu>
+ Tino Calancha <tino.calancha@gmail.com>
+
+ Check AREF and aref_addr subscripts
+
+ * src/lisp.h (gc_asize): Move before first use.
+ (AREF, aref_addr): Check subscripts.
+
+2020-06-18 Mattias Engdegård <mattiase@acm.org>
+
+ Define the dark luminance limit as a named constant
+
+ To make the meaning of the color-dark-p cutoff luminance clear,
+ define it as a named constant. (We no longer use the somewhat
+ obscure 0.6^2.2 definition since it doesn't really make sense
+ to define the limit in gamma-compressed space.)
+
+ * lisp/faces.el (color-luminance-dark-limit): New constant.
+ (color-dark-p): Use color-luminance-dark-limit.
+
+2020-06-18 Michael Albinus <michael.albinus@gmx.de>
+
+ * etc/NEWS: Fix inconsistencies. Add `tramp-crypt-add-directory'.
+
+2020-06-18 Michael Albinus <michael.albinus@gmx.de>
+
+ Some Tramp cleanups, mainly in tramp-crypt.el
+
+ * lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist):
+ Add `add-name-to-file', `make-directory-internal',
+ `make-nearby-temp-file', `temporary-file-directory' and
+ `unhandled-file-name-directory'.
+ (tramp-crypt-file-name-for-operation):
+ Use `tramp-compat-temporary-file-directory'.
+ (tramp-crypt-do-encrypt-or-decrypt-file-name)
+ (tramp-crypt-do-encrypt-or-decrypt-file): Fix syntax error in
+ `tramp-error'.
+
+ * lisp/net/tramp.el (tramp-autoload-file-name-handler):
+ * lisp/net/tramp-rclone.el (tramp-rclone-mounted-p)
+ (tramp-rclone-flush-directory-cache):
+ Use `tramp-compat-temporary-file-directory'.
+
+2020-06-18 Dmitry Gutov <dgutov@yandex.ru>
+
+ Add binding for project-kill-buffers
+
+ * lisp/progmodes/project.el (project-prefix-map):
+ Add binding for project-kill-buffers (bug#41868).
+
+2020-06-18 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Propertize all shr fragment IDs as shr-target-id
+
+ * lisp/net/shr.el (shr-target-id): Add docstring.
+ (shr-descend, shr-tag-a): Display dummy anchor characters as the
+ empty string. Give all relevant 'id' or 'name' fragment identifier
+ attributes the shr-target-id text property. This ensures that
+ cached content, such as tables, retains the property across
+ renders. (Bug#40532)
+
+ * lisp/net/eww.el: (eww-display-html): Adapt shr-target-id property
+ search accordingly.
+
+2020-06-18 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Improve battery.el UPower support
+
+ For discussion, see the following threads:
+ https://lists.gnu.org/archive/html/emacs-devel/2020-01/msg00843.html
+ https://lists.gnu.org/archive/html/emacs-devel/2020-02/msg00042.html
+ https://lists.gnu.org/archive/html/emacs-devel/2020-02/msg00282.html
+
+ * etc/NEWS: Announce that battery-upower is enabled by default.
+
+ * lisp/battery.el (battery-upower-device): Accept both battery and
+ line power device names, or a list thereof (bug#39491).
+ (battery-upower-line-power-device): Remove user option; superseded
+ by battery-upower-device.
+ (battery-upower-subscribe): New user option.
+ (battery-status-function): Check whether a UPower service is
+ provided without activating it.
+ (display-battery-mode): Subscribe to UPower signals when using
+ battery-upower.
+ (battery-upower): Merge data from multiple power sources. Calculate
+ terse battery status %b based on average battery load percentage
+ rather than coarse and often missing BatteryLevel (bug#39491). Add
+ support for average temperature %d.
+
+ (battery-upower-dbus-service)
+ (battery-upower-dbus-interface)
+ (battery-upower-dbus-path)
+ (battery-upower-dbus-device-interface)
+ (battery-upower-dbus-device-path)
+ (battery-upower-device-all-properties): Rename to...
+ (battery-upower-service)
+ (battery-upower-interface)
+ (battery-upower-path)
+ (battery-upower-device-interface)
+ (battery-upower-device-path)
+ (battery--upower-device-properties): ...these, respectively.
+
+ (battery-upower-device-list): Rename to...
+ (battery--upower-devices) ...this. Return a flat list of device
+ names determined by battery-upower-device.
+ (battery-upower-types, battery-upower-states)
+ (battery-upower-device-property, battery-upower-device-autodetect):
+ Remove.
+ (battery--upower-signals): New variable.
+ (battery--upower-signal-handler, battery--upower-props-changed)
+ (battery--upower-unsubscribe, battery--upower-subsribe)
+ (battery--upower-state): New functions.
+
+ * test/lisp/battery-tests.el (battery-upower-state)
+ (battery-upower-state-unknown): New tests.
+
+2020-06-18 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Various battery.el improvements (bug#41808)
+
+ * lisp/battery.el: Mention BSD support in Commentary. Don't load
+ preloaded lisp/emacs-lisp/timer.el.
+ (battery--files): New function.
+ (battery--find-linux-sysfs-batteries): Use it and make fewer
+ syscalls.
+ (battery-status-function): Perform GNU/Linux checks in increasing
+ order of obsolescence: sysfs, ACPI, and then APM. Simplify Darwin
+ check. Add :version tag now that battery-upower is the default.
+ (battery-echo-area-format, battery-mode-line-format): Mention %s.
+ (battery-load-low, battery-load-critical): New faces.
+ (battery-update): Display battery-mode-line-format even if
+ percentage is N/A. Apply faces battery-load-low or
+ battery-load-critical according to the percentage, but append them
+ so they don't override user customizations. Update all mode lines
+ since we are in global-mode-string.
+ (battery-linux-proc-apm-regexp): Mark as obsolete, replacing with...
+ (battery--linux-proc-apm): ...this new rx definition.
+ (battery-linux-proc-apm): Use it. Fix indentation. Simplify.
+ (battery--acpi-rate, battery--acpi-capacity): New rx definitions.
+ (battery-linux-proc-acpi): Use them. Fix pathological whitespace
+ regexps. Simplify.
+ (battery-linux-sysfs): Fix docstring and indentation. Reduce number
+ of file searches. Simplify.
+ (battery-bsd-apm): Fix docstring. Simplify.
+ (battery-pmset): Fix docstring. Simplify ID regexp.
+
+ * lisp/emacs-lisp/rx.el (rx-define): Indent as a defun.
+
+ * test/lisp/battery-tests.el (battery-linux-proc-apm-regexp): Test
+ new battery--linux-proc-apm rx definition.
+ (battery-acpi-rate-regexp, battery-acpi-capacity-regexp): New tests.
+
+2020-06-18 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix and extend format-spec (bug#41758)
+
+ * lisp/format-spec.el: Use lexical-binding. Remove dependence on
+ subr-x.el.
+ (format-spec-make): Clarify docstring.
+ (format-spec--parse-modifiers): Rename to...
+ (format-spec--parse-flags): ...this and simplify. In particular,
+ don't bother parsing :space-pad which is redundant and unused.
+ (format-spec--pad): Remove, replacing with...
+ (format-spec--do-flags): ...this new helper function which performs
+ more of format-spec's supported text manipulation.
+ (format-spec): Autoload. Allow optional argument to take on special
+ values 'ignore' and 'delete' for more control over what happens when
+ a replacement for a format specification isn't provided. Bring back
+ proper support for a precision modifier similar to that of 'format'.
+
+ * lisp/battery.el (battery-format): Rewrite in terms of format-spec.
+ (battery-echo-area-format, battery-mode-line-format): Mention
+ support of format-spec syntax in docstrings.
+
+ * doc/lispref/strings.texi (Custom Format Strings):
+ * etc/NEWS: Document and announce these changes.
+
+ * lisp/dired-aux.el (dired-do-compress-to):
+ * lisp/erc/erc-match.el (erc-log-matches):
+ * lisp/erc/erc.el (erc-update-mode-line-buffer):
+ * lisp/gnus/gnus-sieve.el (gnus-sieve-update):
+ * lisp/gnus/gssapi.el (open-gssapi-stream):
+ * lisp/gnus/mail-source.el (mail-source-fetch-file)
+ (mail-source-fetch-directory, mail-source-fetch-pop)
+ (mail-source-fetch-imap):
+ * lisp/gnus/message.el (message-insert-formatted-citation-line):
+ * lisp/image-dired.el:
+ * lisp/net/eww.el:
+ * lisp/net/imap.el (imap-kerberos4-open, imap-gssapi-open)
+ (imap-shell-open):
+ * lisp/net/network-stream.el (network-stream-open-shell):
+ * lisp/obsolete/tls.el (open-tls-stream):
+ * lisp/textmodes/tex-mode.el:
+ Remove extraneous loads and autoloads of format-spec now that it is
+ autoloaded and simplify its uses where possible.
+
+ * test/lisp/battery-tests.el (battery-format): Test new format-spec
+ support.
+ * test/lisp/format-spec-tests.el (test-format-spec): Rename to...
+ (format-spec) ...this, extending test cases.
+ (test-format-unknown): Rename to...
+ (format-spec-unknown): ...this, extending test cases.
+ (test-format-modifiers): Rename to...
+ (format-spec-flags): ...this.
+ (format-spec-make, format-spec-parse-flags, format-spec-do-flags)
+ (format-spec-do-flags-truncate, format-spec-do-flags-pad)
+ (format-spec-do-flags-chop, format-spec-do-flags-case): New tests.
+
+2020-06-18 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Various dbus.el cleanups (bug#41744)
+
+ * etc/NEWS: Announce removal of aliases obsolete since Emacs 24.3.
+
+ * lisp/net/dbus.el: Remove unneeded dependency on cl-lib.el. Quote
+ function symbols as such.
+ (dbus-ignore-errors): Don't add macro name to font-lock keywords, as
+ emacs-lisp-mode now dynamically fontifies new macro definitions.
+ (dbus-event-error-hooks, dbus-call-method-non-blocking): Remove
+ aliases obsolete since Emacs 24.3.
+ (dbus-register-signal, dbus-escape-as-identifier): Simplify. Use
+ regexp \` and \' in place of ^ and $.
+ (dbus--parse-xml-buffer): New function for libxml2 compatibility.
+ (dbus-introspect-xml): Use it.
+
+ (dbus-string-to-byte-array, dbus-byte-array-to-string)
+ (dbus-unescape-from-identifier, dbus-list-known-names)
+ (dbus-introspect-get-all-nodes, dbus-get-all-properties)
+ (dbus-get-all-managed-objects): Simplify.
+
+ (dbus--introspect-names, dbus--introspect-name): New convenience
+ functions.
+ (dbus-introspect-get-node-names)
+ (dbus-introspect-get-interface-names)
+ (dbus-introspect-get-interface, dbus-introspect-get-method-names)
+ (dbus-introspect-get-method, dbus-introspect-get-signal-names)
+ (dbus-introspect-get-signal, dbus-introspect-get-property-names)
+ (dbus-introspect-get-property)
+ (dbus-introspect-get-annotation-names)
+ (dbus-introspect-get-annotation)
+ (dbus-introspect-get-argument-names, dbus-introspect-get-argument):
+ Use them to DRY.
+
+ * test/lisp/net/dbus-tests.el (dbus-test-all): Quote function
+ symbols as such.
+
+2020-06-18 Tassilo Horn <tsdh@gnu.org>
+
+ ;Fix error in commit dcdf6d7124
+
+2020-06-18 Tassilo Horn <tsdh@gnu.org>
+
+ Make bug-reference auto-setup work in vc-dir or Magit like modes
+
+ * lisp/progmodes/bug-reference.el (bug-reference-try-setup-from-vc):
+ Use default-directory if not in a file-visiting buffer to determine
+ VC URL.
+
+2020-06-18 Tassilo Horn <tsdh@gnu.org>
+
+ Bind default-directory to given DIR.
+
+ Otherwise, "git config branch.<branch>.remote" would return the global
+ default "origin" instead of the actual, project-specific remote name.
+
+ * lisp/vc/vc-git.el (vc-git-dir-extra-headers): Bind default-directory
+ to given DIR.
+
+2020-06-18 Philip K <philip@warpmail.net>
+
+ New command: project-kill-buffers
+
+ * lisp/progmodes/project.el
+ (project-kill-buffers-skip-conditions): New variable.
+ (project--buffer-list): New function.
+ (project-kill-buffers): New command (bug#41868).
+
+2020-06-18 Theodor Thornhill <theo@thornhill.no>
+
+ New command: project-switch-to-buffer
+
+ * lisp/progmodes/project.el (project-switch-to-buffer): New command.
+
+2020-06-18 Theodor Thornhill <theo@thornhill.no>
+
+ Add global bindings for project commands
+
+ * lisp/progmodes/project.el
+ (project-prefix-map): New variable.
+ Add the new keymap to ctl-x-map.
+
+2020-06-18 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix setting project-vc-merge-submodules via .dir-locals.el
+
+ * lisp/progmodes/project.el
+ (project--vc-merge-submodules-p): New function.
+ (project-try-vc, project--vc-list-files): Use it.
+
+2020-06-18 Dmitry Gutov <dgutov@yandex.ru>
+
+ vc-git-dir-extra-headers: Fix recent breakage
+
+ * lisp/vc/vc-git.el (vc-git-dir-extra-headers): Account for
+ 'remote' being set to "" when not found
+ (https://lists.gnu.org/archive/html/emacs-devel/2020-06/msg00582.html).
+ (vc-git-dir-extra-headers): Check the value of remote-url instead.
+
+2020-06-17 Tassilo Horn <tsdh@gnu.org>
+
+ Auto-setup for bug-reference-mode
+
+ Tries to guess suitable bug-reference-bug-regexp and
+ bug-reference-url-format values based on version control URL (in file
+ buffers) and mail information (in Gnus summary and article buffers).
+
+ * lisp/progmodes/bug-reference.el
+ (bug-reference--maybe-setup-from-vc): New defun.
+ (bug-reference-setup-from-vc-alist): New defvar defining setup rules
+ based on version control URL.
+ (bug-reference-try-setup-from-vc): New defun using above defvar.
+ (bug-reference--maybe-setup-from-mail): New defun.
+ (bug-reference-setup-from-mail-alist): New defvar defining setup rules
+ based on mail/newsgroups and header values.
+ (bug-reference-try-setup-from-gnus): New defun using above defvar.
+ (bug-reference--try-setup-gnus-article): New defun.
+ (bug-reference--run-auto-setup): New defun.
+ (bug-reference-mode): Call bug-reference--run-auto-setup as
+ :after-hook.
+ (bug-reference-prog-mode): Call bug-reference--run-auto-setup as
+ :after-hook.
+
+2020-06-17 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 229995ba2c (origin/emacs-27) Fix some Texinfo markup
+ 01e86b9fdf Fix recentf typo in Emacs manual
+ cd4f75bb86 Rename default function to next-error-buffer-unnavigated-c...
+ 1dff0a8949 * lisp/image-mode.el (image-toggle-display-image): Fix fit...
+ a71d1787f1 * doc/misc/tramp.texi (Predefined connection information):...
+ 079b0dc430 Delete, don't kill, dir dir fragments in icomplete-fido-ba...
+ 6cdecc2659 Revert markup change in with-coding-priority docs
+ 22f4fba8a9 * lisp/emulation/cua-rect.el (cua--rectangle-region-insert...
+ 6b9eac6759 * lisp/simple.el (shell-command-on-region): Fix docstring.
+ 43ad7dc1af Clean up D-Bus documentation (bug#41744)
+ c43e5ed60d * lisp/image-mode.el (image-transform-original): New comma...
+ 6eb18a950d Move tab-bar and tab-line faces to faces.el (part of bug#4...
+
+ # Conflicts:
+ # etc/NEWS
+ # lisp/simple.el
+
+2020-06-17 Juri Linkov <juri@linkov.net>
+
+ * lisp/dired-aux.el (dired-vc-deduce-fileset): Add autoload cookie.
+
+2020-06-17 Dmitry Gutov <dgutov@yandex.ru>
+
+ Bump the project.el package version
+
+ * lisp/progmodes/project.el: Bump the package version.
+
+2020-06-17 Dmitry Gutov <dgutov@yandex.ru>
+
+ Change the key for project-find-regexp
+
+ * lisp/progmodes/project.el (project-switch-commands):
+ Change the key for 'project-find-regexp' to 'g', which seems to be
+ the consensus.
+
+2020-06-17 Dmitry Gutov <dgutov@yandex.ru>
+
+ Make project file name completion adhere to customization
+
+ * lisp/progmodes/project.el (project-find-file-in):
+ Bind completion-ignore-case to the value of
+ read-file-name-completion-ignore-case (bug#41902).
+
+2020-06-16 David Edmondson <dme@dme.org>
+
+ gnus-cloud: Improve cloud sync
+
+ After replaying a set of actions downloaded by gnus-cloud, persist the
+ highest sequence number seen as the local `gnus-cloud-sequence'
+ number, in order that a future download will not unnecessarily replay
+ previously seen actions and any future uploads from this emacs
+ instance use a higher sequence number than that downloaded.
+
+ Remove the test on whether individual newsrc entries are older than
+ the current time, as that is always going to be the case.
+
+2020-06-15 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix some Tramp problems seen during tests
+
+ * lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist):
+ Add `access-file'.
+ (tramp-crypt-file-name-for-operation): Rewrite. Take second
+ argument into account.
+ (tramp-crypt-file-name-handler): Use it.
+ (tramp-crypt-send-command): Set buffer multibyte (but utf8 files
+ still don't work).
+ (tramp-crypt-handle-access-file): New defun.
+ (tramp-crypt-do-copy-or-rename-file): Short track if both files
+ are on a crypted remote dir.
+
+ * lisp/net/tramp.el (file-notify-rm-watch): Declare.
+ (tramp-inhibit-progress-reporter): New defvar.
+ (tramp-message): Display message only if not suppressed by
+ progress reporter.
+ (with-tramp-progress-reporter): Suppress concurrent progress
+ reporter messages.
+ (tramp-file-notify-process-sentinel): Simplify.
+
+2020-06-15 Tassilo Horn <tsdh@gnu.org>
+
+ Use vc-git-repository-url in vc-git-dir-extra-headers
+
+ * lisp/vc/vc-git.el (vc-git-dir-extra-headers): Use
+ vc-git-repository-url for getting the remote's URL.
+
+2020-06-15 Tassilo Horn <tsdh@gnu.org>
+
+ Add optional remote-name argument to VC repository-url command
+
+ * lisp/vc/vc.el: Document new remote-name argument of VC
+ repository-url command.
+ * lisp/vc/vc-git.el (vc-git-repository-url): Add and use new arg.
+ * lisp/vc/vc-hg.el (vc-hg-repository-url): Add and use new arg.
+ * lisp/vc/vc-bzr.el (vc-bzr-repository-url): Add new arg but ignore
+ it.
+ * lisp/vc/vc-svn.el (vc-svn-repository-url): Add new arg but ignore
+ it.
+
+2020-06-14 Tassilo Horn <tsdh@gnu.org>
+
+ Add new VC command `repository-url'
+
+ * lisp/vc/vc.el: Document repository-url command.
+ * lisp/vc/vc-bzr.el (vc-bzr-repository-url): New defun.
+ * lisp/vc/vc-git.el (vc-git-repository-url): New defun.
+ * lisp/vc/vc-hg.el (vc-hg-repository-url): New defun.
+ * lisp/vc/vc-svn.el (vc-svn-repository-url): New defun.
+
+2020-06-14 Philipp Stephani <phst@google.com>
+
+ Band-aid for edebugging generator bodies (Bug#40434).
+
+ Edebug doesn't support them well. Rather than trying to fix Edebug,
+ disable instrumentation for now to prevent annoying bugs.
+
+ * lisp/emacs-lisp/generator.el (iter-defun, iter-lambda, iter-make)
+ (iter-do): Don't attempt to instrument bodies that are mangled by the
+ CPS transformer.
+
+ * test/lisp/emacs-lisp/generator-tests.el
+ (generator-tests-edebug): New regression test.
+
+2020-06-14 Philipp Stephani <phst@google.com>
+
+ Ensure that getters and setters can be edebugged at the same time.
+
+ It's necessary to add a name suffix to setters defined with
+ 'gv-define-setter' so that Edebug can distinguish between the getter
+ and the setter (Bug#41853).
+
+ * lisp/emacs-lisp/gv.el (gv-define-setter): Add a name suffix to
+ setter definitions.
+
+ * test/lisp/emacs-lisp/gv-tests.el (gv-setter-edebug): New regression
+ test.
+
+2020-06-14 Michael Albinus <michael.albinus@gmx.de>
+
+ Rearrange detecting remote uid and gid in Tramp
+
+ * lisp/net/tramp-adb.el (tramp-adb-file-name-handler-alist):
+ * lisp/net/tramp-archive.el (tramp-archive-file-name-handler-alist):
+ * lisp/net/tramp-rclone.el (tramp-rclone-file-name-handler-alist):
+ * lisp/net/tramp-smb.el (tramp-smb-file-name-handler-alist):
+ Add `tramp-get-remote-gid' and 'tramp-get-remote-uid'.
+
+ * lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist):
+ Add `file-ownership-preserved-p'.
+ (tramp-crypt-add-directory): Check, that NAME is not quoted.
+ (tramp-crypt-handle-file-ownership-preserved-p): New defun.
+ (tramp-crypt-handle-insert-directory): Fix docstring.
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist):
+ Add `tramp-get-remote-gid' and 'tramp-get-remote-uid'.
+ (tramp-gvfs-handle-file-readable-p): Call `tramp-get-remote-uid'.
+ (tramp-gvfs-handle-get-remote-uid)
+ (tramp-gvfs-handle-get-remote-gid): Rename from
+ `tramp-gvfs-get-remote-{uid,gid}'. Do not cache result.
+ (tramp-gvfs-maybe-open-connection): No special handling for remote
+ uid and gid.
+
+ * lisp/net/tramp-sh.el (tramp-sh-file-name-handler-alist):
+ Add `tramp-get-remote-gid' and 'tramp-get-remote-uid'.
+ (tramp-sh-handle-get-remote-uid, tramp-sh-handle-get-remote-gid):
+ Rename from `tramp-get-remote-{uid,gid}'. Do not cache result.
+ (tramp-sh-handle-file-ownership-preserved-p): Distinguish by GROUP
+ when caching.
+
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-file-name-handler-alist):
+ Add `tramp-get-remote-gid' and 'tramp-get-remote-uid'.
+ (tramp-sudoedit-handle-get-remote-uid)
+ (tramp-sudoedit-handle-get-remote-gid): Rename from
+ `tramp-sudoedit-get-remote-{uid,gid}'. Do not cache result.
+ (tramp-sudoedit-handle-set-file-uid-gid)
+ (tramp-sudoedit-handle-write-region): Call `tramp-get-remote-uid'
+ and `tramp-get-remote-gid'.
+ (tramp-sudoedit-maybe-open-connection): No special handling for
+ remote uid and gid.
+
+ * lisp/net/tramp.el (tramp-file-name-for-operation):
+ Add `tramp-get-remote-gid' and 'tramp-get-remote-uid'.
+ (tramp-handle-write-region, tramp-check-cached-permissions):
+ Call `tramp-get-remote-uid' and `tramp-get-remote-gid'.
+ (tramp-get-remote-uid, tramp-get-remote-gid): New defuns.
+ (tramp-local-host-p): Simplify `tramp-get-remote-uid' call.
+
+ * test/lisp/net/tramp-tests.el (tramp-test17-dired-with-wildcards)
+ Skip if needed.
+
+2020-06-14 Michael R. Mauger <michael@mauger.com>
+
+ * lisp/progmodes/sql.el (sql-add-product): Re-correct argument
+ spec. Previous change was due to my mistake; I have
+ resolved back to the prior behavior (Bug#39960).
+ * test/lisp/progmodes/sql-tests.el (sql-test-add-product): Added
+ test to insure I don't make the same mistake again.
+
+2020-06-13 Glenn Morris <rgm@gnu.org>
+
+ Tag a test as unstable
+
+ * test/lisp/calendar/lunar-tests.el (lunar-test-phase-list):
+ Mark as unstable. Eg fails on hydra.nixos.org.
+
+2020-06-13 Andrea Corallo <akrl@sdf.org>
+
+ Implement 'maybe_gc_or_quit' to allow correct GC in compiled Lisp.
+
+ Implement the backend side of 'maybe_gc_or_quit' so that every time a
+ call to it is emitted we render it accordingly. This allow GC to
+ kicks in during long loops in Lisp code.
+
+ * src/comp.c (comp_t): Add 'maybe_gc_or_quit' field.
+ (helper_link_table): Add 'maybe_gc', 'maybe_quit'.
+ (emit_maybe_gc_or_quit): New function.
+ (declare_runtime_imported_funcs): Import 'maybe_gc', 'maybe_quit'
+ functions.
+ (define_maybe_gc_or_quit): New function.
+ (Fcomp__init_ctxt): Register emitter.
+ (Fcomp__compile_ctxt_to_file): Call 'define_maybe_gc_or_quit'.
+ (syms_of_comp): Define Qcomp_maybe_gc_or_quit.
+
+2020-06-13 Andrea Corallo <akrl@sdf.org>
+
+ Introduce latches
+
+ Define a new kind of basic block 'latch' to close over loops. Its
+ purpose is for now to emit calls to `comp-maybe-gc-or-quit' but in
+ future will be useful for the loop optimizer to exploit unboxes.
+
+ * lisp/emacs-lisp/comp.el (comp-block): New base class.
+ (comp-block-lap): New class for LAP derived basic blocks.
+ (comp-latch): New class.
+ (comp-bb-maybe-add, comp-make-curr-block, comp-emit-handler)
+ (comp-emit-switch, comp-emit-switch, comp-limplify-top-level)
+ (comp-addr-to-bb-name, comp-limplify-block)
+ (comp-limplify-function): Update logic for new bb objects
+ arrangement.
+ (comp-latch-make-fill): New function.
+ (comp-emit-uncond-jump, comp-emit-cond-jump): Update to emit
+ latches.
+ (comp-new-block-sym): Add a postfix paramenter.
+
+2020-06-13 Andrea Corallo <akrl@sdf.org>
+
+ Fix const qualifier warnings
+
+ * src/lisp.h (struct Lisp_Subr): Remove const qualifier from
+ 'native_c_name'.
+
+ * src/alloc.c (cleanup_vector): Cast to discard const qualifier.
+
+2020-06-13 Philip K <philip@warpmail.net>
+
+ Mark python-shell-virtualenv-root as safe for directories
+
+ * lisp/progmodes/python.el (python-shell-virtualenv-root):
+ Require a directory name. (Bug#41619)
+
+2020-06-13 Konstantin Kharlamov <Hi-Angel@yandex.ru>
+
+ Highlight typed variables in Python
+
+ * lisp/progmodes/python.el
+ (python-font-lock-keywords-maximum-decoration): Recognize
+ typed variables like "foo: int = 1" as well. (Bug#41684)
+
+2020-06-13 Andrea Corallo <akrl@sdf.org>
+
+ * src/alloc.c (cleanup_vector): Fix --enable-check-lisp-object-type build.
+
+2020-06-12 Michael Albinus <michael.albinus@gmx.de>
+
+ Further fixes while testing tramp-crypt
+
+ * doc/misc/tramp.texi (External methods): Remove experimental note
+ for rclone.
+ (Keeping files encrypted): Mark file encryption as experimental.
+
+ * lisp/net/tramp-adb.el (tramp-adb-file-name-handler-alist):
+ Use `tramp-handle-file-truename'.
+ (tramp-adb-handle-file-truename): Remove.
+
+ * lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist):
+ Add `file-writable-p'.
+ (tramp-crypt-send-command): Return t if no error.
+ (tramp-crypt-do-encrypt-or-decrypt-file-name)
+ (tramp-crypt-do-encrypt-or-decrypt-file): Raise an error if it fails.
+ (tramp-crypt-do-copy-or-rename-file): Flush file properties also
+ when copying a directory.
+ (tramp-crypt-handle-file-writable-p): New defun.
+ (tramp-crypt-handle-insert-directory): Check for library
+ `text-property-search'.
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-set-file-uid-gid):
+ Rename from `tramp-gvfs-set-file-uid-gid'.
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-file-truename):
+ Use `tramp-handle-file-truename' as fallback.
+
+ * lisp/net/tramp.el (tramp-handle-file-truename):
+ Let-bind `tramp-crypt-enabled' to nil.
+ (tramp-handle-write-region): Set also file ownership.
+
+ * test/lisp/net/tramp-tests.el (tramp-test17-insert-directory):
+ Skip if needed.
+
+2020-06-12 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Derive gnus-edit-form-mode from lisp-data-mode, fix mode map
+
+ * lisp/gnus/gnus-eform.el (gnus-edit-form-mode): Derive from
+ lisp-data-mode, which can be handy for users who have turned on things
+ like paredit for lisp-data-mode.
+ (gnus-edit-form-mode-map): Put creation of the map inside the defvar.
+
+2020-06-11 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savahnna/master' into HEAD
+
+2020-06-11 Andrea Corallo <akrl@sdf.org>
+
+ Fix memory leak when native compiled function is collected
+
+ * src/alloc.c (cleanup_vector): Handle native compiled
+ functions.
+
+2020-06-11 Andrea Corallo <akrl@sdf.org>
+
+ Fix recursive load for non cons hashed 'data_ephemeral_vec' content
+
+ Removing `Vcomp_sym_subr_c_name_h' all c_name functions are GC
+ markable only through 'data_ephemeral_vec'. A recursive load must not
+ override its content otherwise a previously activated load will have
+ the original content collected before it's used.
+
+ * src/comp.h (struct Lisp_Native_Comp_Unit): Add 'load_ongoing'
+ field.
+
+ * src/comp.c (unset_cu_load_ongoing): New function.
+ (load_comp_unit): Update logic to detect and handle recursive
+ loads.
+
+2020-06-11 Andrea Corallo <akrl@sdf.org>
+
+ Remove `Vcomp_sym_subr_c_name_h'
+
+ Given there's no more unique relation symbol-name -> c-name remove
+ `Vcomp_sym_subr_c_name_h' and store the c_name directly in struct
+ Lisp_Subr. The old approach would have failed dumping two functions
+ with the same symbol-name.
+
+ * src/lisp.h (struct Lisp_Subr): Add 'native_c_name' field.
+
+ * src/pdumper.c (dump_subr): Update hash + dump 'native_c_name'.
+ (dump_cold_native_subr): dump 'native_c_name'.
+ (dump_do_dump_relocation): Update logic for reviving using
+ 'native_c_name'.
+
+ * src/comp.c (make_subr): Update for 'native_c_name' field.
+ (Fcomp__register_lambda, Fcomp__register_subr): Clean-up code for
+ 'Vcomp_sym_subr_c_name_h' removal.
+ (syms_of_comp): Remove 'Vcomp_sym_subr_c_name_h'.
+
+2020-06-10 Mattias Engdegård <mattiase@acm.org>
+
+ Improved light/dark colour predicate (bug#41544)
+
+ Add a predicate, color-dark-p, for deciding whether a colour is more
+ readable with black or white as contrast. It has experimentally been
+ shown to be more accurate and robust than the various methods
+ currently employed.
+
+ The new predicate compares the relative luminance of the colour to an
+ empirically determined cut-off value, and it seems to get it right in
+ almost all cases, with no value leading to outright bad results.
+
+ * lisp/faces.el (readable-foreground-color): Use color-dark-p.
+ (color-dark-p): New function.
+ * lisp/facemenu.el (list-colors-print): Use readable-foreground-color,
+ improving readability of list-colors-display.
+ * lisp/textmodes/css-mode.el (css--contrasty-color): Remove.
+ (css--fontify-region): Use readable-foreground-color.
+
+2020-06-10 Michael Albinus <michael.albinus@gmx.de>
+
+ Further tramp-crypt implementation and documentation
+
+ * doc/misc/tramp.texi (Top, Configuration): Insert section
+ `Keeping files encrypted' in menu.
+ (Keeping files encrypted): New node.
+
+ * lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist):
+ Add `tramp-set-file-uid-gid'.
+ (tramp-crypt-maybe-open-connection): Simplify.
+ (tramp-crypt-do-encrypt-or-decrypt-file): Use `binary' coding system.
+ (tramp-crypt-handle-set-file-uid-gid): New defun.
+
+ * test/lisp/net/tramp-tests.el (tramp-test09-insert-file-contents):
+ Adapt test.
+
+2020-06-10 Philipp Stephani <phst@google.com>
+
+ Slightly improve commit 73be4d1ed5b190bd93e9bad6aebe43d0dea0d7d3.
+
+ * lisp/emacs-lisp/cl-macs.el (cl-lambda-list, cl-lambda-list1)
+ (cl-macro-list, cl-macro-list1): Use exactly the same specification as
+ for &optional (sans the third optional list element).
+
+2020-06-10 Philipp Stephani <phst@google.com>
+
+ Allow destructuring in &aux sections when using edebug (Bug#40431)
+
+ * lisp/emacs-lisp/cl-macs.el (cl-lambda-list, cl-lambda-list1)
+ (cl-macro-list, cl-macro-list1): Allow arbitrary 'cl-lambda'
+ arguments in the &aux section.
+
+ * test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs-aux-edebug): New
+ regression test.
+
+2020-06-10 Andrea Corallo <akrl@sdf.org>
+
+ Remove unused 'helper_save_window_excursion'
+
+ * src/comp.c (helper_unwind_protect): Remove definition and
+ declaration.
+
+2020-06-10 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ Copy suffixes passed to 'openp' to avoid GC crashes. Fixes bug#41755
+
+ In openp_add_middle_dir_to_suffixes we build a heap-based list from
+ the passed suffixes. It is crucial that we don't create a heap-based
+ cons that points to a stack-based list.
+
+ * src/lread.c (openp_add_middle_dir_to_suffixes): Copy suffixes when
+ building a list of middle-dirs and suffixes.
+
+2020-06-09 Simen Heggestøyl <simenheg@gmail.com>
+
+ Save project list as lisp data
+
+ Save the project list file as lisp data instead of line separated
+ strings to make it more extendable in the future.
+
+ * lisp/progmodes/project.el (project--read-project-list)
+ (project--write-project-list, project--add-to-project-list-front)
+ (project--remove-from-project-list): Adjust to `project--list' now
+ being an alist.
+
+2020-06-09 Alan Mackenzie <acm@muc.de>
+
+ Orthographical amendments to commit 145aab0672ae259736ee9230f8e0ff4effa5f4fd
+
+ * etc/NEWS: Correct the spelling of CC Mode.
+
+ * lisp/progmodes/cc-fonts.el (doxygen-font-lock-doc-comments): Replace curly
+ quotes in comments by ASCII ones.
+
+2020-06-09 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ * Fix usage of cl-destructuring-bind in package--delete-directory.
+
+ * lisp/emacs-lisp/package.el (package--delete-directory): Fix usage of
+ cl-destructuring-bind.
+
+2020-06-09 Michael Albinus <michael.albinus@gmx.de>
+
+ Continue implementation of tramp-crypt.el
+
+ * lisp/net/tramp-crypt.el (tramp-crypt-do-encrypt-or-decrypt-file):
+ Add leading "/" to infile.
+ (tramp-crypt-add-directory): Fix docstring. Expand NAME.
+ (tramp-crypt-remove-directory)
+ (tramp-crypt-handle-file-name-all-completions)
+ (tramp-crypt-handle-set-file-times): New defuns.
+ (tramp-crypt-handle-file-executable-p)
+ (tramp-crypt-handle-file-readable-p)
+ (tramp-crypt-handle-file-system-info)
+ (tramp-crypt-handle-set-file-modes): Fix implementation.
+
+ * test/lisp/net/tramp-tests.el: Adapt call convention
+ for (tramp--test-crypt-p).
+
+2020-06-09 Juri Linkov <juri@linkov.net>
+
+ * lisp/simple.el (shell-command-on-region): Handle nil replace on rectangles.
+
+ When 'region-noncontiguous-p' is non-nil (rectangular region)
+ but 'replace' is nil, pop up the shell output buffer (bug#41440).
+ When 'replace' is non-nil, trim the trailing newline.
+
+2020-06-08 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.h (struct Lisp_Native_Comp_Unit): Fix missing GCALIGNED_STRUCT.
+
+2020-06-08 Andrea Corallo <akrl@sdf.org>
+
+ Rename lambda_gc_guard -> lambda_gc_guard_h
+
+ * src/comp.h (struct Lisp_Native_Comp_Unit): Rename
+ lambda_gc_guard -> lambda_gc_guard_h
+
+ * src/pdumper.c (dump_do_dump_relocation): Likewise.
+
+ * src/comp.c (check_comp_unit_relocs, Fcomp__register_lambda)
+ (Fnative_elisp_load): Likewise.
+
+2020-06-08 Andrea Corallo <andcor03@e112547.nice.arm.com>
+
+ * Fix load logic for the reloading CU case (bug#41754)
+
+ * src/comp.c (load_comp_unit): When swapping the compilation unit
+ abandoning the new one for the original do not forget to set its
+ loaded_once field to true because is in use by
+ `comp--register-lambda'.
+ (Fcomp__register_lambda): Add sanity a check to spot
+ early if we are trying to load the same lambda twice.
+
+2020-06-08 Andrea Corallo <andcor03@e112547.nice.arm.com>
+
+ * Move final log after containers has been finalized
+
+ * lisp/emacs-lisp/comp.el (comp-final): Remove function log.
+ (comp-compile-ctxt-to-file): Add function log.
+
+2020-06-08 Andrea Corallo <andcor03@e112547.nice.arm.com>
+
+ * src/pdumper.c (dump_do_dump_relocation): Fix 'lambda_gc_guard' fill value.
+
+ Given 'lambda_gc_guard' is in use for sanity checking fill it with t
+ as value.
+
+2020-06-08 Mattias Engdegård <mattiase@acm.org>
+
+ More robust NS hex colour string parsing
+
+ Invalid arguments to color-values, such as "#abcdefg" or "#1234", or
+ valid ones like "#111222333", should not yield nonsense values.
+
+ * src/nsterm.m (ns_get_color):
+ Only accept "#RGB" strings with 1-4 digits per components, equal number
+ of digits each, and no trailing characters. Parse 12-bit colours
+ correctly.
+
+2020-06-08 Michael Albinus <michael.albinus@gmx.de>
+
+ Add autoload problem in tramp-crypt.el.
+
+ * lisp/net/tramp-crypt.el (tramp-crypt-encfs-config):
+ Add ;;;###tramp-autoload cookie.
+ (tramp-crypt-directories): Move it up.
+ (tramp-crypt-file-name-p): Move it up. Add ;;;###tramp-autoload
+ cookie. Make it a defsubst.
+
+ * test/lisp/net/tramp-tests.el (tramp-crypt): Do not require.
+
+2020-06-07 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into dev
+
+2020-06-07 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in lunar.el and add tests
+
+ * lisp/calendar/lunar.el: Use lexical-binding.
+ (lunar-phases, diary-lunar-phases): Silence byte-compiler.
+ * test/lisp/calendar/lunar-tests.el: New file.
+
+2020-06-07 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Add `make-byte-code'.
+
+ `make-byte-code' wraps `vector' doing some sanity check on the input
+ arguments. `vector' is in side-effect-and-error-free-fns so add
+ `make-byte-code' to side-effect-free-fns.
+
+2020-06-07 Glenn Morris <rgm@gnu.org>
+
+ * test/lisp/net/tramp-tests.el: tramp-crypt-file-name-p not autoloaded.
+
+2020-06-07 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-function-optimizable -> comp-function-optimizable-p
+
+ * lisp/emacs-lisp/comp.el (comp-function-optimizable): Rename into
+ 'comp-function-optimizable-p'.
+ (comp-function-call-maybe-remove): Use the new name.
+
+2020-06-07 Andrea Corallo <akrl@sdf.org>
+
+ Fix comp-call-optim-form-call for null `callee'
+
+ * lisp/emacs-lisp/comp.el (comp-call-optim-form-call): Guard
+ agains null `calle'.
+
+2020-06-07 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 35661ef943 (origin/emacs-27) Fix typo in "(elisp) Type Keywords"
+ 1af0e95fec Gnus nnir-summary-line-format has no effect
+ dd366b5d3b Improve documentation of 'window-text-pixel-size'
+ fbd49f969e * src/xdisp.c (Fwindow_text_pixel_size): Doc fix. (Bug#41...
+ d8593fd19f Minor improvements to EDE and EIEIO manuals
+ 3916e63f9e Have Fido mode also imitate Ido mode in ignore-case options
+ cc35b197c7 Update package-menu-quick-help
+ bf09106256 Improve documentation of 'sort-subr'
+ 73749efa13 Update Ukrainian transliteration
+ 30a7ee505a Fix Arabic shaping when eww/shr fill the text to be rendered
+ 7d323f07c0 Silence some byte-compiler warnings in tests
+ cf473e742f * test/lisp/battery-tests.el: New file.
+ b07e3b1d97 Improve format-spec documentation (bug#41571)
+
+ # Conflicts:
+ # test/lisp/emacs-lisp/package-tests.el
+
+2020-06-07 Alan Mackenzie <acm@muc.de>
+
+ * lisp/progmodes/js.el (js-mode): Remove second call to c-init-language-vars
+
+ This spurious second call fouled up already set configuration variables.
+ Fixes bug #41649.
+
+2020-06-07 Andrea Corallo <akrl@sdf.org>
+
+ Improve propagate pass
+
+ As function folding can generate 'setimm' insns handle them in the
+ `comp-propagate-insn'.
+
+ * lisp/emacs-lisp/comp.el (comp-propagate-insn): Handle 'setimm'
+ insn.
+
+2020-06-07 Michael Albinus <michael.albinus@gmx.de>
+
+ Add file encryption to Tramp
+
+ * lisp/net/tramp-crypt.el: New file.
+
+ * lisp/net/tramp.el (tramp-run-real-handler):
+ Add `tramp-crypt-file-name-handler'.
+ (tramp-register-file-name-handlers):
+ Call `tramp-register-crypt-file-name-handler'.
+ (tramp-handle-insert-file-contents, tramp-local-host-p): Check for
+ `tramp-crypt-enabled'
+
+ * test/lisp/net/tramp-tests.el (tramp--test-crypt-p): New defun.
+ (tramp-test24-file-acl, tramp-test25-file-selinux)
+ (tramp-test28-process-file, tramp-test29-start-file-process)
+ (tramp-test30-make-process, tramp-test31-interrupt-process)
+ (tramp-test32-shell-command)
+ (tramp-test32-shell-command-dont-erase-buffer)
+ (tramp-test33-environment-variables)
+ (tramp-test33-environment-variables-and-port-numbers)
+ (tramp-test34-explicit-shell-file-name, tramp-test35-exec-path)
+ (tramp-test35-remote-path, tramp-test36-vc-registered)
+ (tramp--test-check-files, tramp-test43-asynchronous-requests): Use it.
+
+2020-06-07 Michael Albinus <michael.albinus@gmx.de>
+
+ Tramp code cleanup
+
+ * lisp/net/tramp-cache.el (tramp-get-connection-property): Cleanup.
+
+ * lisp/net/tramp-cmds.el (tramp-cleanup-all-connections): Delete also
+ connection processes.
+
+ * lisp/net/tramp-sh.el (tramp-set-remote-path): Cache 4096 even if
+ PIPE_BUF doesn't exist.
+
+2020-06-07 Mattias Engdegård <mattiase@acm.org>
+
+ Use 65535 as color-values scale value in the NS backend
+
+ * src/nsfns.m (Fxw_color_values): Scale with 65535 instead of 65280, for
+ uniformity with other backends.
+ * lisp/faces.el (color-values): Update doc string.
+ * doc/lispref/frames.texi (Color Names): Update examples.
+
+2020-06-07 Andrea Corallo <akrl@sdf.org>
+
+ Optimize optimizable variables
+
+ * lisp/emacs-lisp/comp.el (comp-symbol-values-optimizable): New
+ defconst.
+ (comp-function-call-maybe-remove): New logic to to remove
+ unnecessary `symbol-value' calls.
+
+2020-06-07 Juri Linkov <juri@linkov.net>
+
+ The key prefix 'C-x t t' displays next command buffer in a new tab (bug#41691)
+
+ * lisp/tab-bar.el (other-tab-prefix): New command.
+ (tab-prefix-map): Bind key 'C-x t t' to other-tab-prefix.
+
+ * lisp/windmove.el (windmove-display-in-direction):
+ Use display-buffer-override-next-command.
+
+ * lisp/window.el (display-buffer-override-next-command):
+ New function refactored from windmove-display-in-direction.
+
+2020-06-06 Andrea Corallo <akrl@sdf.org>
+
+ Mitigate possible speed 3 miss-optimization
+
+ Do not perform trampoline optimization at speed 3 on function if their
+ name is not unique inside the compilation unit. Note that the
+ function can still be redefined in any other way therefore this is a
+ mitigation.
+
+ * lisp/emacs-lisp/comp.el (comp-func-unique-in-cu-p): New
+ predicate.
+ (comp-call-optim-form-call): Perform trampoline optimization
+ for named functions only if they are unique within the current
+ compilation unit.
+
+2020-06-06 Andrea Corallo <akrl@sdf.org>
+
+ Allow for optimizing anonymous lambdas in call-optim
+
+ * lisp/emacs-lisp/comp.el (comp-func-in-unit): New function.
+ (comp-call-optim-form-call): Update logic for optimizing
+ anonymous lambdas.
+
+2020-06-06 Andrea Corallo <akrl@sdf.org>
+
+ Clean-up unnecessary lisp_X context definition
+
+ * src/comp.c (Fcomp__init_ctxt, comp_t): Remove lisp_X
+ definition as is used only locally.
+
+2020-06-06 Andrea Corallo <akrl@sdf.org>
+
+ Change 'direct-call' 'direct-callref' LIMPLE ops sematinc
+
+ Is cleaner to have the function c-name as first argument of
+ 'direct-call' 'direct-callref'. This is preparatory to anonymous
+ lambdas optimization.
+
+ * lisp/emacs-lisp/comp.el (comp-propagate-insn): Use c-name when
+ gathering the comp-func definition for direct calls.
+ (comp-call-optim-form-call): Add put c-name as first argument of
+ direct-call direct-callref when optimizing.
+
+ * src/comp.c (emit_call): Update logic for having c-name as
+ first arg of direct calls.
+ (emit_call_ref): Rename 'subr_sym' into 'func'.
+
+2020-06-06 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ Reduce the number of files probed when finding a lisp file.
+
+ * src/lread.c (get-load-suffixes): Do not add any suffix to files that
+ need to be loaded by the dynamic linker.
+ (effective_load_path): Remove function.
+ (load): Don't add any suffix if file ends in a suffix already.
+ (effective_load_path): Remove function.
+ (openp_add_middle_dir_to_suffixes): Add helper function to create
+ pairs of middle directories and suffixes.
+ (openp_max_middledir_and_suffix_len): Add helper function to count the
+ number of bytes needed to store the middle directory and suffix.
+ (openp_fill_filename_buffer): Add helper function to copy middle
+ directory, basename and suffix to the filename buffer.
+
+2020-06-06 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-06-06 Paul Eggert <eggert@cs.ucla.edu>
+
+ make-text-button no longer modifies its string arg
+
+ * etc/NEWS: Mention this.
+ * lisp/apropos.el (apropos-library-button):
+ * lisp/ibuf-ext.el (ibuffer-old-saved-filters-warning):
+ There’s no longer a need copy make-text-button’s string arg.
+ * lisp/button.el (make-text-button): Return a copy of a string arg.
+ Delay making the copy until after error-checking.
+
+2020-06-06 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Un-deprecate oset and oset-default
+
+ For discussion see the following threads:
+ https://lists.gnu.org/archive/html/emacs-devel/2020-05/msg00630.html
+ https://lists.gnu.org/archive/html/emacs-devel/2020-05/msg00674.html
+ https://lists.gnu.org/archive/html/emacs-devel/2020-06/msg00099.html
+
+ * lisp/emacs-lisp/eieio.el (oset, oset-default): Un-deprecate.
+ * lisp/emacs-lisp/eieio-core.el (eieio-oref): Declare gv-setter here
+ instead of in lisp/emacs-lisp/eieio.el. Suggested by
+ Stefan Monnier <monnier@iro.umontreal.ca>.
+ (eieio-oref-default): Add gv-setter declaration.
+ * etc/NEWS: Announce these changes.
+ * doc/misc/eieio.texi (Accessing Slots): Document oref and
+ oref-default as generalized variables. Consistently document
+ getters before setters.
+ * test/lisp/emacs-lisp/eieio-tests/eieio-tests.el: Use
+ lexical-binding.
+ (eieio-test-13-init-methods): Simplify.
+ (eieio-test-33-instance-tracker): Declare IT-list as special.
+
+2020-06-06 Andrea Corallo <akrl@sdf.org>
+
+ Some fixes for --without-nativecomp config
+
+ * src/pdumper.c (dump_subr): Do not add RELOC_NATIVE_SUBR for
+ VERY_LATE_RELOCS in --without-nativecomp.
+ (dump_do_dump_relocation): Add a sanity check that no
+ RELOC_NATIVE_SUBR exists in --without-nativecomp.
+
+ * src/lread.c (Fload): As Fnative_elisp_load is not defined
+ in --without-nativecomp so ifdef this block.
+
+2020-06-06 Ellington Santos <ellingtonsantos@gmail.com> (tiny change)
+
+ Improve battery status display via GNU/Linux sysfs
+
+ * lisp/battery.el (battery-linux-sysfs): Support %b format.
+ Improve the display of %p. (Bug#41542)
+
+2020-06-05 Pip Cet <pipcet@gmail.com>
+
+ Avoid zero-width glyphs and the resulting cursor artifacts
+
+ * src/xdisp.c (fill_gstring_glyph_string): Handle unavailable glyphs.
+ (append_composite_glyph): Mark unavailable glyphs.
+ (gui_produce_glyphs): Make glyphs unavailable for zero-width
+ compositions. (Bug#41645)
+
+2020-06-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Streamline live_*_holding
+
+ (live_string_holding, live_cons_holding, live_symbol_holding)
+ (live_float_p, live_vector_holding):
+ Assert that m->type is correct, instead of testing this at
+ runtime. All callers changed.
+ (live_large_vector_holding, live_small_vector_holding):
+ Now two functions instead of the old live_vector_holding.
+ All callers changed.
+ (live_large_vector_p, live_small_vector_p):
+ Now two functions instead of the old live_vector_p.
+ All callers changed.
+ (mark_maybe_object): Ignore Lisp_Type_Unused0 quickly too,
+ since that cannot possibly be an object.
+ (CHECK_LIVE, CHECK_ALLOCATED_AND_LIVE):
+ New arg MEM_TYPE. All callers changed.
+ (CHECK_ALLOCATED_AND_LIVE_SYMBOL): Simplify by combining
+ GC_CHECK_MARKED_OBJECTS code.
+
+2020-06-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Make live_*_p more accurate
+
+ * src/alloc.c (live_string_holding, live_cons_holding)
+ (live_symbol_holding, live_vector_holding):
+ Return a C pointer, not a Lisp_Object. All callers changed.
+ This helps the compiler a bit.
+ (live_string_p, live_cons_p, live_symbol_p, live_vector_p):
+ Require that P point directly at the object, rather than
+ somewhere within the object. This fixes some false positives
+ with valid_lisp_object_p (used only in debugging).
+ (mark_maybe_object): Rely on the new accuracy.
+
+2020-06-05 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix some side-effecting uses of make-text-button
+
+ For discussion, see the following thread:
+ https://lists.gnu.org/archive/html/emacs-devel/2020-06/msg00117.html
+
+ * lisp/apropos.el (apropos-library-button):
+ * lisp/help-fns.el (help-fns--first-release): Return result of
+ make-text-button instead of relying on its side effects.
+ * lisp/ibuf-ext.el (ibuffer-old-saved-filters-warning): Avoid
+ modifying an immutable string.
+
+2020-06-05 Juri Linkov <juri@linkov.net>
+
+ * lisp/dired.el (dired-toggle-marks): Use region for non-nil dired-mark-region
+
+ (dired-mark--region-use-p, dired-mark--region-beginning)
+ (dired-mark--region-end): New internal functions.
+ (dired-mark-if): Use new functions. (Bug#39902)
+
+2020-06-04 Simen Heggestøyl <simenheg@gmail.com>
+
+ Change default project list filename to "projects"
+
+ * lisp/progmodes/project.el (project-list-file): Change the default
+ filename to "projects".
+
+2020-06-04 Simen Heggestøyl <simenheg@gmail.com>
+
+ Use characters for keys in project-switch-commands
+
+ * lisp/progmodes/project.el (project-switch-commands): Use
+ characters for keys instead of string for better future
+ compatibility with 'read-multiple-choice'.
+ (project-switch-project): Adjust to above change.
+
+2020-06-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/font-lock.el (font-lock--syntax-table-affects-ppss): New var
+
+ This tries to make `font-lock-syntax-table` work correctly even when
+ it changes the parsing of strings and comments, as was the case in
+ `font-latex.el`.
+
+ We should probably deprecate the use of `font-lock-syntax-table` since
+ the present fix is still not 100% and since it comes with performance
+ problems in large files.
+
+ (font-lock-set-defaults): Set it.
+ (font-lock-fontify-syntactically-region): Don't use `syntax-ppss`
+ when we think that `font-lock-syntax-table` would interfere.
+
+2020-06-04 Andrea Corallo <akrl@sdf.org>
+
+ Fix build for --enable-check-lisp-object-type=yes (bug#41703)
+
+ * src/comp.c (emit_coerce): Add missing declaration.
+
+2020-06-04 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-06-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Don’t default to Valgrind unless ENABLE_CHECKING
+
+ * src/alloc.c (USE_VALGRIND): If not defined, don’t default it to
+ 1 unless ENABLE_CHECKING. The Valgrind hooks bloat the garbage
+ collector a bit in production, and there’s no need for them these
+ days if one has a Valgrind suppressions file (which one needs anyway).
+ (mark_maybe_pointer): Use ‘#if USE_VALGRIND’ instead of ‘#ifdef
+ USE_VALGRIND’ for consistency with other uses of USE_VALGRIND.
+ This is in case someone builds with ‘-DENABLE_CHECKING
+ -DUSE_VALGRIND=0’ in CFLAGS.
+
+2020-06-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Revert make-text-button string copy
+
+ * lisp/button.el (make-text-button): Don’t make a copy of
+ a button’s string label. This reverts the change made in
+ 2020-05-17T05:23:28Z!eggert@cs.ucla.edu, which broke SLY.
+ Problem reported by João Távora in:
+ https://lists.gnu.org/r/emacs-devel/2020-06/msg00117.html
+ However, we’ll need a better fix for this once string
+ literals become contents, if SLY uses string constants
+ for text button labels.
+
+2020-06-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix make-text-button bug with string copy
+
+ * lisp/button.el (make-text-button): Use the copy of BEG
+ uniformly, instead of in just one place. This fixes a typo
+ introduced in 2020-05-17T05:23:28Z!eggert@cs.ucla.edu.
+ Problem reported by João Távora in:
+ https://lists.gnu.org/r/emacs-devel/2020-06/msg00117.html
+
+2020-06-03 Andrea Corallo <akrl@sdf.org>
+
+ Introduce `comp-loop-insn-in-block'
+
+ * lisp/emacs-lisp/comp.el (comp-loop-insn-in-block): New macro.
+ (comp-call-optim-func, comp-dead-assignments-func)
+ (comp-remove-type-hints-func): Use `comp-loop-insn-in-block'.
+
+2020-06-03 João Távora <joaotavora@gmail.com>
+
+ Ensure Jsonrpc processes are created in correct buffer
+
+ Report and original implementation by Steve Purcell
+ <steve@sanityinc.com>. See also See
+ https://github.com/joaotavora/eglot/pull/493 for details
+
+ * lisp/jsonrpc.el (initialize-instance): Make process in original
+ buffer.
+ (Version): Bump to 1.0.12
+
+2020-06-03 Mattias Engdegård <mattiase@acm.org>
+
+ Make color-distance symmetric and more accurate
+
+ * src/xfaces.c (color_distance): Don't throw away the low 8 bits of
+ the colours, and make the function symmetric (bug41544)
+ (Fcolor_distance): Add caution about this not being a true metric.
+ * test/src/xfaces-tests.el: New file.
+
+2020-06-03 Pip Cet <pipcet@gmail.com>
+
+ Handle mid-gstring face changes
+
+ * src/xdisp.c (fill_gstring_glyph_string): Don't extend the glyph
+ string past face changes. (Bug#41454)
+
+2020-06-03 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix bug in recent byte-code checking hoist
+
+ Problem reported by Daniel Colascione (Bug#41680).
+ * src/lread.c (read1): Check that AREF (tmp, COMPILED_BYTECODE)
+ is a string before subjecting it to STRING_MULTIBYTE.
+ Be more consistent about using AREF in the neighborhood,
+ to help prevent this sort of problem from recurring.
+
+2020-06-03 Pip Cet <pipcet@gmail.com>
+
+ Avoid losing composition state in handle_stop_backwards
+
+ * src/xdisp.c (handle_stop_backwards): Save composition iterator state
+ across our forward scan. (Bug#41626)
+
+2020-06-03 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ Fix DLL imports of gccjit version functions.
+
+ * src/comp.c (init_gccjit_functions): Use LOAD_DLL_FN_OPT macro to
+ load gcc_jit_version_major, gcc_jit_version_major and
+ gcc_jit_version_patchlevel.
+ * src/w32common.h (LOAD_DLL_FN_OPT): Add macro optionally load a
+ function from a DLL.
+
+2020-06-02 Dmitry Gutov <dgutov@yandex.ru>
+
+ Small cleanup
+
+ * lisp/progmodes/project.el (project--add-to-project-list-front):
+ Small simplification.
+ (project--remove-from-project-list): Remove oudated comment.
+
+2020-06-02 Dmitry Gutov <dgutov@yandex.ru>
+
+ project-list-file: New user option
+
+ * lisp/progmodes/project.el (project): New custom group.
+ (project-vc): Use it as parent.
+ (project-vc-merge-submodules): Tag with Emacs version.
+ (project-read-file-name-function): Assign to the 'project' group.
+ (project-list-file): New user option (bug#41600).
+ (project--write-project-list, project--read-project-list): Use it.
+
+2020-06-02 Eli Zaretskii <eliz@gnu.org>
+
+ Fix Arabic composition rules
+
+ * lisp/language/misc-lang.el (composition-function-table): Reorder
+ Arabic composition rules in descending order of lookback.
+
+ * src/composite.c (syms_of_composite): Document the order of rules
+ in 'composition-function-table'.
+
+2020-06-02 Simen Heggestøyl <simenheg@gmail.com>
+
+ Write project list to file only when changed
+
+ * lisp/progmodes/project.el (project--add-to-project-list-front):
+ Write the project list to file only when it has changed.
+
+2020-06-02 Simen Heggestøyl <simenheg@gmail.com>
+
+ Remove 'project--ensure-file-exists'
+
+ * lisp/progmodes/project.el (project--ensure-file-exists): Remove.
+ (project--read-project-list): Set 'project--list' to nil when the
+ project list file doesn't exist.
+
+2020-06-02 Eli Zaretskii <eliz@gnu.org>
+
+ Fix handling of CGJ in Hebrew text
+
+ * lisp/language/hebrew.el (hebrew): Add CGJ U+034F to the
+ combining characters supported in Hebrew compositions. (Bug#41645)
+
+2020-06-02 Paul Eggert <eggert@cs.ucla.edu>
+
+ Simplify and regularize some offset tests in alloc.c
+
+ * src/alloc.c (live_string_holding, live_cons_holding)
+ (live_symbol_holding, live_float_p): Simplify and regularize.
+
+2020-06-02 Paul Eggert <eggert@cs.ucla.edu>
+
+ Merge from origin/emacs-27
+
+ 0260d2d2db Don't call 'mbrtowc' on WINDOWSNT
+
+2020-06-02 Paul Eggert <eggert@cs.ucla.edu>
+
+ Merge from origin/emacs-27
+
+ 44c0e074f7 * doc/emacs/buffers.texi (Icomplete): Mention icomplete-mi...
+ 68b6dad1d8 Be more aggressive in marking objects during GC
+ 36f508f589 ; * src/xdisp.c (find_last_unchanged_at_beg_row): Fix a typo.
+ cc340da1fe Fix bug #41618 "(byte-compile 'foo) errors when foo is a m...
+ 41232e6797 Avoid crashes due to bidi cache being reset during redisplay
+ f72bb4ce36 * lisp/tab-bar.el (switch-to-buffer-other-tab): Normalize ...
+ d3e0023aaa ; * etc/TODO: Fix formatting. (Bug#41497)
+ a8ad94cd2f Fix mingw.org's MinGW GCC 9 warning about 'execve'
+
+ # Conflicts:
+ # lisp/tab-bar.el
+ # nt/inc/ms-w32.h
+ # src/alloc.c
+
+2020-06-02 Juri Linkov <juri@linkov.net>
+
+ * lisp/progmodes/project.el (project-vc-dir, project-shell): New commands.
+
+ (project-compile): Add args and interactive spec like in 'compile'.
+ (project-switch-commands): Bind project-vc-dir to "v",
+ project-shell to "s", and rebind project-find-regexp from "s" to "r".
+
+ * doc/emacs/maintaining.texi (Project File Commands):
+ Describe project-vc-dir and project-shell.
+
+2020-06-01 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ * Throw an ICE when asked to emit a cast with sign extension.
+
+ * src/comp.c (cast_kind_of_type): Enum that specifies the kind of type
+ in the cast enum (unsigned, signed, pointer).
+ (emit_coerce): Throw an ICE when asked to emit a cast with sign
+ extension.
+ (define_cast_from_to): Return NULL for casts involving sign extension.
+ (define_cast_functions): Specify the kind of each type in the cast
+ union.
+
+2020-06-01 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ * Define casts using functions.
+
+ This is to dump prettier C files.
+ This does not affect compilation times in my tests.
+
+ * src/comp.c: Define a 15x15 cast matrix. Use it in emit_coerce().
+
+2020-06-01 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ * Remove unnecessary DLL load of gcc_jit_block_add_assignment_op.
+
+ * src/comp.c (gcc_jit_block_add_assignment_op): Remove unnecessary
+ func import.
+
+2020-06-01 Alan Mackenzie <acm@muc.de>
+
+ Bug #41061 patch: Fix typos and amend code slightly
+
+ * lisp/progmodes/cc-align.el (c-lineup-ternary-bodies)
+ * doc/misc/cc-mode.texi (Operator Line-Up): Fix typos and amend code.
+
+2020-06-01 Dmitry Gutov <dgutov@yandex.ru>
+
+ Change xref-find-apropos to pass PATTERN to backend verbatim
+
+ * lisp/progmodes/xref.el (xref-backend-apropos): Rename this
+ generic's second arg to PATTERN, to clarify that it should be
+ handled entirely in the backend, with no pre-processing by the
+ command.
+ (xref-find-apropos): Update accordingly, but keep compatibility
+ with backends in older Emacs versions.
+ (xref-apropos-regexp): Extract from xref-find-apropos.
+
+ * lisp/progmodes/etags.el (xref-backend-apropos): Use it here.
+
+ * lisp/progmodes/elisp-mode.el (xref-backend-apropos): And here.
+
+2020-05-31 Andrea Corallo <akrl@sdf.org>
+
+ Store libgccjit version into generated code
+
+ * src/comp.c (emit_ctxt_code): Add libgccjit version into
+ stored optimize qualities.
+ (syms_of_comp): Define Qgccjit here.
+
+ * src/w32fns.c (syms_of_w32fns): Move out Qgccjit definition.
+
+2020-05-31 Andrea Corallo <akrl@sdf.org>
+
+ Optimize 'emit_static_object' for load-time
+
+ * src/comp.c (emit_static_object): Use a chunk size of 200 bytes
+ on bugged GCCs and a longer one (1024) in sane ones. Rename
+ str in buff to disambiguate and prefer xmalloc to a VLA given
+ the buffer is not that small.
+
+2020-05-31 Andrea Corallo <akrl@sdf.org>
+
+ Add `comp-libgccjit-version' subr
+
+ * src/comp.c (gcc_jit_version_major, gcc_jit_version_minor)
+ (gcc_jit_version_patchlevel): Import.
+ (Fcomp_libgccjit_version): New Lisp function.
+ (syms_of_comp): Update for 'comp-libgccjit-version'.
+
+2020-05-31 Philipp Stephani <phst@google.com>
+
+ Unbreak compilation with CHECK_STRUCTS defined.
+
+ * src/pdumper.c (dump_float): Update hash value after commit
+ 9f7bfb6cb06f1480a0904184cabf187e03628e55. The struct layout is still
+ compatible.
+
+2020-05-31 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-05-31 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ * Cut down compile-time emitting static data as string literals
+
+ This change drastically reduce compile time. Apparently GCC optimizer
+ does not scale up well at all for long sequences of assignments into a
+ single array.
+
+ Nicolás Bértolo <nicolasbertolo@gmail.com>
+ Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (gcc_jit_context_new_string_literal)
+ (gcc_jit_block_add_assignment_op): New imports.
+ (comp_t): New 'size_t_type' 'memcpy' fields.
+ (emit_static_object): Define static objects using string literals
+ and memcpy.
+ (define_memcpy): New function.
+ (Fcomp__init_ctxt): Define 'size_t_type' and 'memcpy'.
+
+2020-05-31 Andrea Corallo <akrl@sdf.org>
+
+ Emit better debug comments in emit_static_object
+
+ * src/comp.c (emit_static_object): Do not truncate debug
+ comments at the first NULL character.
+
+2020-05-31 Tom Tromey <tom@tromey.com>
+
+ Remove mhtml--extend-font-lock-region (Bug#41441)
+
+ * lisp/textmodes/mhtml-mode.el (mhtml--extend-font-lock-region):
+ Remove.
+ (mhtml-mode): Don't set font-lock-extend-region-functions.
+
+2020-05-31 Eli Zaretskii <eliz@gnu.org>
+
+ Protect bidi cache from inadvertent resets
+
+ * src/xdisp.c (Fline_pixel_height, Fmove_point_visually): Save and
+ restore the bidi cache, to avoid inadvertently resetting it by
+ starting a new iteration through buffer text. This could cause
+ trouble if these functions are called during a redisplay cycle,
+ especially while we were processing RTL text.
+
+2020-05-31 Tino Calancha <tino.calancha@gmail.com>
+
+ occur: Add bindings for next-error-no-select
+
+ Make the navigation in the occur buffer closer
+ to the navigation in the compilation buffer.
+
+ Add bindings to navigate the occur matches (Bug#39121).
+ Honor `next-error-highlight' and `next-error-highlight-no-select'
+ when navigating the occurrences.
+
+ * lisp/replace.el (occur-highlight-regexp, occur-highlight-overlay):
+ New variables.
+ (occur-1): Set `occur-highlight-regexp' to the searched regexp.
+ (occur-goto-locus-delete-o, occur--highlight-occurrence): New defuns.
+ (occur-mode-display-occurrence, occur-mode-goto-occurrence):
+ Use `occur--highlight-occurrence'.
+ (occur-mode-map): Bind n to `next-error-no-select'
+ and p to `previous-error-no-select'
+
+ * etc/NEWS (Changes in Specialized Modes and Packages in Emacs 28.1):
+ Announce this change.
+
+ * test/lisp/replace-tests.el (replace-tests-with-highlighted-occurrence):
+ Add helper macro.
+ (occur-highlight-occurrence): Add test.
+
+2020-05-31 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ Fix loading of libgccjit.dll while dumping in Windows.
+
+ loadup.el calls `native-comp-available-p', that calls
+ load_gccjit_if_necessary() in Windows. That function tries to load
+ libgccjit using the mappings defined in `dynamic-library-alist'. That
+ mapping is filled by term/w32-win.el, but that file may be loaded too
+ late.
+
+ * src/emacs.c (syms_of_emacs): Add libgccjit to the
+ `dynamic-library-alist' used when starting to dump so
+ `native-comp-available-p' always works in Windows.
+
+2020-05-31 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ Do not call `gensym' too early when loading a dump file.
+
+ This happened when subr.eln was not the first native compilation unit
+ to be loaded. register_native_comp_unit() is called when loading a
+ native compilation unit and that in turn used to call `gensym', which
+ was not loaded yet. This led to a SIGSEGV.
+
+ * src/comp.c (register_native_comp_unit): Replace the call to `gensym'
+ with an ad-hoc counter.
+
+2020-05-30 Dmitry Gutov <dgutov@yandex.ru>
+
+ Don't return transient projects with MAYBE-PROMPT=nil
+
+ * lisp/progmodes/project.el (project-current): Only return
+ transient projects when called with non-nil MAYBE-PROMPT.
+ Also only update the known projects lists in this case.
+ (https://lists.gnu.org/archive/html/emacs-devel/2020-05/msg03375.html).
+
+2020-05-30 immerrr <immerrr@gmail.com>
+
+ Minor fix in 'find-alternate-file'
+
+ This fixes the use case when, for example, 'find-file-hooks'
+ fails.
+ * lisp/files.el (find-alternate-file): If buffer 'oname' exists,
+ kill it before renaming the new one. (Bug#41359)
+
+2020-05-30 Eli Zaretskii <eliz@gnu.org>
+
+ Remove private prototype for 'execve' and its uses in MinGW build
+
+ * src/sysdep.c (emacs_exec_file): Don't compile this function
+ anymore on WINDOWSNT, since it is not used there. This function
+ was the only reason for having 'execve' prototype in ms-w32.h.
+
+ * nt/inc/ms-w32.h (execve): Remove prototype and the MinGW64 vs
+ ming.org mess that it causes.
+
+2020-05-30 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-05-30 Andrea Corallo <akrl@sdf.org>
+
+ Avoid calling Ffile_exists_p too early
+
+ Being quite early in startup initialization is better not to rely on
+ Ffile_exists_p, this call Ffile_expand and not all the necessary
+ initialization already happened.
+
+ * src/pdumper.c (dump_do_dump_relocation): Use fopen instead of
+ Ffile_exists_p.
+
+2020-05-29 Eli Zaretskii <eliz@gnu.org>
+
+ Another fix of display of line-prefix with fringe bitmaps
+
+ * src/xdisp.c (redisplay_internal): Don't use "optimization 1"
+ if a glyph row from which to start display begins with a display
+ property that draws into the fringes. (Bug#41584)
+
+2020-05-29 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/package.el:
+ * lisp/emacs-lisp/smie.el: Fix indent.
+
+ Use the new "space after paren" convention to get the desired indentation
+
+2020-05-29 Dmitry Gutov <dgutov@yandex.ru>
+
+ project-prompt-project-dir: Use more consistent prompts
+
+ * lisp/progmodes/project.el (project-prompt-project-dir):
+ Use more consistent prompts.
+
+2020-05-29 Eli Zaretskii <eliz@gnu.org>
+
+ Fix display of line-prefix with fringe bitmaps
+
+ * src/xdisp.c (try_window_id): Don't use this optimization if a
+ glyph row from which to start display begins with a display
+ property that draws into the fringes. (Bug#41584)
+
+2020-05-29 Eli Zaretskii <eliz@gnu.org>
+
+ Commit indian.el forgotten in previous change.
+
+2020-05-29 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp-smb.el (tramp-smb-errors): Add "NT_STATUS_INVALID_PARAMETER".
+
+2020-05-29 akater <nuclearspace@gmail.com>
+
+ * lisp/emacs-lisp/lisp-mode.el: Add new indentation convention
+
+ (calculate-lisp-indent): To distinguish code and data when indenting,
+ introduce the convention that a space between an open paren and
+ a symbol indicate that this should be indented as a simple data list.
+
+2020-05-29 Arnold Noronha <arnold@tdrhq.com> (tiny change)
+
+ Create a buffer-local binding to improve performance
+
+ * lisp/ido.el (ido-make-buffer-list-1):
+ Create a buffer-local binding to improve performance when a lot of
+ buffers are open (bug#41029).
+
+2020-05-29 Dmitry Gutov <dgutov@yandex.ru>
+
+ next-error-find-buffer-function: Back to #'ignore
+
+ * lisp/simple.el (next-error-find-buffer-function):
+ Change the default back, to simplify the default behavior
+ (bug#40919).
+
+2020-05-28 James Thomas <jimjoe@gmx.net>
+
+ Improve Malayalam language transliteration
+
+ The existing ITRANS scheme did not support some characters and
+ language quirks like 'chillu's. The Inscript method had errors.
+ * lisp/language/ind-util.el (indian-mlm-base-table): Add archaic
+ chars, Mozhi combos; cleanup.
+ (indian-mlm-mozhi-table): New scheme Mozhi.
+ * lisp/leim/quail/indian.el (inscript-mlm-keytable): Correct
+ errors. Add Inscript chillus & zero-width chars, Mozhi scheme.
+ * etc/NEWS: Mention the changes.
+
+2020-05-28 Simen Heggestøyl <simenheg@gmail.com>
+
+ Merge branch 'feature/project-switching'
+
+2020-05-28 Mattias Engdegård <mattiase@acm.org>
+
+ Document that {en,de}code-coding-string preserve match data
+
+ * lisp/international/mule.el (define-coding-system):
+ Require :pre-write-conversion and :post-read-conversion functions
+ to leave the match data untouched.
+ * src/coding.c (Fdecode_coding_string, Fencode_coding_string):
+ Document functions as match-data-preserving.
+
+ Suggested by Stefan Monnier (see bug#41445).
+
+2020-05-28 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ bd7b681dc4 (origin/emacs-27) Tiny texinfo markup fixes
+ d0dd0e0612 ; Fix more @var/@code mixups in Elisp manual
+ 313dc0439e ; Fix another format-spec typo in the Elisp manual
+ 9d7fd78421 Make next-error behavior a bit more flexible
+ 0691d25295 * etc/NEWS.25: Belatedly announce upcase-dwim and downcase...
+ df91c94ca8 Fix access to single-byte characters in buffer text
+
+2020-05-28 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ e7a3ed8a6d Fix tab-bar-tab-name-ellipsis initialization
+ 4737d0af75 Fix Elisp manual entry for format-spec
+ 0195809bb6 Fix rare assertion violations in 'etags'
+ cddb0079ff ; * lisp/format-spec.el (format-spec): Fix typo.
+
+2020-05-27 Noam Postavsky <npostavs@gmail.com>
+
+ Adjust NEWS for revert of eshell fix on emacs-27 (Bug#41370)
+
+ * etc/NEWS.27: Move "Eshell no longer re-initializes its keymap every
+ call" to...
+ * etc/NEWS: ... here.
+
+2020-05-27 Noam Postavsky <npostavs@gmail.com>
+
+ Fix customizing of ido-mode (Bug#41557)
+
+ lisp/ido.el (ido-mode): When setting the user option to nil, pass 0 to
+ the function, so that it will be disabled as intended.
+
+2020-05-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix crash with invalid bytecode vectors
+
+ * src/lread.c (read_vector): If the vector is to short to be for
+ bytecodes don’t do bytecode processing for it, as the processing
+ might run past the end of the vector.
+
+2020-05-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ --with-wide-int is a no-op on 64-bit hosts
+
+ * configure.ac: Clarify wording for --with-wide-int help.
+ * src/pdumper.c (dump_vectorlike_generic):
+ Do the eassert even if --with-wide-int was specified unnecessarily.
+
+2020-05-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ Omit unnecessary USE_LAB_TAG #if
+
+ * src/lisp.h: Omit unnecessary #if; the condition is always false now.
+
+2020-05-27 Simen Heggestøyl <simenheg@gmail.com>
+
+ Simplify the previous commit
+
+ * lisp/progmodes/project.el (project--read-project-list): Simplify the
+ previous commit by utilizing the optional OMIT-NULLS argument to
+ 'split-string'.
+
+2020-05-27 Mattias Engdegård <mattiase@acm.org>
+
+ Don't clobber match data in utf-8-hfs conversion (bug#41445)
+
+ Reported by Ture Pålsson.
+
+ * lisp/international/ucs-normalize.el
+ (ucs-normalize-hfs-nfd-post-read-conversion)
+ (ucs-normalize-hfs-nfd-pre-write-conversion):
+ Use save-match-data to avoid match data clobber in normalisation.
+ * test/lisp/international/ucs-normalize-tests.el
+ (ucs-normalize-save-match-data): New test.
+
+2020-05-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ Tweak GC performance if !USE_LSB_TAG
+
+ Performance issue reported by Eli Zaretskii (Bug#41321#149).
+ * src/alloc.c (GC_OBJECT_ALIGNMENT_MINIMUM): New constant.
+ (maybe_lisp_pointer): Use it instead of GCALIGNMENT.
+
+2020-05-26 Alan Mackenzie <acm@muc.de>
+
+ Introduce some Objective-C 2.0 keywords. This fixes bug #5953
+
+ * lisp/progmodes/cc-langs.el (c-other-decl-kwds): New keywords @property,
+ @dynamic, @synthesize, @compatibility_alias.
+ (c-protection-kwds): New keywords @package, @required, @optional.
+ (c-block-stmt-1-kwds): New keyword @autoreleasepool.
+ (c-constant-kwds): New keywords IBAction, IBOutlet.
+
+2020-05-26 Simen Heggestøyl <simenheg@gmail.com>
+
+ Avoid adding the empty string to the project list
+
+ * lisp/progmodes/project.el (project--read-project-list): Avoid adding
+ the empty string to the project list.
+
+2020-05-26 Simen Heggestøyl <simenheg@gmail.com>
+
+ Adapt project functions to the new 'project-root'
+
+ * lisp/progmodes/project.el (project-dired, project-eshell)
+ (project--read-project-list, project--write-project-list)
+ (project--add-to-project-list-front)
+ (project--remove-from-project-list): Adapt to the new 'project-root'.
+
+2020-05-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ Some copy edits
+
+ * doc/emacs/maintaining.texi (Switching Projects)
+ (Project File Commands): Copy edits.
+
+ * etc/NEWS: Same.
+
+2020-05-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ Teach project-current to inhibit the prompt
+
+ * lisp/progmodes/project.el:
+ (project-current-inhibit-prompt): New variable.
+ (project-current, project-switch-project): Use it.
+
+2020-05-26 Simen Heggestøyl <simenheg@gmail.com>
+
+ Update the Emacs manual with recent project.el changes
+
+ * doc/emacs/maintaining.texi (Projects): Add a menu.
+ (Project File Commands): New subsection describing project file
+ commands (moved here from 'Working with Projects'). Describe the new
+ commands 'project-dired' and 'project-eshell'.
+ (Switching Projects): New subsection.
+
+ * etc/NEWS: Mention project.el changes.
+
+2020-05-26 Simen Heggestøyl <simenheg@gmail.com>
+
+ Rename 'project-switch-menu' to 'project-switch-commands'
+
+ * lisp/progmodes/project.el (project-switch-commands): Rename from
+ 'project-switch-menu'.
+ (project--keymap-prompt, project-switch-project): Update after the
+ renaming.
+
+2020-05-26 Simen Heggestøyl <simenheg@gmail.com>
+
+ Simplify 'project--keymap-prompt' a bit
+
+ * lisp/progmodes/project.el: Remove seq requirement.
+ (project--keymap-prompt): Simplify with 'mapconcat'.
+
+2020-05-26 Simen Heggestøyl <simenheg@gmail.com>
+
+ Turn project switch menu var into a public alist
+
+ * lisp/progmodes/project.el: Require seq.
+ (project--switch-alist): Remove in favor of the public
+ 'project-switch-menu'.
+ (project-add-switch-command): Remove; not needed now that
+ 'project-switch-menu' is a public alist.
+ (project-switch-menu): New variable mapping keys to project switching
+ menu entries.
+ (project--keymap-prompt, project-switch-project): Adjust to the new
+ 'project-switch-menu' format.
+
+2020-05-26 Simen Heggestøyl <simenheg@gmail.com>
+
+ Change dispatch binding of 'project-find-regexp'
+
+ * lisp/progmodes/project.el: Change default dispatch binding of
+ 'project-find-regexp' to 's'.
+
+2020-05-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ Integrate project-switch-project with project-find-regexp
+
+ * lisp/progmodes/project.el:
+ (project-find-regexp): Add to the list of 'switch' commands.
+ (project-switch-project): Use call-interactively so that the
+ former can read its arguments.
+
+2020-05-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ Move project-dired and project-eshell higher
+
+ * lisp/progmodes/project.el:
+ (project-dired, project-eshell): Move higher in the file,
+ according to their universal utility.
+
+2020-05-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ Use an alist instead of a keymap
+
+ * lisp/progmodes/project.el:
+ (project--switch-alist): New variable to use instead of
+ project-switch-keymap, which remove. Update all references.
+
+2020-05-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ Improve project name completion
+
+ * lisp/progmodes/project.el:
+ (project-prompt-project-dir): Use REQUIRE-MATCH=t. Make sure the
+ 'substring' completion style is used by default.
+
+2020-05-26 Dmitry Gutov <dgutov@yandex.ru>
+
+ Simplify a little, and avoid duplicate commands
+
+ * lisp/progmodes/project.el:
+ (project--transient-p) Remove, not needed.
+ (project-current): Move project-find based on the directory here.
+ (project--remove-from-project-list): Only write if the list changed.
+ (project-find-project): Rename to project-prompt-project-dir.
+ Simply return the directory selected by the user.
+ (project-switch-project-find-file): Remove.
+ (project-switch-project-dired): Rename to project-dired and make
+ it follow the convention of existing projec tcommands.
+ (project-switch-project-eshell): Ditto.
+ (project-switch-project): Instead of passing the project instance
+ to the command, just bind default-directory.
+
+2020-05-26 Simen Heggestøyl <simenheg@gmail.com>
+
+ Add project switching functionality
+
+ * lisp/progmodes/project.el: Require subr-x.
+ (project--transient-p, project--ensure-file-exists)
+ (project--read-project-list, project--ensure-read-project-list)
+ (project--write-project-list)
+ (project--add-to-project-list-front)
+ (project--remove-from-project-list, project-find-project)
+ (project-switch-project-find-file, project-switch-project-dired)
+ (project-switch-project-eshell, project-add-switch-command)
+ (project--keymap-prompt, project-switch-project): New functions.
+ (project--list, project-switch-keymap): New variables.
+ (project-current): Call 'project-find-project' when no project is
+ current.
+
+2020-05-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port struct Lisp_FLoat to oddball platforms
+
+ * src/lisp.h (struct Lisp_Float): Declare via
+ GCALIGNED_UNION_MEMBER, not via GCALIGNED_STRUCT, since alloc.c
+ creates these in arrays and GCALIGNED_STRUCT does not necessarily
+ suffice to align struct Lisp_Float when it’s used in an array.
+ This avoids undefined behavior on oddball machines where
+ sizeof (struct Lisp_Float) is not a multiple of 8 and the compiler
+ does not support __attribute__ ((aligned 8)).
+
+2020-05-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Move union emacs_align_type to alloc.c
+
+ * src/alloc.c (union emacs_align_type): Move to here ...
+ * src/lisp.h: ... from here, and uncomment out some of the
+ types that alloc.c can see but lisp.h cannot.
+
+2020-05-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Further fix for aborts due to GC losing pseudovectors
+
+ * src/alloc.c (MALLOC_ALIGNMENT_BOUND): Remove.
+ (LISP_ALIGNMENT): Go back to yesterday’s version, except use
+ union emacs_align_type instead of max_align_t.
+ (MALLOC_IS_LISP_ALIGNED): Go back to yesterday’s version.
+ (maybe_lisp_pointer): Check against GCALIGNMENT, not LISP_ALIGNMENT.
+ * src/lisp.h (union emacs_align_type): Bring back.
+
+2020-05-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Refix aborts due to GC losing pseudovectors
+
+ This is simpler, and fixes a bug in the previous fix.
+ * src/alloc.c (MALLOC_ALIGNMENT_BOUND): Simplify by
+ using max_align_t, since the buggy implementations won’t
+ break this simpler implementation.
+ (LISP_ALIGNMENT): Simplify by just using GCALIGNMENT, since the
+ fancier implementation wasn’t correct anyway, and fixing it
+ isn’t worth the trouble on practical platforms.
+ * src/lisp.h (union emacs_align_type): Remove.
+
+2020-05-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix aborts due to GC losing pseudovectors
+
+ Problem reported by Eli Zaretskii (Bug#41321).
+ * src/alloc.c (MALLOC_ALIGNMENT_BOUND): New constant.
+ (LISP_ALIGNMENT): Lower it to avoid crashes on MinGW and similarly
+ buggy platforms where malloc returns pointers not aligned to
+ alignof (max_align_t). But keep it higher on platforms where this
+ is known to work, as it helps GC performance.
+ (MALLOC_IS_LISP_ALIGNED): Define in terms of the other two.
+ * src/alloc.c (stacktop_sentry):
+ * src/thread.c (run_thread):
+ Don’t overalign or oversize stack sentries; they need to be
+ aligned only for pointers and Lisp_Object, not for arbitrary
+ pseudovector contents.
+ * src/lisp.h (union emacs_align_type): New type, used for
+ LISP_ALIGNMENT.
+
+2020-05-26 Stefan Kangas <stefankangas@gmail.com>
+
+ Mark metamail.el as obsolete (Bug#41388)
+
+ The metamail package was last released in 1994, and has been removed
+ from most GNU/Linux distributions due to being buggy and unmaintained.
+
+ * lisp/mail/metamail.el: Move from here...
+ * lisp/obsolete/metamail.el: ...to here.
+ * etc/NEWS: Mention its obsoletion.
+
+2020-05-25 Andrea Corallo <akrl@sdf.org>
+
+ Add a compiler hint test
+
+ Test that compiler hints are executed transparently.
+
+ * test/src/comp-tests.el (comp-tests-type-hints): New test.
+
+ * test/src/comp-test-funcs.el (comp-tests-hint-fixnum-f)
+ (comp-tests-hint-cons-f): New functions.
+
+2020-05-25 Andrea Corallo <akrl@sdf.org>
+
+ Split type hint pass from dead code removal pass into dedicated one.
+
+ Given SSA prop overwrite mvar type slot we clean-up the compiler type
+ hints as last.
+
+ * lisp/emacs-lisp/comp.el (comp-passes): Add comp-remove-type-hints.
+ (comp-remove-type-hints-func): Code move.
+ (comp-dead-code): Do not call `comp-remove-type-hints-func'.
+ (comp-remove-type-hints): Add as new pass.
+
+2020-05-25 Dmitry Gutov <dgutov@yandex.ru>
+
+ Bump project.el version
+
+ * lisp/progmodes/project.el: Bump the version
+
+2020-05-25 Philipp Stephani <phst@google.com>
+
+ Allow inhibiting 'auto-save-visited-mode' on a per-buffer basis.
+
+ At least for me, 'auto-save-visited-mode' is very slow and blocks user
+ interaction for files visited over TRAMP. Therefore, I'd like a
+ mechanism to disable it for some buffers (namely, those visiting
+ remote files).
+
+ * (auto-save-visited-mode): Document that 'auto-save-visited-mode' can
+ be set to nil buffer-locally.
+
+ * etc/NEWS: Document new behavior.
+
+2020-05-25 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-05-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't bug out in xml-escape-string if invalid characters aren't present
+
+ * lisp/xml.el (xml-escape-string): Don't bug out if invalid
+ characters aren't present.
+
+2020-05-25 ej32u@protonmail.com <ej32u@protonmail.com>
+
+ Add command ffap-other-tab (Bug#41410)
+
+ * lisp/ffap.el (ffap-other-tab): New command, opens files at point in
+ another tab.
+ (ffap-bindings): Bind it to find-file-other-tab's binding.
+
+2020-05-25 Noam Postavsky <npostavs@gmail.com>
+
+ Make dedicated keymap and mode for eshell-command (Bug#41370)
+
+ Otherwise, we end up permanently modifying eshell-mode-map when
+ running eshell-command.
+ * lisp/eshell/eshell.el (eshell-command-mode): New mode, with map to
+ contain the bindings previously set by eshell-return-exits-minibuffer.
+ (eshell-return-exits-minibuffer): Make into obsolete alias for
+ eshell-command-mode.
+ (eshell-command): Use eshell-command-mode instead of
+ eshell-return-exits-minibuffer.
+
+2020-05-25 Noam Postavsky <npostavs@gmail.com>
+
+ Fix segfault on closing frame with tooltip (Bug#41239)
+
+ * src/gtkutil.c (xg_free_frame_widgets): Empty and unreference the
+ tooltip widget before destroying its label.
+
+2020-05-24 Andrea Corallo <akrl@sdf.org>
+
+ Fix GNU style
+
+ * src/comp.h: Fix GNU style.
+
+ * src/comp.c (Fcomp__compile_ctxt_to_file): Likewise.
+
+ * lisp/emacs-lisp/comp.el (comp--replace-output-file): Likewise.
+
+ * src/pdumper.c (dump_do_dump_relocation): Likewise.
+
+2020-05-24 Andrea Corallo <akrl@sdf.org>
+
+ Fix non Windows builds
+
+ * src/emacs.c (Fkill_emacs): Given
+ 'finish_delayed_disposal_of_comp_units',
+ 'dispose_all_remaining_comp_units' and
+ 'clean_package_user_dir_of_old_comp_units' are defined only with
+ windows native-comp builds ifdef them.
+
+ * src/comp.h (dispose_comp_unit): Fix missing parameter in
+ declaration.
+
+2020-05-25 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ Improve handling of native compilation units still in use in Windows
+
+ When closing emacs will inspect all directories from which it loaded
+ native compilation units. If it finds a ".eln.old" file it will try to
+ delete it, if it fails that means that another Emacs instance is using it.
+
+ When compiling a file we rename the file that was in the output path
+ in case it has been loaded into another Emacs instance.
+
+ When deleting a package we move any ".eln" or ".eln.old" files in the
+ package folder that we can't delete to `package-user-dir`. Emacs will
+ check that directory when closing and delete them.
+
+ * lisp/emacs-lisp/comp.el (comp--replace-output-file): Function called
+ from C code to finish the compilation process. It performs renaming of
+ the old file if necessary.
+ * lisp/emacs-lisp/package.el (package--delete-directory): Function to
+ delete a package directory. It moves native compilation units that it
+ can't delete to `package-user-dir'.
+ * src/alloc.c (cleanup_vector): Call dispose_comp_unit().
+ (garbage_collect): Call finish_delayed_disposal_of_comp_units().
+ * src/comp.c: Restore the signal mask using unwind-protect. Store
+ loaded native compilation units in a hash table for disposal on
+ close. Store filenames of native compilation units GC'd in a linked
+ list to finish their disposal when the GC is over.
+ (clean_comp_unit_directory): Delete all *.eln.old files in a
+ directory.
+ (clean_package_user_dir_of_old_comp_units): Delete all *.eln.old files
+ in `package-user-dir'.
+ (dispose_all_remaining_comp_units): Dispose of native compilation
+ units that are still loaded.
+ (dispose_comp_unit): Close handle and cleanup directory or arrange for
+ later cleanup if DELAY is true.
+ (finish_delayed_disposal_of_comp_units): Dispose of native compilation
+ units that were GC'd.
+ (register_native_comp_unit): Register native compilation unit for
+ disposal when Emacs closes.
+ * src/comp.h: Introduce cfile member in Lisp_Native_Comp_Unit.
+ Add declarations of functions that: clean directories of unused native
+ compilation units, handle disposal of native compilation units.
+ * src/emacs.c (kill-emacs): Dispose all remaining compilation units
+ right right before calling exit().
+ * src/eval.c (internal_condition_case_3, internal_condition_case_4):
+ Add functions.
+ * src/lisp.h (internal_condition_case_3, internal_condition_case_4):
+ Add functions.
+ * src/pdumper.c (dump_do_dump_relocation): Set cfile to a copy of the
+ Lisp string specifying the file path.
+
+2020-05-24 Stefan Kangas <stefankangas@gmail.com>
+
+ Mark browse-url-conkeror as obsolete
+
+ * lisp/net/browse-url.el:
+ (browse-url--browser-defcustom-type)
+ (browse-url-conkeror-new-window-is-buffer)
+ (browse-url-conkeror-program, browse-url-conkeror-arguments)
+ (browse-url-default-browser, browse-url-conkeror): Mark the
+ conkeror browser as obsolete.
+
+ * etc/NEWS: Mention this.
+
+2020-05-24 Carl Lei <me@xecycle.info>
+
+ Add three C++20 coroutine keywords, co_await, co_yield, and co_return
+
+ * lisp/progmodes/cc-langs.el (c-operators): Add co_await and co_yield to the
+ C++ value of "Exception" keywords.
+ (c-return-kwds): Create a C++ value containing co_return.
+ (c-simple-stmt-kwds): Add co_return to the C++ value.
+
+2020-05-24 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-05-23 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port etags FALLTHROUGH to C2X
+
+ Problem reported by Ashish SHUKLA in:
+ https://lists.gnu.org/r/emacs-devel/2020-05/msg03013.html
+ * lib-src/etags.c (C_entries): Move label so that FALLTHROUGH
+ precedes a case label, as draft C2X specifies.
+
+2020-05-23 Paul Eggert <eggert@cs.ucla.edu>
+
+ Restore check for Emacs 20.2 bytecodes
+
+ * src/eval.c (Ffetch_bytecode): Check for multibyte bytecodes
+ here too. Problem reported by Stefan Monnier in:
+ https://lists.gnu.org/r/emacs-devel/2020-05/msg02876.html
+
+2020-05-23 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ d6a0b66a0c (origin/emacs-27) * lisp/subr.el (save-match-data): Clarif...
+ 1a6d59eeba Improve the documentation of setting up fontsets
+ c7737d40f2 ; * etc/TODO (Ligatures): Update the entry based on recent...
+ fb2e34cd21 ; * etc/TODO (Ligatures): Update the entry based on recent...
+ 13b6dfd4f7 * doc/emacs/killing.texi (Rectangles): Improve indexing.
+ a10254dd46 Fix accessing files on networked drives on MS-Windows
+
+2020-05-23 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 8cc453d788 Second attempt at improving indexing in control.texi
+
+2020-05-23 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 4b9fbdb5a7 ; Update TODO item about ligature support
+ 03d44acfdd * doc/lispref/control.texi (Processing of Errors): Improve...
+ b48ab743a8 Minor fixups for mutability doc
+ 6ac2326e5b Don’t use “constant” for values you shouldn’t change
+
+2020-05-23 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/loadup.el: Use new 'native-comp-available-p'.
+
+2020-05-23 Philipp Stephani <phst@google.com>
+
+ Reject invalid characters in XML strings (Bug#41094).
+
+ * lisp/xml.el (xml-escape-string): Search for invalid characters.
+ (xml-invalid-character): New error symbol.
+
+ * test/lisp/xml-tests.el (xml-print-invalid-cdata): New unit test.
+
+ * etc/NEWS: Document new behavior.
+
+2020-05-23 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ Windows: Use NUMBER_OF_PROCESSORS environment variable.
+
+ * lisp/emacs-lisp/comp.el (comp-effective-async-max-jobs): Use
+ NUMBER_OF_PROCESSORS environment variable if system is Windows NT,
+ "nproc" if it is in PATH or a default of 1.
+
+2020-05-23 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ * Workaround the 32768 chars command line limit in Windows.
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): Pass the
+ compilation commands through a temporary file that is loaded by the
+ child process. This is also done all other operating systems, even
+ those that support long command lines. It should not be a problem
+ since libgccjit uses temporary files too.
+
+2020-05-23 Chris McMahan <cmcmahan@gmail.com>
+
+ Let user adjust the column widths of the package menu.
+
+ * lisp/emacs-lisp/package.el (package-name-column-width)
+ (package-version-column-width, package-status-column-width)
+ (package-archive-column-width): New defcustoms.
+ (package-menu-mode):
+ Use the values of defcustoms instead of hardcoded
+ values. (Bug#41086)
+
+2020-05-23 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c: Aesthetic, GNU style fixes.
+
+2020-05-23 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ Load libgccjit dynamically in Windows.
+
+ * configure.ac: don't add linker flags if compiling on
+ Windows. Compile dynlib.c if modules or native compilation are
+ enabled. Always compile comp.c
+ * lisp/term/w32-win.el: Map 'gccjit to "libgccjit.dll" in
+ `dynamic-library-alist`.
+ * src/Makefile.in: Update comments. Update to handle changes in
+ configure.ac.
+ * src/comp.c: Add declarations of used libgccjit functions using
+ DEF_DLL_FN. Add calls to load_gccjit_if_necessary() where necessary.
+ Add `native-comp-available-p`
+ * src/comp.h: Remove Fnative_elisp_load. Add syms_of_comp().
+ * src/emacs.c (main): Always call syms_of_comp()
+ * src/w32.c (globals_of_w32): Clear Vlibrary_cache when starting
+ because the libraries loaded when dumping will not be loaded when
+ starting.
+ * src/w32fns.c: Add Qgccjit symbol.
+
+2020-05-23 Stefan Kangas <stefankangas@gmail.com>
+
+ Delete another library obsolete since 23.2
+
+ This was missed in a previous commit to remove obsolete libraries.
+ Its deletion was already announced in NEWS.
+
+ * lisp/obsolete/levents.el: Delete file. This library has been
+ obsolete since 23.2.
+
+2020-05-23 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/doc-view.el (doc-view-presentation): Fix thinko
+
+2020-05-23 Dmitry Gutov <dgutov@yandex.ru>
+
+ Implement 'mark-resolved' for the Git backend
+
+ * lisp/vc/vc-git.el (vc-git-mark-resolved): New function.
+
+2020-05-23 Dmitry Gutov <dgutov@yandex.ru>
+
+ project.el: A project has only one main root now
+
+ Practice shows that the vast majority of projects only use one main
+ root. The users of this API very often make this assumption as well.
+ The rest of the "roots" should be possible to express through
+ project-external-roots.
+
+ * lisp/progmodes/project.el: Update the commentary.
+ Only 4 non-obsolete generics now.
+ (project-root): Replacement for `project-roots'.
+ All callers updated. Implementations too.
+ (project-roots): Declare obsolete.
+ (project-external-roots): Simplify the docstring.
+ (project-ignores): Update the docstring.
+ (project-find-regexp): Omit the second arg to project-files.
+ (project--dir-ignores): Simplify.
+ (project-compile): Simplify, remove outdated comment.
+
+ * lisp/cedet/ede.el: Add a FIXME.
+
+2020-05-23 Dmitry Gutov <dgutov@yandex.ru>
+
+ Disable ido-everywhere when ido-mode is off
+
+ * lisp/ido.el (ido-mode): Disable the effects of 'ido-everywhere'
+ when ido-mode is turned off.
+
+2020-05-22 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c: Fix 32bit wide-int.
+
+ * src/comp.c (emit_XFIXNUM): Make right shift for MSB_TAG
+ arithmetic too to preserve sign bit.
+
+2020-05-22 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c: Fix i386 --enable-check-lisp-object-type
+
+ * src/comp.c (load_comp_unit): Fix return type, on i386 influence
+ parameter passing!
+
+2020-05-22 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c: Some aesthetic code clean-up.
+
+ * src/comp.c (comp_t): Remove 'lisp_X_s' field.
+ (emit_coerce): Respect 80 columns limit.
+ (emit_rvalue_from_emacs_uint): GNU style, unnecessary brackets.
+ (emit_rvalue_from_emacs_int): Likewise.
+ (emit_rvalue_from_lisp_word_tag): Likewise.
+ (emit_rvalue_from_lisp_word): Likewise.
+ (emit_lval_XLI): Remove unused function.
+ (emit_lval_XLP): Remove commented out code.
+ (define_add1_sub1): Respect 80 columns limit.
+ (Fcomp__init_ctxt): Reflect 'lisp_X_s' field removal.
+
+2020-05-22 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Improve shr/eww handling of mailto URLs
+
+ * lisp/net/eww.el (eww): Use function-put in place of put, as
+ recommended in "(elisp) Symbol Plists".
+ (eww-follow-link):
+ * lisp/net/shr.el (shr-browse-url): Rather than call browse-url-mail
+ directly, call browse-url which respects the user options
+ browse-url-handlers and browse-url-mailto-function. (Bug#41133)
+ (shr--current-link-region): Return nil if there is no link at point.
+ (shr--blink-link): Adapt accordingly.
+ (shr-fill-line, shr-indent, shr-table-body): Refactor to avoid some
+ unnecessary allocations.
+ * etc/NEWS: Announce that eww-follow-link and shr-browse-url support
+ custom URL handlers.
+
+2020-05-22 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Various json.el improvements
+
+ * etc/NEWS: Announce that json-read-number is now stricter.
+
+ * lisp/json.el: Bump package version.
+ (json-encoding-lisp-style-closings, json-pre-element-read-function)
+ (json-post-element-read-function, json-advance, json-peek)
+ (json--path): Clarify and improve style of doc strings.
+ (json-join): Define as an obsolete alias of string-join.
+ (json-alist-p, json-plist-p): Refactor for speed and declare as
+ pure, side-effect-free, and error-free.
+ (json--plist-reverse): Rename function...
+ (json--plist-nreverse): ...to this, making it destructive for speed.
+ All callers changed.
+ (json--plist-to-alist): Remove, replacing single use with map-pairs.
+ (json--with-indentation): Accept multiple forms as arguments, fix
+ their indentation, and allow them to be instrumented for debugging.
+ Add docstring.
+ (json-pop, json-read-keyword, json-add-to-object)
+ (json-encode-array): Simplify for speed.
+ (json-skip-whitespace): Put newline before carriage return for
+ likely frequency of occurrence, and so that the characters appear in
+ increasing order.
+ (json--check-position): Use 1+.
+ (json-path-to-position): Open code apply-partially.
+ (json-keywords): Turn into a defconst and mark as obsolete now that
+ it is no longer used.
+ (json--post-value, json--number, json--escape): New rx definitions.
+ (json-encode-keyword): Declare as side-effect-free.
+ (json-read-number): Reject leading zeros and plus signs, and make
+ integer part mandatory in accordance with JSON standards and for
+ consistency with native JSON parsing functions. Eagerly signal
+ json-number-format when garbage follows a valid number, e.g., when
+ reading "1.1.1", instead of leaving that up to the caller. Remove
+ optional internal argument from advertised calling convention now
+ that the function is no longer recursive.
+ (json-encode-number): Define as an alias of number-to-string.
+ (json-special-chars): Turn into a defconst.
+ (json-read-escaped-char, json-new-object, json-read-file)
+ (json-pretty-print): Simplify.
+ (json-read-string): For consistency with other json.el error
+ reporting, remove check for leading '"', and use the integer value
+ rather than the printed representation of characters in error data.
+ At EOB signal json-end-of-file instead of json-string-format.
+ (json--long-string-threshold, json--string-buffer): New variables.
+ (json-encode-string): Reimplement in terms of buffer manipulation
+ for speed (bug#20154).
+ (json-read-object): Escape ?\} properly.
+ (json--encode-alist): New function extracted from json-encode-alist.
+ (json-encode-hash-table, json-encode-alist, json-encode-plist): Use
+ it to avoid destructively modifying the argument when
+ json-encoding-object-sort-predicate is non-nil without incurring
+ unnecessary copying (bug#40693). Encode empty object as "{}" even
+ when pretty-printing. Simplify for speed.
+ (json-read-array): Avoid recomputing list length on each iteration
+ when json-pre-element-read-function is non-nil. Make first element
+ of json-array-format error data a string for consistency with
+ json-object-format and to make the displayed error message clearer.
+ (json-readtable-dispatch): Accept any kind of argument, not just
+ symbols. Generate the table in a simpler manner so the dispatch
+ order is clearer. Remove dispatch on ?+ and ?. now that
+ json-read-number is stricter and for consistency with native JSON
+ parsing functions. Signal json-end-of-file if argument is nil.
+ (json-read): Simplify accordingly.
+ (json-encode): Avoid allocating a list on each invocation.
+
+ * lisp/jsonrpc.el (jsonrpc--json-read, jsonrpc--json-encode): Check
+ whether native JSON functions are fboundp only once, at load time.
+
+ * lisp/progmodes/python.el (python--parse-json-array): New function.
+ (python-shell-prompt-detect): Use it to parse JSON directly as a
+ list rather than converting from a vector.
+
+ * test/lisp/json-tests.el (json-tests--with-temp-buffer): Allow
+ instrumenting for debugging.
+ (test-json-join, test-json-plist-to-alist): Remove tests.
+
+ (test-json-alist-p, test-json-plist-p, test-json-advance)
+ (test-json-peek, test-json-pop, test-json-skip-whitespace)
+ (test-json-read-keyword, test-json-encode-keyword)
+ (test-json-encode-number, test-json-read-escaped-char)
+ (test-json-read-string, test-json-encode-string)
+ (test-json-encode-key, test-json-new-object)
+ (test-json-encode-hash-table, test-json-encode-plist)
+ (test-json-encode-list, test-json-read-array)
+ (test-json-encode-array, test-json-read)
+ (test-json-read-from-string, test-json-encode): Extend tests.
+
+ (test-json-plist-reverse): Rename test...
+ (test-json-plist-nreverse): ...to this and avoid modifying literal
+ lists.
+ (test-json-read-number): Rename test...
+ (test-json-read-integer): ...to this, focusing on integers.
+ (test-json-add-to-object): Rename test...
+ (test-json-add-to-alist): ...to this, focusing on alists.
+ (json-encode-simple-alist): Rename test...
+ (test-json-encode-alist): ...to this, extending it.
+ (test-json-encode-alist-with-sort-predicate): Rename test...
+ (test-json-encode-alist-sort): ...to this, extending it.
+ (test-json-encode-plist-with-sort-predicate): Rename test...
+ (test-json-encode-plist-sort): ...to this, extending it.
+
+ (test-json-read-keyword-invalid, test-json-read-fraction)
+ (test-json-read-exponent, test-json-read-fraction-exponent)
+ (test-json-read-number-invalid)
+ (test-json-read-escaped-char-invalid, test-json-add-to-plist)
+ (test-json-add-to-hash-table, test-json-read-object-empty)
+ (test-json-read-object-invalid, test-json-read-object-function)
+ (test-json-encode-hash-table-pretty)
+ (test-json-encode-hash-table-lisp-style)
+ (test-json-encode-hash-table-sort, test-json-encode-alist-pretty)
+ (test-json-encode-alist-lisp-style, test-json-encode-plist-pretty)
+ (test-json-encode-plist-lisp-style, test-json-read-array-function)
+ (test-json-encode-array-pretty, test-json-encode-array-lisp-style)
+ (test-json-read-invalid): New tests.
+
+ (test-json-path-to-position-no-match): Use should-not.
+ (test-json-read-object): Move error check to new test
+ test-json-read-object-invalid.
+ (test-json-pretty-print-object): Adapt test now that empty objects
+ are pretty-printed as "{}".
+
+2020-05-21 Ryan C. Thompson <rct@thompsonclan.org>
+
+ lisp/ido.el: Respect completion-auto-help setting
+
+ This commit makes ido completion respect the user's setting for
+ `completion-auto-help' by default. It does this by defining a wrapper
+ function `ido-completion-auto-help', which calls `ido-completion-help'
+ only when `completion-auto-help' is non-nil.
+
+ * lisp/ido.el (ido-completion-auto-help): New function.
+ (ido-cannot-complete-command):
+ Use it as the new default (bug#41340).
+
+2020-05-21 Matthias Meulien <orontee@gmail.com>
+
+ Bookmark locations can refer to VC directory buffers (bug#39722)
+
+ * etc/NEWS: Document feature.
+ * lisp/vc/vc-dir.el (vc-dir-mode): Set local bookmark-make-record-function.
+ (bookmark-make-record-default, bookmark-prop-get, bookmark-default-handler)
+ (bookmark-get-bookmark-record): Declarations.
+ (vc-dir-bookmark-make-record): Make record used to bookmark a `vc-dir' buffer.
+ (vc-dir-bookmark-jump): Provides bookmark-jump behavior for a `vc-dir' buffer.
+
+2020-05-20 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ Handle LISP_WORDS_ARE_POINTERS and CHECK_LISP_OBJECT_TYPE.
+
+ * src/comp.c: Introduce the Lisp_X, Lisp_Word, and Lisp_Word_tag
+ types. These types are used instead of long or long long. Use
+ emacs_int_type and emacs_uint_types where appropriate.
+ (emit_coerce): Add special logic that handles the case when
+ Lisp_Object is a struct. This is necessary for handling the
+ --enable-check-lisp-object-type configure option.
+
+ * src/lisp.h: Since libgccjit does not support opaque unions, change
+ Lisp_X to be struct. This is done to ensure that the same types are
+ used in the same binary. It is probably unnecessary since only a
+ pointer to it is used.
+
+2020-05-20 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ * Remove a layer of indirection for access to pure storage.
+
+ * src/comp.c: Taking the address of an array is the same as casting it
+ to a pointer. Therefore, the C expression `(EMACS_INT **) &pure` is in
+ fact adding a layer of indirection that is not necessary. The fix is
+ to cast the `pure` array to a pointer and store that in a void pointer
+ that is part of the compiled shared library.
+
+2020-05-20 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (emit_setjmp): Aesthetic, respect 80 columns limit.
+
+2020-05-20 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ * Handle setjmp() taking two arguments in Windows.
+
+ * src/comp.c: Add `define_setjmp_deps()` and `emit_setjmp()` which
+ abstract over this difference in behavior between operating systems.
+
+ WARNING: Not all cases are handled by this patch. The Mingw-64
+ setjmp.h header deals with many other combinations. I don't think it
+ is a good idea to replicate the logic of that header inside
+ emacs. (Maybe a few lines in the configure script could be added to
+ handle this problem?)
+
+2020-05-20 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Fix bug #39972, by fixing c-display-defun-name for nested defuns
+
+ * lisp/progmodes/cc-mode.el (c-common-init): Build
+ add-log-current-defun-function out of c-defun-name-and-limits instead of the
+ former c-defun-name.
+
+2020-05-20 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Prevent gnus-registry-handle-action from creating spurious entries
+
+ Thanks to Bob Newell for finding this.
+
+ * lisp/gnus/gnus-registry.el (gnus-registry-handle-action): If a
+ message entry ends up with no groups in its 'group key, that means the
+ entry should be deleted.
+
+2020-05-20 Alan Mackenzie <acm@muc.de>
+
+ which-function-mode: put hook function on after-change-major-mode-hook
+
+ , rather than find-file-hook. This keeps which-function-mode active should
+ the major mode be reinitialized. Also accept a null result from
+ add-log-current-defun as definitive, should that function have run. This
+ fixes bug #40714.
+
+ * lisp/progmodes/which-func.el (which-func-ff-hook): Put on
+ after-change-major-mode-hook.
+ (which-function): Enhance the logic to accept a null result from
+ add-log-current-defun.
+
+2020-05-20 Nicolás Bértolo <nicolasbertolo@gmail.com>
+
+ Do not block SIGIO in platforms that don't have it.
+
+ * src/comp.c (comp--compile-ctxt-to-file): Add a preprocessor check to
+ avoid blocking SIGIO in platforms that don't have it.
+
+2020-05-20 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix minor Tramp oddities
+
+ * lisp/net/tramp-archive.el (tramp-archive-file-name-handler):
+ Increase `max-specpdl-size' temporarily.
+
+ * lisp/net/tramp-rclone.el (tramp-rclone-flush-directory-cache):
+ Fix a problem with older Emacsen.
+
+2020-05-20 Paul Eggert <eggert@cs.ucla.edu>
+
+ Hoist some byte-code checking out of eval
+
+ Check Lisp_Compiled objects better as they’re created,
+ so that the byte-code interpreter needn’t do the checks
+ each time it executes them. This improved performance
+ of ‘make compile-always’ by 1.5% on my platform. Also,
+ improve the quality of the (still-incomplete) checks, as
+ this is more practical now that they’re done less often.
+ * src/alloc.c (make_byte_code): Remove. All uses removed.
+ (Fmake_byte_code): Put a better (though still incomplete)
+ check here instead. Simplify by using Fvector instead
+ of make_uninit_vector followed by memcpy, and by using
+ XSETPVECTYPE instead of make_byte_code followed by XSETCOMPILED.
+ * src/bytecode.c (Fbyte_code): Do sanity check and conditional
+ translation to unibyte here instead of each time the function is
+ executed.
+ (exec_byte_code): Omit no-longer-necessary sanity and
+ unibyte checking. Use SCHARS instead of SBYTES where
+ either will do, as SCHARS is faster.
+ * src/eval.c (fetch_and_exec_byte_code): New function.
+ (funcall_lambda): Use it.
+ (funcall_lambda, lambda_arity, Ffetch_bytecode):
+ Omit no-longer-necessary sanity checks.
+ (Ffetch_bytecode): Add sanity check if actually fetching.
+ * src/lisp.h (XSETCOMPILED): Remove. All uses removed.
+ * src/lread.c (read1): Check byte-code objects more thoroughly,
+ albeit still incompletely, and do translation to unibyte here
+ instead of each time the function is executed.
+ (read1): Use XSETPVECYPE instead of make_byte_code.
+ (read_vector): Omit no-longer-necessary sanity check.
+
+2020-05-20 Kévin Le Gouguec <kevin.legouguec@gmail.com>
+
+ Add test for bug#39680
+
+ * test/lisp/electric-tests.el (electric-pair-undo-unrelated-state):
+ New test.
+
+2020-05-20 Philip K <philip@warpmail.net>
+
+ Add project-compile command
+
+ * lisp/progmodes/project.el (project-compile):
+ New function.
+
+2020-05-20 Dmitry Gutov <dgutov@yandex.ru>
+
+ project--vc-list-files: Don't list conflicted files thrice
+
+ * lisp/progmodes/project.el (project--vc-list-files):
+ Use delete-consecutive-dups.
+
+2020-05-19 Tassilo Horn <tsdh@gnu.org>
+
+ Allow back-references in syntax-propertize-rules.
+
+ * lisp/emacs-lisp/syntax.el (syntax-propertize--shift-groups-and-backrefs):
+ Renamed from syntax-propertize--shift-groups, and also shift
+ back-references.
+ (syntax-propertize-rules): Adapt docstring and use renamed function.
+ * test/lisp/emacs-lisp/syntax-tests.el: New test.
+ (syntax-propertize--shift-groups-and-backrefs): New ERT test.
+
+2020-05-19 Tassilo Horn <tsdh@gnu.org>
+
+ Indicate not downloaded parts in MIME buttons.
+
+ Via nnimap-fetch-partial-articles one can tell Gnus to omit fetching
+ certain parts by default. Now the MIME buttons in the article buffer
+ indicate how to fetch the complete message in order to act on those
+ missing parts.
+
+ * lisp/gnus/gnus-art.el (gnus-insert-mime-button): Indicate not
+ downloaded parts in MIME buttons.
+
+2020-05-19 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-num-cpus): Fix definition.
+
+ Introduced by 2aec16ab75.
+
+2020-05-19 Paul Eggert <eggert@cs.ucla.edu>
+
+ Reject attempts to clear pure strings
+
+ * src/fns.c (Ffillarray, Fclear_string):
+ Add CHECK_IMPURE here, to be consistent with Faset etc.
+ (Ffillarray): Prefer memset when the fill is a single byte.
+
+2020-05-19 Stefan Kangas <stefankangas@gmail.com>
+
+ Clarify wording in my last commit
+
+ * lisp/mouse.el (mouse-drag-and-drop-region-show-tooltip): Clarify
+ wording of integer option. Suggested by Eli Zaretskii.
+
+2020-05-19 Paul Eggert <eggert@cs.ucla.edu>
+
+ Improve password-cache-add example in comment
+
+ * lisp/password-cache.el: Improve comment. See Andreas Schwab in:
+ https://lists.gnu.org/r/emacs-devel/2020-05/msg02422.html
+
+2020-05-19 Paul Eggert <eggert@cs.ucla.edu>
+
+ Redo RCS Id for pdumper
+
+ * lisp/version.el: Don’t put an RCS Id style string into the
+ executable via purecopy, as this does not work with the pdumper.
+ * src/emacs.c (RCS_Id): New constant, for 'ident'.
+
+2020-05-18 Glenn Morris <rgm@gnu.org>
+
+ Add test for recent buffer-local-variables change
+
+ * test/src/buffer-tests.el (buffer-tests-buffer-local-variables-undo):
+ New.
+
+2020-05-18 Andrea Corallo <akrl@sdf.org>
+
+ Pacify with the byte-compiler
+
+ * lisp/emacs-lisp/comp.el (comp-num-cpus): New special variable.
+ (comp-effective-async-max-jobs): Make use of `comp-num-cpus'.
+ (comp-call-optim-form-call): Remove unnecessary parameter.
+ (comp-call-optim-func): Reflect `comp-call-optim-form-call'
+ parameter removal.
+
+2020-05-18 Andrea Corallo <akrl@sdf.org>
+
+ Add new customize `comp-async-env-modifier-form' (Bug#40838)
+
+ * lisp/emacs-lisp/comp.el (comp-async-env-modifier-form): New
+ customize.
+ (comp-run-async-workers): Make use of `comp-async-env-modifier-form'.
+
+2020-05-18 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Allow "static" etc. to be placed after a declaration's type name
+
+ Fixes bug #41284.
+
+ * lisp/progmodes/cc-langs.el (c-type-decl-prefix-key): include additionally
+ c-modifier-kwds in the set of keywords at the base of this lang-const.
+
+2020-05-18 Andrea Corallo <akrl@sdf.org>
+
+ Make the Evil happy (Bug#41374)
+
+ * lisp/emacs-lisp/comp.el (comp-never-optimize-functions):
+ Blacklist all primitives advised by evil-mode from trampoline
+ optimization.
+ (comp-call-optim-form-call): Prevent trampoline optimization for
+ recursive calls at speed 2 to respect elisp original semantic.
+
+2020-05-18 Glenn Morris <rgm@gnu.org>
+
+ Restore buffer-undo-list to buffer-local-variables
+
+ It has been missing since 2012-07-03 (Emacs 24.3)
+ "Cleanup basic buffer management", when undo_list was moved to
+ the end of struct buffer. (Bug#33492)
+ * src/buffer.c (buffer_local_variables_1): New function.
+ (Fbuffer_local_variables): Explicitly add buffer-undo-list.
+
+2020-05-18 Simen Heggestøyl <simenheg@gmail.com>
+
+ Use lexical-binding in webjump.el and add tests
+
+ * lisp/net/webjump.el: Use lexical-binding.
+ (webjump-read-url-choice): Remove redundant 'function' around lambda.
+
+ * test/lisp/net/webjump-tests.el: New file with tests for webjump.el.
+
+2020-05-18 Mattias Engdegård <mattiase@acm.org>
+
+ Fix calculator entry of numbers with negative exponents (bug#41347)
+
+ * lisp/calculator.el (calculator-string-to-number):
+ Remove obsolete string transformations preventing entry of 1e-3 etc.
+ Keep one transformation to allow entry of "1.e3".
+ Reported by Chris Zheng.
+
+2020-05-18 Dmitry Gutov <dgutov@yandex.ru>
+
+ Update the package version
+
+ * lisp/progmodes/project.el: Update the package version.
+ (project-vc-merge-submodules): Update the docstring.
+ (project-try-vc): Add a FIXME.
+
+2020-05-18 Dmitry Gutov <dgutov@yandex.ru>
+
+ Add user option project-vc-merge-submodules
+
+ * lisp/progmodes/project.el (project-vc): Update the docstring.
+ (project-vc-merge-submodules): New user option.
+ (project-try-vc): Use it.
+ (project--submodule-p): Extract from project-try-vc.
+
+2020-05-18 Dmitry Gutov <dgutov@yandex.ru>
+
+ vc-working-revision: Bind default-directory
+
+ * lisp/vc/vc-hooks.el (vc-working-revision):
+ Bind default-directory to be on the safe side.
+ Suggested by Ilya Ostapyshyn
+ (https://lists.gnu.org/archive/html/emacs-devel/2020-05/msg02301.html).
+
+2020-05-18 Paul Eggert <eggert@cs.ucla.edu>
+
+ Don’t attempt to modify constant strings
+
+ These attempts were found by ‘make compile-always’.
+ * lisp/language/tibet-util.el (tibetan-obsolete-glyphs):
+ * lisp/org/org-agenda.el (org-agenda-get-restriction-and-command):
+ Don’t try to modify string constants.
+
+2020-05-17 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-05-17 Andrea Corallo <akrl@sdf.org>
+
+ Fix Garbage Collector for missing calle-saved regs content (Bug#41357)
+
+ * src/alloc.c (SET_STACK_TOP_ADDRESS): Do not call
+ __builtin_unwind_init.
+ (flush_stack_call_func1): Rename from 'flush_stack_call_func'.
+ (flush_stack_call_func): New function to spill all registers
+ before calling 'flush_stack_call_func1'. This to make sure the
+ top of the stack identified includes those registers.
+
+2020-05-17 Richard Stallman <rms@gnu.org>
+
+ Don't mention non-GNU package archives.
+
+2020-05-17 Stefan Kangas <stefankangas@gmail.com>
+
+ Fix minor issues with mouse-drag-and-drop-region-show-tooltip
+
+ * lisp/mouse.el (mouse-drag-and-drop-region-show-tooltip): Fix
+ defcustom type to allow all valid values. Suggested by David
+ Ponce. (Bug#41351)
+ (mouse-drag-and-drop-region): Fix bug where setting
+ `drag-and-drop-region-show-tooltip' to 0 would still show a
+ tooltip.
+
+2020-05-17 Andrea Corallo <akrl@sdf.org>
+
+ Fix bug#41346 assertion triggered while loading dump
+
+ * src/comp.c (load_comp_unit): While loading from dump lambda
+ fixups are still to happen here. Verify relocation coherency only
+ after 'top_level_run' execution.
+
+2020-05-17 Paul Eggert <eggert@cs.ucla.edu>
+
+ Don’t attempt to modify constant strings
+
+ * lisp/bookmark.el (bookmark-bmenu-set-header):
+ Use copy-sequence instead of concat, for clarity.
+ Also, the byte-compiler optimizes (concat "a" "b") into "ab".
+ * lisp/button.el (make-text-button):
+ * test/lisp/erc/erc-track-tests.el (erc-track--erc-faces-in):
+ * test/lisp/password-cache-tests.el:
+ (password-cache-tests-add-and-remove)
+ (password-cache-tests-read-from-cache)
+ (password-cache-tests-in-cache-p, password-cache-tests-read)
+ (password-cache-tests-reset)
+ (password-cache-tests-add/expires-key)
+ (password-cache-tests-no-password-cache):
+ Don’t attempt to modify constant strings.
+ * lisp/progmodes/elisp-mode.el (elisp--xref-format)
+ (elisp--xref-format-extra):
+ Don’t attempt to modify constant strings via put-text-property.
+ * test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs-loop-across-ref):
+ Don’t attempt to modify constant vectors or strings.
+
+2020-05-17 Paul Eggert <eggert@cs.ucla.edu>
+
+ Don’t attempt to modify constant conses
+
+ From a patch privately suggested by Mattias Engdegård on 2020-05-11
+ in a followup to Bug#40671.
+ * admin/charsets/cp51932.awk:
+ * admin/charsets/eucjp-ms.awk:
+ Generate code that does not modify constant conses.
+ * doc/misc/emacs-mime.texi (Encoding Customization):
+ * lisp/emacs-lisp/byte-opt.el (byte-compile-side-effect-free-ops):
+ * lisp/frameset.el (frameset-persistent-filter-alist):
+ * lisp/gnus/gnus-sum.el (gnus-article-mode-line-format-alist):
+ Use append instead of nconc.
+ * lisp/language/japanese.el (japanese-ucs-cp932-to-jis-map)
+ (jisx0213-to-unicode):
+ Use mapcar instead of mapc.
+ * lisp/language/lao-util.el (lao-transcription-consonant-alist)
+ (lao-transcription-vowel-alist):
+ * lisp/language/tibetan.el (tibetan-subjoined-transcription-alist):
+ Use copy-sequence.
+ * test/src/fns-tests.el (fns-tests-nreverse):
+ (fns-tests-sort, fns-tests-collate-sort)
+ (fns-tests-string-version-lessp, fns-tests-mapcan):
+ Use copy-sequence, vector, and list.
+
+2020-05-16 John Wiegley <johnw@newartisans.com>
+
+ Add a note to eshell.texi that I, too, was a contributor
+
+2020-05-16 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ b4937f64cd (origin/emacs-27) Improve documentation of manually install...
+ efd4e973a4 Reflect the emacs-devel ELPA/MELPA dispute in FAQ
+ 28541674cd Consider face inheritance when checking region face backgr...
+ e75f6be6cc Fix dired default file operation (bug#41261)
+ 406fb0746c Fix documentation related to 'command-switch-alist'.
+ 747e0a2523 Improve ediff readability in misterioso theme (Bug#41221)
+ 48830c73e7 Fix a crash in handle_display_spec
+ a37290a6f9 In x_hide_tip reset tip_last_frame for GTK+ tooltips only ...
+ 3d81995692 Fix docstring of flymake-make-diagnostic (bug#40351)
+ 632aa9d57a Go back to “Bahá’í”
+ e2406ff60f * lisp/dired.el (dired-toggle-marks): Doc fix. (Bug#41097)
+
+ # Conflicts:
+ # doc/emacs/building.texi
+
+2020-05-16 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove stale comments
+
+ * lisp/printing.el (pr-create-interface):
+ * lisp/progmodes/ebnf2ps.el (ebnf-eps-filename, ebnf-trim-right):
+ Remove old comments about Emacs 21/22 compatibility.
+
+2020-05-16 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove some compat code from CEDET
+
+ * lisp/cedet/data-debug.el (data-debug-overlay-properties)
+ (data-debug-overlay-p, dd-propertize):
+ Redefine as obsolete function aliases.
+ (data-debug-insert-overlay-props, data-debug-insert-hash-table)
+ (data-debug-insert-hash-table-button)
+ (data-debug-insert-widget-properties, data-debug-insert-widget)
+ (data-debug-insert-symbol-from-point)
+ (data-debug-insert-symbol-button, data-debug-insert-string)
+ (data-debug-insert-number, data-debug-thing-alist):
+ Don't use obsolete names.
+
+2020-05-16 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove Emacs 22 compat code from abbrev.el
+
+ * lisp/abbrev.el (write-abbrev-file): Remove Emacs 22
+ compatibility code.
+
+2020-05-16 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove Emacs 22 compat code from ediff-vers.el
+
+ * lisp/vc/ediff-vers.el (ediff-vc-revision-other-window)
+ (ediff-vc-working-revision): Redefine Emacs 22 compatibility
+ aliases as obsolete function aliases.
+ (ediff-vc-internal, ediff-vc-merge-internal): Don't use the now
+ obsolete aliases.
+
+2020-05-16 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove some XEmacs compat code from semantic
+
+ * lisp/cedet/semantic/wisent/comp.el (wisent-ISVALID-TOKEN)
+ (wisent-parse-nonterminals):
+ * lisp/cedet/semantic/wisent/wisent.el
+ (wisent-item-to-string): Remove XEmacs compatibility code.
+ (wisent-char-p): Redefine as obsolete function alias for
+ 'characterp'.
+
+2020-05-16 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/textmodes/bibtex.el: Fix bug#41285 (paren typo)
+
+2020-05-16 Michael Albinus <michael.albinus@gmx.de>
+
+ Introduce process-file-return-signal-string
+
+ * doc/lispref/processes.texi (Synchronous Processes):
+ Describe `process-file-return-signal-string'.
+
+ * doc/misc/tramp.texi: Adapt Tramp and Emacs version numbers.
+ (Remote processes): Describe `process-file-return-signal-string'
+ and $INSIDE_EMACS.
+
+ * etc/NEWS: Describe `process-file-return-signal-string'. Fix typos.
+
+ * lisp/simple.el (process-file-return-signal-string): New user option.
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-process-file):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-process-file): Use it.
+
+ * lisp/net/tramp.el (tramp-get-signal-strings): New defun.
+
+ * test/lisp/net/tramp-tests.el (tramp-test28-process-file): Adapt test.
+
+2020-05-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/project.el (project-try-vc): Fix regexp typo.
+
+2020-05-15 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix submodules, second try
+
+ * lisp/progmodes/project.el (project-try-vc):
+ Call the backend directly instead of binding default-directory.
+
+2020-05-15 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: Fix bug #40052, where a very large macro was too slow in scrolling
+
+ * lisp/progmodes/cc-engine.el (c-end-of-macro): Fix faulty cache handling,
+ where the upper bound of c-macro-cache was never being set.
+ (c-forward-comment-minus-1): New macro which terminates unwanted indefinite
+ backward searching with lots of escaped newlines in c-backward-single-comment.
+ (c-backward-single-comment, c-backward-comments): Use the new macro above.
+
+ * lisp/progmodes/cc-mode.el (c-before-change-check-unbalanced-strings)
+ (c-after-change-mark-abnormal-strings, c-after-change-escape-NL-in-string):
+ Optimize three regexps by using shy groups, thus preventing regexp stack
+ overflow while handling the large C Macro.
+
+2020-05-15 Dmitry Gutov <dgutov@yandex.ru>
+
+ Fix Git submodules detection breakage
+
+ * lisp/progmodes/project.el (project-try-vc):
+ Use the absolute name of .git both times.
+
+2020-05-15 Andrea Corallo <akrl@sdf.org>
+
+ Do not refuse to compile if a dynamic lambda is encountered
+
+ * lisp/emacs-lisp/comp.el (comp-lex-byte-func-p): New subst.
+ (comp-intern-func-in-ctxt): Do not crash if we still encounter a
+ non lexical scoped lambda.
+
+2020-05-15 Andrea Corallo <akrl@sdf.org>
+
+ Allow for logging async compilation command line
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): When non zero
+ verbose log async compilation command line invocation.
+
+2020-05-15 Andrea Corallo <akrl@sdf.org>
+
+ Add check_comp_unit_relocs
+
+ * src/comp.c (check_comp_unit_relocs): Add function to verify
+ relocation coherency.
+ (load_comp_unit): Call it.
+
+2020-05-15 Andrea Corallo <akrl@sdf.org>
+
+ Sanity check on lambdas fixups
+
+ * src/pdumper.c (dump_do_dump_relocation): While fixing up lambda
+ relocation verify placeholder coherency.
+
+ * src/comp.c (syms_of_comp): Define symbol 'lambda-fixup'.
+
+ * lisp/emacs-lisp/comp.el (comp-finalize-container): Leave a
+ lambda-fixup as placeholder in the relocation as a sanity check.
+
+2020-05-15 Andrea Corallo <akrl@sdf.org>
+
+ Fix speed 2 bootstrap
+
+ (comp-call-optim-func): Do nothing if the function name is
+ unknown.
+
+2020-05-15 Andrea Corallo <akrl@sdf.org>
+
+ Native compiler test update
+
+ * test/src/comp-tests.el (comp-tests-lambda-return): Add a test
+ verifying that the returned lambda is actually native compiled.
+
+2020-05-15 Andrea Corallo <akrl@sdf.org>
+
+ Better Vcomp_sym_subr_c_name_h test function + doc
+
+ * src/comp.c (syms_of_comp): 'Vcomp_sym_subr_c_name_h' need only
+ 'eq' as test + fix doc for 'comp-sym-subr-c-name-h'.
+
+2020-05-15 Andrea Corallo <akrl@sdf.org>
+
+ Add anonymous lambdas reload mechanism
+
+ * src/pdumper.c (dump_do_dump_relocation): Initialize
+ 'lambda_gc_guard' while resurrecting.
+ (dump_do_dump_relocation): Revive lambdas and fixup them.
+
+ * src/comp.h (struct Lisp_Native_Comp_Unit): Define new
+ 'lambda_gc_guard' 'lambda_c_name_idx_h' 'data_imp_relocs'
+ 'loaded_once' fields.
+
+ * src/comp.c (load_comp_unit): Use compilaiton unit 'loaded_once'
+ field.
+ (make_subr, Fcomp__register_lambda): New functions.
+ (Fcomp__register_subr): Make use of 'make_subr'.
+ (Fnative_elisp_load): Indent.
+ (Fnative_elisp_load): Initialize 'lambda_gc_guard'
+ 'lambda_c_name_idx_h' fields.
+ (syms_of_comp): Add Scomp__register_lambda.
+
+ * lisp/emacs-lisp/comp.el (comp-ctxt): Change
+ 'byte-func-to-func-h' hash key test.
+ (comp-ctxt): Add 'lambda-fixups-h' slot.
+ (comp-emit-lambda-for-top-level): New function.
+ (comp-finalize-relocs): Never emit lambdas in pure space.
+ (comp-finalize-relocs): Fixup relocation indexes.
+
+2020-05-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/xref.el: Fix first line syntax
+
+ (xref--find-ignores-arguments): Simplify.
+
+2020-05-15 Simen Heggestøyl <simenheg@gmail.com>
+
+ Use lexical-binding in autoconf.el and add tests
+
+ * lisp/progmodes/autoconf.el: Use lexical-binding.
+
+ * test/lisp/progmodes/autoconf-tests.el: New file with tests for
+ autoconf.el.
+
+2020-05-15 Mattias Engdegård <mattiase@acm.org>
+
+ Calc: GCD(0,x)=GCD(x,0)=|x|, not x (bug#41279)
+
+ Reported by David Ongaro.
+
+ * lisp/calc/calc-comb.el (calcFunc-gcd): Fix GCD simplification.
+ * test/lisp/calc/calc-tests.el (calc-gcd, calc-sum-gcd): New tests.
+
+2020-05-15 Stefan Kangas <stefankangas@gmail.com>
+
+ Delete libraries obsolete since 23.1 and 23.2
+
+ Emacs 23.2 was released 10 years ago. old-whitespace.el has a
+ replacement in whitespace.el and is no longer relevant. The other
+ libraries implement compatibility with Lucid Emacs, a modified version
+ of Emacs last released in the 1990s.
+
+ * lisp/obsolete/ledit.el:
+ * lisp/obsolete/lmenu.el:
+ * lisp/obsolete/lucid.el:
+ * lisp/obsolete/old-whitespace.el: Delete files. These libraries have
+ been obsolete since Emacs 23.1 or 23.2.
+ * etc/NEWS: Announce their deletion.
+
+ * admin/authors.el (authors-ignored-files)
+ (authors-fixed-entries, authors-valid-file-names):
+ * lisp/emulation/viper.el (viper-mode):
+ * lisp/ffap.el (ffap-menu-ask): Remove references to deleted files.
+
+2020-05-15 Dmitry Gutov <dgutov@yandex.ru>
+
+ Improve detection of Git submodules
+
+ * lisp/progmodes/project.el (project-try-vc):
+ Improve detection of Git submodules
+ (https://lists.gnu.org/archive/html/emacs-devel/2020-05/msg02008.html).
+
+2020-05-14 Andrea Corallo <akrl@sdf.org>
+
+ Render all immediates as comments at comp-debug > 2
+
+ * src/comp.c (emit_mvar_rval): No reason to emit only fixnums.
+
+2020-05-14 Andrea Corallo <akrl@sdf.org>
+
+ Dump log and intemediate GCC IRs only at comp-debug 3
+
+ * src/comp.c (Fcomp__init_ctxt): Increase threshold for dumping
+ really everything to 'comp-debug' 3.
+
+2020-05-14 Andrea Corallo <akrl@sdf.org>
+
+ Prune now unnecessary byte-code objects
+
+ * lisp/emacs-lisp/comp.el (comp-finalize-container): Prune
+ byte-code that was lambdas.
+ (comp-compile-ctxt-to-file): Remove fixme.
+
+2020-05-14 Andrea Corallo <akrl@sdf.org>
+
+ Rework comp-spill-lap-function
+
+ * lisp/emacs-lisp/comp.el (comp-spill-lap-function): Move code
+ from to comp-intern-func-in-ctxt.
+ (comp-intern-func-in-ctxt): New function, this guard
+ in case byte-to-native-lambda-byte-func is nil.
+
+2020-05-14 Andrea Corallo <akrl@sdf.org>
+
+ Split emit_const_lisp_obj logic
+
+ * src/comp.c (emit_lisp_obj_reloc_lval): New function.
+ (emit_const_lisp_obj): Rename into 'emit_lisp_obj_rval' and strip
+ logic for 'emit_lisp_obj_reloc_lval'.
+ (emit_NILP, emit_CHECK_CONS, emit_mvar_rval, emit_set_internal)
+ (define_CAR_CDR, define_bool_to_lisp_obj): Update for
+ 'emit_const_lisp_obj' being renamed.
+
+2020-05-14 Andrea Corallo <akrl@sdf.org>
+
+ Rename emit_mvar_access -> emit_mvar_lval
+
+ * src/comp.c (emit_mvar_access): Rename into 'emit_mvar_lval'.
+ (emit_mvar_rval, emit_frame_assignment): Update for
+ 'emit_mvar_access' rename.
+
+2020-05-14 Andrea Corallo <akrl@sdf.org>
+
+ Rename emit_mvar_val -> emit_mvar_rval
+
+ * src/comp.c (emit_mvar_val): Rename into 'emit_mvar_rval'.
+ (emit_set_internal, emit_simple_limple_call, emit_limple_insn)
+ (emit_call_with_type_hint, emit_call2_with_type_hint)
+ (emit_consp, emit_numperp, emit_integerp): Update for
+ 'emit_mvar_val' rename.
+
+2020-05-14 Andrea Corallo <akrl@sdf.org>
+
+ Indentation fix
+
+ * src/comp.c (Fcomp__init_ctxt, Fcomp__release_ctxt)
+ (Fcomp__compile_ctxt_to_file, Fcomp__register_subr): Indentation
+ fix.
+
+2020-05-14 Andrea Corallo <akrl@sdf.org>
+
+ Update spill LAP machinery and compile anonymous lambdas
+
+ * lisp/emacs-lisp/comp.el (comp-spill-lap-function): Make use of
+ byte-to-native-lambdas-h and update for 'byte-to-native-func-def'.
+ (comp-spill-lap-function): Rework logic to retrieve LAP using
+ 'byte-to-native-lambdas-h'.
+ (comp-emit-for-top-level): Update for 'byte-to-native-function'.
+
+ * lisp/emacs-lisp/bytecomp.el: Add commentary on new spill LAP
+ mechanism.
+ (byte-to-native-lambda, byte-to-native-func-def): New structures.
+ (byte-to-native-top-level): Indent.
+ (byte-to-native-lambdas-h): Update doc.
+ (byte-compile-lapcode): Add a 'byte-to-native-lambda' instance
+ into byte-to-native-lambdas-h instead of just LAP.
+ (byte-compile-file-form-defmumble): Store into
+ 'byte-to-native-func-def' only the byte compiled function, the LAP
+ will be retrieved through 'byte-to-native-lambdas-h'.
+ (byte-compile-lambda): Return the byte compiled function.
+
+2020-05-14 Tino Calancha <tino.calancha@gmail.com>
+
+ Combine archive-int-to-mode and tar-grind-file-mode
+
+ Add a new function, file-modes-number-to-symbolic.
+ Make archive-int-to-mode and obsolete alias of it; use it
+ to define tar-grind-file-mode (Bug#27952).
+
+ * lisp/files.el (file-modes-number-to-symbolic): New defun.
+ * lisp/arc-mode.el (archive-int-to-mode): Make it an obsolete alias.
+ * lisp/tar-mode.el (tar-grind-file-mode):
+ Use file-modes-number-to-symbolic.
+
+ * test/lisp/arc-mode-tests.el (arc-mode-test-archive-int-to-mode)
+ * test/lisp/tar-mode-tests.el (tar-mode-test-tar-grind-file-mode):
+ Update test.
+
+ * test/lisp/files-tests.el (files-tests-file-modes-symbolic-to-number)
+ (files-tests-file-modes-number-to-symbolic): New tests.
+
+ * doc/lispref/files.texi (Changing Files): Document the new function.
+ * etc/NEWS (Lisp Changes in Emacs 28.1): Announce it.
+
+2020-05-14 Mattias Engdegård <mattiase@acm.org>
+
+ Fix customisation of mouse-drag-and-drop-region (bug#41251)
+
+ Reported by David Ponce.
+
+ * lisp/mouse.el (mouse-drag-and-drop-region): Add missing unquote.
+
+2020-05-14 Mattias Engdegård <mattiase@acm.org>
+
+ Calc: fix LU decomposition for non-numeric matrices (bug#41223)
+
+ Computing determinant and inverse for on some matrices containing
+ non-numeric elements failed or gave the wrong result.
+ Reported by Mauro Aranda.
+
+ * lisp/calc/calc-mtx.el (math-do-matrix-lud): Don't use zero as pivot.
+ * test/lisp/calc/calc-tests.el (calc-matrix-determinant): New test.
+
+2020-05-14 Andrea Corallo <akrl@sdf.org>
+
+ * test/src/comp-tests.el (comp-tests-bootstrap): Fix test.
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-05-13 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix some oddities, uncovered by Tramp tests
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-enabled): Prevent crash for
+ older Emacsen.
+
+ * lisp/net/tramp.el (tramp-process-running-p): Simplify.
+
+ * test/lisp/net/tramp-tests.el (tramp-test28-process-file): Adapt test.
+ (tramp-test33-environment-variables): Unset "INSIDE_EMACS" initially.
+
+2020-05-13 João Távora <joaotavora@gmail.com>
+
+ Turn Eldoc, Xref and Project into GNU ELPA :core packages
+
+ The new packages state they require Emacs 26.3 to function, but a
+ small part of project.el breaks this "soft" rule: the two functions
+ requiring fileloop.el are incompatible with Emacs 26.3.
+
+ * lisp/jsonrpc.el: Tweak comment near Package-Requires.
+
+ * lisp/emacs-lisp/eldoc.el: Add Version and Package-Requires.
+
+ * lisp/progmodes/flymake.el: Add comment near Package-Requires.
+
+ * lisp/progmodes/project.el: Add Version and Package-Requires.
+
+ * lisp/progmodes/xref.el: Add Version and Package-Requires.
+
+2020-05-13 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in t-mouse.el
+
+ * lisp/t-mouse.el: Use lexical-binding.
+
+2020-05-13 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in animate.el and add tests
+
+ * lisp/play/animate.el: Use lexical-binding.
+ * test/lisp/play/animate-tests.el: New file.
+
+2020-05-13 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in dissociate.el and add tests
+
+ * lisp/play/dissociate.el: Use lexical-binding.
+ * test/lisp/play/dissociate-tests.el: New file.
+
+2020-05-13 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in cal-julian.el and add tests
+
+ * lisp/calendar/cal-julian.el: Use lexical-binding.
+ * test/lisp/calendar/cal-julian-tests.el: New file.
+
+2020-05-13 Paul Eggert <eggert@cs.ucla.edu>
+
+ Use proper digraphs in Bahá’í month names
+
+ * lisp/calendar/cal-bahai.el (calendar-bahai-month-name-array):
+ There doesn’t seem to be any disagreement in the sources I
+ consulted that “Mas͟híyyat” and “S͟haraf” both need an “s͟h” digraph
+ instead of plain “sh”.
+
+2020-05-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/syntax.el: Fix bug#41195
+
+ Allow use of `syntax-ppss-flush-cache` in `syntax-propertize-function`.
+
+ (syntax-propertize--inhibit-flush): New var.
+ (syntax-propertize): Bind it.
+ (syntax-ppss-flush-cache): Test it.
+
+2020-05-12 Michael Heerdegen <michael_heerdegen@web.de>
+
+ Revert "Inhibit modification hooks when saving eieio-persistent's"
+
+ This reverts commit c59e878439833d89998e03134ee9060f9c449fd9.
+
+2020-05-12 Stefan Kangas <stefankangas@gmail.com>
+
+ Support sorting timer-list-mode by column (Bug#40854)
+
+ * lisp/emacs-lisp/timer-list.el (timer-list-mode)
+ (timer-list--idle-predicate, timer-list--next-predicate)
+ (timer-list--repeat-predicate)
+ (timer-list--function-predicate): Add support for sorting by column.
+
+2020-05-12 Stefan Kangas <stefankangas@gmail.com>
+
+ Base timer-list-mode on tabulated-list-mode (Bug#40854)
+
+ * lisp/emacs-lisp/timer-list.el (list-timers)
+ (timer-list-mode): Inherit from 'tabulated-list-mode' instead of
+ 'special-mode' and make the necessary changes to support that.
+
+ * doc/lispref/os.texi (Timers): Update documentation.
+
+2020-05-12 Glenn Morris <rgm@gnu.org>
+
+ Suppress test failure on hydra.nixos.org
+
+ * test/lisp/net/tramp-tests.el (tramp-test28-process-file):
+ Attempt to suppress hydra oddity.
+
+2020-05-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify GCC 10.1.0
+
+ Pacify GCC 10.1.0 so that it does not issue false alarms
+ when Emacs is configured with --enable-gcc-warnings.
+ * src/dispnew.c (clear_glyph_row):
+ * src/fns.c (hash_clear):
+ * src/keyboard.c (append_tab_bar_item):
+ * src/lisp.h (vcopy):
+ * src/xfaces.c (get_lface_attributes_no_remap)
+ (Finternal_copy_lisp_face, realize_default_face):
+ * src/xmenu.c (set_frame_menubar):
+ Work around -Warray-bounds false alarm in GCC 10.1.0.
+ * src/intervals.c (copy_properties):
+ Avoid -Wnull-dereference false alarm in GCC 10.1.0.
+ * src/lisp.h (xvector_contents_addr, xvector_contents):
+ New functions, useful for working around GCC bug 95072.
+
+2020-05-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from gnulib
+
+ This incorporates:
+ 2020-05-11 careadlinkat: fix GCC 10 workaround
+ 2020-05-10 careadlinkat: limit GCC workaround
+ 2020-05-10 attribute: clarify list of attributes
+ 2020-05-10 string: fix compilation error in C++ mode
+ 2020-05-09 manywarnings: port to GCC 10.1
+ 2020-05-09 careadlinkat: pacify -Wreturn-local-addr
+ 2020-05-09 attribute: remove ATTRIBUTE_DEPRECATED
+ 2020-05-09 attribute: Add comments
+ * lib/attribute.h, lib/careadlinkat.c, lib/string.in.h:
+ * lib/warn-on-use.h, m4/manywarnings.m4: Copy from Gnulib.
+
+2020-05-11 Alan Mackenzie <acm@muc.de>
+
+ Fix bug #40992 whilst still allowing breakpoint highlights in edebug
+
+ Strategy: when an instrumented function gets re-evaluated, save the former
+ value of its symbol's `edebug' property in the new propery `ghost-edebug'. If
+ this function is still being edebugged, edebug will then access its info from
+ this new property.
+
+ Also fix the bug whereby compile-defun'ing an instrumented function prevents
+ the function being re-instrumented by I (edebug-instrument-callee).
+
+ * lisp/emacs-lisp/edebug.el (edebug-get-edebug-or-ghost): New function.
+ (edebug-read-and-maybe-wrap-form1): save value of `edebug' property in
+ 'ghost-edebug'.
+ (edebug-make-form-wrapper): Set value of `ghost-edebug' to nil.
+ (edebug-make-form-wrapper, edebug-find-stop-point, edebug-next-break-point)
+ (edebug-modify-breakpoint, edebug--overlay-breakpoints, edebug-set-breakpoint)
+ (edebug-unset-breakpoints, edebug-toggle-disable-breakpoint)
+ (edebug--backtrace-goto-source, edebug-display-freq-count)
+ (edebug-set-conditional-breakpoint): Use edebug-get-edebug-or-ghost to access
+ edebug information.
+ (edebug-instrument-function): Also check a function is a cons before declaring
+ it "already instrumented".
+
+2020-05-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/pcase.el (pcase--fgrep): Look inside vectors
+
+2020-05-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/textmodes/bibtex.el: Avoid `eval`
+
+ In the top-level construction of the entry-type commands,
+ use `defalias` instead of (eval `(defun ...)).
+
+ (bibtex-insert-kill): Strength reduce `eval` => `symbol-value`.
+ (bibtex-autokey-before-presentation-function): Avoid nil value.
+
+2020-05-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/subr.el (dolist, dotimes, combine-change-calls): Cosmetic tweaks
+
+ (dolist, dotimes): Adjust comment since testing
+ `lexical-binding` is supposed to be reliable.
+ (combine-change-calls): Add debug and indent specs.
+
+2020-05-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/syntax.el (syntax-propertize): Use run-hook-wrapped
+
+ This way we avoid making assumptions about the content of
+ syntax-propertize-extend-region-functions
+
+2020-05-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/ielm.el: Handle corner case where */**/*** are not yet bound
+
+ Remote redundant :group args.
+
+ (ielm-eval-input): Use bound-and-true-p for */**/***
+
+2020-05-11 Dmitry Gutov <dgutov@yandex.ru>
+
+ Map "mail/compose" icon to "mail-message-new" in GTK
+
+ * lisp/term/x-win.el (x-gtk-stock-map): One more icon mapping.
+
+2020-05-11 Dmitry Gutov <dgutov@yandex.ru>
+
+ Use the "modern" toolbars in Gnus again
+
+ * lisp/gnus/gmm-utils.el (gmm-tool-bar-style):
+ Undo the breakage from commit d88118db37dd
+ (https://lists.gnu.org/archive/html/emacs-devel/2020-04/msg02094.html).
+
+2020-05-11 Dmitry Gutov <dgutov@yandex.ru>
+
+ Use better icons on GTK in message-mode and isearch
+
+ * lisp/gnus/message.el (message-tool-bar-retro):
+ Use non-Gnus-specific icon.
+
+ * lisp/term/x-win.el (x-gtk-stock-map):
+ Use more themed icons (bug#40990).
+
+2020-05-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/pcase.el: Don't bind unused vars in branches
+
+ (pcase--fgrep): Change calling convention to take bindings rather than
+ just variables.
+ (pcase--funcall, pcase--eval): Adjust to this new calling convention.
+ (pcase--expand): Use `pcase--fgrep` to bind only the vars that are used.
+
+2020-05-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/eieio.el (eieio pcase macro): Fix last-minute typo
+
+2020-05-10 Tassilo Horn <tsdh@gnu.org>
+
+ Prefer function-put over put for setting browse-url-browser-kind.
+
+ * lisp/net/browse-url.el: Prefer `function-put' over `put' for setting
+ `browse-url-browser-kind' symbol property.
+
+2020-05-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/eieio.el (eieio pcase macro): Remove unused var `is`
+
+2020-05-10 Simen Heggestøyl <simenheg@gmail.com>
+
+ Use lexical-binding in glasses.el and add tests
+
+ * lisp/progmodes/glasses.el: Use lexical-binding.
+ (glasses-separator, glasses-original-separator, glasses-face)
+ (glasses-separate-parentheses-p)
+ (glasses-separate-parentheses-exceptions)
+ (glasses-separate-capital-groups, glasses-uncapitalize-p)
+ (glasses-uncapitalize-regexp, glasses-convert-on-write-p): Remove
+ redundant :group args.
+
+ * test/lisp/progmodes/glasses-tests.el: New file with tests for
+ glasses.el.
+
+2020-05-10 Simen Heggestøyl <simenheg@gmail.com>
+
+ Allow underscores in CSS variable names
+
+ * lisp/textmodes/css-mode.el (css-nmchar-re): Allow underscores in
+ variable names (and in identifiers in general).
+
+ * test/manual/indent/css-mode.css: Add some examples of variable names
+ with underscores in them.
+
+ * test/manual/indent/less-css-mode.less: Add some examples of variable
+ names with underscores in them.
+
+ * test/manual/indent/scss-mode.scss: Add some examples of variable
+ names with underscores in them.
+
+2020-05-10 Simen Heggestøyl <simenheg@gmail.com>
+
+ Add containment module to CSS property list
+
+ * lisp/textmodes/css-mode.el (css-property-alist): Add new properties
+ from CSS Containment Module Level 1.
+
+2020-05-10 Simen Heggestøyl <simenheg@gmail.com>
+
+ Add writing modes module to CSS property list
+
+ * lisp/textmodes/css-mode.el (css-property-alist): Add new properties
+ from the CSS Writing Modes Level 3 module.
+
+2020-05-10 Andrea Corallo <akrl@sdf.org>
+
+ Fix `comp-deferred-compilation-black-list' effectiveness
+
+ * lisp/emacs-lisp/comp.el (native-compile-async): Fix logic for
+ 'comp-deferred-compilation-black-list' effectiveness.
+
+2020-05-10 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (load_comp_unit): Style fix.
+
+2020-05-09 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-05-09 Andrea Corallo <akrl@sdf.org>
+
+ Fix --enable-check-lisp-object-type GNU/Linux X86_64 build
+
+ * src/comp.c (emit_mvar_val): Fix missing use of XLP macro.
+ (load_comp_unit): Fix missing use of NILP macro.
+
+2020-05-09 Simen Heggestøyl <simenheg@gmail.com>
+
+ Use lexical-binding in help-mode.el and add tests
+
+ * lisp/help-mode.el: Use lexical-binding.
+ (help-mode-map, help-mode-menu, help-mode-setup)
+ (help-mode-finish): Make spelling of "Help mode" consistent throughout
+ the doc strings (also making it consistent with the spelling of "Help
+ mode" used in the Elisp manual).
+ (help-do-xref): Re-indent to make the else-branch easier to see.
+
+ * test/lisp/help-mode-tests.el: New file with tests for help-mode.el.
+
+2020-05-09 Glenn Morris <rgm@gnu.org>
+
+ * src/xdisp.c (Fwindow_text_pixel_size): Fix previous merge.
+
+2020-05-09 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ be0d1cac83 (origin/emacs-27) Small fix for type of 'display-fill-colu...
+ c5e5839776 Fix customization of 'display-fill-column-indicator-charac...
+ d5c184aa3e Refer to fill column indicator Info node in some places.
+ e13300ae50 Merge branch 'emacs-27' of git.sv.gnu.org:/srv/git/emacs i...
+ 0bae57033f Fix GTK's Tool Bar menu radio buttons
+ 4c98aa7ea5 Minor clarifications in NEWS
+ a1cbd05f38 Improve documentation of 'with-suppressed-warnings'.
+ 4a895c1b26 Fix a typo in a comment
+ 2caf3e997e Improve documentation of Hi Lock mode
+ 7081c1d66f Fix typos in the Emacs user manual
+ 0385771e2f Fix references to Speedbar in VHDL mode
+ a76cafea0d Fix handling of FROM = t and TO = t by 'window-text-pixel-...
+
+ # Conflicts:
+ # etc/NEWS
+ # src/xdisp.c
+
+2020-05-09 Pieter van Oostrum <pieter@vanoostrum.org>
+
+ Add new filter command to Package Menu (Bug#39903)
+
+ * lisp/emacs-lisp/package.el
+ (package-menu-filter-marked): New filter command.
+ * test/lisp/emacs-lisp/package-tests.el
+ (package-test-list-filter-marked): New test.
+ (package-menu-mode-menu):
+ (package-menu-mode-map): Update menu to include new filter command.
+
+ * doc/emacs/package.texi (Package Menu): Document the new command.
+ * etc/NEWS: Announce the new command.
+
+2020-05-09 Paul Eggert <eggert@cs.ucla.edu>
+
+ Improve nonnull checking with GCC in emacs-module
+
+ * src/emacs-module.h.in (EMACS_ATTRIBUTE_NONNULL):
+ Also do the nonnull check with GCC. (The old code did the
+ check with Clang but not with GCC.)
+
+2020-05-09 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-05-09 stdio: don't redefine _GL_ATTRIBUTE_FORMAT
+ 2020-05-09 dirent, stdlib, string: don't redefine _GL_ATTRIBUTE_PURE
+ 2020-05-08 limits-h: define LONG_BIT correctly on Haiku/x86_64
+ 2020-05-08 ignore-value tests: use module 'attribute'
+ 2020-05-06 attribute: minor style fixes
+ * build-aux/config.sub, doc/misc/texinfo.tex, lib/attribute.h:
+ * lib/dirent.in.h, lib/limits.in.h, lib/stdio.in.h, lib/stdlib.in.h:
+ * lib/string.in.h, m4/gnulib-common.m4:
+ Copy from Gnulib.
+
+2020-05-09 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-05-09 Andrea Corallo <akrl@sdf.org>
+
+ Add 'comp-deferred-compilation-black-list' customize
+
+ * lisp/emacs-lisp/comp.el (comp-deferred-compilation-black-list):
+ New customize.
+ (native-compile-async): Make use of
+ 'comp-deferred-compilation-black-list'.
+
+2020-05-09 Michal Nazarewicz <mina86@mina86.com>
+
+ cc-mode: extend regexp used by ‘c-or-c++-mode’
+
+ * lisp/progmodes/cc-mode.el (c-or-c++-mode--regexp): Expand the regexp to
+ match some more C++-only constructs and recognise a few more standard
+ C++ header files. Also make sure identifiers start with non-digit.
+ (c-or-c++-mode): Add ‘(interactive)’ declaration.
+
+ * test/lisp/progmodes/cc-mode-tests.el (c-or-c++-mode): Add test case
+ for the newly recognised constructs.
+
+2020-05-09 Michal Nazarewicz <mina86@mina86.com>
+
+ cc-mode: add ‘c-lineup-ternary-bodies’ (bug#41061)
+
+ Introduce ‘c-lineup-ternary-bodies’ function which, when used as
+ a c lineup function, aligns question mark and colon of a ternary
+ operator. For example:
+
+ return arg % 2 == 0 ? arg / 2
+ : (3 * arg + 1);
+
+ * lisp/progmodes/cc-align.el (c-lineup-ternary-bodies): New function.
+ * doc/misc/cc-mode.texi (Operator Line-Up Functions): Document the
+ new function.
+ * test/lisp/progmodes/cc-mode-tests.el (c-lineup-ternary-bodies): New
+ test case.
+
+2020-05-09 Clément Pit-Claudel <clement.pitclaudel@live.com>
+
+ Only treat display strings as buttons if they have 'button' property
+
+ * lisp/button.el (push-button): Use 'posn-point' instead of
+ 'posn-string' if the string doesn't have the 'button'
+ property (Bug#40859).
+
+2020-05-09 Federico Tedin <federicotedin@gmail.com>
+
+ Prevent hanging in next-single-char-property-change
+
+ * src/textprop.c (Fnext_single_char_property_change): Clarify in
+ the doc string the behavior when LIMIT is past the end of OBJECT.
+ Stop the search when position gets to end of buffer, for when LIMIT
+ is beyond that. (Bug#40000)
+
+2020-05-08 Tassilo Horn <tsdh@gnu.org>
+
+ Fix reading kind argument in browse-url-with-browser-kind.
+
+ * lisp/net/browse-url.el (browse-url-with-browser-kind): Convert KIND
+ argument queried from the user to a symbol.
+
+2020-05-08 Tassilo Horn <tsdh@gnu.org>
+
+ Allow predicates for matching in browse-url-handlers.
+
+ * lisp/net/browse-url.el (browse-url-handlers): Allow predicates for
+ matching in browse-url-handlers. Adapt docs and customize type.
+ (browse-url-select-handler): Support predicates in addition to
+ regexes.
+ (browse-url--non-html-file-url-p): New defun.
+ (browse-url-default-handlers): Use above predicate entry instead of
+ two entries.
+
+2020-05-08 Zhu Zihao <all_but_last@163.com>
+
+ Make pcase pattern 'eieio' respect slot access related functions.
+
+ * lisp/emacs-lisp/eieio.el: Make pcase pattern respect slot-missing and
+ slot-unbound
+
+2020-05-07 Tassilo Horn <tsdh@gnu.org>
+
+ Allow browsing an URL explicitly with an internal or external browser.
+
+ * lisp/net/browse-url.el (browse-url-with-browser-kind): New command.
+
+2020-05-07 Tassilo Horn <tsdh@gnu.org>
+
+ Categorize browse-url functions into internal and external ones.
+
+ * lisp/net/browse-url.el: Write package documentation explaining
+ browse-url-browser-kind symbol property. Categorize existing
+ browse-url functions into internal and external ones.
+ (browse-url--browser-kind, browse-url--browser-kind-mailto)
+ (browse-url--browser-kind-man, browse-url--browser-kind-browser): New
+ functions.
+ (browse-url-select-handler): Add KIND argument to restrict selection.
+ * lisp/dnd.el (dnd-handle-one-url): Only select browse-url handler of
+ kind `internal'.
+ * lisp/net/eww.el (eww): Add `browse-url-browser-kind' symbol property
+ with value `internal'.
+
+2020-05-07 Noam Postavsky <npostavs@gmail.com>
+
+ Don't increment array index in cl-loop twice (Bug#40727)
+
+ * lisp/emacs-lisp/cl-macs.el (cl--parse-loop-clause): Put the temp-idx
+ increment in cl--loop-body, leaving just the side-effect free testing
+ of the index for both cl--loop-body and cl--loop-conditions.
+ * test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs-loop-and-arrays):
+ Extend test to cover this case.
+
+2020-05-07 Noam Postavsky <npostavs@gmail.com>
+
+ Revert "cl-loop: Calculate the array length just once"
+
+ It fails when using 'and' (parallel bindings) for arrays (Bug#40727).
+ * lisp/emacs-lisp/cl-macs.el (cl--parse-loop-clause): Revert to
+ recomputing array length.
+ * test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs-loop-and-arrays): New
+ test.
+
+2020-05-07 Tassilo Horn <tsdh@gnu.org>
+
+ Fix browse-url (remove debugging leftover).
+
+ * lisp/net/browse-url.el (browse-url): Fix "No suitable browser for
+ URL" always popping up.
+
+2020-05-07 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-05-07 Andrea Corallo <akrl@sdf.org>
+
+ Fix bug#41112
+
+ * lisp/emacs-lisp/comp.el (comp-jump-table-optimizable): New
+ function.
+ (comp-emit-switch): Make use of 'comp-jump-table-optimizable'.
+
+2020-05-07 Michael Albinus <michael.albinus@gmx.de>
+
+ Handle signals in Tramp's process-file
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-process-file):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-process-file): Handle signals.
+
+ * test/lisp/net/tramp-tests.el (tramp-test28-process-file): Adapt test.
+
+2020-05-07 Tassilo Horn <tsdh@gnu.org>
+
+ Refactor browse-url handler selection into separate function.
+
+ * lisp/net/browse-url.el (browse-url-select-handler): New function.
+ (browse-url): Use it.
+ * lisp/dnd.el (dnd-handle-one-url): Use it.
+
+2020-05-06 Tassilo Horn <tsdh@gnu.org>
+
+ Restore HTML rendering behavior of browse-url-of-buffer/file.
+
+ * lisp/net/browse-url.el (browse-url-default-handlers): Add a browser
+ handler for HTML page file:// URLs before the generic file:// handler.
+ (browse-url--browser): New defun.
+
+2020-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-05-06 Andrea Corallo <akrl@sdf.org>
+
+ Add native compilation unit black list
+
+ * lisp/emacs-lisp/comp.el (comp-bootstrap-black-list): New customize.
+ (batch-native-compile): Rework to make use of
+ 'comp-bootstrap-black-list'.
+ (batch-byte-native-compile-for-bootstrap): Add assertion to make
+ logic assumption explicit.
+
+2020-05-06 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify buggy old GCC with a cast
+
+ * src/bignum.h (bignum_integer): Pacify GCC 4.8.5.
+ Problem reported by Andreas Schwab in:
+ https://lists.gnu.org/r/emacs-devel/2020-05/msg00781.html
+
+2020-05-06 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 76516465bf (origin/emacs-27) * doc/emacs/modes.texi (Major Modes): Fi...
+ f8e6cd11b3 Fix docstring quoting
+
+2020-05-06 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 7be160d800 Improve "Help Summary" section in user manual
+ f6d6ccc984 Clarify message-sendmail-extra-arguments docstring
+ 95fde1a851 * src/editfns.c (Fformat): Small documentation fix.
+
+2020-05-06 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 4b419083f9 Honor search-upper-case
+ 310112fdc7 Fix eww-follow-link on URLs with #target
+
+ # Conflicts:
+ # lisp/fileloop.el
+
+2020-05-06 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ f9fa726ced Improve doc strings of makunbound and fmakunbound
+
+2020-05-06 Tassilo Horn <tsdh@gnu.org>
+
+ Consult browse-url-{default-,}handlers in drag&drop.
+
+ * lisp/dnd.el (dnd-handle-one-url): Consult `browse-url-handlers' and
+ `browse-url-default-handlers' for a matching handler. Adapt
+ docstring.
+ * doc/lispref/frames.texi (Drag and Drop): Remove the docs for the
+ deprecated alist choice of `browse-url-browser-function' and mention
+ `browse-url-handlers' and `browse-url-default-handlers'.
+
+2020-05-06 Michael Albinus <michael.albinus@gmx.de>
+
+ process-file in Tramp must return exit code (Bug#41099)
+
+ * lisp/net/tramp-adb.el (tramp-adb-send-command-and-check): Add optional
+ argument EXIT-STATUS.
+ (tramp-adb-handle-process-file): Use it.
+
+ * lisp/net/tramp-sh.el (tramp-send-command-and-check): Add optional
+ argument EXIT-STATUS.
+ (tramp-sh-handle-process-file): Use it. (Bug#41099)
+
+ * test/lisp/net/tramp-tests.el (tramp-test28-process-file): Adapt test.
+
+2020-05-06 Tassilo Horn <tsdh@gnu.org>
+
+ Allow for custom URL handlers in browse-url.
+
+ * lisp/net/browse-url.el (browse-url-handlers): New defcustom.
+ (browse-url-default-handlers): New defvar.
+ (browse-url): Use them. Adapt docstring. Issue a warning pointing to
+ browse-url-handlers when browse-url-browser-function is an alist.
+ (browse-url--mailto, browse-url--man): New functions.
+ (browse-url--browser-defcustom-type): Add :doc that the alist usage is
+ deprecated.
+ (browse-url-browser-function): Remove documentation referring to the
+ alist usage and mention browse-url-handlers.
+ * doc/emacs/misc.texi: Document browse-url-handlers in Browse-URL
+ node.
+ * etc/NEWS: Mention browse-url-default-handlers and
+ browse-url-handlers.
+
+2020-05-06 Stefan Kangas <stefankangas@gmail.com>
+
+ Prefer 'strong' and 'em' to 'b' and 'i' in html-mode
+
+ * lisp/textmodes/sgml-mode.el (html-face-tag-alist): Prefer inserting
+ 'strong' and 'em' tags to 'b' and 'i' in html-mode. (Bug#41031)
+ * lisp/textmodes/sgml-mode.el (html-mode): Update docstring to do the
+ same.
+
+2020-05-06 Paul Eggert <eggert@cs.ucla.edu>
+
+ Don’t assume __has_attribute in emacs-module.c
+
+ Problem reported by Glenn Morris in:
+ https://lists.gnu.org/r/emacs-devel/2020-05/msg00724.html
+ * src/emacs-module.c: Use HAS_ATTRIBUTE instead of assuming
+ the compiler supports __has_attribute.
+
+2020-05-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Try and improve the *Help* layout for things like `diff-refine`.
+
+ * lisp/help-fns.el (describe-variable-custom-version-info): Follow the
+ usual format of other `help-fns-describe-variable-functions`.
+
+2020-05-05 Andrea Corallo <akrl@sdf.org>
+
+ * configure.ac: Fix var usage + better messaging.
+
+2020-05-05 Andrea Corallo <akrl@sdf.org>
+
+ * configure.ac: Better messaging when libgccjit fails smoke test
+
+ * configure.ac: Fix libgccjit test LDFLAGS plus better messaging
+ in case of its fail.
+
+2020-05-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix typos in recent attribute.h simplification
+
+ Problem reported by Andreas Schwab in:
+ https://lists.gnu.org/r/emacs-devel/2020-05/msg00650.html
+ * src/conf_post.h (HAS_ATTR_no_sanitize): Define to false in case
+ cpp is picky, fixing a longstanding glitch here.
+ (ATTRIBUTE_NO_SANITIZE_ADDRESS, ATTRIBUTE_NO_SANITIZE_UNDEFINED):
+ Use HAS_ATTRIBUTE, not __has_attribute.
+
+2020-05-04 Andrea Corallo <akrl@sdf.org>
+
+ * configure.ac: Add a better libgccjit test plus some morw err message
+
+ * configure.ac (libgccjit_smoke_test, libgccjit_not_found)
+ (libgccjit_broken): New functions.
+
+2020-05-04 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-05-04 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt Tramp tests
+
+ * test/lisp/net/tramp-tests.el (tramp-test33-environment-variables):
+ Adapt test.
+
+2020-05-04 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix setting of INSIDE_EMACS in Tramp
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process)
+ (tramp-sh-handle-process-file, tramp-open-shell): Set proper
+ INSIDE_EMACS environment variable.
+
+2020-05-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Simplify by using attribute.h macros
+
+ attribute.h is partly designed for C2X forward compatibility,
+ since C2X will add some standard attributes. Using its macros
+ should help insulate Emacs from C2X teething problems.
+ * src/conf_post.h: Include attribute.h.
+ (HAS_ATTRIBUTE, HAS_FEATURE): Rename from __has_attribute and
+ __has_feature, to avoid polluting the builtin namespace.
+ All uses changed.
+ (ATTRIBUTE_COLD, ATTRIBUTE_FORMAT, FALLTHROUGH, ATTRIBUTE_CONST)
+ (ATTRIBUTE_PURE, ATTRIBUTE_UNUSED, ATTRIBUTE_MAY_ALIAS)
+ (ATTRIBUTE_MALLOC, ATTRIBUTE_ALLOC_SIZE)
+ (ATTRIBUTE_RETURNS_NONNULL): Remove, as attribute.h does this now.
+ (NO_INLINE, EXTERNALLY_VISIBLE, ARG_NONNULL, ATTRIBUTE_UNUSED):
+ Simplify by defining in terms of attribute.h macros.
+ * src/systhread.h (ATTRIBUTE_WARN_UNUSED_RESULT): Remove.
+ All uses replaced by attribute.h’s NODISCARD.
+
+2020-05-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-05-03 attribute: new module
+ 2020-04-13 explicit_bzero: improve code style
+ 2020-04-13 explicit_bzero: On native Windows, use SecureZeroMemory
+ 2020-04-13 explicit_bzero: use memset_s() when available
+ 2020-04-04 maint: remove a stray inter-word space
+ * build-aux/config.guess, build-aux/config.sub:
+ * build-aux/gitlog-to-changelog, build-aux/update-copyright:
+ * doc/misc/texinfo.tex, lib/explicit_bzero.c, lib/ieee754.in.h:
+ * lib/nstrftime.c, m4/explicit_bzero.m4, m4/gnulib-common.m4:
+ Copy from Gnulib.
+ * lib/attribute.h: New file, copied from Gnulib.
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+
+2020-05-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/eieio.el (oset, oset-default): Mark as obsolete
+
+2020-05-03 Simen Heggestøyl <simenheg@gmail.com>
+
+ Use lexical-binding in check-declare.el and add tests
+
+ * lisp/emacs-lisp/check-declare.el: Use lexical-binding.
+ (check-declare-warn): Silence byte compiler warning about unused
+ lexical argument.
+
+ * test/lisp/emacs-lisp/check-declare-tests.el: New file with tests
+ for check-declare.el.
+
+2020-05-03 Mattias Engdegård <mattiase@acm.org>
+
+ Fix calculator division truncation (bug#40892)
+
+ * lisp/calculator.el (calculator-string-to-number): Convert decimal
+ numbers input to float, fixing a regression introduced in f248292ede.
+ Reported by Aitor Soroa.
+
+2020-05-03 Alan Third <alan@idiocy.org>
+
+ Fix initial frame resizing issue on NS (bug#40200)
+
+ * src/nsterm.m ([EmacsView viewDidResize:]): Don't try to determine
+ the old size when not drawing to the buffer.
+
+2020-05-03 Michal Nazarewicz <mina86@mina86.com>
+
+ cc-mode: document Doxygen ‘c-doc-comment-style’ (bug#40877)
+
+ * doc/misc/cc-mode.texi (Documentation Comments): mention Doxygen markup.
+
+2020-05-03 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 0a3731feef Make memq etc. examples more like they were
+ ed25282b82 Document effect of 'search-upper-case' on replacement comm...
+ 5a5d8a8ec0 * lisp/desktop.el (desktop-save): Doc fix. (Bug#41007)
+
+2020-05-03 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 1d477a0fec Recommend to avoid unnecessary abbreviations in doc
+ aea1b4db72 Revert "Fix calculator division truncation (bug#40892)"
+
+2020-05-03 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 1f17193e00 Expand file name for remote dirs as well
+ 7a12ab5ea2 Fix project.el commands in "transient" projects
+ 274ec97e3c Make sure alist-related functions say so in their doc
+
+2020-05-03 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove redundant :groups args missed in last commit
+
+ * lisp/emacs-lisp/cl-indent.el (lisp-lambda-list-keyword-alignment)
+ (lisp-lambda-list-keyword-parameter-indentation)
+ (lisp-lambda-list-keyword-parameter-alignment)
+ (lisp-indent-backquote-substitution-mode): Remove redundant :group args.
+
+2020-05-03 Stefan Kangas <stefankangas@gmail.com>
+
+ Improve indentation of 'loop' forms
+
+ * lisp/emacs-lisp/cl-indent.el (lisp-loop-keyword-indentation)
+ (lisp-loop-forms-indentation, lisp-simple-loop-indentation): Use a
+ more standard indentation of 'loop' forms. (Bug#2160)
+
+ (lisp-indent-maximum-backtracking, lisp-tag-indentation)
+ (lisp-tag-body-indentation, lisp-backquote-indentation)
+ (lisp-loop-keyword-indentation, lisp-loop-forms-indentation)
+ (lisp-simple-loop-indentation): Remove redundant :group args.
+
+2020-05-03 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in w32-vars.el
+
+ * lisp/w32-vars.el: Use lexical-binding.
+ (w32-use-w32-font-dialog, w32-allow-system-shell
+ (w32-system-shells, w32-fixed-font-alist): Remove redundant :group
+ args.
+
+2020-05-03 Eli Zaretskii <eliz@gnu.org>
+
+ Improve accuracy of apropos commands that search doc strings
+
+ It is conceptually wrong for apropos commands that search doc
+ strings to look for matches of several words only on the same
+ line, because division of doc strings between lines is
+ ephemeral.
+ * lisp/apropos.el (apropos-parse-pattern): Accept an optional
+ argument MULTILINE-P, and if that is non-nil, produce regexps that
+ match words in the list even if they are separated by line
+ boundaries.
+ (apropos-value, apropos-local-value, apropos-documentation): Use
+ the new optional argument in apropos commands that search
+ multiline text, such as doc strings.
+
+ * src/search.c (Fposix_looking_at, Fposix_string_match)
+ (Fposix_search_backward, Fposix_search_forward): Make sure Posix
+ appears in the doc strings near REGEXP, for better matches.
+
+2020-05-03 Andrea Corallo <akrl@sdf.org>
+
+ Add a warning for missing write privilege
+
+ * lisp/emacs-lisp/comp.el (native-compile-async): Check for write
+ privilege and raise a warning in case.
+
+2020-05-03 Andrea Corallo <akrl@sdf.org>
+
+ Introduce `comp-output-directory'
+
+ * lisp/emacs-lisp/comp.el (comp-output-directory): New function.
+ (comp-output-base-filename): Use `comp-output-directory'.
+
+2020-05-03 Mattias Engdegård <mattiase@acm.org>
+
+ Regexps cannot infloop; fix manual
+
+ * doc/lispref/searching.texi (Regexp Special): Edit erroneous
+ statements about infinite looping in regexps.
+
+2020-05-03 Michael Albinus <michael.albinus@gmx.de>
+
+ Do not delete asynchronous Tramp processes due to session timeout
+
+ * lisp/net/tramp-cmds.el (tramp-cleanup-connection): New optional
+ argument KEEP-PROCESSES.
+
+ * lisp/net/tramp-sh.el (tramp-timeout-session): Use it. (Bug#41042)
+
+2020-05-03 Michael Albinus <michael.albinus@gmx.de>
+
+ Improve Tramp debug messages
+
+ * lisp/net/tramp-cache.el (tramp-get-file-property)
+ (tramp-get-connection-property): Improve debug messages.
+ Suggested by Marc Herbert <marc.herbert@gmail.com>.
+
+2020-05-02 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding for some term libraries
+
+ This takes care of the most trivial cases, but there are more that
+ could be easily converted.
+
+ * lisp/term/bobcat.el:
+ * lisp/term/cygwin.el:
+ * lisp/term/konsole.el:
+ * lisp/term/linux.el:
+ * lisp/term/vt100.el:
+ * lisp/term/vt200.el: Use lexical-binding.
+
+2020-05-02 Stefan Kangas <stefankangas@gmail.com>
+
+ Improve Info-mode doc and menu
+
+ * lisp/info.el (Info-mode-menu): Re-arrange to be more logical, move
+ items into submenus, add 'Info-directory' and separators.
+ (Info-mode): Add 'end-of-buffer' to doc string. (Bug#39042)
+
+2020-05-02 Michael Albinus <michael.albinus@gmx.de>
+
+ ;; Revert recent change in tramp-cache.el
+
+ * lisp/net/tramp-cache.el (tramp-dump-connection-properties):
+ Remove compatibility code dumping the persistency file. Use
+ `emacs-lisp-mode' for backward compatibility.
+
+2020-05-02 Eli Zaretskii <eliz@gnu.org>
+
+ Fix 'count-screen-lines' when lines are truncated
+
+ * lisp/window.el (count-screen-lines): Fix the return value when
+ lines are truncated in the window, and the end of the region is
+ invisible due to this truncation. (Bug#40849)
+
+2020-05-02 João Távora <joaotavora@gmail.com>
+
+ Properly fix embarrassing missing paren typo in jsonrpc.el
+
+ Paul Eggert had fixed it in practice, but the missing paren
+ was meant to close a previous with-current-buffer.
+
+ * lisp/jsonrpc.el (initialize-instance): Put parenthesis in right spot.
+ (Version): Bump to 1.0.11
+
+2020-05-01 Michael Heerdegen <michael_heerdegen@web.de>
+
+ Inhibit modification hooks when saving eieio-persistent's
+
+ * lisp/emacs-lisp/eieio-base.el (eieio-persistent-save): Bind
+ inhibit-modification-hooks -> t.
+
+2020-05-01 Michal Nazarewicz <mina86@mina86.com>
+
+ cc-mode: add support for Doxygen documentation style
+
+ * lisp/progmodes/cc-fonts.el (doxygen-font-lock-doc-comments,
+ doxygen-font-lock-keywords): New constants defining Doxygen
+ comment style support.
+ * lisp/progmodes/cc-vars.el (c-doc-comment-style): Updated docstring
+ to mention now-supported Doxygen mode.
+
+2020-05-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ * lisp/jsonrpc.el (initialize-instance): Fix closing-paren typo.
+
+2020-05-01 João Távora <joaotavora@gmail.com>
+
+ Consolidate lisp/jsonrpc.el logging in single events buffer
+
+ For inferior processes having useful stderr, it is no longer
+ cumbersome to switch between different buffers to correlate error
+ messages with transport-level JSONRPC messages.
+
+ The existing stderr and stdout buffers can still be found hidden away
+ from the normal buffer list.
+
+ An original idea of Tobias Rittweiler <trittweiler@gmail.com>.
+
+ * lisp/jsonrpc.el (initialize-instance jsonrpc-process-connection):
+ Setup after-change functions stderr buffer. Hide stderr and stdout
+ buffers.
+ (jsonrpc--log-event): Don't output extra newline. Tweak log format.
+ (Version): Bump to 1.0.10
+
+2020-05-01 Alan Mackenzie <acm@muc.de>
+
+ Protect non-selected face spec components in custimize-face. Fixes bug #40866
+
+ * lisp/cus-edit.el (custom-face-save): If the current face widget is only
+ displaying part of the face spec, temporarily set it to "display" the whole
+ spec around the call to custom-face-mark-to-save.
+
+2020-05-01 João Távora <joaotavora@gmail.com>
+
+ Add lisp-data-mode for editing non-code Lisp data
+
+ (Bug#40573)
+
+ The new mode can be used stand-alone or inherited from by modes
+ intended to edit programs. The existing emacs-lisp-mode and lisp-mode
+ are examples.
+
+ Thanks to Juri Linkov and Basil L. Contovounesios for researching some
+ data files in Emacs that can be automatically set to use the new mode.
+
+ * lisp/files.el (auto-mode-alist): Add entry for ".dir-locals" and
+ ".dir-locals-2"
+
+ * lisp/emacs-lisp/lisp-mode.el: (lisp-data-mode): New major mode.
+ (lisp-mode): Inherit from lisp-data-mode. Set special lisp-mode
+ stuff here.
+
+ * lisp/progmodes/elisp-mode.el (emacs-lisp-mode): Inherit from
+ lisp-data-mode.
+
+ * lisp/bookmark.el (bookmark-insert-file-format-version-stamp):
+ Use lisp-data-mode.
+
+ * lisp/saveplace.el (save-place-alist-to-file): Use
+ lisp-data-mode.
+
+ * lisp/net/eww.el (eww-write-bookmarks): Use lisp-data-mode.
+
+ * lisp/net/nsm.el (nsm-write-settings): Use lisp-data-mode.
+
+ * lisp/net/tramp-cache.el (tramp-dump-connection-properties): Use
+ lisp-data-mode.
+
+ * etc/NEWS: Mention lisp-data-mode.
+
+ * doc/lispref/modes.texi (Example Major Modes): Update example.
+
+2020-05-01 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in most remaining tests
+
+ * test/lisp/comint-tests.el:
+ * test/lisp/custom-resources/custom--test-theme.el:
+ * test/lisp/dabbrev-tests.el:
+ * test/lisp/emulation/viper-tests.el:
+ * test/lisp/erc/erc-track-tests.el:
+ * test/lisp/gnus/gnus-tests.el:
+ * test/lisp/imenu-tests.el:
+ * test/lisp/info-xref-tests.el:
+ * test/lisp/jit-lock-tests.el:
+ * test/lisp/json-tests.el:
+ * test/lisp/man-tests.el:
+ * test/lisp/replace-tests.el:
+ * test/lisp/shadowfile-tests.el:
+ * test/lisp/subr-tests.el:
+ * test/lisp/thingatpt-tests.el:
+ * test/lisp/xml-tests.el: Use lexical-binding.
+
+ * test/lisp/man-tests.el (man-tests-filter-strings):
+ * test/lisp/shadowfile-tests.el (shadow-test00-clusters)
+ (shadow-test01-sites, shadow-test06-literal-groups)
+ (shadow-test07-regexp-groups, shadow-test09-shadow-copy-files):
+ Silence byte-compiler.
+
+2020-04-30 Michael Heerdegen <michael_heerdegen@web.de>
+
+ Make `make-local-variable' declare the var locally dynamic
+
+ The only effect of this change is to get rid of some unnecessary
+ "assignment to free variable" warnings.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-make-local-variable): New
+ function.
+
+2020-04-30 Mattias Engdegård <mattiase@acm.org>
+
+ Fix calculator division truncation (bug#40892)
+
+ * lisp/calculator.el (calculator-string-to-number): Convert decimal
+ numbers input to float, fixing a regression introduced in f248292ede.
+ Reported by Aitor Soroa.
+
+2020-04-30 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in most remaining emacs-lisp tests
+
+ * test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el:
+ * test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el:
+ * test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el:
+ * test/lisp/emacs-lisp/faceup-resources/faceup-test-mode.el:
+ * test/lisp/emacs-lisp/faceup-resources/faceup-test-this-file-directory.el:
+ * test/lisp/emacs-lisp/faceup-tests/faceup-test-basics.el:
+ * test/lisp/emacs-lisp/faceup-tests/faceup-test-files.el:
+ * test/lisp/emacs-lisp/package-resources/newer-versions/new-pkg-1.0.el:
+ * test/lisp/emacs-lisp/package-resources/newer-versions/simple-single-1.4.el:
+ * test/lisp/emacs-lisp/package-resources/simple-depend-1.0.el:
+ * test/lisp/emacs-lisp/package-resources/simple-single-1.3.el:
+ * test/lisp/emacs-lisp/package-resources/simple-two-depend-1.1.el:
+ * test/lisp/emacs-lisp/package-tests.el:
+ * test/lisp/emacs-lisp/shadow-resources/p1/foo.el:
+ * test/lisp/emacs-lisp/shadow-resources/p2/FOO.el: Use lexical-binding.
+
+ * test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el
+ (eitest-F, eitest-H, eitest-I, constructor, make-instance)
+ (initialize-instance, CNM-M):
+ * test/lisp/emacs-lisp/package-tests.el (with-package-test)
+ (package-test-update-archives, package-test-signed): Silence byte-compiler.
+
+2020-04-30 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in qp.el and add tests
+
+ * test/lisp/mail/qp-tests.el: New file.
+ * lisp/mail/qp.el: Use lexical-binding.
+
+2020-04-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add new function dom-remove-attribute
+
+ * doc/lispref/text.texi (Document Object Model): Document it.
+
+ * lisp/dom.el (dom-remove-attribute): Add new function.
+
+2020-04-29 Andrea Corallo <akrl@sdf.org>
+
+ Fix async compilation non respecting `comp-always-compile' nil value.
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): Fix missing
+ `comp-output-filename' usage.
+
+2020-04-29 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-04-29 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ Test iso8601-parse-zone vs format-time-string %z
+
+ * test/lisp/calendar/iso8601-tests.el
+ (iso8601-format-time-string-zone-round-trip): New unit test that
+ format-time-string %z and iso8601-parse-zone are inverses.
+ (test-iso8601-format-time-string-zone-round-trip): New helper function.
+
+2020-04-29 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 2f9bfaef21 (origin/emacs-27) ; Fix last change
+ 520fd3e728 * lisp/env.el (substitute-env-vars): Doc fix. (Bug#40948)
+ 85544f8ef5 * lisp/isearch.el: Fix lazy-highlighting and lazy-counting...
+ d83cc05a73 Fix error in ERC when 'erc-server-coding-system' is custom...
+ 16fed05ba8 Avoid crashes on TTY frames with over-long compositions
+ 0278741676 Fix typo in custom.texi
+ 9f5ae717fb * test/lisp/simple-tests.el (with-shell-command-dont-erase...
+ 1f76a16ed3 * lisp/image-mode.el (image-mode-map): Update menu items.
+ f0e1bf56f0 Fix bugs in tab-bar and tab-line and mention remaining fea...
+ f0b9f18457 Make shell-command tests fit for tcsh.
+ 68f4a740a1 Remove doc duplication
+ ac31cd384c * etc/NEWS: Fix inconsistencies.
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-04-29 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in most eshell tests
+
+ * test/lisp/eshell/em-hist-tests.el:
+ * test/lisp/eshell/em-ls-tests.el:
+ * test/lisp/eshell/esh-opt-tests.el: Use lexical-binding.
+
+2020-04-29 Stefan Kangas <stefankangas@gmail.com>
+
+ Add new tests to bindat-tests.el
+
+ * test/lisp/emacs-lisp/bindat-tests.el (bindat-test-format-vector)
+ (bindat-test-vector-to-dec, bindat-test-vector-to-hex)
+ (bindat-test-ip-to-string): New tests.
+ * lisp/emacs-lisp/bindat.el (bindat-vector-to-hex): Fix typo.
+
+2020-04-29 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in float-sup.el and add tests
+
+ * lisp/emacs-lisp/float-sup.el: Use lexical-binding.
+ * test/lisp/emacs-lisp/float-sup-tests.el: New file.
+
+2020-04-28 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in rfc2368.el and add tests
+
+ * lisp/mail/rfc2368.el: Use lexical-binding.
+ * test/lisp/mail/rfc2368-tests.el: New file.
+
+2020-04-28 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in version.el and add tests
+
+ * lisp/version.el: Use lexical-binding.
+ * test/lisp/version-tests.el: New file.
+
+2020-04-28 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in puny.el and add more tests
+
+ * lisp/net/puny.el: Use lexical-binding.
+ * test/lisp/net/puny-tests.el (puny-test-encode-domain)
+ (puny-test-decode-domain, puny-highly-restrictive-domain-p): New
+ tests.
+
+2020-04-28 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in hmac-md5.el and add tests
+
+ * lisp/net/hmac-md5.el: Use lexical-binding.
+ * test/lisp/net/hmac-md5-tests.el: New file.
+
+2020-04-28 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in many emacs-lisp tests
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el:
+ * test/lisp/emacs-lisp/ert-x-tests.el:
+ * test/lisp/emacs-lisp/nadvice-tests.el:
+ * test/lisp/emacs-lisp/pcase-tests.el:
+ * test/lisp/emacs-lisp/seq-tests.el:
+ * test/lisp/emacs-lisp/subr-x-tests.el:
+ * test/lisp/emacs-lisp/text-property-search-tests.el: Use
+ lexical-binding.
+
+ * test/lisp/emacs-lisp/seq-tests.el (test-seq-filter)
+ (test-seq-remove, test-seq-count, test-seq-every-p): Silence
+ byte-compiler.
+
+2020-04-28 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in most semantic tests
+
+ * test/lisp/cedet/semantic-utest-fmt.el:
+ * test/lisp/cedet/semantic-utest-ia.el:
+ * test/lisp/cedet/semantic-utest.el:
+ * test/lisp/cedet/srecode-utest-getset.el:
+ * test/lisp/cedet/srecode-utest-template.el: Use lexical-binding.
+
+ * test/lisp/cedet/semantic-utest-fmt.el (semantic-fmt-utest):
+ * test/lisp/cedet/semantic-utest.el (semantic-utest-generic)
+ (semantic-utest-Python, semantic-utest-Javascript)
+ (semantic-utest-Java, semantic-utest-Makefile)
+ (semantic-utest-Scheme, semantic-utest-Html, semantic-utest-PHP)
+ (semantic-utest-Csharp, semantic-utest-last-invalid):
+ * test/lisp/cedet/semantic-utest-ia.el (semantic-ia-utest-buffer)
+ (semantic-symref-test-count-hits-in-tag):
+ * test/lisp/cedet/srecode-utest-getset.el
+ (srecode-insert-getset-fully-automatic-flag): Silence
+ byte-compiler.
+
+2020-04-28 Stefan Kangas <stefankangas@gmail.com>
+
+ Don't skip test semantic-utest-Python
+
+ * test/lisp/cedet/semantic-utest.el (semantic-utest-Python):
+ Ensure test is not skipped.
+
+2020-04-28 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in most progmodes tests
+
+ * test/lisp/progmodes/etags-tests.el:
+ * test/lisp/progmodes/f90-tests.el:
+ * test/lisp/progmodes/ps-mode-tests.el:
+ * test/lisp/progmodes/python-tests.el:
+ * test/lisp/progmodes/ruby-mode-tests.el:
+ * test/lisp/progmodes/subword-tests.el:
+ * test/lisp/progmodes/tcl-tests.el:
+ * test/lisp/progmodes/xref-tests.el: Use lexical-binding.
+
+ * test/lisp/progmodes/python-tests.el (python-tests-visible-string)
+ (python-tests-look-at-1, python-tests-look-at-2)
+ (python-shell-calculate-process-environment-2): Silence byte-compiler.
+
+2020-04-28 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in most vc tests
+
+ * test/lisp/vc/add-log-tests.el:
+ * test/lisp/vc/diff-mode-tests.el:
+ * test/lisp/vc/ediff-ptch-tests.el:
+ * test/lisp/vc/smerge-mode-tests.el:
+ * test/lisp/vc/vc-hg-tests.el:
+ * test/lisp/vc/vc-tests.el: Use lexical-binding.
+
+ * test/lisp/vc/add-log-tests.el
+ (add-log-current-defun-deftest): Silence byte-compiler.
+
+2020-04-28 Paul Eggert <eggert@cs.ucla.edu>
+
+ Improve multibyte_length performance
+
+ * src/character.h (multibyte_length):
+ Merge tests so that there are fewer conditional branches.
+ This improved CPU speed of ‘make compile-always’
+ by about 1.5% on my platform.
+
+2020-04-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/jit-lock.el: Don't use `make-variable-buffer-local` on hooks.
+
+ (jit-lock-functions): Clarify that it's a hook.
+ (jit-lock-unregister): Adjust accordingly.
+
+2020-04-27 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in calendar tests
+
+ * test/lisp/calendar/icalendar-tests.el:
+ * test/lisp/calendar/parse-time-tests.el: Use lexical-binding.
+
+ * test/lisp/calendar/icalendar-tests.el (icalendar--format-ical-event)
+ (icalendar--decode-isodatetime, icalendar-tests--do-test-import)
+ (icalendar-tests--decode-isodatetime): Silence byte-compiler.
+
+2020-04-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ Simplify string-to-char
+
+ * src/editfns.c (Fstring_to_char): Simplify.
+
+ * src/editfns.c (Fstring_to_char): Simplify.
+
+ This tweak improved the CPU time performance of
+ ‘make compile-always’ by about 1.8% on my platform.
+
+2020-04-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ Improve string_char_and_length speed
+
+ This tweak improved the CPU time performance of
+ ‘make compile-always’ by about 1.7% on my platform.
+ * src/character.c (string_char): Remove; no longer used.
+ * src/character.h (string_char_and_length): Redo so that it
+ needn’t call string_char. This helps the caller, which can now
+ become a leaf function.
+
+2020-04-27 Glenn Morris <rgm@gnu.org>
+
+ * test/lisp/mail/rfc2045-tests.el: Make it work.
+
+2020-04-26 Andrea Corallo <akrl@sdf.org>
+
+ Rework spill LAP mechanism in preparation of compiling lambdas.
+
+ * lisp/emacs-lisp/comp.el (comp-spill-lap-function): No need anymore
+ to have `byte-native-compiling' bound to free-func.
+ (comp-spill-lap-function): Make use of `byte-to-native-lap-h' and
+ clean-up.
+ (comp-spill-lap-function): Likewise.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-to-native-function): Add lap slot.
+ (byte-to-native-lap): Rename into byte-to-native-lap-h.
+ (byte-compile-lapcode): Spill lap after having int assembled and
+ store it into `byte-to-native-lap-h'.
+ (byte-compile-not-top-level): Remove.
+ (byte-compile-file-form-defmumble): Fill directly lap slot.
+ (byte-compile-lambda): Remove `byte-compile-not-top-level'.
+ (byte-compile-out-toplevel): Restore original code.
+ (byte-compile-form): Remove `byte-compile-not-top-level'.
+ (byte-compile-function-form): Likewise.
+ (byte-compile-flush-pending): No need anymore to set
+ `byte-compile-current-form' so restore original code.
+
+2020-04-26 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding for themes
+
+ * etc/themes/adwaita-theme.el:
+ * etc/themes/deeper-blue-theme.el:
+ * etc/themes/dichromacy-theme.el:
+ * etc/themes/light-blue-theme.el:
+ * etc/themes/manoj-dark-theme.el:
+ * etc/themes/misterioso-theme.el:
+ * etc/themes/tango-dark-theme.el:
+ * etc/themes/tango-theme.el:
+ * etc/themes/tsdh-dark-theme.el:
+ * etc/themes/tsdh-light-theme.el:
+ * etc/themes/wheatgrass-theme.el:
+ * etc/themes/whiteboard-theme.el:
+ * etc/themes/wombat-theme.el: Use lexical-binding.
+
+2020-04-26 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in dos-vars.el
+
+ * lisp/dos-vars.el: Use lexical-binding.
+ (msdos-shells, dos-codepage-setup-hook): Remove redundant :group
+ args.
+
+2020-04-26 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix tramp-test32-shell-command-dont-erase-buffer
+
+ * test/lisp/net/tramp-tests.el
+ (tramp-test32-shell-command-dont-erase-buffer): Adapt test.
+
+2020-04-26 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-04-26 Andrea Corallo <akrl@sdf.org>
+
+ Convert before final function doc hash into a vector.
+
+ * lisp/emacs-lisp/comp.el (comp-finalize-relocs): Convert doc hash
+ table into vector before final.
+ (comp-emit-for-top-level): Rename `comp-ctxt-doc-index-h' ->
+ `comp-ctxt-function-docs'.
+ (comp-ctxt): Likewise.
+
+ * src/comp.c (native_function_doc): Update logic for documentation
+ being a vector.
+ (emit_ctxt_code): Update for 'comp-ctxt-doc-index-h' slot rename.
+
+ * src/comp.h (struct Lisp_Native_Comp_Unit): Rename 'data_fdoc_h'
+ into data_fdoc_v.
+
+ * src/pdumper.c (dump_native_comp_unit): Likewise.
+
+2020-04-26 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in spook.el
+
+ * lisp/play/spook.el: Use lexical-binding.
+ (spook-phrases-file, spook-phrase-default-count): Remove redundant
+ :group args.
+
+2020-04-26 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding for rfc2045.el and add tests
+
+ * lisp/mail/rfc2045.el: Use-lexical-binding.
+ * test/lisp/mail/rfc2045-tests.el: New file.
+
+2020-04-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Inline a couple of functions that were macros
+
+ This reclaims a bit of performance when compiling with gcc -Og.
+ These functions were macros until I changed them in
+ 2020-04-17T14:57:25Z!eggert@cs.ucla.edu.
+ * src/casefiddle.c (make_char_unibyte):
+ * src/ccl.c (GET_TRANSLATION_TABLE): Now inline.
+
+2020-04-26 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in dig.el and add tests
+
+ * lisp/net/dig.el: Use lexical-binding.
+ (dig-program, dig-dns-server, dig-font-lock-keywords): Remove
+ redundant :group args.
+ * test/lisp/net/dig-tests.el: New file.
+
+2020-04-26 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in misc.el and add tests
+
+ * lisp/misc.el: Use lexical-binding.
+ * test/lisp/misc-tests.el: New file.
+
+2020-04-25 Stefan Kangas <stefankangas@gmail.com>
+
+ Improve list-dynamic-libraries when alist empty
+
+ * lisp/misc.el (list-dynamic-libraries--refresh): Improve list format
+ and show message when 'dynamic-library-alist' is empty.
+
+2020-04-25 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+ * src/data.c (syms_of_data): Fix #ifdef HAVE_NATIVE_COMP position.
+
+ * src/comp.h (Fnative_elisp_load): Add fake inline for stock build.
+
+ * src/pdumper.c (dump_subr): Clean-up now unnecessary kludge.
+
+2020-04-25 Andrea Corallo <akrl@sdf.org>
+
+ Lazy load function documentation.
+
+ * src/comp.c (native_function_doc): New function.
+ (load_comp_unit): Do not load function doc during load.
+
+ * src/comp.h: Extern 'native_function_doc'.
+
+ * src/doc.c (Fdocumentation): Call 'native_function_doc' to
+ retrieve function doc.
+
+ * src/pdumper.c (dump_native_comp_unit): Zero 'data_fdoc_h' before
+ dumping.
+
+2020-04-25 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.h (load_comp_unit): Fix declaration style.
+
+2020-04-25 Andrea Corallo <akrl@sdf.org>
+
+ Rename TEXT_OPTIM_QLY into TEXT_OPTIM_QLY_SYM.
+
+ * src/comp.c (TEXT_OPTIM_QLY): Rename into TEXT_OPTIM_QLY_SYM.
+ (emit_ctxt_code): Update TEXT_OPTIM_QLY naming.
+ (load_comp_unit): Likewise.
+
+2020-04-25 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (declare_function): fix missing NILP.
+
+2020-04-25 Andrea Corallo <akrl@sdf.org>
+
+ Store function documentations in a hash table.
+
+ * src/pdumper.c (dump_subr): Update Lisp_Subr hash.
+ (dump_subr): Update for new compilation unit layout.
+ (dump_vectorlike): Update pvec_type hash.
+
+ * src/lisp.h (struct Lisp_Subr): Remove 'native_doc' index.
+ (DEFUN): Update macro for new compilation unit
+ layout.
+
+ * src/doc.c (Fdocumentation): Update for new compilation unit
+ layout.
+
+ * src/comp.h (struct Lisp_Native_Comp_Unit):
+ Add 'data_fdoc_h' field.
+
+ * src/comp.c (TEXT_FDOC_SYM): New macro.
+ (emit_ctxt_code): Emit function documentations.
+ (load_comp_unit): Load function documentation.
+ (Fcomp__register_subr): Rename parameter.
+ (Fcomp__register_subr): Update for new compilation unit
+ layout.
+
+ * src/alloc.c (mark_object): Update for new compilation unit
+ layout.
+ (syms_of_alloc): Likewise.
+
+ * lisp/emacs-lisp/comp.el (comp-ctxt): Add doc-index-h slot.
+ (comp-emit-for-top-level): Emit doc index as 'comp--register-subr'
+ doc parameter.
+
+2020-04-25 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): Use `clrhash'.
+
+2020-04-25 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 45a64c97c7 (origin/emacs-27) Clarify semantics of trace-function CONT...
+ 821760fdc4 Don't let a code literal get modified in mml parsing (Bug#...
+ 74a92be16d * lisp/simple.el (kill-ring-save): Doc fix. (Bug#40797)
+ 3d0e859692 Minor doc clarification regarding fringe bitmaps
+ 4d86c7f822 Fix documentation of fringe bitmaps
+ a76af88dd8 Tweak mutability doc a bit more
+ f7e488d206 Calc: fix autoload errors (bug#40800)
+ 369761b36d ; * src/xdisp.c: Improve the introductory commentary.
+ a92ca1f177 Improve indexing of ELisp manual
+ 5a25d17760 * lisp/image-mode.el (image-transform-resize): Remove FIXM...
+ 37ebec3a95 Improve the default value of 'doc-view-ghostscript-program'.
+ ba6104d1e8 Change doc-view-mode-map prefix key 's' to 'c'.
+ 400ff5cd19 Improve wording about constants
+ d2836fe71b Improve the default value of 'doc-view-ghostscript-program'.
+ fc55f65305 Minor improvements in documentation of the last change
+ a64da75961 Add image-auto-resize defcustoms to image-mode.el
+ 692ad40539 Improve the documentation of tab-bar and tab-line
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-04-25 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-04-25 Andrea Corallo <akrl@sdf.org>
+
+ Fix deferred-compilation for double compilation (bug#40838).
+
+ * lisp/emacs-lisp/comp.el (native-compile-async): Prevent double
+ compilation (bug#40838).
+
+2020-04-25 Andrea Corallo <akrl@sdf.org>
+
+ Store ongoing compilations processes as hash table.
+
+ * lisp/emacs-lisp/comp.el (comp-async-processes): Rename as
+ `comp-async-compilations'.
+ (comp-async-runnings): Make use as `comp-async-compilations'.
+ (comp-run-async-workers): Likewise.
+
+2020-04-25 Eli Zaretskii <eliz@gnu.org>
+
+ Fix GDI+ image loading by file name
+
+ Without a call to image_find_image, we can get a file name that
+ is relative to data-directory/images/, or a file name that
+ starts with "~/", in which case w32_load_image would fail.
+ * src/image.c (native_image_load): Call image_find_image_file to
+ resolve and encode the image file name.
+ * src/w32image.c (w32_load_image): No need to encode the file
+ name, as it's already encoded by native_image_load.
+
+2020-04-25 Igor Saprykin <sheleztt@gmail.com> (tiny change)
+
+ Remove unused variable from ftfont.c
+
+ * src/ftfont.c (ftfont_lookup_cache): Eliminate unnecessary variable.
+
+2020-04-25 Eli Zaretskii <eliz@gnu.org>
+
+ Fix two fringe bitmaps
+
+ * src/fringe.c (question_mark_bits, exclamation_mark_bits): Fix
+ the numerical values. (Bug#40805)
+
+2020-04-25 Simen Heggestøyl <simenheg@gmail.com>
+
+ Use lexical-binding in po.el and add tests
+
+ * lisp/textmodes/po.el: Use lexical-binding.
+
+ * test/lisp/textmodes/po-tests.el: New file with tests for po.el.
+
+2020-04-25 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in forms.el example files
+
+ * etc/forms/forms-d2.el:
+ * etc/forms/forms-pass.el: Use lexical-binding.
+
+2020-04-24 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding for international tests
+
+ * test/lisp/international/mule-util-tests.el:
+ * test/lisp/international/ccl-tests.el: Use lexical-binding.
+
+2020-04-24 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding for all net tests
+
+ * test/lisp/net/dbus-tests.el:
+ * test/lisp/net/gnutls-tests.el:
+ * test/lisp/net/newsticker-tests.el:
+ * test/lisp/net/puny-tests.el:
+ * test/lisp/net/rfc2104-tests.el: Use lexical-binding.
+
+2020-04-24 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding for textmodes tests
+
+ * test/lisp/textmodes/mhtml-mode-tests.el:
+ * test/lisp/textmodes/sgml-mode-tests.el: Use lexical-binding.
+
+2020-04-24 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in most url tests
+
+ * test/lisp/url/url-auth-tests.el:
+ * test/lisp/url/url-expand-tests.el:
+ * test/lisp/url/url-parse-tests.el:
+ * test/lisp/url/url-tramp-tests.el:
+ * test/lisp/url/url-util-tests.el: Use lexical-binding.
+
+2020-04-24 Stefan Kangas <stefankangas@gmail.com>
+
+ Use lexical-binding in most src tests
+
+ * test/src/charset-tests.el:
+ * test/src/chartab-tests.el:
+ * test/src/cmds-tests.el:
+ * test/src/coding-tests.el (top-level)
+ (generate-ascii-file, generate-mostly-nonascii-file):
+ * test/src/doc-tests.el:
+ * test/src/floatfns-tests.el:
+ * test/src/font-tests.el:
+ * test/src/keymap-tests.el:
+ * test/src/process-tests.el (top-level)
+ (process-test-sentinel-wait-function-working-p)
+ (process-test-stderr-buffer, process-test-stderr-filter):
+ * test/src/textprop-tests.el:
+ * test/src/thread-tests.el:
+ * test/src/timefns-tests.el:
+ * test/src/undo-tests.el:
+ * test/src/xml-tests.el: Use lexical-binding.
+
+2020-04-24 Alan Mackenzie <acm@muc.de>
+
+ Fix bug #40766, an error in edebug spec handling
+
+ Also remove some debris.
+
+ * lisp/emacs-lisp/edebug.el (edebug-spec): Move the entry for edebug-spec-list
+ to before that for vector in the &or form. This assures that in a dotted list
+ of vectors, that list gets handled correctly by edebug-spec-list rather than
+ wrongly by (vector ...).
+ (def-edebug-spec &key): Remove, since it is ill formed and superfluous.
+
+2020-04-24 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+ * lisp/subr.el (called-interactively-p): Fix for native code bug#40694.
+
+ * lisp/subr.el (subr-primitive-p): New inline function.
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): Fix non late load.
+
+2020-04-24 Stefan Kangas <stefankangas@gmail.com>
+
+ * etc/edt-user.el: Use lexical-binding.
+
+ * lisp/kermit.el: Use lexical-binding.
+
+2020-04-24 Michael Albinus <michael.albinus@gmx.de>
+
+ * test/lisp/net/tramp-tests.el
+
+ (tramp-test32-shell-command-dont-erase-buffer): Tag it :unstable.
+
+2020-04-23 Eli Zaretskii <eliz@gnu.org>
+
+ Fix display of composed text with :box face attribute
+
+ * src/xdisp.c (get_next_display_element): For a composition on a
+ display or overlay string, set the end_of_box_run_p flag if the
+ string ends at the last character included in the composition.
+ (fill_gstring_glyph_string): Fix the way the width of a gstring
+ glyph string is calculated: use the values calculated in
+ gui_produce_glyphs, since the latter adjusts the width due to the
+ face's ':box' attribute.
+ * src/xterm.c (x_draw_glyph_string_box):
+ * src/w32term.c (w32_draw_glyph_string_box):
+ * src/nsterm.m (ns_dumpglyphs_box_or_relief): Support automatic
+ compositions, which have the right_box_line_p flag set on the last
+ glyph produced from the composition. (Bug#40687)
+
+ * src/w32term.c (w32_compute_glyph_string_overhangs): Update to be
+ consistent with xterm.c in its support of automatic composition
+ glyph strings.
+ * src/dispextern.h (enum glyph_type): More accurate commentary.
+ * src/.gdbinit (pgx): Display slice.img members only for image
+ glyphs.
+
+2020-04-23 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-refresh-preloaded): Add comp.eln
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-04-23 Paul Eggert <eggert@cs.ucla.edu>
+
+ text-char-description minor cleanup
+
+ * src/keymap.c (push_text_char_description): Omit useless code.
+ (Ftext_char_description): Minor code cleanup, inspired by
+ seeing an incorrect comment about MAX_MULTIBYTE_LENGTH’s value.
+
+2020-04-23 Paul Eggert <eggert@cs.ucla.edu>
+
+ Tweak multibyte parsing loops
+
+ * src/character.c (parse_str_as_multibyte, str_as_multibyte):
+ Let the fast loop run a little longer, fixing what appears
+ to be an off-by-1 performance nit.
+
+2020-04-22 Michael Albinus <michael.albinus@gmx.de>
+
+ Support old SMB1 protocol in Tramp
+
+ * doc/misc/tramp.texi (Frequently Asked Questions):
+ Describe `tramp-smb-options'.
+
+ * lisp/net/tramp-smb.el (tramp-smb-conf): Fix docstring.
+ (tramp-smb-options): New defcustom.
+ (tramp-smb-handle-copy-directory, tramp-smb-handle-file-acl)
+ (tramp-smb-handle-set-file-acl, tramp-smb-maybe-open-connection):
+ Use it.
+
+2020-04-21 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix recently introduced error in `tramp-sh-handle-vc-registered'
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-vc-registered): Improve test for
+ `vc-handled-backends'. (Bug#40670)
+
+2020-04-21 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix string-to-multibyte overlong sequence bug
+
+ * src/character.h (MULTIBYTE_LENGTH, MULTIBYTE_LENGTH_NO_CHECK):
+ Remove, replacing with ...
+ (multibyte_length): ... this new function. All callers changed.
+ The new function rejects overlong multibyte forms.
+ * test/src/buffer-tests.el (buffer-multibyte-overlong-sequences):
+ New test.
+
+2020-04-21 Juri Linkov <juri@linkov.net>
+
+ * lisp/hi-lock.el (hi-lock--regexps-at-point): Use proper-list-p, not consp.
+
+2020-04-20 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Remove unnecessary lambda quoting
+
+ * lisp/gnus/nntp.el (nntp-open-connection): Buffer has lexical-binding
+ turned on.
+
+2020-04-20 Eli Zaretskii <eliz@gnu.org>
+
+ Remove workaround from w32image.c
+
+ * src/w32image.c (w32_load_image): Remove a workaround for a bug
+ that is not needed anymore. This error was happening because
+ GDI+ functions were called as CDECL, not as STDCALL.
+
+2020-04-20 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 05089a4d65 (origin/emacs-27) Tweak wording re constant variables
+ a1040861f1 Tweak setcar-related wording
+ 751510f865 * lisp/image-mode.el: Add prefix key 's' and reduce depend...
+ 9261a219ec * doc/emacs/windows.texi (Window Convenience): Describe mor...
+ e1d42da0d6 Fix mutability glitches reported by Drew Adams
+ 5805df74f5 Improve mutability doc
+ dca35b31d0 Improve mutability documentation
+ 81e7d7f111 Document that quoting yields constants
+ 5734339f40 * doc/lispref/keymaps.texi (Extended Menu Items, Easy Menu...
+ 14a570afae Remove #' and function quoting from lambda forms in manual
+ d5ec18c66b * src/regex-emacs.c (re_match_2_internal): Rework comment ...
+ 4df8a61117 Add new node "Image Mode" to Emacs Manual.
+ d7d5ee6c57 ; Fix a typo in cmdargs.texi (bug#40701)
+ 5e9db48fbe * doc/lispref/display.texi (Customizing Bitmaps): Fix typo.
+ eebfb72c90 Document constant vs mutable objects better
+ 6c187ed6b0 Improve documentation of 'sort-lines'
+ 52288f4b66 Mention 'spam-stat-process-directory-age' in the documenta...
+ 067b070598 ; Fix some typos and doc issues (bug#40695)
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-04-20 Stefan Kangas <stefankangas@gmail.com>
+
+ * lisp/cdl.el: Use lexical binding.
+
+2020-04-20 Stefan Kangas <stefankangas@gmail.com>
+
+ Silence byte-compiler after my previous commit
+
+ * lisp/autoarg.el (autoarg-kp-digits): Silence byte-compiler.
+
+2020-04-19 Eli Zaretskii <eliz@gnu.org>
+
+ Rework how GDI+ functions are loaded dynamically in w32image.c
+
+ * src/w32image.c: Define correct WINGDIPAPI typedefs for GDI+
+ functions. We cannot use DEF_DLL_FN, since that is for functions
+ with C calling conventions, whereas GDI+ functions are __stdcall.
+ (gdiplus_init): Load functions from DLL manually, not via
+ LOAD_DLL_FN, as the latter is for __cdecl functions.
+ (w32_frame_delay): Initialize delay with a negative value, as zero
+ is a valid delay.
+
+2020-04-19 Eli Zaretskii <eliz@gnu.org>
+
+ Don't use Gnulib's explicit_bzero on MS-Windows
+
+ This is a preventive change, since Gnulib was recently changed
+ its explicit_bzero to call SecureZeroMemory on MS-Windows,
+ disregarding systems older than XP, which didn't have it.
+
+ * src/w32.c (explicit_bzero): New function.
+
+ * nt/mingw-cfg.site (ac_cv_func_explicit_bzero): Avoid using the
+ Gnulib replacement for explicit_bzero.
+ * nt/inc/ms-w32.h (explicit_bzero): Add prototype.
+
+2020-04-19 Simen Heggestøyl <simenheg@gmail.com>
+
+ Use lexical-binding in elide-head.el and add tests
+
+ * lisp/elide-head.el: Use lexical-binding.
+ (elide-head-headers-to-hide): Remove redundant :group arg.
+ (elide-head-overlay): Use `defvar-local'.
+ (elide-head-show): Fix docstring.
+
+ * test/lisp/elide-head-tests.el: New file with tests for
+ elide-head.el.
+
+2020-04-19 Stefan Kangas <stefankangas@gmail.com>
+
+ * lisp/autoarg.el: Use lexical binding.
+
+2020-04-18 Ahmed Khanzada <lenzuru@gmail.com>
+
+ Fix misnamed variable breaking GNUstep
+
+ * src/nsterm.m (ns_set_offset): Use correct variable.
+
+2020-04-18 Simen Heggestøyl <simenheg@gmail.com>
+
+ Use lexical-binding in apropos.el and add tests
+
+ * lisp/apropos.el: Use lexical-binding and remove redundant
+ :group args.
+ (apropos-words-to-regexp, apropos): Tweak docstrings.
+ (apropos-value-internal): Replace '(if x (progn y))' with
+ '(when x y)'.
+ (apropos-format-plist): Add docstring and replace '(if x (progn y))'
+ with '(when x y)'.
+
+ * test/lisp/apropos-tests.el: New file with tests for apropos.el.
+
+2020-04-18 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ f3b62b6c62 (origin/emacs-27) Avoid crashes in regex-emacs.c due to GC
+ 175c61c18b Fix "C-u M-!" when 'shell-command-dont-erase-buffer' is no...
+ 6b297519b5 Fix cl-most-positive-float doc typo
+ c36c5a3ded ; lisp/ldefs-boot.el: Update.
+ 3876a60569 Fix a typo in calculator.el
+ 9e832ba91b * lisp/erc/erc.el: Add URL to the new ERC page on the Emac...
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-04-18 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 145a151d62 Correct Fido-mode's backspacing of directories with spaces
+ 660b9b8cfb Default completion-flex-nospace to nil
+ fb5f616ae8 Improve an example in w32 FAQ
+
+2020-04-18 Eli Zaretskii <eliz@gnu.org>
+
+ Safeguard the fix of bug#40632
+
+ * src/xdisp.c (move_it_to): Restrict the recent fix to iteration
+ through buffer text.
+
+2020-04-18 Eli Zaretskii <eliz@gnu.org>
+
+ Don't abort when using GDI+ for images
+
+ * src/w32image.c (decode_delay): Instead of aborting when the
+ type of delay value is unrecognized, return an invalid negative
+ value.
+
+2020-04-18 Juan José García-Ripoll <juanjose.garciaripoll@gmail.com>
+
+ Fix loading multi-frame TIFF images via GDI+
+
+ * src/w32image.c (w32_frame_delay): Don't try to compute frame
+ delay if GdipGetPropertyItemSize fails for PropertyTagFrameDelay.
+ (w32_load_image): Don't add 'delay' member to metadata if the
+ delay could not be determined.
+
+2020-04-18 Martin Rudalics <rudalics@gmx.at>
+
+ Fix handling of child frames in prepare_menu_bars (Bug#40639)
+
+ * src/xdisp.c (prepare_menu_bars): Call gui_consider_frame_title
+ for child frames too (Bug#40639). Never try to update menu bar
+ of a child frame. Do not exclude child frames from updating tool
+ or tab bars.
+
+2020-04-17 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port recent character.h changes to --with-wide-int
+
+ * src/fns.c (mapcar1):
+ * src/keymap.c (Fkey_description):
+ * src/syntax.c (scan_lists):
+ Prefer ptrdiff_t to EMACS_INT where either will do; this fixes
+ newly-introduced type errors on --with-wide-int platforms where
+ ptrdiff_t is narrower than EMACS_INT.
+ * src/keymap.c (Fkey_description): Rework for clarity; remove goto.
+ * src/syntax.c (scan_words, Fforward_comment, scan_lists)):
+ Fix unlikely integer overflow problems that can occur on
+ --with-wide-int platforms, and that were caught by the recent
+ character.h changes.
+
+2020-04-17 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify gcc -Og x86-64
+
+ * src/editfns.c (Ftranslate_region_internal): Add UNINIT
+ to pacify gcc -Og x86-64 (GCC 9.3.1 20200317 (Red Hat 9.3.1-1)).
+
+2020-04-17 Paul Eggert <eggert@cs.ucla.edu>
+
+ Prefer more inline functions in character.h
+
+ * src/buffer.h (fetch_char_advance, fetch_char_advance_no_check)
+ (buf_next_char_len, next_char_len, buf_prev_char_len)
+ (prev_char_len, inc_both, dec_both): New inline functions,
+ replacing the old character.h macros FETCH_CHAR_ADVANCE,
+ FETCH_CHAR_ADVANCE_NO_CHECK, BUF_INC_POS, INC_POS, BUF_DEC_POS,
+ DEC_POS, INC_BOTH, DEC_BOTH respectively. All callers changed.
+ These new functions all assume buffer primitives and so need
+ to be here rather than in character.h.
+ * src/casefiddle.c (make_char_unibyte): New static function,
+ replacing the old MAKE_CHAR_UNIBYTE macro. All callers changed.
+ (do_casify_unibyte_string): Use SINGLE_BYTE_CHAR_P instead
+ of open-coding it.
+ * src/ccl.c (GET_TRANSLATION_TABLE): New static function,
+ replacing the old macro of the same name.
+ * src/character.c (string_char): Omit 2nd arg. 3rd arg can no
+ longer be NULL. All callers changed.
+ * src/character.h (SINGLE_BYTE_CHAR_P): Move up.
+ (MAKE_CHAR_UNIBYTE, MAKE_CHAR_MULTIBYTE, PREV_CHAR_BOUNDARY)
+ (STRING_CHAR_AND_LENGTH, STRING_CHAR_ADVANCE)
+ (FETCH_STRING_CHAR_ADVANCE)
+ (FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE)
+ (FETCH_STRING_CHAR_ADVANCE_NO_CHECK, FETCH_CHAR_ADVANCE)
+ (FETCH_CHAR_ADVANCE_NO_CHECK, INC_POS, DEC_POS, INC_BOTH)
+ (DEC_BOTH, BUF_INC_POS, BUF_DEC_POS): Remove.
+ (make_char_multibyte): New static function, replacing
+ the old macro MAKE_CHAR_MULTIBYTE. All callers changed.
+ (CHAR_STRING_ADVANCE): Remove; all callers changed to use
+ CHAR_STRING.
+ (NEXT_CHAR_BOUNDARY): Remove; it was unused.
+ (raw_prev_char_len): New inline function, replacing the
+ old PREV_CHAR_BOUNDARY macro. All callers changed.
+ (string_char_and_length): New inline function, replacing the
+ old STRING_CHAR_AND_LENGTH macro. All callers changed.
+ (STRING_CHAR): Rewrite in terms of string_char_and_length.
+ (string_char_advance): New inline function, replacing the old
+ STRING_CHAR_ADVANCE macro. All callers changed.
+ (fetch_string_char_advance): New inline function, replacing the
+ old FETCH_STRING_CHAR_ADVANCE macro. All callers changed.
+ (fetch_string_char_as_multibyte_advance): New inline function,
+ replacing the old FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE macro.
+ All callers changed.
+ (fetch_string_char_advance_no_check): New inline function,
+ replacing the old FETCH_STRING_CHAR_ADVANCE_NO_CHECK macro. All
+ callers changed.
+ * src/regex-emacs.c (HEAD_ADDR_VSTRING): Remove; no longer used.
+ * src/syntax.c (scan_lists): Use dec_bytepos instead of
+ open-coding it.
+ * src/xdisp.c (string_char_and_length): Rename from
+ string_char_and_length to avoid name conflict with new function in
+ character.h. All callers changed.
+
+2020-04-17 Paul Eggert <eggert@cs.ucla.edu>
+
+ Prefer inline functions in character.h
+
+ In character.h, replace macros with inline functions or enums
+ when this is easy. This improves maintainability and
+ on my platform (Fedora 31 x86-64, gcc -O2) improved CPU
+ performance very slightly (0.3%) on ‘make compile-always’.
+ * src/buffer.h (SANE_TAB_WIDTH, CHARACTER_WIDTH):
+ Move here from character.h, and make them inline functions.
+ Tune CHARACTER_WIDTH so that ASCII_CHAR_WIDTH is no longer needed.
+ (sanitize_tab_width, sanitize_char_width):
+ Move here from character.h.
+ * src/character.h (MAX_CHAR, MAX_UNICODE_CHAR, MAX_1_BYTE_CHAR)
+ (MAX_2_BYTE_CHAR, MAX_3_BYTE_CHAR, MAX_4_BYTE_CHAR)
+ (MAX_5_BYTE_CHAR, MIN_MULTIBYTE_LEADING_CODE)
+ (MAX_MULTIBYTE_LEADING_CODE, MAX_MULTIBYTE_LENGTH):
+ Now enum constants instead of macros.
+ * src/character.h (CHAR_BYTES): Redo to avoid conditional branches.
+ (CHAR_BYTE8_P, BYTE8_TO_CHAR, UNIBYTE_TO_CHAR, CHAR_TO_BYTE8)
+ (CHAR_TO_BYTE_SAFE, CHAR_BYTE8_HEAD_P, CHARACTERP)
+ (CHECK_CHARACTER, CHECK_CHARACTER_CAR, CHECK_CHARACTER_CDR)
+ (CHAR_PRINTABLE_P, CHAR_BYTES, CHAR_LEADING_CODE, BYTE8_STRING)
+ (LEADING_CODE_P, TRAILING_CODE_P, CHAR_HEAD_P)
+ (BYTES_BY_CHAR_HEAD):
+ Now inline functions instead of macros.
+ (ASCII_CHAR_WIDTH): Remove; no longer used.
+ * src/conf_post.h (ATTRIBUTE_PURE): New macro.
+ * src/lisp.h (char_table_ref): Use it, for better inlining.
+ * src/fns.c (base64_decode_1): Add now-necessary casts.
+
+2020-04-17 Basil L. Contovounesios <contovob@tcd.ie>
+
+ Fix effect-free warning in ob-screen.el while loop
+
+ The warning was introduced and detected by an optimizer addition
+ proposed in the following thread:
+ https://lists.gnu.org/archive/html/emacs-devel/2019-12/msg00711.html
+
+ * lisp/org/ob-screen.el (org-babel-screen-test): Avoid 'value
+ returned from (format "...") is unused' warning by doing something
+ more useful than busy string manipulation while waiting for an
+ asynchronous subprocess to make the temporary file readable.
+
+2020-04-17 Justin Timmons <justinmtimmons@gmail.com>
+
+ Bind 'n' and 'p' to move between symbols in apropos
+
+ * lisp/apropos.el (apropos-next-symbol)
+ (apropos-previous-symbol): New commands.
+ (apropos-mode-map): Bind above commands to 'n' and 'p'. (Bug#20694)
+ * etc/NEWS: Announce the new commands.
+
+2020-04-17 Masahiro Nakamura <tsuucat@icloud.com>
+
+ Fix comparing command names in strokes.el (bug#40600)
+
+ * lisp/strokes.el (strokes-alphabetic-lessp): Simply call string-lessp
+ because the cdr of the argument may be a string.
+
+2020-04-16 Alan Third <alan@idiocy.org>
+
+ Use native image API for NS
+
+ * configure.ac (NATIVE_IMAGE_API): Move above NS definitions.
+ (HAVE_NATIVE_IMAGE_API): Set for NS.
+ (HAVE_PNG, HAVE_JPEG, HAVE_GIF, HAVE_TIFF): Enable on NS builds.
+ * src/image.c (HAVE_NS): Fix a number of #if's so they no longer rely
+ on HAVE_NS.
+ (PIX_MASK_DRAW): Add for HAVE_NS so libpng support will compile.
+ (image_can_use_native_api):
+ (native_image_load): Add NS support.
+ (png_load):
+ (jpeg_load):
+ (tiff_load):
+ (gif_load): Remove NS specific definitions.
+ * src/nsimage.m (ns_can_use_native_image_api): New function.
+ * src/nsterm.h: (ns_can_use_native_image_api): New function.
+
+2020-04-16 Alan Third <alan@idiocy.org>
+
+ Allow dynamic choice of drawing path on NS (bug#39883)
+
+ * src/nsterm.h (NS_DRAW_TO_BUFFER): Let this be enabled on versions
+ older than 10.14.
+ * src/nsterm.m (ns_update_begin):
+ (ns_update_end):
+ (ns_focus):
+ (ns_unfocus):
+ ([EmacsView viewDidResize:]):
+ ([EmacsView createDrawingBuffer]):
+ ([EmacsView windowDidChangeBackingProperties:]):
+ ([EmacsView copyRect:to:]):
+ ([EmacsView wantsUpdateLayer]): Dynamically switch between drawing to a
+ buffer and drawing to the screen, depending on the version of AppKit
+ in use.
+ ([EmacsView dealloc]): We can't release the context unless
+ NS_DRAW_TO_BUFFER is defined.
+
+2020-04-16 Alan Third <alan@idiocy.org>
+
+ Fix NS frame resizing issues (bug#40200, bug#28872)
+
+ * src/nsmenu.m (update_frame_tool_bar): Remove reference to
+ updateFrameSize.
+ * src/nsterm.h: ([EmacsView updateFrameSize]):
+ ([EmacsView setRows:andColumns:]): Remove unused
+ method definitions.
+ (NS_PARENT_WINDOW_LEFT_POS):
+ (NS_PARENT_WINDOW_TOP_POS): Move to nsterm.m.
+ * src/nsterm.m (ns_parent_window_rect): New function.
+ (NS_PARENT_WINDOW_LEFT_POS):
+ (NS_PARENT_WINDOW_TOP_POS): Move to nsterm.m and simplify.
+ (ns_set_offset): Fix strange behaviours when using negative values.
+ (ns_set_window_size):
+ (ns_set_undecorated):
+ ([EmacsView windowDidResize:]):
+ ([EmacsView windowDidExitFullScreen]):
+ (ns_judge_scroll_bars): Remove references to updateFrameSize.
+ ([EmacsView dealloc]): Unset resize notification and release buffer.
+ ([EmacsView updateFrameSize:]): Remove function.
+ ([EmacsView windowWillResize:toSize:]): Move some code to
+ viewDidResize.
+ ([EmacsView viewDidResize]): New function.
+ ([EmacsView initFrameFromEmacs:]): Set up resize notification and move
+ buffer creation until after the prerequisite objects are created.
+ ([EmacsView toggleFullScreen:]): Set frame to the size of the
+ contentview, not the whole window, and remove reference to
+ updateFrameSize.
+ ([EmacsView setRows:andColumns:]): Remove unused method.
+ ([EmacsView windowDidMove:]): Tidy up.
+
+2020-04-16 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-never-optimize-functions): Better doc fix
+
+2020-04-16 Mattias Engdegård <mattiase@acm.org>
+
+ Improve regexp in org-table-finish-edit-field
+
+ * lisp/org/org-table.el (org-table-finish-edit-field):
+ Further improvement of regexp, as suggested by Paul Eggert.
+
+2020-04-16 Michael Albinus <michael.albinus@gmx.de>
+
+ Ignore D-Bus errors in tramp-gvfs.el (Bug#40655)
+
+ * lisp/net/tramp-gvfs.el (with-tramp-dbus-call-method): Ignore D-Bus
+ errors. (Bug#40655)
+
+2020-04-16 Alan Mackenzie <acm@muc.de>
+
+ (forward-comment -n): escaped newline is sometimes NOT end of comment
+
+ * src/syntax.c (Fforward_comment) When comment-end-can-be-escaped is non-nil,
+ don't attempt back_comment when point is just after an escaped newline, etc.
+
+2020-04-16 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+ * lisp/emacs-lisp/comp.el (comp-never-optimize-functions): Add yes-or-no-p
+
+2020-04-16 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix type-checking bug in vertical-motion
+
+ * src/indent.c (Fvertical_motion): Fix bug where the type of lcols
+ was checked too late.
+
+2020-04-16 Glenn Morris <rgm@gnu.org>
+
+ * src/indent.c (Fvertical_motion): Fix int/Lisp_Object mix up.
+
+2020-04-16 Mattias Engdegård <mattiase@acm.org>
+
+ Use directory-files-no-dot-files-regexp wherever possible
+
+ Suggested by Paul Eggert.
+
+ * lisp/files.el (directory-files-no-dot-files-regexp):
+ Clarify semantics and purpose.
+ * lisp/dired.el (dired-re-no-dot):
+ Define as obsolete alias of directory-files-no-dot-files-regexp.
+ (dired-delete-file):
+ * lisp/gnus/gnus-util.el (gnus-delete-directory):
+ * lisp/net/ange-ftp.el (ange-ftp-delete-directory):
+ * lisp/obsolete/vc-arch.el (vc-arch-trim-revlib):
+ * lisp/org/ob-core.el (org-babel-remove-temporary-directory):
+ * lisp/vc/vc-rcs.el (vc-rcs-unregister):
+ Use directory-files-no-dot-files-regexp.
+
+2020-04-16 Mattias Engdegård <mattiase@acm.org>
+
+ Quote semanticdb-ebrowse-default-file-name in regexp
+
+ Noticed by Andreas Schwab.
+
+ * lisp/cedet/semantic/db-ebrowse.el (semanticdb-load-ebrowse-caches):
+ Quote file name in regexp.
+
+2020-04-16 Mattias Engdegård <mattiase@acm.org>
+
+ Fix bugs, inefficiencies and bad style in regexps
+
+ Found by relint. See discussion at
+ https://lists.gnu.org/archive/html/emacs-devel/2020-04/msg00265.html
+
+ * lisp/org/org-table.el (org-table-finish-edit-field):
+ * lisp/arc-mode.el (archive-rar-summarize):
+ Avoid wrapped subsumption in repeated sequences.
+ * lisp/erc/erc-dcc.el (erc-dcc-ctcp-query-send-regexp): Replace
+ inefficient repeated empty-matching expression with a plain greedy
+ form.
+ (erc-dcc-handle-ctcp-send): Adjust group numbers.
+ * lisp/net/puny.el (puny-encode-domain): Fix fast-path shortcut
+ pattern so that it actually works as intended.
+ * lisp/progmodes/gdb-mi.el (gdb-control-commands-regexp):
+ * lisp/vc/diff-mode.el (diff-imenu-generic-expression):
+ Remove superfluous backslashes.
+ * lisp/progmodes/scheme.el (scheme-imenu-generic-expression):
+ Correct confused definition-matching pattern which would match more
+ than intended.
+ * lisp/textmodes/sgml-mode.el (sgml-tag-name-re): Avoid inefficient
+ matching by using the fact that the first character cannot match the
+ last char of sgml-name-re.
+
+2020-04-16 Mattias Engdegård <mattiase@acm.org>
+
+ Regularise some file-matching regexps
+
+ * admin/authors.el (authors-obsolete-files-regexps)
+ (authors-renamed-files-regexps): Replace ^ and $ with \` and \'.
+
+2020-04-16 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid compiler warning in indent.c
+
+ * src/indent.c (Fvertical_motion): Avoid compilation warning.
+ Reported by Juanma Barranquero <lekktu@gmail.com>.
+
+2020-04-16 Eli Zaretskii <eliz@gnu.org>
+
+ File-handling cleanup in w32image.c
+
+ * src/w32image.c (w32_load_image): Encode the image file name and
+ convert it via 'map_w32_filename'. No need to do anything special
+ when 'w32_unicode_filenames' is zero, since file names are in
+ UTF-8 internally, and this code will never run on Windows 9X.
+ * src/w32.h (map_w32_filename): Add prototype; removed prototypes
+ from all *.c files.
+
+2020-04-15 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/subr.el (eval-after-load): Make use of load-true-file-name bug#40638
+
+2020-04-15 Eli Zaretskii <eliz@gnu.org>
+
+ Fix retrieval of frame delay when using GDI+
+
+ * src/w32image.c (enum PropertyItem_type): New enumeration.
+ (decode_delay): New function.
+ (w32_frame_delay): Call 'decode_delay' to retrieve the frame delay
+ from image data.
+
+2020-04-15 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ a5f7c26907 (origin/emacs-27) * admin/authors.el: Add an author alias.
+ d87a4d1f4e Limit RLIMIT_NOFILE to FD_SETSIZE on macOS
+ e5ca8e5e73 Fix Elisp manual entry on 'set-window-configuration'
+ 485f24223f ; Update ChangeLog.3
+ 8f200254fb ; Update etc/AUTHORS
+ c7adc851ad * admin/authors.el: Add missing author aliases.
+ 4acdd7fe58 Fix edge case errors in filename-matching regexps
+ 5f36e21fe5 Clarify the doc string of 'yank'
+ 13301d4266 New function erc-track-switch-buffer-other-window
+ 38f7538d8f New function erc-switch-to-buffer-other-window
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-04-15 Eli Zaretskii <eliz@gnu.org>
+
+ Fix small glitches in documenting the native image API feature
+
+ * etc/NEWS: Fix wording of the entry for native image API support.
+ Reported by Juanma Barranquero <lekktu@gmail.com>.
+
+ * configure.ac (native-image-api): Fix the "--help" description.
+
+2020-04-15 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid infloop in redisplay when wrap-prefix is too wide
+
+ * src/xdisp.c (move_it_to): Avoid infloop due to wrap-prefix that
+ is wide enough to leave no space to display even the first
+ character of the continuation line. (Bug#40632)
+
+2020-04-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/htmlfontify.el: Use `font-lock-ensure` unconditionally
+
+ Remove redundant `:group`s.
+
+ (hfy-force-fontification): Make it an obsolete alias for `font-lock-ensure`.
+ Update all callers.
+ (hfy-init-kludge-hooks, hfy-init-kludge-hook): Remove vars, not used any more.
+ (hfy-kludge-cperl-mode): Declare it obsolete.
+
+2020-04-14 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid compiler warning in image.c
+
+ * src/image.c (image_can_use_native_api): Avoid compiler warnings
+ by making this function conditioned on HAVE_NATIVE_IMAGE_API.
+ (initialize_image_type): Call image_can_use_native_api only if
+ HAVE_NATIVE_IMAGE_API is non-zero. Reported by Basil
+ L. Contovounesios <contovob@tcd.ie>.
+
+2020-04-14 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-04-14 Andrea Corallo <akrl@sdf.org>
+
+ Always set `load-true-file-name' where `load-file-name' is set too.
+
+ Fix bug#40620.
+
+ * lisp/cus-dep.el (custom-make-dependencies): Set
+ load-true-file-name.
+
+ * lisp/emacs-lisp/package.el (package-quickstart-refresh):
+ Likewise.
+
+ * lisp/international/mule.el (load-with-code-conversion):
+ Likewise.
+
+ * lisp/loadup.el (load-true-file-name): Likewise.
+
+2020-04-14 Eli Zaretskii <eliz@gnu.org>
+
+ Make use of MS-Windows native image API be selectable at run time
+
+ * configure.ac: Minor cleanup in how w32image.o is added to the
+ build when native image APIs are requested.
+
+ * src/w32gui.h (w32_load_image, w32_can_use_native_image_api)
+ (w32_gdiplus_shutdown): Move prototypes from w32term.h here, since
+ w32.c doesn't include w32term.h.
+ * src/image.c (struct image_type): No need to pass TYPE to the
+ 'valid_p' method. All callers changed.
+ (initialize_image_type) [HAVE_NATIVE_IMAGE_API]: Call
+ 'image_can_use_native_api' before trying image-specific methods.
+ (image_can_use_native_api): New function.
+ (image_types): Remove the native_image_type parts.
+ (syms_of_image): New symbol 'native-image'.
+ (parse_image_spec): Accept native-image "type" for any image type.
+ * src/w32term.c (syms_of_w32term): New variable
+ 'w32-use-native-image-API'.
+ * src/w32image.c: (w32_can_use_native_image_api): New function.
+ (gdiplus_init): Rename from w32_gdiplus_startup. Simplify code.
+ Move the call to GdiplusStartup to a separate function. Use
+ ordinal number for SHCreateMemStream if cannot load it by name.
+ (w32_load_image): Ignore Win32Error status from
+ w32_select_active_frame.
+ Move DEFSYMs from here...
+ * src/image.c (syms_of_image) [HAVE_NATIVE_IMAGE_API]: ...to here.
+
+ * etc/NEWS: Update the entry about native image API use.
+
+2020-04-14 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (native-compile-async): Better error message.
+
+2020-04-14 Juan José García-Ripoll <juanjose.garciaripoll@gmail.com>
+
+ Initial version of native image API support for MS-Windows
+
+ * src/w32image.c: New file.
+ * src/w32term.h: Add prototypes of 'w32_load_image',
+ 'w32_gdiplus_startup', 'w32_gdiplus_shutdown', and
+ 'w32_query_frame_background_color'.
+ * src/w32term.c (w32_query_frame_background_color): No longer
+ static.
+ * src/w32.c (term_ntproc) [HAVE_GDIPLUS]: Call
+ 'w32_gdiplus_shutdown'.
+ * src/image.c (struct image_type) <valid_p>: Accept an additional
+ argument, the image type. All implementations changed.
+ (init_native_image_functions, native_image_p, native_image_load)
+ [HAVE_NATIVE_IMAGE_API]: New methods for "native image type".
+ (initialize_image_type) [HAVE_NATIVE_IMAGE_API]: Call
+ 'init_native_image_functions'.
+ (image_types) [HAVE_NATIVE_IMAGE_API]: Add settings for native
+ image API.
+ (lookup_image_type) [HAVE_NATIVE_IMAGE_API]: Initialize native
+ functions if needed.
+
+ * lisp/term/w32-win.el (dynamic-library-alist): Add gdiplus and
+ shlwapi.
+
+ * etc/NEWS: Announce the new feature.
+
+ * configure.ac (native-image-api): New option, OFF by default.
+ (HAVE_NATIVE_IMAGE_API): If native-image-api is selected, add
+ w32image.o to W32_OBJ.
+
+2020-04-14 Juri Linkov <juri@linkov.net>
+
+ Fix hi-lock test and add new test for unhighlight (bug#40337)
+
+ * lisp/hi-lock.el (hi-lock-unface-buffer): Use hi-lock--hashcons
+ only on strings, not lists.
+
+ * test/lisp/hi-lock-tests.el (hi-lock-bug26666): Revert previous change,
+ use "a" instead of "b".
+ (hi-lock-unhighlight): New test.
+
+2020-04-14 Juri Linkov <juri@linkov.net>
+
+ * lisp/vc/vc.el (vc-deduce-fileset): Improve docstring (bug#34949).
+
+2020-04-13 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-finalize-relocs): Better commentary.
+
+2020-04-13 Andrea Corallo <akrl@sdf.org>
+
+ Fix native-compile-async for bug#40602.
+
+ * lisp/emacs-lisp/comp.el (native-compile-async): Relax coherency condition.
+
+2020-04-13 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-04-13 Andrea Corallo <akrl@sdf.org>
+
+ * src/lread.c (Fload): Clean-up unnecessary sanity check.
+
+ 'is_native_elisp' can't be non zero if NATIVE_COMP_FLAG is not set.
+
+2020-04-13 Andrea Corallo <akrl@sdf.org>
+
+ Fix function find mechanism for installed instance.
+
+ * src/lread.c (parent_directory): New function.
+ (Fload): Make use of 'parent_directory' and fix load-history
+ build-up with relative paths.
+
+2020-04-13 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ f84aed5fd2 (origin/emacs-27) Clarify documentation on inhibit-modific...
+
+2020-04-13 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 1dfc497fac Minor wording change in Introduction to Programming in Ema...
+ ff09b4eeac Fix 'flymake-show-diagnostics-buffer' when line numbers ar...
+ 63e8d0ea87 Fix last changes describing mail commands
+ 01212a762f Do setup Flymake in file-less Elisp buffers
+ 36873ef2b2 Fix error message for ‘cl-struct-unknown-slot’ (bug#39995)
+ 3f9310b0fe Fix and improve documentation of mail-related features
+ 1482a75efa Fix build failure with Fx_gtk_debug
+ cf57663f2a Mention jit-lock deferred as an alternative to fast-but-im...
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-04-13 Glenn Morris <rgm@gnu.org>
+
+ * doc/lispref/processes.texi (Network): Fix xref usage.
+
+ * doc/emacs/msdos.texi (Windows Keyboard): Fix xref.
+
+2020-04-13 Albert <georgealbert@qq.com>
+
+ Fix previous change in w32fns.c
+
+ * src/w32fns.c (w32_msg_pump): Simplify by not calling
+ ImmGetOpenStatus.
+ (Fw32_get_ime_open_status): Fix a typo.
+
+2020-04-13 Eli Zaretskii <eliz@gnu.org>
+
+ Document the new 'w32-get/set-ime-open-status' functions
+
+ * doc/emacs/msdos.texi (Windows Keyboard): Document
+ 'w32-set-ime-open-status'.
+
+ * etc/NEWS: Announce the new IME-related functions.
+
+2020-04-13 Albert <georgealbert@qq.com>
+
+ Support toggling native Input Methods on MS-Windows
+
+ * src/w32term.h (WM_EMACS_IME_STATUS): New message code.
+
+ * src/w32fns.c (ImmGetOpenStatus_Proc, ImmSetOpenStatus_Proc): New
+ typedefs.
+ (w32_msg_pump): Handle the WM_EMACS_IME_STATUS message.
+ (Fw32_get_ime_open_status, Fw32_set_ime_open_status): New functions
+ (syms_of_w32fns): Defsubr them.
+ (globals_of_w32fns): Load ImmGetOpenStatus and ImmSetOpenStatus
+ from IMM2.DLL.
+
+2020-04-13 Štěpán Němec <stepnem@gmail.com>
+
+ gnus-shorten-url: Improve and avoid args-out-of-range error
+
+ 'gnus-shorten-url' (used by 'gnus-summary-browse-url') ignored
+ fragment identifiers and didn't check substring bounds, in some cases
+ leading to runtime errors, e.g.:
+
+ (gnus-shorten-url "https://some.url.with/path/and#also_a_long_target" 40)
+ ;; => Lisp error: (args-out-of-range "/path/and" -18 nil)
+
+ This commit makes it account for #fragments and fixes faulty string
+ computation, reusing existing helper function. (bug#39980)
+
+ * lisp/vc/ediff-init.el (ediff-truncate-string-left): Rename to
+ 'string-truncate-left' and move...
+ * lisp/emacs-lisp/subr-x.el (string-truncate-left): ...here.
+ All callers changed.
+ * lisp/gnus/gnus-sum.el (gnus-shorten-url): Fix args-out-of-range
+ error, don't drop #fragments, use 'string-truncate-left'.
+
+2020-04-13 Andrea Corallo <akrl@sdf.org>
+
+ * src/lread.c (Fload): Add comment.
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-04-13 Andrea Corallo <akrl@sdf.org>
+
+ Revert "Fix org for eln new compilation folder layout"
+
+ This reverts commit f77f6ca77054ca6122df2742345710b7493ad293.
+
+2020-04-13 Andrea Corallo <akrl@sdf.org>
+
+ Introduce load-true-file-name
+
+ * src/comp.c (maybe_defer_native_compilation): Use
+ `load-true-file-name' instead of `load-file-name'.
+
+ * src/lread.c (Fload, end_of_file_error, read1, read_list)
+ (init_lread, syms_of_lread): Add new `load-true-file-name' and
+ fake `load-file-name' value when loading .eln files.
+
+2020-04-13 Eli Zaretskii <eliz@gnu.org>
+
+ Fix last change
+
+ * lisp/mail/rmail.el (rmail-simplified-subject): A prefix can have
+ up to 4 characters, not 3.
+
+2020-04-13 Eli Zaretskii <eliz@gnu.org>
+
+ Improve support of "Re:" in Rmail
+
+ * lisp/mail/rmail.el (rmail-simplified-subject)
+ (rmail-reply-regexp): Recognize U+FF1A FULLWIDTH COLON as a colon
+ after "Re:"-type prefixes.
+ (rmail-re-abbrevs): New defcustom with localized abbreviations of
+ "Re:".
+ (rmail-reply-regexp): Use 'rmail-re-abbrevs'. Recognize U+FF1A
+ in addition to the ASCII colon.
+
+ * etc/NEWS: Call out the new defcustom 'rmail-re-abbrevs'.
+
+2020-04-13 Juri Linkov <juri@linkov.net>
+
+ Fix hi-lock test and add new test for case-fold (bug#40337)
+
+ * lisp/hi-lock.el (hi-lock--regexps-at-point): Handle font-lock faces.
+ (hi-lock-unface-buffer): Simplify default value handling.
+ (hi-lock-set-pattern): Add either lighter or regexp to
+ hi-lock-interactive-lighters.
+ (hi-lock-set-pattern): Put overlay prop hi-lock-overlay-regexp to
+ either lighter or regexp.
+
+ * test/lisp/hi-lock-tests.el (hi-lock-bug26666): Use "b" instead of "a".
+ (hi-lock-case-fold): New test.
+
+2020-04-12 Štěpán Němec <stepnem@gmail.com>
+
+ Fix bootstrap compiler warnings about `read-library-name'
+
+ Introduced by
+
+ 2020-03-28T22:16:28+01:00!stepnem@gmail.com
+ 2c45091791 (load-library, locate-library: Use read-library-name)
+
+ Thanks to Juanma Barranquero <lekktu@gmail.com> for reporting.
+
+ * lisp/files.el:
+ * lisp/subr.el: Declare 'read-library-name'.
+
+2020-04-12 Philipp Stephani <phst@google.com>
+
+ Fix error in 'call-process-region' when START is nil (Bug#40576)
+
+ * src/callproc.c (Fcall_process_region): Fix behavior when START is
+ nil and DELETE is non-nil.
+
+ * test/src/callproc-tests.el
+ (call-process-region-entire-buffer-with-delete): New unit test.
+
+2020-04-12 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-04-12 Andrea Corallo <akrl@sdf.org>
+
+ * src/pdumper.c (dump_do_dump_relocation): Optimize native dump load.
+
+ Check just once if is a local build or Emacs got installed.
+
+2020-04-12 Andrea Corallo <akrl@sdf.org>
+
+ Implement working make install for native build.
+
+2020-04-12 Andrea Corallo <akrl@sdf.org>
+
+ Set invocation variables during dump load.
+
+ Vinvocation_directory must be set during dump load process to support
+ .eln load.
+
+ * src/pdumper.h: (pdumper_load): Add argv0 and original_pwd
+ parameters.
+
+ * src/pdumper.c (pdumper_load): Add argv0 and original_pwd
+ parameter plus call 'set_invocation_vars'.
+
+ * src/lisp.h (set_invocation_vars): New function.
+
+ * src/emacs.c (set_invocation_vars): New function.
+ (init_cmdargs): Move logic into 'set_invocation_vars' and call it.
+ (load_pdump): Add 'original_pwd' parameter and update calls to
+ 'pdumper_load'.
+ (main): Set emacs_wd earlier and update call to 'pdumper_load'.
+
+2020-04-12 Andrea Corallo <akrl@sdf.org>
+
+ Implement position independent dump.
+
+ Set the filename for every compilation unit as realtive to obtain a
+ position independent dump.
+
+ * lisp/loadup.el: Modify filename for every compilation unit as
+ position independent.
+
+ * src/pdumper.c (dump_do_dump_relocation): Update to be invocation
+ directory relative.
+
+2020-04-12 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (native-comp-unit-set-file): New function.
+
+ * src/comp.c (native-comp-unit-file): Better parameter name.
+
+2020-04-12 Philipp Stephani <phst@google.com>
+
+ Also use named functions for the ‘gv’ declare forms (Bug#40491)
+
+ * lisp/emacs-lisp/gv.el (gv--expander-defun-declaration)
+ (gv--setter-defun-declaration): New helper functions; use them.
+
+2020-04-12 Philipp Stephani <phst@google.com>
+
+ Use named functions in {defun,macro}-declarations-alist (Bug#40491)
+
+ * lisp/emacs-lisp/byte-run.el (byte-run--set-advertised-calling-convention)
+ (byte-run--set-obsolete, byte-run--set-interactive-only)
+ (byte-run--set-pure, byte-run--set-side-effect-free)
+ (byte-run--set-compiler-macro, byte-run--set-doc-string)
+ (byte-run--set-indent, byte-run--set-debug)
+ (byte-run--set-no-font-lock-keyword): New helper functions.
+ (defun-declarations-alist, macro-declarations-alist): Use them.
+
+2020-04-12 Philipp Stephani <phst@google.com>
+
+ Fix a bootstrap issue with unescaped character literal detection.
+
+ * src/lread.c (load_warn_unescaped_character_literals): Deal with the
+ case that 'byte-run--unescaped-character-literals-warning' isn't yet
+ defined.
+
+2020-04-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ Remove UNSIGNED_CMP
+
+ I added this macro in 2011 to fix some signedness comparison bugs.
+ However, it’s a weird macro and the bugs can be fixed in a
+ more-straightforward way. This helps performance slightly (0.5%) on my
+ platform (Fedora 31 x86-64, GCC 9.3.1 with -O2).
+ * src/casefiddle.c (do_casify_natnum): Use simple comparison
+ instead of UNSIGNED_CMP.
+ * src/character.h (CHAR_VALID_P, SINGLE_BYTE_CHAR_P, CHAR_STRING):
+ * src/composite.h (COMPOSITION_ENCODE_RULE_VALID):
+ * src/lisp.h (ASCII_CHAR_P):
+ Now an inline function, and uses simple comparison instead of
+ UNSIGNED_CMP.
+ * src/dispextern.h (FACE_FROM_ID, FACE_FROM_ID_OR_NULL)
+ (IMAGE_FROM_ID, IMAGE_OPT_FROM_ID): Move these to ...
+ * src/frame.h (FACE_FROM_ID, FACE_FROM_ID_OR_NULL)
+ (IMAGE_FROM_ID, IMAGE_OPT_FROM_ID): ... here, and make them
+ inline functions that no longer use UNSIGNED_CMP.
+ * src/keyboard.c (read_char): UNSIGNED_CMP is not needed here
+ since XFIXNAT always returns a nonnegative value.
+ * src/lisp.h (UNSIGNED_CMP): Remove; no longer used.
+
+2020-04-12 Juri Linkov <juri@linkov.net>
+
+ * lisp/hi-lock.el (hi-lock-highlight-range): Bump default value (bug#40224)
+
+ * lisp/hi-lock.el (hi-lock-highlight-range): Change default value
+ from 200_000 to 2_000_000.
+
+2020-04-12 Juri Linkov <juri@linkov.net>
+
+ Implement case-insensitivity in hi-lock (bug#40337)
+
+ * lisp/hi-lock.el (hi-lock-interactive-lighters): New buffer-local variable.
+ (hi-lock-mode): Set hi-lock-interactive-lighters to nil.
+ (hi-lock-line-face-buffer): Use case-fold-search and search-upper-case.
+ (hi-lock-face-buffer): Add new arg LIGHTER. Use case-fold-search,
+ search-upper-case and search-spaces-regexp.
+ (hi-lock-face-phrase-buffer): Don't call hi-lock-process-phrase.
+ Use case-fold-search, search-upper-case and search-whitespace-regexp.
+ (hi-lock-face-symbol-at-point): Use case-fold-search and search-upper-case.
+ (hi-lock-unface-buffer): Use hi-lock-interactive-lighters to get
+ a human-readable string for completion and x-popup-menu.
+ (hi-lock-process-phrase): Remove function.
+ (hi-lock-set-pattern): Add new args LIGHTER, CASE-FOLD, SPACES-REGEXP.
+ Set font-lock pattern to a search function. Add mapping from
+ lighter or regexp to pattern to hi-lock-interactive-lighters.
+ Let-bind case-fold-search and search-spaces-regexp in search functions.
+
+ * lisp/isearch.el (isearch--highlight-regexp-or-lines): Replace ugly code
+ with let-binding of case-fold-search, search-upper-case, search-spaces-regexp.
+ (isearch-highlight-regexp, isearch-highlight-lines-matching-regexp):
+ Use lambda.
+
+2020-04-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * etc/NEWS: Mention 'cl-font-lock-built-in-mode'
+
+2020-04-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/cl-font-lock.el: Fix header and make it a minor mode
+
+ Change copyright to FSF and licence to GPLv3+.
+ Tweak Commentary (the code doesn't seem to provide the lambda
+ prettification mentioned).
+
+ (cl-font-lock-add-regexes): Remove macro.
+ (cl-font-lock-built-in-keywords): New variable.
+ (cl-font-lock-built-in-mode): New minor mode.
+
+2020-04-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/cl-font-lock.el: New file
+
+ Taken from commit 1a54066611da213626ab69ea426ba3c63ece3438
+ of https://github.com/cl-font-lock/cl-font-lock,
+ but with names reverted to a `cl-font-lock-` prefix.
+
+2020-04-11 Mattias Engdegård <mattiase@acm.org>
+
+ Allow ENCODE_FILE and DECODE_FILE to use no-copy conversion
+
+ They already did return their argument under some circumstances;
+ this change broadens it to further reduce allocation in common cases
+ (bug#40407).
+
+ * src/coding.c (convert_string_nocopy): New function.
+ (decode_file_name, encode_file_name): Use convert_string_nocopy.
+ * src/coding.h (ENCODE_FILE, DECODE_FILE): Note the nocopy semantics.
+
+2020-04-11 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ fd27685c1e (origin/emacs-27) ; * doc/lispref/keymaps.texi (Extended M...
+ 6057d79a4e * doc/lispref/keymaps.texi (Extended Menu Items): Tweak :k...
+ 17a1bb5a03 Fix redisplay when scrolling under redisplay-dont-pause
+ 90321f595c Fix face extension in pulse.el
+ 36c42d2a30 * doc/misc/tramp.texi (Bug Reports): Avoid line breaks in ...
+ d5750af151 Avoid assertion violation in intervals.c
+ 18d1bc0a09 Improve documentation of 'jit-lock-contextually'
+ 08486f4cae Speed up 'resize-mode' child frames a little
+ f451ef9308 ; * etc/NEWS: Mention 'executing-macro' in removed vars.
+ c49d379f17 Fix some problems with moving and resizing child frames
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-04-11 Federico Tedin <federicotedin@gmail.com>
+
+ Reword documentation for eshell-variable-aliases-list
+
+ * lisp/eshell/esh-var.el (eshell-variable-aliases-list): Update
+ documentation string to avoid passive tense.
+
+2020-04-11 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp.el (tramp-action-process-alive): Read pending output.
+
+2020-04-09 Mattias Engdegård <mattiase@acm.org>
+
+ Set last-coding-system-used upon ASCII conversion bypass (bug#40407)
+
+ Spotted by Kazuhiro Ito.
+
+ * src/coding.c (code_convert_string):
+ Set Vlast_coding_system if appropriate.
+ * test/src/coding-tests.el (coding-nocopy-ascii): Add test.
+
+2020-04-09 Eli Zaretskii <eliz@gnu.org>
+
+ Fix display of boxed header-line
+
+ * src/xdisp.c (init_iterator): Set IT->face_box_p flag for a boxed
+ mode/header/tab line. (Bug#40521)
+
+2020-04-09 Mattias Engdegård <mattiase@acm.org>
+
+ Fix ASCII-only conversion logic (bug#40407)
+
+ To sidestep conversion altogether when EOL conversion applies, we must
+ either be encoding a string without NL, or decoding without CR.
+
+ * src/coding.c (string_ascii_p): Revert to a pure predicate.
+ (code_convert_string): Fix logic. Don't use uninitialised
+ ascii_p (removed). Use memchr to detect CR or LF in string when needed.
+ * test/src/coding-tests.el (coding-nocopy-ascii):
+ Update tests to include encodings with explicit EOL conversions.
+
+2020-04-09 Mattias Engdegård <mattiase@acm.org>
+
+ chinese-hz is not ASCII compatible (bug#40407)
+
+ * lisp/language/chinese.el: Disable :ascii-compatible-p for chinese-hz.
+ * test/lisp/international/mule-tests.el (mule-hz): New test.
+
+2020-04-09 Mattias Engdegård <mattiase@acm.org>
+
+ Don't crash with invalid argument in check-coding-systems-region
+
+ * src/coding.c (Fcheck_coding_systems_region): Don't crash if
+ the third arg contains something that isn't a coding system.
+ * test/src/coding-tests.el (coding-check-coding-systems-region):
+ New test.
+
+2020-04-09 Mattias Engdegård <mattiase@acm.org>
+
+ Don't rely on copying in {EN,DE}CODE_FILE
+
+ Callers of ENCODE_FILE and DECODE_FILE should not assume that these
+ functions always return a new string (bug#40407).
+
+ * src/w32fns.c (Fw32_shell_execute):
+ * src/w32proc.c (Fw32_application_type):
+ Sink taking the address of a Lisp string past GC points.
+ Copy values returned from ENCODE_FILE before mutating them.
+
+2020-04-09 Eli Zaretskii <eliz@gnu.org>
+
+ Fix decoding of ASCII strings with embedded CR characters
+
+ * src/coding.c (string_ascii_p): Return a negative value if an
+ all-ASCII string STR includes the CR character, otherwise a
+ positive value.
+ (code_convert_string): If the string is ASCII, but includes CR
+ characters, use the fast path only if EOL doesn't need to be
+ decoded. (Bug#40519)
+
+ * test/src/coding-tests.el (coding-nocopy-ascii): Add more tests
+ for bug#40519.
+
+2020-04-09 Eli Zaretskii <eliz@gnu.org>
+
+ Fix decoding ASCII strings with embedded CR characters
+
+ * src/coding.c (string_ascii_p): Return a negative value if an
+ all-ASCII string STR includes the CR character, otherwise a
+ positive value.
+ (code_convert_string): If the string is ASCII, but includes CR
+ characters, use the fast path only if EOL doesn't need to be
+ decoded. (Bug#40519)
+
+ * test/src/coding-tests.el (coding-nocopy-ascii): Add tests for
+ bug#40519.
+
+2020-04-08 Eli Zaretskii <eliz@gnu.org>
+
+ Support character composition for Hangul jamo
+
+ * lisp/language/korean.el: Add composition rules for conjoining
+ Hangul jamo. (Bug#40502)
+
+2020-04-08 Paul Eggert <eggert@cs.ucla.edu>
+
+ Revert my KEY_OPS_CFLAGS change to src/Makefile.in
+
+ Now that -Og inlining has been improved this is no longer helpful.
+ * src/Makefile.in (KEY_OPS_CFLAGS): Remove. All uses removed.
+ This improved CPU performance of ‘make compile-always’ by 5% on my
+ platform, which was gcc -Og, GCC 9.3.1 20200317 (Red Hat 9.3.1-1),
+ Fedora 31 x86-64 (AMD Phenom II X4 910e, circa 2010).
+
+2020-04-08 Paul Eggert <eggert@cs.ucla.edu>
+
+ Improve inlining when compiling with -Og
+
+ * src/conf_post.h (EXTERN_INLINE) [!EMACS_EXTERN_INLINE]:
+ Make it static inline, not merely static. This is a worthwhile
+ performance improvement on my two platforms A and B (see below).
+ On my platform A this change improves user+system CPU performance of
+ ‘make compile-always’ by 52% on an -Og build, and by 1.4% on the
+ default -O2 build. On my platform B this improves the same benchmark
+ by 41% on an -Og build, and by -0.8% on the default -O2 build.
+ That "-0.8%" is a small negative for this change, and I recall that
+ it is why I didn't make this change earlier. However, Platform B uses
+ an older GCC so we needn't worry overmuch about this small negative.
+
+ With this change the performance advantage of -O2 over -Og has dropped
+ on platform A; formerly -O2 was 87% faster than -Og, and now it is
+ only 25% faster. On platform B the performance advantage of -O2 over
+ -Og has dropped from being 62% faster to being 14% faster.
+
+ Platform A is GCC 9.3.1 20200317 (Red Hat 9.3.1-1) on Fedora 31
+ x86-64 (AMD Phenom II X4 910e, circa 2010). Platform B is GCC (Ubuntu
+ 7.5.0-3ubuntu1~18.04) 7.5.0 on Ubuntu 18.04.4 (Intel Xeon E3-1225 V2,
+ circa 2012).
+
+ This patch was inspired by a suggestion by Andrea Corallo in:
+ https://lists.gnu.org/r/emacs-devel/2020-04/msg00263.html
+
+2020-04-07 Robert Pluim <rpluim@gmail.com>
+
+ Add :coding support to open-network-stream and open-gnutls-stream
+
+ * doc/lispref/processes.texi (Network): Describe :coding keyword support.
+
+ * doc/misc/emacs-gnutls.texi (Help For Developers): Describe :coding
+ keyword support.
+
+ * etc/NEWS: Announce change to open-network-stream and
+ open-gnutls-stream.
+
+ * lisp/net/gnutls.el (open-gnutls-stream): Add support for :coding, pass it
+ down to open-network-stream.
+
+ * lisp/net/network-stream.el (open-network-stream)
+ (network-stream-open-plain, network-stream-open-starttls): Add
+ support for :coding, pass it down to make-network-process.
+ (network-stream-open-shell): Add support-for :coding, use
+ set-process-coding-system to set it after process creation.
+
+2020-04-07 Robert Pluim <rpluim@gmail.com>
+
+ Use length field when dns-query is using TCP
+
+ * net/dns.el (dns-write): Correct spelling in docstring.
+ (dns-read): Add optional tcp-p parameter, skip 2-byte length field
+ if non-nil.
+ (dns-query): Tell dns-read and dns-write if we're using TCP.
+
+2020-04-06 Mattias Engdegård <mattiase@acm.org>
+
+ utf-7 and utf-7-imap are not ASCII-compatible (bug#40407)
+
+ * lisp/international/mule-conf.el (utf-7, utf-7-imap):
+ Add expedient to disable the :ascii-compatible-p property set
+ automatically by define-coding-system.
+ * test/lisp/international/mule-tests.el (mule-utf-7): New test.
+
+2020-04-06 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify gcc in xpm_scan
+
+ * src/image.c (xpm_scan): Redo a loop for clarity.
+ This also pacifies --enable-gcc-warnings (GCC 9.3.1 x86-64 with -Og).
+
+2020-04-06 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+ * lisp/emacs-lisp/comp.el (comp-c-func-name): Fix for M-x disassemble
+
+ * src/comp.c (emit_FIXNUMP): Don't emit a shift when unnecessary.
+
+2020-04-06 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix case that $PATH is longer than 4096 chars in Tramp
+
+ * lisp/net/tramp-sh.el (tramp-set-remote-path): Use `tramp-send-command'
+ directly.
+
+ * test/lisp/net/tramp-tests.el (tramp-test-vec): New defconst.
+ (tramp--test-enabled, tramp--test-message)
+ (tramp--test-backtrace, tramp-test03-file-name-host-rules)
+ (tramp-test18-file-attributes, tramp-test20-file-modes)
+ (tramp-test26-file-name-completion)
+ (tramp-test33-environment-variables, tramp-test35-remote-path)
+ (tramp-test36-vc-registered, )
+ (tramp-test43-asynchronous-requests): Use it.
+ (tramp-test29-start-file-process, tramp-test30-make-process)
+ (tramp-test33-environment-variables): Remove Hydra specific result.
+ (tramp-test35-remote-path): Rewrite partially.
+
+2020-04-06 Yuan Fu <casouri@gmail.com>
+
+ Unify and improve gdb-mi source buffer display logic
+
+ Unify the behavior of source buffer display for gdb-mi. Before this
+ change, stepping and other gdb command handlers use 'gud-display-line',
+ and 'gdb-goto-breakpoint' uses 'gdb-display-source-buffer'. Now whenever
+ gdb-mi code tries to open a source buffer, 'gdb-display-source-buffer'
+ is used. Also, simplify the logic in 'gdb-display-source-buffer' and
+ add a feature to limit the maximum number of source windows.
+
+ * doc/emacs/building.texi (GDB User Interface Layout): Explain source
+ file display in GDB.
+ * etc/NEWS (gdb-mi): Add news about source display.
+ * lisp/progmodes/gdb-mi.el (gdb-source-window): Remove variable,
+ change to 'gdb-source-window-list'.
+ (gdb-source-window-list): New variable.
+ (gdb-display-source-buffer-action,
+ gdb-max-source-window-count): New options.
+ (gdb-init-1, gdb-setup-windows, gdb-load-window-configuration,
+ gdb-restore-windows): Use 'gdb-source-window' rather than
+ 'gdb-source-window-list'.
+ (gdb-save-window-configuration): Use 'gdb-source-window' rather than
+ 'gdb-source-window-list'. And consider any buffer that is not a
+ command or function buffer as a source buffer.
+ (gdb-display-source-buffer): Use new logic.
+ (gdb-goto-breakpoint): Remove 'display-buffer' call
+ and don't set 'gdb-source-buffer' anymore.
+ * lisp/progmodes/gud.el (gud-display-line): If used by gdb-mi, use
+ 'gdb-display-source-buffer' rather than 'display-buffer'. Don't set
+ 'gdb-source-buffer' anymore.
+
+2020-04-06 Martin Rudalics <rudalics@gmx.at>
+
+ Fix problems when dragging frames with the mouse
+
+ Re-implement 'mouse-drag-frame' via two new functions -
+ 'mouse-drag-frame-resize' and 'mouse-drag-frame-move'. This is
+ needed because with some toolkits the notifications for frame
+ movement and resizing arrive asynchronously, breaking any
+ calculations using intermediate frame sizes and positions.
+
+ * lisp/mouse.el (mouse-drag-mode-line, mouse-drag-left-edge)
+ (mouse-drag-top-left-corner, mouse-drag-top-edge)
+ (mouse-drag-top-right-corner, mouse-drag-right-edge)
+ (mouse-drag-bottom-right-corner, mouse-drag-bottom-edge)
+ (mouse-drag-bottom-left-corner): Call 'mouse-drag-frame-resize'
+ instead of 'mouse-drag-frame'.
+ (mouse-drag-frame): Split into two new functions -
+ 'mouse-drag-frame-move' and 'mouse-drag-frame-resize'.
+ (mouse-drag-frame-resize, mouse-drag-frame-move): New functions
+ to implement functionality of the removed 'mouse-drag-frame'.
+
+2020-04-05 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+ * src/comp.c (emit_XFIXNUM): Fix for LSB_TAG plus annotate a FIXME.
+
+ * src/comp.c (emit_const_lisp_obj, emit_mvar_val): Fix.
+
+ * src/comp.c (hash_native_abi): Fix assertion.
+
+2020-04-05 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (emit_binary_op): New function.
+
+ Wrap gcc_jit_context_new_binary_op within emit_binary_op to make sure
+ input type are coherent and save a slew of code.
+
+2020-04-05 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c: Emit cast only when necessary.
+
+ Coerce only when the destination type is different from the current
+ one.
+
+2020-04-05 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c: Add MSB TAG and wide int support.
+
+ * src/comp.c: Clean-up unnecessary field declaration.
+
+ * lisp/emacs-lisp/comp.el (native-compile): Better documentation.
+
+2020-04-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/coding.c (code_convert_string): Fix type mismatches.
+
+2020-04-05 Eli Zaretskii <eliz@gnu.org>
+
+ Fix a recent change in bignum.c
+
+ * src/bignum.c (check_int_nonnegative): Fix a recent change.
+ Reported by Glenn Morris <rgm@gnu.org>.
+
+2020-04-05 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix thinko in tramp-cache.el
+
+ * lisp/net/tramp-cache.el (tramp-set-connection-property)
+ (tramp-flush-connection-property)
+ (tramp-flush-connection-properties): Use `tramp-file-name-p'.
+
+2020-04-05 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 6de20c7eab (origin/emacs-27) Fix syntax error in man page.
+ f8607d3c03 Handle filling of indented ChangeLog function entries
+ 7e78f0d1b2 Fix void-variable n-reb in re-builder (Bug#40409)
+ 452d776a5d Fix small bug in copy_string_contents.
+ fa823653ff Fix invocations of gpg from Gnus
+ d4f51d0a2e Don't draw GTK's internal border and tab bar on top of eac...
+ 38731d504e ; * src/buffer.c (syms_of_buffer) <inhibit-read-only>: Doc...
+ 44ac9e48bb Tweak htmlfontify's generated output
+
+2020-04-05 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ ac3da1dd96 Handle project--files-in-directory finding no files better
+ 650a664ccd Let imenu to work on the menu bar when its list is a singl...
+
+2020-04-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-macs.el (cl-defstruct): Avoid known cl-defsubst breakage
+
+2020-04-05 Mattias Engdegård <mattiase@acm.org>
+
+ Avoid expensive recoding for ASCII identity cases (bug#40407)
+
+ Optimise for the common case of encoding or decoding an ASCII-only
+ string using an ASCII-compatible coding, for file names in particular.
+
+ * src/coding.c (string_ascii_p): New function.
+ (code_convert_string): Return the input string for ASCII-only inputs
+ and ASCII-compatible codings.
+ * test/src/coding-tests.el (coding-nocopy-ascii): New test.
+
+2020-04-05 Mattias Engdegård <mattiase@acm.org>
+
+ Suppress relint diagnostics in rx-tests.el
+
+ * test/lisp/emacs-lisp/rx-tests.el (rx-char-any, rx-any):
+ Suppress relint complaints; these regexps are intentionally bad.
+
+2020-04-05 Mattias Engdegård <mattiase@acm.org>
+
+ Fix inverted NOCOPY encode/decode parameter (bug#40407)
+
+ In {encode,decode}-coding-string, the NOCOPY parameter had the
+ opposite effect to what was intended and documented. This 18 year old
+ bug (introduced in 4031e2bf0a) only affected calls with CODING-SYSTEM
+ being nil.
+
+ * src/coding.c (code_convert_string): Correct use of NOCOPY.
+ * test/src/coding-tests.el (coding-nocopy-trivial): New test.
+
+2020-04-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Improve integer range checking
+
+ * src/bignum.c (check_integer_range, check_uinteger_max)
+ (check_int_nonnegative): New functions.
+ * src/frame.c (check_frame_pixels): New function.
+ (Fset_frame_height, Fset_frame_width, Fset_frame_size): Use it.
+ * src/lisp.h (CHECK_RANGED_INTEGER, CHECK_TYPE_RANGED_INTEGER):
+ Remove these macros. Unless otherwise specified, all callers
+ replaced by calls to check_integer_range, check_uinteger_range,
+ check_int_nonnegative.
+ * src/frame.c (gui_set_right_divider_width)
+ (gui_set_bottom_divider_width):
+ * src/nsfns.m (ns_set_internal_border_width):
+ * src/xfns.c (x_set_internal_border_width):
+ Using check_int_nonnegative means these functions no longer
+ incorrectly reject negative bignums; they treat them as 0,
+ just like negative fixnums.
+
+2020-04-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/lisp.h: Update overly-optimistic comment.
+
+2020-04-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/arc-mode.el: Rewrite displaying the summaries
+
+ Completely rewrite the code that displayes the summaries, so all
+ backends share the same code.
+
+ (archive--summarize-descs): New function.
+ (archive-arc-summarize, archive-lzh-summarize, archive-zip-summarize)
+ (archive-zoo-summarize, archive-rar-summarize, archive-7z-summarize)
+ (archive-ar-summarize): Use it.
+ (archive-hidden-columns): New custom.
+ (archive-alternate-hidden-columns): New const.
+ (archive-mode-map): Always enable `archive-alternate-display`.
+ (archive-alternate-display): Set `archive-hidden-columns`.
+ (archive-hideshow-column): New command.
+ (archive--fit, archive--fit2, archive--enabled-p): New aux functions.
+
+2020-04-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/arc-mode.el: Remove make-(local-variable|variable-buffer-local)
+
+ (archive-file-list-start, archive-file-list-end)
+ (archive-proper-file-start, archive-file-name-indent, archive-remote)
+ (archive-member-coding-system, archive-alternate-display)
+ (archive-file-name-coding-system, archive-files): Use `defvar-local`.
+ (archive-extract): Use `setq-local`.
+ (archive-get-descr): Use `user-error` when clicking on a directory.
+
+2020-04-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Avoid SAFE_ALLOCA in Fstring, Funibyte_string
+
+ * src/character.c (Fstring, Funibyte_string):
+ Redo to avoid the need for a temporary array allocation
+ and then a copying from that array to the destination.
+
+2020-04-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/arc-mode.el (archive--file-desc): Add fields from other structs
+
+ Add fields `size`, `time` (used by all backends) as well as
+ `pos`, `ratio`, `uid`, and `gid` (used only be some backends).
+
+ (archive-arc--file-desc, archive-rar--file-desc, archive-ar--file-desc)
+ (archive-lzh--file-desc, archive-zip--file-desc, archive-7z--file-desc):
+ Remove defstructs.
+ (archive-arc-summarize): Record size and time in the descrs.
+ (archive-lzh-summarize): Record size, time, uid, and gid in the descrs.
+ (archive-zip-summarize): Record size and time in the descrs.
+ (archive-zoo-summarize): Record size and time in the descrs.
+ (archive-rar-summarize): Adjust to use of `archive--file-desc`.
+ (archive-7z-summarize): Adjust to new constructor.
+ (archive-ar-summarize): Adjust to use of `archive--file-desc`.
+
+ (archive-ar-write-file-member): Remove mode-to-int hack.
+ (archive-get-descr): Directory entries aren't regular members.
+
+2020-04-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Revert unneeded part of gcc -Og change
+
+ * configure.ac (DEFINE_KEY_OPS_AS_MACROS):
+ Undo this recent change to configure.ac; it’s not needed.
+
+2020-04-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ * lib-src/Makefile.in (LINK_CFLAGS): Remove; unused.
+
+2020-04-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Default gcc -Og to inlining key ops
+
+ Problem reported by Martin Rudalics in:
+ https://lists.gnu.org/r/emacs-devel/2020-04/msg00195.html
+ * configure.ac (DEFINE_KEY_OPS_AS_MACROS): Define if -Og.
+ * src/Makefile.in (KEY_OPS_CFLAGS): New macro.
+ (EMACS_CFLAGS): Use it.
+ * src/lisp.h (DEFINE_KEY_OPS_AS_MACROS): Let the gcc command line
+ specify it. Remove use of undocumented INLINING macro.
+
+2020-04-04 Eli Zaretskii <eliz@gnu.org>
+
+ Support the "explore" command in gdb-mi.el
+
+ * lisp/progmodes/gdb-mi.el (gdb-control-commands-regexp): Add
+ support for "explore", "explore value", and "explore type".
+ Allow more than one word after control commands.
+ (gdb-gdb): Decrease gdb-control-level when we get the "(gdb)"
+ prompt, which signals that "explore" exited. (Bug#40250)
+
+2020-04-04 Eli Zaretskii <eliz@gnu.org>
+
+ Fix face spec handling for 'default' "terminal class"
+
+ * lisp/faces.el (face-spec-choose): Reverse order of 'defaults'
+ and 'result' when generating attribute list, so that the spec for
+ 'default' "terminal class" is indeed overridden by the actual
+ class's spec, per the documentation. (Bug#40336)
+
+2020-04-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/arc-mode.el: Remove unused struct fields
+
+ (archive--file-desc): Remove `case-fiddled`.
+ Change all subtypes's constructors as their callers accordingly.
+ (archive--file-desc-case-fiddled): New function.
+ (archive-int-to-mode): Accept a nil input.
+ Make all callers take advantage of it.
+ (archive-arc-rename-entry): Use `make-string`.
+ (archive-zip--file-desc): Change `pos+len` field into `pos` field.
+ (archive-zip-chmod-entry): Simplify accordingly.
+ (archive-zip-summarize): Don't bother with `lheader` which was not used.
+ (archive-zoo--file-desc): Delete struct; use archive--file-desc instead.
+ (archive-7z--file-desc): Remove `user` and `group` fields.
+ Adjust constructor and its caller.
+ (archive-ar-summarize): Use `archive-int-to-mode`.
+
+2020-04-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/arc-mode.el: Use cl-structs rather than vectors
+
+ (archive--file-desc, archive--file-summary, archive-arc--file-desc)
+ (archive-lzh--file-desc, archive-zip--file-desc)
+ (archive-zoo--file-desc, archive-rar--file-desc)
+ (archive-7z--file-desc, archive-ar--file-desc): New structs.
+
+ (archive-get-descr, archive-mode, archive-summarize-files)
+ (archive-maybe-copy, archive-extract, archive-*-write-file-member)
+ (archive-expunge, archive-arc-summarize, archive-arc-rename-entry)
+ (archive-lzh-summarize, archive-lzh-rename-entry, archive-lzh-ogm)
+ (archive-zip-summarize, archive-zip-write-file-member)
+ (archive-zip-chmod-entry, archive-zoo-summarize)
+ (archive-rar-summarize, archive-7z-summarize, archive-ar-summarize)
+ (archive-ar-write-file-member): Use struct constructors and accessors
+ instead of `vector` and `aref`.
+
+ (archive-calc-mode): Remove `error` arg which was always non-nil;
+ adjust all callers.
+ Rewrite using `string-to-number` and `file-modes-symbolic-to-number`.
+
+2020-04-03 Alan Mackenzie <acm@muc.de>
+
+ C++ Mode: recognize brace blocks without the hitherto required = sign
+
+ * lisp/progmodes/cc-engine.el (c-looking-at-or-maybe-in-bracelist): Add code
+ to recognize a literal brace expression following an array declaration for
+ C++.
+ (c-looking-at-inexpr-block): Replace c-symbol-chars with c-symbol-char-key,
+ fixing a coding error.
+
+2020-04-03 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-04-03 Andrea Corallo <akrl@sdf.org>
+
+ src/comp.c: Fix i386
+
+ In i386 ABI parameter passing of structs (and unions) is done as
+ pointer + size. Surprisingly this is done *always* even if the
+ structure is known to be word size.
+
+2020-04-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/arc-mode.el (archive-ar-write-file-member): New function
+
+ (archive-ar--name): New function, extracted from `archive-ar-summarize`.
+ (archive-ar-extract): Use it.
+ (archive-ar-summarize): Use it. Put the extname in the slot 0 of the
+ desc vectors.
+
+2020-04-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/arc-mode.el: Remove redundant `:group`s
+
+ (archive-arc, archive-lzh, archive-zip, archive-zoo): Move them
+ to their corresponding defcustom.
+ (archive-7z): New group, that used to be missing.
+
+2020-04-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/arc-mode.el: Use lexical-binding
+
+ (arc-insert-unibyte): Simplify.
+ (archive--mode-revert): Rename from `archive-mode-revert` and adjust
+ for use as an :around advice.
+ (archive-mode): Use setq-local. Use `add-function` to hook into
+ `revert-buffer-function`.
+ (archive-summarize): Don't use `set` on a hook.
+
+2020-04-03 Robert Pluim <rpluim@gmail.com>
+
+ Check for IPv6 servers in dns.el
+
+ * lisp/net/dns.el (dns-set-servers): Set dns-servers to nil when we
+ don't find any DNS servers with nslookup. Add support for IPv6
+ servers. (Bug#40248).
+ (dns-make-network-process): Check for datagram process support before
+ creating a datagram process.
+ (dns-query): Return nil if dns-servers is nil.
+
+2020-04-03 Robert Pluim <rpluim@gmail.com>
+
+ Make make-{network,serial}-process handle :coding nil consistently
+
+ The handling of :coding nil was different between
+ make-{network,serial}-process and make-{pipe}process. Now they all
+ handle :coding nil as if :coding had not been specified.
+
+ * src/process.c (Fmake_serial_process)
+ (set_network_socket_coding_system): Use plist-get to check if
+ :coding has been specified instead of plist-member, to ensure that
+ ":coding nil" does not override coding-system-for-{read,write}.
+
+ * test/lisp/net/network-stream-tests.el
+ (check-network-process-coding-system-bind)
+ (check-network-process-coding-system-no-override)
+ (check-network-process-coding-system-override): New tests.
+
+ * etc/NEWS: Describe change in make-network-process and
+ make-serial-process :coding behavior.
+
+2020-04-03 Ernest N. Mamikonyan <Ernest.Mamikonyan@sig.com> (tiny change)
+
+ Update texinfo.el following changes in 'tex-start-options-string'
+
+ * lisp/textmodes/texinfo.el (texinfo-texi2dvi-options): New
+ defcustom.
+ (texinfo-tex-buffer): Take 'tex-start-options' from
+ 'texinfo-texi2dvi-options'. (Bug#40001)
+
+ * etc/NEWS: Mention the new option.
+
+2020-04-03 Štěpán Němec <stepnem@gmail.com>
+
+ load-library, locate-library: Use read-library-name
+
+ * lisp/emacs-lisp/find-func.el (read-library-name): Add autoload
+ cookie.
+ * lisp/files.el (load-library)
+ * lisp/subr.el (locate-library): Use 'read-library-name' when called
+ interactively. (bug#6652 bug#6679)
+
+2020-04-03 Asher Gordon <AsDaGo@posteo.net>
+
+ Fix movement commands in gomoku
+
+ * lisp/play/gomoku.el (gomoku-mode-map): Bind cursor motion keys
+ to gomoku-specific commands.
+ (gomoku-point-x, gomoku-move-right, gomoku-move-left): New
+ commands.
+ (gomoku--intangible, gomoku-move-ne, gomoku-move-se)
+ (gomoku-move-nw, gomoku-move-sw): Call gomoku-move-left and
+ gomoku-move-right instead of forward-char and backward-char.
+ (Bug#40169)
+
+ * etc/NEWS: Call out the changes.
+
+2020-04-03 Eli Zaretskii <eliz@gnu.org>
+
+ Improve last change
+
+ * lisp/calendar/time-date.el (date-days-in-month): Improve the
+ error message text and make sure MONTH is a number. (Bug#40217)
+
+2020-04-03 Alex Branham <alex.branham@gmail.com>
+
+ Error out if 'date-days-in-month' is given an invalid month
+
+ * lisp/calendar/time-date.el (date-days-in-month): Add test for
+ month validity; signal an error if it isn't. (Bug#40217)
+ * test/lisp/calendar/time-date-tests.el (test-days-in-month): Add
+ a test for the new error.
+
+2020-04-03 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-04-03 Ashish SHUKLA <ashish.is@lostca.se>
+
+ configure.ac: switch to POSIX sh behaviour
+
+2020-04-03 Federico Tedin <federicotedin@gmail.com>
+
+ Copy INSIDE_EMACS env variable to subprocesses in Eshell (Bug#25496)
+
+ * lisp/eshell/em-dirs.el (eshell-dirs-initialize): Add INSIDE_EMACS
+ variable to buffer-local value of eshell-variable-aliases-alist.
+ (eshell-inside-emacs): Add new constant used for INSIDE_EMACS.
+ * lisp/eshell/esh-var.el (eshell-variable-aliases-list): Update doc
+ string; remove mention of eshell-user-aliases-list and explain that
+ variables can optionally be copied to subprocesses' environments.
+ * test/lisp/eshell/eshell-tests.el (eshell-test/inside-emacs-var): Add
+ test for the INSIDE_EMACS variable.
+ * etc/NEWS: Announce changes.
+
+2020-04-03 Juri Linkov <juri@linkov.net>
+
+ * lisp/vc/vc-dir.el: Commands to mark un/registered files (bug#34949)
+
+ * lisp/vc/vc-dir.el (vc-dir-mark-state-files): New function.
+ (vc-dir-mark-registered-files)
+ (vc-dir-mark-unregistered-files): New commands.
+ (vc-dir-mode-map): Bind vc-dir-mark-registered-files to '* r'.
+ (vc-dir-menu-map): Add menu entries for
+ vc-dir-mark-registered-files and vc-dir-mark-unregistered-files.
+
+2020-04-02 Juri Linkov <juri@linkov.net>
+
+ * lisp/window.el (display-buffer): Extend doc with body-function (bug#39822)
+
+2020-04-02 Alexandre Adolphe <alexandre.adolphe@gmail.com>
+
+ Allow negative line width for :box face attribute
+
+ Separate values for box line width and height and allow both to be
+ negative which makes the visual width and height of the boxed string
+ unchanged (Bug#13011).
+
+ * doc/lispref/display.texi (Face Attributes): Modify :box attribute
+ description to reflect the new possibilities.
+ * lisp/cus-face.el (custom-face-attributes): Set box attribute to get
+ two integer to set vertical and horizontal width and modify pre-filter
+ to accept dotted list of two int as valid box attribute.
+ * src/dispextern.h (face): Use two int for box horizontal and vertical
+ line width.
+
+ * src/nsfont.m (nsfont_draw): Use new face attributes.
+ * src/nsterm.m (ns_draw_box, ns_draw_relief): Support separated
+ horizontal and vertical box line width.
+ (ns_dumpglyphs_box_or_relief, ns_maybe_dumpglyphs_background)
+ (ns_dumpglyphs_image, ns_draw_glyph_string_foreground)
+ (ns_draw_composite_glyph_string_foreground): Use new face attributes.
+
+ * src/w32term.c (w32_draw_box_rect, w32_draw_relief_rect): Support
+ separated horizontal and vertical box line width.
+ (x_draw_glyph_string_background, x_draw_glyph_string_foreground)
+ (x_draw_composite_glyph_string_foreground)
+ (x_draw_glyphless_glyph_string_foreground, x_draw_glyph_string_box)
+ (x_draw_image_foreground, x_draw_image_relief)
+ (w32_draw_image_foreground_1, x_draw_image_glyph_string): Use new face
+ attributes.
+
+ * src/xfaces.c (Sinternal_set_lisp_face_attribute, realize_x_face):
+ Accept box attribute as a list of two ints.
+
+ * src/xdisp.c (estimate_mode_line_height, produce_image_glyph)
+ (produce_xwidget_glyph, x_produce_glyphs): Use new face attributes.
+ * src/xterm.c (x_draw_box_rect, x_draw_relief_rect): Support separated
+ horizontal and vertical box line width.
+ (x_draw_glyph_string_background, x_draw_glyph_string_foreground)
+ (x_draw_composite_glyph_string_foreground)
+ (x_draw_glyphless_glyph_string_foreground, x_draw_glyph_string_box)
+ (x_draw_image_foreground, x_draw_image_relief, x_draw_image_foreground_1)
+ (x_draw_image_glyph_string): Use new face attributes.
+
+2020-04-01 Andreas Schwab <schwab@linux-m68k.org>
+
+ Fix compilation with CHECK_STRUCTS
+
+ * src/pdumper.c (dump_buffer): Update hash of struct buffer.
+
+2020-04-01 Michael Albinus <michael.albinus@gmx.de>
+
+ Avoid error messages loading trampver.el
+
+ * lisp/net/trampver.el (tramp-repository-branch)
+ (tramp-repository-version): Bind `debug-on-error' to nil.
+
+2020-04-01 Filipp Gunbin <fgunbin@fastmail.fm>
+
+ javac support in compilation-parse-errors rules
+
+ * etc/compilation.txt: Add doc and example.
+ * lisp/progmodes/compile.el (compilation-error-regexp-alist-alist):
+ Add javac rule.
+ (compilation-parse-errors): Fix file/line/col test, so that
+ lambda/closure (which are valid values) don't match.
+ * test/lisp/progmodes/compile-tests.el
+ (compile-tests--test-regexps-data, compile-test-error-regexps): Add
+ test.
+
+2020-04-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Remove `all_buffers` and the associated `next` field of buffers
+
+ * src/alloc.c (enum mem_type): Remove MEM_TYPE_BUFFER.
+ (allocate_buffer): Allocate like any other pseudovector.
+ Don't register on `all_buffers` any more.
+ (live_buffer_holding, live_buffer_p): Delete functions.
+ (mark_maybe_object, valid_lisp_object_p): Don't pay attention to
+ MEM_TYPE_BUFFER any more.
+ (garbage_collect): Only compact the live buffers.
+ (mark_buffer): Mark the undo_list of dead buffers here.
+ (mark_object): Buffers are normal pseudovectors now.
+ (sweep_buffers): Don't do the actual sweep here, just cleanup the
+ markers and only for live buffers.
+
+ * src/buffer.c (all_buffers): Remove variable.
+ (Fkill_buffer): Don't check indirect dead buffers.
+ Set the undo_list before we remove ourselves from the list of live buffers.
+ (Fbuffer_swap_text, Fset_buffer_multibyte): Don't check indirect dead
+ buffers.
+ (init_buffer_once): Don't set `all_buffers`.
+ (init_buffer): Don't map new memory for dead buffers.
+
+ * src/buffer.h (struct buffer): Remove `next` field.
+ (FOR_EACH_BUFFER): Remove macro.
+
+ * src/pdumper.c (dump_buffer): Don't dump the `next` field.
+
+2020-04-01 Noam Postavsky <npostavs@gmail.com>
+
+ Don't lose point during fileloop replace (Bug#38867)
+
+ Suggested by Eric Michael Timmons <etimmons@mit.edu>.
+ * lisp/fileloop.el (fileloop-initialize-replace): Save the
+ match-beginning position in a variable instead of the buffer's point.
+ The point may be changed by the time perform-replace is called, e.g.,
+ due to switch-to-buffer-preserve-window-point.
+
+2020-03-31 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/dired.el (dired-readin): Improve comment
+
+2020-03-31 Glenn Morris <rgm@gnu.org>
+
+ Mark recently failing Tramp tests on hydra
+
+ * test/lisp/net/tramp-tests.el (tramp-test29-start-file-process)
+ (tramp-test30-make-process, tramp-test33-environment-variables):
+ Expect failure on hydra.nixos.org, since March 29 Tramp cache changes.
+
+2020-03-31 Juri Linkov <juri@linkov.net>
+
+ * lisp/minibuffer.el (minibuffer-completion-help): Use mainbuf (bug#39822)
+
+ * lisp/minibuffer.el (minibuffer-completion-help): Run
+ display-completion-list in the original buffer mainbuf
+ to allow completion-setup-function set completion-reference-buffer to it.
+
+2020-03-30 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/dired.el (dired-readin): Don't bind inhibit-modification-hooks
+
+ Fixes bug#40332
+
+2020-03-30 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ c6e0981b96 (origin/emacs-27) * lisp/image/image-converter.el: Fix cus...
+ 461bd9cc20 Fix url-cookie.el for lexical binding
+ f3ccfb1926 ; * src/decompress.c: Fix comment style.
+ 1af03e7e92 ; * src/xfaces.c (syms_of_xfaces): Fix wording and typo.
+ 93945fcd19 ; * test/lisp/calc/calc-tests.el: Fix mistake in last commit
+ ee47e00f4e Don't suggest setting face-remapping-alist to a literal (B...
+ c2b8ce4439 Calc: don't treat nil as an integer (bug#40155)
+ e1f0e08922 * lisp/files.el (directory-files-recursively): Doc fix. (...
+ 02b3820315 Document how to disable Tramp file archives
+
+2020-03-30 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 8db6b432bb Calc: Declare dynamic variable bound in lexbind code (bug#...
+
+2020-03-30 Eli Zaretskii <eliz@gnu.org>
+
+ Avoid assertion violation at startup in pdumped Emacs
+
+ * src/buffer.c (init_buffer) [USE_MMAP_FOR_BUFFERS]: Remove the
+ assertion that ensured all buffers in pdumped Emacs have non-NULL
+ pointer to buffer text. That was false when Emacs was pdumped
+ with killed buffer(s) in the all_buffers linked list. See
+ https://lists.gnu.org/archive/html/emacs-devel/2020-03/msg00800.html
+ for more details.
+
+2020-03-30 Juri Linkov <juri@linkov.net>
+
+ Deprecate with-displayed-buffer-window, use body-function instead (bug#39822)
+
+ * doc/lispref/display.texi (Temporary Displays):
+ Remove defmac with-displayed-buffer-window.
+
+ * doc/lispref/windows.texi (Buffer Display Action Alists):
+ Add body-function.
+
+ * lisp/window.el (with-displayed-buffer-window): Declare macro obsolete.
+ (window--display-buffer): Call 'body-function' after displaying the buffer.
+
+ * lisp/dired.el (dired-mark-pop-up):
+ * lisp/files.el (save-buffers-kill-emacs):
+ * lisp/minibuffer.el (minibuffer-completion-help):
+ Replace with-displayed-buffer-window with with-current-buffer-window
+ and add action alist entry 'body-function' with former macro body.
+
+2020-03-30 Juri Linkov <juri@linkov.net>
+
+ Support state changing VC operations on directories in Dired (bug#34949)
+
+ * lisp/dired-aux.el (dired-vc-next-action): New command.
+ (dired-vc-deduce-fileset): Rename from vc-dired-deduce-fileset in vc.el.
+
+ * lisp/dired.el (dired-mode-map): Remap vc-next-action to
+ dired-vc-next-action.
+
+ * lisp/vc/vc-dir.el (vc-dir-mark-files): New function.
+ (vc-dir-refresh): Run hook vc-dir-refresh-hook.
+
+ * lisp/vc/vc.el (vc-deduce-fileset): Rename arg 'observer' to
+ 'not-state-changing' and document it in docstring.
+ (vc-dired-deduce-fileset): Rename to dired-vc-deduce-fileset in dired-aux.el.
+
+ * lisp/cedet/ede.el (ede-turn-on-hook, ede-minor-mode):
+ * lisp/desktop.el (desktop-minor-mode-table): Rename the long ago
+ obsolete vc-dired-mode to vc-dir-mode.
+
+2020-03-29 Eli Zaretskii <eliz@gnu.org>
+
+ Use hard links to Emacs executable in "make install" on MS-Windows
+
+ * configure.ac (LN_S_FILEONLY): Set to "/bin/ln" for MinGW
+ unconditionally.
+
+2020-03-29 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+ Fix free function compilation
+
+ * lisp/emacs-lisp/comp.el (comp-output-base-filename): Handle src
+ being a symbol.
+
+ Add comp-test-40187 checking function shadowing.
+
+ * test/src/comp-tests.el (comp-tests-doc): Fix
+
+ * test/src/comp-test-funcs.el (comp-test-big-interactive): New test
+
+2020-03-29 Andrea Corallo <akrl@sdf.org>
+
+ Prevent collisions in C namespace and function shadowing
+
+ This rework make functions being indexed by their unique C symbol name
+ preventing multiple lisp function with the same name colliding.
+
+2020-03-29 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (maybe_defer_native_compilation): Compile comp dependencies.
+
+ Make maybe_defer_native_compilation able to compile comp dependencies
+ breaking circularity.
+
+2020-03-29 Andrea Corallo <akrl@sdf.org>
+
+ src/comp.c (Fcomp__init_ctxt): Aesthetic
+
+2020-03-29 Andrea Corallo <akrl@sdf.org>
+
+ * .gitlab-ci.yml (test-native-bootstrap-speed*): Timeout to 8h
+
+ Running in tests in parall takes longer.
+
+2020-03-29 Michael Albinus <michael.albinus@gmx.de>
+
+ Improve Tramp cache for asynchronous processes
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-exec-path)
+ (tramp-adb-get-device):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handler-askquestion):
+ * lisp/net/tramp-sh.el (tramp-remote-selinux-p, tramp-remote-acl-p)
+ (tramp-open-connection-setup-interactive-shell)
+ (tramp-maybe-open-connection, tramp-get-remote-path)
+ (tramp-get-inline-compress, tramp-get-inline-coding):
+ * lisp/net/tramp-smb.el (tramp-smb-get-cifs-capabilities)
+ (tramp-smb-get-stat-capability):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-remote-acl-p)
+ (tramp-sudoedit-remote-selinux-p): Cache property in main process.
+
+ * lisp/net/tramp-cache.el (tramp-cache-undefined): New defconst.
+ (tramp-get-hash-table, tramp-connection-property-p): Use it.
+ (tramp-set-connection-property, tramp-flush-connection-property)
+ (tramp-flush-connection-properties): Add sanity checks.
+ (tramp-get-file-property, tramp-set-file-property)
+ (tramp-get-connection-property, tramp-set-connection-property)
+ (tramp-dump-connection-properties): Adapt docstring.
+
+ * lisp/net/tramp-cmds.el (tramp-cleanup-connection): Delete all
+ processes.
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-unmount):
+ Use `tramp-cleanup-connection'.
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-vc-registered):
+ Use `bound-and-true-p'.
+
+ * lisp/net/tramp.el (tramp-get-process): New defun.
+
+2020-03-29 Juri Linkov <juri@linkov.net>
+
+ * lisp/vc/vc-dir.el (vc-dir-root): New command (bug#12492, bug#34949).
+
+ * lisp/vc/vc-hooks.el (vc-menu-map): Change menu command from
+ 'vc-dir' to 'vc-dir-root'.
+
+2020-03-29 Juri Linkov <juri@linkov.net>
+
+ Switch to literal mode with message when regexp is too big in char-fold search
+
+ * lisp/char-fold.el (char-fold-to-regexp): Don't use regexp-quote
+ when the length of regexp reaches 5000. (Bug#40216)
+
+ * lisp/isearch.el (isearch-search): On big regexp in char-fold mode
+ gracefully fall back to literal mode, try to search again and display
+ momentary-message about switching to literal mode.
+ (isearch--momentary-message): Add optional arg SECONDS.
+
+2020-03-28 Paul Eggert <eggert@cs.ucla.edu>
+
+ Stop using newly-deprecated dosname Gnulib module
+
+ Code is supposed to use the filename module now.
+ * admin/merge-gnulib (GNULIB_MODULES): Replace dosname with filename.
+ * lib/dosname.h: Remove this forwarding stub.
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+ * lib-src/emacsclient.c, src/fileio.c:
+ Include filename.h instead of dosname.h.
+
+2020-03-28 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-03-28 Use module 'filename' instead of module 'dosname'
+ 2020-03-28 dosname: Redirect to 'filename'
+ * lib/at-func.c, lib/canonicalize-lgpl.c, lib/dosname.h:
+ Copy from Gnulib.
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+ * lib/filename.h: New file, copied from Gnulib.
+
+2020-03-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/jit-lock.el (jit-lock-mode): Pass `local` to add-hook
+
+ The old code used local=nil knowing that add-hook would affect the
+ local part only anyway. Remove this hideous assumption.
+ Remove redundant `:group` args while we're at it.
+
+2020-03-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/ebrowse.el (ebrowse-tags-loop-call): Rename
+
+ Used to be called `ebrowse-tags-loop-form` and passed to `eval`.
+ Now it's passed to `apply` instead, which is better for karma.
+ (ebrowse-tags-loop-continue, ebrowse-tags-search)
+ (ebrowse-tags-query-replace, ebrowse-tags-search-member-use):
+ Adjust accordingly.
+ (ebrowse-electric-position-mode-map): Move init into declaration.
+ (ebrowse-electric-position-mode): Derive from special.
+
+2020-03-28 Mattias Engdegård <mattiase@acm.org>
+
+ Turn compilation-error-case-fold-search into a defvar
+
+ See bug#40119, and the discussion at
+ https://lists.gnu.org/archive/html/emacs-devel/2020-03/msg00653.html
+
+ * lisp/progmodes/compile.el (compilation-error-case-fold-search):
+ Turn into a defvar.
+ * etc/NEWS: Update.
+
+2020-03-28 Michael Albinus <michael.albinus@gmx.de>
+
+ Tramp cache fixes
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-write-region):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-write-region): Flush the
+ cache after the file has been written.
+
+2020-03-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ Use ATTRIBUTE_CONST for some bignum functions
+
+ * src/bignum.h (mpz_get_d_rounded):
+ * src/lisp.h (bignum_to_double, bignum_to_intmax)
+ (bignum_to_uintmax, bignum_bufsize):
+ Declare as ATTRIBUTE_CONST.
+
+2020-03-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-macs.el (cl-defstruct): Declare the type immediately
+
+2020-03-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/gnus-registry.el: Use lexical-binding
+
+ (gnus-registry-install-shortcuts): Use a closure (with dynamic :documentation)
+ (gnus-registry-user-format-function-M): Use define-obsolete-function-alias.
+ (gnus-registry-article-marks-to-names): η-reduce.
+
+2020-03-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/textmodes/tex-mode.el: Replace double-definition hack with an advice
+
+ (tex-verbatim-environments): Add "Verbatim".
+ (tex--guess-mode): Rename from tex-guess-mode and return the mode
+ rather than calling it.
+ (tex-mode): Replace second definition with an advice.
+
+2020-03-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/ebrowse.el: Prefer hash-tables to obarrays
+
+ Remove redundant :group args.
+ Use `defvar-local` and `setq-local` where possible.
+
+ (ebrowse-some): Use seq-some instead.
+ (ebrowse-every): Use seq-every-p instead.
+ (ebrowse-position): Use seq-position.
+ (ebrowse--tree-table): Rename from `ebrowse--tree-obarray`.
+ Change all users to use a hash-table rather than an obarray.
+ (ebrowse-for-all-trees): Adjust to the table being a hash-table.
+ (ebrowse-tree-table-as-alist): Rename from `ebrowse-tree-obarray-as-alist`.
+ (ebrowse-build-tree-obarray): Rename from `ebrowse-build-tree-obarray`.
+ (ebrowse-tree-mode): Remove redundant setting of `ebrowse--tree-obarray`.
+ (ebrowse-set-tree-indentation, ebrowse-view-file-other-frame)
+ (ebrowse-last-completion-table): Rename from
+ ebrowse-last-completion-obarray.
+ (ebrowse-position): Make it a proper struct.
+
+2020-03-27 Eli Zaretskii <eliz@gnu.org>
+
+ Port the 'module/async-pipe' test to MS-Windows
+
+ These changes let the code compile and produce a valid DLL, but the
+ test hangs. It looks like the hang is in Fdelete_process, when it
+ closes one of the descriptors of the pipe process.
+ In addition, this use of the pipe process cannot currently work
+ on MS-Windows, since make-pipe-process doesn't set up the reader
+ thread to read from the Emacs's side of the pipe, so the select
+ emulation doesn't know there's stuff to read from that pipe.
+ * test/data/emacs-module/mod-test.c [WINDOWSNT]: Include
+ windows.h.
+ (ALIGN_STACK) [!__x86_64__]: Define for 32-bit builds.
+ (sleep_for_half_second): New function.
+ (write_to_pipe): Declare return type differently for WINDOWSNT.
+ Call sleep_for_half_second.
+ (Fmod_test_async_pipe) [WINDOWSNT]: Use _beginthread as substitute
+ for pthread_create.
+ (invalid_finalizer): Replace non_ASCII character in a comment.
+
+ * test/src/emacs-module-tests.el (module/async-pipe): Skip on
+ MS-Windows, as the test fails and then hangs.
+
+2020-03-27 Yuan Fu <casouri@gmail.com>
+
+ Add manual and NEWS entries for previous gdb-mi changes
+
+ * etc/NEWS: Add entries for saving and restoring GDB window
+ configurations.
+ * doc/emacs/building.texi (GDB User Interface Layout): Add
+ documentation for 'gdb-save-window-configuration',
+ 'gdb-load-window-configuration',
+ 'gdb-default-window-configuration-file',
+ 'gdb-window-configuration-directory',
+ 'gdb-restore-window-configuration-after-quit'. Change 'many-windows
+ layout' to 'default layout'.
+
+2020-03-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ Treat out-of-range positions consistently
+
+ If a position argument to get-byte etc. is an out-of-range integer,
+ treat it the same regardless of whether it is a fixnum or a bignum.
+ * src/buffer.c (fix_position): New function.
+ * src/buffer.c (validate_region):
+ * src/character.c (Fget_byte):
+ * src/coding.c (Ffind_coding_systems_region_internal)
+ (Fcheck_coding_systems_region):
+ * src/composite.c (Ffind_composition_internal):
+ * src/editfns.c (Fposition_bytes, Fchar_after, Fchar_before)
+ (Finsert_buffer_substring, Fcompare_buffer_substrings)
+ (Fnarrow_to_region):
+ * src/fns.c (Fsecure_hash_algorithms):
+ * src/font.c (Finternal_char_font, Ffont_at):
+ * src/fringe.c (Ffringe_bitmaps_at_pos):
+ * src/search.c (search_command):
+ * src/textprop.c (get_char_property_and_overlay):
+ * src/window.c (Fpos_visible_in_window_p):
+ * src/xdisp.c (Fwindow_text_pixel_size):
+ Use it instead of CHECK_FIXNUM_COERCE_MARKER, so that
+ the code is simpler and treats bignums consistently with fixnums.
+ * src/buffer.h (CHECK_FIXNUM_COERCE_MARKER): Define here
+ rather than in lisp.h, and reimplement in terms of fix_position
+ so that it treats bignums consistently with fixnums.
+ * src/lisp.h (CHECK_FIXNUM_COERCE_MARKER): Move to buffer.h.
+ * src/textprop.c (validate_interval_range): Signal with original
+ bounds rather than modified ones.
+
+2020-03-27 Juri Linkov <juri@linkov.net>
+
+ Disable enable-local-variables for hunk-only in diff-syntax-fontify-props
+
+ * lisp/vc/diff-mode.el (diff-syntax-fontify-props): Let-bind
+ enable-local-variables to nil when hunk-only is non-nil (bug#39190)
+
+2020-03-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ Refactor and fix typo in CHECK_*_COERCE_MARKER
+
+ * src/data.c (check_integer_coerce_marker)
+ (check_number_coerce_marker): New functions.
+ Also, fix a typo in the former, by having it use
+ Qinteger_or_marker_p not Qnumber_or_marker_p.
+ (arithcompare, floatop_arith_driver, bignum_arith_driver)
+ (arith_driver, Fplus, Fminus, Ftimes, Fquo, Frem, Fmod)
+ (minmax_driver, Flogand, Flogior, Flogxor, Fadd1, Fsub1):
+ Use them in place of the similarly-named macros.
+ * src/lisp.h (CHECK_NUMBER_COERCE_MARKER)
+ (CHECK_INTEGER_COERCE_MARKER): Remove; no longer used.
+
+2020-03-26 Philipp Stephani <phst@google.com>
+
+ Add a module function to open a file descriptor connected to a pipe.
+
+ A common complaint about the module API is that modules can't
+ communicate asynchronously with Emacs. While it isn't possible to
+ call arbitrary Emacs functions asynchronously, writing to a pipe
+ should always be fine and is a pretty low-hanging fruit.
+
+ This patch implements a function that adapts an existing pipe
+ process. That way, users can use familiar tools like process filters
+ or 'accept-process-output'.
+
+ * src/module-env-28.h: Add 'open_channel' module function.
+
+ * src/emacs-module.c (module_open_channel): Provide definition for
+ 'open_channel'.
+ (initialize_environment): Use it.
+
+ * src/process.c (open_channel_for_module): New helper function.
+ (syms_of_process): Define necessary symbol.
+
+ * test/src/emacs-module-tests.el (module/async-pipe): New unit test.
+
+ * test/data/emacs-module/mod-test.c (signal_system_error): New helper
+ function.
+ (signal_errno): Use it.
+ (write_to_pipe): New function running in the background.
+ (Fmod_test_async_pipe): New test module function.
+ (emacs_module_init): Export it.
+
+ * doc/lispref/internals.texi (Module Misc): Document new module
+ function.
+
+ * doc/lispref/processes.texi (Asynchronous Processes): New anchor
+ for pipe processes.
+
+ * etc/NEWS: Document 'open_channel' function.
+
+2020-03-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Remove COERCE_MARKER
+
+ * src/xdisp.c (COERCE_MARKER): Remove. All uses replaced by
+ Fmarker_position; this is simpler as the macro was invoked only on
+ markers.
+
+2020-03-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ line-beginning-position args can be bignums
+
+ * src/editfns.c (Fline_beginning_position, Fline_end_position):
+ Do not restrict integer arguments to fixnums.
+
+2020-03-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix integer overflow in internal_self_insert
+
+ * src/cmds.c (internal_self_insert): Avoid undefined behavior
+ on integer overflow by using saturated add.
+
+2020-03-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix integer overflow in forward-point
+
+ * lisp/subr.el (forward-point): Rewrite in Lisp and move here ...
+ * src/cmds.c (Fforward_point): ... from here. This fixes an
+ integer overflow bug with (forward-point most-positive-fixnum).
+
+2020-03-25 Mattias Engdegård <mattiase@acm.org>
+
+ Make compilation-mode regexp matching case-sensitive (bug#40119)
+
+ The number of regexps is large, they are written independently of one
+ another, and they frequently intersect. Using case-sensitive matching
+ improves separation and performance, and is probably what everyone
+ have being assuming was used by compilation-mode all along.
+
+ * lisp/progmodes/compile.el (compilation-error-case-fold-search): New.
+ (compilation-parse-errors): Bind case-fold-search to
+ compilation-error-case-fold-search during matching.
+ * etc/NEWS: Announce.
+
+2020-03-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from gnulib
+
+ This incorporates:
+ 2020-03-25 getopt-posix: port __GETOPT_PREFIX to macOS
+ 2020-03-22 acl-permissions: Improve autoconf macro
+ * lib/getopt-pfx-core.h, m4/acl.m4: Copy from Gnulib.
+
+2020-03-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify --enable-gcc-warnings for lock_file
+
+ * src/filelock.c (lock_file): Pacify gcc -Wmaybe-uninitialized
+ after recent change to this function.
+
+2020-03-25 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/textmodes/conf-mode.el (conf-mode): Fix last change
+
+ `delay-mode-hooks` cannot be tested from within `define-derived-mode`
+ because it's always non-nil in there, so arrange to test it before we
+ enter the body.
+
+2020-03-25 Eli Zaretskii <eliz@gnu.org>
+
+ Improve the UI of 'list-timers'
+
+ * lisp/emacs-lisp/timer-list.el (list-timers): Display both "Next"
+ and "Repeat" in units of seconds, for consistency.
+ (timer-list-mode): Add help-echo to column headers.
+
+2020-03-24 Juri Linkov <juri@linkov.net>
+
+ Rename dired-mark-region choices and ignore empty region.
+
+ * lisp/dired.el (dired-mark-region): Rename choices
+ 'exclusive' to 'file', and 'inclusive' to 'line'.
+ (dired-mark-if, dired-mark): Check for non-empty region explicitly
+ instead of using use-region-p to ignore non-nil value of
+ use-empty-active-region. (Bug#39902)
+
+2020-03-24 Robert Pluim <rpluim@gmail.com>
+
+ Fix gravatar tests
+
+ * lisp/image/gravatar.el (gravatar--service-libravatar): Don't error
+ when failing to parse email address, just return the default URL.
+
+ * test/lisp/image/gravatar-tests.el (gravatar-build-url): Adjust
+ for new default gravatar url.
+
+2020-03-24 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (emit_mvar_access): Fix speed 1 compilation
+
+ At speed 1 propagate does not run and all mvars are allocated in array
+ 0.
+
+2020-03-24 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (native-compile-async): Fix excessive messaging
+
+2020-03-24 Philip K <philip@warpmail.net>
+
+ Add support for multiple Gravatar services
+
+ Now supports Libravatar and Unicornify, next to Gravatar (Bug#39965).
+
+ * lisp/image/gravatar.el (gravatar-base-url): Remove constant.
+ (gravatar-service-alist): List supported services.
+ (gravatar-service): Add user option to specify service, defaults to
+ Libravatar.
+ (gravatar--service-libravatar): New function, libravatar image host
+ resolver implementation.
+ (gravatar-build-url): Use alist gravatar-service-alist instead of
+ gravatar-base-url.
+ * etc/NEWS: Mention new gravatar service option.
+
+2020-03-24 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-03-24 Eli Zaretskii <eliz@gnu.org>
+
+ Fix sending signals and EOF to the inferior process in gdb-mi.el
+
+ * lisp/progmodes/gdb-mi.el (gdb-io-interrupt, gdb-io-quit)
+ (gdb-io-stop, gdb-io-eof): Send signal/EOF to the inferior
+ process, not to GDB. (Bug#40210)
+
+2020-03-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't add repeated xlmns:xlink declarations in svg-create
+
+ * lisp/svg.el (svg-create): Fix previous unconditional addition of
+ the xmlns:xlink declaration -- callers may already add one, and
+ having it twice is something most svg libraries doesn't like.
+
+2020-03-23 Noam Postavsky <npostavs@gmail.com>
+
+ Make cl-concatenate an alias of seq-concatenate
+
+ * lisp/emacs-lisp/cl-extra.el (cl-concatenate): Use defalias instead
+ of apply. This is simpler and more efficient.
+
+2020-03-23 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el : Fix typo introduced by f8b07ff4f3
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+ Guard against function redefinition during deferred load
+
+2020-03-23 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ d66331aea4 (origin/emacs-27) Don't build the Gnulib 'utimens' module ...
+ f2351a689b Add Harfbuzz dependency
+ 8944310d7c Don't signal during backtrace unrewind (Bug#40088)
+ 8709aaddd8 Fix a couple of problems in changelog generating functions
+ 9ab85f087f Fix cl-concatenate (Bug#40180)
+ 561e9fb91b Improve documentation of project.el commands
+ b28a9a6cc3 Make svg images with links valid
+ 7515252cce * lisp/tab-line.el (tab-line-new-button-show): New defcustom.
+
+ # Conflicts:
+ # etc/NEWS
+ # nt/gnulib-cfg.mk
+
+2020-03-23 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ bed04c502c Use correct registry name for windows-1251 charset
+ 1aa1529301 ERC: Update maintainer address
+
+2020-03-23 Noam Postavsky <npostavs@gmail.com>
+
+ Avoid extra "changed on disk" prompt in save-buffer (Bug#18336)
+
+ * src/filelock.c (lock_file): Don't query the user if the current
+ session already owns the lock.
+
+2020-03-23 Juri Linkov <juri@linkov.net>
+
+ * lisp/dired.el (dired-mark-region): New defcustom (bug#39902)
+
+ * lisp/dired.el (dired-mark-if): Use dired-mark-region.
+ (dired-mark): Use dired-mark-region. Fix docstring.
+ (dired-mark-files-regexp, dired-mark-files-containing-regexp)
+ (dired-mark-symlinks, dired-mark-directories)
+ (dired-mark-executables, dired-flag-auto-save-files)
+ (dired-flag-backup-files): Mention dired-mark-region in docstring.
+
+ * lisp/dired-aux.el (dired-compare-directories):
+ * lisp/dired-x.el (dired-mark-unmarked-files, dired-mark-sexp):
+ Mention dired-mark-region in docstring.
+
+2020-03-22 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-03-22 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (maybe_defer_native_compilation): Fix
+
+ Prevent recursive compilation while deferring compilation.
+
+2020-03-22 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (maybe_defer_native_compilation): Add some debug code
+
+ * lisp/emacs-lisp/comp.el: Add missing require
+
+2020-03-22 Andrea Corallo <akrl@sdf.org>
+
+ * .gitlab-ci.yml: CI test native bootstrap speed1 and speed2
+
+ Do just a fast bootstrap for these two.
+
+2020-03-22 Andrea Corallo <akrl@sdf.org>
+
+ Have a fast build option triggered by env var NATIVE_FAST_BOOT
+
+2020-03-22 Stefan Kangas <stefankangas@gmail.com>
+
+ Revert "Signal user-error on duplicate package refresh" (Bug#39187)
+
+ This reverts commit a6d87ea045d9df73f70765bedfb02522043efd9b.
+
+2020-03-21 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Bug#40156 in Tramp
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-write-region): Copy to temp file
+ only if FILENAME exists. (Bug#40156)
+
+ * test/lisp/net/tramp-tests.el (tramp-test10-write-region): Extend test.
+
+2020-03-21 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove more XEmacs compat code from ediff*.el
+
+ * lisp/vc/ediff-init.el (ediff-H-glyph):
+ * lisp/vc/ediff-util.el (ediff-inferior-compare-regions)
+ (ediff-setup-keymap):
+ * lisp/vc/ediff-wind.el (ediff-control-frame-parameters)
+ (ediff-prefer-iconified-control-frame)
+ (ediff-setup-control-frame, ediff-xemacs-select-frame-hook): Remove
+ XEmacs compat code and declare compatibility functions obsolete.
+
+ * lisp/vc/ediff-init.el (ediff-temp-file-prefix): Redefine as
+ obsolete variable alias for 'temporary-file-directory'.
+ * lisp/vc/ediff-util.el (ediff-make-temp-file): Don't use obsolete
+ variable name.
+
+2020-03-21 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove obsolete XEmacs comment
+
+ * lisp/emacs-lisp/edebug.el (edebug--display-1): Remove comment
+ regarding an XEmacs exclusive variable.
+
+2020-03-21 Stefan Kangas <stefankangas@gmail.com>
+
+ Declare some <package>-version variables obsolete
+
+ These are not used for anything these days and can therefore be
+ removed. Package developers should check the Emacs version instead.
+ Ref: https://lists.gnu.org/r/emacs-devel/2020-03/msg00080.html
+
+ * lisp/calendar/icalendar.el (icalendar-version):
+ * lisp/dframe.el (dframe-version):
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-version):
+ * lisp/emulation/edt.el (edt-version):
+ * lisp/international/mule.el (mule-version)
+ (mule-version-date):
+ * lisp/linum.el (linum-version):
+ * lisp/play/bubbles.el (bubbles-version):
+ * lisp/speedbar.el (speedbar-version):
+ * lisp/textmodes/remember.el (remember-version):
+ * lisp/url/url-vars.el (url-version):
+ * lisp/woman.el (woman-version): Declare obsolete.
+
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-start-section):
+ * lisp/speedbar.el (speedbar-mode):
+ * lisp/url/url-about.el (url-about-protocols):
+ * lisp/url/url-http.el (url-http--user-agent-default-string):
+ * lisp/url/url-news.el (url-news-fetch-message-id):
+ * lisp/woman.el (woman-menu, woman-mode): Stop using variables
+ declared obsolete above.
+
+2020-03-21 Stefan Kangas <stefankangas@gmail.com>
+
+ Add "Old-" prefix to "Version" header in some cases
+
+ These version numbers are historical accidents and not relevant today.
+ Ref: https://lists.gnu.org/r/emacs-devel/2020-03/msg00080.html
+
+ * lisp/calendar/icalendar.el:
+ * lisp/emacs-lisp/checkdoc.el:
+ * lisp/hippie-exp.el:
+ * lisp/linum.el:
+ * lisp/master.el:
+ * lisp/progmodes/cwarn.el:
+ * lisp/repeat.el:
+ * lisp/ruler-mode.el:
+ * lisp/textmodes/remember.el:
+ * lisp/wdired.el:
+ * lisp/woman.el: Change "Version" header to "Old-Version".
+
+2020-03-20 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Remove the Date header from message-draft-headers
+
+ * lisp/gnus/message.el (message-draft-headers): The Date header should
+ reflect when the message is sent, not when it was saved or delayed.
+
+2020-03-19 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el (comp-async-jobs-number): Fix customize type.
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+ * lisp/emacs-lisp/comp.el (comp-run-async-workers): Load only if compilation succeed
+
+2020-03-19 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't have exif bugging out on short strings
+
+ * lisp/image/exif.el (exif--direct-ascii-value): New function
+ (bug#40127).
+ (exif--parse-directory): Use it to get the correct values for
+ in-directory (i.e., shorter than 4 octets) strings.
+
+2020-03-19 Eli Zaretskii <eliz@gnu.org>
+
+ Fix display of :box face when overlay strings are around
+
+ * src/xdisp.c (reset_box_start_end_flags): New function.
+ (handle_face_prop): Only set the start_of_box_run_p flag, don't
+ reset it.
+ (pop_it): Set the face_box_p flag, if the popped face requires
+ that, when continuing iteration over buffer text.
+ (get_next_display_element, next_element_from_display_vector): Only
+ set the end_of_box_run_p flag, never reset it here.
+ (set_iterator_to_next): Don't reset the start_of_box_run_p and
+ end_of_box_run_p flags here. They are now reset as side effect of
+ PRODUCE_GLYPHS.
+ (append_space_for_newline): Restore the end_of_box_run_p flag
+ after PRODUCE_GLYPHS where we previously didn't reset it.
+ * src/dispextern.h (PRODUCE_GLYPHS): Call
+ reset_box_start_end_flags after producing glyphs.
+ (Bug#40124)
+
+2020-03-19 Paul Eggert <eggert@cs.ucla.edu>
+
+ Tiny simplification of frac_to_double
+
+ * src/timefns.c (frac_to_double): Remove unnecessary runtime check,
+ since the denominator is always positive.
+
+2020-03-19 Paul Eggert <eggert@cs.ucla.edu>
+
+ Omit timestamp optimization invalid on 387 FPU
+
+ * src/timefns.c (frac_to_double): Omit optimization that is
+ invalid on machines with excess precision (e.g., gcc x86 with 387
+ FPU), because it double-rounds. Found via ‘gcc -m32’ on x86-64.
+
+2020-03-18 Andrea Corallo <akrl@sdf.org>
+
+ * src/comp.c (native-elisp-load): Guard against missing file.
+
+2020-03-19 Andrea Corallo <akrl@sdf.org>
+
+ Command late load when deferring compilation
+
+ * lisp/emacs-lisp/comp.el: Extend `native-compile-async' for load and late-load
+
+ Extend low level code for late load
+
+ * lisp/emacs-lisp/comp.el: late-load support optional as `native-compile' parameter
+
+ * lisp/emacs-lisp/comp.el: Have the compiler generates 'late_top_level_run'
+
+2020-03-18 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ e92b8e535a (origin/emacs-27) Remove raw carriage return characters fr...
+ 5747a59a88 Recalculate default font when switching font backend
+ a2dd8c4234 * lisp/tab-line.el: Fix tab-line-format and tab-line-forma...
+ a7b8291b6c * etc/NEWS: Make the `--eval` example slightly more precise
+ f8254aad14 * lisp/image/image-converter.el: Support more ImageMagick ...
+ 5beb269505 Support Unicode 13.0
+ 3a671ad7ed Fix regression in wisent-total-conflicts
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-03-18 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 3a8a231810 * lisp/textmodes/fill.el (fill-nobreak-predicate): Fix doc...
+ cbe643104d Improve Package Menu hiding docstrings
+ 8d28c98ae0 Fix display of Big5 characters when using Fontconfig
+
+2020-03-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/vc/smerge-mode.el (smerge-start-session): Don't re-enable
+
+ Don't do anything if smerge-mode is already enabled.
+
+2020-03-17 Mattias Engdegård <mattiase@acm.org>
+
+ Don't generate useless range table entries for ASCII chars
+
+ In multibyte regexps, each ASCII char or range in a character
+ alternative produces a nonsense range table entry in addition to the
+ correct bits in the ASCII bitmap. Those entries do not match anything
+ but waste space and time.
+
+ * src/regex-emacs.c (regex_compile): Don't generate reversed intervals.
+
+2020-03-17 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-03-17 Andrea Corallo <akrl@sdf.org>
+
+ Trigger native compilation when loading bytecode
+
+ Introduce a first mechanism to trigger compilation when lex elc files
+ are loaded. This is off by default and has to be better tested.
+
+2020-03-16 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el: (native-compile-async) do not duplicate queue entries
+
+2020-03-16 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el: Estimate async worker number using system CPU number
+
+ This only when `comp-async-jobs-number' is 0 (default).
+
+2020-03-16 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el: Make compilation logic to be dynamically controllable
+
+ Introduce `comp-async-jobs-number' to control async job number, this
+ can be now adjusted dynamically.
+
+ Also make `native-compile-async' able to dynamically queue new
+ compilations.
+
+2020-03-15 Yuan Fu <casouri@gmail.com>
+
+ Add store/restore window configuration feature for gdb-mi
+
+ Add a feature that allows a user to save a gdb window
+ configuration (window layout) to a file with
+ 'gdb-save-window-configuration' and load it back with
+ 'gdb-load-window-configuration'. Set a default window configuration
+ by setting 'gdb-default-window-configuration-file'.
+ Add an option to make gdb preserve the window configuration
+ that the user had before starting gdb. In window.el, add
+ 'with-window-non-dedicated'.
+
+ * lisp/progmodes/gdb-mi.el (top/level): Require 'pcase' and 'cl-seq'.
+ (gdb--window-configuration-before): New variable.
+ (gdb-restore-window-configuration-after-quit): New option.
+ (gdb-window-configuration-directory,
+ gdb-default-window-configuration-file): New variables.
+ (gdb): Save configuration on startup.
+ (gud-menu-map): Add "Load Layout" and "Save Layout" to menu. Add
+ "Restore Layout After Quit" button to menu. Rename "Restore Window
+ Layout" to "Restore Default Layout", add some help echo, and move it
+ from "GDB-MI" menu to "GDB-WINDOWs" menu.
+ (gdb-toggle-restore-window-configuration): New function.
+ (gdb-get-source-buffer): New function, extracted out of
+ 'gdb-restore-window'.
+ (gdb-setup-windows): Add a condition branch that loads default window
+ configuration when available. Fix docstring.
+ (gdb-buffer-p, gdb-function-buffer-p, gdb--buffer-type,
+ gdb-save-window-configuration, gdb-load-window-configuration): New
+ functions.
+ (gdb-restore-windows): Edit docstring to mention
+ 'gdb-default-window-configuration-file'.
+ (gdb-reset): Restore window configuration after quit.
+ * lisp/window.el (with-window-non-dedicated): New macro.
+
+2020-03-15 Eli Zaretskii <eliz@gnu.org>
+
+ Reverse the meaning of 2nd arg to 'live_buffer_holding'
+
+ * src/alloc.c (live_buffer_holding): Rename ALL_BUFFERS ti
+ IGNORE_KILLED, and reverse the condition for returning killed
+ buffers.
+ (live_buffer_p): Add commentary.
+ (live_buffer_p, mark_maybe_object, mark_maybe_pointer): Reverse
+ the 2nd argument to live_buffer_holding. (Bug#39962)
+
+2020-03-15 Pip Cet <pipcet@gmail.com>
+
+ Make sure we mark reachable killed buffers during GC
+
+ * src/alloc.c (live_buffer_holding): Add ALL_BUFFERS argument for
+ returning killed buffers.
+ (mark_maybe_object, mark_maybe_pointer): Use the additional
+ argument. (Bug#39962)
+
+2020-03-15 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-03-15 Andrea Corallo <akrl@sdf.org>
+
+ * .gitlab-ci.yml: Always run test-filenotify-gio
+
+ test-filenotify-gio is run always to keep stock bootstrap tested.
+
+2020-03-15 Andrea Corallo <akrl@sdf.org>
+
+ * lisp/emacs-lisp/comp.el: Fix missing rx require
+
+2020-03-15 Adam Porter <adam@alphapapa.net>
+
+ comp.el: Minor improvements
+
+ Change: (comp-start-async-worker) Refactor slightly
+
+ Change: (comp-start-async-worker) Inline (comp-to-file-p)
+
+ Change: (comp-source-files) Rename from comp-src-pool
+
+ Add: (comp-start-async-worker) Assertion
+
+ Change: (comp-async-processes) Rename from comp-prc-pool
+
+ Tidy: (native-compile)
+
+ Rename variables, improve docstring, adjust log message, simplify
+ filename code.
+
+ Tidy: (batch-native-compile) Docstring
+
+ Tidy: whitespace-cleanup
+
+ Tidy: (comp-start-async-worker) Use () instead of nil
+
+ Tidy: (comp-files-queue) Rename from comp-source-files
+
+ Change: (native-compile-async) Improve paths support
+
+ Tidy: Comment
+
+ Save a line for one word. :)
+
+ Change: (comp-log) Rewrite without macro, follow tail
+
+ Change: (native-compile-async) Use end-of-string in filename regexps
+
+ Change: (native-compile-async) Use cl-loop instead of dotimes
+
+ Add/Change: (comp-log-to-buffer) And use in comp-log
+
+ Comment: Tidy comment
+
+ Fix: (configure.ac) Option description
+
+ Fix: (comp-log) Argument
+
+ Fix: (comp-start-async-worker) Variable name
+
+ Change: Undo whitespace changes
+
+ Some of them included incorrect indentation because the
+ macros' (declare (indent)) forms were not loaded. The
+ whitespace-cleanup should be run from Emacs 27+ with the file loaded.
+
+2020-03-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/sql.el: Try and avoid `eval`; use define-derived-mode
+
+ Remove redundant `:group` args.
+
+ (sql-interactive-mode-map): `set-keymap-parent` is always fboundp.
+ (sql-get-product-feature): Prefer `symbol-value` over `eval`.
+ (sql--adjust-interactive-setup): New function, extracted from
+ `sql-interactive-mode`.
+ (sql-interactive-mode): Use it and `define-derived-mode`.
+ (sql-connect, sql-connection-menu-filter): Prefer `cl-progv` over `eval`.
+
+2020-03-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/textmodes/conf-mode.el (conf-mode): Use define-derived-mode
+
+ (conf--guess-mode): Extract from conf-mode.
+ (defcustoms): Remove redundant `:group` args.
+ (conf-mode, conf-mode-initialize, conf-javaprop-mode)
+ (conf-space-mode, conf-space-keywords, conf-space-mode-internal)
+ (conf-colon-mode): Use `setq-local`.
+
+2020-03-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/package.el (package-activate-1): Avoid duplicates
+
+ in `Info-directory-list`.
+
+2020-03-14 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-03-14 Andrea Corallo <akrl@sdf.org>
+
+ Fix make bootstrap for native compilation
+
+ Add Makefile target native-compile-clean removing all eln output
+ folders.
+
+ This is also triggered by make bootstrap to perform a clean bootstrap.
+
+ Also revert some modification of the build system against master not
+ effective anymore with the new directory layout.
+
+2020-03-14 Alan Mackenzie <acm@muc.de>
+
+ * lisp/progmodes/cc-defs.el (c-version): update to 5.34.2 for master branch
+
+2020-03-14 Jeremy Compostella <jeremy.compostella@gmail.com>
+
+ Make previous mml-expand-html-into-multipart-related fix more general
+
+ * lisp/gnus/mml.el (mml-expand-html-into-multipart-related): This is
+ function is now called by a recursive
+ engine (mml-expand-all-html-into-multipart-related). The structure of
+ the returned value should be identical between an untouched part and a
+ expanded multipart (bug#39230).
+
+2020-03-14 Eli Zaretskii <eliz@gnu.org>
+
+ Add charsets to 'w32-charset-info-alist'
+
+ * lisp/w32-fns.el: Add a few more charsets to
+ w32-charset-info-alist.
+
+2020-03-14 Mattias Engdegård <mattiase@acm.org>
+
+ Avoid regexp stack overflow in GDB string matching (bug#22149)
+
+ * lisp/progmodes/gdb-mi.el (gdb--string-regexp):
+ Swap the or-clauses so that the rarely matching one comes first.
+ This avoids a build-up of backtrack points on the regexp stack.
+
+2020-03-13 Andrea Corallo <akrl@sdf.org>
+
+ Prefix native compilation folders with "eln-"
+
+2020-03-13 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ a2b07f9f11 (origin/emacs-27) ; * etc/NEWS: Explain how to get back ol...
+ b468b3d1ff Fix a recent documentation change
+ 1ab766fd58 Fix last change
+ ecfe633993 * lisp/tab-bar.el: Last-minute changes.
+ c1ce9fa7f2 * lisp/subr.el (cancel-change-group): Fix bug#39680
+ ef5744a988 Improve docs for horizontal scrolling with mouse and touch...
+ 1bc3fa0bd0 * lisp/emacs-lisp/package.el (package-install): Fix typo i...
+ 4537976afd Port .gdbinit to clang with -gdwarf-4
+ 0883c800a0 Simplify rx example in manual
+ a695189248 ; * etc/NEWS: Fix typo.
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-03-13 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp.el (tramp-accept-process-output): Propagate `quit' signal.
+
+2020-03-13 Pieter van Oostrum <pieter@vanoostrum.org>
+
+ * lisp/emacs-lisp/package.el (package-menu--generate): Fix doc string.
+
+ Add REMEMBER-POS to docstring (bug#39861).
+
+2020-03-13 Andrea Corallo <akrl@sdf.org>
+
+ Do not produce .eln files when a byte compilation error happen
+
+ Have the byte compiler signal an error when compilation fails to stop
+ native compilation too.
+
+2020-03-13 Noam Postavsky <npostavs@gmail.com>
+
+ Make cl-equalp a bit more efficient at comparing strings
+
+ * lisp/emacs-lisp/cl-extra.el (cl-equalp): Use compare-strings with
+ the IGNORE-CASE argument, rather than creating downcased copies of the
+ strings to be compared.
+
+2020-03-13 Noam Postavsky <npostavs@gmail.com>
+
+ rcirc: Match NickServ messages case-insensitively (Bug#39345)
+
+ Reported by Jake Nelson <jake.nelson@gmail.com>.
+ * lisp/net/rcirc.el (rcirc-check-auth-status): NickServ will response
+ will show the nick in the same case used during registration, but
+ it allows case-insensitive matches when logging in. Therefore, we
+ should accept response messages regardless of case.
+
+2020-03-13 Andrii Kolomoiets <andreyk.mad@gmail.com>
+
+ Fix NS child frame in native fullscreen (bug#36672)
+
+ * lisp/frame.el (toggle-frame-fullscreen): Don't sleep on cocoa.
+ Fullscreen animation waiting is moved to src/nsterm.m.
+ * src/nsterm.h (EmacsView): Add in_fullscreen_transition,
+ inFullScreenTransition, waitFullScreenTransition.
+ (NSWindowCollectionBehaviorFullScreenAuxiliary): New define.
+ * src/nsterm.m (ns_make_frame_visible): Wait for fullscreen animation.
+ (ns_set_parent_frame): Set frame collection behavior; make child frames
+ non-fullscreen; make non-child frames fullscreen if parent was fullscreen.
+ ([EmacsView initFrameFromEmacs]): Set in_fullscreen_transition; set frame
+ collection behavior according to parent frame.
+ ([EmacsView windowDidMove]): Remove code by commenting with "fixme".
+ ([EmacsView windowWillEnterFullScreen], [EmacsView windowDidEnterFullScreen])
+ ([EmacsView windowWillExitFullScreen], [EmacsView windowDidExitFullScreen]):
+ Set in_fullscreen_transition.
+ ([EmacsView inFullScreenTransition], [EmacsView waitFullScreenTransition]):
+ New methods.
+ ([EmacsView updateCollectionBehavior]): Set collection behavior according to
+ parent frame.
+ ([EmacsView toggleFullScreen]): Wait for fullscreen animation.
+
+2020-03-12 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-03-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/eldoc.el: Remove redundant `:group` arguments
+
+ * lisp/emacs-lisp/eldoc.el (eldoc--supported-p): Understand the "old" API
+
+ * lisp/subr.el (cancel-change-group): Undo accidental change
+
+2020-03-12 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp-sh.el (tramp-find-shell): Skip for asynchronous processes.
+
+2020-03-11 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove XEmacs exclusive face from themes
+
+ * etc/themes/deeper-blue-theme.el (class):
+ * etc/themes/leuven-theme.el (class):
+ * etc/themes/manoj-dark-theme.el (manoj-dark):
+ * etc/themes/whiteboard-theme.el (class): Don't set XEmacs exclusive
+ face 'font-lock-doc-string-face'.
+
+2020-03-11 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove more XEmacs compat code from eshell
+
+ * lisp/eshell/em-glob.el (eshell-extended-glob):
+ * lisp/eshell/em-ls.el (eshell-do-ls):
+ * lisp/eshell/em-unix.el (eshell/du, eshell-mvcpln-template):
+ * lisp/eshell/esh-util.el (eshell-file-attributes): Remove more XEmacs
+ compat code; no longer let-bind the unused variable ange-cache.
+
+2020-03-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-macs.el: More care with `eval` and with `cl-typep`
+
+ (cl-eval-when, cl--compile-time-too, cl-load-time-value):
+ Obey lexical-binding.
+ (cl-check-type): Prefer the predicate rather than the type in the
+ error signal when it's easy to do (as is done outside of CL).
+ (cl-deftype-satisfies): Add definitions for standard types.
+
+2020-03-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/cl-macs.el (cl--transform-lambda): Simplify result
+
+ It used to return a pair (EXP . LAMBDA-CDR) but EXP was always nil, so
+ just return the LAMBDA-CDR instead.
+
+ (cl-defun, cl-iter-defun, cl-defmacro, cl-function, cl-macrolet):
+ Adjust callers accordingly.
+
+2020-03-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/window.el: Avoid `called-interactively-p`.
+
+ (other-window, delete-other-windows, next-buffer, previous-buffer):
+ Use an `interactive` arg instead.
+
+2020-03-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/ido.el: Remove redundant `:group`s
+
+2020-03-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/subr.el (dlet): New macro
+
+ * lisp/calendar/calendar.el (calendar-dlet*): Use it.
+
+2020-03-10 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-03-10 AndreaCorallo <akrl@sdf.org>
+
+ * Improve load_comp_unit
+
+ Fix uninitialized ephemeral data relocation for the case when a dumped
+ compilation unit is manually reloaded.
+
+ Guard also data_ephemeral_vec against compiler optimizations.
+
+2020-03-10 AndreaCorallo <akrl@sdf.org>
+
+ * Fix store_function_docstring for for native functions
+
+ Do not Nil native_doc fields. This will be naturally dumped by
+ pdumper. This was affecting dumped functions.
+
+2020-03-10 Andrea Corallo <akrl@sdf.org>
+
+ Fix GC mark for native compiled functions
+
+ native_intspec and native_doc fields has to be reached by the subr
+ cause are not anymore in the CU.
+
+2020-03-10 AndreaCorallo <akrl@sdf.org>
+
+ * Set relocation class as ephemeral in `comp-limplify-top-level'
+
+2020-03-10 Juri Linkov <juri@linkov.net>
+
+ Improve new-frame logic of windmove-display-in-direction (bug#39875)
+
+ * lisp/windmove.el (windmove-display-in-direction):
+ For frame-based logic use code similar to display-buffer-pop-up-frame.
+
+2020-03-10 Juri Linkov <juri@linkov.net>
+
+ In vc-print-branch-log use root instead of the default directory (bug#39704)
+
+ * lisp/vc/vc.el (vc-print-branch-log): Use rootdir instead of
+ default-directory for the second arg of vc-print-log-internal.
+
+2020-03-09 Michael Albinus <michael.albinus@gmx.de>
+
+ Finish implementation of set-file-times FLAG arg in Tramp
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-set-file-times):
+ Implement FLAG.
+ (tramp-adb-handle-copy-file): Adapt `set-file-times' call.
+
+ * lisp/net/tramp-compat.el (tramp-compat-set-file-times): New defalias.
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-set-file-modes)
+ (tramp-gvfs-handle-set-file-times, tramp-gvfs-set-file-uid-gid):
+ Simplify `tramp-gvfs-url-file-name' call.
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-set-file-times): Implement FLAG.
+ (tramp-do-copy-or-rename-file-via-buffer)
+ (tramp-do-copy-or-rename-file-out-of-band): Add optional argument
+ OK-IF-ALREADY-EXISTS. Adapt callees.
+ (tramp-do-copy-or-rename-file-via-buffer)
+ (tramp-do-copy-or-rename-file-directly)
+ (tramp-do-copy-or-rename-file-out-of-band): Adapt `set-file-times' call.
+
+ * lisp/net/tramp-smb.el (tramp-smb-handle-copy-directory)
+ (tramp-smb-handle-copy-file): Adapt `set-file-times' call.
+
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-do-copy-or-rename-file):
+ Adapt `set-file-times' call.
+ (tramp-sudoedit-handle-set-file-times): Implement FLAG.
+
+ * test/lisp/net/tramp-tests.el (tramp-test22-file-times): Extend test.
+
+2020-03-09 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+ * Fix regexp instroduced by f055f52321
+
+2020-03-09 Paul Eggert <eggert@cs.ucla.edu>
+
+ Merge from origin/emacs-27
+
+ cf223dc928 ; * src/timefns.c: Fix typo in previous change.
+ 20d3d3a950 * src/timefns.c: Add comments.
+
+2020-03-08 Andrea Corallo <akrl@sdf.org>
+
+ Fix typo into pdumper integration
+
+2020-03-08 Andrea Corallo <akrl@sdf.org>
+
+ New native-comp CI setup
+
+ - Disable 'test-all' till is known to be broken in this branch.
+
+ - Run 'test-native-bootstrap' always (not only when scheduled).
+
+ - Set 'test-native-bootstrap' timeout to 3 hours.
+
+2020-03-08 Andrea Corallo <akrl@sdf.org>
+
+ Fix two find function functions for native compilation
+
+ `find-function-library' and `find-library-name' gets fixed for new eln
+ compilation directory layout.
+
+2020-03-08 Daniel Gröber <dxld@darkboxed.org>
+
+ * lisp/term/rxvt.el: Enable backeted paste and window title
+
+ rxvt-unicode uses the same escape sequences as xterm so just re-use
+ the xterm functions to enable them. The `xterm-rxvt-function-map`
+ keymap already has
+
+ (define-key map "\e[200~" [xterm-paste])
+
+ so we're already handling the paste sequence and only need to enable it.
+ Tested on rxvt-unicode version 9.22.
+
+ (rxvt-set-window-title): New var.
+ (terminal-init-rxvt): Use it; enable bracketed paste mode;
+ run terminal-init-rxvt-hook.
+
+2020-03-08 Alan Mackenzie <acm@muc.de>
+
+ CC Mode: allow specified directives (e.g. pragma) to be indented as statements
+
+ * lisp/progmodes/cc-cmds.el (c-align-cpp-indent-to-body)
+ (c-cpp-indent-to-body-flag, c-electric-pragma)
+ (c-add-indent-to-body-to-abbrev-table, c-clear-stale-indent-to-body-abbrevs)
+ (c-toggle-cpp-indent-to-body): New functions and variables.
+
+ * lisp/progmodes/cc-langs.el (c-std-abbrev-keywords): New lang const/var.
+
+ * lisp/progmodes/cc-mode.el (c-populate-abbrev-table): New function.
+ (c-basic-common-init): call the c-populate-abbrev-table.
+ (c-mode, c++-mode, objc-mode, java-mode, idl-mode, pike-mode, awk-mode):
+ Remove the setting of MODE-abbrev-table.
+
+ * lisp/progmodes/cc-vars.el (c-cpp-indent-to-body-directives): New defcustom.
+
+ * doc/misc/cc-mode.texi (Custom Macros): Introduce and refer to ....
+ (Indenting Directives): New page documenting the new mechanism.
+
+2020-03-08 Eli Zaretskii <eliz@gnu.org>
+
+ Fix the MinGW build as followup to recent "nofollow" changes
+
+ * src/w32.c (fdutimens): Call utimensat instead of utime.
+ (set_file_times): Function deleted.
+ (convert_from_timespec): Renamed from convert_from_time_t and
+ modified to accept 'struct timespec' argument instead of 'time_t'.
+ (utimensat): Renamed from utime and modified to accept 'struct
+ timespec [2]' argument and an additional argument FLAG. Emulate
+ Posix 'utimensat'. Call 'convert_from_timespec'.
+ (w32_copy_file): Call 'utimensat' instead of 'set_file_times'.
+ * src/fileio.c (Fcopy_file) [WINDOWSNT]: Make the error message be
+ identical to that on Posix platforms.
+
+ * nt/inc/sys/stat.h (utimensat): Provide prototype.
+ * nt/mingw-cfg.site (ac_cv_func_futimens)
+ (gl_cv_func_futimens_works, ac_cv_func_utimensat)
+ (gl_cv_func_utimensat_works): Override Gnulib tests.
+ * nt/gnulib-cfg.mk (OMIT_GNULIB_MODULE_futimens)
+ (OMIT_GNULIB_MODULE_utimensat): Disable these Gnulib modules.
+
+2020-03-08 Andrea Corallo <akrl@sdf.org>
+
+ * test-native-bootstrap CI test configured for speed 0
+
+ Run for now only speed 0 to limit memory usage and compilation time.
+
+2020-03-08 Paul Eggert <eggert@cs.ucla.edu>
+
+ Simplify run-at-time
+
+ * lisp/emacs-lisp/timer.el (run-at-time):
+ Remove unnecessary test (Bug#39944).
+
+2020-03-08 Paul Eggert <eggert@cs.ucla.edu>
+
+ Merge from origin/emacs-27
+
+ 0a3682a566 * src/timefns.c: Add comments.
+ b16ba4041d ; lisp/emacs-lisp/seq.el: Explain why we don't use cl-lib ...
+ 3cbf4cb796 Eliminate use of cl-concatenate in 'seq' package
+ 363d927086 Fix bug with JIT stealth timers
+ 818333c85a * doc/lispref/os.texi (time-subtract): Doc fix.
+
+2020-03-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/bytecomp.el: Drop warning for loading into Emacs<23
+
+ Stash the major version of the compiling Emacs such that the loading
+ Emacs can later detect when loading a file compiled by a too-new Emacs.
+
+ (byte-compile-fix-header): Remove.
+ (byte-compile-from-buffer): Don't call it any more.
+ (byte-compile-insert-header): Stash the emacs-major-version in it.
+ Don't leave space for `byte-compile-fix-header`.
+
+2020-03-07 Glenn Morris <rgm@gnu.org>
+
+ Skip filenotify tests on hydra.nixos.org
+
+ They frequently hang for hours.
+ * test/lisp/filenotify-tests.el
+ (file-notify--test-remote-enabled-checked): Default to off on hydra.
+
+2020-03-07 Paul Eggert <eggert@cs.ucla.edu>
+
+ Add ‘nofollow’ flag to set-file-times
+
+ This is a companion to the recent set-file-modes patch.
+ It adds support for a ‘nofollow’ flag to set-file-times (Bug#39773).
+ Like the set-file-modes patch, it needs work in the w32 port.
+ * admin/merge-gnulib (GNULIB_MODULES): Add futimens, utimensat.
+ Remove utimens.
+ * doc/lispref/files.texi (Changing Files):
+ * etc/NEWS: Mention the change.
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+ * lisp/files.el (copy-directory):
+ * lisp/gnus/gnus-cloud.el (gnus-cloud-replace-file):
+ * lisp/net/tramp-adb.el (tramp-adb-handle-copy-file):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-copy-file):
+ * lisp/tar-mode.el (tar-copy):
+ * test/lisp/filenotify-tests.el (file-notify-test03-events):
+ * test/lisp/files-tests.el:
+ (files-tests-file-name-non-special-set-file-times):
+ * test/lisp/net/tramp-tests.el (tramp-test22-file-times):
+ When setting file times, avoid following symbolic links
+ when the file is not supposed to be a symbolic link.
+ * lib/futimens.c, lib/utimensat.c, m4/futimens.m4, m4/utimensat.m4:
+ New files, copied from Gnulib.
+ * lisp/gnus/gnus-cloud.el (gnus-cloud-replace-file):
+ When creating a file that is not supposed to exist already,
+ use the excl flag to check this.
+ * lisp/net/tramp-adb.el (tramp-adb-handle-set-file-times):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-set-file-times):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-set-file-times):
+ Accept an optional FLAG arg that is currently ignored,
+ and add a FIXME comment for it.
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-set-file-times):
+ * src/fileio.c (Fset_file_times):
+ Support an optional FLAG arg.
+ * src/fileio.c (Fcopy_file): Use futimens instead of set_file_times,
+ as it’s simpler and is a POSIX API.
+ * src/sysdep.c (set_file_times): Move from here ...
+ * src/w32.c (set_file_times): ... to here, and make it static,
+ since it is now used only in w32.c. Presumably w32.c should also
+ add support for futimens and utimensat (the POSIX APIs, which
+ Emacs now uses) and it can remove fdutimens (the Gnulib API,
+ which Emacs no longer uses).
+
+2020-03-07 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-03-07 open, openat: port to (O_RDWR | O_RDONLY) != 0
+ * lib/open.c: Copy from Gnulib.
+
+2020-03-07 Andrea Corallo <akrl@sdf.org>
+
+ Raise timeout for test-native-bootstrap CI test and build with -j2
+
+2020-03-07 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 72f87f8873 (origin/emacs-27) NS port documentation updates
+ 5b19db98ad ; * etc/NEWS: correctly describe what fido-mode is
+ fc47e3ad99 Let fido-mode users force a minibuffer-exit
+ e734961d4c icomplete-fido-exit: New command for the M-j binding
+ 335a9bd215 minibuffer-force-complete-and-exit: Allow input with no ma...
+ 34132d4bf6 ; * etc/NEWS: Mark 2 entries as fully documented.
+ d28b73841b ; * etc/NEWS: Fix the 'mml-secure-openpgp-sign-with-sender...
+ d1d56a9fd9 ; * etc/NEWS: 'thunk-let' and 'thunk-let*' are fully docum...
+ fc4f4efabf ; * etc/NEWS: No need to document vc-hg and mergebase chan...
+ 9e8456cf0f ; * etc/NEWS: No need to document changes in Octave mode.
+ 25b4d6fa28 ; * etc/NEWS: No need to document changes in map.el and se...
+ fc4d0f86da ; * etc/NEWS: No need to document Ido news.
+ d4ac478cb3 ; * etc/NEWS: No need to document news of doc-view.el.
+ 08c042bd26 Document that 'byte-compile-dynamic' is obsolete
+ 512b66abd7 ; * etc/NEWS: No need to document 'goto-address-uri-scheme...
+ 3103c01c3e ; * etc/NEWS: Formatting fixes.
+ 98306fdfb8 ; * etc/NEWS: No need to document deprecation of 'cl'.
+ 6281ed58be ; * etc/NEWS: No need to document the change in 'list-proc...
+ e252341e11 ; * etc/NEWS: 'backup-by-copying-when-privileged-mismatch'...
+ ec5a267ddc ; * etc/NEWS: Mark 'byte-count-to-string-function' as undo...
+ 89307ebccd ; * etc/NEWS: Mark 'completion-common-part' face entry as ...
+ fdbe7cacfb Document the changes in 'read-answer'
+ 10c58356e4 Document changes in lexical-binding
+ 5cb312b5b9 Update ERC mailing list address
+ cb1877321b Use regexp-opt to define bibtex-autokey-transcriptions. (...
+ 3f9c340de0 Improve documentation of 'table-generate-source'
+ 33b31dc314 Attempt to avoid rare segfaults in show_mouse_face
+ 88c6db9196 Avoid crashes when a fontset has strange entries
+ 1814c7e158 Fix rx error with ? and ??
+ 40fb20061e * lisp/emacs-lisp/rx.el (rx--string-to-intervals): Fix err...
+ 08d7d28d35 Fix args in 'window-text-pixel-size' call in 'fit-window-t...
+ cb1e30910e Have pulse.el preserve existing overlay priorities
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-03-07 Andrea Corallo <akrl@sdf.org>
+
+ Add test-native-bootstrap as CI test
+
+2020-03-06 Glenn Morris <rgm@gnu.org>
+
+ Remove ancient OS X process-connection-type handling
+
+ * src/process.c (init_process_emacs) [DARWIN_OS]:
+ Remove process-connection-type special-casing
+ for OS X < 10.3 (ie pre-2003).
+ Ref https://lists.gnu.org/r/emacs-devel/2005-01/msg00741.html
+
+2020-03-06 Juri Linkov <juri@linkov.net>
+
+ Fix handling of empty input in describe-variable and describe-symbol
+
+ * lisp/help-fns.el (describe-variable): Use 'user-error' like in
+ 'describe-function'.
+ (describe-symbol): Use empty string for arg SYMBOL when input is empty
+ and there is no default value.
+ This allows to signal the error "You didn't specify a function or variable"
+ instead of displaying help about the symbol 'nil' on empty input.
+ OTOH, still allows to see help about 'nil' when the input is "nil".
+
+2020-03-06 Juri Linkov <juri@linkov.net>
+
+ New command make-frame-on-current-monitor to use in windmove (bug#39875)
+
+ * lisp/frame.el (make-frame-on-current-monitor): New command.
+
+ * lisp/windmove.el (windmove-display-in-direction):
+ Use make-frame-on-current-monitor for 'new-frame'.
+ (windmove-display-new-frame): New command.
+ (windmove-display-default-keybindings): Bind
+ windmove-display-new-frame to 'f' key.
+
+ * lisp/window.el (display-buffer-in-direction): Fix quotes in docstring.
+
+2020-03-04 Andrea Corallo <akrl@sdf.org>
+
+ Fix build for stock configuration
+
+ Vcomp_native_path_postfix is declared only in native configuration.
+
+2020-03-04 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ a3c2d186eb (origin/emacs-27) CC Mode: Fix the handling of two adjacen...
+ a1abf73c76 Fix combine-change-calls-1 for when buffer-undo-list is t
+ db37dd2e84 Don't misinterpret doc string as initial value
+ 40b217c2bf Bump checkdoc-version to match library header
+ 60418a1ab2 Explain how to unset mode bindings (Bug#39802)
+ 7cafbbe964 Fix describe-variable on values with circular syntax (Bug#...
+ 592b1cfee9 Improve documentation of next-error-highlight-no-select (b...
+
+2020-03-04 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ a4e4510ccd Fix handling MS-Windows keyboard input above the BMP
+ a38bebb0c1 * etc/NEWS: More complete description of rx 'not' changes.
+ d373647e8f ; * doc/emacs/mini.texi (Yes or No Prompts): Fix last change.
+ 1ca6d15656 * doc/emacs/mini.texi (Yes or No Prompts): 'y-or-n-p' now ...
+ fe1a447d52 Don't attempt to cache glyph metrics for FONT_INVALID_CODE
+ b42b894d1d Fix fit-frame-to-buffer for multi-monitor setup
+ 366fd4fd07 (emacs-27) ; * etc/NEWS: Fix typo.
+ 49d3cd90bd rx: Improve 'or' compositionality (bug#37659)
+ 6b48aedb6b * lisp/tab-line.el: Fix auto-hscrolling (bug#39649)
+ c5f255d681 (tag: emacs-27.0.90) ; Update lisp/ldefs-boot.el
+ 60c84ad992 ; * etc/TODO: Fix last change.
+ 5af9e5baad ; Add an entry to TODO
+ d424195905 Fix rx charset generation
+ 9908b5a614 Merge branch 'emacs-27' of git.savannah.gnu.org:/srv/git/e...
+ 6dc2ebe00e Fix overquoting in mule.el
+ 5cca73dd82 * src/timefns.c (time_arith): Omit incorrect comment.
+ d767c357ca Merge branch 'emacs-27' of git.savannah.gnu.org:/srv/git/e...
+ 4dec693f70 * lisp/vc/vc-cvs.el (vc-cvs-ignore): Copy-edit doc string
+ ff729e3f97 ; bug#39779: Fix some typos in documentation.
+ 696ee02c3a checkdoc: Don't mistake "cf." for sentence end
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-03-04 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 5b7d226779 * etc/AUTHORS: Update.
+ 4aa758e53d ; ChangeLog.3 update
+ 9261b1ed49 * admin/authors.el (authors-ignored-files): Fix entries.
+ 86e4da6eaf ; ChangeLog.3 update
+ 009c6a1767 ; ChangeLog.3 fixes
+ f9e53947c7 Fix documented slot name of eieio-instance-tracker class
+ 999d75c0c1 Range-check width passed to define-fringe-bitmap
+ 29e415d6b0 ; ChangeLog.3 fixes
+ 4653baa6a5 ; ChangeLog.3 update & fixes.
+ a95ec6e060 * admin/authors.el: Add missing entries
+ af519a6348 Define libgnutls-version properly
+ 9ec6eb1065 vc-dir-ignore: More accurately choose base directory
+ e74fb4688b * lisp/emacs-lisp/cursor-sensor.el (cursor-sensor--detect)...
+ 3bce7ec382 CC Mode: Protect against consecutive calls to before-chang...
+
+2020-03-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Pacify GCC 9.2.1 20190927 -O3
+
+ Original problem report by N. Jackson in:
+ https://lists.gnu.org/r/emacs-devel/2020-03/msg00047.html
+ I found some other warnings when I used gcc, and fixed them
+ with this patch.
+ * lib-src/etags.c: Include verify.h.
+ (xnmalloc, xnrealloc): Tell the compiler that NITEMS is
+ nononnegative and ITEM_SIZE is positive.
+ * src/conf_post.h (__has_attribute_returns_nonnull)
+ (ATTRIBUTE_RETURNS_NONNULL): New macros.
+ * src/editfns.c (Fuser_full_name): Don’t assume Fuser_login_name
+ returns non-nil.
+ * src/intervals.c (rotate_right, rotate_left, update_interval):
+ * src/intervals.h (LENGTH, LEFT_TOTAL_LENGTH, RIGHT_TOTAL_LENGTH):
+ Use TOTAL_LENGTH0 or equivalent on intervals that might be null.
+ * src/intervals.h (TOTAL_LENGTH): Assume arg is nonnull.
+ (TOTAL_LENGTH0): New macro, with the old TOTAL_LENGTH meaning.
+ (make_interval, split_interval_right): Add ATTRIBUTE_RETURNS_NONNULL.
+ * src/pdumper.c (dump_check_dump_off): Now returns void, since
+ no caller uses the return value. Redo assert to pacify GCC.
+ (decode_emacs_reloc): Add a seemingly-random eassume to pacify GCC.
+ Ugly, and I suspect due to a bug in GCC.
+
+2020-03-04 Alan Third <alan@idiocy.org>
+
+ Fix more NS_DRAW_TO_BUFFER #ifdefs (bug#39883)
+
+ * src/nsterm.m (ns_update_end): Make sure the frame is updated after
+ drawing.
+ (ns_focus):
+ (ns_unfocus): Should be checking on NS_DRAW_TO_BUFFER rather than if
+ it's Cocoa or GNUstep.
+
+2020-03-04 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-03-04 Stefan Kangas <stefankangas@gmail.com>
+
+ Declare speedbar-incompatible-version obsolete
+
+ This variable refers to a now ancient version of speedbar, and is no
+ longer useful.
+
+ * lisp/speedbar.el (speedbar-incompatible-version): Declare obsolete.
+
+2020-03-04 Daniel Colascione <dancol@dancol.org>
+
+ Ignore spurious focus events
+
+ * src/xterm.c (x_detect_focus_change): Ignore FocusIn and FocusOut
+ events from grabs
+
+2020-03-04 Stéphane Boucher <Stephane.Boucher@acceo.com> (tiny change)
+
+ Update default-directory in occur buffer (bug#39608)
+
+ * lisp/replace.el (occur-1): Update default-directory in occur buffer.
+
+2020-03-04 AndreaCorallo <akrl@sdf.org>
+
+ * Do not crash if the output directory is created in the meanwhile
+
+2020-03-03 AndreaCorallo <akrl@sdf.org>
+
+ Hash eln ABI once and add it to the output compilation path
+
+ Fix org for eln new compilation folder layout
+
+2020-03-03 AndreaCorallo <akrl@sdf.org>
+
+ Rework `find-lisp-object-file-name'
+
+ Rework it for eln new compilation folder layout.
+
+2020-03-03 Paul Eggert <eggert@cs.ucla.edu>
+
+ Time division speedups
+
+ * src/timefns.c (frac_to_double) [FASTER_TIMEFNS]: Prefer intmax_t
+ division or double division to mpz division if they also yield the
+ correctly rounded result.
+
+2020-03-03 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix rounding errors in time conversion
+
+ * src/timefns.c (frac_to_double): Pass FLT_RADIX to mpz_sizeinbase
+ instead of doing the radix calculation ourselves, not always
+ correctly. Fix off-by-one error in scale, which caused
+ double-rounding.
+ (decode_time_components): Use frac_to_double (via decode_ticks_hz)
+ to fix double-rounding error that can occur even though
+ intermediate results are long double.
+ * test/src/timefns-tests.el (float-time-precision):
+ Test the above fixes.
+
+2020-03-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * etc/NEWS: Add entry missed in previous commit
+
+2020-03-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/elisp-mode.el (elisp-enable-lexical-binding): New command
+
+ (emacs-lisp-mode): Indicate lex/dyn binding mode in the mode line.
+ (elisp--dynlex-modeline-map): New var.
+
+2020-03-03 Štěpán Němec <stepnem@gmail.com>
+
+ Use help-fns-short-filename in other describe- commands
+
+ The commit
+
+ 2015-01-16T22:52:15-05:00!monnier@iro.umontreal.ca
+ 24b7f77581
+ (Improve handling of doc-strings and describe-function for cl-generic)
+
+ added 'help-fns-short-filename', which provides file name shortening
+ smarter than a simple 'file-name-nondirectory' call, but besides the
+ generic/eieio functions ('cl--generic-describe', 'cl--describe-class',
+ 'eieio-help-constructor'), it is currently only used by
+ 'describe-function' (via 'help-fns-function-description-header').
+
+ Make the other help commands use it, too.
+
+ (Other than the obvious consistency/maintenance argument, my immediate
+ motivation for this change is the possibility to customize the file
+ name abbreviation by advising the function.)
+
+ * lisp/help.el (describe-mode): Move to help-fns.el. The command was
+ already depending on 'find-lisp-object-file-name' defined there.
+ * lisp/help-fns.el (describe-variable) (describe-face) (describe-keymap)
+ (describe-mode): Use 'help-fns-short-filename'.
+
+2020-03-02 Paul Eggert <eggert@cs.ucla.edu>
+
+ Tweak GMP usage for (HI LO US PS) timestamps
+
+ * src/timefns.c (decode_time_components): Cut down on the number
+ of calls to GMP functions when generating old-style (HI LO US PS)
+ timestamps.
+
+2020-03-02 Alan Third <alan@idiocy.org>
+
+ Fix macOS/GNUstep compilation warnings
+
+ * src/nsfns.m (handlePanelKeys): Unused function.
+ * src/nsterm.m (ns_set_appearance):
+ ([EmacsView initFrameFromEmacs:]): Use EmacsWindow type instead of
+ NSWindow.
+ (ns_clip_to_row): Unused function.
+ (ns_dumpglyphs_stretch): Remove unused variable.
+ (ns_term_init):
+ ([EmacsWindow setAppearance]): Only compile on macOS.
+ (ns_mouse_position): Make sure f is initialised on GNUstep.
+ * src/emacs.c (main): Move allocation of autorelease pool to before
+ first use.
+
+2020-03-02 Alan Third <alan@idiocy.org>
+
+ Fix #defines controlling when NS port draws to offscreen buffer
+
+ * src/nsterm.h (NS_DRAW_TO_BUFFER): New definition.
+ * src/nsterm.m (ns_update_begin):
+ (ns_update_end):
+ (ns_focus):
+ ([EmacsView updateFrameSize:]):
+ ([EmacsView initFrameFromEmacs:]):
+ ([EmacsView copyRect:to:]): Use new #define.
+
+2020-03-02 Štěpán Němec <stepnem@gmail.com>
+
+ whitespace: Turn long lines regexp into a function (bug#36837)
+
+ * lisp/whitespace.el (whitespace-color-on): Turn long lines regexp
+ into a function to ensure it uses current 'whitespace-line-column'
+ and 'fill-column' values. (Bug#36837)
+ (whitespace-lines-regexp): New function.
+
+2020-03-01 AndreaCorallo <akrl@sdf.org>
+
+ * ; Clean-up out of date comment
+
+2020-03-01 Stefan Kangas <stefankangas@gmail.com>
+
+ * lisp/progmodes/cperl-mode.el: Clarify comment.
+
+2020-03-01 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove more XEmacs compat code from viper
+
+ * lisp/emulation/viper-mous.el (viper-multiclick-timeout)
+ (viper-current-click-count, viper-last-click-event-timestamp)
+ (viper-mouse-click-insert-word)
+ (viper-mouse-click-search-word): Remove XEmacs compat code.
+ (viper-event-click-count): Redefine as obsolete function alias
+ for 'event-click-count'.
+ * lisp/emulation/viper-util.el (viper-check-version): Declare
+ obsolete.
+
+2020-03-01 Stefan Kangas <stefankangas@gmail.com>
+
+ Make 'load-dangerous-libraries' obsolete (Bug#37819)
+
+ When 'load-dangerous-libraries' was t, Emacs allowed loading .elc
+ files compiled by XEmacs. This patch removes the support for that use
+ case, and declares the variable obsolete.
+
+ * lisp/subr.el (load-dangerous-libraries): Declare obsolete.
+ * src/lread.c (Fload): Ignore its value, and thereby refuse to load
+ files byte compiled by XEmacs.
+ (syms_of_lread): Update doc string of 'bytecomp-version-regexp' to not
+ refer to it.
+ * doc/emacs/building.texi (Lisp Libraries): Remove its documentation.
+
+2020-02-29 Noah Friedman <friedman@splode.com>
+
+ Fix XEmacs-specific clause in definition of pascal-outline-map.
+
+ * lisp/progmodes/pascal.el (pascal-outline-map): Call set-keymap-name
+ on map, not pascal-outline-map, as the latter is not yet defined.
+
+2020-02-29 Philipp Stephani <phst@google.com>
+
+ Unbreak build with CHECK_STRUCTS
+
+ * src/pdumper.c (dump_object): Fix hash for Lisp_Type after commit
+ 202c3319a28c029d6971dccea92f92425c5e8067.
+
+2020-02-29 AndreaCorallo <akrl@sdf.org>
+
+ Introduce 'effective_load_path'
+
+2020-02-29 AndreaCorallo <akrl@sdf.org>
+
+ * Keep comp-subr-list into pure space
+
+ Sad pure space is not effective nowadays but anyway... should go there.
+
+2020-02-28 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port timestamp tests to odd timezones, (TICKS . HZ)
+
+ * test/src/timefns-tests.el:
+ (format-time-string-padding-minimal-deletes-unneeded-zeros)
+ (format-time-string-padding-minimal-retains-needed-zeros)
+ (format-time-string-padding-spaces)
+ (format-time-string-padding-zeros-adds-on-insignificant-side):
+ Don't assume local time can represent 2000-02-15 00:00:00,
+ as there might be a DST jump over midnight.
+ Work even when timestamps are of (TICKS . HZ) form.
+ Simplify by avoiding need to call time-add.
+
+2020-02-27 Mattias Engdegård <mattiase@acm.org>
+
+ Revert "Signal an error for the regexp "[:alnum:]""
+
+ This reverts commit 8d5e8cddab732ac90e9ae930c63f7830f9dab24f.
+
+2020-02-27 Mattias Engdegård <mattiase@acm.org>
+
+ Revert "Don't complain about the regexp "[:-:]""
+
+ This reverts commit 3766bf728a43933083f4525970bcf9fdace3838d.
+
+2020-02-27 Robert Pluim <rpluim@gmail.com>
+
+ * src/nsterm.m ([EmacsView toolbarClicked:]): Fix last change
+
+2020-02-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/gtkutil.c, src/nsterm.m: Fix bug#39808
+
+ Complete 3b4bd4be1d where I apparently failed to grep properly and
+ missed two more places where the dummy events were generated.
+
+ * src/nsterm.m ([EmacsView toolbarClicked:]):
+ * src/gtkutil.c (xg_tool_bar_callback): Don't emit dummy "prefix" events.
+
+2020-02-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/emacs-lisp/eldoc.el (eldoc-documentation-function): No nil value
+
+ (eldoc--supported-p): Move after the vars it uses. Simplify.
+ (eldoc-print-current-symbol-info): Revert to previous code which
+ assumed a non-nil value of eldoc-documentation-function.
+
+2020-02-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ nnmail-cache-close should not use nofollow
+
+ nnmail-cache-close did not work when ~/.nnmail-cache was a symlink
+ to some other directory. Reported by Michael Albinus (Bug#39793).
+ * lisp/gnus/nnbabyl.el (nnbabyl-create-mbox):
+ * lisp/gnus/nndiary.el (nndiary-generate-nov-file):
+ * lisp/gnus/nnfolder.el (nnfolder-possibly-change-group):
+ * lisp/gnus/nnmbox.el (nnmbox-create-mbox):
+ * lisp/gnus/nnml.el (nnml-generate-nov-file):
+ Pass ‘excl’ to nnmail-write-region when creating a file, for safety.
+ * lisp/gnus/nnmail.el (nnmail-write-region):
+ Add optional MUSTBENEW arg, to stay consistent with write-region.
+ Past ‘nofollow’ to set-file-modes only when MUSTBENEW is ‘excl’.
+
+2020-02-26 Mattias Engdegård <mattiase@acm.org>
+
+ Don't complain about the regexp "[:-:]"
+
+ Suggested by Clément Pit-Claudel.
+
+ * src/regex-emacs.c (regex_compile):
+ * test/src/regex-emacs-tests.el (regexp-invalid): Tolerate ranges.
+
+2020-02-26 Mattias Engdegård <mattiase@acm.org>
+
+ Signal an error for the regexp "[:alnum:]"
+
+ Omitting the extra brackets is a common mistake; see discussion at
+ https://lists.gnu.org/archive/html/emacs-devel/2020-02/msg00215.html
+
+ * src/regex-emacs.c (reg_errcode_t, re_error_msgid): Add REG_ECLASSBR.
+ (regex_compile): Check for the mistake.
+ * test/src/regex-emacs-tests.el (regexp-invalid): Test.
+ * etc/NEWS: Announce.
+
+2020-02-26 Michael Albinus <michael.albinus@gmx.de>
+
+ Finish Tramp's implementation of 'nofollow
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-file-local-copy):
+ Do not use 'nofollow.
+ (tramp-adb-handle-set-file-modes):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-set-file-modes):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-set-file-modes):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-set-file-modes):
+ Handle FLAG properly.
+ (tramp-get-remote-chmod-h): Adapt implementation.
+
+ * test/lisp/net/tramp-tests.el (tramp-get-remote-chmod-h): Declare.
+ (tramp--test-ignore-make-symbolic-link-error): Revert last change.
+ (tramp-test20-file-modes): Adapt test.
+
+2020-02-26 Ryan Olson <ryanolsonx@gmail.com> (tiny change)
+
+ Show friendly message after package install
+
+ * lisp/emacs-lisp/package.el (package-install): Once we know the
+ package has successfully been installed using the `package-install`
+ command, instead of relying on the compile "Done" message, give a
+ message that tells the user that the package has been
+ installed. (Bug#21857)
+
+2020-02-26 Mark Oteiza <mvoteiza@udel.edu>
+
+ Expose ElDoc functions in a hook (Bug#28257)
+
+ * lisp/emacs-lisp/eldoc.el: Update commentary.
+ (eldoc--eval-expression-setup): Use new hook.
+ (eldoc--supported-p): Accommodate new hook.
+ (eldoc-documentation-functions): New hook.
+ (eldoc-documentation-default, eldoc-documentation-compose): New
+ functions.
+ (eldoc-documentation-function): Use 'eldoc-documentation-default' as new
+ default value. Update documentation and custom attributes.
+ (eldoc-print-current-symbol-info): Accommodate possible null value for
+ 'eldoc-documentation-function'.
+ * etc/NEWS: Mention them.
+ * doc/emacs/programs.texi (Emacs Lisp Documentation Lookup): Mention
+ new hook and changes to 'eldoc-documentation-function'.
+ * lisp/hexl.el (hexl-mode, hexl-revert-buffer-function):
+ * lisp/ielm.el (inferior-emacs-lisp-mode):
+ * lisp/progmodes/cfengine.el (cfengine3-mode):
+ * lisp/progmodes/elisp-mode.el (emacs-lisp-mode):
+ * lisp/progmodes/octave.el (octave-mode):
+ * lisp/progmodes/python.el (python-mode): Use new hook.
+
+2020-02-25 Mattias Engdegård <mattiase@acm.org>
+
+ Generate 'substring' byte op (bug#39709)
+
+ The 'substring' byte op was not emitted, apparently by mistake. Fix.
+ Suggested by Mark Oteiza <mvoteiza@udel.edu>.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-defop-compiler): Add '1-3' clause.
+ (byte-compile-one-to-three-args): New.
+ * lisp/emacs-lisp/byte-opt.el (byte-compile-side-effect-free-ops):
+ Add 'byte-substring'.
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (byte-opt-testsuite-arith-data): Test 'substring'.
+
+2020-02-25 Michael Albinus <michael.albinus@gmx.de>
+
+ Finish implementation of {set-}file-modes FLAG arg in Tramp
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-file-local-copy): Do not use
+ 'nofollow for temporary files. Use `tramp-compat-set-file-modes'.
+ (tramp-adb-handle-write-region): Do not use 'nofollow for
+ temporary files.
+ (tramp-adb-handle-set-file-modes): Implement FLAG.
+
+ * lisp/net/tramp-compat.el (tramp-compat-file-modes)
+ (tramp-compat-set-file-modes): New defaliases.
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-set-file-modes):
+ Make explicit check (eq flag 'nofollow).
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-set-file-modes): Implement FLAG.
+ (tramp-do-copy-or-rename-file-directly)
+ (tramp-sh-handle-file-local-copy, tramp-sh-handle-write-region):
+ Do not use 'nofollow for temporary files.
+ (tramp-get-remote-chmod-h): New defun.
+
+ * lisp/net/tramp-smb.el (tramp-smb-handle-set-file-modes):
+ Implement FLAG.
+
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-set-file-modes):
+ Implement FLAG.
+ (tramp-sudoedit-handle-write-region): Use `tramp-compat-set-file-modes'.
+
+ * lisp/net/tramp.el (tramp-default-file-modes): Optional argument FLAG.
+ (tramp-handle-file-modes): Use `file-truename' instead of
+ `file-chase-links'. The latter function does not work for remote
+ file names.
+ (tramp-handle-write-region): Call `tramp-default-file-modes' with
+ 'nofollow if needed. Do not use 'nofollow for temporary files.
+
+ * test/lisp/net/tramp-tests.el
+ (tramp--test-ignore-make-symbolic-link-error): Check also for
+ "Cannot chmod .* with nofollow flag" error.
+ (tramp-test20-file-modes): Extend test.
+ (tramp--test-emacs28-p): New defun.
+
+2020-02-25 Mattias Engdegård <mattiase@acm.org>
+
+ Fix mistake in regexp cleanup
+
+ This error was introduced in 770f76f050.
+
+ * lisp/org/org.el (org-ts-regexp-inactive): Match up to the first ']'.
+
+2020-02-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-02-24 getloadavg: don't use /usr/local when cross-compiling on AIX
+ 2020-02-24 fcntl: add witness of gnulib override
+ * lib/fcntl.in.h, m4/getloadavg.m4: Copy from Gnulib.
+
+2020-02-25 Juri Linkov <juri@linkov.net>
+
+ * lisp/textmodes/nroff-mode.el (nroff-mode-map): Remove key 'M-s' (bug#39706)
+
+ * lisp/comint.el (comint-redirect-setup): Guard mode-line-process (bug#39705)
+
+2020-02-24 Eli Zaretskii <eliz@gnu.org>
+
+ Adapt the MS-Windows build to 'nofollow' changes
+
+ * nt/gnulib-cfg.mk (OMIT_GNULIB_MODULE_fchmodat)
+ (OMIT_GNULIB_MODULE_lchmod): Set to true to omit building these
+ modules on MS-Windows.
+ * nt/mingw-cfg.site (ac_cv_func_fchmodat)
+ (gl_cv_func_fchmodat_works, ac_cv_func_lchmod): Disable tests on
+ MS-Windows.
+
+ * src/w32.c (chmod_worker, lchmod, fchmodat): New functions.
+ (sys_chmod): Move most of the code to chmod_worker.
+ * src/w32.h (fchmodat, lchmod): Add prototypes.
+
+2020-02-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ Add 'nofollow' flag to set-file-modes etc.
+
+ This avoids some race conditions (Bug#39683). E.g., if some other
+ program changes a file to a symlink between the time Emacs creates
+ the file and the time it changes the file’s permissions, using the
+ new flag prevents Emacs from inadvertently changing the
+ permissions of a victim in some completely unrelated directory.
+ * admin/merge-gnulib (GNULIB_MODULES): Add fchmodat.
+ * doc/lispref/files.texi (Testing Accessibility, Changing Files):
+ * doc/lispref/os.texi (File Notifications):
+ * etc/NEWS:
+ Adjust documentation accordingly.
+ * lib/fchmodat.c, lib/lchmod.c, m4/fchmodat.m4:
+ * m4/lchmod.m4: New files, copied from Gnulib.
+ * lib/gnulib.mk.in: Regenerate.
+ * lisp/dired-aux.el (dired-do-chmod):
+ * lisp/doc-view.el (doc-view-make-safe-dir):
+ * lisp/emacs-lisp/autoload.el (autoload--save-buffer):
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-file):
+ * lisp/eshell/em-pred.el (eshell-pred-file-mode):
+ * lisp/files.el (backup-buffer-copy, copy-directory):
+ * lisp/gnus/mail-source.el (mail-source-movemail):
+ * lisp/gnus/mm-decode.el (mm-display-external):
+ * lisp/gnus/nnmail.el (nnmail-write-region):
+ * lisp/net/tramp-adb.el (tramp-adb-handle-file-local-copy)
+ (tramp-adb-handle-write-region):
+ * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-directly):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-write-region):
+ * lisp/net/tramp.el (tramp-handle-write-region)
+ (tramp-make-tramp-temp-file):
+ * lisp/server.el (server-ensure-safe-dir):
+ * lisp/url/url-util.el (url-make-private-file):
+ When getting or setting file modes, avoid following symbolic links
+ when the file is not supposed to be a symbolic link.
+ * lisp/doc-view.el (doc-view-make-safe-dir):
+ Omit no-longer-needed separate symlink test.
+ * lisp/gnus/gnus-util.el (gnus-set-file-modes):
+ * lisp/net/tramp.el (tramp-handle-file-modes):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-set-file-modes):
+ * src/fileio.c (symlink_nofollow_flag): New function.
+ (Ffile_modes, Fset_file_modes):
+ Support an optional FLAG arg. All C callers changed.
+ * lisp/net/ange-ftp.el (ange-ftp-set-file-modes):
+ * lisp/net/tramp-adb.el (tramp-adb-handle-set-file-modes):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-set-file-modes):
+ * lisp/net/tramp-smb.el (tramp-smb-handle-set-file-modes):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-set-file-modes):
+ Accept an optional FLAG arg that is currently ignored,
+ and add a FIXME comment for it.
+ * m4/gnulib-comp.m4: Regenerate.
+
+2020-02-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-02-23 use 'restrict'
+ * lib/careadlinkat.h, lib/md5.h, lib/sha1.h, lib/sha256.h:
+ * lib/sha512.h, lib/strftime.h, lib/string.in.h, m4/nstrftime.m4:
+ Copy from Gnulib.
+ * m4/gnulib-comp.m4: Regenerate.
+
+2020-02-23 Wilson Snyder <wsnyder@wsnyder.org>
+
+ Add `verilog-auto-inst-template-required'.
+
+ * lisp/progmodes/verilog-mode.el (verilog-auto-inst-template-required)
+ (verilog-auto-inst): Add `verilog-auto-inst-template-required' to only
+ insert AUTOINST ports inside an AUTO_TEMPLATE, msg3170. Reported by Ted
+ Huang, Brian Magnuson.
+
+2020-02-23 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ ba7004b2a7 (origin/emacs-27) Shorten some ppss struct field names
+ 693749c60f Java Mode: Fix fontification of variable decl inside `for'
+ 884b68ca2c CC Mode: Fontify foo in "const auto foo :" correctly
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-02-23 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ dd5756436c Move more logic to vc-ignore from vc-default-ignore
+ 2aed279be1 Warn about the likes of "[:alnum:]" in regexps
+ 0273f261a7 Don't write absolute filenames and duplicate strings to CV...
+ d7c22338d2 Fix cursor-sensor--detect when current buf != selected win...
+ 2e39fc83bb * doc/emacs/sending.texi (Mail Sending): Fix index entries.
+ b410f902d5 Document 'message-send-mail-function' in the Emacs manual
+ ac0546612d Fix reference to 'message-send-and-exit' in Emacs manual
+ cd6a9b8f65 Skip shell prompt on current line in Eshell even if it's p...
+
+2020-02-23 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-02-22 fchmodat, lchmod: simplify
+ 2020-02-22 lchmod: fix link error on Solaris 10
+ 2020-02-22 use 'restrict' in all POSIX function declarations
+ 2020-02-22 chmodat, chownat: new modules
+ * lib/gnulib.mk.in: Regenerate.
+ * lib/inttypes.in.h, lib/openat.h, lib/signal.in.h:
+ * lib/stdio.in.h, lib/stdlib.in.h, lib/string.in.h:
+ * lib/sys_stat.in.h, lib/time.in.h, lib/unistd.in.h, m4/inttypes.m4:
+ * m4/signal_h.m4, m4/stdio_h.m4, m4/stdlib_h.m4, m4/string_h.m4:
+ * m4/sys_socket_h.m4, m4/sys_stat_h.m4, m4/time_h.m4:
+ * m4/unistd_h.m4: Copy from Gnulib.
+
+2020-02-23 Juri Linkov <juri@linkov.net>
+
+ * lisp/font-lock.el (font-lock-ensure): Use font-lock-specified-p (bug#39597)
+
+2020-02-22 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-02-21 largefile: remove _DARWIN_USE_64_BIT_INODE
+ 2020-02-21 Add ‘extern "C"’ to count-one-bits.h etc.
+ * lib/count-leading-zeros.h, lib/count-one-bits.h:
+ * lib/count-trailing-zeros.h, m4/largefile.m4: Copy from Gnulib.
+
+2020-02-22 Paul Eggert <eggert@cs.ucla.edu>
+
+ Restore runtime check for invalid tag
+
+ * src/data.c (wrong_type_argument): Restore check that the
+ object’s tag is valid, since invalid tags exist again.
+ * src/lisp.h (Lisp_Type_Unused0): New constant.
+
+2020-02-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/keyboard.c: Copy last tool-bar change to tab-bar.
+
+ (make_lispy_event) <TAB_BAR_EVENT>: Make event with proper location info.
+
+ * src/xdisp.c (handle_tab_bar_click, tty_handle_tab_bar_click): Don't
+ emit dummy "prefix" event.
+
+2020-02-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/keyboard.c (make_lispy_event): Generate proper tool-bar events.
+
+ Generate events which carry the location info.
+
+ * src/xdisp.c (handle_tool_bar_click): Don't emit dummy "prefix" events.
+
+2020-02-21 Federico Tedin <federicotedin@gmail.com>
+
+ Allow tempo-define-template to reassign tags to new templates
+
+ * lisp/tempo.el (tempo-define-template): Update documentation string
+ to mention that existing tags can be reassigned new templates.
+ (tempo-add-tag): Allow reassigning tags to new templates.
+ Additionally, invalidate tag collections in all buffers if the global
+ tags list is being modified.
+ (tempo-invalidate-collection): Allow invalidating tag collections in
+ all buffers at the same time.
+ * test/lisp/tempo-tests.el (tempo-define-tag-globally-test): Add a
+ test to check that new templates plus tags can be defined from any
+ buffer and then immediately used in other buffers.
+ (tempo-overwrite-tag-test): Add a test to check that tags can be
+ reassigned templates.
+ * etc/NEWS: Announce changes in tempo.el.
+
+ (Bug#39555)
+
+2020-02-20 Mattias Engdegård <mattiase@acm.org>
+
+ Less bad permutation generator in regexp-opt test
+
+ * test/lisp/emacs-lisp/regexp-opt-tests.el
+ (regexp-opt-test--permutation, regexp-opt-test--factorial): Remove.
+ (regexp-opt-test--permutations): Rewrite.
+
+2020-02-20 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 9f08524748 (origin/emacs-27) Fix broken regexps
+ 1d10885763 ; spelling and comment fix
+ 614203bc80 ; make change-history-commit
+ 28399e585e * Makefile.in (PREFERRED_BRANCH): Now emacs-27.
+ 62afbc513a Fix bug when visiting euc-jp-encoded directories
+ a2c4eeeecd Clarify when fixnums are used.
+ 4e5ac4b0c6 Reorder discussion of integer basics
+ f765aad28b Make OMake support slightly less expensive (bug#39595)
+ 39410cfc5a Speed up 'msft' and 'watcom' compilation error regexps
+ 96a269d045 Speed up 'maven' compilation error message regexp
+ efc9d4fe3e Amend c-backward-sws better to handle multiline block comm...
+
+2020-02-20 Mattias Engdegård <mattiase@acm.org>
+
+ Remove subsumed repetitions in regexps
+
+ Make regexps smaller and faster by removing terms that are superfluous
+ by virtue of standing next to another term that matches more. See
+ https://lists.gnu.org/archive/html/emacs-devel/2020-01/msg00949.html
+ for details.
+
+ * lisp/bs.el (bs--make-header-match-string):
+ * lisp/gnus/deuglify.el (gnus-outlook-repair-attribution-block):
+ * lisp/gnus/message.el (message-subject-trailing-was-ask-regexp)
+ (message-subject-trailing-was-regexp):
+ * lisp/informat.el (Info-validate):
+ * lisp/net/browse-url.el (browse-url-button-regexp):
+ * lisp/net/rcirc.el (rcirc-url-regexp):
+ * lisp/org/ob-core.el (org-babel-remove-result):
+ * lisp/org/ob-fortran.el (org-babel-fortran-ensure-main-wrap):
+ * lisp/org/org-capture.el (org-capture-set-target-location):
+ * lisp/org/org-table.el (org-table-expand-lhs-ranges):
+ * lisp/org/org.el (org-maybe-keyword-time-regexp, org-ts-regexp)
+ (org-ts-regexp-inactive, org-ts-regexp-both):
+ * lisp/play/gametree.el (gametree-hack-file-layout):
+ * lisp/progmodes/cc-mode.el (c-Java-defun-prompt-regexp):
+ * lisp/progmodes/idlw-shell.el (idlwave-shell-halting-error):
+ * lisp/progmodes/ruby-mode.el (ruby-mode-set-encoding):
+ * lisp/progmodes/verilog-mode.el (verilog-error-font-lock-keywords)
+ (verilog-verilint-off, verilog-case-indent-level)
+ (verilog-within-translate-off, verilog-start-translate-off)
+ (verilog-back-to-start-translate-off, verilog-end-translate-off)
+ (verilog-expand-dirnames):
+ * lisp/term.el (term-control-seq-regexp):
+ * lisp/textmodes/reftex-vars.el (featurep):
+ * lisp/url/url-gw.el (url-open-telnet):
+ * lisp/vc/ediff-ptch.el (ediff-context-diff-label-regexp):
+ * lisp/vc/pcvs-parse.el (cvs-parse-status):
+ * test/src/regex-emacs-tests.el (regex-tests-PCRE):
+ Remove subsumed repetitions.
+ * lisp/progmodes/sh-script.el (sh-syntax-propertize-function):
+ Simplify repetition of a repetition.
+
+2020-02-20 Mattias Engdegård <mattiase@acm.org>
+
+ Add and remove backslashes in regexps
+
+ These irregularities were found by relint; see
+ https://lists.gnu.org/archive/html/emacs-devel/2020-01/msg00949.html .
+
+ * doc/lispref/modes.texi (Example Major Modes):
+ * etc/srecode/el.srt:
+ * lisp/cedet/data-debug.el (data-debug-mode):
+ * lisp/cedet/semantic/grammar.el (semantic-grammar-mode):
+ * lisp/cedet/srecode/srt-mode.el (srecode-template-mode):
+ * lisp/comint.el (comint--unquote&requote-argument):
+ * lisp/emacs-lisp/lisp-mode.el (lisp-mode):
+ * lisp/gnus/mm-uu.el (mm-uu-type-alist):
+ * lisp/progmodes/cc-awk.el (c-awk-harmless-pattern-characters*):
+ * lisp/progmodes/cfengine.el (cfengine-common-settings):
+ * lisp/progmodes/cperl-mode.el (cperl-after-sub-regexp, cperl-init-faces):
+ * lisp/shell.el (shell-chdrive-regexp, shell--unquote&requote-argument):
+ * lisp/textmodes/tex-mode.el (tex-common-initialization):
+ Remove duplicated backslashes in character alternatives.
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-el-font-lock-keywords-2):
+ * lisp/progmodes/opascal.el (opascal--syntax-propertize):
+ * lisp/progmodes/pascal.el (pascal--syntax-propertize):
+ Remove backslashes escaping non-special characters.
+
+ * lisp/progmodes/fortran.el (fortran-font-lock-keywords-3): Escape '*'.
+ * lisp/progmodes/perl-mode.el (perl-syntax-propertize-function):
+ Escape '^'.
+
+2020-02-20 Mattias Engdegård <mattiase@acm.org>
+
+ Remove Emacs 20 bug workaround in ebnf2ps (bug#39663)
+
+ * lisp/progmodes/ebnf2ps.el (ebnf-range-regexp): Remove. All calls
+ replaced with a string equivalent to the returned value.
+
+2020-02-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ shr comment typo fix
+
+ * lisp/net/shr.el (shr-parse-base): Comment typo fix.
+
+2020-02-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix problem with degenerate <html base="."> specs in shr
+
+ * lisp/url/url-expand.el (url-expand-file-name): Don't bug out on
+ degenerate base/expander pairs (bug#39235).
+
+2020-02-20 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix <button>...</button> submit button rendering in eww
+
+ * lisp/net/eww.el (eww-form-submit): Use the contents of the
+ <button>...</button> for the string if there is no value
+ (bug#39326).
+
+2020-02-20 Kévin Le Gouguec <kevin.legouguec@gmail.com>
+
+ Introduce face for <code> elements in shr
+
+ * lisp/net/shr.el (shr-tag-code): Don't use the `default' font,
+ because it has properties that will override surrounding elements
+ (like <a...>) (bug#39504).
+
+2020-02-19 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix some file-modes races
+
+ * lisp/gnus/gnus-start.el (gnus-save-newsrc-file)
+ (gnus-slave-save-newsrc):
+ * lisp/gnus/gnus-uu.el (gnus-uu-initialize):
+ * lisp/gnus/mm-archive.el (mm-dissect-archive):
+ * lisp/gnus/mm-decode.el (mm-temp-files-delete)
+ (mm-display-external):
+ * lisp/image-dired.el (image-dired-create-thumb-1):
+ Use with-file-modes rather than setting the file modes later.
+ This fixes some race conditions where the file temporarily
+ has the wrong permissions.
+
+2020-02-19 Johan Bockgård <bojohan@gnu.org>
+
+ Fix search for ~/.Xdefaults-HOSTNAME (again)
+
+ * src/xrdb.c (get_environ_db): Fix typo when handling
+ ~/.Xdefaults-HOSTNAME.
+
+2020-02-19 Jeremy Compostella <jeremy.compostella@gmail.com>
+
+ Fix conversion of text/html->multipart/related
+
+ * lisp/gnus/mml.el (mml-expand-all-html-into-multipart-related):
+ New function (bug#39230).
+ (mml-generate-mime): Use it to expand all HTML parts, no matter
+ where in the MIME tree.
+
+2020-02-19 Masahiro Nakamura <tsuucat@icloud.com>
+
+ Fix working text related issues on NS (Bug#38851)
+
+ * src/keyboard.c (read_char): Prevent redsiplay right after
+ ns-unput-working-text event.
+ * src/nsterm.m ([EmacsView insertText:]): Partially revert commit
+ ba04217.
+ ([EmacsView firstRectForCharacterRange:]): Fix candidate window
+ position when cursor is on echoarea.
+ ([EmacsView mouseDown:])
+ ([EmacsView windowDidResignKey:]): Don't delete working text.
+
+2020-02-19 Alan Third <alan@idiocy.org>
+
+ Fix horizontal bit shifting
+
+ * src/nsterm.m ([EmacsView copyRect:to:]): Calculate the horizontal
+ difference instead of just the vertical.
+ ([EmacsView updateLayer]): Fix NSTRACE message.
+
+2020-02-19 Paul Eggert <eggert@cs.ucla.edu>
+
+ * doc/misc/texinfo.tex: Update from Gnulib.
+
+2020-02-19 Juri Linkov <juri@linkov.net>
+
+ Support state changing VC operations in dired-mode on files (bug#34949)
+
+ * lisp/vc/vc.el (vc-deduce-fileset): Don't error out when observer is nil.
+ (vc-dired-deduce-fileset): Add optional args 'state-model-only-files'
+ and 'observer'. Check that all files are in a consistent state
+ when state-model-only-files is non-nil. Error out on directories.
+
+ * lisp/vc/vc-dispatcher.el (vc-dispatcher-browsing): Check dired-mode
+ for derived-mode-p.
+
+2020-02-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/wdired.el (wdired-next-line, wdired-previous-line): Preserve column
+
+2020-02-17 Paul Eggert <eggert@cs.ucla.edu>
+
+ Avoid unlikely load-average bug
+
+ * src/fns.c (Fload_average): Do not crash or return nonsense
+ if the load average exceeds most-positive-fixnum/100 (Bug#39577).
+
+2020-02-16 Paul Eggert <eggert@cs.ucla.edu>
+
+ Improve C-h C-h bug fix
+
+ * src/lread.c (read1): Guard against two 'struct Lisp_Vector *'
+ pointers differing only in their most significant bit. Problem
+ reported by Pip Cet (Bug#39529#22).
+
+2020-02-16 Glenn Morris <rgm@gnu.org>
+
+ * src/lread.c (read1): Fix int/Lisp_Object mix up.
+
+ Found by --enable-check-lisp-object-type.
+
+2020-02-16 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 7ceb45f61f (origin/emacs-27) Reformulate c-end-of-macro, handling mul...
+ 888ffd960c Fix unexec failure on macOS 10.15.4
+ b392c9f365 Fix 'reverse-region' when less than one line is in region
+ 7448834f73 Correct default regexp in 'package-menu-hide-package'
+ faada7ca42 Remove obsolete menu entry "Redisplay buffer"
+ 78d76cd93c Remove redundant 'msft' compilation error rule (bug#39595)
+ 75a9eee8b8 ; * src/editfns.c (Fbuffer_size): Tiny clarification.
+ 4d8d25d641 * doc/lispref/variables.texi (special-variable-p): Clarify...
+ 9f6a4bbcc9 Remove the optional KEEP-ORDER argument to regexp-opt
+ d1e8ce8bb6 Make after-change-functions called from call-process get t...
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-02-16 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix C-h C-h bug due to mutating a hash key
+
+ Problem reported by Federico Tedin (Bug#39529).
+ The problem was that dumping uses a hash table based on 'equal'
+ when purecopying compiled objects, but then modifies the compiled
+ objects while they are keys in the table. This no-no was uncovered
+ by the sxhash fixes in 2020-01-07T19:23:11Z!eggert@cs.ucla.edu.
+ Eli Zaretski pinpointed the patch that triggered the bug.
+ * src/lread.c (read1): When reading a compiled object, replace
+ its docstring with a unique negative integer instead of with 0,
+ so that purecopy doesn’t unify it with some other compiled object
+ that happens to have the same Lisp code.
+
+2020-02-15 Glenn Morris <rgm@gnu.org>
+
+ Remove another test for deleted lread feature
+
+ * test/lisp/emacs-lisp/bytecomp-tests.el
+ (bytecomp-tests--old-style-backquotes): Remove.
+
+2020-02-15 Mark Oteiza <mvoteiza@udel.edu>
+
+ Fix typos
+
+ * src/lcms.c (lcms-xyz->jch, lcms-jch->xyz): Swap first line of docstrings.
+
+2020-02-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * etc/NEWS: Improve last change
+
+2020-02-14 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ When searching a topic in Gnus, search all topic's groups
+
+ Bug#39515
+
+ * lisp/gnus/nnir.el (gnus-group-make-nnir-group): Bring the code in
+ line with the documentation, which says that all topic groups will be
+ searched, even if they're not visible.
+
+2020-02-14 Glenn Morris <rgm@gnu.org>
+
+ Remove lread tests for a feature that was deleted
+
+ * test/src/lread-tests.el (lread-tests--old-style-backquotes)
+ (lread-tests--force-new-style-backquotes): Remove.
+
+2020-02-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/lread.c: Remove old-style backquotes support
+
+ (new_backquote_flag): Delete variable.
+ (load_error_old_style_backquotes): Delete function.
+ (force_new_style_backquotes): Delete variable.
+ (read_internal_start): Don't obey it any more.
+
+2020-02-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/nnmaildir.el: Fix O(n^2) problem when leaving a group
+
+ Use lexical-binding.
+
+ (nnmaildir-close-group): Use a hash-table rather than a list to keep
+ track of the files we have seen.
+
+ * lisp/gnus/nnheader.el (nnheader-parse-naked-head):
+ Use make-full-mail-header.
+
+2020-02-14 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/simple.el (undo): Use undo--last-change-was-undo-p
+
+2020-02-14 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Tramp tests for MS Windows
+
+ * test/lisp/net/tramp-tests.el (tramp-test29-start-file-process)
+ (tramp-test30-make-process): Improve for MS-Windows.
+
+2020-02-14 Mark Oteiza <mvoteiza@udel.edu>
+
+ Add an appropriate error for reading bad JSON arrays
+
+ * lisp/json.el (json-array-format): New error.
+ (json-read-array): Use it.
+
+2020-02-13 Alan Third <alan@idiocy.org>
+
+ Use CGImage instead of NSBitmapImageRep (bug#32932)
+
+ * src/nsterm.m (ns_update_end):
+ (ns_clear_frame): Remove forced draws.
+ (ns_draw_fringe_bitmap):
+ (ns_dumpglyphs_image): No longer need to invert images as the context
+ is already flipped.
+ ([EmacsView updateFrameSize:]):
+ ([EmacsView initFrameFromEmacs:]): Use new function.
+ ([EmacsView createDrawingBuffer]): Replaces createDrawingBufferWithRect:.
+ ([EmacsView focusOnDrawingBuffer]): Set CGImage context.
+ ([EmacsView windowDidChangeBackingProperties:]): Use new function.
+ ([EmacsView copyRect:to:]): Copy using CGImages.
+ ([EmacsView wantsUpdateLayer]):
+ ([EmacsView updateLayer]): New Functions.
+ ([EmacsView drawRect:]): We no longer do anything special here for
+ Cocoa.
+ ([EmacsView windowDidChangeBackingProperties:]): Fix indentation and
+ add NSTRACE.
+
+2020-02-13 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 0304f53076 (origin/emacs-27) doc/misc/org.texi: Fix @dircategory
+ 027da652a4 Fix display of minibuffer prompt in ido.el
+ 5a21aaff46 rx: Use longest match for all-string 'or' forms (bug#37659)
+ 2b12c2b6f2 Make sure not to mark directories
+ ff4ed4a0ff ; Add a TODO
+ 3a5129a1c9 vc-hg-dir-status-files: Fix when DIR is not repository root
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-02-13 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ ad5e350ab7 c-end-of-macro: Handle block comment lines with unescaped N...
+ 06c302d425 Fix set-fontset-font with ADD arg non-nil
+ 530067463b Correct "different than" to "different from" where appropr...
+ 56b8768b32 More accurate documentation of 'package-menu-hide-package'
+
+2020-02-13 Michael Albinus <michael.albinus@gmx.de>
+
+ Simplify Tramp caching
+
+ * lisp/net/tramp-cache.el (tramp-flush-file-upper-properties)
+ (tramp-flush-directory-properties)
+ (tramp-flush-connection-properties, tramp-list-connections)
+ (tramp-parse-connection-properties):
+ * lisp/net/tramp-gvfs.el (tramp-parse-goa-accounts)
+ (tramp-parse-media-names): Simplify cache handling.
+
+2020-02-13 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix `tramp-interrupt-process'
+
+ * lisp/net/tramp.el (tramp-interrupt-process): Improve command.
+
+ * test/lisp/net/tramp-tests.el (tramp-test06-directory-file-name)
+ (tramp-test26-file-name-completion): Simplify.
+ (tramp-test31-interrupt-process): Remove :unstable tag.
+
+2020-02-12 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Tramp tests towards *BSD
+
+ * test/lisp/net/tramp-tests.el (tramp-get-remote-gid): Declare.
+ (tramp-test18-file-attributes): Check `file-ownership-preserved-p'
+ only if possible.
+ (tramp-test30-make-process): Modify test due to *BSD.
+
+2020-02-11 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix problem with auth-source.el in Tramp
+
+ * lisp/net/tramp.el (tramp-read-passwd):
+ Use `tramp-compat-temporary-file-directory'. (Bug#39389, Bug#39489)
+
+2020-02-10 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix window position in Tramp's shell-command
+
+ * lisp/net/tramp.el (tramp-handle-shell-command): Fix `window-start'
+ in output buffer. (Bug#39171)
+
+2020-02-10 Juri Linkov <juri@linkov.net>
+
+ Use quit-restore-window to close tab (bug#39446)
+
+ * lisp/tab-bar.el (display-buffer-in-new-tab): New function with code
+ from display-buffer-in-tab.
+ (display-buffer-in-tab): Call display-buffer-in-new-tab.
+ (switch-to-buffer-other-tab): Instead of 'display-buffer-same-window'
+ use '(reusable-frames . t)'.
+
+ * lisp/windmove.el (windmove-display-in-direction): Set arg 'type'
+ to 'tab' for window--display-buffer when creating a new tab.
+
+ * lisp/window.el (quit-restore-window): Call tab-bar-close-tab
+ when quit-restore type is 'tab'.
+ (display-buffer-record-window): Set window-parameter 'quit-restore'
+ to 'tab' for type 'tab'.
+ (window--display-buffer): Set window-prev-buffers to nil for tab too.
+
+2020-02-09 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-02-08 lchmod: ensure declaration on HP-UX
+ 2020-02-08 fchmodat: fix endless recursion on Cygwin
+ 2020-02-08 Fix compilation errors in a testdir
+ 2020-02-07 fchmodat: AT_SYMLINK_NOFOLLOW fix for non-symlinks
+ 2020-02-04 Port _Noreturn to older Clang
+ 2020-02-03 libc-config: port to Apple’s Clang variant
+ * lib/_Noreturn.h, lib/c++defs.h, lib/libc-config.h, lib/sys_stat.in.h:
+ * m4/gnulib-common.m4, m4/sys_stat_h.m4: Copy from Gnulib.
+ * lib/gnulib.mk.in: Regenerate.
+
+2020-02-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/simple.el (undo-redo): New command
+
+ (undo--last-change-was-undo-p): New function.
+
+ * test/lisp/simple-tests.el (simple-tests--exec): New function.
+ (simple-tests--undo): New test.
+
+2020-02-08 Eli Zaretskii <eliz@gnu.org>
+
+ Allow composition of pure-ASCII strings in the mode line
+
+ * src/composite.c (Fcomposition_get_gstring): Allow unibyte
+ strings if they are pure ASCII, by copying text into a
+ multibyte string.
+
+2020-02-08 Kyle Hubert <khubert@gmail.com> (tiny change)
+
+ Improve prefix arg support in 'ediff-scroll-horizontally'
+
+ * lisp/vc/ediff-util.el (ediff-scroll-horizontally): Use
+ 'current-prefix-arg' to pass the value of prefix argument to
+ scrolling commands. (Bug#39353)
+
+2020-02-08 Yuan Fu <casouri@gmail.com>
+
+ Enhance memory address evaluation in gdb-mi
+
+ Before, the memory buffer evaluated the expression as address and used
+ the fixed result in each stop. This change store the expression
+ itself and reevaluates it in each stop to yield an address.
+ We also add a warning (a red bold exclamation mark) on the header line
+ when the content of the page doesn't represent the memory location
+ user requested for. That happends when some error occurs in
+ evaluating the address, and we display the last successfully displayed
+ memory page.
+ * lisp/progmodes/gdb-mi.el (gdb-memory-address-expression)
+ (gdb--memory-display-warning): New variables.
+ (gdb-memory-address): Change default value to nil; add docstring.
+ (def-gdb-trigger-and-handler, gdb-invalidate-memory)
+ (gdb-memory-set-address): Replace 'gdb-memory-address' with
+ 'gdb-memory-address-expression'.
+ (gdb-memory-header): Add code to display
+ 'gdb-memory-address-expression' on header line. Move the mouse event
+ from address to expression. Add code to display the warning.
+ (gdb-memory-header): Fix the error from
+ 'propertize' when 'gdb-memory-address-expression' or
+ 'gdb-memory-address' is nil.
+ (gdb-read-memory-custom): Change 'error' to 'user-error'. Add code to
+ display the warning. (Bug#39180)
+
+2020-02-07 Michael Albinus <michael.albinus@gmx.de>
+
+ Some Tramp fixes
+
+ * lisp/net/tramp.el (tramp-connectable-p):
+ * lisp/net/tramp-cache.el (tramp-list-connections):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-enabled):
+ Bind `tramp-verbose' to 0.
+
+ * lisp/net/tramp-sh.el (tramp-remote-path, tramp-find-executable):
+ Fix docstring.
+ (tramp-open-shell): Read prompt when moving "~/.editrc".
+
+2020-02-07 Eli Zaretskii <eliz@gnu.org>
+
+ Minor fixes of the last commit
+
+ * src/xdisp.c (get_window_cursor_type): Fix indentation and
+ line-filling.
+ * doc/lispref/frames.texi (Cursor Parameters):
+ * doc/emacs/display.texi (Cursor Display):
+ * etc/NEWS: Fix wording and capitalization of the last change.
+
+2020-02-07 Zajcev Evgeny <zevlg@yandex.ru>
+
+ Support for (box . SIZE) 'cursor-type'
+
+ This allows control of the minimum size of a masked image under
+ which the box cursor becomes hollow.
+ * src/buffer.c (cursor-type): Add commentary about (box . SIZE)
+ 'cursor-type'.
+ * src/xdisp.c (get_specified_cursor_type): Check for 'cursor-type'
+ of the form (box . SIZE).
+ (get_window_cursor_type): Check masked image size for
+ (box . SIZE) 'cursor-type'.
+
+ * doc/emacs/display.texi (Cursor Display):
+ * doc/emacs/display.texi (Cursor Parameters): Add description
+ of (box . SIZE) 'cursor-type'.
+
+ * etc/NEWS: Mention the new (box . SIZE) 'cursor-type'.
+
+2020-02-07 Richard Stallman <rms@gnu.org>
+
+ Merge
+
+2020-02-07 Richard Stallman <rms@gnu.org>
+
+ Lispref: Explain avoiding lambdas on hooks.
+
+ (lispref/modes.texi): Explain avoiding lambdas on hooks.
+
+2020-02-06 AndreaCorallo <akrl@sdf.org>
+
+ Add system-configuration in the compilation output path
+
+ Change parameter name into comp--compile-ctxt-to-file
+
+2020-03-01 Andrea Corallo <akrl@sdf.org>
+
+ Reorganize passes
+
+ - Make propagate responsible for keeping SSA up to date.
+
+ - Run propagate-alloc as very last before final not to risk bothering
+ with mvar array allocation during previous transformations.
+
+ - Fix SSA if TCO modify the CFG.
+
+2020-03-01 Andrea Corallo <akrl@sdf.org>
+
+ Allow for multiple SSA runs
+
+ Add function ssa-status as `comp-func' slot and have `comp-clean-ssa'
+ to run when necessary.
+
+2020-03-01 AndreaCorallo <akrl@sdf.org>
+
+ Remove relocation index form LIMPLE setimm
+
+ Given that every object identify a relocation class simplify setimm too.
+
+2020-03-01 Andrea Corallo <akrl@sdf.org>
+
+ Optimize relocation classes for object duplication
+
+ Merge duplicated objects during final. Precedence is:
+ 1 d-default
+ 2 d-impure
+ 3 d-ephemeral
+
+ Now every object identify uniquely a relocation class. Because of
+ this there's no need to keep the reloc class into m-var.
+
+2020-03-01 Andrea Corallo <akrl@sdf.org>
+
+ Rename comp-emit-set-const -> comp-emit-setimm
+
+ * Reduce stack depth while marking native compiled subrs
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-02-26 AndreaCorallo <akrl@sdf.org>
+
+ * ; Add a TODO for a future optimization
+
+2020-02-26 AndreaCorallo <akrl@sdf.org>
+
+ Store optimize qualities into .eln files
+
+ For now just comp-speed and comp-debug are stored.
+
+2020-02-26 AndreaCorallo <akrl@sdf.org>
+
+ Rename d-base allocation classe into d-default
+
+2020-02-26 AndreaCorallo <akrl@sdf.org>
+
+ Add ephemeral relocation data class
+
+ Add a new class of relocated objects that is in use just during load
+ process. This in order to avoid having to maintain them in the heap
+ and traverse them at every GC.
+
+2020-02-26 Andrea Corallo <akrl@sdf.org>
+
+ Two grammar fixes into async hooks doc
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-02-23 Andrea Corallo <akrl@sdf.org>
+
+ Add two hooks for async native compilation
+
+2020-02-23 Andrea Corallo <akrl@sdf.org>
+
+ Make build process robust against interruptions
+
+ During boo-strap we produce both the .eln and the .elc together.
+ Because the make target is the later this has to be produced as last
+ to be resilient to build interruptions.
+
+2020-02-23 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-02-22 Andrea Corallo <akrl@sdf.org>
+
+ Fix `comp-tests-free-fun'
+
+ Address the case were comp-tests.el is byte-compiled.
+
+2020-02-21 Andrea Corallo <akrl@sdf.org>
+
+ Test 'comp-eq' should not assume any string hashing policy
+
+2020-02-21 AndreaCorallo <akrl@sdf.org>
+
+ Emit 'top_level_run' objects as impure
+
+2020-02-21 Andrea Corallo <akrl@sdf.org>
+
+ Verify '--with-nativecomp' has also '--with-dumping=pdumper'
+
+2020-02-21 AndreaCorallo <akrl@sdf.org>
+
+ Reorder m-var slots
+
+2020-02-21 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-02-16 Andrea Corallo <akrl@sdf.org>
+
+ Update copyright years plus two style nits
+
+ Add a simple pass for self TCO
+
+ Introduce comp-dry-run
+
+ Use `sxhash-eq' to generate mvar SSA ids
+
+2020-02-15 AndreaCorallo <akrl@sdf.org>
+
+ Speed 2 goes default
+
+ Backward propagate only once
+
+2020-02-15 Andrea Corallo <akrl@sdf.org>
+
+ Rework frame layout
+
+ Every function call by reference gets use one unique array of
+ arguments.
+
+2020-02-14 AndreaCorallo <akrl@sdf.org>
+
+ Clean-up old gc disable refuse in comp-tests-non-locals
+
+2020-02-14 Andrea Corallo <akrl@sdf.org>
+
+ Better function naming for comp-function-call-maybe-remove
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-02-06 Andrea Corallo <akrl@sdf.org>
+
+ Clean-up unused variable into load_comp_unit
+
+2020-02-06 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 09eed01afb Wrap some set-auto-mode calls with delay-mode-hooks (bug#3...
+ 4a0a114505 Support ido-vertical-mode better
+ ef5fba9f40 Fix faces tab-bar and tab-line.
+ 831508422e Cater for 3-argument version of pthread_setname_np
+ f27187f963 Clarify lexvar restrictions for add-to-ordered-list, add-t...
+ 32763dac46 Replace add-to-list to lexical variable with push (bug#39373)
+ d07f177382 Clarify add-to-list documentation (bug#39373)
+ d3d2ea927c MH-E: alter content in mh-display-msg, not mh-show-mode
+ db7fa2546f Update documentation for mh-show-mode-hook
+ d10be6bf28 Example goto-addr hook: MH-E already uses goto-address
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-02-06 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/battery.el: Use lexical-binding. Drop Redundant `:group`s.
+
+2020-02-06 Zajcev Evgeny <zevlg@yandex.ru>
+
+ Make 'M-x battery RET' work out-of-box for UPower users.
+
+ * lisp/battery.el (battery-upower-prop): Removed in favor for
+ 'battery-upower-device-property'.
+ (battery-upower-device): Can be nil, meaning autodetect the battery
+ device.
+ (battery-upower-line-power-device): New. line-power device. Can be
+ nil, meaning autodetect line-power device.
+ (battery-status-function): Check UPower service is available to use
+ 'battery-upower' as status function.
+ (battery-upower): Speedup. Request D-Bus only once, fetching all
+ the properties at once. Provide string for "%b" format spec.
+ (battery-upower-device-list, battery-upower-device-all-properties)
+ (battery-upower-device-property): New functions to work with UPower
+ devices.
+ (battery-upower-dbus-service, battery-upower-dbus-interface)
+ (battery-upower-dbus-path, battery-upower-dbus-device-interface)
+ (battery-upower-dbus-device-path): New constants describing UPower
+ D-Bus service.
+
+2020-02-05 Juri Linkov <juri@linkov.net>
+
+ * lisp/wid-edit.el (widget-choose): Use read-char-from-minibuffer (bug#17272)
+
+2020-02-05 Tino Calancha <tino.calancha@gmail.com>
+
+ Eval macro arg just once
+
+ * lisp/emacs-lisp/cl-macs.el (cl--push-clause-loop-body):
+ Use `macroexp-let2' (Bug#39428).
+
+2020-02-05 Tassilo Horn <tsdh@gnu.org>
+
+ Add ':extend t' to mm-uu-extract face
+
+ * lisp/gnus/mm-uu.el (mm-uu-extract): Add ':extend t' to mm-uu-extract
+ face.
+
+2020-02-05 Stefan Kangas <stefankangas@gmail.com>
+
+ Silence byte-compiler warning
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-insert-header): Silence
+ byte-compiler warning about "Unused lexical variable".
+
+2020-02-05 Stefan Kangas <stefankangas@gmail.com>
+
+ Don't use obsolete function in package-tests.el
+
+ * test/lisp/emacs-lisp/package-tests.el
+ (package-test-update-archives, package-test-signed): Use
+ 'revert-buffer' instead of obsolete 'package-menu-refresh'.
+
+2020-02-05 Stefan Kangas <stefankangas@gmail.com>
+
+ Add new filter commands to Package Menu (Bug#38424)
+
+ * lisp/emacs-lisp/package.el (package-menu-filter-by-version)
+ (package-menu-filter-by-status, package-menu-filter-by-archive):
+ New filter commands.
+ (package-menu--filter-by): New helper function.
+ (package-menu-filter-by-keyword, package-menu-filter-by-name): Use
+ the above helper function.
+ (package-menu-mode-menu):
+ (package-menu-mode-map): Update menu to include new filter commands.
+ * doc/emacs/package.texi (Package Menu): Document the new commands and
+ re-arrange the sort order of commands to be closer to the one in
+ describe-major-mode.
+ * etc/NEWS: Announce the new commands.
+
+ * lisp/emacs-lisp/package.el (package-menu--display): New function
+ extracted from....
+ (package-menu--generate): ...here.
+
+ * test/lisp/emacs-lisp/package-tests.el (with-package-menu-test):
+ New macro.
+ (package-test-update-listing, package-test-list-filter-by-name)
+ (package-test-list-filter-clear): Use above macro.
+ (package-test-list-filter-by-archive)
+ (package-test-list-filter-by-keyword)
+ (package-test-list-filter-by-status)
+ (package-test-list-filter-by-version-=)
+ (package-test-list-filter-by-version-<)
+ (package-test-list-filter-by-version->): New tests.
+ (package-test-filter-by-version): New helper function.
+
+2020-02-05 Michael Albinus <michael.albinus@gmx.de>
+
+ Minor fix in tramp-test32-shell-command
+
+ * test/lisp/net/tramp-tests.el (tramp-test32-shell-command):
+ Set `default-directory'.
+
+2020-02-05 Michael Albinus <michael.albinus@gmx.de>
+
+ Handle problem with *BSD libedit in Tramp
+
+ * lisp/net/tramp-sh.el (tramp-sh-extra-args): Add "-noediting" as
+ bash arg.
+ (tramp-open-shell): Provide proper "~/.editrc" if needed. (Bug#39399)
+
+2020-02-05 Michael Albinus <michael.albinus@gmx.de>
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-file-system-info): Fix error.
+
+2020-02-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/gnus-sum.el (gnus-read-move-group-name): Use user-error
+
+2020-02-04 Adam Porter <adam@alphapapa.net>
+
+ * lisp/emacs-lisp/map.el: Add keyword-only pattern abbreviation
+
+ * lisp/emacs-lisp/map.el: Update version to 2.1.
+ ((pcase-defmacro map)): Update docstring.
+ (map--make-pcase-bindings): Match keyword pattern.
+
+ * test/lisp/emacs-lisp/map-tests.el (test-map-plist-pcase): Add test.
+
+2020-02-04 Andrea Corallo <akrl@sdf.org>
+
+ Merge remote-tracking branch 'savannah/master' into HEAD
+
+2020-02-04 Andrea Corallo <akrl@sdf.org>
+
+ Add assertion in load_comp_unit
+
+ While resurrecting from an image dump loading more than once the
+ same compilation unit does not make any sense.
+
+2020-02-04 Stefan Kangas <stefankangas@gmail.com>
+
+ Silence byte-compiler warning
+
+ * lisp/dired.el (grep-read-files-function): Add defvar to silence
+ byte-compiler warning.
+
+2020-02-04 Stefan Kangas <stefankangas@gmail.com>
+
+ Provide default for describe-keymap prompt
+
+ * lisp/help-fns.el (describe-keymap): Provide a reasonable
+ default for prompt. (Bug#30660)
+ (help-fns-find-keymap-name)
+ (help-fns--most-relevant-active-keymap): New functions.
+
+ * test/lisp/help-fns-tests.el
+ (help-fns-test-find-keymap-name): New test.
+
+2020-02-04 Stefan Kangas <stefankangas@gmail.com>
+ Drew Adams <drew.adams@oracle.com>
+
+ Add new help command describe-keymap
+
+ * lisp/help-fns.el (describe-keymap): New command to show key bindings
+ for a given keymap. (Bug#30660)
+ * doc/emacs/help.texi (Misc Help): Document the new command.
+ * doc/lispref/keymaps.texi (Scanning Keymaps): Add a cross-reference
+ to the above documentation.
+ * etc/NEWS: Announce the new command.
+
+ * test/lisp/help-fns-tests.el (help-fns-test-describe-keymap/symbol)
+ (help-fns-test-describe-keymap/value)
+ (help-fns-test-describe-keymap/not-keymap)
+ (help-fns-test-describe-keymap/let-bound)
+ (help-fns-test-describe-keymap/dynamically-bound-no-file): New tests.
+
+2020-02-03 Andrea Corallo <akrl@sdf.org>
+
+ Rework load mechanism to make Vcomp_loaded_handles unnecessary
+
+2020-02-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/sh-script.el: Remove old non-SMIE indentation code
+
+ (sh-learn-basic-offset, sh-blink, sh-use-smie): Remove config vars.
+ (sh-kw-alist, sh-learned-buffer-hook): Remove var.
+ (sh-must-support-indent, sh-mark-init, sh-mark-line): Remove function.
+ (sh-kw, sh-special-keywords): Remove constant.
+ (sh-help-string-for-variable, sh-read-variable, sh-goto-matching-if)
+ (sh-handle-prev-if, sh-handle-this-else, sh-handle-prev-else)
+ (sh-handle-this-fi, sh-handle-prev-fi, sh-handle-this-then)
+ (sh-handle-prev-then, sh-handle-prev-open, sh-handle-this-close)
+ (sh-goto-matching-case, sh-handle-prev-case, sh-handle-this-esac)
+ (sh-handle-prev-esac, sh-handle-after-case-label)
+ (sh-handle-prev-case-alt-end, sh-safe-forward-sexp)
+ (sh-goto-match-for-done, sh-handle-this-done, sh-handle-prev-done)
+ (sh-handle-this-do, sh-handle-prev-do, sh-find-prev-switch)
+ (sh-handle-this-rc-case, sh-handle-prev-rc-case, sh-check-rule)
+ (sh-get-indent-info, sh-get-indent-var-for-line, sh-prev-line)
+ (sh-prev-stmt, sh-get-word, sh-prev-thing, sh-this-is-a-continuation)
+ (sh-get-kw, sh-find-prev-matching, sh-set-var-value)
+ (sh-calculate-indent, sh-indent-line, sh-blink, sh-guess-basic-offset):
+ Remove functions.
+ (sh-show-indent, sh-set-indent, sh-learn-line-indent)
+ (sh-learn-buffer-indent): Redefine as obsolete aliases.
+
+2020-02-03 Andrea Corallo <akrl@sdf.org>
+
+ Always define subr-native-elisp-p also without native compiler
+
+2020-02-03 AndreaCorallo <akrl@sdf.com>
+
+ Fix load_comp_unit for non zero speeds
+
+ 'dlopen' returns the same handle when trying to load two times
+ the same shared.
+
+ Touching 'd_reloc' etc leads to fails in case a frame with a reference
+ to it in a register is active. (comp-speed >= 0)
+
+2020-02-01 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ cdf8c31844 Extend workaround for Cygwin O_PATH bug
+
+2020-02-01 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 5bf2ef3871 Add more blackboard bold characters to TeX input method
+ c362a624d8 ; * lisp/progmodes/gdb-mi.el (gdb-handle-reply): Fix comme...
+ 2b1e18ae85 Protect against errors in gdb-mi.el handlers
+ baceb8e84d Allow exiting the Python interpreter of a GDB session
+ 2e66013dcf Ensure minibuffer input is added to history in read_minibuf
+ de41161534 Tab-bar related fixes.
+ 247f2cfa02 ; ChangeLog.3 fixes.
+ e1a712bb3f * admin/authors.el: Add missing entries.
+
+2020-02-01 Michael Albinus <michael.albinus@gmx.de>
+
+ Implement `shell-command-dont-erase-buffer' in Tramp. (Bug#39067)
+
+ * lisp/net/tramp.el (tramp-handle-shell-command):
+ Handle `shell-command-dont-erase-buffer'. (Bug#39067)
+
+ * test/lisp/net/tramp-tests.el (shell-command-dont-erase-buffer):
+ Declare.
+ (tramp-test10-write-region, tramp-test21-file-links): Use function
+ symbols.
+ (tramp--test-async-shell-command): Don't assume that
+ `async-shell-command' returns the process object.
+ (tramp-test32-shell-command): Rework `async-shell-command-width' test.
+ (tramp-test32-shell-command-dont-erase-buffer): New test.
+
+2020-01-31 Michael Albinus <michael.albinus@gmx.de>
+
+ Remove compatibility hack in Tramp
+
+ * lisp/net/tramp-compat.el (tramp-compat-process-running-p): Remove.
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-enabled):
+ Use `tramp-process-running-p'.
+
+ * lisp/net/tramp.el (with-tramp-progress-reporter): Simplify.
+ (tramp-process-running-p): New defun.
+
+2020-01-31 Juri Linkov <juri@linkov.net>
+
+ * etc/NEWS: Move M-x suggest-key-bindings to "Editing Changes" section.
+
+ * doc/emacs/m-x.texi (M-x): Mention effect of suggest-key-bindings
+ on the completion list of M-x (bug#39035).
+
+2020-01-30 Sam Steingold <sds@gnu.org>
+
+ prune the overly cavalier "kill all gnus buffers exit"
+
+ * lisp/gnus/mail-source.el (mail-source-call-script): Require gnus for
+ `gnus-get-buffer-create', following the pattern in the file.
+ * lisp/gnus/message.el: Autoload `gnus-get-buffer-create'.
+ * lisp/gnus/mm-archive.el: Likewise.
+ * lisp/gnus/mml2015.el: Likewise (the file autoloads other gnus functions).
+ * lisp/gnus/nnheader.el: Likewise.
+ * lisp/gnus/mml1991.el (mml1991-mailcrypt-sign, mml1991-mailcrypt-encrypt):
+ Revert the patch, use `get-buffer-create' instead of `gnus-get-buffer-create'.
+ * lisp/gnus/smime.el (smime-new-details-buffer, smime):
+ smime-certificate-info): Likewise.
+ * lisp/gnus/spam-stat.el (spam-stat-store-current-buffer): Likewise.
+
+2020-01-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Give fuller support for obsolete ---12 dates in iso8601
+
+ * lisp/calendar/iso8601.el
+ (iso8601--outdated-reduced-precision-date-match): New constant.
+ (iso8601--date-match): Use it.
+
+2020-01-30 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make iso8601.el understand two obsolete forms
+
+ * lisp/calendar/iso8601.el (iso8601-parse-date): Understand some
+ obsolete formats to provide compatibility with the vCard RFC
+ (bug#39347).
+
+2020-01-30 Juri Linkov <juri@linkov.net>
+
+ Show key bindings on M-x completion (bug#39035)
+
+ * lisp/simple.el (read-extended-command--annotation): New function.
+ (read-extended-command): Use annotation-function to show key-bindings.
+
+2020-01-29 Sam Steingold <sds@gnu.org>
+
+ fix bug#39344
+
+ * lisp/gnus/gnus.el (gnus-add-buffer): Use 'cl-pushnew' instead of
+ 'push' to avoid duplicate entries.
+
+2020-01-28 Eli Zaretskii <eliz@gnu.org>
+
+ Revert "Fix MS-Windows build broken by "Install C source code""
+
+ This reverts commit 31efd1cea8d692a0b77101ec161a8cf290471ade,
+ since the commit a02b179242a55aba20158aa245e5643a04d07576,
+ which triggered the former commit, has been reverted.
+
+2020-01-28 Alan Third <alan@idiocy.org>
+
+ Merge branch 'scratch/ns/draw-to-bitmap'
+
+2020-01-28 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 1bcac29b2f (origin/emacs-27) dns-mode-soa-auto-increment-serial: safe...
+ abf0f8666d * lisp/wdired.el: Clean out isearch-filter-predicate (bug#...
+ c31c31e57f ; Spelling and URL fixes
+ 066aad7b9d Finish the documentation for c-noise-macro-{,with-parens-}...
+ c8fcabf245 Correct regexp for flags in `format' doc string
+ 2e9a153b26 Moderate recommendation to escape '(' in doc strings
+ d7cd4ab7d9 Objective C Mode: Make c-forward-type work with "unsigned ...
+ 1705e32ebc Fix help text about configure module support
+ baca81e641 * doc/lispref/streams.texi (Output Functions): Improve ind...
+ 568a560fce Improve doc string of 'newline'
+ 7f50698505 Improve doc of eq on bignums etc.
+ e5327a569c Do not refer to obsolete alias
+ fd09196781 ; Clarify what time-stamp-active enables
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-01-28 Sam Steingold <sds@gnu.org>
+
+ Make sure that all gnus buffers are killed on exit
+
+ * lisp/gnus/gnus-agent.el (gnus-agent-synchronize-flags-server):
+ Use `gnus-get-buffer-create' instead of `get-buffer-create'
+ * lisp/gnus/gnus-bookmark.el (gnus-bookmark-write-file): Likewise.
+ (gnus-bookmark-bmenu-list): Likewise.
+ (gnus-bookmark-show-details): Likewise.
+ * lisp/gnus/gnus-draft.el (gnus-draft-setup): Likewise.
+ * lisp/gnus/gnus-icalendar.el (gnus-icalendar-reply): Likewise.
+ * lisp/gnus/gnus-int.el (gnus-backend-trace): Likewise.
+ * lisp/gnus/gnus-srvr.el (gnus-enter-server-buffer): Likewise.
+ * lisp/gnus/gnus-sum.el (gnus-summary-pipe-output): Likewise.
+ * lisp/gnus/gnus-util.el (gnus-output-to-rmail): Likewise.
+ (gnus-output-to-mail): Likewise.
+ (gnus-multiple-choice): Likewise.
+ * lisp/gnus/mail-source.el (mail-source-call-script): Likewise.
+ * lisp/gnus/message.el (message-cancel-news): Likewise.
+ (message-resend): Likewise.
+ * lisp/gnus/mm-archive.el (mm-dissect-archive): Likewise.
+ * lisp/gnus/mml1991.el (mml1991-mailcrypt-sign): Likewise.
+ (mml1991-mailcrypt-encrypt): Likewise.
+ * lisp/gnus/mml2015.el (mml2015-mailcrypt-verify): Likewise.
+ (mml2015-mailcrypt-clear-verify): Likewise.
+ * lisp/gnus/nnbabyl.el (nnbabyl-request-move-article): Likewise.
+ * lisp/gnus/nndiary.el (nndiary-request-move-article): Likewise.
+ (nndiary-find-group-number): Likewise.
+ (nndiary-open-nov): Likewise.
+ (nndiary-generate-nov-file): Likewise.
+ * lisp/gnus/nndoc.el (nndoc-possibly-change-buffer): Likewise.
+ * lisp/gnus/nndraft.el (nndraft-request-move-article): Likewise.
+ (nndraft-auto-save-file-name): Likewise.
+ * lisp/gnus/nneething.el (nneething-get-head): Likewise.
+ * lisp/gnus/nnfolder.el (nnfolder-request-move-article): Likewise.
+ (nnfolder-open-nov): Likewise.
+ * lisp/gnus/nnheader.el (nnheader-init-server-buffer): Likewise.
+ (nnheader-set-temp-buffer): Likewise.
+ * lisp/gnus/nnimap.el (nnimap-log-buffer): Likewise.
+ * lisp/gnus/nnir.el (nnir-run-swish++): Likewise.
+ (nnir-run-swish-e): Likewise.
+ (nnir-run-hyrex): Likewise.
+ (nnir-run-namazu): Likewise.
+ (nnir-run-notmuch): Likewise.
+ (nnir-run-find-grep): Likewise.
+ * lisp/gnus/nnmail.el (nnmail-split-incoming): Likewise.
+ (nnmail-cache-open): Likewise.
+ (nnmail-log-split): Likewise.
+ * lisp/gnus/nnmaildir.el (nnmaildir--with-work-buffer): Likewise.
+ (nnmaildir--with-nov-buffer): Likewise.
+ (nnmaildir--with-move-buffer): Likewise.
+ * lisp/gnus/nnmairix.el (nnmairix-call-mairix-binary): Likewise.
+ (nnmairix-call-mairix-binary-raw): Likewise.
+ (nnmairix-replace-group-and-numbers): Likewise.
+ * lisp/gnus/nnmbox.el (nnmbox-request-move-article): Likewise.
+ * lisp/gnus/nnmh.el (nnmh-request-move-article): Likewise.
+ * lisp/gnus/nnml.el (nnml-request-move-article): Likewise.
+ (nnml-find-group-number): Likewise.
+ (nnml-get-nov-buffer): Likewise.
+ (nnml-generate-nov-file): Likewise.
+ * lisp/gnus/nnrss.el (nnrss-opml-export): Likewise.
+ * lisp/gnus/nntp.el (nntp-record-command): Likewise.
+ * lisp/gnus/nnvirtual.el (nnvirtual-retrieve-headers): Likewise.
+ * lisp/gnus/smime.el (smime-new-details-buffer): Likewise.
+ (smime-certificate-info): Likewise.
+ (smime): Likewise.
+ * lisp/gnus/spam-stat.el (spam-stat-store-current-buffer): Likewise.
+
+2020-01-28 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-01-27 regex: port to non-GCC pre-IEC-60559
+ 2020-01-24 regex: port to Gawk on nonstandard platforms
+ 2020-01-21 regex: fix bug with >=16 subexpressions
+ 2020-01-21 regex: simplify definition of BITSET_WORD_BITS
+ * lib/regex.c, lib/regex_internal.h: Copy from Gnulib.
+
+2020-01-28 Paul Eggert <eggert@cs.ucla.edu>
+
+ Revert the --with-install-srcdir patch
+
+ Also, update description of debuginfo and sources to match
+ Debian and Red Hat more accurately, and move this sad tale
+ from INSTALL to etc/PROBLEMS which is a better home for it.
+ * Makefile.in (emacs_srcdir, install-c-src):
+ * configure.ac (emacs_srcdir, --with-install-srcdir):
+ * src/epaths.in (PATH_EMACS_SOURCE):
+ * src/lread.c (emacs-source-directory):
+ Remove. All uses removed.
+ * lisp/emacs-lisp/find-func.el (find-function-C-source):
+ Do not worry about compressed C sources.
+ * src/lread.c: Do not include <dosname.h>.
+
+2020-01-27 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Bug#39253
+
+ * lisp/net/tramp.el (tramp-handle-shell-command): Set `default-directory'.
+
+2020-01-27 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix problems in Tramp's async-shell-command
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-make-process):
+ * lisp/net/tramp-cache.el (top):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process):
+ Use `insert-file-contents-literally'.
+
+ * lisp/net/tramp.el (tramp-parse-file):
+ Use `insert-file-contents-literally'.
+ (tramp-handle-shell-command): Reorganize error-buffer handling.
+ (tramp-handle-start-file-process): Use `consp' instead of `listp'.
+
+ * test/lisp/net/tramp-tests.el (tramp-test31-interrupt-process):
+ Bind `delete-exited-processes'.
+ (tramp--test-async-shell-command): Bind `delete-exited-processes'.
+ Add additional `accept-process-output'. Move cleanup of output
+ buffer ...
+ (tramp-test32-shell-command): ... here. Test error buffer also
+ for `async-shell-command'.
+
+2020-01-27 Paul Pogonyshev <pogonyshev@gmail.com>
+
+ * lisp/emacs-lisp/debug.el (debug): Merge the non-interactive cases
+
+ bug#38927
+
+2020-01-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/mini-gmp.c: Fix comment typos.
+
+2020-01-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update mini-gmp
+
+ * src/mini-gmp.c, src/mini-gmp.h: Copy from GMP 6.2.0.
+ This incorporates:
+ 2019-12-05 remove some sizeof(mp_limb_t)
+ 2019-12-04 (mpn_invert_3by2): Remove special code for limb sizes
+ 2019-12-04 (mpn_invert_3by2): Limit size of an intermediate
+ 2019-11-20 (mpn_invert_3by2): Use xor instead of negation
+ 2019-11-19 (mpn_invert_3by2): Move an assert earlier
+ 2019-11-19 (mpn_invert_3by2): Add a new shortcut
+ 2019-11-17 Prepend "unsigned" to MINI_GMP_LIMB_TYPE
+ 2019-11-17 Enable testing with different limb sizes (types)
+ 2019-11-20 Use already defined constants
+ 2019-11-09 Avoid undefined behaviour with small limb sizes
+
+2020-01-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Improve doc for emacs-source-directory (Bug#36527).
+
+2020-01-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Propagate NSLocale into Emacs better
+
+ * src/emacs.c (main): Call ns_init_locale before using the
+ environment variable that ns_init_locale sets up (Bug#39248).
+
+2020-01-26 Stefan Kangas <stefankangas@gmail.com>
+
+ Add more tests for bookmark-bmenu-list
+
+ * test/lisp/bookmark-tests.el (cl-lib): Require.
+ (bookmark-test-bmenu-toggle-filenames)
+ (bookmark-test-bmenu-toggle-filenames/show)
+ (bookmark-test-bmenu-show-filenames)
+ (bookmark-test-bmenu-hide-filenames)
+ (bookmark-test-bmenu-bookmark, bookmark-test-bmenu-mark)
+ (bookmark-test-bmenu-any-marks, bookmark-test-bmenu-unmark)
+ (bookmark-test-bmenu-delete, bookmark-test-bmenu-locate): New
+ tests.
+
+ (bookmark-test-bmenu-edit-annotation/show-annotation): Rename from
+ 'bookmark-bmenu-edit-annotation/show-annotation'.
+ (bookmark-test-bmenu-send-edited-annotation): Rename from
+ 'bookmark-bmenu-send-edited-annotation'.
+ (bookmark-test-bmenu-send-edited-annotation/restore-focus): Rename
+ from 'bookmark-bmenu-send-edited-annotation/restore-focus'.
+
+2020-01-25 Michael Albinus <michael.albinus@gmx.de>
+
+ Fix Bug#39279
+
+ * lisp/net/tramp.el (tramp-completion-file-name-handler):
+ Fix thinko. (Bug#39279)
+
+2020-01-25 Eli Zaretskii <eliz@gnu.org>
+
+ Fix MS-Windows build broken by "Install C source code"
+
+ * nt/epaths.nt (PATH_EMACS_SOURCE): Add definition.
+
+2020-01-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ Install C source code for C-h f etc.
+
+ Without this change, on typical GNU/Linux distributions
+ like Debian, the first button of ‘C-h f car RET’ does not work
+ because the source code for ‘car’ is not installed (Bug#37527).
+ Fix this by installing the (compressed) C source code alongside
+ the (compressed) Lisp source code that is already installed.
+ This adds about 3 MB (about 2%) to the size of the installed files
+ on my platform.
+ * Makefile.in (emacs_srcdir): New macro.
+ (epaths-force): Substitute PATH_EMACS_SOURCE.
+ (install-c-src): New rule, that installs a copy of the C source
+ code if emacs_srcdir says to.
+ (install-arch-indep): Depend on it.
+ * configure.ac (emacs_srcdir): New var.
+ Add support for --disable-install-srcdir.
+ * lisp/emacs-lisp/find-func.el (find-function-C-source-directory):
+ Look in emacs-source-directory first.
+ (find-function-C-source): Also look for gzipped source files.
+ * lisp/startup.el (normal-top-level):
+ Also recode emacs-source-directory.
+ * src/epaths.in (PATH_EMACS_SOURCE): New macro.
+ * src/lread.c: Include dosname.h, for IS_ABSOLUTE_FILE_NAME.
+ (syms_of_lread): New var emacs-source-directory.
+
+2020-01-24 Mattias Engdegård <mattiase@acm.org>
+
+ Remove (or double) redundant backslashes in string literals
+
+ See discussion at
+ https://lists.gnu.org/archive/html/emacs-devel/2020-01/msg00749.html .
+
+ * lisp/obsolete/iswitchb.el (iswitchb-summaries-to-end):
+ * test/src/regex-emacs-tests.el (regex-tests-BOOST-frob-escapes):
+ * test/lisp/help-fns-tests.el (help-fns-test-lisp-macro)
+ (help-fns-test-lisp-defun, help-fns-test-lisp-defsubst)
+ (help-fns-test-alias-to-defun, help-fns-test-bug23887):
+ Double backslashes for desired effect.
+ * lisp/org/ol.el (org-link-escape):
+ * lisp/net/nsm.el (nsm-protocol-check--rsa-kx)
+ (nsm-protocol-check--anon-kx, nsm-protocol-check--sha1-sig):
+ * lisp/obsolete/old-whitespace.el (whitespace-buffer):
+ * lisp/obsolete/rcompile.el (remote-compile-run-before):
+ * lisp/obsolete/vi.el (vi-end-of-blank-delimited-word):
+ * lisp/obsolete/vip.el (vip-current-major-mode)
+ (vip-paren-match, vip-switch-to-buffer)
+ (vip-switch-to-buffer-other-window, vip-kill-buffer)
+ (vip-get-ex-token, ex-edit):
+ * lisp/org/org-element.el (org-element--cache-sync-requests):
+ * lisp/org/org.el (org-sparse-tree):
+ * lisp/textmodes/reftex.el (reftex-report-bug):
+ * test/lisp/ibuffer-tests.el (ibuffer-save-filters):
+ * test/lisp/international/ucs-normalize-tests.el
+ (ucs-normalize-tests--insert-failing-lines):
+ * test/lisp/simple-tests.el (undo-test-kill-c-a-then-undo):
+ * test/lisp/textmodes/conf-mode-tests.el (conf-test-toml-mode):
+ * test/src/regex-emacs-tests.el (regex-tests-compare):
+ Remove redundant backslashes.
+
+2020-01-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix iso8601-parse so unknown DST is -1, not nil
+
+ The convention in a decoded time’s dst flag is that t means DST,
+ nil means standard time, and -1 means unknown. This differs from
+ the convention for other components of a decoded time, where nil
+ means unknown. Fix some places where iso8601-parse mistakenly
+ treated nil as meaning that the dst flag was unknown.
+ * doc/lispref/os.texi (Time Parsing):
+ Adjust to match parse-time-string’s doc string.
+ * lisp/calendar/iso8601.el (iso8601-parse):
+ Set dst flag to nil if a numeric time zone or "Z" is given.
+ (iso8601--decoded-time): Default dst flag to -1 if no dst
+ flag or zone is given.
+ * lisp/calendar/time-date.el (decoded-time-set-defaults):
+ When we don’t have a time zone, set the dst flag consistently
+ with DEFAULT-ZONE.
+ * test/lisp/calendar/iso8601-tests.el (test-iso8601-date-years)
+ (test-iso8601-date-dates, test-iso8601-date-obsolete)
+ (test-iso8601-date-weeks, test-iso8601-date-ordinals)
+ (test-iso8601-time, test-iso8601-combined)
+ (test-iso8601-duration, test-iso8601-intervals)
+ (standard-test-dates, standard-test-time-of-day-local-time)
+ (standard-test-time-of-day-fractions)
+ (nonstandard-test-time-of-day-decimals)
+ (standard-test-time-of-day-beginning-of-day)
+ (standard-test-date-and-time-of-day, standard-test-interval):
+ Adjust tests to match fixed behavior.
+
+2020-01-24 Bastien <bzg@gnu.org>
+
+ Fix parse-time-string bug with ISO 8601 defaults
+
+ * lisp/calendar/parse-time.el (parse-time-string):
+ Do not use decoded-time-set-defaults; just let iso8601-parse
+ do its thing.
+
+2020-01-24 Stefan Kangas <stefankangas@gmail.com>
+
+ Add tests for version comparison predicates
+
+ * test/lisp/subr-tests.el (subr-test-version-list-<)
+ (subr-test-version-list-=, subr-test-version-list-<=): New tests.
+
+2020-01-24 Alan Third <address@hidden>
+
+ Draw to offscreen buffer on macOS
+
+ * src/nsfns.m (x_set_background_color): Clear the frame after changing
+ the background color, not before.
+ * src/nsterm.h (drawingBuffer): New variable.
+ ([EmacsView focusOnDrawingBuffer]):
+ ([EmacsView copyRect:to:]):
+ ([EmacsView createDrawingBufferWithRect:]): New methods.
+ * src/nsterm.m (ns_update_begin):
+ (ns_update_end):
+ (ns_focus):
+ (ns_unfocus): Handle drawing to offscreen buffer.
+ (ns_clip_to_row): Use ns_row_rect.
+ (ns_copy_bits): Remove unused function.
+ (ns_scroll_run):
+ (ns_shift_glyphs_for_insert): Use new scrolling method.
+ (ns_draw_fringe_bitmap):
+ (ns_dumpglyphs_image): When drawing to the offscreen buffer, flip
+ images so they appear the right way up.
+ (ns_dumpglyphs_stretch): Remove unnecessary code.
+ (ns_draw_window_cursor): Don't disable screen updates.
+ ([EmacsView updateFrameSize:]): Update the size of the offscreen
+ buffer.
+ ([EmacsView initFrameFromEmacs:]): Create offscreen buffer.
+ ([EmacsView windowDidChangeBackingProperties:]):
+ ([EmacsView createDrawingBufferWithRect:]):
+ ([EmacsView focusOnDrawingBuffer]):
+ ([EmacsView copyRect]): New methods.
+ ([EmacsView viewWillDraw]): Remove method as it no longer does
+ anything useful.
+ ([EmacsView drawRect:]): Handle drawing from offscreen buffer.
+
+2020-01-24 Alan Third <alan@idiocy.org>
+
+ Revert "Make all NS drawing be done from drawRect"
+
+ This reverts commit 7946445962372c4255180af45cb7c857f1b0b5fa.
+
+2020-01-24 Alan Third <alan@idiocy.org>
+
+ Revert "Ensure NS frame is redrawn correctly after scroll"
+
+ This reverts commit a6ab8db3a3dc5ec107ef023c6659620584309c97.
+
+2020-01-24 Alan Third <alan@idiocy.org>
+
+ Revert "Fix some NS drawing issues (bug#32932)"
+
+ This reverts commit 7e8eee60a9dbb0c59cf26f237b21efe7fd1043c9.
+
+2020-01-24 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 0bed550e21 (origin/emacs-27) Remove EmacsOpenPanel and EmacsSavePanel...
+ a0336029db * doc/emacs/files.texi (Auto Save Files): Improve indexing...
+ 57fb8b10c1 Fix inaccurate wording in the Emacs manual
+ 1c487747ab Update ERC module URLs
+ 7d1e9c943f Minor doc string clarification in use-hard-newlines
+
+2020-01-24 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 92f080dda8 Tab-bar related finishing touches.
+ 224e8d1464 Make call_process call signal_after_change. This fixes bu...
+ d02f2a793e * lisp/simple.el: Minor fixes to commentary.
+ 196c42b8bf Fix a few typos
+ 4f2b967795 Fix doc strings for image-dired rotation commands
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-01-24 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Make links in shr use separate mouse highlight regions
+
+ * lisp/net/shr.el (shr-urlify): Make adjacent links have separate
+ mouse highlights (bug#39115).
+
+2020-01-24 Michael Albinus <michael.albinus@gmx.de>
+
+ Adapt tramp-test32-shell-command
+
+ * test/lisp/net/tramp-tests.el (tramp-test32-shell-command):
+ Test error buffer for synchronous `shell-command' only.
+
+2020-01-24 Michael Albinus <michael.albinus@gmx.de>
+
+ Minor code cleanup in Tramp
+
+2020-01-24 Michael Albinus <michael.albinus@gmx.de>
+
+ Support (un)mount of Tramp media devices
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-gio-mapping): Add "gvfs-rename".
+ (tramp-gvfs-do-copy-or-rename-file): Use it.
+ (tramp-gvfs-activation-uri): Handle "media" method.
+ (tramp-gvfs-url-host): New defun.
+ (tramp-gvfs-handler-mounted-unmounted)
+ (tramp-gvfs-connection-mounted-p)
+ (tramp-gvfs-handler-volumeadded-volumeremoved)
+ (tramp-get-media-devices): Use it.
+
+2020-01-24 Robert Pluim <rpluim@gmail.com>
+
+ Expand Cairo and HarfBuzz descriptions
+
+ * etc/NEWS:
+ * configure.ac: Expand description of Cairo and Harfbuzz
+
+2020-01-24 Robert Pluim <rpluim@gmail.com>
+
+ Warn about XFT and about Cairo without HarfBuzz
+
+ * configure.ac: Warn about libXFT usage. Warn about using Cairo
+ without HarfBuzz.
+
+ * etc/NEWS: Announce XFT and HarfBuzz warnings.
+
+2020-01-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ Simplify locale setup
+
+ Stop exporting Vprevious_system_time_locale and
+ Vprevious_system_messages_locale to Elisp. I did that export by
+ mistake in 1999, and the Elisp variables have never been used.
+ Simplifying this cruft should make it easier to fix Bug#39248.
+ * etc/NEWS: Mention this.
+ * src/emacs.c (main): Simplify locale initialization.
+ (synchronize_locale): Simplify.
+ (Vprevious_system_time_locale, Vprevious_system_messages_locale):
+ Now static variables not visible to Lisp, and defined only if
+ HAVE_SETLOCALE.
+ (Vprevious_system_messages_locale): Define only if LC_MESSAGES.
+
+2020-01-24 Glenn Morris <rgm@gnu.org>
+
+ Make so-long test pass following lisp-mnt change
+
+ * lisp/so-long.el (so-long-commentary): Update for lisp-mnt change.
+
+2020-01-23 Bruno Félix Rezende Ribeiro <oitofelix@gnu.org>
+
+ Globally sanitize single-file package long descriptions (Bug#37548)
+
+ Consistent with multi-file package descriptions which don’t have
+ commentary sections nor double semicolon prefixes.
+ * lisp/emacs-lisp/lisp-mnt.el (lm-commentary): Remove commentary
+ header, double semicolon prefixes of each line, trailing new-lines and
+ trailing white-space from commentary.
+ * lisp/emacs-lisp/package.el (package--get-description)
+ (describe-package-1):
+ * lisp/finder.el (finder-commentary):
+ * lisp/info.el (Info-finder-find-node): Remove ad-hoc sanitation.
+
+2020-01-23 Glenn Morris <rgm@gnu.org>
+
+ Unbreak byte compilation
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-fix-header):
+ Update for recent header changes.
+ (byte-compile-insert-header): Add more padding.
+
+2020-01-23 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove irrelevant info from .elc headers
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-insert-header): Don't
+ insert information on ancient Emacs in bytecode headers. (Bug#39233)
+
+2020-01-23 Stefan Kangas <stefankangas@gmail.com>
+
+ Prefer saying "Info manual" to "info page" in docs
+
+ Pointed out by Eli Zaretskii in:
+ https://debbugs.gnu.org/cgi/bugreport.cgi?bug=39215#14
+ * doc/emacs/Makefile.in:
+ * doc/lispintro/Makefile.in:
+ * doc/lispref/Makefile.in:
+ * doc/misc/Makefile.in:
+ * lisp/dired-x.el (top-level):
+ * lisp/gnus/gnus-sum.el (gnus-summary-mode):
+ * lisp/progmodes/cperl-mode.el (cperl-info-page): Doc fix; prefer
+ saying "Info manual" over "info page".
+
+2020-01-23 Michael Albinus <michael.albinus@gmx.de>
+
+ Implement "/media::" default host name in Tramp
+
+ * doc/misc/tramp.texi (GVFS-based methods): Describe default
+ /media:: file name.
+
+ * lisp/net/tramp-cache.el (tramp-get-file-property)
+ (tramp-set-file-property): Check, whether
+ `tramp-cache-{g,s}et-count-*' objects are numbers.
+
+ * lisp/net/tramp-gvfs.el (top): Don't set global default for
+ "media" in `tramp-default-host-alist'.
+ (tramp-gvfs-handler-volumeadded-volumeremoved): New defun.
+ (top): Register "org.gtk.Private.RemoteVolumeMonitor.VolumeAdded"
+ and "org.gtk.Private.RemoteVolumeMonitor.VolumeRemoved" signals.
+ (tramp-get-media-devices): Set defaults for "media" in
+ `tramp-default-host-alist'.
+
+2020-01-23 Tino Calancha <tino.calancha@gmail.com>
+
+ Fix bug 39218
+
+ * lisp/simple.el (shell-command):
+ Ensure a shell command ending with `&' is run asynchronously.
+
+2020-01-23 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix crash when sending Gnus message (Bug#39207)
+
+ * src/alloc.c (resize_string_data): The string must be multibyte.
+ When not bothering to reallocate, do bother to change the byte count.
+ * test/src/alloc-tests.el (aset-nbytes-change) New test.
+
+2020-01-22 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 3b0938c042 (origin/emacs-27) Render Ido suggestions using an overlay
+ d5d90dc412 * doc/misc/tramp.texi (Bug Reports): Encourage use of "ema...
+ ac09e8e121 * lisp/vc/smerge-mode.el (smerge-match-conflict): Fix bug#...
+ 7e37e61f4b Correct statement about ftcr and recommend HarfBuzz
+ 4aec94da37 Avoid leaving artifacts when the system caret is used on w32
+ 5abd8d73b0 Improve display of temporary echo messages
+
+2020-01-22 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 3ba0db41e3 Allow optional truncation of tab names in tab-bar and tab-...
+ 7dd065fc7b Small fixes in documentation.
+ 06166aa719 Improve explanation of available font backends under X
+ 2eb834ead4 Clear output data pointer on NS
+
+2020-01-22 Michael Albinus <michael.albinus@gmx.de>
+
+ Add new Tramp method "media"
+
+ * doc/misc/tramp.texi (Quick Start Guide, GVFS-based methods):
+ Add media devices.
+
+ * etc/NEWS: Mention new Tramp method "media".
+
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-methods): Add "media" method.
+ (tramp-goa-methods): Add tramp-autoload cookie.
+ (tramp-media-methods): New defvar.
+ (tramp-gvfs-service-volumemonitor): New defsubst.
+ (top): Remove media methods if not supported. Add defaults for
+ `tramp-default-host-alist'.
+ (tramp-goa-account): Rename from `tramp-goa-name'. Adapt all callees.
+ (tramp-gvfs-service-afc-volumemonitor)
+ (tramp-gvfs-service-goa-volumemonitor)
+ (tramp-gvfs-service-gphoto2-volumemonitor)
+ (tramp-gvfs-service-mtp-volumemonitor)
+ (tramp-gvfs-path-remotevolumemonitor)
+ (tramp-gvfs-interface-remotevolumemonitor): New defconsts.
+ (tramp-media-device): New defstruct.
+ (tramp-gvfs-activation-uri): New defun.
+ (tramp-gvfs-url-file-name): Use it.
+ (tramp-gvfs-handler-mounted-unmounted)
+ (tramp-gvfs-connection-mounted-p, tramp-gvfs-mount-spec):
+ Handle "media" method.
+ (tramp-get-goa-account): Rename from `tramp-make-goa-name'. Adapt
+ all callees.
+ (tramp-get-goa-accounts): Adapt docstring. Cache with nil key.
+ (tramp-parse-goa-accounts, tramp-get-media-device)
+ (tramp-get-media-devices)
+ (tramp-parse-media-names): New defuns.
+ (top): Rework completion function registration.
+
+ * lisp/net/tramp.el (tramp-dns-sd-service-regexp): New defconst.
+ (tramp-set-completion-function): Use it.
+
+2020-01-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add \sqrt[4] as Latex input method, too
+
+ * lisp/leim/quail/latin-ltx.el: Add \sqrt[4] as input method
+ (bug#25594).
+
+2020-01-22 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Add \sqrt and \sqrt[3] as Latex input methods
+
+ * lisp/leim/quail/latin-ltx.el: Add \sqrt and \sqrt[3] as input
+ methods (bug#25594).
+
+2020-01-22 Nicholas Strauss <nicholas.strauss@gmail.com>
+
+ Support solar and lunar eclipses in Calendar
+
+ * lisp/calendar/lunar.el (eclipse-check): New function to display
+ solar and lunar eclipses (bug#20414).
+ (lunar-phase): Use it.
+ (calendar-lunar-phases): Ditto.
+
+2020-01-22 Helmut Eller <eller.helmut@gmail.com>
+
+ Default lisp-mode to use Common Lisp indentation
+
+ * lisp/emacs-lisp/lisp-mode.el (lisp-mode): Use
+ common-lisp-indent-function instead of lisp-indent-function as
+ Common Lisp is the most common non-Emacs Lisp today (bug#10097).
+
+2020-01-22 Marco Wahl <marcowahlsoft@gmail.com>
+
+ Make find-file-at-point respect port numbers in Tramp file name
+
+ * lisp/ffap.el (ffap-string-at-point-mode-alist): Respect port
+ numbers in files names like /ssh:root@127.0.0.1#2222:/root/ (bug#20412).
+
+2020-01-22 Michael Albinus <michael.albinus@gmx.de>
+
+ Minor cleanup in {autorevert,filenotify,shadowfile}-tests.el
+
+ * test/lisp/autorevert-tests.el (tramp-message-show-message):
+ * test/lisp/shadowfile-tests.el (tramp-message-show-message):
+ * test/lisp/filenotify-tests.el (tramp-message-show-message)
+ Do Not set.
+ (file-notify-test04-autorevert): Inhibit messages.
+
+2020-01-22 Damien Cassou <damien@cassou.me>
+
+ * test/lisp/auth-source-pass-tests.el: Test for multiple ports.
+
+2020-01-21 Andrea Corallo <akrl@sdf.org>
+
+ Extend propagation to a wider set of (non pure) functions
+
+2020-01-21 Robert Pluim <rpluim@gmail.com>
+
+ Recommend use of HarfBuzz
+
+ * etc/NEWS: Add recommendation to use HarfBuzz.
+
+2020-01-21 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/grep.el (grep-read-files-function): New var.
+
+ Also remove redundant :groups while we're here.
+
+ (grep-read-files): Use it instead of a major-mode symbol property.
+ (grep-read-files--default): New function.
+
+ * lisp/dired.el (dired-mode): Use `grep-read-files-function`.
+
+2020-01-21 Robert Pluim <rpluim@gmail.com>
+
+ Add Cairo font backend info
+
+ * etc/NEWS: Add info about which font backends are available under Cairo.
+
+2020-01-20 Andrea Corallo <akrl@sdf.org>
+
+ Clean-up unnecessary member usage
+
+ Do no force speed while running the testsuite
+
+2020-01-20 Andrea Corallo <akrl@sdf.org>
+
+ Always force debug 0 for bootstrap test
+
+ Debug symbols would make it fail otherwise.
+
+2020-01-20 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/international/mule-cmds.el (mule-cmds--prefixed-command-pch): Fix typo
+
+2020-01-20 Eli Zaretskii <eliz@gnu.org>
+
+ Unbreak the MS-Windows build
+
+ * src/w32.c (openat): New function.
+ * src/w32.h (openat): Add prototype.
+
+2020-01-20 Robert Pluim <rpluim@gmail.com>
+
+ Document cairo-related fallout to font-backend settings
+
+ * etc/NEWS: Document some of the possible adjustments required to
+ font settings when using Cairo.
+
+2020-01-20 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 154cd116be (origin/emacs-27) * admin/release-process: Adapt bug numbe...
+ fd19282134 Fix shell-tests failures
+ 891f7de8ed * test/lisp/simple-tests.el: Full path to Emacs binary (bu...
+ 92f30d62c0 * lisp/tab-line.el (tab-line-auto-hscroll): Fix for long t...
+ dde313151d * lisp/menu-bar.el (menu-bar-options-menu): Add desktop-sa...
+ 3543b9fad9 ; Fix a test (Bug#39067)
+ 83f9fe44fa ; * etc/NEWS: Fix typo.
+ 2eb0b7835d Fix shell-command-dont-erase-buffer feature
+ c134978a76 Remove reference to Emacs 19 from FAQ
+ fabf0065c5 Doc fixes in package.el
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-01-20 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ f3d30b5303 Remove some doc references to old Emacs versions
+ 4217bc229b Fix infloop in shell.el
+ 74b151195d Fix erc-notifications-notify for non-PRIVMSGs, broken in l...
+ db4436eaf9 Fix the notification action for PRIVMSG in erc-notificatio...
+ 36a4068105 ERC: New maintainer.
+ 2391d3f45d ; spelling fixes
+ e898442be3 Honor tags-case-fold-search during xref identifier completion
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-01-20 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/progmodes/cc-cmds.el: Don't use local vars as symbols
+
+ (c--call-post-self-insert-hook-more-safely-1): Avoid `add-hook` and
+ `run-hooks` on local vars. Avoid O(n^2) while we're at it.
+
+2020-01-20 Paul Eggert <eggert@cs.ucla.edu>
+
+ Work better if stat etc. are interrupted
+
+ Quit or retry if fstat, lstat, stat or openat fail with EINTR.
+ This should fix some bugs on platforms where accessing files via
+ NFS can fail that way (Bug#9256).
+ * src/dired.c (file_attributes):
+ * src/fileio.c (file_directory_p) [O_PATH]:
+ Use emacs_openat instead of openat.
+ * src/dired.c (file_attributes): Use emacs_fstatat instead of fstatat.
+ * src/fileio.c (barf_or_query_if_file_exists, Frename_file):
+ * src/filelock.c (rename_lock_file):
+ Use emacs_fstatat instead of lstat.
+ * src/fileio.c (file_directory_p, Ffile_regular_p, Ffile_modes)
+ (Ffile_newer_than_file_p, Fverify_visited_file_modtime)
+ (Fset_visited_file_modtime, auto_save_1):
+ * src/lread.c (Fload):
+ * src/sysdep.c (get_current_dir_name_or_unreachable):
+ Use emacs_fstatat instead of stat.
+ * src/sysdep.c (emacs_fstatat, emacs_openat): New functions.
+ (emacs_open): Redo in terms of emacs_open.
+
+2020-01-20 Paul Eggert <eggert@cs.ucla.edu> (tiny change)
+
+ Fix drag and drop from some Qt versions
+
+ * lisp/x-dnd.el (x-dnd-handle-xdnd): Fix XdndDrop time stamp bug.
+ Problem and tiny change reported by Urs Fleisch (Bug#20804).
+
+2020-01-19 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/international/mule-cmds.el (universal-coding-system-argument): Rewrite
+
+ Use the new `prefix-command-*` hooks and functions so it interacts
+ better with other prefix commands (and with itself), and so the
+ pre/post-command-hook and other command-loop operations are performed
+ "normally".
+
+ (mule-cmds--prefixed-command-next-coding-system)
+ (mule-cmds--prefixed-command-last-coding-system): New vars.
+ (mule-cmds--prefixed-command-pch, mule-cmds--prefixed-command-echo)
+ (mule-cmds--prefixed-command-preserve): New functions.
+
+2020-01-19 Stefan Kangas <stefankangas@gmail.com>
+
+ Improve error handling in dired-change-marks
+
+ * lisp/dired.el (dired-change-marks): Signal user-error if mark
+ character is invalid. Catch more invalid characters. (Bug#29842)
+
+2020-01-19 Stefan Kangas <stefankangas@gmail.com>
+
+ Make arguments to dired-chage-marks non-optional
+
+ * lisp/dired.el (dired-change-marks): Make arguments
+ non-optional. (Bug#29842)
+
+2020-01-19 Michael Albinus <michael.albinus@gmx.de>
+
+ Sync with Tramp 2.5.0-pre
+
+ * doc/misc/tramp.texi: Protect Tramp x.y and Emacs x.y by @w{}.
+ (GVFS-based methods): Move "GNOME Online Accounts" index.
+ (Customizing Methods, Android shell setup, File name completion)
+ (Frequently Asked Questions): Fix typos.
+
+ * doc/misc/trampver.texi: Change version to "2.5.0-pre".
+
+ * lisp/net/trampver.el: Change version to "2.5.0-pre".
+ (inhibit-message): Don't declare.
+
+ * lisp/net/tramp.el: Bump version to 2.5.0-pre. Require Emacs 25.1.
+ (tramp-debug-message): Simplify.
+ (tramp-message): Don't use `tramp-message-show-message'.
+ (tramp-with-demoted-errors, with-parsed-tramp-file-name)
+ (with-tramp-file-property, with-tramp-connection-property):
+ Adapt `declare' form.
+ (with-tramp-progress-reporter): Suppress progress reporter when
+ noninteractive.
+ (tramp-completion-mode, tramp-completion-mode-p): Remove.
+
+ * lisp/net/tramp-compat.el (tramp-compat-process-running-p)
+ (format-message): Remove compatibility code.
+ (tramp-compat-directory-name-p)
+ (tramp-compat-tramp-file-name-slots): Remove.
+
+ * lisp/net/tramp.el (tramp-debug-message, tramp-message)
+ (tramp-backtrace, tramp-error, tramp-error-with-buffer)
+ (tramp-user-error, tramp-with-demoted-errors)
+ (tramp-signal-hook-function):
+ * lisp/net/tramp-compat.el (tramp-compat-funcall)
+ * lisp/net/tramp-gvfs.el (tramp-dbus-function):
+ Add `tramp-suppress-trace' property.
+
+ * lisp/net/tramp.el (tramp-get-method-parameter)
+ (tramp-dissect-file-name, tramp-error, tramp-error-with-buffer)
+ (tramp-user-error, with-parsed-tramp-file-name)
+ (with-tramp-progress-reporter, tramp-file-name-handler)
+ (tramp-completion-file-name-handler, tramp-autoload-file-name-handler)
+ (tramp-register-file-name-handlers, tramp-connectable-p)
+ (tramp-handle-file-modes, tramp-handle-file-regular-p)
+ (tramp-handle-file-truename, tramp-handle-insert-directory)
+ (tramp-handle-load, tramp-set-file-uid-gid):
+ * lisp/net/tramp-adb.el (tramp-adb-file-name-handler)
+ (tramp-adb-handle-file-truename, tramp-adb-handle-copy-file)
+ (tramp-adb-handle-rename-file):
+ * lisp/net/tramp-archive.el (with-parsed-tramp-archive-file-name):
+ * lisp/net/tramp-cache.el (tramp-get-file-property, tramp-cache-print):
+ * lisp/net/tramp-compat.el (tramp-compat-process-running-p)
+ (tramp-compat-exec-path):
+ * lisp/net/tramp-gvfs.el (tramp-gvfs-file-name-handler)
+ (tramp-gvfs-dbus-byte-array-to-string)
+ (tramp-gvfs-do-copy-or-rename-file):
+ * lisp/net/tramp-rclone.el (tramp-rclone-file-name-handler)
+ (tramp-rclone-do-copy-or-rename-file):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-file-truename)
+ (tramp-sh-handle-copy-directory, tramp-do-copy-or-rename-file)
+ (tramp-sh-handle-insert-directory, tramp-sh-file-name-handler)
+ (tramp-maybe-open-connection):
+ * lisp/net/tramp-smb.el (tramp-smb-file-name-handler)
+ (tramp-smb-handle-copy-file, tramp-smb-handle-copy-directory)
+ (tramp-smb-handle-copy-file, tramp-smb-handle-insert-directory)
+ (tramp-smb-handle-rename-file, tramp-smb-maybe-open-connection):
+ * lisp/net/tramp-sudoedit.el (tramp-sudoedit-file-name-handler)
+ (tramp-sudoedit-do-copy-or-rename-file)
+ (tramp-sudoedit-handle-file-truename):
+ Use `if-let', `when-let', `directory-name-p', `inhibit-message',
+ `non-essential and `cl-struct-slot-info'. Don't use `seconds-to-time'.
+
+ * test/lisp/net/tramp-archive-tests.el (tramp-message-show-message):
+ Don't set.
+
+ * test/lisp/net/tramp-tests.el (inhibit-message): Don't declare.
+ (tramp-message-show-message): Don't set.
+ (tramp-test06-directory-file-name): Use `non-essential'.
+ (tramp-test10-write-region): Use `inhibit-message'.
+ (tramp-test36-vc-registered): No special handling for old Emacsen.
+ (tramp--test-emacs25-p): Remove.
+ (tramp-test45-unload): Special case of `tramp-completion-mode'.
+
+2020-01-19 Paul Eggert <eggert@cs.ucla.edu>
+
+ Remove Gnulib putenv code
+
+ It’s not needed, since Emacs always uses the system putenv and all
+ platforms have putenv. This improves on the fix for Bug#19874.
+ Suggested by Bruno Haible.
+ * admin/merge-gnulib (GNULIB_MODULES): Remove putenv.
+ * configure.ac: Remove workarounds for Gnulib putenv module.
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+ * lib/putenv.c, m4/putenv.m4: Remove.
+
+2020-01-19 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from Gnulib
+
+ This incorporates:
+ 2020-01-18 Rename ~~gnulib.m4 to zzgnulib.m4
+ 2020-01-18 Fix "m4_require: circular dependency of AC_LANG_COMPILER(C)"
+ 2020-01-18 Ensure Automake does not drop ~~gnulib.m4
+ 2020-01-18 Fix major regression from 2020-01-10
+ * m4/00gnulib.m4, m4/gnulib-common.m4: Copy from Gnulib.
+ * m4/gnulib-comp.m4: Regenerate.
+ * m4/zzgnulib.m4: New file, from Gnulib.
+
+2020-01-19 Rüdiger Sonderfeld <ruediger@c-plusplus.de>
+
+ Add space before message in byte compiler warnings
+
+ According to the GNU coding standards (info "(standards) Errors"):
+ > If you want to mention the column number, use one of these formats:
+ > SOURCE-FILE-NAME:LINENO:COLUMN: MESSAGE
+ > SOURCE-FILE-NAME:LINENO.COLUMN: MESSAGE
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-warning-prefix): Add space
+ before message in byte compiler warnings to comply with the GNU coding
+ standards. (Bug#18969)
+
+2020-01-18 Paul Eggert <eggert@cs.ucla.edu>
+
+ Don’t assume sizeof (size_t) == 4 in allocators
+
+ This removes some old 32-bit assumptions in Emacs allocator tuning,
+ and improves performance of ‘make compile-always’ by about 7% on a
+ couple of 64-bit GNU/Linux platforms I tried it on. It should not
+ affect performance on 32-bit platforms.
+ * src/alloc.c (MALLOC_SIZE_NEAR): New macro.
+ (MALLOC_ALIGNMENT): New constant.
+ (INTERVAL_BLOCK_SIZE, SBLOCK_SIZE, STRING_BLOCK_SIZE): Use the new
+ macro. Make these enum constants since they need not be macros.
+
+2020-01-18 Eric Abrahamsen <eric@ericabrahamsen.net>
+
+ Ensure that gnus-summary-attach-article finds the right articles
+
+ * lisp/gnus/gnus-msg.el (gnus-summary-attach-article): Before
+ iterating over the articles to attach, first close any open
+ article. Using `set-buffer' required `gnus-summary-select-article' to
+ re-set the buffer every time, meaning we never got off the original
+ article.
+
+2020-01-18 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/fns.c (sxhash_obj): Fix crash on sub-char-tables
+
+ Also, look inside overlays, like `internal_equal`.
+
+ (internal_equal): Cosmetic tweak.
+
+2020-01-18 Alan Third <alan@idiocy.org>
+
+ Add ability to find ObjC method names
+
+ * lisp/progmodes/cc-cmds.el (c-defun-name-1): Add Objective-C method
+ name ability.
+
+2020-01-18 Alan Third <alan@idiocy.org>
+
+ Don't error on non-toolkit NS scrollbars (bug#37042)
+
+ * configure.ac (HAVE_NS): Don't error, but warn, on non-toolkit
+ scrollbars.
+
+2020-01-18 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove XEmacs and old Emacs compat code from ebnf2ps.el
+
+ * lisp/progmodes/ebnf2ps.el (ebnf-color-p)
+ (ebnf-style-database): Remove XEmacs and old Emacs compat code.
+
+2020-01-18 Paul Eggert <eggert@cs.ucla.edu>
+
+ Make Faset nonrecursive
+
+ * src/data.c (Faset): Refactor Faset so that it’s not recursive.
+ This helps the compiler and makes the code a bit clearer.
+
+2020-01-18 Paul Eggert <eggert@Penguin.CS.UCLA.EDU>
+
+ Improve performance when a string's byte count changes
+
+ * src/alloc.c (allocate_string_data): Now static.
+ Remove code for when Faset calls this function when S
+ already has data assigned, as that can no longer happen.
+ (resize_string_data): New function, which avoids relocation in
+ more cases than the old code did, by not bothering to relocate
+ when the size changes falls within the alignment slop.
+ * src/data.c (Faset): Use resize_string_data.
+ Change a while to a do-while since it must iterate at least once.
+
+2020-01-18 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove XEmacs compat code from allout.el
+
+ * lisp/allout.el (allout-overlay-preparations)
+ (allout-overlay-interior-modification-handler)
+ (allout-before-change-handler, allout-beginning-of-line)
+ (allout-solicit-alternate-bullet, allout-annotate-hidden)
+ (allout-hide-by-annotation, allout-yank-processing)
+ (allout-flag-region, allout-toggle-subtree-encryption)
+ (allout-mark-marker, allout-substring-no-properties)
+ (allout-select-safe-coding-system)
+ (allout-previous-single-char-property-change)
+ (allout-next-single-char-property-change)
+ (top-level): Remove XEmacs compat code.
+
+2020-01-17 Alan Mackenzie <acm@muc.de>
+
+ Introduce element &error into edebug specification lists for macros
+
+ This fixes bug #37540.
+
+ * lisp/emacs-lisp/edebug.el (top level): New entry for &error in alist used to
+ associate elements with their handling functions.
+ (edebug-match-&error): New function.
+ (nested-backquote-form): Use the new element &error to abort instrumentation
+ on encountering a three deep nesting of backquotes (without intervening
+ commas).
+
+ * doc/lispref/edebug.texi (Specification List): Add an entry for &error.
+
+ * etc/NEWS: Add an entry for &error.
+
+2020-01-17 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 4df0c1c6c4 (origin/emacs-27) ; * src/lread.c (force_new_style_backquo...
+ 069741b2f7 ; * etc/NEWS: Mention latest changes in checkdoc. (Bug#38...
+ a785be29bf Fix wording and punctuation of a recent commit
+ 0d3d3be35c Merge branch 'emacs-27' of git.savannah.gnu.org:/srv/git/e...
+ 5da372e17e ; Minor edit in anti.texi
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-01-17 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 5da372e17e ; Minor edit in anti.texi
+
+2020-01-17 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 8d091f7fc2 ; Fix recent markup change
+ b78426526c ; * lisp/obsolete/vc-arch.el: Add missing "Obsolete-since"...
+ 3fb37dc9a4 ; * lisp/ezimage.el: Fix typo.
+ 778923afe5 Document feature requests in the Emacs manual
+
+2020-01-17 Glenn Morris <rgm@gnu.org>
+
+ * lisp/progmodes/vhdl-mode.el (speedbar-load-hook): Silence compiler.
+
+2020-01-17 Glenn Morris <rgm@gnu.org>
+
+ Make more load-hooks obsolete
+
+ * lisp/align.el (align-load-hook):
+ * lisp/autorevert.el (auto-revert-load-hook):
+ * lisp/bookmark.el (bookmark-load-hook):
+ * lisp/cmuscheme.el (cmuscheme-load-hook):
+ * lisp/dired.el (dired-load-hook):
+ * lisp/expand.el (expand-load-hook):
+ * lisp/ibuffer.el (ibuffer-load-hook):
+ * lisp/msb.el (msb-after-load-hook):
+ * lisp/recentf.el (recentf-load-hook):
+ * lisp/speedbar.el (speedbar-load-hook):
+ * lisp/strokes.el (strokes-load-hook):
+ * lisp/calc/calc.el (calc-load-hook):
+ * lisp/calendar/timeclock.el (timeclock-load-hook):
+ * lisp/emulation/viper-init.el (viper-load-hook):
+ * lisp/progmodes/cwarn.el (cwarn-load-hook):
+ * lisp/progmodes/idlwave.el (idlwave-load-hook):
+ * lisp/progmodes/inf-lisp.el (inferior-lisp-load-hook):
+ * lisp/progmodes/meta-mode.el (meta-mode-load-hook):
+ * lisp/textmodes/reftex-vars.el (reftex-load-hook):
+ * lisp/textmodes/table.el (table-load-hook):
+ * lisp/url/url-vars.el (url-load-hook):
+ * lisp/vc/ediff-init.el (ediff-load-hook):
+ Obsolete for with-eval-after-load.
+
+2020-01-17 Stefan Kangas <stefankangas@gmail.com>
+
+ Make sb-image.el obsolete (Bug#37837)
+
+ * lisp/sb-image.el: Move from here...
+ * lisp/obsolete/sb-image.el: ...to here.
+
+ * lisp/speedbar.el (ezimage): Require instead of 'sb-image'.
+ (speedbar-use-images, speedbar-expand-image-button-alist)
+ (speedbar-insert-image-button-maybe, speedbar-image-dump): Move
+ here from 'sb-image.el'.
+
+2020-01-17 Glenn Morris <rgm@gnu.org>
+
+ * doc/misc/ido.texi (Ignoring): Reword per Texinfo warning.
+
+2020-01-17 Glenn Morris <rgm@gnu.org>
+
+ Replace doc references to load-hooks
+
+ with-eval-after-load is a cleaner, standard feature that works
+ for every file
+ * doc/misc/calc.texi (Hooks):
+ * doc/misc/dired-x.texi (Installation)
+ (Optional Installation File At Point, Omitting Files in Dired)
+ (Omitting Examples, Find File At Point):
+ * doc/misc/ediff.texi (Hooks, Selective Browsing)
+ (Highlighting Difference Regions):
+ * doc/misc/efaq.texi (Disabling backups):
+ * doc/misc/gnus.texi (Startup Variables):
+ * doc/misc/idlwave.texi (Structure Tag Completion, Misc Options):
+ * doc/misc/org.texi (Handling Links):
+ * doc/misc/reftex.texi (Key Bindings, Keymaps and Hooks):
+ * doc/misc/sem-user.texi (Speedbar):
+ * doc/misc/speedbar.texi (Hooks, Minor Display Modes):
+ * doc/misc/viper.texi (Rudimentary Changes):
+ Replace load-hooks with with-eval-after-load
+
+2020-01-17 Glenn Morris <rgm@gnu.org>
+
+ Replace add-hook load-hook with with-eval-after-load
+
+ * lisp/info.el (Info-install-speedbar-variables):
+ * lisp/cedet/ede.el (speedbar):
+ * lisp/cedet/semantic/imenu.el (speedbar):
+ * lisp/emacs-lisp/eieio-opt.el (eieio-class-speedbar-key-map):
+ * lisp/emacs-lisp/eieio-speedbar.el (eieio-speedbar-create):
+ * lisp/erc/erc-speedbar.el (erc-install-speedbar-variables):
+ * lisp/mail/rmail.el (rmail-install-speedbar-variables):
+ * lisp/progmodes/gud.el (gud-install-speedbar-variables):
+ Use with-eval-after-load.
+
+2020-01-17 Glenn Morris <rgm@gnu.org>
+
+ * lisp/obsolete/cust-print.el (print-circle): Doc tweak.
+
+2020-01-17 Glenn Morris <rgm@gnu.org>
+
+ edebug: remove ancient code for ancient XEmacs support libs
+
+ * lisp/emacs-lisp/edebug.el (edebug--require-cl-read): Remove.
+ (edebug-setup-hook, cl-read-load-hooks): Don't modify.
+ (edebug-unload-function): Don't modify cl-read-load-hooks.
+
+2020-01-17 Lin Sun <lin.sun@zoom.us>
+
+ Fix the error message from makefile-move-to-macro
+
+ * lisp/cedet/ede/makefile-edit.el (makefile-macro-file-list):
+ regexp-quote the param in makefile-move-to-macro (Bug#39094).
+
+2020-01-17 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove a FIXME from package.el
+
+ * lisp/emacs-lisp/package.el (package-unpack): Remove FIXME about
+ maybe deleting the package directory. It was decided that this was
+ undesirable. (Bug#7756)
+
+2020-01-17 Stefan Kangas <stefankangas@gmail.com>
+
+ Add index entry "syntax highlighting" to the elisp manual
+
+ * doc/lispref/modes.texi (Font Lock Mode): Add an index entry for
+ "syntax highlighting". (Bug#24827)
+
+2020-01-16 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix hexl jumping to end of file
+
+ Plus some other small fixes nearby.
+ * lisp/hexl.el (hexl-end-of-line): Simplify to match next fix.
+ (hexl-end-of-1k-page, hexl-end-of-512b-page): Use min instead
+ of max. Tiny change by Vladimir Nikishkin (Bug#39131).
+ (hexl-insert-char): Use = instead of eq to compare integers.
+
+2020-01-16 Damien Cassou <damien@cassou.me>
+
+ Add unattended spell-checking to checkdoc
+
+ This commit makes checkdoc capable of spell-checking even when the
+ user isn't using it interactively. When TAKE-NOTES is non-nil,
+ checkdoc will run spell-checking (with ispell) and report spelling
+ mistakes.
+
+ Fixes: (bug#38583).
+
+ * lisp/textmodes/ispell.el (ispell-word): Extract part of it to
+ `ispell--run-on-word`.
+ (ispell--run-on-word): New function, extracted from `ispell-word`.
+ (ispell-error-checking-word): New function.
+ (ispell-correct-p): New function. Use `ispell--run-on-word` and
+ `ispell-error-checking-word`.
+ * lisp/emacs-lisp/checkdoc.el (checkdoc-current-buffer): Pass
+ TAKE-NOTES to `checkdoc-start`.
+ (checkdoc-continue): Pass TAKE-NOTES to `checkdoc-this-string-valid`.
+ (checkdoc-this-string-valid): Add optional argument TAKE-NOTES and
+ pass it to `checkdoc-this-string-valid-engine`.
+ (checkdoc-this-string-valid-engine): Add optional argument TAKE-NOTES
+ and pass it to `checkdoc-ispell-docstring-engine`.
+ (checkdoc-ispell-init): Call `ispell-set-spellchecker-params` and
+ `ispell-accept-buffer-local-defs`. These calls are required to
+ properly use ispell. The problem went unnoticed until now because
+ checkdoc was only using ispell through the high-level command
+ `ispell-word` which takes care of all the initialization for the user.
+ (checkdoc-ispell-docstring-engine): Add optional argument TAKE-NOTES
+ to force reporting of spell-checking errors. Throw error
+ when (checkdoc-ispell-init) fails configuring ispell. Replace a
+ few (if cond nil body) with (unless cond body). Replace (let ((var
+ nil))) with (let (var)). Replace (if (not (eq checkdoc-autofix-flag
+ 'never)) body) with just body because `checkdoc-autofix-flag` is
+ checked at the beginning of the function.
+
+2020-01-16 Stefan Kangas <stefankangas@gmail.com>
+
+ * admin/notes/font-backend: Remove outdated file. (Bug#34663)
+
+ (cherry picked from commit 2be48605c0e31566401853a405dc7ea1892b3ef7)
+
+2020-01-16 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 52080b5778 (origin/emacs-27) * lisp/minibuffer.el (read-file-name-def...
+ e4cec1fd10 ; * etc/NEWS: Fix some file name quotations.
+ 13995f31a2 Make emacs prefer an existing ~/.emacs.d to an existing XD...
+ 91cac24952 ; etc/NEWS minor edits
+ 5505babc07 Describe --with-cairo non-support for bitmapped fonts.
+ caf00066ee Mention GTK font chooser changes in NEWS
+ 23b87db628 ; Unmaintain fortran elisp
+ 3b0d1a50aa f90: handle F2008 module function
+ 55803cc189 Move shell-related menu items to "Shell Commands" submenu ...
+ 2be48605c0 * admin/notes/font-backend: Remove outdated file. (Bug#34663)
+ f07a470124 Declare the ftx font backend driver obsolete
+ 6c08a430fb ; Fix wording of a comment.
+
+ # Conflicts:
+ # admin/notes/font-backend
+ # etc/NEWS
+
+2020-01-16 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove references to obsolete libraries
+
+ * doc/emacs/cmdargs.texi (General Variables):
+ * doc/lispintro/emacs-lisp-intro.texi (Lisp History):
+ * doc/lispref/processes.texi (Network):
+ * doc/misc/gnus-coding.texi (Gnus Coding Style):
+ * doc/misc/gnus.texi (Oort Gnus):
+ * doc/misc/smtpmail.texi (Encryption): Remove references to obsolete
+ libraries. (Bug#37964)
+
+2020-01-16 Simon Josefsson <simon@josefsson.org>
+
+ Add SASL SCRAM-SHA-256 support.
+
+ * lisp/net/sasl.el (sasl-mechanisms): Add SCRAM-SHA-256.
+ (sasl-mechanism-alist): Ditto.
+ * lisp/net/sasl-scram-sha256.el: New file.
+ * test/lisp/net/sasl-scram-rfc-tests.el (sasl-scram-sha-256-test):
+ New function.
+
+2020-01-16 Paul Eggert <eggert@cs.ucla.edu>
+
+ dns-query now represents SOA integers as integers (Bug#38937)
+
+ * lisp/net/dns.el (dns-read-int32): Declare obsolete.
+ Assume bignums.
+ (dns-read-type): Represent SOA integers as integers, not strings.
+
+2020-01-16 Paul Eggert <eggert@cs.ucla.edu>
+
+ Refactor parse-time-string
+
+ * lisp/calendar/parse-time.el (parse-time--rfc-822ish):
+ Remove, and fold its body into its only caller.
+
+2020-01-16 Paul Eggert <eggert@cs.ucla.edu>
+
+ parse-time-string now parses ISO 8601 format strings
+
+ * lisp/calendar/parse-time.el (parse-time-string):
+ Parse strings in ISO 8601 format too (Bug#39001).
+ (parse-time--rfc-822ish): New internal function,
+ containing most of the old parse-time-string implementation.
+ (parse-iso8601-time-string): Simplify, now that
+ parse-time-string groks ISO 8601.
+
+2020-01-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * admin/unidata/unidata-gen.el: Use lexical-binding
+
+ (unidata-prop): Use defstruct to define the 6 accessor functions.
+ (unidata-gen-table-character, unidata-gen-table, unidata-gen-table-name)
+ (unidata-check): Move common code out of `if`.
+ (unidata-word-list-diff, unidata-split-decomposition):
+ Move common code out of `if`; use `push`.
+
+2020-01-15 Stefan Kangas <stefankangas@gmail.com>
+
+ Remove unused ftx font backend driver
+
+ * src/ftxfont.c: Remove file.
+ * admin/notes/font-backend:
+ * configure.ac:
+ * src/Makefile.in:
+ * src/deps.mk (ftxfont.o):
+ * src/font.c (syms_of_font):
+ * src/font.h (top-level, font_property_index):
+ * src/xfns.c (Fx_create_frame, x_create_tip_frame): Remove unused ftx
+ font backend driver. Thanks to Glenn Morris for pointing out that it
+ can be removed. (Bug#34663)
+
+2020-01-15 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 0e936f18f8 (origin/emacs-27) Fix build failure with --with-cairo --wi...
+ c34f7e884b Add new node "Package Statuses" to manual
+ fdee034ac8 * lisp/isearch.el: Fix corner cases of isearch-lazy-count.
+ 7b14329d86 ; * lisp/simple.el (messages-buffer): Doc fix. (Bug#39124)
+ 7ec66a59e3 Document spacing issues with Xft for some fonts
+ 08cd247fbd ; * etc/NEWS: Fix typo.
+ d645628e3c Always use lexical-binding in lisp-interaction-mode (bug#3...
+ c42198f78c ; *etc/NEWS: Fix typo.
+ 0ed9cfa7dc vc-dir: ensure we don't use a pager with git
+ 37e0d00c14 Improve ERC's matching of nicks and URLs (bug#38257)
+ d47b157969 Handle tab-bar clicks on a GPM-capable console.
+ e4791f3f8e ;* etc/TODO: Update.
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-01-15 Andreas Schwab <schwab@linux-m68k.org>
+
+ Fix implicit declaration of getenv and atol
+
+ * src/gtkutil.c: Include <stdlib.h>.
+
+2020-01-14 Michael Albinus <michael.albinus@gmx.de>
+
+ Refactor Tramp async process code
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-make-process):
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process):
+ Update stderr buffer when process has finished. Do not call
+ `auto-revert'.
+
+ * test/lisp/net/tramp-tests.el (tramp-test31-interrupt-process):
+ Tag it :unstable. Change `accept-process-output' arguments.
+ (tramp--test-async-shell-command): New defun.
+ (tramp--test-shell-command-to-string-asynchronously): Use it.
+ (tramp-test32-shell-command): Refactor code.
+
+2020-01-14 Robert Pluim <rpluim@gmail.com>
+
+ Default cairo to enabled
+
+ * configure.ac (USE_CAIRO): Default cairo to enabled.
+
+ * etc/NEWS: Announce the change to use cairo if found.
+
+2020-01-14 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from gnulib
+
+ This incorporates:
+ 2020-01-10 fix major regression from 2020-01-04
+ 2020-01-05 tests: avoid GCC over-optimization
+ 2020-01-04 fix AC_CHECK_DECL so it deactivates clang's built-ins
+ 2020-01-03 getopt-posix: fix compilation failure in testdirs
+ 2020-01-03 doc: mention the 64-bit inode number problem
+ 2020-01-02 wchar: make the HP-UX workaround work on HP-UX 11.31
+ * build-aux/config.guess, build-aux/config.sub, lib/inttypes.in.h:
+ * lib/stdlib.in.h, lib/unistd.in.h, m4/00gnulib.m4, m4/largefile.m4:
+ * m4/unistd_h.m4: Copy from Gnulib
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+
+2020-01-14 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port configure.ac to future Gnulib
+
+ Rewrite an ancient Alpha ELF check to port to a future Gnulib
+ version that may require AC_CHECK_DECL to be set up properly as
+ per the ‘Expanded Before Required’ section of the Autoconf manual
+ Autoconf doesn’t guarantee that AC_CHECK_DECL will work properly
+ if called conditionally (e.g., inside a shell ‘case’ statement)
+ and the condition is false. Problem reported by Bruno Haible in:
+ https://lists.gnu.org/r/bug-gnulib/2020-01/msg00088.html
+ * configure.ac (LD_SWITCH_MACHINE): Migrate ELF check later,
+ when AC_CHECK_DECL is properly set up.
+
+2020-01-13 Philipp Stephani <phst@google.com>
+
+ * src/pdumper.c (dump_vectorlike): Unbreak build after 724af7671590c
+
+2020-01-13 Philipp Stephani <phst@google.com>
+
+ Use decode_string_utf_8 in emacs-module.c.
+
+ Now that decode_string_utf_8 is available, we can use it to signal
+ errors on invalid input.
+
+ * src/coding.c (syms_of_coding): Move Qutf_8_string_p from json.c
+ since it’s now used outside json.c.
+
+ * src/emacs-module.c (module_decode_utf_8): New helper function.
+ (module_make_function, module_copy_string_contents): Use it.
+
+2020-01-12 Andrea Corallo <akrl@sdf.org>
+
+ Split relocated data into two separate arrays
+
+ Rework the functionality of the previous commit to be more efficient.
+
+2020-01-11 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ f0ebd919c1 (origin/emacs-27) ; * doc/lispref/anti.texi (Antinews): Fi...
+ 6f059159ee Update Acknowledgments sections
+ e1262d45f9 Update Antinews in ELisp manual
+ fd8128f0c1 ; Move the description of define-inline to a different nod...
+ 524441d6b3 Improve wording in the ELisp manual
+ 8addfa91c8 Reset to the standard value when reverting session's custo...
+ d6f9b09777 Fix saving multiple themes
+ c556aabde8 Calc: fix interval entry (bug#39040)
+ 91cd3c1372 Fix horizontal line display in Custom buffers
+ 15c8e984ae ; * etc/NEWS: Fix a typo.
+ ff8996a337 flymake: fix typo in variable binding (bug#38752)
+ 16eaaa07e6 ; Minor spelling fixes
+ 5efe795659 Update Antinews in the Emacs manual
+ 5841240295 Use NSNumber instead of BOOL (bug#39047)
+ beec9f64a5 Add comment on fido-mode's file-sorting semantics
+ eb3c6ad325 Consider non-string minibuffer-default in icomplete
+
+ # Conflicts:
+ # etc/NEWS
+
+2020-01-11 Andrea Corallo <akrl@sdf.org>
+
+ Move function reloc data into pure space during bootstrap
+
+2020-01-09 Michael Albinus <michael.albinus@gmx.de>
+
+ Add hexdump/awk file encoding to Tramp. (Bug#35639)
+
+ * lisp/net/tramp-sh.el (tramp-hexdump-encode, tramp-hexdump-awk-encode)
+ (tramp-od-encode, tramp-od-awk-encode): New defconst.
+ (tramp-awk-encode, tramp-awk-decode): Adapt.
+ (tramp-awk-coding-test): Remove.
+ (tramp-remote-coding-commands): Add hexdump/awk encoding. (Bug#35639)
+ (tramp-find-inline-encoding): Adapt handling of awk, hexdump and od.
+ (tramp-get-remote-busybox, tramp-get-remote-awk)
+ (tramp-get-remote-hexdump, tramp-get-remote-od): New defuns.
+
+2020-01-09 Michael Albinus <michael.albinus@gmx.de>
+
+ Remove obsolete thread-alive-p
+
+ * etc/NEWS (thread-alive-p):
+ * lisp/thread.el (thread-alive-p):
+ * src/thread.c (thread-alive-p): Remove.
+
+2020-01-08 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 1fe596d89f (origin/emacs-27) Fix another compilation problem in a bui...
+
+2020-01-08 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 50dc615095 (origin/emacs-27) Fix build without threads
+
+2020-01-08 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 6cd9ccb0a2 (origin/emacs-27) Fix compression of directories in Dired
+ 42329e6d3b ; * etc/NEWS: Review of the whole text.
+ af5709f16b Further enhancement on `tramp-file-local-name'
+ fb432446f5 Objective C Mode imenu: cease recognizing "functions" with...
+ a18373a999 ; * etc/NEWS: Update the text about the XDG_CONFIG_HOME/em...
+ 73fd8a4b53 Fix BSD and macOS builds w.r.t. pthread_setname_np (bug#38...
+ f54b24304d Scale top-left coordinates in display-monitor-attributes-list
+ b46c75b16c xref-matches-in-files: Big Tramp speed-up
+ 883b3490d8 * lisp/net/tramp.el (tramp-file-local-name): Remove `save-...
+ c01f55f126 Fix rendering bug due to unsynchronized cairo surface size...
+ 075f21c0e3 Avoid crash by access to cleared img->pixmap->data/img->ma...
+ 16c6dfb4f1 Avoid assertion violations in very small-height windows
+ 9063124b91 Use pthread_setname_np to set thread name
+
+ # Conflicts:
+ # etc/NEWS
+ # lisp/net/tramp.el
+
+2020-01-07 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix sxhash-equal on bytecodes, markers, etc.
+
+ Problem reported by Pip Cet (Bug#38912#14).
+ * doc/lispref/objects.texi (Equality Predicates):
+ Document better when ‘equal’ looks inside objects.
+ * doc/lispref/windows.texi (Window Configurations):
+ Don’t say that ‘equal’ looks inside window configurations.
+ * etc/NEWS: Mention the change.
+ * src/fns.c (internal_equal):
+ Do not look inside window configurations.
+ (sxhash_obj): Hash markers, byte-code function objects,
+ char-tables, and font objects consistently with Fequal.
+ * src/window.c (compare_window_configurations):
+ Now static. Remove last argument. Caller changed.
+ * test/lisp/ffap-tests.el (ffap-other-window--bug-25352):
+ Use compare-window-configurations, not ‘equal’.
+ * test/src/fns-tests.el (test-sxhash-equal): New test.
+
+2020-01-07 Paul Eggert <eggert@cs.ucla.edu>
+
+ Help the compiler inline sxhash
+
+ * src/fns.c (sxhash_obj): Rename from sxhash and make
+ it static, so that the compiler can inline it better.
+ (sxhash): New function that does not take a depth arg.
+ All callers changed.
+
+2020-01-07 Alan Third <alan@idiocy.org>
+
+ Fix NS frame parameters (bug#39000)
+
+ * src/frame.c (make_frame): Use new system default setting.
+ * src/frame.h (enum ns_appearance_type): Add new system default
+ setting.
+ * src/nsfns.m (Fx_create_frame): Correctly handle Qunbound and support
+ system default appearance.
+ (syms_of_nsfns): Add Qlight.
+ * src/nsterm.h: New method definition.
+ * src/nsterm.m (ns_set_appearance): Correctly handle Qlight and use new
+ setAppearance method.
+ ([EmacsView initFrameFromEmacs:]): Use new setAppearance method.
+ ([EmacsWindow setAppearance]): New method.
+ * doc/lispref/frames.texi (Management Parameters): Document 'light'.
+
+2020-01-07 Michael Albinus <michael.albinus@gmx.de>
+
+ Implement stderr in tramp-adb-handle-make-process
+
+ * lisp/net/tramp-adb.el (tramp-adb-handle-make-process):
+ Implement `stderr'.
+
+ * lisp/net/tramp-sh.el (tramp-sh-handle-make-process):
+ Flush connection properties in time.
+
+ * test/lisp/net/tramp-tests.el (tramp-test30-make-process)
+ (tramp-test32-shell-command): Test asynchronous stderr for tramp-adb.
+
+2020-01-05 Mattias Engdegård <mattiase@acm.org>
+
+ Mark 'catch' and 'condition-case' bytecodes as obsolete
+
+ They have not been generated by the byte-compiler since Emacs 25.
+
+ * lisp/emacs-lisp/bytecomp.el (byte-catch, byte-condition-case):
+ * src/bytecode.c (BYTE_CODES, exec_byte_code):
+ Mark as obsolete (since Emacs 25; they were still generated in 24.4).
+
+2020-01-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Go back to iso-2022-7bit for titdic-cnv.el again
+
+ * admin/notes/unicode: Mention this.
+ * lisp/international/titdic-cnv.el:
+ Go back to iso-2022-7bit for this file, since utf-8-emacs unified
+ characters that tsanq-quick-converter did not want unified.
+ Problem reported by Eli Zaretskii in:
+ https://lists.gnu.org/r/emacs-devel/2020-01/msg00156.html
+
+2020-01-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Merge from origin/emacs-27
+
+ 448df8fec7 Improve doc-strings of 'quit-window' and 'quit-restore-win...
+ 7f01dfca56 Fix MH-E bug #470: Show buffer discards text properties
+ f95a2b8301 Fix some broken conditional forms
+ 28727444f1 Fix a scoping error in tramp-sudoedit.el
+ 6cbdd048bd * lisp/autorevert.el (auto-revert-notify-handler): Fix bra...
+ 076dd1f69a Fix typo in 'window_box_height'
+
+2020-01-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Merge from origin/emacs-27
+
+ 05c5bf4d38 * lisp/net/tramp.el: Fix typos.
+
+2020-01-05 Philipp Stephani <phst@google.com>
+
+ Shorten pointer printing code using a small helper function.
+
+ * src/print.c (print_pointer): New helper function.
+ (print_vectorlike): Use it.
+
+2020-01-05 Philipp Stephani <phst@google.com>
+
+ Also print function data when printing module functions.
+
+ This is especially useful in cases where modules only use a single
+ entry point and use the data to dispatch to the actual function. Such
+ a design is common for languages such as Go and C++.
+
+ * src/emacs-module.c (module_function_data): New function.
+
+ * src/print.c (print_vectorlike): Use it to print module function data
+ if not NULL.
+ (print_object): Adapt size of buffer.
+
+ * test/data/emacs-module/mod-test.c (emacs_module_init): Pass some
+ non-NULL data to ‘mod-test-sum’.
+ (Fmod_test_sum): Check that correct data is passed through.
+
+ * test/src/emacs-module-tests.el (mod-test-sum-test)
+ (module-function-object): Adapt unit tests.
+
+2020-01-05 Mattias Engdegård <mattiase@acm.org>
+
+ Remove generation of old bytecodes for catch/unwind
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile--use-old-handlers)
+ (byte-compile-condition-case, byte-compile-condition-case--old):
+ Remove.
+ (byte-compile-condition-case--new):
+ Rename to byte-compile-condition-case.
+ (byte-compile-catch, byte-compile-unwind-protect):
+ * lisp/emacs-lisp/cconv.el (cconv-convert, cconv-analyze-form):
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker):
+ Simplify.
+
+2020-01-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ * lisp/emacs-lisp/bindat.el: Remove obsolete comment.
+
+ * lisp/arc-mode.el (archive-zip-summarize): Remove unused local.
+
+2020-01-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ Simplify x-dnd.el due to bignums
+
+ * lisp/x-dnd.el (x-dnd-get-drop-x-y, x-dnd-version-from-flags)
+ (x-dnd-more-than-3-from-flags, x-dnd-get-motif-value)
+ (x-dnd-motif-value-to-list): Do not worry about pairs of
+ 16-bit numbers, as the C code no longer generates them;
+ it generates bignums now, when needed on 32-bit platforms.
+
+2020-01-05 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp/gnus/gnus-start.el (gnus-group-change-level): Simplify
+
+ * lisp/gnus/gnus-group.el (gnus-group-unsubscribe-group): Simplify.
+
+2020-01-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix bug in recent allocate_string_data patch
+
+ Reported by Glenn Morris in:
+ https://lists.gnu.org/r/emacs-devel/2020-01/msg00098.html
+ * src/alloc.c (allocate_string_data): If the string is small and
+ there is not enough room in the current block, clear the string if
+ CLEARIT.
+
+2020-01-04 Philipp Stephani <phst@google.com>
+
+ Improve 'noexcept' support in C++17.
+
+ In C++17, 'noexcept' is part of a function type and may be used in
+ typedef declarations, see
+ https://en.cppreference.com/w/cpp/language/noexcept_spec.
+
+ * src/emacs-module.h.in: Mark function pointer type aliases as
+ 'noexcept' in C++17.
+
+2020-01-04 Mattias Engdegård <mattiase@acm.org>
+
+ Generate fewer useless conditionals in cl-loop
+
+ * lisp/emacs-lisp/cl-macs.el (cl--parse-loop-clause):
+ Don't generate a condition if both branches are the same, which
+ is the common case.
+
+2020-01-04 Philipp Stephani <phst@google.com>
+
+ Make module function finalizer test less brittle.
+
+ * test/src/emacs-module-tests.el (module/function-finalizer): Create
+ 100 leaked functions to increase the probability that at least one
+ gets garbage-collected.
+
+2020-01-04 Philipp Stephani <phst@google.com>
+
+ emacs-module.h: Don't generate invalid C++11 code.
+
+ * src/emacs-module.h.in: Remove 'noexcept' from function pointer type
+ aliases. It is illegal there in C++11, see
+ https://en.cppreference.com/w/cpp/language/noexcept_spec.
+
+2020-01-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Let the OS clear new large strings of NUL
+
+ On my platform, this sped up (make-string 4000000000 0) from 2.5
+ to 0.015 seconds (not that people should want to do this much :-).
+ * src/alloc.c (allocate_string_data): New arg CLEARIT.
+ Callers changed.
+ (Fmake_string): Prefer calloc to malloc+memset when allocating a
+ large string of NUL bytes.
+ (make_clear_string): New function.
+ (make_uninit_string): Use it.
+ (make_clear_multibyte_string): New function.
+ (make_uninit_multibyte_string): Use it.
+
+2020-01-03 Glenn Morris <rgm@gnu.org>
+
+ * src/alloc.c (cleanup_vector): Fix --without-modules builds.
+
+2020-01-03 Philipp Stephani <phst@google.com>
+
+ Implement finalizers for module functions (Bug#30373)
+
+ * src/module-env-28.h: Add new module environment functions to
+ module environment for Emacs 28.
+
+ * src/emacs-module.h.in: Document that 'emacs_finalizer' also works
+ for function finalizers.
+
+ * src/emacs-module.c (CHECK_MODULE_FUNCTION): New function.
+ (struct Lisp_Module_Function): Add finalizer data member.
+ (module_make_function): Initialize finalizer.
+ (module_get_function_finalizer)
+ (module_set_function_finalizer): New module environment functions.
+ (module_finalize_function): New function.
+ (initialize_environment): Initialize new environment functions.
+
+ * src/alloc.c (cleanup_vector): Call potential module function
+ finalizer during garbage collection.
+
+ * test/data/emacs-module/mod-test.c (signal_error): New helper
+ function.
+ (memory_full): Use it.
+ (finalizer): New example function finalizer.
+ (Fmod_test_make_function_with_finalizer)
+ (Fmod_test_function_finalizer_calls): New test module functions.
+ (emacs_module_init): Define them.
+
+ * test/src/emacs-module-tests.el (module/function-finalizer): New unit
+ test.
+
+ * doc/lispref/internals.texi (Module Functions): Document new
+ functionality.
+ (Module Misc): Move description of 'emacs_finalizer' type to 'Module
+ Functions' node, and add a reference to it.
+
+ * etc/NEWS: Mention new functionality.
+
+2020-01-03 Andrea Corallo <akrl@sdf.org>
+
+ Simplify configure.ac removing unnecessary empty parameters
+
+ Prevent false warning emission
+
+2020-01-03 Eli Zaretskii <eliz@gnu.org>
+
+ Fix the MS-Windows build broken by "Let the OS clear large new objects"
+
+ * src/w32heap.c (sys_calloc): New function, implements calloc
+ in terms of our private implementations of malloc.
+
+ * nt/inc/ms-w32.h (calloc): Redirect to sys_calloc.
+
+2020-01-03 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 06364316e0 (origin/emacs-27) * lisp/net/tramp.el (tramp-file-local-na...
+ d3884f50e0 Adapt commentary in Tramp persistency file
+ 2d82f5a44e Change Tramp version to 2.4.3.27.1
+ 09b65707cc ; * src/dispnew.c (adjust_glyph_matrix): Fix last change.
+ 37f9182b68 Fix redisplay when mode-line-format changes mode-line's he...
+ 1420906b81 * src/fileio.c (Fwrite_region): Improve the doc string.
+ 01dfcb7c87 Fix removal of frame decorations on Windows (Bug#38705)
+
+2020-01-03 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 071483b6f5 Fix reverting customizations
+ 43203d5068 * lisp/loadup.el: Set max-specpdl-size to 1800 when loading...
+ fab3674b36 Revert "Raise default max-specpdl-size value"
+ 42f66aa502 ; Fix NEWS.24
+ bb9402e6e9 Raise default max-specpdl-size value
+
+2020-01-03 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 138e9051c7 Update distribution documentation
+
+2020-01-03 Mattias Engdegård <mattiase@acm.org>
+
+ * .gitlab-ci.yml (before_script): Install g++ for CEDET tests.
+
+2020-01-03 Paul Eggert <eggert@cs.ucla.edu>
+
+ Let the OS clear large new objects
+
+ Prefer calloc to malloc+memset when allocating large zeroed objects.
+ This avoids page thrashing when (make-vector 1000000000 nil)
+ allocates a large nil vector, as Emacs need not touch the
+ vector’s pages. This wins on platforms like GNU/Linux where
+ calloc can fiddle with page tables to create a block of memory
+ that is lazily zeroed.
+ * src/alloc.c (lisp_malloc, lmalloc, allocate_vectorlike):
+ New arg CLEARIT to tell callee whether to use malloc or calloc.
+ All callers changed.
+ (allocate_clear_vector, allocate_nil_vector): New functions.
+ * src/alloc.c (xzalloc, make_vector):
+ * src/lisp.h (make_nil_vector):
+ Prefer calloc to malloc + memset(...,0,...).
+
+2020-01-02 Andrea Corallo <akrl@sdf.org>
+
+ Extend find-library-suffixes and find-library-name for eln support
+
+ Fix bytecomp message when native compiling
+
+ Do not block sw interrupts in batch mode (don't ignore C-c)
+
+ Better compile-clean and bootstrap-clean target definition
+
+2020-01-01 Eli Zaretskii <eliz@gnu.org>
+
+ Fix compilation with GTK versions older than 3
+
+ * src/xfns.c (x_get_net_workarea): Change a recently moved #ifndef
+ so that GTK builds which need this function will compile it.
+ Reported by John <jpff@codemist.co.uk>.
+
+2020-01-01 Andrea Corallo <akrl@sdf.org>
+
+ Revert "Pacify gcc -Wunused-function on Ubuntu 18.04.3"
+
+ This reverts commit 186152ba400b58d2d278c52d2e3d896decae767e.
+
+2020-01-01 Andrea Corallo <akrl@sdf.org>
+
+ set nativecomp configure option off by default
+
+ make standard emacs compilable again
+
+ check for libgccjit lib to be reachable in configure.ac
+
+ make build system configurable again
+
+ compile each eln to a temporary one and rename it as last
+
+ rework predicates to be homogeneous
+
+ do not crash compilation trying to optimize wrong code
+
+ fix aliased function names trampoline removal
+
+ disable propagation when non locals are present
+
+ rework build system for one pass
+
+ fix nit
+
+ add batch-byte-native-compile-for-bootstrap
+
+ add customize comp-never-optimize-functions
+
+ fix non local propagation handling
+
+ move LATE_RELOCS just before VERY_LATE_RELOCS
+
+ sign and check function link table
+
+ some rework to please --enable-check-lisp-object-type
+
+ rename IMPORTED_FUNC_LINK_TABLE -> FUNC_LINK_TABLE_SYM
+
+ do not force function inlining
+
+ set disassemble buffer in read only
+
+ fix naming for predicate SUBR_NATIVE_COMPILEDP
+
+ adjust max_specpdl_size to sustain bootstrap
+
+ add native support to the build system
+
+ always fill freloc before compiling too
+
+ move late relocs after emacs relocations
+
+ never load a compilation unit without filling the func link table
+
+ add elns to the gitignore
+
+ add batch-native-compile
+
+ mitigate ifdef proliferation
+
+ some style fixes
+
+ add native elisp subr pdumper support
+
+ add native compilation unit pdumper support
+
+ add pdump relocation phases
+
+ some more pdumper integration support
+
+2020-01-01 Andrea Corallo <akrl@sdf.org>
+
+ Revert "split out copy_file_fd"
+
+ This reverts commit 41203ad6abceb6dca39b2dab0adbd8fa711e1f89.
+
+2020-01-01 Andrea Corallo <akrl@sdf.org>
+
+ Revert "use memory mapped file for loading elns"
+
+ This reverts commit 5e07231151ef60a5066617ef6cec7c0077825b1c.
+
+2020-01-01 Andrea Corallo <akrl@sdf.org>
+
+ add initial native compiler pdumper support
+
+ add disassemble support for native compiled functions
+
+ add native-comp-unit-file primitive
+
+ better printing for native compilation unit
+
+ add subr-native-compilation-unit primitive
+
+ fix invalid read in fill_freloc
+
+ add support for native comp unit to type-of
+
+ rationalize load functions
+
+ clean-up unnecessary function prevent_gc
+
+ remove load_handle_stack and use the implementation one
+
+ better compilation unit definition
+
+ some rename on compilation unit struct
+
+ initial gc support
+
+ use memory mapped file for loading elns
+
+ split out copy_file_fd
+
+ introduce SUBRP_NATIVE_COMPILEDP
+
+ make dynlib_close active code
+
+ initial compilation unit as object add
+
+ add basic compilation unit into structure
+
+ better scratch slot support
+
+ fix some nits
+
+ make use of ARRAYELTS macro where possible
+
+2020-01-01 Andrea Corallo <akrl@sdf.org>
+
+ malloc instead of static alloc into emit_ctxt_code
+
+ make it good to be reentrant
+
+2020-01-01 Andrea Corallo <akrl@sdf.org>
+
+ fix comp--register-subr
+
+ remove advice dependency
+
+ clean-up old function relocation code
+
+ reworking relocation mechanism to use one single table
+
+ remove ifdef where unnecessary and add where they are
+
+ stringify within macro ADD_IMPORTED
+
+ use safe alloca in declare_imported_func
+
+ style nit
+
+ single function native compilation doc + interactive support + tests
+
+ add native interactive support test
+
+ add native documentation support test
+
+ native compile interactive functions support
+
+ add int-spec to comp-func
+
+ spill also interactive functions
+
+ renaming comp-decrypt-lambda-list -> comp-decrypt-arg-list
+
+ add native compiled function docstring support
+
+ let intern_c_string works creating with non-pure strings
+
+ better naming variable
+
+ documentation nit
+
+ do not emit elc file while native compiling
+
+ native-compile-async accept list as input
+
+ insert compilation end message at the bottom of the buffer
+
+ fix comp-propagate-insn type propagation
+
+ remove unnecessary return when printing blocks
+
+ gate propagate to comp-speed > 1
+
+ update limple example
+
+ fix wrong enum usage into declare_function
+
+ fix comp-log-edges
+
+ adjust print verbosity according to the doc
+
+ revert unnecessary modifications
+
+ make buffer names constant
+
+ rename native-compile-log-buffer -> comp-log-buffer-name
+
+ do not use thread for async compilation
+
+ update limple comments
+
+ better comp-byte-frame-size
+
+ fix single function top level generation
+
+ add comp-tests-free-fun
+
+ review two slot names in comp-func
+
+ better style into comp-tests-bootstrap
+
+ fix single function compilation
+
+ style fixes into comp.c
+
+ homogeneous setf style
+
+ better loop style into comp-compute-edges
+
+ sanityze orthography in comp.el
+
+ better ert usage into tests
+
+ fix type hints error kind
+
+ error handling rework
+
+ define internal-native-compiler-error as error
+
+ better error handling while loading eln files
+
+ fix symbol_subr + better naming
+
+ comment nit
+
+ fix missing goto into load_comp_unit
+
+ remove unsigned in favor of ptrdiff_t
+
+ remove native-load-history
+
+ fix comp-tests-bootstrap
+
+ fix comp-propagate*
+
+ better comp-function-call-remove
+
+ improve dead assignment
+
+ allow for pure function call removal optimization
+
+ fix jump table emission when test fn is not eq
+
+ some style nits
+
+ add comp-tests-jump-table-2-f
+
+ add comp-tests-signal
+
+ require advice when compiling or loading
+
+ make compilation too robust against advices
+
+ better error signaling while loading
+
+ Vnative_units_loaded -> Vnative_load_history
+
+ remove old eln before creating a new one to prevent crashes
+
+ message when finished compiling
+
+ style nit into load_comp_unit
+
+ add native-units-loaded
+
+ always name the compilation unit responsible for the error
+
+ do not force compiler settings within the testsuite
+
+ fix configure.ac
+
+ emit_limple_push_handler style fix
+
+ rework comp-callref lambda list
+
+ fix emit_limple_call_ref for 0 args case
+
+ add comp-tests-trampoline-removal
+
+ add comp-tests-bootstrap
+
+ fix max depth compilation
+
+ improve subr-native-elisp-p
+
+ do not compile if there's nothing to
+
+ make load mechanism robust against primitives advises
+
+ better error handling into load_comp_unit
+
+ temporary fix subr doc field to zero
+
+2020-01-01 Andrea Corallo <akrl@sdf.org>
+
+ better configure
+
+ check for libgccjit.h file instead of the shared lib in configure
+
+2020-01-01 Andrea Corallo <akrl@sdf.org>
+
+ fix compilation when native compiler is not enabled
+
+ do not compile automatically autoloads
+
+ cleanup unnecessary symbol definition
+
+ propagate load-path into async workers + better messaging
+
+ set intspec to NULL when creating subrs
+
+ make sure to invoke the right emacs when spawning the compiler job
+
+ chasing GNU style
+
+ better FUNCALL1 name
+
+ XFIXNUM return EMACS_INT
+
+ minimal error handling in load_comp_unit
+
+ propagate compiler settings to the async workers
+
+ add native-compile-async
+
+ remove unused variable
+
+ better doc
+
+ compile tests with debug 1
+
+ fix non local mechanism
+
+ better comp-debug customize
+
+ move speed definition into lisp code
+
+ fix two nits
+
+ fix again comp-copy-insn
+
+ fix SIGIO hang after compilation
+
+ fix comp-copy-insn for dotted pairs
+
+ simplify non local exit handler mechanism
+
+ sanity check during eln load
+
+ add pure addr relocation mechanism
+
+ add current thread missing reloc mechanism
+
+ comment unused functions
+
+ two doc nits
+
+ rework log mechanism and trim down verbosity
+
+ have propagate run the correct number of times
+
+ fix ref propagation
+
+ fix missing byte-save-restriction op
+
+ fix ref ssa propagation
+
+ add comp-tests-string-trim
+
+ do not native compile interactive functions
+
+ allow nested loadings
+
+ fix top level macro generation
+
+ add test for macro definition
+
+ test provide
+
+ fix function top_level_run generation
+
+ rework top level environment modification mechanism
+
+ rework comp-spill-lap-functions-file
+
+ add doc slot into comp-func struct
+
+ add top-level-forms slot into comp-ctxt (replace old specific defvar one)
+
+ limplify top level at last
+
+ rework bytecomp spill code
+
+ some code massage
+
+ native compile return the filename of the compilation unit
+
+ fix limplification for functions with more than 8 args
+
+ add a test for functions with more than 8 arguments
+
+ rework limplify to prevent block duplication
+
+ sanity check against block duplication.
+
+ fix comp-emit-narg-prologue
+
+2020-01-01 Andrea Corallo <akrl@sdf.org>
+
+ Revert "simplify comp-limplify-block"
+
+ This reverts commit 31861f63a4b57e69cdcd247e48567242a05bd58e.
+
+2020-01-01 Andrea Corallo <akrl@sdf.org>
+
+ fix invalid write into emit_limple_insn
+
+ fix subr name within comp-limplify-lap-inst
+
+ simplify comp-limplify-block
+
+2020-01-01 Andrea Corallo <akrl@sdf.org>
+
+ better comp-limplify-block
+
+ do not non fall through blocks
+
+2020-01-01 Andrea Corallo <akrl@sdf.org>
+
+ promote a couple of small functions tu subst
+
+ emit TAG number as comment
+
+ make more robust comp-emit-uncond-jump
+
+ fix comp-limplify-block for wrong cl func usage
+
+ fix compilation when modules are enabled
+
+ make non local handler bb generation robust for all order of creation
+
+ some clean-up
+
+ rework emit_limple_insn arg parsing
+
+ add fetch-handler operator
+
+ add autoload
+
+ fix limplification when TAG follow fall through eob
+
+ fix ice logging message
+
+ do not check label stack depth when this is not provided
+
+ fix missing jump into comp-emit-narg-prologue
+
+ fix comp-limplify-block when falling through a return
+
+ log a page break when start compiling
+
+ update emit-handler + rework comp-emit-cond-jump
+
+ fix initial sp value
+
+ remove comp-stack-adjust
+
+ re enable switch support
+
+ reworking comp-limplify-block
+
+ mega loop refactor
+
+ make stack depth computation robust in limplify
+
+ fix initial stack depth
+
+ add stack sanity check
+
+ fix missing fall through handling
+
+ fix label to addr computation
+
+ reworking limplify
+
+ doc fix
+
+ remove unnecessary macros into limplify pass
+
+ fix comp.el compilation warning
+
+ remove nasty nested macro usage in limplify pass
+
+ add comp-test-silly-frame2 to test funcs
+
+ clean-up commented code
+
+ fix frame size computation
+
+ add comp-test-silly-frame to tests
+
+ fix compilation of devar defconst with doc string
+
+ alist-get instead of assoc cdr
+
+ better immediate type propagation
+
+ ignore anonymous forms (they are not functions)
+
+ remove INLINE hints from comp.c
+
+ fix missing direct parameter forwarding into emit_limple_call_ref
+
+ remove unnecessary autostirng usage
+
+ regulate verbosity with comp-verbose
+
+ remove comp-debug
+
+ remove defvar that is not anymore necessary
+
+ don't crash when trying to format a very long string
+
+ always expand file name when bytecompiling
+
+ fix subr-native-elisp-p predicate name
+
+ do not force inlining for func involving ipa-pro
+
+ fix comp.el compilation
+
+ add comp-native-compiling flag
+
+ better description
+
+ initial add for compiler hits
+
+ rework comp-call-optim-form-call
+
+ add type hint to setcar setcdr
+
+ add type hint to car and cdr
+
+ add some call optimizer doc
+
+ use type propagation into add1 sub1 negate
+
+ move gcc_jit_context_dump_reproducer_to_file
+
+ fix missing direct call parsing in comp back-end
+
+ fix push handler propagation
+
+ optimize nil emission
+
+ print object in comment when emitting with emit_const_lisp_obj
+
+ clean ref slot for mvars optimized by comp-call-optim-form-call
+
+ add dead code removal pass
+
+ better note
+
+ repropagate after call-optim
+
+ floating frame in place
+
+ fix nomenclature into declare_function
+
+ clean-up pass mechanism
+
+ rework basic block entry sp emission
+
+ fix comp-new-block-sym
+
+ better comp-func doc
+
+ remove unused field into comp-func
+
+ better doc for comp-func struct
+
+ strengthening comp-compute-edges
+
+ verify to never emit insns into a closed block
+
+ better logging
+
+ rework lap spilling
+
+ better log output
+
+ add missing arguments if missing in comp-call-optim-form-call
+
+ better error signaling when compilation fails
+
+ cleanup unnecessary code and allow inlining at speed 3
+
+ add direct-call direct-callref support into the backend
+
+ extend emit_call to perform direct calls
+
+ split declaration and compilation
+
+ add direct-call direct-callref into frontend
+
+ better naming func_hash -> imported_func_h
+
+ dead code removal
+
+ guard comp-call-optim-form-call for byte compiled callee
+
+ fix compilation for comp.el
+
+ adding comp-call-optim pass
+
+ add native_elisp field into Lisp_Subr
+
+ remove comp-emit-funcall
+
+ add comp-call-optim pass
+
+ add pushhandler to clobber operators
+
+ keep on fixing ssa
+
+ rewriting ssa rename
+
+ give back basic block a C like name
+
+ fix callref parsing into C back-end
+
+ fix comp-compute-edges handling all kind of branches
+
+ add some notes
+
+ fix switch emission due to missing const prop
+
+ modify callref format to explicitate mvars
+
+ adding propagation
+
+ fix again ssa renaming
+
+ add ssa param to comp-new-frame
+
+ clean-up limplify
+
+ fix ssa renaming
+
+ remove incomplete propagation during limplification pass
+
+ add phi finalizer
+
+ add ssa renaming
+
+ core reorder
+
+ add comp-dominator-tree-walker
+
+ place phis
+
+ some code massage + doc into the SSA pass
+
+ add dominator frontiers computation
+
+ compute dominator tree
+
+ ssa and endge number generation with generator
+
+ add edge computation
+
+ rename comp-ctxt-funcs comp-ctxt-exp-funcs
+
+ rework comp-new-frame
+
+ rework basic block creation
+
+ fix missing cl- prefix in comp.el
+
+ style nit
+
+ add test for recursive calls
+
+ fix broken selfcall optimization
+
+ crank optimizations while running native compiler test suite
+
+ pacify gcc and improve sanaity checks
+
+ do not override existing basic blocks when branching backwards!
+
+ add verbosity parameter
+
+ rework log mechanism to work non interactively too
+
+ add sanity check into compile_function
+
+ some error handling in compile_function
+
+ nit into comp-log
+
+ fix pretty printing in native compilation buffer
+
+ add assertion for missing op support
+
+ fix missing specbind import
+
+ add defconst support
+
+ get right dependency during top level form evaluantion
+
+ rename comp-slot-next -> comp-slot+1
+
+ fix varset and add a test
+
+ fix single function compilation
+
+ uncomment back all tests
+
+ fix lambda handling and add a test for that
+
+ rename HAVE_LIBGCCJIT -> HAVE_NATIVE_COMP
+
+ fix build system for native compiler option
+
+ initial top level support (defvar working)
+
+ test separate compile unit
+
+ basic file compilation working
+
+ split final pass + some code rework
+
+ generalize code into comp.el for compile multiple functions
+
+2020-01-01 Andrea Corallo <andrea_corallo@yahoo.it>
+
+ prepare for file compilation
+
+ remove unused helper functions
+
+ use nrevese where necessary
+
+ some order into special vars
+
+ emit fixnum constants as immediates
+
+ fix relocs for all inliners
+
+ update inline emitters
+
+ fix last test broken by reload
+
+ simplify condition in emit_ctxt_code
+
+ need to temporary add a load path
+
+ rename a function test to avoid name clashing
+
+ disable part of comp-tests-ffuncall
+
+ rework static object serialization
+
+ let emit_literal_string_func emit a dbg friendly friendly
+
+ add helper_unwind_protect as runtime imported
+
+ long string literal workaround
+
+ add set_internal as runtime imported
+
+ typo fixes
+
+ add record_unwind_current_buffer as imported
+
+ fix relocation emission into comp.el
+
+ add more runtime helpers
+
+ fix func reloc order emission
+
+ ignore inliners while relocating
+
+ adding runtime relocs
+
+ style fix in emit_limple_push_handler
+
+ always release context even in case of failure
+
+ better messaging when load native elisp
+
+ emit relocs for callref too
+
+ add authorship
+
+ clean-up unnecessary includes
+
+ add NATIVE_ELISP_SUFFIX def into congure.ac
+
+2020-01-01 Andrea Corallo <andrea_corallo@yahoo.it>
+
+ Revert "Make block_atimers unblock_atimers extern"
+
+ This reverts commit 4266794ceb30ba8c3465fb8568695f53b676247d.
+
+2020-01-01 Andrea Corallo <andrea_corallo@yahoo.it>
+
+ Revert "Move native C code into shared library"
+
+ This reverts commit 613f4156880bc6c3d56ebe0297e59f805d2a69ab.
+
+2020-01-01 Andrea Corallo <andrea_corallo@yahoo.it>
+
+ Revert "Create bytecode.h"
+
+ This reverts commit c91954e5bb6365b72ad5654e932bc374a66fb4af.
+
+2020-01-01 Andrea Corallo <andrea_corallo@yahoo.it>
+
+ improve reloc mechanism
+
+ reloc emission mechanism seems ok
+
+ emit function relocation into structure
+
+ some renaming
+
+ seems to emit all relocs
+
+ reloc fist simple func
+
+ emit function relocation name from comp.el
+
+ some clean-up into comp.el
+
+ add and call comp-add-subr-to-relocs
+
+ have subr name in limple
+
+ make use of data relocations
+
+ emit reloc index
+
+ prevent garbage collection
+
+ move away from modules
+
+ basic reload almost working
+
+ add funcs into comp-ctxt
+
+ remove function list form the C compiler ctxt
+
+ fixup data relocs at load time
+
+ emit relocs as text into c code
+
+ improve relocation collection
+
+ rename a bunch o f functions as private
+
+ declare comp-ctxt Vcomp_ctxt
+
+ disable const vect per function
+
+ no need to quote types into structs
+
+ render data_relocs vector
+
+ export native_compiled_emacs_lisp symbol and make it loadable.
+
+ add comp-compile-ctxt-to-file
+
+ some other renaming
+
+ optimize self calls
+
+ some renaming
+
+ code clean-up
+
+ inline setcar setcdr
+
+ fix indent_to
+
+ inline integerp
+
+ inline numberp
+
+ fix preceding-char
+
+ remove duplicate code
+
+ inline negate
+
+ inline car cdr
+
+ inline consp
+
+ inline sub1
+
+ inline add1
+
+ some renaming
+
+ some minors
+
+ improve comp-tests-ffuncall
+
+ C support for new prologue mechanism
+
+ add comp-emit-narg-prologue
+
+ fix &optional args
+
+ rework args structures
+
+ mark todos
+
+ add save-restriction support
+
+ add narrow-to-region + widen support
+
+ add record_unwind_protect_excursion support
+
+ implement log-buffer
+
+ add a test about buffer manipulation
+
+ fix bug for not blanking func_hash after context release
+
+ dipatcher support for helper_unwind_protect record_unwind_current_buffer
+
+ some fixes to unbind_n
+
+ some renaming
+
+ block hash use symbol as key
+
+ save C pointers as mint_ptr type to avoid corruption
+
+ improve routine dispatcher
+
+ change emit_limple_call_ref arg convention
+
+ add routine dispatcher
+
+ fix hash table weakness
+
+ add record_unwind_current_buffer helper_unwind_protect support
+
+ pthread_sigmask instead of unblock_atimers
+
+ clean-up unnecessary declarations
+
+ rework tests
+
+ fix gcc interruption
+
+ fix max_args
+
+ add tromeys tests
+
+ insert page breaks
+
+ add incoming &rest arg support
+
+ add incoming &optional args support
+
+ fix comp-limplify-listn
+
+ add limple switch support
+
+ better make-comp-mvar
+
+ catch works
+
+ pushconditioncase working
+
+ separate basic blocks
+
+ separate code
+
+ rework arg parsing on the C side
+
+ adding non locals
+
+ bubble sort works again
+
+ fix comp-emit-cond-jump
+
+ fix goto
+
+ stackset
+
+ uncomment test
+
+ ops
+
+ uncommenting some test
+
+ Add other ops
+
+ adding ops
+
+ improve comp-op-case again
+
+ add a bunch of ops
+
+ improve comp-op-case
+
+ uncommenting some tests
+
+ better generated code
+
+ adding some ops
+
+ rework comp.el
+
+ fix goto
+
+ add comp-emit-set-call-subr macro
+
+ byte-varbind byte-unbind
+
+ improve comp-c-func-name
+
+ some code massage
+
+ conditionals working
+
+ rename comp-limple-frame comp-limplify
+
+ block to hash
+
+ adding conditionals
+
+ basic funcall
+
+ concat support
+
+ comp-op-case in place plus other rework
+
+ reworking comp.el
+
+ symbol-value +1 test
+
+ add discard aref aset
+
+ let limple support calls with no assignment
+
+ varset support 5 test passing
+
+ some consistency rework one test +
+
+ simplify limple instruction set
+
+ call ref works
+
+ improve function name translation
+
+ fix list
+
+ function name as annotation
+
+ two test passing
+
+ parameter passing works again
+
+ rename entry block
+
+ rework hashtable usage
+
+ proper return in place
+
+ simple call support
+
+ fix function name
+
+ update tests
+
+ wipe out propagation info every new basic block
+
+ introduce FUNCALL1 macro
+
+ first functional function
+
+ basic blocks into C
+
+ block list in limple
+
+ start compilation C side
+
+ comment out unused functions
+
+ add comp-c-func-name
+
+ calling C
+
+ purge C side
+
+ working on
+
+ move out comp-limplify-listn
+
+ clean all crazy macrology in favor of some special var
+
+ add SSA
+
+ some code for const propagation
+
+ add lists car and cdr
+
+ working on
+
+ first limple
+
+ working on comp.el
+
+ spill lap
+
+ add comp.el
+
+ fix jump table
+
+ jump table support
+
+ optimize outgoing native manyarg calls
+
+ rework COMP_DEBUG strategy
+
+ basic &rest working
+
+ add emit_ptr_arithmetic
+
+ extend cast capabilities
+
+ add &rest description
+
+ introduce parsearg
+
+ introduce MAX_POP
+
+ add comp-tests-ffuncall-lambda-f test
+
+ fix native call to MANY func
+
+ fix missing bubble sort test
+
+ add primitive call test
+
+ add emit_assign_to_stack_slot
+
+ optimize primitive native call
+
+ propagate contant types and optimize self calls
+
+ introduce stack_el_t
+
+ pass orig lisp f name into compile_f
+
+ rework emit_cond_jump
+
+ inline setcdr support
+
+ fix setcar
+
+ reworking blocks
+
+ emit comments for inlined functions
+
+ add setcar
+
+ homogeneous emit names
+
+ add define_CHECK_IMPURE
+
+ make use of gcc_jit_context_get_int_type
+
+ adding more types
+
+ rework emit_call_n_ref
+
+ add uintptr_type
+
+ add define_check_type
+
+ inline cdr
+
+ split XCAR
+
+ add car cdr tests
+
+ full inline car
+
+ fix XUNTAG
+
+ add emit_EQ
+
+ add emit_NILP
+
+ add emit_rval_XCONS
+
+ better emit_cast
+
+ define cast union into dedicated function
+
+ reindent define_thread_state_struct
+
+ add XUNTAG
+
+ add char * type support
+
+ better options
+
+ add cons definition
+
+ CASE_CALL_NARGS -> CASE_CALL_N
+
+ remove scratch call mechanism
+
+ locals to array
+
+ bblock -> block
+
+ add format_string
+
+ postfix struct with _s
+
+ add discard macro
+
+ set target stacks for safety
+
+ fix struct thread_state definition
+
+ fix awful pad hack in define_handler_struct
+
+ add non locals tests
+
+ jmp_buf as struct + offset workaround
+
+ fix pushhandler
+
+ dump all ops as comments
+
+ pushhandler
+
+ better emit_lisp_obj_from_ptr
+
+ better logging into emit_scratch_callN
+
+ imrpve macros
+
+ rework debug dump
+
+ name basic blocks
+
+ adding Bpushconditioncase Bpushcatch
+
+ more type definitions
+
+ better macro usage
+
+ use emacs_int
+
+ some renaming convention
+
+ Bcar_safe Bcdr_safe support
+
+ Bstack_set2 support
+
+ Binsert support
+
+ BdiscardN support
+
+ Bnumberp support
+
+ fix consp
+
+ Bintegerp support
+
+ add emit_INTEGERP
+
+ add emit_BIGNUMP
+
+ emit_call funcs return now rval
+
+ helper_PSEUDOVECTOR_TYPEP -> helper_PSEUDOVECTOR_TYPEP_XUNTAG
+
+ fix intern_c_string_1
+
+ better naming ocnvention
+
+ add declare_PSEUDOVECTORP
+
+ XLP XLI l and r values
+
+ rename comp_lisp_obj_from_ptr
+
+ reset compiler context for everi run
+
+ make some order into debug facilities
+
+ add comp_VECTORLIKEP
+
+ adding other ops
+
+ inline consp
+
+ add comp_TAGGEDP
+
+ add bubble sort into to tests
+
+ fix prologue strategy
+
+ improve comp_lisp_obj_as_ptr_from_ptr generated var naming
+
+ add Bstack_set
+
+ add setcar setcdr
+
+ add arithmetic comparisons
+
+ add Bnegate support
+
+ code cleanup
+
+ add Badd1 support
+
+ allow + in lisp functions to be compiled
+
+ add speed parameter
+
+ add sub1
+
+ generate reproducer if needed
+
+ add comp_xfixnum + comp_make_fixnum
+
+ fix uninitialized read
+
+ adding sub1
+
+ remame compiler functions
+
+ move to lispobj as union
+
+ add some new constant
+
+ better errors
+
+ add relative branch ops
+
+ adding conditionals
+
+ add bb computation
+
+ generalize bblocks
+
+ add stuffs
+
+ naming change
+
+ adding more stuffs
+
+ better error msg
+
+ adding stuffs
+
+ precompute nil
+
+ some more ops
+
+ move return into the right place
+
+ replace printfs with proper errors for non supported ops
+
+ add some more ops
+
+ add concat
+
+ store ffuncall with all other functions
+
+ add jit_emit_callN
+
+ rationalize jit_emit_Ffuncall
+
+ some more ops
+
+2020-01-01 Andrea Corallo <andrea_corallo@yahoo.it>
+
+ introduce CASE_CALL_NARGS macro and add various ops
+
+ symbol_function set fset fget fget Bsubstring
+
+2020-01-01 Andrea Corallo <andrea_corallo@yahoo.it>
+
+ add symbol-value
+
+ add aset
+
+ add discard and dup
+
+ Baref
+
+ add Blength
+
+ add void ptr
+
+ generalize lisp call ret type
+
+ add Bunbind
+
+ rename type
+
+ add funcall
+
+ add varbind support
+
+ Add native compiler comp.c
+
+ Make block_atimers unblock_atimers extern
+
+2020-01-01 Tom Tromey <tom@tromey.com>
+
+ Create bytecode.h
+
+ * src/bytecode.h: New file.
+ * src/bytecode.c: Move bytecode definitions to bytecode.h.
+
+2020-01-01 Andrea Corallo <andrea_corallo@yahoo.it>
+
+ Add nativecomp option to configure
+
+ Move native C code into shared library
+
+2020-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Assume C99-style ‘long long’
+
+ Now that Gnulib assumes ‘long long’, it is a good time to clean
+ out old cruft porting to pre-C99 compilers that lack it.
+ * src/data.c (ULL_WIDTH, ULL_MAX): Remove.
+ All uses replaced by ULLONG_WIDTH, ULLONG_MAX.
+ (bits_word_to_host_endian): Assume ‘unsigned long long’.
+ By the way, the old code had a performance typo: it used
+ HAVE_UNSIGNED_LONG_LONG where it should have used
+ HAVE_UNSIGNED_LONG_LONG_INT.
+ * src/sysdep.c (ULLONG_MAX): Remove, as lib/limits.h does this now.
+ (time_from_jiffies) [GNU_LINUX]: Assume ‘long long’.
+
+2020-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Remove files no longer needed from Gnulib
+
+ * m4/count-leading-zeros.m4, m4/count-one-bits.m4:
+ * m4/count-trailing-zeros.m4, m4/longlong.m4:
+ Remove.
+
+2020-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ * etc/NEWS: Update copyright year.
+
+2020-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Update from gnulib
+
+ This incorporates:
+ 2019-12-23 mktime, nstrftime: tweak division performance
+ 2019-12-22 count-leading-zeros: assume 'long long'
+ 2019-12-22 count-one-bits: assume 'long long'
+ 2019-12-22 count-trailing-zeros: assume 'long long'
+ 2019-12-12 inttypes-incomplete: assume 'long long'
+ 2019-12-22 malloca: assume 'long long'
+ 2019-12-22 stdint: assume 'long long'
+ 2019-12-22 strtoll, strtoimax, strtoumax: assume 'long long'
+ 2019-12-22 prefer lib_SOURCES to unconditional AC_LIBOBJ
+ 2019-12-19 nstrftime: avoid a shadowing warning
+ 2019-12-18 improve port of AC_C_RESTRICT to Oracle C++
+ 2019-12-12 stdalign: port to xlclang 16.01
+ 2019-12-11 stddef, unistd: fix compilation error in C++ mode on MSVC
+ 2019-12-08 fix compilation errors in C++ mode on Haiku
+ 2019-12-08 fix compilation errors in 32-bit C++ mode on HP-UX 11/ia64
+ 2019-12-08 fix compilation error in C++ mode on OpenBSD
+ * build-aux/config.guess, doc/misc/texinfo.tex:
+ * lib/count-leading-zeros.h, lib/count-one-bits.h:
+ * lib/count-trailing-zeros.h, lib/inttypes.in.h, lib/malloca.h:
+ * lib/mktime.c, lib/nstrftime.c, lib/signal.in.h, lib/stdalign.in.h:
+ * lib/stddef.in.h, lib/stdint.in.h, lib/stdio.in.h, lib/stdlib.in.h:
+ * lib/strtoimax.c, lib/unistd.in.h, m4/gnulib-common.m4:
+ * m4/inttypes.m4, m4/largefile.m4, m4/malloca.m4, m4/strtoimax.m4:
+ * m4/strtoll.m4:
+ Copy from Gnulib. Also, change copyright notices in some other
+ Gnulib-copied files to exactly match Gnulib, as Gnulib updated
+ them in a trivially different way.
+ * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
+
+2020-01-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Merge from origin/emacs-27
+
+ 186152ba40 Pacify gcc -Wunused-function on Ubuntu 18.04.3
+ 4cd143aded Fix copyright years by hand
+ 365e01cc9f Update copyright year to 2020
+ cd2c156163 ; * etc/NEWS: Make the description of XDG fallback more ac...
+
+ # Conflicts:
+ # etc/NEWS
+ # etc/refcards/ru-refcard.tex
+
+2019-12-31 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 9b6872b4e4 ; * test/lisp/calc/calc-tests.el: Fix warnings
+ 957cdca6f0 Make minibuffer-tests work in out-of-tree builds (bug#38816)
+ 2065316749 Make comint-tests more robust (bug#38813)
+
+2019-12-31 Glenn Morris <rgm@gnu.org>
+
+ * admin/gitmerge.el (gitmerge-skip-regexp): Be more restrictive.
+
+2019-12-30 Michael Albinus <michael.albinus@gmx.de>
+
+ Sync with Tramp 2.4.3
+
+ * doc/misc/trampver.texi:
+ * lisp/net/trampver.el: Change version to "2.4.3".
+
+ * lisp/net/tramp.el: Bump version.
+ (tramp-handle-shell-command): The temp file for error-buffer is remote.
+
+ * test/lisp/net/tramp-tests.el (tramp-test30-make-process):
+ Simplify buffer generation.
+ (tramp-test32-shell-command): Extend test.
+
+ (cherry picked from commit d6922db49dea33ac2bca8b33d24763cc7b2e4cd7)
+
+2019-12-30 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 59f71d20ea (origin/emacs-27) Fix tar-mode reading the oldgnu Tar format
+ e3ec84fd7d Ensure mini-window is resized to show active minibuffer co...
+ 450633f85a Fix mini-window resizing under resize-mini-windows = t
+ 219d47893a (emacs-27) Fixes for makeinfo 4.13
+ 4bbfd2b42f ; fix previous NEWS entry
+ 81b697d106 Fix crash under -nw on macOS properly this time
+ 9ce4207969 Revert "Check for GUI frame in ns_color_index_to_rgba"
+ 732dcfc850 Ignore all color fonts when using XFT
+ aa0c679f48 Avoid unbounded growth of cl-random-state components (bug#...
+
+ # Conflicts:
+ # etc/NEWS
+ # src/nsterm.m
+
+2019-12-30 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 70fe552c61 ; xref-references-in-directory: Autoload as well
+ 181f571651 Fix up requires
+ 43f66c3368 Extract xref-matches-in-files from project--find-regexp-in...
+ 65af18d86e Rename xref-collect-references and xref-collect-matches
+ 98788bf976 ; Improve the docstring some more
+ c190e91a1e Improve docstrings
+ 012c12a05e Fix when expose draws partially visible first glyph (bug#3...
+ d915b8c3f1 Don't require semantic/fw
+ 50a0126402 Do some renames for clarity
+ 74261ff301 Rearrange NEWS, add missing documentation
+ 6c9571379e Fix interactive spec in netrc-parse
+ 32222fb34c Fix documentation of define-obsolete-* functions
+
+ # Conflicts:
+ # etc/NEWS
+
+2019-12-30 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 8224ed7d40 (xref--find-buffer-visiting): Speed up by using get-file-b...
+
+2019-12-28 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix recent gnus-start.el breakage
+
+ * lisp/gnus/gnus-start.el (gnus-group-change-level): Fix previous
+ patch that made info nil when adding new groups (thereby making
+ gnus-newsrc-alist invalid).
+
+ (cherry picked from commit 3434ac67b9ec6b1d19f1c5ebb7d23b0b62dadac9)
+
+2019-12-27 Richard Stallman <rms@gnu.org>
+
+ Display a help text when listing EPA keys
+
+ * lisp/epa.el (epa--list-keys, epa-list-keys): Display a help text
+ that explains what the letters mean.
+
+2019-12-27 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 3f2788d4ac (origin/emacs-27) project--vc-list-files: Recurse into sub...
+ f0da3aa83e Merge branch 'emacs-27' of git.savannah.gnu.org:/srv/git/e...
+ 3b199614cc Minor improvements of buffer documentation
+ e1e0a7a751 xref--collect-matches: Speed up on remote
+ 219b91eb2c ; project--find-regexp-in-files: Avoid prepending remote-i...
+
+2019-12-27 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 8aad80d661 Fix installer build
+ 47a73e3e14 Update Windows build documentation
+ cd55984153 Calc: add missing dynamic variable declarations
+ e8aa6f19e9 * doc/emacs/buffers.texi (Kill Buffer): Improve indexing.
+ ccd7cd2c51 Speed up dired-do-find-regexp
+ 7edb1f0773 ; Remove outdated declarations
+ 6ab40c1a51 ; Clarify the assumption
+ be38e39fcc project--find-regexp-in-files: Support remote files
+ 21c3020fce Document some restrictions for module functions.
+ e1ce9f3423 Don't recommend using 'module-load' for loading modules.
+ 03f962a486 Port x_get_monitor_attributes_fallback to !HAVE_GTK3
+ 0b32f59764 Fix compilation warning in gnus-start.el
+
+2019-12-27 Mattias Engdegård <mattiase@acm.org>
+
+ Deduplicate non-fixnum numeric constants in byte-compilation
+
+ * lisp/emacs-lisp/bytecomp.el (byte-compile-get-constant):
+ Use eql for looking up constants instead of eq, allowing
+ for bignum and flonum deduplication (bug#38708).
+
+2019-12-27 Eli Zaretskii <eliz@gnu.org>
+
+ Fix error message about recursive use of minibuffer
+
+ * src/minibuf.c (read_minibuf): Fix formatting of an error
+ message. Reported by martin rudalics <rudalics@gmx.at>.
+
+2019-12-26 Phillip Lord <phillip.lord@russet.org.uk>
+
+ Update for Emacs-28
+
+ * admin/nt/dist-build/build-dep-zips.py: Emacs major version number.
+
+2019-12-26 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Fix bogus test in body of a while loop
+
+ * lisp/gnus/nnheader.el (nnheader-find-nov-line): Fix return value
+ from while loop.
+
+2019-12-26 Mattias Engdegård <mattiase@acm.org>
+
+ * lisp/net/ldap.el (ldap-search-internal): Add missing setq.
+
+2019-12-26 Mattias Engdegård <mattiase@acm.org>
+
+ Optimise 'while' bodies for effect
+
+ * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker):
+ Treat all expressions in the body of 'while' as for-effect,
+ since their values are discarded. This also finds some errors.
+
+2019-12-26 Mattias Engdegård <mattiase@acm.org>
+
+ Use regexp type for regexps in defcustom declarations
+
+ * lisp/calendar/diary-lib.el (diary-face-attrs):
+ * lisp/cedet/semantic/db-ebrowse.el (semanticdb-ebrowse-file-match):
+ * lisp/cedet/srecode/document.el
+ (srecode-document-autocomment-common-nouns-abbrevs)
+ (srecode-document-autocomment-function-alist)
+ (srecode-document-autocomment-return-first-alist)
+ (srecode-document-autocomment-return-last-alist)
+ (srecode-document-autocomment-param-alist)
+ (srecode-document-autocomment-param-type-alist):
+ * lisp/desktop.el (desktop-clear-preserve-buffers):
+ * lisp/elide-head.el (elide-head-headers-to-hide):
+ * lisp/erc/erc-backend.el (erc-encoding-coding-alist):
+ * lisp/erc/erc-ezbounce.el (erc-ezb-regexp):
+ * lisp/files.el (auto-save-file-name-transforms):
+ * lisp/gnus/deuglify.el (gnus-outlook-deuglify-attrib-cut-regexp)
+ (gnus-outlook-deuglify-attrib-verb-regexp)
+ (gnus-outlook-deuglify-attrib-end-regexp):
+ * lisp/gnus/gnus-fun.el (gnus-x-face-omit-files, gnus-face-omit-files):
+ * lisp/gnus/spam.el (spam-spamassassin-positive-spam-flag-header):
+ * lisp/htmlfontify.el (hfy-src-doc-link-unstyle):
+ * lisp/info-look.el (info-lookup-file-name-alist):
+ * lisp/international/rfc1843.el (rfc1843-newsgroups-regexp):
+ * lisp/mail/feedmail.el (feedmail-queue-slug-suspect-regexp):
+ * lisp/mail/rmail-spam-filter.el (rsf-white-list, rsf-definitions-alist):
+ * lisp/man.el (Man-name-local-regexp):
+ * lisp/net/ange-ftp.el (ange-ftp-dumb-unix-host-regexp):
+ * lisp/net/newst-backend.el (newsticker-auto-mark-filter-list):
+ * lisp/net/rcirc.el (rcirc-authinfo, rcirc-coding-system-alist):
+ * lisp/net/tramp-adb.el (tramp-adb-prompt):
+ * lisp/org/org-agenda.el (org-agenda-hide-tags-regexp)
+ (org-agenda-category-icon-alist):
+ * lisp/org/org-protocol.el (org-protocol-data-separator):
+ * lisp/org/org-table.el (org-table-number-regexp):
+ * lisp/org/ox-latex.el (org-latex-known-warnings):
+ * lisp/progmodes/bug-reference.el (bug-reference-bug-regexp):
+ * lisp/progmodes/hideif.el (hide-ifdef-header-regexp):
+ * lisp/progmodes/idlw-help.el (idlwave-help-doclib-name)
+ (idlwave-help-doclib-keyword):
+ * lisp/progmodes/idlwave.el (idlwave-no-change-comment):
+ * lisp/progmodes/python.el (python-shell-prompt-input-regexps)
+ (python-shell-prompt-output-regexps, python-shell-prompt-regexp)
+ (python-shell-prompt-block-regexp, python-shell-prompt-output-regexp)
+ (python-shell-prompt-pdb-regexp, python-shell-compilation-regexp-alist)
+ (python-pdbtrack-stacktrace-info-regexp):
+ * lisp/progmodes/sql.el (sql-send-terminator, sql-ansi-statement-starters):
+ * lisp/speedbar.el (speedbar-directory-unshown-regexp)
+ (speedbar-file-unshown-regexp):
+ * lisp/textmodes/flyspell.el (flyspell-mark-duplications-exceptions)
+ (flyspell-tex-command-regexp):
+ * lisp/textmodes/paragraphs.el (sentence-end-base):
+ * lisp/textmodes/tildify.el (tildify-pattern, tildify-space-pattern):
+ * lisp/vc/ediff-init.el (ediff-metachars):
+ * lisp/vc/vc-git.el (vc-git-root-log-format):
+ * lisp/vc/vc-hg.el (vc-hg-root-log-format):
+ * lisp/whitespace.el (whitespace-indentation-regexp)
+ (whitespace-space-after-tab-regexp):
+ * lisp/woman.el (woman-manpath-man-regexp)
+ (woman-imenu-generic-expression):
+ Use 'regexp' instead of 'string' as type for values that are regexps
+ in defcustom declarations.
+
+2019-12-26 Philipp Stephani <phst@google.com>
+
+ Simplify an example in the modules manual
+
+ * doc/lispref/internals.texi (Module Misc): Simplify example for how
+ to call 'intern'. There's no need to pass the optional argument
+ explicitly.
+
+2019-12-26 Philipp Stephani <phst@google.com>
+
+ Promote function type aliases to the public module API.
+
+ Previously module authors had to define type aliases for module
+ functions and finalizers themselves. This commit adds and documents
+ aliases so that this is no longer necessary.
+
+ * src/emacs-module.h.in: Add 'emacs_function' and 'emacs_finalizer'
+ type aliases.
+
+ * src/emacs-module.c: Remove old 'emacs_subr' and 'emacs_finalizer'
+ type aliases.
+ (struct Lisp_Module_Function, module_make_function): Switch from
+ 'emacs_subr' to 'emacs_function'.
+
+ * doc/lispref/internals.texi (Module Functions): Document and use
+ 'emacs_function' type alias.
+ (Module Values): Document 'emacs_finalizer' type alias.
+
+ * etc/NEWS: Mention change.
+
+2019-12-25 João Távora <joaotavora@gmail.com>
+
+ Don't always resort in recently introduced icomplete--sorted-completions
+
+ Doing so breaks icomplete-forward-completions and
+ icomplete-backward-completions.
+
+ * lisp/icomplete.el (icomplete--sorted-completions): Don't always
+ resort.
+
+2019-12-25 João Távora <joaotavora@gmail.com>
+
+ Don't force completion recalculation in icomplete-fido-ret
+
+ Besides the adverse effect of delaying completions, it tripped up the
+ useful logic of icomplete-force-complete-and-exit in the case where a
+ default was available, but no completions calculated yet.
+
+ * lisp/icomplete.el (icomplete-fido-ret): Don't force calculation
+ of completions.
+
+2019-12-25 João Távora <joaotavora@gmail.com>
+
+ Correctly cache sorted completions in icomplete--sorted-completions
+
+ * lisp/icomplete.el (icomplete--sorted-completions): Use
+ completion--cache-all-sorted-completions.
+
+2019-12-25 Philipp Stephani <phst@google.com>
+
+ * .gitignore: Ignore .dylib files (shared libraries on macOS)
+
+2019-12-25 Philipp Stephani <phst@google.com>
+
+ Add some documentation for support of .dylib suffix on macOS
+
+ * doc/lispref/loading.texi (Dynamic Modules):
+ * etc/NEWS: Document that dynamic module files on macOS can now have
+ the suffix .dylib.
+
+2019-12-25 Lars Ingebrigtsen <larsi@gnus.org>
+
+ Don't bind XEmacs-only variable in edebug
+
+ * lisp/emacs-lisp/edebug.el (edebug-safe-prin1-to-string): Remove
+ binding of XEmacs-only variable print-readably.
+
+2019-12-25 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ 91c16acbe2 (origin/emacs-27) Improve doc string of 'files--message'
+ c3be58a8f5 (emacs-27) Improve vc--add-line, vc--remove-regexp
+ 9ea9ac9a61 Apply the 'xref-group' property properly
+
+2019-12-25 Glenn Morris <rgm@gnu.org>
+
+ Merge from origin/emacs-27
+
+ ca6a53d3bc Don't default to showing X-Faces externally in Gnus
+ dbf4b5b2d0 Fix manual typo in Special Read Syntax
+ a9fe6dfa90 Fix problem with emacs -nw / eww / svg
+ 0de63092c8 Clarify base64 requirements and say what {en,de}code_codin...
+ 6184aa003f ; * etc/NEWS: Fix boring oddities.
+ 51ea32dd12 * src/emacs-module.h.in: Add reference to manual.
+ 75d0cef20d Trivial docstring fixes
+ ee12c421b6 imagemagick-types needs to initialize ImageMagick
+
+ # Conflicts:
+ # etc/NEWS
+
+2019-12-25 Philipp Stephani <phst@google.com>
+
+ Support .dylib suffix for modules on macOS (Bug#36226).
+
+ On macOS, shared libraries typically have the suffix .dylib. This
+ commit switches the module suffix to .dylib on Darwin to account for
+ that. To also support the .so suffix, introduce the concept of a
+ secondary module suffix.
+
+ * configure.ac: Switch MODULES_SUFFIX to .dylib for Darwin, introduce
+ MODULES_SECONDARY_SUFFIX.
+
+ * src/lread.c (Fload, syms_of_lread): Also use
+ MODULES_SECONDARY_SUFFIX if defined.
+
+ * test/src/emacs-module-tests.el (module-darwin-secondary-suffix): New
+ unit test.
+
+2019-12-24 Federico Tedin <federicotedin@gmail.com>
+
+ Make goto-line keep a separate input history per buffer
+
+ * lisp/simple.el (goto-line-history): New history variable.
+ (goto-line): Use new (buffer-local) variable as input
+ history (Bug#38282).
+ * lisp/subr.el (read-number-history): New history variable.
+ (read-number): Use the new variable as default input history.
+ * doc/lispref/minibuf.texi (Minibuffer History): Document
+ read-number-history and goto-line-history variables.
+ * etc/NEWS: Announce changes.
+
+2019-12-24 João Távora <joaotavora@gmail.com>
+
+ Move flex style's minibuffer-default-aware sorting to lisp/icomplete.el
+
+ This moves the logic from the series of commits starting in the commit named:
+
+ Improve sorting of flex completion style with non-nil minibuffer-default
+
+ to lisp/icomplete.el, so far the only confirmed beneficiary of that
+ functionality.
+
+ * lisp/icomplete.el (icomplete--sorted-completions): Consider
+ minibuffer-default here.
+
+ * lisp/minibuffer.el (completion--flex-adjust-metadata): Simplify.
+
+2019-12-24 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * src/minibuf.c (read_minibuf): Use `user-error`
+
+2019-12-24 Juanma Barranquero <lekktu@gmail.com>
+
+ Don't use `let*' with just one binding
+
+ * lisp/registry.el (registry-reindex):
+ * lisp/emacs-lisp/generator.el (cps--add-state):
+ Use `let', not `let*'.
+
+2019-12-24 Philipp Stephani <phst@google.com>
+
+ Prepare module header generation for Emacs 28.
+
+ * configure.ac: Substitute environment function snippet for Emacs 28.
+
+ * src/module-env-28.h: New file, with dummy contents for now.
+
+ * src/emacs-module.h.in: Provide emacs_env_28 structure.
+
+2019-12-24 Philipp Stephani <phst@google.com>
+
+ * src/emacs-module.h.in: Use @emacs_major_version@ for current env.
+
+2019-12-24 João Távora <joaotavora@gmail.com>
+
+ Make fido-mode behave more like ido-mode when finding directories
+
+ Notably C-x d (M-x dired) and C-x v d (M-x vc-dir) behaved quite
+ differently, having regular files as the default instead of ido's
+ usual "./".
+
+ * lisp/icomplete.el (icomplete--sorted-completions): New helper.
+ (icomplete-completions): Use it.
+
+2019-12-24 João Távora <joaotavora@gmail.com>
+
+ Slightly simplify lisp/icomplete.el with new icomplete--category helper
+
+ * lisp/icomplete.el (icomplete-fido-kill)
+ (icomplete-fido-delete-char, icomplete-fido-ret)
+ (icomplete-fido-backward-updir, icomplete-exhibit): Use
+ icomplete--category.
+ (icomplete--category): New helper.
+
+2019-12-24 João Távora <joaotavora@gmail.com>
+
+ Another adjustment to flex completion style's sorting function
+
+ * lisp/minibuffer.el (completion--flex-adjust-metadata): Adjust
+ case when minibuffer-default is non-nil.
+
+2019-12-23 Philipp Stephani <phst@google.com>
+
+ * src/pdumper.c (Fdump_emacs_portable): Reword error message.
+
+2019-12-23 Philipp Stephani <phst@google.com>
+
+ Remove some undefined behavior related to left shifts.
+
+ Found by UBSan.
+
+ * src/nsfns.m (ns_set_foreground_color, ns_set_background_color):
+ * src/nsimage.m (getPixelAtX:Y:):
+ * src/nsterm.m (ns_color_index_to_rgba): Add explicit casts to avoid
+ undefined behavior when left-shifting beyond the bounds of the int
+ type.
+
+ * src/macfont.m (METRICS_VALUE): Add explicit casts to avoid undefined
+ behavior when left-shifting a negative value.
+
+2019-12-23 Stephen Gildea <stepheng+emacs@gildea.com>
+
+ Further expand coverage of unit tests for time-stamp
+
+ * test/lisp/time-stamp-tests.el (time-stamp-custom-format-tabs-expand,
+ time-stamp-custom-end, time-stamp-helper-string-defaults): New tests.
+ (time-stamp-custom-count): Test 0 case.
+ (time-stamp-format-non-date-conversions): Test different system values.
+
+ Development of these new tests was guided by the "testcover" library.
+
+2019-12-23 Philipp Stephani <phst@google.com>
+
+ Don’t allow portable dumping in interactive mode (Bug#38453).
+
+ * src/pdumper.c (Fdump_emacs_portable): Don’t allow dumping in
+ interactive mode.
+
+2019-12-23 Philipp Stephani <phst@google.com>
+
+ Make argument names in module interface more consistent.
+
+ Previously, the names of arguments and other details were needlessly
+ inconsistent between the documentation, the declarations, and the
+ definitions, as well as between each other. This commit makes them
+ more consistent, in most cases by applying the names from the
+ documentation everywhere.
+
+ * src/module-env-27.h:
+ * src/module-env-25.h:
+ * src/emacs-module.h.in:
+ * src/emacs-module.c (module_get_environment)
+ (module_make_global_ref, module_free_global_ref)
+ (module_non_local_exit_get, module_non_local_exit_signal)
+ (module_make_function, module_funcall, module_type_of)
+ (module_is_not_nil, module_extract_integer)
+ (module_extract_float, module_copy_string_contents)
+ (module_make_string, module_vec_set, module_vec_get)
+ (module_vec_size, module_extract_time)
+ (module_assert_runtime):
+ * doc/lispref/internals.texi (Module Initialization)
+ (Module Functions, Module Values): Make argument names and some other
+ details consistent. No functional changes.
+
+2019-12-23 Eli Zaretskii <eliz@gnu.org>
+
+ Bump Emacs version to 28.0.50
+
+ * README:
+ * configure.ac:
+ * nt/README.W32:
+ * msdos/sed2v2.inp:
+ * src/msdos.c (internal_terminal_init):
+ * etc/refcards/ru-refcard.tex: Bump Emacs version to 28.0.50.
+
+ * lisp/cus-edit.el (customize-changed-options-previous-release):
+ Bump up the value to 26.3.
+
+ * etc/NEWS.27: Renamed from NEWS.
+ * etc/NEWS: New file for Emacs 28.
+
2021-03-25 Eli Zaretskii <eliz@gnu.org>
* Version 27.2 released.
@@ -392,10 +88974,10 @@
Bump Emacs version to 27.1.91
- * README:
- * configure.ac:
- * nt/README.W32:
- * msdos/sed2v2.inp: Bump Emacs version to 27.1.91.
+ * README:
+ * configure.ac:
+ * nt/README.W32:
+ * msdos/sed2v2.inp: Bump Emacs version to 27.1.91.
2021-02-03 Eli Zaretskii <eliz@gnu.org>
@@ -1691,13 +90273,11 @@
2021-02-03 Michael R. Mauger <michael@mauger.com>
- 2020-03-29 Michael R. Mauger <michael@mauger.com>
-
- * lisp/progmodes/sql.el (sql-add-product): Re-correct argument
- spec. Previous change was due to my mistake; I have
- resolved back to the prior behavior (Bug#39960).
- * test/lisp/progmodes/sql-tests.el (sql-test-add-product): Added
- test to insure I don't make the same mistake again.
+ * lisp/progmodes/sql.el (sql-add-product): Re-correct argument
+ spec. Previous change was due to my mistake; I have
+ resolved back to the prior behavior (Bug#39960).
+ * test/lisp/progmodes/sql-tests.el (sql-test-add-product): Added
+ test to insure I don't make the same mistake again.
2021-02-03 Lars Ingebrigtsen <larsi@gnus.org>
@@ -9902,8 +98482,6 @@
2019-11-26 Martin Rudalics <rudalics@gmx.at>
- 2019-11-26 Martin Rudalics <rudalics@gmx.at>
-
* lisp/window.el (switch-to-visible-buffer): Declare obsolete.
(switch-to-prev-buffer-skip): New option.
(switch-to-prev-buffer, switch-to-next-buffer): Obey
@@ -31144,10 +119722,10 @@
* lisp/textmodes/table.el (table-source-languages): Add support
for wiki and mediawiki tables (bug#13287).
- 2019-06-27 Lars Ingebrigtsen <larsi@gnus.org>
+2019-06-27 Lars Ingebrigtsen <larsi@gnus.org>
- * doc/emacs/text.texi (Table Misc): Mention the new wiki and
- mediawiki formats.
+ * doc/emacs/text.texi (Table Misc): Mention the new wiki and
+ mediawiki formats.
2019-06-27 Wilfred Hughes <me@wilfred.me.uk>
@@ -31633,16 +120211,16 @@
Add a new command to report the number and size of the marked files
- 2019-06-25 Constantino Calancha <f92capac@gmail.com>
+2019-06-25 Constantino Calancha <f92capac@gmail.com>
- * lisp/dired.el (dired-mode-map): New keystroke and menu binding
- (bug#22829).
+ * lisp/dired.el (dired-mode-map): New keystroke and menu binding
+ (bug#22829).
- 2019-06-25 Lars Ingebrigtsen <larsi@gnus.org>
+2019-06-25 Lars Ingebrigtsen <larsi@gnus.org>
- * doc/emacs/dired.texi (Marks vs Flags): Document it.
+ * doc/emacs/dired.texi (Marks vs Flags): Document it.
- * lisp/dired.el (dired-number-of-marked-files): New command.
+ * lisp/dired.el (dired-number-of-marked-files): New command.
2019-06-25 Phil Sainty <psainty@orcon.net.nz>
@@ -33355,9 +121933,9 @@
Fix the handling of font backend supersedence on MS-Windows
* src/w32font.c (syms_of_w32font): Don't make the Uniscribe
- font backend "superceded" here, ...
+ font backend "superseded" here, ...
* src/w32uniscribe.c (syms_of_w32uniscribe_for_pdumper):
- ... make it "superceded" here, only if the HarfBuzz DLL was
+ ... make it "superseded" here, only if the HarfBuzz DLL was
successfully loaded. This is because Emacs compiled with
HarfBuzz support might run on a system without the DLL.
* src/w32fns.c (Fx_create_frame, w32_create_tip_frame):
@@ -36913,7 +125491,7 @@
Copy from Gnulib
* m4/gnulib-comp.m4: Regenerate.
- 2019-05-26 Paul Eggert <eggert@cs.ucla.edu>
+2019-05-26 Paul Eggert <eggert@cs.ucla.edu>
Update author/maintainer info
This mostly updates email addresses and fixes spellings of
@@ -36933,7 +125511,7 @@
electric--sort-post-self-insertion-hook.
* lisp/emacs-lisp/syntax.el (syntax-propertize, syntax-ppss):
- Use new `depth` arg to make sure noone accidentally gets added
+ Use new `depth` arg to make sure no one accidentally gets added
after syntax-ppss-flush-cache.
* doc/lispref/modes.texi (Setting Hooks): Document new `depth` arg.
@@ -41572,6 +130150,7 @@
to pacify LeakSanitizer.
2019-04-20 Michael R. Mauger <michael@mauger.com>
+
Fix Bug#35307.
* lisp/progmodes/sql.el(sql-product-alist): Added
@@ -41581,6 +130160,7 @@
adjustments needed for Emacs to support it.
2019-04-20 Michael R. Mauger <michael@mauger.com>
+
Fix Bug#24483.
* lisp/progmodes/sql.el
@@ -45625,7 +134205,8 @@
* lisp/auth-source-pass.el (auth-source-pass-entries):
* lisp/textmodes/artist.el (artist-figlet-get-font-list-windows):
- * lisp/org/ob-abc.el (org-babel-expand-body:abc, org-babel-execute:abc):
+ * lisp/org/ob-abc.el (org-babel-expand-body:abc)
+ (org-babel-execute:abc):
* lisp/org/ob-forth.el (org-babel-forth-session-execute):
* lisp/vc/vc-git.el (vc-git--program-version):
Add backslash in regexp for correctness.
@@ -47056,8 +135637,6 @@
Replace NUL characters when calling into libxml
- 2019-02-27 Robert Pluim <rpluim@gmail.com>
-
* lisp/net/eww.el (eww-display-html): Replace NUL characters with
"\0", as libxml can't handle embedded NULLs. (Bug#34469)
@@ -48398,10 +136977,10 @@
Impl. json-pretty-print with replace-region-contents + minimization
* lisp/json.el (json-pretty-print): Use the new
- replace-region-contents. Add prefix arg for minimzation.
- (json-pretty-print-buffer): Add prefix arg for minimzation.
- (json-pretty-print-buffer-ordered): Add prefix arg for minimzation.
- (json-pretty-print-ordered): Add prefix arg for minimzation.
+ replace-region-contents. Add prefix arg for minimization.
+ (json-pretty-print-buffer): Add prefix arg for minimization.
+ (json-pretty-print-buffer-ordered): Add prefix arg for minimization.
+ (json-pretty-print-ordered): Add prefix arg for minimization.
2019-02-08 Tassilo Horn <tsdh@gnu.org>
@@ -55144,23 +143723,23 @@
Bad assumptions in the `vc-hg-find-file-hook' prevented it from
working. This correctly them. (Bug#33129).
- 2018-10-23 Daniel Pittman <slippycheeze@google.com>
+2018-10-23 Daniel Pittman <slippycheeze@google.com>
- * lisp/vc/vc-hg.el (vc-hg-find-file-hook): This function made two
- assumptions about conflicted files that were not accurate,
- preventing conflicts in files ever being detected.
+ * lisp/vc/vc-hg.el (vc-hg-find-file-hook): This function made two
+ assumptions about conflicted files that were not accurate,
+ preventing conflicts in files ever being detected.
- The first was that the `vc-state' was cache by the time this was
- invoked, which it is not - at least when visiting the file, or
- using `vc-refresh-state'.
+ The first was that the `vc-state' was cache by the time this was
+ invoked, which it is not - at least when visiting the file, or
+ using `vc-refresh-state'.
- The second was that a file with the ".orig" extension would be
- present, next to the file being visited. This is the default
- behavior of Mercurial, but can be overridden by the user.
+ The second was that a file with the ".orig" extension would be
+ present, next to the file being visited. This is the default
+ behavior of Mercurial, but can be overridden by the user.
- Since the VC mode-line code will shortly calculate the state for
- display, the optimization of testing for the ".orig" file only
- delayed this work by a few moments.
+ Since the VC mode-line code will shortly calculate the state for
+ display, the optimization of testing for the ".orig" file only
+ delayed this work by a few moments.
2018-11-02 Stefan Monnier <monnier@iro.umontreal.ca>
@@ -57168,7 +145747,7 @@
* lisp/gnus/nnmaildir.el (nnmaildir-request-accept-article):
Omit leading 0s after "M" in file name.
Problem reported by Glenn Morris in:
- https://lists.gnu.org/r/emacs-devel/2018-09/msg00660.html
+ https://lists.gnu.org/r/emacs-devel/2018-09/msg00660.html
2018-09-15 Paul Eggert <eggert@cs.ucla.edu>
@@ -58138,7 +146717,7 @@
Use bignums when Emacs converts to and from system types like
off_t for file sizes whose values can exceed fixnum range.
- Formerly, Emacs sometimes generted floats and sometimes ad-hoc
+ Formerly, Emacs sometimes generated floats and sometimes ad-hoc
conses of integers. Emacs still accepts floats and conses for
these system types, in case some stray Lisp code is generating
them, though this usage is obsolescent.
@@ -59682,7 +148261,7 @@
(cleanup_vector): Use it. Use if-then-else systematically;
this lets GCC do a bit better job.
- 2018-08-08 Paul Eggert <eggert@cs.ucla.edu>
+2018-08-08 Paul Eggert <eggert@cs.ucla.edu>
* src/alloc.c (VBLOCK_BYTES_MAX): Use vroundup_ct, not
vroundup, so that can be used in static assertions.
@@ -73750,7 +162329,7 @@
1dfc27576a Make pixel-wise scrolling less laggy
f92264fc2a Fix child frame placement issues (bug#29953)
a5f718c4c5 ; * doc/lispref/text.texi (Change Hooks): Fix last change.
- e876f5f9fb Describe the precise interaction of complex primitives wit...
+ e876f5f9fb Describe the precise interaction of complex primitives with...
3a22097cf6 Fix valgrind report in call-interactively
d5f1c87bfe * src/editfns.c (Fsave_excursion): Doc fix. (Bug#30001)
b8d74c4578 Fix mark-defun when there's no spaces between successive d...
@@ -74251,7 +162830,7 @@
13c59d0a83 More improvements for text.texi
7850b7620e Adjudicate review comments for the "Text" chapter of user ...
d7d3b14a99 * lisp/url/url-http.el (url-http-wait-for-headers-change-f...
- f3819ad13e In C-h k <mouse-n>, alert user to existence of any matchin...
+ f3819ad13e In C-h k <mouse-n>, alert user to existence of any matching...
99054fbef9 * net/eww.el (eww): Handle URLs without host part.
de89c0b641 Make C-h c/k S-mouse-1 display message for mouse-appearanc...
720ed0b533 Avoid crashes when ':eval' deletes our frame
@@ -76625,7 +165204,7 @@
completion-all-completions do its work.
(file-cache-minibuffer-complete): Skip `completion-hilit-commonality`
- since `completion-all-completions' already hilighted its output.
+ since `completion-all-completions' already highlighted its output.
Call our setup function directly rather than via `completion-setup-hook`.
(file-cache-buffer): Remove variable.
(file-cache-buffer-default-regexp): Make it a defvar.
@@ -117018,9 +205597,9 @@
auth-source-user-and-password: add forgotten user parameter
- * lisp/auth-source.el (auth-source-user-and-password): Use
- accidentally unused "user" parameter.
- Reported by Oscar Najera <najera.oscar@gmail.com>.
+ * lisp/auth-source.el (auth-source-user-and-password): Use
+ accidentally unused "user" parameter.
+ Reported by Oscar Najera <najera.oscar@gmail.com>.
2017-01-31 Simen Heggestøyl <simenheg@gmail.com>
@@ -122196,7 +210775,7 @@
2012-08-15 Tom Tromey <tromey@redhat.com>
- This parameterizes the GC a bit to make it thread-ready.
+ This parametrizes the GC a bit to make it thread-ready.
The basic idea is that whenever a thread "exits lisp" -- that is,
releases the global lock in favor of another thread -- it must save
@@ -125358,8 +213937,6 @@
Signal file-already-exists if appropriate.
* src/fileio.c (syms_of_fileio): Define file-missing.
- 2016-10-18 Paul Eggert <eggert@cs.ucla.edu>
-
2016-10-21 Mark Oteiza <mvoteiza@udel.edu>
Teach browse-url to open man page urls
@@ -128926,7 +217503,7 @@
a6ae479 Post AppDefined events from the main thread ONLY (bug#23934)
d35d398 Update to the AUTHORS file for Bob Weiner
4d2f4df Revert "Fix local printer set to left aligned string formatter."
- cd1b4d6 Revert "Fix ses-delete-blanks to delete only blanks + documen...
+ cd1b4d6 Revert "Fix ses-delete-blanks to delete only blanks + document...
f7ceb8e Revert "Fix English."
baa7abd Improve doc strings of 'gud-gdb' and 'gdb'
aa4271a Fix doc string of 'minibuffer-message-timeout'
@@ -133272,7 +221849,7 @@
(g_b_init_compare_string_w): Move declaration to file scope.
* src/w32heap.c (dumped_data_commit): Now static.
(FREEABLE_P): Avoid warnings about pointer comparison with integer.
- (mmap_realloc): Cast to 'char *' for arithmetics on void pointers.
+ (mmap_realloc): Cast to 'char *' for arithmetic on void pointers.
* src/w32console.c (ctrl_c_handler, sys_tputs, sys_tgetstr)
(evalcost, cmputc, cmcheckmagic, cmcostinit, cmgoto, Wcm_clear):
Provide prototypes.
@@ -144146,7 +232723,7 @@
Move package test files to new directory.
- * test/lisp/emacs-lisp/package-tests.el: Update resoruce file location.
+ * test/lisp/emacs-lisp/package-tests.el: Update resource file location.
* test/data/package: Moved to test/lisp/emacs-lisp/package-resources
2015-11-24 Phillip Lord <phillip.lord@russet.org.uk>
@@ -144836,9 +233413,7 @@
This file records repository revisions from
commit 9d56a21e6a696ad19ac65c4b405aeca44785884a (exclusive) to
-2021-03-18bd67a4f40a733cb139ace3af4616bc2702282 (inclusive).
-2021-02-03d9244f7cbef9f91e697ad5fc0ce49ec97 (inclusive).
-commit 1ca4da054be7eb340c511d817f3ec89c8b819db7 (inclusive).
+commit 334ff0232e07dad2ff5595b7f85c0f6f5efcb11c (inclusive).
See ChangeLog.2 for earlier changes.
;; Local Variables:
diff --git a/GNUmakefile b/GNUmakefile
index 5155487de28..76fd77ba1b0 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -104,8 +104,13 @@ configure:
Makefile: configure
@echo >&2 'There seems to be no Makefile in this directory.'
+ifeq ($(configure),default)
@echo >&2 'Running ./configure ...'
./configure
+else
+ @echo >&2 'Running ./configure '$(configure)'...'
+ ./configure $(configure)
+endif
@echo >&2 'Makefile built.'
# 'make bootstrap' in a fresh checkout needn't run 'configure' twice.
diff --git a/INSTALL b/INSTALL
index b6f681a153a..21298422af7 100644
--- a/INSTALL
+++ b/INSTALL
@@ -187,6 +187,7 @@ X11 is being used.
X libtiff for TIFF: http://www.simplesystems.org/libtiff/
X libgif for GIF: http://giflib.sourceforge.net/
librsvg2 for SVG: https://wiki.gnome.org/Projects/LibRsvg
+ libwebp for WebP: https://developers.google.com/speed/webp/
If you supply the appropriate --without-LIB option, 'configure' will
omit the corresponding library from Emacs, even if that makes for a
@@ -220,7 +221,7 @@ GNU/Linux distribution that you use, and the options that you want to
configure Emacs with. On Debian-based systems, you can install all the
packages needed to build the installed version of Emacs with a command
like 'apt-get build-dep emacs' (on older systems, replace 'emacs' with
-eg 'emacs25'). On Red Hat-based systems, the corresponding command is
+e.g. 'emacs25'). On Red Hat-based systems, the corresponding command is
'dnf builddep emacs' (on older systems, use 'yum-builddep' instead).
On FreeBSD, the command is 'pkg install -y `pkg rquery %dn emacs-devel`'.
@@ -313,6 +314,7 @@ or more of these options:
--without-gif for GIF image support
--without-png for PNG image support
--without-rsvg for SVG image support
+ --without-webp for WebP image support
Although ImageMagick support is disabled by default due to security
and stability concerns, you can enable it with --with-imagemagick.
@@ -322,8 +324,11 @@ Use --without-toolkit-scroll-bars to disable Motif or Xaw3d scroll bars.
Use --without-xim to inhibit the default use of X Input Methods.
In this case, the X resource useXIM can be used to turn on use of XIM.
-Use --disable-largefile to omit support for files larger than 2GB on
-systems which support that.
+Use --disable-largefile to omit support for files larger than 2GB, and
+--disable-year2038 to omit support for timestamps past the year 2038,
+on systems which allow omitting such support. This may help when
+linking Emacs to a library with an ABI that requires a particular
+width for off_t or for time_t.
Use --without-sound to disable sound support.
diff --git a/INSTALL.REPO b/INSTALL.REPO
index da56d7611b2..182c2e95341 100644
--- a/INSTALL.REPO
+++ b/INSTALL.REPO
@@ -8,9 +8,15 @@ directory on your local machine:
To build the repository code, simply run 'make' in the 'emacs'
directory. This should work if your files are freshly checked out
-from the repository, and if you have the proper tools installed. If
-it doesn't work, or if you have special build requirements, the
-following information may be helpful.
+from the repository, and if you have the proper tools installed; the
+default configuration options will be used. Other configuration
+options can be specified by setting a 'configure' variable, for
+example:
+
+ $ make configure="--prefix=/opt/emacs CFLAGS='-O0 -g3'"
+
+If the above doesn't work, or if you have special build requirements,
+the following information may be helpful.
Building Emacs from the source-code repository requires some tools
that are not needed when building from a release. You will need:
@@ -58,7 +64,16 @@ To update loaddefs.el (and similar files), do:
If either of the above partial procedures fails, try 'make bootstrap'.
If CPU time is not an issue, 'make bootstrap' is a more thorough way
-to rebuild, avoiding spurious problems.
+to rebuild, avoiding spurious problems. 'make bootstrap' rebuilds
+Emacs with the same configuration options as the previous build; it
+can also be used to rebuild Emacs with other configuration options by
+setting a 'configure' variable, for example:
+
+ $ make bootstrap configure="CFLAGS='-O0 -g3'"
+
+To rebuild Emacs with the default configuration options, you can use:
+
+ $ make bootstrap configure=default
Occasionally, there are changes that 'make bootstrap' won't be able to
handle. The most thorough cleaning can be achieved by 'git clean -fdx'
diff --git a/Makefile.in b/Makefile.in
index 235b707673f..202665ea9d0 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -102,6 +102,8 @@ HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@
USE_STARTUP_NOTIFICATION = @USE_STARTUP_NOTIFICATION@
+HAVE_BE_APP = @HAVE_BE_APP@
+
# ==================== Where To Install Things ====================
# Location to install Emacs.app under GNUstep / macOS.
@@ -210,6 +212,9 @@ icondir=$(datarootdir)/icons
# The source directory for the icon files.
iconsrcdir=$(srcdir)/etc/images/icons
+# Where to install the gsettings schema file.
+gsettingsschemadir = @gsettingsschemadir@
+
# ==================== Emacs-specific directories ====================
# These variables hold the values Emacs will actually use. They are
@@ -285,10 +290,16 @@ use_gamedir=$(gameuser)$(gamegroup)
# not use an absolute path. So we must take care to always run
# INSTALL-type commands from the directory containing the Makefile.
# This explains (I think) the cd thisdir seen in several install rules.
+SYSTEM_TYPE = @SYSTEM_TYPE@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_INFO = @INSTALL_INFO@
+ifeq ($(SYSTEM_TYPE),cygwin)
+ INSTALL_ELN = $(INSTALL)
+else
+ INSTALL_ELN = $(INSTALL_DATA)
+endif
# By default, we uphold the dignity of our programs.
INSTALL_STRIP =
MKDIR_P = @MKDIR_P@
@@ -298,6 +309,8 @@ LN_S_FILEONLY = @LN_S_FILEONLY@
# We use gzip to compress installed .el and some .txt files.
GZIP_PROG = @GZIP_PROG@
+GLIB_COMPILE_SCHEMAS = glib-compile-schemas
+
# ============================= Targets ==============================
# Program name transformation.
@@ -307,6 +320,7 @@ TRANSFORM = @program_transform_name@
EMACS_NAME = `echo emacs | sed '$(TRANSFORM)'`
EMACS = ${EMACS_NAME}${EXEEXT}
EMACSFULL = `echo emacs-${version} | sed '$(TRANSFORM)'`${EXEEXT}
+EMACS_PDMP = `./src/emacs${EXEEXT} --fingerprint`.pdmp
# Subdirectories to make recursively.
SUBDIR = $(NTDIR) lib lib-src src lisp
@@ -336,7 +350,9 @@ BIN_DESTDIR='${ns_appbindir}/'
ELN_DESTDIR = ${ns_applibdir}/
endif
-all: ${SUBDIR} info
+gsettings_SCHEMAS = etc/org.gnu.emacs.defaults.gschema.xml
+
+all: ${SUBDIR} info $(gsettings_SCHEMAS:.xml=.valid)
.PHONY: all ${SUBDIR} blessmail epaths-force epaths-force-w32 epaths-force-ns-self-contained etc-emacsver
@@ -418,6 +434,10 @@ epaths-force-ns-self-contained: epaths-force
-e 's;${ns_appdir}/;;') && \
${srcdir}/build-aux/move-if-change epaths.h.$$$$ src/epaths.h
+ifneq ($(NTDIR),)
+$(NTDIR): lib
+endif
+
lib-src src: $(NTDIR) lib
src: lib-src
@@ -488,7 +508,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: 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.
@@ -514,8 +534,14 @@ install-arch-dep: src install-arch-indep install-etcdoc install-$(NTDIR)
$(MAKE) -C lib-src install
ifeq (${ns_self_contained},no)
${INSTALL_PROGRAM} $(INSTALL_STRIP) src/emacs${EXEEXT} "$(DESTDIR)${bindir}/$(EMACSFULL)"
+ifeq (${HAVE_BE_APP},yes)
+ ${INSTALL_PROGRAM} $(INSTALL_STRIP) src/Emacs "$(DESTDIR)${prefix}/apps/Emacs"
+endif
ifeq (${DUMPING},pdumper)
- ${INSTALL_DATA} src/emacs.pdmp "$(DESTDIR)${libexecdir}/emacs/${version}/${configuration}"/emacs.pdmp
+ifeq (${HAVE_BE_APP},yes)
+ ${INSTALL_DATA} src/Emacs.pdmp "$(DESTDIR)${libexecdir}/emacs/${version}/${configuration}"/Emacs.pdmp
+endif
+ ${INSTALL_DATA} src/emacs.pdmp "$(DESTDIR)${libexecdir}/emacs/${version}/${configuration}"/emacs-${EMACS_PDMP}
endif
-chmod 755 "$(DESTDIR)${bindir}/$(EMACSFULL)"
ifndef NO_BIN_LINK
@@ -791,7 +817,7 @@ install-eln: lisp
ifeq ($(HAVE_NATIVE_COMP),yes)
umask 022 ; \
find native-lisp -type d -exec $(MKDIR_P) "$(ELN_DESTDIR){}" \; ; \
- find native-lisp -type f -exec ${INSTALL_DATA} "{}" "$(ELN_DESTDIR){}" \;
+ find native-lisp -type f -exec ${INSTALL_ELN} "{}" "$(ELN_DESTDIR){}" \;
endif
### Build Emacs and install it, stripping binaries while installing them.
@@ -802,7 +828,7 @@ install-strip:
### create (but not the noninstalled files such as 'make all' would create).
###
### Don't delete the lisp and etc directories if they're in the source tree.
-uninstall: uninstall-$(NTDIR) uninstall-doc
+uninstall: uninstall-$(NTDIR) uninstall-doc uninstall-gsettings-schemas
rm -f "$(DESTDIR)$(includedir)/emacs-module.h"
$(MAKE) -C lib-src uninstall
-unset CDPATH; \
@@ -898,7 +924,7 @@ clean_dirs = $(mostlyclean_dirs) nextstep admin/charsets admin/unidata
$(foreach dir,$(clean_dirs),$(eval $(call submake_template,$(dir),clean)))
-clean: $(clean_dirs:=_clean)
+clean: $(clean_dirs:=_clean) clean-gsettings-schemas
-rm -f ./*.tmp etc/*.tmp*
-rm -rf info-dir.*
-rm -rf native-lisp
@@ -1130,14 +1156,23 @@ check-info: info
.PHONY: bootstrap
-# Bootstrapping does the following:
+# Without a 'configure' variable, bootstrapping does the following:
# * Remove files to start from a bootstrap-clean slate.
# * Run autogen.sh.
# * Rebuild Makefile, to update the build procedure itself.
# * Do the actual build.
-bootstrap: bootstrap-clean
+# With a 'configure' variable, bootstrapping does the following:
+# * 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:
+ifndef configure
+ $(MAKE) bootstrap-clean
cd $(srcdir) && ./autogen.sh autoconf
$(MAKE) MAKEFILE_NAME=force-Makefile force-Makefile
+else
+ $(MAKE) extraclean
+endif
$(MAKE) all
.PHONY: ChangeLog change-history change-history-commit change-history-nocommit
@@ -1158,7 +1193,7 @@ ChangeLog:
./$(emacslog) -o $(CHANGELOG) -n $(CHANGELOG_HISTORY_INDEX_MAX)
# Check that we are in a good state for changing history.
-PREFERRED_BRANCH = emacs-27
+PREFERRED_BRANCH = emacs-28
preferred-branch-is-current:
git branch | grep -q '^\* $(PREFERRED_BRANCH)$$'
unchanged-history-files:
@@ -1209,3 +1244,10 @@ gitmerge:
${GITMERGE_EMACS} -batch --no-site-file --no-site-lisp \
-l ${srcdir}/admin/gitmerge.el \
--eval '(setq gitmerge-minimum-missing ${GITMERGE_NMIN})' -f gitmerge
+
+@GSETTINGS_RULES@
+
+install-gsettings-schemas:
+uninstall-gsettings-schemas:
+clean-gsettings-schemas:
+$(gsettings_SCHEMAS:.xml=.valid):
diff --git a/README b/README
index a1d5e2dcef3..6329a7775e9 100644
--- a/README
+++ b/README
@@ -2,7 +2,7 @@ Copyright (C) 2001-2021 Free Software Foundation, Inc.
See the end of the file for license conditions.
-This directory tree holds version 28.0.50 of GNU Emacs, the extensible,
+This directory tree holds version 29.0.50 of GNU Emacs, the extensible,
customizable, self-documenting real-time display editor.
The file INSTALL in this directory says how to build and install GNU
diff --git a/admin/CPP-DEFINES b/admin/CPP-DEFINES
index 68c12438f5a..620ab0bed05 100644
--- a/admin/CPP-DEFINES
+++ b/admin/CPP-DEFINES
@@ -287,6 +287,8 @@ HAVE_UTIMENSAT
HAVE_UTMP_H
HAVE_VFORK
HAVE_VFORK_H
+HAVE_WEBP
+HAVE_SQLITE3
HAVE_WCHAR_H
HAVE_WCHAR_T
HAVE_WINDOW_SYSTEM
diff --git a/admin/MAINTAINERS b/admin/MAINTAINERS
index 02b8cf39bd6..33aeb528651 100644
--- a/admin/MAINTAINERS
+++ b/admin/MAINTAINERS
@@ -138,6 +138,9 @@ Andrea Corallo
lisp/emacs-lisp/comp-cstr.el
test/src/comp-*.el
+Stefan Kangas
+ admin/automerge
+
==============================================================================
2. Areas that someone is willing to maintain, although he would not
necessarily mind if someone else was the official maintainer.
@@ -228,6 +231,7 @@ Michael Albinus
lisp/net/ange-ftp.el
lisp/notifications.el
lisp/shadowfile.el
+ test/infra/*
test/lisp/autorevert-tests.el
test/lisp/files-tests.el (file-name-non-special)
test/lisp/shadowfile-tests.el
diff --git a/admin/README b/admin/README
index 312f09839ea..b0336f91ff2 100644
--- a/admin/README
+++ b/admin/README
@@ -61,8 +61,19 @@ Brief description of sub-directories:
charsets scripts for generating charset map files
in ../etc/charsets
+coccinelle patches to make coccinelle work with
+ the latest Emacs version. Since they
+ apply a few minor changes in Emacs internals
+ in multiple places, they are trivial for
+ copyright purposes.
+grammars wisent and bovine grammars, used to produce
+ files in lisp/cedet/.
+notes miscellaneous notes related to administrative
+ tasks.
+nt support files for administrative tasks related
+ to building MS-Windows distributions.
unidata scripts for generating character property files
- in ../lisp/international
+ in ../lisp/international/.
This file is part of GNU Emacs.
diff --git a/admin/authors.el b/admin/authors.el
index b4e6c934b67..d44bb9bf8e4 100644
--- a/admin/authors.el
+++ b/admin/authors.el
@@ -41,11 +41,16 @@ files.")
(defconst authors-aliases
'(
(nil "A\\. N\\. Other") ; unknown author 2014-12-03, later removed
+ (nil "Anticrisis")
+ (nil "akater")
("Aaron S. Hawley" "Aaron Hawley")
("Alan Third" "Alan J Third")
+ ("Alexander Gramiak" "Alex Gramiak")
("Alexandru Harsanyi" "Alex Harsanyi")
("Álvar Jesús Ibeas Martín" "Álvar Ibeas")
+ ("Andrea Corallo" "AndreaCorallo")
("Andrew Csillag" "Drew Csillag")
+ ("Andrew G Cohen" "Andrew Cohen")
("Anna M. Bigatti" "Anna Bigatti")
("Aurélien Aptel" "Aurelien Aptel")
("Barry A. Warsaw" "Barry A. Warsaw, Century Computing, Inc."
@@ -55,12 +60,14 @@ files.")
("Bill Mann" "William F. Mann")
("Bill Rozas" "Guillermo J. Rozas")
(nil "binjo.cn@gmail.com")
+ (nil "bug-gnu-emacs@gnu.org") ; mistake
("Björn Torkelsson" "Bjorn Torkelsson")
("Brian Fox" "Brian J. Fox")
("Brian P Templeton" "BT Templeton")
("Brian Sniffen" "Brian T. Sniffen")
(nil "castor@my-dejanews")
(nil "chengang31@gmail.com")
+ (nil "chuntaro")
("David Abrahams" "Dave Abrahams")
("David J. Biesack" "David Biesack")
("David De La Harpe Golden" "David Golden")
@@ -70,13 +77,16 @@ files.")
("David M. Koppelman" "David Koppelman")
("David M. Smith" "David Smith" "David M Smith")
("David O'Toole" "David T. O'Toole")
+ (nil "dalanicolai")
(nil "deech@deech")
("Deepak Goel" "D. Goel")
+ ("Earl Hyatt" "Earl" "ej32u@protonmail.com")
("Ed L. Cashin" "Ed L Cashin")
("Edward M. Reingold" "Ed\\(ward\\( M\\)?\\)? Reingold" "Reingold Edward M")
("Emilio C. Lopes" "Emilio Lopes")
("Eric M. Ludlam" "Eric Ludlam")
("Eric S. Raymond" "Eric Raymond")
+ ("Etienne Prud’Homme" "Etienne Prud'Homme")
("Fabián Ezequiel Gallina" "Fabian Ezequiel Gallina" "Fabi.n E\\. Gallina")
(nil "felix.*EmacsWiki")
(nil "foudfou")
@@ -89,26 +99,37 @@ files.")
("Gerd Möllmann" "Gerd Moellmann")
("Hallvard B. Furuseth" "Hallvard B Furuseth" "Hallvard Furuseth")
("Hrvoje Nikšić" "Hrvoje Niksic")
+ ("Ian Dunn" "^Ian D\\>")
;; lisp/org/ChangeLog.1 2010-11-11.
(nil "immerrr")
(nil "aaa bbb")
(nil "Code Extracted") ; lisp/newcomment.el's "Author:" header
+ (nil "jakanakaevangeli")
+ ("J. Alexander Branham" "Alex Branham")
("Jaeyoun Chung" "Jae-youn Chung" "Jae-you Chung" "Chung Jae-youn")
- ("Jan Djärv" "Jan D." "Jan Djarv")
+ ("Jan Djärv" "Jan D\\>" "Jan Djarv")
+ ("João Távora" "João Tãvora")
("Jay K. Adams" "Jay Adams")
+ ("J.D. Smith" "Jd Smith")
("Jérôme Marant" "Jérôme Marant" "Jerome Marant")
+ ("Jens Lechtenbörger" "Jens Lechtenboerger")
("Jens-Ulrik Holger Petersen" "Jens-Ulrik Petersen")
+ ("Jérémie Courrèges-Anglas" "Jeremie Courreges-Anglas")
("Jeremy Bertram Maitin-Shepard" "Jeremy Maitin-Shepard")
+ ("Jérémy Compostella" "Jeremy Compostella")
+ ("Jimmy Aguilar Mena" "Ergus")
("Johan Bockgård" "Johan Bockgard")
("John F. Carr" "John F Carr")
("John J Foerch" "John Foerch")
("John W. Eaton" "John Eaton")
("Jonathan I. Kamens" "Jonathan Kamens")
("Jorgen Schäfer" "Jorgen Schaefer")
+ ("Jose A. Ortega Ruiz" "Jose A Ortega Ruiz")
("Joseph Arceneaux" "Joe Arceneaux")
("Joseph M. Kelsey" "Joe Kelsey") ; FIXME ?
("Juan León Lahoz García" "Juan-Leon Lahoz Garcia")
("Jürgen Hötzel" "Juergen Hoetzel")
+ (nil "k3tu0isui")
("K. Shane Hartman" "Shane Hartman")
("Kai Großjohann" "Kai Grossjohann")
("Karl Berry" "K. Berry")
@@ -126,9 +147,12 @@ files.")
("Mark D. Baushke" "Mark D Baushke")
("Mark E. Shoulson" "Mark Shoulson")
("Marko Kohtala" "Kohtala Marko")
+ ("Maxim Nikulin" "Max Nikulin")
("Agustín Martín" "Agustin Martin" "Agustín Martín Domingo")
("Martin Lorentzon" "Martin Lorentzson")
("Matt Swift" "Matthew Swift")
+ ("Mattias Engdegård" "Mattias Engdegard")
+ (nil "^Madhu")
(nil "mu@magi.net.ru")
("Maxime Edouard Robert Froumentin" "Max Froumentin")
("Michael R. Mauger" "Michael Mauger")
@@ -137,11 +161,13 @@ files.")
("Michael I. Bushnell" "Michael I Bushnell" "Michael I. Bushnell, p/BSG")
("Michael R. Cook" "Michael Cook")
("Michael Sperber" "Mike Sperber" "Michael Sperber \\[Mr. Preprocessor\\]")
+ ("Michalis V" "^mvar")
("Mikio Nakajima" "Nakajima Mikio")
("Nelson Jose dos Santos Ferreira" "Nelson Ferreira")
("Noorul Islam" "Noorul Islam K M")
;;; ("Tetsurou Okazaki" "OKAZAKI Tetsurou") ; FIXME?
("Óscar Fuentes" "Oscar Fuentes")
+ (nil "pillule")
(nil "psyberbits@gmail.com")
("Paul Eggert" "Paul R\\. Eggert")
("Pavel Janík" "Pavel Janík Ml." "Pavel Janik Ml." "Pavel Janik")
@@ -151,8 +177,10 @@ files.")
("Peter J. Weisberg" "PJ Weisberg")
("Peter S. Galbraith" "Peter S Galbraith" "Peter Galbraith")
("Peter Runestig" "Peter 'luna' Runestig")
+ ("Philip Kaludercic" "Philip K\\." "Philip K")
("Philipp Stephani" "Philipp .*phst@google")
("Piotr Zieliński" "Piotr Zielinski")
+ ("Po Lu" "Po Lu Via") ; looks like a mistake
("Przemysław Wojnowski" "Przemyslaw Wojnowski")
("R. Bernstein" "rb@dustyfeet.com")
("Rainer Schöpf" "Rainer Schoepf")
@@ -187,6 +215,7 @@ files.")
("Takaaki Ota" "Tak Ota")
("Takahashi Naoto" "Naoto Takahashi")
("Teodor Zlatanov" "Ted Zlatanov")
+ (nil "^TEC")
(nil "The PCL-CVS Trust")
("Thomas Dye" "Tom Dye")
("Thomas Horsley" "Tom Horsley") ; FIXME ?
@@ -323,11 +352,12 @@ Changes to files matching one of the regexps in this list are not listed.")
"NEWS.unicode" "COPYING.DJ" "Makefile.old" "Makefile.am"
"NEWS.1" "OOOOONEWS...OONEWS" "OOOONEWS" "etc/NEWS"
"NEWS.1-17" "NEWS.18" "NEWS.19" "NEWS.20" "NEWS.21" "NEWS.22"
- "MAINTAINERS" "MH-E-NEWS"
+ "NEWS.23" "NEWS.24" "NEWS.25" "NEWS.26" "NEWS.27" "NEWS.28"
+ "MAINTAINERS" "ERC-NEWS" "MH-E-NEWS" "NXML-NEWS"
"install.sh" "install-sh" "missing" "mkinstalldirs"
"termcap.dat" "termcap.src" "termcap.ucb" "termcap"
"ChangeLog.nextstep" "Emacs.clr" "spec.txt"
- "gfdl.1"
+ "gfdl.1" "ledit.l"
"texi/Makefile.in"
"autodeps.mk"
"lwlib/autodeps.mk"
@@ -349,6 +379,8 @@ Changes to files matching one of the regexps in this list are not listed.")
"cedet/tests/test.py"
"cedet/tests/teststruct.cpp"
"subdirs.el"
+ "etc/facemenu-removal.txt"
+ "src/bytecode.h"
"*.el"
;; Autogen:
"cus-load.el" "finder-inf.el" "ldefs-boot.el" "loaddefs-boot.el"
@@ -359,9 +391,19 @@ Changes to files matching one of the regexps in this list are not listed.")
"autogen/missing" "autogen"
"autogen/copy_autogen" ; not generated, but trivial and now removed
"dir_top"
+ ;; Imported into Emacs but externally maintained.
+ "publicsuffix.txt" "SKK-JISYO.L"
;; Only existed briefly, then renamed:
"images/icons/allout-widgets-dark-bg"
"images/icons/allout-widgets-light-bg"
+ "lisp/shorthand.el"
+ "test/lisp/shorthand-tests.el"
+ "lisp/shorthands.el"
+ "test/src/comp-test-funcs.el"
+ "lisp/net/link.el"
+ "lisp/net/connection.el"
+ "lisp/net/dictionary-link.el"
+ "test/src/comp-test-funcs-dyn.el"
;; Never had any meaningful changes logged, now deleted:
"lib/stdarg.in.h" "lib/stdbool.in.h"
"unidata/bidimirror.awk" "unidata/biditype.awk"
@@ -421,6 +463,10 @@ Changes to files matching one of the regexps in this list are not listed.")
"info/dir"
;; Not in gnulib anymore
"lib/qset-acl.c" "lib/qcopy-acl.c" "lib/file-has-acl.c" "lib/secure_getenv.c"
+ "lib/malloca.c" "lib/malloca.h"
+ ;; Briefly added to repository from gnulib, but not used
+ "lib/localtime-buffer.c"
+ "lib/localtime-buffer.h"
;; files from old MS Windows build procedures
"nt/gnulib-modules-to-delete.cfg"
"makefile.w32-in"
@@ -465,6 +511,9 @@ Changes to files matching one of the regexps in this list are not listed.")
"WHY-FREE"
"MORE.STUFF"
"notes/font-backend"
+ "src/ftxfont.c"
+ "src/ptr-bounds.h"
+ "obsolete/options.el"
;; ada-mode has been deleted, now in GNU ELPA
"ada-mode.texi"
"doc/misc/ada-mode.texi"
@@ -482,6 +531,18 @@ Changes to files matching one of the regexps in this list are not listed.")
"src/mini-gmp-emacs.c"
"lib/dosname.h"
"lib/putenv.c"
+ ;; Moved to the org-contrib repo
+ "ob-asymptote.el"
+ "ob-shen.el"
+ "ob-picolisp.el"
+ "ob-io.el"
+ "ob-mscgen.el"
+ "ob-ledger.el"
+ "lisp/org/ob-abc.el"
+ "lisp/org/ob-ebnf.el"
+ "lisp/org/ob-J.el"
+ ;; Removed -- for now.
+ "test/src/doc-tests.el"
)
"List of files and directories to ignore.
Changes to files in this list are not listed.")
@@ -944,6 +1005,7 @@ in the repository.")
("DIFF" . "OTHER.EMACSES")
("CCADIFF" . "OTHER.EMACSES")
("GOSDIFF" . "OTHER.EMACSES")
+ ("emacs.appdata.xml" . "emacs.metainfo.xml")
;; Nextstep
("nextstep/Cocoa/Emacs.base/Contents/Info.plist" . "nextstep/templates/Info.plist.in")
;; Moved from lisp/tpu-doc.el to etc/tpu-edt.doc in Emacs 19.29.
@@ -998,6 +1060,12 @@ in the repository.")
("lisp/gnus/messcompat.el" . "messcompat.el")
("html2text.el" . "html2text.el")
("lisp/net/html2text.el" . "html2text.el")
+ ;; Obsolete in 28.1.
+ ("inversion.el" . "inversion.el")
+ ("test/lisp/cedet/inversion-tests.el" . "inversion-tests.el")
+ ("test/lisp/mail/rfc2368-tests.el" . "rfc2368-tests.el")
+ ;; This file was briefly obsolete:
+ ("lisp/obsolete/erc-compat.el" . "erc-compat.el")
;; From lisp to etc/forms.
("forms-d2.el" . "forms-d2.el")
("forms-pass.el" . "forms-pass.el")
@@ -1137,6 +1205,15 @@ in the repository.")
("src/mini-gmp.c" . "lib/mini-gmp.c")
("src/mini-gmp.h" . "lib/mini-gmp.h")
("sysdep.c" . "src/sysdep.c")
+ ("lisp/gnus/nnir.el" . "nnir.el")
+ ("src/regex.c" . "emacs-regex.c")
+ ("src/regex.h" . "emacs-regex.h")
+ ("test/manual/rmailmm.el" . "rmailmm-tests.el")
+ ("test/lisp/cedet/semantic-utest-fmt.el" . "format-tests.el")
+ ("test/lisp/emacs-lisp/tabulated-list-test.el" . "tabulated-list-tests.el")
+ ("test/lisp/url/url-handlers-test.el" . "url-handlers-tests.el")
+ ("test/src/dired-tests.el" . "dired-tests.el")
+ (".dir-locals.el" . ".dir-locals.el")
)
"Alist of files which have been renamed during their lifetime.
Elements are (OLDNAME . NEWNAME).")
@@ -1610,7 +1687,8 @@ and a buffer *Authors Errors* containing references to unknown files."
;; the versioned ChangeLog.N rather than the unversioned ChangeLog.
(zerop (call-process "make" nil nil nil
"-C" root "change-history-nocommit"))
- (error "Problem updating ChangeLog, try \"C-u M-x authors RET\""))
+ (error (substitute-command-keys
+ "Problem updating ChangeLog, try \"\\[universal-argument] \\[authors]\"")))
(let ((logs (process-lines find-program root "-name" "ChangeLog*"))
(table (make-hash-table :test 'equal))
(buffer-name "*Authors*")
@@ -1676,7 +1754,7 @@ list of their contributions.\n")
(insert "\n "))
(insert " " file))
(insert "\n")))))
- (insert "\nLocal" " Variables:\ncoding: "
+ (insert "\nLocal" " Variables:\nmode: etc-authors\ncoding: "
(symbol-name authors-coding-system) "\nEnd:\n")
(message "Generating buffer %s... done" buffer-name)
(unless noninteractive
diff --git a/admin/automerge b/admin/automerge
index 61570587d6b..81082f7dc68 100755
--- a/admin/automerge
+++ b/admin/automerge
@@ -4,7 +4,7 @@
## Copyright (C) 2018-2021 Free Software Foundation, Inc.
## Author: Glenn Morris <rgm@gnu.org>
-## Maintainer: emacs-devel@gnu.org
+## Maintainer: Stefan Kangas <stefan@marxist.se>
## This file is part of GNU Emacs.
@@ -37,7 +37,7 @@
die () # write error to stderr and exit
{
- [ $# -gt 0 ] && echo "$PN: $@" >&2
+ [ $# -gt 0 ] && echo "$PN: $*" >&2
exit 1
}
@@ -108,7 +108,8 @@ OPTIND=1
[ "$nocd" ] || {
- cd $PD # this should be the admin directory
+ # $PD should be the admin directory
+ cd $PD || die "Could not change directory to $PD"
cd ../
}
@@ -126,9 +127,13 @@ OPTIND=1
[ "$test" ] && build=1
-tempfile=/tmp/$PN.$$
+if [ -x "$(command -v mktemp)" ]; then
+ tempfile=$(mktemp "/tmp/$PN.XXXXXXXXXX")
+else
+ tempfile=/tmp/$PN.$$
+fi
-trap "rm -f $tempfile 2> /dev/null" EXIT
+trap 'rm -f $tempfile 2> /dev/null' EXIT
[ -e Makefile ] && [ "$build" ] && {
@@ -148,7 +153,7 @@ trap "rm -f $tempfile 2> /dev/null" EXIT
rev=$(git rev-parse HEAD)
-[ $(git rev-parse @{u}) = $rev ] || die "Local state does not match origin"
+[ "$(git rev-parse @{u})" = "$rev" ] || die "Local state does not match origin"
merge ()
@@ -157,12 +162,12 @@ merge ()
if $emacs --batch -Q -l ./admin/gitmerge.el \
--eval "(setq gitmerge-minimum-missing $nmin)" -f gitmerge \
- >| $tempfile 2>&1; then
+ >| "$tempfile" 2>&1; then
echo "merged ok"
return 0
else
- grep -E "Nothing to merge|Number of missing commits" $tempfile && \
+ grep -E "Nothing to merge|Number of missing commits" "$tempfile" && \
exit 0
cat "$tempfile" 1>&2
@@ -186,13 +191,13 @@ git diff --stat --cached origin/master | grep -q "etc/NEWS " && \
echo "Running autoreconf..."
-autoreconf -i -I m4 2>| $tempfile
+autoreconf -i -I m4 2>| "$tempfile"
retval=$?
## Annoyingly, autoreconf puts the "installing `./foo' messages on stderr.
if [ "$quiet" ]; then
- grep -v 'installing `\.' $tempfile 1>&2
+ grep -v 'installing `\.' "$tempfile" 1>&2
else
cat "$tempfile" 1>&2
fi
@@ -231,7 +236,7 @@ echo "Tests finished ok"
echo "Checking for remote changes..."
git fetch || die "fetch error"
-[ $(git rev-parse @{u}) = $rev ] || {
+[ "$(git rev-parse @{u})" = "$rev" ] || {
echo "Upstream has changed"
@@ -240,7 +245,7 @@ git fetch || die "fetch error"
## Ref eg https://lists.gnu.org/r/emacs-devel/2014-12/msg01435.html
## Instead, we throw away what we just did, and do the merge again.
echo "Resetting..."
- git reset --hard $rev
+ git reset --hard "$rev"
echo "Pulling..."
git pull --ff-only || die "pull error"
diff --git a/admin/charsets/mapfiles/CP720.map b/admin/charsets/mapfiles/CP720.map
index e27deac7eee..0e95b5d66e5 100644
--- a/admin/charsets/mapfiles/CP720.map
+++ b/admin/charsets/mapfiles/CP720.map
@@ -1,4 +1,4 @@
-# Created manually from <http://en.wikipedia.org/wiki/Code_page_720>.
+# Created manually from <https://en.wikipedia.org/wiki/Code_page_720>.
# The text in that page is available under the terms of the GNU Free
# Documentation License.
0x00-0x7F 0x0000
diff --git a/admin/charsets/mapfiles/CP858.map b/admin/charsets/mapfiles/CP858.map
index 753dc50946e..d5a59b2c52f 100644
--- a/admin/charsets/mapfiles/CP858.map
+++ b/admin/charsets/mapfiles/CP858.map
@@ -1,4 +1,4 @@
-# Created manually from <http://en.wikipedia.org/wiki/Code_page_858>.
+# Created manually from <https://en.wikipedia.org/wiki/Code_page_858>.
# The text in that page is available under the terms of the GNU Free
# Documentation License.
0x00-0x7F 0x0000
diff --git a/admin/diff-tar-files b/admin/diff-tar-files
index cdcc512ae6b..2fe15401d0d 100755
--- a/admin/diff-tar-files
+++ b/admin/diff-tar-files
@@ -35,7 +35,7 @@ old_tmp=/tmp/old.$$
new_tmp=/tmp/new.$$
trap "rm -f $old_tmp $new_tmp; exit 1" 1 2 15
-tar tzf "$old_tar" | sed -e 's,^[^/]*,,' | sort > $old_tmp
-tar tzf "$new_tar" | sed -e 's,^[^/]*,,' | sort > $new_tmp
+tar tf "$old_tar" | sed -e 's,^[^/]*,,' | sort > $old_tmp
+tar tf "$new_tar" | sed -e 's,^[^/]*,,' | sort > $new_tmp
diff -u $old_tmp $new_tmp
rm -f $new_tmp $old_tmp
diff --git a/admin/emake b/admin/emake
index bdaabc026b3..2ff553289da 100755
--- a/admin/emake
+++ b/admin/emake
@@ -13,7 +13,7 @@ cores=1
# Determine the number of cores.
if [ -f /proc/cpuinfo ]; then
- cores=$(($(egrep "^physical id|^cpu cores" /proc/cpuinfo |\
+ cores=$(($(grep -E "^physical id|^cpu cores" /proc/cpuinfo |\
awk '{ print $4; }' |\
sed '$!N;s/\n/ /' |\
uniq |\
@@ -28,8 +28,9 @@ s#^Installing git hooks...# Installing git hooks...#
s#^Running # Running #
s#^Configured for # Configured for #
s#^./temacs.*# \\& #
+s#^make.*Error# \\& #
' | \
-egrep --line-buffered -v "^make|\
+grep -E --line-buffered -v "^make|\
^Loading|\
SCRAPE|\
INFO.*Scraping.*[.] ?\$|\
@@ -92,4 +93,4 @@ done
# changed since last time.
make -j$cores check-maybe 2>&1 | \
sed -n '/contained unexpected results/,$p' | \
- egrep --line-buffered -v "^make"
+ grep -E --line-buffered -v "^make"
diff --git a/admin/gitmerge.el b/admin/gitmerge.el
index 851212c7bb1..658ceb77f49 100644
--- a/admin/gitmerge.el
+++ b/admin/gitmerge.el
@@ -37,10 +37,10 @@
;; up-to-date).
;; - Mark commits you'd like to skip, meaning to only merge their
;; metadata (merge strategy 'ours').
-;; - Hit 'm' to start merging. Skipped commits will be merged separately.
+;; - Hit 'm' to start merging. Skipped commits will be merged separately.
;; - If conflicts cannot be resolved automatically, you'll have to do
-;; it manually. In that case, resolve the conflicts and restart
-;; gitmerge, which will automatically resume. It will add resolved
+;; it manually. In that case, resolve the conflicts and restart
+;; gitmerge, which will automatically resume. It will add resolved
;; files, commit the pending merge and continue merging the rest.
;; - Inspect master branch, and if everything looks OK, push.
@@ -68,8 +68,7 @@ bump Emacs version\\|Auto-commit"))
(defvar gitmerge-minimum-missing 10
"Minimum number of missing commits to consider merging in batch mode.")
-(defvar gitmerge-status-file (expand-file-name "gitmerge-status"
- user-emacs-directory)
+(defvar gitmerge-status-file (locate-user-emacs-file "gitmerge-status")
"File where missing commits will be saved between sessions.")
(defvar gitmerge-ignore-branches-regexp
@@ -122,13 +121,14 @@ If nil, the function `gitmerge-default-branch' guesses.")
(with-temp-buffer
(if (not branch)
(insert-file-contents "configure.ac")
- (call-process "git" nil t nil "show" (format "%s:configure.ac" branch))
+ (let ((coding-system-for-read vc-git-log-output-coding-system))
+ (call-process "git" nil t nil "show" (format "%s:configure.ac" branch)))
(goto-char (point-min)))
(re-search-forward "^AC_INIT([^,]+, \\([0-9]+\\)\\.")
(string-to-number (match-string 1))))
(defun gitmerge-default-branch ()
- "Default for branch that should be merged; eg \"origin/emacs-26\"."
+ "Default for branch that should be merged; e.g. \"origin/emacs-28\"."
(or gitmerge-default-branch
(format "origin/emacs-%s" (1- (gitmerge-emacs-version)))))
@@ -148,7 +148,8 @@ If nil, the function `gitmerge-default-branch' guesses.")
(pop-to-buffer (get-buffer-create gitmerge-output-buffer))
(fundamental-mode)
(erase-buffer)
- (call-process "git" nil t nil "log" "-1" commit)
+ (let ((coding-system-for-read vc-git-log-output-coding-system))
+ (call-process "git" nil t nil "log" "-1" commit))
(goto-char (point-min))
(gitmerge-highlight-skip-regexp)))))
@@ -160,7 +161,8 @@ If nil, the function `gitmerge-default-branch' guesses.")
(when commit
(pop-to-buffer (get-buffer-create gitmerge-output-buffer))
(erase-buffer)
- (call-process "git" nil t nil "diff-tree" "-p" commit)
+ (let ((coding-system-for-read vc-git-log-output-coding-system))
+ (call-process "git" nil t nil "diff-tree" "-p" commit))
(goto-char (point-min))
(diff-mode)))))
@@ -173,7 +175,9 @@ If nil, the function `gitmerge-default-branch' guesses.")
(pop-to-buffer (get-buffer-create gitmerge-output-buffer))
(erase-buffer)
(fundamental-mode)
- (call-process "git" nil t nil "diff" "--name-only" (concat commit "^!"))
+ (let ((coding-system-for-read vc-git-log-output-coding-system))
+ (call-process "git" nil t nil "diff" "--name-only"
+ (concat commit "^!")))
(goto-char (point-min))))))
(defun gitmerge-toggle-skip ()
@@ -216,9 +220,10 @@ if and why this commit should be skipped."
;; Go through the log and remember all commits that match
;; `gitmerge-skip-regexp' or are marked by --cherry-mark.
(with-temp-buffer
- (call-process "git" nil t nil "log" "--cherry-mark" "--left-only"
- "--no-decorate"
- (concat from "..." (car (vc-git-branches))))
+ (let ((coding-system-for-read vc-git-log-output-coding-system))
+ (call-process "git" nil t nil "log" "--cherry-mark" "--left-only"
+ "--no-decorate"
+ (concat from "..." (car (vc-git-branches)))))
(goto-char (point-max))
(while (re-search-backward "^commit \\(.+\\) \\([0-9a-f]+\\).*" nil t)
(let ((cherrymark (match-string 1))
@@ -241,9 +246,10 @@ if and why this commit should be skipped."
"Create the buffer for choosing commits."
(with-current-buffer (get-buffer-create gitmerge-buffer)
(erase-buffer)
- (call-process "git" nil t nil "log" "--left-only"
- "--pretty=format:%h %<(20,trunc) %an: %<(100,trunc) %s"
- (concat from "..." (car (vc-git-branches))))
+ (let ((coding-system-for-read vc-git-log-output-coding-system))
+ (call-process "git" nil t nil "log" "--left-only"
+ "--pretty=format:%h %<(20,trunc) %an: %<(100,trunc) %s"
+ (concat from "..." (car (vc-git-branches)))))
(goto-char (point-min))
(while (looking-at "^\\([a-f0-9]+\\)")
(let ((skipreason (gitmerge-skip-commit-p (match-string 1) commits)))
@@ -326,7 +332,8 @@ Returns non-nil if conflicts remain."
;; (pop-to-buffer (current-buffer)) (debug 'before-resolve)
))
;; Try to resolve the conflicts.
- (let (temp)
+ (let ((coding-system-for-read vc-git-log-output-coding-system)
+ temp)
(cond
;; FIXME when merging release branch to master, we still
;; need to detect and handle the case where NEWS was modified
@@ -392,9 +399,10 @@ is nil, only the single commit BEG is merged."
(if end "s were " " was ")
"skipped:\n\n")
""))
- (apply #'call-process "git" nil t nil "log" "--oneline"
- (if end (list (concat beg "~.." end))
- `("-1" ,beg)))
+ (let ((coding-system-for-read vc-git-log-output-coding-system))
+ (apply #'call-process "git" nil t nil "log" "--oneline"
+ (if end (list (concat beg "~.." end))
+ `("-1" ,beg))))
(insert "\n")
;; Truncate to 72 chars so that the resulting ChangeLog line fits in 80.
(goto-char (point-min))
@@ -408,8 +416,9 @@ MISSING must be a list of SHA1 strings."
(with-current-buffer (get-buffer-create gitmerge-output-buffer)
(erase-buffer)
(let* ((skip (cdar missing))
+ (coding-system-for-read vc-git-log-output-coding-system)
(beg (car (pop missing)))
- end commitmessage)
+ end commitmessage commitmessage1 commitmessage-file status)
;; Determine last revision with same boolean skip status.
(while (and missing
(eq (null (cdar missing))
@@ -423,12 +432,32 @@ MISSING must be a list of SHA1 strings."
(if end (concat ".." (substring end 0 6)) ""))
(unless end
(setq end beg))
- (unless (zerop
- (apply #'call-process "git" nil t nil "merge" "--no-ff"
- (append (when skip '("-s" "ours"))
- `("-m" ,commitmessage ,end))))
+ (when (eq system-type 'windows-nt)
+ ;; Command lines on MS-Windows cannot include newlines.
+ ;; Since "git merge" doesn't accept a -F FILE option, we
+ ;; commit the merge with a shortened single-line log message,
+ ;; and then invoke "git commit --amend" with the full log
+ ;; message from a temporary file.
+ (setq commitmessage1
+ ;; Make sure the commit message is at most a single line.
+ (car (split-string commitmessage "[\f\n\r\v]+")))
+ (setq commitmessage-file (make-nearby-temp-file "gitmerge-msg"))
+ (let ((coding-system-for-write vc-git-commits-coding-system))
+ (write-region commitmessage nil commitmessage-file nil 'silent)))
+ (unless (setq status
+ (zerop
+ (apply #'call-process "git" nil t nil "merge" "--no-ff"
+ (append (when skip '("-s" "ours"))
+ (if commitmessage-file
+ `("-m" ,commitmessage1 ,end)
+ `("-m" ,commitmessage ,end))))))
(gitmerge-write-missing missing from)
- (gitmerge-resolve-unmerged)))
+ (gitmerge-resolve-unmerged))
+ (when (and commitmessage-file (file-exists-p commitmessage-file))
+ (if status
+ (call-process "git" nil t nil
+ "commit" "--amend" "-F" commitmessage-file))
+ (delete-file commitmessage-file)))
missing))
(defun gitmerge-resolve-unmerged ()
@@ -436,12 +465,13 @@ MISSING must be a list of SHA1 strings."
Throw an user-error if we cannot resolve automatically."
(with-current-buffer (get-buffer-create gitmerge-output-buffer)
(erase-buffer)
- (let (files conflicted)
+ (let ((coding-system-for-read vc-git-log-output-coding-system)
+ files conflicted)
;; List unmerged files
(if (not (zerop
(call-process "git" nil t nil
"diff" "--name-only" "--diff-filter=U")))
- (error "Error listing unmerged files. Resolve manually.")
+ (error "Error listing unmerged files. Resolve manually.")
(goto-char (point-min))
(while (not (eobp))
(push (buffer-substring (point) (line-end-position)) files)
@@ -479,17 +509,19 @@ Throw an user-error if we cannot resolve automatically."
(defun gitmerge-repo-clean ()
"Return non-nil if repository is clean."
(with-temp-buffer
+ (let ((coding-system-for-read vc-git-log-output-coding-system))
(call-process "git" nil t nil
"diff" "--staged" "--name-only")
(call-process "git" nil t nil
"diff" "--name-only")
- (zerop (buffer-size))))
+ (zerop (buffer-size)))))
(defun gitmerge-commit ()
"Commit, and return non-nil if it succeeds."
(with-current-buffer (get-buffer-create gitmerge-output-buffer)
- (erase-buffer)
- (eq 0 (call-process "git" nil t nil "commit" "--no-edit"))))
+ (let ((coding-system-for-read vc-git-log-output-coding-system))
+ (erase-buffer)
+ (eq 0 (call-process "git" nil t nil "commit" "--no-edit")))))
(defun gitmerge-maybe-resume ()
"Check if we have to resume a merge.
@@ -603,7 +635,7 @@ Branch FROM will be prepended to the list."
"(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) Log matches "
+ "(C) Detected backport (cherry-mark), (R) Matches skip "
"regexp, (M) Manually picked\n\n")
(gitmerge-mode)
(pop-to-buffer (current-buffer))
diff --git a/admin/make-tarball.txt b/admin/make-tarball.txt
index ae007d76b03..872cb00ca28 100644
--- a/admin/make-tarball.txt
+++ b/admin/make-tarball.txt
@@ -5,7 +5,7 @@ Instructions to create pretest or release tarballs. -*- coding: utf-8 -*-
Steps to take before starting on the first pretest in any release sequence:
-0. The release branch (e.g. emacs-26) should already have been made
+0. The release branch (e.g. emacs-28) should already have been made
and you should use it for all that follows. Diffs from this
branch should be going to the emacs-diffs mailing list.
@@ -14,12 +14,13 @@ Steps to take before starting on the first pretest in any release sequence:
2. Consider increasing the value of the variable
'customize-changed-options-previous-release' in cus-edit.el to
- refer to a newer version of Emacs. (This is probably needed only
- when preparing the first pretest for a major Emacs release.)
+ refer to a newer version of Emacs. (This is now done when cutting
+ the release branch, see admin/release-branch.txt.)
Commit cus-edit.el if changed.
3. Remove any old pretests from https://alpha.gnu.org/gnu/emacs/pretest.
You can use 'gnupload --delete' (see below for more gnupload details).
+ (We currently don't bother with this.)
General steps (for each step, check for possible errors):
@@ -42,6 +43,12 @@ General steps (for each step, check for possible errors):
because some of the commands below run Make, so they need
Makefiles to be present.
+ For Emacs 28, and as long as --with-native-compilation is not the
+ default, the tree needs to be configured with native-compilation
+ enabled, to ensure all the pertinent *.elc files will end up in
+ the tarball. Otherwise, the *.eln files might not build correctly
+ on the user's system.
+
2. Regenerate the etc/AUTHORS file:
M-: (require 'authors) RET
M-x authors RET
@@ -83,7 +90,7 @@ General steps (for each step, check for possible errors):
admin/release-process must be completed.
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
+ 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
@@ -157,8 +164,15 @@ General steps (for each step, check for possible errors):
If this is the first pretest of a major release, just comparing
with the previous release may overlook many new files. You can try
- something like 'find . | sort' in a clean repository, and compare the
- results against the new tar contents.
+ something like 'find . | sort' in a clean repository, and
+ compare the results against the new tar contents. Another
+ alternative is using something like:
+
+ tar cf - emacs-NEW | tar t -C /tmp | grep -Ev "\.(o|d)$" | sort
+
+ Where emacs-NEW is the directory containing your clean repository.
+ The output of this command might be easier to compare to the
+ tarball than the one you get from find.
7. tar -xf emacs-NEW.tar; cd emacs-NEW
./configure --prefix=/tmp/emacs && make check && make install
@@ -188,6 +202,14 @@ General steps (for each step, check for possible errors):
git tag -a TAG -m "Emacs TAG" SHA1
git push --tags
+ In the past, we were not always consistent with the annotation
+ (i.e. -m "Emacs TAG"). The preferred format is like this for a
+ pretest, release candidate and final release:
+
+ git tag -a emacs-28.0.90 -m "Emacs 28.0.90 pretest"
+ git tag -a emacs-28.1-rc1 -m "Emacs 28.1 RC1"
+ git tag -a emacs-28.1 -m "Emacs 28.1 release"
+
9. Decide what compression schemes to offer.
For a release, at least gz and xz:
gzip --best --no-name -c emacs-NEW.tar > emacs-NEW.tar.gz
@@ -250,6 +272,11 @@ General steps (for each step, check for possible errors):
because replies that invariably are not announcements also get
sent out as if they were.)
+ To create the included SHA1 and SHA256 checksums, run:
+
+ sha1sum emacs-NEW.tar.xz
+ sha256sum emacs-NEW.tar.xz
+
12. After a release, update the Emacs pages as described below.
13. Bump the Emacs version on the release branch.
diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index c12e83dd2fa..c9fe3b2f95a 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -30,7 +30,8 @@ GNULIB_MODULES='
canonicalize-lgpl
careadlinkat close-stream copy-file-range
count-leading-zeros count-one-bits count-trailing-zeros
- crypto/md5-buffer crypto/sha1-buffer crypto/sha256-buffer crypto/sha512-buffer
+ crypto/md5 crypto/md5-buffer
+ crypto/sha1-buffer crypto/sha256-buffer crypto/sha512-buffer
d-type diffseq double-slash-root dtoastr dtotimespec dup2
environ execinfo explicit_bzero faccessat
fchmodat fcntl fcntl-h fdopendir file-has-acl
@@ -38,7 +39,8 @@ GNULIB_MODULES='
free-posix fstatat fsusage fsync futimens
getloadavg getopt-gnu getrandom gettime gettimeofday gitlog-to-changelog
ieee754-h ignore-value intprops largefile libgmp lstat
- manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime nstrftime
+ manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime
+ nproc nstrftime
pathmax pipe2 pselect pthread_sigmask
qcopy-acl readlink readlinkat regex
sig2str sigdescr_np socklen stat-time std-gnu11 stdalign stddef stdio
@@ -49,8 +51,8 @@ GNULIB_MODULES='
'
AVOIDED_MODULES='
- btowc close dup fchdir fstat langinfo lock
- malloc-posix mbrtowc mbsinit memchr mkdir msvc-inval msvc-nothrow nl_langinfo
+ btowc 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
threadlib tzset unsetenv utime utime-h
@@ -118,5 +120,8 @@ cp -- "$gnulib_srcdir"/build-aux/config.guess \
"$gnulib_srcdir"/build-aux/install-sh \
"$gnulib_srcdir"/build-aux/move-if-change \
"$src"build-aux &&
+cp -- "$gnulib_srcdir"/lib/af_alg.h \
+ "$gnulib_srcdir"/lib/save-cwd.h \
+ "$src"lib &&
{ test -z "$src" || cd "$src"; } &&
./autogen.sh
diff --git a/admin/notes/bugtracker b/admin/notes/bugtracker
index 9eb65e1f864..deb06f552cc 100644
--- a/admin/notes/bugtracker
+++ b/admin/notes/bugtracker
@@ -84,7 +84,7 @@ generate a new report. The only time to send mail to the bug list
address is to create a new report.
Gnus users can add the following to message-dont-reply-to-names;
-similarly with Rmail and rmail-dont-reply-to-names:
+similarly with Rmail and mail-dont-reply-to-names:
"\\(emacs-pretest-bug\\|bug-gnu-emacs\\|bug-\\(e\\|gnu\\)macs\\)@gnu\\.org\\|\
\\(submit\\|control\\|owner\\)@debbugs\\.gnu\\.org"
diff --git a/admin/notes/emba b/admin/notes/emba
index 36b126e7735..2135c7a97cc 100644
--- a/admin/notes/emba
+++ b/admin/notes/emba
@@ -28,29 +28,45 @@ The messages contain a URL to the log file of the failed job, like
* Emacs jobset
The Emacs jobset is defined in the Emacs source tree, file
-'.gitlab-ci.yml'. It could be adapted for every Emacs branch, see
+'.gitlab-ci.yml'. All related files are located in directory
+'test/infra'. They could be adapted for every Emacs branch, see
<https://emba.gnu.org/help/ci/yaml/README.md>.
+A jobset on Gitlab is called pipeline. Emacs pipelines run through
+the stages 'build-images', 'platform-images' and 'native-comp-images'
+(create an Emacs instance by 'make bootstrap' with different
+configuration parameters) as well as 'normal', 'platforms' and
+'native-comp' (run respective test jobs based on the produced images).
+
+The jobs for stage 'normal' are contained in the file
+'test/infra/test-jobs.yml'. This file is generated by calling 'make
+-C test generate-test-jobs' in the Emacs source tree, and the
+resulting file shall be pushed to the Emacs git repository afterwards.
+
Every job runs in a Debian docker container. It uses the local clone
of the Emacs git repository to perform a bootstrap and test of Emacs.
This could happen for several jobs with changed configuration, compile
and test parameters.
-There are different types of jobs: 'prep-image-base' is responsible to
-prepare the environment for the following jobs. 'build-image-*' jobs
-are responsible to compile Emacs in different configuration. The
-corresponding 'test-*' jobs run the ert tests.
+The 'build-image-*' jobs of the different '*-images' stages run only
+if there are severe changes in the Emacs sources, like in Makefiles
+etc. Otherwise they are skipped, and the corresponding 'test-*' jobs
+run just 'make -C test ...' in the respective Docker image from a
+previous build run.
-A special job is 'test-all-inotify', which runs 'make check-expensive'.
-While most of the jobs run as soon as a respective file has been
-committed into the Emacs git repository, this test job runs scheduled,
-every 8 hours.
+Jobs in the 'build-images' and 'normal' stages are triggered by
+changes of respective files in the Emacs git repository. All other
+jobs run scheduled in a pipeline every 8 hours.
The log files for every test job are kept on the server for a week.
They can be downloaded from the server, visiting the URL
<https://emba.gnu.org/emacs/emacs/-/pipelines>, and selecting the job
in question.
+Every pipeline generates a JUnit test report for the respective test
+jobs, which can be inspected on the pipeline web page. This test
+report counts completed ERT tests, aborted tests are not counted.
+
* Emba configuration
The emba configuration files are hosted on
diff --git a/admin/notes/git-workflow b/admin/notes/git-workflow
index d109cdaa354..265a106bad5 100644
--- a/admin/notes/git-workflow
+++ b/admin/notes/git-workflow
@@ -16,14 +16,14 @@ Initial setup
Then we want to clone the repository. We normally want to have both
the current master and (if there is one) the active release branch
-(eg emacs-27).
+(eg emacs-28).
mkdir ~/emacs
cd ~/emacs
git clone <membername>@git.sv.gnu.org:/srv/git/emacs.git master
cd master
git config push.default current
-git worktree add ../emacs-27 emacs-27
+git worktree add ../emacs-28 emacs-28
You now have both branches conveniently accessible, and you can do
"git pull" in them once in a while to keep updated.
@@ -67,7 +67,7 @@ which will look like
commit 958b768a6534ae6e77a8547a56fc31b46b63710b
-cd ~/emacs/emacs-27
+cd ~/emacs/emacs-28
git cherry-pick -xe 958b768a6534ae6e77a8547a56fc31b46b63710b
and add "Backport:" to the commit string. Then
@@ -109,7 +109,7 @@ up-to-date by doing a pull. Then start Emacs with
emacs -l admin/gitmerge.el -f gitmerge
You'll be asked for the branch to merge, which will default to
-(eg) 'origin/emacs-27', which you should accept. Merging a local tracking
+(eg) 'origin/emacs-28', which you should accept. Merging a local tracking
branch is discouraged, since it might not be up-to-date, or worse,
contain commits from you which are not yet pushed upstream.
diff --git a/admin/notes/multi-tty b/admin/notes/multi-tty
index 1a337b9d799..fa4df820ae4 100644
--- a/admin/notes/multi-tty
+++ b/admin/notes/multi-tty
@@ -474,7 +474,7 @@ THINGS TO DO
definition.
Exceptions found so far: x-select-text and
- x-cut-buffer-or-selection-value.
+ x-selection-value (old name: x-cut-buffer-or-selection-value).
** Have a look at fatal_error_hook.
diff --git a/admin/notes/unicode b/admin/notes/unicode
index bcede9c6ed1..be51d09d37a 100644
--- a/admin/notes/unicode
+++ b/admin/notes/unicode
@@ -12,17 +12,23 @@ Emacs uses the following files from the Unicode Character Database
. UnicodeData.txt
. Blocks.txt
. BidiBrackets.txt
- . BidiCharacterTest.txt
. BidiMirroring.txt
. IVD_Sequences.txt
. NormalizationTest.txt
. SpecialCasing.txt
+ . emoji-data.txt
+ . emoji-zwj-sequences.txt
+ . emoji-sequences.txt
+ . BidiCharacterTest.txt
+
+Emacs also uses the file emoji-test.txt which should be imported from
+the Unicode's Public/emoji/ directory.
-First, the first 7 files need to be copied into admin/unidata/, and
-the file https://www.unicode.org/copyright.html should be copied over
-copyright.html in admin/unidata (that file might need trailing
-whitespace removed before it can be committed to the Emacs
-repository).
+First, the first 10 files and emoji-test.txt need to be copied into
+admin/unidata/, and the file https://www.unicode.org/copyright.html
+should be copied over copyright.html in admin/unidata (some of them
+might need trailing whitespace removed before they can be committed to
+the Emacs repository).
Then Emacs should be rebuilt for them to take effect. Rebuilding
Emacs updates several derived files elsewhere in the Emacs source
@@ -81,7 +87,47 @@ regarding failing lines.
The file BidiCharacterTest.txt should be copied to the test suite, and
if its format has changed, the file biditest.el there should be
-modified to follow suit.
+modified to follow suit. If there's trailing whitespace in
+BidiCharacterTest.txt, it should be removed before committing the new
+version.
+
+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
+will give you an idea of which codepoints are not supported by
+whichever font Emacs is using.
+
+(defun check-emoji-coverage (font-name-regexp)
+"Display a buffer containing emoji codepoints for which FONT-NAME is not used.
+This must be run from a buffer in the format of emoji-data.txt.
+FONT-NAME-REGEXP is checked using `string-match'."
+(interactive "MFont Name: ")
+(save-excursion
+(goto-char (point-min))
+(let (res char name ifont)
+ (while (re-search-forward "; Emoji_Presentation [^(]+(\\(.\\)[).]" nil t)
+ (setq char (aref (match-string 1) 0))
+ (setq ifont (car (internal-char-font nil char)))
+ (when ifont
+ (setq name (font-xlfd-name ifont)))
+ (if (or (not ifont) (not (string-match font-name-regexp name)))
+ (setq res (concat (string char) res))))
+ (when res
+ (with-output-to-temp-buffer "*Check-Emoji-Coverage*"
+ (princ (format "Font not matching '%s' was used for the following characters:\n%s"
+ font-name-regexp (reverse res))))))))
+
+Visit "emoji-zwj-sequences.txt" and "emoji-sequences.txt" with the
+rebuilt Emacs, and check that the sample sequences are composed
+properly. Also check the Unicode style chart file available at
+https://unicode.org/emoji/charts/emoji-style.txt for any issues
+involving VS-15 and VS-16, if so you may need to update the value
+generated for auto-composition-emoji-eligible-codepoints by
+admin/unidata/emoji-zwj.awk. Note that your emoji font might not have
+glyphs for the newest codepoints yet.
+
+Finally, etc/NEWS should be updated to announce the support for the
+new Unicode version.
Problems, fixmes and other unicode-related issues
-------------------------------------------------------------
diff --git a/admin/nt/dist-build/README-scripts b/admin/nt/dist-build/README-scripts
index f27bcd3bd66..6b1adbe03e1 100644
--- a/admin/nt/dist-build/README-scripts
+++ b/admin/nt/dist-build/README-scripts
@@ -3,6 +3,15 @@ Distribution Build Scripts for Windows
The scripts are used to build the binary distribution zip files for windows.
+Environment
+-----------
+
+A full installation of msys2 is required along for the build. The
+various dependencies of Emacs need to be installed also. These change
+over time, but are listed in build-deps-zips.py.
+
+
+
File System Organization
------------------------
@@ -15,15 +24,19 @@ The file system needs to be organized like so:
~/emacs-build/git
-Contains a checkout of the Emacs git repository, organized according
-to branches, with git worktree
+Contains checkouts and worktrees of the Emacs git repository,
+organized according to branches.
-~/emacs-build/git/emacs-$branch
+~/emacs-build/git/master
-A branch of the git repository containing the current release
+A checkout out of the master branch of the Emacs git repository.
+
+~/emacs-build/git/emacs-$major-version
+
+A worktree of the git repository containing the current release
branch. This has to be created by hand.
-~/emacs-build/git/emacs-$version
+~/emacs-build/git/emacs-$release-version
A branch of the git repository containing the last release. The
build-zips.sh file will create this for you.
@@ -63,8 +76,8 @@ uploaded.
Build Process
-------------
-For each major version
-----------------------
+
+### For each major version
The dependencies files need to be created. This can be around the time
of the pre-tests, then used for all releases of that version, to
@@ -88,8 +101,7 @@ files will be created in ~/emacs-upload from where they can be signed
and uploaded with `gnupload`.
-For snapshots from Master
--------------------------
+### For snapshots from Master
Snapshots are generally created from master when there is a release
branch on which a release has already been created. At this point,
@@ -110,8 +122,7 @@ used.
Now, run `build-zips.sh -s` to build a snapshot release.
-For snapshots from a Release Branch
------------------------------------
+### For snapshots from a Release Branch
Snapshots can be built from a release branch; this is really only
useful before a pre-test has happened.
@@ -123,8 +134,8 @@ version number must be added to the command line with `build-zips.sh
the version (e.g emacs-27-2019-12-26.zip) rather than than the Emacs
version (e.g emacs-27.0.50.zip).
-For snapshots from another branch
----------------------------------
+
+### For snapshots from another branch
Snapshots can be build from any other branch. There is rarely a need
to do this, except where some significant, wide-ranging feature is
diff --git a/admin/nt/dist-build/build-dep-zips.py b/admin/nt/dist-build/build-dep-zips.py
index 19168e7ff25..dfff493b640 100755
--- a/admin/nt/dist-build/build-dep-zips.py
+++ b/admin/nt/dist-build/build-dep-zips.py
@@ -20,6 +20,8 @@ import argparse
import os
import shutil
import re
+import functools
+import operator
from subprocess import check_output
@@ -112,7 +114,7 @@ def ntldd_munge(out):
## Packages to fiddle with
## Source for gcc-libs is part of gcc
SKIP_SRC_PKGS=["mingw-w64-gcc-libs"]
-SKIP_DEP_PKGS=["mingw-w64-glib2"]
+SKIP_DEP_PKGS=frozenset(["mingw-w64-x86_64-glib2"])
MUNGE_SRC_PKGS={"mingw-w64-libwinpthread-git":"mingw-w64-winpthreads-git"}
MUNGE_DEP_PKGS={
"mingw-w64-x86_64-libwinpthread":"mingw-w64-x86_64-libwinpthread-git",
@@ -121,19 +123,17 @@ MUNGE_DEP_PKGS={
## Currently no packages seem to require this!
ARCH_PKGS=[]
-SRC_REPO="https://sourceforge.net/projects/msys2/files/REPOS/MINGW/Sources"
+SRC_REPO="https://repo.msys2.org/mingw/sources"
-def immediate_deps(pkg):
- package_info = check_output(["pacman", "-Si", pkg]).decode("utf-8").split("\n")
+def immediate_deps(pkgs):
+ package_info = check_output(["pacman", "-Si"] + pkgs).decode("utf-8").splitlines()
- ## Extract the "Depends On" line
- depends_on = [x for x in package_info if x.startswith("Depends On")][0]
- ## Remove "Depends On" prefix
- dependencies = depends_on.split(":")[1]
-
- ## Split into dependencies
- dependencies = dependencies.strip().split(" ")
+ ## Extract the packages listed for "Depends On:" lines.
+ dependencies = [line.split(":")[1].split() for line in package_info
+ if line.startswith("Depends On")]
+ ## Flatten dependency lists from multiple packages into one list.
+ dependencies = functools.reduce(operator.iconcat, dependencies, [])
## Remove > signs TODO can we get any other punctuation here?
dependencies = [d.split(">")[0] for d in dependencies if d]
@@ -149,16 +149,18 @@ def extract_deps():
print( "Extracting deps" )
# Get a list of all dependencies needed for packages mentioned above.
- pkgs = PKG_REQ[:]
- n = 0
- while n < len(pkgs):
- subdeps = immediate_deps(pkgs[n])
- for p in subdeps:
- if not (p in pkgs or p in SKIP_DEP_PKGS):
- pkgs.append(p)
- n = n + 1
+ pkgs = set(PKG_REQ)
+ newdeps = pkgs
+ print("adding...")
+ while True:
+ subdeps = frozenset(immediate_deps(list(newdeps)))
+ newdeps = subdeps - SKIP_DEP_PKGS - pkgs
+ if not newdeps:
+ break
+ print('\n'.join(newdeps))
+ pkgs |= newdeps
- return sorted(pkgs)
+ return list(pkgs)
def download_source(tarball):
@@ -167,7 +169,7 @@ def download_source(tarball):
if not os.path.exists("../emacs-src-cache/{}".format(tarball)):
print("Downloading {}...".format(tarball))
check_output_maybe(
- "wget -a ../download.log -O ../emacs-src-cache/{} {}/{}/download"
+ "wget -a ../download.log -O ../emacs-src-cache/{} {}/{}"
.format(tarball, SRC_REPO, tarball),
shell=True
)
@@ -255,7 +257,7 @@ DRY_RUN=args.d
if( args.l ):
print("List of dependencies")
- print( extract_deps() )
+ print( deps )
exit(0)
if args.s:
diff --git a/admin/nt/dist-build/build-zips.sh b/admin/nt/dist-build/build-zips.sh
index 7bc6ea6a9e5..4c3a52af6a7 100755
--- a/admin/nt/dist-build/build-zips.sh
+++ b/admin/nt/dist-build/build-zips.sh
@@ -134,7 +134,7 @@ while getopts "gb:hnsiV:" opt; do
echo " -g git update and worktree only"
echo " -i build installer only"
echo " -n do not configure"
- echo " -s snaphot build"
+ echo " -s snapshot build"
exit 0
;;
\?)
diff --git a/admin/release-branch.txt b/admin/release-branch.txt
new file mode 100644
index 00000000000..0c393a9eccb
--- /dev/null
+++ b/admin/release-branch.txt
@@ -0,0 +1,76 @@
+Instructions for cutting the Emacs release branch
+
+1. In the clone of the Emacs Git repository, switch to the 'master'
+ branch, "git pull", and build it (using 'make bootstrap') to make
+ sure it's not broken. Run 'make check-expensive' and ensure all
+ tests pass. (Alternatively, verify that the automated build
+ servers are showing success for the latest revision.)
+
+2. Create the release branch and switch to it. Assuming that it is
+ for releasing Emacs versions XY.1, XY.2, etc., the command is:
+
+ git checkout -b emacs-XY
+
+3. Switch the release branch to the suitable version. The convention
+ is that release branches start with version XY.0.60, whereas the
+ master branch from which the release branch was cut was at the
+ version XY.0.50. To change the version, do the following inside
+ Emacs:
+
+ M-x load-file RET admin/admin.el RET
+ M-x set-version RET XY.0.60 RET
+
+ Change the value of 'customize-changed-options-previous-release'
+ in cus-edit.el to reference the last release from the emacs-XY-1
+ branch (last release for the previous major version).
+
+ The above modifies several files in the tree; commit the changes
+ with the appropriate log message, something like "Bump Emacs
+ version to XY.0.60", and with header saying "Cut the emacs-XY
+ release branch". Then push the changes:
+
+ git push --set-upstream origin emacs-XY
+
+ The "push" command should show the new branch just created.
+
+4. Switch back to the master branch.
+
+ git checkout master
+ git pull
+
+ Set the version on the master branch to the next major release:
+
+ M-x set-version RET XY+1.0.50 RET
+
+ This creates a new file etc/NEWS.XY. "git add" it.
+
+ Change the value of 'customize-changed-options-previous-release'
+ in cus-edit.el to reference emacs-XY.1, the next version to be
+ released from the newly-committed release branch.
+
+ Update the emacs-module sources for the new version XY+1. This
+ entails:
+
+ . adding a new file src/module-env-XY+1.h, with contents just the
+ comment taken from the beginning of src/module-env-XY.h
+ . removing the comment from the beginning of src/module-env-XY.h
+ . adding two lines to configure.ac:
+
+ AC_SUBST_FILE([module_env_snippet_XY+1])
+ module_env_snippet_XY+1="$srcdir/src/module-env-XY+1.h"
+
+ . adding a new 'struct emacs_env_XY+1' to src/emacs-module.h.in,
+ with the contents identical to'struct emacs_env_XY', with one
+ line added:
+
+ @module_env_snippet_XY+1@
+
+ (FIXME: "M-x set-version" should do this emacs-module stuff
+ automatically when the version is NN.0.60, or when there's no
+ src/module-env-NN.h file.)
+
+ "git add" the new src/module-env-XY+1.h file.
+
+ Then rebuild Emacs. Then commit the new/changed files and push.
+
+5. Announce the new release branch on emacs-devel.
diff --git a/admin/unidata/BidiBrackets.txt b/admin/unidata/BidiBrackets.txt
index a95e5ca5ca7..89698f588ae 100644
--- a/admin/unidata/BidiBrackets.txt
+++ b/admin/unidata/BidiBrackets.txt
@@ -1,11 +1,11 @@
-# BidiBrackets-13.0.0.txt
-# Date: 2019-09-09, 19:31:00 GMT [AG, LI, KW]
-# © 2019 Unicode®, Inc.
+# BidiBrackets-14.0.0.txt
+# Date: 2021-06-30, 23:59:00 GMT [AG, LI, KW]
+# © 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 Character Database
-# For documentation, see http://www.unicode.org/reports/tr44/
+# For documentation, see https://www.unicode.org/reports/tr44/
#
# Bidi_Paired_Bracket and Bidi_Paired_Bracket_Type Properties
#
@@ -56,7 +56,7 @@
# of each line.
#
# For information on bidirectional paired brackets, see UAX #9: Unicode
-# Bidirectional Algorithm, at http://www.unicode.org/unicode/reports/tr9/
+# Bidirectional Algorithm, at https://www.unicode.org/reports/tr9/
#
# This file was originally created by Andrew Glass and Laurentiu Iancu
# for Unicode 6.3.
@@ -147,6 +147,14 @@
2E27; 2E26; c # RIGHT SIDEWAYS U BRACKET
2E28; 2E29; o # LEFT DOUBLE PARENTHESIS
2E29; 2E28; c # RIGHT DOUBLE PARENTHESIS
+2E55; 2E56; o # LEFT SQUARE BRACKET WITH STROKE
+2E56; 2E55; c # RIGHT SQUARE BRACKET WITH STROKE
+2E57; 2E58; o # LEFT SQUARE BRACKET WITH DOUBLE STROKE
+2E58; 2E57; c # RIGHT SQUARE BRACKET WITH DOUBLE STROKE
+2E59; 2E5A; o # TOP HALF LEFT PARENTHESIS
+2E5A; 2E59; c # TOP HALF RIGHT PARENTHESIS
+2E5B; 2E5C; o # BOTTOM HALF LEFT PARENTHESIS
+2E5C; 2E5B; c # BOTTOM HALF RIGHT PARENTHESIS
3008; 3009; o # LEFT ANGLE BRACKET
3009; 3008; c # RIGHT ANGLE BRACKET
300A; 300B; o # LEFT DOUBLE ANGLE BRACKET
diff --git a/admin/unidata/BidiMirroring.txt b/admin/unidata/BidiMirroring.txt
index 34e42ae8dc3..bd8e2c5d001 100644
--- a/admin/unidata/BidiMirroring.txt
+++ b/admin/unidata/BidiMirroring.txt
@@ -1,10 +1,10 @@
-# BidiMirroring-13.0.0.txt
-# Date: 2019-09-09, 19:34:00 GMT [KW, LI, RP]
-# © 2019 Unicode®, Inc.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# BidiMirroring-14.0.0.txt
+# Date: 2021-08-08, 22:55:00 GMT [KW, RP]
+# © 2021 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/
#
# Bidi_Mirroring_Glyph Property
#
@@ -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 13.0.0.
+# The repertoire covered by the file is Unicode 14.0.0.
#
# The file contains a list of lines with mappings from one code point
# to another one for character-based mirroring.
@@ -40,7 +40,7 @@
# for character-based mirroring.
#
# For information on bidi mirroring, see UAX #9: Unicode Bidirectional Algorithm,
-# at http://www.unicode.org/unicode/reports/tr9/
+# at https://www.unicode.org/reports/tr9/
#
# This file was originally created by Markus Scherer.
# Extended for Unicode 3.2, 4.0, 4.1, 5.0, 5.1, 5.2, and 6.0 by Ken Whistler,
@@ -96,10 +96,10 @@
208D; 208E # SUBSCRIPT LEFT PARENTHESIS
208E; 208D # SUBSCRIPT RIGHT PARENTHESIS
2208; 220B # ELEMENT OF
-2209; 220C # NOT AN ELEMENT OF
+2209; 220C # [BEST FIT] NOT AN ELEMENT OF
220A; 220D # SMALL ELEMENT OF
220B; 2208 # CONTAINS AS MEMBER
-220C; 2209 # DOES NOT CONTAIN AS MEMBER
+220C; 2209 # [BEST FIT] DOES NOT CONTAIN AS MEMBER
220D; 220A # SMALL CONTAINS AS MEMBER
2215; 29F5 # DIVISION SLASH
221F; 2BFE # RIGHT ANGLE
@@ -453,6 +453,14 @@
2E27; 2E26 # RIGHT SIDEWAYS U BRACKET
2E28; 2E29 # LEFT DOUBLE PARENTHESIS
2E29; 2E28 # RIGHT DOUBLE PARENTHESIS
+2E55; 2E56 # LEFT SQUARE BRACKET WITH STROKE
+2E56; 2E55 # RIGHT SQUARE BRACKET WITH STROKE
+2E57; 2E58 # LEFT SQUARE BRACKET WITH DOUBLE STROKE
+2E58; 2E57 # RIGHT SQUARE BRACKET WITH DOUBLE STROKE
+2E59; 2E5A # TOP HALF LEFT PARENTHESIS
+2E5A; 2E59 # TOP HALF RIGHT PARENTHESIS
+2E5B; 2E5C # BOTTOM HALF LEFT PARENTHESIS
+2E5C; 2E5B # BOTTOM HALF RIGHT PARENTHESIS
3008; 3009 # LEFT ANGLE BRACKET
3009; 3008 # RIGHT ANGLE BRACKET
300A; 300B # LEFT DOUBLE ANGLE BRACKET
diff --git a/admin/unidata/Blocks.txt b/admin/unidata/Blocks.txt
index 56877db10f3..cc5d61988bb 100644
--- a/admin/unidata/Blocks.txt
+++ b/admin/unidata/Blocks.txt
@@ -1,6 +1,6 @@
-# Blocks-13.0.0.txt
-# Date: 2019-07-10, 19:06:00 GMT [KW]
-# © 2019 Unicode®, Inc.
+# 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
#
# Unicode Character Database
@@ -52,6 +52,7 @@
0800..083F; Samaritan
0840..085F; Mandaic
0860..086F; Syriac Supplement
+0870..089F; Arabic Extended-B
08A0..08FF; Arabic Extended-A
0900..097F; Devanagari
0980..09FF; Bengali
@@ -215,7 +216,9 @@ FFF0..FFFF; Specials
104B0..104FF; Osage
10500..1052F; Elbasan
10530..1056F; Caucasian Albanian
+10570..105BF; Vithkuqi
10600..1077F; Linear A
+10780..107BF; Latin Extended-F
10800..1083F; Cypriot Syllabary
10840..1085F; Imperial Aramaic
10860..1087F; Palmyrene
@@ -240,6 +243,7 @@ FFF0..FFFF; Specials
10E80..10EBF; Yezidi
10F00..10F2F; Old Sogdian
10F30..10F6F; Sogdian
+10F70..10FAF; Old Uyghur
10FB0..10FDF; Chorasmian
10FE0..10FFF; Elymaic
11000..1107F; Brahmi
@@ -259,13 +263,14 @@ FFF0..FFFF; Specials
11600..1165F; Modi
11660..1167F; Mongolian Supplement
11680..116CF; Takri
-11700..1173F; Ahom
+11700..1174F; Ahom
11800..1184F; Dogra
118A0..118FF; Warang Citi
11900..1195F; Dives Akuru
119A0..119FF; Nandinagari
11A00..11A4F; Zanabazar Square
11A50..11AAF; Soyombo
+11AB0..11ABF; Unified Canadian Aboriginal Syllabics Extended-A
11AC0..11AFF; Pau Cin Hau
11C00..11C6F; Bhaiksuki
11C70..11CBF; Marchen
@@ -277,11 +282,13 @@ FFF0..FFFF; Specials
12000..123FF; Cuneiform
12400..1247F; Cuneiform Numbers and Punctuation
12480..1254F; Early Dynastic Cuneiform
+12F90..12FFF; Cypro-Minoan
13000..1342F; Egyptian Hieroglyphs
13430..1343F; Egyptian Hieroglyph Format Controls
14400..1467F; Anatolian Hieroglyphs
16800..16A3F; Bamum Supplement
16A40..16A6F; Mro
+16A70..16ACF; Tangsa
16AD0..16AFF; Bassa Vah
16B00..16B8F; Pahawh Hmong
16E40..16E9F; Medefaidrin
@@ -290,13 +297,15 @@ FFF0..FFFF; Specials
17000..187FF; Tangut
18800..18AFF; Tangut Components
18B00..18CFF; Khitan Small Script
-18D00..18D8F; Tangut Supplement
+18D00..18D7F; Tangut Supplement
+1AFF0..1AFFF; Kana Extended-B
1B000..1B0FF; Kana Supplement
1B100..1B12F; Kana Extended-A
1B130..1B16F; Small Kana Extension
1B170..1B2FF; Nushu
1BC00..1BC9F; Duployan
1BCA0..1BCAF; Shorthand Format Controls
+1CF00..1CFCF; Znamenny Musical Notation
1D000..1D0FF; Byzantine Musical Symbols
1D100..1D1FF; Musical Symbols
1D200..1D24F; Ancient Greek Musical Notation
@@ -305,9 +314,12 @@ FFF0..FFFF; Specials
1D360..1D37F; Counting Rod Numerals
1D400..1D7FF; Mathematical Alphanumeric Symbols
1D800..1DAAF; Sutton SignWriting
+1DF00..1DFFF; Latin Extended-G
1E000..1E02F; Glagolitic Supplement
1E100..1E14F; Nyiakeng Puachue Hmong
+1E290..1E2BF; Toto
1E2C0..1E2FF; Wancho
+1E7E0..1E7FF; Ethiopic Extended-B
1E800..1E8DF; Mende Kikakui
1E900..1E95F; Adlam
1EC70..1ECBF; Indic Siyaq Numbers
diff --git a/admin/unidata/IVD_Sequences.txt b/admin/unidata/IVD_Sequences.txt
index a1a38a2e926..886d8519ab5 100644
--- a/admin/unidata/IVD_Sequences.txt
+++ b/admin/unidata/IVD_Sequences.txt
@@ -2,6 +2,9 @@
#
# History:
#
+# 2020-11-06 Registration of additional sequences in the MSARG
+# collection.
+#
# 2017-12-12 Registration of additional sequences in the Adobe-Japan1
# collection. Combined registration of the KRName collection
# and of sequences in that collection. Registration of
@@ -27,10 +30,10 @@
#
# This file is part of the Unicode Ideographic Variation Database (IVD).
# For more details on the IVD, see UTS #37:
-# http://www.unicode.org/reports/tr37/
+# https://www.unicode.org/reports/tr37/
#
-# Copyright 2006-2017 Unicode, Inc.
-# For terms of use, see: http://www.unicode.org/terms_of_use.html
+# Copyright 2006-2020 Unicode, Inc.
+# For terms of use, see: https://www.unicode.org/copyright.html#8
#
3402 E0100; Adobe-Japan1; CID+13698
3402 E0101; Adobe-Japan1; CID+13697
@@ -864,6 +867,8 @@
4054 E0100; Hanyo-Denshi; IA3507
4054 E0101; Hanyo-Denshi; TK01062970
4058 E0100; Adobe-Japan1; CID+18198
+4058 E0101; MSARG; MD_4058
+4058 E0102; MSARG; ME_4058_001
4071 E0100; Hanyo-Denshi; IA0509
4071 E0100; Moji_Joho; MJ002897
4071 E0101; Hanyo-Denshi; JTB661
@@ -1094,6 +1099,8 @@
4359 E0101; Moji_Joho; MJ003650
4395 E0100; Hanyo-Denshi; IA4278
4395 E0101; Hanyo-Denshi; TK01074010
+4397 E0100; MSARG; MA_9967
+4397 E0101; MSARG; ME_4397_001
43A8 E0100; Hanyo-Denshi; IA4294
43A8 E0101; Hanyo-Denshi; TK01074340
43A9 E0100; Hanyo-Denshi; IA0588
@@ -1407,6 +1414,8 @@
460D E0101; Moji_Joho; MJ004388
460F E0100; Adobe-Japan1; CID+18634
4610 E0100; Adobe-Japan1; CID+19136
+4615 E0100; MSARG; MA_8FEB
+4615 E0101; MSARG; ME_4615_001
462F E0100; Hanyo-Denshi; IA4925
462F E0101; Hanyo-Denshi; TK01083800
4635 E0100; Hanyo-Denshi; IA4929
@@ -1560,6 +1569,8 @@
4921 E0101; Hanyo-Denshi; TK01092060
4938 E0100; Hanyo-Denshi; IA5637
4938 E0101; Hanyo-Denshi; TK01093220
+493E E0100; MSARG; MA_97E1
+493E E0101; MSARG; ME_493E_001
493F E0100; Hanyo-Denshi; IA5643
493F E0100; Moji_Joho; MJ005179
493F E0101; Hanyo-Denshi; KS462830
@@ -1608,6 +1619,8 @@
4A28 E0101; Hanyo-Denshi; IB1033
4A28 E0101; Moji_Joho; MJ005391
4A29 E0100; Adobe-Japan1; CID+18910
+4A29 E0101; MSARG; MD_4A29
+4A29 E0102; MSARG; ME_4A29_001
4A3C E0100; Hanyo-Denshi; IB1041
4A3C E0100; Moji_Joho; MJ005411
4A3C E0101; Hanyo-Denshi; JTBEBD
@@ -2016,6 +2029,8 @@
4E75 E0101; Moji_Joho; MJ006419
4E75 E0102; Hanyo-Denshi; JTAD26
4E75 E0102; Moji_Joho; MJ006420
+4E78 E0100; MSARG; MA_9AFB
+4E78 E0101; MSARG; ME_4E78_001
4E79 E0100; Adobe-Japan1; CID+19143
4E7E E0100; Adobe-Japan1; CID+1505
4E7F E0100; Adobe-Japan1; CID+14306
@@ -2633,6 +2648,8 @@
5029 E0101; Moji_Joho; MJ006862
5029 E0102; Hanyo-Denshi; FT2068
5029 E0102; Moji_Joho; MJ006863
+5029 E0103; MSARG; MB_ADC5
+5029 E0104; MSARG; ME_5029_001
502A E0100; Adobe-Japan1; CID+4157
502B E0100; Adobe-Japan1; CID+3993
502B E0101; Hanyo-Denshi; JA4649
@@ -3511,6 +3528,8 @@
51CD E0100; Adobe-Japan1; CID+3162
51CF E0100; Adobe-Japan1; CID+19177
51D1 E0100; Adobe-Japan1; CID+19178
+51D1 E0101; MSARG; MA_FAA4
+51D1 E0102; MSARG; ME_51D1_001
51D2 E0100; Adobe-Japan1; CID+21186
51D3 E0100; Adobe-Japan1; CID+19179
51D4 E0100; Adobe-Japan1; CID+19180
@@ -4443,6 +4462,8 @@
53D6 E0100; Adobe-Japan1; CID+2324
53D7 E0100; Adobe-Japan1; CID+2337
53D7 E0101; Adobe-Japan1; CID+13813
+53D8 E0100; MSARG; MA_895A
+53D8 E0101; MSARG; ME_53D8_001
53D9 E0100; Adobe-Japan1; CID+2432
53DA E0100; Adobe-Japan1; CID+14372
53DB E0100; Adobe-Japan1; CID+3412
@@ -4943,6 +4964,8 @@
555A E0102; Hanyo-Denshi; KS044550
555A E0102; Moji_Joho; MJ008401
555A E0103; Moji_Joho; MJ057180
+555A E0104; MSARG; MD_555A
+555A E0105; MSARG; ME_555A_001
555B E0100; Adobe-Japan1; CID+21282
555C E0100; Adobe-Japan1; CID+4392
555D E0100; Adobe-Japan1; CID+4398
@@ -4951,6 +4974,8 @@
555D E0102; Hanyo-Denshi; JTAEDA
555D E0102; Moji_Joho; MJ008405
555E E0100; Adobe-Japan1; CID+7633
+555F E0100; MSARG; MB_B1D2
+555F E0101; MSARG; ME_555F_001
5560 E0100; Adobe-Japan1; CID+14392
5561 E0100; Adobe-Japan1; CID+20308
5561 E0101; Adobe-Japan1; CID+14393
@@ -4961,6 +4986,8 @@
5568 E0100; Moji_Joho; MJ008415
5568 E0101; Hanyo-Denshi; IB1035
5568 E0101; Moji_Joho; MJ008416
+556B E0100; MSARG; MA_94DC
+556B E0101; MSARG; ME_556B_001
557B E0100; Adobe-Japan1; CID+4404
557C E0100; Adobe-Japan1; CID+4409
557C E0101; Hanyo-Denshi; JA5138
@@ -5428,6 +5455,8 @@
56A0 E0102; Hanyo-Denshi; JTAF22
56A0 E0102; Moji_Joho; MJ008750
56A2 E0100; Adobe-Japan1; CID+3311
+56A4 E0100; MSARG; MA_97A3
+56A4 E0101; MSARG; ME_56A4_001
56A5 E0100; Adobe-Japan1; CID+4446
56A5 E0101; Adobe-Japan1; CID+7822
56A5 E0102; Hanyo-Denshi; JA5175
@@ -6654,6 +6683,8 @@
59F6 E0100; Adobe-Japan1; CID+1132
59F7 E0100; Adobe-Japan1; CID+21401
59F8 E0100; Adobe-Japan1; CID+19312
+59F8 E0101; MSARG; MA_9D55
+59F8 E0102; MSARG; ME_59F8_001
59FB E0100; Adobe-Japan1; CID+1213
59FF E0100; Adobe-Japan1; CID+2207
59FF E0101; Adobe-Japan1; CID+13792
@@ -6870,6 +6901,8 @@
5ACC E0103; Hanyo-Denshi; FT1791S
5ACC E0103; Moji_Joho; MJ009909
5ACF E0100; Adobe-Japan1; CID+21424
+5ACF E0101; MSARG; MA_92F4
+5ACF E0102; MSARG; ME_5ACF_001
5AD0 E0100; Adobe-Japan1; CID+4603
5AD6 E0100; Adobe-Japan1; CID+4596
5AD7 E0100; Adobe-Japan1; CID+4593
@@ -7540,6 +7573,8 @@
5C8D E0100; Moji_Joho; MJ010418
5C8D E0101; Hanyo-Denshi; JTB06C
5C8D E0101; Moji_Joho; MJ010419
+5C8D E0102; MSARG; MB_CAC0
+5C8D E0103; MSARG; ME_5C8D_001
5C8F E0100; Adobe-Japan1; CID+16840
5C90 E0100; Adobe-Japan1; CID+1584
5C91 E0100; Adobe-Japan1; CID+4663
@@ -7569,6 +7604,8 @@
5CAB E0100; Adobe-Japan1; CID+4666
5CAC E0100; Adobe-Japan1; CID+3764
5CAD E0100; Adobe-Japan1; CID+17557
+5CAD E0101; MSARG; MB_CC64
+5CAD E0102; MSARG; ME_5CAD_001
5CB1 E0100; Adobe-Japan1; CID+2866
5CB2 E0100; Adobe-Japan1; CID+21464
5CB3 E0100; Adobe-Japan1; CID+1463
@@ -10095,6 +10132,8 @@
62D0 E0103; Moji_Joho; MJ012273
62D0 E0104; Hanyo-Denshi; IB1917
62D0 E0104; Moji_Joho; MJ012274
+62D0 E0105; MSARG; MB_A9E4
+62D0 E0106; MSARG; ME_62D0_001
62D1 E0100; Adobe-Japan1; CID+4961
62D2 E0100; Adobe-Japan1; CID+1675
62D2 E0101; Adobe-Japan1; CID+13715
@@ -12633,6 +12672,8 @@
690D E0104; Hanyo-Denshi; KS170180
690D E0104; Moji_Joho; MJ057753
690D E0105; Hanyo-Denshi; TK01044570
+690D E0106; MSARG; MB_B4D3
+690D E0107; MSARG; ME_690D_001
690E E0100; Adobe-Japan1; CID+3043
690F E0100; Adobe-Japan1; CID+5206
6910 E0100; Adobe-Japan1; CID+21777
@@ -13038,6 +13079,8 @@
6A0B E0102; Moji_Joho; MJ014416
6A0B E0103; Hanyo-Denshi; FT1907
6A0B E0103; Moji_Joho; MJ014417
+6A0B E0104; MSARG; MA_FD42
+6A0B E0105; MSARG; ME_6A0B_001
6A0C E0100; Adobe-Japan1; CID+5295
6A0F E0100; Adobe-Japan1; CID+14658
6A11 E0100; Adobe-Japan1; CID+17851
@@ -13898,6 +13941,8 @@
6C67 E0102; Hanyo-Denshi; IB2201
6C67 E0102; Moji_Joho; MJ015090
6C67 E0103; Hanyo-Denshi; TK01049100
+6C67 E0104; MSARG; MB_CB4C
+6C67 E0105; MSARG; ME_6C67_001
6C68 E0100; Adobe-Japan1; CID+5392
6C6A E0100; Adobe-Japan1; CID+5385
6C6A E0101; Hanyo-Denshi; JA6174
@@ -14318,6 +14363,8 @@
6DCD E0100; Hanyo-Denshi; IP6DCD
6DCD E0101; Hanyo-Denshi; TK01050160
6DCE E0100; Adobe-Japan1; CID+17952
+6DCE E0101; MSARG; MD_6DCE
+6DCE E0102; MSARG; ME_6DCE_001
6DCF E0100; Adobe-Japan1; CID+8520
6DCF E0101; Hanyo-Denshi; JB3957
6DCF E0101; Moji_Joho; MJ015459
@@ -15270,6 +15317,8 @@
701E E0106; Hanyo-Denshi; IB2283
701E E0106; Moji_Joho; MJ016159
701E E0107; Hanyo-Denshi; TK01053770
+701E E0108; MSARG; MA_96EE
+701E E0109; MSARG; ME_701E_001
701F E0100; Adobe-Japan1; CID+5546
701F E0101; Hanyo-Denshi; JA6347
701F E0101; Moji_Joho; MJ016166
@@ -15692,6 +15741,8 @@
71A8 E0100; Adobe-Japan1; CID+5580
71AC E0100; Adobe-Japan1; CID+5581
71AE E0100; Adobe-Japan1; CID+18037
+71AE E0101; MSARG; MD_71AE
+71AE E0102; MSARG; ME_71AE_001
71AF E0100; Adobe-Japan1; CID+18038
71B0 E0100; Adobe-Japan1; CID+21938
71B1 E0100; Adobe-Japan1; CID+3300
@@ -15704,6 +15755,8 @@
71B3 E0103; Moji_Joho; MJ016595
71B9 E0100; Adobe-Japan1; CID+5583
71BA E0100; Adobe-Japan1; CID+16965
+71BB E0100; MSARG; MD_71BB
+71BB E0101; MSARG; ME_71BB_001
71BE E0100; Adobe-Japan1; CID+5584
71BE E0101; Hanyo-Denshi; JA6385
71BE E0101; Moji_Joho; MJ016605
@@ -15827,6 +15880,8 @@
7210 E0100; Adobe-Japan1; CID+5597
7213 E0100; Adobe-Japan1; CID+21946
7215 E0100; Adobe-Japan1; CID+16967
+7215 E0101; MSARG; MA_FE41
+7215 E0102; MSARG; ME_7215_001
7217 E0100; Adobe-Japan1; CID+19521
7217 E0101; Hanyo-Denshi; JB4235
7217 E0101; Moji_Joho; MJ016708
@@ -17688,6 +17743,8 @@
771F E0105; Moji_Joho; MJ018174
771F E0106; Hanyo-Denshi; TK01062480
771F E0107; Moji_Joho; MJ018175
+771F E0108; MSARG; MB_AF75
+771F E0109; MSARG; ME_771F_001
7720 E0100; Adobe-Japan1; CID+3774
7722 E0100; Adobe-Japan1; CID+19578
7724 E0100; Adobe-Japan1; CID+5815
@@ -18016,6 +18073,8 @@
784F E0101; Moji_Joho; MJ018495
784F E0102; Hanyo-Denshi; JTB674
784F E0102; Moji_Joho; MJ018496
+784F E0103; MSARG; MD_784F
+784F E0104; MSARG; ME_784F_001
7851 E0100; Adobe-Japan1; CID+15420
7852 E0100; Adobe-Japan1; CID+22078
785C E0100; Adobe-Japan1; CID+19603
@@ -19233,6 +19292,8 @@
7AAE E0103; Moji_Joho; MJ019272
7AAF E0100; Adobe-Japan1; CID+3900
7AB0 E0100; Adobe-Japan1; CID+5938
+7AB0 E0101; MSARG; MA_8E50
+7AB0 E0102; MSARG; ME_7AB0_001
7AB1 E0100; Hanyo-Denshi; IP7AB1
7AB1 E0101; Hanyo-Denshi; TK01068710
7AB3 E0100; Adobe-Japan1; CID+14931
@@ -19444,6 +19505,8 @@
7B51 E0103; Moji_Joho; MJ019458
7B51 E0104; Hanyo-Denshi; JTB7A5
7B51 E0104; Moji_Joho; MJ019456
+7B51 E0105; MSARG; MB_B5AE
+7B51 E0106; MSARG; ME_7B51_001
7B52 E0100; Adobe-Japan1; CID+3189
7B53 E0100; Adobe-Japan1; CID+14173
7B53 E0101; Hanyo-Denshi; IP7B53
@@ -20362,6 +20425,8 @@
7D86 E0103; Moji_Joho; MJ020134
7D88 E0100; Adobe-Japan1; CID+18353
7D89 E0100; Adobe-Japan1; CID+6084
+7D89 E0101; MSARG; MA_8EA7
+7D89 E0102; MSARG; ME_7D89_001
7D8B E0100; Adobe-Japan1; CID+14980
7D8C E0100; Adobe-Japan1; CID+14981
7D8D E0100; Adobe-Japan1; CID+19665
@@ -20427,6 +20492,8 @@
7DAA E0102; Hanyo-Denshi; IB0846
7DAA E0102; Moji_Joho; MJ020184
7DAB E0100; Adobe-Japan1; CID+6095
+7DAB E0101; MSARG; MA_8EA8
+7DAB E0102; MSARG; ME_7DAB_001
7DAC E0100; Adobe-Japan1; CID+2342
7DAD E0100; Adobe-Japan1; CID+1185
7DAD E0101; Hanyo-Denshi; JA1661
@@ -21226,6 +21293,8 @@
7FEB E0103; Moji_Joho; MJ020716
7FEB E0104; Moji_Joho; MJ020718
7FEC E0100; Adobe-Japan1; CID+15007
+7FEC E0101; MSARG; MB_E6F8
+7FEC E0102; MSARG; ME_7FEC_001
7FEE E0100; Adobe-Japan1; CID+15008
7FEF E0100; Adobe-Japan1; CID+15009
7FF0 E0100; Adobe-Japan1; CID+1545
@@ -21238,6 +21307,8 @@
7FF0 E0104; Moji_Joho; MJ020725
7FF0 E0105; Hanyo-Denshi; TK01074020
7FF0 E0106; Hanyo-Denshi; TK01074040
+7FF1 E0100; MSARG; MB_BFAC
+7FF1 E0101; MSARG; ME_7FF1_001
7FF2 E0100; Adobe-Japan1; CID+18402
7FF3 E0100; Adobe-Japan1; CID+6199
7FF3 E0101; Hanyo-Denshi; JA7042
@@ -21250,6 +21321,9 @@
7FF9 E0102; Hanyo-Denshi; FT2443
7FF9 E0102; Moji_Joho; MJ020737
7FFA E0100; Adobe-Japan1; CID+15010
+7FFA E0101; MSARG; MA_8ECB
+7FFA E0102; MSARG; ME_7FFA_001
+7FFA E0103; MSARG; ME_7FFA_002
7FFB E0100; Adobe-Japan1; CID+3723
7FFB E0101; Adobe-Japan1; CID+14040
7FFB E0102; Hanyo-Denshi; JA4361
@@ -23080,6 +23154,8 @@
833A E0101; Moji_Joho; MJ021843
833A E0102; Hanyo-Denshi; KS346690S
833A E0102; Moji_Joho; MJ021844
+833A E0103; MSARG; MB_D072
+833A E0104; MSARG; ME_833A_001
833C E0100; Adobe-Japan1; CID+18489
833C E0101; Hanyo-Denshi; JB5581
833C E0101; Moji_Joho; MJ021846
@@ -23543,6 +23619,8 @@
83C1 E0104; Hanyo-Denshi; FT2479
83C1 E0104; Moji_Joho; MJ022062
83C1 E0105; Hanyo-Denshi; TK01078230
+83C1 E0106; MSARG; MB_B5D7
+83C1 E0107; MSARG; ME_83C1_001
83C2 E0100; Hanyo-Denshi; KS350410
83C2 E0101; Hanyo-Denshi; TK01078690
83C5 E0100; Adobe-Japan1; CID+2625
@@ -24360,6 +24438,8 @@
84A8 E0103; Hanyo-Denshi; IB0865
84A8 E0103; Moji_Joho; MJ022481
84A8 E0104; Hanyo-Denshi; TK01080090
+84A8 E0105; MSARG; MB_E3C8
+84A8 E0106; MSARG; ME_84A8_001
84A9 E0100; Adobe-Japan1; CID+22350
84A9 E0101; Hanyo-Denshi; JB5680
84A9 E0101; Moji_Joho; MJ022484
@@ -24871,6 +24951,8 @@
8534 E0101; Moji_Joho; MJ022738
8534 E0102; Hanyo-Denshi; KS360300
8534 E0102; Moji_Joho; MJ022739
+8534 E0103; MSARG; MA_8F77
+8534 E0104; MSARG; ME_8534_001
8535 E0100; Adobe-Japan1; CID+2818
8535 E0101; Hanyo-Denshi; JA3402
8535 E0102; Hanyo-Denshi; TK01081050
@@ -26682,6 +26764,7 @@
8846 E0106; Hanyo-Denshi; TK01083450
8846 E0107; MSARG; MA_8FBC
8846 E0108; MSARG; ME_8846_001
+8846 E0109; MSARG; ME_8846_002
8848 E0100; Adobe-Japan1; CID+22465
8849 E0100; Adobe-Japan1; CID+22466
884A E0100; Adobe-Japan1; CID+18635
@@ -27969,6 +28052,8 @@
8B66 E0101; Moji_Joho; MJ024795
8B66 E0102; Hanyo-Denshi; KS408750S
8B66 E0102; Moji_Joho; MJ024796
+8B67 E0100; MSARG; MB_F4D4
+8B67 E0101; MSARG; ME_8B67_001
8B69 E0100; Adobe-Japan1; CID+17130
8B69 E0101; Hanyo-Denshi; JC9220
8B69 E0101; Moji_Joho; MJ024799
@@ -28664,6 +28749,8 @@
8E26 E0100; Adobe-Japan1; CID+19850
8E27 E0100; Adobe-Japan1; CID+18732
8E2A E0100; Adobe-Japan1; CID+6824
+8E2D E0100; MSARG; MA_9E5A
+8E2D E0101; MSARG; ME_8E2D_001
8E30 E0100; Adobe-Japan1; CID+6813
8E30 E0101; Hanyo-Denshi; JA7692
8E30 E0101; Moji_Joho; MJ025364
@@ -30340,6 +30427,8 @@
90A8 E0103; Moji_Joho; MJ026250
90A8 E0104; Hanyo-Denshi; TK01090660
90A8 E0105; Hanyo-Denshi; TK01090690
+90A8 E0106; MSARG; MA_9068
+90A8 E0107; MSARG; ME_90A8_001
90AA E0100; Adobe-Japan1; CID+2309
90AA E0101; Adobe-Japan1; CID+13454
90AA E0102; Adobe-Japan1; CID+13806
@@ -30615,6 +30704,8 @@
9175 E0101; Moji_Joho; MJ026482
9175 E0102; Hanyo-Denshi; JTBDA9
9175 E0102; Moji_Joho; MJ026483
+9176 E0100; MSARG; MA_9E4A
+9176 E0101; MSARG; ME_9176_001
9177 E0100; Adobe-Japan1; CID+2053
9177 E0101; Adobe-Japan1; CID+13776
9177 E0102; Hanyo-Denshi; JA2583
@@ -31073,6 +31164,8 @@
92B7 E0102; Moji_Joho; MJ026858
92B8 E0100; Adobe-Japan1; CID+22751
92B9 E0100; Adobe-Japan1; CID+6997
+92B9 E0101; MSARG; MA_F9D7
+92B9 E0102; MSARG; ME_92B9_001
92BA E0100; Adobe-Japan1; CID+22752
92BB E0100; Adobe-Japan1; CID+19920
92BC E0100; Adobe-Japan1; CID+19921
@@ -31310,6 +31403,8 @@
936E E0101; Moji_Joho; MJ027061
936E E0102; Hanyo-Denshi; FT2650
936E E0102; Moji_Joho; MJ027062
+936E E0103; MSARG; MA_A05F
+936E E0104; MSARG; ME_936E_001
936F E0100; Adobe-Japan1; CID+22777
9370 E0100; Adobe-Japan1; CID+8676
9371 E0100; Adobe-Japan1; CID+18852
@@ -32094,6 +32189,8 @@
96B6 E0101; Moji_Joho; MJ027706
96B6 E0102; Hanyo-Denshi; KS475490
96B6 E0102; Moji_Joho; MJ027705
+96B6 E0103; MSARG; MA_90C4
+96B6 E0104; MSARG; ME_96B6_001
96B7 E0100; Adobe-Japan1; CID+4020
96B8 E0100; Adobe-Japan1; CID+7114
96B9 E0100; Adobe-Japan1; CID+7115
@@ -32370,6 +32467,8 @@
9759 E0102; Hanyo-Denshi; JA3237
9759 E0103; Hanyo-Denshi; TK01097430
9759 E0104; Hanyo-Denshi; TK01097490
+9759 E0105; MSARG; MD_9759
+9759 E0106; MSARG; ME_9759_001
975A E0100; Adobe-Japan1; CID+15275
975A E0101; Hanyo-Denshi; JB7121
975A E0101; Moji_Joho; MJ027909
@@ -32392,6 +32491,8 @@
975C E0105; Moji_Joho; MJ027915
975C E0106; Hanyo-Denshi; TK01097530
975C E0107; Hanyo-Denshi; TK01097550
+975C E0108; MSARG; MB_C052
+975C E0109; MSARG; ME_975C_001
975D E0100; Hanyo-Denshi; IB1040
975D E0100; Moji_Joho; MJ027919
975D E0101; Hanyo-Denshi; IP975D
@@ -32439,6 +32540,8 @@
976D E0103; Moji_Joho; MJ027942
976D E0104; Hanyo-Denshi; HG1633
976D E0104; Moji_Joho; MJ027941
+976D E0105; MSARG; MA_9E46
+976D E0106; MSARG; ME_976D_001
976E E0100; Adobe-Japan1; CID+15277
9771 E0100; Adobe-Japan1; CID+7152
9771 E0101; Adobe-Japan1; CID+7710
@@ -32593,6 +32696,8 @@
97C8 E0103; Moji_Joho; MJ028052
97C8 E0104; Hanyo-Denshi; FT2682
97C8 E0104; Moji_Joho; MJ028054
+97C8 E0105; MSARG; MA_9F76
+97C8 E0106; MSARG; ME_97C8_001
97C9 E0100; Adobe-Japan1; CID+17192
97C9 E0101; Hanyo-Denshi; JB7160
97C9 E0101; Moji_Joho; MJ028055
@@ -33066,6 +33171,7 @@
98EB E0103; Moji_Joho; MJ028358
98EC E0100; MSARG; MA_914B
98EC E0101; MSARG; ME_98EC_001
+98EC E0102; MSARG; ME_98EC_002
98ED E0100; Adobe-Japan1; CID+4289
98ED E0101; Hanyo-Denshi; JA5012
98ED E0101; Moji_Joho; MJ028362
@@ -33366,6 +33472,8 @@
9936 E0100; Moji_Joho; MJ028491
9936 E0101; Hanyo-Denshi; IP9936
9936 E0101; Moji_Joho; MJ028492
+9938 E0100; MSARG; MA_9652
+9938 E0101; MSARG; ME_9938_001
9939 E0100; Adobe-Japan1; CID+22892
9939 E0101; Hanyo-Denshi; JB7268
9939 E0101; Moji_Joho; MJ028494
@@ -33844,6 +33952,8 @@
9A5F E0103; Hanyo-Denshi; KS510550
9A5F E0103; Moji_Joho; MJ028831
9A62 E0100; Adobe-Japan1; CID+7261
+9A63 E0100; MSARG; MA_9557
+9A63 E0101; MSARG; ME_9A63_001
9A64 E0100; Adobe-Japan1; CID+7263
9A65 E0100; Adobe-Japan1; CID+7262
9A65 E0101; Adobe-Japan1; CID+14268
@@ -35128,6 +35238,8 @@
9ED8 E0102; Hanyo-Denshi; FT2329
9ED8 E0102; Moji_Joho; MJ029902
9ED9 E0100; Adobe-Japan1; CID+3815
+9ED9 E0101; MSARG; MD_9ED9
+9ED9 E0102; MSARG; ME_9ED9_001
9EDB E0100; Adobe-Japan1; CID+2883
9EDB E0101; Adobe-Japan1; CID+7729
9EDB E0102; Hanyo-Denshi; JA3467
@@ -35813,6 +35925,8 @@ FA29 E0100; Adobe-Japan1; CID+8687
206EE E0101; Moji_Joho; MJ031295
206F9 E0100; Moji_Joho; MJ031302
206F9 E0101; Moji_Joho; MJ031303
+2070E E0100; MSARG; MA_92C3
+2070E E0101; MSARG; ME_2070E_001
2071B E0100; Hanyo-Denshi; KS023680
2071B E0101; Hanyo-Denshi; TK01009920
2074F E0100; Adobe-Japan1; CID+17312
@@ -36093,6 +36207,8 @@ FA29 E0100; Adobe-Japan1; CID+8687
21764 E0100; Moji_Joho; MJ033638
21764 E0101; Hanyo-Denshi; KS073700
21764 E0101; Moji_Joho; MJ057303
+217B5 E0100; MSARG; MA_96FD
+217B5 E0101; MSARG; ME_217B5_001
21800 E0100; Hanyo-Denshi; TK01020690
21800 E0101; Hanyo-Denshi; TK01020760
21898 E0100; Hanyo-Denshi; KS077190
@@ -36168,6 +36284,8 @@ FA29 E0100; Adobe-Japan1; CID+8687
21D45 E0100; Adobe-Japan1; CID+17545
21D58 E0100; Hanyo-Denshi; KS089870
21D58 E0101; Hanyo-Denshi; TK01024500
+21D5E E0100; MSARG; MA_876E
+21D5E E0101; MSARG; ME_21D5E_001
21D62 E0100; Adobe-Japan1; CID+17547
21D78 E0100; Adobe-Japan1; CID+17546
21D92 E0100; Adobe-Japan1; CID+17556
@@ -36660,6 +36778,8 @@ FA29 E0100; Adobe-Japan1; CID+8687
23780 E0101; Hanyo-Denshi; JTB3B8
23780 E0101; Moji_Joho; MJ038377
23780 E0102; Hanyo-Denshi; TK01046760
+237C2 E0100; MSARG; MA_FCF0
+237C2 E0101; MSARG; ME_237C2_001
237E7 E0100; Adobe-Japan1; CID+17875
237E7 E0101; Hanyo-Denshi; JD1574
237E7 E0101; Moji_Joho; MJ038420
@@ -36986,6 +37106,8 @@ FA29 E0100; Adobe-Japan1; CID+8687
254C9 E0101; Hanyo-Denshi; TK01063840
254D9 E0100; Adobe-Japan1; CID+18217
2550E E0100; Adobe-Japan1; CID+17009
+25584 E0100; MSARG; MA_93C3
+25584 E0101; MSARG; ME_25584_001
255A7 E0100; Adobe-Japan1; CID+18229
25607 E0100; Hanyo-Denshi; IB0328
25607 E0100; Moji_Joho; MJ042965
@@ -37297,6 +37419,8 @@ FA29 E0100; Adobe-Japan1; CID+8687
263C1 E0101; Hanyo-Denshi; JTC0CA
263C1 E0101; Moji_Joho; MJ045051
263C1 E0102; Moji_Joho; MJ045050
+263F9 E0100; MSARG; MD_263F9
+263F9 E0101; MSARG; ME_263F9_001
26402 E0100; Adobe-Japan1; CID+18398
26405 E0100; Hanyo-Denshi; KS319810
26405 E0101; Hanyo-Denshi; TK01073730
@@ -37311,12 +37435,18 @@ FA29 E0100; Adobe-Japan1; CID+8687
26408 E0102; Hanyo-Denshi; TK01073790
26409 E0100; Hanyo-Denshi; KS319910
26409 E0101; Hanyo-Denshi; TK01073770
+26410 E0100; MSARG; MA_90CC
+26410 E0101; MSARG; ME_26410_001
+26439 E0100; MSARG; MD_26439
+26439 E0101; MSARG; ME_26439_001
26462 E0100; Hanyo-Denshi; KS321040
26462 E0100; Moji_Joho; MJ045176
26462 E0101; Hanyo-Denshi; KS321270
26462 E0101; Moji_Joho; MJ045177
26489 E0100; Hanyo-Denshi; TK01007100
26489 E0101; Hanyo-Denshi; TK01074030
+26489 E0102; MSARG; MA_8ECC
+26489 E0103; MSARG; ME_26489_001
264B3 E0100; Hanyo-Denshi; KS322190
264B3 E0100; Moji_Joho; MJ058361
264B3 E0101; Hanyo-Denshi; KS322200S
@@ -37581,6 +37711,8 @@ FA29 E0100; Adobe-Japan1; CID+8687
27088 E0101; Hanyo-Denshi; TK01082110
270F0 E0100; Hanyo-Denshi; KS369820
270F0 E0101; Hanyo-Denshi; TK01082380
+270F0 E0102; MSARG; MA_8FA8
+270F0 E0103; MSARG; ME_270F0_001
270F4 E0100; Adobe-Japan1; CID+17103
270F4 E0101; Hanyo-Denshi; JC9141
270F4 E0101; Moji_Joho; MJ047259
@@ -37698,6 +37830,8 @@ FA29 E0100; Adobe-Japan1; CID+8687
2770F E0100; Moji_Joho; MJ048373
2770F E0101; Moji_Joho; MJ048374
27723 E0100; Adobe-Japan1; CID+18652
+27741 E0100; MSARG; MA_94C7
+27741 E0101; MSARG; ME_27741_001
27752 E0100; Adobe-Japan1; CID+18656
27753 E0100; Hanyo-Denshi; KS393290
27753 E0100; Moji_Joho; MJ048418
@@ -39019,6 +39153,8 @@ FA29 E0100; Adobe-Japan1; CID+8687
2CF4C E0101; Moji_Joho; MJ056893
2CF4C E0102; Moji_Joho; MJ056894
2CF4C E0103; Moji_Joho; MJ056898
+2CF7A E0100; MSARG; MC_00045
+2CF7A E0101; MSARG; ME_2CF7A_001
2D020 E0100; Moji_Joho; MJ056969
2D020 E0101; Moji_Joho; MJ056970
2D028 E0100; Moji_Joho; MJ059338
diff --git a/admin/unidata/Makefile.in b/admin/unidata/Makefile.in
index 357b8126783..701fb92b817 100644
--- a/admin/unidata/Makefile.in
+++ b/admin/unidata/Makefile.in
@@ -41,7 +41,7 @@ unifiles = $(addprefix ${unidir}/,$(sort $(shell sed -n 's/^[ \t][ \t]*${lparen}
.PHONY: all
all: ${top_srcdir}/src/macuvs.h ${unifiles} ${unidir}/charscript.el \
- ${unidir}/charprop.el
+ ${unidir}/charprop.el ${unidir}/emoji-zwj.el ${unidir}/emoji-labels.el
## Specify .elc as an order-only prereq so as to not needlessly rebuild
## target just because the .elc is missing.
@@ -72,18 +72,30 @@ ${unifiles}: ${srcdir}/unidata-gen.el \
${srcdir}/BidiBrackets.txt | \
${srcdir}/unidata-gen.elc unidata.txt
$(AM_V_at)[ ! -f $@ ] || chmod +w $@
- $(AM_V_GEN)${emacs} -L ${srcdir} -l unidata-gen \
+ $(AM_V_at)${emacs} -L ${srcdir} -l unidata-gen \
-f unidata-gen-file $@ ${srcdir}
+${unidir}/emoji-labels.el: ${unidir}/../international/emoji.el \
+ ${srcdir}/emoji-test.txt
+ $(AM_V_at)${emacs} -l emoji.el -f emoji--generate-file $@
.PHONY: charscript.el
charscript.el: ${unidir}/charscript.el
blocks = ${srcdir}/blocks.awk
-${unidir}/charscript.el: ${srcdir}/Blocks.txt ${blocks}
- $(AM_V_GEN)$(AWK) -f ${blocks} < $< > $@
+${unidir}/charscript.el: ${blocks}
+
+${unidir}/charscript.el: ${srcdir}/Blocks.txt ${srcdir}/emoji-data.txt
+ $(AM_V_GEN)$(AWK) -f ${blocks} $^ > $@
+
+.PHONY: emoji-zwj.el
+emoji-zwj.el: ${unidir}/emoji-zwj.el
+
+zwj = ${srcdir}/emoji-zwj.awk
+${unidir}/emoji-zwj.el: ${srcdir}/emoji-zwj-sequences.txt $(srcdir)/emoji-sequences.txt ${zwj}
+ $(AM_V_GEN)$(AWK) -f ${zwj} $^ > $@
.PHONY: clean bootstrap-clean distclean maintainer-clean gen-clean
@@ -102,7 +114,9 @@ distclean: clean
## from a make target, we don't delete it here.
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*
## 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 fa9b0d954c8..302c35f37c7 100644
--- a/admin/unidata/NormalizationTest.txt
+++ b/admin/unidata/NormalizationTest.txt
@@ -1,6 +1,6 @@
-# NormalizationTest-13.0.0.txt
-# Date: 2019-09-08, 23:31:12 GMT
-# © 2019 Unicode®, Inc.
+# NormalizationTest-14.0.0.txt
+# Date: 2021-05-28, 21:49:12 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
#
@@ -2409,6 +2409,9 @@
A69C;A69C;A69C;044A;044A; # (ꚜ; ꚜ; ꚜ; ъ; ъ; ) MODIFIER LETTER CYRILLIC HARD SIGN
A69D;A69D;A69D;044C;044C; # (ꚝ; ꚝ; ꚝ; ь; ь; ) MODIFIER LETTER CYRILLIC SOFT SIGN
A770;A770;A770;A76F;A76F; # (ꝰ; ꝰ; ꝰ; ꝯ; ꝯ; ) MODIFIER LETTER US
+A7F2;A7F2;A7F2;0043;0043; # (ꟲ; ꟲ; ꟲ; C; C; ) MODIFIER LETTER CAPITAL C
+A7F3;A7F3;A7F3;0046;0046; # (ꟳ; ꟳ; ꟳ; F; F; ) MODIFIER LETTER CAPITAL F
+A7F4;A7F4;A7F4;0051;0051; # (ꟴ; ꟴ; ꟴ; Q; Q; ) MODIFIER LETTER CAPITAL Q
A7F8;A7F8;A7F8;0126;0126; # (ꟸ; ꟸ; ꟸ; Ħ; Ħ; ) MODIFIER LETTER CAPITAL H WITH STROKE
A7F9;A7F9;A7F9;0153;0153; # (ꟹ; ꟹ; ꟹ; œ; œ; ) MODIFIER LETTER SMALL LIGATURE OE
AB5C;AB5C;AB5C;A727;A727; # (ꭜ; ꭜ; ꭜ; ꜧ; ꜧ; ) MODIFIER LETTER SMALL HENG
@@ -15127,6 +15130,62 @@ FFEB;FFEB;FFEB;2192;2192; # (→; →; →; →; →; ) HALFWIDTH RIGHTWARDS ARR
FFEC;FFEC;FFEC;2193;2193; # (↓; ↓; ↓; ↓; ↓; ) HALFWIDTH DOWNWARDS ARROW
FFED;FFED;FFED;25A0;25A0; # (■; ■; ■; ■; ■; ) HALFWIDTH BLACK SQUARE
FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
+10781;10781;10781;02D0;02D0; # (𐞁; 𐞁; 𐞁; ː; ː; ) MODIFIER LETTER SUPERSCRIPT TRIANGULAR COLON
+10782;10782;10782;02D1;02D1; # (𐞂; 𐞂; 𐞂; ˑ; ˑ; ) MODIFIER LETTER SUPERSCRIPT HALF TRIANGULAR COLON
+10783;10783;10783;00E6;00E6; # (𐞃; 𐞃; 𐞃; æ; æ; ) MODIFIER LETTER SMALL AE
+10784;10784;10784;0299;0299; # (𐞄; 𐞄; 𐞄; ʙ; ʙ; ) MODIFIER LETTER SMALL CAPITAL B
+10785;10785;10785;0253;0253; # (𐞅; 𐞅; 𐞅; ɓ; ɓ; ) MODIFIER LETTER SMALL B WITH HOOK
+10787;10787;10787;02A3;02A3; # (𐞇; 𐞇; 𐞇; ʣ; ʣ; ) MODIFIER LETTER SMALL DZ DIGRAPH
+10788;10788;10788;AB66;AB66; # (𐞈; 𐞈; 𐞈; ꭦ; ꭦ; ) MODIFIER LETTER SMALL DZ DIGRAPH WITH RETROFLEX HOOK
+10789;10789;10789;02A5;02A5; # (𐞉; 𐞉; 𐞉; ʥ; ʥ; ) MODIFIER LETTER SMALL DZ DIGRAPH WITH CURL
+1078A;1078A;1078A;02A4;02A4; # (𐞊; 𐞊; 𐞊; ʤ; ʤ; ) MODIFIER LETTER SMALL DEZH DIGRAPH
+1078B;1078B;1078B;0256;0256; # (𐞋; 𐞋; 𐞋; ɖ; ɖ; ) MODIFIER LETTER SMALL D WITH TAIL
+1078C;1078C;1078C;0257;0257; # (𐞌; 𐞌; 𐞌; ɗ; ɗ; ) MODIFIER LETTER SMALL D WITH HOOK
+1078D;1078D;1078D;1D91;1D91; # (𐞍; 𐞍; 𐞍; ᶑ; ᶑ; ) MODIFIER LETTER SMALL D WITH HOOK AND TAIL
+1078E;1078E;1078E;0258;0258; # (𐞎; 𐞎; 𐞎; ɘ; ɘ; ) MODIFIER LETTER SMALL REVERSED E
+1078F;1078F;1078F;025E;025E; # (𐞏; 𐞏; 𐞏; ɞ; ɞ; ) MODIFIER LETTER SMALL CLOSED REVERSED OPEN E
+10790;10790;10790;02A9;02A9; # (𐞐; 𐞐; 𐞐; ʩ; ʩ; ) MODIFIER LETTER SMALL FENG DIGRAPH
+10791;10791;10791;0264;0264; # (𐞑; 𐞑; 𐞑; ɤ; ɤ; ) MODIFIER LETTER SMALL RAMS HORN
+10792;10792;10792;0262;0262; # (𐞒; 𐞒; 𐞒; ɢ; ɢ; ) MODIFIER LETTER SMALL CAPITAL G
+10793;10793;10793;0260;0260; # (𐞓; 𐞓; 𐞓; ɠ; ɠ; ) MODIFIER LETTER SMALL G WITH HOOK
+10794;10794;10794;029B;029B; # (𐞔; 𐞔; 𐞔; ʛ; ʛ; ) MODIFIER LETTER SMALL CAPITAL G WITH HOOK
+10795;10795;10795;0127;0127; # (𐞕; 𐞕; 𐞕; ħ; ħ; ) MODIFIER LETTER SMALL H WITH STROKE
+10796;10796;10796;029C;029C; # (𐞖; 𐞖; 𐞖; ʜ; ʜ; ) MODIFIER LETTER SMALL CAPITAL H
+10797;10797;10797;0267;0267; # (𐞗; 𐞗; 𐞗; ɧ; ɧ; ) MODIFIER LETTER SMALL HENG WITH HOOK
+10798;10798;10798;0284;0284; # (𐞘; 𐞘; 𐞘; ʄ; ʄ; ) MODIFIER LETTER SMALL DOTLESS J WITH STROKE AND HOOK
+10799;10799;10799;02AA;02AA; # (𐞙; 𐞙; 𐞙; ʪ; ʪ; ) MODIFIER LETTER SMALL LS DIGRAPH
+1079A;1079A;1079A;02AB;02AB; # (𐞚; 𐞚; 𐞚; ʫ; ʫ; ) MODIFIER LETTER SMALL LZ DIGRAPH
+1079B;1079B;1079B;026C;026C; # (𐞛; 𐞛; 𐞛; ɬ; ɬ; ) MODIFIER LETTER SMALL L WITH BELT
+1079C;1079C;1079C;1DF04;1DF04; # (𐞜; 𐞜; 𐞜; 𝼄; 𝼄; ) MODIFIER LETTER SMALL CAPITAL L WITH BELT
+1079D;1079D;1079D;A78E;A78E; # (𐞝; 𐞝; 𐞝; ꞎ; ꞎ; ) MODIFIER LETTER SMALL L WITH RETROFLEX HOOK AND BELT
+1079E;1079E;1079E;026E;026E; # (𐞞; 𐞞; 𐞞; ɮ; ɮ; ) MODIFIER LETTER SMALL LEZH
+1079F;1079F;1079F;1DF05;1DF05; # (𐞟; 𐞟; 𐞟; 𝼅; 𝼅; ) MODIFIER LETTER SMALL LEZH WITH RETROFLEX HOOK
+107A0;107A0;107A0;028E;028E; # (𐞠; 𐞠; 𐞠; ʎ; ʎ; ) MODIFIER LETTER SMALL TURNED Y
+107A1;107A1;107A1;1DF06;1DF06; # (𐞡; 𐞡; 𐞡; 𝼆; 𝼆; ) MODIFIER LETTER SMALL TURNED Y WITH BELT
+107A2;107A2;107A2;00F8;00F8; # (𐞢; 𐞢; 𐞢; ø; ø; ) MODIFIER LETTER SMALL O WITH STROKE
+107A3;107A3;107A3;0276;0276; # (𐞣; 𐞣; 𐞣; ɶ; ɶ; ) MODIFIER LETTER SMALL CAPITAL OE
+107A4;107A4;107A4;0277;0277; # (𐞤; 𐞤; 𐞤; ɷ; ɷ; ) MODIFIER LETTER SMALL CLOSED OMEGA
+107A5;107A5;107A5;0071;0071; # (𐞥; 𐞥; 𐞥; q; q; ) MODIFIER LETTER SMALL Q
+107A6;107A6;107A6;027A;027A; # (𐞦; 𐞦; 𐞦; ɺ; ɺ; ) MODIFIER LETTER SMALL TURNED R WITH LONG LEG
+107A7;107A7;107A7;1DF08;1DF08; # (𐞧; 𐞧; 𐞧; 𝼈; 𝼈; ) MODIFIER LETTER SMALL TURNED R WITH LONG LEG AND RETROFLEX HOOK
+107A8;107A8;107A8;027D;027D; # (𐞨; 𐞨; 𐞨; ɽ; ɽ; ) MODIFIER LETTER SMALL R WITH TAIL
+107A9;107A9;107A9;027E;027E; # (𐞩; 𐞩; 𐞩; ɾ; ɾ; ) MODIFIER LETTER SMALL R WITH FISHHOOK
+107AA;107AA;107AA;0280;0280; # (𐞪; 𐞪; 𐞪; ʀ; ʀ; ) MODIFIER LETTER SMALL CAPITAL R
+107AB;107AB;107AB;02A8;02A8; # (𐞫; 𐞫; 𐞫; ʨ; ʨ; ) MODIFIER LETTER SMALL TC DIGRAPH WITH CURL
+107AC;107AC;107AC;02A6;02A6; # (𐞬; 𐞬; 𐞬; ʦ; ʦ; ) MODIFIER LETTER SMALL TS DIGRAPH
+107AD;107AD;107AD;AB67;AB67; # (𐞭; 𐞭; 𐞭; ꭧ; ꭧ; ) MODIFIER LETTER SMALL TS DIGRAPH WITH RETROFLEX HOOK
+107AE;107AE;107AE;02A7;02A7; # (𐞮; 𐞮; 𐞮; ʧ; ʧ; ) MODIFIER LETTER SMALL TESH DIGRAPH
+107AF;107AF;107AF;0288;0288; # (𐞯; 𐞯; 𐞯; ʈ; ʈ; ) MODIFIER LETTER SMALL T WITH RETROFLEX HOOK
+107B0;107B0;107B0;2C71;2C71; # (𐞰; 𐞰; 𐞰; ⱱ; ⱱ; ) MODIFIER LETTER SMALL V WITH RIGHT HOOK
+107B2;107B2;107B2;028F;028F; # (𐞲; 𐞲; 𐞲; ʏ; ʏ; ) MODIFIER LETTER SMALL CAPITAL Y
+107B3;107B3;107B3;02A1;02A1; # (𐞳; 𐞳; 𐞳; ʡ; ʡ; ) MODIFIER LETTER GLOTTAL STOP WITH STROKE
+107B4;107B4;107B4;02A2;02A2; # (𐞴; 𐞴; 𐞴; ʢ; ʢ; ) MODIFIER LETTER REVERSED GLOTTAL STOP WITH STROKE
+107B5;107B5;107B5;0298;0298; # (𐞵; 𐞵; 𐞵; ʘ; ʘ; ) MODIFIER LETTER BILABIAL CLICK
+107B6;107B6;107B6;01C0;01C0; # (𐞶; 𐞶; 𐞶; ǀ; ǀ; ) MODIFIER LETTER DENTAL CLICK
+107B7;107B7;107B7;01C1;01C1; # (𐞷; 𐞷; 𐞷; ǁ; ǁ; ) MODIFIER LETTER LATERAL CLICK
+107B8;107B8;107B8;01C2;01C2; # (𐞸; 𐞸; 𐞸; ǂ; ǂ; ) MODIFIER LETTER ALVEOLAR CLICK
+107B9;107B9;107B9;1DF0A;1DF0A; # (𐞹; 𐞹; 𐞹; 𝼊; 𝼊; ) MODIFIER LETTER RETROFLEX CLICK WITH RETROFLEX HOOK
+107BA;107BA;107BA;1DF1E;1DF1E; # (𐞺; 𐞺; 𐞺; 𝼞; 𝼞; ) MODIFIER LETTER SMALL S WITH CURL
1109A;1109A;11099 110BA;1109A;11099 110BA; # (𑂚; 𑂚; 𑂙◌𑂺; 𑂚; 𑂙◌𑂺; ) KAITHI LETTER DDDHA
1109C;1109C;1109B 110BA;1109C;1109B 110BA; # (𑂜; 𑂜; 𑂛◌𑂺; 𑂜; 𑂛◌𑂺; ) KAITHI LETTER RHA
110AB;110AB;110A5 110BA;110AB;110A5 110BA; # (𑂫; 𑂫; 𑂥◌𑂺; 𑂫; 𑂥◌𑂺; ) KAITHI LETTER VA
@@ -17025,66 +17084,66 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 0314 0315 0300 05AE 0062;0061 05AE 0314 0300 0315 0062;0061 05AE 0314 0300 0315 0062;0061 05AE 0314 0300 0315 0062;0061 05AE 0314 0300 0315 0062; # (a◌̔◌̕◌̀◌֮b; a◌֮◌̔◌̀◌̕b; a◌֮◌̔◌̀◌̕b; a◌֮◌̔◌̀◌̕b; a◌֮◌̔◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING REVERSED COMMA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 035C 0315 0300 0315 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 035C 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 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, COMBINING COMMA ABOVE RIGHT, LATIN SMALL LETTER B
0061 0315 035C 0315 0300 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 035C 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 035C 0062; # (a◌̕◌͜◌̕◌̀b; à◌̕◌̕◌͜b; a◌̀◌̕◌̕◌͜b; à◌̕◌̕◌͜b; a◌̀◌̕◌̕◌͜b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, LATIN SMALL LETTER B
-0061 059A 0316 302A 0316 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062; # (a◌֚◌̖◌〪◌̖b; a◌〪◌̖◌̖◌֚b; a◌〪◌̖◌̖◌֚b; a◌〪◌̖◌̖◌֚b; a◌〪◌̖◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING GRAVE ACCENT BELOW, LATIN SMALL LETTER B
-0061 0316 059A 0316 302A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062; # (a◌̖◌֚◌̖◌〪b; a◌〪◌̖◌̖◌֚b; a◌〪◌̖◌̖◌֚b; a◌〪◌̖◌̖◌֚b; a◌〪◌̖◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING GRAVE ACCENT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0317 0062;0061 302A 0316 0317 059A 0062;0061 302A 0316 0317 059A 0062;0061 302A 0316 0317 059A 0062;0061 302A 0316 0317 059A 0062; # (a◌֚◌̖◌〪◌̗b; a◌〪◌̖◌̗◌֚b; a◌〪◌̖◌̗◌֚b; a◌〪◌̖◌̗◌֚b; a◌〪◌̖◌̗◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING ACUTE ACCENT BELOW, LATIN SMALL LETTER B
-0061 0317 059A 0316 302A 0062;0061 302A 0317 0316 059A 0062;0061 302A 0317 0316 059A 0062;0061 302A 0317 0316 059A 0062;0061 302A 0317 0316 059A 0062; # (a◌̗◌֚◌̖◌〪b; a◌〪◌̗◌̖◌֚b; a◌〪◌̗◌̖◌֚b; a◌〪◌̗◌̖◌֚b; a◌〪◌̗◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING ACUTE ACCENT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0318 0062;0061 302A 0316 0318 059A 0062;0061 302A 0316 0318 059A 0062;0061 302A 0316 0318 059A 0062;0061 302A 0316 0318 059A 0062; # (a◌֚◌̖◌〪◌̘b; a◌〪◌̖◌̘◌֚b; a◌〪◌̖◌̘◌֚b; a◌〪◌̖◌̘◌֚b; a◌〪◌̖◌̘◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LEFT TACK BELOW, LATIN SMALL LETTER B
-0061 0318 059A 0316 302A 0062;0061 302A 0318 0316 059A 0062;0061 302A 0318 0316 059A 0062;0061 302A 0318 0316 059A 0062;0061 302A 0318 0316 059A 0062; # (a◌̘◌֚◌̖◌〪b; a◌〪◌̘◌̖◌֚b; a◌〪◌̘◌̖◌֚b; a◌〪◌̘◌̖◌֚b; a◌〪◌̘◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT TACK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0319 0062;0061 302A 0316 0319 059A 0062;0061 302A 0316 0319 059A 0062;0061 302A 0316 0319 059A 0062;0061 302A 0316 0319 059A 0062; # (a◌֚◌̖◌〪◌̙b; a◌〪◌̖◌̙◌֚b; a◌〪◌̖◌̙◌֚b; a◌〪◌̖◌̙◌֚b; a◌〪◌̖◌̙◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RIGHT TACK BELOW, LATIN SMALL LETTER B
-0061 0319 059A 0316 302A 0062;0061 302A 0319 0316 059A 0062;0061 302A 0319 0316 059A 0062;0061 302A 0319 0316 059A 0062;0061 302A 0319 0316 059A 0062; # (a◌̙◌֚◌̖◌〪b; a◌〪◌̙◌̖◌֚b; a◌〪◌̙◌̖◌֚b; a◌〪◌̙◌̖◌֚b; a◌〪◌̙◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT TACK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0316 0062;0061 1DFA 0316 0316 059A 0062;0061 1DFA 0316 0316 059A 0062;0061 1DFA 0316 0316 059A 0062;0061 1DFA 0316 0316 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, COMBINING GRAVE ACCENT BELOW, LATIN SMALL LETTER B
+0061 0316 059A 0316 1DFA 0062;0061 1DFA 0316 0316 059A 0062;0061 1DFA 0316 0316 059A 0062;0061 1DFA 0316 0316 059A 0062;0061 1DFA 0316 0316 059A 0062; # (a◌̖◌֚◌̖◌᷺b; a◌᷺◌̖◌̖◌֚b; a◌᷺◌̖◌̖◌֚b; a◌᷺◌̖◌̖◌֚b; a◌᷺◌̖◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING GRAVE ACCENT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0317 0062;0061 1DFA 0316 0317 059A 0062;0061 1DFA 0316 0317 059A 0062;0061 1DFA 0316 0317 059A 0062;0061 1DFA 0316 0317 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, COMBINING ACUTE ACCENT BELOW, LATIN SMALL LETTER B
+0061 0317 059A 0316 1DFA 0062;0061 1DFA 0317 0316 059A 0062;0061 1DFA 0317 0316 059A 0062;0061 1DFA 0317 0316 059A 0062;0061 1DFA 0317 0316 059A 0062; # (a◌̗◌֚◌̖◌᷺b; a◌᷺◌̗◌̖◌֚b; a◌᷺◌̗◌̖◌֚b; a◌᷺◌̗◌̖◌֚b; a◌᷺◌̗◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING ACUTE ACCENT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0318 0062;0061 1DFA 0316 0318 059A 0062;0061 1DFA 0316 0318 059A 0062;0061 1DFA 0316 0318 059A 0062;0061 1DFA 0316 0318 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, COMBINING LEFT TACK BELOW, LATIN SMALL LETTER B
+0061 0318 059A 0316 1DFA 0062;0061 1DFA 0318 0316 059A 0062;0061 1DFA 0318 0316 059A 0062;0061 1DFA 0318 0316 059A 0062;0061 1DFA 0318 0316 059A 0062; # (a◌̘◌֚◌̖◌᷺b; a◌᷺◌̘◌̖◌֚b; a◌᷺◌̘◌̖◌֚b; a◌᷺◌̘◌̖◌֚b; a◌᷺◌̘◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT TACK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0319 0062;0061 1DFA 0316 0319 059A 0062;0061 1DFA 0316 0319 059A 0062;0061 1DFA 0316 0319 059A 0062;0061 1DFA 0316 0319 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, COMBINING RIGHT TACK BELOW, LATIN SMALL LETTER B
+0061 0319 059A 0316 1DFA 0062;0061 1DFA 0319 0316 059A 0062;0061 1DFA 0319 0316 059A 0062;0061 1DFA 0319 0316 059A 0062;0061 1DFA 0319 0316 059A 0062; # (a◌̙◌֚◌̖◌᷺b; a◌᷺◌̙◌̖◌֚b; a◌᷺◌̙◌̖◌֚b; a◌᷺◌̙◌̖◌֚b; a◌᷺◌̙◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT TACK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 035C 0315 0300 031A 0062;00E0 0315 031A 035C 0062;0061 0300 0315 031A 035C 0062;00E0 0315 031A 035C 0062;0061 0300 0315 031A 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, COMBINING LEFT ANGLE ABOVE, LATIN SMALL LETTER B
0061 031A 035C 0315 0300 0062;00E0 031A 0315 035C 0062;0061 0300 031A 0315 035C 0062;00E0 031A 0315 035C 0062;0061 0300 031A 0315 035C 0062; # (a◌̚◌͜◌̕◌̀b; à◌̚◌̕◌͜b; a◌̀◌̚◌̕◌͜b; à◌̚◌̕◌͜b; a◌̀◌̚◌̕◌͜b; ) LATIN SMALL LETTER A, COMBINING LEFT ANGLE ABOVE, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, LATIN SMALL LETTER B
-0061 302A 031B 1DCE 031B 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062; # (a◌〪◌̛◌᷎◌̛b; a◌᷎◌̛◌̛◌〪b; a◌᷎◌̛◌̛◌〪b; a◌᷎◌̛◌̛◌〪b; a◌᷎◌̛◌̛◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, COMBINING HORN, LATIN SMALL LETTER B
-0061 031B 302A 031B 1DCE 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062; # (a◌̛◌〪◌̛◌᷎b; a◌᷎◌̛◌̛◌〪b; a◌᷎◌̛◌̛◌〪b; a◌᷎◌̛◌̛◌〪b; a◌᷎◌̛◌̛◌〪b; ) LATIN SMALL LETTER A, COMBINING HORN, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
-0061 059A 0316 302A 031C 0062;0061 302A 0316 031C 059A 0062;0061 302A 0316 031C 059A 0062;0061 302A 0316 031C 059A 0062;0061 302A 0316 031C 059A 0062; # (a◌֚◌̖◌〪◌̜b; a◌〪◌̖◌̜◌֚b; a◌〪◌̖◌̜◌֚b; a◌〪◌̖◌̜◌֚b; a◌〪◌̖◌̜◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LEFT HALF RING BELOW, LATIN SMALL LETTER B
-0061 031C 059A 0316 302A 0062;0061 302A 031C 0316 059A 0062;0061 302A 031C 0316 059A 0062;0061 302A 031C 0316 059A 0062;0061 302A 031C 0316 059A 0062; # (a◌̜◌֚◌̖◌〪b; a◌〪◌̜◌̖◌֚b; a◌〪◌̜◌̖◌֚b; a◌〪◌̜◌̖◌֚b; a◌〪◌̜◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT HALF RING BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 031D 0062;0061 302A 0316 031D 059A 0062;0061 302A 0316 031D 059A 0062;0061 302A 0316 031D 059A 0062;0061 302A 0316 031D 059A 0062; # (a◌֚◌̖◌〪◌̝b; a◌〪◌̖◌̝◌֚b; a◌〪◌̖◌̝◌֚b; a◌〪◌̖◌̝◌֚b; a◌〪◌̖◌̝◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING UP TACK BELOW, LATIN SMALL LETTER B
-0061 031D 059A 0316 302A 0062;0061 302A 031D 0316 059A 0062;0061 302A 031D 0316 059A 0062;0061 302A 031D 0316 059A 0062;0061 302A 031D 0316 059A 0062; # (a◌̝◌֚◌̖◌〪b; a◌〪◌̝◌̖◌֚b; a◌〪◌̝◌̖◌֚b; a◌〪◌̝◌̖◌֚b; a◌〪◌̝◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING UP TACK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 031E 0062;0061 302A 0316 031E 059A 0062;0061 302A 0316 031E 059A 0062;0061 302A 0316 031E 059A 0062;0061 302A 0316 031E 059A 0062; # (a◌֚◌̖◌〪◌̞b; a◌〪◌̖◌̞◌֚b; a◌〪◌̖◌̞◌֚b; a◌〪◌̖◌̞◌֚b; a◌〪◌̖◌̞◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING DOWN TACK BELOW, LATIN SMALL LETTER B
-0061 031E 059A 0316 302A 0062;0061 302A 031E 0316 059A 0062;0061 302A 031E 0316 059A 0062;0061 302A 031E 0316 059A 0062;0061 302A 031E 0316 059A 0062; # (a◌̞◌֚◌̖◌〪b; a◌〪◌̞◌̖◌֚b; a◌〪◌̞◌̖◌֚b; a◌〪◌̞◌̖◌֚b; a◌〪◌̞◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOWN TACK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 031F 0062;0061 302A 0316 031F 059A 0062;0061 302A 0316 031F 059A 0062;0061 302A 0316 031F 059A 0062;0061 302A 0316 031F 059A 0062; # (a◌֚◌̖◌〪◌̟b; a◌〪◌̖◌̟◌֚b; a◌〪◌̖◌̟◌֚b; a◌〪◌̖◌̟◌֚b; a◌〪◌̖◌̟◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING PLUS SIGN BELOW, LATIN SMALL LETTER B
-0061 031F 059A 0316 302A 0062;0061 302A 031F 0316 059A 0062;0061 302A 031F 0316 059A 0062;0061 302A 031F 0316 059A 0062;0061 302A 031F 0316 059A 0062; # (a◌̟◌֚◌̖◌〪b; a◌〪◌̟◌̖◌֚b; a◌〪◌̟◌̖◌֚b; a◌〪◌̟◌̖◌֚b; a◌〪◌̟◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING PLUS SIGN BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0320 0062;0061 302A 0316 0320 059A 0062;0061 302A 0316 0320 059A 0062;0061 302A 0316 0320 059A 0062;0061 302A 0316 0320 059A 0062; # (a◌֚◌̖◌〪◌̠b; a◌〪◌̖◌̠◌֚b; a◌〪◌̖◌̠◌֚b; a◌〪◌̖◌̠◌֚b; a◌〪◌̖◌̠◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING MINUS SIGN BELOW, LATIN SMALL LETTER B
-0061 0320 059A 0316 302A 0062;0061 302A 0320 0316 059A 0062;0061 302A 0320 0316 059A 0062;0061 302A 0320 0316 059A 0062;0061 302A 0320 0316 059A 0062; # (a◌̠◌֚◌̖◌〪b; a◌〪◌̠◌̖◌֚b; a◌〪◌̠◌̖◌֚b; a◌〪◌̠◌̖◌֚b; a◌〪◌̠◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING MINUS SIGN BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 1DFA 031B 1DCE 031B 0062;0061 1DCE 031B 031B 1DFA 0062;0061 1DCE 031B 031B 1DFA 0062;0061 1DCE 031B 031B 1DFA 0062;0061 1DCE 031B 031B 1DFA 0062; # (a◌᷺◌̛◌᷎◌̛b; a◌᷎◌̛◌̛◌᷺b; a◌᷎◌̛◌̛◌᷺b; a◌᷎◌̛◌̛◌᷺b; a◌᷎◌̛◌̛◌᷺b; ) LATIN SMALL LETTER A, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, COMBINING HORN, LATIN SMALL LETTER B
+0061 031B 1DFA 031B 1DCE 0062;0061 1DCE 031B 031B 1DFA 0062;0061 1DCE 031B 031B 1DFA 0062;0061 1DCE 031B 031B 1DFA 0062;0061 1DCE 031B 031B 1DFA 0062; # (a◌̛◌᷺◌̛◌᷎b; a◌᷎◌̛◌̛◌᷺b; a◌᷎◌̛◌̛◌᷺b; a◌᷎◌̛◌̛◌᷺b; a◌᷎◌̛◌̛◌᷺b; ) LATIN SMALL LETTER A, COMBINING HORN, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 031C 0062;0061 1DFA 0316 031C 059A 0062;0061 1DFA 0316 031C 059A 0062;0061 1DFA 0316 031C 059A 0062;0061 1DFA 0316 031C 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, COMBINING LEFT HALF RING BELOW, LATIN SMALL LETTER B
+0061 031C 059A 0316 1DFA 0062;0061 1DFA 031C 0316 059A 0062;0061 1DFA 031C 0316 059A 0062;0061 1DFA 031C 0316 059A 0062;0061 1DFA 031C 0316 059A 0062; # (a◌̜◌֚◌̖◌᷺b; a◌᷺◌̜◌̖◌֚b; a◌᷺◌̜◌̖◌֚b; a◌᷺◌̜◌̖◌֚b; a◌᷺◌̜◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT HALF RING BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 031D 0062;0061 1DFA 0316 031D 059A 0062;0061 1DFA 0316 031D 059A 0062;0061 1DFA 0316 031D 059A 0062;0061 1DFA 0316 031D 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, COMBINING UP TACK BELOW, LATIN SMALL LETTER B
+0061 031D 059A 0316 1DFA 0062;0061 1DFA 031D 0316 059A 0062;0061 1DFA 031D 0316 059A 0062;0061 1DFA 031D 0316 059A 0062;0061 1DFA 031D 0316 059A 0062; # (a◌̝◌֚◌̖◌᷺b; a◌᷺◌̝◌̖◌֚b; a◌᷺◌̝◌̖◌֚b; a◌᷺◌̝◌̖◌֚b; a◌᷺◌̝◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING UP TACK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 031E 0062;0061 1DFA 0316 031E 059A 0062;0061 1DFA 0316 031E 059A 0062;0061 1DFA 0316 031E 059A 0062;0061 1DFA 0316 031E 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, COMBINING DOWN TACK BELOW, LATIN SMALL LETTER B
+0061 031E 059A 0316 1DFA 0062;0061 1DFA 031E 0316 059A 0062;0061 1DFA 031E 0316 059A 0062;0061 1DFA 031E 0316 059A 0062;0061 1DFA 031E 0316 059A 0062; # (a◌̞◌֚◌̖◌᷺b; a◌᷺◌̞◌̖◌֚b; a◌᷺◌̞◌̖◌֚b; a◌᷺◌̞◌̖◌֚b; a◌᷺◌̞◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOWN TACK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 031F 0062;0061 1DFA 0316 031F 059A 0062;0061 1DFA 0316 031F 059A 0062;0061 1DFA 0316 031F 059A 0062;0061 1DFA 0316 031F 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, COMBINING PLUS SIGN BELOW, LATIN SMALL LETTER B
+0061 031F 059A 0316 1DFA 0062;0061 1DFA 031F 0316 059A 0062;0061 1DFA 031F 0316 059A 0062;0061 1DFA 031F 0316 059A 0062;0061 1DFA 031F 0316 059A 0062; # (a◌̟◌֚◌̖◌᷺b; a◌᷺◌̟◌̖◌֚b; a◌᷺◌̟◌̖◌֚b; a◌᷺◌̟◌̖◌֚b; a◌᷺◌̟◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING PLUS SIGN BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0320 0062;0061 1DFA 0316 0320 059A 0062;0061 1DFA 0316 0320 059A 0062;0061 1DFA 0316 0320 059A 0062;0061 1DFA 0316 0320 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, COMBINING MINUS SIGN BELOW, LATIN SMALL LETTER B
+0061 0320 059A 0316 1DFA 0062;0061 1DFA 0320 0316 059A 0062;0061 1DFA 0320 0316 059A 0062;0061 1DFA 0320 0316 059A 0062;0061 1DFA 0320 0316 059A 0062; # (a◌̠◌֚◌̖◌᷺b; a◌᷺◌̠◌̖◌֚b; a◌᷺◌̠◌̖◌֚b; a◌᷺◌̠◌̖◌֚b; a◌᷺◌̠◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING MINUS SIGN BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 1DCE 0321 0F74 0321 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062; # (a◌᷎◌̡◌ུ◌̡b; a◌ུ◌̡◌̡◌᷎b; a◌ུ◌̡◌̡◌᷎b; a◌ུ◌̡◌̡◌᷎b; a◌ུ◌̡◌̡◌᷎b; ) LATIN SMALL LETTER A, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, COMBINING PALATALIZED HOOK BELOW, LATIN SMALL LETTER B
0061 0321 1DCE 0321 0F74 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062; # (a◌̡◌᷎◌̡◌ུb; a◌ུ◌̡◌̡◌᷎b; a◌ུ◌̡◌̡◌᷎b; a◌ུ◌̡◌̡◌᷎b; a◌ུ◌̡◌̡◌᷎b; ) LATIN SMALL LETTER A, COMBINING PALATALIZED HOOK BELOW, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, LATIN SMALL LETTER B
0061 1DCE 0321 0F74 0322 0062;0061 0F74 0321 0322 1DCE 0062;0061 0F74 0321 0322 1DCE 0062;0061 0F74 0321 0322 1DCE 0062;0061 0F74 0321 0322 1DCE 0062; # (a◌᷎◌̡◌ུ◌̢b; a◌ུ◌̡◌̢◌᷎b; a◌ུ◌̡◌̢◌᷎b; a◌ུ◌̡◌̢◌᷎b; a◌ུ◌̡◌̢◌᷎b; ) LATIN SMALL LETTER A, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, COMBINING RETROFLEX HOOK BELOW, LATIN SMALL LETTER B
0061 0322 1DCE 0321 0F74 0062;0061 0F74 0322 0321 1DCE 0062;0061 0F74 0322 0321 1DCE 0062;0061 0F74 0322 0321 1DCE 0062;0061 0F74 0322 0321 1DCE 0062; # (a◌̢◌᷎◌̡◌ུb; a◌ུ◌̢◌̡◌᷎b; a◌ུ◌̢◌̡◌᷎b; a◌ུ◌̢◌̡◌᷎b; a◌ུ◌̢◌̡◌᷎b; ) LATIN SMALL LETTER A, COMBINING RETROFLEX HOOK BELOW, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, LATIN SMALL LETTER B
-0061 059A 0316 302A 0323 0062;0061 302A 0316 0323 059A 0062;0061 302A 0316 0323 059A 0062;0061 302A 0316 0323 059A 0062;0061 302A 0316 0323 059A 0062; # (a◌֚◌̖◌〪◌̣b; a◌〪◌̖◌̣◌֚b; a◌〪◌̖◌̣◌֚b; a◌〪◌̖◌̣◌֚b; a◌〪◌̖◌̣◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING DOT BELOW, LATIN SMALL LETTER B
-0061 0323 059A 0316 302A 0062;1EA1 302A 0316 059A 0062;0061 302A 0323 0316 059A 0062;1EA1 302A 0316 059A 0062;0061 302A 0323 0316 059A 0062; # (a◌̣◌֚◌̖◌〪b; ạ◌〪◌̖◌֚b; a◌〪◌̣◌̖◌֚b; ạ◌〪◌̖◌֚b; a◌〪◌̣◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0324 0062;0061 302A 0316 0324 059A 0062;0061 302A 0316 0324 059A 0062;0061 302A 0316 0324 059A 0062;0061 302A 0316 0324 059A 0062; # (a◌֚◌̖◌〪◌̤b; a◌〪◌̖◌̤◌֚b; a◌〪◌̖◌̤◌֚b; a◌〪◌̖◌̤◌֚b; a◌〪◌̖◌̤◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING DIAERESIS BELOW, LATIN SMALL LETTER B
-0061 0324 059A 0316 302A 0062;0061 302A 0324 0316 059A 0062;0061 302A 0324 0316 059A 0062;0061 302A 0324 0316 059A 0062;0061 302A 0324 0316 059A 0062; # (a◌̤◌֚◌̖◌〪b; a◌〪◌̤◌̖◌֚b; a◌〪◌̤◌̖◌֚b; a◌〪◌̤◌̖◌֚b; a◌〪◌̤◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DIAERESIS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0325 0062;0061 302A 0316 0325 059A 0062;0061 302A 0316 0325 059A 0062;0061 302A 0316 0325 059A 0062;0061 302A 0316 0325 059A 0062; # (a◌֚◌̖◌〪◌̥b; a◌〪◌̖◌̥◌֚b; a◌〪◌̖◌̥◌֚b; a◌〪◌̖◌̥◌֚b; a◌〪◌̖◌̥◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RING BELOW, LATIN SMALL LETTER B
-0061 0325 059A 0316 302A 0062;1E01 302A 0316 059A 0062;0061 302A 0325 0316 059A 0062;1E01 302A 0316 059A 0062;0061 302A 0325 0316 059A 0062; # (a◌̥◌֚◌̖◌〪b; ḁ◌〪◌̖◌֚b; a◌〪◌̥◌̖◌֚b; ḁ◌〪◌̖◌֚b; a◌〪◌̥◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RING BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0326 0062;0061 302A 0316 0326 059A 0062;0061 302A 0316 0326 059A 0062;0061 302A 0316 0326 059A 0062;0061 302A 0316 0326 059A 0062; # (a◌֚◌̖◌〪◌̦b; a◌〪◌̖◌̦◌֚b; a◌〪◌̖◌̦◌֚b; a◌〪◌̖◌̦◌֚b; a◌〪◌̖◌̦◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING COMMA BELOW, LATIN SMALL LETTER B
-0061 0326 059A 0316 302A 0062;0061 302A 0326 0316 059A 0062;0061 302A 0326 0316 059A 0062;0061 302A 0326 0316 059A 0062;0061 302A 0326 0316 059A 0062; # (a◌̦◌֚◌̖◌〪b; a◌〪◌̦◌̖◌֚b; a◌〪◌̦◌̖◌֚b; a◌〪◌̦◌̖◌֚b; a◌〪◌̦◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING COMMA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0323 0062;0061 1DFA 0316 0323 059A 0062;0061 1DFA 0316 0323 059A 0062;0061 1DFA 0316 0323 059A 0062;0061 1DFA 0316 0323 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, COMBINING DOT BELOW, LATIN SMALL LETTER B
+0061 0323 059A 0316 1DFA 0062;1EA1 1DFA 0316 059A 0062;0061 1DFA 0323 0316 059A 0062;1EA1 1DFA 0316 059A 0062;0061 1DFA 0323 0316 059A 0062; # (a◌̣◌֚◌̖◌᷺b; ạ◌᷺◌̖◌֚b; a◌᷺◌̣◌̖◌֚b; ạ◌᷺◌̖◌֚b; a◌᷺◌̣◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0324 0062;0061 1DFA 0316 0324 059A 0062;0061 1DFA 0316 0324 059A 0062;0061 1DFA 0316 0324 059A 0062;0061 1DFA 0316 0324 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, COMBINING DIAERESIS BELOW, LATIN SMALL LETTER B
+0061 0324 059A 0316 1DFA 0062;0061 1DFA 0324 0316 059A 0062;0061 1DFA 0324 0316 059A 0062;0061 1DFA 0324 0316 059A 0062;0061 1DFA 0324 0316 059A 0062; # (a◌̤◌֚◌̖◌᷺b; a◌᷺◌̤◌̖◌֚b; a◌᷺◌̤◌̖◌֚b; a◌᷺◌̤◌̖◌֚b; a◌᷺◌̤◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DIAERESIS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0325 0062;0061 1DFA 0316 0325 059A 0062;0061 1DFA 0316 0325 059A 0062;0061 1DFA 0316 0325 059A 0062;0061 1DFA 0316 0325 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, COMBINING RING BELOW, LATIN SMALL LETTER B
+0061 0325 059A 0316 1DFA 0062;1E01 1DFA 0316 059A 0062;0061 1DFA 0325 0316 059A 0062;1E01 1DFA 0316 059A 0062;0061 1DFA 0325 0316 059A 0062; # (a◌̥◌֚◌̖◌᷺b; ḁ◌᷺◌̖◌֚b; a◌᷺◌̥◌̖◌֚b; ḁ◌᷺◌̖◌֚b; a◌᷺◌̥◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RING BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0326 0062;0061 1DFA 0316 0326 059A 0062;0061 1DFA 0316 0326 059A 0062;0061 1DFA 0316 0326 059A 0062;0061 1DFA 0316 0326 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, COMBINING COMMA BELOW, LATIN SMALL LETTER B
+0061 0326 059A 0316 1DFA 0062;0061 1DFA 0326 0316 059A 0062;0061 1DFA 0326 0316 059A 0062;0061 1DFA 0326 0316 059A 0062;0061 1DFA 0326 0316 059A 0062; # (a◌̦◌֚◌̖◌᷺b; a◌᷺◌̦◌̖◌֚b; a◌᷺◌̦◌̖◌֚b; a◌᷺◌̦◌̖◌֚b; a◌᷺◌̦◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING COMMA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 1DCE 0321 0F74 0327 0062;0061 0F74 0321 0327 1DCE 0062;0061 0F74 0321 0327 1DCE 0062;0061 0F74 0321 0327 1DCE 0062;0061 0F74 0321 0327 1DCE 0062; # (a◌᷎◌̡◌ུ◌̧b; a◌ུ◌̡◌̧◌᷎b; a◌ུ◌̡◌̧◌᷎b; a◌ུ◌̡◌̧◌᷎b; a◌ུ◌̡◌̧◌᷎b; ) LATIN SMALL LETTER A, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, COMBINING CEDILLA, LATIN SMALL LETTER B
0061 0327 1DCE 0321 0F74 0062;0061 0F74 0327 0321 1DCE 0062;0061 0F74 0327 0321 1DCE 0062;0061 0F74 0327 0321 1DCE 0062;0061 0F74 0327 0321 1DCE 0062; # (a◌̧◌᷎◌̡◌ུb; a◌ུ◌̧◌̡◌᷎b; a◌ུ◌̧◌̡◌᷎b; a◌ུ◌̧◌̡◌᷎b; a◌ུ◌̧◌̡◌᷎b; ) LATIN SMALL LETTER A, COMBINING CEDILLA, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, LATIN SMALL LETTER B
0061 1DCE 0321 0F74 0328 0062;0061 0F74 0321 0328 1DCE 0062;0061 0F74 0321 0328 1DCE 0062;0061 0F74 0321 0328 1DCE 0062;0061 0F74 0321 0328 1DCE 0062; # (a◌᷎◌̡◌ུ◌̨b; a◌ུ◌̡◌̨◌᷎b; a◌ུ◌̡◌̨◌᷎b; a◌ུ◌̡◌̨◌᷎b; a◌ུ◌̡◌̨◌᷎b; ) LATIN SMALL LETTER A, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, COMBINING OGONEK, LATIN SMALL LETTER B
0061 0328 1DCE 0321 0F74 0062;0105 0F74 0321 1DCE 0062;0061 0F74 0328 0321 1DCE 0062;0105 0F74 0321 1DCE 0062;0061 0F74 0328 0321 1DCE 0062; # (a◌̨◌᷎◌̡◌ུb; ą◌ུ◌̡◌᷎b; a◌ུ◌̨◌̡◌᷎b; ą◌ུ◌̡◌᷎b; a◌ུ◌̨◌̡◌᷎b; ) LATIN SMALL LETTER A, COMBINING OGONEK, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, LATIN SMALL LETTER B
-0061 059A 0316 302A 0329 0062;0061 302A 0316 0329 059A 0062;0061 302A 0316 0329 059A 0062;0061 302A 0316 0329 059A 0062;0061 302A 0316 0329 059A 0062; # (a◌֚◌̖◌〪◌̩b; a◌〪◌̖◌̩◌֚b; a◌〪◌̖◌̩◌֚b; a◌〪◌̖◌̩◌֚b; a◌〪◌̖◌̩◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING VERTICAL LINE BELOW, LATIN SMALL LETTER B
-0061 0329 059A 0316 302A 0062;0061 302A 0329 0316 059A 0062;0061 302A 0329 0316 059A 0062;0061 302A 0329 0316 059A 0062;0061 302A 0329 0316 059A 0062; # (a◌̩◌֚◌̖◌〪b; a◌〪◌̩◌̖◌֚b; a◌〪◌̩◌̖◌֚b; a◌〪◌̩◌̖◌֚b; a◌〪◌̩◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING VERTICAL LINE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 032A 0062;0061 302A 0316 032A 059A 0062;0061 302A 0316 032A 059A 0062;0061 302A 0316 032A 059A 0062;0061 302A 0316 032A 059A 0062; # (a◌֚◌̖◌〪◌̪b; a◌〪◌̖◌̪◌֚b; a◌〪◌̖◌̪◌֚b; a◌〪◌̖◌̪◌֚b; a◌〪◌̖◌̪◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING BRIDGE BELOW, LATIN SMALL LETTER B
-0061 032A 059A 0316 302A 0062;0061 302A 032A 0316 059A 0062;0061 302A 032A 0316 059A 0062;0061 302A 032A 0316 059A 0062;0061 302A 032A 0316 059A 0062; # (a◌̪◌֚◌̖◌〪b; a◌〪◌̪◌̖◌֚b; a◌〪◌̪◌̖◌֚b; a◌〪◌̪◌̖◌֚b; a◌〪◌̪◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING BRIDGE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 032B 0062;0061 302A 0316 032B 059A 0062;0061 302A 0316 032B 059A 0062;0061 302A 0316 032B 059A 0062;0061 302A 0316 032B 059A 0062; # (a◌֚◌̖◌〪◌̫b; a◌〪◌̖◌̫◌֚b; a◌〪◌̖◌̫◌֚b; a◌〪◌̖◌̫◌֚b; a◌〪◌̖◌̫◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING INVERTED DOUBLE ARCH BELOW, LATIN SMALL LETTER B
-0061 032B 059A 0316 302A 0062;0061 302A 032B 0316 059A 0062;0061 302A 032B 0316 059A 0062;0061 302A 032B 0316 059A 0062;0061 302A 032B 0316 059A 0062; # (a◌̫◌֚◌̖◌〪b; a◌〪◌̫◌̖◌֚b; a◌〪◌̫◌̖◌֚b; a◌〪◌̫◌̖◌֚b; a◌〪◌̫◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING INVERTED DOUBLE ARCH BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 032C 0062;0061 302A 0316 032C 059A 0062;0061 302A 0316 032C 059A 0062;0061 302A 0316 032C 059A 0062;0061 302A 0316 032C 059A 0062; # (a◌֚◌̖◌〪◌̬b; a◌〪◌̖◌̬◌֚b; a◌〪◌̖◌̬◌֚b; a◌〪◌̖◌̬◌֚b; a◌〪◌̖◌̬◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING CARON BELOW, LATIN SMALL LETTER B
-0061 032C 059A 0316 302A 0062;0061 302A 032C 0316 059A 0062;0061 302A 032C 0316 059A 0062;0061 302A 032C 0316 059A 0062;0061 302A 032C 0316 059A 0062; # (a◌̬◌֚◌̖◌〪b; a◌〪◌̬◌̖◌֚b; a◌〪◌̬◌̖◌֚b; a◌〪◌̬◌̖◌֚b; a◌〪◌̬◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING CARON BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 032D 0062;0061 302A 0316 032D 059A 0062;0061 302A 0316 032D 059A 0062;0061 302A 0316 032D 059A 0062;0061 302A 0316 032D 059A 0062; # (a◌֚◌̖◌〪◌̭b; a◌〪◌̖◌̭◌֚b; a◌〪◌̖◌̭◌֚b; a◌〪◌̖◌̭◌֚b; a◌〪◌̖◌̭◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING CIRCUMFLEX ACCENT BELOW, LATIN SMALL LETTER B
-0061 032D 059A 0316 302A 0062;0061 302A 032D 0316 059A 0062;0061 302A 032D 0316 059A 0062;0061 302A 032D 0316 059A 0062;0061 302A 032D 0316 059A 0062; # (a◌̭◌֚◌̖◌〪b; a◌〪◌̭◌̖◌֚b; a◌〪◌̭◌̖◌֚b; a◌〪◌̭◌̖◌֚b; a◌〪◌̭◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING CIRCUMFLEX ACCENT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 032E 0062;0061 302A 0316 032E 059A 0062;0061 302A 0316 032E 059A 0062;0061 302A 0316 032E 059A 0062;0061 302A 0316 032E 059A 0062; # (a◌֚◌̖◌〪◌̮b; a◌〪◌̖◌̮◌֚b; a◌〪◌̖◌̮◌֚b; a◌〪◌̖◌̮◌֚b; a◌〪◌̖◌̮◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING BREVE BELOW, LATIN SMALL LETTER B
-0061 032E 059A 0316 302A 0062;0061 302A 032E 0316 059A 0062;0061 302A 032E 0316 059A 0062;0061 302A 032E 0316 059A 0062;0061 302A 032E 0316 059A 0062; # (a◌̮◌֚◌̖◌〪b; a◌〪◌̮◌̖◌֚b; a◌〪◌̮◌̖◌֚b; a◌〪◌̮◌̖◌֚b; a◌〪◌̮◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING BREVE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 032F 0062;0061 302A 0316 032F 059A 0062;0061 302A 0316 032F 059A 0062;0061 302A 0316 032F 059A 0062;0061 302A 0316 032F 059A 0062; # (a◌֚◌̖◌〪◌̯b; a◌〪◌̖◌̯◌֚b; a◌〪◌̖◌̯◌֚b; a◌〪◌̖◌̯◌֚b; a◌〪◌̖◌̯◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING INVERTED BREVE BELOW, LATIN SMALL LETTER B
-0061 032F 059A 0316 302A 0062;0061 302A 032F 0316 059A 0062;0061 302A 032F 0316 059A 0062;0061 302A 032F 0316 059A 0062;0061 302A 032F 0316 059A 0062; # (a◌̯◌֚◌̖◌〪b; a◌〪◌̯◌̖◌֚b; a◌〪◌̯◌̖◌֚b; a◌〪◌̯◌̖◌֚b; a◌〪◌̯◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING INVERTED BREVE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0330 0062;0061 302A 0316 0330 059A 0062;0061 302A 0316 0330 059A 0062;0061 302A 0316 0330 059A 0062;0061 302A 0316 0330 059A 0062; # (a◌֚◌̖◌〪◌̰b; a◌〪◌̖◌̰◌֚b; a◌〪◌̖◌̰◌֚b; a◌〪◌̖◌̰◌֚b; a◌〪◌̖◌̰◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING TILDE BELOW, LATIN SMALL LETTER B
-0061 0330 059A 0316 302A 0062;0061 302A 0330 0316 059A 0062;0061 302A 0330 0316 059A 0062;0061 302A 0330 0316 059A 0062;0061 302A 0330 0316 059A 0062; # (a◌̰◌֚◌̖◌〪b; a◌〪◌̰◌̖◌֚b; a◌〪◌̰◌̖◌֚b; a◌〪◌̰◌̖◌֚b; a◌〪◌̰◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING TILDE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0331 0062;0061 302A 0316 0331 059A 0062;0061 302A 0316 0331 059A 0062;0061 302A 0316 0331 059A 0062;0061 302A 0316 0331 059A 0062; # (a◌֚◌̖◌〪◌̱b; a◌〪◌̖◌̱◌֚b; a◌〪◌̖◌̱◌֚b; a◌〪◌̖◌̱◌֚b; a◌〪◌̖◌̱◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING MACRON BELOW, LATIN SMALL LETTER B
-0061 0331 059A 0316 302A 0062;0061 302A 0331 0316 059A 0062;0061 302A 0331 0316 059A 0062;0061 302A 0331 0316 059A 0062;0061 302A 0331 0316 059A 0062; # (a◌̱◌֚◌̖◌〪b; a◌〪◌̱◌̖◌֚b; a◌〪◌̱◌̖◌֚b; a◌〪◌̱◌̖◌֚b; a◌〪◌̱◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING MACRON BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0332 0062;0061 302A 0316 0332 059A 0062;0061 302A 0316 0332 059A 0062;0061 302A 0316 0332 059A 0062;0061 302A 0316 0332 059A 0062; # (a◌֚◌̖◌〪◌̲b; a◌〪◌̖◌̲◌֚b; a◌〪◌̖◌̲◌֚b; a◌〪◌̖◌̲◌֚b; a◌〪◌̖◌̲◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LOW LINE, LATIN SMALL LETTER B
-0061 0332 059A 0316 302A 0062;0061 302A 0332 0316 059A 0062;0061 302A 0332 0316 059A 0062;0061 302A 0332 0316 059A 0062;0061 302A 0332 0316 059A 0062; # (a◌̲◌֚◌̖◌〪b; a◌〪◌̲◌̖◌֚b; a◌〪◌̲◌̖◌֚b; a◌〪◌̲◌̖◌֚b; a◌〪◌̲◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LOW LINE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0333 0062;0061 302A 0316 0333 059A 0062;0061 302A 0316 0333 059A 0062;0061 302A 0316 0333 059A 0062;0061 302A 0316 0333 059A 0062; # (a◌֚◌̖◌〪◌̳b; a◌〪◌̖◌̳◌֚b; a◌〪◌̖◌̳◌֚b; a◌〪◌̖◌̳◌֚b; a◌〪◌̖◌̳◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING DOUBLE LOW LINE, LATIN SMALL LETTER B
-0061 0333 059A 0316 302A 0062;0061 302A 0333 0316 059A 0062;0061 302A 0333 0316 059A 0062;0061 302A 0333 0316 059A 0062;0061 302A 0333 0316 059A 0062; # (a◌̳◌֚◌̖◌〪b; a◌〪◌̳◌̖◌֚b; a◌〪◌̳◌̖◌֚b; a◌〪◌̳◌̖◌֚b; a◌〪◌̳◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOUBLE LOW LINE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0329 0062;0061 1DFA 0316 0329 059A 0062;0061 1DFA 0316 0329 059A 0062;0061 1DFA 0316 0329 059A 0062;0061 1DFA 0316 0329 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, COMBINING VERTICAL LINE BELOW, LATIN SMALL LETTER B
+0061 0329 059A 0316 1DFA 0062;0061 1DFA 0329 0316 059A 0062;0061 1DFA 0329 0316 059A 0062;0061 1DFA 0329 0316 059A 0062;0061 1DFA 0329 0316 059A 0062; # (a◌̩◌֚◌̖◌᷺b; a◌᷺◌̩◌̖◌֚b; a◌᷺◌̩◌̖◌֚b; a◌᷺◌̩◌̖◌֚b; a◌᷺◌̩◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING VERTICAL LINE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 032A 0062;0061 1DFA 0316 032A 059A 0062;0061 1DFA 0316 032A 059A 0062;0061 1DFA 0316 032A 059A 0062;0061 1DFA 0316 032A 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, COMBINING BRIDGE BELOW, LATIN SMALL LETTER B
+0061 032A 059A 0316 1DFA 0062;0061 1DFA 032A 0316 059A 0062;0061 1DFA 032A 0316 059A 0062;0061 1DFA 032A 0316 059A 0062;0061 1DFA 032A 0316 059A 0062; # (a◌̪◌֚◌̖◌᷺b; a◌᷺◌̪◌̖◌֚b; a◌᷺◌̪◌̖◌֚b; a◌᷺◌̪◌̖◌֚b; a◌᷺◌̪◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING BRIDGE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 032B 0062;0061 1DFA 0316 032B 059A 0062;0061 1DFA 0316 032B 059A 0062;0061 1DFA 0316 032B 059A 0062;0061 1DFA 0316 032B 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, COMBINING INVERTED DOUBLE ARCH BELOW, LATIN SMALL LETTER B
+0061 032B 059A 0316 1DFA 0062;0061 1DFA 032B 0316 059A 0062;0061 1DFA 032B 0316 059A 0062;0061 1DFA 032B 0316 059A 0062;0061 1DFA 032B 0316 059A 0062; # (a◌̫◌֚◌̖◌᷺b; a◌᷺◌̫◌̖◌֚b; a◌᷺◌̫◌̖◌֚b; a◌᷺◌̫◌̖◌֚b; a◌᷺◌̫◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING INVERTED DOUBLE ARCH BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 032C 0062;0061 1DFA 0316 032C 059A 0062;0061 1DFA 0316 032C 059A 0062;0061 1DFA 0316 032C 059A 0062;0061 1DFA 0316 032C 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, COMBINING CARON BELOW, LATIN SMALL LETTER B
+0061 032C 059A 0316 1DFA 0062;0061 1DFA 032C 0316 059A 0062;0061 1DFA 032C 0316 059A 0062;0061 1DFA 032C 0316 059A 0062;0061 1DFA 032C 0316 059A 0062; # (a◌̬◌֚◌̖◌᷺b; a◌᷺◌̬◌̖◌֚b; a◌᷺◌̬◌̖◌֚b; a◌᷺◌̬◌̖◌֚b; a◌᷺◌̬◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING CARON BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 032D 0062;0061 1DFA 0316 032D 059A 0062;0061 1DFA 0316 032D 059A 0062;0061 1DFA 0316 032D 059A 0062;0061 1DFA 0316 032D 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, COMBINING CIRCUMFLEX ACCENT BELOW, LATIN SMALL LETTER B
+0061 032D 059A 0316 1DFA 0062;0061 1DFA 032D 0316 059A 0062;0061 1DFA 032D 0316 059A 0062;0061 1DFA 032D 0316 059A 0062;0061 1DFA 032D 0316 059A 0062; # (a◌̭◌֚◌̖◌᷺b; a◌᷺◌̭◌̖◌֚b; a◌᷺◌̭◌̖◌֚b; a◌᷺◌̭◌̖◌֚b; a◌᷺◌̭◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING CIRCUMFLEX ACCENT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 032E 0062;0061 1DFA 0316 032E 059A 0062;0061 1DFA 0316 032E 059A 0062;0061 1DFA 0316 032E 059A 0062;0061 1DFA 0316 032E 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, COMBINING BREVE BELOW, LATIN SMALL LETTER B
+0061 032E 059A 0316 1DFA 0062;0061 1DFA 032E 0316 059A 0062;0061 1DFA 032E 0316 059A 0062;0061 1DFA 032E 0316 059A 0062;0061 1DFA 032E 0316 059A 0062; # (a◌̮◌֚◌̖◌᷺b; a◌᷺◌̮◌̖◌֚b; a◌᷺◌̮◌̖◌֚b; a◌᷺◌̮◌̖◌֚b; a◌᷺◌̮◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING BREVE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 032F 0062;0061 1DFA 0316 032F 059A 0062;0061 1DFA 0316 032F 059A 0062;0061 1DFA 0316 032F 059A 0062;0061 1DFA 0316 032F 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, COMBINING INVERTED BREVE BELOW, LATIN SMALL LETTER B
+0061 032F 059A 0316 1DFA 0062;0061 1DFA 032F 0316 059A 0062;0061 1DFA 032F 0316 059A 0062;0061 1DFA 032F 0316 059A 0062;0061 1DFA 032F 0316 059A 0062; # (a◌̯◌֚◌̖◌᷺b; a◌᷺◌̯◌̖◌֚b; a◌᷺◌̯◌̖◌֚b; a◌᷺◌̯◌̖◌֚b; a◌᷺◌̯◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING INVERTED BREVE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0330 0062;0061 1DFA 0316 0330 059A 0062;0061 1DFA 0316 0330 059A 0062;0061 1DFA 0316 0330 059A 0062;0061 1DFA 0316 0330 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, COMBINING TILDE BELOW, LATIN SMALL LETTER B
+0061 0330 059A 0316 1DFA 0062;0061 1DFA 0330 0316 059A 0062;0061 1DFA 0330 0316 059A 0062;0061 1DFA 0330 0316 059A 0062;0061 1DFA 0330 0316 059A 0062; # (a◌̰◌֚◌̖◌᷺b; a◌᷺◌̰◌̖◌֚b; a◌᷺◌̰◌̖◌֚b; a◌᷺◌̰◌̖◌֚b; a◌᷺◌̰◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING TILDE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0331 0062;0061 1DFA 0316 0331 059A 0062;0061 1DFA 0316 0331 059A 0062;0061 1DFA 0316 0331 059A 0062;0061 1DFA 0316 0331 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, COMBINING MACRON BELOW, LATIN SMALL LETTER B
+0061 0331 059A 0316 1DFA 0062;0061 1DFA 0331 0316 059A 0062;0061 1DFA 0331 0316 059A 0062;0061 1DFA 0331 0316 059A 0062;0061 1DFA 0331 0316 059A 0062; # (a◌̱◌֚◌̖◌᷺b; a◌᷺◌̱◌̖◌֚b; a◌᷺◌̱◌̖◌֚b; a◌᷺◌̱◌̖◌֚b; a◌᷺◌̱◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING MACRON BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0332 0062;0061 1DFA 0316 0332 059A 0062;0061 1DFA 0316 0332 059A 0062;0061 1DFA 0316 0332 059A 0062;0061 1DFA 0316 0332 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, COMBINING LOW LINE, LATIN SMALL LETTER B
+0061 0332 059A 0316 1DFA 0062;0061 1DFA 0332 0316 059A 0062;0061 1DFA 0332 0316 059A 0062;0061 1DFA 0332 0316 059A 0062;0061 1DFA 0332 0316 059A 0062; # (a◌̲◌֚◌̖◌᷺b; a◌᷺◌̲◌̖◌֚b; a◌᷺◌̲◌̖◌֚b; a◌᷺◌̲◌̖◌֚b; a◌᷺◌̲◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LOW LINE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0333 0062;0061 1DFA 0316 0333 059A 0062;0061 1DFA 0316 0333 059A 0062;0061 1DFA 0316 0333 059A 0062;0061 1DFA 0316 0333 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, COMBINING DOUBLE LOW LINE, LATIN SMALL LETTER B
+0061 0333 059A 0316 1DFA 0062;0061 1DFA 0333 0316 059A 0062;0061 1DFA 0333 0316 059A 0062;0061 1DFA 0333 0316 059A 0062;0061 1DFA 0333 0316 059A 0062; # (a◌̳◌֚◌̖◌᷺b; a◌᷺◌̳◌̖◌֚b; a◌᷺◌̳◌̖◌֚b; a◌᷺◌̳◌̖◌֚b; a◌᷺◌̳◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOUBLE LOW LINE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 16FF0 0334 0334 0062;0061 0334 0334 16FF0 0062;0061 0334 0334 16FF0 0062;0061 0334 0334 16FF0 0062;0061 0334 0334 16FF0 0062; # (a𖿰◌̴◌̴b; a◌̴◌̴𖿰b; a◌̴◌̴𖿰b; a◌̴◌̴𖿰b; a◌̴◌̴𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
0061 0334 16FF0 0334 0062;0061 0334 0334 16FF0 0062;0061 0334 0334 16FF0 0062;0061 0334 0334 16FF0 0062;0061 0334 0334 16FF0 0062; # (a◌̴𖿰◌̴b; a◌̴◌̴𖿰b; a◌̴◌̴𖿰b; a◌̴◌̴𖿰b; a◌̴◌̴𖿰b; ) LATIN SMALL LETTER A, COMBINING TILDE OVERLAY, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
0061 16FF0 0334 0335 0062;0061 0334 0335 16FF0 0062;0061 0334 0335 16FF0 0062;0061 0334 0335 16FF0 0062;0061 0334 0335 16FF0 0062; # (a𖿰◌̴◌̵b; a◌̴◌̵𖿰b; a◌̴◌̵𖿰b; a◌̴◌̵𖿰b; a◌̴◌̵𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, COMBINING SHORT STROKE OVERLAY, LATIN SMALL LETTER B
@@ -17095,14 +17154,14 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 0337 16FF0 0334 0062;0061 0337 0334 16FF0 0062;0061 0337 0334 16FF0 0062;0061 0337 0334 16FF0 0062;0061 0337 0334 16FF0 0062; # (a◌̷𖿰◌̴b; a◌̷◌̴𖿰b; a◌̷◌̴𖿰b; a◌̷◌̴𖿰b; a◌̷◌̴𖿰b; ) LATIN SMALL LETTER A, COMBINING SHORT SOLIDUS OVERLAY, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
0061 16FF0 0334 0338 0062;0061 0334 0338 16FF0 0062;0061 0334 0338 16FF0 0062;0061 0334 0338 16FF0 0062;0061 0334 0338 16FF0 0062; # (a𖿰◌̴◌̸b; a◌̴◌̸𖿰b; a◌̴◌̸𖿰b; a◌̴◌̸𖿰b; a◌̴◌̸𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, COMBINING LONG SOLIDUS OVERLAY, LATIN SMALL LETTER B
0061 0338 16FF0 0334 0062;0061 0338 0334 16FF0 0062;0061 0338 0334 16FF0 0062;0061 0338 0334 16FF0 0062;0061 0338 0334 16FF0 0062; # (a◌̸𖿰◌̴b; a◌̸◌̴𖿰b; a◌̸◌̴𖿰b; a◌̸◌̴𖿰b; a◌̸◌̴𖿰b; ) LATIN SMALL LETTER A, COMBINING LONG SOLIDUS OVERLAY, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
-0061 059A 0316 302A 0339 0062;0061 302A 0316 0339 059A 0062;0061 302A 0316 0339 059A 0062;0061 302A 0316 0339 059A 0062;0061 302A 0316 0339 059A 0062; # (a◌֚◌̖◌〪◌̹b; a◌〪◌̖◌̹◌֚b; a◌〪◌̖◌̹◌֚b; a◌〪◌̖◌̹◌֚b; a◌〪◌̖◌̹◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RIGHT HALF RING BELOW, LATIN SMALL LETTER B
-0061 0339 059A 0316 302A 0062;0061 302A 0339 0316 059A 0062;0061 302A 0339 0316 059A 0062;0061 302A 0339 0316 059A 0062;0061 302A 0339 0316 059A 0062; # (a◌̹◌֚◌̖◌〪b; a◌〪◌̹◌̖◌֚b; a◌〪◌̹◌̖◌֚b; a◌〪◌̹◌̖◌֚b; a◌〪◌̹◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT HALF RING BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 033A 0062;0061 302A 0316 033A 059A 0062;0061 302A 0316 033A 059A 0062;0061 302A 0316 033A 059A 0062;0061 302A 0316 033A 059A 0062; # (a◌֚◌̖◌〪◌̺b; a◌〪◌̖◌̺◌֚b; a◌〪◌̖◌̺◌֚b; a◌〪◌̖◌̺◌֚b; a◌〪◌̖◌̺◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING INVERTED BRIDGE BELOW, LATIN SMALL LETTER B
-0061 033A 059A 0316 302A 0062;0061 302A 033A 0316 059A 0062;0061 302A 033A 0316 059A 0062;0061 302A 033A 0316 059A 0062;0061 302A 033A 0316 059A 0062; # (a◌̺◌֚◌̖◌〪b; a◌〪◌̺◌̖◌֚b; a◌〪◌̺◌̖◌֚b; a◌〪◌̺◌̖◌֚b; a◌〪◌̺◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING INVERTED BRIDGE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 033B 0062;0061 302A 0316 033B 059A 0062;0061 302A 0316 033B 059A 0062;0061 302A 0316 033B 059A 0062;0061 302A 0316 033B 059A 0062; # (a◌֚◌̖◌〪◌̻b; a◌〪◌̖◌̻◌֚b; a◌〪◌̖◌̻◌֚b; a◌〪◌̖◌̻◌֚b; a◌〪◌̖◌̻◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING SQUARE BELOW, LATIN SMALL LETTER B
-0061 033B 059A 0316 302A 0062;0061 302A 033B 0316 059A 0062;0061 302A 033B 0316 059A 0062;0061 302A 033B 0316 059A 0062;0061 302A 033B 0316 059A 0062; # (a◌̻◌֚◌̖◌〪b; a◌〪◌̻◌̖◌֚b; a◌〪◌̻◌̖◌֚b; a◌〪◌̻◌̖◌֚b; a◌〪◌̻◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING SQUARE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 033C 0062;0061 302A 0316 033C 059A 0062;0061 302A 0316 033C 059A 0062;0061 302A 0316 033C 059A 0062;0061 302A 0316 033C 059A 0062; # (a◌֚◌̖◌〪◌̼b; a◌〪◌̖◌̼◌֚b; a◌〪◌̖◌̼◌֚b; a◌〪◌̖◌̼◌֚b; a◌〪◌̖◌̼◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING SEAGULL BELOW, LATIN SMALL LETTER B
-0061 033C 059A 0316 302A 0062;0061 302A 033C 0316 059A 0062;0061 302A 033C 0316 059A 0062;0061 302A 033C 0316 059A 0062;0061 302A 033C 0316 059A 0062; # (a◌̼◌֚◌̖◌〪b; a◌〪◌̼◌̖◌֚b; a◌〪◌̼◌̖◌֚b; a◌〪◌̼◌̖◌֚b; a◌〪◌̼◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING SEAGULL BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0339 0062;0061 1DFA 0316 0339 059A 0062;0061 1DFA 0316 0339 059A 0062;0061 1DFA 0316 0339 059A 0062;0061 1DFA 0316 0339 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, COMBINING RIGHT HALF RING BELOW, LATIN SMALL LETTER B
+0061 0339 059A 0316 1DFA 0062;0061 1DFA 0339 0316 059A 0062;0061 1DFA 0339 0316 059A 0062;0061 1DFA 0339 0316 059A 0062;0061 1DFA 0339 0316 059A 0062; # (a◌̹◌֚◌̖◌᷺b; a◌᷺◌̹◌̖◌֚b; a◌᷺◌̹◌̖◌֚b; a◌᷺◌̹◌̖◌֚b; a◌᷺◌̹◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT HALF RING BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 033A 0062;0061 1DFA 0316 033A 059A 0062;0061 1DFA 0316 033A 059A 0062;0061 1DFA 0316 033A 059A 0062;0061 1DFA 0316 033A 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, COMBINING INVERTED BRIDGE BELOW, LATIN SMALL LETTER B
+0061 033A 059A 0316 1DFA 0062;0061 1DFA 033A 0316 059A 0062;0061 1DFA 033A 0316 059A 0062;0061 1DFA 033A 0316 059A 0062;0061 1DFA 033A 0316 059A 0062; # (a◌̺◌֚◌̖◌᷺b; a◌᷺◌̺◌̖◌֚b; a◌᷺◌̺◌̖◌֚b; a◌᷺◌̺◌̖◌֚b; a◌᷺◌̺◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING INVERTED BRIDGE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 033B 0062;0061 1DFA 0316 033B 059A 0062;0061 1DFA 0316 033B 059A 0062;0061 1DFA 0316 033B 059A 0062;0061 1DFA 0316 033B 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, COMBINING SQUARE BELOW, LATIN SMALL LETTER B
+0061 033B 059A 0316 1DFA 0062;0061 1DFA 033B 0316 059A 0062;0061 1DFA 033B 0316 059A 0062;0061 1DFA 033B 0316 059A 0062;0061 1DFA 033B 0316 059A 0062; # (a◌̻◌֚◌̖◌᷺b; a◌᷺◌̻◌̖◌֚b; a◌᷺◌̻◌̖◌֚b; a◌᷺◌̻◌̖◌֚b; a◌᷺◌̻◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING SQUARE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 033C 0062;0061 1DFA 0316 033C 059A 0062;0061 1DFA 0316 033C 059A 0062;0061 1DFA 0316 033C 059A 0062;0061 1DFA 0316 033C 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, COMBINING SEAGULL BELOW, LATIN SMALL LETTER B
+0061 033C 059A 0316 1DFA 0062;0061 1DFA 033C 0316 059A 0062;0061 1DFA 033C 0316 059A 0062;0061 1DFA 033C 0316 059A 0062;0061 1DFA 033C 0316 059A 0062; # (a◌̼◌֚◌̖◌᷺b; a◌᷺◌̼◌̖◌֚b; a◌᷺◌̼◌̖◌֚b; a◌᷺◌̼◌̖◌֚b; a◌᷺◌̼◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING SEAGULL BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 033D 0062;00E0 05AE 033D 0315 0062;0061 05AE 0300 033D 0315 0062;00E0 05AE 033D 0315 0062;0061 05AE 0300 033D 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 X ABOVE, LATIN SMALL LETTER B
0061 033D 0315 0300 05AE 0062;0061 05AE 033D 0300 0315 0062;0061 05AE 033D 0300 0315 0062;0061 05AE 033D 0300 0315 0062;0061 05AE 033D 0300 0315 0062; # (a◌̽◌̕◌̀◌֮b; a◌֮◌̽◌̀◌̕b; a◌֮◌̽◌̀◌̕b; a◌֮◌̽◌̀◌̕b; a◌֮◌̽◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING X ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 033E 0062;00E0 05AE 033E 0315 0062;0061 05AE 0300 033E 0315 0062;00E0 05AE 033E 0315 0062;0061 05AE 0300 033E 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 VERTICAL TILDE, LATIN SMALL LETTER B
@@ -17123,44 +17182,44 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 0345 0345 035D 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062; # (a◌ͅ◌ͅ◌͝b; a◌͝◌ͅ◌ͅb; a◌͝◌ͅ◌ͅb; a◌͝◌ͅ◌ͅb; a◌͝◌ͅ◌ͅb; ) LATIN SMALL LETTER A, COMBINING GREEK YPOGEGRAMMENI, COMBINING GREEK YPOGEGRAMMENI, COMBINING DOUBLE BREVE, LATIN SMALL LETTER B
0061 0315 0300 05AE 0346 0062;00E0 05AE 0346 0315 0062;0061 05AE 0300 0346 0315 0062;00E0 05AE 0346 0315 0062;0061 05AE 0300 0346 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 BRIDGE ABOVE, LATIN SMALL LETTER B
0061 0346 0315 0300 05AE 0062;0061 05AE 0346 0300 0315 0062;0061 05AE 0346 0300 0315 0062;0061 05AE 0346 0300 0315 0062;0061 05AE 0346 0300 0315 0062; # (a◌͆◌̕◌̀◌֮b; a◌֮◌͆◌̀◌̕b; a◌֮◌͆◌̀◌̕b; a◌֮◌͆◌̀◌̕b; a◌֮◌͆◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING BRIDGE ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 0347 0062;0061 302A 0316 0347 059A 0062;0061 302A 0316 0347 059A 0062;0061 302A 0316 0347 059A 0062;0061 302A 0316 0347 059A 0062; # (a◌֚◌̖◌〪◌͇b; a◌〪◌̖◌͇◌֚b; a◌〪◌̖◌͇◌֚b; a◌〪◌̖◌͇◌֚b; a◌〪◌̖◌͇◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING EQUALS SIGN BELOW, LATIN SMALL LETTER B
-0061 0347 059A 0316 302A 0062;0061 302A 0347 0316 059A 0062;0061 302A 0347 0316 059A 0062;0061 302A 0347 0316 059A 0062;0061 302A 0347 0316 059A 0062; # (a◌͇◌֚◌̖◌〪b; a◌〪◌͇◌̖◌֚b; a◌〪◌͇◌̖◌֚b; a◌〪◌͇◌̖◌֚b; a◌〪◌͇◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING EQUALS SIGN BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0348 0062;0061 302A 0316 0348 059A 0062;0061 302A 0316 0348 059A 0062;0061 302A 0316 0348 059A 0062;0061 302A 0316 0348 059A 0062; # (a◌֚◌̖◌〪◌͈b; a◌〪◌̖◌͈◌֚b; a◌〪◌̖◌͈◌֚b; a◌〪◌̖◌͈◌֚b; a◌〪◌̖◌͈◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING DOUBLE VERTICAL LINE BELOW, LATIN SMALL LETTER B
-0061 0348 059A 0316 302A 0062;0061 302A 0348 0316 059A 0062;0061 302A 0348 0316 059A 0062;0061 302A 0348 0316 059A 0062;0061 302A 0348 0316 059A 0062; # (a◌͈◌֚◌̖◌〪b; a◌〪◌͈◌̖◌֚b; a◌〪◌͈◌̖◌֚b; a◌〪◌͈◌̖◌֚b; a◌〪◌͈◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOUBLE VERTICAL LINE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0349 0062;0061 302A 0316 0349 059A 0062;0061 302A 0316 0349 059A 0062;0061 302A 0316 0349 059A 0062;0061 302A 0316 0349 059A 0062; # (a◌֚◌̖◌〪◌͉b; a◌〪◌̖◌͉◌֚b; a◌〪◌̖◌͉◌֚b; a◌〪◌̖◌͉◌֚b; a◌〪◌̖◌͉◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LEFT ANGLE BELOW, LATIN SMALL LETTER B
-0061 0349 059A 0316 302A 0062;0061 302A 0349 0316 059A 0062;0061 302A 0349 0316 059A 0062;0061 302A 0349 0316 059A 0062;0061 302A 0349 0316 059A 0062; # (a◌͉◌֚◌̖◌〪b; a◌〪◌͉◌̖◌֚b; a◌〪◌͉◌̖◌֚b; a◌〪◌͉◌̖◌֚b; a◌〪◌͉◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT ANGLE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0347 0062;0061 1DFA 0316 0347 059A 0062;0061 1DFA 0316 0347 059A 0062;0061 1DFA 0316 0347 059A 0062;0061 1DFA 0316 0347 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, COMBINING EQUALS SIGN BELOW, LATIN SMALL LETTER B
+0061 0347 059A 0316 1DFA 0062;0061 1DFA 0347 0316 059A 0062;0061 1DFA 0347 0316 059A 0062;0061 1DFA 0347 0316 059A 0062;0061 1DFA 0347 0316 059A 0062; # (a◌͇◌֚◌̖◌᷺b; a◌᷺◌͇◌̖◌֚b; a◌᷺◌͇◌̖◌֚b; a◌᷺◌͇◌̖◌֚b; a◌᷺◌͇◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING EQUALS SIGN BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0348 0062;0061 1DFA 0316 0348 059A 0062;0061 1DFA 0316 0348 059A 0062;0061 1DFA 0316 0348 059A 0062;0061 1DFA 0316 0348 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, COMBINING DOUBLE VERTICAL LINE BELOW, LATIN SMALL LETTER B
+0061 0348 059A 0316 1DFA 0062;0061 1DFA 0348 0316 059A 0062;0061 1DFA 0348 0316 059A 0062;0061 1DFA 0348 0316 059A 0062;0061 1DFA 0348 0316 059A 0062; # (a◌͈◌֚◌̖◌᷺b; a◌᷺◌͈◌̖◌֚b; a◌᷺◌͈◌̖◌֚b; a◌᷺◌͈◌̖◌֚b; a◌᷺◌͈◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOUBLE VERTICAL LINE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0349 0062;0061 1DFA 0316 0349 059A 0062;0061 1DFA 0316 0349 059A 0062;0061 1DFA 0316 0349 059A 0062;0061 1DFA 0316 0349 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, COMBINING LEFT ANGLE BELOW, LATIN SMALL LETTER B
+0061 0349 059A 0316 1DFA 0062;0061 1DFA 0349 0316 059A 0062;0061 1DFA 0349 0316 059A 0062;0061 1DFA 0349 0316 059A 0062;0061 1DFA 0349 0316 059A 0062; # (a◌͉◌֚◌̖◌᷺b; a◌᷺◌͉◌̖◌֚b; a◌᷺◌͉◌̖◌֚b; a◌᷺◌͉◌̖◌֚b; a◌᷺◌͉◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT ANGLE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 034A 0062;00E0 05AE 034A 0315 0062;0061 05AE 0300 034A 0315 0062;00E0 05AE 034A 0315 0062;0061 05AE 0300 034A 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 NOT TILDE ABOVE, LATIN SMALL LETTER B
0061 034A 0315 0300 05AE 0062;0061 05AE 034A 0300 0315 0062;0061 05AE 034A 0300 0315 0062;0061 05AE 034A 0300 0315 0062;0061 05AE 034A 0300 0315 0062; # (a◌͊◌̕◌̀◌֮b; a◌֮◌͊◌̀◌̕b; a◌֮◌͊◌̀◌̕b; a◌֮◌͊◌̀◌̕b; a◌֮◌͊◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING NOT TILDE ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 034B 0062;00E0 05AE 034B 0315 0062;0061 05AE 0300 034B 0315 0062;00E0 05AE 034B 0315 0062;0061 05AE 0300 034B 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 HOMOTHETIC ABOVE, LATIN SMALL LETTER B
0061 034B 0315 0300 05AE 0062;0061 05AE 034B 0300 0315 0062;0061 05AE 034B 0300 0315 0062;0061 05AE 034B 0300 0315 0062;0061 05AE 034B 0300 0315 0062; # (a◌͋◌̕◌̀◌֮b; a◌֮◌͋◌̀◌̕b; a◌֮◌͋◌̀◌̕b; a◌֮◌͋◌̀◌̕b; a◌֮◌͋◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING HOMOTHETIC ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 034C 0062;00E0 05AE 034C 0315 0062;0061 05AE 0300 034C 0315 0062;00E0 05AE 034C 0315 0062;0061 05AE 0300 034C 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 ALMOST EQUAL TO ABOVE, LATIN SMALL LETTER B
0061 034C 0315 0300 05AE 0062;0061 05AE 034C 0300 0315 0062;0061 05AE 034C 0300 0315 0062;0061 05AE 034C 0300 0315 0062;0061 05AE 034C 0300 0315 0062; # (a◌͌◌̕◌̀◌֮b; a◌֮◌͌◌̀◌̕b; a◌֮◌͌◌̀◌̕b; a◌֮◌͌◌̀◌̕b; a◌֮◌͌◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING ALMOST EQUAL TO ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 034D 0062;0061 302A 0316 034D 059A 0062;0061 302A 0316 034D 059A 0062;0061 302A 0316 034D 059A 0062;0061 302A 0316 034D 059A 0062; # (a◌֚◌̖◌〪◌͍b; a◌〪◌̖◌͍◌֚b; a◌〪◌̖◌͍◌֚b; a◌〪◌̖◌͍◌֚b; a◌〪◌̖◌͍◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LEFT RIGHT ARROW BELOW, LATIN SMALL LETTER B
-0061 034D 059A 0316 302A 0062;0061 302A 034D 0316 059A 0062;0061 302A 034D 0316 059A 0062;0061 302A 034D 0316 059A 0062;0061 302A 034D 0316 059A 0062; # (a◌͍◌֚◌̖◌〪b; a◌〪◌͍◌̖◌֚b; a◌〪◌͍◌̖◌֚b; a◌〪◌͍◌̖◌֚b; a◌〪◌͍◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT RIGHT ARROW BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 034E 0062;0061 302A 0316 034E 059A 0062;0061 302A 0316 034E 059A 0062;0061 302A 0316 034E 059A 0062;0061 302A 0316 034E 059A 0062; # (a◌֚◌̖◌〪◌͎b; a◌〪◌̖◌͎◌֚b; a◌〪◌̖◌͎◌֚b; a◌〪◌̖◌͎◌֚b; a◌〪◌̖◌͎◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING UPWARDS ARROW BELOW, LATIN SMALL LETTER B
-0061 034E 059A 0316 302A 0062;0061 302A 034E 0316 059A 0062;0061 302A 034E 0316 059A 0062;0061 302A 034E 0316 059A 0062;0061 302A 034E 0316 059A 0062; # (a◌͎◌֚◌̖◌〪b; a◌〪◌͎◌̖◌֚b; a◌〪◌͎◌̖◌֚b; a◌〪◌͎◌̖◌֚b; a◌〪◌͎◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING UPWARDS ARROW BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 034D 0062;0061 1DFA 0316 034D 059A 0062;0061 1DFA 0316 034D 059A 0062;0061 1DFA 0316 034D 059A 0062;0061 1DFA 0316 034D 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, COMBINING LEFT RIGHT ARROW BELOW, LATIN SMALL LETTER B
+0061 034D 059A 0316 1DFA 0062;0061 1DFA 034D 0316 059A 0062;0061 1DFA 034D 0316 059A 0062;0061 1DFA 034D 0316 059A 0062;0061 1DFA 034D 0316 059A 0062; # (a◌͍◌֚◌̖◌᷺b; a◌᷺◌͍◌̖◌֚b; a◌᷺◌͍◌̖◌֚b; a◌᷺◌͍◌̖◌֚b; a◌᷺◌͍◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT RIGHT ARROW BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 034E 0062;0061 1DFA 0316 034E 059A 0062;0061 1DFA 0316 034E 059A 0062;0061 1DFA 0316 034E 059A 0062;0061 1DFA 0316 034E 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, COMBINING UPWARDS ARROW BELOW, LATIN SMALL LETTER B
+0061 034E 059A 0316 1DFA 0062;0061 1DFA 034E 0316 059A 0062;0061 1DFA 034E 0316 059A 0062;0061 1DFA 034E 0316 059A 0062;0061 1DFA 034E 0316 059A 0062; # (a◌͎◌֚◌̖◌᷺b; a◌᷺◌͎◌̖◌֚b; a◌᷺◌͎◌̖◌֚b; a◌᷺◌͎◌̖◌֚b; a◌᷺◌͎◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING UPWARDS ARROW BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 0350 0062;00E0 05AE 0350 0315 0062;0061 05AE 0300 0350 0315 0062;00E0 05AE 0350 0315 0062;0061 05AE 0300 0350 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 RIGHT ARROWHEAD ABOVE, LATIN SMALL LETTER B
0061 0350 0315 0300 05AE 0062;0061 05AE 0350 0300 0315 0062;0061 05AE 0350 0300 0315 0062;0061 05AE 0350 0300 0315 0062;0061 05AE 0350 0300 0315 0062; # (a◌͐◌̕◌̀◌֮b; a◌֮◌͐◌̀◌̕b; a◌֮◌͐◌̀◌̕b; a◌֮◌͐◌̀◌̕b; a◌֮◌͐◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING RIGHT ARROWHEAD ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 0351 0062;00E0 05AE 0351 0315 0062;0061 05AE 0300 0351 0315 0062;00E0 05AE 0351 0315 0062;0061 05AE 0300 0351 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 LEFT HALF RING ABOVE, LATIN SMALL LETTER B
0061 0351 0315 0300 05AE 0062;0061 05AE 0351 0300 0315 0062;0061 05AE 0351 0300 0315 0062;0061 05AE 0351 0300 0315 0062;0061 05AE 0351 0300 0315 0062; # (a◌͑◌̕◌̀◌֮b; a◌֮◌͑◌̀◌̕b; a◌֮◌͑◌̀◌̕b; a◌֮◌͑◌̀◌̕b; a◌֮◌͑◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LEFT HALF RING ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 0352 0062;00E0 05AE 0352 0315 0062;0061 05AE 0300 0352 0315 0062;00E0 05AE 0352 0315 0062;0061 05AE 0300 0352 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 FERMATA, LATIN SMALL LETTER B
0061 0352 0315 0300 05AE 0062;0061 05AE 0352 0300 0315 0062;0061 05AE 0352 0300 0315 0062;0061 05AE 0352 0300 0315 0062;0061 05AE 0352 0300 0315 0062; # (a◌͒◌̕◌̀◌֮b; a◌֮◌͒◌̀◌̕b; a◌֮◌͒◌̀◌̕b; a◌֮◌͒◌̀◌̕b; a◌֮◌͒◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING FERMATA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 0353 0062;0061 302A 0316 0353 059A 0062;0061 302A 0316 0353 059A 0062;0061 302A 0316 0353 059A 0062;0061 302A 0316 0353 059A 0062; # (a◌֚◌̖◌〪◌͓b; a◌〪◌̖◌͓◌֚b; a◌〪◌̖◌͓◌֚b; a◌〪◌̖◌͓◌֚b; a◌〪◌̖◌͓◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING X BELOW, LATIN SMALL LETTER B
-0061 0353 059A 0316 302A 0062;0061 302A 0353 0316 059A 0062;0061 302A 0353 0316 059A 0062;0061 302A 0353 0316 059A 0062;0061 302A 0353 0316 059A 0062; # (a◌͓◌֚◌̖◌〪b; a◌〪◌͓◌̖◌֚b; a◌〪◌͓◌̖◌֚b; a◌〪◌͓◌̖◌֚b; a◌〪◌͓◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING X BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0354 0062;0061 302A 0316 0354 059A 0062;0061 302A 0316 0354 059A 0062;0061 302A 0316 0354 059A 0062;0061 302A 0316 0354 059A 0062; # (a◌֚◌̖◌〪◌͔b; a◌〪◌̖◌͔◌֚b; a◌〪◌̖◌͔◌֚b; a◌〪◌̖◌͔◌֚b; a◌〪◌̖◌͔◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LEFT ARROWHEAD BELOW, LATIN SMALL LETTER B
-0061 0354 059A 0316 302A 0062;0061 302A 0354 0316 059A 0062;0061 302A 0354 0316 059A 0062;0061 302A 0354 0316 059A 0062;0061 302A 0354 0316 059A 0062; # (a◌͔◌֚◌̖◌〪b; a◌〪◌͔◌̖◌֚b; a◌〪◌͔◌̖◌֚b; a◌〪◌͔◌̖◌֚b; a◌〪◌͔◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0355 0062;0061 302A 0316 0355 059A 0062;0061 302A 0316 0355 059A 0062;0061 302A 0316 0355 059A 0062;0061 302A 0316 0355 059A 0062; # (a◌֚◌̖◌〪◌͕b; a◌〪◌̖◌͕◌֚b; a◌〪◌̖◌͕◌֚b; a◌〪◌̖◌͕◌֚b; a◌〪◌̖◌͕◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RIGHT ARROWHEAD BELOW, LATIN SMALL LETTER B
-0061 0355 059A 0316 302A 0062;0061 302A 0355 0316 059A 0062;0061 302A 0355 0316 059A 0062;0061 302A 0355 0316 059A 0062;0061 302A 0355 0316 059A 0062; # (a◌͕◌֚◌̖◌〪b; a◌〪◌͕◌̖◌֚b; a◌〪◌͕◌̖◌֚b; a◌〪◌͕◌̖◌֚b; a◌〪◌͕◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0356 0062;0061 302A 0316 0356 059A 0062;0061 302A 0316 0356 059A 0062;0061 302A 0316 0356 059A 0062;0061 302A 0316 0356 059A 0062; # (a◌֚◌̖◌〪◌͖b; a◌〪◌̖◌͖◌֚b; a◌〪◌̖◌͖◌֚b; a◌〪◌̖◌͖◌֚b; a◌〪◌̖◌͖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW, LATIN SMALL LETTER B
-0061 0356 059A 0316 302A 0062;0061 302A 0356 0316 059A 0062;0061 302A 0356 0316 059A 0062;0061 302A 0356 0316 059A 0062;0061 302A 0356 0316 059A 0062; # (a◌͖◌֚◌̖◌〪b; a◌〪◌͖◌̖◌֚b; a◌〪◌͖◌̖◌֚b; a◌〪◌͖◌̖◌֚b; a◌〪◌͖◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0353 0062;0061 1DFA 0316 0353 059A 0062;0061 1DFA 0316 0353 059A 0062;0061 1DFA 0316 0353 059A 0062;0061 1DFA 0316 0353 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, COMBINING X BELOW, LATIN SMALL LETTER B
+0061 0353 059A 0316 1DFA 0062;0061 1DFA 0353 0316 059A 0062;0061 1DFA 0353 0316 059A 0062;0061 1DFA 0353 0316 059A 0062;0061 1DFA 0353 0316 059A 0062; # (a◌͓◌֚◌̖◌᷺b; a◌᷺◌͓◌̖◌֚b; a◌᷺◌͓◌̖◌֚b; a◌᷺◌͓◌̖◌֚b; a◌᷺◌͓◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING X BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0354 0062;0061 1DFA 0316 0354 059A 0062;0061 1DFA 0316 0354 059A 0062;0061 1DFA 0316 0354 059A 0062;0061 1DFA 0316 0354 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, COMBINING LEFT ARROWHEAD BELOW, LATIN SMALL LETTER B
+0061 0354 059A 0316 1DFA 0062;0061 1DFA 0354 0316 059A 0062;0061 1DFA 0354 0316 059A 0062;0061 1DFA 0354 0316 059A 0062;0061 1DFA 0354 0316 059A 0062; # (a◌͔◌֚◌̖◌᷺b; a◌᷺◌͔◌̖◌֚b; a◌᷺◌͔◌̖◌֚b; a◌᷺◌͔◌̖◌֚b; a◌᷺◌͔◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0355 0062;0061 1DFA 0316 0355 059A 0062;0061 1DFA 0316 0355 059A 0062;0061 1DFA 0316 0355 059A 0062;0061 1DFA 0316 0355 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, COMBINING RIGHT ARROWHEAD BELOW, LATIN SMALL LETTER B
+0061 0355 059A 0316 1DFA 0062;0061 1DFA 0355 0316 059A 0062;0061 1DFA 0355 0316 059A 0062;0061 1DFA 0355 0316 059A 0062;0061 1DFA 0355 0316 059A 0062; # (a◌͕◌֚◌̖◌᷺b; a◌᷺◌͕◌̖◌֚b; a◌᷺◌͕◌̖◌֚b; a◌᷺◌͕◌̖◌֚b; a◌᷺◌͕◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0356 0062;0061 1DFA 0316 0356 059A 0062;0061 1DFA 0316 0356 059A 0062;0061 1DFA 0316 0356 059A 0062;0061 1DFA 0316 0356 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, COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW, LATIN SMALL LETTER B
+0061 0356 059A 0316 1DFA 0062;0061 1DFA 0356 0316 059A 0062;0061 1DFA 0356 0316 059A 0062;0061 1DFA 0356 0316 059A 0062;0061 1DFA 0356 0316 059A 0062; # (a◌͖◌֚◌̖◌᷺b; a◌᷺◌͖◌̖◌֚b; a◌᷺◌͖◌̖◌֚b; a◌᷺◌͖◌̖◌֚b; a◌᷺◌͖◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 0357 0062;00E0 05AE 0357 0315 0062;0061 05AE 0300 0357 0315 0062;00E0 05AE 0357 0315 0062;0061 05AE 0300 0357 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 RIGHT HALF RING ABOVE, LATIN SMALL LETTER B
0061 0357 0315 0300 05AE 0062;0061 05AE 0357 0300 0315 0062;0061 05AE 0357 0300 0315 0062;0061 05AE 0357 0300 0315 0062;0061 05AE 0357 0300 0315 0062; # (a◌͗◌̕◌̀◌֮b; a◌֮◌͗◌̀◌̕b; a◌֮◌͗◌̀◌̕b; a◌֮◌͗◌̀◌̕b; a◌֮◌͗◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING RIGHT HALF RING ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 035C 0315 0300 0358 0062;00E0 0315 0358 035C 0062;0061 0300 0315 0358 035C 0062;00E0 0315 0358 035C 0062;0061 0300 0315 0358 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, COMBINING DOT ABOVE RIGHT, LATIN SMALL LETTER B
0061 0358 035C 0315 0300 0062;00E0 0358 0315 035C 0062;0061 0300 0358 0315 035C 0062;00E0 0358 0315 035C 0062;0061 0300 0358 0315 035C 0062; # (a◌͘◌͜◌̕◌̀b; à◌͘◌̕◌͜b; a◌̀◌͘◌̕◌͜b; à◌͘◌̕◌͜b; a◌̀◌͘◌̕◌͜b; ) LATIN SMALL LETTER A, COMBINING DOT ABOVE RIGHT, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, LATIN SMALL LETTER B
-0061 059A 0316 302A 0359 0062;0061 302A 0316 0359 059A 0062;0061 302A 0316 0359 059A 0062;0061 302A 0316 0359 059A 0062;0061 302A 0316 0359 059A 0062; # (a◌֚◌̖◌〪◌͙b; a◌〪◌̖◌͙◌֚b; a◌〪◌̖◌͙◌֚b; a◌〪◌̖◌͙◌֚b; a◌〪◌̖◌͙◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING ASTERISK BELOW, LATIN SMALL LETTER B
-0061 0359 059A 0316 302A 0062;0061 302A 0359 0316 059A 0062;0061 302A 0359 0316 059A 0062;0061 302A 0359 0316 059A 0062;0061 302A 0359 0316 059A 0062; # (a◌͙◌֚◌̖◌〪b; a◌〪◌͙◌̖◌֚b; a◌〪◌͙◌̖◌֚b; a◌〪◌͙◌̖◌֚b; a◌〪◌͙◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING ASTERISK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 035A 0062;0061 302A 0316 035A 059A 0062;0061 302A 0316 035A 059A 0062;0061 302A 0316 035A 059A 0062;0061 302A 0316 035A 059A 0062; # (a◌֚◌̖◌〪◌͚b; a◌〪◌̖◌͚◌֚b; a◌〪◌̖◌͚◌֚b; a◌〪◌̖◌͚◌֚b; a◌〪◌̖◌͚◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING DOUBLE RING BELOW, LATIN SMALL LETTER B
-0061 035A 059A 0316 302A 0062;0061 302A 035A 0316 059A 0062;0061 302A 035A 0316 059A 0062;0061 302A 035A 0316 059A 0062;0061 302A 035A 0316 059A 0062; # (a◌͚◌֚◌̖◌〪b; a◌〪◌͚◌̖◌֚b; a◌〪◌͚◌̖◌֚b; a◌〪◌͚◌̖◌֚b; a◌〪◌͚◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOUBLE RING BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0359 0062;0061 1DFA 0316 0359 059A 0062;0061 1DFA 0316 0359 059A 0062;0061 1DFA 0316 0359 059A 0062;0061 1DFA 0316 0359 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, COMBINING ASTERISK BELOW, LATIN SMALL LETTER B
+0061 0359 059A 0316 1DFA 0062;0061 1DFA 0359 0316 059A 0062;0061 1DFA 0359 0316 059A 0062;0061 1DFA 0359 0316 059A 0062;0061 1DFA 0359 0316 059A 0062; # (a◌͙◌֚◌̖◌᷺b; a◌᷺◌͙◌̖◌֚b; a◌᷺◌͙◌̖◌֚b; a◌᷺◌͙◌̖◌֚b; a◌᷺◌͙◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING ASTERISK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 035A 0062;0061 1DFA 0316 035A 059A 0062;0061 1DFA 0316 035A 059A 0062;0061 1DFA 0316 035A 059A 0062;0061 1DFA 0316 035A 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, COMBINING DOUBLE RING BELOW, LATIN SMALL LETTER B
+0061 035A 059A 0316 1DFA 0062;0061 1DFA 035A 0316 059A 0062;0061 1DFA 035A 0316 059A 0062;0061 1DFA 035A 0316 059A 0062;0061 1DFA 035A 0316 059A 0062; # (a◌͚◌֚◌̖◌᷺b; a◌᷺◌͚◌̖◌֚b; a◌᷺◌͚◌̖◌֚b; a◌᷺◌͚◌̖◌֚b; a◌᷺◌͚◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOUBLE RING BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 035B 0062;00E0 05AE 035B 0315 0062;0061 05AE 0300 035B 0315 0062;00E0 05AE 035B 0315 0062;0061 05AE 0300 035B 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 ZIGZAG ABOVE, LATIN SMALL LETTER B
0061 035B 0315 0300 05AE 0062;0061 05AE 035B 0300 0315 0062;0061 05AE 035B 0300 0315 0062;0061 05AE 035B 0300 0315 0062;0061 05AE 035B 0300 0315 0062; # (a◌͛◌̕◌̀◌֮b; a◌֮◌͛◌̀◌̕b; a◌֮◌͛◌̀◌̕b; a◌֮◌͛◌̀◌̕b; a◌֮◌͛◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING ZIGZAG ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 035D 035C 0315 035C 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062; # (a◌͝◌͜◌̕◌͜b; a◌̕◌͜◌͜◌͝b; a◌̕◌͜◌͜◌͝b; a◌̕◌͜◌͜◌͝b; a◌̕◌͜◌͜◌͝b; ) LATIN SMALL LETTER A, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING DOUBLE BREVE BELOW, LATIN SMALL LETTER B
@@ -17213,8 +17272,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 0486 0315 0300 05AE 0062;0061 05AE 0486 0300 0315 0062;0061 05AE 0486 0300 0315 0062;0061 05AE 0486 0300 0315 0062;0061 05AE 0486 0300 0315 0062; # (a◌҆◌̕◌̀◌֮b; a◌֮◌҆◌̀◌̕b; a◌֮◌҆◌̀◌̕b; a◌֮◌҆◌̀◌̕b; a◌֮◌҆◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC PSILI PNEUMATA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 0487 0062;00E0 05AE 0487 0315 0062;0061 05AE 0300 0487 0315 0062;00E0 05AE 0487 0315 0062;0061 05AE 0300 0487 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 POKRYTIE, LATIN SMALL LETTER B
0061 0487 0315 0300 05AE 0062;0061 05AE 0487 0300 0315 0062;0061 05AE 0487 0300 0315 0062;0061 05AE 0487 0300 0315 0062;0061 05AE 0487 0300 0315 0062; # (a◌҇◌̕◌̀◌֮b; a◌֮◌҇◌̀◌̕b; a◌֮◌҇◌̀◌̕b; a◌֮◌҇◌̀◌̕b; a◌֮◌҇◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC POKRYTIE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 0591 0062;0061 302A 0316 0591 059A 0062;0061 302A 0316 0591 059A 0062;0061 302A 0316 0591 059A 0062;0061 302A 0316 0591 059A 0062; # (a◌֚◌̖◌〪◌֑b; a◌〪◌̖◌֑◌֚b; a◌〪◌̖◌֑◌֚b; a◌〪◌̖◌֑◌֚b; a◌〪◌̖◌֑◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT ETNAHTA, LATIN SMALL LETTER B
-0061 0591 059A 0316 302A 0062;0061 302A 0591 0316 059A 0062;0061 302A 0591 0316 059A 0062;0061 302A 0591 0316 059A 0062;0061 302A 0591 0316 059A 0062; # (a◌֑◌֚◌̖◌〪b; a◌〪◌֑◌̖◌֚b; a◌〪◌֑◌̖◌֚b; a◌〪◌֑◌̖◌֚b; a◌〪◌֑◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT ETNAHTA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0591 0062;0061 1DFA 0316 0591 059A 0062;0061 1DFA 0316 0591 059A 0062;0061 1DFA 0316 0591 059A 0062;0061 1DFA 0316 0591 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, HEBREW ACCENT ETNAHTA, LATIN SMALL LETTER B
+0061 0591 059A 0316 1DFA 0062;0061 1DFA 0591 0316 059A 0062;0061 1DFA 0591 0316 059A 0062;0061 1DFA 0591 0316 059A 0062;0061 1DFA 0591 0316 059A 0062; # (a◌֑◌֚◌̖◌᷺b; a◌᷺◌֑◌̖◌֚b; a◌᷺◌֑◌̖◌֚b; a◌᷺◌֑◌̖◌֚b; a◌᷺◌֑◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT ETNAHTA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 0592 0062;00E0 05AE 0592 0315 0062;0061 05AE 0300 0592 0315 0062;00E0 05AE 0592 0315 0062;0061 05AE 0300 0592 0315 0062; # (a◌̕◌̀◌֮◌֒b; à◌֮◌֒◌̕b; a◌֮◌̀◌֒◌̕b; à◌֮◌֒◌̕b; a◌֮◌̀◌֒◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT SEGOL, LATIN SMALL LETTER B
0061 0592 0315 0300 05AE 0062;0061 05AE 0592 0300 0315 0062;0061 05AE 0592 0300 0315 0062;0061 05AE 0592 0300 0315 0062;0061 05AE 0592 0300 0315 0062; # (a◌֒◌̕◌̀◌֮b; a◌֮◌֒◌̀◌̕b; a◌֮◌֒◌̀◌̕b; a◌֮◌֒◌̀◌̕b; a◌֮◌֒◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT SEGOL, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 0593 0062;00E0 05AE 0593 0315 0062;0061 05AE 0300 0593 0315 0062;00E0 05AE 0593 0315 0062;0061 05AE 0300 0593 0315 0062; # (a◌̕◌̀◌֮◌֓b; à◌֮◌֓◌̕b; a◌֮◌̀◌֓◌̕b; à◌֮◌֓◌̕b; a◌֮◌̀◌֓◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT SHALSHELET, LATIN SMALL LETTER B
@@ -17223,8 +17282,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 0594 0315 0300 05AE 0062;0061 05AE 0594 0300 0315 0062;0061 05AE 0594 0300 0315 0062;0061 05AE 0594 0300 0315 0062;0061 05AE 0594 0300 0315 0062; # (a◌֔◌̕◌̀◌֮b; a◌֮◌֔◌̀◌̕b; a◌֮◌֔◌̀◌̕b; a◌֮◌֔◌̀◌̕b; a◌֮◌֔◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT ZAQEF QATAN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 0595 0062;00E0 05AE 0595 0315 0062;0061 05AE 0300 0595 0315 0062;00E0 05AE 0595 0315 0062;0061 05AE 0300 0595 0315 0062; # (a◌̕◌̀◌֮◌֕b; à◌֮◌֕◌̕b; a◌֮◌̀◌֕◌̕b; à◌֮◌֕◌̕b; a◌֮◌̀◌֕◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT ZAQEF GADOL, LATIN SMALL LETTER B
0061 0595 0315 0300 05AE 0062;0061 05AE 0595 0300 0315 0062;0061 05AE 0595 0300 0315 0062;0061 05AE 0595 0300 0315 0062;0061 05AE 0595 0300 0315 0062; # (a◌֕◌̕◌̀◌֮b; a◌֮◌֕◌̀◌̕b; a◌֮◌֕◌̀◌̕b; a◌֮◌֕◌̀◌̕b; a◌֮◌֕◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT ZAQEF GADOL, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 0596 0062;0061 302A 0316 0596 059A 0062;0061 302A 0316 0596 059A 0062;0061 302A 0316 0596 059A 0062;0061 302A 0316 0596 059A 0062; # (a◌֚◌̖◌〪◌֖b; a◌〪◌̖◌֖◌֚b; a◌〪◌̖◌֖◌֚b; a◌〪◌̖◌֖◌֚b; a◌〪◌̖◌֖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT TIPEHA, LATIN SMALL LETTER B
-0061 0596 059A 0316 302A 0062;0061 302A 0596 0316 059A 0062;0061 302A 0596 0316 059A 0062;0061 302A 0596 0316 059A 0062;0061 302A 0596 0316 059A 0062; # (a◌֖◌֚◌̖◌〪b; a◌〪◌֖◌̖◌֚b; a◌〪◌֖◌̖◌֚b; a◌〪◌֖◌̖◌֚b; a◌〪◌֖◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT TIPEHA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0596 0062;0061 1DFA 0316 0596 059A 0062;0061 1DFA 0316 0596 059A 0062;0061 1DFA 0316 0596 059A 0062;0061 1DFA 0316 0596 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, HEBREW ACCENT TIPEHA, LATIN SMALL LETTER B
+0061 0596 059A 0316 1DFA 0062;0061 1DFA 0596 0316 059A 0062;0061 1DFA 0596 0316 059A 0062;0061 1DFA 0596 0316 059A 0062;0061 1DFA 0596 0316 059A 0062; # (a◌֖◌֚◌̖◌᷺b; a◌᷺◌֖◌̖◌֚b; a◌᷺◌֖◌̖◌֚b; a◌᷺◌֖◌̖◌֚b; a◌᷺◌֖◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT TIPEHA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 0597 0062;00E0 05AE 0597 0315 0062;0061 05AE 0300 0597 0315 0062;00E0 05AE 0597 0315 0062;0061 05AE 0300 0597 0315 0062; # (a◌̕◌̀◌֮◌֗b; à◌֮◌֗◌̕b; a◌֮◌̀◌֗◌̕b; à◌֮◌֗◌̕b; a◌֮◌̀◌֗◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT REVIA, LATIN SMALL LETTER B
0061 0597 0315 0300 05AE 0062;0061 05AE 0597 0300 0315 0062;0061 05AE 0597 0300 0315 0062;0061 05AE 0597 0300 0315 0062;0061 05AE 0597 0300 0315 0062; # (a◌֗◌̕◌̀◌֮b; a◌֮◌֗◌̀◌̕b; a◌֮◌֗◌̀◌̕b; a◌֮◌֗◌̀◌̕b; a◌֮◌֗◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT REVIA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 0598 0062;00E0 05AE 0598 0315 0062;0061 05AE 0300 0598 0315 0062;00E0 05AE 0598 0315 0062;0061 05AE 0300 0598 0315 0062; # (a◌̕◌̀◌֮◌֘b; à◌֮◌֘◌̕b; a◌֮◌̀◌֘◌̕b; à◌֮◌֘◌̕b; a◌֮◌̀◌֘◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT ZARQA, LATIN SMALL LETTER B
@@ -17233,8 +17292,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 0599 0315 0300 05AE 0062;0061 05AE 0599 0300 0315 0062;0061 05AE 0599 0300 0315 0062;0061 05AE 0599 0300 0315 0062;0061 05AE 0599 0300 0315 0062; # (a◌֙◌̕◌̀◌֮b; a◌֮◌֙◌̀◌̕b; a◌֮◌֙◌̀◌̕b; a◌֮◌֙◌̀◌̕b; a◌֮◌֙◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT PASHTA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 302E 059A 0316 059A 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062; # (a〮◌֚◌̖◌֚b; a◌̖◌֚◌֚〮b; a◌̖◌֚◌֚〮b; a◌̖◌֚◌֚〮b; a◌̖◌֚◌֚〮b; ) LATIN SMALL LETTER A, HANGUL SINGLE DOT TONE MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, HEBREW ACCENT YETIV, LATIN SMALL LETTER B
0061 059A 302E 059A 0316 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062; # (a◌֚〮◌֚◌̖b; a◌̖◌֚◌֚〮b; a◌̖◌֚◌֚〮b; a◌̖◌֚◌֚〮b; a◌̖◌֚◌֚〮b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, HANGUL SINGLE DOT TONE MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, LATIN SMALL LETTER B
-0061 059A 0316 302A 059B 0062;0061 302A 0316 059B 059A 0062;0061 302A 0316 059B 059A 0062;0061 302A 0316 059B 059A 0062;0061 302A 0316 059B 059A 0062; # (a◌֚◌̖◌〪◌֛b; a◌〪◌̖◌֛◌֚b; a◌〪◌̖◌֛◌֚b; a◌〪◌̖◌֛◌֚b; a◌〪◌̖◌֛◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT TEVIR, LATIN SMALL LETTER B
-0061 059B 059A 0316 302A 0062;0061 302A 059B 0316 059A 0062;0061 302A 059B 0316 059A 0062;0061 302A 059B 0316 059A 0062;0061 302A 059B 0316 059A 0062; # (a◌֛◌֚◌̖◌〪b; a◌〪◌֛◌̖◌֚b; a◌〪◌֛◌̖◌֚b; a◌〪◌֛◌̖◌֚b; a◌〪◌֛◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT TEVIR, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 059B 0062;0061 1DFA 0316 059B 059A 0062;0061 1DFA 0316 059B 059A 0062;0061 1DFA 0316 059B 059A 0062;0061 1DFA 0316 059B 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, HEBREW ACCENT TEVIR, LATIN SMALL LETTER B
+0061 059B 059A 0316 1DFA 0062;0061 1DFA 059B 0316 059A 0062;0061 1DFA 059B 0316 059A 0062;0061 1DFA 059B 0316 059A 0062;0061 1DFA 059B 0316 059A 0062; # (a◌֛◌֚◌̖◌᷺b; a◌᷺◌֛◌̖◌֚b; a◌᷺◌֛◌̖◌֚b; a◌᷺◌֛◌̖◌֚b; a◌᷺◌֛◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT TEVIR, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 059C 0062;00E0 05AE 059C 0315 0062;0061 05AE 0300 059C 0315 0062;00E0 05AE 059C 0315 0062;0061 05AE 0300 059C 0315 0062; # (a◌̕◌̀◌֮◌֜b; à◌֮◌֜◌̕b; a◌֮◌̀◌֜◌̕b; à◌֮◌֜◌̕b; a◌֮◌̀◌֜◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT GERESH, LATIN SMALL LETTER B
0061 059C 0315 0300 05AE 0062;0061 05AE 059C 0300 0315 0062;0061 05AE 059C 0300 0315 0062;0061 05AE 059C 0300 0315 0062;0061 05AE 059C 0300 0315 0062; # (a◌֜◌̕◌̀◌֮b; a◌֮◌֜◌̀◌̕b; a◌֮◌֜◌̀◌̕b; a◌֮◌֜◌̀◌̕b; a◌֮◌֜◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT GERESH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 059D 0062;00E0 05AE 059D 0315 0062;0061 05AE 0300 059D 0315 0062;00E0 05AE 059D 0315 0062;0061 05AE 0300 059D 0315 0062; # (a◌̕◌̀◌֮◌֝b; à◌֮◌֝◌̕b; a◌֮◌̀◌֝◌̕b; à◌֮◌֝◌̕b; a◌֮◌̀◌֝◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT GERESH MUQDAM, LATIN SMALL LETTER B
@@ -17247,24 +17306,24 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 05A0 0315 0300 05AE 0062;0061 05AE 05A0 0300 0315 0062;0061 05AE 05A0 0300 0315 0062;0061 05AE 05A0 0300 0315 0062;0061 05AE 05A0 0300 0315 0062; # (a◌֠◌̕◌̀◌֮b; a◌֮◌֠◌̀◌̕b; a◌֮◌֠◌̀◌̕b; a◌֮◌֠◌̀◌̕b; a◌֮◌֠◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT TELISHA GEDOLA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 05A1 0062;00E0 05AE 05A1 0315 0062;0061 05AE 0300 05A1 0315 0062;00E0 05AE 05A1 0315 0062;0061 05AE 0300 05A1 0315 0062; # (a◌̕◌̀◌֮◌֡b; à◌֮◌֡◌̕b; a◌֮◌̀◌֡◌̕b; à◌֮◌֡◌̕b; a◌֮◌̀◌֡◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT PAZER, LATIN SMALL LETTER B
0061 05A1 0315 0300 05AE 0062;0061 05AE 05A1 0300 0315 0062;0061 05AE 05A1 0300 0315 0062;0061 05AE 05A1 0300 0315 0062;0061 05AE 05A1 0300 0315 0062; # (a◌֡◌̕◌̀◌֮b; a◌֮◌֡◌̀◌̕b; a◌֮◌֡◌̀◌̕b; a◌֮◌֡◌̀◌̕b; a◌֮◌֡◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT PAZER, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 05A2 0062;0061 302A 0316 05A2 059A 0062;0061 302A 0316 05A2 059A 0062;0061 302A 0316 05A2 059A 0062;0061 302A 0316 05A2 059A 0062; # (a◌֚◌̖◌〪◌֢b; a◌〪◌̖◌֢◌֚b; a◌〪◌̖◌֢◌֚b; a◌〪◌̖◌֢◌֚b; a◌〪◌̖◌֢◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT ATNAH HAFUKH, LATIN SMALL LETTER B
-0061 05A2 059A 0316 302A 0062;0061 302A 05A2 0316 059A 0062;0061 302A 05A2 0316 059A 0062;0061 302A 05A2 0316 059A 0062;0061 302A 05A2 0316 059A 0062; # (a◌֢◌֚◌̖◌〪b; a◌〪◌֢◌̖◌֚b; a◌〪◌֢◌̖◌֚b; a◌〪◌֢◌̖◌֚b; a◌〪◌֢◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT ATNAH HAFUKH, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 05A3 0062;0061 302A 0316 05A3 059A 0062;0061 302A 0316 05A3 059A 0062;0061 302A 0316 05A3 059A 0062;0061 302A 0316 05A3 059A 0062; # (a◌֚◌̖◌〪◌֣b; a◌〪◌̖◌֣◌֚b; a◌〪◌̖◌֣◌֚b; a◌〪◌̖◌֣◌֚b; a◌〪◌̖◌֣◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT MUNAH, LATIN SMALL LETTER B
-0061 05A3 059A 0316 302A 0062;0061 302A 05A3 0316 059A 0062;0061 302A 05A3 0316 059A 0062;0061 302A 05A3 0316 059A 0062;0061 302A 05A3 0316 059A 0062; # (a◌֣◌֚◌̖◌〪b; a◌〪◌֣◌̖◌֚b; a◌〪◌֣◌̖◌֚b; a◌〪◌֣◌̖◌֚b; a◌〪◌֣◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT MUNAH, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 05A4 0062;0061 302A 0316 05A4 059A 0062;0061 302A 0316 05A4 059A 0062;0061 302A 0316 05A4 059A 0062;0061 302A 0316 05A4 059A 0062; # (a◌֚◌̖◌〪◌֤b; a◌〪◌̖◌֤◌֚b; a◌〪◌̖◌֤◌֚b; a◌〪◌̖◌֤◌֚b; a◌〪◌̖◌֤◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT MAHAPAKH, LATIN SMALL LETTER B
-0061 05A4 059A 0316 302A 0062;0061 302A 05A4 0316 059A 0062;0061 302A 05A4 0316 059A 0062;0061 302A 05A4 0316 059A 0062;0061 302A 05A4 0316 059A 0062; # (a◌֤◌֚◌̖◌〪b; a◌〪◌֤◌̖◌֚b; a◌〪◌֤◌̖◌֚b; a◌〪◌֤◌̖◌֚b; a◌〪◌֤◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT MAHAPAKH, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 05A5 0062;0061 302A 0316 05A5 059A 0062;0061 302A 0316 05A5 059A 0062;0061 302A 0316 05A5 059A 0062;0061 302A 0316 05A5 059A 0062; # (a◌֚◌̖◌〪◌֥b; a◌〪◌̖◌֥◌֚b; a◌〪◌̖◌֥◌֚b; a◌〪◌̖◌֥◌֚b; a◌〪◌̖◌֥◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT MERKHA, LATIN SMALL LETTER B
-0061 05A5 059A 0316 302A 0062;0061 302A 05A5 0316 059A 0062;0061 302A 05A5 0316 059A 0062;0061 302A 05A5 0316 059A 0062;0061 302A 05A5 0316 059A 0062; # (a◌֥◌֚◌̖◌〪b; a◌〪◌֥◌̖◌֚b; a◌〪◌֥◌̖◌֚b; a◌〪◌֥◌̖◌֚b; a◌〪◌֥◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT MERKHA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 05A6 0062;0061 302A 0316 05A6 059A 0062;0061 302A 0316 05A6 059A 0062;0061 302A 0316 05A6 059A 0062;0061 302A 0316 05A6 059A 0062; # (a◌֚◌̖◌〪◌֦b; a◌〪◌̖◌֦◌֚b; a◌〪◌̖◌֦◌֚b; a◌〪◌̖◌֦◌֚b; a◌〪◌̖◌֦◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT MERKHA KEFULA, LATIN SMALL LETTER B
-0061 05A6 059A 0316 302A 0062;0061 302A 05A6 0316 059A 0062;0061 302A 05A6 0316 059A 0062;0061 302A 05A6 0316 059A 0062;0061 302A 05A6 0316 059A 0062; # (a◌֦◌֚◌̖◌〪b; a◌〪◌֦◌̖◌֚b; a◌〪◌֦◌̖◌֚b; a◌〪◌֦◌̖◌֚b; a◌〪◌֦◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT MERKHA KEFULA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 05A7 0062;0061 302A 0316 05A7 059A 0062;0061 302A 0316 05A7 059A 0062;0061 302A 0316 05A7 059A 0062;0061 302A 0316 05A7 059A 0062; # (a◌֚◌̖◌〪◌֧b; a◌〪◌̖◌֧◌֚b; a◌〪◌̖◌֧◌֚b; a◌〪◌̖◌֧◌֚b; a◌〪◌̖◌֧◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT DARGA, LATIN SMALL LETTER B
-0061 05A7 059A 0316 302A 0062;0061 302A 05A7 0316 059A 0062;0061 302A 05A7 0316 059A 0062;0061 302A 05A7 0316 059A 0062;0061 302A 05A7 0316 059A 0062; # (a◌֧◌֚◌̖◌〪b; a◌〪◌֧◌̖◌֚b; a◌〪◌֧◌̖◌֚b; a◌〪◌֧◌̖◌֚b; a◌〪◌֧◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT DARGA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 05A2 0062;0061 1DFA 0316 05A2 059A 0062;0061 1DFA 0316 05A2 059A 0062;0061 1DFA 0316 05A2 059A 0062;0061 1DFA 0316 05A2 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, HEBREW ACCENT ATNAH HAFUKH, LATIN SMALL LETTER B
+0061 05A2 059A 0316 1DFA 0062;0061 1DFA 05A2 0316 059A 0062;0061 1DFA 05A2 0316 059A 0062;0061 1DFA 05A2 0316 059A 0062;0061 1DFA 05A2 0316 059A 0062; # (a◌֢◌֚◌̖◌᷺b; a◌᷺◌֢◌̖◌֚b; a◌᷺◌֢◌̖◌֚b; a◌᷺◌֢◌̖◌֚b; a◌᷺◌֢◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT ATNAH HAFUKH, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 05A3 0062;0061 1DFA 0316 05A3 059A 0062;0061 1DFA 0316 05A3 059A 0062;0061 1DFA 0316 05A3 059A 0062;0061 1DFA 0316 05A3 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, HEBREW ACCENT MUNAH, LATIN SMALL LETTER B
+0061 05A3 059A 0316 1DFA 0062;0061 1DFA 05A3 0316 059A 0062;0061 1DFA 05A3 0316 059A 0062;0061 1DFA 05A3 0316 059A 0062;0061 1DFA 05A3 0316 059A 0062; # (a◌֣◌֚◌̖◌᷺b; a◌᷺◌֣◌̖◌֚b; a◌᷺◌֣◌̖◌֚b; a◌᷺◌֣◌̖◌֚b; a◌᷺◌֣◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT MUNAH, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 05A4 0062;0061 1DFA 0316 05A4 059A 0062;0061 1DFA 0316 05A4 059A 0062;0061 1DFA 0316 05A4 059A 0062;0061 1DFA 0316 05A4 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, HEBREW ACCENT MAHAPAKH, LATIN SMALL LETTER B
+0061 05A4 059A 0316 1DFA 0062;0061 1DFA 05A4 0316 059A 0062;0061 1DFA 05A4 0316 059A 0062;0061 1DFA 05A4 0316 059A 0062;0061 1DFA 05A4 0316 059A 0062; # (a◌֤◌֚◌̖◌᷺b; a◌᷺◌֤◌̖◌֚b; a◌᷺◌֤◌̖◌֚b; a◌᷺◌֤◌̖◌֚b; a◌᷺◌֤◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT MAHAPAKH, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 05A5 0062;0061 1DFA 0316 05A5 059A 0062;0061 1DFA 0316 05A5 059A 0062;0061 1DFA 0316 05A5 059A 0062;0061 1DFA 0316 05A5 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, HEBREW ACCENT MERKHA, LATIN SMALL LETTER B
+0061 05A5 059A 0316 1DFA 0062;0061 1DFA 05A5 0316 059A 0062;0061 1DFA 05A5 0316 059A 0062;0061 1DFA 05A5 0316 059A 0062;0061 1DFA 05A5 0316 059A 0062; # (a◌֥◌֚◌̖◌᷺b; a◌᷺◌֥◌̖◌֚b; a◌᷺◌֥◌̖◌֚b; a◌᷺◌֥◌̖◌֚b; a◌᷺◌֥◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT MERKHA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 05A6 0062;0061 1DFA 0316 05A6 059A 0062;0061 1DFA 0316 05A6 059A 0062;0061 1DFA 0316 05A6 059A 0062;0061 1DFA 0316 05A6 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, HEBREW ACCENT MERKHA KEFULA, LATIN SMALL LETTER B
+0061 05A6 059A 0316 1DFA 0062;0061 1DFA 05A6 0316 059A 0062;0061 1DFA 05A6 0316 059A 0062;0061 1DFA 05A6 0316 059A 0062;0061 1DFA 05A6 0316 059A 0062; # (a◌֦◌֚◌̖◌᷺b; a◌᷺◌֦◌̖◌֚b; a◌᷺◌֦◌̖◌֚b; a◌᷺◌֦◌̖◌֚b; a◌᷺◌֦◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT MERKHA KEFULA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 05A7 0062;0061 1DFA 0316 05A7 059A 0062;0061 1DFA 0316 05A7 059A 0062;0061 1DFA 0316 05A7 059A 0062;0061 1DFA 0316 05A7 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, HEBREW ACCENT DARGA, LATIN SMALL LETTER B
+0061 05A7 059A 0316 1DFA 0062;0061 1DFA 05A7 0316 059A 0062;0061 1DFA 05A7 0316 059A 0062;0061 1DFA 05A7 0316 059A 0062;0061 1DFA 05A7 0316 059A 0062; # (a◌֧◌֚◌̖◌᷺b; a◌᷺◌֧◌̖◌֚b; a◌᷺◌֧◌̖◌֚b; a◌᷺◌֧◌̖◌֚b; a◌᷺◌֧◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT DARGA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 05A8 0062;00E0 05AE 05A8 0315 0062;0061 05AE 0300 05A8 0315 0062;00E0 05AE 05A8 0315 0062;0061 05AE 0300 05A8 0315 0062; # (a◌̕◌̀◌֮◌֨b; à◌֮◌֨◌̕b; a◌֮◌̀◌֨◌̕b; à◌֮◌֨◌̕b; a◌֮◌̀◌֨◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT QADMA, LATIN SMALL LETTER B
0061 05A8 0315 0300 05AE 0062;0061 05AE 05A8 0300 0315 0062;0061 05AE 05A8 0300 0315 0062;0061 05AE 05A8 0300 0315 0062;0061 05AE 05A8 0300 0315 0062; # (a◌֨◌̕◌̀◌֮b; a◌֮◌֨◌̀◌̕b; a◌֮◌֨◌̀◌̕b; a◌֮◌֨◌̀◌̕b; a◌֮◌֨◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT QADMA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 05A9 0062;00E0 05AE 05A9 0315 0062;0061 05AE 0300 05A9 0315 0062;00E0 05AE 05A9 0315 0062;0061 05AE 0300 05A9 0315 0062; # (a◌̕◌̀◌֮◌֩b; à◌֮◌֩◌̕b; a◌֮◌̀◌֩◌̕b; à◌֮◌֩◌̕b; a◌֮◌̀◌֩◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT TELISHA QETANA, LATIN SMALL LETTER B
0061 05A9 0315 0300 05AE 0062;0061 05AE 05A9 0300 0315 0062;0061 05AE 05A9 0300 0315 0062;0061 05AE 05A9 0300 0315 0062;0061 05AE 05A9 0300 0315 0062; # (a◌֩◌̕◌̀◌֮b; a◌֮◌֩◌̀◌̕b; a◌֮◌֩◌̀◌̕b; a◌֮◌֩◌̀◌̕b; a◌֮◌֩◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT TELISHA QETANA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 05AA 0062;0061 302A 0316 05AA 059A 0062;0061 302A 0316 05AA 059A 0062;0061 302A 0316 05AA 059A 0062;0061 302A 0316 05AA 059A 0062; # (a◌֚◌̖◌〪◌֪b; a◌〪◌̖◌֪◌֚b; a◌〪◌̖◌֪◌֚b; a◌〪◌̖◌֪◌֚b; a◌〪◌̖◌֪◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT YERAH BEN YOMO, LATIN SMALL LETTER B
-0061 05AA 059A 0316 302A 0062;0061 302A 05AA 0316 059A 0062;0061 302A 05AA 0316 059A 0062;0061 302A 05AA 0316 059A 0062;0061 302A 05AA 0316 059A 0062; # (a◌֪◌֚◌̖◌〪b; a◌〪◌֪◌̖◌֚b; a◌〪◌֪◌̖◌֚b; a◌〪◌֪◌̖◌֚b; a◌〪◌֪◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YERAH BEN YOMO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 05AA 0062;0061 1DFA 0316 05AA 059A 0062;0061 1DFA 0316 05AA 059A 0062;0061 1DFA 0316 05AA 059A 0062;0061 1DFA 0316 05AA 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, HEBREW ACCENT YERAH BEN YOMO, LATIN SMALL LETTER B
+0061 05AA 059A 0316 1DFA 0062;0061 1DFA 05AA 0316 059A 0062;0061 1DFA 05AA 0316 059A 0062;0061 1DFA 05AA 0316 059A 0062;0061 1DFA 05AA 0316 059A 0062; # (a◌֪◌֚◌̖◌᷺b; a◌᷺◌֪◌̖◌֚b; a◌᷺◌֪◌̖◌֚b; a◌᷺◌֪◌̖◌֚b; a◌᷺◌֪◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YERAH BEN YOMO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 05AB 0062;00E0 05AE 05AB 0315 0062;0061 05AE 0300 05AB 0315 0062;00E0 05AE 05AB 0315 0062;0061 05AE 0300 05AB 0315 0062; # (a◌̕◌̀◌֮◌֫b; à◌֮◌֫◌̕b; a◌֮◌̀◌֫◌̕b; à◌֮◌֫◌̕b; a◌֮◌̀◌֫◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT OLE, LATIN SMALL LETTER B
0061 05AB 0315 0300 05AE 0062;0061 05AE 05AB 0300 0315 0062;0061 05AE 05AB 0300 0315 0062;0061 05AE 05AB 0300 0315 0062;0061 05AE 05AB 0300 0315 0062; # (a◌֫◌̕◌̀◌֮b; a◌֮◌֫◌̀◌̕b; a◌֮◌֫◌̀◌̕b; a◌֮◌֫◌̀◌̕b; a◌֮◌֫◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT OLE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 05AC 0062;00E0 05AE 05AC 0315 0062;0061 05AE 0300 05AC 0315 0062;00E0 05AE 05AC 0315 0062;0061 05AE 0300 05AC 0315 0062; # (a◌̕◌̀◌֮◌֬b; à◌֮◌֬◌̕b; a◌֮◌̀◌֬◌̕b; à◌֮◌֬◌̕b; a◌֮◌̀◌֬◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT ILUY, LATIN SMALL LETTER B
@@ -17311,8 +17370,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 05C2 FB1E 05C2 05C1 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062; # (a◌ׂ◌ﬞ◌ׂ◌ׁb; a◌ׁ◌ׂ◌ׂ◌ﬞb; a◌ׁ◌ׂ◌ׂ◌ﬞb; a◌ׁ◌ׂ◌ׂ◌ﬞb; a◌ׁ◌ׂ◌ׂ◌ﬞb; ) LATIN SMALL LETTER A, HEBREW POINT SIN DOT, HEBREW POINT JUDEO-SPANISH VARIKA, HEBREW POINT SIN DOT, HEBREW POINT SHIN DOT, LATIN SMALL LETTER B
0061 0315 0300 05AE 05C4 0062;00E0 05AE 05C4 0315 0062;0061 05AE 0300 05C4 0315 0062;00E0 05AE 05C4 0315 0062;0061 05AE 0300 05C4 0315 0062; # (a◌̕◌̀◌֮◌ׄb; à◌֮◌ׄ◌̕b; a◌֮◌̀◌ׄ◌̕b; à◌֮◌ׄ◌̕b; a◌֮◌̀◌ׄ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW MARK UPPER DOT, LATIN SMALL LETTER B
0061 05C4 0315 0300 05AE 0062;0061 05AE 05C4 0300 0315 0062;0061 05AE 05C4 0300 0315 0062;0061 05AE 05C4 0300 0315 0062;0061 05AE 05C4 0300 0315 0062; # (a◌ׄ◌̕◌̀◌֮b; a◌֮◌ׄ◌̀◌̕b; a◌֮◌ׄ◌̀◌̕b; a◌֮◌ׄ◌̀◌̕b; a◌֮◌ׄ◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW MARK UPPER DOT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 05C5 0062;0061 302A 0316 05C5 059A 0062;0061 302A 0316 05C5 059A 0062;0061 302A 0316 05C5 059A 0062;0061 302A 0316 05C5 059A 0062; # (a◌֚◌̖◌〪◌ׅb; a◌〪◌̖◌ׅ◌֚b; a◌〪◌̖◌ׅ◌֚b; a◌〪◌̖◌ׅ◌֚b; a◌〪◌̖◌ׅ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW MARK LOWER DOT, LATIN SMALL LETTER B
-0061 05C5 059A 0316 302A 0062;0061 302A 05C5 0316 059A 0062;0061 302A 05C5 0316 059A 0062;0061 302A 05C5 0316 059A 0062;0061 302A 05C5 0316 059A 0062; # (a◌ׅ◌֚◌̖◌〪b; a◌〪◌ׅ◌̖◌֚b; a◌〪◌ׅ◌̖◌֚b; a◌〪◌ׅ◌̖◌֚b; a◌〪◌ׅ◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW MARK LOWER DOT, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 05C5 0062;0061 1DFA 0316 05C5 059A 0062;0061 1DFA 0316 05C5 059A 0062;0061 1DFA 0316 05C5 059A 0062;0061 1DFA 0316 05C5 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, HEBREW MARK LOWER DOT, LATIN SMALL LETTER B
+0061 05C5 059A 0316 1DFA 0062;0061 1DFA 05C5 0316 059A 0062;0061 1DFA 05C5 0316 059A 0062;0061 1DFA 05C5 0316 059A 0062;0061 1DFA 05C5 0316 059A 0062; # (a◌ׅ◌֚◌̖◌᷺b; a◌᷺◌ׅ◌̖◌֚b; a◌᷺◌ׅ◌̖◌֚b; a◌᷺◌ׅ◌̖◌֚b; a◌᷺◌ׅ◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW MARK LOWER DOT, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 05B9 05B8 05B7 05C7 0062;0061 05B7 05B8 05C7 05B9 0062;0061 05B7 05B8 05C7 05B9 0062;0061 05B7 05B8 05C7 05B9 0062;0061 05B7 05B8 05C7 05B9 0062; # (a◌ֹ◌ָ◌ַ◌ׇb; a◌ַ◌ָ◌ׇ◌ֹb; a◌ַ◌ָ◌ׇ◌ֹb; a◌ַ◌ָ◌ׇ◌ֹb; a◌ַ◌ָ◌ׇ◌ֹb; ) LATIN SMALL LETTER A, HEBREW POINT HOLAM, HEBREW POINT QAMATS, HEBREW POINT PATAH, HEBREW POINT QAMATS QATAN, LATIN SMALL LETTER B
0061 05C7 05B9 05B8 05B7 0062;0061 05B7 05C7 05B8 05B9 0062;0061 05B7 05C7 05B8 05B9 0062;0061 05B7 05C7 05B8 05B9 0062;0061 05B7 05C7 05B8 05B9 0062; # (a◌ׇ◌ֹ◌ָ◌ַb; a◌ַ◌ׇ◌ָ◌ֹb; a◌ַ◌ׇ◌ָ◌ֹb; a◌ַ◌ׇ◌ָ◌ֹb; a◌ַ◌ׇ◌ָ◌ֹb; ) LATIN SMALL LETTER A, HEBREW POINT QAMATS QATAN, HEBREW POINT HOLAM, HEBREW POINT QAMATS, HEBREW POINT PATAH, LATIN SMALL LETTER B
0061 0315 0300 05AE 0610 0062;00E0 05AE 0610 0315 0062;0061 05AE 0300 0610 0315 0062;00E0 05AE 0610 0315 0062;0061 05AE 0300 0610 0315 0062; # (a◌̕◌̀◌֮◌ؐb; à◌֮◌ؐ◌̕b; a◌֮◌̀◌ؐ◌̕b; à◌֮◌ؐ◌̕b; a◌֮◌̀◌ؐ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM, LATIN SMALL LETTER B
@@ -17357,10 +17416,10 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 0653 0315 0300 05AE 0062;0061 05AE 0653 0300 0315 0062;0061 05AE 0653 0300 0315 0062;0061 05AE 0653 0300 0315 0062;0061 05AE 0653 0300 0315 0062; # (a◌ٓ◌̕◌̀◌֮b; a◌֮◌ٓ◌̀◌̕b; a◌֮◌ٓ◌̀◌̕b; a◌֮◌ٓ◌̀◌̕b; a◌֮◌ٓ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC MADDAH ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 0654 0062;00E0 05AE 0654 0315 0062;0061 05AE 0300 0654 0315 0062;00E0 05AE 0654 0315 0062;0061 05AE 0300 0654 0315 0062; # (a◌̕◌̀◌֮◌ٔb; à◌֮◌ٔ◌̕b; a◌֮◌̀◌ٔ◌̕b; à◌֮◌ٔ◌̕b; a◌֮◌̀◌ٔ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC HAMZA ABOVE, LATIN SMALL LETTER B
0061 0654 0315 0300 05AE 0062;0061 05AE 0654 0300 0315 0062;0061 05AE 0654 0300 0315 0062;0061 05AE 0654 0300 0315 0062;0061 05AE 0654 0300 0315 0062; # (a◌ٔ◌̕◌̀◌֮b; a◌֮◌ٔ◌̀◌̕b; a◌֮◌ٔ◌̀◌̕b; a◌֮◌ٔ◌̀◌̕b; a◌֮◌ٔ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC HAMZA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 0655 0062;0061 302A 0316 0655 059A 0062;0061 302A 0316 0655 059A 0062;0061 302A 0316 0655 059A 0062;0061 302A 0316 0655 059A 0062; # (a◌֚◌̖◌〪◌ٕb; a◌〪◌̖◌ٕ◌֚b; a◌〪◌̖◌ٕ◌֚b; a◌〪◌̖◌ٕ◌֚b; a◌〪◌̖◌ٕ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC HAMZA BELOW, LATIN SMALL LETTER B
-0061 0655 059A 0316 302A 0062;0061 302A 0655 0316 059A 0062;0061 302A 0655 0316 059A 0062;0061 302A 0655 0316 059A 0062;0061 302A 0655 0316 059A 0062; # (a◌ٕ◌֚◌̖◌〪b; a◌〪◌ٕ◌̖◌֚b; a◌〪◌ٕ◌̖◌֚b; a◌〪◌ٕ◌̖◌֚b; a◌〪◌ٕ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC HAMZA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0656 0062;0061 302A 0316 0656 059A 0062;0061 302A 0316 0656 059A 0062;0061 302A 0316 0656 059A 0062;0061 302A 0316 0656 059A 0062; # (a◌֚◌̖◌〪◌ٖb; a◌〪◌̖◌ٖ◌֚b; a◌〪◌̖◌ٖ◌֚b; a◌〪◌̖◌ٖ◌֚b; a◌〪◌̖◌ٖ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC SUBSCRIPT ALEF, LATIN SMALL LETTER B
-0061 0656 059A 0316 302A 0062;0061 302A 0656 0316 059A 0062;0061 302A 0656 0316 059A 0062;0061 302A 0656 0316 059A 0062;0061 302A 0656 0316 059A 0062; # (a◌ٖ◌֚◌̖◌〪b; a◌〪◌ٖ◌̖◌֚b; a◌〪◌ٖ◌̖◌֚b; a◌〪◌ٖ◌̖◌֚b; a◌〪◌ٖ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SUBSCRIPT ALEF, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0655 0062;0061 1DFA 0316 0655 059A 0062;0061 1DFA 0316 0655 059A 0062;0061 1DFA 0316 0655 059A 0062;0061 1DFA 0316 0655 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 HAMZA BELOW, LATIN SMALL LETTER B
+0061 0655 059A 0316 1DFA 0062;0061 1DFA 0655 0316 059A 0062;0061 1DFA 0655 0316 059A 0062;0061 1DFA 0655 0316 059A 0062;0061 1DFA 0655 0316 059A 0062; # (a◌ٕ◌֚◌̖◌᷺b; a◌᷺◌ٕ◌̖◌֚b; a◌᷺◌ٕ◌̖◌֚b; a◌᷺◌ٕ◌̖◌֚b; a◌᷺◌ٕ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC HAMZA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0656 0062;0061 1DFA 0316 0656 059A 0062;0061 1DFA 0316 0656 059A 0062;0061 1DFA 0316 0656 059A 0062;0061 1DFA 0316 0656 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 SUBSCRIPT ALEF, LATIN SMALL LETTER B
+0061 0656 059A 0316 1DFA 0062;0061 1DFA 0656 0316 059A 0062;0061 1DFA 0656 0316 059A 0062;0061 1DFA 0656 0316 059A 0062;0061 1DFA 0656 0316 059A 0062; # (a◌ٖ◌֚◌̖◌᷺b; a◌᷺◌ٖ◌̖◌֚b; a◌᷺◌ٖ◌̖◌֚b; a◌᷺◌ٖ◌̖◌֚b; a◌᷺◌ٖ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SUBSCRIPT ALEF, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 0657 0062;00E0 05AE 0657 0315 0062;0061 05AE 0300 0657 0315 0062;00E0 05AE 0657 0315 0062;0061 05AE 0300 0657 0315 0062; # (a◌̕◌̀◌֮◌ٗb; à◌֮◌ٗ◌̕b; a◌֮◌̀◌ٗ◌̕b; à◌֮◌ٗ◌̕b; a◌֮◌̀◌ٗ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC INVERTED DAMMA, LATIN SMALL LETTER B
0061 0657 0315 0300 05AE 0062;0061 05AE 0657 0300 0315 0062;0061 05AE 0657 0300 0315 0062;0061 05AE 0657 0300 0315 0062;0061 05AE 0657 0300 0315 0062; # (a◌ٗ◌̕◌̀◌֮b; a◌֮◌ٗ◌̀◌̕b; a◌֮◌ٗ◌̀◌̕b; a◌֮◌ٗ◌̀◌̕b; a◌֮◌ٗ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC INVERTED DAMMA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 0658 0062;00E0 05AE 0658 0315 0062;0061 05AE 0300 0658 0315 0062;00E0 05AE 0658 0315 0062;0061 05AE 0300 0658 0315 0062; # (a◌̕◌̀◌֮◌٘b; à◌֮◌٘◌̕b; a◌֮◌̀◌٘◌̕b; à◌֮◌٘◌̕b; a◌֮◌̀◌٘◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC MARK NOON GHUNNA, LATIN SMALL LETTER B
@@ -17371,14 +17430,14 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 065A 0315 0300 05AE 0062;0061 05AE 065A 0300 0315 0062;0061 05AE 065A 0300 0315 0062;0061 05AE 065A 0300 0315 0062;0061 05AE 065A 0300 0315 0062; # (a◌ٚ◌̕◌̀◌֮b; a◌֮◌ٚ◌̀◌̕b; a◌֮◌ٚ◌̀◌̕b; a◌֮◌ٚ◌̀◌̕b; a◌֮◌ٚ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC VOWEL SIGN SMALL V ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 065B 0062;00E0 05AE 065B 0315 0062;0061 05AE 0300 065B 0315 0062;00E0 05AE 065B 0315 0062;0061 05AE 0300 065B 0315 0062; # (a◌̕◌̀◌֮◌ٛb; à◌֮◌ٛ◌̕b; a◌֮◌̀◌ٛ◌̕b; à◌֮◌ٛ◌̕b; a◌֮◌̀◌ٛ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC VOWEL SIGN INVERTED SMALL V ABOVE, LATIN SMALL LETTER B
0061 065B 0315 0300 05AE 0062;0061 05AE 065B 0300 0315 0062;0061 05AE 065B 0300 0315 0062;0061 05AE 065B 0300 0315 0062;0061 05AE 065B 0300 0315 0062; # (a◌ٛ◌̕◌̀◌֮b; a◌֮◌ٛ◌̀◌̕b; a◌֮◌ٛ◌̀◌̕b; a◌֮◌ٛ◌̀◌̕b; a◌֮◌ٛ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC VOWEL SIGN INVERTED SMALL V ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 065C 0062;0061 302A 0316 065C 059A 0062;0061 302A 0316 065C 059A 0062;0061 302A 0316 065C 059A 0062;0061 302A 0316 065C 059A 0062; # (a◌֚◌̖◌〪◌ٜb; a◌〪◌̖◌ٜ◌֚b; a◌〪◌̖◌ٜ◌֚b; a◌〪◌̖◌ٜ◌֚b; a◌〪◌̖◌ٜ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC VOWEL SIGN DOT BELOW, LATIN SMALL LETTER B
-0061 065C 059A 0316 302A 0062;0061 302A 065C 0316 059A 0062;0061 302A 065C 0316 059A 0062;0061 302A 065C 0316 059A 0062;0061 302A 065C 0316 059A 0062; # (a◌ٜ◌֚◌̖◌〪b; a◌〪◌ٜ◌̖◌֚b; a◌〪◌ٜ◌̖◌֚b; a◌〪◌ٜ◌̖◌֚b; a◌〪◌ٜ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC VOWEL SIGN DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 065C 0062;0061 1DFA 0316 065C 059A 0062;0061 1DFA 0316 065C 059A 0062;0061 1DFA 0316 065C 059A 0062;0061 1DFA 0316 065C 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 VOWEL SIGN DOT BELOW, LATIN SMALL LETTER B
+0061 065C 059A 0316 1DFA 0062;0061 1DFA 065C 0316 059A 0062;0061 1DFA 065C 0316 059A 0062;0061 1DFA 065C 0316 059A 0062;0061 1DFA 065C 0316 059A 0062; # (a◌ٜ◌֚◌̖◌᷺b; a◌᷺◌ٜ◌̖◌֚b; a◌᷺◌ٜ◌̖◌֚b; a◌᷺◌ٜ◌̖◌֚b; a◌᷺◌ٜ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC VOWEL SIGN DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 065D 0062;00E0 05AE 065D 0315 0062;0061 05AE 0300 065D 0315 0062;00E0 05AE 065D 0315 0062;0061 05AE 0300 065D 0315 0062; # (a◌̕◌̀◌֮◌ٝb; à◌֮◌ٝ◌̕b; a◌֮◌̀◌ٝ◌̕b; à◌֮◌ٝ◌̕b; a◌֮◌̀◌ٝ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC REVERSED DAMMA, LATIN SMALL LETTER B
0061 065D 0315 0300 05AE 0062;0061 05AE 065D 0300 0315 0062;0061 05AE 065D 0300 0315 0062;0061 05AE 065D 0300 0315 0062;0061 05AE 065D 0300 0315 0062; # (a◌ٝ◌̕◌̀◌֮b; a◌֮◌ٝ◌̀◌̕b; a◌֮◌ٝ◌̀◌̕b; a◌֮◌ٝ◌̀◌̕b; a◌֮◌ٝ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC REVERSED DAMMA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 065E 0062;00E0 05AE 065E 0315 0062;0061 05AE 0300 065E 0315 0062;00E0 05AE 065E 0315 0062;0061 05AE 0300 065E 0315 0062; # (a◌̕◌̀◌֮◌ٞb; à◌֮◌ٞ◌̕b; a◌֮◌̀◌ٞ◌̕b; à◌֮◌ٞ◌̕b; a◌֮◌̀◌ٞ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC FATHA WITH TWO DOTS, LATIN SMALL LETTER B
0061 065E 0315 0300 05AE 0062;0061 05AE 065E 0300 0315 0062;0061 05AE 065E 0300 0315 0062;0061 05AE 065E 0300 0315 0062;0061 05AE 065E 0300 0315 0062; # (a◌ٞ◌̕◌̀◌֮b; a◌֮◌ٞ◌̀◌̕b; a◌֮◌ٞ◌̀◌̕b; a◌֮◌ٞ◌̀◌̕b; a◌֮◌ٞ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC FATHA WITH TWO DOTS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 065F 0062;0061 302A 0316 065F 059A 0062;0061 302A 0316 065F 059A 0062;0061 302A 0316 065F 059A 0062;0061 302A 0316 065F 059A 0062; # (a◌֚◌̖◌〪◌ٟb; a◌〪◌̖◌ٟ◌֚b; a◌〪◌̖◌ٟ◌֚b; a◌〪◌̖◌ٟ◌֚b; a◌〪◌̖◌ٟ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC WAVY HAMZA BELOW, LATIN SMALL LETTER B
-0061 065F 059A 0316 302A 0062;0061 302A 065F 0316 059A 0062;0061 302A 065F 0316 059A 0062;0061 302A 065F 0316 059A 0062;0061 302A 065F 0316 059A 0062; # (a◌ٟ◌֚◌̖◌〪b; a◌〪◌ٟ◌̖◌֚b; a◌〪◌ٟ◌̖◌֚b; a◌〪◌ٟ◌̖◌֚b; a◌〪◌ٟ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC WAVY HAMZA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 065F 0062;0061 1DFA 0316 065F 059A 0062;0061 1DFA 0316 065F 059A 0062;0061 1DFA 0316 065F 059A 0062;0061 1DFA 0316 065F 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 WAVY HAMZA BELOW, LATIN SMALL LETTER B
+0061 065F 059A 0316 1DFA 0062;0061 1DFA 065F 0316 059A 0062;0061 1DFA 065F 0316 059A 0062;0061 1DFA 065F 0316 059A 0062;0061 1DFA 065F 0316 059A 0062; # (a◌ٟ◌֚◌̖◌᷺b; a◌᷺◌ٟ◌̖◌֚b; a◌᷺◌ٟ◌̖◌֚b; a◌᷺◌ٟ◌̖◌֚b; a◌᷺◌ٟ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC WAVY HAMZA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0711 0670 0652 0670 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062; # (a◌ܑ◌ٰ◌ْ◌ٰb; a◌ْ◌ٰ◌ٰ◌ܑb; a◌ْ◌ٰ◌ٰ◌ܑb; a◌ْ◌ٰ◌ٰ◌ܑb; a◌ْ◌ٰ◌ٰ◌ܑb; ) LATIN SMALL LETTER A, SYRIAC LETTER SUPERSCRIPT ALAPH, ARABIC LETTER SUPERSCRIPT ALEF, ARABIC SUKUN, ARABIC LETTER SUPERSCRIPT ALEF, LATIN SMALL LETTER B
0061 0670 0711 0670 0652 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062; # (a◌ٰ◌ܑ◌ٰ◌ْb; a◌ْ◌ٰ◌ٰ◌ܑb; a◌ْ◌ٰ◌ٰ◌ܑb; a◌ْ◌ٰ◌ٰ◌ܑb; a◌ْ◌ٰ◌ٰ◌ܑb; ) LATIN SMALL LETTER A, ARABIC LETTER SUPERSCRIPT ALEF, SYRIAC LETTER SUPERSCRIPT ALAPH, ARABIC LETTER SUPERSCRIPT ALEF, ARABIC SUKUN, LATIN SMALL LETTER B
0061 0315 0300 05AE 06D6 0062;00E0 05AE 06D6 0315 0062;0061 05AE 0300 06D6 0315 0062;00E0 05AE 06D6 0315 0062;0061 05AE 0300 06D6 0315 0062; # (a◌̕◌̀◌֮◌ۖb; à◌֮◌ۖ◌̕b; a◌֮◌̀◌ۖ◌̕b; à◌֮◌ۖ◌̕b; a◌֮◌̀◌ۖ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA, LATIN SMALL LETTER B
@@ -17403,74 +17462,74 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 06E1 0315 0300 05AE 0062;0061 05AE 06E1 0300 0315 0062;0061 05AE 06E1 0300 0315 0062;0061 05AE 06E1 0300 0315 0062;0061 05AE 06E1 0300 0315 0062; # (a◌ۡ◌̕◌̀◌֮b; a◌֮◌ۡ◌̀◌̕b; a◌֮◌ۡ◌̀◌̕b; a◌֮◌ۡ◌̀◌̕b; a◌֮◌ۡ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH DOTLESS HEAD OF KHAH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 06E2 0062;00E0 05AE 06E2 0315 0062;0061 05AE 0300 06E2 0315 0062;00E0 05AE 06E2 0315 0062;0061 05AE 0300 06E2 0315 0062; # (a◌̕◌̀◌֮◌ۢb; à◌֮◌ۢ◌̕b; a◌֮◌̀◌ۢ◌̕b; à◌֮◌ۢ◌̕b; a◌֮◌̀◌ۢ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH MEEM ISOLATED FORM, LATIN SMALL LETTER B
0061 06E2 0315 0300 05AE 0062;0061 05AE 06E2 0300 0315 0062;0061 05AE 06E2 0300 0315 0062;0061 05AE 06E2 0300 0315 0062;0061 05AE 06E2 0300 0315 0062; # (a◌ۢ◌̕◌̀◌֮b; a◌֮◌ۢ◌̀◌̕b; a◌֮◌ۢ◌̀◌̕b; a◌֮◌ۢ◌̀◌̕b; a◌֮◌ۢ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH MEEM ISOLATED FORM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 06E3 0062;0061 302A 0316 06E3 059A 0062;0061 302A 0316 06E3 059A 0062;0061 302A 0316 06E3 059A 0062;0061 302A 0316 06E3 059A 0062; # (a◌֚◌̖◌〪◌ۣb; a◌〪◌̖◌ۣ◌֚b; a◌〪◌̖◌ۣ◌֚b; a◌〪◌̖◌ۣ◌֚b; a◌〪◌̖◌ۣ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC SMALL LOW SEEN, LATIN SMALL LETTER B
-0061 06E3 059A 0316 302A 0062;0061 302A 06E3 0316 059A 0062;0061 302A 06E3 0316 059A 0062;0061 302A 06E3 0316 059A 0062;0061 302A 06E3 0316 059A 0062; # (a◌ۣ◌֚◌̖◌〪b; a◌〪◌ۣ◌̖◌֚b; a◌〪◌ۣ◌̖◌֚b; a◌〪◌ۣ◌̖◌֚b; a◌〪◌ۣ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SMALL LOW SEEN, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 06E3 0062;0061 1DFA 0316 06E3 059A 0062;0061 1DFA 0316 06E3 059A 0062;0061 1DFA 0316 06E3 059A 0062;0061 1DFA 0316 06E3 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 SEEN, LATIN SMALL LETTER B
+0061 06E3 059A 0316 1DFA 0062;0061 1DFA 06E3 0316 059A 0062;0061 1DFA 06E3 0316 059A 0062;0061 1DFA 06E3 0316 059A 0062;0061 1DFA 06E3 0316 059A 0062; # (a◌ۣ◌֚◌̖◌᷺b; a◌᷺◌ۣ◌̖◌֚b; a◌᷺◌ۣ◌̖◌֚b; a◌᷺◌ۣ◌̖◌֚b; a◌᷺◌ۣ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SMALL LOW SEEN, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 06E4 0062;00E0 05AE 06E4 0315 0062;0061 05AE 0300 06E4 0315 0062;00E0 05AE 06E4 0315 0062;0061 05AE 0300 06E4 0315 0062; # (a◌̕◌̀◌֮◌ۤb; à◌֮◌ۤ◌̕b; a◌֮◌̀◌ۤ◌̕b; à◌֮◌ۤ◌̕b; a◌֮◌̀◌ۤ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH MADDA, LATIN SMALL LETTER B
0061 06E4 0315 0300 05AE 0062;0061 05AE 06E4 0300 0315 0062;0061 05AE 06E4 0300 0315 0062;0061 05AE 06E4 0300 0315 0062;0061 05AE 06E4 0300 0315 0062; # (a◌ۤ◌̕◌̀◌֮b; a◌֮◌ۤ◌̀◌̕b; a◌֮◌ۤ◌̀◌̕b; a◌֮◌ۤ◌̀◌̕b; a◌֮◌ۤ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH MADDA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 06E7 0062;00E0 05AE 06E7 0315 0062;0061 05AE 0300 06E7 0315 0062;00E0 05AE 06E7 0315 0062;0061 05AE 0300 06E7 0315 0062; # (a◌̕◌̀◌֮◌ۧb; à◌֮◌ۧ◌̕b; a◌֮◌̀◌ۧ◌̕b; à◌֮◌ۧ◌̕b; a◌֮◌̀◌ۧ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH YEH, LATIN SMALL LETTER B
0061 06E7 0315 0300 05AE 0062;0061 05AE 06E7 0300 0315 0062;0061 05AE 06E7 0300 0315 0062;0061 05AE 06E7 0300 0315 0062;0061 05AE 06E7 0300 0315 0062; # (a◌ۧ◌̕◌̀◌֮b; a◌֮◌ۧ◌̀◌̕b; a◌֮◌ۧ◌̀◌̕b; a◌֮◌ۧ◌̀◌̕b; a◌֮◌ۧ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH YEH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 06E8 0062;00E0 05AE 06E8 0315 0062;0061 05AE 0300 06E8 0315 0062;00E0 05AE 06E8 0315 0062;0061 05AE 0300 06E8 0315 0062; # (a◌̕◌̀◌֮◌ۨb; à◌֮◌ۨ◌̕b; a◌֮◌̀◌ۨ◌̕b; à◌֮◌ۨ◌̕b; a◌֮◌̀◌ۨ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH NOON, LATIN SMALL LETTER B
0061 06E8 0315 0300 05AE 0062;0061 05AE 06E8 0300 0315 0062;0061 05AE 06E8 0300 0315 0062;0061 05AE 06E8 0300 0315 0062;0061 05AE 06E8 0300 0315 0062; # (a◌ۨ◌̕◌̀◌֮b; a◌֮◌ۨ◌̀◌̕b; a◌֮◌ۨ◌̀◌̕b; a◌֮◌ۨ◌̀◌̕b; a◌֮◌ۨ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH NOON, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 06EA 0062;0061 302A 0316 06EA 059A 0062;0061 302A 0316 06EA 059A 0062;0061 302A 0316 06EA 059A 0062;0061 302A 0316 06EA 059A 0062; # (a◌֚◌̖◌〪◌۪b; a◌〪◌̖◌۪◌֚b; a◌〪◌̖◌۪◌֚b; a◌〪◌̖◌۪◌֚b; a◌〪◌̖◌۪◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC EMPTY CENTRE LOW STOP, LATIN SMALL LETTER B
-0061 06EA 059A 0316 302A 0062;0061 302A 06EA 0316 059A 0062;0061 302A 06EA 0316 059A 0062;0061 302A 06EA 0316 059A 0062;0061 302A 06EA 0316 059A 0062; # (a◌۪◌֚◌̖◌〪b; a◌〪◌۪◌̖◌֚b; a◌〪◌۪◌̖◌֚b; a◌〪◌۪◌̖◌֚b; a◌〪◌۪◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC EMPTY CENTRE LOW STOP, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 06EA 0062;0061 1DFA 0316 06EA 059A 0062;0061 1DFA 0316 06EA 059A 0062;0061 1DFA 0316 06EA 059A 0062;0061 1DFA 0316 06EA 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 EMPTY CENTRE LOW STOP, LATIN SMALL LETTER B
+0061 06EA 059A 0316 1DFA 0062;0061 1DFA 06EA 0316 059A 0062;0061 1DFA 06EA 0316 059A 0062;0061 1DFA 06EA 0316 059A 0062;0061 1DFA 06EA 0316 059A 0062; # (a◌۪◌֚◌̖◌᷺b; a◌᷺◌۪◌̖◌֚b; a◌᷺◌۪◌̖◌֚b; a◌᷺◌۪◌̖◌֚b; a◌᷺◌۪◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC EMPTY CENTRE LOW STOP, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 06EB 0062;00E0 05AE 06EB 0315 0062;0061 05AE 0300 06EB 0315 0062;00E0 05AE 06EB 0315 0062;0061 05AE 0300 06EB 0315 0062; # (a◌̕◌̀◌֮◌۫b; à◌֮◌۫◌̕b; a◌֮◌̀◌۫◌̕b; à◌֮◌۫◌̕b; a◌֮◌̀◌۫◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC EMPTY CENTRE HIGH STOP, LATIN SMALL LETTER B
0061 06EB 0315 0300 05AE 0062;0061 05AE 06EB 0300 0315 0062;0061 05AE 06EB 0300 0315 0062;0061 05AE 06EB 0300 0315 0062;0061 05AE 06EB 0300 0315 0062; # (a◌۫◌̕◌̀◌֮b; a◌֮◌۫◌̀◌̕b; a◌֮◌۫◌̀◌̕b; a◌֮◌۫◌̀◌̕b; a◌֮◌۫◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC EMPTY CENTRE HIGH STOP, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 06EC 0062;00E0 05AE 06EC 0315 0062;0061 05AE 0300 06EC 0315 0062;00E0 05AE 06EC 0315 0062;0061 05AE 0300 06EC 0315 0062; # (a◌̕◌̀◌֮◌۬b; à◌֮◌۬◌̕b; a◌֮◌̀◌۬◌̕b; à◌֮◌۬◌̕b; a◌֮◌̀◌۬◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE, LATIN SMALL LETTER B
0061 06EC 0315 0300 05AE 0062;0061 05AE 06EC 0300 0315 0062;0061 05AE 06EC 0300 0315 0062;0061 05AE 06EC 0300 0315 0062;0061 05AE 06EC 0300 0315 0062; # (a◌۬◌̕◌̀◌֮b; a◌֮◌۬◌̀◌̕b; a◌֮◌۬◌̀◌̕b; a◌֮◌۬◌̀◌̕b; a◌֮◌۬◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 06ED 0062;0061 302A 0316 06ED 059A 0062;0061 302A 0316 06ED 059A 0062;0061 302A 0316 06ED 059A 0062;0061 302A 0316 06ED 059A 0062; # (a◌֚◌̖◌〪◌ۭb; a◌〪◌̖◌ۭ◌֚b; a◌〪◌̖◌ۭ◌֚b; a◌〪◌̖◌ۭ◌֚b; a◌〪◌̖◌ۭ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC SMALL LOW MEEM, LATIN SMALL LETTER B
-0061 06ED 059A 0316 302A 0062;0061 302A 06ED 0316 059A 0062;0061 302A 06ED 0316 059A 0062;0061 302A 06ED 0316 059A 0062;0061 302A 06ED 0316 059A 0062; # (a◌ۭ◌֚◌̖◌〪b; a◌〪◌ۭ◌̖◌֚b; a◌〪◌ۭ◌̖◌֚b; a◌〪◌ۭ◌̖◌֚b; a◌〪◌ۭ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SMALL LOW MEEM, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 06ED 0062;0061 1DFA 0316 06ED 059A 0062;0061 1DFA 0316 06ED 059A 0062;0061 1DFA 0316 06ED 059A 0062;0061 1DFA 0316 06ED 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 MEEM, LATIN SMALL LETTER B
+0061 06ED 059A 0316 1DFA 0062;0061 1DFA 06ED 0316 059A 0062;0061 1DFA 06ED 0316 059A 0062;0061 1DFA 06ED 0316 059A 0062;0061 1DFA 06ED 0316 059A 0062; # (a◌ۭ◌֚◌̖◌᷺b; a◌᷺◌ۭ◌̖◌֚b; a◌᷺◌ۭ◌̖◌֚b; a◌᷺◌ۭ◌̖◌֚b; a◌᷺◌ۭ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SMALL LOW MEEM, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0C55 0711 0670 0711 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062; # (a◌ౕ◌ܑ◌ٰ◌ܑb; a◌ٰ◌ܑ◌ܑ◌ౕb; a◌ٰ◌ܑ◌ܑ◌ౕb; a◌ٰ◌ܑ◌ܑ◌ౕb; a◌ٰ◌ܑ◌ܑ◌ౕb; ) LATIN SMALL LETTER A, TELUGU LENGTH MARK, SYRIAC LETTER SUPERSCRIPT ALAPH, ARABIC LETTER SUPERSCRIPT ALEF, SYRIAC LETTER SUPERSCRIPT ALAPH, LATIN SMALL LETTER B
0061 0711 0C55 0711 0670 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062; # (a◌ܑ◌ౕ◌ܑ◌ٰb; a◌ٰ◌ܑ◌ܑ◌ౕb; a◌ٰ◌ܑ◌ܑ◌ౕb; a◌ٰ◌ܑ◌ܑ◌ౕb; a◌ٰ◌ܑ◌ܑ◌ౕb; ) LATIN SMALL LETTER A, SYRIAC LETTER SUPERSCRIPT ALAPH, TELUGU LENGTH MARK, SYRIAC LETTER SUPERSCRIPT ALAPH, ARABIC LETTER SUPERSCRIPT ALEF, LATIN SMALL LETTER B
0061 0315 0300 05AE 0730 0062;00E0 05AE 0730 0315 0062;0061 05AE 0300 0730 0315 0062;00E0 05AE 0730 0315 0062;0061 05AE 0300 0730 0315 0062; # (a◌̕◌̀◌֮◌ܰb; à◌֮◌ܰ◌̕b; a◌֮◌̀◌ܰ◌̕b; à◌֮◌ܰ◌̕b; a◌֮◌̀◌ܰ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC PTHAHA ABOVE, LATIN SMALL LETTER B
0061 0730 0315 0300 05AE 0062;0061 05AE 0730 0300 0315 0062;0061 05AE 0730 0300 0315 0062;0061 05AE 0730 0300 0315 0062;0061 05AE 0730 0300 0315 0062; # (a◌ܰ◌̕◌̀◌֮b; a◌֮◌ܰ◌̀◌̕b; a◌֮◌ܰ◌̀◌̕b; a◌֮◌ܰ◌̀◌̕b; a◌֮◌ܰ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC PTHAHA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 0731 0062;0061 302A 0316 0731 059A 0062;0061 302A 0316 0731 059A 0062;0061 302A 0316 0731 059A 0062;0061 302A 0316 0731 059A 0062; # (a◌֚◌̖◌〪◌ܱb; a◌〪◌̖◌ܱ◌֚b; a◌〪◌̖◌ܱ◌֚b; a◌〪◌̖◌ܱ◌֚b; a◌〪◌̖◌ܱ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC PTHAHA BELOW, LATIN SMALL LETTER B
-0061 0731 059A 0316 302A 0062;0061 302A 0731 0316 059A 0062;0061 302A 0731 0316 059A 0062;0061 302A 0731 0316 059A 0062;0061 302A 0731 0316 059A 0062; # (a◌ܱ◌֚◌̖◌〪b; a◌〪◌ܱ◌̖◌֚b; a◌〪◌ܱ◌̖◌֚b; a◌〪◌ܱ◌̖◌֚b; a◌〪◌ܱ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC PTHAHA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0731 0062;0061 1DFA 0316 0731 059A 0062;0061 1DFA 0316 0731 059A 0062;0061 1DFA 0316 0731 059A 0062;0061 1DFA 0316 0731 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, SYRIAC PTHAHA BELOW, LATIN SMALL LETTER B
+0061 0731 059A 0316 1DFA 0062;0061 1DFA 0731 0316 059A 0062;0061 1DFA 0731 0316 059A 0062;0061 1DFA 0731 0316 059A 0062;0061 1DFA 0731 0316 059A 0062; # (a◌ܱ◌֚◌̖◌᷺b; a◌᷺◌ܱ◌̖◌֚b; a◌᷺◌ܱ◌̖◌֚b; a◌᷺◌ܱ◌̖◌֚b; a◌᷺◌ܱ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC PTHAHA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 0732 0062;00E0 05AE 0732 0315 0062;0061 05AE 0300 0732 0315 0062;00E0 05AE 0732 0315 0062;0061 05AE 0300 0732 0315 0062; # (a◌̕◌̀◌֮◌ܲb; à◌֮◌ܲ◌̕b; a◌֮◌̀◌ܲ◌̕b; à◌֮◌ܲ◌̕b; a◌֮◌̀◌ܲ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC PTHAHA DOTTED, LATIN SMALL LETTER B
0061 0732 0315 0300 05AE 0062;0061 05AE 0732 0300 0315 0062;0061 05AE 0732 0300 0315 0062;0061 05AE 0732 0300 0315 0062;0061 05AE 0732 0300 0315 0062; # (a◌ܲ◌̕◌̀◌֮b; a◌֮◌ܲ◌̀◌̕b; a◌֮◌ܲ◌̀◌̕b; a◌֮◌ܲ◌̀◌̕b; a◌֮◌ܲ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC PTHAHA DOTTED, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 0733 0062;00E0 05AE 0733 0315 0062;0061 05AE 0300 0733 0315 0062;00E0 05AE 0733 0315 0062;0061 05AE 0300 0733 0315 0062; # (a◌̕◌̀◌֮◌ܳb; à◌֮◌ܳ◌̕b; a◌֮◌̀◌ܳ◌̕b; à◌֮◌ܳ◌̕b; a◌֮◌̀◌ܳ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC ZQAPHA ABOVE, LATIN SMALL LETTER B
0061 0733 0315 0300 05AE 0062;0061 05AE 0733 0300 0315 0062;0061 05AE 0733 0300 0315 0062;0061 05AE 0733 0300 0315 0062;0061 05AE 0733 0300 0315 0062; # (a◌ܳ◌̕◌̀◌֮b; a◌֮◌ܳ◌̀◌̕b; a◌֮◌ܳ◌̀◌̕b; a◌֮◌ܳ◌̀◌̕b; a◌֮◌ܳ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC ZQAPHA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 0734 0062;0061 302A 0316 0734 059A 0062;0061 302A 0316 0734 059A 0062;0061 302A 0316 0734 059A 0062;0061 302A 0316 0734 059A 0062; # (a◌֚◌̖◌〪◌ܴb; a◌〪◌̖◌ܴ◌֚b; a◌〪◌̖◌ܴ◌֚b; a◌〪◌̖◌ܴ◌֚b; a◌〪◌̖◌ܴ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC ZQAPHA BELOW, LATIN SMALL LETTER B
-0061 0734 059A 0316 302A 0062;0061 302A 0734 0316 059A 0062;0061 302A 0734 0316 059A 0062;0061 302A 0734 0316 059A 0062;0061 302A 0734 0316 059A 0062; # (a◌ܴ◌֚◌̖◌〪b; a◌〪◌ܴ◌̖◌֚b; a◌〪◌ܴ◌̖◌֚b; a◌〪◌ܴ◌̖◌֚b; a◌〪◌ܴ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC ZQAPHA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0734 0062;0061 1DFA 0316 0734 059A 0062;0061 1DFA 0316 0734 059A 0062;0061 1DFA 0316 0734 059A 0062;0061 1DFA 0316 0734 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, SYRIAC ZQAPHA BELOW, LATIN SMALL LETTER B
+0061 0734 059A 0316 1DFA 0062;0061 1DFA 0734 0316 059A 0062;0061 1DFA 0734 0316 059A 0062;0061 1DFA 0734 0316 059A 0062;0061 1DFA 0734 0316 059A 0062; # (a◌ܴ◌֚◌̖◌᷺b; a◌᷺◌ܴ◌̖◌֚b; a◌᷺◌ܴ◌̖◌֚b; a◌᷺◌ܴ◌̖◌֚b; a◌᷺◌ܴ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC ZQAPHA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 0735 0062;00E0 05AE 0735 0315 0062;0061 05AE 0300 0735 0315 0062;00E0 05AE 0735 0315 0062;0061 05AE 0300 0735 0315 0062; # (a◌̕◌̀◌֮◌ܵb; à◌֮◌ܵ◌̕b; a◌֮◌̀◌ܵ◌̕b; à◌֮◌ܵ◌̕b; a◌֮◌̀◌ܵ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC ZQAPHA DOTTED, LATIN SMALL LETTER B
0061 0735 0315 0300 05AE 0062;0061 05AE 0735 0300 0315 0062;0061 05AE 0735 0300 0315 0062;0061 05AE 0735 0300 0315 0062;0061 05AE 0735 0300 0315 0062; # (a◌ܵ◌̕◌̀◌֮b; a◌֮◌ܵ◌̀◌̕b; a◌֮◌ܵ◌̀◌̕b; a◌֮◌ܵ◌̀◌̕b; a◌֮◌ܵ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC ZQAPHA DOTTED, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 0736 0062;00E0 05AE 0736 0315 0062;0061 05AE 0300 0736 0315 0062;00E0 05AE 0736 0315 0062;0061 05AE 0300 0736 0315 0062; # (a◌̕◌̀◌֮◌ܶb; à◌֮◌ܶ◌̕b; a◌֮◌̀◌ܶ◌̕b; à◌֮◌ܶ◌̕b; a◌֮◌̀◌ܶ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC RBASA ABOVE, LATIN SMALL LETTER B
0061 0736 0315 0300 05AE 0062;0061 05AE 0736 0300 0315 0062;0061 05AE 0736 0300 0315 0062;0061 05AE 0736 0300 0315 0062;0061 05AE 0736 0300 0315 0062; # (a◌ܶ◌̕◌̀◌֮b; a◌֮◌ܶ◌̀◌̕b; a◌֮◌ܶ◌̀◌̕b; a◌֮◌ܶ◌̀◌̕b; a◌֮◌ܶ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC RBASA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 0737 0062;0061 302A 0316 0737 059A 0062;0061 302A 0316 0737 059A 0062;0061 302A 0316 0737 059A 0062;0061 302A 0316 0737 059A 0062; # (a◌֚◌̖◌〪◌ܷb; a◌〪◌̖◌ܷ◌֚b; a◌〪◌̖◌ܷ◌֚b; a◌〪◌̖◌ܷ◌֚b; a◌〪◌̖◌ܷ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC RBASA BELOW, LATIN SMALL LETTER B
-0061 0737 059A 0316 302A 0062;0061 302A 0737 0316 059A 0062;0061 302A 0737 0316 059A 0062;0061 302A 0737 0316 059A 0062;0061 302A 0737 0316 059A 0062; # (a◌ܷ◌֚◌̖◌〪b; a◌〪◌ܷ◌̖◌֚b; a◌〪◌ܷ◌̖◌֚b; a◌〪◌ܷ◌̖◌֚b; a◌〪◌ܷ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC RBASA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0738 0062;0061 302A 0316 0738 059A 0062;0061 302A 0316 0738 059A 0062;0061 302A 0316 0738 059A 0062;0061 302A 0316 0738 059A 0062; # (a◌֚◌̖◌〪◌ܸb; a◌〪◌̖◌ܸ◌֚b; a◌〪◌̖◌ܸ◌֚b; a◌〪◌̖◌ܸ◌֚b; a◌〪◌̖◌ܸ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC DOTTED ZLAMA HORIZONTAL, LATIN SMALL LETTER B
-0061 0738 059A 0316 302A 0062;0061 302A 0738 0316 059A 0062;0061 302A 0738 0316 059A 0062;0061 302A 0738 0316 059A 0062;0061 302A 0738 0316 059A 0062; # (a◌ܸ◌֚◌̖◌〪b; a◌〪◌ܸ◌̖◌֚b; a◌〪◌ܸ◌̖◌֚b; a◌〪◌ܸ◌̖◌֚b; a◌〪◌ܸ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC DOTTED ZLAMA HORIZONTAL, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0739 0062;0061 302A 0316 0739 059A 0062;0061 302A 0316 0739 059A 0062;0061 302A 0316 0739 059A 0062;0061 302A 0316 0739 059A 0062; # (a◌֚◌̖◌〪◌ܹb; a◌〪◌̖◌ܹ◌֚b; a◌〪◌̖◌ܹ◌֚b; a◌〪◌̖◌ܹ◌֚b; a◌〪◌̖◌ܹ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC DOTTED ZLAMA ANGULAR, LATIN SMALL LETTER B
-0061 0739 059A 0316 302A 0062;0061 302A 0739 0316 059A 0062;0061 302A 0739 0316 059A 0062;0061 302A 0739 0316 059A 0062;0061 302A 0739 0316 059A 0062; # (a◌ܹ◌֚◌̖◌〪b; a◌〪◌ܹ◌̖◌֚b; a◌〪◌ܹ◌̖◌֚b; a◌〪◌ܹ◌̖◌֚b; a◌〪◌ܹ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC DOTTED ZLAMA ANGULAR, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0737 0062;0061 1DFA 0316 0737 059A 0062;0061 1DFA 0316 0737 059A 0062;0061 1DFA 0316 0737 059A 0062;0061 1DFA 0316 0737 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, SYRIAC RBASA BELOW, LATIN SMALL LETTER B
+0061 0737 059A 0316 1DFA 0062;0061 1DFA 0737 0316 059A 0062;0061 1DFA 0737 0316 059A 0062;0061 1DFA 0737 0316 059A 0062;0061 1DFA 0737 0316 059A 0062; # (a◌ܷ◌֚◌̖◌᷺b; a◌᷺◌ܷ◌̖◌֚b; a◌᷺◌ܷ◌̖◌֚b; a◌᷺◌ܷ◌̖◌֚b; a◌᷺◌ܷ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC RBASA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0738 0062;0061 1DFA 0316 0738 059A 0062;0061 1DFA 0316 0738 059A 0062;0061 1DFA 0316 0738 059A 0062;0061 1DFA 0316 0738 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, SYRIAC DOTTED ZLAMA HORIZONTAL, LATIN SMALL LETTER B
+0061 0738 059A 0316 1DFA 0062;0061 1DFA 0738 0316 059A 0062;0061 1DFA 0738 0316 059A 0062;0061 1DFA 0738 0316 059A 0062;0061 1DFA 0738 0316 059A 0062; # (a◌ܸ◌֚◌̖◌᷺b; a◌᷺◌ܸ◌̖◌֚b; a◌᷺◌ܸ◌̖◌֚b; a◌᷺◌ܸ◌̖◌֚b; a◌᷺◌ܸ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC DOTTED ZLAMA HORIZONTAL, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0739 0062;0061 1DFA 0316 0739 059A 0062;0061 1DFA 0316 0739 059A 0062;0061 1DFA 0316 0739 059A 0062;0061 1DFA 0316 0739 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, SYRIAC DOTTED ZLAMA ANGULAR, LATIN SMALL LETTER B
+0061 0739 059A 0316 1DFA 0062;0061 1DFA 0739 0316 059A 0062;0061 1DFA 0739 0316 059A 0062;0061 1DFA 0739 0316 059A 0062;0061 1DFA 0739 0316 059A 0062; # (a◌ܹ◌֚◌̖◌᷺b; a◌᷺◌ܹ◌̖◌֚b; a◌᷺◌ܹ◌̖◌֚b; a◌᷺◌ܹ◌̖◌֚b; a◌᷺◌ܹ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC DOTTED ZLAMA ANGULAR, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 073A 0062;00E0 05AE 073A 0315 0062;0061 05AE 0300 073A 0315 0062;00E0 05AE 073A 0315 0062;0061 05AE 0300 073A 0315 0062; # (a◌̕◌̀◌֮◌ܺb; à◌֮◌ܺ◌̕b; a◌֮◌̀◌ܺ◌̕b; à◌֮◌ܺ◌̕b; a◌֮◌̀◌ܺ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC HBASA ABOVE, LATIN SMALL LETTER B
0061 073A 0315 0300 05AE 0062;0061 05AE 073A 0300 0315 0062;0061 05AE 073A 0300 0315 0062;0061 05AE 073A 0300 0315 0062;0061 05AE 073A 0300 0315 0062; # (a◌ܺ◌̕◌̀◌֮b; a◌֮◌ܺ◌̀◌̕b; a◌֮◌ܺ◌̀◌̕b; a◌֮◌ܺ◌̀◌̕b; a◌֮◌ܺ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC HBASA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 073B 0062;0061 302A 0316 073B 059A 0062;0061 302A 0316 073B 059A 0062;0061 302A 0316 073B 059A 0062;0061 302A 0316 073B 059A 0062; # (a◌֚◌̖◌〪◌ܻb; a◌〪◌̖◌ܻ◌֚b; a◌〪◌̖◌ܻ◌֚b; a◌〪◌̖◌ܻ◌֚b; a◌〪◌̖◌ܻ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC HBASA BELOW, LATIN SMALL LETTER B
-0061 073B 059A 0316 302A 0062;0061 302A 073B 0316 059A 0062;0061 302A 073B 0316 059A 0062;0061 302A 073B 0316 059A 0062;0061 302A 073B 0316 059A 0062; # (a◌ܻ◌֚◌̖◌〪b; a◌〪◌ܻ◌̖◌֚b; a◌〪◌ܻ◌̖◌֚b; a◌〪◌ܻ◌̖◌֚b; a◌〪◌ܻ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC HBASA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 073C 0062;0061 302A 0316 073C 059A 0062;0061 302A 0316 073C 059A 0062;0061 302A 0316 073C 059A 0062;0061 302A 0316 073C 059A 0062; # (a◌֚◌̖◌〪◌ܼb; a◌〪◌̖◌ܼ◌֚b; a◌〪◌̖◌ܼ◌֚b; a◌〪◌̖◌ܼ◌֚b; a◌〪◌̖◌ܼ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC HBASA-ESASA DOTTED, LATIN SMALL LETTER B
-0061 073C 059A 0316 302A 0062;0061 302A 073C 0316 059A 0062;0061 302A 073C 0316 059A 0062;0061 302A 073C 0316 059A 0062;0061 302A 073C 0316 059A 0062; # (a◌ܼ◌֚◌̖◌〪b; a◌〪◌ܼ◌̖◌֚b; a◌〪◌ܼ◌̖◌֚b; a◌〪◌ܼ◌̖◌֚b; a◌〪◌ܼ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC HBASA-ESASA DOTTED, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 073B 0062;0061 1DFA 0316 073B 059A 0062;0061 1DFA 0316 073B 059A 0062;0061 1DFA 0316 073B 059A 0062;0061 1DFA 0316 073B 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, SYRIAC HBASA BELOW, LATIN SMALL LETTER B
+0061 073B 059A 0316 1DFA 0062;0061 1DFA 073B 0316 059A 0062;0061 1DFA 073B 0316 059A 0062;0061 1DFA 073B 0316 059A 0062;0061 1DFA 073B 0316 059A 0062; # (a◌ܻ◌֚◌̖◌᷺b; a◌᷺◌ܻ◌̖◌֚b; a◌᷺◌ܻ◌̖◌֚b; a◌᷺◌ܻ◌̖◌֚b; a◌᷺◌ܻ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC HBASA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 073C 0062;0061 1DFA 0316 073C 059A 0062;0061 1DFA 0316 073C 059A 0062;0061 1DFA 0316 073C 059A 0062;0061 1DFA 0316 073C 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, SYRIAC HBASA-ESASA DOTTED, LATIN SMALL LETTER B
+0061 073C 059A 0316 1DFA 0062;0061 1DFA 073C 0316 059A 0062;0061 1DFA 073C 0316 059A 0062;0061 1DFA 073C 0316 059A 0062;0061 1DFA 073C 0316 059A 0062; # (a◌ܼ◌֚◌̖◌᷺b; a◌᷺◌ܼ◌̖◌֚b; a◌᷺◌ܼ◌̖◌֚b; a◌᷺◌ܼ◌̖◌֚b; a◌᷺◌ܼ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC HBASA-ESASA DOTTED, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 073D 0062;00E0 05AE 073D 0315 0062;0061 05AE 0300 073D 0315 0062;00E0 05AE 073D 0315 0062;0061 05AE 0300 073D 0315 0062; # (a◌̕◌̀◌֮◌ܽb; à◌֮◌ܽ◌̕b; a◌֮◌̀◌ܽ◌̕b; à◌֮◌ܽ◌̕b; a◌֮◌̀◌ܽ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC ESASA ABOVE, LATIN SMALL LETTER B
0061 073D 0315 0300 05AE 0062;0061 05AE 073D 0300 0315 0062;0061 05AE 073D 0300 0315 0062;0061 05AE 073D 0300 0315 0062;0061 05AE 073D 0300 0315 0062; # (a◌ܽ◌̕◌̀◌֮b; a◌֮◌ܽ◌̀◌̕b; a◌֮◌ܽ◌̀◌̕b; a◌֮◌ܽ◌̀◌̕b; a◌֮◌ܽ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC ESASA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 073E 0062;0061 302A 0316 073E 059A 0062;0061 302A 0316 073E 059A 0062;0061 302A 0316 073E 059A 0062;0061 302A 0316 073E 059A 0062; # (a◌֚◌̖◌〪◌ܾb; a◌〪◌̖◌ܾ◌֚b; a◌〪◌̖◌ܾ◌֚b; a◌〪◌̖◌ܾ◌֚b; a◌〪◌̖◌ܾ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC ESASA BELOW, LATIN SMALL LETTER B
-0061 073E 059A 0316 302A 0062;0061 302A 073E 0316 059A 0062;0061 302A 073E 0316 059A 0062;0061 302A 073E 0316 059A 0062;0061 302A 073E 0316 059A 0062; # (a◌ܾ◌֚◌̖◌〪b; a◌〪◌ܾ◌̖◌֚b; a◌〪◌ܾ◌̖◌֚b; a◌〪◌ܾ◌̖◌֚b; a◌〪◌ܾ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC ESASA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 073E 0062;0061 1DFA 0316 073E 059A 0062;0061 1DFA 0316 073E 059A 0062;0061 1DFA 0316 073E 059A 0062;0061 1DFA 0316 073E 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, SYRIAC ESASA BELOW, LATIN SMALL LETTER B
+0061 073E 059A 0316 1DFA 0062;0061 1DFA 073E 0316 059A 0062;0061 1DFA 073E 0316 059A 0062;0061 1DFA 073E 0316 059A 0062;0061 1DFA 073E 0316 059A 0062; # (a◌ܾ◌֚◌̖◌᷺b; a◌᷺◌ܾ◌̖◌֚b; a◌᷺◌ܾ◌̖◌֚b; a◌᷺◌ܾ◌̖◌֚b; a◌᷺◌ܾ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC ESASA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 073F 0062;00E0 05AE 073F 0315 0062;0061 05AE 0300 073F 0315 0062;00E0 05AE 073F 0315 0062;0061 05AE 0300 073F 0315 0062; # (a◌̕◌̀◌֮◌ܿb; à◌֮◌ܿ◌̕b; a◌֮◌̀◌ܿ◌̕b; à◌֮◌ܿ◌̕b; a◌֮◌̀◌ܿ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC RWAHA, LATIN SMALL LETTER B
0061 073F 0315 0300 05AE 0062;0061 05AE 073F 0300 0315 0062;0061 05AE 073F 0300 0315 0062;0061 05AE 073F 0300 0315 0062;0061 05AE 073F 0300 0315 0062; # (a◌ܿ◌̕◌̀◌֮b; a◌֮◌ܿ◌̀◌̕b; a◌֮◌ܿ◌̀◌̕b; a◌֮◌ܿ◌̀◌̕b; a◌֮◌ܿ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC RWAHA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 0740 0062;00E0 05AE 0740 0315 0062;0061 05AE 0300 0740 0315 0062;00E0 05AE 0740 0315 0062;0061 05AE 0300 0740 0315 0062; # (a◌̕◌̀◌֮◌݀b; à◌֮◌݀◌̕b; a◌֮◌̀◌݀◌̕b; à◌֮◌݀◌̕b; a◌֮◌̀◌݀◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC FEMININE DOT, LATIN SMALL LETTER B
0061 0740 0315 0300 05AE 0062;0061 05AE 0740 0300 0315 0062;0061 05AE 0740 0300 0315 0062;0061 05AE 0740 0300 0315 0062;0061 05AE 0740 0300 0315 0062; # (a◌݀◌̕◌̀◌֮b; a◌֮◌݀◌̀◌̕b; a◌֮◌݀◌̀◌̕b; a◌֮◌݀◌̀◌̕b; a◌֮◌݀◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC FEMININE DOT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 0741 0062;00E0 05AE 0741 0315 0062;0061 05AE 0300 0741 0315 0062;00E0 05AE 0741 0315 0062;0061 05AE 0300 0741 0315 0062; # (a◌̕◌̀◌֮◌݁b; à◌֮◌݁◌̕b; a◌֮◌̀◌݁◌̕b; à◌֮◌݁◌̕b; a◌֮◌̀◌݁◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC QUSHSHAYA, LATIN SMALL LETTER B
0061 0741 0315 0300 05AE 0062;0061 05AE 0741 0300 0315 0062;0061 05AE 0741 0300 0315 0062;0061 05AE 0741 0300 0315 0062;0061 05AE 0741 0300 0315 0062; # (a◌݁◌̕◌̀◌֮b; a◌֮◌݁◌̀◌̕b; a◌֮◌݁◌̀◌̕b; a◌֮◌݁◌̀◌̕b; a◌֮◌݁◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC QUSHSHAYA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 0742 0062;0061 302A 0316 0742 059A 0062;0061 302A 0316 0742 059A 0062;0061 302A 0316 0742 059A 0062;0061 302A 0316 0742 059A 0062; # (a◌֚◌̖◌〪◌݂b; a◌〪◌̖◌݂◌֚b; a◌〪◌̖◌݂◌֚b; a◌〪◌̖◌݂◌֚b; a◌〪◌̖◌݂◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC RUKKAKHA, LATIN SMALL LETTER B
-0061 0742 059A 0316 302A 0062;0061 302A 0742 0316 059A 0062;0061 302A 0742 0316 059A 0062;0061 302A 0742 0316 059A 0062;0061 302A 0742 0316 059A 0062; # (a◌݂◌֚◌̖◌〪b; a◌〪◌݂◌̖◌֚b; a◌〪◌݂◌̖◌֚b; a◌〪◌݂◌̖◌֚b; a◌〪◌݂◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC RUKKAKHA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0742 0062;0061 1DFA 0316 0742 059A 0062;0061 1DFA 0316 0742 059A 0062;0061 1DFA 0316 0742 059A 0062;0061 1DFA 0316 0742 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, SYRIAC RUKKAKHA, LATIN SMALL LETTER B
+0061 0742 059A 0316 1DFA 0062;0061 1DFA 0742 0316 059A 0062;0061 1DFA 0742 0316 059A 0062;0061 1DFA 0742 0316 059A 0062;0061 1DFA 0742 0316 059A 0062; # (a◌݂◌֚◌̖◌᷺b; a◌᷺◌݂◌̖◌֚b; a◌᷺◌݂◌̖◌֚b; a◌᷺◌݂◌̖◌֚b; a◌᷺◌݂◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC RUKKAKHA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 0743 0062;00E0 05AE 0743 0315 0062;0061 05AE 0300 0743 0315 0062;00E0 05AE 0743 0315 0062;0061 05AE 0300 0743 0315 0062; # (a◌̕◌̀◌֮◌݃b; à◌֮◌݃◌̕b; a◌֮◌̀◌݃◌̕b; à◌֮◌݃◌̕b; a◌֮◌̀◌݃◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC TWO VERTICAL DOTS ABOVE, LATIN SMALL LETTER B
0061 0743 0315 0300 05AE 0062;0061 05AE 0743 0300 0315 0062;0061 05AE 0743 0300 0315 0062;0061 05AE 0743 0300 0315 0062;0061 05AE 0743 0300 0315 0062; # (a◌݃◌̕◌̀◌֮b; a◌֮◌݃◌̀◌̕b; a◌֮◌݃◌̀◌̕b; a◌֮◌݃◌̀◌̕b; a◌֮◌݃◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC TWO VERTICAL DOTS ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 0744 0062;0061 302A 0316 0744 059A 0062;0061 302A 0316 0744 059A 0062;0061 302A 0316 0744 059A 0062;0061 302A 0316 0744 059A 0062; # (a◌֚◌̖◌〪◌݄b; a◌〪◌̖◌݄◌֚b; a◌〪◌̖◌݄◌֚b; a◌〪◌̖◌݄◌֚b; a◌〪◌̖◌݄◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC TWO VERTICAL DOTS BELOW, LATIN SMALL LETTER B
-0061 0744 059A 0316 302A 0062;0061 302A 0744 0316 059A 0062;0061 302A 0744 0316 059A 0062;0061 302A 0744 0316 059A 0062;0061 302A 0744 0316 059A 0062; # (a◌݄◌֚◌̖◌〪b; a◌〪◌݄◌̖◌֚b; a◌〪◌݄◌̖◌֚b; a◌〪◌݄◌̖◌֚b; a◌〪◌݄◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC TWO VERTICAL DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0744 0062;0061 1DFA 0316 0744 059A 0062;0061 1DFA 0316 0744 059A 0062;0061 1DFA 0316 0744 059A 0062;0061 1DFA 0316 0744 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, SYRIAC TWO VERTICAL DOTS BELOW, LATIN SMALL LETTER B
+0061 0744 059A 0316 1DFA 0062;0061 1DFA 0744 0316 059A 0062;0061 1DFA 0744 0316 059A 0062;0061 1DFA 0744 0316 059A 0062;0061 1DFA 0744 0316 059A 0062; # (a◌݄◌֚◌̖◌᷺b; a◌᷺◌݄◌̖◌֚b; a◌᷺◌݄◌̖◌֚b; a◌᷺◌݄◌̖◌֚b; a◌᷺◌݄◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC TWO VERTICAL DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 0745 0062;00E0 05AE 0745 0315 0062;0061 05AE 0300 0745 0315 0062;00E0 05AE 0745 0315 0062;0061 05AE 0300 0745 0315 0062; # (a◌̕◌̀◌֮◌݅b; à◌֮◌݅◌̕b; a◌֮◌̀◌݅◌̕b; à◌֮◌݅◌̕b; a◌֮◌̀◌݅◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC THREE DOTS ABOVE, LATIN SMALL LETTER B
0061 0745 0315 0300 05AE 0062;0061 05AE 0745 0300 0315 0062;0061 05AE 0745 0300 0315 0062;0061 05AE 0745 0300 0315 0062;0061 05AE 0745 0300 0315 0062; # (a◌݅◌̕◌̀◌֮b; a◌֮◌݅◌̀◌̕b; a◌֮◌݅◌̀◌̕b; a◌֮◌݅◌̀◌̕b; a◌֮◌݅◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC THREE DOTS ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 0746 0062;0061 302A 0316 0746 059A 0062;0061 302A 0316 0746 059A 0062;0061 302A 0316 0746 059A 0062;0061 302A 0316 0746 059A 0062; # (a◌֚◌̖◌〪◌݆b; a◌〪◌̖◌݆◌֚b; a◌〪◌̖◌݆◌֚b; a◌〪◌̖◌݆◌֚b; a◌〪◌̖◌݆◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC THREE DOTS BELOW, LATIN SMALL LETTER B
-0061 0746 059A 0316 302A 0062;0061 302A 0746 0316 059A 0062;0061 302A 0746 0316 059A 0062;0061 302A 0746 0316 059A 0062;0061 302A 0746 0316 059A 0062; # (a◌݆◌֚◌̖◌〪b; a◌〪◌݆◌̖◌֚b; a◌〪◌݆◌̖◌֚b; a◌〪◌݆◌̖◌֚b; a◌〪◌݆◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC THREE DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0746 0062;0061 1DFA 0316 0746 059A 0062;0061 1DFA 0316 0746 059A 0062;0061 1DFA 0316 0746 059A 0062;0061 1DFA 0316 0746 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, SYRIAC THREE DOTS BELOW, LATIN SMALL LETTER B
+0061 0746 059A 0316 1DFA 0062;0061 1DFA 0746 0316 059A 0062;0061 1DFA 0746 0316 059A 0062;0061 1DFA 0746 0316 059A 0062;0061 1DFA 0746 0316 059A 0062; # (a◌݆◌֚◌̖◌᷺b; a◌᷺◌݆◌̖◌֚b; a◌᷺◌݆◌̖◌֚b; a◌᷺◌݆◌̖◌֚b; a◌᷺◌݆◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC THREE DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 0747 0062;00E0 05AE 0747 0315 0062;0061 05AE 0300 0747 0315 0062;00E0 05AE 0747 0315 0062;0061 05AE 0300 0747 0315 0062; # (a◌̕◌̀◌֮◌݇b; à◌֮◌݇◌̕b; a◌֮◌̀◌݇◌̕b; à◌֮◌݇◌̕b; a◌֮◌̀◌݇◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC OBLIQUE LINE ABOVE, LATIN SMALL LETTER B
0061 0747 0315 0300 05AE 0062;0061 05AE 0747 0300 0315 0062;0061 05AE 0747 0300 0315 0062;0061 05AE 0747 0300 0315 0062;0061 05AE 0747 0300 0315 0062; # (a◌݇◌̕◌̀◌֮b; a◌֮◌݇◌̀◌̕b; a◌֮◌݇◌̀◌̕b; a◌֮◌݇◌̀◌̕b; a◌֮◌݇◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC OBLIQUE LINE ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 0748 0062;0061 302A 0316 0748 059A 0062;0061 302A 0316 0748 059A 0062;0061 302A 0316 0748 059A 0062;0061 302A 0316 0748 059A 0062; # (a◌֚◌̖◌〪◌݈b; a◌〪◌̖◌݈◌֚b; a◌〪◌̖◌݈◌֚b; a◌〪◌̖◌݈◌֚b; a◌〪◌̖◌݈◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC OBLIQUE LINE BELOW, LATIN SMALL LETTER B
-0061 0748 059A 0316 302A 0062;0061 302A 0748 0316 059A 0062;0061 302A 0748 0316 059A 0062;0061 302A 0748 0316 059A 0062;0061 302A 0748 0316 059A 0062; # (a◌݈◌֚◌̖◌〪b; a◌〪◌݈◌̖◌֚b; a◌〪◌݈◌̖◌֚b; a◌〪◌݈◌̖◌֚b; a◌〪◌݈◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC OBLIQUE LINE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0748 0062;0061 1DFA 0316 0748 059A 0062;0061 1DFA 0316 0748 059A 0062;0061 1DFA 0316 0748 059A 0062;0061 1DFA 0316 0748 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, SYRIAC OBLIQUE LINE BELOW, LATIN SMALL LETTER B
+0061 0748 059A 0316 1DFA 0062;0061 1DFA 0748 0316 059A 0062;0061 1DFA 0748 0316 059A 0062;0061 1DFA 0748 0316 059A 0062;0061 1DFA 0748 0316 059A 0062; # (a◌݈◌֚◌̖◌᷺b; a◌᷺◌݈◌̖◌֚b; a◌᷺◌݈◌̖◌֚b; a◌᷺◌݈◌̖◌֚b; a◌᷺◌݈◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC OBLIQUE LINE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 0749 0062;00E0 05AE 0749 0315 0062;0061 05AE 0300 0749 0315 0062;00E0 05AE 0749 0315 0062;0061 05AE 0300 0749 0315 0062; # (a◌̕◌̀◌֮◌݉b; à◌֮◌݉◌̕b; a◌֮◌̀◌݉◌̕b; à◌֮◌݉◌̕b; a◌֮◌̀◌݉◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC MUSIC, LATIN SMALL LETTER B
0061 0749 0315 0300 05AE 0062;0061 05AE 0749 0300 0315 0062;0061 05AE 0749 0300 0315 0062;0061 05AE 0749 0300 0315 0062;0061 05AE 0749 0300 0315 0062; # (a◌݉◌̕◌̀◌֮b; a◌֮◌݉◌̀◌̕b; a◌֮◌݉◌̀◌̕b; a◌֮◌݉◌̀◌̕b; a◌֮◌݉◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC MUSIC, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 074A 0062;00E0 05AE 074A 0315 0062;0061 05AE 0300 074A 0315 0062;00E0 05AE 074A 0315 0062;0061 05AE 0300 074A 0315 0062; # (a◌̕◌̀◌֮◌݊b; à◌֮◌݊◌̕b; a◌֮◌̀◌݊◌̕b; à◌֮◌݊◌̕b; a◌֮◌̀◌݊◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC BARREKH, LATIN SMALL LETTER B
@@ -17489,12 +17548,12 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 07F0 0315 0300 05AE 0062;0061 05AE 07F0 0300 0315 0062;0061 05AE 07F0 0300 0315 0062;0061 05AE 07F0 0300 0315 0062;0061 05AE 07F0 0300 0315 0062; # (a◌߰◌̕◌̀◌֮b; a◌֮◌߰◌̀◌̕b; a◌֮◌߰◌̀◌̕b; a◌֮◌߰◌̀◌̕b; a◌֮◌߰◌̀◌̕b; ) LATIN SMALL LETTER A, NKO COMBINING LONG LOW TONE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 07F1 0062;00E0 05AE 07F1 0315 0062;0061 05AE 0300 07F1 0315 0062;00E0 05AE 07F1 0315 0062;0061 05AE 0300 07F1 0315 0062; # (a◌̕◌̀◌֮◌߱b; à◌֮◌߱◌̕b; a◌֮◌̀◌߱◌̕b; à◌֮◌߱◌̕b; a◌֮◌̀◌߱◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NKO COMBINING LONG RISING TONE, LATIN SMALL LETTER B
0061 07F1 0315 0300 05AE 0062;0061 05AE 07F1 0300 0315 0062;0061 05AE 07F1 0300 0315 0062;0061 05AE 07F1 0300 0315 0062;0061 05AE 07F1 0300 0315 0062; # (a◌߱◌̕◌̀◌֮b; a◌֮◌߱◌̀◌̕b; a◌֮◌߱◌̀◌̕b; a◌֮◌߱◌̀◌̕b; a◌֮◌߱◌̀◌̕b; ) LATIN SMALL LETTER A, NKO COMBINING LONG RISING TONE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 07F2 0062;0061 302A 0316 07F2 059A 0062;0061 302A 0316 07F2 059A 0062;0061 302A 0316 07F2 059A 0062;0061 302A 0316 07F2 059A 0062; # (a◌֚◌̖◌〪◌߲b; a◌〪◌̖◌߲◌֚b; a◌〪◌̖◌߲◌֚b; a◌〪◌̖◌߲◌֚b; a◌〪◌̖◌߲◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, NKO COMBINING NASALIZATION MARK, LATIN SMALL LETTER B
-0061 07F2 059A 0316 302A 0062;0061 302A 07F2 0316 059A 0062;0061 302A 07F2 0316 059A 0062;0061 302A 07F2 0316 059A 0062;0061 302A 07F2 0316 059A 0062; # (a◌߲◌֚◌̖◌〪b; a◌〪◌߲◌̖◌֚b; a◌〪◌߲◌̖◌֚b; a◌〪◌߲◌̖◌֚b; a◌〪◌߲◌̖◌֚b; ) LATIN SMALL LETTER A, NKO COMBINING NASALIZATION MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 07F2 0062;0061 1DFA 0316 07F2 059A 0062;0061 1DFA 0316 07F2 059A 0062;0061 1DFA 0316 07F2 059A 0062;0061 1DFA 0316 07F2 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, NKO COMBINING NASALIZATION MARK, LATIN SMALL LETTER B
+0061 07F2 059A 0316 1DFA 0062;0061 1DFA 07F2 0316 059A 0062;0061 1DFA 07F2 0316 059A 0062;0061 1DFA 07F2 0316 059A 0062;0061 1DFA 07F2 0316 059A 0062; # (a◌߲◌֚◌̖◌᷺b; a◌᷺◌߲◌̖◌֚b; a◌᷺◌߲◌̖◌֚b; a◌᷺◌߲◌̖◌֚b; a◌᷺◌߲◌̖◌֚b; ) LATIN SMALL LETTER A, NKO COMBINING NASALIZATION MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 07F3 0062;00E0 05AE 07F3 0315 0062;0061 05AE 0300 07F3 0315 0062;00E0 05AE 07F3 0315 0062;0061 05AE 0300 07F3 0315 0062; # (a◌̕◌̀◌֮◌߳b; à◌֮◌߳◌̕b; a◌֮◌̀◌߳◌̕b; à◌֮◌߳◌̕b; a◌֮◌̀◌߳◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NKO COMBINING DOUBLE DOT ABOVE, LATIN SMALL LETTER B
0061 07F3 0315 0300 05AE 0062;0061 05AE 07F3 0300 0315 0062;0061 05AE 07F3 0300 0315 0062;0061 05AE 07F3 0300 0315 0062;0061 05AE 07F3 0300 0315 0062; # (a◌߳◌̕◌̀◌֮b; a◌֮◌߳◌̀◌̕b; a◌֮◌߳◌̀◌̕b; a◌֮◌߳◌̀◌̕b; a◌֮◌߳◌̀◌̕b; ) LATIN SMALL LETTER A, NKO COMBINING DOUBLE DOT ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 07FD 0062;0061 302A 0316 07FD 059A 0062;0061 302A 0316 07FD 059A 0062;0061 302A 0316 07FD 059A 0062;0061 302A 0316 07FD 059A 0062; # (a◌֚◌̖◌〪◌߽b; a◌〪◌̖◌߽◌֚b; a◌〪◌̖◌߽◌֚b; a◌〪◌̖◌߽◌֚b; a◌〪◌̖◌߽◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, NKO DANTAYALAN, LATIN SMALL LETTER B
-0061 07FD 059A 0316 302A 0062;0061 302A 07FD 0316 059A 0062;0061 302A 07FD 0316 059A 0062;0061 302A 07FD 0316 059A 0062;0061 302A 07FD 0316 059A 0062; # (a◌߽◌֚◌̖◌〪b; a◌〪◌߽◌̖◌֚b; a◌〪◌߽◌̖◌֚b; a◌〪◌߽◌̖◌֚b; a◌〪◌߽◌̖◌֚b; ) LATIN SMALL LETTER A, NKO DANTAYALAN, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 07FD 0062;0061 1DFA 0316 07FD 059A 0062;0061 1DFA 0316 07FD 059A 0062;0061 1DFA 0316 07FD 059A 0062;0061 1DFA 0316 07FD 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, NKO DANTAYALAN, LATIN SMALL LETTER B
+0061 07FD 059A 0316 1DFA 0062;0061 1DFA 07FD 0316 059A 0062;0061 1DFA 07FD 0316 059A 0062;0061 1DFA 07FD 0316 059A 0062;0061 1DFA 07FD 0316 059A 0062; # (a◌߽◌֚◌̖◌᷺b; a◌᷺◌߽◌̖◌֚b; a◌᷺◌߽◌̖◌֚b; a◌᷺◌߽◌̖◌֚b; a◌᷺◌߽◌̖◌֚b; ) LATIN SMALL LETTER A, NKO DANTAYALAN, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 0816 0062;00E0 05AE 0816 0315 0062;0061 05AE 0300 0816 0315 0062;00E0 05AE 0816 0315 0062;0061 05AE 0300 0816 0315 0062; # (a◌̕◌̀◌֮◌ࠖb; à◌֮◌ࠖ◌̕b; a◌֮◌̀◌ࠖ◌̕b; à◌֮◌ࠖ◌̕b; a◌֮◌̀◌ࠖ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN MARK IN, LATIN SMALL LETTER B
0061 0816 0315 0300 05AE 0062;0061 05AE 0816 0300 0315 0062;0061 05AE 0816 0300 0315 0062;0061 05AE 0816 0300 0315 0062;0061 05AE 0816 0300 0315 0062; # (a◌ࠖ◌̕◌̀◌֮b; a◌֮◌ࠖ◌̀◌̕b; a◌֮◌ࠖ◌̀◌̕b; a◌֮◌ࠖ◌̀◌̕b; a◌֮◌ࠖ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN MARK IN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 0817 0062;00E0 05AE 0817 0315 0062;0061 05AE 0300 0817 0315 0062;00E0 05AE 0817 0315 0062;0061 05AE 0300 0817 0315 0062; # (a◌̕◌̀◌֮◌ࠗb; à◌֮◌ࠗ◌̕b; a◌֮◌̀◌ࠗ◌̕b; à◌֮◌ࠗ◌̕b; a◌֮◌̀◌ࠗ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN MARK IN-ALAF, LATIN SMALL LETTER B
@@ -17537,14 +17596,48 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 082C 0315 0300 05AE 0062;0061 05AE 082C 0300 0315 0062;0061 05AE 082C 0300 0315 0062;0061 05AE 082C 0300 0315 0062;0061 05AE 082C 0300 0315 0062; # (a◌ࠬ◌̕◌̀◌֮b; a◌֮◌ࠬ◌̀◌̕b; a◌֮◌ࠬ◌̀◌̕b; a◌֮◌ࠬ◌̀◌̕b; a◌֮◌ࠬ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN SUKUN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 082D 0062;00E0 05AE 082D 0315 0062;0061 05AE 0300 082D 0315 0062;00E0 05AE 082D 0315 0062;0061 05AE 0300 082D 0315 0062; # (a◌̕◌̀◌֮◌࠭b; à◌֮◌࠭◌̕b; a◌֮◌̀◌࠭◌̕b; à◌֮◌࠭◌̕b; a◌֮◌̀◌࠭◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN MARK NEQUDAA, LATIN SMALL LETTER B
0061 082D 0315 0300 05AE 0062;0061 05AE 082D 0300 0315 0062;0061 05AE 082D 0300 0315 0062;0061 05AE 082D 0300 0315 0062;0061 05AE 082D 0300 0315 0062; # (a◌࠭◌̕◌̀◌֮b; a◌֮◌࠭◌̀◌̕b; a◌֮◌࠭◌̀◌̕b; a◌֮◌࠭◌̀◌̕b; a◌֮◌࠭◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN MARK NEQUDAA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 0859 0062;0061 302A 0316 0859 059A 0062;0061 302A 0316 0859 059A 0062;0061 302A 0316 0859 059A 0062;0061 302A 0316 0859 059A 0062; # (a◌֚◌̖◌〪◌࡙b; a◌〪◌̖◌࡙◌֚b; a◌〪◌̖◌࡙◌֚b; a◌〪◌̖◌࡙◌֚b; a◌〪◌̖◌࡙◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MANDAIC AFFRICATION MARK, LATIN SMALL LETTER B
-0061 0859 059A 0316 302A 0062;0061 302A 0859 0316 059A 0062;0061 302A 0859 0316 059A 0062;0061 302A 0859 0316 059A 0062;0061 302A 0859 0316 059A 0062; # (a◌࡙◌֚◌̖◌〪b; a◌〪◌࡙◌̖◌֚b; a◌〪◌࡙◌̖◌֚b; a◌〪◌࡙◌̖◌֚b; a◌〪◌࡙◌̖◌֚b; ) LATIN SMALL LETTER A, MANDAIC AFFRICATION MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 085A 0062;0061 302A 0316 085A 059A 0062;0061 302A 0316 085A 059A 0062;0061 302A 0316 085A 059A 0062;0061 302A 0316 085A 059A 0062; # (a◌֚◌̖◌〪◌࡚b; a◌〪◌̖◌࡚◌֚b; a◌〪◌̖◌࡚◌֚b; a◌〪◌̖◌࡚◌֚b; a◌〪◌̖◌࡚◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MANDAIC VOCALIZATION MARK, LATIN SMALL LETTER B
-0061 085A 059A 0316 302A 0062;0061 302A 085A 0316 059A 0062;0061 302A 085A 0316 059A 0062;0061 302A 085A 0316 059A 0062;0061 302A 085A 0316 059A 0062; # (a◌࡚◌֚◌̖◌〪b; a◌〪◌࡚◌̖◌֚b; a◌〪◌࡚◌̖◌֚b; a◌〪◌࡚◌̖◌֚b; a◌〪◌࡚◌̖◌֚b; ) LATIN SMALL LETTER A, MANDAIC VOCALIZATION MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 085B 0062;0061 302A 0316 085B 059A 0062;0061 302A 0316 085B 059A 0062;0061 302A 0316 085B 059A 0062;0061 302A 0316 085B 059A 0062; # (a◌֚◌̖◌〪◌࡛b; a◌〪◌̖◌࡛◌֚b; a◌〪◌̖◌࡛◌֚b; a◌〪◌̖◌࡛◌֚b; a◌〪◌̖◌࡛◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MANDAIC GEMINATION MARK, LATIN SMALL LETTER B
-0061 085B 059A 0316 302A 0062;0061 302A 085B 0316 059A 0062;0061 302A 085B 0316 059A 0062;0061 302A 085B 0316 059A 0062;0061 302A 085B 0316 059A 0062; # (a◌࡛◌֚◌̖◌〪b; a◌〪◌࡛◌̖◌֚b; a◌〪◌࡛◌̖◌֚b; a◌〪◌࡛◌̖◌֚b; a◌〪◌࡛◌̖◌֚b; ) LATIN SMALL LETTER A, MANDAIC GEMINATION MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 08D3 0062;0061 302A 0316 08D3 059A 0062;0061 302A 0316 08D3 059A 0062;0061 302A 0316 08D3 059A 0062;0061 302A 0316 08D3 059A 0062; # (a◌֚◌̖◌〪◌࣓b; a◌〪◌̖◌࣓◌֚b; a◌〪◌̖◌࣓◌֚b; a◌〪◌̖◌࣓◌֚b; a◌〪◌̖◌࣓◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC SMALL LOW WAW, LATIN SMALL LETTER B
-0061 08D3 059A 0316 302A 0062;0061 302A 08D3 0316 059A 0062;0061 302A 08D3 0316 059A 0062;0061 302A 08D3 0316 059A 0062;0061 302A 08D3 0316 059A 0062; # (a◌࣓◌֚◌̖◌〪b; a◌〪◌࣓◌̖◌֚b; a◌〪◌࣓◌̖◌֚b; a◌〪◌࣓◌̖◌֚b; a◌〪◌࣓◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SMALL LOW WAW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0859 0062;0061 1DFA 0316 0859 059A 0062;0061 1DFA 0316 0859 059A 0062;0061 1DFA 0316 0859 059A 0062;0061 1DFA 0316 0859 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, MANDAIC AFFRICATION MARK, LATIN SMALL LETTER B
+0061 0859 059A 0316 1DFA 0062;0061 1DFA 0859 0316 059A 0062;0061 1DFA 0859 0316 059A 0062;0061 1DFA 0859 0316 059A 0062;0061 1DFA 0859 0316 059A 0062; # (a◌࡙◌֚◌̖◌᷺b; a◌᷺◌࡙◌̖◌֚b; a◌᷺◌࡙◌̖◌֚b; a◌᷺◌࡙◌̖◌֚b; a◌᷺◌࡙◌̖◌֚b; ) LATIN SMALL LETTER A, MANDAIC AFFRICATION MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 085A 0062;0061 1DFA 0316 085A 059A 0062;0061 1DFA 0316 085A 059A 0062;0061 1DFA 0316 085A 059A 0062;0061 1DFA 0316 085A 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, MANDAIC VOCALIZATION MARK, LATIN SMALL LETTER B
+0061 085A 059A 0316 1DFA 0062;0061 1DFA 085A 0316 059A 0062;0061 1DFA 085A 0316 059A 0062;0061 1DFA 085A 0316 059A 0062;0061 1DFA 085A 0316 059A 0062; # (a◌࡚◌֚◌̖◌᷺b; a◌᷺◌࡚◌̖◌֚b; a◌᷺◌࡚◌̖◌֚b; a◌᷺◌࡚◌̖◌֚b; a◌᷺◌࡚◌̖◌֚b; ) LATIN SMALL LETTER A, MANDAIC VOCALIZATION MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 085B 0062;0061 1DFA 0316 085B 059A 0062;0061 1DFA 0316 085B 059A 0062;0061 1DFA 0316 085B 059A 0062;0061 1DFA 0316 085B 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, MANDAIC GEMINATION MARK, LATIN SMALL LETTER B
+0061 085B 059A 0316 1DFA 0062;0061 1DFA 085B 0316 059A 0062;0061 1DFA 085B 0316 059A 0062;0061 1DFA 085B 0316 059A 0062;0061 1DFA 085B 0316 059A 0062; # (a◌࡛◌֚◌̖◌᷺b; a◌᷺◌࡛◌̖◌֚b; a◌᷺◌࡛◌̖◌֚b; a◌᷺◌࡛◌̖◌֚b; a◌᷺◌࡛◌̖◌֚b; ) LATIN SMALL LETTER A, MANDAIC GEMINATION MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0898 0062;00E0 05AE 0898 0315 0062;0061 05AE 0300 0898 0315 0062;00E0 05AE 0898 0315 0062;0061 05AE 0300 0898 0315 0062; # (a◌̕◌̀◌֮◌࢘b; à◌֮◌࢘◌̕b; a◌֮◌̀◌࢘◌̕b; à◌֮◌࢘◌̕b; a◌֮◌̀◌࢘◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH WORD AL-JUZ, LATIN SMALL LETTER B
+0061 0898 0315 0300 05AE 0062;0061 05AE 0898 0300 0315 0062;0061 05AE 0898 0300 0315 0062;0061 05AE 0898 0300 0315 0062;0061 05AE 0898 0300 0315 0062; # (a◌࢘◌̕◌̀◌֮b; a◌֮◌࢘◌̀◌̕b; a◌֮◌࢘◌̀◌̕b; a◌֮◌࢘◌̀◌̕b; a◌֮◌࢘◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH WORD AL-JUZ, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0899 0062;0061 1DFA 0316 0899 059A 0062;0061 1DFA 0316 0899 059A 0062;0061 1DFA 0316 0899 059A 0062;0061 1DFA 0316 0899 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 ISHMAAM, LATIN SMALL LETTER B
+0061 0899 059A 0316 1DFA 0062;0061 1DFA 0899 0316 059A 0062;0061 1DFA 0899 0316 059A 0062;0061 1DFA 0899 0316 059A 0062;0061 1DFA 0899 0316 059A 0062; # (a◌࢙◌֚◌̖◌᷺b; a◌᷺◌࢙◌̖◌֚b; a◌᷺◌࢙◌̖◌֚b; a◌᷺◌࢙◌̖◌֚b; a◌᷺◌࢙◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SMALL LOW WORD ISHMAAM, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 089A 0062;0061 1DFA 0316 089A 059A 0062;0061 1DFA 0316 089A 059A 0062;0061 1DFA 0316 089A 059A 0062;0061 1DFA 0316 089A 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 IMAALA, LATIN SMALL LETTER B
+0061 089A 059A 0316 1DFA 0062;0061 1DFA 089A 0316 059A 0062;0061 1DFA 089A 0316 059A 0062;0061 1DFA 089A 0316 059A 0062;0061 1DFA 089A 0316 059A 0062; # (a◌࢚◌֚◌̖◌᷺b; a◌᷺◌࢚◌̖◌֚b; a◌᷺◌࢚◌̖◌֚b; a◌᷺◌࢚◌̖◌֚b; a◌᷺◌࢚◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SMALL LOW WORD IMAALA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 089B 0062;0061 1DFA 0316 089B 059A 0062;0061 1DFA 0316 089B 059A 0062;0061 1DFA 0316 089B 059A 0062;0061 1DFA 0316 089B 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 TASHEEL, LATIN SMALL LETTER B
+0061 089B 059A 0316 1DFA 0062;0061 1DFA 089B 0316 059A 0062;0061 1DFA 089B 0316 059A 0062;0061 1DFA 089B 0316 059A 0062;0061 1DFA 089B 0316 059A 0062; # (a◌࢛◌֚◌̖◌᷺b; a◌᷺◌࢛◌̖◌֚b; a◌᷺◌࢛◌̖◌֚b; a◌᷺◌࢛◌̖◌֚b; a◌᷺◌࢛◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SMALL LOW WORD TASHEEL, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 0315 0300 05AE 089C 0062;00E0 05AE 089C 0315 0062;0061 05AE 0300 089C 0315 0062;00E0 05AE 089C 0315 0062;0061 05AE 0300 089C 0315 0062; # (a◌̕◌̀◌֮◌࢜b; à◌֮◌࢜◌̕b; a◌֮◌̀◌࢜◌̕b; à◌֮◌࢜◌̕b; a◌֮◌̀◌࢜◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC MADDA WAAJIB, LATIN SMALL LETTER B
+0061 089C 0315 0300 05AE 0062;0061 05AE 089C 0300 0315 0062;0061 05AE 089C 0300 0315 0062;0061 05AE 089C 0300 0315 0062;0061 05AE 089C 0300 0315 0062; # (a◌࢜◌̕◌̀◌֮b; a◌֮◌࢜◌̀◌̕b; a◌֮◌࢜◌̀◌̕b; a◌֮◌࢜◌̀◌̕b; a◌֮◌࢜◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC MADDA WAAJIB, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 089D 0062;00E0 05AE 089D 0315 0062;0061 05AE 0300 089D 0315 0062;00E0 05AE 089D 0315 0062;0061 05AE 0300 089D 0315 0062; # (a◌̕◌̀◌֮◌࢝b; à◌֮◌࢝◌̕b; a◌֮◌̀◌࢝◌̕b; à◌֮◌࢝◌̕b; a◌֮◌̀◌࢝◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SUPERSCRIPT ALEF MOKHASSAS, LATIN SMALL LETTER B
+0061 089D 0315 0300 05AE 0062;0061 05AE 089D 0300 0315 0062;0061 05AE 089D 0300 0315 0062;0061 05AE 089D 0300 0315 0062;0061 05AE 089D 0300 0315 0062; # (a◌࢝◌̕◌̀◌֮b; a◌֮◌࢝◌̀◌̕b; a◌֮◌࢝◌̀◌̕b; a◌֮◌࢝◌̀◌̕b; a◌֮◌࢝◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SUPERSCRIPT ALEF MOKHASSAS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 089E 0062;00E0 05AE 089E 0315 0062;0061 05AE 0300 089E 0315 0062;00E0 05AE 089E 0315 0062;0061 05AE 0300 089E 0315 0062; # (a◌̕◌̀◌֮◌࢞b; à◌֮◌࢞◌̕b; a◌֮◌̀◌࢞◌̕b; à◌֮◌࢞◌̕b; a◌֮◌̀◌࢞◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC DOUBLED MADDA, LATIN SMALL LETTER B
+0061 089E 0315 0300 05AE 0062;0061 05AE 089E 0300 0315 0062;0061 05AE 089E 0300 0315 0062;0061 05AE 089E 0300 0315 0062;0061 05AE 089E 0300 0315 0062; # (a◌࢞◌̕◌̀◌֮b; a◌֮◌࢞◌̀◌̕b; a◌֮◌࢞◌̀◌̕b; a◌֮◌࢞◌̀◌̕b; a◌֮◌࢞◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC DOUBLED MADDA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 089F 0062;00E0 05AE 089F 0315 0062;0061 05AE 0300 089F 0315 0062;00E0 05AE 089F 0315 0062;0061 05AE 0300 089F 0315 0062; # (a◌̕◌̀◌֮◌࢟b; à◌֮◌࢟◌̕b; a◌֮◌̀◌࢟◌̕b; à◌֮◌࢟◌̕b; a◌֮◌̀◌࢟◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC HALF MADDA OVER MADDA, LATIN SMALL LETTER B
+0061 089F 0315 0300 05AE 0062;0061 05AE 089F 0300 0315 0062;0061 05AE 089F 0300 0315 0062;0061 05AE 089F 0300 0315 0062;0061 05AE 089F 0300 0315 0062; # (a◌࢟◌̕◌̀◌֮b; a◌֮◌࢟◌̀◌̕b; a◌֮◌࢟◌̀◌̕b; a◌֮◌࢟◌̀◌̕b; a◌֮◌࢟◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC HALF MADDA OVER MADDA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08CA 0062;00E0 05AE 08CA 0315 0062;0061 05AE 0300 08CA 0315 0062;00E0 05AE 08CA 0315 0062;0061 05AE 0300 08CA 0315 0062; # (a◌̕◌̀◌֮◌࣊b; à◌֮◌࣊◌̕b; a◌֮◌̀◌࣊◌̕b; à◌֮◌࣊◌̕b; a◌֮◌̀◌࣊◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH FARSI YEH, LATIN SMALL LETTER B
+0061 08CA 0315 0300 05AE 0062;0061 05AE 08CA 0300 0315 0062;0061 05AE 08CA 0300 0315 0062;0061 05AE 08CA 0300 0315 0062;0061 05AE 08CA 0300 0315 0062; # (a◌࣊◌̕◌̀◌֮b; a◌֮◌࣊◌̀◌̕b; a◌֮◌࣊◌̀◌̕b; a◌֮◌࣊◌̀◌̕b; a◌֮◌࣊◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH FARSI YEH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08CB 0062;00E0 05AE 08CB 0315 0062;0061 05AE 0300 08CB 0315 0062;00E0 05AE 08CB 0315 0062;0061 05AE 0300 08CB 0315 0062; # (a◌̕◌̀◌֮◌࣋b; à◌֮◌࣋◌̕b; a◌֮◌̀◌࣋◌̕b; à◌֮◌࣋◌̕b; a◌֮◌̀◌࣋◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH YEH BARREE WITH TWO DOTS BELOW, LATIN SMALL LETTER B
+0061 08CB 0315 0300 05AE 0062;0061 05AE 08CB 0300 0315 0062;0061 05AE 08CB 0300 0315 0062;0061 05AE 08CB 0300 0315 0062;0061 05AE 08CB 0300 0315 0062; # (a◌࣋◌̕◌̀◌֮b; a◌֮◌࣋◌̀◌̕b; a◌֮◌࣋◌̀◌̕b; a◌֮◌࣋◌̀◌̕b; a◌֮◌࣋◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH YEH BARREE WITH TWO DOTS BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08CC 0062;00E0 05AE 08CC 0315 0062;0061 05AE 0300 08CC 0315 0062;00E0 05AE 08CC 0315 0062;0061 05AE 0300 08CC 0315 0062; # (a◌̕◌̀◌֮◌࣌b; à◌֮◌࣌◌̕b; a◌֮◌̀◌࣌◌̕b; à◌֮◌࣌◌̕b; a◌֮◌̀◌࣌◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH WORD SAH, LATIN SMALL LETTER B
+0061 08CC 0315 0300 05AE 0062;0061 05AE 08CC 0300 0315 0062;0061 05AE 08CC 0300 0315 0062;0061 05AE 08CC 0300 0315 0062;0061 05AE 08CC 0300 0315 0062; # (a◌࣌◌̕◌̀◌֮b; a◌֮◌࣌◌̀◌̕b; a◌֮◌࣌◌̀◌̕b; a◌֮◌࣌◌̀◌̕b; a◌֮◌࣌◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH WORD SAH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08CD 0062;00E0 05AE 08CD 0315 0062;0061 05AE 0300 08CD 0315 0062;00E0 05AE 08CD 0315 0062;0061 05AE 0300 08CD 0315 0062; # (a◌̕◌̀◌֮◌࣍b; à◌֮◌࣍◌̕b; a◌֮◌̀◌࣍◌̕b; à◌֮◌࣍◌̕b; a◌֮◌̀◌࣍◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH ZAH, LATIN SMALL LETTER B
+0061 08CD 0315 0300 05AE 0062;0061 05AE 08CD 0300 0315 0062;0061 05AE 08CD 0300 0315 0062;0061 05AE 08CD 0300 0315 0062;0061 05AE 08CD 0300 0315 0062; # (a◌࣍◌̕◌̀◌֮b; a◌֮◌࣍◌̀◌̕b; a◌֮◌࣍◌̀◌̕b; a◌֮◌࣍◌̀◌̕b; a◌֮◌࣍◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH ZAH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08CE 0062;00E0 05AE 08CE 0315 0062;0061 05AE 0300 08CE 0315 0062;00E0 05AE 08CE 0315 0062;0061 05AE 0300 08CE 0315 0062; # (a◌̕◌̀◌֮◌࣎b; à◌֮◌࣎◌̕b; a◌֮◌̀◌࣎◌̕b; à◌֮◌࣎◌̕b; a◌֮◌̀◌࣎◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC LARGE ROUND DOT ABOVE, LATIN SMALL LETTER B
+0061 08CE 0315 0300 05AE 0062;0061 05AE 08CE 0300 0315 0062;0061 05AE 08CE 0300 0315 0062;0061 05AE 08CE 0300 0315 0062;0061 05AE 08CE 0300 0315 0062; # (a◌࣎◌̕◌̀◌֮b; a◌֮◌࣎◌̀◌̕b; a◌֮◌࣎◌̀◌̕b; a◌֮◌࣎◌̀◌̕b; a◌֮◌࣎◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC LARGE ROUND DOT ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 08CF 0062;0061 1DFA 0316 08CF 059A 0062;0061 1DFA 0316 08CF 059A 0062;0061 1DFA 0316 08CF 059A 0062;0061 1DFA 0316 08CF 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 LARGE ROUND DOT BELOW, LATIN SMALL LETTER B
+0061 08CF 059A 0316 1DFA 0062;0061 1DFA 08CF 0316 059A 0062;0061 1DFA 08CF 0316 059A 0062;0061 1DFA 08CF 0316 059A 0062;0061 1DFA 08CF 0316 059A 0062; # (a◌࣏◌֚◌̖◌᷺b; a◌᷺◌࣏◌̖◌֚b; a◌᷺◌࣏◌̖◌֚b; a◌᷺◌࣏◌̖◌֚b; a◌᷺◌࣏◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC LARGE ROUND DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 08D0 0062;0061 1DFA 0316 08D0 059A 0062;0061 1DFA 0316 08D0 059A 0062;0061 1DFA 0316 08D0 059A 0062;0061 1DFA 0316 08D0 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 SUKUN BELOW, LATIN SMALL LETTER B
+0061 08D0 059A 0316 1DFA 0062;0061 1DFA 08D0 0316 059A 0062;0061 1DFA 08D0 0316 059A 0062;0061 1DFA 08D0 0316 059A 0062;0061 1DFA 08D0 0316 059A 0062; # (a◌࣐◌֚◌̖◌᷺b; a◌᷺◌࣐◌̖◌֚b; a◌᷺◌࣐◌̖◌֚b; a◌᷺◌࣐◌̖◌֚b; a◌᷺◌࣐◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SUKUN BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 08D1 0062;0061 1DFA 0316 08D1 059A 0062;0061 1DFA 0316 08D1 059A 0062;0061 1DFA 0316 08D1 059A 0062;0061 1DFA 0316 08D1 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 LARGE CIRCLE BELOW, LATIN SMALL LETTER B
+0061 08D1 059A 0316 1DFA 0062;0061 1DFA 08D1 0316 059A 0062;0061 1DFA 08D1 0316 059A 0062;0061 1DFA 08D1 0316 059A 0062;0061 1DFA 08D1 0316 059A 0062; # (a◌࣑◌֚◌̖◌᷺b; a◌᷺◌࣑◌̖◌֚b; a◌᷺◌࣑◌̖◌֚b; a◌᷺◌࣑◌̖◌֚b; a◌᷺◌࣑◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC LARGE CIRCLE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 08D2 0062;0061 1DFA 0316 08D2 059A 0062;0061 1DFA 0316 08D2 059A 0062;0061 1DFA 0316 08D2 059A 0062;0061 1DFA 0316 08D2 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 LARGE ROUND DOT INSIDE CIRCLE BELOW, LATIN SMALL LETTER B
+0061 08D2 059A 0316 1DFA 0062;0061 1DFA 08D2 0316 059A 0062;0061 1DFA 08D2 0316 059A 0062;0061 1DFA 08D2 0316 059A 0062;0061 1DFA 08D2 0316 059A 0062; # (a◌࣒◌֚◌̖◌᷺b; a◌᷺◌࣒◌̖◌֚b; a◌᷺◌࣒◌̖◌֚b; a◌᷺◌࣒◌̖◌֚b; a◌᷺◌࣒◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC LARGE ROUND DOT INSIDE CIRCLE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 08D3 0062;0061 1DFA 0316 08D3 059A 0062;0061 1DFA 0316 08D3 059A 0062;0061 1DFA 0316 08D3 059A 0062;0061 1DFA 0316 08D3 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 WAW, LATIN SMALL LETTER B
+0061 08D3 059A 0316 1DFA 0062;0061 1DFA 08D3 0316 059A 0062;0061 1DFA 08D3 0316 059A 0062;0061 1DFA 08D3 0316 059A 0062;0061 1DFA 08D3 0316 059A 0062; # (a◌࣓◌֚◌̖◌᷺b; a◌᷺◌࣓◌̖◌֚b; a◌᷺◌࣓◌̖◌֚b; a◌᷺◌࣓◌̖◌֚b; a◌᷺◌࣓◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SMALL LOW WAW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 08D4 0062;00E0 05AE 08D4 0315 0062;0061 05AE 0300 08D4 0315 0062;00E0 05AE 08D4 0315 0062;0061 05AE 0300 08D4 0315 0062; # (a◌̕◌̀◌֮◌ࣔb; à◌֮◌ࣔ◌̕b; a◌֮◌̀◌ࣔ◌̕b; à◌֮◌ࣔ◌̕b; a◌֮◌̀◌ࣔ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH WORD AR-RUB, LATIN SMALL LETTER B
0061 08D4 0315 0300 05AE 0062;0061 05AE 08D4 0300 0315 0062;0061 05AE 08D4 0300 0315 0062;0061 05AE 08D4 0300 0315 0062;0061 05AE 08D4 0300 0315 0062; # (a◌ࣔ◌̕◌̀◌֮b; a◌֮◌ࣔ◌̀◌̕b; a◌֮◌ࣔ◌̀◌̕b; a◌֮◌ࣔ◌̀◌̕b; a◌֮◌ࣔ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH WORD AR-RUB, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 08D5 0062;00E0 05AE 08D5 0315 0062;0061 05AE 0300 08D5 0315 0062;00E0 05AE 08D5 0315 0062;0061 05AE 0300 08D5 0315 0062; # (a◌̕◌̀◌֮◌ࣕb; à◌֮◌ࣕ◌̕b; a◌֮◌̀◌ࣕ◌̕b; à◌֮◌ࣕ◌̕b; a◌֮◌̀◌ࣕ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH SAD, LATIN SMALL LETTER B
@@ -17573,32 +17666,32 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 08E0 0315 0300 05AE 0062;0061 05AE 08E0 0300 0315 0062;0061 05AE 08E0 0300 0315 0062;0061 05AE 08E0 0300 0315 0062;0061 05AE 08E0 0300 0315 0062; # (a◌࣠◌̕◌̀◌֮b; a◌֮◌࣠◌̀◌̕b; a◌֮◌࣠◌̀◌̕b; a◌֮◌࣠◌̀◌̕b; a◌֮◌࣠◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH FOOTNOTE MARKER, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 08E1 0062;00E0 05AE 08E1 0315 0062;0061 05AE 0300 08E1 0315 0062;00E0 05AE 08E1 0315 0062;0061 05AE 0300 08E1 0315 0062; # (a◌̕◌̀◌֮◌࣡b; à◌֮◌࣡◌̕b; a◌֮◌̀◌࣡◌̕b; à◌֮◌࣡◌̕b; a◌֮◌̀◌࣡◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH SIGN SAFHA, LATIN SMALL LETTER B
0061 08E1 0315 0300 05AE 0062;0061 05AE 08E1 0300 0315 0062;0061 05AE 08E1 0300 0315 0062;0061 05AE 08E1 0300 0315 0062;0061 05AE 08E1 0300 0315 0062; # (a◌࣡◌̕◌̀◌֮b; a◌֮◌࣡◌̀◌̕b; a◌֮◌࣡◌̀◌̕b; a◌֮◌࣡◌̀◌̕b; a◌֮◌࣡◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH SIGN SAFHA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 08E3 0062;0061 302A 0316 08E3 059A 0062;0061 302A 0316 08E3 059A 0062;0061 302A 0316 08E3 059A 0062;0061 302A 0316 08E3 059A 0062; # (a◌֚◌̖◌〪◌ࣣb; a◌〪◌̖◌ࣣ◌֚b; a◌〪◌̖◌ࣣ◌֚b; a◌〪◌̖◌ࣣ◌֚b; a◌〪◌̖◌ࣣ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC TURNED DAMMA BELOW, LATIN SMALL LETTER B
-0061 08E3 059A 0316 302A 0062;0061 302A 08E3 0316 059A 0062;0061 302A 08E3 0316 059A 0062;0061 302A 08E3 0316 059A 0062;0061 302A 08E3 0316 059A 0062; # (a◌ࣣ◌֚◌̖◌〪b; a◌〪◌ࣣ◌̖◌֚b; a◌〪◌ࣣ◌̖◌֚b; a◌〪◌ࣣ◌̖◌֚b; a◌〪◌ࣣ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC TURNED DAMMA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 08E3 0062;0061 1DFA 0316 08E3 059A 0062;0061 1DFA 0316 08E3 059A 0062;0061 1DFA 0316 08E3 059A 0062;0061 1DFA 0316 08E3 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 TURNED DAMMA BELOW, LATIN SMALL LETTER B
+0061 08E3 059A 0316 1DFA 0062;0061 1DFA 08E3 0316 059A 0062;0061 1DFA 08E3 0316 059A 0062;0061 1DFA 08E3 0316 059A 0062;0061 1DFA 08E3 0316 059A 0062; # (a◌ࣣ◌֚◌̖◌᷺b; a◌᷺◌ࣣ◌̖◌֚b; a◌᷺◌ࣣ◌̖◌֚b; a◌᷺◌ࣣ◌̖◌֚b; a◌᷺◌ࣣ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC TURNED DAMMA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 08E4 0062;00E0 05AE 08E4 0315 0062;0061 05AE 0300 08E4 0315 0062;00E0 05AE 08E4 0315 0062;0061 05AE 0300 08E4 0315 0062; # (a◌̕◌̀◌֮◌ࣤb; à◌֮◌ࣤ◌̕b; a◌֮◌̀◌ࣤ◌̕b; à◌֮◌ࣤ◌̕b; a◌֮◌̀◌ࣤ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC CURLY FATHA, LATIN SMALL LETTER B
0061 08E4 0315 0300 05AE 0062;0061 05AE 08E4 0300 0315 0062;0061 05AE 08E4 0300 0315 0062;0061 05AE 08E4 0300 0315 0062;0061 05AE 08E4 0300 0315 0062; # (a◌ࣤ◌̕◌̀◌֮b; a◌֮◌ࣤ◌̀◌̕b; a◌֮◌ࣤ◌̀◌̕b; a◌֮◌ࣤ◌̀◌̕b; a◌֮◌ࣤ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC CURLY FATHA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 08E5 0062;00E0 05AE 08E5 0315 0062;0061 05AE 0300 08E5 0315 0062;00E0 05AE 08E5 0315 0062;0061 05AE 0300 08E5 0315 0062; # (a◌̕◌̀◌֮◌ࣥb; à◌֮◌ࣥ◌̕b; a◌֮◌̀◌ࣥ◌̕b; à◌֮◌ࣥ◌̕b; a◌֮◌̀◌ࣥ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC CURLY DAMMA, LATIN SMALL LETTER B
0061 08E5 0315 0300 05AE 0062;0061 05AE 08E5 0300 0315 0062;0061 05AE 08E5 0300 0315 0062;0061 05AE 08E5 0300 0315 0062;0061 05AE 08E5 0300 0315 0062; # (a◌ࣥ◌̕◌̀◌֮b; a◌֮◌ࣥ◌̀◌̕b; a◌֮◌ࣥ◌̀◌̕b; a◌֮◌ࣥ◌̀◌̕b; a◌֮◌ࣥ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC CURLY DAMMA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 08E6 0062;0061 302A 0316 08E6 059A 0062;0061 302A 0316 08E6 059A 0062;0061 302A 0316 08E6 059A 0062;0061 302A 0316 08E6 059A 0062; # (a◌֚◌̖◌〪◌ࣦb; a◌〪◌̖◌ࣦ◌֚b; a◌〪◌̖◌ࣦ◌֚b; a◌〪◌̖◌ࣦ◌֚b; a◌〪◌̖◌ࣦ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC CURLY KASRA, LATIN SMALL LETTER B
-0061 08E6 059A 0316 302A 0062;0061 302A 08E6 0316 059A 0062;0061 302A 08E6 0316 059A 0062;0061 302A 08E6 0316 059A 0062;0061 302A 08E6 0316 059A 0062; # (a◌ࣦ◌֚◌̖◌〪b; a◌〪◌ࣦ◌̖◌֚b; a◌〪◌ࣦ◌̖◌֚b; a◌〪◌ࣦ◌̖◌֚b; a◌〪◌ࣦ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC CURLY KASRA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 08E6 0062;0061 1DFA 0316 08E6 059A 0062;0061 1DFA 0316 08E6 059A 0062;0061 1DFA 0316 08E6 059A 0062;0061 1DFA 0316 08E6 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 CURLY KASRA, LATIN SMALL LETTER B
+0061 08E6 059A 0316 1DFA 0062;0061 1DFA 08E6 0316 059A 0062;0061 1DFA 08E6 0316 059A 0062;0061 1DFA 08E6 0316 059A 0062;0061 1DFA 08E6 0316 059A 0062; # (a◌ࣦ◌֚◌̖◌᷺b; a◌᷺◌ࣦ◌̖◌֚b; a◌᷺◌ࣦ◌̖◌֚b; a◌᷺◌ࣦ◌̖◌֚b; a◌᷺◌ࣦ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC CURLY KASRA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 08E7 0062;00E0 05AE 08E7 0315 0062;0061 05AE 0300 08E7 0315 0062;00E0 05AE 08E7 0315 0062;0061 05AE 0300 08E7 0315 0062; # (a◌̕◌̀◌֮◌ࣧb; à◌֮◌ࣧ◌̕b; a◌֮◌̀◌ࣧ◌̕b; à◌֮◌ࣧ◌̕b; a◌֮◌̀◌ࣧ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC CURLY FATHATAN, LATIN SMALL LETTER B
0061 08E7 0315 0300 05AE 0062;0061 05AE 08E7 0300 0315 0062;0061 05AE 08E7 0300 0315 0062;0061 05AE 08E7 0300 0315 0062;0061 05AE 08E7 0300 0315 0062; # (a◌ࣧ◌̕◌̀◌֮b; a◌֮◌ࣧ◌̀◌̕b; a◌֮◌ࣧ◌̀◌̕b; a◌֮◌ࣧ◌̀◌̕b; a◌֮◌ࣧ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC CURLY FATHATAN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 08E8 0062;00E0 05AE 08E8 0315 0062;0061 05AE 0300 08E8 0315 0062;00E0 05AE 08E8 0315 0062;0061 05AE 0300 08E8 0315 0062; # (a◌̕◌̀◌֮◌ࣨb; à◌֮◌ࣨ◌̕b; a◌֮◌̀◌ࣨ◌̕b; à◌֮◌ࣨ◌̕b; a◌֮◌̀◌ࣨ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC CURLY DAMMATAN, LATIN SMALL LETTER B
0061 08E8 0315 0300 05AE 0062;0061 05AE 08E8 0300 0315 0062;0061 05AE 08E8 0300 0315 0062;0061 05AE 08E8 0300 0315 0062;0061 05AE 08E8 0300 0315 0062; # (a◌ࣨ◌̕◌̀◌֮b; a◌֮◌ࣨ◌̀◌̕b; a◌֮◌ࣨ◌̀◌̕b; a◌֮◌ࣨ◌̀◌̕b; a◌֮◌ࣨ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC CURLY DAMMATAN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 08E9 0062;0061 302A 0316 08E9 059A 0062;0061 302A 0316 08E9 059A 0062;0061 302A 0316 08E9 059A 0062;0061 302A 0316 08E9 059A 0062; # (a◌֚◌̖◌〪◌ࣩb; a◌〪◌̖◌ࣩ◌֚b; a◌〪◌̖◌ࣩ◌֚b; a◌〪◌̖◌ࣩ◌֚b; a◌〪◌̖◌ࣩ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC CURLY KASRATAN, LATIN SMALL LETTER B
-0061 08E9 059A 0316 302A 0062;0061 302A 08E9 0316 059A 0062;0061 302A 08E9 0316 059A 0062;0061 302A 08E9 0316 059A 0062;0061 302A 08E9 0316 059A 0062; # (a◌ࣩ◌֚◌̖◌〪b; a◌〪◌ࣩ◌̖◌֚b; a◌〪◌ࣩ◌̖◌֚b; a◌〪◌ࣩ◌̖◌֚b; a◌〪◌ࣩ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC CURLY KASRATAN, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 08E9 0062;0061 1DFA 0316 08E9 059A 0062;0061 1DFA 0316 08E9 059A 0062;0061 1DFA 0316 08E9 059A 0062;0061 1DFA 0316 08E9 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 CURLY KASRATAN, LATIN SMALL LETTER B
+0061 08E9 059A 0316 1DFA 0062;0061 1DFA 08E9 0316 059A 0062;0061 1DFA 08E9 0316 059A 0062;0061 1DFA 08E9 0316 059A 0062;0061 1DFA 08E9 0316 059A 0062; # (a◌ࣩ◌֚◌̖◌᷺b; a◌᷺◌ࣩ◌̖◌֚b; a◌᷺◌ࣩ◌̖◌֚b; a◌᷺◌ࣩ◌̖◌֚b; a◌᷺◌ࣩ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC CURLY KASRATAN, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 08EA 0062;00E0 05AE 08EA 0315 0062;0061 05AE 0300 08EA 0315 0062;00E0 05AE 08EA 0315 0062;0061 05AE 0300 08EA 0315 0062; # (a◌̕◌̀◌֮◌࣪b; à◌֮◌࣪◌̕b; a◌֮◌̀◌࣪◌̕b; à◌֮◌࣪◌̕b; a◌֮◌̀◌࣪◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC TONE ONE DOT ABOVE, LATIN SMALL LETTER B
0061 08EA 0315 0300 05AE 0062;0061 05AE 08EA 0300 0315 0062;0061 05AE 08EA 0300 0315 0062;0061 05AE 08EA 0300 0315 0062;0061 05AE 08EA 0300 0315 0062; # (a◌࣪◌̕◌̀◌֮b; a◌֮◌࣪◌̀◌̕b; a◌֮◌࣪◌̀◌̕b; a◌֮◌࣪◌̀◌̕b; a◌֮◌࣪◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC TONE ONE DOT ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 08EB 0062;00E0 05AE 08EB 0315 0062;0061 05AE 0300 08EB 0315 0062;00E0 05AE 08EB 0315 0062;0061 05AE 0300 08EB 0315 0062; # (a◌̕◌̀◌֮◌࣫b; à◌֮◌࣫◌̕b; a◌֮◌̀◌࣫◌̕b; à◌֮◌࣫◌̕b; a◌֮◌̀◌࣫◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC TONE TWO DOTS ABOVE, LATIN SMALL LETTER B
0061 08EB 0315 0300 05AE 0062;0061 05AE 08EB 0300 0315 0062;0061 05AE 08EB 0300 0315 0062;0061 05AE 08EB 0300 0315 0062;0061 05AE 08EB 0300 0315 0062; # (a◌࣫◌̕◌̀◌֮b; a◌֮◌࣫◌̀◌̕b; a◌֮◌࣫◌̀◌̕b; a◌֮◌࣫◌̀◌̕b; a◌֮◌࣫◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC TONE TWO DOTS ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 08EC 0062;00E0 05AE 08EC 0315 0062;0061 05AE 0300 08EC 0315 0062;00E0 05AE 08EC 0315 0062;0061 05AE 0300 08EC 0315 0062; # (a◌̕◌̀◌֮◌࣬b; à◌֮◌࣬◌̕b; a◌֮◌̀◌࣬◌̕b; à◌֮◌࣬◌̕b; a◌֮◌̀◌࣬◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC TONE LOOP ABOVE, LATIN SMALL LETTER B
0061 08EC 0315 0300 05AE 0062;0061 05AE 08EC 0300 0315 0062;0061 05AE 08EC 0300 0315 0062;0061 05AE 08EC 0300 0315 0062;0061 05AE 08EC 0300 0315 0062; # (a◌࣬◌̕◌̀◌֮b; a◌֮◌࣬◌̀◌̕b; a◌֮◌࣬◌̀◌̕b; a◌֮◌࣬◌̀◌̕b; a◌֮◌࣬◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC TONE LOOP ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 08ED 0062;0061 302A 0316 08ED 059A 0062;0061 302A 0316 08ED 059A 0062;0061 302A 0316 08ED 059A 0062;0061 302A 0316 08ED 059A 0062; # (a◌֚◌̖◌〪◌࣭b; a◌〪◌̖◌࣭◌֚b; a◌〪◌̖◌࣭◌֚b; a◌〪◌̖◌࣭◌֚b; a◌〪◌̖◌࣭◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC TONE ONE DOT BELOW, LATIN SMALL LETTER B
-0061 08ED 059A 0316 302A 0062;0061 302A 08ED 0316 059A 0062;0061 302A 08ED 0316 059A 0062;0061 302A 08ED 0316 059A 0062;0061 302A 08ED 0316 059A 0062; # (a◌࣭◌֚◌̖◌〪b; a◌〪◌࣭◌̖◌֚b; a◌〪◌࣭◌̖◌֚b; a◌〪◌࣭◌̖◌֚b; a◌〪◌࣭◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC TONE ONE DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 08EE 0062;0061 302A 0316 08EE 059A 0062;0061 302A 0316 08EE 059A 0062;0061 302A 0316 08EE 059A 0062;0061 302A 0316 08EE 059A 0062; # (a◌֚◌̖◌〪◌࣮b; a◌〪◌̖◌࣮◌֚b; a◌〪◌̖◌࣮◌֚b; a◌〪◌̖◌࣮◌֚b; a◌〪◌̖◌࣮◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC TONE TWO DOTS BELOW, LATIN SMALL LETTER B
-0061 08EE 059A 0316 302A 0062;0061 302A 08EE 0316 059A 0062;0061 302A 08EE 0316 059A 0062;0061 302A 08EE 0316 059A 0062;0061 302A 08EE 0316 059A 0062; # (a◌࣮◌֚◌̖◌〪b; a◌〪◌࣮◌̖◌֚b; a◌〪◌࣮◌̖◌֚b; a◌〪◌࣮◌̖◌֚b; a◌〪◌࣮◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC TONE TWO DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 08EF 0062;0061 302A 0316 08EF 059A 0062;0061 302A 0316 08EF 059A 0062;0061 302A 0316 08EF 059A 0062;0061 302A 0316 08EF 059A 0062; # (a◌֚◌̖◌〪◌࣯b; a◌〪◌̖◌࣯◌֚b; a◌〪◌̖◌࣯◌֚b; a◌〪◌̖◌࣯◌֚b; a◌〪◌̖◌࣯◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC TONE LOOP BELOW, LATIN SMALL LETTER B
-0061 08EF 059A 0316 302A 0062;0061 302A 08EF 0316 059A 0062;0061 302A 08EF 0316 059A 0062;0061 302A 08EF 0316 059A 0062;0061 302A 08EF 0316 059A 0062; # (a◌࣯◌֚◌̖◌〪b; a◌〪◌࣯◌̖◌֚b; a◌〪◌࣯◌̖◌֚b; a◌〪◌࣯◌̖◌֚b; a◌〪◌࣯◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC TONE LOOP BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 08ED 0062;0061 1DFA 0316 08ED 059A 0062;0061 1DFA 0316 08ED 059A 0062;0061 1DFA 0316 08ED 059A 0062;0061 1DFA 0316 08ED 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 TONE ONE DOT BELOW, LATIN SMALL LETTER B
+0061 08ED 059A 0316 1DFA 0062;0061 1DFA 08ED 0316 059A 0062;0061 1DFA 08ED 0316 059A 0062;0061 1DFA 08ED 0316 059A 0062;0061 1DFA 08ED 0316 059A 0062; # (a◌࣭◌֚◌̖◌᷺b; a◌᷺◌࣭◌̖◌֚b; a◌᷺◌࣭◌̖◌֚b; a◌᷺◌࣭◌̖◌֚b; a◌᷺◌࣭◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC TONE ONE DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 08EE 0062;0061 1DFA 0316 08EE 059A 0062;0061 1DFA 0316 08EE 059A 0062;0061 1DFA 0316 08EE 059A 0062;0061 1DFA 0316 08EE 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 TONE TWO DOTS BELOW, LATIN SMALL LETTER B
+0061 08EE 059A 0316 1DFA 0062;0061 1DFA 08EE 0316 059A 0062;0061 1DFA 08EE 0316 059A 0062;0061 1DFA 08EE 0316 059A 0062;0061 1DFA 08EE 0316 059A 0062; # (a◌࣮◌֚◌̖◌᷺b; a◌᷺◌࣮◌̖◌֚b; a◌᷺◌࣮◌̖◌֚b; a◌᷺◌࣮◌̖◌֚b; a◌᷺◌࣮◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC TONE TWO DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 08EF 0062;0061 1DFA 0316 08EF 059A 0062;0061 1DFA 0316 08EF 059A 0062;0061 1DFA 0316 08EF 059A 0062;0061 1DFA 0316 08EF 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 TONE LOOP BELOW, LATIN SMALL LETTER B
+0061 08EF 059A 0316 1DFA 0062;0061 1DFA 08EF 0316 059A 0062;0061 1DFA 08EF 0316 059A 0062;0061 1DFA 08EF 0316 059A 0062;0061 1DFA 08EF 0316 059A 0062; # (a◌࣯◌֚◌̖◌᷺b; a◌᷺◌࣯◌̖◌֚b; a◌᷺◌࣯◌̖◌֚b; a◌᷺◌࣯◌̖◌֚b; a◌᷺◌࣯◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC TONE LOOP BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 064C 064B FB1E 08F0 0062;0061 FB1E 064B 08F0 064C 0062;0061 FB1E 064B 08F0 064C 0062;0061 FB1E 064B 08F0 064C 0062;0061 FB1E 064B 08F0 064C 0062; # (a◌ٌ◌ً◌ﬞ◌ࣰb; a◌ﬞ◌ً◌ࣰ◌ٌb; a◌ﬞ◌ً◌ࣰ◌ٌb; a◌ﬞ◌ً◌ࣰ◌ٌb; a◌ﬞ◌ً◌ࣰ◌ٌb; ) LATIN SMALL LETTER A, ARABIC DAMMATAN, ARABIC FATHATAN, HEBREW POINT JUDEO-SPANISH VARIKA, ARABIC OPEN FATHATAN, LATIN SMALL LETTER B
0061 08F0 064C 064B FB1E 0062;0061 FB1E 08F0 064B 064C 0062;0061 FB1E 08F0 064B 064C 0062;0061 FB1E 08F0 064B 064C 0062;0061 FB1E 08F0 064B 064C 0062; # (a◌ࣰ◌ٌ◌ً◌ﬞb; a◌ﬞ◌ࣰ◌ً◌ٌb; a◌ﬞ◌ࣰ◌ً◌ٌb; a◌ﬞ◌ࣰ◌ً◌ٌb; a◌ﬞ◌ࣰ◌ً◌ٌb; ) LATIN SMALL LETTER A, ARABIC OPEN FATHATAN, ARABIC DAMMATAN, ARABIC FATHATAN, HEBREW POINT JUDEO-SPANISH VARIKA, LATIN SMALL LETTER B
0061 064D 064C 064B 08F1 0062;0061 064B 064C 08F1 064D 0062;0061 064B 064C 08F1 064D 0062;0061 064B 064C 08F1 064D 0062;0061 064B 064C 08F1 064D 0062; # (a◌ٍ◌ٌ◌ً◌ࣱb; a◌ً◌ٌ◌ࣱ◌ٍb; a◌ً◌ٌ◌ࣱ◌ٍb; a◌ً◌ٌ◌ࣱ◌ٍb; a◌ً◌ٌ◌ࣱ◌ٍb; ) LATIN SMALL LETTER A, ARABIC KASRATAN, ARABIC DAMMATAN, ARABIC FATHATAN, ARABIC OPEN DAMMATAN, LATIN SMALL LETTER B
@@ -17611,16 +17704,16 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 08F4 0315 0300 05AE 0062;0061 05AE 08F4 0300 0315 0062;0061 05AE 08F4 0300 0315 0062;0061 05AE 08F4 0300 0315 0062;0061 05AE 08F4 0300 0315 0062; # (a◌ࣴ◌̕◌̀◌֮b; a◌֮◌ࣴ◌̀◌̕b; a◌֮◌ࣴ◌̀◌̕b; a◌֮◌ࣴ◌̀◌̕b; a◌֮◌ࣴ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC FATHA WITH RING, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 08F5 0062;00E0 05AE 08F5 0315 0062;0061 05AE 0300 08F5 0315 0062;00E0 05AE 08F5 0315 0062;0061 05AE 0300 08F5 0315 0062; # (a◌̕◌̀◌֮◌ࣵb; à◌֮◌ࣵ◌̕b; a◌֮◌̀◌ࣵ◌̕b; à◌֮◌ࣵ◌̕b; a◌֮◌̀◌ࣵ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC FATHA WITH DOT ABOVE, LATIN SMALL LETTER B
0061 08F5 0315 0300 05AE 0062;0061 05AE 08F5 0300 0315 0062;0061 05AE 08F5 0300 0315 0062;0061 05AE 08F5 0300 0315 0062;0061 05AE 08F5 0300 0315 0062; # (a◌ࣵ◌̕◌̀◌֮b; a◌֮◌ࣵ◌̀◌̕b; a◌֮◌ࣵ◌̀◌̕b; a◌֮◌ࣵ◌̀◌̕b; a◌֮◌ࣵ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC FATHA WITH DOT ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 08F6 0062;0061 302A 0316 08F6 059A 0062;0061 302A 0316 08F6 059A 0062;0061 302A 0316 08F6 059A 0062;0061 302A 0316 08F6 059A 0062; # (a◌֚◌̖◌〪◌ࣶb; a◌〪◌̖◌ࣶ◌֚b; a◌〪◌̖◌ࣶ◌֚b; a◌〪◌̖◌ࣶ◌֚b; a◌〪◌̖◌ࣶ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC KASRA WITH DOT BELOW, LATIN SMALL LETTER B
-0061 08F6 059A 0316 302A 0062;0061 302A 08F6 0316 059A 0062;0061 302A 08F6 0316 059A 0062;0061 302A 08F6 0316 059A 0062;0061 302A 08F6 0316 059A 0062; # (a◌ࣶ◌֚◌̖◌〪b; a◌〪◌ࣶ◌̖◌֚b; a◌〪◌ࣶ◌̖◌֚b; a◌〪◌ࣶ◌̖◌֚b; a◌〪◌ࣶ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC KASRA WITH DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 08F6 0062;0061 1DFA 0316 08F6 059A 0062;0061 1DFA 0316 08F6 059A 0062;0061 1DFA 0316 08F6 059A 0062;0061 1DFA 0316 08F6 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 KASRA WITH DOT BELOW, LATIN SMALL LETTER B
+0061 08F6 059A 0316 1DFA 0062;0061 1DFA 08F6 0316 059A 0062;0061 1DFA 08F6 0316 059A 0062;0061 1DFA 08F6 0316 059A 0062;0061 1DFA 08F6 0316 059A 0062; # (a◌ࣶ◌֚◌̖◌᷺b; a◌᷺◌ࣶ◌̖◌֚b; a◌᷺◌ࣶ◌̖◌֚b; a◌᷺◌ࣶ◌̖◌֚b; a◌᷺◌ࣶ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC KASRA WITH DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 08F7 0062;00E0 05AE 08F7 0315 0062;0061 05AE 0300 08F7 0315 0062;00E0 05AE 08F7 0315 0062;0061 05AE 0300 08F7 0315 0062; # (a◌̕◌̀◌֮◌ࣷb; à◌֮◌ࣷ◌̕b; a◌֮◌̀◌ࣷ◌̕b; à◌֮◌ࣷ◌̕b; a◌֮◌̀◌ࣷ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC LEFT ARROWHEAD ABOVE, LATIN SMALL LETTER B
0061 08F7 0315 0300 05AE 0062;0061 05AE 08F7 0300 0315 0062;0061 05AE 08F7 0300 0315 0062;0061 05AE 08F7 0300 0315 0062;0061 05AE 08F7 0300 0315 0062; # (a◌ࣷ◌̕◌̀◌֮b; a◌֮◌ࣷ◌̀◌̕b; a◌֮◌ࣷ◌̀◌̕b; a◌֮◌ࣷ◌̀◌̕b; a◌֮◌ࣷ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC LEFT ARROWHEAD ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 08F8 0062;00E0 05AE 08F8 0315 0062;0061 05AE 0300 08F8 0315 0062;00E0 05AE 08F8 0315 0062;0061 05AE 0300 08F8 0315 0062; # (a◌̕◌̀◌֮◌ࣸb; à◌֮◌ࣸ◌̕b; a◌֮◌̀◌ࣸ◌̕b; à◌֮◌ࣸ◌̕b; a◌֮◌̀◌ࣸ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC RIGHT ARROWHEAD ABOVE, LATIN SMALL LETTER B
0061 08F8 0315 0300 05AE 0062;0061 05AE 08F8 0300 0315 0062;0061 05AE 08F8 0300 0315 0062;0061 05AE 08F8 0300 0315 0062;0061 05AE 08F8 0300 0315 0062; # (a◌ࣸ◌̕◌̀◌֮b; a◌֮◌ࣸ◌̀◌̕b; a◌֮◌ࣸ◌̀◌̕b; a◌֮◌ࣸ◌̀◌̕b; a◌֮◌ࣸ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC RIGHT ARROWHEAD ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 08F9 0062;0061 302A 0316 08F9 059A 0062;0061 302A 0316 08F9 059A 0062;0061 302A 0316 08F9 059A 0062;0061 302A 0316 08F9 059A 0062; # (a◌֚◌̖◌〪◌ࣹb; a◌〪◌̖◌ࣹ◌֚b; a◌〪◌̖◌ࣹ◌֚b; a◌〪◌̖◌ࣹ◌֚b; a◌〪◌̖◌ࣹ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC LEFT ARROWHEAD BELOW, LATIN SMALL LETTER B
-0061 08F9 059A 0316 302A 0062;0061 302A 08F9 0316 059A 0062;0061 302A 08F9 0316 059A 0062;0061 302A 08F9 0316 059A 0062;0061 302A 08F9 0316 059A 0062; # (a◌ࣹ◌֚◌̖◌〪b; a◌〪◌ࣹ◌̖◌֚b; a◌〪◌ࣹ◌̖◌֚b; a◌〪◌ࣹ◌̖◌֚b; a◌〪◌ࣹ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC LEFT ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 08FA 0062;0061 302A 0316 08FA 059A 0062;0061 302A 0316 08FA 059A 0062;0061 302A 0316 08FA 059A 0062;0061 302A 0316 08FA 059A 0062; # (a◌֚◌̖◌〪◌ࣺb; a◌〪◌̖◌ࣺ◌֚b; a◌〪◌̖◌ࣺ◌֚b; a◌〪◌̖◌ࣺ◌֚b; a◌〪◌̖◌ࣺ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC RIGHT ARROWHEAD BELOW, LATIN SMALL LETTER B
-0061 08FA 059A 0316 302A 0062;0061 302A 08FA 0316 059A 0062;0061 302A 08FA 0316 059A 0062;0061 302A 08FA 0316 059A 0062;0061 302A 08FA 0316 059A 0062; # (a◌ࣺ◌֚◌̖◌〪b; a◌〪◌ࣺ◌̖◌֚b; a◌〪◌ࣺ◌̖◌֚b; a◌〪◌ࣺ◌̖◌֚b; a◌〪◌ࣺ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC RIGHT ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 08F9 0062;0061 1DFA 0316 08F9 059A 0062;0061 1DFA 0316 08F9 059A 0062;0061 1DFA 0316 08F9 059A 0062;0061 1DFA 0316 08F9 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 LEFT ARROWHEAD BELOW, LATIN SMALL LETTER B
+0061 08F9 059A 0316 1DFA 0062;0061 1DFA 08F9 0316 059A 0062;0061 1DFA 08F9 0316 059A 0062;0061 1DFA 08F9 0316 059A 0062;0061 1DFA 08F9 0316 059A 0062; # (a◌ࣹ◌֚◌̖◌᷺b; a◌᷺◌ࣹ◌̖◌֚b; a◌᷺◌ࣹ◌̖◌֚b; a◌᷺◌ࣹ◌̖◌֚b; a◌᷺◌ࣹ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC LEFT ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 08FA 0062;0061 1DFA 0316 08FA 059A 0062;0061 1DFA 0316 08FA 059A 0062;0061 1DFA 0316 08FA 059A 0062;0061 1DFA 0316 08FA 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 RIGHT ARROWHEAD BELOW, LATIN SMALL LETTER B
+0061 08FA 059A 0316 1DFA 0062;0061 1DFA 08FA 0316 059A 0062;0061 1DFA 08FA 0316 059A 0062;0061 1DFA 08FA 0316 059A 0062;0061 1DFA 08FA 0316 059A 0062; # (a◌ࣺ◌֚◌̖◌᷺b; a◌᷺◌ࣺ◌̖◌֚b; a◌᷺◌ࣺ◌̖◌֚b; a◌᷺◌ࣺ◌̖◌֚b; a◌᷺◌ࣺ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC RIGHT ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 08FB 0062;00E0 05AE 08FB 0315 0062;0061 05AE 0300 08FB 0315 0062;00E0 05AE 08FB 0315 0062;0061 05AE 0300 08FB 0315 0062; # (a◌̕◌̀◌֮◌ࣻb; à◌֮◌ࣻ◌̕b; a◌֮◌̀◌ࣻ◌̕b; à◌֮◌ࣻ◌̕b; a◌֮◌̀◌ࣻ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC DOUBLE RIGHT ARROWHEAD ABOVE, LATIN SMALL LETTER B
0061 08FB 0315 0300 05AE 0062;0061 05AE 08FB 0300 0315 0062;0061 05AE 08FB 0300 0315 0062;0061 05AE 08FB 0300 0315 0062;0061 05AE 08FB 0300 0315 0062; # (a◌ࣻ◌̕◌̀◌֮b; a◌֮◌ࣻ◌̀◌̕b; a◌֮◌ࣻ◌̀◌̕b; a◌֮◌ࣻ◌̀◌̕b; a◌֮◌ࣻ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC DOUBLE RIGHT ARROWHEAD ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 08FC 0062;00E0 05AE 08FC 0315 0062;0061 05AE 0300 08FC 0315 0062;00E0 05AE 08FC 0315 0062;0061 05AE 0300 08FC 0315 0062; # (a◌̕◌̀◌֮◌ࣼb; à◌֮◌ࣼ◌̕b; a◌֮◌̀◌ࣼ◌̕b; à◌֮◌ࣼ◌̕b; a◌֮◌̀◌ࣼ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC DOUBLE RIGHT ARROWHEAD ABOVE WITH DOT, LATIN SMALL LETTER B
@@ -17637,8 +17730,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 094D 05B0 094D 3099 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062; # (a◌्◌ְ◌्◌゙b; a◌゙◌्◌्◌ְb; a◌゙◌्◌्◌ְb; a◌゙◌्◌्◌ְb; a◌゙◌्◌्◌ְb; ) LATIN SMALL LETTER A, DEVANAGARI SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
0061 0315 0300 05AE 0951 0062;00E0 05AE 0951 0315 0062;0061 05AE 0300 0951 0315 0062;00E0 05AE 0951 0315 0062;0061 05AE 0300 0951 0315 0062; # (a◌̕◌̀◌֮◌॑b; à◌֮◌॑◌̕b; a◌֮◌̀◌॑◌̕b; à◌֮◌॑◌̕b; a◌֮◌̀◌॑◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, DEVANAGARI STRESS SIGN UDATTA, LATIN SMALL LETTER B
0061 0951 0315 0300 05AE 0062;0061 05AE 0951 0300 0315 0062;0061 05AE 0951 0300 0315 0062;0061 05AE 0951 0300 0315 0062;0061 05AE 0951 0300 0315 0062; # (a◌॑◌̕◌̀◌֮b; a◌֮◌॑◌̀◌̕b; a◌֮◌॑◌̀◌̕b; a◌֮◌॑◌̀◌̕b; a◌֮◌॑◌̀◌̕b; ) LATIN SMALL LETTER A, DEVANAGARI STRESS SIGN UDATTA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 0952 0062;0061 302A 0316 0952 059A 0062;0061 302A 0316 0952 059A 0062;0061 302A 0316 0952 059A 0062;0061 302A 0316 0952 059A 0062; # (a◌֚◌̖◌〪◌॒b; a◌〪◌̖◌॒◌֚b; a◌〪◌̖◌॒◌֚b; a◌〪◌̖◌॒◌֚b; a◌〪◌̖◌॒◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, DEVANAGARI STRESS SIGN ANUDATTA, LATIN SMALL LETTER B
-0061 0952 059A 0316 302A 0062;0061 302A 0952 0316 059A 0062;0061 302A 0952 0316 059A 0062;0061 302A 0952 0316 059A 0062;0061 302A 0952 0316 059A 0062; # (a◌॒◌֚◌̖◌〪b; a◌〪◌॒◌̖◌֚b; a◌〪◌॒◌̖◌֚b; a◌〪◌॒◌̖◌֚b; a◌〪◌॒◌̖◌֚b; ) LATIN SMALL LETTER A, DEVANAGARI STRESS SIGN ANUDATTA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0952 0062;0061 1DFA 0316 0952 059A 0062;0061 1DFA 0316 0952 059A 0062;0061 1DFA 0316 0952 059A 0062;0061 1DFA 0316 0952 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, DEVANAGARI STRESS SIGN ANUDATTA, LATIN SMALL LETTER B
+0061 0952 059A 0316 1DFA 0062;0061 1DFA 0952 0316 059A 0062;0061 1DFA 0952 0316 059A 0062;0061 1DFA 0952 0316 059A 0062;0061 1DFA 0952 0316 059A 0062; # (a◌॒◌֚◌̖◌᷺b; a◌᷺◌॒◌̖◌֚b; a◌᷺◌॒◌̖◌֚b; a◌᷺◌॒◌̖◌֚b; a◌᷺◌॒◌̖◌֚b; ) LATIN SMALL LETTER A, DEVANAGARI STRESS SIGN ANUDATTA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 0953 0062;00E0 05AE 0953 0315 0062;0061 05AE 0300 0953 0315 0062;00E0 05AE 0953 0315 0062;0061 05AE 0300 0953 0315 0062; # (a◌̕◌̀◌֮◌॓b; à◌֮◌॓◌̕b; a◌֮◌̀◌॓◌̕b; à◌֮◌॓◌̕b; a◌֮◌̀◌॓◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, DEVANAGARI GRAVE ACCENT, LATIN SMALL LETTER B
0061 0953 0315 0300 05AE 0062;0061 05AE 0953 0300 0315 0062;0061 05AE 0953 0300 0315 0062;0061 05AE 0953 0300 0315 0062;0061 05AE 0953 0300 0315 0062; # (a◌॓◌̕◌̀◌֮b; a◌֮◌॓◌̀◌̕b; a◌֮◌॓◌̀◌̕b; a◌֮◌॓◌̀◌̕b; a◌֮◌॓◌̀◌̕b; ) LATIN SMALL LETTER A, DEVANAGARI GRAVE ACCENT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 0954 0062;00E0 05AE 0954 0315 0062;0061 05AE 0300 0954 0315 0062;00E0 05AE 0954 0315 0062;0061 05AE 0300 0954 0315 0062; # (a◌̕◌̀◌֮◌॔b; à◌֮◌॔◌̕b; a◌֮◌̀◌॔◌̕b; à◌֮◌॔◌̕b; a◌֮◌̀◌॔◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, DEVANAGARI ACUTE ACCENT, LATIN SMALL LETTER B
@@ -17663,6 +17756,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 0B4D 05B0 094D 3099 0062;0061 3099 0B4D 094D 05B0 0062;0061 3099 0B4D 094D 05B0 0062;0061 3099 0B4D 094D 05B0 0062;0061 3099 0B4D 094D 05B0 0062; # (a◌୍◌ְ◌्◌゙b; a◌゙◌୍◌्◌ְb; a◌゙◌୍◌्◌ְb; a◌゙◌୍◌्◌ְb; a◌゙◌୍◌्◌ְb; ) LATIN SMALL LETTER A, ORIYA SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
0061 05B0 094D 3099 0BCD 0062;0061 3099 094D 0BCD 05B0 0062;0061 3099 094D 0BCD 05B0 0062;0061 3099 094D 0BCD 05B0 0062;0061 3099 094D 0BCD 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, TAMIL SIGN VIRAMA, LATIN SMALL LETTER B
0061 0BCD 05B0 094D 3099 0062;0061 3099 0BCD 094D 05B0 0062;0061 3099 0BCD 094D 05B0 0062;0061 3099 0BCD 094D 05B0 0062;0061 3099 0BCD 094D 05B0 0062; # (a◌்◌ְ◌्◌゙b; a◌゙◌்◌्◌ְb; a◌゙◌்◌्◌ְb; a◌゙◌்◌्◌ְb; a◌゙◌்◌्◌ְb; ) LATIN SMALL LETTER A, TAMIL SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 16FF0 0C3C 0062;0061 16FF0 093C 0C3C 3099 0062;0061 16FF0 093C 0C3C 3099 0062;0061 16FF0 093C 0C3C 3099 0062;0061 16FF0 093C 0C3C 3099 0062; # (a◌゙◌𖿰़◌఼b; a𖿰◌़◌఼◌゙b; a𖿰◌़◌఼◌゙b; a𖿰◌़◌఼◌゙b; a𖿰◌़◌఼◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, VIETNAMESE ALTERNATE READING MARK CA, TELUGU SIGN NUKTA, LATIN SMALL LETTER B
+0061 0C3C 3099 093C 16FF0 0062;0061 16FF0 0C3C 093C 3099 0062;0061 16FF0 0C3C 093C 3099 0062;0061 16FF0 0C3C 093C 3099 0062;0061 16FF0 0C3C 093C 3099 0062; # (a◌఼◌゙◌𖿰़b; a𖿰◌఼◌़◌゙b; a𖿰◌఼◌़◌゙b; a𖿰◌఼◌़◌゙b; a𖿰◌఼◌़◌゙b; ) LATIN SMALL LETTER A, TELUGU SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, VIETNAMESE ALTERNATE READING MARK CA, LATIN SMALL LETTER B
0061 05B0 094D 3099 0C4D 0062;0061 3099 094D 0C4D 05B0 0062;0061 3099 094D 0C4D 05B0 0062;0061 3099 094D 0C4D 05B0 0062;0061 3099 094D 0C4D 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, TELUGU SIGN VIRAMA, LATIN SMALL LETTER B
0061 0C4D 05B0 094D 3099 0062;0061 3099 0C4D 094D 05B0 0062;0061 3099 0C4D 094D 05B0 0062;0061 3099 0C4D 094D 05B0 0062;0061 3099 0C4D 094D 05B0 0062; # (a◌్◌ְ◌्◌゙b; a◌゙◌్◌्◌ְb; a◌゙◌్◌्◌ְb; a◌゙◌్◌्◌ְb; a◌゙◌్◌्◌ְb; ) LATIN SMALL LETTER A, TELUGU SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
0061 0C56 0C55 0711 0C55 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062; # (a◌ౖ◌ౕ◌ܑ◌ౕb; a◌ܑ◌ౕ◌ౕ◌ౖb; a◌ܑ◌ౕ◌ౕ◌ౖb; a◌ܑ◌ౕ◌ౕ◌ౖb; a◌ܑ◌ౕ◌ౕ◌ౖb; ) LATIN SMALL LETTER A, TELUGU AI LENGTH MARK, TELUGU LENGTH MARK, SYRIAC LETTER SUPERSCRIPT ALAPH, TELUGU LENGTH MARK, LATIN SMALL LETTER B
@@ -17709,16 +17804,16 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 0ECA 0F71 0EC8 0EB8 0062;0061 0EB8 0ECA 0EC8 0F71 0062;0061 0EB8 0ECA 0EC8 0F71 0062;0061 0EB8 0ECA 0EC8 0F71 0062;0061 0EB8 0ECA 0EC8 0F71 0062; # (a◌໊◌ཱ◌່◌ຸb; a◌ຸ◌໊◌່◌ཱb; a◌ຸ◌໊◌່◌ཱb; a◌ຸ◌໊◌່◌ཱb; a◌ຸ◌໊◌່◌ཱb; ) LATIN SMALL LETTER A, LAO TONE MAI TI, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LAO VOWEL SIGN U, LATIN SMALL LETTER B
0061 0F71 0EC8 0EB8 0ECB 0062;0061 0EB8 0EC8 0ECB 0F71 0062;0061 0EB8 0EC8 0ECB 0F71 0062;0061 0EB8 0EC8 0ECB 0F71 0062;0061 0EB8 0EC8 0ECB 0F71 0062; # (a◌ཱ◌່◌ຸ◌໋b; a◌ຸ◌່◌໋◌ཱb; a◌ຸ◌່◌໋◌ཱb; a◌ຸ◌່◌໋◌ཱb; a◌ຸ◌່◌໋◌ཱb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LAO VOWEL SIGN U, LAO TONE MAI CATAWA, LATIN SMALL LETTER B
0061 0ECB 0F71 0EC8 0EB8 0062;0061 0EB8 0ECB 0EC8 0F71 0062;0061 0EB8 0ECB 0EC8 0F71 0062;0061 0EB8 0ECB 0EC8 0F71 0062;0061 0EB8 0ECB 0EC8 0F71 0062; # (a◌໋◌ཱ◌່◌ຸb; a◌ຸ◌໋◌່◌ཱb; a◌ຸ◌໋◌່◌ཱb; a◌ຸ◌໋◌່◌ཱb; a◌ຸ◌໋◌່◌ཱb; ) LATIN SMALL LETTER A, LAO TONE MAI CATAWA, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LAO VOWEL SIGN U, LATIN SMALL LETTER B
-0061 059A 0316 302A 0F18 0062;0061 302A 0316 0F18 059A 0062;0061 302A 0316 0F18 059A 0062;0061 302A 0316 0F18 059A 0062;0061 302A 0316 0F18 059A 0062; # (a◌֚◌̖◌〪◌༘b; a◌〪◌̖◌༘◌֚b; a◌〪◌̖◌༘◌֚b; a◌〪◌̖◌༘◌֚b; a◌〪◌̖◌༘◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, TIBETAN ASTROLOGICAL SIGN -KHYUD PA, LATIN SMALL LETTER B
-0061 0F18 059A 0316 302A 0062;0061 302A 0F18 0316 059A 0062;0061 302A 0F18 0316 059A 0062;0061 302A 0F18 0316 059A 0062;0061 302A 0F18 0316 059A 0062; # (a◌༘◌֚◌̖◌〪b; a◌〪◌༘◌̖◌֚b; a◌〪◌༘◌̖◌֚b; a◌〪◌༘◌̖◌֚b; a◌〪◌༘◌̖◌֚b; ) LATIN SMALL LETTER A, TIBETAN ASTROLOGICAL SIGN -KHYUD PA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0F19 0062;0061 302A 0316 0F19 059A 0062;0061 302A 0316 0F19 059A 0062;0061 302A 0316 0F19 059A 0062;0061 302A 0316 0F19 059A 0062; # (a◌֚◌̖◌〪◌༙b; a◌〪◌̖◌༙◌֚b; a◌〪◌̖◌༙◌֚b; a◌〪◌̖◌༙◌֚b; a◌〪◌̖◌༙◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS, LATIN SMALL LETTER B
-0061 0F19 059A 0316 302A 0062;0061 302A 0F19 0316 059A 0062;0061 302A 0F19 0316 059A 0062;0061 302A 0F19 0316 059A 0062;0061 302A 0F19 0316 059A 0062; # (a◌༙◌֚◌̖◌〪b; a◌〪◌༙◌̖◌֚b; a◌〪◌༙◌̖◌֚b; a◌〪◌༙◌̖◌֚b; a◌〪◌༙◌̖◌֚b; ) LATIN SMALL LETTER A, TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0F35 0062;0061 302A 0316 0F35 059A 0062;0061 302A 0316 0F35 059A 0062;0061 302A 0316 0F35 059A 0062;0061 302A 0316 0F35 059A 0062; # (a◌֚◌̖◌〪◌༵b; a◌〪◌̖◌༵◌֚b; a◌〪◌̖◌༵◌֚b; a◌〪◌̖◌༵◌֚b; a◌〪◌̖◌༵◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, TIBETAN MARK NGAS BZUNG NYI ZLA, LATIN SMALL LETTER B
-0061 0F35 059A 0316 302A 0062;0061 302A 0F35 0316 059A 0062;0061 302A 0F35 0316 059A 0062;0061 302A 0F35 0316 059A 0062;0061 302A 0F35 0316 059A 0062; # (a◌༵◌֚◌̖◌〪b; a◌〪◌༵◌̖◌֚b; a◌〪◌༵◌̖◌֚b; a◌〪◌༵◌̖◌֚b; a◌〪◌༵◌̖◌֚b; ) LATIN SMALL LETTER A, TIBETAN MARK NGAS BZUNG NYI ZLA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 0F37 0062;0061 302A 0316 0F37 059A 0062;0061 302A 0316 0F37 059A 0062;0061 302A 0316 0F37 059A 0062;0061 302A 0316 0F37 059A 0062; # (a◌֚◌̖◌〪◌༷b; a◌〪◌̖◌༷◌֚b; a◌〪◌̖◌༷◌֚b; a◌〪◌̖◌༷◌֚b; a◌〪◌̖◌༷◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, TIBETAN MARK NGAS BZUNG SGOR RTAGS, LATIN SMALL LETTER B
-0061 0F37 059A 0316 302A 0062;0061 302A 0F37 0316 059A 0062;0061 302A 0F37 0316 059A 0062;0061 302A 0F37 0316 059A 0062;0061 302A 0F37 0316 059A 0062; # (a◌༷◌֚◌̖◌〪b; a◌〪◌༷◌̖◌֚b; a◌〪◌༷◌̖◌֚b; a◌〪◌༷◌̖◌֚b; a◌〪◌༷◌̖◌֚b; ) LATIN SMALL LETTER A, TIBETAN MARK NGAS BZUNG SGOR RTAGS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 302A 031B 1DCE 0F39 0062;0061 1DCE 031B 0F39 302A 0062;0061 1DCE 031B 0F39 302A 0062;0061 1DCE 031B 0F39 302A 0062;0061 1DCE 031B 0F39 302A 0062; # (a◌〪◌̛◌᷎◌༹b; a◌᷎◌̛◌༹◌〪b; a◌᷎◌̛◌༹◌〪b; a◌᷎◌̛◌༹◌〪b; a◌᷎◌̛◌༹◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, TIBETAN MARK TSA -PHRU, LATIN SMALL LETTER B
-0061 0F39 302A 031B 1DCE 0062;0061 1DCE 0F39 031B 302A 0062;0061 1DCE 0F39 031B 302A 0062;0061 1DCE 0F39 031B 302A 0062;0061 1DCE 0F39 031B 302A 0062; # (a◌༹◌〪◌̛◌᷎b; a◌᷎◌༹◌̛◌〪b; a◌᷎◌༹◌̛◌〪b; a◌᷎◌༹◌̛◌〪b; a◌᷎◌༹◌̛◌〪b; ) LATIN SMALL LETTER A, TIBETAN MARK TSA -PHRU, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0F18 0062;0061 1DFA 0316 0F18 059A 0062;0061 1DFA 0316 0F18 059A 0062;0061 1DFA 0316 0F18 059A 0062;0061 1DFA 0316 0F18 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, TIBETAN ASTROLOGICAL SIGN -KHYUD PA, LATIN SMALL LETTER B
+0061 0F18 059A 0316 1DFA 0062;0061 1DFA 0F18 0316 059A 0062;0061 1DFA 0F18 0316 059A 0062;0061 1DFA 0F18 0316 059A 0062;0061 1DFA 0F18 0316 059A 0062; # (a◌༘◌֚◌̖◌᷺b; a◌᷺◌༘◌̖◌֚b; a◌᷺◌༘◌̖◌֚b; a◌᷺◌༘◌̖◌֚b; a◌᷺◌༘◌̖◌֚b; ) LATIN SMALL LETTER A, TIBETAN ASTROLOGICAL SIGN -KHYUD PA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0F19 0062;0061 1DFA 0316 0F19 059A 0062;0061 1DFA 0316 0F19 059A 0062;0061 1DFA 0316 0F19 059A 0062;0061 1DFA 0316 0F19 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, TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS, LATIN SMALL LETTER B
+0061 0F19 059A 0316 1DFA 0062;0061 1DFA 0F19 0316 059A 0062;0061 1DFA 0F19 0316 059A 0062;0061 1DFA 0F19 0316 059A 0062;0061 1DFA 0F19 0316 059A 0062; # (a◌༙◌֚◌̖◌᷺b; a◌᷺◌༙◌̖◌֚b; a◌᷺◌༙◌̖◌֚b; a◌᷺◌༙◌̖◌֚b; a◌᷺◌༙◌̖◌֚b; ) LATIN SMALL LETTER A, TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0F35 0062;0061 1DFA 0316 0F35 059A 0062;0061 1DFA 0316 0F35 059A 0062;0061 1DFA 0316 0F35 059A 0062;0061 1DFA 0316 0F35 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, TIBETAN MARK NGAS BZUNG NYI ZLA, LATIN SMALL LETTER B
+0061 0F35 059A 0316 1DFA 0062;0061 1DFA 0F35 0316 059A 0062;0061 1DFA 0F35 0316 059A 0062;0061 1DFA 0F35 0316 059A 0062;0061 1DFA 0F35 0316 059A 0062; # (a◌༵◌֚◌̖◌᷺b; a◌᷺◌༵◌̖◌֚b; a◌᷺◌༵◌̖◌֚b; a◌᷺◌༵◌̖◌֚b; a◌᷺◌༵◌̖◌֚b; ) LATIN SMALL LETTER A, TIBETAN MARK NGAS BZUNG NYI ZLA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0F37 0062;0061 1DFA 0316 0F37 059A 0062;0061 1DFA 0316 0F37 059A 0062;0061 1DFA 0316 0F37 059A 0062;0061 1DFA 0316 0F37 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, TIBETAN MARK NGAS BZUNG SGOR RTAGS, LATIN SMALL LETTER B
+0061 0F37 059A 0316 1DFA 0062;0061 1DFA 0F37 0316 059A 0062;0061 1DFA 0F37 0316 059A 0062;0061 1DFA 0F37 0316 059A 0062;0061 1DFA 0F37 0316 059A 0062; # (a◌༷◌֚◌̖◌᷺b; a◌᷺◌༷◌̖◌֚b; a◌᷺◌༷◌̖◌֚b; a◌᷺◌༷◌̖◌֚b; a◌᷺◌༷◌̖◌֚b; ) LATIN SMALL LETTER A, TIBETAN MARK NGAS BZUNG SGOR RTAGS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 1DFA 031B 1DCE 0F39 0062;0061 1DCE 031B 0F39 1DFA 0062;0061 1DCE 031B 0F39 1DFA 0062;0061 1DCE 031B 0F39 1DFA 0062;0061 1DCE 031B 0F39 1DFA 0062; # (a◌᷺◌̛◌᷎◌༹b; a◌᷎◌̛◌༹◌᷺b; a◌᷎◌̛◌༹◌᷺b; a◌᷎◌̛◌༹◌᷺b; a◌᷎◌̛◌༹◌᷺b; ) LATIN SMALL LETTER A, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, TIBETAN MARK TSA -PHRU, LATIN SMALL LETTER B
+0061 0F39 1DFA 031B 1DCE 0062;0061 1DCE 0F39 031B 1DFA 0062;0061 1DCE 0F39 031B 1DFA 0062;0061 1DCE 0F39 031B 1DFA 0062;0061 1DCE 0F39 031B 1DFA 0062; # (a◌༹◌᷺◌̛◌᷎b; a◌᷎◌༹◌̛◌᷺b; a◌᷎◌༹◌̛◌᷺b; a◌᷎◌༹◌̛◌᷺b; a◌᷎◌༹◌̛◌᷺b; ) LATIN SMALL LETTER A, TIBETAN MARK TSA -PHRU, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
0061 0F72 0F71 0EC8 0F71 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062; # (a◌ི◌ཱ◌່◌ཱb; a◌່◌ཱ◌ཱ◌ིb; a◌່◌ཱ◌ཱ◌ིb; a◌່◌ཱ◌ཱ◌ིb; a◌່◌ཱ◌ཱ◌ིb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, TIBETAN VOWEL SIGN AA, LATIN SMALL LETTER B
0061 0F71 0F72 0F71 0EC8 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062; # (a◌ཱ◌ི◌ཱ◌່b; a◌່◌ཱ◌ཱ◌ིb; a◌່◌ཱ◌ཱ◌ིb; a◌່◌ཱ◌ཱ◌ིb; a◌່◌ཱ◌ཱ◌ིb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN AA, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LATIN SMALL LETTER B
0061 0F74 0F72 0F71 0F72 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062; # (a◌ུ◌ི◌ཱ◌ིb; a◌ཱ◌ི◌ི◌ུb; a◌ཱ◌ི◌ི◌ུb; a◌ཱ◌ི◌ི◌ུb; a◌ཱ◌ི◌ི◌ུb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN U, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, TIBETAN VOWEL SIGN I, LATIN SMALL LETTER B
@@ -17745,16 +17840,16 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 0F86 0315 0300 05AE 0062;0061 05AE 0F86 0300 0315 0062;0061 05AE 0F86 0300 0315 0062;0061 05AE 0F86 0300 0315 0062;0061 05AE 0F86 0300 0315 0062; # (a◌྆◌̕◌̀◌֮b; a◌֮◌྆◌̀◌̕b; a◌֮◌྆◌̀◌̕b; a◌֮◌྆◌̀◌̕b; a◌֮◌྆◌̀◌̕b; ) LATIN SMALL LETTER A, TIBETAN SIGN LCI RTAGS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 0F87 0062;00E0 05AE 0F87 0315 0062;0061 05AE 0300 0F87 0315 0062;00E0 05AE 0F87 0315 0062;0061 05AE 0300 0F87 0315 0062; # (a◌̕◌̀◌֮◌྇b; à◌֮◌྇◌̕b; a◌֮◌̀◌྇◌̕b; à◌֮◌྇◌̕b; a◌֮◌̀◌྇◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TIBETAN SIGN YANG RTAGS, LATIN SMALL LETTER B
0061 0F87 0315 0300 05AE 0062;0061 05AE 0F87 0300 0315 0062;0061 05AE 0F87 0300 0315 0062;0061 05AE 0F87 0300 0315 0062;0061 05AE 0F87 0300 0315 0062; # (a◌྇◌̕◌̀◌֮b; a◌֮◌྇◌̀◌̕b; a◌֮◌྇◌̀◌̕b; a◌֮◌྇◌̀◌̕b; a◌֮◌྇◌̀◌̕b; ) LATIN SMALL LETTER A, TIBETAN SIGN YANG RTAGS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 0FC6 0062;0061 302A 0316 0FC6 059A 0062;0061 302A 0316 0FC6 059A 0062;0061 302A 0316 0FC6 059A 0062;0061 302A 0316 0FC6 059A 0062; # (a◌֚◌̖◌〪◌࿆b; a◌〪◌̖◌࿆◌֚b; a◌〪◌̖◌࿆◌֚b; a◌〪◌̖◌࿆◌֚b; a◌〪◌̖◌࿆◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, TIBETAN SYMBOL PADMA GDAN, LATIN SMALL LETTER B
-0061 0FC6 059A 0316 302A 0062;0061 302A 0FC6 0316 059A 0062;0061 302A 0FC6 0316 059A 0062;0061 302A 0FC6 0316 059A 0062;0061 302A 0FC6 0316 059A 0062; # (a◌࿆◌֚◌̖◌〪b; a◌〪◌࿆◌̖◌֚b; a◌〪◌࿆◌̖◌֚b; a◌〪◌࿆◌̖◌֚b; a◌〪◌࿆◌̖◌֚b; ) LATIN SMALL LETTER A, TIBETAN SYMBOL PADMA GDAN, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 0FC6 0062;0061 1DFA 0316 0FC6 059A 0062;0061 1DFA 0316 0FC6 059A 0062;0061 1DFA 0316 0FC6 059A 0062;0061 1DFA 0316 0FC6 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, TIBETAN SYMBOL PADMA GDAN, LATIN SMALL LETTER B
+0061 0FC6 059A 0316 1DFA 0062;0061 1DFA 0FC6 0316 059A 0062;0061 1DFA 0FC6 0316 059A 0062;0061 1DFA 0FC6 0316 059A 0062;0061 1DFA 0FC6 0316 059A 0062; # (a◌࿆◌֚◌̖◌᷺b; a◌᷺◌࿆◌̖◌֚b; a◌᷺◌࿆◌̖◌֚b; a◌᷺◌࿆◌̖◌֚b; a◌᷺◌࿆◌̖◌֚b; ) LATIN SMALL LETTER A, TIBETAN SYMBOL PADMA GDAN, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 3099 093C 16FF0 1037 0062;0061 16FF0 093C 1037 3099 0062;0061 16FF0 093C 1037 3099 0062;0061 16FF0 093C 1037 3099 0062;0061 16FF0 093C 1037 3099 0062; # (a◌゙◌𖿰़◌့b; a𖿰◌़◌့◌゙b; a𖿰◌़◌့◌゙b; a𖿰◌़◌့◌゙b; a𖿰◌़◌့◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, VIETNAMESE ALTERNATE READING MARK CA, MYANMAR SIGN DOT BELOW, LATIN SMALL LETTER B
0061 1037 3099 093C 16FF0 0062;0061 16FF0 1037 093C 3099 0062;0061 16FF0 1037 093C 3099 0062;0061 16FF0 1037 093C 3099 0062;0061 16FF0 1037 093C 3099 0062; # (a◌့◌゙◌𖿰़b; a𖿰◌့◌़◌゙b; a𖿰◌့◌़◌゙b; a𖿰◌့◌़◌゙b; a𖿰◌့◌़◌゙b; ) LATIN SMALL LETTER A, MYANMAR SIGN DOT BELOW, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, VIETNAMESE ALTERNATE READING MARK CA, LATIN SMALL LETTER B
0061 05B0 094D 3099 1039 0062;0061 3099 094D 1039 05B0 0062;0061 3099 094D 1039 05B0 0062;0061 3099 094D 1039 05B0 0062;0061 3099 094D 1039 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, MYANMAR SIGN VIRAMA, LATIN SMALL LETTER B
0061 1039 05B0 094D 3099 0062;0061 3099 1039 094D 05B0 0062;0061 3099 1039 094D 05B0 0062;0061 3099 1039 094D 05B0 0062;0061 3099 1039 094D 05B0 0062; # (a◌္◌ְ◌्◌゙b; a◌゙◌္◌्◌ְb; a◌゙◌္◌्◌ְb; a◌゙◌္◌्◌ְb; a◌゙◌္◌्◌ְb; ) LATIN SMALL LETTER A, MYANMAR SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
0061 05B0 094D 3099 103A 0062;0061 3099 094D 103A 05B0 0062;0061 3099 094D 103A 05B0 0062;0061 3099 094D 103A 05B0 0062;0061 3099 094D 103A 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, MYANMAR SIGN ASAT, LATIN SMALL LETTER B
0061 103A 05B0 094D 3099 0062;0061 3099 103A 094D 05B0 0062;0061 3099 103A 094D 05B0 0062;0061 3099 103A 094D 05B0 0062;0061 3099 103A 094D 05B0 0062; # (a◌်◌ְ◌्◌゙b; a◌゙◌်◌्◌ְb; a◌゙◌်◌्◌ְb; a◌゙◌်◌्◌ְb; a◌゙◌်◌्◌ְb; ) LATIN SMALL LETTER A, MYANMAR SIGN ASAT, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 108D 0062;0061 302A 0316 108D 059A 0062;0061 302A 0316 108D 059A 0062;0061 302A 0316 108D 059A 0062;0061 302A 0316 108D 059A 0062; # (a◌֚◌̖◌〪◌ႍb; a◌〪◌̖◌ႍ◌֚b; a◌〪◌̖◌ႍ◌֚b; a◌〪◌̖◌ႍ◌֚b; a◌〪◌̖◌ႍ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE, LATIN SMALL LETTER B
-0061 108D 059A 0316 302A 0062;0061 302A 108D 0316 059A 0062;0061 302A 108D 0316 059A 0062;0061 302A 108D 0316 059A 0062;0061 302A 108D 0316 059A 0062; # (a◌ႍ◌֚◌̖◌〪b; a◌〪◌ႍ◌̖◌֚b; a◌〪◌ႍ◌̖◌֚b; a◌〪◌ႍ◌̖◌֚b; a◌〪◌ႍ◌̖◌֚b; ) LATIN SMALL LETTER A, MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 108D 0062;0061 1DFA 0316 108D 059A 0062;0061 1DFA 0316 108D 059A 0062;0061 1DFA 0316 108D 059A 0062;0061 1DFA 0316 108D 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, MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE, LATIN SMALL LETTER B
+0061 108D 059A 0316 1DFA 0062;0061 1DFA 108D 0316 059A 0062;0061 1DFA 108D 0316 059A 0062;0061 1DFA 108D 0316 059A 0062;0061 1DFA 108D 0316 059A 0062; # (a◌ႍ◌֚◌̖◌᷺b; a◌᷺◌ႍ◌̖◌֚b; a◌᷺◌ႍ◌̖◌֚b; a◌᷺◌ႍ◌̖◌֚b; a◌᷺◌ႍ◌̖◌֚b; ) LATIN SMALL LETTER A, MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 135D 0062;00E0 05AE 135D 0315 0062;0061 05AE 0300 135D 0315 0062;00E0 05AE 135D 0315 0062;0061 05AE 0300 135D 0315 0062; # (a◌̕◌̀◌֮◌፝b; à◌֮◌፝◌̕b; a◌֮◌̀◌፝◌̕b; à◌֮◌፝◌̕b; a◌֮◌̀◌፝◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK, LATIN SMALL LETTER B
0061 135D 0315 0300 05AE 0062;0061 05AE 135D 0300 0315 0062;0061 05AE 135D 0300 0315 0062;0061 05AE 135D 0300 0315 0062;0061 05AE 135D 0300 0315 0062; # (a◌፝◌̕◌̀◌֮b; a◌֮◌፝◌̀◌̕b; a◌֮◌፝◌̀◌̕b; a◌֮◌፝◌̀◌̕b; a◌֮◌፝◌̀◌̕b; ) LATIN SMALL LETTER A, ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 135E 0062;00E0 05AE 135E 0315 0062;0061 05AE 0300 135E 0315 0062;00E0 05AE 135E 0315 0062;0061 05AE 0300 135E 0315 0062; # (a◌̕◌̀◌֮◌፞b; à◌֮◌፞◌̕b; a◌֮◌̀◌፞◌̕b; à◌֮◌፞◌̕b; a◌֮◌̀◌፞◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ETHIOPIC COMBINING VOWEL LENGTH MARK, LATIN SMALL LETTER B
@@ -17763,8 +17858,10 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 135F 0315 0300 05AE 0062;0061 05AE 135F 0300 0315 0062;0061 05AE 135F 0300 0315 0062;0061 05AE 135F 0300 0315 0062;0061 05AE 135F 0300 0315 0062; # (a◌፟◌̕◌̀◌֮b; a◌֮◌፟◌̀◌̕b; a◌֮◌፟◌̀◌̕b; a◌֮◌፟◌̀◌̕b; a◌֮◌፟◌̀◌̕b; ) LATIN SMALL LETTER A, ETHIOPIC COMBINING GEMINATION MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 05B0 094D 3099 1714 0062;0061 3099 094D 1714 05B0 0062;0061 3099 094D 1714 05B0 0062;0061 3099 094D 1714 05B0 0062;0061 3099 094D 1714 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, TAGALOG SIGN VIRAMA, LATIN SMALL LETTER B
0061 1714 05B0 094D 3099 0062;0061 3099 1714 094D 05B0 0062;0061 3099 1714 094D 05B0 0062;0061 3099 1714 094D 05B0 0062;0061 3099 1714 094D 05B0 0062; # (a◌᜔◌ְ◌्◌゙b; a◌゙◌᜔◌्◌ְb; a◌゙◌᜔◌्◌ְb; a◌゙◌᜔◌्◌ְb; a◌゙◌᜔◌्◌ְb; ) LATIN SMALL LETTER A, TAGALOG SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
-0061 05B0 094D 3099 1734 0062;0061 3099 094D 1734 05B0 0062;0061 3099 094D 1734 05B0 0062;0061 3099 094D 1734 05B0 0062;0061 3099 094D 1734 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, HANUNOO SIGN PAMUDPOD, LATIN SMALL LETTER B
-0061 1734 05B0 094D 3099 0062;0061 3099 1734 094D 05B0 0062;0061 3099 1734 094D 05B0 0062;0061 3099 1734 094D 05B0 0062;0061 3099 1734 094D 05B0 0062; # (a◌᜴◌ְ◌्◌゙b; a◌゙◌᜴◌्◌ְb; a◌゙◌᜴◌्◌ְb; a◌゙◌᜴◌्◌ְb; a◌゙◌᜴◌्◌ְb; ) LATIN SMALL LETTER A, HANUNOO SIGN PAMUDPOD, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 1715 0062;0061 3099 094D 1715 05B0 0062;0061 3099 094D 1715 05B0 0062;0061 3099 094D 1715 05B0 0062;0061 3099 094D 1715 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, TAGALOG SIGN PAMUDPOD, LATIN SMALL LETTER B
+0061 1715 05B0 094D 3099 0062;0061 3099 1715 094D 05B0 0062;0061 3099 1715 094D 05B0 0062;0061 3099 1715 094D 05B0 0062;0061 3099 1715 094D 05B0 0062; # (a᜕◌ְ◌्◌゙b; a◌゙᜕◌्◌ְb; a◌゙᜕◌्◌ְb; a◌゙᜕◌्◌ְb; a◌゙᜕◌्◌ְb; ) LATIN SMALL LETTER A, TAGALOG SIGN PAMUDPOD, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 1734 0062;0061 3099 094D 1734 05B0 0062;0061 3099 094D 1734 05B0 0062;0061 3099 094D 1734 05B0 0062;0061 3099 094D 1734 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, HANUNOO SIGN PAMUDPOD, LATIN SMALL LETTER B
+0061 1734 05B0 094D 3099 0062;0061 3099 1734 094D 05B0 0062;0061 3099 1734 094D 05B0 0062;0061 3099 1734 094D 05B0 0062;0061 3099 1734 094D 05B0 0062; # (a᜴◌ְ◌्◌゙b; a◌゙᜴◌्◌ְb; a◌゙᜴◌्◌ְb; a◌゙᜴◌्◌ְb; a◌゙᜴◌्◌ְb; ) LATIN SMALL LETTER A, HANUNOO SIGN PAMUDPOD, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
0061 05B0 094D 3099 17D2 0062;0061 3099 094D 17D2 05B0 0062;0061 3099 094D 17D2 05B0 0062;0061 3099 094D 17D2 05B0 0062;0061 3099 094D 17D2 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, KHMER SIGN COENG, LATIN SMALL LETTER B
0061 17D2 05B0 094D 3099 0062;0061 3099 17D2 094D 05B0 0062;0061 3099 17D2 094D 05B0 0062;0061 3099 17D2 094D 05B0 0062;0061 3099 17D2 094D 05B0 0062; # (a◌្◌ְ◌्◌゙b; a◌゙◌្◌्◌ְb; a◌゙◌្◌्◌ְb; a◌゙◌្◌्◌ְb; a◌゙◌្◌्◌ְb; ) LATIN SMALL LETTER A, KHMER SIGN COENG, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
0061 0315 0300 05AE 17DD 0062;00E0 05AE 17DD 0315 0062;0061 05AE 0300 17DD 0315 0062;00E0 05AE 17DD 0315 0062;0061 05AE 0300 17DD 0315 0062; # (a◌̕◌̀◌֮◌៝b; à◌֮◌៝◌̕b; a◌֮◌̀◌៝◌̕b; à◌֮◌៝◌̕b; a◌֮◌̀◌៝◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, KHMER SIGN ATTHACAN, LATIN SMALL LETTER B
@@ -17775,12 +17872,12 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 1939 302E 059A 0316 0062;0061 0316 1939 059A 302E 0062;0061 0316 1939 059A 302E 0062;0061 0316 1939 059A 302E 0062;0061 0316 1939 059A 302E 0062; # (a◌᤹〮◌֚◌̖b; a◌̖◌᤹◌֚〮b; a◌̖◌᤹◌֚〮b; a◌̖◌᤹◌֚〮b; a◌̖◌᤹◌֚〮b; ) LATIN SMALL LETTER A, LIMBU SIGN MUKPHRENG, HANGUL SINGLE DOT TONE MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, LATIN SMALL LETTER B
0061 0315 0300 05AE 193A 0062;00E0 05AE 193A 0315 0062;0061 05AE 0300 193A 0315 0062;00E0 05AE 193A 0315 0062;0061 05AE 0300 193A 0315 0062; # (a◌̕◌̀◌֮◌᤺b; à◌֮◌᤺◌̕b; a◌֮◌̀◌᤺◌̕b; à◌֮◌᤺◌̕b; a◌֮◌̀◌᤺◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LIMBU SIGN KEMPHRENG, LATIN SMALL LETTER B
0061 193A 0315 0300 05AE 0062;0061 05AE 193A 0300 0315 0062;0061 05AE 193A 0300 0315 0062;0061 05AE 193A 0300 0315 0062;0061 05AE 193A 0300 0315 0062; # (a◌᤺◌̕◌̀◌֮b; a◌֮◌᤺◌̀◌̕b; a◌֮◌᤺◌̀◌̕b; a◌֮◌᤺◌̀◌̕b; a◌֮◌᤺◌̀◌̕b; ) LATIN SMALL LETTER A, LIMBU SIGN KEMPHRENG, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 193B 0062;0061 302A 0316 193B 059A 0062;0061 302A 0316 193B 059A 0062;0061 302A 0316 193B 059A 0062;0061 302A 0316 193B 059A 0062; # (a◌֚◌̖◌〪◌᤻b; a◌〪◌̖◌᤻◌֚b; a◌〪◌̖◌᤻◌֚b; a◌〪◌̖◌᤻◌֚b; a◌〪◌̖◌᤻◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LIMBU SIGN SA-I, LATIN SMALL LETTER B
-0061 193B 059A 0316 302A 0062;0061 302A 193B 0316 059A 0062;0061 302A 193B 0316 059A 0062;0061 302A 193B 0316 059A 0062;0061 302A 193B 0316 059A 0062; # (a◌᤻◌֚◌̖◌〪b; a◌〪◌᤻◌̖◌֚b; a◌〪◌᤻◌̖◌֚b; a◌〪◌᤻◌̖◌֚b; a◌〪◌᤻◌̖◌֚b; ) LATIN SMALL LETTER A, LIMBU SIGN SA-I, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 193B 0062;0061 1DFA 0316 193B 059A 0062;0061 1DFA 0316 193B 059A 0062;0061 1DFA 0316 193B 059A 0062;0061 1DFA 0316 193B 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, LIMBU SIGN SA-I, LATIN SMALL LETTER B
+0061 193B 059A 0316 1DFA 0062;0061 1DFA 193B 0316 059A 0062;0061 1DFA 193B 0316 059A 0062;0061 1DFA 193B 0316 059A 0062;0061 1DFA 193B 0316 059A 0062; # (a◌᤻◌֚◌̖◌᷺b; a◌᷺◌᤻◌̖◌֚b; a◌᷺◌᤻◌̖◌֚b; a◌᷺◌᤻◌̖◌֚b; a◌᷺◌᤻◌̖◌֚b; ) LATIN SMALL LETTER A, LIMBU SIGN SA-I, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 1A17 0062;00E0 05AE 1A17 0315 0062;0061 05AE 0300 1A17 0315 0062;00E0 05AE 1A17 0315 0062;0061 05AE 0300 1A17 0315 0062; # (a◌̕◌̀◌֮◌ᨗb; à◌֮◌ᨗ◌̕b; a◌֮◌̀◌ᨗ◌̕b; à◌֮◌ᨗ◌̕b; a◌֮◌̀◌ᨗ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, BUGINESE VOWEL SIGN I, LATIN SMALL LETTER B
0061 1A17 0315 0300 05AE 0062;0061 05AE 1A17 0300 0315 0062;0061 05AE 1A17 0300 0315 0062;0061 05AE 1A17 0300 0315 0062;0061 05AE 1A17 0300 0315 0062; # (a◌ᨗ◌̕◌̀◌֮b; a◌֮◌ᨗ◌̀◌̕b; a◌֮◌ᨗ◌̀◌̕b; a◌֮◌ᨗ◌̀◌̕b; a◌֮◌ᨗ◌̀◌̕b; ) LATIN SMALL LETTER A, BUGINESE VOWEL SIGN I, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 1A18 0062;0061 302A 0316 1A18 059A 0062;0061 302A 0316 1A18 059A 0062;0061 302A 0316 1A18 059A 0062;0061 302A 0316 1A18 059A 0062; # (a◌֚◌̖◌〪◌ᨘb; a◌〪◌̖◌ᨘ◌֚b; a◌〪◌̖◌ᨘ◌֚b; a◌〪◌̖◌ᨘ◌֚b; a◌〪◌̖◌ᨘ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, BUGINESE VOWEL SIGN U, LATIN SMALL LETTER B
-0061 1A18 059A 0316 302A 0062;0061 302A 1A18 0316 059A 0062;0061 302A 1A18 0316 059A 0062;0061 302A 1A18 0316 059A 0062;0061 302A 1A18 0316 059A 0062; # (a◌ᨘ◌֚◌̖◌〪b; a◌〪◌ᨘ◌̖◌֚b; a◌〪◌ᨘ◌̖◌֚b; a◌〪◌ᨘ◌̖◌֚b; a◌〪◌ᨘ◌̖◌֚b; ) LATIN SMALL LETTER A, BUGINESE VOWEL SIGN U, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1A18 0062;0061 1DFA 0316 1A18 059A 0062;0061 1DFA 0316 1A18 059A 0062;0061 1DFA 0316 1A18 059A 0062;0061 1DFA 0316 1A18 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, BUGINESE VOWEL SIGN U, LATIN SMALL LETTER B
+0061 1A18 059A 0316 1DFA 0062;0061 1DFA 1A18 0316 059A 0062;0061 1DFA 1A18 0316 059A 0062;0061 1DFA 1A18 0316 059A 0062;0061 1DFA 1A18 0316 059A 0062; # (a◌ᨘ◌֚◌̖◌᷺b; a◌᷺◌ᨘ◌̖◌֚b; a◌᷺◌ᨘ◌̖◌֚b; a◌᷺◌ᨘ◌̖◌֚b; a◌᷺◌ᨘ◌̖◌֚b; ) LATIN SMALL LETTER A, BUGINESE VOWEL SIGN U, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 05B0 094D 3099 1A60 0062;0061 3099 094D 1A60 05B0 0062;0061 3099 094D 1A60 05B0 0062;0061 3099 094D 1A60 05B0 0062;0061 3099 094D 1A60 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, TAI THAM SIGN SAKOT, LATIN SMALL LETTER B
0061 1A60 05B0 094D 3099 0062;0061 3099 1A60 094D 05B0 0062;0061 3099 1A60 094D 05B0 0062;0061 3099 1A60 094D 05B0 0062;0061 3099 1A60 094D 05B0 0062; # (a◌᩠◌ְ◌्◌゙b; a◌゙◌᩠◌्◌ְb; a◌゙◌᩠◌्◌ְb; a◌゙◌᩠◌्◌ְb; a◌゙◌᩠◌्◌ְb; ) LATIN SMALL LETTER A, TAI THAM SIGN SAKOT, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
0061 0315 0300 05AE 1A75 0062;00E0 05AE 1A75 0315 0062;0061 05AE 0300 1A75 0315 0062;00E0 05AE 1A75 0315 0062;0061 05AE 0300 1A75 0315 0062; # (a◌̕◌̀◌֮◌᩵b; à◌֮◌᩵◌̕b; a◌֮◌̀◌᩵◌̕b; à◌֮◌᩵◌̕b; a◌֮◌̀◌᩵◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI THAM SIGN TONE-1, LATIN SMALL LETTER B
@@ -17799,8 +17896,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 1A7B 0315 0300 05AE 0062;0061 05AE 1A7B 0300 0315 0062;0061 05AE 1A7B 0300 0315 0062;0061 05AE 1A7B 0300 0315 0062;0061 05AE 1A7B 0300 0315 0062; # (a◌᩻◌̕◌̀◌֮b; a◌֮◌᩻◌̀◌̕b; a◌֮◌᩻◌̀◌̕b; a◌֮◌᩻◌̀◌̕b; a◌֮◌᩻◌̀◌̕b; ) LATIN SMALL LETTER A, TAI THAM SIGN MAI SAM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1A7C 0062;00E0 05AE 1A7C 0315 0062;0061 05AE 0300 1A7C 0315 0062;00E0 05AE 1A7C 0315 0062;0061 05AE 0300 1A7C 0315 0062; # (a◌̕◌̀◌֮◌᩼b; à◌֮◌᩼◌̕b; a◌֮◌̀◌᩼◌̕b; à◌֮◌᩼◌̕b; a◌֮◌̀◌᩼◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI THAM SIGN KHUEN-LUE KARAN, LATIN SMALL LETTER B
0061 1A7C 0315 0300 05AE 0062;0061 05AE 1A7C 0300 0315 0062;0061 05AE 1A7C 0300 0315 0062;0061 05AE 1A7C 0300 0315 0062;0061 05AE 1A7C 0300 0315 0062; # (a◌᩼◌̕◌̀◌֮b; a◌֮◌᩼◌̀◌̕b; a◌֮◌᩼◌̀◌̕b; a◌֮◌᩼◌̀◌̕b; a◌֮◌᩼◌̀◌̕b; ) LATIN SMALL LETTER A, TAI THAM SIGN KHUEN-LUE KARAN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 1A7F 0062;0061 302A 0316 1A7F 059A 0062;0061 302A 0316 1A7F 059A 0062;0061 302A 0316 1A7F 059A 0062;0061 302A 0316 1A7F 059A 0062; # (a◌֚◌̖◌〪◌᩿b; a◌〪◌̖◌᩿◌֚b; a◌〪◌̖◌᩿◌֚b; a◌〪◌̖◌᩿◌֚b; a◌〪◌̖◌᩿◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, TAI THAM COMBINING CRYPTOGRAMMIC DOT, LATIN SMALL LETTER B
-0061 1A7F 059A 0316 302A 0062;0061 302A 1A7F 0316 059A 0062;0061 302A 1A7F 0316 059A 0062;0061 302A 1A7F 0316 059A 0062;0061 302A 1A7F 0316 059A 0062; # (a◌᩿◌֚◌̖◌〪b; a◌〪◌᩿◌̖◌֚b; a◌〪◌᩿◌̖◌֚b; a◌〪◌᩿◌̖◌֚b; a◌〪◌᩿◌̖◌֚b; ) LATIN SMALL LETTER A, TAI THAM COMBINING CRYPTOGRAMMIC DOT, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1A7F 0062;0061 1DFA 0316 1A7F 059A 0062;0061 1DFA 0316 1A7F 059A 0062;0061 1DFA 0316 1A7F 059A 0062;0061 1DFA 0316 1A7F 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, TAI THAM COMBINING CRYPTOGRAMMIC DOT, LATIN SMALL LETTER B
+0061 1A7F 059A 0316 1DFA 0062;0061 1DFA 1A7F 0316 059A 0062;0061 1DFA 1A7F 0316 059A 0062;0061 1DFA 1A7F 0316 059A 0062;0061 1DFA 1A7F 0316 059A 0062; # (a◌᩿◌֚◌̖◌᷺b; a◌᷺◌᩿◌̖◌֚b; a◌᷺◌᩿◌̖◌֚b; a◌᷺◌᩿◌̖◌֚b; a◌᷺◌᩿◌̖◌֚b; ) LATIN SMALL LETTER A, TAI THAM COMBINING CRYPTOGRAMMIC DOT, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 1AB0 0062;00E0 05AE 1AB0 0315 0062;0061 05AE 0300 1AB0 0315 0062;00E0 05AE 1AB0 0315 0062;0061 05AE 0300 1AB0 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 DOUBLED CIRCUMFLEX ACCENT, LATIN SMALL LETTER B
0061 1AB0 0315 0300 05AE 0062;0061 05AE 1AB0 0300 0315 0062;0061 05AE 1AB0 0300 0315 0062;0061 05AE 1AB0 0300 0315 0062;0061 05AE 1AB0 0300 0315 0062; # (a◌᪰◌̕◌̀◌֮b; a◌֮◌᪰◌̀◌̕b; a◌֮◌᪰◌̀◌̕b; a◌֮◌᪰◌̀◌̕b; a◌֮◌᪰◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOUBLED CIRCUMFLEX ACCENT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1AB1 0062;00E0 05AE 1AB1 0315 0062;0061 05AE 0300 1AB1 0315 0062;00E0 05AE 1AB1 0315 0062;0061 05AE 0300 1AB1 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 DIAERESIS-RING, LATIN SMALL LETTER B
@@ -17811,36 +17908,64 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 1AB3 0315 0300 05AE 0062;0061 05AE 1AB3 0300 0315 0062;0061 05AE 1AB3 0300 0315 0062;0061 05AE 1AB3 0300 0315 0062;0061 05AE 1AB3 0300 0315 0062; # (a◌᪳◌̕◌̀◌֮b; a◌֮◌᪳◌̀◌̕b; a◌֮◌᪳◌̀◌̕b; a◌֮◌᪳◌̀◌̕b; a◌֮◌᪳◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOWNWARDS ARROW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1AB4 0062;00E0 05AE 1AB4 0315 0062;0061 05AE 0300 1AB4 0315 0062;00E0 05AE 1AB4 0315 0062;0061 05AE 0300 1AB4 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 TRIPLE DOT, LATIN SMALL LETTER B
0061 1AB4 0315 0300 05AE 0062;0061 05AE 1AB4 0300 0315 0062;0061 05AE 1AB4 0300 0315 0062;0061 05AE 1AB4 0300 0315 0062;0061 05AE 1AB4 0300 0315 0062; # (a◌᪴◌̕◌̀◌֮b; a◌֮◌᪴◌̀◌̕b; a◌֮◌᪴◌̀◌̕b; a◌֮◌᪴◌̀◌̕b; a◌֮◌᪴◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING TRIPLE DOT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 1AB5 0062;0061 302A 0316 1AB5 059A 0062;0061 302A 0316 1AB5 059A 0062;0061 302A 0316 1AB5 059A 0062;0061 302A 0316 1AB5 059A 0062; # (a◌֚◌̖◌〪◌᪵b; a◌〪◌̖◌᪵◌֚b; a◌〪◌̖◌᪵◌֚b; a◌〪◌̖◌᪵◌֚b; a◌〪◌̖◌᪵◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING X-X BELOW, LATIN SMALL LETTER B
-0061 1AB5 059A 0316 302A 0062;0061 302A 1AB5 0316 059A 0062;0061 302A 1AB5 0316 059A 0062;0061 302A 1AB5 0316 059A 0062;0061 302A 1AB5 0316 059A 0062; # (a◌᪵◌֚◌̖◌〪b; a◌〪◌᪵◌̖◌֚b; a◌〪◌᪵◌̖◌֚b; a◌〪◌᪵◌̖◌֚b; a◌〪◌᪵◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING X-X BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1AB6 0062;0061 302A 0316 1AB6 059A 0062;0061 302A 0316 1AB6 059A 0062;0061 302A 0316 1AB6 059A 0062;0061 302A 0316 1AB6 059A 0062; # (a◌֚◌̖◌〪◌᪶b; a◌〪◌̖◌᪶◌֚b; a◌〪◌̖◌᪶◌֚b; a◌〪◌̖◌᪶◌֚b; a◌〪◌̖◌᪶◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING WIGGLY LINE BELOW, LATIN SMALL LETTER B
-0061 1AB6 059A 0316 302A 0062;0061 302A 1AB6 0316 059A 0062;0061 302A 1AB6 0316 059A 0062;0061 302A 1AB6 0316 059A 0062;0061 302A 1AB6 0316 059A 0062; # (a◌᪶◌֚◌̖◌〪b; a◌〪◌᪶◌̖◌֚b; a◌〪◌᪶◌̖◌֚b; a◌〪◌᪶◌̖◌֚b; a◌〪◌᪶◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING WIGGLY LINE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1AB7 0062;0061 302A 0316 1AB7 059A 0062;0061 302A 0316 1AB7 059A 0062;0061 302A 0316 1AB7 059A 0062;0061 302A 0316 1AB7 059A 0062; # (a◌֚◌̖◌〪◌᪷b; a◌〪◌̖◌᪷◌֚b; a◌〪◌̖◌᪷◌֚b; a◌〪◌̖◌᪷◌֚b; a◌〪◌̖◌᪷◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING OPEN MARK BELOW, LATIN SMALL LETTER B
-0061 1AB7 059A 0316 302A 0062;0061 302A 1AB7 0316 059A 0062;0061 302A 1AB7 0316 059A 0062;0061 302A 1AB7 0316 059A 0062;0061 302A 1AB7 0316 059A 0062; # (a◌᪷◌֚◌̖◌〪b; a◌〪◌᪷◌̖◌֚b; a◌〪◌᪷◌̖◌֚b; a◌〪◌᪷◌̖◌֚b; a◌〪◌᪷◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING OPEN MARK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1AB8 0062;0061 302A 0316 1AB8 059A 0062;0061 302A 0316 1AB8 059A 0062;0061 302A 0316 1AB8 059A 0062;0061 302A 0316 1AB8 059A 0062; # (a◌֚◌̖◌〪◌᪸b; a◌〪◌̖◌᪸◌֚b; a◌〪◌̖◌᪸◌֚b; a◌〪◌̖◌᪸◌֚b; a◌〪◌̖◌᪸◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING DOUBLE OPEN MARK BELOW, LATIN SMALL LETTER B
-0061 1AB8 059A 0316 302A 0062;0061 302A 1AB8 0316 059A 0062;0061 302A 1AB8 0316 059A 0062;0061 302A 1AB8 0316 059A 0062;0061 302A 1AB8 0316 059A 0062; # (a◌᪸◌֚◌̖◌〪b; a◌〪◌᪸◌̖◌֚b; a◌〪◌᪸◌̖◌֚b; a◌〪◌᪸◌̖◌֚b; a◌〪◌᪸◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOUBLE OPEN MARK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1AB9 0062;0061 302A 0316 1AB9 059A 0062;0061 302A 0316 1AB9 059A 0062;0061 302A 0316 1AB9 059A 0062;0061 302A 0316 1AB9 059A 0062; # (a◌֚◌̖◌〪◌᪹b; a◌〪◌̖◌᪹◌֚b; a◌〪◌̖◌᪹◌֚b; a◌〪◌̖◌᪹◌֚b; a◌〪◌̖◌᪹◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LIGHT CENTRALIZATION STROKE BELOW, LATIN SMALL LETTER B
-0061 1AB9 059A 0316 302A 0062;0061 302A 1AB9 0316 059A 0062;0061 302A 1AB9 0316 059A 0062;0061 302A 1AB9 0316 059A 0062;0061 302A 1AB9 0316 059A 0062; # (a◌᪹◌֚◌̖◌〪b; a◌〪◌᪹◌̖◌֚b; a◌〪◌᪹◌̖◌֚b; a◌〪◌᪹◌̖◌֚b; a◌〪◌᪹◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LIGHT CENTRALIZATION STROKE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1ABA 0062;0061 302A 0316 1ABA 059A 0062;0061 302A 0316 1ABA 059A 0062;0061 302A 0316 1ABA 059A 0062;0061 302A 0316 1ABA 059A 0062; # (a◌֚◌̖◌〪◌᪺b; a◌〪◌̖◌᪺◌֚b; a◌〪◌̖◌᪺◌֚b; a◌〪◌̖◌᪺◌֚b; a◌〪◌̖◌᪺◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING STRONG CENTRALIZATION STROKE BELOW, LATIN SMALL LETTER B
-0061 1ABA 059A 0316 302A 0062;0061 302A 1ABA 0316 059A 0062;0061 302A 1ABA 0316 059A 0062;0061 302A 1ABA 0316 059A 0062;0061 302A 1ABA 0316 059A 0062; # (a◌᪺◌֚◌̖◌〪b; a◌〪◌᪺◌̖◌֚b; a◌〪◌᪺◌̖◌֚b; a◌〪◌᪺◌̖◌֚b; a◌〪◌᪺◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING STRONG CENTRALIZATION STROKE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1AB5 0062;0061 1DFA 0316 1AB5 059A 0062;0061 1DFA 0316 1AB5 059A 0062;0061 1DFA 0316 1AB5 059A 0062;0061 1DFA 0316 1AB5 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, COMBINING X-X BELOW, LATIN SMALL LETTER B
+0061 1AB5 059A 0316 1DFA 0062;0061 1DFA 1AB5 0316 059A 0062;0061 1DFA 1AB5 0316 059A 0062;0061 1DFA 1AB5 0316 059A 0062;0061 1DFA 1AB5 0316 059A 0062; # (a◌᪵◌֚◌̖◌᷺b; a◌᷺◌᪵◌̖◌֚b; a◌᷺◌᪵◌̖◌֚b; a◌᷺◌᪵◌̖◌֚b; a◌᷺◌᪵◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING X-X BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1AB6 0062;0061 1DFA 0316 1AB6 059A 0062;0061 1DFA 0316 1AB6 059A 0062;0061 1DFA 0316 1AB6 059A 0062;0061 1DFA 0316 1AB6 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, COMBINING WIGGLY LINE BELOW, LATIN SMALL LETTER B
+0061 1AB6 059A 0316 1DFA 0062;0061 1DFA 1AB6 0316 059A 0062;0061 1DFA 1AB6 0316 059A 0062;0061 1DFA 1AB6 0316 059A 0062;0061 1DFA 1AB6 0316 059A 0062; # (a◌᪶◌֚◌̖◌᷺b; a◌᷺◌᪶◌̖◌֚b; a◌᷺◌᪶◌̖◌֚b; a◌᷺◌᪶◌̖◌֚b; a◌᷺◌᪶◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING WIGGLY LINE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1AB7 0062;0061 1DFA 0316 1AB7 059A 0062;0061 1DFA 0316 1AB7 059A 0062;0061 1DFA 0316 1AB7 059A 0062;0061 1DFA 0316 1AB7 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, COMBINING OPEN MARK BELOW, LATIN SMALL LETTER B
+0061 1AB7 059A 0316 1DFA 0062;0061 1DFA 1AB7 0316 059A 0062;0061 1DFA 1AB7 0316 059A 0062;0061 1DFA 1AB7 0316 059A 0062;0061 1DFA 1AB7 0316 059A 0062; # (a◌᪷◌֚◌̖◌᷺b; a◌᷺◌᪷◌̖◌֚b; a◌᷺◌᪷◌̖◌֚b; a◌᷺◌᪷◌̖◌֚b; a◌᷺◌᪷◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING OPEN MARK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1AB8 0062;0061 1DFA 0316 1AB8 059A 0062;0061 1DFA 0316 1AB8 059A 0062;0061 1DFA 0316 1AB8 059A 0062;0061 1DFA 0316 1AB8 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, COMBINING DOUBLE OPEN MARK BELOW, LATIN SMALL LETTER B
+0061 1AB8 059A 0316 1DFA 0062;0061 1DFA 1AB8 0316 059A 0062;0061 1DFA 1AB8 0316 059A 0062;0061 1DFA 1AB8 0316 059A 0062;0061 1DFA 1AB8 0316 059A 0062; # (a◌᪸◌֚◌̖◌᷺b; a◌᷺◌᪸◌̖◌֚b; a◌᷺◌᪸◌̖◌֚b; a◌᷺◌᪸◌̖◌֚b; a◌᷺◌᪸◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOUBLE OPEN MARK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1AB9 0062;0061 1DFA 0316 1AB9 059A 0062;0061 1DFA 0316 1AB9 059A 0062;0061 1DFA 0316 1AB9 059A 0062;0061 1DFA 0316 1AB9 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, COMBINING LIGHT CENTRALIZATION STROKE BELOW, LATIN SMALL LETTER B
+0061 1AB9 059A 0316 1DFA 0062;0061 1DFA 1AB9 0316 059A 0062;0061 1DFA 1AB9 0316 059A 0062;0061 1DFA 1AB9 0316 059A 0062;0061 1DFA 1AB9 0316 059A 0062; # (a◌᪹◌֚◌̖◌᷺b; a◌᷺◌᪹◌̖◌֚b; a◌᷺◌᪹◌̖◌֚b; a◌᷺◌᪹◌̖◌֚b; a◌᷺◌᪹◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LIGHT CENTRALIZATION STROKE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1ABA 0062;0061 1DFA 0316 1ABA 059A 0062;0061 1DFA 0316 1ABA 059A 0062;0061 1DFA 0316 1ABA 059A 0062;0061 1DFA 0316 1ABA 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, COMBINING STRONG CENTRALIZATION STROKE BELOW, LATIN SMALL LETTER B
+0061 1ABA 059A 0316 1DFA 0062;0061 1DFA 1ABA 0316 059A 0062;0061 1DFA 1ABA 0316 059A 0062;0061 1DFA 1ABA 0316 059A 0062;0061 1DFA 1ABA 0316 059A 0062; # (a◌᪺◌֚◌̖◌᷺b; a◌᷺◌᪺◌̖◌֚b; a◌᷺◌᪺◌̖◌֚b; a◌᷺◌᪺◌̖◌֚b; a◌᷺◌᪺◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING STRONG CENTRALIZATION STROKE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 1ABB 0062;00E0 05AE 1ABB 0315 0062;0061 05AE 0300 1ABB 0315 0062;00E0 05AE 1ABB 0315 0062;0061 05AE 0300 1ABB 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 PARENTHESES ABOVE, LATIN SMALL LETTER B
0061 1ABB 0315 0300 05AE 0062;0061 05AE 1ABB 0300 0315 0062;0061 05AE 1ABB 0300 0315 0062;0061 05AE 1ABB 0300 0315 0062;0061 05AE 1ABB 0300 0315 0062; # (a◌᪻◌̕◌̀◌֮b; a◌֮◌᪻◌̀◌̕b; a◌֮◌᪻◌̀◌̕b; a◌֮◌᪻◌̀◌̕b; a◌֮◌᪻◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING PARENTHESES ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1ABC 0062;00E0 05AE 1ABC 0315 0062;0061 05AE 0300 1ABC 0315 0062;00E0 05AE 1ABC 0315 0062;0061 05AE 0300 1ABC 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 DOUBLE PARENTHESES ABOVE, LATIN SMALL LETTER B
0061 1ABC 0315 0300 05AE 0062;0061 05AE 1ABC 0300 0315 0062;0061 05AE 1ABC 0300 0315 0062;0061 05AE 1ABC 0300 0315 0062;0061 05AE 1ABC 0300 0315 0062; # (a◌᪼◌̕◌̀◌֮b; a◌֮◌᪼◌̀◌̕b; a◌֮◌᪼◌̀◌̕b; a◌֮◌᪼◌̀◌̕b; a◌֮◌᪼◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOUBLE PARENTHESES ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 1ABD 0062;0061 302A 0316 1ABD 059A 0062;0061 302A 0316 1ABD 059A 0062;0061 302A 0316 1ABD 059A 0062;0061 302A 0316 1ABD 059A 0062; # (a◌֚◌̖◌〪◌᪽b; a◌〪◌̖◌᪽◌֚b; a◌〪◌̖◌᪽◌֚b; a◌〪◌̖◌᪽◌֚b; a◌〪◌̖◌᪽◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING PARENTHESES BELOW, LATIN SMALL LETTER B
-0061 1ABD 059A 0316 302A 0062;0061 302A 1ABD 0316 059A 0062;0061 302A 1ABD 0316 059A 0062;0061 302A 1ABD 0316 059A 0062;0061 302A 1ABD 0316 059A 0062; # (a◌᪽◌֚◌̖◌〪b; a◌〪◌᪽◌̖◌֚b; a◌〪◌᪽◌̖◌֚b; a◌〪◌᪽◌̖◌֚b; a◌〪◌᪽◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING PARENTHESES BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1ABF 0062;0061 302A 0316 1ABF 059A 0062;0061 302A 0316 1ABF 059A 0062;0061 302A 0316 1ABF 059A 0062;0061 302A 0316 1ABF 059A 0062; # (a◌֚◌̖◌〪◌ᪿb; a◌〪◌̖◌ᪿ◌֚b; a◌〪◌̖◌ᪿ◌֚b; a◌〪◌̖◌ᪿ◌֚b; a◌〪◌̖◌ᪿ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LATIN SMALL LETTER W BELOW, LATIN SMALL LETTER B
-0061 1ABF 059A 0316 302A 0062;0061 302A 1ABF 0316 059A 0062;0061 302A 1ABF 0316 059A 0062;0061 302A 1ABF 0316 059A 0062;0061 302A 1ABF 0316 059A 0062; # (a◌ᪿ◌֚◌̖◌〪b; a◌〪◌ᪿ◌̖◌֚b; a◌〪◌ᪿ◌̖◌֚b; a◌〪◌ᪿ◌̖◌֚b; a◌〪◌ᪿ◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER W BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1AC0 0062;0061 302A 0316 1AC0 059A 0062;0061 302A 0316 1AC0 059A 0062;0061 302A 0316 1AC0 059A 0062;0061 302A 0316 1AC0 059A 0062; # (a◌֚◌̖◌〪◌ᫀb; a◌〪◌̖◌ᫀ◌֚b; a◌〪◌̖◌ᫀ◌֚b; a◌〪◌̖◌ᫀ◌֚b; a◌〪◌̖◌ᫀ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LATIN SMALL LETTER TURNED W BELOW, LATIN SMALL LETTER B
-0061 1AC0 059A 0316 302A 0062;0061 302A 1AC0 0316 059A 0062;0061 302A 1AC0 0316 059A 0062;0061 302A 1AC0 0316 059A 0062;0061 302A 1AC0 0316 059A 0062; # (a◌ᫀ◌֚◌̖◌〪b; a◌〪◌ᫀ◌̖◌֚b; a◌〪◌ᫀ◌̖◌֚b; a◌〪◌ᫀ◌̖◌֚b; a◌〪◌ᫀ◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER TURNED W BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1ABD 0062;0061 1DFA 0316 1ABD 059A 0062;0061 1DFA 0316 1ABD 059A 0062;0061 1DFA 0316 1ABD 059A 0062;0061 1DFA 0316 1ABD 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, COMBINING PARENTHESES BELOW, LATIN SMALL LETTER B
+0061 1ABD 059A 0316 1DFA 0062;0061 1DFA 1ABD 0316 059A 0062;0061 1DFA 1ABD 0316 059A 0062;0061 1DFA 1ABD 0316 059A 0062;0061 1DFA 1ABD 0316 059A 0062; # (a◌᪽◌֚◌̖◌᷺b; a◌᷺◌᪽◌̖◌֚b; a◌᷺◌᪽◌̖◌֚b; a◌᷺◌᪽◌̖◌֚b; a◌᷺◌᪽◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING PARENTHESES BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1ABF 0062;0061 1DFA 0316 1ABF 059A 0062;0061 1DFA 0316 1ABF 059A 0062;0061 1DFA 0316 1ABF 059A 0062;0061 1DFA 0316 1ABF 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, COMBINING LATIN SMALL LETTER W BELOW, LATIN SMALL LETTER B
+0061 1ABF 059A 0316 1DFA 0062;0061 1DFA 1ABF 0316 059A 0062;0061 1DFA 1ABF 0316 059A 0062;0061 1DFA 1ABF 0316 059A 0062;0061 1DFA 1ABF 0316 059A 0062; # (a◌ᪿ◌֚◌̖◌᷺b; a◌᷺◌ᪿ◌̖◌֚b; a◌᷺◌ᪿ◌̖◌֚b; a◌᷺◌ᪿ◌̖◌֚b; a◌᷺◌ᪿ◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER W BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1AC0 0062;0061 1DFA 0316 1AC0 059A 0062;0061 1DFA 0316 1AC0 059A 0062;0061 1DFA 0316 1AC0 059A 0062;0061 1DFA 0316 1AC0 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, COMBINING LATIN SMALL LETTER TURNED W BELOW, LATIN SMALL LETTER B
+0061 1AC0 059A 0316 1DFA 0062;0061 1DFA 1AC0 0316 059A 0062;0061 1DFA 1AC0 0316 059A 0062;0061 1DFA 1AC0 0316 059A 0062;0061 1DFA 1AC0 0316 059A 0062; # (a◌ᫀ◌֚◌̖◌᷺b; a◌᷺◌ᫀ◌̖◌֚b; a◌᷺◌ᫀ◌̖◌֚b; a◌᷺◌ᫀ◌̖◌֚b; a◌᷺◌ᫀ◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER TURNED W BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1AC1 0062;00E0 05AE 1AC1 0315 0062;0061 05AE 0300 1AC1 0315 0062;00E0 05AE 1AC1 0315 0062;0061 05AE 0300 1AC1 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 LEFT PARENTHESIS ABOVE LEFT, LATIN SMALL LETTER B
+0061 1AC1 0315 0300 05AE 0062;0061 05AE 1AC1 0300 0315 0062;0061 05AE 1AC1 0300 0315 0062;0061 05AE 1AC1 0300 0315 0062;0061 05AE 1AC1 0300 0315 0062; # (a◌᫁◌̕◌̀◌֮b; a◌֮◌᫁◌̀◌̕b; a◌֮◌᫁◌̀◌̕b; a◌֮◌᫁◌̀◌̕b; a◌֮◌᫁◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LEFT PARENTHESIS ABOVE LEFT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1AC2 0062;00E0 05AE 1AC2 0315 0062;0061 05AE 0300 1AC2 0315 0062;00E0 05AE 1AC2 0315 0062;0061 05AE 0300 1AC2 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 RIGHT PARENTHESIS ABOVE RIGHT, LATIN SMALL LETTER B
+0061 1AC2 0315 0300 05AE 0062;0061 05AE 1AC2 0300 0315 0062;0061 05AE 1AC2 0300 0315 0062;0061 05AE 1AC2 0300 0315 0062;0061 05AE 1AC2 0300 0315 0062; # (a◌᫂◌̕◌̀◌֮b; a◌֮◌᫂◌̀◌̕b; a◌֮◌᫂◌̀◌̕b; a◌֮◌᫂◌̀◌̕b; a◌֮◌᫂◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING RIGHT PARENTHESIS ABOVE RIGHT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1AC3 0062;0061 1DFA 0316 1AC3 059A 0062;0061 1DFA 0316 1AC3 059A 0062;0061 1DFA 0316 1AC3 059A 0062;0061 1DFA 0316 1AC3 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, COMBINING LEFT PARENTHESIS BELOW LEFT, LATIN SMALL LETTER B
+0061 1AC3 059A 0316 1DFA 0062;0061 1DFA 1AC3 0316 059A 0062;0061 1DFA 1AC3 0316 059A 0062;0061 1DFA 1AC3 0316 059A 0062;0061 1DFA 1AC3 0316 059A 0062; # (a◌᫃◌֚◌̖◌᷺b; a◌᷺◌᫃◌̖◌֚b; a◌᷺◌᫃◌̖◌֚b; a◌᷺◌᫃◌̖◌֚b; a◌᷺◌᫃◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT PARENTHESIS BELOW LEFT, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1AC4 0062;0061 1DFA 0316 1AC4 059A 0062;0061 1DFA 0316 1AC4 059A 0062;0061 1DFA 0316 1AC4 059A 0062;0061 1DFA 0316 1AC4 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, COMBINING RIGHT PARENTHESIS BELOW RIGHT, LATIN SMALL LETTER B
+0061 1AC4 059A 0316 1DFA 0062;0061 1DFA 1AC4 0316 059A 0062;0061 1DFA 1AC4 0316 059A 0062;0061 1DFA 1AC4 0316 059A 0062;0061 1DFA 1AC4 0316 059A 0062; # (a◌᫄◌֚◌̖◌᷺b; a◌᷺◌᫄◌̖◌֚b; a◌᷺◌᫄◌̖◌֚b; a◌᷺◌᫄◌̖◌֚b; a◌᷺◌᫄◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT PARENTHESIS BELOW RIGHT, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1AC5 0062;00E0 05AE 1AC5 0315 0062;0061 05AE 0300 1AC5 0315 0062;00E0 05AE 1AC5 0315 0062;0061 05AE 0300 1AC5 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 SQUARE BRACKETS ABOVE, LATIN SMALL LETTER B
+0061 1AC5 0315 0300 05AE 0062;0061 05AE 1AC5 0300 0315 0062;0061 05AE 1AC5 0300 0315 0062;0061 05AE 1AC5 0300 0315 0062;0061 05AE 1AC5 0300 0315 0062; # (a◌᫅◌̕◌̀◌֮b; a◌֮◌᫅◌̀◌̕b; a◌֮◌᫅◌̀◌̕b; a◌֮◌᫅◌̀◌̕b; a◌֮◌᫅◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING SQUARE BRACKETS ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1AC6 0062;00E0 05AE 1AC6 0315 0062;0061 05AE 0300 1AC6 0315 0062;00E0 05AE 1AC6 0315 0062;0061 05AE 0300 1AC6 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 NUMBER SIGN ABOVE, LATIN SMALL LETTER B
+0061 1AC6 0315 0300 05AE 0062;0061 05AE 1AC6 0300 0315 0062;0061 05AE 1AC6 0300 0315 0062;0061 05AE 1AC6 0300 0315 0062;0061 05AE 1AC6 0300 0315 0062; # (a◌᫆◌̕◌̀◌֮b; a◌֮◌᫆◌̀◌̕b; a◌֮◌᫆◌̀◌̕b; a◌֮◌᫆◌̀◌̕b; a◌֮◌᫆◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING NUMBER SIGN ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1AC7 0062;00E0 05AE 1AC7 0315 0062;0061 05AE 0300 1AC7 0315 0062;00E0 05AE 1AC7 0315 0062;0061 05AE 0300 1AC7 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 INVERTED DOUBLE ARCH ABOVE, LATIN SMALL LETTER B
+0061 1AC7 0315 0300 05AE 0062;0061 05AE 1AC7 0300 0315 0062;0061 05AE 1AC7 0300 0315 0062;0061 05AE 1AC7 0300 0315 0062;0061 05AE 1AC7 0300 0315 0062; # (a◌᫇◌̕◌̀◌֮b; a◌֮◌᫇◌̀◌̕b; a◌֮◌᫇◌̀◌̕b; a◌֮◌᫇◌̀◌̕b; a◌֮◌᫇◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING INVERTED DOUBLE ARCH ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1AC8 0062;00E0 05AE 1AC8 0315 0062;0061 05AE 0300 1AC8 0315 0062;00E0 05AE 1AC8 0315 0062;0061 05AE 0300 1AC8 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 PLUS SIGN ABOVE, LATIN SMALL LETTER B
+0061 1AC8 0315 0300 05AE 0062;0061 05AE 1AC8 0300 0315 0062;0061 05AE 1AC8 0300 0315 0062;0061 05AE 1AC8 0300 0315 0062;0061 05AE 1AC8 0300 0315 0062; # (a◌᫈◌̕◌̀◌֮b; a◌֮◌᫈◌̀◌̕b; a◌֮◌᫈◌̀◌̕b; a◌֮◌᫈◌̀◌̕b; a◌֮◌᫈◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING PLUS SIGN ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1AC9 0062;00E0 05AE 1AC9 0315 0062;0061 05AE 0300 1AC9 0315 0062;00E0 05AE 1AC9 0315 0062;0061 05AE 0300 1AC9 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 DOUBLE PLUS SIGN ABOVE, LATIN SMALL LETTER B
+0061 1AC9 0315 0300 05AE 0062;0061 05AE 1AC9 0300 0315 0062;0061 05AE 1AC9 0300 0315 0062;0061 05AE 1AC9 0300 0315 0062;0061 05AE 1AC9 0300 0315 0062; # (a◌᫉◌̕◌̀◌֮b; a◌֮◌᫉◌̀◌̕b; a◌֮◌᫉◌̀◌̕b; a◌֮◌᫉◌̀◌̕b; a◌֮◌᫉◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOUBLE PLUS SIGN ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1ACA 0062;0061 1DFA 0316 1ACA 059A 0062;0061 1DFA 0316 1ACA 059A 0062;0061 1DFA 0316 1ACA 059A 0062;0061 1DFA 0316 1ACA 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, COMBINING DOUBLE PLUS SIGN BELOW, LATIN SMALL LETTER B
+0061 1ACA 059A 0316 1DFA 0062;0061 1DFA 1ACA 0316 059A 0062;0061 1DFA 1ACA 0316 059A 0062;0061 1DFA 1ACA 0316 059A 0062;0061 1DFA 1ACA 0316 059A 0062; # (a◌᫊◌֚◌̖◌᷺b; a◌᷺◌᫊◌̖◌֚b; a◌᷺◌᫊◌̖◌֚b; a◌᷺◌᫊◌̖◌֚b; a◌᷺◌᫊◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOUBLE PLUS SIGN BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1ACB 0062;00E0 05AE 1ACB 0315 0062;0061 05AE 0300 1ACB 0315 0062;00E0 05AE 1ACB 0315 0062;0061 05AE 0300 1ACB 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 TRIPLE ACUTE ACCENT, LATIN SMALL LETTER B
+0061 1ACB 0315 0300 05AE 0062;0061 05AE 1ACB 0300 0315 0062;0061 05AE 1ACB 0300 0315 0062;0061 05AE 1ACB 0300 0315 0062;0061 05AE 1ACB 0300 0315 0062; # (a◌᫋◌̕◌̀◌֮b; a◌֮◌᫋◌̀◌̕b; a◌֮◌᫋◌̀◌̕b; a◌֮◌᫋◌̀◌̕b; a◌֮◌᫋◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING TRIPLE ACUTE ACCENT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1ACC 0062;00E0 05AE 1ACC 0315 0062;0061 05AE 0300 1ACC 0315 0062;00E0 05AE 1ACC 0315 0062;0061 05AE 0300 1ACC 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 LATIN SMALL LETTER INSULAR G, LATIN SMALL LETTER B
+0061 1ACC 0315 0300 05AE 0062;0061 05AE 1ACC 0300 0315 0062;0061 05AE 1ACC 0300 0315 0062;0061 05AE 1ACC 0300 0315 0062;0061 05AE 1ACC 0300 0315 0062; # (a◌ᫌ◌̕◌̀◌֮b; a◌֮◌ᫌ◌̀◌̕b; a◌֮◌ᫌ◌̀◌̕b; a◌֮◌ᫌ◌̀◌̕b; a◌֮◌ᫌ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER INSULAR G, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1ACD 0062;00E0 05AE 1ACD 0315 0062;0061 05AE 0300 1ACD 0315 0062;00E0 05AE 1ACD 0315 0062;0061 05AE 0300 1ACD 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 LATIN SMALL LETTER INSULAR R, LATIN SMALL LETTER B
+0061 1ACD 0315 0300 05AE 0062;0061 05AE 1ACD 0300 0315 0062;0061 05AE 1ACD 0300 0315 0062;0061 05AE 1ACD 0300 0315 0062;0061 05AE 1ACD 0300 0315 0062; # (a◌ᫍ◌̕◌̀◌֮b; a◌֮◌ᫍ◌̀◌̕b; a◌֮◌ᫍ◌̀◌̕b; a◌֮◌ᫍ◌̀◌̕b; a◌֮◌ᫍ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER INSULAR R, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1ACE 0062;00E0 05AE 1ACE 0315 0062;0061 05AE 0300 1ACE 0315 0062;00E0 05AE 1ACE 0315 0062;0061 05AE 0300 1ACE 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 LATIN SMALL LETTER INSULAR T, LATIN SMALL LETTER B
+0061 1ACE 0315 0300 05AE 0062;0061 05AE 1ACE 0300 0315 0062;0061 05AE 1ACE 0300 0315 0062;0061 05AE 1ACE 0300 0315 0062;0061 05AE 1ACE 0300 0315 0062; # (a◌ᫎ◌̕◌̀◌֮b; a◌֮◌ᫎ◌̀◌̕b; a◌֮◌ᫎ◌̀◌̕b; a◌֮◌ᫎ◌̀◌̕b; a◌֮◌ᫎ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER INSULAR T, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 3099 093C 16FF0 1B34 0062;0061 16FF0 093C 1B34 3099 0062;0061 16FF0 093C 1B34 3099 0062;0061 16FF0 093C 1B34 3099 0062;0061 16FF0 093C 1B34 3099 0062; # (a◌゙◌𖿰़◌᬴b; a𖿰◌़◌᬴◌゙b; a𖿰◌़◌᬴◌゙b; a𖿰◌़◌᬴◌゙b; a𖿰◌़◌᬴◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, VIETNAMESE ALTERNATE READING MARK CA, BALINESE SIGN REREKAN, LATIN SMALL LETTER B
0061 1B34 3099 093C 16FF0 0062;0061 16FF0 1B34 093C 3099 0062;0061 16FF0 1B34 093C 3099 0062;0061 16FF0 1B34 093C 3099 0062;0061 16FF0 1B34 093C 3099 0062; # (a◌᬴◌゙◌𖿰़b; a𖿰◌᬴◌़◌゙b; a𖿰◌᬴◌़◌゙b; a𖿰◌᬴◌़◌゙b; a𖿰◌᬴◌़◌゙b; ) LATIN SMALL LETTER A, BALINESE SIGN REREKAN, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, VIETNAMESE ALTERNATE READING MARK CA, LATIN SMALL LETTER B
0061 05B0 094D 3099 1B44 0062;0061 3099 094D 1B44 05B0 0062;0061 3099 094D 1B44 05B0 0062;0061 3099 094D 1B44 05B0 0062;0061 3099 094D 1B44 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, BALINESE ADEG ADEG, LATIN SMALL LETTER B
0061 1B44 05B0 094D 3099 0062;0061 3099 1B44 094D 05B0 0062;0061 3099 1B44 094D 05B0 0062;0061 3099 1B44 094D 05B0 0062;0061 3099 1B44 094D 05B0 0062; # (a᭄◌ְ◌्◌゙b; a◌゙᭄◌्◌ְb; a◌゙᭄◌्◌ְb; a◌゙᭄◌्◌ְb; a◌゙᭄◌्◌ְb; ) LATIN SMALL LETTER A, BALINESE ADEG ADEG, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
0061 0315 0300 05AE 1B6B 0062;00E0 05AE 1B6B 0315 0062;0061 05AE 0300 1B6B 0315 0062;00E0 05AE 1B6B 0315 0062;0061 05AE 0300 1B6B 0315 0062; # (a◌̕◌̀◌֮◌᭫b; à◌֮◌᭫◌̕b; a◌֮◌̀◌᭫◌̕b; à◌֮◌᭫◌̕b; a◌֮◌̀◌᭫◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, BALINESE MUSICAL SYMBOL COMBINING TEGEH, LATIN SMALL LETTER B
0061 1B6B 0315 0300 05AE 0062;0061 05AE 1B6B 0300 0315 0062;0061 05AE 1B6B 0300 0315 0062;0061 05AE 1B6B 0300 0315 0062;0061 05AE 1B6B 0300 0315 0062; # (a◌᭫◌̕◌̀◌֮b; a◌֮◌᭫◌̀◌̕b; a◌֮◌᭫◌̀◌̕b; a◌֮◌᭫◌̀◌̕b; a◌֮◌᭫◌̀◌̕b; ) LATIN SMALL LETTER A, BALINESE MUSICAL SYMBOL COMBINING TEGEH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 1B6C 0062;0061 302A 0316 1B6C 059A 0062;0061 302A 0316 1B6C 059A 0062;0061 302A 0316 1B6C 059A 0062;0061 302A 0316 1B6C 059A 0062; # (a◌֚◌̖◌〪◌᭬b; a◌〪◌̖◌᭬◌֚b; a◌〪◌̖◌᭬◌֚b; a◌〪◌̖◌᭬◌֚b; a◌〪◌̖◌᭬◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, BALINESE MUSICAL SYMBOL COMBINING ENDEP, LATIN SMALL LETTER B
-0061 1B6C 059A 0316 302A 0062;0061 302A 1B6C 0316 059A 0062;0061 302A 1B6C 0316 059A 0062;0061 302A 1B6C 0316 059A 0062;0061 302A 1B6C 0316 059A 0062; # (a◌᭬◌֚◌̖◌〪b; a◌〪◌᭬◌̖◌֚b; a◌〪◌᭬◌̖◌֚b; a◌〪◌᭬◌̖◌֚b; a◌〪◌᭬◌̖◌֚b; ) LATIN SMALL LETTER A, BALINESE MUSICAL SYMBOL COMBINING ENDEP, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1B6C 0062;0061 1DFA 0316 1B6C 059A 0062;0061 1DFA 0316 1B6C 059A 0062;0061 1DFA 0316 1B6C 059A 0062;0061 1DFA 0316 1B6C 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, BALINESE MUSICAL SYMBOL COMBINING ENDEP, LATIN SMALL LETTER B
+0061 1B6C 059A 0316 1DFA 0062;0061 1DFA 1B6C 0316 059A 0062;0061 1DFA 1B6C 0316 059A 0062;0061 1DFA 1B6C 0316 059A 0062;0061 1DFA 1B6C 0316 059A 0062; # (a◌᭬◌֚◌̖◌᷺b; a◌᷺◌᭬◌̖◌֚b; a◌᷺◌᭬◌̖◌֚b; a◌᷺◌᭬◌̖◌֚b; a◌᷺◌᭬◌̖◌֚b; ) LATIN SMALL LETTER A, BALINESE MUSICAL SYMBOL COMBINING ENDEP, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 1B6D 0062;00E0 05AE 1B6D 0315 0062;0061 05AE 0300 1B6D 0315 0062;00E0 05AE 1B6D 0315 0062;0061 05AE 0300 1B6D 0315 0062; # (a◌̕◌̀◌֮◌᭭b; à◌֮◌᭭◌̕b; a◌֮◌̀◌᭭◌̕b; à◌֮◌᭭◌̕b; a◌֮◌̀◌᭭◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, BALINESE MUSICAL SYMBOL COMBINING KEMPUL, LATIN SMALL LETTER B
0061 1B6D 0315 0300 05AE 0062;0061 05AE 1B6D 0300 0315 0062;0061 05AE 1B6D 0300 0315 0062;0061 05AE 1B6D 0300 0315 0062;0061 05AE 1B6D 0300 0315 0062; # (a◌᭭◌̕◌̀◌֮b; a◌֮◌᭭◌̀◌̕b; a◌֮◌᭭◌̀◌̕b; a◌֮◌᭭◌̀◌̕b; a◌֮◌᭭◌̀◌̕b; ) LATIN SMALL LETTER A, BALINESE MUSICAL SYMBOL COMBINING KEMPUL, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1B6E 0062;00E0 05AE 1B6E 0315 0062;0061 05AE 0300 1B6E 0315 0062;00E0 05AE 1B6E 0315 0062;0061 05AE 0300 1B6E 0315 0062; # (a◌̕◌̀◌֮◌᭮b; à◌֮◌᭮◌̕b; a◌֮◌̀◌᭮◌̕b; à◌֮◌᭮◌̕b; a◌֮◌̀◌᭮◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, BALINESE MUSICAL SYMBOL COMBINING KEMPLI, LATIN SMALL LETTER B
@@ -17875,28 +18000,28 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 1CD2 0315 0300 05AE 0062;0061 05AE 1CD2 0300 0315 0062;0061 05AE 1CD2 0300 0315 0062;0061 05AE 1CD2 0300 0315 0062;0061 05AE 1CD2 0300 0315 0062; # (a◌᳒◌̕◌̀◌֮b; a◌֮◌᳒◌̀◌̕b; a◌֮◌᳒◌̀◌̕b; a◌֮◌᳒◌̀◌̕b; a◌֮◌᳒◌̀◌̕b; ) LATIN SMALL LETTER A, VEDIC TONE PRENKHA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 16FF0 0334 1CD4 0062;0061 0334 1CD4 16FF0 0062;0061 0334 1CD4 16FF0 0062;0061 0334 1CD4 16FF0 0062;0061 0334 1CD4 16FF0 0062; # (a𖿰◌̴◌᳔b; a◌̴◌᳔𖿰b; a◌̴◌᳔𖿰b; a◌̴◌᳔𖿰b; a◌̴◌᳔𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, VEDIC SIGN YAJURVEDIC MIDLINE SVARITA, LATIN SMALL LETTER B
0061 1CD4 16FF0 0334 0062;0061 1CD4 0334 16FF0 0062;0061 1CD4 0334 16FF0 0062;0061 1CD4 0334 16FF0 0062;0061 1CD4 0334 16FF0 0062; # (a◌᳔𖿰◌̴b; a◌᳔◌̴𖿰b; a◌᳔◌̴𖿰b; a◌᳔◌̴𖿰b; a◌᳔◌̴𖿰b; ) LATIN SMALL LETTER A, VEDIC SIGN YAJURVEDIC MIDLINE SVARITA, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
-0061 059A 0316 302A 1CD5 0062;0061 302A 0316 1CD5 059A 0062;0061 302A 0316 1CD5 059A 0062;0061 302A 0316 1CD5 059A 0062;0061 302A 0316 1CD5 059A 0062; # (a◌֚◌̖◌〪◌᳕b; a◌〪◌̖◌᳕◌֚b; a◌〪◌̖◌᳕◌֚b; a◌〪◌̖◌᳕◌֚b; a◌〪◌̖◌᳕◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA, LATIN SMALL LETTER B
-0061 1CD5 059A 0316 302A 0062;0061 302A 1CD5 0316 059A 0062;0061 302A 1CD5 0316 059A 0062;0061 302A 1CD5 0316 059A 0062;0061 302A 1CD5 0316 059A 0062; # (a◌᳕◌֚◌̖◌〪b; a◌〪◌᳕◌̖◌֚b; a◌〪◌᳕◌̖◌֚b; a◌〪◌᳕◌̖◌֚b; a◌〪◌᳕◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1CD6 0062;0061 302A 0316 1CD6 059A 0062;0061 302A 0316 1CD6 059A 0062;0061 302A 0316 1CD6 059A 0062;0061 302A 0316 1CD6 059A 0062; # (a◌֚◌̖◌〪◌᳖b; a◌〪◌̖◌᳖◌֚b; a◌〪◌̖◌᳖◌֚b; a◌〪◌̖◌᳖◌֚b; a◌〪◌̖◌᳖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA, LATIN SMALL LETTER B
-0061 1CD6 059A 0316 302A 0062;0061 302A 1CD6 0316 059A 0062;0061 302A 1CD6 0316 059A 0062;0061 302A 1CD6 0316 059A 0062;0061 302A 1CD6 0316 059A 0062; # (a◌᳖◌֚◌̖◌〪b; a◌〪◌᳖◌̖◌֚b; a◌〪◌᳖◌̖◌֚b; a◌〪◌᳖◌̖◌֚b; a◌〪◌᳖◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1CD7 0062;0061 302A 0316 1CD7 059A 0062;0061 302A 0316 1CD7 059A 0062;0061 302A 0316 1CD7 059A 0062;0061 302A 0316 1CD7 059A 0062; # (a◌֚◌̖◌〪◌᳗b; a◌〪◌̖◌᳗◌֚b; a◌〪◌̖◌᳗◌֚b; a◌〪◌̖◌᳗◌֚b; a◌〪◌̖◌᳗◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA, LATIN SMALL LETTER B
-0061 1CD7 059A 0316 302A 0062;0061 302A 1CD7 0316 059A 0062;0061 302A 1CD7 0316 059A 0062;0061 302A 1CD7 0316 059A 0062;0061 302A 1CD7 0316 059A 0062; # (a◌᳗◌֚◌̖◌〪b; a◌〪◌᳗◌̖◌֚b; a◌〪◌᳗◌̖◌֚b; a◌〪◌᳗◌̖◌֚b; a◌〪◌᳗◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1CD8 0062;0061 302A 0316 1CD8 059A 0062;0061 302A 0316 1CD8 059A 0062;0061 302A 0316 1CD8 059A 0062;0061 302A 0316 1CD8 059A 0062; # (a◌֚◌̖◌〪◌᳘b; a◌〪◌̖◌᳘◌֚b; a◌〪◌̖◌᳘◌֚b; a◌〪◌̖◌᳘◌֚b; a◌〪◌̖◌᳘◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE CANDRA BELOW, LATIN SMALL LETTER B
-0061 1CD8 059A 0316 302A 0062;0061 302A 1CD8 0316 059A 0062;0061 302A 1CD8 0316 059A 0062;0061 302A 1CD8 0316 059A 0062;0061 302A 1CD8 0316 059A 0062; # (a◌᳘◌֚◌̖◌〪b; a◌〪◌᳘◌̖◌֚b; a◌〪◌᳘◌̖◌֚b; a◌〪◌᳘◌̖◌֚b; a◌〪◌᳘◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE CANDRA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1CD9 0062;0061 302A 0316 1CD9 059A 0062;0061 302A 0316 1CD9 059A 0062;0061 302A 0316 1CD9 059A 0062;0061 302A 0316 1CD9 059A 0062; # (a◌֚◌̖◌〪◌᳙b; a◌〪◌̖◌᳙◌֚b; a◌〪◌̖◌᳙◌֚b; a◌〪◌̖◌᳙◌֚b; a◌〪◌̖◌᳙◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER, LATIN SMALL LETTER B
-0061 1CD9 059A 0316 302A 0062;0061 302A 1CD9 0316 059A 0062;0061 302A 1CD9 0316 059A 0062;0061 302A 1CD9 0316 059A 0062;0061 302A 1CD9 0316 059A 0062; # (a◌᳙◌֚◌̖◌〪b; a◌〪◌᳙◌̖◌֚b; a◌〪◌᳙◌̖◌֚b; a◌〪◌᳙◌̖◌֚b; a◌〪◌᳙◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1CD5 0062;0061 1DFA 0316 1CD5 059A 0062;0061 1DFA 0316 1CD5 059A 0062;0061 1DFA 0316 1CD5 059A 0062;0061 1DFA 0316 1CD5 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, VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA, LATIN SMALL LETTER B
+0061 1CD5 059A 0316 1DFA 0062;0061 1DFA 1CD5 0316 059A 0062;0061 1DFA 1CD5 0316 059A 0062;0061 1DFA 1CD5 0316 059A 0062;0061 1DFA 1CD5 0316 059A 0062; # (a◌᳕◌֚◌̖◌᷺b; a◌᷺◌᳕◌̖◌֚b; a◌᷺◌᳕◌̖◌֚b; a◌᷺◌᳕◌̖◌֚b; a◌᷺◌᳕◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1CD6 0062;0061 1DFA 0316 1CD6 059A 0062;0061 1DFA 0316 1CD6 059A 0062;0061 1DFA 0316 1CD6 059A 0062;0061 1DFA 0316 1CD6 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, VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA, LATIN SMALL LETTER B
+0061 1CD6 059A 0316 1DFA 0062;0061 1DFA 1CD6 0316 059A 0062;0061 1DFA 1CD6 0316 059A 0062;0061 1DFA 1CD6 0316 059A 0062;0061 1DFA 1CD6 0316 059A 0062; # (a◌᳖◌֚◌̖◌᷺b; a◌᷺◌᳖◌̖◌֚b; a◌᷺◌᳖◌̖◌֚b; a◌᷺◌᳖◌̖◌֚b; a◌᷺◌᳖◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1CD7 0062;0061 1DFA 0316 1CD7 059A 0062;0061 1DFA 0316 1CD7 059A 0062;0061 1DFA 0316 1CD7 059A 0062;0061 1DFA 0316 1CD7 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, VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA, LATIN SMALL LETTER B
+0061 1CD7 059A 0316 1DFA 0062;0061 1DFA 1CD7 0316 059A 0062;0061 1DFA 1CD7 0316 059A 0062;0061 1DFA 1CD7 0316 059A 0062;0061 1DFA 1CD7 0316 059A 0062; # (a◌᳗◌֚◌̖◌᷺b; a◌᷺◌᳗◌̖◌֚b; a◌᷺◌᳗◌̖◌֚b; a◌᷺◌᳗◌̖◌֚b; a◌᷺◌᳗◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1CD8 0062;0061 1DFA 0316 1CD8 059A 0062;0061 1DFA 0316 1CD8 059A 0062;0061 1DFA 0316 1CD8 059A 0062;0061 1DFA 0316 1CD8 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, VEDIC TONE CANDRA BELOW, LATIN SMALL LETTER B
+0061 1CD8 059A 0316 1DFA 0062;0061 1DFA 1CD8 0316 059A 0062;0061 1DFA 1CD8 0316 059A 0062;0061 1DFA 1CD8 0316 059A 0062;0061 1DFA 1CD8 0316 059A 0062; # (a◌᳘◌֚◌̖◌᷺b; a◌᷺◌᳘◌̖◌֚b; a◌᷺◌᳘◌̖◌֚b; a◌᷺◌᳘◌̖◌֚b; a◌᷺◌᳘◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE CANDRA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1CD9 0062;0061 1DFA 0316 1CD9 059A 0062;0061 1DFA 0316 1CD9 059A 0062;0061 1DFA 0316 1CD9 059A 0062;0061 1DFA 0316 1CD9 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, VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER, LATIN SMALL LETTER B
+0061 1CD9 059A 0316 1DFA 0062;0061 1DFA 1CD9 0316 059A 0062;0061 1DFA 1CD9 0316 059A 0062;0061 1DFA 1CD9 0316 059A 0062;0061 1DFA 1CD9 0316 059A 0062; # (a◌᳙◌֚◌̖◌᷺b; a◌᷺◌᳙◌̖◌֚b; a◌᷺◌᳙◌̖◌֚b; a◌᷺◌᳙◌̖◌֚b; a◌᷺◌᳙◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 1CDA 0062;00E0 05AE 1CDA 0315 0062;0061 05AE 0300 1CDA 0315 0062;00E0 05AE 1CDA 0315 0062;0061 05AE 0300 1CDA 0315 0062; # (a◌̕◌̀◌֮◌᳚b; à◌֮◌᳚◌̕b; a◌֮◌̀◌᳚◌̕b; à◌֮◌᳚◌̕b; a◌֮◌̀◌᳚◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, VEDIC TONE DOUBLE SVARITA, LATIN SMALL LETTER B
0061 1CDA 0315 0300 05AE 0062;0061 05AE 1CDA 0300 0315 0062;0061 05AE 1CDA 0300 0315 0062;0061 05AE 1CDA 0300 0315 0062;0061 05AE 1CDA 0300 0315 0062; # (a◌᳚◌̕◌̀◌֮b; a◌֮◌᳚◌̀◌̕b; a◌֮◌᳚◌̀◌̕b; a◌֮◌᳚◌̀◌̕b; a◌֮◌᳚◌̀◌̕b; ) LATIN SMALL LETTER A, VEDIC TONE DOUBLE SVARITA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1CDB 0062;00E0 05AE 1CDB 0315 0062;0061 05AE 0300 1CDB 0315 0062;00E0 05AE 1CDB 0315 0062;0061 05AE 0300 1CDB 0315 0062; # (a◌̕◌̀◌֮◌᳛b; à◌֮◌᳛◌̕b; a◌֮◌̀◌᳛◌̕b; à◌֮◌᳛◌̕b; a◌֮◌̀◌᳛◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, VEDIC TONE TRIPLE SVARITA, LATIN SMALL LETTER B
0061 1CDB 0315 0300 05AE 0062;0061 05AE 1CDB 0300 0315 0062;0061 05AE 1CDB 0300 0315 0062;0061 05AE 1CDB 0300 0315 0062;0061 05AE 1CDB 0300 0315 0062; # (a◌᳛◌̕◌̀◌֮b; a◌֮◌᳛◌̀◌̕b; a◌֮◌᳛◌̀◌̕b; a◌֮◌᳛◌̀◌̕b; a◌֮◌᳛◌̀◌̕b; ) LATIN SMALL LETTER A, VEDIC TONE TRIPLE SVARITA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 1CDC 0062;0061 302A 0316 1CDC 059A 0062;0061 302A 0316 1CDC 059A 0062;0061 302A 0316 1CDC 059A 0062;0061 302A 0316 1CDC 059A 0062; # (a◌֚◌̖◌〪◌᳜b; a◌〪◌̖◌᳜◌֚b; a◌〪◌̖◌᳜◌֚b; a◌〪◌̖◌᳜◌֚b; a◌〪◌̖◌᳜◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE KATHAKA ANUDATTA, LATIN SMALL LETTER B
-0061 1CDC 059A 0316 302A 0062;0061 302A 1CDC 0316 059A 0062;0061 302A 1CDC 0316 059A 0062;0061 302A 1CDC 0316 059A 0062;0061 302A 1CDC 0316 059A 0062; # (a◌᳜◌֚◌̖◌〪b; a◌〪◌᳜◌̖◌֚b; a◌〪◌᳜◌̖◌֚b; a◌〪◌᳜◌̖◌֚b; a◌〪◌᳜◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE KATHAKA ANUDATTA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1CDD 0062;0061 302A 0316 1CDD 059A 0062;0061 302A 0316 1CDD 059A 0062;0061 302A 0316 1CDD 059A 0062;0061 302A 0316 1CDD 059A 0062; # (a◌֚◌̖◌〪◌᳝b; a◌〪◌̖◌᳝◌֚b; a◌〪◌̖◌᳝◌֚b; a◌〪◌̖◌᳝◌֚b; a◌〪◌̖◌᳝◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE DOT BELOW, LATIN SMALL LETTER B
-0061 1CDD 059A 0316 302A 0062;0061 302A 1CDD 0316 059A 0062;0061 302A 1CDD 0316 059A 0062;0061 302A 1CDD 0316 059A 0062;0061 302A 1CDD 0316 059A 0062; # (a◌᳝◌֚◌̖◌〪b; a◌〪◌᳝◌̖◌֚b; a◌〪◌᳝◌̖◌֚b; a◌〪◌᳝◌̖◌֚b; a◌〪◌᳝◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1CDE 0062;0061 302A 0316 1CDE 059A 0062;0061 302A 0316 1CDE 059A 0062;0061 302A 0316 1CDE 059A 0062;0061 302A 0316 1CDE 059A 0062; # (a◌֚◌̖◌〪◌᳞b; a◌〪◌̖◌᳞◌֚b; a◌〪◌̖◌᳞◌֚b; a◌〪◌̖◌᳞◌֚b; a◌〪◌̖◌᳞◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE TWO DOTS BELOW, LATIN SMALL LETTER B
-0061 1CDE 059A 0316 302A 0062;0061 302A 1CDE 0316 059A 0062;0061 302A 1CDE 0316 059A 0062;0061 302A 1CDE 0316 059A 0062;0061 302A 1CDE 0316 059A 0062; # (a◌᳞◌֚◌̖◌〪b; a◌〪◌᳞◌̖◌֚b; a◌〪◌᳞◌̖◌֚b; a◌〪◌᳞◌̖◌֚b; a◌〪◌᳞◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE TWO DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1CDF 0062;0061 302A 0316 1CDF 059A 0062;0061 302A 0316 1CDF 059A 0062;0061 302A 0316 1CDF 059A 0062;0061 302A 0316 1CDF 059A 0062; # (a◌֚◌̖◌〪◌᳟b; a◌〪◌̖◌᳟◌֚b; a◌〪◌̖◌᳟◌֚b; a◌〪◌̖◌᳟◌֚b; a◌〪◌̖◌᳟◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE THREE DOTS BELOW, LATIN SMALL LETTER B
-0061 1CDF 059A 0316 302A 0062;0061 302A 1CDF 0316 059A 0062;0061 302A 1CDF 0316 059A 0062;0061 302A 1CDF 0316 059A 0062;0061 302A 1CDF 0316 059A 0062; # (a◌᳟◌֚◌̖◌〪b; a◌〪◌᳟◌̖◌֚b; a◌〪◌᳟◌̖◌֚b; a◌〪◌᳟◌̖◌֚b; a◌〪◌᳟◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE THREE DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1CDC 0062;0061 1DFA 0316 1CDC 059A 0062;0061 1DFA 0316 1CDC 059A 0062;0061 1DFA 0316 1CDC 059A 0062;0061 1DFA 0316 1CDC 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, VEDIC TONE KATHAKA ANUDATTA, LATIN SMALL LETTER B
+0061 1CDC 059A 0316 1DFA 0062;0061 1DFA 1CDC 0316 059A 0062;0061 1DFA 1CDC 0316 059A 0062;0061 1DFA 1CDC 0316 059A 0062;0061 1DFA 1CDC 0316 059A 0062; # (a◌᳜◌֚◌̖◌᷺b; a◌᷺◌᳜◌̖◌֚b; a◌᷺◌᳜◌̖◌֚b; a◌᷺◌᳜◌̖◌֚b; a◌᷺◌᳜◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE KATHAKA ANUDATTA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1CDD 0062;0061 1DFA 0316 1CDD 059A 0062;0061 1DFA 0316 1CDD 059A 0062;0061 1DFA 0316 1CDD 059A 0062;0061 1DFA 0316 1CDD 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, VEDIC TONE DOT BELOW, LATIN SMALL LETTER B
+0061 1CDD 059A 0316 1DFA 0062;0061 1DFA 1CDD 0316 059A 0062;0061 1DFA 1CDD 0316 059A 0062;0061 1DFA 1CDD 0316 059A 0062;0061 1DFA 1CDD 0316 059A 0062; # (a◌᳝◌֚◌̖◌᷺b; a◌᷺◌᳝◌̖◌֚b; a◌᷺◌᳝◌̖◌֚b; a◌᷺◌᳝◌̖◌֚b; a◌᷺◌᳝◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1CDE 0062;0061 1DFA 0316 1CDE 059A 0062;0061 1DFA 0316 1CDE 059A 0062;0061 1DFA 0316 1CDE 059A 0062;0061 1DFA 0316 1CDE 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, VEDIC TONE TWO DOTS BELOW, LATIN SMALL LETTER B
+0061 1CDE 059A 0316 1DFA 0062;0061 1DFA 1CDE 0316 059A 0062;0061 1DFA 1CDE 0316 059A 0062;0061 1DFA 1CDE 0316 059A 0062;0061 1DFA 1CDE 0316 059A 0062; # (a◌᳞◌֚◌̖◌᷺b; a◌᷺◌᳞◌̖◌֚b; a◌᷺◌᳞◌̖◌֚b; a◌᷺◌᳞◌̖◌֚b; a◌᷺◌᳞◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE TWO DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1CDF 0062;0061 1DFA 0316 1CDF 059A 0062;0061 1DFA 0316 1CDF 059A 0062;0061 1DFA 0316 1CDF 059A 0062;0061 1DFA 0316 1CDF 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, VEDIC TONE THREE DOTS BELOW, LATIN SMALL LETTER B
+0061 1CDF 059A 0316 1DFA 0062;0061 1DFA 1CDF 0316 059A 0062;0061 1DFA 1CDF 0316 059A 0062;0061 1DFA 1CDF 0316 059A 0062;0061 1DFA 1CDF 0316 059A 0062; # (a◌᳟◌֚◌̖◌᷺b; a◌᷺◌᳟◌̖◌֚b; a◌᷺◌᳟◌̖◌֚b; a◌᷺◌᳟◌̖◌֚b; a◌᷺◌᳟◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE THREE DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 1CE0 0062;00E0 05AE 1CE0 0315 0062;0061 05AE 0300 1CE0 0315 0062;00E0 05AE 1CE0 0315 0062;0061 05AE 0300 1CE0 0315 0062; # (a◌̕◌̀◌֮◌᳠b; à◌֮◌᳠◌̕b; a◌֮◌̀◌᳠◌̕b; à◌֮◌᳠◌̕b; a◌֮◌̀◌᳠◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA, LATIN SMALL LETTER B
0061 1CE0 0315 0300 05AE 0062;0061 05AE 1CE0 0300 0315 0062;0061 05AE 1CE0 0300 0315 0062;0061 05AE 1CE0 0300 0315 0062;0061 05AE 1CE0 0300 0315 0062; # (a◌᳠◌̕◌̀◌֮b; a◌֮◌᳠◌̀◌̕b; a◌֮◌᳠◌̀◌̕b; a◌֮◌᳠◌̀◌̕b; a◌֮◌᳠◌̀◌̕b; ) LATIN SMALL LETTER A, VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 16FF0 0334 1CE2 0062;0061 0334 1CE2 16FF0 0062;0061 0334 1CE2 16FF0 0062;0061 0334 1CE2 16FF0 0062;0061 0334 1CE2 16FF0 0062; # (a𖿰◌̴◌᳢b; a◌̴◌᳢𖿰b; a◌̴◌᳢𖿰b; a◌̴◌᳢𖿰b; a◌̴◌᳢𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, VEDIC SIGN VISARGA SVARITA, LATIN SMALL LETTER B
@@ -17913,8 +18038,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 1CE7 16FF0 0334 0062;0061 1CE7 0334 16FF0 0062;0061 1CE7 0334 16FF0 0062;0061 1CE7 0334 16FF0 0062;0061 1CE7 0334 16FF0 0062; # (a◌᳧𖿰◌̴b; a◌᳧◌̴𖿰b; a◌᳧◌̴𖿰b; a◌᳧◌̴𖿰b; a◌᳧◌̴𖿰b; ) LATIN SMALL LETTER A, VEDIC SIGN VISARGA UDATTA WITH TAIL, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
0061 16FF0 0334 1CE8 0062;0061 0334 1CE8 16FF0 0062;0061 0334 1CE8 16FF0 0062;0061 0334 1CE8 16FF0 0062;0061 0334 1CE8 16FF0 0062; # (a𖿰◌̴◌᳨b; a◌̴◌᳨𖿰b; a◌̴◌᳨𖿰b; a◌̴◌᳨𖿰b; a◌̴◌᳨𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, VEDIC SIGN VISARGA ANUDATTA WITH TAIL, LATIN SMALL LETTER B
0061 1CE8 16FF0 0334 0062;0061 1CE8 0334 16FF0 0062;0061 1CE8 0334 16FF0 0062;0061 1CE8 0334 16FF0 0062;0061 1CE8 0334 16FF0 0062; # (a◌᳨𖿰◌̴b; a◌᳨◌̴𖿰b; a◌᳨◌̴𖿰b; a◌᳨◌̴𖿰b; a◌᳨◌̴𖿰b; ) LATIN SMALL LETTER A, VEDIC SIGN VISARGA ANUDATTA WITH TAIL, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
-0061 059A 0316 302A 1CED 0062;0061 302A 0316 1CED 059A 0062;0061 302A 0316 1CED 059A 0062;0061 302A 0316 1CED 059A 0062;0061 302A 0316 1CED 059A 0062; # (a◌֚◌̖◌〪◌᳭b; a◌〪◌̖◌᳭◌֚b; a◌〪◌̖◌᳭◌֚b; a◌〪◌̖◌᳭◌֚b; a◌〪◌̖◌᳭◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC SIGN TIRYAK, LATIN SMALL LETTER B
-0061 1CED 059A 0316 302A 0062;0061 302A 1CED 0316 059A 0062;0061 302A 1CED 0316 059A 0062;0061 302A 1CED 0316 059A 0062;0061 302A 1CED 0316 059A 0062; # (a◌᳭◌֚◌̖◌〪b; a◌〪◌᳭◌̖◌֚b; a◌〪◌᳭◌̖◌֚b; a◌〪◌᳭◌̖◌֚b; a◌〪◌᳭◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC SIGN TIRYAK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1CED 0062;0061 1DFA 0316 1CED 059A 0062;0061 1DFA 0316 1CED 059A 0062;0061 1DFA 0316 1CED 059A 0062;0061 1DFA 0316 1CED 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, VEDIC SIGN TIRYAK, LATIN SMALL LETTER B
+0061 1CED 059A 0316 1DFA 0062;0061 1DFA 1CED 0316 059A 0062;0061 1DFA 1CED 0316 059A 0062;0061 1DFA 1CED 0316 059A 0062;0061 1DFA 1CED 0316 059A 0062; # (a◌᳭◌֚◌̖◌᷺b; a◌᷺◌᳭◌̖◌֚b; a◌᷺◌᳭◌̖◌֚b; a◌᷺◌᳭◌̖◌֚b; a◌᷺◌᳭◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC SIGN TIRYAK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 1CF4 0062;00E0 05AE 1CF4 0315 0062;0061 05AE 0300 1CF4 0315 0062;00E0 05AE 1CF4 0315 0062;0061 05AE 0300 1CF4 0315 0062; # (a◌̕◌̀◌֮◌᳴b; à◌֮◌᳴◌̕b; a◌֮◌̀◌᳴◌̕b; à◌֮◌᳴◌̕b; a◌֮◌̀◌᳴◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, VEDIC TONE CANDRA ABOVE, LATIN SMALL LETTER B
0061 1CF4 0315 0300 05AE 0062;0061 05AE 1CF4 0300 0315 0062;0061 05AE 1CF4 0300 0315 0062;0061 05AE 1CF4 0300 0315 0062;0061 05AE 1CF4 0300 0315 0062; # (a◌᳴◌̕◌̀◌֮b; a◌֮◌᳴◌̀◌̕b; a◌֮◌᳴◌̀◌̕b; a◌֮◌᳴◌̀◌̕b; a◌֮◌᳴◌̀◌̕b; ) LATIN SMALL LETTER A, VEDIC TONE CANDRA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1CF8 0062;00E0 05AE 1CF8 0315 0062;0061 05AE 0300 1CF8 0315 0062;00E0 05AE 1CF8 0315 0062;0061 05AE 0300 1CF8 0315 0062; # (a◌̕◌̀◌֮◌᳸b; à◌֮◌᳸◌̕b; a◌֮◌̀◌᳸◌̕b; à◌֮◌᳸◌̕b; a◌֮◌̀◌᳸◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, VEDIC TONE RING ABOVE, LATIN SMALL LETTER B
@@ -17925,8 +18050,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 1DC0 0315 0300 05AE 0062;0061 05AE 1DC0 0300 0315 0062;0061 05AE 1DC0 0300 0315 0062;0061 05AE 1DC0 0300 0315 0062;0061 05AE 1DC0 0300 0315 0062; # (a◌᷀◌̕◌̀◌֮b; a◌֮◌᷀◌̀◌̕b; a◌֮◌᷀◌̀◌̕b; a◌֮◌᷀◌̀◌̕b; a◌֮◌᷀◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOTTED GRAVE ACCENT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1DC1 0062;00E0 05AE 1DC1 0315 0062;0061 05AE 0300 1DC1 0315 0062;00E0 05AE 1DC1 0315 0062;0061 05AE 0300 1DC1 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 DOTTED ACUTE ACCENT, LATIN SMALL LETTER B
0061 1DC1 0315 0300 05AE 0062;0061 05AE 1DC1 0300 0315 0062;0061 05AE 1DC1 0300 0315 0062;0061 05AE 1DC1 0300 0315 0062;0061 05AE 1DC1 0300 0315 0062; # (a◌᷁◌̕◌̀◌֮b; a◌֮◌᷁◌̀◌̕b; a◌֮◌᷁◌̀◌̕b; a◌֮◌᷁◌̀◌̕b; a◌֮◌᷁◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOTTED ACUTE ACCENT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 1DC2 0062;0061 302A 0316 1DC2 059A 0062;0061 302A 0316 1DC2 059A 0062;0061 302A 0316 1DC2 059A 0062;0061 302A 0316 1DC2 059A 0062; # (a◌֚◌̖◌〪◌᷂b; a◌〪◌̖◌᷂◌֚b; a◌〪◌̖◌᷂◌֚b; a◌〪◌̖◌᷂◌֚b; a◌〪◌̖◌᷂◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING SNAKE BELOW, LATIN SMALL LETTER B
-0061 1DC2 059A 0316 302A 0062;0061 302A 1DC2 0316 059A 0062;0061 302A 1DC2 0316 059A 0062;0061 302A 1DC2 0316 059A 0062;0061 302A 1DC2 0316 059A 0062; # (a◌᷂◌֚◌̖◌〪b; a◌〪◌᷂◌̖◌֚b; a◌〪◌᷂◌̖◌֚b; a◌〪◌᷂◌̖◌֚b; a◌〪◌᷂◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING SNAKE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1DC2 0062;0061 1DFA 0316 1DC2 059A 0062;0061 1DFA 0316 1DC2 059A 0062;0061 1DFA 0316 1DC2 059A 0062;0061 1DFA 0316 1DC2 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, COMBINING SNAKE BELOW, LATIN SMALL LETTER B
+0061 1DC2 059A 0316 1DFA 0062;0061 1DFA 1DC2 0316 059A 0062;0061 1DFA 1DC2 0316 059A 0062;0061 1DFA 1DC2 0316 059A 0062;0061 1DFA 1DC2 0316 059A 0062; # (a◌᷂◌֚◌̖◌᷺b; a◌᷺◌᷂◌̖◌֚b; a◌᷺◌᷂◌̖◌֚b; a◌᷺◌᷂◌̖◌֚b; a◌᷺◌᷂◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING SNAKE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 1DC3 0062;00E0 05AE 1DC3 0315 0062;0061 05AE 0300 1DC3 0315 0062;00E0 05AE 1DC3 0315 0062;0061 05AE 0300 1DC3 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 SUSPENSION MARK, LATIN SMALL LETTER B
0061 1DC3 0315 0300 05AE 0062;0061 05AE 1DC3 0300 0315 0062;0061 05AE 1DC3 0300 0315 0062;0061 05AE 1DC3 0300 0315 0062;0061 05AE 1DC3 0300 0315 0062; # (a◌᷃◌̕◌̀◌֮b; a◌֮◌᷃◌̀◌̕b; a◌֮◌᷃◌̀◌̕b; a◌֮◌᷃◌̀◌̕b; a◌֮◌᷃◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING SUSPENSION MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1DC4 0062;00E0 05AE 1DC4 0315 0062;0061 05AE 0300 1DC4 0315 0062;00E0 05AE 1DC4 0315 0062;0061 05AE 0300 1DC4 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 MACRON-ACUTE, LATIN SMALL LETTER B
@@ -17941,8 +18066,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 1DC8 0315 0300 05AE 0062;0061 05AE 1DC8 0300 0315 0062;0061 05AE 1DC8 0300 0315 0062;0061 05AE 1DC8 0300 0315 0062;0061 05AE 1DC8 0300 0315 0062; # (a◌᷈◌̕◌̀◌֮b; a◌֮◌᷈◌̀◌̕b; a◌֮◌᷈◌̀◌̕b; a◌֮◌᷈◌̀◌̕b; a◌֮◌᷈◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRAVE-ACUTE-GRAVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1DC9 0062;00E0 05AE 1DC9 0315 0062;0061 05AE 0300 1DC9 0315 0062;00E0 05AE 1DC9 0315 0062;0061 05AE 0300 1DC9 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 ACUTE-GRAVE-ACUTE, LATIN SMALL LETTER B
0061 1DC9 0315 0300 05AE 0062;0061 05AE 1DC9 0300 0315 0062;0061 05AE 1DC9 0300 0315 0062;0061 05AE 1DC9 0300 0315 0062;0061 05AE 1DC9 0300 0315 0062; # (a◌᷉◌̕◌̀◌֮b; a◌֮◌᷉◌̀◌̕b; a◌֮◌᷉◌̀◌̕b; a◌֮◌᷉◌̀◌̕b; a◌֮◌᷉◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING ACUTE-GRAVE-ACUTE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 1DCA 0062;0061 302A 0316 1DCA 059A 0062;0061 302A 0316 1DCA 059A 0062;0061 302A 0316 1DCA 059A 0062;0061 302A 0316 1DCA 059A 0062; # (a◌֚◌̖◌〪◌᷊b; a◌〪◌̖◌᷊◌֚b; a◌〪◌̖◌᷊◌֚b; a◌〪◌̖◌᷊◌֚b; a◌〪◌̖◌᷊◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LATIN SMALL LETTER R BELOW, LATIN SMALL LETTER B
-0061 1DCA 059A 0316 302A 0062;0061 302A 1DCA 0316 059A 0062;0061 302A 1DCA 0316 059A 0062;0061 302A 1DCA 0316 059A 0062;0061 302A 1DCA 0316 059A 0062; # (a◌᷊◌֚◌̖◌〪b; a◌〪◌᷊◌̖◌֚b; a◌〪◌᷊◌̖◌֚b; a◌〪◌᷊◌̖◌֚b; a◌〪◌᷊◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER R BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1DCA 0062;0061 1DFA 0316 1DCA 059A 0062;0061 1DFA 0316 1DCA 059A 0062;0061 1DFA 0316 1DCA 059A 0062;0061 1DFA 0316 1DCA 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, COMBINING LATIN SMALL LETTER R BELOW, LATIN SMALL LETTER B
+0061 1DCA 059A 0316 1DFA 0062;0061 1DFA 1DCA 0316 059A 0062;0061 1DFA 1DCA 0316 059A 0062;0061 1DFA 1DCA 0316 059A 0062;0061 1DFA 1DCA 0316 059A 0062; # (a◌᷊◌֚◌̖◌᷺b; a◌᷺◌᷊◌̖◌֚b; a◌᷺◌᷊◌̖◌֚b; a◌᷺◌᷊◌̖◌֚b; a◌᷺◌᷊◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER R BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 1DCB 0062;00E0 05AE 1DCB 0315 0062;0061 05AE 0300 1DCB 0315 0062;00E0 05AE 1DCB 0315 0062;0061 05AE 0300 1DCB 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 BREVE-MACRON, LATIN SMALL LETTER B
0061 1DCB 0315 0300 05AE 0062;0061 05AE 1DCB 0300 0315 0062;0061 05AE 1DCB 0300 0315 0062;0061 05AE 1DCB 0300 0315 0062;0061 05AE 1DCB 0300 0315 0062; # (a◌᷋◌̕◌̀◌֮b; a◌֮◌᷋◌̀◌̕b; a◌֮◌᷋◌̀◌̕b; a◌֮◌᷋◌̀◌̕b; a◌֮◌᷋◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING BREVE-MACRON, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1DCC 0062;00E0 05AE 1DCC 0315 0062;0061 05AE 0300 1DCC 0315 0062;00E0 05AE 1DCC 0315 0062;0061 05AE 0300 1DCC 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 MACRON-BREVE, LATIN SMALL LETTER B
@@ -17951,8 +18076,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 1DCD 0345 035D 035C 0062;0061 035C 1DCD 035D 0345 0062;0061 035C 1DCD 035D 0345 0062;0061 035C 1DCD 035D 0345 0062;0061 035C 1DCD 035D 0345 0062; # (a◌᷍◌ͅ◌͝◌͜b; a◌͜◌᷍◌͝◌ͅb; a◌͜◌᷍◌͝◌ͅb; a◌͜◌᷍◌͝◌ͅb; a◌͜◌᷍◌͝◌ͅb; ) LATIN SMALL LETTER A, COMBINING DOUBLE CIRCUMFLEX ABOVE, COMBINING GREEK YPOGEGRAMMENI, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, LATIN SMALL LETTER B
0061 031B 1DCE 0321 1DCE 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062; # (a◌̛◌᷎◌̡◌᷎b; a◌̡◌᷎◌᷎◌̛b; a◌̡◌᷎◌᷎◌̛b; a◌̡◌᷎◌᷎◌̛b; a◌̡◌᷎◌᷎◌̛b; ) LATIN SMALL LETTER A, COMBINING HORN, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
0061 1DCE 031B 1DCE 0321 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062; # (a◌᷎◌̛◌᷎◌̡b; a◌̡◌᷎◌᷎◌̛b; a◌̡◌᷎◌᷎◌̛b; a◌̡◌᷎◌᷎◌̛b; a◌̡◌᷎◌᷎◌̛b; ) LATIN SMALL LETTER A, COMBINING OGONEK ABOVE, COMBINING HORN, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, LATIN SMALL LETTER B
-0061 059A 0316 302A 1DCF 0062;0061 302A 0316 1DCF 059A 0062;0061 302A 0316 1DCF 059A 0062;0061 302A 0316 1DCF 059A 0062;0061 302A 0316 1DCF 059A 0062; # (a◌֚◌̖◌〪◌᷏b; a◌〪◌̖◌᷏◌֚b; a◌〪◌̖◌᷏◌֚b; a◌〪◌̖◌᷏◌֚b; a◌〪◌̖◌᷏◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING ZIGZAG BELOW, LATIN SMALL LETTER B
-0061 1DCF 059A 0316 302A 0062;0061 302A 1DCF 0316 059A 0062;0061 302A 1DCF 0316 059A 0062;0061 302A 1DCF 0316 059A 0062;0061 302A 1DCF 0316 059A 0062; # (a◌᷏◌֚◌̖◌〪b; a◌〪◌᷏◌̖◌֚b; a◌〪◌᷏◌̖◌֚b; a◌〪◌᷏◌̖◌֚b; a◌〪◌᷏◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING ZIGZAG BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1DCF 0062;0061 1DFA 0316 1DCF 059A 0062;0061 1DFA 0316 1DCF 059A 0062;0061 1DFA 0316 1DCF 059A 0062;0061 1DFA 0316 1DCF 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, COMBINING ZIGZAG BELOW, LATIN SMALL LETTER B
+0061 1DCF 059A 0316 1DFA 0062;0061 1DFA 1DCF 0316 059A 0062;0061 1DFA 1DCF 0316 059A 0062;0061 1DFA 1DCF 0316 059A 0062;0061 1DFA 1DCF 0316 059A 0062; # (a◌᷏◌֚◌̖◌᷺b; a◌᷺◌᷏◌̖◌֚b; a◌᷺◌᷏◌̖◌֚b; a◌᷺◌᷏◌̖◌֚b; a◌᷺◌᷏◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING ZIGZAG BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 1DCE 0321 0F74 1DD0 0062;0061 0F74 0321 1DD0 1DCE 0062;0061 0F74 0321 1DD0 1DCE 0062;0061 0F74 0321 1DD0 1DCE 0062;0061 0F74 0321 1DD0 1DCE 0062; # (a◌᷎◌̡◌ུ◌᷐b; a◌ུ◌̡◌᷐◌᷎b; a◌ུ◌̡◌᷐◌᷎b; a◌ུ◌̡◌᷐◌᷎b; a◌ུ◌̡◌᷐◌᷎b; ) LATIN SMALL LETTER A, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, COMBINING IS BELOW, LATIN SMALL LETTER B
0061 1DD0 1DCE 0321 0F74 0062;0061 0F74 1DD0 0321 1DCE 0062;0061 0F74 1DD0 0321 1DCE 0062;0061 0F74 1DD0 0321 1DCE 0062;0061 0F74 1DD0 0321 1DCE 0062; # (a◌᷐◌᷎◌̡◌ུb; a◌ུ◌᷐◌̡◌᷎b; a◌ུ◌᷐◌̡◌᷎b; a◌ུ◌᷐◌̡◌᷎b; a◌ུ◌᷐◌̡◌᷎b; ) LATIN SMALL LETTER A, COMBINING IS BELOW, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, LATIN SMALL LETTER B
0061 0315 0300 05AE 1DD1 0062;00E0 05AE 1DD1 0315 0062;0061 05AE 0300 1DD1 0315 0062;00E0 05AE 1DD1 0315 0062;0061 05AE 0300 1DD1 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 UR ABOVE, LATIN SMALL LETTER B
@@ -18035,18 +18160,20 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 1DF7 0300 05AE 1D16D 0062;00E0 1D16D 1DF7 05AE 0062;0061 1D16D 1DF7 05AE 0300 0062;00E0 1D16D 1DF7 05AE 0062;0061 1D16D 1DF7 05AE 0300 0062; # (a◌᷷◌̀◌𝅭֮b; à𝅭◌᷷◌֮b; a𝅭◌᷷◌֮◌̀b; à𝅭◌᷷◌֮b; a𝅭◌᷷◌֮◌̀b; ) LATIN SMALL LETTER A, COMBINING KAVYKA ABOVE LEFT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, LATIN SMALL LETTER B
0061 0300 05AE 1D16D 1DF8 0062;00E0 1D16D 05AE 1DF8 0062;0061 1D16D 05AE 1DF8 0300 0062;00E0 1D16D 05AE 1DF8 0062;0061 1D16D 05AE 1DF8 0300 0062; # (a◌̀◌𝅭֮◌᷸b; à𝅭◌֮◌᷸b; a𝅭◌֮◌᷸◌̀b; à𝅭◌֮◌᷸b; a𝅭◌֮◌᷸◌̀b; ) LATIN SMALL LETTER A, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, COMBINING DOT ABOVE LEFT, LATIN SMALL LETTER B
0061 1DF8 0300 05AE 1D16D 0062;00E0 1D16D 1DF8 05AE 0062;0061 1D16D 1DF8 05AE 0300 0062;00E0 1D16D 1DF8 05AE 0062;0061 1D16D 1DF8 05AE 0300 0062; # (a◌᷸◌̀◌𝅭֮b; à𝅭◌᷸◌֮b; a𝅭◌᷸◌֮◌̀b; à𝅭◌᷸◌֮b; a𝅭◌᷸◌֮◌̀b; ) LATIN SMALL LETTER A, COMBINING DOT ABOVE LEFT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, LATIN SMALL LETTER B
-0061 059A 0316 302A 1DF9 0062;0061 302A 0316 1DF9 059A 0062;0061 302A 0316 1DF9 059A 0062;0061 302A 0316 1DF9 059A 0062;0061 302A 0316 1DF9 059A 0062; # (a◌֚◌̖◌〪◌᷹b; a◌〪◌̖◌᷹◌֚b; a◌〪◌̖◌᷹◌֚b; a◌〪◌̖◌᷹◌֚b; a◌〪◌̖◌᷹◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING WIDE INVERTED BRIDGE BELOW, LATIN SMALL LETTER B
-0061 1DF9 059A 0316 302A 0062;0061 302A 1DF9 0316 059A 0062;0061 302A 1DF9 0316 059A 0062;0061 302A 1DF9 0316 059A 0062;0061 302A 1DF9 0316 059A 0062; # (a◌᷹◌֚◌̖◌〪b; a◌〪◌᷹◌̖◌֚b; a◌〪◌᷹◌̖◌֚b; a◌〪◌᷹◌̖◌֚b; a◌〪◌᷹◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING WIDE INVERTED BRIDGE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1DF9 0062;0061 1DFA 0316 1DF9 059A 0062;0061 1DFA 0316 1DF9 059A 0062;0061 1DFA 0316 1DF9 059A 0062;0061 1DFA 0316 1DF9 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, COMBINING WIDE INVERTED BRIDGE BELOW, LATIN SMALL LETTER B
+0061 1DF9 059A 0316 1DFA 0062;0061 1DFA 1DF9 0316 059A 0062;0061 1DFA 1DF9 0316 059A 0062;0061 1DFA 1DF9 0316 059A 0062;0061 1DFA 1DF9 0316 059A 0062; # (a◌᷹◌֚◌̖◌᷺b; a◌᷺◌᷹◌̖◌֚b; a◌᷺◌᷹◌̖◌֚b; a◌᷺◌᷹◌̖◌֚b; a◌᷺◌᷹◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING WIDE INVERTED BRIDGE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 0316 1DFA 031B 1DFA 0062;0061 031B 1DFA 1DFA 0316 0062;0061 031B 1DFA 1DFA 0316 0062;0061 031B 1DFA 1DFA 0316 0062;0061 031B 1DFA 1DFA 0316 0062; # (a◌̖◌᷺◌̛◌᷺b; a◌̛◌᷺◌᷺◌̖b; a◌̛◌᷺◌᷺◌̖b; a◌̛◌᷺◌᷺◌̖b; a◌̛◌᷺◌᷺◌̖b; ) LATIN SMALL LETTER A, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 1DFA 0316 1DFA 031B 0062;0061 031B 1DFA 1DFA 0316 0062;0061 031B 1DFA 1DFA 0316 0062;0061 031B 1DFA 1DFA 0316 0062;0061 031B 1DFA 1DFA 0316 0062; # (a◌᷺◌̖◌᷺◌̛b; a◌̛◌᷺◌᷺◌̖b; a◌̛◌᷺◌᷺◌̖b; a◌̛◌᷺◌᷺◌̖b; a◌̛◌᷺◌᷺◌̖b; ) LATIN SMALL LETTER A, COMBINING DOT BELOW LEFT, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, COMBINING HORN, LATIN SMALL LETTER B
0061 0315 0300 05AE 1DFB 0062;00E0 05AE 1DFB 0315 0062;0061 05AE 0300 1DFB 0315 0062;00E0 05AE 1DFB 0315 0062;0061 05AE 0300 1DFB 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 DELETION MARK, LATIN SMALL LETTER B
0061 1DFB 0315 0300 05AE 0062;0061 05AE 1DFB 0300 0315 0062;0061 05AE 1DFB 0300 0315 0062;0061 05AE 1DFB 0300 0315 0062;0061 05AE 1DFB 0300 0315 0062; # (a◌᷻◌̕◌̀◌֮b; a◌֮◌᷻◌̀◌̕b; a◌֮◌᷻◌̀◌̕b; a◌֮◌᷻◌̀◌̕b; a◌֮◌᷻◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DELETION MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 035D 035C 0315 1DFC 0062;0061 0315 035C 1DFC 035D 0062;0061 0315 035C 1DFC 035D 0062;0061 0315 035C 1DFC 035D 0062;0061 0315 035C 1DFC 035D 0062; # (a◌͝◌͜◌̕◌᷼b; a◌̕◌͜◌᷼◌͝b; a◌̕◌͜◌᷼◌͝b; a◌̕◌͜◌᷼◌͝b; a◌̕◌͜◌᷼◌͝b; ) LATIN SMALL LETTER A, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING DOUBLE INVERTED BREVE BELOW, LATIN SMALL LETTER B
0061 1DFC 035D 035C 0315 0062;0061 0315 1DFC 035C 035D 0062;0061 0315 1DFC 035C 035D 0062;0061 0315 1DFC 035C 035D 0062;0061 0315 1DFC 035C 035D 0062; # (a◌᷼◌͝◌͜◌̕b; a◌̕◌᷼◌͜◌͝b; a◌̕◌᷼◌͜◌͝b; a◌̕◌᷼◌͜◌͝b; a◌̕◌᷼◌͜◌͝b; ) LATIN SMALL LETTER A, COMBINING DOUBLE INVERTED BREVE BELOW, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, LATIN SMALL LETTER B
-0061 059A 0316 302A 1DFD 0062;0061 302A 0316 1DFD 059A 0062;0061 302A 0316 1DFD 059A 0062;0061 302A 0316 1DFD 059A 0062;0061 302A 0316 1DFD 059A 0062; # (a◌֚◌̖◌〪◌᷽b; a◌〪◌̖◌᷽◌֚b; a◌〪◌̖◌᷽◌֚b; a◌〪◌̖◌᷽◌֚b; a◌〪◌̖◌᷽◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING ALMOST EQUAL TO BELOW, LATIN SMALL LETTER B
-0061 1DFD 059A 0316 302A 0062;0061 302A 1DFD 0316 059A 0062;0061 302A 1DFD 0316 059A 0062;0061 302A 1DFD 0316 059A 0062;0061 302A 1DFD 0316 059A 0062; # (a◌᷽◌֚◌̖◌〪b; a◌〪◌᷽◌̖◌֚b; a◌〪◌᷽◌̖◌֚b; a◌〪◌᷽◌̖◌֚b; a◌〪◌᷽◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING ALMOST EQUAL TO BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1DFD 0062;0061 1DFA 0316 1DFD 059A 0062;0061 1DFA 0316 1DFD 059A 0062;0061 1DFA 0316 1DFD 059A 0062;0061 1DFA 0316 1DFD 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, COMBINING ALMOST EQUAL TO BELOW, LATIN SMALL LETTER B
+0061 1DFD 059A 0316 1DFA 0062;0061 1DFA 1DFD 0316 059A 0062;0061 1DFA 1DFD 0316 059A 0062;0061 1DFA 1DFD 0316 059A 0062;0061 1DFA 1DFD 0316 059A 0062; # (a◌᷽◌֚◌̖◌᷺b; a◌᷺◌᷽◌̖◌֚b; a◌᷺◌᷽◌̖◌֚b; a◌᷺◌᷽◌̖◌֚b; a◌᷺◌᷽◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING ALMOST EQUAL TO BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 1DFE 0062;00E0 05AE 1DFE 0315 0062;0061 05AE 0300 1DFE 0315 0062;00E0 05AE 1DFE 0315 0062;0061 05AE 0300 1DFE 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 LEFT ARROWHEAD ABOVE, LATIN SMALL LETTER B
0061 1DFE 0315 0300 05AE 0062;0061 05AE 1DFE 0300 0315 0062;0061 05AE 1DFE 0300 0315 0062;0061 05AE 1DFE 0300 0315 0062;0061 05AE 1DFE 0300 0315 0062; # (a◌᷾◌̕◌̀◌֮b; a◌֮◌᷾◌̀◌̕b; a◌֮◌᷾◌̀◌̕b; a◌֮◌᷾◌̀◌̕b; a◌֮◌᷾◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LEFT ARROWHEAD ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 1DFF 0062;0061 302A 0316 1DFF 059A 0062;0061 302A 0316 1DFF 059A 0062;0061 302A 0316 1DFF 059A 0062;0061 302A 0316 1DFF 059A 0062; # (a◌֚◌̖◌〪◌᷿b; a◌〪◌̖◌᷿◌֚b; a◌〪◌̖◌᷿◌֚b; a◌〪◌̖◌᷿◌֚b; a◌〪◌̖◌᷿◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW, LATIN SMALL LETTER B
-0061 1DFF 059A 0316 302A 0062;0061 302A 1DFF 0316 059A 0062;0061 302A 1DFF 0316 059A 0062;0061 302A 1DFF 0316 059A 0062;0061 302A 1DFF 0316 059A 0062; # (a◌᷿◌֚◌̖◌〪b; a◌〪◌᷿◌̖◌֚b; a◌〪◌᷿◌̖◌֚b; a◌〪◌᷿◌̖◌֚b; a◌〪◌᷿◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1DFF 0062;0061 1DFA 0316 1DFF 059A 0062;0061 1DFA 0316 1DFF 059A 0062;0061 1DFA 0316 1DFF 059A 0062;0061 1DFA 0316 1DFF 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, COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW, LATIN SMALL LETTER B
+0061 1DFF 059A 0316 1DFA 0062;0061 1DFA 1DFF 0316 059A 0062;0061 1DFA 1DFF 0316 059A 0062;0061 1DFA 1DFF 0316 059A 0062;0061 1DFA 1DFF 0316 059A 0062; # (a◌᷿◌֚◌̖◌᷺b; a◌᷺◌᷿◌̖◌֚b; a◌᷺◌᷿◌̖◌֚b; a◌᷺◌᷿◌̖◌֚b; a◌᷺◌᷿◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 20D0 0062;00E0 05AE 20D0 0315 0062;0061 05AE 0300 20D0 0315 0062;00E0 05AE 20D0 0315 0062;0061 05AE 0300 20D0 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 LEFT HARPOON ABOVE, LATIN SMALL LETTER B
0061 20D0 0315 0300 05AE 0062;0061 05AE 20D0 0300 0315 0062;0061 05AE 20D0 0300 0315 0062;0061 05AE 20D0 0300 0315 0062;0061 05AE 20D0 0300 0315 0062; # (a◌⃐◌̕◌̀◌֮b; a◌֮◌⃐◌̀◌̕b; a◌֮◌⃐◌̀◌̕b; a◌֮◌⃐◌̀◌̕b; a◌֮◌⃐◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LEFT HARPOON ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 20D1 0062;00E0 05AE 20D1 0315 0062;0061 05AE 0300 20D1 0315 0062;00E0 05AE 20D1 0315 0062;0061 05AE 0300 20D1 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 RIGHT HARPOON ABOVE, LATIN SMALL LETTER B
@@ -18081,22 +18208,22 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 20E6 16FF0 0334 0062;0061 20E6 0334 16FF0 0062;0061 20E6 0334 16FF0 0062;0061 20E6 0334 16FF0 0062;0061 20E6 0334 16FF0 0062; # (a◌⃦𖿰◌̴b; a◌⃦◌̴𖿰b; a◌⃦◌̴𖿰b; a◌⃦◌̴𖿰b; a◌⃦◌̴𖿰b; ) LATIN SMALL LETTER A, COMBINING DOUBLE VERTICAL STROKE OVERLAY, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
0061 0315 0300 05AE 20E7 0062;00E0 05AE 20E7 0315 0062;0061 05AE 0300 20E7 0315 0062;00E0 05AE 20E7 0315 0062;0061 05AE 0300 20E7 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 ANNUITY SYMBOL, LATIN SMALL LETTER B
0061 20E7 0315 0300 05AE 0062;0061 05AE 20E7 0300 0315 0062;0061 05AE 20E7 0300 0315 0062;0061 05AE 20E7 0300 0315 0062;0061 05AE 20E7 0300 0315 0062; # (a◌⃧◌̕◌̀◌֮b; a◌֮◌⃧◌̀◌̕b; a◌֮◌⃧◌̀◌̕b; a◌֮◌⃧◌̀◌̕b; a◌֮◌⃧◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING ANNUITY SYMBOL, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 20E8 0062;0061 302A 0316 20E8 059A 0062;0061 302A 0316 20E8 059A 0062;0061 302A 0316 20E8 059A 0062;0061 302A 0316 20E8 059A 0062; # (a◌֚◌̖◌〪◌⃨b; a◌〪◌̖◌⃨◌֚b; a◌〪◌̖◌⃨◌֚b; a◌〪◌̖◌⃨◌֚b; a◌〪◌̖◌⃨◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING TRIPLE UNDERDOT, LATIN SMALL LETTER B
-0061 20E8 059A 0316 302A 0062;0061 302A 20E8 0316 059A 0062;0061 302A 20E8 0316 059A 0062;0061 302A 20E8 0316 059A 0062;0061 302A 20E8 0316 059A 0062; # (a◌⃨◌֚◌̖◌〪b; a◌〪◌⃨◌̖◌֚b; a◌〪◌⃨◌̖◌֚b; a◌〪◌⃨◌̖◌֚b; a◌〪◌⃨◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING TRIPLE UNDERDOT, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 20E8 0062;0061 1DFA 0316 20E8 059A 0062;0061 1DFA 0316 20E8 059A 0062;0061 1DFA 0316 20E8 059A 0062;0061 1DFA 0316 20E8 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, COMBINING TRIPLE UNDERDOT, LATIN SMALL LETTER B
+0061 20E8 059A 0316 1DFA 0062;0061 1DFA 20E8 0316 059A 0062;0061 1DFA 20E8 0316 059A 0062;0061 1DFA 20E8 0316 059A 0062;0061 1DFA 20E8 0316 059A 0062; # (a◌⃨◌֚◌̖◌᷺b; a◌᷺◌⃨◌̖◌֚b; a◌᷺◌⃨◌̖◌֚b; a◌᷺◌⃨◌̖◌֚b; a◌᷺◌⃨◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING TRIPLE UNDERDOT, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 20E9 0062;00E0 05AE 20E9 0315 0062;0061 05AE 0300 20E9 0315 0062;00E0 05AE 20E9 0315 0062;0061 05AE 0300 20E9 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 WIDE BRIDGE ABOVE, LATIN SMALL LETTER B
0061 20E9 0315 0300 05AE 0062;0061 05AE 20E9 0300 0315 0062;0061 05AE 20E9 0300 0315 0062;0061 05AE 20E9 0300 0315 0062;0061 05AE 20E9 0300 0315 0062; # (a◌⃩◌̕◌̀◌֮b; a◌֮◌⃩◌̀◌̕b; a◌֮◌⃩◌̀◌̕b; a◌֮◌⃩◌̀◌̕b; a◌֮◌⃩◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING WIDE BRIDGE ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 16FF0 0334 20EA 0062;0061 0334 20EA 16FF0 0062;0061 0334 20EA 16FF0 0062;0061 0334 20EA 16FF0 0062;0061 0334 20EA 16FF0 0062; # (a𖿰◌̴◌⃪b; a◌̴◌⃪𖿰b; a◌̴◌⃪𖿰b; a◌̴◌⃪𖿰b; a◌̴◌⃪𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, COMBINING LEFTWARDS ARROW OVERLAY, LATIN SMALL LETTER B
0061 20EA 16FF0 0334 0062;0061 20EA 0334 16FF0 0062;0061 20EA 0334 16FF0 0062;0061 20EA 0334 16FF0 0062;0061 20EA 0334 16FF0 0062; # (a◌⃪𖿰◌̴b; a◌⃪◌̴𖿰b; a◌⃪◌̴𖿰b; a◌⃪◌̴𖿰b; a◌⃪◌̴𖿰b; ) LATIN SMALL LETTER A, COMBINING LEFTWARDS ARROW OVERLAY, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
0061 16FF0 0334 20EB 0062;0061 0334 20EB 16FF0 0062;0061 0334 20EB 16FF0 0062;0061 0334 20EB 16FF0 0062;0061 0334 20EB 16FF0 0062; # (a𖿰◌̴◌⃫b; a◌̴◌⃫𖿰b; a◌̴◌⃫𖿰b; a◌̴◌⃫𖿰b; a◌̴◌⃫𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, COMBINING LONG DOUBLE SOLIDUS OVERLAY, LATIN SMALL LETTER B
0061 20EB 16FF0 0334 0062;0061 20EB 0334 16FF0 0062;0061 20EB 0334 16FF0 0062;0061 20EB 0334 16FF0 0062;0061 20EB 0334 16FF0 0062; # (a◌⃫𖿰◌̴b; a◌⃫◌̴𖿰b; a◌⃫◌̴𖿰b; a◌⃫◌̴𖿰b; a◌⃫◌̴𖿰b; ) LATIN SMALL LETTER A, COMBINING LONG DOUBLE SOLIDUS OVERLAY, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
-0061 059A 0316 302A 20EC 0062;0061 302A 0316 20EC 059A 0062;0061 302A 0316 20EC 059A 0062;0061 302A 0316 20EC 059A 0062;0061 302A 0316 20EC 059A 0062; # (a◌֚◌̖◌〪◌⃬b; a◌〪◌̖◌⃬◌֚b; a◌〪◌̖◌⃬◌֚b; a◌〪◌̖◌⃬◌֚b; a◌〪◌̖◌⃬◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS, LATIN SMALL LETTER B
-0061 20EC 059A 0316 302A 0062;0061 302A 20EC 0316 059A 0062;0061 302A 20EC 0316 059A 0062;0061 302A 20EC 0316 059A 0062;0061 302A 20EC 0316 059A 0062; # (a◌⃬◌֚◌̖◌〪b; a◌〪◌⃬◌̖◌֚b; a◌〪◌⃬◌̖◌֚b; a◌〪◌⃬◌̖◌֚b; a◌〪◌⃬◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 20ED 0062;0061 302A 0316 20ED 059A 0062;0061 302A 0316 20ED 059A 0062;0061 302A 0316 20ED 059A 0062;0061 302A 0316 20ED 059A 0062; # (a◌֚◌̖◌〪◌⃭b; a◌〪◌̖◌⃭◌֚b; a◌〪◌̖◌⃭◌֚b; a◌〪◌̖◌⃭◌֚b; a◌〪◌̖◌⃭◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS, LATIN SMALL LETTER B
-0061 20ED 059A 0316 302A 0062;0061 302A 20ED 0316 059A 0062;0061 302A 20ED 0316 059A 0062;0061 302A 20ED 0316 059A 0062;0061 302A 20ED 0316 059A 0062; # (a◌⃭◌֚◌̖◌〪b; a◌〪◌⃭◌̖◌֚b; a◌〪◌⃭◌̖◌֚b; a◌〪◌⃭◌̖◌֚b; a◌〪◌⃭◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 20EE 0062;0061 302A 0316 20EE 059A 0062;0061 302A 0316 20EE 059A 0062;0061 302A 0316 20EE 059A 0062;0061 302A 0316 20EE 059A 0062; # (a◌֚◌̖◌〪◌⃮b; a◌〪◌̖◌⃮◌֚b; a◌〪◌̖◌⃮◌֚b; a◌〪◌̖◌⃮◌֚b; a◌〪◌̖◌⃮◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LEFT ARROW BELOW, LATIN SMALL LETTER B
-0061 20EE 059A 0316 302A 0062;0061 302A 20EE 0316 059A 0062;0061 302A 20EE 0316 059A 0062;0061 302A 20EE 0316 059A 0062;0061 302A 20EE 0316 059A 0062; # (a◌⃮◌֚◌̖◌〪b; a◌〪◌⃮◌̖◌֚b; a◌〪◌⃮◌̖◌֚b; a◌〪◌⃮◌̖◌֚b; a◌〪◌⃮◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT ARROW BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 20EF 0062;0061 302A 0316 20EF 059A 0062;0061 302A 0316 20EF 059A 0062;0061 302A 0316 20EF 059A 0062;0061 302A 0316 20EF 059A 0062; # (a◌֚◌̖◌〪◌⃯b; a◌〪◌̖◌⃯◌֚b; a◌〪◌̖◌⃯◌֚b; a◌〪◌̖◌⃯◌֚b; a◌〪◌̖◌⃯◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RIGHT ARROW BELOW, LATIN SMALL LETTER B
-0061 20EF 059A 0316 302A 0062;0061 302A 20EF 0316 059A 0062;0061 302A 20EF 0316 059A 0062;0061 302A 20EF 0316 059A 0062;0061 302A 20EF 0316 059A 0062; # (a◌⃯◌֚◌̖◌〪b; a◌〪◌⃯◌̖◌֚b; a◌〪◌⃯◌̖◌֚b; a◌〪◌⃯◌̖◌֚b; a◌〪◌⃯◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT ARROW BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 20EC 0062;0061 1DFA 0316 20EC 059A 0062;0061 1DFA 0316 20EC 059A 0062;0061 1DFA 0316 20EC 059A 0062;0061 1DFA 0316 20EC 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, COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS, LATIN SMALL LETTER B
+0061 20EC 059A 0316 1DFA 0062;0061 1DFA 20EC 0316 059A 0062;0061 1DFA 20EC 0316 059A 0062;0061 1DFA 20EC 0316 059A 0062;0061 1DFA 20EC 0316 059A 0062; # (a◌⃬◌֚◌̖◌᷺b; a◌᷺◌⃬◌̖◌֚b; a◌᷺◌⃬◌̖◌֚b; a◌᷺◌⃬◌̖◌֚b; a◌᷺◌⃬◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 20ED 0062;0061 1DFA 0316 20ED 059A 0062;0061 1DFA 0316 20ED 059A 0062;0061 1DFA 0316 20ED 059A 0062;0061 1DFA 0316 20ED 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, COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS, LATIN SMALL LETTER B
+0061 20ED 059A 0316 1DFA 0062;0061 1DFA 20ED 0316 059A 0062;0061 1DFA 20ED 0316 059A 0062;0061 1DFA 20ED 0316 059A 0062;0061 1DFA 20ED 0316 059A 0062; # (a◌⃭◌֚◌̖◌᷺b; a◌᷺◌⃭◌̖◌֚b; a◌᷺◌⃭◌̖◌֚b; a◌᷺◌⃭◌̖◌֚b; a◌᷺◌⃭◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 20EE 0062;0061 1DFA 0316 20EE 059A 0062;0061 1DFA 0316 20EE 059A 0062;0061 1DFA 0316 20EE 059A 0062;0061 1DFA 0316 20EE 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, COMBINING LEFT ARROW BELOW, LATIN SMALL LETTER B
+0061 20EE 059A 0316 1DFA 0062;0061 1DFA 20EE 0316 059A 0062;0061 1DFA 20EE 0316 059A 0062;0061 1DFA 20EE 0316 059A 0062;0061 1DFA 20EE 0316 059A 0062; # (a◌⃮◌֚◌̖◌᷺b; a◌᷺◌⃮◌̖◌֚b; a◌᷺◌⃮◌̖◌֚b; a◌᷺◌⃮◌̖◌֚b; a◌᷺◌⃮◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT ARROW BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 20EF 0062;0061 1DFA 0316 20EF 059A 0062;0061 1DFA 0316 20EF 059A 0062;0061 1DFA 0316 20EF 059A 0062;0061 1DFA 0316 20EF 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, COMBINING RIGHT ARROW BELOW, LATIN SMALL LETTER B
+0061 20EF 059A 0316 1DFA 0062;0061 1DFA 20EF 0316 059A 0062;0061 1DFA 20EF 0316 059A 0062;0061 1DFA 20EF 0316 059A 0062;0061 1DFA 20EF 0316 059A 0062; # (a◌⃯◌֚◌̖◌᷺b; a◌᷺◌⃯◌̖◌֚b; a◌᷺◌⃯◌̖◌֚b; a◌᷺◌⃯◌̖◌֚b; a◌᷺◌⃯◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT ARROW BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 20F0 0062;00E0 05AE 20F0 0315 0062;0061 05AE 0300 20F0 0315 0062;00E0 05AE 20F0 0315 0062;0061 05AE 0300 20F0 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 ASTERISK ABOVE, LATIN SMALL LETTER B
0061 20F0 0315 0300 05AE 0062;0061 05AE 20F0 0300 0315 0062;0061 05AE 20F0 0300 0315 0062;0061 05AE 20F0 0300 0315 0062;0061 05AE 20F0 0300 0315 0062; # (a◌⃰◌̕◌̀◌֮b; a◌֮◌⃰◌̀◌̕b; a◌֮◌⃰◌̀◌̕b; a◌֮◌⃰◌̀◌̕b; a◌֮◌⃰◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING ASTERISK ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 2CEF 0062;00E0 05AE 2CEF 0315 0062;0061 05AE 0300 2CEF 0315 0062;00E0 05AE 2CEF 0315 0062;0061 05AE 0300 2CEF 0315 0062; # (a◌̕◌̀◌֮◌⳯b; à◌֮◌⳯◌̕b; a◌֮◌̀◌⳯◌̕b; à◌֮◌⳯◌̕b; a◌֮◌̀◌⳯◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COPTIC COMBINING NI ABOVE, LATIN SMALL LETTER B
@@ -18171,8 +18298,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 2DFE 0315 0300 05AE 0062;0061 05AE 2DFE 0300 0315 0062;0061 05AE 2DFE 0300 0315 0062;0061 05AE 2DFE 0300 0315 0062;0061 05AE 2DFE 0300 0315 0062; # (a◌ⷾ◌̕◌̀◌֮b; a◌֮◌ⷾ◌̀◌̕b; a◌֮◌ⷾ◌̀◌̕b; a◌֮◌ⷾ◌̀◌̕b; a◌֮◌ⷾ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER BIG YUS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 2DFF 0062;00E0 05AE 2DFF 0315 0062;0061 05AE 0300 2DFF 0315 0062;00E0 05AE 2DFF 0315 0062;0061 05AE 0300 2DFF 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 LETTER IOTIFIED BIG YUS, LATIN SMALL LETTER B
0061 2DFF 0315 0300 05AE 0062;0061 05AE 2DFF 0300 0315 0062;0061 05AE 2DFF 0300 0315 0062;0061 05AE 2DFF 0300 0315 0062;0061 05AE 2DFF 0300 0315 0062; # (a◌ⷿ◌̕◌̀◌֮b; a◌֮◌ⷿ◌̀◌̕b; a◌֮◌ⷿ◌̀◌̕b; a◌֮◌ⷿ◌̀◌̕b; a◌֮◌ⷿ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER IOTIFIED BIG YUS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 0316 302A 031B 302A 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062; # (a◌̖◌〪◌̛◌〪b; a◌̛◌〪◌〪◌̖b; a◌̛◌〪◌〪◌̖b; a◌̛◌〪◌〪◌̖b; a◌̛◌〪◌〪◌̖b; ) LATIN SMALL LETTER A, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 302A 0316 302A 031B 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062; # (a◌〪◌̖◌〪◌̛b; a◌̛◌〪◌〪◌̖b; a◌̛◌〪◌〪◌̖b; a◌̛◌〪◌〪◌̖b; a◌̛◌〪◌〪◌̖b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, LATIN SMALL LETTER B
+0061 0316 1DFA 031B 302A 0062;0061 031B 1DFA 302A 0316 0062;0061 031B 1DFA 302A 0316 0062;0061 031B 1DFA 302A 0316 0062;0061 031B 1DFA 302A 0316 0062; # (a◌̖◌᷺◌̛◌〪b; a◌̛◌᷺◌〪◌̖b; a◌̛◌᷺◌〪◌̖b; a◌̛◌᷺◌〪◌̖b; a◌̛◌᷺◌〪◌̖b; ) LATIN SMALL LETTER A, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, COMBINING HORN, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 302A 0316 1DFA 031B 0062;0061 031B 302A 1DFA 0316 0062;0061 031B 302A 1DFA 0316 0062;0061 031B 302A 1DFA 0316 0062;0061 031B 302A 1DFA 0316 0062; # (a◌〪◌̖◌᷺◌̛b; a◌̛◌〪◌᷺◌̖b; a◌̛◌〪◌᷺◌̖b; a◌̛◌〪◌᷺◌̖b; a◌̛◌〪◌᷺◌̖b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, COMBINING HORN, LATIN SMALL LETTER B
0061 0300 05AE 1D16D 302B 0062;00E0 1D16D 05AE 302B 0062;0061 1D16D 05AE 302B 0300 0062;00E0 1D16D 05AE 302B 0062;0061 1D16D 05AE 302B 0300 0062; # (a◌̀◌𝅭֮◌〫b; à𝅭◌֮◌〫b; a𝅭◌֮◌〫◌̀b; à𝅭◌֮◌〫b; a𝅭◌֮◌〫◌̀b; ) LATIN SMALL LETTER A, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, IDEOGRAPHIC RISING TONE MARK, LATIN SMALL LETTER B
0061 302B 0300 05AE 1D16D 0062;00E0 1D16D 302B 05AE 0062;0061 1D16D 302B 05AE 0300 0062;00E0 1D16D 302B 05AE 0062;0061 1D16D 302B 05AE 0300 0062; # (a◌〫◌̀◌𝅭֮b; à𝅭◌〫◌֮b; a𝅭◌〫◌֮◌̀b; à𝅭◌〫◌֮b; a𝅭◌〫◌֮◌̀b; ) LATIN SMALL LETTER A, IDEOGRAPHIC RISING TONE MARK, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, LATIN SMALL LETTER B
0061 035C 0315 0300 302C 0062;00E0 0315 302C 035C 0062;0061 0300 0315 302C 035C 0062;00E0 0315 302C 035C 0062;0061 0300 0315 302C 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, IDEOGRAPHIC DEPARTING TONE MARK, LATIN SMALL LETTER B
@@ -18259,12 +18386,12 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 A8F0 0315 0300 05AE 0062;0061 05AE A8F0 0300 0315 0062;0061 05AE A8F0 0300 0315 0062;0061 05AE A8F0 0300 0315 0062;0061 05AE A8F0 0300 0315 0062; # (a◌꣰◌̕◌̀◌֮b; a◌֮◌꣰◌̀◌̕b; a◌֮◌꣰◌̀◌̕b; a◌֮◌꣰◌̀◌̕b; a◌֮◌꣰◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI LETTER VI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE A8F1 0062;00E0 05AE A8F1 0315 0062;0061 05AE 0300 A8F1 0315 0062;00E0 05AE A8F1 0315 0062;0061 05AE 0300 A8F1 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 DEVANAGARI SIGN AVAGRAHA, LATIN SMALL LETTER B
0061 A8F1 0315 0300 05AE 0062;0061 05AE A8F1 0300 0315 0062;0061 05AE A8F1 0300 0315 0062;0061 05AE A8F1 0300 0315 0062;0061 05AE A8F1 0300 0315 0062; # (a◌꣱◌̕◌̀◌֮b; a◌֮◌꣱◌̀◌̕b; a◌֮◌꣱◌̀◌̕b; a◌֮◌꣱◌̀◌̕b; a◌֮◌꣱◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI SIGN AVAGRAHA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A A92B 0062;0061 302A 0316 A92B 059A 0062;0061 302A 0316 A92B 059A 0062;0061 302A 0316 A92B 059A 0062;0061 302A 0316 A92B 059A 0062; # (a◌֚◌̖◌〪◌꤫b; a◌〪◌̖◌꤫◌֚b; a◌〪◌̖◌꤫◌֚b; a◌〪◌̖◌꤫◌֚b; a◌〪◌̖◌꤫◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, KAYAH LI TONE PLOPHU, LATIN SMALL LETTER B
-0061 A92B 059A 0316 302A 0062;0061 302A A92B 0316 059A 0062;0061 302A A92B 0316 059A 0062;0061 302A A92B 0316 059A 0062;0061 302A A92B 0316 059A 0062; # (a◌꤫◌֚◌̖◌〪b; a◌〪◌꤫◌̖◌֚b; a◌〪◌꤫◌̖◌֚b; a◌〪◌꤫◌̖◌֚b; a◌〪◌꤫◌̖◌֚b; ) LATIN SMALL LETTER A, KAYAH LI TONE PLOPHU, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A A92C 0062;0061 302A 0316 A92C 059A 0062;0061 302A 0316 A92C 059A 0062;0061 302A 0316 A92C 059A 0062;0061 302A 0316 A92C 059A 0062; # (a◌֚◌̖◌〪◌꤬b; a◌〪◌̖◌꤬◌֚b; a◌〪◌̖◌꤬◌֚b; a◌〪◌̖◌꤬◌֚b; a◌〪◌̖◌꤬◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, KAYAH LI TONE CALYA, LATIN SMALL LETTER B
-0061 A92C 059A 0316 302A 0062;0061 302A A92C 0316 059A 0062;0061 302A A92C 0316 059A 0062;0061 302A A92C 0316 059A 0062;0061 302A A92C 0316 059A 0062; # (a◌꤬◌֚◌̖◌〪b; a◌〪◌꤬◌̖◌֚b; a◌〪◌꤬◌̖◌֚b; a◌〪◌꤬◌̖◌֚b; a◌〪◌꤬◌̖◌֚b; ) LATIN SMALL LETTER A, KAYAH LI TONE CALYA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A A92D 0062;0061 302A 0316 A92D 059A 0062;0061 302A 0316 A92D 059A 0062;0061 302A 0316 A92D 059A 0062;0061 302A 0316 A92D 059A 0062; # (a◌֚◌̖◌〪◌꤭b; a◌〪◌̖◌꤭◌֚b; a◌〪◌̖◌꤭◌֚b; a◌〪◌̖◌꤭◌֚b; a◌〪◌̖◌꤭◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, KAYAH LI TONE CALYA PLOPHU, LATIN SMALL LETTER B
-0061 A92D 059A 0316 302A 0062;0061 302A A92D 0316 059A 0062;0061 302A A92D 0316 059A 0062;0061 302A A92D 0316 059A 0062;0061 302A A92D 0316 059A 0062; # (a◌꤭◌֚◌̖◌〪b; a◌〪◌꤭◌̖◌֚b; a◌〪◌꤭◌̖◌֚b; a◌〪◌꤭◌̖◌֚b; a◌〪◌꤭◌̖◌֚b; ) LATIN SMALL LETTER A, KAYAH LI TONE CALYA PLOPHU, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA A92B 0062;0061 1DFA 0316 A92B 059A 0062;0061 1DFA 0316 A92B 059A 0062;0061 1DFA 0316 A92B 059A 0062;0061 1DFA 0316 A92B 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, KAYAH LI TONE PLOPHU, LATIN SMALL LETTER B
+0061 A92B 059A 0316 1DFA 0062;0061 1DFA A92B 0316 059A 0062;0061 1DFA A92B 0316 059A 0062;0061 1DFA A92B 0316 059A 0062;0061 1DFA A92B 0316 059A 0062; # (a◌꤫◌֚◌̖◌᷺b; a◌᷺◌꤫◌̖◌֚b; a◌᷺◌꤫◌̖◌֚b; a◌᷺◌꤫◌̖◌֚b; a◌᷺◌꤫◌̖◌֚b; ) LATIN SMALL LETTER A, KAYAH LI TONE PLOPHU, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA A92C 0062;0061 1DFA 0316 A92C 059A 0062;0061 1DFA 0316 A92C 059A 0062;0061 1DFA 0316 A92C 059A 0062;0061 1DFA 0316 A92C 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, KAYAH LI TONE CALYA, LATIN SMALL LETTER B
+0061 A92C 059A 0316 1DFA 0062;0061 1DFA A92C 0316 059A 0062;0061 1DFA A92C 0316 059A 0062;0061 1DFA A92C 0316 059A 0062;0061 1DFA A92C 0316 059A 0062; # (a◌꤬◌֚◌̖◌᷺b; a◌᷺◌꤬◌̖◌֚b; a◌᷺◌꤬◌̖◌֚b; a◌᷺◌꤬◌̖◌֚b; a◌᷺◌꤬◌̖◌֚b; ) LATIN SMALL LETTER A, KAYAH LI TONE CALYA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA A92D 0062;0061 1DFA 0316 A92D 059A 0062;0061 1DFA 0316 A92D 059A 0062;0061 1DFA 0316 A92D 059A 0062;0061 1DFA 0316 A92D 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, KAYAH LI TONE CALYA PLOPHU, LATIN SMALL LETTER B
+0061 A92D 059A 0316 1DFA 0062;0061 1DFA A92D 0316 059A 0062;0061 1DFA A92D 0316 059A 0062;0061 1DFA A92D 0316 059A 0062;0061 1DFA A92D 0316 059A 0062; # (a◌꤭◌֚◌̖◌᷺b; a◌᷺◌꤭◌̖◌֚b; a◌᷺◌꤭◌̖◌֚b; a◌᷺◌꤭◌̖◌֚b; a◌᷺◌꤭◌̖◌֚b; ) LATIN SMALL LETTER A, KAYAH LI TONE CALYA PLOPHU, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 05B0 094D 3099 A953 0062;0061 3099 094D A953 05B0 0062;0061 3099 094D A953 05B0 0062;0061 3099 094D A953 05B0 0062;0061 3099 094D A953 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, REJANG VIRAMA, LATIN SMALL LETTER B
0061 A953 05B0 094D 3099 0062;0061 3099 A953 094D 05B0 0062;0061 3099 A953 094D 05B0 0062;0061 3099 A953 094D 05B0 0062;0061 3099 A953 094D 05B0 0062; # (a꥓◌ְ◌्◌゙b; a◌゙꥓◌्◌ְb; a◌゙꥓◌्◌ְb; a◌゙꥓◌्◌ְb; a◌゙꥓◌्◌ְb; ) LATIN SMALL LETTER A, REJANG VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
0061 3099 093C 16FF0 A9B3 0062;0061 16FF0 093C A9B3 3099 0062;0061 16FF0 093C A9B3 3099 0062;0061 16FF0 093C A9B3 3099 0062;0061 16FF0 093C A9B3 3099 0062; # (a◌゙◌𖿰़◌꦳b; a𖿰◌़◌꦳◌゙b; a𖿰◌़◌꦳◌゙b; a𖿰◌़◌꦳◌゙b; a𖿰◌़◌꦳◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, VIETNAMESE ALTERNATE READING MARK CA, JAVANESE SIGN CECAK TELU, LATIN SMALL LETTER B
@@ -18277,8 +18404,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 AAB2 0315 0300 05AE 0062;0061 05AE AAB2 0300 0315 0062;0061 05AE AAB2 0300 0315 0062;0061 05AE AAB2 0300 0315 0062;0061 05AE AAB2 0300 0315 0062; # (a◌ꪲ◌̕◌̀◌֮b; a◌֮◌ꪲ◌̀◌̕b; a◌֮◌ꪲ◌̀◌̕b; a◌֮◌ꪲ◌̀◌̕b; a◌֮◌ꪲ◌̀◌̕b; ) LATIN SMALL LETTER A, TAI VIET VOWEL I, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE AAB3 0062;00E0 05AE AAB3 0315 0062;0061 05AE 0300 AAB3 0315 0062;00E0 05AE AAB3 0315 0062;0061 05AE 0300 AAB3 0315 0062; # (a◌̕◌̀◌֮◌ꪳb; à◌֮◌ꪳ◌̕b; a◌֮◌̀◌ꪳ◌̕b; à◌֮◌ꪳ◌̕b; a◌֮◌̀◌ꪳ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI VIET VOWEL UE, LATIN SMALL LETTER B
0061 AAB3 0315 0300 05AE 0062;0061 05AE AAB3 0300 0315 0062;0061 05AE AAB3 0300 0315 0062;0061 05AE AAB3 0300 0315 0062;0061 05AE AAB3 0300 0315 0062; # (a◌ꪳ◌̕◌̀◌֮b; a◌֮◌ꪳ◌̀◌̕b; a◌֮◌ꪳ◌̀◌̕b; a◌֮◌ꪳ◌̀◌̕b; a◌֮◌ꪳ◌̀◌̕b; ) LATIN SMALL LETTER A, TAI VIET VOWEL UE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A AAB4 0062;0061 302A 0316 AAB4 059A 0062;0061 302A 0316 AAB4 059A 0062;0061 302A 0316 AAB4 059A 0062;0061 302A 0316 AAB4 059A 0062; # (a◌֚◌̖◌〪◌ꪴb; a◌〪◌̖◌ꪴ◌֚b; a◌〪◌̖◌ꪴ◌֚b; a◌〪◌̖◌ꪴ◌֚b; a◌〪◌̖◌ꪴ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, TAI VIET VOWEL U, LATIN SMALL LETTER B
-0061 AAB4 059A 0316 302A 0062;0061 302A AAB4 0316 059A 0062;0061 302A AAB4 0316 059A 0062;0061 302A AAB4 0316 059A 0062;0061 302A AAB4 0316 059A 0062; # (a◌ꪴ◌֚◌̖◌〪b; a◌〪◌ꪴ◌̖◌֚b; a◌〪◌ꪴ◌̖◌֚b; a◌〪◌ꪴ◌̖◌֚b; a◌〪◌ꪴ◌̖◌֚b; ) LATIN SMALL LETTER A, TAI VIET VOWEL U, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA AAB4 0062;0061 1DFA 0316 AAB4 059A 0062;0061 1DFA 0316 AAB4 059A 0062;0061 1DFA 0316 AAB4 059A 0062;0061 1DFA 0316 AAB4 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, TAI VIET VOWEL U, LATIN SMALL LETTER B
+0061 AAB4 059A 0316 1DFA 0062;0061 1DFA AAB4 0316 059A 0062;0061 1DFA AAB4 0316 059A 0062;0061 1DFA AAB4 0316 059A 0062;0061 1DFA AAB4 0316 059A 0062; # (a◌ꪴ◌֚◌̖◌᷺b; a◌᷺◌ꪴ◌̖◌֚b; a◌᷺◌ꪴ◌̖◌֚b; a◌᷺◌ꪴ◌̖◌֚b; a◌᷺◌ꪴ◌̖◌֚b; ) LATIN SMALL LETTER A, TAI VIET VOWEL U, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE AAB7 0062;00E0 05AE AAB7 0315 0062;0061 05AE 0300 AAB7 0315 0062;00E0 05AE AAB7 0315 0062;0061 05AE 0300 AAB7 0315 0062; # (a◌̕◌̀◌֮◌ꪷb; à◌֮◌ꪷ◌̕b; a◌֮◌̀◌ꪷ◌̕b; à◌֮◌ꪷ◌̕b; a◌֮◌̀◌ꪷ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI VIET MAI KHIT, LATIN SMALL LETTER B
0061 AAB7 0315 0300 05AE 0062;0061 05AE AAB7 0300 0315 0062;0061 05AE AAB7 0300 0315 0062;0061 05AE AAB7 0300 0315 0062;0061 05AE AAB7 0300 0315 0062; # (a◌ꪷ◌̕◌̀◌֮b; a◌֮◌ꪷ◌̀◌̕b; a◌֮◌ꪷ◌̀◌̕b; a◌֮◌ꪷ◌̀◌̕b; a◌֮◌ꪷ◌̀◌̕b; ) LATIN SMALL LETTER A, TAI VIET MAI KHIT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE AAB8 0062;00E0 05AE AAB8 0315 0062;0061 05AE 0300 AAB8 0315 0062;00E0 05AE AAB8 0315 0062;0061 05AE 0300 AAB8 0315 0062; # (a◌̕◌̀◌֮◌ꪸb; à◌֮◌ꪸ◌̕b; a◌֮◌̀◌ꪸ◌̕b; à◌֮◌ꪸ◌̕b; a◌֮◌̀◌ꪸ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI VIET VOWEL IA, LATIN SMALL LETTER B
@@ -18309,28 +18436,28 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 FE25 0315 0300 05AE 0062;0061 05AE FE25 0300 0315 0062;0061 05AE FE25 0300 0315 0062;0061 05AE FE25 0300 0315 0062;0061 05AE FE25 0300 0315 0062; # (a◌︥◌̕◌̀◌֮b; a◌֮◌︥◌̀◌̕b; a◌֮◌︥◌̀◌̕b; a◌֮◌︥◌̀◌̕b; a◌֮◌︥◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING MACRON RIGHT HALF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE FE26 0062;00E0 05AE FE26 0315 0062;0061 05AE 0300 FE26 0315 0062;00E0 05AE FE26 0315 0062;0061 05AE 0300 FE26 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 CONJOINING MACRON, LATIN SMALL LETTER B
0061 FE26 0315 0300 05AE 0062;0061 05AE FE26 0300 0315 0062;0061 05AE FE26 0300 0315 0062;0061 05AE FE26 0300 0315 0062;0061 05AE FE26 0300 0315 0062; # (a◌︦◌̕◌̀◌֮b; a◌֮◌︦◌̀◌̕b; a◌֮◌︦◌̀◌̕b; a◌֮◌︦◌̀◌̕b; a◌֮◌︦◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CONJOINING MACRON, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A FE27 0062;0061 302A 0316 FE27 059A 0062;0061 302A 0316 FE27 059A 0062;0061 302A 0316 FE27 059A 0062;0061 302A 0316 FE27 059A 0062; # (a◌֚◌̖◌〪◌︧b; a◌〪◌̖◌︧◌֚b; a◌〪◌̖◌︧◌֚b; a◌〪◌̖◌︧◌֚b; a◌〪◌̖◌︧◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LIGATURE LEFT HALF BELOW, LATIN SMALL LETTER B
-0061 FE27 059A 0316 302A 0062;0061 302A FE27 0316 059A 0062;0061 302A FE27 0316 059A 0062;0061 302A FE27 0316 059A 0062;0061 302A FE27 0316 059A 0062; # (a◌︧◌֚◌̖◌〪b; a◌〪◌︧◌̖◌֚b; a◌〪◌︧◌̖◌֚b; a◌〪◌︧◌̖◌֚b; a◌〪◌︧◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LIGATURE LEFT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A FE28 0062;0061 302A 0316 FE28 059A 0062;0061 302A 0316 FE28 059A 0062;0061 302A 0316 FE28 059A 0062;0061 302A 0316 FE28 059A 0062; # (a◌֚◌̖◌〪◌︨b; a◌〪◌̖◌︨◌֚b; a◌〪◌̖◌︨◌֚b; a◌〪◌̖◌︨◌֚b; a◌〪◌̖◌︨◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LIGATURE RIGHT HALF BELOW, LATIN SMALL LETTER B
-0061 FE28 059A 0316 302A 0062;0061 302A FE28 0316 059A 0062;0061 302A FE28 0316 059A 0062;0061 302A FE28 0316 059A 0062;0061 302A FE28 0316 059A 0062; # (a◌︨◌֚◌̖◌〪b; a◌〪◌︨◌̖◌֚b; a◌〪◌︨◌̖◌֚b; a◌〪◌︨◌̖◌֚b; a◌〪◌︨◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LIGATURE RIGHT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A FE29 0062;0061 302A 0316 FE29 059A 0062;0061 302A 0316 FE29 059A 0062;0061 302A 0316 FE29 059A 0062;0061 302A 0316 FE29 059A 0062; # (a◌֚◌̖◌〪◌︩b; a◌〪◌̖◌︩◌֚b; a◌〪◌̖◌︩◌֚b; a◌〪◌̖◌︩◌֚b; a◌〪◌̖◌︩◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING TILDE LEFT HALF BELOW, LATIN SMALL LETTER B
-0061 FE29 059A 0316 302A 0062;0061 302A FE29 0316 059A 0062;0061 302A FE29 0316 059A 0062;0061 302A FE29 0316 059A 0062;0061 302A FE29 0316 059A 0062; # (a◌︩◌֚◌̖◌〪b; a◌〪◌︩◌̖◌֚b; a◌〪◌︩◌̖◌֚b; a◌〪◌︩◌̖◌֚b; a◌〪◌︩◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING TILDE LEFT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A FE2A 0062;0061 302A 0316 FE2A 059A 0062;0061 302A 0316 FE2A 059A 0062;0061 302A 0316 FE2A 059A 0062;0061 302A 0316 FE2A 059A 0062; # (a◌֚◌̖◌〪◌︪b; a◌〪◌̖◌︪◌֚b; a◌〪◌̖◌︪◌֚b; a◌〪◌̖◌︪◌֚b; a◌〪◌̖◌︪◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING TILDE RIGHT HALF BELOW, LATIN SMALL LETTER B
-0061 FE2A 059A 0316 302A 0062;0061 302A FE2A 0316 059A 0062;0061 302A FE2A 0316 059A 0062;0061 302A FE2A 0316 059A 0062;0061 302A FE2A 0316 059A 0062; # (a◌︪◌֚◌̖◌〪b; a◌〪◌︪◌̖◌֚b; a◌〪◌︪◌̖◌֚b; a◌〪◌︪◌̖◌֚b; a◌〪◌︪◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING TILDE RIGHT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A FE2B 0062;0061 302A 0316 FE2B 059A 0062;0061 302A 0316 FE2B 059A 0062;0061 302A 0316 FE2B 059A 0062;0061 302A 0316 FE2B 059A 0062; # (a◌֚◌̖◌〪◌︫b; a◌〪◌̖◌︫◌֚b; a◌〪◌̖◌︫◌֚b; a◌〪◌̖◌︫◌֚b; a◌〪◌̖◌︫◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING MACRON LEFT HALF BELOW, LATIN SMALL LETTER B
-0061 FE2B 059A 0316 302A 0062;0061 302A FE2B 0316 059A 0062;0061 302A FE2B 0316 059A 0062;0061 302A FE2B 0316 059A 0062;0061 302A FE2B 0316 059A 0062; # (a◌︫◌֚◌̖◌〪b; a◌〪◌︫◌̖◌֚b; a◌〪◌︫◌̖◌֚b; a◌〪◌︫◌̖◌֚b; a◌〪◌︫◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING MACRON LEFT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A FE2C 0062;0061 302A 0316 FE2C 059A 0062;0061 302A 0316 FE2C 059A 0062;0061 302A 0316 FE2C 059A 0062;0061 302A 0316 FE2C 059A 0062; # (a◌֚◌̖◌〪◌︬b; a◌〪◌̖◌︬◌֚b; a◌〪◌̖◌︬◌֚b; a◌〪◌̖◌︬◌֚b; a◌〪◌̖◌︬◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING MACRON RIGHT HALF BELOW, LATIN SMALL LETTER B
-0061 FE2C 059A 0316 302A 0062;0061 302A FE2C 0316 059A 0062;0061 302A FE2C 0316 059A 0062;0061 302A FE2C 0316 059A 0062;0061 302A FE2C 0316 059A 0062; # (a◌︬◌֚◌̖◌〪b; a◌〪◌︬◌̖◌֚b; a◌〪◌︬◌̖◌֚b; a◌〪◌︬◌̖◌֚b; a◌〪◌︬◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING MACRON RIGHT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A FE2D 0062;0061 302A 0316 FE2D 059A 0062;0061 302A 0316 FE2D 059A 0062;0061 302A 0316 FE2D 059A 0062;0061 302A 0316 FE2D 059A 0062; # (a◌֚◌̖◌〪◌︭b; a◌〪◌̖◌︭◌֚b; a◌〪◌̖◌︭◌֚b; a◌〪◌̖◌︭◌֚b; a◌〪◌̖◌︭◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING CONJOINING MACRON BELOW, LATIN SMALL LETTER B
-0061 FE2D 059A 0316 302A 0062;0061 302A FE2D 0316 059A 0062;0061 302A FE2D 0316 059A 0062;0061 302A FE2D 0316 059A 0062;0061 302A FE2D 0316 059A 0062; # (a◌︭◌֚◌̖◌〪b; a◌〪◌︭◌̖◌֚b; a◌〪◌︭◌̖◌֚b; a◌〪◌︭◌̖◌֚b; a◌〪◌︭◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING CONJOINING MACRON BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA FE27 0062;0061 1DFA 0316 FE27 059A 0062;0061 1DFA 0316 FE27 059A 0062;0061 1DFA 0316 FE27 059A 0062;0061 1DFA 0316 FE27 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, COMBINING LIGATURE LEFT HALF BELOW, LATIN SMALL LETTER B
+0061 FE27 059A 0316 1DFA 0062;0061 1DFA FE27 0316 059A 0062;0061 1DFA FE27 0316 059A 0062;0061 1DFA FE27 0316 059A 0062;0061 1DFA FE27 0316 059A 0062; # (a◌︧◌֚◌̖◌᷺b; a◌᷺◌︧◌̖◌֚b; a◌᷺◌︧◌̖◌֚b; a◌᷺◌︧◌̖◌֚b; a◌᷺◌︧◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LIGATURE LEFT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA FE28 0062;0061 1DFA 0316 FE28 059A 0062;0061 1DFA 0316 FE28 059A 0062;0061 1DFA 0316 FE28 059A 0062;0061 1DFA 0316 FE28 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, COMBINING LIGATURE RIGHT HALF BELOW, LATIN SMALL LETTER B
+0061 FE28 059A 0316 1DFA 0062;0061 1DFA FE28 0316 059A 0062;0061 1DFA FE28 0316 059A 0062;0061 1DFA FE28 0316 059A 0062;0061 1DFA FE28 0316 059A 0062; # (a◌︨◌֚◌̖◌᷺b; a◌᷺◌︨◌̖◌֚b; a◌᷺◌︨◌̖◌֚b; a◌᷺◌︨◌̖◌֚b; a◌᷺◌︨◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LIGATURE RIGHT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA FE29 0062;0061 1DFA 0316 FE29 059A 0062;0061 1DFA 0316 FE29 059A 0062;0061 1DFA 0316 FE29 059A 0062;0061 1DFA 0316 FE29 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, COMBINING TILDE LEFT HALF BELOW, LATIN SMALL LETTER B
+0061 FE29 059A 0316 1DFA 0062;0061 1DFA FE29 0316 059A 0062;0061 1DFA FE29 0316 059A 0062;0061 1DFA FE29 0316 059A 0062;0061 1DFA FE29 0316 059A 0062; # (a◌︩◌֚◌̖◌᷺b; a◌᷺◌︩◌̖◌֚b; a◌᷺◌︩◌̖◌֚b; a◌᷺◌︩◌̖◌֚b; a◌᷺◌︩◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING TILDE LEFT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA FE2A 0062;0061 1DFA 0316 FE2A 059A 0062;0061 1DFA 0316 FE2A 059A 0062;0061 1DFA 0316 FE2A 059A 0062;0061 1DFA 0316 FE2A 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, COMBINING TILDE RIGHT HALF BELOW, LATIN SMALL LETTER B
+0061 FE2A 059A 0316 1DFA 0062;0061 1DFA FE2A 0316 059A 0062;0061 1DFA FE2A 0316 059A 0062;0061 1DFA FE2A 0316 059A 0062;0061 1DFA FE2A 0316 059A 0062; # (a◌︪◌֚◌̖◌᷺b; a◌᷺◌︪◌̖◌֚b; a◌᷺◌︪◌̖◌֚b; a◌᷺◌︪◌̖◌֚b; a◌᷺◌︪◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING TILDE RIGHT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA FE2B 0062;0061 1DFA 0316 FE2B 059A 0062;0061 1DFA 0316 FE2B 059A 0062;0061 1DFA 0316 FE2B 059A 0062;0061 1DFA 0316 FE2B 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, COMBINING MACRON LEFT HALF BELOW, LATIN SMALL LETTER B
+0061 FE2B 059A 0316 1DFA 0062;0061 1DFA FE2B 0316 059A 0062;0061 1DFA FE2B 0316 059A 0062;0061 1DFA FE2B 0316 059A 0062;0061 1DFA FE2B 0316 059A 0062; # (a◌︫◌֚◌̖◌᷺b; a◌᷺◌︫◌̖◌֚b; a◌᷺◌︫◌̖◌֚b; a◌᷺◌︫◌̖◌֚b; a◌᷺◌︫◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING MACRON LEFT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA FE2C 0062;0061 1DFA 0316 FE2C 059A 0062;0061 1DFA 0316 FE2C 059A 0062;0061 1DFA 0316 FE2C 059A 0062;0061 1DFA 0316 FE2C 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, COMBINING MACRON RIGHT HALF BELOW, LATIN SMALL LETTER B
+0061 FE2C 059A 0316 1DFA 0062;0061 1DFA FE2C 0316 059A 0062;0061 1DFA FE2C 0316 059A 0062;0061 1DFA FE2C 0316 059A 0062;0061 1DFA FE2C 0316 059A 0062; # (a◌︬◌֚◌̖◌᷺b; a◌᷺◌︬◌̖◌֚b; a◌᷺◌︬◌̖◌֚b; a◌᷺◌︬◌̖◌֚b; a◌᷺◌︬◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING MACRON RIGHT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA FE2D 0062;0061 1DFA 0316 FE2D 059A 0062;0061 1DFA 0316 FE2D 059A 0062;0061 1DFA 0316 FE2D 059A 0062;0061 1DFA 0316 FE2D 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, COMBINING CONJOINING MACRON BELOW, LATIN SMALL LETTER B
+0061 FE2D 059A 0316 1DFA 0062;0061 1DFA FE2D 0316 059A 0062;0061 1DFA FE2D 0316 059A 0062;0061 1DFA FE2D 0316 059A 0062;0061 1DFA FE2D 0316 059A 0062; # (a◌︭◌֚◌̖◌᷺b; a◌᷺◌︭◌̖◌֚b; a◌᷺◌︭◌̖◌֚b; a◌᷺◌︭◌̖◌֚b; a◌᷺◌︭◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING CONJOINING MACRON BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE FE2E 0062;00E0 05AE FE2E 0315 0062;0061 05AE 0300 FE2E 0315 0062;00E0 05AE FE2E 0315 0062;0061 05AE 0300 FE2E 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 TITLO LEFT HALF, LATIN SMALL LETTER B
0061 FE2E 0315 0300 05AE 0062;0061 05AE FE2E 0300 0315 0062;0061 05AE FE2E 0300 0315 0062;0061 05AE FE2E 0300 0315 0062;0061 05AE FE2E 0300 0315 0062; # (a◌︮◌̕◌̀◌֮b; a◌֮◌︮◌̀◌̕b; a◌֮◌︮◌̀◌̕b; a◌֮◌︮◌̀◌̕b; a◌֮◌︮◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO LEFT HALF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE FE2F 0062;00E0 05AE FE2F 0315 0062;0061 05AE 0300 FE2F 0315 0062;00E0 05AE FE2F 0315 0062;0061 05AE 0300 FE2F 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 TITLO RIGHT HALF, LATIN SMALL LETTER B
0061 FE2F 0315 0300 05AE 0062;0061 05AE FE2F 0300 0315 0062;0061 05AE FE2F 0300 0315 0062;0061 05AE FE2F 0300 0315 0062;0061 05AE FE2F 0300 0315 0062; # (a◌︯◌̕◌̀◌֮b; a◌֮◌︯◌̀◌̕b; a◌֮◌︯◌̀◌̕b; a◌֮◌︯◌̀◌̕b; a◌֮◌︯◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO RIGHT HALF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 101FD 0062;0061 302A 0316 101FD 059A 0062;0061 302A 0316 101FD 059A 0062;0061 302A 0316 101FD 059A 0062;0061 302A 0316 101FD 059A 0062; # (a◌֚◌̖◌〪◌𐇽b; a◌〪◌̖◌𐇽◌֚b; a◌〪◌̖◌𐇽◌֚b; a◌〪◌̖◌𐇽◌֚b; a◌〪◌̖◌𐇽◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE, LATIN SMALL LETTER B
-0061 101FD 059A 0316 302A 0062;0061 302A 101FD 0316 059A 0062;0061 302A 101FD 0316 059A 0062;0061 302A 101FD 0316 059A 0062;0061 302A 101FD 0316 059A 0062; # (a◌𐇽◌֚◌̖◌〪b; a◌〪◌𐇽◌̖◌֚b; a◌〪◌𐇽◌̖◌֚b; a◌〪◌𐇽◌̖◌֚b; a◌〪◌𐇽◌̖◌֚b; ) LATIN SMALL LETTER A, PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 102E0 0062;0061 302A 0316 102E0 059A 0062;0061 302A 0316 102E0 059A 0062;0061 302A 0316 102E0 059A 0062;0061 302A 0316 102E0 059A 0062; # (a◌֚◌̖◌〪◌𐋠b; a◌〪◌̖◌𐋠◌֚b; a◌〪◌̖◌𐋠◌֚b; a◌〪◌̖◌𐋠◌֚b; a◌〪◌̖◌𐋠◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COPTIC EPACT THOUSANDS MARK, LATIN SMALL LETTER B
-0061 102E0 059A 0316 302A 0062;0061 302A 102E0 0316 059A 0062;0061 302A 102E0 0316 059A 0062;0061 302A 102E0 0316 059A 0062;0061 302A 102E0 0316 059A 0062; # (a◌𐋠◌֚◌̖◌〪b; a◌〪◌𐋠◌̖◌֚b; a◌〪◌𐋠◌̖◌֚b; a◌〪◌𐋠◌̖◌֚b; a◌〪◌𐋠◌̖◌֚b; ) LATIN SMALL LETTER A, COPTIC EPACT THOUSANDS MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 101FD 0062;0061 1DFA 0316 101FD 059A 0062;0061 1DFA 0316 101FD 059A 0062;0061 1DFA 0316 101FD 059A 0062;0061 1DFA 0316 101FD 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, PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE, LATIN SMALL LETTER B
+0061 101FD 059A 0316 1DFA 0062;0061 1DFA 101FD 0316 059A 0062;0061 1DFA 101FD 0316 059A 0062;0061 1DFA 101FD 0316 059A 0062;0061 1DFA 101FD 0316 059A 0062; # (a◌𐇽◌֚◌̖◌᷺b; a◌᷺◌𐇽◌̖◌֚b; a◌᷺◌𐇽◌̖◌֚b; a◌᷺◌𐇽◌̖◌֚b; a◌᷺◌𐇽◌̖◌֚b; ) LATIN SMALL LETTER A, PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 102E0 0062;0061 1DFA 0316 102E0 059A 0062;0061 1DFA 0316 102E0 059A 0062;0061 1DFA 0316 102E0 059A 0062;0061 1DFA 0316 102E0 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, COPTIC EPACT THOUSANDS MARK, LATIN SMALL LETTER B
+0061 102E0 059A 0316 1DFA 0062;0061 1DFA 102E0 0316 059A 0062;0061 1DFA 102E0 0316 059A 0062;0061 1DFA 102E0 0316 059A 0062;0061 1DFA 102E0 0316 059A 0062; # (a◌𐋠◌֚◌̖◌᷺b; a◌᷺◌𐋠◌̖◌֚b; a◌᷺◌𐋠◌̖◌֚b; a◌᷺◌𐋠◌̖◌֚b; a◌᷺◌𐋠◌̖◌֚b; ) LATIN SMALL LETTER A, COPTIC EPACT THOUSANDS MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 10376 0062;00E0 05AE 10376 0315 0062;0061 05AE 0300 10376 0315 0062;00E0 05AE 10376 0315 0062;0061 05AE 0300 10376 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 OLD PERMIC LETTER AN, LATIN SMALL LETTER B
0061 10376 0315 0300 05AE 0062;0061 05AE 10376 0300 0315 0062;0061 05AE 10376 0300 0315 0062;0061 05AE 10376 0300 0315 0062;0061 05AE 10376 0300 0315 0062; # (a◌𐍶◌̕◌̀◌֮b; a◌֮◌𐍶◌̀◌̕b; a◌֮◌𐍶◌̀◌̕b; a◌֮◌𐍶◌̀◌̕b; a◌֮◌𐍶◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING OLD PERMIC LETTER AN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 10377 0062;00E0 05AE 10377 0315 0062;0061 05AE 0300 10377 0315 0062;00E0 05AE 10377 0315 0062;0061 05AE 0300 10377 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 OLD PERMIC LETTER DOI, LATIN SMALL LETTER B
@@ -18341,22 +18468,22 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 10379 0315 0300 05AE 0062;0061 05AE 10379 0300 0315 0062;0061 05AE 10379 0300 0315 0062;0061 05AE 10379 0300 0315 0062;0061 05AE 10379 0300 0315 0062; # (a◌𐍹◌̕◌̀◌֮b; a◌֮◌𐍹◌̀◌̕b; a◌֮◌𐍹◌̀◌̕b; a◌֮◌𐍹◌̀◌̕b; a◌֮◌𐍹◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING OLD PERMIC LETTER NENOE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1037A 0062;00E0 05AE 1037A 0315 0062;0061 05AE 0300 1037A 0315 0062;00E0 05AE 1037A 0315 0062;0061 05AE 0300 1037A 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 OLD PERMIC LETTER SII, LATIN SMALL LETTER B
0061 1037A 0315 0300 05AE 0062;0061 05AE 1037A 0300 0315 0062;0061 05AE 1037A 0300 0315 0062;0061 05AE 1037A 0300 0315 0062;0061 05AE 1037A 0300 0315 0062; # (a◌𐍺◌̕◌̀◌֮b; a◌֮◌𐍺◌̀◌̕b; a◌֮◌𐍺◌̀◌̕b; a◌֮◌𐍺◌̀◌̕b; a◌֮◌𐍺◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING OLD PERMIC LETTER SII, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 10A0D 0062;0061 302A 0316 10A0D 059A 0062;0061 302A 0316 10A0D 059A 0062;0061 302A 0316 10A0D 059A 0062;0061 302A 0316 10A0D 059A 0062; # (a◌֚◌̖◌〪◌𐨍b; a◌〪◌̖◌𐨍◌֚b; a◌〪◌̖◌𐨍◌֚b; a◌〪◌̖◌𐨍◌֚b; a◌〪◌̖◌𐨍◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, KHAROSHTHI SIGN DOUBLE RING BELOW, LATIN SMALL LETTER B
-0061 10A0D 059A 0316 302A 0062;0061 302A 10A0D 0316 059A 0062;0061 302A 10A0D 0316 059A 0062;0061 302A 10A0D 0316 059A 0062;0061 302A 10A0D 0316 059A 0062; # (a◌𐨍◌֚◌̖◌〪b; a◌〪◌𐨍◌̖◌֚b; a◌〪◌𐨍◌̖◌֚b; a◌〪◌𐨍◌̖◌֚b; a◌〪◌𐨍◌̖◌֚b; ) LATIN SMALL LETTER A, KHAROSHTHI SIGN DOUBLE RING BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 10A0D 0062;0061 1DFA 0316 10A0D 059A 0062;0061 1DFA 0316 10A0D 059A 0062;0061 1DFA 0316 10A0D 059A 0062;0061 1DFA 0316 10A0D 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, KHAROSHTHI SIGN DOUBLE RING BELOW, LATIN SMALL LETTER B
+0061 10A0D 059A 0316 1DFA 0062;0061 1DFA 10A0D 0316 059A 0062;0061 1DFA 10A0D 0316 059A 0062;0061 1DFA 10A0D 0316 059A 0062;0061 1DFA 10A0D 0316 059A 0062; # (a◌𐨍◌֚◌̖◌᷺b; a◌᷺◌𐨍◌̖◌֚b; a◌᷺◌𐨍◌̖◌֚b; a◌᷺◌𐨍◌̖◌֚b; a◌᷺◌𐨍◌̖◌֚b; ) LATIN SMALL LETTER A, KHAROSHTHI SIGN DOUBLE RING BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 10A0F 0062;00E0 05AE 10A0F 0315 0062;0061 05AE 0300 10A0F 0315 0062;00E0 05AE 10A0F 0315 0062;0061 05AE 0300 10A0F 0315 0062; # (a◌̕◌̀◌֮◌𐨏b; à◌֮◌𐨏◌̕b; a◌֮◌̀◌𐨏◌̕b; à◌֮◌𐨏◌̕b; a◌֮◌̀◌𐨏◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, KHAROSHTHI SIGN VISARGA, LATIN SMALL LETTER B
0061 10A0F 0315 0300 05AE 0062;0061 05AE 10A0F 0300 0315 0062;0061 05AE 10A0F 0300 0315 0062;0061 05AE 10A0F 0300 0315 0062;0061 05AE 10A0F 0300 0315 0062; # (a◌𐨏◌̕◌̀◌֮b; a◌֮◌𐨏◌̀◌̕b; a◌֮◌𐨏◌̀◌̕b; a◌֮◌𐨏◌̀◌̕b; a◌֮◌𐨏◌̀◌̕b; ) LATIN SMALL LETTER A, KHAROSHTHI SIGN VISARGA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 10A38 0062;00E0 05AE 10A38 0315 0062;0061 05AE 0300 10A38 0315 0062;00E0 05AE 10A38 0315 0062;0061 05AE 0300 10A38 0315 0062; # (a◌̕◌̀◌֮◌𐨸b; à◌֮◌𐨸◌̕b; a◌֮◌̀◌𐨸◌̕b; à◌֮◌𐨸◌̕b; a◌֮◌̀◌𐨸◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, KHAROSHTHI SIGN BAR ABOVE, LATIN SMALL LETTER B
0061 10A38 0315 0300 05AE 0062;0061 05AE 10A38 0300 0315 0062;0061 05AE 10A38 0300 0315 0062;0061 05AE 10A38 0300 0315 0062;0061 05AE 10A38 0300 0315 0062; # (a◌𐨸◌̕◌̀◌֮b; a◌֮◌𐨸◌̀◌̕b; a◌֮◌𐨸◌̀◌̕b; a◌֮◌𐨸◌̀◌̕b; a◌֮◌𐨸◌̀◌̕b; ) LATIN SMALL LETTER A, KHAROSHTHI SIGN BAR ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 16FF0 0334 10A39 0062;0061 0334 10A39 16FF0 0062;0061 0334 10A39 16FF0 0062;0061 0334 10A39 16FF0 0062;0061 0334 10A39 16FF0 0062; # (a𖿰◌̴◌𐨹b; a◌̴◌𐨹𖿰b; a◌̴◌𐨹𖿰b; a◌̴◌𐨹𖿰b; a◌̴◌𐨹𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, KHAROSHTHI SIGN CAUDA, LATIN SMALL LETTER B
0061 10A39 16FF0 0334 0062;0061 10A39 0334 16FF0 0062;0061 10A39 0334 16FF0 0062;0061 10A39 0334 16FF0 0062;0061 10A39 0334 16FF0 0062; # (a◌𐨹𖿰◌̴b; a◌𐨹◌̴𖿰b; a◌𐨹◌̴𖿰b; a◌𐨹◌̴𖿰b; a◌𐨹◌̴𖿰b; ) LATIN SMALL LETTER A, KHAROSHTHI SIGN CAUDA, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
-0061 059A 0316 302A 10A3A 0062;0061 302A 0316 10A3A 059A 0062;0061 302A 0316 10A3A 059A 0062;0061 302A 0316 10A3A 059A 0062;0061 302A 0316 10A3A 059A 0062; # (a◌֚◌̖◌〪◌𐨺b; a◌〪◌̖◌𐨺◌֚b; a◌〪◌̖◌𐨺◌֚b; a◌〪◌̖◌𐨺◌֚b; a◌〪◌̖◌𐨺◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, KHAROSHTHI SIGN DOT BELOW, LATIN SMALL LETTER B
-0061 10A3A 059A 0316 302A 0062;0061 302A 10A3A 0316 059A 0062;0061 302A 10A3A 0316 059A 0062;0061 302A 10A3A 0316 059A 0062;0061 302A 10A3A 0316 059A 0062; # (a◌𐨺◌֚◌̖◌〪b; a◌〪◌𐨺◌̖◌֚b; a◌〪◌𐨺◌̖◌֚b; a◌〪◌𐨺◌̖◌֚b; a◌〪◌𐨺◌̖◌֚b; ) LATIN SMALL LETTER A, KHAROSHTHI SIGN DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 10A3A 0062;0061 1DFA 0316 10A3A 059A 0062;0061 1DFA 0316 10A3A 059A 0062;0061 1DFA 0316 10A3A 059A 0062;0061 1DFA 0316 10A3A 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, KHAROSHTHI SIGN DOT BELOW, LATIN SMALL LETTER B
+0061 10A3A 059A 0316 1DFA 0062;0061 1DFA 10A3A 0316 059A 0062;0061 1DFA 10A3A 0316 059A 0062;0061 1DFA 10A3A 0316 059A 0062;0061 1DFA 10A3A 0316 059A 0062; # (a◌𐨺◌֚◌̖◌᷺b; a◌᷺◌𐨺◌̖◌֚b; a◌᷺◌𐨺◌̖◌֚b; a◌᷺◌𐨺◌̖◌֚b; a◌᷺◌𐨺◌̖◌֚b; ) LATIN SMALL LETTER A, KHAROSHTHI SIGN DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 05B0 094D 3099 10A3F 0062;0061 3099 094D 10A3F 05B0 0062;0061 3099 094D 10A3F 05B0 0062;0061 3099 094D 10A3F 05B0 0062;0061 3099 094D 10A3F 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, KHAROSHTHI VIRAMA, LATIN SMALL LETTER B
0061 10A3F 05B0 094D 3099 0062;0061 3099 10A3F 094D 05B0 0062;0061 3099 10A3F 094D 05B0 0062;0061 3099 10A3F 094D 05B0 0062;0061 3099 10A3F 094D 05B0 0062; # (a◌𐨿◌ְ◌्◌゙b; a◌゙◌𐨿◌्◌ְb; a◌゙◌𐨿◌्◌ְb; a◌゙◌𐨿◌्◌ְb; a◌゙◌𐨿◌्◌ְb; ) LATIN SMALL LETTER A, KHAROSHTHI VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
0061 0315 0300 05AE 10AE5 0062;00E0 05AE 10AE5 0315 0062;0061 05AE 0300 10AE5 0315 0062;00E0 05AE 10AE5 0315 0062;0061 05AE 0300 10AE5 0315 0062; # (a◌̕◌̀◌֮◌𐫥b; à◌֮◌𐫥◌̕b; a◌֮◌̀◌𐫥◌̕b; à◌֮◌𐫥◌̕b; a◌֮◌̀◌𐫥◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MANICHAEAN ABBREVIATION MARK ABOVE, LATIN SMALL LETTER B
0061 10AE5 0315 0300 05AE 0062;0061 05AE 10AE5 0300 0315 0062;0061 05AE 10AE5 0300 0315 0062;0061 05AE 10AE5 0300 0315 0062;0061 05AE 10AE5 0300 0315 0062; # (a◌𐫥◌̕◌̀◌֮b; a◌֮◌𐫥◌̀◌̕b; a◌֮◌𐫥◌̀◌̕b; a◌֮◌𐫥◌̀◌̕b; a◌֮◌𐫥◌̀◌̕b; ) LATIN SMALL LETTER A, MANICHAEAN ABBREVIATION MARK ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 10AE6 0062;0061 302A 0316 10AE6 059A 0062;0061 302A 0316 10AE6 059A 0062;0061 302A 0316 10AE6 059A 0062;0061 302A 0316 10AE6 059A 0062; # (a◌֚◌̖◌〪◌𐫦b; a◌〪◌̖◌𐫦◌֚b; a◌〪◌̖◌𐫦◌֚b; a◌〪◌̖◌𐫦◌֚b; a◌〪◌̖◌𐫦◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MANICHAEAN ABBREVIATION MARK BELOW, LATIN SMALL LETTER B
-0061 10AE6 059A 0316 302A 0062;0061 302A 10AE6 0316 059A 0062;0061 302A 10AE6 0316 059A 0062;0061 302A 10AE6 0316 059A 0062;0061 302A 10AE6 0316 059A 0062; # (a◌𐫦◌֚◌̖◌〪b; a◌〪◌𐫦◌̖◌֚b; a◌〪◌𐫦◌̖◌֚b; a◌〪◌𐫦◌̖◌֚b; a◌〪◌𐫦◌̖◌֚b; ) LATIN SMALL LETTER A, MANICHAEAN ABBREVIATION MARK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 10AE6 0062;0061 1DFA 0316 10AE6 059A 0062;0061 1DFA 0316 10AE6 059A 0062;0061 1DFA 0316 10AE6 059A 0062;0061 1DFA 0316 10AE6 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, MANICHAEAN ABBREVIATION MARK BELOW, LATIN SMALL LETTER B
+0061 10AE6 059A 0316 1DFA 0062;0061 1DFA 10AE6 0316 059A 0062;0061 1DFA 10AE6 0316 059A 0062;0061 1DFA 10AE6 0316 059A 0062;0061 1DFA 10AE6 0316 059A 0062; # (a◌𐫦◌֚◌̖◌᷺b; a◌᷺◌𐫦◌̖◌֚b; a◌᷺◌𐫦◌̖◌֚b; a◌᷺◌𐫦◌̖◌֚b; a◌᷺◌𐫦◌̖◌֚b; ) LATIN SMALL LETTER A, MANICHAEAN ABBREVIATION MARK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 10D24 0062;00E0 05AE 10D24 0315 0062;0061 05AE 0300 10D24 0315 0062;00E0 05AE 10D24 0315 0062;0061 05AE 0300 10D24 0315 0062; # (a◌̕◌̀◌֮◌𐴤b; à◌֮◌𐴤◌̕b; a◌֮◌̀◌𐴤◌̕b; à◌֮◌𐴤◌̕b; a◌֮◌̀◌𐴤◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HANIFI ROHINGYA SIGN HARBAHAY, LATIN SMALL LETTER B
0061 10D24 0315 0300 05AE 0062;0061 05AE 10D24 0300 0315 0062;0061 05AE 10D24 0300 0315 0062;0061 05AE 10D24 0300 0315 0062;0061 05AE 10D24 0300 0315 0062; # (a◌𐴤◌̕◌̀◌֮b; a◌֮◌𐴤◌̀◌̕b; a◌֮◌𐴤◌̀◌̕b; a◌֮◌𐴤◌̀◌̕b; a◌֮◌𐴤◌̀◌̕b; ) LATIN SMALL LETTER A, HANIFI ROHINGYA SIGN HARBAHAY, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 10D25 0062;00E0 05AE 10D25 0315 0062;0061 05AE 0300 10D25 0315 0062;00E0 05AE 10D25 0315 0062;0061 05AE 0300 10D25 0315 0062; # (a◌̕◌̀◌֮◌𐴥b; à◌֮◌𐴥◌̕b; a◌֮◌̀◌𐴥◌̕b; à◌֮◌𐴥◌̕b; a◌֮◌̀◌𐴥◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HANIFI ROHINGYA SIGN TAHALA, LATIN SMALL LETTER B
@@ -18369,30 +18496,40 @@ 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 302A 10F46 0062;0061 302A 0316 10F46 059A 0062;0061 302A 0316 10F46 059A 0062;0061 302A 0316 10F46 059A 0062;0061 302A 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, IDEOGRAPHIC LEVEL TONE MARK, SOGDIAN COMBINING DOT BELOW, LATIN SMALL LETTER B
-0061 10F46 059A 0316 302A 0062;0061 302A 10F46 0316 059A 0062;0061 302A 10F46 0316 059A 0062;0061 302A 10F46 0316 059A 0062;0061 302A 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, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 10F47 0062;0061 302A 0316 10F47 059A 0062;0061 302A 0316 10F47 059A 0062;0061 302A 0316 10F47 059A 0062;0061 302A 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, IDEOGRAPHIC LEVEL TONE MARK, SOGDIAN COMBINING TWO DOTS BELOW, LATIN SMALL LETTER B
-0061 10F47 059A 0316 302A 0062;0061 302A 10F47 0316 059A 0062;0061 302A 10F47 0316 059A 0062;0061 302A 10F47 0316 059A 0062;0061 302A 10F47 0316 059A 0062; # (a◌𐽇◌֚◌̖◌〪b; a◌〪◌𐽇◌̖◌֚b; a◌〪◌𐽇◌̖◌֚b; a◌〪◌𐽇◌̖◌֚b; a◌〪◌𐽇◌̖◌֚b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING TWO DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, 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
+0061 10F47 059A 0316 1DFA 0062;0061 1DFA 10F47 0316 059A 0062;0061 1DFA 10F47 0316 059A 0062;0061 1DFA 10F47 0316 059A 0062;0061 1DFA 10F47 0316 059A 0062; # (a◌𐽇◌֚◌̖◌᷺b; a◌᷺◌𐽇◌̖◌֚b; a◌᷺◌𐽇◌̖◌֚b; a◌᷺◌𐽇◌̖◌֚b; a◌᷺◌𐽇◌̖◌֚b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING TWO DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 10F48 0062;00E0 05AE 10F48 0315 0062;0061 05AE 0300 10F48 0315 0062;00E0 05AE 10F48 0315 0062;0061 05AE 0300 10F48 0315 0062; # (a◌̕◌̀◌֮◌𐽈b; à◌֮◌𐽈◌̕b; a◌֮◌̀◌𐽈◌̕b; à◌֮◌𐽈◌̕b; a◌֮◌̀◌𐽈◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SOGDIAN COMBINING DOT ABOVE, LATIN SMALL LETTER B
0061 10F48 0315 0300 05AE 0062;0061 05AE 10F48 0300 0315 0062;0061 05AE 10F48 0300 0315 0062;0061 05AE 10F48 0300 0315 0062;0061 05AE 10F48 0300 0315 0062; # (a◌𐽈◌̕◌̀◌֮b; a◌֮◌𐽈◌̀◌̕b; a◌֮◌𐽈◌̀◌̕b; a◌֮◌𐽈◌̀◌̕b; a◌֮◌𐽈◌̀◌̕b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING DOT ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 10F49 0062;00E0 05AE 10F49 0315 0062;0061 05AE 0300 10F49 0315 0062;00E0 05AE 10F49 0315 0062;0061 05AE 0300 10F49 0315 0062; # (a◌̕◌̀◌֮◌𐽉b; à◌֮◌𐽉◌̕b; a◌֮◌̀◌𐽉◌̕b; à◌֮◌𐽉◌̕b; a◌֮◌̀◌𐽉◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SOGDIAN COMBINING TWO DOTS ABOVE, LATIN SMALL LETTER B
0061 10F49 0315 0300 05AE 0062;0061 05AE 10F49 0300 0315 0062;0061 05AE 10F49 0300 0315 0062;0061 05AE 10F49 0300 0315 0062;0061 05AE 10F49 0300 0315 0062; # (a◌𐽉◌̕◌̀◌֮b; a◌֮◌𐽉◌̀◌̕b; a◌֮◌𐽉◌̀◌̕b; a◌֮◌𐽉◌̀◌̕b; a◌֮◌𐽉◌̀◌̕b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING TWO DOTS ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 10F4A 0062;00E0 05AE 10F4A 0315 0062;0061 05AE 0300 10F4A 0315 0062;00E0 05AE 10F4A 0315 0062;0061 05AE 0300 10F4A 0315 0062; # (a◌̕◌̀◌֮◌𐽊b; à◌֮◌𐽊◌̕b; a◌֮◌̀◌𐽊◌̕b; à◌֮◌𐽊◌̕b; a◌֮◌̀◌𐽊◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SOGDIAN COMBINING CURVE ABOVE, LATIN SMALL LETTER B
0061 10F4A 0315 0300 05AE 0062;0061 05AE 10F4A 0300 0315 0062;0061 05AE 10F4A 0300 0315 0062;0061 05AE 10F4A 0300 0315 0062;0061 05AE 10F4A 0300 0315 0062; # (a◌𐽊◌̕◌̀◌֮b; a◌֮◌𐽊◌̀◌̕b; a◌֮◌𐽊◌̀◌̕b; a◌֮◌𐽊◌̀◌̕b; a◌֮◌𐽊◌̀◌̕b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING CURVE ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 10F4B 0062;0061 302A 0316 10F4B 059A 0062;0061 302A 0316 10F4B 059A 0062;0061 302A 0316 10F4B 059A 0062;0061 302A 0316 10F4B 059A 0062; # (a◌֚◌̖◌〪◌𐽋b; a◌〪◌̖◌𐽋◌֚b; a◌〪◌̖◌𐽋◌֚b; a◌〪◌̖◌𐽋◌֚b; a◌〪◌̖◌𐽋◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SOGDIAN COMBINING CURVE BELOW, LATIN SMALL LETTER B
-0061 10F4B 059A 0316 302A 0062;0061 302A 10F4B 0316 059A 0062;0061 302A 10F4B 0316 059A 0062;0061 302A 10F4B 0316 059A 0062;0061 302A 10F4B 0316 059A 0062; # (a◌𐽋◌֚◌̖◌〪b; a◌〪◌𐽋◌̖◌֚b; a◌〪◌𐽋◌̖◌֚b; a◌〪◌𐽋◌̖◌֚b; a◌〪◌𐽋◌̖◌֚b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING CURVE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 10F4B 0062;0061 1DFA 0316 10F4B 059A 0062;0061 1DFA 0316 10F4B 059A 0062;0061 1DFA 0316 10F4B 059A 0062;0061 1DFA 0316 10F4B 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 CURVE BELOW, LATIN SMALL LETTER B
+0061 10F4B 059A 0316 1DFA 0062;0061 1DFA 10F4B 0316 059A 0062;0061 1DFA 10F4B 0316 059A 0062;0061 1DFA 10F4B 0316 059A 0062;0061 1DFA 10F4B 0316 059A 0062; # (a◌𐽋◌֚◌̖◌᷺b; a◌᷺◌𐽋◌̖◌֚b; a◌᷺◌𐽋◌̖◌֚b; a◌᷺◌𐽋◌̖◌֚b; a◌᷺◌𐽋◌̖◌֚b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING CURVE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 10F4C 0062;00E0 05AE 10F4C 0315 0062;0061 05AE 0300 10F4C 0315 0062;00E0 05AE 10F4C 0315 0062;0061 05AE 0300 10F4C 0315 0062; # (a◌̕◌̀◌֮◌𐽌b; à◌֮◌𐽌◌̕b; a◌֮◌̀◌𐽌◌̕b; à◌֮◌𐽌◌̕b; a◌֮◌̀◌𐽌◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SOGDIAN COMBINING HOOK ABOVE, LATIN SMALL LETTER B
0061 10F4C 0315 0300 05AE 0062;0061 05AE 10F4C 0300 0315 0062;0061 05AE 10F4C 0300 0315 0062;0061 05AE 10F4C 0300 0315 0062;0061 05AE 10F4C 0300 0315 0062; # (a◌𐽌◌̕◌̀◌֮b; a◌֮◌𐽌◌̀◌̕b; a◌֮◌𐽌◌̀◌̕b; a◌֮◌𐽌◌̀◌̕b; a◌֮◌𐽌◌̀◌̕b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING HOOK ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 10F4D 0062;0061 302A 0316 10F4D 059A 0062;0061 302A 0316 10F4D 059A 0062;0061 302A 0316 10F4D 059A 0062;0061 302A 0316 10F4D 059A 0062; # (a◌֚◌̖◌〪◌𐽍b; a◌〪◌̖◌𐽍◌֚b; a◌〪◌̖◌𐽍◌֚b; a◌〪◌̖◌𐽍◌֚b; a◌〪◌̖◌𐽍◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SOGDIAN COMBINING HOOK BELOW, LATIN SMALL LETTER B
-0061 10F4D 059A 0316 302A 0062;0061 302A 10F4D 0316 059A 0062;0061 302A 10F4D 0316 059A 0062;0061 302A 10F4D 0316 059A 0062;0061 302A 10F4D 0316 059A 0062; # (a◌𐽍◌֚◌̖◌〪b; a◌〪◌𐽍◌̖◌֚b; a◌〪◌𐽍◌̖◌֚b; a◌〪◌𐽍◌̖◌֚b; a◌〪◌𐽍◌̖◌֚b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING HOOK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 10F4E 0062;0061 302A 0316 10F4E 059A 0062;0061 302A 0316 10F4E 059A 0062;0061 302A 0316 10F4E 059A 0062;0061 302A 0316 10F4E 059A 0062; # (a◌֚◌̖◌〪◌𐽎b; a◌〪◌̖◌𐽎◌֚b; a◌〪◌̖◌𐽎◌֚b; a◌〪◌̖◌𐽎◌֚b; a◌〪◌̖◌𐽎◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SOGDIAN COMBINING LONG HOOK BELOW, LATIN SMALL LETTER B
-0061 10F4E 059A 0316 302A 0062;0061 302A 10F4E 0316 059A 0062;0061 302A 10F4E 0316 059A 0062;0061 302A 10F4E 0316 059A 0062;0061 302A 10F4E 0316 059A 0062; # (a◌𐽎◌֚◌̖◌〪b; a◌〪◌𐽎◌̖◌֚b; a◌〪◌𐽎◌̖◌֚b; a◌〪◌𐽎◌̖◌֚b; a◌〪◌𐽎◌̖◌֚b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING LONG HOOK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 10F4F 0062;0061 302A 0316 10F4F 059A 0062;0061 302A 0316 10F4F 059A 0062;0061 302A 0316 10F4F 059A 0062;0061 302A 0316 10F4F 059A 0062; # (a◌֚◌̖◌〪◌𐽏b; a◌〪◌̖◌𐽏◌֚b; a◌〪◌̖◌𐽏◌֚b; a◌〪◌̖◌𐽏◌֚b; a◌〪◌̖◌𐽏◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SOGDIAN COMBINING RESH BELOW, LATIN SMALL LETTER B
-0061 10F4F 059A 0316 302A 0062;0061 302A 10F4F 0316 059A 0062;0061 302A 10F4F 0316 059A 0062;0061 302A 10F4F 0316 059A 0062;0061 302A 10F4F 0316 059A 0062; # (a◌𐽏◌֚◌̖◌〪b; a◌〪◌𐽏◌̖◌֚b; a◌〪◌𐽏◌̖◌֚b; a◌〪◌𐽏◌̖◌֚b; a◌〪◌𐽏◌̖◌֚b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING RESH BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 10F50 0062;0061 302A 0316 10F50 059A 0062;0061 302A 0316 10F50 059A 0062;0061 302A 0316 10F50 059A 0062;0061 302A 0316 10F50 059A 0062; # (a◌֚◌̖◌〪◌𐽐b; a◌〪◌̖◌𐽐◌֚b; a◌〪◌̖◌𐽐◌֚b; a◌〪◌̖◌𐽐◌֚b; a◌〪◌̖◌𐽐◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SOGDIAN COMBINING STROKE BELOW, LATIN SMALL LETTER B
-0061 10F50 059A 0316 302A 0062;0061 302A 10F50 0316 059A 0062;0061 302A 10F50 0316 059A 0062;0061 302A 10F50 0316 059A 0062;0061 302A 10F50 0316 059A 0062; # (a◌𐽐◌֚◌̖◌〪b; a◌〪◌𐽐◌̖◌֚b; a◌〪◌𐽐◌̖◌֚b; a◌〪◌𐽐◌̖◌֚b; a◌〪◌𐽐◌̖◌֚b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING STROKE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 10F4D 0062;0061 1DFA 0316 10F4D 059A 0062;0061 1DFA 0316 10F4D 059A 0062;0061 1DFA 0316 10F4D 059A 0062;0061 1DFA 0316 10F4D 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 HOOK BELOW, LATIN SMALL LETTER B
+0061 10F4D 059A 0316 1DFA 0062;0061 1DFA 10F4D 0316 059A 0062;0061 1DFA 10F4D 0316 059A 0062;0061 1DFA 10F4D 0316 059A 0062;0061 1DFA 10F4D 0316 059A 0062; # (a◌𐽍◌֚◌̖◌᷺b; a◌᷺◌𐽍◌̖◌֚b; a◌᷺◌𐽍◌̖◌֚b; a◌᷺◌𐽍◌̖◌֚b; a◌᷺◌𐽍◌̖◌֚b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING HOOK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 10F4E 0062;0061 1DFA 0316 10F4E 059A 0062;0061 1DFA 0316 10F4E 059A 0062;0061 1DFA 0316 10F4E 059A 0062;0061 1DFA 0316 10F4E 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 LONG HOOK BELOW, LATIN SMALL LETTER B
+0061 10F4E 059A 0316 1DFA 0062;0061 1DFA 10F4E 0316 059A 0062;0061 1DFA 10F4E 0316 059A 0062;0061 1DFA 10F4E 0316 059A 0062;0061 1DFA 10F4E 0316 059A 0062; # (a◌𐽎◌֚◌̖◌᷺b; a◌᷺◌𐽎◌̖◌֚b; a◌᷺◌𐽎◌̖◌֚b; a◌᷺◌𐽎◌̖◌֚b; a◌᷺◌𐽎◌̖◌֚b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING LONG HOOK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 10F4F 0062;0061 1DFA 0316 10F4F 059A 0062;0061 1DFA 0316 10F4F 059A 0062;0061 1DFA 0316 10F4F 059A 0062;0061 1DFA 0316 10F4F 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 RESH BELOW, LATIN SMALL LETTER B
+0061 10F4F 059A 0316 1DFA 0062;0061 1DFA 10F4F 0316 059A 0062;0061 1DFA 10F4F 0316 059A 0062;0061 1DFA 10F4F 0316 059A 0062;0061 1DFA 10F4F 0316 059A 0062; # (a◌𐽏◌֚◌̖◌᷺b; a◌᷺◌𐽏◌̖◌֚b; a◌᷺◌𐽏◌̖◌֚b; a◌᷺◌𐽏◌̖◌֚b; a◌᷺◌𐽏◌̖◌֚b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING RESH BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 10F50 0062;0061 1DFA 0316 10F50 059A 0062;0061 1DFA 0316 10F50 059A 0062;0061 1DFA 0316 10F50 059A 0062;0061 1DFA 0316 10F50 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 STROKE BELOW, LATIN SMALL LETTER B
+0061 10F50 059A 0316 1DFA 0062;0061 1DFA 10F50 0316 059A 0062;0061 1DFA 10F50 0316 059A 0062;0061 1DFA 10F50 0316 059A 0062;0061 1DFA 10F50 0316 059A 0062; # (a◌𐽐◌֚◌̖◌᷺b; a◌᷺◌𐽐◌̖◌֚b; a◌᷺◌𐽐◌̖◌֚b; a◌᷺◌𐽐◌̖◌֚b; a◌᷺◌𐽐◌̖◌֚b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING STROKE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 0315 0300 05AE 10F82 0062;00E0 05AE 10F82 0315 0062;0061 05AE 0300 10F82 0315 0062;00E0 05AE 10F82 0315 0062;0061 05AE 0300 10F82 0315 0062; # (a◌̕◌̀◌֮◌𐾂b; à◌֮◌𐾂◌̕b; a◌֮◌̀◌𐾂◌̕b; à◌֮◌𐾂◌̕b; a◌֮◌̀◌𐾂◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, OLD UYGHUR COMBINING DOT ABOVE, LATIN SMALL LETTER B
+0061 10F82 0315 0300 05AE 0062;0061 05AE 10F82 0300 0315 0062;0061 05AE 10F82 0300 0315 0062;0061 05AE 10F82 0300 0315 0062;0061 05AE 10F82 0300 0315 0062; # (a◌𐾂◌̕◌̀◌֮b; a◌֮◌𐾂◌̀◌̕b; a◌֮◌𐾂◌̀◌̕b; a◌֮◌𐾂◌̀◌̕b; a◌֮◌𐾂◌̀◌̕b; ) LATIN SMALL LETTER A, OLD UYGHUR COMBINING DOT ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 10F83 0062;0061 1DFA 0316 10F83 059A 0062;0061 1DFA 0316 10F83 059A 0062;0061 1DFA 0316 10F83 059A 0062;0061 1DFA 0316 10F83 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, OLD UYGHUR COMBINING DOT BELOW, LATIN SMALL LETTER B
+0061 10F83 059A 0316 1DFA 0062;0061 1DFA 10F83 0316 059A 0062;0061 1DFA 10F83 0316 059A 0062;0061 1DFA 10F83 0316 059A 0062;0061 1DFA 10F83 0316 059A 0062; # (a◌𐾃◌֚◌̖◌᷺b; a◌᷺◌𐾃◌̖◌֚b; a◌᷺◌𐾃◌̖◌֚b; a◌᷺◌𐾃◌̖◌֚b; a◌᷺◌𐾃◌̖◌֚b; ) LATIN SMALL LETTER A, OLD UYGHUR COMBINING DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 0315 0300 05AE 10F84 0062;00E0 05AE 10F84 0315 0062;0061 05AE 0300 10F84 0315 0062;00E0 05AE 10F84 0315 0062;0061 05AE 0300 10F84 0315 0062; # (a◌̕◌̀◌֮◌𐾄b; à◌֮◌𐾄◌̕b; a◌֮◌̀◌𐾄◌̕b; à◌֮◌𐾄◌̕b; a◌֮◌̀◌𐾄◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, OLD UYGHUR COMBINING TWO DOTS ABOVE, LATIN SMALL LETTER B
+0061 10F84 0315 0300 05AE 0062;0061 05AE 10F84 0300 0315 0062;0061 05AE 10F84 0300 0315 0062;0061 05AE 10F84 0300 0315 0062;0061 05AE 10F84 0300 0315 0062; # (a◌𐾄◌̕◌̀◌֮b; a◌֮◌𐾄◌̀◌̕b; a◌֮◌𐾄◌̀◌̕b; a◌֮◌𐾄◌̀◌̕b; a◌֮◌𐾄◌̀◌̕b; ) LATIN SMALL LETTER A, OLD UYGHUR COMBINING TWO DOTS ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 10F85 0062;0061 1DFA 0316 10F85 059A 0062;0061 1DFA 0316 10F85 059A 0062;0061 1DFA 0316 10F85 059A 0062;0061 1DFA 0316 10F85 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, OLD UYGHUR COMBINING TWO DOTS BELOW, LATIN SMALL LETTER B
+0061 10F85 059A 0316 1DFA 0062;0061 1DFA 10F85 0316 059A 0062;0061 1DFA 10F85 0316 059A 0062;0061 1DFA 10F85 0316 059A 0062;0061 1DFA 10F85 0316 059A 0062; # (a◌𐾅◌֚◌̖◌᷺b; a◌᷺◌𐾅◌̖◌֚b; a◌᷺◌𐾅◌̖◌֚b; a◌᷺◌𐾅◌̖◌֚b; a◌᷺◌𐾅◌̖◌֚b; ) LATIN SMALL LETTER A, OLD UYGHUR COMBINING TWO DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 05B0 094D 3099 11046 0062;0061 3099 094D 11046 05B0 0062;0061 3099 094D 11046 05B0 0062;0061 3099 094D 11046 05B0 0062;0061 3099 094D 11046 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, BRAHMI VIRAMA, LATIN SMALL LETTER B
0061 11046 05B0 094D 3099 0062;0061 3099 11046 094D 05B0 0062;0061 3099 11046 094D 05B0 0062;0061 3099 11046 094D 05B0 0062;0061 3099 11046 094D 05B0 0062; # (a◌𑁆◌ְ◌्◌゙b; a◌゙◌𑁆◌्◌ְb; a◌゙◌𑁆◌्◌ְb; a◌゙◌𑁆◌्◌ְb; a◌゙◌𑁆◌्◌ְb; ) LATIN SMALL LETTER A, BRAHMI VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 11070 0062;0061 3099 094D 11070 05B0 0062;0061 3099 094D 11070 05B0 0062;0061 3099 094D 11070 05B0 0062;0061 3099 094D 11070 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, BRAHMI SIGN OLD TAMIL VIRAMA, LATIN SMALL LETTER B
+0061 11070 05B0 094D 3099 0062;0061 3099 11070 094D 05B0 0062;0061 3099 11070 094D 05B0 0062;0061 3099 11070 094D 05B0 0062;0061 3099 11070 094D 05B0 0062; # (a◌𑁰◌ְ◌्◌゙b; a◌゙◌𑁰◌्◌ְb; a◌゙◌𑁰◌्◌ְb; a◌゙◌𑁰◌्◌ְb; a◌゙◌𑁰◌्◌ְb; ) LATIN SMALL LETTER A, BRAHMI SIGN OLD TAMIL VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
0061 05B0 094D 3099 1107F 0062;0061 3099 094D 1107F 05B0 0062;0061 3099 094D 1107F 05B0 0062;0061 3099 094D 1107F 05B0 0062;0061 3099 094D 1107F 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, BRAHMI NUMBER JOINER, LATIN SMALL LETTER B
0061 1107F 05B0 094D 3099 0062;0061 3099 1107F 094D 05B0 0062;0061 3099 1107F 094D 05B0 0062;0061 3099 1107F 094D 05B0 0062;0061 3099 1107F 094D 05B0 0062; # (a◌𑁿◌ְ◌्◌゙b; a◌゙◌𑁿◌्◌ְb; a◌゙◌𑁿◌्◌ְb; a◌゙◌𑁿◌्◌ְb; a◌゙◌𑁿◌्◌ְb; ) LATIN SMALL LETTER A, BRAHMI NUMBER JOINER, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
0061 05B0 094D 3099 110B9 0062;0061 3099 094D 110B9 05B0 0062;0061 3099 094D 110B9 05B0 0062;0061 3099 094D 110B9 05B0 0062;0061 3099 094D 110B9 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, KAITHI SIGN VIRAMA, LATIN SMALL LETTER B
@@ -18533,10 +18670,10 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 16FF1 093C 16FF0 0334 0062;0061 0334 16FF1 16FF0 093C 0062;0061 0334 16FF1 16FF0 093C 0062;0061 0334 16FF1 16FF0 093C 0062;0061 0334 16FF1 16FF0 093C 0062; # (a𖿱◌𖿰़◌̴b; a◌̴𖿱𖿰◌़b; a◌̴𖿱𖿰◌़b; a◌̴𖿱𖿰◌़b; a◌̴𖿱𖿰◌़b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK NHAY, DEVANAGARI SIGN NUKTA, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
0061 16FF0 0334 1BC9E 0062;0061 0334 1BC9E 16FF0 0062;0061 0334 1BC9E 16FF0 0062;0061 0334 1BC9E 16FF0 0062;0061 0334 1BC9E 16FF0 0062; # (a𖿰◌̴◌𛲞b; a◌̴◌𛲞𖿰b; a◌̴◌𛲞𖿰b; a◌̴◌𛲞𖿰b; a◌̴◌𛲞𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, DUPLOYAN DOUBLE MARK, LATIN SMALL LETTER B
0061 1BC9E 16FF0 0334 0062;0061 1BC9E 0334 16FF0 0062;0061 1BC9E 0334 16FF0 0062;0061 1BC9E 0334 16FF0 0062;0061 1BC9E 0334 16FF0 0062; # (a◌𛲞𖿰◌̴b; a◌𛲞◌̴𖿰b; a◌𛲞◌̴𖿰b; a◌𛲞◌̴𖿰b; a◌𛲞◌̴𖿰b; ) LATIN SMALL LETTER A, DUPLOYAN DOUBLE MARK, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
-0061 302A 031B 1DCE 1D165 0062;0061 1DCE 031B 1D165 302A 0062;0061 1DCE 031B 1D165 302A 0062;0061 1DCE 031B 1D165 302A 0062;0061 1DCE 031B 1D165 302A 0062; # (a◌〪◌̛◌᷎𝅥b; a◌᷎◌̛𝅥◌〪b; a◌᷎◌̛𝅥◌〪b; a◌᷎◌̛𝅥◌〪b; a◌᷎◌̛𝅥◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING STEM, LATIN SMALL LETTER B
-0061 1D165 302A 031B 1DCE 0062;0061 1DCE 1D165 031B 302A 0062;0061 1DCE 1D165 031B 302A 0062;0061 1DCE 1D165 031B 302A 0062;0061 1DCE 1D165 031B 302A 0062; # (a𝅥◌〪◌̛◌᷎b; a◌᷎𝅥◌̛◌〪b; a◌᷎𝅥◌̛◌〪b; a◌᷎𝅥◌̛◌〪b; a◌᷎𝅥◌̛◌〪b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING STEM, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
-0061 302A 031B 1DCE 1D166 0062;0061 1DCE 031B 1D166 302A 0062;0061 1DCE 031B 1D166 302A 0062;0061 1DCE 031B 1D166 302A 0062;0061 1DCE 031B 1D166 302A 0062; # (a◌〪◌̛◌᷎𝅦b; a◌᷎◌̛𝅦◌〪b; a◌᷎◌̛𝅦◌〪b; a◌᷎◌̛𝅦◌〪b; a◌᷎◌̛𝅦◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING SPRECHGESANG STEM, LATIN SMALL LETTER B
-0061 1D166 302A 031B 1DCE 0062;0061 1DCE 1D166 031B 302A 0062;0061 1DCE 1D166 031B 302A 0062;0061 1DCE 1D166 031B 302A 0062;0061 1DCE 1D166 031B 302A 0062; # (a𝅦◌〪◌̛◌᷎b; a◌᷎𝅦◌̛◌〪b; a◌᷎𝅦◌̛◌〪b; a◌᷎𝅦◌̛◌〪b; a◌᷎𝅦◌̛◌〪b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING SPRECHGESANG STEM, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 1DFA 031B 1DCE 1D165 0062;0061 1DCE 031B 1D165 1DFA 0062;0061 1DCE 031B 1D165 1DFA 0062;0061 1DCE 031B 1D165 1DFA 0062;0061 1DCE 031B 1D165 1DFA 0062; # (a◌᷺◌̛◌᷎𝅥b; a◌᷎◌̛𝅥◌᷺b; a◌᷎◌̛𝅥◌᷺b; a◌᷎◌̛𝅥◌᷺b; a◌᷎◌̛𝅥◌᷺b; ) LATIN SMALL LETTER A, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING STEM, LATIN SMALL LETTER B
+0061 1D165 1DFA 031B 1DCE 0062;0061 1DCE 1D165 031B 1DFA 0062;0061 1DCE 1D165 031B 1DFA 0062;0061 1DCE 1D165 031B 1DFA 0062;0061 1DCE 1D165 031B 1DFA 0062; # (a𝅥◌᷺◌̛◌᷎b; a◌᷎𝅥◌̛◌᷺b; a◌᷎𝅥◌̛◌᷺b; a◌᷎𝅥◌̛◌᷺b; a◌᷎𝅥◌̛◌᷺b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING STEM, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 1DFA 031B 1DCE 1D166 0062;0061 1DCE 031B 1D166 1DFA 0062;0061 1DCE 031B 1D166 1DFA 0062;0061 1DCE 031B 1D166 1DFA 0062;0061 1DCE 031B 1D166 1DFA 0062; # (a◌᷺◌̛◌᷎𝅦b; a◌᷎◌̛𝅦◌᷺b; a◌᷎◌̛𝅦◌᷺b; a◌᷎◌̛𝅦◌᷺b; a◌᷎◌̛𝅦◌᷺b; ) LATIN SMALL LETTER A, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING SPRECHGESANG STEM, LATIN SMALL LETTER B
+0061 1D166 1DFA 031B 1DCE 0062;0061 1DCE 1D166 031B 1DFA 0062;0061 1DCE 1D166 031B 1DFA 0062;0061 1DCE 1D166 031B 1DFA 0062;0061 1DCE 1D166 031B 1DFA 0062; # (a𝅦◌᷺◌̛◌᷎b; a◌᷎𝅦◌̛◌᷺b; a◌᷎𝅦◌̛◌᷺b; a◌᷎𝅦◌̛◌᷺b; a◌᷎𝅦◌̛◌᷺b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING SPRECHGESANG STEM, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
0061 16FF0 0334 1D167 0062;0061 0334 1D167 16FF0 0062;0061 0334 1D167 16FF0 0062;0061 0334 1D167 16FF0 0062;0061 0334 1D167 16FF0 0062; # (a𖿰◌̴◌𝅧b; a◌̴◌𝅧𖿰b; a◌̴◌𝅧𖿰b; a◌̴◌𝅧𖿰b; a◌̴◌𝅧𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, MUSICAL SYMBOL COMBINING TREMOLO-1, LATIN SMALL LETTER B
0061 1D167 16FF0 0334 0062;0061 1D167 0334 16FF0 0062;0061 1D167 0334 16FF0 0062;0061 1D167 0334 16FF0 0062;0061 1D167 0334 16FF0 0062; # (a◌𝅧𖿰◌̴b; a◌𝅧◌̴𖿰b; a◌𝅧◌̴𖿰b; a◌𝅧◌̴𖿰b; a◌𝅧◌̴𖿰b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING TREMOLO-1, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
0061 16FF0 0334 1D168 0062;0061 0334 1D168 16FF0 0062;0061 0334 1D168 16FF0 0062;0061 0334 1D168 16FF0 0062;0061 0334 1D168 16FF0 0062; # (a𖿰◌̴◌𝅨b; a◌̴◌𝅨𖿰b; a◌̴◌𝅨𖿰b; a◌̴◌𝅨𖿰b; a◌̴◌𝅨𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, MUSICAL SYMBOL COMBINING TREMOLO-2, LATIN SMALL LETTER B
@@ -18545,32 +18682,32 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 1D169 16FF0 0334 0062;0061 1D169 0334 16FF0 0062;0061 1D169 0334 16FF0 0062;0061 1D169 0334 16FF0 0062;0061 1D169 0334 16FF0 0062; # (a◌𝅩𖿰◌̴b; a◌𝅩◌̴𖿰b; a◌𝅩◌̴𖿰b; a◌𝅩◌̴𖿰b; a◌𝅩◌̴𖿰b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING TREMOLO-3, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
0061 05AE 1D16D 302E 1D16D 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062; # (a◌〮𝅭𝅭֮b; a〮𝅭𝅭◌֮b; a〮𝅭𝅭◌֮b; a〮𝅭𝅭◌֮b; a〮𝅭𝅭◌֮b; ) LATIN SMALL LETTER A, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, HANGUL SINGLE DOT TONE MARK, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, LATIN SMALL LETTER B
0061 1D16D 05AE 1D16D 302E 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062; # (a𝅭◌〮𝅭֮b; a〮𝅭𝅭◌֮b; a〮𝅭𝅭◌֮b; a〮𝅭𝅭◌֮b; a〮𝅭𝅭◌֮b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, HANGUL SINGLE DOT TONE MARK, LATIN SMALL LETTER B
-0061 302A 031B 1DCE 1D16E 0062;0061 1DCE 031B 1D16E 302A 0062;0061 1DCE 031B 1D16E 302A 0062;0061 1DCE 031B 1D16E 302A 0062;0061 1DCE 031B 1D16E 302A 0062; # (a◌〪◌̛◌᷎𝅮b; a◌᷎◌̛𝅮◌〪b; a◌᷎◌̛𝅮◌〪b; a◌᷎◌̛𝅮◌〪b; a◌᷎◌̛𝅮◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING FLAG-1, LATIN SMALL LETTER B
-0061 1D16E 302A 031B 1DCE 0062;0061 1DCE 1D16E 031B 302A 0062;0061 1DCE 1D16E 031B 302A 0062;0061 1DCE 1D16E 031B 302A 0062;0061 1DCE 1D16E 031B 302A 0062; # (a𝅮◌〪◌̛◌᷎b; a◌᷎𝅮◌̛◌〪b; a◌᷎𝅮◌̛◌〪b; a◌᷎𝅮◌̛◌〪b; a◌᷎𝅮◌̛◌〪b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLAG-1, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
-0061 302A 031B 1DCE 1D16F 0062;0061 1DCE 031B 1D16F 302A 0062;0061 1DCE 031B 1D16F 302A 0062;0061 1DCE 031B 1D16F 302A 0062;0061 1DCE 031B 1D16F 302A 0062; # (a◌〪◌̛◌᷎𝅯b; a◌᷎◌̛𝅯◌〪b; a◌᷎◌̛𝅯◌〪b; a◌᷎◌̛𝅯◌〪b; a◌᷎◌̛𝅯◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING FLAG-2, LATIN SMALL LETTER B
-0061 1D16F 302A 031B 1DCE 0062;0061 1DCE 1D16F 031B 302A 0062;0061 1DCE 1D16F 031B 302A 0062;0061 1DCE 1D16F 031B 302A 0062;0061 1DCE 1D16F 031B 302A 0062; # (a𝅯◌〪◌̛◌᷎b; a◌᷎𝅯◌̛◌〪b; a◌᷎𝅯◌̛◌〪b; a◌᷎𝅯◌̛◌〪b; a◌᷎𝅯◌̛◌〪b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLAG-2, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
-0061 302A 031B 1DCE 1D170 0062;0061 1DCE 031B 1D170 302A 0062;0061 1DCE 031B 1D170 302A 0062;0061 1DCE 031B 1D170 302A 0062;0061 1DCE 031B 1D170 302A 0062; # (a◌〪◌̛◌᷎𝅰b; a◌᷎◌̛𝅰◌〪b; a◌᷎◌̛𝅰◌〪b; a◌᷎◌̛𝅰◌〪b; a◌᷎◌̛𝅰◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING FLAG-3, LATIN SMALL LETTER B
-0061 1D170 302A 031B 1DCE 0062;0061 1DCE 1D170 031B 302A 0062;0061 1DCE 1D170 031B 302A 0062;0061 1DCE 1D170 031B 302A 0062;0061 1DCE 1D170 031B 302A 0062; # (a𝅰◌〪◌̛◌᷎b; a◌᷎𝅰◌̛◌〪b; a◌᷎𝅰◌̛◌〪b; a◌᷎𝅰◌̛◌〪b; a◌᷎𝅰◌̛◌〪b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLAG-3, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
-0061 302A 031B 1DCE 1D171 0062;0061 1DCE 031B 1D171 302A 0062;0061 1DCE 031B 1D171 302A 0062;0061 1DCE 031B 1D171 302A 0062;0061 1DCE 031B 1D171 302A 0062; # (a◌〪◌̛◌᷎𝅱b; a◌᷎◌̛𝅱◌〪b; a◌᷎◌̛𝅱◌〪b; a◌᷎◌̛𝅱◌〪b; a◌᷎◌̛𝅱◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING FLAG-4, LATIN SMALL LETTER B
-0061 1D171 302A 031B 1DCE 0062;0061 1DCE 1D171 031B 302A 0062;0061 1DCE 1D171 031B 302A 0062;0061 1DCE 1D171 031B 302A 0062;0061 1DCE 1D171 031B 302A 0062; # (a𝅱◌〪◌̛◌᷎b; a◌᷎𝅱◌̛◌〪b; a◌᷎𝅱◌̛◌〪b; a◌᷎𝅱◌̛◌〪b; a◌᷎𝅱◌̛◌〪b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLAG-4, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
-0061 302A 031B 1DCE 1D172 0062;0061 1DCE 031B 1D172 302A 0062;0061 1DCE 031B 1D172 302A 0062;0061 1DCE 031B 1D172 302A 0062;0061 1DCE 031B 1D172 302A 0062; # (a◌〪◌̛◌᷎𝅲b; a◌᷎◌̛𝅲◌〪b; a◌᷎◌̛𝅲◌〪b; a◌᷎◌̛𝅲◌〪b; a◌᷎◌̛𝅲◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING FLAG-5, LATIN SMALL LETTER B
-0061 1D172 302A 031B 1DCE 0062;0061 1DCE 1D172 031B 302A 0062;0061 1DCE 1D172 031B 302A 0062;0061 1DCE 1D172 031B 302A 0062;0061 1DCE 1D172 031B 302A 0062; # (a𝅲◌〪◌̛◌᷎b; a◌᷎𝅲◌̛◌〪b; a◌᷎𝅲◌̛◌〪b; a◌᷎𝅲◌̛◌〪b; a◌᷎𝅲◌̛◌〪b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLAG-5, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
-0061 059A 0316 302A 1D17B 0062;0061 302A 0316 1D17B 059A 0062;0061 302A 0316 1D17B 059A 0062;0061 302A 0316 1D17B 059A 0062;0061 302A 0316 1D17B 059A 0062; # (a◌֚◌̖◌〪◌𝅻b; a◌〪◌̖◌𝅻◌֚b; a◌〪◌̖◌𝅻◌֚b; a◌〪◌̖◌𝅻◌֚b; a◌〪◌̖◌𝅻◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING ACCENT, LATIN SMALL LETTER B
-0061 1D17B 059A 0316 302A 0062;0061 302A 1D17B 0316 059A 0062;0061 302A 1D17B 0316 059A 0062;0061 302A 1D17B 0316 059A 0062;0061 302A 1D17B 0316 059A 0062; # (a◌𝅻◌֚◌̖◌〪b; a◌〪◌𝅻◌̖◌֚b; a◌〪◌𝅻◌̖◌֚b; a◌〪◌𝅻◌̖◌֚b; a◌〪◌𝅻◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING ACCENT, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1D17C 0062;0061 302A 0316 1D17C 059A 0062;0061 302A 0316 1D17C 059A 0062;0061 302A 0316 1D17C 059A 0062;0061 302A 0316 1D17C 059A 0062; # (a◌֚◌̖◌〪◌𝅼b; a◌〪◌̖◌𝅼◌֚b; a◌〪◌̖◌𝅼◌֚b; a◌〪◌̖◌𝅼◌֚b; a◌〪◌̖◌𝅼◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING STACCATO, LATIN SMALL LETTER B
-0061 1D17C 059A 0316 302A 0062;0061 302A 1D17C 0316 059A 0062;0061 302A 1D17C 0316 059A 0062;0061 302A 1D17C 0316 059A 0062;0061 302A 1D17C 0316 059A 0062; # (a◌𝅼◌֚◌̖◌〪b; a◌〪◌𝅼◌̖◌֚b; a◌〪◌𝅼◌̖◌֚b; a◌〪◌𝅼◌̖◌֚b; a◌〪◌𝅼◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING STACCATO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1D17D 0062;0061 302A 0316 1D17D 059A 0062;0061 302A 0316 1D17D 059A 0062;0061 302A 0316 1D17D 059A 0062;0061 302A 0316 1D17D 059A 0062; # (a◌֚◌̖◌〪◌𝅽b; a◌〪◌̖◌𝅽◌֚b; a◌〪◌̖◌𝅽◌֚b; a◌〪◌̖◌𝅽◌֚b; a◌〪◌̖◌𝅽◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING TENUTO, LATIN SMALL LETTER B
-0061 1D17D 059A 0316 302A 0062;0061 302A 1D17D 0316 059A 0062;0061 302A 1D17D 0316 059A 0062;0061 302A 1D17D 0316 059A 0062;0061 302A 1D17D 0316 059A 0062; # (a◌𝅽◌֚◌̖◌〪b; a◌〪◌𝅽◌̖◌֚b; a◌〪◌𝅽◌̖◌֚b; a◌〪◌𝅽◌̖◌֚b; a◌〪◌𝅽◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING TENUTO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1D17E 0062;0061 302A 0316 1D17E 059A 0062;0061 302A 0316 1D17E 059A 0062;0061 302A 0316 1D17E 059A 0062;0061 302A 0316 1D17E 059A 0062; # (a◌֚◌̖◌〪◌𝅾b; a◌〪◌̖◌𝅾◌֚b; a◌〪◌̖◌𝅾◌֚b; a◌〪◌̖◌𝅾◌֚b; a◌〪◌̖◌𝅾◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING STACCATISSIMO, LATIN SMALL LETTER B
-0061 1D17E 059A 0316 302A 0062;0061 302A 1D17E 0316 059A 0062;0061 302A 1D17E 0316 059A 0062;0061 302A 1D17E 0316 059A 0062;0061 302A 1D17E 0316 059A 0062; # (a◌𝅾◌֚◌̖◌〪b; a◌〪◌𝅾◌̖◌֚b; a◌〪◌𝅾◌̖◌֚b; a◌〪◌𝅾◌̖◌֚b; a◌〪◌𝅾◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING STACCATISSIMO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1D17F 0062;0061 302A 0316 1D17F 059A 0062;0061 302A 0316 1D17F 059A 0062;0061 302A 0316 1D17F 059A 0062;0061 302A 0316 1D17F 059A 0062; # (a◌֚◌̖◌〪◌𝅿b; a◌〪◌̖◌𝅿◌֚b; a◌〪◌̖◌𝅿◌֚b; a◌〪◌̖◌𝅿◌֚b; a◌〪◌̖◌𝅿◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING MARCATO, LATIN SMALL LETTER B
-0061 1D17F 059A 0316 302A 0062;0061 302A 1D17F 0316 059A 0062;0061 302A 1D17F 0316 059A 0062;0061 302A 1D17F 0316 059A 0062;0061 302A 1D17F 0316 059A 0062; # (a◌𝅿◌֚◌̖◌〪b; a◌〪◌𝅿◌̖◌֚b; a◌〪◌𝅿◌̖◌֚b; a◌〪◌𝅿◌̖◌֚b; a◌〪◌𝅿◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING MARCATO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1D180 0062;0061 302A 0316 1D180 059A 0062;0061 302A 0316 1D180 059A 0062;0061 302A 0316 1D180 059A 0062;0061 302A 0316 1D180 059A 0062; # (a◌֚◌̖◌〪◌𝆀b; a◌〪◌̖◌𝆀◌֚b; a◌〪◌̖◌𝆀◌֚b; a◌〪◌̖◌𝆀◌֚b; a◌〪◌̖◌𝆀◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING MARCATO-STACCATO, LATIN SMALL LETTER B
-0061 1D180 059A 0316 302A 0062;0061 302A 1D180 0316 059A 0062;0061 302A 1D180 0316 059A 0062;0061 302A 1D180 0316 059A 0062;0061 302A 1D180 0316 059A 0062; # (a◌𝆀◌֚◌̖◌〪b; a◌〪◌𝆀◌̖◌֚b; a◌〪◌𝆀◌̖◌֚b; a◌〪◌𝆀◌̖◌֚b; a◌〪◌𝆀◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING MARCATO-STACCATO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1D181 0062;0061 302A 0316 1D181 059A 0062;0061 302A 0316 1D181 059A 0062;0061 302A 0316 1D181 059A 0062;0061 302A 0316 1D181 059A 0062; # (a◌֚◌̖◌〪◌𝆁b; a◌〪◌̖◌𝆁◌֚b; a◌〪◌̖◌𝆁◌֚b; a◌〪◌̖◌𝆁◌֚b; a◌〪◌̖◌𝆁◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING ACCENT-STACCATO, LATIN SMALL LETTER B
-0061 1D181 059A 0316 302A 0062;0061 302A 1D181 0316 059A 0062;0061 302A 1D181 0316 059A 0062;0061 302A 1D181 0316 059A 0062;0061 302A 1D181 0316 059A 0062; # (a◌𝆁◌֚◌̖◌〪b; a◌〪◌𝆁◌̖◌֚b; a◌〪◌𝆁◌̖◌֚b; a◌〪◌𝆁◌̖◌֚b; a◌〪◌𝆁◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING ACCENT-STACCATO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1D182 0062;0061 302A 0316 1D182 059A 0062;0061 302A 0316 1D182 059A 0062;0061 302A 0316 1D182 059A 0062;0061 302A 0316 1D182 059A 0062; # (a◌֚◌̖◌〪◌𝆂b; a◌〪◌̖◌𝆂◌֚b; a◌〪◌̖◌𝆂◌֚b; a◌〪◌̖◌𝆂◌֚b; a◌〪◌̖◌𝆂◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING LOURE, LATIN SMALL LETTER B
-0061 1D182 059A 0316 302A 0062;0061 302A 1D182 0316 059A 0062;0061 302A 1D182 0316 059A 0062;0061 302A 1D182 0316 059A 0062;0061 302A 1D182 0316 059A 0062; # (a◌𝆂◌֚◌̖◌〪b; a◌〪◌𝆂◌̖◌֚b; a◌〪◌𝆂◌̖◌֚b; a◌〪◌𝆂◌̖◌֚b; a◌〪◌𝆂◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING LOURE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 1DFA 031B 1DCE 1D16E 0062;0061 1DCE 031B 1D16E 1DFA 0062;0061 1DCE 031B 1D16E 1DFA 0062;0061 1DCE 031B 1D16E 1DFA 0062;0061 1DCE 031B 1D16E 1DFA 0062; # (a◌᷺◌̛◌᷎𝅮b; a◌᷎◌̛𝅮◌᷺b; a◌᷎◌̛𝅮◌᷺b; a◌᷎◌̛𝅮◌᷺b; a◌᷎◌̛𝅮◌᷺b; ) LATIN SMALL LETTER A, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING FLAG-1, LATIN SMALL LETTER B
+0061 1D16E 1DFA 031B 1DCE 0062;0061 1DCE 1D16E 031B 1DFA 0062;0061 1DCE 1D16E 031B 1DFA 0062;0061 1DCE 1D16E 031B 1DFA 0062;0061 1DCE 1D16E 031B 1DFA 0062; # (a𝅮◌᷺◌̛◌᷎b; a◌᷎𝅮◌̛◌᷺b; a◌᷎𝅮◌̛◌᷺b; a◌᷎𝅮◌̛◌᷺b; a◌᷎𝅮◌̛◌᷺b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLAG-1, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 1DFA 031B 1DCE 1D16F 0062;0061 1DCE 031B 1D16F 1DFA 0062;0061 1DCE 031B 1D16F 1DFA 0062;0061 1DCE 031B 1D16F 1DFA 0062;0061 1DCE 031B 1D16F 1DFA 0062; # (a◌᷺◌̛◌᷎𝅯b; a◌᷎◌̛𝅯◌᷺b; a◌᷎◌̛𝅯◌᷺b; a◌᷎◌̛𝅯◌᷺b; a◌᷎◌̛𝅯◌᷺b; ) LATIN SMALL LETTER A, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING FLAG-2, LATIN SMALL LETTER B
+0061 1D16F 1DFA 031B 1DCE 0062;0061 1DCE 1D16F 031B 1DFA 0062;0061 1DCE 1D16F 031B 1DFA 0062;0061 1DCE 1D16F 031B 1DFA 0062;0061 1DCE 1D16F 031B 1DFA 0062; # (a𝅯◌᷺◌̛◌᷎b; a◌᷎𝅯◌̛◌᷺b; a◌᷎𝅯◌̛◌᷺b; a◌᷎𝅯◌̛◌᷺b; a◌᷎𝅯◌̛◌᷺b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLAG-2, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 1DFA 031B 1DCE 1D170 0062;0061 1DCE 031B 1D170 1DFA 0062;0061 1DCE 031B 1D170 1DFA 0062;0061 1DCE 031B 1D170 1DFA 0062;0061 1DCE 031B 1D170 1DFA 0062; # (a◌᷺◌̛◌᷎𝅰b; a◌᷎◌̛𝅰◌᷺b; a◌᷎◌̛𝅰◌᷺b; a◌᷎◌̛𝅰◌᷺b; a◌᷎◌̛𝅰◌᷺b; ) LATIN SMALL LETTER A, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING FLAG-3, LATIN SMALL LETTER B
+0061 1D170 1DFA 031B 1DCE 0062;0061 1DCE 1D170 031B 1DFA 0062;0061 1DCE 1D170 031B 1DFA 0062;0061 1DCE 1D170 031B 1DFA 0062;0061 1DCE 1D170 031B 1DFA 0062; # (a𝅰◌᷺◌̛◌᷎b; a◌᷎𝅰◌̛◌᷺b; a◌᷎𝅰◌̛◌᷺b; a◌᷎𝅰◌̛◌᷺b; a◌᷎𝅰◌̛◌᷺b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLAG-3, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 1DFA 031B 1DCE 1D171 0062;0061 1DCE 031B 1D171 1DFA 0062;0061 1DCE 031B 1D171 1DFA 0062;0061 1DCE 031B 1D171 1DFA 0062;0061 1DCE 031B 1D171 1DFA 0062; # (a◌᷺◌̛◌᷎𝅱b; a◌᷎◌̛𝅱◌᷺b; a◌᷎◌̛𝅱◌᷺b; a◌᷎◌̛𝅱◌᷺b; a◌᷎◌̛𝅱◌᷺b; ) LATIN SMALL LETTER A, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING FLAG-4, LATIN SMALL LETTER B
+0061 1D171 1DFA 031B 1DCE 0062;0061 1DCE 1D171 031B 1DFA 0062;0061 1DCE 1D171 031B 1DFA 0062;0061 1DCE 1D171 031B 1DFA 0062;0061 1DCE 1D171 031B 1DFA 0062; # (a𝅱◌᷺◌̛◌᷎b; a◌᷎𝅱◌̛◌᷺b; a◌᷎𝅱◌̛◌᷺b; a◌᷎𝅱◌̛◌᷺b; a◌᷎𝅱◌̛◌᷺b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLAG-4, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 1DFA 031B 1DCE 1D172 0062;0061 1DCE 031B 1D172 1DFA 0062;0061 1DCE 031B 1D172 1DFA 0062;0061 1DCE 031B 1D172 1DFA 0062;0061 1DCE 031B 1D172 1DFA 0062; # (a◌᷺◌̛◌᷎𝅲b; a◌᷎◌̛𝅲◌᷺b; a◌᷎◌̛𝅲◌᷺b; a◌᷎◌̛𝅲◌᷺b; a◌᷎◌̛𝅲◌᷺b; ) LATIN SMALL LETTER A, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING FLAG-5, LATIN SMALL LETTER B
+0061 1D172 1DFA 031B 1DCE 0062;0061 1DCE 1D172 031B 1DFA 0062;0061 1DCE 1D172 031B 1DFA 0062;0061 1DCE 1D172 031B 1DFA 0062;0061 1DCE 1D172 031B 1DFA 0062; # (a𝅲◌᷺◌̛◌᷎b; a◌᷎𝅲◌̛◌᷺b; a◌᷎𝅲◌̛◌᷺b; a◌᷎𝅲◌̛◌᷺b; a◌᷎𝅲◌̛◌᷺b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLAG-5, COMBINING DOT BELOW LEFT, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1D17B 0062;0061 1DFA 0316 1D17B 059A 0062;0061 1DFA 0316 1D17B 059A 0062;0061 1DFA 0316 1D17B 059A 0062;0061 1DFA 0316 1D17B 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, MUSICAL SYMBOL COMBINING ACCENT, LATIN SMALL LETTER B
+0061 1D17B 059A 0316 1DFA 0062;0061 1DFA 1D17B 0316 059A 0062;0061 1DFA 1D17B 0316 059A 0062;0061 1DFA 1D17B 0316 059A 0062;0061 1DFA 1D17B 0316 059A 0062; # (a◌𝅻◌֚◌̖◌᷺b; a◌᷺◌𝅻◌̖◌֚b; a◌᷺◌𝅻◌̖◌֚b; a◌᷺◌𝅻◌̖◌֚b; a◌᷺◌𝅻◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING ACCENT, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1D17C 0062;0061 1DFA 0316 1D17C 059A 0062;0061 1DFA 0316 1D17C 059A 0062;0061 1DFA 0316 1D17C 059A 0062;0061 1DFA 0316 1D17C 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, MUSICAL SYMBOL COMBINING STACCATO, LATIN SMALL LETTER B
+0061 1D17C 059A 0316 1DFA 0062;0061 1DFA 1D17C 0316 059A 0062;0061 1DFA 1D17C 0316 059A 0062;0061 1DFA 1D17C 0316 059A 0062;0061 1DFA 1D17C 0316 059A 0062; # (a◌𝅼◌֚◌̖◌᷺b; a◌᷺◌𝅼◌̖◌֚b; a◌᷺◌𝅼◌̖◌֚b; a◌᷺◌𝅼◌̖◌֚b; a◌᷺◌𝅼◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING STACCATO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1D17D 0062;0061 1DFA 0316 1D17D 059A 0062;0061 1DFA 0316 1D17D 059A 0062;0061 1DFA 0316 1D17D 059A 0062;0061 1DFA 0316 1D17D 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, MUSICAL SYMBOL COMBINING TENUTO, LATIN SMALL LETTER B
+0061 1D17D 059A 0316 1DFA 0062;0061 1DFA 1D17D 0316 059A 0062;0061 1DFA 1D17D 0316 059A 0062;0061 1DFA 1D17D 0316 059A 0062;0061 1DFA 1D17D 0316 059A 0062; # (a◌𝅽◌֚◌̖◌᷺b; a◌᷺◌𝅽◌̖◌֚b; a◌᷺◌𝅽◌̖◌֚b; a◌᷺◌𝅽◌̖◌֚b; a◌᷺◌𝅽◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING TENUTO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1D17E 0062;0061 1DFA 0316 1D17E 059A 0062;0061 1DFA 0316 1D17E 059A 0062;0061 1DFA 0316 1D17E 059A 0062;0061 1DFA 0316 1D17E 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, MUSICAL SYMBOL COMBINING STACCATISSIMO, LATIN SMALL LETTER B
+0061 1D17E 059A 0316 1DFA 0062;0061 1DFA 1D17E 0316 059A 0062;0061 1DFA 1D17E 0316 059A 0062;0061 1DFA 1D17E 0316 059A 0062;0061 1DFA 1D17E 0316 059A 0062; # (a◌𝅾◌֚◌̖◌᷺b; a◌᷺◌𝅾◌̖◌֚b; a◌᷺◌𝅾◌̖◌֚b; a◌᷺◌𝅾◌̖◌֚b; a◌᷺◌𝅾◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING STACCATISSIMO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1D17F 0062;0061 1DFA 0316 1D17F 059A 0062;0061 1DFA 0316 1D17F 059A 0062;0061 1DFA 0316 1D17F 059A 0062;0061 1DFA 0316 1D17F 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, MUSICAL SYMBOL COMBINING MARCATO, LATIN SMALL LETTER B
+0061 1D17F 059A 0316 1DFA 0062;0061 1DFA 1D17F 0316 059A 0062;0061 1DFA 1D17F 0316 059A 0062;0061 1DFA 1D17F 0316 059A 0062;0061 1DFA 1D17F 0316 059A 0062; # (a◌𝅿◌֚◌̖◌᷺b; a◌᷺◌𝅿◌̖◌֚b; a◌᷺◌𝅿◌̖◌֚b; a◌᷺◌𝅿◌̖◌֚b; a◌᷺◌𝅿◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING MARCATO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1D180 0062;0061 1DFA 0316 1D180 059A 0062;0061 1DFA 0316 1D180 059A 0062;0061 1DFA 0316 1D180 059A 0062;0061 1DFA 0316 1D180 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, MUSICAL SYMBOL COMBINING MARCATO-STACCATO, LATIN SMALL LETTER B
+0061 1D180 059A 0316 1DFA 0062;0061 1DFA 1D180 0316 059A 0062;0061 1DFA 1D180 0316 059A 0062;0061 1DFA 1D180 0316 059A 0062;0061 1DFA 1D180 0316 059A 0062; # (a◌𝆀◌֚◌̖◌᷺b; a◌᷺◌𝆀◌̖◌֚b; a◌᷺◌𝆀◌̖◌֚b; a◌᷺◌𝆀◌̖◌֚b; a◌᷺◌𝆀◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING MARCATO-STACCATO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1D181 0062;0061 1DFA 0316 1D181 059A 0062;0061 1DFA 0316 1D181 059A 0062;0061 1DFA 0316 1D181 059A 0062;0061 1DFA 0316 1D181 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, MUSICAL SYMBOL COMBINING ACCENT-STACCATO, LATIN SMALL LETTER B
+0061 1D181 059A 0316 1DFA 0062;0061 1DFA 1D181 0316 059A 0062;0061 1DFA 1D181 0316 059A 0062;0061 1DFA 1D181 0316 059A 0062;0061 1DFA 1D181 0316 059A 0062; # (a◌𝆁◌֚◌̖◌᷺b; a◌᷺◌𝆁◌̖◌֚b; a◌᷺◌𝆁◌̖◌֚b; a◌᷺◌𝆁◌̖◌֚b; a◌᷺◌𝆁◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING ACCENT-STACCATO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1D182 0062;0061 1DFA 0316 1D182 059A 0062;0061 1DFA 0316 1D182 059A 0062;0061 1DFA 0316 1D182 059A 0062;0061 1DFA 0316 1D182 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, MUSICAL SYMBOL COMBINING LOURE, LATIN SMALL LETTER B
+0061 1D182 059A 0316 1DFA 0062;0061 1DFA 1D182 0316 059A 0062;0061 1DFA 1D182 0316 059A 0062;0061 1DFA 1D182 0316 059A 0062;0061 1DFA 1D182 0316 059A 0062; # (a◌𝆂◌֚◌̖◌᷺b; a◌᷺◌𝆂◌̖◌֚b; a◌᷺◌𝆂◌̖◌֚b; a◌᷺◌𝆂◌̖◌֚b; a◌᷺◌𝆂◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING LOURE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 1D185 0062;00E0 05AE 1D185 0315 0062;0061 05AE 0300 1D185 0315 0062;00E0 05AE 1D185 0315 0062;0061 05AE 0300 1D185 0315 0062; # (a◌̕◌̀◌֮◌𝆅b; à◌֮◌𝆅◌̕b; a◌֮◌̀◌𝆅◌̕b; à◌֮◌𝆅◌̕b; a◌֮◌̀◌𝆅◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING DOIT, LATIN SMALL LETTER B
0061 1D185 0315 0300 05AE 0062;0061 05AE 1D185 0300 0315 0062;0061 05AE 1D185 0300 0315 0062;0061 05AE 1D185 0300 0315 0062;0061 05AE 1D185 0300 0315 0062; # (a◌𝆅◌̕◌̀◌֮b; a◌֮◌𝆅◌̀◌̕b; a◌֮◌𝆅◌̀◌̕b; a◌֮◌𝆅◌̀◌̕b; a◌֮◌𝆅◌̀◌̕b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING DOIT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1D186 0062;00E0 05AE 1D186 0315 0062;0061 05AE 0300 1D186 0315 0062;00E0 05AE 1D186 0315 0062;0061 05AE 0300 1D186 0315 0062; # (a◌̕◌̀◌֮◌𝆆b; à◌֮◌𝆆◌̕b; a◌֮◌̀◌𝆆◌̕b; à◌֮◌𝆆◌̕b; a◌֮◌̀◌𝆆◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING RIP, LATIN SMALL LETTER B
@@ -18581,10 +18718,10 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 1D188 0315 0300 05AE 0062;0061 05AE 1D188 0300 0315 0062;0061 05AE 1D188 0300 0315 0062;0061 05AE 1D188 0300 0315 0062;0061 05AE 1D188 0300 0315 0062; # (a◌𝆈◌̕◌̀◌֮b; a◌֮◌𝆈◌̀◌̕b; a◌֮◌𝆈◌̀◌̕b; a◌֮◌𝆈◌̀◌̕b; a◌֮◌𝆈◌̀◌̕b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING SMEAR, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1D189 0062;00E0 05AE 1D189 0315 0062;0061 05AE 0300 1D189 0315 0062;00E0 05AE 1D189 0315 0062;0061 05AE 0300 1D189 0315 0062; # (a◌̕◌̀◌֮◌𝆉b; à◌֮◌𝆉◌̕b; a◌֮◌̀◌𝆉◌̕b; à◌֮◌𝆉◌̕b; a◌֮◌̀◌𝆉◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING BEND, LATIN SMALL LETTER B
0061 1D189 0315 0300 05AE 0062;0061 05AE 1D189 0300 0315 0062;0061 05AE 1D189 0300 0315 0062;0061 05AE 1D189 0300 0315 0062;0061 05AE 1D189 0300 0315 0062; # (a◌𝆉◌̕◌̀◌֮b; a◌֮◌𝆉◌̀◌̕b; a◌֮◌𝆉◌̀◌̕b; a◌֮◌𝆉◌̀◌̕b; a◌֮◌𝆉◌̀◌̕b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING BEND, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
-0061 059A 0316 302A 1D18A 0062;0061 302A 0316 1D18A 059A 0062;0061 302A 0316 1D18A 059A 0062;0061 302A 0316 1D18A 059A 0062;0061 302A 0316 1D18A 059A 0062; # (a◌֚◌̖◌〪◌𝆊b; a◌〪◌̖◌𝆊◌֚b; a◌〪◌̖◌𝆊◌֚b; a◌〪◌̖◌𝆊◌֚b; a◌〪◌̖◌𝆊◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING DOUBLE TONGUE, LATIN SMALL LETTER B
-0061 1D18A 059A 0316 302A 0062;0061 302A 1D18A 0316 059A 0062;0061 302A 1D18A 0316 059A 0062;0061 302A 1D18A 0316 059A 0062;0061 302A 1D18A 0316 059A 0062; # (a◌𝆊◌֚◌̖◌〪b; a◌〪◌𝆊◌̖◌֚b; a◌〪◌𝆊◌̖◌֚b; a◌〪◌𝆊◌̖◌֚b; a◌〪◌𝆊◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING DOUBLE TONGUE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1D18B 0062;0061 302A 0316 1D18B 059A 0062;0061 302A 0316 1D18B 059A 0062;0061 302A 0316 1D18B 059A 0062;0061 302A 0316 1D18B 059A 0062; # (a◌֚◌̖◌〪◌𝆋b; a◌〪◌̖◌𝆋◌֚b; a◌〪◌̖◌𝆋◌֚b; a◌〪◌̖◌𝆋◌֚b; a◌〪◌̖◌𝆋◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING TRIPLE TONGUE, LATIN SMALL LETTER B
-0061 1D18B 059A 0316 302A 0062;0061 302A 1D18B 0316 059A 0062;0061 302A 1D18B 0316 059A 0062;0061 302A 1D18B 0316 059A 0062;0061 302A 1D18B 0316 059A 0062; # (a◌𝆋◌֚◌̖◌〪b; a◌〪◌𝆋◌̖◌֚b; a◌〪◌𝆋◌̖◌֚b; a◌〪◌𝆋◌̖◌֚b; a◌〪◌𝆋◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING TRIPLE TONGUE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1D18A 0062;0061 1DFA 0316 1D18A 059A 0062;0061 1DFA 0316 1D18A 059A 0062;0061 1DFA 0316 1D18A 059A 0062;0061 1DFA 0316 1D18A 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, MUSICAL SYMBOL COMBINING DOUBLE TONGUE, LATIN SMALL LETTER B
+0061 1D18A 059A 0316 1DFA 0062;0061 1DFA 1D18A 0316 059A 0062;0061 1DFA 1D18A 0316 059A 0062;0061 1DFA 1D18A 0316 059A 0062;0061 1DFA 1D18A 0316 059A 0062; # (a◌𝆊◌֚◌̖◌᷺b; a◌᷺◌𝆊◌̖◌֚b; a◌᷺◌𝆊◌̖◌֚b; a◌᷺◌𝆊◌̖◌֚b; a◌᷺◌𝆊◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING DOUBLE TONGUE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1D18B 0062;0061 1DFA 0316 1D18B 059A 0062;0061 1DFA 0316 1D18B 059A 0062;0061 1DFA 0316 1D18B 059A 0062;0061 1DFA 0316 1D18B 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, MUSICAL SYMBOL COMBINING TRIPLE TONGUE, LATIN SMALL LETTER B
+0061 1D18B 059A 0316 1DFA 0062;0061 1DFA 1D18B 0316 059A 0062;0061 1DFA 1D18B 0316 059A 0062;0061 1DFA 1D18B 0316 059A 0062;0061 1DFA 1D18B 0316 059A 0062; # (a◌𝆋◌֚◌̖◌᷺b; a◌᷺◌𝆋◌̖◌֚b; a◌᷺◌𝆋◌̖◌֚b; a◌᷺◌𝆋◌̖◌֚b; a◌᷺◌𝆋◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING TRIPLE TONGUE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 1D1AA 0062;00E0 05AE 1D1AA 0315 0062;0061 05AE 0300 1D1AA 0315 0062;00E0 05AE 1D1AA 0315 0062;0061 05AE 0300 1D1AA 0315 0062; # (a◌̕◌̀◌֮◌𝆪b; à◌֮◌𝆪◌̕b; a◌֮◌̀◌𝆪◌̕b; à◌֮◌𝆪◌̕b; a◌֮◌̀◌𝆪◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING DOWN BOW, LATIN SMALL LETTER B
0061 1D1AA 0315 0300 05AE 0062;0061 05AE 1D1AA 0300 0315 0062;0061 05AE 1D1AA 0300 0315 0062;0061 05AE 1D1AA 0300 0315 0062;0061 05AE 1D1AA 0300 0315 0062; # (a◌𝆪◌̕◌̀◌֮b; a◌֮◌𝆪◌̀◌̕b; a◌֮◌𝆪◌̀◌̕b; a◌֮◌𝆪◌̀◌̕b; a◌֮◌𝆪◌̀◌̕b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING DOWN BOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1D1AB 0062;00E0 05AE 1D1AB 0315 0062;0061 05AE 0300 1D1AB 0315 0062;00E0 05AE 1D1AB 0315 0062;0061 05AE 0300 1D1AB 0315 0062; # (a◌̕◌̀◌֮◌𝆫b; à◌֮◌𝆫◌̕b; a◌֮◌̀◌𝆫◌̕b; à◌֮◌𝆫◌̕b; a◌֮◌̀◌𝆫◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING UP BOW, LATIN SMALL LETTER B
@@ -18689,6 +18826,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 1E135 0315 0300 05AE 0062;0061 05AE 1E135 0300 0315 0062;0061 05AE 1E135 0300 0315 0062;0061 05AE 1E135 0300 0315 0062;0061 05AE 1E135 0300 0315 0062; # (a◌𞄵◌̕◌̀◌֮b; a◌֮◌𞄵◌̀◌̕b; a◌֮◌𞄵◌̀◌̕b; a◌֮◌𞄵◌̀◌̕b; a◌֮◌𞄵◌̀◌̕b; ) LATIN SMALL LETTER A, NYIAKENG PUACHUE HMONG TONE-G, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1E136 0062;00E0 05AE 1E136 0315 0062;0061 05AE 0300 1E136 0315 0062;00E0 05AE 1E136 0315 0062;0061 05AE 0300 1E136 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-D, LATIN SMALL LETTER B
0061 1E136 0315 0300 05AE 0062;0061 05AE 1E136 0300 0315 0062;0061 05AE 1E136 0300 0315 0062;0061 05AE 1E136 0300 0315 0062;0061 05AE 1E136 0300 0315 0062; # (a◌𞄶◌̕◌̀◌֮b; a◌֮◌𞄶◌̀◌̕b; a◌֮◌𞄶◌̀◌̕b; a◌֮◌𞄶◌̀◌̕b; a◌֮◌𞄶◌̀◌̕b; ) LATIN SMALL LETTER A, NYIAKENG PUACHUE HMONG TONE-D, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E2AE 0062;00E0 05AE 1E2AE 0315 0062;0061 05AE 0300 1E2AE 0315 0062;00E0 05AE 1E2AE 0315 0062;0061 05AE 0300 1E2AE 0315 0062; # (a◌̕◌̀◌֮◌𞊮b; à◌֮◌𞊮◌̕b; a◌֮◌̀◌𞊮◌̕b; à◌֮◌𞊮◌̕b; a◌֮◌̀◌𞊮◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TOTO SIGN RISING TONE, LATIN SMALL LETTER B
+0061 1E2AE 0315 0300 05AE 0062;0061 05AE 1E2AE 0300 0315 0062;0061 05AE 1E2AE 0300 0315 0062;0061 05AE 1E2AE 0300 0315 0062;0061 05AE 1E2AE 0300 0315 0062; # (a◌𞊮◌̕◌̀◌֮b; a◌֮◌𞊮◌̀◌̕b; a◌֮◌𞊮◌̀◌̕b; a◌֮◌𞊮◌̀◌̕b; a◌֮◌𞊮◌̀◌̕b; ) LATIN SMALL LETTER A, TOTO SIGN RISING TONE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1E2EC 0062;00E0 05AE 1E2EC 0315 0062;0061 05AE 0300 1E2EC 0315 0062;00E0 05AE 1E2EC 0315 0062;0061 05AE 0300 1E2EC 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 TUP, LATIN SMALL LETTER B
0061 1E2EC 0315 0300 05AE 0062;0061 05AE 1E2EC 0300 0315 0062;0061 05AE 1E2EC 0300 0315 0062;0061 05AE 1E2EC 0300 0315 0062;0061 05AE 1E2EC 0300 0315 0062; # (a◌𞋬◌̕◌̀◌֮b; a◌֮◌𞋬◌̀◌̕b; a◌֮◌𞋬◌̀◌̕b; a◌֮◌𞋬◌̀◌̕b; a◌֮◌𞋬◌̀◌̕b; ) LATIN SMALL LETTER A, WANCHO TONE TUP, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1E2ED 0062;00E0 05AE 1E2ED 0315 0062;0061 05AE 0300 1E2ED 0315 0062;00E0 05AE 1E2ED 0315 0062;0061 05AE 0300 1E2ED 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 TUPNI, LATIN SMALL LETTER B
@@ -18697,20 +18836,20 @@ 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 059A 0316 302A 1E8D0 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 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, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER TEENS, LATIN SMALL LETTER B
-0061 1E8D0 059A 0316 302A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 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, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1E8D1 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 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, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER TENS, LATIN SMALL LETTER B
-0061 1E8D1 059A 0316 302A 0062;0061 302A 1E8D1 0316 059A 0062;0061 302A 1E8D1 0316 059A 0062;0061 302A 1E8D1 0316 059A 0062;0061 302A 1E8D1 0316 059A 0062; # (a◌𞣑◌֚◌̖◌〪b; a◌〪◌𞣑◌̖◌֚b; a◌〪◌𞣑◌̖◌֚b; a◌〪◌𞣑◌̖◌֚b; a◌〪◌𞣑◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER TENS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1E8D2 0062;0061 302A 0316 1E8D2 059A 0062;0061 302A 0316 1E8D2 059A 0062;0061 302A 0316 1E8D2 059A 0062;0061 302A 0316 1E8D2 059A 0062; # (a◌֚◌̖◌〪◌𞣒b; a◌〪◌̖◌𞣒◌֚b; a◌〪◌̖◌𞣒◌֚b; a◌〪◌̖◌𞣒◌֚b; a◌〪◌̖◌𞣒◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER HUNDREDS, LATIN SMALL LETTER B
-0061 1E8D2 059A 0316 302A 0062;0061 302A 1E8D2 0316 059A 0062;0061 302A 1E8D2 0316 059A 0062;0061 302A 1E8D2 0316 059A 0062;0061 302A 1E8D2 0316 059A 0062; # (a◌𞣒◌֚◌̖◌〪b; a◌〪◌𞣒◌̖◌֚b; a◌〪◌𞣒◌̖◌֚b; a◌〪◌𞣒◌̖◌֚b; a◌〪◌𞣒◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER HUNDREDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1E8D3 0062;0061 302A 0316 1E8D3 059A 0062;0061 302A 0316 1E8D3 059A 0062;0061 302A 0316 1E8D3 059A 0062;0061 302A 0316 1E8D3 059A 0062; # (a◌֚◌̖◌〪◌𞣓b; a◌〪◌̖◌𞣓◌֚b; a◌〪◌̖◌𞣓◌֚b; a◌〪◌̖◌𞣓◌֚b; a◌〪◌̖◌𞣓◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER THOUSANDS, LATIN SMALL LETTER B
-0061 1E8D3 059A 0316 302A 0062;0061 302A 1E8D3 0316 059A 0062;0061 302A 1E8D3 0316 059A 0062;0061 302A 1E8D3 0316 059A 0062;0061 302A 1E8D3 0316 059A 0062; # (a◌𞣓◌֚◌̖◌〪b; a◌〪◌𞣓◌̖◌֚b; a◌〪◌𞣓◌̖◌֚b; a◌〪◌𞣓◌̖◌֚b; a◌〪◌𞣓◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER THOUSANDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1E8D4 0062;0061 302A 0316 1E8D4 059A 0062;0061 302A 0316 1E8D4 059A 0062;0061 302A 0316 1E8D4 059A 0062;0061 302A 0316 1E8D4 059A 0062; # (a◌֚◌̖◌〪◌𞣔b; a◌〪◌̖◌𞣔◌֚b; a◌〪◌̖◌𞣔◌֚b; a◌〪◌̖◌𞣔◌֚b; a◌〪◌̖◌𞣔◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER TEN THOUSANDS, LATIN SMALL LETTER B
-0061 1E8D4 059A 0316 302A 0062;0061 302A 1E8D4 0316 059A 0062;0061 302A 1E8D4 0316 059A 0062;0061 302A 1E8D4 0316 059A 0062;0061 302A 1E8D4 0316 059A 0062; # (a◌𞣔◌֚◌̖◌〪b; a◌〪◌𞣔◌̖◌֚b; a◌〪◌𞣔◌̖◌֚b; a◌〪◌𞣔◌̖◌֚b; a◌〪◌𞣔◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER TEN THOUSANDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1E8D5 0062;0061 302A 0316 1E8D5 059A 0062;0061 302A 0316 1E8D5 059A 0062;0061 302A 0316 1E8D5 059A 0062;0061 302A 0316 1E8D5 059A 0062; # (a◌֚◌̖◌〪◌𞣕b; a◌〪◌̖◌𞣕◌֚b; a◌〪◌̖◌𞣕◌֚b; a◌〪◌̖◌𞣕◌֚b; a◌〪◌̖◌𞣕◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER HUNDRED THOUSANDS, LATIN SMALL LETTER B
-0061 1E8D5 059A 0316 302A 0062;0061 302A 1E8D5 0316 059A 0062;0061 302A 1E8D5 0316 059A 0062;0061 302A 1E8D5 0316 059A 0062;0061 302A 1E8D5 0316 059A 0062; # (a◌𞣕◌֚◌̖◌〪b; a◌〪◌𞣕◌̖◌֚b; a◌〪◌𞣕◌̖◌֚b; a◌〪◌𞣕◌̖◌֚b; a◌〪◌𞣕◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER HUNDRED THOUSANDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
-0061 059A 0316 302A 1E8D6 0062;0061 302A 0316 1E8D6 059A 0062;0061 302A 0316 1E8D6 059A 0062;0061 302A 0316 1E8D6 059A 0062;0061 302A 0316 1E8D6 059A 0062; # (a◌֚◌̖◌〪◌𞣖b; a◌〪◌̖◌𞣖◌֚b; a◌〪◌̖◌𞣖◌֚b; a◌〪◌̖◌𞣖◌֚b; a◌〪◌̖◌𞣖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER MILLIONS, LATIN SMALL LETTER B
-0061 1E8D6 059A 0316 302A 0062;0061 302A 1E8D6 0316 059A 0062;0061 302A 1E8D6 0316 059A 0062;0061 302A 1E8D6 0316 059A 0062;0061 302A 1E8D6 0316 059A 0062; # (a◌𞣖◌֚◌̖◌〪b; a◌〪◌𞣖◌̖◌֚b; a◌〪◌𞣖◌̖◌֚b; a◌〪◌𞣖◌̖◌֚b; a◌〪◌𞣖◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER MILLIONS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, 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
+0061 1E8D1 059A 0316 1DFA 0062;0061 1DFA 1E8D1 0316 059A 0062;0061 1DFA 1E8D1 0316 059A 0062;0061 1DFA 1E8D1 0316 059A 0062;0061 1DFA 1E8D1 0316 059A 0062; # (a◌𞣑◌֚◌̖◌᷺b; a◌᷺◌𞣑◌̖◌֚b; a◌᷺◌𞣑◌̖◌֚b; a◌᷺◌𞣑◌̖◌֚b; a◌᷺◌𞣑◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER TENS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1E8D2 0062;0061 1DFA 0316 1E8D2 059A 0062;0061 1DFA 0316 1E8D2 059A 0062;0061 1DFA 0316 1E8D2 059A 0062;0061 1DFA 0316 1E8D2 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 HUNDREDS, LATIN SMALL LETTER B
+0061 1E8D2 059A 0316 1DFA 0062;0061 1DFA 1E8D2 0316 059A 0062;0061 1DFA 1E8D2 0316 059A 0062;0061 1DFA 1E8D2 0316 059A 0062;0061 1DFA 1E8D2 0316 059A 0062; # (a◌𞣒◌֚◌̖◌᷺b; a◌᷺◌𞣒◌̖◌֚b; a◌᷺◌𞣒◌̖◌֚b; a◌᷺◌𞣒◌̖◌֚b; a◌᷺◌𞣒◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER HUNDREDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1E8D3 0062;0061 1DFA 0316 1E8D3 059A 0062;0061 1DFA 0316 1E8D3 059A 0062;0061 1DFA 0316 1E8D3 059A 0062;0061 1DFA 0316 1E8D3 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 THOUSANDS, LATIN SMALL LETTER B
+0061 1E8D3 059A 0316 1DFA 0062;0061 1DFA 1E8D3 0316 059A 0062;0061 1DFA 1E8D3 0316 059A 0062;0061 1DFA 1E8D3 0316 059A 0062;0061 1DFA 1E8D3 0316 059A 0062; # (a◌𞣓◌֚◌̖◌᷺b; a◌᷺◌𞣓◌̖◌֚b; a◌᷺◌𞣓◌̖◌֚b; a◌᷺◌𞣓◌̖◌֚b; a◌᷺◌𞣓◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER THOUSANDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1E8D4 0062;0061 1DFA 0316 1E8D4 059A 0062;0061 1DFA 0316 1E8D4 059A 0062;0061 1DFA 0316 1E8D4 059A 0062;0061 1DFA 0316 1E8D4 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 TEN THOUSANDS, LATIN SMALL LETTER B
+0061 1E8D4 059A 0316 1DFA 0062;0061 1DFA 1E8D4 0316 059A 0062;0061 1DFA 1E8D4 0316 059A 0062;0061 1DFA 1E8D4 0316 059A 0062;0061 1DFA 1E8D4 0316 059A 0062; # (a◌𞣔◌֚◌̖◌᷺b; a◌᷺◌𞣔◌̖◌֚b; a◌᷺◌𞣔◌̖◌֚b; a◌᷺◌𞣔◌̖◌֚b; a◌᷺◌𞣔◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER TEN THOUSANDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1E8D5 0062;0061 1DFA 0316 1E8D5 059A 0062;0061 1DFA 0316 1E8D5 059A 0062;0061 1DFA 0316 1E8D5 059A 0062;0061 1DFA 0316 1E8D5 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 HUNDRED THOUSANDS, LATIN SMALL LETTER B
+0061 1E8D5 059A 0316 1DFA 0062;0061 1DFA 1E8D5 0316 059A 0062;0061 1DFA 1E8D5 0316 059A 0062;0061 1DFA 1E8D5 0316 059A 0062;0061 1DFA 1E8D5 0316 059A 0062; # (a◌𞣕◌֚◌̖◌᷺b; a◌᷺◌𞣕◌̖◌֚b; a◌᷺◌𞣕◌̖◌֚b; a◌᷺◌𞣕◌̖◌֚b; a◌᷺◌𞣕◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER HUNDRED THOUSANDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1E8D6 0062;0061 1DFA 0316 1E8D6 059A 0062;0061 1DFA 0316 1E8D6 059A 0062;0061 1DFA 0316 1E8D6 059A 0062;0061 1DFA 0316 1E8D6 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 MILLIONS, LATIN SMALL LETTER B
+0061 1E8D6 059A 0316 1DFA 0062;0061 1DFA 1E8D6 0316 059A 0062;0061 1DFA 1E8D6 0316 059A 0062;0061 1DFA 1E8D6 0316 059A 0062;0061 1DFA 1E8D6 0316 059A 0062; # (a◌𞣖◌֚◌̖◌᷺b; a◌᷺◌𞣖◌̖◌֚b; a◌᷺◌𞣖◌̖◌֚b; a◌᷺◌𞣖◌̖◌֚b; a◌᷺◌𞣖◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER MILLIONS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 0315 0300 05AE 1E944 0062;00E0 05AE 1E944 0315 0062;0061 05AE 0300 1E944 0315 0062;00E0 05AE 1E944 0315 0062;0061 05AE 0300 1E944 0315 0062; # (a◌̕◌̀◌֮◌𞥄b; à◌֮◌𞥄◌̕b; a◌֮◌̀◌𞥄◌̕b; à◌֮◌𞥄◌̕b; a◌֮◌̀◌𞥄◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ADLAM ALIF LENGTHENER, LATIN SMALL LETTER B
0061 1E944 0315 0300 05AE 0062;0061 05AE 1E944 0300 0315 0062;0061 05AE 1E944 0300 0315 0062;0061 05AE 1E944 0300 0315 0062;0061 05AE 1E944 0300 0315 0062; # (a◌𞥄◌̕◌̀◌֮b; a◌֮◌𞥄◌̀◌̕b; a◌֮◌𞥄◌̀◌̕b; a◌֮◌𞥄◌̀◌̕b; a◌֮◌𞥄◌̀◌̕b; ) LATIN SMALL LETTER A, ADLAM ALIF LENGTHENER, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1E945 0062;00E0 05AE 1E945 0315 0062;0061 05AE 0300 1E945 0315 0062;00E0 05AE 1E945 0315 0062;0061 05AE 0300 1E945 0315 0062; # (a◌̕◌̀◌֮◌𞥅b; à◌֮◌𞥅◌̕b; a◌֮◌̀◌𞥅◌̕b; à◌֮◌𞥅◌̕b; a◌֮◌̀◌𞥅◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ADLAM VOWEL LENGTHENER, LATIN SMALL LETTER B
diff --git a/admin/unidata/README b/admin/unidata/README
index f5881a1a149..4b8444b0fec 100644
--- a/admin/unidata/README
+++ b/admin/unidata/README
@@ -7,28 +7,44 @@ The names, URLs, and dates for these files are as follows.
BidiBrackets.txt
http://www.unicode.org/Public/UNIDATA/BidiBrackets.txt
-2017-04-20
+2021-06-30
BidiMirroring.txt
http://www.unicode.org/Public/UNIDATA/BidiMirroring.txt
-2017-04-20
-
-IVD_Sequences.txt
-http://www.unicode.org/ivd/
-2016-08-15
-
-UnicodeData.txt
-http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
-2017-03-07
+2021-08-08
Blocks.txt
http://www.unicode.org/Public/8.0.0/ucd/Blocks.txt
-2017-04-20
+2021-01-22
+
+IVD_Sequences.txt
+http://www.unicode.org/ivd/
+2020-11-06
NormalizationTest.txt
http://www.unicode.org/Public/UNIDATA/NormalizationTest.txt
-2017-03-08
+2021-05-28
SpecialCasing.txt
http://unicode.org/Public/UNIDATA/SpecialCasing.txt
-2017-04-20
+2021-03-08
+
+UnicodeData.txt
+http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
+2021-07-06
+
+emoji-data.txt
+https://www.unicode.org/Public/14.0.0/ucd/emoji/emoji-data.txt
+2021-08-26
+
+emoji-zwj-sequences.txt
+https://www.unicode.org/Public/emoji/14.0/emoji-zwj-sequences.txt
+2021-06-08
+
+emoji-sequences.txt
+https://www.unicode.org/Public/emoji/14.0/emoji-sequences.txt
+2020-08-26
+
+emoji-test.txt
+https://unicode.org/Public/emoji/14.0/emoji-test.txt
+2021-10-28
diff --git a/admin/unidata/SpecialCasing.txt b/admin/unidata/SpecialCasing.txt
index 2a1a5a1d6b1..1c2e968a8c4 100644
--- a/admin/unidata/SpecialCasing.txt
+++ b/admin/unidata/SpecialCasing.txt
@@ -1,6 +1,6 @@
-# SpecialCasing-13.0.0.txt
-# Date: 2019-09-08, 23:31:24 GMT
-# © 2019 Unicode®, Inc.
+# SpecialCasing-14.0.0.txt
+# Date: 2021-03-08, 19:35:55 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
#
diff --git a/admin/unidata/UnicodeData.txt b/admin/unidata/UnicodeData.txt
index e22f967bbab..b5abef7ed43 100644
--- a/admin/unidata/UnicodeData.txt
+++ b/admin/unidata/UnicodeData.txt
@@ -1525,6 +1525,7 @@
061A;ARABIC SMALL KASRA;Mn;32;NSM;;;;;N;;;;;
061B;ARABIC SEMICOLON;Po;0;AL;;;;;N;;;;;
061C;ARABIC LETTER MARK;Cf;0;AL;;;;;N;;;;;
+061D;ARABIC END OF TEXT MARK;Po;0;AL;;;;;N;;;;;
061E;ARABIC TRIPLE DOT PUNCTUATION MARK;Po;0;AL;;;;;N;;;;;
061F;ARABIC QUESTION MARK;Po;0;AL;;;;;N;;;;;
0620;ARABIC LETTER KASHMIRI YEH;Lo;0;AL;;;;;N;;;;;
@@ -2089,6 +2090,47 @@
0868;SYRIAC LETTER MALAYALAM LLA;Lo;0;AL;;;;;N;;;;;
0869;SYRIAC LETTER MALAYALAM LLLA;Lo;0;AL;;;;;N;;;;;
086A;SYRIAC LETTER MALAYALAM SSA;Lo;0;AL;;;;;N;;;;;
+0870;ARABIC LETTER ALEF WITH ATTACHED FATHA;Lo;0;AL;;;;;N;;;;;
+0871;ARABIC LETTER ALEF WITH ATTACHED TOP RIGHT FATHA;Lo;0;AL;;;;;N;;;;;
+0872;ARABIC LETTER ALEF WITH RIGHT MIDDLE STROKE;Lo;0;AL;;;;;N;;;;;
+0873;ARABIC LETTER ALEF WITH LEFT MIDDLE STROKE;Lo;0;AL;;;;;N;;;;;
+0874;ARABIC LETTER ALEF WITH ATTACHED KASRA;Lo;0;AL;;;;;N;;;;;
+0875;ARABIC LETTER ALEF WITH ATTACHED BOTTOM RIGHT KASRA;Lo;0;AL;;;;;N;;;;;
+0876;ARABIC LETTER ALEF WITH ATTACHED ROUND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+0877;ARABIC LETTER ALEF WITH ATTACHED RIGHT ROUND DOT;Lo;0;AL;;;;;N;;;;;
+0878;ARABIC LETTER ALEF WITH ATTACHED LEFT ROUND DOT;Lo;0;AL;;;;;N;;;;;
+0879;ARABIC LETTER ALEF WITH ATTACHED ROUND DOT BELOW;Lo;0;AL;;;;;N;;;;;
+087A;ARABIC LETTER ALEF WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+087B;ARABIC LETTER ALEF WITH ATTACHED TOP RIGHT FATHA AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+087C;ARABIC LETTER ALEF WITH RIGHT MIDDLE STROKE AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+087D;ARABIC LETTER ALEF WITH ATTACHED BOTTOM RIGHT KASRA AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+087E;ARABIC LETTER ALEF WITH ATTACHED TOP RIGHT FATHA AND LEFT RING;Lo;0;AL;;;;;N;;;;;
+087F;ARABIC LETTER ALEF WITH RIGHT MIDDLE STROKE AND LEFT RING;Lo;0;AL;;;;;N;;;;;
+0880;ARABIC LETTER ALEF WITH ATTACHED BOTTOM RIGHT KASRA AND LEFT RING;Lo;0;AL;;;;;N;;;;;
+0881;ARABIC LETTER ALEF WITH ATTACHED RIGHT HAMZA;Lo;0;AL;;;;;N;;;;;
+0882;ARABIC LETTER ALEF WITH ATTACHED LEFT HAMZA;Lo;0;AL;;;;;N;;;;;
+0883;ARABIC TATWEEL WITH OVERSTRUCK HAMZA;Lo;0;AL;;;;;N;;;;;
+0884;ARABIC TATWEEL WITH OVERSTRUCK WAW;Lo;0;AL;;;;;N;;;;;
+0885;ARABIC TATWEEL WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+0886;ARABIC LETTER THIN YEH;Lo;0;AL;;;;;N;;;;;
+0887;ARABIC BASELINE ROUND DOT;Lo;0;AL;;;;;N;;;;;
+0888;ARABIC RAISED ROUND DOT;Sk;0;AL;;;;;N;;;;;
+0889;ARABIC LETTER NOON WITH INVERTED SMALL V;Lo;0;AL;;;;;N;;;;;
+088A;ARABIC LETTER HAH WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;;
+088B;ARABIC LETTER TAH WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+088C;ARABIC LETTER TAH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+088D;ARABIC LETTER KEHEH WITH TWO DOTS VERTICALLY BELOW;Lo;0;AL;;;;;N;;;;;
+088E;ARABIC VERTICAL TAIL;Lo;0;AL;;;;;N;;;;;
+0890;ARABIC POUND MARK ABOVE;Cf;0;AN;;;;;N;;;;;
+0891;ARABIC PIASTRE MARK ABOVE;Cf;0;AN;;;;;N;;;;;
+0898;ARABIC SMALL HIGH WORD AL-JUZ;Mn;230;NSM;;;;;N;;;;;
+0899;ARABIC SMALL LOW WORD ISHMAAM;Mn;220;NSM;;;;;N;;;;;
+089A;ARABIC SMALL LOW WORD IMAALA;Mn;220;NSM;;;;;N;;;;;
+089B;ARABIC SMALL LOW WORD TASHEEL;Mn;220;NSM;;;;;N;;;;;
+089C;ARABIC MADDA WAAJIB;Mn;230;NSM;;;;;N;;;;;
+089D;ARABIC SUPERSCRIPT ALEF MOKHASSAS;Mn;230;NSM;;;;;N;;;;;
+089E;ARABIC DOUBLED MADDA;Mn;230;NSM;;;;;N;;;;;
+089F;ARABIC HALF MADDA OVER MADDA;Mn;230;NSM;;;;;N;;;;;
08A0;ARABIC LETTER BEH WITH SMALL V BELOW;Lo;0;AL;;;;;N;;;;;
08A1;ARABIC LETTER BEH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;;
08A2;ARABIC LETTER JEEM WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
@@ -2110,6 +2152,7 @@
08B2;ARABIC LETTER ZAIN WITH INVERTED V ABOVE;Lo;0;AL;;;;;N;;;;;
08B3;ARABIC LETTER AIN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
08B4;ARABIC LETTER KAF WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+08B5;ARABIC LETTER QAF WITH DOT BELOW AND NO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
08B6;ARABIC LETTER BEH WITH SMALL MEEM ABOVE;Lo;0;AL;;;;;N;;;;;
08B7;ARABIC LETTER PEH WITH SMALL MEEM ABOVE;Lo;0;AL;;;;;N;;;;;
08B8;ARABIC LETTER TEH WITH SMALL TEH ABOVE;Lo;0;AL;;;;;N;;;;;
@@ -2128,6 +2171,17 @@
08C5;ARABIC LETTER JEEM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
08C6;ARABIC LETTER JEEM WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
08C7;ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE;Lo;0;AL;;;;;N;;;;;
+08C8;ARABIC LETTER GRAF;Lo;0;AL;;;;;N;;;;;
+08C9;ARABIC SMALL FARSI YEH;Lm;0;AL;;;;;N;;;;;
+08CA;ARABIC SMALL HIGH FARSI YEH;Mn;230;NSM;;;;;N;;;;;
+08CB;ARABIC SMALL HIGH YEH BARREE WITH TWO DOTS BELOW;Mn;230;NSM;;;;;N;;;;;
+08CC;ARABIC SMALL HIGH WORD SAH;Mn;230;NSM;;;;;N;;;;;
+08CD;ARABIC SMALL HIGH ZAH;Mn;230;NSM;;;;;N;;;;;
+08CE;ARABIC LARGE ROUND DOT ABOVE;Mn;230;NSM;;;;;N;;;;;
+08CF;ARABIC LARGE ROUND DOT BELOW;Mn;220;NSM;;;;;N;;;;;
+08D0;ARABIC SUKUN BELOW;Mn;220;NSM;;;;;N;;;;;
+08D1;ARABIC LARGE CIRCLE BELOW;Mn;220;NSM;;;;;N;;;;;
+08D2;ARABIC LARGE ROUND DOT INSIDE CIRCLE BELOW;Mn;220;NSM;;;;;N;;;;;
08D3;ARABIC SMALL LOW WAW;Mn;220;NSM;;;;;N;;;;;
08D4;ARABIC SMALL HIGH WORD AR-RUB;Mn;230;NSM;;;;;N;;;;;
08D5;ARABIC SMALL HIGH SAD;Mn;230;NSM;;;;;N;;;;;
@@ -2786,6 +2840,7 @@
0C37;TELUGU LETTER SSA;Lo;0;L;;;;;N;;;;;
0C38;TELUGU LETTER SA;Lo;0;L;;;;;N;;;;;
0C39;TELUGU LETTER HA;Lo;0;L;;;;;N;;;;;
+0C3C;TELUGU SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
0C3D;TELUGU SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
0C3E;TELUGU VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
0C3F;TELUGU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
@@ -2806,6 +2861,7 @@
0C58;TELUGU LETTER TSA;Lo;0;L;;;;;N;;;;;
0C59;TELUGU LETTER DZA;Lo;0;L;;;;;N;;;;;
0C5A;TELUGU LETTER RRRA;Lo;0;L;;;;;N;;;;;
+0C5D;TELUGU LETTER NAKAARA POLLU;Lo;0;L;;;;;N;;;;;
0C60;TELUGU LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
0C61;TELUGU LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
0C62;TELUGU VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
@@ -2901,6 +2957,7 @@
0CCD;KANNADA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
0CD5;KANNADA LENGTH MARK;Mc;0;L;;;;;N;;;;;
0CD6;KANNADA AI LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0CDD;KANNADA LETTER NAKAARA POLLU;Lo;0;L;;;;;N;;;;;
0CDE;KANNADA LETTER FA;Lo;0;L;;;;;N;;;;;
0CE0;KANNADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
0CE1;KANNADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
@@ -5258,6 +5315,7 @@
170A;TAGALOG LETTER BA;Lo;0;L;;;;;N;;;;;
170B;TAGALOG LETTER MA;Lo;0;L;;;;;N;;;;;
170C;TAGALOG LETTER YA;Lo;0;L;;;;;N;;;;;
+170D;TAGALOG LETTER RA;Lo;0;L;;;;;N;;;;;
170E;TAGALOG LETTER LA;Lo;0;L;;;;;N;;;;;
170F;TAGALOG LETTER WA;Lo;0;L;;;;;N;;;;;
1710;TAGALOG LETTER SA;Lo;0;L;;;;;N;;;;;
@@ -5265,6 +5323,8 @@
1712;TAGALOG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
1713;TAGALOG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
1714;TAGALOG SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+1715;TAGALOG SIGN PAMUDPOD;Mc;9;L;;;;;N;;;;;
+171F;TAGALOG LETTER ARCHAIC RA;Lo;0;L;;;;;N;;;;;
1720;HANUNOO LETTER A;Lo;0;L;;;;;N;;;;;
1721;HANUNOO LETTER I;Lo;0;L;;;;;N;;;;;
1722;HANUNOO LETTER U;Lo;0;L;;;;;N;;;;;
@@ -5285,7 +5345,7 @@
1731;HANUNOO LETTER HA;Lo;0;L;;;;;N;;;;;
1732;HANUNOO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
1733;HANUNOO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
-1734;HANUNOO SIGN PAMUDPOD;Mn;9;NSM;;;;;N;;;;;
+1734;HANUNOO SIGN PAMUDPOD;Mc;9;L;;;;;N;;;;;
1735;PHILIPPINE SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;;
1736;PHILIPPINE DOUBLE PUNCTUATION;Po;0;L;;;;;N;;;;;
1740;BUHID LETTER A;Lo;0;L;;;;;N;;;;;
@@ -5455,6 +5515,7 @@
180C;MONGOLIAN FREE VARIATION SELECTOR TWO;Mn;0;NSM;;;;;N;;;;;
180D;MONGOLIAN FREE VARIATION SELECTOR THREE;Mn;0;NSM;;;;;N;;;;;
180E;MONGOLIAN VOWEL SEPARATOR;Cf;0;BN;;;;;N;;;;;
+180F;MONGOLIAN FREE VARIATION SELECTOR FOUR;Mn;0;NSM;;;;;N;;;;;
1810;MONGOLIAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
1811;MONGOLIAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
1812;MONGOLIAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
@@ -6059,6 +6120,20 @@
1ABE;COMBINING PARENTHESES OVERLAY;Me;0;NSM;;;;;N;;;;;
1ABF;COMBINING LATIN SMALL LETTER W BELOW;Mn;220;NSM;;;;;N;;;;;
1AC0;COMBINING LATIN SMALL LETTER TURNED W BELOW;Mn;220;NSM;;;;;N;;;;;
+1AC1;COMBINING LEFT PARENTHESIS ABOVE LEFT;Mn;230;NSM;;;;;N;;;;;
+1AC2;COMBINING RIGHT PARENTHESIS ABOVE RIGHT;Mn;230;NSM;;;;;N;;;;;
+1AC3;COMBINING LEFT PARENTHESIS BELOW LEFT;Mn;220;NSM;;;;;N;;;;;
+1AC4;COMBINING RIGHT PARENTHESIS BELOW RIGHT;Mn;220;NSM;;;;;N;;;;;
+1AC5;COMBINING SQUARE BRACKETS ABOVE;Mn;230;NSM;;;;;N;;;;;
+1AC6;COMBINING NUMBER SIGN ABOVE;Mn;230;NSM;;;;;N;;;;;
+1AC7;COMBINING INVERTED DOUBLE ARCH ABOVE;Mn;230;NSM;;;;;N;;;;;
+1AC8;COMBINING PLUS SIGN ABOVE;Mn;230;NSM;;;;;N;;;;;
+1AC9;COMBINING DOUBLE PLUS SIGN ABOVE;Mn;230;NSM;;;;;N;;;;;
+1ACA;COMBINING DOUBLE PLUS SIGN BELOW;Mn;220;NSM;;;;;N;;;;;
+1ACB;COMBINING TRIPLE ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;;
+1ACC;COMBINING LATIN SMALL LETTER INSULAR G;Mn;230;NSM;;;;;N;;;;;
+1ACD;COMBINING LATIN SMALL LETTER INSULAR R;Mn;230;NSM;;;;;N;;;;;
+1ACE;COMBINING LATIN SMALL LETTER INSULAR T;Mn;230;NSM;;;;;N;;;;;
1B00;BALINESE SIGN ULU RICEM;Mn;0;NSM;;;;;N;;;;;
1B01;BALINESE SIGN ULU CANDRA;Mn;0;NSM;;;;;N;;;;;
1B02;BALINESE SIGN CECEK;Mn;0;NSM;;;;;N;;;;;
@@ -6135,6 +6210,7 @@
1B49;BALINESE LETTER VE SASAK;Lo;0;L;;;;;N;;;;;
1B4A;BALINESE LETTER ZAL SASAK;Lo;0;L;;;;;N;;;;;
1B4B;BALINESE LETTER ASYURA SASAK;Lo;0;L;;;;;N;;;;;
+1B4C;BALINESE LETTER ARCHAIC JNYA;Lo;0;L;;;;;N;;;;;
1B50;BALINESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
1B51;BALINESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
1B52;BALINESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
@@ -6180,6 +6256,8 @@
1B7A;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLAK;So;0;L;;;;;N;;;;;
1B7B;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLUK;So;0;L;;;;;N;;;;;
1B7C;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING;So;0;L;;;;;N;;;;;
+1B7D;BALINESE PANTI LANTANG;Po;0;L;;;;;N;;;;;
+1B7E;BALINESE PAMADA LANTANG;Po;0;L;;;;;N;;;;;
1B80;SUNDANESE SIGN PANYECEK;Mn;0;NSM;;;;;N;;;;;
1B81;SUNDANESE SIGN PANGLAYAR;Mn;0;NSM;;;;;N;;;;;
1B82;SUNDANESE SIGN PANGWISAD;Mc;0;L;;;;;N;;;;;
@@ -6778,6 +6856,7 @@
1DF7;COMBINING KAVYKA ABOVE LEFT;Mn;228;NSM;;;;;N;;;;;
1DF8;COMBINING DOT ABOVE LEFT;Mn;228;NSM;;;;;N;;;;;
1DF9;COMBINING WIDE INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;;;;;
+1DFA;COMBINING DOT BELOW LEFT;Mn;218;NSM;;;;;N;;;;;
1DFB;COMBINING DELETION MARK;Mn;230;NSM;;;;;N;;;;;
1DFC;COMBINING DOUBLE INVERTED BREVE BELOW;Mn;233;NSM;;;;;N;;;;;
1DFD;COMBINING ALMOST EQUAL TO BELOW;Mn;220;NSM;;;;;N;;;;;
@@ -7457,6 +7536,7 @@
20BD;RUBLE SIGN;Sc;0;ET;;;;;N;;;;;
20BE;LARI SIGN;Sc;0;ET;;;;;N;;;;;
20BF;BITCOIN SIGN;Sc;0;ET;;;;;N;;;;;
+20C0;SOM SIGN;Sc;0;ET;;;;;N;;;;;
20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;;
20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;;
20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;;
@@ -10300,6 +10380,7 @@
2C2C;GLAGOLITIC CAPITAL LETTER SHTAPIC;Lu;0;L;;;;;N;;;;2C5C;
2C2D;GLAGOLITIC CAPITAL LETTER TROKUTASTI A;Lu;0;L;;;;;N;;;;2C5D;
2C2E;GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE;Lu;0;L;;;;;N;;;;2C5E;
+2C2F;GLAGOLITIC CAPITAL LETTER CAUDATE CHRIVI;Lu;0;L;;;;;N;;;;2C5F;
2C30;GLAGOLITIC SMALL LETTER AZU;Ll;0;L;;;;;N;;;2C00;;2C00
2C31;GLAGOLITIC SMALL LETTER BUKY;Ll;0;L;;;;;N;;;2C01;;2C01
2C32;GLAGOLITIC SMALL LETTER VEDE;Ll;0;L;;;;;N;;;2C02;;2C02
@@ -10347,6 +10428,7 @@
2C5C;GLAGOLITIC SMALL LETTER SHTAPIC;Ll;0;L;;;;;N;;;2C2C;;2C2C
2C5D;GLAGOLITIC SMALL LETTER TROKUTASTI A;Ll;0;L;;;;;N;;;2C2D;;2C2D
2C5E;GLAGOLITIC SMALL LETTER LATINATE MYSLITE;Ll;0;L;;;;;N;;;2C2E;;2C2E
+2C5F;GLAGOLITIC SMALL LETTER CAUDATE CHRIVI;Ll;0;L;;;;;N;;;2C2F;;2C2F
2C60;LATIN CAPITAL LETTER L WITH DOUBLE BAR;Lu;0;L;;;;;N;;;;2C61;
2C61;LATIN SMALL LETTER L WITH DOUBLE BAR;Ll;0;L;;;;;N;;;2C60;;2C60
2C62;LATIN CAPITAL LETTER L WITH MIDDLE TILDE;Lu;0;L;;;;;N;;;;026B;
@@ -10795,6 +10877,17 @@
2E50;CROSS PATTY WITH RIGHT CROSSBAR;So;0;ON;;;;;N;;;;;
2E51;CROSS PATTY WITH LEFT CROSSBAR;So;0;ON;;;;;N;;;;;
2E52;TIRONIAN SIGN CAPITAL ET;Po;0;ON;;;;;N;;;;;
+2E53;MEDIEVAL EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
+2E54;MEDIEVAL QUESTION MARK;Po;0;ON;;;;;N;;;;;
+2E55;LEFT SQUARE BRACKET WITH STROKE;Ps;0;ON;;;;;Y;;;;;
+2E56;RIGHT SQUARE BRACKET WITH STROKE;Pe;0;ON;;;;;Y;;;;;
+2E57;LEFT SQUARE BRACKET WITH DOUBLE STROKE;Ps;0;ON;;;;;Y;;;;;
+2E58;RIGHT SQUARE BRACKET WITH DOUBLE STROKE;Pe;0;ON;;;;;Y;;;;;
+2E59;TOP HALF LEFT PARENTHESIS;Ps;0;ON;;;;;Y;;;;;
+2E5A;TOP HALF RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;;;;;
+2E5B;BOTTOM HALF LEFT PARENTHESIS;Ps;0;ON;;;;;Y;;;;;
+2E5C;BOTTOM HALF RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;;;;;
+2E5D;OBLIQUE HYPHEN;Pd;0;ON;;;;;N;;;;;
2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;;
2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;;
2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;;
@@ -12204,7 +12297,7 @@
4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;;
4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;;
4E00;<CJK Ideograph, First>;Lo;0;L;;;;;N;;;;;
-9FFC;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
+9FFF;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;;
A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;;
A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;;
@@ -14149,6 +14242,8 @@ A7BC;LATIN CAPITAL LETTER GLOTTAL I;Lu;0;L;;;;;N;;;;A7BD;
A7BD;LATIN SMALL LETTER GLOTTAL I;Ll;0;L;;;;;N;;;A7BC;;A7BC
A7BE;LATIN CAPITAL LETTER GLOTTAL U;Lu;0;L;;;;;N;;;;A7BF;
A7BF;LATIN SMALL LETTER GLOTTAL U;Ll;0;L;;;;;N;;;A7BE;;A7BE
+A7C0;LATIN CAPITAL LETTER OLD POLISH O;Lu;0;L;;;;;N;;;;A7C1;
+A7C1;LATIN SMALL LETTER OLD POLISH O;Ll;0;L;;;;;N;;;A7C0;;A7C0
A7C2;LATIN CAPITAL LETTER ANGLICANA W;Lu;0;L;;;;;N;;;;A7C3;
A7C3;LATIN SMALL LETTER ANGLICANA W;Ll;0;L;;;;;N;;;A7C2;;A7C2
A7C4;LATIN CAPITAL LETTER C WITH PALATAL HOOK;Lu;0;L;;;;;N;;;;A794;
@@ -14158,6 +14253,17 @@ A7C7;LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY;Lu;0;L;;;;;N;;;;A7C8;
A7C8;LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY;Ll;0;L;;;;;N;;;A7C7;;A7C7
A7C9;LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY;Lu;0;L;;;;;N;;;;A7CA;
A7CA;LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY;Ll;0;L;;;;;N;;;A7C9;;A7C9
+A7D0;LATIN CAPITAL LETTER CLOSED INSULAR G;Lu;0;L;;;;;N;;;;A7D1;
+A7D1;LATIN SMALL LETTER CLOSED INSULAR G;Ll;0;L;;;;;N;;;A7D0;;A7D0
+A7D3;LATIN SMALL LETTER DOUBLE THORN;Ll;0;L;;;;;N;;;;;
+A7D5;LATIN SMALL LETTER DOUBLE WYNN;Ll;0;L;;;;;N;;;;;
+A7D6;LATIN CAPITAL LETTER MIDDLE SCOTS S;Lu;0;L;;;;;N;;;;A7D7;
+A7D7;LATIN SMALL LETTER MIDDLE SCOTS S;Ll;0;L;;;;;N;;;A7D6;;A7D6
+A7D8;LATIN CAPITAL LETTER SIGMOID S;Lu;0;L;;;;;N;;;;A7D9;
+A7D9;LATIN SMALL LETTER SIGMOID S;Ll;0;L;;;;;N;;;A7D8;;A7D8
+A7F2;MODIFIER LETTER CAPITAL C;Lm;0;L;<super> 0043;;;;N;;;;;
+A7F3;MODIFIER LETTER CAPITAL F;Lm;0;L;<super> 0046;;;;N;;;;;
+A7F4;MODIFIER LETTER CAPITAL Q;Lm;0;L;<super> 0051;;;;N;;;;;
A7F5;LATIN CAPITAL LETTER REVERSED HALF H;Lu;0;L;;;;;N;;;;A7F6;
A7F6;LATIN SMALL LETTER REVERSED HALF H;Ll;0;L;;;;;N;;;A7F5;;A7F5
A7F7;LATIN EPIGRAPHIC LETTER SIDEWAYS I;Lo;0;L;;;;;N;;;;;
@@ -15794,6 +15900,7 @@ FBBE;ARABIC SYMBOL TWO DOTS VERTICALLY BELOW;Sk;0;AL;;;;;N;;;;;
FBBF;ARABIC SYMBOL RING;Sk;0;AL;;;;;N;;;;;
FBC0;ARABIC SYMBOL SMALL TAH ABOVE;Sk;0;AL;;;;;N;;;;;
FBC1;ARABIC SYMBOL SMALL TAH BELOW;Sk;0;AL;;;;;N;;;;;
+FBC2;ARABIC SYMBOL WASLA ABOVE;Sk;0;AL;;;;;N;;;;;
FBD3;ARABIC LETTER NG ISOLATED FORM;Lo;0;AL;<isolated> 06AD;;;;N;;;;;
FBD4;ARABIC LETTER NG FINAL FORM;Lo;0;AL;<final> 06AD;;;;N;;;;;
FBD5;ARABIC LETTER NG INITIAL FORM;Lo;0;AL;<initial> 06AD;;;;N;;;;;
@@ -16159,6 +16266,22 @@ FD3C;ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM;Lo;0;AL;<final> 0627 064B;;;;
FD3D;ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM;Lo;0;AL;<isolated> 0627 064B;;;;N;;;;;
FD3E;ORNATE LEFT PARENTHESIS;Pe;0;ON;;;;;N;;;;;
FD3F;ORNATE RIGHT PARENTHESIS;Ps;0;ON;;;;;N;;;;;
+FD40;ARABIC LIGATURE RAHIMAHU ALLAAH;So;0;ON;;;;;N;;;;;
+FD41;ARABIC LIGATURE RADI ALLAAHU ANH;So;0;ON;;;;;N;;;;;
+FD42;ARABIC LIGATURE RADI ALLAAHU ANHAA;So;0;ON;;;;;N;;;;;
+FD43;ARABIC LIGATURE RADI ALLAAHU ANHUM;So;0;ON;;;;;N;;;;;
+FD44;ARABIC LIGATURE RADI ALLAAHU ANHUMAA;So;0;ON;;;;;N;;;;;
+FD45;ARABIC LIGATURE RADI ALLAAHU ANHUNNA;So;0;ON;;;;;N;;;;;
+FD46;ARABIC LIGATURE SALLALLAAHU ALAYHI WA-AALIH;So;0;ON;;;;;N;;;;;
+FD47;ARABIC LIGATURE ALAYHI AS-SALAAM;So;0;ON;;;;;N;;;;;
+FD48;ARABIC LIGATURE ALAYHIM AS-SALAAM;So;0;ON;;;;;N;;;;;
+FD49;ARABIC LIGATURE ALAYHIMAA AS-SALAAM;So;0;ON;;;;;N;;;;;
+FD4A;ARABIC LIGATURE ALAYHI AS-SALAATU WAS-SALAAM;So;0;ON;;;;;N;;;;;
+FD4B;ARABIC LIGATURE QUDDISA SIRRAH;So;0;ON;;;;;N;;;;;
+FD4C;ARABIC LIGATURE SALLALLAHU ALAYHI WAAALIHEE WA-SALLAM;So;0;ON;;;;;N;;;;;
+FD4D;ARABIC LIGATURE ALAYHAA AS-SALAAM;So;0;ON;;;;;N;;;;;
+FD4E;ARABIC LIGATURE TABAARAKA WA-TAAALAA;So;0;ON;;;;;N;;;;;
+FD4F;ARABIC LIGATURE RAHIMAHUM ALLAAH;So;0;ON;;;;;N;;;;;
FD50;ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062C 0645;;;;N;;;;;
FD51;ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM;Lo;0;AL;<final> 062A 062D 062C;;;;N;;;;;
FD52;ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062D 062C;;;;N;;;;;
@@ -16277,6 +16400,7 @@ FDC4;ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639
FDC5;ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0635 0645 0645;;;;N;;;;;
FDC6;ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0633 062E 064A;;;;N;;;;;
FDC7;ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 062C 064A;;;;N;;;;;
+FDCF;ARABIC LIGATURE SALAAMUHU ALAYNAA;So;0;ON;;;;;N;;;;;
FDF0;ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 06D2;;;;N;;;;;
FDF1;ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL;<isolated> 0642 0644 06D2;;;;N;;;;;
FDF2;ARABIC LIGATURE ALLAH ISOLATED FORM;Lo;0;AL;<isolated> 0627 0644 0644 0647;;;;N;;;;;
@@ -16291,6 +16415,8 @@ FDFA;ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM;Lo;0;AL;<isolated> 0635 0644 06
FDFB;ARABIC LIGATURE JALLAJALALOUHOU;Lo;0;AL;<isolated> 062C 0644 0020 062C 0644 0627 0644 0647;;;;N;ARABIC LETTER JALLAJALALOUHOU;;;;
FDFC;RIAL SIGN;Sc;0;AL;<isolated> 0631 06CC 0627 0644;;;;N;;;;;
FDFD;ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM;So;0;ON;;;;;N;;;;;
+FDFE;ARABIC LIGATURE SUBHAANAHU WA TAAALAA;So;0;ON;;;;;N;;;;;
+FDFF;ARABIC LIGATURE AZZA WA JALL;So;0;ON;;;;;N;;;;;
FE00;VARIATION SELECTOR-1;Mn;0;NSM;;;;;N;;;;;
FE01;VARIATION SELECTOR-2;Mn;0;NSM;;;;;N;;;;;
FE02;VARIATION SELECTOR-3;Mn;0;NSM;;;;;N;;;;;
@@ -17798,6 +17924,76 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
10562;CAUCASIAN ALBANIAN LETTER PIWR;Lo;0;L;;;;;N;;;;;
10563;CAUCASIAN ALBANIAN LETTER KIW;Lo;0;L;;;;;N;;;;;
1056F;CAUCASIAN ALBANIAN CITATION MARK;Po;0;L;;;;;N;;;;;
+10570;VITHKUQI CAPITAL LETTER A;Lu;0;L;;;;;N;;;;10597;
+10571;VITHKUQI CAPITAL LETTER BBE;Lu;0;L;;;;;N;;;;10598;
+10572;VITHKUQI CAPITAL LETTER BE;Lu;0;L;;;;;N;;;;10599;
+10573;VITHKUQI CAPITAL LETTER CE;Lu;0;L;;;;;N;;;;1059A;
+10574;VITHKUQI CAPITAL LETTER CHE;Lu;0;L;;;;;N;;;;1059B;
+10575;VITHKUQI CAPITAL LETTER DE;Lu;0;L;;;;;N;;;;1059C;
+10576;VITHKUQI CAPITAL LETTER DHE;Lu;0;L;;;;;N;;;;1059D;
+10577;VITHKUQI CAPITAL LETTER EI;Lu;0;L;;;;;N;;;;1059E;
+10578;VITHKUQI CAPITAL LETTER E;Lu;0;L;;;;;N;;;;1059F;
+10579;VITHKUQI CAPITAL LETTER FE;Lu;0;L;;;;;N;;;;105A0;
+1057A;VITHKUQI CAPITAL LETTER GA;Lu;0;L;;;;;N;;;;105A1;
+1057C;VITHKUQI CAPITAL LETTER HA;Lu;0;L;;;;;N;;;;105A3;
+1057D;VITHKUQI CAPITAL LETTER HHA;Lu;0;L;;;;;N;;;;105A4;
+1057E;VITHKUQI CAPITAL LETTER I;Lu;0;L;;;;;N;;;;105A5;
+1057F;VITHKUQI CAPITAL LETTER IJE;Lu;0;L;;;;;N;;;;105A6;
+10580;VITHKUQI CAPITAL LETTER JE;Lu;0;L;;;;;N;;;;105A7;
+10581;VITHKUQI CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;105A8;
+10582;VITHKUQI CAPITAL LETTER LA;Lu;0;L;;;;;N;;;;105A9;
+10583;VITHKUQI CAPITAL LETTER LLA;Lu;0;L;;;;;N;;;;105AA;
+10584;VITHKUQI CAPITAL LETTER ME;Lu;0;L;;;;;N;;;;105AB;
+10585;VITHKUQI CAPITAL LETTER NE;Lu;0;L;;;;;N;;;;105AC;
+10586;VITHKUQI CAPITAL LETTER NJE;Lu;0;L;;;;;N;;;;105AD;
+10587;VITHKUQI CAPITAL LETTER O;Lu;0;L;;;;;N;;;;105AE;
+10588;VITHKUQI CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;105AF;
+10589;VITHKUQI CAPITAL LETTER QA;Lu;0;L;;;;;N;;;;105B0;
+1058A;VITHKUQI CAPITAL LETTER RE;Lu;0;L;;;;;N;;;;105B1;
+1058C;VITHKUQI CAPITAL LETTER SE;Lu;0;L;;;;;N;;;;105B3;
+1058D;VITHKUQI CAPITAL LETTER SHE;Lu;0;L;;;;;N;;;;105B4;
+1058E;VITHKUQI CAPITAL LETTER TE;Lu;0;L;;;;;N;;;;105B5;
+1058F;VITHKUQI CAPITAL LETTER THE;Lu;0;L;;;;;N;;;;105B6;
+10590;VITHKUQI CAPITAL LETTER U;Lu;0;L;;;;;N;;;;105B7;
+10591;VITHKUQI CAPITAL LETTER VE;Lu;0;L;;;;;N;;;;105B8;
+10592;VITHKUQI CAPITAL LETTER XE;Lu;0;L;;;;;N;;;;105B9;
+10594;VITHKUQI CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;105BB;
+10595;VITHKUQI CAPITAL LETTER ZE;Lu;0;L;;;;;N;;;;105BC;
+10597;VITHKUQI SMALL LETTER A;Ll;0;L;;;;;N;;;10570;;10570
+10598;VITHKUQI SMALL LETTER BBE;Ll;0;L;;;;;N;;;10571;;10571
+10599;VITHKUQI SMALL LETTER BE;Ll;0;L;;;;;N;;;10572;;10572
+1059A;VITHKUQI SMALL LETTER CE;Ll;0;L;;;;;N;;;10573;;10573
+1059B;VITHKUQI SMALL LETTER CHE;Ll;0;L;;;;;N;;;10574;;10574
+1059C;VITHKUQI SMALL LETTER DE;Ll;0;L;;;;;N;;;10575;;10575
+1059D;VITHKUQI SMALL LETTER DHE;Ll;0;L;;;;;N;;;10576;;10576
+1059E;VITHKUQI SMALL LETTER EI;Ll;0;L;;;;;N;;;10577;;10577
+1059F;VITHKUQI SMALL LETTER E;Ll;0;L;;;;;N;;;10578;;10578
+105A0;VITHKUQI SMALL LETTER FE;Ll;0;L;;;;;N;;;10579;;10579
+105A1;VITHKUQI SMALL LETTER GA;Ll;0;L;;;;;N;;;1057A;;1057A
+105A3;VITHKUQI SMALL LETTER HA;Ll;0;L;;;;;N;;;1057C;;1057C
+105A4;VITHKUQI SMALL LETTER HHA;Ll;0;L;;;;;N;;;1057D;;1057D
+105A5;VITHKUQI SMALL LETTER I;Ll;0;L;;;;;N;;;1057E;;1057E
+105A6;VITHKUQI SMALL LETTER IJE;Ll;0;L;;;;;N;;;1057F;;1057F
+105A7;VITHKUQI SMALL LETTER JE;Ll;0;L;;;;;N;;;10580;;10580
+105A8;VITHKUQI SMALL LETTER KA;Ll;0;L;;;;;N;;;10581;;10581
+105A9;VITHKUQI SMALL LETTER LA;Ll;0;L;;;;;N;;;10582;;10582
+105AA;VITHKUQI SMALL LETTER LLA;Ll;0;L;;;;;N;;;10583;;10583
+105AB;VITHKUQI SMALL LETTER ME;Ll;0;L;;;;;N;;;10584;;10584
+105AC;VITHKUQI SMALL LETTER NE;Ll;0;L;;;;;N;;;10585;;10585
+105AD;VITHKUQI SMALL LETTER NJE;Ll;0;L;;;;;N;;;10586;;10586
+105AE;VITHKUQI SMALL LETTER O;Ll;0;L;;;;;N;;;10587;;10587
+105AF;VITHKUQI SMALL LETTER PE;Ll;0;L;;;;;N;;;10588;;10588
+105B0;VITHKUQI SMALL LETTER QA;Ll;0;L;;;;;N;;;10589;;10589
+105B1;VITHKUQI SMALL LETTER RE;Ll;0;L;;;;;N;;;1058A;;1058A
+105B3;VITHKUQI SMALL LETTER SE;Ll;0;L;;;;;N;;;1058C;;1058C
+105B4;VITHKUQI SMALL LETTER SHE;Ll;0;L;;;;;N;;;1058D;;1058D
+105B5;VITHKUQI SMALL LETTER TE;Ll;0;L;;;;;N;;;1058E;;1058E
+105B6;VITHKUQI SMALL LETTER THE;Ll;0;L;;;;;N;;;1058F;;1058F
+105B7;VITHKUQI SMALL LETTER U;Ll;0;L;;;;;N;;;10590;;10590
+105B8;VITHKUQI SMALL LETTER VE;Ll;0;L;;;;;N;;;10591;;10591
+105B9;VITHKUQI SMALL LETTER XE;Ll;0;L;;;;;N;;;10592;;10592
+105BB;VITHKUQI SMALL LETTER Y;Ll;0;L;;;;;N;;;10594;;10594
+105BC;VITHKUQI SMALL LETTER ZE;Ll;0;L;;;;;N;;;10595;;10595
10600;LINEAR A SIGN AB001;Lo;0;L;;;;;N;;;;;
10601;LINEAR A SIGN AB002;Lo;0;L;;;;;N;;;;;
10602;LINEAR A SIGN AB003;Lo;0;L;;;;;N;;;;;
@@ -18139,6 +18335,63 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
10765;LINEAR A SIGN A805;Lo;0;L;;;;;N;;;;;
10766;LINEAR A SIGN A806;Lo;0;L;;;;;N;;;;;
10767;LINEAR A SIGN A807;Lo;0;L;;;;;N;;;;;
+10780;MODIFIER LETTER SMALL CAPITAL AA;Lm;0;L;;;;;N;;;;;
+10781;MODIFIER LETTER SUPERSCRIPT TRIANGULAR COLON;Lm;0;L;<super> 02D0;;;;N;;;;;
+10782;MODIFIER LETTER SUPERSCRIPT HALF TRIANGULAR COLON;Lm;0;L;<super> 02D1;;;;N;;;;;
+10783;MODIFIER LETTER SMALL AE;Lm;0;L;<super> 00E6;;;;N;;;;;
+10784;MODIFIER LETTER SMALL CAPITAL B;Lm;0;L;<super> 0299;;;;N;;;;;
+10785;MODIFIER LETTER SMALL B WITH HOOK;Lm;0;L;<super> 0253;;;;N;;;;;
+10787;MODIFIER LETTER SMALL DZ DIGRAPH;Lm;0;L;<super> 02A3;;;;N;;;;;
+10788;MODIFIER LETTER SMALL DZ DIGRAPH WITH RETROFLEX HOOK;Lm;0;L;<super> AB66;;;;N;;;;;
+10789;MODIFIER LETTER SMALL DZ DIGRAPH WITH CURL;Lm;0;L;<super> 02A5;;;;N;;;;;
+1078A;MODIFIER LETTER SMALL DEZH DIGRAPH;Lm;0;L;<super> 02A4;;;;N;;;;;
+1078B;MODIFIER LETTER SMALL D WITH TAIL;Lm;0;L;<super> 0256;;;;N;;;;;
+1078C;MODIFIER LETTER SMALL D WITH HOOK;Lm;0;L;<super> 0257;;;;N;;;;;
+1078D;MODIFIER LETTER SMALL D WITH HOOK AND TAIL;Lm;0;L;<super> 1D91;;;;N;;;;;
+1078E;MODIFIER LETTER SMALL REVERSED E;Lm;0;L;<super> 0258;;;;N;;;;;
+1078F;MODIFIER LETTER SMALL CLOSED REVERSED OPEN E;Lm;0;L;<super> 025E;;;;N;;;;;
+10790;MODIFIER LETTER SMALL FENG DIGRAPH;Lm;0;L;<super> 02A9;;;;N;;;;;
+10791;MODIFIER LETTER SMALL RAMS HORN;Lm;0;L;<super> 0264;;;;N;;;;;
+10792;MODIFIER LETTER SMALL CAPITAL G;Lm;0;L;<super> 0262;;;;N;;;;;
+10793;MODIFIER LETTER SMALL G WITH HOOK;Lm;0;L;<super> 0260;;;;N;;;;;
+10794;MODIFIER LETTER SMALL CAPITAL G WITH HOOK;Lm;0;L;<super> 029B;;;;N;;;;;
+10795;MODIFIER LETTER SMALL H WITH STROKE;Lm;0;L;<super> 0127;;;;N;;;;;
+10796;MODIFIER LETTER SMALL CAPITAL H;Lm;0;L;<super> 029C;;;;N;;;;;
+10797;MODIFIER LETTER SMALL HENG WITH HOOK;Lm;0;L;<super> 0267;;;;N;;;;;
+10798;MODIFIER LETTER SMALL DOTLESS J WITH STROKE AND HOOK;Lm;0;L;<super> 0284;;;;N;;;;;
+10799;MODIFIER LETTER SMALL LS DIGRAPH;Lm;0;L;<super> 02AA;;;;N;;;;;
+1079A;MODIFIER LETTER SMALL LZ DIGRAPH;Lm;0;L;<super> 02AB;;;;N;;;;;
+1079B;MODIFIER LETTER SMALL L WITH BELT;Lm;0;L;<super> 026C;;;;N;;;;;
+1079C;MODIFIER LETTER SMALL CAPITAL L WITH BELT;Lm;0;L;<super> 1DF04;;;;N;;;;;
+1079D;MODIFIER LETTER SMALL L WITH RETROFLEX HOOK AND BELT;Lm;0;L;<super> A78E;;;;N;;;;;
+1079E;MODIFIER LETTER SMALL LEZH;Lm;0;L;<super> 026E;;;;N;;;;;
+1079F;MODIFIER LETTER SMALL LEZH WITH RETROFLEX HOOK;Lm;0;L;<super> 1DF05;;;;N;;;;;
+107A0;MODIFIER LETTER SMALL TURNED Y;Lm;0;L;<super> 028E;;;;N;;;;;
+107A1;MODIFIER LETTER SMALL TURNED Y WITH BELT;Lm;0;L;<super> 1DF06;;;;N;;;;;
+107A2;MODIFIER LETTER SMALL O WITH STROKE;Lm;0;L;<super> 00F8;;;;N;;;;;
+107A3;MODIFIER LETTER SMALL CAPITAL OE;Lm;0;L;<super> 0276;;;;N;;;;;
+107A4;MODIFIER LETTER SMALL CLOSED OMEGA;Lm;0;L;<super> 0277;;;;N;;;;;
+107A5;MODIFIER LETTER SMALL Q;Lm;0;L;<super> 0071;;;;N;;;;;
+107A6;MODIFIER LETTER SMALL TURNED R WITH LONG LEG;Lm;0;L;<super> 027A;;;;N;;;;;
+107A7;MODIFIER LETTER SMALL TURNED R WITH LONG LEG AND RETROFLEX HOOK;Lm;0;L;<super> 1DF08;;;;N;;;;;
+107A8;MODIFIER LETTER SMALL R WITH TAIL;Lm;0;L;<super> 027D;;;;N;;;;;
+107A9;MODIFIER LETTER SMALL R WITH FISHHOOK;Lm;0;L;<super> 027E;;;;N;;;;;
+107AA;MODIFIER LETTER SMALL CAPITAL R;Lm;0;L;<super> 0280;;;;N;;;;;
+107AB;MODIFIER LETTER SMALL TC DIGRAPH WITH CURL;Lm;0;L;<super> 02A8;;;;N;;;;;
+107AC;MODIFIER LETTER SMALL TS DIGRAPH;Lm;0;L;<super> 02A6;;;;N;;;;;
+107AD;MODIFIER LETTER SMALL TS DIGRAPH WITH RETROFLEX HOOK;Lm;0;L;<super> AB67;;;;N;;;;;
+107AE;MODIFIER LETTER SMALL TESH DIGRAPH;Lm;0;L;<super> 02A7;;;;N;;;;;
+107AF;MODIFIER LETTER SMALL T WITH RETROFLEX HOOK;Lm;0;L;<super> 0288;;;;N;;;;;
+107B0;MODIFIER LETTER SMALL V WITH RIGHT HOOK;Lm;0;L;<super> 2C71;;;;N;;;;;
+107B2;MODIFIER LETTER SMALL CAPITAL Y;Lm;0;L;<super> 028F;;;;N;;;;;
+107B3;MODIFIER LETTER GLOTTAL STOP WITH STROKE;Lm;0;L;<super> 02A1;;;;N;;;;;
+107B4;MODIFIER LETTER REVERSED GLOTTAL STOP WITH STROKE;Lm;0;L;<super> 02A2;;;;N;;;;;
+107B5;MODIFIER LETTER BILABIAL CLICK;Lm;0;L;<super> 0298;;;;N;;;;;
+107B6;MODIFIER LETTER DENTAL CLICK;Lm;0;L;<super> 01C0;;;;N;;;;;
+107B7;MODIFIER LETTER LATERAL CLICK;Lm;0;L;<super> 01C1;;;;N;;;;;
+107B8;MODIFIER LETTER ALVEOLAR CLICK;Lm;0;L;<super> 01C2;;;;N;;;;;
+107B9;MODIFIER LETTER RETROFLEX CLICK WITH RETROFLEX HOOK;Lm;0;L;<super> 1DF0A;;;;N;;;;;
+107BA;MODIFIER LETTER SMALL S WITH CURL;Lm;0;L;<super> 1DF1E;;;;N;;;;;
10800;CYPRIOT SYLLABLE A;Lo;0;R;;;;;N;;;;;
10801;CYPRIOT SYLLABLE E;Lo;0;R;;;;;N;;;;;
10802;CYPRIOT SYLLABLE I;Lo;0;R;;;;;N;;;;;
@@ -19222,6 +19475,32 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
10F57;SOGDIAN PUNCTUATION CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;;
10F58;SOGDIAN PUNCTUATION TWO CIRCLES WITH DOTS;Po;0;AL;;;;;N;;;;;
10F59;SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;;
+10F70;OLD UYGHUR LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10F71;OLD UYGHUR LETTER BETH;Lo;0;R;;;;;N;;;;;
+10F72;OLD UYGHUR LETTER GIMEL-HETH;Lo;0;R;;;;;N;;;;;
+10F73;OLD UYGHUR LETTER WAW;Lo;0;R;;;;;N;;;;;
+10F74;OLD UYGHUR LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10F75;OLD UYGHUR LETTER FINAL HETH;Lo;0;R;;;;;N;;;;;
+10F76;OLD UYGHUR LETTER YODH;Lo;0;R;;;;;N;;;;;
+10F77;OLD UYGHUR LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10F78;OLD UYGHUR LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10F79;OLD UYGHUR LETTER MEM;Lo;0;R;;;;;N;;;;;
+10F7A;OLD UYGHUR LETTER NUN;Lo;0;R;;;;;N;;;;;
+10F7B;OLD UYGHUR LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10F7C;OLD UYGHUR LETTER PE;Lo;0;R;;;;;N;;;;;
+10F7D;OLD UYGHUR LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10F7E;OLD UYGHUR LETTER RESH;Lo;0;R;;;;;N;;;;;
+10F7F;OLD UYGHUR LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10F80;OLD UYGHUR LETTER TAW;Lo;0;R;;;;;N;;;;;
+10F81;OLD UYGHUR LETTER LESH;Lo;0;R;;;;;N;;;;;
+10F82;OLD UYGHUR COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;;;;;
+10F83;OLD UYGHUR COMBINING DOT BELOW;Mn;220;NSM;;;;;N;;;;;
+10F84;OLD UYGHUR COMBINING TWO DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;
+10F85;OLD UYGHUR COMBINING TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
+10F86;OLD UYGHUR PUNCTUATION BAR;Po;0;R;;;;;N;;;;;
+10F87;OLD UYGHUR PUNCTUATION TWO BARS;Po;0;R;;;;;N;;;;;
+10F88;OLD UYGHUR PUNCTUATION TWO DOTS;Po;0;R;;;;;N;;;;;
+10F89;OLD UYGHUR PUNCTUATION FOUR DOTS;Po;0;R;;;;;N;;;;;
10FB0;CHORASMIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;
10FB1;CHORASMIAN LETTER SMALL ALEPH;Lo;0;R;;;;;N;;;;;
10FB2;CHORASMIAN LETTER BETH;Lo;0;R;;;;;N;;;;;
@@ -19381,6 +19660,12 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1106D;BRAHMI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
1106E;BRAHMI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
1106F;BRAHMI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11070;BRAHMI SIGN OLD TAMIL VIRAMA;Mn;9;NSM;;;;;N;;;;;
+11071;BRAHMI LETTER OLD TAMIL SHORT E;Lo;0;L;;;;;N;;;;;
+11072;BRAHMI LETTER OLD TAMIL SHORT O;Lo;0;L;;;;;N;;;;;
+11073;BRAHMI VOWEL SIGN OLD TAMIL SHORT E;Mn;0;NSM;;;;;N;;;;;
+11074;BRAHMI VOWEL SIGN OLD TAMIL SHORT O;Mn;0;NSM;;;;;N;;;;;
+11075;BRAHMI LETTER OLD TAMIL LLA;Lo;0;L;;;;;N;;;;;
1107F;BRAHMI NUMBER JOINER;Mn;9;NSM;;;;;N;;;;;
11080;KAITHI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
11081;KAITHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
@@ -19448,6 +19733,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
110BF;KAITHI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;;
110C0;KAITHI DANDA;Po;0;L;;;;;N;;;;;
110C1;KAITHI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+110C2;KAITHI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
110CD;KAITHI NUMBER SIGN ABOVE;Cf;0;L;;;;;N;;;;;
110D0;SORA SOMPENG LETTER SAH;Lo;0;L;;;;;N;;;;;
110D1;SORA SOMPENG LETTER TAH;Lo;0;L;;;;;N;;;;;
@@ -20385,6 +20671,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
116B6;TAKRI SIGN VIRAMA;Mc;9;L;;;;;N;;;;;
116B7;TAKRI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
116B8;TAKRI LETTER ARCHAIC KHA;Lo;0;L;;;;;N;;;;;
+116B9;TAKRI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
116C0;TAKRI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
116C1;TAKRI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
116C2;TAKRI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
@@ -20453,6 +20740,13 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1173D;AHOM SIGN SECTION;Po;0;L;;;;;N;;;;;
1173E;AHOM SIGN RULAI;Po;0;L;;;;;N;;;;;
1173F;AHOM SYMBOL VI;So;0;L;;;;;N;;;;;
+11740;AHOM LETTER CA;Lo;0;L;;;;;N;;;;;
+11741;AHOM LETTER TTA;Lo;0;L;;;;;N;;;;;
+11742;AHOM LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11743;AHOM LETTER DDA;Lo;0;L;;;;;N;;;;;
+11744;AHOM LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11745;AHOM LETTER NNA;Lo;0;L;;;;;N;;;;;
+11746;AHOM LETTER LLA;Lo;0;L;;;;;N;;;;;
11800;DOGRA LETTER A;Lo;0;L;;;;;N;;;;;
11801;DOGRA LETTER AA;Lo;0;L;;;;;N;;;;;
11802;DOGRA LETTER I;Lo;0;L;;;;;N;;;;;
@@ -20889,6 +21183,22 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
11AA0;SOYOMBO HEAD MARK WITH MOON AND SUN;Po;0;L;;;;;N;;;;;
11AA1;SOYOMBO TERMINAL MARK-1;Po;0;L;;;;;N;;;;;
11AA2;SOYOMBO TERMINAL MARK-2;Po;0;L;;;;;N;;;;;
+11AB0;CANADIAN SYLLABICS NATTILIK HI;Lo;0;L;;;;;N;;;;;
+11AB1;CANADIAN SYLLABICS NATTILIK HII;Lo;0;L;;;;;N;;;;;
+11AB2;CANADIAN SYLLABICS NATTILIK HO;Lo;0;L;;;;;N;;;;;
+11AB3;CANADIAN SYLLABICS NATTILIK HOO;Lo;0;L;;;;;N;;;;;
+11AB4;CANADIAN SYLLABICS NATTILIK HA;Lo;0;L;;;;;N;;;;;
+11AB5;CANADIAN SYLLABICS NATTILIK HAA;Lo;0;L;;;;;N;;;;;
+11AB6;CANADIAN SYLLABICS NATTILIK SHRI;Lo;0;L;;;;;N;;;;;
+11AB7;CANADIAN SYLLABICS NATTILIK SHRII;Lo;0;L;;;;;N;;;;;
+11AB8;CANADIAN SYLLABICS NATTILIK SHRO;Lo;0;L;;;;;N;;;;;
+11AB9;CANADIAN SYLLABICS NATTILIK SHROO;Lo;0;L;;;;;N;;;;;
+11ABA;CANADIAN SYLLABICS NATTILIK SHRA;Lo;0;L;;;;;N;;;;;
+11ABB;CANADIAN SYLLABICS NATTILIK SHRAA;Lo;0;L;;;;;N;;;;;
+11ABC;CANADIAN SYLLABICS SPE;Lo;0;L;;;;;N;;;;;
+11ABD;CANADIAN SYLLABICS SPI;Lo;0;L;;;;;N;;;;;
+11ABE;CANADIAN SYLLABICS SPO;Lo;0;L;;;;;N;;;;;
+11ABF;CANADIAN SYLLABICS SPA;Lo;0;L;;;;;N;;;;;
11AC0;PAU CIN HAU LETTER PA;Lo;0;L;;;;;N;;;;;
11AC1;PAU CIN HAU LETTER KA;Lo;0;L;;;;;N;;;;;
11AC2;PAU CIN HAU LETTER LA;Lo;0;L;;;;;N;;;;;
@@ -22560,6 +22870,105 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
12541;CUNEIFORM SIGN ZA7;Lo;0;L;;;;;N;;;;;
12542;CUNEIFORM SIGN ZU OVER ZU PLUS SAR;Lo;0;L;;;;;N;;;;;
12543;CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU;Lo;0;L;;;;;N;;;;;
+12F90;CYPRO-MINOAN SIGN CM001;Lo;0;L;;;;;N;;;;;
+12F91;CYPRO-MINOAN SIGN CM002;Lo;0;L;;;;;N;;;;;
+12F92;CYPRO-MINOAN SIGN CM004;Lo;0;L;;;;;N;;;;;
+12F93;CYPRO-MINOAN SIGN CM005;Lo;0;L;;;;;N;;;;;
+12F94;CYPRO-MINOAN SIGN CM006;Lo;0;L;;;;;N;;;;;
+12F95;CYPRO-MINOAN SIGN CM007;Lo;0;L;;;;;N;;;;;
+12F96;CYPRO-MINOAN SIGN CM008;Lo;0;L;;;;;N;;;;;
+12F97;CYPRO-MINOAN SIGN CM009;Lo;0;L;;;;;N;;;;;
+12F98;CYPRO-MINOAN SIGN CM010;Lo;0;L;;;;;N;;;;;
+12F99;CYPRO-MINOAN SIGN CM011;Lo;0;L;;;;;N;;;;;
+12F9A;CYPRO-MINOAN SIGN CM012;Lo;0;L;;;;;N;;;;;
+12F9B;CYPRO-MINOAN SIGN CM012B;Lo;0;L;;;;;N;;;;;
+12F9C;CYPRO-MINOAN SIGN CM013;Lo;0;L;;;;;N;;;;;
+12F9D;CYPRO-MINOAN SIGN CM015;Lo;0;L;;;;;N;;;;;
+12F9E;CYPRO-MINOAN SIGN CM017;Lo;0;L;;;;;N;;;;;
+12F9F;CYPRO-MINOAN SIGN CM019;Lo;0;L;;;;;N;;;;;
+12FA0;CYPRO-MINOAN SIGN CM021;Lo;0;L;;;;;N;;;;;
+12FA1;CYPRO-MINOAN SIGN CM023;Lo;0;L;;;;;N;;;;;
+12FA2;CYPRO-MINOAN SIGN CM024;Lo;0;L;;;;;N;;;;;
+12FA3;CYPRO-MINOAN SIGN CM025;Lo;0;L;;;;;N;;;;;
+12FA4;CYPRO-MINOAN SIGN CM026;Lo;0;L;;;;;N;;;;;
+12FA5;CYPRO-MINOAN SIGN CM027;Lo;0;L;;;;;N;;;;;
+12FA6;CYPRO-MINOAN SIGN CM028;Lo;0;L;;;;;N;;;;;
+12FA7;CYPRO-MINOAN SIGN CM029;Lo;0;L;;;;;N;;;;;
+12FA8;CYPRO-MINOAN SIGN CM030;Lo;0;L;;;;;N;;;;;
+12FA9;CYPRO-MINOAN SIGN CM033;Lo;0;L;;;;;N;;;;;
+12FAA;CYPRO-MINOAN SIGN CM034;Lo;0;L;;;;;N;;;;;
+12FAB;CYPRO-MINOAN SIGN CM035;Lo;0;L;;;;;N;;;;;
+12FAC;CYPRO-MINOAN SIGN CM036;Lo;0;L;;;;;N;;;;;
+12FAD;CYPRO-MINOAN SIGN CM037;Lo;0;L;;;;;N;;;;;
+12FAE;CYPRO-MINOAN SIGN CM038;Lo;0;L;;;;;N;;;;;
+12FAF;CYPRO-MINOAN SIGN CM039;Lo;0;L;;;;;N;;;;;
+12FB0;CYPRO-MINOAN SIGN CM040;Lo;0;L;;;;;N;;;;;
+12FB1;CYPRO-MINOAN SIGN CM041;Lo;0;L;;;;;N;;;;;
+12FB2;CYPRO-MINOAN SIGN CM044;Lo;0;L;;;;;N;;;;;
+12FB3;CYPRO-MINOAN SIGN CM046;Lo;0;L;;;;;N;;;;;
+12FB4;CYPRO-MINOAN SIGN CM047;Lo;0;L;;;;;N;;;;;
+12FB5;CYPRO-MINOAN SIGN CM049;Lo;0;L;;;;;N;;;;;
+12FB6;CYPRO-MINOAN SIGN CM050;Lo;0;L;;;;;N;;;;;
+12FB7;CYPRO-MINOAN SIGN CM051;Lo;0;L;;;;;N;;;;;
+12FB8;CYPRO-MINOAN SIGN CM052;Lo;0;L;;;;;N;;;;;
+12FB9;CYPRO-MINOAN SIGN CM053;Lo;0;L;;;;;N;;;;;
+12FBA;CYPRO-MINOAN SIGN CM054;Lo;0;L;;;;;N;;;;;
+12FBB;CYPRO-MINOAN SIGN CM055;Lo;0;L;;;;;N;;;;;
+12FBC;CYPRO-MINOAN SIGN CM056;Lo;0;L;;;;;N;;;;;
+12FBD;CYPRO-MINOAN SIGN CM058;Lo;0;L;;;;;N;;;;;
+12FBE;CYPRO-MINOAN SIGN CM059;Lo;0;L;;;;;N;;;;;
+12FBF;CYPRO-MINOAN SIGN CM060;Lo;0;L;;;;;N;;;;;
+12FC0;CYPRO-MINOAN SIGN CM061;Lo;0;L;;;;;N;;;;;
+12FC1;CYPRO-MINOAN SIGN CM062;Lo;0;L;;;;;N;;;;;
+12FC2;CYPRO-MINOAN SIGN CM063;Lo;0;L;;;;;N;;;;;
+12FC3;CYPRO-MINOAN SIGN CM064;Lo;0;L;;;;;N;;;;;
+12FC4;CYPRO-MINOAN SIGN CM066;Lo;0;L;;;;;N;;;;;
+12FC5;CYPRO-MINOAN SIGN CM067;Lo;0;L;;;;;N;;;;;
+12FC6;CYPRO-MINOAN SIGN CM068;Lo;0;L;;;;;N;;;;;
+12FC7;CYPRO-MINOAN SIGN CM069;Lo;0;L;;;;;N;;;;;
+12FC8;CYPRO-MINOAN SIGN CM070;Lo;0;L;;;;;N;;;;;
+12FC9;CYPRO-MINOAN SIGN CM071;Lo;0;L;;;;;N;;;;;
+12FCA;CYPRO-MINOAN SIGN CM072;Lo;0;L;;;;;N;;;;;
+12FCB;CYPRO-MINOAN SIGN CM073;Lo;0;L;;;;;N;;;;;
+12FCC;CYPRO-MINOAN SIGN CM074;Lo;0;L;;;;;N;;;;;
+12FCD;CYPRO-MINOAN SIGN CM075;Lo;0;L;;;;;N;;;;;
+12FCE;CYPRO-MINOAN SIGN CM075B;Lo;0;L;;;;;N;;;;;
+12FCF;CYPRO-MINOAN SIGN CM076;Lo;0;L;;;;;N;;;;;
+12FD0;CYPRO-MINOAN SIGN CM078;Lo;0;L;;;;;N;;;;;
+12FD1;CYPRO-MINOAN SIGN CM079;Lo;0;L;;;;;N;;;;;
+12FD2;CYPRO-MINOAN SIGN CM080;Lo;0;L;;;;;N;;;;;
+12FD3;CYPRO-MINOAN SIGN CM081;Lo;0;L;;;;;N;;;;;
+12FD4;CYPRO-MINOAN SIGN CM082;Lo;0;L;;;;;N;;;;;
+12FD5;CYPRO-MINOAN SIGN CM083;Lo;0;L;;;;;N;;;;;
+12FD6;CYPRO-MINOAN SIGN CM084;Lo;0;L;;;;;N;;;;;
+12FD7;CYPRO-MINOAN SIGN CM085;Lo;0;L;;;;;N;;;;;
+12FD8;CYPRO-MINOAN SIGN CM086;Lo;0;L;;;;;N;;;;;
+12FD9;CYPRO-MINOAN SIGN CM087;Lo;0;L;;;;;N;;;;;
+12FDA;CYPRO-MINOAN SIGN CM088;Lo;0;L;;;;;N;;;;;
+12FDB;CYPRO-MINOAN SIGN CM089;Lo;0;L;;;;;N;;;;;
+12FDC;CYPRO-MINOAN SIGN CM090;Lo;0;L;;;;;N;;;;;
+12FDD;CYPRO-MINOAN SIGN CM091;Lo;0;L;;;;;N;;;;;
+12FDE;CYPRO-MINOAN SIGN CM092;Lo;0;L;;;;;N;;;;;
+12FDF;CYPRO-MINOAN SIGN CM094;Lo;0;L;;;;;N;;;;;
+12FE0;CYPRO-MINOAN SIGN CM095;Lo;0;L;;;;;N;;;;;
+12FE1;CYPRO-MINOAN SIGN CM096;Lo;0;L;;;;;N;;;;;
+12FE2;CYPRO-MINOAN SIGN CM097;Lo;0;L;;;;;N;;;;;
+12FE3;CYPRO-MINOAN SIGN CM098;Lo;0;L;;;;;N;;;;;
+12FE4;CYPRO-MINOAN SIGN CM099;Lo;0;L;;;;;N;;;;;
+12FE5;CYPRO-MINOAN SIGN CM100;Lo;0;L;;;;;N;;;;;
+12FE6;CYPRO-MINOAN SIGN CM101;Lo;0;L;;;;;N;;;;;
+12FE7;CYPRO-MINOAN SIGN CM102;Lo;0;L;;;;;N;;;;;
+12FE8;CYPRO-MINOAN SIGN CM103;Lo;0;L;;;;;N;;;;;
+12FE9;CYPRO-MINOAN SIGN CM104;Lo;0;L;;;;;N;;;;;
+12FEA;CYPRO-MINOAN SIGN CM105;Lo;0;L;;;;;N;;;;;
+12FEB;CYPRO-MINOAN SIGN CM107;Lo;0;L;;;;;N;;;;;
+12FEC;CYPRO-MINOAN SIGN CM108;Lo;0;L;;;;;N;;;;;
+12FED;CYPRO-MINOAN SIGN CM109;Lo;0;L;;;;;N;;;;;
+12FEE;CYPRO-MINOAN SIGN CM110;Lo;0;L;;;;;N;;;;;
+12FEF;CYPRO-MINOAN SIGN CM112;Lo;0;L;;;;;N;;;;;
+12FF0;CYPRO-MINOAN SIGN CM114;Lo;0;L;;;;;N;;;;;
+12FF1;CYPRO-MINOAN SIGN CM301;Po;0;L;;;;;N;;;;;
+12FF2;CYPRO-MINOAN SIGN CM302;Po;0;L;;;;;N;;;;;
13000;EGYPTIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;;
13001;EGYPTIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;;
13002;EGYPTIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;;
@@ -24835,6 +25244,95 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
16A69;MRO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
16A6E;MRO DANDA;Po;0;L;;;;;N;;;;;
16A6F;MRO DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+16A70;TANGSA LETTER OZ;Lo;0;L;;;;;N;;;;;
+16A71;TANGSA LETTER OC;Lo;0;L;;;;;N;;;;;
+16A72;TANGSA LETTER OQ;Lo;0;L;;;;;N;;;;;
+16A73;TANGSA LETTER OX;Lo;0;L;;;;;N;;;;;
+16A74;TANGSA LETTER AZ;Lo;0;L;;;;;N;;;;;
+16A75;TANGSA LETTER AC;Lo;0;L;;;;;N;;;;;
+16A76;TANGSA LETTER AQ;Lo;0;L;;;;;N;;;;;
+16A77;TANGSA LETTER AX;Lo;0;L;;;;;N;;;;;
+16A78;TANGSA LETTER VZ;Lo;0;L;;;;;N;;;;;
+16A79;TANGSA LETTER VC;Lo;0;L;;;;;N;;;;;
+16A7A;TANGSA LETTER VQ;Lo;0;L;;;;;N;;;;;
+16A7B;TANGSA LETTER VX;Lo;0;L;;;;;N;;;;;
+16A7C;TANGSA LETTER EZ;Lo;0;L;;;;;N;;;;;
+16A7D;TANGSA LETTER EC;Lo;0;L;;;;;N;;;;;
+16A7E;TANGSA LETTER EQ;Lo;0;L;;;;;N;;;;;
+16A7F;TANGSA LETTER EX;Lo;0;L;;;;;N;;;;;
+16A80;TANGSA LETTER IZ;Lo;0;L;;;;;N;;;;;
+16A81;TANGSA LETTER IC;Lo;0;L;;;;;N;;;;;
+16A82;TANGSA LETTER IQ;Lo;0;L;;;;;N;;;;;
+16A83;TANGSA LETTER IX;Lo;0;L;;;;;N;;;;;
+16A84;TANGSA LETTER UZ;Lo;0;L;;;;;N;;;;;
+16A85;TANGSA LETTER UC;Lo;0;L;;;;;N;;;;;
+16A86;TANGSA LETTER UQ;Lo;0;L;;;;;N;;;;;
+16A87;TANGSA LETTER UX;Lo;0;L;;;;;N;;;;;
+16A88;TANGSA LETTER AWZ;Lo;0;L;;;;;N;;;;;
+16A89;TANGSA LETTER AWC;Lo;0;L;;;;;N;;;;;
+16A8A;TANGSA LETTER AWQ;Lo;0;L;;;;;N;;;;;
+16A8B;TANGSA LETTER AWX;Lo;0;L;;;;;N;;;;;
+16A8C;TANGSA LETTER UIZ;Lo;0;L;;;;;N;;;;;
+16A8D;TANGSA LETTER UIC;Lo;0;L;;;;;N;;;;;
+16A8E;TANGSA LETTER UIQ;Lo;0;L;;;;;N;;;;;
+16A8F;TANGSA LETTER UIX;Lo;0;L;;;;;N;;;;;
+16A90;TANGSA LETTER FINAL NG;Lo;0;L;;;;;N;;;;;
+16A91;TANGSA LETTER LONG UEX;Lo;0;L;;;;;N;;;;;
+16A92;TANGSA LETTER SHORT UEZ;Lo;0;L;;;;;N;;;;;
+16A93;TANGSA LETTER SHORT AWX;Lo;0;L;;;;;N;;;;;
+16A94;TANGSA LETTER UEC;Lo;0;L;;;;;N;;;;;
+16A95;TANGSA LETTER UEZ;Lo;0;L;;;;;N;;;;;
+16A96;TANGSA LETTER UEQ;Lo;0;L;;;;;N;;;;;
+16A97;TANGSA LETTER UEX;Lo;0;L;;;;;N;;;;;
+16A98;TANGSA LETTER UIUZ;Lo;0;L;;;;;N;;;;;
+16A99;TANGSA LETTER UIUC;Lo;0;L;;;;;N;;;;;
+16A9A;TANGSA LETTER UIUQ;Lo;0;L;;;;;N;;;;;
+16A9B;TANGSA LETTER UIUX;Lo;0;L;;;;;N;;;;;
+16A9C;TANGSA LETTER MZ;Lo;0;L;;;;;N;;;;;
+16A9D;TANGSA LETTER MC;Lo;0;L;;;;;N;;;;;
+16A9E;TANGSA LETTER MQ;Lo;0;L;;;;;N;;;;;
+16A9F;TANGSA LETTER MX;Lo;0;L;;;;;N;;;;;
+16AA0;TANGSA LETTER KA;Lo;0;L;;;;;N;;;;;
+16AA1;TANGSA LETTER KHA;Lo;0;L;;;;;N;;;;;
+16AA2;TANGSA LETTER GA;Lo;0;L;;;;;N;;;;;
+16AA3;TANGSA LETTER NGA;Lo;0;L;;;;;N;;;;;
+16AA4;TANGSA LETTER SA;Lo;0;L;;;;;N;;;;;
+16AA5;TANGSA LETTER YA;Lo;0;L;;;;;N;;;;;
+16AA6;TANGSA LETTER WA;Lo;0;L;;;;;N;;;;;
+16AA7;TANGSA LETTER PA;Lo;0;L;;;;;N;;;;;
+16AA8;TANGSA LETTER NYA;Lo;0;L;;;;;N;;;;;
+16AA9;TANGSA LETTER PHA;Lo;0;L;;;;;N;;;;;
+16AAA;TANGSA LETTER BA;Lo;0;L;;;;;N;;;;;
+16AAB;TANGSA LETTER MA;Lo;0;L;;;;;N;;;;;
+16AAC;TANGSA LETTER NA;Lo;0;L;;;;;N;;;;;
+16AAD;TANGSA LETTER HA;Lo;0;L;;;;;N;;;;;
+16AAE;TANGSA LETTER LA;Lo;0;L;;;;;N;;;;;
+16AAF;TANGSA LETTER HTA;Lo;0;L;;;;;N;;;;;
+16AB0;TANGSA LETTER TA;Lo;0;L;;;;;N;;;;;
+16AB1;TANGSA LETTER DA;Lo;0;L;;;;;N;;;;;
+16AB2;TANGSA LETTER RA;Lo;0;L;;;;;N;;;;;
+16AB3;TANGSA LETTER NHA;Lo;0;L;;;;;N;;;;;
+16AB4;TANGSA LETTER SHA;Lo;0;L;;;;;N;;;;;
+16AB5;TANGSA LETTER CA;Lo;0;L;;;;;N;;;;;
+16AB6;TANGSA LETTER TSA;Lo;0;L;;;;;N;;;;;
+16AB7;TANGSA LETTER GHA;Lo;0;L;;;;;N;;;;;
+16AB8;TANGSA LETTER HTTA;Lo;0;L;;;;;N;;;;;
+16AB9;TANGSA LETTER THA;Lo;0;L;;;;;N;;;;;
+16ABA;TANGSA LETTER XA;Lo;0;L;;;;;N;;;;;
+16ABB;TANGSA LETTER FA;Lo;0;L;;;;;N;;;;;
+16ABC;TANGSA LETTER DHA;Lo;0;L;;;;;N;;;;;
+16ABD;TANGSA LETTER CHA;Lo;0;L;;;;;N;;;;;
+16ABE;TANGSA LETTER ZA;Lo;0;L;;;;;N;;;;;
+16AC0;TANGSA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+16AC1;TANGSA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+16AC2;TANGSA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+16AC3;TANGSA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+16AC4;TANGSA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+16AC5;TANGSA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+16AC6;TANGSA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+16AC7;TANGSA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+16AC8;TANGSA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+16AC9;TANGSA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
16AD0;BASSA VAH LETTER ENNI;Lo;0;L;;;;;N;;;;;
16AD1;BASSA VAH LETTER KA;Lo;0;L;;;;;N;;;;;
16AD2;BASSA VAH LETTER SE;Lo;0;L;;;;;N;;;;;
@@ -26487,6 +26985,19 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
18CD5;KHITAN SMALL SCRIPT CHARACTER-18CD5;Lo;0;L;;;;;N;;;;;
18D00;<Tangut Ideograph Supplement, First>;Lo;0;L;;;;;N;;;;;
18D08;<Tangut Ideograph Supplement, Last>;Lo;0;L;;;;;N;;;;;
+1AFF0;KATAKANA LETTER MINNAN TONE-2;Lm;0;L;;;;;N;;;;;
+1AFF1;KATAKANA LETTER MINNAN TONE-3;Lm;0;L;;;;;N;;;;;
+1AFF2;KATAKANA LETTER MINNAN TONE-4;Lm;0;L;;;;;N;;;;;
+1AFF3;KATAKANA LETTER MINNAN TONE-5;Lm;0;L;;;;;N;;;;;
+1AFF5;KATAKANA LETTER MINNAN TONE-7;Lm;0;L;;;;;N;;;;;
+1AFF6;KATAKANA LETTER MINNAN TONE-8;Lm;0;L;;;;;N;;;;;
+1AFF7;KATAKANA LETTER MINNAN NASALIZED TONE-1;Lm;0;L;;;;;N;;;;;
+1AFF8;KATAKANA LETTER MINNAN NASALIZED TONE-2;Lm;0;L;;;;;N;;;;;
+1AFF9;KATAKANA LETTER MINNAN NASALIZED TONE-3;Lm;0;L;;;;;N;;;;;
+1AFFA;KATAKANA LETTER MINNAN NASALIZED TONE-4;Lm;0;L;;;;;N;;;;;
+1AFFB;KATAKANA LETTER MINNAN NASALIZED TONE-5;Lm;0;L;;;;;N;;;;;
+1AFFD;KATAKANA LETTER MINNAN NASALIZED TONE-7;Lm;0;L;;;;;N;;;;;
+1AFFE;KATAKANA LETTER MINNAN NASALIZED TONE-8;Lm;0;L;;;;;N;;;;;
1B000;KATAKANA LETTER ARCHAIC E;Lo;0;L;;;;;N;;;;;
1B001;HIRAGANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;;
1B002;HENTAIGANA LETTER A-1;Lo;0;L;;;;;N;;;;;
@@ -26774,6 +27285,10 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1B11C;HENTAIGANA LETTER WO-7;Lo;0;L;;;;;N;;;;;
1B11D;HENTAIGANA LETTER N-MU-MO-1;Lo;0;L;;;;;N;;;;;
1B11E;HENTAIGANA LETTER N-MU-MO-2;Lo;0;L;;;;;N;;;;;
+1B11F;HIRAGANA LETTER ARCHAIC WU;Lo;0;L;;;;;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;;;;;
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;;;;;
@@ -27324,6 +27839,191 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1BCA1;SHORTHAND FORMAT CONTINUING OVERLAP;Cf;0;BN;;;;;N;;;;;
1BCA2;SHORTHAND FORMAT DOWN STEP;Cf;0;BN;;;;;N;;;;;
1BCA3;SHORTHAND FORMAT UP STEP;Cf;0;BN;;;;;N;;;;;
+1CF00;ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF01;ZNAMENNY COMBINING MARK NIZKO S KRYZHEM ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF02;ZNAMENNY COMBINING MARK TSATA ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF03;ZNAMENNY COMBINING MARK GORAZDO NIZKO ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF04;ZNAMENNY COMBINING MARK NIZKO ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF05;ZNAMENNY COMBINING MARK SREDNE ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF06;ZNAMENNY COMBINING MARK MALO POVYSHE ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF07;ZNAMENNY COMBINING MARK POVYSHE ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF08;ZNAMENNY COMBINING MARK VYSOKO ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF09;ZNAMENNY COMBINING MARK MALO POVYSHE S KHOKHLOM ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF0A;ZNAMENNY COMBINING MARK POVYSHE S KHOKHLOM ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF0B;ZNAMENNY COMBINING MARK VYSOKO S KHOKHLOM ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF0C;ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF0D;ZNAMENNY COMBINING MARK NIZKO S KRYZHEM ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF0E;ZNAMENNY COMBINING MARK TSATA ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF0F;ZNAMENNY COMBINING MARK GORAZDO NIZKO ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF10;ZNAMENNY COMBINING MARK NIZKO ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF11;ZNAMENNY COMBINING MARK SREDNE ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF12;ZNAMENNY COMBINING MARK MALO POVYSHE ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF13;ZNAMENNY COMBINING MARK POVYSHE ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF14;ZNAMENNY COMBINING MARK VYSOKO ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF15;ZNAMENNY COMBINING MARK MALO POVYSHE S KHOKHLOM ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF16;ZNAMENNY COMBINING MARK POVYSHE S KHOKHLOM ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF17;ZNAMENNY COMBINING MARK VYSOKO S KHOKHLOM ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF18;ZNAMENNY COMBINING MARK TSATA S KRYZHEM;Mn;0;NSM;;;;;N;;;;;
+1CF19;ZNAMENNY COMBINING MARK MALO POVYSHE S KRYZHEM;Mn;0;NSM;;;;;N;;;;;
+1CF1A;ZNAMENNY COMBINING MARK STRANNO MALO POVYSHE;Mn;0;NSM;;;;;N;;;;;
+1CF1B;ZNAMENNY COMBINING MARK POVYSHE S KRYZHEM;Mn;0;NSM;;;;;N;;;;;
+1CF1C;ZNAMENNY COMBINING MARK POVYSHE STRANNO;Mn;0;NSM;;;;;N;;;;;
+1CF1D;ZNAMENNY COMBINING MARK VYSOKO S KRYZHEM;Mn;0;NSM;;;;;N;;;;;
+1CF1E;ZNAMENNY COMBINING MARK MALO POVYSHE STRANNO;Mn;0;NSM;;;;;N;;;;;
+1CF1F;ZNAMENNY COMBINING MARK GORAZDO VYSOKO;Mn;0;NSM;;;;;N;;;;;
+1CF20;ZNAMENNY COMBINING MARK ZELO;Mn;0;NSM;;;;;N;;;;;
+1CF21;ZNAMENNY COMBINING MARK ON;Mn;0;NSM;;;;;N;;;;;
+1CF22;ZNAMENNY COMBINING MARK RAVNO;Mn;0;NSM;;;;;N;;;;;
+1CF23;ZNAMENNY COMBINING MARK TIKHAYA;Mn;0;NSM;;;;;N;;;;;
+1CF24;ZNAMENNY COMBINING MARK BORZAYA;Mn;0;NSM;;;;;N;;;;;
+1CF25;ZNAMENNY COMBINING MARK UDARKA;Mn;0;NSM;;;;;N;;;;;
+1CF26;ZNAMENNY COMBINING MARK PODVERTKA;Mn;0;NSM;;;;;N;;;;;
+1CF27;ZNAMENNY COMBINING MARK LOMKA;Mn;0;NSM;;;;;N;;;;;
+1CF28;ZNAMENNY COMBINING MARK KUPNAYA;Mn;0;NSM;;;;;N;;;;;
+1CF29;ZNAMENNY COMBINING MARK KACHKA;Mn;0;NSM;;;;;N;;;;;
+1CF2A;ZNAMENNY COMBINING MARK ZEVOK;Mn;0;NSM;;;;;N;;;;;
+1CF2B;ZNAMENNY COMBINING MARK SKOBA;Mn;0;NSM;;;;;N;;;;;
+1CF2C;ZNAMENNY COMBINING MARK RAZSEKA;Mn;0;NSM;;;;;N;;;;;
+1CF2D;ZNAMENNY COMBINING MARK KRYZH ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF30;ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO;Mn;0;NSM;;;;;N;;;;;
+1CF31;ZNAMENNY COMBINING TONAL RANGE MARK SVETLO;Mn;0;NSM;;;;;N;;;;;
+1CF32;ZNAMENNY COMBINING TONAL RANGE MARK TRESVETLO;Mn;0;NSM;;;;;N;;;;;
+1CF33;ZNAMENNY COMBINING MARK ZADERZHKA;Mn;0;NSM;;;;;N;;;;;
+1CF34;ZNAMENNY COMBINING MARK DEMESTVENNY ZADERZHKA;Mn;0;NSM;;;;;N;;;;;
+1CF35;ZNAMENNY COMBINING MARK OTSECHKA;Mn;0;NSM;;;;;N;;;;;
+1CF36;ZNAMENNY COMBINING MARK PODCHASHIE;Mn;0;NSM;;;;;N;;;;;
+1CF37;ZNAMENNY COMBINING MARK PODCHASHIE WITH VERTICAL STROKE;Mn;0;NSM;;;;;N;;;;;
+1CF38;ZNAMENNY COMBINING MARK CHASHKA;Mn;0;NSM;;;;;N;;;;;
+1CF39;ZNAMENNY COMBINING MARK CHASHKA POLNAYA;Mn;0;NSM;;;;;N;;;;;
+1CF3A;ZNAMENNY COMBINING MARK OBLACHKO;Mn;0;NSM;;;;;N;;;;;
+1CF3B;ZNAMENNY COMBINING MARK SOROCHYA NOZHKA;Mn;0;NSM;;;;;N;;;;;
+1CF3C;ZNAMENNY COMBINING MARK TOCHKA;Mn;0;NSM;;;;;N;;;;;
+1CF3D;ZNAMENNY COMBINING MARK DVOETOCHIE;Mn;0;NSM;;;;;N;;;;;
+1CF3E;ZNAMENNY COMBINING ATTACHING VERTICAL OMET;Mn;0;NSM;;;;;N;;;;;
+1CF3F;ZNAMENNY COMBINING MARK CURVED OMET;Mn;0;NSM;;;;;N;;;;;
+1CF40;ZNAMENNY COMBINING MARK KRYZH;Mn;0;NSM;;;;;N;;;;;
+1CF41;ZNAMENNY COMBINING LOWER TONAL RANGE INDICATOR;Mn;0;NSM;;;;;N;;;;;
+1CF42;ZNAMENNY PRIZNAK MODIFIER LEVEL-2;Mn;0;NSM;;;;;N;;;;;
+1CF43;ZNAMENNY PRIZNAK MODIFIER LEVEL-3;Mn;0;NSM;;;;;N;;;;;
+1CF44;ZNAMENNY PRIZNAK MODIFIER DIRECTION FLIP;Mn;0;NSM;;;;;N;;;;;
+1CF45;ZNAMENNY PRIZNAK MODIFIER KRYZH;Mn;0;NSM;;;;;N;;;;;
+1CF46;ZNAMENNY PRIZNAK MODIFIER ROG;Mn;0;NSM;;;;;N;;;;;
+1CF50;ZNAMENNY NEUME KRYUK;So;0;L;;;;;N;;;;;
+1CF51;ZNAMENNY NEUME KRYUK TIKHY;So;0;L;;;;;N;;;;;
+1CF52;ZNAMENNY NEUME PARAKLIT;So;0;L;;;;;N;;;;;
+1CF53;ZNAMENNY NEUME DVA V CHELNU;So;0;L;;;;;N;;;;;
+1CF54;ZNAMENNY NEUME KLYUCH;So;0;L;;;;;N;;;;;
+1CF55;ZNAMENNY NEUME ZANOZHEK;So;0;L;;;;;N;;;;;
+1CF56;ZNAMENNY NEUME STOPITSA;So;0;L;;;;;N;;;;;
+1CF57;ZNAMENNY NEUME STOPITSA S OCHKOM;So;0;L;;;;;N;;;;;
+1CF58;ZNAMENNY NEUME PEREVODKA;So;0;L;;;;;N;;;;;
+1CF59;ZNAMENNY NEUME PEREVODKA NEPOSTOYANNAYA;So;0;L;;;;;N;;;;;
+1CF5A;ZNAMENNY NEUME STOPITSA WITH SOROCHYA NOZHKA;So;0;L;;;;;N;;;;;
+1CF5B;ZNAMENNY NEUME CHELYUSTKA;So;0;L;;;;;N;;;;;
+1CF5C;ZNAMENNY NEUME PALKA;So;0;L;;;;;N;;;;;
+1CF5D;ZNAMENNY NEUME ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CF5E;ZNAMENNY NEUME GOLUBCHIK BORZY;So;0;L;;;;;N;;;;;
+1CF5F;ZNAMENNY NEUME GOLUBCHIK TIKHY;So;0;L;;;;;N;;;;;
+1CF60;ZNAMENNY NEUME GOLUBCHIK MRACHNY;So;0;L;;;;;N;;;;;
+1CF61;ZNAMENNY NEUME GOLUBCHIK SVETLY;So;0;L;;;;;N;;;;;
+1CF62;ZNAMENNY NEUME GOLUBCHIK TRESVETLY;So;0;L;;;;;N;;;;;
+1CF63;ZNAMENNY NEUME VRAKHIYA PROSTAYA;So;0;L;;;;;N;;;;;
+1CF64;ZNAMENNY NEUME VRAKHIYA MRACHNAYA;So;0;L;;;;;N;;;;;
+1CF65;ZNAMENNY NEUME VRAKHIYA SVETLAYA;So;0;L;;;;;N;;;;;
+1CF66;ZNAMENNY NEUME VRAKHIYA TRESVETLAYA;So;0;L;;;;;N;;;;;
+1CF67;ZNAMENNY NEUME VRAKHIYA KLYUCHEVAYA PROSTAYA;So;0;L;;;;;N;;;;;
+1CF68;ZNAMENNY NEUME VRAKHIYA KLYUCHEVAYA MRACHNAYA;So;0;L;;;;;N;;;;;
+1CF69;ZNAMENNY NEUME VRAKHIYA KLYUCHEVAYA SVETLAYA;So;0;L;;;;;N;;;;;
+1CF6A;ZNAMENNY NEUME VRAKHIYA KLYUCHEVAYA TRESVETLAYA;So;0;L;;;;;N;;;;;
+1CF6B;ZNAMENNY NEUME DOUBLE ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CF6C;ZNAMENNY NEUME REVERSED CHELYUSTKA;So;0;L;;;;;N;;;;;
+1CF6D;ZNAMENNY NEUME DERBITSA;So;0;L;;;;;N;;;;;
+1CF6E;ZNAMENNY NEUME KHAMILO;So;0;L;;;;;N;;;;;
+1CF6F;ZNAMENNY NEUME CHASHKA;So;0;L;;;;;N;;;;;
+1CF70;ZNAMENNY NEUME PODCHASHIE;So;0;L;;;;;N;;;;;
+1CF71;ZNAMENNY NEUME SKAMEYTSA MRACHNAYA;So;0;L;;;;;N;;;;;
+1CF72;ZNAMENNY NEUME SKAMEYTSA SVETLAYA;So;0;L;;;;;N;;;;;
+1CF73;ZNAMENNY NEUME SKAMEYTSA TRESVETLAYA;So;0;L;;;;;N;;;;;
+1CF74;ZNAMENNY NEUME SKAMEYTSA TIKHAYA;So;0;L;;;;;N;;;;;
+1CF75;ZNAMENNY NEUME DEMESTVENNY KLYUCH;So;0;L;;;;;N;;;;;
+1CF76;ZNAMENNY NEUME SKAMEYTSA KLYUCHEVAYA SVETLAYA;So;0;L;;;;;N;;;;;
+1CF77;ZNAMENNY NEUME SKAMEYTSA KLYUCHENEPOSTOYANNAYA;So;0;L;;;;;N;;;;;
+1CF78;ZNAMENNY NEUME SKAMEYTSA KLYUCHEVAYA TIKHAYA;So;0;L;;;;;N;;;;;
+1CF79;ZNAMENNY NEUME SKAMEYTSA DVOECHELNAYA PROSTAYA;So;0;L;;;;;N;;;;;
+1CF7A;ZNAMENNY NEUME SKAMEYTSA DVOECHELNAYA SVETLAYA;So;0;L;;;;;N;;;;;
+1CF7B;ZNAMENNY NEUME SKAMEYTSA DVOECHELNAYA NEPOSTOYANNAYA;So;0;L;;;;;N;;;;;
+1CF7C;ZNAMENNY NEUME SKAMEYTSA DVOECHELNAYA KLYUCHEVAYA;So;0;L;;;;;N;;;;;
+1CF7D;ZNAMENNY NEUME SLOZHITIE;So;0;L;;;;;N;;;;;
+1CF7E;ZNAMENNY NEUME SLOZHITIE S ZAPYATOY;So;0;L;;;;;N;;;;;
+1CF7F;ZNAMENNY NEUME SLOZHITIE ZAKRYTOE;So;0;L;;;;;N;;;;;
+1CF80;ZNAMENNY NEUME SLOZHITIE S KRYZHEM;So;0;L;;;;;N;;;;;
+1CF81;ZNAMENNY NEUME KRYZH;So;0;L;;;;;N;;;;;
+1CF82;ZNAMENNY NEUME ROG;So;0;L;;;;;N;;;;;
+1CF83;ZNAMENNY NEUME FITA;So;0;L;;;;;N;;;;;
+1CF84;ZNAMENNY NEUME KOBYLA;So;0;L;;;;;N;;;;;
+1CF85;ZNAMENNY NEUME ZMEYTSA;So;0;L;;;;;N;;;;;
+1CF86;ZNAMENNY NEUME STATYA;So;0;L;;;;;N;;;;;
+1CF87;ZNAMENNY NEUME STATYA S ZAPYATOY;So;0;L;;;;;N;;;;;
+1CF88;ZNAMENNY NEUME STATYA S KRYZHEM;So;0;L;;;;;N;;;;;
+1CF89;ZNAMENNY NEUME STATYA S ZAPYATOY I KRYZHEM;So;0;L;;;;;N;;;;;
+1CF8A;ZNAMENNY NEUME STATYA S KRYZHEM I ZAPYATOY;So;0;L;;;;;N;;;;;
+1CF8B;ZNAMENNY NEUME STATYA ZAKRYTAYA;So;0;L;;;;;N;;;;;
+1CF8C;ZNAMENNY NEUME STATYA ZAKRYTAYA S ZAPYATOY;So;0;L;;;;;N;;;;;
+1CF8D;ZNAMENNY NEUME STATYA S ROGOM;So;0;L;;;;;N;;;;;
+1CF8E;ZNAMENNY NEUME STATYA S DVUMYA ZAPYATYMI;So;0;L;;;;;N;;;;;
+1CF8F;ZNAMENNY NEUME STATYA S ZAPYATOY I PODCHASHIEM;So;0;L;;;;;N;;;;;
+1CF90;ZNAMENNY NEUME POLKULIZMY;So;0;L;;;;;N;;;;;
+1CF91;ZNAMENNY NEUME STATYA NEPOSTOYANNAYA;So;0;L;;;;;N;;;;;
+1CF92;ZNAMENNY NEUME STRELA PROSTAYA;So;0;L;;;;;N;;;;;
+1CF93;ZNAMENNY NEUME STRELA MRACHNOTIKHAYA;So;0;L;;;;;N;;;;;
+1CF94;ZNAMENNY NEUME STRELA KRYZHEVAYA;So;0;L;;;;;N;;;;;
+1CF95;ZNAMENNY NEUME STRELA POLUPOVODNAYA;So;0;L;;;;;N;;;;;
+1CF96;ZNAMENNY NEUME STRELA POVODNAYA;So;0;L;;;;;N;;;;;
+1CF97;ZNAMENNY NEUME STRELA NEPOSTOYANNAYA;So;0;L;;;;;N;;;;;
+1CF98;ZNAMENNY NEUME STRELA KLYUCHEPOVODNAYA;So;0;L;;;;;N;;;;;
+1CF99;ZNAMENNY NEUME STRELA KLYUCHENEPOSTOYANNAYA;So;0;L;;;;;N;;;;;
+1CF9A;ZNAMENNY NEUME STRELA TIKHAYA PUTNAYA;So;0;L;;;;;N;;;;;
+1CF9B;ZNAMENNY NEUME STRELA DVOECHELNAYA;So;0;L;;;;;N;;;;;
+1CF9C;ZNAMENNY NEUME STRELA DVOECHELNOKRYZHEVAYA;So;0;L;;;;;N;;;;;
+1CF9D;ZNAMENNY NEUME STRELA DVOECHELNOPOVODNAYA;So;0;L;;;;;N;;;;;
+1CF9E;ZNAMENNY NEUME STRELA DVOECHELNAYA KLYUCHEVAYA;So;0;L;;;;;N;;;;;
+1CF9F;ZNAMENNY NEUME STRELA DVOECHELNOPOVODNAYA KLYUCHEVAYA;So;0;L;;;;;N;;;;;
+1CFA0;ZNAMENNY NEUME STRELA GROMNAYA WITH SINGLE ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CFA1;ZNAMENNY NEUME STRELA GROMOPOVODNAYA WITH SINGLE ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CFA2;ZNAMENNY NEUME STRELA GROMNAYA;So;0;L;;;;;N;;;;;
+1CFA3;ZNAMENNY NEUME STRELA GROMOPOVODNAYA;So;0;L;;;;;N;;;;;
+1CFA4;ZNAMENNY NEUME STRELA GROMOPOVODNAYA WITH DOUBLE ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CFA5;ZNAMENNY NEUME STRELA GROMOKRYZHEVAYA;So;0;L;;;;;N;;;;;
+1CFA6;ZNAMENNY NEUME STRELA GROMOKRYZHEVAYA POVODNAYA;So;0;L;;;;;N;;;;;
+1CFA7;ZNAMENNY NEUME MECHIK;So;0;L;;;;;N;;;;;
+1CFA8;ZNAMENNY NEUME MECHIK POVODNY;So;0;L;;;;;N;;;;;
+1CFA9;ZNAMENNY NEUME MECHIK KLYUCHEVOY;So;0;L;;;;;N;;;;;
+1CFAA;ZNAMENNY NEUME MECHIK KLYUCHEPOVODNY;So;0;L;;;;;N;;;;;
+1CFAB;ZNAMENNY NEUME MECHIK KLYUCHENEPOSTOYANNY;So;0;L;;;;;N;;;;;
+1CFAC;ZNAMENNY NEUME STRELA TRYASOGLASNAYA;So;0;L;;;;;N;;;;;
+1CFAD;ZNAMENNY NEUME STRELA TRYASOPOVODNAYA;So;0;L;;;;;N;;;;;
+1CFAE;ZNAMENNY NEUME STRELA TRYASOSTRELNAYA;So;0;L;;;;;N;;;;;
+1CFAF;ZNAMENNY NEUME OSOKA;So;0;L;;;;;N;;;;;
+1CFB0;ZNAMENNY NEUME OSOKA SVETLAYA;So;0;L;;;;;N;;;;;
+1CFB1;ZNAMENNY NEUME OSOKA TRESVETLAYA;So;0;L;;;;;N;;;;;
+1CFB2;ZNAMENNY NEUME OSOKA KRYUKOVAYA SVETLAYA;So;0;L;;;;;N;;;;;
+1CFB3;ZNAMENNY NEUME OSOKA KLYUCHEVAYA SVETLAYA;So;0;L;;;;;N;;;;;
+1CFB4;ZNAMENNY NEUME OSOKA KLYUCHEVAYA NEPOSTOYANNAYA;So;0;L;;;;;N;;;;;
+1CFB5;ZNAMENNY NEUME STRELA KRYUKOVAYA;So;0;L;;;;;N;;;;;
+1CFB6;ZNAMENNY NEUME STRELA KRYUKOVAYA POVODNAYA;So;0;L;;;;;N;;;;;
+1CFB7;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMNAYA WITH SINGLE ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CFB8;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMOPOVODNAYA WITH SINGLE ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CFB9;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMNAYA;So;0;L;;;;;N;;;;;
+1CFBA;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMOPOVODNAYA;So;0;L;;;;;N;;;;;
+1CFBB;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMOPOVODNAYA WITH DOUBLE ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CFBC;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMOKRYZHEVAYA;So;0;L;;;;;N;;;;;
+1CFBD;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMOKRYZHEVAYA POVODNAYA;So;0;L;;;;;N;;;;;
+1CFBE;ZNAMENNY NEUME STRELA KRYUKOVAYA TRYASKA;So;0;L;;;;;N;;;;;
+1CFBF;ZNAMENNY NEUME KUFISMA;So;0;L;;;;;N;;;;;
+1CFC0;ZNAMENNY NEUME OBLAKO;So;0;L;;;;;N;;;;;
+1CFC1;ZNAMENNY NEUME DUDA;So;0;L;;;;;N;;;;;
+1CFC2;ZNAMENNY NEUME NEMKA;So;0;L;;;;;N;;;;;
+1CFC3;ZNAMENNY NEUME PAUK;So;0;L;;;;;N;;;;;
1D000;BYZANTINE MUSICAL SYMBOL PSILI;So;0;L;;;;;N;;;;;
1D001;BYZANTINE MUSICAL SYMBOL DASEIA;So;0;L;;;;;N;;;;;
1D002;BYZANTINE MUSICAL SYMBOL PERISPOMENI;So;0;L;;;;;N;;;;;
@@ -27801,6 +28501,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1D1E6;MUSICAL SYMBOL KIEVAN EIGHTH NOTE STEM DOWN;So;0;L;;;;;N;;;;;
1D1E7;MUSICAL SYMBOL KIEVAN EIGHTH NOTE STEM UP;So;0;L;;;;;N;;;;;
1D1E8;MUSICAL SYMBOL KIEVAN FLAT SIGN;So;0;L;;;;;N;;;;;
+1D1E9;MUSICAL SYMBOL SORI;So;0;ON;;;;;N;;;;;
+1D1EA;MUSICAL SYMBOL KORON;So;0;ON;;;;;N;;;;;
1D200;GREEK VOCAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;;
1D201;GREEK VOCAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;;
1D202;GREEK VOCAL NOTATION SYMBOL-3;So;0;ON;;;;;N;;;;;
@@ -29671,6 +30373,37 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1DAAD;SIGNWRITING ROTATION MODIFIER-14;Mn;0;NSM;;;;;N;;;;;
1DAAE;SIGNWRITING ROTATION MODIFIER-15;Mn;0;NSM;;;;;N;;;;;
1DAAF;SIGNWRITING ROTATION MODIFIER-16;Mn;0;NSM;;;;;N;;;;;
+1DF00;LATIN SMALL LETTER FENG DIGRAPH WITH TRILL;Ll;0;L;;;;;N;;;;;
+1DF01;LATIN SMALL LETTER REVERSED SCRIPT G;Ll;0;L;;;;;N;;;;;
+1DF02;LATIN LETTER SMALL CAPITAL TURNED G;Ll;0;L;;;;;N;;;;;
+1DF03;LATIN SMALL LETTER REVERSED K;Ll;0;L;;;;;N;;;;;
+1DF04;LATIN LETTER SMALL CAPITAL L WITH BELT;Ll;0;L;;;;;N;;;;;
+1DF05;LATIN SMALL LETTER LEZH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1DF06;LATIN SMALL LETTER TURNED Y WITH BELT;Ll;0;L;;;;;N;;;;;
+1DF07;LATIN SMALL LETTER REVERSED ENG;Ll;0;L;;;;;N;;;;;
+1DF08;LATIN SMALL LETTER TURNED R WITH LONG LEG AND RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1DF09;LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1DF0A;LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK;Lo;0;L;;;;;N;;;;;
+1DF0B;LATIN SMALL LETTER ESH WITH DOUBLE BAR;Ll;0;L;;;;;N;;;;;
+1DF0C;LATIN SMALL LETTER ESH WITH DOUBLE BAR AND CURL;Ll;0;L;;;;;N;;;;;
+1DF0D;LATIN SMALL LETTER TURNED T WITH CURL;Ll;0;L;;;;;N;;;;;
+1DF0E;LATIN LETTER INVERTED GLOTTAL STOP WITH CURL;Ll;0;L;;;;;N;;;;;
+1DF0F;LATIN LETTER STRETCHED C WITH CURL;Ll;0;L;;;;;N;;;;;
+1DF10;LATIN LETTER SMALL CAPITAL TURNED K;Ll;0;L;;;;;N;;;;;
+1DF11;LATIN SMALL LETTER L WITH FISHHOOK;Ll;0;L;;;;;N;;;;;
+1DF12;LATIN SMALL LETTER DEZH DIGRAPH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1DF13;LATIN SMALL LETTER L WITH BELT AND PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1DF14;LATIN SMALL LETTER ENG WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1DF15;LATIN SMALL LETTER TURNED R WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1DF16;LATIN SMALL LETTER R WITH FISHHOOK AND PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1DF17;LATIN SMALL LETTER TESH DIGRAPH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1DF18;LATIN SMALL LETTER EZH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1DF19;LATIN SMALL LETTER DEZH DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1DF1A;LATIN SMALL LETTER I WITH STROKE AND RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1DF1B;LATIN SMALL LETTER O WITH RETROFLEX HOOK;Ll;0;L;;;;;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;;;;;
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;;;;;
@@ -29780,6 +30513,37 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1E149;NYIAKENG PUACHUE HMONG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
1E14E;NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ;Lo;0;L;;;;;N;;;;;
1E14F;NYIAKENG PUACHUE HMONG CIRCLED CA;So;0;L;;;;;N;;;;;
+1E290;TOTO LETTER PA;Lo;0;L;;;;;N;;;;;
+1E291;TOTO LETTER BA;Lo;0;L;;;;;N;;;;;
+1E292;TOTO LETTER TA;Lo;0;L;;;;;N;;;;;
+1E293;TOTO LETTER DA;Lo;0;L;;;;;N;;;;;
+1E294;TOTO LETTER KA;Lo;0;L;;;;;N;;;;;
+1E295;TOTO LETTER GA;Lo;0;L;;;;;N;;;;;
+1E296;TOTO LETTER MA;Lo;0;L;;;;;N;;;;;
+1E297;TOTO LETTER NA;Lo;0;L;;;;;N;;;;;
+1E298;TOTO LETTER NGA;Lo;0;L;;;;;N;;;;;
+1E299;TOTO LETTER SA;Lo;0;L;;;;;N;;;;;
+1E29A;TOTO LETTER CHA;Lo;0;L;;;;;N;;;;;
+1E29B;TOTO LETTER YA;Lo;0;L;;;;;N;;;;;
+1E29C;TOTO LETTER WA;Lo;0;L;;;;;N;;;;;
+1E29D;TOTO LETTER JA;Lo;0;L;;;;;N;;;;;
+1E29E;TOTO LETTER HA;Lo;0;L;;;;;N;;;;;
+1E29F;TOTO LETTER RA;Lo;0;L;;;;;N;;;;;
+1E2A0;TOTO LETTER LA;Lo;0;L;;;;;N;;;;;
+1E2A1;TOTO LETTER I;Lo;0;L;;;;;N;;;;;
+1E2A2;TOTO LETTER BREATHY I;Lo;0;L;;;;;N;;;;;
+1E2A3;TOTO LETTER IU;Lo;0;L;;;;;N;;;;;
+1E2A4;TOTO LETTER BREATHY IU;Lo;0;L;;;;;N;;;;;
+1E2A5;TOTO LETTER U;Lo;0;L;;;;;N;;;;;
+1E2A6;TOTO LETTER E;Lo;0;L;;;;;N;;;;;
+1E2A7;TOTO LETTER BREATHY E;Lo;0;L;;;;;N;;;;;
+1E2A8;TOTO LETTER EO;Lo;0;L;;;;;N;;;;;
+1E2A9;TOTO LETTER BREATHY EO;Lo;0;L;;;;;N;;;;;
+1E2AA;TOTO LETTER O;Lo;0;L;;;;;N;;;;;
+1E2AB;TOTO LETTER AE;Lo;0;L;;;;;N;;;;;
+1E2AC;TOTO LETTER BREATHY AE;Lo;0;L;;;;;N;;;;;
+1E2AD;TOTO LETTER A;Lo;0;L;;;;;N;;;;;
+1E2AE;TOTO SIGN RISING TONE;Mn;230;NSM;;;;;N;;;;;
1E2C0;WANCHO LETTER AA;Lo;0;L;;;;;N;;;;;
1E2C1;WANCHO LETTER A;Lo;0;L;;;;;N;;;;;
1E2C2;WANCHO LETTER BA;Lo;0;L;;;;;N;;;;;
@@ -29839,6 +30603,34 @@ 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;;;;;
+1E7E0;ETHIOPIC SYLLABLE HHYA;Lo;0;L;;;;;N;;;;;
+1E7E1;ETHIOPIC SYLLABLE HHYU;Lo;0;L;;;;;N;;;;;
+1E7E2;ETHIOPIC SYLLABLE HHYI;Lo;0;L;;;;;N;;;;;
+1E7E3;ETHIOPIC SYLLABLE HHYAA;Lo;0;L;;;;;N;;;;;
+1E7E4;ETHIOPIC SYLLABLE HHYEE;Lo;0;L;;;;;N;;;;;
+1E7E5;ETHIOPIC SYLLABLE HHYE;Lo;0;L;;;;;N;;;;;
+1E7E6;ETHIOPIC SYLLABLE HHYO;Lo;0;L;;;;;N;;;;;
+1E7E8;ETHIOPIC SYLLABLE GURAGE HHWA;Lo;0;L;;;;;N;;;;;
+1E7E9;ETHIOPIC SYLLABLE HHWI;Lo;0;L;;;;;N;;;;;
+1E7EA;ETHIOPIC SYLLABLE HHWEE;Lo;0;L;;;;;N;;;;;
+1E7EB;ETHIOPIC SYLLABLE HHWE;Lo;0;L;;;;;N;;;;;
+1E7ED;ETHIOPIC SYLLABLE GURAGE MWI;Lo;0;L;;;;;N;;;;;
+1E7EE;ETHIOPIC SYLLABLE GURAGE MWEE;Lo;0;L;;;;;N;;;;;
+1E7F0;ETHIOPIC SYLLABLE GURAGE QWI;Lo;0;L;;;;;N;;;;;
+1E7F1;ETHIOPIC SYLLABLE GURAGE QWEE;Lo;0;L;;;;;N;;;;;
+1E7F2;ETHIOPIC SYLLABLE GURAGE QWE;Lo;0;L;;;;;N;;;;;
+1E7F3;ETHIOPIC SYLLABLE GURAGE BWI;Lo;0;L;;;;;N;;;;;
+1E7F4;ETHIOPIC SYLLABLE GURAGE BWEE;Lo;0;L;;;;;N;;;;;
+1E7F5;ETHIOPIC SYLLABLE GURAGE KWI;Lo;0;L;;;;;N;;;;;
+1E7F6;ETHIOPIC SYLLABLE GURAGE KWEE;Lo;0;L;;;;;N;;;;;
+1E7F7;ETHIOPIC SYLLABLE GURAGE KWE;Lo;0;L;;;;;N;;;;;
+1E7F8;ETHIOPIC SYLLABLE GURAGE GWI;Lo;0;L;;;;;N;;;;;
+1E7F9;ETHIOPIC SYLLABLE GURAGE GWEE;Lo;0;L;;;;;N;;;;;
+1E7FA;ETHIOPIC SYLLABLE GURAGE GWE;Lo;0;L;;;;;N;;;;;
+1E7FB;ETHIOPIC SYLLABLE GURAGE FWI;Lo;0;L;;;;;N;;;;;
+1E7FC;ETHIOPIC SYLLABLE GURAGE FWEE;Lo;0;L;;;;;N;;;;;
+1E7FD;ETHIOPIC SYLLABLE GURAGE PWI;Lo;0;L;;;;;N;;;;;
+1E7FE;ETHIOPIC SYLLABLE GURAGE PWEE;Lo;0;L;;;;;N;;;;;
1E800;MENDE KIKAKUI SYLLABLE M001 KI;Lo;0;R;;;;;N;;;;;
1E801;MENDE KIKAKUI SYLLABLE M002 KA;Lo;0;R;;;;;N;;;;;
1E802;MENDE KIKAKUI SYLLABLE M003 KU;Lo;0;R;;;;;N;;;;;
@@ -31886,6 +32678,9 @@ 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;;;;;
+1F6DD;PLAYGROUND SLIDE;So;0;ON;;;;;N;;;;;
+1F6DE;WHEEL;So;0;ON;;;;;N;;;;;
+1F6DF;RING BUOY;So;0;ON;;;;;N;;;;;
1F6E0;HAMMER AND WRENCH;So;0;ON;;;;;N;;;;;
1F6E1;SHIELD;So;0;ON;;;;;N;;;;;
1F6E2;OIL DRUM;So;0;ON;;;;;N;;;;;
@@ -32129,6 +32924,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F7E9;LARGE GREEN SQUARE;So;0;ON;;;;;N;;;;;
1F7EA;LARGE PURPLE SQUARE;So;0;ON;;;;;N;;;;;
1F7EB;LARGE BROWN SQUARE;So;0;ON;;;;;N;;;;;
+1F7F0;HEAVY EQUALS SIGN;So;0;ON;;;;;N;;;;;
1F800;LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
1F801;UPWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
1F802;RIGHTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
@@ -32400,6 +33196,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F976;FREEZING FACE;So;0;ON;;;;;N;;;;;
1F977;NINJA;So;0;ON;;;;;N;;;;;
1F978;DISGUISED FACE;So;0;ON;;;;;N;;;;;
+1F979;FACE HOLDING BACK TEARS;So;0;ON;;;;;N;;;;;
1F97A;FACE WITH PLEADING EYES;So;0;ON;;;;;N;;;;;
1F97B;SARI;So;0;ON;;;;;N;;;;;
1F97C;LAB COAT;So;0;ON;;;;;N;;;;;
@@ -32482,6 +33279,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F9C9;MATE DRINK;So;0;ON;;;;;N;;;;;
1F9CA;ICE CUBE;So;0;ON;;;;;N;;;;;
1F9CB;BUBBLE TEA;So;0;ON;;;;;N;;;;;
+1F9CC;TROLL;So;0;ON;;;;;N;;;;;
1F9CD;STANDING PERSON;So;0;ON;;;;;N;;;;;
1F9CE;KNEELING PERSON;So;0;ON;;;;;N;;;;;
1F9CF;DEAF PERSON;So;0;ON;;;;;N;;;;;
@@ -32639,6 +33437,8 @@ FFFD;REPLACEMENT CHARACTER;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;;;;;
+1FA7B;X-RAY;So;0;ON;;;;;N;;;;;
+1FA7C;CRUTCH;So;0;ON;;;;;N;;;;;
1FA80;YO-YO;So;0;ON;;;;;N;;;;;
1FA81;KITE;So;0;ON;;;;;N;;;;;
1FA82;PARACHUTE;So;0;ON;;;;;N;;;;;
@@ -32671,6 +33471,10 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FAA6;HEADSTONE;So;0;ON;;;;;N;;;;;
1FAA7;PLACARD;So;0;ON;;;;;N;;;;;
1FAA8;ROCK;So;0;ON;;;;;N;;;;;
+1FAA9;MIRROR BALL;So;0;ON;;;;;N;;;;;
+1FAAA;IDENTIFICATION CARD;So;0;ON;;;;;N;;;;;
+1FAAB;LOW BATTERY;So;0;ON;;;;;N;;;;;
+1FAAC;HAMSA;So;0;ON;;;;;N;;;;;
1FAB0;FLY;So;0;ON;;;;;N;;;;;
1FAB1;WORM;So;0;ON;;;;;N;;;;;
1FAB2;BEETLE;So;0;ON;;;;;N;;;;;
@@ -32678,9 +33482,16 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FAB4;POTTED PLANT;So;0;ON;;;;;N;;;;;
1FAB5;WOOD;So;0;ON;;;;;N;;;;;
1FAB6;FEATHER;So;0;ON;;;;;N;;;;;
+1FAB7;LOTUS;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;;;;;
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;;;;;
1FAD0;BLUEBERRIES;So;0;ON;;;;;N;;;;;
1FAD1;BELL PEPPER;So;0;ON;;;;;N;;;;;
1FAD2;OLIVE;So;0;ON;;;;;N;;;;;
@@ -32688,6 +33499,24 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FAD4;TAMALE;So;0;ON;;;;;N;;;;;
1FAD5;FONDUE;So;0;ON;;;;;N;;;;;
1FAD6;TEAPOT;So;0;ON;;;;;N;;;;;
+1FAD7;POURING LIQUID;So;0;ON;;;;;N;;;;;
+1FAD8;BEANS;So;0;ON;;;;;N;;;;;
+1FAD9;JAR;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;;;;;
+1FAE3;FACE WITH PEEKING EYE;So;0;ON;;;;;N;;;;;
+1FAE4;FACE WITH DIAGONAL MOUTH;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;;;;;
+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;;;;;
+1FAF3;PALM DOWN HAND;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;;;;;
1FB00;BLOCK SEXTANT-1;So;0;ON;;;;;N;;;;;
1FB01;BLOCK SEXTANT-2;So;0;ON;;;;;N;;;;;
1FB02;BLOCK SEXTANT-12;So;0;ON;;;;;N;;;;;
@@ -32901,9 +33730,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FBF8;SEGMENTED DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
1FBF9;SEGMENTED DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
20000;<CJK Ideograph Extension B, First>;Lo;0;L;;;;;N;;;;;
-2A6DD;<CJK Ideograph Extension B, Last>;Lo;0;L;;;;;N;;;;;
+2A6DF;<CJK Ideograph Extension B, Last>;Lo;0;L;;;;;N;;;;;
2A700;<CJK Ideograph Extension C, First>;Lo;0;L;;;;;N;;;;;
-2B734;<CJK Ideograph Extension C, Last>;Lo;0;L;;;;;N;;;;;
+2B738;<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;;;;;
diff --git a/admin/unidata/blocks.awk b/admin/unidata/blocks.awk
index 4ecb233fe7b..314ac3e9394 100755
--- a/admin/unidata/blocks.awk
+++ b/admin/unidata/blocks.awk
@@ -131,7 +131,7 @@ function name2alias(name , w, w2) {
return name
}
-/^[0-9A-F]/ {
+FILENAME ~ "Blocks.txt" && /^[0-9A-F]/ {
sep = index($1, "..")
len = length($1)
s = substr($1,1,sep-1)
@@ -202,9 +202,42 @@ function name2alias(name , w, w2) {
}
}
+FILENAME ~ "emoji-data.txt" && /^[0-9A-F].*; Emoji_Presentation / {
+ sep = index($1, "..")
+ len = length($1)
+ if (sep > 0) {
+ s = substr($1,1,sep-1)
+ e = substr($1,sep+2,len-sep-1)
+ } else {
+ s = $1
+ e = $1
+ }
+ $1 = ""
+ i++
+ start[i] = s
+ end[i] = e
+ alt[i] = "emoji"
+ name[i] = "Autogenerated emoji"
+}
+
END {
+ idx = 0
+ # ## These are here so that font_range can choose Emoji presentation
+ # ## for the preceding codepoint when it encounters a VS
+ override_start[idx] = "FE00"
+ override_end[idx] = "FE0F"
+
+ for (k in override_start)
+ {
+ i++
+ start[i] = override_start[k]
+ end[i] = override_end[k]
+ alt[i] = "emoji"
+ name[i] = "Autogenerated emoji (override)"
+ }
+
print ";;; charscript.el --- character script table -*- lexical-binding:t -*-"
- print ";;; Automatically generated from admin/unidata/Blocks.txt"
+ print ";;; Automatically generated from admin/unidata/{Blocks,emoji-data}.txt"
print "(let (script-list)"
print " (dolist (elt '("
@@ -223,6 +256,6 @@ END {
print " (or (memq (nth 2 elt) script-list)"
print " (setq script-list (cons (nth 2 elt) script-list))))"
print " (set-char-table-extra-slot char-script-table 0 (nreverse script-list)))"
- print ""
+ print "\n"
print "(provide 'charscript)"
}
diff --git a/admin/unidata/copyright.html b/admin/unidata/copyright.html
index 6bbc16b1363..66e54b06fc4 100644
--- a/admin/unidata/copyright.html
+++ b/admin/unidata/copyright.html
@@ -118,7 +118,7 @@ pre {
<ol type="A">
<li><u><a name="1"></a>Unicode Copyright</u>
<ol>
- <li>Copyright © 1991-2020 Unicode, Inc. All rights reserved.</li>
+ <li>Copyright © 1991-2021 Unicode, Inc. All rights reserved.</li>
</ol>
</li>
diff --git a/admin/unidata/emoji-data.txt b/admin/unidata/emoji-data.txt
new file mode 100644
index 00000000000..2e9cf75ad4d
--- /dev/null
+++ b/admin/unidata/emoji-data.txt
@@ -0,0 +1,1297 @@
+# emoji-data-14.0.0.txt
+# Date: 2021-08-26, 17:22:22 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
+#
+# Emoji Data for UTS #51
+# Used with Emoji Version 14.0 and subsequent minor revisions (if any)
+#
+# For documentation and usage, see http://www.unicode.org/reports/tr51
+#
+# Format:
+# <codepoint(s)> ; <property> # <comments>
+# Note: there is no guarantee as to the structure of whitespace or comments
+#
+# Characters and sequences are listed in code point order. Users should be shown a more natural order.
+# See the CLDR collation order for Emoji.
+
+
+# ================================================
+
+# 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
+0030..0039 ; Emoji # E0.0 [10] (0️..9️) digit zero..digit nine
+00A9 ; Emoji # E0.6 [1] (©️) copyright
+00AE ; Emoji # E0.6 [1] (®️) registered
+203C ; Emoji # E0.6 [1] (‼️) double exclamation mark
+2049 ; Emoji # E0.6 [1] (⁉️) exclamation question mark
+2122 ; Emoji # E0.6 [1] (™️) trade mark
+2139 ; Emoji # E0.6 [1] (ℹ️) information
+2194..2199 ; Emoji # E0.6 [6] (↔️..↙️) left-right arrow..down-left arrow
+21A9..21AA ; Emoji # E0.6 [2] (↩️..↪️) right arrow curving left..left arrow curving right
+231A..231B ; Emoji # E0.6 [2] (⌚..⌛) watch..hourglass done
+2328 ; Emoji # E1.0 [1] (⌨️) keyboard
+23CF ; Emoji # E1.0 [1] (⏏️) eject button
+23E9..23EC ; Emoji # E0.6 [4] (⏩..⏬) fast-forward button..fast down button
+23ED..23EE ; Emoji # E0.7 [2] (⏭️..⏮️) next track button..last track button
+23EF ; Emoji # E1.0 [1] (⏯️) play or pause button
+23F0 ; Emoji # E0.6 [1] (⏰) alarm clock
+23F1..23F2 ; Emoji # E1.0 [2] (⏱️..⏲️) stopwatch..timer clock
+23F3 ; Emoji # E0.6 [1] (⏳) hourglass not done
+23F8..23FA ; Emoji # E0.7 [3] (⏸️..⏺️) pause button..record button
+24C2 ; Emoji # E0.6 [1] (Ⓜ️) circled M
+25AA..25AB ; Emoji # E0.6 [2] (▪️..▫️) black small square..white small square
+25B6 ; Emoji # E0.6 [1] (▶️) play button
+25C0 ; Emoji # E0.6 [1] (◀️) reverse button
+25FB..25FE ; Emoji # E0.6 [4] (◻️..◾) white medium square..black medium-small square
+2600..2601 ; Emoji # E0.6 [2] (☀️..☁️) sun..cloud
+2602..2603 ; Emoji # E0.7 [2] (☂️..☃️) umbrella..snowman
+2604 ; Emoji # E1.0 [1] (☄️) comet
+260E ; Emoji # E0.6 [1] (☎️) telephone
+2611 ; Emoji # E0.6 [1] (☑️) check box with check
+2614..2615 ; Emoji # E0.6 [2] (☔..☕) umbrella with rain drops..hot beverage
+2618 ; Emoji # E1.0 [1] (☘️) shamrock
+261D ; Emoji # E0.6 [1] (☝️) index pointing up
+2620 ; Emoji # E1.0 [1] (☠️) skull and crossbones
+2622..2623 ; Emoji # E1.0 [2] (☢️..☣️) radioactive..biohazard
+2626 ; Emoji # E1.0 [1] (☦️) orthodox cross
+262A ; Emoji # E0.7 [1] (☪️) star and crescent
+262E ; Emoji # E1.0 [1] (☮️) peace symbol
+262F ; Emoji # E0.7 [1] (☯️) yin yang
+2638..2639 ; Emoji # E0.7 [2] (☸️..☹️) wheel of dharma..frowning face
+263A ; Emoji # E0.6 [1] (☺️) smiling face
+2640 ; Emoji # E4.0 [1] (♀️) female sign
+2642 ; Emoji # E4.0 [1] (♂️) male sign
+2648..2653 ; Emoji # E0.6 [12] (♈..♓) Aries..Pisces
+265F ; Emoji # E11.0 [1] (♟️) chess pawn
+2660 ; Emoji # E0.6 [1] (♠️) spade suit
+2663 ; Emoji # E0.6 [1] (♣️) club suit
+2665..2666 ; Emoji # E0.6 [2] (♥️..♦️) heart suit..diamond suit
+2668 ; Emoji # E0.6 [1] (♨️) hot springs
+267B ; Emoji # E0.6 [1] (♻️) recycling symbol
+267E ; Emoji # E11.0 [1] (♾️) infinity
+267F ; Emoji # E0.6 [1] (♿) wheelchair symbol
+2692 ; Emoji # E1.0 [1] (⚒️) hammer and pick
+2693 ; Emoji # E0.6 [1] (⚓) anchor
+2694 ; Emoji # E1.0 [1] (⚔️) crossed swords
+2695 ; Emoji # E4.0 [1] (⚕️) medical symbol
+2696..2697 ; Emoji # E1.0 [2] (⚖️..⚗️) balance scale..alembic
+2699 ; Emoji # E1.0 [1] (⚙️) gear
+269B..269C ; Emoji # E1.0 [2] (⚛️..⚜️) atom symbol..fleur-de-lis
+26A0..26A1 ; Emoji # E0.6 [2] (⚠️..⚡) warning..high voltage
+26A7 ; Emoji # E13.0 [1] (⚧️) transgender symbol
+26AA..26AB ; Emoji # E0.6 [2] (⚪..⚫) white circle..black circle
+26B0..26B1 ; Emoji # E1.0 [2] (⚰️..⚱️) coffin..funeral urn
+26BD..26BE ; Emoji # E0.6 [2] (⚽..⚾) soccer ball..baseball
+26C4..26C5 ; Emoji # E0.6 [2] (⛄..⛅) snowman without snow..sun behind cloud
+26C8 ; Emoji # E0.7 [1] (⛈️) cloud with lightning and rain
+26CE ; Emoji # E0.6 [1] (⛎) Ophiuchus
+26CF ; Emoji # E0.7 [1] (⛏️) pick
+26D1 ; Emoji # E0.7 [1] (⛑️) rescue worker’s helmet
+26D3 ; Emoji # E0.7 [1] (⛓️) chains
+26D4 ; Emoji # E0.6 [1] (⛔) no entry
+26E9 ; Emoji # E0.7 [1] (⛩️) shinto shrine
+26EA ; Emoji # E0.6 [1] (⛪) church
+26F0..26F1 ; Emoji # E0.7 [2] (⛰️..⛱️) mountain..umbrella on ground
+26F2..26F3 ; Emoji # E0.6 [2] (⛲..⛳) fountain..flag in hole
+26F4 ; Emoji # E0.7 [1] (⛴️) ferry
+26F5 ; Emoji # E0.6 [1] (⛵) sailboat
+26F7..26F9 ; Emoji # E0.7 [3] (⛷️..⛹️) skier..person bouncing ball
+26FA ; Emoji # E0.6 [1] (⛺) tent
+26FD ; Emoji # E0.6 [1] (⛽) fuel pump
+2702 ; Emoji # E0.6 [1] (✂️) scissors
+2705 ; Emoji # E0.6 [1] (✅) check mark button
+2708..270C ; Emoji # E0.6 [5] (✈️..✌️) airplane..victory hand
+270D ; Emoji # E0.7 [1] (✍️) writing hand
+270F ; Emoji # E0.6 [1] (✏️) pencil
+2712 ; Emoji # E0.6 [1] (✒️) black nib
+2714 ; Emoji # E0.6 [1] (✔️) check mark
+2716 ; Emoji # E0.6 [1] (✖️) multiply
+271D ; Emoji # E0.7 [1] (✝️) latin cross
+2721 ; Emoji # E0.7 [1] (✡️) star of David
+2728 ; Emoji # E0.6 [1] (✨) sparkles
+2733..2734 ; Emoji # E0.6 [2] (✳️..✴️) eight-spoked asterisk..eight-pointed star
+2744 ; Emoji # E0.6 [1] (❄️) snowflake
+2747 ; Emoji # E0.6 [1] (❇️) sparkle
+274C ; Emoji # E0.6 [1] (❌) cross mark
+274E ; Emoji # E0.6 [1] (❎) cross mark button
+2753..2755 ; Emoji # E0.6 [3] (❓..❕) red question mark..white exclamation mark
+2757 ; Emoji # E0.6 [1] (❗) red exclamation mark
+2763 ; Emoji # E1.0 [1] (❣️) heart exclamation
+2764 ; Emoji # E0.6 [1] (❤️) red heart
+2795..2797 ; Emoji # E0.6 [3] (➕..➗) plus..divide
+27A1 ; Emoji # E0.6 [1] (➡️) right arrow
+27B0 ; Emoji # E0.6 [1] (➰) curly loop
+27BF ; Emoji # E1.0 [1] (➿) double curly loop
+2934..2935 ; Emoji # E0.6 [2] (⤴️..⤵️) right arrow curving up..right arrow curving down
+2B05..2B07 ; Emoji # E0.6 [3] (⬅️..⬇️) left arrow..down arrow
+2B1B..2B1C ; Emoji # E0.6 [2] (⬛..⬜) black large square..white large square
+2B50 ; Emoji # E0.6 [1] (⭐) star
+2B55 ; Emoji # E0.6 [1] (⭕) hollow red circle
+3030 ; Emoji # E0.6 [1] (〰️) wavy dash
+303D ; Emoji # E0.6 [1] (〽️) part alternation mark
+3297 ; Emoji # E0.6 [1] (㊗️) Japanese “congratulations” button
+3299 ; Emoji # E0.6 [1] (㊙️) Japanese “secret” button
+1F004 ; Emoji # E0.6 [1] (🀄) mahjong red dragon
+1F0CF ; Emoji # E0.6 [1] (🃏) joker
+1F170..1F171 ; Emoji # E0.6 [2] (🅰️..🅱️) A button (blood type)..B button (blood type)
+1F17E..1F17F ; Emoji # E0.6 [2] (🅾️..🅿️) O button (blood type)..P button
+1F18E ; Emoji # E0.6 [1] (🆎) AB button (blood type)
+1F191..1F19A ; Emoji # E0.6 [10] (🆑..🆚) CL button..VS button
+1F1E6..1F1FF ; Emoji # E0.0 [26] (🇦..🇿) regional indicator symbol letter a..regional indicator symbol letter z
+1F201..1F202 ; Emoji # E0.6 [2] (🈁..🈂️) Japanese “here” button..Japanese “service charge” button
+1F21A ; Emoji # E0.6 [1] (🈚) Japanese “free of charge” button
+1F22F ; Emoji # E0.6 [1] (🈯) Japanese “reserved” button
+1F232..1F23A ; Emoji # E0.6 [9] (🈲..🈺) Japanese “prohibited” button..Japanese “open for business” button
+1F250..1F251 ; Emoji # E0.6 [2] (🉐..🉑) Japanese “bargain” button..Japanese “acceptable” button
+1F300..1F30C ; Emoji # E0.6 [13] (🌀..🌌) cyclone..milky way
+1F30D..1F30E ; Emoji # E0.7 [2] (🌍..🌎) globe showing Europe-Africa..globe showing Americas
+1F30F ; Emoji # E0.6 [1] (🌏) globe showing Asia-Australia
+1F310 ; Emoji # E1.0 [1] (🌐) globe with meridians
+1F311 ; Emoji # E0.6 [1] (🌑) new moon
+1F312 ; Emoji # E1.0 [1] (🌒) waxing crescent moon
+1F313..1F315 ; Emoji # E0.6 [3] (🌓..🌕) first quarter moon..full moon
+1F316..1F318 ; Emoji # E1.0 [3] (🌖..🌘) waning gibbous moon..waning crescent moon
+1F319 ; Emoji # E0.6 [1] (🌙) crescent moon
+1F31A ; Emoji # E1.0 [1] (🌚) new moon face
+1F31B ; Emoji # E0.6 [1] (🌛) first quarter moon face
+1F31C ; Emoji # E0.7 [1] (🌜) last quarter moon face
+1F31D..1F31E ; Emoji # E1.0 [2] (🌝..🌞) full moon face..sun with face
+1F31F..1F320 ; Emoji # E0.6 [2] (🌟..🌠) glowing star..shooting star
+1F321 ; Emoji # E0.7 [1] (🌡️) thermometer
+1F324..1F32C ; Emoji # E0.7 [9] (🌤️..🌬️) sun behind small cloud..wind face
+1F32D..1F32F ; Emoji # E1.0 [3] (🌭..🌯) hot dog..burrito
+1F330..1F331 ; Emoji # E0.6 [2] (🌰..🌱) chestnut..seedling
+1F332..1F333 ; Emoji # E1.0 [2] (🌲..🌳) evergreen tree..deciduous tree
+1F334..1F335 ; Emoji # E0.6 [2] (🌴..🌵) palm tree..cactus
+1F336 ; Emoji # E0.7 [1] (🌶️) hot pepper
+1F337..1F34A ; Emoji # E0.6 [20] (🌷..🍊) tulip..tangerine
+1F34B ; Emoji # E1.0 [1] (🍋) lemon
+1F34C..1F34F ; Emoji # E0.6 [4] (🍌..🍏) banana..green apple
+1F350 ; Emoji # E1.0 [1] (🍐) pear
+1F351..1F37B ; Emoji # E0.6 [43] (🍑..🍻) peach..clinking beer mugs
+1F37C ; Emoji # E1.0 [1] (🍼) baby bottle
+1F37D ; Emoji # E0.7 [1] (🍽️) fork and knife with plate
+1F37E..1F37F ; Emoji # E1.0 [2] (🍾..🍿) bottle with popping cork..popcorn
+1F380..1F393 ; Emoji # E0.6 [20] (🎀..🎓) ribbon..graduation cap
+1F396..1F397 ; Emoji # E0.7 [2] (🎖️..🎗️) military medal..reminder ribbon
+1F399..1F39B ; Emoji # E0.7 [3] (🎙️..🎛️) studio microphone..control knobs
+1F39E..1F39F ; Emoji # E0.7 [2] (🎞️..🎟️) film frames..admission tickets
+1F3A0..1F3C4 ; Emoji # E0.6 [37] (🎠..🏄) carousel horse..person surfing
+1F3C5 ; Emoji # E1.0 [1] (🏅) sports medal
+1F3C6 ; Emoji # E0.6 [1] (🏆) trophy
+1F3C7 ; Emoji # E1.0 [1] (🏇) horse racing
+1F3C8 ; Emoji # E0.6 [1] (🏈) american football
+1F3C9 ; Emoji # E1.0 [1] (🏉) rugby football
+1F3CA ; Emoji # E0.6 [1] (🏊) person swimming
+1F3CB..1F3CE ; Emoji # E0.7 [4] (🏋️..🏎️) person lifting weights..racing car
+1F3CF..1F3D3 ; Emoji # E1.0 [5] (🏏..🏓) cricket game..ping pong
+1F3D4..1F3DF ; Emoji # E0.7 [12] (🏔️..🏟️) snow-capped mountain..stadium
+1F3E0..1F3E3 ; Emoji # E0.6 [4] (🏠..🏣) house..Japanese post office
+1F3E4 ; Emoji # E1.0 [1] (🏤) post office
+1F3E5..1F3F0 ; Emoji # E0.6 [12] (🏥..🏰) hospital..castle
+1F3F3 ; Emoji # E0.7 [1] (🏳️) white flag
+1F3F4 ; Emoji # E1.0 [1] (🏴) black flag
+1F3F5 ; Emoji # E0.7 [1] (🏵️) rosette
+1F3F7 ; Emoji # E0.7 [1] (🏷️) label
+1F3F8..1F407 ; Emoji # E1.0 [16] (🏸..🐇) badminton..rabbit
+1F408 ; Emoji # E0.7 [1] (🐈) cat
+1F409..1F40B ; Emoji # E1.0 [3] (🐉..🐋) dragon..whale
+1F40C..1F40E ; Emoji # E0.6 [3] (🐌..🐎) snail..horse
+1F40F..1F410 ; Emoji # E1.0 [2] (🐏..🐐) ram..goat
+1F411..1F412 ; Emoji # E0.6 [2] (🐑..🐒) ewe..monkey
+1F413 ; Emoji # E1.0 [1] (🐓) rooster
+1F414 ; Emoji # E0.6 [1] (🐔) chicken
+1F415 ; Emoji # E0.7 [1] (🐕) dog
+1F416 ; Emoji # E1.0 [1] (🐖) pig
+1F417..1F429 ; Emoji # E0.6 [19] (🐗..🐩) boar..poodle
+1F42A ; Emoji # E1.0 [1] (🐪) camel
+1F42B..1F43E ; Emoji # E0.6 [20] (🐫..🐾) two-hump camel..paw prints
+1F43F ; Emoji # E0.7 [1] (🐿️) chipmunk
+1F440 ; Emoji # E0.6 [1] (👀) eyes
+1F441 ; Emoji # E0.7 [1] (👁️) eye
+1F442..1F464 ; Emoji # E0.6 [35] (👂..👤) ear..bust in silhouette
+1F465 ; Emoji # E1.0 [1] (👥) busts in silhouette
+1F466..1F46B ; Emoji # E0.6 [6] (👦..👫) boy..woman and man holding hands
+1F46C..1F46D ; Emoji # E1.0 [2] (👬..👭) men holding hands..women holding hands
+1F46E..1F4AC ; Emoji # E0.6 [63] (👮..💬) police officer..speech balloon
+1F4AD ; Emoji # E1.0 [1] (💭) thought balloon
+1F4AE..1F4B5 ; Emoji # E0.6 [8] (💮..💵) white flower..dollar banknote
+1F4B6..1F4B7 ; Emoji # E1.0 [2] (💶..💷) euro banknote..pound banknote
+1F4B8..1F4EB ; Emoji # E0.6 [52] (💸..📫) money with wings..closed mailbox with raised flag
+1F4EC..1F4ED ; Emoji # E0.7 [2] (📬..📭) open mailbox with raised flag..open mailbox with lowered flag
+1F4EE ; Emoji # E0.6 [1] (📮) postbox
+1F4EF ; Emoji # E1.0 [1] (📯) postal horn
+1F4F0..1F4F4 ; Emoji # E0.6 [5] (📰..📴) newspaper..mobile phone off
+1F4F5 ; Emoji # E1.0 [1] (📵) no mobile phones
+1F4F6..1F4F7 ; Emoji # E0.6 [2] (📶..📷) antenna bars..camera
+1F4F8 ; Emoji # E1.0 [1] (📸) camera with flash
+1F4F9..1F4FC ; Emoji # E0.6 [4] (📹..📼) video camera..videocassette
+1F4FD ; Emoji # E0.7 [1] (📽️) film projector
+1F4FF..1F502 ; Emoji # E1.0 [4] (📿..🔂) prayer beads..repeat single button
+1F503 ; Emoji # E0.6 [1] (🔃) clockwise vertical arrows
+1F504..1F507 ; Emoji # E1.0 [4] (🔄..🔇) counterclockwise arrows button..muted speaker
+1F508 ; Emoji # E0.7 [1] (🔈) speaker low volume
+1F509 ; Emoji # E1.0 [1] (🔉) speaker medium volume
+1F50A..1F514 ; Emoji # E0.6 [11] (🔊..🔔) speaker high volume..bell
+1F515 ; Emoji # E1.0 [1] (🔕) bell with slash
+1F516..1F52B ; Emoji # E0.6 [22] (🔖..🔫) bookmark..water pistol
+1F52C..1F52D ; Emoji # E1.0 [2] (🔬..🔭) microscope..telescope
+1F52E..1F53D ; Emoji # E0.6 [16] (🔮..🔽) crystal ball..downwards button
+1F549..1F54A ; Emoji # E0.7 [2] (🕉️..🕊️) om..dove
+1F54B..1F54E ; Emoji # E1.0 [4] (🕋..🕎) kaaba..menorah
+1F550..1F55B ; Emoji # E0.6 [12] (🕐..🕛) one o’clock..twelve o’clock
+1F55C..1F567 ; Emoji # E0.7 [12] (🕜..🕧) one-thirty..twelve-thirty
+1F56F..1F570 ; Emoji # E0.7 [2] (🕯️..🕰️) candle..mantelpiece clock
+1F573..1F579 ; Emoji # E0.7 [7] (🕳️..🕹️) hole..joystick
+1F57A ; Emoji # E3.0 [1] (🕺) man dancing
+1F587 ; Emoji # E0.7 [1] (🖇️) linked paperclips
+1F58A..1F58D ; Emoji # E0.7 [4] (🖊️..🖍️) pen..crayon
+1F590 ; Emoji # E0.7 [1] (🖐️) hand with fingers splayed
+1F595..1F596 ; Emoji # E1.0 [2] (🖕..🖖) middle finger..vulcan salute
+1F5A4 ; Emoji # E3.0 [1] (🖤) black heart
+1F5A5 ; Emoji # E0.7 [1] (🖥️) desktop computer
+1F5A8 ; Emoji # E0.7 [1] (🖨️) printer
+1F5B1..1F5B2 ; Emoji # E0.7 [2] (🖱️..🖲️) computer mouse..trackball
+1F5BC ; Emoji # E0.7 [1] (🖼️) framed picture
+1F5C2..1F5C4 ; Emoji # E0.7 [3] (🗂️..🗄️) card index dividers..file cabinet
+1F5D1..1F5D3 ; Emoji # E0.7 [3] (🗑️..🗓️) wastebasket..spiral calendar
+1F5DC..1F5DE ; Emoji # E0.7 [3] (🗜️..🗞️) clamp..rolled-up newspaper
+1F5E1 ; Emoji # E0.7 [1] (🗡️) dagger
+1F5E3 ; Emoji # E0.7 [1] (🗣️) speaking head
+1F5E8 ; Emoji # E2.0 [1] (🗨️) left speech bubble
+1F5EF ; Emoji # E0.7 [1] (🗯️) right anger bubble
+1F5F3 ; Emoji # E0.7 [1] (🗳️) ballot box with ballot
+1F5FA ; Emoji # E0.7 [1] (🗺️) world map
+1F5FB..1F5FF ; Emoji # E0.6 [5] (🗻..🗿) mount fuji..moai
+1F600 ; Emoji # E1.0 [1] (😀) grinning face
+1F601..1F606 ; Emoji # E0.6 [6] (😁..😆) beaming face with smiling eyes..grinning squinting face
+1F607..1F608 ; Emoji # E1.0 [2] (😇..😈) smiling face with halo..smiling face with horns
+1F609..1F60D ; Emoji # E0.6 [5] (😉..😍) winking face..smiling face with heart-eyes
+1F60E ; Emoji # E1.0 [1] (😎) smiling face with sunglasses
+1F60F ; Emoji # E0.6 [1] (😏) smirking face
+1F610 ; Emoji # E0.7 [1] (😐) neutral face
+1F611 ; Emoji # E1.0 [1] (😑) expressionless face
+1F612..1F614 ; Emoji # E0.6 [3] (😒..😔) unamused face..pensive face
+1F615 ; Emoji # E1.0 [1] (😕) confused face
+1F616 ; Emoji # E0.6 [1] (😖) confounded face
+1F617 ; Emoji # E1.0 [1] (😗) kissing face
+1F618 ; Emoji # E0.6 [1] (😘) face blowing a kiss
+1F619 ; Emoji # E1.0 [1] (😙) kissing face with smiling eyes
+1F61A ; Emoji # E0.6 [1] (😚) kissing face with closed eyes
+1F61B ; Emoji # E1.0 [1] (😛) face with tongue
+1F61C..1F61E ; Emoji # E0.6 [3] (😜..😞) winking face with tongue..disappointed face
+1F61F ; Emoji # E1.0 [1] (😟) worried face
+1F620..1F625 ; Emoji # E0.6 [6] (😠..😥) angry face..sad but relieved face
+1F626..1F627 ; Emoji # E1.0 [2] (😦..😧) frowning face with open mouth..anguished face
+1F628..1F62B ; Emoji # E0.6 [4] (😨..😫) fearful face..tired face
+1F62C ; Emoji # E1.0 [1] (😬) grimacing face
+1F62D ; Emoji # E0.6 [1] (😭) loudly crying face
+1F62E..1F62F ; Emoji # E1.0 [2] (😮..😯) face with open mouth..hushed face
+1F630..1F633 ; Emoji # E0.6 [4] (😰..😳) anxious face with sweat..flushed face
+1F634 ; Emoji # E1.0 [1] (😴) sleeping face
+1F635 ; Emoji # E0.6 [1] (😵) face with crossed-out eyes
+1F636 ; Emoji # E1.0 [1] (😶) face without mouth
+1F637..1F640 ; Emoji # E0.6 [10] (😷..🙀) face with medical mask..weary cat
+1F641..1F644 ; Emoji # E1.0 [4] (🙁..🙄) slightly frowning face..face with rolling eyes
+1F645..1F64F ; Emoji # E0.6 [11] (🙅..🙏) person gesturing NO..folded hands
+1F680 ; Emoji # E0.6 [1] (🚀) rocket
+1F681..1F682 ; Emoji # E1.0 [2] (🚁..🚂) helicopter..locomotive
+1F683..1F685 ; Emoji # E0.6 [3] (🚃..🚅) railway car..bullet train
+1F686 ; Emoji # E1.0 [1] (🚆) train
+1F687 ; Emoji # E0.6 [1] (🚇) metro
+1F688 ; Emoji # E1.0 [1] (🚈) light rail
+1F689 ; Emoji # E0.6 [1] (🚉) station
+1F68A..1F68B ; Emoji # E1.0 [2] (🚊..🚋) tram..tram car
+1F68C ; Emoji # E0.6 [1] (🚌) bus
+1F68D ; Emoji # E0.7 [1] (🚍) oncoming bus
+1F68E ; Emoji # E1.0 [1] (🚎) trolleybus
+1F68F ; Emoji # E0.6 [1] (🚏) bus stop
+1F690 ; Emoji # E1.0 [1] (🚐) minibus
+1F691..1F693 ; Emoji # E0.6 [3] (🚑..🚓) ambulance..police car
+1F694 ; Emoji # E0.7 [1] (🚔) oncoming police car
+1F695 ; Emoji # E0.6 [1] (🚕) taxi
+1F696 ; Emoji # E1.0 [1] (🚖) oncoming taxi
+1F697 ; Emoji # E0.6 [1] (🚗) automobile
+1F698 ; Emoji # E0.7 [1] (🚘) oncoming automobile
+1F699..1F69A ; Emoji # E0.6 [2] (🚙..🚚) sport utility vehicle..delivery truck
+1F69B..1F6A1 ; Emoji # E1.0 [7] (🚛..🚡) articulated lorry..aerial tramway
+1F6A2 ; Emoji # E0.6 [1] (🚢) ship
+1F6A3 ; Emoji # E1.0 [1] (🚣) person rowing boat
+1F6A4..1F6A5 ; Emoji # E0.6 [2] (🚤..🚥) speedboat..horizontal traffic light
+1F6A6 ; Emoji # E1.0 [1] (🚦) vertical traffic light
+1F6A7..1F6AD ; Emoji # E0.6 [7] (🚧..🚭) construction..no smoking
+1F6AE..1F6B1 ; Emoji # E1.0 [4] (🚮..🚱) litter in bin sign..non-potable water
+1F6B2 ; Emoji # E0.6 [1] (🚲) bicycle
+1F6B3..1F6B5 ; Emoji # E1.0 [3] (🚳..🚵) no bicycles..person mountain biking
+1F6B6 ; Emoji # E0.6 [1] (🚶) person walking
+1F6B7..1F6B8 ; Emoji # E1.0 [2] (🚷..🚸) no pedestrians..children crossing
+1F6B9..1F6BE ; Emoji # E0.6 [6] (🚹..🚾) men’s room..water closet
+1F6BF ; Emoji # E1.0 [1] (🚿) shower
+1F6C0 ; Emoji # E0.6 [1] (🛀) person taking bath
+1F6C1..1F6C5 ; Emoji # E1.0 [5] (🛁..🛅) bathtub..left luggage
+1F6CB ; Emoji # E0.7 [1] (🛋️) couch and lamp
+1F6CC ; Emoji # E1.0 [1] (🛌) person in bed
+1F6CD..1F6CF ; Emoji # E0.7 [3] (🛍️..🛏️) shopping bags..bed
+1F6D0 ; Emoji # E1.0 [1] (🛐) place of worship
+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
+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
+1F6EB..1F6EC ; Emoji # E1.0 [2] (🛫..🛬) airplane departure..airplane arrival
+1F6F0 ; Emoji # E0.7 [1] (🛰️) satellite
+1F6F3 ; Emoji # E0.7 [1] (🛳️) passenger ship
+1F6F4..1F6F6 ; Emoji # E3.0 [3] (🛴..🛶) kick scooter..canoe
+1F6F7..1F6F8 ; Emoji # E5.0 [2] (🛷..🛸) sled..flying saucer
+1F6F9 ; Emoji # E11.0 [1] (🛹) skateboard
+1F6FA ; Emoji # E12.0 [1] (🛺) auto rickshaw
+1F6FB..1F6FC ; Emoji # E13.0 [2] (🛻..🛼) pickup truck..roller skate
+1F7E0..1F7EB ; Emoji # E12.0 [12] (🟠..🟫) orange circle..brown square
+1F7F0 ; Emoji # E14.0 [1] (🟰) heavy equals sign
+1F90C ; Emoji # E13.0 [1] (🤌) pinched fingers
+1F90D..1F90F ; Emoji # E12.0 [3] (🤍..🤏) white heart..pinching hand
+1F910..1F918 ; Emoji # E1.0 [9] (🤐..🤘) zipper-mouth face..sign of the horns
+1F919..1F91E ; Emoji # E3.0 [6] (🤙..🤞) call me hand..crossed fingers
+1F91F ; Emoji # E5.0 [1] (🤟) love-you gesture
+1F920..1F927 ; Emoji # E3.0 [8] (🤠..🤧) cowboy hat face..sneezing face
+1F928..1F92F ; Emoji # E5.0 [8] (🤨..🤯) face with raised eyebrow..exploding head
+1F930 ; Emoji # E3.0 [1] (🤰) pregnant woman
+1F931..1F932 ; Emoji # E5.0 [2] (🤱..🤲) breast-feeding..palms up together
+1F933..1F93A ; Emoji # E3.0 [8] (🤳..🤺) selfie..person fencing
+1F93C..1F93E ; Emoji # E3.0 [3] (🤼..🤾) people wrestling..person playing handball
+1F93F ; Emoji # E12.0 [1] (🤿) diving mask
+1F940..1F945 ; Emoji # E3.0 [6] (🥀..🥅) wilted flower..goal net
+1F947..1F94B ; Emoji # E3.0 [5] (🥇..🥋) 1st place medal..martial arts uniform
+1F94C ; Emoji # E5.0 [1] (🥌) curling stone
+1F94D..1F94F ; Emoji # E11.0 [3] (🥍..🥏) lacrosse..flying disc
+1F950..1F95E ; Emoji # E3.0 [15] (🥐..🥞) croissant..pancakes
+1F95F..1F96B ; Emoji # E5.0 [13] (🥟..🥫) dumpling..canned food
+1F96C..1F970 ; Emoji # E11.0 [5] (🥬..🥰) leafy green..smiling face with hearts
+1F971 ; Emoji # E12.0 [1] (🥱) yawning face
+1F972 ; Emoji # E13.0 [1] (🥲) smiling face with tear
+1F973..1F976 ; Emoji # E11.0 [4] (🥳..🥶) partying face..cold face
+1F977..1F978 ; Emoji # E13.0 [2] (🥷..🥸) ninja..disguised face
+1F979 ; Emoji # E14.0 [1] (🥹) face holding back tears
+1F97A ; Emoji # E11.0 [1] (🥺) pleading face
+1F97B ; Emoji # E12.0 [1] (🥻) sari
+1F97C..1F97F ; Emoji # E11.0 [4] (🥼..🥿) lab coat..flat shoe
+1F980..1F984 ; Emoji # E1.0 [5] (🦀..🦄) crab..unicorn
+1F985..1F991 ; Emoji # E3.0 [13] (🦅..🦑) eagle..squid
+1F992..1F997 ; Emoji # E5.0 [6] (🦒..🦗) giraffe..cricket
+1F998..1F9A2 ; Emoji # E11.0 [11] (🦘..🦢) kangaroo..swan
+1F9A3..1F9A4 ; Emoji # E13.0 [2] (🦣..🦤) mammoth..dodo
+1F9A5..1F9AA ; Emoji # E12.0 [6] (🦥..🦪) sloth..oyster
+1F9AB..1F9AD ; Emoji # E13.0 [3] (🦫..🦭) beaver..seal
+1F9AE..1F9AF ; Emoji # E12.0 [2] (🦮..🦯) guide dog..white cane
+1F9B0..1F9B9 ; Emoji # E11.0 [10] (🦰..🦹) red hair..supervillain
+1F9BA..1F9BF ; Emoji # E12.0 [6] (🦺..🦿) safety vest..mechanical leg
+1F9C0 ; Emoji # E1.0 [1] (🧀) cheese wedge
+1F9C1..1F9C2 ; Emoji # E11.0 [2] (🧁..🧂) cupcake..salt
+1F9C3..1F9CA ; Emoji # E12.0 [8] (🧃..🧊) beverage box..ice
+1F9CB ; Emoji # E13.0 [1] (🧋) bubble tea
+1F9CC ; Emoji # E14.0 [1] (🧌) troll
+1F9CD..1F9CF ; Emoji # E12.0 [3] (🧍..🧏) person standing..deaf person
+1F9D0..1F9E6 ; Emoji # E5.0 [23] (🧐..🧦) face with monocle..socks
+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
+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
+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
+1FAB0..1FAB6 ; Emoji # E13.0 [7] (🪰..🪶) fly..feather
+1FAB7..1FABA ; Emoji # E14.0 [4] (🪷..🪺) lotus..nest with eggs
+1FAC0..1FAC2 ; Emoji # E13.0 [3] (🫀..🫂) anatomical heart..people hugging
+1FAC3..1FAC5 ; Emoji # E14.0 [3] (🫃..🫅) pregnant man..person with crown
+1FAD0..1FAD6 ; Emoji # E13.0 [7] (🫐..🫖) blueberries..teapot
+1FAD7..1FAD9 ; Emoji # E14.0 [3] (🫗..🫙) pouring liquid..jar
+1FAE0..1FAE7 ; Emoji # E14.0 [8] (🫠..🫧) melting face..bubbles
+1FAF0..1FAF6 ; Emoji # E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands
+
+# Total elements: 1404
+
+# ================================================
+
+# 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
+23F0 ; Emoji_Presentation # E0.6 [1] (⏰) alarm clock
+23F3 ; Emoji_Presentation # E0.6 [1] (⏳) hourglass not done
+25FD..25FE ; Emoji_Presentation # E0.6 [2] (◽..◾) white medium-small square..black medium-small square
+2614..2615 ; Emoji_Presentation # E0.6 [2] (☔..☕) umbrella with rain drops..hot beverage
+2648..2653 ; Emoji_Presentation # E0.6 [12] (♈..♓) Aries..Pisces
+267F ; Emoji_Presentation # E0.6 [1] (♿) wheelchair symbol
+2693 ; Emoji_Presentation # E0.6 [1] (⚓) anchor
+26A1 ; Emoji_Presentation # E0.6 [1] (⚡) high voltage
+26AA..26AB ; Emoji_Presentation # E0.6 [2] (⚪..⚫) white circle..black circle
+26BD..26BE ; Emoji_Presentation # E0.6 [2] (⚽..⚾) soccer ball..baseball
+26C4..26C5 ; Emoji_Presentation # E0.6 [2] (⛄..⛅) snowman without snow..sun behind cloud
+26CE ; Emoji_Presentation # E0.6 [1] (⛎) Ophiuchus
+26D4 ; Emoji_Presentation # E0.6 [1] (⛔) no entry
+26EA ; Emoji_Presentation # E0.6 [1] (⛪) church
+26F2..26F3 ; Emoji_Presentation # E0.6 [2] (⛲..⛳) fountain..flag in hole
+26F5 ; Emoji_Presentation # E0.6 [1] (⛵) sailboat
+26FA ; Emoji_Presentation # E0.6 [1] (⛺) tent
+26FD ; Emoji_Presentation # E0.6 [1] (⛽) fuel pump
+2705 ; Emoji_Presentation # E0.6 [1] (✅) check mark button
+270A..270B ; Emoji_Presentation # E0.6 [2] (✊..✋) raised fist..raised hand
+2728 ; Emoji_Presentation # E0.6 [1] (✨) sparkles
+274C ; Emoji_Presentation # E0.6 [1] (❌) cross mark
+274E ; Emoji_Presentation # E0.6 [1] (❎) cross mark button
+2753..2755 ; Emoji_Presentation # E0.6 [3] (❓..❕) red question mark..white exclamation mark
+2757 ; Emoji_Presentation # E0.6 [1] (❗) red exclamation mark
+2795..2797 ; Emoji_Presentation # E0.6 [3] (➕..➗) plus..divide
+27B0 ; Emoji_Presentation # E0.6 [1] (➰) curly loop
+27BF ; Emoji_Presentation # E1.0 [1] (➿) double curly loop
+2B1B..2B1C ; Emoji_Presentation # E0.6 [2] (⬛..⬜) black large square..white large square
+2B50 ; Emoji_Presentation # E0.6 [1] (⭐) star
+2B55 ; Emoji_Presentation # E0.6 [1] (⭕) hollow red circle
+1F004 ; Emoji_Presentation # E0.6 [1] (🀄) mahjong red dragon
+1F0CF ; Emoji_Presentation # E0.6 [1] (🃏) joker
+1F18E ; Emoji_Presentation # E0.6 [1] (🆎) AB button (blood type)
+1F191..1F19A ; Emoji_Presentation # E0.6 [10] (🆑..🆚) CL button..VS button
+1F1E6..1F1FF ; Emoji_Presentation # E0.0 [26] (🇦..🇿) regional indicator symbol letter a..regional indicator symbol letter z
+1F201 ; Emoji_Presentation # E0.6 [1] (🈁) Japanese “here” button
+1F21A ; Emoji_Presentation # E0.6 [1] (🈚) Japanese “free of charge” button
+1F22F ; Emoji_Presentation # E0.6 [1] (🈯) Japanese “reserved” button
+1F232..1F236 ; Emoji_Presentation # E0.6 [5] (🈲..🈶) Japanese “prohibited” button..Japanese “not free of charge” button
+1F238..1F23A ; Emoji_Presentation # E0.6 [3] (🈸..🈺) Japanese “application” button..Japanese “open for business” button
+1F250..1F251 ; Emoji_Presentation # E0.6 [2] (🉐..🉑) Japanese “bargain” button..Japanese “acceptable” button
+1F300..1F30C ; Emoji_Presentation # E0.6 [13] (🌀..🌌) cyclone..milky way
+1F30D..1F30E ; Emoji_Presentation # E0.7 [2] (🌍..🌎) globe showing Europe-Africa..globe showing Americas
+1F30F ; Emoji_Presentation # E0.6 [1] (🌏) globe showing Asia-Australia
+1F310 ; Emoji_Presentation # E1.0 [1] (🌐) globe with meridians
+1F311 ; Emoji_Presentation # E0.6 [1] (🌑) new moon
+1F312 ; Emoji_Presentation # E1.0 [1] (🌒) waxing crescent moon
+1F313..1F315 ; Emoji_Presentation # E0.6 [3] (🌓..🌕) first quarter moon..full moon
+1F316..1F318 ; Emoji_Presentation # E1.0 [3] (🌖..🌘) waning gibbous moon..waning crescent moon
+1F319 ; Emoji_Presentation # E0.6 [1] (🌙) crescent moon
+1F31A ; Emoji_Presentation # E1.0 [1] (🌚) new moon face
+1F31B ; Emoji_Presentation # E0.6 [1] (🌛) first quarter moon face
+1F31C ; Emoji_Presentation # E0.7 [1] (🌜) last quarter moon face
+1F31D..1F31E ; Emoji_Presentation # E1.0 [2] (🌝..🌞) full moon face..sun with face
+1F31F..1F320 ; Emoji_Presentation # E0.6 [2] (🌟..🌠) glowing star..shooting star
+1F32D..1F32F ; Emoji_Presentation # E1.0 [3] (🌭..🌯) hot dog..burrito
+1F330..1F331 ; Emoji_Presentation # E0.6 [2] (🌰..🌱) chestnut..seedling
+1F332..1F333 ; Emoji_Presentation # E1.0 [2] (🌲..🌳) evergreen tree..deciduous tree
+1F334..1F335 ; Emoji_Presentation # E0.6 [2] (🌴..🌵) palm tree..cactus
+1F337..1F34A ; Emoji_Presentation # E0.6 [20] (🌷..🍊) tulip..tangerine
+1F34B ; Emoji_Presentation # E1.0 [1] (🍋) lemon
+1F34C..1F34F ; Emoji_Presentation # E0.6 [4] (🍌..🍏) banana..green apple
+1F350 ; Emoji_Presentation # E1.0 [1] (🍐) pear
+1F351..1F37B ; Emoji_Presentation # E0.6 [43] (🍑..🍻) peach..clinking beer mugs
+1F37C ; Emoji_Presentation # E1.0 [1] (🍼) baby bottle
+1F37E..1F37F ; Emoji_Presentation # E1.0 [2] (🍾..🍿) bottle with popping cork..popcorn
+1F380..1F393 ; Emoji_Presentation # E0.6 [20] (🎀..🎓) ribbon..graduation cap
+1F3A0..1F3C4 ; Emoji_Presentation # E0.6 [37] (🎠..🏄) carousel horse..person surfing
+1F3C5 ; Emoji_Presentation # E1.0 [1] (🏅) sports medal
+1F3C6 ; Emoji_Presentation # E0.6 [1] (🏆) trophy
+1F3C7 ; Emoji_Presentation # E1.0 [1] (🏇) horse racing
+1F3C8 ; Emoji_Presentation # E0.6 [1] (🏈) american football
+1F3C9 ; Emoji_Presentation # E1.0 [1] (🏉) rugby football
+1F3CA ; Emoji_Presentation # E0.6 [1] (🏊) person swimming
+1F3CF..1F3D3 ; Emoji_Presentation # E1.0 [5] (🏏..🏓) cricket game..ping pong
+1F3E0..1F3E3 ; Emoji_Presentation # E0.6 [4] (🏠..🏣) house..Japanese post office
+1F3E4 ; Emoji_Presentation # E1.0 [1] (🏤) post office
+1F3E5..1F3F0 ; Emoji_Presentation # E0.6 [12] (🏥..🏰) hospital..castle
+1F3F4 ; Emoji_Presentation # E1.0 [1] (🏴) black flag
+1F3F8..1F407 ; Emoji_Presentation # E1.0 [16] (🏸..🐇) badminton..rabbit
+1F408 ; Emoji_Presentation # E0.7 [1] (🐈) cat
+1F409..1F40B ; Emoji_Presentation # E1.0 [3] (🐉..🐋) dragon..whale
+1F40C..1F40E ; Emoji_Presentation # E0.6 [3] (🐌..🐎) snail..horse
+1F40F..1F410 ; Emoji_Presentation # E1.0 [2] (🐏..🐐) ram..goat
+1F411..1F412 ; Emoji_Presentation # E0.6 [2] (🐑..🐒) ewe..monkey
+1F413 ; Emoji_Presentation # E1.0 [1] (🐓) rooster
+1F414 ; Emoji_Presentation # E0.6 [1] (🐔) chicken
+1F415 ; Emoji_Presentation # E0.7 [1] (🐕) dog
+1F416 ; Emoji_Presentation # E1.0 [1] (🐖) pig
+1F417..1F429 ; Emoji_Presentation # E0.6 [19] (🐗..🐩) boar..poodle
+1F42A ; Emoji_Presentation # E1.0 [1] (🐪) camel
+1F42B..1F43E ; Emoji_Presentation # E0.6 [20] (🐫..🐾) two-hump camel..paw prints
+1F440 ; Emoji_Presentation # E0.6 [1] (👀) eyes
+1F442..1F464 ; Emoji_Presentation # E0.6 [35] (👂..👤) ear..bust in silhouette
+1F465 ; Emoji_Presentation # E1.0 [1] (👥) busts in silhouette
+1F466..1F46B ; Emoji_Presentation # E0.6 [6] (👦..👫) boy..woman and man holding hands
+1F46C..1F46D ; Emoji_Presentation # E1.0 [2] (👬..👭) men holding hands..women holding hands
+1F46E..1F4AC ; Emoji_Presentation # E0.6 [63] (👮..💬) police officer..speech balloon
+1F4AD ; Emoji_Presentation # E1.0 [1] (💭) thought balloon
+1F4AE..1F4B5 ; Emoji_Presentation # E0.6 [8] (💮..💵) white flower..dollar banknote
+1F4B6..1F4B7 ; Emoji_Presentation # E1.0 [2] (💶..💷) euro banknote..pound banknote
+1F4B8..1F4EB ; Emoji_Presentation # E0.6 [52] (💸..📫) money with wings..closed mailbox with raised flag
+1F4EC..1F4ED ; Emoji_Presentation # E0.7 [2] (📬..📭) open mailbox with raised flag..open mailbox with lowered flag
+1F4EE ; Emoji_Presentation # E0.6 [1] (📮) postbox
+1F4EF ; Emoji_Presentation # E1.0 [1] (📯) postal horn
+1F4F0..1F4F4 ; Emoji_Presentation # E0.6 [5] (📰..📴) newspaper..mobile phone off
+1F4F5 ; Emoji_Presentation # E1.0 [1] (📵) no mobile phones
+1F4F6..1F4F7 ; Emoji_Presentation # E0.6 [2] (📶..📷) antenna bars..camera
+1F4F8 ; Emoji_Presentation # E1.0 [1] (📸) camera with flash
+1F4F9..1F4FC ; Emoji_Presentation # E0.6 [4] (📹..📼) video camera..videocassette
+1F4FF..1F502 ; Emoji_Presentation # E1.0 [4] (📿..🔂) prayer beads..repeat single button
+1F503 ; Emoji_Presentation # E0.6 [1] (🔃) clockwise vertical arrows
+1F504..1F507 ; Emoji_Presentation # E1.0 [4] (🔄..🔇) counterclockwise arrows button..muted speaker
+1F508 ; Emoji_Presentation # E0.7 [1] (🔈) speaker low volume
+1F509 ; Emoji_Presentation # E1.0 [1] (🔉) speaker medium volume
+1F50A..1F514 ; Emoji_Presentation # E0.6 [11] (🔊..🔔) speaker high volume..bell
+1F515 ; Emoji_Presentation # E1.0 [1] (🔕) bell with slash
+1F516..1F52B ; Emoji_Presentation # E0.6 [22] (🔖..🔫) bookmark..water pistol
+1F52C..1F52D ; Emoji_Presentation # E1.0 [2] (🔬..🔭) microscope..telescope
+1F52E..1F53D ; Emoji_Presentation # E0.6 [16] (🔮..🔽) crystal ball..downwards button
+1F54B..1F54E ; Emoji_Presentation # E1.0 [4] (🕋..🕎) kaaba..menorah
+1F550..1F55B ; Emoji_Presentation # E0.6 [12] (🕐..🕛) one o’clock..twelve o’clock
+1F55C..1F567 ; Emoji_Presentation # E0.7 [12] (🕜..🕧) one-thirty..twelve-thirty
+1F57A ; Emoji_Presentation # E3.0 [1] (🕺) man dancing
+1F595..1F596 ; Emoji_Presentation # E1.0 [2] (🖕..🖖) middle finger..vulcan salute
+1F5A4 ; Emoji_Presentation # E3.0 [1] (🖤) black heart
+1F5FB..1F5FF ; Emoji_Presentation # E0.6 [5] (🗻..🗿) mount fuji..moai
+1F600 ; Emoji_Presentation # E1.0 [1] (😀) grinning face
+1F601..1F606 ; Emoji_Presentation # E0.6 [6] (😁..😆) beaming face with smiling eyes..grinning squinting face
+1F607..1F608 ; Emoji_Presentation # E1.0 [2] (😇..😈) smiling face with halo..smiling face with horns
+1F609..1F60D ; Emoji_Presentation # E0.6 [5] (😉..😍) winking face..smiling face with heart-eyes
+1F60E ; Emoji_Presentation # E1.0 [1] (😎) smiling face with sunglasses
+1F60F ; Emoji_Presentation # E0.6 [1] (😏) smirking face
+1F610 ; Emoji_Presentation # E0.7 [1] (😐) neutral face
+1F611 ; Emoji_Presentation # E1.0 [1] (😑) expressionless face
+1F612..1F614 ; Emoji_Presentation # E0.6 [3] (😒..😔) unamused face..pensive face
+1F615 ; Emoji_Presentation # E1.0 [1] (😕) confused face
+1F616 ; Emoji_Presentation # E0.6 [1] (😖) confounded face
+1F617 ; Emoji_Presentation # E1.0 [1] (😗) kissing face
+1F618 ; Emoji_Presentation # E0.6 [1] (😘) face blowing a kiss
+1F619 ; Emoji_Presentation # E1.0 [1] (😙) kissing face with smiling eyes
+1F61A ; Emoji_Presentation # E0.6 [1] (😚) kissing face with closed eyes
+1F61B ; Emoji_Presentation # E1.0 [1] (😛) face with tongue
+1F61C..1F61E ; Emoji_Presentation # E0.6 [3] (😜..😞) winking face with tongue..disappointed face
+1F61F ; Emoji_Presentation # E1.0 [1] (😟) worried face
+1F620..1F625 ; Emoji_Presentation # E0.6 [6] (😠..😥) angry face..sad but relieved face
+1F626..1F627 ; Emoji_Presentation # E1.0 [2] (😦..😧) frowning face with open mouth..anguished face
+1F628..1F62B ; Emoji_Presentation # E0.6 [4] (😨..😫) fearful face..tired face
+1F62C ; Emoji_Presentation # E1.0 [1] (😬) grimacing face
+1F62D ; Emoji_Presentation # E0.6 [1] (😭) loudly crying face
+1F62E..1F62F ; Emoji_Presentation # E1.0 [2] (😮..😯) face with open mouth..hushed face
+1F630..1F633 ; Emoji_Presentation # E0.6 [4] (😰..😳) anxious face with sweat..flushed face
+1F634 ; Emoji_Presentation # E1.0 [1] (😴) sleeping face
+1F635 ; Emoji_Presentation # E0.6 [1] (😵) face with crossed-out eyes
+1F636 ; Emoji_Presentation # E1.0 [1] (😶) face without mouth
+1F637..1F640 ; Emoji_Presentation # E0.6 [10] (😷..🙀) face with medical mask..weary cat
+1F641..1F644 ; Emoji_Presentation # E1.0 [4] (🙁..🙄) slightly frowning face..face with rolling eyes
+1F645..1F64F ; Emoji_Presentation # E0.6 [11] (🙅..🙏) person gesturing NO..folded hands
+1F680 ; Emoji_Presentation # E0.6 [1] (🚀) rocket
+1F681..1F682 ; Emoji_Presentation # E1.0 [2] (🚁..🚂) helicopter..locomotive
+1F683..1F685 ; Emoji_Presentation # E0.6 [3] (🚃..🚅) railway car..bullet train
+1F686 ; Emoji_Presentation # E1.0 [1] (🚆) train
+1F687 ; Emoji_Presentation # E0.6 [1] (🚇) metro
+1F688 ; Emoji_Presentation # E1.0 [1] (🚈) light rail
+1F689 ; Emoji_Presentation # E0.6 [1] (🚉) station
+1F68A..1F68B ; Emoji_Presentation # E1.0 [2] (🚊..🚋) tram..tram car
+1F68C ; Emoji_Presentation # E0.6 [1] (🚌) bus
+1F68D ; Emoji_Presentation # E0.7 [1] (🚍) oncoming bus
+1F68E ; Emoji_Presentation # E1.0 [1] (🚎) trolleybus
+1F68F ; Emoji_Presentation # E0.6 [1] (🚏) bus stop
+1F690 ; Emoji_Presentation # E1.0 [1] (🚐) minibus
+1F691..1F693 ; Emoji_Presentation # E0.6 [3] (🚑..🚓) ambulance..police car
+1F694 ; Emoji_Presentation # E0.7 [1] (🚔) oncoming police car
+1F695 ; Emoji_Presentation # E0.6 [1] (🚕) taxi
+1F696 ; Emoji_Presentation # E1.0 [1] (🚖) oncoming taxi
+1F697 ; Emoji_Presentation # E0.6 [1] (🚗) automobile
+1F698 ; Emoji_Presentation # E0.7 [1] (🚘) oncoming automobile
+1F699..1F69A ; Emoji_Presentation # E0.6 [2] (🚙..🚚) sport utility vehicle..delivery truck
+1F69B..1F6A1 ; Emoji_Presentation # E1.0 [7] (🚛..🚡) articulated lorry..aerial tramway
+1F6A2 ; Emoji_Presentation # E0.6 [1] (🚢) ship
+1F6A3 ; Emoji_Presentation # E1.0 [1] (🚣) person rowing boat
+1F6A4..1F6A5 ; Emoji_Presentation # E0.6 [2] (🚤..🚥) speedboat..horizontal traffic light
+1F6A6 ; Emoji_Presentation # E1.0 [1] (🚦) vertical traffic light
+1F6A7..1F6AD ; Emoji_Presentation # E0.6 [7] (🚧..🚭) construction..no smoking
+1F6AE..1F6B1 ; Emoji_Presentation # E1.0 [4] (🚮..🚱) litter in bin sign..non-potable water
+1F6B2 ; Emoji_Presentation # E0.6 [1] (🚲) bicycle
+1F6B3..1F6B5 ; Emoji_Presentation # E1.0 [3] (🚳..🚵) no bicycles..person mountain biking
+1F6B6 ; Emoji_Presentation # E0.6 [1] (🚶) person walking
+1F6B7..1F6B8 ; Emoji_Presentation # E1.0 [2] (🚷..🚸) no pedestrians..children crossing
+1F6B9..1F6BE ; Emoji_Presentation # E0.6 [6] (🚹..🚾) men’s room..water closet
+1F6BF ; Emoji_Presentation # E1.0 [1] (🚿) shower
+1F6C0 ; Emoji_Presentation # E0.6 [1] (🛀) person taking bath
+1F6C1..1F6C5 ; Emoji_Presentation # E1.0 [5] (🛁..🛅) bathtub..left luggage
+1F6CC ; Emoji_Presentation # E1.0 [1] (🛌) person in bed
+1F6D0 ; Emoji_Presentation # E1.0 [1] (🛐) place of worship
+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
+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
+1F6F7..1F6F8 ; Emoji_Presentation # E5.0 [2] (🛷..🛸) sled..flying saucer
+1F6F9 ; Emoji_Presentation # E11.0 [1] (🛹) skateboard
+1F6FA ; Emoji_Presentation # E12.0 [1] (🛺) auto rickshaw
+1F6FB..1F6FC ; Emoji_Presentation # E13.0 [2] (🛻..🛼) pickup truck..roller skate
+1F7E0..1F7EB ; Emoji_Presentation # E12.0 [12] (🟠..🟫) orange circle..brown square
+1F7F0 ; Emoji_Presentation # E14.0 [1] (🟰) heavy equals sign
+1F90C ; Emoji_Presentation # E13.0 [1] (🤌) pinched fingers
+1F90D..1F90F ; Emoji_Presentation # E12.0 [3] (🤍..🤏) white heart..pinching hand
+1F910..1F918 ; Emoji_Presentation # E1.0 [9] (🤐..🤘) zipper-mouth face..sign of the horns
+1F919..1F91E ; Emoji_Presentation # E3.0 [6] (🤙..🤞) call me hand..crossed fingers
+1F91F ; Emoji_Presentation # E5.0 [1] (🤟) love-you gesture
+1F920..1F927 ; Emoji_Presentation # E3.0 [8] (🤠..🤧) cowboy hat face..sneezing face
+1F928..1F92F ; Emoji_Presentation # E5.0 [8] (🤨..🤯) face with raised eyebrow..exploding head
+1F930 ; Emoji_Presentation # E3.0 [1] (🤰) pregnant woman
+1F931..1F932 ; Emoji_Presentation # E5.0 [2] (🤱..🤲) breast-feeding..palms up together
+1F933..1F93A ; Emoji_Presentation # E3.0 [8] (🤳..🤺) selfie..person fencing
+1F93C..1F93E ; Emoji_Presentation # E3.0 [3] (🤼..🤾) people wrestling..person playing handball
+1F93F ; Emoji_Presentation # E12.0 [1] (🤿) diving mask
+1F940..1F945 ; Emoji_Presentation # E3.0 [6] (🥀..🥅) wilted flower..goal net
+1F947..1F94B ; Emoji_Presentation # E3.0 [5] (🥇..🥋) 1st place medal..martial arts uniform
+1F94C ; Emoji_Presentation # E5.0 [1] (🥌) curling stone
+1F94D..1F94F ; Emoji_Presentation # E11.0 [3] (🥍..🥏) lacrosse..flying disc
+1F950..1F95E ; Emoji_Presentation # E3.0 [15] (🥐..🥞) croissant..pancakes
+1F95F..1F96B ; Emoji_Presentation # E5.0 [13] (🥟..🥫) dumpling..canned food
+1F96C..1F970 ; Emoji_Presentation # E11.0 [5] (🥬..🥰) leafy green..smiling face with hearts
+1F971 ; Emoji_Presentation # E12.0 [1] (🥱) yawning face
+1F972 ; Emoji_Presentation # E13.0 [1] (🥲) smiling face with tear
+1F973..1F976 ; Emoji_Presentation # E11.0 [4] (🥳..🥶) partying face..cold face
+1F977..1F978 ; Emoji_Presentation # E13.0 [2] (🥷..🥸) ninja..disguised face
+1F979 ; Emoji_Presentation # E14.0 [1] (🥹) face holding back tears
+1F97A ; Emoji_Presentation # E11.0 [1] (🥺) pleading face
+1F97B ; Emoji_Presentation # E12.0 [1] (🥻) sari
+1F97C..1F97F ; Emoji_Presentation # E11.0 [4] (🥼..🥿) lab coat..flat shoe
+1F980..1F984 ; Emoji_Presentation # E1.0 [5] (🦀..🦄) crab..unicorn
+1F985..1F991 ; Emoji_Presentation # E3.0 [13] (🦅..🦑) eagle..squid
+1F992..1F997 ; Emoji_Presentation # E5.0 [6] (🦒..🦗) giraffe..cricket
+1F998..1F9A2 ; Emoji_Presentation # E11.0 [11] (🦘..🦢) kangaroo..swan
+1F9A3..1F9A4 ; Emoji_Presentation # E13.0 [2] (🦣..🦤) mammoth..dodo
+1F9A5..1F9AA ; Emoji_Presentation # E12.0 [6] (🦥..🦪) sloth..oyster
+1F9AB..1F9AD ; Emoji_Presentation # E13.0 [3] (🦫..🦭) beaver..seal
+1F9AE..1F9AF ; Emoji_Presentation # E12.0 [2] (🦮..🦯) guide dog..white cane
+1F9B0..1F9B9 ; Emoji_Presentation # E11.0 [10] (🦰..🦹) red hair..supervillain
+1F9BA..1F9BF ; Emoji_Presentation # E12.0 [6] (🦺..🦿) safety vest..mechanical leg
+1F9C0 ; Emoji_Presentation # E1.0 [1] (🧀) cheese wedge
+1F9C1..1F9C2 ; Emoji_Presentation # E11.0 [2] (🧁..🧂) cupcake..salt
+1F9C3..1F9CA ; Emoji_Presentation # E12.0 [8] (🧃..🧊) beverage box..ice
+1F9CB ; Emoji_Presentation # E13.0 [1] (🧋) bubble tea
+1F9CC ; Emoji_Presentation # E14.0 [1] (🧌) troll
+1F9CD..1F9CF ; Emoji_Presentation # E12.0 [3] (🧍..🧏) person standing..deaf person
+1F9D0..1F9E6 ; Emoji_Presentation # E5.0 [23] (🧐..🧦) face with monocle..socks
+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
+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
+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
+1FAB0..1FAB6 ; Emoji_Presentation # E13.0 [7] (🪰..🪶) fly..feather
+1FAB7..1FABA ; Emoji_Presentation # E14.0 [4] (🪷..🪺) lotus..nest with eggs
+1FAC0..1FAC2 ; Emoji_Presentation # E13.0 [3] (🫀..🫂) anatomical heart..people hugging
+1FAC3..1FAC5 ; Emoji_Presentation # E14.0 [3] (🫃..🫅) pregnant man..person with crown
+1FAD0..1FAD6 ; Emoji_Presentation # E13.0 [7] (🫐..🫖) blueberries..teapot
+1FAD7..1FAD9 ; Emoji_Presentation # E14.0 [3] (🫗..🫙) pouring liquid..jar
+1FAE0..1FAE7 ; Emoji_Presentation # E14.0 [8] (🫠..🫧) melting face..bubbles
+1FAF0..1FAF6 ; Emoji_Presentation # E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands
+
+# Total elements: 1185
+
+# ================================================
+
+# 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
+
+# Total elements: 5
+
+# ================================================
+
+# 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
+270A..270C ; Emoji_Modifier_Base # E0.6 [3] (✊..✌️) raised fist..victory hand
+270D ; Emoji_Modifier_Base # E0.7 [1] (✍️) writing hand
+1F385 ; Emoji_Modifier_Base # E0.6 [1] (🎅) Santa Claus
+1F3C2..1F3C4 ; Emoji_Modifier_Base # E0.6 [3] (🏂..🏄) snowboarder..person surfing
+1F3C7 ; Emoji_Modifier_Base # E1.0 [1] (🏇) horse racing
+1F3CA ; Emoji_Modifier_Base # E0.6 [1] (🏊) person swimming
+1F3CB..1F3CC ; Emoji_Modifier_Base # E0.7 [2] (🏋️..🏌️) person lifting weights..person golfing
+1F442..1F443 ; Emoji_Modifier_Base # E0.6 [2] (👂..👃) ear..nose
+1F446..1F450 ; Emoji_Modifier_Base # E0.6 [11] (👆..👐) backhand index pointing up..open hands
+1F466..1F46B ; Emoji_Modifier_Base # E0.6 [6] (👦..👫) boy..woman and man holding hands
+1F46C..1F46D ; Emoji_Modifier_Base # E1.0 [2] (👬..👭) men holding hands..women holding hands
+1F46E..1F478 ; Emoji_Modifier_Base # E0.6 [11] (👮..👸) police officer..princess
+1F47C ; Emoji_Modifier_Base # E0.6 [1] (👼) baby angel
+1F481..1F483 ; Emoji_Modifier_Base # E0.6 [3] (💁..💃) person tipping hand..woman dancing
+1F485..1F487 ; Emoji_Modifier_Base # E0.6 [3] (💅..💇) nail polish..person getting haircut
+1F48F ; Emoji_Modifier_Base # E0.6 [1] (💏) kiss
+1F491 ; Emoji_Modifier_Base # E0.6 [1] (💑) couple with heart
+1F4AA ; Emoji_Modifier_Base # E0.6 [1] (💪) flexed biceps
+1F574..1F575 ; Emoji_Modifier_Base # E0.7 [2] (🕴️..🕵️) person in suit levitating..detective
+1F57A ; Emoji_Modifier_Base # E3.0 [1] (🕺) man dancing
+1F590 ; Emoji_Modifier_Base # E0.7 [1] (🖐️) hand with fingers splayed
+1F595..1F596 ; Emoji_Modifier_Base # E1.0 [2] (🖕..🖖) middle finger..vulcan salute
+1F645..1F647 ; Emoji_Modifier_Base # E0.6 [3] (🙅..🙇) person gesturing NO..person bowing
+1F64B..1F64F ; Emoji_Modifier_Base # E0.6 [5] (🙋..🙏) person raising hand..folded hands
+1F6A3 ; Emoji_Modifier_Base # E1.0 [1] (🚣) person rowing boat
+1F6B4..1F6B5 ; Emoji_Modifier_Base # E1.0 [2] (🚴..🚵) person biking..person mountain biking
+1F6B6 ; Emoji_Modifier_Base # E0.6 [1] (🚶) person walking
+1F6C0 ; Emoji_Modifier_Base # E0.6 [1] (🛀) person taking bath
+1F6CC ; Emoji_Modifier_Base # E1.0 [1] (🛌) person in bed
+1F90C ; Emoji_Modifier_Base # E13.0 [1] (🤌) pinched fingers
+1F90F ; Emoji_Modifier_Base # E12.0 [1] (🤏) pinching hand
+1F918 ; Emoji_Modifier_Base # E1.0 [1] (🤘) sign of the horns
+1F919..1F91E ; Emoji_Modifier_Base # E3.0 [6] (🤙..🤞) call me hand..crossed fingers
+1F91F ; Emoji_Modifier_Base # E5.0 [1] (🤟) love-you gesture
+1F926 ; Emoji_Modifier_Base # E3.0 [1] (🤦) person facepalming
+1F930 ; Emoji_Modifier_Base # E3.0 [1] (🤰) pregnant woman
+1F931..1F932 ; Emoji_Modifier_Base # E5.0 [2] (🤱..🤲) breast-feeding..palms up together
+1F933..1F939 ; Emoji_Modifier_Base # E3.0 [7] (🤳..🤹) selfie..person juggling
+1F93C..1F93E ; Emoji_Modifier_Base # E3.0 [3] (🤼..🤾) people wrestling..person playing handball
+1F977 ; Emoji_Modifier_Base # E13.0 [1] (🥷) ninja
+1F9B5..1F9B6 ; Emoji_Modifier_Base # E11.0 [2] (🦵..🦶) leg..foot
+1F9B8..1F9B9 ; Emoji_Modifier_Base # E11.0 [2] (🦸..🦹) superhero..supervillain
+1F9BB ; Emoji_Modifier_Base # E12.0 [1] (🦻) ear with hearing aid
+1F9CD..1F9CF ; Emoji_Modifier_Base # E12.0 [3] (🧍..🧏) person standing..deaf person
+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
+
+# Total elements: 132
+
+# ================================================
+
+# 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
+0030..0039 ; Emoji_Component # E0.0 [10] (0️..9️) digit zero..digit nine
+200D ; Emoji_Component # E0.0 [1] (‍) zero width joiner
+20E3 ; Emoji_Component # E0.0 [1] (⃣) combining enclosing keycap
+FE0F ; Emoji_Component # E0.0 [1] () VARIATION SELECTOR-16
+1F1E6..1F1FF ; Emoji_Component # E0.0 [26] (🇦..🇿) regional indicator symbol letter a..regional indicator symbol letter z
+1F3FB..1F3FF ; Emoji_Component # E1.0 [5] (🏻..🏿) light skin tone..dark skin tone
+1F9B0..1F9B3 ; Emoji_Component # E11.0 [4] (🦰..🦳) red hair..white hair
+E0020..E007F ; Emoji_Component # E0.0 [96] (󠀠..󠁿) tag space..cancel tag
+
+# Total elements: 146
+
+# ================================================
+
+# 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
+203C ; Extended_Pictographic# E0.6 [1] (‼️) double exclamation mark
+2049 ; Extended_Pictographic# E0.6 [1] (⁉️) exclamation question mark
+2122 ; Extended_Pictographic# E0.6 [1] (™️) trade mark
+2139 ; Extended_Pictographic# E0.6 [1] (ℹ️) information
+2194..2199 ; Extended_Pictographic# E0.6 [6] (↔️..↙️) left-right arrow..down-left arrow
+21A9..21AA ; Extended_Pictographic# E0.6 [2] (↩️..↪️) right arrow curving left..left arrow curving right
+231A..231B ; Extended_Pictographic# E0.6 [2] (⌚..⌛) watch..hourglass done
+2328 ; Extended_Pictographic# E1.0 [1] (⌨️) keyboard
+2388 ; Extended_Pictographic# E0.0 [1] (⎈) HELM SYMBOL
+23CF ; Extended_Pictographic# E1.0 [1] (⏏️) eject button
+23E9..23EC ; Extended_Pictographic# E0.6 [4] (⏩..⏬) fast-forward button..fast down button
+23ED..23EE ; Extended_Pictographic# E0.7 [2] (⏭️..⏮️) next track button..last track button
+23EF ; Extended_Pictographic# E1.0 [1] (⏯️) play or pause button
+23F0 ; Extended_Pictographic# E0.6 [1] (⏰) alarm clock
+23F1..23F2 ; Extended_Pictographic# E1.0 [2] (⏱️..⏲️) stopwatch..timer clock
+23F3 ; Extended_Pictographic# E0.6 [1] (⏳) hourglass not done
+23F8..23FA ; Extended_Pictographic# E0.7 [3] (⏸️..⏺️) pause button..record button
+24C2 ; Extended_Pictographic# E0.6 [1] (Ⓜ️) circled M
+25AA..25AB ; Extended_Pictographic# E0.6 [2] (▪️..▫️) black small square..white small square
+25B6 ; Extended_Pictographic# E0.6 [1] (▶️) play button
+25C0 ; Extended_Pictographic# E0.6 [1] (◀️) reverse button
+25FB..25FE ; Extended_Pictographic# E0.6 [4] (◻️..◾) white medium square..black medium-small square
+2600..2601 ; Extended_Pictographic# E0.6 [2] (☀️..☁️) sun..cloud
+2602..2603 ; Extended_Pictographic# E0.7 [2] (☂️..☃️) umbrella..snowman
+2604 ; Extended_Pictographic# E1.0 [1] (☄️) comet
+2605 ; Extended_Pictographic# E0.0 [1] (★) BLACK STAR
+2607..260D ; Extended_Pictographic# E0.0 [7] (☇..☍) LIGHTNING..OPPOSITION
+260E ; Extended_Pictographic# E0.6 [1] (☎️) telephone
+260F..2610 ; Extended_Pictographic# E0.0 [2] (☏..☐) WHITE TELEPHONE..BALLOT BOX
+2611 ; Extended_Pictographic# E0.6 [1] (☑️) check box with check
+2612 ; Extended_Pictographic# E0.0 [1] (☒) BALLOT BOX WITH X
+2614..2615 ; Extended_Pictographic# E0.6 [2] (☔..☕) umbrella with rain drops..hot beverage
+2616..2617 ; Extended_Pictographic# E0.0 [2] (☖..☗) WHITE SHOGI PIECE..BLACK SHOGI PIECE
+2618 ; Extended_Pictographic# E1.0 [1] (☘️) shamrock
+2619..261C ; Extended_Pictographic# E0.0 [4] (☙..☜) REVERSED ROTATED FLORAL HEART BULLET..WHITE LEFT POINTING INDEX
+261D ; Extended_Pictographic# E0.6 [1] (☝️) index pointing up
+261E..261F ; Extended_Pictographic# E0.0 [2] (☞..☟) WHITE RIGHT POINTING INDEX..WHITE DOWN POINTING INDEX
+2620 ; Extended_Pictographic# E1.0 [1] (☠️) skull and crossbones
+2621 ; Extended_Pictographic# E0.0 [1] (☡) CAUTION SIGN
+2622..2623 ; Extended_Pictographic# E1.0 [2] (☢️..☣️) radioactive..biohazard
+2624..2625 ; Extended_Pictographic# E0.0 [2] (☤..☥) CADUCEUS..ANKH
+2626 ; Extended_Pictographic# E1.0 [1] (☦️) orthodox cross
+2627..2629 ; Extended_Pictographic# E0.0 [3] (☧..☩) CHI RHO..CROSS OF JERUSALEM
+262A ; Extended_Pictographic# E0.7 [1] (☪️) star and crescent
+262B..262D ; Extended_Pictographic# E0.0 [3] (☫..☭) FARSI SYMBOL..HAMMER AND SICKLE
+262E ; Extended_Pictographic# E1.0 [1] (☮️) peace symbol
+262F ; Extended_Pictographic# E0.7 [1] (☯️) yin yang
+2630..2637 ; Extended_Pictographic# E0.0 [8] (☰..☷) TRIGRAM FOR HEAVEN..TRIGRAM FOR EARTH
+2638..2639 ; Extended_Pictographic# E0.7 [2] (☸️..☹️) wheel of dharma..frowning face
+263A ; Extended_Pictographic# E0.6 [1] (☺️) smiling face
+263B..263F ; Extended_Pictographic# E0.0 [5] (☻..☿) BLACK SMILING FACE..MERCURY
+2640 ; Extended_Pictographic# E4.0 [1] (♀️) female sign
+2641 ; Extended_Pictographic# E0.0 [1] (♁) EARTH
+2642 ; Extended_Pictographic# E4.0 [1] (♂️) male sign
+2643..2647 ; Extended_Pictographic# E0.0 [5] (♃..♇) JUPITER..PLUTO
+2648..2653 ; Extended_Pictographic# E0.6 [12] (♈..♓) Aries..Pisces
+2654..265E ; Extended_Pictographic# E0.0 [11] (♔..♞) WHITE CHESS KING..BLACK CHESS KNIGHT
+265F ; Extended_Pictographic# E11.0 [1] (♟️) chess pawn
+2660 ; Extended_Pictographic# E0.6 [1] (♠️) spade suit
+2661..2662 ; Extended_Pictographic# E0.0 [2] (♡..♢) WHITE HEART SUIT..WHITE DIAMOND SUIT
+2663 ; Extended_Pictographic# E0.6 [1] (♣️) club suit
+2664 ; Extended_Pictographic# E0.0 [1] (♤) WHITE SPADE SUIT
+2665..2666 ; Extended_Pictographic# E0.6 [2] (♥️..♦️) heart suit..diamond suit
+2667 ; Extended_Pictographic# E0.0 [1] (♧) WHITE CLUB SUIT
+2668 ; Extended_Pictographic# E0.6 [1] (♨️) hot springs
+2669..267A ; Extended_Pictographic# E0.0 [18] (♩..♺) QUARTER NOTE..RECYCLING SYMBOL FOR GENERIC MATERIALS
+267B ; Extended_Pictographic# E0.6 [1] (♻️) recycling symbol
+267C..267D ; Extended_Pictographic# E0.0 [2] (♼..♽) RECYCLED PAPER SYMBOL..PARTIALLY-RECYCLED PAPER SYMBOL
+267E ; Extended_Pictographic# E11.0 [1] (♾️) infinity
+267F ; Extended_Pictographic# E0.6 [1] (♿) wheelchair symbol
+2680..2685 ; Extended_Pictographic# E0.0 [6] (⚀..⚅) DIE FACE-1..DIE FACE-6
+2690..2691 ; Extended_Pictographic# E0.0 [2] (⚐..⚑) WHITE FLAG..BLACK FLAG
+2692 ; Extended_Pictographic# E1.0 [1] (⚒️) hammer and pick
+2693 ; Extended_Pictographic# E0.6 [1] (⚓) anchor
+2694 ; Extended_Pictographic# E1.0 [1] (⚔️) crossed swords
+2695 ; Extended_Pictographic# E4.0 [1] (⚕️) medical symbol
+2696..2697 ; Extended_Pictographic# E1.0 [2] (⚖️..⚗️) balance scale..alembic
+2698 ; Extended_Pictographic# E0.0 [1] (⚘) FLOWER
+2699 ; Extended_Pictographic# E1.0 [1] (⚙️) gear
+269A ; Extended_Pictographic# E0.0 [1] (⚚) STAFF OF HERMES
+269B..269C ; Extended_Pictographic# E1.0 [2] (⚛️..⚜️) atom symbol..fleur-de-lis
+269D..269F ; Extended_Pictographic# E0.0 [3] (⚝..⚟) OUTLINED WHITE STAR..THREE LINES CONVERGING LEFT
+26A0..26A1 ; Extended_Pictographic# E0.6 [2] (⚠️..⚡) warning..high voltage
+26A2..26A6 ; Extended_Pictographic# E0.0 [5] (⚢..⚦) DOUBLED FEMALE SIGN..MALE WITH STROKE SIGN
+26A7 ; Extended_Pictographic# E13.0 [1] (⚧️) transgender symbol
+26A8..26A9 ; Extended_Pictographic# E0.0 [2] (⚨..⚩) VERTICAL MALE WITH STROKE SIGN..HORIZONTAL MALE WITH STROKE SIGN
+26AA..26AB ; Extended_Pictographic# E0.6 [2] (⚪..⚫) white circle..black circle
+26AC..26AF ; Extended_Pictographic# E0.0 [4] (⚬..⚯) MEDIUM SMALL WHITE CIRCLE..UNMARRIED PARTNERSHIP SYMBOL
+26B0..26B1 ; Extended_Pictographic# E1.0 [2] (⚰️..⚱️) coffin..funeral urn
+26B2..26BC ; Extended_Pictographic# E0.0 [11] (⚲..⚼) NEUTER..SESQUIQUADRATE
+26BD..26BE ; Extended_Pictographic# E0.6 [2] (⚽..⚾) soccer ball..baseball
+26BF..26C3 ; Extended_Pictographic# E0.0 [5] (⚿..⛃) SQUARED KEY..BLACK DRAUGHTS KING
+26C4..26C5 ; Extended_Pictographic# E0.6 [2] (⛄..⛅) snowman without snow..sun behind cloud
+26C6..26C7 ; Extended_Pictographic# E0.0 [2] (⛆..⛇) RAIN..BLACK SNOWMAN
+26C8 ; Extended_Pictographic# E0.7 [1] (⛈️) cloud with lightning and rain
+26C9..26CD ; Extended_Pictographic# E0.0 [5] (⛉..⛍) TURNED WHITE SHOGI PIECE..DISABLED CAR
+26CE ; Extended_Pictographic# E0.6 [1] (⛎) Ophiuchus
+26CF ; Extended_Pictographic# E0.7 [1] (⛏️) pick
+26D0 ; Extended_Pictographic# E0.0 [1] (⛐) CAR SLIDING
+26D1 ; Extended_Pictographic# E0.7 [1] (⛑️) rescue worker’s helmet
+26D2 ; Extended_Pictographic# E0.0 [1] (⛒) CIRCLED CROSSING LANES
+26D3 ; Extended_Pictographic# E0.7 [1] (⛓️) chains
+26D4 ; Extended_Pictographic# E0.6 [1] (⛔) no entry
+26D5..26E8 ; Extended_Pictographic# E0.0 [20] (⛕..⛨) ALTERNATE ONE-WAY LEFT WAY TRAFFIC..BLACK CROSS ON SHIELD
+26E9 ; Extended_Pictographic# E0.7 [1] (⛩️) shinto shrine
+26EA ; Extended_Pictographic# E0.6 [1] (⛪) church
+26EB..26EF ; Extended_Pictographic# E0.0 [5] (⛫..⛯) CASTLE..MAP SYMBOL FOR LIGHTHOUSE
+26F0..26F1 ; Extended_Pictographic# E0.7 [2] (⛰️..⛱️) mountain..umbrella on ground
+26F2..26F3 ; Extended_Pictographic# E0.6 [2] (⛲..⛳) fountain..flag in hole
+26F4 ; Extended_Pictographic# E0.7 [1] (⛴️) ferry
+26F5 ; Extended_Pictographic# E0.6 [1] (⛵) sailboat
+26F6 ; Extended_Pictographic# E0.0 [1] (⛶) SQUARE FOUR CORNERS
+26F7..26F9 ; Extended_Pictographic# E0.7 [3] (⛷️..⛹️) skier..person bouncing ball
+26FA ; Extended_Pictographic# E0.6 [1] (⛺) tent
+26FB..26FC ; Extended_Pictographic# E0.0 [2] (⛻..⛼) JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL
+26FD ; Extended_Pictographic# E0.6 [1] (⛽) fuel pump
+26FE..2701 ; Extended_Pictographic# E0.0 [4] (⛾..✁) CUP ON BLACK SQUARE..UPPER BLADE SCISSORS
+2702 ; Extended_Pictographic# E0.6 [1] (✂️) scissors
+2703..2704 ; Extended_Pictographic# E0.0 [2] (✃..✄) LOWER BLADE SCISSORS..WHITE SCISSORS
+2705 ; Extended_Pictographic# E0.6 [1] (✅) check mark button
+2708..270C ; Extended_Pictographic# E0.6 [5] (✈️..✌️) airplane..victory hand
+270D ; Extended_Pictographic# E0.7 [1] (✍️) writing hand
+270E ; Extended_Pictographic# E0.0 [1] (✎) LOWER RIGHT PENCIL
+270F ; Extended_Pictographic# E0.6 [1] (✏️) pencil
+2710..2711 ; Extended_Pictographic# E0.0 [2] (✐..✑) UPPER RIGHT PENCIL..WHITE NIB
+2712 ; Extended_Pictographic# E0.6 [1] (✒️) black nib
+2714 ; Extended_Pictographic# E0.6 [1] (✔️) check mark
+2716 ; Extended_Pictographic# E0.6 [1] (✖️) multiply
+271D ; Extended_Pictographic# E0.7 [1] (✝️) latin cross
+2721 ; Extended_Pictographic# E0.7 [1] (✡️) star of David
+2728 ; Extended_Pictographic# E0.6 [1] (✨) sparkles
+2733..2734 ; Extended_Pictographic# E0.6 [2] (✳️..✴️) eight-spoked asterisk..eight-pointed star
+2744 ; Extended_Pictographic# E0.6 [1] (❄️) snowflake
+2747 ; Extended_Pictographic# E0.6 [1] (❇️) sparkle
+274C ; Extended_Pictographic# E0.6 [1] (❌) cross mark
+274E ; Extended_Pictographic# E0.6 [1] (❎) cross mark button
+2753..2755 ; Extended_Pictographic# E0.6 [3] (❓..❕) red question mark..white exclamation mark
+2757 ; Extended_Pictographic# E0.6 [1] (❗) red exclamation mark
+2763 ; Extended_Pictographic# E1.0 [1] (❣️) heart exclamation
+2764 ; Extended_Pictographic# E0.6 [1] (❤️) red heart
+2765..2767 ; Extended_Pictographic# E0.0 [3] (❥..❧) ROTATED HEAVY BLACK HEART BULLET..ROTATED FLORAL HEART BULLET
+2795..2797 ; Extended_Pictographic# E0.6 [3] (➕..➗) plus..divide
+27A1 ; Extended_Pictographic# E0.6 [1] (➡️) right arrow
+27B0 ; Extended_Pictographic# E0.6 [1] (➰) curly loop
+27BF ; Extended_Pictographic# E1.0 [1] (➿) double curly loop
+2934..2935 ; Extended_Pictographic# E0.6 [2] (⤴️..⤵️) right arrow curving up..right arrow curving down
+2B05..2B07 ; Extended_Pictographic# E0.6 [3] (⬅️..⬇️) left arrow..down arrow
+2B1B..2B1C ; Extended_Pictographic# E0.6 [2] (⬛..⬜) black large square..white large square
+2B50 ; Extended_Pictographic# E0.6 [1] (⭐) star
+2B55 ; Extended_Pictographic# E0.6 [1] (⭕) hollow red circle
+3030 ; Extended_Pictographic# E0.6 [1] (〰️) wavy dash
+303D ; Extended_Pictographic# E0.6 [1] (〽️) part alternation mark
+3297 ; Extended_Pictographic# E0.6 [1] (㊗️) Japanese “congratulations” button
+3299 ; Extended_Pictographic# E0.6 [1] (㊙️) Japanese “secret” button
+1F000..1F003 ; Extended_Pictographic# E0.0 [4] (🀀..🀃) MAHJONG TILE EAST WIND..MAHJONG TILE NORTH WIND
+1F004 ; Extended_Pictographic# E0.6 [1] (🀄) mahjong red dragon
+1F005..1F0CE ; Extended_Pictographic# E0.0 [202] (🀅..🃎) MAHJONG TILE GREEN DRAGON..PLAYING CARD KING OF DIAMONDS
+1F0CF ; Extended_Pictographic# E0.6 [1] (🃏) joker
+1F0D0..1F0FF ; Extended_Pictographic# E0.0 [48] (🃐..🃿) <reserved-1F0D0>..<reserved-1F0FF>
+1F10D..1F10F ; Extended_Pictographic# E0.0 [3] (🄍..🄏) CIRCLED ZERO WITH SLASH..CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH
+1F12F ; Extended_Pictographic# E0.0 [1] (🄯) COPYLEFT SYMBOL
+1F16C..1F16F ; Extended_Pictographic# E0.0 [4] (🅬..🅯) RAISED MR SIGN..CIRCLED HUMAN FIGURE
+1F170..1F171 ; Extended_Pictographic# E0.6 [2] (🅰️..🅱️) A button (blood type)..B button (blood type)
+1F17E..1F17F ; Extended_Pictographic# E0.6 [2] (🅾️..🅿️) O button (blood type)..P button
+1F18E ; Extended_Pictographic# E0.6 [1] (🆎) AB button (blood type)
+1F191..1F19A ; Extended_Pictographic# E0.6 [10] (🆑..🆚) CL button..VS button
+1F1AD..1F1E5 ; Extended_Pictographic# E0.0 [57] (🆭..🇥) MASK WORK SYMBOL..<reserved-1F1E5>
+1F201..1F202 ; Extended_Pictographic# E0.6 [2] (🈁..🈂️) Japanese “here” button..Japanese “service charge” button
+1F203..1F20F ; Extended_Pictographic# E0.0 [13] (🈃..🈏) <reserved-1F203>..<reserved-1F20F>
+1F21A ; Extended_Pictographic# E0.6 [1] (🈚) Japanese “free of charge” button
+1F22F ; Extended_Pictographic# E0.6 [1] (🈯) Japanese “reserved” button
+1F232..1F23A ; Extended_Pictographic# E0.6 [9] (🈲..🈺) Japanese “prohibited” button..Japanese “open for business” button
+1F23C..1F23F ; Extended_Pictographic# E0.0 [4] (🈼..🈿) <reserved-1F23C>..<reserved-1F23F>
+1F249..1F24F ; Extended_Pictographic# E0.0 [7] (🉉..🉏) <reserved-1F249>..<reserved-1F24F>
+1F250..1F251 ; Extended_Pictographic# E0.6 [2] (🉐..🉑) Japanese “bargain” button..Japanese “acceptable” button
+1F252..1F2FF ; Extended_Pictographic# E0.0 [174] (🉒..🋿) <reserved-1F252>..<reserved-1F2FF>
+1F300..1F30C ; Extended_Pictographic# E0.6 [13] (🌀..🌌) cyclone..milky way
+1F30D..1F30E ; Extended_Pictographic# E0.7 [2] (🌍..🌎) globe showing Europe-Africa..globe showing Americas
+1F30F ; Extended_Pictographic# E0.6 [1] (🌏) globe showing Asia-Australia
+1F310 ; Extended_Pictographic# E1.0 [1] (🌐) globe with meridians
+1F311 ; Extended_Pictographic# E0.6 [1] (🌑) new moon
+1F312 ; Extended_Pictographic# E1.0 [1] (🌒) waxing crescent moon
+1F313..1F315 ; Extended_Pictographic# E0.6 [3] (🌓..🌕) first quarter moon..full moon
+1F316..1F318 ; Extended_Pictographic# E1.0 [3] (🌖..🌘) waning gibbous moon..waning crescent moon
+1F319 ; Extended_Pictographic# E0.6 [1] (🌙) crescent moon
+1F31A ; Extended_Pictographic# E1.0 [1] (🌚) new moon face
+1F31B ; Extended_Pictographic# E0.6 [1] (🌛) first quarter moon face
+1F31C ; Extended_Pictographic# E0.7 [1] (🌜) last quarter moon face
+1F31D..1F31E ; Extended_Pictographic# E1.0 [2] (🌝..🌞) full moon face..sun with face
+1F31F..1F320 ; Extended_Pictographic# E0.6 [2] (🌟..🌠) glowing star..shooting star
+1F321 ; Extended_Pictographic# E0.7 [1] (🌡️) thermometer
+1F322..1F323 ; Extended_Pictographic# E0.0 [2] (🌢..🌣) BLACK DROPLET..WHITE SUN
+1F324..1F32C ; Extended_Pictographic# E0.7 [9] (🌤️..🌬️) sun behind small cloud..wind face
+1F32D..1F32F ; Extended_Pictographic# E1.0 [3] (🌭..🌯) hot dog..burrito
+1F330..1F331 ; Extended_Pictographic# E0.6 [2] (🌰..🌱) chestnut..seedling
+1F332..1F333 ; Extended_Pictographic# E1.0 [2] (🌲..🌳) evergreen tree..deciduous tree
+1F334..1F335 ; Extended_Pictographic# E0.6 [2] (🌴..🌵) palm tree..cactus
+1F336 ; Extended_Pictographic# E0.7 [1] (🌶️) hot pepper
+1F337..1F34A ; Extended_Pictographic# E0.6 [20] (🌷..🍊) tulip..tangerine
+1F34B ; Extended_Pictographic# E1.0 [1] (🍋) lemon
+1F34C..1F34F ; Extended_Pictographic# E0.6 [4] (🍌..🍏) banana..green apple
+1F350 ; Extended_Pictographic# E1.0 [1] (🍐) pear
+1F351..1F37B ; Extended_Pictographic# E0.6 [43] (🍑..🍻) peach..clinking beer mugs
+1F37C ; Extended_Pictographic# E1.0 [1] (🍼) baby bottle
+1F37D ; Extended_Pictographic# E0.7 [1] (🍽️) fork and knife with plate
+1F37E..1F37F ; Extended_Pictographic# E1.0 [2] (🍾..🍿) bottle with popping cork..popcorn
+1F380..1F393 ; Extended_Pictographic# E0.6 [20] (🎀..🎓) ribbon..graduation cap
+1F394..1F395 ; Extended_Pictographic# E0.0 [2] (🎔..🎕) HEART WITH TIP ON THE LEFT..BOUQUET OF FLOWERS
+1F396..1F397 ; Extended_Pictographic# E0.7 [2] (🎖️..🎗️) military medal..reminder ribbon
+1F398 ; Extended_Pictographic# E0.0 [1] (🎘) MUSICAL KEYBOARD WITH JACKS
+1F399..1F39B ; Extended_Pictographic# E0.7 [3] (🎙️..🎛️) studio microphone..control knobs
+1F39C..1F39D ; Extended_Pictographic# E0.0 [2] (🎜..🎝) BEAMED ASCENDING MUSICAL NOTES..BEAMED DESCENDING MUSICAL NOTES
+1F39E..1F39F ; Extended_Pictographic# E0.7 [2] (🎞️..🎟️) film frames..admission tickets
+1F3A0..1F3C4 ; Extended_Pictographic# E0.6 [37] (🎠..🏄) carousel horse..person surfing
+1F3C5 ; Extended_Pictographic# E1.0 [1] (🏅) sports medal
+1F3C6 ; Extended_Pictographic# E0.6 [1] (🏆) trophy
+1F3C7 ; Extended_Pictographic# E1.0 [1] (🏇) horse racing
+1F3C8 ; Extended_Pictographic# E0.6 [1] (🏈) american football
+1F3C9 ; Extended_Pictographic# E1.0 [1] (🏉) rugby football
+1F3CA ; Extended_Pictographic# E0.6 [1] (🏊) person swimming
+1F3CB..1F3CE ; Extended_Pictographic# E0.7 [4] (🏋️..🏎️) person lifting weights..racing car
+1F3CF..1F3D3 ; Extended_Pictographic# E1.0 [5] (🏏..🏓) cricket game..ping pong
+1F3D4..1F3DF ; Extended_Pictographic# E0.7 [12] (🏔️..🏟️) snow-capped mountain..stadium
+1F3E0..1F3E3 ; Extended_Pictographic# E0.6 [4] (🏠..🏣) house..Japanese post office
+1F3E4 ; Extended_Pictographic# E1.0 [1] (🏤) post office
+1F3E5..1F3F0 ; Extended_Pictographic# E0.6 [12] (🏥..🏰) hospital..castle
+1F3F1..1F3F2 ; Extended_Pictographic# E0.0 [2] (🏱..🏲) WHITE PENNANT..BLACK PENNANT
+1F3F3 ; Extended_Pictographic# E0.7 [1] (🏳️) white flag
+1F3F4 ; Extended_Pictographic# E1.0 [1] (🏴) black flag
+1F3F5 ; Extended_Pictographic# E0.7 [1] (🏵️) rosette
+1F3F6 ; Extended_Pictographic# E0.0 [1] (🏶) BLACK ROSETTE
+1F3F7 ; Extended_Pictographic# E0.7 [1] (🏷️) label
+1F3F8..1F3FA ; Extended_Pictographic# E1.0 [3] (🏸..🏺) badminton..amphora
+1F400..1F407 ; Extended_Pictographic# E1.0 [8] (🐀..🐇) rat..rabbit
+1F408 ; Extended_Pictographic# E0.7 [1] (🐈) cat
+1F409..1F40B ; Extended_Pictographic# E1.0 [3] (🐉..🐋) dragon..whale
+1F40C..1F40E ; Extended_Pictographic# E0.6 [3] (🐌..🐎) snail..horse
+1F40F..1F410 ; Extended_Pictographic# E1.0 [2] (🐏..🐐) ram..goat
+1F411..1F412 ; Extended_Pictographic# E0.6 [2] (🐑..🐒) ewe..monkey
+1F413 ; Extended_Pictographic# E1.0 [1] (🐓) rooster
+1F414 ; Extended_Pictographic# E0.6 [1] (🐔) chicken
+1F415 ; Extended_Pictographic# E0.7 [1] (🐕) dog
+1F416 ; Extended_Pictographic# E1.0 [1] (🐖) pig
+1F417..1F429 ; Extended_Pictographic# E0.6 [19] (🐗..🐩) boar..poodle
+1F42A ; Extended_Pictographic# E1.0 [1] (🐪) camel
+1F42B..1F43E ; Extended_Pictographic# E0.6 [20] (🐫..🐾) two-hump camel..paw prints
+1F43F ; Extended_Pictographic# E0.7 [1] (🐿️) chipmunk
+1F440 ; Extended_Pictographic# E0.6 [1] (👀) eyes
+1F441 ; Extended_Pictographic# E0.7 [1] (👁️) eye
+1F442..1F464 ; Extended_Pictographic# E0.6 [35] (👂..👤) ear..bust in silhouette
+1F465 ; Extended_Pictographic# E1.0 [1] (👥) busts in silhouette
+1F466..1F46B ; Extended_Pictographic# E0.6 [6] (👦..👫) boy..woman and man holding hands
+1F46C..1F46D ; Extended_Pictographic# E1.0 [2] (👬..👭) men holding hands..women holding hands
+1F46E..1F4AC ; Extended_Pictographic# E0.6 [63] (👮..💬) police officer..speech balloon
+1F4AD ; Extended_Pictographic# E1.0 [1] (💭) thought balloon
+1F4AE..1F4B5 ; Extended_Pictographic# E0.6 [8] (💮..💵) white flower..dollar banknote
+1F4B6..1F4B7 ; Extended_Pictographic# E1.0 [2] (💶..💷) euro banknote..pound banknote
+1F4B8..1F4EB ; Extended_Pictographic# E0.6 [52] (💸..📫) money with wings..closed mailbox with raised flag
+1F4EC..1F4ED ; Extended_Pictographic# E0.7 [2] (📬..📭) open mailbox with raised flag..open mailbox with lowered flag
+1F4EE ; Extended_Pictographic# E0.6 [1] (📮) postbox
+1F4EF ; Extended_Pictographic# E1.0 [1] (📯) postal horn
+1F4F0..1F4F4 ; Extended_Pictographic# E0.6 [5] (📰..📴) newspaper..mobile phone off
+1F4F5 ; Extended_Pictographic# E1.0 [1] (📵) no mobile phones
+1F4F6..1F4F7 ; Extended_Pictographic# E0.6 [2] (📶..📷) antenna bars..camera
+1F4F8 ; Extended_Pictographic# E1.0 [1] (📸) camera with flash
+1F4F9..1F4FC ; Extended_Pictographic# E0.6 [4] (📹..📼) video camera..videocassette
+1F4FD ; Extended_Pictographic# E0.7 [1] (📽️) film projector
+1F4FE ; Extended_Pictographic# E0.0 [1] (📾) PORTABLE STEREO
+1F4FF..1F502 ; Extended_Pictographic# E1.0 [4] (📿..🔂) prayer beads..repeat single button
+1F503 ; Extended_Pictographic# E0.6 [1] (🔃) clockwise vertical arrows
+1F504..1F507 ; Extended_Pictographic# E1.0 [4] (🔄..🔇) counterclockwise arrows button..muted speaker
+1F508 ; Extended_Pictographic# E0.7 [1] (🔈) speaker low volume
+1F509 ; Extended_Pictographic# E1.0 [1] (🔉) speaker medium volume
+1F50A..1F514 ; Extended_Pictographic# E0.6 [11] (🔊..🔔) speaker high volume..bell
+1F515 ; Extended_Pictographic# E1.0 [1] (🔕) bell with slash
+1F516..1F52B ; Extended_Pictographic# E0.6 [22] (🔖..🔫) bookmark..water pistol
+1F52C..1F52D ; Extended_Pictographic# E1.0 [2] (🔬..🔭) microscope..telescope
+1F52E..1F53D ; Extended_Pictographic# E0.6 [16] (🔮..🔽) crystal ball..downwards button
+1F546..1F548 ; Extended_Pictographic# E0.0 [3] (🕆..🕈) WHITE LATIN CROSS..CELTIC CROSS
+1F549..1F54A ; Extended_Pictographic# E0.7 [2] (🕉️..🕊️) om..dove
+1F54B..1F54E ; Extended_Pictographic# E1.0 [4] (🕋..🕎) kaaba..menorah
+1F54F ; Extended_Pictographic# E0.0 [1] (🕏) BOWL OF HYGIEIA
+1F550..1F55B ; Extended_Pictographic# E0.6 [12] (🕐..🕛) one o’clock..twelve o’clock
+1F55C..1F567 ; Extended_Pictographic# E0.7 [12] (🕜..🕧) one-thirty..twelve-thirty
+1F568..1F56E ; Extended_Pictographic# E0.0 [7] (🕨..🕮) RIGHT SPEAKER..BOOK
+1F56F..1F570 ; Extended_Pictographic# E0.7 [2] (🕯️..🕰️) candle..mantelpiece clock
+1F571..1F572 ; Extended_Pictographic# E0.0 [2] (🕱..🕲) BLACK SKULL AND CROSSBONES..NO PIRACY
+1F573..1F579 ; Extended_Pictographic# E0.7 [7] (🕳️..🕹️) hole..joystick
+1F57A ; Extended_Pictographic# E3.0 [1] (🕺) man dancing
+1F57B..1F586 ; Extended_Pictographic# E0.0 [12] (🕻..🖆) LEFT HAND TELEPHONE RECEIVER..PEN OVER STAMPED ENVELOPE
+1F587 ; Extended_Pictographic# E0.7 [1] (🖇️) linked paperclips
+1F588..1F589 ; Extended_Pictographic# E0.0 [2] (🖈..🖉) BLACK PUSHPIN..LOWER LEFT PENCIL
+1F58A..1F58D ; Extended_Pictographic# E0.7 [4] (🖊️..🖍️) pen..crayon
+1F58E..1F58F ; Extended_Pictographic# E0.0 [2] (🖎..🖏) LEFT WRITING HAND..TURNED OK HAND SIGN
+1F590 ; Extended_Pictographic# E0.7 [1] (🖐️) hand with fingers splayed
+1F591..1F594 ; Extended_Pictographic# E0.0 [4] (🖑..🖔) REVERSED RAISED HAND WITH FINGERS SPLAYED..REVERSED VICTORY HAND
+1F595..1F596 ; Extended_Pictographic# E1.0 [2] (🖕..🖖) middle finger..vulcan salute
+1F597..1F5A3 ; Extended_Pictographic# E0.0 [13] (🖗..🖣) WHITE DOWN POINTING LEFT HAND INDEX..BLACK DOWN POINTING BACKHAND INDEX
+1F5A4 ; Extended_Pictographic# E3.0 [1] (🖤) black heart
+1F5A5 ; Extended_Pictographic# E0.7 [1] (🖥️) desktop computer
+1F5A6..1F5A7 ; Extended_Pictographic# E0.0 [2] (🖦..🖧) KEYBOARD AND MOUSE..THREE NETWORKED COMPUTERS
+1F5A8 ; Extended_Pictographic# E0.7 [1] (🖨️) printer
+1F5A9..1F5B0 ; Extended_Pictographic# E0.0 [8] (🖩..🖰) POCKET CALCULATOR..TWO BUTTON MOUSE
+1F5B1..1F5B2 ; Extended_Pictographic# E0.7 [2] (🖱️..🖲️) computer mouse..trackball
+1F5B3..1F5BB ; Extended_Pictographic# E0.0 [9] (🖳..🖻) OLD PERSONAL COMPUTER..DOCUMENT WITH PICTURE
+1F5BC ; Extended_Pictographic# E0.7 [1] (🖼️) framed picture
+1F5BD..1F5C1 ; Extended_Pictographic# E0.0 [5] (🖽..🗁) FRAME WITH TILES..OPEN FOLDER
+1F5C2..1F5C4 ; Extended_Pictographic# E0.7 [3] (🗂️..🗄️) card index dividers..file cabinet
+1F5C5..1F5D0 ; Extended_Pictographic# E0.0 [12] (🗅..🗐) EMPTY NOTE..PAGES
+1F5D1..1F5D3 ; Extended_Pictographic# E0.7 [3] (🗑️..🗓️) wastebasket..spiral calendar
+1F5D4..1F5DB ; Extended_Pictographic# E0.0 [8] (🗔..🗛) DESKTOP WINDOW..DECREASE FONT SIZE SYMBOL
+1F5DC..1F5DE ; Extended_Pictographic# E0.7 [3] (🗜️..🗞️) clamp..rolled-up newspaper
+1F5DF..1F5E0 ; Extended_Pictographic# E0.0 [2] (🗟..🗠) PAGE WITH CIRCLED TEXT..STOCK CHART
+1F5E1 ; Extended_Pictographic# E0.7 [1] (🗡️) dagger
+1F5E2 ; Extended_Pictographic# E0.0 [1] (🗢) LIPS
+1F5E3 ; Extended_Pictographic# E0.7 [1] (🗣️) speaking head
+1F5E4..1F5E7 ; Extended_Pictographic# E0.0 [4] (🗤..🗧) THREE RAYS ABOVE..THREE RAYS RIGHT
+1F5E8 ; Extended_Pictographic# E2.0 [1] (🗨️) left speech bubble
+1F5E9..1F5EE ; Extended_Pictographic# E0.0 [6] (🗩..🗮) RIGHT SPEECH BUBBLE..LEFT ANGER BUBBLE
+1F5EF ; Extended_Pictographic# E0.7 [1] (🗯️) right anger bubble
+1F5F0..1F5F2 ; Extended_Pictographic# E0.0 [3] (🗰..🗲) MOOD BUBBLE..LIGHTNING MOOD
+1F5F3 ; Extended_Pictographic# E0.7 [1] (🗳️) ballot box with ballot
+1F5F4..1F5F9 ; Extended_Pictographic# E0.0 [6] (🗴..🗹) BALLOT SCRIPT X..BALLOT BOX WITH BOLD CHECK
+1F5FA ; Extended_Pictographic# E0.7 [1] (🗺️) world map
+1F5FB..1F5FF ; Extended_Pictographic# E0.6 [5] (🗻..🗿) mount fuji..moai
+1F600 ; Extended_Pictographic# E1.0 [1] (😀) grinning face
+1F601..1F606 ; Extended_Pictographic# E0.6 [6] (😁..😆) beaming face with smiling eyes..grinning squinting face
+1F607..1F608 ; Extended_Pictographic# E1.0 [2] (😇..😈) smiling face with halo..smiling face with horns
+1F609..1F60D ; Extended_Pictographic# E0.6 [5] (😉..😍) winking face..smiling face with heart-eyes
+1F60E ; Extended_Pictographic# E1.0 [1] (😎) smiling face with sunglasses
+1F60F ; Extended_Pictographic# E0.6 [1] (😏) smirking face
+1F610 ; Extended_Pictographic# E0.7 [1] (😐) neutral face
+1F611 ; Extended_Pictographic# E1.0 [1] (😑) expressionless face
+1F612..1F614 ; Extended_Pictographic# E0.6 [3] (😒..😔) unamused face..pensive face
+1F615 ; Extended_Pictographic# E1.0 [1] (😕) confused face
+1F616 ; Extended_Pictographic# E0.6 [1] (😖) confounded face
+1F617 ; Extended_Pictographic# E1.0 [1] (😗) kissing face
+1F618 ; Extended_Pictographic# E0.6 [1] (😘) face blowing a kiss
+1F619 ; Extended_Pictographic# E1.0 [1] (😙) kissing face with smiling eyes
+1F61A ; Extended_Pictographic# E0.6 [1] (😚) kissing face with closed eyes
+1F61B ; Extended_Pictographic# E1.0 [1] (😛) face with tongue
+1F61C..1F61E ; Extended_Pictographic# E0.6 [3] (😜..😞) winking face with tongue..disappointed face
+1F61F ; Extended_Pictographic# E1.0 [1] (😟) worried face
+1F620..1F625 ; Extended_Pictographic# E0.6 [6] (😠..😥) angry face..sad but relieved face
+1F626..1F627 ; Extended_Pictographic# E1.0 [2] (😦..😧) frowning face with open mouth..anguished face
+1F628..1F62B ; Extended_Pictographic# E0.6 [4] (😨..😫) fearful face..tired face
+1F62C ; Extended_Pictographic# E1.0 [1] (😬) grimacing face
+1F62D ; Extended_Pictographic# E0.6 [1] (😭) loudly crying face
+1F62E..1F62F ; Extended_Pictographic# E1.0 [2] (😮..😯) face with open mouth..hushed face
+1F630..1F633 ; Extended_Pictographic# E0.6 [4] (😰..😳) anxious face with sweat..flushed face
+1F634 ; Extended_Pictographic# E1.0 [1] (😴) sleeping face
+1F635 ; Extended_Pictographic# E0.6 [1] (😵) face with crossed-out eyes
+1F636 ; Extended_Pictographic# E1.0 [1] (😶) face without mouth
+1F637..1F640 ; Extended_Pictographic# E0.6 [10] (😷..🙀) face with medical mask..weary cat
+1F641..1F644 ; Extended_Pictographic# E1.0 [4] (🙁..🙄) slightly frowning face..face with rolling eyes
+1F645..1F64F ; Extended_Pictographic# E0.6 [11] (🙅..🙏) person gesturing NO..folded hands
+1F680 ; Extended_Pictographic# E0.6 [1] (🚀) rocket
+1F681..1F682 ; Extended_Pictographic# E1.0 [2] (🚁..🚂) helicopter..locomotive
+1F683..1F685 ; Extended_Pictographic# E0.6 [3] (🚃..🚅) railway car..bullet train
+1F686 ; Extended_Pictographic# E1.0 [1] (🚆) train
+1F687 ; Extended_Pictographic# E0.6 [1] (🚇) metro
+1F688 ; Extended_Pictographic# E1.0 [1] (🚈) light rail
+1F689 ; Extended_Pictographic# E0.6 [1] (🚉) station
+1F68A..1F68B ; Extended_Pictographic# E1.0 [2] (🚊..🚋) tram..tram car
+1F68C ; Extended_Pictographic# E0.6 [1] (🚌) bus
+1F68D ; Extended_Pictographic# E0.7 [1] (🚍) oncoming bus
+1F68E ; Extended_Pictographic# E1.0 [1] (🚎) trolleybus
+1F68F ; Extended_Pictographic# E0.6 [1] (🚏) bus stop
+1F690 ; Extended_Pictographic# E1.0 [1] (🚐) minibus
+1F691..1F693 ; Extended_Pictographic# E0.6 [3] (🚑..🚓) ambulance..police car
+1F694 ; Extended_Pictographic# E0.7 [1] (🚔) oncoming police car
+1F695 ; Extended_Pictographic# E0.6 [1] (🚕) taxi
+1F696 ; Extended_Pictographic# E1.0 [1] (🚖) oncoming taxi
+1F697 ; Extended_Pictographic# E0.6 [1] (🚗) automobile
+1F698 ; Extended_Pictographic# E0.7 [1] (🚘) oncoming automobile
+1F699..1F69A ; Extended_Pictographic# E0.6 [2] (🚙..🚚) sport utility vehicle..delivery truck
+1F69B..1F6A1 ; Extended_Pictographic# E1.0 [7] (🚛..🚡) articulated lorry..aerial tramway
+1F6A2 ; Extended_Pictographic# E0.6 [1] (🚢) ship
+1F6A3 ; Extended_Pictographic# E1.0 [1] (🚣) person rowing boat
+1F6A4..1F6A5 ; Extended_Pictographic# E0.6 [2] (🚤..🚥) speedboat..horizontal traffic light
+1F6A6 ; Extended_Pictographic# E1.0 [1] (🚦) vertical traffic light
+1F6A7..1F6AD ; Extended_Pictographic# E0.6 [7] (🚧..🚭) construction..no smoking
+1F6AE..1F6B1 ; Extended_Pictographic# E1.0 [4] (🚮..🚱) litter in bin sign..non-potable water
+1F6B2 ; Extended_Pictographic# E0.6 [1] (🚲) bicycle
+1F6B3..1F6B5 ; Extended_Pictographic# E1.0 [3] (🚳..🚵) no bicycles..person mountain biking
+1F6B6 ; Extended_Pictographic# E0.6 [1] (🚶) person walking
+1F6B7..1F6B8 ; Extended_Pictographic# E1.0 [2] (🚷..🚸) no pedestrians..children crossing
+1F6B9..1F6BE ; Extended_Pictographic# E0.6 [6] (🚹..🚾) men’s room..water closet
+1F6BF ; Extended_Pictographic# E1.0 [1] (🚿) shower
+1F6C0 ; Extended_Pictographic# E0.6 [1] (🛀) person taking bath
+1F6C1..1F6C5 ; Extended_Pictographic# E1.0 [5] (🛁..🛅) bathtub..left luggage
+1F6C6..1F6CA ; Extended_Pictographic# E0.0 [5] (🛆..🛊) TRIANGLE WITH ROUNDED CORNERS..GIRLS SYMBOL
+1F6CB ; Extended_Pictographic# E0.7 [1] (🛋️) couch and lamp
+1F6CC ; Extended_Pictographic# E1.0 [1] (🛌) person in bed
+1F6CD..1F6CF ; Extended_Pictographic# E0.7 [3] (🛍️..🛏️) shopping bags..bed
+1F6D0 ; Extended_Pictographic# E1.0 [1] (🛐) place of worship
+1F6D1..1F6D2 ; Extended_Pictographic# E3.0 [2] (🛑..🛒) stop sign..shopping cart
+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>
+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
+1F6E9 ; Extended_Pictographic# E0.7 [1] (🛩️) small airplane
+1F6EA ; Extended_Pictographic# E0.0 [1] (🛪) NORTHEAST-POINTING AIRPLANE
+1F6EB..1F6EC ; Extended_Pictographic# E1.0 [2] (🛫..🛬) airplane departure..airplane arrival
+1F6ED..1F6EF ; Extended_Pictographic# E0.0 [3] (🛭..🛯) <reserved-1F6ED>..<reserved-1F6EF>
+1F6F0 ; Extended_Pictographic# E0.7 [1] (🛰️) satellite
+1F6F1..1F6F2 ; Extended_Pictographic# E0.0 [2] (🛱..🛲) ONCOMING FIRE ENGINE..DIESEL LOCOMOTIVE
+1F6F3 ; Extended_Pictographic# E0.7 [1] (🛳️) passenger ship
+1F6F4..1F6F6 ; Extended_Pictographic# E3.0 [3] (🛴..🛶) kick scooter..canoe
+1F6F7..1F6F8 ; Extended_Pictographic# E5.0 [2] (🛷..🛸) sled..flying saucer
+1F6F9 ; Extended_Pictographic# E11.0 [1] (🛹) skateboard
+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>
+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>
+1F7F0 ; Extended_Pictographic# E14.0 [1] (🟰) heavy equals sign
+1F7F1..1F7FF ; Extended_Pictographic# E0.0 [15] (🟱..🟿) <reserved-1F7F1>..<reserved-1F7FF>
+1F80C..1F80F ; Extended_Pictographic# E0.0 [4] (🠌..🠏) <reserved-1F80C>..<reserved-1F80F>
+1F848..1F84F ; Extended_Pictographic# E0.0 [8] (🡈..🡏) <reserved-1F848>..<reserved-1F84F>
+1F85A..1F85F ; Extended_Pictographic# E0.0 [6] (🡚..🡟) <reserved-1F85A>..<reserved-1F85F>
+1F888..1F88F ; Extended_Pictographic# E0.0 [8] (🢈..🢏) <reserved-1F888>..<reserved-1F88F>
+1F8AE..1F8FF ; Extended_Pictographic# E0.0 [82] (🢮..🣿) <reserved-1F8AE>..<reserved-1F8FF>
+1F90C ; Extended_Pictographic# E13.0 [1] (🤌) pinched fingers
+1F90D..1F90F ; Extended_Pictographic# E12.0 [3] (🤍..🤏) white heart..pinching hand
+1F910..1F918 ; Extended_Pictographic# E1.0 [9] (🤐..🤘) zipper-mouth face..sign of the horns
+1F919..1F91E ; Extended_Pictographic# E3.0 [6] (🤙..🤞) call me hand..crossed fingers
+1F91F ; Extended_Pictographic# E5.0 [1] (🤟) love-you gesture
+1F920..1F927 ; Extended_Pictographic# E3.0 [8] (🤠..🤧) cowboy hat face..sneezing face
+1F928..1F92F ; Extended_Pictographic# E5.0 [8] (🤨..🤯) face with raised eyebrow..exploding head
+1F930 ; Extended_Pictographic# E3.0 [1] (🤰) pregnant woman
+1F931..1F932 ; Extended_Pictographic# E5.0 [2] (🤱..🤲) breast-feeding..palms up together
+1F933..1F93A ; Extended_Pictographic# E3.0 [8] (🤳..🤺) selfie..person fencing
+1F93C..1F93E ; Extended_Pictographic# E3.0 [3] (🤼..🤾) people wrestling..person playing handball
+1F93F ; Extended_Pictographic# E12.0 [1] (🤿) diving mask
+1F940..1F945 ; Extended_Pictographic# E3.0 [6] (🥀..🥅) wilted flower..goal net
+1F947..1F94B ; Extended_Pictographic# E3.0 [5] (🥇..🥋) 1st place medal..martial arts uniform
+1F94C ; Extended_Pictographic# E5.0 [1] (🥌) curling stone
+1F94D..1F94F ; Extended_Pictographic# E11.0 [3] (🥍..🥏) lacrosse..flying disc
+1F950..1F95E ; Extended_Pictographic# E3.0 [15] (🥐..🥞) croissant..pancakes
+1F95F..1F96B ; Extended_Pictographic# E5.0 [13] (🥟..🥫) dumpling..canned food
+1F96C..1F970 ; Extended_Pictographic# E11.0 [5] (🥬..🥰) leafy green..smiling face with hearts
+1F971 ; Extended_Pictographic# E12.0 [1] (🥱) yawning face
+1F972 ; Extended_Pictographic# E13.0 [1] (🥲) smiling face with tear
+1F973..1F976 ; Extended_Pictographic# E11.0 [4] (🥳..🥶) partying face..cold face
+1F977..1F978 ; Extended_Pictographic# E13.0 [2] (🥷..🥸) ninja..disguised face
+1F979 ; Extended_Pictographic# E14.0 [1] (🥹) face holding back tears
+1F97A ; Extended_Pictographic# E11.0 [1] (🥺) pleading face
+1F97B ; Extended_Pictographic# E12.0 [1] (🥻) sari
+1F97C..1F97F ; Extended_Pictographic# E11.0 [4] (🥼..🥿) lab coat..flat shoe
+1F980..1F984 ; Extended_Pictographic# E1.0 [5] (🦀..🦄) crab..unicorn
+1F985..1F991 ; Extended_Pictographic# E3.0 [13] (🦅..🦑) eagle..squid
+1F992..1F997 ; Extended_Pictographic# E5.0 [6] (🦒..🦗) giraffe..cricket
+1F998..1F9A2 ; Extended_Pictographic# E11.0 [11] (🦘..🦢) kangaroo..swan
+1F9A3..1F9A4 ; Extended_Pictographic# E13.0 [2] (🦣..🦤) mammoth..dodo
+1F9A5..1F9AA ; Extended_Pictographic# E12.0 [6] (🦥..🦪) sloth..oyster
+1F9AB..1F9AD ; Extended_Pictographic# E13.0 [3] (🦫..🦭) beaver..seal
+1F9AE..1F9AF ; Extended_Pictographic# E12.0 [2] (🦮..🦯) guide dog..white cane
+1F9B0..1F9B9 ; Extended_Pictographic# E11.0 [10] (🦰..🦹) red hair..supervillain
+1F9BA..1F9BF ; Extended_Pictographic# E12.0 [6] (🦺..🦿) safety vest..mechanical leg
+1F9C0 ; Extended_Pictographic# E1.0 [1] (🧀) cheese wedge
+1F9C1..1F9C2 ; Extended_Pictographic# E11.0 [2] (🧁..🧂) cupcake..salt
+1F9C3..1F9CA ; Extended_Pictographic# E12.0 [8] (🧃..🧊) beverage box..ice
+1F9CB ; Extended_Pictographic# E13.0 [1] (🧋) bubble tea
+1F9CC ; Extended_Pictographic# E14.0 [1] (🧌) troll
+1F9CD..1F9CF ; Extended_Pictographic# E12.0 [3] (🧍..🧏) person standing..deaf person
+1F9D0..1F9E6 ; Extended_Pictographic# E5.0 [23] (🧐..🧦) face with monocle..socks
+1F9E7..1F9FF ; Extended_Pictographic# E11.0 [25] (🧧..🧿) red envelope..nazar amulet
+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>
+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>
+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>
+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>
+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>
+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>
+1FAE0..1FAE7 ; Extended_Pictographic# E14.0 [8] (🫠..🫧) melting face..bubbles
+1FAE8..1FAEF ; Extended_Pictographic# E0.0 [8] (🫨..🫯) <reserved-1FAE8>..<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>
+1FC00..1FFFD ; Extended_Pictographic# E0.0[1022] (🰀..🿽) <reserved-1FC00>..<reserved-1FFFD>
+
+# Total elements: 3537
+
+#EOF
diff --git a/admin/unidata/emoji-sequences.txt b/admin/unidata/emoji-sequences.txt
new file mode 100644
index 00000000000..dedf7ff543b
--- /dev/null
+++ b/admin/unidata/emoji-sequences.txt
@@ -0,0 +1,1469 @@
+# emoji-sequences.txt
+# Date: 2021-08-26, 17:22:22 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
+#
+# Emoji Sequence Data for UTS #51
+# Version: 14.0
+#
+# For documentation and usage, see http://www.unicode.org/reports/tr51
+#
+# Format:
+# code_point(s) ; type_field ; description # comments
+# Fields:
+# code_point(s): one or more code points in hex format, separated by spaces
+# type_field, one of the following:
+# Basic_Emoji
+# Emoji_Keycap_Sequence
+# RGI_Emoji_Flag_Sequence
+# RGI_Emoji_Tag_Sequence
+# RGI_Emoji_Modifier_Sequence
+# The type_field is a convenience for parsing the emoji sequence files, and is not intended to be maintained as a property.
+# short name: CLDR short name of sequence; characters may be escaped with \x{hex}.
+#
+# For the purpose of regular expressions, each of the type fields defines the name of
+# a binary property of strings. The short name of each property is the same as the long name.
+#
+# For the purpose of regular expressions, the property RGI_Emoji is defined as
+# a binary property of strings corresponding to ED-27 in UTS #51 Unicode Emoji.
+# That is, it is the union of the above properties plus RGI_Emoji_ZWJ_Sequence,
+# whose data is in emoji-zwj-sequences.txt.
+# The short name of RGI_Emoji is the same as the long name.
+#
+# Characters and sequences are listed in code point order. Users should be shown a more natural order.
+# See the CLDR collation order for Emoji.
+
+# ================================================
+
+# Basic_Emoji
+
+231A..231B ; Basic_Emoji ; watch # E0.6 [2] (⌚..⌛)
+23E9..23EC ; Basic_Emoji ; fast-forward 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] (♈..♓)
+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] (⛄..⛅)
+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] (⛲..⛳)
+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] (✊..✋)
+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] (❓..❕)
+2757 ; Basic_Emoji ; red exclamation mark # E0.6 [1] (❗)
+2795..2797 ; Basic_Emoji ; plus # 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] (⬛..⬜)
+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] (🆑..🆚)
+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] (🌍..🌎)
+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] (🌖..🌘)
+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] (🌷..🍊)
+1F34B ; Basic_Emoji ; lemon # E1.0 [1] (🍋)
+1F34C..1F34F ; Basic_Emoji ; banana # E0.6 [4] (🍌..🍏)
+1F350 ; Basic_Emoji ; pear # E1.0 [1] (🍐)
+1F351..1F37B ; Basic_Emoji ; peach # 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] (🎠..🏄)
+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] (🏠..🏣)
+1F3E4 ; Basic_Emoji ; post office # E1.0 [1] (🏤)
+1F3E5..1F3F0 ; Basic_Emoji ; hospital # E0.6 [12] (🏥..🏰)
+1F3F4 ; Basic_Emoji ; black flag # E1.0 [1] (🏴)
+1F3F8..1F407 ; Basic_Emoji ; badminton # 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] (🐑..🐒)
+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] (🐗..🐩)
+1F42A ; Basic_Emoji ; camel # E1.0 [1] (🐪)
+1F42B..1F43E ; Basic_Emoji ; two-hump camel # E0.6 [20] (🐫..🐾)
+1F440 ; Basic_Emoji ; eyes # E0.6 [1] (👀)
+1F442..1F464 ; Basic_Emoji ; ear # 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] (👮..💬)
+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] (📬..📭)
+1F4EE ; Basic_Emoji ; postbox # E0.6 [1] (📮)
+1F4EF ; Basic_Emoji ; postal horn # E1.0 [1] (📯)
+1F4F0..1F4F4 ; Basic_Emoji ; newspaper # E0.6 [5] (📰..📴)
+1F4F5 ; Basic_Emoji ; no mobile phones # E1.0 [1] (📵)
+1F4F6..1F4F7 ; Basic_Emoji ; antenna bars # 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] (📿..🔂)
+1F503 ; Basic_Emoji ; clockwise vertical arrows # E0.6 [1] (🔃)
+1F504..1F507 ; Basic_Emoji ; counterclockwise arrows button # 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] (🔊..🔔)
+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] (🕜..🕧)
+1F57A ; Basic_Emoji ; man dancing # E3.0 [1] (🕺)
+1F595..1F596 ; Basic_Emoji ; middle finger # E1.0 [2] (🖕..🖖)
+1F5A4 ; Basic_Emoji ; black heart # E3.0 [1] (🖤)
+1F5FB..1F5FF ; Basic_Emoji ; mount fuji # 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] (😉..😍)
+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] (😒..😔)
+1F615 ; Basic_Emoji ; confused face # E1.0 [1] (😕)
+1F616 ; Basic_Emoji ; confounded face # E0.6 [1] (😖)
+1F617 ; Basic_Emoji ; kissing face # E1.0 [1] (😗)
+1F618 ; Basic_Emoji ; face blowing a kiss # E0.6 [1] (😘)
+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] (😜..😞)
+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] (😨..😫)
+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] (😰..😳)
+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] (🙅..🙏)
+1F680 ; Basic_Emoji ; rocket # E0.6 [1] (🚀)
+1F681..1F682 ; Basic_Emoji ; helicopter # E1.0 [2] (🚁..🚂)
+1F683..1F685 ; Basic_Emoji ; railway car # 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] (🚊..🚋)
+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] (🚑..🚓)
+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] (🚛..🚡)
+1F6A2 ; Basic_Emoji ; ship # E0.6 [1] (🚢)
+1F6A3 ; Basic_Emoji ; person rowing boat # E1.0 [1] (🚣)
+1F6A4..1F6A5 ; Basic_Emoji ; speedboat # 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] (🚮..🚱)
+1F6B2 ; Basic_Emoji ; bicycle # E0.6 [1] (🚲)
+1F6B3..1F6B5 ; Basic_Emoji ; no bicycles # 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] (🚹..🚾)
+1F6BF ; Basic_Emoji ; shower # E1.0 [1] (🚿)
+1F6C0 ; Basic_Emoji ; person taking bath # E0.6 [1] (🛀)
+1F6C1..1F6C5 ; Basic_Emoji ; bathtub # 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] (🛑..🛒)
+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] (🛷..🛸)
+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] (🟠..🟫)
+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] (🤙..🤞)
+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] (🤨..🤯)
+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] (🤼..🤾)
+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] (🥇..🥋)
+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] (🥬..🥰)
+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] (🥷..🥸)
+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] (🦺..🦿)
+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] (🧃..🧊)
+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] (🩰..🩳)
+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] (🫰..🫶)
+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] (‼️)
+2049 FE0F ; Basic_Emoji ; exclamation question mark # E0.6 [1] (⁉️)
+2122 FE0F ; Basic_Emoji ; trade mark # E0.6 [1] (™️)
+2139 FE0F ; Basic_Emoji ; information # E0.6 [1] (ℹ️)
+2194 FE0F ; Basic_Emoji ; left-right arrow # E0.6 [1] (↔️)
+2195 FE0F ; Basic_Emoji ; up-down arrow # E0.6 [1] (↕️)
+2196 FE0F ; Basic_Emoji ; up-left arrow # E0.6 [1] (↖️)
+2197 FE0F ; Basic_Emoji ; up-right arrow # E0.6 [1] (↗️)
+2198 FE0F ; Basic_Emoji ; down-right arrow # E0.6 [1] (↘️)
+2199 FE0F ; Basic_Emoji ; down-left arrow # E0.6 [1] (↙️)
+21A9 FE0F ; Basic_Emoji ; right arrow curving left # E0.6 [1] (↩️)
+21AA FE0F ; Basic_Emoji ; left arrow curving right # E0.6 [1] (↪️)
+2328 FE0F ; Basic_Emoji ; keyboard # E1.0 [1] (⌨️)
+23CF FE0F ; Basic_Emoji ; eject button # E1.0 [1] (⏏️)
+23ED FE0F ; Basic_Emoji ; next track button # E0.7 [1] (⏭️)
+23EE FE0F ; Basic_Emoji ; last track button # E0.7 [1] (⏮️)
+23EF FE0F ; Basic_Emoji ; play or pause button # E1.0 [1] (⏯️)
+23F1 FE0F ; Basic_Emoji ; stopwatch # E1.0 [1] (⏱️)
+23F2 FE0F ; Basic_Emoji ; timer clock # E1.0 [1] (⏲️)
+23F8 FE0F ; Basic_Emoji ; pause button # E0.7 [1] (⏸️)
+23F9 FE0F ; Basic_Emoji ; stop button # E0.7 [1] (⏹️)
+23FA FE0F ; Basic_Emoji ; record button # E0.7 [1] (⏺️)
+24C2 FE0F ; Basic_Emoji ; circled M # E0.6 [1] (Ⓜ️)
+25AA FE0F ; Basic_Emoji ; black small square # E0.6 [1] (▪️)
+25AB FE0F ; Basic_Emoji ; white small square # E0.6 [1] (▫️)
+25B6 FE0F ; Basic_Emoji ; play button # E0.6 [1] (▶️)
+25C0 FE0F ; Basic_Emoji ; reverse button # E0.6 [1] (◀️)
+25FB FE0F ; Basic_Emoji ; white medium square # E0.6 [1] (◻️)
+25FC FE0F ; Basic_Emoji ; black medium square # E0.6 [1] (◼️)
+2600 FE0F ; Basic_Emoji ; sun # E0.6 [1] (☀️)
+2601 FE0F ; Basic_Emoji ; cloud # E0.6 [1] (☁️)
+2602 FE0F ; Basic_Emoji ; umbrella # E0.7 [1] (☂️)
+2603 FE0F ; Basic_Emoji ; snowman # E0.7 [1] (☃️)
+2604 FE0F ; Basic_Emoji ; comet # E1.0 [1] (☄️)
+260E FE0F ; Basic_Emoji ; telephone # E0.6 [1] (☎️)
+2611 FE0F ; Basic_Emoji ; check box with check # E0.6 [1] (☑️)
+2618 FE0F ; Basic_Emoji ; shamrock # E1.0 [1] (☘️)
+261D FE0F ; Basic_Emoji ; index pointing up # E0.6 [1] (☝️)
+2620 FE0F ; Basic_Emoji ; skull and crossbones # E1.0 [1] (☠️)
+2622 FE0F ; Basic_Emoji ; radioactive # E1.0 [1] (☢️)
+2623 FE0F ; Basic_Emoji ; biohazard # E1.0 [1] (☣️)
+2626 FE0F ; Basic_Emoji ; orthodox cross # E1.0 [1] (☦️)
+262A FE0F ; Basic_Emoji ; star and crescent # E0.7 [1] (☪️)
+262E FE0F ; Basic_Emoji ; peace symbol # E1.0 [1] (☮️)
+262F FE0F ; Basic_Emoji ; yin yang # E0.7 [1] (☯️)
+2638 FE0F ; Basic_Emoji ; wheel of dharma # E0.7 [1] (☸️)
+2639 FE0F ; Basic_Emoji ; frowning face # E0.7 [1] (☹️)
+263A FE0F ; Basic_Emoji ; smiling face # E0.6 [1] (☺️)
+2640 FE0F ; Basic_Emoji ; female sign # E4.0 [1] (♀️)
+2642 FE0F ; Basic_Emoji ; male sign # E4.0 [1] (♂️)
+265F FE0F ; Basic_Emoji ; chess pawn # E11.0 [1] (♟️)
+2660 FE0F ; Basic_Emoji ; spade suit # E0.6 [1] (♠️)
+2663 FE0F ; Basic_Emoji ; club suit # E0.6 [1] (♣️)
+2665 FE0F ; Basic_Emoji ; heart suit # E0.6 [1] (♥️)
+2666 FE0F ; Basic_Emoji ; diamond suit # E0.6 [1] (♦️)
+2668 FE0F ; Basic_Emoji ; hot springs # E0.6 [1] (♨️)
+267B FE0F ; Basic_Emoji ; recycling symbol # E0.6 [1] (♻️)
+267E FE0F ; Basic_Emoji ; infinity # E11.0 [1] (♾️)
+2692 FE0F ; Basic_Emoji ; hammer and pick # E1.0 [1] (⚒️)
+2694 FE0F ; Basic_Emoji ; crossed swords # E1.0 [1] (⚔️)
+2695 FE0F ; Basic_Emoji ; medical symbol # E4.0 [1] (⚕️)
+2696 FE0F ; Basic_Emoji ; balance scale # E1.0 [1] (⚖️)
+2697 FE0F ; Basic_Emoji ; alembic # E1.0 [1] (⚗️)
+2699 FE0F ; Basic_Emoji ; gear # E1.0 [1] (⚙️)
+269B FE0F ; Basic_Emoji ; atom symbol # E1.0 [1] (⚛️)
+269C FE0F ; Basic_Emoji ; fleur-de-lis # E1.0 [1] (⚜️)
+26A0 FE0F ; Basic_Emoji ; warning # E0.6 [1] (⚠️)
+26A7 FE0F ; Basic_Emoji ; transgender symbol # E13.0 [1] (⚧️)
+26B0 FE0F ; Basic_Emoji ; coffin # E1.0 [1] (⚰️)
+26B1 FE0F ; Basic_Emoji ; funeral urn # E1.0 [1] (⚱️)
+26C8 FE0F ; Basic_Emoji ; cloud with lightning and rain # E0.7 [1] (⛈️)
+26CF FE0F ; Basic_Emoji ; pick # E0.7 [1] (⛏️)
+26D1 FE0F ; Basic_Emoji ; rescue worker’s helmet # E0.7 [1] (⛑️)
+26D3 FE0F ; Basic_Emoji ; chains # E0.7 [1] (⛓️)
+26E9 FE0F ; Basic_Emoji ; shinto shrine # E0.7 [1] (⛩️)
+26F0 FE0F ; Basic_Emoji ; mountain # E0.7 [1] (⛰️)
+26F1 FE0F ; Basic_Emoji ; umbrella on ground # E0.7 [1] (⛱️)
+26F4 FE0F ; Basic_Emoji ; ferry # E0.7 [1] (⛴️)
+26F7 FE0F ; Basic_Emoji ; skier # E0.7 [1] (⛷️)
+26F8 FE0F ; Basic_Emoji ; ice skate # E0.7 [1] (⛸️)
+26F9 FE0F ; Basic_Emoji ; person bouncing ball # E0.7 [1] (⛹️)
+2702 FE0F ; Basic_Emoji ; scissors # E0.6 [1] (✂️)
+2708 FE0F ; Basic_Emoji ; airplane # E0.6 [1] (✈️)
+2709 FE0F ; Basic_Emoji ; envelope # E0.6 [1] (✉️)
+270C FE0F ; Basic_Emoji ; victory hand # E0.6 [1] (✌️)
+270D FE0F ; Basic_Emoji ; writing hand # E0.7 [1] (✍️)
+270F FE0F ; Basic_Emoji ; pencil # E0.6 [1] (✏️)
+2712 FE0F ; Basic_Emoji ; black nib # E0.6 [1] (✒️)
+2714 FE0F ; Basic_Emoji ; check mark # E0.6 [1] (✔️)
+2716 FE0F ; Basic_Emoji ; multiply # E0.6 [1] (✖️)
+271D FE0F ; Basic_Emoji ; latin cross # E0.7 [1] (✝️)
+2721 FE0F ; Basic_Emoji ; star of David # E0.7 [1] (✡️)
+2733 FE0F ; Basic_Emoji ; eight-spoked asterisk # E0.6 [1] (✳️)
+2734 FE0F ; Basic_Emoji ; eight-pointed star # E0.6 [1] (✴️)
+2744 FE0F ; Basic_Emoji ; snowflake # E0.6 [1] (❄️)
+2747 FE0F ; Basic_Emoji ; sparkle # E0.6 [1] (❇️)
+2763 FE0F ; Basic_Emoji ; heart exclamation # E1.0 [1] (❣️)
+2764 FE0F ; Basic_Emoji ; red heart # E0.6 [1] (❤️)
+27A1 FE0F ; Basic_Emoji ; right arrow # E0.6 [1] (➡️)
+2934 FE0F ; Basic_Emoji ; right arrow curving up # E0.6 [1] (⤴️)
+2935 FE0F ; Basic_Emoji ; right arrow curving down # E0.6 [1] (⤵️)
+2B05 FE0F ; Basic_Emoji ; left arrow # E0.6 [1] (⬅️)
+2B06 FE0F ; Basic_Emoji ; up arrow # E0.6 [1] (⬆️)
+2B07 FE0F ; Basic_Emoji ; down arrow # E0.6 [1] (⬇️)
+3030 FE0F ; Basic_Emoji ; wavy dash # E0.6 [1] (〰️)
+303D FE0F ; Basic_Emoji ; part alternation mark # E0.6 [1] (〽️)
+3297 FE0F ; Basic_Emoji ; Japanese “congratulations” button # E0.6 [1] (㊗️)
+3299 FE0F ; Basic_Emoji ; Japanese “secret” button # E0.6 [1] (㊙️)
+1F170 FE0F ; Basic_Emoji ; A button (blood type) # E0.6 [1] (🅰️)
+1F171 FE0F ; Basic_Emoji ; B button (blood type) # E0.6 [1] (🅱️)
+1F17E FE0F ; Basic_Emoji ; O button (blood type) # E0.6 [1] (🅾️)
+1F17F FE0F ; Basic_Emoji ; P button # E0.6 [1] (🅿️)
+1F202 FE0F ; Basic_Emoji ; Japanese “service charge” button # E0.6 [1] (🈂️)
+1F237 FE0F ; Basic_Emoji ; Japanese “monthly amount” button # E0.6 [1] (🈷️)
+1F321 FE0F ; Basic_Emoji ; thermometer # E0.7 [1] (🌡️)
+1F324 FE0F ; Basic_Emoji ; sun behind small cloud # E0.7 [1] (🌤️)
+1F325 FE0F ; Basic_Emoji ; sun behind large cloud # E0.7 [1] (🌥️)
+1F326 FE0F ; Basic_Emoji ; sun behind rain cloud # E0.7 [1] (🌦️)
+1F327 FE0F ; Basic_Emoji ; cloud with rain # E0.7 [1] (🌧️)
+1F328 FE0F ; Basic_Emoji ; cloud with snow # E0.7 [1] (🌨️)
+1F329 FE0F ; Basic_Emoji ; cloud with lightning # E0.7 [1] (🌩️)
+1F32A FE0F ; Basic_Emoji ; tornado # E0.7 [1] (🌪️)
+1F32B FE0F ; Basic_Emoji ; fog # E0.7 [1] (🌫️)
+1F32C FE0F ; Basic_Emoji ; wind face # E0.7 [1] (🌬️)
+1F336 FE0F ; Basic_Emoji ; hot pepper # E0.7 [1] (🌶️)
+1F37D FE0F ; Basic_Emoji ; fork and knife with plate # E0.7 [1] (🍽️)
+1F396 FE0F ; Basic_Emoji ; military medal # E0.7 [1] (🎖️)
+1F397 FE0F ; Basic_Emoji ; reminder ribbon # E0.7 [1] (🎗️)
+1F399 FE0F ; Basic_Emoji ; studio microphone # E0.7 [1] (🎙️)
+1F39A FE0F ; Basic_Emoji ; level slider # E0.7 [1] (🎚️)
+1F39B FE0F ; Basic_Emoji ; control knobs # E0.7 [1] (🎛️)
+1F39E FE0F ; Basic_Emoji ; film frames # E0.7 [1] (🎞️)
+1F39F FE0F ; Basic_Emoji ; admission tickets # E0.7 [1] (🎟️)
+1F3CB FE0F ; Basic_Emoji ; person lifting weights # E0.7 [1] (🏋️)
+1F3CC FE0F ; Basic_Emoji ; person golfing # E0.7 [1] (🏌️)
+1F3CD FE0F ; Basic_Emoji ; motorcycle # E0.7 [1] (🏍️)
+1F3CE FE0F ; Basic_Emoji ; racing car # E0.7 [1] (🏎️)
+1F3D4 FE0F ; Basic_Emoji ; snow-capped mountain # E0.7 [1] (🏔️)
+1F3D5 FE0F ; Basic_Emoji ; camping # E0.7 [1] (🏕️)
+1F3D6 FE0F ; Basic_Emoji ; beach with umbrella # E0.7 [1] (🏖️)
+1F3D7 FE0F ; Basic_Emoji ; building construction # E0.7 [1] (🏗️)
+1F3D8 FE0F ; Basic_Emoji ; houses # E0.7 [1] (🏘️)
+1F3D9 FE0F ; Basic_Emoji ; cityscape # E0.7 [1] (🏙️)
+1F3DA FE0F ; Basic_Emoji ; derelict house # E0.7 [1] (🏚️)
+1F3DB FE0F ; Basic_Emoji ; classical building # E0.7 [1] (🏛️)
+1F3DC FE0F ; Basic_Emoji ; desert # E0.7 [1] (🏜️)
+1F3DD FE0F ; Basic_Emoji ; desert island # E0.7 [1] (🏝️)
+1F3DE FE0F ; Basic_Emoji ; national park # E0.7 [1] (🏞️)
+1F3DF FE0F ; Basic_Emoji ; stadium # E0.7 [1] (🏟️)
+1F3F3 FE0F ; Basic_Emoji ; white flag # E0.7 [1] (🏳️)
+1F3F5 FE0F ; Basic_Emoji ; rosette # E0.7 [1] (🏵️)
+1F3F7 FE0F ; Basic_Emoji ; label # E0.7 [1] (🏷️)
+1F43F FE0F ; Basic_Emoji ; chipmunk # E0.7 [1] (🐿️)
+1F441 FE0F ; Basic_Emoji ; eye # E0.7 [1] (👁️)
+1F4FD FE0F ; Basic_Emoji ; film projector # E0.7 [1] (📽️)
+1F549 FE0F ; Basic_Emoji ; om # E0.7 [1] (🕉️)
+1F54A FE0F ; Basic_Emoji ; dove # E0.7 [1] (🕊️)
+1F56F FE0F ; Basic_Emoji ; candle # E0.7 [1] (🕯️)
+1F570 FE0F ; Basic_Emoji ; mantelpiece clock # E0.7 [1] (🕰️)
+1F573 FE0F ; Basic_Emoji ; hole # E0.7 [1] (🕳️)
+1F574 FE0F ; Basic_Emoji ; person in suit levitating # E0.7 [1] (🕴️)
+1F575 FE0F ; Basic_Emoji ; detective # E0.7 [1] (🕵️)
+1F576 FE0F ; Basic_Emoji ; sunglasses # E0.7 [1] (🕶️)
+1F577 FE0F ; Basic_Emoji ; spider # E0.7 [1] (🕷️)
+1F578 FE0F ; Basic_Emoji ; spider web # E0.7 [1] (🕸️)
+1F579 FE0F ; Basic_Emoji ; joystick # E0.7 [1] (🕹️)
+1F587 FE0F ; Basic_Emoji ; linked paperclips # E0.7 [1] (🖇️)
+1F58A FE0F ; Basic_Emoji ; pen # E0.7 [1] (🖊️)
+1F58B FE0F ; Basic_Emoji ; fountain pen # E0.7 [1] (🖋️)
+1F58C FE0F ; Basic_Emoji ; paintbrush # E0.7 [1] (🖌️)
+1F58D FE0F ; Basic_Emoji ; crayon # E0.7 [1] (🖍️)
+1F590 FE0F ; Basic_Emoji ; hand with fingers splayed # E0.7 [1] (🖐️)
+1F5A5 FE0F ; Basic_Emoji ; desktop computer # E0.7 [1] (🖥️)
+1F5A8 FE0F ; Basic_Emoji ; printer # E0.7 [1] (🖨️)
+1F5B1 FE0F ; Basic_Emoji ; computer mouse # E0.7 [1] (🖱️)
+1F5B2 FE0F ; Basic_Emoji ; trackball # E0.7 [1] (🖲️)
+1F5BC FE0F ; Basic_Emoji ; framed picture # E0.7 [1] (🖼️)
+1F5C2 FE0F ; Basic_Emoji ; card index dividers # E0.7 [1] (🗂️)
+1F5C3 FE0F ; Basic_Emoji ; card file box # E0.7 [1] (🗃️)
+1F5C4 FE0F ; Basic_Emoji ; file cabinet # E0.7 [1] (🗄️)
+1F5D1 FE0F ; Basic_Emoji ; wastebasket # E0.7 [1] (🗑️)
+1F5D2 FE0F ; Basic_Emoji ; spiral notepad # E0.7 [1] (🗒️)
+1F5D3 FE0F ; Basic_Emoji ; spiral calendar # E0.7 [1] (🗓️)
+1F5DC FE0F ; Basic_Emoji ; clamp # E0.7 [1] (🗜️)
+1F5DD FE0F ; Basic_Emoji ; old key # E0.7 [1] (🗝️)
+1F5DE FE0F ; Basic_Emoji ; rolled-up newspaper # E0.7 [1] (🗞️)
+1F5E1 FE0F ; Basic_Emoji ; dagger # E0.7 [1] (🗡️)
+1F5E3 FE0F ; Basic_Emoji ; speaking head # E0.7 [1] (🗣️)
+1F5E8 FE0F ; Basic_Emoji ; left speech bubble # E2.0 [1] (🗨️)
+1F5EF FE0F ; Basic_Emoji ; right anger bubble # E0.7 [1] (🗯️)
+1F5F3 FE0F ; Basic_Emoji ; ballot box with ballot # E0.7 [1] (🗳️)
+1F5FA FE0F ; Basic_Emoji ; world map # E0.7 [1] (🗺️)
+1F6CB FE0F ; Basic_Emoji ; couch and lamp # E0.7 [1] (🛋️)
+1F6CD FE0F ; Basic_Emoji ; shopping bags # E0.7 [1] (🛍️)
+1F6CE FE0F ; Basic_Emoji ; bellhop bell # E0.7 [1] (🛎️)
+1F6CF FE0F ; Basic_Emoji ; bed # E0.7 [1] (🛏️)
+1F6E0 FE0F ; Basic_Emoji ; hammer and wrench # E0.7 [1] (🛠️)
+1F6E1 FE0F ; Basic_Emoji ; shield # E0.7 [1] (🛡️)
+1F6E2 FE0F ; Basic_Emoji ; oil drum # E0.7 [1] (🛢️)
+1F6E3 FE0F ; Basic_Emoji ; motorway # E0.7 [1] (🛣️)
+1F6E4 FE0F ; Basic_Emoji ; railway track # E0.7 [1] (🛤️)
+1F6E5 FE0F ; Basic_Emoji ; motor boat # E0.7 [1] (🛥️)
+1F6E9 FE0F ; Basic_Emoji ; small airplane # E0.7 [1] (🛩️)
+1F6F0 FE0F ; Basic_Emoji ; satellite # E0.7 [1] (🛰️)
+1F6F3 FE0F ; Basic_Emoji ; passenger ship # E0.7 [1] (🛳️)
+
+# Total elements: 1366
+
+# ================================================
+
+# 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️⃣)
+0031 FE0F 20E3; Emoji_Keycap_Sequence ; keycap: 1 # E0.6 [1] (1️⃣)
+0032 FE0F 20E3; Emoji_Keycap_Sequence ; keycap: 2 # E0.6 [1] (2️⃣)
+0033 FE0F 20E3; Emoji_Keycap_Sequence ; keycap: 3 # E0.6 [1] (3️⃣)
+0034 FE0F 20E3; Emoji_Keycap_Sequence ; keycap: 4 # E0.6 [1] (4️⃣)
+0035 FE0F 20E3; Emoji_Keycap_Sequence ; keycap: 5 # E0.6 [1] (5️⃣)
+0036 FE0F 20E3; Emoji_Keycap_Sequence ; keycap: 6 # E0.6 [1] (6️⃣)
+0037 FE0F 20E3; Emoji_Keycap_Sequence ; keycap: 7 # E0.6 [1] (7️⃣)
+0038 FE0F 20E3; Emoji_Keycap_Sequence ; keycap: 8 # E0.6 [1] (8️⃣)
+0039 FE0F 20E3; Emoji_Keycap_Sequence ; keycap: 9 # E0.6 [1] (9️⃣)
+
+# Total elements: 12
+
+# ================================================
+
+# 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] (🇦🇪)
+1F1E6 1F1EB ; RGI_Emoji_Flag_Sequence ; flag: Afghanistan # E2.0 [1] (🇦🇫)
+1F1E6 1F1EC ; RGI_Emoji_Flag_Sequence ; flag: Antigua & Barbuda # E2.0 [1] (🇦🇬)
+1F1E6 1F1EE ; RGI_Emoji_Flag_Sequence ; flag: Anguilla # E2.0 [1] (🇦🇮)
+1F1E6 1F1F1 ; RGI_Emoji_Flag_Sequence ; flag: Albania # E2.0 [1] (🇦🇱)
+1F1E6 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: Armenia # E2.0 [1] (🇦🇲)
+1F1E6 1F1F4 ; RGI_Emoji_Flag_Sequence ; flag: Angola # E2.0 [1] (🇦🇴)
+1F1E6 1F1F6 ; RGI_Emoji_Flag_Sequence ; flag: Antarctica # E2.0 [1] (🇦🇶)
+1F1E6 1F1F7 ; RGI_Emoji_Flag_Sequence ; flag: Argentina # E2.0 [1] (🇦🇷)
+1F1E6 1F1F8 ; RGI_Emoji_Flag_Sequence ; flag: American Samoa # E2.0 [1] (🇦🇸)
+1F1E6 1F1F9 ; RGI_Emoji_Flag_Sequence ; flag: Austria # E2.0 [1] (🇦🇹)
+1F1E6 1F1FA ; RGI_Emoji_Flag_Sequence ; flag: Australia # E2.0 [1] (🇦🇺)
+1F1E6 1F1FC ; RGI_Emoji_Flag_Sequence ; flag: Aruba # E2.0 [1] (🇦🇼)
+1F1E6 1F1FD ; RGI_Emoji_Flag_Sequence ; flag: Åland Islands # E2.0 [1] (🇦🇽)
+1F1E6 1F1FF ; RGI_Emoji_Flag_Sequence ; flag: Azerbaijan # E2.0 [1] (🇦🇿)
+1F1E7 1F1E6 ; RGI_Emoji_Flag_Sequence ; flag: Bosnia & Herzegovina # E2.0 [1] (🇧🇦)
+1F1E7 1F1E7 ; RGI_Emoji_Flag_Sequence ; flag: Barbados # E2.0 [1] (🇧🇧)
+1F1E7 1F1E9 ; RGI_Emoji_Flag_Sequence ; flag: Bangladesh # E2.0 [1] (🇧🇩)
+1F1E7 1F1EA ; RGI_Emoji_Flag_Sequence ; flag: Belgium # E2.0 [1] (🇧🇪)
+1F1E7 1F1EB ; RGI_Emoji_Flag_Sequence ; flag: Burkina Faso # E2.0 [1] (🇧🇫)
+1F1E7 1F1EC ; RGI_Emoji_Flag_Sequence ; flag: Bulgaria # E2.0 [1] (🇧🇬)
+1F1E7 1F1ED ; RGI_Emoji_Flag_Sequence ; flag: Bahrain # E2.0 [1] (🇧🇭)
+1F1E7 1F1EE ; RGI_Emoji_Flag_Sequence ; flag: Burundi # E2.0 [1] (🇧🇮)
+1F1E7 1F1EF ; RGI_Emoji_Flag_Sequence ; flag: Benin # E2.0 [1] (🇧🇯)
+1F1E7 1F1F1 ; RGI_Emoji_Flag_Sequence ; flag: St. Barthélemy # E2.0 [1] (🇧🇱)
+1F1E7 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: Bermuda # E2.0 [1] (🇧🇲)
+1F1E7 1F1F3 ; RGI_Emoji_Flag_Sequence ; flag: Brunei # E2.0 [1] (🇧🇳)
+1F1E7 1F1F4 ; RGI_Emoji_Flag_Sequence ; flag: Bolivia # E2.0 [1] (🇧🇴)
+1F1E7 1F1F6 ; RGI_Emoji_Flag_Sequence ; flag: Caribbean Netherlands # E2.0 [1] (🇧🇶)
+1F1E7 1F1F7 ; RGI_Emoji_Flag_Sequence ; flag: Brazil # E2.0 [1] (🇧🇷)
+1F1E7 1F1F8 ; RGI_Emoji_Flag_Sequence ; flag: Bahamas # E2.0 [1] (🇧🇸)
+1F1E7 1F1F9 ; RGI_Emoji_Flag_Sequence ; flag: Bhutan # E2.0 [1] (🇧🇹)
+1F1E7 1F1FB ; RGI_Emoji_Flag_Sequence ; flag: Bouvet Island # E2.0 [1] (🇧🇻)
+1F1E7 1F1FC ; RGI_Emoji_Flag_Sequence ; flag: Botswana # E2.0 [1] (🇧🇼)
+1F1E7 1F1FE ; RGI_Emoji_Flag_Sequence ; flag: Belarus # E2.0 [1] (🇧🇾)
+1F1E7 1F1FF ; RGI_Emoji_Flag_Sequence ; flag: Belize # E2.0 [1] (🇧🇿)
+1F1E8 1F1E6 ; RGI_Emoji_Flag_Sequence ; flag: Canada # E2.0 [1] (🇨🇦)
+1F1E8 1F1E8 ; RGI_Emoji_Flag_Sequence ; flag: Cocos (Keeling) Islands # E2.0 [1] (🇨🇨)
+1F1E8 1F1E9 ; RGI_Emoji_Flag_Sequence ; flag: Congo - Kinshasa # E2.0 [1] (🇨🇩)
+1F1E8 1F1EB ; RGI_Emoji_Flag_Sequence ; flag: Central African Republic # E2.0 [1] (🇨🇫)
+1F1E8 1F1EC ; RGI_Emoji_Flag_Sequence ; flag: Congo - Brazzaville # E2.0 [1] (🇨🇬)
+1F1E8 1F1ED ; RGI_Emoji_Flag_Sequence ; flag: Switzerland # E2.0 [1] (🇨🇭)
+1F1E8 1F1EE ; RGI_Emoji_Flag_Sequence ; flag: Côte d’Ivoire # E2.0 [1] (🇨🇮)
+1F1E8 1F1F0 ; RGI_Emoji_Flag_Sequence ; flag: Cook Islands # E2.0 [1] (🇨🇰)
+1F1E8 1F1F1 ; RGI_Emoji_Flag_Sequence ; flag: Chile # E2.0 [1] (🇨🇱)
+1F1E8 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: Cameroon # E2.0 [1] (🇨🇲)
+1F1E8 1F1F3 ; RGI_Emoji_Flag_Sequence ; flag: China # E0.6 [1] (🇨🇳)
+1F1E8 1F1F4 ; RGI_Emoji_Flag_Sequence ; flag: Colombia # E2.0 [1] (🇨🇴)
+1F1E8 1F1F5 ; RGI_Emoji_Flag_Sequence ; flag: Clipperton Island # E2.0 [1] (🇨🇵)
+1F1E8 1F1F7 ; RGI_Emoji_Flag_Sequence ; flag: Costa Rica # E2.0 [1] (🇨🇷)
+1F1E8 1F1FA ; RGI_Emoji_Flag_Sequence ; flag: Cuba # E2.0 [1] (🇨🇺)
+1F1E8 1F1FB ; RGI_Emoji_Flag_Sequence ; flag: Cape Verde # E2.0 [1] (🇨🇻)
+1F1E8 1F1FC ; RGI_Emoji_Flag_Sequence ; flag: Curaçao # E2.0 [1] (🇨🇼)
+1F1E8 1F1FD ; RGI_Emoji_Flag_Sequence ; flag: Christmas Island # E2.0 [1] (🇨🇽)
+1F1E8 1F1FE ; RGI_Emoji_Flag_Sequence ; flag: Cyprus # E2.0 [1] (🇨🇾)
+1F1E8 1F1FF ; RGI_Emoji_Flag_Sequence ; flag: Czechia # E2.0 [1] (🇨🇿)
+1F1E9 1F1EA ; RGI_Emoji_Flag_Sequence ; flag: Germany # E0.6 [1] (🇩🇪)
+1F1E9 1F1EC ; RGI_Emoji_Flag_Sequence ; flag: Diego Garcia # E2.0 [1] (🇩🇬)
+1F1E9 1F1EF ; RGI_Emoji_Flag_Sequence ; flag: Djibouti # E2.0 [1] (🇩🇯)
+1F1E9 1F1F0 ; RGI_Emoji_Flag_Sequence ; flag: Denmark # E2.0 [1] (🇩🇰)
+1F1E9 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: Dominica # E2.0 [1] (🇩🇲)
+1F1E9 1F1F4 ; RGI_Emoji_Flag_Sequence ; flag: Dominican Republic # E2.0 [1] (🇩🇴)
+1F1E9 1F1FF ; RGI_Emoji_Flag_Sequence ; flag: Algeria # E2.0 [1] (🇩🇿)
+1F1EA 1F1E6 ; RGI_Emoji_Flag_Sequence ; flag: Ceuta & Melilla # E2.0 [1] (🇪🇦)
+1F1EA 1F1E8 ; RGI_Emoji_Flag_Sequence ; flag: Ecuador # E2.0 [1] (🇪🇨)
+1F1EA 1F1EA ; RGI_Emoji_Flag_Sequence ; flag: Estonia # E2.0 [1] (🇪🇪)
+1F1EA 1F1EC ; RGI_Emoji_Flag_Sequence ; flag: Egypt # E2.0 [1] (🇪🇬)
+1F1EA 1F1ED ; RGI_Emoji_Flag_Sequence ; flag: Western Sahara # E2.0 [1] (🇪🇭)
+1F1EA 1F1F7 ; RGI_Emoji_Flag_Sequence ; flag: Eritrea # E2.0 [1] (🇪🇷)
+1F1EA 1F1F8 ; RGI_Emoji_Flag_Sequence ; flag: Spain # E0.6 [1] (🇪🇸)
+1F1EA 1F1F9 ; RGI_Emoji_Flag_Sequence ; flag: Ethiopia # E2.0 [1] (🇪🇹)
+1F1EA 1F1FA ; RGI_Emoji_Flag_Sequence ; flag: European Union # E2.0 [1] (🇪🇺)
+1F1EB 1F1EE ; RGI_Emoji_Flag_Sequence ; flag: Finland # E2.0 [1] (🇫🇮)
+1F1EB 1F1EF ; RGI_Emoji_Flag_Sequence ; flag: Fiji # E2.0 [1] (🇫🇯)
+1F1EB 1F1F0 ; RGI_Emoji_Flag_Sequence ; flag: Falkland Islands # E2.0 [1] (🇫🇰)
+1F1EB 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: Micronesia # E2.0 [1] (🇫🇲)
+1F1EB 1F1F4 ; RGI_Emoji_Flag_Sequence ; flag: Faroe Islands # E2.0 [1] (🇫🇴)
+1F1EB 1F1F7 ; RGI_Emoji_Flag_Sequence ; flag: France # E0.6 [1] (🇫🇷)
+1F1EC 1F1E6 ; RGI_Emoji_Flag_Sequence ; flag: Gabon # E2.0 [1] (🇬🇦)
+1F1EC 1F1E7 ; RGI_Emoji_Flag_Sequence ; flag: United Kingdom # E0.6 [1] (🇬🇧)
+1F1EC 1F1E9 ; RGI_Emoji_Flag_Sequence ; flag: Grenada # E2.0 [1] (🇬🇩)
+1F1EC 1F1EA ; RGI_Emoji_Flag_Sequence ; flag: Georgia # E2.0 [1] (🇬🇪)
+1F1EC 1F1EB ; RGI_Emoji_Flag_Sequence ; flag: French Guiana # E2.0 [1] (🇬🇫)
+1F1EC 1F1EC ; RGI_Emoji_Flag_Sequence ; flag: Guernsey # E2.0 [1] (🇬🇬)
+1F1EC 1F1ED ; RGI_Emoji_Flag_Sequence ; flag: Ghana # E2.0 [1] (🇬🇭)
+1F1EC 1F1EE ; RGI_Emoji_Flag_Sequence ; flag: Gibraltar # E2.0 [1] (🇬🇮)
+1F1EC 1F1F1 ; RGI_Emoji_Flag_Sequence ; flag: Greenland # E2.0 [1] (🇬🇱)
+1F1EC 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: Gambia # E2.0 [1] (🇬🇲)
+1F1EC 1F1F3 ; RGI_Emoji_Flag_Sequence ; flag: Guinea # E2.0 [1] (🇬🇳)
+1F1EC 1F1F5 ; RGI_Emoji_Flag_Sequence ; flag: Guadeloupe # E2.0 [1] (🇬🇵)
+1F1EC 1F1F6 ; RGI_Emoji_Flag_Sequence ; flag: Equatorial Guinea # E2.0 [1] (🇬🇶)
+1F1EC 1F1F7 ; RGI_Emoji_Flag_Sequence ; flag: Greece # E2.0 [1] (🇬🇷)
+1F1EC 1F1F8 ; RGI_Emoji_Flag_Sequence ; flag: South Georgia & South Sandwich Islands # E2.0 [1] (🇬🇸)
+1F1EC 1F1F9 ; RGI_Emoji_Flag_Sequence ; flag: Guatemala # E2.0 [1] (🇬🇹)
+1F1EC 1F1FA ; RGI_Emoji_Flag_Sequence ; flag: Guam # E2.0 [1] (🇬🇺)
+1F1EC 1F1FC ; RGI_Emoji_Flag_Sequence ; flag: Guinea-Bissau # E2.0 [1] (🇬🇼)
+1F1EC 1F1FE ; RGI_Emoji_Flag_Sequence ; flag: Guyana # E2.0 [1] (🇬🇾)
+1F1ED 1F1F0 ; RGI_Emoji_Flag_Sequence ; flag: Hong Kong SAR China # E2.0 [1] (🇭🇰)
+1F1ED 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: Heard & McDonald Islands # E2.0 [1] (🇭🇲)
+1F1ED 1F1F3 ; RGI_Emoji_Flag_Sequence ; flag: Honduras # E2.0 [1] (🇭🇳)
+1F1ED 1F1F7 ; RGI_Emoji_Flag_Sequence ; flag: Croatia # E2.0 [1] (🇭🇷)
+1F1ED 1F1F9 ; RGI_Emoji_Flag_Sequence ; flag: Haiti # E2.0 [1] (🇭🇹)
+1F1ED 1F1FA ; RGI_Emoji_Flag_Sequence ; flag: Hungary # E2.0 [1] (🇭🇺)
+1F1EE 1F1E8 ; RGI_Emoji_Flag_Sequence ; flag: Canary Islands # E2.0 [1] (🇮🇨)
+1F1EE 1F1E9 ; RGI_Emoji_Flag_Sequence ; flag: Indonesia # E2.0 [1] (🇮🇩)
+1F1EE 1F1EA ; RGI_Emoji_Flag_Sequence ; flag: Ireland # E2.0 [1] (🇮🇪)
+1F1EE 1F1F1 ; RGI_Emoji_Flag_Sequence ; flag: Israel # E2.0 [1] (🇮🇱)
+1F1EE 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: Isle of Man # E2.0 [1] (🇮🇲)
+1F1EE 1F1F3 ; RGI_Emoji_Flag_Sequence ; flag: India # E2.0 [1] (🇮🇳)
+1F1EE 1F1F4 ; RGI_Emoji_Flag_Sequence ; flag: British Indian Ocean Territory # E2.0 [1] (🇮🇴)
+1F1EE 1F1F6 ; RGI_Emoji_Flag_Sequence ; flag: Iraq # E2.0 [1] (🇮🇶)
+1F1EE 1F1F7 ; RGI_Emoji_Flag_Sequence ; flag: Iran # E2.0 [1] (🇮🇷)
+1F1EE 1F1F8 ; RGI_Emoji_Flag_Sequence ; flag: Iceland # E2.0 [1] (🇮🇸)
+1F1EE 1F1F9 ; RGI_Emoji_Flag_Sequence ; flag: Italy # E0.6 [1] (🇮🇹)
+1F1EF 1F1EA ; RGI_Emoji_Flag_Sequence ; flag: Jersey # E2.0 [1] (🇯🇪)
+1F1EF 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: Jamaica # E2.0 [1] (🇯🇲)
+1F1EF 1F1F4 ; RGI_Emoji_Flag_Sequence ; flag: Jordan # E2.0 [1] (🇯🇴)
+1F1EF 1F1F5 ; RGI_Emoji_Flag_Sequence ; flag: Japan # E0.6 [1] (🇯🇵)
+1F1F0 1F1EA ; RGI_Emoji_Flag_Sequence ; flag: Kenya # E2.0 [1] (🇰🇪)
+1F1F0 1F1EC ; RGI_Emoji_Flag_Sequence ; flag: Kyrgyzstan # E2.0 [1] (🇰🇬)
+1F1F0 1F1ED ; RGI_Emoji_Flag_Sequence ; flag: Cambodia # E2.0 [1] (🇰🇭)
+1F1F0 1F1EE ; RGI_Emoji_Flag_Sequence ; flag: Kiribati # E2.0 [1] (🇰🇮)
+1F1F0 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: Comoros # E2.0 [1] (🇰🇲)
+1F1F0 1F1F3 ; RGI_Emoji_Flag_Sequence ; flag: St. Kitts & Nevis # E2.0 [1] (🇰🇳)
+1F1F0 1F1F5 ; RGI_Emoji_Flag_Sequence ; flag: North Korea # E2.0 [1] (🇰🇵)
+1F1F0 1F1F7 ; RGI_Emoji_Flag_Sequence ; flag: South Korea # E0.6 [1] (🇰🇷)
+1F1F0 1F1FC ; RGI_Emoji_Flag_Sequence ; flag: Kuwait # E2.0 [1] (🇰🇼)
+1F1F0 1F1FE ; RGI_Emoji_Flag_Sequence ; flag: Cayman Islands # E2.0 [1] (🇰🇾)
+1F1F0 1F1FF ; RGI_Emoji_Flag_Sequence ; flag: Kazakhstan # E2.0 [1] (🇰🇿)
+1F1F1 1F1E6 ; RGI_Emoji_Flag_Sequence ; flag: Laos # E2.0 [1] (🇱🇦)
+1F1F1 1F1E7 ; RGI_Emoji_Flag_Sequence ; flag: Lebanon # E2.0 [1] (🇱🇧)
+1F1F1 1F1E8 ; RGI_Emoji_Flag_Sequence ; flag: St. Lucia # E2.0 [1] (🇱🇨)
+1F1F1 1F1EE ; RGI_Emoji_Flag_Sequence ; flag: Liechtenstein # E2.0 [1] (🇱🇮)
+1F1F1 1F1F0 ; RGI_Emoji_Flag_Sequence ; flag: Sri Lanka # E2.0 [1] (🇱🇰)
+1F1F1 1F1F7 ; RGI_Emoji_Flag_Sequence ; flag: Liberia # E2.0 [1] (🇱🇷)
+1F1F1 1F1F8 ; RGI_Emoji_Flag_Sequence ; flag: Lesotho # E2.0 [1] (🇱🇸)
+1F1F1 1F1F9 ; RGI_Emoji_Flag_Sequence ; flag: Lithuania # E2.0 [1] (🇱🇹)
+1F1F1 1F1FA ; RGI_Emoji_Flag_Sequence ; flag: Luxembourg # E2.0 [1] (🇱🇺)
+1F1F1 1F1FB ; RGI_Emoji_Flag_Sequence ; flag: Latvia # E2.0 [1] (🇱🇻)
+1F1F1 1F1FE ; RGI_Emoji_Flag_Sequence ; flag: Libya # E2.0 [1] (🇱🇾)
+1F1F2 1F1E6 ; RGI_Emoji_Flag_Sequence ; flag: Morocco # E2.0 [1] (🇲🇦)
+1F1F2 1F1E8 ; RGI_Emoji_Flag_Sequence ; flag: Monaco # E2.0 [1] (🇲🇨)
+1F1F2 1F1E9 ; RGI_Emoji_Flag_Sequence ; flag: Moldova # E2.0 [1] (🇲🇩)
+1F1F2 1F1EA ; RGI_Emoji_Flag_Sequence ; flag: Montenegro # E2.0 [1] (🇲🇪)
+1F1F2 1F1EB ; RGI_Emoji_Flag_Sequence ; flag: St. Martin # E2.0 [1] (🇲🇫)
+1F1F2 1F1EC ; RGI_Emoji_Flag_Sequence ; flag: Madagascar # E2.0 [1] (🇲🇬)
+1F1F2 1F1ED ; RGI_Emoji_Flag_Sequence ; flag: Marshall Islands # E2.0 [1] (🇲🇭)
+1F1F2 1F1F0 ; RGI_Emoji_Flag_Sequence ; flag: North Macedonia # E2.0 [1] (🇲🇰)
+1F1F2 1F1F1 ; RGI_Emoji_Flag_Sequence ; flag: Mali # E2.0 [1] (🇲🇱)
+1F1F2 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: Myanmar (Burma) # E2.0 [1] (🇲🇲)
+1F1F2 1F1F3 ; RGI_Emoji_Flag_Sequence ; flag: Mongolia # E2.0 [1] (🇲🇳)
+1F1F2 1F1F4 ; RGI_Emoji_Flag_Sequence ; flag: Macao SAR China # E2.0 [1] (🇲🇴)
+1F1F2 1F1F5 ; RGI_Emoji_Flag_Sequence ; flag: Northern Mariana Islands # E2.0 [1] (🇲🇵)
+1F1F2 1F1F6 ; RGI_Emoji_Flag_Sequence ; flag: Martinique # E2.0 [1] (🇲🇶)
+1F1F2 1F1F7 ; RGI_Emoji_Flag_Sequence ; flag: Mauritania # E2.0 [1] (🇲🇷)
+1F1F2 1F1F8 ; RGI_Emoji_Flag_Sequence ; flag: Montserrat # E2.0 [1] (🇲🇸)
+1F1F2 1F1F9 ; RGI_Emoji_Flag_Sequence ; flag: Malta # E2.0 [1] (🇲🇹)
+1F1F2 1F1FA ; RGI_Emoji_Flag_Sequence ; flag: Mauritius # E2.0 [1] (🇲🇺)
+1F1F2 1F1FB ; RGI_Emoji_Flag_Sequence ; flag: Maldives # E2.0 [1] (🇲🇻)
+1F1F2 1F1FC ; RGI_Emoji_Flag_Sequence ; flag: Malawi # E2.0 [1] (🇲🇼)
+1F1F2 1F1FD ; RGI_Emoji_Flag_Sequence ; flag: Mexico # E2.0 [1] (🇲🇽)
+1F1F2 1F1FE ; RGI_Emoji_Flag_Sequence ; flag: Malaysia # E2.0 [1] (🇲🇾)
+1F1F2 1F1FF ; RGI_Emoji_Flag_Sequence ; flag: Mozambique # E2.0 [1] (🇲🇿)
+1F1F3 1F1E6 ; RGI_Emoji_Flag_Sequence ; flag: Namibia # E2.0 [1] (🇳🇦)
+1F1F3 1F1E8 ; RGI_Emoji_Flag_Sequence ; flag: New Caledonia # E2.0 [1] (🇳🇨)
+1F1F3 1F1EA ; RGI_Emoji_Flag_Sequence ; flag: Niger # E2.0 [1] (🇳🇪)
+1F1F3 1F1EB ; RGI_Emoji_Flag_Sequence ; flag: Norfolk Island # E2.0 [1] (🇳🇫)
+1F1F3 1F1EC ; RGI_Emoji_Flag_Sequence ; flag: Nigeria # E2.0 [1] (🇳🇬)
+1F1F3 1F1EE ; RGI_Emoji_Flag_Sequence ; flag: Nicaragua # E2.0 [1] (🇳🇮)
+1F1F3 1F1F1 ; RGI_Emoji_Flag_Sequence ; flag: Netherlands # E2.0 [1] (🇳🇱)
+1F1F3 1F1F4 ; RGI_Emoji_Flag_Sequence ; flag: Norway # E2.0 [1] (🇳🇴)
+1F1F3 1F1F5 ; RGI_Emoji_Flag_Sequence ; flag: Nepal # E2.0 [1] (🇳🇵)
+1F1F3 1F1F7 ; RGI_Emoji_Flag_Sequence ; flag: Nauru # E2.0 [1] (🇳🇷)
+1F1F3 1F1FA ; RGI_Emoji_Flag_Sequence ; flag: Niue # E2.0 [1] (🇳🇺)
+1F1F3 1F1FF ; RGI_Emoji_Flag_Sequence ; flag: New Zealand # E2.0 [1] (🇳🇿)
+1F1F4 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: Oman # E2.0 [1] (🇴🇲)
+1F1F5 1F1E6 ; RGI_Emoji_Flag_Sequence ; flag: Panama # E2.0 [1] (🇵🇦)
+1F1F5 1F1EA ; RGI_Emoji_Flag_Sequence ; flag: Peru # E2.0 [1] (🇵🇪)
+1F1F5 1F1EB ; RGI_Emoji_Flag_Sequence ; flag: French Polynesia # E2.0 [1] (🇵🇫)
+1F1F5 1F1EC ; RGI_Emoji_Flag_Sequence ; flag: Papua New Guinea # E2.0 [1] (🇵🇬)
+1F1F5 1F1ED ; RGI_Emoji_Flag_Sequence ; flag: Philippines # E2.0 [1] (🇵🇭)
+1F1F5 1F1F0 ; RGI_Emoji_Flag_Sequence ; flag: Pakistan # E2.0 [1] (🇵🇰)
+1F1F5 1F1F1 ; RGI_Emoji_Flag_Sequence ; flag: Poland # E2.0 [1] (🇵🇱)
+1F1F5 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: St. Pierre & Miquelon # E2.0 [1] (🇵🇲)
+1F1F5 1F1F3 ; RGI_Emoji_Flag_Sequence ; flag: Pitcairn Islands # E2.0 [1] (🇵🇳)
+1F1F5 1F1F7 ; RGI_Emoji_Flag_Sequence ; flag: Puerto Rico # E2.0 [1] (🇵🇷)
+1F1F5 1F1F8 ; RGI_Emoji_Flag_Sequence ; flag: Palestinian Territories # E2.0 [1] (🇵🇸)
+1F1F5 1F1F9 ; RGI_Emoji_Flag_Sequence ; flag: Portugal # E2.0 [1] (🇵🇹)
+1F1F5 1F1FC ; RGI_Emoji_Flag_Sequence ; flag: Palau # E2.0 [1] (🇵🇼)
+1F1F5 1F1FE ; RGI_Emoji_Flag_Sequence ; flag: Paraguay # E2.0 [1] (🇵🇾)
+1F1F6 1F1E6 ; RGI_Emoji_Flag_Sequence ; flag: Qatar # E2.0 [1] (🇶🇦)
+1F1F7 1F1EA ; RGI_Emoji_Flag_Sequence ; flag: Réunion # E2.0 [1] (🇷🇪)
+1F1F7 1F1F4 ; RGI_Emoji_Flag_Sequence ; flag: Romania # E2.0 [1] (🇷🇴)
+1F1F7 1F1F8 ; RGI_Emoji_Flag_Sequence ; flag: Serbia # E2.0 [1] (🇷🇸)
+1F1F7 1F1FA ; RGI_Emoji_Flag_Sequence ; flag: Russia # E0.6 [1] (🇷🇺)
+1F1F7 1F1FC ; RGI_Emoji_Flag_Sequence ; flag: Rwanda # E2.0 [1] (🇷🇼)
+1F1F8 1F1E6 ; RGI_Emoji_Flag_Sequence ; flag: Saudi Arabia # E2.0 [1] (🇸🇦)
+1F1F8 1F1E7 ; RGI_Emoji_Flag_Sequence ; flag: Solomon Islands # E2.0 [1] (🇸🇧)
+1F1F8 1F1E8 ; RGI_Emoji_Flag_Sequence ; flag: Seychelles # E2.0 [1] (🇸🇨)
+1F1F8 1F1E9 ; RGI_Emoji_Flag_Sequence ; flag: Sudan # E2.0 [1] (🇸🇩)
+1F1F8 1F1EA ; RGI_Emoji_Flag_Sequence ; flag: Sweden # E2.0 [1] (🇸🇪)
+1F1F8 1F1EC ; RGI_Emoji_Flag_Sequence ; flag: Singapore # E2.0 [1] (🇸🇬)
+1F1F8 1F1ED ; RGI_Emoji_Flag_Sequence ; flag: St. Helena # E2.0 [1] (🇸🇭)
+1F1F8 1F1EE ; RGI_Emoji_Flag_Sequence ; flag: Slovenia # E2.0 [1] (🇸🇮)
+1F1F8 1F1EF ; RGI_Emoji_Flag_Sequence ; flag: Svalbard & Jan Mayen # E2.0 [1] (🇸🇯)
+1F1F8 1F1F0 ; RGI_Emoji_Flag_Sequence ; flag: Slovakia # E2.0 [1] (🇸🇰)
+1F1F8 1F1F1 ; RGI_Emoji_Flag_Sequence ; flag: Sierra Leone # E2.0 [1] (🇸🇱)
+1F1F8 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: San Marino # E2.0 [1] (🇸🇲)
+1F1F8 1F1F3 ; RGI_Emoji_Flag_Sequence ; flag: Senegal # E2.0 [1] (🇸🇳)
+1F1F8 1F1F4 ; RGI_Emoji_Flag_Sequence ; flag: Somalia # E2.0 [1] (🇸🇴)
+1F1F8 1F1F7 ; RGI_Emoji_Flag_Sequence ; flag: Suriname # E2.0 [1] (🇸🇷)
+1F1F8 1F1F8 ; RGI_Emoji_Flag_Sequence ; flag: South Sudan # E2.0 [1] (🇸🇸)
+1F1F8 1F1F9 ; RGI_Emoji_Flag_Sequence ; flag: São Tomé & Príncipe # E2.0 [1] (🇸🇹)
+1F1F8 1F1FB ; RGI_Emoji_Flag_Sequence ; flag: El Salvador # E2.0 [1] (🇸🇻)
+1F1F8 1F1FD ; RGI_Emoji_Flag_Sequence ; flag: Sint Maarten # E2.0 [1] (🇸🇽)
+1F1F8 1F1FE ; RGI_Emoji_Flag_Sequence ; flag: Syria # E2.0 [1] (🇸🇾)
+1F1F8 1F1FF ; RGI_Emoji_Flag_Sequence ; flag: Eswatini # E2.0 [1] (🇸🇿)
+1F1F9 1F1E6 ; RGI_Emoji_Flag_Sequence ; flag: Tristan da Cunha # E2.0 [1] (🇹🇦)
+1F1F9 1F1E8 ; RGI_Emoji_Flag_Sequence ; flag: Turks & Caicos Islands # E2.0 [1] (🇹🇨)
+1F1F9 1F1E9 ; RGI_Emoji_Flag_Sequence ; flag: Chad # E2.0 [1] (🇹🇩)
+1F1F9 1F1EB ; RGI_Emoji_Flag_Sequence ; flag: French Southern Territories # E2.0 [1] (🇹🇫)
+1F1F9 1F1EC ; RGI_Emoji_Flag_Sequence ; flag: Togo # E2.0 [1] (🇹🇬)
+1F1F9 1F1ED ; RGI_Emoji_Flag_Sequence ; flag: Thailand # E2.0 [1] (🇹🇭)
+1F1F9 1F1EF ; RGI_Emoji_Flag_Sequence ; flag: Tajikistan # E2.0 [1] (🇹🇯)
+1F1F9 1F1F0 ; RGI_Emoji_Flag_Sequence ; flag: Tokelau # E2.0 [1] (🇹🇰)
+1F1F9 1F1F1 ; RGI_Emoji_Flag_Sequence ; flag: Timor-Leste # E2.0 [1] (🇹🇱)
+1F1F9 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: Turkmenistan # E2.0 [1] (🇹🇲)
+1F1F9 1F1F3 ; RGI_Emoji_Flag_Sequence ; flag: Tunisia # E2.0 [1] (🇹🇳)
+1F1F9 1F1F4 ; RGI_Emoji_Flag_Sequence ; flag: Tonga # E2.0 [1] (🇹🇴)
+1F1F9 1F1F7 ; RGI_Emoji_Flag_Sequence ; flag: Turkey # E2.0 [1] (🇹🇷)
+1F1F9 1F1F9 ; RGI_Emoji_Flag_Sequence ; flag: Trinidad & Tobago # E2.0 [1] (🇹🇹)
+1F1F9 1F1FB ; RGI_Emoji_Flag_Sequence ; flag: Tuvalu # E2.0 [1] (🇹🇻)
+1F1F9 1F1FC ; RGI_Emoji_Flag_Sequence ; flag: Taiwan # E2.0 [1] (🇹🇼)
+1F1F9 1F1FF ; RGI_Emoji_Flag_Sequence ; flag: Tanzania # E2.0 [1] (🇹🇿)
+1F1FA 1F1E6 ; RGI_Emoji_Flag_Sequence ; flag: Ukraine # E2.0 [1] (🇺🇦)
+1F1FA 1F1EC ; RGI_Emoji_Flag_Sequence ; flag: Uganda # E2.0 [1] (🇺🇬)
+1F1FA 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: U.S. Outlying Islands # E2.0 [1] (🇺🇲)
+1F1FA 1F1F3 ; RGI_Emoji_Flag_Sequence ; flag: United Nations # E4.0 [1] (🇺🇳)
+1F1FA 1F1F8 ; RGI_Emoji_Flag_Sequence ; flag: United States # E0.6 [1] (🇺🇸)
+1F1FA 1F1FE ; RGI_Emoji_Flag_Sequence ; flag: Uruguay # E2.0 [1] (🇺🇾)
+1F1FA 1F1FF ; RGI_Emoji_Flag_Sequence ; flag: Uzbekistan # E2.0 [1] (🇺🇿)
+1F1FB 1F1E6 ; RGI_Emoji_Flag_Sequence ; flag: Vatican City # E2.0 [1] (🇻🇦)
+1F1FB 1F1E8 ; RGI_Emoji_Flag_Sequence ; flag: St. Vincent & Grenadines # E2.0 [1] (🇻🇨)
+1F1FB 1F1EA ; RGI_Emoji_Flag_Sequence ; flag: Venezuela # E2.0 [1] (🇻🇪)
+1F1FB 1F1EC ; RGI_Emoji_Flag_Sequence ; flag: British Virgin Islands # E2.0 [1] (🇻🇬)
+1F1FB 1F1EE ; RGI_Emoji_Flag_Sequence ; flag: U.S. Virgin Islands # E2.0 [1] (🇻🇮)
+1F1FB 1F1F3 ; RGI_Emoji_Flag_Sequence ; flag: Vietnam # E2.0 [1] (🇻🇳)
+1F1FB 1F1FA ; RGI_Emoji_Flag_Sequence ; flag: Vanuatu # E2.0 [1] (🇻🇺)
+1F1FC 1F1EB ; RGI_Emoji_Flag_Sequence ; flag: Wallis & Futuna # E2.0 [1] (🇼🇫)
+1F1FC 1F1F8 ; RGI_Emoji_Flag_Sequence ; flag: Samoa # E2.0 [1] (🇼🇸)
+1F1FD 1F1F0 ; RGI_Emoji_Flag_Sequence ; flag: Kosovo # E2.0 [1] (🇽🇰)
+1F1FE 1F1EA ; RGI_Emoji_Flag_Sequence ; flag: Yemen # E2.0 [1] (🇾🇪)
+1F1FE 1F1F9 ; RGI_Emoji_Flag_Sequence ; flag: Mayotte # E2.0 [1] (🇾🇹)
+1F1FF 1F1E6 ; RGI_Emoji_Flag_Sequence ; flag: South Africa # E2.0 [1] (🇿🇦)
+1F1FF 1F1F2 ; RGI_Emoji_Flag_Sequence ; flag: Zambia # E2.0 [1] (🇿🇲)
+1F1FF 1F1FC ; RGI_Emoji_Flag_Sequence ; flag: Zimbabwe # E2.0 [1] (🇿🇼)
+
+# Total elements: 258
+
+# ================================================
+
+# 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] (🏴󠁧󠁢󠁷󠁬󠁳󠁿)
+
+# Total elements: 3
+
+# ================================================
+
+# 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] (☝🏽)
+261D 1F3FE ; RGI_Emoji_Modifier_Sequence ; index pointing up: medium-dark skin tone # E1.0 [1] (☝🏾)
+261D 1F3FF ; RGI_Emoji_Modifier_Sequence ; index pointing up: dark skin tone # E1.0 [1] (☝🏿)
+26F9 1F3FB ; RGI_Emoji_Modifier_Sequence ; person bouncing ball: light skin tone # E2.0 [1] (⛹🏻)
+26F9 1F3FC ; RGI_Emoji_Modifier_Sequence ; person bouncing ball: medium-light skin tone # E2.0 [1] (⛹🏼)
+26F9 1F3FD ; RGI_Emoji_Modifier_Sequence ; person bouncing ball: medium skin tone # E2.0 [1] (⛹🏽)
+26F9 1F3FE ; RGI_Emoji_Modifier_Sequence ; person bouncing ball: medium-dark skin tone # E2.0 [1] (⛹🏾)
+26F9 1F3FF ; RGI_Emoji_Modifier_Sequence ; person bouncing ball: dark skin tone # E2.0 [1] (⛹🏿)
+270A 1F3FB ; RGI_Emoji_Modifier_Sequence ; raised fist: light skin tone # E1.0 [1] (✊🏻)
+270A 1F3FC ; RGI_Emoji_Modifier_Sequence ; raised fist: medium-light skin tone # E1.0 [1] (✊🏼)
+270A 1F3FD ; RGI_Emoji_Modifier_Sequence ; raised fist: medium skin tone # E1.0 [1] (✊🏽)
+270A 1F3FE ; RGI_Emoji_Modifier_Sequence ; raised fist: medium-dark skin tone # E1.0 [1] (✊🏾)
+270A 1F3FF ; RGI_Emoji_Modifier_Sequence ; raised fist: dark skin tone # E1.0 [1] (✊🏿)
+270B 1F3FB ; RGI_Emoji_Modifier_Sequence ; raised hand: light skin tone # E1.0 [1] (✋🏻)
+270B 1F3FC ; RGI_Emoji_Modifier_Sequence ; raised hand: medium-light skin tone # E1.0 [1] (✋🏼)
+270B 1F3FD ; RGI_Emoji_Modifier_Sequence ; raised hand: medium skin tone # E1.0 [1] (✋🏽)
+270B 1F3FE ; RGI_Emoji_Modifier_Sequence ; raised hand: medium-dark skin tone # E1.0 [1] (✋🏾)
+270B 1F3FF ; RGI_Emoji_Modifier_Sequence ; raised hand: dark skin tone # E1.0 [1] (✋🏿)
+270C 1F3FB ; RGI_Emoji_Modifier_Sequence ; victory hand: light skin tone # E1.0 [1] (✌🏻)
+270C 1F3FC ; RGI_Emoji_Modifier_Sequence ; victory hand: medium-light skin tone # E1.0 [1] (✌🏼)
+270C 1F3FD ; RGI_Emoji_Modifier_Sequence ; victory hand: medium skin tone # E1.0 [1] (✌🏽)
+270C 1F3FE ; RGI_Emoji_Modifier_Sequence ; victory hand: medium-dark skin tone # E1.0 [1] (✌🏾)
+270C 1F3FF ; RGI_Emoji_Modifier_Sequence ; victory hand: dark skin tone # E1.0 [1] (✌🏿)
+270D 1F3FB ; RGI_Emoji_Modifier_Sequence ; writing hand: light skin tone # E1.0 [1] (✍🏻)
+270D 1F3FC ; RGI_Emoji_Modifier_Sequence ; writing hand: medium-light skin tone # E1.0 [1] (✍🏼)
+270D 1F3FD ; RGI_Emoji_Modifier_Sequence ; writing hand: medium skin tone # E1.0 [1] (✍🏽)
+270D 1F3FE ; RGI_Emoji_Modifier_Sequence ; writing hand: medium-dark skin tone # E1.0 [1] (✍🏾)
+270D 1F3FF ; RGI_Emoji_Modifier_Sequence ; writing hand: dark skin tone # E1.0 [1] (✍🏿)
+1F385 1F3FB ; RGI_Emoji_Modifier_Sequence ; Santa Claus: light skin tone # E1.0 [1] (🎅🏻)
+1F385 1F3FC ; RGI_Emoji_Modifier_Sequence ; Santa Claus: medium-light skin tone # E1.0 [1] (🎅🏼)
+1F385 1F3FD ; RGI_Emoji_Modifier_Sequence ; Santa Claus: medium skin tone # E1.0 [1] (🎅🏽)
+1F385 1F3FE ; RGI_Emoji_Modifier_Sequence ; Santa Claus: medium-dark skin tone # E1.0 [1] (🎅🏾)
+1F385 1F3FF ; RGI_Emoji_Modifier_Sequence ; Santa Claus: dark skin tone # E1.0 [1] (🎅🏿)
+1F3C2 1F3FB ; RGI_Emoji_Modifier_Sequence ; snowboarder: light skin tone # E1.0 [1] (🏂🏻)
+1F3C2 1F3FC ; RGI_Emoji_Modifier_Sequence ; snowboarder: medium-light skin tone # E1.0 [1] (🏂🏼)
+1F3C2 1F3FD ; RGI_Emoji_Modifier_Sequence ; snowboarder: medium skin tone # E1.0 [1] (🏂🏽)
+1F3C2 1F3FE ; RGI_Emoji_Modifier_Sequence ; snowboarder: medium-dark skin tone # E1.0 [1] (🏂🏾)
+1F3C2 1F3FF ; RGI_Emoji_Modifier_Sequence ; snowboarder: dark skin tone # E1.0 [1] (🏂🏿)
+1F3C3 1F3FB ; RGI_Emoji_Modifier_Sequence ; person running: light skin tone # E1.0 [1] (🏃🏻)
+1F3C3 1F3FC ; RGI_Emoji_Modifier_Sequence ; person running: medium-light skin tone # E1.0 [1] (🏃🏼)
+1F3C3 1F3FD ; RGI_Emoji_Modifier_Sequence ; person running: medium skin tone # E1.0 [1] (🏃🏽)
+1F3C3 1F3FE ; RGI_Emoji_Modifier_Sequence ; person running: medium-dark skin tone # E1.0 [1] (🏃🏾)
+1F3C3 1F3FF ; RGI_Emoji_Modifier_Sequence ; person running: dark skin tone # E1.0 [1] (🏃🏿)
+1F3C4 1F3FB ; RGI_Emoji_Modifier_Sequence ; person surfing: light skin tone # E1.0 [1] (🏄🏻)
+1F3C4 1F3FC ; RGI_Emoji_Modifier_Sequence ; person surfing: medium-light skin tone # E1.0 [1] (🏄🏼)
+1F3C4 1F3FD ; RGI_Emoji_Modifier_Sequence ; person surfing: medium skin tone # E1.0 [1] (🏄🏽)
+1F3C4 1F3FE ; RGI_Emoji_Modifier_Sequence ; person surfing: medium-dark skin tone # E1.0 [1] (🏄🏾)
+1F3C4 1F3FF ; RGI_Emoji_Modifier_Sequence ; person surfing: dark skin tone # E1.0 [1] (🏄🏿)
+1F3C7 1F3FB ; RGI_Emoji_Modifier_Sequence ; horse racing: light skin tone # E1.0 [1] (🏇🏻)
+1F3C7 1F3FC ; RGI_Emoji_Modifier_Sequence ; horse racing: medium-light skin tone # E1.0 [1] (🏇🏼)
+1F3C7 1F3FD ; RGI_Emoji_Modifier_Sequence ; horse racing: medium skin tone # E1.0 [1] (🏇🏽)
+1F3C7 1F3FE ; RGI_Emoji_Modifier_Sequence ; horse racing: medium-dark skin tone # E1.0 [1] (🏇🏾)
+1F3C7 1F3FF ; RGI_Emoji_Modifier_Sequence ; horse racing: dark skin tone # E1.0 [1] (🏇🏿)
+1F3CA 1F3FB ; RGI_Emoji_Modifier_Sequence ; person swimming: light skin tone # E1.0 [1] (🏊🏻)
+1F3CA 1F3FC ; RGI_Emoji_Modifier_Sequence ; person swimming: medium-light skin tone # E1.0 [1] (🏊🏼)
+1F3CA 1F3FD ; RGI_Emoji_Modifier_Sequence ; person swimming: medium skin tone # E1.0 [1] (🏊🏽)
+1F3CA 1F3FE ; RGI_Emoji_Modifier_Sequence ; person swimming: medium-dark skin tone # E1.0 [1] (🏊🏾)
+1F3CA 1F3FF ; RGI_Emoji_Modifier_Sequence ; person swimming: dark skin tone # E1.0 [1] (🏊🏿)
+1F3CB 1F3FB ; RGI_Emoji_Modifier_Sequence ; person lifting weights: light skin tone # E2.0 [1] (🏋🏻)
+1F3CB 1F3FC ; RGI_Emoji_Modifier_Sequence ; person lifting weights: medium-light skin tone # E2.0 [1] (🏋🏼)
+1F3CB 1F3FD ; RGI_Emoji_Modifier_Sequence ; person lifting weights: medium skin tone # E2.0 [1] (🏋🏽)
+1F3CB 1F3FE ; RGI_Emoji_Modifier_Sequence ; person lifting weights: medium-dark skin tone # E2.0 [1] (🏋🏾)
+1F3CB 1F3FF ; RGI_Emoji_Modifier_Sequence ; person lifting weights: dark skin tone # E2.0 [1] (🏋🏿)
+1F3CC 1F3FB ; RGI_Emoji_Modifier_Sequence ; person golfing: light skin tone # E4.0 [1] (🏌🏻)
+1F3CC 1F3FC ; RGI_Emoji_Modifier_Sequence ; person golfing: medium-light skin tone # E4.0 [1] (🏌🏼)
+1F3CC 1F3FD ; RGI_Emoji_Modifier_Sequence ; person golfing: medium skin tone # E4.0 [1] (🏌🏽)
+1F3CC 1F3FE ; RGI_Emoji_Modifier_Sequence ; person golfing: medium-dark skin tone # E4.0 [1] (🏌🏾)
+1F3CC 1F3FF ; RGI_Emoji_Modifier_Sequence ; person golfing: dark skin tone # E4.0 [1] (🏌🏿)
+1F442 1F3FB ; RGI_Emoji_Modifier_Sequence ; ear: light skin tone # E1.0 [1] (👂🏻)
+1F442 1F3FC ; RGI_Emoji_Modifier_Sequence ; ear: medium-light skin tone # E1.0 [1] (👂🏼)
+1F442 1F3FD ; RGI_Emoji_Modifier_Sequence ; ear: medium skin tone # E1.0 [1] (👂🏽)
+1F442 1F3FE ; RGI_Emoji_Modifier_Sequence ; ear: medium-dark skin tone # E1.0 [1] (👂🏾)
+1F442 1F3FF ; RGI_Emoji_Modifier_Sequence ; ear: dark skin tone # E1.0 [1] (👂🏿)
+1F443 1F3FB ; RGI_Emoji_Modifier_Sequence ; nose: light skin tone # E1.0 [1] (👃🏻)
+1F443 1F3FC ; RGI_Emoji_Modifier_Sequence ; nose: medium-light skin tone # E1.0 [1] (👃🏼)
+1F443 1F3FD ; RGI_Emoji_Modifier_Sequence ; nose: medium skin tone # E1.0 [1] (👃🏽)
+1F443 1F3FE ; RGI_Emoji_Modifier_Sequence ; nose: medium-dark skin tone # E1.0 [1] (👃🏾)
+1F443 1F3FF ; RGI_Emoji_Modifier_Sequence ; nose: dark skin tone # E1.0 [1] (👃🏿)
+1F446 1F3FB ; RGI_Emoji_Modifier_Sequence ; backhand index pointing up: light skin tone # E1.0 [1] (👆🏻)
+1F446 1F3FC ; RGI_Emoji_Modifier_Sequence ; backhand index pointing up: medium-light skin tone # E1.0 [1] (👆🏼)
+1F446 1F3FD ; RGI_Emoji_Modifier_Sequence ; backhand index pointing up: medium skin tone # E1.0 [1] (👆🏽)
+1F446 1F3FE ; RGI_Emoji_Modifier_Sequence ; backhand index pointing up: medium-dark skin tone # E1.0 [1] (👆🏾)
+1F446 1F3FF ; RGI_Emoji_Modifier_Sequence ; backhand index pointing up: dark skin tone # E1.0 [1] (👆🏿)
+1F447 1F3FB ; RGI_Emoji_Modifier_Sequence ; backhand index pointing down: light skin tone # E1.0 [1] (👇🏻)
+1F447 1F3FC ; RGI_Emoji_Modifier_Sequence ; backhand index pointing down: medium-light skin tone # E1.0 [1] (👇🏼)
+1F447 1F3FD ; RGI_Emoji_Modifier_Sequence ; backhand index pointing down: medium skin tone # E1.0 [1] (👇🏽)
+1F447 1F3FE ; RGI_Emoji_Modifier_Sequence ; backhand index pointing down: medium-dark skin tone # E1.0 [1] (👇🏾)
+1F447 1F3FF ; RGI_Emoji_Modifier_Sequence ; backhand index pointing down: dark skin tone # E1.0 [1] (👇🏿)
+1F448 1F3FB ; RGI_Emoji_Modifier_Sequence ; backhand index pointing left: light skin tone # E1.0 [1] (👈🏻)
+1F448 1F3FC ; RGI_Emoji_Modifier_Sequence ; backhand index pointing left: medium-light skin tone # E1.0 [1] (👈🏼)
+1F448 1F3FD ; RGI_Emoji_Modifier_Sequence ; backhand index pointing left: medium skin tone # E1.0 [1] (👈🏽)
+1F448 1F3FE ; RGI_Emoji_Modifier_Sequence ; backhand index pointing left: medium-dark skin tone # E1.0 [1] (👈🏾)
+1F448 1F3FF ; RGI_Emoji_Modifier_Sequence ; backhand index pointing left: dark skin tone # E1.0 [1] (👈🏿)
+1F449 1F3FB ; RGI_Emoji_Modifier_Sequence ; backhand index pointing right: light skin tone # E1.0 [1] (👉🏻)
+1F449 1F3FC ; RGI_Emoji_Modifier_Sequence ; backhand index pointing right: medium-light skin tone # E1.0 [1] (👉🏼)
+1F449 1F3FD ; RGI_Emoji_Modifier_Sequence ; backhand index pointing right: medium skin tone # E1.0 [1] (👉🏽)
+1F449 1F3FE ; RGI_Emoji_Modifier_Sequence ; backhand index pointing right: medium-dark skin tone # E1.0 [1] (👉🏾)
+1F449 1F3FF ; RGI_Emoji_Modifier_Sequence ; backhand index pointing right: dark skin tone # E1.0 [1] (👉🏿)
+1F44A 1F3FB ; RGI_Emoji_Modifier_Sequence ; oncoming fist: light skin tone # E1.0 [1] (👊🏻)
+1F44A 1F3FC ; RGI_Emoji_Modifier_Sequence ; oncoming fist: medium-light skin tone # E1.0 [1] (👊🏼)
+1F44A 1F3FD ; RGI_Emoji_Modifier_Sequence ; oncoming fist: medium skin tone # E1.0 [1] (👊🏽)
+1F44A 1F3FE ; RGI_Emoji_Modifier_Sequence ; oncoming fist: medium-dark skin tone # E1.0 [1] (👊🏾)
+1F44A 1F3FF ; RGI_Emoji_Modifier_Sequence ; oncoming fist: dark skin tone # E1.0 [1] (👊🏿)
+1F44B 1F3FB ; RGI_Emoji_Modifier_Sequence ; waving hand: light skin tone # E1.0 [1] (👋🏻)
+1F44B 1F3FC ; RGI_Emoji_Modifier_Sequence ; waving hand: medium-light skin tone # E1.0 [1] (👋🏼)
+1F44B 1F3FD ; RGI_Emoji_Modifier_Sequence ; waving hand: medium skin tone # E1.0 [1] (👋🏽)
+1F44B 1F3FE ; RGI_Emoji_Modifier_Sequence ; waving hand: medium-dark skin tone # E1.0 [1] (👋🏾)
+1F44B 1F3FF ; RGI_Emoji_Modifier_Sequence ; waving hand: dark skin tone # E1.0 [1] (👋🏿)
+1F44C 1F3FB ; RGI_Emoji_Modifier_Sequence ; OK hand: light skin tone # E1.0 [1] (👌🏻)
+1F44C 1F3FC ; RGI_Emoji_Modifier_Sequence ; OK hand: medium-light skin tone # E1.0 [1] (👌🏼)
+1F44C 1F3FD ; RGI_Emoji_Modifier_Sequence ; OK hand: medium skin tone # E1.0 [1] (👌🏽)
+1F44C 1F3FE ; RGI_Emoji_Modifier_Sequence ; OK hand: medium-dark skin tone # E1.0 [1] (👌🏾)
+1F44C 1F3FF ; RGI_Emoji_Modifier_Sequence ; OK hand: dark skin tone # E1.0 [1] (👌🏿)
+1F44D 1F3FB ; RGI_Emoji_Modifier_Sequence ; thumbs up: light skin tone # E1.0 [1] (👍🏻)
+1F44D 1F3FC ; RGI_Emoji_Modifier_Sequence ; thumbs up: medium-light skin tone # E1.0 [1] (👍🏼)
+1F44D 1F3FD ; RGI_Emoji_Modifier_Sequence ; thumbs up: medium skin tone # E1.0 [1] (👍🏽)
+1F44D 1F3FE ; RGI_Emoji_Modifier_Sequence ; thumbs up: medium-dark skin tone # E1.0 [1] (👍🏾)
+1F44D 1F3FF ; RGI_Emoji_Modifier_Sequence ; thumbs up: dark skin tone # E1.0 [1] (👍🏿)
+1F44E 1F3FB ; RGI_Emoji_Modifier_Sequence ; thumbs down: light skin tone # E1.0 [1] (👎🏻)
+1F44E 1F3FC ; RGI_Emoji_Modifier_Sequence ; thumbs down: medium-light skin tone # E1.0 [1] (👎🏼)
+1F44E 1F3FD ; RGI_Emoji_Modifier_Sequence ; thumbs down: medium skin tone # E1.0 [1] (👎🏽)
+1F44E 1F3FE ; RGI_Emoji_Modifier_Sequence ; thumbs down: medium-dark skin tone # E1.0 [1] (👎🏾)
+1F44E 1F3FF ; RGI_Emoji_Modifier_Sequence ; thumbs down: dark skin tone # E1.0 [1] (👎🏿)
+1F44F 1F3FB ; RGI_Emoji_Modifier_Sequence ; clapping hands: light skin tone # E1.0 [1] (👏🏻)
+1F44F 1F3FC ; RGI_Emoji_Modifier_Sequence ; clapping hands: medium-light skin tone # E1.0 [1] (👏🏼)
+1F44F 1F3FD ; RGI_Emoji_Modifier_Sequence ; clapping hands: medium skin tone # E1.0 [1] (👏🏽)
+1F44F 1F3FE ; RGI_Emoji_Modifier_Sequence ; clapping hands: medium-dark skin tone # E1.0 [1] (👏🏾)
+1F44F 1F3FF ; RGI_Emoji_Modifier_Sequence ; clapping hands: dark skin tone # E1.0 [1] (👏🏿)
+1F450 1F3FB ; RGI_Emoji_Modifier_Sequence ; open hands: light skin tone # E1.0 [1] (👐🏻)
+1F450 1F3FC ; RGI_Emoji_Modifier_Sequence ; open hands: medium-light skin tone # E1.0 [1] (👐🏼)
+1F450 1F3FD ; RGI_Emoji_Modifier_Sequence ; open hands: medium skin tone # E1.0 [1] (👐🏽)
+1F450 1F3FE ; RGI_Emoji_Modifier_Sequence ; open hands: medium-dark skin tone # E1.0 [1] (👐🏾)
+1F450 1F3FF ; RGI_Emoji_Modifier_Sequence ; open hands: dark skin tone # E1.0 [1] (👐🏿)
+1F466 1F3FB ; RGI_Emoji_Modifier_Sequence ; boy: light skin tone # E1.0 [1] (👦🏻)
+1F466 1F3FC ; RGI_Emoji_Modifier_Sequence ; boy: medium-light skin tone # E1.0 [1] (👦🏼)
+1F466 1F3FD ; RGI_Emoji_Modifier_Sequence ; boy: medium skin tone # E1.0 [1] (👦🏽)
+1F466 1F3FE ; RGI_Emoji_Modifier_Sequence ; boy: medium-dark skin tone # E1.0 [1] (👦🏾)
+1F466 1F3FF ; RGI_Emoji_Modifier_Sequence ; boy: dark skin tone # E1.0 [1] (👦🏿)
+1F467 1F3FB ; RGI_Emoji_Modifier_Sequence ; girl: light skin tone # E1.0 [1] (👧🏻)
+1F467 1F3FC ; RGI_Emoji_Modifier_Sequence ; girl: medium-light skin tone # E1.0 [1] (👧🏼)
+1F467 1F3FD ; RGI_Emoji_Modifier_Sequence ; girl: medium skin tone # E1.0 [1] (👧🏽)
+1F467 1F3FE ; RGI_Emoji_Modifier_Sequence ; girl: medium-dark skin tone # E1.0 [1] (👧🏾)
+1F467 1F3FF ; RGI_Emoji_Modifier_Sequence ; girl: dark skin tone # E1.0 [1] (👧🏿)
+1F468 1F3FB ; RGI_Emoji_Modifier_Sequence ; man: light skin tone # E1.0 [1] (👨🏻)
+1F468 1F3FC ; RGI_Emoji_Modifier_Sequence ; man: medium-light skin tone # E1.0 [1] (👨🏼)
+1F468 1F3FD ; RGI_Emoji_Modifier_Sequence ; man: medium skin tone # E1.0 [1] (👨🏽)
+1F468 1F3FE ; RGI_Emoji_Modifier_Sequence ; man: medium-dark skin tone # E1.0 [1] (👨🏾)
+1F468 1F3FF ; RGI_Emoji_Modifier_Sequence ; man: dark skin tone # E1.0 [1] (👨🏿)
+1F469 1F3FB ; RGI_Emoji_Modifier_Sequence ; woman: light skin tone # E1.0 [1] (👩🏻)
+1F469 1F3FC ; RGI_Emoji_Modifier_Sequence ; woman: medium-light skin tone # E1.0 [1] (👩🏼)
+1F469 1F3FD ; RGI_Emoji_Modifier_Sequence ; woman: medium skin tone # E1.0 [1] (👩🏽)
+1F469 1F3FE ; RGI_Emoji_Modifier_Sequence ; woman: medium-dark skin tone # E1.0 [1] (👩🏾)
+1F469 1F3FF ; RGI_Emoji_Modifier_Sequence ; woman: dark skin tone # E1.0 [1] (👩🏿)
+1F46B 1F3FB ; RGI_Emoji_Modifier_Sequence ; woman and man holding hands: light skin tone # E12.0 [1] (👫🏻)
+1F46B 1F3FC ; RGI_Emoji_Modifier_Sequence ; woman and man holding hands: medium-light skin tone # E12.0 [1] (👫🏼)
+1F46B 1F3FD ; RGI_Emoji_Modifier_Sequence ; woman and man holding hands: medium skin tone # E12.0 [1] (👫🏽)
+1F46B 1F3FE ; RGI_Emoji_Modifier_Sequence ; woman and man holding hands: medium-dark skin tone # E12.0 [1] (👫🏾)
+1F46B 1F3FF ; RGI_Emoji_Modifier_Sequence ; woman and man holding hands: dark skin tone # E12.0 [1] (👫🏿)
+1F46C 1F3FB ; RGI_Emoji_Modifier_Sequence ; men holding hands: light skin tone # E12.0 [1] (👬🏻)
+1F46C 1F3FC ; RGI_Emoji_Modifier_Sequence ; men holding hands: medium-light skin tone # E12.0 [1] (👬🏼)
+1F46C 1F3FD ; RGI_Emoji_Modifier_Sequence ; men holding hands: medium skin tone # E12.0 [1] (👬🏽)
+1F46C 1F3FE ; RGI_Emoji_Modifier_Sequence ; men holding hands: medium-dark skin tone # E12.0 [1] (👬🏾)
+1F46C 1F3FF ; RGI_Emoji_Modifier_Sequence ; men holding hands: dark skin tone # E12.0 [1] (👬🏿)
+1F46D 1F3FB ; RGI_Emoji_Modifier_Sequence ; women holding hands: light skin tone # E12.0 [1] (👭🏻)
+1F46D 1F3FC ; RGI_Emoji_Modifier_Sequence ; women holding hands: medium-light skin tone # E12.0 [1] (👭🏼)
+1F46D 1F3FD ; RGI_Emoji_Modifier_Sequence ; women holding hands: medium skin tone # E12.0 [1] (👭🏽)
+1F46D 1F3FE ; RGI_Emoji_Modifier_Sequence ; women holding hands: medium-dark skin tone # E12.0 [1] (👭🏾)
+1F46D 1F3FF ; RGI_Emoji_Modifier_Sequence ; women holding hands: dark skin tone # E12.0 [1] (👭🏿)
+1F46E 1F3FB ; RGI_Emoji_Modifier_Sequence ; police officer: light skin tone # E1.0 [1] (👮🏻)
+1F46E 1F3FC ; RGI_Emoji_Modifier_Sequence ; police officer: medium-light skin tone # E1.0 [1] (👮🏼)
+1F46E 1F3FD ; RGI_Emoji_Modifier_Sequence ; police officer: medium skin tone # E1.0 [1] (👮🏽)
+1F46E 1F3FE ; RGI_Emoji_Modifier_Sequence ; police officer: medium-dark skin tone # E1.0 [1] (👮🏾)
+1F46E 1F3FF ; RGI_Emoji_Modifier_Sequence ; police officer: dark skin tone # E1.0 [1] (👮🏿)
+1F470 1F3FB ; RGI_Emoji_Modifier_Sequence ; person with veil: light skin tone # E1.0 [1] (👰🏻)
+1F470 1F3FC ; RGI_Emoji_Modifier_Sequence ; person with veil: medium-light skin tone # E1.0 [1] (👰🏼)
+1F470 1F3FD ; RGI_Emoji_Modifier_Sequence ; person with veil: medium skin tone # E1.0 [1] (👰🏽)
+1F470 1F3FE ; RGI_Emoji_Modifier_Sequence ; person with veil: medium-dark skin tone # E1.0 [1] (👰🏾)
+1F470 1F3FF ; RGI_Emoji_Modifier_Sequence ; person with veil: dark skin tone # E1.0 [1] (👰🏿)
+1F471 1F3FB ; RGI_Emoji_Modifier_Sequence ; person: light skin tone, blond hair # E1.0 [1] (👱🏻)
+1F471 1F3FC ; RGI_Emoji_Modifier_Sequence ; person: medium-light skin tone, blond hair # E1.0 [1] (👱🏼)
+1F471 1F3FD ; RGI_Emoji_Modifier_Sequence ; person: medium skin tone, blond hair # E1.0 [1] (👱🏽)
+1F471 1F3FE ; RGI_Emoji_Modifier_Sequence ; person: medium-dark skin tone, blond hair # E1.0 [1] (👱🏾)
+1F471 1F3FF ; RGI_Emoji_Modifier_Sequence ; person: dark skin tone, blond hair # E1.0 [1] (👱🏿)
+1F472 1F3FB ; RGI_Emoji_Modifier_Sequence ; person with skullcap: light skin tone # E1.0 [1] (👲🏻)
+1F472 1F3FC ; RGI_Emoji_Modifier_Sequence ; person with skullcap: medium-light skin tone # E1.0 [1] (👲🏼)
+1F472 1F3FD ; RGI_Emoji_Modifier_Sequence ; person with skullcap: medium skin tone # E1.0 [1] (👲🏽)
+1F472 1F3FE ; RGI_Emoji_Modifier_Sequence ; person with skullcap: medium-dark skin tone # E1.0 [1] (👲🏾)
+1F472 1F3FF ; RGI_Emoji_Modifier_Sequence ; person with skullcap: dark skin tone # E1.0 [1] (👲🏿)
+1F473 1F3FB ; RGI_Emoji_Modifier_Sequence ; person wearing turban: light skin tone # E1.0 [1] (👳🏻)
+1F473 1F3FC ; RGI_Emoji_Modifier_Sequence ; person wearing turban: medium-light skin tone # E1.0 [1] (👳🏼)
+1F473 1F3FD ; RGI_Emoji_Modifier_Sequence ; person wearing turban: medium skin tone # E1.0 [1] (👳🏽)
+1F473 1F3FE ; RGI_Emoji_Modifier_Sequence ; person wearing turban: medium-dark skin tone # E1.0 [1] (👳🏾)
+1F473 1F3FF ; RGI_Emoji_Modifier_Sequence ; person wearing turban: dark skin tone # E1.0 [1] (👳🏿)
+1F474 1F3FB ; RGI_Emoji_Modifier_Sequence ; old man: light skin tone # E1.0 [1] (👴🏻)
+1F474 1F3FC ; RGI_Emoji_Modifier_Sequence ; old man: medium-light skin tone # E1.0 [1] (👴🏼)
+1F474 1F3FD ; RGI_Emoji_Modifier_Sequence ; old man: medium skin tone # E1.0 [1] (👴🏽)
+1F474 1F3FE ; RGI_Emoji_Modifier_Sequence ; old man: medium-dark skin tone # E1.0 [1] (👴🏾)
+1F474 1F3FF ; RGI_Emoji_Modifier_Sequence ; old man: dark skin tone # E1.0 [1] (👴🏿)
+1F475 1F3FB ; RGI_Emoji_Modifier_Sequence ; old woman: light skin tone # E1.0 [1] (👵🏻)
+1F475 1F3FC ; RGI_Emoji_Modifier_Sequence ; old woman: medium-light skin tone # E1.0 [1] (👵🏼)
+1F475 1F3FD ; RGI_Emoji_Modifier_Sequence ; old woman: medium skin tone # E1.0 [1] (👵🏽)
+1F475 1F3FE ; RGI_Emoji_Modifier_Sequence ; old woman: medium-dark skin tone # E1.0 [1] (👵🏾)
+1F475 1F3FF ; RGI_Emoji_Modifier_Sequence ; old woman: dark skin tone # E1.0 [1] (👵🏿)
+1F476 1F3FB ; RGI_Emoji_Modifier_Sequence ; baby: light skin tone # E1.0 [1] (👶🏻)
+1F476 1F3FC ; RGI_Emoji_Modifier_Sequence ; baby: medium-light skin tone # E1.0 [1] (👶🏼)
+1F476 1F3FD ; RGI_Emoji_Modifier_Sequence ; baby: medium skin tone # E1.0 [1] (👶🏽)
+1F476 1F3FE ; RGI_Emoji_Modifier_Sequence ; baby: medium-dark skin tone # E1.0 [1] (👶🏾)
+1F476 1F3FF ; RGI_Emoji_Modifier_Sequence ; baby: dark skin tone # E1.0 [1] (👶🏿)
+1F477 1F3FB ; RGI_Emoji_Modifier_Sequence ; construction worker: light skin tone # E1.0 [1] (👷🏻)
+1F477 1F3FC ; RGI_Emoji_Modifier_Sequence ; construction worker: medium-light skin tone # E1.0 [1] (👷🏼)
+1F477 1F3FD ; RGI_Emoji_Modifier_Sequence ; construction worker: medium skin tone # E1.0 [1] (👷🏽)
+1F477 1F3FE ; RGI_Emoji_Modifier_Sequence ; construction worker: medium-dark skin tone # E1.0 [1] (👷🏾)
+1F477 1F3FF ; RGI_Emoji_Modifier_Sequence ; construction worker: dark skin tone # E1.0 [1] (👷🏿)
+1F478 1F3FB ; RGI_Emoji_Modifier_Sequence ; princess: light skin tone # E1.0 [1] (👸🏻)
+1F478 1F3FC ; RGI_Emoji_Modifier_Sequence ; princess: medium-light skin tone # E1.0 [1] (👸🏼)
+1F478 1F3FD ; RGI_Emoji_Modifier_Sequence ; princess: medium skin tone # E1.0 [1] (👸🏽)
+1F478 1F3FE ; RGI_Emoji_Modifier_Sequence ; princess: medium-dark skin tone # E1.0 [1] (👸🏾)
+1F478 1F3FF ; RGI_Emoji_Modifier_Sequence ; princess: dark skin tone # E1.0 [1] (👸🏿)
+1F47C 1F3FB ; RGI_Emoji_Modifier_Sequence ; baby angel: light skin tone # E1.0 [1] (👼🏻)
+1F47C 1F3FC ; RGI_Emoji_Modifier_Sequence ; baby angel: medium-light skin tone # E1.0 [1] (👼🏼)
+1F47C 1F3FD ; RGI_Emoji_Modifier_Sequence ; baby angel: medium skin tone # E1.0 [1] (👼🏽)
+1F47C 1F3FE ; RGI_Emoji_Modifier_Sequence ; baby angel: medium-dark skin tone # E1.0 [1] (👼🏾)
+1F47C 1F3FF ; RGI_Emoji_Modifier_Sequence ; baby angel: dark skin tone # E1.0 [1] (👼🏿)
+1F481 1F3FB ; RGI_Emoji_Modifier_Sequence ; person tipping hand: light skin tone # E1.0 [1] (💁🏻)
+1F481 1F3FC ; RGI_Emoji_Modifier_Sequence ; person tipping hand: medium-light skin tone # E1.0 [1] (💁🏼)
+1F481 1F3FD ; RGI_Emoji_Modifier_Sequence ; person tipping hand: medium skin tone # E1.0 [1] (💁🏽)
+1F481 1F3FE ; RGI_Emoji_Modifier_Sequence ; person tipping hand: medium-dark skin tone # E1.0 [1] (💁🏾)
+1F481 1F3FF ; RGI_Emoji_Modifier_Sequence ; person tipping hand: dark skin tone # E1.0 [1] (💁🏿)
+1F482 1F3FB ; RGI_Emoji_Modifier_Sequence ; guard: light skin tone # E1.0 [1] (💂🏻)
+1F482 1F3FC ; RGI_Emoji_Modifier_Sequence ; guard: medium-light skin tone # E1.0 [1] (💂🏼)
+1F482 1F3FD ; RGI_Emoji_Modifier_Sequence ; guard: medium skin tone # E1.0 [1] (💂🏽)
+1F482 1F3FE ; RGI_Emoji_Modifier_Sequence ; guard: medium-dark skin tone # E1.0 [1] (💂🏾)
+1F482 1F3FF ; RGI_Emoji_Modifier_Sequence ; guard: dark skin tone # E1.0 [1] (💂🏿)
+1F483 1F3FB ; RGI_Emoji_Modifier_Sequence ; woman dancing: light skin tone # E1.0 [1] (💃🏻)
+1F483 1F3FC ; RGI_Emoji_Modifier_Sequence ; woman dancing: medium-light skin tone # E1.0 [1] (💃🏼)
+1F483 1F3FD ; RGI_Emoji_Modifier_Sequence ; woman dancing: medium skin tone # E1.0 [1] (💃🏽)
+1F483 1F3FE ; RGI_Emoji_Modifier_Sequence ; woman dancing: medium-dark skin tone # E1.0 [1] (💃🏾)
+1F483 1F3FF ; RGI_Emoji_Modifier_Sequence ; woman dancing: dark skin tone # E1.0 [1] (💃🏿)
+1F485 1F3FB ; RGI_Emoji_Modifier_Sequence ; nail polish: light skin tone # E1.0 [1] (💅🏻)
+1F485 1F3FC ; RGI_Emoji_Modifier_Sequence ; nail polish: medium-light skin tone # E1.0 [1] (💅🏼)
+1F485 1F3FD ; RGI_Emoji_Modifier_Sequence ; nail polish: medium skin tone # E1.0 [1] (💅🏽)
+1F485 1F3FE ; RGI_Emoji_Modifier_Sequence ; nail polish: medium-dark skin tone # E1.0 [1] (💅🏾)
+1F485 1F3FF ; RGI_Emoji_Modifier_Sequence ; nail polish: dark skin tone # E1.0 [1] (💅🏿)
+1F486 1F3FB ; RGI_Emoji_Modifier_Sequence ; person getting massage: light skin tone # E1.0 [1] (💆🏻)
+1F486 1F3FC ; RGI_Emoji_Modifier_Sequence ; person getting massage: medium-light skin tone # E1.0 [1] (💆🏼)
+1F486 1F3FD ; RGI_Emoji_Modifier_Sequence ; person getting massage: medium skin tone # E1.0 [1] (💆🏽)
+1F486 1F3FE ; RGI_Emoji_Modifier_Sequence ; person getting massage: medium-dark skin tone # E1.0 [1] (💆🏾)
+1F486 1F3FF ; RGI_Emoji_Modifier_Sequence ; person getting massage: dark skin tone # E1.0 [1] (💆🏿)
+1F487 1F3FB ; RGI_Emoji_Modifier_Sequence ; person getting haircut: light skin tone # E1.0 [1] (💇🏻)
+1F487 1F3FC ; RGI_Emoji_Modifier_Sequence ; person getting haircut: medium-light skin tone # E1.0 [1] (💇🏼)
+1F487 1F3FD ; RGI_Emoji_Modifier_Sequence ; person getting haircut: medium skin tone # E1.0 [1] (💇🏽)
+1F487 1F3FE ; RGI_Emoji_Modifier_Sequence ; person getting haircut: medium-dark skin tone # E1.0 [1] (💇🏾)
+1F487 1F3FF ; RGI_Emoji_Modifier_Sequence ; person getting haircut: dark skin tone # E1.0 [1] (💇🏿)
+1F48F 1F3FB ; RGI_Emoji_Modifier_Sequence ; kiss: light skin tone # E13.1 [1] (💏🏻)
+1F48F 1F3FC ; RGI_Emoji_Modifier_Sequence ; kiss: medium-light skin tone # E13.1 [1] (💏🏼)
+1F48F 1F3FD ; RGI_Emoji_Modifier_Sequence ; kiss: medium skin tone # E13.1 [1] (💏🏽)
+1F48F 1F3FE ; RGI_Emoji_Modifier_Sequence ; kiss: medium-dark skin tone # E13.1 [1] (💏🏾)
+1F48F 1F3FF ; RGI_Emoji_Modifier_Sequence ; kiss: dark skin tone # E13.1 [1] (💏🏿)
+1F491 1F3FB ; RGI_Emoji_Modifier_Sequence ; couple with heart: light skin tone # E13.1 [1] (💑🏻)
+1F491 1F3FC ; RGI_Emoji_Modifier_Sequence ; couple with heart: medium-light skin tone # E13.1 [1] (💑🏼)
+1F491 1F3FD ; RGI_Emoji_Modifier_Sequence ; couple with heart: medium skin tone # E13.1 [1] (💑🏽)
+1F491 1F3FE ; RGI_Emoji_Modifier_Sequence ; couple with heart: medium-dark skin tone # E13.1 [1] (💑🏾)
+1F491 1F3FF ; RGI_Emoji_Modifier_Sequence ; couple with heart: dark skin tone # E13.1 [1] (💑🏿)
+1F4AA 1F3FB ; RGI_Emoji_Modifier_Sequence ; flexed biceps: light skin tone # E1.0 [1] (💪🏻)
+1F4AA 1F3FC ; RGI_Emoji_Modifier_Sequence ; flexed biceps: medium-light skin tone # E1.0 [1] (💪🏼)
+1F4AA 1F3FD ; RGI_Emoji_Modifier_Sequence ; flexed biceps: medium skin tone # E1.0 [1] (💪🏽)
+1F4AA 1F3FE ; RGI_Emoji_Modifier_Sequence ; flexed biceps: medium-dark skin tone # E1.0 [1] (💪🏾)
+1F4AA 1F3FF ; RGI_Emoji_Modifier_Sequence ; flexed biceps: dark skin tone # E1.0 [1] (💪🏿)
+1F574 1F3FB ; RGI_Emoji_Modifier_Sequence ; person in suit levitating: light skin tone # E4.0 [1] (🕴🏻)
+1F574 1F3FC ; RGI_Emoji_Modifier_Sequence ; person in suit levitating: medium-light skin tone # E4.0 [1] (🕴🏼)
+1F574 1F3FD ; RGI_Emoji_Modifier_Sequence ; person in suit levitating: medium skin tone # E4.0 [1] (🕴🏽)
+1F574 1F3FE ; RGI_Emoji_Modifier_Sequence ; person in suit levitating: medium-dark skin tone # E4.0 [1] (🕴🏾)
+1F574 1F3FF ; RGI_Emoji_Modifier_Sequence ; person in suit levitating: dark skin tone # E4.0 [1] (🕴🏿)
+1F575 1F3FB ; RGI_Emoji_Modifier_Sequence ; detective: light skin tone # E2.0 [1] (🕵🏻)
+1F575 1F3FC ; RGI_Emoji_Modifier_Sequence ; detective: medium-light skin tone # E2.0 [1] (🕵🏼)
+1F575 1F3FD ; RGI_Emoji_Modifier_Sequence ; detective: medium skin tone # E2.0 [1] (🕵🏽)
+1F575 1F3FE ; RGI_Emoji_Modifier_Sequence ; detective: medium-dark skin tone # E2.0 [1] (🕵🏾)
+1F575 1F3FF ; RGI_Emoji_Modifier_Sequence ; detective: dark skin tone # E2.0 [1] (🕵🏿)
+1F57A 1F3FB ; RGI_Emoji_Modifier_Sequence ; man dancing: light skin tone # E3.0 [1] (🕺🏻)
+1F57A 1F3FC ; RGI_Emoji_Modifier_Sequence ; man dancing: medium-light skin tone # E3.0 [1] (🕺🏼)
+1F57A 1F3FD ; RGI_Emoji_Modifier_Sequence ; man dancing: medium skin tone # E3.0 [1] (🕺🏽)
+1F57A 1F3FE ; RGI_Emoji_Modifier_Sequence ; man dancing: medium-dark skin tone # E3.0 [1] (🕺🏾)
+1F57A 1F3FF ; RGI_Emoji_Modifier_Sequence ; man dancing: dark skin tone # E3.0 [1] (🕺🏿)
+1F590 1F3FB ; RGI_Emoji_Modifier_Sequence ; hand with fingers splayed: light skin tone # E1.0 [1] (🖐🏻)
+1F590 1F3FC ; RGI_Emoji_Modifier_Sequence ; hand with fingers splayed: medium-light skin tone # E1.0 [1] (🖐🏼)
+1F590 1F3FD ; RGI_Emoji_Modifier_Sequence ; hand with fingers splayed: medium skin tone # E1.0 [1] (🖐🏽)
+1F590 1F3FE ; RGI_Emoji_Modifier_Sequence ; hand with fingers splayed: medium-dark skin tone # E1.0 [1] (🖐🏾)
+1F590 1F3FF ; RGI_Emoji_Modifier_Sequence ; hand with fingers splayed: dark skin tone # E1.0 [1] (🖐🏿)
+1F595 1F3FB ; RGI_Emoji_Modifier_Sequence ; middle finger: light skin tone # E1.0 [1] (🖕🏻)
+1F595 1F3FC ; RGI_Emoji_Modifier_Sequence ; middle finger: medium-light skin tone # E1.0 [1] (🖕🏼)
+1F595 1F3FD ; RGI_Emoji_Modifier_Sequence ; middle finger: medium skin tone # E1.0 [1] (🖕🏽)
+1F595 1F3FE ; RGI_Emoji_Modifier_Sequence ; middle finger: medium-dark skin tone # E1.0 [1] (🖕🏾)
+1F595 1F3FF ; RGI_Emoji_Modifier_Sequence ; middle finger: dark skin tone # E1.0 [1] (🖕🏿)
+1F596 1F3FB ; RGI_Emoji_Modifier_Sequence ; vulcan salute: light skin tone # E1.0 [1] (🖖🏻)
+1F596 1F3FC ; RGI_Emoji_Modifier_Sequence ; vulcan salute: medium-light skin tone # E1.0 [1] (🖖🏼)
+1F596 1F3FD ; RGI_Emoji_Modifier_Sequence ; vulcan salute: medium skin tone # E1.0 [1] (🖖🏽)
+1F596 1F3FE ; RGI_Emoji_Modifier_Sequence ; vulcan salute: medium-dark skin tone # E1.0 [1] (🖖🏾)
+1F596 1F3FF ; RGI_Emoji_Modifier_Sequence ; vulcan salute: dark skin tone # E1.0 [1] (🖖🏿)
+1F645 1F3FB ; RGI_Emoji_Modifier_Sequence ; person gesturing NO: light skin tone # E1.0 [1] (🙅🏻)
+1F645 1F3FC ; RGI_Emoji_Modifier_Sequence ; person gesturing NO: medium-light skin tone # E1.0 [1] (🙅🏼)
+1F645 1F3FD ; RGI_Emoji_Modifier_Sequence ; person gesturing NO: medium skin tone # E1.0 [1] (🙅🏽)
+1F645 1F3FE ; RGI_Emoji_Modifier_Sequence ; person gesturing NO: medium-dark skin tone # E1.0 [1] (🙅🏾)
+1F645 1F3FF ; RGI_Emoji_Modifier_Sequence ; person gesturing NO: dark skin tone # E1.0 [1] (🙅🏿)
+1F646 1F3FB ; RGI_Emoji_Modifier_Sequence ; person gesturing OK: light skin tone # E1.0 [1] (🙆🏻)
+1F646 1F3FC ; RGI_Emoji_Modifier_Sequence ; person gesturing OK: medium-light skin tone # E1.0 [1] (🙆🏼)
+1F646 1F3FD ; RGI_Emoji_Modifier_Sequence ; person gesturing OK: medium skin tone # E1.0 [1] (🙆🏽)
+1F646 1F3FE ; RGI_Emoji_Modifier_Sequence ; person gesturing OK: medium-dark skin tone # E1.0 [1] (🙆🏾)
+1F646 1F3FF ; RGI_Emoji_Modifier_Sequence ; person gesturing OK: dark skin tone # E1.0 [1] (🙆🏿)
+1F647 1F3FB ; RGI_Emoji_Modifier_Sequence ; person bowing: light skin tone # E1.0 [1] (🙇🏻)
+1F647 1F3FC ; RGI_Emoji_Modifier_Sequence ; person bowing: medium-light skin tone # E1.0 [1] (🙇🏼)
+1F647 1F3FD ; RGI_Emoji_Modifier_Sequence ; person bowing: medium skin tone # E1.0 [1] (🙇🏽)
+1F647 1F3FE ; RGI_Emoji_Modifier_Sequence ; person bowing: medium-dark skin tone # E1.0 [1] (🙇🏾)
+1F647 1F3FF ; RGI_Emoji_Modifier_Sequence ; person bowing: dark skin tone # E1.0 [1] (🙇🏿)
+1F64B 1F3FB ; RGI_Emoji_Modifier_Sequence ; person raising hand: light skin tone # E1.0 [1] (🙋🏻)
+1F64B 1F3FC ; RGI_Emoji_Modifier_Sequence ; person raising hand: medium-light skin tone # E1.0 [1] (🙋🏼)
+1F64B 1F3FD ; RGI_Emoji_Modifier_Sequence ; person raising hand: medium skin tone # E1.0 [1] (🙋🏽)
+1F64B 1F3FE ; RGI_Emoji_Modifier_Sequence ; person raising hand: medium-dark skin tone # E1.0 [1] (🙋🏾)
+1F64B 1F3FF ; RGI_Emoji_Modifier_Sequence ; person raising hand: dark skin tone # E1.0 [1] (🙋🏿)
+1F64C 1F3FB ; RGI_Emoji_Modifier_Sequence ; raising hands: light skin tone # E1.0 [1] (🙌🏻)
+1F64C 1F3FC ; RGI_Emoji_Modifier_Sequence ; raising hands: medium-light skin tone # E1.0 [1] (🙌🏼)
+1F64C 1F3FD ; RGI_Emoji_Modifier_Sequence ; raising hands: medium skin tone # E1.0 [1] (🙌🏽)
+1F64C 1F3FE ; RGI_Emoji_Modifier_Sequence ; raising hands: medium-dark skin tone # E1.0 [1] (🙌🏾)
+1F64C 1F3FF ; RGI_Emoji_Modifier_Sequence ; raising hands: dark skin tone # E1.0 [1] (🙌🏿)
+1F64D 1F3FB ; RGI_Emoji_Modifier_Sequence ; person frowning: light skin tone # E1.0 [1] (🙍🏻)
+1F64D 1F3FC ; RGI_Emoji_Modifier_Sequence ; person frowning: medium-light skin tone # E1.0 [1] (🙍🏼)
+1F64D 1F3FD ; RGI_Emoji_Modifier_Sequence ; person frowning: medium skin tone # E1.0 [1] (🙍🏽)
+1F64D 1F3FE ; RGI_Emoji_Modifier_Sequence ; person frowning: medium-dark skin tone # E1.0 [1] (🙍🏾)
+1F64D 1F3FF ; RGI_Emoji_Modifier_Sequence ; person frowning: dark skin tone # E1.0 [1] (🙍🏿)
+1F64E 1F3FB ; RGI_Emoji_Modifier_Sequence ; person pouting: light skin tone # E1.0 [1] (🙎🏻)
+1F64E 1F3FC ; RGI_Emoji_Modifier_Sequence ; person pouting: medium-light skin tone # E1.0 [1] (🙎🏼)
+1F64E 1F3FD ; RGI_Emoji_Modifier_Sequence ; person pouting: medium skin tone # E1.0 [1] (🙎🏽)
+1F64E 1F3FE ; RGI_Emoji_Modifier_Sequence ; person pouting: medium-dark skin tone # E1.0 [1] (🙎🏾)
+1F64E 1F3FF ; RGI_Emoji_Modifier_Sequence ; person pouting: dark skin tone # E1.0 [1] (🙎🏿)
+1F64F 1F3FB ; RGI_Emoji_Modifier_Sequence ; folded hands: light skin tone # E1.0 [1] (🙏🏻)
+1F64F 1F3FC ; RGI_Emoji_Modifier_Sequence ; folded hands: medium-light skin tone # E1.0 [1] (🙏🏼)
+1F64F 1F3FD ; RGI_Emoji_Modifier_Sequence ; folded hands: medium skin tone # E1.0 [1] (🙏🏽)
+1F64F 1F3FE ; RGI_Emoji_Modifier_Sequence ; folded hands: medium-dark skin tone # E1.0 [1] (🙏🏾)
+1F64F 1F3FF ; RGI_Emoji_Modifier_Sequence ; folded hands: dark skin tone # E1.0 [1] (🙏🏿)
+1F6A3 1F3FB ; RGI_Emoji_Modifier_Sequence ; person rowing boat: light skin tone # E1.0 [1] (🚣🏻)
+1F6A3 1F3FC ; RGI_Emoji_Modifier_Sequence ; person rowing boat: medium-light skin tone # E1.0 [1] (🚣🏼)
+1F6A3 1F3FD ; RGI_Emoji_Modifier_Sequence ; person rowing boat: medium skin tone # E1.0 [1] (🚣🏽)
+1F6A3 1F3FE ; RGI_Emoji_Modifier_Sequence ; person rowing boat: medium-dark skin tone # E1.0 [1] (🚣🏾)
+1F6A3 1F3FF ; RGI_Emoji_Modifier_Sequence ; person rowing boat: dark skin tone # E1.0 [1] (🚣🏿)
+1F6B4 1F3FB ; RGI_Emoji_Modifier_Sequence ; person biking: light skin tone # E1.0 [1] (🚴🏻)
+1F6B4 1F3FC ; RGI_Emoji_Modifier_Sequence ; person biking: medium-light skin tone # E1.0 [1] (🚴🏼)
+1F6B4 1F3FD ; RGI_Emoji_Modifier_Sequence ; person biking: medium skin tone # E1.0 [1] (🚴🏽)
+1F6B4 1F3FE ; RGI_Emoji_Modifier_Sequence ; person biking: medium-dark skin tone # E1.0 [1] (🚴🏾)
+1F6B4 1F3FF ; RGI_Emoji_Modifier_Sequence ; person biking: dark skin tone # E1.0 [1] (🚴🏿)
+1F6B5 1F3FB ; RGI_Emoji_Modifier_Sequence ; person mountain biking: light skin tone # E1.0 [1] (🚵🏻)
+1F6B5 1F3FC ; RGI_Emoji_Modifier_Sequence ; person mountain biking: medium-light skin tone # E1.0 [1] (🚵🏼)
+1F6B5 1F3FD ; RGI_Emoji_Modifier_Sequence ; person mountain biking: medium skin tone # E1.0 [1] (🚵🏽)
+1F6B5 1F3FE ; RGI_Emoji_Modifier_Sequence ; person mountain biking: medium-dark skin tone # E1.0 [1] (🚵🏾)
+1F6B5 1F3FF ; RGI_Emoji_Modifier_Sequence ; person mountain biking: dark skin tone # E1.0 [1] (🚵🏿)
+1F6B6 1F3FB ; RGI_Emoji_Modifier_Sequence ; person walking: light skin tone # E1.0 [1] (🚶🏻)
+1F6B6 1F3FC ; RGI_Emoji_Modifier_Sequence ; person walking: medium-light skin tone # E1.0 [1] (🚶🏼)
+1F6B6 1F3FD ; RGI_Emoji_Modifier_Sequence ; person walking: medium skin tone # E1.0 [1] (🚶🏽)
+1F6B6 1F3FE ; RGI_Emoji_Modifier_Sequence ; person walking: medium-dark skin tone # E1.0 [1] (🚶🏾)
+1F6B6 1F3FF ; RGI_Emoji_Modifier_Sequence ; person walking: dark skin tone # E1.0 [1] (🚶🏿)
+1F6C0 1F3FB ; RGI_Emoji_Modifier_Sequence ; person taking bath: light skin tone # E1.0 [1] (🛀🏻)
+1F6C0 1F3FC ; RGI_Emoji_Modifier_Sequence ; person taking bath: medium-light skin tone # E1.0 [1] (🛀🏼)
+1F6C0 1F3FD ; RGI_Emoji_Modifier_Sequence ; person taking bath: medium skin tone # E1.0 [1] (🛀🏽)
+1F6C0 1F3FE ; RGI_Emoji_Modifier_Sequence ; person taking bath: medium-dark skin tone # E1.0 [1] (🛀🏾)
+1F6C0 1F3FF ; RGI_Emoji_Modifier_Sequence ; person taking bath: dark skin tone # E1.0 [1] (🛀🏿)
+1F6CC 1F3FB ; RGI_Emoji_Modifier_Sequence ; person in bed: light skin tone # E4.0 [1] (🛌🏻)
+1F6CC 1F3FC ; RGI_Emoji_Modifier_Sequence ; person in bed: medium-light skin tone # E4.0 [1] (🛌🏼)
+1F6CC 1F3FD ; RGI_Emoji_Modifier_Sequence ; person in bed: medium skin tone # E4.0 [1] (🛌🏽)
+1F6CC 1F3FE ; RGI_Emoji_Modifier_Sequence ; person in bed: medium-dark skin tone # E4.0 [1] (🛌🏾)
+1F6CC 1F3FF ; RGI_Emoji_Modifier_Sequence ; person in bed: dark skin tone # E4.0 [1] (🛌🏿)
+1F90C 1F3FB ; RGI_Emoji_Modifier_Sequence ; pinched fingers: light skin tone # E13.0 [1] (🤌🏻)
+1F90C 1F3FC ; RGI_Emoji_Modifier_Sequence ; pinched fingers: medium-light skin tone # E13.0 [1] (🤌🏼)
+1F90C 1F3FD ; RGI_Emoji_Modifier_Sequence ; pinched fingers: medium skin tone # E13.0 [1] (🤌🏽)
+1F90C 1F3FE ; RGI_Emoji_Modifier_Sequence ; pinched fingers: medium-dark skin tone # E13.0 [1] (🤌🏾)
+1F90C 1F3FF ; RGI_Emoji_Modifier_Sequence ; pinched fingers: dark skin tone # E13.0 [1] (🤌🏿)
+1F90F 1F3FB ; RGI_Emoji_Modifier_Sequence ; pinching hand: light skin tone # E12.0 [1] (🤏🏻)
+1F90F 1F3FC ; RGI_Emoji_Modifier_Sequence ; pinching hand: medium-light skin tone # E12.0 [1] (🤏🏼)
+1F90F 1F3FD ; RGI_Emoji_Modifier_Sequence ; pinching hand: medium skin tone # E12.0 [1] (🤏🏽)
+1F90F 1F3FE ; RGI_Emoji_Modifier_Sequence ; pinching hand: medium-dark skin tone # E12.0 [1] (🤏🏾)
+1F90F 1F3FF ; RGI_Emoji_Modifier_Sequence ; pinching hand: dark skin tone # E12.0 [1] (🤏🏿)
+1F918 1F3FB ; RGI_Emoji_Modifier_Sequence ; sign of the horns: light skin tone # E1.0 [1] (🤘🏻)
+1F918 1F3FC ; RGI_Emoji_Modifier_Sequence ; sign of the horns: medium-light skin tone # E1.0 [1] (🤘🏼)
+1F918 1F3FD ; RGI_Emoji_Modifier_Sequence ; sign of the horns: medium skin tone # E1.0 [1] (🤘🏽)
+1F918 1F3FE ; RGI_Emoji_Modifier_Sequence ; sign of the horns: medium-dark skin tone # E1.0 [1] (🤘🏾)
+1F918 1F3FF ; RGI_Emoji_Modifier_Sequence ; sign of the horns: dark skin tone # E1.0 [1] (🤘🏿)
+1F919 1F3FB ; RGI_Emoji_Modifier_Sequence ; call me hand: light skin tone # E3.0 [1] (🤙🏻)
+1F919 1F3FC ; RGI_Emoji_Modifier_Sequence ; call me hand: medium-light skin tone # E3.0 [1] (🤙🏼)
+1F919 1F3FD ; RGI_Emoji_Modifier_Sequence ; call me hand: medium skin tone # E3.0 [1] (🤙🏽)
+1F919 1F3FE ; RGI_Emoji_Modifier_Sequence ; call me hand: medium-dark skin tone # E3.0 [1] (🤙🏾)
+1F919 1F3FF ; RGI_Emoji_Modifier_Sequence ; call me hand: dark skin tone # E3.0 [1] (🤙🏿)
+1F91A 1F3FB ; RGI_Emoji_Modifier_Sequence ; raised back of hand: light skin tone # E3.0 [1] (🤚🏻)
+1F91A 1F3FC ; RGI_Emoji_Modifier_Sequence ; raised back of hand: medium-light skin tone # E3.0 [1] (🤚🏼)
+1F91A 1F3FD ; RGI_Emoji_Modifier_Sequence ; raised back of hand: medium skin tone # E3.0 [1] (🤚🏽)
+1F91A 1F3FE ; RGI_Emoji_Modifier_Sequence ; raised back of hand: medium-dark skin tone # E3.0 [1] (🤚🏾)
+1F91A 1F3FF ; RGI_Emoji_Modifier_Sequence ; raised back of hand: dark skin tone # E3.0 [1] (🤚🏿)
+1F91B 1F3FB ; RGI_Emoji_Modifier_Sequence ; left-facing fist: light skin tone # E3.0 [1] (🤛🏻)
+1F91B 1F3FC ; RGI_Emoji_Modifier_Sequence ; left-facing fist: medium-light skin tone # E3.0 [1] (🤛🏼)
+1F91B 1F3FD ; RGI_Emoji_Modifier_Sequence ; left-facing fist: medium skin tone # E3.0 [1] (🤛🏽)
+1F91B 1F3FE ; RGI_Emoji_Modifier_Sequence ; left-facing fist: medium-dark skin tone # E3.0 [1] (🤛🏾)
+1F91B 1F3FF ; RGI_Emoji_Modifier_Sequence ; left-facing fist: dark skin tone # E3.0 [1] (🤛🏿)
+1F91C 1F3FB ; RGI_Emoji_Modifier_Sequence ; right-facing fist: light skin tone # E3.0 [1] (🤜🏻)
+1F91C 1F3FC ; RGI_Emoji_Modifier_Sequence ; right-facing fist: medium-light skin tone # E3.0 [1] (🤜🏼)
+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] (🤝🏿)
+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] (🤞🏽)
+1F91E 1F3FE ; RGI_Emoji_Modifier_Sequence ; crossed fingers: medium-dark skin tone # E3.0 [1] (🤞🏾)
+1F91E 1F3FF ; RGI_Emoji_Modifier_Sequence ; crossed fingers: dark skin tone # E3.0 [1] (🤞🏿)
+1F91F 1F3FB ; RGI_Emoji_Modifier_Sequence ; love-you gesture: light skin tone # E5.0 [1] (🤟🏻)
+1F91F 1F3FC ; RGI_Emoji_Modifier_Sequence ; love-you gesture: medium-light skin tone # E5.0 [1] (🤟🏼)
+1F91F 1F3FD ; RGI_Emoji_Modifier_Sequence ; love-you gesture: medium skin tone # E5.0 [1] (🤟🏽)
+1F91F 1F3FE ; RGI_Emoji_Modifier_Sequence ; love-you gesture: medium-dark skin tone # E5.0 [1] (🤟🏾)
+1F91F 1F3FF ; RGI_Emoji_Modifier_Sequence ; love-you gesture: dark skin tone # E5.0 [1] (🤟🏿)
+1F926 1F3FB ; RGI_Emoji_Modifier_Sequence ; person facepalming: light skin tone # E3.0 [1] (🤦🏻)
+1F926 1F3FC ; RGI_Emoji_Modifier_Sequence ; person facepalming: medium-light skin tone # E3.0 [1] (🤦🏼)
+1F926 1F3FD ; RGI_Emoji_Modifier_Sequence ; person facepalming: medium skin tone # E3.0 [1] (🤦🏽)
+1F926 1F3FE ; RGI_Emoji_Modifier_Sequence ; person facepalming: medium-dark skin tone # E3.0 [1] (🤦🏾)
+1F926 1F3FF ; RGI_Emoji_Modifier_Sequence ; person facepalming: dark skin tone # E3.0 [1] (🤦🏿)
+1F930 1F3FB ; RGI_Emoji_Modifier_Sequence ; pregnant woman: light skin tone # E3.0 [1] (🤰🏻)
+1F930 1F3FC ; RGI_Emoji_Modifier_Sequence ; pregnant woman: medium-light skin tone # E3.0 [1] (🤰🏼)
+1F930 1F3FD ; RGI_Emoji_Modifier_Sequence ; pregnant woman: medium skin tone # E3.0 [1] (🤰🏽)
+1F930 1F3FE ; RGI_Emoji_Modifier_Sequence ; pregnant woman: medium-dark skin tone # E3.0 [1] (🤰🏾)
+1F930 1F3FF ; RGI_Emoji_Modifier_Sequence ; pregnant woman: dark skin tone # E3.0 [1] (🤰🏿)
+1F931 1F3FB ; RGI_Emoji_Modifier_Sequence ; breast-feeding: light skin tone # E5.0 [1] (🤱🏻)
+1F931 1F3FC ; RGI_Emoji_Modifier_Sequence ; breast-feeding: medium-light skin tone # E5.0 [1] (🤱🏼)
+1F931 1F3FD ; RGI_Emoji_Modifier_Sequence ; breast-feeding: medium skin tone # E5.0 [1] (🤱🏽)
+1F931 1F3FE ; RGI_Emoji_Modifier_Sequence ; breast-feeding: medium-dark skin tone # E5.0 [1] (🤱🏾)
+1F931 1F3FF ; RGI_Emoji_Modifier_Sequence ; breast-feeding: dark skin tone # E5.0 [1] (🤱🏿)
+1F932 1F3FB ; RGI_Emoji_Modifier_Sequence ; palms up together: light skin tone # E5.0 [1] (🤲🏻)
+1F932 1F3FC ; RGI_Emoji_Modifier_Sequence ; palms up together: medium-light skin tone # E5.0 [1] (🤲🏼)
+1F932 1F3FD ; RGI_Emoji_Modifier_Sequence ; palms up together: medium skin tone # E5.0 [1] (🤲🏽)
+1F932 1F3FE ; RGI_Emoji_Modifier_Sequence ; palms up together: medium-dark skin tone # E5.0 [1] (🤲🏾)
+1F932 1F3FF ; RGI_Emoji_Modifier_Sequence ; palms up together: dark skin tone # E5.0 [1] (🤲🏿)
+1F933 1F3FB ; RGI_Emoji_Modifier_Sequence ; selfie: light skin tone # E3.0 [1] (🤳🏻)
+1F933 1F3FC ; RGI_Emoji_Modifier_Sequence ; selfie: medium-light skin tone # E3.0 [1] (🤳🏼)
+1F933 1F3FD ; RGI_Emoji_Modifier_Sequence ; selfie: medium skin tone # E3.0 [1] (🤳🏽)
+1F933 1F3FE ; RGI_Emoji_Modifier_Sequence ; selfie: medium-dark skin tone # E3.0 [1] (🤳🏾)
+1F933 1F3FF ; RGI_Emoji_Modifier_Sequence ; selfie: dark skin tone # E3.0 [1] (🤳🏿)
+1F934 1F3FB ; RGI_Emoji_Modifier_Sequence ; prince: light skin tone # E3.0 [1] (🤴🏻)
+1F934 1F3FC ; RGI_Emoji_Modifier_Sequence ; prince: medium-light skin tone # E3.0 [1] (🤴🏼)
+1F934 1F3FD ; RGI_Emoji_Modifier_Sequence ; prince: medium skin tone # E3.0 [1] (🤴🏽)
+1F934 1F3FE ; RGI_Emoji_Modifier_Sequence ; prince: medium-dark skin tone # E3.0 [1] (🤴🏾)
+1F934 1F3FF ; RGI_Emoji_Modifier_Sequence ; prince: dark skin tone # E3.0 [1] (🤴🏿)
+1F935 1F3FB ; RGI_Emoji_Modifier_Sequence ; person in tuxedo: light skin tone # E3.0 [1] (🤵🏻)
+1F935 1F3FC ; RGI_Emoji_Modifier_Sequence ; person in tuxedo: medium-light skin tone # E3.0 [1] (🤵🏼)
+1F935 1F3FD ; RGI_Emoji_Modifier_Sequence ; person in tuxedo: medium skin tone # E3.0 [1] (🤵🏽)
+1F935 1F3FE ; RGI_Emoji_Modifier_Sequence ; person in tuxedo: medium-dark skin tone # E3.0 [1] (🤵🏾)
+1F935 1F3FF ; RGI_Emoji_Modifier_Sequence ; person in tuxedo: dark skin tone # E3.0 [1] (🤵🏿)
+1F936 1F3FB ; RGI_Emoji_Modifier_Sequence ; Mrs. Claus: light skin tone # E3.0 [1] (🤶🏻)
+1F936 1F3FC ; RGI_Emoji_Modifier_Sequence ; Mrs. Claus: medium-light skin tone # E3.0 [1] (🤶🏼)
+1F936 1F3FD ; RGI_Emoji_Modifier_Sequence ; Mrs. Claus: medium skin tone # E3.0 [1] (🤶🏽)
+1F936 1F3FE ; RGI_Emoji_Modifier_Sequence ; Mrs. Claus: medium-dark skin tone # E3.0 [1] (🤶🏾)
+1F936 1F3FF ; RGI_Emoji_Modifier_Sequence ; Mrs. Claus: dark skin tone # E3.0 [1] (🤶🏿)
+1F937 1F3FB ; RGI_Emoji_Modifier_Sequence ; person shrugging: light skin tone # E3.0 [1] (🤷🏻)
+1F937 1F3FC ; RGI_Emoji_Modifier_Sequence ; person shrugging: medium-light skin tone # E3.0 [1] (🤷🏼)
+1F937 1F3FD ; RGI_Emoji_Modifier_Sequence ; person shrugging: medium skin tone # E3.0 [1] (🤷🏽)
+1F937 1F3FE ; RGI_Emoji_Modifier_Sequence ; person shrugging: medium-dark skin tone # E3.0 [1] (🤷🏾)
+1F937 1F3FF ; RGI_Emoji_Modifier_Sequence ; person shrugging: dark skin tone # E3.0 [1] (🤷🏿)
+1F938 1F3FB ; RGI_Emoji_Modifier_Sequence ; person cartwheeling: light skin tone # E3.0 [1] (🤸🏻)
+1F938 1F3FC ; RGI_Emoji_Modifier_Sequence ; person cartwheeling: medium-light skin tone # E3.0 [1] (🤸🏼)
+1F938 1F3FD ; RGI_Emoji_Modifier_Sequence ; person cartwheeling: medium skin tone # E3.0 [1] (🤸🏽)
+1F938 1F3FE ; RGI_Emoji_Modifier_Sequence ; person cartwheeling: medium-dark skin tone # E3.0 [1] (🤸🏾)
+1F938 1F3FF ; RGI_Emoji_Modifier_Sequence ; person cartwheeling: dark skin tone # E3.0 [1] (🤸🏿)
+1F939 1F3FB ; RGI_Emoji_Modifier_Sequence ; person juggling: light skin tone # E3.0 [1] (🤹🏻)
+1F939 1F3FC ; RGI_Emoji_Modifier_Sequence ; person juggling: medium-light skin tone # E3.0 [1] (🤹🏼)
+1F939 1F3FD ; RGI_Emoji_Modifier_Sequence ; person juggling: medium skin tone # E3.0 [1] (🤹🏽)
+1F939 1F3FE ; RGI_Emoji_Modifier_Sequence ; person juggling: medium-dark skin tone # E3.0 [1] (🤹🏾)
+1F939 1F3FF ; RGI_Emoji_Modifier_Sequence ; person juggling: dark skin tone # E3.0 [1] (🤹🏿)
+1F93D 1F3FB ; RGI_Emoji_Modifier_Sequence ; person playing water polo: light skin tone # E3.0 [1] (🤽🏻)
+1F93D 1F3FC ; RGI_Emoji_Modifier_Sequence ; person playing water polo: medium-light skin tone # E3.0 [1] (🤽🏼)
+1F93D 1F3FD ; RGI_Emoji_Modifier_Sequence ; person playing water polo: medium skin tone # E3.0 [1] (🤽🏽)
+1F93D 1F3FE ; RGI_Emoji_Modifier_Sequence ; person playing water polo: medium-dark skin tone # E3.0 [1] (🤽🏾)
+1F93D 1F3FF ; RGI_Emoji_Modifier_Sequence ; person playing water polo: dark skin tone # E3.0 [1] (🤽🏿)
+1F93E 1F3FB ; RGI_Emoji_Modifier_Sequence ; person playing handball: light skin tone # E3.0 [1] (🤾🏻)
+1F93E 1F3FC ; RGI_Emoji_Modifier_Sequence ; person playing handball: medium-light skin tone # E3.0 [1] (🤾🏼)
+1F93E 1F3FD ; RGI_Emoji_Modifier_Sequence ; person playing handball: medium skin tone # E3.0 [1] (🤾🏽)
+1F93E 1F3FE ; RGI_Emoji_Modifier_Sequence ; person playing handball: medium-dark skin tone # E3.0 [1] (🤾🏾)
+1F93E 1F3FF ; RGI_Emoji_Modifier_Sequence ; person playing handball: dark skin tone # E3.0 [1] (🤾🏿)
+1F977 1F3FB ; RGI_Emoji_Modifier_Sequence ; ninja: light skin tone # E13.0 [1] (🥷🏻)
+1F977 1F3FC ; RGI_Emoji_Modifier_Sequence ; ninja: medium-light skin tone # E13.0 [1] (🥷🏼)
+1F977 1F3FD ; RGI_Emoji_Modifier_Sequence ; ninja: medium skin tone # E13.0 [1] (🥷🏽)
+1F977 1F3FE ; RGI_Emoji_Modifier_Sequence ; ninja: medium-dark skin tone # E13.0 [1] (🥷🏾)
+1F977 1F3FF ; RGI_Emoji_Modifier_Sequence ; ninja: dark skin tone # E13.0 [1] (🥷🏿)
+1F9B5 1F3FB ; RGI_Emoji_Modifier_Sequence ; leg: light skin tone # E11.0 [1] (🦵🏻)
+1F9B5 1F3FC ; RGI_Emoji_Modifier_Sequence ; leg: medium-light skin tone # E11.0 [1] (🦵🏼)
+1F9B5 1F3FD ; RGI_Emoji_Modifier_Sequence ; leg: medium skin tone # E11.0 [1] (🦵🏽)
+1F9B5 1F3FE ; RGI_Emoji_Modifier_Sequence ; leg: medium-dark skin tone # E11.0 [1] (🦵🏾)
+1F9B5 1F3FF ; RGI_Emoji_Modifier_Sequence ; leg: dark skin tone # E11.0 [1] (🦵🏿)
+1F9B6 1F3FB ; RGI_Emoji_Modifier_Sequence ; foot: light skin tone # E11.0 [1] (🦶🏻)
+1F9B6 1F3FC ; RGI_Emoji_Modifier_Sequence ; foot: medium-light skin tone # E11.0 [1] (🦶🏼)
+1F9B6 1F3FD ; RGI_Emoji_Modifier_Sequence ; foot: medium skin tone # E11.0 [1] (🦶🏽)
+1F9B6 1F3FE ; RGI_Emoji_Modifier_Sequence ; foot: medium-dark skin tone # E11.0 [1] (🦶🏾)
+1F9B6 1F3FF ; RGI_Emoji_Modifier_Sequence ; foot: dark skin tone # E11.0 [1] (🦶🏿)
+1F9B8 1F3FB ; RGI_Emoji_Modifier_Sequence ; superhero: light skin tone # E11.0 [1] (🦸🏻)
+1F9B8 1F3FC ; RGI_Emoji_Modifier_Sequence ; superhero: medium-light skin tone # E11.0 [1] (🦸🏼)
+1F9B8 1F3FD ; RGI_Emoji_Modifier_Sequence ; superhero: medium skin tone # E11.0 [1] (🦸🏽)
+1F9B8 1F3FE ; RGI_Emoji_Modifier_Sequence ; superhero: medium-dark skin tone # E11.0 [1] (🦸🏾)
+1F9B8 1F3FF ; RGI_Emoji_Modifier_Sequence ; superhero: dark skin tone # E11.0 [1] (🦸🏿)
+1F9B9 1F3FB ; RGI_Emoji_Modifier_Sequence ; supervillain: light skin tone # E11.0 [1] (🦹🏻)
+1F9B9 1F3FC ; RGI_Emoji_Modifier_Sequence ; supervillain: medium-light skin tone # E11.0 [1] (🦹🏼)
+1F9B9 1F3FD ; RGI_Emoji_Modifier_Sequence ; supervillain: medium skin tone # E11.0 [1] (🦹🏽)
+1F9B9 1F3FE ; RGI_Emoji_Modifier_Sequence ; supervillain: medium-dark skin tone # E11.0 [1] (🦹🏾)
+1F9B9 1F3FF ; RGI_Emoji_Modifier_Sequence ; supervillain: dark skin tone # E11.0 [1] (🦹🏿)
+1F9BB 1F3FB ; RGI_Emoji_Modifier_Sequence ; ear with hearing aid: light skin tone # E12.0 [1] (🦻🏻)
+1F9BB 1F3FC ; RGI_Emoji_Modifier_Sequence ; ear with hearing aid: medium-light skin tone # E12.0 [1] (🦻🏼)
+1F9BB 1F3FD ; RGI_Emoji_Modifier_Sequence ; ear with hearing aid: medium skin tone # E12.0 [1] (🦻🏽)
+1F9BB 1F3FE ; RGI_Emoji_Modifier_Sequence ; ear with hearing aid: medium-dark skin tone # E12.0 [1] (🦻🏾)
+1F9BB 1F3FF ; RGI_Emoji_Modifier_Sequence ; ear with hearing aid: dark skin tone # E12.0 [1] (🦻🏿)
+1F9CD 1F3FB ; RGI_Emoji_Modifier_Sequence ; person standing: light skin tone # E12.0 [1] (🧍🏻)
+1F9CD 1F3FC ; RGI_Emoji_Modifier_Sequence ; person standing: medium-light skin tone # E12.0 [1] (🧍🏼)
+1F9CD 1F3FD ; RGI_Emoji_Modifier_Sequence ; person standing: medium skin tone # E12.0 [1] (🧍🏽)
+1F9CD 1F3FE ; RGI_Emoji_Modifier_Sequence ; person standing: medium-dark skin tone # E12.0 [1] (🧍🏾)
+1F9CD 1F3FF ; RGI_Emoji_Modifier_Sequence ; person standing: dark skin tone # E12.0 [1] (🧍🏿)
+1F9CE 1F3FB ; RGI_Emoji_Modifier_Sequence ; person kneeling: light skin tone # E12.0 [1] (🧎🏻)
+1F9CE 1F3FC ; RGI_Emoji_Modifier_Sequence ; person kneeling: medium-light skin tone # E12.0 [1] (🧎🏼)
+1F9CE 1F3FD ; RGI_Emoji_Modifier_Sequence ; person kneeling: medium skin tone # E12.0 [1] (🧎🏽)
+1F9CE 1F3FE ; RGI_Emoji_Modifier_Sequence ; person kneeling: medium-dark skin tone # E12.0 [1] (🧎🏾)
+1F9CE 1F3FF ; RGI_Emoji_Modifier_Sequence ; person kneeling: dark skin tone # E12.0 [1] (🧎🏿)
+1F9CF 1F3FB ; RGI_Emoji_Modifier_Sequence ; deaf person: light skin tone # E12.0 [1] (🧏🏻)
+1F9CF 1F3FC ; RGI_Emoji_Modifier_Sequence ; deaf person: medium-light skin tone # E12.0 [1] (🧏🏼)
+1F9CF 1F3FD ; RGI_Emoji_Modifier_Sequence ; deaf person: medium skin tone # E12.0 [1] (🧏🏽)
+1F9CF 1F3FE ; RGI_Emoji_Modifier_Sequence ; deaf person: medium-dark skin tone # E12.0 [1] (🧏🏾)
+1F9CF 1F3FF ; RGI_Emoji_Modifier_Sequence ; deaf person: dark skin tone # E12.0 [1] (🧏🏿)
+1F9D1 1F3FB ; RGI_Emoji_Modifier_Sequence ; person: light skin tone # E5.0 [1] (🧑🏻)
+1F9D1 1F3FC ; RGI_Emoji_Modifier_Sequence ; person: medium-light skin tone # E5.0 [1] (🧑🏼)
+1F9D1 1F3FD ; RGI_Emoji_Modifier_Sequence ; person: medium skin tone # E5.0 [1] (🧑🏽)
+1F9D1 1F3FE ; RGI_Emoji_Modifier_Sequence ; person: medium-dark skin tone # E5.0 [1] (🧑🏾)
+1F9D1 1F3FF ; RGI_Emoji_Modifier_Sequence ; person: dark skin tone # E5.0 [1] (🧑🏿)
+1F9D2 1F3FB ; RGI_Emoji_Modifier_Sequence ; child: light skin tone # E5.0 [1] (🧒🏻)
+1F9D2 1F3FC ; RGI_Emoji_Modifier_Sequence ; child: medium-light skin tone # E5.0 [1] (🧒🏼)
+1F9D2 1F3FD ; RGI_Emoji_Modifier_Sequence ; child: medium skin tone # E5.0 [1] (🧒🏽)
+1F9D2 1F3FE ; RGI_Emoji_Modifier_Sequence ; child: medium-dark skin tone # E5.0 [1] (🧒🏾)
+1F9D2 1F3FF ; RGI_Emoji_Modifier_Sequence ; child: dark skin tone # E5.0 [1] (🧒🏿)
+1F9D3 1F3FB ; RGI_Emoji_Modifier_Sequence ; older person: light skin tone # E5.0 [1] (🧓🏻)
+1F9D3 1F3FC ; RGI_Emoji_Modifier_Sequence ; older person: medium-light skin tone # E5.0 [1] (🧓🏼)
+1F9D3 1F3FD ; RGI_Emoji_Modifier_Sequence ; older person: medium skin tone # E5.0 [1] (🧓🏽)
+1F9D3 1F3FE ; RGI_Emoji_Modifier_Sequence ; older person: medium-dark skin tone # E5.0 [1] (🧓🏾)
+1F9D3 1F3FF ; RGI_Emoji_Modifier_Sequence ; older person: dark skin tone # E5.0 [1] (🧓🏿)
+1F9D4 1F3FB ; RGI_Emoji_Modifier_Sequence ; person: light skin tone, beard # E5.0 [1] (🧔🏻)
+1F9D4 1F3FC ; RGI_Emoji_Modifier_Sequence ; person: medium-light skin tone, beard # E5.0 [1] (🧔🏼)
+1F9D4 1F3FD ; RGI_Emoji_Modifier_Sequence ; person: medium skin tone, beard # E5.0 [1] (🧔🏽)
+1F9D4 1F3FE ; RGI_Emoji_Modifier_Sequence ; person: medium-dark skin tone, beard # E5.0 [1] (🧔🏾)
+1F9D4 1F3FF ; RGI_Emoji_Modifier_Sequence ; person: dark skin tone, beard # E5.0 [1] (🧔🏿)
+1F9D5 1F3FB ; RGI_Emoji_Modifier_Sequence ; woman with headscarf: light skin tone # E5.0 [1] (🧕🏻)
+1F9D5 1F3FC ; RGI_Emoji_Modifier_Sequence ; woman with headscarf: medium-light skin tone # E5.0 [1] (🧕🏼)
+1F9D5 1F3FD ; RGI_Emoji_Modifier_Sequence ; woman with headscarf: medium skin tone # E5.0 [1] (🧕🏽)
+1F9D5 1F3FE ; RGI_Emoji_Modifier_Sequence ; woman with headscarf: medium-dark skin tone # E5.0 [1] (🧕🏾)
+1F9D5 1F3FF ; RGI_Emoji_Modifier_Sequence ; woman with headscarf: dark skin tone # E5.0 [1] (🧕🏿)
+1F9D6 1F3FB ; RGI_Emoji_Modifier_Sequence ; person in steamy room: light skin tone # E5.0 [1] (🧖🏻)
+1F9D6 1F3FC ; RGI_Emoji_Modifier_Sequence ; person in steamy room: medium-light skin tone # E5.0 [1] (🧖🏼)
+1F9D6 1F3FD ; RGI_Emoji_Modifier_Sequence ; person in steamy room: medium skin tone # E5.0 [1] (🧖🏽)
+1F9D6 1F3FE ; RGI_Emoji_Modifier_Sequence ; person in steamy room: medium-dark skin tone # E5.0 [1] (🧖🏾)
+1F9D6 1F3FF ; RGI_Emoji_Modifier_Sequence ; person in steamy room: dark skin tone # E5.0 [1] (🧖🏿)
+1F9D7 1F3FB ; RGI_Emoji_Modifier_Sequence ; person climbing: light skin tone # E5.0 [1] (🧗🏻)
+1F9D7 1F3FC ; RGI_Emoji_Modifier_Sequence ; person climbing: medium-light skin tone # E5.0 [1] (🧗🏼)
+1F9D7 1F3FD ; RGI_Emoji_Modifier_Sequence ; person climbing: medium skin tone # E5.0 [1] (🧗🏽)
+1F9D7 1F3FE ; RGI_Emoji_Modifier_Sequence ; person climbing: medium-dark skin tone # E5.0 [1] (🧗🏾)
+1F9D7 1F3FF ; RGI_Emoji_Modifier_Sequence ; person climbing: dark skin tone # E5.0 [1] (🧗🏿)
+1F9D8 1F3FB ; RGI_Emoji_Modifier_Sequence ; person in lotus position: light skin tone # E5.0 [1] (🧘🏻)
+1F9D8 1F3FC ; RGI_Emoji_Modifier_Sequence ; person in lotus position: medium-light skin tone # E5.0 [1] (🧘🏼)
+1F9D8 1F3FD ; RGI_Emoji_Modifier_Sequence ; person in lotus position: medium skin tone # E5.0 [1] (🧘🏽)
+1F9D8 1F3FE ; RGI_Emoji_Modifier_Sequence ; person in lotus position: medium-dark skin tone # E5.0 [1] (🧘🏾)
+1F9D8 1F3FF ; RGI_Emoji_Modifier_Sequence ; person in lotus position: dark skin tone # E5.0 [1] (🧘🏿)
+1F9D9 1F3FB ; RGI_Emoji_Modifier_Sequence ; mage: light skin tone # E5.0 [1] (🧙🏻)
+1F9D9 1F3FC ; RGI_Emoji_Modifier_Sequence ; mage: medium-light skin tone # E5.0 [1] (🧙🏼)
+1F9D9 1F3FD ; RGI_Emoji_Modifier_Sequence ; mage: medium skin tone # E5.0 [1] (🧙🏽)
+1F9D9 1F3FE ; RGI_Emoji_Modifier_Sequence ; mage: medium-dark skin tone # E5.0 [1] (🧙🏾)
+1F9D9 1F3FF ; RGI_Emoji_Modifier_Sequence ; mage: dark skin tone # E5.0 [1] (🧙🏿)
+1F9DA 1F3FB ; RGI_Emoji_Modifier_Sequence ; fairy: light skin tone # E5.0 [1] (🧚🏻)
+1F9DA 1F3FC ; RGI_Emoji_Modifier_Sequence ; fairy: medium-light skin tone # E5.0 [1] (🧚🏼)
+1F9DA 1F3FD ; RGI_Emoji_Modifier_Sequence ; fairy: medium skin tone # E5.0 [1] (🧚🏽)
+1F9DA 1F3FE ; RGI_Emoji_Modifier_Sequence ; fairy: medium-dark skin tone # E5.0 [1] (🧚🏾)
+1F9DA 1F3FF ; RGI_Emoji_Modifier_Sequence ; fairy: dark skin tone # E5.0 [1] (🧚🏿)
+1F9DB 1F3FB ; RGI_Emoji_Modifier_Sequence ; vampire: light skin tone # E5.0 [1] (🧛🏻)
+1F9DB 1F3FC ; RGI_Emoji_Modifier_Sequence ; vampire: medium-light skin tone # E5.0 [1] (🧛🏼)
+1F9DB 1F3FD ; RGI_Emoji_Modifier_Sequence ; vampire: medium skin tone # E5.0 [1] (🧛🏽)
+1F9DB 1F3FE ; RGI_Emoji_Modifier_Sequence ; vampire: medium-dark skin tone # E5.0 [1] (🧛🏾)
+1F9DB 1F3FF ; RGI_Emoji_Modifier_Sequence ; vampire: dark skin tone # E5.0 [1] (🧛🏿)
+1F9DC 1F3FB ; RGI_Emoji_Modifier_Sequence ; merperson: light skin tone # E5.0 [1] (🧜🏻)
+1F9DC 1F3FC ; RGI_Emoji_Modifier_Sequence ; merperson: medium-light skin tone # E5.0 [1] (🧜🏼)
+1F9DC 1F3FD ; RGI_Emoji_Modifier_Sequence ; merperson: medium skin tone # E5.0 [1] (🧜🏽)
+1F9DC 1F3FE ; RGI_Emoji_Modifier_Sequence ; merperson: medium-dark skin tone # E5.0 [1] (🧜🏾)
+1F9DC 1F3FF ; RGI_Emoji_Modifier_Sequence ; merperson: dark skin tone # E5.0 [1] (🧜🏿)
+1F9DD 1F3FB ; RGI_Emoji_Modifier_Sequence ; elf: light skin tone # E5.0 [1] (🧝🏻)
+1F9DD 1F3FC ; RGI_Emoji_Modifier_Sequence ; elf: medium-light skin tone # E5.0 [1] (🧝🏼)
+1F9DD 1F3FD ; RGI_Emoji_Modifier_Sequence ; elf: medium skin tone # E5.0 [1] (🧝🏽)
+1F9DD 1F3FE ; RGI_Emoji_Modifier_Sequence ; elf: medium-dark skin tone # E5.0 [1] (🧝🏾)
+1F9DD 1F3FF ; RGI_Emoji_Modifier_Sequence ; elf: dark skin tone # E5.0 [1] (🧝🏿)
+1FAC3 1F3FB ; RGI_Emoji_Modifier_Sequence ; pregnant man: light skin tone # E14.0 [1] (🫃🏻)
+1FAC3 1F3FC ; RGI_Emoji_Modifier_Sequence ; pregnant man: medium-light skin tone # E14.0 [1] (🫃🏼)
+1FAC3 1F3FD ; RGI_Emoji_Modifier_Sequence ; pregnant man: medium skin tone # E14.0 [1] (🫃🏽)
+1FAC3 1F3FE ; RGI_Emoji_Modifier_Sequence ; pregnant man: medium-dark skin tone # E14.0 [1] (🫃🏾)
+1FAC3 1F3FF ; RGI_Emoji_Modifier_Sequence ; pregnant man: dark skin tone # E14.0 [1] (🫃🏿)
+1FAC4 1F3FB ; RGI_Emoji_Modifier_Sequence ; pregnant person: light skin tone # E14.0 [1] (🫄🏻)
+1FAC4 1F3FC ; RGI_Emoji_Modifier_Sequence ; pregnant person: medium-light skin tone # E14.0 [1] (🫄🏼)
+1FAC4 1F3FD ; RGI_Emoji_Modifier_Sequence ; pregnant person: medium skin tone # E14.0 [1] (🫄🏽)
+1FAC4 1F3FE ; RGI_Emoji_Modifier_Sequence ; pregnant person: medium-dark skin tone # E14.0 [1] (🫄🏾)
+1FAC4 1F3FF ; RGI_Emoji_Modifier_Sequence ; pregnant person: dark skin tone # E14.0 [1] (🫄🏿)
+1FAC5 1F3FB ; RGI_Emoji_Modifier_Sequence ; person with crown: light skin tone # E14.0 [1] (🫅🏻)
+1FAC5 1F3FC ; RGI_Emoji_Modifier_Sequence ; person with crown: medium-light skin tone # E14.0 [1] (🫅🏼)
+1FAC5 1F3FD ; RGI_Emoji_Modifier_Sequence ; person with crown: medium skin tone # E14.0 [1] (🫅🏽)
+1FAC5 1F3FE ; RGI_Emoji_Modifier_Sequence ; person with crown: medium-dark skin tone # E14.0 [1] (🫅🏾)
+1FAC5 1F3FF ; RGI_Emoji_Modifier_Sequence ; person with crown: dark skin tone # E14.0 [1] (🫅🏿)
+1FAF0 1F3FB ; RGI_Emoji_Modifier_Sequence ; hand with index finger and thumb crossed: light skin tone # E14.0 [1] (🫰🏻)
+1FAF0 1F3FC ; RGI_Emoji_Modifier_Sequence ; hand with index finger and thumb crossed: medium-light skin tone #E14.0 [1] (🫰🏼)
+1FAF0 1F3FD ; RGI_Emoji_Modifier_Sequence ; hand with index finger and thumb crossed: medium skin tone # E14.0 [1] (🫰🏽)
+1FAF0 1F3FE ; RGI_Emoji_Modifier_Sequence ; hand with index finger and thumb crossed: medium-dark skin tone #E14.0 [1] (🫰🏾)
+1FAF0 1F3FF ; RGI_Emoji_Modifier_Sequence ; hand with index finger and thumb crossed: dark skin tone # E14.0 [1] (🫰🏿)
+1FAF1 1F3FB ; RGI_Emoji_Modifier_Sequence ; rightwards hand: light skin tone # E14.0 [1] (🫱🏻)
+1FAF1 1F3FC ; RGI_Emoji_Modifier_Sequence ; rightwards hand: medium-light skin tone # E14.0 [1] (🫱🏼)
+1FAF1 1F3FD ; RGI_Emoji_Modifier_Sequence ; rightwards hand: medium skin tone # E14.0 [1] (🫱🏽)
+1FAF1 1F3FE ; RGI_Emoji_Modifier_Sequence ; rightwards hand: medium-dark skin tone # E14.0 [1] (🫱🏾)
+1FAF1 1F3FF ; RGI_Emoji_Modifier_Sequence ; rightwards hand: dark skin tone # E14.0 [1] (🫱🏿)
+1FAF2 1F3FB ; RGI_Emoji_Modifier_Sequence ; leftwards hand: light skin tone # E14.0 [1] (🫲🏻)
+1FAF2 1F3FC ; RGI_Emoji_Modifier_Sequence ; leftwards hand: medium-light skin tone # E14.0 [1] (🫲🏼)
+1FAF2 1F3FD ; RGI_Emoji_Modifier_Sequence ; leftwards hand: medium skin tone # E14.0 [1] (🫲🏽)
+1FAF2 1F3FE ; RGI_Emoji_Modifier_Sequence ; leftwards hand: medium-dark skin tone # E14.0 [1] (🫲🏾)
+1FAF2 1F3FF ; RGI_Emoji_Modifier_Sequence ; leftwards hand: dark skin tone # E14.0 [1] (🫲🏿)
+1FAF3 1F3FB ; RGI_Emoji_Modifier_Sequence ; palm down hand: light skin tone # E14.0 [1] (🫳🏻)
+1FAF3 1F3FC ; RGI_Emoji_Modifier_Sequence ; palm down hand: medium-light skin tone # E14.0 [1] (🫳🏼)
+1FAF3 1F3FD ; RGI_Emoji_Modifier_Sequence ; palm down hand: medium skin tone # E14.0 [1] (🫳🏽)
+1FAF3 1F3FE ; RGI_Emoji_Modifier_Sequence ; palm down hand: medium-dark skin tone # E14.0 [1] (🫳🏾)
+1FAF3 1F3FF ; RGI_Emoji_Modifier_Sequence ; palm down hand: dark skin tone # E14.0 [1] (🫳🏿)
+1FAF4 1F3FB ; RGI_Emoji_Modifier_Sequence ; palm up hand: light skin tone # E14.0 [1] (🫴🏻)
+1FAF4 1F3FC ; RGI_Emoji_Modifier_Sequence ; palm up hand: medium-light skin tone # E14.0 [1] (🫴🏼)
+1FAF4 1F3FD ; RGI_Emoji_Modifier_Sequence ; palm up hand: medium skin tone # E14.0 [1] (🫴🏽)
+1FAF4 1F3FE ; RGI_Emoji_Modifier_Sequence ; palm up hand: medium-dark skin tone # E14.0 [1] (🫴🏾)
+1FAF4 1F3FF ; RGI_Emoji_Modifier_Sequence ; palm up hand: dark skin tone # E14.0 [1] (🫴🏿)
+1FAF5 1F3FB ; RGI_Emoji_Modifier_Sequence ; index pointing at the viewer: light skin tone # E14.0 [1] (🫵🏻)
+1FAF5 1F3FC ; RGI_Emoji_Modifier_Sequence ; index pointing at the viewer: medium-light skin tone # E14.0 [1] (🫵🏼)
+1FAF5 1F3FD ; RGI_Emoji_Modifier_Sequence ; index pointing at the viewer: medium skin tone # E14.0 [1] (🫵🏽)
+1FAF5 1F3FE ; RGI_Emoji_Modifier_Sequence ; index pointing at the viewer: medium-dark skin tone # E14.0 [1] (🫵🏾)
+1FAF5 1F3FF ; RGI_Emoji_Modifier_Sequence ; index pointing at the viewer: dark skin tone # E14.0 [1] (🫵🏿)
+1FAF6 1F3FB ; RGI_Emoji_Modifier_Sequence ; heart hands: light skin tone # E14.0 [1] (🫶🏻)
+1FAF6 1F3FC ; RGI_Emoji_Modifier_Sequence ; heart hands: medium-light skin tone # E14.0 [1] (🫶🏼)
+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] (🫶🏿)
+
+# Total elements: 645
+
+#EOF
diff --git a/admin/unidata/emoji-test.txt b/admin/unidata/emoji-test.txt
new file mode 100644
index 00000000000..42e6210cd28
--- /dev/null
+++ b/admin/unidata/emoji-test.txt
@@ -0,0 +1,4991 @@
+# emoji-test.txt
+# Date: 2021-08-26, 17:22:23 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
+#
+# Emoji Keyboard/Display Test Data for UTS #51
+# Version: 14.0
+#
+# For documentation and usage, see http://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
+# Code points — list of one or more hex code points, separated by spaces
+# Status
+# component — an Emoji_Component,
+# excluding Regional_Indicators, ASCII, and non-Emoji.
+# fully-qualified — a fully-qualified emoji (see ED-18 in UTS #51),
+# excluding Emoji_Component
+# minimally-qualified — a minimally-qualified emoji (see ED-18a in UTS #51)
+# unqualified — a unqualified emoji (See ED-19 in UTS #51)
+# Notes:
+# • This includes the emoji components that need emoji presentation (skin tone and hair)
+# when isolated, but omits the components that need not have an emoji
+# presentation when isolated.
+# • The RGI set is covered by the listed fully-qualified emoji.
+# • The listed minimally-qualified and unqualified cover all cases where an
+# element of the RGI set is missing one or more emoji presentation selectors.
+# • The file is in CLDR order, not codepoint order. This is recommended (but not required!) for keyboard palettes.
+# • The groups and subgroups are illustrative. See the Emoji Order chart for more information.
+
+
+# group: Smileys & Emotion
+
+# subgroup: face-smiling
+1F600 ; fully-qualified # 😀 E1.0 grinning face
+1F603 ; fully-qualified # 😃 E0.6 grinning face with big eyes
+1F604 ; fully-qualified # 😄 E0.6 grinning face with smiling eyes
+1F601 ; fully-qualified # 😁 E0.6 beaming face with smiling eyes
+1F606 ; fully-qualified # 😆 E0.6 grinning squinting face
+1F605 ; fully-qualified # 😅 E0.6 grinning face with sweat
+1F923 ; fully-qualified # 🤣 E3.0 rolling on the floor laughing
+1F602 ; fully-qualified # 😂 E0.6 face with tears of joy
+1F642 ; fully-qualified # 🙂 E1.0 slightly smiling face
+1F643 ; fully-qualified # 🙃 E1.0 upside-down face
+1FAE0 ; fully-qualified # 🫠 E14.0 melting face
+1F609 ; fully-qualified # 😉 E0.6 winking face
+1F60A ; fully-qualified # 😊 E0.6 smiling face with smiling eyes
+1F607 ; fully-qualified # 😇 E1.0 smiling face with halo
+
+# subgroup: face-affection
+1F970 ; fully-qualified # 🥰 E11.0 smiling face with hearts
+1F60D ; fully-qualified # 😍 E0.6 smiling face with heart-eyes
+1F929 ; fully-qualified # 🤩 E5.0 star-struck
+1F618 ; fully-qualified # 😘 E0.6 face blowing a kiss
+1F617 ; fully-qualified # 😗 E1.0 kissing face
+263A FE0F ; fully-qualified # ☺️ E0.6 smiling face
+263A ; unqualified # ☺ E0.6 smiling face
+1F61A ; fully-qualified # 😚 E0.6 kissing face with closed eyes
+1F619 ; fully-qualified # 😙 E1.0 kissing face with smiling eyes
+1F972 ; fully-qualified # 🥲 E13.0 smiling face with tear
+
+# subgroup: face-tongue
+1F60B ; fully-qualified # 😋 E0.6 face savoring food
+1F61B ; fully-qualified # 😛 E1.0 face with tongue
+1F61C ; fully-qualified # 😜 E0.6 winking face with tongue
+1F92A ; fully-qualified # 🤪 E5.0 zany face
+1F61D ; fully-qualified # 😝 E0.6 squinting face with tongue
+1F911 ; fully-qualified # 🤑 E1.0 money-mouth face
+
+# subgroup: face-hand
+1F917 ; fully-qualified # 🤗 E1.0 smiling face with open hands
+1F92D ; fully-qualified # 🤭 E5.0 face with hand over mouth
+1FAE2 ; fully-qualified # 🫢 E14.0 face with open eyes and hand over mouth
+1FAE3 ; fully-qualified # 🫣 E14.0 face with peeking eye
+1F92B ; fully-qualified # 🤫 E5.0 shushing face
+1F914 ; fully-qualified # 🤔 E1.0 thinking face
+1FAE1 ; fully-qualified # 🫡 E14.0 saluting face
+
+# subgroup: face-neutral-skeptical
+1F910 ; fully-qualified # 🤐 E1.0 zipper-mouth face
+1F928 ; fully-qualified # 🤨 E5.0 face with raised eyebrow
+1F610 ; fully-qualified # 😐 E0.7 neutral face
+1F611 ; fully-qualified # 😑 E1.0 expressionless face
+1F636 ; fully-qualified # 😶 E1.0 face without mouth
+1FAE5 ; fully-qualified # 🫥 E14.0 dotted line face
+1F636 200D 1F32B FE0F ; fully-qualified # 😶‍🌫️ E13.1 face in clouds
+1F636 200D 1F32B ; minimally-qualified # 😶‍🌫 E13.1 face in clouds
+1F60F ; fully-qualified # 😏 E0.6 smirking face
+1F612 ; fully-qualified # 😒 E0.6 unamused face
+1F644 ; fully-qualified # 🙄 E1.0 face with rolling eyes
+1F62C ; fully-qualified # 😬 E1.0 grimacing face
+1F62E 200D 1F4A8 ; fully-qualified # 😮‍💨 E13.1 face exhaling
+1F925 ; fully-qualified # 🤥 E3.0 lying face
+
+# subgroup: face-sleepy
+1F60C ; fully-qualified # 😌 E0.6 relieved face
+1F614 ; fully-qualified # 😔 E0.6 pensive face
+1F62A ; fully-qualified # 😪 E0.6 sleepy face
+1F924 ; fully-qualified # 🤤 E3.0 drooling face
+1F634 ; fully-qualified # 😴 E1.0 sleeping face
+
+# subgroup: face-unwell
+1F637 ; fully-qualified # 😷 E0.6 face with medical mask
+1F912 ; fully-qualified # 🤒 E1.0 face with thermometer
+1F915 ; fully-qualified # 🤕 E1.0 face with head-bandage
+1F922 ; fully-qualified # 🤢 E3.0 nauseated face
+1F92E ; fully-qualified # 🤮 E5.0 face vomiting
+1F927 ; fully-qualified # 🤧 E3.0 sneezing face
+1F975 ; fully-qualified # 🥵 E11.0 hot face
+1F976 ; fully-qualified # 🥶 E11.0 cold face
+1F974 ; fully-qualified # 🥴 E11.0 woozy face
+1F635 ; fully-qualified # 😵 E0.6 face with crossed-out eyes
+1F635 200D 1F4AB ; fully-qualified # 😵‍💫 E13.1 face with spiral eyes
+1F92F ; fully-qualified # 🤯 E5.0 exploding head
+
+# subgroup: face-hat
+1F920 ; fully-qualified # 🤠 E3.0 cowboy hat face
+1F973 ; fully-qualified # 🥳 E11.0 partying face
+1F978 ; fully-qualified # 🥸 E13.0 disguised face
+
+# subgroup: face-glasses
+1F60E ; fully-qualified # 😎 E1.0 smiling face with sunglasses
+1F913 ; fully-qualified # 🤓 E1.0 nerd face
+1F9D0 ; fully-qualified # 🧐 E5.0 face with monocle
+
+# subgroup: face-concerned
+1F615 ; fully-qualified # 😕 E1.0 confused face
+1FAE4 ; fully-qualified # 🫤 E14.0 face with diagonal mouth
+1F61F ; fully-qualified # 😟 E1.0 worried face
+1F641 ; fully-qualified # 🙁 E1.0 slightly frowning face
+2639 FE0F ; fully-qualified # ☹️ E0.7 frowning face
+2639 ; unqualified # ☹ E0.7 frowning face
+1F62E ; fully-qualified # 😮 E1.0 face with open mouth
+1F62F ; fully-qualified # 😯 E1.0 hushed face
+1F632 ; fully-qualified # 😲 E0.6 astonished face
+1F633 ; fully-qualified # 😳 E0.6 flushed face
+1F97A ; fully-qualified # 🥺 E11.0 pleading face
+1F979 ; fully-qualified # 🥹 E14.0 face holding back tears
+1F626 ; fully-qualified # 😦 E1.0 frowning face with open mouth
+1F627 ; fully-qualified # 😧 E1.0 anguished face
+1F628 ; fully-qualified # 😨 E0.6 fearful face
+1F630 ; fully-qualified # 😰 E0.6 anxious face with sweat
+1F625 ; fully-qualified # 😥 E0.6 sad but relieved face
+1F622 ; fully-qualified # 😢 E0.6 crying face
+1F62D ; fully-qualified # 😭 E0.6 loudly crying face
+1F631 ; fully-qualified # 😱 E0.6 face screaming in fear
+1F616 ; fully-qualified # 😖 E0.6 confounded face
+1F623 ; fully-qualified # 😣 E0.6 persevering face
+1F61E ; fully-qualified # 😞 E0.6 disappointed face
+1F613 ; fully-qualified # 😓 E0.6 downcast face with sweat
+1F629 ; fully-qualified # 😩 E0.6 weary face
+1F62B ; fully-qualified # 😫 E0.6 tired face
+1F971 ; fully-qualified # 🥱 E12.0 yawning face
+
+# subgroup: face-negative
+1F624 ; fully-qualified # 😤 E0.6 face with steam from nose
+1F621 ; fully-qualified # 😡 E0.6 pouting 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
+1F47F ; fully-qualified # 👿 E0.6 angry face with horns
+1F480 ; fully-qualified # 💀 E0.6 skull
+2620 FE0F ; fully-qualified # ☠️ E1.0 skull and crossbones
+2620 ; unqualified # ☠ E1.0 skull and crossbones
+
+# subgroup: face-costume
+1F4A9 ; fully-qualified # 💩 E0.6 pile of poo
+1F921 ; fully-qualified # 🤡 E3.0 clown face
+1F479 ; fully-qualified # 👹 E0.6 ogre
+1F47A ; fully-qualified # 👺 E0.6 goblin
+1F47B ; fully-qualified # 👻 E0.6 ghost
+1F47D ; fully-qualified # 👽 E0.6 alien
+1F47E ; fully-qualified # 👾 E0.6 alien monster
+1F916 ; fully-qualified # 🤖 E1.0 robot
+
+# subgroup: cat-face
+1F63A ; fully-qualified # 😺 E0.6 grinning cat
+1F638 ; fully-qualified # 😸 E0.6 grinning cat with smiling eyes
+1F639 ; fully-qualified # 😹 E0.6 cat with tears of joy
+1F63B ; fully-qualified # 😻 E0.6 smiling cat with heart-eyes
+1F63C ; fully-qualified # 😼 E0.6 cat with wry smile
+1F63D ; fully-qualified # 😽 E0.6 kissing cat
+1F640 ; fully-qualified # 🙀 E0.6 weary cat
+1F63F ; fully-qualified # 😿 E0.6 crying cat
+1F63E ; fully-qualified # 😾 E0.6 pouting cat
+
+# subgroup: monkey-face
+1F648 ; fully-qualified # 🙈 E0.6 see-no-evil monkey
+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
+1F48C ; fully-qualified # 💌 E0.6 love letter
+1F498 ; fully-qualified # 💘 E0.6 heart with arrow
+1F49D ; fully-qualified # 💝 E0.6 heart with ribbon
+1F496 ; fully-qualified # 💖 E0.6 sparkling heart
+1F497 ; fully-qualified # 💗 E0.6 growing heart
+1F493 ; fully-qualified # 💓 E0.6 beating heart
+1F49E ; fully-qualified # 💞 E0.6 revolving hearts
+1F495 ; fully-qualified # 💕 E0.6 two hearts
+1F49F ; fully-qualified # 💟 E0.6 heart decoration
+2763 FE0F ; fully-qualified # ❣️ E1.0 heart exclamation
+2763 ; unqualified # ❣ E1.0 heart exclamation
+1F494 ; fully-qualified # 💔 E0.6 broken heart
+2764 FE0F 200D 1F525 ; fully-qualified # ❤️‍🔥 E13.1 heart on fire
+2764 200D 1F525 ; unqualified # ❤‍🔥 E13.1 heart on fire
+2764 FE0F 200D 1FA79 ; fully-qualified # ❤️‍🩹 E13.1 mending heart
+2764 200D 1FA79 ; unqualified # ❤‍🩹 E13.1 mending heart
+2764 FE0F ; fully-qualified # ❤️ E0.6 red heart
+2764 ; unqualified # ❤ E0.6 red 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
+1F49C ; fully-qualified # 💜 E0.6 purple heart
+1F90E ; fully-qualified # 🤎 E12.0 brown heart
+1F5A4 ; fully-qualified # 🖤 E3.0 black heart
+1F90D ; fully-qualified # 🤍 E12.0 white heart
+1F4AF ; fully-qualified # 💯 E0.6 hundred points
+1F4A2 ; fully-qualified # 💢 E0.6 anger symbol
+1F4A5 ; fully-qualified # 💥 E0.6 collision
+1F4AB ; fully-qualified # 💫 E0.6 dizzy
+1F4A6 ; fully-qualified # 💦 E0.6 sweat droplets
+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 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
+
+# Smileys & Emotion subtotal: 177
+# Smileys & Emotion subtotal: 177 w/o modifiers
+
+# group: People & Body
+
+# subgroup: hand-fingers-open
+1F44B ; fully-qualified # 👋 E0.6 waving hand
+1F44B 1F3FB ; fully-qualified # 👋🏻 E1.0 waving hand: light skin tone
+1F44B 1F3FC ; fully-qualified # 👋🏼 E1.0 waving hand: medium-light skin tone
+1F44B 1F3FD ; fully-qualified # 👋🏽 E1.0 waving hand: medium skin tone
+1F44B 1F3FE ; fully-qualified # 👋🏾 E1.0 waving hand: medium-dark skin tone
+1F44B 1F3FF ; fully-qualified # 👋🏿 E1.0 waving hand: dark skin tone
+1F91A ; fully-qualified # 🤚 E3.0 raised back of hand
+1F91A 1F3FB ; fully-qualified # 🤚🏻 E3.0 raised back of hand: light skin tone
+1F91A 1F3FC ; fully-qualified # 🤚🏼 E3.0 raised back of hand: medium-light skin tone
+1F91A 1F3FD ; fully-qualified # 🤚🏽 E3.0 raised back of hand: medium skin tone
+1F91A 1F3FE ; fully-qualified # 🤚🏾 E3.0 raised back of hand: medium-dark skin tone
+1F91A 1F3FF ; fully-qualified # 🤚🏿 E3.0 raised back of hand: dark skin tone
+1F590 FE0F ; fully-qualified # 🖐️ E0.7 hand with fingers splayed
+1F590 ; unqualified # 🖐 E0.7 hand with fingers splayed
+1F590 1F3FB ; fully-qualified # 🖐🏻 E1.0 hand with fingers splayed: light skin tone
+1F590 1F3FC ; fully-qualified # 🖐🏼 E1.0 hand with fingers splayed: medium-light skin tone
+1F590 1F3FD ; fully-qualified # 🖐🏽 E1.0 hand with fingers splayed: medium skin tone
+1F590 1F3FE ; fully-qualified # 🖐🏾 E1.0 hand with fingers splayed: medium-dark skin tone
+1F590 1F3FF ; fully-qualified # 🖐🏿 E1.0 hand with fingers splayed: dark skin tone
+270B ; fully-qualified # ✋ E0.6 raised hand
+270B 1F3FB ; fully-qualified # ✋🏻 E1.0 raised hand: light skin tone
+270B 1F3FC ; fully-qualified # ✋🏼 E1.0 raised hand: medium-light skin tone
+270B 1F3FD ; fully-qualified # ✋🏽 E1.0 raised hand: medium skin tone
+270B 1F3FE ; fully-qualified # ✋🏾 E1.0 raised hand: medium-dark skin tone
+270B 1F3FF ; fully-qualified # ✋🏿 E1.0 raised hand: dark skin tone
+1F596 ; fully-qualified # 🖖 E1.0 vulcan salute
+1F596 1F3FB ; fully-qualified # 🖖🏻 E1.0 vulcan salute: light skin tone
+1F596 1F3FC ; fully-qualified # 🖖🏼 E1.0 vulcan salute: medium-light skin tone
+1F596 1F3FD ; fully-qualified # 🖖🏽 E1.0 vulcan salute: medium skin tone
+1F596 1F3FE ; fully-qualified # 🖖🏾 E1.0 vulcan salute: medium-dark skin tone
+1F596 1F3FF ; fully-qualified # 🖖🏿 E1.0 vulcan salute: dark skin tone
+1FAF1 ; fully-qualified # 🫱 E14.0 rightwards hand
+1FAF1 1F3FB ; fully-qualified # 🫱🏻 E14.0 rightwards hand: light skin tone
+1FAF1 1F3FC ; fully-qualified # 🫱🏼 E14.0 rightwards hand: medium-light skin tone
+1FAF1 1F3FD ; fully-qualified # 🫱🏽 E14.0 rightwards hand: medium skin tone
+1FAF1 1F3FE ; fully-qualified # 🫱🏾 E14.0 rightwards hand: medium-dark skin tone
+1FAF1 1F3FF ; fully-qualified # 🫱🏿 E14.0 rightwards hand: dark skin tone
+1FAF2 ; fully-qualified # 🫲 E14.0 leftwards hand
+1FAF2 1F3FB ; fully-qualified # 🫲🏻 E14.0 leftwards hand: light skin tone
+1FAF2 1F3FC ; fully-qualified # 🫲🏼 E14.0 leftwards hand: medium-light skin tone
+1FAF2 1F3FD ; fully-qualified # 🫲🏽 E14.0 leftwards hand: medium skin tone
+1FAF2 1F3FE ; fully-qualified # 🫲🏾 E14.0 leftwards hand: medium-dark skin tone
+1FAF2 1F3FF ; fully-qualified # 🫲🏿 E14.0 leftwards hand: dark skin tone
+1FAF3 ; fully-qualified # 🫳 E14.0 palm down hand
+1FAF3 1F3FB ; fully-qualified # 🫳🏻 E14.0 palm down hand: light skin tone
+1FAF3 1F3FC ; fully-qualified # 🫳🏼 E14.0 palm down hand: medium-light skin tone
+1FAF3 1F3FD ; fully-qualified # 🫳🏽 E14.0 palm down hand: medium skin tone
+1FAF3 1F3FE ; fully-qualified # 🫳🏾 E14.0 palm down hand: medium-dark skin tone
+1FAF3 1F3FF ; fully-qualified # 🫳🏿 E14.0 palm down hand: dark skin tone
+1FAF4 ; fully-qualified # 🫴 E14.0 palm up hand
+1FAF4 1F3FB ; fully-qualified # 🫴🏻 E14.0 palm up hand: light skin tone
+1FAF4 1F3FC ; fully-qualified # 🫴🏼 E14.0 palm up hand: medium-light skin tone
+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
+
+# subgroup: hand-fingers-partial
+1F44C ; fully-qualified # 👌 E0.6 OK hand
+1F44C 1F3FB ; fully-qualified # 👌🏻 E1.0 OK hand: light skin tone
+1F44C 1F3FC ; fully-qualified # 👌🏼 E1.0 OK hand: medium-light skin tone
+1F44C 1F3FD ; fully-qualified # 👌🏽 E1.0 OK hand: medium skin tone
+1F44C 1F3FE ; fully-qualified # 👌🏾 E1.0 OK hand: medium-dark skin tone
+1F44C 1F3FF ; fully-qualified # 👌🏿 E1.0 OK hand: dark skin tone
+1F90C ; fully-qualified # 🤌 E13.0 pinched fingers
+1F90C 1F3FB ; fully-qualified # 🤌🏻 E13.0 pinched fingers: light skin tone
+1F90C 1F3FC ; fully-qualified # 🤌🏼 E13.0 pinched fingers: medium-light skin tone
+1F90C 1F3FD ; fully-qualified # 🤌🏽 E13.0 pinched fingers: medium skin tone
+1F90C 1F3FE ; fully-qualified # 🤌🏾 E13.0 pinched fingers: medium-dark skin tone
+1F90C 1F3FF ; fully-qualified # 🤌🏿 E13.0 pinched fingers: dark skin tone
+1F90F ; fully-qualified # 🤏 E12.0 pinching hand
+1F90F 1F3FB ; fully-qualified # 🤏🏻 E12.0 pinching hand: light skin tone
+1F90F 1F3FC ; fully-qualified # 🤏🏼 E12.0 pinching hand: medium-light skin tone
+1F90F 1F3FD ; fully-qualified # 🤏🏽 E12.0 pinching hand: medium skin tone
+1F90F 1F3FE ; fully-qualified # 🤏🏾 E12.0 pinching hand: medium-dark skin tone
+1F90F 1F3FF ; fully-qualified # 🤏🏿 E12.0 pinching hand: dark skin tone
+270C FE0F ; fully-qualified # ✌️ E0.6 victory hand
+270C ; unqualified # ✌ E0.6 victory hand
+270C 1F3FB ; fully-qualified # ✌🏻 E1.0 victory hand: light skin tone
+270C 1F3FC ; fully-qualified # ✌🏼 E1.0 victory hand: medium-light skin tone
+270C 1F3FD ; fully-qualified # ✌🏽 E1.0 victory hand: medium skin tone
+270C 1F3FE ; fully-qualified # ✌🏾 E1.0 victory hand: medium-dark skin tone
+270C 1F3FF ; fully-qualified # ✌🏿 E1.0 victory hand: dark skin tone
+1F91E ; fully-qualified # 🤞 E3.0 crossed fingers
+1F91E 1F3FB ; fully-qualified # 🤞🏻 E3.0 crossed fingers: light skin tone
+1F91E 1F3FC ; fully-qualified # 🤞🏼 E3.0 crossed fingers: medium-light skin tone
+1F91E 1F3FD ; fully-qualified # 🤞🏽 E3.0 crossed fingers: medium skin tone
+1F91E 1F3FE ; fully-qualified # 🤞🏾 E3.0 crossed fingers: medium-dark skin tone
+1F91E 1F3FF ; fully-qualified # 🤞🏿 E3.0 crossed fingers: dark skin tone
+1FAF0 ; fully-qualified # 🫰 E14.0 hand with index finger and thumb crossed
+1FAF0 1F3FB ; fully-qualified # 🫰🏻 E14.0 hand with index finger and thumb crossed: light skin tone
+1FAF0 1F3FC ; fully-qualified # 🫰🏼 E14.0 hand with index finger and thumb crossed: medium-light skin tone
+1FAF0 1F3FD ; fully-qualified # 🫰🏽 E14.0 hand with index finger and thumb crossed: medium skin tone
+1FAF0 1F3FE ; fully-qualified # 🫰🏾 E14.0 hand with index finger and thumb crossed: medium-dark skin tone
+1FAF0 1F3FF ; fully-qualified # 🫰🏿 E14.0 hand with index finger and thumb crossed: dark skin tone
+1F91F ; fully-qualified # 🤟 E5.0 love-you gesture
+1F91F 1F3FB ; fully-qualified # 🤟🏻 E5.0 love-you gesture: light skin tone
+1F91F 1F3FC ; fully-qualified # 🤟🏼 E5.0 love-you gesture: medium-light skin tone
+1F91F 1F3FD ; fully-qualified # 🤟🏽 E5.0 love-you gesture: medium skin tone
+1F91F 1F3FE ; fully-qualified # 🤟🏾 E5.0 love-you gesture: medium-dark skin tone
+1F91F 1F3FF ; fully-qualified # 🤟🏿 E5.0 love-you gesture: dark skin tone
+1F918 ; fully-qualified # 🤘 E1.0 sign of the horns
+1F918 1F3FB ; fully-qualified # 🤘🏻 E1.0 sign of the horns: light skin tone
+1F918 1F3FC ; fully-qualified # 🤘🏼 E1.0 sign of the horns: medium-light skin tone
+1F918 1F3FD ; fully-qualified # 🤘🏽 E1.0 sign of the horns: medium skin tone
+1F918 1F3FE ; fully-qualified # 🤘🏾 E1.0 sign of the horns: medium-dark skin tone
+1F918 1F3FF ; fully-qualified # 🤘🏿 E1.0 sign of the horns: dark skin tone
+1F919 ; fully-qualified # 🤙 E3.0 call me hand
+1F919 1F3FB ; fully-qualified # 🤙🏻 E3.0 call me hand: light skin tone
+1F919 1F3FC ; fully-qualified # 🤙🏼 E3.0 call me hand: medium-light skin tone
+1F919 1F3FD ; fully-qualified # 🤙🏽 E3.0 call me hand: medium skin tone
+1F919 1F3FE ; fully-qualified # 🤙🏾 E3.0 call me hand: medium-dark skin tone
+1F919 1F3FF ; fully-qualified # 🤙🏿 E3.0 call me hand: dark skin tone
+
+# subgroup: hand-single-finger
+1F448 ; fully-qualified # 👈 E0.6 backhand index pointing left
+1F448 1F3FB ; fully-qualified # 👈🏻 E1.0 backhand index pointing left: light skin tone
+1F448 1F3FC ; fully-qualified # 👈🏼 E1.0 backhand index pointing left: medium-light skin tone
+1F448 1F3FD ; fully-qualified # 👈🏽 E1.0 backhand index pointing left: medium skin tone
+1F448 1F3FE ; fully-qualified # 👈🏾 E1.0 backhand index pointing left: medium-dark skin tone
+1F448 1F3FF ; fully-qualified # 👈🏿 E1.0 backhand index pointing left: dark skin tone
+1F449 ; fully-qualified # 👉 E0.6 backhand index pointing right
+1F449 1F3FB ; fully-qualified # 👉🏻 E1.0 backhand index pointing right: light skin tone
+1F449 1F3FC ; fully-qualified # 👉🏼 E1.0 backhand index pointing right: medium-light skin tone
+1F449 1F3FD ; fully-qualified # 👉🏽 E1.0 backhand index pointing right: medium skin tone
+1F449 1F3FE ; fully-qualified # 👉🏾 E1.0 backhand index pointing right: medium-dark skin tone
+1F449 1F3FF ; fully-qualified # 👉🏿 E1.0 backhand index pointing right: dark skin tone
+1F446 ; fully-qualified # 👆 E0.6 backhand index pointing up
+1F446 1F3FB ; fully-qualified # 👆🏻 E1.0 backhand index pointing up: light skin tone
+1F446 1F3FC ; fully-qualified # 👆🏼 E1.0 backhand index pointing up: medium-light skin tone
+1F446 1F3FD ; fully-qualified # 👆🏽 E1.0 backhand index pointing up: medium skin tone
+1F446 1F3FE ; fully-qualified # 👆🏾 E1.0 backhand index pointing up: medium-dark skin tone
+1F446 1F3FF ; fully-qualified # 👆🏿 E1.0 backhand index pointing up: dark skin tone
+1F595 ; fully-qualified # 🖕 E1.0 middle finger
+1F595 1F3FB ; fully-qualified # 🖕🏻 E1.0 middle finger: light skin tone
+1F595 1F3FC ; fully-qualified # 🖕🏼 E1.0 middle finger: medium-light skin tone
+1F595 1F3FD ; fully-qualified # 🖕🏽 E1.0 middle finger: medium skin tone
+1F595 1F3FE ; fully-qualified # 🖕🏾 E1.0 middle finger: medium-dark skin tone
+1F595 1F3FF ; fully-qualified # 🖕🏿 E1.0 middle finger: dark skin tone
+1F447 ; fully-qualified # 👇 E0.6 backhand index pointing down
+1F447 1F3FB ; fully-qualified # 👇🏻 E1.0 backhand index pointing down: light skin tone
+1F447 1F3FC ; fully-qualified # 👇🏼 E1.0 backhand index pointing down: medium-light skin tone
+1F447 1F3FD ; fully-qualified # 👇🏽 E1.0 backhand index pointing down: medium skin tone
+1F447 1F3FE ; fully-qualified # 👇🏾 E1.0 backhand index pointing down: medium-dark skin tone
+1F447 1F3FF ; fully-qualified # 👇🏿 E1.0 backhand index pointing down: dark skin tone
+261D FE0F ; fully-qualified # ☝️ E0.6 index pointing up
+261D ; unqualified # ☝ E0.6 index pointing up
+261D 1F3FB ; fully-qualified # ☝🏻 E1.0 index pointing up: light skin tone
+261D 1F3FC ; fully-qualified # ☝🏼 E1.0 index pointing up: medium-light skin tone
+261D 1F3FD ; fully-qualified # ☝🏽 E1.0 index pointing up: medium skin tone
+261D 1F3FE ; fully-qualified # ☝🏾 E1.0 index pointing up: medium-dark skin tone
+261D 1F3FF ; fully-qualified # ☝🏿 E1.0 index pointing up: dark skin tone
+1FAF5 ; fully-qualified # 🫵 E14.0 index pointing at the viewer
+1FAF5 1F3FB ; fully-qualified # 🫵🏻 E14.0 index pointing at the viewer: light skin tone
+1FAF5 1F3FC ; fully-qualified # 🫵🏼 E14.0 index pointing at the viewer: medium-light skin tone
+1FAF5 1F3FD ; fully-qualified # 🫵🏽 E14.0 index pointing at the viewer: medium skin tone
+1FAF5 1F3FE ; fully-qualified # 🫵🏾 E14.0 index pointing at the viewer: medium-dark skin tone
+1FAF5 1F3FF ; fully-qualified # 🫵🏿 E14.0 index pointing at the viewer: dark skin tone
+
+# subgroup: hand-fingers-closed
+1F44D ; fully-qualified # 👍 E0.6 thumbs up
+1F44D 1F3FB ; fully-qualified # 👍🏻 E1.0 thumbs up: light skin tone
+1F44D 1F3FC ; fully-qualified # 👍🏼 E1.0 thumbs up: medium-light skin tone
+1F44D 1F3FD ; fully-qualified # 👍🏽 E1.0 thumbs up: medium skin tone
+1F44D 1F3FE ; fully-qualified # 👍🏾 E1.0 thumbs up: medium-dark skin tone
+1F44D 1F3FF ; fully-qualified # 👍🏿 E1.0 thumbs up: dark skin tone
+1F44E ; fully-qualified # 👎 E0.6 thumbs down
+1F44E 1F3FB ; fully-qualified # 👎🏻 E1.0 thumbs down: light skin tone
+1F44E 1F3FC ; fully-qualified # 👎🏼 E1.0 thumbs down: medium-light skin tone
+1F44E 1F3FD ; fully-qualified # 👎🏽 E1.0 thumbs down: medium skin tone
+1F44E 1F3FE ; fully-qualified # 👎🏾 E1.0 thumbs down: medium-dark skin tone
+1F44E 1F3FF ; fully-qualified # 👎🏿 E1.0 thumbs down: dark skin tone
+270A ; fully-qualified # ✊ E0.6 raised fist
+270A 1F3FB ; fully-qualified # ✊🏻 E1.0 raised fist: light skin tone
+270A 1F3FC ; fully-qualified # ✊🏼 E1.0 raised fist: medium-light skin tone
+270A 1F3FD ; fully-qualified # ✊🏽 E1.0 raised fist: medium skin tone
+270A 1F3FE ; fully-qualified # ✊🏾 E1.0 raised fist: medium-dark skin tone
+270A 1F3FF ; fully-qualified # ✊🏿 E1.0 raised fist: dark skin tone
+1F44A ; fully-qualified # 👊 E0.6 oncoming fist
+1F44A 1F3FB ; fully-qualified # 👊🏻 E1.0 oncoming fist: light skin tone
+1F44A 1F3FC ; fully-qualified # 👊🏼 E1.0 oncoming fist: medium-light skin tone
+1F44A 1F3FD ; fully-qualified # 👊🏽 E1.0 oncoming fist: medium skin tone
+1F44A 1F3FE ; fully-qualified # 👊🏾 E1.0 oncoming fist: medium-dark skin tone
+1F44A 1F3FF ; fully-qualified # 👊🏿 E1.0 oncoming fist: dark skin tone
+1F91B ; fully-qualified # 🤛 E3.0 left-facing fist
+1F91B 1F3FB ; fully-qualified # 🤛🏻 E3.0 left-facing fist: light skin tone
+1F91B 1F3FC ; fully-qualified # 🤛🏼 E3.0 left-facing fist: medium-light skin tone
+1F91B 1F3FD ; fully-qualified # 🤛🏽 E3.0 left-facing fist: medium skin tone
+1F91B 1F3FE ; fully-qualified # 🤛🏾 E3.0 left-facing fist: medium-dark skin tone
+1F91B 1F3FF ; fully-qualified # 🤛🏿 E3.0 left-facing fist: dark skin tone
+1F91C ; fully-qualified # 🤜 E3.0 right-facing fist
+1F91C 1F3FB ; fully-qualified # 🤜🏻 E3.0 right-facing fist: light skin tone
+1F91C 1F3FC ; fully-qualified # 🤜🏼 E3.0 right-facing fist: medium-light skin tone
+1F91C 1F3FD ; fully-qualified # 🤜🏽 E3.0 right-facing fist: medium skin tone
+1F91C 1F3FE ; fully-qualified # 🤜🏾 E3.0 right-facing fist: medium-dark skin tone
+1F91C 1F3FF ; fully-qualified # 🤜🏿 E3.0 right-facing fist: dark skin tone
+
+# subgroup: hands
+1F44F ; fully-qualified # 👏 E0.6 clapping hands
+1F44F 1F3FB ; fully-qualified # 👏🏻 E1.0 clapping hands: light skin tone
+1F44F 1F3FC ; fully-qualified # 👏🏼 E1.0 clapping hands: medium-light skin tone
+1F44F 1F3FD ; fully-qualified # 👏🏽 E1.0 clapping hands: medium skin tone
+1F44F 1F3FE ; fully-qualified # 👏🏾 E1.0 clapping hands: medium-dark skin tone
+1F44F 1F3FF ; fully-qualified # 👏🏿 E1.0 clapping hands: dark skin tone
+1F64C ; fully-qualified # 🙌 E0.6 raising hands
+1F64C 1F3FB ; fully-qualified # 🙌🏻 E1.0 raising hands: light skin tone
+1F64C 1F3FC ; fully-qualified # 🙌🏼 E1.0 raising hands: medium-light skin tone
+1F64C 1F3FD ; fully-qualified # 🙌🏽 E1.0 raising hands: medium skin tone
+1F64C 1F3FE ; fully-qualified # 🙌🏾 E1.0 raising hands: medium-dark skin tone
+1F64C 1F3FF ; fully-qualified # 🙌🏿 E1.0 raising hands: dark skin tone
+1FAF6 ; fully-qualified # 🫶 E14.0 heart hands
+1FAF6 1F3FB ; fully-qualified # 🫶🏻 E14.0 heart hands: light skin tone
+1FAF6 1F3FC ; fully-qualified # 🫶🏼 E14.0 heart hands: medium-light skin tone
+1FAF6 1F3FD ; fully-qualified # 🫶🏽 E14.0 heart hands: medium skin tone
+1FAF6 1F3FE ; fully-qualified # 🫶🏾 E14.0 heart hands: medium-dark skin tone
+1FAF6 1F3FF ; fully-qualified # 🫶🏿 E14.0 heart hands: dark skin tone
+1F450 ; fully-qualified # 👐 E0.6 open hands
+1F450 1F3FB ; fully-qualified # 👐🏻 E1.0 open hands: light skin tone
+1F450 1F3FC ; fully-qualified # 👐🏼 E1.0 open hands: medium-light skin tone
+1F450 1F3FD ; fully-qualified # 👐🏽 E1.0 open hands: medium skin tone
+1F450 1F3FE ; fully-qualified # 👐🏾 E1.0 open hands: medium-dark skin tone
+1F450 1F3FF ; fully-qualified # 👐🏿 E1.0 open hands: dark skin tone
+1F932 ; fully-qualified # 🤲 E5.0 palms up together
+1F932 1F3FB ; fully-qualified # 🤲🏻 E5.0 palms up together: light skin tone
+1F932 1F3FC ; fully-qualified # 🤲🏼 E5.0 palms up together: medium-light skin tone
+1F932 1F3FD ; fully-qualified # 🤲🏽 E5.0 palms up together: medium skin tone
+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
+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
+1FAF1 1F3FB 200D 1FAF2 1F3FF ; fully-qualified # 🫱🏻‍🫲🏿 E14.0 handshake: light skin tone, dark skin tone
+1FAF1 1F3FC 200D 1FAF2 1F3FB ; fully-qualified # 🫱🏼‍🫲🏻 E14.0 handshake: medium-light skin tone, light skin tone
+1FAF1 1F3FC 200D 1FAF2 1F3FD ; fully-qualified # 🫱🏼‍🫲🏽 E14.0 handshake: medium-light skin tone, medium skin tone
+1FAF1 1F3FC 200D 1FAF2 1F3FE ; fully-qualified # 🫱🏼‍🫲🏾 E14.0 handshake: medium-light skin tone, medium-dark skin tone
+1FAF1 1F3FC 200D 1FAF2 1F3FF ; fully-qualified # 🫱🏼‍🫲🏿 E14.0 handshake: medium-light skin tone, dark skin tone
+1FAF1 1F3FD 200D 1FAF2 1F3FB ; fully-qualified # 🫱🏽‍🫲🏻 E14.0 handshake: medium skin tone, light skin tone
+1FAF1 1F3FD 200D 1FAF2 1F3FC ; fully-qualified # 🫱🏽‍🫲🏼 E14.0 handshake: medium skin tone, medium-light skin tone
+1FAF1 1F3FD 200D 1FAF2 1F3FE ; fully-qualified # 🫱🏽‍🫲🏾 E14.0 handshake: medium skin tone, medium-dark skin tone
+1FAF1 1F3FD 200D 1FAF2 1F3FF ; fully-qualified # 🫱🏽‍🫲🏿 E14.0 handshake: medium skin tone, dark skin tone
+1FAF1 1F3FE 200D 1FAF2 1F3FB ; fully-qualified # 🫱🏾‍🫲🏻 E14.0 handshake: medium-dark skin tone, light skin tone
+1FAF1 1F3FE 200D 1FAF2 1F3FC ; fully-qualified # 🫱🏾‍🫲🏼 E14.0 handshake: medium-dark skin tone, medium-light skin tone
+1FAF1 1F3FE 200D 1FAF2 1F3FD ; fully-qualified # 🫱🏾‍🫲🏽 E14.0 handshake: medium-dark skin tone, medium skin tone
+1FAF1 1F3FE 200D 1FAF2 1F3FF ; fully-qualified # 🫱🏾‍🫲🏿 E14.0 handshake: medium-dark skin tone, dark skin tone
+1FAF1 1F3FF 200D 1FAF2 1F3FB ; fully-qualified # 🫱🏿‍🫲🏻 E14.0 handshake: dark skin tone, light skin tone
+1FAF1 1F3FF 200D 1FAF2 1F3FC ; fully-qualified # 🫱🏿‍🫲🏼 E14.0 handshake: dark skin tone, medium-light skin tone
+1FAF1 1F3FF 200D 1FAF2 1F3FD ; fully-qualified # 🫱🏿‍🫲🏽 E14.0 handshake: dark skin tone, medium skin tone
+1FAF1 1F3FF 200D 1FAF2 1F3FE ; fully-qualified # 🫱🏿‍🫲🏾 E14.0 handshake: dark skin tone, medium-dark skin tone
+1F64F ; fully-qualified # 🙏 E0.6 folded hands
+1F64F 1F3FB ; fully-qualified # 🙏🏻 E1.0 folded hands: light skin tone
+1F64F 1F3FC ; fully-qualified # 🙏🏼 E1.0 folded hands: medium-light skin tone
+1F64F 1F3FD ; fully-qualified # 🙏🏽 E1.0 folded hands: medium skin tone
+1F64F 1F3FE ; fully-qualified # 🙏🏾 E1.0 folded hands: medium-dark skin tone
+1F64F 1F3FF ; fully-qualified # 🙏🏿 E1.0 folded hands: dark skin tone
+
+# subgroup: hand-prop
+270D FE0F ; fully-qualified # ✍️ E0.7 writing hand
+270D ; unqualified # ✍ E0.7 writing hand
+270D 1F3FB ; fully-qualified # ✍🏻 E1.0 writing hand: light skin tone
+270D 1F3FC ; fully-qualified # ✍🏼 E1.0 writing hand: medium-light skin tone
+270D 1F3FD ; fully-qualified # ✍🏽 E1.0 writing hand: medium skin tone
+270D 1F3FE ; fully-qualified # ✍🏾 E1.0 writing hand: medium-dark skin tone
+270D 1F3FF ; fully-qualified # ✍🏿 E1.0 writing hand: dark skin tone
+1F485 ; fully-qualified # 💅 E0.6 nail polish
+1F485 1F3FB ; fully-qualified # 💅🏻 E1.0 nail polish: light skin tone
+1F485 1F3FC ; fully-qualified # 💅🏼 E1.0 nail polish: medium-light skin tone
+1F485 1F3FD ; fully-qualified # 💅🏽 E1.0 nail polish: medium skin tone
+1F485 1F3FE ; fully-qualified # 💅🏾 E1.0 nail polish: medium-dark skin tone
+1F485 1F3FF ; fully-qualified # 💅🏿 E1.0 nail polish: dark skin tone
+1F933 ; fully-qualified # 🤳 E3.0 selfie
+1F933 1F3FB ; fully-qualified # 🤳🏻 E3.0 selfie: light skin tone
+1F933 1F3FC ; fully-qualified # 🤳🏼 E3.0 selfie: medium-light skin tone
+1F933 1F3FD ; fully-qualified # 🤳🏽 E3.0 selfie: medium skin tone
+1F933 1F3FE ; fully-qualified # 🤳🏾 E3.0 selfie: medium-dark skin tone
+1F933 1F3FF ; fully-qualified # 🤳🏿 E3.0 selfie: dark skin tone
+
+# subgroup: body-parts
+1F4AA ; fully-qualified # 💪 E0.6 flexed biceps
+1F4AA 1F3FB ; fully-qualified # 💪🏻 E1.0 flexed biceps: light skin tone
+1F4AA 1F3FC ; fully-qualified # 💪🏼 E1.0 flexed biceps: medium-light skin tone
+1F4AA 1F3FD ; fully-qualified # 💪🏽 E1.0 flexed biceps: medium skin tone
+1F4AA 1F3FE ; fully-qualified # 💪🏾 E1.0 flexed biceps: medium-dark skin tone
+1F4AA 1F3FF ; fully-qualified # 💪🏿 E1.0 flexed biceps: dark skin tone
+1F9BE ; fully-qualified # 🦾 E12.0 mechanical arm
+1F9BF ; fully-qualified # 🦿 E12.0 mechanical leg
+1F9B5 ; fully-qualified # 🦵 E11.0 leg
+1F9B5 1F3FB ; fully-qualified # 🦵🏻 E11.0 leg: light skin tone
+1F9B5 1F3FC ; fully-qualified # 🦵🏼 E11.0 leg: medium-light skin tone
+1F9B5 1F3FD ; fully-qualified # 🦵🏽 E11.0 leg: medium skin tone
+1F9B5 1F3FE ; fully-qualified # 🦵🏾 E11.0 leg: medium-dark skin tone
+1F9B5 1F3FF ; fully-qualified # 🦵🏿 E11.0 leg: dark skin tone
+1F9B6 ; fully-qualified # 🦶 E11.0 foot
+1F9B6 1F3FB ; fully-qualified # 🦶🏻 E11.0 foot: light skin tone
+1F9B6 1F3FC ; fully-qualified # 🦶🏼 E11.0 foot: medium-light skin tone
+1F9B6 1F3FD ; fully-qualified # 🦶🏽 E11.0 foot: medium skin tone
+1F9B6 1F3FE ; fully-qualified # 🦶🏾 E11.0 foot: medium-dark skin tone
+1F9B6 1F3FF ; fully-qualified # 🦶🏿 E11.0 foot: dark skin tone
+1F442 ; fully-qualified # 👂 E0.6 ear
+1F442 1F3FB ; fully-qualified # 👂🏻 E1.0 ear: light skin tone
+1F442 1F3FC ; fully-qualified # 👂🏼 E1.0 ear: medium-light skin tone
+1F442 1F3FD ; fully-qualified # 👂🏽 E1.0 ear: medium skin tone
+1F442 1F3FE ; fully-qualified # 👂🏾 E1.0 ear: medium-dark skin tone
+1F442 1F3FF ; fully-qualified # 👂🏿 E1.0 ear: dark skin tone
+1F9BB ; fully-qualified # 🦻 E12.0 ear with hearing aid
+1F9BB 1F3FB ; fully-qualified # 🦻🏻 E12.0 ear with hearing aid: light skin tone
+1F9BB 1F3FC ; fully-qualified # 🦻🏼 E12.0 ear with hearing aid: medium-light skin tone
+1F9BB 1F3FD ; fully-qualified # 🦻🏽 E12.0 ear with hearing aid: medium skin tone
+1F9BB 1F3FE ; fully-qualified # 🦻🏾 E12.0 ear with hearing aid: medium-dark skin tone
+1F9BB 1F3FF ; fully-qualified # 🦻🏿 E12.0 ear with hearing aid: dark skin tone
+1F443 ; fully-qualified # 👃 E0.6 nose
+1F443 1F3FB ; fully-qualified # 👃🏻 E1.0 nose: light skin tone
+1F443 1F3FC ; fully-qualified # 👃🏼 E1.0 nose: medium-light skin tone
+1F443 1F3FD ; fully-qualified # 👃🏽 E1.0 nose: medium skin tone
+1F443 1F3FE ; fully-qualified # 👃🏾 E1.0 nose: medium-dark skin tone
+1F443 1F3FF ; fully-qualified # 👃🏿 E1.0 nose: dark skin tone
+1F9E0 ; fully-qualified # 🧠 E5.0 brain
+1FAC0 ; fully-qualified # 🫀 E13.0 anatomical heart
+1FAC1 ; fully-qualified # 🫁 E13.0 lungs
+1F9B7 ; fully-qualified # 🦷 E11.0 tooth
+1F9B4 ; fully-qualified # 🦴 E11.0 bone
+1F440 ; fully-qualified # 👀 E0.6 eyes
+1F441 FE0F ; fully-qualified # 👁️ E0.7 eye
+1F441 ; unqualified # 👁 E0.7 eye
+1F445 ; fully-qualified # 👅 E0.6 tongue
+1F444 ; fully-qualified # 👄 E0.6 mouth
+1FAE6 ; fully-qualified # 🫦 E14.0 biting lip
+
+# subgroup: person
+1F476 ; fully-qualified # 👶 E0.6 baby
+1F476 1F3FB ; fully-qualified # 👶🏻 E1.0 baby: light skin tone
+1F476 1F3FC ; fully-qualified # 👶🏼 E1.0 baby: medium-light skin tone
+1F476 1F3FD ; fully-qualified # 👶🏽 E1.0 baby: medium skin tone
+1F476 1F3FE ; fully-qualified # 👶🏾 E1.0 baby: medium-dark skin tone
+1F476 1F3FF ; fully-qualified # 👶🏿 E1.0 baby: dark skin tone
+1F9D2 ; fully-qualified # 🧒 E5.0 child
+1F9D2 1F3FB ; fully-qualified # 🧒🏻 E5.0 child: light skin tone
+1F9D2 1F3FC ; fully-qualified # 🧒🏼 E5.0 child: medium-light skin tone
+1F9D2 1F3FD ; fully-qualified # 🧒🏽 E5.0 child: medium skin tone
+1F9D2 1F3FE ; fully-qualified # 🧒🏾 E5.0 child: medium-dark skin tone
+1F9D2 1F3FF ; fully-qualified # 🧒🏿 E5.0 child: dark skin tone
+1F466 ; fully-qualified # 👦 E0.6 boy
+1F466 1F3FB ; fully-qualified # 👦🏻 E1.0 boy: light skin tone
+1F466 1F3FC ; fully-qualified # 👦🏼 E1.0 boy: medium-light skin tone
+1F466 1F3FD ; fully-qualified # 👦🏽 E1.0 boy: medium skin tone
+1F466 1F3FE ; fully-qualified # 👦🏾 E1.0 boy: medium-dark skin tone
+1F466 1F3FF ; fully-qualified # 👦🏿 E1.0 boy: dark skin tone
+1F467 ; fully-qualified # 👧 E0.6 girl
+1F467 1F3FB ; fully-qualified # 👧🏻 E1.0 girl: light skin tone
+1F467 1F3FC ; fully-qualified # 👧🏼 E1.0 girl: medium-light skin tone
+1F467 1F3FD ; fully-qualified # 👧🏽 E1.0 girl: medium skin tone
+1F467 1F3FE ; fully-qualified # 👧🏾 E1.0 girl: medium-dark skin tone
+1F467 1F3FF ; fully-qualified # 👧🏿 E1.0 girl: dark skin tone
+1F9D1 ; fully-qualified # 🧑 E5.0 person
+1F9D1 1F3FB ; fully-qualified # 🧑🏻 E5.0 person: light skin tone
+1F9D1 1F3FC ; fully-qualified # 🧑🏼 E5.0 person: medium-light skin tone
+1F9D1 1F3FD ; fully-qualified # 🧑🏽 E5.0 person: medium skin tone
+1F9D1 1F3FE ; fully-qualified # 🧑🏾 E5.0 person: medium-dark skin tone
+1F9D1 1F3FF ; fully-qualified # 🧑🏿 E5.0 person: dark skin tone
+1F471 ; fully-qualified # 👱 E0.6 person: blond hair
+1F471 1F3FB ; fully-qualified # 👱🏻 E1.0 person: light skin tone, blond hair
+1F471 1F3FC ; fully-qualified # 👱🏼 E1.0 person: medium-light skin tone, blond hair
+1F471 1F3FD ; fully-qualified # 👱🏽 E1.0 person: medium skin tone, blond hair
+1F471 1F3FE ; fully-qualified # 👱🏾 E1.0 person: medium-dark skin tone, blond hair
+1F471 1F3FF ; fully-qualified # 👱🏿 E1.0 person: dark skin tone, blond hair
+1F468 ; fully-qualified # 👨 E0.6 man
+1F468 1F3FB ; fully-qualified # 👨🏻 E1.0 man: light skin tone
+1F468 1F3FC ; fully-qualified # 👨🏼 E1.0 man: medium-light skin tone
+1F468 1F3FD ; fully-qualified # 👨🏽 E1.0 man: medium skin tone
+1F468 1F3FE ; fully-qualified # 👨🏾 E1.0 man: medium-dark skin tone
+1F468 1F3FF ; fully-qualified # 👨🏿 E1.0 man: dark skin tone
+1F9D4 ; fully-qualified # 🧔 E5.0 person: beard
+1F9D4 1F3FB ; fully-qualified # 🧔🏻 E5.0 person: light skin tone, beard
+1F9D4 1F3FC ; fully-qualified # 🧔🏼 E5.0 person: medium-light skin tone, beard
+1F9D4 1F3FD ; fully-qualified # 🧔🏽 E5.0 person: medium skin tone, beard
+1F9D4 1F3FE ; fully-qualified # 🧔🏾 E5.0 person: medium-dark skin tone, beard
+1F9D4 1F3FF ; fully-qualified # 🧔🏿 E5.0 person: dark skin tone, beard
+1F9D4 200D 2642 FE0F ; fully-qualified # 🧔‍♂️ E13.1 man: beard
+1F9D4 200D 2642 ; minimally-qualified # 🧔‍♂ E13.1 man: beard
+1F9D4 1F3FB 200D 2642 FE0F ; fully-qualified # 🧔🏻‍♂️ E13.1 man: light skin tone, beard
+1F9D4 1F3FB 200D 2642 ; minimally-qualified # 🧔🏻‍♂ E13.1 man: light skin tone, beard
+1F9D4 1F3FC 200D 2642 FE0F ; fully-qualified # 🧔🏼‍♂️ E13.1 man: medium-light skin tone, beard
+1F9D4 1F3FC 200D 2642 ; minimally-qualified # 🧔🏼‍♂ E13.1 man: medium-light skin tone, beard
+1F9D4 1F3FD 200D 2642 FE0F ; fully-qualified # 🧔🏽‍♂️ E13.1 man: medium skin tone, beard
+1F9D4 1F3FD 200D 2642 ; minimally-qualified # 🧔🏽‍♂ E13.1 man: medium skin tone, beard
+1F9D4 1F3FE 200D 2642 FE0F ; fully-qualified # 🧔🏾‍♂️ E13.1 man: medium-dark skin tone, beard
+1F9D4 1F3FE 200D 2642 ; minimally-qualified # 🧔🏾‍♂ E13.1 man: medium-dark skin tone, beard
+1F9D4 1F3FF 200D 2642 FE0F ; fully-qualified # 🧔🏿‍♂️ E13.1 man: dark skin tone, beard
+1F9D4 1F3FF 200D 2642 ; minimally-qualified # 🧔🏿‍♂ E13.1 man: dark skin tone, beard
+1F9D4 200D 2640 FE0F ; fully-qualified # 🧔‍♀️ E13.1 woman: beard
+1F9D4 200D 2640 ; minimally-qualified # 🧔‍♀ E13.1 woman: beard
+1F9D4 1F3FB 200D 2640 FE0F ; fully-qualified # 🧔🏻‍♀️ E13.1 woman: light skin tone, beard
+1F9D4 1F3FB 200D 2640 ; minimally-qualified # 🧔🏻‍♀ E13.1 woman: light skin tone, beard
+1F9D4 1F3FC 200D 2640 FE0F ; fully-qualified # 🧔🏼‍♀️ E13.1 woman: medium-light skin tone, beard
+1F9D4 1F3FC 200D 2640 ; minimally-qualified # 🧔🏼‍♀ E13.1 woman: medium-light skin tone, beard
+1F9D4 1F3FD 200D 2640 FE0F ; fully-qualified # 🧔🏽‍♀️ E13.1 woman: medium skin tone, beard
+1F9D4 1F3FD 200D 2640 ; minimally-qualified # 🧔🏽‍♀ E13.1 woman: medium skin tone, beard
+1F9D4 1F3FE 200D 2640 FE0F ; fully-qualified # 🧔🏾‍♀️ E13.1 woman: medium-dark skin tone, beard
+1F9D4 1F3FE 200D 2640 ; minimally-qualified # 🧔🏾‍♀ E13.1 woman: medium-dark skin tone, beard
+1F9D4 1F3FF 200D 2640 FE0F ; fully-qualified # 🧔🏿‍♀️ E13.1 woman: dark skin tone, beard
+1F9D4 1F3FF 200D 2640 ; minimally-qualified # 🧔🏿‍♀ E13.1 woman: dark skin tone, beard
+1F468 200D 1F9B0 ; fully-qualified # 👨‍🦰 E11.0 man: red hair
+1F468 1F3FB 200D 1F9B0 ; fully-qualified # 👨🏻‍🦰 E11.0 man: light skin tone, red hair
+1F468 1F3FC 200D 1F9B0 ; fully-qualified # 👨🏼‍🦰 E11.0 man: medium-light skin tone, red hair
+1F468 1F3FD 200D 1F9B0 ; fully-qualified # 👨🏽‍🦰 E11.0 man: medium skin tone, red hair
+1F468 1F3FE 200D 1F9B0 ; fully-qualified # 👨🏾‍🦰 E11.0 man: medium-dark skin tone, red hair
+1F468 1F3FF 200D 1F9B0 ; fully-qualified # 👨🏿‍🦰 E11.0 man: dark skin tone, red hair
+1F468 200D 1F9B1 ; fully-qualified # 👨‍🦱 E11.0 man: curly hair
+1F468 1F3FB 200D 1F9B1 ; fully-qualified # 👨🏻‍🦱 E11.0 man: light skin tone, curly hair
+1F468 1F3FC 200D 1F9B1 ; fully-qualified # 👨🏼‍🦱 E11.0 man: medium-light skin tone, curly hair
+1F468 1F3FD 200D 1F9B1 ; fully-qualified # 👨🏽‍🦱 E11.0 man: medium skin tone, curly hair
+1F468 1F3FE 200D 1F9B1 ; fully-qualified # 👨🏾‍🦱 E11.0 man: medium-dark skin tone, curly hair
+1F468 1F3FF 200D 1F9B1 ; fully-qualified # 👨🏿‍🦱 E11.0 man: dark skin tone, curly hair
+1F468 200D 1F9B3 ; fully-qualified # 👨‍🦳 E11.0 man: white hair
+1F468 1F3FB 200D 1F9B3 ; fully-qualified # 👨🏻‍🦳 E11.0 man: light skin tone, white hair
+1F468 1F3FC 200D 1F9B3 ; fully-qualified # 👨🏼‍🦳 E11.0 man: medium-light skin tone, white hair
+1F468 1F3FD 200D 1F9B3 ; fully-qualified # 👨🏽‍🦳 E11.0 man: medium skin tone, white hair
+1F468 1F3FE 200D 1F9B3 ; fully-qualified # 👨🏾‍🦳 E11.0 man: medium-dark skin tone, white hair
+1F468 1F3FF 200D 1F9B3 ; fully-qualified # 👨🏿‍🦳 E11.0 man: dark skin tone, white hair
+1F468 200D 1F9B2 ; fully-qualified # 👨‍🦲 E11.0 man: bald
+1F468 1F3FB 200D 1F9B2 ; fully-qualified # 👨🏻‍🦲 E11.0 man: light skin tone, bald
+1F468 1F3FC 200D 1F9B2 ; fully-qualified # 👨🏼‍🦲 E11.0 man: medium-light skin tone, bald
+1F468 1F3FD 200D 1F9B2 ; fully-qualified # 👨🏽‍🦲 E11.0 man: medium skin tone, bald
+1F468 1F3FE 200D 1F9B2 ; fully-qualified # 👨🏾‍🦲 E11.0 man: medium-dark skin tone, bald
+1F468 1F3FF 200D 1F9B2 ; fully-qualified # 👨🏿‍🦲 E11.0 man: dark skin tone, bald
+1F469 ; fully-qualified # 👩 E0.6 woman
+1F469 1F3FB ; fully-qualified # 👩🏻 E1.0 woman: light skin tone
+1F469 1F3FC ; fully-qualified # 👩🏼 E1.0 woman: medium-light skin tone
+1F469 1F3FD ; fully-qualified # 👩🏽 E1.0 woman: medium skin tone
+1F469 1F3FE ; fully-qualified # 👩🏾 E1.0 woman: medium-dark skin tone
+1F469 1F3FF ; fully-qualified # 👩🏿 E1.0 woman: dark skin tone
+1F469 200D 1F9B0 ; fully-qualified # 👩‍🦰 E11.0 woman: red hair
+1F469 1F3FB 200D 1F9B0 ; fully-qualified # 👩🏻‍🦰 E11.0 woman: light skin tone, red hair
+1F469 1F3FC 200D 1F9B0 ; fully-qualified # 👩🏼‍🦰 E11.0 woman: medium-light skin tone, red hair
+1F469 1F3FD 200D 1F9B0 ; fully-qualified # 👩🏽‍🦰 E11.0 woman: medium skin tone, red hair
+1F469 1F3FE 200D 1F9B0 ; fully-qualified # 👩🏾‍🦰 E11.0 woman: medium-dark skin tone, red hair
+1F469 1F3FF 200D 1F9B0 ; fully-qualified # 👩🏿‍🦰 E11.0 woman: dark skin tone, red hair
+1F9D1 200D 1F9B0 ; fully-qualified # 🧑‍🦰 E12.1 person: red hair
+1F9D1 1F3FB 200D 1F9B0 ; fully-qualified # 🧑🏻‍🦰 E12.1 person: light skin tone, red hair
+1F9D1 1F3FC 200D 1F9B0 ; fully-qualified # 🧑🏼‍🦰 E12.1 person: medium-light skin tone, red hair
+1F9D1 1F3FD 200D 1F9B0 ; fully-qualified # 🧑🏽‍🦰 E12.1 person: medium skin tone, red hair
+1F9D1 1F3FE 200D 1F9B0 ; fully-qualified # 🧑🏾‍🦰 E12.1 person: medium-dark skin tone, red hair
+1F9D1 1F3FF 200D 1F9B0 ; fully-qualified # 🧑🏿‍🦰 E12.1 person: dark skin tone, red hair
+1F469 200D 1F9B1 ; fully-qualified # 👩‍🦱 E11.0 woman: curly hair
+1F469 1F3FB 200D 1F9B1 ; fully-qualified # 👩🏻‍🦱 E11.0 woman: light skin tone, curly hair
+1F469 1F3FC 200D 1F9B1 ; fully-qualified # 👩🏼‍🦱 E11.0 woman: medium-light skin tone, curly hair
+1F469 1F3FD 200D 1F9B1 ; fully-qualified # 👩🏽‍🦱 E11.0 woman: medium skin tone, curly hair
+1F469 1F3FE 200D 1F9B1 ; fully-qualified # 👩🏾‍🦱 E11.0 woman: medium-dark skin tone, curly hair
+1F469 1F3FF 200D 1F9B1 ; fully-qualified # 👩🏿‍🦱 E11.0 woman: dark skin tone, curly hair
+1F9D1 200D 1F9B1 ; fully-qualified # 🧑‍🦱 E12.1 person: curly hair
+1F9D1 1F3FB 200D 1F9B1 ; fully-qualified # 🧑🏻‍🦱 E12.1 person: light skin tone, curly hair
+1F9D1 1F3FC 200D 1F9B1 ; fully-qualified # 🧑🏼‍🦱 E12.1 person: medium-light skin tone, curly hair
+1F9D1 1F3FD 200D 1F9B1 ; fully-qualified # 🧑🏽‍🦱 E12.1 person: medium skin tone, curly hair
+1F9D1 1F3FE 200D 1F9B1 ; fully-qualified # 🧑🏾‍🦱 E12.1 person: medium-dark skin tone, curly hair
+1F9D1 1F3FF 200D 1F9B1 ; fully-qualified # 🧑🏿‍🦱 E12.1 person: dark skin tone, curly hair
+1F469 200D 1F9B3 ; fully-qualified # 👩‍🦳 E11.0 woman: white hair
+1F469 1F3FB 200D 1F9B3 ; fully-qualified # 👩🏻‍🦳 E11.0 woman: light skin tone, white hair
+1F469 1F3FC 200D 1F9B3 ; fully-qualified # 👩🏼‍🦳 E11.0 woman: medium-light skin tone, white hair
+1F469 1F3FD 200D 1F9B3 ; fully-qualified # 👩🏽‍🦳 E11.0 woman: medium skin tone, white hair
+1F469 1F3FE 200D 1F9B3 ; fully-qualified # 👩🏾‍🦳 E11.0 woman: medium-dark skin tone, white hair
+1F469 1F3FF 200D 1F9B3 ; fully-qualified # 👩🏿‍🦳 E11.0 woman: dark skin tone, white hair
+1F9D1 200D 1F9B3 ; fully-qualified # 🧑‍🦳 E12.1 person: white hair
+1F9D1 1F3FB 200D 1F9B3 ; fully-qualified # 🧑🏻‍🦳 E12.1 person: light skin tone, white hair
+1F9D1 1F3FC 200D 1F9B3 ; fully-qualified # 🧑🏼‍🦳 E12.1 person: medium-light skin tone, white hair
+1F9D1 1F3FD 200D 1F9B3 ; fully-qualified # 🧑🏽‍🦳 E12.1 person: medium skin tone, white hair
+1F9D1 1F3FE 200D 1F9B3 ; fully-qualified # 🧑🏾‍🦳 E12.1 person: medium-dark skin tone, white hair
+1F9D1 1F3FF 200D 1F9B3 ; fully-qualified # 🧑🏿‍🦳 E12.1 person: dark skin tone, white hair
+1F469 200D 1F9B2 ; fully-qualified # 👩‍🦲 E11.0 woman: bald
+1F469 1F3FB 200D 1F9B2 ; fully-qualified # 👩🏻‍🦲 E11.0 woman: light skin tone, bald
+1F469 1F3FC 200D 1F9B2 ; fully-qualified # 👩🏼‍🦲 E11.0 woman: medium-light skin tone, bald
+1F469 1F3FD 200D 1F9B2 ; fully-qualified # 👩🏽‍🦲 E11.0 woman: medium skin tone, bald
+1F469 1F3FE 200D 1F9B2 ; fully-qualified # 👩🏾‍🦲 E11.0 woman: medium-dark skin tone, bald
+1F469 1F3FF 200D 1F9B2 ; fully-qualified # 👩🏿‍🦲 E11.0 woman: dark skin tone, bald
+1F9D1 200D 1F9B2 ; fully-qualified # 🧑‍🦲 E12.1 person: bald
+1F9D1 1F3FB 200D 1F9B2 ; fully-qualified # 🧑🏻‍🦲 E12.1 person: light skin tone, bald
+1F9D1 1F3FC 200D 1F9B2 ; fully-qualified # 🧑🏼‍🦲 E12.1 person: medium-light skin tone, bald
+1F9D1 1F3FD 200D 1F9B2 ; fully-qualified # 🧑🏽‍🦲 E12.1 person: medium skin tone, bald
+1F9D1 1F3FE 200D 1F9B2 ; fully-qualified # 🧑🏾‍🦲 E12.1 person: medium-dark skin tone, bald
+1F9D1 1F3FF 200D 1F9B2 ; fully-qualified # 🧑🏿‍🦲 E12.1 person: dark skin tone, bald
+1F471 200D 2640 FE0F ; fully-qualified # 👱‍♀️ E4.0 woman: blond hair
+1F471 200D 2640 ; minimally-qualified # 👱‍♀ E4.0 woman: blond hair
+1F471 1F3FB 200D 2640 FE0F ; fully-qualified # 👱🏻‍♀️ E4.0 woman: light skin tone, blond hair
+1F471 1F3FB 200D 2640 ; minimally-qualified # 👱🏻‍♀ E4.0 woman: light skin tone, blond hair
+1F471 1F3FC 200D 2640 FE0F ; fully-qualified # 👱🏼‍♀️ E4.0 woman: medium-light skin tone, blond hair
+1F471 1F3FC 200D 2640 ; minimally-qualified # 👱🏼‍♀ E4.0 woman: medium-light skin tone, blond hair
+1F471 1F3FD 200D 2640 FE0F ; fully-qualified # 👱🏽‍♀️ E4.0 woman: medium skin tone, blond hair
+1F471 1F3FD 200D 2640 ; minimally-qualified # 👱🏽‍♀ E4.0 woman: medium skin tone, blond hair
+1F471 1F3FE 200D 2640 FE0F ; fully-qualified # 👱🏾‍♀️ E4.0 woman: medium-dark skin tone, blond hair
+1F471 1F3FE 200D 2640 ; minimally-qualified # 👱🏾‍♀ E4.0 woman: medium-dark skin tone, blond hair
+1F471 1F3FF 200D 2640 FE0F ; fully-qualified # 👱🏿‍♀️ E4.0 woman: dark skin tone, blond hair
+1F471 1F3FF 200D 2640 ; minimally-qualified # 👱🏿‍♀ E4.0 woman: dark skin tone, blond hair
+1F471 200D 2642 FE0F ; fully-qualified # 👱‍♂️ E4.0 man: blond hair
+1F471 200D 2642 ; minimally-qualified # 👱‍♂ E4.0 man: blond hair
+1F471 1F3FB 200D 2642 FE0F ; fully-qualified # 👱🏻‍♂️ E4.0 man: light skin tone, blond hair
+1F471 1F3FB 200D 2642 ; minimally-qualified # 👱🏻‍♂ E4.0 man: light skin tone, blond hair
+1F471 1F3FC 200D 2642 FE0F ; fully-qualified # 👱🏼‍♂️ E4.0 man: medium-light skin tone, blond hair
+1F471 1F3FC 200D 2642 ; minimally-qualified # 👱🏼‍♂ E4.0 man: medium-light skin tone, blond hair
+1F471 1F3FD 200D 2642 FE0F ; fully-qualified # 👱🏽‍♂️ E4.0 man: medium skin tone, blond hair
+1F471 1F3FD 200D 2642 ; minimally-qualified # 👱🏽‍♂ E4.0 man: medium skin tone, blond hair
+1F471 1F3FE 200D 2642 FE0F ; fully-qualified # 👱🏾‍♂️ E4.0 man: medium-dark skin tone, blond hair
+1F471 1F3FE 200D 2642 ; minimally-qualified # 👱🏾‍♂ E4.0 man: medium-dark skin tone, blond hair
+1F471 1F3FF 200D 2642 FE0F ; fully-qualified # 👱🏿‍♂️ E4.0 man: dark skin tone, blond hair
+1F471 1F3FF 200D 2642 ; minimally-qualified # 👱🏿‍♂ E4.0 man: dark skin tone, blond hair
+1F9D3 ; fully-qualified # 🧓 E5.0 older person
+1F9D3 1F3FB ; fully-qualified # 🧓🏻 E5.0 older person: light skin tone
+1F9D3 1F3FC ; fully-qualified # 🧓🏼 E5.0 older person: medium-light skin tone
+1F9D3 1F3FD ; fully-qualified # 🧓🏽 E5.0 older person: medium skin tone
+1F9D3 1F3FE ; fully-qualified # 🧓🏾 E5.0 older person: medium-dark skin tone
+1F9D3 1F3FF ; fully-qualified # 🧓🏿 E5.0 older person: dark skin tone
+1F474 ; fully-qualified # 👴 E0.6 old man
+1F474 1F3FB ; fully-qualified # 👴🏻 E1.0 old man: light skin tone
+1F474 1F3FC ; fully-qualified # 👴🏼 E1.0 old man: medium-light skin tone
+1F474 1F3FD ; fully-qualified # 👴🏽 E1.0 old man: medium skin tone
+1F474 1F3FE ; fully-qualified # 👴🏾 E1.0 old man: medium-dark skin tone
+1F474 1F3FF ; fully-qualified # 👴🏿 E1.0 old man: dark skin tone
+1F475 ; fully-qualified # 👵 E0.6 old woman
+1F475 1F3FB ; fully-qualified # 👵🏻 E1.0 old woman: light skin tone
+1F475 1F3FC ; fully-qualified # 👵🏼 E1.0 old woman: medium-light skin tone
+1F475 1F3FD ; fully-qualified # 👵🏽 E1.0 old woman: medium skin tone
+1F475 1F3FE ; fully-qualified # 👵🏾 E1.0 old woman: medium-dark skin tone
+1F475 1F3FF ; fully-qualified # 👵🏿 E1.0 old woman: dark skin tone
+
+# subgroup: person-gesture
+1F64D ; fully-qualified # 🙍 E0.6 person frowning
+1F64D 1F3FB ; fully-qualified # 🙍🏻 E1.0 person frowning: light skin tone
+1F64D 1F3FC ; fully-qualified # 🙍🏼 E1.0 person frowning: medium-light skin tone
+1F64D 1F3FD ; fully-qualified # 🙍🏽 E1.0 person frowning: medium skin tone
+1F64D 1F3FE ; fully-qualified # 🙍🏾 E1.0 person frowning: medium-dark skin tone
+1F64D 1F3FF ; fully-qualified # 🙍🏿 E1.0 person frowning: dark skin tone
+1F64D 200D 2642 FE0F ; fully-qualified # 🙍‍♂️ E4.0 man frowning
+1F64D 200D 2642 ; minimally-qualified # 🙍‍♂ E4.0 man frowning
+1F64D 1F3FB 200D 2642 FE0F ; fully-qualified # 🙍🏻‍♂️ E4.0 man frowning: light skin tone
+1F64D 1F3FB 200D 2642 ; minimally-qualified # 🙍🏻‍♂ E4.0 man frowning: light skin tone
+1F64D 1F3FC 200D 2642 FE0F ; fully-qualified # 🙍🏼‍♂️ E4.0 man frowning: medium-light skin tone
+1F64D 1F3FC 200D 2642 ; minimally-qualified # 🙍🏼‍♂ E4.0 man frowning: medium-light skin tone
+1F64D 1F3FD 200D 2642 FE0F ; fully-qualified # 🙍🏽‍♂️ E4.0 man frowning: medium skin tone
+1F64D 1F3FD 200D 2642 ; minimally-qualified # 🙍🏽‍♂ E4.0 man frowning: medium skin tone
+1F64D 1F3FE 200D 2642 FE0F ; fully-qualified # 🙍🏾‍♂️ E4.0 man frowning: medium-dark skin tone
+1F64D 1F3FE 200D 2642 ; minimally-qualified # 🙍🏾‍♂ E4.0 man frowning: medium-dark skin tone
+1F64D 1F3FF 200D 2642 FE0F ; fully-qualified # 🙍🏿‍♂️ E4.0 man frowning: dark skin tone
+1F64D 1F3FF 200D 2642 ; minimally-qualified # 🙍🏿‍♂ E4.0 man frowning: dark skin tone
+1F64D 200D 2640 FE0F ; fully-qualified # 🙍‍♀️ E4.0 woman frowning
+1F64D 200D 2640 ; minimally-qualified # 🙍‍♀ E4.0 woman frowning
+1F64D 1F3FB 200D 2640 FE0F ; fully-qualified # 🙍🏻‍♀️ E4.0 woman frowning: light skin tone
+1F64D 1F3FB 200D 2640 ; minimally-qualified # 🙍🏻‍♀ E4.0 woman frowning: light skin tone
+1F64D 1F3FC 200D 2640 FE0F ; fully-qualified # 🙍🏼‍♀️ E4.0 woman frowning: medium-light skin tone
+1F64D 1F3FC 200D 2640 ; minimally-qualified # 🙍🏼‍♀ E4.0 woman frowning: medium-light skin tone
+1F64D 1F3FD 200D 2640 FE0F ; fully-qualified # 🙍🏽‍♀️ E4.0 woman frowning: medium skin tone
+1F64D 1F3FD 200D 2640 ; minimally-qualified # 🙍🏽‍♀ E4.0 woman frowning: medium skin tone
+1F64D 1F3FE 200D 2640 FE0F ; fully-qualified # 🙍🏾‍♀️ E4.0 woman frowning: medium-dark skin tone
+1F64D 1F3FE 200D 2640 ; minimally-qualified # 🙍🏾‍♀ E4.0 woman frowning: medium-dark skin tone
+1F64D 1F3FF 200D 2640 FE0F ; fully-qualified # 🙍🏿‍♀️ E4.0 woman frowning: dark skin tone
+1F64D 1F3FF 200D 2640 ; minimally-qualified # 🙍🏿‍♀ E4.0 woman frowning: dark skin tone
+1F64E ; fully-qualified # 🙎 E0.6 person pouting
+1F64E 1F3FB ; fully-qualified # 🙎🏻 E1.0 person pouting: light skin tone
+1F64E 1F3FC ; fully-qualified # 🙎🏼 E1.0 person pouting: medium-light skin tone
+1F64E 1F3FD ; fully-qualified # 🙎🏽 E1.0 person pouting: medium skin tone
+1F64E 1F3FE ; fully-qualified # 🙎🏾 E1.0 person pouting: medium-dark skin tone
+1F64E 1F3FF ; fully-qualified # 🙎🏿 E1.0 person pouting: dark skin tone
+1F64E 200D 2642 FE0F ; fully-qualified # 🙎‍♂️ E4.0 man pouting
+1F64E 200D 2642 ; minimally-qualified # 🙎‍♂ E4.0 man pouting
+1F64E 1F3FB 200D 2642 FE0F ; fully-qualified # 🙎🏻‍♂️ E4.0 man pouting: light skin tone
+1F64E 1F3FB 200D 2642 ; minimally-qualified # 🙎🏻‍♂ E4.0 man pouting: light skin tone
+1F64E 1F3FC 200D 2642 FE0F ; fully-qualified # 🙎🏼‍♂️ E4.0 man pouting: medium-light skin tone
+1F64E 1F3FC 200D 2642 ; minimally-qualified # 🙎🏼‍♂ E4.0 man pouting: medium-light skin tone
+1F64E 1F3FD 200D 2642 FE0F ; fully-qualified # 🙎🏽‍♂️ E4.0 man pouting: medium skin tone
+1F64E 1F3FD 200D 2642 ; minimally-qualified # 🙎🏽‍♂ E4.0 man pouting: medium skin tone
+1F64E 1F3FE 200D 2642 FE0F ; fully-qualified # 🙎🏾‍♂️ E4.0 man pouting: medium-dark skin tone
+1F64E 1F3FE 200D 2642 ; minimally-qualified # 🙎🏾‍♂ E4.0 man pouting: medium-dark skin tone
+1F64E 1F3FF 200D 2642 FE0F ; fully-qualified # 🙎🏿‍♂️ E4.0 man pouting: dark skin tone
+1F64E 1F3FF 200D 2642 ; minimally-qualified # 🙎🏿‍♂ E4.0 man pouting: dark skin tone
+1F64E 200D 2640 FE0F ; fully-qualified # 🙎‍♀️ E4.0 woman pouting
+1F64E 200D 2640 ; minimally-qualified # 🙎‍♀ E4.0 woman pouting
+1F64E 1F3FB 200D 2640 FE0F ; fully-qualified # 🙎🏻‍♀️ E4.0 woman pouting: light skin tone
+1F64E 1F3FB 200D 2640 ; minimally-qualified # 🙎🏻‍♀ E4.0 woman pouting: light skin tone
+1F64E 1F3FC 200D 2640 FE0F ; fully-qualified # 🙎🏼‍♀️ E4.0 woman pouting: medium-light skin tone
+1F64E 1F3FC 200D 2640 ; minimally-qualified # 🙎🏼‍♀ E4.0 woman pouting: medium-light skin tone
+1F64E 1F3FD 200D 2640 FE0F ; fully-qualified # 🙎🏽‍♀️ E4.0 woman pouting: medium skin tone
+1F64E 1F3FD 200D 2640 ; minimally-qualified # 🙎🏽‍♀ E4.0 woman pouting: medium skin tone
+1F64E 1F3FE 200D 2640 FE0F ; fully-qualified # 🙎🏾‍♀️ E4.0 woman pouting: medium-dark skin tone
+1F64E 1F3FE 200D 2640 ; minimally-qualified # 🙎🏾‍♀ E4.0 woman pouting: medium-dark skin tone
+1F64E 1F3FF 200D 2640 FE0F ; fully-qualified # 🙎🏿‍♀️ E4.0 woman pouting: dark skin tone
+1F64E 1F3FF 200D 2640 ; minimally-qualified # 🙎🏿‍♀ E4.0 woman pouting: dark skin tone
+1F645 ; fully-qualified # 🙅 E0.6 person gesturing NO
+1F645 1F3FB ; fully-qualified # 🙅🏻 E1.0 person gesturing NO: light skin tone
+1F645 1F3FC ; fully-qualified # 🙅🏼 E1.0 person gesturing NO: medium-light skin tone
+1F645 1F3FD ; fully-qualified # 🙅🏽 E1.0 person gesturing NO: medium skin tone
+1F645 1F3FE ; fully-qualified # 🙅🏾 E1.0 person gesturing NO: medium-dark skin tone
+1F645 1F3FF ; fully-qualified # 🙅🏿 E1.0 person gesturing NO: dark skin tone
+1F645 200D 2642 FE0F ; fully-qualified # 🙅‍♂️ E4.0 man gesturing NO
+1F645 200D 2642 ; minimally-qualified # 🙅‍♂ E4.0 man gesturing NO
+1F645 1F3FB 200D 2642 FE0F ; fully-qualified # 🙅🏻‍♂️ E4.0 man gesturing NO: light skin tone
+1F645 1F3FB 200D 2642 ; minimally-qualified # 🙅🏻‍♂ E4.0 man gesturing NO: light skin tone
+1F645 1F3FC 200D 2642 FE0F ; fully-qualified # 🙅🏼‍♂️ E4.0 man gesturing NO: medium-light skin tone
+1F645 1F3FC 200D 2642 ; minimally-qualified # 🙅🏼‍♂ E4.0 man gesturing NO: medium-light skin tone
+1F645 1F3FD 200D 2642 FE0F ; fully-qualified # 🙅🏽‍♂️ E4.0 man gesturing NO: medium skin tone
+1F645 1F3FD 200D 2642 ; minimally-qualified # 🙅🏽‍♂ E4.0 man gesturing NO: medium skin tone
+1F645 1F3FE 200D 2642 FE0F ; fully-qualified # 🙅🏾‍♂️ E4.0 man gesturing NO: medium-dark skin tone
+1F645 1F3FE 200D 2642 ; minimally-qualified # 🙅🏾‍♂ E4.0 man gesturing NO: medium-dark skin tone
+1F645 1F3FF 200D 2642 FE0F ; fully-qualified # 🙅🏿‍♂️ E4.0 man gesturing NO: dark skin tone
+1F645 1F3FF 200D 2642 ; minimally-qualified # 🙅🏿‍♂ E4.0 man gesturing NO: dark skin tone
+1F645 200D 2640 FE0F ; fully-qualified # 🙅‍♀️ E4.0 woman gesturing NO
+1F645 200D 2640 ; minimally-qualified # 🙅‍♀ E4.0 woman gesturing NO
+1F645 1F3FB 200D 2640 FE0F ; fully-qualified # 🙅🏻‍♀️ E4.0 woman gesturing NO: light skin tone
+1F645 1F3FB 200D 2640 ; minimally-qualified # 🙅🏻‍♀ E4.0 woman gesturing NO: light skin tone
+1F645 1F3FC 200D 2640 FE0F ; fully-qualified # 🙅🏼‍♀️ E4.0 woman gesturing NO: medium-light skin tone
+1F645 1F3FC 200D 2640 ; minimally-qualified # 🙅🏼‍♀ E4.0 woman gesturing NO: medium-light skin tone
+1F645 1F3FD 200D 2640 FE0F ; fully-qualified # 🙅🏽‍♀️ E4.0 woman gesturing NO: medium skin tone
+1F645 1F3FD 200D 2640 ; minimally-qualified # 🙅🏽‍♀ E4.0 woman gesturing NO: medium skin tone
+1F645 1F3FE 200D 2640 FE0F ; fully-qualified # 🙅🏾‍♀️ E4.0 woman gesturing NO: medium-dark skin tone
+1F645 1F3FE 200D 2640 ; minimally-qualified # 🙅🏾‍♀ E4.0 woman gesturing NO: medium-dark skin tone
+1F645 1F3FF 200D 2640 FE0F ; fully-qualified # 🙅🏿‍♀️ E4.0 woman gesturing NO: dark skin tone
+1F645 1F3FF 200D 2640 ; minimally-qualified # 🙅🏿‍♀ E4.0 woman gesturing NO: dark skin tone
+1F646 ; fully-qualified # 🙆 E0.6 person gesturing OK
+1F646 1F3FB ; fully-qualified # 🙆🏻 E1.0 person gesturing OK: light skin tone
+1F646 1F3FC ; fully-qualified # 🙆🏼 E1.0 person gesturing OK: medium-light skin tone
+1F646 1F3FD ; fully-qualified # 🙆🏽 E1.0 person gesturing OK: medium skin tone
+1F646 1F3FE ; fully-qualified # 🙆🏾 E1.0 person gesturing OK: medium-dark skin tone
+1F646 1F3FF ; fully-qualified # 🙆🏿 E1.0 person gesturing OK: dark skin tone
+1F646 200D 2642 FE0F ; fully-qualified # 🙆‍♂️ E4.0 man gesturing OK
+1F646 200D 2642 ; minimally-qualified # 🙆‍♂ E4.0 man gesturing OK
+1F646 1F3FB 200D 2642 FE0F ; fully-qualified # 🙆🏻‍♂️ E4.0 man gesturing OK: light skin tone
+1F646 1F3FB 200D 2642 ; minimally-qualified # 🙆🏻‍♂ E4.0 man gesturing OK: light skin tone
+1F646 1F3FC 200D 2642 FE0F ; fully-qualified # 🙆🏼‍♂️ E4.0 man gesturing OK: medium-light skin tone
+1F646 1F3FC 200D 2642 ; minimally-qualified # 🙆🏼‍♂ E4.0 man gesturing OK: medium-light skin tone
+1F646 1F3FD 200D 2642 FE0F ; fully-qualified # 🙆🏽‍♂️ E4.0 man gesturing OK: medium skin tone
+1F646 1F3FD 200D 2642 ; minimally-qualified # 🙆🏽‍♂ E4.0 man gesturing OK: medium skin tone
+1F646 1F3FE 200D 2642 FE0F ; fully-qualified # 🙆🏾‍♂️ E4.0 man gesturing OK: medium-dark skin tone
+1F646 1F3FE 200D 2642 ; minimally-qualified # 🙆🏾‍♂ E4.0 man gesturing OK: medium-dark skin tone
+1F646 1F3FF 200D 2642 FE0F ; fully-qualified # 🙆🏿‍♂️ E4.0 man gesturing OK: dark skin tone
+1F646 1F3FF 200D 2642 ; minimally-qualified # 🙆🏿‍♂ E4.0 man gesturing OK: dark skin tone
+1F646 200D 2640 FE0F ; fully-qualified # 🙆‍♀️ E4.0 woman gesturing OK
+1F646 200D 2640 ; minimally-qualified # 🙆‍♀ E4.0 woman gesturing OK
+1F646 1F3FB 200D 2640 FE0F ; fully-qualified # 🙆🏻‍♀️ E4.0 woman gesturing OK: light skin tone
+1F646 1F3FB 200D 2640 ; minimally-qualified # 🙆🏻‍♀ E4.0 woman gesturing OK: light skin tone
+1F646 1F3FC 200D 2640 FE0F ; fully-qualified # 🙆🏼‍♀️ E4.0 woman gesturing OK: medium-light skin tone
+1F646 1F3FC 200D 2640 ; minimally-qualified # 🙆🏼‍♀ E4.0 woman gesturing OK: medium-light skin tone
+1F646 1F3FD 200D 2640 FE0F ; fully-qualified # 🙆🏽‍♀️ E4.0 woman gesturing OK: medium skin tone
+1F646 1F3FD 200D 2640 ; minimally-qualified # 🙆🏽‍♀ E4.0 woman gesturing OK: medium skin tone
+1F646 1F3FE 200D 2640 FE0F ; fully-qualified # 🙆🏾‍♀️ E4.0 woman gesturing OK: medium-dark skin tone
+1F646 1F3FE 200D 2640 ; minimally-qualified # 🙆🏾‍♀ E4.0 woman gesturing OK: medium-dark skin tone
+1F646 1F3FF 200D 2640 FE0F ; fully-qualified # 🙆🏿‍♀️ E4.0 woman gesturing OK: dark skin tone
+1F646 1F3FF 200D 2640 ; minimally-qualified # 🙆🏿‍♀ E4.0 woman gesturing OK: dark skin tone
+1F481 ; fully-qualified # 💁 E0.6 person tipping hand
+1F481 1F3FB ; fully-qualified # 💁🏻 E1.0 person tipping hand: light skin tone
+1F481 1F3FC ; fully-qualified # 💁🏼 E1.0 person tipping hand: medium-light skin tone
+1F481 1F3FD ; fully-qualified # 💁🏽 E1.0 person tipping hand: medium skin tone
+1F481 1F3FE ; fully-qualified # 💁🏾 E1.0 person tipping hand: medium-dark skin tone
+1F481 1F3FF ; fully-qualified # 💁🏿 E1.0 person tipping hand: dark skin tone
+1F481 200D 2642 FE0F ; fully-qualified # 💁‍♂️ E4.0 man tipping hand
+1F481 200D 2642 ; minimally-qualified # 💁‍♂ E4.0 man tipping hand
+1F481 1F3FB 200D 2642 FE0F ; fully-qualified # 💁🏻‍♂️ E4.0 man tipping hand: light skin tone
+1F481 1F3FB 200D 2642 ; minimally-qualified # 💁🏻‍♂ E4.0 man tipping hand: light skin tone
+1F481 1F3FC 200D 2642 FE0F ; fully-qualified # 💁🏼‍♂️ E4.0 man tipping hand: medium-light skin tone
+1F481 1F3FC 200D 2642 ; minimally-qualified # 💁🏼‍♂ E4.0 man tipping hand: medium-light skin tone
+1F481 1F3FD 200D 2642 FE0F ; fully-qualified # 💁🏽‍♂️ E4.0 man tipping hand: medium skin tone
+1F481 1F3FD 200D 2642 ; minimally-qualified # 💁🏽‍♂ E4.0 man tipping hand: medium skin tone
+1F481 1F3FE 200D 2642 FE0F ; fully-qualified # 💁🏾‍♂️ E4.0 man tipping hand: medium-dark skin tone
+1F481 1F3FE 200D 2642 ; minimally-qualified # 💁🏾‍♂ E4.0 man tipping hand: medium-dark skin tone
+1F481 1F3FF 200D 2642 FE0F ; fully-qualified # 💁🏿‍♂️ E4.0 man tipping hand: dark skin tone
+1F481 1F3FF 200D 2642 ; minimally-qualified # 💁🏿‍♂ E4.0 man tipping hand: dark skin tone
+1F481 200D 2640 FE0F ; fully-qualified # 💁‍♀️ E4.0 woman tipping hand
+1F481 200D 2640 ; minimally-qualified # 💁‍♀ E4.0 woman tipping hand
+1F481 1F3FB 200D 2640 FE0F ; fully-qualified # 💁🏻‍♀️ E4.0 woman tipping hand: light skin tone
+1F481 1F3FB 200D 2640 ; minimally-qualified # 💁🏻‍♀ E4.0 woman tipping hand: light skin tone
+1F481 1F3FC 200D 2640 FE0F ; fully-qualified # 💁🏼‍♀️ E4.0 woman tipping hand: medium-light skin tone
+1F481 1F3FC 200D 2640 ; minimally-qualified # 💁🏼‍♀ E4.0 woman tipping hand: medium-light skin tone
+1F481 1F3FD 200D 2640 FE0F ; fully-qualified # 💁🏽‍♀️ E4.0 woman tipping hand: medium skin tone
+1F481 1F3FD 200D 2640 ; minimally-qualified # 💁🏽‍♀ E4.0 woman tipping hand: medium skin tone
+1F481 1F3FE 200D 2640 FE0F ; fully-qualified # 💁🏾‍♀️ E4.0 woman tipping hand: medium-dark skin tone
+1F481 1F3FE 200D 2640 ; minimally-qualified # 💁🏾‍♀ E4.0 woman tipping hand: medium-dark skin tone
+1F481 1F3FF 200D 2640 FE0F ; fully-qualified # 💁🏿‍♀️ E4.0 woman tipping hand: dark skin tone
+1F481 1F3FF 200D 2640 ; minimally-qualified # 💁🏿‍♀ E4.0 woman tipping hand: dark skin tone
+1F64B ; fully-qualified # 🙋 E0.6 person raising hand
+1F64B 1F3FB ; fully-qualified # 🙋🏻 E1.0 person raising hand: light skin tone
+1F64B 1F3FC ; fully-qualified # 🙋🏼 E1.0 person raising hand: medium-light skin tone
+1F64B 1F3FD ; fully-qualified # 🙋🏽 E1.0 person raising hand: medium skin tone
+1F64B 1F3FE ; fully-qualified # 🙋🏾 E1.0 person raising hand: medium-dark skin tone
+1F64B 1F3FF ; fully-qualified # 🙋🏿 E1.0 person raising hand: dark skin tone
+1F64B 200D 2642 FE0F ; fully-qualified # 🙋‍♂️ E4.0 man raising hand
+1F64B 200D 2642 ; minimally-qualified # 🙋‍♂ E4.0 man raising hand
+1F64B 1F3FB 200D 2642 FE0F ; fully-qualified # 🙋🏻‍♂️ E4.0 man raising hand: light skin tone
+1F64B 1F3FB 200D 2642 ; minimally-qualified # 🙋🏻‍♂ E4.0 man raising hand: light skin tone
+1F64B 1F3FC 200D 2642 FE0F ; fully-qualified # 🙋🏼‍♂️ E4.0 man raising hand: medium-light skin tone
+1F64B 1F3FC 200D 2642 ; minimally-qualified # 🙋🏼‍♂ E4.0 man raising hand: medium-light skin tone
+1F64B 1F3FD 200D 2642 FE0F ; fully-qualified # 🙋🏽‍♂️ E4.0 man raising hand: medium skin tone
+1F64B 1F3FD 200D 2642 ; minimally-qualified # 🙋🏽‍♂ E4.0 man raising hand: medium skin tone
+1F64B 1F3FE 200D 2642 FE0F ; fully-qualified # 🙋🏾‍♂️ E4.0 man raising hand: medium-dark skin tone
+1F64B 1F3FE 200D 2642 ; minimally-qualified # 🙋🏾‍♂ E4.0 man raising hand: medium-dark skin tone
+1F64B 1F3FF 200D 2642 FE0F ; fully-qualified # 🙋🏿‍♂️ E4.0 man raising hand: dark skin tone
+1F64B 1F3FF 200D 2642 ; minimally-qualified # 🙋🏿‍♂ E4.0 man raising hand: dark skin tone
+1F64B 200D 2640 FE0F ; fully-qualified # 🙋‍♀️ E4.0 woman raising hand
+1F64B 200D 2640 ; minimally-qualified # 🙋‍♀ E4.0 woman raising hand
+1F64B 1F3FB 200D 2640 FE0F ; fully-qualified # 🙋🏻‍♀️ E4.0 woman raising hand: light skin tone
+1F64B 1F3FB 200D 2640 ; minimally-qualified # 🙋🏻‍♀ E4.0 woman raising hand: light skin tone
+1F64B 1F3FC 200D 2640 FE0F ; fully-qualified # 🙋🏼‍♀️ E4.0 woman raising hand: medium-light skin tone
+1F64B 1F3FC 200D 2640 ; minimally-qualified # 🙋🏼‍♀ E4.0 woman raising hand: medium-light skin tone
+1F64B 1F3FD 200D 2640 FE0F ; fully-qualified # 🙋🏽‍♀️ E4.0 woman raising hand: medium skin tone
+1F64B 1F3FD 200D 2640 ; minimally-qualified # 🙋🏽‍♀ E4.0 woman raising hand: medium skin tone
+1F64B 1F3FE 200D 2640 FE0F ; fully-qualified # 🙋🏾‍♀️ E4.0 woman raising hand: medium-dark skin tone
+1F64B 1F3FE 200D 2640 ; minimally-qualified # 🙋🏾‍♀ E4.0 woman raising hand: medium-dark skin tone
+1F64B 1F3FF 200D 2640 FE0F ; fully-qualified # 🙋🏿‍♀️ E4.0 woman raising hand: dark skin tone
+1F64B 1F3FF 200D 2640 ; minimally-qualified # 🙋🏿‍♀ E4.0 woman raising hand: dark skin tone
+1F9CF ; fully-qualified # 🧏 E12.0 deaf person
+1F9CF 1F3FB ; fully-qualified # 🧏🏻 E12.0 deaf person: light skin tone
+1F9CF 1F3FC ; fully-qualified # 🧏🏼 E12.0 deaf person: medium-light skin tone
+1F9CF 1F3FD ; fully-qualified # 🧏🏽 E12.0 deaf person: medium skin tone
+1F9CF 1F3FE ; fully-qualified # 🧏🏾 E12.0 deaf person: medium-dark skin tone
+1F9CF 1F3FF ; fully-qualified # 🧏🏿 E12.0 deaf person: dark skin tone
+1F9CF 200D 2642 FE0F ; fully-qualified # 🧏‍♂️ E12.0 deaf man
+1F9CF 200D 2642 ; minimally-qualified # 🧏‍♂ E12.0 deaf man
+1F9CF 1F3FB 200D 2642 FE0F ; fully-qualified # 🧏🏻‍♂️ E12.0 deaf man: light skin tone
+1F9CF 1F3FB 200D 2642 ; minimally-qualified # 🧏🏻‍♂ E12.0 deaf man: light skin tone
+1F9CF 1F3FC 200D 2642 FE0F ; fully-qualified # 🧏🏼‍♂️ E12.0 deaf man: medium-light skin tone
+1F9CF 1F3FC 200D 2642 ; minimally-qualified # 🧏🏼‍♂ E12.0 deaf man: medium-light skin tone
+1F9CF 1F3FD 200D 2642 FE0F ; fully-qualified # 🧏🏽‍♂️ E12.0 deaf man: medium skin tone
+1F9CF 1F3FD 200D 2642 ; minimally-qualified # 🧏🏽‍♂ E12.0 deaf man: medium skin tone
+1F9CF 1F3FE 200D 2642 FE0F ; fully-qualified # 🧏🏾‍♂️ E12.0 deaf man: medium-dark skin tone
+1F9CF 1F3FE 200D 2642 ; minimally-qualified # 🧏🏾‍♂ E12.0 deaf man: medium-dark skin tone
+1F9CF 1F3FF 200D 2642 FE0F ; fully-qualified # 🧏🏿‍♂️ E12.0 deaf man: dark skin tone
+1F9CF 1F3FF 200D 2642 ; minimally-qualified # 🧏🏿‍♂ E12.0 deaf man: dark skin tone
+1F9CF 200D 2640 FE0F ; fully-qualified # 🧏‍♀️ E12.0 deaf woman
+1F9CF 200D 2640 ; minimally-qualified # 🧏‍♀ E12.0 deaf woman
+1F9CF 1F3FB 200D 2640 FE0F ; fully-qualified # 🧏🏻‍♀️ E12.0 deaf woman: light skin tone
+1F9CF 1F3FB 200D 2640 ; minimally-qualified # 🧏🏻‍♀ E12.0 deaf woman: light skin tone
+1F9CF 1F3FC 200D 2640 FE0F ; fully-qualified # 🧏🏼‍♀️ E12.0 deaf woman: medium-light skin tone
+1F9CF 1F3FC 200D 2640 ; minimally-qualified # 🧏🏼‍♀ E12.0 deaf woman: medium-light skin tone
+1F9CF 1F3FD 200D 2640 FE0F ; fully-qualified # 🧏🏽‍♀️ E12.0 deaf woman: medium skin tone
+1F9CF 1F3FD 200D 2640 ; minimally-qualified # 🧏🏽‍♀ E12.0 deaf woman: medium skin tone
+1F9CF 1F3FE 200D 2640 FE0F ; fully-qualified # 🧏🏾‍♀️ E12.0 deaf woman: medium-dark skin tone
+1F9CF 1F3FE 200D 2640 ; minimally-qualified # 🧏🏾‍♀ E12.0 deaf woman: medium-dark skin tone
+1F9CF 1F3FF 200D 2640 FE0F ; fully-qualified # 🧏🏿‍♀️ E12.0 deaf woman: dark skin tone
+1F9CF 1F3FF 200D 2640 ; minimally-qualified # 🧏🏿‍♀ E12.0 deaf woman: dark skin tone
+1F647 ; fully-qualified # 🙇 E0.6 person bowing
+1F647 1F3FB ; fully-qualified # 🙇🏻 E1.0 person bowing: light skin tone
+1F647 1F3FC ; fully-qualified # 🙇🏼 E1.0 person bowing: medium-light skin tone
+1F647 1F3FD ; fully-qualified # 🙇🏽 E1.0 person bowing: medium skin tone
+1F647 1F3FE ; fully-qualified # 🙇🏾 E1.0 person bowing: medium-dark skin tone
+1F647 1F3FF ; fully-qualified # 🙇🏿 E1.0 person bowing: dark skin tone
+1F647 200D 2642 FE0F ; fully-qualified # 🙇‍♂️ E4.0 man bowing
+1F647 200D 2642 ; minimally-qualified # 🙇‍♂ E4.0 man bowing
+1F647 1F3FB 200D 2642 FE0F ; fully-qualified # 🙇🏻‍♂️ E4.0 man bowing: light skin tone
+1F647 1F3FB 200D 2642 ; minimally-qualified # 🙇🏻‍♂ E4.0 man bowing: light skin tone
+1F647 1F3FC 200D 2642 FE0F ; fully-qualified # 🙇🏼‍♂️ E4.0 man bowing: medium-light skin tone
+1F647 1F3FC 200D 2642 ; minimally-qualified # 🙇🏼‍♂ E4.0 man bowing: medium-light skin tone
+1F647 1F3FD 200D 2642 FE0F ; fully-qualified # 🙇🏽‍♂️ E4.0 man bowing: medium skin tone
+1F647 1F3FD 200D 2642 ; minimally-qualified # 🙇🏽‍♂ E4.0 man bowing: medium skin tone
+1F647 1F3FE 200D 2642 FE0F ; fully-qualified # 🙇🏾‍♂️ E4.0 man bowing: medium-dark skin tone
+1F647 1F3FE 200D 2642 ; minimally-qualified # 🙇🏾‍♂ E4.0 man bowing: medium-dark skin tone
+1F647 1F3FF 200D 2642 FE0F ; fully-qualified # 🙇🏿‍♂️ E4.0 man bowing: dark skin tone
+1F647 1F3FF 200D 2642 ; minimally-qualified # 🙇🏿‍♂ E4.0 man bowing: dark skin tone
+1F647 200D 2640 FE0F ; fully-qualified # 🙇‍♀️ E4.0 woman bowing
+1F647 200D 2640 ; minimally-qualified # 🙇‍♀ E4.0 woman bowing
+1F647 1F3FB 200D 2640 FE0F ; fully-qualified # 🙇🏻‍♀️ E4.0 woman bowing: light skin tone
+1F647 1F3FB 200D 2640 ; minimally-qualified # 🙇🏻‍♀ E4.0 woman bowing: light skin tone
+1F647 1F3FC 200D 2640 FE0F ; fully-qualified # 🙇🏼‍♀️ E4.0 woman bowing: medium-light skin tone
+1F647 1F3FC 200D 2640 ; minimally-qualified # 🙇🏼‍♀ E4.0 woman bowing: medium-light skin tone
+1F647 1F3FD 200D 2640 FE0F ; fully-qualified # 🙇🏽‍♀️ E4.0 woman bowing: medium skin tone
+1F647 1F3FD 200D 2640 ; minimally-qualified # 🙇🏽‍♀ E4.0 woman bowing: medium skin tone
+1F647 1F3FE 200D 2640 FE0F ; fully-qualified # 🙇🏾‍♀️ E4.0 woman bowing: medium-dark skin tone
+1F647 1F3FE 200D 2640 ; minimally-qualified # 🙇🏾‍♀ E4.0 woman bowing: medium-dark skin tone
+1F647 1F3FF 200D 2640 FE0F ; fully-qualified # 🙇🏿‍♀️ E4.0 woman bowing: dark skin tone
+1F647 1F3FF 200D 2640 ; minimally-qualified # 🙇🏿‍♀ E4.0 woman bowing: dark skin tone
+1F926 ; fully-qualified # 🤦 E3.0 person facepalming
+1F926 1F3FB ; fully-qualified # 🤦🏻 E3.0 person facepalming: light skin tone
+1F926 1F3FC ; fully-qualified # 🤦🏼 E3.0 person facepalming: medium-light skin tone
+1F926 1F3FD ; fully-qualified # 🤦🏽 E3.0 person facepalming: medium skin tone
+1F926 1F3FE ; fully-qualified # 🤦🏾 E3.0 person facepalming: medium-dark skin tone
+1F926 1F3FF ; fully-qualified # 🤦🏿 E3.0 person facepalming: dark skin tone
+1F926 200D 2642 FE0F ; fully-qualified # 🤦‍♂️ E4.0 man facepalming
+1F926 200D 2642 ; minimally-qualified # 🤦‍♂ E4.0 man facepalming
+1F926 1F3FB 200D 2642 FE0F ; fully-qualified # 🤦🏻‍♂️ E4.0 man facepalming: light skin tone
+1F926 1F3FB 200D 2642 ; minimally-qualified # 🤦🏻‍♂ E4.0 man facepalming: light skin tone
+1F926 1F3FC 200D 2642 FE0F ; fully-qualified # 🤦🏼‍♂️ E4.0 man facepalming: medium-light skin tone
+1F926 1F3FC 200D 2642 ; minimally-qualified # 🤦🏼‍♂ E4.0 man facepalming: medium-light skin tone
+1F926 1F3FD 200D 2642 FE0F ; fully-qualified # 🤦🏽‍♂️ E4.0 man facepalming: medium skin tone
+1F926 1F3FD 200D 2642 ; minimally-qualified # 🤦🏽‍♂ E4.0 man facepalming: medium skin tone
+1F926 1F3FE 200D 2642 FE0F ; fully-qualified # 🤦🏾‍♂️ E4.0 man facepalming: medium-dark skin tone
+1F926 1F3FE 200D 2642 ; minimally-qualified # 🤦🏾‍♂ E4.0 man facepalming: medium-dark skin tone
+1F926 1F3FF 200D 2642 FE0F ; fully-qualified # 🤦🏿‍♂️ E4.0 man facepalming: dark skin tone
+1F926 1F3FF 200D 2642 ; minimally-qualified # 🤦🏿‍♂ E4.0 man facepalming: dark skin tone
+1F926 200D 2640 FE0F ; fully-qualified # 🤦‍♀️ E4.0 woman facepalming
+1F926 200D 2640 ; minimally-qualified # 🤦‍♀ E4.0 woman facepalming
+1F926 1F3FB 200D 2640 FE0F ; fully-qualified # 🤦🏻‍♀️ E4.0 woman facepalming: light skin tone
+1F926 1F3FB 200D 2640 ; minimally-qualified # 🤦🏻‍♀ E4.0 woman facepalming: light skin tone
+1F926 1F3FC 200D 2640 FE0F ; fully-qualified # 🤦🏼‍♀️ E4.0 woman facepalming: medium-light skin tone
+1F926 1F3FC 200D 2640 ; minimally-qualified # 🤦🏼‍♀ E4.0 woman facepalming: medium-light skin tone
+1F926 1F3FD 200D 2640 FE0F ; fully-qualified # 🤦🏽‍♀️ E4.0 woman facepalming: medium skin tone
+1F926 1F3FD 200D 2640 ; minimally-qualified # 🤦🏽‍♀ E4.0 woman facepalming: medium skin tone
+1F926 1F3FE 200D 2640 FE0F ; fully-qualified # 🤦🏾‍♀️ E4.0 woman facepalming: medium-dark skin tone
+1F926 1F3FE 200D 2640 ; minimally-qualified # 🤦🏾‍♀ E4.0 woman facepalming: medium-dark skin tone
+1F926 1F3FF 200D 2640 FE0F ; fully-qualified # 🤦🏿‍♀️ E4.0 woman facepalming: dark skin tone
+1F926 1F3FF 200D 2640 ; minimally-qualified # 🤦🏿‍♀ E4.0 woman facepalming: dark skin tone
+1F937 ; fully-qualified # 🤷 E3.0 person shrugging
+1F937 1F3FB ; fully-qualified # 🤷🏻 E3.0 person shrugging: light skin tone
+1F937 1F3FC ; fully-qualified # 🤷🏼 E3.0 person shrugging: medium-light skin tone
+1F937 1F3FD ; fully-qualified # 🤷🏽 E3.0 person shrugging: medium skin tone
+1F937 1F3FE ; fully-qualified # 🤷🏾 E3.0 person shrugging: medium-dark skin tone
+1F937 1F3FF ; fully-qualified # 🤷🏿 E3.0 person shrugging: dark skin tone
+1F937 200D 2642 FE0F ; fully-qualified # 🤷‍♂️ E4.0 man shrugging
+1F937 200D 2642 ; minimally-qualified # 🤷‍♂ E4.0 man shrugging
+1F937 1F3FB 200D 2642 FE0F ; fully-qualified # 🤷🏻‍♂️ E4.0 man shrugging: light skin tone
+1F937 1F3FB 200D 2642 ; minimally-qualified # 🤷🏻‍♂ E4.0 man shrugging: light skin tone
+1F937 1F3FC 200D 2642 FE0F ; fully-qualified # 🤷🏼‍♂️ E4.0 man shrugging: medium-light skin tone
+1F937 1F3FC 200D 2642 ; minimally-qualified # 🤷🏼‍♂ E4.0 man shrugging: medium-light skin tone
+1F937 1F3FD 200D 2642 FE0F ; fully-qualified # 🤷🏽‍♂️ E4.0 man shrugging: medium skin tone
+1F937 1F3FD 200D 2642 ; minimally-qualified # 🤷🏽‍♂ E4.0 man shrugging: medium skin tone
+1F937 1F3FE 200D 2642 FE0F ; fully-qualified # 🤷🏾‍♂️ E4.0 man shrugging: medium-dark skin tone
+1F937 1F3FE 200D 2642 ; minimally-qualified # 🤷🏾‍♂ E4.0 man shrugging: medium-dark skin tone
+1F937 1F3FF 200D 2642 FE0F ; fully-qualified # 🤷🏿‍♂️ E4.0 man shrugging: dark skin tone
+1F937 1F3FF 200D 2642 ; minimally-qualified # 🤷🏿‍♂ E4.0 man shrugging: dark skin tone
+1F937 200D 2640 FE0F ; fully-qualified # 🤷‍♀️ E4.0 woman shrugging
+1F937 200D 2640 ; minimally-qualified # 🤷‍♀ E4.0 woman shrugging
+1F937 1F3FB 200D 2640 FE0F ; fully-qualified # 🤷🏻‍♀️ E4.0 woman shrugging: light skin tone
+1F937 1F3FB 200D 2640 ; minimally-qualified # 🤷🏻‍♀ E4.0 woman shrugging: light skin tone
+1F937 1F3FC 200D 2640 FE0F ; fully-qualified # 🤷🏼‍♀️ E4.0 woman shrugging: medium-light skin tone
+1F937 1F3FC 200D 2640 ; minimally-qualified # 🤷🏼‍♀ E4.0 woman shrugging: medium-light skin tone
+1F937 1F3FD 200D 2640 FE0F ; fully-qualified # 🤷🏽‍♀️ E4.0 woman shrugging: medium skin tone
+1F937 1F3FD 200D 2640 ; minimally-qualified # 🤷🏽‍♀ E4.0 woman shrugging: medium skin tone
+1F937 1F3FE 200D 2640 FE0F ; fully-qualified # 🤷🏾‍♀️ E4.0 woman shrugging: medium-dark skin tone
+1F937 1F3FE 200D 2640 ; minimally-qualified # 🤷🏾‍♀ E4.0 woman shrugging: medium-dark skin tone
+1F937 1F3FF 200D 2640 FE0F ; fully-qualified # 🤷🏿‍♀️ E4.0 woman shrugging: dark skin tone
+1F937 1F3FF 200D 2640 ; minimally-qualified # 🤷🏿‍♀ E4.0 woman shrugging: dark skin tone
+
+# subgroup: person-role
+1F9D1 200D 2695 FE0F ; fully-qualified # 🧑‍⚕️ E12.1 health worker
+1F9D1 200D 2695 ; minimally-qualified # 🧑‍⚕ E12.1 health worker
+1F9D1 1F3FB 200D 2695 FE0F ; fully-qualified # 🧑🏻‍⚕️ E12.1 health worker: light skin tone
+1F9D1 1F3FB 200D 2695 ; minimally-qualified # 🧑🏻‍⚕ E12.1 health worker: light skin tone
+1F9D1 1F3FC 200D 2695 FE0F ; fully-qualified # 🧑🏼‍⚕️ E12.1 health worker: medium-light skin tone
+1F9D1 1F3FC 200D 2695 ; minimally-qualified # 🧑🏼‍⚕ E12.1 health worker: medium-light skin tone
+1F9D1 1F3FD 200D 2695 FE0F ; fully-qualified # 🧑🏽‍⚕️ E12.1 health worker: medium skin tone
+1F9D1 1F3FD 200D 2695 ; minimally-qualified # 🧑🏽‍⚕ E12.1 health worker: medium skin tone
+1F9D1 1F3FE 200D 2695 FE0F ; fully-qualified # 🧑🏾‍⚕️ E12.1 health worker: medium-dark skin tone
+1F9D1 1F3FE 200D 2695 ; minimally-qualified # 🧑🏾‍⚕ E12.1 health worker: medium-dark skin tone
+1F9D1 1F3FF 200D 2695 FE0F ; fully-qualified # 🧑🏿‍⚕️ E12.1 health worker: dark skin tone
+1F9D1 1F3FF 200D 2695 ; minimally-qualified # 🧑🏿‍⚕ E12.1 health worker: dark skin tone
+1F468 200D 2695 FE0F ; fully-qualified # 👨‍⚕️ E4.0 man health worker
+1F468 200D 2695 ; minimally-qualified # 👨‍⚕ E4.0 man health worker
+1F468 1F3FB 200D 2695 FE0F ; fully-qualified # 👨🏻‍⚕️ E4.0 man health worker: light skin tone
+1F468 1F3FB 200D 2695 ; minimally-qualified # 👨🏻‍⚕ E4.0 man health worker: light skin tone
+1F468 1F3FC 200D 2695 FE0F ; fully-qualified # 👨🏼‍⚕️ E4.0 man health worker: medium-light skin tone
+1F468 1F3FC 200D 2695 ; minimally-qualified # 👨🏼‍⚕ E4.0 man health worker: medium-light skin tone
+1F468 1F3FD 200D 2695 FE0F ; fully-qualified # 👨🏽‍⚕️ E4.0 man health worker: medium skin tone
+1F468 1F3FD 200D 2695 ; minimally-qualified # 👨🏽‍⚕ E4.0 man health worker: medium skin tone
+1F468 1F3FE 200D 2695 FE0F ; fully-qualified # 👨🏾‍⚕️ E4.0 man health worker: medium-dark skin tone
+1F468 1F3FE 200D 2695 ; minimally-qualified # 👨🏾‍⚕ E4.0 man health worker: medium-dark skin tone
+1F468 1F3FF 200D 2695 FE0F ; fully-qualified # 👨🏿‍⚕️ E4.0 man health worker: dark skin tone
+1F468 1F3FF 200D 2695 ; minimally-qualified # 👨🏿‍⚕ E4.0 man health worker: dark skin tone
+1F469 200D 2695 FE0F ; fully-qualified # 👩‍⚕️ E4.0 woman health worker
+1F469 200D 2695 ; minimally-qualified # 👩‍⚕ E4.0 woman health worker
+1F469 1F3FB 200D 2695 FE0F ; fully-qualified # 👩🏻‍⚕️ E4.0 woman health worker: light skin tone
+1F469 1F3FB 200D 2695 ; minimally-qualified # 👩🏻‍⚕ E4.0 woman health worker: light skin tone
+1F469 1F3FC 200D 2695 FE0F ; fully-qualified # 👩🏼‍⚕️ E4.0 woman health worker: medium-light skin tone
+1F469 1F3FC 200D 2695 ; minimally-qualified # 👩🏼‍⚕ E4.0 woman health worker: medium-light skin tone
+1F469 1F3FD 200D 2695 FE0F ; fully-qualified # 👩🏽‍⚕️ E4.0 woman health worker: medium skin tone
+1F469 1F3FD 200D 2695 ; minimally-qualified # 👩🏽‍⚕ E4.0 woman health worker: medium skin tone
+1F469 1F3FE 200D 2695 FE0F ; fully-qualified # 👩🏾‍⚕️ E4.0 woman health worker: medium-dark skin tone
+1F469 1F3FE 200D 2695 ; minimally-qualified # 👩🏾‍⚕ E4.0 woman health worker: medium-dark skin tone
+1F469 1F3FF 200D 2695 FE0F ; fully-qualified # 👩🏿‍⚕️ E4.0 woman health worker: dark skin tone
+1F469 1F3FF 200D 2695 ; minimally-qualified # 👩🏿‍⚕ E4.0 woman health worker: dark skin tone
+1F9D1 200D 1F393 ; fully-qualified # 🧑‍🎓 E12.1 student
+1F9D1 1F3FB 200D 1F393 ; fully-qualified # 🧑🏻‍🎓 E12.1 student: light skin tone
+1F9D1 1F3FC 200D 1F393 ; fully-qualified # 🧑🏼‍🎓 E12.1 student: medium-light skin tone
+1F9D1 1F3FD 200D 1F393 ; fully-qualified # 🧑🏽‍🎓 E12.1 student: medium skin tone
+1F9D1 1F3FE 200D 1F393 ; fully-qualified # 🧑🏾‍🎓 E12.1 student: medium-dark skin tone
+1F9D1 1F3FF 200D 1F393 ; fully-qualified # 🧑🏿‍🎓 E12.1 student: dark skin tone
+1F468 200D 1F393 ; fully-qualified # 👨‍🎓 E4.0 man student
+1F468 1F3FB 200D 1F393 ; fully-qualified # 👨🏻‍🎓 E4.0 man student: light skin tone
+1F468 1F3FC 200D 1F393 ; fully-qualified # 👨🏼‍🎓 E4.0 man student: medium-light skin tone
+1F468 1F3FD 200D 1F393 ; fully-qualified # 👨🏽‍🎓 E4.0 man student: medium skin tone
+1F468 1F3FE 200D 1F393 ; fully-qualified # 👨🏾‍🎓 E4.0 man student: medium-dark skin tone
+1F468 1F3FF 200D 1F393 ; fully-qualified # 👨🏿‍🎓 E4.0 man student: dark skin tone
+1F469 200D 1F393 ; fully-qualified # 👩‍🎓 E4.0 woman student
+1F469 1F3FB 200D 1F393 ; fully-qualified # 👩🏻‍🎓 E4.0 woman student: light skin tone
+1F469 1F3FC 200D 1F393 ; fully-qualified # 👩🏼‍🎓 E4.0 woman student: medium-light skin tone
+1F469 1F3FD 200D 1F393 ; fully-qualified # 👩🏽‍🎓 E4.0 woman student: medium skin tone
+1F469 1F3FE 200D 1F393 ; fully-qualified # 👩🏾‍🎓 E4.0 woman student: medium-dark skin tone
+1F469 1F3FF 200D 1F393 ; fully-qualified # 👩🏿‍🎓 E4.0 woman student: dark skin tone
+1F9D1 200D 1F3EB ; fully-qualified # 🧑‍🏫 E12.1 teacher
+1F9D1 1F3FB 200D 1F3EB ; fully-qualified # 🧑🏻‍🏫 E12.1 teacher: light skin tone
+1F9D1 1F3FC 200D 1F3EB ; fully-qualified # 🧑🏼‍🏫 E12.1 teacher: medium-light skin tone
+1F9D1 1F3FD 200D 1F3EB ; fully-qualified # 🧑🏽‍🏫 E12.1 teacher: medium skin tone
+1F9D1 1F3FE 200D 1F3EB ; fully-qualified # 🧑🏾‍🏫 E12.1 teacher: medium-dark skin tone
+1F9D1 1F3FF 200D 1F3EB ; fully-qualified # 🧑🏿‍🏫 E12.1 teacher: dark skin tone
+1F468 200D 1F3EB ; fully-qualified # 👨‍🏫 E4.0 man teacher
+1F468 1F3FB 200D 1F3EB ; fully-qualified # 👨🏻‍🏫 E4.0 man teacher: light skin tone
+1F468 1F3FC 200D 1F3EB ; fully-qualified # 👨🏼‍🏫 E4.0 man teacher: medium-light skin tone
+1F468 1F3FD 200D 1F3EB ; fully-qualified # 👨🏽‍🏫 E4.0 man teacher: medium skin tone
+1F468 1F3FE 200D 1F3EB ; fully-qualified # 👨🏾‍🏫 E4.0 man teacher: medium-dark skin tone
+1F468 1F3FF 200D 1F3EB ; fully-qualified # 👨🏿‍🏫 E4.0 man teacher: dark skin tone
+1F469 200D 1F3EB ; fully-qualified # 👩‍🏫 E4.0 woman teacher
+1F469 1F3FB 200D 1F3EB ; fully-qualified # 👩🏻‍🏫 E4.0 woman teacher: light skin tone
+1F469 1F3FC 200D 1F3EB ; fully-qualified # 👩🏼‍🏫 E4.0 woman teacher: medium-light skin tone
+1F469 1F3FD 200D 1F3EB ; fully-qualified # 👩🏽‍🏫 E4.0 woman teacher: medium skin tone
+1F469 1F3FE 200D 1F3EB ; fully-qualified # 👩🏾‍🏫 E4.0 woman teacher: medium-dark skin tone
+1F469 1F3FF 200D 1F3EB ; fully-qualified # 👩🏿‍🏫 E4.0 woman teacher: dark skin tone
+1F9D1 200D 2696 FE0F ; fully-qualified # 🧑‍⚖️ E12.1 judge
+1F9D1 200D 2696 ; minimally-qualified # 🧑‍⚖ E12.1 judge
+1F9D1 1F3FB 200D 2696 FE0F ; fully-qualified # 🧑🏻‍⚖️ E12.1 judge: light skin tone
+1F9D1 1F3FB 200D 2696 ; minimally-qualified # 🧑🏻‍⚖ E12.1 judge: light skin tone
+1F9D1 1F3FC 200D 2696 FE0F ; fully-qualified # 🧑🏼‍⚖️ E12.1 judge: medium-light skin tone
+1F9D1 1F3FC 200D 2696 ; minimally-qualified # 🧑🏼‍⚖ E12.1 judge: medium-light skin tone
+1F9D1 1F3FD 200D 2696 FE0F ; fully-qualified # 🧑🏽‍⚖️ E12.1 judge: medium skin tone
+1F9D1 1F3FD 200D 2696 ; minimally-qualified # 🧑🏽‍⚖ E12.1 judge: medium skin tone
+1F9D1 1F3FE 200D 2696 FE0F ; fully-qualified # 🧑🏾‍⚖️ E12.1 judge: medium-dark skin tone
+1F9D1 1F3FE 200D 2696 ; minimally-qualified # 🧑🏾‍⚖ E12.1 judge: medium-dark skin tone
+1F9D1 1F3FF 200D 2696 FE0F ; fully-qualified # 🧑🏿‍⚖️ E12.1 judge: dark skin tone
+1F9D1 1F3FF 200D 2696 ; minimally-qualified # 🧑🏿‍⚖ E12.1 judge: dark skin tone
+1F468 200D 2696 FE0F ; fully-qualified # 👨‍⚖️ E4.0 man judge
+1F468 200D 2696 ; minimally-qualified # 👨‍⚖ E4.0 man judge
+1F468 1F3FB 200D 2696 FE0F ; fully-qualified # 👨🏻‍⚖️ E4.0 man judge: light skin tone
+1F468 1F3FB 200D 2696 ; minimally-qualified # 👨🏻‍⚖ E4.0 man judge: light skin tone
+1F468 1F3FC 200D 2696 FE0F ; fully-qualified # 👨🏼‍⚖️ E4.0 man judge: medium-light skin tone
+1F468 1F3FC 200D 2696 ; minimally-qualified # 👨🏼‍⚖ E4.0 man judge: medium-light skin tone
+1F468 1F3FD 200D 2696 FE0F ; fully-qualified # 👨🏽‍⚖️ E4.0 man judge: medium skin tone
+1F468 1F3FD 200D 2696 ; minimally-qualified # 👨🏽‍⚖ E4.0 man judge: medium skin tone
+1F468 1F3FE 200D 2696 FE0F ; fully-qualified # 👨🏾‍⚖️ E4.0 man judge: medium-dark skin tone
+1F468 1F3FE 200D 2696 ; minimally-qualified # 👨🏾‍⚖ E4.0 man judge: medium-dark skin tone
+1F468 1F3FF 200D 2696 FE0F ; fully-qualified # 👨🏿‍⚖️ E4.0 man judge: dark skin tone
+1F468 1F3FF 200D 2696 ; minimally-qualified # 👨🏿‍⚖ E4.0 man judge: dark skin tone
+1F469 200D 2696 FE0F ; fully-qualified # 👩‍⚖️ E4.0 woman judge
+1F469 200D 2696 ; minimally-qualified # 👩‍⚖ E4.0 woman judge
+1F469 1F3FB 200D 2696 FE0F ; fully-qualified # 👩🏻‍⚖️ E4.0 woman judge: light skin tone
+1F469 1F3FB 200D 2696 ; minimally-qualified # 👩🏻‍⚖ E4.0 woman judge: light skin tone
+1F469 1F3FC 200D 2696 FE0F ; fully-qualified # 👩🏼‍⚖️ E4.0 woman judge: medium-light skin tone
+1F469 1F3FC 200D 2696 ; minimally-qualified # 👩🏼‍⚖ E4.0 woman judge: medium-light skin tone
+1F469 1F3FD 200D 2696 FE0F ; fully-qualified # 👩🏽‍⚖️ E4.0 woman judge: medium skin tone
+1F469 1F3FD 200D 2696 ; minimally-qualified # 👩🏽‍⚖ E4.0 woman judge: medium skin tone
+1F469 1F3FE 200D 2696 FE0F ; fully-qualified # 👩🏾‍⚖️ E4.0 woman judge: medium-dark skin tone
+1F469 1F3FE 200D 2696 ; minimally-qualified # 👩🏾‍⚖ E4.0 woman judge: medium-dark skin tone
+1F469 1F3FF 200D 2696 FE0F ; fully-qualified # 👩🏿‍⚖️ E4.0 woman judge: dark skin tone
+1F469 1F3FF 200D 2696 ; minimally-qualified # 👩🏿‍⚖ E4.0 woman judge: dark skin tone
+1F9D1 200D 1F33E ; fully-qualified # 🧑‍🌾 E12.1 farmer
+1F9D1 1F3FB 200D 1F33E ; fully-qualified # 🧑🏻‍🌾 E12.1 farmer: light skin tone
+1F9D1 1F3FC 200D 1F33E ; fully-qualified # 🧑🏼‍🌾 E12.1 farmer: medium-light skin tone
+1F9D1 1F3FD 200D 1F33E ; fully-qualified # 🧑🏽‍🌾 E12.1 farmer: medium skin tone
+1F9D1 1F3FE 200D 1F33E ; fully-qualified # 🧑🏾‍🌾 E12.1 farmer: medium-dark skin tone
+1F9D1 1F3FF 200D 1F33E ; fully-qualified # 🧑🏿‍🌾 E12.1 farmer: dark skin tone
+1F468 200D 1F33E ; fully-qualified # 👨‍🌾 E4.0 man farmer
+1F468 1F3FB 200D 1F33E ; fully-qualified # 👨🏻‍🌾 E4.0 man farmer: light skin tone
+1F468 1F3FC 200D 1F33E ; fully-qualified # 👨🏼‍🌾 E4.0 man farmer: medium-light skin tone
+1F468 1F3FD 200D 1F33E ; fully-qualified # 👨🏽‍🌾 E4.0 man farmer: medium skin tone
+1F468 1F3FE 200D 1F33E ; fully-qualified # 👨🏾‍🌾 E4.0 man farmer: medium-dark skin tone
+1F468 1F3FF 200D 1F33E ; fully-qualified # 👨🏿‍🌾 E4.0 man farmer: dark skin tone
+1F469 200D 1F33E ; fully-qualified # 👩‍🌾 E4.0 woman farmer
+1F469 1F3FB 200D 1F33E ; fully-qualified # 👩🏻‍🌾 E4.0 woman farmer: light skin tone
+1F469 1F3FC 200D 1F33E ; fully-qualified # 👩🏼‍🌾 E4.0 woman farmer: medium-light skin tone
+1F469 1F3FD 200D 1F33E ; fully-qualified # 👩🏽‍🌾 E4.0 woman farmer: medium skin tone
+1F469 1F3FE 200D 1F33E ; fully-qualified # 👩🏾‍🌾 E4.0 woman farmer: medium-dark skin tone
+1F469 1F3FF 200D 1F33E ; fully-qualified # 👩🏿‍🌾 E4.0 woman farmer: dark skin tone
+1F9D1 200D 1F373 ; fully-qualified # 🧑‍🍳 E12.1 cook
+1F9D1 1F3FB 200D 1F373 ; fully-qualified # 🧑🏻‍🍳 E12.1 cook: light skin tone
+1F9D1 1F3FC 200D 1F373 ; fully-qualified # 🧑🏼‍🍳 E12.1 cook: medium-light skin tone
+1F9D1 1F3FD 200D 1F373 ; fully-qualified # 🧑🏽‍🍳 E12.1 cook: medium skin tone
+1F9D1 1F3FE 200D 1F373 ; fully-qualified # 🧑🏾‍🍳 E12.1 cook: medium-dark skin tone
+1F9D1 1F3FF 200D 1F373 ; fully-qualified # 🧑🏿‍🍳 E12.1 cook: dark skin tone
+1F468 200D 1F373 ; fully-qualified # 👨‍🍳 E4.0 man cook
+1F468 1F3FB 200D 1F373 ; fully-qualified # 👨🏻‍🍳 E4.0 man cook: light skin tone
+1F468 1F3FC 200D 1F373 ; fully-qualified # 👨🏼‍🍳 E4.0 man cook: medium-light skin tone
+1F468 1F3FD 200D 1F373 ; fully-qualified # 👨🏽‍🍳 E4.0 man cook: medium skin tone
+1F468 1F3FE 200D 1F373 ; fully-qualified # 👨🏾‍🍳 E4.0 man cook: medium-dark skin tone
+1F468 1F3FF 200D 1F373 ; fully-qualified # 👨🏿‍🍳 E4.0 man cook: dark skin tone
+1F469 200D 1F373 ; fully-qualified # 👩‍🍳 E4.0 woman cook
+1F469 1F3FB 200D 1F373 ; fully-qualified # 👩🏻‍🍳 E4.0 woman cook: light skin tone
+1F469 1F3FC 200D 1F373 ; fully-qualified # 👩🏼‍🍳 E4.0 woman cook: medium-light skin tone
+1F469 1F3FD 200D 1F373 ; fully-qualified # 👩🏽‍🍳 E4.0 woman cook: medium skin tone
+1F469 1F3FE 200D 1F373 ; fully-qualified # 👩🏾‍🍳 E4.0 woman cook: medium-dark skin tone
+1F469 1F3FF 200D 1F373 ; fully-qualified # 👩🏿‍🍳 E4.0 woman cook: dark skin tone
+1F9D1 200D 1F527 ; fully-qualified # 🧑‍🔧 E12.1 mechanic
+1F9D1 1F3FB 200D 1F527 ; fully-qualified # 🧑🏻‍🔧 E12.1 mechanic: light skin tone
+1F9D1 1F3FC 200D 1F527 ; fully-qualified # 🧑🏼‍🔧 E12.1 mechanic: medium-light skin tone
+1F9D1 1F3FD 200D 1F527 ; fully-qualified # 🧑🏽‍🔧 E12.1 mechanic: medium skin tone
+1F9D1 1F3FE 200D 1F527 ; fully-qualified # 🧑🏾‍🔧 E12.1 mechanic: medium-dark skin tone
+1F9D1 1F3FF 200D 1F527 ; fully-qualified # 🧑🏿‍🔧 E12.1 mechanic: dark skin tone
+1F468 200D 1F527 ; fully-qualified # 👨‍🔧 E4.0 man mechanic
+1F468 1F3FB 200D 1F527 ; fully-qualified # 👨🏻‍🔧 E4.0 man mechanic: light skin tone
+1F468 1F3FC 200D 1F527 ; fully-qualified # 👨🏼‍🔧 E4.0 man mechanic: medium-light skin tone
+1F468 1F3FD 200D 1F527 ; fully-qualified # 👨🏽‍🔧 E4.0 man mechanic: medium skin tone
+1F468 1F3FE 200D 1F527 ; fully-qualified # 👨🏾‍🔧 E4.0 man mechanic: medium-dark skin tone
+1F468 1F3FF 200D 1F527 ; fully-qualified # 👨🏿‍🔧 E4.0 man mechanic: dark skin tone
+1F469 200D 1F527 ; fully-qualified # 👩‍🔧 E4.0 woman mechanic
+1F469 1F3FB 200D 1F527 ; fully-qualified # 👩🏻‍🔧 E4.0 woman mechanic: light skin tone
+1F469 1F3FC 200D 1F527 ; fully-qualified # 👩🏼‍🔧 E4.0 woman mechanic: medium-light skin tone
+1F469 1F3FD 200D 1F527 ; fully-qualified # 👩🏽‍🔧 E4.0 woman mechanic: medium skin tone
+1F469 1F3FE 200D 1F527 ; fully-qualified # 👩🏾‍🔧 E4.0 woman mechanic: medium-dark skin tone
+1F469 1F3FF 200D 1F527 ; fully-qualified # 👩🏿‍🔧 E4.0 woman mechanic: dark skin tone
+1F9D1 200D 1F3ED ; fully-qualified # 🧑‍🏭 E12.1 factory worker
+1F9D1 1F3FB 200D 1F3ED ; fully-qualified # 🧑🏻‍🏭 E12.1 factory worker: light skin tone
+1F9D1 1F3FC 200D 1F3ED ; fully-qualified # 🧑🏼‍🏭 E12.1 factory worker: medium-light skin tone
+1F9D1 1F3FD 200D 1F3ED ; fully-qualified # 🧑🏽‍🏭 E12.1 factory worker: medium skin tone
+1F9D1 1F3FE 200D 1F3ED ; fully-qualified # 🧑🏾‍🏭 E12.1 factory worker: medium-dark skin tone
+1F9D1 1F3FF 200D 1F3ED ; fully-qualified # 🧑🏿‍🏭 E12.1 factory worker: dark skin tone
+1F468 200D 1F3ED ; fully-qualified # 👨‍🏭 E4.0 man factory worker
+1F468 1F3FB 200D 1F3ED ; fully-qualified # 👨🏻‍🏭 E4.0 man factory worker: light skin tone
+1F468 1F3FC 200D 1F3ED ; fully-qualified # 👨🏼‍🏭 E4.0 man factory worker: medium-light skin tone
+1F468 1F3FD 200D 1F3ED ; fully-qualified # 👨🏽‍🏭 E4.0 man factory worker: medium skin tone
+1F468 1F3FE 200D 1F3ED ; fully-qualified # 👨🏾‍🏭 E4.0 man factory worker: medium-dark skin tone
+1F468 1F3FF 200D 1F3ED ; fully-qualified # 👨🏿‍🏭 E4.0 man factory worker: dark skin tone
+1F469 200D 1F3ED ; fully-qualified # 👩‍🏭 E4.0 woman factory worker
+1F469 1F3FB 200D 1F3ED ; fully-qualified # 👩🏻‍🏭 E4.0 woman factory worker: light skin tone
+1F469 1F3FC 200D 1F3ED ; fully-qualified # 👩🏼‍🏭 E4.0 woman factory worker: medium-light skin tone
+1F469 1F3FD 200D 1F3ED ; fully-qualified # 👩🏽‍🏭 E4.0 woman factory worker: medium skin tone
+1F469 1F3FE 200D 1F3ED ; fully-qualified # 👩🏾‍🏭 E4.0 woman factory worker: medium-dark skin tone
+1F469 1F3FF 200D 1F3ED ; fully-qualified # 👩🏿‍🏭 E4.0 woman factory worker: dark skin tone
+1F9D1 200D 1F4BC ; fully-qualified # 🧑‍💼 E12.1 office worker
+1F9D1 1F3FB 200D 1F4BC ; fully-qualified # 🧑🏻‍💼 E12.1 office worker: light skin tone
+1F9D1 1F3FC 200D 1F4BC ; fully-qualified # 🧑🏼‍💼 E12.1 office worker: medium-light skin tone
+1F9D1 1F3FD 200D 1F4BC ; fully-qualified # 🧑🏽‍💼 E12.1 office worker: medium skin tone
+1F9D1 1F3FE 200D 1F4BC ; fully-qualified # 🧑🏾‍💼 E12.1 office worker: medium-dark skin tone
+1F9D1 1F3FF 200D 1F4BC ; fully-qualified # 🧑🏿‍💼 E12.1 office worker: dark skin tone
+1F468 200D 1F4BC ; fully-qualified # 👨‍💼 E4.0 man office worker
+1F468 1F3FB 200D 1F4BC ; fully-qualified # 👨🏻‍💼 E4.0 man office worker: light skin tone
+1F468 1F3FC 200D 1F4BC ; fully-qualified # 👨🏼‍💼 E4.0 man office worker: medium-light skin tone
+1F468 1F3FD 200D 1F4BC ; fully-qualified # 👨🏽‍💼 E4.0 man office worker: medium skin tone
+1F468 1F3FE 200D 1F4BC ; fully-qualified # 👨🏾‍💼 E4.0 man office worker: medium-dark skin tone
+1F468 1F3FF 200D 1F4BC ; fully-qualified # 👨🏿‍💼 E4.0 man office worker: dark skin tone
+1F469 200D 1F4BC ; fully-qualified # 👩‍💼 E4.0 woman office worker
+1F469 1F3FB 200D 1F4BC ; fully-qualified # 👩🏻‍💼 E4.0 woman office worker: light skin tone
+1F469 1F3FC 200D 1F4BC ; fully-qualified # 👩🏼‍💼 E4.0 woman office worker: medium-light skin tone
+1F469 1F3FD 200D 1F4BC ; fully-qualified # 👩🏽‍💼 E4.0 woman office worker: medium skin tone
+1F469 1F3FE 200D 1F4BC ; fully-qualified # 👩🏾‍💼 E4.0 woman office worker: medium-dark skin tone
+1F469 1F3FF 200D 1F4BC ; fully-qualified # 👩🏿‍💼 E4.0 woman office worker: dark skin tone
+1F9D1 200D 1F52C ; fully-qualified # 🧑‍🔬 E12.1 scientist
+1F9D1 1F3FB 200D 1F52C ; fully-qualified # 🧑🏻‍🔬 E12.1 scientist: light skin tone
+1F9D1 1F3FC 200D 1F52C ; fully-qualified # 🧑🏼‍🔬 E12.1 scientist: medium-light skin tone
+1F9D1 1F3FD 200D 1F52C ; fully-qualified # 🧑🏽‍🔬 E12.1 scientist: medium skin tone
+1F9D1 1F3FE 200D 1F52C ; fully-qualified # 🧑🏾‍🔬 E12.1 scientist: medium-dark skin tone
+1F9D1 1F3FF 200D 1F52C ; fully-qualified # 🧑🏿‍🔬 E12.1 scientist: dark skin tone
+1F468 200D 1F52C ; fully-qualified # 👨‍🔬 E4.0 man scientist
+1F468 1F3FB 200D 1F52C ; fully-qualified # 👨🏻‍🔬 E4.0 man scientist: light skin tone
+1F468 1F3FC 200D 1F52C ; fully-qualified # 👨🏼‍🔬 E4.0 man scientist: medium-light skin tone
+1F468 1F3FD 200D 1F52C ; fully-qualified # 👨🏽‍🔬 E4.0 man scientist: medium skin tone
+1F468 1F3FE 200D 1F52C ; fully-qualified # 👨🏾‍🔬 E4.0 man scientist: medium-dark skin tone
+1F468 1F3FF 200D 1F52C ; fully-qualified # 👨🏿‍🔬 E4.0 man scientist: dark skin tone
+1F469 200D 1F52C ; fully-qualified # 👩‍🔬 E4.0 woman scientist
+1F469 1F3FB 200D 1F52C ; fully-qualified # 👩🏻‍🔬 E4.0 woman scientist: light skin tone
+1F469 1F3FC 200D 1F52C ; fully-qualified # 👩🏼‍🔬 E4.0 woman scientist: medium-light skin tone
+1F469 1F3FD 200D 1F52C ; fully-qualified # 👩🏽‍🔬 E4.0 woman scientist: medium skin tone
+1F469 1F3FE 200D 1F52C ; fully-qualified # 👩🏾‍🔬 E4.0 woman scientist: medium-dark skin tone
+1F469 1F3FF 200D 1F52C ; fully-qualified # 👩🏿‍🔬 E4.0 woman scientist: dark skin tone
+1F9D1 200D 1F4BB ; fully-qualified # 🧑‍💻 E12.1 technologist
+1F9D1 1F3FB 200D 1F4BB ; fully-qualified # 🧑🏻‍💻 E12.1 technologist: light skin tone
+1F9D1 1F3FC 200D 1F4BB ; fully-qualified # 🧑🏼‍💻 E12.1 technologist: medium-light skin tone
+1F9D1 1F3FD 200D 1F4BB ; fully-qualified # 🧑🏽‍💻 E12.1 technologist: medium skin tone
+1F9D1 1F3FE 200D 1F4BB ; fully-qualified # 🧑🏾‍💻 E12.1 technologist: medium-dark skin tone
+1F9D1 1F3FF 200D 1F4BB ; fully-qualified # 🧑🏿‍💻 E12.1 technologist: dark skin tone
+1F468 200D 1F4BB ; fully-qualified # 👨‍💻 E4.0 man technologist
+1F468 1F3FB 200D 1F4BB ; fully-qualified # 👨🏻‍💻 E4.0 man technologist: light skin tone
+1F468 1F3FC 200D 1F4BB ; fully-qualified # 👨🏼‍💻 E4.0 man technologist: medium-light skin tone
+1F468 1F3FD 200D 1F4BB ; fully-qualified # 👨🏽‍💻 E4.0 man technologist: medium skin tone
+1F468 1F3FE 200D 1F4BB ; fully-qualified # 👨🏾‍💻 E4.0 man technologist: medium-dark skin tone
+1F468 1F3FF 200D 1F4BB ; fully-qualified # 👨🏿‍💻 E4.0 man technologist: dark skin tone
+1F469 200D 1F4BB ; fully-qualified # 👩‍💻 E4.0 woman technologist
+1F469 1F3FB 200D 1F4BB ; fully-qualified # 👩🏻‍💻 E4.0 woman technologist: light skin tone
+1F469 1F3FC 200D 1F4BB ; fully-qualified # 👩🏼‍💻 E4.0 woman technologist: medium-light skin tone
+1F469 1F3FD 200D 1F4BB ; fully-qualified # 👩🏽‍💻 E4.0 woman technologist: medium skin tone
+1F469 1F3FE 200D 1F4BB ; fully-qualified # 👩🏾‍💻 E4.0 woman technologist: medium-dark skin tone
+1F469 1F3FF 200D 1F4BB ; fully-qualified # 👩🏿‍💻 E4.0 woman technologist: dark skin tone
+1F9D1 200D 1F3A4 ; fully-qualified # 🧑‍🎤 E12.1 singer
+1F9D1 1F3FB 200D 1F3A4 ; fully-qualified # 🧑🏻‍🎤 E12.1 singer: light skin tone
+1F9D1 1F3FC 200D 1F3A4 ; fully-qualified # 🧑🏼‍🎤 E12.1 singer: medium-light skin tone
+1F9D1 1F3FD 200D 1F3A4 ; fully-qualified # 🧑🏽‍🎤 E12.1 singer: medium skin tone
+1F9D1 1F3FE 200D 1F3A4 ; fully-qualified # 🧑🏾‍🎤 E12.1 singer: medium-dark skin tone
+1F9D1 1F3FF 200D 1F3A4 ; fully-qualified # 🧑🏿‍🎤 E12.1 singer: dark skin tone
+1F468 200D 1F3A4 ; fully-qualified # 👨‍🎤 E4.0 man singer
+1F468 1F3FB 200D 1F3A4 ; fully-qualified # 👨🏻‍🎤 E4.0 man singer: light skin tone
+1F468 1F3FC 200D 1F3A4 ; fully-qualified # 👨🏼‍🎤 E4.0 man singer: medium-light skin tone
+1F468 1F3FD 200D 1F3A4 ; fully-qualified # 👨🏽‍🎤 E4.0 man singer: medium skin tone
+1F468 1F3FE 200D 1F3A4 ; fully-qualified # 👨🏾‍🎤 E4.0 man singer: medium-dark skin tone
+1F468 1F3FF 200D 1F3A4 ; fully-qualified # 👨🏿‍🎤 E4.0 man singer: dark skin tone
+1F469 200D 1F3A4 ; fully-qualified # 👩‍🎤 E4.0 woman singer
+1F469 1F3FB 200D 1F3A4 ; fully-qualified # 👩🏻‍🎤 E4.0 woman singer: light skin tone
+1F469 1F3FC 200D 1F3A4 ; fully-qualified # 👩🏼‍🎤 E4.0 woman singer: medium-light skin tone
+1F469 1F3FD 200D 1F3A4 ; fully-qualified # 👩🏽‍🎤 E4.0 woman singer: medium skin tone
+1F469 1F3FE 200D 1F3A4 ; fully-qualified # 👩🏾‍🎤 E4.0 woman singer: medium-dark skin tone
+1F469 1F3FF 200D 1F3A4 ; fully-qualified # 👩🏿‍🎤 E4.0 woman singer: dark skin tone
+1F9D1 200D 1F3A8 ; fully-qualified # 🧑‍🎨 E12.1 artist
+1F9D1 1F3FB 200D 1F3A8 ; fully-qualified # 🧑🏻‍🎨 E12.1 artist: light skin tone
+1F9D1 1F3FC 200D 1F3A8 ; fully-qualified # 🧑🏼‍🎨 E12.1 artist: medium-light skin tone
+1F9D1 1F3FD 200D 1F3A8 ; fully-qualified # 🧑🏽‍🎨 E12.1 artist: medium skin tone
+1F9D1 1F3FE 200D 1F3A8 ; fully-qualified # 🧑🏾‍🎨 E12.1 artist: medium-dark skin tone
+1F9D1 1F3FF 200D 1F3A8 ; fully-qualified # 🧑🏿‍🎨 E12.1 artist: dark skin tone
+1F468 200D 1F3A8 ; fully-qualified # 👨‍🎨 E4.0 man artist
+1F468 1F3FB 200D 1F3A8 ; fully-qualified # 👨🏻‍🎨 E4.0 man artist: light skin tone
+1F468 1F3FC 200D 1F3A8 ; fully-qualified # 👨🏼‍🎨 E4.0 man artist: medium-light skin tone
+1F468 1F3FD 200D 1F3A8 ; fully-qualified # 👨🏽‍🎨 E4.0 man artist: medium skin tone
+1F468 1F3FE 200D 1F3A8 ; fully-qualified # 👨🏾‍🎨 E4.0 man artist: medium-dark skin tone
+1F468 1F3FF 200D 1F3A8 ; fully-qualified # 👨🏿‍🎨 E4.0 man artist: dark skin tone
+1F469 200D 1F3A8 ; fully-qualified # 👩‍🎨 E4.0 woman artist
+1F469 1F3FB 200D 1F3A8 ; fully-qualified # 👩🏻‍🎨 E4.0 woman artist: light skin tone
+1F469 1F3FC 200D 1F3A8 ; fully-qualified # 👩🏼‍🎨 E4.0 woman artist: medium-light skin tone
+1F469 1F3FD 200D 1F3A8 ; fully-qualified # 👩🏽‍🎨 E4.0 woman artist: medium skin tone
+1F469 1F3FE 200D 1F3A8 ; fully-qualified # 👩🏾‍🎨 E4.0 woman artist: medium-dark skin tone
+1F469 1F3FF 200D 1F3A8 ; fully-qualified # 👩🏿‍🎨 E4.0 woman artist: dark skin tone
+1F9D1 200D 2708 FE0F ; fully-qualified # 🧑‍✈️ E12.1 pilot
+1F9D1 200D 2708 ; minimally-qualified # 🧑‍✈ E12.1 pilot
+1F9D1 1F3FB 200D 2708 FE0F ; fully-qualified # 🧑🏻‍✈️ E12.1 pilot: light skin tone
+1F9D1 1F3FB 200D 2708 ; minimally-qualified # 🧑🏻‍✈ E12.1 pilot: light skin tone
+1F9D1 1F3FC 200D 2708 FE0F ; fully-qualified # 🧑🏼‍✈️ E12.1 pilot: medium-light skin tone
+1F9D1 1F3FC 200D 2708 ; minimally-qualified # 🧑🏼‍✈ E12.1 pilot: medium-light skin tone
+1F9D1 1F3FD 200D 2708 FE0F ; fully-qualified # 🧑🏽‍✈️ E12.1 pilot: medium skin tone
+1F9D1 1F3FD 200D 2708 ; minimally-qualified # 🧑🏽‍✈ E12.1 pilot: medium skin tone
+1F9D1 1F3FE 200D 2708 FE0F ; fully-qualified # 🧑🏾‍✈️ E12.1 pilot: medium-dark skin tone
+1F9D1 1F3FE 200D 2708 ; minimally-qualified # 🧑🏾‍✈ E12.1 pilot: medium-dark skin tone
+1F9D1 1F3FF 200D 2708 FE0F ; fully-qualified # 🧑🏿‍✈️ E12.1 pilot: dark skin tone
+1F9D1 1F3FF 200D 2708 ; minimally-qualified # 🧑🏿‍✈ E12.1 pilot: dark skin tone
+1F468 200D 2708 FE0F ; fully-qualified # 👨‍✈️ E4.0 man pilot
+1F468 200D 2708 ; minimally-qualified # 👨‍✈ E4.0 man pilot
+1F468 1F3FB 200D 2708 FE0F ; fully-qualified # 👨🏻‍✈️ E4.0 man pilot: light skin tone
+1F468 1F3FB 200D 2708 ; minimally-qualified # 👨🏻‍✈ E4.0 man pilot: light skin tone
+1F468 1F3FC 200D 2708 FE0F ; fully-qualified # 👨🏼‍✈️ E4.0 man pilot: medium-light skin tone
+1F468 1F3FC 200D 2708 ; minimally-qualified # 👨🏼‍✈ E4.0 man pilot: medium-light skin tone
+1F468 1F3FD 200D 2708 FE0F ; fully-qualified # 👨🏽‍✈️ E4.0 man pilot: medium skin tone
+1F468 1F3FD 200D 2708 ; minimally-qualified # 👨🏽‍✈ E4.0 man pilot: medium skin tone
+1F468 1F3FE 200D 2708 FE0F ; fully-qualified # 👨🏾‍✈️ E4.0 man pilot: medium-dark skin tone
+1F468 1F3FE 200D 2708 ; minimally-qualified # 👨🏾‍✈ E4.0 man pilot: medium-dark skin tone
+1F468 1F3FF 200D 2708 FE0F ; fully-qualified # 👨🏿‍✈️ E4.0 man pilot: dark skin tone
+1F468 1F3FF 200D 2708 ; minimally-qualified # 👨🏿‍✈ E4.0 man pilot: dark skin tone
+1F469 200D 2708 FE0F ; fully-qualified # 👩‍✈️ E4.0 woman pilot
+1F469 200D 2708 ; minimally-qualified # 👩‍✈ E4.0 woman pilot
+1F469 1F3FB 200D 2708 FE0F ; fully-qualified # 👩🏻‍✈️ E4.0 woman pilot: light skin tone
+1F469 1F3FB 200D 2708 ; minimally-qualified # 👩🏻‍✈ E4.0 woman pilot: light skin tone
+1F469 1F3FC 200D 2708 FE0F ; fully-qualified # 👩🏼‍✈️ E4.0 woman pilot: medium-light skin tone
+1F469 1F3FC 200D 2708 ; minimally-qualified # 👩🏼‍✈ E4.0 woman pilot: medium-light skin tone
+1F469 1F3FD 200D 2708 FE0F ; fully-qualified # 👩🏽‍✈️ E4.0 woman pilot: medium skin tone
+1F469 1F3FD 200D 2708 ; minimally-qualified # 👩🏽‍✈ E4.0 woman pilot: medium skin tone
+1F469 1F3FE 200D 2708 FE0F ; fully-qualified # 👩🏾‍✈️ E4.0 woman pilot: medium-dark skin tone
+1F469 1F3FE 200D 2708 ; minimally-qualified # 👩🏾‍✈ E4.0 woman pilot: medium-dark skin tone
+1F469 1F3FF 200D 2708 FE0F ; fully-qualified # 👩🏿‍✈️ E4.0 woman pilot: dark skin tone
+1F469 1F3FF 200D 2708 ; minimally-qualified # 👩🏿‍✈ E4.0 woman pilot: dark skin tone
+1F9D1 200D 1F680 ; fully-qualified # 🧑‍🚀 E12.1 astronaut
+1F9D1 1F3FB 200D 1F680 ; fully-qualified # 🧑🏻‍🚀 E12.1 astronaut: light skin tone
+1F9D1 1F3FC 200D 1F680 ; fully-qualified # 🧑🏼‍🚀 E12.1 astronaut: medium-light skin tone
+1F9D1 1F3FD 200D 1F680 ; fully-qualified # 🧑🏽‍🚀 E12.1 astronaut: medium skin tone
+1F9D1 1F3FE 200D 1F680 ; fully-qualified # 🧑🏾‍🚀 E12.1 astronaut: medium-dark skin tone
+1F9D1 1F3FF 200D 1F680 ; fully-qualified # 🧑🏿‍🚀 E12.1 astronaut: dark skin tone
+1F468 200D 1F680 ; fully-qualified # 👨‍🚀 E4.0 man astronaut
+1F468 1F3FB 200D 1F680 ; fully-qualified # 👨🏻‍🚀 E4.0 man astronaut: light skin tone
+1F468 1F3FC 200D 1F680 ; fully-qualified # 👨🏼‍🚀 E4.0 man astronaut: medium-light skin tone
+1F468 1F3FD 200D 1F680 ; fully-qualified # 👨🏽‍🚀 E4.0 man astronaut: medium skin tone
+1F468 1F3FE 200D 1F680 ; fully-qualified # 👨🏾‍🚀 E4.0 man astronaut: medium-dark skin tone
+1F468 1F3FF 200D 1F680 ; fully-qualified # 👨🏿‍🚀 E4.0 man astronaut: dark skin tone
+1F469 200D 1F680 ; fully-qualified # 👩‍🚀 E4.0 woman astronaut
+1F469 1F3FB 200D 1F680 ; fully-qualified # 👩🏻‍🚀 E4.0 woman astronaut: light skin tone
+1F469 1F3FC 200D 1F680 ; fully-qualified # 👩🏼‍🚀 E4.0 woman astronaut: medium-light skin tone
+1F469 1F3FD 200D 1F680 ; fully-qualified # 👩🏽‍🚀 E4.0 woman astronaut: medium skin tone
+1F469 1F3FE 200D 1F680 ; fully-qualified # 👩🏾‍🚀 E4.0 woman astronaut: medium-dark skin tone
+1F469 1F3FF 200D 1F680 ; fully-qualified # 👩🏿‍🚀 E4.0 woman astronaut: dark skin tone
+1F9D1 200D 1F692 ; fully-qualified # 🧑‍🚒 E12.1 firefighter
+1F9D1 1F3FB 200D 1F692 ; fully-qualified # 🧑🏻‍🚒 E12.1 firefighter: light skin tone
+1F9D1 1F3FC 200D 1F692 ; fully-qualified # 🧑🏼‍🚒 E12.1 firefighter: medium-light skin tone
+1F9D1 1F3FD 200D 1F692 ; fully-qualified # 🧑🏽‍🚒 E12.1 firefighter: medium skin tone
+1F9D1 1F3FE 200D 1F692 ; fully-qualified # 🧑🏾‍🚒 E12.1 firefighter: medium-dark skin tone
+1F9D1 1F3FF 200D 1F692 ; fully-qualified # 🧑🏿‍🚒 E12.1 firefighter: dark skin tone
+1F468 200D 1F692 ; fully-qualified # 👨‍🚒 E4.0 man firefighter
+1F468 1F3FB 200D 1F692 ; fully-qualified # 👨🏻‍🚒 E4.0 man firefighter: light skin tone
+1F468 1F3FC 200D 1F692 ; fully-qualified # 👨🏼‍🚒 E4.0 man firefighter: medium-light skin tone
+1F468 1F3FD 200D 1F692 ; fully-qualified # 👨🏽‍🚒 E4.0 man firefighter: medium skin tone
+1F468 1F3FE 200D 1F692 ; fully-qualified # 👨🏾‍🚒 E4.0 man firefighter: medium-dark skin tone
+1F468 1F3FF 200D 1F692 ; fully-qualified # 👨🏿‍🚒 E4.0 man firefighter: dark skin tone
+1F469 200D 1F692 ; fully-qualified # 👩‍🚒 E4.0 woman firefighter
+1F469 1F3FB 200D 1F692 ; fully-qualified # 👩🏻‍🚒 E4.0 woman firefighter: light skin tone
+1F469 1F3FC 200D 1F692 ; fully-qualified # 👩🏼‍🚒 E4.0 woman firefighter: medium-light skin tone
+1F469 1F3FD 200D 1F692 ; fully-qualified # 👩🏽‍🚒 E4.0 woman firefighter: medium skin tone
+1F469 1F3FE 200D 1F692 ; fully-qualified # 👩🏾‍🚒 E4.0 woman firefighter: medium-dark skin tone
+1F469 1F3FF 200D 1F692 ; fully-qualified # 👩🏿‍🚒 E4.0 woman firefighter: dark skin tone
+1F46E ; fully-qualified # 👮 E0.6 police officer
+1F46E 1F3FB ; fully-qualified # 👮🏻 E1.0 police officer: light skin tone
+1F46E 1F3FC ; fully-qualified # 👮🏼 E1.0 police officer: medium-light skin tone
+1F46E 1F3FD ; fully-qualified # 👮🏽 E1.0 police officer: medium skin tone
+1F46E 1F3FE ; fully-qualified # 👮🏾 E1.0 police officer: medium-dark skin tone
+1F46E 1F3FF ; fully-qualified # 👮🏿 E1.0 police officer: dark skin tone
+1F46E 200D 2642 FE0F ; fully-qualified # 👮‍♂️ E4.0 man police officer
+1F46E 200D 2642 ; minimally-qualified # 👮‍♂ E4.0 man police officer
+1F46E 1F3FB 200D 2642 FE0F ; fully-qualified # 👮🏻‍♂️ E4.0 man police officer: light skin tone
+1F46E 1F3FB 200D 2642 ; minimally-qualified # 👮🏻‍♂ E4.0 man police officer: light skin tone
+1F46E 1F3FC 200D 2642 FE0F ; fully-qualified # 👮🏼‍♂️ E4.0 man police officer: medium-light skin tone
+1F46E 1F3FC 200D 2642 ; minimally-qualified # 👮🏼‍♂ E4.0 man police officer: medium-light skin tone
+1F46E 1F3FD 200D 2642 FE0F ; fully-qualified # 👮🏽‍♂️ E4.0 man police officer: medium skin tone
+1F46E 1F3FD 200D 2642 ; minimally-qualified # 👮🏽‍♂ E4.0 man police officer: medium skin tone
+1F46E 1F3FE 200D 2642 FE0F ; fully-qualified # 👮🏾‍♂️ E4.0 man police officer: medium-dark skin tone
+1F46E 1F3FE 200D 2642 ; minimally-qualified # 👮🏾‍♂ E4.0 man police officer: medium-dark skin tone
+1F46E 1F3FF 200D 2642 FE0F ; fully-qualified # 👮🏿‍♂️ E4.0 man police officer: dark skin tone
+1F46E 1F3FF 200D 2642 ; minimally-qualified # 👮🏿‍♂ E4.0 man police officer: dark skin tone
+1F46E 200D 2640 FE0F ; fully-qualified # 👮‍♀️ E4.0 woman police officer
+1F46E 200D 2640 ; minimally-qualified # 👮‍♀ E4.0 woman police officer
+1F46E 1F3FB 200D 2640 FE0F ; fully-qualified # 👮🏻‍♀️ E4.0 woman police officer: light skin tone
+1F46E 1F3FB 200D 2640 ; minimally-qualified # 👮🏻‍♀ E4.0 woman police officer: light skin tone
+1F46E 1F3FC 200D 2640 FE0F ; fully-qualified # 👮🏼‍♀️ E4.0 woman police officer: medium-light skin tone
+1F46E 1F3FC 200D 2640 ; minimally-qualified # 👮🏼‍♀ E4.0 woman police officer: medium-light skin tone
+1F46E 1F3FD 200D 2640 FE0F ; fully-qualified # 👮🏽‍♀️ E4.0 woman police officer: medium skin tone
+1F46E 1F3FD 200D 2640 ; minimally-qualified # 👮🏽‍♀ E4.0 woman police officer: medium skin tone
+1F46E 1F3FE 200D 2640 FE0F ; fully-qualified # 👮🏾‍♀️ E4.0 woman police officer: medium-dark skin tone
+1F46E 1F3FE 200D 2640 ; minimally-qualified # 👮🏾‍♀ E4.0 woman police officer: medium-dark skin tone
+1F46E 1F3FF 200D 2640 FE0F ; fully-qualified # 👮🏿‍♀️ E4.0 woman police officer: dark skin tone
+1F46E 1F3FF 200D 2640 ; minimally-qualified # 👮🏿‍♀ E4.0 woman police officer: dark skin tone
+1F575 FE0F ; fully-qualified # 🕵️ E0.7 detective
+1F575 ; unqualified # 🕵 E0.7 detective
+1F575 1F3FB ; fully-qualified # 🕵🏻 E2.0 detective: light skin tone
+1F575 1F3FC ; fully-qualified # 🕵🏼 E2.0 detective: medium-light skin tone
+1F575 1F3FD ; fully-qualified # 🕵🏽 E2.0 detective: medium skin tone
+1F575 1F3FE ; fully-qualified # 🕵🏾 E2.0 detective: medium-dark skin tone
+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 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
+1F575 1F3FC 200D 2642 FE0F ; fully-qualified # 🕵🏼‍♂️ E4.0 man detective: medium-light skin tone
+1F575 1F3FC 200D 2642 ; minimally-qualified # 🕵🏼‍♂ E4.0 man detective: medium-light skin tone
+1F575 1F3FD 200D 2642 FE0F ; fully-qualified # 🕵🏽‍♂️ E4.0 man detective: medium skin tone
+1F575 1F3FD 200D 2642 ; minimally-qualified # 🕵🏽‍♂ E4.0 man detective: medium skin tone
+1F575 1F3FE 200D 2642 FE0F ; fully-qualified # 🕵🏾‍♂️ E4.0 man detective: medium-dark skin tone
+1F575 1F3FE 200D 2642 ; minimally-qualified # 🕵🏾‍♂ E4.0 man detective: medium-dark skin tone
+1F575 1F3FF 200D 2642 FE0F ; fully-qualified # 🕵🏿‍♂️ E4.0 man detective: dark skin tone
+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 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
+1F575 1F3FC 200D 2640 FE0F ; fully-qualified # 🕵🏼‍♀️ E4.0 woman detective: medium-light skin tone
+1F575 1F3FC 200D 2640 ; minimally-qualified # 🕵🏼‍♀ E4.0 woman detective: medium-light skin tone
+1F575 1F3FD 200D 2640 FE0F ; fully-qualified # 🕵🏽‍♀️ E4.0 woman detective: medium skin tone
+1F575 1F3FD 200D 2640 ; minimally-qualified # 🕵🏽‍♀ E4.0 woman detective: medium skin tone
+1F575 1F3FE 200D 2640 FE0F ; fully-qualified # 🕵🏾‍♀️ E4.0 woman detective: medium-dark skin tone
+1F575 1F3FE 200D 2640 ; minimally-qualified # 🕵🏾‍♀ E4.0 woman detective: medium-dark skin tone
+1F575 1F3FF 200D 2640 FE0F ; fully-qualified # 🕵🏿‍♀️ E4.0 woman detective: dark skin tone
+1F575 1F3FF 200D 2640 ; minimally-qualified # 🕵🏿‍♀ E4.0 woman detective: dark skin tone
+1F482 ; fully-qualified # 💂 E0.6 guard
+1F482 1F3FB ; fully-qualified # 💂🏻 E1.0 guard: light skin tone
+1F482 1F3FC ; fully-qualified # 💂🏼 E1.0 guard: medium-light skin tone
+1F482 1F3FD ; fully-qualified # 💂🏽 E1.0 guard: medium skin tone
+1F482 1F3FE ; fully-qualified # 💂🏾 E1.0 guard: medium-dark skin tone
+1F482 1F3FF ; fully-qualified # 💂🏿 E1.0 guard: dark skin tone
+1F482 200D 2642 FE0F ; fully-qualified # 💂‍♂️ E4.0 man guard
+1F482 200D 2642 ; minimally-qualified # 💂‍♂ E4.0 man guard
+1F482 1F3FB 200D 2642 FE0F ; fully-qualified # 💂🏻‍♂️ E4.0 man guard: light skin tone
+1F482 1F3FB 200D 2642 ; minimally-qualified # 💂🏻‍♂ E4.0 man guard: light skin tone
+1F482 1F3FC 200D 2642 FE0F ; fully-qualified # 💂🏼‍♂️ E4.0 man guard: medium-light skin tone
+1F482 1F3FC 200D 2642 ; minimally-qualified # 💂🏼‍♂ E4.0 man guard: medium-light skin tone
+1F482 1F3FD 200D 2642 FE0F ; fully-qualified # 💂🏽‍♂️ E4.0 man guard: medium skin tone
+1F482 1F3FD 200D 2642 ; minimally-qualified # 💂🏽‍♂ E4.0 man guard: medium skin tone
+1F482 1F3FE 200D 2642 FE0F ; fully-qualified # 💂🏾‍♂️ E4.0 man guard: medium-dark skin tone
+1F482 1F3FE 200D 2642 ; minimally-qualified # 💂🏾‍♂ E4.0 man guard: medium-dark skin tone
+1F482 1F3FF 200D 2642 FE0F ; fully-qualified # 💂🏿‍♂️ E4.0 man guard: dark skin tone
+1F482 1F3FF 200D 2642 ; minimally-qualified # 💂🏿‍♂ E4.0 man guard: dark skin tone
+1F482 200D 2640 FE0F ; fully-qualified # 💂‍♀️ E4.0 woman guard
+1F482 200D 2640 ; minimally-qualified # 💂‍♀ E4.0 woman guard
+1F482 1F3FB 200D 2640 FE0F ; fully-qualified # 💂🏻‍♀️ E4.0 woman guard: light skin tone
+1F482 1F3FB 200D 2640 ; minimally-qualified # 💂🏻‍♀ E4.0 woman guard: light skin tone
+1F482 1F3FC 200D 2640 FE0F ; fully-qualified # 💂🏼‍♀️ E4.0 woman guard: medium-light skin tone
+1F482 1F3FC 200D 2640 ; minimally-qualified # 💂🏼‍♀ E4.0 woman guard: medium-light skin tone
+1F482 1F3FD 200D 2640 FE0F ; fully-qualified # 💂🏽‍♀️ E4.0 woman guard: medium skin tone
+1F482 1F3FD 200D 2640 ; minimally-qualified # 💂🏽‍♀ E4.0 woman guard: medium skin tone
+1F482 1F3FE 200D 2640 FE0F ; fully-qualified # 💂🏾‍♀️ E4.0 woman guard: medium-dark skin tone
+1F482 1F3FE 200D 2640 ; minimally-qualified # 💂🏾‍♀ E4.0 woman guard: medium-dark skin tone
+1F482 1F3FF 200D 2640 FE0F ; fully-qualified # 💂🏿‍♀️ E4.0 woman guard: dark skin tone
+1F482 1F3FF 200D 2640 ; minimally-qualified # 💂🏿‍♀ E4.0 woman guard: dark skin tone
+1F977 ; fully-qualified # 🥷 E13.0 ninja
+1F977 1F3FB ; fully-qualified # 🥷🏻 E13.0 ninja: light skin tone
+1F977 1F3FC ; fully-qualified # 🥷🏼 E13.0 ninja: medium-light skin tone
+1F977 1F3FD ; fully-qualified # 🥷🏽 E13.0 ninja: medium skin tone
+1F977 1F3FE ; fully-qualified # 🥷🏾 E13.0 ninja: medium-dark skin tone
+1F977 1F3FF ; fully-qualified # 🥷🏿 E13.0 ninja: dark skin tone
+1F477 ; fully-qualified # 👷 E0.6 construction worker
+1F477 1F3FB ; fully-qualified # 👷🏻 E1.0 construction worker: light skin tone
+1F477 1F3FC ; fully-qualified # 👷🏼 E1.0 construction worker: medium-light skin tone
+1F477 1F3FD ; fully-qualified # 👷🏽 E1.0 construction worker: medium skin tone
+1F477 1F3FE ; fully-qualified # 👷🏾 E1.0 construction worker: medium-dark skin tone
+1F477 1F3FF ; fully-qualified # 👷🏿 E1.0 construction worker: dark skin tone
+1F477 200D 2642 FE0F ; fully-qualified # 👷‍♂️ E4.0 man construction worker
+1F477 200D 2642 ; minimally-qualified # 👷‍♂ E4.0 man construction worker
+1F477 1F3FB 200D 2642 FE0F ; fully-qualified # 👷🏻‍♂️ E4.0 man construction worker: light skin tone
+1F477 1F3FB 200D 2642 ; minimally-qualified # 👷🏻‍♂ E4.0 man construction worker: light skin tone
+1F477 1F3FC 200D 2642 FE0F ; fully-qualified # 👷🏼‍♂️ E4.0 man construction worker: medium-light skin tone
+1F477 1F3FC 200D 2642 ; minimally-qualified # 👷🏼‍♂ E4.0 man construction worker: medium-light skin tone
+1F477 1F3FD 200D 2642 FE0F ; fully-qualified # 👷🏽‍♂️ E4.0 man construction worker: medium skin tone
+1F477 1F3FD 200D 2642 ; minimally-qualified # 👷🏽‍♂ E4.0 man construction worker: medium skin tone
+1F477 1F3FE 200D 2642 FE0F ; fully-qualified # 👷🏾‍♂️ E4.0 man construction worker: medium-dark skin tone
+1F477 1F3FE 200D 2642 ; minimally-qualified # 👷🏾‍♂ E4.0 man construction worker: medium-dark skin tone
+1F477 1F3FF 200D 2642 FE0F ; fully-qualified # 👷🏿‍♂️ E4.0 man construction worker: dark skin tone
+1F477 1F3FF 200D 2642 ; minimally-qualified # 👷🏿‍♂ E4.0 man construction worker: dark skin tone
+1F477 200D 2640 FE0F ; fully-qualified # 👷‍♀️ E4.0 woman construction worker
+1F477 200D 2640 ; minimally-qualified # 👷‍♀ E4.0 woman construction worker
+1F477 1F3FB 200D 2640 FE0F ; fully-qualified # 👷🏻‍♀️ E4.0 woman construction worker: light skin tone
+1F477 1F3FB 200D 2640 ; minimally-qualified # 👷🏻‍♀ E4.0 woman construction worker: light skin tone
+1F477 1F3FC 200D 2640 FE0F ; fully-qualified # 👷🏼‍♀️ E4.0 woman construction worker: medium-light skin tone
+1F477 1F3FC 200D 2640 ; minimally-qualified # 👷🏼‍♀ E4.0 woman construction worker: medium-light skin tone
+1F477 1F3FD 200D 2640 FE0F ; fully-qualified # 👷🏽‍♀️ E4.0 woman construction worker: medium skin tone
+1F477 1F3FD 200D 2640 ; minimally-qualified # 👷🏽‍♀ E4.0 woman construction worker: medium skin tone
+1F477 1F3FE 200D 2640 FE0F ; fully-qualified # 👷🏾‍♀️ E4.0 woman construction worker: medium-dark skin tone
+1F477 1F3FE 200D 2640 ; minimally-qualified # 👷🏾‍♀ E4.0 woman construction worker: medium-dark skin tone
+1F477 1F3FF 200D 2640 FE0F ; fully-qualified # 👷🏿‍♀️ E4.0 woman construction worker: dark skin tone
+1F477 1F3FF 200D 2640 ; minimally-qualified # 👷🏿‍♀ E4.0 woman construction worker: dark skin tone
+1FAC5 ; fully-qualified # 🫅 E14.0 person with crown
+1FAC5 1F3FB ; fully-qualified # 🫅🏻 E14.0 person with crown: light skin tone
+1FAC5 1F3FC ; fully-qualified # 🫅🏼 E14.0 person with crown: medium-light skin tone
+1FAC5 1F3FD ; fully-qualified # 🫅🏽 E14.0 person with crown: medium skin tone
+1FAC5 1F3FE ; fully-qualified # 🫅🏾 E14.0 person with crown: medium-dark skin tone
+1FAC5 1F3FF ; fully-qualified # 🫅🏿 E14.0 person with crown: dark skin tone
+1F934 ; fully-qualified # 🤴 E3.0 prince
+1F934 1F3FB ; fully-qualified # 🤴🏻 E3.0 prince: light skin tone
+1F934 1F3FC ; fully-qualified # 🤴🏼 E3.0 prince: medium-light skin tone
+1F934 1F3FD ; fully-qualified # 🤴🏽 E3.0 prince: medium skin tone
+1F934 1F3FE ; fully-qualified # 🤴🏾 E3.0 prince: medium-dark skin tone
+1F934 1F3FF ; fully-qualified # 🤴🏿 E3.0 prince: dark skin tone
+1F478 ; fully-qualified # 👸 E0.6 princess
+1F478 1F3FB ; fully-qualified # 👸🏻 E1.0 princess: light skin tone
+1F478 1F3FC ; fully-qualified # 👸🏼 E1.0 princess: medium-light skin tone
+1F478 1F3FD ; fully-qualified # 👸🏽 E1.0 princess: medium skin tone
+1F478 1F3FE ; fully-qualified # 👸🏾 E1.0 princess: medium-dark skin tone
+1F478 1F3FF ; fully-qualified # 👸🏿 E1.0 princess: dark skin tone
+1F473 ; fully-qualified # 👳 E0.6 person wearing turban
+1F473 1F3FB ; fully-qualified # 👳🏻 E1.0 person wearing turban: light skin tone
+1F473 1F3FC ; fully-qualified # 👳🏼 E1.0 person wearing turban: medium-light skin tone
+1F473 1F3FD ; fully-qualified # 👳🏽 E1.0 person wearing turban: medium skin tone
+1F473 1F3FE ; fully-qualified # 👳🏾 E1.0 person wearing turban: medium-dark skin tone
+1F473 1F3FF ; fully-qualified # 👳🏿 E1.0 person wearing turban: dark skin tone
+1F473 200D 2642 FE0F ; fully-qualified # 👳‍♂️ E4.0 man wearing turban
+1F473 200D 2642 ; minimally-qualified # 👳‍♂ E4.0 man wearing turban
+1F473 1F3FB 200D 2642 FE0F ; fully-qualified # 👳🏻‍♂️ E4.0 man wearing turban: light skin tone
+1F473 1F3FB 200D 2642 ; minimally-qualified # 👳🏻‍♂ E4.0 man wearing turban: light skin tone
+1F473 1F3FC 200D 2642 FE0F ; fully-qualified # 👳🏼‍♂️ E4.0 man wearing turban: medium-light skin tone
+1F473 1F3FC 200D 2642 ; minimally-qualified # 👳🏼‍♂ E4.0 man wearing turban: medium-light skin tone
+1F473 1F3FD 200D 2642 FE0F ; fully-qualified # 👳🏽‍♂️ E4.0 man wearing turban: medium skin tone
+1F473 1F3FD 200D 2642 ; minimally-qualified # 👳🏽‍♂ E4.0 man wearing turban: medium skin tone
+1F473 1F3FE 200D 2642 FE0F ; fully-qualified # 👳🏾‍♂️ E4.0 man wearing turban: medium-dark skin tone
+1F473 1F3FE 200D 2642 ; minimally-qualified # 👳🏾‍♂ E4.0 man wearing turban: medium-dark skin tone
+1F473 1F3FF 200D 2642 FE0F ; fully-qualified # 👳🏿‍♂️ E4.0 man wearing turban: dark skin tone
+1F473 1F3FF 200D 2642 ; minimally-qualified # 👳🏿‍♂ E4.0 man wearing turban: dark skin tone
+1F473 200D 2640 FE0F ; fully-qualified # 👳‍♀️ E4.0 woman wearing turban
+1F473 200D 2640 ; minimally-qualified # 👳‍♀ E4.0 woman wearing turban
+1F473 1F3FB 200D 2640 FE0F ; fully-qualified # 👳🏻‍♀️ E4.0 woman wearing turban: light skin tone
+1F473 1F3FB 200D 2640 ; minimally-qualified # 👳🏻‍♀ E4.0 woman wearing turban: light skin tone
+1F473 1F3FC 200D 2640 FE0F ; fully-qualified # 👳🏼‍♀️ E4.0 woman wearing turban: medium-light skin tone
+1F473 1F3FC 200D 2640 ; minimally-qualified # 👳🏼‍♀ E4.0 woman wearing turban: medium-light skin tone
+1F473 1F3FD 200D 2640 FE0F ; fully-qualified # 👳🏽‍♀️ E4.0 woman wearing turban: medium skin tone
+1F473 1F3FD 200D 2640 ; minimally-qualified # 👳🏽‍♀ E4.0 woman wearing turban: medium skin tone
+1F473 1F3FE 200D 2640 FE0F ; fully-qualified # 👳🏾‍♀️ E4.0 woman wearing turban: medium-dark skin tone
+1F473 1F3FE 200D 2640 ; minimally-qualified # 👳🏾‍♀ E4.0 woman wearing turban: medium-dark skin tone
+1F473 1F3FF 200D 2640 FE0F ; fully-qualified # 👳🏿‍♀️ E4.0 woman wearing turban: dark skin tone
+1F473 1F3FF 200D 2640 ; minimally-qualified # 👳🏿‍♀ E4.0 woman wearing turban: dark skin tone
+1F472 ; fully-qualified # 👲 E0.6 person with skullcap
+1F472 1F3FB ; fully-qualified # 👲🏻 E1.0 person with skullcap: light skin tone
+1F472 1F3FC ; fully-qualified # 👲🏼 E1.0 person with skullcap: medium-light skin tone
+1F472 1F3FD ; fully-qualified # 👲🏽 E1.0 person with skullcap: medium skin tone
+1F472 1F3FE ; fully-qualified # 👲🏾 E1.0 person with skullcap: medium-dark skin tone
+1F472 1F3FF ; fully-qualified # 👲🏿 E1.0 person with skullcap: dark skin tone
+1F9D5 ; fully-qualified # 🧕 E5.0 woman with headscarf
+1F9D5 1F3FB ; fully-qualified # 🧕🏻 E5.0 woman with headscarf: light skin tone
+1F9D5 1F3FC ; fully-qualified # 🧕🏼 E5.0 woman with headscarf: medium-light skin tone
+1F9D5 1F3FD ; fully-qualified # 🧕🏽 E5.0 woman with headscarf: medium skin tone
+1F9D5 1F3FE ; fully-qualified # 🧕🏾 E5.0 woman with headscarf: medium-dark skin tone
+1F9D5 1F3FF ; fully-qualified # 🧕🏿 E5.0 woman with headscarf: dark skin tone
+1F935 ; fully-qualified # 🤵 E3.0 person in tuxedo
+1F935 1F3FB ; fully-qualified # 🤵🏻 E3.0 person in tuxedo: light skin tone
+1F935 1F3FC ; fully-qualified # 🤵🏼 E3.0 person in tuxedo: medium-light skin tone
+1F935 1F3FD ; fully-qualified # 🤵🏽 E3.0 person in tuxedo: medium skin tone
+1F935 1F3FE ; fully-qualified # 🤵🏾 E3.0 person in tuxedo: medium-dark skin tone
+1F935 1F3FF ; fully-qualified # 🤵🏿 E3.0 person in tuxedo: dark skin tone
+1F935 200D 2642 FE0F ; fully-qualified # 🤵‍♂️ E13.0 man in tuxedo
+1F935 200D 2642 ; minimally-qualified # 🤵‍♂ E13.0 man in tuxedo
+1F935 1F3FB 200D 2642 FE0F ; fully-qualified # 🤵🏻‍♂️ E13.0 man in tuxedo: light skin tone
+1F935 1F3FB 200D 2642 ; minimally-qualified # 🤵🏻‍♂ E13.0 man in tuxedo: light skin tone
+1F935 1F3FC 200D 2642 FE0F ; fully-qualified # 🤵🏼‍♂️ E13.0 man in tuxedo: medium-light skin tone
+1F935 1F3FC 200D 2642 ; minimally-qualified # 🤵🏼‍♂ E13.0 man in tuxedo: medium-light skin tone
+1F935 1F3FD 200D 2642 FE0F ; fully-qualified # 🤵🏽‍♂️ E13.0 man in tuxedo: medium skin tone
+1F935 1F3FD 200D 2642 ; minimally-qualified # 🤵🏽‍♂ E13.0 man in tuxedo: medium skin tone
+1F935 1F3FE 200D 2642 FE0F ; fully-qualified # 🤵🏾‍♂️ E13.0 man in tuxedo: medium-dark skin tone
+1F935 1F3FE 200D 2642 ; minimally-qualified # 🤵🏾‍♂ E13.0 man in tuxedo: medium-dark skin tone
+1F935 1F3FF 200D 2642 FE0F ; fully-qualified # 🤵🏿‍♂️ E13.0 man in tuxedo: dark skin tone
+1F935 1F3FF 200D 2642 ; minimally-qualified # 🤵🏿‍♂ E13.0 man in tuxedo: dark skin tone
+1F935 200D 2640 FE0F ; fully-qualified # 🤵‍♀️ E13.0 woman in tuxedo
+1F935 200D 2640 ; minimally-qualified # 🤵‍♀ E13.0 woman in tuxedo
+1F935 1F3FB 200D 2640 FE0F ; fully-qualified # 🤵🏻‍♀️ E13.0 woman in tuxedo: light skin tone
+1F935 1F3FB 200D 2640 ; minimally-qualified # 🤵🏻‍♀ E13.0 woman in tuxedo: light skin tone
+1F935 1F3FC 200D 2640 FE0F ; fully-qualified # 🤵🏼‍♀️ E13.0 woman in tuxedo: medium-light skin tone
+1F935 1F3FC 200D 2640 ; minimally-qualified # 🤵🏼‍♀ E13.0 woman in tuxedo: medium-light skin tone
+1F935 1F3FD 200D 2640 FE0F ; fully-qualified # 🤵🏽‍♀️ E13.0 woman in tuxedo: medium skin tone
+1F935 1F3FD 200D 2640 ; minimally-qualified # 🤵🏽‍♀ E13.0 woman in tuxedo: medium skin tone
+1F935 1F3FE 200D 2640 FE0F ; fully-qualified # 🤵🏾‍♀️ E13.0 woman in tuxedo: medium-dark skin tone
+1F935 1F3FE 200D 2640 ; minimally-qualified # 🤵🏾‍♀ E13.0 woman in tuxedo: medium-dark skin tone
+1F935 1F3FF 200D 2640 FE0F ; fully-qualified # 🤵🏿‍♀️ E13.0 woman in tuxedo: dark skin tone
+1F935 1F3FF 200D 2640 ; minimally-qualified # 🤵🏿‍♀ E13.0 woman in tuxedo: dark skin tone
+1F470 ; fully-qualified # 👰 E0.6 person with veil
+1F470 1F3FB ; fully-qualified # 👰🏻 E1.0 person with veil: light skin tone
+1F470 1F3FC ; fully-qualified # 👰🏼 E1.0 person with veil: medium-light skin tone
+1F470 1F3FD ; fully-qualified # 👰🏽 E1.0 person with veil: medium skin tone
+1F470 1F3FE ; fully-qualified # 👰🏾 E1.0 person with veil: medium-dark skin tone
+1F470 1F3FF ; fully-qualified # 👰🏿 E1.0 person with veil: dark skin tone
+1F470 200D 2642 FE0F ; fully-qualified # 👰‍♂️ E13.0 man with veil
+1F470 200D 2642 ; minimally-qualified # 👰‍♂ E13.0 man with veil
+1F470 1F3FB 200D 2642 FE0F ; fully-qualified # 👰🏻‍♂️ E13.0 man with veil: light skin tone
+1F470 1F3FB 200D 2642 ; minimally-qualified # 👰🏻‍♂ E13.0 man with veil: light skin tone
+1F470 1F3FC 200D 2642 FE0F ; fully-qualified # 👰🏼‍♂️ E13.0 man with veil: medium-light skin tone
+1F470 1F3FC 200D 2642 ; minimally-qualified # 👰🏼‍♂ E13.0 man with veil: medium-light skin tone
+1F470 1F3FD 200D 2642 FE0F ; fully-qualified # 👰🏽‍♂️ E13.0 man with veil: medium skin tone
+1F470 1F3FD 200D 2642 ; minimally-qualified # 👰🏽‍♂ E13.0 man with veil: medium skin tone
+1F470 1F3FE 200D 2642 FE0F ; fully-qualified # 👰🏾‍♂️ E13.0 man with veil: medium-dark skin tone
+1F470 1F3FE 200D 2642 ; minimally-qualified # 👰🏾‍♂ E13.0 man with veil: medium-dark skin tone
+1F470 1F3FF 200D 2642 FE0F ; fully-qualified # 👰🏿‍♂️ E13.0 man with veil: dark skin tone
+1F470 1F3FF 200D 2642 ; minimally-qualified # 👰🏿‍♂ E13.0 man with veil: dark skin tone
+1F470 200D 2640 FE0F ; fully-qualified # 👰‍♀️ E13.0 woman with veil
+1F470 200D 2640 ; minimally-qualified # 👰‍♀ E13.0 woman with veil
+1F470 1F3FB 200D 2640 FE0F ; fully-qualified # 👰🏻‍♀️ E13.0 woman with veil: light skin tone
+1F470 1F3FB 200D 2640 ; minimally-qualified # 👰🏻‍♀ E13.0 woman with veil: light skin tone
+1F470 1F3FC 200D 2640 FE0F ; fully-qualified # 👰🏼‍♀️ E13.0 woman with veil: medium-light skin tone
+1F470 1F3FC 200D 2640 ; minimally-qualified # 👰🏼‍♀ E13.0 woman with veil: medium-light skin tone
+1F470 1F3FD 200D 2640 FE0F ; fully-qualified # 👰🏽‍♀️ E13.0 woman with veil: medium skin tone
+1F470 1F3FD 200D 2640 ; minimally-qualified # 👰🏽‍♀ E13.0 woman with veil: medium skin tone
+1F470 1F3FE 200D 2640 FE0F ; fully-qualified # 👰🏾‍♀️ E13.0 woman with veil: medium-dark skin tone
+1F470 1F3FE 200D 2640 ; minimally-qualified # 👰🏾‍♀ E13.0 woman with veil: medium-dark skin tone
+1F470 1F3FF 200D 2640 FE0F ; fully-qualified # 👰🏿‍♀️ E13.0 woman with veil: dark skin tone
+1F470 1F3FF 200D 2640 ; minimally-qualified # 👰🏿‍♀ E13.0 woman with veil: dark skin tone
+1F930 ; fully-qualified # 🤰 E3.0 pregnant woman
+1F930 1F3FB ; fully-qualified # 🤰🏻 E3.0 pregnant woman: light skin tone
+1F930 1F3FC ; fully-qualified # 🤰🏼 E3.0 pregnant woman: medium-light skin tone
+1F930 1F3FD ; fully-qualified # 🤰🏽 E3.0 pregnant woman: medium skin tone
+1F930 1F3FE ; fully-qualified # 🤰🏾 E3.0 pregnant woman: medium-dark skin tone
+1F930 1F3FF ; fully-qualified # 🤰🏿 E3.0 pregnant woman: dark skin tone
+1FAC3 ; fully-qualified # 🫃 E14.0 pregnant man
+1FAC3 1F3FB ; fully-qualified # 🫃🏻 E14.0 pregnant man: light skin tone
+1FAC3 1F3FC ; fully-qualified # 🫃🏼 E14.0 pregnant man: medium-light skin tone
+1FAC3 1F3FD ; fully-qualified # 🫃🏽 E14.0 pregnant man: medium skin tone
+1FAC3 1F3FE ; fully-qualified # 🫃🏾 E14.0 pregnant man: medium-dark skin tone
+1FAC3 1F3FF ; fully-qualified # 🫃🏿 E14.0 pregnant man: dark skin tone
+1FAC4 ; fully-qualified # 🫄 E14.0 pregnant person
+1FAC4 1F3FB ; fully-qualified # 🫄🏻 E14.0 pregnant person: light skin tone
+1FAC4 1F3FC ; fully-qualified # 🫄🏼 E14.0 pregnant person: medium-light skin tone
+1FAC4 1F3FD ; fully-qualified # 🫄🏽 E14.0 pregnant person: medium skin tone
+1FAC4 1F3FE ; fully-qualified # 🫄🏾 E14.0 pregnant person: medium-dark skin tone
+1FAC4 1F3FF ; fully-qualified # 🫄🏿 E14.0 pregnant person: dark skin tone
+1F931 ; fully-qualified # 🤱 E5.0 breast-feeding
+1F931 1F3FB ; fully-qualified # 🤱🏻 E5.0 breast-feeding: light skin tone
+1F931 1F3FC ; fully-qualified # 🤱🏼 E5.0 breast-feeding: medium-light skin tone
+1F931 1F3FD ; fully-qualified # 🤱🏽 E5.0 breast-feeding: medium skin tone
+1F931 1F3FE ; fully-qualified # 🤱🏾 E5.0 breast-feeding: medium-dark skin tone
+1F931 1F3FF ; fully-qualified # 🤱🏿 E5.0 breast-feeding: dark skin tone
+1F469 200D 1F37C ; fully-qualified # 👩‍🍼 E13.0 woman feeding baby
+1F469 1F3FB 200D 1F37C ; fully-qualified # 👩🏻‍🍼 E13.0 woman feeding baby: light skin tone
+1F469 1F3FC 200D 1F37C ; fully-qualified # 👩🏼‍🍼 E13.0 woman feeding baby: medium-light skin tone
+1F469 1F3FD 200D 1F37C ; fully-qualified # 👩🏽‍🍼 E13.0 woman feeding baby: medium skin tone
+1F469 1F3FE 200D 1F37C ; fully-qualified # 👩🏾‍🍼 E13.0 woman feeding baby: medium-dark skin tone
+1F469 1F3FF 200D 1F37C ; fully-qualified # 👩🏿‍🍼 E13.0 woman feeding baby: dark skin tone
+1F468 200D 1F37C ; fully-qualified # 👨‍🍼 E13.0 man feeding baby
+1F468 1F3FB 200D 1F37C ; fully-qualified # 👨🏻‍🍼 E13.0 man feeding baby: light skin tone
+1F468 1F3FC 200D 1F37C ; fully-qualified # 👨🏼‍🍼 E13.0 man feeding baby: medium-light skin tone
+1F468 1F3FD 200D 1F37C ; fully-qualified # 👨🏽‍🍼 E13.0 man feeding baby: medium skin tone
+1F468 1F3FE 200D 1F37C ; fully-qualified # 👨🏾‍🍼 E13.0 man feeding baby: medium-dark skin tone
+1F468 1F3FF 200D 1F37C ; fully-qualified # 👨🏿‍🍼 E13.0 man feeding baby: dark skin tone
+1F9D1 200D 1F37C ; fully-qualified # 🧑‍🍼 E13.0 person feeding baby
+1F9D1 1F3FB 200D 1F37C ; fully-qualified # 🧑🏻‍🍼 E13.0 person feeding baby: light skin tone
+1F9D1 1F3FC 200D 1F37C ; fully-qualified # 🧑🏼‍🍼 E13.0 person feeding baby: medium-light skin tone
+1F9D1 1F3FD 200D 1F37C ; fully-qualified # 🧑🏽‍🍼 E13.0 person feeding baby: medium skin tone
+1F9D1 1F3FE 200D 1F37C ; fully-qualified # 🧑🏾‍🍼 E13.0 person feeding baby: medium-dark skin tone
+1F9D1 1F3FF 200D 1F37C ; fully-qualified # 🧑🏿‍🍼 E13.0 person feeding baby: dark skin tone
+
+# subgroup: person-fantasy
+1F47C ; fully-qualified # 👼 E0.6 baby angel
+1F47C 1F3FB ; fully-qualified # 👼🏻 E1.0 baby angel: light skin tone
+1F47C 1F3FC ; fully-qualified # 👼🏼 E1.0 baby angel: medium-light skin tone
+1F47C 1F3FD ; fully-qualified # 👼🏽 E1.0 baby angel: medium skin tone
+1F47C 1F3FE ; fully-qualified # 👼🏾 E1.0 baby angel: medium-dark skin tone
+1F47C 1F3FF ; fully-qualified # 👼🏿 E1.0 baby angel: dark skin tone
+1F385 ; fully-qualified # 🎅 E0.6 Santa Claus
+1F385 1F3FB ; fully-qualified # 🎅🏻 E1.0 Santa Claus: light skin tone
+1F385 1F3FC ; fully-qualified # 🎅🏼 E1.0 Santa Claus: medium-light skin tone
+1F385 1F3FD ; fully-qualified # 🎅🏽 E1.0 Santa Claus: medium skin tone
+1F385 1F3FE ; fully-qualified # 🎅🏾 E1.0 Santa Claus: medium-dark skin tone
+1F385 1F3FF ; fully-qualified # 🎅🏿 E1.0 Santa Claus: dark skin tone
+1F936 ; fully-qualified # 🤶 E3.0 Mrs. Claus
+1F936 1F3FB ; fully-qualified # 🤶🏻 E3.0 Mrs. Claus: light skin tone
+1F936 1F3FC ; fully-qualified # 🤶🏼 E3.0 Mrs. Claus: medium-light skin tone
+1F936 1F3FD ; fully-qualified # 🤶🏽 E3.0 Mrs. Claus: medium skin tone
+1F936 1F3FE ; fully-qualified # 🤶🏾 E3.0 Mrs. Claus: medium-dark skin tone
+1F936 1F3FF ; fully-qualified # 🤶🏿 E3.0 Mrs. Claus: dark skin tone
+1F9D1 200D 1F384 ; fully-qualified # 🧑‍🎄 E13.0 mx claus
+1F9D1 1F3FB 200D 1F384 ; fully-qualified # 🧑🏻‍🎄 E13.0 mx claus: light skin tone
+1F9D1 1F3FC 200D 1F384 ; fully-qualified # 🧑🏼‍🎄 E13.0 mx claus: medium-light skin tone
+1F9D1 1F3FD 200D 1F384 ; fully-qualified # 🧑🏽‍🎄 E13.0 mx claus: medium skin tone
+1F9D1 1F3FE 200D 1F384 ; fully-qualified # 🧑🏾‍🎄 E13.0 mx claus: medium-dark skin tone
+1F9D1 1F3FF 200D 1F384 ; fully-qualified # 🧑🏿‍🎄 E13.0 mx claus: dark skin tone
+1F9B8 ; fully-qualified # 🦸 E11.0 superhero
+1F9B8 1F3FB ; fully-qualified # 🦸🏻 E11.0 superhero: light skin tone
+1F9B8 1F3FC ; fully-qualified # 🦸🏼 E11.0 superhero: medium-light skin tone
+1F9B8 1F3FD ; fully-qualified # 🦸🏽 E11.0 superhero: medium skin tone
+1F9B8 1F3FE ; fully-qualified # 🦸🏾 E11.0 superhero: medium-dark skin tone
+1F9B8 1F3FF ; fully-qualified # 🦸🏿 E11.0 superhero: dark skin tone
+1F9B8 200D 2642 FE0F ; fully-qualified # 🦸‍♂️ E11.0 man superhero
+1F9B8 200D 2642 ; minimally-qualified # 🦸‍♂ E11.0 man superhero
+1F9B8 1F3FB 200D 2642 FE0F ; fully-qualified # 🦸🏻‍♂️ E11.0 man superhero: light skin tone
+1F9B8 1F3FB 200D 2642 ; minimally-qualified # 🦸🏻‍♂ E11.0 man superhero: light skin tone
+1F9B8 1F3FC 200D 2642 FE0F ; fully-qualified # 🦸🏼‍♂️ E11.0 man superhero: medium-light skin tone
+1F9B8 1F3FC 200D 2642 ; minimally-qualified # 🦸🏼‍♂ E11.0 man superhero: medium-light skin tone
+1F9B8 1F3FD 200D 2642 FE0F ; fully-qualified # 🦸🏽‍♂️ E11.0 man superhero: medium skin tone
+1F9B8 1F3FD 200D 2642 ; minimally-qualified # 🦸🏽‍♂ E11.0 man superhero: medium skin tone
+1F9B8 1F3FE 200D 2642 FE0F ; fully-qualified # 🦸🏾‍♂️ E11.0 man superhero: medium-dark skin tone
+1F9B8 1F3FE 200D 2642 ; minimally-qualified # 🦸🏾‍♂ E11.0 man superhero: medium-dark skin tone
+1F9B8 1F3FF 200D 2642 FE0F ; fully-qualified # 🦸🏿‍♂️ E11.0 man superhero: dark skin tone
+1F9B8 1F3FF 200D 2642 ; minimally-qualified # 🦸🏿‍♂ E11.0 man superhero: dark skin tone
+1F9B8 200D 2640 FE0F ; fully-qualified # 🦸‍♀️ E11.0 woman superhero
+1F9B8 200D 2640 ; minimally-qualified # 🦸‍♀ E11.0 woman superhero
+1F9B8 1F3FB 200D 2640 FE0F ; fully-qualified # 🦸🏻‍♀️ E11.0 woman superhero: light skin tone
+1F9B8 1F3FB 200D 2640 ; minimally-qualified # 🦸🏻‍♀ E11.0 woman superhero: light skin tone
+1F9B8 1F3FC 200D 2640 FE0F ; fully-qualified # 🦸🏼‍♀️ E11.0 woman superhero: medium-light skin tone
+1F9B8 1F3FC 200D 2640 ; minimally-qualified # 🦸🏼‍♀ E11.0 woman superhero: medium-light skin tone
+1F9B8 1F3FD 200D 2640 FE0F ; fully-qualified # 🦸🏽‍♀️ E11.0 woman superhero: medium skin tone
+1F9B8 1F3FD 200D 2640 ; minimally-qualified # 🦸🏽‍♀ E11.0 woman superhero: medium skin tone
+1F9B8 1F3FE 200D 2640 FE0F ; fully-qualified # 🦸🏾‍♀️ E11.0 woman superhero: medium-dark skin tone
+1F9B8 1F3FE 200D 2640 ; minimally-qualified # 🦸🏾‍♀ E11.0 woman superhero: medium-dark skin tone
+1F9B8 1F3FF 200D 2640 FE0F ; fully-qualified # 🦸🏿‍♀️ E11.0 woman superhero: dark skin tone
+1F9B8 1F3FF 200D 2640 ; minimally-qualified # 🦸🏿‍♀ E11.0 woman superhero: dark skin tone
+1F9B9 ; fully-qualified # 🦹 E11.0 supervillain
+1F9B9 1F3FB ; fully-qualified # 🦹🏻 E11.0 supervillain: light skin tone
+1F9B9 1F3FC ; fully-qualified # 🦹🏼 E11.0 supervillain: medium-light skin tone
+1F9B9 1F3FD ; fully-qualified # 🦹🏽 E11.0 supervillain: medium skin tone
+1F9B9 1F3FE ; fully-qualified # 🦹🏾 E11.0 supervillain: medium-dark skin tone
+1F9B9 1F3FF ; fully-qualified # 🦹🏿 E11.0 supervillain: dark skin tone
+1F9B9 200D 2642 FE0F ; fully-qualified # 🦹‍♂️ E11.0 man supervillain
+1F9B9 200D 2642 ; minimally-qualified # 🦹‍♂ E11.0 man supervillain
+1F9B9 1F3FB 200D 2642 FE0F ; fully-qualified # 🦹🏻‍♂️ E11.0 man supervillain: light skin tone
+1F9B9 1F3FB 200D 2642 ; minimally-qualified # 🦹🏻‍♂ E11.0 man supervillain: light skin tone
+1F9B9 1F3FC 200D 2642 FE0F ; fully-qualified # 🦹🏼‍♂️ E11.0 man supervillain: medium-light skin tone
+1F9B9 1F3FC 200D 2642 ; minimally-qualified # 🦹🏼‍♂ E11.0 man supervillain: medium-light skin tone
+1F9B9 1F3FD 200D 2642 FE0F ; fully-qualified # 🦹🏽‍♂️ E11.0 man supervillain: medium skin tone
+1F9B9 1F3FD 200D 2642 ; minimally-qualified # 🦹🏽‍♂ E11.0 man supervillain: medium skin tone
+1F9B9 1F3FE 200D 2642 FE0F ; fully-qualified # 🦹🏾‍♂️ E11.0 man supervillain: medium-dark skin tone
+1F9B9 1F3FE 200D 2642 ; minimally-qualified # 🦹🏾‍♂ E11.0 man supervillain: medium-dark skin tone
+1F9B9 1F3FF 200D 2642 FE0F ; fully-qualified # 🦹🏿‍♂️ E11.0 man supervillain: dark skin tone
+1F9B9 1F3FF 200D 2642 ; minimally-qualified # 🦹🏿‍♂ E11.0 man supervillain: dark skin tone
+1F9B9 200D 2640 FE0F ; fully-qualified # 🦹‍♀️ E11.0 woman supervillain
+1F9B9 200D 2640 ; minimally-qualified # 🦹‍♀ E11.0 woman supervillain
+1F9B9 1F3FB 200D 2640 FE0F ; fully-qualified # 🦹🏻‍♀️ E11.0 woman supervillain: light skin tone
+1F9B9 1F3FB 200D 2640 ; minimally-qualified # 🦹🏻‍♀ E11.0 woman supervillain: light skin tone
+1F9B9 1F3FC 200D 2640 FE0F ; fully-qualified # 🦹🏼‍♀️ E11.0 woman supervillain: medium-light skin tone
+1F9B9 1F3FC 200D 2640 ; minimally-qualified # 🦹🏼‍♀ E11.0 woman supervillain: medium-light skin tone
+1F9B9 1F3FD 200D 2640 FE0F ; fully-qualified # 🦹🏽‍♀️ E11.0 woman supervillain: medium skin tone
+1F9B9 1F3FD 200D 2640 ; minimally-qualified # 🦹🏽‍♀ E11.0 woman supervillain: medium skin tone
+1F9B9 1F3FE 200D 2640 FE0F ; fully-qualified # 🦹🏾‍♀️ E11.0 woman supervillain: medium-dark skin tone
+1F9B9 1F3FE 200D 2640 ; minimally-qualified # 🦹🏾‍♀ E11.0 woman supervillain: medium-dark skin tone
+1F9B9 1F3FF 200D 2640 FE0F ; fully-qualified # 🦹🏿‍♀️ E11.0 woman supervillain: dark skin tone
+1F9B9 1F3FF 200D 2640 ; minimally-qualified # 🦹🏿‍♀ E11.0 woman supervillain: dark skin tone
+1F9D9 ; fully-qualified # 🧙 E5.0 mage
+1F9D9 1F3FB ; fully-qualified # 🧙🏻 E5.0 mage: light skin tone
+1F9D9 1F3FC ; fully-qualified # 🧙🏼 E5.0 mage: medium-light skin tone
+1F9D9 1F3FD ; fully-qualified # 🧙🏽 E5.0 mage: medium skin tone
+1F9D9 1F3FE ; fully-qualified # 🧙🏾 E5.0 mage: medium-dark skin tone
+1F9D9 1F3FF ; fully-qualified # 🧙🏿 E5.0 mage: dark skin tone
+1F9D9 200D 2642 FE0F ; fully-qualified # 🧙‍♂️ E5.0 man mage
+1F9D9 200D 2642 ; minimally-qualified # 🧙‍♂ E5.0 man mage
+1F9D9 1F3FB 200D 2642 FE0F ; fully-qualified # 🧙🏻‍♂️ E5.0 man mage: light skin tone
+1F9D9 1F3FB 200D 2642 ; minimally-qualified # 🧙🏻‍♂ E5.0 man mage: light skin tone
+1F9D9 1F3FC 200D 2642 FE0F ; fully-qualified # 🧙🏼‍♂️ E5.0 man mage: medium-light skin tone
+1F9D9 1F3FC 200D 2642 ; minimally-qualified # 🧙🏼‍♂ E5.0 man mage: medium-light skin tone
+1F9D9 1F3FD 200D 2642 FE0F ; fully-qualified # 🧙🏽‍♂️ E5.0 man mage: medium skin tone
+1F9D9 1F3FD 200D 2642 ; minimally-qualified # 🧙🏽‍♂ E5.0 man mage: medium skin tone
+1F9D9 1F3FE 200D 2642 FE0F ; fully-qualified # 🧙🏾‍♂️ E5.0 man mage: medium-dark skin tone
+1F9D9 1F3FE 200D 2642 ; minimally-qualified # 🧙🏾‍♂ E5.0 man mage: medium-dark skin tone
+1F9D9 1F3FF 200D 2642 FE0F ; fully-qualified # 🧙🏿‍♂️ E5.0 man mage: dark skin tone
+1F9D9 1F3FF 200D 2642 ; minimally-qualified # 🧙🏿‍♂ E5.0 man mage: dark skin tone
+1F9D9 200D 2640 FE0F ; fully-qualified # 🧙‍♀️ E5.0 woman mage
+1F9D9 200D 2640 ; minimally-qualified # 🧙‍♀ E5.0 woman mage
+1F9D9 1F3FB 200D 2640 FE0F ; fully-qualified # 🧙🏻‍♀️ E5.0 woman mage: light skin tone
+1F9D9 1F3FB 200D 2640 ; minimally-qualified # 🧙🏻‍♀ E5.0 woman mage: light skin tone
+1F9D9 1F3FC 200D 2640 FE0F ; fully-qualified # 🧙🏼‍♀️ E5.0 woman mage: medium-light skin tone
+1F9D9 1F3FC 200D 2640 ; minimally-qualified # 🧙🏼‍♀ E5.0 woman mage: medium-light skin tone
+1F9D9 1F3FD 200D 2640 FE0F ; fully-qualified # 🧙🏽‍♀️ E5.0 woman mage: medium skin tone
+1F9D9 1F3FD 200D 2640 ; minimally-qualified # 🧙🏽‍♀ E5.0 woman mage: medium skin tone
+1F9D9 1F3FE 200D 2640 FE0F ; fully-qualified # 🧙🏾‍♀️ E5.0 woman mage: medium-dark skin tone
+1F9D9 1F3FE 200D 2640 ; minimally-qualified # 🧙🏾‍♀ E5.0 woman mage: medium-dark skin tone
+1F9D9 1F3FF 200D 2640 FE0F ; fully-qualified # 🧙🏿‍♀️ E5.0 woman mage: dark skin tone
+1F9D9 1F3FF 200D 2640 ; minimally-qualified # 🧙🏿‍♀ E5.0 woman mage: dark skin tone
+1F9DA ; fully-qualified # 🧚 E5.0 fairy
+1F9DA 1F3FB ; fully-qualified # 🧚🏻 E5.0 fairy: light skin tone
+1F9DA 1F3FC ; fully-qualified # 🧚🏼 E5.0 fairy: medium-light skin tone
+1F9DA 1F3FD ; fully-qualified # 🧚🏽 E5.0 fairy: medium skin tone
+1F9DA 1F3FE ; fully-qualified # 🧚🏾 E5.0 fairy: medium-dark skin tone
+1F9DA 1F3FF ; fully-qualified # 🧚🏿 E5.0 fairy: dark skin tone
+1F9DA 200D 2642 FE0F ; fully-qualified # 🧚‍♂️ E5.0 man fairy
+1F9DA 200D 2642 ; minimally-qualified # 🧚‍♂ E5.0 man fairy
+1F9DA 1F3FB 200D 2642 FE0F ; fully-qualified # 🧚🏻‍♂️ E5.0 man fairy: light skin tone
+1F9DA 1F3FB 200D 2642 ; minimally-qualified # 🧚🏻‍♂ E5.0 man fairy: light skin tone
+1F9DA 1F3FC 200D 2642 FE0F ; fully-qualified # 🧚🏼‍♂️ E5.0 man fairy: medium-light skin tone
+1F9DA 1F3FC 200D 2642 ; minimally-qualified # 🧚🏼‍♂ E5.0 man fairy: medium-light skin tone
+1F9DA 1F3FD 200D 2642 FE0F ; fully-qualified # 🧚🏽‍♂️ E5.0 man fairy: medium skin tone
+1F9DA 1F3FD 200D 2642 ; minimally-qualified # 🧚🏽‍♂ E5.0 man fairy: medium skin tone
+1F9DA 1F3FE 200D 2642 FE0F ; fully-qualified # 🧚🏾‍♂️ E5.0 man fairy: medium-dark skin tone
+1F9DA 1F3FE 200D 2642 ; minimally-qualified # 🧚🏾‍♂ E5.0 man fairy: medium-dark skin tone
+1F9DA 1F3FF 200D 2642 FE0F ; fully-qualified # 🧚🏿‍♂️ E5.0 man fairy: dark skin tone
+1F9DA 1F3FF 200D 2642 ; minimally-qualified # 🧚🏿‍♂ E5.0 man fairy: dark skin tone
+1F9DA 200D 2640 FE0F ; fully-qualified # 🧚‍♀️ E5.0 woman fairy
+1F9DA 200D 2640 ; minimally-qualified # 🧚‍♀ E5.0 woman fairy
+1F9DA 1F3FB 200D 2640 FE0F ; fully-qualified # 🧚🏻‍♀️ E5.0 woman fairy: light skin tone
+1F9DA 1F3FB 200D 2640 ; minimally-qualified # 🧚🏻‍♀ E5.0 woman fairy: light skin tone
+1F9DA 1F3FC 200D 2640 FE0F ; fully-qualified # 🧚🏼‍♀️ E5.0 woman fairy: medium-light skin tone
+1F9DA 1F3FC 200D 2640 ; minimally-qualified # 🧚🏼‍♀ E5.0 woman fairy: medium-light skin tone
+1F9DA 1F3FD 200D 2640 FE0F ; fully-qualified # 🧚🏽‍♀️ E5.0 woman fairy: medium skin tone
+1F9DA 1F3FD 200D 2640 ; minimally-qualified # 🧚🏽‍♀ E5.0 woman fairy: medium skin tone
+1F9DA 1F3FE 200D 2640 FE0F ; fully-qualified # 🧚🏾‍♀️ E5.0 woman fairy: medium-dark skin tone
+1F9DA 1F3FE 200D 2640 ; minimally-qualified # 🧚🏾‍♀ E5.0 woman fairy: medium-dark skin tone
+1F9DA 1F3FF 200D 2640 FE0F ; fully-qualified # 🧚🏿‍♀️ E5.0 woman fairy: dark skin tone
+1F9DA 1F3FF 200D 2640 ; minimally-qualified # 🧚🏿‍♀ E5.0 woman fairy: dark skin tone
+1F9DB ; fully-qualified # 🧛 E5.0 vampire
+1F9DB 1F3FB ; fully-qualified # 🧛🏻 E5.0 vampire: light skin tone
+1F9DB 1F3FC ; fully-qualified # 🧛🏼 E5.0 vampire: medium-light skin tone
+1F9DB 1F3FD ; fully-qualified # 🧛🏽 E5.0 vampire: medium skin tone
+1F9DB 1F3FE ; fully-qualified # 🧛🏾 E5.0 vampire: medium-dark skin tone
+1F9DB 1F3FF ; fully-qualified # 🧛🏿 E5.0 vampire: dark skin tone
+1F9DB 200D 2642 FE0F ; fully-qualified # 🧛‍♂️ E5.0 man vampire
+1F9DB 200D 2642 ; minimally-qualified # 🧛‍♂ E5.0 man vampire
+1F9DB 1F3FB 200D 2642 FE0F ; fully-qualified # 🧛🏻‍♂️ E5.0 man vampire: light skin tone
+1F9DB 1F3FB 200D 2642 ; minimally-qualified # 🧛🏻‍♂ E5.0 man vampire: light skin tone
+1F9DB 1F3FC 200D 2642 FE0F ; fully-qualified # 🧛🏼‍♂️ E5.0 man vampire: medium-light skin tone
+1F9DB 1F3FC 200D 2642 ; minimally-qualified # 🧛🏼‍♂ E5.0 man vampire: medium-light skin tone
+1F9DB 1F3FD 200D 2642 FE0F ; fully-qualified # 🧛🏽‍♂️ E5.0 man vampire: medium skin tone
+1F9DB 1F3FD 200D 2642 ; minimally-qualified # 🧛🏽‍♂ E5.0 man vampire: medium skin tone
+1F9DB 1F3FE 200D 2642 FE0F ; fully-qualified # 🧛🏾‍♂️ E5.0 man vampire: medium-dark skin tone
+1F9DB 1F3FE 200D 2642 ; minimally-qualified # 🧛🏾‍♂ E5.0 man vampire: medium-dark skin tone
+1F9DB 1F3FF 200D 2642 FE0F ; fully-qualified # 🧛🏿‍♂️ E5.0 man vampire: dark skin tone
+1F9DB 1F3FF 200D 2642 ; minimally-qualified # 🧛🏿‍♂ E5.0 man vampire: dark skin tone
+1F9DB 200D 2640 FE0F ; fully-qualified # 🧛‍♀️ E5.0 woman vampire
+1F9DB 200D 2640 ; minimally-qualified # 🧛‍♀ E5.0 woman vampire
+1F9DB 1F3FB 200D 2640 FE0F ; fully-qualified # 🧛🏻‍♀️ E5.0 woman vampire: light skin tone
+1F9DB 1F3FB 200D 2640 ; minimally-qualified # 🧛🏻‍♀ E5.0 woman vampire: light skin tone
+1F9DB 1F3FC 200D 2640 FE0F ; fully-qualified # 🧛🏼‍♀️ E5.0 woman vampire: medium-light skin tone
+1F9DB 1F3FC 200D 2640 ; minimally-qualified # 🧛🏼‍♀ E5.0 woman vampire: medium-light skin tone
+1F9DB 1F3FD 200D 2640 FE0F ; fully-qualified # 🧛🏽‍♀️ E5.0 woman vampire: medium skin tone
+1F9DB 1F3FD 200D 2640 ; minimally-qualified # 🧛🏽‍♀ E5.0 woman vampire: medium skin tone
+1F9DB 1F3FE 200D 2640 FE0F ; fully-qualified # 🧛🏾‍♀️ E5.0 woman vampire: medium-dark skin tone
+1F9DB 1F3FE 200D 2640 ; minimally-qualified # 🧛🏾‍♀ E5.0 woman vampire: medium-dark skin tone
+1F9DB 1F3FF 200D 2640 FE0F ; fully-qualified # 🧛🏿‍♀️ E5.0 woman vampire: dark skin tone
+1F9DB 1F3FF 200D 2640 ; minimally-qualified # 🧛🏿‍♀ E5.0 woman vampire: dark skin tone
+1F9DC ; fully-qualified # 🧜 E5.0 merperson
+1F9DC 1F3FB ; fully-qualified # 🧜🏻 E5.0 merperson: light skin tone
+1F9DC 1F3FC ; fully-qualified # 🧜🏼 E5.0 merperson: medium-light skin tone
+1F9DC 1F3FD ; fully-qualified # 🧜🏽 E5.0 merperson: medium skin tone
+1F9DC 1F3FE ; fully-qualified # 🧜🏾 E5.0 merperson: medium-dark skin tone
+1F9DC 1F3FF ; fully-qualified # 🧜🏿 E5.0 merperson: dark skin tone
+1F9DC 200D 2642 FE0F ; fully-qualified # 🧜‍♂️ E5.0 merman
+1F9DC 200D 2642 ; minimally-qualified # 🧜‍♂ E5.0 merman
+1F9DC 1F3FB 200D 2642 FE0F ; fully-qualified # 🧜🏻‍♂️ E5.0 merman: light skin tone
+1F9DC 1F3FB 200D 2642 ; minimally-qualified # 🧜🏻‍♂ E5.0 merman: light skin tone
+1F9DC 1F3FC 200D 2642 FE0F ; fully-qualified # 🧜🏼‍♂️ E5.0 merman: medium-light skin tone
+1F9DC 1F3FC 200D 2642 ; minimally-qualified # 🧜🏼‍♂ E5.0 merman: medium-light skin tone
+1F9DC 1F3FD 200D 2642 FE0F ; fully-qualified # 🧜🏽‍♂️ E5.0 merman: medium skin tone
+1F9DC 1F3FD 200D 2642 ; minimally-qualified # 🧜🏽‍♂ E5.0 merman: medium skin tone
+1F9DC 1F3FE 200D 2642 FE0F ; fully-qualified # 🧜🏾‍♂️ E5.0 merman: medium-dark skin tone
+1F9DC 1F3FE 200D 2642 ; minimally-qualified # 🧜🏾‍♂ E5.0 merman: medium-dark skin tone
+1F9DC 1F3FF 200D 2642 FE0F ; fully-qualified # 🧜🏿‍♂️ E5.0 merman: dark skin tone
+1F9DC 1F3FF 200D 2642 ; minimally-qualified # 🧜🏿‍♂ E5.0 merman: dark skin tone
+1F9DC 200D 2640 FE0F ; fully-qualified # 🧜‍♀️ E5.0 mermaid
+1F9DC 200D 2640 ; minimally-qualified # 🧜‍♀ E5.0 mermaid
+1F9DC 1F3FB 200D 2640 FE0F ; fully-qualified # 🧜🏻‍♀️ E5.0 mermaid: light skin tone
+1F9DC 1F3FB 200D 2640 ; minimally-qualified # 🧜🏻‍♀ E5.0 mermaid: light skin tone
+1F9DC 1F3FC 200D 2640 FE0F ; fully-qualified # 🧜🏼‍♀️ E5.0 mermaid: medium-light skin tone
+1F9DC 1F3FC 200D 2640 ; minimally-qualified # 🧜🏼‍♀ E5.0 mermaid: medium-light skin tone
+1F9DC 1F3FD 200D 2640 FE0F ; fully-qualified # 🧜🏽‍♀️ E5.0 mermaid: medium skin tone
+1F9DC 1F3FD 200D 2640 ; minimally-qualified # 🧜🏽‍♀ E5.0 mermaid: medium skin tone
+1F9DC 1F3FE 200D 2640 FE0F ; fully-qualified # 🧜🏾‍♀️ E5.0 mermaid: medium-dark skin tone
+1F9DC 1F3FE 200D 2640 ; minimally-qualified # 🧜🏾‍♀ E5.0 mermaid: medium-dark skin tone
+1F9DC 1F3FF 200D 2640 FE0F ; fully-qualified # 🧜🏿‍♀️ E5.0 mermaid: dark skin tone
+1F9DC 1F3FF 200D 2640 ; minimally-qualified # 🧜🏿‍♀ E5.0 mermaid: dark skin tone
+1F9DD ; fully-qualified # 🧝 E5.0 elf
+1F9DD 1F3FB ; fully-qualified # 🧝🏻 E5.0 elf: light skin tone
+1F9DD 1F3FC ; fully-qualified # 🧝🏼 E5.0 elf: medium-light skin tone
+1F9DD 1F3FD ; fully-qualified # 🧝🏽 E5.0 elf: medium skin tone
+1F9DD 1F3FE ; fully-qualified # 🧝🏾 E5.0 elf: medium-dark skin tone
+1F9DD 1F3FF ; fully-qualified # 🧝🏿 E5.0 elf: dark skin tone
+1F9DD 200D 2642 FE0F ; fully-qualified # 🧝‍♂️ E5.0 man elf
+1F9DD 200D 2642 ; minimally-qualified # 🧝‍♂ E5.0 man elf
+1F9DD 1F3FB 200D 2642 FE0F ; fully-qualified # 🧝🏻‍♂️ E5.0 man elf: light skin tone
+1F9DD 1F3FB 200D 2642 ; minimally-qualified # 🧝🏻‍♂ E5.0 man elf: light skin tone
+1F9DD 1F3FC 200D 2642 FE0F ; fully-qualified # 🧝🏼‍♂️ E5.0 man elf: medium-light skin tone
+1F9DD 1F3FC 200D 2642 ; minimally-qualified # 🧝🏼‍♂ E5.0 man elf: medium-light skin tone
+1F9DD 1F3FD 200D 2642 FE0F ; fully-qualified # 🧝🏽‍♂️ E5.0 man elf: medium skin tone
+1F9DD 1F3FD 200D 2642 ; minimally-qualified # 🧝🏽‍♂ E5.0 man elf: medium skin tone
+1F9DD 1F3FE 200D 2642 FE0F ; fully-qualified # 🧝🏾‍♂️ E5.0 man elf: medium-dark skin tone
+1F9DD 1F3FE 200D 2642 ; minimally-qualified # 🧝🏾‍♂ E5.0 man elf: medium-dark skin tone
+1F9DD 1F3FF 200D 2642 FE0F ; fully-qualified # 🧝🏿‍♂️ E5.0 man elf: dark skin tone
+1F9DD 1F3FF 200D 2642 ; minimally-qualified # 🧝🏿‍♂ E5.0 man elf: dark skin tone
+1F9DD 200D 2640 FE0F ; fully-qualified # 🧝‍♀️ E5.0 woman elf
+1F9DD 200D 2640 ; minimally-qualified # 🧝‍♀ E5.0 woman elf
+1F9DD 1F3FB 200D 2640 FE0F ; fully-qualified # 🧝🏻‍♀️ E5.0 woman elf: light skin tone
+1F9DD 1F3FB 200D 2640 ; minimally-qualified # 🧝🏻‍♀ E5.0 woman elf: light skin tone
+1F9DD 1F3FC 200D 2640 FE0F ; fully-qualified # 🧝🏼‍♀️ E5.0 woman elf: medium-light skin tone
+1F9DD 1F3FC 200D 2640 ; minimally-qualified # 🧝🏼‍♀ E5.0 woman elf: medium-light skin tone
+1F9DD 1F3FD 200D 2640 FE0F ; fully-qualified # 🧝🏽‍♀️ E5.0 woman elf: medium skin tone
+1F9DD 1F3FD 200D 2640 ; minimally-qualified # 🧝🏽‍♀ E5.0 woman elf: medium skin tone
+1F9DD 1F3FE 200D 2640 FE0F ; fully-qualified # 🧝🏾‍♀️ E5.0 woman elf: medium-dark skin tone
+1F9DD 1F3FE 200D 2640 ; minimally-qualified # 🧝🏾‍♀ E5.0 woman elf: medium-dark skin tone
+1F9DD 1F3FF 200D 2640 FE0F ; fully-qualified # 🧝🏿‍♀️ E5.0 woman elf: dark skin tone
+1F9DD 1F3FF 200D 2640 ; minimally-qualified # 🧝🏿‍♀ E5.0 woman elf: dark skin tone
+1F9DE ; fully-qualified # 🧞 E5.0 genie
+1F9DE 200D 2642 FE0F ; fully-qualified # 🧞‍♂️ E5.0 man genie
+1F9DE 200D 2642 ; minimally-qualified # 🧞‍♂ E5.0 man genie
+1F9DE 200D 2640 FE0F ; fully-qualified # 🧞‍♀️ E5.0 woman genie
+1F9DE 200D 2640 ; minimally-qualified # 🧞‍♀ E5.0 woman genie
+1F9DF ; fully-qualified # 🧟 E5.0 zombie
+1F9DF 200D 2642 FE0F ; fully-qualified # 🧟‍♂️ E5.0 man zombie
+1F9DF 200D 2642 ; minimally-qualified # 🧟‍♂ E5.0 man zombie
+1F9DF 200D 2640 FE0F ; fully-qualified # 🧟‍♀️ E5.0 woman zombie
+1F9DF 200D 2640 ; minimally-qualified # 🧟‍♀ E5.0 woman zombie
+1F9CC ; fully-qualified # 🧌 E14.0 troll
+
+# subgroup: person-activity
+1F486 ; fully-qualified # 💆 E0.6 person getting massage
+1F486 1F3FB ; fully-qualified # 💆🏻 E1.0 person getting massage: light skin tone
+1F486 1F3FC ; fully-qualified # 💆🏼 E1.0 person getting massage: medium-light skin tone
+1F486 1F3FD ; fully-qualified # 💆🏽 E1.0 person getting massage: medium skin tone
+1F486 1F3FE ; fully-qualified # 💆🏾 E1.0 person getting massage: medium-dark skin tone
+1F486 1F3FF ; fully-qualified # 💆🏿 E1.0 person getting massage: dark skin tone
+1F486 200D 2642 FE0F ; fully-qualified # 💆‍♂️ E4.0 man getting massage
+1F486 200D 2642 ; minimally-qualified # 💆‍♂ E4.0 man getting massage
+1F486 1F3FB 200D 2642 FE0F ; fully-qualified # 💆🏻‍♂️ E4.0 man getting massage: light skin tone
+1F486 1F3FB 200D 2642 ; minimally-qualified # 💆🏻‍♂ E4.0 man getting massage: light skin tone
+1F486 1F3FC 200D 2642 FE0F ; fully-qualified # 💆🏼‍♂️ E4.0 man getting massage: medium-light skin tone
+1F486 1F3FC 200D 2642 ; minimally-qualified # 💆🏼‍♂ E4.0 man getting massage: medium-light skin tone
+1F486 1F3FD 200D 2642 FE0F ; fully-qualified # 💆🏽‍♂️ E4.0 man getting massage: medium skin tone
+1F486 1F3FD 200D 2642 ; minimally-qualified # 💆🏽‍♂ E4.0 man getting massage: medium skin tone
+1F486 1F3FE 200D 2642 FE0F ; fully-qualified # 💆🏾‍♂️ E4.0 man getting massage: medium-dark skin tone
+1F486 1F3FE 200D 2642 ; minimally-qualified # 💆🏾‍♂ E4.0 man getting massage: medium-dark skin tone
+1F486 1F3FF 200D 2642 FE0F ; fully-qualified # 💆🏿‍♂️ E4.0 man getting massage: dark skin tone
+1F486 1F3FF 200D 2642 ; minimally-qualified # 💆🏿‍♂ E4.0 man getting massage: dark skin tone
+1F486 200D 2640 FE0F ; fully-qualified # 💆‍♀️ E4.0 woman getting massage
+1F486 200D 2640 ; minimally-qualified # 💆‍♀ E4.0 woman getting massage
+1F486 1F3FB 200D 2640 FE0F ; fully-qualified # 💆🏻‍♀️ E4.0 woman getting massage: light skin tone
+1F486 1F3FB 200D 2640 ; minimally-qualified # 💆🏻‍♀ E4.0 woman getting massage: light skin tone
+1F486 1F3FC 200D 2640 FE0F ; fully-qualified # 💆🏼‍♀️ E4.0 woman getting massage: medium-light skin tone
+1F486 1F3FC 200D 2640 ; minimally-qualified # 💆🏼‍♀ E4.0 woman getting massage: medium-light skin tone
+1F486 1F3FD 200D 2640 FE0F ; fully-qualified # 💆🏽‍♀️ E4.0 woman getting massage: medium skin tone
+1F486 1F3FD 200D 2640 ; minimally-qualified # 💆🏽‍♀ E4.0 woman getting massage: medium skin tone
+1F486 1F3FE 200D 2640 FE0F ; fully-qualified # 💆🏾‍♀️ E4.0 woman getting massage: medium-dark skin tone
+1F486 1F3FE 200D 2640 ; minimally-qualified # 💆🏾‍♀ E4.0 woman getting massage: medium-dark skin tone
+1F486 1F3FF 200D 2640 FE0F ; fully-qualified # 💆🏿‍♀️ E4.0 woman getting massage: dark skin tone
+1F486 1F3FF 200D 2640 ; minimally-qualified # 💆🏿‍♀ E4.0 woman getting massage: dark skin tone
+1F487 ; fully-qualified # 💇 E0.6 person getting haircut
+1F487 1F3FB ; fully-qualified # 💇🏻 E1.0 person getting haircut: light skin tone
+1F487 1F3FC ; fully-qualified # 💇🏼 E1.0 person getting haircut: medium-light skin tone
+1F487 1F3FD ; fully-qualified # 💇🏽 E1.0 person getting haircut: medium skin tone
+1F487 1F3FE ; fully-qualified # 💇🏾 E1.0 person getting haircut: medium-dark skin tone
+1F487 1F3FF ; fully-qualified # 💇🏿 E1.0 person getting haircut: dark skin tone
+1F487 200D 2642 FE0F ; fully-qualified # 💇‍♂️ E4.0 man getting haircut
+1F487 200D 2642 ; minimally-qualified # 💇‍♂ E4.0 man getting haircut
+1F487 1F3FB 200D 2642 FE0F ; fully-qualified # 💇🏻‍♂️ E4.0 man getting haircut: light skin tone
+1F487 1F3FB 200D 2642 ; minimally-qualified # 💇🏻‍♂ E4.0 man getting haircut: light skin tone
+1F487 1F3FC 200D 2642 FE0F ; fully-qualified # 💇🏼‍♂️ E4.0 man getting haircut: medium-light skin tone
+1F487 1F3FC 200D 2642 ; minimally-qualified # 💇🏼‍♂ E4.0 man getting haircut: medium-light skin tone
+1F487 1F3FD 200D 2642 FE0F ; fully-qualified # 💇🏽‍♂️ E4.0 man getting haircut: medium skin tone
+1F487 1F3FD 200D 2642 ; minimally-qualified # 💇🏽‍♂ E4.0 man getting haircut: medium skin tone
+1F487 1F3FE 200D 2642 FE0F ; fully-qualified # 💇🏾‍♂️ E4.0 man getting haircut: medium-dark skin tone
+1F487 1F3FE 200D 2642 ; minimally-qualified # 💇🏾‍♂ E4.0 man getting haircut: medium-dark skin tone
+1F487 1F3FF 200D 2642 FE0F ; fully-qualified # 💇🏿‍♂️ E4.0 man getting haircut: dark skin tone
+1F487 1F3FF 200D 2642 ; minimally-qualified # 💇🏿‍♂ E4.0 man getting haircut: dark skin tone
+1F487 200D 2640 FE0F ; fully-qualified # 💇‍♀️ E4.0 woman getting haircut
+1F487 200D 2640 ; minimally-qualified # 💇‍♀ E4.0 woman getting haircut
+1F487 1F3FB 200D 2640 FE0F ; fully-qualified # 💇🏻‍♀️ E4.0 woman getting haircut: light skin tone
+1F487 1F3FB 200D 2640 ; minimally-qualified # 💇🏻‍♀ E4.0 woman getting haircut: light skin tone
+1F487 1F3FC 200D 2640 FE0F ; fully-qualified # 💇🏼‍♀️ E4.0 woman getting haircut: medium-light skin tone
+1F487 1F3FC 200D 2640 ; minimally-qualified # 💇🏼‍♀ E4.0 woman getting haircut: medium-light skin tone
+1F487 1F3FD 200D 2640 FE0F ; fully-qualified # 💇🏽‍♀️ E4.0 woman getting haircut: medium skin tone
+1F487 1F3FD 200D 2640 ; minimally-qualified # 💇🏽‍♀ E4.0 woman getting haircut: medium skin tone
+1F487 1F3FE 200D 2640 FE0F ; fully-qualified # 💇🏾‍♀️ E4.0 woman getting haircut: medium-dark skin tone
+1F487 1F3FE 200D 2640 ; minimally-qualified # 💇🏾‍♀ E4.0 woman getting haircut: medium-dark skin tone
+1F487 1F3FF 200D 2640 FE0F ; fully-qualified # 💇🏿‍♀️ E4.0 woman getting haircut: dark skin tone
+1F487 1F3FF 200D 2640 ; minimally-qualified # 💇🏿‍♀ E4.0 woman getting haircut: dark skin tone
+1F6B6 ; fully-qualified # 🚶 E0.6 person walking
+1F6B6 1F3FB ; fully-qualified # 🚶🏻 E1.0 person walking: light skin tone
+1F6B6 1F3FC ; fully-qualified # 🚶🏼 E1.0 person walking: medium-light skin tone
+1F6B6 1F3FD ; fully-qualified # 🚶🏽 E1.0 person walking: medium skin tone
+1F6B6 1F3FE ; fully-qualified # 🚶🏾 E1.0 person walking: medium-dark skin tone
+1F6B6 1F3FF ; fully-qualified # 🚶🏿 E1.0 person walking: dark skin tone
+1F6B6 200D 2642 FE0F ; fully-qualified # 🚶‍♂️ E4.0 man walking
+1F6B6 200D 2642 ; minimally-qualified # 🚶‍♂ E4.0 man walking
+1F6B6 1F3FB 200D 2642 FE0F ; fully-qualified # 🚶🏻‍♂️ E4.0 man walking: light skin tone
+1F6B6 1F3FB 200D 2642 ; minimally-qualified # 🚶🏻‍♂ E4.0 man walking: light skin tone
+1F6B6 1F3FC 200D 2642 FE0F ; fully-qualified # 🚶🏼‍♂️ E4.0 man walking: medium-light skin tone
+1F6B6 1F3FC 200D 2642 ; minimally-qualified # 🚶🏼‍♂ E4.0 man walking: medium-light skin tone
+1F6B6 1F3FD 200D 2642 FE0F ; fully-qualified # 🚶🏽‍♂️ E4.0 man walking: medium skin tone
+1F6B6 1F3FD 200D 2642 ; minimally-qualified # 🚶🏽‍♂ E4.0 man walking: medium skin tone
+1F6B6 1F3FE 200D 2642 FE0F ; fully-qualified # 🚶🏾‍♂️ E4.0 man walking: medium-dark skin tone
+1F6B6 1F3FE 200D 2642 ; minimally-qualified # 🚶🏾‍♂ E4.0 man walking: medium-dark skin tone
+1F6B6 1F3FF 200D 2642 FE0F ; fully-qualified # 🚶🏿‍♂️ E4.0 man walking: dark skin tone
+1F6B6 1F3FF 200D 2642 ; minimally-qualified # 🚶🏿‍♂ E4.0 man walking: dark skin tone
+1F6B6 200D 2640 FE0F ; fully-qualified # 🚶‍♀️ E4.0 woman walking
+1F6B6 200D 2640 ; minimally-qualified # 🚶‍♀ E4.0 woman walking
+1F6B6 1F3FB 200D 2640 FE0F ; fully-qualified # 🚶🏻‍♀️ E4.0 woman walking: light skin tone
+1F6B6 1F3FB 200D 2640 ; minimally-qualified # 🚶🏻‍♀ E4.0 woman walking: light skin tone
+1F6B6 1F3FC 200D 2640 FE0F ; fully-qualified # 🚶🏼‍♀️ E4.0 woman walking: medium-light skin tone
+1F6B6 1F3FC 200D 2640 ; minimally-qualified # 🚶🏼‍♀ E4.0 woman walking: medium-light skin tone
+1F6B6 1F3FD 200D 2640 FE0F ; fully-qualified # 🚶🏽‍♀️ E4.0 woman walking: medium skin tone
+1F6B6 1F3FD 200D 2640 ; minimally-qualified # 🚶🏽‍♀ E4.0 woman walking: medium skin tone
+1F6B6 1F3FE 200D 2640 FE0F ; fully-qualified # 🚶🏾‍♀️ E4.0 woman walking: medium-dark skin tone
+1F6B6 1F3FE 200D 2640 ; minimally-qualified # 🚶🏾‍♀ E4.0 woman walking: medium-dark skin tone
+1F6B6 1F3FF 200D 2640 FE0F ; fully-qualified # 🚶🏿‍♀️ E4.0 woman walking: dark skin tone
+1F6B6 1F3FF 200D 2640 ; minimally-qualified # 🚶🏿‍♀ E4.0 woman walking: dark skin tone
+1F9CD ; fully-qualified # 🧍 E12.0 person standing
+1F9CD 1F3FB ; fully-qualified # 🧍🏻 E12.0 person standing: light skin tone
+1F9CD 1F3FC ; fully-qualified # 🧍🏼 E12.0 person standing: medium-light skin tone
+1F9CD 1F3FD ; fully-qualified # 🧍🏽 E12.0 person standing: medium skin tone
+1F9CD 1F3FE ; fully-qualified # 🧍🏾 E12.0 person standing: medium-dark skin tone
+1F9CD 1F3FF ; fully-qualified # 🧍🏿 E12.0 person standing: dark skin tone
+1F9CD 200D 2642 FE0F ; fully-qualified # 🧍‍♂️ E12.0 man standing
+1F9CD 200D 2642 ; minimally-qualified # 🧍‍♂ E12.0 man standing
+1F9CD 1F3FB 200D 2642 FE0F ; fully-qualified # 🧍🏻‍♂️ E12.0 man standing: light skin tone
+1F9CD 1F3FB 200D 2642 ; minimally-qualified # 🧍🏻‍♂ E12.0 man standing: light skin tone
+1F9CD 1F3FC 200D 2642 FE0F ; fully-qualified # 🧍🏼‍♂️ E12.0 man standing: medium-light skin tone
+1F9CD 1F3FC 200D 2642 ; minimally-qualified # 🧍🏼‍♂ E12.0 man standing: medium-light skin tone
+1F9CD 1F3FD 200D 2642 FE0F ; fully-qualified # 🧍🏽‍♂️ E12.0 man standing: medium skin tone
+1F9CD 1F3FD 200D 2642 ; minimally-qualified # 🧍🏽‍♂ E12.0 man standing: medium skin tone
+1F9CD 1F3FE 200D 2642 FE0F ; fully-qualified # 🧍🏾‍♂️ E12.0 man standing: medium-dark skin tone
+1F9CD 1F3FE 200D 2642 ; minimally-qualified # 🧍🏾‍♂ E12.0 man standing: medium-dark skin tone
+1F9CD 1F3FF 200D 2642 FE0F ; fully-qualified # 🧍🏿‍♂️ E12.0 man standing: dark skin tone
+1F9CD 1F3FF 200D 2642 ; minimally-qualified # 🧍🏿‍♂ E12.0 man standing: dark skin tone
+1F9CD 200D 2640 FE0F ; fully-qualified # 🧍‍♀️ E12.0 woman standing
+1F9CD 200D 2640 ; minimally-qualified # 🧍‍♀ E12.0 woman standing
+1F9CD 1F3FB 200D 2640 FE0F ; fully-qualified # 🧍🏻‍♀️ E12.0 woman standing: light skin tone
+1F9CD 1F3FB 200D 2640 ; minimally-qualified # 🧍🏻‍♀ E12.0 woman standing: light skin tone
+1F9CD 1F3FC 200D 2640 FE0F ; fully-qualified # 🧍🏼‍♀️ E12.0 woman standing: medium-light skin tone
+1F9CD 1F3FC 200D 2640 ; minimally-qualified # 🧍🏼‍♀ E12.0 woman standing: medium-light skin tone
+1F9CD 1F3FD 200D 2640 FE0F ; fully-qualified # 🧍🏽‍♀️ E12.0 woman standing: medium skin tone
+1F9CD 1F3FD 200D 2640 ; minimally-qualified # 🧍🏽‍♀ E12.0 woman standing: medium skin tone
+1F9CD 1F3FE 200D 2640 FE0F ; fully-qualified # 🧍🏾‍♀️ E12.0 woman standing: medium-dark skin tone
+1F9CD 1F3FE 200D 2640 ; minimally-qualified # 🧍🏾‍♀ E12.0 woman standing: medium-dark skin tone
+1F9CD 1F3FF 200D 2640 FE0F ; fully-qualified # 🧍🏿‍♀️ E12.0 woman standing: dark skin tone
+1F9CD 1F3FF 200D 2640 ; minimally-qualified # 🧍🏿‍♀ E12.0 woman standing: dark skin tone
+1F9CE ; fully-qualified # 🧎 E12.0 person kneeling
+1F9CE 1F3FB ; fully-qualified # 🧎🏻 E12.0 person kneeling: light skin tone
+1F9CE 1F3FC ; fully-qualified # 🧎🏼 E12.0 person kneeling: medium-light skin tone
+1F9CE 1F3FD ; fully-qualified # 🧎🏽 E12.0 person kneeling: medium skin tone
+1F9CE 1F3FE ; fully-qualified # 🧎🏾 E12.0 person kneeling: medium-dark skin tone
+1F9CE 1F3FF ; fully-qualified # 🧎🏿 E12.0 person kneeling: dark skin tone
+1F9CE 200D 2642 FE0F ; fully-qualified # 🧎‍♂️ E12.0 man kneeling
+1F9CE 200D 2642 ; minimally-qualified # 🧎‍♂ E12.0 man kneeling
+1F9CE 1F3FB 200D 2642 FE0F ; fully-qualified # 🧎🏻‍♂️ E12.0 man kneeling: light skin tone
+1F9CE 1F3FB 200D 2642 ; minimally-qualified # 🧎🏻‍♂ E12.0 man kneeling: light skin tone
+1F9CE 1F3FC 200D 2642 FE0F ; fully-qualified # 🧎🏼‍♂️ E12.0 man kneeling: medium-light skin tone
+1F9CE 1F3FC 200D 2642 ; minimally-qualified # 🧎🏼‍♂ E12.0 man kneeling: medium-light skin tone
+1F9CE 1F3FD 200D 2642 FE0F ; fully-qualified # 🧎🏽‍♂️ E12.0 man kneeling: medium skin tone
+1F9CE 1F3FD 200D 2642 ; minimally-qualified # 🧎🏽‍♂ E12.0 man kneeling: medium skin tone
+1F9CE 1F3FE 200D 2642 FE0F ; fully-qualified # 🧎🏾‍♂️ E12.0 man kneeling: medium-dark skin tone
+1F9CE 1F3FE 200D 2642 ; minimally-qualified # 🧎🏾‍♂ E12.0 man kneeling: medium-dark skin tone
+1F9CE 1F3FF 200D 2642 FE0F ; fully-qualified # 🧎🏿‍♂️ E12.0 man kneeling: dark skin tone
+1F9CE 1F3FF 200D 2642 ; minimally-qualified # 🧎🏿‍♂ E12.0 man kneeling: dark skin tone
+1F9CE 200D 2640 FE0F ; fully-qualified # 🧎‍♀️ E12.0 woman kneeling
+1F9CE 200D 2640 ; minimally-qualified # 🧎‍♀ E12.0 woman kneeling
+1F9CE 1F3FB 200D 2640 FE0F ; fully-qualified # 🧎🏻‍♀️ E12.0 woman kneeling: light skin tone
+1F9CE 1F3FB 200D 2640 ; minimally-qualified # 🧎🏻‍♀ E12.0 woman kneeling: light skin tone
+1F9CE 1F3FC 200D 2640 FE0F ; fully-qualified # 🧎🏼‍♀️ E12.0 woman kneeling: medium-light skin tone
+1F9CE 1F3FC 200D 2640 ; minimally-qualified # 🧎🏼‍♀ E12.0 woman kneeling: medium-light skin tone
+1F9CE 1F3FD 200D 2640 FE0F ; fully-qualified # 🧎🏽‍♀️ E12.0 woman kneeling: medium skin tone
+1F9CE 1F3FD 200D 2640 ; minimally-qualified # 🧎🏽‍♀ E12.0 woman kneeling: medium skin tone
+1F9CE 1F3FE 200D 2640 FE0F ; fully-qualified # 🧎🏾‍♀️ E12.0 woman kneeling: medium-dark skin tone
+1F9CE 1F3FE 200D 2640 ; minimally-qualified # 🧎🏾‍♀ E12.0 woman kneeling: medium-dark skin tone
+1F9CE 1F3FF 200D 2640 FE0F ; fully-qualified # 🧎🏿‍♀️ E12.0 woman kneeling: dark skin tone
+1F9CE 1F3FF 200D 2640 ; minimally-qualified # 🧎🏿‍♀ E12.0 woman kneeling: dark skin tone
+1F9D1 200D 1F9AF ; fully-qualified # 🧑‍🦯 E12.1 person with white cane
+1F9D1 1F3FB 200D 1F9AF ; fully-qualified # 🧑🏻‍🦯 E12.1 person with white cane: light skin tone
+1F9D1 1F3FC 200D 1F9AF ; fully-qualified # 🧑🏼‍🦯 E12.1 person with white cane: medium-light skin tone
+1F9D1 1F3FD 200D 1F9AF ; fully-qualified # 🧑🏽‍🦯 E12.1 person with white cane: medium skin tone
+1F9D1 1F3FE 200D 1F9AF ; fully-qualified # 🧑🏾‍🦯 E12.1 person with white cane: medium-dark skin tone
+1F9D1 1F3FF 200D 1F9AF ; fully-qualified # 🧑🏿‍🦯 E12.1 person with white cane: dark skin tone
+1F468 200D 1F9AF ; fully-qualified # 👨‍🦯 E12.0 man with white cane
+1F468 1F3FB 200D 1F9AF ; fully-qualified # 👨🏻‍🦯 E12.0 man with white cane: light skin tone
+1F468 1F3FC 200D 1F9AF ; fully-qualified # 👨🏼‍🦯 E12.0 man with white cane: medium-light skin tone
+1F468 1F3FD 200D 1F9AF ; fully-qualified # 👨🏽‍🦯 E12.0 man with white cane: medium skin tone
+1F468 1F3FE 200D 1F9AF ; fully-qualified # 👨🏾‍🦯 E12.0 man with white cane: medium-dark skin tone
+1F468 1F3FF 200D 1F9AF ; fully-qualified # 👨🏿‍🦯 E12.0 man with white cane: dark skin tone
+1F469 200D 1F9AF ; fully-qualified # 👩‍🦯 E12.0 woman with white cane
+1F469 1F3FB 200D 1F9AF ; fully-qualified # 👩🏻‍🦯 E12.0 woman with white cane: light skin tone
+1F469 1F3FC 200D 1F9AF ; fully-qualified # 👩🏼‍🦯 E12.0 woman with white cane: medium-light skin tone
+1F469 1F3FD 200D 1F9AF ; fully-qualified # 👩🏽‍🦯 E12.0 woman with white cane: medium skin tone
+1F469 1F3FE 200D 1F9AF ; fully-qualified # 👩🏾‍🦯 E12.0 woman with white cane: medium-dark skin tone
+1F469 1F3FF 200D 1F9AF ; fully-qualified # 👩🏿‍🦯 E12.0 woman with white cane: dark skin tone
+1F9D1 200D 1F9BC ; fully-qualified # 🧑‍🦼 E12.1 person in motorized wheelchair
+1F9D1 1F3FB 200D 1F9BC ; fully-qualified # 🧑🏻‍🦼 E12.1 person in motorized wheelchair: light skin tone
+1F9D1 1F3FC 200D 1F9BC ; fully-qualified # 🧑🏼‍🦼 E12.1 person in motorized wheelchair: medium-light skin tone
+1F9D1 1F3FD 200D 1F9BC ; fully-qualified # 🧑🏽‍🦼 E12.1 person in motorized wheelchair: medium skin tone
+1F9D1 1F3FE 200D 1F9BC ; fully-qualified # 🧑🏾‍🦼 E12.1 person in motorized wheelchair: medium-dark skin tone
+1F9D1 1F3FF 200D 1F9BC ; fully-qualified # 🧑🏿‍🦼 E12.1 person in motorized wheelchair: dark skin tone
+1F468 200D 1F9BC ; fully-qualified # 👨‍🦼 E12.0 man in motorized wheelchair
+1F468 1F3FB 200D 1F9BC ; fully-qualified # 👨🏻‍🦼 E12.0 man in motorized wheelchair: light skin tone
+1F468 1F3FC 200D 1F9BC ; fully-qualified # 👨🏼‍🦼 E12.0 man in motorized wheelchair: medium-light skin tone
+1F468 1F3FD 200D 1F9BC ; fully-qualified # 👨🏽‍🦼 E12.0 man in motorized wheelchair: medium skin tone
+1F468 1F3FE 200D 1F9BC ; fully-qualified # 👨🏾‍🦼 E12.0 man in motorized wheelchair: medium-dark skin tone
+1F468 1F3FF 200D 1F9BC ; fully-qualified # 👨🏿‍🦼 E12.0 man in motorized wheelchair: dark skin tone
+1F469 200D 1F9BC ; fully-qualified # 👩‍🦼 E12.0 woman in motorized wheelchair
+1F469 1F3FB 200D 1F9BC ; fully-qualified # 👩🏻‍🦼 E12.0 woman in motorized wheelchair: light skin tone
+1F469 1F3FC 200D 1F9BC ; fully-qualified # 👩🏼‍🦼 E12.0 woman in motorized wheelchair: medium-light skin tone
+1F469 1F3FD 200D 1F9BC ; fully-qualified # 👩🏽‍🦼 E12.0 woman in motorized wheelchair: medium skin tone
+1F469 1F3FE 200D 1F9BC ; fully-qualified # 👩🏾‍🦼 E12.0 woman in motorized wheelchair: medium-dark skin tone
+1F469 1F3FF 200D 1F9BC ; fully-qualified # 👩🏿‍🦼 E12.0 woman in motorized wheelchair: dark skin tone
+1F9D1 200D 1F9BD ; fully-qualified # 🧑‍🦽 E12.1 person in manual wheelchair
+1F9D1 1F3FB 200D 1F9BD ; fully-qualified # 🧑🏻‍🦽 E12.1 person in manual wheelchair: light skin tone
+1F9D1 1F3FC 200D 1F9BD ; fully-qualified # 🧑🏼‍🦽 E12.1 person in manual wheelchair: medium-light skin tone
+1F9D1 1F3FD 200D 1F9BD ; fully-qualified # 🧑🏽‍🦽 E12.1 person in manual wheelchair: medium skin tone
+1F9D1 1F3FE 200D 1F9BD ; fully-qualified # 🧑🏾‍🦽 E12.1 person in manual wheelchair: medium-dark skin tone
+1F9D1 1F3FF 200D 1F9BD ; fully-qualified # 🧑🏿‍🦽 E12.1 person in manual wheelchair: dark skin tone
+1F468 200D 1F9BD ; fully-qualified # 👨‍🦽 E12.0 man in manual wheelchair
+1F468 1F3FB 200D 1F9BD ; fully-qualified # 👨🏻‍🦽 E12.0 man in manual wheelchair: light skin tone
+1F468 1F3FC 200D 1F9BD ; fully-qualified # 👨🏼‍🦽 E12.0 man in manual wheelchair: medium-light skin tone
+1F468 1F3FD 200D 1F9BD ; fully-qualified # 👨🏽‍🦽 E12.0 man in manual wheelchair: medium skin tone
+1F468 1F3FE 200D 1F9BD ; fully-qualified # 👨🏾‍🦽 E12.0 man in manual wheelchair: medium-dark skin tone
+1F468 1F3FF 200D 1F9BD ; fully-qualified # 👨🏿‍🦽 E12.0 man in manual wheelchair: dark skin tone
+1F469 200D 1F9BD ; fully-qualified # 👩‍🦽 E12.0 woman in manual wheelchair
+1F469 1F3FB 200D 1F9BD ; fully-qualified # 👩🏻‍🦽 E12.0 woman in manual wheelchair: light skin tone
+1F469 1F3FC 200D 1F9BD ; fully-qualified # 👩🏼‍🦽 E12.0 woman in manual wheelchair: medium-light skin tone
+1F469 1F3FD 200D 1F9BD ; fully-qualified # 👩🏽‍🦽 E12.0 woman in manual wheelchair: medium skin tone
+1F469 1F3FE 200D 1F9BD ; fully-qualified # 👩🏾‍🦽 E12.0 woman in manual wheelchair: medium-dark skin tone
+1F469 1F3FF 200D 1F9BD ; fully-qualified # 👩🏿‍🦽 E12.0 woman in manual wheelchair: dark skin tone
+1F3C3 ; fully-qualified # 🏃 E0.6 person running
+1F3C3 1F3FB ; fully-qualified # 🏃🏻 E1.0 person running: light skin tone
+1F3C3 1F3FC ; fully-qualified # 🏃🏼 E1.0 person running: medium-light skin tone
+1F3C3 1F3FD ; fully-qualified # 🏃🏽 E1.0 person running: medium skin tone
+1F3C3 1F3FE ; fully-qualified # 🏃🏾 E1.0 person running: medium-dark skin tone
+1F3C3 1F3FF ; fully-qualified # 🏃🏿 E1.0 person running: dark skin tone
+1F3C3 200D 2642 FE0F ; fully-qualified # 🏃‍♂️ E4.0 man running
+1F3C3 200D 2642 ; minimally-qualified # 🏃‍♂ E4.0 man running
+1F3C3 1F3FB 200D 2642 FE0F ; fully-qualified # 🏃🏻‍♂️ E4.0 man running: light skin tone
+1F3C3 1F3FB 200D 2642 ; minimally-qualified # 🏃🏻‍♂ E4.0 man running: light skin tone
+1F3C3 1F3FC 200D 2642 FE0F ; fully-qualified # 🏃🏼‍♂️ E4.0 man running: medium-light skin tone
+1F3C3 1F3FC 200D 2642 ; minimally-qualified # 🏃🏼‍♂ E4.0 man running: medium-light skin tone
+1F3C3 1F3FD 200D 2642 FE0F ; fully-qualified # 🏃🏽‍♂️ E4.0 man running: medium skin tone
+1F3C3 1F3FD 200D 2642 ; minimally-qualified # 🏃🏽‍♂ E4.0 man running: medium skin tone
+1F3C3 1F3FE 200D 2642 FE0F ; fully-qualified # 🏃🏾‍♂️ E4.0 man running: medium-dark skin tone
+1F3C3 1F3FE 200D 2642 ; minimally-qualified # 🏃🏾‍♂ E4.0 man running: medium-dark skin tone
+1F3C3 1F3FF 200D 2642 FE0F ; fully-qualified # 🏃🏿‍♂️ E4.0 man running: dark skin tone
+1F3C3 1F3FF 200D 2642 ; minimally-qualified # 🏃🏿‍♂ E4.0 man running: dark skin tone
+1F3C3 200D 2640 FE0F ; fully-qualified # 🏃‍♀️ E4.0 woman running
+1F3C3 200D 2640 ; minimally-qualified # 🏃‍♀ E4.0 woman running
+1F3C3 1F3FB 200D 2640 FE0F ; fully-qualified # 🏃🏻‍♀️ E4.0 woman running: light skin tone
+1F3C3 1F3FB 200D 2640 ; minimally-qualified # 🏃🏻‍♀ E4.0 woman running: light skin tone
+1F3C3 1F3FC 200D 2640 FE0F ; fully-qualified # 🏃🏼‍♀️ E4.0 woman running: medium-light skin tone
+1F3C3 1F3FC 200D 2640 ; minimally-qualified # 🏃🏼‍♀ E4.0 woman running: medium-light skin tone
+1F3C3 1F3FD 200D 2640 FE0F ; fully-qualified # 🏃🏽‍♀️ E4.0 woman running: medium skin tone
+1F3C3 1F3FD 200D 2640 ; minimally-qualified # 🏃🏽‍♀ E4.0 woman running: medium skin tone
+1F3C3 1F3FE 200D 2640 FE0F ; fully-qualified # 🏃🏾‍♀️ E4.0 woman running: medium-dark skin tone
+1F3C3 1F3FE 200D 2640 ; minimally-qualified # 🏃🏾‍♀ E4.0 woman running: medium-dark skin tone
+1F3C3 1F3FF 200D 2640 FE0F ; fully-qualified # 🏃🏿‍♀️ E4.0 woman running: dark skin tone
+1F3C3 1F3FF 200D 2640 ; minimally-qualified # 🏃🏿‍♀ E4.0 woman running: dark skin tone
+1F483 ; fully-qualified # 💃 E0.6 woman dancing
+1F483 1F3FB ; fully-qualified # 💃🏻 E1.0 woman dancing: light skin tone
+1F483 1F3FC ; fully-qualified # 💃🏼 E1.0 woman dancing: medium-light skin tone
+1F483 1F3FD ; fully-qualified # 💃🏽 E1.0 woman dancing: medium skin tone
+1F483 1F3FE ; fully-qualified # 💃🏾 E1.0 woman dancing: medium-dark skin tone
+1F483 1F3FF ; fully-qualified # 💃🏿 E1.0 woman dancing: dark skin tone
+1F57A ; fully-qualified # 🕺 E3.0 man dancing
+1F57A 1F3FB ; fully-qualified # 🕺🏻 E3.0 man dancing: light skin tone
+1F57A 1F3FC ; fully-qualified # 🕺🏼 E3.0 man dancing: medium-light skin tone
+1F57A 1F3FD ; fully-qualified # 🕺🏽 E3.0 man dancing: medium skin tone
+1F57A 1F3FE ; fully-qualified # 🕺🏾 E3.0 man dancing: medium-dark skin tone
+1F57A 1F3FF ; fully-qualified # 🕺🏿 E3.0 man dancing: dark skin tone
+1F574 FE0F ; fully-qualified # 🕴️ E0.7 person in suit levitating
+1F574 ; unqualified # 🕴 E0.7 person in suit levitating
+1F574 1F3FB ; fully-qualified # 🕴🏻 E4.0 person in suit levitating: light skin tone
+1F574 1F3FC ; fully-qualified # 🕴🏼 E4.0 person in suit levitating: medium-light skin tone
+1F574 1F3FD ; fully-qualified # 🕴🏽 E4.0 person in suit levitating: medium skin tone
+1F574 1F3FE ; fully-qualified # 🕴🏾 E4.0 person in suit levitating: medium-dark skin tone
+1F574 1F3FF ; fully-qualified # 🕴🏿 E4.0 person in suit levitating: dark skin tone
+1F46F ; fully-qualified # 👯 E0.6 people with bunny ears
+1F46F 200D 2642 FE0F ; fully-qualified # 👯‍♂️ E4.0 men with bunny ears
+1F46F 200D 2642 ; minimally-qualified # 👯‍♂ E4.0 men with bunny ears
+1F46F 200D 2640 FE0F ; fully-qualified # 👯‍♀️ E4.0 women with bunny ears
+1F46F 200D 2640 ; minimally-qualified # 👯‍♀ E4.0 women with bunny ears
+1F9D6 ; fully-qualified # 🧖 E5.0 person in steamy room
+1F9D6 1F3FB ; fully-qualified # 🧖🏻 E5.0 person in steamy room: light skin tone
+1F9D6 1F3FC ; fully-qualified # 🧖🏼 E5.0 person in steamy room: medium-light skin tone
+1F9D6 1F3FD ; fully-qualified # 🧖🏽 E5.0 person in steamy room: medium skin tone
+1F9D6 1F3FE ; fully-qualified # 🧖🏾 E5.0 person in steamy room: medium-dark skin tone
+1F9D6 1F3FF ; fully-qualified # 🧖🏿 E5.0 person in steamy room: dark skin tone
+1F9D6 200D 2642 FE0F ; fully-qualified # 🧖‍♂️ E5.0 man in steamy room
+1F9D6 200D 2642 ; minimally-qualified # 🧖‍♂ E5.0 man in steamy room
+1F9D6 1F3FB 200D 2642 FE0F ; fully-qualified # 🧖🏻‍♂️ E5.0 man in steamy room: light skin tone
+1F9D6 1F3FB 200D 2642 ; minimally-qualified # 🧖🏻‍♂ E5.0 man in steamy room: light skin tone
+1F9D6 1F3FC 200D 2642 FE0F ; fully-qualified # 🧖🏼‍♂️ E5.0 man in steamy room: medium-light skin tone
+1F9D6 1F3FC 200D 2642 ; minimally-qualified # 🧖🏼‍♂ E5.0 man in steamy room: medium-light skin tone
+1F9D6 1F3FD 200D 2642 FE0F ; fully-qualified # 🧖🏽‍♂️ E5.0 man in steamy room: medium skin tone
+1F9D6 1F3FD 200D 2642 ; minimally-qualified # 🧖🏽‍♂ E5.0 man in steamy room: medium skin tone
+1F9D6 1F3FE 200D 2642 FE0F ; fully-qualified # 🧖🏾‍♂️ E5.0 man in steamy room: medium-dark skin tone
+1F9D6 1F3FE 200D 2642 ; minimally-qualified # 🧖🏾‍♂ E5.0 man in steamy room: medium-dark skin tone
+1F9D6 1F3FF 200D 2642 FE0F ; fully-qualified # 🧖🏿‍♂️ E5.0 man in steamy room: dark skin tone
+1F9D6 1F3FF 200D 2642 ; minimally-qualified # 🧖🏿‍♂ E5.0 man in steamy room: dark skin tone
+1F9D6 200D 2640 FE0F ; fully-qualified # 🧖‍♀️ E5.0 woman in steamy room
+1F9D6 200D 2640 ; minimally-qualified # 🧖‍♀ E5.0 woman in steamy room
+1F9D6 1F3FB 200D 2640 FE0F ; fully-qualified # 🧖🏻‍♀️ E5.0 woman in steamy room: light skin tone
+1F9D6 1F3FB 200D 2640 ; minimally-qualified # 🧖🏻‍♀ E5.0 woman in steamy room: light skin tone
+1F9D6 1F3FC 200D 2640 FE0F ; fully-qualified # 🧖🏼‍♀️ E5.0 woman in steamy room: medium-light skin tone
+1F9D6 1F3FC 200D 2640 ; minimally-qualified # 🧖🏼‍♀ E5.0 woman in steamy room: medium-light skin tone
+1F9D6 1F3FD 200D 2640 FE0F ; fully-qualified # 🧖🏽‍♀️ E5.0 woman in steamy room: medium skin tone
+1F9D6 1F3FD 200D 2640 ; minimally-qualified # 🧖🏽‍♀ E5.0 woman in steamy room: medium skin tone
+1F9D6 1F3FE 200D 2640 FE0F ; fully-qualified # 🧖🏾‍♀️ E5.0 woman in steamy room: medium-dark skin tone
+1F9D6 1F3FE 200D 2640 ; minimally-qualified # 🧖🏾‍♀ E5.0 woman in steamy room: medium-dark skin tone
+1F9D6 1F3FF 200D 2640 FE0F ; fully-qualified # 🧖🏿‍♀️ E5.0 woman in steamy room: dark skin tone
+1F9D6 1F3FF 200D 2640 ; minimally-qualified # 🧖🏿‍♀ E5.0 woman in steamy room: dark skin tone
+1F9D7 ; fully-qualified # 🧗 E5.0 person climbing
+1F9D7 1F3FB ; fully-qualified # 🧗🏻 E5.0 person climbing: light skin tone
+1F9D7 1F3FC ; fully-qualified # 🧗🏼 E5.0 person climbing: medium-light skin tone
+1F9D7 1F3FD ; fully-qualified # 🧗🏽 E5.0 person climbing: medium skin tone
+1F9D7 1F3FE ; fully-qualified # 🧗🏾 E5.0 person climbing: medium-dark skin tone
+1F9D7 1F3FF ; fully-qualified # 🧗🏿 E5.0 person climbing: dark skin tone
+1F9D7 200D 2642 FE0F ; fully-qualified # 🧗‍♂️ E5.0 man climbing
+1F9D7 200D 2642 ; minimally-qualified # 🧗‍♂ E5.0 man climbing
+1F9D7 1F3FB 200D 2642 FE0F ; fully-qualified # 🧗🏻‍♂️ E5.0 man climbing: light skin tone
+1F9D7 1F3FB 200D 2642 ; minimally-qualified # 🧗🏻‍♂ E5.0 man climbing: light skin tone
+1F9D7 1F3FC 200D 2642 FE0F ; fully-qualified # 🧗🏼‍♂️ E5.0 man climbing: medium-light skin tone
+1F9D7 1F3FC 200D 2642 ; minimally-qualified # 🧗🏼‍♂ E5.0 man climbing: medium-light skin tone
+1F9D7 1F3FD 200D 2642 FE0F ; fully-qualified # 🧗🏽‍♂️ E5.0 man climbing: medium skin tone
+1F9D7 1F3FD 200D 2642 ; minimally-qualified # 🧗🏽‍♂ E5.0 man climbing: medium skin tone
+1F9D7 1F3FE 200D 2642 FE0F ; fully-qualified # 🧗🏾‍♂️ E5.0 man climbing: medium-dark skin tone
+1F9D7 1F3FE 200D 2642 ; minimally-qualified # 🧗🏾‍♂ E5.0 man climbing: medium-dark skin tone
+1F9D7 1F3FF 200D 2642 FE0F ; fully-qualified # 🧗🏿‍♂️ E5.0 man climbing: dark skin tone
+1F9D7 1F3FF 200D 2642 ; minimally-qualified # 🧗🏿‍♂ E5.0 man climbing: dark skin tone
+1F9D7 200D 2640 FE0F ; fully-qualified # 🧗‍♀️ E5.0 woman climbing
+1F9D7 200D 2640 ; minimally-qualified # 🧗‍♀ E5.0 woman climbing
+1F9D7 1F3FB 200D 2640 FE0F ; fully-qualified # 🧗🏻‍♀️ E5.0 woman climbing: light skin tone
+1F9D7 1F3FB 200D 2640 ; minimally-qualified # 🧗🏻‍♀ E5.0 woman climbing: light skin tone
+1F9D7 1F3FC 200D 2640 FE0F ; fully-qualified # 🧗🏼‍♀️ E5.0 woman climbing: medium-light skin tone
+1F9D7 1F3FC 200D 2640 ; minimally-qualified # 🧗🏼‍♀ E5.0 woman climbing: medium-light skin tone
+1F9D7 1F3FD 200D 2640 FE0F ; fully-qualified # 🧗🏽‍♀️ E5.0 woman climbing: medium skin tone
+1F9D7 1F3FD 200D 2640 ; minimally-qualified # 🧗🏽‍♀ E5.0 woman climbing: medium skin tone
+1F9D7 1F3FE 200D 2640 FE0F ; fully-qualified # 🧗🏾‍♀️ E5.0 woman climbing: medium-dark skin tone
+1F9D7 1F3FE 200D 2640 ; minimally-qualified # 🧗🏾‍♀ E5.0 woman climbing: medium-dark skin tone
+1F9D7 1F3FF 200D 2640 FE0F ; fully-qualified # 🧗🏿‍♀️ E5.0 woman climbing: dark skin tone
+1F9D7 1F3FF 200D 2640 ; minimally-qualified # 🧗🏿‍♀ E5.0 woman climbing: dark skin tone
+
+# subgroup: person-sport
+1F93A ; fully-qualified # 🤺 E3.0 person fencing
+1F3C7 ; fully-qualified # 🏇 E1.0 horse racing
+1F3C7 1F3FB ; fully-qualified # 🏇🏻 E1.0 horse racing: light skin tone
+1F3C7 1F3FC ; fully-qualified # 🏇🏼 E1.0 horse racing: medium-light skin tone
+1F3C7 1F3FD ; fully-qualified # 🏇🏽 E1.0 horse racing: medium skin tone
+1F3C7 1F3FE ; fully-qualified # 🏇🏾 E1.0 horse racing: medium-dark skin tone
+1F3C7 1F3FF ; fully-qualified # 🏇🏿 E1.0 horse racing: dark skin tone
+26F7 FE0F ; fully-qualified # ⛷️ E0.7 skier
+26F7 ; unqualified # ⛷ E0.7 skier
+1F3C2 ; fully-qualified # 🏂 E0.6 snowboarder
+1F3C2 1F3FB ; fully-qualified # 🏂🏻 E1.0 snowboarder: light skin tone
+1F3C2 1F3FC ; fully-qualified # 🏂🏼 E1.0 snowboarder: medium-light skin tone
+1F3C2 1F3FD ; fully-qualified # 🏂🏽 E1.0 snowboarder: medium skin tone
+1F3C2 1F3FE ; fully-qualified # 🏂🏾 E1.0 snowboarder: medium-dark skin tone
+1F3C2 1F3FF ; fully-qualified # 🏂🏿 E1.0 snowboarder: dark skin tone
+1F3CC FE0F ; fully-qualified # 🏌️ E0.7 person golfing
+1F3CC ; unqualified # 🏌 E0.7 person golfing
+1F3CC 1F3FB ; fully-qualified # 🏌🏻 E4.0 person golfing: light skin tone
+1F3CC 1F3FC ; fully-qualified # 🏌🏼 E4.0 person golfing: medium-light skin tone
+1F3CC 1F3FD ; fully-qualified # 🏌🏽 E4.0 person golfing: medium skin tone
+1F3CC 1F3FE ; fully-qualified # 🏌🏾 E4.0 person golfing: medium-dark skin tone
+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 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
+1F3CC 1F3FC 200D 2642 FE0F ; fully-qualified # 🏌🏼‍♂️ E4.0 man golfing: medium-light skin tone
+1F3CC 1F3FC 200D 2642 ; minimally-qualified # 🏌🏼‍♂ E4.0 man golfing: medium-light skin tone
+1F3CC 1F3FD 200D 2642 FE0F ; fully-qualified # 🏌🏽‍♂️ E4.0 man golfing: medium skin tone
+1F3CC 1F3FD 200D 2642 ; minimally-qualified # 🏌🏽‍♂ E4.0 man golfing: medium skin tone
+1F3CC 1F3FE 200D 2642 FE0F ; fully-qualified # 🏌🏾‍♂️ E4.0 man golfing: medium-dark skin tone
+1F3CC 1F3FE 200D 2642 ; minimally-qualified # 🏌🏾‍♂ E4.0 man golfing: medium-dark skin tone
+1F3CC 1F3FF 200D 2642 FE0F ; fully-qualified # 🏌🏿‍♂️ E4.0 man golfing: dark skin tone
+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 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
+1F3CC 1F3FC 200D 2640 FE0F ; fully-qualified # 🏌🏼‍♀️ E4.0 woman golfing: medium-light skin tone
+1F3CC 1F3FC 200D 2640 ; minimally-qualified # 🏌🏼‍♀ E4.0 woman golfing: medium-light skin tone
+1F3CC 1F3FD 200D 2640 FE0F ; fully-qualified # 🏌🏽‍♀️ E4.0 woman golfing: medium skin tone
+1F3CC 1F3FD 200D 2640 ; minimally-qualified # 🏌🏽‍♀ E4.0 woman golfing: medium skin tone
+1F3CC 1F3FE 200D 2640 FE0F ; fully-qualified # 🏌🏾‍♀️ E4.0 woman golfing: medium-dark skin tone
+1F3CC 1F3FE 200D 2640 ; minimally-qualified # 🏌🏾‍♀ E4.0 woman golfing: medium-dark skin tone
+1F3CC 1F3FF 200D 2640 FE0F ; fully-qualified # 🏌🏿‍♀️ E4.0 woman golfing: dark skin tone
+1F3CC 1F3FF 200D 2640 ; minimally-qualified # 🏌🏿‍♀ E4.0 woman golfing: dark skin tone
+1F3C4 ; fully-qualified # 🏄 E0.6 person surfing
+1F3C4 1F3FB ; fully-qualified # 🏄🏻 E1.0 person surfing: light skin tone
+1F3C4 1F3FC ; fully-qualified # 🏄🏼 E1.0 person surfing: medium-light skin tone
+1F3C4 1F3FD ; fully-qualified # 🏄🏽 E1.0 person surfing: medium skin tone
+1F3C4 1F3FE ; fully-qualified # 🏄🏾 E1.0 person surfing: medium-dark skin tone
+1F3C4 1F3FF ; fully-qualified # 🏄🏿 E1.0 person surfing: dark skin tone
+1F3C4 200D 2642 FE0F ; fully-qualified # 🏄‍♂️ E4.0 man surfing
+1F3C4 200D 2642 ; minimally-qualified # 🏄‍♂ E4.0 man surfing
+1F3C4 1F3FB 200D 2642 FE0F ; fully-qualified # 🏄🏻‍♂️ E4.0 man surfing: light skin tone
+1F3C4 1F3FB 200D 2642 ; minimally-qualified # 🏄🏻‍♂ E4.0 man surfing: light skin tone
+1F3C4 1F3FC 200D 2642 FE0F ; fully-qualified # 🏄🏼‍♂️ E4.0 man surfing: medium-light skin tone
+1F3C4 1F3FC 200D 2642 ; minimally-qualified # 🏄🏼‍♂ E4.0 man surfing: medium-light skin tone
+1F3C4 1F3FD 200D 2642 FE0F ; fully-qualified # 🏄🏽‍♂️ E4.0 man surfing: medium skin tone
+1F3C4 1F3FD 200D 2642 ; minimally-qualified # 🏄🏽‍♂ E4.0 man surfing: medium skin tone
+1F3C4 1F3FE 200D 2642 FE0F ; fully-qualified # 🏄🏾‍♂️ E4.0 man surfing: medium-dark skin tone
+1F3C4 1F3FE 200D 2642 ; minimally-qualified # 🏄🏾‍♂ E4.0 man surfing: medium-dark skin tone
+1F3C4 1F3FF 200D 2642 FE0F ; fully-qualified # 🏄🏿‍♂️ E4.0 man surfing: dark skin tone
+1F3C4 1F3FF 200D 2642 ; minimally-qualified # 🏄🏿‍♂ E4.0 man surfing: dark skin tone
+1F3C4 200D 2640 FE0F ; fully-qualified # 🏄‍♀️ E4.0 woman surfing
+1F3C4 200D 2640 ; minimally-qualified # 🏄‍♀ E4.0 woman surfing
+1F3C4 1F3FB 200D 2640 FE0F ; fully-qualified # 🏄🏻‍♀️ E4.0 woman surfing: light skin tone
+1F3C4 1F3FB 200D 2640 ; minimally-qualified # 🏄🏻‍♀ E4.0 woman surfing: light skin tone
+1F3C4 1F3FC 200D 2640 FE0F ; fully-qualified # 🏄🏼‍♀️ E4.0 woman surfing: medium-light skin tone
+1F3C4 1F3FC 200D 2640 ; minimally-qualified # 🏄🏼‍♀ E4.0 woman surfing: medium-light skin tone
+1F3C4 1F3FD 200D 2640 FE0F ; fully-qualified # 🏄🏽‍♀️ E4.0 woman surfing: medium skin tone
+1F3C4 1F3FD 200D 2640 ; minimally-qualified # 🏄🏽‍♀ E4.0 woman surfing: medium skin tone
+1F3C4 1F3FE 200D 2640 FE0F ; fully-qualified # 🏄🏾‍♀️ E4.0 woman surfing: medium-dark skin tone
+1F3C4 1F3FE 200D 2640 ; minimally-qualified # 🏄🏾‍♀ E4.0 woman surfing: medium-dark skin tone
+1F3C4 1F3FF 200D 2640 FE0F ; fully-qualified # 🏄🏿‍♀️ E4.0 woman surfing: dark skin tone
+1F3C4 1F3FF 200D 2640 ; minimally-qualified # 🏄🏿‍♀ E4.0 woman surfing: dark skin tone
+1F6A3 ; fully-qualified # 🚣 E1.0 person rowing boat
+1F6A3 1F3FB ; fully-qualified # 🚣🏻 E1.0 person rowing boat: light skin tone
+1F6A3 1F3FC ; fully-qualified # 🚣🏼 E1.0 person rowing boat: medium-light skin tone
+1F6A3 1F3FD ; fully-qualified # 🚣🏽 E1.0 person rowing boat: medium skin tone
+1F6A3 1F3FE ; fully-qualified # 🚣🏾 E1.0 person rowing boat: medium-dark skin tone
+1F6A3 1F3FF ; fully-qualified # 🚣🏿 E1.0 person rowing boat: dark skin tone
+1F6A3 200D 2642 FE0F ; fully-qualified # 🚣‍♂️ E4.0 man rowing boat
+1F6A3 200D 2642 ; minimally-qualified # 🚣‍♂ E4.0 man rowing boat
+1F6A3 1F3FB 200D 2642 FE0F ; fully-qualified # 🚣🏻‍♂️ E4.0 man rowing boat: light skin tone
+1F6A3 1F3FB 200D 2642 ; minimally-qualified # 🚣🏻‍♂ E4.0 man rowing boat: light skin tone
+1F6A3 1F3FC 200D 2642 FE0F ; fully-qualified # 🚣🏼‍♂️ E4.0 man rowing boat: medium-light skin tone
+1F6A3 1F3FC 200D 2642 ; minimally-qualified # 🚣🏼‍♂ E4.0 man rowing boat: medium-light skin tone
+1F6A3 1F3FD 200D 2642 FE0F ; fully-qualified # 🚣🏽‍♂️ E4.0 man rowing boat: medium skin tone
+1F6A3 1F3FD 200D 2642 ; minimally-qualified # 🚣🏽‍♂ E4.0 man rowing boat: medium skin tone
+1F6A3 1F3FE 200D 2642 FE0F ; fully-qualified # 🚣🏾‍♂️ E4.0 man rowing boat: medium-dark skin tone
+1F6A3 1F3FE 200D 2642 ; minimally-qualified # 🚣🏾‍♂ E4.0 man rowing boat: medium-dark skin tone
+1F6A3 1F3FF 200D 2642 FE0F ; fully-qualified # 🚣🏿‍♂️ E4.0 man rowing boat: dark skin tone
+1F6A3 1F3FF 200D 2642 ; minimally-qualified # 🚣🏿‍♂ E4.0 man rowing boat: dark skin tone
+1F6A3 200D 2640 FE0F ; fully-qualified # 🚣‍♀️ E4.0 woman rowing boat
+1F6A3 200D 2640 ; minimally-qualified # 🚣‍♀ E4.0 woman rowing boat
+1F6A3 1F3FB 200D 2640 FE0F ; fully-qualified # 🚣🏻‍♀️ E4.0 woman rowing boat: light skin tone
+1F6A3 1F3FB 200D 2640 ; minimally-qualified # 🚣🏻‍♀ E4.0 woman rowing boat: light skin tone
+1F6A3 1F3FC 200D 2640 FE0F ; fully-qualified # 🚣🏼‍♀️ E4.0 woman rowing boat: medium-light skin tone
+1F6A3 1F3FC 200D 2640 ; minimally-qualified # 🚣🏼‍♀ E4.0 woman rowing boat: medium-light skin tone
+1F6A3 1F3FD 200D 2640 FE0F ; fully-qualified # 🚣🏽‍♀️ E4.0 woman rowing boat: medium skin tone
+1F6A3 1F3FD 200D 2640 ; minimally-qualified # 🚣🏽‍♀ E4.0 woman rowing boat: medium skin tone
+1F6A3 1F3FE 200D 2640 FE0F ; fully-qualified # 🚣🏾‍♀️ E4.0 woman rowing boat: medium-dark skin tone
+1F6A3 1F3FE 200D 2640 ; minimally-qualified # 🚣🏾‍♀ E4.0 woman rowing boat: medium-dark skin tone
+1F6A3 1F3FF 200D 2640 FE0F ; fully-qualified # 🚣🏿‍♀️ E4.0 woman rowing boat: dark skin tone
+1F6A3 1F3FF 200D 2640 ; minimally-qualified # 🚣🏿‍♀ E4.0 woman rowing boat: dark skin tone
+1F3CA ; fully-qualified # 🏊 E0.6 person swimming
+1F3CA 1F3FB ; fully-qualified # 🏊🏻 E1.0 person swimming: light skin tone
+1F3CA 1F3FC ; fully-qualified # 🏊🏼 E1.0 person swimming: medium-light skin tone
+1F3CA 1F3FD ; fully-qualified # 🏊🏽 E1.0 person swimming: medium skin tone
+1F3CA 1F3FE ; fully-qualified # 🏊🏾 E1.0 person swimming: medium-dark skin tone
+1F3CA 1F3FF ; fully-qualified # 🏊🏿 E1.0 person swimming: dark skin tone
+1F3CA 200D 2642 FE0F ; fully-qualified # 🏊‍♂️ E4.0 man swimming
+1F3CA 200D 2642 ; minimally-qualified # 🏊‍♂ E4.0 man swimming
+1F3CA 1F3FB 200D 2642 FE0F ; fully-qualified # 🏊🏻‍♂️ E4.0 man swimming: light skin tone
+1F3CA 1F3FB 200D 2642 ; minimally-qualified # 🏊🏻‍♂ E4.0 man swimming: light skin tone
+1F3CA 1F3FC 200D 2642 FE0F ; fully-qualified # 🏊🏼‍♂️ E4.0 man swimming: medium-light skin tone
+1F3CA 1F3FC 200D 2642 ; minimally-qualified # 🏊🏼‍♂ E4.0 man swimming: medium-light skin tone
+1F3CA 1F3FD 200D 2642 FE0F ; fully-qualified # 🏊🏽‍♂️ E4.0 man swimming: medium skin tone
+1F3CA 1F3FD 200D 2642 ; minimally-qualified # 🏊🏽‍♂ E4.0 man swimming: medium skin tone
+1F3CA 1F3FE 200D 2642 FE0F ; fully-qualified # 🏊🏾‍♂️ E4.0 man swimming: medium-dark skin tone
+1F3CA 1F3FE 200D 2642 ; minimally-qualified # 🏊🏾‍♂ E4.0 man swimming: medium-dark skin tone
+1F3CA 1F3FF 200D 2642 FE0F ; fully-qualified # 🏊🏿‍♂️ E4.0 man swimming: dark skin tone
+1F3CA 1F3FF 200D 2642 ; minimally-qualified # 🏊🏿‍♂ E4.0 man swimming: dark skin tone
+1F3CA 200D 2640 FE0F ; fully-qualified # 🏊‍♀️ E4.0 woman swimming
+1F3CA 200D 2640 ; minimally-qualified # 🏊‍♀ E4.0 woman swimming
+1F3CA 1F3FB 200D 2640 FE0F ; fully-qualified # 🏊🏻‍♀️ E4.0 woman swimming: light skin tone
+1F3CA 1F3FB 200D 2640 ; minimally-qualified # 🏊🏻‍♀ E4.0 woman swimming: light skin tone
+1F3CA 1F3FC 200D 2640 FE0F ; fully-qualified # 🏊🏼‍♀️ E4.0 woman swimming: medium-light skin tone
+1F3CA 1F3FC 200D 2640 ; minimally-qualified # 🏊🏼‍♀ E4.0 woman swimming: medium-light skin tone
+1F3CA 1F3FD 200D 2640 FE0F ; fully-qualified # 🏊🏽‍♀️ E4.0 woman swimming: medium skin tone
+1F3CA 1F3FD 200D 2640 ; minimally-qualified # 🏊🏽‍♀ E4.0 woman swimming: medium skin tone
+1F3CA 1F3FE 200D 2640 FE0F ; fully-qualified # 🏊🏾‍♀️ E4.0 woman swimming: medium-dark skin tone
+1F3CA 1F3FE 200D 2640 ; minimally-qualified # 🏊🏾‍♀ E4.0 woman swimming: medium-dark skin tone
+1F3CA 1F3FF 200D 2640 FE0F ; fully-qualified # 🏊🏿‍♀️ E4.0 woman swimming: dark skin tone
+1F3CA 1F3FF 200D 2640 ; minimally-qualified # 🏊🏿‍♀ E4.0 woman swimming: dark skin tone
+26F9 FE0F ; fully-qualified # ⛹️ E0.7 person bouncing ball
+26F9 ; unqualified # ⛹ E0.7 person bouncing ball
+26F9 1F3FB ; fully-qualified # ⛹🏻 E2.0 person bouncing ball: light skin tone
+26F9 1F3FC ; fully-qualified # ⛹🏼 E2.0 person bouncing ball: medium-light skin tone
+26F9 1F3FD ; fully-qualified # ⛹🏽 E2.0 person bouncing ball: medium skin tone
+26F9 1F3FE ; fully-qualified # ⛹🏾 E2.0 person bouncing ball: medium-dark skin tone
+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 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
+26F9 1F3FC 200D 2642 FE0F ; fully-qualified # ⛹🏼‍♂️ E4.0 man bouncing ball: medium-light skin tone
+26F9 1F3FC 200D 2642 ; minimally-qualified # ⛹🏼‍♂ E4.0 man bouncing ball: medium-light skin tone
+26F9 1F3FD 200D 2642 FE0F ; fully-qualified # ⛹🏽‍♂️ E4.0 man bouncing ball: medium skin tone
+26F9 1F3FD 200D 2642 ; minimally-qualified # ⛹🏽‍♂ E4.0 man bouncing ball: medium skin tone
+26F9 1F3FE 200D 2642 FE0F ; fully-qualified # ⛹🏾‍♂️ E4.0 man bouncing ball: medium-dark skin tone
+26F9 1F3FE 200D 2642 ; minimally-qualified # ⛹🏾‍♂ E4.0 man bouncing ball: medium-dark skin tone
+26F9 1F3FF 200D 2642 FE0F ; fully-qualified # ⛹🏿‍♂️ E4.0 man bouncing ball: dark skin tone
+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 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
+26F9 1F3FC 200D 2640 FE0F ; fully-qualified # ⛹🏼‍♀️ E4.0 woman bouncing ball: medium-light skin tone
+26F9 1F3FC 200D 2640 ; minimally-qualified # ⛹🏼‍♀ E4.0 woman bouncing ball: medium-light skin tone
+26F9 1F3FD 200D 2640 FE0F ; fully-qualified # ⛹🏽‍♀️ E4.0 woman bouncing ball: medium skin tone
+26F9 1F3FD 200D 2640 ; minimally-qualified # ⛹🏽‍♀ E4.0 woman bouncing ball: medium skin tone
+26F9 1F3FE 200D 2640 FE0F ; fully-qualified # ⛹🏾‍♀️ E4.0 woman bouncing ball: medium-dark skin tone
+26F9 1F3FE 200D 2640 ; minimally-qualified # ⛹🏾‍♀ E4.0 woman bouncing ball: medium-dark skin tone
+26F9 1F3FF 200D 2640 FE0F ; fully-qualified # ⛹🏿‍♀️ E4.0 woman bouncing ball: dark skin tone
+26F9 1F3FF 200D 2640 ; minimally-qualified # ⛹🏿‍♀ E4.0 woman bouncing ball: dark skin tone
+1F3CB FE0F ; fully-qualified # 🏋️ E0.7 person lifting weights
+1F3CB ; unqualified # 🏋 E0.7 person lifting weights
+1F3CB 1F3FB ; fully-qualified # 🏋🏻 E2.0 person lifting weights: light skin tone
+1F3CB 1F3FC ; fully-qualified # 🏋🏼 E2.0 person lifting weights: medium-light skin tone
+1F3CB 1F3FD ; fully-qualified # 🏋🏽 E2.0 person lifting weights: medium skin tone
+1F3CB 1F3FE ; fully-qualified # 🏋🏾 E2.0 person lifting weights: medium-dark skin tone
+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 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
+1F3CB 1F3FC 200D 2642 FE0F ; fully-qualified # 🏋🏼‍♂️ E4.0 man lifting weights: medium-light skin tone
+1F3CB 1F3FC 200D 2642 ; minimally-qualified # 🏋🏼‍♂ E4.0 man lifting weights: medium-light skin tone
+1F3CB 1F3FD 200D 2642 FE0F ; fully-qualified # 🏋🏽‍♂️ E4.0 man lifting weights: medium skin tone
+1F3CB 1F3FD 200D 2642 ; minimally-qualified # 🏋🏽‍♂ E4.0 man lifting weights: medium skin tone
+1F3CB 1F3FE 200D 2642 FE0F ; fully-qualified # 🏋🏾‍♂️ E4.0 man lifting weights: medium-dark skin tone
+1F3CB 1F3FE 200D 2642 ; minimally-qualified # 🏋🏾‍♂ E4.0 man lifting weights: medium-dark skin tone
+1F3CB 1F3FF 200D 2642 FE0F ; fully-qualified # 🏋🏿‍♂️ E4.0 man lifting weights: dark skin tone
+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 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
+1F3CB 1F3FC 200D 2640 FE0F ; fully-qualified # 🏋🏼‍♀️ E4.0 woman lifting weights: medium-light skin tone
+1F3CB 1F3FC 200D 2640 ; minimally-qualified # 🏋🏼‍♀ E4.0 woman lifting weights: medium-light skin tone
+1F3CB 1F3FD 200D 2640 FE0F ; fully-qualified # 🏋🏽‍♀️ E4.0 woman lifting weights: medium skin tone
+1F3CB 1F3FD 200D 2640 ; minimally-qualified # 🏋🏽‍♀ E4.0 woman lifting weights: medium skin tone
+1F3CB 1F3FE 200D 2640 FE0F ; fully-qualified # 🏋🏾‍♀️ E4.0 woman lifting weights: medium-dark skin tone
+1F3CB 1F3FE 200D 2640 ; minimally-qualified # 🏋🏾‍♀ E4.0 woman lifting weights: medium-dark skin tone
+1F3CB 1F3FF 200D 2640 FE0F ; fully-qualified # 🏋🏿‍♀️ E4.0 woman lifting weights: dark skin tone
+1F3CB 1F3FF 200D 2640 ; minimally-qualified # 🏋🏿‍♀ E4.0 woman lifting weights: dark skin tone
+1F6B4 ; fully-qualified # 🚴 E1.0 person biking
+1F6B4 1F3FB ; fully-qualified # 🚴🏻 E1.0 person biking: light skin tone
+1F6B4 1F3FC ; fully-qualified # 🚴🏼 E1.0 person biking: medium-light skin tone
+1F6B4 1F3FD ; fully-qualified # 🚴🏽 E1.0 person biking: medium skin tone
+1F6B4 1F3FE ; fully-qualified # 🚴🏾 E1.0 person biking: medium-dark skin tone
+1F6B4 1F3FF ; fully-qualified # 🚴🏿 E1.0 person biking: dark skin tone
+1F6B4 200D 2642 FE0F ; fully-qualified # 🚴‍♂️ E4.0 man biking
+1F6B4 200D 2642 ; minimally-qualified # 🚴‍♂ E4.0 man biking
+1F6B4 1F3FB 200D 2642 FE0F ; fully-qualified # 🚴🏻‍♂️ E4.0 man biking: light skin tone
+1F6B4 1F3FB 200D 2642 ; minimally-qualified # 🚴🏻‍♂ E4.0 man biking: light skin tone
+1F6B4 1F3FC 200D 2642 FE0F ; fully-qualified # 🚴🏼‍♂️ E4.0 man biking: medium-light skin tone
+1F6B4 1F3FC 200D 2642 ; minimally-qualified # 🚴🏼‍♂ E4.0 man biking: medium-light skin tone
+1F6B4 1F3FD 200D 2642 FE0F ; fully-qualified # 🚴🏽‍♂️ E4.0 man biking: medium skin tone
+1F6B4 1F3FD 200D 2642 ; minimally-qualified # 🚴🏽‍♂ E4.0 man biking: medium skin tone
+1F6B4 1F3FE 200D 2642 FE0F ; fully-qualified # 🚴🏾‍♂️ E4.0 man biking: medium-dark skin tone
+1F6B4 1F3FE 200D 2642 ; minimally-qualified # 🚴🏾‍♂ E4.0 man biking: medium-dark skin tone
+1F6B4 1F3FF 200D 2642 FE0F ; fully-qualified # 🚴🏿‍♂️ E4.0 man biking: dark skin tone
+1F6B4 1F3FF 200D 2642 ; minimally-qualified # 🚴🏿‍♂ E4.0 man biking: dark skin tone
+1F6B4 200D 2640 FE0F ; fully-qualified # 🚴‍♀️ E4.0 woman biking
+1F6B4 200D 2640 ; minimally-qualified # 🚴‍♀ E4.0 woman biking
+1F6B4 1F3FB 200D 2640 FE0F ; fully-qualified # 🚴🏻‍♀️ E4.0 woman biking: light skin tone
+1F6B4 1F3FB 200D 2640 ; minimally-qualified # 🚴🏻‍♀ E4.0 woman biking: light skin tone
+1F6B4 1F3FC 200D 2640 FE0F ; fully-qualified # 🚴🏼‍♀️ E4.0 woman biking: medium-light skin tone
+1F6B4 1F3FC 200D 2640 ; minimally-qualified # 🚴🏼‍♀ E4.0 woman biking: medium-light skin tone
+1F6B4 1F3FD 200D 2640 FE0F ; fully-qualified # 🚴🏽‍♀️ E4.0 woman biking: medium skin tone
+1F6B4 1F3FD 200D 2640 ; minimally-qualified # 🚴🏽‍♀ E4.0 woman biking: medium skin tone
+1F6B4 1F3FE 200D 2640 FE0F ; fully-qualified # 🚴🏾‍♀️ E4.0 woman biking: medium-dark skin tone
+1F6B4 1F3FE 200D 2640 ; minimally-qualified # 🚴🏾‍♀ E4.0 woman biking: medium-dark skin tone
+1F6B4 1F3FF 200D 2640 FE0F ; fully-qualified # 🚴🏿‍♀️ E4.0 woman biking: dark skin tone
+1F6B4 1F3FF 200D 2640 ; minimally-qualified # 🚴🏿‍♀ E4.0 woman biking: dark skin tone
+1F6B5 ; fully-qualified # 🚵 E1.0 person mountain biking
+1F6B5 1F3FB ; fully-qualified # 🚵🏻 E1.0 person mountain biking: light skin tone
+1F6B5 1F3FC ; fully-qualified # 🚵🏼 E1.0 person mountain biking: medium-light skin tone
+1F6B5 1F3FD ; fully-qualified # 🚵🏽 E1.0 person mountain biking: medium skin tone
+1F6B5 1F3FE ; fully-qualified # 🚵🏾 E1.0 person mountain biking: medium-dark skin tone
+1F6B5 1F3FF ; fully-qualified # 🚵🏿 E1.0 person mountain biking: dark skin tone
+1F6B5 200D 2642 FE0F ; fully-qualified # 🚵‍♂️ E4.0 man mountain biking
+1F6B5 200D 2642 ; minimally-qualified # 🚵‍♂ E4.0 man mountain biking
+1F6B5 1F3FB 200D 2642 FE0F ; fully-qualified # 🚵🏻‍♂️ E4.0 man mountain biking: light skin tone
+1F6B5 1F3FB 200D 2642 ; minimally-qualified # 🚵🏻‍♂ E4.0 man mountain biking: light skin tone
+1F6B5 1F3FC 200D 2642 FE0F ; fully-qualified # 🚵🏼‍♂️ E4.0 man mountain biking: medium-light skin tone
+1F6B5 1F3FC 200D 2642 ; minimally-qualified # 🚵🏼‍♂ E4.0 man mountain biking: medium-light skin tone
+1F6B5 1F3FD 200D 2642 FE0F ; fully-qualified # 🚵🏽‍♂️ E4.0 man mountain biking: medium skin tone
+1F6B5 1F3FD 200D 2642 ; minimally-qualified # 🚵🏽‍♂ E4.0 man mountain biking: medium skin tone
+1F6B5 1F3FE 200D 2642 FE0F ; fully-qualified # 🚵🏾‍♂️ E4.0 man mountain biking: medium-dark skin tone
+1F6B5 1F3FE 200D 2642 ; minimally-qualified # 🚵🏾‍♂ E4.0 man mountain biking: medium-dark skin tone
+1F6B5 1F3FF 200D 2642 FE0F ; fully-qualified # 🚵🏿‍♂️ E4.0 man mountain biking: dark skin tone
+1F6B5 1F3FF 200D 2642 ; minimally-qualified # 🚵🏿‍♂ E4.0 man mountain biking: dark skin tone
+1F6B5 200D 2640 FE0F ; fully-qualified # 🚵‍♀️ E4.0 woman mountain biking
+1F6B5 200D 2640 ; minimally-qualified # 🚵‍♀ E4.0 woman mountain biking
+1F6B5 1F3FB 200D 2640 FE0F ; fully-qualified # 🚵🏻‍♀️ E4.0 woman mountain biking: light skin tone
+1F6B5 1F3FB 200D 2640 ; minimally-qualified # 🚵🏻‍♀ E4.0 woman mountain biking: light skin tone
+1F6B5 1F3FC 200D 2640 FE0F ; fully-qualified # 🚵🏼‍♀️ E4.0 woman mountain biking: medium-light skin tone
+1F6B5 1F3FC 200D 2640 ; minimally-qualified # 🚵🏼‍♀ E4.0 woman mountain biking: medium-light skin tone
+1F6B5 1F3FD 200D 2640 FE0F ; fully-qualified # 🚵🏽‍♀️ E4.0 woman mountain biking: medium skin tone
+1F6B5 1F3FD 200D 2640 ; minimally-qualified # 🚵🏽‍♀ E4.0 woman mountain biking: medium skin tone
+1F6B5 1F3FE 200D 2640 FE0F ; fully-qualified # 🚵🏾‍♀️ E4.0 woman mountain biking: medium-dark skin tone
+1F6B5 1F3FE 200D 2640 ; minimally-qualified # 🚵🏾‍♀ E4.0 woman mountain biking: medium-dark skin tone
+1F6B5 1F3FF 200D 2640 FE0F ; fully-qualified # 🚵🏿‍♀️ E4.0 woman mountain biking: dark skin tone
+1F6B5 1F3FF 200D 2640 ; minimally-qualified # 🚵🏿‍♀ E4.0 woman mountain biking: dark skin tone
+1F938 ; fully-qualified # 🤸 E3.0 person cartwheeling
+1F938 1F3FB ; fully-qualified # 🤸🏻 E3.0 person cartwheeling: light skin tone
+1F938 1F3FC ; fully-qualified # 🤸🏼 E3.0 person cartwheeling: medium-light skin tone
+1F938 1F3FD ; fully-qualified # 🤸🏽 E3.0 person cartwheeling: medium skin tone
+1F938 1F3FE ; fully-qualified # 🤸🏾 E3.0 person cartwheeling: medium-dark skin tone
+1F938 1F3FF ; fully-qualified # 🤸🏿 E3.0 person cartwheeling: dark skin tone
+1F938 200D 2642 FE0F ; fully-qualified # 🤸‍♂️ E4.0 man cartwheeling
+1F938 200D 2642 ; minimally-qualified # 🤸‍♂ E4.0 man cartwheeling
+1F938 1F3FB 200D 2642 FE0F ; fully-qualified # 🤸🏻‍♂️ E4.0 man cartwheeling: light skin tone
+1F938 1F3FB 200D 2642 ; minimally-qualified # 🤸🏻‍♂ E4.0 man cartwheeling: light skin tone
+1F938 1F3FC 200D 2642 FE0F ; fully-qualified # 🤸🏼‍♂️ E4.0 man cartwheeling: medium-light skin tone
+1F938 1F3FC 200D 2642 ; minimally-qualified # 🤸🏼‍♂ E4.0 man cartwheeling: medium-light skin tone
+1F938 1F3FD 200D 2642 FE0F ; fully-qualified # 🤸🏽‍♂️ E4.0 man cartwheeling: medium skin tone
+1F938 1F3FD 200D 2642 ; minimally-qualified # 🤸🏽‍♂ E4.0 man cartwheeling: medium skin tone
+1F938 1F3FE 200D 2642 FE0F ; fully-qualified # 🤸🏾‍♂️ E4.0 man cartwheeling: medium-dark skin tone
+1F938 1F3FE 200D 2642 ; minimally-qualified # 🤸🏾‍♂ E4.0 man cartwheeling: medium-dark skin tone
+1F938 1F3FF 200D 2642 FE0F ; fully-qualified # 🤸🏿‍♂️ E4.0 man cartwheeling: dark skin tone
+1F938 1F3FF 200D 2642 ; minimally-qualified # 🤸🏿‍♂ E4.0 man cartwheeling: dark skin tone
+1F938 200D 2640 FE0F ; fully-qualified # 🤸‍♀️ E4.0 woman cartwheeling
+1F938 200D 2640 ; minimally-qualified # 🤸‍♀ E4.0 woman cartwheeling
+1F938 1F3FB 200D 2640 FE0F ; fully-qualified # 🤸🏻‍♀️ E4.0 woman cartwheeling: light skin tone
+1F938 1F3FB 200D 2640 ; minimally-qualified # 🤸🏻‍♀ E4.0 woman cartwheeling: light skin tone
+1F938 1F3FC 200D 2640 FE0F ; fully-qualified # 🤸🏼‍♀️ E4.0 woman cartwheeling: medium-light skin tone
+1F938 1F3FC 200D 2640 ; minimally-qualified # 🤸🏼‍♀ E4.0 woman cartwheeling: medium-light skin tone
+1F938 1F3FD 200D 2640 FE0F ; fully-qualified # 🤸🏽‍♀️ E4.0 woman cartwheeling: medium skin tone
+1F938 1F3FD 200D 2640 ; minimally-qualified # 🤸🏽‍♀ E4.0 woman cartwheeling: medium skin tone
+1F938 1F3FE 200D 2640 FE0F ; fully-qualified # 🤸🏾‍♀️ E4.0 woman cartwheeling: medium-dark skin tone
+1F938 1F3FE 200D 2640 ; minimally-qualified # 🤸🏾‍♀ E4.0 woman cartwheeling: medium-dark skin tone
+1F938 1F3FF 200D 2640 FE0F ; fully-qualified # 🤸🏿‍♀️ E4.0 woman cartwheeling: dark skin tone
+1F938 1F3FF 200D 2640 ; minimally-qualified # 🤸🏿‍♀ E4.0 woman cartwheeling: dark skin tone
+1F93C ; fully-qualified # 🤼 E3.0 people wrestling
+1F93C 200D 2642 FE0F ; fully-qualified # 🤼‍♂️ E4.0 men wrestling
+1F93C 200D 2642 ; minimally-qualified # 🤼‍♂ E4.0 men wrestling
+1F93C 200D 2640 FE0F ; fully-qualified # 🤼‍♀️ E4.0 women wrestling
+1F93C 200D 2640 ; minimally-qualified # 🤼‍♀ E4.0 women wrestling
+1F93D ; fully-qualified # 🤽 E3.0 person playing water polo
+1F93D 1F3FB ; fully-qualified # 🤽🏻 E3.0 person playing water polo: light skin tone
+1F93D 1F3FC ; fully-qualified # 🤽🏼 E3.0 person playing water polo: medium-light skin tone
+1F93D 1F3FD ; fully-qualified # 🤽🏽 E3.0 person playing water polo: medium skin tone
+1F93D 1F3FE ; fully-qualified # 🤽🏾 E3.0 person playing water polo: medium-dark skin tone
+1F93D 1F3FF ; fully-qualified # 🤽🏿 E3.0 person playing water polo: dark skin tone
+1F93D 200D 2642 FE0F ; fully-qualified # 🤽‍♂️ E4.0 man playing water polo
+1F93D 200D 2642 ; minimally-qualified # 🤽‍♂ E4.0 man playing water polo
+1F93D 1F3FB 200D 2642 FE0F ; fully-qualified # 🤽🏻‍♂️ E4.0 man playing water polo: light skin tone
+1F93D 1F3FB 200D 2642 ; minimally-qualified # 🤽🏻‍♂ E4.0 man playing water polo: light skin tone
+1F93D 1F3FC 200D 2642 FE0F ; fully-qualified # 🤽🏼‍♂️ E4.0 man playing water polo: medium-light skin tone
+1F93D 1F3FC 200D 2642 ; minimally-qualified # 🤽🏼‍♂ E4.0 man playing water polo: medium-light skin tone
+1F93D 1F3FD 200D 2642 FE0F ; fully-qualified # 🤽🏽‍♂️ E4.0 man playing water polo: medium skin tone
+1F93D 1F3FD 200D 2642 ; minimally-qualified # 🤽🏽‍♂ E4.0 man playing water polo: medium skin tone
+1F93D 1F3FE 200D 2642 FE0F ; fully-qualified # 🤽🏾‍♂️ E4.0 man playing water polo: medium-dark skin tone
+1F93D 1F3FE 200D 2642 ; minimally-qualified # 🤽🏾‍♂ E4.0 man playing water polo: medium-dark skin tone
+1F93D 1F3FF 200D 2642 FE0F ; fully-qualified # 🤽🏿‍♂️ E4.0 man playing water polo: dark skin tone
+1F93D 1F3FF 200D 2642 ; minimally-qualified # 🤽🏿‍♂ E4.0 man playing water polo: dark skin tone
+1F93D 200D 2640 FE0F ; fully-qualified # 🤽‍♀️ E4.0 woman playing water polo
+1F93D 200D 2640 ; minimally-qualified # 🤽‍♀ E4.0 woman playing water polo
+1F93D 1F3FB 200D 2640 FE0F ; fully-qualified # 🤽🏻‍♀️ E4.0 woman playing water polo: light skin tone
+1F93D 1F3FB 200D 2640 ; minimally-qualified # 🤽🏻‍♀ E4.0 woman playing water polo: light skin tone
+1F93D 1F3FC 200D 2640 FE0F ; fully-qualified # 🤽🏼‍♀️ E4.0 woman playing water polo: medium-light skin tone
+1F93D 1F3FC 200D 2640 ; minimally-qualified # 🤽🏼‍♀ E4.0 woman playing water polo: medium-light skin tone
+1F93D 1F3FD 200D 2640 FE0F ; fully-qualified # 🤽🏽‍♀️ E4.0 woman playing water polo: medium skin tone
+1F93D 1F3FD 200D 2640 ; minimally-qualified # 🤽🏽‍♀ E4.0 woman playing water polo: medium skin tone
+1F93D 1F3FE 200D 2640 FE0F ; fully-qualified # 🤽🏾‍♀️ E4.0 woman playing water polo: medium-dark skin tone
+1F93D 1F3FE 200D 2640 ; minimally-qualified # 🤽🏾‍♀ E4.0 woman playing water polo: medium-dark skin tone
+1F93D 1F3FF 200D 2640 FE0F ; fully-qualified # 🤽🏿‍♀️ E4.0 woman playing water polo: dark skin tone
+1F93D 1F3FF 200D 2640 ; minimally-qualified # 🤽🏿‍♀ E4.0 woman playing water polo: dark skin tone
+1F93E ; fully-qualified # 🤾 E3.0 person playing handball
+1F93E 1F3FB ; fully-qualified # 🤾🏻 E3.0 person playing handball: light skin tone
+1F93E 1F3FC ; fully-qualified # 🤾🏼 E3.0 person playing handball: medium-light skin tone
+1F93E 1F3FD ; fully-qualified # 🤾🏽 E3.0 person playing handball: medium skin tone
+1F93E 1F3FE ; fully-qualified # 🤾🏾 E3.0 person playing handball: medium-dark skin tone
+1F93E 1F3FF ; fully-qualified # 🤾🏿 E3.0 person playing handball: dark skin tone
+1F93E 200D 2642 FE0F ; fully-qualified # 🤾‍♂️ E4.0 man playing handball
+1F93E 200D 2642 ; minimally-qualified # 🤾‍♂ E4.0 man playing handball
+1F93E 1F3FB 200D 2642 FE0F ; fully-qualified # 🤾🏻‍♂️ E4.0 man playing handball: light skin tone
+1F93E 1F3FB 200D 2642 ; minimally-qualified # 🤾🏻‍♂ E4.0 man playing handball: light skin tone
+1F93E 1F3FC 200D 2642 FE0F ; fully-qualified # 🤾🏼‍♂️ E4.0 man playing handball: medium-light skin tone
+1F93E 1F3FC 200D 2642 ; minimally-qualified # 🤾🏼‍♂ E4.0 man playing handball: medium-light skin tone
+1F93E 1F3FD 200D 2642 FE0F ; fully-qualified # 🤾🏽‍♂️ E4.0 man playing handball: medium skin tone
+1F93E 1F3FD 200D 2642 ; minimally-qualified # 🤾🏽‍♂ E4.0 man playing handball: medium skin tone
+1F93E 1F3FE 200D 2642 FE0F ; fully-qualified # 🤾🏾‍♂️ E4.0 man playing handball: medium-dark skin tone
+1F93E 1F3FE 200D 2642 ; minimally-qualified # 🤾🏾‍♂ E4.0 man playing handball: medium-dark skin tone
+1F93E 1F3FF 200D 2642 FE0F ; fully-qualified # 🤾🏿‍♂️ E4.0 man playing handball: dark skin tone
+1F93E 1F3FF 200D 2642 ; minimally-qualified # 🤾🏿‍♂ E4.0 man playing handball: dark skin tone
+1F93E 200D 2640 FE0F ; fully-qualified # 🤾‍♀️ E4.0 woman playing handball
+1F93E 200D 2640 ; minimally-qualified # 🤾‍♀ E4.0 woman playing handball
+1F93E 1F3FB 200D 2640 FE0F ; fully-qualified # 🤾🏻‍♀️ E4.0 woman playing handball: light skin tone
+1F93E 1F3FB 200D 2640 ; minimally-qualified # 🤾🏻‍♀ E4.0 woman playing handball: light skin tone
+1F93E 1F3FC 200D 2640 FE0F ; fully-qualified # 🤾🏼‍♀️ E4.0 woman playing handball: medium-light skin tone
+1F93E 1F3FC 200D 2640 ; minimally-qualified # 🤾🏼‍♀ E4.0 woman playing handball: medium-light skin tone
+1F93E 1F3FD 200D 2640 FE0F ; fully-qualified # 🤾🏽‍♀️ E4.0 woman playing handball: medium skin tone
+1F93E 1F3FD 200D 2640 ; minimally-qualified # 🤾🏽‍♀ E4.0 woman playing handball: medium skin tone
+1F93E 1F3FE 200D 2640 FE0F ; fully-qualified # 🤾🏾‍♀️ E4.0 woman playing handball: medium-dark skin tone
+1F93E 1F3FE 200D 2640 ; minimally-qualified # 🤾🏾‍♀ E4.0 woman playing handball: medium-dark skin tone
+1F93E 1F3FF 200D 2640 FE0F ; fully-qualified # 🤾🏿‍♀️ E4.0 woman playing handball: dark skin tone
+1F93E 1F3FF 200D 2640 ; minimally-qualified # 🤾🏿‍♀ E4.0 woman playing handball: dark skin tone
+1F939 ; fully-qualified # 🤹 E3.0 person juggling
+1F939 1F3FB ; fully-qualified # 🤹🏻 E3.0 person juggling: light skin tone
+1F939 1F3FC ; fully-qualified # 🤹🏼 E3.0 person juggling: medium-light skin tone
+1F939 1F3FD ; fully-qualified # 🤹🏽 E3.0 person juggling: medium skin tone
+1F939 1F3FE ; fully-qualified # 🤹🏾 E3.0 person juggling: medium-dark skin tone
+1F939 1F3FF ; fully-qualified # 🤹🏿 E3.0 person juggling: dark skin tone
+1F939 200D 2642 FE0F ; fully-qualified # 🤹‍♂️ E4.0 man juggling
+1F939 200D 2642 ; minimally-qualified # 🤹‍♂ E4.0 man juggling
+1F939 1F3FB 200D 2642 FE0F ; fully-qualified # 🤹🏻‍♂️ E4.0 man juggling: light skin tone
+1F939 1F3FB 200D 2642 ; minimally-qualified # 🤹🏻‍♂ E4.0 man juggling: light skin tone
+1F939 1F3FC 200D 2642 FE0F ; fully-qualified # 🤹🏼‍♂️ E4.0 man juggling: medium-light skin tone
+1F939 1F3FC 200D 2642 ; minimally-qualified # 🤹🏼‍♂ E4.0 man juggling: medium-light skin tone
+1F939 1F3FD 200D 2642 FE0F ; fully-qualified # 🤹🏽‍♂️ E4.0 man juggling: medium skin tone
+1F939 1F3FD 200D 2642 ; minimally-qualified # 🤹🏽‍♂ E4.0 man juggling: medium skin tone
+1F939 1F3FE 200D 2642 FE0F ; fully-qualified # 🤹🏾‍♂️ E4.0 man juggling: medium-dark skin tone
+1F939 1F3FE 200D 2642 ; minimally-qualified # 🤹🏾‍♂ E4.0 man juggling: medium-dark skin tone
+1F939 1F3FF 200D 2642 FE0F ; fully-qualified # 🤹🏿‍♂️ E4.0 man juggling: dark skin tone
+1F939 1F3FF 200D 2642 ; minimally-qualified # 🤹🏿‍♂ E4.0 man juggling: dark skin tone
+1F939 200D 2640 FE0F ; fully-qualified # 🤹‍♀️ E4.0 woman juggling
+1F939 200D 2640 ; minimally-qualified # 🤹‍♀ E4.0 woman juggling
+1F939 1F3FB 200D 2640 FE0F ; fully-qualified # 🤹🏻‍♀️ E4.0 woman juggling: light skin tone
+1F939 1F3FB 200D 2640 ; minimally-qualified # 🤹🏻‍♀ E4.0 woman juggling: light skin tone
+1F939 1F3FC 200D 2640 FE0F ; fully-qualified # 🤹🏼‍♀️ E4.0 woman juggling: medium-light skin tone
+1F939 1F3FC 200D 2640 ; minimally-qualified # 🤹🏼‍♀ E4.0 woman juggling: medium-light skin tone
+1F939 1F3FD 200D 2640 FE0F ; fully-qualified # 🤹🏽‍♀️ E4.0 woman juggling: medium skin tone
+1F939 1F3FD 200D 2640 ; minimally-qualified # 🤹🏽‍♀ E4.0 woman juggling: medium skin tone
+1F939 1F3FE 200D 2640 FE0F ; fully-qualified # 🤹🏾‍♀️ E4.0 woman juggling: medium-dark skin tone
+1F939 1F3FE 200D 2640 ; minimally-qualified # 🤹🏾‍♀ E4.0 woman juggling: medium-dark skin tone
+1F939 1F3FF 200D 2640 FE0F ; fully-qualified # 🤹🏿‍♀️ E4.0 woman juggling: dark skin tone
+1F939 1F3FF 200D 2640 ; minimally-qualified # 🤹🏿‍♀ E4.0 woman juggling: dark skin tone
+
+# subgroup: person-resting
+1F9D8 ; fully-qualified # 🧘 E5.0 person in lotus position
+1F9D8 1F3FB ; fully-qualified # 🧘🏻 E5.0 person in lotus position: light skin tone
+1F9D8 1F3FC ; fully-qualified # 🧘🏼 E5.0 person in lotus position: medium-light skin tone
+1F9D8 1F3FD ; fully-qualified # 🧘🏽 E5.0 person in lotus position: medium skin tone
+1F9D8 1F3FE ; fully-qualified # 🧘🏾 E5.0 person in lotus position: medium-dark skin tone
+1F9D8 1F3FF ; fully-qualified # 🧘🏿 E5.0 person in lotus position: dark skin tone
+1F9D8 200D 2642 FE0F ; fully-qualified # 🧘‍♂️ E5.0 man in lotus position
+1F9D8 200D 2642 ; minimally-qualified # 🧘‍♂ E5.0 man in lotus position
+1F9D8 1F3FB 200D 2642 FE0F ; fully-qualified # 🧘🏻‍♂️ E5.0 man in lotus position: light skin tone
+1F9D8 1F3FB 200D 2642 ; minimally-qualified # 🧘🏻‍♂ E5.0 man in lotus position: light skin tone
+1F9D8 1F3FC 200D 2642 FE0F ; fully-qualified # 🧘🏼‍♂️ E5.0 man in lotus position: medium-light skin tone
+1F9D8 1F3FC 200D 2642 ; minimally-qualified # 🧘🏼‍♂ E5.0 man in lotus position: medium-light skin tone
+1F9D8 1F3FD 200D 2642 FE0F ; fully-qualified # 🧘🏽‍♂️ E5.0 man in lotus position: medium skin tone
+1F9D8 1F3FD 200D 2642 ; minimally-qualified # 🧘🏽‍♂ E5.0 man in lotus position: medium skin tone
+1F9D8 1F3FE 200D 2642 FE0F ; fully-qualified # 🧘🏾‍♂️ E5.0 man in lotus position: medium-dark skin tone
+1F9D8 1F3FE 200D 2642 ; minimally-qualified # 🧘🏾‍♂ E5.0 man in lotus position: medium-dark skin tone
+1F9D8 1F3FF 200D 2642 FE0F ; fully-qualified # 🧘🏿‍♂️ E5.0 man in lotus position: dark skin tone
+1F9D8 1F3FF 200D 2642 ; minimally-qualified # 🧘🏿‍♂ E5.0 man in lotus position: dark skin tone
+1F9D8 200D 2640 FE0F ; fully-qualified # 🧘‍♀️ E5.0 woman in lotus position
+1F9D8 200D 2640 ; minimally-qualified # 🧘‍♀ E5.0 woman in lotus position
+1F9D8 1F3FB 200D 2640 FE0F ; fully-qualified # 🧘🏻‍♀️ E5.0 woman in lotus position: light skin tone
+1F9D8 1F3FB 200D 2640 ; minimally-qualified # 🧘🏻‍♀ E5.0 woman in lotus position: light skin tone
+1F9D8 1F3FC 200D 2640 FE0F ; fully-qualified # 🧘🏼‍♀️ E5.0 woman in lotus position: medium-light skin tone
+1F9D8 1F3FC 200D 2640 ; minimally-qualified # 🧘🏼‍♀ E5.0 woman in lotus position: medium-light skin tone
+1F9D8 1F3FD 200D 2640 FE0F ; fully-qualified # 🧘🏽‍♀️ E5.0 woman in lotus position: medium skin tone
+1F9D8 1F3FD 200D 2640 ; minimally-qualified # 🧘🏽‍♀ E5.0 woman in lotus position: medium skin tone
+1F9D8 1F3FE 200D 2640 FE0F ; fully-qualified # 🧘🏾‍♀️ E5.0 woman in lotus position: medium-dark skin tone
+1F9D8 1F3FE 200D 2640 ; minimally-qualified # 🧘🏾‍♀ E5.0 woman in lotus position: medium-dark skin tone
+1F9D8 1F3FF 200D 2640 FE0F ; fully-qualified # 🧘🏿‍♀️ E5.0 woman in lotus position: dark skin tone
+1F9D8 1F3FF 200D 2640 ; minimally-qualified # 🧘🏿‍♀ E5.0 woman in lotus position: dark skin tone
+1F6C0 ; fully-qualified # 🛀 E0.6 person taking bath
+1F6C0 1F3FB ; fully-qualified # 🛀🏻 E1.0 person taking bath: light skin tone
+1F6C0 1F3FC ; fully-qualified # 🛀🏼 E1.0 person taking bath: medium-light skin tone
+1F6C0 1F3FD ; fully-qualified # 🛀🏽 E1.0 person taking bath: medium skin tone
+1F6C0 1F3FE ; fully-qualified # 🛀🏾 E1.0 person taking bath: medium-dark skin tone
+1F6C0 1F3FF ; fully-qualified # 🛀🏿 E1.0 person taking bath: dark skin tone
+1F6CC ; fully-qualified # 🛌 E1.0 person in bed
+1F6CC 1F3FB ; fully-qualified # 🛌🏻 E4.0 person in bed: light skin tone
+1F6CC 1F3FC ; fully-qualified # 🛌🏼 E4.0 person in bed: medium-light skin tone
+1F6CC 1F3FD ; fully-qualified # 🛌🏽 E4.0 person in bed: medium skin tone
+1F6CC 1F3FE ; fully-qualified # 🛌🏾 E4.0 person in bed: medium-dark skin tone
+1F6CC 1F3FF ; fully-qualified # 🛌🏿 E4.0 person in bed: dark skin tone
+
+# subgroup: family
+1F9D1 200D 1F91D 200D 1F9D1 ; fully-qualified # 🧑‍🤝‍🧑 E12.0 people holding hands
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏻‍🤝‍🧑🏻 E12.0 people holding hands: light skin tone
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏻‍🤝‍🧑🏼 E12.1 people holding hands: light skin tone, medium-light skin tone
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏻‍🤝‍🧑🏽 E12.1 people holding hands: light skin tone, medium skin tone
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏻‍🤝‍🧑🏾 E12.1 people holding hands: light skin tone, medium-dark skin tone
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏻‍🤝‍🧑🏿 E12.1 people holding hands: light skin tone, dark skin tone
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏼‍🤝‍🧑🏻 E12.0 people holding hands: medium-light skin tone, light skin tone
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏼‍🤝‍🧑🏼 E12.0 people holding hands: medium-light skin tone
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏼‍🤝‍🧑🏽 E12.1 people holding hands: medium-light skin tone, medium skin tone
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏼‍🤝‍🧑🏾 E12.1 people holding hands: medium-light skin tone, medium-dark skin tone
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏼‍🤝‍🧑🏿 E12.1 people holding hands: medium-light skin tone, dark skin tone
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏽‍🤝‍🧑🏻 E12.0 people holding hands: medium skin tone, light skin tone
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏽‍🤝‍🧑🏼 E12.0 people holding hands: medium skin tone, medium-light skin tone
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏽‍🤝‍🧑🏽 E12.0 people holding hands: medium skin tone
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏽‍🤝‍🧑🏾 E12.1 people holding hands: medium skin tone, medium-dark skin tone
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏽‍🤝‍🧑🏿 E12.1 people holding hands: medium skin tone, dark skin tone
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏾‍🤝‍🧑🏻 E12.0 people holding hands: medium-dark skin tone, light skin tone
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏾‍🤝‍🧑🏼 E12.0 people holding hands: medium-dark skin tone, medium-light skin tone
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏾‍🤝‍🧑🏽 E12.0 people holding hands: medium-dark skin tone, medium skin tone
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏾‍🤝‍🧑🏾 E12.0 people holding hands: medium-dark skin tone
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏾‍🤝‍🧑🏿 E12.1 people holding hands: medium-dark skin tone, dark skin tone
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏿‍🤝‍🧑🏻 E12.0 people holding hands: dark skin tone, light skin tone
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏿‍🤝‍🧑🏼 E12.0 people holding hands: dark skin tone, medium-light skin tone
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏿‍🤝‍🧑🏽 E12.0 people holding hands: dark skin tone, medium skin tone
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏿‍🤝‍🧑🏾 E12.0 people holding hands: dark skin tone, medium-dark skin tone
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏿‍🤝‍🧑🏿 E12.0 people holding hands: dark skin tone
+1F46D ; fully-qualified # 👭 E1.0 women holding hands
+1F46D 1F3FB ; fully-qualified # 👭🏻 E12.0 women holding hands: light skin tone
+1F469 1F3FB 200D 1F91D 200D 1F469 1F3FC ; fully-qualified # 👩🏻‍🤝‍👩🏼 E12.1 women holding hands: light skin tone, medium-light skin tone
+1F469 1F3FB 200D 1F91D 200D 1F469 1F3FD ; fully-qualified # 👩🏻‍🤝‍👩🏽 E12.1 women holding hands: light skin tone, medium skin tone
+1F469 1F3FB 200D 1F91D 200D 1F469 1F3FE ; fully-qualified # 👩🏻‍🤝‍👩🏾 E12.1 women holding hands: light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 1F91D 200D 1F469 1F3FF ; fully-qualified # 👩🏻‍🤝‍👩🏿 E12.1 women holding hands: light skin tone, dark skin tone
+1F469 1F3FC 200D 1F91D 200D 1F469 1F3FB ; fully-qualified # 👩🏼‍🤝‍👩🏻 E12.0 women holding hands: medium-light skin tone, light skin tone
+1F46D 1F3FC ; fully-qualified # 👭🏼 E12.0 women holding hands: medium-light skin tone
+1F469 1F3FC 200D 1F91D 200D 1F469 1F3FD ; fully-qualified # 👩🏼‍🤝‍👩🏽 E12.1 women holding hands: medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 1F91D 200D 1F469 1F3FE ; fully-qualified # 👩🏼‍🤝‍👩🏾 E12.1 women holding hands: medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 1F91D 200D 1F469 1F3FF ; fully-qualified # 👩🏼‍🤝‍👩🏿 E12.1 women holding hands: medium-light skin tone, dark skin tone
+1F469 1F3FD 200D 1F91D 200D 1F469 1F3FB ; fully-qualified # 👩🏽‍🤝‍👩🏻 E12.0 women holding hands: medium skin tone, light skin tone
+1F469 1F3FD 200D 1F91D 200D 1F469 1F3FC ; fully-qualified # 👩🏽‍🤝‍👩🏼 E12.0 women holding hands: medium skin tone, medium-light skin tone
+1F46D 1F3FD ; fully-qualified # 👭🏽 E12.0 women holding hands: medium skin tone
+1F469 1F3FD 200D 1F91D 200D 1F469 1F3FE ; fully-qualified # 👩🏽‍🤝‍👩🏾 E12.1 women holding hands: medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 1F91D 200D 1F469 1F3FF ; fully-qualified # 👩🏽‍🤝‍👩🏿 E12.1 women holding hands: medium skin tone, dark skin tone
+1F469 1F3FE 200D 1F91D 200D 1F469 1F3FB ; fully-qualified # 👩🏾‍🤝‍👩🏻 E12.0 women holding hands: medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 1F91D 200D 1F469 1F3FC ; fully-qualified # 👩🏾‍🤝‍👩🏼 E12.0 women holding hands: medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 1F91D 200D 1F469 1F3FD ; fully-qualified # 👩🏾‍🤝‍👩🏽 E12.0 women holding hands: medium-dark skin tone, medium skin tone
+1F46D 1F3FE ; fully-qualified # 👭🏾 E12.0 women holding hands: medium-dark skin tone
+1F469 1F3FE 200D 1F91D 200D 1F469 1F3FF ; fully-qualified # 👩🏾‍🤝‍👩🏿 E12.1 women holding hands: medium-dark skin tone, dark skin tone
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FB ; fully-qualified # 👩🏿‍🤝‍👩🏻 E12.0 women holding hands: dark skin tone, light skin tone
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FC ; fully-qualified # 👩🏿‍🤝‍👩🏼 E12.0 women holding hands: dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FD ; fully-qualified # 👩🏿‍🤝‍👩🏽 E12.0 women holding hands: dark skin tone, medium skin tone
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FE ; fully-qualified # 👩🏿‍🤝‍👩🏾 E12.0 women holding hands: dark skin tone, medium-dark skin tone
+1F46D 1F3FF ; fully-qualified # 👭🏿 E12.0 women holding hands: dark skin tone
+1F46B ; fully-qualified # 👫 E0.6 woman and man holding hands
+1F46B 1F3FB ; fully-qualified # 👫🏻 E12.0 woman and man holding hands: light skin tone
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👩🏻‍🤝‍👨🏼 E12.0 woman and man holding hands: light skin tone, medium-light skin tone
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👩🏻‍🤝‍👨🏽 E12.0 woman and man holding hands: light skin tone, medium skin tone
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👩🏻‍🤝‍👨🏾 E12.0 woman and man holding hands: light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👩🏻‍🤝‍👨🏿 E12.0 woman and man holding hands: light skin tone, dark skin tone
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👩🏼‍🤝‍👨🏻 E12.0 woman and man holding hands: medium-light skin tone, light skin tone
+1F46B 1F3FC ; fully-qualified # 👫🏼 E12.0 woman and man holding hands: medium-light skin tone
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👩🏼‍🤝‍👨🏽 E12.0 woman and man holding hands: medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👩🏼‍🤝‍👨🏾 E12.0 woman and man holding hands: medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👩🏼‍🤝‍👨🏿 E12.0 woman and man holding hands: medium-light skin tone, dark skin tone
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👩🏽‍🤝‍👨🏻 E12.0 woman and man holding hands: medium skin tone, light skin tone
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👩🏽‍🤝‍👨🏼 E12.0 woman and man holding hands: medium skin tone, medium-light skin tone
+1F46B 1F3FD ; fully-qualified # 👫🏽 E12.0 woman and man holding hands: medium skin tone
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👩🏽‍🤝‍👨🏾 E12.0 woman and man holding hands: medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👩🏽‍🤝‍👨🏿 E12.0 woman and man holding hands: medium skin tone, dark skin tone
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👩🏾‍🤝‍👨🏻 E12.0 woman and man holding hands: medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👩🏾‍🤝‍👨🏼 E12.0 woman and man holding hands: medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👩🏾‍🤝‍👨🏽 E12.0 woman and man holding hands: medium-dark skin tone, medium skin tone
+1F46B 1F3FE ; fully-qualified # 👫🏾 E12.0 woman and man holding hands: medium-dark skin tone
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👩🏾‍🤝‍👨🏿 E12.0 woman and man holding hands: medium-dark skin tone, dark skin tone
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👩🏿‍🤝‍👨🏻 E12.0 woman and man holding hands: dark skin tone, light skin tone
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👩🏿‍🤝‍👨🏼 E12.0 woman and man holding hands: dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👩🏿‍🤝‍👨🏽 E12.0 woman and man holding hands: dark skin tone, medium skin tone
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👩🏿‍🤝‍👨🏾 E12.0 woman and man holding hands: dark skin tone, medium-dark skin tone
+1F46B 1F3FF ; fully-qualified # 👫🏿 E12.0 woman and man holding hands: dark skin tone
+1F46C ; fully-qualified # 👬 E1.0 men holding hands
+1F46C 1F3FB ; fully-qualified # 👬🏻 E12.0 men holding hands: light skin tone
+1F468 1F3FB 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👨🏻‍🤝‍👨🏼 E12.1 men holding hands: light skin tone, medium-light skin tone
+1F468 1F3FB 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👨🏻‍🤝‍👨🏽 E12.1 men holding hands: light skin tone, medium skin tone
+1F468 1F3FB 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👨🏻‍🤝‍👨🏾 E12.1 men holding hands: light skin tone, medium-dark skin tone
+1F468 1F3FB 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👨🏻‍🤝‍👨🏿 E12.1 men holding hands: light skin tone, dark skin tone
+1F468 1F3FC 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👨🏼‍🤝‍👨🏻 E12.0 men holding hands: medium-light skin tone, light skin tone
+1F46C 1F3FC ; fully-qualified # 👬🏼 E12.0 men holding hands: medium-light skin tone
+1F468 1F3FC 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👨🏼‍🤝‍👨🏽 E12.1 men holding hands: medium-light skin tone, medium skin tone
+1F468 1F3FC 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👨🏼‍🤝‍👨🏾 E12.1 men holding hands: medium-light skin tone, medium-dark skin tone
+1F468 1F3FC 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👨🏼‍🤝‍👨🏿 E12.1 men holding hands: medium-light skin tone, dark skin tone
+1F468 1F3FD 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👨🏽‍🤝‍👨🏻 E12.0 men holding hands: medium skin tone, light skin tone
+1F468 1F3FD 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👨🏽‍🤝‍👨🏼 E12.0 men holding hands: medium skin tone, medium-light skin tone
+1F46C 1F3FD ; fully-qualified # 👬🏽 E12.0 men holding hands: medium skin tone
+1F468 1F3FD 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👨🏽‍🤝‍👨🏾 E12.1 men holding hands: medium skin tone, medium-dark skin tone
+1F468 1F3FD 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👨🏽‍🤝‍👨🏿 E12.1 men holding hands: medium skin tone, dark skin tone
+1F468 1F3FE 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👨🏾‍🤝‍👨🏻 E12.0 men holding hands: medium-dark skin tone, light skin tone
+1F468 1F3FE 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👨🏾‍🤝‍👨🏼 E12.0 men holding hands: medium-dark skin tone, medium-light skin tone
+1F468 1F3FE 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👨🏾‍🤝‍👨🏽 E12.0 men holding hands: medium-dark skin tone, medium skin tone
+1F46C 1F3FE ; fully-qualified # 👬🏾 E12.0 men holding hands: medium-dark skin tone
+1F468 1F3FE 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👨🏾‍🤝‍👨🏿 E12.1 men holding hands: medium-dark skin tone, dark skin tone
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👨🏿‍🤝‍👨🏻 E12.0 men holding hands: dark skin tone, light skin tone
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👨🏿‍🤝‍👨🏼 E12.0 men holding hands: dark skin tone, medium-light skin tone
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👨🏿‍🤝‍👨🏽 E12.0 men holding hands: dark skin tone, medium skin tone
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👨🏿‍🤝‍👨🏾 E12.0 men holding hands: dark skin tone, medium-dark skin tone
+1F46C 1F3FF ; fully-qualified # 👬🏿 E12.0 men holding hands: dark skin tone
+1F48F ; fully-qualified # 💏 E0.6 kiss
+1F48F 1F3FB ; fully-qualified # 💏🏻 E13.1 kiss: light skin tone
+1F48F 1F3FC ; fully-qualified # 💏🏼 E13.1 kiss: medium-light skin tone
+1F48F 1F3FD ; fully-qualified # 💏🏽 E13.1 kiss: medium skin tone
+1F48F 1F3FE ; fully-qualified # 💏🏾 E13.1 kiss: medium-dark skin tone
+1F48F 1F3FF ; fully-qualified # 💏🏿 E13.1 kiss: dark skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏻‍❤️‍💋‍🧑🏼 E13.1 kiss: person, person, light skin tone, medium-light skin tone
+1F9D1 1F3FB 200D 2764 200D 1F48B 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏻‍❤‍💋‍🧑🏼 E13.1 kiss: person, person, light skin tone, medium-light skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏻‍❤️‍💋‍🧑🏽 E13.1 kiss: person, person, light skin tone, medium skin tone
+1F9D1 1F3FB 200D 2764 200D 1F48B 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏻‍❤‍💋‍🧑🏽 E13.1 kiss: person, person, light skin tone, medium skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏻‍❤️‍💋‍🧑🏾 E13.1 kiss: person, person, light skin tone, medium-dark skin tone
+1F9D1 1F3FB 200D 2764 200D 1F48B 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏻‍❤‍💋‍🧑🏾 E13.1 kiss: person, person, light skin tone, medium-dark skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏻‍❤️‍💋‍🧑🏿 E13.1 kiss: person, person, light skin tone, dark skin tone
+1F9D1 1F3FB 200D 2764 200D 1F48B 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏻‍❤‍💋‍🧑🏿 E13.1 kiss: person, person, light skin tone, dark skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏼‍❤️‍💋‍🧑🏻 E13.1 kiss: person, person, medium-light skin tone, light skin tone
+1F9D1 1F3FC 200D 2764 200D 1F48B 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏼‍❤‍💋‍🧑🏻 E13.1 kiss: person, person, medium-light skin tone, light skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏼‍❤️‍💋‍🧑🏽 E13.1 kiss: person, person, medium-light skin tone, medium skin tone
+1F9D1 1F3FC 200D 2764 200D 1F48B 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏼‍❤‍💋‍🧑🏽 E13.1 kiss: person, person, medium-light skin tone, medium skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏼‍❤️‍💋‍🧑🏾 E13.1 kiss: person, person, medium-light skin tone, medium-dark skin tone
+1F9D1 1F3FC 200D 2764 200D 1F48B 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏼‍❤‍💋‍🧑🏾 E13.1 kiss: person, person, medium-light skin tone, medium-dark skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏼‍❤️‍💋‍🧑🏿 E13.1 kiss: person, person, medium-light skin tone, dark skin tone
+1F9D1 1F3FC 200D 2764 200D 1F48B 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏼‍❤‍💋‍🧑🏿 E13.1 kiss: person, person, medium-light skin tone, dark skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏽‍❤️‍💋‍🧑🏻 E13.1 kiss: person, person, medium skin tone, light skin tone
+1F9D1 1F3FD 200D 2764 200D 1F48B 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏽‍❤‍💋‍🧑🏻 E13.1 kiss: person, person, medium skin tone, light skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏽‍❤️‍💋‍🧑🏼 E13.1 kiss: person, person, medium skin tone, medium-light skin tone
+1F9D1 1F3FD 200D 2764 200D 1F48B 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏽‍❤‍💋‍🧑🏼 E13.1 kiss: person, person, medium skin tone, medium-light skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏽‍❤️‍💋‍🧑🏾 E13.1 kiss: person, person, medium skin tone, medium-dark skin tone
+1F9D1 1F3FD 200D 2764 200D 1F48B 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏽‍❤‍💋‍🧑🏾 E13.1 kiss: person, person, medium skin tone, medium-dark skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏽‍❤️‍💋‍🧑🏿 E13.1 kiss: person, person, medium skin tone, dark skin tone
+1F9D1 1F3FD 200D 2764 200D 1F48B 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏽‍❤‍💋‍🧑🏿 E13.1 kiss: person, person, medium skin tone, dark skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏾‍❤️‍💋‍🧑🏻 E13.1 kiss: person, person, medium-dark skin tone, light skin tone
+1F9D1 1F3FE 200D 2764 200D 1F48B 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏾‍❤‍💋‍🧑🏻 E13.1 kiss: person, person, medium-dark skin tone, light skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏾‍❤️‍💋‍🧑🏼 E13.1 kiss: person, person, medium-dark skin tone, medium-light skin tone
+1F9D1 1F3FE 200D 2764 200D 1F48B 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏾‍❤‍💋‍🧑🏼 E13.1 kiss: person, person, medium-dark skin tone, medium-light skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏾‍❤️‍💋‍🧑🏽 E13.1 kiss: person, person, medium-dark skin tone, medium skin tone
+1F9D1 1F3FE 200D 2764 200D 1F48B 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏾‍❤‍💋‍🧑🏽 E13.1 kiss: person, person, medium-dark skin tone, medium skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏾‍❤️‍💋‍🧑🏿 E13.1 kiss: person, person, medium-dark skin tone, dark skin tone
+1F9D1 1F3FE 200D 2764 200D 1F48B 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏾‍❤‍💋‍🧑🏿 E13.1 kiss: person, person, medium-dark skin tone, dark skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏿‍❤️‍💋‍🧑🏻 E13.1 kiss: person, person, dark skin tone, light skin tone
+1F9D1 1F3FF 200D 2764 200D 1F48B 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏿‍❤‍💋‍🧑🏻 E13.1 kiss: person, person, dark skin tone, light skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏿‍❤️‍💋‍🧑🏼 E13.1 kiss: person, person, dark skin tone, medium-light skin tone
+1F9D1 1F3FF 200D 2764 200D 1F48B 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏿‍❤‍💋‍🧑🏼 E13.1 kiss: person, person, dark skin tone, medium-light skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏿‍❤️‍💋‍🧑🏽 E13.1 kiss: person, person, dark skin tone, medium skin tone
+1F9D1 1F3FF 200D 2764 200D 1F48B 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏿‍❤‍💋‍🧑🏽 E13.1 kiss: person, person, dark skin tone, medium skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏿‍❤️‍💋‍🧑🏾 E13.1 kiss: person, person, dark skin tone, medium-dark skin tone
+1F9D1 1F3FF 200D 2764 200D 1F48B 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏿‍❤‍💋‍🧑🏾 E13.1 kiss: person, person, dark skin tone, medium-dark skin tone
+1F469 200D 2764 FE0F 200D 1F48B 200D 1F468 ; fully-qualified # 👩‍❤️‍💋‍👨 E2.0 kiss: woman, man
+1F469 200D 2764 200D 1F48B 200D 1F468 ; minimally-qualified # 👩‍❤‍💋‍👨 E2.0 kiss: woman, man
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👩🏻‍❤️‍💋‍👨🏻 E13.1 kiss: woman, man, light skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👩🏻‍❤‍💋‍👨🏻 E13.1 kiss: woman, man, light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👩🏻‍❤️‍💋‍👨🏼 E13.1 kiss: woman, man, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👩🏻‍❤‍💋‍👨🏼 E13.1 kiss: woman, man, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👩🏻‍❤️‍💋‍👨🏽 E13.1 kiss: woman, man, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👩🏻‍❤‍💋‍👨🏽 E13.1 kiss: woman, man, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👩🏻‍❤️‍💋‍👨🏾 E13.1 kiss: woman, man, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👩🏻‍❤‍💋‍👨🏾 E13.1 kiss: woman, man, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👩🏻‍❤️‍💋‍👨🏿 E13.1 kiss: woman, man, light skin tone, dark skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👩🏻‍❤‍💋‍👨🏿 E13.1 kiss: woman, man, light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👩🏼‍❤️‍💋‍👨🏻 E13.1 kiss: woman, man, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👩🏼‍❤‍💋‍👨🏻 E13.1 kiss: woman, man, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👩🏼‍❤️‍💋‍👨🏼 E13.1 kiss: woman, man, medium-light skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👩🏼‍❤‍💋‍👨🏼 E13.1 kiss: woman, man, medium-light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👩🏼‍❤️‍💋‍👨🏽 E13.1 kiss: woman, man, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👩🏼‍❤‍💋‍👨🏽 E13.1 kiss: woman, man, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👩🏼‍❤️‍💋‍👨🏾 E13.1 kiss: woman, man, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👩🏼‍❤‍💋‍👨🏾 E13.1 kiss: woman, man, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👩🏼‍❤️‍💋‍👨🏿 E13.1 kiss: woman, man, medium-light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👩🏼‍❤‍💋‍👨🏿 E13.1 kiss: woman, man, medium-light skin tone, dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👩🏽‍❤️‍💋‍👨🏻 E13.1 kiss: woman, man, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👩🏽‍❤‍💋‍👨🏻 E13.1 kiss: woman, man, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👩🏽‍❤️‍💋‍👨🏼 E13.1 kiss: woman, man, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👩🏽‍❤‍💋‍👨🏼 E13.1 kiss: woman, man, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👩🏽‍❤️‍💋‍👨🏽 E13.1 kiss: woman, man, medium skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👩🏽‍❤‍💋‍👨🏽 E13.1 kiss: woman, man, medium skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👩🏽‍❤️‍💋‍👨🏾 E13.1 kiss: woman, man, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👩🏽‍❤‍💋‍👨🏾 E13.1 kiss: woman, man, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👩🏽‍❤️‍💋‍👨🏿 E13.1 kiss: woman, man, medium skin tone, dark skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👩🏽‍❤‍💋‍👨🏿 E13.1 kiss: woman, man, medium skin tone, dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👩🏾‍❤️‍💋‍👨🏻 E13.1 kiss: woman, man, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👩🏾‍❤‍💋‍👨🏻 E13.1 kiss: woman, man, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👩🏾‍❤️‍💋‍👨🏼 E13.1 kiss: woman, man, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👩🏾‍❤‍💋‍👨🏼 E13.1 kiss: woman, man, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👩🏾‍❤️‍💋‍👨🏽 E13.1 kiss: woman, man, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👩🏾‍❤‍💋‍👨🏽 E13.1 kiss: woman, man, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👩🏾‍❤️‍💋‍👨🏾 E13.1 kiss: woman, man, medium-dark skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👩🏾‍❤‍💋‍👨🏾 E13.1 kiss: woman, man, medium-dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👩🏾‍❤️‍💋‍👨🏿 E13.1 kiss: woman, man, medium-dark skin tone, dark skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👩🏾‍❤‍💋‍👨🏿 E13.1 kiss: woman, man, medium-dark skin tone, dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👩🏿‍❤️‍💋‍👨🏻 E13.1 kiss: woman, man, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👩🏿‍❤‍💋‍👨🏻 E13.1 kiss: woman, man, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👩🏿‍❤️‍💋‍👨🏼 E13.1 kiss: woman, man, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👩🏿‍❤‍💋‍👨🏼 E13.1 kiss: woman, man, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👩🏿‍❤️‍💋‍👨🏽 E13.1 kiss: woman, man, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👩🏿‍❤‍💋‍👨🏽 E13.1 kiss: woman, man, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👩🏿‍❤️‍💋‍👨🏾 E13.1 kiss: woman, man, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👩🏿‍❤‍💋‍👨🏾 E13.1 kiss: woman, man, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👩🏿‍❤️‍💋‍👨🏿 E13.1 kiss: woman, man, dark skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👩🏿‍❤‍💋‍👨🏿 E13.1 kiss: woman, man, dark skin tone
+1F468 200D 2764 FE0F 200D 1F48B 200D 1F468 ; fully-qualified # 👨‍❤️‍💋‍👨 E2.0 kiss: man, man
+1F468 200D 2764 200D 1F48B 200D 1F468 ; minimally-qualified # 👨‍❤‍💋‍👨 E2.0 kiss: man, man
+1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👨🏻‍❤️‍💋‍👨🏻 E13.1 kiss: man, man, light skin tone
+1F468 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👨🏻‍❤‍💋‍👨🏻 E13.1 kiss: man, man, light skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👨🏻‍❤️‍💋‍👨🏼 E13.1 kiss: man, man, light skin tone, medium-light skin tone
+1F468 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👨🏻‍❤‍💋‍👨🏼 E13.1 kiss: man, man, light skin tone, medium-light skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👨🏻‍❤️‍💋‍👨🏽 E13.1 kiss: man, man, light skin tone, medium skin tone
+1F468 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👨🏻‍❤‍💋‍👨🏽 E13.1 kiss: man, man, light skin tone, medium skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👨🏻‍❤️‍💋‍👨🏾 E13.1 kiss: man, man, light skin tone, medium-dark skin tone
+1F468 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👨🏻‍❤‍💋‍👨🏾 E13.1 kiss: man, man, light skin tone, medium-dark skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👨🏻‍❤️‍💋‍👨🏿 E13.1 kiss: man, man, light skin tone, dark skin tone
+1F468 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👨🏻‍❤‍💋‍👨🏿 E13.1 kiss: man, man, light skin tone, dark skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👨🏼‍❤️‍💋‍👨🏻 E13.1 kiss: man, man, medium-light skin tone, light skin tone
+1F468 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👨🏼‍❤‍💋‍👨🏻 E13.1 kiss: man, man, medium-light skin tone, light skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👨🏼‍❤️‍💋‍👨🏼 E13.1 kiss: man, man, medium-light skin tone
+1F468 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👨🏼‍❤‍💋‍👨🏼 E13.1 kiss: man, man, medium-light skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👨🏼‍❤️‍💋‍👨🏽 E13.1 kiss: man, man, medium-light skin tone, medium skin tone
+1F468 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👨🏼‍❤‍💋‍👨🏽 E13.1 kiss: man, man, medium-light skin tone, medium skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👨🏼‍❤️‍💋‍👨🏾 E13.1 kiss: man, man, medium-light skin tone, medium-dark skin tone
+1F468 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👨🏼‍❤‍💋‍👨🏾 E13.1 kiss: man, man, medium-light skin tone, medium-dark skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👨🏼‍❤️‍💋‍👨🏿 E13.1 kiss: man, man, medium-light skin tone, dark skin tone
+1F468 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👨🏼‍❤‍💋‍👨🏿 E13.1 kiss: man, man, medium-light skin tone, dark skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👨🏽‍❤️‍💋‍👨🏻 E13.1 kiss: man, man, medium skin tone, light skin tone
+1F468 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👨🏽‍❤‍💋‍👨🏻 E13.1 kiss: man, man, medium skin tone, light skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👨🏽‍❤️‍💋‍👨🏼 E13.1 kiss: man, man, medium skin tone, medium-light skin tone
+1F468 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👨🏽‍❤‍💋‍👨🏼 E13.1 kiss: man, man, medium skin tone, medium-light skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👨🏽‍❤️‍💋‍👨🏽 E13.1 kiss: man, man, medium skin tone
+1F468 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👨🏽‍❤‍💋‍👨🏽 E13.1 kiss: man, man, medium skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👨🏽‍❤️‍💋‍👨🏾 E13.1 kiss: man, man, medium skin tone, medium-dark skin tone
+1F468 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👨🏽‍❤‍💋‍👨🏾 E13.1 kiss: man, man, medium skin tone, medium-dark skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👨🏽‍❤️‍💋‍👨🏿 E13.1 kiss: man, man, medium skin tone, dark skin tone
+1F468 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👨🏽‍❤‍💋‍👨🏿 E13.1 kiss: man, man, medium skin tone, dark skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👨🏾‍❤️‍💋‍👨🏻 E13.1 kiss: man, man, medium-dark skin tone, light skin tone
+1F468 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👨🏾‍❤‍💋‍👨🏻 E13.1 kiss: man, man, medium-dark skin tone, light skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👨🏾‍❤️‍💋‍👨🏼 E13.1 kiss: man, man, medium-dark skin tone, medium-light skin tone
+1F468 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👨🏾‍❤‍💋‍👨🏼 E13.1 kiss: man, man, medium-dark skin tone, medium-light skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👨🏾‍❤️‍💋‍👨🏽 E13.1 kiss: man, man, medium-dark skin tone, medium skin tone
+1F468 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👨🏾‍❤‍💋‍👨🏽 E13.1 kiss: man, man, medium-dark skin tone, medium skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👨🏾‍❤️‍💋‍👨🏾 E13.1 kiss: man, man, medium-dark skin tone
+1F468 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👨🏾‍❤‍💋‍👨🏾 E13.1 kiss: man, man, medium-dark skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👨🏾‍❤️‍💋‍👨🏿 E13.1 kiss: man, man, medium-dark skin tone, dark skin tone
+1F468 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👨🏾‍❤‍💋‍👨🏿 E13.1 kiss: man, man, medium-dark skin tone, dark skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👨🏿‍❤️‍💋‍👨🏻 E13.1 kiss: man, man, dark skin tone, light skin tone
+1F468 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👨🏿‍❤‍💋‍👨🏻 E13.1 kiss: man, man, dark skin tone, light skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👨🏿‍❤️‍💋‍👨🏼 E13.1 kiss: man, man, dark skin tone, medium-light skin tone
+1F468 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👨🏿‍❤‍💋‍👨🏼 E13.1 kiss: man, man, dark skin tone, medium-light skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👨🏿‍❤️‍💋‍👨🏽 E13.1 kiss: man, man, dark skin tone, medium skin tone
+1F468 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👨🏿‍❤‍💋‍👨🏽 E13.1 kiss: man, man, dark skin tone, medium skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👨🏿‍❤️‍💋‍👨🏾 E13.1 kiss: man, man, dark skin tone, medium-dark skin tone
+1F468 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👨🏿‍❤‍💋‍👨🏾 E13.1 kiss: man, man, dark skin tone, medium-dark skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👨🏿‍❤️‍💋‍👨🏿 E13.1 kiss: man, man, dark skin tone
+1F468 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👨🏿‍❤‍💋‍👨🏿 E13.1 kiss: man, man, dark skin tone
+1F469 200D 2764 FE0F 200D 1F48B 200D 1F469 ; fully-qualified # 👩‍❤️‍💋‍👩 E2.0 kiss: woman, woman
+1F469 200D 2764 200D 1F48B 200D 1F469 ; minimally-qualified # 👩‍❤‍💋‍👩 E2.0 kiss: woman, woman
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB ; fully-qualified # 👩🏻‍❤️‍💋‍👩🏻 E13.1 kiss: woman, woman, light skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F469 1F3FB ; minimally-qualified # 👩🏻‍❤‍💋‍👩🏻 E13.1 kiss: woman, woman, light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC ; fully-qualified # 👩🏻‍❤️‍💋‍👩🏼 E13.1 kiss: woman, woman, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F469 1F3FC ; minimally-qualified # 👩🏻‍❤‍💋‍👩🏼 E13.1 kiss: woman, woman, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD ; fully-qualified # 👩🏻‍❤️‍💋‍👩🏽 E13.1 kiss: woman, woman, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F469 1F3FD ; minimally-qualified # 👩🏻‍❤‍💋‍👩🏽 E13.1 kiss: woman, woman, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE ; fully-qualified # 👩🏻‍❤️‍💋‍👩🏾 E13.1 kiss: woman, woman, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F469 1F3FE ; minimally-qualified # 👩🏻‍❤‍💋‍👩🏾 E13.1 kiss: woman, woman, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF ; fully-qualified # 👩🏻‍❤️‍💋‍👩🏿 E13.1 kiss: woman, woman, light skin tone, dark skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F469 1F3FF ; minimally-qualified # 👩🏻‍❤‍💋‍👩🏿 E13.1 kiss: woman, woman, light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB ; fully-qualified # 👩🏼‍❤️‍💋‍👩🏻 E13.1 kiss: woman, woman, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F469 1F3FB ; minimally-qualified # 👩🏼‍❤‍💋‍👩🏻 E13.1 kiss: woman, woman, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC ; fully-qualified # 👩🏼‍❤️‍💋‍👩🏼 E13.1 kiss: woman, woman, medium-light skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F469 1F3FC ; minimally-qualified # 👩🏼‍❤‍💋‍👩🏼 E13.1 kiss: woman, woman, medium-light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD ; fully-qualified # 👩🏼‍❤️‍💋‍👩🏽 E13.1 kiss: woman, woman, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F469 1F3FD ; minimally-qualified # 👩🏼‍❤‍💋‍👩🏽 E13.1 kiss: woman, woman, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE ; fully-qualified # 👩🏼‍❤️‍💋‍👩🏾 E13.1 kiss: woman, woman, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F469 1F3FE ; minimally-qualified # 👩🏼‍❤‍💋‍👩🏾 E13.1 kiss: woman, woman, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF ; fully-qualified # 👩🏼‍❤️‍💋‍👩🏿 E13.1 kiss: woman, woman, medium-light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F469 1F3FF ; minimally-qualified # 👩🏼‍❤‍💋‍👩🏿 E13.1 kiss: woman, woman, medium-light skin tone, dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB ; fully-qualified # 👩🏽‍❤️‍💋‍👩🏻 E13.1 kiss: woman, woman, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F469 1F3FB ; minimally-qualified # 👩🏽‍❤‍💋‍👩🏻 E13.1 kiss: woman, woman, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC ; fully-qualified # 👩🏽‍❤️‍💋‍👩🏼 E13.1 kiss: woman, woman, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F469 1F3FC ; minimally-qualified # 👩🏽‍❤‍💋‍👩🏼 E13.1 kiss: woman, woman, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD ; fully-qualified # 👩🏽‍❤️‍💋‍👩🏽 E13.1 kiss: woman, woman, medium skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F469 1F3FD ; minimally-qualified # 👩🏽‍❤‍💋‍👩🏽 E13.1 kiss: woman, woman, medium skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE ; fully-qualified # 👩🏽‍❤️‍💋‍👩🏾 E13.1 kiss: woman, woman, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F469 1F3FE ; minimally-qualified # 👩🏽‍❤‍💋‍👩🏾 E13.1 kiss: woman, woman, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF ; fully-qualified # 👩🏽‍❤️‍💋‍👩🏿 E13.1 kiss: woman, woman, medium skin tone, dark skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F469 1F3FF ; minimally-qualified # 👩🏽‍❤‍💋‍👩🏿 E13.1 kiss: woman, woman, medium skin tone, dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB ; fully-qualified # 👩🏾‍❤️‍💋‍👩🏻 E13.1 kiss: woman, woman, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F469 1F3FB ; minimally-qualified # 👩🏾‍❤‍💋‍👩🏻 E13.1 kiss: woman, woman, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC ; fully-qualified # 👩🏾‍❤️‍💋‍👩🏼 E13.1 kiss: woman, woman, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F469 1F3FC ; minimally-qualified # 👩🏾‍❤‍💋‍👩🏼 E13.1 kiss: woman, woman, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD ; fully-qualified # 👩🏾‍❤️‍💋‍👩🏽 E13.1 kiss: woman, woman, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F469 1F3FD ; minimally-qualified # 👩🏾‍❤‍💋‍👩🏽 E13.1 kiss: woman, woman, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE ; fully-qualified # 👩🏾‍❤️‍💋‍👩🏾 E13.1 kiss: woman, woman, medium-dark skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F469 1F3FE ; minimally-qualified # 👩🏾‍❤‍💋‍👩🏾 E13.1 kiss: woman, woman, medium-dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF ; fully-qualified # 👩🏾‍❤️‍💋‍👩🏿 E13.1 kiss: woman, woman, medium-dark skin tone, dark skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F469 1F3FF ; minimally-qualified # 👩🏾‍❤‍💋‍👩🏿 E13.1 kiss: woman, woman, medium-dark skin tone, dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB ; fully-qualified # 👩🏿‍❤️‍💋‍👩🏻 E13.1 kiss: woman, woman, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F469 1F3FB ; minimally-qualified # 👩🏿‍❤‍💋‍👩🏻 E13.1 kiss: woman, woman, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC ; fully-qualified # 👩🏿‍❤️‍💋‍👩🏼 E13.1 kiss: woman, woman, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F469 1F3FC ; minimally-qualified # 👩🏿‍❤‍💋‍👩🏼 E13.1 kiss: woman, woman, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD ; fully-qualified # 👩🏿‍❤️‍💋‍👩🏽 E13.1 kiss: woman, woman, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F469 1F3FD ; minimally-qualified # 👩🏿‍❤‍💋‍👩🏽 E13.1 kiss: woman, woman, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE ; fully-qualified # 👩🏿‍❤️‍💋‍👩🏾 E13.1 kiss: woman, woman, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F469 1F3FE ; minimally-qualified # 👩🏿‍❤‍💋‍👩🏾 E13.1 kiss: woman, woman, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF ; fully-qualified # 👩🏿‍❤️‍💋‍👩🏿 E13.1 kiss: woman, woman, dark skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F469 1F3FF ; minimally-qualified # 👩🏿‍❤‍💋‍👩🏿 E13.1 kiss: woman, woman, dark skin tone
+1F491 ; fully-qualified # 💑 E0.6 couple with heart
+1F491 1F3FB ; fully-qualified # 💑🏻 E13.1 couple with heart: light skin tone
+1F491 1F3FC ; fully-qualified # 💑🏼 E13.1 couple with heart: medium-light skin tone
+1F491 1F3FD ; fully-qualified # 💑🏽 E13.1 couple with heart: medium skin tone
+1F491 1F3FE ; fully-qualified # 💑🏾 E13.1 couple with heart: medium-dark skin tone
+1F491 1F3FF ; fully-qualified # 💑🏿 E13.1 couple with heart: dark skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏻‍❤️‍🧑🏼 E13.1 couple with heart: person, person, light skin tone, medium-light skin tone
+1F9D1 1F3FB 200D 2764 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏻‍❤‍🧑🏼 E13.1 couple with heart: person, person, light skin tone, medium-light skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏻‍❤️‍🧑🏽 E13.1 couple with heart: person, person, light skin tone, medium skin tone
+1F9D1 1F3FB 200D 2764 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏻‍❤‍🧑🏽 E13.1 couple with heart: person, person, light skin tone, medium skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏻‍❤️‍🧑🏾 E13.1 couple with heart: person, person, light skin tone, medium-dark skin tone
+1F9D1 1F3FB 200D 2764 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏻‍❤‍🧑🏾 E13.1 couple with heart: person, person, light skin tone, medium-dark skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏻‍❤️‍🧑🏿 E13.1 couple with heart: person, person, light skin tone, dark skin tone
+1F9D1 1F3FB 200D 2764 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏻‍❤‍🧑🏿 E13.1 couple with heart: person, person, light skin tone, dark skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏼‍❤️‍🧑🏻 E13.1 couple with heart: person, person, medium-light skin tone, light skin tone
+1F9D1 1F3FC 200D 2764 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏼‍❤‍🧑🏻 E13.1 couple with heart: person, person, medium-light skin tone, light skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏼‍❤️‍🧑🏽 E13.1 couple with heart: person, person, medium-light skin tone, medium skin tone
+1F9D1 1F3FC 200D 2764 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏼‍❤‍🧑🏽 E13.1 couple with heart: person, person, medium-light skin tone, medium skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏼‍❤️‍🧑🏾 E13.1 couple with heart: person, person, medium-light skin tone, medium-dark skin tone
+1F9D1 1F3FC 200D 2764 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏼‍❤‍🧑🏾 E13.1 couple with heart: person, person, medium-light skin tone, medium-dark skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏼‍❤️‍🧑🏿 E13.1 couple with heart: person, person, medium-light skin tone, dark skin tone
+1F9D1 1F3FC 200D 2764 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏼‍❤‍🧑🏿 E13.1 couple with heart: person, person, medium-light skin tone, dark skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏽‍❤️‍🧑🏻 E13.1 couple with heart: person, person, medium skin tone, light skin tone
+1F9D1 1F3FD 200D 2764 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏽‍❤‍🧑🏻 E13.1 couple with heart: person, person, medium skin tone, light skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏽‍❤️‍🧑🏼 E13.1 couple with heart: person, person, medium skin tone, medium-light skin tone
+1F9D1 1F3FD 200D 2764 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏽‍❤‍🧑🏼 E13.1 couple with heart: person, person, medium skin tone, medium-light skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏽‍❤️‍🧑🏾 E13.1 couple with heart: person, person, medium skin tone, medium-dark skin tone
+1F9D1 1F3FD 200D 2764 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏽‍❤‍🧑🏾 E13.1 couple with heart: person, person, medium skin tone, medium-dark skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏽‍❤️‍🧑🏿 E13.1 couple with heart: person, person, medium skin tone, dark skin tone
+1F9D1 1F3FD 200D 2764 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏽‍❤‍🧑🏿 E13.1 couple with heart: person, person, medium skin tone, dark skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏾‍❤️‍🧑🏻 E13.1 couple with heart: person, person, medium-dark skin tone, light skin tone
+1F9D1 1F3FE 200D 2764 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏾‍❤‍🧑🏻 E13.1 couple with heart: person, person, medium-dark skin tone, light skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏾‍❤️‍🧑🏼 E13.1 couple with heart: person, person, medium-dark skin tone, medium-light skin tone
+1F9D1 1F3FE 200D 2764 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏾‍❤‍🧑🏼 E13.1 couple with heart: person, person, medium-dark skin tone, medium-light skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏾‍❤️‍🧑🏽 E13.1 couple with heart: person, person, medium-dark skin tone, medium skin tone
+1F9D1 1F3FE 200D 2764 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏾‍❤‍🧑🏽 E13.1 couple with heart: person, person, medium-dark skin tone, medium skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏾‍❤️‍🧑🏿 E13.1 couple with heart: person, person, medium-dark skin tone, dark skin tone
+1F9D1 1F3FE 200D 2764 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏾‍❤‍🧑🏿 E13.1 couple with heart: person, person, medium-dark skin tone, dark skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏿‍❤️‍🧑🏻 E13.1 couple with heart: person, person, dark skin tone, light skin tone
+1F9D1 1F3FF 200D 2764 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏿‍❤‍🧑🏻 E13.1 couple with heart: person, person, dark skin tone, light skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏿‍❤️‍🧑🏼 E13.1 couple with heart: person, person, dark skin tone, medium-light skin tone
+1F9D1 1F3FF 200D 2764 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏿‍❤‍🧑🏼 E13.1 couple with heart: person, person, dark skin tone, medium-light skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏿‍❤️‍🧑🏽 E13.1 couple with heart: person, person, dark skin tone, medium skin tone
+1F9D1 1F3FF 200D 2764 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏿‍❤‍🧑🏽 E13.1 couple with heart: person, person, dark skin tone, medium skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏿‍❤️‍🧑🏾 E13.1 couple with heart: person, person, dark skin tone, medium-dark skin tone
+1F9D1 1F3FF 200D 2764 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏿‍❤‍🧑🏾 E13.1 couple with heart: person, person, dark skin tone, medium-dark skin tone
+1F469 200D 2764 FE0F 200D 1F468 ; fully-qualified # 👩‍❤️‍👨 E2.0 couple with heart: woman, man
+1F469 200D 2764 200D 1F468 ; minimally-qualified # 👩‍❤‍👨 E2.0 couple with heart: woman, man
+1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👩🏻‍❤️‍👨🏻 E13.1 couple with heart: woman, man, light skin tone
+1F469 1F3FB 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👩🏻‍❤‍👨🏻 E13.1 couple with heart: woman, man, light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👩🏻‍❤️‍👨🏼 E13.1 couple with heart: woman, man, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👩🏻‍❤‍👨🏼 E13.1 couple with heart: woman, man, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👩🏻‍❤️‍👨🏽 E13.1 couple with heart: woman, man, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👩🏻‍❤‍👨🏽 E13.1 couple with heart: woman, man, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👩🏻‍❤️‍👨🏾 E13.1 couple with heart: woman, man, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👩🏻‍❤‍👨🏾 E13.1 couple with heart: woman, man, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👩🏻‍❤️‍👨🏿 E13.1 couple with heart: woman, man, light skin tone, dark skin tone
+1F469 1F3FB 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👩🏻‍❤‍👨🏿 E13.1 couple with heart: woman, man, light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👩🏼‍❤️‍👨🏻 E13.1 couple with heart: woman, man, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👩🏼‍❤‍👨🏻 E13.1 couple with heart: woman, man, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👩🏼‍❤️‍👨🏼 E13.1 couple with heart: woman, man, medium-light skin tone
+1F469 1F3FC 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👩🏼‍❤‍👨🏼 E13.1 couple with heart: woman, man, medium-light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👩🏼‍❤️‍👨🏽 E13.1 couple with heart: woman, man, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👩🏼‍❤‍👨🏽 E13.1 couple with heart: woman, man, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👩🏼‍❤️‍👨🏾 E13.1 couple with heart: woman, man, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👩🏼‍❤‍👨🏾 E13.1 couple with heart: woman, man, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👩🏼‍❤️‍👨🏿 E13.1 couple with heart: woman, man, medium-light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👩🏼‍❤‍👨🏿 E13.1 couple with heart: woman, man, medium-light skin tone, dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👩🏽‍❤️‍👨🏻 E13.1 couple with heart: woman, man, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👩🏽‍❤‍👨🏻 E13.1 couple with heart: woman, man, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👩🏽‍❤️‍👨🏼 E13.1 couple with heart: woman, man, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👩🏽‍❤‍👨🏼 E13.1 couple with heart: woman, man, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👩🏽‍❤️‍👨🏽 E13.1 couple with heart: woman, man, medium skin tone
+1F469 1F3FD 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👩🏽‍❤‍👨🏽 E13.1 couple with heart: woman, man, medium skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👩🏽‍❤️‍👨🏾 E13.1 couple with heart: woman, man, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👩🏽‍❤‍👨🏾 E13.1 couple with heart: woman, man, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👩🏽‍❤️‍👨🏿 E13.1 couple with heart: woman, man, medium skin tone, dark skin tone
+1F469 1F3FD 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👩🏽‍❤‍👨🏿 E13.1 couple with heart: woman, man, medium skin tone, dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👩🏾‍❤️‍👨🏻 E13.1 couple with heart: woman, man, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👩🏾‍❤‍👨🏻 E13.1 couple with heart: woman, man, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👩🏾‍❤️‍👨🏼 E13.1 couple with heart: woman, man, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👩🏾‍❤‍👨🏼 E13.1 couple with heart: woman, man, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👩🏾‍❤️‍👨🏽 E13.1 couple with heart: woman, man, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👩🏾‍❤‍👨🏽 E13.1 couple with heart: woman, man, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👩🏾‍❤️‍👨🏾 E13.1 couple with heart: woman, man, medium-dark skin tone
+1F469 1F3FE 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👩🏾‍❤‍👨🏾 E13.1 couple with heart: woman, man, medium-dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👩🏾‍❤️‍👨🏿 E13.1 couple with heart: woman, man, medium-dark skin tone, dark skin tone
+1F469 1F3FE 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👩🏾‍❤‍👨🏿 E13.1 couple with heart: woman, man, medium-dark skin tone, dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👩🏿‍❤️‍👨🏻 E13.1 couple with heart: woman, man, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👩🏿‍❤‍👨🏻 E13.1 couple with heart: woman, man, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👩🏿‍❤️‍👨🏼 E13.1 couple with heart: woman, man, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👩🏿‍❤‍👨🏼 E13.1 couple with heart: woman, man, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👩🏿‍❤️‍👨🏽 E13.1 couple with heart: woman, man, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👩🏿‍❤‍👨🏽 E13.1 couple with heart: woman, man, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👩🏿‍❤️‍👨🏾 E13.1 couple with heart: woman, man, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👩🏿‍❤‍👨🏾 E13.1 couple with heart: woman, man, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👩🏿‍❤️‍👨🏿 E13.1 couple with heart: woman, man, dark skin tone
+1F469 1F3FF 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👩🏿‍❤‍👨🏿 E13.1 couple with heart: woman, man, dark skin tone
+1F468 200D 2764 FE0F 200D 1F468 ; fully-qualified # 👨‍❤️‍👨 E2.0 couple with heart: man, man
+1F468 200D 2764 200D 1F468 ; minimally-qualified # 👨‍❤‍👨 E2.0 couple with heart: man, man
+1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👨🏻‍❤️‍👨🏻 E13.1 couple with heart: man, man, light skin tone
+1F468 1F3FB 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👨🏻‍❤‍👨🏻 E13.1 couple with heart: man, man, light skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👨🏻‍❤️‍👨🏼 E13.1 couple with heart: man, man, light skin tone, medium-light skin tone
+1F468 1F3FB 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👨🏻‍❤‍👨🏼 E13.1 couple with heart: man, man, light skin tone, medium-light skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👨🏻‍❤️‍👨🏽 E13.1 couple with heart: man, man, light skin tone, medium skin tone
+1F468 1F3FB 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👨🏻‍❤‍👨🏽 E13.1 couple with heart: man, man, light skin tone, medium skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👨🏻‍❤️‍👨🏾 E13.1 couple with heart: man, man, light skin tone, medium-dark skin tone
+1F468 1F3FB 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👨🏻‍❤‍👨🏾 E13.1 couple with heart: man, man, light skin tone, medium-dark skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👨🏻‍❤️‍👨🏿 E13.1 couple with heart: man, man, light skin tone, dark skin tone
+1F468 1F3FB 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👨🏻‍❤‍👨🏿 E13.1 couple with heart: man, man, light skin tone, dark skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👨🏼‍❤️‍👨🏻 E13.1 couple with heart: man, man, medium-light skin tone, light skin tone
+1F468 1F3FC 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👨🏼‍❤‍👨🏻 E13.1 couple with heart: man, man, medium-light skin tone, light skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👨🏼‍❤️‍👨🏼 E13.1 couple with heart: man, man, medium-light skin tone
+1F468 1F3FC 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👨🏼‍❤‍👨🏼 E13.1 couple with heart: man, man, medium-light skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👨🏼‍❤️‍👨🏽 E13.1 couple with heart: man, man, medium-light skin tone, medium skin tone
+1F468 1F3FC 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👨🏼‍❤‍👨🏽 E13.1 couple with heart: man, man, medium-light skin tone, medium skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👨🏼‍❤️‍👨🏾 E13.1 couple with heart: man, man, medium-light skin tone, medium-dark skin tone
+1F468 1F3FC 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👨🏼‍❤‍👨🏾 E13.1 couple with heart: man, man, medium-light skin tone, medium-dark skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👨🏼‍❤️‍👨🏿 E13.1 couple with heart: man, man, medium-light skin tone, dark skin tone
+1F468 1F3FC 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👨🏼‍❤‍👨🏿 E13.1 couple with heart: man, man, medium-light skin tone, dark skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👨🏽‍❤️‍👨🏻 E13.1 couple with heart: man, man, medium skin tone, light skin tone
+1F468 1F3FD 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👨🏽‍❤‍👨🏻 E13.1 couple with heart: man, man, medium skin tone, light skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👨🏽‍❤️‍👨🏼 E13.1 couple with heart: man, man, medium skin tone, medium-light skin tone
+1F468 1F3FD 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👨🏽‍❤‍👨🏼 E13.1 couple with heart: man, man, medium skin tone, medium-light skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👨🏽‍❤️‍👨🏽 E13.1 couple with heart: man, man, medium skin tone
+1F468 1F3FD 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👨🏽‍❤‍👨🏽 E13.1 couple with heart: man, man, medium skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👨🏽‍❤️‍👨🏾 E13.1 couple with heart: man, man, medium skin tone, medium-dark skin tone
+1F468 1F3FD 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👨🏽‍❤‍👨🏾 E13.1 couple with heart: man, man, medium skin tone, medium-dark skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👨🏽‍❤️‍👨🏿 E13.1 couple with heart: man, man, medium skin tone, dark skin tone
+1F468 1F3FD 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👨🏽‍❤‍👨🏿 E13.1 couple with heart: man, man, medium skin tone, dark skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👨🏾‍❤️‍👨🏻 E13.1 couple with heart: man, man, medium-dark skin tone, light skin tone
+1F468 1F3FE 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👨🏾‍❤‍👨🏻 E13.1 couple with heart: man, man, medium-dark skin tone, light skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👨🏾‍❤️‍👨🏼 E13.1 couple with heart: man, man, medium-dark skin tone, medium-light skin tone
+1F468 1F3FE 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👨🏾‍❤‍👨🏼 E13.1 couple with heart: man, man, medium-dark skin tone, medium-light skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👨🏾‍❤️‍👨🏽 E13.1 couple with heart: man, man, medium-dark skin tone, medium skin tone
+1F468 1F3FE 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👨🏾‍❤‍👨🏽 E13.1 couple with heart: man, man, medium-dark skin tone, medium skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👨🏾‍❤️‍👨🏾 E13.1 couple with heart: man, man, medium-dark skin tone
+1F468 1F3FE 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👨🏾‍❤‍👨🏾 E13.1 couple with heart: man, man, medium-dark skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👨🏾‍❤️‍👨🏿 E13.1 couple with heart: man, man, medium-dark skin tone, dark skin tone
+1F468 1F3FE 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👨🏾‍❤‍👨🏿 E13.1 couple with heart: man, man, medium-dark skin tone, dark skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👨🏿‍❤️‍👨🏻 E13.1 couple with heart: man, man, dark skin tone, light skin tone
+1F468 1F3FF 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👨🏿‍❤‍👨🏻 E13.1 couple with heart: man, man, dark skin tone, light skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👨🏿‍❤️‍👨🏼 E13.1 couple with heart: man, man, dark skin tone, medium-light skin tone
+1F468 1F3FF 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👨🏿‍❤‍👨🏼 E13.1 couple with heart: man, man, dark skin tone, medium-light skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👨🏿‍❤️‍👨🏽 E13.1 couple with heart: man, man, dark skin tone, medium skin tone
+1F468 1F3FF 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👨🏿‍❤‍👨🏽 E13.1 couple with heart: man, man, dark skin tone, medium skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👨🏿‍❤️‍👨🏾 E13.1 couple with heart: man, man, dark skin tone, medium-dark skin tone
+1F468 1F3FF 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👨🏿‍❤‍👨🏾 E13.1 couple with heart: man, man, dark skin tone, medium-dark skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👨🏿‍❤️‍👨🏿 E13.1 couple with heart: man, man, dark skin tone
+1F468 1F3FF 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👨🏿‍❤‍👨🏿 E13.1 couple with heart: man, man, dark skin tone
+1F469 200D 2764 FE0F 200D 1F469 ; fully-qualified # 👩‍❤️‍👩 E2.0 couple with heart: woman, woman
+1F469 200D 2764 200D 1F469 ; minimally-qualified # 👩‍❤‍👩 E2.0 couple with heart: woman, woman
+1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FB ; fully-qualified # 👩🏻‍❤️‍👩🏻 E13.1 couple with heart: woman, woman, light skin tone
+1F469 1F3FB 200D 2764 200D 1F469 1F3FB ; minimally-qualified # 👩🏻‍❤‍👩🏻 E13.1 couple with heart: woman, woman, light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FC ; fully-qualified # 👩🏻‍❤️‍👩🏼 E13.1 couple with heart: woman, woman, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 200D 1F469 1F3FC ; minimally-qualified # 👩🏻‍❤‍👩🏼 E13.1 couple with heart: woman, woman, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FD ; fully-qualified # 👩🏻‍❤️‍👩🏽 E13.1 couple with heart: woman, woman, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 200D 1F469 1F3FD ; minimally-qualified # 👩🏻‍❤‍👩🏽 E13.1 couple with heart: woman, woman, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FE ; fully-qualified # 👩🏻‍❤️‍👩🏾 E13.1 couple with heart: woman, woman, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 200D 1F469 1F3FE ; minimally-qualified # 👩🏻‍❤‍👩🏾 E13.1 couple with heart: woman, woman, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FF ; fully-qualified # 👩🏻‍❤️‍👩🏿 E13.1 couple with heart: woman, woman, light skin tone, dark skin tone
+1F469 1F3FB 200D 2764 200D 1F469 1F3FF ; minimally-qualified # 👩🏻‍❤‍👩🏿 E13.1 couple with heart: woman, woman, light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FB ; fully-qualified # 👩🏼‍❤️‍👩🏻 E13.1 couple with heart: woman, woman, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 200D 1F469 1F3FB ; minimally-qualified # 👩🏼‍❤‍👩🏻 E13.1 couple with heart: woman, woman, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FC ; fully-qualified # 👩🏼‍❤️‍👩🏼 E13.1 couple with heart: woman, woman, medium-light skin tone
+1F469 1F3FC 200D 2764 200D 1F469 1F3FC ; minimally-qualified # 👩🏼‍❤‍👩🏼 E13.1 couple with heart: woman, woman, medium-light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FD ; fully-qualified # 👩🏼‍❤️‍👩🏽 E13.1 couple with heart: woman, woman, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 200D 1F469 1F3FD ; minimally-qualified # 👩🏼‍❤‍👩🏽 E13.1 couple with heart: woman, woman, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FE ; fully-qualified # 👩🏼‍❤️‍👩🏾 E13.1 couple with heart: woman, woman, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 200D 1F469 1F3FE ; minimally-qualified # 👩🏼‍❤‍👩🏾 E13.1 couple with heart: woman, woman, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FF ; fully-qualified # 👩🏼‍❤️‍👩🏿 E13.1 couple with heart: woman, woman, medium-light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 200D 1F469 1F3FF ; minimally-qualified # 👩🏼‍❤‍👩🏿 E13.1 couple with heart: woman, woman, medium-light skin tone, dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FB ; fully-qualified # 👩🏽‍❤️‍👩🏻 E13.1 couple with heart: woman, woman, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 200D 1F469 1F3FB ; minimally-qualified # 👩🏽‍❤‍👩🏻 E13.1 couple with heart: woman, woman, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FC ; fully-qualified # 👩🏽‍❤️‍👩🏼 E13.1 couple with heart: woman, woman, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 200D 1F469 1F3FC ; minimally-qualified # 👩🏽‍❤‍👩🏼 E13.1 couple with heart: woman, woman, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FD ; fully-qualified # 👩🏽‍❤️‍👩🏽 E13.1 couple with heart: woman, woman, medium skin tone
+1F469 1F3FD 200D 2764 200D 1F469 1F3FD ; minimally-qualified # 👩🏽‍❤‍👩🏽 E13.1 couple with heart: woman, woman, medium skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FE ; fully-qualified # 👩🏽‍❤️‍👩🏾 E13.1 couple with heart: woman, woman, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 200D 1F469 1F3FE ; minimally-qualified # 👩🏽‍❤‍👩🏾 E13.1 couple with heart: woman, woman, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FF ; fully-qualified # 👩🏽‍❤️‍👩🏿 E13.1 couple with heart: woman, woman, medium skin tone, dark skin tone
+1F469 1F3FD 200D 2764 200D 1F469 1F3FF ; minimally-qualified # 👩🏽‍❤‍👩🏿 E13.1 couple with heart: woman, woman, medium skin tone, dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FB ; fully-qualified # 👩🏾‍❤️‍👩🏻 E13.1 couple with heart: woman, woman, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 200D 1F469 1F3FB ; minimally-qualified # 👩🏾‍❤‍👩🏻 E13.1 couple with heart: woman, woman, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FC ; fully-qualified # 👩🏾‍❤️‍👩🏼 E13.1 couple with heart: woman, woman, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 200D 1F469 1F3FC ; minimally-qualified # 👩🏾‍❤‍👩🏼 E13.1 couple with heart: woman, woman, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FD ; fully-qualified # 👩🏾‍❤️‍👩🏽 E13.1 couple with heart: woman, woman, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 200D 1F469 1F3FD ; minimally-qualified # 👩🏾‍❤‍👩🏽 E13.1 couple with heart: woman, woman, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FE ; fully-qualified # 👩🏾‍❤️‍👩🏾 E13.1 couple with heart: woman, woman, medium-dark skin tone
+1F469 1F3FE 200D 2764 200D 1F469 1F3FE ; minimally-qualified # 👩🏾‍❤‍👩🏾 E13.1 couple with heart: woman, woman, medium-dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FF ; fully-qualified # 👩🏾‍❤️‍👩🏿 E13.1 couple with heart: woman, woman, medium-dark skin tone, dark skin tone
+1F469 1F3FE 200D 2764 200D 1F469 1F3FF ; minimally-qualified # 👩🏾‍❤‍👩🏿 E13.1 couple with heart: woman, woman, medium-dark skin tone, dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FB ; fully-qualified # 👩🏿‍❤️‍👩🏻 E13.1 couple with heart: woman, woman, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 200D 1F469 1F3FB ; minimally-qualified # 👩🏿‍❤‍👩🏻 E13.1 couple with heart: woman, woman, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FC ; fully-qualified # 👩🏿‍❤️‍👩🏼 E13.1 couple with heart: woman, woman, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 200D 1F469 1F3FC ; minimally-qualified # 👩🏿‍❤‍👩🏼 E13.1 couple with heart: woman, woman, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FD ; fully-qualified # 👩🏿‍❤️‍👩🏽 E13.1 couple with heart: woman, woman, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 200D 1F469 1F3FD ; minimally-qualified # 👩🏿‍❤‍👩🏽 E13.1 couple with heart: woman, woman, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FE ; fully-qualified # 👩🏿‍❤️‍👩🏾 E13.1 couple with heart: woman, woman, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 200D 1F469 1F3FE ; minimally-qualified # 👩🏿‍❤‍👩🏾 E13.1 couple with heart: woman, woman, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FF ; fully-qualified # 👩🏿‍❤️‍👩🏿 E13.1 couple with heart: woman, woman, dark skin tone
+1F469 1F3FF 200D 2764 200D 1F469 1F3FF ; minimally-qualified # 👩🏿‍❤‍👩🏿 E13.1 couple with heart: woman, woman, dark skin tone
+1F46A ; fully-qualified # 👪 E0.6 family
+1F468 200D 1F469 200D 1F466 ; fully-qualified # 👨‍👩‍👦 E2.0 family: man, woman, boy
+1F468 200D 1F469 200D 1F467 ; fully-qualified # 👨‍👩‍👧 E2.0 family: man, woman, girl
+1F468 200D 1F469 200D 1F467 200D 1F466 ; fully-qualified # 👨‍👩‍👧‍👦 E2.0 family: man, woman, girl, boy
+1F468 200D 1F469 200D 1F466 200D 1F466 ; fully-qualified # 👨‍👩‍👦‍👦 E2.0 family: man, woman, boy, boy
+1F468 200D 1F469 200D 1F467 200D 1F467 ; fully-qualified # 👨‍👩‍👧‍👧 E2.0 family: man, woman, girl, girl
+1F468 200D 1F468 200D 1F466 ; fully-qualified # 👨‍👨‍👦 E2.0 family: man, man, boy
+1F468 200D 1F468 200D 1F467 ; fully-qualified # 👨‍👨‍👧 E2.0 family: man, man, girl
+1F468 200D 1F468 200D 1F467 200D 1F466 ; fully-qualified # 👨‍👨‍👧‍👦 E2.0 family: man, man, girl, boy
+1F468 200D 1F468 200D 1F466 200D 1F466 ; fully-qualified # 👨‍👨‍👦‍👦 E2.0 family: man, man, boy, boy
+1F468 200D 1F468 200D 1F467 200D 1F467 ; fully-qualified # 👨‍👨‍👧‍👧 E2.0 family: man, man, girl, girl
+1F469 200D 1F469 200D 1F466 ; fully-qualified # 👩‍👩‍👦 E2.0 family: woman, woman, boy
+1F469 200D 1F469 200D 1F467 ; fully-qualified # 👩‍👩‍👧 E2.0 family: woman, woman, girl
+1F469 200D 1F469 200D 1F467 200D 1F466 ; fully-qualified # 👩‍👩‍👧‍👦 E2.0 family: woman, woman, girl, boy
+1F469 200D 1F469 200D 1F466 200D 1F466 ; fully-qualified # 👩‍👩‍👦‍👦 E2.0 family: woman, woman, boy, boy
+1F469 200D 1F469 200D 1F467 200D 1F467 ; fully-qualified # 👩‍👩‍👧‍👧 E2.0 family: woman, woman, girl, girl
+1F468 200D 1F466 ; fully-qualified # 👨‍👦 E4.0 family: man, boy
+1F468 200D 1F466 200D 1F466 ; fully-qualified # 👨‍👦‍👦 E4.0 family: man, boy, boy
+1F468 200D 1F467 ; fully-qualified # 👨‍👧 E4.0 family: man, girl
+1F468 200D 1F467 200D 1F466 ; fully-qualified # 👨‍👧‍👦 E4.0 family: man, girl, boy
+1F468 200D 1F467 200D 1F467 ; fully-qualified # 👨‍👧‍👧 E4.0 family: man, girl, girl
+1F469 200D 1F466 ; fully-qualified # 👩‍👦 E4.0 family: woman, boy
+1F469 200D 1F466 200D 1F466 ; fully-qualified # 👩‍👦‍👦 E4.0 family: woman, boy, boy
+1F469 200D 1F467 ; fully-qualified # 👩‍👧 E4.0 family: woman, girl
+1F469 200D 1F467 200D 1F466 ; fully-qualified # 👩‍👧‍👦 E4.0 family: woman, girl, boy
+1F469 200D 1F467 200D 1F467 ; fully-qualified # 👩‍👧‍👧 E4.0 family: woman, girl, girl
+
+# subgroup: person-symbol
+1F5E3 FE0F ; fully-qualified # 🗣️ E0.7 speaking head
+1F5E3 ; unqualified # 🗣 E0.7 speaking head
+1F464 ; fully-qualified # 👤 E0.6 bust in silhouette
+1F465 ; fully-qualified # 👥 E1.0 busts in silhouette
+1FAC2 ; fully-qualified # 🫂 E13.0 people hugging
+1F463 ; fully-qualified # 👣 E0.6 footprints
+
+# People & Body subtotal: 2986
+# People & Body subtotal: 506 w/o modifiers
+
+# group: Component
+
+# subgroup: skin-tone
+1F3FB ; component # 🏻 E1.0 light skin tone
+1F3FC ; component # 🏼 E1.0 medium-light skin tone
+1F3FD ; component # 🏽 E1.0 medium skin tone
+1F3FE ; component # 🏾 E1.0 medium-dark skin tone
+1F3FF ; component # 🏿 E1.0 dark skin tone
+
+# subgroup: hair-style
+1F9B0 ; component # 🦰 E11.0 red hair
+1F9B1 ; component # 🦱 E11.0 curly hair
+1F9B3 ; component # 🦳 E11.0 white hair
+1F9B2 ; component # 🦲 E11.0 bald
+
+# Component subtotal: 9
+# Component subtotal: 4 w/o modifiers
+
+# group: Animals & Nature
+
+# subgroup: animal-mammal
+1F435 ; fully-qualified # 🐵 E0.6 monkey face
+1F412 ; fully-qualified # 🐒 E0.6 monkey
+1F98D ; fully-qualified # 🦍 E3.0 gorilla
+1F9A7 ; fully-qualified # 🦧 E12.0 orangutan
+1F436 ; fully-qualified # 🐶 E0.6 dog face
+1F415 ; fully-qualified # 🐕 E0.7 dog
+1F9AE ; fully-qualified # 🦮 E12.0 guide dog
+1F415 200D 1F9BA ; fully-qualified # 🐕‍🦺 E12.0 service dog
+1F429 ; fully-qualified # 🐩 E0.6 poodle
+1F43A ; fully-qualified # 🐺 E0.6 wolf
+1F98A ; fully-qualified # 🦊 E3.0 fox
+1F99D ; fully-qualified # 🦝 E11.0 raccoon
+1F431 ; fully-qualified # 🐱 E0.6 cat face
+1F408 ; fully-qualified # 🐈 E0.7 cat
+1F408 200D 2B1B ; fully-qualified # 🐈‍⬛ E13.0 black cat
+1F981 ; fully-qualified # 🦁 E1.0 lion
+1F42F ; fully-qualified # 🐯 E0.6 tiger face
+1F405 ; fully-qualified # 🐅 E1.0 tiger
+1F406 ; fully-qualified # 🐆 E1.0 leopard
+1F434 ; fully-qualified # 🐴 E0.6 horse face
+1F40E ; fully-qualified # 🐎 E0.6 horse
+1F984 ; fully-qualified # 🦄 E1.0 unicorn
+1F993 ; fully-qualified # 🦓 E5.0 zebra
+1F98C ; fully-qualified # 🦌 E3.0 deer
+1F9AC ; fully-qualified # 🦬 E13.0 bison
+1F42E ; fully-qualified # 🐮 E0.6 cow face
+1F402 ; fully-qualified # 🐂 E1.0 ox
+1F403 ; fully-qualified # 🐃 E1.0 water buffalo
+1F404 ; fully-qualified # 🐄 E1.0 cow
+1F437 ; fully-qualified # 🐷 E0.6 pig face
+1F416 ; fully-qualified # 🐖 E1.0 pig
+1F417 ; fully-qualified # 🐗 E0.6 boar
+1F43D ; fully-qualified # 🐽 E0.6 pig nose
+1F40F ; fully-qualified # 🐏 E1.0 ram
+1F411 ; fully-qualified # 🐑 E0.6 ewe
+1F410 ; fully-qualified # 🐐 E1.0 goat
+1F42A ; fully-qualified # 🐪 E1.0 camel
+1F42B ; fully-qualified # 🐫 E0.6 two-hump camel
+1F999 ; fully-qualified # 🦙 E11.0 llama
+1F992 ; fully-qualified # 🦒 E5.0 giraffe
+1F418 ; fully-qualified # 🐘 E0.6 elephant
+1F9A3 ; fully-qualified # 🦣 E13.0 mammoth
+1F98F ; fully-qualified # 🦏 E3.0 rhinoceros
+1F99B ; fully-qualified # 🦛 E11.0 hippopotamus
+1F42D ; fully-qualified # 🐭 E0.6 mouse face
+1F401 ; fully-qualified # 🐁 E1.0 mouse
+1F400 ; fully-qualified # 🐀 E1.0 rat
+1F439 ; fully-qualified # 🐹 E0.6 hamster
+1F430 ; fully-qualified # 🐰 E0.6 rabbit face
+1F407 ; fully-qualified # 🐇 E1.0 rabbit
+1F43F FE0F ; fully-qualified # 🐿️ E0.7 chipmunk
+1F43F ; unqualified # 🐿 E0.7 chipmunk
+1F9AB ; fully-qualified # 🦫 E13.0 beaver
+1F994 ; fully-qualified # 🦔 E5.0 hedgehog
+1F987 ; fully-qualified # 🦇 E3.0 bat
+1F43B ; fully-qualified # 🐻 E0.6 bear
+1F43B 200D 2744 FE0F ; fully-qualified # 🐻‍❄️ E13.0 polar bear
+1F43B 200D 2744 ; minimally-qualified # 🐻‍❄ E13.0 polar bear
+1F428 ; fully-qualified # 🐨 E0.6 koala
+1F43C ; fully-qualified # 🐼 E0.6 panda
+1F9A5 ; fully-qualified # 🦥 E12.0 sloth
+1F9A6 ; fully-qualified # 🦦 E12.0 otter
+1F9A8 ; fully-qualified # 🦨 E12.0 skunk
+1F998 ; fully-qualified # 🦘 E11.0 kangaroo
+1F9A1 ; fully-qualified # 🦡 E11.0 badger
+1F43E ; fully-qualified # 🐾 E0.6 paw prints
+
+# subgroup: animal-bird
+1F983 ; fully-qualified # 🦃 E1.0 turkey
+1F414 ; fully-qualified # 🐔 E0.6 chicken
+1F413 ; fully-qualified # 🐓 E1.0 rooster
+1F423 ; fully-qualified # 🐣 E0.6 hatching chick
+1F424 ; fully-qualified # 🐤 E0.6 baby chick
+1F425 ; fully-qualified # 🐥 E0.6 front-facing baby chick
+1F426 ; fully-qualified # 🐦 E0.6 bird
+1F427 ; fully-qualified # 🐧 E0.6 penguin
+1F54A FE0F ; fully-qualified # 🕊️ E0.7 dove
+1F54A ; unqualified # 🕊 E0.7 dove
+1F985 ; fully-qualified # 🦅 E3.0 eagle
+1F986 ; fully-qualified # 🦆 E3.0 duck
+1F9A2 ; fully-qualified # 🦢 E11.0 swan
+1F989 ; fully-qualified # 🦉 E3.0 owl
+1F9A4 ; fully-qualified # 🦤 E13.0 dodo
+1FAB6 ; fully-qualified # 🪶 E13.0 feather
+1F9A9 ; fully-qualified # 🦩 E12.0 flamingo
+1F99A ; fully-qualified # 🦚 E11.0 peacock
+1F99C ; fully-qualified # 🦜 E11.0 parrot
+
+# subgroup: animal-amphibian
+1F438 ; fully-qualified # 🐸 E0.6 frog
+
+# subgroup: animal-reptile
+1F40A ; fully-qualified # 🐊 E1.0 crocodile
+1F422 ; fully-qualified # 🐢 E0.6 turtle
+1F98E ; fully-qualified # 🦎 E3.0 lizard
+1F40D ; fully-qualified # 🐍 E0.6 snake
+1F432 ; fully-qualified # 🐲 E0.6 dragon face
+1F409 ; fully-qualified # 🐉 E1.0 dragon
+1F995 ; fully-qualified # 🦕 E5.0 sauropod
+1F996 ; fully-qualified # 🦖 E5.0 T-Rex
+
+# subgroup: animal-marine
+1F433 ; fully-qualified # 🐳 E0.6 spouting whale
+1F40B ; fully-qualified # 🐋 E1.0 whale
+1F42C ; fully-qualified # 🐬 E0.6 dolphin
+1F9AD ; fully-qualified # 🦭 E13.0 seal
+1F41F ; fully-qualified # 🐟 E0.6 fish
+1F420 ; fully-qualified # 🐠 E0.6 tropical fish
+1F421 ; fully-qualified # 🐡 E0.6 blowfish
+1F988 ; fully-qualified # 🦈 E3.0 shark
+1F419 ; fully-qualified # 🐙 E0.6 octopus
+1F41A ; fully-qualified # 🐚 E0.6 spiral shell
+1FAB8 ; fully-qualified # 🪸 E14.0 coral
+
+# subgroup: animal-bug
+1F40C ; fully-qualified # 🐌 E0.6 snail
+1F98B ; fully-qualified # 🦋 E3.0 butterfly
+1F41B ; fully-qualified # 🐛 E0.6 bug
+1F41C ; fully-qualified # 🐜 E0.6 ant
+1F41D ; fully-qualified # 🐝 E0.6 honeybee
+1FAB2 ; fully-qualified # 🪲 E13.0 beetle
+1F41E ; fully-qualified # 🐞 E0.6 lady beetle
+1F997 ; fully-qualified # 🦗 E5.0 cricket
+1FAB3 ; fully-qualified # 🪳 E13.0 cockroach
+1F577 FE0F ; fully-qualified # 🕷️ E0.7 spider
+1F577 ; unqualified # 🕷 E0.7 spider
+1F578 FE0F ; fully-qualified # 🕸️ E0.7 spider web
+1F578 ; unqualified # 🕸 E0.7 spider web
+1F982 ; fully-qualified # 🦂 E1.0 scorpion
+1F99F ; fully-qualified # 🦟 E11.0 mosquito
+1FAB0 ; fully-qualified # 🪰 E13.0 fly
+1FAB1 ; fully-qualified # 🪱 E13.0 worm
+1F9A0 ; fully-qualified # 🦠 E11.0 microbe
+
+# subgroup: plant-flower
+1F490 ; fully-qualified # 💐 E0.6 bouquet
+1F338 ; fully-qualified # 🌸 E0.6 cherry blossom
+1F4AE ; fully-qualified # 💮 E0.6 white flower
+1FAB7 ; fully-qualified # 🪷 E14.0 lotus
+1F3F5 FE0F ; fully-qualified # 🏵️ E0.7 rosette
+1F3F5 ; unqualified # 🏵 E0.7 rosette
+1F339 ; fully-qualified # 🌹 E0.6 rose
+1F940 ; fully-qualified # 🥀 E3.0 wilted flower
+1F33A ; fully-qualified # 🌺 E0.6 hibiscus
+1F33B ; fully-qualified # 🌻 E0.6 sunflower
+1F33C ; fully-qualified # 🌼 E0.6 blossom
+1F337 ; fully-qualified # 🌷 E0.6 tulip
+
+# subgroup: plant-other
+1F331 ; fully-qualified # 🌱 E0.6 seedling
+1FAB4 ; fully-qualified # 🪴 E13.0 potted plant
+1F332 ; fully-qualified # 🌲 E1.0 evergreen tree
+1F333 ; fully-qualified # 🌳 E1.0 deciduous tree
+1F334 ; fully-qualified # 🌴 E0.6 palm tree
+1F335 ; fully-qualified # 🌵 E0.6 cactus
+1F33E ; fully-qualified # 🌾 E0.6 sheaf of rice
+1F33F ; fully-qualified # 🌿 E0.6 herb
+2618 FE0F ; fully-qualified # ☘️ E1.0 shamrock
+2618 ; unqualified # ☘ E1.0 shamrock
+1F340 ; fully-qualified # 🍀 E0.6 four leaf clover
+1F341 ; fully-qualified # 🍁 E0.6 maple leaf
+1F342 ; fully-qualified # 🍂 E0.6 fallen leaf
+1F343 ; fully-qualified # 🍃 E0.6 leaf fluttering in wind
+1FAB9 ; fully-qualified # 🪹 E14.0 empty nest
+1FABA ; fully-qualified # 🪺 E14.0 nest with eggs
+
+# Animals & Nature subtotal: 151
+# Animals & Nature subtotal: 151 w/o modifiers
+
+# group: Food & Drink
+
+# subgroup: food-fruit
+1F347 ; fully-qualified # 🍇 E0.6 grapes
+1F348 ; fully-qualified # 🍈 E0.6 melon
+1F349 ; fully-qualified # 🍉 E0.6 watermelon
+1F34A ; fully-qualified # 🍊 E0.6 tangerine
+1F34B ; fully-qualified # 🍋 E1.0 lemon
+1F34C ; fully-qualified # 🍌 E0.6 banana
+1F34D ; fully-qualified # 🍍 E0.6 pineapple
+1F96D ; fully-qualified # 🥭 E11.0 mango
+1F34E ; fully-qualified # 🍎 E0.6 red apple
+1F34F ; fully-qualified # 🍏 E0.6 green apple
+1F350 ; fully-qualified # 🍐 E1.0 pear
+1F351 ; fully-qualified # 🍑 E0.6 peach
+1F352 ; fully-qualified # 🍒 E0.6 cherries
+1F353 ; fully-qualified # 🍓 E0.6 strawberry
+1FAD0 ; fully-qualified # 🫐 E13.0 blueberries
+1F95D ; fully-qualified # 🥝 E3.0 kiwi fruit
+1F345 ; fully-qualified # 🍅 E0.6 tomato
+1FAD2 ; fully-qualified # 🫒 E13.0 olive
+1F965 ; fully-qualified # 🥥 E5.0 coconut
+
+# subgroup: food-vegetable
+1F951 ; fully-qualified # 🥑 E3.0 avocado
+1F346 ; fully-qualified # 🍆 E0.6 eggplant
+1F954 ; fully-qualified # 🥔 E3.0 potato
+1F955 ; fully-qualified # 🥕 E3.0 carrot
+1F33D ; fully-qualified # 🌽 E0.6 ear of corn
+1F336 FE0F ; fully-qualified # 🌶️ E0.7 hot pepper
+1F336 ; unqualified # 🌶 E0.7 hot pepper
+1FAD1 ; fully-qualified # 🫑 E13.0 bell pepper
+1F952 ; fully-qualified # 🥒 E3.0 cucumber
+1F96C ; fully-qualified # 🥬 E11.0 leafy green
+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
+
+# subgroup: food-prepared
+1F35E ; fully-qualified # 🍞 E0.6 bread
+1F950 ; fully-qualified # 🥐 E3.0 croissant
+1F956 ; fully-qualified # 🥖 E3.0 baguette bread
+1FAD3 ; fully-qualified # 🫓 E13.0 flatbread
+1F968 ; fully-qualified # 🥨 E5.0 pretzel
+1F96F ; fully-qualified # 🥯 E11.0 bagel
+1F95E ; fully-qualified # 🥞 E3.0 pancakes
+1F9C7 ; fully-qualified # 🧇 E12.0 waffle
+1F9C0 ; fully-qualified # 🧀 E1.0 cheese wedge
+1F356 ; fully-qualified # 🍖 E0.6 meat on bone
+1F357 ; fully-qualified # 🍗 E0.6 poultry leg
+1F969 ; fully-qualified # 🥩 E5.0 cut of meat
+1F953 ; fully-qualified # 🥓 E3.0 bacon
+1F354 ; fully-qualified # 🍔 E0.6 hamburger
+1F35F ; fully-qualified # 🍟 E0.6 french fries
+1F355 ; fully-qualified # 🍕 E0.6 pizza
+1F32D ; fully-qualified # 🌭 E1.0 hot dog
+1F96A ; fully-qualified # 🥪 E5.0 sandwich
+1F32E ; fully-qualified # 🌮 E1.0 taco
+1F32F ; fully-qualified # 🌯 E1.0 burrito
+1FAD4 ; fully-qualified # 🫔 E13.0 tamale
+1F959 ; fully-qualified # 🥙 E3.0 stuffed flatbread
+1F9C6 ; fully-qualified # 🧆 E12.0 falafel
+1F95A ; fully-qualified # 🥚 E3.0 egg
+1F373 ; fully-qualified # 🍳 E0.6 cooking
+1F958 ; fully-qualified # 🥘 E3.0 shallow pan of food
+1F372 ; fully-qualified # 🍲 E0.6 pot of food
+1FAD5 ; fully-qualified # 🫕 E13.0 fondue
+1F963 ; fully-qualified # 🥣 E5.0 bowl with spoon
+1F957 ; fully-qualified # 🥗 E3.0 green salad
+1F37F ; fully-qualified # 🍿 E1.0 popcorn
+1F9C8 ; fully-qualified # 🧈 E12.0 butter
+1F9C2 ; fully-qualified # 🧂 E11.0 salt
+1F96B ; fully-qualified # 🥫 E5.0 canned food
+
+# subgroup: food-asian
+1F371 ; fully-qualified # 🍱 E0.6 bento box
+1F358 ; fully-qualified # 🍘 E0.6 rice cracker
+1F359 ; fully-qualified # 🍙 E0.6 rice ball
+1F35A ; fully-qualified # 🍚 E0.6 cooked rice
+1F35B ; fully-qualified # 🍛 E0.6 curry rice
+1F35C ; fully-qualified # 🍜 E0.6 steaming bowl
+1F35D ; fully-qualified # 🍝 E0.6 spaghetti
+1F360 ; fully-qualified # 🍠 E0.6 roasted sweet potato
+1F362 ; fully-qualified # 🍢 E0.6 oden
+1F363 ; fully-qualified # 🍣 E0.6 sushi
+1F364 ; fully-qualified # 🍤 E0.6 fried shrimp
+1F365 ; fully-qualified # 🍥 E0.6 fish cake with swirl
+1F96E ; fully-qualified # 🥮 E11.0 moon cake
+1F361 ; fully-qualified # 🍡 E0.6 dango
+1F95F ; fully-qualified # 🥟 E5.0 dumpling
+1F960 ; fully-qualified # 🥠 E5.0 fortune cookie
+1F961 ; fully-qualified # 🥡 E5.0 takeout box
+
+# subgroup: food-marine
+1F980 ; fully-qualified # 🦀 E1.0 crab
+1F99E ; fully-qualified # 🦞 E11.0 lobster
+1F990 ; fully-qualified # 🦐 E3.0 shrimp
+1F991 ; fully-qualified # 🦑 E3.0 squid
+1F9AA ; fully-qualified # 🦪 E12.0 oyster
+
+# subgroup: food-sweet
+1F366 ; fully-qualified # 🍦 E0.6 soft ice cream
+1F367 ; fully-qualified # 🍧 E0.6 shaved ice
+1F368 ; fully-qualified # 🍨 E0.6 ice cream
+1F369 ; fully-qualified # 🍩 E0.6 doughnut
+1F36A ; fully-qualified # 🍪 E0.6 cookie
+1F382 ; fully-qualified # 🎂 E0.6 birthday cake
+1F370 ; fully-qualified # 🍰 E0.6 shortcake
+1F9C1 ; fully-qualified # 🧁 E11.0 cupcake
+1F967 ; fully-qualified # 🥧 E5.0 pie
+1F36B ; fully-qualified # 🍫 E0.6 chocolate bar
+1F36C ; fully-qualified # 🍬 E0.6 candy
+1F36D ; fully-qualified # 🍭 E0.6 lollipop
+1F36E ; fully-qualified # 🍮 E0.6 custard
+1F36F ; fully-qualified # 🍯 E0.6 honey pot
+
+# subgroup: drink
+1F37C ; fully-qualified # 🍼 E1.0 baby bottle
+1F95B ; fully-qualified # 🥛 E3.0 glass of milk
+2615 ; fully-qualified # ☕ E0.6 hot beverage
+1FAD6 ; fully-qualified # 🫖 E13.0 teapot
+1F375 ; fully-qualified # 🍵 E0.6 teacup without handle
+1F376 ; fully-qualified # 🍶 E0.6 sake
+1F37E ; fully-qualified # 🍾 E1.0 bottle with popping cork
+1F377 ; fully-qualified # 🍷 E0.6 wine glass
+1F378 ; fully-qualified # 🍸 E0.6 cocktail glass
+1F379 ; fully-qualified # 🍹 E0.6 tropical drink
+1F37A ; fully-qualified # 🍺 E0.6 beer mug
+1F37B ; fully-qualified # 🍻 E0.6 clinking beer mugs
+1F942 ; fully-qualified # 🥂 E3.0 clinking glasses
+1F943 ; fully-qualified # 🥃 E3.0 tumbler glass
+1FAD7 ; fully-qualified # 🫗 E14.0 pouring liquid
+1F964 ; fully-qualified # 🥤 E5.0 cup with straw
+1F9CB ; fully-qualified # 🧋 E13.0 bubble tea
+1F9C3 ; fully-qualified # 🧃 E12.0 beverage box
+1F9C9 ; fully-qualified # 🧉 E12.0 mate
+1F9CA ; fully-qualified # 🧊 E12.0 ice
+
+# subgroup: dishware
+1F962 ; fully-qualified # 🥢 E5.0 chopsticks
+1F37D FE0F ; fully-qualified # 🍽️ E0.7 fork and knife with plate
+1F37D ; unqualified # 🍽 E0.7 fork and knife with plate
+1F374 ; fully-qualified # 🍴 E0.6 fork and knife
+1F944 ; fully-qualified # 🥄 E3.0 spoon
+1F52A ; fully-qualified # 🔪 E0.6 kitchen knife
+1FAD9 ; fully-qualified # 🫙 E14.0 jar
+1F3FA ; fully-qualified # 🏺 E1.0 amphora
+
+# Food & Drink subtotal: 134
+# Food & Drink subtotal: 134 w/o modifiers
+
+# group: Travel & Places
+
+# subgroup: place-map
+1F30D ; fully-qualified # 🌍 E0.7 globe showing Europe-Africa
+1F30E ; fully-qualified # 🌎 E0.7 globe showing Americas
+1F30F ; fully-qualified # 🌏 E0.6 globe showing Asia-Australia
+1F310 ; fully-qualified # 🌐 E1.0 globe with meridians
+1F5FA FE0F ; fully-qualified # 🗺️ E0.7 world map
+1F5FA ; unqualified # 🗺 E0.7 world map
+1F5FE ; fully-qualified # 🗾 E0.6 map of Japan
+1F9ED ; fully-qualified # 🧭 E11.0 compass
+
+# subgroup: place-geographic
+1F3D4 FE0F ; fully-qualified # 🏔️ E0.7 snow-capped mountain
+1F3D4 ; unqualified # 🏔 E0.7 snow-capped mountain
+26F0 FE0F ; fully-qualified # ⛰️ E0.7 mountain
+26F0 ; unqualified # ⛰ E0.7 mountain
+1F30B ; fully-qualified # 🌋 E0.6 volcano
+1F5FB ; fully-qualified # 🗻 E0.6 mount fuji
+1F3D5 FE0F ; fully-qualified # 🏕️ E0.7 camping
+1F3D5 ; unqualified # 🏕 E0.7 camping
+1F3D6 FE0F ; fully-qualified # 🏖️ E0.7 beach with umbrella
+1F3D6 ; unqualified # 🏖 E0.7 beach with umbrella
+1F3DC FE0F ; fully-qualified # 🏜️ E0.7 desert
+1F3DC ; unqualified # 🏜 E0.7 desert
+1F3DD FE0F ; fully-qualified # 🏝️ E0.7 desert island
+1F3DD ; unqualified # 🏝 E0.7 desert island
+1F3DE FE0F ; fully-qualified # 🏞️ E0.7 national park
+1F3DE ; unqualified # 🏞 E0.7 national park
+
+# subgroup: place-building
+1F3DF FE0F ; fully-qualified # 🏟️ E0.7 stadium
+1F3DF ; unqualified # 🏟 E0.7 stadium
+1F3DB FE0F ; fully-qualified # 🏛️ E0.7 classical building
+1F3DB ; unqualified # 🏛 E0.7 classical building
+1F3D7 FE0F ; fully-qualified # 🏗️ E0.7 building construction
+1F3D7 ; unqualified # 🏗 E0.7 building construction
+1F9F1 ; fully-qualified # 🧱 E11.0 brick
+1FAA8 ; fully-qualified # 🪨 E13.0 rock
+1FAB5 ; fully-qualified # 🪵 E13.0 wood
+1F6D6 ; fully-qualified # 🛖 E13.0 hut
+1F3D8 FE0F ; fully-qualified # 🏘️ E0.7 houses
+1F3D8 ; unqualified # 🏘 E0.7 houses
+1F3DA FE0F ; fully-qualified # 🏚️ E0.7 derelict house
+1F3DA ; unqualified # 🏚 E0.7 derelict house
+1F3E0 ; fully-qualified # 🏠 E0.6 house
+1F3E1 ; fully-qualified # 🏡 E0.6 house with garden
+1F3E2 ; fully-qualified # 🏢 E0.6 office building
+1F3E3 ; fully-qualified # 🏣 E0.6 Japanese post office
+1F3E4 ; fully-qualified # 🏤 E1.0 post office
+1F3E5 ; fully-qualified # 🏥 E0.6 hospital
+1F3E6 ; fully-qualified # 🏦 E0.6 bank
+1F3E8 ; fully-qualified # 🏨 E0.6 hotel
+1F3E9 ; fully-qualified # 🏩 E0.6 love hotel
+1F3EA ; fully-qualified # 🏪 E0.6 convenience store
+1F3EB ; fully-qualified # 🏫 E0.6 school
+1F3EC ; fully-qualified # 🏬 E0.6 department store
+1F3ED ; fully-qualified # 🏭 E0.6 factory
+1F3EF ; fully-qualified # 🏯 E0.6 Japanese castle
+1F3F0 ; fully-qualified # 🏰 E0.6 castle
+1F492 ; fully-qualified # 💒 E0.6 wedding
+1F5FC ; fully-qualified # 🗼 E0.6 Tokyo tower
+1F5FD ; fully-qualified # 🗽 E0.6 Statue of Liberty
+
+# subgroup: place-religious
+26EA ; fully-qualified # ⛪ E0.6 church
+1F54C ; fully-qualified # 🕌 E1.0 mosque
+1F6D5 ; fully-qualified # 🛕 E12.0 hindu temple
+1F54D ; fully-qualified # 🕍 E1.0 synagogue
+26E9 FE0F ; fully-qualified # ⛩️ E0.7 shinto shrine
+26E9 ; unqualified # ⛩ E0.7 shinto shrine
+1F54B ; fully-qualified # 🕋 E1.0 kaaba
+
+# subgroup: place-other
+26F2 ; fully-qualified # ⛲ E0.6 fountain
+26FA ; fully-qualified # ⛺ E0.6 tent
+1F301 ; fully-qualified # 🌁 E0.6 foggy
+1F303 ; fully-qualified # 🌃 E0.6 night with stars
+1F3D9 FE0F ; fully-qualified # 🏙️ E0.7 cityscape
+1F3D9 ; unqualified # 🏙 E0.7 cityscape
+1F304 ; fully-qualified # 🌄 E0.6 sunrise over mountains
+1F305 ; fully-qualified # 🌅 E0.6 sunrise
+1F306 ; fully-qualified # 🌆 E0.6 cityscape at dusk
+1F307 ; fully-qualified # 🌇 E0.6 sunset
+1F309 ; fully-qualified # 🌉 E0.6 bridge at night
+2668 FE0F ; fully-qualified # ♨️ E0.6 hot springs
+2668 ; unqualified # ♨ E0.6 hot springs
+1F3A0 ; fully-qualified # 🎠 E0.6 carousel horse
+1F6DD ; fully-qualified # 🛝 E14.0 playground slide
+1F3A1 ; fully-qualified # 🎡 E0.6 ferris wheel
+1F3A2 ; fully-qualified # 🎢 E0.6 roller coaster
+1F488 ; fully-qualified # 💈 E0.6 barber pole
+1F3AA ; fully-qualified # 🎪 E0.6 circus tent
+
+# subgroup: transport-ground
+1F682 ; fully-qualified # 🚂 E1.0 locomotive
+1F683 ; fully-qualified # 🚃 E0.6 railway car
+1F684 ; fully-qualified # 🚄 E0.6 high-speed train
+1F685 ; fully-qualified # 🚅 E0.6 bullet train
+1F686 ; fully-qualified # 🚆 E1.0 train
+1F687 ; fully-qualified # 🚇 E0.6 metro
+1F688 ; fully-qualified # 🚈 E1.0 light rail
+1F689 ; fully-qualified # 🚉 E0.6 station
+1F68A ; fully-qualified # 🚊 E1.0 tram
+1F69D ; fully-qualified # 🚝 E1.0 monorail
+1F69E ; fully-qualified # 🚞 E1.0 mountain railway
+1F68B ; fully-qualified # 🚋 E1.0 tram car
+1F68C ; fully-qualified # 🚌 E0.6 bus
+1F68D ; fully-qualified # 🚍 E0.7 oncoming bus
+1F68E ; fully-qualified # 🚎 E1.0 trolleybus
+1F690 ; fully-qualified # 🚐 E1.0 minibus
+1F691 ; fully-qualified # 🚑 E0.6 ambulance
+1F692 ; fully-qualified # 🚒 E0.6 fire engine
+1F693 ; fully-qualified # 🚓 E0.6 police car
+1F694 ; fully-qualified # 🚔 E0.7 oncoming police car
+1F695 ; fully-qualified # 🚕 E0.6 taxi
+1F696 ; fully-qualified # 🚖 E1.0 oncoming taxi
+1F697 ; fully-qualified # 🚗 E0.6 automobile
+1F698 ; fully-qualified # 🚘 E0.7 oncoming automobile
+1F699 ; fully-qualified # 🚙 E0.6 sport utility vehicle
+1F6FB ; fully-qualified # 🛻 E13.0 pickup truck
+1F69A ; fully-qualified # 🚚 E0.6 delivery truck
+1F69B ; fully-qualified # 🚛 E1.0 articulated lorry
+1F69C ; fully-qualified # 🚜 E1.0 tractor
+1F3CE FE0F ; fully-qualified # 🏎️ E0.7 racing car
+1F3CE ; unqualified # 🏎 E0.7 racing car
+1F3CD FE0F ; fully-qualified # 🏍️ E0.7 motorcycle
+1F3CD ; unqualified # 🏍 E0.7 motorcycle
+1F6F5 ; fully-qualified # 🛵 E3.0 motor scooter
+1F9BD ; fully-qualified # 🦽 E12.0 manual wheelchair
+1F9BC ; fully-qualified # 🦼 E12.0 motorized wheelchair
+1F6FA ; fully-qualified # 🛺 E12.0 auto rickshaw
+1F6B2 ; fully-qualified # 🚲 E0.6 bicycle
+1F6F4 ; fully-qualified # 🛴 E3.0 kick scooter
+1F6F9 ; fully-qualified # 🛹 E11.0 skateboard
+1F6FC ; fully-qualified # 🛼 E13.0 roller skate
+1F68F ; fully-qualified # 🚏 E0.6 bus stop
+1F6E3 FE0F ; fully-qualified # 🛣️ E0.7 motorway
+1F6E3 ; unqualified # 🛣 E0.7 motorway
+1F6E4 FE0F ; fully-qualified # 🛤️ E0.7 railway track
+1F6E4 ; unqualified # 🛤 E0.7 railway track
+1F6E2 FE0F ; fully-qualified # 🛢️ E0.7 oil drum
+1F6E2 ; unqualified # 🛢 E0.7 oil drum
+26FD ; fully-qualified # ⛽ E0.6 fuel pump
+1F6DE ; fully-qualified # 🛞 E14.0 wheel
+1F6A8 ; fully-qualified # 🚨 E0.6 police car light
+1F6A5 ; fully-qualified # 🚥 E0.6 horizontal traffic light
+1F6A6 ; fully-qualified # 🚦 E1.0 vertical traffic light
+1F6D1 ; fully-qualified # 🛑 E3.0 stop sign
+1F6A7 ; fully-qualified # 🚧 E0.6 construction
+
+# subgroup: transport-water
+2693 ; fully-qualified # ⚓ E0.6 anchor
+1F6DF ; fully-qualified # 🛟 E14.0 ring buoy
+26F5 ; fully-qualified # ⛵ E0.6 sailboat
+1F6F6 ; fully-qualified # 🛶 E3.0 canoe
+1F6A4 ; fully-qualified # 🚤 E0.6 speedboat
+1F6F3 FE0F ; fully-qualified # 🛳️ E0.7 passenger ship
+1F6F3 ; unqualified # 🛳 E0.7 passenger ship
+26F4 FE0F ; fully-qualified # ⛴️ E0.7 ferry
+26F4 ; unqualified # ⛴ E0.7 ferry
+1F6E5 FE0F ; fully-qualified # 🛥️ E0.7 motor boat
+1F6E5 ; unqualified # 🛥 E0.7 motor boat
+1F6A2 ; fully-qualified # 🚢 E0.6 ship
+
+# subgroup: transport-air
+2708 FE0F ; fully-qualified # ✈️ E0.6 airplane
+2708 ; unqualified # ✈ E0.6 airplane
+1F6E9 FE0F ; fully-qualified # 🛩️ E0.7 small airplane
+1F6E9 ; unqualified # 🛩 E0.7 small airplane
+1F6EB ; fully-qualified # 🛫 E1.0 airplane departure
+1F6EC ; fully-qualified # 🛬 E1.0 airplane arrival
+1FA82 ; fully-qualified # 🪂 E12.0 parachute
+1F4BA ; fully-qualified # 💺 E0.6 seat
+1F681 ; fully-qualified # 🚁 E1.0 helicopter
+1F69F ; fully-qualified # 🚟 E1.0 suspension railway
+1F6A0 ; fully-qualified # 🚠 E1.0 mountain cableway
+1F6A1 ; fully-qualified # 🚡 E1.0 aerial tramway
+1F6F0 FE0F ; fully-qualified # 🛰️ E0.7 satellite
+1F6F0 ; unqualified # 🛰 E0.7 satellite
+1F680 ; fully-qualified # 🚀 E0.6 rocket
+1F6F8 ; fully-qualified # 🛸 E5.0 flying saucer
+
+# subgroup: hotel
+1F6CE FE0F ; fully-qualified # 🛎️ E0.7 bellhop bell
+1F6CE ; unqualified # 🛎 E0.7 bellhop bell
+1F9F3 ; fully-qualified # 🧳 E11.0 luggage
+
+# subgroup: time
+231B ; fully-qualified # ⌛ E0.6 hourglass done
+23F3 ; fully-qualified # ⏳ E0.6 hourglass not done
+231A ; fully-qualified # ⌚ E0.6 watch
+23F0 ; fully-qualified # ⏰ E0.6 alarm clock
+23F1 FE0F ; fully-qualified # ⏱️ E1.0 stopwatch
+23F1 ; unqualified # ⏱ E1.0 stopwatch
+23F2 FE0F ; fully-qualified # ⏲️ E1.0 timer clock
+23F2 ; unqualified # ⏲ E1.0 timer clock
+1F570 FE0F ; fully-qualified # 🕰️ E0.7 mantelpiece clock
+1F570 ; unqualified # 🕰 E0.7 mantelpiece clock
+1F55B ; fully-qualified # 🕛 E0.6 twelve o’clock
+1F567 ; fully-qualified # 🕧 E0.7 twelve-thirty
+1F550 ; fully-qualified # 🕐 E0.6 one o’clock
+1F55C ; fully-qualified # 🕜 E0.7 one-thirty
+1F551 ; fully-qualified # 🕑 E0.6 two o’clock
+1F55D ; fully-qualified # 🕝 E0.7 two-thirty
+1F552 ; fully-qualified # 🕒 E0.6 three o’clock
+1F55E ; fully-qualified # 🕞 E0.7 three-thirty
+1F553 ; fully-qualified # 🕓 E0.6 four o’clock
+1F55F ; fully-qualified # 🕟 E0.7 four-thirty
+1F554 ; fully-qualified # 🕔 E0.6 five o’clock
+1F560 ; fully-qualified # 🕠 E0.7 five-thirty
+1F555 ; fully-qualified # 🕕 E0.6 six o’clock
+1F561 ; fully-qualified # 🕡 E0.7 six-thirty
+1F556 ; fully-qualified # 🕖 E0.6 seven o’clock
+1F562 ; fully-qualified # 🕢 E0.7 seven-thirty
+1F557 ; fully-qualified # 🕗 E0.6 eight o’clock
+1F563 ; fully-qualified # 🕣 E0.7 eight-thirty
+1F558 ; fully-qualified # 🕘 E0.6 nine o’clock
+1F564 ; fully-qualified # 🕤 E0.7 nine-thirty
+1F559 ; fully-qualified # 🕙 E0.6 ten o’clock
+1F565 ; fully-qualified # 🕥 E0.7 ten-thirty
+1F55A ; fully-qualified # 🕚 E0.6 eleven o’clock
+1F566 ; fully-qualified # 🕦 E0.7 eleven-thirty
+
+# subgroup: sky & weather
+1F311 ; fully-qualified # 🌑 E0.6 new moon
+1F312 ; fully-qualified # 🌒 E1.0 waxing crescent moon
+1F313 ; fully-qualified # 🌓 E0.6 first quarter moon
+1F314 ; fully-qualified # 🌔 E0.6 waxing gibbous moon
+1F315 ; fully-qualified # 🌕 E0.6 full moon
+1F316 ; fully-qualified # 🌖 E1.0 waning gibbous moon
+1F317 ; fully-qualified # 🌗 E1.0 last quarter moon
+1F318 ; fully-qualified # 🌘 E1.0 waning crescent moon
+1F319 ; fully-qualified # 🌙 E0.6 crescent moon
+1F31A ; fully-qualified # 🌚 E1.0 new moon face
+1F31B ; fully-qualified # 🌛 E0.6 first quarter moon face
+1F31C ; fully-qualified # 🌜 E0.7 last quarter moon face
+1F321 FE0F ; fully-qualified # 🌡️ E0.7 thermometer
+1F321 ; unqualified # 🌡 E0.7 thermometer
+2600 FE0F ; fully-qualified # ☀️ E0.6 sun
+2600 ; unqualified # ☀ E0.6 sun
+1F31D ; fully-qualified # 🌝 E1.0 full moon face
+1F31E ; fully-qualified # 🌞 E1.0 sun with face
+1FA90 ; fully-qualified # 🪐 E12.0 ringed planet
+2B50 ; fully-qualified # ⭐ E0.6 star
+1F31F ; fully-qualified # 🌟 E0.6 glowing star
+1F320 ; fully-qualified # 🌠 E0.6 shooting star
+1F30C ; fully-qualified # 🌌 E0.6 milky way
+2601 FE0F ; fully-qualified # ☁️ E0.6 cloud
+2601 ; unqualified # ☁ E0.6 cloud
+26C5 ; fully-qualified # ⛅ E0.6 sun behind cloud
+26C8 FE0F ; fully-qualified # ⛈️ E0.7 cloud with lightning and rain
+26C8 ; unqualified # ⛈ E0.7 cloud with lightning and rain
+1F324 FE0F ; fully-qualified # 🌤️ E0.7 sun behind small cloud
+1F324 ; unqualified # 🌤 E0.7 sun behind small cloud
+1F325 FE0F ; fully-qualified # 🌥️ E0.7 sun behind large cloud
+1F325 ; unqualified # 🌥 E0.7 sun behind large cloud
+1F326 FE0F ; fully-qualified # 🌦️ E0.7 sun behind rain cloud
+1F326 ; unqualified # 🌦 E0.7 sun behind rain cloud
+1F327 FE0F ; fully-qualified # 🌧️ E0.7 cloud with rain
+1F327 ; unqualified # 🌧 E0.7 cloud with rain
+1F328 FE0F ; fully-qualified # 🌨️ E0.7 cloud with snow
+1F328 ; unqualified # 🌨 E0.7 cloud with snow
+1F329 FE0F ; fully-qualified # 🌩️ E0.7 cloud with lightning
+1F329 ; unqualified # 🌩 E0.7 cloud with lightning
+1F32A FE0F ; fully-qualified # 🌪️ E0.7 tornado
+1F32A ; unqualified # 🌪 E0.7 tornado
+1F32B FE0F ; fully-qualified # 🌫️ E0.7 fog
+1F32B ; unqualified # 🌫 E0.7 fog
+1F32C FE0F ; fully-qualified # 🌬️ E0.7 wind face
+1F32C ; unqualified # 🌬 E0.7 wind face
+1F300 ; fully-qualified # 🌀 E0.6 cyclone
+1F308 ; fully-qualified # 🌈 E0.6 rainbow
+1F302 ; fully-qualified # 🌂 E0.6 closed umbrella
+2602 FE0F ; fully-qualified # ☂️ E0.7 umbrella
+2602 ; unqualified # ☂ E0.7 umbrella
+2614 ; fully-qualified # ☔ E0.6 umbrella with rain drops
+26F1 FE0F ; fully-qualified # ⛱️ E0.7 umbrella on ground
+26F1 ; unqualified # ⛱ E0.7 umbrella on ground
+26A1 ; fully-qualified # ⚡ E0.6 high voltage
+2744 FE0F ; fully-qualified # ❄️ E0.6 snowflake
+2744 ; unqualified # ❄ E0.6 snowflake
+2603 FE0F ; fully-qualified # ☃️ E0.7 snowman
+2603 ; unqualified # ☃ E0.7 snowman
+26C4 ; fully-qualified # ⛄ E0.6 snowman without snow
+2604 FE0F ; fully-qualified # ☄️ E1.0 comet
+2604 ; unqualified # ☄ E1.0 comet
+1F525 ; fully-qualified # 🔥 E0.6 fire
+1F4A7 ; fully-qualified # 💧 E0.6 droplet
+1F30A ; fully-qualified # 🌊 E0.6 water wave
+
+# Travel & Places subtotal: 267
+# Travel & Places subtotal: 267 w/o modifiers
+
+# group: Activities
+
+# subgroup: event
+1F383 ; fully-qualified # 🎃 E0.6 jack-o-lantern
+1F384 ; fully-qualified # 🎄 E0.6 Christmas tree
+1F386 ; fully-qualified # 🎆 E0.6 fireworks
+1F387 ; fully-qualified # 🎇 E0.6 sparkler
+1F9E8 ; fully-qualified # 🧨 E11.0 firecracker
+2728 ; fully-qualified # ✨ E0.6 sparkles
+1F388 ; fully-qualified # 🎈 E0.6 balloon
+1F389 ; fully-qualified # 🎉 E0.6 party popper
+1F38A ; fully-qualified # 🎊 E0.6 confetti ball
+1F38B ; fully-qualified # 🎋 E0.6 tanabata tree
+1F38D ; fully-qualified # 🎍 E0.6 pine decoration
+1F38E ; fully-qualified # 🎎 E0.6 Japanese dolls
+1F38F ; fully-qualified # 🎏 E0.6 carp streamer
+1F390 ; fully-qualified # 🎐 E0.6 wind chime
+1F391 ; fully-qualified # 🎑 E0.6 moon viewing ceremony
+1F9E7 ; fully-qualified # 🧧 E11.0 red envelope
+1F380 ; fully-qualified # 🎀 E0.6 ribbon
+1F381 ; fully-qualified # 🎁 E0.6 wrapped gift
+1F397 FE0F ; fully-qualified # 🎗️ E0.7 reminder ribbon
+1F397 ; unqualified # 🎗 E0.7 reminder ribbon
+1F39F FE0F ; fully-qualified # 🎟️ E0.7 admission tickets
+1F39F ; unqualified # 🎟 E0.7 admission tickets
+1F3AB ; fully-qualified # 🎫 E0.6 ticket
+
+# subgroup: award-medal
+1F396 FE0F ; fully-qualified # 🎖️ E0.7 military medal
+1F396 ; unqualified # 🎖 E0.7 military medal
+1F3C6 ; fully-qualified # 🏆 E0.6 trophy
+1F3C5 ; fully-qualified # 🏅 E1.0 sports medal
+1F947 ; fully-qualified # 🥇 E3.0 1st place medal
+1F948 ; fully-qualified # 🥈 E3.0 2nd place medal
+1F949 ; fully-qualified # 🥉 E3.0 3rd place medal
+
+# subgroup: sport
+26BD ; fully-qualified # ⚽ E0.6 soccer ball
+26BE ; fully-qualified # ⚾ E0.6 baseball
+1F94E ; fully-qualified # 🥎 E11.0 softball
+1F3C0 ; fully-qualified # 🏀 E0.6 basketball
+1F3D0 ; fully-qualified # 🏐 E1.0 volleyball
+1F3C8 ; fully-qualified # 🏈 E0.6 american football
+1F3C9 ; fully-qualified # 🏉 E1.0 rugby football
+1F3BE ; fully-qualified # 🎾 E0.6 tennis
+1F94F ; fully-qualified # 🥏 E11.0 flying disc
+1F3B3 ; fully-qualified # 🎳 E0.6 bowling
+1F3CF ; fully-qualified # 🏏 E1.0 cricket game
+1F3D1 ; fully-qualified # 🏑 E1.0 field hockey
+1F3D2 ; fully-qualified # 🏒 E1.0 ice hockey
+1F94D ; fully-qualified # 🥍 E11.0 lacrosse
+1F3D3 ; fully-qualified # 🏓 E1.0 ping pong
+1F3F8 ; fully-qualified # 🏸 E1.0 badminton
+1F94A ; fully-qualified # 🥊 E3.0 boxing glove
+1F94B ; fully-qualified # 🥋 E3.0 martial arts uniform
+1F945 ; fully-qualified # 🥅 E3.0 goal net
+26F3 ; fully-qualified # ⛳ E0.6 flag in hole
+26F8 FE0F ; fully-qualified # ⛸️ E0.7 ice skate
+26F8 ; unqualified # ⛸ E0.7 ice skate
+1F3A3 ; fully-qualified # 🎣 E0.6 fishing pole
+1F93F ; fully-qualified # 🤿 E12.0 diving mask
+1F3BD ; fully-qualified # 🎽 E0.6 running shirt
+1F3BF ; fully-qualified # 🎿 E0.6 skis
+1F6F7 ; fully-qualified # 🛷 E5.0 sled
+1F94C ; fully-qualified # 🥌 E5.0 curling stone
+
+# subgroup: game
+1F3AF ; fully-qualified # 🎯 E0.6 bullseye
+1FA80 ; fully-qualified # 🪀 E12.0 yo-yo
+1FA81 ; fully-qualified # 🪁 E12.0 kite
+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
+1F3B0 ; fully-qualified # 🎰 E0.6 slot machine
+1F3B2 ; fully-qualified # 🎲 E0.6 game die
+1F9E9 ; fully-qualified # 🧩 E11.0 puzzle piece
+1F9F8 ; fully-qualified # 🧸 E11.0 teddy bear
+1FA85 ; fully-qualified # 🪅 E13.0 piñata
+1FAA9 ; fully-qualified # 🪩 E14.0 mirror ball
+1FA86 ; fully-qualified # 🪆 E13.0 nesting dolls
+2660 FE0F ; fully-qualified # ♠️ E0.6 spade suit
+2660 ; unqualified # ♠ E0.6 spade suit
+2665 FE0F ; fully-qualified # ♥️ E0.6 heart suit
+2665 ; unqualified # ♥ E0.6 heart suit
+2666 FE0F ; fully-qualified # ♦️ E0.6 diamond suit
+2666 ; unqualified # ♦ E0.6 diamond suit
+2663 FE0F ; fully-qualified # ♣️ E0.6 club suit
+2663 ; unqualified # ♣ E0.6 club suit
+265F FE0F ; fully-qualified # ♟️ E11.0 chess pawn
+265F ; unqualified # ♟ E11.0 chess pawn
+1F0CF ; fully-qualified # 🃏 E0.6 joker
+1F004 ; fully-qualified # 🀄 E0.6 mahjong red dragon
+1F3B4 ; fully-qualified # 🎴 E0.6 flower playing cards
+
+# subgroup: arts & crafts
+1F3AD ; fully-qualified # 🎭 E0.6 performing arts
+1F5BC FE0F ; fully-qualified # 🖼️ E0.7 framed picture
+1F5BC ; unqualified # 🖼 E0.7 framed picture
+1F3A8 ; fully-qualified # 🎨 E0.6 artist palette
+1F9F5 ; fully-qualified # 🧵 E11.0 thread
+1FAA1 ; fully-qualified # 🪡 E13.0 sewing needle
+1F9F6 ; fully-qualified # 🧶 E11.0 yarn
+1FAA2 ; fully-qualified # 🪢 E13.0 knot
+
+# Activities subtotal: 97
+# Activities subtotal: 97 w/o modifiers
+
+# group: Objects
+
+# subgroup: clothing
+1F453 ; fully-qualified # 👓 E0.6 glasses
+1F576 FE0F ; fully-qualified # 🕶️ E0.7 sunglasses
+1F576 ; unqualified # 🕶 E0.7 sunglasses
+1F97D ; fully-qualified # 🥽 E11.0 goggles
+1F97C ; fully-qualified # 🥼 E11.0 lab coat
+1F9BA ; fully-qualified # 🦺 E12.0 safety vest
+1F454 ; fully-qualified # 👔 E0.6 necktie
+1F455 ; fully-qualified # 👕 E0.6 t-shirt
+1F456 ; fully-qualified # 👖 E0.6 jeans
+1F9E3 ; fully-qualified # 🧣 E5.0 scarf
+1F9E4 ; fully-qualified # 🧤 E5.0 gloves
+1F9E5 ; fully-qualified # 🧥 E5.0 coat
+1F9E6 ; fully-qualified # 🧦 E5.0 socks
+1F457 ; fully-qualified # 👗 E0.6 dress
+1F458 ; fully-qualified # 👘 E0.6 kimono
+1F97B ; fully-qualified # 🥻 E12.0 sari
+1FA71 ; fully-qualified # 🩱 E12.0 one-piece swimsuit
+1FA72 ; fully-qualified # 🩲 E12.0 briefs
+1FA73 ; fully-qualified # 🩳 E12.0 shorts
+1F459 ; fully-qualified # 👙 E0.6 bikini
+1F45A ; fully-qualified # 👚 E0.6 woman’s clothes
+1F45B ; fully-qualified # 👛 E0.6 purse
+1F45C ; fully-qualified # 👜 E0.6 handbag
+1F45D ; fully-qualified # 👝 E0.6 clutch bag
+1F6CD FE0F ; fully-qualified # 🛍️ E0.7 shopping bags
+1F6CD ; unqualified # 🛍 E0.7 shopping bags
+1F392 ; fully-qualified # 🎒 E0.6 backpack
+1FA74 ; fully-qualified # 🩴 E13.0 thong sandal
+1F45E ; fully-qualified # 👞 E0.6 man’s shoe
+1F45F ; fully-qualified # 👟 E0.6 running shoe
+1F97E ; fully-qualified # 🥾 E11.0 hiking boot
+1F97F ; fully-qualified # 🥿 E11.0 flat shoe
+1F460 ; fully-qualified # 👠 E0.6 high-heeled shoe
+1F461 ; fully-qualified # 👡 E0.6 woman’s sandal
+1FA70 ; fully-qualified # 🩰 E12.0 ballet shoes
+1F462 ; fully-qualified # 👢 E0.6 woman’s boot
+1F451 ; fully-qualified # 👑 E0.6 crown
+1F452 ; fully-qualified # 👒 E0.6 woman’s hat
+1F3A9 ; fully-qualified # 🎩 E0.6 top hat
+1F393 ; fully-qualified # 🎓 E0.6 graduation cap
+1F9E2 ; fully-qualified # 🧢 E5.0 billed cap
+1FA96 ; fully-qualified # 🪖 E13.0 military helmet
+26D1 FE0F ; fully-qualified # ⛑️ E0.7 rescue worker’s helmet
+26D1 ; unqualified # ⛑ E0.7 rescue worker’s helmet
+1F4FF ; fully-qualified # 📿 E1.0 prayer beads
+1F484 ; fully-qualified # 💄 E0.6 lipstick
+1F48D ; fully-qualified # 💍 E0.6 ring
+1F48E ; fully-qualified # 💎 E0.6 gem stone
+
+# subgroup: sound
+1F507 ; fully-qualified # 🔇 E1.0 muted speaker
+1F508 ; fully-qualified # 🔈 E0.7 speaker low volume
+1F509 ; fully-qualified # 🔉 E1.0 speaker medium volume
+1F50A ; fully-qualified # 🔊 E0.6 speaker high volume
+1F4E2 ; fully-qualified # 📢 E0.6 loudspeaker
+1F4E3 ; fully-qualified # 📣 E0.6 megaphone
+1F4EF ; fully-qualified # 📯 E1.0 postal horn
+1F514 ; fully-qualified # 🔔 E0.6 bell
+1F515 ; fully-qualified # 🔕 E1.0 bell with slash
+
+# subgroup: music
+1F3BC ; fully-qualified # 🎼 E0.6 musical score
+1F3B5 ; fully-qualified # 🎵 E0.6 musical note
+1F3B6 ; fully-qualified # 🎶 E0.6 musical notes
+1F399 FE0F ; fully-qualified # 🎙️ E0.7 studio microphone
+1F399 ; unqualified # 🎙 E0.7 studio microphone
+1F39A FE0F ; fully-qualified # 🎚️ E0.7 level slider
+1F39A ; unqualified # 🎚 E0.7 level slider
+1F39B FE0F ; fully-qualified # 🎛️ E0.7 control knobs
+1F39B ; unqualified # 🎛 E0.7 control knobs
+1F3A4 ; fully-qualified # 🎤 E0.6 microphone
+1F3A7 ; fully-qualified # 🎧 E0.6 headphone
+1F4FB ; fully-qualified # 📻 E0.6 radio
+
+# subgroup: musical-instrument
+1F3B7 ; fully-qualified # 🎷 E0.6 saxophone
+1FA97 ; fully-qualified # 🪗 E13.0 accordion
+1F3B8 ; fully-qualified # 🎸 E0.6 guitar
+1F3B9 ; fully-qualified # 🎹 E0.6 musical keyboard
+1F3BA ; fully-qualified # 🎺 E0.6 trumpet
+1F3BB ; fully-qualified # 🎻 E0.6 violin
+1FA95 ; fully-qualified # 🪕 E12.0 banjo
+1F941 ; fully-qualified # 🥁 E3.0 drum
+1FA98 ; fully-qualified # 🪘 E13.0 long drum
+
+# subgroup: phone
+1F4F1 ; fully-qualified # 📱 E0.6 mobile phone
+1F4F2 ; fully-qualified # 📲 E0.6 mobile phone with arrow
+260E FE0F ; fully-qualified # ☎️ E0.6 telephone
+260E ; unqualified # ☎ E0.6 telephone
+1F4DE ; fully-qualified # 📞 E0.6 telephone receiver
+1F4DF ; fully-qualified # 📟 E0.6 pager
+1F4E0 ; fully-qualified # 📠 E0.6 fax machine
+
+# subgroup: computer
+1F50B ; fully-qualified # 🔋 E0.6 battery
+1FAAB ; fully-qualified # 🪫 E14.0 low battery
+1F50C ; fully-qualified # 🔌 E0.6 electric plug
+1F4BB ; fully-qualified # 💻 E0.6 laptop
+1F5A5 FE0F ; fully-qualified # 🖥️ E0.7 desktop computer
+1F5A5 ; unqualified # 🖥 E0.7 desktop computer
+1F5A8 FE0F ; fully-qualified # 🖨️ E0.7 printer
+1F5A8 ; unqualified # 🖨 E0.7 printer
+2328 FE0F ; fully-qualified # ⌨️ E1.0 keyboard
+2328 ; unqualified # ⌨ E1.0 keyboard
+1F5B1 FE0F ; fully-qualified # 🖱️ E0.7 computer mouse
+1F5B1 ; unqualified # 🖱 E0.7 computer mouse
+1F5B2 FE0F ; fully-qualified # 🖲️ E0.7 trackball
+1F5B2 ; unqualified # 🖲 E0.7 trackball
+1F4BD ; fully-qualified # 💽 E0.6 computer disk
+1F4BE ; fully-qualified # 💾 E0.6 floppy disk
+1F4BF ; fully-qualified # 💿 E0.6 optical disk
+1F4C0 ; fully-qualified # 📀 E0.6 dvd
+1F9EE ; fully-qualified # 🧮 E11.0 abacus
+
+# subgroup: light & video
+1F3A5 ; fully-qualified # 🎥 E0.6 movie camera
+1F39E FE0F ; fully-qualified # 🎞️ E0.7 film frames
+1F39E ; unqualified # 🎞 E0.7 film frames
+1F4FD FE0F ; fully-qualified # 📽️ E0.7 film projector
+1F4FD ; unqualified # 📽 E0.7 film projector
+1F3AC ; fully-qualified # 🎬 E0.6 clapper board
+1F4FA ; fully-qualified # 📺 E0.6 television
+1F4F7 ; fully-qualified # 📷 E0.6 camera
+1F4F8 ; fully-qualified # 📸 E1.0 camera with flash
+1F4F9 ; fully-qualified # 📹 E0.6 video camera
+1F4FC ; fully-qualified # 📼 E0.6 videocassette
+1F50D ; fully-qualified # 🔍 E0.6 magnifying glass tilted left
+1F50E ; fully-qualified # 🔎 E0.6 magnifying glass tilted right
+1F56F FE0F ; fully-qualified # 🕯️ E0.7 candle
+1F56F ; unqualified # 🕯 E0.7 candle
+1F4A1 ; fully-qualified # 💡 E0.6 light bulb
+1F526 ; fully-qualified # 🔦 E0.6 flashlight
+1F3EE ; fully-qualified # 🏮 E0.6 red paper lantern
+1FA94 ; fully-qualified # 🪔 E12.0 diya lamp
+
+# subgroup: book-paper
+1F4D4 ; fully-qualified # 📔 E0.6 notebook with decorative cover
+1F4D5 ; fully-qualified # 📕 E0.6 closed book
+1F4D6 ; fully-qualified # 📖 E0.6 open book
+1F4D7 ; fully-qualified # 📗 E0.6 green book
+1F4D8 ; fully-qualified # 📘 E0.6 blue book
+1F4D9 ; fully-qualified # 📙 E0.6 orange book
+1F4DA ; fully-qualified # 📚 E0.6 books
+1F4D3 ; fully-qualified # 📓 E0.6 notebook
+1F4D2 ; fully-qualified # 📒 E0.6 ledger
+1F4C3 ; fully-qualified # 📃 E0.6 page with curl
+1F4DC ; fully-qualified # 📜 E0.6 scroll
+1F4C4 ; fully-qualified # 📄 E0.6 page facing up
+1F4F0 ; fully-qualified # 📰 E0.6 newspaper
+1F5DE FE0F ; fully-qualified # 🗞️ E0.7 rolled-up newspaper
+1F5DE ; unqualified # 🗞 E0.7 rolled-up newspaper
+1F4D1 ; fully-qualified # 📑 E0.6 bookmark tabs
+1F516 ; fully-qualified # 🔖 E0.6 bookmark
+1F3F7 FE0F ; fully-qualified # 🏷️ E0.7 label
+1F3F7 ; unqualified # 🏷 E0.7 label
+
+# subgroup: money
+1F4B0 ; fully-qualified # 💰 E0.6 money bag
+1FA99 ; fully-qualified # 🪙 E13.0 coin
+1F4B4 ; fully-qualified # 💴 E0.6 yen banknote
+1F4B5 ; fully-qualified # 💵 E0.6 dollar banknote
+1F4B6 ; fully-qualified # 💶 E1.0 euro banknote
+1F4B7 ; fully-qualified # 💷 E1.0 pound banknote
+1F4B8 ; fully-qualified # 💸 E0.6 money with wings
+1F4B3 ; fully-qualified # 💳 E0.6 credit card
+1F9FE ; fully-qualified # 🧾 E11.0 receipt
+1F4B9 ; fully-qualified # 💹 E0.6 chart increasing with yen
+
+# subgroup: mail
+2709 FE0F ; fully-qualified # ✉️ E0.6 envelope
+2709 ; unqualified # ✉ E0.6 envelope
+1F4E7 ; fully-qualified # 📧 E0.6 e-mail
+1F4E8 ; fully-qualified # 📨 E0.6 incoming envelope
+1F4E9 ; fully-qualified # 📩 E0.6 envelope with arrow
+1F4E4 ; fully-qualified # 📤 E0.6 outbox tray
+1F4E5 ; fully-qualified # 📥 E0.6 inbox tray
+1F4E6 ; fully-qualified # 📦 E0.6 package
+1F4EB ; fully-qualified # 📫 E0.6 closed mailbox with raised flag
+1F4EA ; fully-qualified # 📪 E0.6 closed mailbox with lowered flag
+1F4EC ; fully-qualified # 📬 E0.7 open mailbox with raised flag
+1F4ED ; fully-qualified # 📭 E0.7 open mailbox with lowered flag
+1F4EE ; fully-qualified # 📮 E0.6 postbox
+1F5F3 FE0F ; fully-qualified # 🗳️ E0.7 ballot box with ballot
+1F5F3 ; unqualified # 🗳 E0.7 ballot box with ballot
+
+# subgroup: writing
+270F FE0F ; fully-qualified # ✏️ E0.6 pencil
+270F ; unqualified # ✏ E0.6 pencil
+2712 FE0F ; fully-qualified # ✒️ E0.6 black nib
+2712 ; unqualified # ✒ E0.6 black nib
+1F58B FE0F ; fully-qualified # 🖋️ E0.7 fountain pen
+1F58B ; unqualified # 🖋 E0.7 fountain pen
+1F58A FE0F ; fully-qualified # 🖊️ E0.7 pen
+1F58A ; unqualified # 🖊 E0.7 pen
+1F58C FE0F ; fully-qualified # 🖌️ E0.7 paintbrush
+1F58C ; unqualified # 🖌 E0.7 paintbrush
+1F58D FE0F ; fully-qualified # 🖍️ E0.7 crayon
+1F58D ; unqualified # 🖍 E0.7 crayon
+1F4DD ; fully-qualified # 📝 E0.6 memo
+
+# subgroup: office
+1F4BC ; fully-qualified # 💼 E0.6 briefcase
+1F4C1 ; fully-qualified # 📁 E0.6 file folder
+1F4C2 ; fully-qualified # 📂 E0.6 open file folder
+1F5C2 FE0F ; fully-qualified # 🗂️ E0.7 card index dividers
+1F5C2 ; unqualified # 🗂 E0.7 card index dividers
+1F4C5 ; fully-qualified # 📅 E0.6 calendar
+1F4C6 ; fully-qualified # 📆 E0.6 tear-off calendar
+1F5D2 FE0F ; fully-qualified # 🗒️ E0.7 spiral notepad
+1F5D2 ; unqualified # 🗒 E0.7 spiral notepad
+1F5D3 FE0F ; fully-qualified # 🗓️ E0.7 spiral calendar
+1F5D3 ; unqualified # 🗓 E0.7 spiral calendar
+1F4C7 ; fully-qualified # 📇 E0.6 card index
+1F4C8 ; fully-qualified # 📈 E0.6 chart increasing
+1F4C9 ; fully-qualified # 📉 E0.6 chart decreasing
+1F4CA ; fully-qualified # 📊 E0.6 bar chart
+1F4CB ; fully-qualified # 📋 E0.6 clipboard
+1F4CC ; fully-qualified # 📌 E0.6 pushpin
+1F4CD ; fully-qualified # 📍 E0.6 round pushpin
+1F4CE ; fully-qualified # 📎 E0.6 paperclip
+1F587 FE0F ; fully-qualified # 🖇️ E0.7 linked paperclips
+1F587 ; unqualified # 🖇 E0.7 linked paperclips
+1F4CF ; fully-qualified # 📏 E0.6 straight ruler
+1F4D0 ; fully-qualified # 📐 E0.6 triangular ruler
+2702 FE0F ; fully-qualified # ✂️ E0.6 scissors
+2702 ; unqualified # ✂ E0.6 scissors
+1F5C3 FE0F ; fully-qualified # 🗃️ E0.7 card file box
+1F5C3 ; unqualified # 🗃 E0.7 card file box
+1F5C4 FE0F ; fully-qualified # 🗄️ E0.7 file cabinet
+1F5C4 ; unqualified # 🗄 E0.7 file cabinet
+1F5D1 FE0F ; fully-qualified # 🗑️ E0.7 wastebasket
+1F5D1 ; unqualified # 🗑 E0.7 wastebasket
+
+# subgroup: lock
+1F512 ; fully-qualified # 🔒 E0.6 locked
+1F513 ; fully-qualified # 🔓 E0.6 unlocked
+1F50F ; fully-qualified # 🔏 E0.6 locked with pen
+1F510 ; fully-qualified # 🔐 E0.6 locked with key
+1F511 ; fully-qualified # 🔑 E0.6 key
+1F5DD FE0F ; fully-qualified # 🗝️ E0.7 old key
+1F5DD ; unqualified # 🗝 E0.7 old key
+
+# subgroup: tool
+1F528 ; fully-qualified # 🔨 E0.6 hammer
+1FA93 ; fully-qualified # 🪓 E12.0 axe
+26CF FE0F ; fully-qualified # ⛏️ E0.7 pick
+26CF ; unqualified # ⛏ E0.7 pick
+2692 FE0F ; fully-qualified # ⚒️ E1.0 hammer and pick
+2692 ; unqualified # ⚒ E1.0 hammer and pick
+1F6E0 FE0F ; fully-qualified # 🛠️ E0.7 hammer and wrench
+1F6E0 ; unqualified # 🛠 E0.7 hammer and wrench
+1F5E1 FE0F ; fully-qualified # 🗡️ E0.7 dagger
+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
+1FA83 ; fully-qualified # 🪃 E13.0 boomerang
+1F3F9 ; fully-qualified # 🏹 E1.0 bow and arrow
+1F6E1 FE0F ; fully-qualified # 🛡️ E0.7 shield
+1F6E1 ; unqualified # 🛡 E0.7 shield
+1FA9A ; fully-qualified # 🪚 E13.0 carpentry saw
+1F527 ; fully-qualified # 🔧 E0.6 wrench
+1FA9B ; fully-qualified # 🪛 E13.0 screwdriver
+1F529 ; fully-qualified # 🔩 E0.6 nut and bolt
+2699 FE0F ; fully-qualified # ⚙️ E1.0 gear
+2699 ; unqualified # ⚙ E1.0 gear
+1F5DC FE0F ; fully-qualified # 🗜️ E0.7 clamp
+1F5DC ; unqualified # 🗜 E0.7 clamp
+2696 FE0F ; fully-qualified # ⚖️ E1.0 balance scale
+2696 ; unqualified # ⚖ E1.0 balance scale
+1F9AF ; fully-qualified # 🦯 E12.0 white cane
+1F517 ; fully-qualified # 🔗 E0.6 link
+26D3 FE0F ; fully-qualified # ⛓️ E0.7 chains
+26D3 ; unqualified # ⛓ E0.7 chains
+1FA9D ; fully-qualified # 🪝 E13.0 hook
+1F9F0 ; fully-qualified # 🧰 E11.0 toolbox
+1F9F2 ; fully-qualified # 🧲 E11.0 magnet
+1FA9C ; fully-qualified # 🪜 E13.0 ladder
+
+# subgroup: science
+2697 FE0F ; fully-qualified # ⚗️ E1.0 alembic
+2697 ; unqualified # ⚗ E1.0 alembic
+1F9EA ; fully-qualified # 🧪 E11.0 test tube
+1F9EB ; fully-qualified # 🧫 E11.0 petri dish
+1F9EC ; fully-qualified # 🧬 E11.0 dna
+1F52C ; fully-qualified # 🔬 E1.0 microscope
+1F52D ; fully-qualified # 🔭 E1.0 telescope
+1F4E1 ; fully-qualified # 📡 E0.6 satellite antenna
+
+# subgroup: medical
+1F489 ; fully-qualified # 💉 E0.6 syringe
+1FA78 ; fully-qualified # 🩸 E12.0 drop of blood
+1F48A ; fully-qualified # 💊 E0.6 pill
+1FA79 ; fully-qualified # 🩹 E12.0 adhesive bandage
+1FA7C ; fully-qualified # 🩼 E14.0 crutch
+1FA7A ; fully-qualified # 🩺 E12.0 stethoscope
+1FA7B ; fully-qualified # 🩻 E14.0 x-ray
+
+# subgroup: household
+1F6AA ; fully-qualified # 🚪 E0.6 door
+1F6D7 ; fully-qualified # 🛗 E13.0 elevator
+1FA9E ; fully-qualified # 🪞 E13.0 mirror
+1FA9F ; fully-qualified # 🪟 E13.0 window
+1F6CF FE0F ; fully-qualified # 🛏️ E0.7 bed
+1F6CF ; unqualified # 🛏 E0.7 bed
+1F6CB FE0F ; fully-qualified # 🛋️ E0.7 couch and lamp
+1F6CB ; unqualified # 🛋 E0.7 couch and lamp
+1FA91 ; fully-qualified # 🪑 E12.0 chair
+1F6BD ; fully-qualified # 🚽 E0.6 toilet
+1FAA0 ; fully-qualified # 🪠 E13.0 plunger
+1F6BF ; fully-qualified # 🚿 E1.0 shower
+1F6C1 ; fully-qualified # 🛁 E1.0 bathtub
+1FAA4 ; fully-qualified # 🪤 E13.0 mouse trap
+1FA92 ; fully-qualified # 🪒 E12.0 razor
+1F9F4 ; fully-qualified # 🧴 E11.0 lotion bottle
+1F9F7 ; fully-qualified # 🧷 E11.0 safety pin
+1F9F9 ; fully-qualified # 🧹 E11.0 broom
+1F9FA ; fully-qualified # 🧺 E11.0 basket
+1F9FB ; fully-qualified # 🧻 E11.0 roll of paper
+1FAA3 ; fully-qualified # 🪣 E13.0 bucket
+1F9FC ; fully-qualified # 🧼 E11.0 soap
+1FAE7 ; fully-qualified # 🫧 E14.0 bubbles
+1FAA5 ; fully-qualified # 🪥 E13.0 toothbrush
+1F9FD ; fully-qualified # 🧽 E11.0 sponge
+1F9EF ; fully-qualified # 🧯 E11.0 fire extinguisher
+1F6D2 ; fully-qualified # 🛒 E3.0 shopping cart
+
+# subgroup: other-object
+1F6AC ; fully-qualified # 🚬 E0.6 cigarette
+26B0 FE0F ; fully-qualified # ⚰️ E1.0 coffin
+26B0 ; unqualified # ⚰ E1.0 coffin
+1FAA6 ; fully-qualified # 🪦 E13.0 headstone
+26B1 FE0F ; fully-qualified # ⚱️ E1.0 funeral urn
+26B1 ; unqualified # ⚱ E1.0 funeral urn
+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
+
+# group: Symbols
+
+# subgroup: transport-sign
+1F3E7 ; fully-qualified # 🏧 E0.6 ATM sign
+1F6AE ; fully-qualified # 🚮 E1.0 litter in bin sign
+1F6B0 ; fully-qualified # 🚰 E1.0 potable water
+267F ; fully-qualified # ♿ E0.6 wheelchair symbol
+1F6B9 ; fully-qualified # 🚹 E0.6 men’s room
+1F6BA ; fully-qualified # 🚺 E0.6 women’s room
+1F6BB ; fully-qualified # 🚻 E0.6 restroom
+1F6BC ; fully-qualified # 🚼 E0.6 baby symbol
+1F6BE ; fully-qualified # 🚾 E0.6 water closet
+1F6C2 ; fully-qualified # 🛂 E1.0 passport control
+1F6C3 ; fully-qualified # 🛃 E1.0 customs
+1F6C4 ; fully-qualified # 🛄 E1.0 baggage claim
+1F6C5 ; fully-qualified # 🛅 E1.0 left luggage
+
+# subgroup: warning
+26A0 FE0F ; fully-qualified # ⚠️ E0.6 warning
+26A0 ; unqualified # ⚠ E0.6 warning
+1F6B8 ; fully-qualified # 🚸 E1.0 children crossing
+26D4 ; fully-qualified # ⛔ E0.6 no entry
+1F6AB ; fully-qualified # 🚫 E0.6 prohibited
+1F6B3 ; fully-qualified # 🚳 E1.0 no bicycles
+1F6AD ; fully-qualified # 🚭 E0.6 no smoking
+1F6AF ; fully-qualified # 🚯 E1.0 no littering
+1F6B1 ; fully-qualified # 🚱 E1.0 non-potable water
+1F6B7 ; fully-qualified # 🚷 E1.0 no pedestrians
+1F4F5 ; fully-qualified # 📵 E1.0 no mobile phones
+1F51E ; fully-qualified # 🔞 E0.6 no one under eighteen
+2622 FE0F ; fully-qualified # ☢️ E1.0 radioactive
+2622 ; unqualified # ☢ E1.0 radioactive
+2623 FE0F ; fully-qualified # ☣️ E1.0 biohazard
+2623 ; unqualified # ☣ E1.0 biohazard
+
+# subgroup: arrow
+2B06 FE0F ; fully-qualified # ⬆️ E0.6 up arrow
+2B06 ; unqualified # ⬆ E0.6 up arrow
+2197 FE0F ; fully-qualified # ↗️ E0.6 up-right arrow
+2197 ; unqualified # ↗ E0.6 up-right arrow
+27A1 FE0F ; fully-qualified # ➡️ E0.6 right arrow
+27A1 ; unqualified # ➡ E0.6 right arrow
+2198 FE0F ; fully-qualified # ↘️ E0.6 down-right arrow
+2198 ; unqualified # ↘ E0.6 down-right arrow
+2B07 FE0F ; fully-qualified # ⬇️ E0.6 down arrow
+2B07 ; unqualified # ⬇ E0.6 down arrow
+2199 FE0F ; fully-qualified # ↙️ E0.6 down-left arrow
+2199 ; unqualified # ↙ E0.6 down-left arrow
+2B05 FE0F ; fully-qualified # ⬅️ E0.6 left arrow
+2B05 ; unqualified # ⬅ E0.6 left arrow
+2196 FE0F ; fully-qualified # ↖️ E0.6 up-left arrow
+2196 ; unqualified # ↖ E0.6 up-left arrow
+2195 FE0F ; fully-qualified # ↕️ E0.6 up-down arrow
+2195 ; unqualified # ↕ E0.6 up-down arrow
+2194 FE0F ; fully-qualified # ↔️ E0.6 left-right arrow
+2194 ; unqualified # ↔ E0.6 left-right arrow
+21A9 FE0F ; fully-qualified # ↩️ E0.6 right arrow curving left
+21A9 ; unqualified # ↩ E0.6 right arrow curving left
+21AA FE0F ; fully-qualified # ↪️ E0.6 left arrow curving right
+21AA ; unqualified # ↪ E0.6 left arrow curving right
+2934 FE0F ; fully-qualified # ⤴️ E0.6 right arrow curving up
+2934 ; unqualified # ⤴ E0.6 right arrow curving up
+2935 FE0F ; fully-qualified # ⤵️ E0.6 right arrow curving down
+2935 ; unqualified # ⤵ E0.6 right arrow curving down
+1F503 ; fully-qualified # 🔃 E0.6 clockwise vertical arrows
+1F504 ; fully-qualified # 🔄 E1.0 counterclockwise arrows button
+1F519 ; fully-qualified # 🔙 E0.6 BACK arrow
+1F51A ; fully-qualified # 🔚 E0.6 END arrow
+1F51B ; fully-qualified # 🔛 E0.6 ON! arrow
+1F51C ; fully-qualified # 🔜 E0.6 SOON arrow
+1F51D ; fully-qualified # 🔝 E0.6 TOP arrow
+
+# subgroup: religion
+1F6D0 ; fully-qualified # 🛐 E1.0 place of worship
+269B FE0F ; fully-qualified # ⚛️ E1.0 atom symbol
+269B ; unqualified # ⚛ E1.0 atom symbol
+1F549 FE0F ; fully-qualified # 🕉️ E0.7 om
+1F549 ; unqualified # 🕉 E0.7 om
+2721 FE0F ; fully-qualified # ✡️ E0.7 star of David
+2721 ; unqualified # ✡ E0.7 star of David
+2638 FE0F ; fully-qualified # ☸️ E0.7 wheel of dharma
+2638 ; unqualified # ☸ E0.7 wheel of dharma
+262F FE0F ; fully-qualified # ☯️ E0.7 yin yang
+262F ; unqualified # ☯ E0.7 yin yang
+271D FE0F ; fully-qualified # ✝️ E0.7 latin cross
+271D ; unqualified # ✝ E0.7 latin cross
+2626 FE0F ; fully-qualified # ☦️ E1.0 orthodox cross
+2626 ; unqualified # ☦ E1.0 orthodox cross
+262A FE0F ; fully-qualified # ☪️ E0.7 star and crescent
+262A ; unqualified # ☪ E0.7 star and crescent
+262E FE0F ; fully-qualified # ☮️ E1.0 peace symbol
+262E ; unqualified # ☮ E1.0 peace symbol
+1F54E ; fully-qualified # 🕎 E1.0 menorah
+1F52F ; fully-qualified # 🔯 E0.6 dotted six-pointed star
+
+# subgroup: zodiac
+2648 ; fully-qualified # ♈ E0.6 Aries
+2649 ; fully-qualified # ♉ E0.6 Taurus
+264A ; fully-qualified # ♊ E0.6 Gemini
+264B ; fully-qualified # ♋ E0.6 Cancer
+264C ; fully-qualified # ♌ E0.6 Leo
+264D ; fully-qualified # ♍ E0.6 Virgo
+264E ; fully-qualified # ♎ E0.6 Libra
+264F ; fully-qualified # ♏ E0.6 Scorpio
+2650 ; fully-qualified # ♐ E0.6 Sagittarius
+2651 ; fully-qualified # ♑ E0.6 Capricorn
+2652 ; fully-qualified # ♒ E0.6 Aquarius
+2653 ; fully-qualified # ♓ E0.6 Pisces
+26CE ; fully-qualified # ⛎ E0.6 Ophiuchus
+
+# subgroup: av-symbol
+1F500 ; fully-qualified # 🔀 E1.0 shuffle tracks button
+1F501 ; fully-qualified # 🔁 E1.0 repeat button
+1F502 ; fully-qualified # 🔂 E1.0 repeat single button
+25B6 FE0F ; fully-qualified # ▶️ E0.6 play button
+25B6 ; unqualified # ▶ E0.6 play button
+23E9 ; fully-qualified # ⏩ E0.6 fast-forward button
+23ED FE0F ; fully-qualified # ⏭️ E0.7 next track button
+23ED ; unqualified # ⏭ E0.7 next track button
+23EF FE0F ; fully-qualified # ⏯️ E1.0 play or pause button
+23EF ; unqualified # ⏯ E1.0 play or pause button
+25C0 FE0F ; fully-qualified # ◀️ E0.6 reverse button
+25C0 ; unqualified # ◀ E0.6 reverse button
+23EA ; fully-qualified # ⏪ E0.6 fast reverse button
+23EE FE0F ; fully-qualified # ⏮️ E0.7 last track button
+23EE ; unqualified # ⏮ E0.7 last track button
+1F53C ; fully-qualified # 🔼 E0.6 upwards button
+23EB ; fully-qualified # ⏫ E0.6 fast up button
+1F53D ; fully-qualified # 🔽 E0.6 downwards button
+23EC ; fully-qualified # ⏬ E0.6 fast down button
+23F8 FE0F ; fully-qualified # ⏸️ E0.7 pause button
+23F8 ; unqualified # ⏸ E0.7 pause button
+23F9 FE0F ; fully-qualified # ⏹️ E0.7 stop button
+23F9 ; unqualified # ⏹ E0.7 stop button
+23FA FE0F ; fully-qualified # ⏺️ E0.7 record button
+23FA ; unqualified # ⏺ E0.7 record button
+23CF FE0F ; fully-qualified # ⏏️ E1.0 eject button
+23CF ; unqualified # ⏏ E1.0 eject button
+1F3A6 ; fully-qualified # 🎦 E0.6 cinema
+1F505 ; fully-qualified # 🔅 E1.0 dim button
+1F506 ; fully-qualified # 🔆 E1.0 bright button
+1F4F6 ; fully-qualified # 📶 E0.6 antenna bars
+1F4F3 ; fully-qualified # 📳 E0.6 vibration mode
+1F4F4 ; fully-qualified # 📴 E0.6 mobile phone off
+
+# subgroup: gender
+2640 FE0F ; fully-qualified # ♀️ E4.0 female sign
+2640 ; unqualified # ♀ E4.0 female sign
+2642 FE0F ; fully-qualified # ♂️ E4.0 male sign
+2642 ; unqualified # ♂ E4.0 male sign
+26A7 FE0F ; fully-qualified # ⚧️ E13.0 transgender symbol
+26A7 ; unqualified # ⚧ E13.0 transgender symbol
+
+# subgroup: math
+2716 FE0F ; fully-qualified # ✖️ E0.6 multiply
+2716 ; unqualified # ✖ E0.6 multiply
+2795 ; fully-qualified # ➕ E0.6 plus
+2796 ; fully-qualified # ➖ E0.6 minus
+2797 ; fully-qualified # ➗ E0.6 divide
+1F7F0 ; fully-qualified # 🟰 E14.0 heavy equals sign
+267E FE0F ; fully-qualified # ♾️ E11.0 infinity
+267E ; unqualified # ♾ E11.0 infinity
+
+# subgroup: punctuation
+203C FE0F ; fully-qualified # ‼️ E0.6 double exclamation mark
+203C ; unqualified # ‼ E0.6 double exclamation mark
+2049 FE0F ; fully-qualified # ⁉️ E0.6 exclamation question mark
+2049 ; unqualified # ⁉ E0.6 exclamation question mark
+2753 ; fully-qualified # ❓ E0.6 red question mark
+2754 ; fully-qualified # ❔ E0.6 white question mark
+2755 ; fully-qualified # ❕ E0.6 white exclamation mark
+2757 ; fully-qualified # ❗ E0.6 red exclamation mark
+3030 FE0F ; fully-qualified # 〰️ E0.6 wavy dash
+3030 ; unqualified # 〰 E0.6 wavy dash
+
+# subgroup: currency
+1F4B1 ; fully-qualified # 💱 E0.6 currency exchange
+1F4B2 ; fully-qualified # 💲 E0.6 heavy dollar sign
+
+# subgroup: other-symbol
+2695 FE0F ; fully-qualified # ⚕️ E4.0 medical symbol
+2695 ; unqualified # ⚕ E4.0 medical symbol
+267B FE0F ; fully-qualified # ♻️ E0.6 recycling symbol
+267B ; unqualified # ♻ E0.6 recycling symbol
+269C FE0F ; fully-qualified # ⚜️ E1.0 fleur-de-lis
+269C ; unqualified # ⚜ E1.0 fleur-de-lis
+1F531 ; fully-qualified # 🔱 E0.6 trident emblem
+1F4DB ; fully-qualified # 📛 E0.6 name badge
+1F530 ; fully-qualified # 🔰 E0.6 Japanese symbol for beginner
+2B55 ; fully-qualified # ⭕ E0.6 hollow red circle
+2705 ; fully-qualified # ✅ E0.6 check mark button
+2611 FE0F ; fully-qualified # ☑️ E0.6 check box with check
+2611 ; unqualified # ☑ E0.6 check box with check
+2714 FE0F ; fully-qualified # ✔️ E0.6 check mark
+2714 ; unqualified # ✔ E0.6 check mark
+274C ; fully-qualified # ❌ E0.6 cross mark
+274E ; fully-qualified # ❎ E0.6 cross mark button
+27B0 ; fully-qualified # ➰ E0.6 curly loop
+27BF ; fully-qualified # ➿ E1.0 double curly loop
+303D FE0F ; fully-qualified # 〽️ E0.6 part alternation mark
+303D ; unqualified # 〽 E0.6 part alternation mark
+2733 FE0F ; fully-qualified # ✳️ E0.6 eight-spoked asterisk
+2733 ; unqualified # ✳ E0.6 eight-spoked asterisk
+2734 FE0F ; fully-qualified # ✴️ E0.6 eight-pointed star
+2734 ; unqualified # ✴ E0.6 eight-pointed star
+2747 FE0F ; fully-qualified # ❇️ E0.6 sparkle
+2747 ; unqualified # ❇ E0.6 sparkle
+00A9 FE0F ; fully-qualified # ©️ E0.6 copyright
+00A9 ; unqualified # © E0.6 copyright
+00AE FE0F ; fully-qualified # ®️ E0.6 registered
+00AE ; unqualified # ® E0.6 registered
+2122 FE0F ; fully-qualified # ™️ E0.6 trade mark
+2122 ; unqualified # ™ E0.6 trade mark
+
+# subgroup: keycap
+0023 FE0F 20E3 ; fully-qualified # #️⃣ E0.6 keycap: #
+0023 20E3 ; unqualified # #⃣ E0.6 keycap: #
+002A FE0F 20E3 ; fully-qualified # *️⃣ E2.0 keycap: *
+002A 20E3 ; unqualified # *⃣ E2.0 keycap: *
+0030 FE0F 20E3 ; fully-qualified # 0️⃣ E0.6 keycap: 0
+0030 20E3 ; unqualified # 0⃣ E0.6 keycap: 0
+0031 FE0F 20E3 ; fully-qualified # 1️⃣ E0.6 keycap: 1
+0031 20E3 ; unqualified # 1⃣ E0.6 keycap: 1
+0032 FE0F 20E3 ; fully-qualified # 2️⃣ E0.6 keycap: 2
+0032 20E3 ; unqualified # 2⃣ E0.6 keycap: 2
+0033 FE0F 20E3 ; fully-qualified # 3️⃣ E0.6 keycap: 3
+0033 20E3 ; unqualified # 3⃣ E0.6 keycap: 3
+0034 FE0F 20E3 ; fully-qualified # 4️⃣ E0.6 keycap: 4
+0034 20E3 ; unqualified # 4⃣ E0.6 keycap: 4
+0035 FE0F 20E3 ; fully-qualified # 5️⃣ E0.6 keycap: 5
+0035 20E3 ; unqualified # 5⃣ E0.6 keycap: 5
+0036 FE0F 20E3 ; fully-qualified # 6️⃣ E0.6 keycap: 6
+0036 20E3 ; unqualified # 6⃣ E0.6 keycap: 6
+0037 FE0F 20E3 ; fully-qualified # 7️⃣ E0.6 keycap: 7
+0037 20E3 ; unqualified # 7⃣ E0.6 keycap: 7
+0038 FE0F 20E3 ; fully-qualified # 8️⃣ E0.6 keycap: 8
+0038 20E3 ; unqualified # 8⃣ E0.6 keycap: 8
+0039 FE0F 20E3 ; fully-qualified # 9️⃣ E0.6 keycap: 9
+0039 20E3 ; unqualified # 9⃣ E0.6 keycap: 9
+1F51F ; fully-qualified # 🔟 E0.6 keycap: 10
+
+# subgroup: alphanum
+1F520 ; fully-qualified # 🔠 E0.6 input latin uppercase
+1F521 ; fully-qualified # 🔡 E0.6 input latin lowercase
+1F522 ; fully-qualified # 🔢 E0.6 input numbers
+1F523 ; fully-qualified # 🔣 E0.6 input symbols
+1F524 ; fully-qualified # 🔤 E0.6 input latin letters
+1F170 FE0F ; fully-qualified # 🅰️ E0.6 A button (blood type)
+1F170 ; unqualified # 🅰 E0.6 A button (blood type)
+1F18E ; fully-qualified # 🆎 E0.6 AB button (blood type)
+1F171 FE0F ; fully-qualified # 🅱️ E0.6 B button (blood type)
+1F171 ; unqualified # 🅱 E0.6 B button (blood type)
+1F191 ; fully-qualified # 🆑 E0.6 CL button
+1F192 ; fully-qualified # 🆒 E0.6 COOL button
+1F193 ; fully-qualified # 🆓 E0.6 FREE button
+2139 FE0F ; fully-qualified # ℹ️ E0.6 information
+2139 ; unqualified # ℹ E0.6 information
+1F194 ; fully-qualified # 🆔 E0.6 ID button
+24C2 FE0F ; fully-qualified # Ⓜ️ E0.6 circled M
+24C2 ; unqualified # Ⓜ E0.6 circled M
+1F195 ; fully-qualified # 🆕 E0.6 NEW button
+1F196 ; fully-qualified # 🆖 E0.6 NG button
+1F17E FE0F ; fully-qualified # 🅾️ E0.6 O button (blood type)
+1F17E ; unqualified # 🅾 E0.6 O button (blood type)
+1F197 ; fully-qualified # 🆗 E0.6 OK button
+1F17F FE0F ; fully-qualified # 🅿️ E0.6 P button
+1F17F ; unqualified # 🅿 E0.6 P button
+1F198 ; fully-qualified # 🆘 E0.6 SOS button
+1F199 ; fully-qualified # 🆙 E0.6 UP! button
+1F19A ; fully-qualified # 🆚 E0.6 VS button
+1F201 ; fully-qualified # 🈁 E0.6 Japanese “here” button
+1F202 FE0F ; fully-qualified # 🈂️ E0.6 Japanese “service charge” button
+1F202 ; unqualified # 🈂 E0.6 Japanese “service charge” button
+1F237 FE0F ; fully-qualified # 🈷️ E0.6 Japanese “monthly amount” button
+1F237 ; unqualified # 🈷 E0.6 Japanese “monthly amount” button
+1F236 ; fully-qualified # 🈶 E0.6 Japanese “not free of charge” button
+1F22F ; fully-qualified # 🈯 E0.6 Japanese “reserved” button
+1F250 ; fully-qualified # 🉐 E0.6 Japanese “bargain” button
+1F239 ; fully-qualified # 🈹 E0.6 Japanese “discount” button
+1F21A ; fully-qualified # 🈚 E0.6 Japanese “free of charge” button
+1F232 ; fully-qualified # 🈲 E0.6 Japanese “prohibited” button
+1F251 ; fully-qualified # 🉑 E0.6 Japanese “acceptable” button
+1F238 ; fully-qualified # 🈸 E0.6 Japanese “application” button
+1F234 ; fully-qualified # 🈴 E0.6 Japanese “passing grade” button
+1F233 ; fully-qualified # 🈳 E0.6 Japanese “vacancy” button
+3297 FE0F ; fully-qualified # ㊗️ E0.6 Japanese “congratulations” button
+3297 ; unqualified # ㊗ E0.6 Japanese “congratulations” button
+3299 FE0F ; fully-qualified # ㊙️ E0.6 Japanese “secret” button
+3299 ; unqualified # ㊙ E0.6 Japanese “secret” button
+1F23A ; fully-qualified # 🈺 E0.6 Japanese “open for business” button
+1F235 ; fully-qualified # 🈵 E0.6 Japanese “no vacancy” button
+
+# subgroup: geometric
+1F534 ; fully-qualified # 🔴 E0.6 red circle
+1F7E0 ; fully-qualified # 🟠 E12.0 orange circle
+1F7E1 ; fully-qualified # 🟡 E12.0 yellow circle
+1F7E2 ; fully-qualified # 🟢 E12.0 green circle
+1F535 ; fully-qualified # 🔵 E0.6 blue circle
+1F7E3 ; fully-qualified # 🟣 E12.0 purple circle
+1F7E4 ; fully-qualified # 🟤 E12.0 brown circle
+26AB ; fully-qualified # ⚫ E0.6 black circle
+26AA ; fully-qualified # ⚪ E0.6 white circle
+1F7E5 ; fully-qualified # 🟥 E12.0 red square
+1F7E7 ; fully-qualified # 🟧 E12.0 orange square
+1F7E8 ; fully-qualified # 🟨 E12.0 yellow square
+1F7E9 ; fully-qualified # 🟩 E12.0 green square
+1F7E6 ; fully-qualified # 🟦 E12.0 blue square
+1F7EA ; fully-qualified # 🟪 E12.0 purple square
+1F7EB ; fully-qualified # 🟫 E12.0 brown square
+2B1B ; fully-qualified # ⬛ E0.6 black large square
+2B1C ; fully-qualified # ⬜ E0.6 white large square
+25FC FE0F ; fully-qualified # ◼️ E0.6 black medium square
+25FC ; unqualified # ◼ E0.6 black medium square
+25FB FE0F ; fully-qualified # ◻️ E0.6 white medium square
+25FB ; unqualified # ◻ E0.6 white medium square
+25FE ; fully-qualified # ◾ E0.6 black medium-small square
+25FD ; fully-qualified # ◽ E0.6 white medium-small square
+25AA FE0F ; fully-qualified # ▪️ E0.6 black small square
+25AA ; unqualified # ▪ E0.6 black small square
+25AB FE0F ; fully-qualified # ▫️ E0.6 white small square
+25AB ; unqualified # ▫ E0.6 white small square
+1F536 ; fully-qualified # 🔶 E0.6 large orange diamond
+1F537 ; fully-qualified # 🔷 E0.6 large blue diamond
+1F538 ; fully-qualified # 🔸 E0.6 small orange diamond
+1F539 ; fully-qualified # 🔹 E0.6 small blue diamond
+1F53A ; fully-qualified # 🔺 E0.6 red triangle pointed up
+1F53B ; fully-qualified # 🔻 E0.6 red triangle pointed down
+1F4A0 ; fully-qualified # 💠 E0.6 diamond with a dot
+1F518 ; fully-qualified # 🔘 E0.6 radio button
+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
+
+# group: Flags
+
+# subgroup: flag
+1F3C1 ; fully-qualified # 🏁 E0.6 chequered flag
+1F6A9 ; fully-qualified # 🚩 E0.6 triangular flag
+1F38C ; fully-qualified # 🎌 E0.6 crossed flags
+1F3F4 ; fully-qualified # 🏴 E1.0 black flag
+1F3F3 FE0F ; fully-qualified # 🏳️ E0.7 white flag
+1F3F3 ; unqualified # 🏳 E0.7 white flag
+1F3F3 FE0F 200D 1F308 ; fully-qualified # 🏳️‍🌈 E4.0 rainbow flag
+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 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
+
+# subgroup: country-flag
+1F1E6 1F1E8 ; fully-qualified # 🇦🇨 E2.0 flag: Ascension Island
+1F1E6 1F1E9 ; fully-qualified # 🇦🇩 E2.0 flag: Andorra
+1F1E6 1F1EA ; fully-qualified # 🇦🇪 E2.0 flag: United Arab Emirates
+1F1E6 1F1EB ; fully-qualified # 🇦🇫 E2.0 flag: Afghanistan
+1F1E6 1F1EC ; fully-qualified # 🇦🇬 E2.0 flag: Antigua & Barbuda
+1F1E6 1F1EE ; fully-qualified # 🇦🇮 E2.0 flag: Anguilla
+1F1E6 1F1F1 ; fully-qualified # 🇦🇱 E2.0 flag: Albania
+1F1E6 1F1F2 ; fully-qualified # 🇦🇲 E2.0 flag: Armenia
+1F1E6 1F1F4 ; fully-qualified # 🇦🇴 E2.0 flag: Angola
+1F1E6 1F1F6 ; fully-qualified # 🇦🇶 E2.0 flag: Antarctica
+1F1E6 1F1F7 ; fully-qualified # 🇦🇷 E2.0 flag: Argentina
+1F1E6 1F1F8 ; fully-qualified # 🇦🇸 E2.0 flag: American Samoa
+1F1E6 1F1F9 ; fully-qualified # 🇦🇹 E2.0 flag: Austria
+1F1E6 1F1FA ; fully-qualified # 🇦🇺 E2.0 flag: Australia
+1F1E6 1F1FC ; fully-qualified # 🇦🇼 E2.0 flag: Aruba
+1F1E6 1F1FD ; fully-qualified # 🇦🇽 E2.0 flag: Åland Islands
+1F1E6 1F1FF ; fully-qualified # 🇦🇿 E2.0 flag: Azerbaijan
+1F1E7 1F1E6 ; fully-qualified # 🇧🇦 E2.0 flag: Bosnia & Herzegovina
+1F1E7 1F1E7 ; fully-qualified # 🇧🇧 E2.0 flag: Barbados
+1F1E7 1F1E9 ; fully-qualified # 🇧🇩 E2.0 flag: Bangladesh
+1F1E7 1F1EA ; fully-qualified # 🇧🇪 E2.0 flag: Belgium
+1F1E7 1F1EB ; fully-qualified # 🇧🇫 E2.0 flag: Burkina Faso
+1F1E7 1F1EC ; fully-qualified # 🇧🇬 E2.0 flag: Bulgaria
+1F1E7 1F1ED ; fully-qualified # 🇧🇭 E2.0 flag: Bahrain
+1F1E7 1F1EE ; fully-qualified # 🇧🇮 E2.0 flag: Burundi
+1F1E7 1F1EF ; fully-qualified # 🇧🇯 E2.0 flag: Benin
+1F1E7 1F1F1 ; fully-qualified # 🇧🇱 E2.0 flag: St. Barthélemy
+1F1E7 1F1F2 ; fully-qualified # 🇧🇲 E2.0 flag: Bermuda
+1F1E7 1F1F3 ; fully-qualified # 🇧🇳 E2.0 flag: Brunei
+1F1E7 1F1F4 ; fully-qualified # 🇧🇴 E2.0 flag: Bolivia
+1F1E7 1F1F6 ; fully-qualified # 🇧🇶 E2.0 flag: Caribbean Netherlands
+1F1E7 1F1F7 ; fully-qualified # 🇧🇷 E2.0 flag: Brazil
+1F1E7 1F1F8 ; fully-qualified # 🇧🇸 E2.0 flag: Bahamas
+1F1E7 1F1F9 ; fully-qualified # 🇧🇹 E2.0 flag: Bhutan
+1F1E7 1F1FB ; fully-qualified # 🇧🇻 E2.0 flag: Bouvet Island
+1F1E7 1F1FC ; fully-qualified # 🇧🇼 E2.0 flag: Botswana
+1F1E7 1F1FE ; fully-qualified # 🇧🇾 E2.0 flag: Belarus
+1F1E7 1F1FF ; fully-qualified # 🇧🇿 E2.0 flag: Belize
+1F1E8 1F1E6 ; fully-qualified # 🇨🇦 E2.0 flag: Canada
+1F1E8 1F1E8 ; fully-qualified # 🇨🇨 E2.0 flag: Cocos (Keeling) Islands
+1F1E8 1F1E9 ; fully-qualified # 🇨🇩 E2.0 flag: Congo - Kinshasa
+1F1E8 1F1EB ; fully-qualified # 🇨🇫 E2.0 flag: Central African Republic
+1F1E8 1F1EC ; fully-qualified # 🇨🇬 E2.0 flag: Congo - Brazzaville
+1F1E8 1F1ED ; fully-qualified # 🇨🇭 E2.0 flag: Switzerland
+1F1E8 1F1EE ; fully-qualified # 🇨🇮 E2.0 flag: Côte d’Ivoire
+1F1E8 1F1F0 ; fully-qualified # 🇨🇰 E2.0 flag: Cook Islands
+1F1E8 1F1F1 ; fully-qualified # 🇨🇱 E2.0 flag: Chile
+1F1E8 1F1F2 ; fully-qualified # 🇨🇲 E2.0 flag: Cameroon
+1F1E8 1F1F3 ; fully-qualified # 🇨🇳 E0.6 flag: China
+1F1E8 1F1F4 ; fully-qualified # 🇨🇴 E2.0 flag: Colombia
+1F1E8 1F1F5 ; fully-qualified # 🇨🇵 E2.0 flag: Clipperton Island
+1F1E8 1F1F7 ; fully-qualified # 🇨🇷 E2.0 flag: Costa Rica
+1F1E8 1F1FA ; fully-qualified # 🇨🇺 E2.0 flag: Cuba
+1F1E8 1F1FB ; fully-qualified # 🇨🇻 E2.0 flag: Cape Verde
+1F1E8 1F1FC ; fully-qualified # 🇨🇼 E2.0 flag: Curaçao
+1F1E8 1F1FD ; fully-qualified # 🇨🇽 E2.0 flag: Christmas Island
+1F1E8 1F1FE ; fully-qualified # 🇨🇾 E2.0 flag: Cyprus
+1F1E8 1F1FF ; fully-qualified # 🇨🇿 E2.0 flag: Czechia
+1F1E9 1F1EA ; fully-qualified # 🇩🇪 E0.6 flag: Germany
+1F1E9 1F1EC ; fully-qualified # 🇩🇬 E2.0 flag: Diego Garcia
+1F1E9 1F1EF ; fully-qualified # 🇩🇯 E2.0 flag: Djibouti
+1F1E9 1F1F0 ; fully-qualified # 🇩🇰 E2.0 flag: Denmark
+1F1E9 1F1F2 ; fully-qualified # 🇩🇲 E2.0 flag: Dominica
+1F1E9 1F1F4 ; fully-qualified # 🇩🇴 E2.0 flag: Dominican Republic
+1F1E9 1F1FF ; fully-qualified # 🇩🇿 E2.0 flag: Algeria
+1F1EA 1F1E6 ; fully-qualified # 🇪🇦 E2.0 flag: Ceuta & Melilla
+1F1EA 1F1E8 ; fully-qualified # 🇪🇨 E2.0 flag: Ecuador
+1F1EA 1F1EA ; fully-qualified # 🇪🇪 E2.0 flag: Estonia
+1F1EA 1F1EC ; fully-qualified # 🇪🇬 E2.0 flag: Egypt
+1F1EA 1F1ED ; fully-qualified # 🇪🇭 E2.0 flag: Western Sahara
+1F1EA 1F1F7 ; fully-qualified # 🇪🇷 E2.0 flag: Eritrea
+1F1EA 1F1F8 ; fully-qualified # 🇪🇸 E0.6 flag: Spain
+1F1EA 1F1F9 ; fully-qualified # 🇪🇹 E2.0 flag: Ethiopia
+1F1EA 1F1FA ; fully-qualified # 🇪🇺 E2.0 flag: European Union
+1F1EB 1F1EE ; fully-qualified # 🇫🇮 E2.0 flag: Finland
+1F1EB 1F1EF ; fully-qualified # 🇫🇯 E2.0 flag: Fiji
+1F1EB 1F1F0 ; fully-qualified # 🇫🇰 E2.0 flag: Falkland Islands
+1F1EB 1F1F2 ; fully-qualified # 🇫🇲 E2.0 flag: Micronesia
+1F1EB 1F1F4 ; fully-qualified # 🇫🇴 E2.0 flag: Faroe Islands
+1F1EB 1F1F7 ; fully-qualified # 🇫🇷 E0.6 flag: France
+1F1EC 1F1E6 ; fully-qualified # 🇬🇦 E2.0 flag: Gabon
+1F1EC 1F1E7 ; fully-qualified # 🇬🇧 E0.6 flag: United Kingdom
+1F1EC 1F1E9 ; fully-qualified # 🇬🇩 E2.0 flag: Grenada
+1F1EC 1F1EA ; fully-qualified # 🇬🇪 E2.0 flag: Georgia
+1F1EC 1F1EB ; fully-qualified # 🇬🇫 E2.0 flag: French Guiana
+1F1EC 1F1EC ; fully-qualified # 🇬🇬 E2.0 flag: Guernsey
+1F1EC 1F1ED ; fully-qualified # 🇬🇭 E2.0 flag: Ghana
+1F1EC 1F1EE ; fully-qualified # 🇬🇮 E2.0 flag: Gibraltar
+1F1EC 1F1F1 ; fully-qualified # 🇬🇱 E2.0 flag: Greenland
+1F1EC 1F1F2 ; fully-qualified # 🇬🇲 E2.0 flag: Gambia
+1F1EC 1F1F3 ; fully-qualified # 🇬🇳 E2.0 flag: Guinea
+1F1EC 1F1F5 ; fully-qualified # 🇬🇵 E2.0 flag: Guadeloupe
+1F1EC 1F1F6 ; fully-qualified # 🇬🇶 E2.0 flag: Equatorial Guinea
+1F1EC 1F1F7 ; fully-qualified # 🇬🇷 E2.0 flag: Greece
+1F1EC 1F1F8 ; fully-qualified # 🇬🇸 E2.0 flag: South Georgia & South Sandwich Islands
+1F1EC 1F1F9 ; fully-qualified # 🇬🇹 E2.0 flag: Guatemala
+1F1EC 1F1FA ; fully-qualified # 🇬🇺 E2.0 flag: Guam
+1F1EC 1F1FC ; fully-qualified # 🇬🇼 E2.0 flag: Guinea-Bissau
+1F1EC 1F1FE ; fully-qualified # 🇬🇾 E2.0 flag: Guyana
+1F1ED 1F1F0 ; fully-qualified # 🇭🇰 E2.0 flag: Hong Kong SAR China
+1F1ED 1F1F2 ; fully-qualified # 🇭🇲 E2.0 flag: Heard & McDonald Islands
+1F1ED 1F1F3 ; fully-qualified # 🇭🇳 E2.0 flag: Honduras
+1F1ED 1F1F7 ; fully-qualified # 🇭🇷 E2.0 flag: Croatia
+1F1ED 1F1F9 ; fully-qualified # 🇭🇹 E2.0 flag: Haiti
+1F1ED 1F1FA ; fully-qualified # 🇭🇺 E2.0 flag: Hungary
+1F1EE 1F1E8 ; fully-qualified # 🇮🇨 E2.0 flag: Canary Islands
+1F1EE 1F1E9 ; fully-qualified # 🇮🇩 E2.0 flag: Indonesia
+1F1EE 1F1EA ; fully-qualified # 🇮🇪 E2.0 flag: Ireland
+1F1EE 1F1F1 ; fully-qualified # 🇮🇱 E2.0 flag: Israel
+1F1EE 1F1F2 ; fully-qualified # 🇮🇲 E2.0 flag: Isle of Man
+1F1EE 1F1F3 ; fully-qualified # 🇮🇳 E2.0 flag: India
+1F1EE 1F1F4 ; fully-qualified # 🇮🇴 E2.0 flag: British Indian Ocean Territory
+1F1EE 1F1F6 ; fully-qualified # 🇮🇶 E2.0 flag: Iraq
+1F1EE 1F1F7 ; fully-qualified # 🇮🇷 E2.0 flag: Iran
+1F1EE 1F1F8 ; fully-qualified # 🇮🇸 E2.0 flag: Iceland
+1F1EE 1F1F9 ; fully-qualified # 🇮🇹 E0.6 flag: Italy
+1F1EF 1F1EA ; fully-qualified # 🇯🇪 E2.0 flag: Jersey
+1F1EF 1F1F2 ; fully-qualified # 🇯🇲 E2.0 flag: Jamaica
+1F1EF 1F1F4 ; fully-qualified # 🇯🇴 E2.0 flag: Jordan
+1F1EF 1F1F5 ; fully-qualified # 🇯🇵 E0.6 flag: Japan
+1F1F0 1F1EA ; fully-qualified # 🇰🇪 E2.0 flag: Kenya
+1F1F0 1F1EC ; fully-qualified # 🇰🇬 E2.0 flag: Kyrgyzstan
+1F1F0 1F1ED ; fully-qualified # 🇰🇭 E2.0 flag: Cambodia
+1F1F0 1F1EE ; fully-qualified # 🇰🇮 E2.0 flag: Kiribati
+1F1F0 1F1F2 ; fully-qualified # 🇰🇲 E2.0 flag: Comoros
+1F1F0 1F1F3 ; fully-qualified # 🇰🇳 E2.0 flag: St. Kitts & Nevis
+1F1F0 1F1F5 ; fully-qualified # 🇰🇵 E2.0 flag: North Korea
+1F1F0 1F1F7 ; fully-qualified # 🇰🇷 E0.6 flag: South Korea
+1F1F0 1F1FC ; fully-qualified # 🇰🇼 E2.0 flag: Kuwait
+1F1F0 1F1FE ; fully-qualified # 🇰🇾 E2.0 flag: Cayman Islands
+1F1F0 1F1FF ; fully-qualified # 🇰🇿 E2.0 flag: Kazakhstan
+1F1F1 1F1E6 ; fully-qualified # 🇱🇦 E2.0 flag: Laos
+1F1F1 1F1E7 ; fully-qualified # 🇱🇧 E2.0 flag: Lebanon
+1F1F1 1F1E8 ; fully-qualified # 🇱🇨 E2.0 flag: St. Lucia
+1F1F1 1F1EE ; fully-qualified # 🇱🇮 E2.0 flag: Liechtenstein
+1F1F1 1F1F0 ; fully-qualified # 🇱🇰 E2.0 flag: Sri Lanka
+1F1F1 1F1F7 ; fully-qualified # 🇱🇷 E2.0 flag: Liberia
+1F1F1 1F1F8 ; fully-qualified # 🇱🇸 E2.0 flag: Lesotho
+1F1F1 1F1F9 ; fully-qualified # 🇱🇹 E2.0 flag: Lithuania
+1F1F1 1F1FA ; fully-qualified # 🇱🇺 E2.0 flag: Luxembourg
+1F1F1 1F1FB ; fully-qualified # 🇱🇻 E2.0 flag: Latvia
+1F1F1 1F1FE ; fully-qualified # 🇱🇾 E2.0 flag: Libya
+1F1F2 1F1E6 ; fully-qualified # 🇲🇦 E2.0 flag: Morocco
+1F1F2 1F1E8 ; fully-qualified # 🇲🇨 E2.0 flag: Monaco
+1F1F2 1F1E9 ; fully-qualified # 🇲🇩 E2.0 flag: Moldova
+1F1F2 1F1EA ; fully-qualified # 🇲🇪 E2.0 flag: Montenegro
+1F1F2 1F1EB ; fully-qualified # 🇲🇫 E2.0 flag: St. Martin
+1F1F2 1F1EC ; fully-qualified # 🇲🇬 E2.0 flag: Madagascar
+1F1F2 1F1ED ; fully-qualified # 🇲🇭 E2.0 flag: Marshall Islands
+1F1F2 1F1F0 ; fully-qualified # 🇲🇰 E2.0 flag: North Macedonia
+1F1F2 1F1F1 ; fully-qualified # 🇲🇱 E2.0 flag: Mali
+1F1F2 1F1F2 ; fully-qualified # 🇲🇲 E2.0 flag: Myanmar (Burma)
+1F1F2 1F1F3 ; fully-qualified # 🇲🇳 E2.0 flag: Mongolia
+1F1F2 1F1F4 ; fully-qualified # 🇲🇴 E2.0 flag: Macao SAR China
+1F1F2 1F1F5 ; fully-qualified # 🇲🇵 E2.0 flag: Northern Mariana Islands
+1F1F2 1F1F6 ; fully-qualified # 🇲🇶 E2.0 flag: Martinique
+1F1F2 1F1F7 ; fully-qualified # 🇲🇷 E2.0 flag: Mauritania
+1F1F2 1F1F8 ; fully-qualified # 🇲🇸 E2.0 flag: Montserrat
+1F1F2 1F1F9 ; fully-qualified # 🇲🇹 E2.0 flag: Malta
+1F1F2 1F1FA ; fully-qualified # 🇲🇺 E2.0 flag: Mauritius
+1F1F2 1F1FB ; fully-qualified # 🇲🇻 E2.0 flag: Maldives
+1F1F2 1F1FC ; fully-qualified # 🇲🇼 E2.0 flag: Malawi
+1F1F2 1F1FD ; fully-qualified # 🇲🇽 E2.0 flag: Mexico
+1F1F2 1F1FE ; fully-qualified # 🇲🇾 E2.0 flag: Malaysia
+1F1F2 1F1FF ; fully-qualified # 🇲🇿 E2.0 flag: Mozambique
+1F1F3 1F1E6 ; fully-qualified # 🇳🇦 E2.0 flag: Namibia
+1F1F3 1F1E8 ; fully-qualified # 🇳🇨 E2.0 flag: New Caledonia
+1F1F3 1F1EA ; fully-qualified # 🇳🇪 E2.0 flag: Niger
+1F1F3 1F1EB ; fully-qualified # 🇳🇫 E2.0 flag: Norfolk Island
+1F1F3 1F1EC ; fully-qualified # 🇳🇬 E2.0 flag: Nigeria
+1F1F3 1F1EE ; fully-qualified # 🇳🇮 E2.0 flag: Nicaragua
+1F1F3 1F1F1 ; fully-qualified # 🇳🇱 E2.0 flag: Netherlands
+1F1F3 1F1F4 ; fully-qualified # 🇳🇴 E2.0 flag: Norway
+1F1F3 1F1F5 ; fully-qualified # 🇳🇵 E2.0 flag: Nepal
+1F1F3 1F1F7 ; fully-qualified # 🇳🇷 E2.0 flag: Nauru
+1F1F3 1F1FA ; fully-qualified # 🇳🇺 E2.0 flag: Niue
+1F1F3 1F1FF ; fully-qualified # 🇳🇿 E2.0 flag: New Zealand
+1F1F4 1F1F2 ; fully-qualified # 🇴🇲 E2.0 flag: Oman
+1F1F5 1F1E6 ; fully-qualified # 🇵🇦 E2.0 flag: Panama
+1F1F5 1F1EA ; fully-qualified # 🇵🇪 E2.0 flag: Peru
+1F1F5 1F1EB ; fully-qualified # 🇵🇫 E2.0 flag: French Polynesia
+1F1F5 1F1EC ; fully-qualified # 🇵🇬 E2.0 flag: Papua New Guinea
+1F1F5 1F1ED ; fully-qualified # 🇵🇭 E2.0 flag: Philippines
+1F1F5 1F1F0 ; fully-qualified # 🇵🇰 E2.0 flag: Pakistan
+1F1F5 1F1F1 ; fully-qualified # 🇵🇱 E2.0 flag: Poland
+1F1F5 1F1F2 ; fully-qualified # 🇵🇲 E2.0 flag: St. Pierre & Miquelon
+1F1F5 1F1F3 ; fully-qualified # 🇵🇳 E2.0 flag: Pitcairn Islands
+1F1F5 1F1F7 ; fully-qualified # 🇵🇷 E2.0 flag: Puerto Rico
+1F1F5 1F1F8 ; fully-qualified # 🇵🇸 E2.0 flag: Palestinian Territories
+1F1F5 1F1F9 ; fully-qualified # 🇵🇹 E2.0 flag: Portugal
+1F1F5 1F1FC ; fully-qualified # 🇵🇼 E2.0 flag: Palau
+1F1F5 1F1FE ; fully-qualified # 🇵🇾 E2.0 flag: Paraguay
+1F1F6 1F1E6 ; fully-qualified # 🇶🇦 E2.0 flag: Qatar
+1F1F7 1F1EA ; fully-qualified # 🇷🇪 E2.0 flag: Réunion
+1F1F7 1F1F4 ; fully-qualified # 🇷🇴 E2.0 flag: Romania
+1F1F7 1F1F8 ; fully-qualified # 🇷🇸 E2.0 flag: Serbia
+1F1F7 1F1FA ; fully-qualified # 🇷🇺 E0.6 flag: Russia
+1F1F7 1F1FC ; fully-qualified # 🇷🇼 E2.0 flag: Rwanda
+1F1F8 1F1E6 ; fully-qualified # 🇸🇦 E2.0 flag: Saudi Arabia
+1F1F8 1F1E7 ; fully-qualified # 🇸🇧 E2.0 flag: Solomon Islands
+1F1F8 1F1E8 ; fully-qualified # 🇸🇨 E2.0 flag: Seychelles
+1F1F8 1F1E9 ; fully-qualified # 🇸🇩 E2.0 flag: Sudan
+1F1F8 1F1EA ; fully-qualified # 🇸🇪 E2.0 flag: Sweden
+1F1F8 1F1EC ; fully-qualified # 🇸🇬 E2.0 flag: Singapore
+1F1F8 1F1ED ; fully-qualified # 🇸🇭 E2.0 flag: St. Helena
+1F1F8 1F1EE ; fully-qualified # 🇸🇮 E2.0 flag: Slovenia
+1F1F8 1F1EF ; fully-qualified # 🇸🇯 E2.0 flag: Svalbard & Jan Mayen
+1F1F8 1F1F0 ; fully-qualified # 🇸🇰 E2.0 flag: Slovakia
+1F1F8 1F1F1 ; fully-qualified # 🇸🇱 E2.0 flag: Sierra Leone
+1F1F8 1F1F2 ; fully-qualified # 🇸🇲 E2.0 flag: San Marino
+1F1F8 1F1F3 ; fully-qualified # 🇸🇳 E2.0 flag: Senegal
+1F1F8 1F1F4 ; fully-qualified # 🇸🇴 E2.0 flag: Somalia
+1F1F8 1F1F7 ; fully-qualified # 🇸🇷 E2.0 flag: Suriname
+1F1F8 1F1F8 ; fully-qualified # 🇸🇸 E2.0 flag: South Sudan
+1F1F8 1F1F9 ; fully-qualified # 🇸🇹 E2.0 flag: São Tomé & Príncipe
+1F1F8 1F1FB ; fully-qualified # 🇸🇻 E2.0 flag: El Salvador
+1F1F8 1F1FD ; fully-qualified # 🇸🇽 E2.0 flag: Sint Maarten
+1F1F8 1F1FE ; fully-qualified # 🇸🇾 E2.0 flag: Syria
+1F1F8 1F1FF ; fully-qualified # 🇸🇿 E2.0 flag: Eswatini
+1F1F9 1F1E6 ; fully-qualified # 🇹🇦 E2.0 flag: Tristan da Cunha
+1F1F9 1F1E8 ; fully-qualified # 🇹🇨 E2.0 flag: Turks & Caicos Islands
+1F1F9 1F1E9 ; fully-qualified # 🇹🇩 E2.0 flag: Chad
+1F1F9 1F1EB ; fully-qualified # 🇹🇫 E2.0 flag: French Southern Territories
+1F1F9 1F1EC ; fully-qualified # 🇹🇬 E2.0 flag: Togo
+1F1F9 1F1ED ; fully-qualified # 🇹🇭 E2.0 flag: Thailand
+1F1F9 1F1EF ; fully-qualified # 🇹🇯 E2.0 flag: Tajikistan
+1F1F9 1F1F0 ; fully-qualified # 🇹🇰 E2.0 flag: Tokelau
+1F1F9 1F1F1 ; fully-qualified # 🇹🇱 E2.0 flag: Timor-Leste
+1F1F9 1F1F2 ; fully-qualified # 🇹🇲 E2.0 flag: Turkmenistan
+1F1F9 1F1F3 ; fully-qualified # 🇹🇳 E2.0 flag: Tunisia
+1F1F9 1F1F4 ; fully-qualified # 🇹🇴 E2.0 flag: Tonga
+1F1F9 1F1F7 ; fully-qualified # 🇹🇷 E2.0 flag: Turkey
+1F1F9 1F1F9 ; fully-qualified # 🇹🇹 E2.0 flag: Trinidad & Tobago
+1F1F9 1F1FB ; fully-qualified # 🇹🇻 E2.0 flag: Tuvalu
+1F1F9 1F1FC ; fully-qualified # 🇹🇼 E2.0 flag: Taiwan
+1F1F9 1F1FF ; fully-qualified # 🇹🇿 E2.0 flag: Tanzania
+1F1FA 1F1E6 ; fully-qualified # 🇺🇦 E2.0 flag: Ukraine
+1F1FA 1F1EC ; fully-qualified # 🇺🇬 E2.0 flag: Uganda
+1F1FA 1F1F2 ; fully-qualified # 🇺🇲 E2.0 flag: U.S. Outlying Islands
+1F1FA 1F1F3 ; fully-qualified # 🇺🇳 E4.0 flag: United Nations
+1F1FA 1F1F8 ; fully-qualified # 🇺🇸 E0.6 flag: United States
+1F1FA 1F1FE ; fully-qualified # 🇺🇾 E2.0 flag: Uruguay
+1F1FA 1F1FF ; fully-qualified # 🇺🇿 E2.0 flag: Uzbekistan
+1F1FB 1F1E6 ; fully-qualified # 🇻🇦 E2.0 flag: Vatican City
+1F1FB 1F1E8 ; fully-qualified # 🇻🇨 E2.0 flag: St. Vincent & Grenadines
+1F1FB 1F1EA ; fully-qualified # 🇻🇪 E2.0 flag: Venezuela
+1F1FB 1F1EC ; fully-qualified # 🇻🇬 E2.0 flag: British Virgin Islands
+1F1FB 1F1EE ; fully-qualified # 🇻🇮 E2.0 flag: U.S. Virgin Islands
+1F1FB 1F1F3 ; fully-qualified # 🇻🇳 E2.0 flag: Vietnam
+1F1FB 1F1FA ; fully-qualified # 🇻🇺 E2.0 flag: Vanuatu
+1F1FC 1F1EB ; fully-qualified # 🇼🇫 E2.0 flag: Wallis & Futuna
+1F1FC 1F1F8 ; fully-qualified # 🇼🇸 E2.0 flag: Samoa
+1F1FD 1F1F0 ; fully-qualified # 🇽🇰 E2.0 flag: Kosovo
+1F1FE 1F1EA ; fully-qualified # 🇾🇪 E2.0 flag: Yemen
+1F1FE 1F1F9 ; fully-qualified # 🇾🇹 E2.0 flag: Mayotte
+1F1FF 1F1E6 ; fully-qualified # 🇿🇦 E2.0 flag: South Africa
+1F1FF 1F1F2 ; fully-qualified # 🇿🇲 E2.0 flag: Zambia
+1F1FF 1F1FC ; fully-qualified # 🇿🇼 E2.0 flag: Zimbabwe
+
+# subgroup: subdivision-flag
+1F3F4 E0067 E0062 E0065 E006E E0067 E007F ; fully-qualified # 🏴󠁧󠁢󠁥󠁮󠁧󠁿 E5.0 flag: England
+1F3F4 E0067 E0062 E0073 E0063 E0074 E007F ; fully-qualified # 🏴󠁧󠁢󠁳󠁣󠁴󠁿 E5.0 flag: Scotland
+1F3F4 E0067 E0062 E0077 E006C E0073 E007F ; fully-qualified # 🏴󠁧󠁢󠁷󠁬󠁳󠁿 E5.0 flag: Wales
+
+# Flags subtotal: 275
+# Flags subtotal: 275 w/o modifiers
+
+# Status Counts
+# fully-qualified : 3624
+# minimally-qualified : 817
+# unqualified : 252
+# component : 9
+
+#EOF
diff --git a/admin/unidata/emoji-zwj-sequences.txt b/admin/unidata/emoji-zwj-sequences.txt
new file mode 100644
index 00000000000..6f94721a73a
--- /dev/null
+++ b/admin/unidata/emoji-zwj-sequences.txt
@@ -0,0 +1,1410 @@
+# emoji-zwj-sequences.txt
+# Date: 2021-06-08, 05:19:16 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
+#
+# Emoji ZWJ Sequences for UTS #51
+# Version: 14.0
+#
+# For documentation and usage, see http://www.unicode.org/reports/tr51
+#
+# Format:
+# code_point(s) ; type_field ; description # comments
+# Fields:
+# code_point(s): one or more code points in hex format, separated by spaces
+# type_field :RGI_Emoji_ZWJ_Sequence
+# The type_field is a convenience for parsing the emoji sequence files, and is not intended to be maintained as a property.
+# short name: CLDR short name of sequence; characters may be escaped with \x{hex}.
+#
+# For the purpose of regular expressions, the above type field defines the name of
+# a binary property of strings. The short name of the property is the same as the long name.
+#
+# Characters and sequences are listed in code point order. Users should be shown a more natural order.
+# See the CLDR collation order for Emoji.
+
+# ================================================
+
+# RGI_Emoji_ZWJ_Sequence: Family
+
+1F468 200D 2764 FE0F 200D 1F468 ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man # E2.0 [1] (👨‍❤️‍👨)
+1F468 200D 2764 FE0F 200D 1F48B 200D 1F468 ; RGI_Emoji_ZWJ_Sequence ; kiss: man, man # E2.0 [1] (👨‍❤️‍💋‍👨)
+1F468 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, boy # E4.0 [1] (👨‍👦)
+1F468 200D 1F466 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, boy, boy # E4.0 [1] (👨‍👦‍👦)
+1F468 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: man, girl # E4.0 [1] (👨‍👧)
+1F468 200D 1F467 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, girl, boy # E4.0 [1] (👨‍👧‍👦)
+1F468 200D 1F467 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: man, girl, girl # E4.0 [1] (👨‍👧‍👧)
+1F468 200D 1F468 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, man, boy # E2.0 [1] (👨‍👨‍👦)
+1F468 200D 1F468 200D 1F466 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, man, boy, boy # E2.0 [1] (👨‍👨‍👦‍👦)
+1F468 200D 1F468 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: man, man, girl # E2.0 [1] (👨‍👨‍👧)
+1F468 200D 1F468 200D 1F467 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, man, girl, boy # E2.0 [1] (👨‍👨‍👧‍👦)
+1F468 200D 1F468 200D 1F467 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: man, man, girl, girl # E2.0 [1] (👨‍👨‍👧‍👧)
+1F468 200D 1F469 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, woman, boy # E2.0 [1] (👨‍👩‍👦)
+1F468 200D 1F469 200D 1F466 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, woman, boy, boy # E2.0 [1] (👨‍👩‍👦‍👦)
+1F468 200D 1F469 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: man, woman, girl # E2.0 [1] (👨‍👩‍👧)
+1F468 200D 1F469 200D 1F467 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: man, woman, girl, boy # E2.0 [1] (👨‍👩‍👧‍👦)
+1F468 200D 1F469 200D 1F467 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: man, woman, girl, girl # E2.0 [1] (👨‍👩‍👧‍👧)
+1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, light skin tone # E13.1 [1] (👨🏻‍❤️‍👨🏻)
+1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, light skin tone, medium-light skin tone #E13.1[1] (👨🏻‍❤️‍👨🏼)
+1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, light skin tone, medium skin tone # E13.1 [1] (👨🏻‍❤️‍👨🏽)
+1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, light skin tone, medium-dark skin tone #E13.1[1] (👨🏻‍❤️‍👨🏾)
+1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, light skin tone, dark skin tone # E13.1 [1] (👨🏻‍❤️‍👨🏿)
+1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: man, man, light skin tone # E13.1 [1] (👨🏻‍❤️‍💋‍👨🏻)
+1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: man, man, light skin tone, medium-light skin tone #E13.1 [1] (👨🏻‍❤️‍💋‍👨🏼)
+1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: man, man, light skin tone, medium skin tone # E13.1 [1] (👨🏻‍❤️‍💋‍👨🏽)
+1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: man, man, light skin tone, medium-dark skin tone # E13.1 [1] (👨🏻‍❤️‍💋‍👨🏾)
+1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: man, man, light skin tone, dark skin tone # E13.1 [1] (👨🏻‍❤️‍💋‍👨🏿)
+1F468 1F3FB 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; men holding hands: light skin tone, medium-light skin tone # E12.1 [1] (👨🏻‍🤝‍👨🏼)
+1F468 1F3FB 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; men holding hands: light skin tone, medium skin tone # E12.1 [1] (👨🏻‍🤝‍👨🏽)
+1F468 1F3FB 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; men holding hands: light skin tone, medium-dark skin tone # E12.1 [1] (👨🏻‍🤝‍👨🏾)
+1F468 1F3FB 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; men holding hands: light skin tone, dark skin tone # E12.1 [1] (👨🏻‍🤝‍👨🏿)
+1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-light skin tone, light skin tone #E13.1[1] (👨🏼‍❤️‍👨🏻)
+1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-light skin tone # E13.1 [1] (👨🏼‍❤️‍👨🏼)
+1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-light skin tone, medium skin tone #E13.1[1] (👨🏼‍❤️‍👨🏽)
+1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-light skin tone, medium-dark skin tone #E13.1[1] (👨🏼‍❤️‍👨🏾)
+1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-light skin tone, dark skin tone #E13.1[1] (👨🏼‍❤️‍👨🏿)
+1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-light skin tone, light skin tone #E13.1 [1] (👨🏼‍❤️‍💋‍👨🏻)
+1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-light skin tone # E13.1 [1] (👨🏼‍❤️‍💋‍👨🏼)
+1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-light skin tone, medium skin tone #E13.1 [1] (👨🏼‍❤️‍💋‍👨🏽)
+1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-light skin tone, medium-dark skin tone #E13.1[1] (👨🏼‍❤️‍💋‍👨🏾)
+1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-light skin tone, dark skin tone # E13.1 [1] (👨🏼‍❤️‍💋‍👨🏿)
+1F468 1F3FC 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-light skin tone, light skin tone # E12.0 [1] (👨🏼‍🤝‍👨🏻)
+1F468 1F3FC 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-light skin tone, medium skin tone # E12.1 [1] (👨🏼‍🤝‍👨🏽)
+1F468 1F3FC 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-light skin tone, medium-dark skin tone #E12.1 [1] (👨🏼‍🤝‍👨🏾)
+1F468 1F3FC 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-light skin tone, dark skin tone # E12.1 [1] (👨🏼‍🤝‍👨🏿)
+1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium skin tone, light skin tone # E13.1 [1] (👨🏽‍❤️‍👨🏻)
+1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium skin tone, medium-light skin tone #E13.1[1] (👨🏽‍❤️‍👨🏼)
+1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium skin tone # E13.1 [1] (👨🏽‍❤️‍👨🏽)
+1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium skin tone, medium-dark skin tone #E13.1[1] (👨🏽‍❤️‍👨🏾)
+1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium skin tone, dark skin tone # E13.1 [1] (👨🏽‍❤️‍👨🏿)
+1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium skin tone, light skin tone # E13.1 [1] (👨🏽‍❤️‍💋‍👨🏻)
+1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium skin tone, medium-light skin tone #E13.1 [1] (👨🏽‍❤️‍💋‍👨🏼)
+1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium skin tone # E13.1 [1] (👨🏽‍❤️‍💋‍👨🏽)
+1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium skin tone, medium-dark skin tone #E13.1 [1] (👨🏽‍❤️‍💋‍👨🏾)
+1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium skin tone, dark skin tone # E13.1 [1] (👨🏽‍❤️‍💋‍👨🏿)
+1F468 1F3FD 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium skin tone, light skin tone # E12.0 [1] (👨🏽‍🤝‍👨🏻)
+1F468 1F3FD 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium skin tone, medium-light skin tone # E12.0 [1] (👨🏽‍🤝‍👨🏼)
+1F468 1F3FD 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium skin tone, medium-dark skin tone # E12.1 [1] (👨🏽‍🤝‍👨🏾)
+1F468 1F3FD 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium skin tone, dark skin tone # E12.1 [1] (👨🏽‍🤝‍👨🏿)
+1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-dark skin tone, light skin tone #E13.1[1] (👨🏾‍❤️‍👨🏻)
+1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-dark skin tone, medium-light skin tone #E13.1[1] (👨🏾‍❤️‍👨🏼)
+1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-dark skin tone, medium skin tone #E13.1[1] (👨🏾‍❤️‍👨🏽)
+1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-dark skin tone # E13.1 [1] (👨🏾‍❤️‍👨🏾)
+1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, medium-dark skin tone, dark skin tone #E13.1[1] (👨🏾‍❤️‍👨🏿)
+1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-dark skin tone, light skin tone # E13.1 [1] (👨🏾‍❤️‍💋‍👨🏻)
+1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-dark skin tone, medium-light skin tone #E13.1[1] (👨🏾‍❤️‍💋‍👨🏼)
+1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-dark skin tone, medium skin tone #E13.1 [1] (👨🏾‍❤️‍💋‍👨🏽)
+1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-dark skin tone # E13.1 [1] (👨🏾‍❤️‍💋‍👨🏾)
+1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: man, man, medium-dark skin tone, dark skin tone # E13.1 [1] (👨🏾‍❤️‍💋‍👨🏿)
+1F468 1F3FE 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-dark skin tone, light skin tone # E12.0 [1] (👨🏾‍🤝‍👨🏻)
+1F468 1F3FE 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-dark skin tone, medium-light skin tone #E12.0 [1] (👨🏾‍🤝‍👨🏼)
+1F468 1F3FE 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-dark skin tone, medium skin tone # E12.0 [1] (👨🏾‍🤝‍👨🏽)
+1F468 1F3FE 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; men holding hands: medium-dark skin tone, dark skin tone # E12.1 [1] (👨🏾‍🤝‍👨🏿)
+1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, dark skin tone, light skin tone # E13.1 [1] (👨🏿‍❤️‍👨🏻)
+1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, dark skin tone, medium-light skin tone #E13.1[1] (👨🏿‍❤️‍👨🏼)
+1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, dark skin tone, medium skin tone # E13.1 [1] (👨🏿‍❤️‍👨🏽)
+1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, dark skin tone, medium-dark skin tone #E13.1[1] (👨🏿‍❤️‍👨🏾)
+1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: man, man, dark skin tone # E13.1 [1] (👨🏿‍❤️‍👨🏿)
+1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: man, man, dark skin tone, light skin tone # E13.1 [1] (👨🏿‍❤️‍💋‍👨🏻)
+1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: man, man, dark skin tone, medium-light skin tone # E13.1 [1] (👨🏿‍❤️‍💋‍👨🏼)
+1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: man, man, dark skin tone, medium skin tone # E13.1 [1] (👨🏿‍❤️‍💋‍👨🏽)
+1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: man, man, dark skin tone, medium-dark skin tone # E13.1 [1] (👨🏿‍❤️‍💋‍👨🏾)
+1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: man, man, dark skin tone # E13.1 [1] (👨🏿‍❤️‍💋‍👨🏿)
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; men holding hands: dark skin tone, light skin tone # E12.0 [1] (👨🏿‍🤝‍👨🏻)
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; men holding hands: dark skin tone, medium-light skin tone # E12.0 [1] (👨🏿‍🤝‍👨🏼)
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; men holding hands: dark skin tone, medium skin tone # E12.0 [1] (👨🏿‍🤝‍👨🏽)
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; men holding hands: dark skin tone, medium-dark skin tone # E12.0 [1] (👨🏿‍🤝‍👨🏾)
+1F469 200D 2764 FE0F 200D 1F468 ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man # E2.0 [1] (👩‍❤️‍👨)
+1F469 200D 2764 FE0F 200D 1F469 ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman # E2.0 [1] (👩‍❤️‍👩)
+1F469 200D 2764 FE0F 200D 1F48B 200D 1F468 ; RGI_Emoji_ZWJ_Sequence ; kiss: woman, man # E2.0 [1] (👩‍❤️‍💋‍👨)
+1F469 200D 2764 FE0F 200D 1F48B 200D 1F469 ; RGI_Emoji_ZWJ_Sequence ; kiss: woman, woman # E2.0 [1] (👩‍❤️‍💋‍👩)
+1F469 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: woman, boy # E4.0 [1] (👩‍👦)
+1F469 200D 1F466 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: woman, boy, boy # E4.0 [1] (👩‍👦‍👦)
+1F469 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: woman, girl # E4.0 [1] (👩‍👧)
+1F469 200D 1F467 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: woman, girl, boy # E4.0 [1] (👩‍👧‍👦)
+1F469 200D 1F467 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: woman, girl, girl # E4.0 [1] (👩‍👧‍👧)
+1F469 200D 1F469 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: woman, woman, boy # E2.0 [1] (👩‍👩‍👦)
+1F469 200D 1F469 200D 1F466 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: woman, woman, boy, boy # E2.0 [1] (👩‍👩‍👦‍👦)
+1F469 200D 1F469 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: woman, woman, girl # E2.0 [1] (👩‍👩‍👧)
+1F469 200D 1F469 200D 1F467 200D 1F466 ; RGI_Emoji_ZWJ_Sequence ; family: woman, woman, girl, boy # E2.0 [1] (👩‍👩‍👧‍👦)
+1F469 200D 1F469 200D 1F467 200D 1F467 ; RGI_Emoji_ZWJ_Sequence ; family: woman, woman, girl, girl # E2.0 [1] (👩‍👩‍👧‍👧)
+1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, light skin tone # E13.1 [1] (👩🏻‍❤️‍👨🏻)
+1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, light skin tone, medium-light skin tone #E13.1[1] (👩🏻‍❤️‍👨🏼)
+1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, light skin tone, medium skin tone #E13.1 [1] (👩🏻‍❤️‍👨🏽)
+1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, light skin tone, medium-dark skin tone #E13.1[1] (👩🏻‍❤️‍👨🏾)
+1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, light skin tone, dark skin tone # E13.1 [1] (👩🏻‍❤️‍👨🏿)
+1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, light skin tone # E13.1 [1] (👩🏻‍❤️‍👩🏻)
+1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, light skin tone, medium-light skin tone #E13.1[1] (👩🏻‍❤️‍👩🏼)
+1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, light skin tone, medium skin tone #E13.1[1] (👩🏻‍❤️‍👩🏽)
+1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, light skin tone, medium-dark skin tone #E13.1[1] (👩🏻‍❤️‍👩🏾)
+1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, light skin tone, dark skin tone #E13.1 [1] (👩🏻‍❤️‍👩🏿)
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, light skin tone # E13.1 [1] (👩🏻‍❤️‍💋‍👨🏻)
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, light skin tone, medium-light skin tone #E13.1[1] (👩🏻‍❤️‍💋‍👨🏼)
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, light skin tone, medium skin tone # E13.1 [1] (👩🏻‍❤️‍💋‍👨🏽)
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, light skin tone, medium-dark skin tone #E13.1 [1] (👩🏻‍❤️‍💋‍👨🏾)
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, light skin tone, dark skin tone # E13.1 [1] (👩🏻‍❤️‍💋‍👨🏿)
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, light skin tone # E13.1 [1] (👩🏻‍❤️‍💋‍👩🏻)
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, light skin tone, medium-light skin tone #E13.1[1] (👩🏻‍❤️‍💋‍👩🏼)
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, light skin tone, medium skin tone # E13.1 [1] (👩🏻‍❤️‍💋‍👩🏽)
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, light skin tone, medium-dark skin tone #E13.1[1] (👩🏻‍❤️‍💋‍👩🏾)
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, light skin tone, dark skin tone # E13.1 [1] (👩🏻‍❤️‍💋‍👩🏿)
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: light skin tone, medium-light skin tone #E12.0[1] (👩🏻‍🤝‍👨🏼)
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: light skin tone, medium skin tone # E12.0 [1] (👩🏻‍🤝‍👨🏽)
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: light skin tone, medium-dark skin tone #E12.0[1] (👩🏻‍🤝‍👨🏾)
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: light skin tone, dark skin tone # E12.0 [1] (👩🏻‍🤝‍👨🏿)
+1F469 1F3FB 200D 1F91D 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; women holding hands: light skin tone, medium-light skin tone # E12.1 [1] (👩🏻‍🤝‍👩🏼)
+1F469 1F3FB 200D 1F91D 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; women holding hands: light skin tone, medium skin tone # E12.1 [1] (👩🏻‍🤝‍👩🏽)
+1F469 1F3FB 200D 1F91D 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; women holding hands: light skin tone, medium-dark skin tone # E12.1 [1] (👩🏻‍🤝‍👩🏾)
+1F469 1F3FB 200D 1F91D 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; women holding hands: light skin tone, dark skin tone # E12.1 [1] (👩🏻‍🤝‍👩🏿)
+1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-light skin tone, light skin tone #E13.1[1] (👩🏼‍❤️‍👨🏻)
+1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-light skin tone # E13.1 [1] (👩🏼‍❤️‍👨🏼)
+1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-light skin tone, medium skin tone #E13.1[1] (👩🏼‍❤️‍👨🏽)
+1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-light skin tone, medium-dark skin tone #E13.1[1] (👩🏼‍❤️‍👨🏾)
+1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-light skin tone, dark skin tone #E13.1[1] (👩🏼‍❤️‍👨🏿)
+1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-light skin tone, light skin tone #E13.1[1] (👩🏼‍❤️‍👩🏻)
+1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-light skin tone # E13.1 [1] (👩🏼‍❤️‍👩🏼)
+1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-light skin tone, medium skin tone #E13.1[1] (👩🏼‍❤️‍👩🏽)
+1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-light skin tone, medium-dark skin tone #E13.1[1] (👩🏼‍❤️‍👩🏾)
+1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-light skin tone, dark skin tone #E13.1[1] (👩🏼‍❤️‍👩🏿)
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-light skin tone, light skin tone #E13.1[1] (👩🏼‍❤️‍💋‍👨🏻)
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-light skin tone # E13.1 [1] (👩🏼‍❤️‍💋‍👨🏼)
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-light skin tone, medium skin tone #E13.1[1] (👩🏼‍❤️‍💋‍👨🏽)
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-light skin tone, medium-dark skin tone #E13.1[1] (👩🏼‍❤️‍💋‍👨🏾)
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-light skin tone, dark skin tone #E13.1 [1] (👩🏼‍❤️‍💋‍👨🏿)
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-light skin tone, light skin tone #E13.1[1] (👩🏼‍❤️‍💋‍👩🏻)
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-light skin tone # E13.1 [1] (👩🏼‍❤️‍💋‍👩🏼)
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-light skin tone, medium skin tone #E13.1[1] (👩🏼‍❤️‍💋‍👩🏽)
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-light skin tone, medium-dark skin tone #E13.1[1] (👩🏼‍❤️‍💋‍👩🏾)
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-light skin tone, dark skin tone #E13.1[1] (👩🏼‍❤️‍💋‍👩🏿)
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-light skin tone, light skin tone #E12.0[1] (👩🏼‍🤝‍👨🏻)
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-light skin tone, medium skin tone #E12.0[1] (👩🏼‍🤝‍👨🏽)
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-light skin tone, medium-dark skin tone #E12.0[1] (👩🏼‍🤝‍👨🏾)
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-light skin tone, dark skin tone #E12.0[1] (👩🏼‍🤝‍👨🏿)
+1F469 1F3FC 200D 1F91D 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-light skin tone, light skin tone # E12.0 [1] (👩🏼‍🤝‍👩🏻)
+1F469 1F3FC 200D 1F91D 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-light skin tone, medium skin tone # E12.1 [1] (👩🏼‍🤝‍👩🏽)
+1F469 1F3FC 200D 1F91D 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-light skin tone, medium-dark skin tone #E12.1[1] (👩🏼‍🤝‍👩🏾)
+1F469 1F3FC 200D 1F91D 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-light skin tone, dark skin tone # E12.1 [1] (👩🏼‍🤝‍👩🏿)
+1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium skin tone, light skin tone #E13.1 [1] (👩🏽‍❤️‍👨🏻)
+1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium skin tone, medium-light skin tone #E13.1[1] (👩🏽‍❤️‍👨🏼)
+1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium skin tone # E13.1 [1] (👩🏽‍❤️‍👨🏽)
+1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium skin tone, medium-dark skin tone #E13.1[1] (👩🏽‍❤️‍👨🏾)
+1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium skin tone, dark skin tone #E13.1 [1] (👩🏽‍❤️‍👨🏿)
+1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium skin tone, light skin tone #E13.1[1] (👩🏽‍❤️‍👩🏻)
+1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium skin tone, medium-light skin tone #E13.1[1] (👩🏽‍❤️‍👩🏼)
+1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium skin tone # E13.1 [1] (👩🏽‍❤️‍👩🏽)
+1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium skin tone, medium-dark skin tone #E13.1[1] (👩🏽‍❤️‍👩🏾)
+1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium skin tone, dark skin tone #E13.1[1] (👩🏽‍❤️‍👩🏿)
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium skin tone, light skin tone # E13.1 [1] (👩🏽‍❤️‍💋‍👨🏻)
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium skin tone, medium-light skin tone #E13.1[1] (👩🏽‍❤️‍💋‍👨🏼)
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium skin tone # E13.1 [1] (👩🏽‍❤️‍💋‍👨🏽)
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium skin tone, medium-dark skin tone #E13.1[1] (👩🏽‍❤️‍💋‍👨🏾)
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium skin tone, dark skin tone # E13.1 [1] (👩🏽‍❤️‍💋‍👨🏿)
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium skin tone, light skin tone # E13.1 [1] (👩🏽‍❤️‍💋‍👩🏻)
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium skin tone, medium-light skin tone #E13.1[1] (👩🏽‍❤️‍💋‍👩🏼)
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium skin tone # E13.1 [1] (👩🏽‍❤️‍💋‍👩🏽)
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium skin tone, medium-dark skin tone #E13.1[1] (👩🏽‍❤️‍💋‍👩🏾)
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium skin tone, dark skin tone # E13.1 [1] (👩🏽‍❤️‍💋‍👩🏿)
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium skin tone, light skin tone # E12.0 [1] (👩🏽‍🤝‍👨🏻)
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium skin tone, medium-light skin tone #E12.0[1] (👩🏽‍🤝‍👨🏼)
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium skin tone, medium-dark skin tone #E12.0[1] (👩🏽‍🤝‍👨🏾)
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium skin tone, dark skin tone # E12.0 [1] (👩🏽‍🤝‍👨🏿)
+1F469 1F3FD 200D 1F91D 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium skin tone, light skin tone # E12.0 [1] (👩🏽‍🤝‍👩🏻)
+1F469 1F3FD 200D 1F91D 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium skin tone, medium-light skin tone # E12.0 [1] (👩🏽‍🤝‍👩🏼)
+1F469 1F3FD 200D 1F91D 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium skin tone, medium-dark skin tone # E12.1 [1] (👩🏽‍🤝‍👩🏾)
+1F469 1F3FD 200D 1F91D 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium skin tone, dark skin tone # E12.1 [1] (👩🏽‍🤝‍👩🏿)
+1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-dark skin tone, light skin tone #E13.1[1] (👩🏾‍❤️‍👨🏻)
+1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-dark skin tone, medium-light skin tone #E13.1[1] (👩🏾‍❤️‍👨🏼)
+1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-dark skin tone, medium skin tone #E13.1[1] (👩🏾‍❤️‍👨🏽)
+1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-dark skin tone # E13.1 [1] (👩🏾‍❤️‍👨🏾)
+1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, medium-dark skin tone, dark skin tone #E13.1[1] (👩🏾‍❤️‍👨🏿)
+1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-dark skin tone, light skin tone #E13.1[1] (👩🏾‍❤️‍👩🏻)
+1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-dark skin tone, medium-light skin tone #E13.1[1] (👩🏾‍❤️‍👩🏼)
+1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-dark skin tone, medium skin tone #E13.1[1] (👩🏾‍❤️‍👩🏽)
+1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-dark skin tone # E13.1 [1] (👩🏾‍❤️‍👩🏾)
+1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, medium-dark skin tone, dark skin tone #E13.1[1] (👩🏾‍❤️‍👩🏿)
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-dark skin tone, light skin tone #E13.1 [1] (👩🏾‍❤️‍💋‍👨🏻)
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-dark skin tone, medium-light skin tone #E13.1[1] (👩🏾‍❤️‍💋‍👨🏼)
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-dark skin tone, medium skin tone #E13.1[1] (👩🏾‍❤️‍💋‍👨🏽)
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-dark skin tone # E13.1 [1] (👩🏾‍❤️‍💋‍👨🏾)
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, medium-dark skin tone, dark skin tone #E13.1 [1] (👩🏾‍❤️‍💋‍👨🏿)
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-dark skin tone, light skin tone #E13.1[1] (👩🏾‍❤️‍💋‍👩🏻)
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-dark skin tone, medium-light skin tone #E13.1[1] (👩🏾‍❤️‍💋‍👩🏼)
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-dark skin tone, medium skin tone #E13.1[1] (👩🏾‍❤️‍💋‍👩🏽)
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-dark skin tone # E13.1 [1] (👩🏾‍❤️‍💋‍👩🏾)
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, medium-dark skin tone, dark skin tone #E13.1[1] (👩🏾‍❤️‍💋‍👩🏿)
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-dark skin tone, light skin tone #E12.0[1] (👩🏾‍🤝‍👨🏻)
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-dark skin tone, medium-light skin tone #E12.0[1] (👩🏾‍🤝‍👨🏼)
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-dark skin tone, medium skin tone #E12.0[1] (👩🏾‍🤝‍👨🏽)
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: medium-dark skin tone, dark skin tone #E12.0[1] (👩🏾‍🤝‍👨🏿)
+1F469 1F3FE 200D 1F91D 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-dark skin tone, light skin tone # E12.0 [1] (👩🏾‍🤝‍👩🏻)
+1F469 1F3FE 200D 1F91D 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-dark skin tone, medium-light skin tone #E12.0[1] (👩🏾‍🤝‍👩🏼)
+1F469 1F3FE 200D 1F91D 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-dark skin tone, medium skin tone # E12.0 [1] (👩🏾‍🤝‍👩🏽)
+1F469 1F3FE 200D 1F91D 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; women holding hands: medium-dark skin tone, dark skin tone # E12.1 [1] (👩🏾‍🤝‍👩🏿)
+1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, dark skin tone, light skin tone # E13.1 [1] (👩🏿‍❤️‍👨🏻)
+1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, dark skin tone, medium-light skin tone #E13.1[1] (👩🏿‍❤️‍👨🏼)
+1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, dark skin tone, medium skin tone #E13.1 [1] (👩🏿‍❤️‍👨🏽)
+1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, dark skin tone, medium-dark skin tone #E13.1[1] (👩🏿‍❤️‍👨🏾)
+1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, man, dark skin tone # E13.1 [1] (👩🏿‍❤️‍👨🏿)
+1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, dark skin tone, light skin tone #E13.1 [1] (👩🏿‍❤️‍👩🏻)
+1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, dark skin tone, medium-light skin tone #E13.1[1] (👩🏿‍❤️‍👩🏼)
+1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, dark skin tone, medium skin tone #E13.1[1] (👩🏿‍❤️‍👩🏽)
+1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, dark skin tone, medium-dark skin tone #E13.1[1] (👩🏿‍❤️‍👩🏾)
+1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: woman, woman, dark skin tone # E13.1 [1] (👩🏿‍❤️‍👩🏿)
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, dark skin tone, light skin tone # E13.1 [1] (👩🏿‍❤️‍💋‍👨🏻)
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, dark skin tone, medium-light skin tone #E13.1 [1] (👩🏿‍❤️‍💋‍👨🏼)
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, dark skin tone, medium skin tone # E13.1 [1] (👩🏿‍❤️‍💋‍👨🏽)
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, dark skin tone, medium-dark skin tone #E13.1 [1] (👩🏿‍❤️‍💋‍👨🏾)
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, man, dark skin tone # E13.1 [1] (👩🏿‍❤️‍💋‍👨🏿)
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, dark skin tone, light skin tone # E13.1 [1] (👩🏿‍❤️‍💋‍👩🏻)
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, dark skin tone, medium-light skin tone #E13.1[1] (👩🏿‍❤️‍💋‍👩🏼)
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, dark skin tone, medium skin tone # E13.1 [1] (👩🏿‍❤️‍💋‍👩🏽)
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, dark skin tone, medium-dark skin tone #E13.1[1] (👩🏿‍❤️‍💋‍👩🏾)
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: woman, woman, dark skin tone # E13.1 [1] (👩🏿‍❤️‍💋‍👩🏿)
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FB ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: dark skin tone, light skin tone # E12.0 [1] (👩🏿‍🤝‍👨🏻)
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FC ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: dark skin tone, medium-light skin tone #E12.0[1] (👩🏿‍🤝‍👨🏼)
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FD ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: dark skin tone, medium skin tone # E12.0 [1] (👩🏿‍🤝‍👨🏽)
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FE ; RGI_Emoji_ZWJ_Sequence ; woman and man holding hands: dark skin tone, medium-dark skin tone #E12.0[1] (👩🏿‍🤝‍👨🏾)
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FB ; RGI_Emoji_ZWJ_Sequence ; women holding hands: dark skin tone, light skin tone # E12.0 [1] (👩🏿‍🤝‍👩🏻)
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FC ; RGI_Emoji_ZWJ_Sequence ; women holding hands: dark skin tone, medium-light skin tone # E12.0 [1] (👩🏿‍🤝‍👩🏼)
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FD ; RGI_Emoji_ZWJ_Sequence ; women holding hands: dark skin tone, medium skin tone # E12.0 [1] (👩🏿‍🤝‍👩🏽)
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FE ; RGI_Emoji_ZWJ_Sequence ; women holding hands: dark skin tone, medium-dark skin tone # E12.0 [1] (👩🏿‍🤝‍👩🏾)
+1F9D1 200D 1F91D 200D 1F9D1 ; RGI_Emoji_ZWJ_Sequence ; people holding hands # E12.0 [1] (🧑‍🤝‍🧑)
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: person, person, light skin tone, medium-light skin tone #E13.1[1] (🧑🏻‍❤️‍💋‍🧑🏼)
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: person, person, light skin tone, medium skin tone #E13.1 [1] (🧑🏻‍❤️‍💋‍🧑🏽)
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: person, person, light skin tone, medium-dark skin tone #E13.1[1] (🧑🏻‍❤️‍💋‍🧑🏾)
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: person, person, light skin tone, dark skin tone # E13.1 [1] (🧑🏻‍❤️‍💋‍🧑🏿)
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, light skin tone, medium-light skin tone #E13.1[1] (🧑🏻‍❤️‍🧑🏼)
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, light skin tone, medium skin tone #E13.1[1] (🧑🏻‍❤️‍🧑🏽)
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, light skin tone, medium-dark skin tone #E13.1[1] (🧑🏻‍❤️‍🧑🏾)
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, light skin tone, dark skin tone #E13.1[1] (🧑🏻‍❤️‍🧑🏿)
+1F9D1 1F3FB 200D 1F384 ; RGI_Emoji_ZWJ_Sequence ; mx claus: light skin tone # E13.0 [1] (🧑🏻‍🎄)
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; people holding hands: light skin tone # E12.0 [1] (🧑🏻‍🤝‍🧑🏻)
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; people holding hands: light skin tone, medium-light skin tone # E12.1 [1] (🧑🏻‍🤝‍🧑🏼)
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; people holding hands: light skin tone, medium skin tone # E12.1 [1] (🧑🏻‍🤝‍🧑🏽)
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; people holding hands: light skin tone, medium-dark skin tone # E12.1 [1] (🧑🏻‍🤝‍🧑🏾)
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; people holding hands: light skin tone, dark skin tone # E12.1 [1] (🧑🏻‍🤝‍🧑🏿)
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-light skin tone, light skin tone #E13.1[1] (🧑🏼‍❤️‍💋‍🧑🏻)
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-light skin tone, medium skin tone #E13.1[1] (🧑🏼‍❤️‍💋‍🧑🏽)
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-light skin tone, medium-dark skin tone #E13.1[1] (🧑🏼‍❤️‍💋‍🧑🏾)
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-light skin tone, dark skin tone #E13.1[1] (🧑🏼‍❤️‍💋‍🧑🏿)
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-light skin tone, light skin tone #E13.1[1] (🧑🏼‍❤️‍🧑🏻)
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-light skin tone, medium skin tone #E13.1[1] (🧑🏼‍❤️‍🧑🏽)
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-light skin tone, medium-dark skin tone #E13.1[1] (🧑🏼‍❤️‍🧑🏾)
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-light skin tone, dark skin tone #E13.1[1] (🧑🏼‍❤️‍🧑🏿)
+1F9D1 1F3FC 200D 1F384 ; RGI_Emoji_ZWJ_Sequence ; mx claus: medium-light skin tone # E13.0 [1] (🧑🏼‍🎄)
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-light skin tone, light skin tone # E12.0 [1] (🧑🏼‍🤝‍🧑🏻)
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-light skin tone # E12.0 [1] (🧑🏼‍🤝‍🧑🏼)
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-light skin tone, medium skin tone # E12.1 [1] (🧑🏼‍🤝‍🧑🏽)
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-light skin tone, medium-dark skin tone #E12.1[1] (🧑🏼‍🤝‍🧑🏾)
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-light skin tone, dark skin tone # E12.1 [1] (🧑🏼‍🤝‍🧑🏿)
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium skin tone, light skin tone #E13.1 [1] (🧑🏽‍❤️‍💋‍🧑🏻)
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium skin tone, medium-light skin tone #E13.1[1] (🧑🏽‍❤️‍💋‍🧑🏼)
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium skin tone, medium-dark skin tone #E13.1[1] (🧑🏽‍❤️‍💋‍🧑🏾)
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium skin tone, dark skin tone # E13.1 [1] (🧑🏽‍❤️‍💋‍🧑🏿)
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium skin tone, light skin tone #E13.1[1] (🧑🏽‍❤️‍🧑🏻)
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium skin tone, medium-light skin tone #E13.1[1] (🧑🏽‍❤️‍🧑🏼)
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium skin tone, medium-dark skin tone #E13.1[1] (🧑🏽‍❤️‍🧑🏾)
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium skin tone, dark skin tone #E13.1[1] (🧑🏽‍❤️‍🧑🏿)
+1F9D1 1F3FD 200D 1F384 ; RGI_Emoji_ZWJ_Sequence ; mx claus: medium skin tone # E13.0 [1] (🧑🏽‍🎄)
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium skin tone, light skin tone # E12.0 [1] (🧑🏽‍🤝‍🧑🏻)
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium skin tone, medium-light skin tone # E12.0 [1] (🧑🏽‍🤝‍🧑🏼)
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium skin tone # E12.0 [1] (🧑🏽‍🤝‍🧑🏽)
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium skin tone, medium-dark skin tone # E12.1 [1] (🧑🏽‍🤝‍🧑🏾)
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium skin tone, dark skin tone # E12.1 [1] (🧑🏽‍🤝‍🧑🏿)
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-dark skin tone, light skin tone #E13.1[1] (🧑🏾‍❤️‍💋‍🧑🏻)
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-dark skin tone, medium-light skin tone #E13.1[1] (🧑🏾‍❤️‍💋‍🧑🏼)
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-dark skin tone, medium skin tone #E13.1[1] (🧑🏾‍❤️‍💋‍🧑🏽)
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF; RGI_Emoji_ZWJ_Sequence; kiss: person, person, medium-dark skin tone, dark skin tone #E13.1[1] (🧑🏾‍❤️‍💋‍🧑🏿)
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-dark skin tone, light skin tone #E13.1[1] (🧑🏾‍❤️‍🧑🏻)
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-dark skin tone, medium-light skin tone #E13.1[1] (🧑🏾‍❤️‍🧑🏼)
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-dark skin tone, medium skin tone #E13.1[1] (🧑🏾‍❤️‍🧑🏽)
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, medium-dark skin tone, dark skin tone #E13.1[1] (🧑🏾‍❤️‍🧑🏿)
+1F9D1 1F3FE 200D 1F384 ; RGI_Emoji_ZWJ_Sequence ; mx claus: medium-dark skin tone # E13.0 [1] (🧑🏾‍🎄)
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-dark skin tone, light skin tone # E12.0 [1] (🧑🏾‍🤝‍🧑🏻)
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-dark skin tone, medium-light skin tone #E12.0[1] (🧑🏾‍🤝‍🧑🏼)
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-dark skin tone, medium skin tone # E12.0 [1] (🧑🏾‍🤝‍🧑🏽)
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-dark skin tone # E12.0 [1] (🧑🏾‍🤝‍🧑🏾)
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; people holding hands: medium-dark skin tone, dark skin tone # E12.1 [1] (🧑🏾‍🤝‍🧑🏿)
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB; RGI_Emoji_ZWJ_Sequence; kiss: person, person, dark skin tone, light skin tone # E13.1 [1] (🧑🏿‍❤️‍💋‍🧑🏻)
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC; RGI_Emoji_ZWJ_Sequence; kiss: person, person, dark skin tone, medium-light skin tone #E13.1[1] (🧑🏿‍❤️‍💋‍🧑🏼)
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD; RGI_Emoji_ZWJ_Sequence; kiss: person, person, dark skin tone, medium skin tone # E13.1 [1] (🧑🏿‍❤️‍💋‍🧑🏽)
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE; RGI_Emoji_ZWJ_Sequence; kiss: person, person, dark skin tone, medium-dark skin tone #E13.1[1] (🧑🏿‍❤️‍💋‍🧑🏾)
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, dark skin tone, light skin tone #E13.1[1] (🧑🏿‍❤️‍🧑🏻)
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, dark skin tone, medium-light skin tone #E13.1[1] (🧑🏿‍❤️‍🧑🏼)
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, dark skin tone, medium skin tone #E13.1[1] (🧑🏿‍❤️‍🧑🏽)
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; couple with heart: person, person, dark skin tone, medium-dark skin tone #E13.1[1] (🧑🏿‍❤️‍🧑🏾)
+1F9D1 1F3FF 200D 1F384 ; RGI_Emoji_ZWJ_Sequence ; mx claus: dark skin tone # E13.0 [1] (🧑🏿‍🎄)
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FB ; RGI_Emoji_ZWJ_Sequence ; people holding hands: dark skin tone, light skin tone # E12.0 [1] (🧑🏿‍🤝‍🧑🏻)
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FC ; RGI_Emoji_ZWJ_Sequence ; people holding hands: dark skin tone, medium-light skin tone # E12.0 [1] (🧑🏿‍🤝‍🧑🏼)
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FD ; RGI_Emoji_ZWJ_Sequence ; people holding hands: dark skin tone, medium skin tone # E12.0 [1] (🧑🏿‍🤝‍🧑🏽)
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FE ; RGI_Emoji_ZWJ_Sequence ; people holding hands: dark skin tone, medium-dark skin tone # E12.0 [1] (🧑🏿‍🤝‍🧑🏾)
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FF ; RGI_Emoji_ZWJ_Sequence ; people holding hands: dark skin tone # E12.0 [1] (🧑🏿‍🤝‍🧑🏿)
+1FAF1 1F3FB 200D 1FAF2 1F3FC ; RGI_Emoji_ZWJ_Sequence ; handshake: light skin tone, medium-light skin tone # E14.0 [1] (🫱🏻‍🫲🏼)
+1FAF1 1F3FB 200D 1FAF2 1F3FD ; RGI_Emoji_ZWJ_Sequence ; handshake: light skin tone, medium skin tone # E14.0 [1] (🫱🏻‍🫲🏽)
+1FAF1 1F3FB 200D 1FAF2 1F3FE ; RGI_Emoji_ZWJ_Sequence ; handshake: light skin tone, medium-dark skin tone # E14.0 [1] (🫱🏻‍🫲🏾)
+1FAF1 1F3FB 200D 1FAF2 1F3FF ; RGI_Emoji_ZWJ_Sequence ; handshake: light skin tone, dark skin tone # E14.0 [1] (🫱🏻‍🫲🏿)
+1FAF1 1F3FC 200D 1FAF2 1F3FB ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-light skin tone, light skin tone # E14.0 [1] (🫱🏼‍🫲🏻)
+1FAF1 1F3FC 200D 1FAF2 1F3FD ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-light skin tone, medium skin tone # E14.0 [1] (🫱🏼‍🫲🏽)
+1FAF1 1F3FC 200D 1FAF2 1F3FE ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-light skin tone, medium-dark skin tone # E14.0 [1] (🫱🏼‍🫲🏾)
+1FAF1 1F3FC 200D 1FAF2 1F3FF ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-light skin tone, dark skin tone # E14.0 [1] (🫱🏼‍🫲🏿)
+1FAF1 1F3FD 200D 1FAF2 1F3FB ; RGI_Emoji_ZWJ_Sequence ; handshake: medium skin tone, light skin tone # E14.0 [1] (🫱🏽‍🫲🏻)
+1FAF1 1F3FD 200D 1FAF2 1F3FC ; RGI_Emoji_ZWJ_Sequence ; handshake: medium skin tone, medium-light skin tone # E14.0 [1] (🫱🏽‍🫲🏼)
+1FAF1 1F3FD 200D 1FAF2 1F3FE ; RGI_Emoji_ZWJ_Sequence ; handshake: medium skin tone, medium-dark skin tone # E14.0 [1] (🫱🏽‍🫲🏾)
+1FAF1 1F3FD 200D 1FAF2 1F3FF ; RGI_Emoji_ZWJ_Sequence ; handshake: medium skin tone, dark skin tone # E14.0 [1] (🫱🏽‍🫲🏿)
+1FAF1 1F3FE 200D 1FAF2 1F3FB ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-dark skin tone, light skin tone # E14.0 [1] (🫱🏾‍🫲🏻)
+1FAF1 1F3FE 200D 1FAF2 1F3FC ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-dark skin tone, medium-light skin tone # E14.0 [1] (🫱🏾‍🫲🏼)
+1FAF1 1F3FE 200D 1FAF2 1F3FD ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-dark skin tone, medium skin tone # E14.0 [1] (🫱🏾‍🫲🏽)
+1FAF1 1F3FE 200D 1FAF2 1F3FF ; RGI_Emoji_ZWJ_Sequence ; handshake: medium-dark skin tone, dark skin tone # E14.0 [1] (🫱🏾‍🫲🏿)
+1FAF1 1F3FF 200D 1FAF2 1F3FB ; RGI_Emoji_ZWJ_Sequence ; handshake: dark skin tone, light skin tone # E14.0 [1] (🫱🏿‍🫲🏻)
+1FAF1 1F3FF 200D 1FAF2 1F3FC ; RGI_Emoji_ZWJ_Sequence ; handshake: dark skin tone, medium-light skin tone # E14.0 [1] (🫱🏿‍🫲🏼)
+1FAF1 1F3FF 200D 1FAF2 1F3FD ; RGI_Emoji_ZWJ_Sequence ; handshake: dark skin tone, medium skin tone # E14.0 [1] (🫱🏿‍🫲🏽)
+1FAF1 1F3FF 200D 1FAF2 1F3FE ; RGI_Emoji_ZWJ_Sequence ; handshake: dark skin tone, medium-dark skin tone # E14.0 [1] (🫱🏿‍🫲🏾)
+
+# Total elements: 332
+
+# ================================================
+
+# RGI_Emoji_ZWJ_Sequence: Role
+
+1F468 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; man health worker # E4.0 [1] (👨‍⚕️)
+1F468 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; man judge # E4.0 [1] (👨‍⚖️)
+1F468 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pilot # E4.0 [1] (👨‍✈️)
+1F468 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; man farmer # E4.0 [1] (👨‍🌾)
+1F468 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; man cook # E4.0 [1] (👨‍🍳)
+1F468 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; man feeding baby # E13.0 [1] (👨‍🍼)
+1F468 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; man student # E4.0 [1] (👨‍🎓)
+1F468 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; man singer # E4.0 [1] (👨‍🎤)
+1F468 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; man artist # E4.0 [1] (👨‍🎨)
+1F468 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; man teacher # E4.0 [1] (👨‍🏫)
+1F468 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; man factory worker # E4.0 [1] (👨‍🏭)
+1F468 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; man technologist # E4.0 [1] (👨‍💻)
+1F468 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; man office worker # E4.0 [1] (👨‍💼)
+1F468 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; man mechanic # E4.0 [1] (👨‍🔧)
+1F468 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; man scientist # E4.0 [1] (👨‍🔬)
+1F468 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; man astronaut # E4.0 [1] (👨‍🚀)
+1F468 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; man firefighter # E4.0 [1] (👨‍🚒)
+1F468 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; man with white cane # E12.0 [1] (👨‍🦯)
+1F468 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair # E12.0 [1] (👨‍🦼)
+1F468 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair # E12.0 [1] (👨‍🦽)
+1F468 1F3FB 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; man health worker: light skin tone # E4.0 [1] (👨🏻‍⚕️)
+1F468 1F3FB 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; man judge: light skin tone # E4.0 [1] (👨🏻‍⚖️)
+1F468 1F3FB 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pilot: light skin tone # E4.0 [1] (👨🏻‍✈️)
+1F468 1F3FB 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; man farmer: light skin tone # E4.0 [1] (👨🏻‍🌾)
+1F468 1F3FB 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; man cook: light skin tone # E4.0 [1] (👨🏻‍🍳)
+1F468 1F3FB 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; man feeding baby: light skin tone # E13.0 [1] (👨🏻‍🍼)
+1F468 1F3FB 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; man student: light skin tone # E4.0 [1] (👨🏻‍🎓)
+1F468 1F3FB 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; man singer: light skin tone # E4.0 [1] (👨🏻‍🎤)
+1F468 1F3FB 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; man artist: light skin tone # E4.0 [1] (👨🏻‍🎨)
+1F468 1F3FB 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; man teacher: light skin tone # E4.0 [1] (👨🏻‍🏫)
+1F468 1F3FB 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; man factory worker: light skin tone # E4.0 [1] (👨🏻‍🏭)
+1F468 1F3FB 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; man technologist: light skin tone # E4.0 [1] (👨🏻‍💻)
+1F468 1F3FB 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; man office worker: light skin tone # E4.0 [1] (👨🏻‍💼)
+1F468 1F3FB 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; man mechanic: light skin tone # E4.0 [1] (👨🏻‍🔧)
+1F468 1F3FB 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; man scientist: light skin tone # E4.0 [1] (👨🏻‍🔬)
+1F468 1F3FB 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; man astronaut: light skin tone # E4.0 [1] (👨🏻‍🚀)
+1F468 1F3FB 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; man firefighter: light skin tone # E4.0 [1] (👨🏻‍🚒)
+1F468 1F3FB 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; man with white cane: light skin tone # E12.0 [1] (👨🏻‍🦯)
+1F468 1F3FB 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair: light skin tone # E12.0 [1] (👨🏻‍🦼)
+1F468 1F3FB 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair: light skin tone # E12.0 [1] (👨🏻‍🦽)
+1F468 1F3FC 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; man health worker: medium-light skin tone # E4.0 [1] (👨🏼‍⚕️)
+1F468 1F3FC 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; man judge: medium-light skin tone # E4.0 [1] (👨🏼‍⚖️)
+1F468 1F3FC 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pilot: medium-light skin tone # E4.0 [1] (👨🏼‍✈️)
+1F468 1F3FC 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; man farmer: medium-light skin tone # E4.0 [1] (👨🏼‍🌾)
+1F468 1F3FC 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; man cook: medium-light skin tone # E4.0 [1] (👨🏼‍🍳)
+1F468 1F3FC 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; man feeding baby: medium-light skin tone # E13.0 [1] (👨🏼‍🍼)
+1F468 1F3FC 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; man student: medium-light skin tone # E4.0 [1] (👨🏼‍🎓)
+1F468 1F3FC 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; man singer: medium-light skin tone # E4.0 [1] (👨🏼‍🎤)
+1F468 1F3FC 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; man artist: medium-light skin tone # E4.0 [1] (👨🏼‍🎨)
+1F468 1F3FC 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; man teacher: medium-light skin tone # E4.0 [1] (👨🏼‍🏫)
+1F468 1F3FC 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; man factory worker: medium-light skin tone # E4.0 [1] (👨🏼‍🏭)
+1F468 1F3FC 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; man technologist: medium-light skin tone # E4.0 [1] (👨🏼‍💻)
+1F468 1F3FC 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; man office worker: medium-light skin tone # E4.0 [1] (👨🏼‍💼)
+1F468 1F3FC 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; man mechanic: medium-light skin tone # E4.0 [1] (👨🏼‍🔧)
+1F468 1F3FC 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; man scientist: medium-light skin tone # E4.0 [1] (👨🏼‍🔬)
+1F468 1F3FC 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; man astronaut: medium-light skin tone # E4.0 [1] (👨🏼‍🚀)
+1F468 1F3FC 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; man firefighter: medium-light skin tone # E4.0 [1] (👨🏼‍🚒)
+1F468 1F3FC 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; man with white cane: medium-light skin tone # E12.0 [1] (👨🏼‍🦯)
+1F468 1F3FC 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair: medium-light skin tone # E12.0 [1] (👨🏼‍🦼)
+1F468 1F3FC 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair: medium-light skin tone # E12.0 [1] (👨🏼‍🦽)
+1F468 1F3FD 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; man health worker: medium skin tone # E4.0 [1] (👨🏽‍⚕️)
+1F468 1F3FD 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; man judge: medium skin tone # E4.0 [1] (👨🏽‍⚖️)
+1F468 1F3FD 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pilot: medium skin tone # E4.0 [1] (👨🏽‍✈️)
+1F468 1F3FD 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; man farmer: medium skin tone # E4.0 [1] (👨🏽‍🌾)
+1F468 1F3FD 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; man cook: medium skin tone # E4.0 [1] (👨🏽‍🍳)
+1F468 1F3FD 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; man feeding baby: medium skin tone # E13.0 [1] (👨🏽‍🍼)
+1F468 1F3FD 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; man student: medium skin tone # E4.0 [1] (👨🏽‍🎓)
+1F468 1F3FD 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; man singer: medium skin tone # E4.0 [1] (👨🏽‍🎤)
+1F468 1F3FD 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; man artist: medium skin tone # E4.0 [1] (👨🏽‍🎨)
+1F468 1F3FD 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; man teacher: medium skin tone # E4.0 [1] (👨🏽‍🏫)
+1F468 1F3FD 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; man factory worker: medium skin tone # E4.0 [1] (👨🏽‍🏭)
+1F468 1F3FD 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; man technologist: medium skin tone # E4.0 [1] (👨🏽‍💻)
+1F468 1F3FD 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; man office worker: medium skin tone # E4.0 [1] (👨🏽‍💼)
+1F468 1F3FD 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; man mechanic: medium skin tone # E4.0 [1] (👨🏽‍🔧)
+1F468 1F3FD 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; man scientist: medium skin tone # E4.0 [1] (👨🏽‍🔬)
+1F468 1F3FD 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; man astronaut: medium skin tone # E4.0 [1] (👨🏽‍🚀)
+1F468 1F3FD 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; man firefighter: medium skin tone # E4.0 [1] (👨🏽‍🚒)
+1F468 1F3FD 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; man with white cane: medium skin tone # E12.0 [1] (👨🏽‍🦯)
+1F468 1F3FD 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair: medium skin tone # E12.0 [1] (👨🏽‍🦼)
+1F468 1F3FD 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair: medium skin tone # E12.0 [1] (👨🏽‍🦽)
+1F468 1F3FE 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; man health worker: medium-dark skin tone # E4.0 [1] (👨🏾‍⚕️)
+1F468 1F3FE 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; man judge: medium-dark skin tone # E4.0 [1] (👨🏾‍⚖️)
+1F468 1F3FE 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pilot: medium-dark skin tone # E4.0 [1] (👨🏾‍✈️)
+1F468 1F3FE 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; man farmer: medium-dark skin tone # E4.0 [1] (👨🏾‍🌾)
+1F468 1F3FE 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; man cook: medium-dark skin tone # E4.0 [1] (👨🏾‍🍳)
+1F468 1F3FE 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; man feeding baby: medium-dark skin tone # E13.0 [1] (👨🏾‍🍼)
+1F468 1F3FE 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; man student: medium-dark skin tone # E4.0 [1] (👨🏾‍🎓)
+1F468 1F3FE 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; man singer: medium-dark skin tone # E4.0 [1] (👨🏾‍🎤)
+1F468 1F3FE 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; man artist: medium-dark skin tone # E4.0 [1] (👨🏾‍🎨)
+1F468 1F3FE 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; man teacher: medium-dark skin tone # E4.0 [1] (👨🏾‍🏫)
+1F468 1F3FE 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; man factory worker: medium-dark skin tone # E4.0 [1] (👨🏾‍🏭)
+1F468 1F3FE 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; man technologist: medium-dark skin tone # E4.0 [1] (👨🏾‍💻)
+1F468 1F3FE 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; man office worker: medium-dark skin tone # E4.0 [1] (👨🏾‍💼)
+1F468 1F3FE 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; man mechanic: medium-dark skin tone # E4.0 [1] (👨🏾‍🔧)
+1F468 1F3FE 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; man scientist: medium-dark skin tone # E4.0 [1] (👨🏾‍🔬)
+1F468 1F3FE 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; man astronaut: medium-dark skin tone # E4.0 [1] (👨🏾‍🚀)
+1F468 1F3FE 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; man firefighter: medium-dark skin tone # E4.0 [1] (👨🏾‍🚒)
+1F468 1F3FE 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; man with white cane: medium-dark skin tone # E12.0 [1] (👨🏾‍🦯)
+1F468 1F3FE 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair: medium-dark skin tone # E12.0 [1] (👨🏾‍🦼)
+1F468 1F3FE 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair: medium-dark skin tone # E12.0 [1] (👨🏾‍🦽)
+1F468 1F3FF 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; man health worker: dark skin tone # E4.0 [1] (👨🏿‍⚕️)
+1F468 1F3FF 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; man judge: dark skin tone # E4.0 [1] (👨🏿‍⚖️)
+1F468 1F3FF 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pilot: dark skin tone # E4.0 [1] (👨🏿‍✈️)
+1F468 1F3FF 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; man farmer: dark skin tone # E4.0 [1] (👨🏿‍🌾)
+1F468 1F3FF 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; man cook: dark skin tone # E4.0 [1] (👨🏿‍🍳)
+1F468 1F3FF 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; man feeding baby: dark skin tone # E13.0 [1] (👨🏿‍🍼)
+1F468 1F3FF 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; man student: dark skin tone # E4.0 [1] (👨🏿‍🎓)
+1F468 1F3FF 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; man singer: dark skin tone # E4.0 [1] (👨🏿‍🎤)
+1F468 1F3FF 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; man artist: dark skin tone # E4.0 [1] (👨🏿‍🎨)
+1F468 1F3FF 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; man teacher: dark skin tone # E4.0 [1] (👨🏿‍🏫)
+1F468 1F3FF 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; man factory worker: dark skin tone # E4.0 [1] (👨🏿‍🏭)
+1F468 1F3FF 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; man technologist: dark skin tone # E4.0 [1] (👨🏿‍💻)
+1F468 1F3FF 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; man office worker: dark skin tone # E4.0 [1] (👨🏿‍💼)
+1F468 1F3FF 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; man mechanic: dark skin tone # E4.0 [1] (👨🏿‍🔧)
+1F468 1F3FF 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; man scientist: dark skin tone # E4.0 [1] (👨🏿‍🔬)
+1F468 1F3FF 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; man astronaut: dark skin tone # E4.0 [1] (👨🏿‍🚀)
+1F468 1F3FF 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; man firefighter: dark skin tone # E4.0 [1] (👨🏿‍🚒)
+1F468 1F3FF 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; man with white cane: dark skin tone # E12.0 [1] (👨🏿‍🦯)
+1F468 1F3FF 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; man in motorized wheelchair: dark skin tone # E12.0 [1] (👨🏿‍🦼)
+1F468 1F3FF 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; man in manual wheelchair: dark skin tone # E12.0 [1] (👨🏿‍🦽)
+1F469 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman health worker # E4.0 [1] (👩‍⚕️)
+1F469 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman judge # E4.0 [1] (👩‍⚖️)
+1F469 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pilot # E4.0 [1] (👩‍✈️)
+1F469 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; woman farmer # E4.0 [1] (👩‍🌾)
+1F469 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; woman cook # E4.0 [1] (👩‍🍳)
+1F469 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; woman feeding baby # E13.0 [1] (👩‍🍼)
+1F469 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; woman student # E4.0 [1] (👩‍🎓)
+1F469 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; woman singer # E4.0 [1] (👩‍🎤)
+1F469 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; woman artist # E4.0 [1] (👩‍🎨)
+1F469 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; woman teacher # E4.0 [1] (👩‍🏫)
+1F469 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; woman factory worker # E4.0 [1] (👩‍🏭)
+1F469 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; woman technologist # E4.0 [1] (👩‍💻)
+1F469 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; woman office worker # E4.0 [1] (👩‍💼)
+1F469 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; woman mechanic # E4.0 [1] (👩‍🔧)
+1F469 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; woman scientist # E4.0 [1] (👩‍🔬)
+1F469 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; woman astronaut # E4.0 [1] (👩‍🚀)
+1F469 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; woman firefighter # E4.0 [1] (👩‍🚒)
+1F469 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; woman with white cane # E12.0 [1] (👩‍🦯)
+1F469 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair # E12.0 [1] (👩‍🦼)
+1F469 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair # E12.0 [1] (👩‍🦽)
+1F469 1F3FB 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman health worker: light skin tone # E4.0 [1] (👩🏻‍⚕️)
+1F469 1F3FB 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman judge: light skin tone # E4.0 [1] (👩🏻‍⚖️)
+1F469 1F3FB 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pilot: light skin tone # E4.0 [1] (👩🏻‍✈️)
+1F469 1F3FB 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; woman farmer: light skin tone # E4.0 [1] (👩🏻‍🌾)
+1F469 1F3FB 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; woman cook: light skin tone # E4.0 [1] (👩🏻‍🍳)
+1F469 1F3FB 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; woman feeding baby: light skin tone # E13.0 [1] (👩🏻‍🍼)
+1F469 1F3FB 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; woman student: light skin tone # E4.0 [1] (👩🏻‍🎓)
+1F469 1F3FB 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; woman singer: light skin tone # E4.0 [1] (👩🏻‍🎤)
+1F469 1F3FB 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; woman artist: light skin tone # E4.0 [1] (👩🏻‍🎨)
+1F469 1F3FB 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; woman teacher: light skin tone # E4.0 [1] (👩🏻‍🏫)
+1F469 1F3FB 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; woman factory worker: light skin tone # E4.0 [1] (👩🏻‍🏭)
+1F469 1F3FB 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; woman technologist: light skin tone # E4.0 [1] (👩🏻‍💻)
+1F469 1F3FB 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; woman office worker: light skin tone # E4.0 [1] (👩🏻‍💼)
+1F469 1F3FB 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; woman mechanic: light skin tone # E4.0 [1] (👩🏻‍🔧)
+1F469 1F3FB 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; woman scientist: light skin tone # E4.0 [1] (👩🏻‍🔬)
+1F469 1F3FB 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; woman astronaut: light skin tone # E4.0 [1] (👩🏻‍🚀)
+1F469 1F3FB 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; woman firefighter: light skin tone # E4.0 [1] (👩🏻‍🚒)
+1F469 1F3FB 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; woman with white cane: light skin tone # E12.0 [1] (👩🏻‍🦯)
+1F469 1F3FB 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair: light skin tone # E12.0 [1] (👩🏻‍🦼)
+1F469 1F3FB 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair: light skin tone # E12.0 [1] (👩🏻‍🦽)
+1F469 1F3FC 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman health worker: medium-light skin tone # E4.0 [1] (👩🏼‍⚕️)
+1F469 1F3FC 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman judge: medium-light skin tone # E4.0 [1] (👩🏼‍⚖️)
+1F469 1F3FC 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pilot: medium-light skin tone # E4.0 [1] (👩🏼‍✈️)
+1F469 1F3FC 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; woman farmer: medium-light skin tone # E4.0 [1] (👩🏼‍🌾)
+1F469 1F3FC 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; woman cook: medium-light skin tone # E4.0 [1] (👩🏼‍🍳)
+1F469 1F3FC 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; woman feeding baby: medium-light skin tone # E13.0 [1] (👩🏼‍🍼)
+1F469 1F3FC 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; woman student: medium-light skin tone # E4.0 [1] (👩🏼‍🎓)
+1F469 1F3FC 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; woman singer: medium-light skin tone # E4.0 [1] (👩🏼‍🎤)
+1F469 1F3FC 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; woman artist: medium-light skin tone # E4.0 [1] (👩🏼‍🎨)
+1F469 1F3FC 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; woman teacher: medium-light skin tone # E4.0 [1] (👩🏼‍🏫)
+1F469 1F3FC 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; woman factory worker: medium-light skin tone # E4.0 [1] (👩🏼‍🏭)
+1F469 1F3FC 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; woman technologist: medium-light skin tone # E4.0 [1] (👩🏼‍💻)
+1F469 1F3FC 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; woman office worker: medium-light skin tone # E4.0 [1] (👩🏼‍💼)
+1F469 1F3FC 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; woman mechanic: medium-light skin tone # E4.0 [1] (👩🏼‍🔧)
+1F469 1F3FC 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; woman scientist: medium-light skin tone # E4.0 [1] (👩🏼‍🔬)
+1F469 1F3FC 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; woman astronaut: medium-light skin tone # E4.0 [1] (👩🏼‍🚀)
+1F469 1F3FC 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; woman firefighter: medium-light skin tone # E4.0 [1] (👩🏼‍🚒)
+1F469 1F3FC 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; woman with white cane: medium-light skin tone # E12.0 [1] (👩🏼‍🦯)
+1F469 1F3FC 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair: medium-light skin tone # E12.0 [1] (👩🏼‍🦼)
+1F469 1F3FC 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair: medium-light skin tone # E12.0 [1] (👩🏼‍🦽)
+1F469 1F3FD 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman health worker: medium skin tone # E4.0 [1] (👩🏽‍⚕️)
+1F469 1F3FD 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman judge: medium skin tone # E4.0 [1] (👩🏽‍⚖️)
+1F469 1F3FD 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pilot: medium skin tone # E4.0 [1] (👩🏽‍✈️)
+1F469 1F3FD 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; woman farmer: medium skin tone # E4.0 [1] (👩🏽‍🌾)
+1F469 1F3FD 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; woman cook: medium skin tone # E4.0 [1] (👩🏽‍🍳)
+1F469 1F3FD 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; woman feeding baby: medium skin tone # E13.0 [1] (👩🏽‍🍼)
+1F469 1F3FD 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; woman student: medium skin tone # E4.0 [1] (👩🏽‍🎓)
+1F469 1F3FD 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; woman singer: medium skin tone # E4.0 [1] (👩🏽‍🎤)
+1F469 1F3FD 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; woman artist: medium skin tone # E4.0 [1] (👩🏽‍🎨)
+1F469 1F3FD 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; woman teacher: medium skin tone # E4.0 [1] (👩🏽‍🏫)
+1F469 1F3FD 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; woman factory worker: medium skin tone # E4.0 [1] (👩🏽‍🏭)
+1F469 1F3FD 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; woman technologist: medium skin tone # E4.0 [1] (👩🏽‍💻)
+1F469 1F3FD 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; woman office worker: medium skin tone # E4.0 [1] (👩🏽‍💼)
+1F469 1F3FD 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; woman mechanic: medium skin tone # E4.0 [1] (👩🏽‍🔧)
+1F469 1F3FD 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; woman scientist: medium skin tone # E4.0 [1] (👩🏽‍🔬)
+1F469 1F3FD 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; woman astronaut: medium skin tone # E4.0 [1] (👩🏽‍🚀)
+1F469 1F3FD 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; woman firefighter: medium skin tone # E4.0 [1] (👩🏽‍🚒)
+1F469 1F3FD 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; woman with white cane: medium skin tone # E12.0 [1] (👩🏽‍🦯)
+1F469 1F3FD 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair: medium skin tone # E12.0 [1] (👩🏽‍🦼)
+1F469 1F3FD 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair: medium skin tone # E12.0 [1] (👩🏽‍🦽)
+1F469 1F3FE 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman health worker: medium-dark skin tone # E4.0 [1] (👩🏾‍⚕️)
+1F469 1F3FE 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman judge: medium-dark skin tone # E4.0 [1] (👩🏾‍⚖️)
+1F469 1F3FE 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pilot: medium-dark skin tone # E4.0 [1] (👩🏾‍✈️)
+1F469 1F3FE 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; woman farmer: medium-dark skin tone # E4.0 [1] (👩🏾‍🌾)
+1F469 1F3FE 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; woman cook: medium-dark skin tone # E4.0 [1] (👩🏾‍🍳)
+1F469 1F3FE 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; woman feeding baby: medium-dark skin tone # E13.0 [1] (👩🏾‍🍼)
+1F469 1F3FE 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; woman student: medium-dark skin tone # E4.0 [1] (👩🏾‍🎓)
+1F469 1F3FE 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; woman singer: medium-dark skin tone # E4.0 [1] (👩🏾‍🎤)
+1F469 1F3FE 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; woman artist: medium-dark skin tone # E4.0 [1] (👩🏾‍🎨)
+1F469 1F3FE 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; woman teacher: medium-dark skin tone # E4.0 [1] (👩🏾‍🏫)
+1F469 1F3FE 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; woman factory worker: medium-dark skin tone # E4.0 [1] (👩🏾‍🏭)
+1F469 1F3FE 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; woman technologist: medium-dark skin tone # E4.0 [1] (👩🏾‍💻)
+1F469 1F3FE 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; woman office worker: medium-dark skin tone # E4.0 [1] (👩🏾‍💼)
+1F469 1F3FE 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; woman mechanic: medium-dark skin tone # E4.0 [1] (👩🏾‍🔧)
+1F469 1F3FE 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; woman scientist: medium-dark skin tone # E4.0 [1] (👩🏾‍🔬)
+1F469 1F3FE 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; woman astronaut: medium-dark skin tone # E4.0 [1] (👩🏾‍🚀)
+1F469 1F3FE 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; woman firefighter: medium-dark skin tone # E4.0 [1] (👩🏾‍🚒)
+1F469 1F3FE 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; woman with white cane: medium-dark skin tone # E12.0 [1] (👩🏾‍🦯)
+1F469 1F3FE 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair: medium-dark skin tone # E12.0 [1] (👩🏾‍🦼)
+1F469 1F3FE 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair: medium-dark skin tone # E12.0 [1] (👩🏾‍🦽)
+1F469 1F3FF 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman health worker: dark skin tone # E4.0 [1] (👩🏿‍⚕️)
+1F469 1F3FF 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman judge: dark skin tone # E4.0 [1] (👩🏿‍⚖️)
+1F469 1F3FF 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pilot: dark skin tone # E4.0 [1] (👩🏿‍✈️)
+1F469 1F3FF 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; woman farmer: dark skin tone # E4.0 [1] (👩🏿‍🌾)
+1F469 1F3FF 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; woman cook: dark skin tone # E4.0 [1] (👩🏿‍🍳)
+1F469 1F3FF 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; woman feeding baby: dark skin tone # E13.0 [1] (👩🏿‍🍼)
+1F469 1F3FF 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; woman student: dark skin tone # E4.0 [1] (👩🏿‍🎓)
+1F469 1F3FF 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; woman singer: dark skin tone # E4.0 [1] (👩🏿‍🎤)
+1F469 1F3FF 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; woman artist: dark skin tone # E4.0 [1] (👩🏿‍🎨)
+1F469 1F3FF 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; woman teacher: dark skin tone # E4.0 [1] (👩🏿‍🏫)
+1F469 1F3FF 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; woman factory worker: dark skin tone # E4.0 [1] (👩🏿‍🏭)
+1F469 1F3FF 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; woman technologist: dark skin tone # E4.0 [1] (👩🏿‍💻)
+1F469 1F3FF 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; woman office worker: dark skin tone # E4.0 [1] (👩🏿‍💼)
+1F469 1F3FF 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; woman mechanic: dark skin tone # E4.0 [1] (👩🏿‍🔧)
+1F469 1F3FF 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; woman scientist: dark skin tone # E4.0 [1] (👩🏿‍🔬)
+1F469 1F3FF 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; woman astronaut: dark skin tone # E4.0 [1] (👩🏿‍🚀)
+1F469 1F3FF 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; woman firefighter: dark skin tone # E4.0 [1] (👩🏿‍🚒)
+1F469 1F3FF 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; woman with white cane: dark skin tone # E12.0 [1] (👩🏿‍🦯)
+1F469 1F3FF 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; woman in motorized wheelchair: dark skin tone # E12.0 [1] (👩🏿‍🦼)
+1F469 1F3FF 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; woman in manual wheelchair: dark skin tone # E12.0 [1] (👩🏿‍🦽)
+1F9D1 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; health worker # E12.1 [1] (🧑‍⚕️)
+1F9D1 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; judge # E12.1 [1] (🧑‍⚖️)
+1F9D1 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; pilot # E12.1 [1] (🧑‍✈️)
+1F9D1 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; farmer # E12.1 [1] (🧑‍🌾)
+1F9D1 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; cook # E12.1 [1] (🧑‍🍳)
+1F9D1 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; person feeding baby # E13.0 [1] (🧑‍🍼)
+1F9D1 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; student # E12.1 [1] (🧑‍🎓)
+1F9D1 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; singer # E12.1 [1] (🧑‍🎤)
+1F9D1 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; artist # E12.1 [1] (🧑‍🎨)
+1F9D1 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; teacher # E12.1 [1] (🧑‍🏫)
+1F9D1 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; factory worker # E12.1 [1] (🧑‍🏭)
+1F9D1 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; technologist # E12.1 [1] (🧑‍💻)
+1F9D1 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; office worker # E12.1 [1] (🧑‍💼)
+1F9D1 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; mechanic # E12.1 [1] (🧑‍🔧)
+1F9D1 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; scientist # E12.1 [1] (🧑‍🔬)
+1F9D1 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; astronaut # E12.1 [1] (🧑‍🚀)
+1F9D1 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; firefighter # E12.1 [1] (🧑‍🚒)
+1F9D1 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; person with white cane # E12.1 [1] (🧑‍🦯)
+1F9D1 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair # E12.1 [1] (🧑‍🦼)
+1F9D1 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair # E12.1 [1] (🧑‍🦽)
+1F9D1 1F3FB 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; health worker: light skin tone # E12.1 [1] (🧑🏻‍⚕️)
+1F9D1 1F3FB 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; judge: light skin tone # E12.1 [1] (🧑🏻‍⚖️)
+1F9D1 1F3FB 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; pilot: light skin tone # E12.1 [1] (🧑🏻‍✈️)
+1F9D1 1F3FB 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; farmer: light skin tone # E12.1 [1] (🧑🏻‍🌾)
+1F9D1 1F3FB 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; cook: light skin tone # E12.1 [1] (🧑🏻‍🍳)
+1F9D1 1F3FB 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; person feeding baby: light skin tone # E13.0 [1] (🧑🏻‍🍼)
+1F9D1 1F3FB 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; student: light skin tone # E12.1 [1] (🧑🏻‍🎓)
+1F9D1 1F3FB 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; singer: light skin tone # E12.1 [1] (🧑🏻‍🎤)
+1F9D1 1F3FB 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; artist: light skin tone # E12.1 [1] (🧑🏻‍🎨)
+1F9D1 1F3FB 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; teacher: light skin tone # E12.1 [1] (🧑🏻‍🏫)
+1F9D1 1F3FB 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; factory worker: light skin tone # E12.1 [1] (🧑🏻‍🏭)
+1F9D1 1F3FB 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; technologist: light skin tone # E12.1 [1] (🧑🏻‍💻)
+1F9D1 1F3FB 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; office worker: light skin tone # E12.1 [1] (🧑🏻‍💼)
+1F9D1 1F3FB 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; mechanic: light skin tone # E12.1 [1] (🧑🏻‍🔧)
+1F9D1 1F3FB 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; scientist: light skin tone # E12.1 [1] (🧑🏻‍🔬)
+1F9D1 1F3FB 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; astronaut: light skin tone # E12.1 [1] (🧑🏻‍🚀)
+1F9D1 1F3FB 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; firefighter: light skin tone # E12.1 [1] (🧑🏻‍🚒)
+1F9D1 1F3FB 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; person with white cane: light skin tone # E12.1 [1] (🧑🏻‍🦯)
+1F9D1 1F3FB 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair: light skin tone # E12.1 [1] (🧑🏻‍🦼)
+1F9D1 1F3FB 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair: light skin tone # E12.1 [1] (🧑🏻‍🦽)
+1F9D1 1F3FC 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; health worker: medium-light skin tone # E12.1 [1] (🧑🏼‍⚕️)
+1F9D1 1F3FC 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; judge: medium-light skin tone # E12.1 [1] (🧑🏼‍⚖️)
+1F9D1 1F3FC 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; pilot: medium-light skin tone # E12.1 [1] (🧑🏼‍✈️)
+1F9D1 1F3FC 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; farmer: medium-light skin tone # E12.1 [1] (🧑🏼‍🌾)
+1F9D1 1F3FC 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; cook: medium-light skin tone # E12.1 [1] (🧑🏼‍🍳)
+1F9D1 1F3FC 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; person feeding baby: medium-light skin tone # E13.0 [1] (🧑🏼‍🍼)
+1F9D1 1F3FC 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; student: medium-light skin tone # E12.1 [1] (🧑🏼‍🎓)
+1F9D1 1F3FC 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; singer: medium-light skin tone # E12.1 [1] (🧑🏼‍🎤)
+1F9D1 1F3FC 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; artist: medium-light skin tone # E12.1 [1] (🧑🏼‍🎨)
+1F9D1 1F3FC 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; teacher: medium-light skin tone # E12.1 [1] (🧑🏼‍🏫)
+1F9D1 1F3FC 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; factory worker: medium-light skin tone # E12.1 [1] (🧑🏼‍🏭)
+1F9D1 1F3FC 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; technologist: medium-light skin tone # E12.1 [1] (🧑🏼‍💻)
+1F9D1 1F3FC 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; office worker: medium-light skin tone # E12.1 [1] (🧑🏼‍💼)
+1F9D1 1F3FC 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; mechanic: medium-light skin tone # E12.1 [1] (🧑🏼‍🔧)
+1F9D1 1F3FC 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; scientist: medium-light skin tone # E12.1 [1] (🧑🏼‍🔬)
+1F9D1 1F3FC 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; astronaut: medium-light skin tone # E12.1 [1] (🧑🏼‍🚀)
+1F9D1 1F3FC 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; firefighter: medium-light skin tone # E12.1 [1] (🧑🏼‍🚒)
+1F9D1 1F3FC 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; person with white cane: medium-light skin tone # E12.1 [1] (🧑🏼‍🦯)
+1F9D1 1F3FC 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair: medium-light skin tone # E12.1 [1] (🧑🏼‍🦼)
+1F9D1 1F3FC 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair: medium-light skin tone # E12.1 [1] (🧑🏼‍🦽)
+1F9D1 1F3FD 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; health worker: medium skin tone # E12.1 [1] (🧑🏽‍⚕️)
+1F9D1 1F3FD 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; judge: medium skin tone # E12.1 [1] (🧑🏽‍⚖️)
+1F9D1 1F3FD 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; pilot: medium skin tone # E12.1 [1] (🧑🏽‍✈️)
+1F9D1 1F3FD 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; farmer: medium skin tone # E12.1 [1] (🧑🏽‍🌾)
+1F9D1 1F3FD 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; cook: medium skin tone # E12.1 [1] (🧑🏽‍🍳)
+1F9D1 1F3FD 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; person feeding baby: medium skin tone # E13.0 [1] (🧑🏽‍🍼)
+1F9D1 1F3FD 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; student: medium skin tone # E12.1 [1] (🧑🏽‍🎓)
+1F9D1 1F3FD 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; singer: medium skin tone # E12.1 [1] (🧑🏽‍🎤)
+1F9D1 1F3FD 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; artist: medium skin tone # E12.1 [1] (🧑🏽‍🎨)
+1F9D1 1F3FD 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; teacher: medium skin tone # E12.1 [1] (🧑🏽‍🏫)
+1F9D1 1F3FD 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; factory worker: medium skin tone # E12.1 [1] (🧑🏽‍🏭)
+1F9D1 1F3FD 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; technologist: medium skin tone # E12.1 [1] (🧑🏽‍💻)
+1F9D1 1F3FD 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; office worker: medium skin tone # E12.1 [1] (🧑🏽‍💼)
+1F9D1 1F3FD 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; mechanic: medium skin tone # E12.1 [1] (🧑🏽‍🔧)
+1F9D1 1F3FD 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; scientist: medium skin tone # E12.1 [1] (🧑🏽‍🔬)
+1F9D1 1F3FD 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; astronaut: medium skin tone # E12.1 [1] (🧑🏽‍🚀)
+1F9D1 1F3FD 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; firefighter: medium skin tone # E12.1 [1] (🧑🏽‍🚒)
+1F9D1 1F3FD 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; person with white cane: medium skin tone # E12.1 [1] (🧑🏽‍🦯)
+1F9D1 1F3FD 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair: medium skin tone # E12.1 [1] (🧑🏽‍🦼)
+1F9D1 1F3FD 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair: medium skin tone # E12.1 [1] (🧑🏽‍🦽)
+1F9D1 1F3FE 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; health worker: medium-dark skin tone # E12.1 [1] (🧑🏾‍⚕️)
+1F9D1 1F3FE 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; judge: medium-dark skin tone # E12.1 [1] (🧑🏾‍⚖️)
+1F9D1 1F3FE 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; pilot: medium-dark skin tone # E12.1 [1] (🧑🏾‍✈️)
+1F9D1 1F3FE 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; farmer: medium-dark skin tone # E12.1 [1] (🧑🏾‍🌾)
+1F9D1 1F3FE 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; cook: medium-dark skin tone # E12.1 [1] (🧑🏾‍🍳)
+1F9D1 1F3FE 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; person feeding baby: medium-dark skin tone # E13.0 [1] (🧑🏾‍🍼)
+1F9D1 1F3FE 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; student: medium-dark skin tone # E12.1 [1] (🧑🏾‍🎓)
+1F9D1 1F3FE 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; singer: medium-dark skin tone # E12.1 [1] (🧑🏾‍🎤)
+1F9D1 1F3FE 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; artist: medium-dark skin tone # E12.1 [1] (🧑🏾‍🎨)
+1F9D1 1F3FE 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; teacher: medium-dark skin tone # E12.1 [1] (🧑🏾‍🏫)
+1F9D1 1F3FE 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; factory worker: medium-dark skin tone # E12.1 [1] (🧑🏾‍🏭)
+1F9D1 1F3FE 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; technologist: medium-dark skin tone # E12.1 [1] (🧑🏾‍💻)
+1F9D1 1F3FE 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; office worker: medium-dark skin tone # E12.1 [1] (🧑🏾‍💼)
+1F9D1 1F3FE 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; mechanic: medium-dark skin tone # E12.1 [1] (🧑🏾‍🔧)
+1F9D1 1F3FE 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; scientist: medium-dark skin tone # E12.1 [1] (🧑🏾‍🔬)
+1F9D1 1F3FE 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; astronaut: medium-dark skin tone # E12.1 [1] (🧑🏾‍🚀)
+1F9D1 1F3FE 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; firefighter: medium-dark skin tone # E12.1 [1] (🧑🏾‍🚒)
+1F9D1 1F3FE 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; person with white cane: medium-dark skin tone # E12.1 [1] (🧑🏾‍🦯)
+1F9D1 1F3FE 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair: medium-dark skin tone # E12.1 [1] (🧑🏾‍🦼)
+1F9D1 1F3FE 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair: medium-dark skin tone # E12.1 [1] (🧑🏾‍🦽)
+1F9D1 1F3FF 200D 2695 FE0F ; RGI_Emoji_ZWJ_Sequence ; health worker: dark skin tone # E12.1 [1] (🧑🏿‍⚕️)
+1F9D1 1F3FF 200D 2696 FE0F ; RGI_Emoji_ZWJ_Sequence ; judge: dark skin tone # E12.1 [1] (🧑🏿‍⚖️)
+1F9D1 1F3FF 200D 2708 FE0F ; RGI_Emoji_ZWJ_Sequence ; pilot: dark skin tone # E12.1 [1] (🧑🏿‍✈️)
+1F9D1 1F3FF 200D 1F33E ; RGI_Emoji_ZWJ_Sequence ; farmer: dark skin tone # E12.1 [1] (🧑🏿‍🌾)
+1F9D1 1F3FF 200D 1F373 ; RGI_Emoji_ZWJ_Sequence ; cook: dark skin tone # E12.1 [1] (🧑🏿‍🍳)
+1F9D1 1F3FF 200D 1F37C ; RGI_Emoji_ZWJ_Sequence ; person feeding baby: dark skin tone # E13.0 [1] (🧑🏿‍🍼)
+1F9D1 1F3FF 200D 1F393 ; RGI_Emoji_ZWJ_Sequence ; student: dark skin tone # E12.1 [1] (🧑🏿‍🎓)
+1F9D1 1F3FF 200D 1F3A4 ; RGI_Emoji_ZWJ_Sequence ; singer: dark skin tone # E12.1 [1] (🧑🏿‍🎤)
+1F9D1 1F3FF 200D 1F3A8 ; RGI_Emoji_ZWJ_Sequence ; artist: dark skin tone # E12.1 [1] (🧑🏿‍🎨)
+1F9D1 1F3FF 200D 1F3EB ; RGI_Emoji_ZWJ_Sequence ; teacher: dark skin tone # E12.1 [1] (🧑🏿‍🏫)
+1F9D1 1F3FF 200D 1F3ED ; RGI_Emoji_ZWJ_Sequence ; factory worker: dark skin tone # E12.1 [1] (🧑🏿‍🏭)
+1F9D1 1F3FF 200D 1F4BB ; RGI_Emoji_ZWJ_Sequence ; technologist: dark skin tone # E12.1 [1] (🧑🏿‍💻)
+1F9D1 1F3FF 200D 1F4BC ; RGI_Emoji_ZWJ_Sequence ; office worker: dark skin tone # E12.1 [1] (🧑🏿‍💼)
+1F9D1 1F3FF 200D 1F527 ; RGI_Emoji_ZWJ_Sequence ; mechanic: dark skin tone # E12.1 [1] (🧑🏿‍🔧)
+1F9D1 1F3FF 200D 1F52C ; RGI_Emoji_ZWJ_Sequence ; scientist: dark skin tone # E12.1 [1] (🧑🏿‍🔬)
+1F9D1 1F3FF 200D 1F680 ; RGI_Emoji_ZWJ_Sequence ; astronaut: dark skin tone # E12.1 [1] (🧑🏿‍🚀)
+1F9D1 1F3FF 200D 1F692 ; RGI_Emoji_ZWJ_Sequence ; firefighter: dark skin tone # E12.1 [1] (🧑🏿‍🚒)
+1F9D1 1F3FF 200D 1F9AF ; RGI_Emoji_ZWJ_Sequence ; person with white cane: dark skin tone # E12.1 [1] (🧑🏿‍🦯)
+1F9D1 1F3FF 200D 1F9BC ; RGI_Emoji_ZWJ_Sequence ; person in motorized wheelchair: dark skin tone # E12.1 [1] (🧑🏿‍🦼)
+1F9D1 1F3FF 200D 1F9BD ; RGI_Emoji_ZWJ_Sequence ; person in manual wheelchair: dark skin tone # E12.1 [1] (🧑🏿‍🦽)
+
+# Total elements: 360
+
+# ================================================
+
+# RGI_Emoji_ZWJ_Sequence: Gendered
+
+26F9 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bouncing ball: light skin tone # E4.0 [1] (⛹🏻‍♀️)
+26F9 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bouncing ball: light skin tone # E4.0 [1] (⛹🏻‍♂️)
+26F9 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bouncing ball: medium-light skin tone # E4.0 [1] (⛹🏼‍♀️)
+26F9 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bouncing ball: medium-light skin tone # E4.0 [1] (⛹🏼‍♂️)
+26F9 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bouncing ball: medium skin tone # E4.0 [1] (⛹🏽‍♀️)
+26F9 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bouncing ball: medium skin tone # E4.0 [1] (⛹🏽‍♂️)
+26F9 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bouncing ball: medium-dark skin tone # E4.0 [1] (⛹🏾‍♀️)
+26F9 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bouncing ball: medium-dark skin tone # E4.0 [1] (⛹🏾‍♂️)
+26F9 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bouncing ball: dark skin tone # E4.0 [1] (⛹🏿‍♀️)
+26F9 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bouncing ball: dark skin tone # E4.0 [1] (⛹🏿‍♂️)
+26F9 FE0F 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bouncing ball # E4.0 [1] (⛹️‍♀️)
+26F9 FE0F 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bouncing ball # E4.0 [1] (⛹️‍♂️)
+1F3C3 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running # E4.0 [1] (🏃‍♀️)
+1F3C3 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running # E4.0 [1] (🏃‍♂️)
+1F3C3 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running: light skin tone # E4.0 [1] (🏃🏻‍♀️)
+1F3C3 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running: light skin tone # E4.0 [1] (🏃🏻‍♂️)
+1F3C3 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running: medium-light skin tone # E4.0 [1] (🏃🏼‍♀️)
+1F3C3 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running: medium-light skin tone # E4.0 [1] (🏃🏼‍♂️)
+1F3C3 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running: medium skin tone # E4.0 [1] (🏃🏽‍♀️)
+1F3C3 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running: medium skin tone # E4.0 [1] (🏃🏽‍♂️)
+1F3C3 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running: medium-dark skin tone # E4.0 [1] (🏃🏾‍♀️)
+1F3C3 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running: medium-dark skin tone # E4.0 [1] (🏃🏾‍♂️)
+1F3C3 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman running: dark skin tone # E4.0 [1] (🏃🏿‍♀️)
+1F3C3 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man running: dark skin tone # E4.0 [1] (🏃🏿‍♂️)
+1F3C4 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman surfing # E4.0 [1] (🏄‍♀️)
+1F3C4 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man surfing # E4.0 [1] (🏄‍♂️)
+1F3C4 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman surfing: light skin tone # E4.0 [1] (🏄🏻‍♀️)
+1F3C4 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man surfing: light skin tone # E4.0 [1] (🏄🏻‍♂️)
+1F3C4 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman surfing: medium-light skin tone # E4.0 [1] (🏄🏼‍♀️)
+1F3C4 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man surfing: medium-light skin tone # E4.0 [1] (🏄🏼‍♂️)
+1F3C4 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman surfing: medium skin tone # E4.0 [1] (🏄🏽‍♀️)
+1F3C4 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man surfing: medium skin tone # E4.0 [1] (🏄🏽‍♂️)
+1F3C4 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman surfing: medium-dark skin tone # E4.0 [1] (🏄🏾‍♀️)
+1F3C4 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man surfing: medium-dark skin tone # E4.0 [1] (🏄🏾‍♂️)
+1F3C4 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman surfing: dark skin tone # E4.0 [1] (🏄🏿‍♀️)
+1F3C4 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man surfing: dark skin tone # E4.0 [1] (🏄🏿‍♂️)
+1F3CA 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman swimming # E4.0 [1] (🏊‍♀️)
+1F3CA 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man swimming # E4.0 [1] (🏊‍♂️)
+1F3CA 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman swimming: light skin tone # E4.0 [1] (🏊🏻‍♀️)
+1F3CA 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man swimming: light skin tone # E4.0 [1] (🏊🏻‍♂️)
+1F3CA 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman swimming: medium-light skin tone # E4.0 [1] (🏊🏼‍♀️)
+1F3CA 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man swimming: medium-light skin tone # E4.0 [1] (🏊🏼‍♂️)
+1F3CA 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman swimming: medium skin tone # E4.0 [1] (🏊🏽‍♀️)
+1F3CA 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man swimming: medium skin tone # E4.0 [1] (🏊🏽‍♂️)
+1F3CA 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman swimming: medium-dark skin tone # E4.0 [1] (🏊🏾‍♀️)
+1F3CA 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man swimming: medium-dark skin tone # E4.0 [1] (🏊🏾‍♂️)
+1F3CA 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman swimming: dark skin tone # E4.0 [1] (🏊🏿‍♀️)
+1F3CA 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man swimming: dark skin tone # E4.0 [1] (🏊🏿‍♂️)
+1F3CB 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman lifting weights: light skin tone # E4.0 [1] (🏋🏻‍♀️)
+1F3CB 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man lifting weights: light skin tone # E4.0 [1] (🏋🏻‍♂️)
+1F3CB 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman lifting weights: medium-light skin tone # E4.0 [1] (🏋🏼‍♀️)
+1F3CB 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man lifting weights: medium-light skin tone # E4.0 [1] (🏋🏼‍♂️)
+1F3CB 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman lifting weights: medium skin tone # E4.0 [1] (🏋🏽‍♀️)
+1F3CB 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man lifting weights: medium skin tone # E4.0 [1] (🏋🏽‍♂️)
+1F3CB 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman lifting weights: medium-dark skin tone # E4.0 [1] (🏋🏾‍♀️)
+1F3CB 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man lifting weights: medium-dark skin tone # E4.0 [1] (🏋🏾‍♂️)
+1F3CB 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman lifting weights: dark skin tone # E4.0 [1] (🏋🏿‍♀️)
+1F3CB 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man lifting weights: dark skin tone # E4.0 [1] (🏋🏿‍♂️)
+1F3CB FE0F 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman lifting weights # E4.0 [1] (🏋️‍♀️)
+1F3CB FE0F 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man lifting weights # E4.0 [1] (🏋️‍♂️)
+1F3CC 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman golfing: light skin tone # E4.0 [1] (🏌🏻‍♀️)
+1F3CC 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man golfing: light skin tone # E4.0 [1] (🏌🏻‍♂️)
+1F3CC 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman golfing: medium-light skin tone # E4.0 [1] (🏌🏼‍♀️)
+1F3CC 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man golfing: medium-light skin tone # E4.0 [1] (🏌🏼‍♂️)
+1F3CC 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman golfing: medium skin tone # E4.0 [1] (🏌🏽‍♀️)
+1F3CC 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man golfing: medium skin tone # E4.0 [1] (🏌🏽‍♂️)
+1F3CC 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman golfing: medium-dark skin tone # E4.0 [1] (🏌🏾‍♀️)
+1F3CC 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man golfing: medium-dark skin tone # E4.0 [1] (🏌🏾‍♂️)
+1F3CC 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman golfing: dark skin tone # E4.0 [1] (🏌🏿‍♀️)
+1F3CC 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man golfing: dark skin tone # E4.0 [1] (🏌🏿‍♂️)
+1F3CC FE0F 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman golfing # E4.0 [1] (🏌️‍♀️)
+1F3CC FE0F 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man golfing # E4.0 [1] (🏌️‍♂️)
+1F46E 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman police officer # E4.0 [1] (👮‍♀️)
+1F46E 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man police officer # E4.0 [1] (👮‍♂️)
+1F46E 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman police officer: light skin tone # E4.0 [1] (👮🏻‍♀️)
+1F46E 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man police officer: light skin tone # E4.0 [1] (👮🏻‍♂️)
+1F46E 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman police officer: medium-light skin tone # E4.0 [1] (👮🏼‍♀️)
+1F46E 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man police officer: medium-light skin tone # E4.0 [1] (👮🏼‍♂️)
+1F46E 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman police officer: medium skin tone # E4.0 [1] (👮🏽‍♀️)
+1F46E 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man police officer: medium skin tone # E4.0 [1] (👮🏽‍♂️)
+1F46E 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman police officer: medium-dark skin tone # E4.0 [1] (👮🏾‍♀️)
+1F46E 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man police officer: medium-dark skin tone # E4.0 [1] (👮🏾‍♂️)
+1F46E 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman police officer: dark skin tone # E4.0 [1] (👮🏿‍♀️)
+1F46E 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man police officer: dark skin tone # E4.0 [1] (👮🏿‍♂️)
+1F46F 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; women with bunny ears # E4.0 [1] (👯‍♀️)
+1F46F 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; men with bunny ears # E4.0 [1] (👯‍♂️)
+1F470 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with veil # E13.0 [1] (👰‍♀️)
+1F470 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with veil # E13.0 [1] (👰‍♂️)
+1F470 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with veil: light skin tone # E13.0 [1] (👰🏻‍♀️)
+1F470 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with veil: light skin tone # E13.0 [1] (👰🏻‍♂️)
+1F470 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with veil: medium-light skin tone # E13.0 [1] (👰🏼‍♀️)
+1F470 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with veil: medium-light skin tone # E13.0 [1] (👰🏼‍♂️)
+1F470 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with veil: medium skin tone # E13.0 [1] (👰🏽‍♀️)
+1F470 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with veil: medium skin tone # E13.0 [1] (👰🏽‍♂️)
+1F470 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with veil: medium-dark skin tone # E13.0 [1] (👰🏾‍♀️)
+1F470 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with veil: medium-dark skin tone # E13.0 [1] (👰🏾‍♂️)
+1F470 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman with veil: dark skin tone # E13.0 [1] (👰🏿‍♀️)
+1F470 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man with veil: dark skin tone # E13.0 [1] (👰🏿‍♂️)
+1F471 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: blond hair # E4.0 [1] (👱‍♀️)
+1F471 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: blond hair # E4.0 [1] (👱‍♂️)
+1F471 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: light skin tone, blond hair # E4.0 [1] (👱🏻‍♀️)
+1F471 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: light skin tone, blond hair # E4.0 [1] (👱🏻‍♂️)
+1F471 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: medium-light skin tone, blond hair # E4.0 [1] (👱🏼‍♀️)
+1F471 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: medium-light skin tone, blond hair # E4.0 [1] (👱🏼‍♂️)
+1F471 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: medium skin tone, blond hair # E4.0 [1] (👱🏽‍♀️)
+1F471 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: medium skin tone, blond hair # E4.0 [1] (👱🏽‍♂️)
+1F471 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: medium-dark skin tone, blond hair # E4.0 [1] (👱🏾‍♀️)
+1F471 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: medium-dark skin tone, blond hair # E4.0 [1] (👱🏾‍♂️)
+1F471 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: dark skin tone, blond hair # E4.0 [1] (👱🏿‍♀️)
+1F471 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: dark skin tone, blond hair # E4.0 [1] (👱🏿‍♂️)
+1F473 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman wearing turban # E4.0 [1] (👳‍♀️)
+1F473 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man wearing turban # E4.0 [1] (👳‍♂️)
+1F473 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman wearing turban: light skin tone # E4.0 [1] (👳🏻‍♀️)
+1F473 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man wearing turban: light skin tone # E4.0 [1] (👳🏻‍♂️)
+1F473 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman wearing turban: medium-light skin tone # E4.0 [1] (👳🏼‍♀️)
+1F473 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man wearing turban: medium-light skin tone # E4.0 [1] (👳🏼‍♂️)
+1F473 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman wearing turban: medium skin tone # E4.0 [1] (👳🏽‍♀️)
+1F473 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man wearing turban: medium skin tone # E4.0 [1] (👳🏽‍♂️)
+1F473 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman wearing turban: medium-dark skin tone # E4.0 [1] (👳🏾‍♀️)
+1F473 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man wearing turban: medium-dark skin tone # E4.0 [1] (👳🏾‍♂️)
+1F473 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman wearing turban: dark skin tone # E4.0 [1] (👳🏿‍♀️)
+1F473 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man wearing turban: dark skin tone # E4.0 [1] (👳🏿‍♂️)
+1F477 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman construction worker # E4.0 [1] (👷‍♀️)
+1F477 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man construction worker # E4.0 [1] (👷‍♂️)
+1F477 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman construction worker: light skin tone # E4.0 [1] (👷🏻‍♀️)
+1F477 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man construction worker: light skin tone # E4.0 [1] (👷🏻‍♂️)
+1F477 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman construction worker: medium-light skin tone # E4.0 [1] (👷🏼‍♀️)
+1F477 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man construction worker: medium-light skin tone # E4.0 [1] (👷🏼‍♂️)
+1F477 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman construction worker: medium skin tone # E4.0 [1] (👷🏽‍♀️)
+1F477 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man construction worker: medium skin tone # E4.0 [1] (👷🏽‍♂️)
+1F477 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman construction worker: medium-dark skin tone # E4.0 [1] (👷🏾‍♀️)
+1F477 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man construction worker: medium-dark skin tone # E4.0 [1] (👷🏾‍♂️)
+1F477 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman construction worker: dark skin tone # E4.0 [1] (👷🏿‍♀️)
+1F477 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man construction worker: dark skin tone # E4.0 [1] (👷🏿‍♂️)
+1F481 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman tipping hand # E4.0 [1] (💁‍♀️)
+1F481 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man tipping hand # E4.0 [1] (💁‍♂️)
+1F481 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman tipping hand: light skin tone # E4.0 [1] (💁🏻‍♀️)
+1F481 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man tipping hand: light skin tone # E4.0 [1] (💁🏻‍♂️)
+1F481 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman tipping hand: medium-light skin tone # E4.0 [1] (💁🏼‍♀️)
+1F481 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man tipping hand: medium-light skin tone # E4.0 [1] (💁🏼‍♂️)
+1F481 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman tipping hand: medium skin tone # E4.0 [1] (💁🏽‍♀️)
+1F481 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man tipping hand: medium skin tone # E4.0 [1] (💁🏽‍♂️)
+1F481 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman tipping hand: medium-dark skin tone # E4.0 [1] (💁🏾‍♀️)
+1F481 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man tipping hand: medium-dark skin tone # E4.0 [1] (💁🏾‍♂️)
+1F481 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman tipping hand: dark skin tone # E4.0 [1] (💁🏿‍♀️)
+1F481 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man tipping hand: dark skin tone # E4.0 [1] (💁🏿‍♂️)
+1F482 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman guard # E4.0 [1] (💂‍♀️)
+1F482 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man guard # E4.0 [1] (💂‍♂️)
+1F482 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman guard: light skin tone # E4.0 [1] (💂🏻‍♀️)
+1F482 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man guard: light skin tone # E4.0 [1] (💂🏻‍♂️)
+1F482 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman guard: medium-light skin tone # E4.0 [1] (💂🏼‍♀️)
+1F482 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man guard: medium-light skin tone # E4.0 [1] (💂🏼‍♂️)
+1F482 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman guard: medium skin tone # E4.0 [1] (💂🏽‍♀️)
+1F482 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man guard: medium skin tone # E4.0 [1] (💂🏽‍♂️)
+1F482 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman guard: medium-dark skin tone # E4.0 [1] (💂🏾‍♀️)
+1F482 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man guard: medium-dark skin tone # E4.0 [1] (💂🏾‍♂️)
+1F482 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman guard: dark skin tone # E4.0 [1] (💂🏿‍♀️)
+1F482 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man guard: dark skin tone # E4.0 [1] (💂🏿‍♂️)
+1F486 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting massage # E4.0 [1] (💆‍♀️)
+1F486 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting massage # E4.0 [1] (💆‍♂️)
+1F486 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting massage: light skin tone # E4.0 [1] (💆🏻‍♀️)
+1F486 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting massage: light skin tone # E4.0 [1] (💆🏻‍♂️)
+1F486 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting massage: medium-light skin tone # E4.0 [1] (💆🏼‍♀️)
+1F486 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting massage: medium-light skin tone # E4.0 [1] (💆🏼‍♂️)
+1F486 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting massage: medium skin tone # E4.0 [1] (💆🏽‍♀️)
+1F486 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting massage: medium skin tone # E4.0 [1] (💆🏽‍♂️)
+1F486 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting massage: medium-dark skin tone # E4.0 [1] (💆🏾‍♀️)
+1F486 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting massage: medium-dark skin tone # E4.0 [1] (💆🏾‍♂️)
+1F486 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting massage: dark skin tone # E4.0 [1] (💆🏿‍♀️)
+1F486 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting massage: dark skin tone # E4.0 [1] (💆🏿‍♂️)
+1F487 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting haircut # E4.0 [1] (💇‍♀️)
+1F487 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting haircut # E4.0 [1] (💇‍♂️)
+1F487 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting haircut: light skin tone # E4.0 [1] (💇🏻‍♀️)
+1F487 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting haircut: light skin tone # E4.0 [1] (💇🏻‍♂️)
+1F487 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting haircut: medium-light skin tone # E4.0 [1] (💇🏼‍♀️)
+1F487 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting haircut: medium-light skin tone # E4.0 [1] (💇🏼‍♂️)
+1F487 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting haircut: medium skin tone # E4.0 [1] (💇🏽‍♀️)
+1F487 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting haircut: medium skin tone # E4.0 [1] (💇🏽‍♂️)
+1F487 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting haircut: medium-dark skin tone # E4.0 [1] (💇🏾‍♀️)
+1F487 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting haircut: medium-dark skin tone # E4.0 [1] (💇🏾‍♂️)
+1F487 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman getting haircut: dark skin tone # E4.0 [1] (💇🏿‍♀️)
+1F487 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man getting haircut: dark skin tone # E4.0 [1] (💇🏿‍♂️)
+1F575 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman detective: light skin tone # E4.0 [1] (🕵🏻‍♀️)
+1F575 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man detective: light skin tone # E4.0 [1] (🕵🏻‍♂️)
+1F575 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman detective: medium-light skin tone # E4.0 [1] (🕵🏼‍♀️)
+1F575 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man detective: medium-light skin tone # E4.0 [1] (🕵🏼‍♂️)
+1F575 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman detective: medium skin tone # E4.0 [1] (🕵🏽‍♀️)
+1F575 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man detective: medium skin tone # E4.0 [1] (🕵🏽‍♂️)
+1F575 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman detective: medium-dark skin tone # E4.0 [1] (🕵🏾‍♀️)
+1F575 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man detective: medium-dark skin tone # E4.0 [1] (🕵🏾‍♂️)
+1F575 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman detective: dark skin tone # E4.0 [1] (🕵🏿‍♀️)
+1F575 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man detective: dark skin tone # E4.0 [1] (🕵🏿‍♂️)
+1F575 FE0F 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman detective # E4.0 [1] (🕵️‍♀️)
+1F575 FE0F 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man detective # E4.0 [1] (🕵️‍♂️)
+1F645 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing NO # E4.0 [1] (🙅‍♀️)
+1F645 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing NO # E4.0 [1] (🙅‍♂️)
+1F645 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing NO: light skin tone # E4.0 [1] (🙅🏻‍♀️)
+1F645 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing NO: light skin tone # E4.0 [1] (🙅🏻‍♂️)
+1F645 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing NO: medium-light skin tone # E4.0 [1] (🙅🏼‍♀️)
+1F645 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing NO: medium-light skin tone # E4.0 [1] (🙅🏼‍♂️)
+1F645 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing NO: medium skin tone # E4.0 [1] (🙅🏽‍♀️)
+1F645 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing NO: medium skin tone # E4.0 [1] (🙅🏽‍♂️)
+1F645 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing NO: medium-dark skin tone # E4.0 [1] (🙅🏾‍♀️)
+1F645 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing NO: medium-dark skin tone # E4.0 [1] (🙅🏾‍♂️)
+1F645 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing NO: dark skin tone # E4.0 [1] (🙅🏿‍♀️)
+1F645 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing NO: dark skin tone # E4.0 [1] (🙅🏿‍♂️)
+1F646 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing OK # E4.0 [1] (🙆‍♀️)
+1F646 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing OK # E4.0 [1] (🙆‍♂️)
+1F646 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing OK: light skin tone # E4.0 [1] (🙆🏻‍♀️)
+1F646 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing OK: light skin tone # E4.0 [1] (🙆🏻‍♂️)
+1F646 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing OK: medium-light skin tone # E4.0 [1] (🙆🏼‍♀️)
+1F646 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing OK: medium-light skin tone # E4.0 [1] (🙆🏼‍♂️)
+1F646 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing OK: medium skin tone # E4.0 [1] (🙆🏽‍♀️)
+1F646 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing OK: medium skin tone # E4.0 [1] (🙆🏽‍♂️)
+1F646 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing OK: medium-dark skin tone # E4.0 [1] (🙆🏾‍♀️)
+1F646 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing OK: medium-dark skin tone # E4.0 [1] (🙆🏾‍♂️)
+1F646 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman gesturing OK: dark skin tone # E4.0 [1] (🙆🏿‍♀️)
+1F646 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man gesturing OK: dark skin tone # E4.0 [1] (🙆🏿‍♂️)
+1F647 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bowing # E4.0 [1] (🙇‍♀️)
+1F647 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bowing # E4.0 [1] (🙇‍♂️)
+1F647 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bowing: light skin tone # E4.0 [1] (🙇🏻‍♀️)
+1F647 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bowing: light skin tone # E4.0 [1] (🙇🏻‍♂️)
+1F647 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bowing: medium-light skin tone # E4.0 [1] (🙇🏼‍♀️)
+1F647 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bowing: medium-light skin tone # E4.0 [1] (🙇🏼‍♂️)
+1F647 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bowing: medium skin tone # E4.0 [1] (🙇🏽‍♀️)
+1F647 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bowing: medium skin tone # E4.0 [1] (🙇🏽‍♂️)
+1F647 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bowing: medium-dark skin tone # E4.0 [1] (🙇🏾‍♀️)
+1F647 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bowing: medium-dark skin tone # E4.0 [1] (🙇🏾‍♂️)
+1F647 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman bowing: dark skin tone # E4.0 [1] (🙇🏿‍♀️)
+1F647 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man bowing: dark skin tone # E4.0 [1] (🙇🏿‍♂️)
+1F64B 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman raising hand # E4.0 [1] (🙋‍♀️)
+1F64B 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man raising hand # E4.0 [1] (🙋‍♂️)
+1F64B 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman raising hand: light skin tone # E4.0 [1] (🙋🏻‍♀️)
+1F64B 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man raising hand: light skin tone # E4.0 [1] (🙋🏻‍♂️)
+1F64B 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman raising hand: medium-light skin tone # E4.0 [1] (🙋🏼‍♀️)
+1F64B 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man raising hand: medium-light skin tone # E4.0 [1] (🙋🏼‍♂️)
+1F64B 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman raising hand: medium skin tone # E4.0 [1] (🙋🏽‍♀️)
+1F64B 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man raising hand: medium skin tone # E4.0 [1] (🙋🏽‍♂️)
+1F64B 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman raising hand: medium-dark skin tone # E4.0 [1] (🙋🏾‍♀️)
+1F64B 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man raising hand: medium-dark skin tone # E4.0 [1] (🙋🏾‍♂️)
+1F64B 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman raising hand: dark skin tone # E4.0 [1] (🙋🏿‍♀️)
+1F64B 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man raising hand: dark skin tone # E4.0 [1] (🙋🏿‍♂️)
+1F64D 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman frowning # E4.0 [1] (🙍‍♀️)
+1F64D 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man frowning # E4.0 [1] (🙍‍♂️)
+1F64D 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman frowning: light skin tone # E4.0 [1] (🙍🏻‍♀️)
+1F64D 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man frowning: light skin tone # E4.0 [1] (🙍🏻‍♂️)
+1F64D 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman frowning: medium-light skin tone # E4.0 [1] (🙍🏼‍♀️)
+1F64D 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man frowning: medium-light skin tone # E4.0 [1] (🙍🏼‍♂️)
+1F64D 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman frowning: medium skin tone # E4.0 [1] (🙍🏽‍♀️)
+1F64D 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man frowning: medium skin tone # E4.0 [1] (🙍🏽‍♂️)
+1F64D 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman frowning: medium-dark skin tone # E4.0 [1] (🙍🏾‍♀️)
+1F64D 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man frowning: medium-dark skin tone # E4.0 [1] (🙍🏾‍♂️)
+1F64D 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman frowning: dark skin tone # E4.0 [1] (🙍🏿‍♀️)
+1F64D 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man frowning: dark skin tone # E4.0 [1] (🙍🏿‍♂️)
+1F64E 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pouting # E4.0 [1] (🙎‍♀️)
+1F64E 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pouting # E4.0 [1] (🙎‍♂️)
+1F64E 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pouting: light skin tone # E4.0 [1] (🙎🏻‍♀️)
+1F64E 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pouting: light skin tone # E4.0 [1] (🙎🏻‍♂️)
+1F64E 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pouting: medium-light skin tone # E4.0 [1] (🙎🏼‍♀️)
+1F64E 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pouting: medium-light skin tone # E4.0 [1] (🙎🏼‍♂️)
+1F64E 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pouting: medium skin tone # E4.0 [1] (🙎🏽‍♀️)
+1F64E 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pouting: medium skin tone # E4.0 [1] (🙎🏽‍♂️)
+1F64E 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pouting: medium-dark skin tone # E4.0 [1] (🙎🏾‍♀️)
+1F64E 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pouting: medium-dark skin tone # E4.0 [1] (🙎🏾‍♂️)
+1F64E 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman pouting: dark skin tone # E4.0 [1] (🙎🏿‍♀️)
+1F64E 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man pouting: dark skin tone # E4.0 [1] (🙎🏿‍♂️)
+1F6A3 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman rowing boat # E4.0 [1] (🚣‍♀️)
+1F6A3 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man rowing boat # E4.0 [1] (🚣‍♂️)
+1F6A3 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman rowing boat: light skin tone # E4.0 [1] (🚣🏻‍♀️)
+1F6A3 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man rowing boat: light skin tone # E4.0 [1] (🚣🏻‍♂️)
+1F6A3 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman rowing boat: medium-light skin tone # E4.0 [1] (🚣🏼‍♀️)
+1F6A3 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man rowing boat: medium-light skin tone # E4.0 [1] (🚣🏼‍♂️)
+1F6A3 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman rowing boat: medium skin tone # E4.0 [1] (🚣🏽‍♀️)
+1F6A3 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man rowing boat: medium skin tone # E4.0 [1] (🚣🏽‍♂️)
+1F6A3 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman rowing boat: medium-dark skin tone # E4.0 [1] (🚣🏾‍♀️)
+1F6A3 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man rowing boat: medium-dark skin tone # E4.0 [1] (🚣🏾‍♂️)
+1F6A3 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman rowing boat: dark skin tone # E4.0 [1] (🚣🏿‍♀️)
+1F6A3 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man rowing boat: dark skin tone # E4.0 [1] (🚣🏿‍♂️)
+1F6B4 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman biking # E4.0 [1] (🚴‍♀️)
+1F6B4 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man biking # E4.0 [1] (🚴‍♂️)
+1F6B4 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman biking: light skin tone # E4.0 [1] (🚴🏻‍♀️)
+1F6B4 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man biking: light skin tone # E4.0 [1] (🚴🏻‍♂️)
+1F6B4 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman biking: medium-light skin tone # E4.0 [1] (🚴🏼‍♀️)
+1F6B4 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man biking: medium-light skin tone # E4.0 [1] (🚴🏼‍♂️)
+1F6B4 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman biking: medium skin tone # E4.0 [1] (🚴🏽‍♀️)
+1F6B4 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man biking: medium skin tone # E4.0 [1] (🚴🏽‍♂️)
+1F6B4 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman biking: medium-dark skin tone # E4.0 [1] (🚴🏾‍♀️)
+1F6B4 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man biking: medium-dark skin tone # E4.0 [1] (🚴🏾‍♂️)
+1F6B4 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman biking: dark skin tone # E4.0 [1] (🚴🏿‍♀️)
+1F6B4 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man biking: dark skin tone # E4.0 [1] (🚴🏿‍♂️)
+1F6B5 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mountain biking # E4.0 [1] (🚵‍♀️)
+1F6B5 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mountain biking # E4.0 [1] (🚵‍♂️)
+1F6B5 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mountain biking: light skin tone # E4.0 [1] (🚵🏻‍♀️)
+1F6B5 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mountain biking: light skin tone # E4.0 [1] (🚵🏻‍♂️)
+1F6B5 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mountain biking: medium-light skin tone # E4.0 [1] (🚵🏼‍♀️)
+1F6B5 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mountain biking: medium-light skin tone # E4.0 [1] (🚵🏼‍♂️)
+1F6B5 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mountain biking: medium skin tone # E4.0 [1] (🚵🏽‍♀️)
+1F6B5 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mountain biking: medium skin tone # E4.0 [1] (🚵🏽‍♂️)
+1F6B5 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mountain biking: medium-dark skin tone # E4.0 [1] (🚵🏾‍♀️)
+1F6B5 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mountain biking: medium-dark skin tone # E4.0 [1] (🚵🏾‍♂️)
+1F6B5 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mountain biking: dark skin tone # E4.0 [1] (🚵🏿‍♀️)
+1F6B5 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mountain biking: dark skin tone # E4.0 [1] (🚵🏿‍♂️)
+1F6B6 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking # E4.0 [1] (🚶‍♀️)
+1F6B6 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking # E4.0 [1] (🚶‍♂️)
+1F6B6 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking: light skin tone # E4.0 [1] (🚶🏻‍♀️)
+1F6B6 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking: light skin tone # E4.0 [1] (🚶🏻‍♂️)
+1F6B6 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking: medium-light skin tone # E4.0 [1] (🚶🏼‍♀️)
+1F6B6 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking: medium-light skin tone # E4.0 [1] (🚶🏼‍♂️)
+1F6B6 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking: medium skin tone # E4.0 [1] (🚶🏽‍♀️)
+1F6B6 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking: medium skin tone # E4.0 [1] (🚶🏽‍♂️)
+1F6B6 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking: medium-dark skin tone # E4.0 [1] (🚶🏾‍♀️)
+1F6B6 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking: medium-dark skin tone # E4.0 [1] (🚶🏾‍♂️)
+1F6B6 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman walking: dark skin tone # E4.0 [1] (🚶🏿‍♀️)
+1F6B6 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man walking: dark skin tone # E4.0 [1] (🚶🏿‍♂️)
+1F926 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman facepalming # E4.0 [1] (🤦‍♀️)
+1F926 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man facepalming # E4.0 [1] (🤦‍♂️)
+1F926 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman facepalming: light skin tone # E4.0 [1] (🤦🏻‍♀️)
+1F926 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man facepalming: light skin tone # E4.0 [1] (🤦🏻‍♂️)
+1F926 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman facepalming: medium-light skin tone # E4.0 [1] (🤦🏼‍♀️)
+1F926 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man facepalming: medium-light skin tone # E4.0 [1] (🤦🏼‍♂️)
+1F926 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman facepalming: medium skin tone # E4.0 [1] (🤦🏽‍♀️)
+1F926 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man facepalming: medium skin tone # E4.0 [1] (🤦🏽‍♂️)
+1F926 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman facepalming: medium-dark skin tone # E4.0 [1] (🤦🏾‍♀️)
+1F926 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man facepalming: medium-dark skin tone # E4.0 [1] (🤦🏾‍♂️)
+1F926 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman facepalming: dark skin tone # E4.0 [1] (🤦🏿‍♀️)
+1F926 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man facepalming: dark skin tone # E4.0 [1] (🤦🏿‍♂️)
+1F935 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in tuxedo # E13.0 [1] (🤵‍♀️)
+1F935 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in tuxedo # E13.0 [1] (🤵‍♂️)
+1F935 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in tuxedo: light skin tone # E13.0 [1] (🤵🏻‍♀️)
+1F935 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in tuxedo: light skin tone # E13.0 [1] (🤵🏻‍♂️)
+1F935 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in tuxedo: medium-light skin tone # E13.0 [1] (🤵🏼‍♀️)
+1F935 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in tuxedo: medium-light skin tone # E13.0 [1] (🤵🏼‍♂️)
+1F935 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in tuxedo: medium skin tone # E13.0 [1] (🤵🏽‍♀️)
+1F935 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in tuxedo: medium skin tone # E13.0 [1] (🤵🏽‍♂️)
+1F935 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in tuxedo: medium-dark skin tone # E13.0 [1] (🤵🏾‍♀️)
+1F935 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in tuxedo: medium-dark skin tone # E13.0 [1] (🤵🏾‍♂️)
+1F935 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in tuxedo: dark skin tone # E13.0 [1] (🤵🏿‍♀️)
+1F935 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in tuxedo: dark skin tone # E13.0 [1] (🤵🏿‍♂️)
+1F937 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman shrugging # E4.0 [1] (🤷‍♀️)
+1F937 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man shrugging # E4.0 [1] (🤷‍♂️)
+1F937 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman shrugging: light skin tone # E4.0 [1] (🤷🏻‍♀️)
+1F937 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man shrugging: light skin tone # E4.0 [1] (🤷🏻‍♂️)
+1F937 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman shrugging: medium-light skin tone # E4.0 [1] (🤷🏼‍♀️)
+1F937 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man shrugging: medium-light skin tone # E4.0 [1] (🤷🏼‍♂️)
+1F937 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman shrugging: medium skin tone # E4.0 [1] (🤷🏽‍♀️)
+1F937 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man shrugging: medium skin tone # E4.0 [1] (🤷🏽‍♂️)
+1F937 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman shrugging: medium-dark skin tone # E4.0 [1] (🤷🏾‍♀️)
+1F937 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man shrugging: medium-dark skin tone # E4.0 [1] (🤷🏾‍♂️)
+1F937 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman shrugging: dark skin tone # E4.0 [1] (🤷🏿‍♀️)
+1F937 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man shrugging: dark skin tone # E4.0 [1] (🤷🏿‍♂️)
+1F938 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman cartwheeling # E4.0 [1] (🤸‍♀️)
+1F938 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man cartwheeling # E4.0 [1] (🤸‍♂️)
+1F938 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman cartwheeling: light skin tone # E4.0 [1] (🤸🏻‍♀️)
+1F938 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man cartwheeling: light skin tone # E4.0 [1] (🤸🏻‍♂️)
+1F938 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman cartwheeling: medium-light skin tone # E4.0 [1] (🤸🏼‍♀️)
+1F938 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man cartwheeling: medium-light skin tone # E4.0 [1] (🤸🏼‍♂️)
+1F938 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman cartwheeling: medium skin tone # E4.0 [1] (🤸🏽‍♀️)
+1F938 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man cartwheeling: medium skin tone # E4.0 [1] (🤸🏽‍♂️)
+1F938 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman cartwheeling: medium-dark skin tone # E4.0 [1] (🤸🏾‍♀️)
+1F938 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man cartwheeling: medium-dark skin tone # E4.0 [1] (🤸🏾‍♂️)
+1F938 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman cartwheeling: dark skin tone # E4.0 [1] (🤸🏿‍♀️)
+1F938 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man cartwheeling: dark skin tone # E4.0 [1] (🤸🏿‍♂️)
+1F939 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman juggling # E4.0 [1] (🤹‍♀️)
+1F939 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man juggling # E4.0 [1] (🤹‍♂️)
+1F939 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman juggling: light skin tone # E4.0 [1] (🤹🏻‍♀️)
+1F939 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man juggling: light skin tone # E4.0 [1] (🤹🏻‍♂️)
+1F939 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman juggling: medium-light skin tone # E4.0 [1] (🤹🏼‍♀️)
+1F939 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man juggling: medium-light skin tone # E4.0 [1] (🤹🏼‍♂️)
+1F939 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman juggling: medium skin tone # E4.0 [1] (🤹🏽‍♀️)
+1F939 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man juggling: medium skin tone # E4.0 [1] (🤹🏽‍♂️)
+1F939 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman juggling: medium-dark skin tone # E4.0 [1] (🤹🏾‍♀️)
+1F939 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man juggling: medium-dark skin tone # E4.0 [1] (🤹🏾‍♂️)
+1F939 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman juggling: dark skin tone # E4.0 [1] (🤹🏿‍♀️)
+1F939 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man juggling: dark skin tone # E4.0 [1] (🤹🏿‍♂️)
+1F93C 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; women wrestling # E4.0 [1] (🤼‍♀️)
+1F93C 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; men wrestling # E4.0 [1] (🤼‍♂️)
+1F93D 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing water polo # E4.0 [1] (🤽‍♀️)
+1F93D 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing water polo # E4.0 [1] (🤽‍♂️)
+1F93D 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing water polo: light skin tone # E4.0 [1] (🤽🏻‍♀️)
+1F93D 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing water polo: light skin tone # E4.0 [1] (🤽🏻‍♂️)
+1F93D 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing water polo: medium-light skin tone # E4.0 [1] (🤽🏼‍♀️)
+1F93D 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing water polo: medium-light skin tone # E4.0 [1] (🤽🏼‍♂️)
+1F93D 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing water polo: medium skin tone # E4.0 [1] (🤽🏽‍♀️)
+1F93D 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing water polo: medium skin tone # E4.0 [1] (🤽🏽‍♂️)
+1F93D 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing water polo: medium-dark skin tone # E4.0 [1] (🤽🏾‍♀️)
+1F93D 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing water polo: medium-dark skin tone # E4.0 [1] (🤽🏾‍♂️)
+1F93D 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing water polo: dark skin tone # E4.0 [1] (🤽🏿‍♀️)
+1F93D 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing water polo: dark skin tone # E4.0 [1] (🤽🏿‍♂️)
+1F93E 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing handball # E4.0 [1] (🤾‍♀️)
+1F93E 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing handball # E4.0 [1] (🤾‍♂️)
+1F93E 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing handball: light skin tone # E4.0 [1] (🤾🏻‍♀️)
+1F93E 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing handball: light skin tone # E4.0 [1] (🤾🏻‍♂️)
+1F93E 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing handball: medium-light skin tone # E4.0 [1] (🤾🏼‍♀️)
+1F93E 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing handball: medium-light skin tone # E4.0 [1] (🤾🏼‍♂️)
+1F93E 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing handball: medium skin tone # E4.0 [1] (🤾🏽‍♀️)
+1F93E 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing handball: medium skin tone # E4.0 [1] (🤾🏽‍♂️)
+1F93E 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing handball: medium-dark skin tone # E4.0 [1] (🤾🏾‍♀️)
+1F93E 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing handball: medium-dark skin tone # E4.0 [1] (🤾🏾‍♂️)
+1F93E 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman playing handball: dark skin tone # E4.0 [1] (🤾🏿‍♀️)
+1F93E 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man playing handball: dark skin tone # E4.0 [1] (🤾🏿‍♂️)
+1F9B8 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman superhero # E11.0 [1] (🦸‍♀️)
+1F9B8 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man superhero # E11.0 [1] (🦸‍♂️)
+1F9B8 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman superhero: light skin tone # E11.0 [1] (🦸🏻‍♀️)
+1F9B8 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man superhero: light skin tone # E11.0 [1] (🦸🏻‍♂️)
+1F9B8 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman superhero: medium-light skin tone # E11.0 [1] (🦸🏼‍♀️)
+1F9B8 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man superhero: medium-light skin tone # E11.0 [1] (🦸🏼‍♂️)
+1F9B8 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman superhero: medium skin tone # E11.0 [1] (🦸🏽‍♀️)
+1F9B8 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man superhero: medium skin tone # E11.0 [1] (🦸🏽‍♂️)
+1F9B8 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman superhero: medium-dark skin tone # E11.0 [1] (🦸🏾‍♀️)
+1F9B8 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man superhero: medium-dark skin tone # E11.0 [1] (🦸🏾‍♂️)
+1F9B8 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman superhero: dark skin tone # E11.0 [1] (🦸🏿‍♀️)
+1F9B8 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man superhero: dark skin tone # E11.0 [1] (🦸🏿‍♂️)
+1F9B9 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman supervillain # E11.0 [1] (🦹‍♀️)
+1F9B9 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man supervillain # E11.0 [1] (🦹‍♂️)
+1F9B9 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman supervillain: light skin tone # E11.0 [1] (🦹🏻‍♀️)
+1F9B9 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man supervillain: light skin tone # E11.0 [1] (🦹🏻‍♂️)
+1F9B9 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman supervillain: medium-light skin tone # E11.0 [1] (🦹🏼‍♀️)
+1F9B9 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man supervillain: medium-light skin tone # E11.0 [1] (🦹🏼‍♂️)
+1F9B9 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman supervillain: medium skin tone # E11.0 [1] (🦹🏽‍♀️)
+1F9B9 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man supervillain: medium skin tone # E11.0 [1] (🦹🏽‍♂️)
+1F9B9 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman supervillain: medium-dark skin tone # E11.0 [1] (🦹🏾‍♀️)
+1F9B9 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man supervillain: medium-dark skin tone # E11.0 [1] (🦹🏾‍♂️)
+1F9B9 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman supervillain: dark skin tone # E11.0 [1] (🦹🏿‍♀️)
+1F9B9 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man supervillain: dark skin tone # E11.0 [1] (🦹🏿‍♂️)
+1F9CD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman standing # E12.0 [1] (🧍‍♀️)
+1F9CD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man standing # E12.0 [1] (🧍‍♂️)
+1F9CD 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman standing: light skin tone # E12.0 [1] (🧍🏻‍♀️)
+1F9CD 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man standing: light skin tone # E12.0 [1] (🧍🏻‍♂️)
+1F9CD 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman standing: medium-light skin tone # E12.0 [1] (🧍🏼‍♀️)
+1F9CD 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man standing: medium-light skin tone # E12.0 [1] (🧍🏼‍♂️)
+1F9CD 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman standing: medium skin tone # E12.0 [1] (🧍🏽‍♀️)
+1F9CD 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man standing: medium skin tone # E12.0 [1] (🧍🏽‍♂️)
+1F9CD 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman standing: medium-dark skin tone # E12.0 [1] (🧍🏾‍♀️)
+1F9CD 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man standing: medium-dark skin tone # E12.0 [1] (🧍🏾‍♂️)
+1F9CD 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman standing: dark skin tone # E12.0 [1] (🧍🏿‍♀️)
+1F9CD 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man standing: dark skin tone # E12.0 [1] (🧍🏿‍♂️)
+1F9CE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling # E12.0 [1] (🧎‍♀️)
+1F9CE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling # E12.0 [1] (🧎‍♂️)
+1F9CE 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling: light skin tone # E12.0 [1] (🧎🏻‍♀️)
+1F9CE 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling: light skin tone # E12.0 [1] (🧎🏻‍♂️)
+1F9CE 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling: medium-light skin tone # E12.0 [1] (🧎🏼‍♀️)
+1F9CE 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling: medium-light skin tone # E12.0 [1] (🧎🏼‍♂️)
+1F9CE 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling: medium skin tone # E12.0 [1] (🧎🏽‍♀️)
+1F9CE 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling: medium skin tone # E12.0 [1] (🧎🏽‍♂️)
+1F9CE 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling: medium-dark skin tone # E12.0 [1] (🧎🏾‍♀️)
+1F9CE 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling: medium-dark skin tone # E12.0 [1] (🧎🏾‍♂️)
+1F9CE 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman kneeling: dark skin tone # E12.0 [1] (🧎🏿‍♀️)
+1F9CE 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man kneeling: dark skin tone # E12.0 [1] (🧎🏿‍♂️)
+1F9CF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf woman # E12.0 [1] (🧏‍♀️)
+1F9CF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf man # E12.0 [1] (🧏‍♂️)
+1F9CF 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf woman: light skin tone # E12.0 [1] (🧏🏻‍♀️)
+1F9CF 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf man: light skin tone # E12.0 [1] (🧏🏻‍♂️)
+1F9CF 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf woman: medium-light skin tone # E12.0 [1] (🧏🏼‍♀️)
+1F9CF 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf man: medium-light skin tone # E12.0 [1] (🧏🏼‍♂️)
+1F9CF 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf woman: medium skin tone # E12.0 [1] (🧏🏽‍♀️)
+1F9CF 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf man: medium skin tone # E12.0 [1] (🧏🏽‍♂️)
+1F9CF 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf woman: medium-dark skin tone # E12.0 [1] (🧏🏾‍♀️)
+1F9CF 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf man: medium-dark skin tone # E12.0 [1] (🧏🏾‍♂️)
+1F9CF 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf woman: dark skin tone # E12.0 [1] (🧏🏿‍♀️)
+1F9CF 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; deaf man: dark skin tone # E12.0 [1] (🧏🏿‍♂️)
+1F9D4 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: beard # E13.1 [1] (🧔‍♀️)
+1F9D4 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: beard # E13.1 [1] (🧔‍♂️)
+1F9D4 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: light skin tone, beard # E13.1 [1] (🧔🏻‍♀️)
+1F9D4 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: light skin tone, beard # E13.1 [1] (🧔🏻‍♂️)
+1F9D4 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: medium-light skin tone, beard # E13.1 [1] (🧔🏼‍♀️)
+1F9D4 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: medium-light skin tone, beard # E13.1 [1] (🧔🏼‍♂️)
+1F9D4 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: medium skin tone, beard # E13.1 [1] (🧔🏽‍♀️)
+1F9D4 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: medium skin tone, beard # E13.1 [1] (🧔🏽‍♂️)
+1F9D4 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: medium-dark skin tone, beard # E13.1 [1] (🧔🏾‍♀️)
+1F9D4 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: medium-dark skin tone, beard # E13.1 [1] (🧔🏾‍♂️)
+1F9D4 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman: dark skin tone, beard # E13.1 [1] (🧔🏿‍♀️)
+1F9D4 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man: dark skin tone, beard # E13.1 [1] (🧔🏿‍♂️)
+1F9D6 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in steamy room # E5.0 [1] (🧖‍♀️)
+1F9D6 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in steamy room # E5.0 [1] (🧖‍♂️)
+1F9D6 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in steamy room: light skin tone # E5.0 [1] (🧖🏻‍♀️)
+1F9D6 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in steamy room: light skin tone # E5.0 [1] (🧖🏻‍♂️)
+1F9D6 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in steamy room: medium-light skin tone # E5.0 [1] (🧖🏼‍♀️)
+1F9D6 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in steamy room: medium-light skin tone # E5.0 [1] (🧖🏼‍♂️)
+1F9D6 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in steamy room: medium skin tone # E5.0 [1] (🧖🏽‍♀️)
+1F9D6 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in steamy room: medium skin tone # E5.0 [1] (🧖🏽‍♂️)
+1F9D6 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in steamy room: medium-dark skin tone # E5.0 [1] (🧖🏾‍♀️)
+1F9D6 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in steamy room: medium-dark skin tone # E5.0 [1] (🧖🏾‍♂️)
+1F9D6 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in steamy room: dark skin tone # E5.0 [1] (🧖🏿‍♀️)
+1F9D6 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in steamy room: dark skin tone # E5.0 [1] (🧖🏿‍♂️)
+1F9D7 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman climbing # E5.0 [1] (🧗‍♀️)
+1F9D7 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man climbing # E5.0 [1] (🧗‍♂️)
+1F9D7 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman climbing: light skin tone # E5.0 [1] (🧗🏻‍♀️)
+1F9D7 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man climbing: light skin tone # E5.0 [1] (🧗🏻‍♂️)
+1F9D7 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman climbing: medium-light skin tone # E5.0 [1] (🧗🏼‍♀️)
+1F9D7 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man climbing: medium-light skin tone # E5.0 [1] (🧗🏼‍♂️)
+1F9D7 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman climbing: medium skin tone # E5.0 [1] (🧗🏽‍♀️)
+1F9D7 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man climbing: medium skin tone # E5.0 [1] (🧗🏽‍♂️)
+1F9D7 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman climbing: medium-dark skin tone # E5.0 [1] (🧗🏾‍♀️)
+1F9D7 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man climbing: medium-dark skin tone # E5.0 [1] (🧗🏾‍♂️)
+1F9D7 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman climbing: dark skin tone # E5.0 [1] (🧗🏿‍♀️)
+1F9D7 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man climbing: dark skin tone # E5.0 [1] (🧗🏿‍♂️)
+1F9D8 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in lotus position # E5.0 [1] (🧘‍♀️)
+1F9D8 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in lotus position # E5.0 [1] (🧘‍♂️)
+1F9D8 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in lotus position: light skin tone # E5.0 [1] (🧘🏻‍♀️)
+1F9D8 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in lotus position: light skin tone # E5.0 [1] (🧘🏻‍♂️)
+1F9D8 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in lotus position: medium-light skin tone # E5.0 [1] (🧘🏼‍♀️)
+1F9D8 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in lotus position: medium-light skin tone # E5.0 [1] (🧘🏼‍♂️)
+1F9D8 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in lotus position: medium skin tone # E5.0 [1] (🧘🏽‍♀️)
+1F9D8 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in lotus position: medium skin tone # E5.0 [1] (🧘🏽‍♂️)
+1F9D8 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in lotus position: medium-dark skin tone # E5.0 [1] (🧘🏾‍♀️)
+1F9D8 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in lotus position: medium-dark skin tone # E5.0 [1] (🧘🏾‍♂️)
+1F9D8 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman in lotus position: dark skin tone # E5.0 [1] (🧘🏿‍♀️)
+1F9D8 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man in lotus position: dark skin tone # E5.0 [1] (🧘🏿‍♂️)
+1F9D9 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mage # E5.0 [1] (🧙‍♀️)
+1F9D9 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mage # E5.0 [1] (🧙‍♂️)
+1F9D9 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mage: light skin tone # E5.0 [1] (🧙🏻‍♀️)
+1F9D9 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mage: light skin tone # E5.0 [1] (🧙🏻‍♂️)
+1F9D9 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mage: medium-light skin tone # E5.0 [1] (🧙🏼‍♀️)
+1F9D9 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mage: medium-light skin tone # E5.0 [1] (🧙🏼‍♂️)
+1F9D9 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mage: medium skin tone # E5.0 [1] (🧙🏽‍♀️)
+1F9D9 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mage: medium skin tone # E5.0 [1] (🧙🏽‍♂️)
+1F9D9 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mage: medium-dark skin tone # E5.0 [1] (🧙🏾‍♀️)
+1F9D9 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mage: medium-dark skin tone # E5.0 [1] (🧙🏾‍♂️)
+1F9D9 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman mage: dark skin tone # E5.0 [1] (🧙🏿‍♀️)
+1F9D9 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man mage: dark skin tone # E5.0 [1] (🧙🏿‍♂️)
+1F9DA 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman fairy # E5.0 [1] (🧚‍♀️)
+1F9DA 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man fairy # E5.0 [1] (🧚‍♂️)
+1F9DA 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman fairy: light skin tone # E5.0 [1] (🧚🏻‍♀️)
+1F9DA 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man fairy: light skin tone # E5.0 [1] (🧚🏻‍♂️)
+1F9DA 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman fairy: medium-light skin tone # E5.0 [1] (🧚🏼‍♀️)
+1F9DA 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man fairy: medium-light skin tone # E5.0 [1] (🧚🏼‍♂️)
+1F9DA 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman fairy: medium skin tone # E5.0 [1] (🧚🏽‍♀️)
+1F9DA 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man fairy: medium skin tone # E5.0 [1] (🧚🏽‍♂️)
+1F9DA 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman fairy: medium-dark skin tone # E5.0 [1] (🧚🏾‍♀️)
+1F9DA 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man fairy: medium-dark skin tone # E5.0 [1] (🧚🏾‍♂️)
+1F9DA 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman fairy: dark skin tone # E5.0 [1] (🧚🏿‍♀️)
+1F9DA 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man fairy: dark skin tone # E5.0 [1] (🧚🏿‍♂️)
+1F9DB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman vampire # E5.0 [1] (🧛‍♀️)
+1F9DB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man vampire # E5.0 [1] (🧛‍♂️)
+1F9DB 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman vampire: light skin tone # E5.0 [1] (🧛🏻‍♀️)
+1F9DB 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man vampire: light skin tone # E5.0 [1] (🧛🏻‍♂️)
+1F9DB 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman vampire: medium-light skin tone # E5.0 [1] (🧛🏼‍♀️)
+1F9DB 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man vampire: medium-light skin tone # E5.0 [1] (🧛🏼‍♂️)
+1F9DB 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman vampire: medium skin tone # E5.0 [1] (🧛🏽‍♀️)
+1F9DB 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man vampire: medium skin tone # E5.0 [1] (🧛🏽‍♂️)
+1F9DB 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman vampire: medium-dark skin tone # E5.0 [1] (🧛🏾‍♀️)
+1F9DB 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man vampire: medium-dark skin tone # E5.0 [1] (🧛🏾‍♂️)
+1F9DB 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman vampire: dark skin tone # E5.0 [1] (🧛🏿‍♀️)
+1F9DB 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man vampire: dark skin tone # E5.0 [1] (🧛🏿‍♂️)
+1F9DC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; mermaid # E5.0 [1] (🧜‍♀️)
+1F9DC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; merman # E5.0 [1] (🧜‍♂️)
+1F9DC 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; mermaid: light skin tone # E5.0 [1] (🧜🏻‍♀️)
+1F9DC 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; merman: light skin tone # E5.0 [1] (🧜🏻‍♂️)
+1F9DC 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; mermaid: medium-light skin tone # E5.0 [1] (🧜🏼‍♀️)
+1F9DC 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; merman: medium-light skin tone # E5.0 [1] (🧜🏼‍♂️)
+1F9DC 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; mermaid: medium skin tone # E5.0 [1] (🧜🏽‍♀️)
+1F9DC 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; merman: medium skin tone # E5.0 [1] (🧜🏽‍♂️)
+1F9DC 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; mermaid: medium-dark skin tone # E5.0 [1] (🧜🏾‍♀️)
+1F9DC 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; merman: medium-dark skin tone # E5.0 [1] (🧜🏾‍♂️)
+1F9DC 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; mermaid: dark skin tone # E5.0 [1] (🧜🏿‍♀️)
+1F9DC 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; merman: dark skin tone # E5.0 [1] (🧜🏿‍♂️)
+1F9DD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman elf # E5.0 [1] (🧝‍♀️)
+1F9DD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man elf # E5.0 [1] (🧝‍♂️)
+1F9DD 1F3FB 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman elf: light skin tone # E5.0 [1] (🧝🏻‍♀️)
+1F9DD 1F3FB 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man elf: light skin tone # E5.0 [1] (🧝🏻‍♂️)
+1F9DD 1F3FC 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman elf: medium-light skin tone # E5.0 [1] (🧝🏼‍♀️)
+1F9DD 1F3FC 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man elf: medium-light skin tone # E5.0 [1] (🧝🏼‍♂️)
+1F9DD 1F3FD 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman elf: medium skin tone # E5.0 [1] (🧝🏽‍♀️)
+1F9DD 1F3FD 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man elf: medium skin tone # E5.0 [1] (🧝🏽‍♂️)
+1F9DD 1F3FE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman elf: medium-dark skin tone # E5.0 [1] (🧝🏾‍♀️)
+1F9DD 1F3FE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man elf: medium-dark skin tone # E5.0 [1] (🧝🏾‍♂️)
+1F9DD 1F3FF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman elf: dark skin tone # E5.0 [1] (🧝🏿‍♀️)
+1F9DD 1F3FF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man elf: dark skin tone # E5.0 [1] (🧝🏿‍♂️)
+1F9DE 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman genie # E5.0 [1] (🧞‍♀️)
+1F9DE 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man genie # E5.0 [1] (🧞‍♂️)
+1F9DF 200D 2640 FE0F ; RGI_Emoji_ZWJ_Sequence ; woman zombie # E5.0 [1] (🧟‍♀️)
+1F9DF 200D 2642 FE0F ; RGI_Emoji_ZWJ_Sequence ; man zombie # E5.0 [1] (🧟‍♂️)
+
+# Total elements: 572
+
+# ================================================
+
+# RGI_Emoji_ZWJ_Sequence: Hair
+
+1F468 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; man: red hair # E11.0 [1] (👨‍🦰)
+1F468 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; man: curly hair # E11.0 [1] (👨‍🦱)
+1F468 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; man: bald # E11.0 [1] (👨‍🦲)
+1F468 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; man: white hair # E11.0 [1] (👨‍🦳)
+1F468 1F3FB 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; man: light skin tone, red hair # E11.0 [1] (👨🏻‍🦰)
+1F468 1F3FB 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; man: light skin tone, curly hair # E11.0 [1] (👨🏻‍🦱)
+1F468 1F3FB 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; man: light skin tone, bald # E11.0 [1] (👨🏻‍🦲)
+1F468 1F3FB 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; man: light skin tone, white hair # E11.0 [1] (👨🏻‍🦳)
+1F468 1F3FC 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; man: medium-light skin tone, red hair # E11.0 [1] (👨🏼‍🦰)
+1F468 1F3FC 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; man: medium-light skin tone, curly hair # E11.0 [1] (👨🏼‍🦱)
+1F468 1F3FC 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; man: medium-light skin tone, bald # E11.0 [1] (👨🏼‍🦲)
+1F468 1F3FC 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; man: medium-light skin tone, white hair # E11.0 [1] (👨🏼‍🦳)
+1F468 1F3FD 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; man: medium skin tone, red hair # E11.0 [1] (👨🏽‍🦰)
+1F468 1F3FD 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; man: medium skin tone, curly hair # E11.0 [1] (👨🏽‍🦱)
+1F468 1F3FD 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; man: medium skin tone, bald # E11.0 [1] (👨🏽‍🦲)
+1F468 1F3FD 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; man: medium skin tone, white hair # E11.0 [1] (👨🏽‍🦳)
+1F468 1F3FE 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; man: medium-dark skin tone, red hair # E11.0 [1] (👨🏾‍🦰)
+1F468 1F3FE 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; man: medium-dark skin tone, curly hair # E11.0 [1] (👨🏾‍🦱)
+1F468 1F3FE 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; man: medium-dark skin tone, bald # E11.0 [1] (👨🏾‍🦲)
+1F468 1F3FE 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; man: medium-dark skin tone, white hair # E11.0 [1] (👨🏾‍🦳)
+1F468 1F3FF 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; man: dark skin tone, red hair # E11.0 [1] (👨🏿‍🦰)
+1F468 1F3FF 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; man: dark skin tone, curly hair # E11.0 [1] (👨🏿‍🦱)
+1F468 1F3FF 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; man: dark skin tone, bald # E11.0 [1] (👨🏿‍🦲)
+1F468 1F3FF 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; man: dark skin tone, white hair # E11.0 [1] (👨🏿‍🦳)
+1F469 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; woman: red hair # E11.0 [1] (👩‍🦰)
+1F469 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; woman: curly hair # E11.0 [1] (👩‍🦱)
+1F469 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; woman: bald # E11.0 [1] (👩‍🦲)
+1F469 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; woman: white hair # E11.0 [1] (👩‍🦳)
+1F469 1F3FB 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; woman: light skin tone, red hair # E11.0 [1] (👩🏻‍🦰)
+1F469 1F3FB 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; woman: light skin tone, curly hair # E11.0 [1] (👩🏻‍🦱)
+1F469 1F3FB 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; woman: light skin tone, bald # E11.0 [1] (👩🏻‍🦲)
+1F469 1F3FB 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; woman: light skin tone, white hair # E11.0 [1] (👩🏻‍🦳)
+1F469 1F3FC 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-light skin tone, red hair # E11.0 [1] (👩🏼‍🦰)
+1F469 1F3FC 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-light skin tone, curly hair # E11.0 [1] (👩🏼‍🦱)
+1F469 1F3FC 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-light skin tone, bald # E11.0 [1] (👩🏼‍🦲)
+1F469 1F3FC 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-light skin tone, white hair # E11.0 [1] (👩🏼‍🦳)
+1F469 1F3FD 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; woman: medium skin tone, red hair # E11.0 [1] (👩🏽‍🦰)
+1F469 1F3FD 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; woman: medium skin tone, curly hair # E11.0 [1] (👩🏽‍🦱)
+1F469 1F3FD 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; woman: medium skin tone, bald # E11.0 [1] (👩🏽‍🦲)
+1F469 1F3FD 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; woman: medium skin tone, white hair # E11.0 [1] (👩🏽‍🦳)
+1F469 1F3FE 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-dark skin tone, red hair # E11.0 [1] (👩🏾‍🦰)
+1F469 1F3FE 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-dark skin tone, curly hair # E11.0 [1] (👩🏾‍🦱)
+1F469 1F3FE 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-dark skin tone, bald # E11.0 [1] (👩🏾‍🦲)
+1F469 1F3FE 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; woman: medium-dark skin tone, white hair # E11.0 [1] (👩🏾‍🦳)
+1F469 1F3FF 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; woman: dark skin tone, red hair # E11.0 [1] (👩🏿‍🦰)
+1F469 1F3FF 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; woman: dark skin tone, curly hair # E11.0 [1] (👩🏿‍🦱)
+1F469 1F3FF 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; woman: dark skin tone, bald # E11.0 [1] (👩🏿‍🦲)
+1F469 1F3FF 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; woman: dark skin tone, white hair # E11.0 [1] (👩🏿‍🦳)
+1F9D1 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; person: red hair # E12.1 [1] (🧑‍🦰)
+1F9D1 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; person: curly hair # E12.1 [1] (🧑‍🦱)
+1F9D1 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; person: bald # E12.1 [1] (🧑‍🦲)
+1F9D1 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; person: white hair # E12.1 [1] (🧑‍🦳)
+1F9D1 1F3FB 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; person: light skin tone, red hair # E12.1 [1] (🧑🏻‍🦰)
+1F9D1 1F3FB 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; person: light skin tone, curly hair # E12.1 [1] (🧑🏻‍🦱)
+1F9D1 1F3FB 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; person: light skin tone, bald # E12.1 [1] (🧑🏻‍🦲)
+1F9D1 1F3FB 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; person: light skin tone, white hair # E12.1 [1] (🧑🏻‍🦳)
+1F9D1 1F3FC 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; person: medium-light skin tone, red hair # E12.1 [1] (🧑🏼‍🦰)
+1F9D1 1F3FC 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; person: medium-light skin tone, curly hair # E12.1 [1] (🧑🏼‍🦱)
+1F9D1 1F3FC 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; person: medium-light skin tone, bald # E12.1 [1] (🧑🏼‍🦲)
+1F9D1 1F3FC 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; person: medium-light skin tone, white hair # E12.1 [1] (🧑🏼‍🦳)
+1F9D1 1F3FD 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; person: medium skin tone, red hair # E12.1 [1] (🧑🏽‍🦰)
+1F9D1 1F3FD 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; person: medium skin tone, curly hair # E12.1 [1] (🧑🏽‍🦱)
+1F9D1 1F3FD 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; person: medium skin tone, bald # E12.1 [1] (🧑🏽‍🦲)
+1F9D1 1F3FD 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; person: medium skin tone, white hair # E12.1 [1] (🧑🏽‍🦳)
+1F9D1 1F3FE 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; person: medium-dark skin tone, red hair # E12.1 [1] (🧑🏾‍🦰)
+1F9D1 1F3FE 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; person: medium-dark skin tone, curly hair # E12.1 [1] (🧑🏾‍🦱)
+1F9D1 1F3FE 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; person: medium-dark skin tone, bald # E12.1 [1] (🧑🏾‍🦲)
+1F9D1 1F3FE 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; person: medium-dark skin tone, white hair # E12.1 [1] (🧑🏾‍🦳)
+1F9D1 1F3FF 200D 1F9B0 ; RGI_Emoji_ZWJ_Sequence ; person: dark skin tone, red hair # E12.1 [1] (🧑🏿‍🦰)
+1F9D1 1F3FF 200D 1F9B1 ; RGI_Emoji_ZWJ_Sequence ; person: dark skin tone, curly hair # E12.1 [1] (🧑🏿‍🦱)
+1F9D1 1F3FF 200D 1F9B2 ; RGI_Emoji_ZWJ_Sequence ; person: dark skin tone, bald # E12.1 [1] (🧑🏿‍🦲)
+1F9D1 1F3FF 200D 1F9B3 ; RGI_Emoji_ZWJ_Sequence ; person: dark skin tone, white hair # E12.1 [1] (🧑🏿‍🦳)
+
+# Total elements: 72
+
+# ================================================
+
+# RGI_Emoji_ZWJ_Sequence: Other
+
+2764 FE0F 200D 1F525 ; RGI_Emoji_ZWJ_Sequence ; heart on fire # E13.1 [1] (❤️‍🔥)
+2764 FE0F 200D 1FA79 ; RGI_Emoji_ZWJ_Sequence ; mending heart # E13.1 [1] (❤️‍🩹)
+1F3F3 FE0F 200D 26A7 FE0F ; RGI_Emoji_ZWJ_Sequence ; transgender flag # E13.0 [1] (🏳️‍⚧️)
+1F3F3 FE0F 200D 1F308 ; RGI_Emoji_ZWJ_Sequence ; rainbow flag # E4.0 [1] (🏳️‍🌈)
+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] (🐕‍🦺)
+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] (😮‍💨)
+1F635 200D 1F4AB ; RGI_Emoji_ZWJ_Sequence ; face with spiral eyes # E13.1 [1] (😵‍💫)
+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
+
+#EOF
diff --git a/admin/unidata/emoji-zwj.awk b/admin/unidata/emoji-zwj.awk
new file mode 100644
index 00000000000..e704cb45263
--- /dev/null
+++ b/admin/unidata/emoji-zwj.awk
@@ -0,0 +1,140 @@
+#!/usr/bin/awk -f
+
+## Copyright (C) 2020 Free Software Foundation, Inc.
+
+## Author: Robert Pluim <rpluim@gmail.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/>.
+
+### Commentary:
+
+## This script takes as input Unicode's emoji-zwj-sequences.txt
+## and produces output for Emacs's lisp/international/emoji-zwj.el.
+## It also outputs the composition sequences for flags, UK flags, and
+## skin tones which have been derived from emoji-sequences.txt by hand.
+
+## For additional details, see <https://debbugs.gnu.org/39799#8>.
+
+## Things to do after installing a new version of
+## emoji-zwj-sequences.txt and emoji-sequences.txt
+## Check the output against the old output. See if there are any new
+## composition sequences in emoji-sequences.txt that that need to be
+## added Rebuild emacs, visit emoji-zwj-sequences.txt and
+## emoji-sequences.txt and check that the various sequences are being
+## composed properly. Don't forget to install an appropriate font,
+## such as Noto Color Emoji.
+
+### Code:
+
+/^[0-9A-F].*; RGI_Emoji_(ZWJ|Modifier)_Sequence/ {
+ sub(/ *;.*/, "", $0)
+ num = split($0, elts)
+ if (ch[elts[1]] == "")
+ {
+ vec[elts[1]] = ""
+ ch[elts[1]] = elts[1]
+ }
+ else
+ {
+ vec[elts[1]] = vec[elts[1]] "\n"
+ }
+ vec[elts[1]] = vec[elts[1]] "\""
+ for (j = 1; j <= num; j++)
+ {
+ c = sprintf("\\N{U+%s}", elts[j])
+ vec[elts[1]] = vec[elts[1]] c
+ }
+ vec[elts[1]] = vec[elts[1]] "\""
+}
+
+END {
+ print ";;; emoji-zwj.el --- emoji zwj character composition table -*- lexical-binding:t -*-"
+ print ";;; Automatically generated from admin/unidata/emoji-{zwj-,}sequences.txt"
+ print "(eval-when-compile (require 'regexp-opt))"
+
+ # The following codepoints are not emoji, but they are part of
+ # emoji sequences. We have code in font.c:font_range that will
+ # try to display them with the emoji font anyway.
+
+ trigger_codepoints[1] = "261D"
+ trigger_codepoints[2] = "26F9"
+ trigger_codepoints[3] = "270C"
+ trigger_codepoints[4] = "270D"
+ trigger_codepoints[5] = "2764"
+ trigger_codepoints[6] = "1F3CB"
+ trigger_codepoints[7] = "1F3CC"
+ trigger_codepoints[8] = "1F3F3"
+ trigger_codepoints[9] = "1F3F4"
+ trigger_codepoints[10] = "1F441"
+ trigger_codepoints[11] = "1F574"
+ trigger_codepoints[12] = "1F575"
+ trigger_codepoints[13] = "1F590"
+
+ printf "(setq auto-composition-emoji-eligible-codepoints\n"
+ printf "'("
+
+ for (trig in trigger_codepoints)
+ {
+ printf("\n?\\N{U+%s}", trigger_codepoints[trig])
+ }
+ printf "\n))\n\n"
+
+ # We add entries for 'codepoint U+FE0F' here to ensure that the
+ # code in font_range is triggered.
+
+ for (trig in trigger_codepoints)
+ {
+ codepoint = trigger_codepoints[trig]
+ c = sprintf("\\N{U+%s}", codepoint)
+ vec[codepoint] = vec[codepoint] "\n\"" c "\\N{U+FE0F}\""
+ }
+
+ print "(dolist (elt `("
+
+ for (elt in ch)
+ {
+ printf("(#x%s .\n,(eval-when-compile (regexp-opt\n'(\n%s\n))))\n", elt, vec[elt])
+ }
+ print "))"
+ print " (set-char-table-range composition-function-table"
+ print " (car elt)"
+ print " (nconc (char-table-range composition-function-table (car elt))"
+ print " (list (vector (cdr elt)"
+ print " 0"
+ print " #'compose-gstring-for-graphic)))))"
+
+ print ";; The following two blocks are derived by hand from emoji-sequences.txt"
+ print ";; FIXME: add support for Emoji_Keycap_Sequence once we learn how to respect FE0F/VS-16"
+ print ";; for ASCII characters."
+
+ print ";; Flags"
+ print "(set-char-table-range composition-function-table"
+ print " '(#x1F1E6 . #x1F1FF)"
+ print " (nconc (char-table-range composition-function-table '(#x1F1E6 . #x1F1FF))"
+ print " (list (vector \"[\\U0001F1E6-\\U0001F1FF][\\U0001F1E6-\\U0001F1FF]\""
+ print " 0"
+ print " #'compose-gstring-for-graphic))))"
+
+ print ";; UK Flags"
+ print "(set-char-table-range composition-function-table"
+ print " #x1F3F4"
+ print " (nconc (char-table-range composition-function-table #x1F3F4)"
+ print " (list (vector \"\\U0001F3F4\\U000E0067\\U000E0062\\\\(?:\\U000E0065\\U000E006E\\U000E0067\\\\|\\U000E0073\\U000E0063\\U000E0074\\\\|\\U000E0077\\U000E006C\\U000E0073\\\\)\\U000E007F\""
+ print " 0"
+ print " #'compose-gstring-for-graphic))))"
+
+ printf "\n(provide 'emoji-zwj)"
+}
diff --git a/admin/update_autogen b/admin/update_autogen
index 11c4313ae37..99297a9c0dc 100755
--- a/admin/update_autogen
+++ b/admin/update_autogen
@@ -44,7 +44,7 @@ PD=${0%/*}
[ "$PD" = "$0" ] && PD=. # if PATH includes PWD
## This should be the admin directory.
-cd $PD
+cd $PD || exit
cd ../
[ -d admin ] || die "Could not locate admin directory"
@@ -53,7 +53,7 @@ cd ../
usage ()
{
cat 1>&2 <<EOF
-Usage: ${PN} [-f] [-c] [-q] [-A dir] [-I] [-L] [-C] [-- make-flags]
+Usage: ${PN} [-f] [-c] [-q] [-A dir] [-L] [-C] [-- make-flags]
Update some auto-generated files in the Emacs tree.
By default, only does the versioned loaddefs-like files in lisp/.
This requires a build. Passes any non-option args to make (eg -- -j2).
@@ -63,8 +63,6 @@ Options:
commit them (caution).
-q: be quiet; only give error messages, not status messages.
-A: only update autotools files, copying into specified dir.
--H: also update ChangeLog.${changelog_n}
--I: also update info/dir.
-L: also update ldefs-boot.el.
-C: start from a clean state. Slower, but more correct.
EOF
@@ -81,14 +79,10 @@ clean=
autogendir= # was "autogen"
ldefs_flag=1
lboot_flag=
-info_flag=
-changelog_flag=
## Parameters.
ldefs_in=lisp/loaddefs.el
ldefs_out=lisp/ldefs-boot.el
-changelog_n=$(sed -n 's/CHANGELOG_HISTORY_INDEX_MAX *= *//p' Makefile.in)
-changelog_files="ChangeLog.$changelog_n"
sources="configure.ac lib/Makefile.am"
## Files to copy into autogendir.
## Everything:
@@ -108,10 +102,10 @@ done
tempfile=/tmp/$PN.$$
-trap "rm -f $tempfile 2> /dev/null" EXIT
+trap 'rm -f $tempfile 2> /dev/null' EXIT
-while getopts ":hcfqA:HCIL" option ; do
+while getopts ":hcfqA:CL" option ; do
case $option in
(h) usage ;;
@@ -127,10 +121,6 @@ while getopts ":hcfqA:HCIL" option ; do
(C) clean=1 ;;
- (H) changelog_flag=1 ;;
-
- (I) info_flag=1 ;;
-
(L) lboot_flag=1 ;;
(\?) die "Bad option -$OPTARG" ;;
@@ -172,7 +162,7 @@ status ()
echo "Checking input file status..."
## The lisp portion could be more permissive, eg only care about .el files.
-modified=$(status ${autogendir:+$sources} ${ldefs_flag:+lisp} ${info_flag:+doc}) || die
+modified=$(status ${autogendir:+$sources} ${ldefs_flag:+lisp}) || die
[ "$modified" ] && {
echo "Locally modified: $modified"
@@ -235,65 +225,8 @@ commit ()
} # function commit
-## No longer used since info/dir is now generated at install time if needed,
-## and is not in the repository any more.
-info_dir ()
-{
- local basefile=build-aux/dir_top outfile=info/dir
-
- echo "Regenerating info/dir..."
-
- ## Header contains non-printing characters, so this is more
- ## reliable than using echo.
- rm -f $outfile
- cp $basefile $outfile
-
- local topic file dircat dirent
-
- ## FIXME inefficient looping.
- for topic in "Texinfo documentation system" "Emacs" "GNU Emacs Lisp" \
- "Emacs editing modes" "Emacs network features" "Emacs misc features" \
- "Emacs lisp libraries"; do
-
- cat - <<EOF >> $outfile
-
-$topic
-EOF
- ## Bit faster than doc/*/*.texi.
- for file in doc/emacs/emacs.texi doc/lispintro/*.texi \
- doc/lispref/elisp.texi doc/misc/*.texi; do
-
- ## FIXME do not ignore w32 if OS is w32.
- case $file in
- *-xtra.texi|*efaq-w32.texi) continue ;;
- esac
-
- dircat=$(sed -n -e 's/@value{emacsname}/Emacs/' -e 's/^@dircategory //p' $file)
-
- ## TODO warn about unknown topics (check-info in top-level
- ## Makefile does this).
- [ "$dircat" = "$topic" ] || continue
-
- sed -n -e 's/@value{emacsname}/Emacs/' \
- -e 's/@acronym{\([A-Z]*\)}/\1/' \
- -e '/^@direntry/,/^@end direntry/ s/^\([^@]\)/\1/p' \
- $file >> $outfile
-
- done
- done
-
- local modified
-
- modified=$(status $outfile) || die
-
- commit "info/dir" $modified || die "commit error"
-} # function info_dir
-
-
[ "$autogendir" ] && {
- oldpwd=$PWD
-
cp $genfiles $autogendir/
cd $autogendir || die "cd error for $autogendir"
@@ -308,9 +241,6 @@ EOF
} # $autogendir
-[ "$info_flag" ] && info_dir
-
-
[ "$ldefs_flag" ] || exit 0
@@ -385,14 +315,6 @@ modified=$(status $genfiles $ldefs_out $grammar_out) || die
commit "loaddefs" $modified || die "commit error"
-## Less important than the other stuff, so do it last.
-[ ! "$changelog_flag" ] || {
- make change-history-nocommit || die "make change-history error"
- modified=$(status $changelog_files) || die
- commit "ChangeLog" $modified || die "commit error"
-}
-
-
exit 0
### update_autogen ends here
diff --git a/build-aux/config.guess b/build-aux/config.guess
index f7727026b70..e81d3ae7c21 100755
--- a/build-aux/config.guess
+++ b/build-aux/config.guess
@@ -2,7 +2,9 @@
# Attempt to guess a canonical system name.
# Copyright 1992-2021 Free Software Foundation, Inc.
-timestamp='2021-01-01'
+# shellcheck disable=SC2006,SC2268 # see below for rationale
+
+timestamp='2021-06-03'
# 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
@@ -32,7 +34,15 @@ timestamp='2021-01-01'
# Please send patches to <config-patches@gnu.org>.
-me=$(echo "$0" | sed -e 's,.*/,,')
+# The "shellcheck disable" line above the timestamp inhibits complaints
+# about features and limitations of the classic Bourne shell that were
+# superseded or lifted in POSIX. However, this script identifies a wide
+# variety of pre-POSIX systems that do not have POSIX shells at all, and
+# even some reasonably current systems (Solaris 10 as case-in-point) still
+# have a pre-POSIX /bin/sh.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
@@ -84,6 +94,9 @@ if test $# != 0; then
exit 1
fi
+# Just in case it came from the environment.
+GUESS=
+
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
@@ -102,8 +115,8 @@ set_cc_for_build() {
# prevent multiple calls if $tmp is already set
test "$tmp" && return 0
: "${TMPDIR=/tmp}"
- # shellcheck disable=SC2039
- { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } ||
+ # shellcheck disable=SC2039,SC3028
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
@@ -112,7 +125,7 @@ set_cc_for_build() {
,,) echo "int x;" > "$dummy.c"
for driver in cc gcc c89 c99 ; do
if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$driver"
+ CC_FOR_BUILD=$driver
break
fi
done
@@ -131,12 +144,12 @@ if test -f /.attbin/uname ; then
PATH=$PATH:/.attbin ; export PATH
fi
-UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown
-UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown
-UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown
-UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-case "$UNAME_SYSTEM" in
+case $UNAME_SYSTEM in
Linux|GNU|GNU/*)
LIBC=unknown
@@ -157,7 +170,8 @@ Linux|GNU|GNU/*)
#endif
#endif
EOF
- eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')"
+ cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ eval "$cc_set_libc"
# Second heuristic to detect musl libc.
if [ "$LIBC" = unknown ] &&
@@ -176,7 +190,7 @@ esac
# Note: order is significant - the case branches are not exclusive.
-case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
+case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
@@ -188,12 +202,11 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
#
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
- sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \
- "/sbin/$sysctl" 2>/dev/null || \
- "/usr/sbin/$sysctl" 2>/dev/null || \
- echo unknown))
- case "$UNAME_MACHINE_ARCH" in
+ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \
+ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
+ echo unknown)`
+ case $UNAME_MACHINE_ARCH in
aarch64eb) machine=aarch64_be-unknown ;;
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
@@ -201,15 +214,15 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
earmv*)
- arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,')
- endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p')
- machine="${arch}${endian}"-unknown
+ arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine=${arch}${endian}-unknown
;;
- *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
+ *) machine=$UNAME_MACHINE_ARCH-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently (or will in the future) and ABI.
- case "$UNAME_MACHINE_ARCH" in
+ case $UNAME_MACHINE_ARCH in
earm*)
os=netbsdelf
;;
@@ -230,10 +243,10 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
;;
esac
# Determine ABI tags.
- case "$UNAME_MACHINE_ARCH" in
+ case $UNAME_MACHINE_ARCH in
earm*)
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
- abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr")
+ abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
;;
esac
# The OS release
@@ -241,76 +254,82 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
- case "$UNAME_VERSION" in
+ case $UNAME_VERSION in
Debian*)
release='-gnu'
;;
*)
- release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2)
+ release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "$machine-${os}${release}${abi-}"
- exit ;;
+ GUESS=$machine-${os}${release}${abi-}
+ ;;
*:Bitrig:*:*)
- UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//')
- echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
- exit ;;
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE
+ ;;
*:OpenBSD:*:*)
- UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//')
- echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
- exit ;;
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE
+ ;;
+ *:SecBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE
+ ;;
*:LibertyBSD:*:*)
- UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//')
- echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
- exit ;;
+ UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE
+ ;;
*:MidnightBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE
+ ;;
*:ekkoBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE
+ ;;
*:SolidBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE
+ ;;
*:OS108:*:*)
- echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE
+ ;;
macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE
+ ;;
*:MirBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE
+ ;;
*:Sortix:*:*)
- echo "$UNAME_MACHINE"-unknown-sortix
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-sortix
+ ;;
*:Twizzler:*:*)
- echo "$UNAME_MACHINE"-unknown-twizzler
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-twizzler
+ ;;
*:Redox:*:*)
- echo "$UNAME_MACHINE"-unknown-redox
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-redox
+ ;;
mips:OSF1:*.*)
- echo mips-dec-osf1
- exit ;;
+ GUESS=mips-dec-osf1
+ ;;
alpha:OSF1:*:*)
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ trap '' 0
case $UNAME_RELEASE in
*4.0)
- UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}')
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
- UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}')
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
# OSF/1 and Tru64 systems produced since 1995. I hope that
# covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0.
- ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1)
- case "$ALPHA_CPU_TYPE" in
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case $ALPHA_CPU_TYPE in
"EV4 (21064)")
UNAME_MACHINE=alpha ;;
"EV4.5 (21064)")
@@ -347,68 +366,69 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)"
- # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
- exitcode=$?
- trap '' 0
- exit $exitcode ;;
+ OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ GUESS=$UNAME_MACHINE-dec-osf$OSF_REL
+ ;;
Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
+ GUESS=m68k-unknown-sysv4
+ ;;
*:[Aa]miga[Oo][Ss]:*:*)
- echo "$UNAME_MACHINE"-unknown-amigaos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-amigaos
+ ;;
*:[Mm]orph[Oo][Ss]:*:*)
- echo "$UNAME_MACHINE"-unknown-morphos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-morphos
+ ;;
*:OS/390:*:*)
- echo i370-ibm-openedition
- exit ;;
+ GUESS=i370-ibm-openedition
+ ;;
*:z/VM:*:*)
- echo s390-ibm-zvmoe
- exit ;;
+ GUESS=s390-ibm-zvmoe
+ ;;
*:OS400:*:*)
- echo powerpc-ibm-os400
- exit ;;
+ GUESS=powerpc-ibm-os400
+ ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix"$UNAME_RELEASE"
- exit ;;
+ GUESS=arm-acorn-riscix$UNAME_RELEASE
+ ;;
arm*:riscos:*:*|arm*:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
+ GUESS=arm-unknown-riscos
+ ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit ;;
+ GUESS=hppa1.1-hitachi-hiuxmpp
+ ;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "$( (/bin/universe) 2>/dev/null)" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
+ case `(/bin/universe) 2>/dev/null` in
+ att) GUESS=pyramid-pyramid-sysv3 ;;
+ *) GUESS=pyramid-pyramid-bsd ;;
+ esac
+ ;;
NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit ;;
+ GUESS=pyramid-pyramid-svr4
+ ;;
DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit ;;
+ GUESS=sparc-icl-nx6
+ ;;
DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
- case $(/usr/bin/uname -p) in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
+ case `/usr/bin/uname -p` in
+ sparc) GUESS=sparc-icl-nx7 ;;
+ esac
+ ;;
s390x:SunOS:*:*)
- echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL
+ ;;
sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-hal-solaris2$SUN_REL
+ ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-sun-solaris2$SUN_REL
+ ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
- echo i386-pc-auroraux"$UNAME_RELEASE"
- exit ;;
+ GUESS=i386-pc-auroraux$UNAME_RELEASE
+ ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
set_cc_for_build
SUN_ARCH=i386
@@ -423,41 +443,44 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
SUN_ARCH=x86_64
fi
fi
- echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=$SUN_ARCH-pc-solaris2$SUN_REL
+ ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-sun-solaris3$SUN_REL
+ ;;
sun4*:SunOS:*:*)
- case "$(/usr/bin/arch -k)" in
+ case `/usr/bin/arch -k` in
Series*|S4*)
- UNAME_RELEASE=$(uname -v)
+ UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
+ GUESS=sparc-sun-sunos$SUN_REL
+ ;;
sun3*:SunOS:*:*)
- echo m68k-sun-sunos"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-sun-sunos$UNAME_RELEASE
+ ;;
sun*:*:4.2BSD:*)
- UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
- case "$(/bin/arch)" in
+ case `/bin/arch` in
sun3)
- echo m68k-sun-sunos"$UNAME_RELEASE"
+ GUESS=m68k-sun-sunos$UNAME_RELEASE
;;
sun4)
- echo sparc-sun-sunos"$UNAME_RELEASE"
+ GUESS=sparc-sun-sunos$UNAME_RELEASE
;;
esac
- exit ;;
+ ;;
aushp:SunOS:*:*)
- echo sparc-auspex-sunos"$UNAME_RELEASE"
- exit ;;
+ GUESS=sparc-auspex-sunos$UNAME_RELEASE
+ ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
@@ -467,41 +490,41 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-milan-mint$UNAME_RELEASE
+ ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-hades-mint$UNAME_RELEASE
+ ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-unknown-mint$UNAME_RELEASE
+ ;;
m68k:machten:*:*)
- echo m68k-apple-machten"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-apple-machten$UNAME_RELEASE
+ ;;
powerpc:machten:*:*)
- echo powerpc-apple-machten"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-apple-machten$UNAME_RELEASE
+ ;;
RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
+ GUESS=mips-dec-mach_bsd4.3
+ ;;
RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-dec-ultrix$UNAME_RELEASE
+ ;;
VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix"$UNAME_RELEASE"
- exit ;;
+ GUESS=vax-dec-ultrix$UNAME_RELEASE
+ ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix"$UNAME_RELEASE"
- exit ;;
+ GUESS=clipper-intergraph-clix$UNAME_RELEASE
+ ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
@@ -526,78 +549,79 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
}
EOF
$CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
- dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') &&
- SYSTEM_NAME=$("$dummy" "$dummyarg") &&
+ dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
{ echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-mips-riscos$UNAME_RELEASE
+ ;;
Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit ;;
+ GUESS=powerpc-motorola-powermax
+ ;;
Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit ;;
+ GUESS=powerpc-harris-powermax
+ ;;
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit ;;
+ GUESS=powerpc-harris-powermax
+ ;;
Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit ;;
+ GUESS=powerpc-harris-powerunix
+ ;;
m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
+ GUESS=m88k-harris-cxux7
+ ;;
m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
+ GUESS=m88k-motorola-sysv4
+ ;;
m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
+ GUESS=m88k-motorola-sysv3
+ ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=$(/usr/bin/uname -p)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
then
if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
test "$TARGET_BINARY_INTERFACE"x = x
then
- echo m88k-dg-dgux"$UNAME_RELEASE"
+ GUESS=m88k-dg-dgux$UNAME_RELEASE
else
- echo m88k-dg-dguxbcs"$UNAME_RELEASE"
+ GUESS=m88k-dg-dguxbcs$UNAME_RELEASE
fi
else
- echo i586-dg-dgux"$UNAME_RELEASE"
+ GUESS=i586-dg-dgux$UNAME_RELEASE
fi
- exit ;;
+ ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
+ GUESS=m88k-dolphin-sysv3
+ ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
+ GUESS=m88k-motorola-sysv3
+ ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
+ GUESS=m88k-tektronix-sysv3
+ ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
+ GUESS=m68k-tektronix-bsd
+ ;;
*:IRIX*:*:*)
- echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')"
- exit ;;
+ IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'`
+ GUESS=mips-sgi-irix$IRIX_REL
+ ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'$(uname -s)'" gives 'AIX '
+ GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
+ GUESS=i386-ibm-aix
+ ;;
ia64:AIX:*:*)
if test -x /usr/bin/oslevel ; then
- IBM_REV=$(/usr/bin/oslevel)
+ IBM_REV=`/usr/bin/oslevel`
else
- IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+ IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
fi
- echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
- exit ;;
+ GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV
+ ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
set_cc_for_build
@@ -612,68 +636,68 @@ EOF
exit(0);
}
EOF
- if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy")
+ if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
then
- echo "$SYSTEM_NAME"
+ GUESS=$SYSTEM_NAME
else
- echo rs6000-ibm-aix3.2.5
+ GUESS=rs6000-ibm-aix3.2.5
fi
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
+ GUESS=rs6000-ibm-aix3.2.4
else
- echo rs6000-ibm-aix3.2
+ GUESS=rs6000-ibm-aix3.2
fi
- exit ;;
+ ;;
*:AIX:*:[4567])
- IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }')
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if test -x /usr/bin/lslpp ; then
- IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc |
- awk -F: '{ print $3 }' | sed s/[0-9]*$/0/)
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
- IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+ IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
fi
- echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
- exit ;;
+ GUESS=$IBM_ARCH-ibm-aix$IBM_REV
+ ;;
*:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
+ GUESS=rs6000-ibm-aix
+ ;;
ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
+ GUESS=romp-ibm-bsd4.4
+ ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
+ GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to
+ ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
+ GUESS=rs6000-bull-bosx
+ ;;
DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
+ GUESS=m68k-bull-sysv3
+ ;;
9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
+ GUESS=m68k-hp-bsd
+ ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
+ GUESS=m68k-hp-bsd4.4
+ ;;
9000/[34678]??:HP-UX:*:*)
- HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
- case "$UNAME_MACHINE" in
+ HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
+ case $UNAME_MACHINE in
9000/31?) HP_ARCH=m68000 ;;
9000/[34]??) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if test -x /usr/bin/getconf; then
- sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null)
- sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null)
- case "$sc_cpu_version" in
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case $sc_cpu_version in
523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
- case "$sc_kernel_bits" in
+ case $sc_kernel_bits in
32) HP_ARCH=hppa2.0n ;;
64) HP_ARCH=hppa2.0w ;;
'') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
@@ -715,7 +739,7 @@ EOF
exit (0);
}
EOF
- (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy")
+ (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
@@ -740,12 +764,12 @@ EOF
HP_ARCH=hppa64
fi
fi
- echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
- exit ;;
+ GUESS=$HP_ARCH-hp-hpux$HPUX_REV
+ ;;
ia64:HP-UX:*:*)
- HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
- echo ia64-hp-hpux"$HPUX_REV"
- exit ;;
+ HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
+ GUESS=ia64-hp-hpux$HPUX_REV
+ ;;
3050*:HI-UX:*:*)
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
@@ -773,38 +797,38 @@ EOF
exit (0);
}
EOF
- $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") &&
+ $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
+ GUESS=unknown-hitachi-hiuxwe2
+ ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
- echo hppa1.1-hp-bsd
- exit ;;
+ GUESS=hppa1.1-hp-bsd
+ ;;
9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
+ GUESS=hppa1.0-hp-bsd
+ ;;
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
+ GUESS=hppa1.0-hp-mpeix
+ ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
- echo hppa1.1-hp-osf
- exit ;;
+ GUESS=hppa1.1-hp-osf
+ ;;
hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
+ GUESS=hppa1.0-hp-osf
+ ;;
i*86:OSF1:*:*)
if test -x /usr/sbin/sysversion ; then
- echo "$UNAME_MACHINE"-unknown-osf1mk
+ GUESS=$UNAME_MACHINE-unknown-osf1mk
else
- echo "$UNAME_MACHINE"-unknown-osf1
+ GUESS=$UNAME_MACHINE-unknown-osf1
fi
- exit ;;
+ ;;
parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
+ GUESS=hppa1.1-hp-lites
+ ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
+ GUESS=c1-convex-bsd
+ ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
@@ -812,17 +836,18 @@ EOF
fi
exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
+ GUESS=c34-convex-bsd
+ ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
+ GUESS=c38-convex-bsd
+ ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
+ GUESS=c4-convex-bsd
+ ;;
CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=ymp-cray-unicos$CRAY_REL
+ ;;
CRAY*[A-Z]90:*:*:*)
echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
@@ -830,114 +855,126 @@ EOF
-e 's/\.[^.]*$/.X/'
exit ;;
CRAY*TS:*:*:*)
- echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=t90-cray-unicos$CRAY_REL
+ ;;
CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=alphaev5-cray-unicosmk$CRAY_REL
+ ;;
CRAY*SV1:*:*:*)
- echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=sv1-cray-unicos$CRAY_REL
+ ;;
*:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=craynv-cray-unicosmp$CRAY_REL
+ ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)
- FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
- FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/')
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
+ GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+ ;;
5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
- FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/')
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
+ GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+ ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE
+ ;;
sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi"$UNAME_RELEASE"
- exit ;;
+ GUESS=sparc-unknown-bsdi$UNAME_RELEASE
+ ;;
*:BSD/OS:*:*)
- echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE
+ ;;
arm:FreeBSD:*:*)
- UNAME_PROCESSOR=$(uname -p)
+ UNAME_PROCESSOR=`uname -p`
set_cc_for_build
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi
else
- echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf
fi
- exit ;;
+ ;;
*:FreeBSD:*:*)
- UNAME_PROCESSOR=$(/usr/bin/uname -p)
- case "$UNAME_PROCESSOR" in
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case $UNAME_PROCESSOR in
amd64)
UNAME_PROCESSOR=x86_64 ;;
i386)
UNAME_PROCESSOR=i586 ;;
esac
- echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
- exit ;;
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL
+ ;;
i*:CYGWIN*:*)
- echo "$UNAME_MACHINE"-pc-cygwin
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-cygwin
+ ;;
*:MINGW64*:*)
- echo "$UNAME_MACHINE"-pc-mingw64
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-mingw64
+ ;;
*:MINGW*:*)
- echo "$UNAME_MACHINE"-pc-mingw32
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-mingw32
+ ;;
*:MSYS*:*)
- echo "$UNAME_MACHINE"-pc-msys
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-msys
+ ;;
i*:PW*:*)
- echo "$UNAME_MACHINE"-pc-pw32
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-pw32
+ ;;
*:Interix*:*)
- case "$UNAME_MACHINE" in
+ case $UNAME_MACHINE in
x86)
- echo i586-pc-interix"$UNAME_RELEASE"
- exit ;;
+ GUESS=i586-pc-interix$UNAME_RELEASE
+ ;;
authenticamd | genuineintel | EM64T)
- echo x86_64-unknown-interix"$UNAME_RELEASE"
- exit ;;
+ GUESS=x86_64-unknown-interix$UNAME_RELEASE
+ ;;
IA64)
- echo ia64-unknown-interix"$UNAME_RELEASE"
- exit ;;
+ GUESS=ia64-unknown-interix$UNAME_RELEASE
+ ;;
esac ;;
i*:UWIN*:*)
- echo "$UNAME_MACHINE"-pc-uwin
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-uwin
+ ;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-pc-cygwin
- exit ;;
+ GUESS=x86_64-pc-cygwin
+ ;;
prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=powerpcle-unknown-solaris2$SUN_REL
+ ;;
*:GNU:*:*)
# the GNU system
- echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')"
- exit ;;
+ GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'`
+ GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'`
+ GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL
+ ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC"
- exit ;;
+ GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"`
+ GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
+ ;;
*:Minix:*:*)
- echo "$UNAME_MACHINE"-unknown-minix
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-minix
+ ;;
aarch64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
alpha:Linux:*:*)
- case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
@@ -948,63 +985,63 @@ EOF
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
- arc:Linux:*:* | arceb:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
+ arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*)
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
arm*:Linux:*:*)
set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
+ GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi
else
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
+ GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf
fi
fi
- exit ;;
+ ;;
avr32*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
cris:Linux:*:*)
- echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+ ;;
crisv32:Linux:*:*)
- echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+ ;;
e2k:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
frv:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
hexagon:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
i*86:Linux:*:*)
- echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-linux-$LIBC
+ ;;
ia64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
k1om:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
m32r*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
m68*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
mips:Linux:*:* | mips64:Linux:*:*)
set_cc_for_build
IS_GLIBC=0
@@ -1049,65 +1086,66 @@ EOF
#endif
#endif
EOF
- eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')"
+ cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`
+ eval "$cc_set_vars"
test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
;;
mips64el:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
openrisc*:Linux:*:*)
- echo or1k-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=or1k-unknown-linux-$LIBC
+ ;;
or32:Linux:*:* | or1k*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
padre:Linux:*:*)
- echo sparc-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=sparc-unknown-linux-$LIBC
+ ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=hppa64-unknown-linux-$LIBC
+ ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
- case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in
- PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
- PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
- *) echo hppa-unknown-linux-"$LIBC" ;;
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;;
+ PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;;
+ *) GUESS=hppa-unknown-linux-$LIBC ;;
esac
- exit ;;
+ ;;
ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpc64-unknown-linux-$LIBC
+ ;;
ppc:Linux:*:*)
- echo powerpc-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpc-unknown-linux-$LIBC
+ ;;
ppc64le:Linux:*:*)
- echo powerpc64le-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpc64le-unknown-linux-$LIBC
+ ;;
ppcle:Linux:*:*)
- echo powerpcle-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpcle-unknown-linux-$LIBC
+ ;;
riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
s390:Linux:*:* | s390x:Linux:*:*)
- echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-ibm-linux-$LIBC
+ ;;
sh64*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
sh*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
tile*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
vax:Linux:*:*)
- echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-dec-linux-$LIBC
+ ;;
x86_64:Linux:*:*)
set_cc_for_build
LIBCABI=$LIBC
@@ -1116,71 +1154,71 @@ EOF
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_X32 >/dev/null
then
- LIBCABI="$LIBC"x32
+ LIBCABI=${LIBC}x32
fi
fi
- echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI
+ ;;
xtensa*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
- echo i386-sequent-sysv4
- exit ;;
+ GUESS=i386-sequent-sysv4
+ ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
- echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
+ ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
- echo "$UNAME_MACHINE"-pc-os2-emx
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-os2-emx
+ ;;
i*86:XTS-300:*:STOP)
- echo "$UNAME_MACHINE"-unknown-stop
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-stop
+ ;;
i*86:atheos:*:*)
- echo "$UNAME_MACHINE"-unknown-atheos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-atheos
+ ;;
i*86:syllable:*:*)
- echo "$UNAME_MACHINE"-pc-syllable
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-syllable
+ ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
- echo i386-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=i386-unknown-lynxos$UNAME_RELEASE
+ ;;
i*86:*DOS:*:*)
- echo "$UNAME_MACHINE"-pc-msdosdjgpp
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-msdosdjgpp
+ ;;
i*86:*:4.*:*)
- UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//')
+ UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL
else
- echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL
fi
- exit ;;
+ ;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
- case $(/bin/uname -X | grep "^Machine") in
+ case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
- echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
- UNAME_REL=$(sed -n 's/.*Version //p' </usr/options/cb.name)
- echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ GUESS=$UNAME_MACHINE-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //'))
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
@@ -1188,11 +1226,11 @@ EOF
&& UNAME_MACHINE=i686
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
- echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL
else
- echo "$UNAME_MACHINE"-pc-sysv32
+ GUESS=$UNAME_MACHINE-pc-sysv32
fi
- exit ;;
+ ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
@@ -1200,37 +1238,37 @@ EOF
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configure will decide that
# this is a cross-build.
- echo i586-pc-msdosdjgpp
- exit ;;
+ GUESS=i586-pc-msdosdjgpp
+ ;;
Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
+ GUESS=i386-pc-mach3
+ ;;
paragon:*:*:*)
- echo i860-intel-osf1
- exit ;;
+ GUESS=i860-intel-osf1
+ ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
+ GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4
+ GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4
fi
- exit ;;
+ ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
- echo m68010-convergent-sysv
- exit ;;
+ GUESS=m68010-convergent-sysv
+ ;;
mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit ;;
+ GUESS=m68k-convergent-sysv
+ ;;
M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit ;;
+ GUESS=m68k-diab-dnix
+ ;;
M68*:*:R3V[5678]*:*)
test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
- && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
@@ -1241,7 +1279,7 @@ EOF
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3'
test -r /etc/.relid \
- && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
@@ -1249,118 +1287,118 @@ EOF
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
&& { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-unknown-lynxos$UNAME_RELEASE
+ ;;
mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
+ GUESS=m68k-atari-sysv4
+ ;;
TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=sparc-unknown-lynxos$UNAME_RELEASE
+ ;;
rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=rs6000-unknown-lynxos$UNAME_RELEASE
+ ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-unknown-lynxos$UNAME_RELEASE
+ ;;
SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-dde-sysv$UNAME_RELEASE
+ ;;
RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
+ GUESS=mips-sni-sysv4
+ ;;
RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
+ GUESS=mips-sni-sysv4
+ ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=$( (uname -p) 2>/dev/null)
- echo "$UNAME_MACHINE"-sni-sysv4
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ GUESS=$UNAME_MACHINE-sni-sysv4
else
- echo ns32k-sni-sysv
+ GUESS=ns32k-sni-sysv
fi
- exit ;;
+ ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
+ GUESS=i586-unisys-sysv4
+ ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
+ GUESS=hppa1.1-stratus-sysv4
+ ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- exit ;;
+ GUESS=i860-stratus-sysv4
+ ;;
i*86:VOS:*:*)
# From Paul.Green@stratus.com.
- echo "$UNAME_MACHINE"-stratus-vos
- exit ;;
+ GUESS=$UNAME_MACHINE-stratus-vos
+ ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
- echo hppa1.1-stratus-vos
- exit ;;
+ GUESS=hppa1.1-stratus-vos
+ ;;
mc68*:A/UX:*:*)
- echo m68k-apple-aux"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-apple-aux$UNAME_RELEASE
+ ;;
news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
+ GUESS=mips-sony-newsos6
+ ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if test -d /usr/nec; then
- echo mips-nec-sysv"$UNAME_RELEASE"
+ GUESS=mips-nec-sysv$UNAME_RELEASE
else
- echo mips-unknown-sysv"$UNAME_RELEASE"
+ GUESS=mips-unknown-sysv$UNAME_RELEASE
fi
- exit ;;
+ ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
+ GUESS=powerpc-be-beos
+ ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
+ GUESS=powerpc-apple-beos
+ ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
+ GUESS=i586-pc-beos
+ ;;
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
- echo i586-pc-haiku
- exit ;;
+ GUESS=i586-pc-haiku
+ ;;
x86_64:Haiku:*:*)
- echo x86_64-unknown-haiku
- exit ;;
+ GUESS=x86_64-unknown-haiku
+ ;;
SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx4-nec-superux$UNAME_RELEASE
+ ;;
SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx5-nec-superux$UNAME_RELEASE
+ ;;
SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx6-nec-superux$UNAME_RELEASE
+ ;;
SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx7-nec-superux$UNAME_RELEASE
+ ;;
SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx8-nec-superux$UNAME_RELEASE
+ ;;
SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx8r-nec-superux$UNAME_RELEASE
+ ;;
SX-ACE:SUPER-UX:*:*)
- echo sxace-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sxace-nec-superux$UNAME_RELEASE
+ ;;
Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-apple-rhapsody$UNAME_RELEASE
+ ;;
*:Rhapsody:*:*)
- echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE
+ ;;
arm64:Darwin:*:*)
- echo aarch64-apple-darwin"$UNAME_RELEASE"
- exit ;;
+ GUESS=aarch64-apple-darwin$UNAME_RELEASE
+ ;;
*:Darwin:*:*)
- UNAME_PROCESSOR=$(uname -p)
+ UNAME_PROCESSOR=`uname -p`
case $UNAME_PROCESSOR in
unknown) UNAME_PROCESSOR=powerpc ;;
esac
@@ -1394,109 +1432,116 @@ EOF
# uname -m returns i386 or x86_64
UNAME_PROCESSOR=$UNAME_MACHINE
fi
- echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE
+ ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=$(uname -p)
+ UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = x86; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
- echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE
+ ;;
*:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
+ GUESS=i386-pc-qnx
+ ;;
NEO-*:NONSTOP_KERNEL:*:*)
- echo neo-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=neo-tandem-nsk$UNAME_RELEASE
+ ;;
NSE-*:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nse-tandem-nsk$UNAME_RELEASE
+ ;;
NSR-*:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nsr-tandem-nsk$UNAME_RELEASE
+ ;;
NSV-*:NONSTOP_KERNEL:*:*)
- echo nsv-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nsv-tandem-nsk$UNAME_RELEASE
+ ;;
NSX-*:NONSTOP_KERNEL:*:*)
- echo nsx-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nsx-tandem-nsk$UNAME_RELEASE
+ ;;
*:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
+ GUESS=mips-compaq-nonstopux
+ ;;
BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
+ GUESS=bs2000-siemens-sysv
+ ;;
DS/*:UNIX_System_V:*:*)
- echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE
+ ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
- # shellcheck disable=SC2154
- if test "$cputype" = 386; then
+ if test "${cputype-}" = 386; then
UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
+ elif test "x${cputype-}" != x; then
+ UNAME_MACHINE=$cputype
fi
- echo "$UNAME_MACHINE"-unknown-plan9
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-plan9
+ ;;
*:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
+ GUESS=pdp10-unknown-tops10
+ ;;
*:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
+ GUESS=pdp10-unknown-tenex
+ ;;
KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
+ GUESS=pdp10-dec-tops20
+ ;;
XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
+ GUESS=pdp10-xkl-tops20
+ ;;
*:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
+ GUESS=pdp10-unknown-tops20
+ ;;
*:ITS:*:*)
- echo pdp10-unknown-its
- exit ;;
+ GUESS=pdp10-unknown-its
+ ;;
SEI:*:*:SEIUX)
- echo mips-sei-seiux"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-sei-seiux$UNAME_RELEASE
+ ;;
*:DragonFly:*:*)
- echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
- exit ;;
+ DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL
+ ;;
*:*VMS:*:*)
- UNAME_MACHINE=$( (uname -p) 2>/dev/null)
- case "$UNAME_MACHINE" in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- V*) echo vax-dec-vms ; exit ;;
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case $UNAME_MACHINE in
+ A*) GUESS=alpha-dec-vms ;;
+ I*) GUESS=ia64-dec-vms ;;
+ V*) GUESS=vax-dec-vms ;;
esac ;;
*:XENIX:*:SysV)
- echo i386-pc-xenix
- exit ;;
+ GUESS=i386-pc-xenix
+ ;;
i*86:skyos:*:*)
- echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')"
- exit ;;
+ SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`
+ GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL
+ ;;
i*86:rdos:*:*)
- echo "$UNAME_MACHINE"-pc-rdos
- exit ;;
- i*86:AROS:*:*)
- echo "$UNAME_MACHINE"-pc-aros
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-rdos
+ ;;
+ *:AROS:*:*)
+ GUESS=$UNAME_MACHINE-unknown-aros
+ ;;
x86_64:VMkernel:*:*)
- echo "$UNAME_MACHINE"-unknown-esx
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-esx
+ ;;
amd64:Isilon\ OneFS:*:*)
- echo x86_64-unknown-onefs
- exit ;;
+ GUESS=x86_64-unknown-onefs
+ ;;
*:Unleashed:*:*)
- echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
+ ;;
esac
+# Do we have a guess based on uname results?
+if test "x$GUESS" != x; then
+ echo "$GUESS"
+ exit
+fi
+
# No uname command or uname output not recognized.
set_cc_for_build
cat > "$dummy.c" <<EOF
@@ -1536,7 +1581,7 @@ main ()
#define __ARCHITECTURE__ "m68k"
#endif
int version;
- version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null);
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
@@ -1628,7 +1673,7 @@ main ()
}
EOF
-$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) &&
+$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment.
@@ -1636,7 +1681,7 @@ test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }
echo "$0: unable to guess system type" >&2
-case "$UNAME_MACHINE:$UNAME_SYSTEM" in
+case $UNAME_MACHINE:$UNAME_SYSTEM in
mips:Linux | mips64:Linux)
# If we got here on MIPS GNU/Linux, output extra information.
cat >&2 <<EOF
@@ -1658,9 +1703,11 @@ and
https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
EOF
-year=$(echo $timestamp | sed 's,-.*,,')
+our_year=`echo $timestamp | sed 's,-.*,,'`
+thisyear=`date +%Y`
# shellcheck disable=SC2003
-if test "$(expr "$(date +%Y)" - "$year")" -lt 3 ; then
+script_age=`expr "$thisyear" - "$our_year"`
+if test "$script_age" -lt 3 ; then
cat >&2 <<EOF
If $0 has already been updated, send the following data and any
@@ -1669,20 +1716,20 @@ provide the necessary information to handle your system.
config.guess timestamp = $timestamp
-uname -m = $( (uname -m) 2>/dev/null || echo unknown)
-uname -r = $( (uname -r) 2>/dev/null || echo unknown)
-uname -s = $( (uname -s) 2>/dev/null || echo unknown)
-uname -v = $( (uname -v) 2>/dev/null || echo unknown)
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
-/usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null)
-/bin/uname -X = $( (/bin/uname -X) 2>/dev/null)
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-hostinfo = $( (hostinfo) 2>/dev/null)
-/bin/universe = $( (/bin/universe) 2>/dev/null)
-/usr/bin/arch -k = $( (/usr/bin/arch -k) 2>/dev/null)
-/bin/arch = $( (/bin/arch) 2>/dev/null)
-/usr/bin/oslevel = $( (/usr/bin/oslevel) 2>/dev/null)
-/usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null)
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
UNAME_MACHINE = "$UNAME_MACHINE"
UNAME_RELEASE = "$UNAME_RELEASE"
diff --git a/build-aux/config.sub b/build-aux/config.sub
index b0f8492348d..d74fb6deac9 100755
--- a/build-aux/config.sub
+++ b/build-aux/config.sub
@@ -2,7 +2,9 @@
# Configuration validation subroutine script.
# Copyright 1992-2021 Free Software Foundation, Inc.
-timestamp='2021-01-07'
+# shellcheck disable=SC2006,SC2268 # see below for rationale
+
+timestamp='2021-08-14'
# 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
@@ -50,7 +52,14 @@ timestamp='2021-01-07'
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
-me=$(echo "$0" | sed -e 's,.*/,,')
+# The "shellcheck disable" line above the timestamp inhibits complaints
+# about features and limitations of the classic Bourne shell that were
+# superseded or lifted in POSIX. However, this script identifies a wide
+# variety of pre-POSIX systems that do not have POSIX shells at all, and
+# even some reasonably current systems (Solaris 10 as case-in-point) still
+# have a pre-POSIX /bin/sh.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
@@ -112,9 +121,11 @@ esac
# Split fields of configuration type
# shellcheck disable=SC2162
+saved_IFS=$IFS
IFS="-" read field1 field2 field3 field4 <<EOF
$1
EOF
+IFS=$saved_IFS
# Separate into logical components for further validation
case $1 in
@@ -163,6 +174,10 @@ case $1 in
basic_machine=$field1
basic_os=$field2
;;
+ zephyr*)
+ basic_machine=$field1-unknown
+ basic_os=$field2
+ ;;
# Manufacturers
dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
| att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
@@ -769,22 +784,22 @@ case $basic_machine in
vendor=hp
;;
i*86v32)
- cpu=$(echo "$1" | sed -e 's/86.*/86/')
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=sysv32
;;
i*86v4*)
- cpu=$(echo "$1" | sed -e 's/86.*/86/')
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=sysv4
;;
i*86v)
- cpu=$(echo "$1" | sed -e 's/86.*/86/')
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=sysv
;;
i*86sol2)
- cpu=$(echo "$1" | sed -e 's/86.*/86/')
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
basic_os=solaris2
;;
@@ -917,14 +932,16 @@ case $basic_machine in
;;
leon-*|leon[3-9]-*)
cpu=sparc
- vendor=$(echo "$basic_machine" | sed 's/-.*//')
+ vendor=`echo "$basic_machine" | sed 's/-.*//'`
;;
*-*)
# shellcheck disable=SC2162
+ saved_IFS=$IFS
IFS="-" read cpu vendor <<EOF
$basic_machine
EOF
+ IFS=$saved_IFS
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
@@ -1084,7 +1101,7 @@ case $cpu-$vendor in
cpu=mipsisa64sb1el
;;
sh5e[lb]-*)
- cpu=$(echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/')
+ cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
;;
spur-*)
cpu=spur
@@ -1102,7 +1119,7 @@ case $cpu-$vendor in
cpu=x86_64
;;
xscale-* | xscalee[bl]-*)
- cpu=$(echo "$cpu" | sed 's/^xscale/arm/')
+ cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
;;
arm64-*)
cpu=aarch64
@@ -1165,7 +1182,7 @@ case $cpu-$vendor in
| alphapca5[67] | alpha64pca5[67] \
| am33_2.0 \
| amdgcn \
- | arc | arceb \
+ | arc | arceb | arc32 | arc64 \
| arm | arm[lb]e | arme[lb] | armv* \
| avr | avr32 \
| asmjs \
@@ -1204,9 +1221,13 @@ case $cpu-$vendor in
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r3 | mipsisa32r3el \
+ | mipsisa32r5 | mipsisa32r5el \
| mipsisa32r6 | mipsisa32r6el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r3 | mipsisa64r3el \
+ | mipsisa64r5 | mipsisa64r5el \
| mipsisa64r6 | mipsisa64r6el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
@@ -1288,30 +1309,32 @@ then
case $basic_os in
gnu/linux*)
kernel=linux
- os=$(echo $basic_os | sed -e 's|gnu/linux|gnu|')
+ os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'`
;;
os2-emx)
kernel=os2
- os=$(echo $basic_os | sed -e 's|os2-emx|emx|')
+ os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'`
;;
nto-qnx*)
kernel=nto
- os=$(echo $basic_os | sed -e 's|nto-qnx|qnx|')
+ os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'`
;;
*-*)
# shellcheck disable=SC2162
+ saved_IFS=$IFS
IFS="-" read kernel os <<EOF
$basic_os
EOF
+ IFS=$saved_IFS
;;
# Default OS when just kernel was specified
nto*)
kernel=nto
- os=$(echo $basic_os | sed -e 's|nto|qnx|')
+ os=`echo "$basic_os" | sed -e 's|nto|qnx|'`
;;
linux*)
kernel=linux
- os=$(echo $basic_os | sed -e 's|linux|gnu|')
+ os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
;;
*)
kernel=
@@ -1332,7 +1355,7 @@ case $os in
os=cnk
;;
solaris1 | solaris1.*)
- os=$(echo $os | sed -e 's|solaris1|sunos4|')
+ os=`echo "$os" | sed -e 's|solaris1|sunos4|'`
;;
solaris)
os=solaris2
@@ -1361,7 +1384,7 @@ case $os in
os=sco3.2v4
;;
sco3.2.[4-9]*)
- os=$(echo $os | sed -e 's/sco3.2./sco3.2v/')
+ os=`echo "$os" | sed -e 's/sco3.2./sco3.2v/'`
;;
sco*v* | scout)
# Don't match below
@@ -1391,7 +1414,7 @@ case $os in
os=lynxos
;;
mac[0-9]*)
- os=$(echo "$os" | sed -e 's|mac|macos|')
+ os=`echo "$os" | sed -e 's|mac|macos|'`
;;
opened*)
os=openedition
@@ -1400,10 +1423,10 @@ case $os in
os=os400
;;
sunos5*)
- os=$(echo "$os" | sed -e 's|sunos5|solaris2|')
+ os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
;;
sunos6*)
- os=$(echo "$os" | sed -e 's|sunos6|solaris3|')
+ os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
;;
wince*)
os=wince
@@ -1437,7 +1460,7 @@ case $os in
;;
# Preserve the version number of sinix5.
sinix5.*)
- os=$(echo $os | sed -e 's|sinix|sysv|')
+ os=`echo "$os" | sed -e 's|sinix|sysv|'`
;;
sinix*)
os=sysv4
@@ -1683,12 +1706,15 @@ fi
# Now, validate our (potentially fixed-up) OS.
case $os in
- # Sometimes we do "kernel-abi", so those need to count as OSes.
- musl* | newlib* | uclibc*)
+ # Sometimes we do "kernel-libc", so those need to count as OSes.
+ musl* | newlib* | relibc* | uclibc*)
;;
- # Likewise for "kernel-libc"
+ # Likewise for "kernel-abi"
eabi* | gnueabi*)
;;
+ # VxWorks passes extra cpu info in the 4th filed.
+ simlinux | simwindows | spe)
+ ;;
# Now accept the basic system types.
# The portable systems comes first.
# Each alternative MUST end in a * to match a version number.
@@ -1704,12 +1730,12 @@ case $os in
| nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
| clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
| mirbsd* | netbsd* | dicos* | openedition* | ose* \
- | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \
+ | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \
| ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
| bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
| ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
| udi* | lites* | ieee* | go32* | aux* | hcos* \
- | chorusrdb* | cegcc* | glidix* \
+ | chorusrdb* | cegcc* | glidix* | serenity* \
| cygwin* | msys* | pe* | moss* | proelf* | rtems* \
| midipix* | mingw32* | mingw64* | mint* \
| uxpv* | beos* | mpeix* | udk* | moxiebox* \
@@ -1722,7 +1748,7 @@ case $os in
| skyos* | haiku* | rdos* | toppers* | drops* | es* \
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
- | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx*)
+ | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr*)
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
@@ -1739,11 +1765,12 @@ esac
# As a final step for OS-related things, validate the OS-kernel combination
# (given a valid OS), if there is a kernel.
case $kernel-$os in
- linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* )
+ linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
+ | linux-musl* | linux-relibc* | linux-uclibc* )
;;
uclinux-uclibc* )
;;
- -dietlibc* | -newlib* | -musl* | -uclibc* )
+ -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* )
# These are just libc implementations, not actual OSes, and thus
# require a kernel.
echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
@@ -1751,6 +1778,8 @@ case $kernel-$os in
;;
kfreebsd*-gnu* | kopensolaris*-gnu*)
;;
+ vxworks-simlinux | vxworks-simwindows | vxworks-spe)
+ ;;
nto-qnx*)
;;
os2-emx)
diff --git a/build-aux/gitlog-to-changelog b/build-aux/gitlog-to-changelog
index de76f658d48..9ff15f60198 100755
--- a/build-aux/gitlog-to-changelog
+++ b/build-aux/gitlog-to-changelog
@@ -35,7 +35,7 @@
eval 'exec perl -wSx "$0" "$@"'
if 0;
-my $VERSION = '2020-04-04 15:07'; # UTC
+my $VERSION = '2021-02-24 23:42'; # UTC
# The definition above must lie within the first 8 lines in order
# for the Emacs time-stamp write hook (at end) to update it.
# If you change this file with Emacs, please let the write hook
@@ -455,7 +455,8 @@ sub git_dir_option($)
# If there were any lines
if (@line == 0)
{
- warn "$ME: warning: empty commit message:\n $date_line\n";
+ warn "$ME: warning: empty commit message:\n"
+ . " commit $sha\n $date_line\n";
}
else
{
diff --git a/config.bat b/config.bat
index cba73360992..e4332cd3263 100644
--- a/config.bat
+++ b/config.bat
@@ -283,6 +283,7 @@ If Exist execinfo.in.h update execinfo.in.h execinfo.in-h
If Exist fcntl.in.h update fcntl.in.h fcntl.in-h
If Exist getopt.in.h update getopt.in.h getopt.in-h
If Exist getopt-cdefs.in.h update getopt-cdefs.in.h getopt-cdefs.in-h
+If Exist ieee754.in.h update ieee754.in.h ieee754.in-h
If Exist inttypes.in.h update inttypes.in.h inttypes.in-h
If Exist limits.in.h update limits.in.h limits.in-h
If Exist signal.in.h update signal.in.h signal.in-h
@@ -293,6 +294,7 @@ If Exist stdint.in.h update stdint.in.h stdint.in-h
If Exist stdio.in.h update stdio.in.h stdio.in-h
If Exist stdlib.in.h update stdlib.in.h stdlib.in-h
If Exist string.in.h update string.in.h string.in-h
+If Exist sys_random.in.h update sys_random.in.h sys_random.in-h
If Exist sys_select.in.h update sys_select.in.h sys_select.in-h
If Exist sys_stat.in.h update sys_stat.in.h sys_stat.in-h
If Exist sys_time.in.h update sys_time.in.h sys_time.in-h
@@ -308,10 +310,13 @@ rm -f makefile.tmp
sed -f ../msdos/sedlibcf.inp < gnulib.mk-in > gnulib.tmp
sed -f ../msdos/sedlibmk.inp < gnulib.tmp > gnulib.mk
rm -f gnulib.tmp
-Rem Create .d files for new files in lib/
+Rem Create .d files for new files in lib/ and lib/malloc/
If Not Exist deps\stamp mkdir deps
for %%f in (*.c) do @call ..\msdos\depfiles.bat %%f
echo deps-stamp > deps\stamp
+If Not Exist deps\malloc\stamp mkdir deps\malloc
+for %%f in (malloc\*.c) do @call ..\msdos\depfiles.bat %%f
+echo deps-stamp > deps\malloc\stamp
cd ..
rem ----------------------------------------------------------------------
Echo Configuring the lisp directory...
diff --git a/configure.ac b/configure.ac
index eff55915436..c00233edecb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@ dnl along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
AC_PREREQ(2.65)
dnl Note this is parsed by (at least) make-dist and lisp/cedet/ede/emacs.el.
-AC_INIT(GNU Emacs, 28.0.50, bug-gnu-emacs@gnu.org, , https://www.gnu.org/software/emacs/)
+AC_INIT(GNU Emacs, 29.0.50, bug-gnu-emacs@gnu.org, , https://www.gnu.org/software/emacs/)
dnl Set emacs_config_options to the options of 'configure', quoted for the shell,
dnl and then quoted again for a C string. Separate options with spaces.
@@ -447,6 +447,8 @@ OPTION_DEFAULT_ON([tiff],[don't compile with TIFF image support])
OPTION_DEFAULT_ON([gif],[don't compile with GIF image support])
OPTION_DEFAULT_ON([png],[don't compile with PNG image support])
OPTION_DEFAULT_ON([rsvg],[don't compile with SVG image support])
+OPTION_DEFAULT_ON([webp],[don't compile with WebP image support])
+OPTION_DEFAULT_ON([sqlite3],[don't compile with sqlite3 support])
OPTION_DEFAULT_ON([lcms2],[don't compile with Little CMS support])
OPTION_DEFAULT_ON([libsystemd],[don't compile with libsystemd support])
OPTION_DEFAULT_ON([cairo],[don't compile with Cairo drawing])
@@ -468,6 +470,7 @@ AC_ARG_WITH([ns],[AS_HELP_STRING([--with-ns],
[use Nextstep (macOS Cocoa or GNUstep) windowing system.
On by default on macOS.])],[],[with_ns=maybe])
OPTION_DEFAULT_OFF([w32], [use native MS Windows GUI in a Cygwin build])
+OPTION_DEFAULT_OFF([pgtk], [use pure GTK build without reliance on X libs (Wayland support) (requires cairo) - Experimental])
OPTION_DEFAULT_ON([gpm],[don't use -lgpm for mouse support on a GNU/Linux console])
OPTION_DEFAULT_ON([dbus],[don't compile with D-Bus support])
@@ -485,6 +488,8 @@ 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_OFF([xinput2],[use version 2 of the X Input Extension for input])
AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB],
[use a file notification library (LIB one of: yes, inotify, kqueue, gfile, w32, no)])],
@@ -508,6 +513,12 @@ otherwise for the first of 'inotify', 'kqueue' or 'gfile' that is usable.])
OPTION_DEFAULT_OFF([xwidgets],
[enable use of xwidgets in Emacs buffers (requires gtk3 or macOS Cocoa)])
+OPTION_DEFAULT_OFF([be-app],
+ [enable use of Haiku's Application Kit as a window system])
+
+OPTION_DEFAULT_OFF([be-cairo],
+ [enable use of cairo under Haiku's Application Kit])
+
## Makefile.in needs the cache file name.
AC_SUBST(cache_file)
@@ -784,6 +795,10 @@ case "${canonical}" in
LDFLAGS="-N2M $LDFLAGS"
;;
+ *-haiku )
+ opsys=haiku
+ ;;
+
## Intel 386 machines where we don't care about the manufacturer.
i[3456]86-*-* )
case "${canonical}" in
@@ -875,8 +890,8 @@ done
ac_func_list=$funcs
# Emacs does not use the wchar or wctype-h modules.
AC_DEFUN([gt_TYPE_WINT_T],
- [GNULIB_OVERRIDES_WINT_T=0
- AC_SUBST([GNULIB_OVERRIDES_WINT_T])])
+ [GNULIBHEADERS_OVERRIDE_WINT_T=0
+ AC_SUBST([GNULIBHEADERS_OVERRIDE_WINT_T])])
# Initialize gnulib right after choosing the compiler.
dnl Amongst other things, this sets AR and ARFLAGS.
@@ -905,7 +920,9 @@ if test "$ac_test_CFLAGS" != set; then
if test $emacs_cv_prog_cc_g3 != yes; then
CFLAGS=$emacs_save_CFLAGS
fi
- if test $opsys = mingw32; then
+ # Haiku also needs -gdwarf-2 because its GDB is too old
+ # to understand newer formats.
+ if test $opsys = mingw32 || test $opsys = haiku; then
CFLAGS="$CFLAGS -gdwarf-2"
fi
fi
@@ -1335,7 +1352,9 @@ if test -n "$BREW"; then
fi
# Check MacPorts on macOS.
-AC_PATH_PROG(HAVE_MACPORTS, port)
+if test $opsys = darwin; then
+ AC_PATH_PROG(HAVE_MACPORTS, port)
+fi
## Require makeinfo >= 4.13 (last of the 4.x series) to build the manuals.
: ${MAKEINFO:=makeinfo}
@@ -1570,6 +1589,8 @@ case "$opsys" in
## Motif needs -lgen.
unixware) LIBS_SYSTEM="-lsocket -lnsl -lelf -lgen" ;;
+
+ haiku) LIBS_SYSTEM="-lnetwork" ;;
esac
AC_SUBST(LIBS_SYSTEM)
@@ -1820,8 +1841,14 @@ AC_SUBST(AUTO_DEPEND)
## window-system-specific substs.
window_system=none
+
+if test "${with_pgtk}" = "yes"; then
+ window_system=pgtk
+fi
+
+
AC_PATH_X
-if test "$no_x" != yes; then
+if test "$no_x" != yes && test "${with_pgtk}" != "yes"; then
window_system=x11
fi
@@ -2075,6 +2102,22 @@ if test "${HAVE_NS}" = yes; then
fi
fi
+HAVE_BE_APP=no
+if test "${opsys}" = "haiku" && test "${with_be_app}" = "yes"; then
+ dnl Only GCC is supported. Clang might work, but it's
+ dnl not reliable, so don't check for it here.
+ AC_PROG_CXX([gcc g++])
+ CXXFLAGS="$CXXFLAGS $emacs_g3_CFLAGS"
+ AC_LANG_PUSH([C++])
+ AC_CHECK_HEADER([app/Application.h], [HAVE_BE_APP=yes],
+ [AC_MSG_ERROR([The Application Kit headers required for building
+with the Application Kit were not found or cannot be compiled. Either fix this, or
+re-configure with the option '--without-be-app'.])])
+ AC_LANG_POP([C++])
+fi
+
+AC_SUBST(HAVE_BE_APP)
+
HAVE_W32=no
W32_OBJ=
W32_LIBS=
@@ -2196,6 +2239,39 @@ if test "${HAVE_W32}" = "yes"; then
with_xft=no
fi
+HAIKU_OBJ=
+HAIKU_CXX_OBJ=
+HAIKU_LIBS=
+HAIKU_CFLAGS=
+
+if test "$opsys" = "haiku"; then
+ HAIKU_OBJ="$HAIKU_OBJ haiku.o"
+fi
+
+if test "${HAVE_BE_APP}" = "yes"; then
+ AC_DEFINE([HAVE_HAIKU], 1,
+ [Define if Emacs will be built with Haiku windowing support])
+fi
+
+if test "${HAVE_BE_APP}" = "yes"; then
+ window_system=haiku
+ with_xft=no
+ HAIKU_OBJ="$HAIKU_OBJ haikufns.o haikuterm.o haikumenu.o haikufont.o haikuselect.o haiku_io.o"
+ HAIKU_CXX_OBJ="haiku_support.o haiku_font_support.o haiku_draw_support.o haiku_select.o"
+ HAIKU_LIBS="-lbe -lgame -ltranslation -ltracker" # -lgame is needed for set_mouse_position.
+
+ if test "${with_native_image_api}" = yes; then
+ AC_DEFINE(HAVE_NATIVE_IMAGE_API, 1, [Define to use native OS APIs for images.])
+ NATIVE_IMAGE_API="yes (haiku)"
+ HAIKU_OBJ="$HAIKU_OBJ haikuimage.o"
+ fi
+fi
+
+AC_SUBST(HAIKU_LIBS)
+AC_SUBST(HAIKU_OBJ)
+AC_SUBST(HAIKU_CXX_OBJ)
+AC_SUBST(HAIKU_CFLAGS)
+
## $window_system is now set to the window system we will
## ultimately use.
@@ -2235,6 +2311,14 @@ dnl use the toolkit if we have gtk, or X11R5 or newer.
w32 )
term_header=w32term.h
;;
+ pgtk )
+ term_header=pgtkterm.h
+ with_gtk3=yes
+ USE_X_TOOLKIT=none
+ ;;
+ haiku )
+ term_header=haikuterm.h
+ ;;
esac
if test "$window_system" = none && test "X$with_x" != "Xno"; then
@@ -2566,7 +2650,9 @@ fi
### Use -lrsvg-2 if available, unless '--with-rsvg=no' is specified.
HAVE_RSVG=no
-if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${opsys}" = "mingw32"; then
+if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" \
+ || test "${opsys}" = "mingw32" || test "${HAVE_BE_APP}" = "yes" \
+ || test "${window_system}" = "pgtk"; then
if test "${with_rsvg}" != "no"; then
RSVG_REQUIRED=2.14.0
RSVG_MODULE="librsvg-2.0 >= $RSVG_REQUIRED"
@@ -2586,8 +2672,53 @@ if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${opsys}" =
fi
fi
+### Use -lwebp if available, unless '--with-webp=no'
+HAVE_WEBP=no
+if test "${with_webp}" != "no"; then
+ if test "${HAVE_X11}" = "yes" || test "${opsys}" = "mingw32" \
+ || test "${HAVE_W32}" = "yes" || test "${HAVE_NS}" = "yes" \
+ || test "${HAVE_BE_APP}" = "yes"; then
+ WEBP_REQUIRED=0.6.0
+ WEBP_MODULE="libwebp >= $WEBP_REQUIRED"
+
+ EMACS_CHECK_MODULES([WEBP], [$WEBP_MODULE])
+ AC_SUBST(WEBP_CFLAGS)
+ AC_SUBST(WEBP_LIBS)
+ fi
+ if test $HAVE_WEBP = yes; then
+ AC_DEFINE(HAVE_WEBP, 1, [Define to 1 if using libwebp.])
+ CFLAGS="$CFLAGS $WEBP_CFLAGS"
+ # Windows loads libwebp dynamically
+ if test "${opsys}" = "mingw32"; then
+ WEBP_LIBS=
+ fi
+ fi
+fi
+
+### Use -lsqlite3 if available, unless '--with-sqlite3=no'
+HAVE_SQLITE3=no
+if test "${with_sqlite3}" != "no"; then
+ AC_CHECK_LIB(sqlite3, sqlite3_open_v2, HAVE_SQLITE3=yes, HAVE_SQLITE3=no)
+ if test "$HAVE_SQLITE3" = "yes"; then
+ SQLITE3_LIBS=-lsqlite3
+ AC_SUBST(SQLITE3_LIBS)
+ LIBS="$SQLITE3_LIBS $LIBS"
+ AC_DEFINE(HAVE_SQLITE3, 1, [Define to 1 if you have the libsqlite3 library (-lsqlite).])
+ # Windows loads libsqlite dynamically
+ if test "${opsys}" = "mingw32"; then
+ SQLITE3_LIBS=
+ fi
+ AC_CHECK_LIB(sqlite3, sqlite3_load_extension,
+ HAVE_SQLITE3_LOAD_EXTENSION=yes, HAVE_SQLITE3_LOAD_EXTENSION=no)
+ if test "$HAVE_SQLITE3_LOAD_EXTENSION" = "yes"; then
+ AC_DEFINE(HAVE_SQLITE3_LOAD_EXTENSION, 1, [Define to 1 if sqlite3 supports loading extensions.])
+ fi
+ fi
+fi
+
HAVE_IMAGEMAGICK=no
-if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${HAVE_W32}" = "yes"; then
+if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${HAVE_W32}" = "yes" || \
+ test "${HAVE_BE_APP}" = "yes" || test "${window_system}" = "pgtk"; then
if test "${with_imagemagick}" != "no"; then
if test -n "$BREW"; then
# Homebrew doesn't link ImageMagick 6 by default, so make sure
@@ -2670,6 +2801,9 @@ if test "${opsys}" != "mingw32"; then
AC_DEFINE([GLIB_DISABLE_DEPRECATION_WARNINGS], [1],
[Define to 1 to disable Glib deprecation warnings.])
fi
+ if test "$window_system" = pgtk; then
+ GLIB_GSETTINGS
+ fi
else
check_gtk2=yes
gtk3_pkg_errors="$GTK_PKG_ERRORS "
@@ -2811,6 +2945,17 @@ AC_SUBST(XWIDGETS_OBJ)
CFLAGS=$OLD_CFLAGS
LIBS=$OLD_LIBS
+PGTK_OBJ=
+PGTK_LIBS=
+if test "$window_system" = "pgtk"; then
+ PGTK_OBJ="pgtkfns.o pgtkterm.o pgtkselect.o pgtkmenu.o pgtkim.o xsettings.o"
+ PGTK_LIBS="$GTK_LIBS"
+ HAVE_PGTK=yes
+ AC_DEFINE([HAVE_PGTK], 1, [Define to 1 if you have pure Gtk+-3.])
+fi
+AC_SUBST(PGTK_OBJ)
+AC_SUBST(PGTK_LIBS)
+
dnl D-Bus has been tested under GNU/Linux only. Must be adapted for
dnl other platforms.
HAVE_DBUS=no
@@ -2840,7 +2985,7 @@ AC_SUBST(DBUS_OBJ)
dnl GSettings has been tested under GNU/Linux only.
HAVE_GSETTINGS=no
-if test "${HAVE_X11}" = "yes" && test "${with_gsettings}" = "yes"; then
+if test "${HAVE_X11}" = "yes" -o "${window_system}" = "pgtk" && test "${with_gsettings}" = "yes"; then
EMACS_CHECK_MODULES([GSETTINGS], [gio-2.0 >= 2.26])
if test "$HAVE_GSETTINGS" = "yes"; then
old_CFLAGS=$CFLAGS
@@ -2874,7 +3019,7 @@ fi
dnl GConf has been tested under GNU/Linux only.
dnl The version is really arbitrary, it is about the same age as Gtk+ 2.6.
HAVE_GCONF=no
-if test "${HAVE_X11}" = "yes" && test "${with_gconf}" != "no"; then
+if test "${HAVE_X11}" = "yes" -o "${window_system}" = "pgtk" && test "${with_gconf}" != "no"; then
EMACS_CHECK_MODULES([GCONF], [gconf-2.0 >= 2.13])
if test "$HAVE_GCONF" = yes; then
AC_DEFINE(HAVE_GCONF, 1, [Define to 1 if using GConf.])
@@ -3237,6 +3382,9 @@ if test "${with_toolkit_scroll_bars}" != "no"; then
elif test "${HAVE_W32}" = "yes"; then
AC_DEFINE(USE_TOOLKIT_SCROLL_BARS)
USE_TOOLKIT_SCROLL_BARS=yes
+ elif test "${HAVE_BE_APP}" = "yes"; then
+ AC_DEFINE(USE_TOOLKIT_SCROLL_BARS)
+ USE_TOOLKIT_SCROLL_BARS=yes
fi
fi
@@ -3327,6 +3475,39 @@ if test "${HAVE_X11}" = "yes"; then
fi
fi
+if test "$window_system" = "pgtk"; then
+ CAIRO_REQUIRED=1.12.0
+ CAIRO_MODULE="cairo >= $CAIRO_REQUIRED"
+ EMACS_CHECK_MODULES(CAIRO, $CAIRO_MODULE)
+ if test $HAVE_CAIRO = yes; then
+ AC_DEFINE(USE_CAIRO, 1, [Define to 1 if using cairo.])
+ else
+ AC_MSG_ERROR([cairo required but not found.])
+ fi
+
+ CFLAGS="$CFLAGS $CAIRO_CFLAGS"
+ LIBS="$LIBS $CAIRO_LIBS"
+ AC_SUBST(CAIRO_CFLAGS)
+ AC_SUBST(CAIRO_LIBS)
+fi
+
+if test "${HAVE_BE_APP}" = "yes"; then
+ if test "${with_be_cairo}" != "no"; then
+ CAIRO_REQUIRED=1.8.0
+ CAIRO_MODULE="cairo >= $CAIRO_REQUIRED"
+ EMACS_CHECK_MODULES(CAIRO, $CAIRO_MODULE)
+ if test $HAVE_CAIRO = yes; then
+ AC_DEFINE(USE_BE_CAIRO, 1, [Define to 1 if using cairo on Haiku.])
+ CFLAGS="$CFLAGS $CAIRO_CFLAGS"
+ LIBS="$LIBS $CAIRO_LIBS"
+ AC_SUBST(CAIRO_CFLAGS)
+ AC_SUBST(CAIRO_LIBS)
+ else
+ AC_MSG_WARN([cairo requested but not found.])
+ fi
+ fi
+fi
+
### Start of font-backend (under any platform) section.
# (nothing here yet -- this is a placeholder)
### End of font-backend (under any platform) section.
@@ -3446,10 +3627,34 @@ if test "${HAVE_X11}" = "yes"; then
fi
fi
else # "${HAVE_X11}" != "yes"
- HAVE_XFT=no
- HAVE_FREETYPE=no
- HAVE_LIBOTF=no
- HAVE_M17N_FLT=no
+ if test $window_system = pgtk; then
+ EMACS_CHECK_MODULES([FONTCONFIG], [fontconfig >= 2.2.0])
+ EMACS_CHECK_MODULES([FREETYPE], [freetype2])
+ if test "$HAVE_FONTCONFIG" != yes -o "$HAVE_FREETYPE" != yes; then
+ AC_MSG_ERROR(fontconfig and freetype is required.)
+ fi
+ HAVE_LIBOTF=no
+ AC_DEFINE(HAVE_FREETYPE, 1,
+ [Define to 1 if using the freetype and fontconfig libraries.])
+ if test "${with_libotf}" != "no"; then
+ EMACS_CHECK_MODULES([LIBOTF], [libotf])
+ if test "$HAVE_LIBOTF" = "yes"; then
+ AC_DEFINE(HAVE_LIBOTF, 1, [Define to 1 if using libotf.])
+ AC_CHECK_LIB(otf, OTF_get_variation_glyphs,
+ HAVE_OTF_GET_VARIATION_GLYPHS=yes,
+ HAVE_OTF_GET_VARIATION_GLYPHS=no)
+ if test "${HAVE_OTF_GET_VARIATION_GLYPHS}" = "yes"; then
+ AC_DEFINE(HAVE_OTF_GET_VARIATION_GLYPHS, 1,
+ [Define to 1 if libotf has OTF_get_variation_glyphs.])
+ fi
+ fi
+ fi
+ else
+ HAVE_XFT=no
+ HAVE_FREETYPE=no
+ HAVE_LIBOTF=no
+ HAVE_M17N_FLT=no
+ fi
fi # "${HAVE_X11}" != "yes"
HAVE_HARFBUZZ=no
@@ -3461,6 +3666,7 @@ else
harfbuzz_required_ver=0.9.42
fi
if test "${HAVE_X11}" = "yes" && test "${HAVE_FREETYPE}" = "yes" \
+ || test "$window_system" = "pgtk" \
|| test "${HAVE_W32}" = "yes"; then
if test "${with_harfbuzz}" != "no"; then
EMACS_CHECK_MODULES([HARFBUZZ], [harfbuzz >= $harfbuzz_required_ver])
@@ -3475,6 +3681,58 @@ if test "${HAVE_X11}" = "yes" && test "${HAVE_FREETYPE}" = "yes" \
fi
fi
+### Start of font-backend (under Haiku) selectionn.
+if test "${HAVE_BE_APP}" = "yes"; then
+ if test $HAVE_CAIRO = "yes"; then
+ EMACS_CHECK_MODULES([FREETYPE], [freetype2 >= 2.5.0])
+ test "$HAVE_FREETYPE" = "no" && AC_MSG_ERROR(cairo on Haiku requires libfreetype)
+ EMACS_CHECK_MODULES([FONTCONFIG], [fontconfig >= 2.2.0])
+ test "$HAVE_FONTCONFIG" = "no" && AC_MSG_ERROR(cairo on Haiku requires libfontconfig)
+ fi
+
+ HAVE_LIBOTF=no
+
+ if test "${HAVE_FREETYPE}" = "yes"; then
+ AC_DEFINE(HAVE_FREETYPE, 1,
+ [Define to 1 if using the freetype and fontconfig libraries.])
+ OLD_CFLAGS=$CFLAGS
+ OLD_LIBS=$LIBS
+ CFLAGS="$CFLAGS $FREETYPE_CFLAGS"
+ LIBS="$FREETYPE_LIBS $LIBS"
+ AC_CHECK_FUNCS(FT_Face_GetCharVariantIndex)
+ CFLAGS=$OLD_CFLAGS
+ LIBS=$OLD_LIBS
+ if test "${with_libotf}" != "no"; then
+ EMACS_CHECK_MODULES([LIBOTF], [libotf])
+ if test "$HAVE_LIBOTF" = "yes"; then
+ AC_DEFINE(HAVE_LIBOTF, 1, [Define to 1 if using libotf.])
+ AC_CHECK_LIB(otf, OTF_get_variation_glyphs,
+ HAVE_OTF_GET_VARIATION_GLYPHS=yes,
+ HAVE_OTF_GET_VARIATION_GLYPHS=no)
+ if test "${HAVE_OTF_GET_VARIATION_GLYPHS}" = "yes"; then
+ AC_DEFINE(HAVE_OTF_GET_VARIATION_GLYPHS, 1,
+ [Define to 1 if libotf has OTF_get_variation_glyphs.])
+ fi
+ if ! $PKG_CONFIG --atleast-version=0.9.16 libotf; then
+ AC_DEFINE(HAVE_OTF_KANNADA_BUG, 1,
+[Define to 1 if libotf is affected by https://debbugs.gnu.org/28110.])
+ fi
+ fi
+ fi
+ dnl FIXME should there be an error if HAVE_FREETYPE != yes?
+ dnl Does the new font backend require it, or can it work without it?
+ fi
+fi
+
+if test "${HAVE_BE_APP}" = "yes" && test "${HAVE_FREETYPE}" = "yes"; then
+ if test "${with_harfbuzz}" != "no"; then
+ EMACS_CHECK_MODULES([HARFBUZZ], [harfbuzz >= $harfbuzz_required_ver])
+ if test "$HAVE_HARFBUZZ" = "yes"; then
+ AC_DEFINE(HAVE_HARFBUZZ, 1, [Define to 1 if using HarfBuzz.])
+ fi
+ fi
+fi
+
### End of font-backend section.
AC_SUBST(FREETYPE_CFLAGS)
@@ -3596,7 +3854,8 @@ AC_SUBST(LIBXPM)
HAVE_JPEG=no
LIBJPEG=
if test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \
- || test "${HAVE_NS}" = "yes"; then
+ || test "${HAVE_NS}" = "yes" || test "${HAVE_BE_APP}" = "yes" \
+ || test "$window_system" = "pgtk"; then
if test "${with_jpeg}" != "no"; then
AC_CACHE_CHECK([for jpeglib 6b or later],
[emacs_cv_jpeglib],
@@ -3736,10 +3995,12 @@ AC_SUBST_FILE([module_env_snippet_25])
AC_SUBST_FILE([module_env_snippet_26])
AC_SUBST_FILE([module_env_snippet_27])
AC_SUBST_FILE([module_env_snippet_28])
+AC_SUBST_FILE([module_env_snippet_29])
module_env_snippet_25="$srcdir/src/module-env-25.h"
module_env_snippet_26="$srcdir/src/module-env-26.h"
module_env_snippet_27="$srcdir/src/module-env-27.h"
module_env_snippet_28="$srcdir/src/module-env-28.h"
+module_env_snippet_29="$srcdir/src/module-env-29.h"
emacs_major_version="${PACKAGE_VERSION%%.*}"
AC_SUBST(emacs_major_version)
@@ -3795,7 +4056,7 @@ AC_DEFUN([libgccjit_dev_not_found], [
not found.
Please try installing libgccjit-dev or a similar package.
If you are sure you want Emacs be compiled without ELisp native compiler,
-pass the --without-nativecomp option to configure.])])
+pass the --without-native-compilation option to configure.])])
AC_DEFUN([libgccjit_broken], [
AC_MSG_ERROR([The installed libgccjit failed to compile and run a test program using
@@ -3812,47 +4073,66 @@ source on this site:
HAVE_NATIVE_COMP=no
LIBGCCJIT_LIBS=
LIBGCCJIT_CFLAGS=
+if test "$canonical" = i686-pc-cygwin; then
+ if test "${with_cygwin32_native_compilation}" = yes; then
+ with_native_compilation=yes
+ elif test "${with_native_compilation}" != no; then
+ AC_MSG_ERROR([Native compilation is not supported on 32-bit Cygwin.
+If you really want to try it anyway, use the configure option
+'--with-cygwin32-native-compilation'.])
+ fi
+fi
+
if test "${with_native_compilation}" != "no"; then
if test "${HAVE_PDUMPER}" = no; then
- AC_MSG_ERROR(['--with-nativecomp' requires '--with-dumping=pdumper'])
+ AC_MSG_ERROR(['--with-native-compilation' requires '--with-dumping=pdumper'])
fi
if test "${HAVE_ZLIB}" = no; then
- AC_MSG_ERROR(['--with-nativecomp' requires zlib])
+ AC_MSG_ERROR(['--with-native-compilation' requires zlib])
fi
- # Ensure libgccjit installed by Homebrew can be found.
- if test -n "$BREW"; then
- BREW_LIBGCCJIT_PREFIX=`$BREW --prefix --installed libgccjit 2>/dev/null`
- if test "$BREW_LIBGCCJIT_PREFIX"; then
- brew_libdir=`find ${BREW_LIBGCCJIT_PREFIX}/ -name \*.so \
- | sed -e '1!d;s|/[[^/]]*\.so$||'`
- CFLAGS="$CFLAGS -I${BREW_LIBGCCJIT_PREFIX}/include"
- LDFLAGS="$LDFLAGS -L${brew_libdir} -I${BREW_LIBGCCJIT_PREFIX}/include"
+ SAVE_CFLAGS=$CFLAGS
+ SAVE_LIBS=$LIBS
+
+ if test "${opsys}" = "darwin"; then
+ # Ensure libgccjit installed by Homebrew or macports can be found.
+ if test -n "$BREW"; then
+ if test -n "`$BREW --prefix --installed libgccjit 2>/dev/null`"; then
+ MAC_CFLAGS="-I$(dirname $($BREW ls -v libgccjit | \
+ grep libgccjit.h))"
+ MAC_LIBS="-L$(dirname $($BREW ls -v libgccjit| \
+ grep libgccjit.so\$))"
+ fi
+ fi
+
+ if test -n "$HAVE_MACPORTS"; then
+ # Determine which gcc version has been installed (gcc11, for
+ # instance). Use the latest version, if more than one is
+ # available. (We filter out the gcc4 packages, because they
+ # don't support jit, and they have names like "gcc49" that
+ # sort later than "gcc11".)
+ PORT_PACKAGE=$(port installed active | grep '^ *gcc@<:@0-9@:>@* ' | \
+ awk '{ print $1; }' | grep -v 'gcc4@<:@0-9@:>@' | \
+ sort -V | tail -n 1)
+ if test -n "$PORT_PACKAGE"; then
+ MAC_CFLAGS="-I$(dirname $(port contents $PORT_PACKAGE | \
+ grep libgccjit.h))"
+ MAC_LIBS="-L$(dirname $(port contents $PORT_PACKAGE | \
+ grep libgccjit.dylib))"
+ fi
fi
- fi
- # Ensure libgccjit installed by MacPorts can be found.
- if test -n "$HAVE_MACPORTS"; then
- # Determine which gcc version has been installed (gcc11, for
- # instance).
- PORT_PACKAGE=$(port installed active | grep '^ *gcc@<:@0-9@:>@* ' | \
- awk '{ print $1; }')
- MACPORTS_LIBGCCJIT_INCLUDE=$(dirname $(port contents $PORT_PACKAGE | \
- grep libgccjit.h))
- MACPORTS_LIBGCCJIT_LIB=$(dirname $(port contents $PORT_PACKAGE | \
- grep libgccjit.dylib))
- CFLAGS="$CFLAGS -I${MACPORTS_LIBGCCJIT_INCLUDE}"
- LDFLAGS="$LDFLAGS -L${MACPORTS_LIBGCCJIT_LIB}"
+ if test -n "$MAC_CFLAGS" && test -n "$MAC_LIBS"; then
+ CFLAGS="$CFLAGS ${MAC_CFLAGS}"
+ LIBS="$LIBS ${MAC_LIBS}"
+ fi
fi
# Check if libgccjit is available.
AC_CHECK_LIB(gccjit, gcc_jit_context_acquire, [], [libgccjit_not_found])
AC_CHECK_HEADERS(libgccjit.h, [], [libgccjit_dev_not_found])
- emacs_save_LIBS=$LIBS
- LIBS="-lgccjit"
# Check if libgccjit really works.
AC_RUN_IFELSE([libgccjit_smoke_test], [], [libgccjit_broken])
- LIBS=$emacs_save_LIBS
HAVE_NATIVE_COMP=yes
case "${opsys}" in
# mingw32 loads the library dynamically.
@@ -3860,17 +4140,17 @@ if test "${with_native_compilation}" != "no"; then
# OpenBSD doesn't have libdl, all the functions are in libc
netbsd|openbsd)
LIBGCCJIT_LIBS="-lgccjit" ;;
+ darwin)
+ LIBGCCJIT_CFLAGS="${MAC_CFLAGS}"
+ LIBGCCJIT_LIBS="${MAC_LIBS} -lgccjit -ldl";;
*)
LIBGCCJIT_LIBS="-lgccjit -ldl" ;;
esac
NEED_DYNLIB=yes
AC_DEFINE(HAVE_NATIVE_COMP, 1, [Define to 1 if native compiler is available.])
- # Ensure libgccjit installed by MacPorts can be found.
- if test -n "$HAVE_MACPORTS"; then
- LIBGCCJIT_CFLAGS="$LIBGCCJIT_CFLAGS -I${MACPORTS_LIBGCCJIT_INCLUDE}"
- LIBGCCJIT_LIBS="-L${MACPORTS_LIBGCCJIT_LIB} $LIBGCCJIT_LIBS"
- fi
+ CFLAGS=$SAVE_CFLAGS
+ LIBS=$SAVE_LIBS
fi
AC_DEFINE_UNQUOTED(NATIVE_ELISP_SUFFIX, ".eln",
[System extension for native compiled elisp])
@@ -3893,7 +4173,8 @@ if test "${with_png}" != no; then
if test "$opsys" = mingw32; then
AC_CHECK_HEADER([png.h], [HAVE_PNG=yes])
elif test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \
- || test "${HAVE_NS}" = "yes"; then
+ || test "${HAVE_NS}" = "yes" || test "${HAVE_BE_APP}" = "yes" \
+ || test "$window_system" = "pgtk"; then
EMACS_CHECK_MODULES([PNG], [libpng >= 1.0.0])
if test $HAVE_PNG = yes; then
LIBPNG=$PNG_LIBS
@@ -3968,7 +4249,8 @@ if test "${opsys}" = "mingw32"; then
AC_DEFINE(HAVE_TIFF, 1, [Define to 1 if you have the tiff library (-ltiff).])
fi
elif test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \
- || test "${HAVE_NS}" = "yes"; then
+ || test "${HAVE_NS}" = "yes" || test "${HAVE_BE_APP}" = "yes" \
+ || test "$window_system" = "pgtk"; then
if test "${with_tiff}" != "no"; then
AC_CHECK_HEADER(tiffio.h,
[tifflibs="-lz -lm"
@@ -3997,7 +4279,8 @@ if test "${opsys}" = "mingw32"; then
AC_DEFINE(HAVE_GIF, 1, [Define to 1 if you have a gif (or ungif) library.])
fi
elif test "${HAVE_X11}" = "yes" && test "${with_gif}" != "no" \
- || test "${HAVE_W32}" = "yes" || test "${HAVE_NS}" = "yes"; then
+ || test "${HAVE_W32}" = "yes" || test "${HAVE_NS}" = "yes" \
+ || test "${HAVE_BE_APP}" = "yes" || test "$window_system" = "pgtk"; then
AC_CHECK_HEADER(gif_lib.h,
# EGifPutExtensionLast only exists from version libungif-4.1.0b1.
# Earlier versions can crash Emacs, but version 5.0 removes EGifPutExtensionLast.
@@ -4190,6 +4473,26 @@ fi
AC_SUBST(XFIXES_CFLAGS)
AC_SUBST(XFIXES_LIBS)
+## Use XInput 2.0 if available
+HAVE_XINPUT2=no
+if test "${HAVE_X11}" = "yes" && test "${with_xinput2}" != "no"; then
+ EMACS_CHECK_MODULES([XINPUT], [xi])
+ if test $HAVE_XINPUT = yes; then
+ # Now check for XInput2.h
+ AC_CHECK_HEADER(X11/extensions/XInput2.h,
+ [AC_CHECK_LIB(Xi, XIGrabButton, HAVE_XINPUT2=yes)])
+ fi
+ if test $HAVE_XINPUT2 = yes; then
+ AC_DEFINE(HAVE_XINPUT2, 1, [Define to 1 if the X Input Extension version 2.0 or later is present.])
+ if test "$USE_GTK_TOOLKIT" = "GTK2"; then
+ AC_MSG_WARN([You are building Emacs with GTK+ 2 and the X Input Extension version 2.
+This might lead to problems if your version of GTK+ is not built with support for XInput 2.])
+ fi
+ fi
+fi
+AC_SUBST(XINPUT_CFLAGS)
+AC_SUBST(XINPUT_LIBS)
+
### Use Xdbe (-lXdbe) if available
HAVE_XDBE=no
if test "${HAVE_X11}" = "yes"; then
@@ -4414,6 +4717,13 @@ case $with_unexec,$canonical in
[AC_MSG_ERROR([Non-ELF systems are not supported on this platform.])]);;
esac
+if test "$with_unexec" = yes && test "$opsys" = "haiku"; then
+ dnl A serious attempt was actually made to port unexec to Haiku.
+ dnl Something in libstdc++ seems to prevent it from working.
+ AC_MSG_ERROR([Haiku is not supported by the legacy unexec dumper.
+Please use the portable dumper instead.])
+fi
+
# Dump loading
AC_CHECK_FUNCS([posix_madvise])
@@ -4724,6 +5034,23 @@ dnl AC_CHECK_FUNCS_ONCE wouldn’t be right for snprintf, which needs
dnl the current CFLAGS etc.
AC_CHECK_FUNCS(snprintf)
+dnl posix_spawn. The chdir and setsid functionality is relatively
+dnl recent, so we check for it specifically.
+AC_CHECK_HEADERS([spawn.h])
+AC_SUBST([HAVE_SPAWN_H])
+AC_CHECK_FUNCS([posix_spawn \
+ posix_spawn_file_actions_addchdir \
+ posix_spawn_file_actions_addchdir_np \
+ posix_spawnattr_setflags])
+AC_SUBST([HAVE_POSIX_SPAWN])
+AC_SUBST([HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR])
+AC_SUBST([HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP])
+AC_SUBST([HAVE_POSIX_SPAWNATTR_SETFLAGS])
+AC_CHECK_DECLS([POSIX_SPAWN_SETSID], [], [], [[
+ #include <spawn.h>
+ ]])
+AC_SUBST([HAVE_DECL_POSIX_SPAWN_SETSID])
+
dnl Check for glib. This differs from other library checks in that
dnl Emacs need not link to glib unless some other library is already
dnl linking to glib. Although glib provides no facilities that Emacs
@@ -4750,7 +5077,7 @@ CFLAGS="$OLDCFLAGS"
LIBS="$OLDLIBS"])
if test "${emacs_cv_links_glib}" = "yes"; then
AC_DEFINE(HAVE_GLIB, 1, [Define to 1 if GLib is linked in.])
- if test "$HAVE_NS" = no;then
+ if test "$HAVE_NS" = no ; then
XGSELOBJ=xgselect.o
fi
fi
@@ -5005,7 +5332,7 @@ dnl It would have Emacs fork off a separate process
dnl to read the input and send it to the true Emacs process
dnl through a pipe.
case $opsys in
- darwin | gnu-linux | gnu-kfreebsd )
+ darwin | gnu-linux | gnu-kfreebsd)
AC_DEFINE(INTERRUPT_INPUT, 1, [Define to read input using SIGIO.])
;;
esac
@@ -5101,6 +5428,14 @@ case $opsys in
AC_DEFINE(PTY_OPEN, [fd = open (pty_name, O_RDWR | O_NONBLOCK)])
AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; int grantpt_result; sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); grantpt_result = grantpt (fd); pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (grantpt_result == -1) fatal("could not grant slave pty"); if (unlockpt(fd) == -1) fatal("could not unlock slave pty"); if (!(ptyname = ptsname(fd))) fatal ("could not enable slave pty"); snprintf (pty_name, PTY_NAME_SIZE, "%s", ptyname); }])
;;
+
+ haiku*)
+ AC_DEFINE(FIRST_PTY_LETTER, ['s'])
+ AC_DEFINE(PTY_NAME_SPRINTF, [])
+ dnl on Haiku pty names aren't distinctive, thus the use of posix_openpt
+ AC_DEFINE(PTY_OPEN, [fd = posix_openpt (O_RDWR | O_NONBLOCK)])
+ AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptyname; int grantpt_result; sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); grantpt_result = grantpt (fd); pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (grantpt_result == -1) fatal("could not grant slave pty"); if (unlockpt(fd) == -1) fatal("could not unlock slave pty"); if (!(ptyname = ptsname(fd))) fatal ("could not enable slave pty"); snprintf (pty_name, PTY_NAME_SIZE, "%s", ptyname); }])
+ ;;
esac
@@ -5185,6 +5520,7 @@ case $opsys in
#if defined __i386__ || defined __sparc__ || defined __mc68000__ \
|| defined __alpha__ || defined __mips__ || defined __s390__ \
|| defined __arm__ || defined __powerpc__ || defined __amd64__ \
+ || defined __x86_64__ \
|| defined __ia64__ || defined __sh__
/* ok */
#else
@@ -5322,8 +5658,25 @@ case $opsys in
AC_DEFINE(USG, [])
AC_DEFINE(USG5_4, [])
;;
+
+ haiku)
+ AC_DEFINE(HAIKU, [], [Define if the system is Haiku.])
+ ;;
esac
+AC_SYS_POSIX_TERMIOS
+if test $ac_cv_sys_posix_termios = yes; then
+ AC_CHECK_SIZEOF([speed_t], [], [#include <termios.h>])
+ dnl on Haiku, and possibly other platforms, speed_t is defined to
+ dnl unsigned char, even when speeds greater than 200 baud are
+ dnl defined.
+
+ if test ${ac_cv_sizeof_speed_t} -lt 2; then
+ AC_DEFINE([HAVE_TINY_SPEED_T], [1],
+ [Define to 1 if speed_t has some sort of nonsensically tiny size.])
+ fi
+fi
+
AC_CACHE_CHECK([for usable FIONREAD], [emacs_cv_usable_FIONREAD],
[case $opsys in
aix4-2 | nacl)
@@ -5366,6 +5719,22 @@ if test $emacs_cv_usable_FIONREAD = yes; then
AC_DEFINE([USABLE_SIGIO], [1], [Define to 1 if SIGIO is usable.])
fi
fi
+
+ if test $emacs_broken_SIGIO = no && test $emacs_cv_usable_SIGIO = no; then
+ AC_CACHE_CHECK([for usable SIGPOLL], [emacs_cv_usable_SIGPOLL],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[#include <fcntl.h>
+ #include <signal.h>
+ ]],
+ [[int foo = SIGPOLL | F_SETFL;]])],
+ [emacs_cv_usable_SIGPOLL=yes],
+ [emacs_cv_usable_SIGPOLL=no])],
+ [emacs_cv_usable_SIGPOLL=yes],
+ [emacs_cv_usable_SIGPOLL=no])
+ if test $emacs_cv_usable_SIGPOLL = yes; then
+ AC_DEFINE([USABLE_SIGPOLL], [1], [Define to 1 if SIGPOLL is usable but SIGIO is not.])
+ fi
+ fi
fi
case $opsys in
@@ -5416,6 +5785,7 @@ AC_SUBST(prefix)
AC_SUBST(exec_prefix)
AC_SUBST(bindir)
AC_SUBST(datadir)
+AC_SUBST(gsettingsschemadir)
AC_SUBST(sharedstatedir)
AC_SUBST(libexecdir)
AC_SUBST(mandir)
@@ -5478,6 +5848,17 @@ if test "${HAVE_X_WINDOWS}" = "yes" ; then
FONT_OBJ="$FONT_OBJ ftfont.o"
fi
fi
+
+if test "${window_system}" = "pgtk"; then
+ FONT_OBJ="ftfont.o ftcrfont.o"
+fi
+
+if test "${HAVE_BE_APP}" = "yes" ; then
+ if test "${HAVE_CAIRO}" = "yes"; then
+ FONT_OBJ="$FONT_OBJ ftfont.o ftcrfont.o"
+ fi
+fi
+
if test "${HAVE_HARFBUZZ}" = "yes" ; then
FONT_OBJ="$FONT_OBJ hbfont.o"
fi
@@ -5660,11 +6041,12 @@ CFLAGS=$pre_PKG_CONFIG_CFLAGS
LIBS="$LIB_PTHREAD $pre_PKG_CONFIG_LIBS"
gl_ASSERT_NO_GNULIB_POSIXCHECK
gl_ASSERT_NO_GNULIB_TESTS
+gl_EEMALLOC
gl_INIT
CFLAGS=$SAVE_CFLAGS
LIBS=$SAVE_LIBS
-# timer_getoverrun needs the same libarary as timer_settime
+# timer_getoverrun needs the same library as timer_settime
OLD_LIBS=$LIBS
LIBS="$LIB_TIMER_TIME $LIBS"
AC_CHECK_FUNCS(timer_getoverrun)
@@ -5865,11 +6247,11 @@ Configured for '${canonical}'.
#### Please respect alphabetical ordering when making additions.
optsep=
emacs_config_features=
-for opt in ACL CAIRO DBUS FREETYPE GCONF GIF GLIB GMP GNUTLS GPM GSETTINGS \
+for opt in ACL BE_APP CAIRO DBUS FREETYPE GCONF GIF GLIB GMP GNUTLS GPM GSETTINGS \
HARFBUZZ IMAGEMAGICK JPEG JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 \
- M17N_FLT MODULES NATIVE_COMP NOTIFY NS OLDXMENU PDUMPER PNG RSVG SECCOMP \
- SOUND THREADS TIFF \
- TOOLKIT_SCROLL_BARS UNEXEC X11 XAW3D XDBE XFT XIM XPM XWIDGETS X_TOOLKIT \
+ M17N_FLT MODULES NATIVE_COMP NOTIFY NS OLDXMENU PDUMPER PGTK PNG RSVG SECCOMP \
+ SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS \
+ UNEXEC WEBP X11 XAW3D XDBE XFT XIM XINPUT2 XPM XWIDGETS X_TOOLKIT \
ZLIB; do
case $opt in
@@ -5914,6 +6296,8 @@ AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D
Does Emacs use a gif library? ${HAVE_GIF} $LIBGIF
Does Emacs use a png library? ${HAVE_PNG} $LIBPNG
Does Emacs use -lrsvg-2? ${HAVE_RSVG}
+ Does Emacs use -lwebp? ${HAVE_WEBP}
+ Does Emacs use -lsqlite3? ${HAVE_SQLITE3}
Does Emacs use cairo? ${HAVE_CAIRO}
Does Emacs use -llcms2? ${HAVE_LCMS2}
Does Emacs use imagemagick? ${HAVE_IMAGEMAGICK}
@@ -5945,6 +6329,7 @@ AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D
Does Emacs support legacy unexec dumping? ${with_unexec}
Which dumping strategy does Emacs use? ${with_dumping}
Does Emacs have native lisp compiler? ${HAVE_NATIVE_COMP}
+ Does Emacs use version 2 of the the X Input Extension? ${HAVE_XINPUT2}
"])
if test -n "${EMACSDATA}"; then
@@ -6021,6 +6406,13 @@ if test -f "$srcdir/$opt_makefile.in"; then
dnl ", [], [opt_makefile='$opt_makefile']" and it should work.
AC_CONFIG_FILES([test/Makefile])
fi
+opt_makefile=test/infra/Makefile
+if test -f "$srcdir/$opt_makefile.in"; then
+ SUBDIR_MAKEFILES="$SUBDIR_MAKEFILES $opt_makefile"
+ dnl Again, it's best not to use a variable. Though you can add
+ dnl ", [], [opt_makefile='$opt_makefile']" and it should work.
+ AC_CONFIG_FILES([test/infra/Makefile])
+fi
dnl The admin/ directory used to be excluded from tarfiles.
diff --git a/doc/emacs/Makefile.in b/doc/emacs/Makefile.in
index 69d39efa8b9..dde3ae83c16 100644
--- a/doc/emacs/Makefile.in
+++ b/doc/emacs/Makefile.in
@@ -140,6 +140,7 @@ EMACSSOURCES= \
${srcdir}/xresources.texi \
${srcdir}/anti.texi \
${srcdir}/macos.texi \
+ $(srcdir)/haiku.texi \
${srcdir}/msdos.texi \
${srcdir}/gnu.texi \
${srcdir}/glossary.texi \
diff --git a/doc/emacs/abbrevs.texi b/doc/emacs/abbrevs.texi
index c83da8aaec6..972416ff1cd 100644
--- a/doc/emacs/abbrevs.texi
+++ b/doc/emacs/abbrevs.texi
@@ -274,7 +274,7 @@ Edit a list of abbrevs; you can add, alter or remove definitions.
@example
@var{various other tables@dots{}}
(lisp-mode-abbrev-table)
-"dk" 0 "define-key"
+"ks" 0 "keymap-set"
(global-abbrev-table)
"dfn" 0 "definition"
@end example
diff --git a/doc/emacs/anti.texi b/doc/emacs/anti.texi
index 49da473fa51..3b02187b5cb 100644
--- a/doc/emacs/anti.texi
+++ b/doc/emacs/anti.texi
@@ -4,156 +4,138 @@
@c See file emacs.texi for copying conditions.
@node Antinews
-@appendix Emacs 26 Antinews
+@appendix Emacs 27 Antinews
@c Update the emacs.texi Antinews menu entry with the above version number.
For those users who live backwards in time, here is information
-about downgrading to Emacs version 26.3. We hope you will enjoy the
+about downgrading to Emacs version 27.2. We hope you will enjoy the
greater simplicity that results from the absence of many @w{Emacs
@value{EMACSVER}} features.
@itemize @bullet
@item
-Emacs no longer uses @acronym{GMP}, the GNU Multiple Precision
-library, and doesn't support Lisp integers greater than
-@code{most-positive-fixnum} or smaller than
-@code{most-negative-fixnum}. We now have only one kind of a Lisp
-integer. This simplifies many Lisp programs that use integers, and
-makes integer calculations always fast. If you want larger values,
-use Lisp floats, as Emacs has done since day one.
+Emacs can no longer be built with support of native compilation of
+Lisp programs. This means Emacs builds much faster, and the problems
+that came with native compilation: the need to have GCC and Binutils
+installed, the complications of managing your @file{eln-cache}
+directories---all of that is now future history. The simplicity and
+elegance of the Emacs byte-compiled code is now restored in all of its
+pristine beauty.
@item
-Emacs no longer supports HarfBuzz as the engine for shaping complex
-text. As you move back in time, we will gradually shed off all traces
-of support for complex text shaping, and this is one step in that
-direction.
+Emacs no longer builds by default with Cairo, even if it's present.
+The warnings about not using HarfBuzz are also gone, in preparation
+for complete removal of HarfBuzz support in previous Emacs versions.
+Fancy text shaping and display is becoming less important as you move
+back in time. The @code{ftx} font backend is again part of Emacs, for
+the same reasons.
@item
-We have removed support for building with the Jansson library, and
-consequently the native support for JSON parsing is gone. The
-importance of JSON decreases as we go back in time, so for now using
-the Lisp code for handling it should be good enough; in one of the
-past Emacs versions, we intend to remove even that, as useless bloat.
-
-The library for supporting JSONRPC applications was removed for the
-same reason.
+As Motif becomes more and more important with moving farther into the
+past, we've reinstated the code which supports Motif in Emacs.
@item
-The ``portable dumper'' feature is gone. We are once again using the
-field-proven ``unexec'' way of dumping Emacs. With that, the hope for
-being able to re-dump your customized Emacs session is also gone: why
-would anyone want to record their random customization experiments on
-disk, and restore them the next time they start Emacs? And true
-Emacsers don't restart their Emacs sessions anyway.
+Emacs once again supports versions 5.3 and older OpenBSD systems,
+which will be needed as you move back in time.
@item
-We dropped the support for @acronym{XDG}-style configuration
-directories and the @env{XDG_CONFIG_HOME} environment variable.
-There's once again only one place where Emacs looks for its init
-files: the @file{~/.emacs.d} directory, with the @file{~/.emacs} file
-as fallback. We think this will go a long way towards preventing
-confusion among users who for some reason have @env{XDG_CONFIG_HOME}
-set, thus risking to have their init files randomly spread between two
-places. In one of the past Emacs versions, we intend to further
-simplify this, removing the @file{~/.emacs.d} place and leaving only
-@file{~/.emacs}; stay tuned.
-
-For similar reasons, we've removed the ``early init'' file. You can
-now again use all the tricks you want to initialize variables like
-@code{package-user-dir} and @code{package-load-list} just in time for
-the packages to load.
+We've dropped support for Secure Computing filter on GNU/Linux. The
+past world is much more secure than the present, so the complexities
+related with this stuff, which can only be explained by severe
+paranoia, are no longer justified.
-@command{emacsclient} no longer supports @acronym{XDG}-style directory
-trees, either.
+@item
+Emacs reverted back to supporting Unicode 13.x, since the following
+versions of the standards are not yet published where you are going.
+The @samp{emoji} script and the support for displaying Emoji sequences
+were removed for the same reasons: no one will produce them in the
+past.
@item
-TLS connections are back to their lenient security settings. We
-decided that too tight security settings are an annoyance for users,
-and make little sense considering the world-wide tendency to have
-fewer and fewer network security problems as we move back in time
-(those issues will be completely gone when networks disappear in some
-distant past).
+Mode-specific commands and the @kbd{M-S-x} command that invokes them
+were removed. As you move back in time, the command set in Emacs
+becomes smaller, so any such filtering of applicable commands just
+gets in the way.
@item
-The @code{server-after-make-frame-hook} hook was deleted, in
-preparation for removing the entire daemon business in some past Emacs
-version. You will be glad to learn that setting up the GUI
-customizations of your sessions is now once again as easy as it ever
-was, with just the @code{after-make-frame-functions} to use.
+We have removed the system for displaying documentation of groups of
+related functions, the @kbd{shortdoc-display-group} command to go with
+it, and the corresponding ``See also'' button in the @file{*Help*}
+buffer. That should make searching for certain functions simpler:
+just use the venerable @samp{apropos} commands.
@item
-The @code{flex} completion style was removed. We feel that it
-unnecessarily complicates the Emacs user experience, and therefore
-will continue to remove other tricky completion styles, until in some
-past Emacs version we get to a single original style Emacs pioneered
-decades ago. Long live simplicity; down with complications!
+The @code{context-menu-mode} was removed, and with it the context
+menus popped by pressing the right mouse button. This is one small
+step towards freeing Emacs (and eventually, the whole world of
+computing) from the tyranny of the GUI pointing devices in general,
+and moving back to the simplicity of text-mode user interfaces.
+Down with mice and other rodents!
@item
-The optional display of the fill-column indicator is no longer
-supported. With the display sizes becoming smaller and smaller as you
-move back in time, we feel that the display itself will always show
-you where to fill or wrap your text, and do this much more easily and
-reliably than any such display indicator.
+The commands @kbd{C-x 4 4} and @kbd{C-x 5 5} for displaying the
+results in a new window/frame re gone. We are quite certain that
+creating a new window/frame before running a command is much simpler,
+and doesn't require a complication of a new prefix.
@item
-We removed the features that made visiting large files easier. Thus,
-Emacs will no longer suggest visiting a large file literally, nor
-offer the @code{so-long} mode to deal with overly-long lines. We
-decided that this simplification is worthwhile, given that the general
-tendency of having very large files is becoming a rarity as we move
-back in time.
+The behavior of active minibuffers when switching frames is now the
+perfect mess it should be: sometimes the minibuffer moves to the new
+selected frame, sometimes it doesn't, and sometimes you get an error.
+This makes Emacs usage much more fun, as you get to guess the result,
+instead of having it boringly consistent.
@item
-We have removed the feature that displayed echo-area messages without
-hiding content of the active minibuffer. This should prevent user
-confusion from having two unrelated pieces of text staring at them,
-with no clear separation between them. Users with good memories (and
-Emacs users are all expected to be of that kind) will have no trouble
-keeping the minibuffer text in their minds, and typing the responses
-without actually seeing the prompts.
+Compact mode-line display mode has been removed. The items displayed
+on the mode line are now always in the same place, and if there's not
+enough space for them, they are not displayed at all, instead of being
+confusingly displayed in a different position. You no longer need to
+think twice where to find a particular mode-line element on display.
@item
-Horizontal scrolling using the mouse or touchpad has been removed. In
-the past, wide monitors will become less popular, so horizontal
-scrolling will no longer be needed. Removal of the mouse support for
-horizontal scrolling is the first step towards its complete removal in
-prior Emacs versions.
+Many commands and options related to tab bars were removed, including
+(but not limited to) frame-specific appearance of tab bars, the
+@code{tab-bar-format} option, the @kbd{C-x t n}, @kbd{C-x t N},
+@kbd{C-x t M}, and @kbd{C-x t G} commands, and many mouse gestures on
+the tab bar. We are going to delete the tab bar support from Emacs in
+one of the past versions, and this is a step in that direction.
@item
-The @code{main-thread} variable and @code{list-threads} were removed,
-and @code{thread-join} no longer returns the result of the finished
-thread. We intend to remove the support for Lisp threads in some past
-Emacs version, so we continue removing the associated complexities and
-features as we go back in time.
+The ``transient'' input methods have been removed; use @kbd{C-\} to
+turn input methods on and off instead. This is in preparation for
+complete removal of input methods from Emacs in version 19, and
+consistent with the fact that the number of input methods we support
+becomes smaller as you move back in time.
@item
-Tab bar and window tab-lines were removed. This should make the Emacs
-display simpler and less cluttered, and help those users who disable
-menu bar and tool bar in their GUI sessions. The fashion to provide
-tabs in every GUI application out there is gaining less and less
-popularity as we move back in time, and will completely disappear at
-some past point; removing the tabs from Emacs is the step in that
-direction.
+We disabled @code{show-paren-mode} by default, since we think the
+venerable @code{blink-matching-paren} feature is more than enough, and
+better fits the simplicity of past Emacs versions. It will definitely
+be better when colors are removed from Emacs in the distant past.
+
+For the same reason, sub-groups in interactive regexp searches are no
+longer highlighted in distinct colors.
@item
-Displaying line numbers for a buffer is only possibly using add-on
-features, such as @code{linum-mode}, which can only display the
-numbers in the display margins. Line-number display using these
-features is also slow, as we firmly believe such a feature is
-un-Emacsy and should not have been included in Emacs to begin with.
-Consequently, @code{display-line-numbers-mode} was removed.
+On our permanent quest for simplifying Emacs, we've removed the Ispell
+command @code{ispell-comment-or-string-at-point}; the old-time friend
+@code{ispell-comments-and-strings} should suffice.
@item
-On our permanent quest for simplifying Emacs, we've removed the
-support for changing the font size by turning the mouse wheel.
+Many Gnus commands and options were deemed to unnecessarily complicate
+the use of Gnus (which is too complex to begin with), and thus were
+removed. This includes @code{gnus-topic-display-predicate},
+@code{gnus-process-mark-toggle}, @code{gnus-registry-register-all},
+@code{gnus-paging-select-next}, and many others. The @code{nnselect}
+backend was deleted for the same reason.
@item
-Several commands, deemed to be unnecessary complications, have been
-removed. Examples include @code{make-empty-file},
-@code{font-lock-refontify}, @code{xref-find-definitions-at-mouse},
-@code{make-frame-on-monitor}, and @code{diff-buffers}.
+The @file{project.el} package have been redesigned to remove many
+unnecessary features, so that just the bare essentials remain. We
+plan on removing this package from Emacs in a previous version, but
+decided to begin with removing some extra features first.
@item
To keep up with decreasing computer memory capacity and disk space, many
-other functions and files have been eliminated in Emacs 26.3.
+other functions and files have been eliminated in Emacs 27.2.
@end itemize
diff --git a/doc/emacs/basic.texi b/doc/emacs/basic.texi
index ba8d822b18e..c4fa0d64ed7 100644
--- a/doc/emacs/basic.texi
+++ b/doc/emacs/basic.texi
@@ -887,15 +887,19 @@ z z z}. The first @kbd{C-x z} repeats the command once, and each
subsequent @kbd{z} repeats it once again.
@findex repeat-mode
- Also you can activate @code{repeat-mode} that temporarily enables
-a transient mode with short keys after a limited number of commands.
+@vindex repeat-exit-key
+@vindex repeat-exit-timeout
+ Also you can activate @code{repeat-mode} that temporarily enables a
+transient mode with short keys after a limited number of commands.
Currently supported shorter key sequences are @kbd{C-x u u} instead of
@kbd{C-x u C-x u} to undo many changes, @kbd{C-x o o} instead of
@kbd{C-x o C-x o} to switch several windows, @kbd{C-x @{ @{ @} @} ^ ^
v v} to resize the selected window interactively, @kbd{M-g n n p p} to
-navigate @code{next-error} matches. Any other key exits transient mode
-and then is executed normally. The user option @code{repeat-exit-key}
-defines an additional key to exit this transient mode. Also it's
-possible to break the repetition chain automatically after idle time
-by customizing the user option @code{repeat-exit-timeout} to a number
-of seconds.
+navigate @code{next-error} matches, and @kbd{C-x ] ] [ [} to navigate
+through pages. Any other key exits transient mode and then is
+executed normally. The user option @code{repeat-exit-key} defines an
+additional key to exit this transient mode. Also it's possible to
+break the repetition chain automatically after some idle time by
+customizing the user option @code{repeat-exit-timeout} to specify the
+idle time in seconds after which this transient mode will be turned
+off.
diff --git a/doc/emacs/building.texi b/doc/emacs/building.texi
index 8de93867baa..f9ea1b390f7 100644
--- a/doc/emacs/building.texi
+++ b/doc/emacs/building.texi
@@ -213,7 +213,6 @@ Select a buffer to be used by next invocation of @code{next-error} and
@kindex M-g n
@kindex C-x `
@findex next-error
-@findex next-error-message
@vindex next-error-message-highlight
@vindex next-error-highlight
@vindex next-error-highlight-no-select
@@ -263,7 +262,9 @@ to skip any messages.
highlights the relevant source line. The duration of this highlight
is determined by the variable @code{next-error-highlight} for the locus
in the selected buffer, and @code{next-error-highlight-no-select} for
-the locus in non-selected buffers.
+the locus in non-selected buffers. Also you can customize the variable
+@code{next-error-message-highlight} that defines how to highlight the
+current error message in the buffer that contains messages.
@vindex compilation-context-lines
If the @file{*compilation*} buffer is shown in a window with a left
@@ -1491,7 +1492,7 @@ Emacs Lisp Reference Manual}.
code not unlike the one produced by a C or Fortran compiler. Native
code runs even faster than byte-code. Natively-compiled Emacs Lisp
code is stored in files whose names end in @samp{.eln}. @xref{Native
-Compilation,, Byte Compilation, elisp, the Emacs Lisp Reference Manual}.
+Compilation,, Native Compilation, elisp, the Emacs Lisp Reference Manual}.
@findex load-file
To @dfn{load} an Emacs Lisp file, type @kbd{M-x load-file}. This
diff --git a/doc/emacs/calendar.texi b/doc/emacs/calendar.texi
index 3750e78e709..18de721e288 100644
--- a/doc/emacs/calendar.texi
+++ b/doc/emacs/calendar.texi
@@ -1363,6 +1363,20 @@ the 11 above to @samp{'(1 2 3)} and have the entry apply to the last
Thursday of January, February, and March. If the month is @code{t}, the
entry applies to all months of the year.
+@findex diary-offset
+@example
+%%(diary-offset '(diary-float t 3 4) 2) Monthly committee meeting
+@end example
+
+@noindent
+This entry applies to the Saturday after the third Thursday of each
+month. The 2 specifies number of days after when the sexp
+@w{@code{'(diary-float t 3 4)}} would evaluate to @code{t}. This is
+useful when for example your organization has a committee meeting two
+days after every monthly meeting which takes place on the third
+Thursday, or if you would like to attend a virtual meeting scheduled
+in a different timezone causing a difference in the date.
+
Each of the standard sexp diary entries takes an optional parameter
specifying the name of a face or a single-character string to use when
marking the entry in the calendar. Most generally, sexp diary entries
diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi
index b7f0bda7851..b1e471f6d63 100644
--- a/doc/emacs/cmdargs.texi
+++ b/doc/emacs/cmdargs.texi
@@ -185,6 +185,11 @@ successfully.
@item --version
@opindex --version
Print Emacs version, then exit successfully.
+
+@item --fingerprint
+@opindex --fingerprint
+Print the Emacs ``fingerprint'', which is used to uniquely identify
+the compiled version of Emacs.
@end table
@node Initial Options
@@ -266,6 +271,11 @@ disables auto-saving except in buffers for which auto-saving is
explicitly requested, and when saving files it omits the @code{fsync}
system call unless otherwise requested.
+@vindex backtrace-on-error-noninteractive
+Errors that occur when running a @samp{--batch} Emacs will result in
+an Emacs Lisp backtrace being printed. To disable this behavior, set
+@code{backtrace-on-error-noninteractive} to @code{nil}.
+
@item --script @var{file}
@opindex --script
@cindex script mode
@@ -746,6 +756,10 @@ On MS-Windows, if you set this variable, Emacs will load and initialize
the network library at startup, instead of waiting until the first
time it is required.
+@item WAYLAND_DISPLAY
+Pgtk Emacs (built with @option{--with-pgtk}) can run on Wayland natively.
+@env{WAYLAND_DISPLAY} specifies the connection to the compositor.
+
@item emacs_dir
On MS-Windows, @env{emacs_dir} is a special environment variable, which
indicates the full path of the directory in which Emacs is installed.
diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index 999234e6d33..c4c43f2713a 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -195,7 +195,7 @@ the customization buffer:
The first line shows that the variable is named
@code{kill-ring-max}, formatted as @samp{Kill Ring Max} for easier
-viewing. Its value is @samp{60}. The button labeled @samp{[Hide]},
+viewing. Its value is @samp{120}. The button labeled @samp{[Hide]},
if activated, hides the variable's value and state; this is useful to
avoid cluttering up the customization buffer with very long values
(for this reason, variables that have very long values may start out
@@ -1084,8 +1084,9 @@ first line:
@noindent
You can specify any number of variable/value pairs in this way, each
pair with a colon and semicolon. The special variable/value pair
-@code{mode: @var{modename};}, if present, specifies a major mode. The
-@var{value}s are used literally, and not evaluated.
+@code{mode: @var{modename};}, if present, specifies a major mode
+(without the ``-mode'' suffix). The @var{value}s are used literally,
+and not evaluated.
@findex add-file-local-variable-prop-line
@findex delete-file-local-variable-prop-line
@@ -1473,9 +1474,10 @@ as Dired buffers (@pxref{Dired}).
Most of the variables reflect the situation on the local machine.
Often, they must use a different value when you operate in buffers
-with a remote default directory. Think about the shell to be applied
-when calling @code{shell} -- it might be @file{/bin/bash} on your
-local machine, and @file{/bin/ksh} on a remote machine.
+with a remote default directory. Think about the behavior when
+calling @code{shell} -- on your local machine, you might use
+@file{/bin/bash} and rely on termcap, but on a remote machine, it may
+be @file{/bin/ksh} and terminfo.
This can be accomplished with @dfn{connection-local variables}.
Directory and file local variables override connection-local
@@ -1491,6 +1493,10 @@ variables/value pairs in a @dfn{profile}, using the
criteria, identifying a remote machine:
@example
+(connection-local-set-profile-variables 'remote-terminfo
+ '((system-uses-terminfo . t)
+ (comint-terminfo-terminal . "dumb-emacs-ansi")))
+
(connection-local-set-profile-variables 'remote-ksh
'((shell-file-name . "/bin/ksh")
(shell-command-switch . "-c")))
@@ -1500,13 +1506,15 @@ criteria, identifying a remote machine:
(shell-command-switch . "-c")))
(connection-local-set-profiles
- '(:application tramp :machine "remotemachine") 'remote-ksh)
+ '(:application tramp :machine "remotemachine")
+ 'remote-terminfo 'remote-ksh)
@end example
- This code declares two different profiles, @code{remote-ksh} and
-@code{remote-bash}. The profile @code{remote-ksh} is applied to all
+ This code declares three different profiles, @code{remote-terminfo},
+@code{remote-ksh}, and @code{remote-bash}. The profiles
+@code{remote-terminfo} and @code{remote-ksh} are applied to all
buffers which have a remote default directory matching the regexp
-@code{"remotemachine} as host name. Such a criteria can also
+@code{"remotemachine"} as host name. Such a criteria can also
discriminate for the properties @code{:protocol} (this is the Tramp
method) or @code{:user} (a remote user name). The @code{nil} criteria
matches all buffers with a remote default directory.
@@ -1576,7 +1584,7 @@ which overrides the global definitions of some keys.
self-inserting because the global keymap binds it to the command
@code{self-insert-command}. The standard Emacs editing characters
such as @kbd{C-a} also get their standard meanings from the global
-keymap. Commands to rebind keys, such as @kbd{M-x global-set-key},
+keymap. Commands to rebind keys, such as @kbd{M-x keymap-global-set},
work by storing the new binding in the proper place in the global map
(@pxref{Rebinding}). To view the current key bindings, use the
@kbd{C-h b} command.
@@ -1699,7 +1707,6 @@ circumstances.
@vindex minibuffer-local-completion-map
@vindex minibuffer-local-must-match-map
@vindex minibuffer-local-filename-completion-map
-@vindex minibuffer-local-filename-must-match-map
The minibuffer has its own set of local keymaps; they contain various
completion and exit commands.
@@ -1715,12 +1722,22 @@ just like @key{RET}.
@code{minibuffer-local-must-match-map} is for strict completion and
for cautious completion.
@item
-@code{minibuffer-local-filename-completion-map} and
-@code{minibuffer-local-filename-must-match-map} are like the two
-previous ones, but they are specifically for file name completion.
-They do not bind @key{SPC}.
+@code{minibuffer-local-filename-completion-map} is like the two
+previous ones, but specifically for file name completion.
+It does not bind @key{SPC}.
@end itemize
+By default, @key{TAB}, @key{SPC} and @key{?} do completion in
+@code{minibuffer-local-completion-map}. If you commonly complete over
+collections that have elements with space or question mark characters in
+them, it may be convenient to disable completion on those keys by
+putting this in your init file:
+
+@lisp
+(keymap-set minibuffer-local-completion-map "SPC" 'self-insert-command)
+(keymap-set minibuffer-local-completion-map "?" 'self-insert-command)
+@end lisp
+
@node Rebinding
@subsection Changing Key Bindings Interactively
@cindex key rebinding, this session
@@ -1737,19 +1754,19 @@ local keymap, which affects all buffers using the same major mode.
Emacs session. @xref{Init Rebinding}, for a description of how to
make key rebindings affect future Emacs sessions.
-@findex global-set-key
-@findex local-set-key
-@findex global-unset-key
-@findex local-unset-key
+@findex keymap-global-set
+@findex keymap-local-set
+@findex keymap-global-unset
+@findex keymap-local-unset
@table @kbd
-@item M-x global-set-key @key{RET} @var{key} @var{cmd} @key{RET}
+@item M-x keymap-global-set @key{RET} @var{key} @var{cmd} @key{RET}
Define @var{key} globally to run @var{cmd}.
-@item M-x local-set-key @key{RET} @var{key} @var{cmd} @key{RET}
+@item M-x keymap-local-set @key{RET} @var{key} @var{cmd} @key{RET}
Define @var{key} locally (in the major mode now in effect) to run
@var{cmd}.
-@item M-x global-unset-key @key{RET} @var{key}
+@item M-x keymap-global-unset @key{RET} @var{key}
Make @var{key} undefined in the global map.
-@item M-x local-unset-key @key{RET} @var{key}
+@item M-x keymap-local-unset @key{RET} @var{key}
Make @var{key} undefined locally (in the major mode now in effect).
@end table
@@ -1758,11 +1775,11 @@ command (@pxref{Interactive Shell}), replacing the normal global
definition of @kbd{C-z}:
@example
-M-x global-set-key @key{RET} C-z shell @key{RET}
+M-x keymap-global-set @key{RET} C-z shell @key{RET}
@end example
@noindent
-The @code{global-set-key} command reads the command name after the
+The @code{keymap-global-set} command reads the command name after the
key. After you press the key, a message like this appears so that you
can confirm that you are binding the key you want:
@@ -1783,7 +1800,7 @@ reads another character; if that is @kbd{4}, another prefix character,
it reads one more character, and so on. For example,
@example
-M-x global-set-key @key{RET} C-x 4 $ spell-other-window @key{RET}
+M-x keymap-global-set @key{RET} C-x 4 $ spell-other-window @key{RET}
@end example
@noindent
@@ -1791,8 +1808,8 @@ redefines @kbd{C-x 4 $} to run the (fictitious) command
@code{spell-other-window}.
You can remove the global definition of a key with
-@code{global-unset-key}. This makes the key @dfn{undefined}; if you
-type it, Emacs will just beep. Similarly, @code{local-unset-key} makes
+@code{keymap-global-unset}. This makes the key @dfn{undefined}; if you
+type it, Emacs will just beep. Similarly, @code{keymap-local-unset} makes
a key undefined in the current major mode keymap, which makes the global
definition (or lack of one) come back into effect in that major mode.
@@ -1825,11 +1842,11 @@ you can specify them in your initialization file by writing Lisp code.
simplest is to use the @code{kbd} function, which converts a textual
representation of a key sequence---similar to how we have written key
sequences in this manual---into a form that can be passed as an
-argument to @code{global-set-key}. For example, here's how to bind
+argument to @code{keymap-global-set}. For example, here's how to bind
@kbd{C-z} to the @code{shell} command (@pxref{Interactive Shell}):
@example
-(global-set-key (kbd "C-z") 'shell)
+(keymap-global-set "C-z" 'shell)
@end example
@noindent
@@ -1842,69 +1859,24 @@ causes an error; it certainly isn't what you want.
and mouse events:
@example
-(global-set-key (kbd "C-c y") 'clipboard-yank)
-(global-set-key (kbd "C-M-q") 'query-replace)
-(global-set-key (kbd "<f5>") 'flyspell-mode)
-(global-set-key (kbd "C-<f5>") 'display-line-numbers-mode)
-(global-set-key (kbd "C-<right>") 'forward-sentence)
-(global-set-key (kbd "<mouse-2>") 'mouse-save-then-kill)
-@end example
-
- Instead of using @code{kbd}, you can use a Lisp string or vector to
-specify the key sequence. Using a string is simpler, but only works
-for @acronym{ASCII} characters and Meta-modified @acronym{ASCII}
-characters. For example, here's how to bind @kbd{C-x M-l} to
-@code{make-symbolic-link} (@pxref{Copying and Naming}):
-
-@example
-(global-set-key "\C-x\M-l" 'make-symbolic-link)
-@end example
-
- To bind a key sequence including @key{TAB}, @key{RET}, @key{ESC}, or
-@key{DEL}, the string should contain the Emacs Lisp escape sequence
-@samp{\t}, @samp{\r}, @samp{\e}, or @samp{\d} respectively. Here is
-an example which binds @kbd{C-x @key{TAB}} to @code{indent-rigidly}
-(@pxref{Indentation}):
-
-@example
-(global-set-key "\C-x\t" 'indent-rigidly)
-@end example
-
- When the key sequence includes function keys or mouse button events,
-or non-@acronym{ASCII} characters such as @code{C-=} or @code{H-a},
-you can use a vector to specify the key sequence. Each element in the
-vector stands for an input event; the elements are separated by spaces
-and surrounded by a pair of square brackets. If a vector element is a
-character, write it as a Lisp character constant: @samp{?} followed by
-the character as it would appear in a string. Function keys are
-represented by symbols (@pxref{Function Keys}); simply write the
-symbol's name, with no other delimiters or punctuation. Here are some
-examples:
-
-@example
-(global-set-key [?\C-=] 'make-symbolic-link)
-(global-set-key [?\M-\C-=] 'make-symbolic-link)
-(global-set-key [?\H-a] 'make-symbolic-link)
-(global-set-key [f7] 'make-symbolic-link)
-(global-set-key [C-mouse-1] 'make-symbolic-link)
-@end example
-
-@noindent
-You can use a vector for the simple cases too:
-
-@example
-(global-set-key [?\C-z ?\M-l] 'make-symbolic-link)
+(keymap-global-set "C-c y" 'clipboard-yank)
+(keymap-global-set "C-M-q" 'query-replace)
+(keymap-global-set "<f5>" 'flyspell-mode)
+(keymap-global-set "C-<f5>" 'display-line-numbers-mode)
+(keymap-global-set "C-<right>" 'forward-sentence)
+(keymap-global-set "<mouse-2>" 'mouse-save-then-kill)
@end example
Language and coding systems may cause problems with key bindings for
non-@acronym{ASCII} characters. @xref{Init Non-ASCII}.
-@findex define-key
+@findex keymap-set
+@findex keymap-unset
As described in @ref{Local Keymaps}, major modes and minor modes can
define local keymaps. These keymaps are constructed when the mode is
-loaded for the first time in a session. The function @code{define-key}
-can be used to make changes in a specific keymap. This function can
-also unset keys, when passed @code{nil} as the binding.
+loaded for the first time in a session. The function @code{keymap-set}
+can be used to make changes in a specific keymap. To remove a key
+binding, use @code{keymap-unset}.
Since a mode's keymaps are not constructed until it has been loaded,
you must delay running code which modifies them, e.g., by putting it
@@ -1916,11 +1888,11 @@ the one for @kbd{C-c C-x x} in Texinfo mode:
@example
(add-hook 'texinfo-mode-hook
(lambda ()
- (define-key texinfo-mode-map "\C-cp"
+ (keymap-set texinfo-mode-map "C-c p"
'backward-paragraph)
- (define-key texinfo-mode-map "\C-cn"
+ (keymap-set texinfo-mode-map "C-c n"
'forward-paragraph)))
- (define-key texinfo-mode-map "\C-c\C-xx" nil)
+ (keymap-set texinfo-mode-map "C-c C-x x" nil)
@end example
@node Modifier Keys
@@ -1942,7 +1914,7 @@ between those keystrokes. However, you can bind shifted @key{Control}
alphabetical keystrokes in GUI frames:
@lisp
-(global-set-key (kbd "C-S-n") #'previous-line)
+(keymap-global-set "C-S-n" #'previous-line)
@end lisp
For all other modifiers, you can make the modified alphabetical
@@ -2096,7 +2068,7 @@ button, @code{mouse-2} for the next, and so on. Here is how you can
redefine the second mouse button to split the current window:
@example
-(global-set-key [mouse-2] 'split-window-below)
+(keymap-global-set "<mouse-2>" 'split-window-below)
@end example
The symbols for drag events are similar, but have the prefix
@@ -2179,7 +2151,7 @@ Thus, here is how to define the command for clicking the first button in
a mode line to run @code{scroll-up-command}:
@example
-(global-set-key [mode-line mouse-1] 'scroll-up-command)
+(keymap-global-set "<mode-line> <mouse-1>" 'scroll-up-command)
@end example
Here is the complete list of these dummy prefix keys and their
@@ -2355,14 +2327,19 @@ function @code{setq} to set the variable @code{fill-column}
(@pxref{Filling}) to 60.
You can set any Lisp variable with @code{setq}, but with certain
-variables @code{setq} won't do what you probably want in the
-init file. Some variables automatically become buffer-local
-when set with @code{setq}; what you want in the init file is to set
-the default value, using @code{setq-default}. Some customizable minor
-mode variables do special things to enable the mode when you set them
-with Customize, but ordinary @code{setq} won't do that; to enable the
-mode in your init file, call the minor mode command. The
-following section has examples of both of these methods.
+variables @code{setq} won't do what you probably want in the init
+file. Some variables automatically become buffer-local when set with
+@code{setq}; what you want in the init file is to set the default
+value, using @code{setq-default}. (The following section has examples
+of both of these methods.)
+
+Some customizable minor mode variables do special things to enable the
+mode when you set them with Customize, but ordinary @code{setq} won't
+do that; to enable the mode in your init file, call the minor mode
+command. Finally, a few customizable user options are initialized in
+complex ways, and these have to be set either via the customize
+interface (@pxref{Customization}) or by using
+@code{customize-set-variable} (@pxref{Examining}).
The second argument to @code{setq} is an expression for the new
value of the variable. This can be a constant, a variable, or a
@@ -2511,6 +2488,14 @@ Turn on Auto Fill mode automatically in Text mode and related modes
@end example
@item
+Change the coding system used when using the clipboard
+(@pxref{Communication Coding}).
+
+@example
+(customize-set-variable 'selection-coding-system 'utf-8)
+@end example
+
+@item
Load the installed Lisp library named @file{foo} (actually a file
@file{foo.elc} or @file{foo.el} in a standard Emacs directory).
@@ -2557,13 +2542,13 @@ Rebind the key @kbd{C-x l} to run the function @code{make-symbolic-link}
(@pxref{Init Rebinding}).
@example
-(global-set-key "\C-xl" 'make-symbolic-link)
+(keymap-global-set "C-x l" 'make-symbolic-link)
@end example
or
@example
-(define-key global-map "\C-xl" 'make-symbolic-link)
+(keymap-set global-map "C-x l" 'make-symbolic-link)
@end example
Note once again the single-quote used to refer to the symbol
@@ -2573,24 +2558,23 @@ Note once again the single-quote used to refer to the symbol
Do the same thing for Lisp mode only.
@example
-(define-key lisp-mode-map "\C-xl" 'make-symbolic-link)
+(keymap-set lisp-mode-map "C-x l" 'make-symbolic-link)
@end example
@item
Redefine all keys which now run @code{next-line} in Fundamental mode
so that they run @code{forward-line} instead.
-@findex substitute-key-definition
+@findex keymap-substitute
@example
-(substitute-key-definition 'next-line 'forward-line
- global-map)
+(keymap-substitute global-map 'next-line 'forward-line)
@end example
@item
Make @kbd{C-x C-v} undefined.
@example
-(global-unset-key "\C-x\C-v")
+(keymap-global-unset "C-x C-v")
@end example
One reason to undefine a key is so that you can make it a prefix.
@@ -2766,29 +2750,17 @@ strings incorrectly. You should then avoid adding Emacs Lisp code
that modifies the coding system in other ways, such as calls to
@code{set-language-environment}.
- To bind non-@acronym{ASCII} keys, you must use a vector (@pxref{Init
-Rebinding}). The string syntax cannot be used, since the
-non-@acronym{ASCII} characters will be interpreted as meta keys. For
-instance:
-
-@example
-(global-set-key [?@var{char}] 'some-function)
-@end example
-
-@noindent
-Type @kbd{C-q}, followed by the key you want to bind, to insert @var{char}.
-
@node Early Init File
@subsection The Early Init File
@cindex early init file
Most customizations for Emacs should be put in the normal init file.
-@xref{Init File}. However, it is sometimes desirable
-to have customizations that take effect during Emacs startup earlier than the
+@xref{Init File}. However, it is sometimes necessary
+to have customizations take effect during Emacs startup earlier than the
normal init file is processed. Such customizations can be put in the early
init file, @file{~/.config/emacs/early-init.el} or @file{~/.emacs.d/early-init.el}. This file is loaded before the
package system and GUI is initialized, so in it you can customize variables
-that affect frame appearance as well as the package initialization process,
+that affect the package initialization process,
such as @code{package-enable-at-startup}, @code{package-load-list}, and
@code{package-user-dir}. Note that variables like @code{package-archives}
which only affect the installation of new packages, and not the process of
diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi
index 680b20c5938..48cf5630eea 100644
--- a/doc/emacs/dired.texi
+++ b/doc/emacs/dired.texi
@@ -742,6 +742,15 @@ never creates such missing directories; the value @code{always},
means Dired automatically creates them; the value @code{ask}
means Dired asks you for confirmation before creating them.
+@vindex dired-create-destination-dirs-on-trailing-dirsep
+If the option @code{dired-create-destination-dirs-on-trailing-dirsep}
+is non-@code{nil} in addition to @code{dired-create-destination-dirs},
+a trailing directory separator at the destination directory is treated
+specially. In that case, when copying to @samp{test/} and no
+directory @samp{test} exists already, it will be created and the
+specified source files or directories are copied into the newly
+created directory.
+
@vindex dired-copy-preserve-time
If @code{dired-copy-preserve-time} is non-@code{nil}, then copying
with this command preserves the modification time of the old file in
@@ -784,6 +793,14 @@ which to move the files (this is like the shell command @command{mv}).
The option @code{dired-create-destination-dirs} controls whether Dired
should create non-existent directories in @var{new}.
+The option @code{dired-create-destination-dirs-on-trailing-dirsep},
+when set in addition to @code{dired-create-destination-dirs}, controls
+wether a trailing directory separator at the destination is treated
+specially. In that case, when renaming a directory @samp{old} to
+@samp{new/} and no directory @samp{new} exists already, it will be
+created and @samp{old} is moved into the newly created directory.
+Otherwise, @samp{old} is renamed to @samp{new}.
+
Dired automatically changes the visited file name of buffers associated
with renamed files so that they refer to the new names.
@@ -823,7 +840,9 @@ link.
Change the mode (also called @dfn{permission bits}) of the specified
files (@code{dired-do-chmod}). @var{modespec} can be in octal or
symbolic notation, like arguments handled by the @command{chmod}
-program.
+program. This command does not follow symbolic links, so it reports
+an error if you try to change the mode of a symbolic link on a
+platform where such modes are immutable.
@findex dired-do-chgrp
@kindex G @r{(Dired)}
@@ -850,8 +869,8 @@ different systems put @command{chown} in different places).
@cindex changing file time (in Dired)
@item T @var{timestamp} @key{RET}
Touch the specified files (@code{dired-do-touch}). This means
-updating their modification times to the present time. This is like
-the shell command @code{touch}.
+updating their modification times to @var{timestamp}, which defaults
+to the present time. This is like the shell command @command{touch}.
@findex dired-do-print
@kindex P @r{(Dired)}
@@ -1505,16 +1524,14 @@ 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
image files. This creates thumbnails for all the images in that
-directory, and displays them all in the thumbnail buffer. This
-takes a long time if the directory contains many image files, and it
-asks for confirmation if the number of image files exceeds
-@code{image-dired-show-all-from-dir-max-files}.
+directory, and displays them all in the thumbnail buffer. The
+thumbnails are generated in the background and are loaded as they
+become available.
With point in the thumbnail buffer, you can type @key{RET}
-(@code{image-dired-display-thumbnail-original-image}) to display a
-sized version of it in another window. This sizes the image to fit
-the window. Use the arrow keys to move around in the buffer. For
-easy browsing, use @key{SPC}
+(@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
@@ -1567,6 +1584,14 @@ rotation is lossless, and uses an external utility called
@node Misc Dired Features
@section Other Dired Features
+@vindex dired-free-space
+ By default, Dired will display the available space on the disk in
+the first line. This is the @code{first} value of the
+@code{dired-free-space} variable. If you set this to
+@code{separate} instead, Dired will display this on a separate line
+(including the space the files in the current directory takes). If
+you set this to @code{nil}, the free space isn't displayed at all.
+
@kindex + @r{(Dired)}
@findex dired-create-directory
The command @kbd{+} (@code{dired-create-directory}) reads a
diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi
index ae345c11df5..15cad88d596 100644
--- a/doc/emacs/display.texi
+++ b/doc/emacs/display.texi
@@ -150,6 +150,14 @@ gives you less jerky scrolling when you hold down @kbd{C-v}, but the
window contents after any action which scrolls into a fresh portion of
the buffer will be momentarily unfontified.
+@vindex redisplay-skip-fontification-on-input
+Finally, a third alternative to these variables is
+@code{redisplay-skip-fontification-on-input}. If this variable is
+non-@code{nil}, skip some fontifications is there's input pending.
+This usually does not affect the display because redisplay is
+completely skipped anyway if input was pending, but it can make
+scrolling smoother by avoiding unnecessary fontification.
+
@vindex scroll-up
@vindex scroll-down
@findex scroll-up-line
@@ -634,24 +642,41 @@ apply them to specific text when you want the effects they produce.
@item default
This face is used for ordinary text that doesn't specify any face.
Its background color is used as the frame's background color.
+
@item bold
This face uses a bold variant of the default font.
+
@item italic
This face uses an italic variant of the default font.
+
@item bold-italic
This face uses a bold italic variant of the default font.
+
@item underline
This face underlines text.
+
@item fixed-pitch
This face forces use of a fixed-width font. It's reasonable to
customize this face to use a different fixed-width font, if you like,
but you should not make it a variable-width font.
+
@item fixed-pitch-serif
This face is like @code{fixed-pitch}, except the font has serifs and
looks more like traditional typewriting.
+
@cindex @code{variable-pitch} face
@item variable-pitch
-This face forces use of a variable-width font.
+This face forces use of a variable-width (i.e., proportional) font.
+The font size picked for this face matches the font picked for the
+default (usually fixed-width) font.
+
+@item variable-pitch-text
+This is like the @code{variable-pitch} face (from which it inherits),
+but is slightly larger. A proportional font of the same height as a
+monospace font usually appears visually smaller, and can therefore be
+harder to read. When displaying longer texts, this face can be a good
+choice over the (slightly smaller) @code{variable-pitch} face.
+
@cindex @code{shadow} face
@item shadow
This face is used for making the text less noticeable than the surrounding
@@ -708,46 +733,62 @@ frame:
@table @code
@item mode-line
@cindex @code{mode-line} face
-@cindex faces for mode lines
-This face is used for the mode line of the currently selected window,
+This is the base face used for the mode lines, as well as header lines
and for menu bars when toolkit menus are not used. By default, it's
drawn with shadows for a raised effect on graphical displays, and
drawn as the inverse of the default face on non-windowed terminals.
+
+The @code{mode-line-active} and @code{mode-line-inactive} faces (which
+are the ones used on the mode lines) inherit from this face.
+
+@item mode-line-active
+@cindex faces for mode lines
+Like @code{mode-line}, but used for the mode line of the currently
+selected window. This face inherits from @code{mode-line}, so changes
+in that face affect mode lines in all windows.
+
@item mode-line-inactive
@cindex @code{mode-line-inactive} face
Like @code{mode-line}, but used for mode lines of the windows other
than the selected one (if @code{mode-line-in-non-selected-windows} is
non-@code{nil}). This face inherits from @code{mode-line}, so changes
in that face affect mode lines in all windows.
+
@item mode-line-highlight
@cindex @code{mode-line-highlight} face
Like @code{highlight}, but used for mouse-sensitive portions of text
on mode lines. Such portions of text typically pop up tooltips
(@pxref{Tooltips}) when the mouse pointer hovers above them.
+
@item mode-line-buffer-id
@cindex @code{mode-line-buffer-id} face
This face is used for buffer identification parts in the mode line.
+
@item header-line
@cindex @code{header-line} face
Similar to @code{mode-line} for a window's header line, which appears
at the top of a window just as the mode line appears at the bottom.
Most windows do not have a header line---only some special modes, such
Info mode, create one.
+
@item header-line-highlight
@cindex @code{header-line-highlight} face
Similar to @code{highlight} and @code{mode-line-highlight}, but used
for mouse-sensitive portions of text on header lines. This is a
separate face because the @code{header-line} face might be customized
in a way that does not interact well with @code{highlight}.
+
@item tab-line
@cindex @code{tab-line} face
Similar to @code{mode-line} for a window's tab line, which appears
at the top of a window with tabs representing window buffers.
@xref{Tab Line}.
+
@item vertical-border
@cindex @code{vertical-border} face
This face is used for the vertical divider between windows on text
terminals.
+
@item minibuffer-prompt
@cindex @code{minibuffer-prompt} face
@vindex minibuffer-prompt-properties
@@ -757,19 +798,23 @@ By default, Emacs automatically adds this face to the value of
properties (@pxref{Text Properties,,, elisp, the Emacs Lisp Reference
Manual}) used to display the prompt text. (This variable takes effect
when you enter the minibuffer.)
+
@item fringe
@cindex @code{fringe} face
The face for the fringes to the left and right of windows on graphic
displays. (The fringes are the narrow portions of the Emacs frame
between the text area and the window's right and left borders.)
@xref{Fringes}.
+
@item cursor
The @code{:background} attribute of this face specifies the color of
the text cursor. @xref{Cursor Display}.
+
@item tooltip
This face is used for tooltip text. By default, if Emacs is built
with GTK+ support, tooltips are drawn via GTK+ and this face has no
effect. @xref{Tooltips}.
+
@item mouse
This face determines the color of the mouse pointer.
@end table
@@ -1645,6 +1690,12 @@ characters more prominent on display. @xref{Glyphless Chars,,
Glyphless Character Display, elisp, The Emacs Lisp Reference Manual},
for details.
+@findex glyphless-display-mode
+ The @code{glyphless-display-mode} minor mode can be used to toggle
+the display of glyphless characters in the current buffer. The
+glyphless characters will be displayed as boxes with acronyms of their
+names inside.
+
@cindex curly quotes, and terminal capabilities
@cindex curved quotes, and terminal capabilities
@cindex @code{homoglyph} face
@@ -1767,6 +1818,10 @@ multiple screen lines. Setting the variable @code{truncate-lines} in
any way makes it local to the current buffer; until that time, the
default value, which is normally @code{nil}, is in effect.
+ Since line truncation and word wrap (described in the next section)
+are contradictory, @code{toggle-truncate-lines} disables word wrap
+when it turns on line truncation.
+
If a split window becomes too narrow, Emacs may automatically enable
line truncation. @xref{Split Window}, for the variable
@code{truncate-partial-width-windows} which controls this.
@@ -1797,6 +1852,10 @@ mode is enabled, the mode line shows the string @samp{wrap} in the
mode display. The command @kbd{M-x global-visual-line-mode} toggles
Visual Line mode in all buffers.
+ Since word wrap and line truncation (described in the previous
+section) are contradictory, turning on @code{visual-line-mode}
+disables line truncation.
+
@findex beginning-of-visual-line
@findex end-of-visual-line
@findex next-logical-line
diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi
index d2011ebf974..dff42c7b42c 100644
--- a/doc/emacs/emacs.texi
+++ b/doc/emacs/emacs.texi
@@ -116,7 +116,7 @@ ways to customize it; it corresponds to GNU Emacs version @value{EMACSVER}.
@c See 'manual-html-mono' and 'manual-html-node' in admin/admin.el.
@ifset WWW_GNU_ORG
@html
-The homepage for GNU Emacs is at
+The GNU Emacs website is at
<a href="/software/emacs/">https://www.gnu.org/software/emacs/</a>.<br>
To view this manual in other formats, click
<a href="/software/emacs/manual/emacs.html">here</a>.<br>
@@ -219,8 +219,9 @@ Appendices
* GNU Free Documentation License:: The license for this documentation.
* Emacs Invocation:: Hairy startup options.
* X Resources:: X resources for customizing Emacs.
-* Antinews:: Information about Emacs version 26.
+* Antinews:: Information about Emacs version 27.
* Mac OS / GNUstep:: Using Emacs under macOS and GNUstep.
+* Haiku:: Using Emacs on Haiku.
* Microsoft Windows:: Using Emacs on Microsoft Windows and MS-DOS.
* Manifesto:: What's GNU? Gnu's Not Unix!
@@ -344,14 +345,14 @@ Cut and Paste Operations on Graphical Displays
Registers
-* Position Registers:: Saving positions in registers.
-* Text Registers:: Saving text in registers.
-* Rectangle Registers:: Saving rectangles in registers.
-* Configuration Registers:: Saving window configurations in registers.
-* Number Registers:: Numbers in registers.
-* File Registers:: File names in registers.
-* Keyboard Macro Registers:: Keyboard macros in registers.
-* Bookmarks:: Bookmarks are like registers, but persistent.
+* Position Registers:: Saving positions in registers.
+* Text Registers:: Saving text in registers.
+* Rectangle Registers:: Saving rectangles in registers.
+* Configuration Registers:: Saving window configurations in registers.
+* Number Registers:: Numbers in registers.
+* File and Buffer Registers:: File and buffer names in registers.
+* Keyboard Macro Registers:: Keyboard macros in registers.
+* Bookmarks:: Bookmarks are like registers, but persistent.
Controlling the Display
@@ -1249,6 +1250,11 @@ Emacs and macOS / GNUstep
* Mac / GNUstep Events:: How window system events are handled.
* GNUstep Support:: Details on status of GNUstep support.
+Emacs and Haiku
+
+* Haiku Basics:: Basic Emacs usage and installation under Haiku.
+* Haiku Fonts:: The various options for displaying fonts on Haiku.
+
Emacs and Microsoft Windows/MS-DOS
* Windows Startup:: How to start Emacs on Windows.
@@ -1618,6 +1624,7 @@ Lisp programming.
@include anti.texi
@include macos.texi
+@include haiku.texi
@c Includes msdos-xtra.
@include msdos.texi
@include gnu.texi
diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi
index 8304e40706a..b7016b00575 100644
--- a/doc/emacs/files.texi
+++ b/doc/emacs/files.texi
@@ -742,6 +742,17 @@ always supposed to end in newlines. Such major modes set the variable
setting the latter variable, you can control how these modes handle
final newlines.
+@vindex file-preserve-symlinks-on-save
+If this option is non-@code{nil} and you're visiting a file via a
+symbolic link, Emacs will break the symbolic link upon saving the
+buffer, and will write the buffer to a file with the same name as the
+symbolic link, if the value of @code{file-precious-flag} is
+non-@code{nil} (@pxref{Saving Buffers, file-precious-flag,, elisp, The
+Emacs Lisp Reference Manual}). If you want Emacs to save the buffer
+to the file the symbolic link points to (thereby preserving the link)
+in these cases, customize the variable
+@code{file-preserve-symlinks-on-save} to @code{t}.
+
@vindex write-region-inhibit-fsync
Normally, when a program writes a file, the operating system briefly
caches the file's data in main memory before committing the data to
@@ -1180,6 +1191,13 @@ visited file. (You can inhibit this by setting the variable
file name with @kbd{C-x C-w} or @code{set-visited-file-name} renames
any auto-save file to go with the new visited name.
+@vindex kill-buffer-delete-auto-save-files
+ Killing a buffer, by default, doesn't remove the buffer's auto-save
+file. If @code{kill-buffer-delete-auto-save-files} is non-@code{nil},
+killing a buffer that has an auto-save file will make Emacs prompt the
+user for whether the auto-save file should be deleted. (This is
+inhibited if @code{delete-auto-save-files} is @code{nil}.)
+
@node Auto Save Control
@subsection Controlling Auto-Saving
@@ -1458,8 +1476,8 @@ characters that don't match. Then the command exits.
If point in the two windows is followed by non-matching text when
the command starts, @kbd{M-x compare-windows} tries heuristically to
advance up to matching text in the two windows, and then exits. So if
-you use @kbd{M-x compare-windows} repeatedly, each time it either
-skips one matching range or finds the start of another.
+you use @kbd{M-x compare-windows} repeatedly (@pxref{Repeating}), each
+time it either skips one matching range or finds the start of another.
@vindex compare-ignore-case
@vindex compare-ignore-whitespace
@@ -1728,12 +1746,16 @@ exists.
@kbd{M-x copy-file} copies the contents of the file @var{old} to the
file @var{new}.
+@vindex copy-directory-create-symlink
@findex copy-directory
@kbd{M-x copy-directory} copies directories, similar to the
@command{cp -r} shell command. If @var{new} is a directory name, it
creates a copy of the @var{old} directory and puts it in @var{new}.
Otherwise it copies all the contents of @var{old} into a new directory
-named @var{new}.
+named @var{new}. If @code{copy-directory-create-symlink} is
+non-@code{nil} and @var{old} is a symbolic link, this command will
+copy the symbolic link. If @code{nil}, this command will follow the
+link and copy the contents instead. (This is the default.)
@cindex renaming files
@findex rename-file
@@ -2183,11 +2205,11 @@ window, so this is only necessary if you customize the default
behavior by using the options @code{image-auto-resize} and
@code{image-auto-resize-on-window-resize}.
-@findex image-transform-fit-both
+@findex image-transform-fit-to-window
@findex image-transform-set-scale
@findex image-transform-reset
To resize the image manually you can use the command
-@code{image-transform-fit-both} bound to @kbd{s b}
+@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 specifying a scale factor, use the command
@code{image-transform-set-scale} bound to @kbd{s s}.
diff --git a/doc/emacs/fixit.texi b/doc/emacs/fixit.texi
index b558ebc3fdc..7feebddee8c 100644
--- a/doc/emacs/fixit.texi
+++ b/doc/emacs/fixit.texi
@@ -462,10 +462,9 @@ use @code{flyspell-region} or @code{flyspell-buffer} for that.
When Flyspell mode highlights a word as misspelled, you can click on
it with @kbd{mouse-2} (@code{flyspell-correct-word}) to display a menu
of possible corrections and actions. If you want this menu on
-@kbd{mouse-3} instead, customize the variable
-@code{flyspell-use-mouse-3-for-menu}. In addition, @kbd{C-.} or
-@kbd{@key{ESC}-@key{TAB}} (@code{flyspell-auto-correct-word}) will
-propose various successive corrections for the word at point, and
+@kbd{mouse-3} instead, enable @code{context-menu-mode}. In addition,
+@kbd{C-.} or @kbd{@key{ESC} @key{TAB}} (@code{flyspell-auto-correct-word})
+will propose various successive corrections for the word at point, and
@w{@kbd{C-c $}} (@code{flyspell-correct-word-before-point}) will pop
up a menu of possible corrections. Of course, you can always correct
the misspelled word by editing it manually in any way you like.
diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi
index 5b15e6290d0..c14ada29576 100644
--- a/doc/emacs/frames.texi
+++ b/doc/emacs/frames.texi
@@ -370,11 +370,20 @@ This menu is for changing the default face within the window's buffer.
@findex context-menu-mode
@vindex context-menu-functions
@kindex Down-mouse-3
- Some graphical applications use @kbd{mouse-3} for a mode-specific
-menu. If you prefer @kbd{mouse-3} in Emacs to bring up such a context
-menu instead of running the @code{mouse-save-then-kill} command,
-enable @code{context-menu-mode} and customize the variable
-@code{context-menu-functions}.
+@kindex S-F10
+ Many GUI applications use @kbd{mouse-3} to display @dfn{context
+menus}: menus that provide access to various pertinent settings and
+actions for the location and context of the mouse click. If you
+prefer this in Emacs over the default function of @kbd{mouse-3}, which
+is bound to the @code{mouse-save-then-kill} command (@pxref{Mouse
+Commands}), you can enable the minor mode @code{context-menu-mode}.
+Then Emacs will show context menus when you click @kbd{mouse-3}. The
+exact contents of these context menus depends on the current major
+mode and the buffer contents around the place where you click the
+mouse. To customize the contents of the context menu, you can use the
+variable @code{context-menu-functions} (@pxref{Major Mode
+Conventions,,, elisp, The Emacs Lisp Reference Manual}).
+You can also invoke the context menu by pressing @kbd{S-@key{F10}}.
@node Mode Line Mouse
@section Mode Line Mouse Commands
@@ -443,7 +452,14 @@ buffer to select:
@item C-x 5 2
@kindex C-x 5 2
@findex make-frame-command
-Create a new frame (@code{make-frame-command}).
+Create a new frame using the default frame parameters
+(@code{make-frame-command}).
+
+@item C-x 5 c
+@kindex C-x 5 c
+@findex clone-frame
+Create a new frame using the window configuration and frame parameters
+of the current frame (@code{clone-frame}).
@item C-x 5 b @var{bufname} @key{RET}
Select buffer @var{bufname} in another frame. This runs
@@ -1265,19 +1281,23 @@ displayed by moving the mouse pointer to the top of the screen.
@section Tab Bars
@cindex tab bar mode
@cindex mode, Tab Bar
-@cindex tabs, tabbar
+@cindex tabs, on the Tab Bar
On graphical displays and on text terminals, Emacs can optionally
display a @dfn{Tab Bar} at the top of each frame, just below the menu
-bar. The Tab Bar is a row of @dfn{tabs}---buttons that you can click
-to switch between window configurations on that frame.
+bar (@pxref{Menu Bars}) and above or below the tool bar (@pxref{Tool
+Bars}) depending on the variable @code{tab-bar-position}.
+The Tab Bar is a row of @dfn{tabs}---buttons that you can click to
+switch between window configurations.
Each tab on the Tab Bar represents a named persistent window
-configuration. Its name is composed from the list of names of buffers
-visible in windows of that window configuration. Clicking on the tab
-switches to the window configuration recorded by the tab; it is a
-configuration of windows and buffers which was previously used in the
-frame when that tab was the current tab.
+configuration of its frame, i.e., how that frame is partitioned into
+windows and which buffer is displayed in each window. The tab's name
+is composed from the list of names of buffers shown in windows of that
+window configuration. Clicking on the tab switches to the window
+configuration recorded by the tab; it is a configuration of windows
+and buffers which was previously used in the frame when that tab was
+the current tab.
If you are using the desktop library to save and restore your
sessions (@pxref{Saving Emacs Sessions}), the tabs from the Tab Bar are
@@ -1286,28 +1306,40 @@ configurations, and will be available after restoring the session.
Note that the Tab Bar is different from the Tab Line (@pxref{Tab Line}).
Whereas tabs on the Tab Line at the top of each window are used to
-switch between buffers, tabs on the Tab Bar at the top of each frame
-are used to switch between window configurations containing several
-windows with buffers.
+switch between buffers in the window, tabs on the Tab Bar at the top
+of each frame are used to switch between window configurations
+containing several windows showing one or more buffers.
@findex tab-bar-mode
- To toggle the use of tab bars, type @kbd{M-x tab-bar-mode}. This
+ To toggle the use of Tab Bars, type @kbd{M-x tab-bar-mode}. This
command applies to all frames, including frames yet to be created. To
control the use of tab bars at startup, customize the variable
-@code{tab-bar-mode}.
+@code{tab-bar-mode} and save your customization.
@vindex tab-bar-show
The variable @code{tab-bar-show} controls whether the Tab Bar mode
is turned on automatically. If the value is @code{t}, then
@code{tab-bar-mode} is enabled when using the commands that create new
tabs. The value @code{1} hides the tab bar when it has only one tab,
-and shows it again when more tabs are created. The value @code{nil}
-always keeps the tab bar hidden; in this case it's still possible to
-switch between named window configurations without the tab bar by
-using @kbd{M-x tab-next}, @kbd{M-x tab-switcher}, and other commands
-that provide completion on tab names. Also it's possible to create
-and close tabs without the tab bar by using commands @kbd{M-x
-tab-new}, @kbd{M-x tab-close}, etc.
+and shows it again when more tabs are created. More generally, a
+value that is a non-negative integer causes the Tab Bar to be
+displayed only if the number of tabs is greater than that integer.
+The value @code{nil} always keeps the Tab Bar hidden; in this case
+it's still possible to switch between named window configurations
+without displaying the Tab Bar by using @kbd{M-x tab-next}, @kbd{M-x
+tab-switcher}, and other commands that provide completion on tab
+names. Also it's possible to create and close tabs without the Tab
+Bar by using commands @kbd{M-x tab-new}, @kbd{M-x tab-close}, etc.
+
+ Note that a numerical value of @code{tab-bar-show} can cause the Tab
+Bar to be displayed on some frames, but not on others, depending on
+the number of tabs created on each frame.
+
+@findex toggle-frame-tab-bar
+ To toggle the use of the Tab Bar only on the selected frame, type
+@kbd{M-x toggle-frame-tab-bar}. This command allows to enable the
+display of the Tab Bar on some frames and disable it on others,
+regardless of the values of @code{tab-bar-mode} and @code{tab-bar-show}.
@kindex C-x t
The prefix key @kbd{C-x t} is analogous to @kbd{C-x 5}.
@@ -1320,29 +1352,41 @@ buffer to select. The following commands can be used to select a buffer
in a new tab:
@table @kbd
-@item C-x t 2
@kindex C-x t 2
@findex tab-new
+@vindex tab-bar-tab-name-function
+@item C-x t 2
Add a new tab (@code{tab-new}). You can control the choice of the
buffer displayed in a new tab by customizing the variable
-@code{tab-bar-new-tab-choice}.
+@code{tab-bar-new-tab-choice}. You can control the names given by
+default to new tabs by customizing the variable
+@code{tab-bar-tab-name-function}.
+@kindex C-x t b
+@findex switch-to-buffer-other-tab
@item C-x t b @var{bufname} @key{RET}
Select buffer @var{bufname} in another tab. This runs
@code{switch-to-buffer-other-tab}.
+@kindex C-x t f
+@findex find-file-other-tab
@item C-x t f @var{filename} @key{RET}
-Visit file @var{filename} and select its buffer in another tab. This
-runs @code{find-file-other-tab}. @xref{Visiting}.
+Visit the file @var{filename} (@pxref{Visiting}) and select its buffer
+in another tab. This runs @code{find-file-other-tab}.
+@kindex C-x t d
+@findex dired-other-tab
@item C-x t d @var{directory} @key{RET}
-Select a Dired buffer for directory @var{directory} in another tab.
-This runs @code{dired-other-tab}. @xref{Dired}.
+Edit the specified @var{directory} (@pxref{Dired}) in another tab.
+This runs @code{dired-other-tab}.
+@kindex C-x t t
+@findex other-tab-prefix
@item C-x t t
-A more general prefix command affects the buffer displayed by the next
-command invoked immediately after this prefix command. It requests
-the buffer of the next command to be displayed in another tab.
+This is a prefix command (@code{other-tab-prefix}) that affects the
+next command invoked immediately after this prefix command. It
+requests the buffer displayed by the next command to be shown in
+another tab.
@end table
@vindex tab-bar-new-tab-choice
@@ -1358,17 +1402,18 @@ By default, a new tab is added on the right side of the current tab.
The following commands can be used to delete tabs:
@table @kbd
-@item C-x t 0
@kindex C-x t 0
@findex tab-close
-Close the selected tab (@code{tab-close}). It has no effect if there
+@vindex tab-bar-close-last-tab-choice
+@item C-x t 0
+Close the selected tab (@code{tab-close}). This has no effect if there
is only one tab, unless the variable @code{tab-bar-close-last-tab-choice}
is customized to a non-default value.
-@item C-x t 1
@kindex C-x t 1
@findex tab-close-other
-Close all tabs on the selected frame, except the selected one.
+@item C-x t 1
+Close all tabs, except the selected tab, on the selected frame.
@end table
@vindex tab-bar-close-tab-select
@@ -1382,77 +1427,113 @@ a recently used tab.
The following commands can be used to switch between tabs:
@table @kbd
-@item C-x t o
-@itemx C-@key{TAB}
@kindex C-x t o
@kindex C-TAB
@findex tab-next
-Switch to the next tab. If you repeat this command, it cycles through
-all the tabs on the selected frame. With a positive numeric argument
-@var{n}, it switches to the next @var{n}th tab; with a negative
-argument @minus{}@var{n}, it switches back to the previous @var{n}th
-tab.
+@item C-x t o
+@itemx C-@key{TAB}
+Switch to the next tab (@code{tab-next}). If you repeat this command,
+it cycles through all the tabs on the selected frame. With a positive
+numeric argument @var{n}, it switches to the @var{n}th next tab; with
+a negative argument @minus{}@var{n}, it switches back to the @var{n}th
+previous tab.
-@item S-C-@key{TAB}
@kindex S-C-TAB
@findex tab-previous
-Switch to the previous tab. With a positive numeric argument @var{n},
-it switches to the previous @var{n}th tab; with a negative argument
-@minus{}@var{n}, it switches back to the next @var{n}th tab.
+@item S-C-@key{TAB}
+Switch to the previous tab (@code{tab-previous}). With a positive
+numeric argument @var{n}, it switches to the @var{n}th previous tab;
+with a negative argument @minus{}@var{n}, it switches to the
+@var{n}th next tab.
+@kindex C-x t @key{RET}
+@findex tab-switch
@item C-x t @key{RET} @var{tabname} @key{RET}
-Switch to the tab by its name, with completion on all tab names.
-Default values are tab names sorted by recency, so you can use
-@kbd{M-n} (@code{next-history-element}) to get the name of the last
-visited tab, the second last, and so on.
-
-@item @var{modifier}-@var{tabnumber}
+Switch to the tab by its name (@code{tab-switch}), with completion on
+all tab names. The default value and the ``future history'' of tab
+names is sorted by recency, so you can use @kbd{M-n}
+(@code{next-history-element}) to get the name of the last visited tab,
+the second last, and so on.
+
+@kindex C-1, tab bar
+@kindex M-1, tab bar
@findex tab-select
-Switch to the tab by its number. After customizing the variable
-@code{tab-bar-select-tab-modifiers} to specify a @var{modifier} key, you
-can select a tab by its ordinal number using the specified modifier in
-combination with the tab number to select. To display the tab number
-alongside the tab name, you can customize another variable
-@code{tab-bar-tab-hints}. This will help you to decide what key to press
-to select the tab by its number.
-
-@item @var{modifier}-@kbd{0}
+@vindex tab-bar-select-tab-modifiers
+@vindex tab-bar-tab-hints
+@item @var{modifier}-@var{tab-number}
+Switch to the tab by its number @var{tab-number} (@code{tab-select}).
+After customizing the variable @code{tab-bar-select-tab-modifiers} to
+specify one or more @var{modifier} keys, you can select a tab by its
+ordinal number using one of the specified modifiers in combination
+with the tab number to select. The number 9 can be used to select the
+last tab. You can select any modifiers supported by Emacs,
+@pxref{Modifier Keys}. To display the tab number alongside the tab
+name, you can customize another variable @code{tab-bar-tab-hints}.
+This will help you decide which numerical key to press to select the
+tab by its number.
+
+@kindex C-9, tab bar
+@kindex M-9, tab bar
+@findex tab-last
+@item @var{modifier}-@kbd{9}
+Switch to the last tab (@code{tab-last}). The key combination is
+the modifier key defined by @code{tab-bar-select-tab-modifiers} and
+the key @kbd{9}. With a numeric argument @var{n}, switch to the
+@var{n}th last tab.
+
+@kindex C-0, tab bar
+@kindex M-0, tab bar
@findex tab-recent
-Switch to the recent tab. The key combination is the modifier key
-defined by @code{tab-bar-select-tab-modifiers} and the key @kbd{0}.
-With a numeric argument @var{n}, switch to the @var{n}th recent tab.
+@item @var{modifier}-@kbd{0}
+Switch to the recent tab (@code{tab-recent}). The key combination is
+the modifier key defined by @code{tab-bar-select-tab-modifiers} and
+the key @kbd{0}. With a numeric argument @var{n}, switch to the
+@var{n}th recent tab.
@end table
The following commands can be used to operate on tabs:
@table @kbd
-@item C-x t r @var{tabname} @key{RET}
+@kindex C-x t r
@findex tab-rename
-Rename the current tab to @var{tabname}. You can control the
-programmatic name given to a tab by default by customizing the
-variable @code{tab-bar-tab-name-function}.
+@item C-x t r @var{tabname} @key{RET}
+Rename the current tab to @var{tabname} (@code{tab-rename}).
-@item C-x t m
+@kindex C-x t m
@findex tab-move
-Move the current tab @var{n} positions to the right with a positive
-numeric argument @var{n}. With a negative argument @minus{}@var{n},
-move the current tab @var{n} positions to the left.
+@item C-x t m
+Move the current tab one position to the right (@code{tab-move}).
+With a positive numeric argument @var{n}, move it that many positions
+to the right; with a negative argument @minus{}@var{n}, move it
+@var{n} positions to the left.
@end table
+ You can use the mouse to operate on tabs. Clicking @kbd{mouse-2}
+closes the tab. Clicking @kbd{mouse-3} pops up the context menu with
+the items that operate on the clicked tab. Dragging the tab with
+@kbd{mouse-1} moves it to another position on the tab bar. Mouse
+wheel scrolling switches to the next or previous tab. Holding down
+the @key{SHIFT} key during scrolling moves the tab to the left or right.
+
@findex tab-bar-history-mode
You can enable @code{tab-bar-history-mode} to remember window
-configurations used in every tab, and restore them.
+configurations used in every tab, and later restore them.
@table @kbd
-@item tab-bar-history-back
+@findex tab-bar-history-back
+@item M-x tab-bar-history-back
Restore a previous window configuration used in the current tab.
This navigates back in the history of window configurations.
-@item tab-bar-history-forward
+@findex tab-bar-history-forward
+@item M-x tab-bar-history-forward
Cancel restoration of the previous window configuration.
-This navigates forward in the history of window configurations.
+This moves forward in the history of window configurations.
@end table
+ It's possible to customize the items displayed on the tab bar
+by the user option @code{tab-bar-format}.
+
@node Dialog Boxes
@section Using Dialog Boxes
@cindex dialog boxes
diff --git a/doc/emacs/glossary.texi b/doc/emacs/glossary.texi
index 4f971eb1e01..9c06bcc4af1 100644
--- a/doc/emacs/glossary.texi
+++ b/doc/emacs/glossary.texi
@@ -86,8 +86,8 @@ delimiter for you (@pxref{Matching,,Matching Parens}).
@anchor{Glossary---Balanced Expression}
@item Balanced Expressions
A balanced expression is a syntactically recognizable expression, such
-as a symbol, number, string constant, block, or parenthesized expression
-in C@. @xref{Expressions,Balanced Expressions}.
+as a symbol (q.v.@:), number, string constant, block, or parenthesized
+expression in C@. @xref{Expressions,Balanced Expressions}.
@item Balloon Help
@xref{Glossary---Tooltips}.
@@ -238,7 +238,7 @@ a key binding in Emacs or to be invoked by its name
@anchor{Glossary---Command Name}
@item Command Name
-A command name is the name of a Lisp symbol that is a command
+A command name is the name of a Lisp symbol (q.v.@:) that is a command
(@pxref{Commands}). You can invoke any command by its name using
@kbd{M-x} (@pxref{M-x,M-x,Running Commands by Name}).
@@ -1113,7 +1113,7 @@ Emacs. @xref{Query Replace}.
@anchor{Glossary---Quitting}
@item Quitting
Quitting means canceling a partially typed command or a running
-command, using @kbd{C-g} (or @kbd{C-@key{BREAK}} on MS-DOS). @xref{Quitting}.
+command, using @kbd{C-g} (or @kbd{C-@key{Break}} on MS-DOS). @xref{Quitting}.
@item Quoting
Quoting means depriving a character of its usual special significance.
@@ -1334,6 +1334,13 @@ allowed as well.
@item String Substitution
@xref{Glossary---Global Substitution}.
+@item Symbol
+A symbol in Emacs Lisp is an object with a name. The object can be a
+variable (q.v.@:), a function or command (q.v.@:), or a face (q.v.@:).
+The symbol's name serves as the printed representation of the symbol.
+@xref{Symbol Type,, Symbol Type, elisp, The Emacs Lisp Reference
+Manual}.
+
@item Syntax Highlighting
@xref{Glossary---Font Lock}.
diff --git a/doc/emacs/haiku.texi b/doc/emacs/haiku.texi
new file mode 100644
index 00000000000..d2b7eb8408f
--- /dev/null
+++ b/doc/emacs/haiku.texi
@@ -0,0 +1,124 @@
+@c This is part of the Emacs manual.
+@c Copyright (C) 2021 Free Software Foundation, Inc.
+@c See file emacs.texi for copying conditions.
+@node Haiku
+@appendix Emacs and Haiku
+@cindex Haiku
+
+ Haiku is a Unix-like operating system that originated as a
+re-implementation of the operating system BeOS.
+
+ This section describes the peculiarities of using Emacs built with
+the Application Kit, the windowing system native to Haiku. The
+oddities described here do not apply to using Emacs on Haiku built
+without windowing support, or built with X11.
+
+@menu
+* Haiku Basics:: Basic Emacs usage and installation under Haiku.
+* Haiku Fonts:: The various options for displaying fonts on Haiku.
+@end menu
+
+@node Haiku Basics
+@section Installation and usage peculiarities under Haiku
+@cindex haiku application
+@cindex haiku installation
+
+ Emacs installs two separate executables under Haiku; it is up to the
+user to decide which one suits him best: A regular executable, with
+the lowercase name @code{emacs}, and a binary containing
+Haiku-specific application metadata, with the name @code{Emacs}.
+
+@cindex launching Emacs from the tracker
+@cindex tty Emacs in haiku
+ If you are launching Emacs from the Tracker, or want to make the
+Tracker open files using Emacs, you should use the binary named
+@code{Emacs}; if you are going to use Emacs in the terminal, or wish
+to launch separate instances of Emacs, or do not care for the
+aforementioned system integration features, use the binary named
+@code{emacs} instead.
+
+@cindex modifier keys and system keymap (Haiku)
+@cindex haiku keymap
+ On Haiku, unusual modifier keys such as the Hyper key are
+unsupported. By default, the super key corresponds with the option
+key defined by the operating system, the meta key with the command
+key, the control key with the system control key, and the shift key
+with the system shift key. On a standard PC keyboard, Haiku should
+map these keys to positions familiar to those using a GNU system, but
+this may require some adjustment to your system's configuration to
+work.
+
+ It is impossible to type accented characters using the system super
+key map.
+
+ You can customize the correspondence between modifier keys known to
+the system, and those known to Emacs. The variables that allow for
+that are described below.
+
+@cindex modifier key customization (Haiku)
+@table @code
+@vindex haiku-meta-keysym
+@item haiku-meta-keysym
+The system modifier key that will be treated as the Meta key by Emacs.
+It defaults to @code{command}.
+
+@vindex haiku-control-keysym
+@item haiku-control-keysym
+The system modifier key that will be treated as the Control key by
+Emacs. It defaults to @code{control}.
+
+@vindex haiku-super-keysym
+@item haiku-super-keysym
+The system modifier key that will be treated as the Super key by
+Emacs. It defaults to @code{option}.
+
+@vindex haiku-shift-keysym
+@item haiku-shift-keysym
+The system modifier key that will be treated as the Shift key by
+Emacs. It defaults to @code{shift}.
+@end table
+
+The value of each variable can be one of the symbols @code{command},
+@code{control}, @code{option}, @code{shift}, or @code{nil}.
+@code{nil} or any other value will cause the default value to be used
+instead.
+
+@cindex tooltips (haiku)
+@cindex haiku tooltips
+@vindex haiku-use-system-tooltips
+ On Haiku, Emacs defaults to using the system tooltip mechanism.
+This usually leads to more responsive tooltips, but the tooltips will
+not be able to display text properties or faces. If you need those
+features, customize the variable @code{haiku-use-system-tooltips} to
+the nil value, and Emacs will use its own implementation of tooltips.
+
+ Both system tooltips and Emacs's own tooltips cannot display above
+the menu bar, so help text in the menu bar will display in the echo
+area instead.
+
+@subsection What to do when Emacs crashes
+@cindex crashes, Haiku
+@cindex haiku debugger
+@vindex haiku-debug-on-fatal-error
+ If the variable @code{haiku-debug-on-fatal-error} is non-nil, Emacs
+will launch the system debugger when a fatal signal is received. It
+defaults to @code{t}. If GDB cannot be used on your system, please
+attach the report generated by the system debugger when reporting a
+bug.
+
+@node Haiku Fonts
+@section Font and font backend selection on Haiku
+@cindex font backend selection (Haiku)
+
+ Emacs, when built with Haiku windowing support, can be built with
+several different font backends. You can specify font backends by
+specifying @kbd{-xrm Emacs.fontBackend:BACKEND} on the command line
+used to invoke Emacs, where @kbd{BACKEND} is one of the backends
+specified below, or on a per-frame basis by changing the
+@code{font-backend} frame parameter.
+
+ Two of these backends, @code{ftcr} and @code{ftcrhb} are identical
+to their counterparts on the X Window System. There is also a
+Haiku-specific backend named @code{haiku}, that uses the App Server to
+draw fonts, but does not at present support display of color font and
+emoji.
diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi
index 0caab681d34..20a9d8be13b 100644
--- a/doc/emacs/help.texi
+++ b/doc/emacs/help.texi
@@ -278,6 +278,15 @@ name is defined as a Lisp function. Type @kbd{C-g} to cancel the
@kbd{C-h f} command if you don't really want to view the
documentation.
+@vindex help-enable-symbol-autoload
+ If you request help for an autoloaded function whose @code{autoload}
+form (@pxref{Autoload,,, elisp, The Emacs Lisp Reference Manual})
+doesn't provide a doc string, the @file{*Help*} buffer won't have any
+doc string to display. In that case, if
+@code{help-enable-symbol-autoload} is non-@code{nil}, Emacs will try
+to load the file in which the function is defined to see whether
+there's a doc string there.
+
@findex shortdoc-display-group
You can get an overview of functions relevant for a particular topic
by using the @kbd{M-x shortdoc-display-group} command. This will
@@ -310,6 +319,14 @@ variable, or a face. If the symbol has more than one definition, like
it has both definition as a function and as a variable, this command
will show the documentation of all of them, one after the other.
+@vindex completions-detailed
+ If the @code{completions-detailed} user option is non-@code{nil},
+some commands provide details about the possible values when
+displaying completions. For instance, @kbd{C-h o TAB} will then
+include the first line of the doc string, and will also say whether
+each symbol is a function or a variable (and so on). Which details
+are included varies depending on the command used.
+
@node Apropos
@section Apropos
@cindex apropos
@@ -426,11 +443,13 @@ alphabetical order, change the variable
@node Help Mode
@section Help Mode Commands
+@findex help-mode
+@cindex help mode
- Help buffers provide the same commands as View mode (@pxref{View
-Mode}); for instance, @key{SPC} scrolls forward, and @key{DEL} or
-@kbd{S-@key{SPC}} scrolls backward. A few special commands are also
-provided:
+ Help buffers have Help mode as their major mode. Help mode provides
+the same commands as View mode (@pxref{View Mode}); for instance,
+@key{SPC} scrolls forward, and @key{DEL} or @kbd{S-@key{SPC}} scrolls
+backward. It also provides a few special commands:
@table @kbd
@item @key{RET}
@@ -442,15 +461,18 @@ Move point back to the previous hyperlink (@code{backward-button}).
@item mouse-1
@itemx mouse-2
Follow a hyperlink that you click on.
+@item n
+@itemx p
+Move forward and back between pages in the Help buffer.
@item C-c C-c
Show all documentation about the symbol at point
(@code{help-follow-symbol}).
@item C-c C-f
@itemx r
-Go forward to the next help topic (@code{help-go-forward}).
+Go forward in history of help commands (@code{help-go-forward}).
@item C-c C-b
@itemx l
-Go back to the previous help topic (@code{help-go-back}).
+Go back in history of help commands (@code{help-go-back}).
@item s
View the source of the current help topic (if any)
(@code{help-view-source}).
@@ -479,6 +501,30 @@ C-b} or @kbd{l} (@code{help-go-back}). While retracing your steps,
you can go forward by using @kbd{C-c C-f} or @kbd{r}
(@code{help-go-forward}).
+@kindex TAB @r{(Help mode)}
+@findex forward-button
+@kindex S-TAB @r{(Help mode)}
+@findex backward-button
+ To move between hyperlinks in a help buffer, use @key{TAB}
+(@code{forward-button}) to move forward to the next hyperlink and
+@kbd{S-@key{TAB}} (@code{backward-button}) to move back to the
+previous hyperlink. These commands act cyclically; for instance,
+typing @key{TAB} at the last hyperlink moves back to the first
+hyperlink.
+
+@kindex n @r{(Help mode)}
+@kindex p @r{(Help mode)}
+@findex help-goto-next-page
+@findex help-goto-previous-page
+ Help buffers produced by some Help commands (like @kbd{C-h b}, which
+shows a long list of key bindings) are divided into pages by the
+@samp{^L} character. In such buffers, the @kbd{n}
+(@code{help-goto-next-page}) command will take you to the next start
+of page, and the @kbd{p} (@code{help-goto-previous-page}) command will
+take you to the previous start of page. This way you can quickly
+navigate between the different kinds of documentation in a help
+buffer.
+
@cindex URL, viewing in help
@cindex help, viewing web pages
@cindex viewing web pages in help
@@ -488,16 +534,6 @@ code definitions, and URLs (web pages). The first two are opened in
Emacs, and the third using a web browser via the @code{browse-url}
command (@pxref{Browse-URL}).
-@kindex TAB @r{(Help mode)}
-@findex forward-button
-@kindex S-TAB @r{(Help mode)}
-@findex backward-button
- In a help buffer, @key{TAB} (@code{forward-button}) moves point
-forward to the next hyperlink, while @kbd{S-@key{TAB}}
-(@code{backward-button}) moves point back to the previous hyperlink.
-These commands act cyclically; for instance, typing @key{TAB} at the
-last hyperlink moves back to the first hyperlink.
-
To view all documentation about any symbol in the text, move point
to the symbol and type @kbd{C-c C-c} (@code{help-follow-symbol}).
This shows the documentation for all the meanings of the symbol---as a
@@ -629,14 +665,14 @@ Emacs Lisp Reference Manual}).
@findex describe-prefix-bindings
You can get a list of subcommands for a particular prefix key by
-typing @kbd{C-h}, @kbd{?}, or @key{f1}
+typing @kbd{C-h}, @kbd{?}, or @key{F1}
(@code{describe-prefix-bindings}) after the prefix key. (There are a
few prefix keys for which not all of these keys work---those that
provide their own bindings for that key. One of these prefix keys
is @key{ESC}, because @kbd{@key{ESC} C-h} and @kbd{@key{ESC} ?} are
actually @kbd{C-M-h} (@code{mark-defun}) and @kbd{M-?}
(@code{xref-find-references}), respectively. However,
-@w{@kbd{@key{ESC} @key{f1}}} works fine.)
+@w{@kbd{@key{ESC} @key{F1}}} works fine.)
@findex describe-keymap
Finally, @kbd{M-x describe-keymap} prompts for the name of a keymap,
diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi
index 6e4fd77e8b9..375ac970d78 100644
--- a/doc/emacs/killing.texi
+++ b/doc/emacs/killing.texi
@@ -353,7 +353,7 @@ other ways to move text around.)
@vindex kill-ring-max
The maximum number of entries in the kill ring is controlled by the
-variable @code{kill-ring-max}. The default is 60. If you make a new
+variable @code{kill-ring-max}. The default is 120. If you make a new
kill when this limit has been reached, Emacs makes room by deleting
the oldest entry in the kill ring.
@@ -562,6 +562,14 @@ new yank to the clipboard.
To prevent kill and yank commands from accessing the clipboard,
change the variable @code{select-enable-clipboard} to @code{nil}.
+@findex yank-media
+ Programs can put other things than plain text on the clipboard. For
+instance, a web browser will usually let you choose ``Copy Image'' on
+images, and this image will be put on the clipboard. On capable
+platforms, Emacs can yank these objects with the @code{yank-media}
+command---but only in modes that have support for it (@pxref{Yanking
+Media,,, elisp, The Emacs Lisp Reference Manual}).
+
@cindex clipboard manager
@vindex x-select-enable-clipboard-manager
Many X desktop environments support a feature called the
diff --git a/doc/emacs/kmacro.texi b/doc/emacs/kmacro.texi
index e713c6ef8c0..e0533f049ea 100644
--- a/doc/emacs/kmacro.texi
+++ b/doc/emacs/kmacro.texi
@@ -102,7 +102,7 @@ are in the process of defining one, or calls the last macro
otherwise.) You can also supply @key{F4} with a numeric prefix
argument @samp{n}, which means to invoke the macro @samp{n} times. An
argument of zero repeats the macro indefinitely, until it gets an
-error or you type @kbd{C-g} (or, on MS-DOS, @kbd{C-@key{BREAK}}).
+error or you type @kbd{C-g} (or, on MS-DOS, @kbd{C-@key{Break}}).
The above example demonstrates a handy trick that you can employ
with keyboard macros: if you wish to repeat an operation at regularly
@@ -180,11 +180,11 @@ define it, so @kbd{C-u 4 C-x )} executes the macro immediately 3
additional times.
@findex kdb-macro-redisplay
-@kindex C-x C-k Q
+@kindex C-x C-k d
While executing a long-running keyboard macro, it can sometimes be
useful to trigger a redisplay (to show how far we've gotten). The
-@kbd{C-x C-k Q} can be used for this. As a not very useful example,
-@kbd{C-x ( M-f C-x C-k Q C-x )} will create a macro that will
+@kbd{C-x C-k d} command can be used for this. As a not very useful
+example, @kbd{C-x ( M-f C-x C-k d C-x )} will create a macro that will
redisplay once per iteration when saying @kbd{C-u 42 C-x e}.
@node Keyboard Macro Ring
@@ -439,7 +439,7 @@ name to execute the last keyboard macro, in its current form. (If you
later add to the definition of this macro, that does not alter the
name's definition as a macro.) The macro name is a Lisp symbol, and
defining it in this way makes it a valid command name for calling with
-@kbd{M-x} or for binding a key to with @code{global-set-key}
+@kbd{M-x} or for binding a key to with @code{keymap-global-set}
(@pxref{Keymaps}). If you specify a name that has a prior definition
other than a keyboard macro, an error message is shown and nothing is
changed.
diff --git a/doc/emacs/m-x.texi b/doc/emacs/m-x.texi
index d35a8351541..7b9b40388c2 100644
--- a/doc/emacs/m-x.texi
+++ b/doc/emacs/m-x.texi
@@ -45,10 +45,11 @@ from running the command by name.
@cindex obsolete command
When @kbd{M-x} completes on commands, it ignores the commands that
-are declared @dfn{obsolete}; for these, you will have to type their
-full name. (Obsolete commands are those for which newer, better
-alternatives exist, and which are slated for removal in some future
-Emacs release.)
+were declared @dfn{obsolete} in any previous major version of Emacs;
+for these, you will have to type their full name. Commands that were
+marked obsolete in the current version of Emacs are listed. (Obsolete
+commands are those for which newer, better alternatives exist, and
+which are slated for removal in some future Emacs release.)
@vindex read-extended-command-predicate
In addition, @kbd{M-x} completion can exclude commands that are not
diff --git a/doc/emacs/macos.texi b/doc/emacs/macos.texi
index cd1db1a7bab..99c67ed09e5 100644
--- a/doc/emacs/macos.texi
+++ b/doc/emacs/macos.texi
@@ -290,7 +290,7 @@ The default behavior is to save all file-visiting buffers.
@cindex using Nextstep services (macOS)
Emacs also allows users to make use of Nextstep services, via a set
of commands whose names begin with @samp{ns-service-} and end with the
-name of the service. Type @kbd{M-x ns-service-@key{TAB}} to
+name of the service. Type @kbd{M-x ns-service- @key{TAB}} to
see a list of these commands. These functions either operate on
marked text (replacing it with the result) or take a string argument
and return the result as a string. You can also use the Lisp function
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi
index 3205e6dbdf7..ebd72fa2a00 100644
--- a/doc/emacs/maintaining.texi
+++ b/doc/emacs/maintaining.texi
@@ -493,7 +493,7 @@ action on the current VC fileset: either registering it with a version
control system, or committing it, or unlocking it, or merging changes
into it. The precise actions are described in detail in the following
subsections. You can use @kbd{C-x v v} either in a file-visiting
-buffer or in a VC Directory buffer.
+buffer, in a Dired buffer, or in a VC Directory buffer.
Note that VC filesets are distinct from the named filesets used
for viewing and visiting files in functional groups
@@ -945,7 +945,7 @@ the author's description of the changes in the revision on the current
line.
@item w
-Annotate the working revision--the one you are editing. If you used
+Annotate the working revision---the one you are editing. If you used
@kbd{p} and @kbd{n} to browse to other revisions, use this key to
return to your working revision.
@@ -1136,13 +1136,17 @@ Revert the work file(s) in the current VC fileset to the last revision
@findex vc-revert
@vindex vc-revert-show-diff
If you want to discard all the changes you have made to the current
-VC fileset, type @kbd{C-x v u} (@code{vc-revert}). This shows
-you a diff between the work file(s) and the revision from which you
-started editing, and asks for confirmation for discarding the changes.
-If you agree, the fileset is reverted. If you don't want @kbd{C-x v
-u} to show a diff, set the variable @code{vc-revert-show-diff} to
-@code{nil} (you can still view the diff directly with @kbd{C-x v =};
-@pxref{Old Revisions}).
+VC fileset, type @kbd{C-x v u} (@code{vc-revert}). This will ask you
+for confirmation before discarding the changes. If you agree, the
+fileset is reverted.
+
+ If @code{vc-revert-show-diff} is non-@code{nil}, this command will
+show you a diff between the work file(s) and the revision from which
+you started editing. Afterwards, the diff buffer will either be
+killed (if this variable is @code{kill}), or the buffer will be buried
+(any other non-@code{nil} value). If you don't want @kbd{C-x v u} to
+show a diff, set this variable to @code{nil} (you can still view the
+diff directly with @kbd{C-x v =}; @pxref{Old Revisions}).
On locking-based version control systems, @kbd{C-x v u} leaves files
unlocked; you must lock again to resume editing. You can also use
@@ -1731,7 +1735,8 @@ the full file name of the file to visit, you can type only the file's
base name (i.e., omit the leading directories). In addition, the
completion candidates considered by the command include only the files
belonging to the current project, and nothing else. If there's a file
-name at point, this command offers that file as the default to visit.
+name at point, this command offers that file as the first element of
+the ``future history''.
@findex project-find-regexp
The command @kbd{C-x p g} (@code{project-find-regexp}) is similar to
@@ -1743,10 +1748,12 @@ commands (@pxref{Xref Commands}). When invoked with a prefix
argument, this command additionally prompts for the base directory
from which to start the search; this allows, for example, to limit the
search only to project files under a certain subdirectory of the
-project root.
+project root. The way this command displays the matches is affected
+by the value of @code{xref-auto-jump-to-first-xref} (@pxref{Identifier
+Search}).
@findex project-search
- @kbd{M-x project-search} is an interactive variant of
+ @kbd{M-x project-search} is a sequential variant of
@code{project-find-regexp}. It prompts for a regular expression to
search in the current project's files, but instead of finding all the
matches and displaying them, it stops when it finds a match and visits
@@ -1762,8 +1769,13 @@ Replace}), and continues to the next match after you respond. If your
response causes Emacs to exit the query-replace loop, you can later
continue with @w{@kbd{M-x fileloop-continue @key{RET}}}.
+@findex project-find-dir
+ The command @kbd{C-x p d} (@code{project-find-dir}) prompts you to
+choose a directory inside the current project, with completion.
+And opens a Dired buffer (@pxref{Dired}) listing the files in it.
+
@findex project-dired
- The command @kbd{C-x p d} (@code{project-dired}) opens a Dired
+ The command @kbd{C-x p D} (@code{project-dired}) opens a Dired
buffer (@pxref{Dired}) listing the files in the current project's root
directory.
@@ -1854,14 +1866,14 @@ records the list of known projects. It defaults to the file
@subsection Managing the Project List File
@table @kbd
-@item M-x project-remove-known-project
+@item M-x project-forget-project
Remove a known project from the @code{project-list-file}.
@end table
-@findex project-remove-known-project
+@findex project-forget-project
Normally Emacs automatically adds and removes projects to and from the
@code{project-list-file}, but sometimes you may want to manually edit
-the available projects. @kbd{M-x project-remove-known-project}
+the available projects. @kbd{M-x project-forget-project}
prompts you to choose one of the available projects, and then removes
it from the file.
@@ -2127,7 +2139,10 @@ Find definition of identifier, and display it in a new frame
Find definition of identifier at mouse click.
@item M-,
Go back to where you previously invoked @kbd{M-.} and friends
-(@code{xref-pop-marker-stack}).
+(@code{xref-go-back}).
+@item C-M-,
+Go forward to where you previously invoked @kbd{M-,}
+(@code{xref-go-forward}).
@item M-x xref-etags-mode
Switch @code{xref} to use the @code{etags} backend.
@end table
@@ -2135,24 +2150,15 @@ Switch @code{xref} to use the @code{etags} backend.
@kindex M-.
@findex xref-find-definitions
@vindex xref-prompt-for-identifier
- @kbd{M-.}@: (@code{xref-find-definitions}) shows the definitions of
+ @kbd{M-.}@: (@code{xref-find-definitions}) shows the definition of
the identifier at point. With a prefix argument, or if there's no
identifier at point, it prompts for the identifier. (If you want it
to always prompt, customize @code{xref-prompt-for-identifier} to
@code{t}.)
-If the specified identifier has only one definition, the command jumps
-to it. If the identifier has more than one possible definition (e.g.,
-in an object-oriented language, or if there's a function and a
-variable by the same name), the command shows the candidate
-definitions in the @file{*xref*} buffer, together with the files in
-which these definitions are found. Selecting one of these candidates
-by typing @kbd{@key{RET}} or clicking @kbd{mouse-2} will pop a buffer
-showing the corresponding definition.
-
- When entering the identifier argument to @kbd{M-.}, the usual
-minibuffer completion commands can be used (@pxref{Completion}), with
-the known identifier names as completion candidates.
+ When entering the identifier argument to @kbd{M-.}, you can use the
+usual minibuffer completion commands (@pxref{Completion}), with the
+known identifier names being the completion candidates.
@kindex C-x 4 .
@findex xref-find-definitions-other-window
@@ -2170,29 +2176,48 @@ former is @w{@kbd{C-x 4 .}}
or around the place of a mouse event. This command is intended to be
bound to a mouse event, such as @kbd{C-M-mouse-1}, for example.
-@findex xref-find-apropos
@kindex C-M-.
- The command @kbd{C-M-.} (@code{xref-find-apropos}) finds the
-definitions of one or more identifiers that match a specified regular
-expression. It is just like @kbd{M-.} except that it does regexp
+@findex xref-find-apropos
+@vindex tags-apropos-additional-actions
+ The command @kbd{C-M-.}@: (@code{xref-find-apropos}) is like
+@code{apropos} for tags (@pxref{Apropos}). It displays a list of
+identifiers in the selected tags table whose names match the specified
+@var{regexp}. This is just like @kbd{M-.}, except that it does regexp
matching of identifiers instead of matching symbol names as fixed
-strings.
-
- When any of the above commands finds more than one definition, it
-presents the @file{*xref*} buffer showing the definition candidates.
-In that buffer, you have several specialized commands, described in
-@ref{Xref Commands}.
+strings. By default, the command pops up the @file{*xref*} buffer,
+like @kbd{M-.}, but you can display additional output by customizing
+the variable @code{tags-apropos-additional-actions}; see its
+documentation for details.
+
+@vindex xref-auto-jump-to-first-definition
+ If any of the above commands finds more than one matching
+definition, it by default pops up the @file{*xref*} buffer showing the
+matching candidates. (@kbd{C-M-.}@: @emph{always} pops up the
+@file{*xref*} buffer if it finds at least one match.) The candidates
+are normally shown in that buffer as the name of a file and the
+matching identifier(s) in that file. In that buffer, you can select
+any of the candidates for display, and you have several additional
+commands, described in @ref{Xref Commands}. However, if the value of
+the variable @code{xref-auto-jump-to-first-definition} is @code{move},
+the first of these candidates is automatically selected in the
+@file{*xref*} buffer, and if it's @code{t} or @code{show}, the first
+candidate is automatically shown in its own window; @code{t} also
+selects the window showing the first candidate. The default value is
+@code{nil}, which just shows the candidates in the @file{*xref*}
+buffer, but doesn't select any of them.
@kindex M-,
-@findex xref-pop-marker-stack
-@vindex xref-marker-ring-length
- To go back to places @emph{from where} you found the definition,
-use @kbd{M-,} (@code{xref-pop-marker-stack}). It jumps back to the
+@findex xref-go-back
+ To go back to places @emph{from where} you've displayed the definition,
+use @kbd{M-,} (@code{xref-go-back}). It jumps back to the
point of the last invocation of @kbd{M-.}. Thus you can find and
examine the definition of something with @kbd{M-.} and then return to
-where you were with @kbd{M-,}. @kbd{M-,} allows you to retrace your
-steps to a depth determined by the variable
-@code{xref-marker-ring-length}, which defaults to 16.
+where you were with @kbd{M-,}.
+
+@kindex C-M-,
+@findex xref-go-forward
+ Go forward to a place from where you previously went back using @kbd{M-,}.
+This is useful if you find that you went back too far.
@findex xref-etags-mode
Some major modes install @code{xref} support facilities that might
@@ -2218,10 +2243,16 @@ the special XREF mode:
@table @kbd
@item @key{RET}
-@itemx mouse-2
+@itemx mouse-1
Display the reference on the current line (@code{xref-goto-xref}).
With prefix argument, also bury the @file{*xref*} buffer.
+@item mouse-2
+@findex xref-select-and-show-xref
+The same as @code{mouse-1}, but make the window displaying the
+@file{*xref*} buffer the selected window
+(@code{xref-select-and-show-xref}).
+
@item n
@itemx .
@findex xref-next-line
@@ -2257,10 +2288,15 @@ the match with @var{replacement}. @xref{Identifier Search}.
@item g
@findex xref-revert-buffer
Refresh the contents of the @file{*xref*} buffer
-(@code{xref-revert-buffer}.
+(@code{xref-revert-buffer}).
+
+@item M-,
+@findex xref-quit-and-pop-marker-stack
+Quit the window showing the @file{*xref*} buffer, and then jump to the
+previous Xref stack location (@code{xref-quit-and-pop-marker-stack}).
-@findex xref-quit
@item q
+@findex xref-quit
Quit the window showing the @file{*xref*} buffer (@code{xref-quit}).
@end table
@@ -2311,6 +2347,16 @@ identifier, showing the file name and the line where the identifier is
referenced. The XREF mode commands are available in this buffer, see
@ref{Xref Commands}.
+@vindex xref-auto-jump-to-first-xref
+ If the value of the variable @code{xref-auto-jump-to-first-xref} is
+@code{t}, @code{xref-find-references} automatically jumps to the first
+result and selects the window where it is displayed. If the value is
+@code{show}, the first result is shown, but the window showing the
+@file{*xref*} buffer is left selected. If the value is @code{move},
+the first result is selected in the @file{*xref*} buffer, but is not
+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 regexp to match identifier
names and a replacement string, just like ordinary @kbd{M-x
@@ -2381,13 +2427,14 @@ Searching}.
Perform completion on the text around point, possibly using the
selected tags table if one is loaded (@code{completion-at-point}).
-@item M-x xref-find-apropos @key{RET} @var{regexp} @key{RET}
-Display a list of all known identifiers matching @var{regexp}.
-
@item M-x list-tags @key{RET} @var{file} @key{RET}
Display a list of the identifiers defined in the program file
@var{file}.
+@item C-M-. @var{regexp} @key{RET}
+Display a list of all identifiers matching @var{regexp}
+(@code{xref-find-apropos}). @xref{Looking Up Identifiers}.
+
@item M-x tags-next-file
Visit files recorded in the selected tags table.
@end table
@@ -2409,26 +2456,6 @@ for the project to be available. @xref{Tags Tables}. If used
interactively, the default tag is file name of the current buffer if
used interactively.
-@c Sadly, the new-and-improved Xref feature doesn't provide anything
-@c close to the described below features of the now-obsoleted
-@c tags-apropos. I'm leaving this here to encourage enhancements to
-@c xref.el.
-@ignore
-@findex tags-apropos
-@vindex tags-apropos-verbose
-@vindex tags-tag-face
-@vindex tags-apropos-additional-actions
- @kbd{M-x tags-apropos} is like @code{apropos} for tags
-(@pxref{Apropos}). It displays a list of tags in the selected tags
-table whose entries match @var{regexp}. If the variable
-@code{tags-apropos-verbose} is non-@code{nil}, it displays the names
-of the tags files together with the tag names. You can customize the
-appearance of the output by setting the variable @code{tags-tag-face}
-to a face. You can display additional output by customizing the
-variable @code{tags-apropos-additional-actions}; see its documentation
-for details.
-@end ignore
-
@findex tags-next-file
@kbd{M-x tags-next-file} visits files covered by the selected tags table.
The first time it is called, it visits the first file covered by the
@@ -3097,19 +3124,23 @@ these local variables section would do.
@smallexample
;; Local Variables:
-;; bug-reference-bug-regexp: "\\([Bb]ug[#-]\\)\\([0-9]+\\)"
+;; bug-reference-bug-regexp: "\\([Bb]ug[#-]\\([0-9]+\\)\\)"
;; bug-reference-url-format: "https://project.org/issues/%s"
;; End:
@end smallexample
+The string captured by the first regexp group defines the bounds of
+the overlay bug-reference creates, i.e., the part which is highlighted
+and made clickable.
+
The string captured by the second regexp group in
@code{bug-reference-bug-regexp} is used to replace the @code{%s}
template in the @code{bug-reference-url-format}.
Note that @code{bug-reference-url-format} may also be a function in
-order to cater for more complex scenarios, e.g., when the part before
-the actual bug number has to be used to distinguish between issues and
-merge requests where each of them has a different URL.
+order to cater for more complex scenarios, e.g., when different parts
+of the bug reference have to be used to distinguish between issues and
+merge requests resulting in different URLs.
@heading Automatic Setup
@@ -3124,20 +3155,22 @@ variables itself by calling the functions in
one is able to set the variables.
@vindex bug-reference-setup-from-vc-alist
+@vindex bug-reference-forge-alist
@vindex bug-reference-setup-from-mail-alist
@vindex bug-reference-setup-from-irc-alist
Right now, there are three types of setup functions.
@enumerate
@item
-Setup for version-controlled files configurable by the variable
-@code{bug-reference-setup-from-vc-alist}. The default is able to
+Setup for version-controlled files configurable by the variables
+@code{bug-reference-forge-alist}, and
+@code{bug-reference-setup-from-vc-alist}. The defaults are able to
setup GNU projects where @url{https://debbugs.gnu.org} is used as
issue tracker and issues are usually referenced as @code{bug#13} (but
-many different notations are considered, too), Sourcehut projects
-where issues are referenced using the notation @code{#17}, Codeberg
-and Github projects where both bugs and pull requests are referenced
-using the same notation, and GitLab projects where bugs are referenced
-with @code{#17}, too, but merge requests use the @code{!18} notation.
+many different notations are considered, too), and several kinds of
+modern software forges such as GitLab, Gitea, SourceHut, or GitHub.
+If you deploy a self-hosted instance of such a forge, the easiest way
+to tell bug-reference about it is through
+@code{bug-reference-forge-alist}.
@item
Setup for email guessing from mail folder/mbox names, and mail header
diff --git a/doc/emacs/mark.texi b/doc/emacs/mark.texi
index 20cb8ee2c65..2461cb0f6af 100644
--- a/doc/emacs/mark.texi
+++ b/doc/emacs/mark.texi
@@ -409,9 +409,14 @@ region by dragging the mouse, you can continue to extend the region
using shifted cursor motion commands. In either case, any unshifted
cursor motion command deactivates the mark.
+@vindex shift-select-mode
To turn off shift-selection, set @code{shift-select-mode} to
@code{nil}. Doing so does not disable setting the mark via mouse
-commands.
+commands. If you set @code{shift-select-mode} to the value
+@code{permanent}, cursor motion keys that were not shift-translated
+will not deactivate the mark, so, for example, the region set by prior
+commands can be extended by shift-selection, and unshifted cursor
+motion keys will extend the region set by shift-selection.
@node Disabled Transient Mark
@section Disabling Transient Mark Mode
diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi
index 6dcee3fa824..b0f6e424a7f 100644
--- a/doc/emacs/mini.texi
+++ b/doc/emacs/mini.texi
@@ -41,11 +41,14 @@ Alternatively, you can type @kbd{C-g} to exit the minibuffer by
canceling the command asking for the argument (@pxref{Quitting}).
@cindex default argument
+@vindex minibuffer-default-prompt-format
Sometimes, the prompt shows a @dfn{default argument}, inside
parentheses before the colon. This default will be used as the
argument if you just type @key{RET}. For example, commands that read
buffer names usually show a buffer name as the default; you can type
-@key{RET} to operate on that default buffer.
+@key{RET} to operate on that default buffer. You can customize how
+the default argument is shown with the user option
+@code{minibuffer-default-prompt-format}.
@cindex Minibuffer Electric Default mode
@cindex mode, Minibuffer Electric Default
diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi
index 528cfa94c66..1f2c852fac1 100644
--- a/doc/emacs/misc.texi
+++ b/doc/emacs/misc.texi
@@ -1113,6 +1113,19 @@ subshell:
@end example
@end table
+By default, Shell mode handles common @acronym{ANSI} escape codes (for
+instance, for changing the color of text). Emacs also optionally
+supports some extend escape codes, like some of the @acronym{OSC}
+(Operating System Codes) if you put the following in your init file:
+
+@lisp
+(add-hook 'comint-output-filter-functions 'comint-osc-process-output)
+@end lisp
+
+With this enabled, the output from, for instance, @code{ls
+--hyperlink} will be made into clickable buttons in the Shell mode
+buffer.
+
@cindex Comint mode
@cindex mode, Comint
Shell mode is a derivative of Comint mode, a general-purpose mode for
@@ -1484,14 +1497,20 @@ directory stack if they are not already on it
underlying shell, of course.
@vindex comint-terminfo-terminal
+@vindex system-uses-terminfo
@vindex TERM@r{, environment variable, in sub-shell}
Comint mode sets the @env{TERM} environment variable to a safe default
value, but this value disables some useful features. For example,
color is disabled in applications that use @env{TERM} to determine if
color is supported. Therefore, Emacs provides an option
-@code{comint-terminfo-terminal}, which you can set to a terminal that
-is present in your system's terminfo database, in order to take
-advantage of advanced features of that terminal.
+@code{comint-terminfo-terminal} to let you choose a terminal with more
+advanced features, as defined in your system's terminfo database.
+Emacs will use this option as the value for @env{TERM} so long as
+@code{system-uses-terminfo} is non-nil.
+
+Both @code{comint-terminfo-terminal} and @code{system-uses-terminfo}
+can be declared as connection-local variables to adjust these options
+to match what a remote system expects (@pxref{Connection Variables}).
@node Terminal emulator
@subsection Emacs Terminal Emulator
@@ -1684,6 +1703,11 @@ options. @xref{Initial Options}. When Emacs is started this way, it
calls @code{server-start} after initialization and does not open an
initial frame. It then waits for edit requests from clients.
+@item
+Run the command @code{emacsclient} with the @samp{--alternate-editor=""}
+command-line option. This starts an Emacs daemon only if no Emacs daemon
+is already running.
+
@cindex systemd unit file
@item
If your operating system uses @command{systemd} to manage startup,
@@ -1750,6 +1774,32 @@ you can give each daemon its own server name like this:
emacs --daemon=foo
@end example
+@findex server-stop-automatically
+ The Emacs server can optionally be stopped automatically when
+certain conditions are met. To do this, call the function
+@code{server-stop-automatically} in your init file (@pxref{Init
+File}), with one of the following arguments:
+
+@itemize
+@item
+With the argument @code{empty}, the server is stopped when it has no
+clients, no unsaved file-visiting buffers and no running processes
+anymore.
+
+@item
+With the argument @code{delete-frame}, when the last client frame is
+being closed, you are asked whether each unsaved file-visiting buffer
+must be saved and each unfinished process can be stopped, and if so,
+the server is stopped.
+
+@item
+With the argument @code{kill-terminal}, when the last client frame is
+being closed with @kbd{C-x C-c} (@code{save-buffers-kill-terminal}),
+you are asked whether each unsaved file-visiting buffer must be saved
+and each unfinished process can be stopped, and if so, the server is
+stopped.
+@end itemize
+
@findex server-eval-at
If you have defined a server by a unique server name, it is possible
to connect to the server from another Emacs instance and evaluate Lisp
@@ -1973,6 +2023,11 @@ the new frame displays the @file{*scratch*} buffer by default. You
can customize this behavior with the variable @code{initial-buffer-choice}
(@pxref{Entering Emacs}).
+@item -r
+@itemx --reuse-frame
+Create a new graphical client frame if none exists, otherwise use an
+existing Emacs frame.
+
@item -F @var{alist}
@itemx --frame-parameters=@var{alist}
Set the parameters for a newly-created graphical frame
@@ -2589,7 +2644,7 @@ invoked @code{hexl-mode}.
@noindent
Other Hexl commands let you insert strings (sequences) of binary
bytes, move by @code{short}s or @code{int}s, etc.; type @kbd{C-h a
-hexl-@key{RET}} for details.
+hexl- @key{TAB}} for details.
Hexl mode can also be used for editing text files. This could come
in handy if the text file includes unusual characters or uses unusual
@@ -2929,6 +2984,41 @@ one-key commands for scrolling the widget, changing its size, and
reloading it. Type @w{@kbd{C-h b}} in that buffer to see the key
bindings.
+@findex xwidget-webkit-edit-mode
+@cindex xwidget-webkit-edit-mode
+ By default, typing a self-inserting character inside an xwidget
+webkit buffer will do nothing, or trigger some special action. To
+make those characters and other common editing keys insert themselves
+when pressed, you can enable @code{xwidget-webkit-edit-mode}, which
+redefines them to be passed through to the WebKit xwidget.
+
+You can also enable @code{xwidget-webkit-edit-mode} by typing @kbd{e}
+inside the xwidget webkit buffer.
+
+@findex xwidget-webkit-isearch-mode
+@cindex searching in webkit buffers
+ @code{xwidget-webkit-isearch-mode} is a minor mode that behaves
+similarly to incremental search (@pxref{Incremental Search}), but
+operates on the contents of a WebKit widget instead of the current
+buffer. It is bound to @kbd{C-s} and @kbd{C-r} inside xwidget-webkit
+buffers. When it is invoked by @kbd{C-r}, the initial search will be
+performed in reverse direction.
+
+Typing any self-inserting character will cause the character to be
+inserted into the current search query. Typing @kbd{C-s} will cause
+the WebKit widget to display the next search result, while typing
+@kbd{C-r} will cause it to display the previous one.
+
+To leave incremental search, you can type @kbd{C-g}.
+
+@findex xwidget-webkit-browse-history
+@cindex history of webkit buffers
+ The command @code{xwidget-webkit-browse-history} displays a buffer
+containing a list of pages previously loaded by the current WebKit
+buffer, and lets you navigate to those pages by hitting @kbd{RET}.
+
+It is bound to @kbd{H}.
+
@node Browse-URL
@subsection Following URLs
@cindex World Wide Web
diff --git a/doc/emacs/msdos-xtra.texi b/doc/emacs/msdos-xtra.texi
index fce6ae46f81..114700f08d3 100644
--- a/doc/emacs/msdos-xtra.texi
+++ b/doc/emacs/msdos-xtra.texi
@@ -105,7 +105,7 @@ following line into your @file{_emacs} file:
@smallexample
;; @r{Make the @key{ENTER} key from the numeric keypad act as @kbd{C-j}.}
-(define-key function-key-map [kp-enter] [?\C-j])
+(keymap-set function-key-map "<kp-enter>" "C-j")
@end smallexample
@node MS-DOS Mouse
diff --git a/doc/emacs/msdos.texi b/doc/emacs/msdos.texi
index 33d389acd50..20eaa0bcb6f 100644
--- a/doc/emacs/msdos.texi
+++ b/doc/emacs/msdos.texi
@@ -543,7 +543,7 @@ keyboard input in Emacs.
conventional uses in MS-Windows programs conflict with traditional
Emacs key bindings. (These Emacs key bindings were established years
before Microsoft was founded.) Examples of conflicts include
-@kbd{C-c}, @kbd{C-x}, @kbd{C-z}, @kbd{C-a}, and @kbd{W-@key{SPC}}.
+@kbd{C-c}, @kbd{C-x}, @kbd{C-z}, and @kbd{C-a}.
You can redefine some of them with meanings more like the MS-Windows
meanings by enabling CUA Mode (@pxref{CUA Bindings}). Another
optional feature which will make Emacs behave like other Windows
@@ -1181,6 +1181,14 @@ The default is @code{t}, which fits well with the Windows default
click-to-focus policy.
@end ifnottex
+ On Windows 10 (version 1809 and higher) and Windows 11, Emacs title
+bars and scroll bars will follow the system's Light or Dark mode,
+similar to other programs such as Explorer and Command Prompt. To
+change the color mode, select @code{Personalization} from
+@w{@code{Windows Settings}}, then
+@w{@code{Colors->Choose your color}} (or @w{@code{Choose your default
+app mode}}); then restart Emacs.
+
@ifnottex
@include msdos-xtra.texi
@end ifnottex
diff --git a/doc/emacs/mule.texi b/doc/emacs/mule.texi
index 22b3677b5b0..121d6967309 100644
--- a/doc/emacs/mule.texi
+++ b/doc/emacs/mule.texi
@@ -473,6 +473,10 @@ First, letters are mapped into symbols for particular sounds or tone
marks; then, sequences of these that make up a whole syllable are
mapped into one syllable sign.
+@kindex C-f@r{, when using input methods}
+@kindex C-b@r{, when using input methods}
+@kindex C-n@r{, when using input methods}
+@kindex C-p@r{, when using input methods}
Chinese and Japanese require more complex methods. In Chinese input
methods, first you enter the phonetic spelling of a Chinese word (in
input method @code{chinese-py}, among others), or a sequence of
@@ -498,6 +502,7 @@ alternatives in the row are also numbered; the number appears before
the alternative. Typing a number selects the associated alternative
of the current row and uses it as input.
+@kindex TAB@r{, when using Chinese input methods}
@key{TAB} in these Chinese input methods displays a buffer showing
all the possible characters at once; then clicking @kbd{mouse-2} on
one of them selects that alternative. The keys @kbd{C-f}, @kbd{C-b},
@@ -571,11 +576,37 @@ modes that make buffer text or parts of it read-only, such as
@code{read-only-mode} and @code{image-mode}, even when an input method
is active.
+@kindex C-x 8 @key{RET}
+@cindex insert character by name or code-point
Another facility for typing characters not on your keyboard is by
using @kbd{C-x 8 @key{RET}} (@code{insert-char}) to insert a single
character based on its Unicode name or code-point; see @ref{Inserting
Text}.
+@cindex emoji input
+@cindex inserting Emoji
+@kindex C-x 8 e
+@findex emoji-insert
+@findex emoji-list
+@findex emoji-search
+ There are specialized commands for inserting Emoji, and these can be
+found on the @kbd{C-x 8 e} keymap. @kbd{C-x 8 e e}
+(@code{emoji-insert}) will let you navigate through different Emoji
+categories and then choose one. @kbd{C-x 8 e l} (@code{emoji-list})
+will pop up a new buffer and list all the Emoji; clicking (or using
+@kbd{RET}) on an emoji character will insert it in the current buffer.
+Finally, @kbd{C-x 8 e s} (@code{emoji-search}) will allow you to
+search for Emoji based on their names.
+
+@findex emoji-describe
+ @code{describe-char} displays a lot of information about the
+character/glyphs under point (including emojis). It's sometimes
+useful to get a quick description of the name, and you can use the
+@kbd{C-x 8 e d} (@code{emoji-describe}) command to do that. It's
+meant primarily to help distinguish between different Emoji
+variants (which can look very similar), but it will also tell you
+the names of non-Emoji characters.
+
@node Select Input Method
@section Selecting an Input Method
@@ -1330,6 +1361,12 @@ You can do this by putting
@noindent
in your init file.
+@findex w32-set-console-codepage
+ Setting @code{keyboard-coding-system} has no effect on MS-Windows,
+except on old Windows 9X systems, in which case the encoding must
+match the current codepage of the MS-Windows console, which can be
+changed by calling @code{w32-set-console-codepage}.
+
There is a similarity between using a coding system translation for
keyboard input, and using an input method: both define sequences of
keyboard input that translate into single characters. However, input
@@ -1955,3 +1992,16 @@ or right of the current screen position, moving to the next or
previous screen line as appropriate. Note that this might potentially
move point many buffer positions away, depending on the surrounding
bidirectional context.
+
+@cindex bidi formatting control characters
+ Bidirectional text sometimes uses special formatting characters to
+affect the reordering of text for display. The @sc{lrm} and @sc{rlm}
+characters, mentioned above, are two such characters, but there are
+more of them. They are by default displayed as thin space glyphs on
+GUI frames, and as simple spaces on text-mode frames. If you want to
+be aware of these special control characters, so that their effect on
+display does not come as a surprise, you can turn on the
+@code{glyphless-display-mode} (@pxref{Text Display}). This minor mode
+will cause these formatting characters to be displayed as acronyms
+inside a small box, so that they stand out on display, and make their
+effect easier to understand.
diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi
index d419a4e24b5..570afd5be2b 100644
--- a/doc/emacs/package.texi
+++ b/doc/emacs/package.texi
@@ -129,7 +129,7 @@ entails.
@item w
@kindex w @r{(Package Menu)}
@findex package-browse-url
-Open the home page of the package on the current line in a browser
+Open the package website on the current line in a browser
(@code{package-browse-url}). @code{browse-url} is used to open the
browser.
diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index fe3ee57ac0a..85ed65a4954 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -275,8 +275,10 @@ a non-@code{nil} value. There is no need to rescan because of small
changes in the text.
@vindex imenu-auto-rescan-maxout
+@vindex imenu-max-index-time
@code{imenu-auto-rescan} will be disabled in buffers that are larger
-than @code{imenu-auto-rescan-maxout} in bytes.
+than @code{imenu-auto-rescan-maxout} in bytes, and scanning is
+stopped if it takes more than @code{imenu-max-index-time} seconds.
@vindex imenu-sort-function
You can customize the way the menus are sorted by setting the
@@ -469,6 +471,23 @@ the function name. This is normally done for macro definitions, using
the @code{declare} construct. @xref{Defining Macros,,, elisp, The
Emacs Lisp Reference Manual}.
+ In Emacs Lisp, lists are usually indented as if they are
+function-like forms:
+
+@lisp
+(setq foo '(bar zot
+ gazonk))
+@end lisp
+
+ However, if you add a space after the opening parenthesis, this tells
+Emacs that it's a data list instead of a piece of code, and Emacs will
+then indent it like this:
+
+@lisp
+(setq foo '( bar zot
+ gazonk))
+@end lisp
+
@node C Indent
@subsection Commands for C Indentation
@@ -809,41 +828,55 @@ displayed. The default is 102400.
@cindex Show Paren mode
@cindex highlighting matching parentheses
@findex show-paren-mode
- Show Paren mode, a global minor mode, provides a more powerful kind
+@findex show-paren-local-mode
+ Show Paren mode is a minor mode that provides a more powerful kind
of automatic matching. Whenever point is before an opening delimiter
or after a closing delimiter, the delimiter, its matching delimiter,
and optionally the text between them are highlighted. To toggle Show
-Paren mode, type @kbd{M-x show-paren-mode}. To customize it, type
-@kbd{M-x customize-group @key{RET} paren-showing}. The customizable
-options which control the operation of this mode include:
+Paren mode globally, type @kbd{M-x show-paren-mode}. To toggle it
+only in the current buffer, type @kbd{M-x show-paren-local-mode}. To
+customize it, type @w{@kbd{M-x customize-group @key{RET} paren-showing}}.
+The customizable options which control the operation of this mode
+include:
@itemize @bullet
@item
@vindex show-paren-highlight-openparen
@code{show-paren-highlight-openparen} controls whether to highlight
-an open paren when point stands just before it, and hence its position
+an open paren when point is just before it, and hence its position
is marked by the cursor anyway. The default is non-@code{nil} (yes).
@item
@vindex show-paren-style
@code{show-paren-style} controls whether just the two parens, or also
-the space between them get highlighted. The valid options here are
+the text between them get highlighted. The valid options here are
@code{parenthesis} (show the matching paren), @code{expression}
(highlight the entire expression enclosed by the parens), and
-@code{mixed} (highlight the matching paren if it is visible, the
-expression otherwise).
+@code{mixed} (highlight the matching paren if it is visible in the
+window, the expression otherwise).
@item
@vindex show-paren-when-point-inside-paren
@code{show-paren-when-point-inside-paren}, when non-@code{nil}, causes
-highlighting also when point is on the inside of a parenthesis.
+highlighting also when point is inside of the parentheses. The
+default is @code{nil}.
@item
@vindex show-paren-when-point-in-periphery
@code{show-paren-when-point-in-periphery}, when non-@code{nil}, causes
-highlighting also when point is in whitespace at the beginning or end
-of a line, and there is a paren at, respectively, the first or last,
-or the last, non-whitespace position on the line.
+highlighting also when point is in whitespace at the beginning of a
+line and there is a paren at the first or last non-whitespace position
+on the line, or when point is at the end of a line and there is a
+paren at the last non-whitespace position on the line.
+
+@item
+@vindex show-paren-context-when-offscreen
+@code{show-paren-context-when-offscreen}, when non-@code{nil}, shows
+some context in the echo area when point is in a closing delimiter and
+the opening delimiter is offscreen. The context is usually the line
+that contains the opening delimiter, except if the opening delimiter
+is on its own line, in which case the context includes the previous
+nonblank line.
@end itemize
@cindex Electric Pair mode
@@ -1098,13 +1131,13 @@ match the last comment before point in the buffer, and then does a
expression that is the value of the variable @code{comment-start-skip}.
Make sure this regexp does not match the null string. It may match more
than the comment starting delimiter in the strictest sense of the word;
-for example, in C mode the value of the variable is
+for example, in C mode the value of the variable could be
@c This stops M-q from breaking the line inside that @code.
-@code{@w{"\\(//+\\|/\\*+\\)\\s *"}}, which matches extra stars and
-spaces after the @samp{/*} itself, and accepts C++ style comments
-also. (Note that @samp{\\} is needed in Lisp syntax to include a
-@samp{\} in the string, which is needed to deny the first star its
-special meaning in regexp syntax. @xref{Regexp Backslash}.)
+@code{@w{"/\\*+[ \t]*\\|//+[ \t]*"}}, which matches extra stars and
+spaces after the @samp{/*} itself, and accepts C++ style (@samp{//})
+comments also. (Note that @samp{\\} is needed in Lisp syntax to
+include a @samp{\} in the string, which is needed to deny the first
+star its special meaning in regexp syntax. @xref{Regexp Backslash}.)
@vindex comment-start
@vindex comment-end
@@ -1794,7 +1827,7 @@ sure the keymap is loaded before we try to change it.
@example
(defun my-bind-clb ()
- (define-key c-mode-base-map "\C-m"
+ (keymap-set c-mode-base-map "RET"
'c-context-line-break))
(add-hook 'c-initialization-hook 'my-bind-clb)
@end example
diff --git a/doc/emacs/regs.texi b/doc/emacs/regs.texi
index 59fa0ff0a1c..df1eec04c00 100644
--- a/doc/emacs/regs.texi
+++ b/doc/emacs/regs.texi
@@ -47,14 +47,14 @@ are similar in spirit to registers, so they are also documented in
this chapter.
@menu
-* Position Registers:: Saving positions in registers.
-* Text Registers:: Saving text in registers.
-* Rectangle Registers:: Saving rectangles in registers.
-* Configuration Registers:: Saving window configurations in registers.
-* Number Registers:: Numbers in registers.
-* File Registers:: File names in registers.
-* Keyboard Macro Registers:: Keyboard macros in registers.
-* Bookmarks:: Bookmarks are like registers, but persistent.
+* Position Registers:: Saving positions in registers.
+* Text Registers:: Saving text in registers.
+* Rectangle Registers:: Saving rectangles in registers.
+* Configuration Registers:: Saving window configurations in registers.
+* Number Registers:: Numbers in registers.
+* File and Buffer Registers:: File and buffer names in registers.
+* Keyboard Macro Registers:: Keyboard macros in registers.
+* Bookmarks:: Bookmarks are like registers, but persistent.
@end menu
@node Position Registers
@@ -238,9 +238,10 @@ register contents into the buffer. @kbd{C-x r +} with no numeric
argument increments the register value by 1; @kbd{C-x r n} with no
numeric argument stores zero in the register.
-@node File Registers
-@section Keeping File Names in Registers
+@node File and Buffer Registers
+@section Keeping File and Buffer Names in Registers
@cindex saving file name in a register
+@cindex saving buffer name in a register
If you visit certain file names frequently, you can visit them more
conveniently if you put their names in registers. Here's the Lisp code
@@ -265,6 +266,15 @@ puts the file name shown in register @samp{z}.
@var{r}}. (This is the same command used to jump to a position or
restore a frame configuration.)
+ Similarly, if there's certain buffers you visit frequently, you
+can put their names in registers. For instance, if you visit the
+@samp{*Messages*} buffer often, you can use the following snippet to
+put that buffer into the @samp{m} register:
+
+@smallexample
+(set-register ?m '(buffer . "*Messages*"))
+@end smallexample
+
@node Keyboard Macro Registers
@section Keyboard Macro Registers
@cindex saving keyboard macro in a register
diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index a1760ad66ff..fbbb1f6e682 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -222,6 +222,15 @@ going past the original starting point of the search, it changes to
@samp{Overwrapped}, which means that you are revisiting matches that
you have already seen.
+@vindex isearch-wrap-pause
+ You can control what happens when there are no more matches by
+customizing the @code{isearch-wrap-pause} user option. If it is
+@code{t} (the default), signal an error. (Repeating the search will
+wrap around.) If @code{no}, issue a @code{ding} and wrap immediately
+after reaching the last match. If @code{no-ding}, wrap immediately,
+but don't @code{ding}. Finally, if @code{nil}, never wrap, but just
+stop at the last match.
+
@cindex search ring
@findex isearch-ring-advance
@findex isearch-ring-retreat
@@ -328,6 +337,16 @@ value of the variable @code{search-upper-case} (@pxref{Lax Search,
search-upper-case}) is other than @code{not-yanks}, that disables this
down-casing.
+@kindex M-s M-.
+@findex isearch-forward-thing-at-point
+ To begin a new incremental search with the text near point yanked
+into the initial search string, type @kbd{M-s M-.} that runs the
+command @code{isearch-forward-thing-at-point}. If the region was
+active, then it yanks the text from the region into the search string.
+Otherwise, it tries to yank a URL, a symbol or an expression found
+near point. What to yank is defined by the user option
+@code{isearch-forward-thing-at-point}.
+
@node Error in Isearch
@subsection Errors in Incremental Search
@@ -593,6 +612,19 @@ or the selected window and frame. The command must not itself attempt
an incremental search. This feature is disabled if
@code{isearch-allow-scroll} is @code{nil} (which it is by default).
+@vindex isearch-allow-motion
+@vindex isearch-motion-changes-direction
+ Likewise, if you change the variable @code{isearch-allow-motion}
+to a non-@code{nil} value, this enables the use of the keyboard motion
+commands @kbd{M-<}, @kbd{M->}, @kbd{C-v} and @kbd{M-v}, to move
+respectively to the first occurrence of the current search string in
+the buffer, the last one, the first one after the current window,
+and the last one before the current window. The search direction
+does not change when these motion commands are used, unless you change
+the variable @code{isearch-motion-changes-direction} to a non-@code{nil}
+value, in which case the search direction is forward after @kbd{M-<} and
+@kbd{C-v}, and backward after @kbd{M->} and @kbd{M-v}.
+
@item Motion Commands
@cindex motion commands, during incremental search
When @code{isearch-yank-on-move} is customized to @code{shift},
@@ -1309,10 +1341,9 @@ matches @w{@samp{foo bar}}, @w{@samp{foo@ @ bar}},
precisely, Emacs matches each sequence of space characters in the
search string to a regular expression specified by the variable
@code{search-whitespace-regexp}. For example, to make spaces match
-sequences of newlines as well as spaces, set it to
-@samp{"[[:space:]\n]+"}. The default value of this variable depends
-on the buffer's major mode; most major modes classify spaces, tabs,
-and formfeed characters as whitespace.
+sequences of newlines as well as spaces, set it to the regular expression
+@samp{[[:space:]\n]+}. The default value of this variable considers
+any sequence of spaces and tab characters as whitespace.
If you want whitespace characters to match exactly, you can turn lax
space matching off by typing @kbd{M-s @key{SPC}}
diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi
index dc8ca903b72..ead0f699bb3 100644
--- a/doc/emacs/text.texi
+++ b/doc/emacs/text.texi
@@ -996,11 +996,18 @@ specific file (@pxref{File Variables}).
major mode's special commands. (The variable
@code{outline-minor-mode-prefix} controls the prefix used.)
+@vindex outline-minor-mode-use-buttons
+ If @code{outline-minor-mode-use-buttons} is non-@code{nil}, Outline
+minor mode will use buttons (at the start of the header lines) in
+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-cycle
If the @code{outline-minor-mode-cycle} user option is
-non-@code{nil}, the @kbd{TAB} and @kbd{S-TAB} keys are enabled on the
+non-@code{nil}, the @kbd{TAB} and @kbd{S-@key{TAB}} keys are enabled on the
outline heading lines. @kbd{TAB} cycles hiding, showing the
-sub-heading, and showing all for the current section. @kbd{S-TAB}
+sub-heading, and showing all for the current section. @kbd{S-@key{TAB}}
does the same for the entire buffer.
@menu
diff --git a/doc/emacs/trouble.texi b/doc/emacs/trouble.texi
index 9a638818c91..027086cab50 100644
--- a/doc/emacs/trouble.texi
+++ b/doc/emacs/trouble.texi
@@ -393,7 +393,7 @@ this---saving them---updates the files themselves.
associated with any files, or if the autosave was not recent enough to
have recorded important changes, you can use the
@file{etc/emacs-buffer.gdb} script with GDB (the GNU Debugger) to
-retrieve them from a core dump--provided that a core dump was saved,
+retrieve them from a core dump---provided that a core dump was saved,
and that the Emacs executable was not stripped of its debugging
symbols.
@@ -1352,8 +1352,13 @@ downloaded the repository source, you should read the file
from a normal build).
If you would like to make more extensive contributions, see the
-@file{CONTRIBUTE} file in the Emacs distribution for information on
-how to be an Emacs developer.
+@file{CONTRIBUTE} file in the Emacs source tree for information on how
+to be an Emacs developer. That file is distributed as part of the source
+tarball of every released Emacs version, and can also be found on-line
+in the @url{https://git.savannah.gnu.org/cgit/emacs.git/tree/CONTRIBUTE,
+Emacs on-line source repository}. If you cloned the Emacs repository,
+per the instructions in @url{https://savannah.gnu.org/projects/emacs/},
+you will find this file in the top directory of the source Emacs tree.
For documentation on Emacs (to understand how to implement your
desired change), refer to:
diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi
index facbc7f3ed8..27c754133f7 100644
--- a/doc/emacs/windows.texi
+++ b/doc/emacs/windows.texi
@@ -444,7 +444,7 @@ selected window write:
@group
(customize-set-variable
'display-buffer-alist
- '("\\*scratch\\*" (display-buffer-same-window)))
+ '(("\\*scratch\\*" (display-buffer-same-window))))
@end group
@end example
@@ -603,16 +603,16 @@ buffer. @xref{Follow Mode}.
between neighboring windows in a frame. @kbd{M-x windmove-right}
selects the window immediately to the right of the currently selected
one, and similarly for the left, up, and down counterparts.
-@w{@kbd{M-x windmove-default-keybindings}} binds these commands to
+@code{windmove-default-keybindings} binds these commands to
@kbd{S-right} etc.; doing so disables shift selection for those keys
(@pxref{Shift Selection}). In the same way as keybindings can be
defined for commands that select windows directionally, you can use
-@w{@kbd{M-x windmove-display-default-keybindings}} to define
-keybindings for commands that specify in what direction to display the
-window for the buffer that the next command is going to display.
-Also there is @w{@kbd{M-x windmove-delete-default-keybindings}} to
-define keybindings for commands that delete windows directionally, and
-@w{@kbd{M-x windmove-swap-states-default-keybindings}} that defines
+@code{windmove-display-default-keybindings} to define keybindings for
+commands that specify in what direction to display the window for the
+buffer that the next command is going to display. Also there is
+@code{windmove-delete-default-keybindings} to define keybindings for
+commands that delete windows directionally, and
+@code{windmove-swap-states-default-keybindings} that defines
keybindings for commands that swap the window contents of the selected
window with the window in the specified direction.
diff --git a/doc/emacs/xresources.texi b/doc/emacs/xresources.texi
index 00fa6c0aa31..a7bd006df4d 100644
--- a/doc/emacs/xresources.texi
+++ b/doc/emacs/xresources.texi
@@ -395,6 +395,8 @@ Background color.
Foreground color for a selected item.
@item foreground
Foreground color.
+@item disabledForeground
+Foreground color for a disabled menu item.
@ifnottex
@item horizontalSpacing
Horizontal spacing in pixels between items. Default is 3.
@@ -406,6 +408,12 @@ the associated text. Default is 10.
@item shadowThickness
Thickness of shadow lines for 3D buttons, arrows, and other graphical
elements. Default is 1.
+@item borderThickness
+Thickness of the external borders of the menu bars and pop-up menus.
+Default is 1.
+@item cursor
+Name of the cursor to use in the menu bars and pop-up menus. Default
+is @code{"right_ptr"}.
@end ifnottex
@item margin
Margin of the menu bar, in characters. Default is 1.
diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi
index fade4096e38..43f1c2ddd54 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -238,7 +238,7 @@ supports it in developing GNU and promoting software freedom.''
@ifset WWW_GNU_ORG
@html
-<p>The homepage for GNU Emacs is at
+<p>The GNU Emacs website is at
<a href="/software/emacs/">https://www.gnu.org/software/emacs/</a>.<br>
To view this manual in other formats, click
<a href="/software/emacs/manual/eintr.html">here</a>.
@@ -1162,6 +1162,10 @@ computer. Often, people use the term @dfn{expression}
indiscriminately. (Also, in many texts, the word @dfn{form} is used
as a synonym for expression.)
+@c This and the next paragraph say ``kinds of atom'', but that is not
+@c a typo, just slightly ``old-fashioned wording which adds a fillip
+@c of interest to it'', and ``is more elegant writing'', according to
+@c RMS.
Incidentally, the atoms that make up our universe were named such when
they were thought to be indivisible; but it has been found that physical
atoms are not indivisible. Parts can split off an atom or it can
@@ -2142,9 +2146,10 @@ number---the number of characters the location is from the beginning
of the buffer.) In Emacs Lisp, @code{+} can be used to add the
numeric value of marker positions as numbers.
+@cindex @samp{predicate} defined
The @samp{p} of @code{number-or-marker-p} is the embodiment of a
practice started in the early days of Lisp programming. The @samp{p}
-stands for ``predicate''. In the jargon used by the early Lisp
+stands for @dfn{predicate}. In the jargon used by the early Lisp
researchers, a predicate refers to a function to determine whether some
property is true or false. So the @samp{p} tells us that
@code{number-or-marker-p} is the name of a function that determines
@@ -4201,7 +4206,7 @@ times.
The part of the buffer between point and mark is called @dfn{the
region}. Numerous commands work on the region, including
-@code{center-region}, @code{count-lines-region}, @code{kill-region}, and
+@code{center-region}, @code{count-words-region}, @code{kill-region}, and
@code{print-region}.
The @code{save-excursion} special form saves the location of point and
@@ -4214,7 +4219,7 @@ evaluated.
In Emacs, a function frequently moves point as part of its internal
workings even though a user would not expect this. For example,
-@code{count-lines-region} moves point. To prevent the user from being
+@code{count-words-region} moves point. To prevent the user from being
bothered by jumps that are both unexpected and (from the user's point of
view) unnecessary, @code{save-excursion} is often used to keep point in
the location expected by the user. The use of
@@ -4891,8 +4896,6 @@ result of this, point is placed at the beginning of the buffer and mark
is set at the end of the buffer. The whole buffer is, therefore, the
region.
-@c FIXME: the definition of append-to-buffer has been changed (in
-@c 2010-03-30).
@node append-to-buffer
@section The Definition of @code{append-to-buffer}
@findex append-to-buffer
@@ -4927,8 +4930,9 @@ buffer to which the text will go, the window it comes from and goes
to, and the region that will be copied.
@need 1250
-Here is the complete text of the function:
+Here is a possible implementation of the function:
+@c GNU Emacs 22
@smallexample
@group
(defun append-to-buffer (buffer start end)
@@ -4995,7 +4999,9 @@ name. (The function can handle either.)
Since the @code{append-to-buffer} function will be used interactively,
the function must have an @code{interactive} expression. (For a
review of @code{interactive}, see @ref{Interactive, , Making a
-Function Interactive}.) The expression reads as follows:
+Function Interactive}.)
+
+The expression reads as follows:
@smallexample
@group
@@ -5024,7 +5030,7 @@ for true.
The first argument to @code{other-buffer}, the exception, is yet
another function, @code{current-buffer}. That is not going to be
-returned. The second argument is the symbol for true, @code{t}. that
+returned. The second argument is the symbol for true, @code{t}. That
tells @code{other-buffer} that it may show visible buffers (except in
this case, it will not show the current buffer, which makes sense).
@@ -5060,33 +5066,6 @@ point and mark. That argument worked fine.)
@node append-to-buffer body
@subsection The Body of @code{append-to-buffer}
-@ignore
-in GNU Emacs 22 in /usr/local/src/emacs/lisp/simple.el
-
-(defun append-to-buffer (buffer start end)
- "Append to specified buffer the text of the region.
-It is inserted into that buffer before its point.
-
-When calling from a program, give three arguments:
-BUFFER (or buffer name), START and END.
-START and END specify the portion of the current buffer to be copied."
- (interactive
- (list (read-buffer "Append to buffer: " (other-buffer (current-buffer) t))
- (region-beginning) (region-end)))
- (let ((oldbuf (current-buffer)))
- (save-excursion
- (let* ((append-to (get-buffer-create buffer))
- (windows (get-buffer-window-list append-to t t))
- point)
- (set-buffer append-to)
- (setq point (point))
- (barf-if-buffer-read-only)
- (insert-buffer-substring oldbuf start end)
- (dolist (window windows)
- (when (= (window-point window) point)
- (set-window-point window (point))))))))
-@end ignore
-
The body of the @code{append-to-buffer} function begins with @code{let}.
As we have seen before (@pxref{let, , @code{let}}), the purpose of a
@@ -5105,7 +5084,7 @@ whole by showing a template for @code{append-to-buffer} with the
"@var{documentation}@dots{}"
(interactive @dots{})
(let ((@var{variable} @var{value}))
- @var{body}@dots{})
+ @var{body}@dots{}))
@end group
@end smallexample
@@ -5225,19 +5204,39 @@ of filling in the slots of a template:
@need 1200
@noindent
+@anchor{let* introduced}
+@findex let*
In this function, the body of the @code{save-excursion} contains only
one expression, the @code{let*} expression. You know about a
-@code{let} function. The @code{let*} function is different. It has a
-@samp{*} in its name. It enables Emacs to set each variable in its
-varlist in sequence, one after another.
+@code{let} function. The @code{let*} function is different. It
+enables Emacs to set each variable in its varlist in sequence, one
+after another; such that variables in the latter part of the varlist
+can make use of the values to which Emacs set variables earlier in the
+varlist.
-Its critical feature is that variables later in the varlist can make
-use of the values to which Emacs set variables earlier in the varlist.
-@xref{fwd-para let, , The @code{let*} expression}.
+Looking at the @code{let*} expression in @code{append-to-buffer}:
-We will skip functions like @code{let*} and focus on two: the
-@code{set-buffer} function and the @code{insert-buffer-substring}
-function.
+@smallexample
+@group
+(let* ((append-to (get-buffer-create buffer))
+ (windows (get-buffer-window-list append-to t t))
+ point)
+ BODY...)
+@end group
+@end smallexample
+
+@noindent
+we see that @code{append-to} is bound to the value returned by the
+@w{@code{(get-buffer-create buffer)}}. On the next line,
+@code{append-to} is used as an argument to
+@code{get-buffer-window-list}; this would not be possible with the
+@code{let} expression. Note that @code{point} is automatically bound
+to @code{nil}, the same way as it would be done in the @code{let}
+statement.
+
+Now let's focus on the functions @code{set-buffer} and
+@code{insert-buffer-substring} in the body of the @code{let*}
+expression.
@need 1250
In the old days, the @code{set-buffer} expression was simply
@@ -5255,27 +5254,8 @@ but now it is
@end smallexample
@noindent
-@code{append-to} is bound to @code{(get-buffer-create buffer)} earlier
-on in the @code{let*} expression. That extra binding would not be
-necessary except for that @code{append-to} is used later in the
-varlist as an argument to @code{get-buffer-window-list}.
-
-@ignore
-in GNU Emacs 22
-
- (let ((oldbuf (current-buffer)))
- (save-excursion
- (let* ((append-to (get-buffer-create buffer))
- (windows (get-buffer-window-list append-to t t))
- point)
- (set-buffer append-to)
- (setq point (point))
- (barf-if-buffer-read-only)
- (insert-buffer-substring oldbuf start end)
- (dolist (window windows)
- (when (= (window-point window) point)
- (set-window-point window (point))))))))
-@end ignore
+This is because @code{append-to} was bound to @code{(get-buffer-create
+buffer)} earlier on in the @code{let*} expression.
The @code{append-to-buffer} function definition inserts text from the
buffer in which you are currently to a named buffer. It happens that
@@ -5372,6 +5352,12 @@ an argument and insert the region into the current buffer.
@item mark-whole-buffer
Mark the whole buffer as a region. Normally bound to @kbd{C-x h}.
+@item let*
+Declare a list of variables and give them an initial value; then
+evaluate the rest of the expressions in the body of @code{let*}. The
+values of the variables can be used to bind ensuing variables in the
+list.
+
@item set-buffer
Switch the attention of Emacs to another buffer, but do not change the
window being displayed. Used when the program rather than a human is
@@ -5797,7 +5783,7 @@ written like this:
@subsection The @code{let} Expression in @code{insert-buffer}
After ensuring that the variable @code{buffer} refers to a buffer itself
-and not just to the name of a buffer, the @code{insert-buffer function}
+and not just to the name of a buffer, the @code{insert-buffer} function
continues with a @code{let} expression. This specifies three local
variables, @code{start}, @code{end}, and @code{newmark} and binds them
to the initial value @code{nil}. These variables are used inside the
@@ -8767,7 +8753,7 @@ keeps the kill ring from growing too long. It looks like this:
The code checks whether the length of the kill ring is greater than
the maximum permitted length. This is the value of
-@code{kill-ring-max} (which is 60, by default). If the length of the
+@code{kill-ring-max} (which is 120, by default). If the length of the
kill ring is too long, then this code sets the last element of the
kill ring to @code{nil}. It does this by using two functions,
@code{nthcdr} and @code{setcdr}.
@@ -12874,25 +12860,12 @@ familiar part of this function.
@node fwd-para let
@unnumberedsubsec The @code{let*} expression
-The next line of the @code{forward-paragraph} function begins a
-@code{let*} expression. This is different from @code{let}. The
-symbol is @code{let*} not @code{let}.
-
@findex let*
-The @code{let*} special form is like @code{let} except that Emacs sets
-each variable in sequence, one after another, and variables in the
-latter part of the varlist can make use of the values to which Emacs
-set variables in the earlier part of the varlist.
-
-@ignore
-( refappend save-excursion, , code save-excursion in code append-to-buffer .)
-@end ignore
-
-(@ref{append save-excursion, , @code{save-excursion} in @code{append-to-buffer}}.)
-
-In the @code{let*} expression in this function, Emacs binds a total of
-seven variables: @code{opoint}, @code{fill-prefix-regexp},
-@code{parstart}, @code{parsep}, @code{sp-parstart}, @code{start}, and
+The next line of the @code{forward-paragraph} function begins a
+@code{let*} expression (@pxref{let* introduced,,@code{let*}
+introduced}), in which Emacs binds a total of seven variables:
+@code{opoint}, @code{fill-prefix-regexp}, @code{parstart},
+@code{parsep}, @code{sp-parstart}, @code{start}, and
@code{found-start}.
The variable @code{parsep} appears twice, first, to remove instances
@@ -13473,10 +13446,9 @@ The template for an interactive function definition is, as always:
What we need to do is fill in the slots.
-The name of the function should be self-explanatory and similar to the
-existing @code{count-lines-region} name. This makes the name easier
+The name of the function should be self-explanatory and easy
to remember. @code{count-words-region} is the obvious choice. Since
-that name is now used for the standard Emacs command to count words, we
+that name is used for the standard Emacs command to count words, we
will name our implementation @code{@value{COUNT-WORDS}}.
The function counts words within a region. This means that the
@@ -14650,7 +14622,9 @@ Let's re-use @kbd{C-c =} as a convenient keybinding:
Now we can try out @code{count-words-defun}: install both
@code{count-words-in-defun} and @code{count-words-defun}, and set the
-keybinding, and then place the cursor within the following definition:
+keybinding. Then copy the following to an Emacs Lisp buffer (like,
+for instance, @file{*scratch*}), place the cursor within the
+definition, and use the @kbd{C-c =} command.
@smallexample
@group
@@ -17455,9 +17429,9 @@ Manual}, for more information.
@findex line-to-top-of-window
@cindex Simple extension in @file{.emacs} file
-Here is a simple extension to Emacs that moves the line point is on to
-the top of the window. I use this all the time, to make text easier
-to read.
+Here is a simple extension to Emacs that moves the line that point is
+on to the top of the window. I use this all the time, to make text
+easier to read.
You can put the following code into a separate file and then load it
from your @file{.emacs} file, or you can include it within your
@@ -17838,7 +17812,7 @@ xmodmap -e "keysym Alt_L = Meta_L Alt_L"
Finally, a feature I really like: a modified mode line.
When I work over a network, I forget which machine I am using. Also,
-I tend to I lose track of where I am, and which line point is on.
+I tend to lose track of where I am, and which line point is on.
So I reset my mode line to look like this:
diff --git a/doc/lispref/anti.texi b/doc/lispref/anti.texi
index ced8082f6a4..45cbff61e0b 100644
--- a/doc/lispref/anti.texi
+++ b/doc/lispref/anti.texi
@@ -6,186 +6,179 @@
@c This node must have no pointers.
@node Antinews
-@appendix Emacs 26 Antinews
+@appendix Emacs 27 Antinews
@c Update the elisp.texi Antinews menu entry with the above version number.
For those users who live backwards in time, here is information about
-downgrading to Emacs version 26.3. We hope you will enjoy the greater
+downgrading to Emacs version 27.2. We hope you will enjoy the greater
simplicity that results from the absence of many @w{Emacs
@value{EMACSVER}} features.
@itemize @bullet
@item
-Lisp objects are again implemented on the C level as integer types,
-not as pointers. This might be a small step for Emacs Lisp users, but
-it's a giant leap for the Emacs developers who work on the C level,
-since it is now again easy to print Lisp object in the debugger in the
-decimal format, which is so much easier for debugging. It also makes
-calling Emacs functions from the debugger easier, and allows us to
-freely mix integers and Lisp objects in the C code.
+The annoying @code{lexical-binding} local variable now heeds the
+value of @code{enable-local-variables}: if it's @code{nil}, the
+@code{lexical-binding} cookie is ignored. We are working hard on
+removing the lexical-binding support in some past Emacs version, and
+this small step advances us back to that change.
@item
-The test suite was removed from the distribution tarball. We believe
-that tests need seldom if ever be run, certainly not by the end
-users. Removing the tests from the tarball makes it much smaller,
-which is important since disk space becomes more and more at premium
-as you move back in time.
+The @code{load-dangerous-libraries} variable is not obsolete, as it
+must be used to allow loading Lisp compiled by XEmacs, which will
+become more and more important as you move back in time.
@item
-Dynamic module support is disabled by default. This both makes Emacs
-smaller (a worthy goal by itself), and removes the complications and
-additional complexity related with installing module support files and
-letting random shared objects an opportunity to be loaded into Emacs
-and mess with it.
+The optional @var{modes} argument of @code{interactive} is not
+supported, and every command is deemed applicable to any major mode.
+We believe this makes the life of Lisp programmers much simpler, as
+there's now no need to tag commands with the modes where they make
+sense.
@item
-You now must activate any installed packages only after loading your
-init files. That requires an explicit call to
-@code{package-initialize} in your init file, which is a Good Thing, as
-it makes you think seriously where and indeed whether you'd like your
-packages to become available to your sessions. Simplicity should
-tramp convenience!
+Shorthands for Lisp symbols have been removed, which makes loading
+Lisp files and handling Lisp symbols much simpler and more efficient.
+This is important for decent performance on slower CPUs as you move
+back in time.
@item
To reduce the amount of code in Emacs related to unimportant features,
-we've removed native rotation and resizing of images. You will have
-to build Emacs with ImageMagick if you want to resize or rotate images
-inside Emacs. We don't expect anyone to miss that.
+we've removed the variables @code{global-minor-modes} and
+@code{local-minor-modes}. If your Lisp program needs to determine
+whether some minor mode is in effect, it will have to test explicitly
+for every mode. We don't expect anyone to miss those fancy variables.
@item
-We've re-enabled color fonts usage by the XFT font back-end. We
-consider the availability of these fonts more important than a random
-crash here and there, especially since the use of these fonts for
-displaying Emoji will become less and less important as we travel back
-in time, and will completely disappear in some past Emacs version.
+The default preference for servicing sub-processes that produce output
+at a high rate, and the associated variable
+@code{process-prioritize-lower-fds}, have been removed. Moving back
+in time means fewer and fewer programs can produce such high-rate
+output, so this features becomes just useless crud.
@item
-The function @code{network-interface-list} can now return only IPv4
-addresses. We consider the complexity introduced by IPv6 to be too
-much to be justified, and on the other hand its removal is the step in
-the right direction, given that IPv6 is expected to be completely
-removed as we move back in time.
+The encodings that are variants of EBCDIC were removed. This includes
+@code{ibm256}, @code{ibm273}, and others---variants of the EBCDIC
+encoding tailored for some Japanese and European locales. You won't
+need those where you are going.
@item
-The limit on repetitions in regular expressions was reduced to
-@ifnottex
-2**15 @minus{} 1.
-@end ifnottex
-@tex
-@math{2^{15}-1}.
-@end tex
-We envision that regular expressions will become more and more simple
-as we move towards the distant past.
+The ``Bindat type expression'' description language has been removed,
+as the existing data layout specifications are perfectly suited for
+this job.
@item
To simplify code and reduce complexity, we removed the capability of
-searching programs on remote hosts in @code{executable-find}. If you
-really need this feature (why would you?), you can always write your
-own shell script and run it on the remote.
+specifying the success handler in @code{condition-case} via the
+@code{:success} keyword. If you really need this feature (why would
+you?), you can always write some simple Lisp that has the same effect.
@item
-The @code{:extend} face attribute is no longer available; all faces
-have their background color extended by default past end of line.
-This should significantly simplify face management and remove
-unnecessary code bloat, as well as make faces significantly simpler to
-understand and use.
+Emacs modules can no longer provide interactive functions, or install
+finalizers, nor open channels to existing pipe sub-processes. All
+this is extra ballast, especially since we plan on removing modules in
+some past Emacs version. The @code{make_unibyte_string} module API
+was removed for the same reason.
@item
-The predicates @code{display-blink-cursor-p} and
-@code{display-symbol-keys-p} were deleted. They are rarely if ever
-needed, and can easily be substituted by appropriate calls to old and
-proven APIs like @code{display-graphic-p}. As an additional bonus,
-writing Lisp programs that depend on this functionality will make sure
-the programmer understands better what exactly is the required
-features of the display terminal.
+To keep Emacs clean and elegant, we've removed the
+@code{print-integers-as-characters} option. Recognizing characters by
+their decimal codes is a basic requirement for Emacs Lisp programmers,
+and with the expected decrease in use of Unicode characters, this will
+be soon limited to ASCII only: surely something you all can master!
@item
-Relative directories in the value of the @env{HOME} environment
-variable are once again interpreted relative to the
-@code{default-directory} of the current buffer. This is much simpler,
-and also allows @env{HOME} to resolve to a different place in
-different buffers, which allows some interesting applications.
+The optional @var{count} argument of the @code{directory-files}
+function has been removed. Extracting the first @var{n} members from
+the full list is trivial, so this is a significant simplification for
+an insignificant cost.
-For the same reasons, @code{file-name-absolute-p} now again considers
-@file{~foo} an absolute file name, even if there's no known user
-@samp{foo}. This means a Lisp program which uses such file names will
-always work the same on any system, regardless of its known users.
+@item
+Functions that create sub-processes and network connections no longer
+accept the @code{:coding} argument; use
+@code{set-process-coding-system} or bind
+@code{coding-system-for-read/write} instead: again, a significant
+reduction in Emacs complexity for little or no cost.
+
+@item
+We deleted from the macros @code{define-derived-mode} and
+@code{define-minor-mode} the code which allowed using the
+@code{:interactive} argument. The possibility of marking a mode
+non-interactive makes very little sense,
+
+@item
+The possibility of having links to man pages in doc strings has been
+removed. Use plain text instead, if you need such references.
+
+@item
+Temporary buffers are no longer exempt from running any buffer-related
+hooks. Programs that don't want such hooks in some buffer can always
+disable it locally, whereas making that simpler complicates Emacs for
+no good reason.
@item
-File-related primitives like @code{file-attributes},
-@code{file-modes}, @code{file-newer-than-file-p}, and some others once
-again return @code{nil} when the underlying low-level APIs fail,
-instead of signaling an error. We decided that functions which signal
-errors require more complex code from Lisp programs which use them,
-and found this complexity unjustified when returning @code{nil} will
-do.
+Several features that complicated the byte compiler have been removed:
+@itemize @minus
@item
-Similarly, old-style backquotes no longer signal errors; they generate
-warnings instead. You can remove error handling from programs that
-use backquotes.
+The checks for missing declarations of dynamic variables. This will
+continue making less and less sense as we move away of lexical-binding
+support.
@item
-Formatting floating-point numbers has been sped up by letting the
-underlying implementation produce unpredictable values, instead of
-signaling errors when the number is too large to format correctly. We
-believe the Emacs Lisp programmers should always know what they are
-doing when they deal with floating-point values.
+The ability of compiling symlinked @file{*.el} files, which is really
+gross: copy the files instead.
@item
-The function @code{read-char-from-minibuffer} was deleted. We decided
-that @code{read-char} should be enough for any Lisp program that needs
-to ask the user for a single-character input, in recognition of the
-fact that nothing makes Emacs Lisp hackers rejoice more than the need
-to sit down and write yet another interactive question-and-answer
-function, and make it optimal for each specific case. Consequently,
-no history is provided for such responses (why would someone want
-history of single-key strokes, anyway?).
+The warnings about too-wide doc strings---that is just a nuisance, as
+the programmers should be trusted to know what they are doing.
+@end itemize
+
+
+@item
+We deleted several features of the @code{pcase} macro, in accordance
+with our general plan to remove @code{pcase} from Emacs:
+@itemize @minus
@item
-The function @code{ngettext} was deleted. Non-English languages will
-become less and less widespread, let alone useful, as you move back in
-time, so we took this small step in that direction, and simplified
-Emacs as a nice bonus.
+The @code{cl-type} pattern.
@item
-Focus-change notifications on text-mode frames are no longer
-recognized or supported. You can now safely disregard the possibility
-of receiving such notifications on TTY frames. This is one small step
-on the long road of removing all non-character input events Emacs
-supports on TTY frames.
+the @code{pcase-setq} macro.
+
+@item
+The @code{pcase-compile-patterns} function.
+@end itemize
@item
-Face specifications in @code{face-remapping-alist} now have to be
-buffer-specific, without any differences between windows showing the
-same buffers. This allowed us to remove a lot of unneeded code bloat
-from Emacs, and make the face handling much simpler.
+Some of the keywords used in Edebug specification lists were deemed to
+be of little use, and were therefore removed: @code{&interpose},
+@code{&error}, and @code{&name}. The long-term plane is for Emacs to
+drop Edebug entirely, leaving only the trusted Lisp debugger, and we
+continue working according to that plan.
@item
-The @samp{%o} and @samp{%x} formats now always produce unsigned
-values, as you'd expect. This allows you to reveal the underlying
-machine representation, which is different on each architecture,
-something we consider a valuable feature.
+The function @code{object-intervals} was dropped, as a Lisp program
+can easily collect the intervals of a buffer or a string by iterating
+through them one by one.
@item
-We no longer highlight in @code{font-lock-warning-face} symbols with
-confusable quote characters, such as U+2018. Detecting them
-needed non-trivial amount of code, and we firmly believe that Lisp
-programmers always know what they are doing, and don't need to be
-annoyed with typefaces that stand out and distract.
+We decided that the @code{require-theme} function is an unnecessary
+complication, so we deleted it. Lisp programs can easily search along
+@code{custom-theme-load-path} instead.
@item
-The function @code{file-system-info} was dropped on Posix platforms,
-since you can always invoke @command{df} instead and parse its
-output.
+The convenience functions @code{length<}, @code{length>}, and
+@code{length=} were removed, as using @code{length} followed by a
+comparison should be good enough for everyone, especially considering
+that the typical length of a list keeps going down as you move back
+through time.
@item
-The functions that implement the @samp{base64url} encoding were
-removed, as they can always be emulated by suitable tweaking of the
-normal base-64 encoding. No need to bloat Emacs and force Lisp
-programmers learn more interfaces on this account.
+The variable @code{current-minibuffer-command} is no longer available,
+as we found little justification for keeping it.
@item
As part of the ongoing quest for simplicity, many other functions and
-variables have been eliminated.
+variables have been eliminated. Other functions and variables, that
+were declared obsolete since Emacs 23, have been added back, in
+preparation for releasing Emacs 23 in some distant past.
@end itemize
diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi
index 55e9d00d8bf..6a0095dca97 100644
--- a/doc/lispref/buffers.texi
+++ b/doc/lispref/buffers.texi
@@ -89,11 +89,12 @@ in which most editing takes place. Most of the primitives for
examining or changing text operate implicitly on the current buffer
(@pxref{Text}).
- Normally, the buffer displayed in the selected window is the current
-buffer, but this is not always so: a Lisp program can temporarily
-designate any buffer as current in order to operate on its contents,
-without changing what is displayed on the screen. The most basic
-function for designating a current buffer is @code{set-buffer}.
+ Normally, the buffer displayed in the selected window
+(@pxref{Selecting Windows}) is the current buffer, but this is not
+always so: a Lisp program can temporarily designate any buffer as
+current in order to operate on its contents, without changing what is
+displayed on the screen. The most basic function for designating a
+current buffer is @code{set-buffer}.
@defun current-buffer
This function returns the current buffer.
@@ -118,12 +119,12 @@ on it.
When an editing command returns to the editor command loop, Emacs
automatically calls @code{set-buffer} on the buffer shown in the
-selected window. This is to prevent confusion: it ensures that the
-buffer that the cursor is in, when Emacs reads a command, is the
-buffer to which that command applies (@pxref{Command Loop}). Thus,
-you should not use @code{set-buffer} to switch visibly to a different
-buffer; for that, use the functions described in @ref{Switching
-Buffers}.
+selected window (@pxref{Selecting Windows}). This is to prevent
+confusion: it ensures that the buffer that the cursor is in, when Emacs
+reads a command, is the buffer to which that command applies
+(@pxref{Command Loop}). Thus, you should not use @code{set-buffer} to
+switch visibly to a different buffer; for that, use the functions
+described in @ref{Switching Buffers}.
When writing a Lisp function, do @emph{not} rely on this behavior of
the command loop to restore the current buffer after an operation.
@@ -912,16 +913,17 @@ History}) provided it is shown in that window.
If @var{buffer-or-name} is @code{nil} or omitted, this means to bury the
current buffer. In addition, if the current buffer is displayed in the
-selected window, this makes sure that the window is either deleted or
-another buffer is shown in it. More precisely, if the selected window
-is dedicated (@pxref{Dedicated Windows}) and there are other windows on
-its frame, the window is deleted. If it is the only window on its frame
-and that frame is not the only frame on its terminal, the frame is
-dismissed by calling the function specified by
-@code{frame-auto-hide-function} (@pxref{Quitting Windows}). Otherwise,
-it calls @code{switch-to-prev-buffer} (@pxref{Window History}) to show
-another buffer in that window. If @var{buffer-or-name} is displayed in
-some other window, it remains displayed there.
+selected window (@pxref{Selecting Windows}), this makes sure that the
+window is either deleted or another buffer is shown in it. More
+precisely, if the selected window is dedicated (@pxref{Dedicated
+Windows}) and there are other windows on its frame, the window is
+deleted. If it is the only window on its frame and that frame is not
+the only frame on its terminal, the frame is dismissed by calling the
+function specified by @code{frame-auto-hide-function} (@pxref{Quitting
+Windows}). Otherwise, it calls @code{switch-to-prev-buffer}
+(@pxref{Window History}) to show another buffer in that window. If
+@var{buffer-or-name} is displayed in some other window, it remains
+displayed there.
To replace a buffer in all the windows that display it, use
@code{replace-buffer-in-windows}, @xref{Buffers and Windows}.
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index 6d450998673..0a324a642fe 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -451,11 +451,11 @@ reads and discards the following up-event. You can get access to that
up-event with the @samp{U} code character.
This kind of input is used by commands such as @code{describe-key} and
-@code{global-set-key}.
+@code{keymap-global-set}.
@item K
A key sequence on a form that can be used as input to functions like
-@code{define-key}. This works like @samp{k}, except that it
+@code{keymap-set}. This works like @samp{k}, except that it
suppresses, for the last input event in the key sequence, the
conversions that are normally used (when necessary) to convert an
undefined key into a defined one (@pxref{Key Sequence Input}), so this
@@ -1175,7 +1175,9 @@ intended by Lisp code to be used as an event.
* Button-Down Events:: A button was pushed and not yet released.
* Repeat Events:: Double and triple click (or drag, or down).
* Motion Events:: Just moving the mouse, not pushing a button.
+* Touchscreen Events:: Tapping and moving fingers on a touchscreen.
* Focus Events:: Moving the mouse between frames.
+* Xwidget Events:: Events generated by xwidgets.
* Misc Events:: Other events the system can generate.
* Event Examples:: Examples of the lists for mouse events.
* Classifying Events:: Finding the modifier keys in an event symbol.
@@ -1314,12 +1316,9 @@ actually treated as the meta key, not this.)
It is best to avoid mentioning specific bit numbers in your program.
To test the modifier bits of a character, use the function
@code{event-modifiers} (@pxref{Classifying Events}). When making key
-bindings, you can use the read syntax for characters with modifier bits
-(@samp{\C-}, @samp{\M-}, and so on). For making key bindings with
-@code{define-key}, you can use lists such as @code{(control hyper ?x)} to
-specify the characters (@pxref{Changing Key Bindings}). The function
-@code{event-convert-list} converts such a list into an event type
-(@pxref{Classifying Events}).
+bindings with @code{keymap-set}, you specify these events using
+strings like @samp{C-H-x} instead (for ``control hyper x'')
+(@pxref{Changing Key Bindings}).
@node Function Keys
@subsection Function Keys
@@ -1424,9 +1423,12 @@ binding of the key sequence.
@subsection Click Events
@cindex click event
@cindex mouse click event
+@cindex mouse wheel event
When the user presses a mouse button and releases it at the same
-location, that generates a @dfn{click} event. All mouse click event
+location, that generates a @dfn{click} event. Depending on how your
+window-system reports mouse-wheel events, turning the mouse wheel can
+generate either a mouse click or a mouse-wheel event. All mouse event
share the same format:
@example
@@ -1437,7 +1439,8 @@ share the same format:
@item @var{event-type}
This is a symbol that indicates which mouse button was used. It is
one of the symbols @code{mouse-1}, @code{mouse-2}, @dots{}, where the
-buttons are numbered left to right.
+buttons are numbered left to right. For mouse-wheel event, it can be
+@code{wheel-up} or @code{wheel-down}.
You can also use prefixes @samp{A-}, @samp{C-}, @samp{H-}, @samp{M-},
@samp{S-} and @samp{s-} for modifiers alt, control, hyper, meta, shift
@@ -1450,19 +1453,20 @@ describe events by their types; thus, if there is a key binding for
@item @var{position}
@cindex mouse position list
-This is a @dfn{mouse position list} specifying where the mouse click
+This is a @dfn{mouse position list} specifying where the mouse event
occurred; see below for details.
@item @var{click-count}
This is the number of rapid repeated presses so far of the same mouse
-button. @xref{Repeat Events}.
+button or the number of repeated turns of the wheel. @xref{Repeat
+Events}.
@end table
To access the contents of a mouse position list in the
-@var{position} slot of a click event, you should typically use the
+@var{position} slot of a mouse event, you should typically use the
functions documented in @ref{Accessing Mouse}.
-The explicit format of the list depends on where the click occurred.
+The explicit format of the list depends on where the event occurred.
For clicks in the text area, mode line, header line, tab line, or in
the fringe or marginal areas, the mouse position list has the form
@@ -1477,11 +1481,11 @@ The meanings of these list elements are as follows:
@table @asis
@item @var{window}
-The window in which the click occurred.
+The window in which the mouse event occurred.
@item @var{pos-or-area}
The buffer position of the character clicked on in the text area; or,
-if the click was outside the text area, the window area where it
+if the event was outside the text area, the window area where it
occurred. It is one of the symbols @code{mode-line},
@code{header-line}, @code{tab-line}, @code{vertical-line},
@code{left-margin}, @code{right-margin}, @code{left-fringe}, or
@@ -1493,10 +1497,10 @@ happens after the imaginary prefix keys for the event are registered
by Emacs. @xref{Key Sequence Input}.
@item @var{x}, @var{y}
-The relative pixel coordinates of the click. For clicks in the text
+The relative pixel coordinates of the event. For events in the text
area of a window, the coordinate origin @code{(0 . 0)} is taken to be
the top left corner of the text area. @xref{Window Sizes}. For
-clicks in a mode line, header line or tab line, the coordinate origin
+events in a mode line, header line or tab line, the coordinate origin
is the top left corner of the window itself. For fringes, margins,
and the vertical border, @var{x} does not have meaningful data.
For fringes and margins, @var{y} is relative to the bottom edge of the
@@ -1508,9 +1512,9 @@ The time at which the event occurred, as an integer number of
milliseconds since a system-dependent initial time.
@item @var{object}
-Either @code{nil}, which means the click occurred on buffer text, or a
+Either @code{nil}, which means the event occurred on buffer text, or a
cons cell of the form @w{(@var{string} . @var{string-pos})} if there
-is a string from a text property or an overlay at the click position.
+is a string from a text property or an overlay at the event position.
@table @asis
@item @var{string}
@@ -1553,8 +1557,10 @@ corner of @var{object}, which is @code{(0 . 0)}. If @var{object} is
the top left corner of the character glyph clicked on.
@item @var{width}, @var{height}
-These are the pixel width and height of @var{object} or, if this is
-@code{nil}, those of the character glyph clicked on.
+If the click is on a character, either from buffer text or from
+overlay or display string, these are the pixel width and height of
+that character's glyph; otherwise they are dimensions of @var{object}
+clicked on.
@end table
For clicks on a scroll bar, @var{position} has this form:
@@ -1595,7 +1601,8 @@ handle), @code{up} (the up arrow at one end of the scroll bar), or
@end table
For clicks on the frame's internal border (@pxref{Frame Layout}),
-@var{position} has this form:
+the frame's tool bar (@pxref{Tool Bar}) or tab bar, @var{position}
+has this form:
@example
(@var{frame} @var{part} (@var{X} . @var{Y}) @var{timestamp})
@@ -1603,19 +1610,20 @@ For clicks on the frame's internal border (@pxref{Frame Layout}),
@table @asis
@item @var{frame}
-The frame whose internal border was clicked on.
+The frame whose internal border or tool bar or tab bar was clicked on.
@item @var{part}
-The part of the internal border which was clicked on. This can be one
+The part of the frame which was clicked on. This can be one
of the following:
@table @code
-@item nil
-The frame does not have an internal border. This usually happens on
-text-mode frames. This can also happen on GUI frames with internal
-border if the frame doesn't have its @code{drag-internal-border}
-parameter (@pxref{Mouse Dragging Parameters}) set to a non-@code{nil}
-value.
+@cindex tool-bar mouse events
+@item tool-bar
+The frame has a tool bar, and the event was in the tool-bar area.
+
+@cindex tab-bar mouse events
+@item tab-bar
+The frame has a tab bar, and the event was in the tab-bar area.
@item left-edge
@itemx top-edge
@@ -1629,6 +1637,13 @@ canonical character from the border's nearest corner.
@itemx bottom-right-corner
@itemx bottom-left-corner
The click was on the corresponding corner of the internal border.
+
+@item nil
+The frame does not have an internal border, and the event was not on
+the tab bar or the tool bar. This usually happens on text-mode
+frames. This can also happen on GUI frames with internal border if
+the frame doesn't have its @code{drag-internal-border} parameter
+(@pxref{Mouse Dragging Parameters}) set to a non-@code{nil} value.
@end table
@end table
@@ -1821,6 +1836,59 @@ small movements. Otherwise, motion events are not generated as long
as the mouse cursor remains pointing to the same glyph in the text.
@end defvar
+@node Touchscreen Events
+@subsection Touchscreen Events
+@cindex touchscreen events
+@cindex support for touchscreens
+
+Some window systems provide support for input devices that react to
+the user's touching the screen and moving fingers while touching the
+screen. These input devices are known as touchscreens, and Emacs
+reports the events they generate as @dfn{touchscreen events}.
+
+Most individual events generated by a touchscreen only have meaning as
+part of a larger sequence of other events: for instance, the simple
+operation of tapping the touchscreen involves the user placing and
+raising a finger on the touchscreen, and swiping the display to
+scroll it involves placing a finger, moving it many times upwards or
+downwards, and then raising the finger.
+
+@cindex touch point, in touchscreen events
+While a simplistic model consisting of one finger is adequate for taps
+and scrolling, more complicated gestures require support for keeping
+track of multiple fingers, where the position of each finger is
+represented by a @dfn{touch point}. For example, a ``pinch to zoom''
+gesture might consist of the user placing two fingers and moving them
+individually in opposite directions, where the distance between the
+positions of their individual points determine the amount by which to
+zoom the display, and the center of an imaginary line between those
+positions determines where to pan the display after zooming.
+
+The low-level touchscreen events described below can be used to
+implement all the touch sequences described above. In those events,
+each point is represented by a cons of an arbitrary number identifying
+the point and a mouse position list (@pxref{Click Events}) specifying
+the position of the finger when the event occurred.
+
+@table @code
+@cindex @code{touchscreen-begin} event
+@item (touchscreen-begin @var{point})
+This event is sent when @var{point} is created by the user pressing a
+finger against the touchscreen.
+
+@cindex @code{touchscreen-update} event
+@item (touchscreen-update @var{points})
+This event is sent when a point on the touchscreen has changed
+position. @var{points} is a list of touch points containing the
+up-to-date positions of each touch point currently on the touchscreen.
+
+@cindex @code{touchscreen-end} event
+@item (touchscreen-end @var{point})
+This event is sent when @var{point} is no longer present on the
+display, because another program took the grab, or because the user
+raised the finger from the touchscreen.
+@end table
+
@node Focus Events
@subsection Focus Events
@cindex focus event
@@ -1857,6 +1925,100 @@ sequence---that is, after a prefix key---then Emacs reorders the events
so that the focus event comes either before or after the multi-event key
sequence, and not within it.
+@node Xwidget Events
+@subsection Xwidget events
+
+Xwidgets (@pxref{Xwidgets}) can send events to update Lisp programs on
+their status. These events are dubbed @code{xwidget-events}, and
+contain various data describing the nature of the change.
+
+@table @code
+@cindex @code{xwidget-event} event
+@item (xwidget-event @var{kind} @var{xwidget} @var{arg})
+This event is sent whenever some kind of update occurs in
+@var{xwidget}. There are several types of updates, identified by
+their @var{kind}.
+
+@cindex xwidget callbacks
+It is a special event (@pxref{Special Events}), which should be
+handled by adding a callback to an xwidget that is called whenever an
+xwidget event for @var{xwidget} is received.
+
+You can add a callback by setting the @code{callback} of an xwidget's
+property list, which should be a function that accepts @var{xwidget}
+and @var{kind} as arguments.
+
+@table @code
+@cindex @code{load-changed} xwidget event
+@item load-changed
+This xwidget event indicates that the @var{xwidget} has reached a
+particular point of the page-loading process. When these events are
+sent, @var{arg} will contain a string that futher describes the status
+of the widget:
+
+@table @samp
+@cindex @samp{load-started} in xwidgets
+@item load-started
+This means the widget has begun a page-loading operation.
+
+@cindex @samp{load-finished} in xwidgets
+@item load-finished
+This means the @var{xwidget} has finished processing whatever
+page-loading operation that it was previously performing.
+
+@cindex @samp{load-redirected} in xwidgets
+@item load-redirected
+This means the @var{xwidget} has encountered and followed a redirect
+during the page-loading operation.
+
+@cindex @samp{load-committed} in xwidgets
+@item load-committed
+This means the @var{xwidget} has committed to a given URL during the
+page-loading operation, i.e.@: the URL is the final URL that will be
+rendered by @var{xwidget} during the current page-loading operation.
+@end table
+
+@cindex @code{download-callback} xwidget events
+@item download-callback
+This event indicates that a download of some kind has been completed.
+@end table
+
+In the above events, there can be arguments after @var{arg}, which
+itself indicates the URL from which the download file was retrieved:
+the first argument after @var{arg} indicates the MIME type of the
+download, as a string, while the second argument contains the full
+file name of the downloaded file.
+
+@table @code
+@cindex @code{download-started} xwidget events
+@item download-started
+This event indicates that a download has been started. In these
+events, @var{arg} contains the URL of the file that is currently being
+downloaded.
+
+@cindex @code{javascript-callback} xwidget events
+@item javascript-callback
+This event contains JavaScript callback data. These events are used
+internally by @code{xwidget-webkit-execute-script}.
+@end table
+
+@cindex @code{xwidget-display-event} event
+@item (xwidget-display-event @var{xwidget} @var{source})
+This event is sent whenever an xwidget requests that another xwidget
+be displayed. @var{xwidget} is the xwidget that should be displayed,
+and @var{source} is the xwidget that asked to display @var{xwidget}.
+
+It is also a special event which should be handled through callbacks.
+You can add such a callback by setting the @code{display-callback} of
+@var{source}'s property list, which should be a function that accepts
+@var{xwidget} and @var{source} as arguments.
+
+@var{xwidget}'s buffer will be set to a temporary buffer. When
+displaying the widget, care should be taken to replace the buffer with
+the buffer in which the xwidget will be displayed, using
+@code{set-xwidget-buffer} (@pxref{Xwidgets}).
+@end table
+
@node Misc Events
@subsection Miscellaneous System Events
@@ -1884,15 +2046,37 @@ This kind of event indicates that the user deiconified @var{frame} using
the window manager. Its standard definition is @code{ignore}; since the
frame has already been made visible, Emacs has no work to do.
+@cindex @code{touch-end} event
+@item (touch-end (@var{position}))
+This kind of event indicates that the user's finger moved off the
+mouse wheel or the touchpad. The @var{position} element is a mouse
+position list (@pxref{Click Events}), specifying the position of the
+mouse cursor when the finger moved off the mouse wheel.
+
@cindex @code{wheel-up} event
@cindex @code{wheel-down} event
-@item (wheel-up @var{position})
-@itemx (wheel-down @var{position})
+@item (wheel-up @var{position} @var{clicks} @var{lines} @var{pixel-delta})
+@itemx (wheel-down @var{position} @var{clicks} @var{lines} @var{pixel-delta})
These kinds of event are generated by moving a mouse wheel. The
@var{position} element is a mouse position list (@pxref{Click
Events}), specifying the position of the mouse cursor when the event
occurred.
+@var{clicks}, if present, is the number of times that the wheel was
+moved in quick succession. @xref{Repeat Events}. @var{lines}, if
+present and not @code{nil}, is the number of screen lines that should
+be scrolled. @var{pixel-delta}, if present, is a cons cell of the
+form @w{@code{(@var{x} . @var{y})}}, where @var{x} and @var{y} are the
+numbers of pixels by which to scroll in each axis, a.k.a.@:
+@dfn{pixelwise deltas}.
+
+@cindex pixel-resolution wheel events
+You can use these @var{x} and @var{y} pixelwise deltas to determine
+how much the mouse wheel has actually moved at pixel resolution. For
+example, the pixelwise deltas could be used to scroll the display at
+pixel resolution, exactly according to the user's turning the mouse
+wheel.
+
@vindex mouse-wheel-up-event
@vindex mouse-wheel-down-event
This kind of event is generated only on some kinds of systems. On some
@@ -1952,7 +2136,7 @@ example:
(interactive)
(message "Caught signal %S" last-input-event))
-(define-key special-event-map [sigusr1] 'sigusr-handler)
+(keymap-set special-event-map "<sigusr1>" 'sigusr-handler)
@end smallexample
To test the signal handler, you can make Emacs send a signal to itself:
@@ -2053,7 +2237,7 @@ bind it to the @code{signal usr1} event sequence:
(defun usr1-handler ()
(interactive)
(message "Got USR1 signal"))
-(global-set-key [signal usr1] 'usr1-handler)
+(keymap-global-set "<signal> <usr1>" 'usr1-handler)
@end smallexample
@node Classifying Events
@@ -2158,21 +2342,6 @@ This function returns non-@code{nil} if @var{object} is a mouse movement
event. @xref{Motion Events}.
@end defun
-@defun event-convert-list list
-This function converts a list of modifier names and a basic event type
-to an event type which specifies all of them. The basic event type
-must be the last element of the list. For example,
-
-@example
-(event-convert-list '(control ?a))
- @result{} 1
-(event-convert-list '(control meta ?a))
- @result{} -134217727
-(event-convert-list '(control super f1))
- @result{} C-s-f1
-@end example
-@end defun
-
@node Accessing Mouse
@subsection Accessing Mouse Events
@cindex mouse events, data in
@@ -2340,10 +2509,9 @@ This function returns position information corresponding to pixel
coordinates @var{x} and @var{y} in a specified frame or window,
@var{frame-or-window}, which defaults to the selected window.
The coordinates @var{x} and @var{y} are relative to the
-frame or window used.
-If @var{whole} is @code{nil}, the coordinates are relative
-to the window text area, otherwise they are relative to
-the entire window area including scroll bars, margins and fringes.
+text area of the selected window.
+If @var{whole} is @code{non-nil}, the @var{x} coordinate is relative
+to the entire window area including scroll bars, margins and fringes.
@end defun
@node Accessing Scroll
@@ -2393,25 +2561,14 @@ characters in a string is a complex matter, for reasons of historical
compatibility, and it is not always possible.
We recommend that new programs avoid dealing with these complexities
-by not storing keyboard events in strings. Here is how to do that:
-
-@itemize @bullet
-@item
-Use vectors instead of strings for key sequences, when you plan to use
-them for anything other than as arguments to @code{lookup-key} and
-@code{define-key}. For example, you can use
-@code{read-key-sequence-vector} instead of @code{read-key-sequence}, and
-@code{this-command-keys-vector} instead of @code{this-command-keys}.
-
-@item
-Use vectors to write key sequence constants containing meta characters,
-even when passing them directly to @code{define-key}.
+by not storing keyboard events in strings containing control
+characters or the like, but instead store them in the common Emacs
+format as understood by @code{key-valid-p}.
-@item
-When you have to look at the contents of a key sequence that might be a
-string, use @code{listify-key-sequence} (@pxref{Event Input Misc})
-first, to convert it to a list.
-@end itemize
+ If you read a key sequence with @code{read-key-sequence-vector} (or
+@code{read-key-sequence}), or access a key sequence with
+@code{this-command-keys-vector} (or @code{this-command-keys}), you can
+transform this to the recommended format by using @code{key-description}.
The complexities stem from the modifier bits that keyboard input
characters can include. Aside from the Meta modifier, none of these
@@ -2603,10 +2760,14 @@ returns the key sequence as a vector, never as a string.
@cindex upper case key sequence
@cindex downcasing in @code{lookup-key}
@cindex shift-translation
+@vindex translate-upper-case-key-bindings
If an input character is upper-case (or has the shift modifier) and
has no key binding, but its lower-case equivalent has one, then
-@code{read-key-sequence} converts the character to lower case. Note
-that @code{lookup-key} does not perform case conversion in this way.
+@code{read-key-sequence} converts the character to lower case. (This
+behaviour can be disabled by setting the
+@code{translate-upper-case-key-bindings} user option to @code{nil}.)
+Note that @code{lookup-key} does not perform case conversion in this
+way.
@vindex this-command-keys-shift-translated
When reading input results in such a @dfn{shift-translation}, Emacs
@@ -2919,7 +3080,7 @@ supplied to input methods (@pxref{Input Methods}). Use
if you want to translate characters after input methods operate.
@end defvar
-@defun keyboard-translate from to
+@defun key-translate from to
This function modifies @code{keyboard-translate-table} to translate
character code @var{from} into character code @var{to}. It creates
the keyboard translate table if necessary.
@@ -2930,12 +3091,12 @@ make @kbd{C-x}, @kbd{C-c} and @kbd{C-v} perform the cut, copy and paste
operations:
@example
-(keyboard-translate ?\C-x 'control-x)
-(keyboard-translate ?\C-c 'control-c)
-(keyboard-translate ?\C-v 'control-v)
-(global-set-key [control-x] 'kill-region)
-(global-set-key [control-c] 'kill-ring-save)
-(global-set-key [control-v] 'yank)
+(key-translate "C-x" "<control-x>")
+(key-translate "C-c" "<control-c>")
+(key-translate "C-v" "<control-v>")
+(keymap-global-set "<control-x>" 'kill-region)
+(keymap-global-set "<control-c>" 'kill-ring-save)
+(keymap-global-set "<control-v>" 'yank)
@end example
@noindent
@@ -3571,17 +3732,19 @@ commands.
@cindex exit recursive editing
@cindex aborting
To invoke a recursive editing level, call the function
-@code{recursive-edit}. This function contains the command loop; it also
-contains a call to @code{catch} with tag @code{exit}, which makes it
-possible to exit the recursive editing level by throwing to @code{exit}
-(@pxref{Catch and Throw}). If you throw a @code{nil} value, then
-@code{recursive-edit} returns normally to the function that called it.
-The command @kbd{C-M-c} (@code{exit-recursive-edit}) does this.
-Throwing a @code{t} value causes @code{recursive-edit} to quit, so that
-control returns to the command loop one level up. This is called
-@dfn{aborting}, and is done by @kbd{C-]} (@code{abort-recursive-edit}).
-You can also throw a function value. In that case,
+@code{recursive-edit}. This function contains the command loop; it
+also contains a call to @code{catch} with tag @code{exit}, which makes
+it possible to exit the recursive editing level by throwing to
+@code{exit} (@pxref{Catch and Throw}). Throwing a @code{t} value
+causes @code{recursive-edit} to quit, so that control returns to the
+command loop one level up. This is called @dfn{aborting}, and is done
+by @kbd{C-]} (@code{abort-recursive-edit}). Similarly, you can throw
+a string value to make @code{recursive-edit} signal an error, printing
+this string as the message. If you throw a function,
@code{recursive-edit} will call it without arguments before returning.
+Throwing any other value, will make @code{recursive-edit} return
+normally to the function that called it. The command @kbd{C-M-c}
+(@code{exit-recursive-edit}) does this.
Most applications should not use recursive editing, except as part of
using the minibuffer. Usually it is more convenient for the user if you
diff --git a/doc/lispref/compile.texi b/doc/lispref/compile.texi
index f48f4f47e8b..1ca1f66b95d 100644
--- a/doc/lispref/compile.texi
+++ b/doc/lispref/compile.texi
@@ -811,8 +811,7 @@ for you to be able to native-compile Lisp code.
@vindex native-compile@r{, a Lisp feature}
To determine whether the current Emacs process can produce and load
-natively-compiled Lisp code, test whether the @code{native-compile}
-feature is available (@pxref{Named Features}). Alternatively, call
+natively-compiled Lisp code, call
@code{native-comp-available-p} (@pxref{Native-Compilation Functions}).
Unlike byte-compiled code, natively-compiled Lisp code is executed
@@ -904,13 +903,20 @@ invokes the same Emacs executable as the process that called this
function.
@end defun
-@defun batch-native-compile
+@defun batch-native-compile &optional for-tarball
This function runs native-compilation on files specified on the Emacs
command line in batch mode. It must be used only in a batch execution
of Emacs, as it kills Emacs upon completion of the compilation. If
one or more of the files fail to compile, the Emacs process will
attempt to compile all the other files, and will terminate with a
-non-zero status code.
+non-zero status code. The optional argument @var{for-tarball}, if
+non-@code{nil}, tells the function to place the resulting @file{.eln}
+files in the last directory mentioned in
+@code{native-comp-eln-load-path} (@pxref{Library Search}); this is
+meant to be used as part of building an Emacs source tarball for the
+first time, when the natively-compiled files, which are absent from
+the source tarball, should be generated in the build tree instead of
+the user's cache directory.
@end defun
Native compilation can be run entirely asynchronously, in a subprocess
@@ -918,7 +924,11 @@ of the main Emacs process. This leaves the main Emacs process free to
use while the compilation runs in the background. This is the method
used by Emacs to natively-compile any Lisp file or byte-compiled Lisp
file that is loaded into Emacs, when no natively-compiled file for it
-is available.
+is available. Note that because of this use of a subprocess, native
+compilation may produce warning and errors which byte-compilation does
+not, and lisp code may thus need to be modified to work correctly. See
+@code{native-comp-async-report-warnings-errors} in @pxref{Native-Compilation
+Variables} for more details.
@defun native-compile-async files &optional recursively load selector
This function compiles the named @var{files} asynchronously. The
@@ -1032,6 +1042,12 @@ Emacs session in a buffer named @file{*Warnings*}. The default value
@code{t} means display the resulting buffer. To log warnings without
popping up the @file{*Warnings*} buffer, set this variable to
@code{silent}.
+
+ A common cause for asynchronous native-compilation to produce
+warnings is compiling a file that is missing some @code{require} of a
+necessary feature. The feature may be loaded into the main emacs, but
+because native compilation always starts from a subprocess with a
+pristine environment, that may not be true for the subprocess.
@end defopt
@defopt native-comp-async-query-on-exit
diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi
index aacf66c5cf8..06da1025186 100644
--- a/doc/lispref/control.texi
+++ b/doc/lispref/control.texi
@@ -557,7 +557,7 @@ Likewise, it makes no sense to bind keyword symbols
@item (cl-type @var{type})
Matches if @var{expval} is of type @var{type}, which is a type
-descriptor as accepted by @code{cl-typep} (@pxref{cl-typep,,,cl,Common
+descriptor as accepted by @code{cl-typep} (@pxref{Type Predicates,,,cl,Common
Lisp Extensions}). Examples:
@lisp
@@ -1283,6 +1283,15 @@ bindings that can then be used inside @var{body}. The variable
bindings are produced by destructuring binding of elements of
@var{pattern} to the values of the corresponding elements of the
evaluated @var{exp}.
+
+Here's a trivial example:
+
+@example
+(pcase-let ((`(,major ,minor)
+ (split-string "image/png" "/")))
+ minor)
+ @result{} "png"
+@end example
@end defmac
@defmac pcase-let* bindings body@dots{}
diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi
index bc35982c172..00287a7212a 100644
--- a/doc/lispref/customize.texi
+++ b/doc/lispref/customize.texi
@@ -594,6 +594,9 @@ want to take the time to work out a more specific type to use.
@item integer
The value must be an integer.
+@item natnum
+The value must be a nonnegative integer.
+
@item number
The value must be a number (floating point or integer).
@@ -734,7 +737,7 @@ If omitted, @var{key-type} and @var{value-type} default to
The user can add any key matching the specified key type, but you can
give some keys a preferential treatment by specifying them with the
-@code{:options} (see @ref{Variable Definitions}). The specified keys
+@code{:options} (@pxref{Variable Definitions}). The specified keys
will always be shown in the customize buffer (together with a suitable
value), with a checkbox to include or exclude or disable the key/value
pair from the alist. The user will not be able to edit the keys
diff --git a/doc/lispref/debugging.texi b/doc/lispref/debugging.texi
index e458d76d5d0..6548437817c 100644
--- a/doc/lispref/debugging.texi
+++ b/doc/lispref/debugging.texi
@@ -1043,9 +1043,9 @@ functions written in Lisp, it cannot profile Emacs primitives.
@cindex benchmarking
You can measure the time it takes to evaluate individual Emacs Lisp
forms using the @file{benchmark} library. See the function
-@code{benchmark-call} as well as the macros
-@code{benchmark-run}, @code{benchmark-run-compiled} and
-@code{benchmark-progn} in @file{benchmark.el}. You can also use the
+@code{benchmark-call} as well as the macros @code{benchmark-run},
+@code{benchmark-run-compiled}, @code{benchmark-progn} and
+@code{benchmark-call} in @file{benchmark.el}. You can also use the
@code{benchmark} command for timing forms interactively.
@c Not worth putting in the printed manual.
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 7ab2896778d..98a15404f91 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -152,6 +152,9 @@ truncation; a @samp{\} on the rightmost column indicates a line that
wraps. (The display table can specify alternate characters to use
for this; @pxref{Display Tables}).
+ Since wrapping and truncation of text contradict each other, Emacs
+turns off line truncation when wrapping is requested, and vice versa.
+
@defopt truncate-lines
If this buffer-local variable is non-@code{nil}, lines that extend
beyond the right edge of the window are truncated; otherwise, they are
@@ -558,6 +561,26 @@ You can rewrite the previous example with this macro as follows:
@end example
@end defmac
+@defmac with-delayed-message (timeout message) body@dots{}
+Sometimes it's unclear whether an operation will take a long time to
+execute or not, or it can be inconvenient to implement a progress
+reporter. This macro can be used in those situations.
+
+@lisp
+(with-delayed-message (2 (format "Gathering data for %s" entry))
+ (setq data (gather-data entry)))
+@end lisp
+
+In this example, if the body takes more than two seconds to execute,
+the message will be displayed. If it takes a shorter time than that,
+the message won't be displayed. In either case, the body is evaluated
+as normally, and the return value of the final element in the body is
+the return value of the macro.
+
+The @var{message} element is evaluated before @var{body}, and is
+always evaluated, whether the message is displayed or not.
+@end defmac
+
@node Logging Messages
@subsection Logging Messages in @file{*Messages*}
@cindex logging echo-area messages
@@ -1331,6 +1354,11 @@ are not resized. By default, this mode uses @code{fit-window-to-buffer}
(@pxref{Resizing Windows}) for resizing. You can specify a different
function by customizing the options @code{temp-buffer-max-height} and
@code{temp-buffer-max-width} below.
+
+The effect of this option can be overridden by providing a suitable
+@code{window-height}, @code{window-width} or @code{window-size} action
+alist entry for @code{display-buffer} (@pxref{Buffer Display Action
+Alists}).
@end defopt
@defopt temp-buffer-max-height
@@ -1980,7 +2008,8 @@ The return value is an approximation: it only considers the values
returned by @code{char-width} for the constituent characters, always
takes a tab character as taking @code{tab-width} columns, ignores
display properties and fonts, etc. For these reasons, we recommend
-using @code{window-text-pixel-size}, described below, instead.
+using @code{window-text-pixel-size} or @code{string-pixel-width},
+described below, instead.
@end defun
@defun truncate-string-to-width string width &optional start-column padding ellipsis ellipsis-text-property
@@ -1994,11 +2023,11 @@ If a multi-column character in @var{string} exceeds the goal
result can sometimes fall short of @var{width}, but cannot go beyond
it.
-The optional argument @var{start-column} specifies the starting column.
-If this is non-@code{nil}, then the first @var{start-column} columns of
-the string are omitted from the result. If one multi-column character in
-@var{string} extends across the column @var{start-column}, that
-character is omitted.
+The optional argument @var{start-column} specifies the starting
+column; it defaults to zero. If this is non-@code{nil}, then the
+first @var{start-column} columns of the string are omitted from the
+result. If one multi-column character in @var{string} extends across
+the column @var{start-column}, that character is omitted.
The optional argument @var{padding}, if non-@code{nil}, is a padding
character added at the beginning and end of the result string, to
@@ -2024,11 +2053,21 @@ property (@pxref{Display Property}) showing the ellipsis, instead of
actually truncating the string.
@example
+@group
(truncate-string-to-width "\tab\t" 12 4)
@result{} "ab"
(truncate-string-to-width "\tab\t" 12 4 ?\s)
@result{} " ab "
+@end group
@end example
+
+This function uses @code{string-width} and @code{char-width} to find
+the suitable truncation point when @var{string} is too wide, so it
+suffers from the same basic issues as @code{string-width} does. In
+particular, when character composition happens within @var{string},
+the display width of a string could be smaller than the sum of widths
+of the constituent characters, and this function might return
+inaccurate results.
@end defun
@defun truncate-string-ellipsis
@@ -2047,7 +2086,7 @@ displayed in a given window. This function is used by
(@pxref{Resizing Windows}) to make a window exactly as large as the text
it contains.
-@defun window-text-pixel-size &optional window from to x-limit y-limit mode-and-header-line
+@defun window-text-pixel-size &optional window from to x-limit y-limit mode-lines ignore-line-at-end
This function returns the size of the text of @var{window}'s buffer in
pixels. @var{window} must be a live window and defaults to the
selected one. The return value is a cons of the maximum pixel-width
@@ -2089,14 +2128,20 @@ calculating the pixel-height of a large buffer can take some time, it
makes sense to specify this argument; in particular, if the caller
does not know the size of the buffer.
-The optional argument @var{mode-and-header-line} @code{nil} or omitted
-means to not include the height of the mode- or header-line of
-@var{window} in the return value. If it is either the symbol
-@code{mode-line} or @code{header-line}, include only the height of that
+The optional argument @var{mode-lines} @code{nil} or omitted means to
+not include the height of the mode-, tab- or header-line of @var{window}
+in the return value. If it is either the symbol @code{mode-line},
+@code{tab-line} or @code{header-line}, include only the height of that
line, if present, in the return value. If it is @code{t}, include the
-height of both, if present, in the return value.
+height of all of these lines, if present, in the return value.
@end defun
+The optional argument @var{ignore-line-at-end} controls whether or
+not to count the height of text in @var{to}'s screen line as part of
+the returned pixel-height. This is useful if your Lisp program is
+only interested in the dimensions of text up to and excluding the
+visual beginning of @var{to}'s screen line.
+
@code{window-text-pixel-size} treats the text displayed in a window as a
whole and does not care about the size of individual lines. The
following function does.
@@ -2162,12 +2207,59 @@ though when this function is run from an idle timer with a delay of zero
seconds.
@end defun
+@defun buffer-text-pixel-size &optional buffer-or-name window from to x-limit y-limit
+This is much like @code{window-text-pixel-size}, but can be used when
+the buffer isn't shown in a window. (@code{window-text-pixel-size} is
+faster when it is, so this function shouldn't be used in that case.)
+
+@var{buffer-or-name} must specify a live buffer or the name of a live
+buffer and defaults to the current buffer. @var{window} must be a
+live window and defaults to the selected one; the function will
+compute the text dimensions as if @var{buffer} is displayed in
+@var{window}. The return value is a cons of the maximum pixel-width
+of any text line and the pixel-height of all the text lines of the
+buffer specified by @var{buffer-or-name}.
+
+The optional arguments @var{x-limit} and @var{y-limit} have the same
+meaning as with @code{window-text-pixel-size}.
+@end defun
+
+@defun string-pixel-width string
+This is a convenience function that uses @code{window-text-pixel-size}
+to compute the width of @var{string} (in pixels).
+@end defun
+
@defun line-pixel-height
This function returns the height in pixels of the line at point in the
selected window. The value includes the line spacing of the line
(@pxref{Line Height}).
@end defun
+@cindex grapheme cluster
+@defun string-glyph-split string
+When character compositions are in effect, sequence of characters can
+be composed for display to form @dfn{grapheme clusters}, for example
+to display accented characters, or ligatures, or Emoji, or when
+complex text shaping requires that for some scripts. When that
+happens, characters no longer map in a simple way to display columns,
+and display layout decisions with such strings, such as truncating too
+wide strings, can be a complex job. This function helps in performing
+suvh jobs: it splits up its argument @var{string} into a list of
+substrings, where each substring produces a single grapheme cluster
+that should be displayed as a unit. Lisp programs can then use this
+list to construct visually-valid substrings of @var{string} which will
+look correctly on display, or compute the width of any substring of
+@var{string} by adding the width of its constituents in the returned
+list, etc.
+
+For instance, if you want to display a string without the first glyph,
+you can say:
+
+@example
+(apply #'insert (cdr (string-glyph-split string))))
+@end example
+@end defun
+
When a buffer is displayed with line numbers (@pxref{Display Custom,,,
emacs, The GNU Emacs Manual}), it is sometimes useful to know the
width taken for displaying the line numbers. The following function
@@ -2359,8 +2451,10 @@ value @code{unspecified}. This special value means that the face
doesn't specify that attribute directly. An @code{unspecified}
attribute tells Emacs to refer instead to a parent face (see the
description @code{:inherit} attribute below); or, failing that, to an
-underlying face (@pxref{Displaying Faces}). The @code{default} face
-must specify all attributes.
+underlying face (@pxref{Displaying Faces}). (However,
+@code{unspecified} is not a valid value in @code{defface}.)
+
+ The @code{default} face must specify all attributes.
Some of these attributes are meaningful only on certain kinds of
displays. If your display cannot handle a certain attribute, the
@@ -2696,8 +2790,9 @@ apply to. Here are the possible values of @var{characteristic}:
@item type
The kind of window system the terminal uses---either @code{graphic}
(any graphics-capable display), @code{x}, @code{pc} (for the MS-DOS
-console), @code{w32} (for MS Windows 9X/NT/2K/XP), or @code{tty} (a
-non-graphics-capable display). @xref{Window Systems, window-system}.
+console), @code{w32} (for MS Windows 9X/NT/2K/XP), @code{haiku} (for
+Haiku), @code{pgtk} (for GTK), or @code{tty} (a non-graphics-capable
+display). @xref{Window Systems, window-system}.
@item class
What kinds of colors the terminal supports---either @code{color},
@@ -2747,6 +2842,11 @@ terminal must match one of the @var{value}s specified for it in
:group 'basic-faces)
@end example
+@kindex face-defface-spec @r{(face symbol property)}
+@kindex saved-face @r{(face symbol property)}
+@kindex customized-face @r{(face symbol property)}
+@kindex theme-face @r{(face symbol property)}
+@kindex face-documentation @r{(face symbol property)}
Internally, Emacs stores each face's default spec in its
@code{face-defface-spec} symbol property (@pxref{Symbol Properties}).
The @code{saved-face} property stores any face spec saved by the user
@@ -2803,9 +2903,12 @@ This function returns the value of the @var{attribute} attribute for
If @var{frame} is omitted or @code{nil}, that means the selected frame
(@pxref{Input Focus}). If @var{frame} is @code{t}, this function
-returns the value of the specified attribute for newly-created frames
-(this is normally @code{unspecified}, unless you have specified some
-value using @code{set-face-attribute}; see below).
+returns the value of the specified attribute for newly-created frames,
+i.e.@: the value of the attribute before applying the face spec in the
+face's @code{defface} definition (@pxref{Defining Faces}) or the spec
+set by @code{face-spec-set}. This default value of @var{attribute} is
+normally @code{unspecified}, unless you have specified some other
+value using @code{set-face-attribute}; see below.
If @var{inherit} is @code{nil}, only attributes directly defined by
@var{face} are considered, so the return value may be
@@ -2855,7 +2958,12 @@ elements of the result are name-value pairs of the form
@w{@code{(@var{attr-name} . @var{attr-value})}}. Optional argument
@var{frame} specifies the frame whose definition of @var{face} to
return; if omitted or @code{nil}, the returned value describes the
-default attributes of @var{face} for newly created frames.
+default attributes of @var{face} for newly created frames, i.e.@: the
+values these attributes have before applying the face spec in the
+face's @code{defface} definition or the spec set by
+@code{face-spec-set}. These default values of the attributes are
+normally @code{unspecified}, unless you have specified some other
+value using @code{set-face-attribute}; see below.
@end defun
@defun merge-face-attribute attribute value1 value2
@@ -2873,7 +2981,7 @@ for all frames. This function is mostly intended for internal usage.
@defun set-face-attribute face frame &rest arguments
This function sets one or more attributes of @var{face} for
-@var{frame}. The attributes specifies in this way override the face
+@var{frame}. The attributes specified in this way override the face
spec(s) belonging to @var{face}.
The extra arguments @var{arguments} specify the attributes to set, and
@@ -2890,9 +2998,10 @@ sets the attribute @code{:weight} to @code{bold} and the attribute
If @var{frame} is @code{t}, this function sets the default attributes
-for newly created frames. If @var{frame} is @code{nil}, this function
-sets the attributes for all existing frames, as well as for newly
-created frames.
+for newly created frames; they will effectively override the attribute
+values specified by @code{defface}. If @var{frame} is @code{nil},
+this function sets the attributes for all existing frames, as well as
+for newly created frames.
@end defun
The following commands and functions mostly provide compatibility
@@ -4771,9 +4880,7 @@ window on a minibuffer-less frame.
The @code{display} text property (or overlay property) is used to
insert images into text, and to control other aspects of how text
-displays. The value of the @code{display} property should be a
-display specification, or a list or vector containing several display
-specifications. Display specifications in the same @code{display}
+displays. Display specifications in the same @code{display}
property value generally apply in parallel to the text they cover.
If several sources (overlays and/or a text property) specify values
@@ -4781,6 +4888,50 @@ for the @code{display} property, only one of the values takes effect,
following the rules of @code{get-char-property}. @xref{Examining
Properties}.
+ The value of the @code{display} property should be a display
+specification, or a list or vector containing several display
+specifications.
+
+@defun get-display-property position prop &optional object properties
+This convenience function can be used to get a specific display
+property, no matter whether the @code{display} property is a vector, a
+list or a simple property. This is like @code{get-text-property}
+(@pxref{Examining Properties}), but works on the @code{display}
+property only.
+
+@var{position} is the position in the buffer or string to examine, and
+@var{prop} is the @code{display} property to return. The optional
+@var{object} argument should be either a string or a buffer, and
+defaults to the current buffer. If the optional @var{properties}
+argument is non-@code{nil}, it should be a @code{display} property,
+and in that case, @var{position} and @var{object} are ignored. (This
+can be useful if you've already gotten the @code{display} property
+with @code{get-char-property}, for instance (@pxref{Examining
+Properties}).
+@end defun
+
+@defun add-display-text-property start end prop value &optional object
+Add @code{display} property @var{prop} of @var{value} to the text from
+@var{start} to @var{end}.
+
+If any text in the region has a non-@code{nil} @code{display}
+property, those properties are retained. For instance:
+
+@lisp
+(add-display-text-property 4 8 'height 2.0)
+(add-display-text-property 2 12 'raise 0.5)
+@end lisp
+
+After doing this, the region from 2 to 4 will have the @code{raise}
+@code{display} property, the region from 4 to 8 will have both the
+@code{raise} and @code{height} @code{display} properties, and finally
+the region from 8 to 12 will only have the @code{raise} @code{display}
+property.
+
+If @var{object} is non-@code{nil}, it should be a string or a buffer.
+If @code{nil}, this defaults to the current buffer.
+@end defun
+
@cindex display property, unsafe evaluation
@cindex security, and display specifications
Some of the display specifications allow inclusion of Lisp forms,
@@ -5056,6 +5207,24 @@ text that has the specification. It displays all of these spaces
be an integer or float. Characters other than spaces are not affected
at all; in particular, this has no effect on tab characters.
+@item (min-width (@var{width}))
+This display specification ensures the text that has it takes at least
+@var{width} space on display, by adding a stretch of white space to
+the end of the text if the text is shorter than @var{width}. The text
+is partitioned using the identity of the parameter, which is why the
+parameter is a list with one element. For instance:
+
+@lisp
+(insert (propertize "foo" '(display (min-width (6.0)))))
+@end lisp
+
+This will add padding after @samp{foo} bringing the total width up to
+the width of six normal characters. Note that the affected characters
+are identified by the @code{(6.0)} list in the display property,
+compared with @code{eq}. The element @var{width} can be either an
+integer or a float specifying the required minimum width of the text
+(@pxref{Pixel Specification}).
+
@item (height @var{height})
This display specification makes the text taller or shorter.
Here are the possibilities for @var{height}:
@@ -5256,13 +5425,13 @@ to modify the set of known names for these dynamic libraries.
Supported image formats (and the required support libraries) include
PBM and XBM (which do not depend on support libraries and are always
available), XPM (@code{libXpm}), GIF (@code{libgif} or
-@code{libungif}), JPEG (@code{libjpeg}), TIFF
-(@code{libtiff}), PNG (@code{libpng}), and SVG (@code{librsvg}).
+@code{libungif}), JPEG (@code{libjpeg}), TIFF (@code{libtiff}), PNG
+(@code{libpng}), SVG (@code{librsvg}), and WebP (@code{libwebp}).
Each of these image formats is associated with an @dfn{image type
symbol}. The symbols for the above formats are, respectively,
-@code{pbm}, @code{xbm}, @code{xpm}, @code{gif},
-@code{jpeg}, @code{tiff}, @code{png}, and @code{svg}.
+@code{pbm}, @code{xbm}, @code{xpm}, @code{gif}, @code{jpeg},
+@code{tiff}, @code{png}, @code{svg}, and @code{webp}.
Furthermore, if you build Emacs with ImageMagick
(@code{libMagickWand}) support, Emacs can display any image format
@@ -5970,7 +6139,7 @@ To @var{svg} add an embedded (raster) image placed at
@code{:base-uri} specifies a (possibly non-existing) file name of the
svg image to be created, thus all the embedded files are searched
relatively to the @code{:base-uri} filename's directory. If
-@code{:base-uri} is ommited, then filename from where svg image is
+@code{:base-uri} is omitted, then filename from where svg image is
loaded is used. Using @code{:base-uri} improves the performance of
embedding large images, comparing to @code{svg-embed}, because all the
work is done directly by librsvg.
@@ -6266,6 +6435,9 @@ Image type @code{png}.
@item TIFF
Image type @code{tiff}.
Supports the @code{:index} property. @xref{Multi-Frame Images}.
+
+@item WebP
+Image type @code{webp}.
@end table
@node Defining Images
@@ -6417,7 +6589,7 @@ will compute a scaling factor based on the font pixel size.
property yourself, but it is easier to use the functions in this
section.
-@defun insert-image image &optional string area slice
+@defun insert-image image &optional string area slice inhibit-isearch
This function inserts @var{image} in the current buffer at point. The
value @var{image} should be an image descriptor; it could be a value
returned by @code{create-image}, or the value of a symbol defined with
@@ -6442,7 +6614,9 @@ image.
Internally, this function inserts @var{string} in the buffer, and gives
it a @code{display} property which specifies @var{image}. @xref{Display
-Property}.
+Property}. By default, doing interactive searches in the buffer will
+consider @var{string} when searching. If @var{inhibit-isearch} is
+non-@code{nil}, this is inhibited.
@end defun
@cindex slice, image
@@ -6518,6 +6692,11 @@ cache, it can always be displayed, even if the value of
@code{max-image-size} is subsequently changed (@pxref{Image Cache}).
@end defvar
+@defun image-at-point-p
+This function returns @code{t} if point is on an image, and @code{nil}
+otherwise.
+@end defun
+
Images inserted with the insertion functions above also get a local
keymap installed in the text properties (or overlays) that span the
displayed image. This keymap defines the following commands:
@@ -6689,7 +6868,10 @@ xwidget object, and then use that object as the display specifier
in a @code{display} text or overlay property (@pxref{Display
Property}).
-@defun make-xwidget type title width height arguments &optional buffer
+ Embedded widgets can send events notifying Lisp code about changes
+occurring within them. (@pxref{Xwidget Events}).
+
+@defun make-xwidget type title width height arguments &optional buffer related
This creates and returns an xwidget object. If
@var{buffer} is omitted or @code{nil}, it defaults to the current
buffer. If @var{buffer} names a buffer that doesn't exist, it will be
@@ -6702,7 +6884,17 @@ The WebKit component.
@end table
The @var{width} and @var{height} arguments specify the widget size in
-pixels, and @var{title}, a string, specifies its title.
+pixels, and @var{title}, a string, specifies its title. @var{related}
+is used internally by the WebKit widget, and specifies another WebKit
+widget that the newly created widget should share settings and
+subprocesses with.
+
+The xwidget that is returned will be killed alongside its buffer
+(@pxref{Killing Buffers}). You can also kill it using
+@code{kill-xwidget}. Once it is killed, the xwidget may continue to
+exist as a Lisp object and act as a @code{display} property until all
+references to it are gone, but most actions that can be performed on
+live xwidgets will no longer be available.
@end defun
@defun xwidgetp object
@@ -6710,6 +6902,17 @@ This function returns @code{t} if @var{object} is an xwidget,
@code{nil} otherwise.
@end defun
+@defun xwidget-live-p object
+This function returns @code{t} if @var{object} is an xwidget that
+hasn't been killed, and @code{nil} otherwise.
+@end defun
+
+@defun kill-xwidget xwidget
+This function kills @var{xwidget}, by removing it from its buffer and
+releasing window system resources it holds.
+@end defun
+
+@cindex xwidget property list
@defun xwidget-plist xwidget
This function returns the property list of @var{xwidget}.
@end defun
@@ -6720,7 +6923,12 @@ property list given by @var{plist}.
@end defun
@defun xwidget-buffer xwidget
-This function returns the buffer of @var{xwidget}.
+This function returns the buffer of @var{xwidget}. If @var{xwidget}
+has been killed, it returns @code{nil}.
+@end defun
+
+@defun set-xwidget-buffer xwidget buffer
+This function sets the buffer of @var{xwidget} to @var{buffer}.
@end defun
@defun get-buffer-xwidgets buffer
@@ -6783,6 +6991,130 @@ This function returns the current setting of @var{xwidget}s
query-on-exit flag, either @code{t} or @code{nil}.
@end defun
+@defun xwidget-perform-lispy-event xwidget event frame
+Send an input event @var{event} to @var{xwidget}. The precise action
+performed is platform-specific. @xref{Input Events}.
+
+You can optionally pass the frame on which the event was generated via
+@var{frame}. On X11, modifier keys in key events will not be
+considered if @var{frame} is @code{nil}, and the selected frame is not
+an X-Windows frame.
+
+On GTK, only keyboard and function key events are supported. Mouse,
+motion, and click events are dispatched to the xwidget without going
+through Lisp code, and as such shouldn't require this function to be
+called.
+@end defun
+
+@defun xwidget-webkit-search query xwidget &optional case-insensitive backwards wrap-around
+Start an incremental search on the WebKit widget @var{xwidget} with
+the string @var{query} as the query. @var{case-insensitive} denotes
+whether or not the search is case-insensitive, @var{backwards}
+determines if the search is performed backwards towards the start of
+the document, and @var{wrap-around} determines whether or not the
+search terminates at the end of the document.
+
+If the function is called while a search query is already present,
+then the query specified here will replace the existing query.
+
+To stop a search query, use @code{xwidget-webkit-finish-search}.
+@end defun
+
+@defun xwidget-webkit-next-result xwidget
+Display the next search result in @var{xwidget}. This function will
+signal an error if a search query has not been already started in
+@var{xwidget} through @code{xwidget-webkit-search}.
+
+If @code{wrap-around} was non-nil when @code{xwidget-webkit-search}
+was called, then the search will restart from the beginning of the
+document when its end is reached.
+@end defun
+
+@defun xwidget-webkit-previous-result xwidget
+Display the previous search result in @var{xwidget}. This function
+signals an error if a search query has not been already started in
+@var{xwidget} through @code{xwidget-webkit-search}.
+
+If @code{wrap-around} was non-nil when @code{xwidget-webkit-search}
+was called, then the search will restart from the end of the
+document when its beginning is reached.
+@end defun
+
+@defun xwidget-webkit-finish-search xwidget
+Finish a search operation started with @code{xwidget-webkit-search} in
+@var{xwidget}. If there is no query currently ongoing, this function
+signals an error.
+@end defun
+
+@defun xwidget-webkit-load-html xwidget text &optional base-uri
+Load @var{text}, a string, into @var{xwidget}, which should be a
+WebKit xwidget. Any HTML markup in @var{text} will be processed
+by @var{xwidget} while rendering the text.
+
+Optional argument @var{base-uri}, which should be a string, specifies
+the absolute location of the web resources referenced by @var{text},
+to be used for resolving relative links in @var{text}.
+@end defun
+
+@defun xwidget-webkit-goto-history xwidget rel-pos
+Make @var{xwidget}, a WebKit widget, load the @var{rel-pos}th element
+in its navigation history.
+
+If @var{rel-pos} is zero, the current page will be reloaded instead.
+@end defun
+
+@defun xwidget-webkit-back-forward-list xwidget &optional limit
+Return the navigation history of @var{xwidget}, up to @var{limit}
+items in each direction. If not specified, @var{limit} defaults to
+50.
+
+The returned value is a list of the form @w{@code{(@var{back}
+@var{here} @var{forward})}}, where @var{here} is the current
+navigation item, while @var{back} is a list of items containing the
+items recorded by WebKit before the current navigation item, and
+@var{forward} is a list of items recorded after the current navigation
+item. @var{back}, @var{here} and @var{forward} can all be @code{nil}.
+
+When @var{here} is @code{nil}, it means that no items have been
+recorded yet; if @var{back} or @var{forward} are @code{nil}, it means
+that there is no history recorded before or after the current item
+respectively.
+
+Navigation items are themselves lists of the form @w{@code{(@var{idx}
+@var{title} @var{uri})}}. In these lists, @var{idx} is an index that
+can be passed to @code{xwidget-webkit-goto-history}, @var{title} is
+the human-readable title of the item, and @var{uri} is the URI of the
+item. The user should normally have no reason to load @var{uri}
+manually to reach a specific history item. Instead, @var{idx} should
+be passed as an index to @code{xwidget-webkit-goto-history}.
+@end defun
+
+@defun xwidget-webkit-estimated-load-progress xwidget
+Return an estimate of how much data is remaining to be transferred
+before the page displayed by the WebKit widget @var{xwidget} is fully
+loaded.
+
+The value returned is a float ranging between 0.0 and 1.0.
+@end defun
+
+@defun xwidget-webkit-set-cookie-storage-file xwidget file
+Make the WebKit widget @var{xwidget} store cookies in @var{file}.
+
+@var{file} must be an absolute file name. The new setting will also
+affect any xwidget that was created with @var{xwidget} as the
+@code{related} argument to @code{make-xwidget}, and widgets related to
+those as well.
+
+If this function is not called at least once on @var{xwidget} or a
+related widget, @var{xwidget} will not store cookies on disk at all.
+@end defun
+
+@defun xwidget-webkit-stop-loading xwidget
+Terminate any data transfer still in progress in the WebKit widget
+@var{xwidget} as part of a page-loading operation. If a page is not
+being loaded, this function does nothing.
+@end defun
+
@node Buttons
@section Buttons
@cindex buttons in buffers
@@ -6976,7 +7308,7 @@ This inserts a button with the label @var{label} at point, using text
properties.
@end defun
-@defun button-buttonize string callback &optional data
+@defun buttonize string callback &optional data
Sometimes it's more convenient to make a string into a button without
inserting it into a buffer immediately, for instance when creating
data structures that may then, later, be inserted into a buffer. This
@@ -7451,16 +7783,14 @@ The string is formatted #RRGGBB (hash followed by six hex digits)."
(kill-buffer nil))
(setq colorcomp-mode-map
- (let ((m (make-sparse-keymap)))
- (suppress-keymap m)
- (define-key m "i" 'colorcomp-R-less)
- (define-key m "o" 'colorcomp-R-more)
- (define-key m "k" 'colorcomp-G-less)
- (define-key m "l" 'colorcomp-G-more)
- (define-key m "," 'colorcomp-B-less)
- (define-key m "." 'colorcomp-B-more)
- (define-key m " " 'colorcomp-copy-as-kill-and-exit)
- m))
+ (define-keymap :suppress t
+ "i" 'colorcomp-R-less
+ "o" 'colorcomp-R-more
+ "k" 'colorcomp-G-less
+ "l" 'colorcomp-G-more
+ "," 'colorcomp-B-less
+ "." 'colorcomp-B-more
+ "SPC" 'colorcomp-copy-as-kill-and-exit))
@end smallexample
Note that we never modify the data in each node, which is fixed when the
@@ -7869,7 +8199,14 @@ there is no available font (on a graphical display), and characters
which cannot be encoded by the terminal's coding system (on a text
terminal).
+@vindex glyphless-display-mode
+The @code{glyphless-display-mode} minor mode can be used to toggle
+displaying glyphless characters in a convenient manner in the current
+buffer. If this mode is enabled, all the glyphless characters are
+displayed as boxes that display acronyms of their character names.
+
@defvar glyphless-char-display
+For more fine-grained (and global) control, this variable can be used.
The value of this variable is a char-table which defines glyphless
characters and how they are displayed. Each entry must be one of the
following display methods:
@@ -7949,6 +8286,21 @@ Characters of Unicode General Category [Cf], such as U+200E
@sc{left-to-right mark}, but excluding characters that have graphic
images, such as U+00AD @sc{soft hyphen}.
+@item bidi-control
+This is a subset of @code{format-control}, but only includes
+characters that are related to bidirectional formatting control, like
+U+2069 @sc{pop directional isolate} and U+202A @sc{left-to-right
+embedding}. @xref{Bidirectional Display}.
+
+Characters of Unicode General Category [Cf], such as U+200E
+@sc{left-to-right mark}, but excluding characters that have graphic
+images, such as U+00AD @sc{soft hyphen}.
+
+@item variation-selectors
+Unicode VS-1 through VS-16 (U+FE00 through U+FE0F), which are used to
+select between different glyphs for the same codepoints (typically
+emojis).
+
@item no-font
Characters for which there is no suitable font, or which cannot be
encoded by the terminal's coding system.
@@ -8021,6 +8373,8 @@ Emacs is displaying the frame using the Nextstep interface (used on
GNUstep and macOS).
@item pc
Emacs is displaying the frame using MS-DOS direct screen writes.
+@item haiku
+Emacs is displaying the frame using the Application Kit on Haiku.
@item nil
Emacs is displaying the frame on a character-based terminal.
@end table
@@ -8067,6 +8421,7 @@ area. On text-mode (a.k.a.@: ``TTY'') frames, tooltips are always
displayed in the echo area.
@end defun
+@cindex system tooltips
@vindex x-gtk-use-system-tooltips
When Emacs is built with GTK+ support, it by default displays tooltips
using GTK+ functions, and the appearance of the tooltips is then
diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi
index 323130f2378..0db77255a65 100644
--- a/doc/lispref/edebug.texi
+++ b/doc/lispref/edebug.texi
@@ -1216,9 +1216,7 @@ directs processing of arguments.
@table @asis
@item @code{t}
All arguments are instrumented for evaluation.
-
-@item @code{0}
-None of the arguments is instrumented.
+This is short for @code{(body)}.
@item a symbol
The symbol must have an Edebug specification, which is used instead.
@@ -1269,7 +1267,7 @@ balanced parentheses, recursive processing of forms, and recursion via
indirect specifications.
Here's a table of the possible elements of a specification list, with
-their meanings (see @ref{Specification Examples}, for the referenced
+their meanings (@pxref{Specification Examples}, for the referenced
examples):
@table @code
@@ -1528,6 +1526,16 @@ example of the @code{let} specification.
It may be easier to understand Edebug specifications by studying
the examples provided here.
+Consider a hypothetical macro @code{my-test-generator} that runs
+tests on supplied lists of data. Although it is Edebug's default
+behavior to not instrument arguments as code, as controlled by
+@code{edebug-eval-macro-args} (@pxref{Instrumenting Macro Calls}),
+it can be useful to explicitly document that the arguments are data:
+
+@example
+(def-edebug-spec my-test-generator (&rest sexp))
+@end example
+
A @code{let} special form has a sequence of bindings and a body. Each
of the bindings is either a symbol or a sublist with a symbol and
optional expression. In the specification below, notice the @code{gate}
diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi
index 55bcf399d81..2186203eb6d 100644
--- a/doc/lispref/elisp.texi
+++ b/doc/lispref/elisp.texi
@@ -161,7 +161,7 @@ Cover art by Etienne Suvasa.
@ifset WWW_GNU_ORG
@html
-<p>The homepage for GNU Emacs is at
+<p>The GNU Emacs website is at
<a href="/software/emacs/">https://www.gnu.org/software/emacs/</a>.<br>
For information on using Emacs, refer to the
<a href="/software/emacs/manual/emacs.html">Emacs Manual</a>.<br>
@@ -234,7 +234,7 @@ To view this manual in other formats, click
Appendices
-* Antinews:: Info for users downgrading to Emacs 26.
+* Antinews:: Info for users downgrading to Emacs 27.
* GNU Free Documentation License:: The license for this documentation.
* GPL:: Conditions for copying and changing GNU Emacs.
* Tips:: Advice and coding conventions for Emacs Lisp.
@@ -365,6 +365,7 @@ Editing Types
* Keymap Type:: What function a keystroke invokes.
* Overlay Type:: How an overlay is represented.
* Font Type:: Fonts for displaying text.
+* Xwidget Type:: Embeddable widgets.
Numbers
@@ -525,6 +526,7 @@ Variables
* Variables with Restricted Values:: Non-constant variables whose value can
@emph{not} be an arbitrary Lisp object.
* Generalized Variables:: Extending the concept of variables.
+* Multisession Variables:: Variables that survive restarting Emacs.
Scoping Rules for Variable Bindings
@@ -546,6 +548,10 @@ Generalized Variables
* Setting Generalized Variables:: The @code{setf} macro.
* Adding Generalized Variables:: Defining new @code{setf} forms.
+Multisession Variables
+
+* Multisession Variables:: Variables that survive restarting Emacs.
+
Functions
* What Is a Function:: Lisp functions vs. primitives; terminology.
@@ -839,6 +845,7 @@ Keymaps
* Key Lookup:: Finding a key's binding in one keymap.
* Functions for Key Lookup:: How to request key lookup.
* Changing Key Bindings:: Redefining a key in a keymap.
+* Low-Level Key Binding:: Legacy key syntax description.
* Remapping Commands:: A keymap can translate one command to another.
* Translation Keymaps:: Keymaps for translating sequences of events.
* Key Binding Commands:: Interactive interfaces for redefining keys.
@@ -1048,6 +1055,7 @@ Windows
* Basic Windows:: Basic information on using windows.
* Windows and Frames:: Relating windows to the frame they appear on.
+* Selecting Windows:: The selected window is the one that you edit in.
* Window Sizes:: Accessing a window's size.
* Resizing Windows:: Changing the sizes of windows.
* Preserving Window Sizes:: Preserving the size of windows.
@@ -1055,7 +1063,6 @@ Windows
* Deleting Windows:: Deleting a window gives its space to other windows.
* Recombining Windows:: Preserving the frame layout when splitting and
deleting windows.
-* Selecting Windows:: The selected window is the one that you edit in.
* Cyclic Window Ordering:: Moving around the existing windows.
* Buffers and Windows:: Each window displays the contents of a buffer.
* Switching Buffers:: Higher-level functions for switching to a buffer.
@@ -1123,6 +1130,7 @@ Frames
* Dialog Boxes:: Displaying a box to ask yes or no.
* Pointer Shape:: Specifying the shape of the mouse pointer.
* Window System Selections::Transferring text to and from other X clients.
+* Yanking Media:: Yanking things that aren't plain text.
* Drag and Drop:: Internals of Drag-and-Drop implementation.
* Color Names:: Getting the definitions of color names.
* Text Terminal Colors:: Defining colors for text terminals.
@@ -1221,6 +1229,7 @@ Text
* Base 64:: Conversion to or from base 64 encoding.
* Checksum/Hash:: Computing cryptographic hashes.
* GnuTLS Cryptography:: Cryptographic algorithms imported from GnuTLS.
+* Database:: Interacting with an SQL database.
* Parsing HTML/XML:: Parsing HTML and XML.
* Atomic Changes:: Installing several buffer changes atomically.
* Change Hooks:: Supplying functions to be run when text is changed.
@@ -1316,6 +1325,7 @@ Regular Expressions
* Rx Notation:: An alternative, structured regexp notation.
@end ifnottex
* Regexp Functions:: Functions for operating on regular expressions.
+* Regexp Problems:: Some problems and how they may be avoided.
Syntax of Regular Expressions
diff --git a/doc/lispref/eval.texi b/doc/lispref/eval.texi
index 7893895eee9..e1998842cf0 100644
--- a/doc/lispref/eval.texi
+++ b/doc/lispref/eval.texi
@@ -862,8 +862,13 @@ expressions that were read, evaluated, and printed from buffers
(including the minibuffer) by the standard Emacs commands which do
this. (Note that this does @emph{not} include evaluation in
@file{*ielm*} buffers, nor evaluation using @kbd{C-j}, @kbd{C-x C-e},
-and similar evaluation commands in @code{lisp-interaction-mode}.) The
-elements are ordered most recent first.
+and similar evaluation commands in @code{lisp-interaction-mode}.)
+
+This variable is obsolete, and will be removed in a future version,
+since it constantly enlarges the memory footprint of the Emacs
+process. For that reason, we recommend against using it.
+
+The elements of @code{values} are ordered most recent first.
@example
@group
@@ -880,8 +885,8 @@ values
@end group
@end example
-This variable is useful for referring back to values of forms recently
-evaluated. It is generally a bad idea to print the value of
+This variable could be useful for referring back to values of forms
+recently evaluated. It is generally a bad idea to print the value of
@code{values} itself, since this may be very long. Instead, examine
particular elements, like this:
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 266501d46d0..4b114ba111d 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -563,7 +563,17 @@ In this case, @var{visit} must be @code{nil}. For example,
@end example
@noindent
-inserts the first 500 characters of a file.
+inserts the characters coded by the first 500 bytes of a file.
+
+If @var{beg} or @var{end} happens to be in the middle of a character's
+multibyte sequence, Emacs's character code conversion will insert one
+or more eight-bit characters (a.k.a.@: ``raw bytes'')
+(@pxref{Character Sets}) into the buffer. If you want to read part of
+a file this way, we recommend to bind @code{coding-system-for-read} to
+a suitable value around the call to this function (@pxref{Specifying
+Coding Systems}), and to write Lisp code which will check for raw
+bytes at the boundaries, read the entire sequence of these bytes, and
+convert them back to valid characters.
If the argument @var{replace} is non-@code{nil}, it means to replace the
contents of the buffer (actually, just the accessible portion) with the
@@ -577,10 +587,11 @@ with @code{insert-file-contents}, as long as @var{replace} and
@end defun
@defun insert-file-contents-literally filename &optional visit beg end replace
-This function works like @code{insert-file-contents} except that it
-does not run @code{after-insert-file-functions}, and does not do
-format decoding, character code conversion, automatic uncompression,
-and so on.
+This function works like @code{insert-file-contents} except that each
+byte in the file is handled separately, being converted into an
+eight-bit character if needed. It does not run
+@code{after-insert-file-functions}, and does not do format decoding,
+character code conversion, automatic uncompression, and so on.
@end defun
If you want to pass a file name to another process so that another
@@ -936,6 +947,16 @@ file in @file{/foo/} will give an error:
@end example
@end defun
+@defmac with-existing-directory body@dots{}
+This macro ensures that @code{default-directory} is bound to an
+existing directory before executing @var{body}. If
+@code{default-directory} already exists, that's preferred, and
+otherwise some other directory is used. This macro can be useful, for
+instance, when calling an external command that requires that it's
+running in a directory that exists. The chosen directory is not
+guaranteed to be writable.
+@end defmac
+
@defun access-file filename string
If you can read @var{filename} this function returns @code{nil};
otherwise it signals an error
@@ -1293,6 +1314,20 @@ on the 19th, @file{aug-20} was written on the 20th, and the file
@end example
@end defun
+@defun file-has-changed-p filename tag
+This function returns non-@code{nil} if the time stamp of
+@var{filename} has changed since the last call. When called for the
+first time for some @var{filename}, it records the last modification
+time and size of the file, and returns non-@code{nil} when
+@var{filename} exists. Thereafter, when called for the same
+@var{filename}, it compares the current time stamp and size with the
+recorded ones, and returns non-@code{nil} only if either the time
+stamp or the size (or both) are different. This is useful when a Lisp
+program wants to re-read a file whenever it changes. With an optional
+argument @var{tag}, which must be a symbol, the size and modification
+time comparisons are limited to calls with the same tag.
+@end defun
+
@defun file-attributes filename &optional id-format
@anchor{Definition of file-attributes}
This function returns a list of attributes of file @var{filename}. If
@@ -1864,7 +1899,7 @@ Interactively, @var{mode} is read from the minibuffer using
@code{read-file-modes} (see below), which lets the user type in either
an integer or a string representing the permissions symbolically.
-@xref{File Attributes}, for the function @code{file-modes}, which
+@xref{Testing Accessibility}, for the function @code{file-modes}, which
returns the permissions of a file.
@end deffn
@@ -2062,6 +2097,9 @@ directory. Therefore, Emacs considers a file name as having two main
parts: the @dfn{directory name} part, and the @dfn{nondirectory} part
(or @dfn{file name within the directory}). Either part may be empty.
Concatenating these two parts reproduces the original file name.
+@footnote{Emacs follows the GNU convention to use the term @emph{file name}
+instead of the term @emph{pathname}. We use the term @emph{path} only for
+search paths, which are lists of directory names.}
On most systems, the directory part is everything up to and including
the last slash (backslash is also allowed in input on MS-DOS or
@@ -2206,6 +2244,19 @@ and @code{file-name-nondirectory}. For example,
@end example
@end defun
+@defun file-name-split filename
+This function splits a file name into its components, and can be
+thought of as the inverse of @code{string-join} with the appropriate
+directory separator. For example,
+
+@example
+(file-name-split "/tmp/foo.txt")
+ @result{} ("" "tmp" "foo.txt")
+(string-join (file-name-split "/tmp/foo.txt") "/")
+ @result{} "/tmp/foo.txt"
+@end example
+@end defun
+
@node Relative File Names
@subsection Absolute and Relative File Names
@cindex absolute file name
@@ -3257,8 +3308,8 @@ first, before handlers for jobs such as remote file access.
@ifnottex
@noindent
-@code{access-file}, @code{add-name-to-file},
-@code{byte-compiler-base-file-name},@*
+@code{abbreviate-file-name}, @code{access-file},
+@code{add-name-to-file}, @code{byte-compiler-base-file-name},@*
@code{copy-directory}, @code{copy-file},
@code{delete-directory}, @code{delete-file},
@code{diff-latest-backup-file},
@@ -3317,7 +3368,8 @@ first, before handlers for jobs such as remote file access.
@iftex
@noindent
@flushleft
-@code{access-file}, @code{add-name-to-file},
+@code{abbreviate-file-name}, @code{access-file},
+@code{add-name-to-file},
@code{byte-com@discretionary{}{}{}piler-base-file-name},
@code{copy-directory}, @code{copy-file},
@code{delete-directory}, @code{delete-file},
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index 25706befc8d..712c842a048 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -105,6 +105,7 @@ window of another Emacs frame. @xref{Child Frames}.
* Dialog Boxes:: Displaying a box to ask yes or no.
* Pointer Shape:: Specifying the shape of the mouse pointer.
* Window System Selections:: Transferring text to and from other X clients.
+* Yanking Media:: Yanking things that aren't plain text.
* Drag and Drop:: Internals of Drag-and-Drop implementation.
* Color Names:: Getting the definitions of color names.
* Text Terminal Colors:: Defining colors for text terminals.
@@ -151,7 +152,7 @@ the window (a.k.a.@: the @dfn{dominating} monitor).
This function itself does not make the new frame the selected frame.
@xref{Input Focus}. The previously selected frame remains selected.
-On graphical terminals, however, the windowing system may select the
+On graphical terminals, however, the window system may select the
new frame for its own reasons.
@end deffn
@@ -170,7 +171,9 @@ usually not run for the initial frame, since Emacs reads the initial
file only after creating that frame. However, if the initial frame is
specified to use a separate minibuffer frame (@pxref{Minibuffers and
Frames}), the functions will be run for both, the minibuffer-less and
-the minibuffer frame.
+the minibuffer frame. Alternatively, you can add functions to these
+hooks in your ``early init file'' (@pxref{Init File}), in which case
+they will be in effect for the initial frame as well.
@defvar frame-inherited-parameters
This variable specifies the list of frame parameters that a newly
@@ -213,7 +216,8 @@ The terminal and keyboard coding systems used on the terminal.
@item
The kind of display associated with the terminal. This is the symbol
returned by the function @code{terminal-live-p} (i.e., @code{x},
-@code{t}, @code{w32}, @code{ns}, or @code{pc}). @xref{Frames}.
+@code{t}, @code{w32}, @code{ns}, @code{pc}, @code{haiku}, or @code{pgtk}).
+@xref{Frames}.
@item
A list of terminal parameters. @xref{Terminal Parameters}.
@@ -494,7 +498,8 @@ a graphical terminal:
| | |_____________ Title Bar ______________| |
| | (1)_____________ Menu Bar ______________| | ^
| | (2)_____________ Tool Bar ______________| | ^
- | | (3) _________ Internal Border ________ | | ^
+ | | (3)_____________ Tab Bar _______________| | ^
+ | | | _________ Internal Border ________ | | ^
| | | | ^ | | | |
| | | | | | | | |
Outer | | | Inner | | | Native
@@ -640,6 +645,15 @@ GTK+, on the other hand, never wraps the tool bar but may
automatically increase the outer width of a frame in order to
accommodate an overlong tool bar.
+@item Tab Bar
+@cindex tab bar
+The tab bar (@pxref{Tab Bars,,,emacs, The GNU Emacs Manual}) is always
+drawn by Emacs itself. The tab bar appears above the tool bar in
+Emacs built with an internal tool bar, and below the tool bar in
+builds with an external tool bar.
+Display of the tab bar can be suppressed by setting the
+@code{tab-bar-lines} parameter (@pxref{Layout Parameters}) to zero.
+
@item Native Frame
@cindex native frame
@cindex native edges
@@ -669,7 +683,7 @@ indicate that position for the various builds:
@itemize @w{}
@item (1) non-toolkit and terminal frames
-@item (2) Lucid, Motif and MS-Windows frames
+@item (2) Lucid, Motif, MS-Windows, and Haiku frames
@item (3) GTK+ and NS frames
@end itemize
@@ -740,8 +754,8 @@ the internal border, one vertical scroll bar, and one left and one right
fringe if they are specified for this frame, see @ref{Layout
Parameters}. Its height can be obtained by removing from that of the
native height the widths of the internal border and the heights of the
-frame's internal menu and tool bars and one horizontal scroll bar if
-specified for this frame.
+frame's internal menu and tool bars, the tab bar and one horizontal
+scroll bar if specified for this frame.
@end table
@cindex absolute position
@@ -1208,10 +1222,10 @@ width of one scroll bar provided this option is @code{nil} and keep it
unchanged if this option is @code{t} or a list containing
@code{vertical-scroll-bars}.
-The default value is @code{'(tab-bar-lines tool-bar-lines)} for Lucid,
+The default value is @code{(tab-bar-lines tool-bar-lines)} for Lucid,
Motif and MS-Windows (which means that adding/removing a tool or tab
bar there does not change the outer frame height),
-@code{'(tab-bar-lines)} on all other window systems including GTK+
+@code{(tab-bar-lines)} on all other window systems including GTK+
(which means that changing any of the parameters listed above with the
exception of @code{tab-bar-lines} may change the size of the outer
frame), and @code{t} otherwise (which means the outer frame size never
@@ -1718,7 +1732,9 @@ fit will be clipped by the window manager.
@item fullscreen
This parameter specifies whether to maximize the frame's width, height
or both. Its value can be @code{fullwidth}, @code{fullheight},
-@code{fullboth}, or @code{maximized}. A @dfn{fullwidth} frame is as
+@code{fullboth}, or @code{maximized}.@footnote{On Haiku, setting
+@code{fullscreen} to @code{fullwidth} or @code{fullheight} has no
+effect.} A @dfn{fullwidth} frame is as
wide as possible, a @dfn{fullheight} frame is as tall as possible, and
a @dfn{fullboth} frame is both as wide and as tall as possible. A
@dfn{maximized} frame is like a ``fullboth'' frame, except that it usually
@@ -1875,6 +1891,13 @@ The position of the tool bar when Emacs was built with GTK+. Its value
can be one of @code{top}, @code{bottom} @code{left}, @code{right}. The
default is @code{top}.
+@vindex tab-bar-lines@r{, a frame parameter}
+@item tab-bar-lines
+The number of lines to use for the tab bar (@pxref{Tab Bars,,,emacs, The
+GNU Emacs Manual}). The default is one if Tab Bar mode is enabled and
+zero otherwise. This value may change whenever the tab bar wraps
+(@pxref{Frame Layout}).
+
@vindex line-spacing@r{, a frame parameter}
@item line-spacing
Additional space to leave below each text line, in pixels (a positive
@@ -2173,7 +2196,10 @@ either via @code{focus-follows-mouse} (@pxref{Input Focus}) or
@code{mouse-autoselect-window} (@pxref{Mouse Window Auto-selection}).
This may have the unwanted side-effect that a user cannot scroll a
non-selected frame with the mouse. Some window managers may not honor
-this parameter.
+this parameter. On Haiku, it also has the side-effect that the window
+will not be able to receive any keyboard input from the user, not even
+if the user switches to the frame using the key combination
+@kbd{Alt-@key{TAB}}.
@vindex undecorated@r{, a frame parameter}
@item undecorated
@@ -2334,7 +2360,10 @@ driver for OTF and TTF fonts with text shaping by the Uniscribe
engine), and @code{harfbuzz} (font driver for OTF and TTF fonts with
HarfBuzz text shaping) (@pxref{Windows Fonts,,, emacs, The GNU Emacs
Manual}). The @code{harfbuzz} driver is similarly recommended. On
-other systems, there is only one available font backend, so it does
+Haiku, there can be several font drivers (@pxref{Haiku Fonts,,, emacs,
+The GNU Emacs Manual}).
+
+On other systems, there is only one available font backend, so it does
not make sense to modify this frame parameter.
@vindex background-mode@r{, a frame parameter}
@@ -2692,18 +2721,19 @@ frame and defaults to the selected frame. It never returns a frame
whose @code{no-other-frame} parameter (@pxref{Frame Interaction
Parameters}) is non-@code{nil}.
-The second argument, @var{minibuf}, says which frames to consider:
+The second argument, @var{minibuf}, says which frames to consider when
+deciding what the next frame should be:
@table @asis
@item @code{nil}
-Exclude minibuffer-only frames.
+Consider all frames except minibuffer-only frames.
@item @code{visible}
-Consider all visible frames.
+Consider only visible frames.
@item 0
-Consider all visible or iconified frames.
+Consider only visible or iconified frames.
@item a window
Consider only the frames using that particular window as their
-minibuffer.
+minibuffer window.
@item anything else
Consider all frames.
@end table
@@ -2757,7 +2787,8 @@ Terminals}.
@cindex selected frame
At any time, one frame in Emacs is the @dfn{selected frame}. The
-selected window always resides on the selected frame.
+selected window (@pxref{Selecting Windows}) always resides on the
+selected frame.
When Emacs displays its frames on several terminals (@pxref{Multiple
Terminals}), each terminal has its own selected frame. But only one
@@ -2991,12 +3022,11 @@ Auto-selection}).
Note that this option does not distinguish ``sloppy'' focus (where the
frame that previously had focus retains focus as long as the mouse
-pointer does not move into another window manager window) from
-``strict'' focus (where a frame immediately loses focus when it's left
-by the mouse pointer). Neither does it recognize whether your window
-manager supports delayed focusing or auto-raising where you can
-explicitly specify the time until a new frame gets focus or is
-auto-raised.
+pointer does not move into another window-system window) from ``strict''
+focus (where a frame immediately loses focus when it's left by the mouse
+pointer). Neither does it recognize whether your window manager
+supports delayed focusing or auto-raising where you can explicitly
+specify the time until a new frame gets focus or is auto-raised.
You can supply a ``focus follows mouse'' policy for individual Emacs
windows by customizing the variable @code{mouse-autoselect-window}
@@ -3122,8 +3152,10 @@ raises @var{frame} above all other child frames of its parent.
@deffn Command lower-frame &optional frame
This function lowers frame @var{frame} (default, the selected frame)
below all other frames belonging to the same or a higher z-group as
-@var{frame}. If @var{frame} is a child frame (@pxref{Child Frames}),
-this lowers @var{frame} below all other child frames of its parent.
+@var{frame}.@footnote{Lowering frames is not supported on Haiku, due
+to limitations imposed by the system.} If @var{frame} is a child
+frame (@pxref{Child Frames}), this lowers @var{frame} below all other
+child frames of its parent.
@end deffn
@defun frame-restack frame1 frame2 &optional above
@@ -3133,7 +3165,8 @@ that if both frames are visible and their display areas overlap,
third argument @var{above} is non-@code{nil}, this function restacks
@var{frame1} above @var{frame2}. This means that if both frames are
visible and their display areas overlap, @var{frame1} will (partially)
-obscure @var{frame2}.
+obscure @var{frame2}.@footnote{Restacking frames is not supported on
+Haiku, due to limitations imposed by the system.}
Technically, this function may be thought of as an atomic action
performed in two steps: The first step removes @var{frame1}'s
@@ -3228,12 +3261,16 @@ parent frame's window-system window.
@cindex reparent frame
@cindex nest frame
- The @code{parent-frame} parameter can be changed at any time. Setting
-it to another frame @dfn{reparents} the child frame. Setting it to
-another child frame makes the frame a @dfn{nested} child frame. Setting
-it to @code{nil} restores the frame's status as a top-level frame---a
-frame whose window-system window is a child of its display's root
-window.
+ The @code{parent-frame} parameter can be changed at any time.
+Setting it to another frame @dfn{reparents} the child frame. Setting
+it to another child frame makes the frame a @dfn{nested} child frame.
+Setting it to @code{nil} restores the frame's status as a top-level
+frame---a frame whose window-system window is a child of its display's
+root window.@footnote{On Haiku, child frames are only visible when a
+parent frame is active, owing to a limitation of the Haiku windowing
+system. Owing to the same limitation, child frames are only
+guaranteed to appear above their top-level parent; that is to say, the
+top-most frame in the hierarchy, which does not have a parent frame.}
Since child frames can be arbitrarily nested, a frame can be both a
child and a parent frame. Also, the relative roles of child and parent
@@ -3905,6 +3942,47 @@ For backward compatibility, there are obsolete aliases
names of @code{gui-get-selection} and @code{gui-set-selection} before
Emacs 25.1.
+@node Yanking Media
+@section Yanking Media
+
+ If you choose, for instance, ``Copy Image'' in a web browser, that
+image is put onto the clipboard, and Emacs can access it via
+@code{gui-get-selection}. But in general, inserting image data into
+an arbitrary buffer isn't very useful---you can't really do much with
+it by default.
+
+ So Emacs has a system to let modes register handlers for these
+``complicated'' selections.
+
+@defun yank-media-handler types handler
+@var{types} can be a @acronym{MIME} media type symbol, a regexp to
+match these, or a list of these symbols and regexps. For instance:
+
+@example
+(yank-media-handler 'text/html #'my-html-handler)
+(yank-media-handler "image/.*" #'my-image-handler)
+@end example
+
+A mode can register as many handlers as required.
+
+ The @var{handler} function is called with two parameters: The
+@acronym{MIME} media type symbol and the data (as a string). The
+handler should then insert the object into the buffer, or save it, or
+do whatever is appropriate for the mode.
+@end defun
+
+ The @code{yank-media} command will consult the registered handlers in
+the current buffer, compare that with the available media types on the
+clipboard, and then pass on the matching selection to the handler (if
+any). If there's more than one matching selection, the user is
+queried first.
+
+ The @code{yank-media-types} command can be used to explore the
+clipboard/primary selection. It lists all the media types that are
+currently available, and can be handy when creating handlers---to see
+what data is actually available. Some applications put a surprising
+amount of different data types on the clipboard.
+
@node Drag and Drop
@section Drag and Drop
@cindex drag and drop
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index 77d1465c876..46a1e57ea58 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -378,7 +378,7 @@ keyword @code{&rest} before one final argument.
@group
(@var{required-vars}@dots{}
@r{[}&optional @r{[}@var{optional-vars}@dots{}@r{]}@r{]}
- @r{[}&rest @r{[}@var{rest-var}@r{]}@r{]})
+ @r{[}&rest @var{rest-var}@r{]})
@end group
@end example
@@ -826,12 +826,20 @@ This function returns a new function which, when called, will call
@var{func} with the list of arguments composed from @var{args} and
additional arguments specified at the time of the call. If @var{func}
accepts @var{n} arguments, then a call to @code{apply-partially} with
-@w{@code{@var{m} < @var{n}}} arguments will produce a new function of
-@w{@code{@var{n} - @var{m}}} arguments.
+@w{@code{@var{m} <= @var{n}}} arguments will produce a new function of
+@w{@code{@var{n} - @var{m}}} arguments@footnote{
+If the number of arguments that @var{func} can accept is unlimited,
+then the new function will also accept an unlimited number of
+arguments, so in that case @code{apply-partially} doesn't reduce the
+number of arguments that the new function could accept.
+}.
Here's how we could define the built-in function @code{1+}, if it
didn't exist, using @code{apply-partially} and @code{+}, another
-built-in function:
+built-in function@footnote{
+Note that unlike the built-in function, this version accepts any
+number of arguments.
+}:
@example
@group
@@ -902,11 +910,11 @@ length of @var{sequence}. For example:
@example
@group
-(mapcar 'car '((a b) (c d) (e f)))
+(mapcar #'car '((a b) (c d) (e f)))
@result{} (a c e)
-(mapcar '1+ [1 2 3])
+(mapcar #'1+ [1 2 3])
@result{} (2 3 4)
-(mapcar 'string "abc")
+(mapcar #'string "abc")
@result{} ("a" "b" "c")
@end group
@@ -922,14 +930,14 @@ Return the list of results."
;; @r{If no list is exhausted,}
(if (not (memq nil args))
;; @r{apply function to @sc{car}s.}
- (cons (apply function (mapcar 'car args))
- (apply 'mapcar* function
+ (cons (apply function (mapcar #'car args))
+ (apply #'mapcar* function
;; @r{Recurse for rest of elements.}
- (mapcar 'cdr args)))))
+ (mapcar #'cdr args)))))
@end group
@group
-(mapcar* 'cons '(a b c) '(1 2 3 4))
+(mapcar* #'cons '(a b c) '(1 2 3 4))
@result{} ((a . 1) (b . 2) (c . 3))
@end group
@end example
@@ -946,10 +954,10 @@ the results (which must be lists), by altering the results (using
@example
@group
;; @r{Contrast this:}
-(mapcar 'list '(a b c d))
+(mapcar #'list '(a b c d))
@result{} ((a) (b) (c) (d))
;; @r{with this:}
-(mapcan 'list '(a b c d))
+(mapcan #'list '(a b c d))
@result{} (a b c d)
@end group
@end example
@@ -961,14 +969,14 @@ side-effects only---the values it returns are ignored, not collected
into a list. @code{mapc} always returns @var{sequence}.
@end defun
-@defun mapconcat function sequence separator
+@defun mapconcat function sequence &optional separator
@code{mapconcat} applies @var{function} to each element of
@var{sequence}; the results, which must be sequences of characters
(strings, vectors, or lists), are concatenated into a single string
return value. Between each pair of result sequences, @code{mapconcat}
inserts the characters from @var{separator}, which also must be a
-string, or a vector or list of characters. @xref{Sequences Arrays
-Vectors}.
+string, or a vector or list of characters; a @code{nil} value is
+treated as the empty string. @xref{Sequences Arrays Vectors}.
The argument @var{function} must be a function that can take one
argument and returns a sequence of characters: a string, a vector, or
@@ -978,7 +986,7 @@ string.
@example
@group
-(mapconcat 'symbol-name
+(mapconcat #'symbol-name
'(The cat in the hat)
" ")
@result{} "The cat in the hat"
@@ -986,8 +994,7 @@ string.
@group
(mapconcat (lambda (x) (format "%c" (1+ x)))
- "HAL-8000"
- "")
+ "HAL-8000")
@result{} "IBM.9111"
@end group
@end example
@@ -1443,7 +1450,7 @@ is not a function, e.g., a keyboard macro (@pxref{Keyboard Macros}):
@result{} "\^u2\^k"
@end example
-It you wish to use @code{fset} to make an alternate name for a
+If you wish to use @code{fset} to make an alternate name for a
function, consider using @code{defalias} instead. @xref{Definition of
defalias}.
@end defun
@@ -1640,9 +1647,10 @@ function will be interactive and will use the interactive spec of
@var{function}. One exception: if the interactive spec of @var{function}
is a function (i.e., a @code{lambda} expression or an @code{fbound}
symbol rather than an expression or a string), then the interactive
-spec of the combined function will be a call to that function with as sole
-argument the interactive spec of the original function. To interpret the spec
-received as argument, use @code{advice-eval-interactive-spec}.
+spec of the combined function will be a call to that function with
+the interactive spec of the original function as sole argument. To
+interpret the spec received as argument, use
+@code{advice-eval-interactive-spec}.
Note: The interactive spec of @var{function} will apply to the combined
function and should hence obey the calling convention of the combined function
diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi
index a788852de75..e7b6406fd8c 100644
--- a/doc/lispref/help.texi
+++ b/doc/lispref/help.texi
@@ -333,6 +333,13 @@ stands for no text itself. It is used only for a side effect: it
specifies @var{mapvar}'s value as the keymap for any following
@samp{\[@var{command}]} sequences in this documentation string.
+@item \`@var{KEYSEQ}'
+stands for a key sequence @var{KEYSEQ}, which will use the same face
+as a command substitution. This should be used only when a key
+sequence has no corresponding command, for example when it is read
+directly with @code{read-key-sequence}. It must be a valid key
+sequence according to @code{key-valid-p}.
+
@item `
(grave accent) stands for a left quote.
This generates a left single quotation mark, an apostrophe, or a grave
@@ -372,11 +379,15 @@ quotes. You can customize it freely according to your personal
preference.
@end defopt
-@defun substitute-command-keys string
+@defun substitute-command-keys string &optional no-face
+@vindex help-key-binding@r{ (face)}
This function scans @var{string} for the above special sequences and
replaces them by what they stand for, returning the result as a string.
This permits display of documentation that refers accurately to the
-user's own customized key bindings.
+user's own customized key bindings. By default, the key bindings are
+given a special face @code{help-key-binding}, but if the optional
+argument @var{no-face} is non-@code{nil}, the function doesn't add
+this face to the produced string.
@cindex advertised binding
If a command has multiple bindings, this function normally uses the
@@ -640,7 +651,7 @@ follows:
@smallexample
@group
-(define-key global-map (string help-char) 'help-command)
+(keymap-set global-map (key-description (string help-char)) 'help-command)
(fset 'help-command help-map)
@end group
@end smallexample
diff --git a/doc/lispref/hooks.texi b/doc/lispref/hooks.texi
index 394928454b0..e9d1e270d8e 100644
--- a/doc/lispref/hooks.texi
+++ b/doc/lispref/hooks.texi
@@ -18,11 +18,13 @@ arguments and their values are completely ignored. The recommended way
to put a new function on such a hook is to call @code{add-hook}.
@xref{Hooks}, for more information about using hooks.
-The variables whose names end in @samp{-functions} are usually @dfn{abnormal
-hooks} (some old code may also use the deprecated @samp{-hooks} suffix); their
-values are lists of functions, but these functions are called in a special way
-(they are passed arguments, or their return values are used). The variables
-whose names end in @samp{-function} have single functions as their values.
+The variables whose names end in @samp{-functions} are usually
+@dfn{abnormal hooks} (some old code may also use the deprecated
+@samp{-hooks} suffix). Their values are lists of functions, but these
+functions are called in a special way: they are either passed
+arguments, or their return values are used in some way. The variables
+whose names end in @samp{-function} have single functions as their
+values.
This is not an exhaustive list, it only covers the more general hooks.
For example, every major mode defines a hook named
@@ -262,7 +264,6 @@ after-set-visited-file-name-hook
auto-coding-functions
choose-completion-string-functions
completing-read-function
-completion-annotate-function
completion-at-point-functions
completion-list-insert-choice-function
deactivate-current-input-method-function
diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi
index 0e250d0f59b..7718712b9b8 100644
--- a/doc/lispref/internals.texi
+++ b/doc/lispref/internals.texi
@@ -218,6 +218,14 @@ the Emacs executable that dumped them.
If you want to use this function in an Emacs that was already dumped,
you must run Emacs with the @samp{-batch} option.
+
+@vindex after-pdump-load-hook
+If you're including @samp{.el} files in the dumped Emacs and that
+@samp{.el} file has code that is normally run at load time, that code
+won't be run when Emacs starts after dumping. To help work around
+that problem, you can put functions on the
+@code{after-pdump-load-hook} hook. This hook is run when starting
+Emacs.
@end defun
@defun dump-emacs to-file from-file
@@ -337,18 +345,22 @@ by the vector allocation code while iterating over the vector blocks.
It is quite common to use some storage for a while, then release it
by (for example) killing a buffer or deleting the last pointer to an
object. Emacs provides a @dfn{garbage collector} to reclaim this
-abandoned storage. The garbage collector operates by finding and
-marking all Lisp objects that are still accessible to Lisp programs.
-To begin with, it assumes all the symbols, their values and associated
-function definitions, and any data presently on the stack, are
-accessible. Any objects that can be reached indirectly through other
-accessible objects are also accessible.
+abandoned storage. The garbage collector operates, in essence, by
+finding and marking all Lisp objects that are still accessible to Lisp
+programs. To begin with, it assumes all the symbols, their values and
+associated function definitions, and any data presently on the stack,
+are accessible. Any objects that can be reached indirectly through
+other accessible objects are also accessible, but this calculation is
+done ``conservatively'', so it may slightly overestimate how many
+objects that are accessible.
When marking is finished, all objects still unmarked are garbage. No
matter what the Lisp program or the user does, it is impossible to refer
to them, since there is no longer a way to reach them. Their space
might as well be reused, since no one will miss them. The second
-(sweep) phase of the garbage collector arranges to reuse them.
+(sweep) phase of the garbage collector arranges to reuse them. (But
+since the marking was done ``conservatively'', not all unused objects
+are guaranteed to be garbage-collected by any one sweep.)
@c ??? Maybe add something describing weak hash tables here?
diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi
index 4097c86f074..edf1d6e83fd 100644
--- a/doc/lispref/keymaps.texi
+++ b/doc/lispref/keymaps.texi
@@ -30,6 +30,7 @@ is found. The whole process is called @dfn{key lookup}.
* Key Lookup:: Finding a key's binding in one keymap.
* Functions for Key Lookup:: How to request key lookup.
* Changing Key Bindings:: Redefining a key in a keymap.
+* Low-Level Key Binding:: Legacy key syntax description.
* Remapping Commands:: A keymap can translate one command to another.
* Translation Keymaps:: Keymaps for translating sequences of events.
* Key Binding Commands:: Interactive interfaces for redefining keys.
@@ -94,8 +95,15 @@ Manual}.
(kbd "<f1> SPC") @result{} [f1 32]
(kbd "C-M-<down>") @result{} [C-M-down]
@end example
+
+@findex key-valid-p
+The @code{kbd} function is very permissive, and will try to return
+something sensible even if the syntax used isn't completely
+conforming. To check whether the syntax is actually valid, use the
+@code{key-valid-p} function.
@end defun
+
@node Keymap Basics
@section Keymap Basics
@cindex key binding
@@ -359,7 +367,7 @@ I.e., something like:
@group
(let ((map (make-sparse-keymap)))
(set-keymap-parent map <theirmap>)
- (define-key map ...)
+ (keymap-set map ...)
...)
@end group
@end example
@@ -412,10 +420,10 @@ The effect is that this keymap inherits all the bindings of
but can add to them or override them with @var{elements}.
If you change the bindings in @var{parent-keymap} using
-@code{define-key} or other key-binding functions, these changed
+@code{keymap-set} or other key-binding functions, these changed
bindings are visible in the inheriting keymap, unless shadowed by the
bindings made by @var{elements}. The converse is not true: if you use
-@code{define-key} to change bindings in the inheriting keymap, these
+@code{keymap-set} to change bindings in the inheriting keymap, these
changes are recorded in @var{elements}, but have no effect on
@var{parent-keymap}.
@@ -610,16 +618,16 @@ active keymap.
@result{} nil
@end group
@group
-(local-set-key "\C-p" ctl-x-map)
+(keymap-local-set "C-p" ctl-x-map)
@result{} nil
@end group
@group
-(key-binding "\C-p\C-f")
+(keymap-binding "C-p C-f")
@result{} find-file
@end group
@group
-(key-binding "\C-p6")
+(keymap-binding "C-p 6")
@result{} nil
@end group
@end example
@@ -682,7 +690,7 @@ use, in place of the buffer's default local keymap.
@cindex major mode keymap
The local keymap is normally set by the buffer's major mode, and
every buffer with the same major mode shares the same local keymap.
-Hence, if you call @code{local-set-key} (@pxref{Key Binding Commands})
+Hence, if you call @code{keymap-local-set} (@pxref{Key Binding Commands})
to change the local keymap in one buffer, that also affects the local
keymaps in other buffers with the same major mode.
@@ -716,39 +724,7 @@ Normally it ignores @code{overriding-local-map} and
then it pays attention to them. @var{position} can optionally be either
an event position as returned by @code{event-start} or a buffer
position, and may change the keymaps as described for
-@code{key-binding}.
-@end defun
-
-@defun key-binding key &optional accept-defaults no-remap position
-This function returns the binding for @var{key} according to the
-current active keymaps. The result is @code{nil} if @var{key} is
-undefined in the keymaps.
-
-The argument @var{accept-defaults} controls checking for default
-bindings, as in @code{lookup-key} (@pxref{Functions for Key Lookup}).
-
-When commands are remapped (@pxref{Remapping Commands}),
-@code{key-binding} normally processes command remappings so as to
-return the remapped command that will actually be executed. However,
-if @var{no-remap} is non-@code{nil}, @code{key-binding} ignores
-remappings and returns the binding directly specified for @var{key}.
-
-If @var{key} starts with a mouse event (perhaps following a prefix
-event), the maps to be consulted are determined based on the event's
-position. Otherwise, they are determined based on the value of point.
-However, you can override either of them by specifying @var{position}.
-If @var{position} is non-@code{nil}, it should be either a buffer
-position or an event position like the value of @code{event-start}.
-Then the maps consulted are determined based on @var{position}.
-
-Emacs signals an error if @var{key} is not a string or a vector.
-
-@example
-@group
-(key-binding "\C-x\C-f")
- @result{} find-file
-@end group
-@end example
+@code{keymap-binding}.
@end defun
@node Searching Keymaps
@@ -821,7 +797,7 @@ out with.
This function returns the current global keymap. This is the same as
the value of @code{global-map} unless you change one or the other.
The return value is a reference, not a copy; if you use
-@code{define-key} or other functions on it you will alter global
+@code{keymap-set} or other functions on it you will alter global
bindings.
@example
@@ -857,7 +833,7 @@ keymap.
@end defun
@code{current-local-map} returns a reference to the local keymap, not
-a copy of it; if you use @code{define-key} or other functions on it
+a copy of it; if you use @code{keymap-set} or other functions on it
you will alter local bindings.
@defun current-minor-mode-maps
@@ -1025,7 +1001,7 @@ keymap.
Let's use the term @dfn{keymap entry} to describe the value found by
looking up an event type in a keymap. (This doesn't include the item
string and other extra elements in a keymap element for a menu item, because
-@code{lookup-key} and other key lookup functions don't include them in
+@code{keymap-lookup} and other key lookup functions don't include them in
the returned value.) While any Lisp object may be stored in a keymap
as a keymap entry, not all make sense for key lookup. Here is a table
of the meaningful types of keymap entries:
@@ -1176,7 +1152,7 @@ Used in keymaps to undefine keys. It calls @code{ding}, but does
not cause an error.
@end deffn
-@defun local-key-binding key &optional accept-defaults
+@defun keymap-local-binding key &optional accept-defaults
This function returns the binding for @var{key} in the current
local keymap, or @code{nil} if it is undefined there.
@@ -1184,7 +1160,7 @@ The argument @var{accept-defaults} controls checking for default bindings,
as in @code{lookup-key} (above).
@end defun
-@defun global-key-binding key &optional accept-defaults
+@defun keymap-global-binding key &optional accept-defaults
This function returns the binding for command @var{key} in the
current global keymap, or @code{nil} if it is undefined there.
@@ -1267,51 +1243,63 @@ change a binding in the global keymap, the change is effective in all
buffers (though it has no direct effect in buffers that shadow the
global binding with a local one). If you change the current buffer's
local map, that usually affects all buffers using the same major mode.
-The @code{global-set-key} and @code{local-set-key} functions are
+The @code{keymap-global-set} and @code{keymap-local-set} functions are
convenient interfaces for these operations (@pxref{Key Binding
-Commands}). You can also use @code{define-key}, a more general
+Commands}). You can also use @code{keymap-set}, a more general
function; then you must explicitly specify the map to change.
When choosing the key sequences for Lisp programs to rebind, please
follow the Emacs conventions for use of various keys (@pxref{Key
Binding Conventions}).
-@cindex meta character key constants
-@cindex control character key constants
- In writing the key sequence to rebind, it is good to use the special
-escape sequences for control and meta characters (@pxref{String Type}).
-The syntax @samp{\C-} means that the following character is a control
-character and @samp{\M-} means that the following character is a meta
-character. Thus, the string @code{"\M-x"} is read as containing a
-single @kbd{M-x}, @code{"\C-f"} is read as containing a single
-@kbd{C-f}, and @code{"\M-\C-x"} and @code{"\C-\M-x"} are both read as
-containing a single @kbd{C-M-x}. You can also use this escape syntax in
-vectors, as well as others that aren't allowed in strings; one example
-is @samp{[?\C-\H-x home]}. @xref{Character Type}.
-
- The key definition and lookup functions accept an alternate syntax for
-event types in a key sequence that is a vector: you can use a list
-containing modifier names plus one base event (a character or function
-key name). For example, @code{(control ?a)} is equivalent to
-@code{?\C-a} and @code{(hyper control left)} is equivalent to
-@code{C-H-left}. One advantage of such lists is that the precise
-numeric codes for the modifier bits don't appear in compiled files.
-
The functions below signal an error if @var{keymap} is not a keymap,
-or if @var{key} is not a string or vector representing a key sequence.
-You can use event types (symbols) as shorthand for events that are
-lists. The @code{kbd} function (@pxref{Key Sequences}) is a
-convenient way to specify the key sequence.
+or if @var{key} is not a valid key.
+
+@var{key} is a string representing a single key or a series of key
+strokes. Key strokes are separated by a single space character.
+
+Each key stroke is either a single character, or the name of an
+event, surrounded by angle brackets. In addition, any key stroke
+may be preceded by one or more modifier keys. Finally, a limited
+number of characters have a special shorthand syntax. Here's some
+example key sequences:
+
+@table @kbd
+@item f
+The key @kbd{f}.
+
+@item S o m
+A three key sequence of the keys @kbd{S}, @kbd{o} and @kbd{m}.
+
+@item C-c o
+A two key sequence of the keys @kbd{c} with the control modifier and
+then the key @kbd{o}
+
+@item H-<left>
+The key named @kbd{left} with the hyper modifier.
+
+@item M-RET
+The @kbd{return} key with a meta modifier.
+
+@item C-M-<space>
+The @kbd{space} key with both the control and meta modifiers.
+@end table
+
+The only keys that have a special shorthand syntax are @kbd{NUL},
+@kbd{RET}, @kbd{TAB}, @kbd{LFD}, @kbd{ESC}, @kbd{SPC} and @kbd{DEL}.
-@defun define-key keymap key binding
+The modifiers have to be specified in alphabetical order:
+@samp{A-C-H-M-S-s}, which is @samp{Alt-Control-Hyper-Meta-Shift-super}.
+
+@defun keymap-set keymap key binding
This function sets the binding for @var{key} in @var{keymap}. (If
@var{key} is more than one event long, the change is actually made
in another keymap reached from @var{keymap}.) The argument
@var{binding} can be any Lisp object, but only certain types are
meaningful. (For a list of meaningful types, see @ref{Key Lookup}.)
-The value returned by @code{define-key} is @var{binding}.
+The value returned by @code{keymap-set} is @var{binding}.
-If @var{key} is @code{[t]}, this sets the default binding in
+If @var{key} is @kbd{<t>}, this sets the default binding in
@var{keymap}. When an event has no binding of its own, the Emacs
command loop uses the keymap's default binding, if there is one.
@@ -1319,7 +1307,7 @@ command loop uses the keymap's default binding, if there is one.
@cindex key sequence error
Every prefix of @var{key} must be a prefix key (i.e., bound to a keymap)
or undefined; otherwise an error is signaled. If some prefix of
-@var{key} is undefined, then @code{define-key} defines it as a prefix
+@var{key} is undefined, then @code{keymap-set} defines it as a prefix
key so that the rest of @var{key} can be defined as specified.
If there was previously no binding for @var{key} in @var{keymap}, the
@@ -1337,7 +1325,7 @@ bindings in it:
@result{} (keymap)
@end group
@group
-(define-key map "\C-f" 'forward-char)
+(keymap-set map "C-f" 'forward-char)
@result{} forward-char
@end group
@group
@@ -1347,7 +1335,7 @@ map
@group
;; @r{Build sparse submap for @kbd{C-x} and bind @kbd{f} in that.}
-(define-key map (kbd "C-x f") 'forward-word)
+(keymap-set map "C-x f" 'forward-word)
@result{} forward-word
@end group
@group
@@ -1360,14 +1348,14 @@ map
@group
;; @r{Bind @kbd{C-p} to the @code{ctl-x-map}.}
-(define-key map (kbd "C-p") ctl-x-map)
+(keymap-set map "C-p" ctl-x-map)
;; @code{ctl-x-map}
@result{} [nil @dots{} find-file @dots{} backward-kill-sentence]
@end group
@group
;; @r{Bind @kbd{C-f} to @code{foo} in the @code{ctl-x-map}.}
-(define-key map (kbd "C-p C-f") 'foo)
+(keymap-set map "C-p C-f" 'foo)
@result{} 'foo
@end group
@group
@@ -1386,6 +1374,99 @@ changing an entry in @code{ctl-x-map}, and this has the effect of
changing the bindings of both @kbd{C-p C-f} and @kbd{C-x C-f} in the
default global map.
+@defun define-keymap &key options... &rest pairs...
+@code{keymap-set} is the general work horse for defining a key in a
+keymap. When writing modes, however, you frequently have to bind a
+large number of keys at once, and using @code{keymap-set} on them all
+can be tedious and error-prone. Instead you can use
+@code{define-keymap}, which creates a keymaps and binds a number of
+keys. Here's a very basic example:
+
+@lisp
+(define-keymap
+ "n" #'forward-line
+ "f" #'previous-line
+ "C-c C-c" #'quit-window)
+@end lisp
+
+This function creates a new sparse keymap, defines the two keystrokes
+in @var{pairs}, and returns the new keymap.
+
+@var{pairs} is a list of alternating key bindings and key definitions,
+as accepted by @code{keymap-set}. In addition the key can be the
+special symbol @code{:menu}, in which case the definition should be a
+menu definition as accepted by @code{easy-menu-define} (@pxref{Easy
+Menu}). Here's a brief example:
+
+@lisp
+(define-keymap :full t
+ "g" #'eww-reload
+ :menu '("Eww"
+ ["Exit" quit-window t]
+ ["Reload" eww-reload t]))
+@end lisp
+
+A number of keywords can be used before the key/definition pairs to
+changes features of the new keymap. If the keyword is missing, the
+default value for the feature is @code{nil}. Here's a list of the
+available keywords:
+
+@table @code
+@item :full
+If non-@code{nil}, create a chartable keymap (as from
+@code{make-keymap}) instead of a sparse keymap (as from
+@code{make-sparse-keymap} (@pxref{Creating Keymaps}). A sparse keymap
+is the default.
+
+@item :parent
+If non-@code{nil}, this should be a keymap to use as the parent
+(@pxref{Inheritance and Keymaps}).
+
+@item :keymap
+If non-@code{nil}, this should be a keymap. Instead of creating a new
+keymap, this keymap is modified instead.
+
+@item :suppress
+If non-@code{nil}, the keymap will be suppressed with
+@code{suppress-keymap} (@pxref{Changing Key Bindings}). If
+@code{nodigits}, treat digits like other chars.
+
+@item :name
+If non-@code{nil}, this should be a string to use as the menu for the
+keymap if you use it as a menu with @code{x-popup-menu} (@pxref{Pop-Up
+Menus}).
+
+@item :prefix
+If non-@code{nil}, this should be a symbol to be used as a prefix
+command (@pxref{Prefix Keys}). If this is the case, this symbol is
+returned by @code{define-keymap} instead of the map itself.
+@end table
+
+@end defun
+
+@defmac defvar-keymap name &key options... &rest pairs...
+By far, the most common thing to do with a keymap is to bind it to a
+variable. This is what virtually all modes do---a mode called
+@code{foo} almost always has a variable called @code{foo-mode-map}.
+
+This macro defines @var{name} as a variable, and passes @var{options}
+and @var{pars} to @code{define-keymap}, and uses the result as the
+default value for the variable.
+
+@var{options} is like the keywords in @code{define-keymap}, but adds a
+@code{:doc} keyword that says what the doc string for the @var{name}
+variable should be.
+
+Here's an example:
+
+@lisp
+(defvar-keymap eww-textarea-map
+ :parent text-mode-map
+ "RET" #'forward-line
+ "TAB" #'shr-next-link)
+@end lisp
+@end defmac
+
The function @code{substitute-key-definition} scans a keymap for
keys that have a certain binding and rebinds them with a different
binding. Another feature which is cleaner and can often produce the
@@ -1485,13 +1566,181 @@ Modes}); then its keymap will automatically inherit from
(defvar special-mode-map
(let ((map (make-sparse-keymap)))
(suppress-keymap map)
- (define-key map "q" 'quit-window)
+ (keymap-set map "q" 'quit-window)
@dots{}
map))
@end group
@end smallexample
@end defun
+@node Low-Level Key Binding
+@section Low-Level Key Binding
+@cindex low-level key bindings
+
+ Historically, Emacs has supported a number of different syntaxes for
+defining keys. The documented way to bind a key today is to use the
+syntax supported by @code{key-valid-p}, which is what all the
+functions like @code{keymap-set} and @code{keymap-lookup} supports.
+This section documents the old-style syntax and interface functions;
+they should not be used in new code.
+
+@cindex meta character key constants
+@cindex control character key constants
+ @code{define-key} (and other low-level functions that are used to
+rebind keys) understand a number of different syntaxes for the keys.
+
+@table @asis
+@item A vector containing lists of keys.
+You can use a list containing modifier names plus one base event (a
+character or function key name). For example, @code{[(control ?a)
+(meta b)]} is equivalent to @kbd{C-a M-b} and @code{[(hyper control
+left)]} is equivalent to @kbd{C-H-left}.
+
+@item A string of characters with modifiers
+Internally, key sequences are often represented as strings using the
+special escape sequences for shift, control and meta modifiers
+(@pxref{String Type}), but this representation can also be used by
+users when rebinding keys. A string like @code{"\M-x"} is read as
+containing a single @kbd{M-x}, @code{"\C-f"} is read as containing a
+single @kbd{C-f}, and @code{"\M-\C-x"} and @code{"\C-\M-x"} are both
+read as containing a single @kbd{C-M-x}.
+
+@item A vector of characters and key symbols
+This is the other internal representation of key sequences. It
+supports a fuller range of modifiers than the string representation,
+and also support function keys. An example is @w{@samp{[?\C-\H-x
+home]}}, which represents the @w{@kbd{C-H-x @key{home}}} key sequence.
+@xref{Character Type}.
+@end table
+
+@defun define-key keymap key binding &optional remove
+This function is like @code{keymap-set} (@pxref{Changing Key
+Bindings}, but understands only the legacy key syntaxes.
+
+In addition, this function also has a @var{remove} argument. If it is
+non-@code{nil}, the definition will be removed. This is almost the
+same as setting the definition to @code{nil}, but makes a difference
+if the @var{keymap} has a parent, and @var{key} is shadowing the same
+binding in the parent. With @var{remove}, subsequent lookups will
+return the binding in the parent, and with a nil @var{def}, the
+lookups will return @code{nil}.
+@end defun
+
+Here are other legacy key definition functions and commands, with the
+equivalent modern function to use instead in new code.
+
+@deffn Command global-set-key key binding
+This function sets the binding of @var{key} in the current global map
+to @var{binding}. Use @code{keymap-global-set} instead.
+@end deffn
+
+@deffn Command global-unset-key key
+This function removes the binding of @var{key} from the current
+global map. Use @code{keymap-global-unset} instead.
+@end deffn
+
+@deffn Command local-set-key key binding
+This function sets the binding of @var{key} in the current local
+keymap to @var{binding}. Use @code{keymap-local-set} instead.
+@end deffn
+
+@deffn Command local-unset-key key
+This function removes the binding of @var{key} from the current
+local map. Use @code{keymap-local-unset} instead.
+@end deffn
+
+@defun substitute-key-definition olddef newdef keymap &optional oldmap
+This function replaces @var{olddef} with @var{newdef} for any keys in
+@var{keymap} that were bound to @var{olddef}. In other words,
+@var{olddef} is replaced with @var{newdef} wherever it appears. The
+function returns @code{nil}. Use @code{keymap-substitute} instead.
+@end defun
+
+@defun define-key-after map key binding &optional after
+Define a binding in @var{map} for @var{key}, with value @var{binding},
+just like @code{define-key}, but position the binding in @var{map} after
+the binding for the event @var{after}. The argument @var{key} should be
+of length one---a vector or string with just one element. But
+@var{after} should be a single event type---a symbol or a character, not
+a sequence. The new binding goes after the binding for @var{after}. If
+@var{after} is @code{t} or is omitted, then the new binding goes last, at
+the end of the keymap. However, new bindings are added before any
+inherited keymap. Use @code{keymap-set-after} instead of this function.
+@end defun
+
+@defun keyboard-translate from to
+This function modifies @code{keyboard-translate-table} to translate
+character code @var{from} into character code @var{to}. It creates
+the keyboard translate table if necessary. Use @code{key-translate}
+instead.
+@end defun
+
+@defun key-binding key &optional accept-defaults no-remap position
+This function returns the binding for @var{key} according to the
+current active keymaps. The result is @code{nil} if @var{key} is
+undefined in the keymaps. The argument @var{accept-defaults} controls
+checking for default bindings, as in @code{lookup-key}
+(@pxref{Functions for Key Lookup}). If @var{no-remap} is
+non-@code{nil}, @code{key-binding} ignores command remappings
+(@pxref{Remapping Commands}) and returns the binding directly
+specified for @var{key}. The optional argument @var{position} should
+be either a buffer position or an event position like the value of
+@code{event-start}; it tells the function to consult the maps
+determined based on that @var{position}.
+
+Emacs signals an error if @var{key} is not a string or a vector.
+
+Use @code{keymap-lookup} instead of this function.
+@end defun
+
+@defun lookup-key keymap key &optional accept-defaults
+This function returns the definition of @var{key} in @var{keymap}. If
+the string or vector @var{key} is not a valid key sequence according
+to the prefix keys specified in @var{keymap}, it must be too long and
+have extra events at the end that do not fit into a single key
+sequence. Then the value is a number, the number of events at the
+front of @var{key} that compose a complete key.
+
+If @var{accept-defaults} is non-@code{nil}, then @code{lookup-key}
+considers default bindings as well as bindings for the specific events
+in @var{key}. Otherwise, @code{lookup-key} reports only bindings for
+the specific sequence @var{key}, ignoring default bindings except when
+you explicitly ask about them.
+
+Use @code{keymap-lookup} instead of this function.
+@end defun
+
+@defun local-key-binding key &optional accept-defaults
+This function returns the binding for @var{key} in the current
+local keymap, or @code{nil} if it is undefined there.
+
+The argument @var{accept-defaults} controls checking for default bindings,
+as in @code{lookup-key} (above).
+@end defun
+
+@defun global-key-binding key &optional accept-defaults
+This function returns the binding for command @var{key} in the
+current global keymap, or @code{nil} if it is undefined there.
+
+The argument @var{accept-defaults} controls checking for default bindings,
+as in @code{lookup-key} (above).
+@end defun
+
+@defun event-convert-list list
+This function converts a list of modifier names and a basic event type
+to an event type which specifies all of them. The basic event type
+must be the last element of the list. For example,
+
+@example
+(event-convert-list '(control ?a))
+ @result{} 1
+(event-convert-list '(control meta ?a))
+ @result{} -134217727
+(event-convert-list '(control super f1))
+ @result{} C-s-f1
+@end example
+@end defun
+
@node Remapping Commands
@section Remapping Commands
@cindex remapping commands
@@ -1510,7 +1759,7 @@ definition for a key binding).
the following remapping:
@smallexample
-(define-key my-mode-map [remap kill-line] 'my-kill-line)
+(keymap-set my-mode-map "<remap> <kill-line>" 'my-kill-line)
@end smallexample
@noindent
@@ -1525,8 +1774,8 @@ In addition, remapping only works through a single level; in the
following example,
@smallexample
-(define-key my-mode-map [remap kill-line] 'my-kill-line)
-(define-key my-mode-map [remap my-kill-line] 'my-other-kill-line)
+(keymap-set my-mode-map "<remap> <kill-line>" 'my-kill-line)
+(keymap-set my-mode-map "<remap> <my-kill-line>" 'my-other-kill-line)
@end smallexample
@noindent
@@ -1538,7 +1787,7 @@ remapped to @code{my-kill-line}; if an ordinary binding specifies
To undo the remapping of a command, remap it to @code{nil}; e.g.,
@smallexample
-(define-key my-mode-map [remap kill-line] nil)
+(keymap-set my-mode-map "<remap> <kill-line>" nil)
@end smallexample
@defun command-remapping command &optional position keymaps
@@ -1670,7 +1919,7 @@ to turn the character that follows into a Hyper character:
symbol
(cons symbol (cdr e)))))
-(define-key local-function-key-map "\C-ch" 'hyperify)
+(keymap-set local-function-key-map "C-c h" 'hyperify)
@end group
@end example
@@ -1700,34 +1949,20 @@ problematic suffixes/prefixes are @kbd{@key{ESC}}, @kbd{M-O} (which is really
@section Commands for Binding Keys
This section describes some convenient interactive interfaces for
-changing key bindings. They work by calling @code{define-key}.
+changing key bindings. They work by calling @code{keymap-set}.
- People often use @code{global-set-key} in their init files
+ People often use @code{keymap-global-set} in their init files
(@pxref{Init File}) for simple customization. For example,
@smallexample
-(global-set-key (kbd "C-x C-\\") 'next-line)
-@end smallexample
-
-@noindent
-or
-
-@smallexample
-(global-set-key [?\C-x ?\C-\\] 'next-line)
-@end smallexample
-
-@noindent
-or
-
-@smallexample
-(global-set-key [(control ?x) (control ?\\)] 'next-line)
+(keymap-global-set "C-x C-\\" 'next-line)
@end smallexample
@noindent
redefines @kbd{C-x C-\} to move down a line.
@smallexample
-(global-set-key [M-mouse-1] 'mouse-set-point)
+(keymap-global-set "M-<mouse-1>" 'mouse-set-point)
@end smallexample
@noindent
@@ -1741,14 +1976,7 @@ they usually will be in a Lisp file (@pxref{Loading Non-ASCII}), you
must type the keys as multibyte too. For instance, if you use this:
@smallexample
-(global-set-key "ö" 'my-function) ; bind o-umlaut
-@end smallexample
-
-@noindent
-or
-
-@smallexample
-(global-set-key ?ö 'my-function) ; bind o-umlaut
+(keymap-global-set "ö" 'my-function) ; bind o-umlaut
@end smallexample
@noindent
@@ -1759,20 +1987,20 @@ binding, you need to teach Emacs how to decode the keyboard by using an
appropriate input method (@pxref{Input Methods, , Input Methods, emacs, The GNU
Emacs Manual}).
-@deffn Command global-set-key key binding
+@deffn Command keymap-global-set key binding
This function sets the binding of @var{key} in the current global map
to @var{binding}.
@smallexample
@group
-(global-set-key @var{key} @var{binding})
+(keymap-global-set @var{key} @var{binding})
@equiv{}
-(define-key (current-global-map) @var{key} @var{binding})
+(keymap-set (current-global-map) @var{key} @var{binding})
@end group
@end smallexample
@end deffn
-@deffn Command global-unset-key key
+@deffn Command keymap-global-unset key
@cindex unbinding keys
This function removes the binding of @var{key} from the current
global map.
@@ -1783,50 +2011,32 @@ that uses @var{key} as a prefix---which would not be allowed if
@smallexample
@group
-(global-unset-key "\C-l")
+(keymap-global-unset "C-l")
@result{} nil
@end group
@group
-(global-set-key "\C-l\C-l" 'redraw-display)
+(keymap-global-set "C-l C-l" 'redraw-display)
@result{} nil
@end group
@end smallexample
-
-This function is equivalent to using @code{define-key} as follows:
-
-@smallexample
-@group
-(global-unset-key @var{key})
-@equiv{}
-(define-key (current-global-map) @var{key} nil)
-@end group
-@end smallexample
@end deffn
-@deffn Command local-set-key key binding
+@deffn Command keymap-local-set key binding
This function sets the binding of @var{key} in the current local
keymap to @var{binding}.
@smallexample
@group
-(local-set-key @var{key} @var{binding})
+(keymap-local-set @var{key} @var{binding})
@equiv{}
-(define-key (current-local-map) @var{key} @var{binding})
+(keymap-set (current-local-map) @var{key} @var{binding})
@end group
@end smallexample
@end deffn
-@deffn Command local-unset-key key
+@deffn Command keymap-local-unset key
This function removes the binding of @var{key} from the current
local map.
-
-@smallexample
-@group
-(local-unset-key @var{key})
-@equiv{}
-(define-key (current-local-map) @var{key} nil)
-@end group
-@end smallexample
@end deffn
@node Scanning Keymaps
@@ -2227,6 +2437,12 @@ This property specifies that @var{string} is the string to display
as the keyboard equivalent for this menu item. You can use
the @samp{\\[...]} documentation construct in @var{string}.
+This property can also be a function (which will be called with no
+arguments). This function should return a string. This function will
+be called every time the menu is computed, so using a function that
+takes a lot of time to compute is not a good idea, and it should
+expect to be called from any context.
+
@item :filter @var{filter-fn}
This property provides a way to compute the menu item dynamically.
The property value @var{filter-fn} should be a function of one argument;
@@ -2675,9 +2891,9 @@ using an indirection through @code{tool-bar-map}.
By default, the global map binds @code{[tool-bar]} as follows:
@example
-(global-set-key [tool-bar]
- `(menu-item ,(purecopy "tool bar") ignore
- :filter tool-bar-make-keymap))
+(keymap-global-set "<tool-bar>"
+ `(menu-item ,(purecopy "tool bar") ignore
+ :filter tool-bar-make-keymap))
@end example
@noindent
diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi
index bbe1dce42d8..f98ae76da9a 100644
--- a/doc/lispref/lists.texi
+++ b/doc/lispref/lists.texi
@@ -679,6 +679,20 @@ list are in the same order as in @var{tree}.
@result{}(1 2 3 4 5 6 7)
@end example
+@defun ensure-list object
+This function returns @var{object} as a list. If @var{object} is
+already a list, the function returns it; otherwise, the function
+returns a one-element list containing @var{object}.
+
+This is usually useful if you have a variable that may or may not be a
+list, and you can then say, for instance:
+
+@lisp
+(dolist (elem (ensure-list foo))
+ (princ elem))
+@end lisp
+@end defun
+
@defun number-sequence from &optional to separation
This function returns a list of numbers starting with @var{from} and
incrementing by @var{separation}, and ending at or just before
@@ -1213,13 +1227,13 @@ this is not guaranteed to happen):
@cindex lists as sets
@cindex sets
- A list can represent an unordered mathematical set---simply consider a
-value an element of a set if it appears in the list, and ignore the
-order of the list. To form the union of two sets, use @code{append} (as
-long as you don't mind having duplicate elements). You can remove
-@code{equal} duplicates using @code{delete-dups}. Other useful
-functions for sets include @code{memq} and @code{delq}, and their
-@code{equal} versions, @code{member} and @code{delete}.
+ A list can represent an unordered mathematical set---simply consider
+a value an element of a set if it appears in the list, and ignore the
+order of the list. To form the union of two sets, use @code{append}
+(as long as you don't mind having duplicate elements). You can remove
+@code{equal} duplicates using @code{delete-dups} or @code{seq-uniq}.
+Other useful functions for sets include @code{memq} and @code{delq},
+and their @code{equal} versions, @code{member} and @code{delete}.
@cindex CL note---lack @code{union}, @code{intersection}
@quotation
@@ -1475,7 +1489,8 @@ comparison.
This function destructively removes all @code{equal} duplicates from
@var{list}, stores the result in @var{list} and returns it. Of
several @code{equal} occurrences of an element in @var{list},
-@code{delete-dups} keeps the first one.
+@code{delete-dups} keeps the first one. See @code{seq-uniq} for
+non-destructive operation (@pxref{Sequence Functions}).
@end defun
See also the function @code{add-to-list}, in @ref{List Variables},
diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi
index 4d683da1ad3..ee119445e56 100644
--- a/doc/lispref/loading.texi
+++ b/doc/lispref/loading.texi
@@ -552,7 +552,7 @@ An autoloaded keymap loads automatically during key lookup when a prefix
key's binding is the symbol @var{function}. Autoloading does not occur
for other kinds of access to the keymap. In particular, it does not
happen when a Lisp program gets the keymap from the value of a variable
-and calls @code{define-key}; not even if the variable name is the same
+and calls @code{keymap-set}; not even if the variable name is the same
symbol @var{function}.
@cindex function cell in autoload
@@ -1156,7 +1156,7 @@ You don't need to give a directory or extension in the file name
@var{library}. Normally, you just give a bare file name, like this:
@example
-(with-eval-after-load "js" (define-key js-mode-map "\C-c\C-c" 'js-eval))
+(with-eval-after-load "js" (keymap-set js-mode-map "C-c C-c" 'js-eval))
@end example
To restrict which files can trigger the evaluation, include a
diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi
index d54c654562f..281e987e7f1 100644
--- a/doc/lispref/minibuf.texi
+++ b/doc/lispref/minibuf.texi
@@ -2209,7 +2209,7 @@ Here is an example:
@smallexample
@group
-(yes-or-no-p "Do you really want to remove everything? ")
+(yes-or-no-p "Do you really want to remove everything?")
;; @r{After evaluation of the preceding expression,}
;; @r{the following prompt appears,}
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index d9caeab3bc3..69c022e5253 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -59,12 +59,13 @@ runs just before Emacs suspends itself (@pxref{Suspending Emacs}).
@cindex abnormal hook
If the hook variable's name does not end with @samp{-hook}, that
-indicates it is probably an @dfn{abnormal hook}. That means the hook
-functions are called with arguments, or their return values are used
-in some way. The hook's documentation says how the functions are
-called. Any functions added to an abnormal hook must follow the
-hook's calling convention. By convention, abnormal hook names end in
-@samp{-functions}.
+indicates it is probably an @dfn{abnormal hook}. These differ from
+normal hooks in two ways: they can be called with one or more
+arguments, and their return values can be used in some way. The
+hook's documentation says how the functions are called and how their
+return values are used. Any functions added to an abnormal hook must
+follow the hook's calling convention. By convention, abnormal hook
+names end in @samp{-functions}.
@cindex single-function hook
If the name of the variable ends in @samp{-predicate} or
@@ -268,6 +269,18 @@ normal-mode}), but tries to force it not to choose any modes in
@var{avoided-modes}, if that argument is non-@code{nil}.
@end defun
+@defun clean-mode
+Changing the major mode clears out most local variables, but it
+doesn't remove all artefacts in the buffer (like text properties and
+overlays). It's rare to change a buffer from one major mode to
+another (except from @code{fundamental-mode} to everything else), so
+this is usually not a concern. It can sometimes be convenient (mostly
+when debugging a problem in a buffer) to do a ``full reset'' of the
+buffer, and that's what the @code{clean-mode} major mode offers. It
+will kill all local variables (even the permanently local ones), and
+also removes all overlays and text properties.
+@end defun
+
The easiest way to write a major mode is to use the macro
@code{define-derived-mode}, which sets up the new mode as a variant of
an existing major mode. @xref{Derived Modes}. We recommend using
@@ -471,6 +484,22 @@ Each face that the mode defines should, if possible, inherit from an
existing Emacs face. @xref{Basic Faces}, and @ref{Faces for Font Lock}.
@item
+Consider adding a mode-specific menu to the menu bar. This should
+preferably include the most important menu-specific settings and
+commands that will allow users discovering the main features quickly
+and efficiently.
+
+@item
+@cindex context menus, for a major mode
+@vindex context-menu-functions
+Consider adding mode-specific context menus for the mode, to be used
+if and when users activate the @code{context-menu-mode} (@pxref{Menu
+Mouse Clicks,,, emacs, The Emacs Manual}). To this end, define a
+mode-specific function which builds one or more menus depending on the
+location of the @kbd{mouse-3} click in the buffer, and then add that
+function to the buffer-local value of @code{context-menu-functions}.
+
+@item
The mode should specify how Imenu should find the definitions or
sections of a buffer, by setting up a buffer-local value for the
variable @code{imenu-generic-expression}, for the two variables
@@ -887,10 +916,8 @@ which in turn may have been changed in a mode hook.
Here is a hypothetical example:
@example
-(defvar hypertext-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [down-mouse-3] 'do-hyper-link)
- map))
+(defvar-keymap hypertext-mode-map
+ "<down-mouse-3>" #'do-hyper-link)
(define-derived-mode hypertext-mode
text-mode "Hypertext"
@@ -1121,10 +1148,11 @@ re-sorting entries. Comparison is done with @code{equal}.
@item
@var{contents} is a vector with the same number of elements as
@code{tabulated-list-format}. Each vector element is either a string,
-which is inserted into the buffer as-is, or a list @code{(@var{label}
-. @var{properties})}, which means to insert a text button by calling
-@code{insert-text-button} with @var{label} and @var{properties} as
-arguments (@pxref{Making Buttons}).
+which is inserted into the buffer as-is; an image descriptor, which is
+used to insert an image (@pxref{Image Descriptors}); or a list
+@w{@code{(@var{label} . @var{properties})}}, which means to insert a
+text button by calling @code{insert-text-button} with @var{label} and
+@var{properties} as arguments (@pxref{Making Buttons}).
There should be no newlines in any of these strings.
@end itemize
@@ -1314,11 +1342,9 @@ the conventions listed above:
;; @r{Create the keymap for this mode.}
@group
-(defvar text-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\e\t" 'ispell-complete-word)
- @dots{}
- map)
+(defvar-keymap text-mode-map
+ "C-M-i" #'ispell-complete-word
+ @dots{})
"Keymap for `text-mode'.
Many other modes, such as `mail-mode', `outline-mode' and
`indented-text-mode', inherit all the commands defined in this map.")
@@ -1391,13 +1417,11 @@ common. The following code sets up the common commands:
@smallexample
@group
-(defvar lisp-mode-shared-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map prog-mode-map)
- (define-key map "\e\C-q" 'indent-sexp)
- (define-key map "\177" 'backward-delete-char-untabify)
- map)
- "Keymap for commands shared by all sorts of Lisp modes.")
+(defvar-keymap lisp-mode-shared-map
+ :parent prog-mode-map
+ :doc "Keymap for commands shared by all sorts of Lisp modes."
+ "C-M-q" #'indent-sexp
+ "DEL" #'backward-delete-char-untabify)
@end group
@end smallexample
@@ -1406,16 +1430,12 @@ And here is the code to set up the keymap for Lisp mode:
@smallexample
@group
-(defvar lisp-mode-map
- (let ((map (make-sparse-keymap))
- (menu-map (make-sparse-keymap "Lisp")))
- (set-keymap-parent map lisp-mode-shared-map)
- (define-key map "\e\C-x" 'lisp-eval-defun)
- (define-key map "\C-c\C-z" 'run-lisp)
- @dots{}
- map)
- "Keymap for ordinary Lisp mode.
-All commands in `lisp-mode-shared-map' are inherited by this map.")
+(defvar-keymap lisp-mode-map
+ :doc "Keymap for ordinary Lisp mode.
+All commands in `lisp-mode-shared-map' are inherited by this map."
+ :parent lisp-mode-shared-map
+ "C-M-x" #'lisp-eval-defun
+ "C-c C-z" #'run-lisp)
@end group
@end smallexample
@@ -3299,6 +3319,11 @@ This function tells Font Lock mode to run the Lisp function
current buffer. It calls @var{function} before calling the default
fontification functions, and gives it two arguments, @var{start} and
@var{end}, which specify the region to be fontified or refontified.
+If @var{function} performs fontifications, it can return a list of the
+form @w{@code{(jit-lock-bounds @var{beg} . @var{end})}}, to indicate
+the bounds of the region it actually fontified; JIT font-lock will use
+this information to optimize subsequent redisplay cycles and regions
+of buffer text it will pass to future calls to @var{function}.
The optional argument @var{contextual}, if non-@code{nil}, forces Font
Lock mode to always refontify a syntactically relevant part of the
diff --git a/doc/lispref/nonascii.texi b/doc/lispref/nonascii.texi
index c22930d624e..24117b50014 100644
--- a/doc/lispref/nonascii.texi
+++ b/doc/lispref/nonascii.texi
@@ -459,7 +459,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/Unicode12.1.0/ch04.pdf, Character
+@uref{https://www.unicode.org/versions/Unicode14.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
@@ -1048,9 +1048,9 @@ Alternativnyj, and KOI8.
Every coding system specifies a particular set of character code
conversions, but the coding system @code{undecided} is special: it
leaves the choice unspecified, to be chosen heuristically for each
-file, based on the file's data. The coding system @code{prefer-utf-8}
-is like @code{undecided}, but it prefers to choose @code{utf-8} when
-possible.
+file or string, based on the file's or string's data, when they are
+decoded or encoded. The coding system @code{prefer-utf-8} is like
+@code{undecided}, but it prefers to choose @code{utf-8} when possible.
In general, a coding system doesn't guarantee roundtrip identity:
decoding a byte sequence using a coding system, then encoding the
@@ -1921,9 +1921,24 @@ length of the decoded text. If that buffer is a unibyte buffer
the decoded text (@pxref{Text Representations}) is inserted into the
buffer as individual bytes.
+@cindex @code{charset}, text property on buffer text
This command puts a @code{charset} text property on the decoded text.
The value of the property states the character set used to decode the
original text.
+
+@cindex undecided coding-system, when decoding
+This command detects the encoding of the text if necessary. If
+@var{coding-system} is @code{undecided}, the command detects the
+encoding of the text based on the byte sequences it finds in the text,
+and also detects the type of end-of-line convention used by the text
+(@pxref{Lisp and Coding Systems, eol type}). If @var{coding-system}
+is @code{undecided-@var{eol-type}}, where @var{eol-type} is
+@code{unix}, @code{dos}, or @code{mac}, then the command detects only
+the encoding of the text. Any @var{coding-system} that doesn't
+specify @var{eol-type}, as in @code{utf-8}, causes the command to
+detect the end-of-line convention; specify the encoding completely, as
+in @code{utf-8-unix}, if the EOL convention used by the text is known
+in advance, to prevent any automatic detection.
@end deffn
@defun decode-coding-string string coding-system &optional nocopy buffer
@@ -1936,13 +1951,16 @@ trivial. To make explicit decoding useful, the contents of
values, but a multibyte string is also acceptable (assuming it
contains 8-bit bytes in their multibyte form).
+This function detects the encoding of the string if needed, like
+@code{decode-coding-region} does.
+
If optional argument @var{buffer} specifies a buffer, the decoded text
is inserted in that buffer after point (point does not move). In this
case, the return value is the length of the decoded text. If that
buffer is a unibyte buffer, the internal representation of the decoded
text is inserted into it as individual bytes.
-@cindex @code{charset}, text property
+@cindex @code{charset}, text property on strings
This function puts a @code{charset} text property on the decoded text.
The value of the property states the character set used to decode the
original text:
@@ -1988,7 +2006,9 @@ for decoding keyboard input from @var{terminal}. If
@var{coding-system} is @code{nil}, that means not to decode keyboard
input. If @var{terminal} is a frame, it means that frame's terminal;
if it is @code{nil}, that means the currently selected frame's
-terminal. @xref{Multiple Terminals}.
+terminal. @xref{Multiple Terminals}. Note that on modern MS-Windows
+systems Emacs always uses Unicode input when decoding keyboard input,
+so the encoding set by this command has no effect on Windows.
@end deffn
@defun terminal-coding-system &optional terminal
diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi
index 365d5ac8d61..bbd3973f61b 100644
--- a/doc/lispref/objects.texi
+++ b/doc/lispref/objects.texi
@@ -516,9 +516,9 @@ codes for these non-@acronym{ASCII} control characters include the
2**26
@end ifnottex
bit as well as the code for the corresponding non-control character.
-Ordinary text terminals have no way of generating non-@acronym{ASCII}
-control characters, but you can generate them straightforwardly using
-X and other window systems.
+Not all text terminals can generate non-@acronym{ASCII} control
+characters, but it is straightforward to generate them using X and
+other window systems.
For historical reasons, Emacs treats the @key{DEL} character as
the control equivalent of @kbd{?}:
@@ -588,8 +588,8 @@ character is upper case or lower case. Emacs uses the
2**25
@end ifnottex
bit to indicate that the shift key was used in typing a control
-character. This distinction is possible only when you use X terminals
-or other special terminals; ordinary text terminals do not report the
+character. This distinction is possible only on a graphical display
+such as a GUI display on X; text terminals do not report the
distinction. The Lisp syntax for the shift bit is @samp{\S-}; thus,
@samp{?\C-\S-o} or @samp{?\C-\S-O} represents the shifted-control-o
character.
@@ -1535,6 +1535,7 @@ editing.
* Keymap Type:: What function a keystroke invokes.
* Overlay Type:: How an overlay is represented.
* Font Type:: Fonts for displaying text.
+* Xwidget Type:: Embeddable widgets.
@end menu
@node Buffer Type
@@ -1625,19 +1626,18 @@ markers.
@node Window Type
@subsection Window Type
- A @dfn{window} describes the portion of the terminal screen that Emacs
-uses to display a buffer. Every window has one associated buffer, whose
-contents appear in the window. By contrast, a given buffer may appear
-in one window, no window, or several windows.
+ A @dfn{window} describes the portion of the screen that Emacs uses to
+display buffers. Every live window (@pxref{Basic Windows}) has one
+associated buffer, whose contents appear in that window. By contrast, a
+given buffer may appear in one window, no window, or several windows.
+Windows are grouped on the screen into frames; each window belongs to
+one and only one frame. @xref{Frame Type}.
Though many windows may exist simultaneously, at any time one window
-is designated the @dfn{selected window}. This is the window where the
-cursor is (usually) displayed when Emacs is ready for a command. The
-selected window usually displays the current buffer (@pxref{Current
-Buffer}), but this is not necessarily the case.
-
- Windows are grouped on the screen into frames; each window belongs to
-one and only one frame. @xref{Frame Type}.
+is designated the @dfn{selected window} (@pxref{Selecting Windows}).
+This is the window where the cursor is (usually) displayed when Emacs is
+ready for a command. The selected window usually displays the current
+buffer (@pxref{Current Buffer}), but this is not necessarily the case.
Windows have no read syntax. They print in hash notation, giving the
window number and the name of the buffer being displayed. The window
@@ -1861,6 +1861,20 @@ syntax looks like @samp{#<font-object>}, @samp{#<font-spec>}, and
@samp{#<font-entity>} respectively. @xref{Low-Level Font}, for a
description of these Lisp objects.
+@node Xwidget Type
+@subsection Xwidget Type
+@cindex xwidget type
+@cindex xwidget-view type
+
+ An @dfn{xwidget} is a special display element, such as a web
+browser, that can be embedded inside a buffer. Each window that
+displays an xwidget will also have an @dfn{xwidget view}, which on
+X-Windows corresponds to a single X window used to display the widget.
+
+Neither of these objects are readable; their print syntaxes look like
+@samp{#<xwidget>} and @samp{#<xwidget-view>}, respectively.
+@xref{Xwidgets}, for a more detailed description of xwidgets.
+
@node Circular Objects
@section Read Syntax for Circular Objects
@cindex circular structure, read syntax
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index 12ddaf04b6a..de76ab4884a 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -813,7 +813,7 @@ Here is an example of how you could use these hooks:
@smallexample
@group
(add-hook 'suspend-hook
- (lambda () (or (y-or-n-p "Really suspend? ")
+ (lambda () (or (y-or-n-p "Really suspend?")
(error "Suspend canceled"))))
@end group
(add-hook 'suspend-resume-hook (lambda () (message "Resumed!")
@@ -947,6 +947,9 @@ actually Linux is just the kernel, not the whole system.)
@item gnu/kfreebsd
A GNU (glibc-based) system with a FreeBSD kernel.
+@item haiku
+The Haiku operating system, a derivative of the Be Operating System.
+
@item hpux
Hewlett-Packard HPUX operating system.
@@ -1042,6 +1045,21 @@ that variable with @code{let} is also reasonable practice.
if it removed @var{variable} from the environment.
@end deffn
+@defmac with-environment-variables variables body@dots{}
+This macro sets the environment variables according to @var{variables}
+temporarily when executing @var{body}. The previous values are
+restored when the form finishes. The argument @var{variables} should
+be a list of pairs of strings of the form
+@w{@code{(@var{var} @var{value})}}, where @var{var} is the name of the
+environment variable and @var{value} is that variable's value.
+
+@lisp
+(with-environment-variables (("LANG" "C")
+ ("LANGUAGE" "en_US:en"))
+ (call-process "ls" nil t))
+@end lisp
+@end defmac
+
@defvar process-environment
This variable is a list of strings, each describing one environment
variable. The functions @code{getenv} and @code{setenv} work by means
@@ -1334,7 +1352,7 @@ may change as higher-resolution clocks become available.
@cindex time value
Function arguments, e.g., the @var{time} argument to
-@code{current-time-string}, accept a more-general @dfn{time value}
+@code{format-time-string}, accept a more-general @dfn{time value}
format, which can be a Lisp timestamp, @code{nil} for the current
time, a single floating-point number for seconds, or a list
@code{(@var{high} @var{low} @var{micro})} or @code{(@var{high}
@@ -1489,10 +1507,7 @@ The optional @var{form} argument specifies the timestamp form to be
returned. If @var{form} is the symbol @code{integer}, this function
returns an integer count of seconds. If @var{form} is a positive
integer, it specifies a clock frequency and this function returns an
-integer-pair timestamp @code{(@var{ticks}
-. @var{form})}.@footnote{Currently a positive integer @var{form}
-should be at least 65536 if the returned value is intended to be given
-to standard functions expecting Lisp timestamps.} If @var{form} is
+integer-pair timestamp @code{(@var{ticks} . @var{form})}. If @var{form} is
@code{t}, this function treats it as a positive integer suitable for
representing the timestamp; for example, it is treated as 1000000000
if @var{time} is nil and the platform timestamp has nanosecond
@@ -1706,7 +1721,8 @@ This function parses the time-string @var{string} and returns the
corresponding Lisp timestamp. The argument @var{string} should represent
a date-time, and should be in one of the forms recognized by
@code{parse-time-string} (see below). This function assumes Universal
-Time if @var{string} lacks explicit time zone information.
+Time if @var{string} lacks explicit time zone information,
+and assumes earliest values if @var{string} lacks month, day, or time.
The operating system limits the range of time and zone values.
@end defun
@@ -2165,7 +2181,13 @@ In most cases, @var{repeat} has no effect on when @emph{first} call
takes place---@var{time} alone specifies that. There is one exception:
if @var{time} is @code{t}, then the timer runs whenever the time is a
multiple of @var{repeat} seconds after the epoch. This is useful for
-functions like @code{display-time}.
+functions like @code{display-time}. For instance, the following will
+make @var{function} run at every ``whole'' minute (e.g.,
+@samp{11:03:00}, @samp{11:04:00}, etc):
+
+@example
+(run-at-time t 60 @var{function})
+@end example
If Emacs didn't get any CPU time when the timer would have run (for
example if the system was busy running another process or if the
@@ -3109,8 +3131,9 @@ watch for file attribute changes, like permissions or modification
time
@end table
-If @var{file} is a directory, changes for all files in that directory
-will be notified. This does not work recursively.
+If @var{file} is a directory, @code{change} watches for file creation
+or deletion in that directory. Some of the file notification backends
+report also file changes. This does not work recursively.
When any event happens, Emacs will call the @var{callback} function
passing it a single argument @var{event}, which is of the form
@@ -3215,6 +3238,14 @@ Removes an existing file watch specified by its @var{descriptor}.
@code{file-notify-add-watch}.
@end defun
+@deffn Command file-notify-rm-all-watches
+Removes all existing file notification watches from Emacs.
+
+Use this command with caution, because it could have unexpected side
+effects on packages relying on file watches. It is intended mainly
+for debugging purposes, or when Emacs has been stalled.
+@end deffn
+
@defun file-notify-valid-p descriptor
Checks a watch specified by its @var{descriptor} for validity.
@var{descriptor} should be an object returned by
diff --git a/doc/lispref/package.texi b/doc/lispref/package.texi
index 9c033fe3df8..aeb455bb25f 100644
--- a/doc/lispref/package.texi
+++ b/doc/lispref/package.texi
@@ -17,6 +17,11 @@ put it in a @dfn{package archive} for others to download.
@xref{Packages,,, emacs, The GNU Emacs Manual}, for a description of
user-level features of the packaging system.
+ These sections are mostly directed towards package archive
+maintainers---much of this information is not relevant for package
+authors (i.e., people who write code that will be distributed via
+these archives).
+
@menu
* Packaging Basics:: The basic concepts of Emacs Lisp packages.
* Simple Packages:: How to package a single .el file.
diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi
index 90c42156372..ac5d4d16277 100644
--- a/doc/lispref/processes.texi
+++ b/doc/lispref/processes.texi
@@ -966,6 +966,15 @@ use the function @code{process-tty-name} (@pxref{Process
Information}).
@end defvar
+@defvar process-error-pause-time
+If a process sentinel/filter function has an error, Emacs will (by
+default) pause Emacs for @code{process-error-pause-time} seconds after
+displaying this error, so that users will see the error in question.
+However, this can lead to situations where Emacs becomes unresponsive
+(if there's a lot of these errors happening), so this can be disabled
+by setting @code{process-error-pause-time} to 0.
+@end defvar
+
@node Deleting Processes
@section Deleting Processes
@cindex deleting processes
@@ -1047,6 +1056,19 @@ This function returns a list of all processes that have not been deleted.
@end smallexample
@end defun
+@defun num-processors &optional query
+This function returns the number of processors, a positive integer.
+Each usable thread execution unit counts as a processor.
+By default, the count includes the number of available processors,
+which you can override by setting the
+@url{https://www.openmp.org/spec-html/5.1/openmpse59.html,
+@env{OMP_NUM_THREADS} environment variable of OpenMP}.
+If the optional argument @var{query} is @code{current},
+this function ignores @env{OMP_NUM_THREADS};
+if @var{query} is @code{all}, this function also counts processors
+that are on the system but are not available to the current process.
+@end defun
+
@defun get-process name
This function returns the process named @var{name} (a string), or
@code{nil} if there is none. The argument @var{name} can also be a
@@ -1766,9 +1788,12 @@ or more batches of output; one way to do this is to insert the
received text into a temporary buffer, which can then be searched.
@defun set-process-filter process filter
-This function gives @var{process} the filter function @var{filter}. If
-@var{filter} is @code{nil}, it gives the process the default filter,
-which inserts the process output into the process buffer.
+This function gives @var{process} the filter function @var{filter}.
+If @var{filter} is @code{nil}, it gives the process the default
+filter, which inserts the process output into the process buffer. If
+@var{filter} is @code{t}, Emacs stops accepting output from the
+process, unless it's a network server process that listens for
+incoming connections.
@end defun
@defun process-filter process
diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi
index 4d5ae3cb437..296ce20169c 100644
--- a/doc/lispref/searching.texi
+++ b/doc/lispref/searching.texi
@@ -263,6 +263,7 @@ case-sensitive.
* Rx Notation:: An alternative, structured regexp notation.
@end ifnottex
* Regexp Functions:: Functions for operating on regular expressions.
+* Regexp Problems:: Some problems and how they may be avoided.
@end menu
@node Syntax of Regexps
@@ -343,15 +344,6 @@ first tries to match all three @samp{a}s; but the rest of the pattern is
The next alternative is for @samp{a*} to match only two @samp{a}s. With
this choice, the rest of the regexp matches successfully.
-@strong{Warning:} Nested repetition operators can run for a very
-long time, if they lead to ambiguous matching. For
-example, trying to match the regular expression @samp{\(x+y*\)*a}
-against the string @samp{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz} could
-take hours before it ultimately fails. Emacs may try each way of
-grouping the @samp{x}s before concluding that none of them can work.
-In general, avoid expressions that can match the same string in
-multiple ways.
-
@item @samp{+}
@cindex @samp{+} in regexp
is a postfix operator, similar to @samp{*} except that it must match
@@ -1060,7 +1052,8 @@ customization.
The various forms in @code{rx} regexps are described below. The
shorthand @var{rx} represents any @code{rx} form, and @var{rx}@dots{}
-means zero or more @code{rx} forms. Where the corresponding string
+means zero or more @code{rx} forms. These are all valid arguments to
+the @code{rx} macro. Where the corresponding string
regexp syntax is given, @var{A}, @var{B}, @dots{} are string regexp
subexpressions.
@@ -1356,7 +1349,8 @@ names:
For details, @pxref{Syntax Class Table}. Please note that
@code{(syntax punctuation)} is @emph{not} equivalent to the character class
@code{punctuation}.@*
-Corresponding string regexp: @samp{\s@var{code}}
+Corresponding string regexp: @samp{\s@var{char}} where @var{char} is the
+syntax character.
@item @code{(category @var{category})}
@cindex @code{category} in rx
@@ -1413,7 +1407,8 @@ the names below or its category character.
For more information about currently defined categories, run the
command @kbd{M-x describe-categories @key{RET}}. For how to define
new categories, @pxref{Categories}.@*
-Corresponding string regexp: @samp{\c@var{code}}
+Corresponding string regexp: @samp{\c@var{char}} where @var{char} is the
+category character.
@end table
@subsubheading Zero-width assertions
@@ -1543,11 +1538,18 @@ in the current global environment.
@node Rx Functions
@subsubsection Functions and macros using @code{rx} regexps
-@defmac rx rx-expr@dots{}
-Translate the @var{rx-expr}s to a string regexp, as if they were the
+@defmac rx rx-form@dots{}
+Translate the @var{rx-form}s to a string regexp, as if they were the
body of a @code{(seq @dots{})} form. The @code{rx} macro expands to a
string constant, or, if @code{literal} or @code{regexp} forms are
-used, a Lisp expression that evaluates to a string.
+used, a Lisp expression that evaluates to a string. Example:
+
+@example
+@group
+(rx (+ alpha) "=" (+ digit))
+ @result{} "[[:alpha:]]+=[[:digit:]]+"
+@end group
+@end example
@end defmac
@defun rx-to-string rx-expr &optional no-group
@@ -1555,6 +1557,14 @@ Translate @var{rx-expr} to a string regexp which is returned.
If @var{no-group} is absent or nil, bracket the result in a
non-capturing group, @samp{\(?:@dots{}\)}, if necessary to ensure that
a postfix operator appended to it will apply to the whole expression.
+Example:
+
+@example
+@group
+(rx-to-string '(seq (+ alpha) "=" (+ digit)) t)
+ @result{} "[[:alpha:]]+=[[:digit:]]+"
+@end group
+@end example
Arguments to @code{literal} and @code{regexp} forms in @var{rx-expr}
must be string literals.
@@ -1649,6 +1659,24 @@ extra actual argument values not matched by any other parameter in
Since the definition is global, it is recommended to give @var{name} a
package prefix to avoid name clashes with definitions elsewhere, as is
usual when naming non-local variables and functions.
+
+Forms defined this way only perform simple template substitution.
+For arbitrary computations, use them together with the @code{rx}
+forms @code{eval}, @code{regexp} or @code{literal}. Example:
+
+@example
+@group
+(defun n-tuple-rx (n element)
+ `(seq "<"
+ (group-n 1 ,element)
+ ,@@(mapcar (lambda (i) `(seq ?, (group-n ,i ,element)))
+ (number-sequence 2 n))
+ ">"))
+(rx-define n-tuple (n element) (eval (n-tuple-rx n 'element)))
+(rx (n-tuple 3 (+ (in "0-9"))))
+ @result{} "<\\(?1:[0-9]+\\),\\(?2:[0-9]+\\),\\(?3:[0-9]+\\)>"
+@end group
+@end example
@end defmac
@defmac rx-let (bindings@dots{}) body@dots{}
@@ -1848,6 +1876,73 @@ variables that may be set to a pattern that actually matches
something.
@end defvar
+@node Regexp Problems
+@subsection Problems with Regular Expressions
+@cindex regular expression problems
+@cindex regexp stack overflow
+@cindex stack overflow in regexp
+
+The Emacs regexp implementation, like many of its kind, is generally
+robust but occasionally causes trouble in either of two ways: matching
+may run out of internal stack space and signal an error, and it can
+take a long time to complete. The advice below will make these
+symptoms less likely and help alleviate problems that do arise.
+
+@itemize
+@item
+Anchor regexps at the beginning of a line, string or buffer using
+zero-width assertions (@samp{^} and @code{\`}). This takes advantage
+of fast paths in the implementation and can avoid futile matching
+attempts. Other zero-width assertions may also bring benefits by
+causing a match to fail early.
+
+@item
+Avoid or-patterns in favour of character alternatives: write
+@samp{[ab]} instead of @samp{a\|b}. Recall that @samp{\s-} and @samp{\sw}
+are equivalent to @samp{[[:space:]]} and @samp{[[:word:]]}, respectively.
+
+@item
+Since the last branch of an or-pattern does not add a backtrack point
+on the stack, consider putting the most likely matched pattern last.
+For example, @samp{^\(?:a\|.b\)*c} will run out of stack if trying to
+match a very long string of @samp{a}s, but the equivalent
+@samp{^\(?:.b\|a\)*c} will not.
+
+(It is a trade-off: successfully matched or-patterns run faster with
+the most frequently matched pattern first.)
+
+@item
+Try to ensure that any part of the text can only match in a single
+way. For example, @samp{a*a*} will match the same set of strings as
+@samp{a*}, but the former can do so in many ways and will therefore
+cause slow backtracking if the match fails later on. Make or-pattern
+branches mutually exclusive if possible, so that matching will not go
+far into more than one branch before failing.
+
+Be especially careful with nested repetitions: they can easily result
+in very slow matching in the presence of ambiguities. For example,
+@samp{\(?:a*b*\)+c} will take a long time attempting to match even a
+moderately long string of @samp{a}s before failing. The equivalent
+@samp{\(?:a\|b\)*c} is much faster, and @samp{[ab]*c} better still.
+
+@item
+Don't use capturing groups unless they are really needed; that is, use
+@samp{\(?:@dots{}\)} instead of @samp{\(@dots{}\)} for bracketing
+purposes.
+
+@ifnottex
+@item
+Consider using @code{rx} (@pxref{Rx Notation}); it can optimise some
+or-patterns automatically and will never introduce capturing groups
+unless explicitly requested.
+@end ifnottex
+@end itemize
+
+If you run into regexp stack overflow despite following the above
+advice, don't be afraid of performing the matching in multiple
+function calls, each using a simpler regexp where backtracking can
+more easily be contained.
+
@node Regexp Search
@section Regular Expression Searching
@cindex regular expression searching
@@ -1950,7 +2045,7 @@ feature for matching regular expressions from end to beginning. It's
not worth the trouble of implementing that.
@end deffn
-@defun string-match regexp string &optional start
+@defun string-match regexp string &optional start inhibit-modify
This function returns the index of the start of the first match for
the regular expression @var{regexp} in @var{string}, or @code{nil} if
there is no match. If @var{start} is non-@code{nil}, the search starts
@@ -1975,8 +2070,10 @@ For example,
The index of the first character of the
string is 0, the index of the second character is 1, and so on.
-If this function finds a match, the index of the first character beyond
-the match is available as @code{(match-end 0)}. @xref{Match Data}.
+By default, if this function finds a match, the index of the first
+character beyond the match is available as @code{(match-end 0)}.
+@xref{Match Data}. If @var{inhibit-modify} is non-@code{nil}, the
+match data isn't modified.
@example
@group
@@ -1997,16 +2094,18 @@ This predicate function does what @code{string-match} does, but it
avoids modifying the match data.
@end defun
-@defun looking-at regexp
+@defun looking-at regexp &optional inhibit-modify
This function determines whether the text in the current buffer directly
following point matches the regular expression @var{regexp}. ``Directly
following'' means precisely that: the search is ``anchored'' and it can
succeed only starting with the first character following point. The
result is @code{t} if so, @code{nil} otherwise.
-This function does not move point, but it does update the match data.
-@xref{Match Data}. If you need to test for a match without modifying
-the match data, use @code{looking-at-p}, described below.
+This function does not move point, but it does update the match data
+(if @var{inhibit-modify} is @code{nil} or missing, which is the
+default). @xref{Match Data}. As a convenience, instead of using the
+@var{inhibit-modify} argument, you can use @code{looking-at-p},
+described below.
In this example, point is located directly before the @samp{T}. If it
were anywhere else, the result would be @code{nil}.
@@ -2113,13 +2212,13 @@ backtracking specified by the POSIX standard for regular expression
matching.
@end deffn
-@defun posix-looking-at regexp
+@defun posix-looking-at regexp &optional inhibit-modify
This is like @code{looking-at} except that it performs the full
backtracking specified by the POSIX standard for regular expression
matching.
@end defun
-@defun posix-string-match regexp string &optional start
+@defun posix-string-match regexp string &optional start inhibit-modify
This is like @code{string-match} except that it performs the full
backtracking specified by the POSIX standard for regular expression
matching.
@@ -2602,9 +2701,9 @@ replacement string. The match data at this point are the result
of matching @var{regexp} against a substring of @var{string}.
@end defun
-@defun string-replace fromstring tostring instring
-This function replaces all occurrences of @var{fromstring} with
-@var{tostring} in @var{instring} and returns the result. It may
+@defun string-replace from-string to-string in-string
+This function replaces all occurrences of @var{from-string} with
+@var{to-string} in @var{in-string} and returns the result. It may
return one of its arguments unchanged, a constant string or a new
string. Case is significant, and text properties are ignored.
@end defun
diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index 20816ce8ca2..4a48d62f6db 100644
--- a/doc/lispref/sequences.texi
+++ b/doc/lispref/sequences.texi
@@ -953,6 +953,24 @@ contain less elements than @var{n}. @var{n} must be an integer. If
@end example
@end defun
+@defun seq-union sequence1 sequence2 &optional function
+@cindex sequences, union of
+@cindex union of sequences
+ This function returns a list of the elements that appear either in
+@var{sequence1} or @var{sequence2}. The elements of the returned list
+are all unique, in the sense that no two elements there will compare
+equal. If the optional argument @var{function} is non-@code{nil}, it
+should be a function of two arguments to use to compare elements,
+instead of the default @code{equal}.
+
+@example
+@group
+(seq-union [1 2 3] [3 5])
+@result{} (1 2 3 5)
+@end group
+@end example
+@end defun
+
@defun seq-intersection sequence1 sequence2 &optional function
@cindex sequences, intersection of
@cindex intersection of sequences
diff --git a/doc/lispref/spellfile b/doc/lispref/spellfile
index 45a122d26ac..11a6ce813af 100644
--- a/doc/lispref/spellfile
+++ b/doc/lispref/spellfile
@@ -179,6 +179,8 @@ copyleft
counterintuitive
cr
creatable
+customization
+customizations
customize
deactivate
deactivated
@@ -243,6 +245,8 @@ fmakunbound
fo
fol
following'
+fontification
+fontified
fooba
foobaz
foox
@@ -257,6 +261,7 @@ garbles
gc
getenv
gid
+glyphs
gp
grep
gtr
@@ -270,6 +275,8 @@ hostname
hpux
hscroll
ick
+iconified
+iconify
id
idiom
ii
@@ -314,6 +321,7 @@ mathsurround
memq
mh
mini
+minibuf
minibuffer's
minibuffers
misalignment
@@ -387,6 +395,7 @@ passwd
ped
perverse
pid
+pixelwise
plist
pointer'
pointm
@@ -417,6 +426,10 @@ reader'
rebind
rec
rechecking
+redisplay
+redisplayed
+redisplaying
+redisplays
redo
redrawing
redraws
@@ -430,6 +443,7 @@ reinitialize
reinitialized
reinstall
reinstalled
+resizable
resize
resized
resizes
@@ -486,6 +500,8 @@ terpri
text'
tildes
time's
+tooltip
+tooltips
towards
transportable
txt
@@ -494,6 +510,7 @@ unbind
unbinding
unbinds
unclutters
+uncustomized
undefine
undefines
underfull
@@ -520,6 +537,7 @@ vconcat
vectorp
vn
voidness
+whitespace
window'
windowing
windowp
diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi
index b4d7bc729f5..0914f204113 100644
--- a/doc/lispref/strings.texi
+++ b/doc/lispref/strings.texi
@@ -402,7 +402,7 @@ Remove the trailing text that matches @var{regexp} from @var{string}.
@defun string-trim string &optional trim-left trim-right
Remove the leading text that matches @var{trim-left} and trailing text
-that matches @var{trim-right} from from @var{string}. Both regexps
+that matches @var{trim-right} from @var{string}. Both regexps
default to @samp{[ \t\n\r]+}.
@end defun
@@ -414,18 +414,24 @@ will not be shortened.
@end defun
@defun string-limit string length &optional end coding-system
-If @var{string} is shorter than @var{length}, @var{string} is returned
-as is. Otherwise, return a substring of @var{string} consisting of
-the first @var{length} characters. If the optional @var{end}
-parameter is given, return a string of the @var{length} last
+If @var{string} is shorter than @var{length} characters, @var{string}
+is returned as is. Otherwise, return a substring of @var{string}
+consisting of the first @var{length} characters. If the optional
+@var{end} parameter is given, return a string of the @var{length} last
characters instead.
If @var{coding-system} is non-@code{nil}, @var{string} will be encoded
before limiting, and the result will be a unibyte string that's
-shorter than @code{length}. If @var{string} contains characters that
-are encoded into several bytes (for instance, when using
+shorter than @code{length} bytes. If @var{string} contains characters
+that are encoded into several bytes (for instance, when using
@code{utf-8}), the resulting unibyte string is never truncated in the
middle of a character representation.
+
+This function measures the string length in characters or bytes, and
+thus is generally inappropriate if you need to shorten strings for
+display purposes; use @code{truncate-string-to-width} or
+@code{window-text-pixel-size} or @code{string-glyph-split} instead
+(@pxref{Size of Displayed Text}).
@end defun
@defun string-lines string &optional omit-nulls
diff --git a/doc/lispref/symbols.texi b/doc/lispref/symbols.texi
index ed36f5139a8..b30a16927ec 100644
--- a/doc/lispref/symbols.texi
+++ b/doc/lispref/symbols.texi
@@ -29,6 +29,9 @@ otherwise.
* Creating Symbols:: How symbols are kept unique.
* Symbol Properties:: Each symbol has a property list
for recording miscellaneous information.
+* Shorthands:: Properly organize your symbol names but
+ type less of them.
+
@end menu
@node Symbol Components
@@ -67,7 +70,10 @@ important not to have two symbols with the same name. The Lisp reader
ensures this: every time it reads a symbol, it looks for an existing
symbol with the specified name before it creates a new one. To get a
symbol's name, use the function @code{symbol-name} (@pxref{Creating
-Symbols}).
+Symbols}). However, although each symbol has only one unique
+@emph{print name}, it is nevertheless possible to refer to that same
+symbol via different alias names called ``shorthands''
+(@pxref{Shorthands}).
The value cell holds a symbol's value as a variable, which is what
you get if the symbol itself is evaluated as a Lisp expression.
@@ -166,26 +172,39 @@ definitions. @xref{Name Help,,, emacs, The GNU Emacs Manual}.
@section Creating and Interning Symbols
@cindex reading symbols
- To understand how symbols are created in GNU Emacs Lisp, you must know
-how Lisp reads them. Lisp must ensure that it finds the same symbol
-every time it reads the same set of characters. Failure to do so would
-cause complete confusion.
+ To understand how symbols are created in GNU Emacs Lisp, you must
+know how Lisp reads them. Lisp must ensure that it finds the same
+symbol every time it reads the same sequence of characters in the same
+context. Failure to do so would cause complete confusion.
@cindex symbol name hashing
@cindex hashing
@cindex obarray
@cindex bucket (in obarray)
- When the Lisp reader encounters a symbol, it reads all the characters
-of the name. Then it hashes those characters to find an index in a
-table called an @dfn{obarray}. Hashing is an efficient method of
-looking something up. For example, instead of searching a telephone
-book cover to cover when looking up Jan Jones, you start with the J's
-and go from there. That is a simple version of hashing. Each element
-of the obarray is a @dfn{bucket} which holds all the symbols with a
-given hash code; to look for a given name, it is sufficient to look
-through all the symbols in the bucket for that name's hash code. (The
-same idea is used for general Emacs hash tables, but they are a
-different data type; see @ref{Hash Tables}.)
+ When the Lisp reader encounters a name that references a symbol in
+the source code, it reads all the characters of that name. Then it
+looks up that name in a table called an @dfn{obarray} to find the
+symbol that the programmer meant. The technique used in this lookup
+is called ``hashing'', an efficient method of looking something up by
+converting a sequence of characters to a number, known as a ``hash
+code''. For example, instead of searching a telephone book cover to
+cover when looking up Jan Jones, you start with the J's and go from
+there. That is a simple version of hashing. Each element of the
+obarray is a @dfn{bucket} which holds all the symbols with a given
+hash code; to look for a given name, it is sufficient to look through
+all the symbols in the bucket for that name's hash code. (The same
+idea is used for general Emacs hash tables, but they are a different
+data type; see @ref{Hash Tables}.)
+
+When looking up names, the Lisp reader also considers ``shorthands''.
+If the programmer supplied them, this allows the reader to find a
+symbol even if its name isn't present in its full form in the source
+code. Of course, the reader needs to be aware of some pre-established
+context about such shorthands, much as one needs context to be to able
+to refer uniquely to Jan Jones by just the name ``Jan'': it's probably
+fine when amongst the Joneses, or when Jan has been mentioned
+recently, but very ambiguous in any other situation.
+@xref{Shorthands}.
@cindex interning
If a symbol with the desired name is found, the reader uses that
@@ -200,9 +219,13 @@ same obarray. Thus, the reader gets the same symbols for the same
names, as long as you keep reading with the same obarray.
Interning usually happens automatically in the reader, but sometimes
-other programs need to do it. For example, after the @kbd{M-x} command
-obtains the command name as a string using the minibuffer, it then
-interns the string, to get the interned symbol with that name.
+other programs may want to do it. For example, after the @kbd{M-x}
+command obtains the command name as a string using the minibuffer, it
+then interns the string, to get the interned symbol with that name.
+As another example, a hypothetical telephone book program could intern
+the name of each looked up person's name as a symbol, even if the
+obarray did not contain it, so that it could attach information to
+that new symbol, such as the last time someone looked it up.
@cindex symbol equality
@cindex uninterned symbol
@@ -210,11 +233,8 @@ interns the string, to get the interned symbol with that name.
obarray. They are called @dfn{uninterned symbols}. An uninterned
symbol has the same four cells as other symbols; however, the only way
to gain access to it is by finding it in some other object or as the
-value of a variable.
-
- Creating an uninterned symbol is useful in generating Lisp code,
-because an uninterned symbol used as a variable in the code you generate
-cannot clash with any variables used in other Lisp programs.
+value of a variable. Uninterned symbols are sometimes useful in
+generating Lisp code, see below.
In Emacs Lisp, an obarray is actually a vector. Each element of the
vector is a bucket; its value is either an interned symbol whose name
@@ -236,7 +256,10 @@ not work---only @code{intern} can enter a symbol in an obarray properly.
@cindex CL note---symbol in obarrays
@quotation
@b{Common Lisp note:} Unlike Common Lisp, Emacs Lisp does not provide
-for interning a single symbol in several obarrays.
+for interning the same name in several different ``packages'', thus
+creating multiple symbols with the same name but different packages.
+Emacs Lisp provides a different namespacing system called
+``shorthands'' (@pxref{Shorthands}).
@end quotation
Most of the functions below take a name and sometimes an obarray as
@@ -258,6 +281,11 @@ change the name of the symbol, but fails to update the obarray, so don't
do it!
@end defun
+@cindex uninterned symbol, and generating Lisp code
+Creating an uninterned symbol is useful in generating Lisp code,
+because an uninterned symbol used as a variable in the code you
+generate cannot clash with any variables used in other Lisp programs.
+
@defun make-symbol name
This function returns a newly-allocated, uninterned symbol whose name is
@var{name} (which must be a string). Its value and function definition
@@ -275,10 +303,16 @@ distinct uninterned symbol whose name is also @samp{foo}.
@defun gensym &optional prefix
This function returns a symbol using @code{make-symbol}, whose name is
-made by appending @code{gensym-counter} to @var{prefix}. The prefix
-defaults to @code{"g"}.
+made by appending @code{gensym-counter} to @var{prefix} and incrementing
+that counter, guaranteeing that no two calls to this function will
+generate a symbol with the same name. The prefix defaults to
+@code{"g"}.
@end defun
+To avoid problems when accidentally interning printed representation
+of generated code (@pxref{Printed Representation}), it is recommended
+to use @code{gensym} instead of @code{make-symbol}.
+
@defun intern name &optional obarray
This function returns the interned symbol whose name is @var{name}. If
there is no such symbol in the obarray @var{obarray}, @code{intern}
@@ -600,3 +634,120 @@ If non-@code{nil}, this specifies the named variable's documentation
string. This is set automatically by @code{defvar} and related
functions. @xref{Defining Faces}.
@end table
+
+@node Shorthands
+@section Shorthands
+@cindex shorthands
+@cindex symbolic shorthands
+@cindex namespacing
+@cindex namespaces
+
+ The symbol @dfn{shorthands}, sometimes known as ``renamed symbols'', are
+symbolic forms found in Lisp source. They're just like regular
+symbolic forms, except that when the Lisp reader encounters them, it
+produces symbols which have a different and usually longer @dfn{print
+name} (@pxref{Symbol Components}).
+
+It is useful to think of shorthands as @emph{abbreviating} the full
+names of intended symbols. Despite this, do not confuse shorthands with the
+Abbrev system @pxref{Abbrevs}.
+
+@cindex namespace etiquette
+Shorthands make Emacs Lisp's @dfn{namespacing etiquette} easier to work
+with. Since all symbols are stored in a single obarray
+(@pxref{Creating Symbols}), programmers commonly prefix each symbol
+name with the name of the library where it originates. For example,
+the functions @code{text-property-search-forward} and
+@code{text-property-search-backward} both belong to the
+@file{text-property-search.el} library (@pxref{Loading}). By properly
+prefixing symbol names, one effectively prevents clashes between
+similarly named symbols which belong to different libraries and thus do
+different things. However, this practice commonly originates very
+long symbols names, which are inconvenient to type and read after a
+while. Shorthands solve these issues in a clean way.
+
+@defvar read-symbol-shorthands
+This variable's value is an alist whose elements have the form
+@code{(@var{shorthand-prefix} . @var{longhand-prefix})}. Each element
+instructs the Lisp reader to read every symbol form which starts with
+@var{shorthand-prefix} as if it started with @var{longhand-prefix}
+instead.
+
+This variable may only be set in file-local variables (@pxref{File Variables, ,
+Local Variables in Files, emacs, The GNU Emacs Manual}).
+@end defvar
+
+Here's an example of shorthands usage in a hypothetical string
+manipulating library @file{some-nice-string-utils.el}.
+
+@smalllisp
+(defun some-nice-string-utils-split (separator s &optional omit-nulls)
+ "A match-data saving variant of `split-string'."
+ (save-match-data (split-string s separator omit-nulls)))
+
+(defun some-nice-string-utils-lines (s)
+ "Split string S at newline characters into a list of strings."
+ (some-nice-string-utils-split "\\(\r\n\\|[\n\r]\\)" s))
+@end smalllisp
+
+As can be seen, it's quite tedious to read or develop this code since
+the symbol names to type are so long. We can use shorthands to
+alleviate that.
+
+@lisp
+(defun snu-split (separator s &optional omit-nulls)
+ "A match-data saving variation on `split-string'."
+ (save-match-data (split-string s separator omit-nulls)))
+
+(defun snu-lines (s)
+ "Split string S into a list of strings on newline characters."
+ (snu-split "\\(\r\n\\|[\n\r]\\)" s))
+
+;; Local Variables:
+;; read-symbol-shorthands: (("snu-" . "some-nice-string-utils-"))
+;; End:
+@end lisp
+
+Even though the two excerpts look different, they are quite identical
+after the Lisp reader processes them. Both will lead to the very same
+symbols being interned (@pxref{Creating Symbols}). Thus loading or
+byte-compiling any of the two files has equivalent results. The
+shorthands @code{snu-split} and @code{snu-lines} used in the second
+version are @emph{not} interned in the obarray. This is easily seen
+by moving point to the location where the shorthands are used and
+waiting for ElDoc (@pxref{Lisp Doc, , Local Variables in Files, emacs,
+The GNU Emacs Manual}) to hint at the true full name of the symbol
+under point in the echo area.
+
+Since @code{read-symbol-shorthands} is a file-local variable, it is
+possible that multiple libraries depending on
+@file{some-nice-string-utils-lines.el} refer to the same symbols under
+@emph{different} shorthands, or not using shorthands at all. In the
+next example, the @file{my-tricks.el} library refers to the symbol
+@code{some-nice-string-utils-lines} using the @code{sns-} prefix
+instead of @code{snu-}.
+
+@example
+(defun t-reverse-lines (s) (string-join (reverse (sns-lines s)) "\n")
+
+;; Local Variables:
+;; read-symbol-shorthands: (("t-" . "my-tricks-")
+;; ("sns-" . "some-nice-string-utils-"))
+;; End:
+@end example
+
+@subsection Exceptions
+
+There are two exceptions to rules governing Shorthand transformations:
+
+@itemize @bullet
+@item
+Symbol forms comprised entirely of characters in the Emacs Lisp symbol
+constituent class (@pxref{Syntax Class Table}) are not transformed.
+For example, it's possible to use @code{-} or @code{/=} as shorthand
+prefixes, but that won't shadow the arithmetic @emph{functions} of
+those names.
+
+@item
+Symbol forms whose names start with @samp{#_} are not transformed.
+@end itemize
diff --git a/doc/lispref/syntax.texi b/doc/lispref/syntax.texi
index deec3f44c08..87ade73c2ae 100644
--- a/doc/lispref/syntax.texi
+++ b/doc/lispref/syntax.texi
@@ -900,6 +900,7 @@ arrived at a top level position.
@defun syntax-ppss-context state
Return @code{string} if the end position of the scan returning
@var{state} is in a string, and @code{comment} if it's in a comment.
+Otherwise return @code{nil}.
@end defun
@node Low-Level Parsing
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index 9e0401fffb9..5ab5e5715f0 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -60,6 +60,7 @@ the character after point.
* Base 64:: Conversion to or from base 64 encoding.
* Checksum/Hash:: Computing cryptographic hashes.
* GnuTLS Cryptography:: Cryptographic algorithms imported from GnuTLS.
+* Database:: Interacting with an SQL database.
* Parsing HTML/XML:: Parsing HTML and XML.
* Parsing JSON:: Parsing and generating JSON values.
* JSONRPC:: JSON Remote Procedure Call protocol
@@ -319,7 +320,7 @@ The argument @var{thing} is a symbol which specifies a kind of
syntactic entity. Possibilities include @code{symbol}, @code{list},
@code{sexp}, @code{defun}, @code{filename}, @code{existing-filename},
@code{url}, @code{word}, @code{sentence}, @code{whitespace},
-@code{line}, @code{page}, and others.
+@code{line}, @code{page}, @code{string}, and others.
When the optional argument @var{no-properties} is non-@code{nil}, this
function strips text properties from the return value.
@@ -599,6 +600,19 @@ This command indents to the left margin if that is not zero.
The value returned is @code{nil}.
@end deffn
+@deffn Command ensure-empty-lines &optional number-of-empty-lines
+This command can be used to ensure that you have a specific number of
+empty lines before point. (An ``empty line'' is here defined as a
+line with no characters on it---a line with space characters isn't an
+empty line.) It defaults to ensuring that there's a single empty line
+before point.
+
+If point isn't at the beginning of a line, a newline character is
+inserted first. If there's more empty lines before point than
+specified, the number of empty lines is reduced. Otherwise it's
+increased to the specified number.
+@end deffn
+
@defvar overwrite-mode
This variable controls whether overwrite mode is in effect. The value
should be @code{overwrite-mode-textual}, @code{overwrite-mode-binary},
@@ -1329,7 +1343,7 @@ that @kbd{C-y} should yank.
@defopt kill-ring-max
The value of this variable is the maximum length to which the kill
ring can grow, before elements are thrown away at the end. The default
-value for @code{kill-ring-max} is 60.
+value for @code{kill-ring-max} is 120.
@end defopt
@node Undo
@@ -1493,6 +1507,11 @@ continuing to undo.
This function does not bind @code{undo-in-progress}.
@end defun
+@defmac with-undo-amalgamate body@dots{}
+This macro removes all the undo boundaries inserted during the
+execution of @var{body} so that it can be undone as a single step.
+@end defmac
+
Some commands leave the region active after execution in such a way that
it interferes with selective undo of that command. To make @code{undo}
ignore the active region when invoked immediately after such a command,
@@ -1633,6 +1652,47 @@ The variable @code{paragraph-separate} controls how to distinguish
paragraphs. @xref{Standard Regexps}.
@end deffn
+@defun pixel-fill-region start end pixel-width
+Most Emacs buffers use monospaced text, so all the filling functions
+(like @code{fill-region}) work based on the number of characters and
+@code{char-width}. However, Emacs can render other types of things,
+like text that contains images and using proportional fonts, and the
+@code{pixel-fill-region} exists to handle that. It fills the region
+of text between @var{start} and @var{end} at pixel granularity, so
+text using variable-pitch fonts or several different fonts looks
+filled regardless of different character sizes. The argument
+@var{pixel-width} specifies the maximum pixel width a line is allowed
+to have after filling; it is the pixel-resolution equivalent of the
+@code{fill-column} in @code{fill-region}. For instance, this Lisp
+snippet will insert text using a proportional font, and then fill this
+to be no wider than 300 pixels:
+
+@lisp
+(insert (propertize
+ "This is a sentence that's ends here."
+ 'face 'variable-pitch))
+(pixel-fill-region (point) (point-max) 300)
+@end lisp
+
+If @var{start} isn't at the start of a line, the horizontal position
+of @var{start}, converted to pixel units, will be used as the
+indentation prefix on subsequent lines.
+
+@findex pixel-fill-width
+The @code{pixel-fill-width} helper function can be used to compute the
+pixel width to use. If given no arguments, it'll return a value
+slightly less than the width of the current window. The first
+optional value, @var{columns}, specifies the number of columns using
+the standard, monospaced fonts, e.g. @code{fill-column}. The second
+optional value is the window to use. You'd typically use it like
+this:
+
+@lisp
+(pixel-fill-region
+ start end (pixel-fill-width fill-column))
+@end lisp
+@end defun
+
@deffn Command fill-individual-paragraphs start end &optional justify citation-regexp
This command fills each paragraph in the region according to its
individual fill prefix. Thus, if the lines of a paragraph were indented
@@ -1802,7 +1862,12 @@ read, you should set @code{fill-column} to no more than 70. Otherwise
the line will be too long for people to read comfortably, and this can
make the text seem clumsy.
-The default value for @code{fill-column} is 70.
+The default value for @code{fill-column} is 70. To disable Auto Fill
+mode in a specific mode, you could say something like:
+
+@lisp
+(add-hook 'foo-mode-hook (lambda () (auto-fill-mode -1))
+@end lisp
@end defopt
@deffn Command set-left-margin from to margin
@@ -3597,6 +3662,11 @@ edited even in read-only buffers. @xref{Read Only Buffers}.
A non-@code{nil} @code{invisible} property can make a character invisible
on the screen. @xref{Invisible Text}, for details.
+@kindex inhibit-isearch @r{(text property)}
+@item inhibit-isearch
+A non-@code{nil} @code{inhibit-isearch} property will make isearch
+skip the text.
+
@item intangible
@kindex intangible @r{(text property)}
If a group of consecutive characters have equal and non-@code{nil}
@@ -3622,9 +3692,20 @@ property is obsolete; use the @code{cursor-intangible} property instead.
@item cursor-intangible
@kindex cursor-intangible @r{(text property)}
@findex cursor-intangible-mode
+@cindex rear-nonsticky, and cursor-intangible property
When the minor mode @code{cursor-intangible-mode} is turned on, point
is moved away from any position that has a non-@code{nil}
@code{cursor-intangible} property, just before redisplay happens.
+Note that ``stickiness'' of the property (@pxref{Sticky Properties})
+is taken into account when computing allowed cursor positions, so (for
+instance) to insert a stretch of five @samp{x} characters into which
+the cursor can't enter, you should do something like:
+
+@lisp
+(insert
+ (propertize "xxxx" 'cursor-intangible t)
+ (propertize "x" 'cursor-intangible t 'rear-nonsticky t))
+@end lisp
@vindex cursor-sensor-inhibit
When the variable @code{cursor-sensor-inhibit} is non-@code{nil}, the
@@ -3642,14 +3723,14 @@ Consecutive characters with the same @code{field} property constitute a
@kindex cursor @r{(text property)}
Normally, the cursor is displayed at the beginning or the end of any
overlay and text property strings present at the current buffer
-position. You can place the cursor on any desired character of these
-strings by giving that character a non-@code{nil} @code{cursor} text
-property. In addition, if the value of the @code{cursor} property is
-an integer, it specifies the number of buffer's character
-positions, starting with the position where the overlay or the
-@code{display} property begins, for which the cursor should be
-displayed on that character. Specifically, if the value of the
-@code{cursor} property of a character is the number @var{n}, the
+position. You can instead tell Emacs to place the cursor on any
+desired character of these strings by giving that character a
+non-@code{nil} @code{cursor} text property. In addition, if the value
+of the @code{cursor} property is an integer, it specifies the number
+of buffer's character positions, starting with the position where the
+overlay or the @code{display} property begins, for which the cursor
+should be displayed on that character. Specifically, if the value of
+the @code{cursor} property of a character is the number @var{n}, the
cursor will be displayed on this character for any buffer position in
the range @code{[@var{ovpos}..@var{ovpos}+@var{n})}, where @var{ovpos}
is the overlay's starting position given by @code{overlay-start}
@@ -3658,14 +3739,23 @@ text property begins in the buffer.
In other words, the string character with the @code{cursor} property
of any non-@code{nil} value is the character where to display the
-cursor. The value of the property says for which buffer positions to
-display the cursor there. If the value is an integer @var{n},
-the cursor is displayed there when point is anywhere between the
-beginning of the overlay or @code{display} property and @var{n}
-positions after that. If the value is anything else and
-non-@code{nil}, the cursor is displayed there only when point is at
-the beginning of the @code{display} property or at
-@code{overlay-start}.
+cursor when the overlay or display string make point not visible on
+display. The value of the property says for which buffer positions to
+display the cursor there. If the value is an integer @var{n}, the
+cursor is displayed there when point is anywhere between the beginning
+of the overlay or @code{display} property and @var{n} positions after
+that. If the value is anything else and non-@code{nil}, the cursor is
+displayed there only when point is at the buffer position that is the
+beginning of the @code{display} property, or at @code{overlay-start}
+if that position is not visible on display. Note that an integer
+value of the @code{cursor} property could mean that the cursor is
+displayed on that character even when point is visible on display.
+
+One subtlety of this property is that it doesn't work to put this
+property on a newline character that is part of a display or overlay
+string. That's because the newline doesn't have a graphic
+representation on the screen for Emacs to find when it looks for a
+character on display with that @code{cursor} property.
@cindex cursor position for @code{display} properties and overlays
When the buffer has many overlay strings (e.g., @pxref{Overlay
@@ -3922,6 +4012,8 @@ of the kill ring. To insert with inheritance, use the special
primitives described in this section. Self-inserting characters
inherit properties because they work using these primitives.
+@cindex front-sticky text property
+@cindex rear-nonsticky text property
When you do insertion with inheritance, @emph{which} properties are
inherited, and from where, depends on which properties are @dfn{sticky}.
Insertion after a character inherits those of its properties that are
@@ -4154,7 +4246,7 @@ position. The action code is always @code{t}.
For example, here is how Info mode handles @key{mouse-1}:
@smallexample
-(define-key Info-mode-map [follow-link] 'mouse-face)
+(keymap-set Info-mode-map "<follow-link>" 'mouse-face)
@end smallexample
@item a function
@@ -4167,9 +4259,9 @@ For example, here is how pcvs enables @kbd{mouse-1} to follow links on
file names only:
@smallexample
-(define-key map [follow-link]
- (lambda (pos)
- (eq (get-char-property pos 'face) 'cvs-filename-face)))
+(keymap-set map "<follow-link>"
+ (lambda (pos)
+ (eq (get-char-property pos 'face) 'cvs-filename-face)))
@end smallexample
@item anything else
@@ -5044,6 +5136,177 @@ On success, it returns a list of a binary string (the output) and the
IV used.
@end defun
+@node Database
+@section Database
+@cindex database access, SQLite
+
+ Emacs can be compiled with built-in support for accessing SQLite
+databases. This section describes the facilities available for
+accessing SQLite databases from Lisp programs.
+
+@defun sqlite-available-p
+The function returns non-@code{nil} if built-in SQLite support is
+available in this Emacs session.
+@end defun
+
+When SQLite support is available, the following functions can be used.
+
+@cindex database object
+@defun sqlite-open &optional file
+This function opens @var{file} as an SQLite database file. If
+@var{file} doesn't exist, a new database will be created and stored in
+that file. If @var{file} is omitted or @code{nil}, a new in-memory
+database is created instead.
+
+The return value is a @dfn{database object} that can be used as the
+argument to most of the subsequent functions described below.
+@end defun
+
+@defun sqlitep object
+This predicate returns non-@code{nil} if @var{object} is an SQLite
+database object. The database object returned by the
+@code{sqlite-open} function satisfies this predicate.
+@end defun
+
+@defun sqlite-close db
+Close the database @var{db}. It's usually not necessary to call this
+function explicitly---the database will automatically be closed if
+Emacs shuts down or the database object is garbage collected.
+@end defun
+
+@defun sqlite-execute db statement &optional values
+Execute the @acronym{SQL} @var{statement}. For instance:
+
+@lisp
+(sqlite-execute db "insert into foo values ('bar', 2)")
+@end lisp
+
+If the optional @var{values} parameter is present, it should be either
+a list or a vector of values to bind while executing the statement.
+For instance:
+
+@lisp
+(sqlite-execute db "insert into foo values (?, ?)" '("bar" 2))
+@end lisp
+
+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.
+@end defun
+
+@defun sqlite-select db query &optional values result-type
+Select some data from @var{db} and return them. For instance:
+
+@lisp
+(sqlite-select db "select * from foo where key = 2")
+ @result{} (("bar" 2))
+@end lisp
+
+As with the @code{sqlite-execute}, you can optionally pass in a list
+or a vector of values that will be bound before executing the select:
+
+@lisp
+(sqlite-select db "select * from foo where key = ?" [2])
+ @result{} (("bar" 2))
+@end lisp
+
+This is usually more efficient and safer than the method used by the
+previous example.
+
+By default, this function returns a list of matching rows, where each
+row is a list of column values. If @var{return-type} is @code{full},
+the names of the columns (as a list of strings) will be returned as
+the first element in the return value.
+
+@cindex statement object
+If @var{return-type} is @code{set}, this function will return a
+@dfn{statement object} instead. This object can be examined by using
+the @code{sqlite-next}, @code{sqlite-columns} and @code{sqlite-more-p}
+functions. If the result set is small, it's often more convenient to
+just return the data directly, but if the result set is large (or if
+you won't be using all the data from the set), using the @code{set}
+method will allocate a lot less memory, and is therefore more
+memory-efficient.
+@end defun
+
+@defun sqlite-next statement
+This function returns the next row in the result set @var{statement},
+typically an object returned by @code{sqlite-select}.
+
+@lisp
+(sqlite-next stmt)
+ @result{} ("bar" 2)
+@end lisp
+@end defun
+
+@defun sqlite-columns statement
+This function returns the column names of the result set
+@var{statement}, typically an object returned by @code{sqlite-select}.
+
+@lisp
+(sqlite-columns stmt)
+ @result{} ("name" "issue")
+@end lisp
+@end defun
+
+@defun sqlite-more-p statement
+This predicate says whether there is more data to be fetched from the
+result set @var{statement}, typically an object returned by
+@code{sqlite-select}.
+@end defun
+
+@defun sqlite-finalize statement
+If @var{statement} is not going to be used any more, calling this
+function will free the resources used by @var{statement}. This is
+usually not necessary---when the @var{statement} object is
+garbage-collected, Emacs will automatically free its resources.
+@end defun
+
+@defun sqlite-transaction db
+Start a transaction in @var{db}. When in a transaction, other readers
+of the database won't access the results until the transaction has
+been committed by @code{sqlite-commit}.
+@end defun
+
+@defun sqlite-commit db
+End a transaction in @var{db} and write the data out to its file.
+@end defun
+
+@defun sqlite-rollback db
+End a transaction in @var{db} and discard any changes that have been
+made by the transaction.
+@end defun
+
+@defmac with-sqlite-transaction db body@dots{}
+Like @code{progn} (@pxref{Sequencing}), but executes @var{body} with a
+transaction held, and commits the transaction at the end.
+@end defmac
+
+@defun sqlite-pragma db pragma
+Execute @var{pragma} in @var{db}. A @dfn{pragma} is usually a command
+that affects the database overall, instead of any particular table.
+For instance, to make SQLite automatically garbage collect data that's
+no longer needed, you can say:
+
+@lisp
+(sqlite-pragma db "auto_vacuum = FULL")
+@end lisp
+
+This function returns non-@code{nil} on success and @code{nil} if the
+pragma failed. Many pragmas can only be issued when the database is
+brand new and empty.
+@end defun
+
+@defun sqlite-load-extension db module
+Load the named extension @var{module} into the database @var{db}.
+Extensions are usually shared-library files; on GNU and Unix systems,
+they have the @file{.so} file-name extension.
+@end defun
+
@node Parsing HTML/XML
@section Parsing HTML and XML
@cindex parsing html
diff --git a/doc/lispref/tips.texi b/doc/lispref/tips.texi
index 8aa225a00c3..cbfcbd8d14f 100644
--- a/doc/lispref/tips.texi
+++ b/doc/lispref/tips.texi
@@ -252,6 +252,13 @@ themselves; Lisp programmers find this disconcerting.
Please put a copyright notice and copying permission notice on the
file if you distribute copies. @xref{Library Headers}.
+@item
+For variables holding (or functions returning) a file or directory name,
+avoid using @code{path} in its name, preferring @code{file},
+@code{file-name}, or @code{directory} instead, since Emacs follows the
+GNU convention to use the term @emph{path} only for search paths,
+which are lists of directory names.
+
@end itemize
@node Key Binding Conventions
@@ -393,12 +400,18 @@ Don't use @code{message}, @code{throw}, @code{sleep-for}, or
@item
An error message should start with a capital letter but should not end
-with a period.
+with a period or other punctuation.
+
+It is occasionally useful to tell the user where an error originated,
+even if @code{debug-on-error} is @code{nil}. In such cases, a
+lower-case Lisp symbol can be prepended to the error message. For
+example, the error message ``Invalid input'' could be extended to say
+``some-function: Invalid input''.
@item
A question asked in the minibuffer with @code{yes-or-no-p} or
@code{y-or-n-p} should start with a capital letter and end with
-@samp{? }.
+@samp{?}.
@item
When you mention a default value in a minibuffer prompt,
@@ -755,11 +768,33 @@ anchor}. The Info file name defaults to @samp{emacs}. For example,
See Info node `Font Lock' and Info node `(elisp)Font Lock Basics'.
@end smallexample
+To make a hyperlink to a man page, write the single-quoted name of the
+man page, preceded by @samp{Man page}, @samp{man page}, or @samp{man
+page for}. For example,
+
+@smallexample
+See the man page `chmod(1)' for details.
+@end smallexample
+
+@noindent
+The Info documentation is always preferable to man pages, so be sure
+to link to an Info manual where available. For example,
+@command{chmod} is documented in the GNU Coreutils manual, so it is
+better to link to that instead of the man page.
+
+To link to a customization group, write the single-quoted name of the
+group, preceded by @samp{customization group} (the first character in
+each word is case-insensitive). For example,
+
+@smallexample
+See the customization group `whitespace' for details.
+@end smallexample
+
Finally, to create a hyperlink to URLs, write the single-quoted URL,
preceded by @samp{URL}. For example,
@smallexample
-The home page for the GNU project has more information (see URL
+The GNU project wesite has more information (see URL
`https://www.gnu.org/').
@end smallexample
@@ -781,10 +816,12 @@ the first use of @samp{\\[@dots{}]}. The text inside the
@samp{\\<@dots{}>} should be the name of the variable containing the
local keymap for the major mode.
-It is not practical to use @samp{\\[@dots{}]} very many times, because
-display of the documentation string will become slow. So use this to
-describe the most important commands in your major mode, and then use
-@samp{\\@{@dots{}@}} to display the rest of the mode's keymap.
+Each use of @samp{\\[@dots{}]} slows the display of the documentation
+string by a tiny amount. If you use a lot of them, these tiny
+slowdowns will add up, and might become tangible, especially on slow
+systems. So our recommendation is not to over-use them; e.g., try to
+avoid using more than one reference to the same command in the same
+doc string.
@item
For consistency, phrase the verb in the first sentence of a function's
@@ -1090,9 +1127,9 @@ The name of this field is unfortunate, since people often assume it is
the place to write arbitrary keywords that describe their package,
rather than just the relevant Finder keywords.
-@item Homepage
-@itemx URL
-These lines state the homepage of the library.
+@item URL
+@itemx Homepage
+These lines state the website of the library.
@item Package-Version
If @samp{Version} is not suitable for use by the package manager, then
diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi
index 9356fb9f699..98a9487aea9 100644
--- a/doc/lispref/variables.texi
+++ b/doc/lispref/variables.texi
@@ -44,6 +44,7 @@ representing the variable.
* Variables with Restricted Values:: Non-constant variables whose value can
@emph{not} be an arbitrary Lisp object.
* Generalized Variables:: Extending the concept of variables.
+* Multisession Variables:: Variables that survive restarting Emacs.
@end menu
@node Global Variables
@@ -194,7 +195,7 @@ default scoping rule in Emacs Lisp is called @dfn{dynamic scoping},
which simply states that the current binding at any given point in the
execution of a program is the most recently-created binding for that
variable that still exists. For details about dynamic scoping, and an
-alternative scoping rule called @dfn{lexical scoping}, @xref{Variable
+alternative scoping rule called @dfn{lexical scoping}, @pxref{Variable
Scoping}.
The special forms @code{let} and @code{let*} exist to create local
@@ -286,6 +287,57 @@ being run once:
@end lisp
@end defspec
+@cindex dynamic binding, temporarily
+@cindex dynamic let-binding
+@defspec dlet (bindings@dots{}) forms@dots{}
+This special form is like @code{let}, but it binds all variables
+dynamically. This is rarely useful---you usually want to bind normal
+variables lexically, and special variables (i.e., variables that are
+defined with @code{defvar}) dynamically, and this is what @code{let}
+does.
+
+@code{dlet} can be useful when interfacing with old code that assumes
+that certain variables are dynamically bound (@pxref{Dynamic
+Binding}), but it's impractical to @code{defvar} these variables.
+@code{dlet} will temporarily make the bound variables special, execute
+the forms, and then make the variables non-special again.
+@end defspec
+
+@defspec named-let name bindings &rest body
+This special form is a looping construct inspired from the
+Scheme language. It is similar to @code{let}: It binds the variables in
+@var{bindings}, and then evaluates @var{body}. However,
+@code{named-let} also binds @var{name} to a
+local function whose formal arguments are the variables in @var{bindings}
+and whose body is @var{body}. This allows @var{body} to call itself
+recursively by calling
+@var{name}, where the arguments passed to @var{name} are used as the
+new values of the bound variables in the recursive invocation.
+
+Example of a loop summing a list of numbers:
+
+@lisp
+(named-let sum ((numbers '(1 2 3 4))
+ (running-sum 0))
+ (if numbers
+ (sum (cdr numbers) (+ running-sum (car numbers)))
+ running-sum))
+@result{} 10
+@end lisp
+
+@anchor{Tail recursion}
+Recursive calls to @var{name} that occur in @emph{tail
+positions} in @var{body} are guaranteed to be optimised as @emph{tail
+calls}, which means that they will not consume any additional stack
+space no matter how deeply the recursion runs. Such recursive calls
+will effectively jump to the top of the loop with new values for the
+variables.
+
+A function call is in the tail position if it's the very last thing
+done so that the value returned by the call is the value of @var{body}
+itself, as is the case in the recursive call to @code{sum} above.
+@end defspec
+
Here is a complete list of the other facilities that create local
bindings:
@@ -312,7 +364,7 @@ where you are in Emacs.
@cindex evaluation error
@cindex infinite recursion
This variable defines the limit on the total number of local variable
-bindings and @code{unwind-protect} cleanups (see @ref{Cleanups,,
+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"}).
@@ -635,7 +687,7 @@ entire computation of the value into the @code{defvar}, like this:
@example
(defvar my-mode-map
(let ((map (make-sparse-keymap)))
- (define-key map "\C-c\C-a" 'my-command)
+ (keymap-set map "C-c C-a" 'my-command)
@dots{}
map)
@var{docstring})
@@ -651,25 +703,6 @@ important if the user has run hooks to alter part of the contents
(such as, to rebind keys). Third, evaluating the @code{defvar} form
with @kbd{C-M-x} will reinitialize the map completely.
- Putting so much code in the @code{defvar} form has one disadvantage:
-it puts the documentation string far away from the line which names the
-variable. Here's a safe way to avoid that:
-
-@example
-(defvar my-mode-map nil
- @var{docstring})
-(unless my-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\C-c\C-a" 'my-command)
- @dots{}
- (setq my-mode-map map)))
-@end example
-
-@noindent
-This has all the same advantages as putting the initialization inside
-the @code{defvar}, except that you must type @kbd{C-M-x} twice, once on
-each form, if you do want to reinitialize the variable.
-
@node Accessing Variables
@section Accessing Variable Values
@@ -1644,12 +1677,14 @@ buffer-local variables interactively.
@end deffn
@cindex local variables, killed by major mode
-@defun kill-all-local-variables
+@defun kill-all-local-variables &optional kill-permanent
This function eliminates all the buffer-local variable bindings of the
-current buffer except for variables marked as permanent and local
-hook functions that have a non-@code{nil} @code{permanent-local-hook}
-property (@pxref{Setting Hooks}). As a result, the buffer will see
-the default values of most variables.
+current buffer. As a result, the buffer will see the default values
+of most variables. By default, for variables marked as permanent and
+local hook functions that have a non-@code{nil}
+@code{permanent-local-hook} property (@pxref{Setting Hooks}) won't be
+killed, but if the optional @var{kill-permanent} argument is
+non-@code{nil}, even these variables will be killed.
This function also resets certain other information pertaining to the
buffer: it sets the local keymap to @code{nil}, the syntax table to the
@@ -2718,3 +2753,157 @@ form that has not already had an appropriate expansion defined. In
Common Lisp, this is not an error since the function @code{(setf
@var{func})} might be defined later.
@end quotation
+
+@node Multisession Variables
+@section Multisession Variables
+
+@cindex multisession variable
+ When you set a variable to a value and then close Emacs and restart
+it, that value won't be automatically restored. Users usually set
+normal variables in their startup files, or use Customize
+(@pxref{Customization}) to set user options permanently, and various
+packages have various files wher they store the data (e.g., Gnus
+stores this in @file{.newsrc.eld} and the URL library stores cookies
+in @file{~/.emacs.d/url/cookies}).
+
+For things in between these two extremes (i.e., configuration which
+goes in the startup file, and massive application state that goes into
+separate files), Emacs provides a facility to replicate data between
+sessions called @dfn{multisession variables}. (This facility may not
+be available on all systems.) To give you an idea of how these are
+meant to be used, here's a small example:
+
+@lisp
+@group
+(define-multisession-variable foo-var 0)
+(defun my-adder (num)
+ (interactive "nAdd number: ")
+ (setf (multisession-value foo)
+ (+ (multisession-value foo) num))
+ (message "The new number is: %s" (multisession-value foo)))
+@end group
+@end lisp
+
+@noindent
+This defines the variable @code{foo-var} and binds it to a special
+multisession object which is initialized with the value @samp{0} (if
+the variable doesn't already exist from a previous session). The
+@code{my-adder} command queries the user for a number, adds this to
+the old (possibly saved value), and then saves the new value.
+
+This facility isn't meant to be used for huge data structures, but
+should be performant for most values.
+
+@defmac define-multisession-variable name initial-value &optional doc &rest args
+This macro defines @var{name} as a multisession variable, and gives it
+the @var{initial-value} if this variable hasn't been assigned a value
+earlier. @var{doc} is the doc string, and several keyword arguments can
+be used in @var{args}:
+
+@table @code
+@item :package @var{package-symbol}
+This keyword says that a multisession variable belongs to the package
+specified by @var{package-symbol}. The combination of
+@var{package-symbol} and @var{name} has to be unique. If
+@var{package-symbol} isn't given, this will default to the first
+``segment'' of the @var{name} symbol's name, which is the part of its
+name up to and excluding the first @samp{-}. For instance, if
+@var{name} is @code{foo-var} and @var{package-symbol} isn't given,
+@var{package-symbol} will default to @code{foo}.
+
+@cindex synchronized multisession variables
+@item :synchronized @var{bool}
+Multisession variables can be @dfn{synchronized} if @var{bool} is
+non-@code{nil}. This means that if there're two concurrent Emacs
+instances running, and the other Emacs changes the multisession
+variable @code{foo-var}, the current Emacs instance will retrieve that
+modified data when accessing the value. If @var{synchronized} is
+@code{nil} or missing, this won't happen, and the values in all
+Emacs sessions using the variable will be independent of each other.
+
+@item :storage @var{storage}
+Use the specified @var{storage} method. This can be either
+@code{sqlite} (in Emacs compiled with SQLite support) or @code{files}.
+If not given, this defaults to the value of the
+@code{multisession-storage} variable, described below.
+@end table
+@end defmac
+
+@defun multisession-value variable
+This function returns the current value of @var{variable}. If this
+variable hasn't been accessed before in this Emacs session, or if it's
+changed externally, it will be read in from external storage. If not,
+the current value in this session is returned as is. It is an error
+to call this function for a @var{variable} that is not a multisession
+variable.
+
+Values retrieved via @code{multisession-value} may or may not be
+@code{eq} to each other, but they will always be @code{equal}.
+
+This is a generalized variable (@pxref{Generalized Variables}), so the
+way to update such a variable is to say, for instance:
+
+@lisp
+(setf (multisession-value foo-bar) 'zot)
+@end lisp
+
+Only Emacs Lisp values that have a readable print syntax
+(@pxref{Printed Representation}) can be saved this way.
+
+If the multisession variable is synchronized, setting it may update
+the value first. For instance:
+
+@lisp
+(cl-incf (multisession-value foo-bar))
+@end lisp
+
+This first checks whether the value has changed in a different
+Emacs instance, retrieves that value, and then adds 1 to that value and
+stores it. But note that this is done without locking, so if many
+instances are updating the value at the same time, it's unpredictable
+which instance ``wins''.
+@end defun
+
+@defun multisession-delete object
+This function deletes @var{object} and its value from its persistent
+storage.
+@end defun
+
+@c FIXME: this lacks the documentation of the form of the arguments.
+@defun make-multisession
+You can also make persistent values that aren't tied to a specific
+variable, but are tied to an explicit package and key.
+
+@example
+(setq foo (make-multisession :package "mail"
+ :key "friends"))
+(setf (multisession-value foo) 'everybody)
+@end example
+
+This supports the same keywords as
+@code{define-multisession-variable}, but also supports a
+@code{:initial-value} keyword, which specifies the default value.
+@end defun
+
+@defopt multisession-storage
+This variable controls how the multisession variables are stored. It
+value defaults to @code{files}, which means that the values are stored
+in a one-file-per-variable structure inside the directory specified by
+@code{multisession-directory}. If this value is @code{sqlite}
+instead, the values are stored in an SQLite database; this is only
+available if Emacs was built with SQLite support.
+@end defopt
+
+@defopt multisession-directory
+The multisession variables are stored under this directory, which
+defaults to @file{multisession/} subdirectory of the
+@code{user-emacs-directory}, which is typically
+@file{~/.emacs.d/multisession/}.
+@end defopt
+
+@findex multisession-edit-mode
+@deffn Command list-multisession-values
+This command pops up a buffer listing all the multisession variables,
+and enters a special mode @code{multisession-edit-mode} which allows
+you to delete them and edit their values.
+@end deffn
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 26f85df160e..c3894bc3954 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -14,6 +14,7 @@ is displayed in windows.
@menu
* Basic Windows:: Basic information on using windows.
* Windows and Frames:: Relating windows to the frame they appear on.
+* Selecting Windows:: The selected window is the one that you edit in.
* Window Sizes:: Accessing a window's size.
* Resizing Windows:: Changing the sizes of windows.
* Preserving Window Sizes:: Preserving the size of windows.
@@ -21,7 +22,6 @@ is displayed in windows.
* Deleting Windows:: Removing a window from its frame.
* Recombining Windows:: Preserving the frame layout when splitting and
deleting windows.
-* Selecting Windows:: The selected window is the one that you edit in.
* Cyclic Window Ordering:: Moving around the existing windows.
* Buffers and Windows:: Each window displays the contents of a buffer.
* Switching Buffers:: Higher-level functions for switching to a buffer.
@@ -53,32 +53,37 @@ is displayed in windows.
@section Basic Concepts of Emacs Windows
@cindex window
-A @dfn{window} is an area of the screen that is used to display a buffer
-(@pxref{Buffers}). In Emacs Lisp, windows are represented by a special
-Lisp object type.
-
@cindex multiple windows
- Windows are grouped into frames (@pxref{Frames}). Each frame
-contains at least one window; the user can subdivide it into multiple,
-non-overlapping windows to view several buffers at once. Lisp
-programs can use multiple windows for a variety of purposes. In
-Rmail, for example, you can view a summary of message titles in one
-window, and the contents of the selected message in another window.
+A @dfn{window} is an area of the screen that can be used to display a
+buffer (@pxref{Buffers}). Windows are grouped into frames
+(@pxref{Frames}). Each frame contains at least one window; the user can
+subdivide a frame into multiple, non-overlapping windows to view several
+buffers at once. Lisp programs can use multiple windows for a variety
+of purposes. In Rmail, for example, you can view a summary of message
+titles in one window, and the contents of the selected message in
+another window.
@cindex terminal screen
@cindex screen of terminal
- Emacs uses the word ``window'' with a different meaning than in
-graphical desktop environments and window systems, such as the X
-Window System. When Emacs is run on X, each of its graphical X
-windows is an Emacs frame (containing one or more Emacs windows).
-When Emacs is run on a text terminal, the frame fills the entire
-terminal screen.
+@cindex window-system window
+ Emacs uses the term ``window'' with a different meaning than in
+graphical desktop environments and window systems, such as the X Window
+System. When Emacs is run on X, each graphical X window owned by the
+Emacs process corresponds to one Emacs frame. When Emacs is run on a
+text terminal, each Emacs frame fills the entire terminal screen. In
+either case, the frame may contain one or more Emacs windows. For
+disambiguation, we use the term @dfn{window-system window} when we mean
+the window-system window corresponding to an Emacs frame.
@cindex tiled windows
Unlike X windows, Emacs windows are @dfn{tiled}; they never overlap
-within the area of the frame. When a window is created, resized, or
-deleted, the change in window space is taken from or given to the
-adjacent windows, so that the total area of the frame is unchanged.
+within the area of their frame. When a window is created, resized, or
+deleted, the change in window space is taken from or given to other
+windows on the same frame, so that the total area of the frame is
+unchanged.
+
+In Emacs Lisp, windows are represented by a special Lisp object type
+(@pxref{Window Type}).
@defun windowp object
This function returns @code{t} if @var{object} is a window (whether or
@@ -117,94 +122,145 @@ internal window in a window tree. Otherwise, it returns @code{nil},
including for the case where @var{object} is a deleted window.
@end defun
-@cindex selected window
-@cindex window selected within a frame
- In each frame, at any time, exactly one Emacs window is designated
-as @dfn{selected within the frame}. For the selected frame, that
-window is called the @dfn{selected window}---the one in which most
-editing takes place, and in which the cursor for selected windows
-appears (@pxref{Cursor Parameters}). Keyboard input that inserts or
-deletes text is also normally directed to this window. The selected
-window's buffer is usually also the current buffer, except when
-@code{set-buffer} has been used (@pxref{Current Buffer}). As for
-non-selected frames, the window selected within the frame becomes the
-selected window if the frame is ever selected. @xref{Selecting
-Windows}.
+ The following schematic shows the structure of a live window:
-@defun selected-window
-This function returns the selected window (which is always a live
-window).
-@end defun
+@smallexample
+@group
+ ____________________________________________
+ |________________ Tab Line _______________|RD| ^
+ |______________ Header Line ______________| | |
+ ^ |LS|LM|LF| |RF|RM|RS| | |
+ | | | | | | | | | | |
+Window | | | | | | | | | Window
+Body | | | | | Window Body | | | | | Total
+Height | | | | | | | | | Height
+ | | | | |<- Window Body Width ->| | | | | |
+ v |__|__|__|_______________________|__|__|__| | |
+ |_________ Horizontal Scroll Bar _________| | |
+ |_______________ Mode Line _______________|__| |
+ |_____________ Bottom Divider _______________| v
+ <---------- Window Total Width ------------>
-@anchor{Window Group}Sometimes several windows collectively and
-cooperatively display a buffer, for example, under the management of
-Follow Mode (@pxref{Follow Mode,,, emacs}), where the windows together
-display a bigger portion of the buffer than one window could alone.
-It is often useful to consider such a @dfn{window group} as a single
-entity. Several functions such as @code{window-group-start}
-(@pxref{Window Start and End}) allow you to do this by supplying, as
-an argument, one of the windows as a stand in for the whole group.
+@end group
+@end smallexample
-@defun selected-window-group
-@vindex selected-window-group-function
-When the selected window is a member of a group of windows, this
-function returns a list of the windows in the group, ordered such that
-the first window in the list is displaying the earliest part of the
-buffer, and so on. Otherwise the function returns a list containing
-just the selected window.
+@cindex window body
+@cindex body of a window
+@cindex window decorations
+@cindex left and right window decorations
+@cindex top and bottom window decorations
+ At the center of that window is the @dfn{body}, where the buffer
+text is displayed. The body can be surrounded by a series of optional
+areas which we will call @dfn{window decorations}. On the left and
+right, from innermost to outermost, these are the left and right
+fringes, denoted by LF and RF (@pxref{Fringes}); the left and right
+margins, denoted by LM and RM in the schematic (@pxref{Display
+Margins}); the left or right vertical scroll bar, only one of which is
+present at any time, denoted by LS and RS (@pxref{Scroll Bars}); and
+the right divider, denoted by RD (@pxref{Window Dividers}). Together
+these are the window's @dfn{left and right decorations}.
+
+@cindex text area of a window
+ At the top of the window are the tab line and the header line
+(@pxref{Header Lines}). The @dfn{text area} of the window includes
+the header line and the tab line, if they are present in the window.
+At the bottom of the window are the horizontal scroll bar
+(@pxref{Scroll Bars}); the mode line (@pxref{Mode Line Format}); and
+the bottom divider (@pxref{Window Dividers}). Together these form the
+window's @dfn{top and bottom decorations}.
+
+ There are two special areas omitted in the schematic:
+
+@itemize @bullet
+@item
+When any of the fringes is missing, the display engine may use one
+character cell in its place for showing a continuation or truncation
+glyph provided a text line doesn't fit in a window.
+
+@item
+When both, the vertical scroll bar and the right divider are missing,
+the display engine usurps one pixel for drawing a vertical divider line
+between this window and the window on its right, provided such a window
+exists. On a text terminal, this divider always occupies an entire
+character cell.
+@end itemize
+
+In either case, the resulting artifact is considered part of the
+window's body although its screen space cannot be used for displaying
+buffer text.
+
+ Note also, that line numbers (and their surrounding whitespace) as
+displayed by @code{display-line-numbers-mode} (@pxref{Display Custom,,,
+emacs, The GNU Emacs Manual}) do not count as decorations either; they
+are part of the window's body too.
+
+ Internal windows neither show any text nor do they have decorations.
+Hence, the concept of ``body'' does not make sense for them. In fact,
+most functions operating on the body of a window will yield an error
+when applied to an internal window.
+
+@cindex minibuffer window
+@cindex tooltip window
+ By default, an Emacs frame exhibits one special live window that is
+used for displaying messages and accepting user input---the
+@dfn{minibuffer window} (@pxref{Minibuffer Windows}). Since the
+minibuffer window is used for displaying text, it has a body but it does
+not have a tab or header line or any margins. Finally, a @dfn{tooltip
+window} which is used for displaying a tooltip in a tooltip frame
+(@pxref{Tooltips}) has a body too but no decorations at all.
-The selected window is considered part of a group when the buffer
-local variable @code{selected-window-group-function} is set to a
-function. In this case, @code{selected-window-group} calls it with no
-arguments and returns its result (which should be the list of windows
-in the group).
-@end defun
@node Windows and Frames
@section Windows and Frames
-Each window belongs to exactly one frame (@pxref{Frames}).
+Each window belongs to exactly one frame (@pxref{Frames}). For all
+windows belonging to a specific frame, we sometimes also say that these
+windows are @dfn{owned} by that frame or simply that they are on that
+frame.
@defun window-frame &optional window
-This function returns the frame that the window @var{window} belongs
-to. If @var{window} is @code{nil}, it defaults to the selected
-window.
+This function returns the specified @var{window}'s frame---the frame
+that @var{window} belongs to. If @var{window} is omitted or @code{nil},
+it defaults to the selected window (@pxref{Selecting Windows}).
@end defun
@defun window-list &optional frame minibuffer window
-This function returns a list of live windows belonging to the frame
+This function returns a list of all live windows owned by the specified
@var{frame}. If @var{frame} is omitted or @code{nil}, it defaults to
-the selected frame.
+the selected frame (@pxref{Input Focus}).
-The optional argument @var{minibuffer} specifies whether to include
-the minibuffer window in the returned list. If @var{minibuffer} is
-@code{t}, the minibuffer window is included. If @var{minibuffer} is
+The optional argument @var{minibuffer} specifies whether to include the
+minibuffer window (@pxref{Minibuffer Windows}) in that list. If
+@var{minibuffer} is @code{t}, the minibuffer window is included. If
@code{nil} or omitted, the minibuffer window is included only if it is
active. If @var{minibuffer} is neither @code{nil} nor @code{t}, the
minibuffer window is never included.
-The optional argument @var{window}, if non-@code{nil}, should be a live
+The optional argument @var{window}, if non-@code{nil}, must be a live
window on the specified frame; then @var{window} will be the first
element in the returned list. If @var{window} is omitted or @code{nil},
-the window selected within the frame is the first element.
+the window selected within @var{frame} (@pxref{Selecting Windows}) is
+the first element.
@end defun
@cindex window tree
@cindex root window
- Windows in the same frame are organized into a @dfn{window tree},
+ Windows on the same frame are organized into a @dfn{window tree},
whose leaf nodes are the live windows. The internal nodes of a window
tree are not live; they exist for the purpose of organizing the
relationships between live windows. The root node of a window tree is
-called the @dfn{root window}. It can be either a live window (if the
-frame has just one window), or an internal window.
-
- A minibuffer window (@pxref{Minibuffer Windows}) that is not alone
-on its frame does not have a parent window, so it strictly speaking is
-not part of its frame's window tree. Nonetheless, it is a sibling
-window of the frame's root window, and thus can be reached via
-@code{window-next-sibling}. Also, the function @code{window-tree}
-described at the end of this section lists the minibuffer window
-alongside the actual window tree.
+called the @dfn{root window}. It is either a live window or an
+internal window. If it is a live window, then the frame has just one
+window besides the minibuffer window, or the frame is a
+minibuffer-only frame, @pxref{Frame Layout}.
+
+ A minibuffer window (@pxref{Minibuffer Windows}) that is not alone on
+its frame does not have a parent window, so it strictly speaking is not
+part of its frame's window tree. Nonetheless, it is a sibling window of
+the frame's root window, and thus can be reached from the root window via
+@code{window-next-sibling}, see below. Also, the function
+@code{window-tree} described at the end of this section lists the
+minibuffer window alongside the actual window tree.
@defun frame-root-window &optional frame-or-window
This function returns the root window for @var{frame-or-window}. The
@@ -217,15 +273,15 @@ of that window's frame.
@cindex parent window
@cindex child window
@cindex sibling window
- When a window is split, there are two live windows where previously
-there was one. One of these is represented by the same Lisp window
-object as the original window, and the other is represented by a
-newly-created Lisp window object. Both of these live windows become
-leaf nodes of the window tree, as @dfn{child windows} of a single
-internal window. If necessary, Emacs automatically creates this
-internal window, which is also called the @dfn{parent window}, and
-assigns it to the appropriate position in the window tree. A set of
-windows that share the same parent are called @dfn{siblings}.
+ When a live window is split (@pxref{Splitting Windows}), there are two
+live windows where previously there was one. One of these is
+represented by the same Lisp window object as the original window, and
+the other is represented by a newly-created Lisp window object. Both of
+these live windows become leaf nodes of the window tree, as @dfn{child
+windows} of a single internal window. If necessary, Emacs automatically
+creates this internal window, which is also called the @dfn{parent
+window}, and assigns it to the appropriate position in the window tree.
+The set of windows that share the same parent are called @dfn{siblings}.
@cindex parent window
@defun window-parent &optional window
@@ -235,16 +291,16 @@ window. The return value is @code{nil} if @var{window} has no parent
(i.e., it is a minibuffer window or the root window of its frame).
@end defun
- Each internal window always has at least two child windows. If this
-number falls to one as a result of window deletion, Emacs
-automatically deletes the internal window, and its sole remaining
-child window takes its place in the window tree.
+ A parent window always has at least two child windows. If this number
+were to fall to one as a result of window deletion (@pxref{Deleting
+Windows}), Emacs automatically deletes the parent window too, and its
+sole remaining child window takes its place in the window tree.
- Each child window can be either a live window, or an internal window
+ A child window can be either a live window, or an internal window
(which in turn would have its own child windows). Therefore, each
internal window can be thought of as occupying a certain rectangular
-@dfn{screen area}---the union of the areas occupied by the live
-windows that are ultimately descended from it.
+@dfn{screen area}---the union of the areas occupied by the live windows
+that are ultimately descended from it.
@cindex window combination
@cindex vertical combination
@@ -284,7 +340,9 @@ windows @var{W4} and @var{W5}. Hence, the live windows in this
window tree are @var{W2}, @var{W4}, and @var{W5}.
The following functions can be used to retrieve a child window of an
-internal window, and the siblings of a child window.
+internal window, and the siblings of a child window. Their @var{window}
+argument always defaults to the selected window (@pxref{Selecting
+Windows}).
@defun window-top-child &optional window
This function returns the topmost child window of @var{window}, if
@@ -309,8 +367,7 @@ the leftmost child window for a horizontal combination. If
@defun window-combined-p &optional window horizontal
This function returns a non-@code{nil} value if and only if
-@var{window} is part of a vertical combination. If @var{window} is
-omitted or @code{nil}, it defaults to the selected one.
+@var{window} is part of a vertical combination.
If the optional argument @var{horizontal} is non-@code{nil}, this
means to return non-@code{nil} if and only if @var{window} is part of
@@ -318,24 +375,21 @@ a horizontal combination.
@end defun
@defun window-next-sibling &optional window
-This function returns the next sibling of the window @var{window}. If
-omitted or @code{nil}, @var{window} defaults to the selected window.
-The return value is @code{nil} if @var{window} is the last child of
-its parent.
+This function returns the next sibling of the specified @var{window}. The
+return value is @code{nil} if @var{window} is the last child of its
+parent.
@end defun
@defun window-prev-sibling &optional window
-This function returns the previous sibling of the window @var{window}.
-If omitted or @code{nil}, @var{window} defaults to the selected
-window. The return value is @code{nil} if @var{window} is the first
-child of its parent.
+This function returns the previous sibling of the specified @var{window}.
+The return value is @code{nil} if @var{window} is the first child of its
+parent.
@end defun
-The functions @code{window-next-sibling} and
-@code{window-prev-sibling} should not be confused with the functions
-@code{next-window} and @code{previous-window}, which return the next
-and previous window, respectively, in the cyclic ordering of windows
-(@pxref{Cyclic Window Ordering}).
+The functions @code{window-next-sibling} and @code{window-prev-sibling}
+should not be confused with the functions @code{next-window} and
+@code{previous-window}, which return the next and previous window in the
+cyclic ordering of windows (@pxref{Cyclic Window Ordering}).
The following functions can be useful to locate a window within its
frame.
@@ -408,8 +462,7 @@ Don't use this function to check whether there is @emph{no} window in
much more efficient way to do that.
@end defun
-The following function allows the entire window tree of a frame to be
-retrieved:
+The following function retrieves the entire window tree of a frame:
@defun window-tree &optional frame
This function returns a list representing the window tree for frame
@@ -433,54 +486,218 @@ internal window). The @var{edges} element is a list @code{(@var{left}
@end defun
+@node Selecting Windows
+@section Selecting Windows
+@cindex selecting a window
+
+@cindex selected window
+@cindex window selected within a frame
+ In each frame, at any time, exactly one Emacs window is designated
+as @dfn{selected within the frame}. For the selected frame, that
+window is called the @dfn{selected window}---the one in which most
+editing takes place, and in which the cursor for selected windows
+appears (@pxref{Cursor Parameters}). Keyboard input that inserts or
+deletes text is also normally directed to this window. The selected
+window's buffer is usually also the current buffer, except when
+@code{set-buffer} has been used (@pxref{Current Buffer}). As for
+non-selected frames, the window selected within the frame becomes the
+selected window if the frame is ever selected.
+
+@defun selected-window
+This function returns the selected window (which is always a live
+window).
+@end defun
+
+The following function explicitly selects a window and its frame.
+
+@defun select-window window &optional norecord
+This function makes @var{window} the selected window and the window
+selected within its frame, and selects that frame. It also makes
+@var{window}'s buffer (@pxref{Buffers and Windows}) current and sets
+that buffer's value of @code{point} to the value of @code{window-point}
+(@pxref{Window Point}) in @var{window}. @var{window} must be a live
+window. The return value is @var{window}.
+
+By default, this function also moves @var{window}'s buffer to the front
+of the buffer list (@pxref{Buffer List}) and makes @var{window} the most
+recently selected window. If the optional argument @var{norecord} is
+non-@code{nil}, these additional actions are omitted.
+
+In addition, this function by default also tells the display engine to
+update the display of @var{window} when its frame gets redisplayed the
+next time. If @var{norecord} is non-@code{nil}, such updates are
+usually not performed. If, however, @var{norecord} equals the special
+symbol @code{mark-for-redisplay}, the additional actions mentioned above
+are omitted but @var{window}'s display will be nevertheless updated.
+
+Note that sometimes selecting a window is not enough to show it, or
+make its frame the top-most frame on display: you may also need to
+raise the frame or make sure input focus is directed to that frame.
+@xref{Input Focus}.
+@end defun
+
+@cindex select window hooks
+@cindex running a hook when a window gets selected
+For historical reasons, Emacs does not run a separate hook whenever a
+window gets selected. Applications and internal routines often
+temporarily select a window to perform a few actions on it. They do
+that either to simplify coding---because many functions by default
+operate on the selected window when no @var{window} argument is
+specified---or because some functions did not (and still do not) take a
+window as argument and always operate(d) on the selected window instead.
+Running a hook every time a window gets selected for a short time and
+once more when the previously selected window gets restored is not
+useful.
+
+ However, when its @var{norecord} argument is @code{nil},
+@code{select-window} updates the buffer list and thus indirectly runs
+the normal hook @code{buffer-list-update-hook} (@pxref{Buffer List}).
+Consequently, that hook provides one way to run a function whenever a
+window gets selected more ``permanently''.
+
+ Since @code{buffer-list-update-hook} is also run by functions that are
+not related to window management, it will usually make sense to save the
+value of the selected window somewhere and compare it with the value of
+@code{selected-window} while running that hook. Also, to avoid false
+positives when using @code{buffer-list-update-hook}, it is good practice
+that every @code{select-window} call supposed to select a window only
+temporarily passes a non-@code{nil} @var{norecord} argument. If
+possible, the macro @code{with-selected-window} (see below) should be
+used in such cases.
+
+ Emacs also runs the hook @code{window-selection-change-functions}
+whenever the redisplay routine detects that another window has been
+selected since last redisplay. @xref{Window Hooks}, for a detailed
+explanation. @code{window-state-change-functions} (described in the
+same section) is another abnormal hook run after a different window
+has been selected but is triggered by other window changes as well.
+
+@cindex most recently selected windows
+ The sequence of calls to @code{select-window} with a non-@code{nil}
+@var{norecord} argument determines an ordering of windows by their
+selection or use time, see below. The function @code{get-lru-window},
+for example, can then be used to retrieve the least recently selected
+window (@pxref{Cyclic Window Ordering}).
+
+@defun frame-selected-window &optional frame
+This function returns the window on @var{frame} that is selected
+within that frame. @var{frame} should be a live frame; if omitted or
+@code{nil}, it defaults to the selected frame.
+@end defun
+
+@defun set-frame-selected-window frame window &optional norecord
+This function makes @var{window} the window selected within the frame
+@var{frame}. @var{frame} should be a live frame; if @code{nil}, it
+defaults to the selected frame. @var{window} should be a live window;
+if @code{nil}, it defaults to the selected window.
+
+If @var{frame} is the selected frame, this makes @var{window} the
+selected window.
+
+If the optional argument @var{norecord} is non-@code{nil}, this function
+does not alter the ordering of the most recently selected windows, nor
+the buffer list.
+@end defun
+
+ The following macros are useful to temporarily select a window without
+affecting the ordering of recently selected windows or the buffer list.
+
+@defmac save-selected-window forms@dots{}
+This macro records the selected frame, as well as the selected window
+of each frame, executes @var{forms} in sequence, then restores the
+earlier selected frame and windows. It also saves and restores the
+current buffer. It returns the value of the last form in @var{forms}.
+
+This macro does not save or restore anything about the sizes,
+arrangement or contents of windows; therefore, if @var{forms} change
+them, the change persists. If the previously selected window of some
+frame is no longer live at the time of exit from @var{forms}, that
+frame's selected window is left alone. If the previously selected
+window is no longer live, then whatever window is selected at the end of
+@var{forms} remains selected. The current buffer is restored if and
+only if it is still live when exiting @var{forms}.
+
+This macro changes neither the ordering of recently selected windows nor
+the buffer list.
+@end defmac
+
+@defmac with-selected-window window forms@dots{}
+This macro selects @var{window}, executes @var{forms} in sequence, then
+restores the previously selected window and current buffer. The
+ordering of recently selected windows and the buffer list remain
+unchanged unless you deliberately change them within @var{forms}; for
+example, by calling @code{select-window} with argument @var{norecord}
+@code{nil}. Hence, this macro is the preferred way to temporarily work
+with @var{window} as the selected window without needlessly running
+@code{buffer-list-update-hook}.
+@end defmac
+
+@defmac with-selected-frame frame forms@dots{}
+This macro executes @var{forms} with @var{frame} as the selected
+frame. The value returned is the value of the last form in
+@var{forms}. This macro saves and restores the selected frame, and
+changes the order of neither the recently selected windows nor the
+buffers in the buffer list.
+@end defmac
+
+@cindex window use time
+@cindex use time of window
+@cindex window order by time of last use
+@defun window-use-time &optional window
+This function returns the use time of window @var{window}. @var{window}
+must be a live window and defaults to the selected one.
+
+The @dfn{use time} of a window is not really a time value, but an
+integer that does increase monotonically with each call of
+@code{select-window} with a @code{nil} @var{norecord} argument. The
+window with the lowest use time is usually called the least recently
+used window while the window with the highest use time is called the
+most recently used one (@pxref{Cyclic Window Ordering}).
+@end defun
+
+@defun window-bump-use-time &optional window
+This function marks @var{window} as being the most recently used
+one. This can be useful when writing certain @code{pop-to-buffer}
+scenarios (@pxref{Switching Buffers}). @var{window} must be a live
+window and defaults to the selected one.
+@end defun
+
+@anchor{Window Group}Sometimes several windows collectively and
+cooperatively display a buffer, for example, under the management of
+Follow Mode (@pxref{Follow Mode,,, emacs}), where the windows together
+display a bigger portion of the buffer than one window could alone.
+It is often useful to consider such a @dfn{window group} as a single
+entity. Several functions such as @code{window-group-start}
+(@pxref{Window Start and End}) allow you to do this by supplying, as
+an argument, one of the windows as a stand-in for the whole group.
+
+@defun selected-window-group
+@vindex selected-window-group-function
+When the selected window is a member of a group of windows, this
+function returns a list of the windows in the group, ordered such that
+the first window in the list is displaying the earliest part of the
+buffer, and so on. Otherwise the function returns a list containing
+just the selected window.
+
+The selected window is considered part of a group when the buffer
+local variable @code{selected-window-group-function} is set to a
+function. In this case, @code{selected-window-group} calls it with no
+arguments and returns its result (which should be the list of windows
+in the group).
+@end defun
+
+
@node Window Sizes
@section Window Sizes
@cindex window size
@cindex size of window
- The following schematic shows the structure of a live window:
-
-@smallexample
-@group
- ____________________________________________
- |______________ Header Line ______________|RD| ^
- ^ |LS|LM|LF| |RF|RM|RS| | |
- | | | | | | | | | | |
-Window | | | | Text Area | | | | | Window
-Body | | | | | (Window Body) | | | | | Total
-Height | | | | | | | | | Height
- | | | | |<- Window Body Width ->| | | | | |
- v |__|__|__|_______________________|__|__|__| | |
- |_________ Horizontal Scroll Bar _________| | |
- |_______________ Mode Line _______________|__| |
- |_____________ Bottom Divider _______________| v
- <---------- Window Total Width ------------>
-
-@end group
-@end smallexample
-
-@cindex window body
-@cindex text area of a window
-@cindex body of a window
- At the center of the window is the @dfn{text area}, or @dfn{body},
-where the buffer text is displayed. The text area can be surrounded by
-a series of optional areas. On the left and right, from innermost to
-outermost, these are the left and right fringes, denoted by LF and RF
-(@pxref{Fringes}); the left and right margins, denoted by LM and RM in
-the schematic (@pxref{Display Margins}); the left or right vertical
-scroll bar, only one of which is present at any time, denoted by LS and
-RS (@pxref{Scroll Bars}); and the right divider, denoted by RD
-(@pxref{Window Dividers}). At the top of the window is the header line
-(@pxref{Header Lines}). At the bottom of the window are the horizontal
-scroll bar (@pxref{Scroll Bars}); the mode line (@pxref{Mode Line
-Format}); and the bottom divider (@pxref{Window Dividers}).
-
- Emacs provides miscellaneous functions for finding the height and
-width of a window. The return value of many of these functions can be
+Emacs provides miscellaneous functions for finding the height and width
+of a window. The return value of many of these functions can be
specified either in units of pixels or in units of lines and columns.
On a graphical display, the latter actually correspond to the height and
-width of a default character specified by the frame's default font
-as returned by @code{frame-char-height} and @code{frame-char-width}
+width of a default character specified by the frame's default font as
+returned by @code{frame-char-height} and @code{frame-char-width}
(@pxref{Frame Font}). Thus, if a window is displaying text with a
different font or size, the reported line height and column width for
that window may differ from the actual number of text lines or columns
@@ -490,8 +707,7 @@ displayed within it.
@cindex height of a window
@cindex total height of a window
The @dfn{total height} of a window is the number of lines comprising
-the window's body, the header line, the horizontal scroll bar, the mode
-line and the bottom divider (if any).
+its body and its top and bottom decorations (@pxref{Basic Windows}).
@defun window-total-height &optional window round
This function returns the total height, in lines, of the window
@@ -521,9 +737,8 @@ with any other @var{round} it returns the internal value of
@cindex window width
@cindex width of a window
@cindex total width of a window
-The @dfn{total width} of a window is the number of lines comprising the
-window's body, its margins, fringes, scroll bars and a right divider (if
-any).
+The @dfn{total width} of a window is the number of lines comprising its
+body and its left and right decorations (@pxref{Basic Windows}).
@defun window-total-width &optional window round
This function returns the total width, in columns, of the window
@@ -564,10 +779,9 @@ window in units of pixels.
This function returns the total height of window @var{window} in pixels.
@var{window} must be a valid window and defaults to the selected one.
-The return value includes mode and header line, a horizontal scroll bar
-and a bottom divider, if any. If @var{window} is an internal window,
-its pixel height is the pixel height of the screen areas spanned by its
-children.
+The return value includes the heights of @var{window}'s top and bottom
+decorations. If @var{window} is an internal window, its pixel height is
+the pixel height of the screen areas spanned by its children.
@end defun
@cindex window pixel width
@@ -578,10 +792,9 @@ children.
This function returns the width of window @var{window} in pixels.
@var{window} must be a valid window and defaults to the selected one.
-The return value includes the fringes and margins of @var{window} as
-well as any vertical dividers or scroll bars belonging to @var{window}.
-If @var{window} is an internal window, its pixel width is the width of
-the screen areas spanned by its children.
+The return value includes the widths of @var{window}'s left and right
+decorations. If @var{window} is an internal window, its pixel width is
+the width of the screen areas spanned by its children.
@end defun
@cindex full-width window
@@ -607,9 +820,9 @@ that of the root window on that frame. If @var{window} is omitted or
@cindex window body height
@cindex body height of a window
-The @dfn{body height} of a window is the height of its text area, which
-does not include a mode or header line, a horizontal scroll bar, or a
-bottom divider.
+The @dfn{body height} of a window is the height of its body, which
+does not include any of its top or bottom decorations (@pxref{Basic
+Windows}).
@defun window-body-height &optional window pixelwise
This function returns the height, in lines, of the body of window
@@ -628,8 +841,10 @@ exceed its total height as returned by @code{window-total-height}.
@cindex window body width
@cindex body width of a window
-The @dfn{body width} of a window is the width of its text area, which
-does not include the scroll bar, fringes, margins or a right divider.
+The @dfn{body width} of a window is the width of its body and of the
+text area, which does not include any of its left or right decorations
+(@pxref{Basic Windows}).
+
Note that when one or both fringes are removed (by setting their width
to zero), the display engine reserves two character cells, one on each
side of the window, for displaying the continuation and truncation
@@ -662,16 +877,11 @@ to calling @code{window-body-width}. In either case, the optional
argument @var{pixelwise} is passed to the function called.
@end defun
-For compatibility with previous versions of Emacs,
-@code{window-height} is an alias for @code{window-total-height}, and
-@code{window-width} is an alias for @code{window-body-width}. These
-aliases are considered obsolete and will be removed in the future.
-
- The pixel heights of a window's mode and header line can be retrieved
-with the functions given below. Their return value is usually accurate
-unless the window has not been displayed before: In that case, the
-return value is based on an estimate of the font used for the window's
-frame.
+ The pixel heights of a window's mode, tab and header line can be
+retrieved with the functions given below. Their return value is usually
+accurate unless the window has not been displayed before: In that case,
+the return value is based on an estimate of the font used for the
+window's frame.
@defun window-mode-line-height &optional window
This function returns the height in pixels of @var{window}'s mode line.
@@ -679,6 +889,12 @@ This function returns the height in pixels of @var{window}'s mode line.
@var{window} has no mode line, the return value is zero.
@end defun
+@defun window-tab-line-height &optional window
+This function returns the height in pixels of @var{window}'s tab line.
+@var{window} must be a live window and defaults to the selected one. If
+@var{window} has no tab line, the return value is zero.
+@end defun
+
@defun window-header-line-height &optional window
This function returns the height in pixels of @var{window}'s header
line. @var{window} must be a live window and defaults to the selected
@@ -720,15 +936,14 @@ size (@pxref{Preserving Window Sizes}).
@defopt window-min-height
This option specifies the minimum total height, in lines, of any window.
-Its value has to accommodate at least one text line as well as a mode
-and header line, a horizontal scroll bar and a bottom divider, if
-present.
+Its value has to accommodate at least one text line and any top or
+bottom decorations.
@end defopt
@defopt window-min-width
This option specifies the minimum total width, in columns, of any
-window. Its value has to accommodate two text columns as well as
-margins, fringes, a scroll bar and a right divider, if present.
+window. Its value has to accommodate at least two text columns and any
+left or right decorations.
@end defopt
The following function tells how small a specific window can get taking
@@ -745,10 +960,9 @@ of @var{window}'s lines.
The return value makes sure that all components of @var{window} remain
fully visible if @var{window}'s size were actually set to it. With
-@var{horizontal} @code{nil} it includes the mode and header line, the
-horizontal scroll bar and the bottom divider, if present. With
-@var{horizontal} non-@code{nil} it includes the margins and fringes, the
-vertical scroll bar and the right divider, if present.
+@var{horizontal} @code{nil} it includes any top or bottom decorations.
+With @var{horizontal} non-@code{nil} it includes any left or right
+decorations of @var{window}.
The optional argument @var{ignore}, if non-@code{nil}, means ignore
restrictions imposed by fixed size windows, @code{window-min-height} or
@@ -770,10 +984,10 @@ minimum size of @var{window} counted in pixels.
@cindex changing window size
@cindex window size, changing
- This section describes functions for resizing a window without
-changing the size of its frame. Because live windows do not overlap,
-these functions are meaningful only on frames that contain two or more
-windows: resizing a window also changes the size of a neighboring
+This section describes functions for resizing a window without changing
+the size of its frame. Because live windows do not overlap, these
+functions are meaningful only on frames that contain two or more
+windows: resizing a window also changes the size of at least one other
window. If there is just one window on a frame, its size cannot be
changed except by resizing the frame (@pxref{Frame Size}).
@@ -801,11 +1015,10 @@ Normally, the variables @code{window-min-height} and
(@pxref{Window Sizes}). However, if the optional argument @var{ignore}
is non-@code{nil}, this function ignores @code{window-min-height} and
@code{window-min-width}, as well as @code{window-size-fixed}. Instead,
-it considers the minimum-height window to be one consisting of a header
-and a mode line, a horizontal scrollbar and a bottom divider (if any),
-plus a text area one line tall; and a minimum-width window as one
-consisting of fringes, margins, a scroll bar and a right divider (if
-any), plus a text area two columns wide.
+it considers the minimum height of a window as the sum of its top and
+bottom decorations plus the text of one line; and its minimum width
+as the sum of its left and right decorations plus text that takes two
+columns.
If the optional argument @var{pixelwise} is non-@code{nil},
@var{delta} is interpreted as pixels.
@@ -889,7 +1102,7 @@ that this function can give @var{window}. The optional argument
@var{min-height}, if non-@code{nil}, specifies the minimum total height
that it can give, which overrides the variable @code{window-min-height}.
Both @var{max-height} and @var{min-height} are specified in lines and
-include mode and header line and a bottom divider, if any.
+include any top or bottom decorations of @var{window}.
If @var{window} is part of a horizontal combination and the value of the
option @code{fit-window-to-buffer-horizontally} (see below) is
@@ -900,8 +1113,8 @@ The optional argument @var{max-width} specifies a maximum width and
defaults to the width of @var{window}'s frame. The optional argument
@var{min-width} specifies a minimum width and defaults to
@code{window-min-width}. Both @var{max-width} and @var{min-width} are
-specified in columns and include fringes, margins and scrollbars, if
-any.
+specified in columns and include any left or right decorations of
+@var{window}.
The optional argument @var{preserve-size}, if non-@code{nil}, will
install a parameter to preserve the size of @var{window} during future
@@ -1144,19 +1357,18 @@ Sizes}). Thus, it signals an error if splitting would result in making
a window smaller than those variables specify. However, a
non-@code{nil} value for @var{size} causes those variables to be
ignored; in that case, the smallest allowable window is considered to be
-one that has space for a text area one line tall and/or two columns
+one that has space for a text that is one line tall and/or two columns
wide.
Hence, if @var{size} is specified, it's the caller's responsibility to
-check whether the emanating windows are large enough to encompass all
-areas like a mode line or a scroll bar. The function
+check whether the emanating windows are large enough to encompass all of
+their decorations like a mode line or a scroll bar. The function
@code{window-min-size} (@pxref{Window Sizes}) can be used to determine
the minimum requirements of @var{window} in this regard. Since the new
-window usually inherits areas like the mode line or the scroll bar
-from @var{window}, that function is also a good guess for the minimum
-size of the new window. The caller should specify a smaller size only
-if it correspondingly removes an inherited area before the next
-redisplay.
+window usually inherits areas like the mode line or the scroll bar from
+@var{window}, that function is also a good guess for the minimum size of
+the new window. The caller should specify a smaller size only if it
+correspondingly removes an inherited area before the next redisplay.
The optional third argument @var{side} determines the position of the
new window relative to @var{window}. If it is @code{nil} or
@@ -1762,153 +1974,6 @@ distribute its space proportionally among the two remaining live
windows.
-@node Selecting Windows
-@section Selecting Windows
-@cindex selecting a window
-
-@defun select-window window &optional norecord
-This function makes @var{window} the selected window and the window
-selected within its frame (@pxref{Basic Windows}), and selects that
-frame. It also makes @var{window}'s buffer (@pxref{Buffers and
-Windows}) current and sets that buffer's value of @code{point} to the
-value of @code{window-point} (@pxref{Window Point}) in @var{window}.
-@var{window} must be a live window. The return value is @var{window}.
-
-By default, this function also moves @var{window}'s buffer to the front
-of the buffer list (@pxref{Buffer List}) and makes @var{window} the most
-recently selected window. If the optional argument @var{norecord} is
-non-@code{nil}, these additional actions are omitted.
-
-In addition, this function by default also tells the display engine to
-update the display of @var{window} when its frame gets redisplayed the
-next time. If @var{norecord} is non-@code{nil}, such updates are
-usually not performed. If, however, @var{norecord} equals the special
-symbol @code{mark-for-redisplay}, the additional actions mentioned above
-are omitted but @var{window} will be nevertheless updated.
-
-Note that sometimes selecting a window is not enough to show it, or
-make its frame the top-most frame on display: you may also need to
-raise the frame or make sure input focus is directed to that frame.
-@xref{Input Focus}.
-@end defun
-
-@cindex select window hooks
-@cindex running a hook when a window gets selected
-For historical reasons, Emacs does not run a separate hook whenever a
-window gets selected. Applications and internal routines often
-temporarily select a window to perform a few actions on it. They do
-that either to simplify coding---because many functions by default
-operate on the selected window when no @var{window} argument is
-specified---or because some functions did not (and still do not) take a
-window as argument and always operate(d) on the selected window instead.
-Running a hook every time a window gets selected for a short time and
-once more when the previously selected window gets restored is not
-useful.
-
- However, when its @var{norecord} argument is @code{nil},
-@code{select-window} updates the buffer list and thus indirectly runs
-the normal hook @code{buffer-list-update-hook} (@pxref{Buffer List}).
-Consequently, that hook provides one way to run a function whenever a
-window gets selected more ``permanently''.
-
- Since @code{buffer-list-update-hook} is also run by functions that are
-not related to window management, it will usually make sense to save the
-value of the selected window somewhere and compare it with the value of
-@code{selected-window} while running that hook. Also, to avoid false
-positives when using @code{buffer-list-update-hook}, it is good practice
-that every @code{select-window} call supposed to select a window only
-temporarily passes a non-@code{nil} @var{norecord} argument. If
-possible, the macro @code{with-selected-window} (see below) should be
-used in such cases.
-
- Emacs also runs the hook @code{window-selection-change-functions}
-whenever the redisplay routine detects that another window has been
-selected since last redisplay. @xref{Window Hooks}, for a detailed
-explanation. @code{window-state-change-functions} (described in the
-same section) is another abnormal hook run after a different window
-has been selected but is triggered by other window changes as well.
-
-@cindex most recently selected windows
- The sequence of calls to @code{select-window} with a non-@code{nil}
-@var{norecord} argument determines an ordering of windows by their
-selection time. The function @code{get-lru-window} can be used to
-retrieve the least recently selected live window (@pxref{Cyclic Window
-Ordering}).
-
-@defmac save-selected-window forms@dots{}
-This macro records the selected frame, as well as the selected window
-of each frame, executes @var{forms} in sequence, then restores the
-earlier selected frame and windows. It also saves and restores the
-current buffer. It returns the value of the last form in @var{forms}.
-
-This macro does not save or restore anything about the sizes,
-arrangement or contents of windows; therefore, if @var{forms} change
-them, the change persists. If the previously selected window of some
-frame is no longer live at the time of exit from @var{forms}, that
-frame's selected window is left alone. If the previously selected
-window is no longer live, then whatever window is selected at the end of
-@var{forms} remains selected. The current buffer is restored if and
-only if it is still live when exiting @var{forms}.
-
-This macro changes neither the ordering of recently selected windows nor
-the buffer list.
-@end defmac
-
-@defmac with-selected-window window forms@dots{}
-This macro selects @var{window}, executes @var{forms} in sequence, then
-restores the previously selected window and current buffer. The
-ordering of recently selected windows and the buffer list remain
-unchanged unless you deliberately change them within @var{forms}; for
-example, by calling @code{select-window} with argument @var{norecord}
-@code{nil}. Hence, this macro is the preferred way to temporarily work
-with @var{window} as the selected window without needlessly running
-@code{buffer-list-update-hook}.
-@end defmac
-
-@defmac with-selected-frame frame forms@dots{}
-This macro executes @var{forms} with @var{frame} as the selected
-frame. The value returned is the value of the last form in
-@var{forms}. This macro saves and restores the selected frame, and
-changes the order of neither the recently selected windows nor the
-buffers in the buffer list.
-@end defmac
-
-@defun frame-selected-window &optional frame
-This function returns the window on @var{frame} that is selected
-within that frame. @var{frame} should be a live frame; if omitted or
-@code{nil}, it defaults to the selected frame.
-@end defun
-
-@defun set-frame-selected-window frame window &optional norecord
-This function makes @var{window} the window selected within the frame
-@var{frame}. @var{frame} should be a live frame; if @code{nil}, it
-defaults to the selected frame. @var{window} should be a live window;
-if @code{nil}, it defaults to the selected window.
-
-If @var{frame} is the selected frame, this makes @var{window} the
-selected window.
-
-If the optional argument @var{norecord} is non-@code{nil}, this
-function does not alter the list of most recently selected windows,
-nor the buffer list.
-@end defun
-
-@cindex window use time
-@cindex use time of window
-@cindex window order by time of last use
-@defun window-use-time &optional window
-This functions returns the use time of window @var{window}.
-@var{window} must be a live window and defaults to the selected one.
-
-The @dfn{use time} of a window is not really a time value, but an
-integer that does increase monotonically with each call of
-@code{select-window} with a @code{nil} @var{norecord} argument. The
-window with the lowest use time is usually called the least recently
-used window while the window with the highest use time is called the
-most recently used one (@pxref{Cyclic Window Ordering}).
-@end defun
-
-
@node Cyclic Window Ordering
@section Cyclic Ordering of Windows
@cindex cyclic ordering of windows
@@ -2036,8 +2101,11 @@ criterion, without selecting it:
@cindex least recently used window
@defun get-lru-window &optional all-frames dedicated not-selected no-other
This function returns a live window which is heuristically the least
-recently used. The optional argument @var{all-frames} has
-the same meaning as in @code{next-window}.
+recently used one. The @dfn{least recently used window} is the least
+recently selected one---the window whose use time is less than the use
+time of all other live windows (@pxref{Selecting Windows}). The
+optional argument @var{all-frames} has the same meaning as in
+@code{next-window}.
If any full-width windows are present, only those windows are
considered. A minibuffer window is never a candidate. A dedicated
@@ -2053,8 +2121,14 @@ function returns @code{nil} in that case. The optional argument
@cindex most recently used window
@defun get-mru-window &optional all-frames dedicated not-selected no-other
This function is like @code{get-lru-window}, but it returns the most
-recently used window instead. The meaning of the arguments is the
-same as for @code{get-lru-window}.
+recently used window instead. The @dfn{most recently used window} is
+the most recently selected one---the window whose use time exceeds the
+use time of all other live windows (@pxref{Selecting Windows}). The
+meaning of the arguments is the same as for @code{get-lru-window}.
+
+Since in practice the most recently used window is always the selected
+one, it usually makes sense to call this function with a non-@code{nil}
+@var{not-selected} argument only.
@end defun
@cindex largest window
@@ -2919,9 +2993,9 @@ A non-@code{nil} value prevents another frame from being raised or
selected, if the window chosen by @code{display-buffer} is displayed
there. Primarily affected by this are
@code{display-buffer-use-some-frame} and
-@code{display-buffer-reuse-window}.
-@code{display-buffer-pop-up-frame} should be affected as well, but
-there is no guarantee that the window manager will comply.
+@code{display-buffer-reuse-window}. Ideally,
+@code{display-buffer-pop-up-frame} should be affected as well, but there
+is no guarantee that the window manager will comply.
@vindex window-parameters@r{, a buffer display action alist entry}
@item window-parameters
@@ -2964,11 +3038,16 @@ desired total height with respect to the total height of its frame's
root window.
@item
+A cons cell whose @sc{car} is @code{body-lines} and whose @sc{cdr} is an
+integer that specifies the height of the chosen window's body in frame
+lines.
+
+@item
If the value specifies a function, that function is called with one
argument---the chosen window. The function is supposed to adjust the
height of the window; its return value is ignored. Suitable functions
-are @code{shrink-window-if-larger-than-buffer} and
-@code{fit-window-to-buffer}, see @ref{Resizing Windows}.
+are @code{fit-window-to-buffer} and
+@code{shrink-window-if-larger-than-buffer}, see @ref{Resizing Windows}.
@end itemize
By convention, the height of the chosen window is adjusted only if the
@@ -2997,16 +3076,47 @@ desired total width with respect to the total width of the frame's
root window.
@item
+A cons cell whose @sc{car} is @code{body-columns} and whose @sc{cdr} is
+an integer that specifies the width of the chosen window's body in frame
+columns.
+
+@item
If the value specifies a function, that function is called with one
argument---the chosen window. The function is supposed to adjust the
width of the window; its return value is ignored.
@end itemize
-By convention, the width of the chosen window is adjusted only if the
-window is part of a horizontal combination (@pxref{Windows and
-Frames}) to avoid changing the width of other, unrelated windows.
-Also, this entry should be processed under only certain conditions
-which are specified right below this list.
+@vindex window-size@r{, a buffer display action alist entry}
+@item window-size
+This entry is a combination of the two preceding ones and can be used to
+adjust the chosen window's height @emph{and} width. Since windows can
+be resized in one direction only without affecting other windows,
+@code{window-size} is effective only to set up the size of a window
+appearing alone on a frame. The value can be one of the following:
+
+@itemize @bullet
+@item
+@code{nil} means to leave the size of the chosen window alone.
+
+@item
+A cons cell of two integers specifies the desired total width and height
+of the chosen window in lines and columns. It's effect is to adjust the
+size of the frame accordingly.
+
+@item
+A cons cell whose @sc{car} equals @code{body-chars} and whose @sc{cdr}
+is a cons cell of two integers---the desired body width and height of
+the chosen window in frame columns and lines. It's effect is to adjust
+the size of the frame accordingly.
+
+@item
+If the value specifies a function, that function is called with one
+argument---the chosen window. The function is supposed to adjust the
+size of the window's frame; its return value is ignored.
+@end itemize
+
+This entry should be processed under only certain conditions which are
+specified right below this list.
@vindex dedicated@r{, a buffer display action alist entry}
@item dedicated
@@ -3107,6 +3217,14 @@ the window was created earlier by @code{display-buffer} to show the
buffer and never was used to show another buffer until it was reused
by the current invocation of @code{display-buffer}.
+If no @code{window-height}, @code{window-width} or @code{window-size}
+entry was specified, the window may still be resized automatically when
+the buffer is temporary and @code{temp-buffer-resize-mode} has been
+enabled, @ref{Temporary Displays}. In that case, the @sc{cdr} of a
+@code{window-height}, @code{window-width} or @code{window-size} entry
+can be used to inhibit or override the default behavior of
+@code{temp-buffer-resize-mode} for specific buffers or invocations of
+@code{display-buffer}.
@node Choosing Window Options
@subsection Additional Options for Displaying Buffers
@@ -4111,97 +4229,48 @@ action alist entry (@pxref{Buffer Display Action Alists}).
@node Quitting Windows
@section Quitting Windows
-
-When you want to get rid of a window used for displaying a buffer, you
-can call @code{delete-window} or @code{delete-windows-on}
-(@pxref{Deleting Windows}) to remove that window from its frame. If the
-buffer is shown on a separate frame, you might want to call
-@code{delete-frame} (@pxref{Deleting Frames}) instead. If, on the other
-hand, a window has been reused for displaying the buffer, you might
-prefer showing the buffer previously shown in that window, by calling the
-function @code{switch-to-prev-buffer} (@pxref{Window History}).
-Finally, you might want to either bury (@pxref{Buffer List}) or kill
-(@pxref{Killing Buffers}) the window's buffer.
-
- The following command uses information on how the window for
-displaying the buffer was obtained in the first place, thus attempting
-to automate the above decisions for you.
+@cindex quitting windows
+
+After a command uses @code{display-buffer} to put a buffer on the
+screen, the user may decide to hide it and return to the previous
+configuration of the Emacs display. We call that @dfn{quitting the
+window}. The way to do this is to call @code{quit-window} while the
+window used by @code{display-buffer} is the selected window.
+
+The right way to restore the previous configuration of the display
+depends on what was done to the window where the buffer now appears.
+It might be right to delete that window, or delete its frame, or just
+display another buffer in that window. One complication is that the
+user may have changed the window configuration since the act of
+displaying that buffer, and it would be undesirable to undo the user's
+explicitly requested changes.
+
+To enable @code{quit-window} to do the right thing,
+@code{display-buffer} saves information about what it did in the
+window's @code{quit-restore} parameter (@pxref{Window Parameters}).
@deffn Command quit-window &optional kill window
This command quits @var{window} and buries its buffer. The argument
@var{window} must be a live window and defaults to the selected one.
With prefix argument @var{kill} non-@code{nil}, it kills the buffer
-instead of burying it. It calls the function @code{quit-restore-window}
-described next to deal with the window and its buffer.
+instead of burying it.
@vindex quit-window-hook
-The functions in @code{quit-window-hook} are run before doing anything
-else.
+The function @code{quit-window} first runs @code{quit-window-hook}.
+Then it calls the function @code{quit-restore-window}, described next,
+which does the hard work.
@end deffn
+You can get more control by calling @code{quit-restore-window} instead.
+
@defun quit-restore-window &optional window bury-or-kill
This function handles @var{window} and its buffer after quitting. The
optional argument @var{window} must be a live window and defaults to
-the selected one. The function's behavior is determined by the four
-elements of the list specified by @var{window}'s @code{quit-restore}
-parameter (@pxref{Window Parameters}).
-
-The first element of the @code{quit-restore} parameter is one of the
-symbols @code{window}, meaning that the window has been specially
-created by @code{display-buffer}; @code{frame}, a separate frame has
-been created; @code{same}, the window has only ever displayed this
-buffer; or @code{other}, the window showed another buffer before.
-@code{frame} and @code{window} affect how the window is quit, while
-@code{same} and @code{other} affect the redisplay of buffers
-previously shown in @var{window}.
-
-The parameter's second element is either one of the symbols
-@code{window} or @code{frame}, or a list whose elements are the buffer
-shown in @var{window} before, that buffer's window start and window
-point positions, and @var{window}'s height at that time. If that
-buffer is still live when @var{window} is quit, then this function may
-reuse @var{window} to display it.
-
-The third element is the window selected at the time the parameter was
-created. If this function deletes @var{window}, it subsequently tries
-to reselect the window named by that element.
-
-The fourth element is the buffer whose display caused the creation of
-this parameter. This function may delete @var{window} if and only if
-it still shows that buffer.
-
-This function will try to delete @var{window} if and only if (1) the
-first element of its @code{quit-restore} parameter is either
-@code{window} or @code{frame}, (2) the window has no history of
-previously-displayed buffers and (3) the fourth element of the
-@code{quit-restore} parameter specifies the buffer currently displayed
-in @var{window}. If @var{window} is part of an atomic window
-(@pxref{Atomic Windows}), it will try to delete the root of that
-atomic window instead. In either case, it tries to avoid signaling an
-error when @var{window} cannot be deleted.
-
-If @var{window} shall be deleted, is the only window on its frame and
-there are other frames on that frame's terminal, the value of the
-optional argument @var{bury-or-kill} determines how to proceed with
-the window. If @var{bury-or-kill} equals @code{kill}, the frame is
-deleted unconditionally. Otherwise, the fate of the frame is
-determined by calling @code{frame-auto-hide-function} (see below) with
-that frame as sole argument.
-
-If the third element of the @code{quit-restore} parameter is a list of
-buffer, window start (@pxref{Window Start and End}), and point
-(@pxref{Window Point}), and that buffer is still live, the buffer will
-be displayed, and start and point set accordingly. If, in addition,
-@var{window}'s buffer was temporarily resized, this function will also
-try to restore the original height of @var{window}.
-
-Otherwise, if @var{window} was previously used for displaying other
-buffers (@pxref{Window History}), the most recent buffer in that
-history will be displayed. In either case, if @var{window} is not
-deleted, its @code{quit-restore} parameter is reset to @code{nil}.
+the selected one. The function takes account of the @var{window}'s
+@code{quit-restore} parameter.
The optional argument @var{bury-or-kill} specifies how to deal with
-@var{window}'s buffer. The following values are handled:
+@var{window}'s buffer. The following values are meaningful:
@table @code
@item nil
@@ -4211,25 +4280,106 @@ consequence, if @var{window} is not deleted, invoking
@item append
This means that if @var{window} is not deleted, its buffer is moved to
-the end of @var{window}'s list of previous buffers, so it's less likely
-that a future invocation of @code{switch-to-prev-buffer} will switch to
-it. Also, it moves the buffer to the end of the frame's buffer list.
+the end of @var{window}'s list of previous buffers (@pxref{Window
+History}), so it's less likely that future invocations of
+@code{switch-to-prev-buffer} will switch to it. Also, it moves the
+buffer to the end of the frame's buffer list (@pxref{Buffer List}).
@item bury
This means that if @var{window} is not deleted, its buffer is removed
-from @var{window}'s list of previous buffers. Also, it moves the buffer
-to the end of the frame's buffer list. This value provides the most
-reliable remedy to not have @code{switch-to-prev-buffer} switch to this
-buffer again without killing the buffer.
+from @var{window}'s list of previous buffers. Also, it moves the
+buffer to the end of the frame's buffer list. This is the most
+reliable way to prevent @code{switch-to-prev-buffer} from switching to
+this buffer again, short of killing the buffer.
@item kill
This means to kill @var{window}'s buffer.
@end table
+The argument @var{bury-or-kill} also specifies what to do with
+@var{window}'s frame when @var{window} should be deleted, if it is the
+only window on its frame, and there are other frames on that frame's
+terminal. If @var{bury-or-kill} equals @code{kill}, it means to
+delete the frame. Otherwise, the fate of the frame is determined by
+calling @code{frame-auto-hide-function} (see below) with that frame as
+sole argument.
+
+This function always sets @var{window}'s @code{quit-restore} parameter
+to @code{nil} unless it deletes the window.
+@end defun
+
+The window @var{window}'s @code{quit-restore} parameter (@pxref{Window
+Parameters}) should be @code{nil} or a list of four elements:
+@c FIXME: describe what quit-restore-window does if this is nil.
+
+@lisp
+(@var{method} @var{obuffer} @var{owindow} @var{this-buffer})
+@end lisp
+
+The first element, @var{method}, is one of the four symbols
+@code{window}, @code{frame}, @code{same} and @code{other}.
+@code{frame} and @code{window} control how to delete @var{window},
+while @code{same} and @code{other} control displaying some other
+buffer in it.
+
+Specifically, @code{window} means that the window has been specially
+created by @code{display-buffer}; @code{frame} means that a separate
+frame has been created; @code{same}, that the window has only ever
+displayed this buffer; @code{other}, that the window showed another
+buffer before.
+
+The second element, @var{obuffer}, is either one of the symbols
+@code{window} or @code{frame}, or a list of the form
+
+@lisp
+(@var{prev-buffer} @var{prev-window-start} @var{prev-window-point} @var{height})
+@end lisp
+
+@noindent
+which says which buffer was shown in @var{window} before, that
+buffer's window start (@pxref{Window Start and End}) and window point
+(@pxref{Window Point}) positions at that time, and
+@var{window}'s height at that time. If @var{prev-buffer} is still
+live when quitting @var{window}, quitting the window may reuse
+@var{window} to display @var{prev-buffer}.
+
+The third element, @var{owindow}, is the window that was selected
+just before the displaying was done. If quitting deletes
+@var{window}, it tries to select @var{owindow}.
+
+The fourth element, @var{this-buffer}, is the buffer whose displaying
+set the @code{quit-restore} parameter. Quitting @var{window} may delete
+that window only if it still shows that buffer.
+
+Quitting @var{window} tries to delete it if and only if (1)
+@var{method} is either @code{window} or @code{frame}, (2) the window
+has no history of previously-displayed buffers and (3)
+@var{this-buffer} equals the buffer currently displayed in
+@var{window}. If @var{window} is part of an atomic window
+(@pxref{Atomic Windows}), quitting will try to delete the root of that
+atomic window instead. In either case, it tries to avoid signaling an
+error when @var{window} cannot be deleted.
+
+If @var{obuffer} is a list, and @var{prev-buffer} is still live,
+quitting displays @var{prev-buffer} in @var{window} according to the
+rest of the elements of @var{obuffer}. This includes resizing the
+window to @var{height} if it was temporarily resized to display
+@var{this-buffer}.
+
+Otherwise, if @var{window} was previously used for displaying other
+buffers (@pxref{Window History}), the most recent buffer in that
+history will be displayed.
+
+@ignore
+@c FIXME: Should we document display-buffer-reuse-window?
+If we document display-buffer-record-window, it should be with @defun.
+And maybe not here.
+
+
Typically, the display routines run by @code{display-buffer} will set
-the @code{quit-restore} window parameter correctly. It's also
-possible to set it manually, using the following code for displaying
-@var{buffer} in @var{window}:
+the @code{quit-restore} window parameter correctly. You can also set
+it manually, using the following code for displaying @var{buffer} in
+@var{window}:
@example
@group
@@ -4243,11 +4393,10 @@ possible to set it manually, using the following code for displaying
Setting the window history to @code{nil} ensures that a future call to
@code{quit-window} can delete the window altogether.
+@end ignore
-@end defun
-
-The following option specifies how to deal with a frame containing just
-one window that should be either quit, or whose buffer should be buried.
+The following option specifies a function to do the right thing with a
+frame containing one window when quitting that window.
@defopt frame-auto-hide-function
The function specified by this option is called to automatically hide
@@ -4276,7 +4425,6 @@ that frame's @code{auto-hide-function} frame parameter (@pxref{Frame
Interaction Parameters}).
@end defopt
-
@node Side Windows
@section Side Windows
@cindex side windows
@@ -5085,7 +5233,7 @@ window.
If @var{count} is negative, it scrolls backward instead. If
@var{count} is @code{nil} (or omitted), the distance scrolled is
@code{next-screen-context-lines} lines less than the height of the
-window's text area.
+window's body.
If the selected window cannot be scrolled any further, this function
signals an error. Otherwise, it returns @code{nil}.
@@ -5578,16 +5726,15 @@ right of the rightmost column, and the Y coordinate one row down from
the bottommost row.
Note that these are the actual outer edges of the window, including any
-header line, mode line, scroll bar, fringes, window divider and display
-margins. On a text terminal, if the window has a neighbor on its right,
-its right edge includes the separator line between the window and its
-neighbor.
+of its decorations. On a text terminal, if the window has a neighbor on
+its right, its right edge includes the separator line between the window
+and its neighbor.
If the optional argument @var{body} is @code{nil}, this means to
return the edges corresponding to the total size of @var{window}.
@var{body} non-@code{nil} means to return the edges of @var{window}'s
-body (aka text area). If @var{body} is non-@code{nil}, @var{window}
-must specify a live window.
+body. If @var{body} is non-@code{nil}, @var{window} must specify a
+live window.
If the optional argument @var{absolute} is @code{nil}, this means to
return edges relative to the native position of @var{window}'s frame.
@@ -5897,12 +6044,11 @@ all other child frames of that frame's parent frame.
@cindex saving window information
A @dfn{window configuration} records the entire layout of one
-frame---all windows, their sizes, which buffers they contain, how those
-buffers are scrolled, and their value of point; also their
-fringes, margins, and scroll bar settings. It also includes the value
-of @code{minibuffer-scroll-window}. As a special exception, the window
-configuration does not record the value of point in the selected window
-for the current buffer.
+frame---all windows, their sizes, their decorations, which buffers they
+contain, how those buffers are scrolled, and their value of point, It
+also includes the value of @code{minibuffer-scroll-window}. As a
+special exception, the window configuration does not record the value of
+point in the selected window for the current buffer.
You can bring back an entire frame layout by restoring a previously
saved window configuration. If you want to record the layout of all
@@ -6303,7 +6449,9 @@ changed. @xref{Other Font Lock Variables}.
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}.
+change functions}. As any hook, these hooks can be set either
+globally of buffer-locally via the @var{local} argument of
+@code{add-hook} (@pxref{Setting Hooks}) when the hook is installed.
@cindex window buffer change
The first of these hooks is run after a @dfn{window buffer change} is
diff --git a/doc/man/emacs.1.in b/doc/man/emacs.1.in
index 290be604e3b..b2be8bb07b1 100644
--- a/doc/man/emacs.1.in
+++ b/doc/man/emacs.1.in
@@ -1,5 +1,5 @@
.\" See section COPYING for copyright and redistribution information.
-.TH EMACS 1 "2020-04-05" "GNU Emacs @version@" "GNU"
+.TH EMACS 1 "2021-09-28" "GNU Emacs @version@" "GNU"
.
.
.SH NAME
@@ -215,6 +215,9 @@ Specify the name which should be assigned to the initial
window.
This controls looking up X resources as well as the window title.
.TP
+.BR \-\-no\-x\-resources
+Do not load X resources.
+.TP
.BI \-T " name\fR,\fP " \-\-title= "name"
Specify the title for the initial X window.
.TP
diff --git a/doc/man/emacsclient.1 b/doc/man/emacsclient.1
index ba64efa282c..e5d1bbe09ae 100644
--- a/doc/man/emacsclient.1
+++ b/doc/man/emacsclient.1
@@ -1,5 +1,5 @@
.\" See section COPYING for conditions for redistribution.
-.TH EMACSCLIENT 1 "2020-10-18" "GNU Emacs" "GNU"
+.TH EMACSCLIENT 1 "2021-11-05" "GNU Emacs" "GNU"
.\" NAME should be all caps, SECTION should be 1-8, maybe w/ subsection
.\" other params are allowed: see man(7), man(1)
.SH NAME
@@ -69,6 +69,9 @@ start Emacs in daemon mode, and try to connect to it.
.B -c, \-\-create-frame
Create a new frame instead of trying to use the current Emacs frame.
.TP
+.B -r \-\-reuse-frame
+Reuse an existing frame if one exists, otherwise create a new frame.
+.TP
.B \-F, \-\-frame-parameters=ALIST
Set the parameters of a newly-created frame.
.TP
diff --git a/doc/misc/ChangeLog.1 b/doc/misc/ChangeLog.1
index c050e5d4cb8..be2a7cad1bc 100644
--- a/doc/misc/ChangeLog.1
+++ b/doc/misc/ChangeLog.1
@@ -5965,7 +5965,7 @@
names when publishing to the source directory.
(Clean view): Document `org-indent-mode'.
(Clocking work time): Add documentation for the
- new :timetamp option when creating a clock report.
+ new :timestamp option when creating a clock report.
(Paragraphs): Fix many typos.
(Plain lists): Remove duplicate explanation about the
`C-c *' command.
diff --git a/doc/misc/calc.texi b/doc/misc/calc.texi
index e11267e7a20..c77ccf766f2 100644
--- a/doc/misc/calc.texi
+++ b/doc/misc/calc.texi
@@ -2865,7 +2865,7 @@ that always equals one. Let's try to verify this identity.
@smallexample
@group
2: -64 2: -64 2: -64 2: 9.7192e54 2: 9.7192e54
-1: -64 1: -3.1175e27 1: 9.7192e54 1: -64 1: 9.7192e54
+1: -64 1: 3.1175e27 1: 9.7192e54 1: -64 1: 9.7192e54
. . . . .
64 n @key{RET} @key{RET} H C 2 ^ @key{TAB} H S 2 ^
diff --git a/doc/misc/cc-mode.texi b/doc/misc/cc-mode.texi
index 98ded68e713..a2ff572a3f4 100644
--- a/doc/misc/cc-mode.texi
+++ b/doc/misc/cc-mode.texi
@@ -283,6 +283,8 @@ Font Locking
* Font Locking Preliminaries::
* Faces::
* Doc Comments::
+* Wrong Comment Style::
+* Found Types::
* Misc Font Locking::
* AWK Mode Font Locking::
@@ -1855,6 +1857,7 @@ sections apply to the other languages.
* Faces::
* Doc Comments::
* Wrong Comment Style::
+* Found Types::
* Misc Font Locking::
* AWK Mode Font Locking::
@end menu
@@ -2162,6 +2165,60 @@ which aren't of the default style will be fontified with
@end defvar
@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+@node Found Types
+@comment node-name, next, previous, up
+@section ``Found Type'' handling.
+@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+In most languages handled by CC Mode, @dfn{found types} are recognized
+as types by their context in the source code. These contrast with
+types which are basic to a language or are declared as types (e.g. by
+@code{typedef} in C).
+
+In earlier versions of @ccmode{}, when @code{jit-lock-mode} was
+enabled in Emacs (which it is by default), found types would
+frequently fail to get fontified properly. This happened when the
+fontification functions scanned a use of the found type before
+scanning the code which caused it to be recognized.
+
+From @ccmode{} version 5.36, a timer mechanism scans the entire buffer
+for found types in the seconds immediately after starting the major
+mode. When a found type gets recognized, all its occurrences in the
+buffer get marked for (re)fontification. This scanning happens in
+short time slices interleaved with other processing, such as keyboard
+handling, so that the responsiveness of Emacs should be barely
+affected. This mechanism can be disabled (see below). It is only
+active when @code{jit-lock-mode} is also active.
+
+@defvar c-type-finder-time-slot
+@vindex type-finder-time-slot (c-)
+The approximate time in seconds that CC Mode spends in scanning source
+code before relinquishing control to other Emacs activities. The
+default value is 0.05. To disable the scanning mechanism, set this
+variable to @code{nil}.
+@end defvar
+
+@defvar c-type-finder-repeat-time
+@vindex type-finder-repeat-time (c-)
+The approximate frequency (in seconds) with which the scanning
+mechanism is triggered. This time must be greater than
+@code{c-type-finder-time-slot}. Its default value is 0.1. If a less
+powerful machine becomes sluggish due to the scanning, increase the
+value of @code{c-type-finder-repeat-time} to compensate.
+@end defvar
+
+@defvar c-type-finder-chunk-size
+@vindex type-finder-chunk-size (c-)
+The approximate size (in characters) of the buffer chunk processed as
+a unit before the scanning mechanism checks whether
+@code{c-type-finder-time-slot} seconds have passed. The default value
+is 1000. A too small value here will cause inefficiencies due to the
+initialization which happens for each chunk, whereas a too large value
+will cause the processing to consume an excessive proportion of the
+@code{c-type-finder-repeat-time}.
+@end defvar
+
+@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@node Misc Font Locking
@comment node-name, next, previous, up
@section Miscellaneous Font Locking
diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi
index c89e0e75f85..55b112cb24a 100644
--- a/doc/misc/cl.texi
+++ b/doc/misc/cl.texi
@@ -1245,6 +1245,12 @@ blocks for other macros like @code{cl-incf}, and @code{cl-pushnew}.
The @code{cl-letf} and @code{cl-letf*} macros are used in the processing
of symbol macros; @pxref{Macro Bindings}.
+@defmac with-memoization @var{place} @var{code}@dots{}
+This macro provides a simple way to do memoization. @var{code} is
+evaluated and then stashed in @var{place}. If @var{place}'s value is
+non-@code{nil}, return that value instead of evaluating @var{code}.
+@end defmac
+
@node Variable Bindings
@section Variable Bindings
@@ -3364,9 +3370,13 @@ true for all elements.
@end defun
@defun cl-reduce function seq @t{&key :from-end :start :end :initial-value :key}
-This function combines the elements of @var{seq} using an associative
-binary operation. Suppose @var{function} is @code{*} and @var{seq} is
-the list @code{(2 3 4 5)}. The first two elements of the list are
+This function returns the result of calling @var{function} on the
+first and second element of @var{seq}, then calling @var{function}
+with that result and the third element of @var{seq}, then with that
+result and the third element of @var{seq}, etc.
+
+Here is an example. Suppose @var{function} is @code{*} and @var{seq}
+is the list @code{(2 3 4 5)}. The first two elements of the list are
combined with @code{(* 2 3) = 6}; this is combined with the next
element, @code{(* 6 4) = 24}, and that is combined with the final
element: @code{(* 24 5) = 120}. Note that the @code{*} function happens
@@ -3962,22 +3972,22 @@ In the simplest case, @var{name} and each of the @var{slots}
are symbols. For example,
@example
-(cl-defstruct person name age sex)
+(cl-defstruct person first-name age sex)
@end example
@noindent
-defines a struct type called @code{person} that contains three
-slots. Given a @code{person} object @var{p}, you can access those
-slots by calling @code{(person-name @var{p})}, @code{(person-age @var{p})},
-and @code{(person-sex @var{p})}. You can also change these slots by
-using @code{setf} on any of these place forms, for example:
+defines a struct type called @code{person} that contains three slots.
+Given a @code{person} object @var{p}, you can access those slots by
+calling @code{(person-first-name @var{p})}, @code{(person-age
+@var{p})}, and @code{(person-sex @var{p})}. You can also change these
+slots by using @code{setf} on any of these place forms, for example:
@example
(cl-incf (person-age birthday-boy))
@end example
You can create a new @code{person} by calling @code{make-person},
-which takes keyword arguments @code{:name}, @code{:age}, and
+which takes keyword arguments @code{:first-name}, @code{:age}, and
@code{:sex} to specify the initial values of these slots in the
new object. (Omitting any of these arguments leaves the corresponding
slot ``undefined'', according to the Common Lisp standard; in Emacs
@@ -3989,7 +3999,7 @@ object of the same type whose slots are @code{eq} to those of @var{p}.
Given any Lisp object @var{x}, @code{(person-p @var{x})} returns
true if @var{x} is a @code{person}, and false otherwise.
-Accessors like @code{person-name} normally check their arguments
+Accessors like @code{person-first-name} normally check their arguments
(effectively using @code{person-p}) and signal an error if the
argument is the wrong type. This check is affected by
@code{(optimize (safety @dots{}))} declarations. Safety level 1,
@@ -4002,13 +4012,13 @@ always print a descriptive error message for incorrect inputs.
@xref{Declarations}.
@example
-(setq dave (make-person :name "Dave" :sex 'male))
+(setq dave (make-person :first-name "Dave" :sex 'male))
@result{} [cl-struct-person "Dave" nil male]
(setq other (copy-person dave))
@result{} [cl-struct-person "Dave" nil male]
(eq dave other)
@result{} nil
-(eq (person-name dave) (person-name other))
+(eq (person-first-name dave) (person-first-name other))
@result{} t
(person-p dave)
@result{} t
@@ -4021,7 +4031,7 @@ always print a descriptive error message for incorrect inputs.
@end example
In general, @var{name} is either a name symbol or a list of a name
-symbol followed by any number of @dfn{struct options}; each @var{slot}
+symbol followed by any number of @dfn{structure options}; each @var{slot}
is either a slot symbol or a list of the form @samp{(@var{slot-name}
@var{default-value} @var{slot-options}@dots{})}. The @var{default-value}
is a Lisp form that is evaluated any time an instance of the
@@ -4029,7 +4039,7 @@ structure type is created without specifying that slot's value.
@example
(cl-defstruct person
- (name nil :read-only t)
+ (first-name nil :read-only t)
age
(sex 'unknown))
@end example
@@ -4062,7 +4072,7 @@ enclosed in lists.)
(cl-defstruct (person (:constructor create-person)
(:type list)
:named)
- name age sex)
+ first-name age sex)
@end example
The following structure options are recognized.
@@ -4108,12 +4118,12 @@ option.
(person
(:constructor nil) ; no default constructor
(:constructor new-person
- (name sex &optional (age 0)))
- (:constructor new-hound (&key (name "Rover")
+ (first-name sex &optional (age 0)))
+ (:constructor new-hound (&key (first-name "Rover")
(dog-years 0)
&aux (age (* 7 dog-years))
(sex 'canine))))
- name age sex)
+ first-name age sex)
@end example
The first constructor here takes its arguments positionally rather
@@ -4165,16 +4175,16 @@ slot descriptors for slots in the included structure, possibly with
modified default values. Borrowing an example from Steele:
@example
-(cl-defstruct person name (age 0) sex)
+(cl-defstruct person first-name (age 0) sex)
@result{} person
(cl-defstruct (astronaut (:include person (age 45)))
helmet-size
(favorite-beverage 'tang))
@result{} astronaut
-(setq joe (make-person :name "Joe"))
+(setq joe (make-person :first-name "Joe"))
@result{} [cl-struct-person "Joe" 0 nil]
-(setq buzz (make-astronaut :name "Buzz"))
+(setq buzz (make-astronaut :first-name "Buzz"))
@result{} [cl-struct-astronaut "Buzz" 45 nil nil tang]
(list (person-p joe) (person-p buzz))
@@ -4182,17 +4192,17 @@ modified default values. Borrowing an example from Steele:
(list (astronaut-p joe) (astronaut-p buzz))
@result{} (nil t)
-(person-name buzz)
+(person-first-name buzz)
@result{} "Buzz"
-(astronaut-name joe)
- @result{} error: "astronaut-name accessing a non-astronaut"
+(astronaut-first-name joe)
+ @result{} error: "astronaut-first-name accessing a non-astronaut"
@end example
Thus, if @code{astronaut} is a specialization of @code{person},
then every @code{astronaut} is also a @code{person} (but not the
other way around). Every @code{astronaut} includes all the slots
of a @code{person}, plus extra slots that are specific to
-astronauts. Operations that work on people (like @code{person-name})
+astronauts. Operations that work on people (like @code{person-first-name})
work on astronauts just like other people.
@item :noinline
@@ -4230,10 +4240,10 @@ records, which are always tagged. Therefore, @code{:named} is only
useful in conjunction with @code{:type}.
@example
-(cl-defstruct (person1) name age sex)
-(cl-defstruct (person2 (:type list) :named) name age sex)
-(cl-defstruct (person3 (:type list)) name age sex)
-(cl-defstruct (person4 (:type vector)) name age sex)
+(cl-defstruct (person1) first-name age sex)
+(cl-defstruct (person2 (:type list) :named) first-name age sex)
+(cl-defstruct (person3 (:type list)) first-name age sex)
+(cl-defstruct (person4 (:type vector)) first-name age sex)
(setq p1 (make-person1))
@result{} #s(person1 nil nil nil)
@@ -4254,10 +4264,10 @@ useful in conjunction with @code{:type}.
Since unnamed structures don't have tags, @code{cl-defstruct} is not
able to make a useful predicate for recognizing them. Also,
-accessors like @code{person3-name} will be generated but they
-will not be able to do any type checking. The @code{person3-name}
+accessors like @code{person3-first-name} will be generated but they
+will not be able to do any type checking. The @code{person3-first-name}
function, for example, will simply be a synonym for @code{car} in
-this case. By contrast, @code{person2-name} is able to verify
+this case. By contrast, @code{person2-first-name} is able to verify
that its argument is indeed a @code{person2} object before
proceeding.
@@ -5024,7 +5034,7 @@ The above @code{incf} example could be written using
@ignore
(defmacro concatf (place &rest args)
(gv-letplace (getter setter) place
- (macroexp-let2 nil v (mapconcat 'identity args "")
+ (macroexp-let2 nil v (mapconcat 'identity args)
(funcall setter `(concat ,getter ,v)))))
@end ignore
@end defmac
diff --git a/doc/misc/ede.texi b/doc/misc/ede.texi
index a0f316f8480..5e9c3d7eef6 100644
--- a/doc/misc/ede.texi
+++ b/doc/misc/ede.texi
@@ -1556,7 +1556,7 @@ You can also use TRAMP for use with rcp & scp.
@item :web-site-file @*
-A file which contains the home page for this project.
+A file which contains the website for this project.
This file can be relative to slot @code{web-site-directory}.
This can be a local file, use ange-ftp, EFS, or TRAMP.
diff --git a/doc/misc/efaq-w32.texi b/doc/misc/efaq-w32.texi
index 6eff88b76e3..a5b5251d6ea 100644
--- a/doc/misc/efaq-w32.texi
+++ b/doc/misc/efaq-w32.texi
@@ -628,7 +628,7 @@ REGEDIT4
@node Swap Caps 98
@subsubsection Windows 95/98/ME
-Microsoft has a tool called keyremap that is part of their Kernel Toys add ons
+Microsoft has a tool called keyremap that is part of their Kernel Toys add-ons
for Windows 95. The tool has also been confirmed to work on Windows 98.
@node Make Emacs like a Windows app
@@ -2278,7 +2278,7 @@ In Emacs, you can browse the manual using Info by typing @kbd{C-h r},
and you can view the FAQ by typing @kbd{C-h C-f}. Other resources include:
@itemize
-@item @uref{https://www.gnu.org/software/emacs/, The Emacs homepage}
+@item @uref{https://www.gnu.org/software/emacs/, The Emacs website}
@item @uref{https://www.gnu.org/software/emacs/manual/, Other Emacs manuals}
@item @uref{https://www.emacswiki.org/, Emacs Wiki}
@end itemize
diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi
index d66c12f9fc3..28f0cb972d0 100644
--- a/doc/misc/efaq.texi
+++ b/doc/misc/efaq.texi
@@ -7,10 +7,6 @@
@include emacsver.texi
-@c This file is maintained by Romain Francoise <rfrancoise@gnu.org>.
-@c Feel free to install changes without prior permission (but I'd
-@c appreciate a notice if you do).
-
@copying
Copyright @copyright{} 2001--2021 Free Software Foundation, Inc.@*
Copyright @copyright{} 1994, 1995, 1996, 1997, 1998, 1999, 2000
@@ -86,7 +82,7 @@ Emacs, the Emacs manual is often the best starting point.
* FAQ notation::
* General questions::
* Getting help::
-* Status of Emacs::
+* History of Emacs::
* Common requests::
* Bugs and problems::
* Compiling and installing Emacs::
@@ -155,7 +151,7 @@ and @key{Meta}
@item
@key{DEL}: @key{Delete}, usually @strong{not} the same as
-@key{Backspace}; same as @kbd{C-?} (see @ref{Backspace invokes help}, if
+@key{Backspace}; same as @kbd{C-?} (@pxref{Backspace invokes help}, if
deleting invokes Emacs help)
@item
@@ -215,11 +211,6 @@ completion, @kbd{?} for a list of possibilities, and @kbd{M-p} and
@kbd{M-n} (or up-arrow and down-arrow) to see previous commands entered.
An Emacs @dfn{command} is an @dfn{interactive} Emacs function.
-@cindex @key{Do} key
-Your system administrator may have bound other key sequences to invoke
-@code{execute-extended-command}. A function key labeled @kbd{Do} is a
-good candidate for this, on keyboards that have such a key.
-
If you need to run non-interactive Emacs functions, see @ref{Evaluating
Emacs Lisp code}.
@@ -231,7 +222,7 @@ Emacs Lisp code}.
@cindex Info, finding topics in
When we refer you to some @var{topic} in the Emacs manual, you can
-read this manual node inside Emacs (assuming nothing is broken) by
+read this manual node inside Emacs by
typing @kbd{C-h i m emacs @key{RET} m @var{topic} @key{RET}}.
This invokes Info, the GNU hypertext documentation browser. If you don't
@@ -240,9 +231,8 @@ already know how to use Info, type @kbd{?} from within Info.
If we refer to @var{topic}:@var{subtopic}, type @kbd{C-h i m emacs
@key{RET} m @var{topic} @key{RET} m @var{subtopic} @key{RET}}.
-If these commands don't work as expected, your system administrator may
-not have installed the Info files, or may have installed them
-improperly. In this case you should complain.
+(If these commands don't work as expected, your system may be missing
+the Info files, or they may not be installed properly.)
If you are reading this FAQ in Info, you can simply press @key{RET} on a
reference to follow it.
@@ -304,6 +294,9 @@ Richard Matthew Stallman
@item GPL
GNU General Public License
+See @uref{https://gnu.org/licenses/, the GNU web site} for more
+information about the GPL.
+
@end table
The word ``free'' in the title of the Free Software Foundation refers to
@@ -322,7 +315,6 @@ This chapter contains general questions having to do with Emacs, the
Free Software Foundation, and related organizations.
@menu
-* Real meaning of copyleft::
* Guidelines for mailing list postings::
* Mailing list archives::
* Reporting bugs::
@@ -330,67 +322,31 @@ Free Software Foundation, and related organizations.
* Contacting the FSF::
@end menu
-@node Real meaning of copyleft
-@section What is the real legal meaning of the GNU copyleft?
-@cindex Copyleft, real meaning of
-@cindex GPL, real meaning of
-@cindex General Public License, real meaning of
-@cindex Discussion of the GPL
-
-The real legal meaning of the GNU General Public License (copyleft) will
-only be known if and when a judge rules on its validity and scope.
-There has never been a copyright infringement case involving the GPL to
-set any precedents. Although legal actions have been brought against
-companies for violating the terms of the GPL, so far all have been
-settled out of court (in favor of the plaintiffs). Please take any
-discussion regarding this issue to
-@uref{https://lists.gnu.org/mailman/listinfo/gnu-misc-discuss, the
-gnu-misc-discuss mailing list}, which was created to hold the
-extensive flame wars on the subject.
-
-RMS writes:
-
-@quotation
-The legal meaning of the GNU copyleft is less important than the spirit,
-which is that Emacs is a free software project and that work pertaining
-to Emacs should also be free software. ``Free'' means that all users
-have the freedom to study, share, change and improve Emacs. To make
-sure everyone has this freedom, pass along source code when you
-distribute any version of Emacs or a related program, and give the
-recipients the same freedom that you enjoyed.
-@end quotation
-
@node Guidelines for mailing list postings
@section What are appropriate messages for the various Emacs mailing lists?
-@cindex Newsgroups, appropriate messages for
-@cindex GNU newsgroups, appropriate messages for
-@cindex GNU mailing lists, appropriate messages for
-@cindex Usenet groups, appropriate messages for
@cindex Mailing lists, appropriate messages for
@cindex Posting messages to mailing lists
-
@cindex GNU mailing lists
-The Emacs mailing lists are described at
+
+There are various Emacs mailing lists, described at
@uref{https://savannah.gnu.org/mail/?group=emacs, the Emacs Savannah
page}.
-Messages advocating ``non-free'' software are considered unacceptable
-on any of the GNU mailing lists, except for
-@url{https://lists.gnu.org/mailman/listinfo/gnu-misc-discuss, the
-gnu-misc-discuss mailing list} which was created to hold the extensive
-flame-wars on the subject.
-
-``Non-free'' software includes any software for which the end user
-can't freely modify the source code and exchange enhancements. Be
-careful to remove any GNU mailing lists from @samp{Cc:} when posting a
-reply that recommends such software.
-
-@url{https://lists.gnu.org/mailman/listinfo/bug-gnu-emacs, The
-bug-gnu-emacs list} is a place where bug reports appear, but we
-recommend using the commands @kbd{M-x report-emacs-bug} or @kbd{M-x
-submit-emacs-patch} if at all possible (@pxref{Reporting bugs}).
-
-Some GNU mailing lists are gatewayed to (Usenet) newsgroups.
+The main ones are: @code{help-gnu-emacs}, @code{bug-gnu-emacs},
+and @code{emacs-devel}.
+
+Messages advocating ``non-free'' software are considered unacceptable on
+any of the GNU mailing lists, except for
+@url{https://lists.gnu.org/mailman/listinfo/gnu-misc-discuss,
+the gnu-misc-discuss mailing list}.
+``Non-free'' software includes any software for which the end user can't
+freely modify the source code and exchange enhancements. Please
+remove GNU mailing lists from the recipients when
+posting a reply that recommends such software.
+
+@cindex newsgroups
+Some of the GNU mailing lists are gatewayed to newsgroups (although
+the connection is occasionally unreliable).
For example, sending an email to
@url{https://lists.gnu.org/mailman/listinfo/bug-gnu-emacs, The
bug-gnu-emacs list} has the effect of posting on the newsgroup
@@ -412,6 +368,8 @@ years, although there may be some unintentional gaps in coverage. The
archive can be browsed over the web at
@uref{https://lists.gnu.org/r/, the GNU mail archive}.
+@cindex Usenet archives for GNU groups
+@cindex Old Usenet postings for GNU groups
Some web-based Usenet search services also archive the @code{gnu.*}
newsgroups.
@@ -422,15 +380,8 @@ newsgroups.
@cindex How to submit a bug report
@cindex Reporting bugs
-The correct way to report Emacs bugs is to use the command
-@kbd{M-x report-emacs-bug}. It sets up a mail buffer with the
-essential information and the correct e-mail address,
-@email{bug-gnu-emacs@@gnu.org}.
-
-Be sure to read the ``Bugs'' section of the Emacs manual before reporting
-a bug! The manual describes in detail how to submit a useful bug
-report (@pxref{Bugs, , Reporting Bugs, emacs, The GNU Emacs Manual}).
-(@xref{Emacs manual}, if you don't know how to read the manual.)
+Please see the Emacs manual for information on how to report bugs.
+@xref{Checklist, , Checklist for Bug Reports, emacs, The GNU Emacs Manual}.
Sending bug reports to
@url{https://lists.gnu.org/mailman/listinfo/help-gnu-emacs, the
@@ -444,7 +395,7 @@ more messages about Emacs than the others.
If you have reported a bug and you don't hear about a possible fix,
then after a suitable delay (such as a week) it is okay to post on
-@code{help-gnu-emacs@@gnu.org} asking if anyone can help you.
+the help list asking if anyone can help you.
If you are unsure whether you have found a bug, consider the following
non-exhaustive list, courtesy of RMS:
@@ -842,7 +793,7 @@ informational files about Emacs and relevant aspects of the GNU project
are available for you to read.
The following files (and others) are available in the @file{etc}
-directory of the Emacs distribution (see @ref{File-name conventions}, if
+directory of the Emacs distribution (@pxref{File-name conventions}, if
you're not sure where that is). Many of these files are available via
the Emacs @samp{Help} menu, or by typing @kbd{C-h ?} (@kbd{M-x
help-for-help}).
@@ -863,12 +814,9 @@ Emacs news, a history of recent user-visible changes
@end table
-More GNU information, including back issues of the @cite{GNU's
-Bulletin}, are at
-
-@uref{https://www.gnu.org/bulletins/bulletins.html} and
+More GNU and FSF information is available at
-@uref{https://www.cs.pdx.edu/~trent/gnu/gnu.html}
+@uref{https://www.gnu.org} and @uref{https://www.fsf.org}
@node Help installing Emacs
@section Where can I get help in installing Emacs?
@@ -894,16 +842,14 @@ C-f} (@kbd{M-x view-emacs-FAQ}). The very latest version is available
in the Emacs development repository (@pxref{Latest version of Emacs}).
@c ------------------------------------------------------------
-@node Status of Emacs
-@chapter Status of Emacs
-@cindex Status of Emacs
-
-This chapter gives you basic information about Emacs, including the
-status of its latest version.
+@node History of Emacs
+@chapter History of Emacs
+@cindex History of Emacs
@menu
* Origin of the term Emacs::
* Latest version of Emacs::
+* New in Emacs 28::
* New in Emacs 27::
* New in Emacs 26::
* New in Emacs 25::
@@ -912,6 +858,7 @@ status of its latest version.
* New in Emacs 22::
* New in Emacs 21::
* New in Emacs 20::
+* What was XEmacs?::
@end menu
@node Origin of the term Emacs
@@ -950,12 +897,11 @@ conventions}).
@cindex Latest version of Emacs
@cindex Development, Emacs
@cindex Repository, Emacs
-@cindex Bazaar repository, Emacs
Emacs @value{EMACSVER} is the current version as of this writing. A version
-number with two components (e.g., @samp{24.5}) indicates a released
+number with two components (e.g., @samp{28.1}) indicates a released
version; three components indicate a development
-version (e.g., @samp{28.0.50} is what will eventually become @samp{28.1}).
+version (e.g., @samp{29.0.50} is what will eventually become @samp{29.1}).
Emacs is under active development, hosted at
@uref{https://savannah.gnu.org/projects/emacs/, Savannah}.
@@ -974,6 +920,97 @@ Emacs, type @kbd{C-h C-n} (@kbd{M-x view-emacs-news}). You can give
this command a prefix argument to read about which features were new
in older versions.
+@node New in Emacs 28
+@section What is different about Emacs 28?
+@cindex Differences between Emacs 27 and Emacs 28
+@cindex Emacs 28, new features in
+
+Emacs 28 has too many new features and changes to list all of them
+here. We list below a small selection; consult the Emacs @file{NEWS}
+file (@kbd{C-h n}) for the full list of changes in Emacs 28.
+
+@itemize
+@cindex native compilation of Lisp files
+@item
+Emacs now optionally supports native compilation of Lisp files. This
+can improves performance significantly in some cases. To enable this,
+configure Emacs with the @option{--with-native-compilation} option.
+
+@item
+The new NonGNU ELPA archive is enabled by default alongside GNU ELPA.
+Thus, packages on NonGNU ELPA will appear by default in the list shown
+by the @code{list-packages} command.
+
+@item
+The Cairo graphics library is now used by default if present.
+
+@item
+On GNU/Linux, Emacs now supports loading Secure Computing filters. To
+use this feature, invoke Emacs with the @option{--seccomp=@var{file}}
+command-line switch, where @var{file} names a binary file that defines
+the filtering. See the manual page of the @code{seccomp} system call
+for more details.
+
+@item
+The new themes @samp{modus-vivendi} and @samp{modus-operandi} have
+been added. They are designed to conform with the highest standard
+for color-contrast accessibility (WCAG AAA).
+
+@item
+On capable systems, Emacs now correctly displays Emoji and Emoji
+sequences by default, provided that a suitable font is available.
+
+@item
+New system for displaying documentation for groups of functions
+(@kbd{M-x shortdoc-display-group RET}).
+
+@item
+Emacs can now support 24-bit color text-mode terminals even if their
+terminfo database doesn't state this support in a standard way. Set
+the @env{COLORTERM} environment variable to the value @samp{truecolor}
+to activate this.
+
+@item
+The @code{strike-through} face attribute is now supported on capable
+text-mode terminals.
+
+@item
+@code{xterm-mouse-mode} supports TTY menus.
+
+@item
+A new minor mode @code{context-menu-mode} causes @code{mouse-3}
+(a.k.a.@: ``right-clicks'') of the mouse to pop up context-dependent
+menus.
+
+@item
+Prefix commands to control the display of the results of the next
+command. @kbd{C-x 4 4 @var{command}} displays the result of
+@var{command} in a new window. @kbd{C-x 5 5 @var{command}} displays
+the results of @var{command} in a new frame.
+
+@item
+Emacs now supports ``transient'' input methods. A transient input
+method is enabled for inserting a single character, and is then
+automatically disabled. Select a transient input method with @kbd{C-u
+C-x \}; enable it (for inserting a single character) with @kbd{C-x \}.
+New input methods @code{compose} (based on X Window System Multi_key
+sequences) and @code{iso-transl} are especially convenient with this
+feature, when you need to insert a single special character.
+
+@item
+@kbd{M-y}, when invoked after a command that is not a yank command,
+allows selection of one of the previous kills.
+
+@item
+New minor mode @code{repeat-mode} allows to repeat commands with fewer
+keystrokes.
+
+@item
+Among the many internal changes in this release, we would like to
+highlight that all files in the tree now use @code{lexical-binding}.
+@end itemize
+
+
@node New in Emacs 27
@section What is different about Emacs 27?
@cindex Differences between Emacs 26 and Emacs 27
@@ -1028,8 +1065,8 @@ Built-in support for tabs (tab bar and tab line).
Support for resizing and rotating of images without ImageMagick.
@end itemize
-Consult the Emacs @file{NEWS} file (@kbd{C-h n}) for the full list of
-changes in Emacs 27.
+Consult the Emacs @file{NEWS.27} file for the full list of changes in
+Emacs 27.
@node New in Emacs 26
@section What is different about Emacs 26?
@@ -1107,8 +1144,8 @@ Emacs 26.2 comes with data files imported from the latest Unicode
Standard version 11.0.0.
@end itemize
-Consult the Emacs @file{NEWS} file (@kbd{C-h n}) for the full list of
-changes in Emacs 26.
+Consult the Emacs @file{NEWS.26} file for the full list of changes in
+Emacs 26.
@node New in Emacs 25
@section What is different about Emacs 25?
@@ -1141,7 +1178,7 @@ Emacs Lisp form at point.
@cindex pasting text on text terminals
@cindex bracketed paste mode
@item
-On text terminals that support the ``bracketed paste mode'' EMacs now
+On text terminals that support the ``bracketed paste mode'' Emacs now
uses that mode by default. This mode allows Emacs to distinguish
between pasted text and text typed by the user.
@@ -1207,8 +1244,8 @@ provide toolkit scroll bars, namely Gtk+, Lucid, Motif and Windows.
@end itemize
-Consult the Emacs @file{NEWS} file (@kbd{C-h n}) for the full list of
-changes in Emacs 25.
+Consult the Emacs @file{NEWS.25} file for the full list of changes in
+Emacs 25.
@node New in Emacs 24
@section What is different about Emacs 24?
@@ -1281,7 +1318,8 @@ Much more flexibility in the handling of windows and buffer display.
@end itemize
-As always, consult the @file{NEWS} file for more information.
+Consult the Emacs @file{NEWS.24} file for the full list of changes in
+Emacs 24.
@node New in Emacs 23
@@ -1340,6 +1378,9 @@ new Visual Line mode for line-motion; improved completion; a new mode
mode (for editing XML documents) is included; VC has been updated for
newer version control systems; etc.
+Consult the Emacs @file{NEWS.23} file for the full list of changes in
+Emacs 23.
+
@node New in Emacs 22
@section What is different about Emacs 22?
@@ -1436,6 +1477,9 @@ In addition, Emacs 22 now includes the Emacs Lisp Reference Manual
(@pxref{Emacs Lisp documentation}) and the Emacs Lisp Intro.
@end itemize
+Consult the Emacs @file{NEWS.22} file for the full list of changes in
+Emacs 22.
+
@node New in Emacs 21
@section What is different about Emacs 21?
@@ -1458,6 +1502,9 @@ In addition, Emacs 21 supports faces on text-only terminals. This means
that you can now have colors when you run Emacs on a GNU/Linux console
and on @code{xterm} with @kbd{emacs -nw}.
+Consult the Emacs @file{NEWS.21} file for the full list of changes in
+Emacs 21.
+
@node New in Emacs 20
@section What is different about Emacs 20?
@@ -1475,6 +1522,33 @@ several languages in the same document; the ``Customize'' facility for
modifying variables without having to use Lisp; and automatic conversion
of files from Macintosh, Microsoft, and Unix platforms.
+Consult the Emacs @file{NEWS.20} file for the full list of changes in
+Emacs 20.
+
+
+@node What was XEmacs?
+@section What was XEmacs?
+@cindex XEmacs
+
+XEmacs was a branch version of Emacs that is no longer actively
+developed. Originally known as ``Lucid Emacs'', XEmacs was forked
+from a prerelease version of Emacs 19. XEmacs last released a new
+version on January 30, 2009, which lacks many important features that
+exist in Emacs. Since its development has stopped, we do not expect
+to see any new releases.
+
+In the past, it was not uncommon for Emacs packages to include code
+for compatibility with XEmacs. Nowadays, most built-in and third party
+packages have either stopped supporting XEmacs or were developed
+exclusively for Emacs.
+
+If you want to talk about these two versions and distinguish them,
+please call them ``Emacs'' and ``XEmacs.'' To contrast ``XEmacs''
+with ``GNU Emacs'' would be misleading, since XEmacs too has its
+origin in the work of the GNU Project. Terms such as ``Emacsen'' and
+``(X)Emacs'' are not wrong, but they are not very clear, so it
+is better to write ``Emacs and XEmacs.''
+
@c ------------------------------------------------------------
@node Common requests
@chapter Common requests
@@ -1598,7 +1672,7 @@ capabilities.
The command @kbd{M-x list-colors-display} pops up a window which
exhibits all the colors Emacs knows about on the current display.
-Syntax highlighting is on by default since version 22.1.
+Syntax highlighting is also on by default on text-only terminals.
@cindex direct color in terminals
Emacs 26.1 and later support direct color mode in terminals. If Emacs
@@ -2574,12 +2648,12 @@ load @code{dired-x} by adding the following to your @file{.emacs} file:
(require 'dired-x))
@end lisp
-With @code{dired-x} loaded, @kbd{M-o} toggles omitting in each dired buffer.
+With @code{dired-x} loaded, @kbd{C-x M-o} toggles omitting in each dired buffer.
You can make omitting the default for new dired buffers by putting the
following in your @file{.emacs}:
@lisp
-(add-hook 'dired-mode-hook 'dired-omit-toggle)
+(add-hook 'dired-mode-hook 'dired-omit-mode)
@end lisp
If you're tired of seeing backup files whenever you do an @samp{ls} at
@@ -3380,6 +3454,7 @@ dired, @code{directory-listing-before-filename-regexp}.
@menu
* Installing Emacs::
+* Emacs for other operating systems::
* Problems building Emacs::
@end menu
@@ -3392,9 +3467,7 @@ dired, @code{directory-listing-before-filename-regexp}.
@cindex Source code, building Emacs from
This answer is meant for users of Unix and Unix-like systems. Users of
-other operating systems should see the series of questions beginning
-with @ref{Emacs for MS-DOS}, which describe where to get non-Unix source
-and binaries, and how to install Emacs on those systems.
+other operating systems should see @xref{Emacs for other operating systems}.
Most GNU/Linux distributions provide pre-built Emacs packages.
If Emacs is not installed already, you can install it by running (as
@@ -3413,20 +3486,20 @@ a list of sites that make them available. On @url{https://ftp.gnu.org},
the main GNU distribution site, sources are available as
@c Don't include VER in the file name, because pretests are not there.
-@uref{https://ftp.gnu.org/pub/gnu/emacs/emacs-VERSION.tar.gz}
+@uref{https://ftp.gnu.org/pub/gnu/emacs/emacs-VERSION.tar.xz}
(Replace @samp{VERSION} with the relevant version number, e.g., @samp{28.1}.)
@item
Next uncompress and extract the source files. This requires
-the @code{gzip} and @code{tar} programs, which are standard utilities.
+the @code{xz} and @code{tar} programs, which are standard utilities.
If your system does not have them, these can also be downloaded from
@url{https://ftp.gnu.org}.
GNU @code{tar} can uncompress and extract in a single-step:
@example
-tar -zxvf emacs-VERSION.tar.gz
+tar -axvf emacs-VERSION.tar.xz
@end example
@item
@@ -3440,9 +3513,8 @@ cd emacs-VERSION
make # use Makefile to build components, then Emacs
@end example
-If the @code{make} completes successfully, the odds are fairly good that
-the build has gone well. (@xref{Problems building Emacs}, if you weren't
-successful.)
+If the @code{make} completes successfully, you can go on to install it.
+(@xref{Problems building Emacs}, if you weren't successful.)
@item
By default, Emacs is installed in @file{/usr/local}. To actually
@@ -3457,6 +3529,46 @@ and any Emacs Info files that might be in @file{/usr/local/share/info/}.
@end itemize
+@node Emacs for other operating systems
+@section Where can I get Emacs for macOS, MS Windows, etc?
+
+@cindex Apple computers, Emacs for
+@cindex Macintosh, Emacs for
+@cindex macOS, Emacs for
+Beginning with version 22.1, Emacs supports macOS natively.
+See the file @file{nextstep/INSTALL} in the distribution.
+
+@cindex FAQ for Emacs on MS-Windows
+@cindex Emacs for MS-Windows
+@cindex Microsoft Windows, Emacs for
+There is a separate FAQ for Emacs on MS-Windows,
+@pxref{Top,,,efaq-w32,FAQ for Emacs on MS Windows}.
+
+@cindex GNUstep, Emacs for
+Beginning with version 23.1, Emacs supports GNUstep natively.
+See the file @file{nextstep/INSTALL} in the distribution.
+
+@cindex MS-DOS, Emacs for
+@cindex DOS, Emacs for
+@cindex Compiling Emacs for DOS
+@cindex Emacs for MS-DOS
+To build Emacs from source for MS-DOS, see the instructions in the file
+@file{msdos/INSTALL} in the distribution. The DOS port builds and runs
+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}
+
+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}
+
+Note that while many of these programs look similar to Emacs, they often
+lack certain features, such as the Emacs Lisp extension language.
+
+
@node Problems building Emacs
@section What should I do if I have trouble building Emacs?
@cindex Problems building Emacs
@@ -3480,26 +3592,20 @@ problem (@pxref{Reporting bugs}).
@cindex Finding Emacs and related packages
@menu
-* Finding Emacs on the Internet::
+* Downloading Emacs::
* Finding a package with particular functionality::
* Packages that do not come with Emacs::
* Spell-checkers::
* Current GNU distributions::
-* What was XEmacs?::
* Emacs for minimalists::
-* Emacs for MS-DOS::
-* Emacs for MS-Windows::
-* Emacs for GNUstep::
-* Emacs for macOS::
@end menu
-@node Finding Emacs on the Internet
-@section Where can I get Emacs on the net?
-@cindex Finding Emacs on the Internet
+@node Downloading Emacs
+@section Downloading Emacs
@cindex Downloading Emacs
Information on downloading Emacs is available at
-@uref{https://www.gnu.org/software/emacs/, the Emacs home-page}.
+@uref{https://www.gnu.org/software/emacs/, the Emacs website}.
@xref{Installing Emacs}, for information on how to obtain and build the latest
version of Emacs, and see @ref{Current GNU distributions}, for a list of
@@ -3511,25 +3617,22 @@ archive sites that make GNU software available.
@cindex Finding an Emacs Lisp package
@cindex Functionality, finding a particular package
-First of all, you should check to make sure that the package isn't
-already available. For example, typing @kbd{M-x apropos @key{RET}
-python @key{RET}} lists all functions and variables containing the
-string @samp{python}.
-
-It is also possible that the package is on your system, but has not been
-loaded. To see which packages are available for loading, look through
-your computer's lisp directory (@pxref{File-name conventions}). The Lisp
-source to most packages contains a short description of how they
-should be loaded, invoked, and configured---so before you use or
-modify a Lisp package, see if the author has provided any hints in the
-source code.
-
The command @kbd{C-h p} (@code{finder-by-keyword}) allows you to browse
-the constituent Emacs packages.
+the packages that come with Emacs.
For advice on how to find extra packages that are not part of Emacs,
see @ref{Packages that do not come with Emacs}.
+Other techniques that might be useful:
+
+Typing @kbd{M-x apropos @key{RET} python @key{RET}} lists all
+functions and variables containing the string @samp{python}.
+
+You can look through your computer's lisp directory (@pxref{File-name
+conventions}). The Lisp source to most packages contains a short
+description of what they do and how they should be used.
+
+
@c Note that M-x view-external-packages references this node.
@node Packages that do not come with Emacs
@section Where can I get Emacs Lisp packages that don't come with Emacs?
@@ -3619,28 +3722,6 @@ A list of sites mirroring @samp{ftp.gnu.org} can be found at
@uref{https://www.gnu.org/prep/ftp}
-@node What was XEmacs?
-@section What was XEmacs?
-@cindex XEmacs
-
-XEmacs was a branch version of Emacs that is no longer actively
-developed. XEmacs last released a new version on January 30, 2009,
-and it lacks many important features that exist in Emacs. Since its
-development has stopped, we do not expect to see any new releases.
-
-In the past, it was not uncommon for Emacs packages to include code
-for compatibility with XEmacs. Nowadays, most built-in and third party
-packages have either stopped supporting XEmacs or were developed
-exclusively for Emacs.
-
-XEmacs was initially derived from a prerelease version of Emacs 19.
-If you want to talk about these two versions and distinguish them,
-please call them ``Emacs'' and ``XEmacs.'' To contrast ``XEmacs''
-with ``GNU Emacs'' would be misleading, since XEmacs too has its
-origin in the work of the GNU Project. Terms such as ``Emacsen'' and
-``(X)Emacs'' are not wrong, but they are not very clear, so it
-is better to write ``Emacs and XEmacs.''
-
@node Emacs for minimalists
@section I don't have enough disk space to install Emacs
@cindex Zile
@@ -3654,63 +3735,6 @@ information is available from
@uref{https://www.gnu.org/software/zile/}
-
-@node Emacs for MS-DOS
-@section Where can I get Emacs for MS-DOS?
-@cindex MS-DOS, Emacs for
-@cindex DOS, Emacs for
-@cindex Compiling Emacs for DOS
-@cindex Emacs for MS-DOS
-
-To build Emacs from source for MS-DOS, see the instructions in the file
-@file{msdos/INSTALL} in the distribution. The DOS port builds and runs
-on plain DOS, and also on all versions of MS-Windows from version 3.X
-onwards, including Windows XP and Vista.
-
-The file @file{etc/PROBLEMS} contains some additional information
-regarding Emacs under MS-DOS.
-
-A pre-built binary distribution of the old Emacs 24 is available, as
-described at
-
-@uref{http://www.delorie.com/pub/djgpp/current/v2gnu/emacs.README}
-
-For a list of other MS-DOS implementations of Emacs (and Emacs
-look-alikes), consult the list of ``Emacs implementations and literature,''
-available at
-
-@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.
-
-@node Emacs for MS-Windows
-@section Where can I get Emacs for Microsoft Windows?
-@cindex FAQ for Emacs on MS-Windows
-@cindex Emacs for MS-Windows
-@cindex Microsoft Windows, Emacs for
-
-There is a separate FAQ for Emacs on MS-Windows,
-@pxref{Top,,,efaq-w32,FAQ for Emacs on MS Windows}.
-For MS-DOS, @pxref{Emacs for MS-DOS}.
-
-
-@node Emacs for GNUstep
-@section Where can I get Emacs for GNUstep?
-@cindex GNUstep, Emacs for
-
-Emacs supports GNUstep natively. See the file @file{nextstep/INSTALL}
-in the distribution.
-
-@node Emacs for macOS
-@section Where can I get Emacs for macOS?
-@cindex Apple computers, Emacs for
-@cindex Macintosh, Emacs for
-@cindex macOS, Emacs for
-
-Emacs supports macOS natively. See the file @file{nextstep/INSTALL}
-in the distribution.
-
@c ------------------------------------------------------------
@node Key bindings
@chapter Key bindings
@@ -4218,9 +4242,6 @@ You can get the old behavior by binding @kbd{SPC} to
@lisp
(define-key minibuffer-local-filename-completion-map (kbd "SPC")
'minibuffer-complete-word)
-
-(define-key minibuffer-local-filename-must-match-map (kbd "SPC")
- 'minibuffer-complete-word)
@end lisp
@c ------------------------------------------------------------
diff --git a/doc/misc/eieio.texi b/doc/misc/eieio.texi
index 63b42827311..c8d488d6edb 100644
--- a/doc/misc/eieio.texi
+++ b/doc/misc/eieio.texi
@@ -700,18 +700,18 @@ slot values, and use the previously mentioned set/ref routines.
@defun slot-value object slot
@anchor{slot-value}
This function retrieves the value of @var{slot} from @var{object}.
+It can also be used on objects defined by @code{cl-defstruct}.
This is a generalized variable that can be used with @code{setf} to
-modify the value stored in @var{slot}. @xref{Generalized
-Variables,,,elisp,GNU Emacs Lisp Reference Manual}.
+modify the value stored in @var{slot}.
+@xref{Generalized Variables,,,elisp,GNU Emacs Lisp Reference Manual}.
@end defun
@defun set-slot-value object slot value
@anchor{set-slot-value}
This function sets the value of @var{slot} from @var{object}.
-This is not a CLOS function, but is the obsolete setter for
-@code{slot-value} used by the @code{setf} macro. It is therefore
+This is not a CLOS function. It is therefore
recommended to use @w{@code{(setf (slot-value @var{object} @var{slot})
@var{value})}} instead.
@end defun
@@ -856,11 +856,12 @@ 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.
-@end defmac
-In CLOS, a generic call 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.
+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
@section Methods
diff --git a/doc/misc/emacs-mime.texi b/doc/misc/emacs-mime.texi
index 7cd3e5f5828..96a4ad556f6 100644
--- a/doc/misc/emacs-mime.texi
+++ b/doc/misc/emacs-mime.texi
@@ -454,7 +454,8 @@ setting this option to non-@code{nil}. The default value is @code{t}.
@item mm-external-terminal-program
@vindex mm-external-terminal-program
-The program used to start an external terminal.
+This should be a list of strings; typically something like
+@samp{("xterm" "-e")} or @samp{("gnome-terminal" "--")}.
@item mm-enable-external
@vindex mm-enable-external
diff --git a/doc/misc/erc.texi b/doc/misc/erc.texi
index 10ced678e1d..e7286d2ebe3 100644
--- a/doc/misc/erc.texi
+++ b/doc/misc/erc.texi
@@ -2,13 +2,15 @@
@c %**start of header
@setfilename ../../info/erc.info
@settitle ERC Manual
+@set ERCVER 5.4.1
+@set ERCDIST as distributed with Emacs @value{EMACSVER}
@include docstyle.texi
@syncodeindex fn cp
@include emacsver.texi
@c %**end of header
@copying
-This manual is for ERC as distributed with Emacs @value{EMACSVER}.
+This manual is for ERC @value{ERCVER} @value{ERCDIST}.
Copyright @copyright{} 2005--2021 Free Software Foundation, Inc.
@@ -70,7 +72,7 @@ and modified without restriction.
Getting Started
-* Sample Session:: Example of connecting to the #emacs channel
+* Sample Session:: Example of connecting to the @samp{#emacs} channel
* Special Features:: Differences from standalone IRC clients
Advanced Usage
@@ -88,7 +90,28 @@ Advanced Usage
ERC is a powerful, modular, and extensible IRC client for Emacs.
It is distributed with Emacs since version 22.1.
-It comes with the following capabilities enabled by default.
+IRC is short for Internet Relay Chat. When using IRC, you can
+communicate with other users on the same IRC network. There are many
+different networks---if you search for ``IRC networks'' in your
+favorite search engine, you will find up-to-date lists of IRC networks
+catering to various interests and topics.
+
+To use IRC, you need an IRC client such as ERC. Using the client, you
+connect to an IRC server. Once you've done that, you will have access
+to all available channels on that server's network. A channel is
+basically a chat room, and what you type in a channel will be shown to
+all other users in that channel. You can be in several channels at
+the same time---ERC will show each channel in its own buffer.
+
+IRC channel names always begin with a @samp{#} character. For
+example, the Emacs channel on Libera.Chat is @samp{#emacs}, and the
+ERC channel is @samp{#erc}. Do not confuse them with the hashtags
+used on many social media platforms.
+
+You can also send private messages to other IRC users on the same
+network, even if they are not in the same channels as you.
+
+ERC comes with the following capabilities enabled by default.
@itemize @bullet
@item Flood control
@@ -112,7 +135,11 @@ It comes with the following capabilities enabled by default.
@cindex settings
The command @kbd{M-x erc} will start ERC and prompt for the server to
-connect to.
+connect to. If you're unsure of which server or network to connect
+to, we suggest starting with ``irc.libera.chat''. There you will find
+the @samp{#emacs} channels where you can chat with other Emacs users,
+and if you're having trouble with ERC, you can join the @samp{#erc}
+channel and ask for help there.
If you want to place ERC settings in their own file, you can place them
in @file{~/.emacs.d/.ercrc.el}, creating it if necessary.
@@ -132,14 +159,15 @@ customize-variable @key{RET} erc-modules @key{RET}}.
@section Sample Session
This is an example ERC session which shows how to connect to the
-#emacs channel on Libera.Chat. Another IRC channel on Libera.Chat
-that may be of interest is #erc, which is a channel where ERC users
-and developers hang out. These channels used to live on the Freenode
-IRC network until June 2021, when they---along with the official IRC
-channels of the GNU Project, the Free Software Foundation, and many
-other free software communities---relocated to the Libera.Chat network
-in the aftermath of changes in governance and policies of Freenode in
-May and June 2021. GNU and FSF's announcements about this are at
+@samp{#emacs} channel on Libera.Chat. Another IRC channel on
+Libera.Chat that may be of interest is @samp{#erc}, which is a channel
+where ERC users and developers hang out. These channels used to live
+on the Freenode IRC network until June 2021, when they---along with
+the official IRC channels of the GNU Project, the Free Software
+Foundation, and many other free software communities---relocated to
+the Libera.Chat network in the aftermath of changes in governance and
+policies of Freenode in May and June 2021. GNU and FSF's
+announcements about this are at
@uref{https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00005.html},
@uref{https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00007.html},
and
@@ -149,7 +177,7 @@ and
@item Connect to Libera.Chat
-Run @kbd{M-x erc}. Use ``irc.libera.chat as the IRC server, ``6667''
+Run @kbd{M-x erc}. Use ``irc.libera.chat'' as the IRC server, ``6667''
as the port, and choose a nickname.
@item Get used to the interface
@@ -264,7 +292,7 @@ new command in capital letters.
If the connection goes away at some point, ERC will try to reconnect
automatically. If it fails to reconnect, and you want to try to
manually reestablish the connection at some later point, switch to an
-ERC buffer and run the @code{/RECONNECT} command.
+ERC buffer and run the @code{/RECONNECT} command.
@end itemize
@@ -283,7 +311,7 @@ Go to beginning of line or end of prompt.
@item @key{RET} (@code{erc-send-current-line})
Send the current line
-@item @key{TAB} (@code{erc-complete-word})
+@item @key{TAB} (@code{completion-at-point} or @code{erc-button-next})
If at prompt, complete the current word.
Otherwise, move to the next link or button.
@@ -931,7 +959,7 @@ over the project entirely.''
So we happily hacked away on ERC, and soon after (September 2001)
released the next "stable" version, 2.1.
-Most of the development of the new ERC happened on #emacs on
+Most of the development of the new ERC happened on @samp{#emacs} on
irc.openprojects.net. Over time, many people contributed code, ideas,
bugfixes, and a lot of alpha/beta/gamma testing.
diff --git a/doc/misc/ert.texi b/doc/misc/ert.texi
index fafdb8c4eb4..71c423ad9c6 100644
--- a/doc/misc/ert.texi
+++ b/doc/misc/ert.texi
@@ -109,6 +109,7 @@ Appendix
@end menu
@end ifnottex
+
@node Introduction
@chapter Introduction
@cindex introduction to ERT
@@ -123,7 +124,7 @@ commands to run them to verify whether the definitions that are
currently loaded in Emacs pass the tests.
Some Lisp files have comments like the following (adapted from the
-package @code{pp.el}):
+package @file{pp.el}):
@lisp
;; (pp-to-string '(quote quote)) ; expected: "'quote"
@@ -260,35 +261,103 @@ unexpected result. In the example above, there are two failures, both
due to failed @code{should} forms. @xref{Understanding Explanations},
for more details.
+The following key bindings are available in the ERT results buffer:
+
+@table @kbd
+
+@item @key{RET}
+@kindex RET@r{, in ert results buffer}
+Each name of a function or macro in this buffer is a button; moving
+point to it and typing @kbd{@key{RET}} jumps to its definition.
+
+@item @key{TAB}
+@itemx S-@key{TAB}
@kindex TAB@r{, in ert results buffer}
@kindex S-TAB@r{, in ert results buffer}
-In the ERT results buffer, @kbd{@key{TAB}} and @kbd{S-@key{TAB}} cycle between
-buttons. Each name of a function or macro in this buffer is a button;
-moving point to it and typing @kbd{@key{RET}} jumps to its definition.
+Cycle between buttons forward (@code{forward-button}) and backward
+(@code{backward-button}).
+@item r
@kindex r@r{, in ert results buffer}
+@findex ert-results-rerun-test-at-point
+Re-run the test near point on its own
+(@code{ert-results-rerun-test-at-point}).
+
+@item d
@kindex d@r{, in ert results buffer}
+@findex ert-results-rerun-test-at-point-debugging-errors
+Re-run the test near point on its own with the debugger enabled
+(@code{ert-results-rerun-test-at-point-debugging-errors}).
+
+@item R
+@kindex R@r{, in ert results buffer}
+@findex ert-results-rerun-all-tests
+Re-run all tests (@code{ert-results-rerun-all-tests}).
+
+@item .
@kindex .@r{, in ert results buffer}
+@findex ert-results-find-test-at-point-other-window
+Jump to the definition of the test near point
+(@code{ert-results-find-test-at-point-other-window}). This has the
+same effect as @kbd{@key{RET}}, but does not require point to be on
+the name of the test.
+
+@item b
@kindex b@r{, in ert results buffer}
+@findex ert-results-pop-to-backtrace-for-test-at-point
@cindex backtrace of a failed test
-Pressing @kbd{r} re-runs the test near point on its own. Pressing
-@kbd{d} re-runs it with the debugger enabled. @kbd{.} jumps to the
-definition of the test near point (@kbd{@key{RET}} has the same effect
-if point is on the name of the test). On a failed test, @kbd{b} shows
-the backtrace of the failure. @xref{Debugging,, Backtraces, elisp,
-GNU Emacs Lisp Reference Manual}, for more information about
-backtraces.
+Show the backtrace of a failed test
+(@code{ert-results-pop-to-backtrace-for-test-at-point}).
+@xref{Debugging,, Backtraces, elisp, GNU Emacs Lisp Reference Manual},
+for more information about backtraces.
+@item l
@kindex l@r{, in ert results buffer}
-@kbd{l} shows the list of @code{should} forms executed in the test.
-If any messages were generated (with the Lisp function @code{message})
-in a test or any of the code that it invoked, @kbd{m} will show them.
-
+@findex ert-results-pop-to-should-forms-for-test-at-point
+Show the list of @code{should} forms executed in the test
+(@code{ert-results-pop-to-should-forms-for-test-at-point}).
+
+@item m
+@kindex m@r{, in ert results buffer}
+@findex ert-results-pop-to-messages-for-test-at-point
+Show any messages that were generated (with the Lisp function
+@code{message}) in in a test or any of the code that it invoked
+(@code{ert-results-pop-to-messages-for-test-at-point}).
+
+@item L
@kindex L@r{, in ert results buffer}
+@findex ert-results-toggle-printer-limits-for-test-at-point
By default, long expressions in the failure details are abbreviated
-using @code{print-length} and @code{print-level}. Pressing @kbd{L}
-while point is on a test failure will increase the limits to show more
-of the expression.
+using @code{print-length} and @code{print-level}. Increase the limits
+to show more of the expression by moving point to a test failure with
+this command (@code{ert-results-toggle-printer-limits-for-test-at-point}).
+
+@item D
+@kindex D@r{, in ert results buffer}
+@findex ert-delete-test
+@cindex delete test
+Delete a test from the running Emacs session (@code{ert-delete-test}).
+
+@item h
+@kindex h@r{, in ert results buffer}
+@findex ert-describe-test
+Show the documentation of a test (@code{ert-describe-test}).
+
+@item T
+@kindex T@r{, in ert results buffer}
+@findex ert-results-pop-to-timings
+Display test timings for the last run (@code{ert-results-pop-to-timings}).
+
+@item M-x ert-delete-all-tests
+@findex ert-delete-all-tests
+@cindex delete all tests
+Delete all tests from the running session.
+
+@item M-x ert-describe-test
+@findex ert-results-describe-test-at-point
+Prompt for a test and then show its documentation.
+
+@end table
@node Running Tests in Batch Mode
@@ -308,7 +377,7 @@ emacs -batch -l ert -l my-tests.el -f ert-run-tests-batch-and-exit
@end example
This command will start up Emacs in batch mode, load ERT, load
-@code{my-tests.el}, and run all tests defined in it. It will exit
+@file{my-tests.el}, and run all tests defined in it. It will exit
with a zero exit status if all tests passed, or nonzero if any tests
failed or if anything else went wrong. It will also print progress
messages and error diagnostics to standard output.
@@ -323,12 +392,37 @@ summary as shown below:
emacs -batch -l ert -f ert-summarize-tests-batch-and-exit output.log
@end example
+@vindex ert-batch-print-level
+@vindex ert-batch-print-length
+ERT attempts to limit the output size for failed tests by choosing
+conservative values for @code{print-level} and @code{print-length}
+when printing Lisp values. This can in some cases make it difficult
+to see which portions of those values are incorrect. Use
+@code{ert-batch-print-level} and @code{ert-batch-print-length}
+to customize that:
+
+@example
+emacs -batch -l ert -l my-tests.el \
+ --eval "(let ((ert-batch-print-level 10) \
+ (ert-batch-print-length 120)) \
+ (ert-run-tests-batch-and-exit))"
+@end example
+
+@vindex ert-batch-backtrace-line-length
+Even modest settings for @code{print-level} and @code{print-length} can
+produce extremely long lines in backtraces, however, with attendant
+pauses in execution progress. Set
+@code{ert-batch-backtrace-line-length} to t to use the value of
+@code{backtrace-line-length}, @code{nil} to stop any limitations on backtrace
+line lengths (that is, to get full backtraces), or a positive integer to
+limit backtrace line length to that number.
+
@vindex ert-quiet
By default, ERT in batch mode is quite verbose, printing a line with
result after each test. This gives you progress information: how many
tests have been executed and how many there are. However, in some
cases this much output may be undesirable. In this case, set
-@code{ert-quiet} variable to a non-nil value:
+@code{ert-quiet} variable to a non-@code{nil} value:
@example
emacs -batch -l ert -l my-tests.el \
@@ -347,10 +441,21 @@ emacs -batch -l ert -l my-tests.el \
-eval '(ert-run-tests-batch-and-exit "to-match")'
@end example
+@vindex EMACS_TEST_VERBOSE@r{, environment variable}
By default, ERT test failure summaries are quite brief in batch
-mode--only the names of the failed tests are listed. If the
-EMACS_TEST_VERBOSE environment variable is set, the failure summaries
-will also include the data from the failing test.
+mode---only the names of the failed tests are listed. If the
+@env{EMACS_TEST_VERBOSE} environment variable is set, the failure
+summaries will also include the data from the failing test.
+
+@vindex EMACS_TEST_JUNIT_REPORT@r{, environment variable}
+ERT can produce JUnit test reports in batch mode. If the environment
+variable @env{EMACS_TEST_JUNIT_REPORT} is set, ERT will produce for
+every test package @file{my-tests.el} a corresponding JUnit test
+report @file{my-tests.xml}. The function
+@code{ert-summarize-tests-batch-and-exit} collects all these package
+test reports into a new JUnit test report, with the respective name of
+that environment variable.
+
@node Test Selectors
@section Test Selectors
@@ -419,8 +524,10 @@ to find where a test was defined if the test was loaded from a file.
* Expected Failures:: Tests for known bugs.
* Tests and Their Environment:: Don't depend on customizations; no side effects.
* Useful Techniques:: Some examples.
+* erts files:: Files containing many buffer tests.
@end menu
+
@node The @code{should} Macro
@section The @code{should} Macro
@@ -701,6 +808,121 @@ for testing. Usually, this makes the interfaces easier to use as
well.
+@node erts files
+@section erts files
+
+@findex ert-test-erts-file
+Many relevant Emacs tests depend on comparing the contents of a buffer
+before and after executing a particular function. These tests can be
+written the normal way---making a temporary buffer, inserting the
+``before'' text, running the function, and then comparing with the
+expected ``after'' text. However, this often leads to test code
+that's pretty difficult to read and write, especially when the text in
+question is multi-line.
+
+So ert provides a function called @code{ert-test-erts-file} that takes
+two parameters: The name of a specially-formatted @dfn{erts} file, and
+(optionally) a function that performs the transform.
+
+@findex erts-mode
+These erts files can be edited with the @code{erts-mode} major mode.
+
+An erts file is divided into sections by the (@samp{=-=}) separator.
+
+Here's an example file containing two tests:
+
+@example
+Name: flet
+
+=-=
+(cl-flet ((bla (x)
+(* x x)))
+(bla 42))
+=-=
+(cl-flet ((bla (x)
+ (* x x)))
+ (bla 42))
+=-=-=
+
+Name: defun
+
+=-=
+(defun x ()
+ (print (quote ( thingy great
+ stuff))))
+=-=-=
+@end example
+
+A test starts with a line containing just @samp{=-=} and ends with a
+line containing just @samp{=-=-=}. The test may be preceded by
+freeform text (for instance, comments), and also name/value pairs (see
+below for a list of them).
+
+If there is a line with @samp{=-=} inside the test, that designates
+the start of the ``after'' text. Otherwise, the ``before'' and
+``after'' texts are assumed to be identical, which you typically see
+when writing indentation tests.
+
+@code{ert-test-erts-file} puts the ``before'' section into a temporary
+buffer, calls the transform function, and then compares with the
+``after'' section.
+
+Here's an example usage:
+
+@lisp
+(ert-test-erts-file "elisp.erts"
+ (lambda ()
+ (emacs-lisp-mode)
+ (indent-region (point-min) (point-max))))
+@end lisp
+
+A list of the name/value specifications that can appear before a test
+follows. The general syntax is @samp{Name: Value}, but continuation
+lines can be used (along the same lines as in mail---subsequent lines
+that start with a space are part of the value).
+
+@example
+Name: foo
+Code: (indent-region
+ (point-min) (point-max))
+@end example
+
+@table @samp
+@item Name
+All tests should have a name. This name will appear in ERT output if
+the test fails, and helps to identify the failing test.
+
+@item Code
+This is the code that will be run to do the transform. This can also
+be passed in via the @code{ert-test-erts-file} call, but @samp{Code}
+overrides that. It's used not only in the following test, but in all
+subsequent tests in the file (until overridden by another @samp{Code}
+specification).
+
+@item No-Before-Newline
+@itemx No-After-Newline
+These specifications say whether the ``before'' or ``after'' portions
+have a newline at the end. (This would otherwise be impossible to
+specify.)
+
+@item Point-Char
+Sometimes it's useful to be able to put point at a specific place
+before executing the transform function. @samp{Point-Char: |} will
+make @code{ert-test-erts-file} place point where @samp{|} is in the
+``before'' form (and remove that character), and will check that it's
+where the @samp{|} character is in the ``after'' form (and issue a
+test failure if that isn't the case). (This is used in all subsequent
+tests, unless overridden by a new @samp{Point-Char} spec.)
+
+@item Skip
+If this is present and value is a form that evaluates to a
+non-@code{nil} value, the test will be skipped.
+@end table
+
+If you need to use the literal line single line @samp{=-=} in a test
+section, you can quote it with a @samp{\} character.
+
+
@node How to Debug Tests
@chapter How to Debug Tests
@@ -902,6 +1124,7 @@ For information on mocks, stubs, fixtures, or test suites, see below.
* Fixtures and Test Suites:: How ERT differs from tools for other languages.
@end menu
+
@node Mocks and Stubs
@section Other Tools for Emacs Lisp
@cindex mocks and stubs
@@ -976,11 +1199,13 @@ e.g., to run quick tests during interactive development and slow tests less
often. This can be achieved with the @code{:tag} argument to
@code{ert-deftest} and @code{tag} test selectors.
+
@node Index
@unnumbered Index
@printindex cp
+
@node GNU Free Documentation License
@appendix GNU Free Documentation License
@include doclicense.texi
diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi
index fc2e3f3b111..a87dd4308c5 100644
--- a/doc/misc/eshell.texi
+++ b/doc/misc/eshell.texi
@@ -271,8 +271,30 @@ Some of the built-in commands have different behavior from their
external counterparts, and some have no external counterpart. Most of
these will print a usage message when given the @code{--help} option.
+In some cases, a built-in command's behavior can be configured via
+user settings, some of which are mentioned below. For example,
+certain commands have two user settings to allow them to overwrite
+files without warning and to ensure that they always prompt before
+overwriting files. If both settings are non-@code{nil}, the commands
+always prompt. If both settings are @code{nil} (the default), the
+commands signal an error.
+
+Several commands observe the value of
+@code{eshell-default-target-is-dot}. If non-@code{nil}, then the
+default target for the commands @command{cp}, @command{mv}, and
+@command{ln} is the current directory.
+
+A few commands are wrappers for more niche Emacs features, and can be
+loaded as part of the eshell-xtra module. @xref{Extension modules}.
+
@table @code
+@item .
+@cmindex .
+Source an Eshell file in the current environment. This is not to be
+confused with the command @command{source}, which sources a file in a
+subshell environment.
+
@item addpath
@cmindex addpath
Adds a given path or set of paths to the PATH environment variable, or,
@@ -282,26 +304,137 @@ with no arguments, prints the current paths in this variable.
@cmindex alias
Define an alias (@pxref{Aliases}). This adds it to the aliases file.
+@item basename
+@cmindex basename
+Return a file name without its directory.
+
+@item cat
+@cmindex cat
+Concatenate file contents into standard output. If in a pipeline, or
+if the file is not a regular file, directory, or symlink, then this
+command reverts to the system's definition of @command{cat}.
+
+@item cd
+@cmindex cd
+This command changes the current working directory. Usually, it is
+invoked as @kbd{cd @var{dir}} where @file{@var{dir}} is the new
+working directory. But @command{cd} knows about a few special
+arguments:
+
+@itemize @minus{}
+@item
+When it receives no argument at all, it changes to the home directory.
+
+@item
+Giving the command @kbd{cd -} changes back to the previous working
+directory (this is the same as @kbd{cd $-}).
+
+@item
+The command @kbd{cd =} shows the directory stack. Each line is
+numbered.
+
+@item
+With @kbd{cd =foo}, Eshell searches the directory stack for a directory
+matching the regular expression @samp{foo}, and changes to that
+directory.
+
+@item
+With @kbd{cd -42}, you can access the directory stack slots by number.
+
+@item
+If @code{eshell-cd-shows-directory} is non-@code{nil}, @command{cd}
+will report the directory it changes to. If
+@code{eshell-list-files-after-cd} is non-@code{nil}, then @command{ls}
+is called with any remaining arguments after changing directories.
+@end itemize
+
@item clear
@cmindex clear
-Scrolls the contents of the eshell window out of sight, leaving a blank window.
-If provided with an optional non-nil argument, the scrollback contents are
-cleared instead.
+Scrolls the contents of the Eshell window out of sight, leaving a
+blank window. If provided with an optional non-@code{nil} argument,
+the scrollback contents are cleared instead.
+
+@item clear-scrollback
+@cmindex clear-scrollback
+Clear the scrollback contents of the Eshell window. Unlike the
+command @command{clear}, this command deletes content in the Eshell
+buffer.
+
+@item cp
+@cmindex cp
+Copy a file to a new location or copy multiple files to the same
+directory.
+
+If @code{eshell-cp-overwrite-files} is non-@code{nil}, then
+@command{cp} will overwrite files without warning. If
+@code{eshell-cp-interactive-query} is non-@code{nil}, then
+@command{cp} will ask before overwriting anything.
@item date
@cmindex date
-Similar to, but slightly different from, the GNU Coreutils
+Print the current local time as a human-readable string. This command
+is similar to, but slightly different from, the GNU Coreutils
@command{date} command.
@item define
@cmindex define
-Define a varalias.
+Define a variable alias.
@xref{Variable Aliases, , , elisp, The Emacs Lisp Reference Manual}.
@item diff
@cmindex diff
-Use Emacs's internal @code{diff} (not to be confused with
-@code{ediff}). @xref{Comparing Files, , , emacs, The GNU Emacs Manual}.
+Compare files using Emacs's internal @code{diff} (not to be confused
+with @code{ediff}). @xref{Comparing Files, , , emacs, The GNU Emacs
+Manual}.
+
+If @code{eshell-plain-diff-behavior} is non-@code{nil}, then this
+command does not use Emacs's internal @code{diff}. This is the same
+as using @samp{alias diff '*diff $*'}.
+
+@item dirname
+@cmindex dirname
+Return the directory component of a file name.
+
+@item dirs
+@cmindex dirs
+Prints the directory stack. Directories can be added or removed from
+the stack using the commands @command{pushd} and @command{popd},
+respectively.
+
+@item du
+@cmindex du
+Summarize disk usage for each file.
+
+@item echo
+@cmindex echo
+Echoes its input. If @code{eshell-plain-echo-behavior} is
+non-@code{nil}, @command{echo} will try to behave more like a plain
+shell's @command{echo}.
+
+@item env
+@cmindex env
+Prints the current environment variables. Unlike in Bash, this
+command does not yet support running commands with a modified
+environment.
+
+@item exit
+@cmindex exit
+Exit Eshell and save the history. By default, this command kills the
+Eshell buffer, but if @code{eshell-kill-on-exit} is @code{nil}, then
+the buffer is merely buried instead.
+
+@item export
+@cmindex export
+Set environment variables using input like Bash's @command{export}, as
+in @samp{export @var{var1}=@var{val1} @var{var2}=@var{val2} @dots{}}.
+
+@item expr
+@cmindex expr
+An implementation of @command{expr} using the Calc package.
+@xref{Top,,, calc, The GNU Emacs Calculator}.
+
+This command can be loaded as part of the eshell-xtra module, which is
+disabled by default.
@item grep
@cmindex grep
@@ -313,13 +446,36 @@ Use Emacs's internal @code{diff} (not to be confused with
@cmindex fgrep
@itemx glimpse
@cmindex glimpse
-The @command{grep} commands are compatible with GNU @command{grep}, but
-use Emacs's internal @code{grep} instead.
+The @command{grep} commands are compatible with GNU @command{grep},
+but use Emacs's internal @code{grep} instead.
+@xref{Grep Searching, , , emacs, The GNU Emacs Manual}.
+
+If @code{eshell-plain-grep-behavior} is non-@code{nil}, then these
+commands do not use Emacs's internal @code{grep}. This is the same as
+using @samp{alias grep '*grep $*'}, though this setting applies to all
+of the built-in commands for which you would need to create a separate
+alias.
+
+@item history
+@cmindex history
+Prints Eshell's input history. With a numeric argument @var{N}, this
+command prints the @var{N} most recent items in the history.
@item info
@cmindex info
-Same as the external @command{info} command, but uses Emacs's internal
-Info reader.
+Browse the available Info documentation. This command is the same as
+the external @command{info} command, but uses Emacs's internal Info
+reader.
+@xref{Misc Help, , , emacs, The GNU Emacs Manual}.
+
+@item intersection
+@cmindex intersection
+A wrapper around the function @code{cl-intersection} (@pxref{Lists as
+Sets,,, cl, GNU Emacs Common Lisp Emulation}). This command
+can be used for comparing lists of strings.
+
+This command can be loaded as part of the eshell-xtra module, which is
+disabled by default.
@item jobs
@cmindex jobs
@@ -337,46 +493,152 @@ Eshell version of @code{list}. Allows you to create a list using Eshell
syntax, rather than Elisp syntax. For example, @samp{listify foo bar}
and @code{("foo" "bar")} both evaluate to @code{("foo" "bar")}.
+@item ln
+@cmindex ln
+Create links to files.
+
+If @code{eshell-ln-overwrite-files} is non-@code{nil}, @command{ln}
+will overwrite files without warning. If
+@code{eshell-ln-interactive-query} is non-@code{nil}, then
+@command{ln} will ask before overwriting files.
+
@item locate
@cmindex locate
Alias to Emacs's @code{locate} function, which simply runs the external
@command{locate} command and parses the results.
@xref{Dired and Find, , , emacs, The GNU Emacs Manual}.
+If @code{eshell-plain-locate-behavior} is non-@code{nil}, then Emacs's
+internal @code{locate} is not used. This is the same as using
+@samp{alias locate '*locate $*'}.
+
+@item ls
+@cmindex ls
+Lists the contents of directories.
+
+If @code{eshell-ls-use-colors} is non-@code{nil}, the contents of a
+directory is color-coded according to file type and status. These
+colors and the regexps used to identify their corresponding files can
+be customized via @w{@kbd{M-x customize-group @key{RET} eshell-ls @key{RET}}}.
+
+The user option @code{eshell-ls-date-format} determines how the date
+is displayed when using the @option{-l} option. The date is produced
+using the function @code{format-time-string} (@pxref{Time Parsing,,,
+elisp, GNU Emacs Lisp Reference Manual}).
+
+The user option @code{eshell-ls-initial-args} contains a list of
+arguments to include with any call to @command{ls}. For example, you
+can include the option @option{-h} to always use a more human-readable
+format.
+
+The user option @code{eshell-ls-default-blocksize} determines the
+default blocksize used when displaying file sizes with the option
+@option{-s}.
+
@item make
@cmindex make
Run @command{make} through @code{compile} when run asynchronously
(e.g., @samp{make &}). @xref{Compilation, , , emacs, The GNU Emacs
Manual}. Otherwise call the external @command{make} command.
+@item man
+@cmindex man
+Display Man pages using the Emacs @code{man} command.
+@xref{Man Page, , , emacs, The GNU Emacs Manual}.
+
+@item mismatch
+@cmindex mismatch
+A wrapper around the function @code{cl-mismatch} (@pxref{Searching
+Sequences,,, cl, GNU Emacs Common Lisp Emulation}). This command can
+be used for comparing lists of strings.
+
+This command can be loaded as part of the eshell-xtra module, which is
+disabled by default.
+
+@item mkdir
+@cmindex mkdir
+Make new directories.
+
+@item mv
+@cmindex mv
+Move or rename files.
+
+If @code{eshell-mv-overwrite-files} is non-@code{nil}, @command{mv}
+will overwrite files without warning. If
+@code{eshell-mv-interactive-query} is non-@code{nil}, @command{mv}
+will prompt before overwriting anything.
+
@item occur
@cmindex occur
Alias to Emacs's @code{occur}.
@xref{Other Repeating Search, , , emacs, The GNU Emacs Manual}.
+@item popd
+@cmindex popd
+Pop a directory from the directory stack and switch to a another place
+in the stack.
+
@item printnl
@cmindex printnl
Print the arguments separated by newlines.
-@item cd
-@cmindex cd
-This command changes the current working directory. Usually, it is
-invoked as @samp{cd foo} where @file{foo} is the new working directory.
-But @command{cd} knows about a few special arguments:
-
-When it receives no argument at all, it changes to the home directory.
-
-Giving the command @samp{cd -} changes back to the previous working
-directory (this is the same as @samp{cd $-}).
-
-The command @samp{cd =} shows the directory stack. Each line is
-numbered.
-
-With @samp{cd =foo}, Eshell searches the directory stack for a directory
-matching the regular expression @samp{foo} and changes to that
-directory.
-
-With @samp{cd -42}, you can access the directory stack by number.
+@item pushd
+@cmindex pushd
+Push the current directory onto the directory stack, then change to
+another directory.
+
+If @code{eshell-pushd-dunique} is non-@code{nil}, then only unique
+directories will be added to the stack. If
+@code{eshell-pushd-dextract} is non-@code{nil}, then @samp{pushd
++@var{n}} will pop the @var{n}th directory to the top of the stack.
+
+@item pwd
+@cmindex pwd
+Prints the current working directory.
+
+@item rm
+@cmindex rm
+Removes files, buffers, processes, or Emacs Lisp symbols, depending on
+the argument.
+
+If @code{eshell-rm-interactive-query} is non-@code{nil}, @command{rm}
+will prompt before removing anything. If
+@code{eshell-rm-removes-directories} is non-@code{nil}, then
+@command{rm} can also remove directories. Otherwise, @command{rmdir}
+is required.
+
+@item rmdir
+@cmindex rmdir
+Removes directories if they are empty.
+
+@item set-difference
+@cmindex set-difference
+A wrapper around the function @code{cl-set-difference} (@pxref{Lists as
+Sets,,, cl, GNU Emacs Common Lisp Emulation}). This command
+can be used for comparing lists of strings.
+
+This command can be loaded as part of the eshell-xtra module, which is
+disabled by default.
+
+@item set-exclusive-or
+@cmindex set-exclusive-or
+A wrapper around the function @code{cl-set-exclusive-or} (@pxref{Lists
+as Sets,,, cl, GNU Emacs Common Lisp Emulation}). This command can be
+used for comparing lists of strings.
+
+This command can be loaded as part of the eshell-xtra module, which is
+disabled by default.
+
+@item setq
+@cmindex setq
+Set variable values, using the function @code{setq} like a command.
+@xref{Setting Variables,,, elisp, GNU Emacs Lisp Reference Manual}.
+
+@item source
+@cmindex source
+Source an Eshell file in a subshell environment. This is not to be
+confused with the command @command{.}, which sources a file in the
+current environment.
@item su
@cmindex su
@@ -386,6 +648,50 @@ Uses TRAMP's @command{su} or @command{sudo} method @pxref{Inline methods, , , tr
to run a command via @command{su} or @command{sudo}. These commands
are in the eshell-tramp module, which is disabled by default.
+
+@item substitute
+@cmindex substitute
+A wrapper around the function @code{cl-substitute} (@pxref{Sequence
+Functions,,, cl, GNU Emacs Common Lisp Emulation}). This command can
+be used for comparing lists of strings.
+
+This command can be loaded as part of the eshell-xtra module, which is
+disabled by default.
+
+@item time
+@cmindex time
+Show the time elapsed during a command's execution.
+
+@item umask
+@cmindex umask
+Set or view the default file permissions for newly created files and
+directories.
+
+@item union
+@cmindex union
+A wrapper around the function @code{cl-union} (@pxref{Lists as Sets,,,
+cl, GNU Emacs Common Lisp Emulation}). This command can be used for
+comparing lists of strings.
+
+This command can be loaded as part of the eshell-xtra module, which is
+disabled by default.
+
+@item unset
+@cmindex unset
+Unset an environment variable.
+
+@item wait
+@cmindex wait
+Wait until a process has successfully completed.
+
+@item which
+@cmindex which
+Identify a command and its location.
+
+@item whoami
+@cmindex whoami
+Print the current user. This Eshell version of @command{whoami}
+supports Tramp.
@end table
@subsection Built-in variables
@@ -744,21 +1050,33 @@ Eshell module.} You also need to load the following as shown:
@node Writing a module
@section Writing a module
+This section is not yet written.
+
@node Module testing
@section Module testing
+This section is not yet written.
+
@node Directory handling
@section Directory handling
+This section is not yet written.
+
@node Key rebinding
@section Key rebinding
+This section is not yet written.
+
@node Smart scrolling
@section Smart scrolling
+This section is not yet written.
+
@node Terminal emulation
@section Terminal emulation
+This section is not yet written.
+
@node Bugs and ideas
@chapter Bugs and ideas
@cindex reporting bugs and ideas
diff --git a/doc/misc/eww.texi b/doc/misc/eww.texi
index cc546a92d63..ebfdaf546e3 100644
--- a/doc/misc/eww.texi
+++ b/doc/misc/eww.texi
@@ -228,11 +228,12 @@ in an external browser by customizing
@findex eww-retrieve-command
EWW normally uses @code{url-retrieve} to fetch the @acronym{HTML}
-before rendering it. It can sometimes be convenient to use an
-external program to do this, and @code{eww-retrieve-command} should
-then be a list that specifies a command and the parameters. For
-instance, to use the Chromium browser, you could say something like
-this:
+before rendering it, and @code{url-retrieve-synchronously} when
+the value of @code{eww-retrieve-command} is @code{sync}. It can
+sometimes be convenient to use an external program to do this, and
+@code{eww-retrieve-command} should then be a list that specifies
+a command and the parameters. For instance, to use the Chromium
+browser, you could say something like this:
@lisp
(setq eww-retrieve-command
@@ -379,6 +380,32 @@ thus allowing for the use of the usual substitutions, such as
@code{\[eww-reload]} for the current key binding of the
@code{eww-reload} command.
+@vindex eww-auto-rename-buffer
+ If the @code{eww-auto-rename-buffer} user option is non-@code{nil},
+EWW buffers will be renamed after rendering a document. If this is
+@code{title}, rename based on the title of the document. If this is
+@code{url}, rename based on the @acronym{URL} of the document. This
+can also be a user-defined function, which is called with no
+parameters in the EWW buffer, and should return a string.
+
+@cindex utm
+@vindex eww-url-transformers
+ EWW runs the URLs through @code{eww-url-transformers} before using
+them. This user option is a list of functions, where each function is
+called with the URL as the parameter, and should return the (possibly)
+transformed URL. By default, this variable contains
+@code{eww-remove-tracking}, which removes the common @samp{utm_}
+trackers from links.
+
+@cindex video
+@vindex shr-use-xwidgets-for-media
+ If Emacs has been built with xwidget support, EWW can use that to
+display @samp{<video>} elements. However, this support is still
+experimental, and on some systems doesn't work (and even worse) may
+crash your Emacs, so this feature is off by default. If you wish to
+switch it on, set @code{shr-use-xwidgets-for-media} to a
+non-@code{nil} value.
+
@node Command Line
@chapter Command Line Usage
diff --git a/doc/misc/flymake.texi b/doc/misc/flymake.texi
index 9c838a8341a..ca464aff665 100644
--- a/doc/misc/flymake.texi
+++ b/doc/misc/flymake.texi
@@ -1,8 +1,8 @@
-\input texinfo @c -*-texinfo; coding: utf-8 -*-
+\input texinfo @c -*- mode: texinfo; coding: utf-8 -*-
@comment %**start of header
@setfilename ../../info/flymake.info
-@set VERSION 1.0
-@set UPDATED June 2018
+@set VERSION 1.2
+@set UPDATED September 2021
@settitle GNU Flymake @value{VERSION}
@include docstyle.texi
@syncodeindex pg cp
@@ -11,8 +11,7 @@
@comment %**end of header
@copying
-This manual is for GNU Flymake (version @value{VERSION}, @value{UPDATED}),
-which is a universal on-the-fly syntax checker for GNU Emacs.
+This manual is for GNU Flymake (version @value{VERSION}, @value{UPDATED}).
Copyright @copyright{} 2004--2021 Free Software Foundation, Inc.
@@ -41,6 +40,7 @@ modify this GNU manual.''
@page
@vskip 0pt plus 1filll
@insertcopying
+
@end titlepage
@contents
@@ -48,6 +48,25 @@ modify this GNU manual.''
@ifnottex
@node Top
@top GNU Flymake
+@end ifnottex
+
+Flymake is a universal on-the-fly syntax checker for Emacs. When
+enabled, Flymake contacts one or more source @dfn{backends} to
+collect information about problems in the buffer, called
+@dfn{diagnostics}, and visually annotates them with a special face.
+The mode line displays overall status including totals for different
+types of diagnostics.
+
+To learn about using Flymake, @pxref{Using Flymake}.
+
+Flymake is designed to be easily extended to support new backends via
+an Elisp interface. @xref{Extending Flymake}.
+
+Historically, Flymake used to accept diagnostics from a single
+backend. Although obsolete, it is still functional. To learn how to
+use and customize it, @pxref{The legacy Proc backend}.
+
+@ifnottex
@insertcopying
@end ifnottex
@@ -64,19 +83,34 @@ modify this GNU manual.''
@cindex overview of flymake
@cindex using flymake
-Flymake is a universal on-the-fly buffer checker implemented as an
-Emacs minor mode. To use Flymake, you must first activate
-@code{flymake-mode} by using the command @kbd{flymake-mode}.
+Flymake is only useful if at least one @dfn{backend} is configured to
+provide the buffer-checking service. This is done via the hook
+@code{flymake-diagnostic-functions}. @xref{Hooks,Hooks,, emacs, The
+Emacs Editor}.
+
+It's possible that some major modes or a third-party package has
+already setup this hook for you, by adding @dfn{backend functions} to
+@code{flymake-diagnostic-functions}. If you know Elisp you may also
+write your own Flymake backend functions. @xref{Backend functions}.
-When enabled, Flymake collects information about problems in the
-buffer, called @dfn{diagnostics}, from one or more different sources,
-or @dfn{backends}, and then visually annotates the buffer by
-highlighting problematic buffer regions with a special face.
+@menu
+* Starting Flymake::
+* Finding diagnostics::
+* Mode line status::
+* Troubleshooting::
+* Customizable variables::
+@end menu
-It also displays an overall buffer status in the mode line containing
-totals for different types of diagnostics.
+@node Starting Flymake
+@section Starting Flymake
+@cindex starting Flymake
-Syntax check is done ``on-the-fly''. It is started whenever
+To use Flymake, activate the minor-mode @code{flymake-mode}.
+Use the command @kbd{flymake-mode} to toggle it on and off. The
+mode line should indicate its presence via an indicator (@pxref{Mode
+line status}).
+
+Syntax checks happen ``on-the-fly''. Each check is started whenever:
@itemize @bullet
@item
@@ -90,50 +124,56 @@ nil;
@item
some changes were made to the buffer more than @code{0.5} seconds ago
(the delay is configurable in @code{flymake-no-changes-timeout}).
-@end itemize
-Syntax check can also be started manually by typing the @kbd{M-x
-flymake-start @key{RET}} command.
+@item
+When the user invokes the command @code{flymake-start}.
+@end itemize
If the check detected errors or warnings, the respective buffer
-regions are highlighted. You can place point on those regions and use
-@kbd{C-h .} (@code{display-local-help}) to see what the specific
-problem was. Alternatively, hovering the mouse on those regions
-should also display a tool-tip with the same information.
+regions are highlighted. @xref{Finding diagnostics}, for how to
+learn what the problems are.
+
+@node Finding diagnostics
+@section Finding diagnostics
+@cindex read diagnostic message
+If Flymake has highlighted the buffer, you may hover the mouse on the
+highlighted regions to learn what the specific problem
+is. Alternatively, place point on the highlighted regions and use the
+commands @code{eldoc} or @code{display-local-help}.
+
+@cindex next and previous diagnostic
+If the diagnostics are outside the visible region of the buffer,
@code{flymake-goto-next-error} and @code{flymake-goto-prev-error} are
-commands that allow easy navigation to the next/previous erroneous
-regions, respectively. It might be a good idea to map them to @kbd{M-n}
-and @kbd{M-p} in @code{flymake-mode}, by adding to your init file:
+let you navigate to the next/previous erroneous regions,
+respectively. It might be a good idea to map them to @kbd{M-n} and
+@kbd{M-p} in @code{flymake-mode}, by adding to your init file:
@lisp
(define-key flymake-mode-map (kbd "M-n") 'flymake-goto-next-error)
(define-key flymake-mode-map (kbd "M-p") 'flymake-goto-prev-error)
@end lisp
-Flymake is a universal syntax checker in the sense that it's easily
-extended to support new backends (@pxref{Extending Flymake}).
-
-Historically, Flymake used to accept diagnostics from a single
-backend, albeit a reasonably flexible one.
-
-This backend isn't (yet) obsolete, and so is still available as a
-fallback and active by default (@pxref{The legacy Proc backend}). It works by
-selecting a syntax check tool from a preconfigured list (compiler for
-C@t{++} files, @command{perl} for Perl files, etc.), and executing it in the
-background, passing it a temporary file which is a copy of the current
-buffer, and parsing the output for known error/warning message
-patterns.
-
-@menu
-* Syntax check statuses::
-* Backend exceptions::
-* Customizable variables::
-@end menu
-
-@node Syntax check statuses
-@section Syntax check statuses
-@cindex Syntax check statuses
+@cindex listing diagnostics
+Sometimes it is useful to have a detailed overview of the diagnostics
+in your files without having to jump to each one. The commands
+@code{flymake-show-buffer-diagnostics} and
+@code{flymake-show-project-diagnostics} are designed to handle this
+situation. When invoked, they bring up a separate buffer containing a
+detailed structured listing of multiple diagnostics in the current
+buffer or for the current project, respectively (@pxref{Projects,,,
+emacs, The Emacs Editor}).
+
+The listings is continuously updated as you edit source code, adding or
+removing lines as you make or correct mistakes. Each line of this
+listing includes the type of the diagnostic, its line and column in
+the file, as well as the diagnostic message. You may sort the listing
+by each of these columns.
+
+@node Mode line status
+@section Mode line status
+@cindex flymake mode line
+@cindex syntax check status
When enabled, Flymake displays its status in the mode line, which
provides a visual summary of diagnostic collection. It may also hint
@@ -157,7 +197,7 @@ delay and Flymake will resume normal operation soon.
@item @code{!}
@tab All the configured Flymake backends have disabled themselves: Flymake
cannot annotate the buffer and action from the user is needed to
-investigate and remedy the situation (@pxref{Backend exceptions}).
+investigate and remedy the situation (@pxref{Troubleshooting}).
@item @code{?}
@tab There are no applicable Flymake backends for this buffer, thus Flymake
@@ -166,17 +206,24 @@ and add a new backend (@pxref{Extending Flymake}).
@end multitable
-@node Backend exceptions
-@section Backend exceptions
+If you would like to customize the appearance of the mode-line, you
+can use the variables @code{flymake-mode-line-format} and
+@code{flymake-mode-line-counter-format} for that purpose.
+@xref{Customizable variables}.
+
+@node Troubleshooting
+@section Troubleshooting
+@cindex troubleshooting
@cindex backend exceptions
@cindex disabled backends
@cindex backends, disabled
-Some backends may take longer than others to respond or complete, and
-some may decide to @emph{disable} themselves if they are not suitable
-for the current buffer or encounter some unavoidable problem. A
-disabled backend is not tried again for future checks of the current
-buffer.
+As Flymake supports multiple simultaneously active external backends,
+is becomes useful to monitor their status. For example, some backends
+may take longer than others to respond or complete, and some may
+decide to @emph{disable} themselves if they are not suitable for the
+current buffer or encounter some unavoidable problem. A disabled
+backend is not tried again for future checks of the current buffer.
@findex flymake-reporting-backends
@findex flymake-running-backends
@@ -186,18 +233,23 @@ The commands @code{flymake-reporting-backends},
show the backends currently used and those which are disabled.
@cindex reset disabled backends
-Toggling @code{flymake-mode} off and on again, or invoking
-@code{flymake-start} with a prefix argument is one way to reset the
-disabled backend list, so that they will be tried again in the next check.
+Sometimes, re-starting a backend that disabled itself is useful after
+some external roadblock has been removed (for example after the user
+installed a needed syntax-check program). Invoking
+@code{flymake-start} with a prefix argument is a way to reset the
+disabled backend list, so that they will be tried again in the next
+check. Manually toggling @code{flymake-mode} off and on again also
+works.
@cindex logging
@cindex flymake logging
-Flymake also uses a simple logging facility for indicating important
-points in the control flow. The logging facility sends logging
-messages to the @file{*Flymake log*} buffer. The information logged
-can be used for resolving various problems related to Flymake. For
-convenience, a shortcut to this buffer can be found in Flymake's menu,
-accessible from the top menu bar or just left of the status indicator.
+Flymake uses a simple logging facility for indicating important points
+in the control flow. The logging facility sends logging messages to
+the @file{*Flymake log*} buffer. The logged information can be used
+for resolving various problems related to Flymake. For convenience, a
+shortcut to this buffer can be found in Flymake's menu, accessible
+from the top menu bar or just left of the status indicator. The
+command @code{flymake-switch-to-log-buffer} is another alternative.
@vindex warning-minimum-log-level
@vindex warning-minimum-level
@@ -217,7 +269,7 @@ configuration of the Flymake user interface.
Format to use for the Flymake mode line indicator.
@item flymake-mode-line-counter-format
-Mode-line construct for formatting Flymake diagnostic counters inside
+mode line construct for formatting Flymake diagnostic counters inside
the Flymake mode line indicator.
@item flymake-no-changes-timeout
@@ -270,10 +322,10 @@ Flymake can primarily be extended in one of two ways:
@enumerate
@item
By changing the look and feel of the annotations produced by the
-different backends.
+different backends. @xref{Flymake error types}.
@item
-By adding a new buffer-checking backend.
+By adding a new buffer-checking backend. @xref{Backend functions}.
@end enumerate
The following sections discuss each approach in detail.
@@ -288,10 +340,12 @@ The following sections discuss each approach in detail.
@cindex customizing error types
@cindex error types, customization
-To customize the appearance of error types, set properties on the
-symbols associated with each diagnostic type. The standard diagnostic
-symbols are @code{:error}, @code{:warning} and @code{:note} (though
-the backend may define more, @pxref{Backend functions}).
+To customize the appearance of error types, the user must set
+properties on the symbols associated with each diagnostic type.
+
+The three standard diagnostic keyword symbols -- @code{:error},
+@code{:warning} and @code{:note} -- have pre-configured appearances.
+However a backend may define more (@pxref{Backend functions}).
The following properties can be set:
@@ -489,7 +543,7 @@ manual}) or other asynchronous mechanisms.
In any case, backend functions are expected to return quickly or
signal an error, in which case the backend is disabled
-(@pxref{Backend exceptions}).
+(@pxref{Troubleshooting}).
If the function returns, Flymake considers the backend to be
@dfn{running}. If it has not done so already, the backend is expected
@@ -540,6 +594,7 @@ reports targeting other parts of the buffer remain valid.
@menu
* Flymake utility functions::
+* Foreign and list-only diagnostics::
* An annotated example backend::
@end menu
@@ -551,20 +606,26 @@ reports targeting other parts of the buffer remain valid.
Before delivering them to Flymake, backends create diagnostic objects
by calling the function @code{flymake-make-diagnostic}.
-@deffn Function flymake-make-diagnostic buffer beg end type text
-Make a Flymake diagnostic for @var{buffer}'s region from @var{beg} to
-@var{end}. @var{type} is a diagnostic symbol (@pxref{Flymake error
-types}), and @var{text} is a description of the problem detected in
-this region. Currently, it is unspecified behavior to make
-diagnostics for buffers other than the buffer that the Flymake backend
-is responsible for.
+@deffn Function flymake-make-diagnostic locus beg end type text &optional data
+Make a Flymake diagnostic for the region of text in @var{locus}'s
+delimited by @var{beg} and @var{end}. @var{type} is a diagnostic
+symbol (@pxref{Flymake error types}), and @var{text} is a description
+of the problem detected in this region. Most commonly @var{locus} is
+the buffer object designating for the current buffer being
+syntax-checked. However, it may be a string nameing a file relative
+to the current working directory. @xref{Foreign and list-only
+diagnostics}, for when this may be useful. Depending on the type of
+@var{locus}, @var{beg} and @var{end} are both either buffer positions
+or conses (@var{line} . @var{col}) which specify the line and column
+of the diagnostic's start and end positions, respectively.
@end deffn
@cindex access diagnostic object
These objects' properties can be accessed with the functions
@code{flymake-diagnostic-backend}, @code{flymake-diagnostic-buffer},
@code{flymake-diagnostic-text}, @code{flymake-diagnostic-beg},
-@code{flymake-diagnostic-end} and @code{flymake-diagnostic-type}.
+@code{flymake-diagnostic-end}, @code{flymake-diagnostic-type} and
+@code{flymake-diagnostic-data}.
Additionally, the function @code{flymake-diagnostics} will collect
such objects in the region you specify.
@@ -595,7 +656,7 @@ elisp, The Emacs Lisp Reference Manual}).
@cindex add a log message
For troubleshooting purposes, backends may record arbitrary
exceptional or erroneous situations into the Flymake log
-buffer (@pxref{Backend exceptions}):
+buffer (@pxref{Troubleshooting}):
@deffn Macro flymake-log level msg &optional args
Log, at level @var{level}, the message @var{msg} formatted with
@@ -604,6 +665,58 @@ Log, at level @var{level}, the message @var{msg} formatted with
used to display the warning in Flymake's log buffer.
@end deffn
+@node Foreign and list-only diagnostics
+@subsection Foreign and list-only diagnostics
+@cindex create diagnostic object for other buffer
+
+It is possible for a given backend's implementation to use
+@code{flymake-make-diagnostic} to create diagnostics for buffers or
+files other than the ``source'' buffer where Flymake was enabled. For
+instance, this is useful when a given backend has access to
+information about the health of neighboring files that are not yet
+visited or whose diagnostics depend on the current buffer's state.
+There are two alternative ways to go about doing this:
+
+@enumerate
+
+@item
+@cindex foreign diagnostics
+@cindex domestic diagnostics
+If the information about neighboring diagnostics is obtained
+regularly, like when each syntax-checking iteration of a @code{.c}
+file also reports a number of associated problems in an neighboring
+@code{.h} file, it is better to create so-called ``foreign''
+diagnostics.
+
+This is done by passing a file name to @code{flymake-make-diagnostic}
+(@pxref{Flymake utility functions}). Then, the resulting object is
+simply reported along with the other ``domestic'' diagnostics for the
+source buffer (@pxref{Backend functions}). When the neighboring file
+is visited as a buffer and Flymake is active there, a number of
+supplemental annotations will appear and automatically update whenever
+as the ``source'' buffer is syntax-checked.
+
+@item
+@cindex list-only diagnostics
+@vindex flymake-list-only-diagnostics
+If information about neighboring diagnostics is obtained infrequently,
+like when running a time-consuming and sporadic check of a large
+project, it is easier for the backend to modify the global variable
+@code{flymake-list-only-diagnostics}.
+
+Flymake will look up this variable when asked to compile project-wide
+lists of diagnostics. The backend should add one or more alist
+entries that look like (@var{file-name} . @var{diags}).
+@var{file-name} is the absolute name of the neighboring file presumed
+not to be visited in Emacs already, as that would mean that that
+buffer contains more up-to-date information on its diagnostics.
+@var{diags} is a list of diagnostic objects. When the neighboring
+file @var{file-name} is visited as a buffer and Flymake is activated
+there, the ``list-only'' diagnostics will @emph{not} produce
+annotations for @var{diags}, as Flymake assumes that the Flymake
+activation in the new buffer will take care of that.
+@end enumerate
+
@node An annotated example backend
@subsection An annotated example backend
@cindex example of backend
@@ -661,7 +774,7 @@ Binding,,, elisp, The Emacs Lisp Reference Manual}) to be active.
;; Check that the process has indeed exited, as it might
;; be simply suspended.
;;
- (when (eq 'exit (process-status proc))
+ (when (memq (process-status proc) '(exit signal))
(unwind-protect
;; Only proceed if `proc' is the same as
;; `ruby--flymake-proc', which indicates that
@@ -1032,13 +1145,13 @@ file are parsed.
For @file{file.h}, the include directives to look for are
@code{#include "file.h"}, @code{#include "../file.h"}, etc. Each
include is checked against a list of include directories
-(see @ref{Getting the include directories}) to be sure it points to the
+(@pxref{Getting the include directories}) to be sure it points to the
correct @file{file.h}.
First matching master file found stops the search. The master file is then
patched and saved to disk. In case no master file is found, syntax check is
aborted, and corresponding status (@samp{!}) is reported in the mode line.
-@xref{Syntax check statuses}.
+@xref{Mode line status}.
@node Getting the include directories
@section Getting the include directories
@@ -1064,7 +1177,7 @@ of every syntax check attempt.
@section Locating the buildfile
@cindex locating the buildfile
@cindex buildfile, locating
-@cindex Makefile, locating
+@cindex makefile, locating
The Proc backend can be configured to use different tools for
performing syntax checks. For example, it can use direct compiler
diff --git a/doc/misc/gnus-faq.texi b/doc/misc/gnus-faq.texi
index 28bee11d2bd..36c402ab35a 100644
--- a/doc/misc/gnus-faq.texi
+++ b/doc/misc/gnus-faq.texi
@@ -1443,7 +1443,7 @@ details.
However, what you really want is the Insidious Big Brother
Database bbdb. Get it from
-@uref{http://bbdb.sourceforge.net/, bbdb's homepage}.
+@uref{http://bbdb.sourceforge.net/, bbdb's website}.
Now place the following in @file{~/.gnus.el}, to activate bbdb for Gnus:
@example
@@ -1559,7 +1559,7 @@ if you already use Gnus 5.10, if you still use 5.8.8 or
"Request confirmation when replying to news."
(interactive)
(when (or (not (gnus-news-group-p gnus-newsgroup-name))
- (y-or-n-p "Really reply by mail to article author? "))
+ (y-or-n-p "Really reply by mail to article author?"))
ad-do-it))))
@end example
@noindent
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index 5f3fba00df7..74b5fb442e3 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -1004,7 +1004,7 @@ The fundamental building blocks of Gnus are @dfn{servers},
@dfn{groups}, and @dfn{articles}. Servers can be local or remote.
Each server maintains a list of groups, and those groups contain
articles. Because Gnus presents a unified interface to a wide variety
-of servers, the vocabulary doesn't always quite line up (see @ref{FAQ
+of servers, the vocabulary doesn't always quite line up (@pxref{FAQ
- Glossary}, for a more complete glossary). Thus a local maildir is
referred to as a ``server'' (@pxref{Finding the News}) the same as a
Usenet or IMAP server is; ``groups'' (@pxref{Group Buffer}) might mean
@@ -7130,20 +7130,15 @@ as 10, you might consider setting this variable to something sensible:
(setq gnus-simplify-ignored-prefixes
(concat
"\\`\\[?\\("
- (mapconcat
- 'identity
- '("looking"
- "wanted" "followup" "summary\\( of\\)?"
- "help" "query" "problem" "question"
- "answer" "reference" "announce"
- "How can I" "How to" "Comparison of"
- ;; ...
- )
- "\\|")
+ (regexp-opt '("looking"
+ "wanted" "followup" "summary" "summary of"
+ "help" "query" "problem" "question"
+ "answer" "reference" "announce"
+ "How can I" "How to" "Comparison of"
+ ;; ...
+ ))
"\\)\\s *\\("
- (mapconcat 'identity
- '("for" "for reference" "with" "about")
- "\\|")
+ (regexp-opt '("for" "for reference" "with" "about"))
"\\)?\\]?:?[ \t]*"))
@end lisp
@@ -9374,6 +9369,12 @@ Use html2text---a simple @acronym{HTML} converter included with Gnus.
@end table
+@item W D F
+@kindex W D F @r{(Summary)}
+@findex gnus-article-toggle-fonts
+Toggle proportional fonts for @acronym{HTML} articles. This temporarily
+changes the @code{shr-use-fonts} variable in the current article buffer.
+
@item W b
@kindex W b @r{(Summary)}
@findex gnus-article-add-buttons
@@ -9842,6 +9843,13 @@ Gravatarify the @code{From} header (@code{gnus-treat-from-gravatar}).
Gravatarify all mail headers (i.e., @code{Cc}, @code{To})
(@code{gnus-treat-from-gravatar}).
+@item W D e
+@kindex W D e @r{(Summary)}
+@findex gnus-article-emojize-symbols
+Some symbols have both a non-emoji presentation and an emoji
+presentation. This command will make Gnus choose the emoji presentation
+(@code{gnus-article-emojize-symbols}).
+
@item W D D
@kindex W D D @r{(Summary)}
@findex gnus-article-remove-images
@@ -12184,6 +12192,7 @@ controlling variable is a predicate list, as described above.
@vindex gnus-treat-capitalize-sentences
@vindex gnus-treat-overstrike
@vindex gnus-treat-strip-cr
+@vindex gnus-treat-emojize-symbols
@vindex gnus-treat-strip-headers-in-body
@vindex gnus-treat-strip-leading-blank-lines
@vindex gnus-treat-strip-multiple-blank-lines
@@ -12236,6 +12245,7 @@ possible but those listed are probably sufficient for most people.
@item gnus-treat-capitalize-sentences (t, integer)
@item gnus-treat-overstrike (t, integer)
@item gnus-treat-strip-cr (t, integer)
+@item gnus-treat-emojize-symbols (t, integer)
@item gnus-treat-strip-headers-in-body (t, integer)
@item gnus-treat-strip-leading-blank-lines (t, first, integer)
@item gnus-treat-strip-multiple-blank-lines (t, integer)
@@ -13869,11 +13879,9 @@ present in this hook.
@item nntp-authinfo-function
@vindex nntp-authinfo-function
@findex nntp-send-authinfo
-@vindex nntp-authinfo-file
This function will be used to send @samp{AUTHINFO} to the @acronym{NNTP}
server. The default function is @code{nntp-send-authinfo}, which looks
-through your @file{~/.authinfo} (or whatever you've set the
-@code{nntp-authinfo-file} variable to) for applicable entries. If none
+through your @file{~/.authinfo} for applicable entries. If none
are found, it will prompt you for a login name and a password. The
format of the @file{~/.authinfo} file is (almost) the same as the
@code{ftp} @file{~/.netrc} file, which is defined in the @code{ftp}
@@ -15439,10 +15447,6 @@ If non-@code{nil}, ask for confirmation before deleting old incoming
files. This variable only applies when
@code{mail-source-delete-incoming} is a positive number.
-@item mail-source-ignore-errors
-@vindex mail-source-ignore-errors
-If non-@code{nil}, ignore errors when reading mail from a mail source.
-
@item mail-source-directory
@vindex mail-source-directory
Directory where incoming mail source files (if any) will be stored. The
@@ -18044,7 +18048,7 @@ find all messages that have been received recently from certain groups:
(list
(cons 'query
(format-time-string "SENTSINCE %d-%b-%Y"
- (time-subtract (current-time)
+ (time-subtract nil
(days-to-time (car args)))))
(cons 'criteria "")))
(group-spec (cadr args)))
@@ -21892,7 +21896,7 @@ bound to mairix searches and are automatically updated.
Mairix is a tool for indexing and searching words in locally stored
mail. It was written by Richard Curnow and is licensed under the
GPL@. Mairix comes with most popular GNU/Linux distributions, but it also
-runs under Windows (with cygwin), macOS and Solaris. The homepage can
+runs under Windows (with cygwin), macOS and Solaris. The website can
be found at
@uref{http://www.rpcurnow.force9.co.uk/mairix/index.html}
@@ -22721,6 +22725,13 @@ output lines in the various buffers. There's quite a lot of them.
Fortunately, they all use the same syntax, so there's not that much to
be annoyed by.
+Gnus does not use the font locking machinery used by most modes in
+Emacs, so switching @code{font-lock-mode} on in the Gnus
+group/summary/article buffers usually doesn't do anything
+useful---instead it'll just mess up the faces that Gnus has already
+put in the buffer. (This is also the case for other minor modes that
+use the font locking machinery, like @code{whitespace-mode}.)
+
Here's an example format spec (from the group buffer): @samp{%M%S%5y:
%(%g%)\n}. We see that it is indeed extremely ugly, and that there are
lots of percentages everywhere.
@@ -26311,7 +26322,7 @@ Fortunately, setting up the Gnus registry is pretty easy:
@end lisp
This adds registry saves to Gnus newsrc saves (which happen on exit
-and when you press @kbd{s} from the @file{*Group*} buffer. It also
+and when you press @kbd{s} from the @file{*Group*} buffer). It also
adds registry calls to article actions in Gnus (copy, move, etc.)@: so
it's not easy to undo the initialization. See
@code{gnus-registry-initialize} for the gory details.
@@ -28875,7 +28886,7 @@ gnus-agent-cache nil)} reverts to the old behavior.
@item
Dired integration
-@code{gnus-dired-minor-mode} (see @ref{Other modes}) installs key
+@code{gnus-dired-minor-mode} (@pxref{Other modes}) installs key
bindings in dired buffers to send a file as an attachment, open a file
using the appropriate mailcap entry, and print a file using the mailcap
entry.
diff --git a/doc/misc/htmlfontify.texi b/doc/misc/htmlfontify.texi
index 1674565cdac..b2216924e2d 100644
--- a/doc/misc/htmlfontify.texi
+++ b/doc/misc/htmlfontify.texi
@@ -633,7 +633,7 @@ Convert an Emacs :foreground property to a CSS color property.
(hfy-flatten-style @var{style})
@end lisp
-Take @var{style} (see @ref{hfy-face-to-style-i}, @ref{hfy-face-to-style})
+Take @var{style} (@pxref{hfy-face-to-style-i}, @pxref{hfy-face-to-style})
and merge any multiple attributes appropriately. Currently only font-size is
merged down to a single occurrence---others may need special handling, but I
haven't encountered them yet. Returns a @ref{hfy-style-assoc}.
@@ -841,7 +841,7 @@ See @ref{hfy-display-class} for details of valid values for @var{class}.
@end lisp
Find face in effect at point P@. If overlays are to be considered
-(see @ref{hfy-optimizations}) then this may return a @code{defface} style
+(@pxref{hfy-optimizations}) then this may return a @code{defface} style
list of face properties instead of a face symbol.
@item hfy-bgcol
diff --git a/doc/misc/mairix-el.texi b/doc/misc/mairix-el.texi
index a571c744870..e57b5ed5422 100644
--- a/doc/misc/mairix-el.texi
+++ b/doc/misc/mairix-el.texi
@@ -60,6 +60,8 @@ database.
* Using:: List of interactive functions
* Extending:: Support your favorite mail reader!
* GNU Free Documentation License:: The license for this documentation.
+* Function Index: Function Index.
+* Variable Index: Variable Index.
@end menu
@node About
@@ -68,7 +70,7 @@ database.
Mairix is a tool for indexing and searching words in locally stored
mail. It was written by Richard Curnow and is licensed under the
GPL@. Mairix comes with most popular GNU/Linux distributions, but it also
-runs under Windows (with cygwin), macOS and Solaris. The homepage can
+runs under Windows (with cygwin), macOS and Solaris. The website can
be found at
@uref{http://www.rpcurnow.force9.co.uk/mairix/index.html}
@@ -339,4 +341,14 @@ And that's it!
@appendix GNU Free Documentation License
@include doclicense.texi
+@node Function Index
+@unnumbered Function Index
+
+@printindex fn
+
+@node Variable Index
+@unnumbered Variable Index
+
+@printindex vr
+
@bye
diff --git a/doc/misc/message.texi b/doc/misc/message.texi
index c0e3dfae12d..4136ad859f7 100644
--- a/doc/misc/message.texi
+++ b/doc/misc/message.texi
@@ -1699,14 +1699,15 @@ result is inserted.
@cindex Sv
@cindex Re
Responses to messages have subjects that start with @samp{Re: }. This
-is @emph{not} an abbreviation of the English word ``response'', but is
-Latin, and means ``in response to''. Some illiterate nincompoops have
-failed to grasp this fact, and have ``internationalized'' their software
-to use abominations like @samp{Aw: } (``antwort'') or @samp{Sv: }
-(``svar'') instead, which is meaningless and evil. However, you may
-have to deal with users that use these evil tools, in which case you may
-set this variable to a regexp that matches these prefixes. Myself, I
-just throw away non-compliant mail.
+is @emph{not} an abbreviation of the English word ``response'', but it
+comes from the Latin ``res'', and means ``in the matter of''. Some
+illiterate nincompoops have failed to grasp this fact, and have
+``internationalized'' their software to use abominations like
+@samp{Aw: } (``antwort'') or @samp{Sv: } (``svar'') instead, which is
+meaningless and evil. However, you may have to deal with users that
+use these evil tools, in which case you may set this variable to a
+regexp that matches these prefixes. Myself, I just throw away
+non-compliant mail.
Here's an example of a value to deal with these headers when
responding to a message:
diff --git a/doc/misc/mh-e.texi b/doc/misc/mh-e.texi
index a7c1fed29cb..d96c243f52b 100644
--- a/doc/misc/mh-e.texi
+++ b/doc/misc/mh-e.texi
@@ -1018,16 +1018,16 @@ Send multimedia messages (@pxref{Adding Attachments}).
Read HTML messages (@pxref{HTML}).
@c -------------------------
@item
-Use aliases and identities (see @ref{Aliases}, @pxref{Identities}).
+Use aliases and identities (@pxref{Aliases}, @pxref{Identities}).
@c -------------------------
@item
-Create different views of your mail (see @ref{Threading}, @pxref{Limits}).
+Create different views of your mail (@pxref{Threading}, @pxref{Limits}).
@c -------------------------
@item
Deal with junk mail (@pxref{Junk}).
@c -------------------------
@item
-Handle signed and encrypted messages (see @ref{Reading PGP},
+Handle signed and encrypted messages (@pxref{Reading PGP},
@pxref{Sending PGP}).
@c -------------------------
@item
@@ -1038,7 +1038,7 @@ Process mail that was sent with @command{shar} or @command{uuencode}
Use sequences conveniently (@pxref{Sequences}).
@c -------------------------
@item
-Use the speedbar, tool bar, and menu bar (see @ref{Speedbar}, see @ref{Tool
+Use the speedbar, tool bar, and menu bar (@pxref{Speedbar}, @pxref{Tool
Bar}, @pxref{Menu Bar}).
@c -------------------------
@item
@@ -8114,7 +8114,7 @@ width is 4, so you would use @samp{(mh-set-cmd-note 4)}.
@vindex mh-scan-format-nmh
The default setting for @code{mh-scan-format-file} is @samp{Use MH-E
-scan Format}. This means that the format string will be taken from the
+scan Format}. This means that the format string will be taken from
either @code{mh-scan-format-mh} or @code{mh-scan-format-nmh} depending
on whether MH or nmh (or GNU mailutils MH) is in use. This setting
also enables you to turn on the option
@@ -8816,8 +8816,8 @@ hands several times since then. Jim Larus wanted to do something
similar for GNU Emacs, and ended up completely rewriting it that same
year. In 1989, Stephen Gildea picked it up and added many
improvements. Bill Wohler then took over in 2000 and moved its
-development to @uref{https://sourceforge.net/, SourceForge} where it
-lives today.
+development to @uref{https://sourceforge.net/, SourceForge}.
+Since 2016, MH-E development occurs within the Emacs repository.
@menu
* From Brian Reid::
diff --git a/doc/misc/modus-themes.org b/doc/misc/modus-themes.org
index 5bb230f892a..f67a1795673 100644
--- a/doc/misc/modus-themes.org
+++ b/doc/misc/modus-themes.org
@@ -5,9 +5,9 @@
#+options: ':t toc:nil author:t email:t num:t
#+startup: content
-#+macro: stable-version 1.5.0
-#+macro: release-date 2021-07-15
-#+macro: development-version 1.6.0-dev
+#+macro: stable-version 1.7.0
+#+macro: release-date 2021-11-18
+#+macro: development-version 1.8.0-dev
#+macro: file @@texinfo:@file{@@$1@@texinfo:}@@
#+macro: space @@texinfo:@: @@
#+macro: kbd @@texinfo:@kbd{@@$1@@texinfo:}@@
@@ -95,7 +95,7 @@ Emacs.
:end:
#+cindex: Screenshots
-Check the web page with [[https://protesilaos.com/modus-themes-pictures/][the screen shots]]. There are lots of scenarios
+Check the web page with [[https://protesilaos.com/emacs/modus-themes-pictures/][the screen shots]]. There are lots of scenarios
on display that draw attention to details and important aspects in the
design of the themes. They also showcase the numerous customization
options.
@@ -108,7 +108,7 @@ options.
:end:
#+cindex: Changelog
-Please refer to the [[https://protesilaos.com/modus-themes-changelog][web page with the change log]]. It is comprehensive
+Please refer to the [[https://protesilaos.com/emacs/modus-themes-changelog][web page with the change log]]. It is comprehensive
and covers everything that goes into every tagged release of the themes.
* Installation
@@ -268,7 +268,7 @@ could look like:
(define-key global-map (kbd "<f5>") #'modus-themes-toggle)
#+end_src
-[[#h:e979734c-a9e1-4373-9365-0f2cd36107b8][Sample configuration for use-package]].
+[[#h:e979734c-a9e1-4373-9365-0f2cd36107b8][Sample configuration with and without use-package]].
With those granted, bear in mind a couple of technical points on
~modus-themes-load-operandi~ and ~modus-themes-load-vivendi~, as well as
@@ -279,15 +279,16 @@ With those granted, bear in mind a couple of technical points on
2. The functions will run the ~modus-themes-after-load-theme-hook~ as
their final step. This can be employed for bespoke configurations
- ([[#h:f4651d55-8c07-46aa-b52b-bed1e53463bb][Advanced customization (do-it-yourself)]]). Experienced users may not
- wish to rely on such a hook and the functions that run it: they may
- prefer a custom solution ([[#h:86f6906b-f090-46cc-9816-1fe8aeb38776][A theme-agnostic hook for theme loading]]).
+ ([[#h:f4651d55-8c07-46aa-b52b-bed1e53463bb][Advanced customization]]). Experienced users may not wish to rely
+ on such a hook and the functions that run it: they may prefer a
+ custom solution ([[#h:86f6906b-f090-46cc-9816-1fe8aeb38776][A theme-agnostic hook for theme loading]]).
-** Sample configuration for use-package
+** Sample configuration with and without use-package
:properties:
:custom_id: h:e979734c-a9e1-4373-9365-0f2cd36107b8
:end:
#+cindex: use-package configuration
+#+cindex: sample configuration
It is common for Emacs users to rely on ~use-package~ for declaring
package configurations in their setup. We use this as an example:
@@ -309,6 +310,25 @@ package configurations in their setup. We use this as an example:
:bind ("<f5>" . modus-themes-toggle))
#+end_src
+The same without ~use-package~:
+
+#+begin_src emacs-lisp
+(require 'modus-themes)
+
+;; Add all your customizations prior to loading the themes
+(setq modus-themes-italic-constructs t
+ modus-themes-bold-constructs nil
+ modus-themes-region '(bg-only no-extend))
+
+;; Load the theme files before enabling a theme
+(modus-themes-load-themes)
+
+;; Load the theme of your choice:
+(modus-themes-load-operandi) ;; OR (modus-themes-load-vivendi)
+
+(define-key global-map (kbd "<f5>") #'modus-themes-toggle)
+#+end_src
+
[[#h:e68560b3-7fb0-42bc-a151-e015948f8a35][Differences between loading and enabling]].
Note: make sure not to customize the variable ~custom-theme-load-path~
@@ -325,7 +345,7 @@ package declaration of the themes.
The reason we recommend ~load-theme~ instead of the other option of
~enable-theme~ is that the former does a kind of "reset" on the face
-specs. It quite literally loads (or re-loads) the theme. Whereas the
+specs. It quite literally loads (or reloads) the theme. Whereas the
latter simply puts an already loaded theme at the top of the list of
enabled items, re-using whatever state was last loaded.
@@ -352,7 +372,7 @@ session, are better off using something like this:
(enable-theme 'modus-operandi) ;; OR (enable-theme 'modus-vivendi)
#+end_src
-[[#h:e979734c-a9e1-4373-9365-0f2cd36107b8][Sample configuration for use-package]].
+[[#h:e979734c-a9e1-4373-9365-0f2cd36107b8][Sample configuration with and without use-package]].
With the above granted, other sections of the manual discuss how to
configure custom faces, where ~load-theme~ is expected, though
@@ -372,7 +392,8 @@ without any further tweaks. By default, all customization options are
set to nil, unless otherwise noted in this manual.
Remember that all customization options must be evaluated before loading
-a theme ([[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]]).
+a theme ([[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]]). If the theme is already active, it must be
+reloaded for changes in user options to come into force.
Below is a summary of what you will learn in the subsequent sections of
this manual.
@@ -380,9 +401,11 @@ this manual.
#+begin_src emacs-lisp
(setq modus-themes-italic-constructs t
modus-themes-bold-constructs nil
- modus-themes-no-mixed-fonts nil
+ modus-themes-mixed-fonts nil
modus-themes-subtle-line-numbers nil
+ modus-themes-intense-markup t
modus-themes-success-deuteranopia t
+ modus-themes-tabs-accented t
modus-themes-inhibit-reload t ; only applies to `customize-set-variable' and related
modus-themes-fringes nil ; {nil,'subtle,'intense}
@@ -390,14 +413,17 @@ this manual.
;; Options for `modus-themes-lang-checkers' are either nil (the
;; default), or a list of properties that may include any of those
;; symbols: `straight-underline', `text-also', `background',
- ;; `intense'
+ ;; `intense' OR `faint'.
modus-themes-lang-checkers nil
;; Options for `modus-themes-mode-line' are either nil, or a list
;; that can combine any of `3d' OR `moody', `borderless',
- ;; `accented'. The variable's doc string shows all possible
- ;; combinations.
- modus-themes-mode-line '(3d accented)
+ ;; `accented', `padded'.
+ modus-themes-mode-line '(padded accented borderless)
+
+ ;; This one only works when `modus-themes-mode-line' (above) has
+ ;; the `padded' property. It takes a positive integer.
+ modus-themes-mode-line-padding 3
;; Options for `modus-themes-syntax' are either nil (the default),
;; or a list of properties that may include any of those symbols:
@@ -443,13 +469,14 @@ this manual.
modus-themes-org-agenda ; this is an alist: read the manual or its doc string
'((header-block . (variable-pitch scale-title))
(header-date . (grayscale workaholic bold-today))
+ (event . (accented scale-small))
(scheduled . uniform)
(habit . traffic-light-deuteranopia))
modus-themes-headings ; this is an alist: read the manual or its doc string
'((1 . (overline background))
(2 . (rainbow overline))
- (t . (no-bold)))
+ (t . (semibold)))
modus-themes-variable-pitch-ui nil
modus-themes-variable-pitch-headings t
@@ -469,11 +496,14 @@ this manual.
:end:
#+vindex: modus-themes-inhibit-reload
-Symbol: ~modus-themes-inhibit-reload~
+Brief: Toggle reloading of the active theme when an option is changed
+through the Customize UI.
+
+Symbol: ~modus-themes-inhibit-reload~ (=boolean= type)
Possible values:
-1. ~nil~
+1. ~nil~
2. ~t~ (default)
By default, customizing a theme-related user option through the Custom
@@ -482,7 +512,10 @@ currently active Modus theme.
Enable this behaviour by setting this variable to ~nil~.
-** Option for color-coding success state (deuteranopia)
+Regardless of this option, the active theme must be reloaded for changes
+to user options to take effect ([[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]]).
+
+** Option for color-coding success state
:properties:
:alt_title: Success' color-code
:description: Toggle blue color for success or done states
@@ -490,25 +523,27 @@ Enable this behaviour by setting this variable to ~nil~.
:end:
#+vindex: modus-themes-success-deuteranopia
-Symbol: ~modus-themes-success-deuteranopia~
+Brief: Toggle the use of blue instead of green in places which
+color-code green as "success" and red as "failure".
+
+Symbol: ~modus-themes-success-deuteranopia~ (=boolean= type)
Possible values:
1. ~nil~ (default)
2. ~t~
-The default is to colorise all faces that denote "success", "done", or
-similar with a variant of green.
+The default is to colorise a passing state in a green hue. This affects
+all faces that denote "success", "done", marking a selection as opposed
+to marking for deletion, the current search match in contrast to lazily
+highlighted ones, and the like.
With a non-nil value (~t~), use variants of blue instead of green. This
is meant to empower users with red-green color deficiency.
-The present customization option should apply to all contexts where
-there can be a color-coded distinction between success and failure,
-to-do and done, and so on.
-
-Diffs, which have a red/green dichotomy by default, can also be
-configured to conform with deuteranopia.
+Diffs, which rely on a red/green dichotomy by default, can also be
+configured to meet the needs of users with deuteranopia via the option
+~modus-themes-diffs~.
[[#h:ea7ac54f-5827-49bd-b09f-62424b3b6427][Option for diff buffer looks]].
@@ -520,7 +555,9 @@ configured to conform with deuteranopia.
:end:
#+vindex: modus-themes-bold-constructs
-Symbol: ~modus-themes-bold-constructs~
+Brief: Use bold for code syntax highlighting and related.
+
+Symbol: ~modus-themes-bold-constructs~ (=boolean= type)
Possible values:
@@ -548,7 +585,9 @@ Advanced users may also want to configure the exact attributes of the
:end:
#+vindex: modus-themes-italic-constructs
-Symbol: ~modus-themes-italic-constructs~
+Brief: Use italics for code syntax highlighting and related.
+
+Symbol: ~modus-themes-italic-constructs~ (=boolean= type)
Possible values:
@@ -574,7 +613,9 @@ Advanced users may also want to configure the exact attributes of the
:end:
#+vindex: modus-themes-syntax
-Symbol: ~modus-themes-syntax~
+Brief: Set the overall style of code syntax highlighting.
+
+Symbol: ~modus-themes-syntax~ (=choice= type, list of properties)
Possible values are expressed as a list of properties (default is ~nil~ or
an empty list). The list can include any of the following symbols:
@@ -628,36 +669,41 @@ weight or italic text: ~modus-themes-bold-constructs~ and
[[#h:977c900d-0d6d-4dbb-82d9-c2aae69543d6][Option for more italic constructs]].
-** Option for no font mixing
+** Option for font mixing
:properties:
-:alt_title: No mixed fonts
+:alt_title: Mixed fonts
:description: Toggle mixing of font families
:custom_id: h:115e6c23-ee35-4a16-8cef-e2fcbb08e28b
:end:
-#+vindex: modus-themes-no-mixed-fonts
+#+vindex: modus-themes-mixed-fonts
-Symbol: ~modus-themes-no-mixed-fonts~
+Brief: Toggle the use of monospaced fonts for spacing-sensitive
+constructs (affects font families).
+
+Symbol: ~modus-themes-mixed-fonts~ (=boolean= type)
Possible values:
1. ~nil~ (default)
2. ~t~
-By default, the themes configure some spacing-sensitive faces like Org
+When set to non-nil (~t~), configure some spacing-sensitive faces like Org
tables and code blocks to always inherit from the ~fixed-pitch~ face.
-This is to ensure that those constructs remain monospaced even when
-users opt for a mode that remaps typeface families, such as the built-in
-{{{kbd(M-x variable-pitch-mode)}}}. Otherwise the layout would appear
-broken, due to how spacing is done. To disable this behaviour, set the
-option to ~t~.
+This is to ensure that certain constructs like code blocks and tables
+remain monospaced even when users opt for a mode that remaps typeface
+families, such as the built-in {{{kbd(M-x variable-pitch-mode)}}}. Otherwise
+the layout would appear broken, due to how spacing is done.
-Users may prefer to use another package for handling mixed typeface
-configurations, rather than letting the theme do it, perhaps because a
-purpose-specific package has extra functionality. Two possible options
-are ~org-variable-pitch~ and ~mixed-pitch~.
+For a consistent experience, user may need to specify the font family of
+the ~fixed-pitch~ face.
[[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations for Org and others]].
+Furthermore, users may prefer to use another package for handling mixed
+typeface configurations, rather than letting the theme do it, perhaps
+because a purpose-specific package has extra functionality. Two
+possible options are ~org-variable-pitch~ and ~mixed-pitch~.
+
** Option for links
:properties:
:alt_title: Link styles
@@ -666,7 +712,9 @@ are ~org-variable-pitch~ and ~mixed-pitch~.
:end:
#+vindex: modus-themes-links
-Symbol: ~modus-themes-links~
+Brief: Control the style of links to web pages, files, buffers...
+
+Symbol: ~modus-themes-links~ (=choice= type, list of properties)
Possible values are expressed as a list of properties (default is ~nil~ or
an empty list). The list can include any of the following symbols:
@@ -737,7 +785,10 @@ their documentation strings.
:end:
#+vindex: modus-themes-prompts
-Symbol: ~modus-themes-prompts~
+Brief: Control the style of command prompts (e.g. minibuffer, shell, IRC
+clients).
+
+Symbol: ~modus-themes-prompts~ (=choice= type, list of properties)
Possible values are expressed as a list of properties (default is ~nil~ or
an empty list). The list can include any of the following symbols:
@@ -793,7 +844,9 @@ In user configuration files the form may look like this:
:end:
#+vindex: modus-themes-mode-line
-Symbol: ~modus-themes-mode-line~
+Brief: Control the style of the mode lines.
+
+Symbol: ~modus-themes-mode-line~ (=choice= type, list of properties)
Possible values, which can be expressed as a list of combinations of box
effect, color, and border visibility:
@@ -803,6 +856,7 @@ effect, color, and border visibility:
- ~moody~
+ ~accented~
+ ~borderless~
++ ~padded~
The default (a nil value or an empty list) is a two-dimensional
rectangle with a border around it. The active and the inactive
@@ -829,6 +883,16 @@ the same as the background, effectively creating some padding.
The ~accented~ property ensures that the active mode line uses a
colored background instead of the standard shade of gray.
+The ~padded~ property increases the apparent height of the mode line.
+This is done by applying box effects and combining them with an
+underline and overline. To ensure that the underline is placed at the
+bottom, set ~x-underline-at-descent-line~ to non-nil. The ~padded~ property
+has no effect when the ~moody~ property is also used, because Moody
+already applies its own padding. The exact value of the padding is
+controlled by the variable ~modus-themes-mode-line-padding~.
+
+[[#h:a12b4d3c-e66b-42ed-99ab-4ea039b69e2e][Option for mode line padding]].
+
Combinations of any of those properties are expressed as a list,
like in these examples:
@@ -843,7 +907,7 @@ The order in which the properties are set is not significant.
In user configuration files the form may look like this:
#+begin_src emacs-lisp
-(setq modus-themes-prompts '(borderless accented))
+(setq modus-themes-mode-line '(borderless accented))
#+end_src
Note that Moody does not expose any faces that the themes could style
@@ -868,6 +932,51 @@ Furthermore, because Moody expects an underline and overline instead of
a box style, it is advised to set ~x-underline-at-descent-line~ to a
non-nil value.
+Finally, note that various packages which heavily modify the mode line,
+such as =doom-modeline=, =nano-modeline=, =powerline=, =spaceline= may not look
+as intended with all possible combinations of this user option.
+
+*** Option for mode line padding
+:properties:
+:custom_id: h:a12b4d3c-e66b-42ed-99ab-4ea039b69e2e
+:end:
+#+vindex: modus-themes-mode-line-padding
+
+Brief: Set the padding of the mode lines.
+
+Symbol: ~modus-themes-mode-line-padding~ (=natnum= type)
+
+Controls the exact width of the mode line's padding. Possible values
+are positive integers. The default value is =6=.
+
+This customization option applies only when ~modus-themes-mode-line~ is
+configured with the ~padded~ property.
+
+[[#h:27943af6-d950-42d0-bc23-106e43f50a24][Option for mode line presentation]].
+
+** Option for accented background in tab interfaces
+:properties:
+:alt_title: Tab style
+:description: Toggle accented background for tabs
+:custom_id: h:27cef8f5-dc4e-4c93-ba41-b899e650d936
+:end:
+#+vindex: modus-themes-tabs-accented
+
+Brief: Toggle accent colors for tabbed interfaces.
+
+Symbol: ~modus-themes-tabs-accented~ (=boolean= type)
+
+Possible values:
+
++ ~nil~ (default)
++ ~t~
+
+By default, all tab interfaces use backgrounds which are shades of gray.
+When this option is set to non-nil, the backgrounds become colorful.
+
+This affects the built-in ~tab-bar-mode~ and ~tab-line-mode~, as well as the
+Centaur tabs package.
+
** Option for completion framework aesthetics
:properties:
:alt_title: Completion UIs
@@ -876,7 +985,9 @@ non-nil value.
:end:
#+vindex: modus-themes-completions
-Symbol: ~modus-themes-completions~
+Brief: Set the overall style of completion framework interfaces.
+
+Symbol: ~modus-themes-completions~ (=choice= type)
Possible values:
@@ -921,7 +1032,10 @@ possibilities.
:end:
#+vindex: modus-themes-mail-citations
-Symbol: ~modus-themes-mail-citations~
+Brief: Set the overall style of citations/quotes when composing
+emails.
+
+Symbol: ~modus-themes-mail-citations~ (=choice= type)
Possible values:
@@ -950,7 +1064,9 @@ not touch.
:end:
#+vindex: modus-themes-fringes
-Symbol: ~modus-themes-fringes~
+Brief: Control the overall coloration of the fringes.
+
+Symbol: ~modus-themes-fringes~ (=choice= type)
Possible values:
@@ -974,7 +1090,10 @@ names imply.
:end:
#+vindex: modus-themes-lang-checkers
-Symbol: ~modus-themes-lang-checkers~
+Brief: Control the style of in-buffer warnings and errors produced by
+spell checkers, code linters, and the like.
+
+Symbol: ~modus-themes-lang-checkers~ (=choice= type, list of properties)
Possible values are expressed as a list of properties (default is ~nil~ or
an empty list). The list can include any of the following symbols:
@@ -982,7 +1101,9 @@ an empty list). The list can include any of the following symbols:
+ ~straight-underline~
+ ~text-also~
+ ~background~
-+ ~intense~
++ Overall coloration:
+ - ~intense~
+ - ~faint~
The default (a ~nil~ value or an empty list) applies a color-coded
underline to the affected text, while it leaves the original foreground
@@ -998,15 +1119,15 @@ affected text.
The property ~background~ adds a color-coded background.
The property ~intense~ amplifies the applicable colors if ~background~
-and/or ~text-only~ are set. If ~intense~ is set on its own, then it implies
-~text-only~.
+and/or ~text-also~ are set. If ~intense~ is set on its own, then it implies
+~text-also~.
-To disable fringe indicators for Flymake or Flycheck, refer to variables
-~flymake-fringe-indicator-position~ and ~flycheck-indication-mode~,
-respectively.
+The property ~faint~ uses nuanced colors for the underline and for the
+foreground when ~text-also~ is included. If both ~faint~ and ~intense~ are
+specified, the former takes precedence.
-Combinations of any of those properties can be expressed in a
-list, as in those examples:
+Combinations of any of those properties can be expressed in a list, as
+in those examples:
#+begin_src emacs-lisp
(background)
@@ -1026,7 +1147,11 @@ NOTE: The placement of the straight underline, though not the wave
style, is controlled by the built-in variables ~underline-minimum-offset~,
~x-underline-at-descent-line~, ~x-use-underline-position-properties~.
-** Option for line highlighting (hl-line-mode)
+To disable fringe indicators for Flymake or Flycheck, refer to variables
+~flymake-fringe-indicator-position~ and ~flycheck-indication-mode~,
+respectively.
+
+** Option for line highlighting
:properties:
:alt_title: Line highlighting
:description: Choose style of current line (hl-line-mode)
@@ -1034,7 +1159,9 @@ style, is controlled by the built-in variables ~underline-minimum-offset~,
:end:
#+vindex: modus-themes-hl-line
-Symbol: ~modus-themes-hl-line~
+Brief: Control the style of the current line of ~hl-line-mode~.
+
+Symbol: ~modus-themes-hl-line~ (=choice= type, list of properties)
Possible values are expressed as a list of properties (default is ~nil~ or
an empty list). The list can include any of the following symbols:
@@ -1078,7 +1205,7 @@ with underlines.
This style affects several packages that enable ~hl-line-mode~, such as
=elfeed=, =notmuch=, and =mu4e=.
-** Option for line numbers (display-line-numbers-mode)
+** Option for line numbers
:properties:
:alt_title: Line numbers
:description: Toggle subtle style for line numbers
@@ -1086,7 +1213,9 @@ This style affects several packages that enable ~hl-line-mode~, such as
:end:
#+vindex: modus-themes-subtle-line-numbers
-Symbol: ~modus-themes-subtle-line-numbers~
+Brief: Toggle subtle line numbers.
+
+Symbol: ~modus-themes-subtle-line-numbers~ (=boolean= type)
Possible value:
@@ -1107,7 +1236,31 @@ Instead they retain the primary background of the theme, blending with
the rest of the buffer. Foreground values for all relevant faces are
updated to accommodate this aesthetic.
-** Option for parenthesis matching (show-paren-mode)
+** Option for intense markup in Org and others
+:properties:
+:alt_title: Intense markup
+:description: Toggle intense style for markup in Org and others
+:custom_id: h:9d9a4e64-99ac-4018-8f66-3051b9c43fd7
+:end:
+#+vindex: modus-themes-intense-markup
+
+Brief: Toggle intense style for inline code and related markup.
+
+Symbol: ~modus-themes-intense-markup~ (=boolean= type)
+
+Possible value:
+
+1. ~nil~ (default)
+2. ~t~
+
+The default style for certain markup types like inline code and verbatim
+constructs in Org and related major modes is a subtle foreground color
+combined with a subtle background.
+
+With a non-nil value (~t~), these constructs will use a more prominent
+background and foreground color combination instead.
+
+** Option for parenthesis matching
:properties:
:alt_title: Matching parentheses
:description: Choose between various styles for matching delimiters/parentheses
@@ -1115,7 +1268,10 @@ updated to accommodate this aesthetic.
:end:
#+vindex: modus-themes-paren-match
-Symbol: ~modus-themes-paren-match~
+Brief: Control the style of matching delimiters produced by
+~show-paren-mode~.
+
+Symbol: ~modus-themes-paren-match~ (=choice= type, list of properties)
Possible values are expressed as a list of properties (default is ~nil~ or
an empty list). The list can include any of the following symbols:
@@ -1162,7 +1318,9 @@ This customization variable affects the built-in ~show-paren-mode~ and the
:end:
#+vindex: modus-themes-region
-Symbol: ~modus-themes-region~
+Brief: Control the style of the region.
+
+Symbol: ~modus-themes-region~ (=choice= type, list of properties)
Possible values are expressed as a list of properties (default is ~nil~ or
an empty list). The list can include any of the following symbols:
@@ -1208,7 +1366,9 @@ In user configuration files the form may look like this:
:end:
#+vindex: modus-themes-diffs
-Symbol: ~modus-themes-diffs~
+Bried: Set the overall style of diffs.
+
+Symbol: ~modus-themes-diffs~ (=choice= type)
Possible values:
@@ -1254,7 +1414,9 @@ interest of backward compatibility.
:end:
#+vindex: modus-themes-org-blocks
-Symbol: ~modus-themes-org-blocks~
+Brief: Set the overall style of Org code blocks, quotes, and the like.
+
+Symbol: ~modus-themes-org-blocks~ (=choice= type)
Possible values:
@@ -1295,7 +1457,10 @@ and ~rainbow~. Those will continue to work as they are aliases for
:end:
#+vindex: modus-themes-org-agenda
-Symbol: ~modus-themes-org-agenda~
+Brief: Control the style of the Org agenda. Multiple parameters are
+available, each with its own options.
+
+Symbol: ~modus-themes-org-agenda~ (=alist= type, multiple styles)
This is an alist that accepts a =(key . value)= combination. Some values
are specified as a list. Here is a sample, followed by a description of
@@ -1305,6 +1470,7 @@ all possible combinations:
(setq modus-themes-org-agenda
'((header-block . (variable-pitch scale-title))
(header-date . (grayscale workaholic bold-today))
+ (event . (accented italic varied))
(scheduled . uniform)
(habit . traffic-light)))
#+end_src
@@ -1346,6 +1512,11 @@ the following properties:
- ~bold-today~ to apply a bold typographic weight to the current
date;
- ~bold-all~ to render all date headings in a bold weight.
+- ~scale-heading~ increases the height of the date headings to the value
+ of ~modus-themes-scale-1~ (which is the first step in the scale for
+ regular headings).
+- ~underline-today~ applies an underline to the current date while
+ removing the background it has by default.
For example:
@@ -1355,6 +1526,44 @@ For example:
(header-date . (grayscale bold-all))
(header-date . (grayscale workaholic))
(header-date . (grayscale workaholic bold-today))
+(header-date . (grayscale workaholic bold-today scale-heading))
+#+end_src
+
+An ~event~ key covers (i) headings with a plain time stamp that are
+shown on the agenda, also known as events, (ii) entries imported from
+the diary, and (iii) other items that derive from a symbolic expression
+or sexp (phases of the moon, holidays, etc.). By default all those look
+the same and have a subtle foreground color (the default is a nil value
+or an empty list). This key accepts a list of properties. Those are:
+
+- ~scale-small~ reduces the height of the entries to the value of
+ the user option ~modus-themes-scale-small~ (0.9 the height of
+ the main font size by default). This work best when the
+ relevant entries have no tags associated with them and when the
+ user is interested in reducing their presence in the agenda
+ view.
+- ~accented~ applies an accent value to the event's foreground,
+ replacing the original gray. It makes all entries stand out more.
+- ~italic~ adds a slant to the font's forms (italic or oblique forms,
+ depending on the typeface).
+- ~varied~ differentiates between events with a plain time stamp and
+ entries that are generated from either the diary or a symbolic
+ expression. It generally puts more emphasis on events. When ~varied~
+ is combined with ~accented~, it makes only events use an accent color,
+ while diary/sexp entries retain their original subtle foreground.
+ When ~varied~ is used in tandem with ~italic~, it applies a slant only
+ to diary and sexp entries, not events. And when ~varied~ is the sole
+ property passed to the ~event~ key, it has the same meaning as the
+ list (italic varied). The combination of ~varied~, ~accented~,
+ ~italic~ covers all of the aforementioned cases.
+
+For example:
+
+#+begin_src emacs-lisp
+(event . nil)
+(event . (italic))
+(event . (accented italic))
+(event . (accented italic varied))
#+end_src
A ~scheduled~ key applies to tasks with a scheduled date. By default (a
@@ -1416,6 +1625,7 @@ Putting it all together, the alist can look like this:
#+begin_src emacs-lisp
'((header-block . (scale-title variable-pitch))
(header-date . (grayscale workaholic bold-today))
+ (event . (accented scale-small))
(scheduled . uniform)
(habit . traffic-light))
@@ -1423,6 +1633,7 @@ Putting it all together, the alist can look like this:
(setq modus-themes-org-agenda
'((header-block . (scale-title variable-pitch))
(header-date . (grayscale workaholic bold-today))
+ (event . (accented scale-small))
(scheduled . uniform)
(habit . traffic-light)))
#+end_src
@@ -1435,7 +1646,10 @@ Putting it all together, the alist can look like this:
:end:
#+vindex: modus-themes-headings
-Symbol: ~modus-themes-headings~
+Brief: Control the style of headings. This can be particularised for
+each level of heading (e.g. Org has eight levels).
+
+Symbol: ~modus-themes-headings~ (=alist= type, multiple properties)
This is an alist that accepts a =(key . list-of-values)= combination. The
key is either a number, representing the heading's level or ~t~, which
@@ -1455,8 +1669,21 @@ Properties:
+ ~rainbow~
+ ~overline~
+ ~background~
-+ ~no-bold~
+ ~monochrome~
++ A font weight, which must be supported by the underlying typeface:
+ - ~thin~
+ - ~ultralight~
+ - ~extralight~
+ - ~light~
+ - ~semilight~
+ - ~regular~
+ - ~medium~
+ - ~semibold~
+ - ~bold~
+ - ~heavy~
+ - ~extrabold~
+ - ~ultrabold~
++ ~no-bold~
By default (a ~nil~ value for this variable), all headings have a bold
typographic weight and use a desaturated text color.
@@ -1468,20 +1695,27 @@ An ~overline~ property draws a line above the area of the heading.
A ~background~ property adds a subtle tinted color to the background of
the heading.
-A ~no-bold~ property removes the bold weight from the heading's text.
-
A ~monochrome~ property makes all headings the same base color, which is
that of the default for the active theme (black/white). When ~background~
is also set, ~monochrome~ changes its color to gray. If both ~monochrome~
and ~rainbow~ are set, the former takes precedence.
+The symbol of a weight attribute adjusts the font of the heading
+accordingly, such as ~light~, ~semibold~, etc. Valid symbols are defined in
+the internal variable ~modus-themes--heading-weights~. The absence of a
+weight means that bold will be used by virtue of inheriting the ~bold~
+face. For backward compatibility, the ~no-bold~ value is accepted, though
+users are encouraged to specify a ~regular~ weight instead.
+
+[[#h:2793a224-2109-4f61-a106-721c57c01375][Configure bold and italic faces]].
+
Combinations of any of those properties are expressed as a list, like in
these examples:
#+begin_src emacs-lisp
-(no-bold)
+(semibold)
(rainbow background)
-(overline monochrome no-bold)
+(overline monochrome semibold)
#+end_src
The order in which the properties are set is not significant.
@@ -1492,7 +1726,7 @@ In user configuration files the form may look like this:
(setq modus-themes-headings
'((1 . (background overline rainbow))
(2 . (background overline))
- (t . (overline no-bold))))
+ (t . (overline semibold))))
#+end_src
When defining the styles per heading level, it is possible to pass a
@@ -1507,7 +1741,7 @@ original aesthetic for that level. For example:
(setq modus-themes-headings
'((1 . (background overline))
- (2 . (rainbow no-bold))
+ (2 . (rainbow semibold))
(t . t))) ; default style for all other levels
#+end_src
@@ -1528,7 +1762,9 @@ others, such as ~org-fontify-done-headline~.
:end:
#+vindex: modus-themes-scale-headings
-Symbol: ~modus-themes-scale-headings~
+Brief: Toggle the scaling of headings.
+
+Symbol: ~modus-themes-scale-headings~ (=boolean= type)
Possible values:
@@ -1547,6 +1783,17 @@ main text. This is noticeable in modes like Org, Markdown, and Info.
:custom_id: h:6868baa1-beba-45ed-baa5-5fd68322ccb3
:end:
+Brief: Specify the height for individual heading scales.
+
+Symbols (all are =number= type):
+
++ ~modus-themes-scale-1~
++ ~modus-themes-scale-2~
++ ~modus-themes-scale-3~
++ ~modus-themes-scale-4~
++ ~modus-themes-scale-title~
++ ~modus-themes-scale-small~
+
In addition to the toggle for enabling scaled headings, users can also
specify a number of their own.
@@ -1574,7 +1821,8 @@ resource for finding a consistent scale:
modus-themes-scale-2 1.1
modus-themes-scale-3 1.15
modus-themes-scale-4 1.2
- modus-themes-scale-title 1.3)
+ modus-themes-scale-title 1.3
+ modus-themes-scale-small 0.9)
#+end_src
As for the application of that scale, the variables that range from
@@ -1593,6 +1841,11 @@ supposed to signify the primary header. Similarly, the Org Agenda's
structure headings are not part of a recognisable scale and so they also
get ~modus-themes-scale-title~ ([[#h:68f481bc-5904-4725-a3e6-d7ecfa7c3dbc][Option for Org agenda constructs]]).
+Similarly ~modus-themes-scale-small~ is not applied to regular headings,
+but reserved for special contexts where the user is presented with an
+option to use a smaller font height than the base size. It is only
+implemented for the Org agenda.
+
Users who wish to maintain scaled headings for the normal syntax while
preventing special headings from standing out, can assign a value of =1.0=
to ~modus-themes-scale-title~ to make it the same as body text (or
@@ -1612,7 +1865,10 @@ size of the heading, but not of keywords that were added to it, like
:end:
#+vindex: modus-themes-variable-pitch-ui
-Symbol: ~modus-themes-variable-pitch-ui~
+Brief: Toggle the use of proportionately spaced (~variable-pitch~) fonts
+in the User Interface.
+
+Symbol: ~modus-themes-variable-pitch-ui~ (=boolean= type)
Possible values:
@@ -1639,7 +1895,10 @@ is done by assigning the ~variable-pitch~ face to the relevant items.
:end:
#+vindex: modus-themes-variable-pitch-headings
-Symbol: ~modus-themes-variable-pitch-headings~
+Brief: Toggle the use of proportionately spaced (~variable-pitch~) fonts
+in headings.
+
+Symbol: ~modus-themes-variable-pitch-headings~ (=boolean= type)
Possible values:
@@ -1654,7 +1913,7 @@ With a non-nil value (~t~) apply a proportionately spaced typeface, else
[[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations for Org and others]].
-* Advanced customization (do-it-yourself)
+* Advanced customization
:properties:
:custom_id: h:f4651d55-8c07-46aa-b52b-bed1e53463bb
:end:
@@ -1669,7 +1928,7 @@ their own local tweaks and who are willing to deal with any possible
incompatibilities between versioned releases of the themes. As such,
they are labelled as "do-it-yourself" or "DIY".
-** Per-theme customization settings (DIY)
+** Per-theme customization settings
:properties:
:custom_id: h:a897b302-8e10-4a26-beab-3caaee1e1193
:end:
@@ -1704,7 +1963,7 @@ equivalent the themes provide.
For a more elaborate design, it is better to inspect the source code of
~modus-themes-toggle~ and relevant functions.
-** Case-by-case face specs using the themes' palette (DIY)
+** Case-by-case face specs using the themes' palette
:properties:
:custom_id: h:1487c631-f4fe-490d-8d58-d72ffa3bd474
:end:
@@ -1808,7 +2067,7 @@ Take the previous example with the ~cursor~ face:
(set-face-attribute 'cursor nil :background (modus-themes-color-alts 'blue 'red))
#+end_src
-** Face specs at scale using the themes' palette (DIY)
+** Face specs at scale using the themes' palette
:properties:
:custom_id: h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae
:end:
@@ -1923,7 +2182,7 @@ the previous section. Adapt the above example like this:
...))
#+end_src
-** Remap face with local value (DIY)
+** Remap face with local value
:properties:
:custom_id: h:7a93cb6f-4eca-4d56-a85c-9dcd813d6b0f
:end:
@@ -1985,7 +2244,7 @@ Perhaps you may wish to generalise those findings in to a set of
functions that also accept an arbitrary face. We shall leave the
experimentation up to you.
-** Cycle through arbitrary colors (DIY)
+** Cycle through arbitrary colors
:properties:
:custom_id: h:77dc4a30-b96a-4849-85a8-fee3c2995305
:end:
@@ -2149,7 +2408,7 @@ Must become this:
...)
#+end_src
-** Override colors (DIY)
+** Override colors
:properties:
:custom_id: h:307d95dd-8dbd-4ece-a543-10ae86f155a6
:end:
@@ -2265,7 +2524,7 @@ that we provide: [[#h:02e25930-e71a-493d-828a-8907fc80f874][test color combinati
ratio between two color values, so it can help in overriding the palette
(or a subset thereof) without making the end result inaccessible.
-** Override color saturation (DIY)
+** Override color saturation
:properties:
:custom_id: h:4589acdc-2505-41fc-9f5e-699cfc45ab00
:end:
@@ -2321,8 +2580,8 @@ Using the above has an immediate effect, as it reloads the active Modus
theme.
The =my-modus-themes-saturate= function stores new color values in the
-variables =modus-themes-operandi-color-overrides= and
-=modus-themes-vivendi-color-overrides=, meaning that it undoes changes
+variables ~modus-themes-operandi-color-overrides~ and
+~modus-themes-vivendi-color-overrides~, meaning that it undoes changes
implemented by the user on individual colors. To have both automatic
saturation adjustment across the board and retain per-case edits to the
palette, some tweaks to the above function are required. For example:
@@ -2385,23 +2644,22 @@ inspiration from the ~modus-themes-toggle~ we already provide:
('modus-vivendi (modus-themes-load-vivendi))))
#+end_src
-** Font configurations for Org and others (DIY)
+** Font configurations for Org and others
:properties:
:custom_id: h:defcf4fc-8fa8-4c29-b12e-7119582cc929
:end:
#+cindex: Font configurations
-The themes are designed to cope well with mixed font configurations.
-
-[[#h:115e6c23-ee35-4a16-8cef-e2fcbb08e28b][Option for no font mixing]].
+The themes are designed to optionally cope well with mixed font
+configurations. This mostly concerns ~org-mode~ and ~markdown-mode~, though
+expect to find it elsewhere like in ~Info-mode~.
-This mostly concerns ~org-mode~ and ~markdown-mode~, though expect to find
-it elsewhere like in ~Info-mode~.
+[[#h:115e6c23-ee35-4a16-8cef-e2fcbb08e28b][Option for font mixing]].
In practice it means that the user can safely opt for a more
prose-friendly proportionately spaced typeface as their default, while
-letting spacing-sensitive elements like tables and inline code always
-use a monospaced font, by inheriting from the ~fixed-pitch~ face.
+spacing-sensitive elements like tables and inline code always use a
+monospaced font, by inheriting from the ~fixed-pitch~ face.
Users can try the built-in {{{kbd(M-x variable-pitch-mode)}}} to see the
effect in action.
@@ -2422,7 +2680,14 @@ reading the doc string of ~set-face-attribute~):
(set-face-attribute 'variable-pitch nil :family "DejaVu Serif" :height 1.0)
;; Monospaced typeface
-(set-face-attribute 'fixed-pitch nil :family "DejaVu Sans Mono" :height 1.0)
+(set-face-attribute 'fixed-pitch nil :family "DejaVu Sans Mono" :height 1.5)
+#+end_src
+
+Or employ the ~face-attribute~ function to read an existing value, such as
+if you want to make ~fixed-pitch~ use the font family of the ~default~ face:
+
+#+begin_src emacs-lisp
+(set-face-attribute 'fixed-pitch nil :family (face-attribute 'default :family))
#+end_src
The next section shows how to make those work in a more elaborate setup
@@ -2435,16 +2700,17 @@ specify an absolute value, which is the point size × 10. So if you want
to use a font at point size =11=, you set the height to =110=.[fn:: ~:height~
values do not need to be rounded to multiples of ten: the likes of =115=
are perfectly valid—some typefaces will change to account for those
-finer increments.] Whereas every other face must have a value that is
-relative to the default, represented as a floating point (if you use an
-integer, then that means an absolute height). This is of paramount
-importance: it ensures that all fonts can scale gracefully when using
-something like the ~text-scale-adjust~ command which only operates on the
-base font size (i.e. the ~default~ face's absolute height).
+finer increments.] Whereas every other face must either not specify a
+height or have a value that is relative to the default, represented as a
+floating point. If you use an integer, then that means an absolute
+height. This is of paramount importance: it ensures that all fonts can
+scale gracefully when using something like the ~text-scale-adjust~ command
+which only operates on the base font size (i.e. the ~default~ face's
+absolute height).
-[[#h:e6c5451f-6763-4be7-8fdb-b4706a422a4c][Note for EWW and Elfeed fonts (SHR fonts)]].
+[[#h:e6c5451f-6763-4be7-8fdb-b4706a422a4c][Note for EWW and Elfeed fonts]].
-** Configure bold and italic faces (DIY)
+** Configure bold and italic faces
:properties:
:custom_id: h:2793a224-2109-4f61-a106-721c57c01375
:end:
@@ -2476,7 +2742,7 @@ it means for a construct to be bold/italic, by tweaking the ~bold~ and
To achieve those effects, one must first be sure that the fonts they use
have support for those features. It then is a matter of following the
-instructions for all face tweaks.
+instructions for all typeface tweaks.
[[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations for Org and others]].
@@ -2504,19 +2770,20 @@ To reset the font family, one can use this:
To ensure that the effects persist after switching between the Modus
themes (such as with {{{kbd(M-x modus-themes-toggle)}}}), the user needs to
-write their configurations to a function and hook it up to the
-~modus-themes-after-load-theme-hook~. This is necessary because the
-themes set the default styles of faces (otherwise changing themes would
-not be possible).
+write their configurations to a function and pass it to the
+~modus-themes-after-load-theme-hook~. This is necessary because themes
+set the styles of faces upon activation, overriding prior values where
+conflicts occur between the previous and the current states (otherwise
+changing themes would not be possible).
[[#h:86f6906b-f090-46cc-9816-1fe8aeb38776][A theme-agnostic hook for theme loading]].
This is a minimal setup to preserve font configurations across theme
-load phases. For a more permanent setup, it is better to employ the
+load phases. For a more permanent setup, it is better to rely on the
~custom-set-faces~ function: ~set-face-attribute~ works just fine, though it
-is more convenient for quick previews or for smaller scale operations
-(~custom-set-faces~ follows the format used in the source code of the
-themes).
+probably is better suited for quick previews or for smaller scale
+operations (~custom-set-faces~ follows the format used in the source code
+of the themes, which can make it easier to redefine faces in bulk).
#+begin_src emacs-lisp
;; our generic function
@@ -2536,7 +2803,9 @@ themes).
(add-hook 'modus-themes-after-load-theme-hook #'my-modes-themes-bold-italic-faces)
#+end_src
-** Custom Org user faces (DIY)
+[[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]].
+
+** Custom Org user faces
:properties:
:custom_id: h:89f0678d-c5c3-4a57-a526-668b2bb2d7ad
:end:
@@ -2574,9 +2843,9 @@ two):
#+begin_src emacs-lisp
(setq org-todo-keyword-faces
- '(("MEET" . '(font-lock-preprocessor-face org-todo))
- ("STUDY" . '(font-lock-variable-name-face org-todo))
- ("WRITE" . '(font-lock-type-face org-todo))))
+ '(("MEET" . '(bold org-todo))
+ ("STUDY" . '(warning org-todo))
+ ("WRITE" . '(shadow org-todo))))
#+end_src
This will refashion the keywords you specify, while letting the other
@@ -2607,7 +2876,7 @@ configuration of the priority cookies:
#+begin_src emacs-lisp
(setq org-priority-faces
- '((?A . '(org-scheduled-today org-priority))
+ '((?A . '(bold org-priority))
(?B . org-priority)
(?C . '(shadow org-priority))))
#+end_src
@@ -2624,7 +2893,7 @@ it if you plan to control face attributes.
[[#h:02e25930-e71a-493d-828a-8907fc80f874][Check color combinations]].
-** Update Org block delimiter fontification (DIY)
+** Update Org block delimiter fontification
:properties:
:custom_id: h:f44cc6e3-b0f1-4a5e-8a90-9e48fa557b50
:end:
@@ -2666,7 +2935,7 @@ Run this function at the post theme load phase, such as with the
(font-lock-flush)))
#+end_src
-** Measure color contrast (DIY)
+** Measure color contrast
:properties:
:custom_id: h:02e25930-e71a-493d-828a-8907fc80f874
:end:
@@ -2700,7 +2969,7 @@ A couple of examples (rounded numbers):
;; Pure black with pure green
(modus-themes-contrast "#000000" "#00ff00")
;; => 15.3
-;; That is is a highly accessible combo
+;; That is a highly accessible combo
#+end_src
It does not matter which color value comes first. The ratio is always
@@ -2739,7 +3008,7 @@ minutia and relevant commentary.
Such knowledge may prove valuable while attempting to override some of
the themes' colors: [[#h:307d95dd-8dbd-4ece-a543-10ae86f155a6][Override colors]].
-** Load theme depending on time of day (DIY)
+** Load theme depending on time of day
:properties:
:custom_id: h:1d1ef4b4-8600-4a09-993c-6de3af0ddd26
:end:
@@ -2766,7 +3035,7 @@ package:
(circadian-setup))
#+end_src
-** Backdrop for pdf-tools (DIY)
+** Backdrop for pdf-tools
:properties:
:custom_id: h:ff69dfe1-29c0-447a-915c-b5ff7c5509cd
:end:
@@ -2828,7 +3097,102 @@ With those in place, PDFs have a distinct backdrop for their page, while
they automatically switch to their dark mode when ~modus-themes-toggle~ is
called from inside a buffer whose major-mode is ~pdf-view-mode~.
-** A theme-agnostic hook for theme loading (DIY)
+** Decrease mode line height
+:properties:
+:custom_id: h:03be4438-dae1-4961-9596-60a307c070b5
+:end:
+#+cindex: Decrease mode line height
+
+By default, the mode line of the Modus themes is set to 1 pixel width
+for its =:box= attribute. In contrast, the mode line of stock Emacs is -1
+pixel. This small difference is considered necessary for the purposes
+of accessibility as our out-of-the-box design has a prominent color
+around the mode line (a border) to make its boundaries clear. With a
+negative width the border and the text on the mode line can feel a bit
+more difficult to read under certain scenaria.
+
+Furthermore, the user option ~modus-themes-mode-line~ ([[#h:27943af6-d950-42d0-bc23-106e43f50a24][Mode line]]) does not
+allow for such a negative value because there are many edge cases that
+simply make for a counter-intuitive set of possibilities, such as a =0=
+value not being acceptable by the underlying face infrastructure, and
+negative values greater than =-2= not being particularly usable.
+
+For these reasons, users who wish to decrease the overall height of the
+mode line must handle things on their own by implementing the methods
+for face customization documented herein.
+
+[[#h:1487c631-f4fe-490d-8d58-d72ffa3bd474][Basic face customization]].
+
+One such method is to create a function that configures the desired
+faces and hook it to ~modus-themes-after-load-theme-hook~ so that it
+persists while switching between the Modus themes with the command
+~modus-themes-toggle~.
+
+This one simply disables the box altogether, which will reduce the
+height of the mode lines, but also remove their border:
+
+#+begin_src emacs-lisp
+(defun my-modus-themes-custom-faces ()
+ (set-face-attribute 'mode-line nil :box nil)
+ (set-face-attribute 'mode-line-inactive nil :box nil))
+
+(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces)
+#+end_src
+
+The above relies on the ~set-face-attribute~ function, though users who
+plan to re-use colors from the theme and do so at scale are better off
+with the more streamlined combination of the ~modus-themes-with-colors~
+macro and ~custom-set-faces~.
+
+[[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face customization at scale]].
+
+As explained before in this document, this approach has a syntax that is
+consistent with the source code of the themes, so it probably is easier
+to re-use parts of the design.
+
+The following emulates the stock Emacs style, while still using the
+colors of the Modus themes (whichever attribute is not explicitly stated
+is inherited from the underlying theme):
+
+#+begin_src emacs-lisp
+(defun my-modus-themes-custom-faces ()
+ (modus-themes-with-colors
+ (custom-set-faces
+ `(mode-line ((,class :box (:line-width -1 :style released-button))))
+ `(mode-line-inactive ((,class :box (:line-width -1 :color ,bg-region)))))))
+
+(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces)
+#+end_src
+
+And this one is like the out-of-the-box style of the Modus themes, but
+with the -1 height instead of 1:
+
+#+begin_src emacs-lisp
+(defun my-modus-themes-custom-faces ()
+ (modus-themes-with-colors
+ (custom-set-faces
+ `(mode-line ((,class :box (:line-width -1 :color ,fg-alt))))
+ `(mode-line-inactive ((,class :box (:line-width -1 :color ,bg-region)))))))
+
+(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces)
+#+end_src
+
+Finally, to also change the background color of the active mode line,
+such as that it looks like the "accented" variant which is possible via
+the user option ~modus-themes-mode-line~, the =:background= attribute needs
+to be specified as well:
+
+#+begin_src emacs-lisp
+(defun my-modus-themes-custom-faces ()
+ (modus-themes-with-colors
+ (custom-set-faces
+ `(mode-line ((,class :box (:line-width -1 :color ,fg-alt) :background ,bg-active-accent)))
+ `(mode-line-inactive ((,class :box (:line-width -1 :color ,bg-region)))))))
+
+(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces)
+#+end_src
+
+** A theme-agnostic hook for theme loading
:properties:
:custom_id: h:86f6906b-f090-46cc-9816-1fe8aeb38776
:end:
@@ -2904,6 +3268,7 @@ have lots of extensions, so the "full support" may not be 100% true…
+ alert
+ all-the-icons
+ annotate
++ ansi-color
+ anzu
+ apropos
+ apt-sources-list
@@ -2943,6 +3308,7 @@ have lots of extensions, so the "full support" may not be 100% true…
+ css-mode
+ csv-mode
+ ctrlf
++ cursor-flash
+ custom (what you get with {{{kbd(M-x customize)}}})
+ dap-mode
+ dashboard (emacs-dashboard)
@@ -2977,6 +3343,7 @@ have lots of extensions, so the "full support" may not be 100% true…
+ eldoc-box
+ elfeed
+ elfeed-score
++ elpher
+ embark
+ emms
+ enh-ruby-mode (enhanced-ruby-mode)
@@ -3033,6 +3400,7 @@ have lots of extensions, so the "full support" may not be 100% true…
+ highlight-escape-sequences (~hes-mode~)
+ highlight-indentation
+ highlight-numbers
++ highlight-parentheses ([[#h:24bab397-dcb2-421d-aa6e-ec5bd622b913][Note on highlight-parentheses.el]])
+ highlight-symbol
+ highlight-tail
+ highlight-thing
@@ -3048,6 +3416,7 @@ have lots of extensions, so the "full support" may not be 100% true…
+ ido-mode
+ iedit
+ iflipb
++ image-dired
+ imenu-list
+ indium
+ info
@@ -3089,6 +3458,7 @@ have lots of extensions, so the "full support" may not be 100% true…
+ mu4e
+ mu4e-conversation
+ multiple-cursors
++ nano-modeline
+ neotree
+ no-emoji
+ notmuch
@@ -3190,6 +3560,7 @@ have lots of extensions, so the "full support" may not be 100% true…
+ vc-annotate (the output of {{{kbd(C-x v g)}}})
+ vdiff
+ vertico
++ vertico-quick
+ vimish-fold
+ visible-mark
+ visual-regexp
@@ -3225,6 +3596,7 @@ These do not require any extra styles because they are configured to
inherit from some basic faces or their dependencies which are directly
supported by the themes.
++ bufler
+ counsel-notmuch
+ edit-indirect
+ evil-owl
@@ -3234,8 +3606,12 @@ supported by the themes.
+ perl-mode
+ php-mode
+ rjsx-mode
++ side-hustle
+ swift-mode
+ tab-bar-echo-area
++ tide
++ vertico-indexed
++ vertico-mouse
* Notes on individual packages
:properties:
@@ -3415,6 +3791,135 @@ and have the foreground be indistinguishable from it. For example:
[[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]].
+** Note on highlight-parentheses.el
+:PROPERTIES:
+:CUSTOM_ID: h:24bab397-dcb2-421d-aa6e-ec5bd622b913
+:END:
+
+The =highlight-parentheses= package provides contextual coloration of
+surrounding parentheses, highlighting only those which are around the
+point. The package expects users to customize the applicable colors on
+their own by configuring certain variables.
+
+To make the Modus themes work as expected with this, we need to use some
+of the techniques that are discussed at length in the various
+"Do-It-Yourself" (DIY) sections, which provide insight into the more
+advanced customization options of the themes.
+
+[[#h:f4651d55-8c07-46aa-b52b-bed1e53463bb][Advanced customization]].
+
+In the following example, we are assuming that the user wants to (i)
+re-use color variables provided by the themes, (ii) be able to retain
+their tweaks while switching between ~modus-operandi~ and ~modus-vivendi~,
+and (iii) have the option to highlight either the foreground of the
+parentheses or the background as well.
+
+We start by defining our own variable, which will serve as a toggle
+between foreground and background coloration styles:
+
+#+begin_src emacs-lisp
+(defvar my-highlight-parentheses-use-background t
+ "Prefer `highlight-parentheses-background-colors'.")
+#+end_src
+
+Then we can update our preference with this:
+
+#+begin_src emacs-lisp
+;; Set to nil to disable backgrounds.
+(setq my-highlight-parentheses-use-background nil)
+#+end_src
+
+To re-use colors from the themes, we must wrap our code in the
+~modus-themes-with-colors~ macro. Our implementation must interface with
+the variables ~highlight-parentheses-background-colors~ and/or
+~highlight-parentheses-colors~.
+
+So we can have something like this (the doc string of
+~modus-themes-with-colors~ explains where the names of the colors can be
+found):
+
+#+begin_src emacs-lisp
+(modus-themes-with-colors
+ ;; Our preference for setting either background or foreground
+ ;; styles, depending on `my-highlight-parentheses-use-background'.
+ (if my-highlight-parentheses-use-background
+
+ ;; Here we set color combinations that involve both a background
+ ;; and a foreground value.
+ (setq highlight-parentheses-background-colors (list cyan-refine-bg
+ magenta-refine-bg
+ green-refine-bg
+ yellow-refine-bg)
+ highlight-parentheses-colors (list cyan-refine-fg
+ magenta-refine-fg
+ green-refine-fg
+ yellow-refine-fg))
+
+ ;; And here we pass only foreground colors while disabling any
+ ;; backgrounds.
+ (setq highlight-parentheses-colors (list green-intense
+ magenta-intense
+ blue-intense
+ red-intense)
+ highlight-parentheses-background-colors nil)))
+
+;; Include this if you also want to make the parentheses bold:
+(set-face-attribute 'highlight-parentheses-highlight nil :inherit 'bold)
+
+;; Our changes must be evaluated before enabling the relevant mode, so
+;; this comes last.
+(global-highlight-parentheses-mode 1)
+#+end_src
+
+For our changes to persist while switching between the Modus themes, we
+need to include them in a function which can then get passed to
+~modus-themes-after-load-theme-hook~. This is the complete
+implementation:
+
+#+begin_src emacs-lisp
+;; Configurations for `highlight-parentheses':
+(require 'highlight-parentheses)
+
+(defvar my-highlight-parentheses-use-background t
+ "Prefer `highlight-parentheses-background-colors'.")
+
+(setq my-highlight-parentheses-use-background nil) ; Set to nil to disable backgrounds
+
+(defun my-modus-themes-highlight-parentheses ()
+ (modus-themes-with-colors
+ ;; Our preference for setting either background or foreground
+ ;; styles, depending on `my-highlight-parentheses-use-background'.
+ (if my-highlight-parentheses-use-background
+
+ ;; Here we set color combinations that involve both a background
+ ;; and a foreground value.
+ (setq highlight-parentheses-background-colors (list cyan-refine-bg
+ magenta-refine-bg
+ green-refine-bg
+ yellow-refine-bg)
+ highlight-parentheses-colors (list cyan-refine-fg
+ magenta-refine-fg
+ green-refine-fg
+ yellow-refine-fg))
+
+ ;; And here we pass only foreground colors while disabling any
+ ;; backgrounds.
+ (setq highlight-parentheses-colors (list green-intense
+ magenta-intense
+ blue-intense
+ red-intense)
+ highlight-parentheses-background-colors nil)))
+
+ ;; Include this if you also want to make the parentheses bold:
+ (set-face-attribute 'highlight-parentheses-highlight nil :inherit 'bold)
+
+ ;; Our changes must be evaluated before enabling the relevant mode, so
+ ;; this comes last.
+ (global-highlight-parentheses-mode 1))
+
+(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-highlight-parentheses)
+#+end_src
+
** Note on mmm-mode.el background colors
:properties:
:custom_id: h:99cf0d6c-e478-4e26-9932-3bf3427d13f6
@@ -3520,7 +4025,7 @@ With 8 colors:
:desaturations '(0) ; do not change---may lower the contrast ratio
:lightens '(0) ; same
:colors (modus-themes-with-colors
- (list fg-special-cold
+ (list blue
magenta
magenta-alt-other
cyan-alt-other
@@ -3540,10 +4045,10 @@ to the themes' default aesthetic:
:desaturations '(0) ; do not change---may lower the contrast ratio
:lightens '(0) ; same
:colors (modus-themes-with-colors
- (list fg-main
- cyan-alt-other
+ (list blue
+ magenta
magenta-alt-other
- magenta)))
+ green-alt)))
#+end_src
If you need to apply desaturation and lightening, you can use what the
@@ -3567,12 +4072,12 @@ examples with the 4, 8, 16 colors):
:custom_id: h:4da1d515-3e05-47ef-9e45-8251fc7e986a
:end:
-The ~god-mode~ library does not provide faces that could be configured by
-the Modus themes. Users who would like to get some visual feedback on
-the status of {{{kbd(M-x god-mode)}}} are instead encouraged by upstream to
-set up their own configurations, such as by changing the ~mode-line~ face
-([[#h:f4651d55-8c07-46aa-b52b-bed1e53463bb][Advanced customization (do-it-yourself)]]). This is an adaptation of the
-approach followed in the upstream README:
+The ~god-mode~ library does not provide faces that could be configured
+by the Modus themes. Users who would like to get some visual feedback
+on the status of {{{kbd(M-x god-mode)}}} are instead encouraged by upstream
+to set up their own configurations, such as by changing the ~mode-line~
+face ([[#h:f4651d55-8c07-46aa-b52b-bed1e53463bb][Advanced customization]]). This is an adaptation of the approach
+followed in the upstream README:
#+begin_src emacs-lisp
(defun my-god-mode-update-mode-line ()
@@ -3666,7 +4171,7 @@ specifications the webpage provides.
Consult {{{kbd(C-h v shr-use-colors)}}}.
-** Note on EWW and Elfeed fonts (SHR fonts)
+** Note on EWW and Elfeed fonts
:properties:
:custom_id: h:e6c5451f-6763-4be7-8fdb-b4706a422a4c
:end:
@@ -3780,7 +4285,7 @@ you've customized any faces.
"-draw" "text %X,%Y '%c'"))))
#+end_src
-* Frequently Asked Questions (FAQ)
+* Frequently Asked Questions
:properties:
:custom_id: h:b3384767-30d3-4484-ba7f-081729f03a47
:end:
@@ -3958,7 +4463,7 @@ latter case.
~modus-operandi~ is best used outdoors or in a room that either gets
direct sunlight or has plenty of light. Whereas ~modus-vivendi~ works
better when there is not a lot of sunshine or the room has a source of
-light, preferably a faint or warm one. It is possible to use
+light that is preferably a faint and/or warm one. It is possible to use
~modus-operandi~ at night and ~modus-vivendi~ during the day, though that
will depend on several variables, such as one's overall perception of
color, the paint on the walls and how that contributes to the impression
@@ -4005,15 +4510,13 @@ in which you can contribute to their ongoing development.
:end:
#+cindex: Sources of the themes
-The ~modus-operandi~ and ~modus-vivendi~ themes are built into Emacs.
-Currently they are in Emacs' git main branch (trunk), which is tracking
-the next development release target.
+The ~modus-operandi~ and ~modus-vivendi~ themes are built into Emacs 28.
The source code of the themes is [[https://gitlab.com/protesilaos/modus-themes/][available on Gitlab]], for the time
being. A [[https://github.com/protesilaos/modus-themes/][mirror on Github]] is also on offer.
An HTML version of this manual is provided as an extension of the
-[[https://protesilaos.com/modus-themes/][author's personal website]] (does not rely on any non-free code).
+[[https://protesilaos.com/emacs/modus-themes/][author's personal website]] (does not rely on any non-free code).
** Issues you can help with
:properties:
@@ -4117,21 +4620,22 @@ The Modus themes are a collective effort. Every bit of work matters.
+ Author/maintainer :: Protesilaos Stavrou.
+ Contributions to code or documentation :: Anders Johansson, Basil
- L.{{{space()}}} Contovounesios, Carlo Zancanaro, Eli Zaretskii, Fritz Grabo,
- Kostadin Ninev, Madhavan Krishnan, Markus Beppler, Matthew Stevenson,
- Mauro Aranda, Nicolas De Jaeghere, Philip Kaludercic, Rudolf
- Adamkovič, Shreyas Ragavan, Stefan Kangas, Vincent Murphy, Xinglu
- Chen.
-
-+ Ideas and user feedback :: Aaron Jensen, Adam Spiers, Adrian Manea,
- Alex Griffin, Alex Peitsinis, Alexey Shmalko, Alok Singh, Anders
- Johansson, André Alexandre Gomes, Arif Rezai, Basil L.{{{space()}}}
- Contovounesios, Burgess Chang, Christian Tietze, Christopher Dimech,
- Damien Cassou, Daniel Mendler, Dario Gjorgjevski, David Edmondson,
- Davor Rotim, Divan Santana, Emanuele Michele Alberto Monterosso,
- Farasha Euker, Gautier Ponsinet, Gerry Agbobada, Gianluca Recchia,
- Gustavo Barros, Hörmetjan Yiltiz, Ilja Kocken, Iris Garcia, Jeremy
- Friesen, Jerry Zhang, John Haman, Joshua O'Connor, Kevin Fleming,
+ L.{{{space()}}} Contovounesios, Carlo Zancanaro, Christian Tietze, Daniel
+ Mendler, Eli Zaretskii, Fritz Grabo, Kévin Le Gouguec, Kostadin Ninev,
+ Madhavan Krishnan, Markus Beppler, Matthew Stevenson, Mauro Aranda,
+ Nicolas De Jaeghere, Philip Kaludercic, Rudolf Adamkovič, Stephen
+ Gildea, Shreyas Ragavan, Stefan Kangas, Vincent Murphy, Xinglu Chen.
+
++ Ideas and user feedback :: Aaron Jensen, Adam Porter, Adam Spiers,
+ Adrian Manea, Alex Griffin, Alex Peitsinis, Alexey Shmalko, Alok
+ Singh, Anders Johansson, André Alexandre Gomes, Arif Rezai, Basil
+ L.{{{space()}}} Contovounesios, Burgess Chang, Christian Tietze, Christopher
+ Dimech, 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, Guilherme Semente, Gustavo Barros,
+ Hörmetjan Yiltiz, Ilja Kocken, Iris Garcia, Jeremy Friesen, Jerry
+ Zhang, Johannes Grødem, John Haman, Joshua O'Connor, Kevin Fleming,
Kévin Le Gouguec, Kostadin Ninev, Len Trigg, Manuel Uberti, Mark
Burton, Markus Beppler, Mauro Aranda, Michael Goldenberg, Morgan
Smith, Murilo Pereira, Nicky van Foreest, Nicolas De Jaeghere, Paul
@@ -4152,9 +4656,10 @@ The Modus themes are a collective effort. Every bit of work matters.
+ Inspiration for certain features :: Bozhidar Batsov (zenburn-theme),
Fabrice Niessen (leuven-theme).
-Special thanks, in no particular order, to Manuel Uberti, Gustavo
-Barros, and Omar Antolín Camarena for their long time contributions and
-insightful commentary.
+Special thanks (from A-Z) to Gustavo Barros, Manuel Uberti, Nicolas De
+Jaeghere, and Omar Antolín Camarena for their long time contributions
+and insightful commentary on key aspects of the themes' design and/or
+aspects of their functionality.
* Meta
:properties:
@@ -4178,12 +4683,13 @@ of this sort):
+ [[https://protesilaos.com/codelog/2020-12-27-modus-themes-review-rainbow-delimiters/][Modus themes: review rainbow-delimiters faces]] (2020-12-27)
+ [[https://protesilaos.com/codelog/2021-01-11-modus-themes-review-select-faint-colours/][Modus themes: review of select "faint" colours]] (2021-01-11)
+ [[https://protesilaos.com/codelog/2021-02-25-modus-themes-diffs-deuteranopia/][The Modus themes now cover deuteranopia in diffs]] (2021-02-25)
++ [[https://protesilaos.com/codelog/2021-06-02-modus-themes-org-agenda/][Introducing the variable modus-themes-org-agenda]] (2021-06-02)
And here are the canonical sources of this project's documentation:
-+ Manual :: <https://protesilaos.com/modus-themes>
-+ Change Log :: <https://protesilaos.com/modus-themes-changelog>
-+ Screenshots :: <https://protesilaos.com/modus-themes-pictures>
++ Manual :: <https://protesilaos.com/emacs/modus-themes>
++ Change Log :: <https://protesilaos.com/emacs/modus-themes-changelog>
++ Screenshots :: <https://protesilaos.com/emacs/modus-themes-pictures>
* GNU Free Documentation License
:properties:
diff --git a/doc/misc/org.org b/doc/misc/org.org
index f072b5e00e0..adf24da1c3f 100644
--- a/doc/misc/org.org
+++ b/doc/misc/org.org
@@ -82,11 +82,8 @@ probably do not need to install it. Most users will simply activate
Org and begin exploring its many features.
If, for one reason or another, you want to install Org on top of this
-pre-packaged version, there are three ways to do it:
-
-- by using the Emacs package system;
-- by downloading Org as an archive; or
-- by using Org's git repository.
+pre-packaged version, you can use the Emacs package system or clone
+Org's git repository.
We *strongly recommend* sticking to a single installation method.
@@ -106,32 +103,6 @@ visited, i.e., where no Org built-in function have been loaded.
Otherwise autoload Org functions will mess up the installation.
#+end_quote
-If you want to use Org's package repository, check out the [[https://orgmode.org/elpa.html][Org ELPA
-page]].
-
-*** Downloading Org as an archive
-:PROPERTIES:
-:UNNUMBERED: notoc
-:END:
-
-You can download Org latest release from [[https://orgmode.org/][Org's website]]. In this case,
-make sure you set the load path correctly in your Emacs init file:
-
-#+begin_src emacs-lisp
-(add-to-list 'load-path "~/path/to/orgdir/lisp")
-#+end_src
-
-The downloaded archive contains contributed libraries that are not
-included in Emacs. If you want to use them, add the =contrib/=
-directory to your load path:
-
-#+begin_src emacs-lisp
-(add-to-list 'load-path "~/path/to/orgdir/contrib/lisp" t)
-#+end_src
-
-Optionally, you can compile the files and/or install them in your
-system. Run =make help= to list compilation and installation options.
-
*** Using Org's git repository
:PROPERTIES:
:UNNUMBERED: notoc
@@ -141,7 +112,7 @@ You can clone Org's repository and install Org like this:
#+begin_example
$ cd ~/src/
-$ git clone https://code.orgmode.org/bzg/org-mode.git
+$ git clone https://git.savannah.gnu.org/git/emacs/org-mode.git
$ cd org-mode/
$ make autoloads
#+end_example
@@ -161,6 +132,16 @@ list of compilation/installation options.
For more detailed explanations on Org's build system, please check the
Org Build System page on [[https://orgmode.org/worg/dev/org-build-system.html][Worg]].
+*** Installing Org's contributed packages
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+Org's repository used to contain =contrib/= directory for add-ons
+contributed by others. As of Org 9.5, the directory has bee moved to
+this new dedicated [[https://git.sr.ht/~bzg/org-contrib][org-contrib]] repository, which you can install
+separately.
+
** Activation
:PROPERTIES:
:DESCRIPTION: How to activate Org for certain buffers.
@@ -189,9 +170,9 @@ to globally available keys, like the ones reserved for users (see
please modify the keys to your own liking.
#+begin_src emacs-lisp
-(global-set-key (kbd "C-c l") 'org-store-link)
-(global-set-key (kbd "C-c a") 'org-agenda)
-(global-set-key (kbd "C-c c") 'org-capture)
+(global-set-key (kbd "C-c l") #'org-store-link)
+(global-set-key (kbd "C-c a") #'org-agenda)
+(global-set-key (kbd "C-c c") #'org-capture)
#+end_src
#+cindex: Org mode, turning on
@@ -273,7 +254,6 @@ shown below.
;; Add latest Org mode to load path.
(add-to-list 'load-path (expand-file-name "/path/to/org-mode/lisp"))
-(add-to-list 'load-path (expand-file-name "/path/to/org-mode/contrib/lisp" t))
#+end_src
If an error occurs, a "backtrace" can be very useful---see below on
@@ -344,7 +324,7 @@ conventions:
- =boss=, =ARCHIVE= ::
- Tags are case-sensitive. User-defined tags are written in
+ Tags are case-sensitive. User-defined tags are usually written in
lowercase; built-in tags with special meaning are written as they
should appear in the document, usually with all capitals.
@@ -577,6 +557,10 @@ buffer:
,#+STARTUP: overview
,#+STARTUP: content
,#+STARTUP: showall
+,#+STARTUP: show2levels
+,#+STARTUP: show3levels
+,#+STARTUP: show4levels
+,#+STARTUP: show5levels
,#+STARTUP: showeverything
#+end_example
@@ -656,10 +640,10 @@ The following commands jump to other headlines in the buffer.
where you can use the following keys to find your destination:
#+attr_texinfo: :columns 0.3 0.7
- | {{{kbd(TAB)}}} | Cycle visibility. |
+ | {{{kbd(TAB)}}} | Cycle visibility. |
| {{{kbd(DOWN)}}} / {{{kbd(UP)}}} | Next/previous visible headline. |
- | {{{kbd(RET)}}} | Select this location. |
- | {{{kbd(/)}}} | Do a Sparse-tree search |
+ | {{{kbd(RET)}}} | Select this location. |
+ | {{{kbd(/)}}} | Do a Sparse-tree search |
#+texinfo: @noindent
The following keys work if you turn off ~org-goto-auto-isearch~
@@ -667,9 +651,9 @@ The following commands jump to other headlines in the buffer.
#+attr_texinfo: :columns 0.3 0.7
| {{{kbd(n)}}} / {{{kbd(p)}}} | Next/previous visible headline. |
| {{{kbd(f)}}} / {{{kbd(b)}}} | Next/previous headline same level. |
- | {{{kbd(u)}}} | One level up. |
+ | {{{kbd(u)}}} | One level up. |
| {{{kbd(0)}}} ... {{{kbd(9)}}} | Digit argument. |
- | {{{kbd(q)}}} | Quit. |
+ | {{{kbd(q)}}} | Quit. |
#+vindex: org-goto-interface
#+texinfo: @noindent
@@ -932,16 +916,16 @@ commands can be accessed through a dispatcher:
#+kindex: C-c / /
#+findex: org-occur
#+vindex: org-remove-highlights-with-change
- Prompts for a regexp and shows a sparse tree with all matches. If
- the match is in a headline, the headline is made visible. If the
- match is in the body of an entry, headline and body are made
- visible. In order to provide minimal context, also the full
- hierarchy of headlines above the match is shown, as well as the
- headline following the match. Each match is also highlighted; the
- highlights disappear when the buffer is changed by an editing
- command, or by pressing {{{kbd(C-c C-c)}}}[fn:8]. When called with
- a {{{kbd(C-u)}}} prefix argument, previous highlights are kept, so
- several calls to this command can be stacked.
+ Prompts for a regexp (see [[*Regular Expressions]]) and shows a sparse
+ tree with all matches. If the match is in a headline, the headline
+ is made visible. If the match is in the body of an entry, headline
+ and body are made visible. In order to provide minimal context,
+ also the full hierarchy of headlines above the match is shown, as
+ well as the headline following the match. Each match is also
+ highlighted; the highlights disappear when the buffer is changed by
+ an editing command, or by pressing {{{kbd(C-c C-c)}}}[fn:8]. When
+ called with a {{{kbd(C-u)}}} prefix argument, previous highlights
+ are kept, so several calls to this command can be stacked.
- {{{kbd(M-g n)}}} or {{{kbd(M-g M-n)}}} (~next-error~) ::
@@ -1371,9 +1355,8 @@ you, configure the option ~org-table-auto-blank-field~.
Re-align the table, move to the next field. Creates a new row if
necessary.
-- {{{kbd(C-c SPC)}}} (~org-table-blank-field~) ::
+- {{{kbd(M-x org-table-blank-field)}}} ::
- #+kindex: C-c SPC
#+findex: org-table-blank-field
Blank the field at point.
@@ -1805,7 +1788,7 @@ mode with {{{kbd(M-x orgtbl-mode)}}}. To turn it on by default, for
example in Message mode, use
#+begin_src emacs-lisp
-(add-hook 'message-mode-hook 'turn-on-orgtbl)
+(add-hook 'message-mode-hook #'turn-on-orgtbl)
#+end_src
Furthermore, with some special setup, it is possible to maintain
@@ -2074,6 +2057,14 @@ variable ~org-calc-default-modes~.
Fraction and symbolic modes of Calc.
+- =u= ::
+
+ Units simplification mode of Calc. Calc is also a symbolic
+ calculator and is capable of working with values having a unit,
+ represented with numerals followed by a unit string in Org table
+ cells. This mode instructs Calc to simplify the units in the
+ computed expression before returning the result.
+
- =T=, =t=, =U= ::
Duration computations in Calc or Lisp, [[*Durations and time values]].
@@ -2169,38 +2160,54 @@ It is also possible to write a formula in Emacs Lisp. This can be
useful for string manipulation and control structures, if Calc's
functionality is not enough.
-If a formula starts with a single-quote followed by an opening
-parenthesis, then it is evaluated as a Lisp form. The evaluation
-should return either a string or a number. Just as with Calc
-formulas, you can specify modes and a ~printf~ format after
-a semicolon.
+A formula is evaluated as a Lisp form when it starts with a
+single-quote followed by an opening parenthesis. Cell table
+references are interpolated into the Lisp form before execution. The
+evaluation should return either a string or a number. Evaluation
+modes and a ~printf~ format used to render the returned values can be
+specified after a semicolon.
-With Emacs Lisp forms, you need to be conscious about the way field
-references are interpolated into the form. By default, a reference is
-interpolated as a Lisp string (in double-quotes) containing the field.
-If you provide the =N= mode switch, all referenced elements are
-numbers---non-number fields will be zero---and interpolated as Lisp
-numbers, without quotes. If you provide the =L= flag, all fields are
-interpolated literally, without quotes. For example, if you want a
-reference to be interpreted as a string by the Lisp form, enclose the
-reference operator itself in double-quotes, like ="$3"=. Ranges are
-inserted as space-separated fields, so you can embed them in list or
-vector syntax.
+By default, references are interpolated as literal Lisp strings: the
+field content is replaced in the Lisp form stripped of leading and
+trailing white space and surrounded in double-quotes. For example:
-Here are a few examples---note how the =N= mode is used when we do
-computations in Lisp:
+: '(concat $1 $2)
-- ='(concat (substring $1 1 2) (substring $1 0 1) (substring $1 2))= ::
+#+texinfo: @noindent
+concatenates the content of columns 1 and column 2.
+
+When the =N= flag is used, all referenced elements are parsed as
+numbers and interpolated as Lisp numbers, without quotes. Fields that
+cannot be parsed as numbers are interpolated as zeros. For example:
- Swap the first two characters of the content of column 1.
+: '(+ $1 $2);N
-- ='(+ $1 $2);N= ::
+#+texinfo: @noindent
+adds columns 1 and 2, equivalent to Calc's =$1+$2=. Ranges are
+inserted as space-separated fields, so they can be embedded in list or
+vector syntax. For example:
- Add columns 1 and 2, equivalent to Calc's =$1+$2=.
+: '(apply '+ '($1..$4));N
-- ='(apply '+ '($1..$4));N= ::
+#+texinfo: @noindent
+computes the sum of columns 1 to 4, like Calc's =vsum($1..$4)=.
+
+When the =L= flag is used, all fields are interpolated literally: the
+cell content is replaced in the Lisp form stripped of leading and
+trailing white space and without quotes. If a reference is intended
+to be interpreted as a string by the Lisp form, the reference operator
+itself should be enclosed in double-quotes, like ="$3"=. The =L= flag
+is useful when strings and numbers are used in the same Lisp form. For
+example:
- Compute the sum of columns 1 to 4, like Calc's =vsum($1..$4)=.
+: '(substring "$1" $2 $3);L
+
+#+texinfo: @noindent
+extracts the part of the string in column 1 between the character
+positions specified in the integers in column 2 and 3 and it is easier
+to read than the equivalent:
+
+: '(substring $1 (string-to-number $2) (string-to-number $3))
*** Durations and time values
:PROPERTIES:
@@ -2797,7 +2804,7 @@ either graphically or in ASCII art.
#+cindex: @samp{PLOT}, keyword
Org Plot can produce 2D and 3D graphs of information stored in Org
-tables using [[http://www.gnuplot.info/][Gnuplot]] and [[http://cars9.uchicago.edu/~ravel/software/gnuplot-mode.html][Gnuplot mode]]. To see this in action, ensure
+tables using [[https://www.gnuplot.info/][Gnuplot]] and [[http://cars9.uchicago.edu/~ravel/software/gnuplot-mode.html][Gnuplot mode]]. To see this in action, ensure
that you have both Gnuplot and Gnuplot mode installed on your system,
then call {{{kbd(C-c \quot g)}}} or {{{kbd(M-x org-plot/gnuplot)}}} on the
following table.
@@ -2813,6 +2820,19 @@ following table.
| Morelia | 257.56 | 17.67 |
#+end_example
+Org Plot supports a range of plot types, and provides the ability to add more.
+For example, a radar plot can be generated like so:
+#+begin_example
+,#+PLOT: title:"An evaluation of plaintext document formats" transpose:yes type:radar min:0 max:4
+| Format | Fine-grained-control | Initial Effort | Syntax simplicity | Editor Support | Integrations | Ease-of-referencing | Versatility |
+|-------------------+----------------------+----------------+-------------------+----------------+--------------+---------------------+-------------|
+| Word | 2 | 4 | 4 | 2 | 3 | 2 | 2 |
+| LaTeX | 4 | 1 | 1 | 3 | 2 | 4 | 3 |
+| Org Mode | 4 | 2 | 3.5 | 1 | 4 | 4 | 4 |
+| Markdown | 1 | 3 | 3 | 4 | 3 | 3 | 1 |
+| Markdown + Pandoc | 2.5 | 2.5 | 2.5 | 3 | 3 | 3 | 2 |
+#+end_example
+
Notice that Org Plot is smart enough to apply the table's headers as
labels. Further control over the labels, type, content, and
appearance of plots can be exercised through the =PLOT= keyword
@@ -2843,9 +2863,15 @@ For more information and examples see the [[https://orgmode.org/worg/org-tutoria
the third and fourth columns. Defaults to graphing all other
columns aside from the =ind= column.
+- transpose ::
+
+ When =y=, =yes=, or =t= attempt to transpose the table data before
+ plotting. Also recognises the shorthand option =trans=.
+
- =type= ::
- Specify whether the plot is =2d=, =3d=, or =grid=.
+ Specify the type of the plot, by default one of =2d=, =3d=, =radar=, or =grid=.
+ Available types can be customised with ~org-plot/preset-plot-types~.
- =with= ::
@@ -2872,6 +2898,27 @@ For more information and examples see the [[https://orgmode.org/worg/org-tutoria
When plotting =3d= or =grid= types, set this to =t= to graph a flat
mapping rather than a =3d= slope.
+- min ::
+
+ Provides a minimum axis value that may be used by a plot type.
+ Implicitly assumes the =y= axis is being referred to. Can
+ explicitly provide a value for a either the =x= or =y= axis with
+ =xmin= and =ymin=.
+
+- max ::
+
+ Provides a maximum axis value that may be used by a plot type.
+ Implicitly assumes the =y= axis is being referred to. Can
+ explicitly provide a value for a either the =x= or =y= axis with
+ =xmax= and =ymax=.
+
+- ticks ::
+
+ Provides a desired number of axis ticks to display, that may be used
+ by a plot type. If none is given a plot type that requires ticks
+ will use ~org--plot/sensible-tick-num~ to try to determine a good
+ value.
+
- =timefmt= ::
Specify format of Org mode timestamps as they will be parsed by
@@ -3113,14 +3160,14 @@ Here is the full set of built-in link types:
- =file= ::
- File links. File name may be remote, absolute, or relative.
+ File links. File name may be remote, absolute, or relative.
- Additionally, you can specify a line number, or a text search.
- In Org files, you may link to a headline name, a custom ID, or a
- code reference instead.
+ Additionally, you can specify a line number, or a text search.
+ In Org files, you may link to a headline name, a custom ID, or a
+ code reference instead.
- As a special case, "file" prefix may be omitted if the file name
- is complete, e.g., it starts with =./=, or =/=.
+ As a special case, "file" prefix may be omitted if the file name
+ is complete, e.g., it starts with =./=, or =/=.
- =attachment= ::
@@ -3224,9 +3271,10 @@ options:
#+cindex: VM links
#+cindex: Wanderlust links
On top of these built-in link types, additional ones are available
-through the =contrib/= directory (see [[*Installation]]). For example,
-these links to VM or Wanderlust messages are available when you load
-the corresponding libraries from the =contrib/= directory:
+through the =org-contrib= repository (see [[*Installation]]). For
+example, these links to VM or Wanderlust messages are available when
+you load the corresponding libraries from the =org-contrib=
+repository:
| =vm:folder= | VM folder link |
| =vm:folder#id= | VM message link |
@@ -3291,8 +3339,9 @@ current buffer:
=ID= property for the link[fn:29]. So using this command in Org
buffers potentially creates two links: a human-readable link from
the custom ID, and one that is globally unique and works even if the
- entry is moved from file to file. Later, when inserting the link,
- you need to decide which one to use.
+ entry is moved from file to file. The =ID= property can be either a
+ UUID (default) or a timestamp, depending on ~org-id-method~. Later,
+ when inserting the link, you need to decide which one to use.
- /Email/News clients: VM, Rmail, Wanderlust, MH-E, Gnus/ ::
@@ -3474,8 +3523,8 @@ generally, act on links.
#+begin_src emacs-lisp
(with-eval-after-load 'org
- (define-key org-mode-map (kbd "M-n") 'org-next-link)
- (define-key org-mode-map (kbd "M-p") 'org-previous-link))
+ (define-key org-mode-map (kbd "M-n") #'org-next-link)
+ (define-key org-mode-map (kbd "M-p") #'org-previous-link))
#+end_src
** Using Links Outside Org
@@ -3516,7 +3565,7 @@ replacement text. Here is an example:
#+begin_src emacs-lisp
(setq org-link-abbrev-alist
'(("bugzilla" . "http://10.1.2.9/bugzilla/show_bug.cgi?id=")
- ("Nu Html Checker" . "https://validator.w3.org/nu/?doc=%h")
+ ("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")
("ads" . "https://ui.adsabs.harvard.edu/search/q=%20author%3A\"%s\"")))
@@ -3616,10 +3665,10 @@ link, together with explanations for each:
- =/REGEXP/= ::
- Do a regular expression search for {{{var(REGEXP)}}}. This uses the
- Emacs command ~occur~ to list all matches in a separate window. If
- the target file is in Org mode, ~org-occur~ is used to create
- a sparse tree with the matches.
+ Do a regular expression search for {{{var(REGEXP)}}} (see [[*Regular
+ Expressions]]). This uses the Emacs command ~occur~ to list all
+ matches in a separate window. If the target file is in Org mode,
+ ~org-occur~ is used to create a sparse tree with the matches.
As a degenerate case, a file link with an empty file name can be used
to search the current file. For example, =[[file:::find me]]= does
@@ -3944,9 +3993,9 @@ interpretation, but it means the same as =#+TODO=, or
A setup for using several sets in parallel would be:
#+begin_example
-,#+TODO: TODO | DONE
-,#+TODO: REPORT BUG KNOWNCAUSE | FIXED
-,#+TODO: | CANCELED
+,#+TODO: TODO(t) | DONE(d)
+,#+TODO: REPORT(r) BUG(b) KNOWNCAUSE(k) | FIXED(f)
+,#+TODO: | CANCELED(c)
#+end_example
#+cindex: completion, of option keywords
@@ -4070,7 +4119,7 @@ checkboxes is blocked from switching to DONE.
If you need more complex dependency structures, for example
dependencies between entries in different trees or files, check out
-the contributed module =org-depend.el=.
+the module =org-depend.el= in the =org-contrib= repository.
** Progress Logging
:PROPERTIES:
@@ -4158,10 +4207,6 @@ example, with the setting
'((sequence "TODO(t)" "WAIT(w@/!)" "|" "DONE(d!)" "CANCELED(c@)")))
#+end_src
-#+texinfo: @noindent
-To record a timestamp without a note for TODO keywords configured with
-=@=, just type {{{kbd(C-c C-c)}}} to enter a blank note when prompted.
-
#+vindex: org-log-done
You not only define global TODO keywords and fast access keys, but
also request that a time is recorded when the entry is set to =DONE=,
@@ -4181,6 +4226,9 @@ to a buffer:
: #+TODO: TODO(t) WAIT(w@/!) | DONE(d!) CANCELED(c@)
+To record a timestamp without a note for TODO keywords configured with
+=@=, just type {{{kbd(C-c C-c)}}} to enter a blank note when prompted.
+
#+cindex: @samp{LOGGING}, property
In order to define logging settings that are local to a subtree or
a single item, define a =LOGGING= property in this entry. Any
@@ -4443,7 +4491,7 @@ all children are done, you can use the following setup:
(let (org-log-done org-log-states) ; turn off logging
(org-todo (if (= n-not-done 0) "DONE" "TODO"))))
-(add-hook 'org-after-todo-statistics-hook 'org-summary-todo)
+(add-hook 'org-after-todo-statistics-hook #'org-summary-todo)
#+end_src
Another possibility is the use of checkboxes to identify (a hierarchy
@@ -4794,9 +4842,10 @@ In this interface, you can also use the following special keys:
#+kindex: TAB
Enter a tag in the minibuffer, even if the tag is not in the
- predefined list. You can complete on all tags present in the
- buffer. You can also add several tags: just separate them with
- a comma.
+ predefined list. You can complete on all tags present in the buffer
+ and globally pre-defined tags from ~org-tag-alist~ and
+ ~org-tag-persistent-alist~. You can also add several tags: just
+ separate them with a comma.
- {{{kbd(SPC)}}} ::
@@ -4931,8 +4980,9 @@ mutually exclusive.
Furthermore, the members of a group tag can also be regular
expressions, creating the possibility of a more dynamic and rule-based
-tag structure. The regular expressions in the group must be specified
-within curly brackets. Here is an expanded example:
+tag structure (see [[*Regular Expressions]]). The regular expressions in
+the group must be specified within curly brackets. Here is an
+expanded example:
#+begin_example
,#+TAGS: [ Vision : {V@.+} ]
@@ -5274,7 +5324,7 @@ single property:
tree is created with all entries that define this property with the
given value. If you enclose the value in curly braces, it is
interpreted as a regular expression and matched against the property
- values.
+ values (see [[*Regular Expressions]]).
** Property Inheritance
:PROPERTIES:
@@ -5737,8 +5787,8 @@ block. If there is a =TBLFM= keyword after the table, the table is
recalculated automatically after an update.
An alternative way to capture and process property values into a table
-is provided by Eric Schulte's =org-collector.el=, which is
-a contributed package[fn:58]. It provides a general API to collect
+is provided by Eric Schulte's =org-collector.el=, which is a package
+in =org-contrib=[fn:58]. It provides a general API to collect
properties from entries in a certain scope, and arbitrary Lisp
expressions to process these values before inserting them into a table
or a dynamic block.
@@ -6022,6 +6072,7 @@ dash(es) as the separator in the former case and use =+= as the
separator in the latter case, e.g.:
| =11am-1:15pm= | \rArr{} 11:00-13:15 |
+| =11h-13h15= | \rArr{} same as above |
| =11am--1:15pm= | \rArr{} same as above |
| =11am+2:15= | \rArr{} same as above |
@@ -7197,6 +7248,16 @@ special command:
Copying works like refiling, except that the original note is not
deleted.
+- {{{kbd(C-c C-M-w)}}} (~org-refile-reverse~) ::
+
+ #+kindex: C-c C-M-w
+ #+findex: org-refile-reverse
+ Works like refiling, except that it temporarily toggles how the
+ value of ~org-reverse-note-order~ applies to the current buffer. So
+ if ~org-refile~ would append the entry as the last entry under the
+ target header, ~org-refile-reverse~ will prepend it as the first
+ entry, and vice-versa.
+
** Archiving
:PROPERTIES:
:DESCRIPTION: What to do with finished products.
@@ -7746,6 +7807,9 @@ Now lets look at the elements of a template definition. Each entry in
Do not save the target file after finishing the capture.
+ - ~:refile-targets :: Temporarily set ~org-refile-targets~ to the
+ value of this property.
+
**** Template expansion
:PROPERTIES:
:DESCRIPTION: Filling in information about time and context.
@@ -7804,6 +7868,10 @@ here:
Like =%a=, but only insert the literal link.
+- =%L= ::
+
+ Like =%l=, but without brackets (the link content itself).
+
- =%c= ::
Current kill ring head.
@@ -7859,7 +7927,8 @@ here:
- =%^{PROP}p= ::
- Prompt the user for a value for property {{{var(PROP)}}}.
+ Prompt the user for a value for property {{{var(PROP)}}}. You may
+ specify a default value with =%^{PROP|default}=.
- =%^{PROMPT}= ::
@@ -7912,7 +7981,7 @@ patches. Then you would configure this option like this:
#+begin_src emacs-lisp
(setq org-capture-templates-contexts
- '(("p" (in-mode . "message-mode"))))
+ '(("p" ((in-mode . "message-mode")))))
#+end_src
You can also tell that the command key {{{kbd(p)}}} should refer to
@@ -7920,7 +7989,7 @@ another template. In that case, add this command key like this:
#+begin_src emacs-lisp
(setq org-capture-templates-contexts
- '(("p" "q" (in-mode . "message-mode"))))
+ '(("p" "q" ((in-mode . "message-mode")))))
#+end_src
See the docstring of the variable for more information.
@@ -8199,7 +8268,7 @@ To make Org mode take care of versioning of attachments for you, add
the following to your Emacs config:
#+begin_src emacs-lisp
- (require 'org-attach-git)
+(require 'org-attach-git)
#+end_src
*** Attach from Dired
@@ -8259,7 +8328,7 @@ variable has detailed information. With the following
#+begin_src emacs-lisp
(setq org-feed-alist
'(("Slashdot"
- "http://rss.slashdot.org/Slashdot/slashdot"
+ "https://rss.slashdot.org/Slashdot/slashdot"
"~/txt/org/feeds.org" "Slashdot Entries")))
#+end_src
@@ -8847,8 +8916,9 @@ only tags.
#+cindex: regular expressions, with tags search
Instead of a tag, you may also specify a regular expression enclosed
-in curly braces. For example, =work+{^boss.*}= matches headlines that
-contain the tag =:work:= and any tag /starting/ with =boss=.
+in curly braces (see [[*Regular Expressions]]). For example,
+=work+{^boss.*}= matches headlines that contain the tag =:work:= and
+any tag /starting/ with =boss=.
#+cindex: group tags, as regular expressions
Group tags (see [[*Tag Hierarchy]]) are expanded as regular expressions.
@@ -8888,7 +8958,7 @@ to test the value of a property. Here is a complex example:
#+begin_example
+work-boss+PRIORITY="A"+Coffee="unlimited"+Effort<2
- +With={Sarah|Denny}+SCHEDULED>="<2008-10-11>"
+ +With={Sarah\|Denny}+SCHEDULED>="<2008-10-11>"
#+end_example
#+texinfo: @noindent
@@ -8918,7 +8988,7 @@ So the search string in the example finds entries tagged =work= but
not =boss=, which also have a priority value =A=, a =Coffee= property
with the value =unlimited=, an =EFFORT= property that is numerically
smaller than 2, a =With= property that is matched by the regular
-expression =Sarah|Denny=, and that are scheduled on or after October
+expression =Sarah\|Denny=, and that are scheduled on or after October
11, 2008.
You can configure Org mode to use property inheritance during
@@ -9296,16 +9366,16 @@ filter elements are accumulated.
selects entries with category =work= and effort estimates below 10
minutes, and deselects entries with tag =John= or matching the
- regexp =plot=. You can leave =+= out if that does not lead to
- ambiguities. The sequence of elements is arbitrary. The filter
- syntax assumes that there is no overlap between categories and tags.
- Otherwise, tags take priority. If you reply to the prompt with the
- empty string, all filtering is removed. If a filter is specified,
- it replaces all current filters. But if you call the command with
- a double prefix argument, or if you add an additional =+= (e.g.,
- =++work=) to the front of the string, the new filter elements are
- added to the active ones. A single prefix argument applies the
- entire filter in a negative sense.
+ regexp =plot= (see [[*Regular Expressions]]). You can leave =+= out if
+ that does not lead to ambiguities. The sequence of elements is
+ arbitrary. The filter syntax assumes that there is no overlap
+ between categories and tags. Otherwise, tags take priority. If you
+ reply to the prompt with the empty string, all filtering is removed.
+ If a filter is specified, it replaces all current filters. But if
+ you call the command with a double prefix argument, or if you add an
+ additional =+= (e.g., =++work=) to the front of the string, the new
+ filter elements are added to the active ones. A single prefix
+ argument applies the entire filter in a negative sense.
- {{{kbd(|)}}} (~org-agenda-filter-remove-all~) ::
@@ -10741,6 +10811,18 @@ To turn off fontification for marked up text, you can set
~org-fontify-emphasized-text~ to ~nil~. To narrow down the list of
available markup syntax, you can customize ~org-emphasis-alist~.
+Sometimes, when marked text also contains the marker character itself,
+the result may be unsettling. For example,
+
+#+begin_example
+/One may expect this whole sentence to be italicized, but the
+following ~user/?variable~ contains =/= character, which effectively
+stops emphasis there./
+#+end_example
+
+You can use zero width space to help Org sorting out the ambiguity.
+See [[*Escape Character]] for more details.
+
** Subscripts and Superscripts
:PROPERTIES:
:DESCRIPTION: Simple syntax for raising/lowering text.
@@ -10863,7 +10945,7 @@ pretty output for a number of export back-ends.
Org mode can contain LaTeX math fragments, and it supports ways to
process these for several export back-ends. When exporting to LaTeX,
the code is left as it is. When exporting to HTML, Org can use either
-[[http://www.mathjax.org][MathJax]] (see [[*Math formatting in HTML export]]) or transcode the math
+[[https://www.mathjax.org][MathJax]] (see [[*Math formatting in HTML export]]) or transcode the math
into images (see [[*Previewing LaTeX fragments]]).
LaTeX fragments do not need any special marking at all. The following
@@ -10968,7 +11050,7 @@ current buffer with {{{kbd(M-x org-cdlatex-mode)}}}, or for all Org
files with
#+begin_src emacs-lisp
-(add-hook 'org-mode-hook 'turn-on-org-cdlatex)
+(add-hook 'org-mode-hook #'turn-on-org-cdlatex)
#+end_src
When this mode is enabled, the following features are present (for
@@ -11304,7 +11386,7 @@ The following command handles footnotes:
#+attr_texinfo: :columns 0.1 0.9
| {{{kbd(s)}}} | Sort the footnote definitions by reference sequence. |
| {{{kbd(r)}}} | Renumber the simple =fn:N= footnotes. |
- | {{{kbd(S)}}} | Short for first {{{kbd(r)}}}, then {{{kbd(s)}}} action. |
+ | {{{kbd(S)}}} | Short for first {{{kbd(r)}}}, then {{{kbd(s)}}} action. |
| {{{kbd(n)}}} | Rename all footnotes into a =fn:1= ... =fn:n= sequence. |
| {{{kbd(d)}}} | Delete the footnote at point, including definition and references. |
@@ -11361,7 +11443,7 @@ Users can install libraries for additional formats from the Emacs
packaging system. For easy discovery, these packages have a common
naming scheme: ~ox-NAME~, where {{{var(NAME)}}} is a format. For
example, ~ox-koma-letter~ for /koma-letter/ back-end. More libraries
-can be found in the =contrib/= directory (see [[*Installation]]).
+can be found in the =org-contrib= repository (see [[*Installation]]).
#+vindex: org-export-backends
Org only loads back-ends for the following formats by default: ASCII,
@@ -11452,7 +11534,7 @@ further alter what is exported, and how.
Toggle visible-only export. This is useful for exporting only
certain parts of an Org document by adjusting the visibility of
- particular headings.
+ particular headings. See also [[*Sparse Trees]].
** Export Settings
:PROPERTIES:
@@ -11961,7 +12043,7 @@ example
#+texinfo: @noindent
becomes
-: Rose is red, violet's blue. Life's ordered: Org assists you.
+: Rose is red, violet's blue. Life's ordered: Org assists you.
As a special case, Org parses any replacement text starting with
=(eval= as an Emacs Lisp expression and evaluates it accordingly.
@@ -12527,7 +12609,7 @@ compatible with XHTML 1.0 strict standard.
#+findex: org-html-export-to-html
Export as HTML file with a =.html= extension. For =myfile.org=, Org
- exports to =myfile.html=, overwriting without warning. {{{kbd{C-c
+ exports to =myfile.html=, overwriting without warning. {{{kbd(C-c
C-e h o)}}} exports to HTML and opens it in a web browser.
- {{{kbd(C-c C-e h H)}}} (~org-html-export-as-html~) ::
@@ -12552,6 +12634,9 @@ settings described in [[*Export Settings]].
multiple =DESCRIPTION= lines. The exporter takes care of wrapping
the lines properly.
+ The exporter includes a number of other meta tags, which can be customized
+ by modifying ~org-html-meta-tags~.
+
- =HTML_DOCTYPE= ::
#+cindex: @samp{HTML_DOCTYPE}, keyword
@@ -12693,8 +12778,8 @@ exports to:
#+begin_src html
<video controls="controls" width="350">
<source src="movie.mp4" type="video/mp4">
- <source src="movie.ogg" type="video/ogg">
- <p>Your browser does not support the video tag.</p>
+ <source src="movie.ogg" type="video/ogg">
+ <p>Your browser does not support the video tag.</p>
</video>
#+end_src
@@ -12925,7 +13010,7 @@ as-is.
#+vindex: org-html-mathjax-options~
LaTeX math snippets (see [[*LaTeX fragments]]) can be displayed in two
-different ways on HTML pages. The default is to use the [[http://www.mathjax.org][MathJax]],
+different ways on HTML pages. The default is to use the [[https://www.mathjax.org][MathJax]],
which should work out of the box with Org[fn:129][fn:130]. Some MathJax
display options can be configured via ~org-html-mathjax-options~, or
in the buffer. For example, with the following settings,
@@ -13621,7 +13706,7 @@ placement.
#+cindex: image, centering in LaTeX export
The LaTeX export back-end centers all images by default. Setting
=:center= to =nil= disables centering. To disable centering globally,
-set ~org-latex-images-centered~ to =t=.
+set ~org-latex-images-centered~ to =nil=.
Set the =:comment-include= attribute to non-~nil~ value for the LaTeX
export back-end to comment out the =\includegraphics= macro.
@@ -13698,7 +13783,7 @@ objects through the attributes =:float= and =:options=. For =:float=:
The LaTeX export back-end passes string values in =:options= to LaTeX
packages for customization of that specific source block. In the
example below, the =:options= are set for Minted. Minted is a source
-code highlighting LaTeX package with many configurable options.
+code highlighting LaTeX package with many configurable options[fn:134].
#+begin_example
,#+ATTR_LATEX: :options commentstyle=\bfseries
@@ -13801,6 +13886,95 @@ The LaTeX export back-end converts horizontal rules by the specified
-----
#+end_example
+*** Verse blocks in LaTeX export
+:PROPERTIES:
+:DESCRIPTION: Attributes specific to special blocks.
+:END:
+
+#+cindex: verse blocks, in @LaTeX{} export
+#+cindex: @samp{ATTR_LATEX}, keyword
+
+The LaTeX export back-end accepts four attributes for verse blocks:
+=:lines=, =:center=, =:versewidth= and =:latexcode=. The three first
+require the external LaTeX package =verse.sty=, which is an extension
+of the standard LaTeX environment.
+
+- =:lines= :: To add marginal verse numbering. Its value is an
+ integer, the sequence in which the verses should be numbered.
+- =:center= :: With value =t= all the verses on the page are optically
+ centered (a typographic convention for poetry), taking as a
+ reference the longest verse, which must be indicated by the
+ attribute =:versewidth=.
+- =:versewidth= :: Its value is a literal text string with the longest
+ verse.
+- =:latexcode= :: It accepts any arbitrary LaTeX code that can be
+ included within a LaTeX =verse= environment.
+
+A complete example with Shakespeare's first sonnet:
+
+#+begin_src org
+,#+ATTR_LATEX: :center t :latexcode \color{red} :lines 5
+,#+ATTR_LATEX: :versewidth Feed’st thy light’s flame with self-substantial fuel,
+,#+BEGIN_VERSE
+From fairest creatures we desire increase,
+That thereby beauty’s rose might never die,
+But as the riper should by time decease
+His tender heir might bear his memory
+But thou, contracted to thine own bright eyes,
+Feed’st thy light’s flame with self-substantial fuel,
+Making a famine where abundance lies,
+Thyself thy foe, to thy sweet self too cruel.
+Thou that art now the world’s fresh ornament,
+And only herald to the gaudy spring,
+Within thine own bud buriest thy content,
+And, tender churl, mak’st waste in niggardly.
+Pity the world, or else this glutton be,
+To eat the world’s due, by the grave and thee.
+,#+END_VERSE
+#+end_src
+
+*** Quote blocks in LaTeX export
+:PROPERTIES:
+:DESCRIPTION: Attributes specific to quote blocks.
+:END:
+
+#+cindex: quote blocks, in @LaTeX{} export
+#+cindex: @samp{ATTR_LATEX}, keyword
+#+cindex: org-latex-default-quote-environment
+
+The LaTeX export back-end accepts two attributes for quote blocks:
+=:environment=, for an arbitrary quoting environment (the default
+value is that of ~org-latex-default-quote-environment~: ~"quote"~) and
+=:options=. For example, to choose the environment =quotation=,
+included as an alternative to =quote= in standard LaTeX classes:
+
+#+begin_example
+,#+ATTR_LATEX: :environment quotation
+,#+BEGIN_QUOTE
+some text...
+,#+END_QUOTE
+#+end_example
+
+To choose the =foreigndisplayquote= environment, included in the LaTeX
+package =csquotes=, with the =german= option, use this syntax:
+
+#+begin_example
+,#+LATEX_HEADER:\usepackage[autostyle=true]{csquotes}
+,#+ATTR_LATEX: :environment foreigndisplayquote :options {german}
+,#+BEGIN_QUOTE
+some text in German...
+,#+END_QUOTE
+#+end_example
+
+#+texinfo: @noindent
+which is exported to LaTeX as
+
+#+begin_example
+\begin{foreigndisplayquote}{german}
+some text in German...
+\end{foreigndisplayquote}
+#+end_example
+
** Markdown Export
:PROPERTIES:
:DESCRIPTION: Exporting to Markdown.
@@ -13860,7 +14034,7 @@ a limit to a level before the absolute limit (see [[*Export Settings]]).
The ODT export back-end handles creating of OpenDocument Text (ODT)
format. Documents created by this exporter use the
-{{{cite(OpenDocument-v1.2 specification)}}}[fn:134] and are compatible
+{{{cite(OpenDocument-v1.2 specification)}}}[fn:135] and are compatible
with LibreOffice 3.4.
*** Pre-requisites for ODT export
@@ -14261,7 +14435,7 @@ document in one of the following ways:
variables ~org-latex-to-mathml-convert-command~ and
~org-latex-to-mathml-jar-file~.
- If you prefer to use MathToWeb[fn:135] as your converter, you can
+ If you prefer to use MathToWeb[fn:136] as your converter, you can
configure the above variables as shown below.
#+begin_src emacs-lisp
@@ -14272,7 +14446,7 @@ document in one of the following ways:
#+end_src
#+texinfo: @noindent
- or, to use LaTeX​ML[fn:136] instead,
+ or, to use LaTeX​ML[fn:137] instead,
#+begin_src emacs-lisp
(setq org-latex-to-mathml-convert-command
@@ -14591,7 +14765,7 @@ with the =#+ATTR_ODT= line. For a discussion on default formatting of
tables, see [[*Tables in ODT export]].
This feature closely mimics the way table templates are defined in the
-OpenDocument-v1.2 specification[fn:137].
+OpenDocument-v1.2 specification[fn:138].
#+vindex: org-odt-table-styles
For quick preview of this feature, install the settings below and export the
@@ -14625,7 +14799,7 @@ templates, define new styles there.
To use this feature proceed as follows:
-1. Create a table template[fn:138].
+1. Create a table template[fn:139].
A table template is set of =table-cell= and =paragraph= styles for
each of the following table cell categories:
@@ -14664,7 +14838,7 @@ To use this feature proceed as follows:
=</office:automatic-styles>= element of the content template file
(see [[x-orgodtcontenttemplate-xml][Factory styles]]).
-2. Define a table style[fn:139].
+2. Define a table style[fn:140].
#+vindex: org-odt-table-styles
To define a table style, create an entry for the style in the
@@ -15159,7 +15333,7 @@ To specify the author of the quotation, use the =:author= attribute.
,#+BEGIN_QUOTE
The Lady of the Lake, her arm clad in the purest shimmering samite,
held aloft Excalibur from the bosom of the water, signifying by divine
-providence that I, Arthur, was to carry Excalibur. That is why I am
+providence that I, Arthur, was to carry Excalibur. That is why I am
your king.
,#+END_QUOTE
#+end_example
@@ -15397,7 +15571,7 @@ for usage and configuration details.
:DESCRIPTION: Fine-tuning the export output.
:END:
-*** Hooks
+*** Export hooks
:PROPERTIES:
:UNNUMBERED: notoc
:END:
@@ -15422,7 +15596,7 @@ BACKEND is the export back-end being used, as a symbol."
(org-map-entries
(lambda () (delete-region (point) (line-beginning-position 2)))))
-(add-hook 'org-export-before-parsing-hook 'my-headline-removal)
+(add-hook 'org-export-before-parsing-hook #'my-headline-removal)
#+end_src
*** Filters
@@ -15768,17 +15942,17 @@ following properties
Publishing means that a file is copied to the destination directory
and possibly transformed in the process. The default transformation
is to export Org files as HTML files, and this is done by the function
-~org-publish-org-to-html~ which calls the HTML exporter (see [[*HTML
+~org-html-publish-to-html~ which calls the HTML exporter (see [[*HTML
Export]]). But you can also publish your content as PDF files using
-~org-publish-org-to-pdf~, or as ASCII, Texinfo, etc., using the
+~org-latex-publish-to-pdf~, or as ASCII, Texinfo, etc., using the
corresponding functions.
If you want to publish the Org file as an =.org= file but with
/archived/, /commented/, and /tag-excluded/ trees removed, use
-~org-publish-org-to-org~. This produces =file.org= and put it in the
+~org-org-publish-to-org~. This produces =file.org= and puts it in the
publishing directory. If you want a htmlized version of this file,
set the parameter ~:htmlized-source~ to ~t~. It produces
-=file.org.html= in the publishing directory[fn:140].
+=file.org.html= in the publishing directory[fn:141].
Other files like images only need to be copied to the publishing
destination; for this you can use ~org-publish-attachment~. For
@@ -16247,12 +16421,13 @@ directory on the local machine.
(setq org-publish-project-alist
'(("org"
:base-directory "~/org/"
+ :publishing-function org-html-publish-to-html
:publishing-directory "~/public_html"
:section-numbers nil
- :table-of-contents nil
- :style "<link rel=\"stylesheet\"
- href=\"../other/mystyle.css\"
- type=\"text/css\"/>")))
+ :with-toc nil
+ :html-head "<link rel=\"stylesheet\"
+ href=\"../other/mystyle.css\"
+ type=\"text/css\"/>")))
#+end_src
*** Example: complex publishing configuration
@@ -16347,6 +16522,127 @@ of the commands above, or by customizing the variable
particular if files include other files via =SETUPFILE= or =INCLUDE=
keywords.
+* Citation handling
+:PROPERTIES:
+:DESCRIPTION: create, follow and export citations.
+:END:
+#+cindex: citation
+
+The =oc.el= library provides tooling to handle citations in Org via
+"citation processors" that offer some or all of the following
+capabilities:
+
+- activate :: Fontification, tooltip preview, etc.
+- follow :: At-point actions on citations via ~org-open-at-point~.
+- insert :: Add and edit citations via ~org-cite-insert~.
+- export :: Via different libraries for different target formats.
+
+The user can configure these with ~org-cite-activate-processor~,
+~org-cite-follow-processor~, ~org-cite-insert-processor~, and
+~org-cite-export-processors~ respectively.
+
+The included "basic" processor provides all four capabilities.
+
+** Citations
+
+Before adding citations, first set one-or-more bibliographies, either
+globally with ~org-cite-global-bibliography~, or locally using one or
+more "bibliography" keywords.
+
+#+begin_example
+#+bibliography: SomeFile.bib
+#+bibliography: /some/other/file.json
+#+bibliography: "/some/file/with spaces/in its name.bib"
+#+end_example
+
+#+kindex: C-c C-x @@
+#+findex: org-cite-insert
+One can then insert and edit citations using ~org-cite-insert~, called
+with {{{kbd(C-c C-x @)}}}.
+
+A /citation/ requires one or more citation /key(s)/, elements
+identifying a reference in the bibliography.
+
+- Each citation is surrounded by brackets and uses the =cite= type.
+
+- Each key starts with the character =@=.
+
+- Each key can be qualified by a /prefix/ (e.g.\nbsp{}"see ") and/or
+ a /suffix/ (e.g.\nbsp{}"p.\nbsp{}123"), giving information useful or necessary
+ fo the comprehension of the citation but not included in the
+ reference.
+
+- A single citation can cite more than one reference ; the keys are
+ separated by semicolons ; the formatting of such citation groups is
+ specified by the style.
+
+- One can also specify a stylistic variation for the citations by
+ inserting a =/= and a style name between the =cite= keyword and the
+ colon; this usually makes sense only for the author-year styles.
+
+: [cite/style:common prefix ;prefix @key suffix; ... ; common suffix]
+
+The only mandatory elements are:
+
+- The =cite= keyword and the colon.
+- The =@= character immediately preceding each key.
+- The brackets surrounding the citation(s) (group).
+
+** Citation export processors
+
+Org currently includes the following export processors:
+
+- Two processors can export to a variety of formats, including =latex=
+ (and therefore =pdf=), =html=, =odt= and plain (UTF8) text:
+
+ - basic :: a basic export processor, well adapted to situations
+ where backward compatibility is not a requirement and formatting
+ needs are minimal;
+
+ - csl :: this export processor uses format files written in [[https://en.wikipedia.org/wiki/Citation_Style_Language][Citation
+ Style Language]] via [[https://github.com/andras-simonyi/citeproc-el][citeproc-el]];
+
+- In contrast, two other processors target LaTeX and LaTeX-derived
+ formats exclusively:
+
+ - natbib :: this export processor uses BibTeX, the historical
+ bibliographic processor used with LaTeX, thus allowing the use of
+ data and style files compatible with this processor (including
+ a large number of publishers' styles). It uses citation commands
+ implemented in the LaTeX package =natbib=, allowing more stylistic
+ variants that LaTeX's =\cite= command.
+
+ - biblatex :: this backend allows the use of data and formats
+ prepared for BibLaTeX, an alternate bibliographic processor used
+ with LaTeX, which overcomes some serious BibTeX limitations, but
+ has not (yet?)\nbsp{}been widely adopted by publishers.
+
+The =CITE_EXPORT= keyword specifies the export processor and the
+citation (and possibly reference) style(s); for example (all arguments
+are optional)
+
+: #+cite_export: basic author author-year
+
+#+texinfo: @noindent
+specifies the "basic" export processor with citations inserted as
+author's name and references indexed by author's names and year;
+
+: #+cite_export: csl /some/path/to/vancouver-brackets.csl
+
+#+texinfo: @noindent
+specifies the "csl" processor and CSL style, which in this case
+defines numeric citations and numeric references according to the
+=Vancouver= specification (as style used in many medical journals),
+following a typesetting variation putting citations between brackets;
+
+: #+cite_export: natbib kluwer
+
+#+texinfo: @noindent
+specifies the =natbib= export processor with a label citation style
+conformant to the Harvard style and the specification of the
+Wolkers-Kluwer publisher; since it relies on the ~bibtex~ processor of
+your LaTeX installation, it won't export to anything but PDF.
+
* Working with Source Code
:PROPERTIES:
:DESCRIPTION: Export, evaluate, and tangle code blocks.
@@ -16393,7 +16689,7 @@ extract, export, and publish source code blocks. Org can also compile
and execute a source code block, then capture the results. The Org
mode literature sometimes refers to source code blocks as /live code/
blocks because they can alter the content of the Org document or the
-material that it exports. Users can control how live they want each
+material that it exports. Users can control the "liveliness" of each
source code block by tweaking the header arguments (see [[*Using Header
Arguments]]) for compiling, execution, extraction, and exporting.
@@ -16736,7 +17032,11 @@ the =var= header argument.
body. {{{var(ASSIGN)}}} is a literal value, such as a string,
a number, a reference to a table, a list, a literal example, another
code block---with or without arguments---or the results of evaluating
-a code block.
+a code block. {{{var(ASSIGN)}}} may specify a filename for references
+to elements in a different file, using a =:= to separate the filename
+from the reference.
+
+: :var NAME=FILE:REFERENCE
Here are examples of passing values by reference:
@@ -16815,6 +17115,9 @@ Here are examples of passing values by reference:
| two | 16 | 17 | 18 | 19 | 20 |
#+end_example
+To refer to a table in another file, join the filename and table name with
+a colon, for example: =:var table=other-file.org:example-table=.
+
- list ::
A simple named list.
@@ -17156,13 +17459,13 @@ See [[*Languages]] to enable other languages.
#+kindex: C-c C-v e
#+findex: org-babel-execute-src-block
Org provides many ways to execute code blocks. {{{kbd(C-c C-c)}}} or
-{{{kbd(C-c C-v e)}}} with the point on a code block[fn:141] calls the
+{{{kbd(C-c C-v e)}}} with the point on a code block[fn:142] calls the
~org-babel-execute-src-block~ function, which executes the code in the
block, collects the results, and inserts them in the buffer.
#+cindex: @samp{CALL}, keyword
#+vindex: org-babel-inline-result-wrap
-By calling a named code block[fn:142] from an Org mode buffer or
+By calling a named code block[fn:143] from an Org mode buffer or
a table. Org can call the named code blocks from the current Org mode
buffer or from the "Library of Babel" (see [[*Library of Babel]]).
@@ -17363,7 +17666,7 @@ they are mutually exclusive.
- =value= ::
- Default for most Babel libraries[fn:142]. Functional mode. Org
+ Default for most Babel libraries[fn:143]. Functional mode. Org
gets the value by wrapping the code in a function definition in the
language of the source block. That is why when using =:results
value=, code should execute like a function and return a value. For
@@ -17488,10 +17791,12 @@ default behavior is to automatically determine the result type.
#+end_example
#+cindex: @samp{file-desc}, header argument
- The =file-desc= header argument defines the description (see
- [[*Link Format]]) for the link. If =file-desc= is present but has no value,
+ The =file-desc= header argument defines the description (see [[*Link
+ Format]]) for the link. If =file-desc= is present but has no value,
the =file= value is used as the link description. When this
- argument is not present, the description is omitted.
+ argument is not present, the description is omitted. If you want to
+ provide the =file-desc= argument but omit the description, you can
+ provide it with an empty vector (i.e., :file-desc []).
#+cindex: @samp{sep}, header argument
By default, Org assumes that a table written to a file has
@@ -17549,7 +17854,7 @@ follows from the type specified above.
#+begin_example
,#+begin_src shell :results file link :file "download.tar.gz"
- wget -c "http://example.com/download.tar.gz"
+ wget -c "https://example.com/download.tar.gz"
,#+end_src
#+end_example
@@ -17595,15 +17900,20 @@ value listed above. E.g.,
Handling options after collecting the results.
+- =replace= ::
+
+ Default. Insert results in the Org buffer. Remove previous
+ results. Usage example: =:results output replace=.
+
- =silent= ::
Do not insert results in the Org mode buffer, but echo them in the
minibuffer. Usage example: =:results output silent=.
-- =replace= ::
+- =none= ::
- Default. Insert results in the Org buffer. Remove previous
- results. Usage example: =:results output replace=.
+ Do not process results at all. No inserting in the Org mode buffer
+ nor echo them in the minibuffer. Usage example: =:results none=.
- =append= ::
@@ -17893,7 +18203,7 @@ expanded anyway.
#+kindex: C-c C-v f
Choose a file to tangle. Bound to {{{kbd(C-c C-v f)}}}.
-*** Hooks
+*** Tangle hooks
:PROPERTIES:
:UNNUMBERED: notoc
:END:
@@ -17929,35 +18239,8 @@ code block header arguments:
#+cindex: source code, languages
#+cindex: code block, languages
-Code blocks in the following languages are supported.
-
-#+attr_texinfo: :columns 0.25 0.25 0.25 0.20
-| Language | Identifier | Language | Identifier |
-|------------+---------------+----------------+--------------|
-| Asymptote | =asymptote= | Lisp | =lisp= |
-| Awk | =awk= | Lua | =lua= |
-| C | =C= | MATLAB | =matlab= |
-| C++ | =C++=[fn:143] | Mscgen | =mscgen= |
-| Clojure | =clojure= | Objective Caml | =ocaml= |
-| CSS | =css= | Octave | =octave= |
-| D | =D=[fn:144] | Org mode | =org= |
-| ditaa | =ditaa= | Oz | =oz= |
-| Emacs Calc | =calc= | Perl | =perl= |
-| Emacs Lisp | =emacs-lisp= | Plantuml | =plantuml= |
-| Eshell | =eshell= | Processing.js | =processing= |
-| Fortran | =fortran= | Python | =python= |
-| Gnuplot | =gnuplot= | R | =R= |
-| GNU Screen | =screen= | Ruby | =ruby= |
-| Graphviz | =dot= | Sass | =sass= |
-| Haskell | =haskell= | Scheme | =scheme= |
-| Java | =java= | Sed | =sed= |
-| Javascript | =js= | shell | =sh= |
-| LaTeX | =latex= | SQL | =sql= |
-| Ledger | =ledger= | SQLite | =sqlite= |
-| Lilypond | =lilypond= | Vala | =vala= |
-
-Additional documentation for some languages is at
-https://orgmode.org/worg/org-contrib/babel/languages.html.
+Code blocks in dozens of languages are supported. See Worg for
+[[https://orgmode.org/worg/org-contrib/babel/languages/index.html][language specific documentation]].
#+vindex: org-babel-load-languages
By default, only Emacs Lisp is enabled for evaluation. To enable or
@@ -18071,7 +18354,7 @@ for Python and Emacs Lisp languages.
#+cindex: @samp{noweb-ref}, header argument
Source code blocks can include references to other source code blocks,
-using a noweb[fn:145] style syntax:
+using a noweb[fn:144] style syntax:
: <<CODE-BLOCK-ID>>
@@ -18582,14 +18865,14 @@ Org Tempo expands snippets to structures defined in
~org-structure-template-alist~ and ~org-tempo-keywords-alist~. For
example, {{{kbd(< s TAB)}}} creates a code block. Enable it by
customizing ~org-modules~ or add =(require 'org-tempo)= to your Emacs
-init file[fn:146].
+init file[fn:145].
#+attr_texinfo: :columns 0.1 0.9
| {{{kbd(a)}}} | =#+BEGIN_EXPORT ascii= ... =#+END_EXPORT= |
| {{{kbd(c)}}} | =#+BEGIN_CENTER= ... =#+END_CENTER= |
| {{{kbd(C)}}} | =#+BEGIN_COMMENT= ... =#+END_COMMENT= |
| {{{kbd(e)}}} | =#+BEGIN_EXAMPLE= ... =#+END_EXAMPLE= |
-| {{{kbd(E)}}} | =#+BEGIN_EXPORT= ... =#+END_EXPORT= |
+| {{{kbd(E)}}} | =#+BEGIN_EXPORT= ... =#+END_EXPORT= |
| {{{kbd(h)}}} | =#+BEGIN_EXPORT html= ... =#+END_EXPORT= |
| {{{kbd(l)}}} | =#+BEGIN_EXPORT latex= ... =#+END_EXPORT= |
| {{{kbd(q)}}} | =#+BEGIN_QUOTE= ... =#+END_QUOTE= |
@@ -18616,14 +18899,14 @@ the variable ~org-use-speed-commands~ to a non-~nil~ value. To
trigger a Speed Key, point must be at the beginning of an Org
headline, before any of the stars.
-#+vindex: org-speed-commands-user
+#+vindex: org-speed-commands
#+findex: org-speed-command-help
Org comes with a pre-defined list of Speed Keys. To add or modify
-Speed Keys, customize the variable, ~org-speed-commands-user~. For
-more details, see the variable's docstring. With Speed Keys
-activated, {{{kbd(M-x org-speed-command-help)}}}, or {{{kbd(?)}}} when
-point is at the beginning of an Org headline, shows currently active
-Speed Keys, including the user-defined ones.
+Speed Keys, customize the option ~org-speed-commands~. For more
+details, see the variable's docstring. With Speed Keys activated,
+{{{kbd(M-x org-speed-command-help)}}}, or {{{kbd(?)}}} when point is at the
+beginning of an Org headline, shows currently active Speed Keys,
+including the user-defined ones.
** A Cleaner Outline View
:PROPERTIES:
@@ -18662,7 +18945,7 @@ in the desired amount with hard spaces and hiding leading stars.
To display the buffer in the indented view, activate Org Indent minor
mode, using {{{kbd(M-x org-indent-mode)}}}. Text lines that are not
headlines are prefixed with virtual spaces to vertically align with
-the headline text[fn:147].
+the headline text[fn:146].
#+vindex: org-indent-indentation-per-level
To make more horizontal space, the headlines are shifted by two
@@ -18690,15 +18973,15 @@ use =STARTUP= keyword as follows:
It is possible to use hard spaces to achieve the indentation instead,
if the bare ASCII file should have the indented look also outside
-Emacs[fn:148]. With Org's support, you have to indent all lines to
+Emacs[fn:147]. With Org's support, you have to indent all lines to
line up with the outline headers. You would use these
-settings[fn:149]:
+settings[fn:148]:
- #+begin_src emacs-lisp
- (setq org-adapt-indentation t
- org-hide-leading-stars t
- org-odd-levels-only t)
- #+end_src
+#+begin_src emacs-lisp
+(setq org-adapt-indentation t
+ org-hide-leading-stars t
+ org-odd-levels-only t)
+#+end_src
- /Indentation of text below headlines/ (~org-adapt-indentation~) ::
@@ -18955,11 +19238,15 @@ changes.
| =overview= | Top-level headlines only. |
| =content= | All headlines. |
| =showall= | No folding on any entry. |
+ | =show2levels= | Headline levels 1-2. |
+ | =show3levels= | Headline levels 1-3. |
+ | =show4levels= | Headline levels 1-4. |
+ | =show5levels= | Headline levels 1-5. |
| =showeverything= | Show even drawer contents. |
#+vindex: org-startup-indented
Dynamic virtual indentation is controlled by the variable
- ~org-startup-indented~[fn:150].
+ ~org-startup-indented~[fn:149].
| =indent= | Start with Org Indent mode turned on. |
| =noindent= | Start with Org Indent mode turned off. |
@@ -19095,6 +19382,22 @@ changes.
These lines set the TODO keywords and their interpretation in the
current file. The corresponding variable is ~org-todo-keywords~.
+** Regular Expressions
+:PROPERTIES:
+:DESCRIPTION: Elisp regular expressions.
+:END:
+#+cindex: regular expressions syntax
+#+cindex: regular expressions, in searches
+
+Org, as an Emacs mode, makes use of Elisp regular expressions for
+searching, matching and filtering. Elisp regular expressions have a
+somewhat different syntax then some common standards. Most notably,
+alternation is indicated using =\|= and matching groups are denoted by
+=\(...\)=. For example the string =home\|work= matches either =home=
+or =work=.
+
+For more information, see [[info:emacs::Regexps][Regular Expressions in Emacs]].
+
** Org Syntax
:PROPERTIES:
:DESCRIPTION: Formal description of Org's syntax.
@@ -19533,7 +19836,7 @@ passed to Emacs through the =emacsclient= command, so you also need to
ensure an Emacs server is running. More precisely, when the
application calls
-: emacsclient org-protocol://PROTOCOL?key1=val1&key2=val2
+: emacsclient "org-protocol://PROTOCOL?key1=val1&key2=val2"
#+texinfo: @noindent
Emacs calls the handler associated to {{{var(PROTOCOL)}}} with
@@ -19556,7 +19859,7 @@ Using the ~store-link~ handler, you can copy links, to that they can
be inserted using {{{kbd(M-x org-insert-link)}}} or yanking. More
precisely, the command
-: emacsclient org-protocol://store-link?url=URL&title=TITLE
+: emacsclient "org-protocol://store-link?url=URL&title=TITLE"
#+texinfo: @noindent
stores the following link:
@@ -19571,10 +19874,19 @@ To use this feature from a browser, add a bookmark with an arbitrary
name, e.g., =Org: store-link= and enter this as /Location/:
#+begin_example
+javascript:location.href='org-protocol://store-link?' +
+ new URLSearchParams({url:location.href, title:document.title});
+#+end_example
+
+Title is an optional parameter. Another expression was recommended earlier:
+
+#+begin_example
javascript:location.href='org-protocol://store-link?url='+
encodeURIComponent(location.href);
#+end_example
+The latter form is compatible with older Org versions from 9.0 to 9.4.
+
*** The ~capture~ protocol
:PROPERTIES:
:DESCRIPTION: Fill a buffer with external information.
@@ -19585,18 +19897,31 @@ javascript:location.href='org-protocol://store-link?url='+
Activating the "capture" handler pops up a =Capture= buffer in Emacs,
using acapture template.
-: emacsclient org-protocol://capture?template=X?url=URL?title=TITLE?body=BODY
+: emacsclient "org-protocol://capture?template=X&url=URL&title=TITLE&body=BODY"
To use this feature, add a bookmark with an arbitrary name, e.g.,
=Org: capture=, and enter this as =Location=:
#+begin_example
+javascript:location.href='org-protocol://capture?' +
+ new URLSearchParams({
+ template: 'x', url: window.location.href,
+ title: document.title, body: window.getSelection()});
+#+end_example
+
+You might have seen another expression:
+
+#+begin_example
javascript:location.href='org-protocol://capture?template=x'+
'&url='+encodeURIComponent(window.location.href)+
'&title='+encodeURIComponent(document.title)+
'&body='+encodeURIComponent(window.getSelection());
#+end_example
+It is a bit more cluttered than the former one, but it is compatible
+with previous Org versions 9.0-9.4. In these versions encoding of
+space as "+" character was not supported by URI decoder.
+
#+vindex: org-protocol-default-template-key
The capture template to be used can be specified in the bookmark (like
=X= above). If unspecified, the template key is set in the variable
@@ -19652,13 +19977,13 @@ click the bookmark and start editing.
#+cindex: rewritten URL in open-source protocol
#+cindex: protocol, open-source rewritten URL
However, such mapping may not always yield the desired results.
-Suppose you maintain an online store located at =http://example.com/=.
+Suppose you maintain an online store located at =https://example.com/=.
The local sources reside in =/home/user/example/=. It is common
practice to serve all products in such a store through one file and
rewrite URLs that do not match an existing file on the server. That
-way, a request to =http://example.com/print/posters.html= might be
+way, a request to =https://example.com/print/posters.html= might be
rewritten on the server to something like
-=http://example.com/shop/products.php/posters.html.php=. The
+=https://example.com/shop/products.php/posters.html.php=. The
~open-source~ handler probably cannot find a file named
=/home/user/example/print/posters.html.php= and fails.
@@ -19673,7 +19998,7 @@ adding ~:rewrites~ rules like this:
#+begin_src emacs-lisp
(setq org-protocol-project-alist
'(("example.com"
- :base-url "http://example.com/"
+ :base-url "https://example.com/"
:working-directory "/home/user/example/"
:online-suffix ".php"
:working-suffix ".php"
@@ -19704,8 +20029,8 @@ an Org file that is part of a publishing project.
:END:
Org Crypt encrypts the text of an entry, but not the headline, or
-properties. Behind the scene, it uses the Emacs EasyPG library to
-encrypt and decrypt files.
+properties. Behind the scene, it uses the [[info:epa][Emacs EasyPG Library]] to
+encrypt and decrypt files, and EasyPG needs a correct [[info:gnupg][GnuPG]] setup.
#+vindex: org-crypt-tag-matcher
Any text below a headline that has a =crypt= tag is automatically
@@ -19778,7 +20103,7 @@ Tags]]) only for those set in these variables.
#+vindex: org-mobile-directory
The mobile application needs access to a file directory on
-a server[fn:151] to interact with Emacs. Pass its location through
+a server[fn:150] to interact with Emacs. Pass its location through
the ~org-mobile-directory~ variable. If you can mount that directory
locally just set the variable to point to that directory:
@@ -19799,7 +20124,7 @@ With a public server, consider encrypting the files. Org also
requires OpenSSL installed on the local computer. To turn on
encryption, set the same password in the mobile application and in
Emacs. Set the password in the variable
-~org-mobile-use-encryption~[fn:152]. Note that even after the mobile
+~org-mobile-use-encryption~[fn:151]. Note that even after the mobile
application encrypts the file contents, the file name remains visible
on the file systems of the local computer, the server, and the mobile
device.
@@ -19815,15 +20140,15 @@ The command ~org-mobile-push~ copies files listed in
~org-mobile-files~ into the staging area. Files include agenda files
(as listed in ~org-agenda-files~). Customize ~org-mobile-files~ to
add other files. File names are staged with paths relative to
-~org-directory~, so all files should be inside this directory[fn:153].
+~org-directory~, so all files should be inside this directory[fn:152].
Push creates a special Org file =agendas.org= with custom agenda views
-defined by the user[fn:154].
+defined by the user[fn:153].
Finally, Org writes the file =index.org=, containing links to other
files. The mobile application reads this file first from the server
to determine what other files to download for agendas. For faster
-downloads, it is expected to only read files whose checksums[fn:155]
+downloads, it is expected to only read files whose checksums[fn:154]
have changed.
*** Pulling from the mobile application
@@ -19840,7 +20165,7 @@ data in an inbox file format, through the following steps:
1.
#+vindex: org-mobile-inbox-for-pull
- Org moves all entries found in =mobileorg.org=[fn:156] and appends
+ Org moves all entries found in =mobileorg.org=[fn:155] and appends
them to the file pointed to by the variable
~org-mobile-inbox-for-pull~. It should reside neither in the
staging area nor on the server. Each captured entry and each
@@ -19904,12 +20229,10 @@ https://orgmode.org/worg/doc.html#hooks.
:END:
#+cindex: add-on packages
-Various authors wrote a large number of add-on packages for Org.
-
-These packages are not part of Emacs, but they are distributed as
-contributed packages with the separate release available at
-https://orgmode.org. See the =contrib/README= file in the source code
-directory for a list of contributed files. Worg page with more
+Various authors wrote a large number of add-on packages for Org. Some
+of these packages used to be part of the =org-mode= repository but are
+now hosted in a separate =org-contrib= repository
+[[https://git.sr.ht/~bzg/org-contrib][here]]. A Worg page with more
information is at: https://orgmode.org/worg/org-contrib/.
** Adding Hyperlink Types
@@ -20136,9 +20459,9 @@ of these strategies:
#+cindex: @LaTeX{}, and Orgtbl mode
To wrap a source table in LaTeX, use the =comment= environment
-provided by =comment.sty=[fn:157]. To activate it, put
+provided by =comment.sty=[fn:156]. To activate it, put
~\usepackage{comment}~ in the document header. Orgtbl mode inserts
-a radio table skeleton[fn:158] with the command {{{kbd(M-x
+a radio table skeleton[fn:157] with the command {{{kbd(M-x
orgtbl-insert-radio-table)}}}, which prompts for a table name. For
example, if =salesfigures= is the name, the template inserts:
@@ -20157,7 +20480,7 @@ The line =#+ORGTBL: SEND= tells Orgtbl mode to use the function
~orgtbl-to-latex~ to convert the table to LaTeX format, then insert
the table at the target (receive) location named =salesfigures=. Now
the table is ready for data entry. It can even use spreadsheet
-features[fn:159]:
+features[fn:158]:
#+begin_example
% BEGIN RECEIVE ORGTBL salesfigures
@@ -20373,7 +20696,7 @@ Dynamic blocks, like any other block, can be narrowed with
#+vindex: org-agenda-skip-function
#+vindex: org-agenda-skip-function-global
Org provides a special hook to further limit items in agenda views:
-~agenda~, ~agenda*~[fn:160], ~todo~, ~alltodo~, ~tags~, ~tags-todo~,
+~agenda~, ~agenda*~[fn:159], ~todo~, ~alltodo~, ~tags~, ~tags-todo~,
~tags-tree~. Specify a custom function that tests inclusion of every
matched item in the view. This function can also skip as much as is
needed.
@@ -20416,7 +20739,7 @@ meaningful string suitable for the agenda view.
#+vindex: org-agenda-skip-function
Search for entries with a limit set on levels for the custom search.
This is a general approach to creating custom searches in Org. To
-include all levels, use =LEVEL>0=[fn:161]. Then to selectively pick
+include all levels, use =LEVEL>0=[fn:160]. Then to selectively pick
the matched entries, use ~org-agenda-skip-function~, which also
accepts Lisp forms, such as ~org-agenda-skip-entry-if~ and
~org-agenda-skip-subtree-if~. For example:
@@ -21017,6 +21340,9 @@ be complete if the ones above were not mentioned in this manual.
- Charles Cave's suggestion sparked the implementation of templates
for Remember, which are now templates for capture.
+- Timothy E Chapman worked on a complete overhaul of the orgmode.org
+ website in 2020 and helped fixing various bugs.
+
- Pavel Chalmoviansky influenced the agenda treatment of items with
specified time.
@@ -21106,6 +21432,9 @@ be complete if the ones above were not mentioned in this manual.
- Jason\nbsp{}F.\nbsp{}McBrayer suggested agenda export to CSV format.
+- Kyle Meyer helped setting up the [[https://public-inbox.org/][public-inbox]] archive of the [[https://orgmode.org/list/][Org
+ mailing list]] and has been fixing many bugs.
+
- Max Mikhanosha came up with the idea of refiling.
- Dmitri Minaev sent a patch to set priority limits on a per-file
@@ -21143,6 +21472,9 @@ be complete if the ones above were not mentioned in this manual.
- Martin Pohlack provided the code snippet to bundle character
insertion into bundles of 20 for undo.
+- Ihor Radchenko helped with fixing bugs and improving the user
+ experience regarding Org's speed.
+
- T.\nbsp{}V.\nbsp{}Raman reported bugs and suggested improvements.
- Matthias Rempe (Oelde) provided ideas, Windows support, and quality
@@ -21173,7 +21505,7 @@ be complete if the ones above were not mentioned in this manual.
literal examples, and remote highlighting for referenced code lines.
- Stathis Sideris wrote the =ditaa.jar= ASCII to PNG converter that is
- now packaged into Org's =contrib/= directory.
+ now packaged into the [[https://git.sr.ht/~bzg/org-contrib][org-contrib]] repository.
- Daniel Sinder came up with the idea of internal archiving by locking
subtrees.
@@ -21296,7 +21628,7 @@ modify this GNU manual."
* Footnotes
[fn:1] If you do not use Font Lock globally turn it on in Org buffer
-with =(add-hook 'org-mode-hook 'turn-on-font-lock)=.
+with =(add-hook 'org-mode-hook #'turn-on-font-lock)=.
[fn:2] Please consider subscribing to the mailing list in order to
minimize the work the mailing list moderators have to do.
@@ -21597,12 +21929,12 @@ lognoteclock-out=.
line---the line is broken here only to fit it into the manual.
[fn:81] On computers using macOS, idleness is based on actual user
-idleness, not just Emacs' idle time. For X11, you can install
-a utility program =x11idle.c=, available in the =contrib/scripts/=
-directory of the Org Git distribution, or install the xprintidle
-package and set it to the variable ~org-clock-x11idle-program-name~ if
-you are running Debian, to get the same general treatment of idleness.
-On other systems, idle time refers to Emacs idle time only.
+idleness, not just Emacs' idle time. For X11, you can install a
+utility program =x11idle.c=, available in the =org-contrib/=
+repository, or install the xprintidle package and set it to the
+variable ~org-clock-x11idle-program-name~ if you are running Debian,
+to get the same general treatment of idleness. On other systems, idle
+time refers to Emacs idle time only.
[fn:82] Please note the pitfalls of summing hierarchical data in
a flat list (see [[*Using Column View in the Agenda]]).
@@ -21733,7 +22065,7 @@ a fragment, see the documentation of the function
version 1.34 of the =htmlize.el= package, which you need to install).
Fontified code chunks in LaTeX can be achieved using either the
[[https://www.ctan.org/pkg/listings][listings]] package or the [[https://www.ctan.org/pkg/minted][minted]] package. Refer to
-~org-export-latex-listings~ for details.
+~org-latex-listings~ for details.
[fn:115] Source code in code blocks may also be evaluated either
interactively or on export. See [[*Working with Source Code]] for more
@@ -21762,7 +22094,9 @@ and =#+STARTUP: nofnadjust=.
[fn:122] The variable ~org-export-date-timestamp-format~ defines how
this timestamp are exported.
-[fn:123] DEFINITION NOT FOUND.
+[fn:123] For export to LaTeX format---or LaTeX-related formats such as
+Beamer---, the =org-latex-package-alist= variable needs further
+configuration. See [[LaTeX specific export settings]].
[fn:124] At the moment, some export back-ends do not obey this
specification. For example, LaTeX export excludes every unnumbered
@@ -21785,7 +22119,7 @@ to make it visible. The tag serves as a visual aid and has no
semantic relevance.
[fn:129] By default Org loads MathJax from [[https://cdnjs.com][cdnjs.com]] as recommended by
-[[http://www.mathjax.org][MathJax]].
+[[https://www.mathjax.org][MathJax]].
[fn:130] Please note that exported formulas are part of an HTML
document, and that signs such as =<=, =>=, or =&= have special
@@ -21802,93 +22136,89 @@ use the variables ~org-html-todo-kwd-class-prefix~ and
for different files. However, "smart" LaTeX compilation systems, such
as latexmk, can select the correct bibliography compiler.
-[fn:134] See [[http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html][Open Document Format for Office Applications
+[fn:134] Minted uses an external Python package for code highlighting,
+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
(OpenDocument) Version 1.2]].
-[fn:135] See [[http://www.mathtoweb.com/cgi-bin/mathtoweb_home.pl][MathToWeb]].
+[fn:136] See [[http://www.mathtoweb.com/cgi-bin/mathtoweb_home.pl][MathToWeb]].
-[fn:136] See [[http://dlmf.nist.gov/LaTeXML/]].
+[fn:137] See [[http://dlmf.nist.gov/LaTeXML/]].
-[fn:137] [[http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html][OpenDocument-v1.2 Specification]]
+[fn:138] [[http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html][OpenDocument-v1.2 Specification]]
-[fn:138] See the =<table:table-template>= element of the
+[fn:139] See the =<table:table-template>= element of the
OpenDocument-v1.2 specification.
-[fn:139] See the attributes =table:template-name=,
+[fn:140] See the attributes =table:template-name=,
=table:use-first-row-styles=, =table:use-last-row-styles=,
=table:use-first-column-styles=, =table:use-last-column-styles=,
=table:use-banding-rows-styles=, and =table:use-banding-column-styles=
of the =<table:table>= element in the OpenDocument-v1.2 specification.
-[fn:140] If the publishing directory is the same as the source
+[fn:141] If the publishing directory is the same as the source
directory, =file.org= is exported as =file.org.org=, so you probably
do not want to do this.
-[fn:141] The option ~org-babel-no-eval-on-ctrl-c-ctrl-c~ can be used
+[fn:142] The option ~org-babel-no-eval-on-ctrl-c-ctrl-c~ can be used
to remove code evaluation from the {{{kbd(C-c C-c)}}} key binding.
-[fn:142] Actually, the constructs =call_<name>()= and =src_<lang>{}=
+[fn:143] Actually, the constructs =call_<name>()= and =src_<lang>{}=
are not evaluated when they appear in a keyword (see [[*Summary of
In-Buffer Settings]]).
-[fn:143] C++ language is handled in =ob-C.el=. Even though the
-identifier for such source blocks is =C++=, you activate it by loading
-the C language.
-
-[fn:144] D language is handled in =ob-C.el=. Even though the
-identifier for such source blocks is =D=, you activate it by loading
-the C language.
-
-[fn:145] For noweb literate programming details, see
+[fn:144] For noweb literate programming details, see
http://www.cs.tufts.edu/~nr/noweb/.
-[fn:146] For more information, please refer to the commentary section
+[fn:145] For more information, please refer to the commentary section
in =org-tempo.el=.
-[fn:147] Org Indent mode also sets ~wrap-prefix~ correctly for
+[fn:146] Org Indent mode also sets ~wrap-prefix~ correctly for
indenting and wrapping long lines of headlines or text. This minor
mode also handles Visual Line mode and directly applied settings
through ~word-wrap~.
-[fn:148] This works, but requires extra effort. Org Indent mode is
+[fn:147] This works, but requires extra effort. Org Indent mode is
more convenient for most applications.
-[fn:149] ~org-adapt-indentation~ can also be set to ='headline-data=,
+[fn:148] ~org-adapt-indentation~ can also be set to ='headline-data=,
in which case only data lines below the headline will be indented.
-[fn:150] Note that Org Indent mode also sets the ~wrap-prefix~
+[fn:149] Note that Org Indent mode also sets the ~wrap-prefix~
property, such that Visual Line mode (or purely setting ~word-wrap~)
wraps long lines, including headlines, correctly indented.
-[fn:151] For a server to host files, consider using a WebDAV server,
+[fn:150] For a server to host files, consider using a WebDAV server,
such as [[https://nextcloud.com][Nextcloud]]. Additional help is at this [[https://orgmode.org/worg/org-faq.html#mobileorg_webdav][FAQ entry]].
-[fn:152] If Emacs is configured for safe storing of passwords, then
+[fn:151] If Emacs is configured for safe storing of passwords, then
configure the variable ~org-mobile-encryption-password~; please read
the docstring of that variable.
-[fn:153] Symbolic links in ~org-directory~ need to have the same name
+[fn:152] Symbolic links in ~org-directory~ need to have the same name
as their targets.
-[fn:154] While creating the agendas, Org mode forces =ID= properties
+[fn:153] While creating the agendas, Org mode forces =ID= properties
on all referenced entries, so that these entries can be uniquely
identified if Org Mobile flags them for further action. To avoid
setting properties configure the variable
~org-mobile-force-id-on-agenda-items~ to ~nil~. Org mode then relies
on outline paths, assuming they are unique.
-[fn:155] Checksums are stored automatically in the file
+[fn:154] Checksums are stored automatically in the file
=checksums.dat=.
-[fn:156] The file will be empty after this operation.
+[fn:155] The file will be empty after this operation.
-[fn:157] https://www.ctan.org/pkg/comment
+[fn:156] https://www.ctan.org/pkg/comment
-[fn:158] By default this works only for LaTeX, HTML, and Texinfo.
+[fn:157] By default this works only for LaTeX, HTML, and Texinfo.
Configure the variable ~orgtbl-radio-table-templates~ to install
templates for other modes.
-[fn:159] If the =TBLFM= keyword contains an odd number of dollar
+[fn:158] If the =TBLFM= keyword contains an odd number of dollar
characters, this may cause problems with Font Lock in LaTeX mode. As
shown in the example you can fix this by adding an extra line inside
the =comment= environment that is used to balance the dollar
@@ -21896,9 +22226,9 @@ expressions. If you are using AUCTeX with the font-latex library,
a much better solution is to add the =comment= environment to the
variable ~LaTeX-verbatim-environments~.
-[fn:160] The ~agenda*~ view is the same as ~agenda~ except that it
+[fn:159] The ~agenda*~ view is the same as ~agenda~ except that it
only considers /appointments/, i.e., scheduled and deadline items that
have a time specification =[h]h:mm= in their time-stamps.
-[fn:161] Note that, for ~org-odd-levels-only~, a level number
+[fn:160] Note that, for ~org-odd-levels-only~, a level number
corresponds to order in the hierarchy, not to the number of stars.
diff --git a/doc/misc/pcl-cvs.texi b/doc/misc/pcl-cvs.texi
index 4ba067fd81f..833326c089b 100644
--- a/doc/misc/pcl-cvs.texi
+++ b/doc/misc/pcl-cvs.texi
@@ -524,8 +524,8 @@ you can use in PCL-CVS@. They are grouped together by type.
Most commands in PCL-CVS require that you have a @file{*cvs*}
buffer. The commands that you use to get one are listed below.
For each, a @samp{cvs} process will be run, the output will be parsed by
-PCL-CVS, and the result will be printed in the @file{*cvs*} buffer (see
-@ref{Buffer contents}, for a description of the buffer's contents).
+PCL-CVS, and the result will be printed in the @file{*cvs*} buffer
+(@pxref{Buffer contents}, for a description of the buffer's contents).
@table @kbd
@item M-x cvs-update
diff --git a/doc/misc/pgg.texi b/doc/misc/pgg.texi
index 82495275fca..e796da6da37 100644
--- a/doc/misc/pgg.texi
+++ b/doc/misc/pgg.texi
@@ -27,7 +27,8 @@ modify this GNU manual.''
@dircategory Emacs network features
@direntry
-* PGG: (pgg). Emacs interface to various PGP implementations.
+* PGG: (pgg). An obsolete Emacs interface to various
+ PGP implementations.
@end direntry
@titlepage
diff --git a/doc/misc/rcirc.texi b/doc/misc/rcirc.texi
index ae3a3b13e62..f03f614275c 100644
--- a/doc/misc/rcirc.texi
+++ b/doc/misc/rcirc.texi
@@ -254,6 +254,10 @@ To make this permanent, add the following to your init file:
Use @kbd{C-c C-@key{SPC}} to switch to these buffers.
+@vindex rcirc-track-ignore-server-buffer-flag
+If the user wishes to ignore events in the server buffer, set
+@code{rcirc-track-ignore-server-buffer-flag} to a non-nil value.
+
@node Reference
@chapter Reference
@cindex reference
@@ -426,7 +430,13 @@ lost. The simple solution is to use @kbd{M-x rcirc}. The problem is
that this opens an @emph{additional} connection, so you'll have two
copies of every channel buffer, one dead and one live.
-The real answer, therefore, is the @code{/reconnect} command.
+One option therefore, is the @code{/reconnect} command.
+
+An other approach is to set @code{rcirc-reconnect-delay} to a value
+greater than 0, and allow rcirc to reconnect when it detects that the
+connection has been closed. By default it will try to do this three
+times (as specified by @code{rcirc-reconnect-attempts}), before giving
+up.
@end table
@node Useful IRC commands
@@ -454,7 +464,7 @@ your status as ``being back'' if you do not. People can use the
@cindex help about irc
Typical IRC servers implement many more commands. You can read more
about the fantastic world of IRC online at
-@uref{http://www.irchelp.org/, the Internet Relay Chat (IRC) help
+@uref{https://www.irchelp.org/, the Internet Relay Chat (IRC) help
archive}.
@node Configuration
@@ -599,12 +609,6 @@ Use this symbol if you need to identify yourself in the Bitlbee channel
as follows: @code{identify secret}. The necessary arguments are the
nickname you want to use this for, and the password to use.
-@item sasl
-@cindex sasl authentication
-Use this symbol if you want to use @acronym{SASL} authentication. The
-necessary arguments are the nickname you want to use this for, and the
-password to use.
-
@cindex gateway to other IM services
@cindex instant messaging, other services
@cindex Jabber
@@ -623,6 +627,19 @@ the other instant messaging services, and Bitlbee will log you in. All
@code{rcirc} needs to know, is the login to your Bitlbee account. Don't
confuse the Bitlbee account with all the other accounts.
+@item sasl
+@cindex sasl authentication
+Use this symbol if you want to use @acronym{SASL} authentication. The
+necessary arguments are the nickname you want to use this for, and the
+password to use.
+
+@item certfp
+@cindex certfp authentication
+Use this symbol if you want to use CertFP authentication. The
+necessary arguments are the path to the client certificate key and
+password. The CertFP authentication requires a @acronym{TLS}
+connection.
+
@end table
@end table
@@ -671,6 +688,12 @@ window is showing them), the mode line will now show you the abbreviated
channel or nick name. Use @kbd{C-c C-@key{SPC}} to switch to these
buffers.
+@cindex rcirc-track-abbrevate-flag
+By default the channel names are abbreviated, set
+@code{rcirc-track-abbrevate-flag} to a non-nil value. This might be
+interesting if the IRC activities are not tracked in the mode line,
+but somewhere else.
+
@vindex rcirc-mode-hook
If you prefer not to load @code{rcirc} immediately, you can delay the
activation of this mode:
@@ -807,6 +830,19 @@ active and only omits a message if the nick has not been active. The
window @code{rcirc} considers is controlled by the
@code{rcirc-omit-threshold} variable.
+@vindex rcirc-omit-unless-requested
+Certain messages can be omitted by default, unless the user manual
+requests them. For example, if you don't want to display @code{TOPIC}
+and @code{NAMES} messages, after reconnecting, you can configure
+@code{rcirc-omit-unless-requested} to hide:
+
+@example
+(setq rcirc-omit-unless-requested '("TOPIC" "NAMES"))
+@end example
+
+Now NAMES will only be displayed, after it has been requested via the
+@code{rcirc-cmd-name} command.
+
@node Hacking and Tweaking
@chapter Hacking and Tweaking
@cindex hacking and tweaking
@@ -819,6 +855,7 @@ Here are some examples of stuff you can do to configure @code{rcirc}.
* Scrolling conservatively::
* Changing the time stamp format::
* Defining a new command::
+* Using rcirc with bouncers::
@end menu
@node Skipping /away messages using handlers
@@ -903,20 +940,48 @@ how to include the date in the time stamp:
@cindex new commands, defining
Here's a simple new command, @code{/sv}. With it, you can boast about
-your IRC client. It shows how you can use @code{defun-rcirc-command} to
+your IRC client. It shows how you can use @code{rcirc-define-command} to
define new commands.
+@findex rcirc-define-command
We're waiting for the definition of this command until @code{rcirc} is loaded
-because @code{defun-rcirc-command} is not yet available, and without
+because @code{rcirc-define-command} is not yet available, and without
@code{rcirc} loaded, the command wouldn't do us much good anyway.
@smallexample
(with-eval-after-load 'rcirc
- (defun-rcirc-command sv (arg)
+ (rcirc-define-command sv ()
"Boast about rcirc."
(interactive "i")
- (rcirc-send-message process target
- (concat "I use " rcirc-id-string))))
+ (rcirc-send-message process target "I use " rcirc-id-string)))
+@end smallexample
+
+@node Using rcirc with bouncers
+@section Using rcirc with bouncers
+@cindex bouncer
+
+Some bouncers multiplex connections to various servers, but have to
+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,
+these will be used to change how nicks and channel names are
+displayed. A simple configuration to fix the above example might be:
+
+@smallexample
+(defun my/rcirc-remove-suffix (STR)
+ "Remove suffixes from STR."
+ (save-match-data
+ (if (string-match "/[[:alpha:]]+?\\'" str)
+ (substring str 0 (match-beginning 0))
+ str)))
+
+(setq rcirc-nick-filter #'my/rcirc-remove-suffix
+ rcirc-channel-filter #'local/rcirc-soju-suffix)
@end smallexample
@node GNU Free Documentation License
diff --git a/doc/misc/reftex.texi b/doc/misc/reftex.texi
index 88ca4450d59..8bde241e18f 100644
--- a/doc/misc/reftex.texi
+++ b/doc/misc/reftex.texi
@@ -658,9 +658,9 @@ variable @code{reftex-auto-recenter-toc}.
@end table
-@vindex reftex-toc-map
+@vindex reftex-toc-mode-map
In order to define additional commands for the @file{*toc*} buffer, the
-keymap @code{reftex-toc-map} may be used.
+keymap @code{reftex-toc-mode-map} may be used.
@findex reftex-toc-recenter
@vindex reftex-auto-recenter-toc
@@ -1021,9 +1021,9 @@ document and let you select a label from there (@pxref{LaTeX xr Package,,xr}).
@end table
-@vindex reftex-select-label-map
+@vindex reftex-select-label-mode-map
In order to define additional commands for the selection process, the
-keymap @code{reftex-select-label-map} may be used.
+keymap @code{reftex-select-label-mode-map} may be used.
@node Builtin Label Environments
@section Builtin Label Environments
@@ -1871,9 +1871,9 @@ entries.
@end table
-@vindex reftex-select-bib-map
+@vindex reftex-select-bib-mode-map
In order to define additional commands for this selection process, the
-keymap @code{reftex-select-bib-map} may be used.
+keymap @code{reftex-select-bib-mode-map} may be used.
Note that if you do not use Emacs to edit the @BibTeX{} database files,
@RefTeX{} will ask if the related buffers should be updated once it
@@ -3192,7 +3192,7 @@ with the @kbd{g} key. To get this behavior, use instead
@AUCTeX{} is without doubt the best major mode for editing @TeX{} and @LaTeX{}
files with Emacs (@pxref{Top,AUCTeX,,auctex, The AUCTeX User Manual}).
-You can get it from its home page at @value{AUCTEXSITE}, but since
+You can get it from its website at @value{AUCTEXSITE}, but since
it is available from GNU ELPA, you can simply install it from @kbd{M-x
list-packages}.
@@ -3565,7 +3565,7 @@ With @i{Viper} mode prior to Vipers version 3.01, you need to protect
@cindex Acknowledgments
@cindex Thanks
@cindex Bug reports
-@cindex @code{http}, @RefTeX{} home page
+@cindex @code{http}, @RefTeX{} website
@cindex @code{ftp}, @RefTeX{} site
@c dominik@@science.uva.nl
@@ -3960,7 +3960,7 @@ Normal hook which is run when a @file{*toc*} buffer is
created.
@end deffn
-@deffn Keymap reftex-toc-map
+@deffn Keymap reftex-toc-mode-map
The keymap which is active in the @file{*toc*} buffer.
(@pxref{Table of Contents}).
@end deffn
@@ -4425,7 +4425,7 @@ Normal hook which is run when a selection buffer enters
@code{reftex-select-label-mode}.
@end deffn
-@deffn Keymap reftex-select-label-map
+@deffn Keymap reftex-select-label-mode-map
The keymap which is active in the labels selection process
(@pxref{Referencing Labels}).
@end deffn
@@ -4586,7 +4586,7 @@ Normal hook which is run when a selection buffer enters
@code{reftex-select-bib-mode}.
@end deffn
-@deffn Keymap reftex-select-bib-map
+@deffn Keymap reftex-select-bib-mode-map
The keymap which is active in the citation-key selection process
(@pxref{Creating Citations}).
@end deffn
@@ -4792,7 +4792,7 @@ into blocks. Sorting will then preserve blocks, so that lines are
re-arranged only within blocks.
@end defopt
-@defopt reftex-index-phrases-map
+@defopt reftex-index-phrases-mode-map
Keymap for the Index Phrases buffer.
@end defopt
@@ -4824,7 +4824,7 @@ the document. This flag can be toggled from within the @file{*Index*}
buffer with the @kbd{f} key.
@end defopt
-@deffn Keymap reftex-index-map
+@deffn Keymap reftex-index-mode-map
The keymap which is active in the @file{*Index*} buffer
(@pxref{Index Support}).
@end deffn
@@ -5813,8 +5813,8 @@ buffer).
@noindent @b{Version 3.12}
@itemize @bullet
@item
-There are 3 new keymaps for customization: @code{reftex-toc-map},
-@code{reftex-select-label-map}, @code{reftex-select-bib-map}.
+There are 3 new keymaps for customization: @code{reftex-toc-mode-map},
+@code{reftex-select-label-mode-map}, @code{reftex-select-bib-mode-map}.
@item
Refontification uses more standard font-lock stuff.
@item
diff --git a/doc/misc/speedbar.texi b/doc/misc/speedbar.texi
index 9991917b3fd..70d4b054166 100644
--- a/doc/misc/speedbar.texi
+++ b/doc/misc/speedbar.texi
@@ -896,7 +896,7 @@ augmented with speedbar.
@enumerate
@item
-Create the keymap variable @code{@var{name}-speedbar-key-map}.
+Create the keymap variable @code{@var{name}-speedbar-mode-map}.
@item
Create a function, named whatever you like, which assigns values into your
@@ -904,7 +904,7 @@ keymap. Use this command to create the keymap before assigning
bindings:
@smallexample
- (setq @var{name}-speedbar-key-map (speedbar-make-specialized-keymap))
+ (setq @var{name}-speedbar-mode-map (speedbar-make-specialized-keymap))
@end smallexample
This function creates a special keymap for use in speedbar.
@@ -977,7 +977,7 @@ Next, register your extension like this;
@example
(speedbar-add-expansion-list '("MyExtension"
MyExtension-speedbar-menu-items
- MyExtension-speedbar-key-map
+ MyExtension-speedbar-mode-map
MyExtension-speedbar-buttons))
@end example
diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex
index a91181b116e..e48383defc4 100644
--- a/doc/misc/texinfo.tex
+++ b/doc/misc/texinfo.tex
@@ -3,9 +3,9 @@
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
-\def\texinfoversion{2020-11-25.18}
+\def\texinfoversion{2021-04-25.21}
%
-% Copyright 1985, 1986, 1988, 1990-2020 Free Software Foundation, Inc.
+% Copyright 1985, 1986, 1988, 1990-2021 Free Software Foundation, Inc.
%
% This texinfo.tex file is free software: you can redistribute it and/or
% modify it under the terms of the GNU General Public License as
@@ -574,7 +574,7 @@
% @end foo calls \checkenv and executes the definition of \Efoo.
-\parseargdef\end{
+\parseargdef\end{%
\if 1\csname iscond.#1\endcsname
\else
% The general wording of \badenverr may not be ideal.
@@ -1002,6 +1002,14 @@ where each line of input produces a line of output.}
\global\everypar = {}%
}
+% leave vertical mode without cancelling any first paragraph indent
+\gdef\imageindent{%
+ \toks0=\everypar
+ \everypar={}%
+ \ptexnoindent
+ \global\everypar=\toks0
+}
+
% @refill is a no-op.
\let\refill=\relax
@@ -1181,7 +1189,7 @@ where each line of input produces a line of output.}
% double any backslashes. Otherwise, a name like "\node" will be
% interpreted as a newline (\n), followed by o, d, e. Not good.
%
-% See https://mailman.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and
+% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and
% related messages. The final outcome is that it is up to the TeX user
% to double the backslashes and otherwise make the string valid, so
% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to
@@ -1862,19 +1870,23 @@ output) for that.)}
\closein 1
\endgroup
%
- \def\xetexpdfext{pdf}%
- \ifx\xeteximgext\xetexpdfext
- \XeTeXpdffile "#1".\xeteximgext ""
- \else
- \def\xetexpdfext{PDF}%
+ % Putting an \hbox around the image can prevent an over-long line
+ % after the image.
+ \hbox\bgroup
+ \def\xetexpdfext{pdf}%
\ifx\xeteximgext\xetexpdfext
\XeTeXpdffile "#1".\xeteximgext ""
\else
- \XeTeXpicfile "#1".\xeteximgext ""
+ \def\xetexpdfext{PDF}%
+ \ifx\xeteximgext\xetexpdfext
+ \XeTeXpdffile "#1".\xeteximgext ""
+ \else
+ \XeTeXpicfile "#1".\xeteximgext ""
+ \fi
\fi
- \fi
- \ifdim \wd0 >0pt width \xeteximagewidth \fi
- \ifdim \wd2 >0pt height \xeteximageheight \fi \relax
+ \ifdim \wd0 >0pt width \xeteximagewidth \fi
+ \ifdim \wd2 >0pt height \xeteximageheight \fi \relax
+ \egroup
}
\fi
@@ -3539,7 +3551,7 @@ $$%
% We use the free feym* fonts from the eurosym package by Henrik
% Theiling, which support regular, slanted, bold and bold slanted (and
% "outlined" (blackboard board, sort of) versions, which we don't need).
-% It is available from https://www.ctan.org/tex-archive/fonts/eurosym.
+% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
%
% Although only regular is the truly official Euro symbol, we ignore
% that. The Euro is designed to be slightly taller than the regular
@@ -4289,82 +4301,8 @@ $$%
\doitemize{#1.}\flushcr
}
-% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
-% to @enumerate.
-%
-\def\alphaenumerate{\enumerate{a}}
-\def\capsenumerate{\enumerate{A}}
-\def\Ealphaenumerate{\Eenumerate}
-\def\Ecapsenumerate{\Eenumerate}
-
% @multitable macros
-% Amy Hendrickson, 8/18/94, 3/6/96
-%
-% @multitable ... @end multitable will make as many columns as desired.
-% Contents of each column will wrap at width given in preamble. Width
-% can be specified either with sample text given in a template line,
-% or in percent of \hsize, the current width of text on page.
-
-% Table can continue over pages but will only break between lines.
-
-% To make preamble:
-%
-% Either define widths of columns in terms of percent of \hsize:
-% @multitable @columnfractions .25 .3 .45
-% @item ...
-%
-% Numbers following @columnfractions are the percent of the total
-% current hsize to be used for each column. You may use as many
-% columns as desired.
-
-
-% Or use a template:
-% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
-% @item ...
-% using the widest term desired in each column.
-
-% Each new table line starts with @item, each subsequent new column
-% starts with @tab. Empty columns may be produced by supplying @tab's
-% with nothing between them for as many times as empty columns are needed,
-% ie, @tab@tab@tab will produce two empty columns.
-
-% @item, @tab do not need to be on their own lines, but it will not hurt
-% if they are.
-
-% Sample multitable:
-
-% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
-% @item first col stuff @tab second col stuff @tab third col
-% @item
-% first col stuff
-% @tab
-% second col stuff
-% @tab
-% third col
-% @item first col stuff @tab second col stuff
-% @tab Many paragraphs of text may be used in any column.
-%
-% They will wrap at the width determined by the template.
-% @item@tab@tab This will be in third column.
-% @end multitable
-
-% Default dimensions may be reset by user.
-% @multitableparskip is vertical space between paragraphs in table.
-% @multitableparindent is paragraph indent in table.
-% @multitablecolmargin is horizontal space to be left between columns.
-% @multitablelinespace is space to leave between table items, baseline
-% to baseline.
-% 0pt means it depends on current normal line spacing.
-%
-\newskip\multitableparskip
-\newskip\multitableparindent
-\newdimen\multitablecolspace
-\newskip\multitablelinespace
-\multitableparskip=0pt
-\multitableparindent=6pt
-\multitablecolspace=12pt
-\multitablelinespace=0pt
% Macros used to set up halign preamble:
%
@@ -4412,8 +4350,6 @@ $$%
\go
}
-% multitable-only commands.
-%
% @headitem starts a heading row, which we typeset in bold. Assignments
% have to be global since we are inside the implicit group of an
% alignment entry. \everycr below resets \everytab so we don't have to
@@ -4430,14 +4366,8 @@ $$%
% default for tables with no headings.
\let\headitemcrhook=\relax
%
-% A \tab used to include \hskip1sp. But then the space in a template
-% line is not enough. That is bad. So let's go back to just `&' until
-% we again encounter the problem the 1sp was intended to solve.
-% --karl, nathan@acm.org, 20apr99.
\def\tab{\checkenv\multitable &\the\everytab}%
-% @multitable ... @end multitable definitions:
-%
\newtoks\everytab % insert after every tab.
%
\envdef\multitable{%
@@ -4452,9 +4382,8 @@ $$%
%
\tolerance=9500
\hbadness=9500
- \setmultitablespacing
- \parskip=\multitableparskip
- \parindent=\multitableparindent
+ \parskip=0pt
+ \parindent=6pt
\overfullrule=0pt
\global\colcount=0
%
@@ -4484,47 +4413,24 @@ $$%
% continue for many paragraphs if desired.
\halign\bgroup &%
\global\advance\colcount by 1
- \multistrut
+ \strut
\vtop{%
- % Use the current \colcount to find the correct column width:
+ \advance\hsize by -1\leftskip
+ % Find the correct column width
\hsize=\expandafter\csname col\the\colcount\endcsname
%
- % In order to keep entries from bumping into each other
- % we will add a \leftskip of \multitablecolspace to all columns after
- % the first one.
- %
- % If a template has been used, we will add \multitablecolspace
- % to the width of each template entry.
- %
- % If the user has set preamble in terms of percent of \hsize we will
- % use that dimension as the width of the column, and the \leftskip
- % will keep entries from bumping into each other. Table will start at
- % left margin and final column will justify at right margin.
- %
- % Make sure we don't inherit \rightskip from the outer environment.
\rightskip=0pt
\ifnum\colcount=1
- % The first column will be indented with the surrounding text.
- \advance\hsize by\leftskip
+ \advance\hsize by\leftskip % Add indent of surrounding text
\else
- \ifsetpercent \else
- % If user has not set preamble in terms of percent of \hsize
- % we will advance \hsize by \multitablecolspace.
- \advance\hsize by \multitablecolspace
- \fi
- % In either case we will make \leftskip=\multitablecolspace:
- \leftskip=\multitablecolspace
+ % In order to keep entries from bumping into each other.
+ \leftskip=12pt
+ \ifsetpercent \else
+ % If a template has been used
+ \advance\hsize by \leftskip
+ \fi
\fi
- % Ignoring space at the beginning and end avoids an occasional spurious
- % blank line, when TeX decides to break the line at the space before the
- % box from the multistrut, so the strut ends up on a line by itself.
- % For example:
- % @multitable @columnfractions .11 .89
- % @item @code{#}
- % @tab Legal holiday which is valid in major parts of the whole country.
- % Is automatically provided with highlighting sequences respectively
- % marking characters.
- \noindent\ignorespaces##\unskip\multistrut
+ \noindent\ignorespaces##\unskip\strut
}\cr
}
\def\Emultitable{%
@@ -4533,31 +4439,6 @@ $$%
\global\setpercentfalse
}
-\def\setmultitablespacing{%
- \def\multistrut{\strut}% just use the standard line spacing
- %
- % Compute \multitablelinespace (if not defined by user) for use in
- % \multitableparskip calculation. We used define \multistrut based on
- % this, but (ironically) that caused the spacing to be off.
- % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
-\ifdim\multitablelinespace=0pt
-\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
-\global\advance\multitablelinespace by-\ht0
-\fi
-% Test to see if parskip is larger than space between lines of
-% table. If not, do nothing.
-% If so, set to same dimension as multitablelinespace.
-\ifdim\multitableparskip>\multitablelinespace
-\global\multitableparskip=\multitablelinespace
-\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
- % than skip between lines in the table.
-\fi%
-\ifdim\multitableparskip=0pt
-\global\multitableparskip=\multitablelinespace
-\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
- % than skip between lines in the table.
-\fi}
-
\message{conditionals,}
@@ -5171,30 +5052,29 @@ $$%
\let\lbracechar\{%
\let\rbracechar\}%
%
+ % Non-English letters.
+ \def\AA{AA}%
+ \def\AE{AE}%
+ \def\DH{DZZ}%
+ \def\L{L}%
+ \def\OE{OE}%
+ \def\O{O}%
+ \def\TH{TH}%
+ \def\aa{aa}%
+ \def\ae{ae}%
+ \def\dh{dzz}%
+ \def\exclamdown{!}%
+ \def\l{l}%
+ \def\oe{oe}%
+ \def\ordf{a}%
+ \def\ordm{o}%
+ \def\o{o}%
+ \def\questiondown{?}%
+ \def\ss{ss}%
+ \def\th{th}%
%
\let\do\indexnofontsdef
%
- % Non-English letters.
- \do\AA{AA}%
- \do\AE{AE}%
- \do\DH{DZZ}%
- \do\L{L}%
- \do\OE{OE}%
- \do\O{O}%
- \do\TH{TH}%
- \do\aa{aa}%
- \do\ae{ae}%
- \do\dh{dzz}%
- \do\exclamdown{!}%
- \do\l{l}%
- \do\oe{oe}%
- \do\ordf{a}%
- \do\ordm{o}%
- \do\o{o}%
- \do\questiondown{?}%
- \do\ss{ss}%
- \do\th{th}%
- %
\do\LaTeX{LaTeX}%
\do\TeX{TeX}%
%
@@ -8931,7 +8811,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\else
\ifhavexrefs
% We (should) know the real title if we have the xref values.
- \def\printedrefname{\refx{#1-title}{}}%
+ \def\printedrefname{\refx{#1-title}}%
\else
% Otherwise just copy the Info node name.
\def\printedrefname{\ignorespaces #1}%
@@ -9025,7 +8905,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% If the user specified the print name (third arg) to the ref,
% print it instead of our usual "Figure 1.2".
\ifdim\wd\printedrefnamebox = 0pt
- \refx{#1-snt}{}%
+ \refx{#1-snt}%
\else
\printedrefname
\fi
@@ -9060,9 +8940,9 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\else
% Reference within this manual.
%
- % Only output a following space if the -snt ref is nonempty; for
- % @unnumbered and @anchor, it won't be.
- \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+ % Only output a following space if the -snt ref is nonempty, as the ref
+ % will be empty for @unnumbered and @anchor.
+ \setbox2 = \hbox{\ignorespaces \refx{#1-snt}}%
\ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
%
% output the `[mynode]' via the macro below so it can be overridden.
@@ -9073,7 +8953,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
,\space
%
% output the `page 3'.
- \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+ \turnoffactive \putwordpage\tie\refx{#1-pg}%
% Add a , if xref followed by a space
\if\space\noexpand\tokenafterxref ,%
\else\ifx\ \tokenafterxref ,% @TAB
@@ -9150,9 +9030,8 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\fi\fi\fi
}
-% \refx{NAME}{SUFFIX} - reference a cross-reference string named NAME. SUFFIX
-% is output afterwards if non-empty.
-\def\refx#1#2{%
+% \refx{NAME} - reference a cross-reference string named NAME.
+\def\refx#1{%
\requireauxfile
{%
\indexnofonts
@@ -9179,7 +9058,6 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% It's defined, so just use it.
\thisrefX
\fi
- #2% Output the suffix in any case.
}
% This is the macro invoked by entries in the aux file. Define a control
@@ -9289,10 +9167,10 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\catcode`\[=\other
\catcode`\]=\other
\catcode`\"=\other
- \catcode`\_=\other
- \catcode`\|=\other
- \catcode`\<=\other
- \catcode`\>=\other
+ \catcode`\_=\active
+ \catcode`\|=\active
+ \catcode`\<=\active
+ \catcode`\>=\active
\catcode`\$=\other
\catcode`\#=\other
\catcode`\&=\other
@@ -9539,7 +9417,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% On the other hand, if we are in the case of @center @image, we don't
% want to start a paragraph, which will create a hsize-width box and
% eradicate the centering.
- \ifx\centersub\centerV\else \noindent \fi
+ \ifx\centersub\centerV \else \imageindent \fi
%
% Output the image.
\ifpdf
@@ -11731,3 +11609,4 @@ directory should work if nowhere else does.}
@c vim:sw=2:
@enablebackslashhack
+
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index bd9bd998dfb..86f4d1c38eb 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -290,7 +290,7 @@ file's contents.
For external transfers, @value{tramp} sends a command as follows:
@example
-rcp user@@host:/path/to/remote/file /tmp/tramp.4711
+$ rcp user@@host:/path/to/remote/file /tmp/tramp.4711
@end example
@value{tramp} reads the local temporary file @file{/tmp/tramp.4711}
into a buffer, and then deletes the temporary file.
@@ -1071,7 +1071,7 @@ capable of servicing requests from @value{tramp}.
This non-native @value{tramp} method connects via the Server Message
Block (SMB) networking protocol to hosts running file servers that are
-typically based on @url{https://www.samba.org/,,Samba} or MS Windows.
+typically based on @uref{https://www.samba.org/,,Samba} or MS Windows.
Using @command{smbclient} requires a few tweaks when working with
@value{tramp}:
@@ -1323,7 +1323,7 @@ possible, @value{tramp} emulates those operations otherwise.
@vindex tramp-rclone-program
The program @command{rclone} allows to access different system
-storages in the cloud, see @url{https://rclone.org/} for a list of
+storages in the cloud, see @uref{https://rclone.org/} for a list of
supported systems. If the @command{rclone} program isn't found in
your @env{PATH} environment variable, you can tell @value{tramp} its
absolute path via the user option @code{tramp-rclone-program}.
@@ -1362,7 +1362,7 @@ for accessing the system storage, you should use it.
On local hosts which have installed the @command{sshfs} client for
mounting a file system based on @command{sftp}, this method can be
used, see
-@url{https://github.com/libfuse/sshfs/blob/master/README.rst/}. If
+@uref{https://github.com/libfuse/sshfs/blob/master/README.rst/}. If
the @command{sshfs} program isn't found in your @env{PATH} environment
variable, you can tell @value{tramp} its absolute path via the user
option @code{tramp-sshfs-program}.
@@ -2238,8 +2238,7 @@ preserves the path value, which can be used to update
shell supports the login argument @samp{-l}.
@end defopt
-Starting with @w{Emacs 26}, @code{tramp-remote-path} can be set per
-host via connection-local
+@code{tramp-remote-path} can also be set per host via connection-local
@ifinfo
variables, @xref{Connection Variables, , , emacs}.
@end ifinfo
@@ -2610,7 +2609,7 @@ where @samp{192.168.0.1} is the remote host IP address
@node FUSE setup
@section @acronym{FUSE} setup hints
-The @acronym{FUSE} file systems are mounted per default at
+The @acronym{FUSE} file systems are mounted by default at
@file{/tmp/tramp.method.user@@host#port}. The user name and port
number are optional. If the file system is already mounted, it will
be used as it is. If the mount point does not exist yet,
@@ -2629,6 +2628,11 @@ Example:
@end group
@end lisp
+@vindex tramp-fuse-unmount-on-cleanup
+The user option @code{tramp-fuse-unmount-on-cleanup}, when set to
+non-@code{nil}, controls, whether a mount point is unmounted on
+connection cleanup or on Emacs exiting.
+
@anchor{Setup of rclone method}
@subsection @option{rclone} setup
@@ -3231,7 +3235,10 @@ directory @file{/sbin} on your local host.
Type @kbd{s h @value{postfixhop}} for the minibuffer completion to
@samp{@value{prefix}ssh@value{postfixhop}}. Typing @kbd{@key{TAB}}
shows host names @value{tramp} extracts from @file{~/.ssh/config}
-file, for example.
+@c bug#50387
+file, for example@footnote{Some completion styles, like
+@code{substring} or @code{flex}, require to type at least one
+character after the trailing @samp{@value{postfixhop}}.}.
@example
@group
@@ -3381,9 +3388,9 @@ returns the exit code for it. When the user option
indication that the process has been interrupted, and returns a
corresponding string.
-This remote process handling does not apply to @acronym{GVFS} (see
-@ref{GVFS-based methods}) because the remote file system is mounted on
-the local host and @value{tramp} accesses it by changing the
+This remote process handling does not apply to @acronym{GVFS}
+(@pxref{GVFS-based methods}) because the remote file system is mounted
+on the local host and @value{tramp} accesses it by changing the
@code{default-directory}.
@value{tramp} starts a remote process when a command is executed in a
@@ -3403,7 +3410,7 @@ might also add their name to this environment variable, like
For @value{tramp} to find the command on the remote, it must be
accessible through the default search path as setup by @value{tramp}
upon first connection. Alternatively, use an absolute path or extend
-@code{tramp-remote-path} (see @ref{Remote programs}):
+@code{tramp-remote-path} (@pxref{Remote programs}):
@lisp
@group
@@ -3525,9 +3532,8 @@ ensures the correct name of the remote shell program.
When @code{explicit-shell-file-name} is equal to @code{nil}, calling
@code{shell} interactively will prompt for a shell name.
-Starting with @w{Emacs 26}, you could use connection-local variables
-for setting different values of @code{explicit-shell-file-name} for
-different remote hosts.
+You could use connection-local variables for setting different values
+of @code{explicit-shell-file-name} for different remote hosts.
@ifinfo
@xref{Connection Variables, , , emacs}.
@end ifinfo
@@ -3738,26 +3744,27 @@ To open @command{powershell} as a remote shell, use this:
@vindex process-connection-type
@cindex tramp-process-connection-type
-Asynchronous processes differ in the way, whether they use a pseudo
-tty, or not. This is controlled by the variable
+Asynchronous processes behave differently based on whether they use a
+pseudo tty or not. This is controlled by the variable
@code{process-connection-type}, which can be @code{t} or @code{pty}
-(use a pseudo tty), or @code{nil} or @code{pipe} (don't use it).
+(use a pseudo tty), or @code{nil} or @code{pipe} (don't use one).
@value{tramp} is based on running shells on the remote host, which
-require a pseudo tty. Therefore, it declares the variable
+requires a pseudo tty. Therefore, it declares the variable
@code{tramp-process-connection-type}, which carries this information
-for remote processes. Per default, its value is @code{t}. The name
-of the remote pseudo tty is returned by the function
-@code{process-tty-name}.
+for remote processes. Its default value is @code{t}, and there is no
+need to change it. The name of the remote pseudo tty is returned by
+the function @code{process-tty-name}.
-If a remote process, started by @code{start-file-process}, shouldn't
-use a pseudo tty, this is emulated by let-binding this variable to
-@code{nil} or @code{pipe}. There is still a pseudo tty for the
-started process, but some terminal properties are changed, like
-suppressing translation of carriage return characters into newline.
+If a remote process, started by @code{start-file-process}, should
+@emph{not} use a pseudo tty, this can be requested by setting
+@code{process-connection-type} to @code{nil} or @code{pipe}. There is
+still a pseudo tty for the started process, but some terminal
+properties are changed, like suppressing translation of carriage
+return characters into newline.
-The function @code{make-process} allows an explicit setting by the
-@code{:connection-type} keyword. If this keyword is not used, the
-value of @code{tramp-process-connection-type} is applied instead.
+The function @code{make-process} allows controlling this explicitly by
+using the @code{:connection-type} keyword. If this keyword is not
+used, the value of @code{process-connection-type} is applied instead.
@anchor{Improving performance of asynchronous remote processes}
@@ -4052,6 +4059,11 @@ CPIO archives
@cindex @file{cpio} file archive suffix
@cindex file archive suffix @file{cpio}
+@item @samp{.crate} ---
+Cargo (Rust) packages
+@cindex @file{crate} file archive suffix
+@cindex file archive suffix @file{crate}
+
@item @samp{.deb} ---
Debian packages
@cindex @file{deb} file archive suffix
@@ -4219,7 +4231,7 @@ It is even possible to access file archives in file archives, as
(progn
(url-handler-mode 1)
(find-file
- "http://ftp.debian.org/debian/pool/main/c/coreutils/coreutils_8.28-1_amd64.deb/control.tar.gz/control"))
+ "https://ftp.debian.org/debian/pool/main/c/coreutils/coreutils_8.28-1_amd64.deb/control.tar.gz/control"))
@end group
@end lisp
@@ -4285,6 +4297,14 @@ passwords from @file{auth-source.el} (@pxref{Password handling}). The
latter does not happen for the @option{sudoedit} method, otherwise it
would be unusable.
+If you use the GNU ELPA version of @value{tramp}, you must load it
+explicitly, because @command{emacs -Q} ignores installed ELPA
+packages. Call (version number adapted)
+
+@example
+$ emacs -Q -l ~/.emacs.d/elpa/tramp-2.4.5.1/tramp-autoloads
+@end example
+
When including @value{tramp}'s messages in the bug report, increase
the verbosity level to 6 (@pxref{Traces and Profiles, Traces}) in the
@file{~/.emacs} file before repeating steps to the bug. Include the
@@ -4294,6 +4314,11 @@ non-@acronym{ASCII} characters which are relevant for analysis, append
the buffers as attachments to the bug report. This is also needed in
order to avoid line breaks during mail transfer.
+If you send the message from Emacs, you are asked about to append
+these buffers to the bug report. If you use an external mail program,
+you must save these buffers to files, and append them with that mail
+program.
+
@strong{Note} that a verbosity level greater than 6 is not necessary
at this stage. Also note that a verbosity level of 6 or greater, the
contents of files and directories will be included in the debug
@@ -4325,8 +4350,8 @@ Where is the latest @value{tramp}?
@item
Which systems does it work on?
-The package works successfully on @w{Emacs 25}, @w{Emacs 26}, @w{Emacs
-27}, and @w{Emacs 28}.
+The package works successfully on @w{Emacs 26}, @w{Emacs 27}, @w{Emacs
+28}, and @w{Emacs 29}.
While Unix and Unix-like systems are the primary remote targets,
@value{tramp} has equal success connecting to other platforms, such as
@@ -5087,7 +5112,7 @@ location.
Then start Emacs Client from the command line:
@example
-emacsclient @trampfn{ssh,user@@host,/file/to/edit}
+$ emacsclient @trampfn{ssh,user@@host,/file/to/edit}
@end example
@code{user} and @code{host} refer to the local host.
@@ -5107,7 +5132,7 @@ Then change the environment variable @env{EDITOR} to point to the
wrapper script:
@example
-export EDITOR=/path/to/emacsclient.sh
+$ export EDITOR=/path/to/emacsclient.sh
@end example
@@ -5170,12 +5195,15 @@ tramp-compat-with-mutex}
@value{tramp} comes with compatibility code for different Emacs
versions. When you see such a message (the text might differ), you
-don't use the Emacs built-in version of @value{tramp}. In case you
-have installed @value{tramp} from GNU ELPA, see the package README
-file for instructions how to recompile it.
+don't use the Emacs built-in version of @value{tramp}, and you must
+recompile it. In case you have installed @value{tramp} from GNU ELPA,
@ifset installchapter
-@xref{Recompilation}.
+@xref{ELPA Installation}. Otherwise, @xref{Recompilation}.
@end ifset
+@ifclear installchapter
+see @uref{@value{trampurl}#ELPA-Installation}. Otherwise, see
+@uref{@value{trampurl}#Recompilation}.
+@end ifclear
@item
@@ -5200,6 +5228,28 @@ time being you can suppress this error by the following code in your
@item
+I get an error @samp{Remote file error: Not a valid Tramp file name
+function `tramp-FOO-file-name-p'}
+
+@value{tramp} has changed the signature of an internal function.
+External packages implementing an own @value{tramp} backend must
+follow this change. Please report this problem to the author of that
+package.
+
+For the running session, @value{tramp} disables the external package,
+and you can continue to work. If you don't want to see this error
+while activating @value{tramp}, you can suppress it by the same code
+as above in your @file{~/.emacs}:
+
+@lisp
+@group
+(setq debug-ignored-errors
+ (cons 'remote-file-error debug-ignored-errors))
+@end group
+@end lisp
+
+
+@item
How to disable other packages from calling @value{tramp}?
There are packages that call @value{tramp} without the user ever
@@ -5304,6 +5354,12 @@ handlers.
@node External packages
@section Integrating with external Lisp packages
+
+In general, it is not recommended to use @value{tramp} functions and
+variables not described in this manual. They might change their
+signature and/or semantics without any announcement.
+
+
@subsection File name completion
@vindex non-essential
diff --git a/doc/misc/trampver.texi b/doc/misc/trampver.texi
index b11ee39f884..89c478035c0 100644
--- a/doc/misc/trampver.texi
+++ b/doc/misc/trampver.texi
@@ -8,10 +8,10 @@
@c In the Tramp GIT, the version numbers are auto-frobbed from
@c tramp.el, and the bug report address is auto-frobbed from
@c configure.ac.
-@set trampver 2.5.2-pre
+@set trampver 2.6.0-pre
@set trampurl https://www.gnu.org/software/tramp/
@set tramp-bug-report-address tramp-devel@@gnu.org
-@set emacsver 25.1
+@set emacsver 26.1
@c Other flags from configuration.
@set instprefix /usr/local
diff --git a/doc/misc/url.texi b/doc/misc/url.texi
index 8f15e11007e..90e38e5d30e 100644
--- a/doc/misc/url.texi
+++ b/doc/misc/url.texi
@@ -90,7 +90,7 @@ can be accessed (usually over a network) in a specific way.
@example
ftp://ftp.is.co.za/rfc/rfc1808.txt
-http://www.ietf.org/rfc/rfc2396.txt
+https://www.ietf.org/rfc/rfc2396.txt
ldap://[2001:db8::7]/c=GB?objectClass?one
mailto:John.Doe@@example.com
news:comp.infosystems.www.servers.unix
@@ -708,7 +708,7 @@ Well-known ports are used if the URL does not specify a port.
@cindex rcirc
The @code{irc} scheme is defined in the Internet Draft at
-@url{http://www.w3.org/Addressing/draft-mirashi-url-irc-01.txt} (which
+@url{https://www.w3.org/Addressing/draft-mirashi-url-irc-01.txt} (which
was never approved as an RFC). Such URLs have the form
@example
@@ -1181,7 +1181,7 @@ opened by the URL library.
@c machines off the local network. This is characterized by being able
@c to reach someplace with a raw ip number, but not its hostname
@c (@url{http://129.79.254.191/} works, but
-@c @url{http://www.cs.indiana.edu/} doesn't). This used to happen on
+@c @url{https://www.cs.indiana.edu/} doesn't). This used to happen on
@c SunOS4 and Ultrix, but is now probably now rare. If Emacs can't be
@c rebuilt linked against the resolver library, it can use the external
@c @command{nslookup} program instead.
diff --git a/doc/misc/vhdl-mode.texi b/doc/misc/vhdl-mode.texi
index fef98a74636..7022582db51 100644
--- a/doc/misc/vhdl-mode.texi
+++ b/doc/misc/vhdl-mode.texi
@@ -243,7 +243,7 @@ components. Also notice that the first component,
@vindex vhdl-offsets-alist
@vindex offsets-alist @r{(vhdl-)}
Indentation for the current line is calculated using the syntactic
-component list derived in step 1 above (see @ref{Syntactic
+component list derived in step 1 above (@pxref{Syntactic
Analysis}). Each component contributes to the final total indentation
of the line in two ways.
@@ -668,7 +668,7 @@ not handled by the mode directly.
@cindex custom indentation functions
One of the most common ways to customize VHDL Mode is by writing
@dfn{custom indentation functions} and associating them with specific
-syntactic symbols (see @ref{Syntactic Symbols}). VHDL Mode itself
+syntactic symbols (@pxref{Syntactic Symbols}). VHDL Mode itself
uses custom indentation functions to provide more sophisticated
indentation, for example when lining up selected signal assignments:
@example
@@ -732,7 +732,7 @@ operator on the first line of the statement. Here is the lisp code
@end example
@noindent
Custom indent functions take a single argument, which is a syntactic
-component cons cell (see @ref{Syntactic Analysis}). The
+component cons cell (@pxref{Syntactic Analysis}). The
function returns an integer offset value that will be added to the
running total indentation for the line. Note that what actually gets
returned is the difference between the column that the signal assignment
diff --git a/etc/AUTHORS b/etc/AUTHORS
index 3e91efb570e..60b1ee4bd01 100644
--- a/etc/AUTHORS
+++ b/etc/AUTHORS
@@ -9,8 +9,9 @@ Aaron Ecay: changed ob-R.el ob-core.el org-src.el ox-latex.el nsterm.m
ob-awk.el ob-exp.el ob-python.el ob-tangle.el org-bibtex.el org-id.el
org.el org.texi package.el paren.el
-Aaron Jensen: changed frameset.el nsterm.m Info.plist.in flyspell.el
- mouse.el server.el systhread.c w32term.c xdisp.c xterm.c
+Aaron Jensen: changed frameset.el nsterm.m xdisp-tests.el xdisp.c
+ Info.plist.in flyspell.el mouse.el server.el systhread.c w32term.c
+ xterm.c
Aaron Larson: co-wrote bibtex.el
@@ -18,7 +19,7 @@ Aaron S. Hawley: wrote lisp-tests.el undo-tests.el
and changed simple.el files.texi isearch.el morse.el sgml-mode.el
tar-mode.el textmodes/table.el thingatpt.el add-log.el autoinsert.el
building.texi calc.el cc-fonts.el comint.el compare-w.el custom.texi
- diff.el edebug.el etags.el ffap.el files.el and 31 other files
+ diff.el edebug.el etags.el ffap.el files.el and 30 other files
Abdó Roig-Maranges: changed org.el org-agenda.el ox-html.el ox-odt.el
@@ -37,11 +38,14 @@ Adam Gołębiowski: changed lib-src/Makefile.in
Adam Hupp: changed emacs.py emacs2.py emacs3.py gud.el
progmodes/python.el
+Adam Porter: changed tab-line.el cl-macs.el map.el control.texi
+ map-tests.el pcase-tests.el tab-bar.el
+
Adam Sjøgren: changed mml2015.el shr.el spam.el xterm.c blink.xpm
braindamaged.xpm cry.xpm dead.xpm evil.xpm forced.xpm frown.xpm
gnus-sum.el grin.xpm gtkutil.c indifferent.xpm message.el
reverse-smile.xpm sad.xpm smile.xpm wry.xpm gnus-html.el
- and 7 other files
+ and 10 other files
Adam Sokolnicki: changed ruby-mode.el
@@ -70,7 +74,7 @@ and changed nsterm.m nsfns.m nsfont.m nsterm.h nsmenu.m configure.ac
Agustín Martín: changed ispell.el flyspell.el fixit.texi
-Ahmed Khanzada: changed battery.el
+Ahmed Khanzada: changed battery.el nsterm.m
Aidan Gauland: wrote em-tramp.el
and changed eshell.texi em-term.el em-unix.el erc-match.el em-cmpl.el
@@ -85,6 +89,8 @@ and changed cc-mode.el perl-mode.el
Akinori Musha: changed ruby-mode.el Makefile.in sieve-mode.el
+Akira Kyle: changed eww.el process.c xwidget.c
+
Aki Vehtari: changed bibtex.el gnus-art.el gnus-score.el gnus-sum.el
nnmail.el tar-mode.el
@@ -97,25 +103,26 @@ Alakazam Petrofsky: changed hanoi.el
Alan Mackenzie: wrote cc-awk.el
and co-wrote cc-align.el cc-cmds.el cc-defs.el cc-engine.el cc-fonts.el
cc-langs.el cc-mode.el cc-styles.el cc-vars.el
-and changed cc-mode.texi bytecomp.el display.texi follow.el subr.el
- edebug.el progmodes/compile.el programs.texi syntax.texi modes.texi
- font-lock.el isearch.el text.texi help.el ispell.el lread.c syntax.c
- windows.texi .dir-locals.el control.texi cus-start.el
- and 148 other files
+and changed cc-mode.texi minibuf.c bytecomp.el edebug.el follow.el
+ window.c display.texi subr.el syntax.texi progmodes/compile.el
+ programs.texi keyboard.c lisp.h modes.texi window.el windows.texi
+ cus-start.el eval.c font-lock.el isearch.el newcomment.el
+ and 166 other files
Alan Modra: changed unexelf.c
-Alan Schmitt: changed gnus-sum.el nnimap.el ob-ocaml.el org-faces.el
+Alan Schmitt: co-wrote ox-koma-letter.el
+and changed gnus-sum.el nnimap.el ob-ocaml.el org-faces.el
Alan Shutko: changed diary-lib.el calendar.el bindings.el cal-hebrew.el
easy-mmode.el gnus-sum.el ibuf-ext.el ibuffer.el lunar.el macros.el
solar.el
Alan Third: wrote dabbrev-tests.el image-transforms-tests.el
-and changed nsterm.m nsterm.h nsfns.m nsmenu.m ns-win.el nsimage.m
- image.c macfont.m configure.ac frame.el xdisp.c macos.texi display.texi
- image.el xterm.c Info.plist.in conf_post.h dispextern.h frame.c frame.h
- frames.texi and 21 other files
+and changed nsterm.m nsterm.h nsfns.m image.c nsmenu.m configure.ac
+ nsimage.m ns-win.el macfont.m dispextern.h frame.el nsfont.m
+ display.texi xdisp.c frame.c frame.h macos.texi xterm.c .gitlab-ci.yml
+ Makefile.in emacs.c and 39 other files
Alastair Burt: changed gnus-art.el smiley.el
@@ -125,25 +132,104 @@ and changed sieve.el gnus-msg.el gnus.texi mail/sieve-manage.el
Albert L. Ting: changed gnus-group.el mail-hist.el
+Aleksandr Vityazev: changed tramp-compat.el
+
Aleksei Gusev: changed progmodes/compile.el
-Alexandru Harsanyi: changed soap-client.el soap-inspect.el emacs3.py
- vc-hooks.el vc.el xml.el
+Alexander Adolf: wrote eudcb-macos-contacts.el
+and changed eudc.texi
+
+Alexander Becher: changed vc-annotate.el
+
+Alexander Gramiak: changed w32term.c xterm.c nsterm.m dispextern.h
+ xdisp.c frame.c image.c nsgui.h w32gui.h xfns.c frame.el termhooks.h
+ w32fns.c w32term.h faces.el nsterm.h xfaces.c xterm.h frame.h xfont.c
+ configure.ac and 69 other files
+
+Alexander Haeckel: changed getset.el
+
+Alexander Klimov: changed files.el calc-graph.el files.texi man.el rx.el
+ sendmail.el
+
+Alexander Kreuzer: changed nnrss.el
+
+Alexander Kuleshov: changed dns-mode.el files.texi image-mode.el
+ keyboard.c ld-script.el xdisp.c
+
+Alexander L. Belikoff: wrote erc.el
+
+Alexander Miller: changed dispextern.h faces.el frame.c frame.h
+ frames.texi nsfns.m nsterm.m w32fns.c xfaces.c xfns.c xterm.c
+
+Alexander Pohoyda: co-wrote mail/rmailmm.el
+and changed rmailsum.el man.el rmail.el sendmail.el
+
+Alexander Shopov: changed code-pages.el
+
+Alexander Vorobiev: changed org-compat.el
+
+Alexander Zhuckov: changed ebrowse.c
+
+Alexandre Adolphe: changed cus-face.el dispextern.h display.texi nsfont.m
+ nsterm.m w32term.c xdisp.c xfaces.c xterm.c
+
+Alexandre Duret-Lutz: changed nnmaildir.el
+
+Alexandre Garreau: changed message.el
+
+Alexandre Julliard: wrote vc-git.el
+and changed vc.el ewoc.el
+
+Alexandre Oliva: wrote gnus-mlspl.el
+and changed unexelf.c emacs-regex.c format.el iris4d.h iris5d.h unexsgi.c
+
+Alexandre Veyrenc: changed fr-refcard.tex
+
+Alexandru Harsanyi: wrote soap-client.el soap-inspect.el
+and changed emacs3.py vc-hooks.el vc.el xml.el
+
+Alexandr Vityazev: changed shortdoc.el
+
+Alex Bochannek: changed gnus.texi gnus-sum.el gnus-score.el gnus-topic.el
+ gnus-util.el gnus-fun.el gnus-group.el gnus.el ange-ftp.el gnus-art.el
+ nnimap.el tramp-sh.el
+
+Alex Coventry: changed files.el
+
+Alex Dunn: changed subr-tests.el subr.el
+
+Alexei Khlebnikov: changed autorevert.el vc-git.el
+
+Alex Kosorukoff: changed org-capture.el
+
+Alex Mcgrath: changed rcirc.el
-Alex Gramiak: wrote ansi-color.el conf-mode-tests.el cus-theme.el
- erc-compat.el erc-hecomplete.el erc-join.el erc-lang.el erc-ring.el
- erc.el gnus-mlspl.el master.el soap-client.el soap-inspect.el
- spam-stat.el sql.el vc-git.el which-func.el
+Alex Murray: changed erc-desktop-notifications.el network-stream.el
+
+Alex Ott: changed TUTORIAL.ru ede/files.el ru-refcard.tex base.el
+ cedet-files.el cpp-root.el ede.el ede/generic.el idle.el ispell.el
+ semantic/format.el
+
+Alex Reed: changed verilog-mode.el
+
+Alex Rezinsky: wrote which-func.el
+
+Alex Schroeder: wrote ansi-color.el cus-theme.el erc-compat.el
+ erc-hecomplete.el erc-join.el erc-lang.el erc-ring.el master.el
+ spam-stat.el sql.el
and co-wrote longlines.el mail/rmailmm.el
-and changed erc-track.el erc-button.el w32term.c xterm.c erc-stamp.el
- nsterm.m xdisp.c dispextern.h frame.c image.c nsgui.h w32gui.h xfns.c
- erc-match.el frame.el termhooks.h w32fns.c Makefile TUTORIAL.ru
- erc-autoaway.el erc-nickserv.el and 215 other files
+and changed erc.el erc-track.el erc-button.el erc-stamp.el erc-match.el
+ erc-autoaway.el erc-nickserv.el rcirc.texi Makefile erc-autojoin.el
+ erc-fill.el erc-pcomplete.el erc-complete.el erc-ibuffer.el
+ erc-members.el rmail.el comint.el custom.el erc-bbdb.el erc-chess.el
+ erc-ezbounce.el and 35 other files
+
+Alex Shinn: changed files.el
Alfred Correira: changed generic-x.el
Alfred M. Szmidt: changed rmail.el vc-svn.el html2text.el openbsd.h
- progmodes/compile.el rmailsum.el
+ progmodes/compile.el rmailsum.el vc.el
Alfredo Finelli: changed TUTORIAL.it
@@ -151,10 +237,10 @@ Ali Bahrami: changed configure configure.ac sol2-10.h
Alin C. Soare: changed lisp-mode.el hexl.el
-Allen Li: changed abbrev.el abbrev-tests.el abbrevs.texi sending.texi
- autoload.el bookmark.el comint.el dired-x.el misc.texi nsm.el
- progmodes/compile.el ring-tests.el ring.el sequences.texi subr.el
- xref.el
+Allen Li: changed abbrev.el abbrev-tests.el abbrevs.texi recentf.el
+ sending.texi autoload.el bookmark.el comint.el dired-x.el gnus-group.el
+ misc.texi nsm.el progmodes/compile.el ring-tests.el ring.el
+ sequences.texi subr.el xref.el
Allen S. Rout: changed org-capture.el
@@ -166,14 +252,18 @@ Alp Aker: changed nsfont.m nsterm.m buff-menu.el nsfns.m nsmenu.m
Álvar Jesús Ibeas Martín: changed TUTORIAL.es emacs-lisp-intro.texi
+Alyssa Ross: changed progmodes/compile.el simple.el
+
Ami Fischman: changed bindings.el calendar.el diary-lib.el print.c
savehist.el vc-git.el
-Amin Bandali: changed erc.el erc-button.el erc-desktop-notifications.el
- erc-track.el erc-autoaway.el erc-compat.el erc-fill.el erc-ibuffer.el
- erc-imenu.el erc-join.el erc-lang.el erc-list.el erc-log.el
- erc-match.el erc-notify.el erc-pcomplete.el erc-replace.el erc-ring.el
- erc-services.el erc-sound.el erc-speedbar.el and 5 other files
+Amin Bandali: changed erc.el erc-backend.el erc-button.el erc-compat.el
+ erc-track.el erc-dcc.el erc-desktop-notifications.el erc-match.el
+ erc-services.el erc-speedbar.el erc-status-sidebar.el erc.texi
+ erc-autoaway.el erc-fill.el erc-goodies.el erc-ibuffer.el erc-imenu.el
+ erc-join.el erc-lang.el erc-list.el erc-log.el and 11 other files
+
+Amos Bird: changed xfns.c
Anand Mitra: changed gnus-sum.el
@@ -183,12 +273,19 @@ Anders Lindgren: wrote autorevert.el cwarn.el faceup-test-basics.el
faceup-test-files.el faceup.el follow.el
and changed nsterm.m nsfns.m nsmenu.m nsterm.h font-lock.el nsimage.m
README etags.c term.el window.el Info.plist.in compile.el diff-mode.el
- ert.el faceup-test-mode.el faceup-test-this-file-directory.el loadup.el
- lread.c ns-win.el nsfont.m test1.txt and 3 other files
+ ert.el faceup-test-mode.el faceup-test-this-file-directory.el
+ lisp-mode.el loadup.el lread.c ns-win.el nsfont.m and 4 other files
Anders Waldenborg: changed emacsclient.c
-Andrea Corallo: changed map-tests.el map.el
+Andrea Corallo: wrote comp-cstr-tests.el comp-cstr.el comp-tests.el
+ comp.el
+and changed comp.c pdumper.c lread.c bytecomp.el comp.h configure.ac
+ lisp.h startup.el loadup.el alloc.c data.c emacs.c .gitlab-ci.yml
+ nadvice.el cl-macs.el advice.el help.el lisp/Makefile.in package.el
+ Makefile.in comp-test-funcs.el and 62 other files
+
+André A. Gomes: changed ispell.el
Andrea Rossetti: changed ruler-mode.el
@@ -203,11 +300,11 @@ Andreas Büsching: changed emacsclient.c
Andreas Fuchs: wrote erc-ezbounce.el erc-match.el erc-replace.el
erc-truncate.el
and co-wrote erc-fill.el
-and changed erc.el erc-bbdb.el erc-button.el erc-log.el erc-stamp.el
- erc-autoaway.el erc-autojoin.el erc-dcc.el erc-imenu.el erc-list.el
- erc-members.el erc-menu.el erc-netsplit.el erc-notify.el erc-ring.el
- erc-speedbar.el erc-track.el erc-xdcc.el gnus-registry.el mml-sec.el
- mml2015.el
+and changed erc.el erc-bbdb.el erc-button.el erc-log.el comp.c
+ erc-stamp.el comp.el erc-autoaway.el erc-autojoin.el erc-dcc.el
+ erc-imenu.el erc-list.el erc-members.el erc-menu.el erc-netsplit.el
+ erc-notify.el erc-ring.el erc-speedbar.el erc-track.el erc-xdcc.el
+ gnus-registry.el and 3 other files
Andreas Jaeger: changed gnus-msg.el gnus-start.el gnus-xmas.el
nnfolder.el nnml.el
@@ -230,8 +327,8 @@ Andreas Rottmann: changed emacsclient.1 emacsclient.c misc.texi server.el
Andreas Schwab: changed configure.ac lisp.h xdisp.c process.c alloc.c
coding.c Makefile.in files.el fileio.c keyboard.c lread.c xterm.c fns.c
- editfns.c emacs.c src/Makefile.in print.c eval.c font.c xfns.c sysdep.c
- and 651 other files
+ src/Makefile.in editfns.c emacs.c print.c eval.c font.c xfns.c sysdep.c
+ and 656 other files
Andreas Seltenreich: changed nnweb.el gnus.texi message.el gnus-sum.el
gnus.el nnslashdot.el gnus-srvr.el gnus-util.el mm-url.el mm-uu.el
@@ -251,23 +348,27 @@ Andre Spiegel: changed vc.el vc-hooks.el vc-cvs.el vc-rcs.el vc-sccs.el
Andre Srinivasan: changed gnus-group.el gnus-sum.el gnus.texi message.el
mm-decode.el mml.el nnmail.el
+Andrew Barbarello: wrote erc-status-sidebar.el
+
Andrew Beals: changed spook.lines
+Andrew Burgess: changed cua-base.el
+
Andrew Choi: changed macterm.c darwin.h mac-win.el sysdep.c emacs.c mac.c
macfns.c fontset.c frame.c keyboard.c xfaces.c dispextern.h macmenu.c
unexmacosx.c configure.ac frame.h macterm.h titdic-cnv.el xdisp.c
alloc.c callproc.c and 27 other files
-Andrew Cohen: wrote spam-wash.el
-and changed nnir.el gnus-sum.el nnimap.el gnus-msg.el gnus.texi
- gnus-group.el gnus-int.el dns.el gnus-art.el gnus-registry.el
- gnus-srvr.el gnus.el nnheader.el nnspool.el
-
Andrew Csillag: wrote m4-mode.el
Andrew Eggenberger: changed cl-extra.el seq.el
-Andrew G Cohen: changed gnus-sum.el gnus-art.el
+Andrew G Cohen: wrote nnselect.el spam-wash.el
+and changed nnir.el gnus-sum.el nnimap.el gnus-msg.el gnus-group.el
+ gnus.texi gnus-int.el gnus-art.el gnus-cache.el gnus.el nnheader.el
+ nnspool.el auth-source.el dns.el gnus-agent.el gnus-cloud.el
+ gnus-registry.el gnus-srvr.el gnus-start.el nndiary.el nnfolder.el
+ and 5 other files
Andrew Hall: changed paren.el
@@ -289,6 +390,8 @@ Andrew Schein: changed sql.el
Andrew Schwartzmeyer: changed subr-tests.el subr.el
+Andrew Whatson: changed comp.el
+
Andrew W. Nosenko: changed tramp.el
Andrew Zhilin: changed emacs22.png emacs22.ico
@@ -299,10 +402,9 @@ Andrey Slusar: changed gnus-async.el gnus.el
Andrey Zhdanov: changed gud.el
-Andrii Kolomoiets: changed vc-hg.el progmodes/python.el vc-git.el vc.el
- maintaining.texi vc-svn.el
-
-Andrzej Lichnerowicz: wrote ob-io.el
+Andrii Kolomoiets: changed vc-hg.el progmodes/python.el vc.el vc-dir.el
+ vc-git.el cyril-util.el ewoc.el frame.c frame.el maintaining.texi
+ ns-win.el nsterm.h nsterm.m project.el vc-dispatcher.el vc-svn.el
Andrzej P: changed gdb-mi.el
@@ -332,16 +434,18 @@ Ansgar Burchardt: changed latin-ltx.el
Antoine Beaupré: changed vc-git.el
-Antoine Levitt: changed gnus-group.el gnus-sum.el message.texi ada-prj.el
+Antoine Levitt: changed gnus-group.el gnus-sum.el message.texi
ange-ftp.el cus-edit.el dired-x.el ebnf2ps.el emerge.el erc-button.el
erc-goodies.el erc-stamp.el erc-track.el files.el find-file.el
gnus-art.el gnus-uu.el gnus.el gnus.texi message.el mh-funcs.el
- and 8 other files
+ mh-mime.el and 7 other files
Antonin Houska: changed newcomment.el
-Arash Esbati: changed reftex-vars.el reftex-ref.el reftex.el nnmaildir.el
- reftex-auc.el reftex-cite.el reftex-dcr.el
+Arash Esbati: changed reftex-vars.el reftex-auc.el reftex-ref.el
+ reftex.el nnmaildir.el reftex-cite.el reftex-dcr.el reftex-toc.el
+
+Arik Mitschang: changed smime.el
Ari Roponen: changed xterm.c image.c atimer.c doc.c ftcrfont.c hash.texi
mule.texi package.el startup.el subr.el svg.el time-date.el woman.el
@@ -362,21 +466,32 @@ and changed smime.el mml-smime.el smime-ldap.el flymake.el gnus-art.el
Arni Magnusson: wrote bat-mode.el
and changed frames.texi generic-x.el texinfo.el
+Arnold Noronha: changed ido.el
+
Artem Chuprina: changed message.el
+Artem Loenko: changed src/Makefile.in
+
+Arthur Miller: changed help-fns.el ange-ftp.el bytecomp.el comp.c comp.el
+ dired-tests.el dired.c dired.el files.texi help.texi lisp.h ls-lisp.el
+ sysdep.c tramp-adb.el tramp-rclone.el tramp-sh.el tramp-smb.el tramp.el
+ wdired.el
+
Artur Malabarba: wrote char-fold-tests.el faces-tests.el isearch-tests.el
- let-alist.el simple-tests.el sort-tests.el tabulated-list-test.el
+ let-alist.el simple-tests.el sort-tests.el tabulated-list-tests.el
and changed package.el isearch.el lisp/char-fold.el files.el
tabulated-list.el package-test.el menu-bar.el replace.el bytecomp.el
faces.el files-x.el custom.el custom.texi help-fns.el
let-alist-tests.el simple.el subr-tests.el align.el bindings.el
- cl-lib-tests.el cl-macs.el and 42 other files
+ cl-lib-tests.el cl-macs.el and 43 other files
Artyom Loenko: changed Info.plist.in
Arun Persaud: changed org-agenda.el org-src.el
-Ashish Shukla: changed emacs-gnutls.texi gnutls.el
+Asher Gordon: changed gomoku.el mml.el
+
+Ashish Shukla: changed emacs-gnutls.texi gnutls.el comp.el
Ashwin Ram: wrote refer.el
@@ -386,6 +501,9 @@ Atsuo Ohki: changed lread.c
Aubrey Jaffer: changed info.el unexelf.c
+Augusto Stoffel: changed progmodes/python.el comint.el isearch.el
+ eldoc.el misc.texi progmodes/compile.el search.texi
+
Aurélien Aptel: changed alloc.c emacs-module.h lisp.h Makefile
configure.ac cus-face.el data.c dispextern.h display.texi dynlib.c
dynlib.h emacs-module.c faces.el lread.c modhelp.py nsterm.m ox-html.el
@@ -421,14 +539,16 @@ Bartosz Duszel: changed allout.el bib-mode.el cc-cmds.el hexl.el icon.el
sendmail.el ses.el simple.el verilog-mode.el vi.el vip.el viper-cmd.el
xscheme.el
-Basil L. Contovounesios: changed simple.el message.el subr.el gravatar.el
- custom.el gnus-group.el gnus-sum.el gnus-win.el internals.texi
- modes.texi text.texi window.c bibtex.el button.el customize.texi
- display.texi eww.el gnus-art.el gnus-msg.el gnus.texi lists.texi
- and 150 other files
+Basil L. Contovounesios: changed simple.el message.el subr.el eww.el
+ custom.el bibtex.el text.texi gnus-sum.el modes.texi customize.texi
+ files.texi gnus-group.el gnus-win.el gravatar.el internals.texi json.el
+ shr.el window.c battery-tests.el button.el custom-tests.el
+ and 278 other files
+
+Bastian Beischer: changed semantic/complete.el calc-yank.el include.el
+ mru-bookmark.el refs.el senator.el
-Bastian Beischer: changed semantic/complete.el include.el mru-bookmark.el
- refs.el senator.el
+Bastian Beranek: changed tab-bar.el
Bastien Guerry: wrote gnus-bookmark.el
and co-wrote ol-bibtex.el org-list.el org-protocol.el org-src.el
@@ -436,7 +556,7 @@ and changed org.el org-agenda.el org.texi ox-html.el org-clock.el
org-capture.el org-table.el ox-latex.el ox.el ox-odt.el org-compat.el
ox-publish.el ob.el org-mobile.el org-colview.el org-macs.el
org-pcomplete.el org-timer.el org-faces.el ox-ascii.el org-archive.el
- and 120 other files
+ and 119 other files
Ben A. Mesander: co-wrote erc-dcc.el
@@ -455,9 +575,9 @@ and changed org-clock.el org.el
Benjamin Ragheb: changed fortune.el
-Benjamin Riefenstahl: changed files.el image-mode.el w32select.c emacs.c
- image.el inc/ms-w32.h lisp.h mac-win.el macterm.c mule-cmds.el
- runemacs.c tcl.el w32.c w32.h
+Benjamin Riefenstahl: changed files.el image-mode.el nnrss-tests.el
+ w32select.c emacs.c image.el inc/ms-w32.h lisp.h mac-win.el macterm.c
+ mule-cmds.el nnrss.el runemacs.c tcl.el w32.c w32.h
Benjamin Rutt: co-wrote gnus-dired.el
and changed vc.el gnus-msg.el message.el diff-mode.el ffap.el nnimap.el
@@ -511,6 +631,8 @@ and changed mh-customize.el mh-search.el mh-alias.el mh-e.texi Makefile
Bjarte Johansen: wrote ob-sed.el
+Björn Holby: changed vhdl-mode.el
+
Björn Lindström: changed rcirc.texi
Bjørn Mork: changed nnimap.el gnus-agent.el message.el mml2015.el
@@ -554,7 +676,8 @@ and changed fill.el simple.el indent.el paragraphs.el cmds.c intervals.c
Boris Samorodov: changed imap.el
Boruch Baum: co-wrote footnote.el
-and changed bookmark.el
+and changed bookmark.el apropos.el autorevert.el calc.el cua-rect.el
+ help.el ses.el simple.el textmodes/table.el
Boyd Lynn Gerber: changed configure.ac
@@ -585,6 +708,9 @@ Brian Fox: changed Makefile.in Makefile configure.ac minibuf.c dired.el
Brian Jenkins: changed frame.c frames.texi hooks.texi
+Brian Leung: changed comint.el gud.el advice.el comp.c comp.el em-hist.el
+ files.el find-func.el gdb-mi.el help.el nadvice.el shell.el shortdoc.el
+
Brian Marick: co-wrote hideif.el
Brian McKenna: changed eww.el
@@ -606,7 +732,8 @@ Brian van den Broek: changed org.texi
Bruce Stephens: changed calc-ext.el
-Bruno Félix Rezende Ribeiro: changed functions.texi gnus.texi
+Bruno Félix Rezende Ribeiro: changed os.texi finder.el functions.texi
+ gnus.texi info.el lisp-mnt.el package.el
Bruno Haible: co-wrote po.el
and changed INSTALL emacs.1 epaths.in info.el paths.el
@@ -615,6 +742,8 @@ Bryan Henderson: changed Makefile term.el
Bryan O'Sullivan: changed ange-ftp.el
+Caio Henrique: changed menu-bar.el
+
Caio Tiago Oliveira: changed ob-scala.el
Caleb Deupree: changed w32-fns.el
@@ -630,19 +759,23 @@ Carl Edman: co-wrote ns-win.el
Carl Henrik Lunde: changed format-spec.el
-Carlos Pita: changed progmodes/python.el erc-pcomplete.el fringe.c
- gtkutil.c image-mode.el keyboard.c sh-script.el
+Carl Lei: changed cc-langs.el
+
+Carlos Pita: changed progmodes/python.el Makefile.in comint.el
+ emacs.service emacsclient.desktop erc-pcomplete.el fringe.c gtkutil.c
+ image-mode.el keyboard.c sh-script.el
Carsten Bormann: changed ibmrs6000.h latin-post.el
Carsten Dominik: wrote idlw-complete-structtag.el idlw-toolbar.el
- ol-info.el ol-rmail.el ol.el org-agenda.el org-archive.el
+ ol-info.el ol-man.el ol-rmail.el ol.el org-agenda.el org-archive.el
org-capture.el org-clock.el org-colview.el org-compat.el
org-datetree.el org-faces.el org-feed.el org-footnote.el org-goto.el
org-id.el org-indent.el org-inlinetask.el org-macs.el org-mobile.el
- org-table.el org-timer.el org.el reftex-auc.el reftex-cite.el
- reftex-dcr.el reftex-global.el reftex-index.el reftex-parse.el
- reftex-ref.el reftex-sel.el reftex-toc.el reftex-vars.el reftex.el
+ org-refile.el org-table.el org-timer.el org.el reftex-auc.el
+ reftex-cite.el reftex-dcr.el reftex-global.el reftex-index.el
+ reftex-parse.el reftex-ref.el reftex-sel.el reftex-toc.el
+ reftex-vars.el reftex.el
and co-wrote idlw-help.el idlw-shell.el idlwave.el ol-bbdb.el
ol-bibtex.el ol-gnus.el org-entities.el org-list.el org-pcomplete.el
org-src.el ox-beamer.el ox-html.el ox-icalendar.el
@@ -667,7 +800,7 @@ Changwoo Ryu: changed files.el
Chao-Hong Liu: changed TUTORIAL.cn TUTORIAL.zh
-Charles A. Roelli: changed nsterm.m vc.el nsfns.m simple.el isearch.el
+Charles A. Roelli: changed nsterm.m vc.el simple.el nsfns.m isearch.el
nsmenu.m nsterm.h process.c register.el diff-mode.el display.texi
files.el files.texi fixit.texi macfont.m minibuf.c nsfont.m nsimage.m
nsselect.m org-clock.el progmodes/python.el and 47 other files
@@ -698,7 +831,7 @@ and co-wrote longlines.el tango-dark-theme.el tango-theme.el
and changed simple.el display.texi xdisp.c files.el frames.texi
cus-edit.el files.texi custom.el subr.el text.texi faces.el keyboard.c
startup.el package.el misc.texi emacs.texi modes.texi mouse.el
- custom.texi image.c window.el and 933 other files
+ custom.texi image.c window.el and 932 other files
Chris Chase: co-wrote idlw-shell.el idlwave.el
@@ -715,13 +848,15 @@ Chris Hall: changed callproc.c frame.c
Chris Hanson: changed xscheme.el scheme.el xterm.c hpux.h x11term.c
hp9000s300.h keyboard.c process.c texinfmt.el sort.el syntax.c
- texnfo-upd.el x11fns.c xfns.c dired.el emacsclient.c fileio.c
- hp9000s800.h indent.c info.el man.el and 17 other files
+ texnfo-upd.el x11fns.c xfns.c dired.el emacs-regex.c emacsclient.c
+ fileio.c hp9000s800.h indent.c info.el and 17 other files
Chris Hecker: changed calc-aent.el
Chris Lindblad: co-wrote tcl.el
+Chris Mcmahan: changed package.el
+
Chris Moore: changed dired.el hexl.el jka-cmpr-hook.el replace.el
wdired.el Makefile.in comint.el diff-mode.el gnus-sum.el isearch.el
mouse.el pgg-gpg.el pgg-pgp.el pgg-pgp5.el server.el shell.el
@@ -739,8 +874,6 @@ Christian Egli: changed org-taskjuggler.el org.texi
Christian Faulhammer: changed configure configure.ac src/Makefile.in
vc-bzr.el
-Christian Garbs: wrote ob-vala.el
-
Christian Limpach: co-wrote ns-win.el
and changed configure.ac
@@ -794,6 +927,8 @@ and changed replace.el files.el ispell.el time.el
Christopher J. White: changed url-http.el
+Christopher League: changed bookmark.el cus-theme.el
+
Christopher Oliver: changed mouse.el
Christopher Schmidt: changed files.el ibuffer.el org.el tips.texi
@@ -806,7 +941,7 @@ Christopher Thorne: changed dired.el progmodes/grep.el
Christopher Wellons: changed emacs-lisp/cl-lib.el hashcash.el
viper-cmd.el viper-ex.el viper-init.el viper.el
-Christophe Troestler: changed epg.el
+Christophe Troestler: changed gnus-icalendar.el epg.el newcomment.el
Christoph Scholtes: changed README.W32 progmodes/python.el stdint.h
INSTALL maintaining.texi INSTALL.REPO admin.el bookmark.el
@@ -832,10 +967,16 @@ Claudio Bley: changed image.c image.el process.c stat.h w32-win.el w32.c
Claudio Fontana: changed Makefile.in leim/Makefile.in lib-src/Makefile.in
+Clemens Radermacher: changed cus-start.el frame.c minibuf.texi window.el
+
Clément Pit--Claudel: changed debugging.texi emacs-lisp/debug.el eval.c
progmodes/python.el subr-tests.el subr.el url-http.el url-vars.el
-Clément Pit-Claudel: changed keyboard.c text.texi
+Clément Pit-Claudel: changed Dockerfile.emba button.el configure.ac
+ display.texi ert.el gitlab-ci.yml keyboard.c tex-mode.el text.texi
+ xdisp.c
+
+Codruț Constantin Gușoi: changed files.el
Colin Marquardt: changed gnus.el message.el
@@ -850,8 +991,14 @@ and changed calc.el replace.el update-game-score.c calc-ext.el
Colin Williams: changed calc.texi
+Colin Woodbury: changed files.el files.texi macros.texi shortdoc.el
+
Constantin Kulikov: changed server.el startup.el
+Constantino Calancha: changed dired.el
+
+Corwin Brust: changed erc-services.el
+
Courtney Bane: changed term.c
Craig Markwardt: changed icalendar.el
@@ -878,12 +1025,14 @@ and changed mail-extr.el
Dale Sedivec: changed sgml-mode.el wisent/python.el
-Damien Cassou: wrote auth-source-pass-tests.el
+Damien Cassou: wrote auth-source-pass-tests.el hierarchy-tests.el
+ hierarchy.el
and co-wrote auth-source-pass.el auth-source-tests.el
-and changed auth.texi message.el seq-tests.el seq.el simple-tests.el
- simple.el auth-source.el checkdoc-tests.el checkdoc.el imenu-tests.el
- imenu.el info.el isearch.el ispell.el json-tests.el json.el
- message-tests.el package.el rmc.el sequences.texi xref.el
+and changed auth.texi checkdoc.el ispell.el message.el seq-tests.el
+ seq.el simple-tests.el simple.el auth-source.el autorevert.el
+ checkdoc-tests.el imenu-tests.el imenu.el info.el isearch.el
+ json-tests.el json.el message-tests.el package.el rmc.el sequences.texi
+ xref.el
Damien Elmes: changed erc.el erc-dcc.el erc-track.el erc-log.el
erc-pcomplete.el README erc-button.el erc-nets.el erc-ring.el Makefile
@@ -898,12 +1047,12 @@ Dan Christensen: changed gnus-sum.el nndoc.el nnfolder.el gnus-art.el
spam.el time-date.el
Dan Davison: wrote ob-matlab.el ob-octave.el
-and co-wrote ob-R.el ob-core.el ob-exp.el ob-lob.el ob-perl.el
+and co-wrote ob-R.el ob-core.el ob-exp.el ob-java.el ob-lob.el ob-perl.el
ob-python.el ob-ref.el org-src.el
and changed ob.el ob-sh.el org.el ox.el ox-latex.el ob-tangle.el ob-C.el
- ob-asymptote.el ob-clojure.el ob-haskell.el ob-ruby.el ob-scheme.el
- ob-table.el ob-ditaa.el ob-dot.el ob-gnuplot.el ob-js.el ob-mscgen.el
- ob-ocaml.el ob-org.el ob-plantuml.el and 14 other files
+ ob-clojure.el ob-haskell.el ob-ruby.el ob-scheme.el ob-table.el
+ ob-ditaa.el ob-dot.el ob-gnuplot.el ob-js.el ob-ocaml.el ob-org.el
+ ob-plantuml.el ob-sass.el ob-screen.el and 12 other files
Daniel Barrett: changed dbnotn.rnc
@@ -919,7 +1068,7 @@ and co-wrote js.el
and changed keyboard.c emacs.c w32fns.c alloc.c image.c cl-macs.el lisp.h
src/Makefile.in configure.ac frame.c frame.el process.c xterm.el
sh-script.el xfaces.c coding.c cygw32.c data.c dbusbind.c fns.c font.c
- and 216 other files
+ and 213 other files
Daniel Dehennin: changed gnus-mlspl.el mml2015.el gnus-msg.el gnus.texi
mm-decode.el nnmail.el ox.el
@@ -931,6 +1080,10 @@ Daniel Elliott: changed octave.el
Daniel Engeler: changed sysdep.c elisp.texi emacs.texi internals.texi
misc.texi process.c process.h processes.texi term.el w32.c w32.h
+Daniele Nicolodi: changed url-http.el
+
+Daniel Gröber: changed rxvt.el
+
Daniel Hackney: wrote package-tests.el
and co-wrote package.el
and changed package-test.el package-x.el ange-ftp.el
@@ -943,20 +1096,31 @@ Daniel Jensen: changed apropos.el
Daniel Kahn Gillmor: changed mml-sec.el
-Daniel Koning: changed artist.el commands.texi subr.el
+Daniel Koning: changed simple.el artist.el commands.texi subr.el
Daniel LaLiberte: wrote cust-print.el edebug.el isearch.el
and co-wrote hideif.el
and changed mlconvert.el eval-region.el
+Daniel Lenski: changed speedbar.el
+
Daniel Lopez: changed progmodes/compile.el
Daniel Lublin: changed dns-mode.el
+Daniel Martín: changed shortdoc.el nsterm.m erc.texi files.el files.texi
+ msdos-xtra.texi ns-win.el basic.texi cmacexp.el compilation.txt
+ compile-tests.el cscope.el diff.el dired.el editfns.c emacs.texi
+ files-tests.el find-func-tests.el find-func.el frame.c frame.el
+ and 16 other files
+
Daniel McClanahan: changed lisp-mode.el
Daniel M Coffman: changed arc-mode.el
+Daniel Mendler: changed minibuffer.el minibuf.texi simple.el help-fns.el
+ info.el minibuf.c minibuffer-tests.el xref.el
+
Daniel M German: co-wrote org-protocol.el
Daniel Néri: changed message.el
@@ -983,6 +1147,8 @@ Daniel Ralston: changed rcirc.el
Daniel Schoepe: changed gnus-sum.el
+Daniel Semyonov: changed mairix.el
+
Dani Moncayo: changed msys-to-w32 Makefile.in configure.ac buffers.texi
lists.texi mini.texi INSTALL README.W32 basic.texi custom.texi
dired.texi display.texi emacs-lisp-intro.texi files.texi killing.texi
@@ -993,15 +1159,19 @@ and co-wrote hideshow.el
and changed vc.el configure.ac vc-hg.el vc-git.el src/Makefile.in
vc-bzr.el sysdep.c emacs.c process.c vc-cvs.el lisp.h term.c
vc-hooks.el xterm.c keyboard.c vc-svn.el xterm.el callproc.c darwin.h
- term.el gnu-linux.h and 921 other files
+ term.el gnu-linux.h and 920 other files
Danny Roozendaal: wrote handwrite.el
Danny Siu: changed gnus-sum.el gnus-picon.el nndoc.el nnimap.el smiley.el
+Dan Ports: changed configure.ac
+
Dan Rosenberg: changed movemail.c
-Dario Gjorgjevski: changed auth-source.el recentf.el syntax.el
+Dario Gjorgjevski: changed progmodes/python.el project.el auth-source.el
+ cus-edit.el erc-desktop-notifications.el ido.el minibuffer-tests.el
+ recentf.el sh-script.el syntax.el tramp.el xml.el
Darren Hoo: changed db-find.el db.el gnus-art.el isearch.el man.el
nsmenu.m startup.el
@@ -1027,7 +1197,7 @@ and co-wrote latin-ltx.el socks.el
and changed configure.ac help.el mule-cmds.el fortran.el mule-conf.el
xterm.c browse-url.el mule.el coding.c src/Makefile.in european.el
fns.c mule-diag.el simple.el wid-edit.el cus-edit.el cus-start.el
- files.el keyboard.c byte-opt.el info.el and 772 other files
+ files.el keyboard.c byte-opt.el info.el and 771 other files
Dave Pearson: wrote 5x5.el quickurl.el
@@ -1063,8 +1233,10 @@ David De La Harpe Golden: changed files.el mouse.el simple.el fileio.c
cus-start.el nsselect.m select.el w32-fns.el x-win.el xterm.c
David Edmondson: changed message.el erc.el mml2015.el process.c
- gnus-cite.el imap.el mm-uu.el mm-view.el nnfolder.el nnimap.el nnml.el
- rcirc.el shr.el
+ gnus-cite.el gnus-cloud.el gnus.texi imap.el mm-uu.el mm-view.el
+ nnfolder.el nnimap.el nnml.el rcirc.el shr.el
+
+Davide Masserut: changed bindings.el basic.texi
David Engster: wrote mairix.el nnmairix.el
and co-wrote gitmerge.el
@@ -1072,7 +1244,7 @@ and changed cedet/semantic.el db.el insert.el semantic/complete.el c.by
c.el db-el.el db-file.el db-find.el ede-grammar.el eieio-opt.el
eieio.el eieio.texi gnus.texi registry.el srecode/compile.el
wisent/python.el analyze.el bovine/el.el bovine/grammar.el
- decorate/mode.el and 87 other files
+ decorate/mode.el and 88 other files
David Gillespie: wrote calc-aent.el calc-alg.el calc-arith.el calc-bin.el
calc-comb.el calc-cplx.el calc-embed.el calc-ext.el calc-fin.el
@@ -1139,7 +1311,7 @@ and changed mode-clone.el
David Michael: changed files.el
David M. Koppelman: wrote hi-lock.el
-and changed display.texi
+and changed display.texi userlock.el
David Moore: co-wrote nnvirtual.el
and changed gnus-xmas.el
@@ -1195,13 +1367,15 @@ Debarshi Ray: changed erc-backend.el erc.el
Decklin Foster: changed nngateway.el
-Deepak Goel: changed idlw-shell.el ada-xref.el feedmail.el files.el
- find-func.el flymake.el mh-search.el mh-seq.el mh-thread.el mh-xface.el
- org.el simple.el vc.el vhdl-mode.el wdired.el README ada-mode.el
- allout.el appt.el apropos.el artist.el and 85 other files
+Deepak Goel: changed idlw-shell.el feedmail.el files.el find-func.el
+ flymake.el mh-search.el mh-seq.el mh-thread.el mh-xface.el org.el
+ simple.el vc.el vhdl-mode.el wdired.el README allout.el appt.el
+ apropos.el artist.el bibtex.el bindings.el and 83 other files
D. E. Evans: changed basic.texi
+Deneb Meketa: changed progmodes/python.el
+
Denis B. Roegel: co-wrote solar.el
Denis Bueno: changed autorevert.el
@@ -1228,6 +1402,8 @@ Derek Peschel: changed etags.c
Derek Upham: changed nxml-mode.el
+Derek Zhou: changed process.c
+
Detlev Zundel: wrote re-builder.el
and changed buffer.c
@@ -1243,7 +1419,11 @@ Diane Murray: changed erc.el erc-backend.el erc-menu.el erc-button.el
erc-goodies.el erc-ibuffer.el erc-log.el erc-nicklist.el url-http.el
Makefile erc-dcc.el and 36 other files
-Dick R. Chiang: changed checkdoc.el cl-macs-tests.el cl-macs.el
+Dick R. Chiang: changed ffap-tests.el ffap.el gnus-group.el gnus.texi
+ message.el bindings.el buffer-tests.el buffer.c checkdoc.el
+ cl-macs-tests.el cl-macs.el comint-tests.el gnus-srvr.el gnus-sum.el
+ gnus-topic.el gnutls.c key.pub key.sec minibuffer.el misc.texi mml.el
+ and 7 other files
Didier Verna: wrote gnus-diary.el nndiary.el
and co-wrote nnml.el
@@ -1263,7 +1443,7 @@ Dima Kogan: wrote diff-mode-tests.el
and changed diff-mode.el erc-backend.el image.c font.c gud.el hideshow.el
autorevert.el comint.el find-file.el subword.el BOOST.tests PCRE.tests
PTESTS TESTS align.el alloc.c ediff-mult.el ediff.el erc-button.el
- isearch.el keyboard.c and 11 other files
+ isearch.el keyboard.c and 12 other files
Dirk Herrmann: co-wrote bibtex.el
@@ -1271,12 +1451,14 @@ Dirk-Jan C. Binnema: changed org-agenda.el
Dirk Ullrich: changed ispell.el
+Dmitrii Kuragin: changed ispell.el
+
Dmitri Paduchikh: changed advice.el
Dmitry Antipov: changed lisp.h xdisp.c alloc.c xterm.c frame.c buffer.c
xfns.c window.c font.c w32term.c frame.h keyboard.c nsterm.m w32fns.c
editfns.c xterm.h xfaces.c dispnew.c fileio.c dispextern.h fns.c
- and 278 other files
+ and 277 other files
Dmitry Bolshakov: changed hideshow.el
@@ -1287,11 +1469,11 @@ Dmitry Gorbik: changed org.el
Dmitry Gutov: wrote elisp-mode-tests.el jit-lock-tests.el json-tests.el
vc-hg-tests.el xref-tests.el
-and changed ruby-mode.el xref.el project.el vc-git.el elisp-mode.el
- etags.el ruby-mode-tests.el js.el package.el vc-hg.el vc.el
- symref/grep.el log-edit.el dired-aux.el simple.el minibuffer.el
- menu-bar.el package-test.el progmodes/grep.el vc-svn.el eldoc.el
- and 111 other files
+and changed xref.el ruby-mode.el project.el vc-git.el elisp-mode.el
+ etags.el ruby-mode-tests.el js.el vc.el vc-hg.el package.el
+ symref/grep.el dired-aux.el simple.el log-edit.el minibuffer.el
+ progmodes/grep.el ido.el maintaining.texi menu-bar.el package-test.el
+ and 123 other files
Dmitry Kurochkin: changed isearch.el
@@ -1311,6 +1493,10 @@ Don Woods: changed replace.el
Doug Cutting: co-wrote disass.el
+Doug Davis: changed elisp-mode.el progmodes/python.el
+
+Doug Gilmore: changed xterm.c
+
Douglas Lewan: changed TUTORIAL.pt_BR
Doug Maxey: changed mouse.el
@@ -1319,12 +1505,16 @@ Drake Wilson: changed emacsclient.c files.el misc.texi
Drew Adams: wrote light-blue-theme.el
and co-wrote color.el
-and changed dired.el cus-edit.el imenu.el info.el ls-lisp.el faces.el
- files.el help-mode.el help.el isearch.el menu-bar.el modes.texi
- mouse.el ange-ftp.el apropos.el bindings.el bookmark.el custom.el
- descr-text.el dired-aux.el dired.texi and 18 other files
+and changed dired.el cus-edit.el imenu.el info.el ls-lisp.el menu-bar.el
+ dired.texi faces.el files.el frame.el help-fns.el help-mode.el help.el
+ help.texi isearch.el modes.texi mouse.el wid-edit.el ange-ftp.el
+ apropos.el bindings.el and 22 other files
+
+Earl Hyatt: changed ffap.el seq-tests.el sequences.texi windows.texi
+ control.texi cus-edit.el hi-lock.el misc.texi pcase-tests.el pcase.el
+ replace.el search.texi seq.el tab-bar.el
-E. Choroba: changed simple.el
+E. Choroba: changed cperl-mode.el simple.el
Edison Ibañez: changed auth-source-pass-tests.el
@@ -1361,6 +1551,8 @@ Eirik Fuller: changed ralloc.c xterm.c
E. Jay Berkenbilt: changed b2m.c flyspell.el ispell.el unrmail.el
whitespace.el window.h
+Elad Lahav: changed configure.ac
+
Elias Oltmanns: changed tls.el gnus-agent.el gnus-cite.el gnus-int.el
gnus-srvr.el gnus.el nnimap.el
@@ -1373,13 +1565,19 @@ and changed simple.el dired.el
Eli Tziperman: wrote rmail-spam-filter.el
Eli Zaretskii: wrote [bidirectional display in xdisp.c]
- [tty menus in term.c] abbrev-tests.el bidi.c biditest.el
- chartab-tests.el coding-tests.el doc-tests.el etags-tests.el rxvt.el
- tty-colors.el
-and changed xdisp.c msdos.c w32.c display.texi w32fns.c simple.el
- files.el fileio.c keyboard.c w32term.c w32proc.c emacs.c files.texi
- text.texi dispnew.c frames.texi lisp.h dispextern.h window.c process.c
- term.c and 1188 other files
+ [tty menus in term.c] abbrev-tests.el bidi.c biditest.el cham.el
+ chartab-tests.el coding-tests.el etags-tests.el rxvt.el tty-colors.el
+and co-wrote help-tests.el
+and changed xdisp.c display.texi w32.c msdos.c w32fns.c simple.el
+ files.el fileio.c keyboard.c emacs.c w32term.c text.texi dispnew.c
+ w32proc.c files.texi frames.texi configure.ac lisp.h dispextern.h
+ process.c editfns.c and 1231 other files
+
+Eliza Velasquez: changed server.el
+
+Ellington Santos: changed battery.el
+
+Emacs-F: changed rmail-spam-filter.el
Emanuele Giaquinta: changed configure.ac rxvt.el charset.c etags.c
fontset.c frame.el gnus-faq.texi loadup.el lread.c sh-script.el
@@ -1391,20 +1589,21 @@ Emilio C. Lopes: changed woman.el cmuscheme.el help.el vc.el advice.el
animate.el apropos.el artist.el bookmark.el cal-menu.el calc-prog.el
calc-store.el calcalg3.el calendar.el calendar.texi checkdoc.el
code-pages.el codepage.el completion.el cus-edit.el diff.el
- and 57 other files
+ and 58 other files
Emmanuel Briot: wrote xml.el
-and changed ada-mode.el ada-stmt.el ada-prj.el ada-xref.el
+and changed ada-stmt.el
Era Eriksson: changed bibtex.el dired.el json.el ses.el ses.texi shell.el
tramp.el tramp.texi
-Eric Abrahamsen: wrote gnus-test-headers.el
-and changed gnus-sum.el gnus-group.el gnus-start.el gnus-registry.el
- eieio-base.el nnimap.el gnus.texi nnir.el gnus-agent.el registry.el
- gnus-srvr.el gnus.el eieio.el gnus-score.el files.el files.texi
- gnus-art.el gnus-cache.el nnmail.el nnmaildir.el nnrss.el
- and 43 other files
+Eric Abrahamsen: wrote gnus-dbus.el gnus-search-tests.el gnus-search.el
+ gnus-test-headers.el
+and changed gnus-sum.el gnus-group.el gnus-registry.el gnus-start.el
+ gnus.texi eieio-base.el nnimap.el nnir.el gnus-agent.el gnus.el
+ registry.el gnus-srvr.el eieio.el gnus-cache.el gnus-msg.el
+ gnus-score.el message.el files.el files.texi gnus-art.el gnus-util.el
+ and 50 other files
Eric Bélanger: changed image.c
@@ -1430,62 +1629,61 @@ Eric Marsden: changed gnus-cache.el url-util.el
Eric M. Ludlam: wrote analyze.el analyze/complete.el analyze/debug.el
args.el auto.el autoconf-edit.el base.el bovine.el bovine/debug.el
- bovine/el.el bovine/make.el c.el cedet-cscope.el cedet-files.el
- cedet-global.el cedet-idutils.el cedet-utests.el cedet/semantic.el
- cedet/srecode.el checkdoc.el config.el cpp-root.el cscope.el
- data-debug.el db-debug.el db-el.el db-file.el db-find.el db-global.el
- db-mode.el db-ref.el db-typecache.el db.el decorate.el decorate/mode.el
- dep.el detect.el dframe.el dictionary.el doc.el document.el
- ede-grammar.el ede-tests.el ede.el ede/custom.el ede/dired.el
- ede/files.el ede/generic.el ede/linux.el ede/locate.el ede/make.el
- ede/shell.el ede/simple.el ede/speedbar.el ede/srecode.el ede/util.el
- edit.el eieio-base.el eieio-compat.el eieio-core.el eieio-custom.el
- eieio-datadebug.el eieio-opt.el eieio-speedbar.el
- eieio-test-methodinvoke.el eieio-test-persist.el eieio-tests.el
- eieio.el emacs-lisp/chart.el emacs.el expandproto.el extract.el
- ezimage.el fcn.el fields.el filter.el filters.el fw.el gcc.el getset.el
- global.el html.el ia-sb.el ia.el idle.el idutils.el include.el
- insert.el inversion.el javascript.el lex-spp.el lex.el list.el
- makefile-edit.el map.el mru-bookmark.el pconf.el pmake.el
- proj-archive.el proj-aux.el proj-comp.el proj-elisp.el proj-info.el
- proj-misc.el proj-obj.el proj-prog.el proj-scheme.el proj-shared.el
- proj.el project-am.el pulse.el refs.el sb-image.el sb.el scm.el
- scope.el semantic-tests.el semantic-utest-c.el semantic-utest-fmt.el
+ bovine/el.el bovine/make.el c.el cedet-cscope.el cedet-files-tests.el
+ cedet-files.el cedet-global.el cedet-idutils.el cedet-utests.el
+ cedet/semantic.el cedet/srecode.el checkdoc.el config.el cpp-root.el
+ cscope.el data-debug.el db-debug.el db-el.el db-file.el db-find.el
+ db-global.el db-mode.el db-ref.el db-typecache.el db.el decorate.el
+ decorate/mode.el dep.el detect.el dframe.el dictionary.el doc.el
+ document-tests.el document.el ede-grammar.el ede-tests.el ede.el
+ ede/custom.el ede/dired.el ede/files.el ede/generic.el ede/linux.el
+ ede/locate.el ede/make.el ede/shell.el ede/simple.el ede/speedbar.el
+ ede/srecode.el ede/util.el edit.el eieio-base.el eieio-compat.el
+ eieio-core.el eieio-custom.el eieio-datadebug.el eieio-opt.el
+ eieio-speedbar.el eieio-test-methodinvoke.el eieio-test-persist.el
+ eieio-tests.el eieio.el emacs-lisp/chart.el emacs.el expandproto.el
+ extract.el ezimage.el fcn.el fields-tests.el fields.el filter.el
+ filters.el format-tests.el fw-tests.el fw.el gcc-tests.el gcc.el
+ getset.el global.el html.el ia-sb.el ia.el idle.el idutils.el
+ include.el insert.el inversion-tests.el inversion.el javascript.el
+ lex-spp.el lex.el list.el makefile-edit.el map.el mru-bookmark.el
+ pconf.el pmake.el proj-archive.el proj-aux.el proj-comp.el
+ proj-elisp.el proj-info.el proj-misc.el proj-obj.el proj-prog.el
+ proj-scheme.el proj-shared.el proj.el project-am.el pulse.el refs.el
+ sb-image.el sb.el scm.el scope.el semantic-tests.el semantic-utest-c.el
semantic-utest-ia.el semantic-utest.el semantic/chart.el
semantic/complete.el semantic/ctxt.el semantic/debug.el
semantic/find.el semantic/format.el semantic/imenu.el semantic/sort.el
semantic/texi.el semantic/util.el source.el speedbar.el
- srecode-tests.el srecode/compile.el srecode/ctxt.el srecode/el.el
- srecode/find.el srecode/java.el srecode/mode.el srecode/semantic.el
- srecode/table.el srecode/texi.el srt.el symref.el symref/grep.el
- system.el tag-file.el tag-ls.el tag-write.el tag.el test-fmt.el test.el
+ srecode/compile.el srecode/ctxt.el srecode/el.el srecode/find.el
+ srecode/java.el srecode/mode.el srecode/semantic.el srecode/table.el
+ srecode/texi.el srt.el symref.el symref/grep.el system.el tag-file.el
+ tag-ls.el tag-write.el tag.el test.el
and co-wrote db-ebrowse.el srecode/cpp.el util-modes.el
and changed c.srt ede.texi info.el rmail.el speedbspec.el cedet.el
ede-autoconf.srt ede-make.srt eieio.texi gud.el sb-dir-minus.xpm
sb-dir-plus.xpm sb-dir.xpm sb-mail.xpm sb-pg-minus.xpm sb-pg-plus.xpm
sb-pg.xpm sb-tag-gt.xpm sb-tag-minus.xpm sb-tag-plus.xpm
- and 50 other files
+ and 35 other files
-Eric Schulte: wrote ob-asymptote.el ob-awk.el ob-calc.el ob-comint.el
- ob-coq.el ob-css.el ob-ditaa.el ob-dot.el ob-emacs-lisp.el ob-eval.el
- ob-forth.el ob-gnuplot.el ob-haskell.el ob-java.el ob-js.el ob-latex.el
- ob-makefile.el ob-ocaml.el ob-org.el ob-ruby.el ob-sass.el ob-shell.el
- ob-shen.el ob-sql.el ob-sqlite.el ob-table.el ob-tangle.el ob.el
- org-plot.el
+Eric Schulte: wrote ob-awk.el ob-calc.el ob-comint.el ob-css.el
+ ob-ditaa.el ob-dot.el ob-emacs-lisp.el ob-eval.el ob-forth.el
+ ob-gnuplot.el ob-haskell.el ob-js.el ob-latex.el ob-makefile.el
+ ob-ocaml.el ob-org.el ob-ruby.el ob-sass.el ob-shell.el ob-sql.el
+ ob-sqlite.el ob-table.el ob-tangle.el ob.el org-plot.el
and co-wrote ob-C.el ob-R.el ob-core.el ob-exp.el ob-fortran.el
- ob-lisp.el ob-lob.el ob-maxima.el ob-perl.el ob-picolisp.el
- ob-python.el ob-ref.el ob-scheme.el ol-bibtex.el
+ ob-java.el ob-lisp.el ob-lob.el ob-maxima.el ob-perl.el ob-python.el
+ ob-ref.el ob-scheme.el ol-bibtex.el
and changed org.texi org.el ob-clojure.el org-exp-blocks.el ob-sh.el
org-bibtex.el ox.el ox-latex.el org-src.el ob-plantuml.el ob-keys.el
ob-screen.el org-macs.el org-table.el org-agenda.el org-mouse.el
- orgcard.tex ob-lilypond.el ob-mscgen.el ob-octave.el org-clock.el
- and 16 other files
+ orgcard.tex ob-lilypond.el ob-octave.el org-clock.el org-compat.el
+ and 13 other files
-Eric S Fraga: wrote ob-ledger.el
-and co-wrote ob-maxima.el
+Eric S Fraga: co-wrote ob-maxima.el
and changed ox-icalendar.el org.texi ox-latex.el
-Eric Skoglund: changed esh-proc.el eshell.texi
+Eric Skoglund: changed esh-proc.el eshell.texi replace.el
Eric S. Raymond: wrote AT386.el asm-mode.el cookie1.el finder.el gud.el
lisp-mnt.el loadhist.el
@@ -1513,6 +1711,10 @@ Erik Toubro Nielsen: changed gnus-sum.el gnus-topic.el
Ernest Adrogué: changed european.el latin-pre.el mule-cmds.el
+Ernest N. Mamikonyan: changed texinfo.el
+
+Ernesto Alfonso: changed simple.el
+
E Sabof: changed hi-lock.el image-dired.el
Espen Skoglund: wrote pascal.el
@@ -1524,9 +1726,7 @@ Ethan Bradford: changed ispell.el ange-ftp.el gnus.el gnuspost.el lpr.el
Ethan Ligon: changed org-docbook.el ox-html.el
-Etienne Prud'homme: changed align.el
-
-Etienne Prud’Homme: changed css-mode-tests.el css-mode.el
+Etienne Prud’Homme: changed align.el css-mode-tests.el css-mode.el
Eugene Exarevsky: changed sql.el
@@ -1551,7 +1751,10 @@ Eyal Lotem: changed ido.el
Fabián Ezequiel Gallina: wrote progmodes/python.el subr-x-tests.el
and changed python-tests.el subr-x.el imenu.el wisent/python.el
-Fabrice Bauzac: changed dired-aux.el fixit.texi search.texi
+Fabrice Bauzac: changed objects.texi dired-aux.el fixit.texi ibuf-ext.el
+ search.texi
+
+Fabrice Nicol: changed etags.c etags.1
Fabrice Niessen: wrote leuven-theme.el
and changed org-agenda.el
@@ -1559,7 +1762,7 @@ and changed org-agenda.el
Fabrice Popineau: changed w32.c ms-w32.h w32fns.c w32heap.c w32term.c
configure.ac lisp.h unexw32.c buffer.c emacs.c image.c w32heap.h
w32proc.c w32term.h INSTALL addsection.c alloc.c dispextern.h
- emacs-x64.manifest emacs-x86.manifest etags.c and 25 other files
+ emacs-regex.c emacs-x64.manifest emacs-x86.manifest and 25 other files
Fan Kai: changed esh-arg.el
@@ -1568,14 +1771,14 @@ Faried Nawaz: changed message.el
Federico Beffa: changed xscheme.el
Federico Tedin: wrote tempo-tests.el
-and changed minibuf.c mouse.el package.el rect.el cursor-sensor.el
- cus-start.el doc-view.el edebug.el eww.el files.texi gamegrid.el
- keyboard.c minibuf.texi package-tests.el package.texi simple.el
- tempo.el vc-git.el xfaces.c
+and changed minibuf.c esh-var.el minibuf.texi mouse.el package.el rect.el
+ simple.el tempo.el coding.c cursor-sensor.el cus-start.el doc-view.el
+ edebug.el em-dirs.el eshell-tests.el eww.el fileio-tests.el fileio.c
+ files.texi gamegrid.el keyboard.c and 8 other files
Felicián Németh: changed project.el xref.el
-Felipe Ochoa: changed faces.el js.el js.js paren.el
+Felipe Ochoa: changed faces.el js.el paren.el
Felix E. Klee: co-wrote svg.el
and changed display.texi
@@ -1593,18 +1796,20 @@ Feng Li: changed calc-ext.el pascal.el which-func.el
Feng Shu: changed org.el org.texi ox.el ox-html.el ox-latex.el ox-odt.el
+Ferdinand Pieper: changed flow-fill-tests.el flow-fill.el
+
Ferenc Wagner: changed nnweb.el
Filipe Cabecinhas: changed nsterm.m
-Filipp Gunbin: changed auth-source-tests.el auth-source.el autorevert.el
- compilation.txt dired-aux.el gnus-ml.el progmodes/compile.el shell.el
- cc-menus.el custom.el dabbrev.el gnus-sum.el imenu.el info.el info.texi
- ldap.el search.texi sql.el
-
-Fix Bug#24483.: changed sql.el sql-tests.el
+Filipp Gunbin: changed compilation.txt progmodes/compile.el
+ auth-source-tests.el auth-source.el autorevert.el dired-aux.el
+ gnus-ml.el shell.el sysdep.c cc-menus.el compile-tests.el custom.el
+ dabbrev.el gnus-sum.el imenu.el info.el info.texi keymaps.texi ldap.el
+ processes.texi search.texi and 3 other files
-Fix Bug#35307.: changed sql.el
+F. Jason Park: changed socks-tests.el erc-tests.el erc.el socks.el
+ erc-button.el erc-ring.el erc-services.el puny-tests.el puny.el
Flemming Hoejstrup Hansen: changed forms.el
@@ -1614,6 +1819,8 @@ Florian Beck: changed org.el
Florian Ragwitz: changed gnus-html.el mail/sieve-manage.el
+Florian V. Savigny: changed sql.el
+
Florian Weimer: changed message.el gnus.el coding.c gnus-sum.el gnus.texi
mm-decode.el mm-util.el
@@ -1623,7 +1830,7 @@ Francesco Potortì: wrote cmacexp.el
and changed etags.c man.el delta.h etags.1 undigest.el rmail.el comint.el
configure.ac maintaining.texi uniquify.el latin-post.el etags.el
latin-alt.el lib-src/Makefile.in sgml-mode.el Makefile.in data.c
- european.el filelock.c files.el generic-x.el and 44 other files
+ european.el filelock.c files.el generic-x.el and 45 other files
Francesc Rocher: changed splash.png splash.svg startup.el README
cus-start.el gnus.el gnus.png gnus.svg macterm.c splash.pbm splash.xpm
@@ -1701,12 +1908,16 @@ Fujii Hironori: changed w32fns.c
Gábor Vida: changed gnus-demon.el auth-source.el ido.el
+Gabriel Do Nascimento Ribeiro: changed remember.el mb-depth.el repeat.el
+ tab-line.el cmuscheme.el comint.el esh-mode.el etags.el gnus-sum.el
+ hl-line.el idlwave.el inf-lisp.el mh-gnus.el mh-letter.el mh-mime.el
+ mh-seq.el mh-utils.el minibuf.c minibuffer.el mule-cmds.el package.el
+ and 10 other files
+
Gaby Launay: changed auth-source-pass.el
Gareth Jones: changed fns.c gnus-score.el
-Gareth Rees: changed NEWS.24
-
Garrett Wollman: changed sendmail.el
Gary Delp: wrote mailpost.el (public domain)
@@ -1730,11 +1941,11 @@ Geert Kloosterman: changed which-func.el
Gemini Lasswell: wrote backtrace-tests.el backtrace.el edebug-tests.el
kmacro-tests.el testcover-tests.el thread-tests.el thread.el
-and changed edebug.el cl-print.el edebug.texi cl-print-tests.el
- debugging.texi cl-macs.el emacs-lisp/debug.el edebug-test-code.el
- subr.el testcases.el testcover.el cl-generic.el ert-x.el eval.c
- eieio-compat.el elisp.texi ert.el ert.texi eval-tests.el generator.el
- print.c and 24 other files
+and changed edebug.el cl-print.el edebug.texi emacs-lisp/debug.el
+ cl-print-tests.el debugging.texi cl-macs.el edebug-test-code.el subr.el
+ testcases.el testcover.el cl-generic.el ert-x.el eval.c eieio-compat.el
+ elisp.texi ert.el ert.texi eval-tests.el generator.el print.c
+ and 24 other files
Geoff Gole: changed align.el ibuffer.el whitespace.el
@@ -1765,7 +1976,7 @@ Gerd Möllmann: wrote authors.el ebrowse.el jit-lock.el tooltip.el
and changed xdisp.c xterm.c dispnew.c dispextern.h xfns.c xfaces.c
window.c keyboard.c lisp.h faces.el alloc.c buffer.c startup.el xterm.h
fns.c simple.el term.c configure.ac frame.c xmenu.c emacs.c
- and 610 other files
+ and 607 other files
Gergely Nagy: changed erc.el
@@ -1786,24 +1997,30 @@ Giuliano Procida: changed perl-mode.el
Giuseppe Scrivano: changed browse-url.el buffer.c configure.ac sysdep.c
xsmfns.c
+G. Jay Kerns: wrote ob-julia.el
+
Glenn Morris: wrote check-declare.el f90-tests.el vc-bzr-tests.el
and changed configure.ac Makefile.in src/Makefile.in calendar.el
- diary-lib.el lisp/Makefile.in files.el make-dist rmail.el
- progmodes/f90.el bytecomp.el simple.el authors.el admin.el startup.el
- emacs.texi misc/Makefile.in display.texi lib-src/Makefile.in ack.texi
- subr.el and 1760 other files
+ lisp/Makefile.in diary-lib.el files.el make-dist rmail.el
+ progmodes/f90.el bytecomp.el admin.el misc/Makefile.in simple.el
+ authors.el startup.el emacs.texi lib-src/Makefile.in display.texi
+ ack.texi subr.el and 1790 other files
Glynn Clements: wrote gamegrid.el snake.el tetris.el
Göktuğ Kayaalp: changed electric.el european.el text.texi vc-cvs.el
vc-hg.el
+Gong Qijian: changed startup.el
+
Göran Uddeborg: changed isc4-1.h
Gordon Matzigkeit: changed gnus-uu.el
Graham Dobbins: changed lisp-mode.el
+Grant Shangreaux: changed HELLO latin-post.el latin-pre.el
+
Greg A. Woods: co-wrote pcvs.el
Greg Hill: changed bytecomp.el
@@ -1818,11 +2035,10 @@ and changed tar-mode.el
Gregoire Jadi: changed proced.el
-Grégoire Jadi: changed org.texi emacsgtkfixed.c keyboard.c rcirc.el
- xwidget.c xwidget.el Makefile.in cl-generic.el configure.ac
- dispextern.h dispnew.c emacs.c latin-post.el lisp.h ob-core.el
- org-id.el org.el print.c reporter.el sendmail.el shr.el
- and 6 other files
+Grégoire Jadi: changed org.texi configure.ac emacsgtkfixed.c keyboard.c
+ rcirc.el xwidget.c xwidget.el Makefile.in bibtex-tests.el bibtex.el
+ cl-generic.el dispextern.h dispnew.c emacs.c latin-post.el lisp.h
+ ob-core.el org-id.el org.el print.c reporter.el and 8 other files
Gregorio Gervasio, Jr.: changed gnus-sum.el
@@ -1833,11 +2049,16 @@ Gregor Schmid: changed intervals.c intervals.h tcl-mode.el textprop.c
Gregory Chernov: changed nnslashdot.el
-Grégory Mounié: changed display.texi hi-lock.el man.el
+Gregory Heytings: changed isearch.el minibuffer.el mini.texi quail.el
+ search.texi simple.el HELLO buffers.texi diff-mode.el emake facemenu.el
+ files.el fringe.c help-macro.el icomplete.el keyboard.c misc-lang.el
+ modula2.el pcmpl-gnu.el print.c pulse.el and 4 other files
+
+Grégory Mounié: changed display.texi hi-lock.el man.el xfns.c
Gregory Neil Shapiro: changed mailabbrev.el
-Gregor Zattler: changed eshell.texi emacs-lisp-intro.texi
+Gregor Zattler: changed eww.texi eshell.texi emacs-lisp-intro.texi
Greg Stark: changed gnus-ems.el timezone.el
@@ -1882,7 +2103,11 @@ Hans Wennborg: changed emacs.c
Han-Wen Nienhuys: changed emacsclient.c server.el
-Harald Hanche-Olsen: changed sgml-mode.el skeleton.el
+Harald Hanche-Olsen: changed misc.texi server.el sgml-mode.el skeleton.el
+
+Harald Jörg: wrote cperl-mode-tests.el
+and changed cperl-mode.el perl-mode.el grammar.pl cperl-bug-19709.pl
+ cperl-indent-exp.pl cperl-indent-styles.pl
Harald Maier: changed w32heap.c
@@ -1891,14 +2116,14 @@ Harald Meland: changed gnus-art.el gnus-salt.el gnus-score.el
Harri Kiiskinen: changed org-protocol.el ox-publish.el
-H. Dieter Wilhelm: changed calc-help.el maintaining.texi
+H. Dieter Wilhelm: changed calc-help.el maintaining.texi paragraphs.el
Heiko Muenkel: changed b2m.c
-Helmut Eller: changed emacs-lisp/debug.el xref.el CTAGS.good ETAGS.good_1
- ETAGS.good_2 ETAGS.good_3 ETAGS.good_4 ETAGS.good_5 ETAGS.good_6
- cl-indent.el cl-macs.el elisp-mode.el ert.el etags.c etags.el eval.c
- lisp-mode.el process-tests.el process.c test-forth.fth
+Helmut Eller: changed emacs-lisp/debug.el lisp-mode.el xref.el CTAGS.good
+ ETAGS.good_1 ETAGS.good_2 ETAGS.good_3 ETAGS.good_4 ETAGS.good_5
+ ETAGS.good_6 cl-indent.el cl-macs.el elisp-mode.el ert.el etags.c
+ etags.el eval.c process-tests.el process.c test-forth.fth
Helmut Waitzmann: changed gnus-sum.el gnus.texi
@@ -1933,17 +2158,18 @@ Holger Schauer: wrote fortune.el
and changed message-utils.el
Hong Xu: changed etags.el simple.el maintaining.texi minibuf.texi
- paren.el progmodes/python.el search.c editfns.c em-cmpl.el
+ tramp.texi paren.el progmodes/python.el search.c editfns.c em-cmpl.el
emacs-mime.texi files.texi flyspell.el gnus-cite.el message.el
parse-time-tests.el parse-time.el progmodes/cpp.el programs.texi
- python-tests.el subr.el url-util.el and 3 other files
+ python-tests.el subr.el and 4 other files
Hosoya Kei: changed TUTORIAL.ja
Hovav Shacham: wrote windmove.el
Howard Gayle: wrote case-table.el casetab.c iso-ascii.el iso-transl.el
- rot13.el vt100-led.el
+ vt100-led.el
+and co-wrote rot13.el
Howard Melman: changed imenu.el picture.el
@@ -1959,11 +2185,11 @@ Hubert Chan: changed spam.el
Hugh Brown: changed progmodes/grep.el building.texi
-Hynek Schlawack: changed gnus-art.el gnus-sum.el
+Hugh Daschbach: changed dbus-tests.el dbus.el org.gnu.Emacs.TestDBus.xml
-Ian D: changed doc-view.el image-mode.el
+Hynek Schlawack: changed gnus-art.el gnus-sum.el
-Ian Dunn: changed eww.el vc-hg.el
+Ian Dunn: changed eww.el doc-view.el image-mode.el vc-hg.el
Ian Eure: changed sql.el url-util.el
@@ -1976,16 +2202,24 @@ Ian Lance Taylor: changed sco4.h
Ian T Zimmerman: wrote gametree.el
and changed ange-ftp.el desktop.el tex-mode.el
-İ. Göktuğ Kayaalp: changed eww.el frames.texi mwheel.el vc-rcs.el
+Ian W: changed ispell.el
+
+İ. Göktuğ Kayaalp: changed eww.el frame.h frames.texi mwheel.el vc-rcs.el
Igor Kuzmin: wrote cconv.el
+Igor Saprykin: changed ftfont.c
+
+Ihor Radchenko: changed fns.c
+
Iku Iwasa: changed auth-source-pass-tests.el auth-source-pass.el
Ikumi Keita: changed characters.el japan-util.el kinsoku.el minibuf.c
Ilja Weis: co-wrote gnus-topic.el
+Illia Ostapyshyn: changed cus-start.el calc-graph.el
+
Ilya N. Golubev: changed mm-util.el shell.el
Ilya Shlyakhter: changed org.el ob-lilypond.el org-clock.el
@@ -1994,10 +2228,12 @@ Ilya Shlyakhter: changed org.el ob-lilypond.el org-clock.el
Ilya Zakharevich: wrote tmm.el
and co-wrote cperl-mode.el
and changed w32fns.c syntax.c intervals.c syntax.h textprop.c dired.c
- font-lock.el intervals.h regex.c regex.h search.c
+ emacs-regex.c emacs-regex.h font-lock.el intervals.h search.c
Ilya Zonov: changed org-mouse.el
+Imran Khan: changed css-mode.el
+
Indiana University Foundation: changed buffer.c buffer.h indent.c
region-cache.c region-cache.h search.c xdisp.c
@@ -2007,15 +2243,16 @@ Inge Frick: changed easymenu.el keyboard.c view.el compile.el
Inge Wallin: co-wrote avl-tree.el ewoc.el
-Ingo Lohmar: changed calendar.el calendar.texi help-fns.el
- js-indent-align-list-continuation-nil.js js.el ls-lisp.el org-agenda.el
- org.el
+Ingo Lohmar: changed sql.el calendar.el calendar.texi help-fns.el js.el
+ ls-lisp.el org-agenda.el org.el
Inoue Seiichiro: changed xterm.c xfns.c xterm.h
International Business Machines: changed emacs.c fileio.c process.c
sysdep.c unexcoff.c
+Ioannis Kappas: changed package.el process-tests.el
+
Ippei Furuhashi: changed org.texi org-colview.el org-table.el org.el
Irie Shinsuke: changed subr.el
@@ -2028,6 +2265,10 @@ Ismail S: changed org-capture.el
Istvan Marko: changed gnus-agent.el xfns.c
+Itai Seggev: changed src/Makefile.in
+
+Itai Y. Efrat: changed browse-url.el
+
Itai Zukerman: changed mm-decode.el
Ivan Andrus: changed editfns.c epg.el ffap.el find-file.el ibuf-ext.el
@@ -2046,6 +2287,8 @@ Ivan Shmakov: changed eww.el shr.el desktop.el eww.texi faces.el files.el
erc-track.el facemenu.el files.texi iso-transl.el misearch.el nndoc.el
rcirc.el simple.el smerge-mode.el and 5 other files
+Ivan Sokolov: changed ansi-color.el project.el
+
Ivan Vilata i Balaguer: changed org-clock.el org.texi
Ivan Zakharyaschev: changed codepage.el lread.c
@@ -2064,10 +2307,7 @@ Jack Duthen: changed which-func.el
Jack Repenning: changed unexelfsgi.c
-Jackson Ray Hamilton: changed js.el jsx-unclosed-2.jsx jsx.jsx js.js
- jsx-comment-string.jsx files.el jsx-align-gt-with-lt.jsx
- jsx-indent-level.jsx jsx-quote.jsx jsx-self-closing.jsx
- jsx-unclosed-1.jsx sgml-mode.el
+Jackson Ray Hamilton: changed js.el files.el sgml-mode.el
Jack Twilley: changed message.el
@@ -2077,10 +2317,20 @@ Jacques Duthen: co-wrote ps-print.el ps-samp.el
Jae-hyeon Park: changed fontset.el
-Jaesup Kwak: changed xwidget.c
+Jaesup Kwak: changed xwidget.c nsxwidget.m xwidget.el nsxwidget.h
+ xwidget.h Info.plist.in configure.ac emacs.c nsterm.m src/Makefile.in
Jaeyoun Chung: changed hangul3.el hanja3.el gnus-mule.el hangul.el
+Jakub-W: changed calculator.el
+
+J. Alexander Branham: wrote conf-mode-tests.el
+and changed checkdoc.el indent.el text.texi bibtex.el em-rebind.el
+ esh-util.el js.el lpr.el message.el subr.el .dir-locals.el
+ auth-source-pass.el bug-reference.el comint.el conf-mode.el dired-x.el
+ dired.el ediff-diff.el ediff-help.el ediff-hook.el ediff-init.el
+ and 43 other files
+
Jambunathan K: wrote ox-odt.el
and co-wrote ox-html.el
and changed org-lparse.el org.el org.texi ox.el icomplete.el
@@ -2099,6 +2349,8 @@ and changed fns.c nxml-mode.texi window.c xselect.c
James Cloos: wrote arabic.el
and changed url-history.el xfns.c xterm.c xterm.h
+James N. V. Cash: changed tab-bar.el eldoc.el help-fns.el
+
James R. Larus: co-wrote mh-e.el
James R. Van Zandt: changed sh-script.el
@@ -2109,6 +2361,8 @@ James TD Smith: changed org.el org-colview.el org-clock.el
org-remember.el org-plot.el org-agenda.el org-compat.el org-habit.el
org.texi
+James Thomas: changed ind-util.el quail/indian.el
+
James Troup: changed gnus-sum.el
James Van Artsdalen: changed unexcoff.c
@@ -2119,7 +2373,7 @@ Jamie Zawinski: wrote mailabbrev.el tar-mode.el
and co-wrote byte-opt.el byte-run.el bytecomp.el disass.el font-lock.el
and changed bytecode.c mail-extr.el subr.el
-Jan Beich: changed configure.ac mml-smime.el
+Jan Beich: changed configure.ac efaq.texi mml-smime.el term.c
Jan Böcker: wrote ol-docview.el
and changed org.el org-docview.el org.texi
@@ -2128,7 +2382,7 @@ Jan Djärv: wrote dnd.el dynamic-setting.el x-dnd.el
and changed gtkutil.c xterm.c nsterm.m xfns.c configure.ac nsfns.m
xmenu.c xterm.h nsterm.h nsmenu.m gtkutil.h keyboard.c x-win.el emacs.c
frame.c src/Makefile.in process.c xsettings.c cus-start.el nsfont.m
- frames.texi and 304 other files
+ frames.texi and 303 other files
Jan-Hein Buhrman: changed ange-ftp.el env.el
@@ -2146,12 +2400,19 @@ Jan Schormann: wrote solitaire.el
Jan Seeger: changed ox-publish.el parse-time.el
-Jan Tatarik: wrote gnus-icalendar.el
+Jan Synacek: changed emacs-lisp-intro.texi minibuffer.el mwheel.el
+ vc-git.el
+
+Jan Tatarik: wrote gnus-icalendar-tests.el gnus-icalendar.el
and changed gnus-score.el gnus-logic.el
Jan Vroonhof: changed gnus-cite.el gnus-msg.el nntp.el
-Jared Finder: changed progmodes/compile.el
+Jared Finder: changed menu-bar.el term.c commands.texi frame.c isearch.el
+ mouse.el tmm.el wid-edit.el xt-mouse.el artist.el dispnew.c
+ ediff-wind.el ediff.el faces.el foldout.el frames.texi keyboard.c
+ lread.c mouse-drag.el progmodes/compile.el ruler-mode.el
+ and 7 other files
Jarek Czekalski: changed keyboard.c callproc.c mini.texi minibuf.c
misc.texi server.el shell.el w32fns.c xgselect.c
@@ -2161,7 +2422,7 @@ and changed add-log.el filecache.el progmodes/grep.el comint.el
gnus-art.el gnus-sum.el gnus.texi ispell.el lisp-mnt.el man.el
nnmail.el apropos.el autorevert.el checkdoc.el cperl-mode.el
css-mode.el desktop.el em-ls.el emacs-lisp/debug.el emacsclient.1
- executable.el and 23 other files
+ executable.el and 24 other files
Jarmo Hurri: wrote ob-processing.el
and changed org-gnus.el org-table.el org.texi
@@ -2171,10 +2432,15 @@ and changed url-auth.el
Jarosław Rzeszótko: changed ielm.el url-http.el
+Jashank Jeremy: changed elisp-mode.el faces.el frame.c frame.el frame.h
+ xfaces.c
+
Jason Baker: changed gnus-art.el
Jason Dunsmore: changed org.el ox-html.el
+Jason Kim: changed shell.el
+
Jason L. Wright: changed smtpmail.el
Jason Merrill: changed gnus-sum.el add-log.el gnus-salt.el imap.el
@@ -2205,17 +2471,20 @@ Jay McCarthy: changed org-colview.el
Jay Sachs: changed gnus-score.el gnus-win.el
-Jd Smith: co-wrote idlw-help.el idlw-shell.el idlwave.el
-
-J.D. Smith: changed idlwave.el idlw-shell.el idlw-help.el idlw-rinfo.el
- idlw-toolbar.el comint.el idlwave.texi vc.el bibtex.el files.texi
- hideshow.el idlw-complete-structtag.el misc.texi mouse.el
+J.D. Smith: co-wrote idlw-help.el idlw-shell.el idlwave.el
+and changed idlw-rinfo.el idlw-toolbar.el comint.el idlwave.texi vc.el
+ bibtex.el files.texi hideshow.el idlw-complete-structtag.el misc.texi
+ mouse.el
Jean-Christophe Helary: changed emacs-lisp-intro.texi ns-win.el
package-tests.el package.el strings.texi subr-x.el ucs-normalize.el
+Jean Forget: changed cal-french.el
+
Jean Haidouk: changed latin-alt.el latin-post.el latin-pre.el
+Jean Louis: changed dired-aux.el
+
Jean-Philippe Gravel: changed gdb-mi.el
Jean-Philippe Theberge: wrote thumbs.el
@@ -2246,14 +2515,21 @@ and changed mh-e.el mh-comp.el mh-utils.el mh-mime.el mh-customize.el
mh-folder.el mh-funcs.el mh-alias.el mh-seq.el mh-show.el Makefile
bsdos4.h mh-identity.el mh-junk.el mh-letter.el
+Jeff Spencer: changed dired.el
+
+Jeff Walsh: changed xwidget.c
+
Jelle Licht: changed auth-source-pass-tests.el auth-source-pass.el
+Jen-Chieh Shen: changed window.el
+
Jens Krinke: changed smime.el
Jens Lautenbacher: changed gnus.el
-Jens Lechtenboerger: changed mml-sec.el gnus-util.el message.texi
- mml-smime.el mml1991.el mml2015.el message.el package.el package.texi
+Jens Lechtenbörger: wrote gnus-util-tests.el mml-sec-tests.el
+and changed mml-sec.el gnus-util.el message.texi mml-smime.el mml1991.el
+ mml2015.el message.el package.el package.texi
Jens Petersen: wrote find-func.el
and changed mule-cmds.el pcmpl-rpm.el
@@ -2267,15 +2543,13 @@ Jens Uwe Schmidt: changed edebug.el
Jeramey Crawford: changed amdx86-64.h configure.ac
-Jeremie Courreges-Anglas: changed kqueue.c
-
-Jérémie Courrèges-Anglas: changed org.texi ox-latex.el
+Jérémie Courrèges-Anglas: changed kqueue.c org.texi ox-latex.el
Jeremy Bertram Maitin-Shepard: changed erc.el erc-backend.el
erc-button.el erc-track.el mml.el
-Jérémy Compostella: changed tramp-sh.el battery.el keyboard.c windmove.el
- window.el xdisp.c
+Jérémy Compostella: changed tramp-sh.el mml.el battery.el keyboard.c
+ windmove.el window.el xdisp.c
Jeremy Moore: changed hideif.el
@@ -2300,6 +2574,8 @@ and changed gnus-sum.el gnus-art.el message.el gnus-group.el gnus-msg.el
Jhair Tocancipa Triana: changed gnus-audio.el
+Jiacai Liu: changed project.el
+
Jiajie Chen: changed button.el
Jihyun Cho: wrote hangul.el hanja-util.el
@@ -2309,7 +2585,7 @@ and co-wrote pcvs.el wyse50.el
and changed keyboard.c xterm.c xfns.c window.c process.c ymakefile
dispnew.c xdisp.c sysdep.c configure.ac lisp.h Makefile.in keymap.c
configure make-dist buffer.c frame.c screen.c simple.el alloc.c emacs.c
- and 402 other files
+ and 403 other files
Jim Diamond: changed server.el
@@ -2321,13 +2597,20 @@ Jim Meyering: changed lread.c make-docfile.c w32.c w32font.c copyright.el
alloc.c artist.el autoinsert.el buffer.h callproc.c character.h
charset.c configure and 55 other files
-Jimmy Aguilar Mena: changed xdisp.c xfaces.c dispextern.h face-remap.el
- hl-line.el icomplete.el xwidget.c
+Jimmy Aguilar Mena: changed xdisp.c xfaces.c dispextern.h mouse.el
+ face-remap.el hl-line.el icomplete.el uniquify.el xwidget.c
-Jimmy Yuen Ho Wong: changed nsm.el gnutls.c gnutls.el net-utils.el
+Jimmy Yuen Ho Wong: changed nsm.el gnutls.c gnutls.el disass.el
+ net-utils.el
Jim Paris: changed process.c
+Jim Porter: changed delsel.el ansi-color-tests.el ansi-color.el
+ bindings.el term-tests.el term.el tramp.el callproc.c
+ dichromacy-theme.el diff-mode.el files-tests.el gdb-mi.el grep-tests.el
+ ispell.el leuven-theme.el man.el menu-bar.el misterioso-theme.el
+ process.c process.h progmodes/grep.el and 6 other files
+
Jim Radford: changed gnus-start.el
Jim Salem: wrote completion.el
@@ -2363,12 +2646,12 @@ Joanna Pluta: changed TUTORIAL.pl
João Cachopo: changed spam.el
João Távora: wrote elec-pair.el electric-tests.el flymake-cc.el
- jsonrpc-tests.el jsonrpc.el message-tests.el
-and changed flymake.el flymake-proc.el icomplete.el minibuffer.el
- flymake-tests.el flymake.texi elisp-mode.el flymake-elisp.el
- electric.el flymake-ui.el text.texi json-tests.el tex-mode.el
- errors-and-warnings.c json.c xref.el auth-source-pass.el linum.el
- maintaining.texi message.el progmodes/python.el and 30 other files
+ jsonrpc-tests.el jsonrpc.el message-tests.el shorthands.el
+and changed flymake.el icomplete.el minibuffer.el flymake-proc.el
+ eldoc.el elisp-mode.el flymake.texi flymake-tests.el flymake-elisp.el
+ electric.el elisp-mode-tests.el lread.c flymake-ui.el
+ progmodes/python.el text.texi xref.el json-tests.el project.el
+ tex-mode.el buffers.texi cfengine.el and 55 other files
Jochen Hein: changed gnus-art.el
@@ -2438,6 +2721,8 @@ John Anthony: changed inf-lisp.el ruby-mode.el text-mode.el
John Basrai: changed man.el
+John Cummings: changed files.el
+
John F. Carr: changed dired.c
John Fremlin: changed gnus-msg.el message.el
@@ -2502,8 +2787,12 @@ John Yates: changed hideshow.el
Jon Anders Skorpen: changed ox-publish.el
-Jonas Bernoulli: changed eieio.el button.el cus-edit.el ido.el
- lisp-mnt.el tabulated-list.el tips.texi
+Jonas Bernoulli: wrote transient.el
+and changed epa.el epa-file.el lisp-mnt.el tips.texi dired-aux.el
+ dired-x.el dired.el eieio.el epa-dired.el font-lock.el
+ progmodes/compile.el simple.el allout.el button.el comint.el
+ cus-edit.el eldoc.el emacs-module-tests.el epa-hook.el epg-config.el
+ epg.el and 9 other files
Jonas Hoersch: changed org-inlinetask.el org.el
@@ -2534,10 +2823,11 @@ Jonathan Tomer: changed files-tests.el files.el tramp-tests.el
Jonathan Vail: changed vc.el
-Jonathan Yavner: wrote ses.el tcover-ses.el tcover-unsafep.el
- testcover.el unsafep.el
+Jonathan Yavner: wrote ses.el tcover-ses.el testcover.el unsafep-tests.el
+ unsafep.el
and changed ses.texi ses-example.ses edebug.el editfns.c files.el
- functions.texi misc/Makefile.in subr.el variables.texi
+ functions.texi misc/Makefile.in subr.el tcover-unsafep.el
+ variables.texi
Jon Ericson: changed gnus.el spam-report.el
@@ -2560,9 +2850,11 @@ and changed erc.el erc-track.el erc-backend.el erc-match.el misc.el
erc-ibuffer.el erc-macs.el erc-page.el erc-pcomplete.el erc-sound.el
minibuffer.el and 15 other files
-Jose A. Ortega Ruiz: changed gnus-sum.el url-http.el
+Jorge P. De Morais Neto: changed TUTORIAL cl.texi
-Jose E. Marchesi: changed ada-mode.el gomoku.el simple.el smtpmail.el
+Jose A. Ortega Ruiz: changed mixal-mode.el gnus-sum.el url-http.el
+
+Jose E. Marchesi: changed gomoku.el simple.el smtpmail.el
José L. Doménech: changed dired-aux.el
@@ -2594,18 +2886,22 @@ Jostein Kjønigsen: changed nxml-mode.el progmodes/compile.el
Jouni K. Seppänen: changed gnus.texi nnimap.el mm-url.el
+J. Scott Berg: changed xterm.c
+
+Juan José García-Ripoll: changed w32image.c configure.ac image.c
+ w32-win.el w32.c w32term.c w32term.h
+
Juan León Lahoz García: wrote wdired.el
and changed files.el perl-mode.el
-Juanma Barranquero: wrote emacs-lock.el frameset.el help-tests.el
- keymap-tests.el
+Juanma Barranquero: wrote emacs-lock.el frameset.el
+and co-wrote help-tests.el keymap-tests.el
and changed subr.el desktop.el w32fns.c faces.el simple.el emacsclient.c
files.el server.el bs.el help-fns.el xdisp.c org.el w32term.c w32.c
buffer.c keyboard.c ido.el image.c window.c eval.c allout.el
- and 1235 other files
+ and 1226 other files
-Juan Pechiar: wrote ob-mscgen.el
-and changed ob-octave.el
+Juan Pechiar: changed ob-octave.el
Juergen Kreileder: changed imap.el nnimap.el
@@ -2615,7 +2911,7 @@ Jules Tamagnan: changed progmodes/python.el
Julian Gehring: changed org.texi orgcard.tex
-Julian Scheid: changed tramp.el color.el
+Julian Scheid: changed tramp.el cl-extra.el color.el ert.el
Julien Avarre: changed gnus-fun.el
@@ -2635,6 +2931,8 @@ Jun Hao: changed auth-source.el desktop.el
Junio Hamano: changed window.el
+Junya Takahashi: changed epa-file.el
+
Jure Cuhalev: changed ispell.el
Jürgen Hartmann: changed window.el
@@ -2643,12 +2941,12 @@ Jürgen Hötzel: wrote tramp-adb.el
and changed tramp-gvfs.el tramp-sh.el comint.el em-unix.el esh-util.el
tramp-cache.el tramp.el url-handlers.el wid-edit.el
-Juri Linkov: wrote files-x.el misearch.el replace-tests.el tab-bar.el
- tab-line.el
-and changed isearch.el info.el simple.el replace.el dired.el dired-aux.el
- progmodes/grep.el progmodes/compile.el startup.el subr.el diff-mode.el
- files.el menu-bar.el faces.el bindings.el display.texi image-mode.el
- desktop.el comint.el minibuffer.el search.texi and 419 other files
+Juri Linkov: wrote compose.el files-x.el misearch.el repeat-tests.el
+ replace-tests.el tab-bar.el tab-line.el
+and changed isearch.el simple.el info.el replace.el dired.el dired-aux.el
+ progmodes/grep.el subr.el window.el image-mode.el mouse.el diff-mode.el
+ files.el menu-bar.el minibuffer.el progmodes/compile.el startup.el
+ faces.el vc.el display.texi search.texi and 444 other files
Jussi Lahdenniemi: changed w32fns.c ms-w32.h msdos.texi w32.c w32.h
w32console.c w32heap.c w32inevt.c w32term.h
@@ -2661,7 +2959,7 @@ Justin Gordon: changed ox-md.el
Justin Sheehy: changed gnus-sum.el nntp.el
-Justin Timmons: changed progmodes/python.el
+Justin Timmons: changed apropos.el progmodes/python.el
Justus Piater: changed org-agenda.el smtpmail.el
@@ -2672,7 +2970,7 @@ and co-wrote longlines.el tramp-sh.el tramp.el
and changed message.el gnus-agent.el gnus-sum.el files.el nnmail.el
tramp.texi nntp.el gnus.el simple.el ange-ftp.el dired.el paragraphs.el
bindings.el files.texi gnus-art.el gnus-group.el man.el INSTALL
- Makefile.in crisp.el fileio.c and 44 other files
+ Makefile.in crisp.el fileio.c and 45 other files
Kailash C. Chowksey: changed HELLO ind-util.el kannada.el knd-util.el
lisp/Makefile.in loadup.el
@@ -2681,13 +2979,15 @@ Kai Tetzlaff: changed ox-publish.el url-http.el
Kalle Kankare: changed image.c
-Kalle Olavi Niemitalo: changed keyboard.c
+Kalle Olavi Niemitalo: changed xselect.c keyboard.c xfns.c xterm.h
Kanematsu Daiji: changed nnimap.el
Kan-Ru Chen: changed nnir.el ecomplete.el window.el gnus-diary.el
gnus.texi ibuf-ext.el nnmbox.el nroff-mode.el
+Kapuze Martin: changed python.wy
+
Karel Klíč: changed fileio.c files.el configure.ac eval.c ftfont.c lisp.h
src/Makefile.in text.texi tramp.el
@@ -2736,6 +3036,8 @@ Károly Lőrentey: changed xfns.c bindings.el keyboard.c menu-bar.el
x-win.el xdisp.c xt-mouse.el xterm.c xterm.h .gdbinit AT386.el HELLO
README and 101 other files
+Karthik Chikmagalur: changed pcmpl-unix.el
+
Katsuhiro Hermit Endo: changed gnus-group.el gnus-spec.el
Katsumi Yamaoka: wrote canlock.el
@@ -2744,10 +3046,10 @@ and changed gnus-art.el gnus-sum.el message.el mm-decode.el gnus.texi
shr.el rfc2047.el gnus-start.el gnus.el nntp.el gnus-agent.el nnrss.el
mm-uu.el nnmail.el emacs-mime.texi and 161 other files
-Kaushal Modi: changed files.el isearch.el apropos.el calc-yank.el
- custom.texi desktop.el ediff-diff.el eww.el ffap.el maintaining.texi
- printing.el ps-print.el tips.texi variables.texi vc-hooks.el
- vc1-xtra.texi woman.el
+Kaushal Modi: changed dired-aux.el files.el isearch.el apropos.el
+ calc-yank.el custom.texi desktop.el dired.el dired.texi ediff-diff.el
+ eww.el ffap.el maintaining.texi printing.el ps-print.el tips.texi
+ variables.texi vc-hooks.el vc1-xtra.texi woman.el
Kaushik Srenevasan: changed gdb-mi.el
@@ -2755,8 +3057,8 @@ Kaveh R. Ghazi: changed delta88k.h xterm.c
Kayvan Sylvan: changed supercite.el
-Kazuhiro Ito: changed coding.c flow-fill.el font.c keyboard.c
- make-mode.el net/starttls.el xdisp.c
+Kazuhiro Ito: changed coding.c uudecode.el flow-fill.el font.c
+ japan-util.el keyboard.c make-mode.el net/starttls.el xdisp.c
Kazushi Marukawa: changed filelock.c hexl.c profile.c unexalpha.c
@@ -2769,6 +3071,8 @@ Keitaro Miyazaki: changed re-builder.el
Keith Amidon: co-wrote auth-source-pass.el
and changed auth-source-pass-tests.el
+Keith David Bershatsky: changed ns-win.el tex-mode.el
+
Keith Gabryelski: wrote hexl.c hexl.el
Keith Packard: changed font.c
@@ -2777,13 +3081,13 @@ Kelly Dean: changed simple.el help-mode.el desktop.el files.el lisp.el
register.el easy-mmode.el fileio.c help-fns.el help-macro.el help.el
keyboard.c package-x.el rect.el windmove.el winner.el
-Kelvin White: changed erc.el erc-pcomplete.el erc.texi NEWS.24
- erc-backend.el erc-ring.el erc-stamp.el
+Kelvin White: changed erc.el erc-pcomplete.el erc.texi erc-backend.el
+ erc-ring.el erc-stamp.el
Ken Brown: changed configure.ac gmalloc.c sheap.c emacs.c w32fns.c
fileio.c w32term.c unexcw.c conf_post.h cygwin.h filenotify-tests.el
- lisp.h browse-url.el dispextern.h emacs.rc.in fileio-tests.el frame.c
- image.c keyboard.c profiler.c src/Makefile.in and 48 other files
+ src/Makefile.in lisp.h sysdep.c browse-url.el dispextern.h emacs.rc.in
+ fileio-tests.el frame.c image.c keyboard.c and 50 other files
Ken Brush: changed emacsclient.c
@@ -2793,7 +3097,7 @@ and co-wrote ps-def.el ps-mule.el ps-print.el ps-samp.el quail.el
and changed coding.c mule-cmds.el mule.el fontset.c charset.c xdisp.c
font.c fontset.el xterm.c fileio.c mule-conf.el ftfont.c characters.el
fns.c mule-diag.el coding.h charset.h ccl.c xfaces.c editfns.c
- composite.c and 389 other files
+ composite.c and 387 other files
Kenichi Okada: co-wrote sasl-cram.el sasl-digest.el
@@ -2828,7 +3132,7 @@ Kevin Blake: changed font-lock.el ring.el
Kevin Broadey: wrote foldout.el
-Kevin Brubeck Unhammer: changed erc-track.el
+Kevin Brubeck Unhammer: changed erc-join.el erc-track.el erc.el
Kevin Christian: changed gnus-score.el
@@ -2851,7 +3155,9 @@ and changed gnus-agent.el gnus-sum.el gnus-start.el gnus-int.el nntp.el
Kevin Layer: changed mml.el w32proc.c
-Kévin Le Gouguec: changed font-lock.el font-lock-tests.el
+Kévin Le Gouguec: changed font-lock.el gnus-sum.el dired-aux-tests.el
+ dired-aux.el electric-tests.el font-lock-tests.el gnus.el message.texi
+ project.el sh-script.el shr.el
Kevin Rodgers: changed compile.el mailabbrev.el progmodes/compile.el
dired-x.el files.el ange-ftp.el byte-opt.el desktop.el diff-mode.el
@@ -2863,14 +3169,16 @@ Kevin Ryde: wrote info-xref.el
and changed info-look.el info.el checkdoc.el cl.texi compilation.txt
etags.c arc-mode.el ffap.el gnus-art.el gnus-sum.el mule.el os.texi
progmodes/compile.el woman.el browse-url.el copyright.el dig.el
- files.el flyspell.el keyboard.c mailcap.el and 86 other files
+ files.el flyspell.el keyboard.c mailcap.el and 88 other files
+
+Kien Nguyen: changed comp.c
Kim F. Storm: wrote bindat.el cua-base.el cua-gmrk.el cua-rect.el ido.el
keypad.el kmacro.el
and changed xdisp.c dispextern.h process.c simple.el window.c keyboard.c
xterm.c dispnew.c subr.el w32term.c lisp.h fringe.c display.texi
macterm.c alloc.c fns.c xfaces.c keymap.c xfns.c xterm.h .gdbinit
- and 249 other files
+ and 248 other files
Kimit Yada: changed copyright.el
@@ -2884,6 +3192,8 @@ Kirk Kelsey: changed make-mode.el vc-hg.el
Kishore Kumar: changed terminal.el
+Kiso Katsuyuki: changed tab-line.el
+
Klaus Straubinger: changed url-http.el url-history.el pcmpl-rpm.el
url-cookie.el url.el
@@ -2906,16 +3216,18 @@ Koichi Arakawa: changed tramp-sh.el w32proc.c
Konrad Hinsen: wrote ol-eshell.el
and changed ob-python.el
-Konstantin Kharlamov: changed ada-mode.el calc-aent.el calc-ext.el
- calc-lang.el cc-mode.el cperl-mode.el css-mode.el cua-rect.el
- diff-mode.el dnd.el ebnf-abn.el ebnf-dtd.el ebnf-ebx.el
- emacs-module-tests.el epg.el faces.el gnus-art.el gtkutil.c hideif.el
- htmlfontify.el lex.el and 24 other files
+Konstantin Kharlamov: changed smerge-mode.el diff-mode.el files.el
+ autorevert.el calc-aent.el calc-ext.el calc-lang.el cc-mode.el
+ cperl-mode.el css-mode.el cua-rect.el dnd.el ebnf-abn.el ebnf-dtd.el
+ ebnf-ebx.el emacs-module-tests.el epg.el faces.el gnus-art.el gtkutil.c
+ hideif.el and 26 other files
Konstantin Kliakhandler: changed org-agenda.el
Konstantin Novitsky: changed progmodes/python.el
+Kristian Hole: changed sql.el
+
Kristoffer Grönlund: wrote wombat-theme.el
Krzysztof Jurewicz: changed erc.el secrets.el
@@ -2935,11 +3247,12 @@ and changed battery.el ielm.el octave-hlp.el octave-mode.texi term.el
Kurt Swanson: changed gnus-art.el gnus-salt.el gnus-sum.el gnus-ems.el
gnus-group.el gnus-msg.el gnus-score.el gnus-util.el nnmail.el window.c
+Kyle Hubert: changed ediff-util.el
+
Kyle Jones: wrote life.el
and changed saveconf.el buffer.c mail-utils.el sendmail.el
-Kyle Meyer: wrote ob-stan.el
-and changed org-compat.el ox.el
+Kyle Meyer: changed org-compat.el ox.el
Kyotaro Horiguchi: changed coding.c indent.c
@@ -2968,29 +3281,29 @@ and co-wrote dabbrev.el imenu.el
Lars Ljung: changed esh-ext.el isearch.el
Lars Magne Ingebrigtsen: wrote compface.el decompress-tests.el dns.el
- dom.el ecomplete.el eww.el exif.el format-spec.el gnus-agent.el
- gnus-art.el gnus-async.el gnus-bcklg.el gnus-cache.el gnus-cloud.el
- gnus-demon.el gnus-draft.el gnus-dup.el gnus-eform.el gnus-fun.el
- gnus-group.el gnus-html.el gnus-int.el gnus-logic.el gnus-picon.el
- gnus-range.el gnus-salt.el gnus-spec.el gnus-srvr.el gnus-start.el
- gnus-sum.el gnus-undo.el gnus-util.el gnus-uu.el gnus-win.el
- ietf-drums.el image-converter.el mail-parse.el mail-prsvr.el
- mail-source.el message.el messcompat.el mm-archive.el mm-view.el mml.el
- netrc.el network-stream-tests.el network-stream.el nnagent.el nndir.el
- nndraft.el nngateway.el nnmail.el nnoo.el nntp.el nnweb.el nsm.el
- parse-time-tests.el puny.el qp.el rfc2045.el rfc2104-tests.el
- rfc2231.el rtree.el score-mode.el shr-tests.el shr.el spam.el
- text-property-search-tests.el text-property-search.el url-domsuf.el
- url-queue.el
+ dom.el ecomplete.el erc-tests.el eww.el exif.el format-spec.el
+ gnus-agent.el gnus-art.el gnus-async.el gnus-bcklg.el gnus-cache.el
+ gnus-cloud.el gnus-demon.el gnus-draft.el gnus-dup.el gnus-eform.el
+ gnus-fun.el gnus-group.el gnus-html.el gnus-int.el gnus-logic.el
+ gnus-picon.el gnus-range.el gnus-salt.el gnus-spec.el gnus-srvr.el
+ gnus-start.el gnus-sum.el gnus-undo.el gnus-util.el gnus-uu.el
+ gnus-win.el ietf-drums.el image-converter.el mail-parse.el
+ mail-prsvr.el mail-source.el message.el messcompat.el mm-archive.el
+ mm-view.el mml.el netrc.el network-stream-tests.el network-stream.el
+ nnagent.el nndir.el nndraft.el nngateway.el nnmail.el nnoo.el nntp.el
+ nnweb.el nsm.el parse-time-tests.el puny.el qp.el rfc2045.el
+ rfc2104-tests.el rfc2231.el rtree.el score-mode.el shr-tests.el shr.el
+ spam.el text-property-search-tests.el text-property-search.el
+ url-domsuf.el url-queue.el
and co-wrote gnus-kill.el gnus-mh.el gnus-msg.el gnus-score.el
gnus-topic.el gnus.el gssapi.el mailcap.el mm-bodies.el mm-decode.el
mm-encode.el mm-util.el nnbabyl.el nndoc.el nneething.el nnfolder.el
nnheader.el nnimap.el nnmbox.el nnmh.el nnml.el nnspool.el nnvirtual.el
rfc2047.el svg.el time-date.el
-and changed gnus.texi process.c subr.el simple.el files.el gnutls.c
- gnus-ems.el smtpmail.el display.texi url-http.el auth-source.el
- gnus-cite.el pop3.el dired.el edebug.el gnus-xmas.el text.texi image.el
- image.c gnutls.el nnrss.el and 651 other files
+and changed gnus.texi simple.el subr.el files.el process.c text.texi
+ display.texi dired.el gnutls.c gnus-ems.el smtpmail.el help-fns.el
+ auth-source.el url-http.el edebug.el gnus-cite.el image.el pop3.el
+ dired-aux.el fns.c image.c and 860 other files
Lars Rasmusson: changed ebrowse.c
@@ -3016,15 +3329,15 @@ Lee Duhem: changed eval.c
Leigh Stoller: changed emacsclient.c server.el
-Lele Gaifax: changed progmodes/python.el flymake.el python-tests.el
- TUTORIAL.it flymake-proc.el flymake.texi isearch.el
+Lele Gaifax: changed progmodes/python.el TUTORIAL.it flymake.el
+ python-tests.el flymake-proc.el flymake.texi isearch.el
Lennart Borgman: co-wrote ert-x.el
-and changed nxml-mode.el tutorial.el re-builder.el window.el ada-xref.el
- buff-menu.el emacs-lisp/debug.el emacsclient.c filesets.el flymake.el
- help-fns.el isearch.el linum.el lisp-mode.el lisp.el mouse.el
- recentf.el remember.el replace.el ruby-mode.el shell.el
- and 4 other files
+and changed nxml-mode.el tutorial.el re-builder.el window.el buff-menu.el
+ emacs-lisp/debug.el emacsclient.c filesets.el flymake.el help-fns.el
+ isearch.el linum.el lisp-mode.el lisp.el mouse.el progmodes/grep.el
+ recentf.el remember.el replace.el reveal.el ruby-mode.el
+ and 5 other files
Lennart Staflin: changed dired.el diary-ins.el diary-lib.el tq.el xdisp.c
@@ -3042,8 +3355,12 @@ Leonardo Nobrega: changed progmodes/python.el
Leonard Randall: changed org-bibtex.el reftex-parse.el
+Leon Vack: changed erc-services.el
+
Leo P. White: changed eieio-custom.el
+Leo Vivier: changed dired-aux.el
+
Levin Du: changed parse-time.el org-clock.el
Le Wang: changed org-src.el comint.el hilit-chg.el misc.el
@@ -3056,15 +3373,20 @@ Liam Stitt: changed url-file.el url-vars.el
Liang Wang: changed etags.el
+Liāu, Kiong-Gē 廖宮毅: changed comp.c mingw-cfg.site
+
Lixin Chin: changed bibtex.el
Lloyd Zusman: changed mml.el pgg-gpg.el
Lluís Vilanova: changed ede/linux.el
+Logan Perkins: changed keyboard.c
+
Luca Capello: changed mm-encode.el
-Lucas Werkmeister: changed emacs.c emacs.service
+Lucas Werkmeister: changed emacs.c emacs.service nxml-mode.el
+ sgml-mode.el
Lucid, Inc.: changed byte-opt.el byte-run.el bytecode.c bytecomp.el
delsel.el disass.el faces.el font-lock.el mailabbrev.el select.el
@@ -3074,7 +3396,7 @@ Luc Teirlinck: wrote help-at-pt.el
and changed files.el autorevert.el cus-edit.el subr.el simple.el
frames.texi startup.el display.texi files.texi dired.el comint.el
modes.texi custom.texi emacs.texi fns.c frame.el ielm.el minibuf.texi
- variables.texi buffers.texi commands.texi and 211 other files
+ variables.texi buffers.texi commands.texi and 212 other files
Ludovic Courtès: wrote nnregistry.el
and changed configure.ac gnus.texi loadup.el
@@ -3090,9 +3412,9 @@ Lukas Huonker: changed tetris.el
Łukasz Jędrzejewski: changed auth-source-pass-tests.el
auth-source-pass.el
-Łukasz Stelmach: changed erc.el ps-print.el cookie1.el gnus-group.el
- gtkutil.c message.el org-agenda.el org-bbdb.el org.el org.texi
- ox-html.el ox.el simple.el
+Łukasz Stelmach: changed erc.el message.el ps-print.el cookie1.el
+ gnus-group.el gtkutil.c org-agenda.el org-bbdb.el org.el org.texi
+ ox-html.el ox.el shr.el simple.el
Luke Lee: changed hideif.el
@@ -3102,7 +3424,7 @@ Lute Kamstra: changed modes.texi emacs-lisp/debug.el generic-x.el
generic.el font-lock.el simple.el subr.el battery.el debugging.texi
easy-mmode.el elisp.texi emacs-lisp/generic.el hl-line.el info.el
octave.el basic.texi bindings.el calc.el cmdargs.texi diff-mode.el
- doclicense.texi and 290 other files
+ doclicense.texi and 288 other files
Lynn Slater: wrote help-macro.el
@@ -3123,12 +3445,14 @@ Malcolm Purvis: changed spam-stat.el
Manoj Srivastava: wrote manoj-dark-theme.el
-Manuel Giraud: changed ox-html.el ox-publish.el org.texi
+Manuel Giraud: changed ox-html.el ox-publish.el vc.el idlwave.el org.texi
Manuel Gómez: changed speedbar.el
Manuel Serrano: wrote flyspell.el
+Manuel Uberti: changed project.el
+
Marcelo Toledo: changed TUTORIAL.pt_BR TUTORIAL.cn TUTORIAL.cs
TUTORIAL.de TUTORIAL.es TUTORIAL.fr TUTORIAL.it TUTORIAL.ja TUTORIAL.ko
TUTORIAL.pl TUTORIAL.ro TUTORIAL.ru TUTORIAL.sk TUTORIAL.sl TUTORIAL.th
@@ -3144,11 +3468,13 @@ and changed battery.el doc-view.el elisp-mode-tests.el fill.el lisp.el
Marc Lefranc: changed gnus-art.el
+Marco Centurion: changed dired-aux.el files.el files.texi
+
Marco Melgazzi: changed term.el
Marco Wahl: wrote ol-eww.el
-and changed org-agenda.el page-ext.el org.el scroll-lock-tests.el
- scroll-lock.el
+and changed org-agenda.el page-ext.el ffap.el kmacro.el kmacro.texi
+ org.el scroll-lock-tests.el scroll-lock.el
Marco Walther: changed mips-siemens.h unexelfsni.c unexsni.c
@@ -3178,10 +3504,11 @@ and changed erc.el erc-dcc.el erc-speak.el Makefile erc-bbdb.el
and 48 other files
Mark A. Hershberger: changed xml.el nnrss.el mm-url.el cperl-mode.el
- isearch.el vc-bzr.el NXML-NEWS cc-mode.texi compilation.txt ede.texi
+ isearch.el vc-bzr.el OpenDocument-schema-v1.3+libreoffice.rnc
+ OpenDocument-schema-v1.3.rnc cc-mode.texi compilation.txt ede.texi
eieio.texi esh-mode.el flymake.el gnus-group.el menu-bar.el
misc/Makefile.in nxml-mode.texi progmodes/compile.el
- progmodes/python.el programs.texi and 8 other files
+ progmodes/python.el and 10 other files
Mark Davies: changed amdx86-64.h configure configure.ac hp800.h
lib-src/Makefile.in netbsd.h ralloc.c sh3el.h sort.el
@@ -3217,9 +3544,9 @@ Mark Osbourne: changed hexl-mode.el
Mark Oteiza: wrote mailcap-tests.el md4-tests.el xdg-tests.el xdg.el
and changed image-dired.el dunnet.el mpc.el eww.el json.el calc-units.el
- subr-x.el subr.el lcms.c message.el tex-mode.el cl-macs.el cl.texi
- ibuffer.el lcms-tests.el mailcap.el cl-print.el emacs-lisp/chart.el
- files.el htmlfontify.el pcase.el and 178 other files
+ lcms.c subr-x.el subr.el message.el tex-mode.el cl-macs.el cl.texi
+ ibuffer.el lcms-tests.el mailcap.el progmodes/python.el cl-print.el
+ eldoc.el emacs-lisp/chart.el files.el and 173 other files
Mark Plaksin: changed nnrss.el term.el
@@ -3242,7 +3569,7 @@ and changed cus-edit.el files.el progmodes/compile.el rmail.el
tex-mode.el find-func.el rmailsum.el simple.el cus-dep.el dired.el
mule-cmds.el rmailout.el checkdoc.el configure.ac custom.el emacsbug.el
gnus.el help-fns.el ls-lisp.el mwheel.el sendmail.el
- and 126 other files
+ and 125 other files
Markus Sauermann: changed lisp-mode.el
@@ -3267,6 +3594,8 @@ Martin Buchholz: changed etags.c
Martin Jesper Low Madsen: changed auth-source.el
+Martin Joerg: changed tramp-sh.el
+
Martin J. Reed: changed ldap.el
Martin Kletzander: changed erc-join.el
@@ -3283,9 +3612,9 @@ Martin Neitzel: changed supercite.el
Martin Pohlack: changed iimage.el pc-select.el
Martin Rudalics: changed window.el window.c windows.texi frame.c xdisp.c
- w32fns.c xterm.c frames.texi w32term.c xfns.c frame.el display.texi
- help.el buffer.c window.h cus-start.el frame.h dispnew.c mouse.el
- nsfns.m gtkutil.c and 209 other files
+ xterm.c w32fns.c frames.texi w32term.c xfns.c frame.el display.texi
+ frame.h cus-start.el help.el buffer.c window.h mouse.el dispnew.c
+ nsfns.m gtkutil.c and 211 other files
Martin Stjernholm: wrote cc-bytecomp.el
and co-wrote cc-align.el cc-cmds.el cc-compat.el cc-defs.el cc-engine.el
@@ -3304,7 +3633,9 @@ and changed ob-emacs-lisp.el
Masahiko Sato: wrote vip.el
-Masahiro Nakamura: changed ns-win.el nsterm.m
+Masahiro Nakamura: changed mpc.el tramp.texi nsterm.m w32fns.c keyboard.c
+ ns-win.el nsmenu.m nsterm.h package.el refcard.tex shortdoc.el
+ strokes.el
Masanobu Umeda: wrote metamail.el rmailsort.el timezone.el
and co-wrote gnus-kill.el gnus-mh.el gnus-msg.el gnus.el nnbabyl.el
@@ -3328,7 +3659,7 @@ Masayuki Ataka: changed texinfmt.el texinfo.el characters.el cmuscheme.el
Masayuki Fujii: changed dnd.el w32-win.el
Mathias Dahl: wrote image-dired.el
-and changed tumme.el dired.el dired.texi
+and changed tumme.el dired.el dired.texi abbrev.el abbrevs.texi
Mathias Megyei: changed lisp/Makefile.in
@@ -3336,7 +3667,12 @@ Mathieu Othacehe: changed tramp-adb.el
Mats Lidell: changed TUTORIAL.sv european.el gnus-art.el org-element.el
-Matt Armstrong: changed gnus-topic.el gnus.el imap.el message.el shell.el
+Matt Armstrong: changed display.texi filelock-tests.el buffer.c
+ commands.texi filelock.c files.el gnus-topic.el gnus.el imap.el
+ lisp-mnt.el map-tests.el marker.c message.el shell.el simple.el
+ userlock.el
+
+Matt Beshara: changed js.el nsfns.m
Matt Bisson: changed xterm.c
@@ -3344,7 +3680,7 @@ Matt Curtis: changed pulse.el
Matt Fidler: changed package.el
-Matthew Bauer: changed comint.el startup.el
+Matthew Bauer: changed comint.el shell.el startup.el
Matthew Carter: changed sql.el
@@ -3364,12 +3700,16 @@ Matthew Mundell: changed calendar.texi diary-lib.el files.texi
Matthew Newton: changed imenu.el
+Matthew White: changed buffer.c bookmark-tests.el bookmark.el
+ test-list.bmk
+
Matthias Dahl: changed faces.el process.c process.h
Matthias Förste: changed files.el
-Matthias Meulien: changed bookmark.el progmodes/python.el buff-menu.el
- prog-mode.el simple.el tabify.el vc-dir.el vc-git.el
+Matthias Meulien: changed bookmark.el progmodes/python.el vc-dir.el
+ buff-menu.el prog-mode.el simple.el tab-bar.el tabify.el vc-git.el
+ vc-tests.el
Matthias Wiehl: changed gnus.el
@@ -3384,11 +3724,13 @@ Matt Hodges: changed textmodes/table.el faces.el iswitchb.el simple.el
edebug.texi eldoc.el em-hist.el em-pred.el fixit.texi icon.el ido.el
locate.el paragraphs.el pcomplete.el repeat.el and 3 other files
-Mattias Engdegård: changed rx.el searching.texi rx-tests.el autorevert.el
- calc-tests.el regexp-opt.el filenotify.el subr.el files.el
- progmodes/compile.el mouse.el bytecomp.el compile-tests.el
- autorevert-tests.el byte-opt.el bytecomp-tests.el calc-alg.el
- compilation.txt dired.el font.c regex-emacs.c and 161 other files
+Mattias Engdegård: changed byte-opt.el rx.el rx-tests.el searching.texi
+ bytecomp-tests.el bytecomp.el calc-tests.el progmodes/compile.el
+ subr.el autorevert.el gdb-mi.el files.el regex-emacs-tests.el mouse.el
+ regexp-opt.el replace.el calc.el coding.c filenotify.el regex-emacs.c
+ calc-ext.el and 537 other files
+
+Mattias M: changed asm-mode-tests.el asm-mode.el
Matt Lundin: changed org-agenda.el org.el org-bibtex.el org-footnote.el
ox-publish.el org-bbdb.el org-datetree.el org-gnus.el
@@ -3402,15 +3744,17 @@ Matt Simmons: changed message.el
Matt Swift: changed dired.el editfns.c lisp-mode.el mm-decode.el
outline.el progmodes/compile.el rx.el simple.el startup.el
-Mauro Aranda: changed wid-edit.el cus-edit.el gnus.texi octave.el pong.el
- autorevert.el cc-mode.texi control.texi custom-tests.el custom.el
- dbus.texi dired-x.texi elisp-mode.el epa.el esh-mode.el
- eshell/eshell.el eudc.texi files.texi functions.texi gnus-faq.texi
- info.el and 14 other files
+Mauro Aranda: changed wid-edit.el cus-edit.el custom.el wid-edit-tests.el
+ widget.texi custom-tests.el checkdoc-tests.el checkdoc.el
+ cus-edit-tests.el cus-theme.el customize.texi files.texi gnus.texi
+ octave.el pong.el autorevert.el button.el cc-mode.texi control.texi
+ custom--test-theme.el dbus.texi and 35 other files
Maxime Edouard Robert Froumentin: changed gnus-art.el mml.el
-Max Mikhanosha: changed org-agenda.el org-habit.el org.el
+Maxim Nikulin: changed mailcap.el
+
+Max Mikhanosha: changed org-agenda.el org-habit.el keyboard.c org.el
Memnon Anon: changed org.texi
@@ -3419,14 +3763,15 @@ Micah Anderson: changed spook.lines
Michael Albinus: wrote autorevert-tests.el dbus-tests.el dbus.el
filenotify-tests.el filenotify.el files-x-tests.el secrets-tests.el
secrets.el shadowfile-tests.el tramp-archive-tests.el tramp-archive.el
- tramp-cmds.el tramp-compat.el tramp-crypt.el tramp-ftp.el tramp-gvfs.el
- tramp-integration.el tramp-rclone.el tramp-smb.el tramp-sudoedit.el
- tramp-tests.el url-tramp-tests.el url-tramp.el vc-tests.el zeroconf.el
+ tramp-cmds.el tramp-compat.el tramp-crypt.el tramp-ftp.el tramp-fuse.el
+ tramp-gvfs.el tramp-integration.el tramp-rclone.el tramp-smb.el
+ tramp-sshfs.el tramp-sudoedit.el tramp-tests.el url-tramp-tests.el
+ url-tramp.el vc-tests.el zeroconf.el
and co-wrote tramp-cache.el tramp-sh.el tramp.el
and changed tramp.texi tramp-adb.el trampver.el trampver.texi dbusbind.c
- file-notify-tests.el files.el ange-ftp.el files.texi dbus.texi
- autorevert.el tramp-fish.el kqueue.c tramp-gw.el tramp-imap.el os.texi
- xesam.el configure.ac lisp.h shell.el gfilenotify.c and 253 other files
+ files.el ange-ftp.el file-notify-tests.el files.texi dbus.texi
+ autorevert.el tramp-fish.el kqueue.c tramp-gw.el os.texi shell.el
+ tramp-imap.el gitlab-ci.yml lisp.h README xesam.el and 280 other files
Michael Ben-Gershon: changed acorn.h configure.ac riscix1-1.h riscix1-2.h
unexec.c
@@ -3453,19 +3798,18 @@ Michael Downes: changed gnus-sum.el
Michael D. Prange: wrote fortran.el
and changed tex-mode.el
-Michael Gauland: wrote ob-ebnf.el
-and co-wrote ob-scheme.el
+Michael Gauland: co-wrote ob-scheme.el
and changed ebnf2ps.el org-src.el
Michael Gschwind: wrote iso-cvt.el
Michael Harnois: changed nnimap.el
-Michael Heerdegen: changed cl-macs.el subr.el control.texi copyright.el
- css-mode.el dired.el easy-mmode.el filesets.el hi-lock.el macroexp.el
- modula2.el ob-C.el ob-core.el ob-exp.el ob-groovy.el ob-haskell.el
- ob-io.el ob-lisp.el ob-lob.el ob-lua.el ob-octave.el
- and 227 other files
+Michael Heerdegen: changed bytecomp.el cl-macs.el subr.el control.texi
+ copyright.el css-mode.el dired.el easy-mmode.el eieio-core.el
+ filesets.el hi-lock.el macroexp.el modula2.el ob-C.el ob-core.el
+ ob-exp.el ob-groovy.el ob-haskell.el ob-lisp.el ob-lob.el ob-lua.el
+ and 229 other files
Michael Hendricks: changed help.el
@@ -3497,9 +3841,9 @@ Michael McNamara: co-wrote verilog-mode.el
Michael Olson: changed erc.el erc-backend.el Makefile erc-track.el
erc-log.el erc-stamp.el erc-autoaway.el erc-dcc.el erc-goodies.el
- erc-list.el erc-compat.el erc-identd.el erc.texi ERC-NEWS erc-bbdb.el
+ erc-list.el erc-compat.el erc-identd.el erc.texi erc-bbdb.el
erc-match.el erc-notify.el erc-ibuffer.el erc-services.el remember.el
- erc-button.el and 54 other files
+ erc-button.el erc-nicklist.el and 54 other files
Michael Orlitzky: changed tex-mode.el
@@ -3538,6 +3882,8 @@ Michael Weylandt: changed ox-latex.el
Michael Witten: changed TUTORIAL fixit.texi intro.texi
+Michalis V: changed dired-aux.el em-cmpl.el help-mode.el tcl.el
+
Michal Jankowski: changed insdel.c keyboard.c
Michał Kondraciuk: changed cus-edit.el
@@ -3547,11 +3893,11 @@ Michał Krzywkowski: changed elide-head.el
Michal Nazarewicz: wrote cc-mode-tests.el descr-text-tests.el
tildify-tests.el
and co-wrote tildify.el
-and changed regex.c casefiddle.c simple.el test/src/regex-emacs-tests.el
- casefiddle-tests.el message.el regex.h search.c buffer.h ert-x.el
- files.el frame.c remember.el sgml-mode.el unidata-gen.el README
- SpecialCasing.txt bindings.el buffer.c cc-mode.el cfengine.el
- and 37 other files
+and changed emacs-regex.c casefiddle.c simple.el
+ test/src/regex-emacs-tests.el casefiddle-tests.el emacs-regex.h
+ message.el search.c buffer.h cc-mode.el cc-mode.texi ert-x.el files.el
+ frame.c remember.el sgml-mode.el unidata-gen.el README
+ SpecialCasing.txt bindings.el buffer.c and 41 other files
Michal Nowak: changed gnutls.el
@@ -3573,6 +3919,10 @@ Miguel Ruiz: changed ob-gnuplot.el
Mihai Olteanu: changed hexl.el
+Miha Rihtaršič: changed keyboard.c commands.texi minibuf.c minibuffer.el
+ simple.el comint.el data.c delsel.el errors.texi esh-mode.el eval.c
+ ibuffer.el macros.c process.c sh-script.el
+
Mihir Rege: changed js.el
Mikael Djurfeldt: changed xdisp.c
@@ -3585,11 +3935,13 @@ Mike Gulick: changed gdb-mi.el
Mike Haertel: changed 7300.h
+Mike Hamrick: changed dispextern.h term.c termchar.h xfaces.c
+
Mike Kazantsev: changed erc-dcc.el
Mike Kupfer: changed mh-comp.el mh-e.el ftcrfont.c mh-utils.el
- emacs-mime.texi ftxfont.c gnus-mh.el gnus.texi mh-acros.el mh-compat.el
- mh-e.texi mh-identity.el mh-mime.el xftfont.c
+ emacs-mime.texi gnus-mh.el gnus.texi mh-acros.el mh-compat.el mh-e.texi
+ mh-identity.el mh-mime.el xftfont.c
Mike Lamb: changed em-unix.el esh-util.el pcmpl-unix.el
@@ -3621,10 +3973,12 @@ Miles Bader: wrote button.el face-remap.el image-file.el macroexp.el
and changed comint.el faces.el simple.el editfns.c xfaces.c xdisp.c
info.el minibuf.c display.texi quick-install-emacs wid-edit.el xterm.c
dispextern.h subr.el window.el cus-edit.el diff-mode.el xfns.c
- bytecomp.el help.el lisp.h and 272 other files
+ bytecomp.el help.el lisp.h and 271 other files
Milton Wulei: changed gdb-ui.el
+Mingde Matthew Zeng: changed erc-join.el erc.el
+
Mirek Kaim: changed configure.ac
Mirko Vukovic: changed emacs.texi maintaining.texi
@@ -3673,14 +4027,22 @@ Nakamura Toshikazu: changed w32fns.c
Nali Toja: changed configure.ac
+Naofumi Yasufuku: changed tramp-sh.el
+
Naohiro Aota: changed fontset.c ftfont.c gnus-art.el mm-view.el tls.el
xftfont.c
+Naoya Yamashita: changed gv-tests.el gv.el
+
+Narendra Joshi: changed repeat.el
+
Nathaniel Flath: changed cc-menus.el cc-engine.el cc-fonts.el cc-langs.el
cc-mode.el cc-vars.el
Nathan J. Williams: changed imap.el
+Nathan Moreau: changed vc.el
+
Nathan Trapuzzano: changed cconv.el cl-macs.el cperl-mode.el gnus.texi
linum.el progmodes/python.el python-tests.el
@@ -3690,7 +4052,7 @@ Neal Ziring: co-wrote vi.el (public domain)
Neil Mager: wrote appt.el
-Neil Roberts: changed custom.texi files.el
+Neil Roberts: changed custom.texi display.texi files.el xdisp.c
Neil W. Van Dyke: wrote webjump.el
@@ -3709,10 +4071,12 @@ Niall Mansfield: changed etags.c
Nic Ferrier: changed ert.el tramp.el
-Nicholas Drozd: changed calc.texi editfns.c ol.html ol.txt shr.el
+Nicholas Drozd: changed calc.texi editfns.c shr.el
Nicholas Maniscalco: changed term.el
+Nicholas Strauss: changed lunar.el
+
Nick Alcock: changed control.texi customize.texi display.texi files.el
frames.texi gnus.el keymaps.texi modes.texi nonascii.texi syntax.texi
text.texi windows.texi
@@ -3721,9 +4085,11 @@ Nick Dokos: changed org-table.el ox.el icalendar.el mh-search.el
org-mobile.el org.el ox-ascii.el url-cache.el
Nick Drozd: changed quail/georgian.el eww.el eww.texi shr.el HELLO
- cc-mode-tests.el ido.texi
+ cc-mode-tests.el ido.texi replace-tests.el
-Nick Helm: changed eldoc.el help.el help.texi nsterm.m
+Nick Gasson: changed comint-tests.el comint.el rmailsum.el
+
+Nick Helm: changed dired-aux.el eldoc.el help.el help.texi nsterm.m
whitespace-tests.el whitespace.el
Nick Roberts: wrote gdb-mi.el t-mouse.el
@@ -3732,31 +4098,38 @@ and changed gdb-ui.el gud.el building.texi tooltip.el speedbar.el
keyboard.c subr.el frames.texi help-mode.el progmodes/compile.el
xdisp.c display.texi term.c vc-svn.el and 145 other files
+Nick Savage: changed help-mode.el
+
Nick Terrell: changed jka-cmpr-hook.el
Nico Francois: changed w32fns.c w32inevt.c w32menu.c
Nicolas Avrutin: changed url-http.el
+Nicolás Bértolo: changed comp.c comp.el emacs.c lread.c comp.h lisp.h
+ package.el alloc.c configure.ac eval.c pdumper.c src/Makefile.in
+ w32-win.el w32.c w32common.h w32fns.c
+
Nicolas Calderon Asselin: changed org-clock.el
-Nicolas Goaziou: wrote org-duration.el org-element.el org-keys.el
- org-lint.el org-macro.el org-num.el ox-ascii.el ox-latex.el ox-md.el
- ox-org.el ox.el
-and co-wrote ox-beamer.el ox-icalendar.el ox-man.el
+Nicolas Goaziou: wrote oc-basic.el oc-biblatex.el oc-csl.el oc-natbib.el
+ oc.el ol-doi.el org-duration.el org-element.el org-keys.el org-lint.el
+ org-macro.el org-num.el ox-ascii.el ox-latex.el ox-md.el ox-org.el
+ ox.el
+and co-wrote ox-beamer.el ox-icalendar.el ox-koma-letter.el ox-man.el
and changed org-list.el org.el ox-html.el org-footnote.el ox-texinfo.el
org.texi ox-publish.el ox-odt.el org-inlinetask.el org-indent.el
org-docbook.el ob-exp.el org-agenda.el org-timer.el ob.el
- org-capture.el ob-asymptote.el org-clock.el org-macs.el
- org-pcomplete.el org-table.el and 22 other files
+ org-capture.el org-clock.el org-macs.el org-pcomplete.el org-table.el
+ org-archive.el and 21 other files
-Nicolas Graner: changed message.el
+Nicolas Graner: changed eww.el message.el
Nicolas Petton: wrote map-tests.el map.el seq-tests.el seq.el
- thunk-tests.el thunk.el url-handlers-test.el
+ thunk-tests.el thunk.el url-handlers-tests.el
and co-wrote auth-source-pass.el auth-source-tests.el subr-tests.el
-and changed README configure.ac sed2v2.inp authors.el sequences.texi
- README.W32 emacs.png emacs23.png HISTORY arc-mode.el cl-extra.el
+and changed README authors.el configure.ac sed2v2.inp sequences.texi
+ README.W32 emacs.png HISTORY emacs23.png arc-mode.el cl-extra.el
emacs.svg manoj-dark-theme.el Emacs.icns Makefile.in auth-source.el
emacs.ico fns.c make-tarball.txt obarray-tests.el obarray.el
and 37 other files
@@ -3783,7 +4156,7 @@ Nikolaj Schumacher: changed flymake.el progmodes/compile.el eldoc.el
Nikolaus Rath: changed nnimap.el gnus-sum.el gnus.texi
-Nikolay Kudryavtsev: changed sql.el vc-git.el
+Nikolay Kudryavtsev: changed bytecomp.el checkdoc.el sql.el vc-git.el
Nil Geisweiller: changed flymake.el
@@ -3791,24 +4164,26 @@ Nils Ackermann: changed message.el nnmh.el reftex-vars.el
Nitish Chinta: changed progmodes/python.el sendmail.el simple.el
-N. Jackson: changed emacs.texi forms.texi
+N. Jackson: changed emacs.texi forms.texi os.texi
+
+Noah Evans: changed follow.el
Noah Friedman: wrote eldoc.el rlogin.el type-break.el
and co-wrote erc-dcc.el
and changed rsz-mini.el emacs-buffer.gdb comint.el files.el Makefile
- mailabbrev.el sendmail.el subr.el timer.el xfns.c yow.el apropos.el
- battery.el bytecomp.el calc.el coding.c complete.el config.in
- configure.ac copyright.h fns.c and 22 other files
+ mailabbrev.el sendmail.el shell.el src/sysdep.c subr.el timer.el xfns.c
+ yow.el apropos.el battery.el bytecomp.el calc.el coding.c complete.el
+ config.in configure.ac and 24 other files
Noah Lavine: changed tramp.el
-Noah Swainland: changed calc.el
+Noah Swainland: changed calc.el goto-addr.el misc.texi
Noam Postavsky: changed progmodes/python.el lisp-mode.el bytecomp.el
- lisp-mode-tests.el term.el xdisp.c eval.c cl-macs.el data.c
- emacs-lisp/debug.el simple.el help-fns.el modes.texi subr.el
- elisp-mode.el ert.el isearch.el processes.texi cl-print.el diff-mode.el
- ffap.el and 359 other files
+ lisp-mode-tests.el term.el xdisp.c cl-macs.el eval.c simple.el data.c
+ emacs-lisp/debug.el modes.texi help-fns.el subr.el elisp-mode.el ert.el
+ isearch.el processes.texi search.c cl-print.el diff-mode.el
+ and 363 other files
Nobuyoshi Nakada: co-wrote ruby-mode.el
and changed ruby-mode-tests.el
@@ -3851,12 +4226,11 @@ Oleg Pykhalov: changed gnus-sum.el
Oleg S. Tihonov: changed cyrillic.el ispell.el language/cyrillic.el
map-ynp.el subr.el
-Oleh Krehel: wrote ob-J.el
-and co-wrote subr-tests.el
+Oleh Krehel: co-wrote subr-tests.el
and changed dired-aux.el outline.el checkdoc.el files.el subr.el buffer.c
check-declare.el alloc.c appt.el buffer.h calc.el category.c
- cl-indent.el custom.el derived.el dired-x.el dired.el dired.texi
- display.texi easy-mmode.el ffap.el and 14 other files
+ cl-indent.el cus-edit.el custom.el derived.el dired-x.el dired.el
+ dired.texi display.texi easy-mmode.el and 15 other files
Oleksandr Gavenko: changed generic-x.el progmodes/grep.el
@@ -3872,6 +4246,9 @@ and changed gamegrid.el gnus-cite.el nonascii.texi rx.el startup.el
Oliver Seidel: wrote otodo-mode.el
and co-wrote todo-mode.el
+Olivier Certner: changed erc-track.el erc-ibuffer.el erc-services.el
+ erc-stamp.el
+
Olivier Laurens: changed forms.el
Olivier Lecarme: changed make-mode.el ange-ftp.el apropos.el bibtex.el
@@ -3882,6 +4259,8 @@ Olli Savia: changed etags.c syssignal.h
Olof Ohlsson Sax: changed vc-svn.el
+Omar Polo: changed configure.ac emacsclient.c sysdep.c vc.el
+
Orivej Desh: changed tramp-sh.el
Osamu Yamane: changed smtpmail.el
@@ -3898,6 +4277,11 @@ and changed ph.el
Øyvind Stegard: changed gnus-msg.el
+Pablo Barbáchano: wrote ansi-color-tests.el
+and changed ansi-color.el
+
+Pankaj Jangid: changed gnus-sum.el gnus.texi semantic.texi frame.c
+
Pascal Dupuis: changed octave.el
Pascal Rigaux: changed image.c rfc2231.el
@@ -3915,10 +4299,10 @@ and changed imenu.el make-mode.el
Paul Eggert: wrote rcs2log
and co-wrote cal-dst.el
-and changed lisp.h configure.ac alloc.c process.c fileio.c editfns.c
- xdisp.c sysdep.c image.c keyboard.c data.c emacs.c fns.c lread.c
- xterm.c eval.c callproc.c Makefile.in frame.c buffer.c gnulib-comp.m4
- and 1813 other files
+and changed lisp.h configure.ac alloc.c fileio.c process.c editfns.c
+ sysdep.c xdisp.c fns.c image.c keyboard.c emacs.c data.c lread.c
+ xterm.c eval.c gnulib-comp.m4 callproc.c Makefile.in frame.c buffer.c
+ and 1851 other files
Paul Fisher: changed fns.c
@@ -3930,10 +4314,10 @@ Paul Jarc: wrote nnmaildir.el (public domain) nnnil.el (public domain)
and changed message.el gnus-util.el gnus-int.el gnus.el gnus-agent.el
gnus-start.el gnus-sum.el nnmail.el
-Paul Pogonyshev: changed subr.el byte-opt.el eval.c progmodes/python.el
- which-func.el align.el bytecode.c bytecomp.el cc-langs.el cl-macs.el
- configure.ac dabbrev.el display.texi eldoc.el elisp-mode.el
- emacs-lisp/debug.el ert.el ert.texi etags.el fns-tests.el fns.c
+Paul Pogonyshev: changed subr.el byte-opt.el bytecomp.el
+ emacs-lisp/debug.el eval.c progmodes/python.el which-func.el align.el
+ bytecode.c cc-langs.el cl-macs.el configure.ac dabbrev.el display.texi
+ eldoc.el elisp-mode.el ert.el ert.texi etags.el fns-tests.el fns.c
and 20 other files
Paul Rankin: changed outline.el
@@ -3944,7 +4328,7 @@ Paul Reilly: changed dgux.h lwlib-Xm.c lwlib.c xlwmenu.c configure.ac
lwlib/Makefile.in mail/rmailmm.el rmailedit.el rmailkwd.el
and 10 other files
-Paul Rivier: changed ada-mode.el mixal-mode.el reftex-vars.el reftex.el
+Paul Rivier: changed mixal-mode.el reftex-vars.el reftex.el
Paul Rubin: changed config.h sun2.h texinfmt.el window.c
@@ -3958,20 +4342,24 @@ Paul Stodghill: changed gnus-agent.el gnus-util.el
Paul Van Der Walt: changed message.el
+Paul W. Rankin: changed bookmark.el font-lock.el nsterm.m outline.el
+
Pavel Janík: co-wrote eudc-bob.el eudc-export.el eudc-hotlist.el
eudc-vars.el eudc.el eudcb-bbdb.el eudcb-ldap.el eudcb-ph.el
and changed keyboard.c xterm.c COPYING xdisp.c process.c emacs.c lisp.h
menu-bar.el ldap.el make-dist xfns.c buffer.c coding.c eval.c fileio.c
flyspell.el fns.c indent.c Makefile.in callint.c cus-start.el
- and 702 other files
+ and 699 other files
Pavel Kobiakov: wrote flymake-proc.el flymake.el
and changed flymake.texi
Peder O. Klingenberg: wrote dns-mode-tests.el
and changed dns-mode.el icalendar.el mm-decode.el calc-comb.el calc.texi
- dunnet.el emacsbug.el emacsclient.c eww.el gnus.texi misc.texi
- url-http.el url-queue.el url-util.el url-vars.el url.texi
+ dunnet.el emacsbug.el emacsclient.c eww.el gnus.texi misc.texi snake.el
+ subr.el url-http.el url-queue.el url-util.el url-vars.el url.texi
+
+Pedro Andres Aranda Gutierrez: changed cus-face.el xfaces.c
P. E. Jareth Hein: changed gnus-util.el
@@ -4000,8 +4388,8 @@ Perry E. Metzger: changed xdisp.c bindings.el buffer.c display.texi
Per Starbäck: changed ispell.el characters.el dired.el gnus-start.el BUGS
apropos.el bibtex.el bytecomp.el charset.h coding.c doctor.el emacs.c
- european.el iso-transl.el pcmpl-gnu.el replace.el startup.el
- trouble.texi vc.el xdisp.c
+ european.el iso-transl.el pcmpl-gnu.el progmodes/python.el replace.el
+ startup.el trouble.texi vc.el xdisp.c
Pete Beardmore: changed semantic/complete.el idle.el
@@ -4017,7 +4405,7 @@ Peter Doornbosch: changed vc-svn.el
Peter Dyballa: changed calendar.el
-Peter Feigl: changed scheme.el HELLO
+Peter Feigl: changed scheme.el HELLO tabulated-list.el
Peter Heslin: changed flyspell.el outline.el
@@ -4031,12 +4419,14 @@ Peter Kleiweg: wrote ps-mode.el
Peter Liljenberg: wrote elint.el
-Peter Münster: changed gnus-delay.el gnus-demon.el gnus-group.el
- gnus-start.el gnus.texi org-agenda.el org.el
+Peter Münster: changed image-dired.el gnus-delay.el gnus-demon.el
+ gnus-group.el gnus-start.el gnus.texi org-agenda.el org.el
Peter O'Gorman: changed configure.ac frame.h hpux10-20.h termhooks.h
-Peter Oliver: changed perl-mode.el server.el vc-sccs.el
+Peter Oliver: changed emacsclient.desktop emacsclient-mail.desktop
+ Makefile.in emacs-mail.desktop server.el configure.ac emacs.desktop
+ emacs.metainfo.xml misc.texi perl-mode.el ruby-mode-tests.el vc-sccs.el
Peter Povinec: changed term.el
@@ -4075,15 +4465,24 @@ Petri Kaurinkoski: changed configure.ac iris4d.h irix6-0.h irix6-5.h
Petr Salinger: changed configure.ac gnu-kfreebsd.h
+Petteri Hintsanen: changed sequences.texi Makefile.in emacs/Makefile.in
+ lispintro/Makefile.in lispref/Makefile.in misc/Makefile.in
+
Phil Hagelberg: wrote ert-x-tests.el
and changed package.el pcmpl-unix.el subr.el
+Philip Brown: changed comp.el
+
Philip Hudson: changed em-hist.el
Philip Jackson: wrote find-cmd.el ol-irc.el
and changed org-irc.el
-Philip K: changed ispell.el
+Philip Kaludercic: wrote epa-ks.el
+and changed rcirc.el rcirc.texi project.el gravatar.el outline.el
+ message.el windmove.el css-mode.el epa.texi erc.el fns-tests.el fns.c
+ ispell.el message.texi nnmaildir.el progmodes/python.el recentf.el
+ replace.el sgml-mode.el skeleton.el subr.el timeclock.el
Philippe Schnoebelen: wrote gomoku.el mpuz.el
and changed cl-extra.el
@@ -4096,35 +4495,40 @@ Philippe Waroquiers: changed etags.el term.c
Philipp Haselwarter: changed gnus-agent.el gnus-sum.el gnus-sync.el
gnus.texi newcomment.el
+Philipp Klaus Krause: changed emacs.c movemail.c
+
Philipp Rumpf: changed electric.el
Philipp Stephani: wrote callint-tests.el checkdoc-tests.el
cl-preloaded-tests.el ediff-diff-tests.el eval-tests.el ido-tests.el
lread-tests.el mouse-tests.el startup-tests.el xt-mouse-tests.el
-and changed emacs-module.c emacs-module-tests.el json.c json-tests.el
- eval.c mod-test.c lisp.h lread.c nsterm.m configure.ac bytecomp.el
- internals.texi gtkutil.c emacs-module.h.in files.el alloc.c
- electric-tests.el electric.el test/Makefile.in editfns.c emacs.c
- and 127 other files
-
-Phillip Lord: wrote ps-print-tests.el
-and changed build-zips.sh lisp/Makefile.in undo.c build-dep-zips.py
- simple.el test/Makefile.in Makefile Makefile.in emacs.nsi keyboard.c
- viper-cmd.el README-windows-binaries README.W32 elisp-mode-tests.el
- ldefs-clean.el loadup.el README-scripts autoload.el
+and changed emacs-module.c emacs-module-tests.el configure.ac json.c
+ eval.c process.c json-tests.el process-tests.el internals.texi alloc.c
+ emacs-module.h.in emacs.c lread.c nsterm.m lisp.h bytecomp.el pdumper.c
+ callproc.c seccomp-filter.c gtkutil.c files.el and 179 other files
+
+Phillip Lord: wrote ps-print-tests.el w32-feature.el
+and changed build-zips.sh build-dep-zips.py lisp/Makefile.in undo.c
+ simple.el test/Makefile.in README-scripts README-windows-binaries
+ emacs.nsi Makefile Makefile.in keyboard.c viper-cmd.el README.W32
+ elisp-mode-tests.el ldefs-clean.el loadup.el autoload.el
automated/Makefile.in cmds.c dired.el and 171 other files
Phil Sainty: wrote autoload-longlines-mode-tests.el
autoload-major-mode-tests.el autoload-minor-mode-tests.el
so-long-tests-helpers.el so-long-tests.el so-long.el spelling-tests.el
-and changed diff.el goto-addr.el term.el cl-macs.el comint.el derived.el
+and changed comint.el term.el diff.el goto-addr.el cl-macs.el derived.el
easy-mmode.el emacs.texi files.texi lisp.el misc.texi package.el
progmodes/grep.el simple.el subword.el trouble.texi
Phil Sung: changed wdired.el dired.texi follow.el progmodes/python.el
+Pierre-Antoine Rouby: changed etags.1 etags.c maintaining.texi
+
Pierre Lorenzon: changed eieio-custom.el pconf.el
+Pierre Neidhardt: changed shell.el
+
Pierre Poissinger: changed charset.c
Pierre Téchoueyres: changed browse-url.el eieio-test-persist.el epg.el
@@ -4138,7 +4542,8 @@ Pieter Praet: changed org-crypt.el
Pieter Schoenmakers: changed TUTORIAL.nl
-Pieter Van Oostrum: changed package.el shell-tests.el shell.el
+Pieter Van Oostrum: changed package.el package-tests.el package.texi
+ shell-tests.el shell.el
Piet van Oostrum: changed data.c fileio.c flyspell.el smtpmail.el
@@ -4148,10 +4553,13 @@ Piotr Trojanek: changed gnutls.c process.c
Piotr Zieliński: wrote org-mouse.el
-Pip Cet: changed fns.c display.texi xdisp.c xterm.c dispextern.h frame.el
- gtkutil.c image.c json-tests.el json.c mail-utils.el nsterm.m simple.el
- subr.el text.texi textprop.c timer-list.el tty-colors-tests.el
- tty-colors.el url-http.el xfaces.c xterm.h
+Pip Cet: wrote image-circular-tests.el
+and changed xdisp.c comp.c fns.c pdumper.c alloc.c byte-opt.el
+ display.texi ftcrfont.c image.c xterm.c bytecomp-tests.el bytecomp.el
+ ccl-tests.el ccl.c ccl.el cmds.c comint.el comp-test-funcs.el
+ comp-tests.el comp.el composite.c and 28 other files
+
+Po Lu: changed xdisp.c browse-url.el cc-compat.el nsfns.m nsterm.m
Pontus Michael: changed simple.el
@@ -4159,15 +4567,23 @@ Prestoo Ten: changed screen.el
Primoz Peterlin: changed TUTORIAL.sl
+Protesilaos Stavrou: wrote modus-operandi-theme.el modus-themes.el
+ modus-vivendi-theme.el
+and changed modus-themes.org vc-dir.el log-view.el modus-themes.texi
+ vc-git.el apropos.el custom.el diff-mode.el perl-mode.el shortdoc.el
+ shr.el vc-cvs.el vc-hg.el vc-svn.el vc/vc-bzr.el
+
Przemysław Wojnowski: wrote obarray-tests.el sgml-mode-tests.el
and changed abbrev-tests.el abbrev.el cl-lib-tests.el loadup.el
obarray.el sgml-mode.el
Puneeth Chaganti: changed org.texi ox.el org-agenda.el org-capture.el
- ox-html.el svg.el
+ ox-html.el svg.el xwidget.el
+
+Qiantan Hong: changed xwidget.c
Radon Rosborough: changed package.el custom.texi package.texi startup.el
- eval.c lread.c org.texi os.texi
+ eval.c lread.c org.texi os.texi xterm.c
Rafael Laboissiere: changed org-remember.el org-bibtex.el org.el org.texi
@@ -4189,6 +4605,8 @@ Rajappa Iyer: changed gnus-salt.el
Raja R. Harinath: changed gnus-salt.el nnml.el
+Rajeev Narang: changed icalendar.el
+
Rajesh Vaidheeswarran: changed whitespace.el ffap.el
Ralf Angeli: wrote scroll-lock.el
@@ -4203,8 +4621,8 @@ Ralf Fassel: changed dabbrev.el files.el fill.el iso-acc.el tar-mode.el
Ralf Mattes: changed el.srt
Ralph Schleicher: wrote battery.el info-look.el
-and changed libc.el browse-url.el fileio.c info.el mm-decode.el
- nnultimate.el perl-mode.el which-func.el
+and changed libc.el browse-url.el eww.el eww.texi fileio.c info.el
+ mm-decode.el nnultimate.el perl-mode.el shr.el which-func.el
Ramakrishnan M: changed mlm-util.el
@@ -4218,8 +4636,9 @@ Randal Schwartz: wrote pp.el
Ransom Williams: changed files.el
Rasmus Pank Roulund: wrote org-tempo.el
-and changed ox-latex.el gnus-notifications.el org.el ange-ftp.el
- gnus-fun.el gnus-icalendar.el gnus-sum.el gnus.texi ido.el message.texi
+and co-wrote ox-koma-letter.el
+and changed ox-latex.el gnus-icalendar.el gnus-notifications.el org.el
+ ange-ftp.el gnus-fun.el gnus-sum.el gnus.texi ido.el message.texi
ob-C.el org-entities.el org-src.el org.texi ox-html.el ox.el vc-git.el
Raul Acevedo: changed info.el options.el
@@ -4242,6 +4661,8 @@ Remek Trzaska: changed gnus-ems.el
Remi Letot: changed nnmaildir.el
+Remington Furman: changed thingatpt.el
+
Rémi Vanicat: changed ox-icalendar.el org-table.el
Renaud Rioboo: changed nnmail.el
@@ -4254,15 +4675,14 @@ and changed vhdl-mode.texi
Reuben Thomas: changed ispell.el whitespace.el dired-x.el files.el
sh-script.el emacsclient-tests.el remember.el README emacsclient.c
- misc.texi msdos.c simple.el INSTALL ada-mode.el ada-xref.el alloc.c
- arc-mode.el authors.el config.bat copyright dired-x.texi
- and 36 other files
+ misc.texi msdos.c simple.el INSTALL alloc.c arc-mode.el authors.el
+ config.bat copyright dired-x.texi dired.el dosfns.c and 35 other files
Ricardo Wurmus: changed xwidget.el xwidget.c configure.ac xwidget.h
Riccardo Murri: changed vc-bzr.el tls.el
-Richard Copley: changed Makefile.in epaths.in epaths.nt gdb-mi.el
+Richard Copley: changed Makefile.in epaths.in epaths.nt gdb-mi.el sort.el
text.texi
Richard Dawe: changed config.in src/Makefile.in
@@ -4272,7 +4692,7 @@ Richard G. Bielawski: changed modes.texi paren.el
Richard Hoskins: changed message.el
Richard Kim: wrote wisent/python.el
-and changed bovine.texi db-global.el loading.texi python-wy.el
+and changed bovine.texi db-global.el gud.el loading.texi python-wy.el
texnfo-upd.el wisent.texi
Richard King: wrote filelock.c uniquify.el userlock.el
@@ -4346,15 +4766,15 @@ Roberto Rodríguez: changed glossary.texi widget.texi
Robert P. Goldman: changed org.texi ob-exp.el org.el ox-latex.el
Robert Pluim: wrote nsm-tests.el
-and changed process.c ftfont.c gtkutil.c processes.texi vc-git.el
- configure.ac font.c network-stream.el nsm.el process-tests.el xfns.c
- dispextern.h files.texi ftcrfont.c gnus-icalendar.el gnutls.el
- gtkutil.h network-stream-tests.el nsterm.m text.texi w32.c
- and 90 other files
+and changed configure.ac process.c blocks.awk network-stream-tests.el
+ font.c processes.texi ftfont.c gtkutil.c vc-git.el process-tests.el
+ emoji-zwj.awk gnutls.el network-stream.el nsm.el tramp.texi mml-sec.el
+ nsterm.m unicode xfns.c auth.texi composite.c and 133 other files
-Robert Thorpe: changed cus-start.el indent.el
+Robert Thorpe: changed cus-start.el indent.el rmail.texi
-Robert Weiner: changed cus-edit.el
+Robert Weiner: changed cus-edit.el etags.el positions.texi simple.el
+ subr.el texinfo.el
Rob Giardina: changed org-agenda.el
@@ -4375,7 +4795,7 @@ Roger Breitenstein: changed smtpmail.el
Roland B. Roberts: changed buffer.h callproc.c dired.c files.el
gnus-group.el gnus-sum.el process.c sort.el sysdep.c systty.h
-Roland Kaufmann: changed ox.el
+Roland Kaufmann: changed configure.ac ox.el
Roland McGrath: wrote autoload.el etags.el map-ynp.el progmodes/grep.el
and co-wrote find-dired.el progmodes/compile.el
@@ -4386,9 +4806,9 @@ and changed compile.el add-log.el configure.ac files.el vc.el simple.el
Roland Winkler: wrote proced.el
and changed bibtex.el faces.el crm.el find-dired.el bookmark.el process.c
- appt.el artist.el bibtex-style.el conf-mode.el cus-edit.el diary-lib.el
- flyspell.el hideshow.el ibuf-ext.el ibuffer.el ispell.el make-mode.el
- sgml-mode.el sh-script.el skeleton.el smtpmail.el
+ smtpmail.el appt.el artist.el bibtex-style.el conf-mode.el cus-edit.el
+ diary-lib.el flyspell.el gnus.texi hideshow.el ibuf-ext.el ibuffer.el
+ ispell.el make-mode.el nnimap.el and 5 other files
Rolf Ade: changed sql.el tcl.el
@@ -4417,9 +4837,9 @@ Roy Liu: changed ns-win.el
Rüdiger Sonderfeld: wrote inotify-tests.el reftex-tests.el
and changed eww.el octave.el shr.el bibtex.el configure.ac
- misc/Makefile.in reftex-vars.el vc-git.el TUTORIAL.de ada-mode.el
- autoinsert.el building.texi calc-lang.el cc-langs.el dired.texi
- editfns.c emacs.c emacs.texi epa.el erc.el eww.texi and 39 other files
+ misc/Makefile.in reftex-vars.el vc-git.el TUTORIAL.de autoinsert.el
+ building.texi bytecomp.el calc-lang.el cc-langs.el dired.texi editfns.c
+ emacs.c emacs.texi epa.el erc.el eww.texi and 39 other files
Rui-Tao Dong: changed nnweb.el
@@ -4431,13 +4851,19 @@ Ruslan Bekenev: changed rfc2045.el rfc2047.el rfc2231.el
Russ Allbery: changed message.el
+Ruthra Kumar: changed arc-mode.el esh-cmd.el files.el
+
Ryan Barrett: changed dirtrack.el
Ryan Brown: changed cl-indent.el
-Ryan Crum: changed json.el
+Ryan Crum: changed term.el json.el
+
+Ryan Olson: changed package.el
-Ryan Thompson: changed advice-tests.el ido.el minibuffer-tests.el
+Ryan Prior: changed comint.el
+
+Ryan Thompson: changed ido.el advice-tests.el minibuffer-tests.el
minibuffer.el savehist.el tmm.el
Ryan Twitchell: changed ido.el
@@ -4471,9 +4897,8 @@ Sam Kendall: changed etags.c etags.el
Sam Steingold: wrote gulp.el midnight.el
and changed progmodes/compile.el cl-indent.el simple.el vc-cvs.el vc.el
mouse.el vc-hg.el etags.el files.el font-lock.el tex-mode.el
- ange-ftp.el sgml-mode.el vc-git.el window.el add-log.el bindings.el
- bookmark.el bug-reference.el calendar.el cperl-mode.el
- and 157 other files
+ ange-ftp.el gnus-sum.el message.el sgml-mode.el vc-git.el window.el
+ add-log.el bindings.el bookmark.el bug-reference.el and 186 other files
Samuel Bronson: changed custom.el emacsclient.c keyboard.c
progmodes/grep.el semantic/format.el unexmacosx.c
@@ -4490,6 +4915,8 @@ Sanghyuk Suh: changed mac-win.el macterm.c
Santiago Payà i Miralta: changed vc-hg.el
+Saroj Thirumalai: changed printing.el
+
Sascha Lüdecke: co-wrote mml1991.el
and changed gnus-win.el
@@ -4498,6 +4925,8 @@ Sascha Wilde: changed pgg-gpg.el pgg.texi pgg.el bubbles.el configure.ac
Sašo Živanović: changed reftex-parse.el reftex.el
+Satoshi Nakagawa: changed url-http.el
+
Satyaki Das: wrote mh-acros.el mh-gnus.el mh-search.el mh-speed.el
mh-thread.el mh-tool-bar.el
and co-wrote mh-junk.el
@@ -4539,6 +4968,9 @@ Sean O'Rourke: changed complete.el comint.el dabbrev.el find-func.el
Sean Sieger: changed emacs-lisp-intro.texi
+Sean Whitton: changed project.el bindings.el files.texi simple.el
+ repeat.el
+
Sebastian Freundt: changed nnmaildir.el
Sebastian Hermida: wrote misterioso-theme.el
@@ -4554,6 +4986,9 @@ and changed ox-publish.el ftfont.c ox-jsinfo.el
Sebastian Tennant: changed desktop.el
+Sebastian Urban: changed display.texi basic.texi docstyle.texi emacs.texi
+ fixit.texi text.texi
+
Sebastian Wiesner: changed bytecomp.el comint.el files.el replace.el
simple.el
@@ -4578,14 +5013,18 @@ Seppo Sade: changed esh-ext.el
Sergei Organov: changed vc.el
+Serge Tupchii: changed etags.c
+
Sergey Litvinov: co-wrote ob-fortran.el
and changed ob-maxima.el ob-octave.el
+Sergey Organov: changed desktop.el
+
Sergey Poznyakoff: changed rmail.el mh-mime.el rmail.texi smtpmail.el
Sergey Trofimov: changed window.el
-Sergey Vinokurov: changed emacs-module-tests.el emacs-module.c mod-test.c
+Sergey Vinokurov: changed emacs-module-tests.el emacs-module.c
Sergio Durigan Junior: changed eudcb-bbdb.el gdb-mi.el
@@ -4623,6 +5062,10 @@ Shingo Tanaka: changed files.el
Shinichirou Sugou: changed etags.c
+Shitikanth Kashyap: changed progmodes/python.el tabulated-list.el
+
+Shohei Yoshida: changed configure.ac
+
Shoji Nishimura: changed org.el
Sho Nakatani: changed doc-view.el
@@ -4642,16 +5085,16 @@ Sidney Markowitz: changed doctor.el nsmenu.m
Sigbjorn Finne: changed gnus-srvr.el
Simen Heggestøyl: wrote apropos-tests.el asm-mode-tests.el
- autoconf-tests.el autoinsert-tests.el check-declare-tests.el
- color-tests.el css-mode-tests.el dom-tests.el elide-head-tests.el
- glasses-tests.el help-mode-tests.el makesum-tests.el page-tests.el
- paren-tests.el po-tests.el ring-tests.el rot13-tests.el sql-tests.el
- webjump-tests.el
-and changed css-mode.el css-mode.css json-tests.el json.el sgml-mode.el
- scss-mode.scss page.el ring.el rot13.el scheme.el sql.el asm-mode.el
- autoinsert.el color.el files.el js.el less-css-mode.el
- less-css-mode.less maintaining.texi makesum.el midnight.el
- and 5 other files
+ autoconf-tests.el autoinsert-tests.el browse-url-tests.el
+ check-declare-tests.el color-tests.el css-mode-tests.el dom-tests.el
+ elide-head-tests.el glasses-tests.el help-mode-tests.el
+ makesum-tests.el page-tests.el paren-tests.el po-tests.el ring-tests.el
+ rot13-tests.el sql-tests.el webjump-tests.el
+and changed css-mode.el project.el json-tests.el json.el scss-mode.scss
+ sgml-mode.el less-css-mode.less maintaining.texi modes.texi page.el
+ ring.el rot13.el scheme.el sql.el apropos.el asm-mode.el autoconf.el
+ autoinsert.el browse-url.el check-declare.el color.el
+ and 15 other files
Simona Arizanova: changed help.el
@@ -4660,13 +5103,16 @@ Simon Josefsson: wrote dig.el dns-mode.el flow-fill.el fringe.el imap.el
sasl-scram-sha256.el sieve-mode.el sieve.el smime.el starttls.el tls.el
url-imap.el
and co-wrote gnus-sieve.el gssapi.el mml1991.el nnfolder.el nnimap.el
- nnml.el sieve-manage.el
+ nnml.el rot13.el sieve-manage.el
and changed message.el gnus-sum.el gnus-art.el smtpmail.el pgg-gpg.el
pgg.el gnus-agent.el mml2015.el mml.el gnus-group.el mm-decode.el
gnus-msg.el gnus.texi mail/sieve-manage.el pgg-pgp5.el browse-url.el
gnus-int.el gnus.el hashcash.el mm-view.el password.el
and 101 other files
+Simon Lang: changed building.texi icomplete.el misterioso-theme.el
+ progmodes/grep.el
+
Simon Law: changed delsel.el electric.el
Simon Leinen: changed Makefile.in smtpmail.el Makefile cm.c cm.h hpux9.h
@@ -4680,8 +5126,6 @@ and changed font-lock.el rmail.el fortran.el sendmail.el subr.el dired.el
menu-bar.el perl-mode.el ps-print.el rmailsum.el bytecomp.el
cc-fonts.el data.c faces.el lisp-mode.el and 56 other files
-Simon Michael: wrote ob-hledger.el
-
Simon Schubert: changed json.el
Simon South: co-wrote opascal.el
@@ -4693,6 +5137,8 @@ Skip Collins: changed w32fns.c w32term.c w32term.h
Sławomir Nowaczyk: changed emacs.py progmodes/python.el TUTORIAL.pl
flyspell.el ls-lisp.el w32proc.c
+Spencer Baugh: changed data-tests.el alloc.c autorevert.el
+
Spencer Thomas: changed dabbrev.el emacsclient.c gnus.texi server.el
unexcoff.c
@@ -4707,30 +5153,35 @@ Stefan Bruda: co-wrote prolog.el
Stefan Guath: changed find-dired.el
Stefan Kangas: wrote bookmark-tests.el cal-julian-tests.el
- delim-col-tests.el lunar-tests.el misc-tests.el morse-tests.el
- paragraphs-tests.el password-cache-tests.el qp-tests.el
- rfc2045-tests.el studly-tests.el tabify-tests.el timezone-tests.el
- underline-tests.el uudecode-tests.el
-and changed bookmark.el package.el efaq.texi package.texi ibuffer.el
- mwheel.el cperl-mode.el fns.c gud.el simple.el subr.el autoinsert.el
- comint-tests.el cus-edit.el delim-col.el dired-aux.el dired-x.el
- em-term.el ert.texi flow-fill.el frames.texi and 147 other files
+ delim-col-tests.el etc-authors-mode.el life-tests.el loadhist-tests.el
+ lunar-tests.el mail-utils-tests.el misc-tests.el morse-tests.el
+ netrc-tests.el paragraphs-tests.el password-cache-tests.el qp-tests.el
+ rfc2045-tests.el sasl-cram-tests.el sasl-tests.el saveplace-tests.el
+ studly-tests.el tabify-tests.el time-tests.el timezone-tests.el
+ underline-tests.el uudecode-tests.el warnings-tests.el
+and co-wrote help-tests.el keymap-tests.el
+and changed efaq.texi checkdoc.el package.el cperl-mode.el bookmark.el
+ help.el keymap.c subr.el simple.el erc.el ediff-util.el idlwave.el
+ time.el bytecomp-tests.el comp.el speedbar.el bytecomp.el
+ emacs-lisp-intro.texi flyspell.el ibuffer.el package-tests.el
+ and 1337 other files
Stefan Merten: co-wrote rst.el
Stefan Monnier: wrote bibtex-style.el bytecomp-tests.el
cl-generic-tests.el cl-generic.el cl-preloaded.el cl-print.el cl.el
css-mode.el cursor-sensor.el cvs-status.el diff-mode.el fileloop.el
- footnote-tests.el gv.el inline.el lisp-tests.el log-edit.el log-view.el
+ find-func-tests.el footnote-tests.el gv.el inline.el lisp-mnt-tests.el
+ lisp-tests.el log-edit.el log-view.el macroexp-tests.el
minibuffer-tests.el minibuffer.el mpc.el nadvice.el pcase.el
pcvs-defs.el pcvs-info.el pcvs-parse.el pcvs-util.el radix-tree.el
regexp-opt-tests.el reveal.el smerge-mode.el smie.el subword-tests.el
vc-mtn.el
and co-wrote font-lock.el gitmerge.el pcvs.el
-and changed subr.el simple.el keyboard.c bytecomp.el files.el lisp.h
- cl-macs.el vc.el xdisp.c alloc.c eval.c sh-script.el
- progmodes/compile.el keymap.c tex-mode.el buffer.c newcomment.el
- window.c lread.c fileio.c help-fns.el and 1372 other files
+and changed subr.el simple.el keyboard.c bytecomp.el cl-macs.el files.el
+ lisp.h vc.el xdisp.c alloc.c eval.c sh-script.el progmodes/compile.el
+ keymap.c buffer.c window.c tex-mode.el lisp-mode.el newcomment.el
+ help-fns.el lread.c and 1616 other files
Stefano Facchini: changed gtkutil.c
@@ -4748,11 +5199,13 @@ Stefan Wiens: changed gnus-sum.el
Steinar Bang: changed gnus-setup.el imap.el
-Štěpán Němec: changed INSTALL calc-ext.el checkdoc.el cl.texi comint.el
- edebug.texi font-lock.el functions.texi gnus-sum.el insdel.c
- leim-ext.el loading.texi maps.texi mark.texi message.texi mini.texi
- minibuf.texi misc.texi programs.texi subr.el text.texi
- and 7 other files
+Štěpán Němec: changed loadhist.el files.el gnus-sum.el loading.texi
+ subr.el INSTALL calc-ext.el checkdoc.el cl.texi comint.el edebug.texi
+ ediff-init.el emacs-lisp/cl-lib.el find-func.el fixit.texi font-lock.el
+ functions.texi gnus-art.el gnus.texi help-fns.el help.el
+ and 22 other files
+
+Stéphane Boucher: changed replace.el
Stephan Stahl: changed which-func.el buff-menu.el buffer.c dired-x.texi
ediff-mult.el
@@ -4761,11 +5214,11 @@ Stephen A. Wood: changed fortran.el
Stephen Berman: wrote todo-mode-tests.el
and co-wrote todo-mode.el
-and changed wdired.el todo-mode.texi diary-lib.el wdired-tests.el
- dired-tests.el doc-view.el files.el minibuffer.el dired.el frames.texi
- hl-line.el info.el menu-bar.el mouse.el otodo-mode.el subr.el
- .gitattributes TUTORIAL allout.el artist.el compile.texi
- and 43 other files
+and changed wdired.el todo-mode.texi diary-lib.el dired.el
+ wdired-tests.el dired-tests.el doc-view.el files.el info.el
+ minibuffer.el todo-test-1.todo eww.el frames.texi hl-line.el
+ menu-bar.el mouse.el otodo-mode.el subr.el .gitattributes TUTORIAL
+ allout.el and 59 other files
Stephen C. Gilardi: changed configure.ac
@@ -4779,19 +5232,20 @@ and changed diary-lib.el octave.el org-agenda.el locate.el replace.el
Stephen Gildea: wrote refcard.tex
and co-wrote mh-funcs.el mh-search.el
-and changed time-stamp.el time-stamp-tests.el mh-e.el mh-comp.el
- mh-utils.el mh-junk.el files.el mh-customize.el mh-e.texi mh-show.el
- backups.texi dns-mode.el fileio.c files.texi fortran.el goto-addr.el
- mh-mime.el misc.texi mwheel.el tex-mode.el
+and changed time-stamp.el time-stamp-tests.el mh-e.el mh-junk.el
+ mh-comp.el mh-utils-tests.el mh-utils.el mh-e.texi mh-show.el files.el
+ mh-customize.el mh-xface-tests.el backups.texi compile.texi dns-mode.el
+ fileio.c files.texi finder.el fortran.el goto-addr.el iso8601-tests.el
+ and 17 other files
Stephen J. Turnbull: changed ediff-init.el strings.texi subr.el
Stephen Leake: wrote elisp-mode-tests.el
-and changed ada-mode.el ada-xref.el elisp-mode.el xref.el window.el
- mode-local.el CONTRIBUTE ada-prj.el project.el vc-mtn.el ada-stmt.el
- cedet-global.el ede/generic.el simple.el autoload.el bytecomp.el
- cl-generic.el ede/locate.el files.texi functions.texi package.el
- and 30 other files
+and changed elisp-mode.el xref.el window.el mode-local.el CONTRIBUTE
+ project.el vc-mtn.el ada-stmt.el cedet-global.el ede/generic.el
+ simple.el autoload.el bytecomp.el cl-generic.el ede/locate.el
+ files.texi functions.texi package.el progmodes/grep.el windows.texi
+ INSTALL.REPO and 32 other files
Stephen Pegoraro: changed xterm.c
@@ -4803,7 +5257,8 @@ Steve Fisk: co-wrote cal-tex.el
Steve Grubb: changed vcdiff
-Steven Allen: changed em-prompt.el xdg.el
+Steven Allen: changed em-prompt.el esh-mode.el tramp-gvfs.el
+ tramp-integration.el url-expand.el xdg.el
Steven De Herdt: changed vc/vc-bzr.el
@@ -4825,7 +5280,7 @@ Steven Tamm: changed macterm.c mac.c macfns.c configure.ac mac-win.el
Steve Nygard: changed unexnext.c
Steve Purcell: wrote less-css-mode.el
-and changed package.el nnimap.el nsterm.m sql.el
+and changed package.el nnimap.el nsterm.m ruby-mode.el sql.el
Steve Scott: changed rcirc.el
@@ -4855,6 +5310,11 @@ Suhail Shergill: changed ob-core.el ox-html.el
Sundar Narasimhan: changed rnews.el
+Sungbin Jo: changed nsxwidget.m xwidget.c xwidget.el nsxwidget.h
+ xwidget.h Info.plist.in configure.ac emacs.c nsterm.m src/Makefile.in
+
+Sun Lin: changed dired-aux.el
+
Sun Microsystems, Inc: wrote emacs.icon sun.el
and changed emacsclient.c server.el
@@ -4903,8 +5363,11 @@ Takai Kousuke: changed ccl.el image/compface.el
Takeshi Yamada: changed fns.c
+Takesi Ayanokoji: changed anti.texi efaq.texi
+
Tak Kunihiro: wrote pixel-scroll.el
-and changed frames.texi mouse.el mwheel.el dired.el ns-win.el
+and changed frames.texi mouse.el mwheel.el dired.el lists.texi ns-win.el
+ subr.el
Tao Fang: changed url-http.el
@@ -4913,11 +5376,11 @@ and changed arc-mode.el
Tassilo Horn: wrote doc-view.el
and co-wrote ol-gnus.el
-and changed reftex-vars.el tex-mode.el gnus.texi reftex-cite.el
- tsdh-dark-theme.el tsdh-light-theme.el gnus-sum.el file-notify-tests.el
- reftex.el misc.texi org-gnus.el prog-mode.el subword.el image-mode.el
- json.el lisp-mode.el cc-cmds.el display.texi em-term.el emacsbug.el
- files.el and 82 other files
+and changed bug-reference.el reftex-vars.el tex-mode.el browse-url.el
+ gnus.texi reftex-cite.el tsdh-dark-theme.el tsdh-light-theme.el
+ gnus-sum.el maintaining.texi file-notify-tests.el gnus-art.el misc.texi
+ reftex.el org-gnus.el prog-mode.el subword.el image-mode.el json.el
+ lisp-mode.el rcirc.el and 99 other files
Tatsuya Ichikawa: changed gnus-agent.el gnus-cache.el
@@ -4936,8 +5399,9 @@ Teodor Zlatanov: wrote auth-source.el gnus-registry.el gnus-tests.el
url-future-tests.el url-future.el url-util-tests.el
and changed spam.el gnus.el nnimap.el gnus.texi gnutls.c gnus-sum.el
auth.texi cfengine.el gnus-sync.el gnus-util.el gnus-start.el netrc.el
- gnutls.h message.el spam-stat.el encrypt.el mail-source.el nnir.el
- nnmail.el auth-source-tests.el configure.ac and 119 other files
+ gnutls.h message.el spam-stat.el .gitlab-ci.yml encrypt.el
+ mail-source.el nnir.el nnmail.el auth-source-tests.el
+ and 125 other files
Terje Rosten: changed xfns.c version.el xterm.c xterm.h
@@ -4956,12 +5420,17 @@ Thamer Mahmoud: changed arabic.el
Theodore Jump: changed makefile.nt makefile.def w32-win.el w32faces.c
+Theodor Thornhill: changed project.el css-mode.el maintaining.texi
+ mwheel.el shell.el tutorial.el
+
Theresa O'Connor: wrote json.el
and changed erc.el erc-viper.el erc-log.el erc-track.el viper.el
erc-backend.el erc-chess.el erc-dcc.el erc-ezbounce.el erc-goodies.el
erc-list.el erc-macs.el erc-match.el erc-ring.el erc-services.el
erc-stamp.el goto-addr.el latin-ltx.el progmodes/python.el url-auth.el
+Thibault Polge: changed ibuffer.el subr.el
+
Thien-Thi Nguyen: wrote last-chance.el
and co-wrote hideshow.el
and changed ewoc.el vc.el info.el processes.texi zone.el lisp-mode.el
@@ -4978,7 +5447,7 @@ Thierry Volpiatto: changed bookmark.el files.el dired-aux.el
eshell/eshell.el gnus-sum.el keyboard.c net-utils.el package.el
tramp.el eldoc.el files.texi image-mode.el info.el man.el minibuffer.el
pcmpl-gnu.el subr.el winner.el woman.el avoid.el commands.texi
- and 15 other files
+ and 16 other files
Thomas Bach: changed wisent/python.el
@@ -4994,10 +5463,11 @@ Thomas Dorner: changed ange-ftp.el
Thomas Dye: changed org.texi org-bibtex.el ob-R.el org.el
Thomas Fitzsimmons: wrote soap-client.el
-and changed soap-inspect.el ldap.el eudc-vars.el eudc.el eudc.texi
- ntlm.el eudcb-ldap.el eudcb-bbdb.el eudc-bob.el eudc-export.el
- eudcb-ph.el package.el url-http.el diary-lib.el display.texi
- eudc-hotlist.el icalendar.el url-auth.el
+and changed soap-inspect.el ldap.el eudc.texi eudc-vars.el eudc.el
+ ntlm.el url-http.el eudcb-ldap.el eudcb-bbdb.el ntlm-tests.el
+ eudc-bob.el eudc-export.el eudcb-ph.el package.el README authinfo
+ diary-lib.el display.texi eudc-hotlist.el eudcb-macos-contacts.el
+ icalendar.el and 3 other files
Thomas Horsley: changed cxux-crt0.s cxux.h cxux7.h emacs.c nh3000.h
nh4000.h simple.el sysdep.c xterm.c
@@ -5026,8 +5496,6 @@ and changed emacs-lock.el subr.el
Thor Kristoffersen: changed nntp.el
-Thorsten Jolitz: co-wrote ob-picolisp.el
-
Thorsten Ohl: changed lread.c next.h
Tiago Saboga: changed files.el
@@ -5048,28 +5516,32 @@ Tim Harper: changed ns-win.el
Tim Howe: changed org-clock.el
-Tim Landscheidt: changed gnus-art.el gnus.texi icalendar.el sort.el
- ws-mode.el
+Tim Landscheidt: changed gnus-art.el eieio-opt.el gnus.texi icalendar.el
+ sort.el ws-mode.el
Timo Juhani Lindfors: changed gnus-msg.el
Timo Lilja: changed mail-source.el
-Timo Myyrä: changed battery.el
+Timo Myyrä: changed battery.el configure.ac english.el european.el
+ language/japanese.el mule-conf.el systhread.c
Timo Savola: changed emacs.c gtkutil.c startup.el x-win.el xfns.c xterm.c
xterm.h
+Tim Ruffing: changed emacs.service
+
Tim Van Holder: changed emacsclient.c Makefile.in configure.ac
progmodes/compile.el which-func.el
Tino Calancha: wrote buff-menu-tests.el ediff-ptch-tests.el
em-ls-tests.el ffap-tests.el hi-lock-tests.el ls-lisp-tests.el
register-tests.el rmc-tests.el
-and changed ibuffer.el ibuf-ext.el dired-tests.el dired.el replace.el
- dired-aux.el replace-tests.el simple.el ibuf-macs.el subr.el dired.texi
- ibuffer-tests.el ls-lisp.el diff-mode.el files.el cl-macs.el cl-seq.el
- dired-x.el ediff-ptch.el em-ls.el buff-menu.el and 95 other files
+and changed ibuffer.el dired.el ibuf-ext.el dired-tests.el replace.el
+ dired-aux.el simple.el replace-tests.el dired.texi files.el
+ ibuf-macs.el subr.el ibuffer-tests.el ls-lisp.el cl-macs.el
+ diff-mode.el cl-seq.el dired-x.el ediff-ptch.el em-ls.el files-tests.el
+ and 113 other files
Titus von der Malsburg: changed simple.el window.el
@@ -5081,12 +5553,14 @@ Tobias Gerdin: changed xref.el
Tobias Ringström: changed etags.c
-Tobias Zawada: changed wid-edit.el
+Tobias Rittweiler: changed xref-tests.el xref.el
+
+Tobias Zawada: changed find-func.el hideshow.el wid-edit.el
Toby Allsopp: changed ldap.el eudc.el
Toby Cubitt: co-wrote avl-tree.el
-and changed org-capture.el org.el org-agenda.el org-clock.el
+and changed org-capture.el org.el org-agenda.el cl-macs.el org-clock.el
org-colview.el org.texi
Toby Speight: changed generic-x.el window.el
@@ -5098,10 +5572,18 @@ Tokuya Kameshima: changed org-mew.el org-agenda.el
Tomas Abrahamsson: wrote artist.el
+Tomas Nordin: changed progmodes/python.el
+
Tomasz Gajewski: changed cpp-root.el
+Tomasz Konojacki: changed perl-mode.el
+
Tom Breton: changed autoinsert.el cus-edit.el gnus-agent.el lread.c
+Tom Fitzhenry: changed vc-hg.el
+
+Tom Gillespie: changed files.el
+
Tom Hageman: changed etags.c
Tom Houlder: wrote mantemp.el
@@ -5135,10 +5617,10 @@ Tom Seddon: changed w32font.c
Tom Tromey: wrote bug-reference.el erc-list.el package-x.el
and co-wrote package.el tcl.el
-and changed data.c lisp.h js.el buffer.c data-tests.el alloc.c
- css-mode.el js-tests.el mhtml-mode.el process.c window.c editfns.c
- fns.c keyboard.c keymap.c lread.c makefile.el xfns.c bytecode.c cmds.c
- configure.ac and 206 other files
+and changed data.c lisp.h js.el buffer.c data-tests.el mhtml-mode.el
+ alloc.c css-mode.el js-tests.el process.c window.c bytecode.c editfns.c
+ files.el fns.c keyboard.c keymap.c lread.c makefile.el xfns.c cmds.c
+ and 208 other files
Tom Willemse: changed elec-pair.el package.el perl-mode.el prog-mode.el
progmodes/python.el simple.el
@@ -5154,6 +5636,9 @@ Torsten Anders: changed ox-beamer.el
Torsten Bronger: changed latin-ltx.el
+Torsten Hilbrich: wrote dictionary-connection.el dictionary.el
+and changed net
+
Toru Tomabechi: wrote language/tibetan.el quail/tibetan.el tibet-util.el
Toru Tsuneyoshi: changed ange-ftp.el buff-menu.el cus-start.el fileio.c
@@ -5163,7 +5648,7 @@ Toshiaki Nomura: changed uxpds.h
Trent W. Buck: changed rcirc.el remember.el rx.el
-Trevor Murphy: changed find-dired.el gnus.texi nnimap.el org.el
+Trevor Murphy: changed find-dired.el gnus.texi nnimap.el org.el window.el
Trevor Spiteri: changed progmodes/grep.el
@@ -5184,8 +5669,8 @@ Tsuchiya Masatoshi: changed gnus-art.el mm-view.el gnus-sum.el
Tsugutomo Enami: changed frame.c keyboard.c configure.ac dispnew.c
fileio.c process.c simple.el sysdep.c xdisp.c add-log.el bytecomp.el
- editfns.c emacs.c frame.h gnus-group.el netbsd.h nnheader.el nnimap.el
- perl-mode.el regex.c regex.h and 6 other files
+ editfns.c emacs-regex.c emacs-regex.h emacs.c frame.h gnus-group.el
+ netbsd.h nnheader.el nnimap.el perl-mode.el and 6 other files
Tsuyoshi Akiho: changed gnus-sum.el nnrss.el
@@ -5214,16 +5699,21 @@ Ulrich Müller: changed configure.ac calc-units.el lib-src/Makefile.in
src/Makefile.in version.el doctor.el emacs.1 files.el gamegrid.el
gud.el server.el ChgPane.c ChgSel.c HELLO INSTALL Makefile.in
XMakeAssoc.c authors.el bytecomp.el case-table.el configure
- and 39 other files
+ and 40 other files
Ulrich Neumerkel: changed xterm.c
+Ulrich Ölmann: changed misc.texi
+
Ulrik Vieth: wrote meta-mode.el
and changed files.el
Ury Marshak: changed nsfns.m
-Uwe Brauer: changed mml-smime.el
+Utkarsh Singh: changed em-script.el files.el outline.el tex-mode.el
+ vc-git.el window.el
+
+Uwe Brauer: changed tex-mode.el mml-smime.el
Vadim Nasardinov: changed allout.el
@@ -5237,9 +5727,11 @@ Valentin Gatien-Baron: changed emacs-module.c
Valentin Wüstholz: changed org.el
+Valery Alexeev: changed cyril-util.el cyrillic.el
+
Van L: changed subr.el
-Vasilij Schneidermann: changed cus-start.el eww.el cc-mode.el
+Vasilij Schneidermann: changed ETAGS.EBNF cus-start.el eww.el cc-mode.el
debugging.texi display.texi edebug.el emacs-lisp/debug.el eval.c
ielm.el os.texi profiler.el redisplay-testsuite.el shr.el snake.el
term.el tetris.el xdisp.c xterm.c
@@ -5260,7 +5752,10 @@ Victor J. Orlikowski: changed erc-dcc.el
Victor Zandy: wrote zone.el
-Viktor Rosenfeld: changed ob-sql.el org.el
+Viktor Rosenfeld: co-wrote ox-koma-letter.el
+and changed ob-sql.el org.el
+
+Viktor Slavkovikj: changed rmail.el
Ville Skyttä: changed mh-comp.el pgg.el tcl.el
@@ -5296,10 +5791,14 @@ and changed erc-backend.el erc.el erc-services.el hexl.el emacs.c
erc-button.el erc-capab.el erc-join.el htmlfontify.texi sh-script.el
xterm.c xterm.h
+Vladimir Alexiev: changed arc-mode.el nnvirtual.el tmm.el
+
Vladimir Kazanov: changed java.srt
Vladimir Lomov: changed ox-html.el
+Vladimir Nikishkin: changed scm.el
+
Vladimir Panteleev: wrote bat-mode-tests.el
and changed ert.texi bat-mode.el
@@ -5343,6 +5842,8 @@ Wilfred Hughes: changed button.el byte-opt.el css-mode.el find-func.el
Will Glozer: changed macterm.c
+William Denton: changed ruby-mode.el
+
William F. Schelter: wrote telnet.el
William M. Perry: wrote url-dav.el url-gw.el url-http.el url-util.el
@@ -5363,10 +5864,8 @@ William Sommerfeld: wrote emacsclient.c scribe.el server.el
William Stevenson: wrote adwaita-theme.el
and changed artist.el
-William Waites: wrote ob-abc.el
-
William Xu: changed arc-mode.el gcc.el hideif.el nsterm.m outline.el
- url.el webjump.el
+ url.el webjump.el xref.el
Will Mengarini: wrote repeat.el
@@ -5377,6 +5876,8 @@ and changed files.el
Wim Nieuwenhuizen: changed TUTORIAL.nl
+Win Treese: changed nsmenu.m
+
Wlodzimierz Bzyl: co-wrote ogonek.el
and changed pl-refcard.tex
@@ -5405,6 +5906,7 @@ and changed process.c alloc.c callint.c config.in configure.ac data.c
print.c sort.el
Wolfgang Scherer: changed vc-cvs.el vc-dir.el vc-svn.el vc.el pcvs.el
+ vc-git.el
Wolfgang Schnerring: changed emacsclient.c
@@ -5418,7 +5920,7 @@ Xavier Maillard: changed gnus-faq.texi gnus-score.el mh-utils.el spam.el
Xi Lu: changed etags.c tramp-sh.el
-Xu Chunyang: changed dom.el eww.el gud.el netrc.el
+Xu Chunyang: changed eww.el dom.el gud.el netrc.el
Xue Fuqiao: changed display.texi emacs-lisp-intro.texi files.texi
maintaining.texi text.texi windows.texi nonascii.texi frames.texi
@@ -5433,14 +5935,18 @@ Yair F: changed hebrew.el
Yamamoto Mitsuharu: wrote uvs.el
and changed macterm.c macfns.c mac-win.el xterm.c mac.c macterm.h image.c
macmenu.c macgui.h xdisp.c ftfont.c xfns.c keyboard.c macselect.c
- ftcrfont.c configure.ac macfont.m w32term.c dispextern.h
- src/Makefile.in unexmacosx.c and 109 other files
+ ftcrfont.c macfont.m configure.ac w32term.c dispextern.h
+ src/Makefile.in unexmacosx.c and 108 other files
+
+Yan Gajdos: changed vc-git.el
Yann Dirson: changed imenu.el
Yann Hodique: changed ox-publish.el package.el rcirc.el
-Yasuhiro Kimura: changed japan-util.el
+Yasuhiro Kimura: changed schemas.xml japan-util.el
+
+Yasuoka Masahiko: changed configure.ac
Yasushi Shoji: changed org-clock.el org.texi ox-ascii.el
@@ -5449,6 +5955,10 @@ Yavor Doganov: changed configure.ac Makefile.in emacs.1 etags.1 make-dist
Ye Qianchuan: changed descr-text.el
+Yichao Yu: changed xfns.c xterm.c
+
+Yikai Zhao: changed memory-report.el
+
Yoichi Nakayama: changed browse-url.el finder.el man.el rfc2368.el
Yong Lu: changed charset.c coding.c language/greek.el
@@ -5466,17 +5976,23 @@ Yoshinari Nomura: changed ox-html.el ox.el
Yoshinori Koseki: wrote iimage.el
and changed fontset.el message.el nnheader.el nnmail.el
-Yuan Fu: changed gdb-mi.el
+Yuan Fu: changed gdb-mi.el building.texi doc-view.el outline.el
+ simple-tests.el cus-start.el display.texi gud.el simple.el text.texi
+ window.el xdisp.c
Yuanle Song: changed rng-xsd.el
+Yuchen Pei: changed calendar.texi diary-lib.el icalendar-tests.el
+
Yue Daian: wrote cl-font-lock.el
+Yuga Ego: changed emacs-lisp-intro.texi
+
Yu-ji Hosokawa: changed README.W32
Yukihiro Matsumoto: co-wrote ruby-mode.el
-Yuri D'elia: changed message.el package.el
+Yuri D'Elia: changed message.el package.el
Yuri Karaban: changed pop3.el
@@ -5500,15 +6016,20 @@ Yves Baumes: changed package.el
Zachary Kanfer: changed org.el cus-edit.el keyboard.c newcomment.el
simple.el
+Zajcev Evgeny: changed display.texi image.c battery.el buffer.c fileio.c
+ lread.c svg.el window.el xdisp.c
+
Zhang Wei: changed chinese.el characters.el mule-cmds.el xfns.c erc.el
faces.el fontset.el mm-util.el mule.el org-publish.el rfc2047.el
x-win.el
Zhang Weize: wrote ob-plantuml.el
+Zhiwei Chen: changed hideif.el
+
Zhongwei Yao: changed tramp-adb.el
-Zhu Zihao: changed svg.el
+Zhu Zihao: changed eieio.el svg.el
Zoltan Kemenczy: changed gud.el
@@ -5521,5 +6042,6 @@ Zoran Milojevic: changed avoid.el
উৎসব রায়: changed quail/indian.el
Local Variables:
+mode: etc-authors
coding: utf-8
End:
diff --git a/etc/DEBUG b/etc/DEBUG
index fae87261865..a05aeef1606 100644
--- a/etc/DEBUG
+++ b/etc/DEBUG
@@ -573,6 +573,32 @@ debugging did not (yet) happen. Here are some useful techniques for that:
GET_FROM_IMAGE for displaying an image, etc. See 'enum it_method' in
dispextern.h for the full list of values.
+** Debugging problems with native-compiled Lisp.
+
+When you encounter problems specific to native-compilation of Lisp, we
+recommend to follow the procedure below to try to identify the cause:
+
+ . Reduce the problematic .el file to the minimum by bisection, and
+ try identifying the function that causes the problem.
+
+ . Reduce the problematic function to the minimal code that still
+ reproduces the problem.
+
+ . Study the problem's artifacts, like Lisp or C backtraces, to try
+ identifying the cause of the problem.
+
+If you cannot figure out the cause for the problem using the above,
+native-compile the problematic file after setting the variable
+'comp-libgccjit-reproducer' to a non-nil value. That should produce a
+file named ELNFILENAME_libgccjit_repro.c, where ELNFILENAME is the
+name of the problematic .eln file, either in the same directory where
+the .eln file is produced, or under your ~/.emacs.d/eln-cache (which
+one depends on how the native-compilation is invoked). It is also
+possible that the reproducer file's name will be something like
+subr--trampoline-XXXXXXX_FUNCTION_libgccjit_repro.c, where XXXXXXX is
+a long string of hex digits and FUNCTION is some function from the
+compiled .el file. Attach that reproducer C file to your bug report.
+
** Following longjmp call.
Recent versions of glibc (2.4+?) encrypt stored values for setjmp/longjmp which
@@ -875,15 +901,6 @@ It is also useful to look at the corrupted object or data structure in
a fresh Emacs session and compare its contents with a session that you
are debugging.
-** Debugging problems with non-ASCII characters
-
-If you experience problems which seem to be related to non-ASCII
-characters, such as \201 characters appearing in the buffer or in your
-files, set the variable byte-debug-flag to t. This causes Emacs to do
-some extra checks, such as look for broken relations between byte and
-character positions in buffers and strings; the resulting diagnostics
-might pinpoint the cause of the problem.
-
** Debugging the TTY (non-windowed) version
The most convenient method of debugging the character-terminal display
diff --git a/etc/DISTRIB b/etc/DISTRIB
index 610c347289e..3dd1bf3d98b 100644
--- a/etc/DISTRIB
+++ b/etc/DISTRIB
@@ -73,8 +73,7 @@ you can contribute.
Your donations will help to support the development of additional GNU
software. GNU/Linux systems (variants of GNU, based on the kernel
Linux) have millions of users, but there is still much to be done.
-For more information on GNU, see the file 'GNU' in this directory (see
-above).
+For more information on GNU, visit https://www.gnu.org/.
Richard M Stallman
Chief GNUisance, Founder of the FSF
diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS
index 8c9306b5cac..31ea3de620d 100644
--- a/etc/ERC-NEWS
+++ b/etc/ERC-NEWS
@@ -3,8 +3,181 @@ ERC NEWS -*- outline -*-
Copyright (C) 2006-2021 Free Software Foundation, Inc.
See the end of the file for license conditions.
-* For changes after ERC 5.3, see the main Emacs NEWS file
+Please send ERC bug reports to 'bug-gnu-emacs@gnu.org',
+and Cc the 'emacs-erc@gnu.org' mailing list as well.
+If possible, use 'M-x erc-bug' or 'M-x report-emacs-bug'.
+This file is about changes in ERC, the powerful, modular, and
+extensible IRC (Internet Relay Chat) client distributed with
+GNU Emacs since Emacs version 22.1.
+
+
+* Changes in ERC 5.4.1
+
+** No user-visible changes since ERC 5.4, but a few tweaks in some ERC
+file headers and the ERC manual in order to successfully build ERC for
+GNU ELPA. (See below for the news item of ERC now being distributed
+on GNU ELPA in addition to its continued inclusion in GNU Emacs core.)
+
+
+* Changes in ERC 5.4
+
+** Starting with Emacs 28.1 and ERC 5.4, ERC NEWS are added here again.
+After ERC 5.3, since November 2012, ERC's NEWS items were added in the
+main Emacs NEWS file, and users were referred to there. Now, starting
+with Emacs 28.1 and ERC 5.4, which mark ERC's release to GNU ELPA, ERC
+NEWS have been moved to this file again, so that we can include a NEWS
+file consisting only of ERC changes in ERC's package on GNU ELPA.
+
+The NEWS entries for ERC changes in Emacs 28.1 have been moved from
+the main Emacs NEWS file to here. For ERC NEWS entries corresponding
+to Emacs versions before 28, to avoid modifying the NEWS file for all
+of those releases, the ERC NEWS entries have only been copied below,
+and the NEWS.* files were left intact.
+
+** ERC is now available on GNU ELPA.
+Starting with ERC 5.4, in addition to being distributed with GNU Emacs
+itself, ERC is also included in GNU ELPA, allowing users to enjoy the
+improvements of newer ERC versions on older Emacs versions as well.
+
+ERC's package page on GNU ELPA: https://elpa.gnu.org/packages/erc.html
+
+** New option 'erc-rename-buffers'.
+
+** New faces 'erc-my-nick-prefix-face' and 'erc-nick-prefix-face'.
+
+** 'erc-format-@nick' displays all user modes instead of only op and voice.
+
+** The display of irc commands in the current buffer has been disabled.
+
+** 'erc-version' now follows the Emacs version.
+
+** ERC can now hide message types by network or channel.
+'erc-hide-list' will hide all messages of the specified type, while
+'erc-network-hide-list' and 'erc-channel-hide-list' will only hide the
+specified message types for the respective specified targets.
+
+** Reconnection is now asynchronous.
+
+** Nick completion is now case-insensitive again after inadvertently
+being made case-sensitive in Emacs 24.2.
+
+** New variable 'erc-default-port-tls' used to connect to TLS IRC
+servers.
+
+** New hook 'erc-insert-done-hook'.
+This hook is called after strings have been inserted into the buffer,
+and is free to alter point and window configurations, as it's not
+called from inside a 'save-excursion', as opposed to 'erc-insert-post-hook'.
+
+** 'erc-button-google-url' has been renamed to 'erc-button-search-url'
+and its value has been changed to Duck Duck Go.
+
+** 'erc-send-pre-hook' and 'erc-send-this' have been obsoleted.
+The user option to use instead to alter text to be sent is now
+'erc-pre-send-functions'.
+
+** Improve matching/highlighting of nicknames.
+Open and close parenthesis and apostrophe are not considered valid
+nick characters anymore, matching the given grammar in RFC 2812
+section 2.3.1. This enables correct matching and highlighting of
+nicks when they are surrounded by parentheses, like "(nick)", and when
+adjacent to an apostrophe, like "nick's".
+
+** Set 'erc-button-url-regexp' to 'browse-url-button-regexp'
+which better handles surrounding pair of parentheses.
+
+** New function 'erc-switch-to-buffer-other-window'
+which is like 'erc-switch-to-buffer', but opens the buffer in another
+window.
+
+** New function 'erc-track-switch-buffer-other-window'
+which is like 'erc-track-switch-buffer', but opens the buffer in
+another window.
+
+** NickServ passwords can now be retrieved from auth-source.
+The 'erc-use-auth-source-for-nickserv-password' user option enables
+querying auth-source for NickServ passwords. To enable this, add the
+following to your init file:
+
+ (setq erc-use-auth-source-for-nickserv-password t)
+
+** NickServ identification now prompts for password last.
+When 'erc-prompt-for-nickserv-password' is non-nil, the user used to
+be unconditionally prompted interactively for a password, regardless
+of the value of 'erc-nickserv-passwords', which was effectively
+ignored (same for the new
+'erc-use-auth-source-for-nickserv-password'). This limitation is now
+lifted, and the user is interactively prompted last, after the other
+identification methods have run.
+
+** The '/ignore' command will now ask for a timeout to stop ignoring the user.
+Allowed inputs are seconds or ISO8601-like periods like "1h" or "4h30m".
+
+** ERC now recognizes 'C-]' for italic text.
+Italic text is displayed in the new 'erc-italic-face'.
+
+** erc-match.el now supports 'message' highlight type (not including the nick).
+The 'erc-current-nick-highlight-type', 'erc-pal-highlight-type',
+'erc-fool-highlight-type', 'erc-keyword-highlight-type', and
+'erc-dangerous-host-highlight-type' user options now support a
+'message' type for highlighting the entire message but not the
+sender's nick.
+
+** erc-status-sidebar.el is now part of ERC.
+The 'erc-status-sidebar' package which provides a HexChat-like
+activity overview sidebar for joined IRC channels is now part of ERC.
+
+** erc-tls now supports specifying a TLS client certificate.
+The 'erc-tls' function has been updated to allow specifying a TLS
+client certificate for authentication, as an alternative to NickServ
+password-based authentication. This is referred to as "CertFP" (short
+for Certificate Fingerprint) by several IRC networks. See the Info
+node "(erc) Connecting" in the ERC manual for more details and
+examples on how to specify and use TLS client certificates with
+'erc-tls'.
+
+** Update IRC-related references to point to Libera.Chat.
+The Free Software Foundation and the GNU Project have moved their
+official IRC channels from the Freenode network to Libera.Chat.
+For the original announcement and the follow-up update, including
+more details, see:
+
+https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00005.html
+https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00007.html
+
+Given the relocation of GNU and FSF's official IRC channels, as well
+as #emacs and various other Emacs-themed channels (see the link below)
+to Libera.Chat, IRC-related references in the Emacs repository have
+now been updated to point to Libera.Chat.
+
+https://lists.gnu.org/archive/html/info-gnu-emacs/2021-06/msg00000.html
+
+** Add 'erc-track-select-mode-line-face' (obsoletes 'erc-track-find-face').
+The 'erc-track-find-face' function of the erc-track module has been
+declared obsolete and rewritten as 'erc-track-select-mode-line-face',
+with different expected arguments (the current and old faces are now
+separated) and clearer documentation.
+
+** Add '/opme' and '/deopme' convenience commands.
+The new '/opme' convenience command asks ChanServ to set the operator
+status for the current nick in the current channel, and '/deopme'
+unsets it.
+
+** Add '/wii' convenience command for whois with idle time.
+The new '/wii' convenience command calls the '/whois' command with the
+given nick as both arguments, which is useful for displaying the whois
+information for the nick along with idle time, even if the nick is on
+a different server than the one the current user is connected to.
+Using the given nick itself instead of the server it is connected to
+is not standardized, but is widely supported across IRC networks.
+
+** Add 'erc-bug' command for reporting ERC bugs.
+The new 'erc-bug' command prompts for a subject, and passes it on to
+'report-emacs-bug' along with the current ERC version, and adds the
+ERC mailing list in Cc.
+
+
* Changes in ERC 5.3
** New function `erc-tls' is to be used for connecting to a server via TLS.
@@ -249,6 +422,7 @@ message types are "333" and "353", respectively.
**** Turn this into the "xdcc" module for ERC, so that it can be more
easily enabled.
+
* Changes in ERC 5.2
** M-x erc RET now starts ERC.
@@ -528,6 +702,7 @@ not.
**** New function: `erc-toggle-timestamps'.
Toggles display of timestamps.
+
* Changes in ERC 5.1.4
** Make find-function and find-variable work in Emacs 22 for
@@ -551,6 +726,7 @@ is deactivated.
**** Fix some errors that occur when exiting Emacs without first
quitting open IRC servers.
+
* Changes in ERC 5.1.3
** Fix use of /quote command with no initial whitespace.
@@ -665,6 +841,7 @@ modules.
**** Don't complete the user's current nickname.
+
* Changes in ERC 5.1.2
** Fix compiler errors in erc-autojoin.el and erc-dcc.el.
@@ -701,6 +878,7 @@ A side effect of using this new method is that there will only be one
space before a right timestamp in any saved logs. If this is
unacceptable, set `erc-timestamp-use-align-to' to nil.
+
* Changes in ERC 5.1.1
** Fix a requirement on cl.el.
@@ -734,6 +912,7 @@ new `erc-timestamp-right-align-by-pixel' option to non-nil.
**** Since most of these changes are now merged into Emacs22, detect
whether we need these changes and install them only if necessary.
+
* Changes in ERC 5.1
** Improve XEmacs compatibility.
@@ -940,10 +1119,12 @@ the right margin.
**** Helps ERC work correctly in viper-mode.
+
* Changes in ERC 5.0.4
** Fix a problem with undo in channels.
+
* Changes in ERC 5.0.3
** Fix typo in the `ctcp-request-to' entry of the English catalog.
@@ -985,6 +1166,7 @@ indicator. Previously, there was an additional unnecessary space.
**** Fix an error that occurred when unchecked buffers existed when
invoking /QUIT.
+
* Changes in ERC 5.0.2
** If a channel key is required for a certain channel, ERC will prompt
@@ -1018,6 +1200,7 @@ choice anymore.
**** You can now save logs and truncate buffers from the menu-bar.
+
* Changes in ERC 5.0.1
** Narrowing in ERC buffers no longer causes formatting errors.
@@ -1032,6 +1215,7 @@ choice anymore.
This means that `erc-track-priority-faces-only', `erc-track-exclude',
and `erc-track-exclude-types' now work with server buffers.
+
* Changes in ERC 5.0
** Channel members are now stored as a hash-table.
@@ -1276,6 +1460,7 @@ in XEmacs.
mode-line where modified channels are shown (only works in GNU
Emacs versions above 21.3).
+
* Changes in ERC 4.0
** The module system has again changed a lot. You can now customize
@@ -1299,6 +1484,7 @@ in XEmacs.
openprojects to freenode. You may need to update your configuration
for a successful automatic nickserv identification.
+
* Changes in ERC 3.0.cvs.20030119
** New module erc-dcc:
@@ -1330,6 +1516,7 @@ Same applies to timestamps. You no longer need to (require
the rest should be automatic.
+----------------------------------------------------------------------
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
@@ -1344,3 +1531,10 @@ 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/>.
+
+
+Local variables:
+coding: utf-8
+mode: outline
+paragraph-separate: "[ ]*$"
+end:
diff --git a/etc/HELLO b/etc/HELLO
index 577c2828ded..8bd489fb401 100644
--- a/etc/HELLO
+++ b/etc/HELLO
@@ -38,7 +38,7 @@ Czech (čeština) Dobrý den
Danish (dansk) Hej / Goddag / Halløj
Dutch (Nederlands) Hallo / Dag
Efik /ˈɛfɪk/ Mɔkɔm
-Egyptian Hieroglyphs (𓂋𓐰𓏤𓈖𓆎𓅓𓏏𓐰𓊖) 𓅓𓊵𓐰𓐷𓏏𓊪𓐸, 𓇍𓇋𓂻𓍘𓇋
+Egyptian Hieroglyphs (𓂋𓏤𓈖𓆎𓅓‌𓏏𓊖) 𓅓𓊵𓏏𓊪, 𓇍𓇋𓂻𓍘𓇋
Emacs emacs --no-splash -f view-hello-file
Emoji 👋
English /ˈɪŋɡlɪʃ/ Hello
diff --git a/etc/MACHINES b/etc/MACHINES
index d8d0b86fb4d..d883f1abd60 100644
--- a/etc/MACHINES
+++ b/etc/MACHINES
@@ -103,6 +103,34 @@ the list at the end of this file.
./configure CC='gcc -m64' # GCC
./configure CC='cc -m64' # Oracle Developer Studio
+** Haiku
+
+ On 32-bit Haiku it is required that the newer GCC 8 be used, instead
+ of the legacy GCC 2 used by default. This can be achieved by
+ invoking configure inside a shell launched by the 'setarch' program
+ invoked as 'setarch x86'.
+
+ When building with packages discovered through pkg-config, such as
+ libpng, on a GCC 2/GCC 8 hybrid system, simply evaluating 'setarch
+ x86' is insufficient to ensure that all required libraries are found
+ at their correct locations. To avoid this problem, set the
+ environment variable 'PKG_CONFIG_PATH' to the GCC 8 pkg-config
+ directory at '/system/develop/lib/x86/pkgconfig/' before configuring
+ Emacs.
+
+ If GCC complains about not being able to resolve symbols such as
+ "BHandler::LockLooper", you are almost certainly experiencing this
+ problem.
+
+ Haiku running on non-x86 systems has not been tested. It is
+ anticipated that Haiku running on big-endian systems will experience
+ problems when Emacs is built with Haiku windowing support, but there
+ doesn't seem to be any reliable way to get Haiku running on a
+ big-endian system at present.
+
+ The earliest release of Haiku that will successfully compile Emacs
+ is R1/Beta2. For windowing support, R1/Beta3 or later is required.
+
* Obsolete platforms
diff --git a/etc/NEWS b/etc/NEWS
index b221f136241..e3665b918a3 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1,15 +1,15 @@
GNU Emacs NEWS -- history of user-visible changes.
-Copyright (C) 2017-2021 Free Software Foundation, Inc.
+Copyright (C) 2021 Free Software Foundation, Inc.
See the end of the file for license conditions.
Please send Emacs bug reports to 'bug-gnu-emacs@gnu.org'.
If possible, use 'M-x report-emacs-bug'.
-This file is about changes in Emacs version 28.
+This file is about changes in Emacs version 29.
See file HISTORY for a list of GNU Emacs versions and release dates.
-See files NEWS.27, NEWS.26, ..., NEWS.18, and NEWS.1-17 for changes
+See files NEWS.28, NEWS.27, ..., NEWS.18, and NEWS.1-17 for changes
in older Emacs versions.
You can narrow news to a specific version by calling 'view-emacs-news'
@@ -22,3839 +22,1169 @@ When you add a new item, use the appropriate mark if you are sure it
applies, and please also update docstrings as needed.
-* Installation Changes in Emacs 28.1
-
-** Emacs now optionally supports native compilation of Lisp files.
-To enable this, configure Emacs with the '--with-native-compilation' option.
-This requires the libgccjit library to be installed and functional,
-and also requires GCC and Binutils to be available when Lisp code is
-natively compiled. See the Info node "(elisp) Native Compilation" for
-more details.
-
----
-** Support for building with Motif has been removed.
-
-** The Cairo graphics library is now used by default if present.
-'--with-cairo' is now the default, if the appropriate development files
-are found by 'configure'. Note that building with Cairo means using
-Pango instead of libXFT for font support. Since Pango 1.44 has
-removed support for bitmapped fonts, this may require you to adjust
-your font settings.
-
-Note also that 'FontBackend' settings in ".Xdefaults" or
-".Xresources", or 'font-backend' frame parameter settings in your init
-files, may need to be adjusted, as 'xft' is no longer a valid backend
-when using Cairo. Use 'ftcrhb' if your Emacs was built with HarfBuzz
-text shaping support, and 'ftcr' otherwise. You can determine this by
-checking 'system-configuration-features'. The 'ftcr' backend will
-still be available when HarfBuzz is supported, but will not be used by
-default. We strongly recommend building with HarBuzz support. 'x' is
-still a valid backend.
-
----
-** Building without double buffering support.
-'configure --with-xdbe=no' can now be used to disable double buffering
-at build time.
-
----
-** 'configure' now warns about building with libXft support.
-libXft is unmaintained, and causes a number of problems with modern
-fonts including but not limited to crashes; support for it may be
-removed in a future version of Emacs. Please consider using
-Cairo + HarfBuzz instead.
-
----
-** 'configure' now warns about not using HarfBuzz if using Cairo.
-We want to encourage people to use the most modern font features
-available, and this is the Cairo graphics library + HarfBuzz for font
-shaping, so 'configure' now recommends that combination.
-
----
-** The ftx font backend driver has been removed.
-It was declared obsolete in Emacs 27.1.
-
----
-** The configure option '--without-makeinfo' has been removed.
-This was only ever relevant when building from a repository checkout.
-This now requires makeinfo, which is part of the texinfo package.
-
----
-** Support for building with '-fcheck-pointer-bounds' has been removed.
-GCC has withdrawn the '-fcheck-pointer-bounds' option and support for
-its implementation has been removed from the Linux kernel.
-
----
-** Emacs no longer supports old OpenBSD systems.
-OpenBSD 5.3 and older releases are no longer supported, as they lack
-proper pty support that Emacs needs.
-
-
-* Startup Changes in Emacs 28.1
-
----
-** File names given on the command line will now be pushed onto
-'file-name-history'.
-
----
-** In GTK builds, Emacs now supports startup notification.
-This means that Emacs won't steal keyboard focus upon startup
-(when started via the Desktop) if the user is typing into another
-application.
-
-** Emacs can support 24-bit color TTY without terminfo database.
-If your text-mode terminal supports 24-bit true color, but your system
-lacks the terminfo database, you can instruct Emacs to support 24-bit
-true color by setting 'COLORTERM=truecolor' in the environment. This is
-useful on systems such as FreeBSD which ships only with "etc/termcap".
-
-** Emacs now supports loading a Secure Computing filter.
-This is supported only on capable GNU/Linux systems. To activate,
-invoke Emacs with the '--seccomp=FILE' command-line option. FILE must
-name a binary file containing an array of 'struct sock_filter'
-structures. Emacs will then install that list of Secure Computing
-filters into its own process early during the startup process. You
-can use this functionality to put an Emacs process in a sandbox to
-avoid security issues when executing untrusted code. See the manual
-page for 'seccomp' system call, for details about Secure Computing
-filters.
-
-** Setting 'fill-column' to nil is obsolete.
-This undocumented use of 'fill-column' is now obsolete. To disable
-auto filling, turn off 'auto-fill-mode' instead.
-
-For instance, you could add something like the following to your init
-file:
-
- (add-hook 'foo-mode-hook (lambda () (auto-fill-mode -1))
-
-
-* Changes in Emacs 28.1
-
-** 'blink-cursor-mode' is now enabled by default regardless of the UI.
-It used to be enabled when Emacs is started in GUI mode but not when started
-in text mode. The cursor still only actually blinks in GUI frames.
-
----
-** 'auto-composition-mode' can now be selectively disabled on some TTYs.
-Some text-mode terminals produce display glitches trying to compose
-characters. The 'auto-composition-mode' can now have a string value
-that names a terminal type; if the value returned by the 'tty-type'
-function compares equal with that string, automatic composition will
-be disabled in windows shown on that terminal. The Linux terminal
-sets this up by default.
+* Installation Changes in Emacs 29.1
+++
-** Etags now supports the Mercury programming language.
-See https://mercurylang.org.
+** Emacs can be built with built-in support for accessing SQLite databases.
+This uses the popular sqlite3 library, and can be disabled by using
+the '--without-sqlite3' option to the 'configure' script.
-+++
-** Etags command line option '--declarations' now has Mercury-specific behavior.
-All Mercury declarations are tagged by default. However, for
-compatibility with 'etags' support for Prolog, predicates and
-functions appearing first in clauses will also be tagged if 'etags' is
-invoked with the '--declarations' command-line option.
-
-+++
-** New command 'font-lock-update', bound to 'C-x x f'.
-This command updates the syntax highlighting in this buffer.
+** Emacs has been ported to the Haiku operating system.
+The configuration process should automatically detect and build for
+Haiku. There is also an optional window-system port to Haiku, which
+can be enabled by configuring Emacs with the option '--with-be-app',
+which will require the Haiku Application Kit development headers and a
+C++ compiler to be present on your system. If Emacs is not built with
+the option '--with-be-app', the resulting Emacs will only run in
+text-mode terminals.
+++
-** A new standard face 'font-lock-doc-markup-face'.
-Intended for documentation mark-up syntax and tags inside text that
-uses 'font-lock-doc-face', with which it should harmonise. It would
-typically be used in structured documentation comments in program
-source code by language-specific modes, for mark-up conventions like
-Haddock, Javadoc or Doxygen. By default this face inherits from
-'font-lock-constant-face'.
-
-** The new NonGNU ELPA archive is enabled by default alongside GNU ELPA.
-
-+++
-** New command 'recenter-other-window', bound to 'S-M-C-l'.
-Like 'recenter-top-bottom' acting in the other window.
-
-** Minibuffer scrolling is now conservative by default.
-This is controlled by the new variable 'scroll-minibuffer-conservatively'.
-
-In addition, there is a new variable
-'redisplay-adhoc-scroll-in-resize-mini-windows' to disable the
-ad-hoc auto-scrolling when resizing minibuffer windows. It has been
-found that its heuristic can be counter productive in some corner
-cases, tho the cure may be worse than the disease. This said, the
-effect should be negligible in the vast majority of cases anyway.
-
-+++
-** Improved handling of minibuffers on switching frames.
-By default, when you switch to another frame, an active minibuffer now
-moves to the newly selected frame. Nevertheless, the effect of what
-you type in the minibuffer happens in the frame where the minibuffer
-was first activated. An alternative behavior is available by
-customizing 'minibuffer-follows-selected-frame' to nil. Here, the
-minibuffer stays in the frame where you first opened it, and you must
-switch back to this frame to continue or abort its command. The old
-behavior, which mixed these two, can be approximated by customizing
-'minibuffer-follows-selected-frame' to a value which is neither nil
-nor t.
-
-+++
-** New user option 'read-minibuffer-restore-windows'.
-When customized to nil, it uses 'minibuffer-restore-windows' in
-'minibuffer-exit-hook' to remove only the window showing the
-"*Completions*" buffer.
-
-+++
-** New system for displaying documentation for groups of functions.
-This can either be used by saying 'M-x shortdoc-display-group' and
-choosing a group, or clicking a button in the "*Help*" buffers when
-looking at the doc string of a function that belongs to one of these
-groups.
+*** Cairo drawing support has been enabled for Haiku builds.
+To enable Cairo support, ensure that the Cairo and FreeType
+development files are present on your system, and configure Emacs with
+'--with-be-cairo'.
---
-** Improved "find definition" feature of "*Help*" buffers.
-Now clicking on the link to find the definition of functions generated
-by 'cl-defstruct', or variables generated by 'define-derived-mode',
-for example, will go to the exact place where they are defined.
+*** Double buffering is now enabled on the Haiku operating system.
+Unlike X, there is no compile-time option to enable or disable
+double-buffering. If you wish to disable double-buffering, change the
+frame parameter 'inhibit-double-buffering' instead.
-** New variable 'redisplay-skip-initial-frame' to enable batch redisplay tests.
-Setting it to nil forces the redisplay to do its job even in the
-initial frame used in batch mode.
+** Emacs now installs the ".pdmp" file using a unique fingerprint in the name.
+The file is typically installed using a file name akin to
+"...dir/libexec/emacs/29.1/x86_64-pc-linux-gnu/emacs-<fingerprint>.pdmp".
+If a constant file name is required, the file can be renamed to
+"emacs.pdmp", and Emacs will find it during startup anyway.
----
-** Support for the 'strike-through' face attribute on TTY frames.
-If your terminal's termcap or terminfo database entry has the 'smxx'
-capability defined, Emacs will now emit the prescribed escape
-sequences necessary to render faces with the 'strike-through'
-attribute on TTY frames.
-
-+++
-** Emacs now defaults to UTF-8 instead of ISO-8859-1.
-This is only for the default, where the user has set no 'LANG' (or
-similar) variable or environment. This change should lead to no
-user-visible changes for normal usage.
+** Emacs now supports use of XInput 2 for input events.
+If your X server has support and you have the XInput 2 development headers
+installed, you can configure Emacs with the option '--with-xinput2' to enable
+this support.
-+++
-** New variables that hold default buffer names for shell output.
-The new constants 'shell-command-buffer-name' and
-'shell-command-buffer-name-async' store the default buffer names
-for the output of, respectively, synchronous and async shell
-commands.
-
-** Support for '(box . SIZE)' 'cursor-type'.
-By default, 'box' cursor always has a filled box shape. But if you
-specify 'cursor-type' to be '(box . SIZE)', the cursor becomes a hollow
-box if the point is on an image larger than SIZE pixels in any
-dimension.
-
-+++
-** New user option 'word-wrap-by-category'.
-When word-wrap is enabled, and this option is non-nil, that allows
-Emacs to break lines after more characters than just whitespace
-characters. In particular, this significantly improves word-wrapping
-for CJK text mixed with Latin text.
-
----
-** Rudimentary support for the 'st' terminal emulator.
-Emacs now supports 256 color display on the 'st' terminal emulator.
-
----
-** Mouse wheel scrolling now works on more parts of frame's display.
-When using 'mwheel-mode', the mouse wheel will now scroll also when
-the mouse cursor is on the scroll bars, fringes, margins, header line,
-and mode line. ('mwheel-mode' is enabled by default on most graphical
-displays.)
-
----
-** Mouse wheel scrolling now defaults to one line at a time.
-
-+++
-** Mouse wheel scrolling with Shift modifier now scrolls horizontally.
-This works in text buffers and over images. Typing a numeric prefix arg
-(e.g. 'M-5') before starting horizontal scrolling changes its step value.
-The value is saved in the user option 'mouse-wheel-scroll-amount-horizontal'.
-
----
-** New choice 'permanent' for 'shift-select-mode'.
-When the mark was activated by shifted motion keys,
-non-shifted motion keys don't deactivate the mark
-after customizing 'shift-select-mode' to 'permanent'.
-
----
-** The default value of 'frame-title-format' and 'icon-title-format' has changed.
-These variables are used to display the title bar of visible frames
-and the title bar of an iconified frame. They now show the name of
-the current buffer and the text "GNU Emacs" instead of the value of
-'invocation-name'. To get the old behavior back, add the following to
-your init file:
-
- (setq frame-title-format '(multiple-frames "%b"
- ("" invocation-name "@" system-name)))
-
-+++
-** 'nobreak-char-display' now also affects all non-ASCII space characters.
-Previously, this was limited only to NO-BREAK-SPACE and hyphen
-characters. Now it also covers the rest of the non-ASCII Unicode
-space characters.
-
----
-** Prefer "chat.freenode.net" to "irc.freenode.net".
-"chat.freenode.net" has been the preferred address for connecting to the
-freenode IRC network for years now. Occurrences of "irc.freenode.net"
-have been replaced with "chat.freenode.net" throughout Emacs.
-
-+++
-** New functions 'null-device' and 'path-separator'.
-These functions return the connection local value of the respective
-variables. This can be used for remote hosts.
-
-** Emacs now prints a backtrace when signaling an error in batch mode.
-This makes debugging Emacs Lisp scripts run in batch mode easier. To
-get back the old behavior, set the new variable
-'backtrace-on-error-noninteractive' to a nil value.
-
-** 'redisplay-skip-fontification-on-input' helps Emacs keep up with fast input.
-This is another attempt to solve the problem of handling high key repeat rate
-and other "slow scrolling" situations. It is hoped it behaves better
-than 'fast-but-imprecise-scrolling' and 'jit-lock-defer-time'.
-It is not enabled by default.
-
-+++
-** Modifiers now go outside angle brackets in pretty-printed key bindings.
-For example, 'RET' with Control and Meta modifiers is now shown as
-'C-M-<return>' instead of '<C-M-return>'. Either variant can be used
-as input; functions such as 'kbd' and 'read-kbd-macro' accept both
-styles as equivalent (they have done so for a long time).
-
-+++
-** New user option 'lazy-highlight-no-delay-length'.
-Lazy highlighting of matches in Isearch now starts immediately if the
-search string is at least this long. 'lazy-highlight-initial-delay'
-still applies for shorter search strings, which avoids flicker in the
-search buffer due to too many matches being highlighted.
-
-+++
-** A new keymap for buffer actions has been added.
-The 'C-x x' keymap now holds keystrokes for various buffer-oriented
-commands. The new keystrokes are 'C-x x g' ('revert-buffer-quick'),
-'C-x x r' ('rename-buffer'), 'C-x x u' ('rename-uniquely'), 'C-x x n'
-('clone-buffer'), 'C-x x i' ('insert-buffer'), 'C-x x t'
-('toggle-truncate-lines') and 'C-x x f' ('font-lock-update').
-
----
-** Commands 'set-frame-width' and 'set-frame-height' can now get their
-input using the minibuffer.
-
----
-** New help window when Emacs prompts before opening a large file.
-Commands like 'find-file' or 'visit-tags-table' ask to visit a file
-normally or literally when the file is larger than a certain size (by
-default, 9.5 MiB). Press '?' or 'C-h' in that prompt to read more
-about the different options to visit a file, how you can disable the
-prompt, and how you can tweak the file size threshold.
-
-+++
-** New user option 'query-about-changed-file'.
-If non-nil (the default), users are prompted as before when
-re-visiting a file that has changed externally after it was visited
-the first time. If nil, the user is not prompted, but instead the
-buffer is opened with its contents before the change, and the user is
-given instructions how to revert the buffer.
-
-+++
-** Improved support for terminal emulators that encode the Meta flag.
-Some terminal emulators set the 8th bit of Meta characters, and then
-encode the resulting character code as if it were non-ASCII character
-above codepoint 127. Previously, the only way of using these in Emacs
-was to set up the terminal emulator to use the 'ESC' characters to send
-Meta characters to Emacs, e.g., send "ESC x" when the user types
-'M-x'. You can now avoid the need for this setup of such terminal
-emulators by using the new input-meta-mode with the special value
-'encoded' with these terminal emulators.
-
-+++
-** New frame parameter 'drag-with-tab-line'.
-This parameter, similar to 'drag-with-header-line', allows moving frames
-by dragging the tab lines of their topmost windows with the mouse.
+The named feature 'xinput2' can be used to test for the presence of
+XInput 2 support from Lisp programs.
-* Editing Changes in Emacs 28.1
-
-** New value 'save-some-buffers-root' of 'save-some-buffers-default-predicate'.
-It allows to ask about saving only files under the project root
-or in subdirectories of the directory that was default during
-command invocation.
-
----
-** Dragging a file to Emacs will now also push the name of the file
-onto 'file-name-history'.
+* Startup Changes in Emacs 29.1
+++
-** A prefix arg now causes 'delete-other-frames' to only iconify frames.
-
-** Menus
-
-+++
-*** New minor mode 'context-menu-mode' for context menus popped by 'mouse-3'.
-When this mode is enabled, clicking 'down-mouse-3' anywhere in the buffer
-pops up a menu whose contents depends on surrounding context near the
-mouse click. You can change the order of the default sub-menus in the
-context menu by customizing the user option 'context-menu-functions'.
-
-+++
-*** The "Edit => Clear" menu item now obeys a rectangular region.
-
-+++
-** New command 'execute-extended-command-for-buffer'.
-This new command, bound to 'M-S-x', works like
-'execute-extended-command', but limits the set of commands to the
-commands that have been determined to be particularly useful with the
-current mode.
+** Emacs now has a '--fingerprint' option.
+This will output a string identifying the current Emacs build.
+++
-** New user option 'read-extended-command-predicate'.
-This user option controls how 'M-x' performs completion of commands when
-you type 'TAB'. By default, any command that matches what you have
-typed is considered a completion candidate, but you can customize this
-option to exclude commands that are not applicable to the current
-buffer's major and minor modes, and respect the command's completion
-predicate (if any).
+** New hook 'after-pdump-load-hook'.
+This is run at the end of the Emacs startup process, and it meant to
+be used to reinitialize structures that would normally be done at load
+time.
----
-** 'eval-expression' now no longer signals an error on incomplete expressions.
-Previously, typing 'M-: ( RET' would result in Emacs saying "End of
-file during parsing" and dropping out of the minibuffer. The user
-would have to type 'M-: M-p' to edit and redo the expression. Now
-Emacs will echo the message and allow the user to continue editing.
-
-+++
-** 'eval-last-sexp' now handles 'defvar'/'defcustom'/'defface' specially.
-This command would previously not redefine values defined by these
-forms, but this command has now been changed to work more like
-'eval-defun', and reset the values as specified.
-
-+++
-** Standalone 'M-y' allows interactive selection from previous kills.
-'M-y' can now be typed after a command that is not a yank command.
-When invoked like that, it prompts in the minibuffer for one of the
-previous kills, offering completion and minibuffer-history navigation
-through previous kills recorded in the kill ring. A similar feature
-in Isearch can be invoked if you bind 'C-s M-y' to the command
-'isearch-yank-pop'. When the user option 'yank-from-kill-ring-rotate'
-is nil the kill ring is not rotated after 'yank-from-kill-ring'.
+
+* Incompatible changes in Emacs 29.1
---
-** New user options 'copy-region-blink-delay' and 'delete-pair-blink-delay'.
-'copy-region-blink-delay' specifies a delay to indicate the region
-copied by 'kill-ring-save'. 'delete-pair-blink-delay' specifies
-a delay to show a paired character to delete.
-
-+++
-** New command 'undo-redo'.
-It undoes previous undo commands, but doesn't record itself as an
-undoable command.
-
-+++
-** 'read-number' now has its own history variable.
-Additionally, the function now accepts a HIST argument which can be
-used to specify a custom history variable.
-
-+++
-** Input history for 'goto-line' can now be made local to every buffer.
-In any event, line numbers used with 'goto-line' are kept in their own
-history list. This should help make faster the process of finding
-line numbers that were previously jumped to. By default, all buffers
-share a single history list. To make every buffer have its own
-history list, customize the user option 'goto-line-history-local'.
-
-+++
-** New command 'goto-line-relative' to use in a narrowed buffer.
-It moves point to the line relative to the accessible portion of the
-narrowed buffer. 'M-g M-g' in Info is rebound to this command.
-When 'widen-automatically' is non-nil, 'goto-line' widens the narrowed
-buffer to be able to move point to the inaccessible portion.
-'goto-line-relative' is bound to 'C-x n g'.
-
-+++
-** When called interactively, 'goto-char' now offers the number at
-point as default.
-
-+++
-** When 'suggest-key-bindings' is non-nil, the completion list of 'M-x'
-shows equivalent key bindings for all commands that have them.
-
-** Autosaving via 'auto-save-visited-mode' can now be inhibited by
-setting the variable 'auto-save-visited-mode' buffer-locally to nil.
-
-** New commands to describe buttons and widgets have been added.
-'widget-describe' (on a widget) will pop up a help buffer and give a
-description of the properties. Likewise 'button-describe' does the
-same for a button.
-
-** Obsolete aliases are no longer hidden from command completion.
-Completion of command names now considers obsolete aliases as
-candidates, if they were marked obsolete in the current major version
-of Emacs. Invoking a command via an obsolete alias now mentions the
-obsolescence fact and shows the new name of the command.
-
-+++
-** New command 'revert-buffer-with-fine-grain'.
-Revert a buffer trying to be as non-destructive as possible,
-preserving markers, properties and overlays. The new variable
-'revert-buffer-with-fine-grain-max-seconds' specifies the maximum
-number of seconds that 'revert-buffer-with-fine-grain' should spend
-trying to be non-destructive.
-
-+++
-** New command 'memory-report'.
-This command opens a new buffer called "*Memory Report*" and gives a
-summary of where Emacs is using memory currently.
-
-+++
-** New user option 'isearch-repeat-on-direction-change'.
-When this option is set, direction changes in Isearch move to another
-search match, if there is one, instead of moving point to the other
-end of the current match.
-
-** Outline
-
-+++
-*** New commands to cycle heading visibility.
-Typing 'TAB' on a heading line cycles the current section between
-"hide all", "subheadings", and "show all" states. Typing 'S-TAB'
-anywhere in the buffer cycles the whole buffer between "only top-level
-headings", "all headings and subheadings", and "show all" states.
-
-+++
-*** New user option 'outline-minor-mode-cycle'.
-This user option customizes 'outline-minor-mode', with the difference
-that 'TAB' and 'S-TAB' on heading lines cycle heading visibility.
-Typing 'TAB' on a heading line cycles the current section between
-"hide all", "subheadings", and "show all" states. Typing 'S-TAB' on a
-heading line cycles the whole buffer between "only top-level
-headings", "all headings and subheadings", and "show all" states.
+** 'C-x 8 .' has been moved to 'C-x 8 . .'.
+This is to open up the 'C-x 8 .' map to bind further characters there.
---
-*** New user option 'outline-minor-mode-highlight'.
-This user option customizes 'outline-minor-mode'. It puts
-highlighting on heading lines using standard outline faces. This
-works well only when there are no conflicts with faces used by the
-major mode.
+** The mode line now uses a proportional font by default.
+To get the old monospaced mode line back, customize the
+'mode-line-active' and 'mode-line-inactive' faces not to inherit from
+the 'variable-pitch' face, or add this to your "~/.emacs":
-+++
-** New commands 'copy-matching-lines' and 'kill-matching-lines'.
-These commands are similar to the command 'flush-lines',
-but add the matching lines to the kill ring as a single string,
-including the newlines that separate the lines.
+ (set-face-attribute 'mode-line-active nil :inherit 'mode-line)
+ (set-face-attribute 'mode-line-inactive nil :inherit 'mode-line)
-* Changes in Specialized Modes and Packages in Emacs 28.1
-
-** Completion List Mode
-New key bindings have been added: 'n' and 'p' to navigate completions,
-and 'M-g M-c' to switch to the minibuffer, and you can also switch back
-to the completion list buffer with 'M-g M-c'.
+* Changes in Emacs 29.1
-** Benchmark
-*** New function 'benchmark-call' to measure the execution time of a function.
-Additionally, the number of repetitions can be expressed as a minimal duration
-in seconds.
+** New command 'sqlite-mode-open-file' for examining an sqlite3 file.
+This uses the new 'sqlite-mode' which allows listing the tables in a
+DB file, and examining and modifying the columns and the contents of
+those tables.
-** Macroexp
---
-*** New function 'macroexp-file-name' to know the name of the current file.
----
-*** New function 'macroexp-compiling-p' to know if we're compiling.
----
-*** New function 'macroexp-warn-and-return' to help emit warnings.
-This used to be named 'macroexp--warn-and-return' and has proved useful
-and well-behaved enough to lose the "internal" marker.
-
-** Bindat
-
-+++
-*** New 'Bindat type expression' description language.
-This new system is provided by the new macro 'bindat-type' and
-obsoletes the old data layout specifications. It supports
-arbitrary-size integers, recursive types, and more. See the Info node
-"(elisp) Byte Packing" in the ELisp manual for more details.
-
-** pcase
-
-+++
-*** The 'or' pattern now binds the union of the vars of its sub-patterns.
-If a variable is not bound by the subpattern that matched, it gets bound
-to nil. This was already sometimes the case, but it is now guaranteed.
+** 'write-file' will now copy some file mode bits.
+If the current buffer is visiting a file that is executable, the
+'C-x C-w' command will now make the new file executable, too.
+++
-*** The 'pred' pattern can now take the form '(pred (not FUN))'.
-This is like '(pred (lambda (x) (not (FUN x))))' but results
-in better code.
-
----
-*** New function 'pcase-compile-patterns' to write other macros.
-
-*** Added 'cl-type' pattern.
-The new 'cl-type' pattern compares types using 'cl-typep', which allows
-comparing simple types like '(cl-type integer)', as well as forms like
-'(cl-type (integer 0 10))'.
-
-*** New macro 'pcase-setq'
-This macro is the 'setq' equivalent of 'pcase-let', which allows for
-destructuring patterns in a 'setq' form.
+** New user option 'process-error-pause-time'.
+This determines how long to pause Emacs after a process
+filter/sentinel error has been handled.
+++
-** profiler.el
-The results displayed by 'profiler-report' now have the usage figures
-at the left hand side followed by the function name. This is intended
-to make better use of the horizontal space, in particular eliminating
-the truncation of function names. There is no way to get the former
-layout back.
-
-** Loading dunnet.el in batch mode doesn't start the game any more.
-Instead you need to do "emacs -f dun-batch" to start the game in
-batch mode.
-
-** Emacs Server
+** New face 'variable-pitch-text'.
+This face is like 'variable-pitch' (from which it inherits), but is
+slightly larger, which should help with the visual size differences
+between the default, non-proportional font and proportional fonts when
+mixed.
+++
-*** New user option 'server-client-instructions'.
-When emacsclient connects, Emacs will (by default) output a message
-about how to exit the client frame. If 'server-client-instructions'
-is set to nil, this message is inhibited.
+** New face 'mode-line-active'.
+This inherits from the 'mode-line' face, but is the face actually used
+on the mode lines (along with 'mode-line-inactive').
+++
-*** New command 'server-edit-abort'.
-This command (not bound to any key by default) can be used to abort
-an edit instead of marking it as "Done" (which the 'C-x #' command
-does). The 'emacsclient' program exits with an abnormal status as
-result of this command.
+** 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 desktop integration for connecting to the server.
-If your operating system’s desktop environment is
-freedesktop.org-compatible (which is true of most GNU/Linux and other
-recent Unix-like GUIs), you may use the new "Emacs (Client)" desktop
-menu entry to open files in an existing Emacs instance rather than
-starting a new one. The daemon starts if not already running.
-
-** Perl mode
+** New X resource: "borderThickness".
+This controls the thickness of the external borders of the menu bars
+and pop-up menus.
---
-*** New face 'perl-non-scalar-variable'.
-This is used to fontify non-scalar variables.
-
-** Python mode
+** New minor mode 'pixel-scroll-precision-mode'.
+When enabled, and if your mouse supports it, you can scroll the
+display up or down at pixel resolution, according to what your mouse
+wheel reports. Unlike 'pixel-scroll-mode', this mode scrolls the
+display pixel-by-pixel, as opposed to only animating line-by-line
+scrolls.
----
-*** New user option 'python-forward-sexp-function'.
-This allows the user to easier customize whether to use block-based
-navigation or not.
+** Terminal Emacs
---
-*** 'python-shell-interpreter' now defaults to python3 on systems with python3.
+*** Emacs will now use 24-bit colors on terminals that support "Tc" capability.
+This is in addition to previously-supported ways of discovering 24-bit
+color support: either via the "RGB" or "setf24" capabilities, or if
+the 'COLORTERM' environment variable is set to the value "truecolor".
----
-*** 'C-c C-r' can now be used on arbitrary regions.
-The command previously extended the start of the region to the start
-of the line, but will now actually send the marked region, as
-documented.
-
-** Ruby mode
-
----
-*** 'ruby-use-smie' is declared obsolete.
-SMIE is now always enabled and 'ruby-use-smie' only controls whether
-indentation is done using SMIE or with the old ad-hoc code.
-
-** Icomplete
-
----
-*** New user option 'icomplete-matches-format'.
-This allows controlling the current/total number of matches for the
-prompt prefix.
+** ERT
+++
-*** New minor modes 'icomplete-vertical-mode' and 'fido-vertical-mode'
-These modes modify Icomplete ('M-x icomplete-mode') and Fido ('M-x
-fido-mode'), to display completions candidates vertically instead of
-horizontally. In Icomplete, completions are rotated and selection
-kept at the top. In Fido, completions scroll like a typical dropdown
-widget. Both these new minor modes will first turn on their
-non-vertical counterparts first, if they are not on already.
-
----
-*** Default value of 'icomplete-compute-delay' has been changed to 0.15 s.
+*** New ERT variables 'ert-batch-print-length' and 'ert-batch-print-level'.
+These variables will override 'print-length' and 'print-level' when
+printing Lisp values in ERT batch test results.
---
-*** Default value of 'icomplete-max-delay-chars' has been changed to 2.
-
----
-*** Reduced blinking while completing the next completions set.
-Icomplete doesn't hide the hint with the previously computed
-completions anymore when compute delay is in effect, or the previous
-computation has been aborted by input. Instead it shows the previous
-completions until the new ones are ready.
-
----
-** Specific warnings can now be disabled from the warning buffer.
-When a warning is displayed to the user, the resulting buffer now has
-buttons which allow making permanent changes to the treatment of that
-warning. Automatic showing of the warning can be disabled (although
-it is still logged to the "*Messages*" buffer), or the warning can be
-disabled entirely.
-
-** mspool.el
-
----
-*** Autoload the main entry point 'mspool-show'.
-
-** Windmove
+*** Redefining an ERT test in batch mode now signals an error.
+Executing 'ert-deftest' with the same name as an existing test causes
+the previous definition to be discarded, which was probably not
+intended when this occurs in batch mode. To remedy the error, rename
+tests so that they all have unique names.
+++
-*** New user options to customize windmove keybindings.
-These options include 'windmove-default-keybindings',
-'windmove-display-default-keybindings',
-'windmove-delete-default-keybindings',
-'windmove-swap-states-default-keybindings'.
+*** ERT can generate JUnit test reports.
+When environment variable 'EMACS_TEST_JUNIT_REPORT' is set, ERT
+generates a JUnit test report under this file name. This is useful
+for Emacs integration into CI/CD test environments.
-** Windows
+** Emoji
+++
-*** New user option 'delete-window-choose-selected'.
-This allows to choose a frame's selected window after deleting the
-previously selected one.
+*** Emacs now has several new methods for inserting Emojis.
+The Emoji commands are under the new 'C-x 8 e' prefix.
+++
-*** New argument NO-OTHER for some window functions.
-'get-lru-window', ‘get-mru-window’ and 'get-largest-window' now accept a
-new optional argument NO-OTHER which, if non-nil, avoids returning a
-window whose 'no-other-window' parameter is non-nil.
+*** New command 'emoji-insert' (bound to 'C-x 8 e e' and 'C-x 8 e i').
+This command guides you through various Emoji categories and
+combinations in a graphical menu system.
+++
-*** New 'display-buffer' function 'display-buffer-use-least-recent-window'.
-This is like 'display-buffer-use-some-window', but won't reuse the
-current window, and when called repeatedly will try not to reuse a
-previously selected window.
-
-*** New function 'window-bump-use-time'.
-This updates the use time of a window.
-
-*** The key prefix 'C-x 4 1' displays next command buffer in the same window.
-It's bound to the command 'same-window-prefix' that requests the buffer
-of the next command to be displayed in the same window.
-
-*** The key prefix 'C-x 4 4' displays next command buffer in a new window.
-It's bound to the command 'other-window-prefix' that requests the buffer
-of the next command to be displayed in a new window.
-
-** Frames
+*** New command 'emoji-search' (bound to 'C-x 8 e s').
+This command lets you search for Emojis based on names.
+++
-*** The key prefix 'C-x 5 5' displays next command buffer in a new frame.
-It's bound to the command 'other-frame-prefix' that requests the buffer
-of the next command to be displayed in a new frame.
-
-** Tab Bars
-
-*** The key prefix 'C-x t t' displays next command buffer in a new tab.
-It's bound to the command 'other-tab-prefix' that requests the buffer
-of the next command to be displayed in a new tab.
-
-+++
-*** New command 'C-x t C-r' to open file read-only in other tab.
-
----
-*** The tab bar is frame-local when 'tab-bar-show' is a number.
-Show/hide the tab bar independently for each frame, according to the
-value of 'tab-bar-show'.
-
----
-*** New command 'toggle-frame-tab-bar'.
-It can be used to enable/disable the tab bar individually on each frame
-independently from the value of 'tab-bar-mode' and 'tab-bar-show'.
-
----
-*** New user option 'tab-bar-format' defines a list of tab bar items.
-When it contains 'tab-bar-format-global' (possibly appended after
-'tab-bar-format-align-right'), then after enabling 'display-time-mode'
-(or any other mode that uses 'global-mode-string') it displays time
-aligned to the right on the tab bar instead of the mode line.
-When 'tab-bar-format-tabs' is replaced with 'tab-bar-format-tabs-groups',
-then the tab bar displays tab groups.
-
----
-*** 'Mod-9' bound to 'tab-last' now switches to the last tab.
-It also supports a negative argument.
-
----
-*** New command 'tab-duplicate' bound to 'C-x t n'.
+*** New command 'emoji-list' (bound to 'C-x 8 e l').
+This command lists all Emojis (categorized by themes) in a special
+buffer and lets you choose one of them.
---
-*** 'C-x t N' creates a new tab at the specified absolute position.
-It also supports a negative argument.
-
----
-*** 'C-x t M' moves the current tab to the specified absolute position.
-It also supports a negative argument.
-
----
-*** 'C-x t G' assigns a group name to the tab.
-'tab-close-group' can close all tabs that belong to the selected group.
-The user option 'tab-bar-new-tab-group' defines the default group of a
-new tab. After customizing 'tab-bar-tab-post-change-group-functions'
-to 'tab-bar-move-tab-to-group', changing the tab group will also move it
-closer to other tabs in the same group.
-
----
-*** New user option 'tab-bar-tab-name-format-function'.
-
----
-*** New user option 'tab-line-tab-name-format-function'.
-
----
-*** The tabs in the tab line can now be scrolled using horizontal scroll.
-If your mouse or trackpad supports it, you can now scroll tabs when
-the mouse pointer is in the tab line by scrolling left or right.
-
----
-*** New tab-line faces and options.
-The face 'tab-line-tab-special' is used for tabs whose buffers are
-special, i.e. not file-backed. The face
-'tab-line-tab-inactive-alternate' is used to display inactive tabs
-with an alternating background color, making them easier to
-distinguish between, especially if the face 'tab-line-tab' is
-configured to not display with a box; this alternate face is only
-applied when the option 'tab-line-tab-face-functions' is
-so-configured. That option may also be used to customize tab-line
-faces in other ways.
-
-** Occur mode
-
-*** New bindings in occur-mode, 'next-error-no-select' bound to 'n' and
-'previous-error-no-select' bound to 'p'.
-
-*** The new command 'recenter-current-error', bound to 'l' in Occur or
-compilation buffers, recenters the current displayed occurrence/error.
-
-*** Matches in target buffers are now highlighted as in 'compilation-mode'.
-The method of highlighting is specified by the user options
-'next-error-highlight' and 'next-error-highlight-no-select'.
-
----
-*** A fringe arrow in the "*Occur*" buffer indicates the selected match.
-
----
-*** Occur mode may use a different type for 'occur-target' property values.
-The value was previously always a marker set to the start of the first
-match on the line but can now also be a list of '(BEGIN . END)' pairs
-of markers delimiting each match on the line.
-This is a fully compatible change to the internal occur-mode
-implementation, and code creating their own occur-mode buffers will
-work as before.
-
-** EIEIO
+*** New command 'emoji-recent' (bound to 'C-x 8 e r').
+This command lets you choose among the Emojis you have recently
+inserted.
+++
-*** The macro 'oref-default' can now be used with 'setf'.
-It is now defined as a generalized variable that can be used with
-'setf' to modify the value stored in a given class slot.
-
----
-*** 'form' in '(eql form)' specializers in 'cl-defmethod' is now evaluated.
-This corresponds to the behavior of defmethod in Common Lisp Object System.
-For compatibility, '(eql SYMBOL)' does not evaluate SYMBOL, for now.
+*** New command 'emoji-describe' (bound to 'C-x 8 e d').
+This command will tell you the name of the Emoji at point. (This
+command also works for non-Emoji characters.)
-** New minor mode 'cl-font-lock-built-in-mode' for 'lisp-mode'.
-The mode provides refined highlighting of built-in functions, types,
-and variables.
-
-** Archive mode
+** Help
---
-*** Archive Mode can now parse ".squashfs" files.
-
-*** Can now modify members of 'ar' archives.
-
-*** Display of summaries unified between backends.
-
-*** New user option 'archive-hidden-columns' and command
-'archive-hideshow-column'. These let you control which columns are
-displayed and which are kept hidden.
+*** 'C-h b' uses outlining by default.
+Set 'describe-bindings-outline' to nil to get the old behavior.
---
-*** New command bound to 'C': 'archive-copy-file'.
-This command extracts the file under point and writes the data to a
-file.
-
-** Emacs Lisp mode
-
-*** The mode-line now indicates whether we're using lexical or dynamic scoping.
-
-*** A space between an open paren and a symbol changes the indentation rule.
-The presence of a space between an open paren and a symbol now is
-taken as a statement by the programmer that this should be indented
-as a data list rather than as a piece of code.
-
-** Calendar
-
-+++
-*** New user option 'calendar-time-zone-style'.
-If 'numeric', calendar functions (eg 'calendar-sunrise-sunset') that display
-time zones will use a form like "+0100" instead of "CET".
-
-** Dired
+*** Jumping to function/variable source now saves mark before moving point.
+Jumping to source from "*Help*" buffer moves the point when the source
+buffer is already open. Now, the old point is pushed to mark ring.
+++
-*** New user option 'dired-kill-when-opening-new-dired-buffer'.
-If non-nil, Dired will kill the current buffer when selecting a new
-directory to display.
+*** New key bindings in "*Help*" buffers: 'n' and 'p'.
+These will take you (respectively) to the next and previous "page".
---
-*** Behavior change on 'dired-clean-confirm-killing-deleted-buffers'.
-Previously, if 'dired-clean-up-buffers-too' was non-nil, and
-'dired-clean-confirm-killing-deleted-buffers' was nil, the buffers
-wouldn't be killed. This combination will now kill the buffers.
+*** 'describe-char' now also outputs the name of emoji combinations.
-+++
-*** New user option 'dired-switches-in-mode-line'.
-This user option controls how 'ls' switches are displayed in the mode
-line, and allows truncating them (to preserve space on the mode line)
-or showing them literally, either instead of, or in addition to,
-displaying "by name" or "by date" sort order.
+** Outline Minor Mode
+++
-*** New user option 'dired-compress-directory-default-suffix'.
-This user option controls default suffix for compressing a directory.
-If it's nil, ".tar.gz" will be used. Refer to
-'dired-compress-files-alist' for a list of supported suffixes.
-
-+++
-*** New user option 'dired-compress-file-default-suffix'.
-This user option controls the default suffix for compressing files.
-If it's nil, ".gz" will be used. Refer to 'dired-compress-file-alist'
-for a list of supported suffixes.
+*** 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. Default nil.
---
-*** Broken and circular links are shown with the 'dired-broken-symlink' face.
-
-*** '=' ('dired-diff') will now put all backup files into the 'M-n' history.
-When using '=' on a file with backup files, the default file to use
-for diffing is the newest backup file. You can now use 'M-n' to quickly
-select a different backup file instead.
+*** New user option 'outline-minor-mode-buttons'.
+This is a list of pairs of open/close strings used to display buttons.
+++
-*** New user option 'dired-maybe-use-globstar'.
-If set, enables globstar (recursive globbing) in shells that support
-this feature, but turn it off by default. This allows producing
-directory listings with files matching a wildcard in all the
-subdirectories of a given directory. The new variable
-'dired-enable-globstar-in-shell' lists which shells can have globstar
-enabled, and how to enable it.
+** Support for the WebP image format.
+This support is built by default when the libwebp library is
+available. To disable it, use the '--without-webp' configure flag.
+Image specifiers can now use ':type webp'.
-+++
-*** New user option 'dired-copy-dereference'.
-If set to non-nil, Dired will dereference symbolic links when copying.
-This can be switched off on a per-usage basis by providing
-'dired-do-copy' with a 'C-u' prefix.
-
-*** New user option 'dired-do-revert-buffer'.
-Non-nil reverts the destination Dired buffer after performing one
-of these operations: 'dired-do-copy', 'dired-do-rename',
-'dired-do-symlink', 'dired-do-hardlink'.
-
-*** New user option 'dired-mark-region' affects all Dired commands
-that mark files. When non-nil and the region is active in Transient
-Mark mode, then Dired commands operate only on files in the active
-region. The values 'file' and 'line' of this user option define the
-details of marking the file at the end of the region.
-
-*** State changing VC operations are supported in Dired on files and
-directories with the help of new command 'dired-vc-next-action'.
+** Windows
+++
-*** 'dired-jump' and 'dired-jump-other-window' moved from 'dired-x' to 'dired'.
-The 'dired-jump' and 'dired-jump-other-window' commands have been
-moved from the 'dired-x' package to 'dired'. The user option
-'dired-bind-jump' no longer has any effect and is now obsolete.
-The commands are now bound to 'C-x C-j' and 'C-x 4 C-j' by default.
-
-To get the old behavior of 'dired-bind-jump' back and unbind the above
-keys, add the following to your init file:
-
-(global-set-key "\C-x\C-j" nil)
-(global-set-key "\C-x4\C-j" nil)
+*** 'display-buffer' now can set up the body size of the chosen window.
+For example, a 'display-buffer-alist' entry of
-** Change Logs and VC
+ '(window-width . (body-columns . 40))'
-*** More VC commands can be used from non-file buffers.
-The relevant commands are those that don't change the VC state.
-The non-file buffers which can use VC commands are those that have
-their 'default-directory' under VC.
+will make the body of the chosen window 40 columns wide. For the
+height use 'window-height' in combination with 'body-lines'.
-*** New command 'vc-dir-root' uses the root directory without asking.
+** Tab Bars and Tab Lines
---
-*** New face 'log-view-commit-body'.
-This is used when expanding commit messages from 'vc-print-root-log'
-and similar commands.
+*** 'C-x t RET' creates a new tab when the provided tab name doesn't exist.
----
-*** New faces for 'vc-dir' buffers.
-Those are: 'vc-dir-header', 'vc-dir-header-value', 'vc-dir-directory',
-'vc-dir-file', 'vc-dir-mark-indicator', 'vc-dir-status-warning',
-'vc-dir-status-edited', 'vc-dir-status-up-to-date',
-'vc-dir-status-ignored'.
-
----
-*** The responsible VC backend is now the most specific one.
-'vc-responsible-backend' loops over the backends in
-'vc-handled-backends' to determine which backend is responsible for a
-specific (unregistered) file. Previously the first matching backend
-was chosen, but now the one with the most specific path is chosen (in
-case there's a directory handled by one backend inside another).
-
-*** New commands 'vc-dir-mark-registered-files' (bound to '* r') and
-'vc-dir-mark-unregistered-files'.
+** Better detection of text suspiciously reordered on display.
+The function 'bidi-find-overridden-directionality' has been extended
+to detect reordering effects produced by embeddings and isolates
+(started by directional formatting control characters such as RLO and
+LRI). The new command 'highlight-confusing-reorderings' finds and
+highlights segments of buffer text whose reordering for display is
+suspicious and could be malicious.
-*** Support for bookmark.el.
-Bookmark locations can refer to VC directory buffers.
-
----
-*** New user option 'vc-hg-create-bookmark'.
-It controls whether a bookmark or branch will be created when you
-invoke 'C-u C-x v s' ('vc-create-tag').
-
----
-*** 'vc-hg' now uses 'hg summary' to populate extra 'vc-dir' headers.
-
----
-*** New user option 'vc-git-revision-complete-only-branches'.
-If non-nil, only branches and remotes are considered when doing
-completion over Git branch names. The default is nil, which causes
-tags to be considered as well.
-
----
-*** New user option 'vc-git-log-switches'.
-String or list of strings specifying switches for Git log under VC.
-
-** Gnus
-
-+++
-*** New user option 'gnus-topic-display-predicate'.
-This can be used to inhibit the display of some topics completely.
-
-+++
-*** nnimap now supports the oauth2.el library.
-
-+++
-*** New Summary buffer sort options for extra headers.
-The extra header sort option ('C-c C-s C-x') prompts for a header
-and fails if no sort function has been defined. Sorting by
-Newsgroups ('C-c C-s C-u') has been pre-defined.
+** Emacs server and client changes
+++
-*** The '#' command in the Group and Summary buffer now toggles,
-instead of sets, the process mark.
+*** New command-line option '-r' for emacsclient.
+With this command-line option, Emacs reuses an existing graphical client
+frame if one exists; otherwise it creates a new frame.
+++
-*** New user option 'gnus-process-mark-toggle'.
-If non-nil (the default), the '#' command in the Group and Summary
-buffers will toggle, instead of set, the process mark.
+*** 'server-stop-automatically' can be used to automatically stop the server.
+The Emacs server will be automatically stopped when certain conditions
+are met. The conditions are given by the argument, which can be
+'empty', 'delete-frame' or 'kill-terminal'.
-
-+++
-*** New user option 'gnus-registry-register-all'.
-If non-nil (the default), create registry entries for all messages.
-If nil, don't automatically create entries, they must be created
-manually.
-
-+++
-*** New user options to customise the summary line specs "%[" and "%]".
-Four new options introduced in customisation group
-'gnus-summary-format'. These are 'gnus-sum-opening-bracket',
-'gnus-sum-closing-bracket', 'gnus-sum-opening-bracket-adopted', and
-'gnus-sum-closing-bracket-adopted'. Their default values are "[", "]",
-"<", ">" respectively. These options control the appearance of "%["
-and "%]" specs in the summary line format. "%[" will normally display
-the value of 'gnus-sum-opening-bracket', but can also be
-'gnus-sum-opening-bracket-adopted' for the adopted articles. "%]" will
-normally display the value of 'gnus-sum-closing-bracket', but can also
-be 'gnus-sum-closing-bracket-adopted' for the adopted articles.
-
-+++
-*** New user option 'gnus-paging-select-next'.
-This controls what happens when using commands like 'SPC' and 'DEL' to
-page the current article. If non-nil (the default), go to the
-next/prev article, but if nil, do nothing at the end/start of the article.
-
-+++
-*** New gnus-search library.
-A new unified search syntax which can be used across multiple
-supported search engines. Set 'gnus-search-use-parsed-queries' to
-non-nil to enable.
-
-+++
-*** New value for user option 'smiley-style'.
-Smileys can now be rendered with emojis instead of small images when
-using the new 'emoji' value in 'smiley-style'.
-
-+++
-*** New user option 'gnus-agent-eagerly-store-articles'.
-If non-nil (which is the default), the Gnus Agent will store all read
-articles in the Agent cache.
-
-+++
-*** New user option 'gnus-global-groups'.
-Gnus handles private groups differently from public (i.e., NNTP-like)
-groups. Most importantly, Gnus doesn't download external images from
-mail-like groups. This can be overridden by putting group names in
-'gnus-global-groups': Any group present in that list will be treated
-like a public group.
-
-+++
-*** New scoring types for the Date header.
-You can now score based on the relative age of an article with the new
-'<' and '>' date scoring types.
-
-+++
-*** User-defined scoring is now possible.
-The new type is 'score-fn'. More information in the Gnus manual node
-"(gnus) Score File Format".
-
-+++
-*** New backend 'nnselect'.
-The newly added 'nnselect' backend allows creating groups from an
-arbitrary list of articles that may come from multiple groups and
-servers. These groups generally behave like any other group: they may
-be ephemeral or persistent, and allow article marking, moving,
-deletion, etc. 'nnselect' groups may be created like any other group,
-but there are three convenience functions for the common case of
-obtaining the list of articles as a result of a search:
-'gnus-group-make-search-group' ('G g') that will prompt for an 'nnir'
-search query and create a persistent group for that search;
-'gnus-group-read-ephemeral-search-group' ('G G') that will prompt for
-an 'nnir' search query and create an ephemeral group for that search;
-and 'gnus-summary-make-group-from-search' ('C-c C-p') that will create
-a persistent group with the search parameters of a current ephemeral
-search group.
-
-As part of this addition, the user option 'nnir-summary-line-format'
-has been removed; its functionality is now available directly in the
-'gnus-summary-line-format' specs '%G' and '%g'. The user option
-'gnus-refer-thread-use-nnir' has been renamed to
-'gnus-refer-thread-use-search'.
-
-+++
-*** New user option 'gnus-dbus-close-on-sleep'.
-On systems with D-Bus support, it is now possible to register a signal
-to close all Gnus servers before the system sleeps.
-
-+++
-*** The key binding of 'gnus-summary-search-article-forward' has changed.
-This command was previously on 'M-s' and shadowed the global 'M-s'
-search prefix. The command has now been moved to 'M-s M-s'. (For
-consistency, the 'M-s M-r' key binding has been added for the
-'gnus-summary-search-article-backward' command.)
+* Editing Changes in Emacs 29.1
---
-*** The value of "all" in the 'large-newsgroup-initial' group parameter changes.
-It was previously nil, which didn't work, because nil is
-indistinguishable from not being present. The new value for "all" is
-the symbol 'all'.
+** Indentation of 'cl-flet' and 'cl-labels' has changed.
+These forms now indent like this:
-+++
-*** The name of dependent Gnus sessions has changed from "slave" to "child".
-The names of the commands 'gnus-slave', 'gnus-slave-no-server' and
-'gnus-slave-unplugged' have changed to 'gnus-child',
-'gnus-child-no-server' and 'gnus-child-unplugged' respectively.
+ (cl-flet ((bla (x)
+ (* x x)))
+ (bla 42))
-+++
-*** The 'W Q' summary mode command now takes a numerical prefix to
-allow adjusting the fill width.
+This change also affects 'cl-macrolet', 'cl-flet*' and
+'cl-symbol-macrolet'.
+++
-*** New variable 'mm-inline-font-lock'.
-This variable is supposed to be bound by callers to determine whether
-inline MIME parts (that support it) are supposed to be font-locked or
-not.
-
-** Message
-
----
-*** Respect 'message-forward-ignored-headers' more.
-Previously, this user option would not be consulted if
-'message-forward-show-mml' was nil and forwarding as MIME.
+** New user option 'translate-upper-case-key-bindings'.
+This can be set to nil to inhibit translating upper case keys to lower
+case keys.
+++
-*** New user option 'message-forward-included-mime-headers'.
-This is used when forwarding messages as MIME, but not using MML.
-
-+++
-*** Message now supports the OpenPGP header.
-To generate these headers, add the new function
-'message-add-openpgp-header' to 'message-send-hook'. The header will
-be generated according to the new 'message-openpgp-header' variable.
+** New command 'ensure-empty-lines'.
+This command increases (or decreases) the number of empty lines before
+point.
---
-*** A change to how "Mail-Copies-To: never" is handled.
-If a user has specified "Mail-Copies-To: never", and Message was asked
-to do a "wide reply", some other arbitrary recipient would end up in
-the resulting "To" header, while the remaining recipients would be put
-in the "Cc" header. This is somewhat misleading, as it looks like
-you're responding to a specific person in particular. This has been
-changed so that all the recipients are put in the "To" header in these
-instances.
-
-+++
-*** New command to start Emacs in Message mode to send an email.
-Emacs can be defined as a handler for the "x-scheme-handler/mailto"
-MIME type with the following command: "emacs -f message-mailto %u".
-An "emacs-mail.desktop" file has been included, suitable for
-installing in desktop directories like "/usr/share/applications" or
-"~/.local/share/applications".
-Clicking on a 'mailto:' link in other applications will then open
-Emacs with headers filled out according to the link, e.g.
-"mailto:larsi@gnus.org?subject=This+is+a+test". If you prefer
-emacsclient, use "emacsclient -e '(message-mailto "%u")'"
-or "emacsclient-mail.desktop".
-
----
-*** Change to default value of 'message-draft-headers' user option.
-The 'Date' symbol has been removed from the default value, meaning that
-draft or delayed messages will get a date reflecting when the message
-was sent. To restore the original behavior of dating a message
-from when it is first saved or delayed, add the symbol 'Date' back to
-this user option.
-
-+++
-*** New command to take screenshots.
-In Message mode buffers, the 'C-c C-p' ('message-insert-screenshot')
-command has been added. It depends on using an external program to
-take the actual screenshot, and defaults to "ImageMagick import".
-
-** Smtpmail
+*** Improved mouse behavior with auto-scrolling modes.
+When clicking inside the 'scroll-margin' or 'hscroll-margin' region
+the point is now moved only when releasing the mouse button. This no
+longer results in a bogus selection, unless the mouse has been
+effectively dragged.
+++
-*** smtpmail now supports using the oauth2.el library.
-
-+++
-*** New user option 'smtpmail-store-queue-variables'.
-If non-nil, SMTP variables will be stored together with the queued
-messages, and will then be used when sending with
-'M-x smtpmail-send-queued-mail'.
-
-+++
-*** Allow direct selection of smtp authentication mechanism.
-A server entry retrieved by auth-source can request a desired smtp
-authentication mechanism by setting a value for the key 'smtp-auth'.
-
-** Search and Replace
-
-*** New key 'M-s M-.' starts isearch with the thing found at point.
-This key is bound to the new command 'isearch-forward-thing-at-point'.
-The new user option 'isearch-forward-thing-at-point' defines
-a list of symbols to try to get the "thing" at point. By default,
-the first element of the list is 'region' that tries to yank
-the currently active region to the search string.
-
-*** New user option 'isearch-wrap-pause' defines how to wrap the search.
-There are choices to disable wrapping completely and to wrap immediately.
-When wrapping immediately, it consistently handles the numeric arguments
-of 'C-s' ('isearch-repeat-forward') and 'C-r' ('isearch-repeat-backward'),
-continuing with the remaining count after wrapping.
-
-** Grep
-
-+++
-*** New user option 'grep-match-regexp' matches grep markers to highlight.
-Grep emits SGR ANSI escape sequences to color its output. The new
-user option 'grep-match-regexp' holds the regular expression to match
-the appropriate markers in order to provide highlighting in the source
-buffer. The user option can be customized to accommodate other
-grep-like tools.
+** 'kill-ring-max' now defaults to 120.
---
-*** The 'lgrep' command now ignores directories.
-On systems where the grep command supports it, directories will be
-skipped.
-
-*** Commands that use 'grep-find' now follow symlinks for command-line args.
-This is because the default value of 'grep-find-template' now includes
-the 'find' option '-H'. Commands that use that variable, including
-indirectly via a call to 'xref-matches-in-directory', might be
-affected. In particular, there should be no need anymore to ensure
-any directory names on the 'find' command lines end in a slash.
-This change is for better compatibility with old versions of non-GNU
-'find', such as the one used on macOS.
+** New user option 'yank-menu-max-items'.
+Customize this option to limit the number of entries in the menu
+"Edit->Paste from Kill Menu". The default is 60.
----
-*** New utility function 'grep-file-at-point'.
-This returns the name of the file at point (if any) in 'grep-mode'
-buffers.
-
-** Help
+** show-paren-mode
+++
-*** New convenience commands with short keys in the Help buffer.
-New command 'help-view-source' ('s') will view the source file (if
-any) of the current help topic. New command 'help-goto-info' ('i')
-will look up the current symbol (if any) in Info. New command
-'help-customize' ('c') will customize the variable or the face
-(if any) whose doc string is being shown in the Help buffer.
+*** New user option 'show-paren-context-when-offscreen'.
+When non-nil, if the point is in a closing delimiter and the opening
+delimiter is offscreen, shows some context around the opening
+delimiter in the echo area. Default nil.
----
-*** The 'help-for-help' ('C-h C-h') screen has been redesigned.
-
----
-*** Keybindings in 'help-mode' use the new 'help-key-binding' face.
-This face is added by 'substitute-command-keys' to any "\[command]"
-substitution. The return value of that function should consequently
-be assumed to be a propertized string.
-
-Note that the new face will also be used in tooltips. When using the
-GTK toolkit, this is only true if 'x-gtk-use-system-tooltips' is t.
-
----
-*** 'g' ('revert-buffer') in 'help-mode' no longer requires confirmation.
+** Comint
+++
-*** New command 'describe-command' shows help for a command.
-This can be used instead of 'describe-function' for interactive
-commands and is globally bound to 'C-h x'.
+*** 'comint-term-environment' is now aware of connection-local variables.
+The user option 'comint-terminfo-terminal' and variable
+'system-uses-terminfo' can now be set as connection-local variables to
+change the terminal used on a remote host.
-+++
-*** New command 'describe-keymap' describes keybindings in a keymap.
+** Mwheel
---
-*** New user option 'describe-bindings-outline'.
-It enables outlines in the output buffer of 'describe-bindings' that
-can provide a better overview in a long list of available bindings.
+*** New user options for alternate wheel events.
+The options 'mouse-wheel-down-alternate-event', 'mouse-wheel-up-alternate-event',
+'mouse-wheel-left-alternate-event', and 'mouse-wheel-right-alternate-event' have
+been added to better support systems where two kinds of wheel events can be
+received.
----
-*** New keybinding 'C-h R' prompts for a manual to display and displays it.
-
----
-*** Closing the "*Help*" buffer from the toolbar now buries the buffer.
-In previous Emacs versions, the "*Help*" buffer was killed instead when
-clicking the "X" icon in the tool bar.
-
-** Info
+
+* Changes in Specialized Modes and Packages in Emacs 29.1
----
-*** New user option 'Info-warn-on-index-alternatives-wrap'.
-This option affects what happens when using the ',' command after
-looking up an entry with 'i' in info buffers. If non-nil (the
-default), the ',' command will now warn you when proceeding beyond the
-final entry, and tapping ',' once more will then take you to the
-first entry.
+** Isearch and Replace
-+++
-** New command 'lossage-size'.
-It allows users to set the maximum number of keystrokes and commands
-recorded for the purpose of 'view-lossage'.
+*** New user option 'char-fold-override' omits the default character-folding.
----
-*** The command 'view-lossage' can now be invoked from the menu bar.
-The menu bar "Help" menu now has a "Show Recent Inputs" item under the
-"Describe" sub-menu.
+** New minor mode 'glyphless-display-mode'.
+This allows an easy way to toggle seeing all glyphless characters in
+the current buffer.
-** Input methods
+** Registers
+++
-*** Emacs now supports "transient" input methods.
-A transient input method is enabled for inserting a single character,
-and is then automatically disabled. 'C-x \' temporarily enables the
-selected transient input method. Use 'C-u C-x \' to select a
-transient input method (which can be different from the input method
-enabled by 'C-\'). For example, 'C-u C-x \ compose RET' selects the
-'compose' input method; then typing 'C-x \ 1 2' will insert the
-character '½', and disable the 'compose' input method afterwards.
-You can use 'C-x \' in incremental search to insert a single character
-to the search string.
-
----
-*** New input method 'compose' based on X Multi_key sequences.
-
----
-*** New input method 'iso-transl' with the same keys as 'C-x 8'.
-After selecting it as a transient input method with 'C-u C-x \
-iso-transl RET', it supports the same key sequences as 'C-x 8',
-so e.g. like 'C-x 8 [' inserts a left single quotation mark,
-'C-x \ [' does the same.
+*** Buffer names can now be stored in registers.
+For instance, to enable jumping to the "*Messages*" buffer with
+'C-x r j m':
----
-*** New user option 'read-char-by-name-sort'.
-It defines the sorting order of characters for completion of 'C-x 8 RET TAB'
-and can be customized to sort them by codepoints instead of character names.
-Additionally, you can group characters by Unicode blocks after customizing
-'completions-group' and 'completions-group-sort'.
-
----
-*** Improved language transliteration in Malayalam input methods.
-Added a new Mozhi scheme. The inapplicable ITRANS scheme is now
-deprecated. Errors in the Inscript method were corrected.
-
----
-*** New input method 'cham'.
-There's also a Cham greeting in "etc/HELLO".
-
----
-*** New input methods for Lakota language orthographies.
-Two orthographies are represented here, the Suggested Lakota
-Orthography and what is known as the White Hat Orthography. Input
-methods 'lakota-slo-prefix', 'lakota-slo-postfix', and
-'lakota-white-hat-postfix' have been added. There is also a Lakota
-greeting in "etc/HELLO".
+ (set-register ?m '(buffer . "*Messages*"))
-** Ispell
+** pixel-fill
+++
-*** 'ispell-comments-and-strings' now accepts START and END arguments,
-defaulting to active region when used interactively.
+*** This is a new package that deals with filling variable-pitch text.
+++
-*** New command 'ispell-comment-or-string-at-point' is provided.
-
----
-** The old non-SMIE indentation of 'sh-mode' has been removed.
-
----
-** The sb-image.el library is now marked obsolete.
-This file was a compatibility kludge which is no longer needed.
-
----
-** Lisp mode now uses 'common-lisp-indent-function'.
-To revert to the previous behavior,
-'(setq lisp-indent-function 'lisp-indent-function)' from 'lisp-mode-hook'.
-
-** Customize
-
----
-*** Customize buffers can now be reverted with 'C-x x g'.
-
-*** Most customize commands now hide obsolete user options.
-Obsolete user options are no longer shown in the listings produced by
-the commands 'customize', 'customize-group', 'customize-apropos' and
-'customize-changed'.
-
-To customize obsolete user options, use 'customize-option' or
-'customize-saved'.
-
-*** New SVG icons for checkboxes and arrows.
-They will be used automatically instead of the old icons. If Emacs is
-built without SVG support, the old icons will be used instead.
-
-** Bookmarks
-
-*** Bookmarks can now be targets for new tabs.
-When the bookmark.el library is loaded, a customize choice is added
-to 'tab-bar-new-tab-choice' for new tabs to show the bookmark list.
+*** New function 'pixel-fill-region'.
+This fills the region to be no wider than a specified pixel width.
----
-*** The 'list-bookmarks' menu is now based on 'tabulated-list-mode'.
-The interactive bookmark list will now benefit from features in
-'tabulated-list-mode' like sorting columns or changing column width.
-
-Support for the optional "inline" header line, allowing for a header
-without using 'header-line-format', has been dropped. Consequently,
-the variables 'bookmark-bmenu-use-header-line' and
-'bookmark-bmenu-inline-header-height' are now declared obsolete.
-
----
-*** New user option 'bookmark-fontify'.
-If non-nil, setting a bookmark will colorize the current line with
-'bookmark-face'.
+** Info
---
-*** New user option 'bookmark-menu-confirm-deletion'.
-In Bookmark Menu mode, Emacs by default does not prompt for
-confirmation when you type 'x' to execute the deletion of bookmarks
-that have been marked for deletion. However, if this new option is
-non-nil then Emacs will require confirmation with 'yes-or-no-p' before
-deleting.
+*** New command 'Info-goto-node-web' and key binding 'G'.
+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.
-** Edebug
+** vc
-*** Obsoletions
---
-**** 'get-edebug-spec' is obsolete, replaced by 'edebug-get-spec'.
-+++
-**** The spec operator ':name NAME' is obsolete, use '&name' instead.
-+++
-**** The spec element 'function-form' is obsolete, use 'form' instead.
-
-+++
-*** New function 'def-edebug-elem-spec' to define Edebug spec elements.
-These used to be defined with 'def-edebug-spec' thus conflating the
-two name spaces, which lead to name collisions.
-The use of 'def-edebug-spec' to define Edebug spec elements is
-declared obsolete.
-
-*** Edebug specification lists can use some new keywords:
-
-+++
-**** '&interpose SPEC FUN ARGS..' lets FUN control parsing after SPEC.
-More specifically, FUN is called with 'HEAD PF ARGS..' where
-PF is a parsing function that expects a single argument (the specs to
-use) and HEAD is the code that matched SPEC.
-
-+++
-**** '&error MSG' unconditionally aborts the current edebug instrumentation.
+*** 'C-x v v' on an unregistered file will now use the most specific backend.
+Previously, if you had an SVN-covered "~/" directory, and a Git-covered
+directory in "~/foo/bar", using 'C-x v v' on a new, unregistered file
+"~/foo/bar/zot" would register it in the SVN repository in "~/" instead of
+in the Git repository in "~/foo/bar". This makes this command
+consistent with 'vc-responsible-backend'.
-+++
-**** '&name SPEC FUN' extracts the current name from the code matching SPEC.
-
-** ElDoc
-
-+++
-*** New user option 'eldoc-echo-area-display-truncation-message'.
-If non-nil (the default), eldoc will display a message saying
-something like "(Documentation truncated. Use `M-x eldoc-doc-buffer'
-to see rest)" when a message has been truncated. If nil, truncated
-messages will be marked with just "..." at the end.
-
-+++
-*** New hook 'eldoc-documentation-functions'.
-This hook is intended to be used for registering doc string functions.
-These functions don't need to produce the doc string right away, they
-may arrange for it to be produced asynchronously. The results of all
-doc string functions are accessible to the user through the user
-option 'eldoc-documentation-strategy'.
-
-*** New hook 'eldoc-display-functions'.
-This hook is intended to be used for displaying doc strings. The
-functions receive the doc string composed according to
-'eldoc-documentation-strategy' and are tasked with displaying it to
-the user. Examples of such functions would use the echo area, a
-separate buffer, or a tooltip.
-
-+++
-*** New user option 'eldoc-documentation-strategy'.
-The built-in choices available for this user option let users compose
-the results of 'eldoc-documentation-functions' in various ways, even
-if some of those functions are synchronous and some asynchronous.
-The user option replaces 'eldoc-documentation-function', which is now
-obsolete.
-
-*** 'eldoc-echo-area-use-multiline-p' is now handled by ElDoc.
-The user option 'eldoc-echo-area-use-multiline-p' is now handled
-by the ElDoc library itself. Functions in
-'eldoc-documentation-functions' don't need to worry about consulting
-it when producing a doc string.
-
-** Shell
+** Message
---
-*** New command in 'shell-mode': 'narrow-to-prompt'.
-This is bound to 'C-x n d' in 'shell-mode' buffers, and narrows to the
-command line under point (and any following output).
+*** New user option 'mml-attach-file-at-the-end'.
+If non-nil, 'C-c C-a' will put attached files at the end of the message.
---
-*** New user option 'shell-has-auto-cd'.
-If non-nil, 'shell-mode' handles implicit "cd" commands, changing the
-directory if the command is a directory. Useful for shells like "zsh"
-that has this feature.
+*** Message Mode now supports image yanking.
-+++
-*** 'comint-delete-output' can now save deleted text in the kill-ring.
-Interactively, 'C-u C-c C-o' triggers this new optional behavior.
-
-** Eshell
+** HTML Mode
---
-*** 'eshell-hist-ignoredups' can now also be used to mimic "erasedups" in bash.
+*** HTML Mode now supports "text/html" and "image/*" yanking.
----
-*** Environment variable 'INSIDE_EMACS' is now copied to subprocesses.
-Its value contains the result of evaluating '(format "%s,eshell"
-emacs-version)'. Other package names, like "tramp", could also be included.
+** Texinfo Mode
---
-*** Eshell no longer re-initializes its keymap every call.
-This allows users to use (define-key eshell-mode-map ...) as usual.
-Some modules have their own minor mode now to account for these
-changes.
-
-** EUDC
-
-+++
-*** New macOS Contacts backend.
-This backend works on newer versions of macOS and is generally
-preferred over the eudcb-mab.el backend.
-
-** Tramp
-
-+++
-*** New connection method "mtp", which allows accessing media devices
-like cell phones, tablets or cameras.
+*** 'texinfo-mode' now has a specialised 'narrow-to-defun' definition.
+It narrows to the current node.
-+++
-*** New connection method "sshfs", which allows accessing remote files
-via a file system mounted with 'sshfs'.
+** eww/shr
+++
-*** Tramp supports SSH authentication via a hardware security key now.
-This requires at least OpenSSH 8.2, and a FIDO U2F compatible
-security key, like yubikey, solokey, or nitrokey.
+*** New user option 'shr-use-xwidgets-for-media'.
+If non-nil (and Emacs has been built with support for xwidgets),
+display <video> elements with an xwidget. Note that this is
+experimental, and is known to crash Emacs on some systems, and just
+doesn't work on other systems. Also see etc/PROBLEMS.
+++
-*** Trashed remote files are moved to the local trash directory.
-All remote files, which are trashed, are moved to the local trash
-directory. Except remote encrypted files, which are always deleted.
-
-+++
-*** New command 'tramp-crypt-add-directory'.
-This command marks a remote directory to contain only encrypted files.
-See the "(tramp) Keeping files encrypted" node of the Tramp manual for
-details. This feature is experimental.
-
-+++
-*** Support of direct asynchronous process invocation.
-When Tramp connection property "direct-async-process" is set to
-non-nil for a given connection, 'make-process' and 'start-file-process'
-calls are performed directly as in "ssh ... <command>". This avoids
-initialization performance penalties. See the "(tramp) Improving
-performance of asynchronous remote processes" node of the Tramp manual
-for details, and also for a discussion or restrictions. This feature
-is experimental.
-
-+++
-*** New user option 'tramp-debug-to-file'.
-When non-nil, this user option instructs Tramp to mirror the debug
-buffer to a file under the "/tmp/" directory. This is useful, if (in
-rare cases) Tramp blocks Emacs, and we need further debug information.
-
-+++
-*** Tramp supports lock files now.
-In order to deactivate this, set user option
-'remote-file-name-inhibit-locks' to t.
-
-+++
-*** Writing sensitive auto-save, backup or lock files to the local
-temporary directory must be confirmed. In order to suppress this
-confirmation, set user option 'tramp-allow-unsafe-temporary-files' to
-t.
-
-** Tempo
-
----
-*** 'tempo-define-template' can now re-assign templates to tags.
-Previously, assigning a new template to an already defined tag had no
-effect.
-
-** map.el
-
-*** Pcase 'map' pattern added keyword symbols abbreviation.
-A pattern like '(map :sym)' binds the map's value for ':sym' to 'sym',
-equivalent to '(map (:sym sym))'.
-
----
-*** The function 'map-copy' now uses 'copy-alist' on alists.
-This is a slightly deeper copy than the previous 'copy-sequence'.
+*** New user option 'eww-url-transformers'.
+These are used to alter an URL before using it. By default it removes
+the common "utm_" trackers from URLs.
----
-*** The function 'map-contains-key' now supports plists.
+** Gnus
---
-*** More consistent duplicate key handling in 'map-merge-with'.
-Until now, 'map-merge-with' promised to call its function argument
-whenever multiple maps contained 'eql' keys. However, this did not
-always coincide with the keys that were actually merged, which could
-be 'equal' instead. The function argument is now called whenever keys
-are merged, for greater consistency with 'map-merge' and 'map-elt'.
+*** Gnus now uses a variable-pitch font in the headers by default.
+To get the monospace font back, you can put something like the
+following in your .gnus file:
-** Package
+ (set-face-attribute 'gnus-header nil :inherit 'unspecified)
---
-*** '/ s' ('package-menu-filter-by-status') changes parameter handling.
-The command was documented to take a comma-separated list of statuses
-to filter by, but instead it used the parameter as a regexp. The
-command has been changed so that it now works as documented, and
-checks statuses not as a regexp, but instead an exact match from the
-comma-separated list.
-
-+++
-*** New command 'package-browse-url' and keystroke 'w'.
-
-+++
-*** 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-filter-clear
-
-*** Option to automatically native-compile packages upon installation.
-Customize the user option 'package-native-compile' to enable automatic
-native compilation of packages when they are installed. That option
-is nil by default; if set non-nil, and if your Emacs was built with
-native-compilation support, each package will be natively compiled
-when it is installed, by invoking an asynchronous Emacs subprocess to
-run the native-compilation of the package files.
+*** The default value of 'gnus-treat-fold-headers' is now 'head'.
---
-*** Column widths in 'list-packages' display can now be customized.
-See the new user options 'package-name-column-width',
-'package-version-column-width', 'package-status-column-width', and
-'package-archive-column-width'.
-
-** gdb-mi
-
-*** New user option 'gdb-registers-enable-filter'.
-If non-nil, apply a register filter based on
-'gdb-registers-filter-pattern-list'.
+*** New face 'gnus-header'.
+All other 'gnus-header-*' faces inherit from this face now.
+++
-*** gdb-mi can now store and restore window configurations.
-Use 'gdb-save-window-configuration' to save window configuration to a
-file and 'gdb-load-window-configuration' to load from a file. These
-commands can also be accessed through the menu bar under "Gud =>
-GDB-Windows". 'gdb-default-window-configuration-file', when non-nil,
-is loaded when GDB starts up.
+*** New user option 'gnus-treat-emojize-symbols'.
+If non-nil, symbols that have an emoji representation will be
+displayed as emojis. Default nil.
+++
-*** gdb-mi can now restore window configuration after quit.
-Set 'gdb-restore-window-configuration-after-quit' to non-nil and Emacs
-will remember the window configuration before GDB started and restore
-it after GDB quits. A toggle button is also provided under "Gud =>
-GDB-Windows".
+*** New command 'gnus-article-emojize-symbols'.
+This is bound to 'W D e' and will display symbols that have emoji
+representation as emojis.
-+++
-*** gdb-mi now has a better logic for displaying source buffers.
-Now GDB only uses one source window to display source file by default.
-Customize 'gdb-max-source-window-count' to use more than one window.
-Control source file display by 'gdb-display-source-buffer-action'.
-
-+++
-*** The default value of 'gdb-mi-decode-strings' is now t.
-This means that the default coding-system is now used to decode strings
-and source file names from GDB.
-
-** Gravatar
-
----
-*** New user option 'gravatar-service' for host to query for gravatars.
-Defaults to 'libravatar', with 'unicornify' and 'gravatar' as options.
-
-** Compilation mode
-
----
-*** New function 'ansi-color-compilation-filter'.
-This function is meant to be used in 'compilation-filter-hook'.
-
----
-*** New user option 'ansi-color-for-compilation-mode'.
-This controls what 'ansi-color-compilation-filter' does.
-
-*** Regexp matching of messages is now case-sensitive by default.
-The variable 'compilation-error-case-fold-search' can be set for
-case-insensitive matching of messages when the old behavior is
-required, but the recommended solution is to use a correctly matching
-regexp instead.
-
----
-*** New user option 'compilation-search-all-directories'.
-When doing parallel builds, directories and compilation errors may
-arrive in the "*compilation*" buffer out-of-order. If this variable is
-non-nil (the default), Emacs will now search backwards in the buffer
-for any directory the file with errors may be in. If nil, this won't
-be done (and this restores how this previously worked).
-
----
-*** Messages from ShellCheck are now recognized.
-
----
-*** Messages from Visual Studio that mention column numbers are now recognized.
-
-** Hi Lock mode
-
----
-*** Matching in 'hi-lock-mode' is case-sensitive when regexp contains
-upper case characters and 'search-upper-case' is non-nil.
-'highlight-phrase' also uses 'search-whitespace-regexp'
-to substitute spaces in regexp search.
-
----
-*** The default value of 'hi-lock-highlight-range' was enlarged.
-The new default value is 2000000 (2 megabytes).
-
-** Whitespace mode
+** EIEIO
+++
-*** New style 'missing-newline-at-eof'.
-If present in 'whitespace-style' (as it is by default), the final
-character in the buffer will be highlighted if the buffer doesn't end
-with a newline.
-
----
-*** The default 'whitespace-enable-predicate' predicate has changed.
-It used to check elements in the list version of
-'whitespace-global-modes' with 'eq', but now uses 'derived-mode-p'.
-
-** Texinfo
-
----
-*** New user option 'texinfo-texi2dvi-options'.
-This is used when invoking 'texi2dvi' from 'texinfo-tex-buffer'.
+*** 'slot-value' can now be used to access slots of 'cl-defstruct' objects.
----
-*** New commands for moving in and between environments.
-An "environment" is something that ends with '@end'. The commands are
-'C-c C-c C-f' (next end), 'C-c C-c C-b' (previous end),
-'C-c C-c C-n' (next start) and 'C-c C-c C-p' (previous start), as well
-as 'C-c .', which will alternate between the start and the end of the
-current environment.
-
-** Rmail
-
----
-*** New user option 'rmail-re-abbrevs'.
-Its default value matches localized abbreviations of the "reply"
-prefix on the Subject line in various languages.
-
----
-*** New user option 'shr-offer-extend-specpdl'.
-If this is nil, rendering of HTML in the email message body that
-requires to enlarge 'max-specpdl-size', the number of Lisp variable
-bindings, will be aborted, and Emacs will not ask you whether to
-enlarge 'max-specpdl-size' to complete the rendering. The default is
-t, which preserves the original behavior.
-
----
-*** New user option 'rmail-show-message-set-modified'.
-If set non-nil, showing an unseen message will set the Rmail buffer's
-modified flag.
+** align
---
-*** New faces for heading elements.
-Those are 'shr-h1', 'shr-h2', 'shr-h3', 'shr-h4', 'shr-h5', 'shr-h6'.
-
-** MH-E mail handler for Emacs
+*** Alignment in 'text-mode' has changed.
+Previously, 'M-x align' didn't do anything, and you had to say 'C-u
+M-x align' for it to work. This has now been changed. The default
+regexp for 'C-u M-x align-regexp' has also been changed to be easier
+for inexperienced users to use.
-Functions and variables related to handling junk mail have been
-renamed to not associate color with sender quality.
-
-+++
-*** New names for mh-junk interactive functions.
-Function 'mh-junk-whitelist' is renamed 'mh-junk-allowlist'.
-Function 'mh-junk-blacklist' is renamed 'mh-junk-blocklist'.
+** eww
+++
-*** New binding for 'mh-junk-allowlist'.
-The key binding for 'mh-junk-allowlist' is changed from 'J w' to 'J a'.
-The old binding is supported but warns that it is obsolete.
+*** New user option to automatically rename EWW buffers.
+The 'eww-auto-rename-buffer' user option can be configured to rename
+rendered web pages by using their title, URL, or a user-defined
+function which returns a string. For the first two cases, the length
+of the resulting name is controlled by 'eww-buffer-name-length'. By
+default, no automatic renaming is performed.
-+++
-*** New names for some hooks.
-'mh-whitelist-msg-hook' is renamed 'mh-allowlist-msg-hook'.
-'mh-blacklist-msg-hook' is renamed 'mh-blocklist-msg-hook'.
-
-+++
-*** New names for some variables.
-Variable 'mh-whitelist-preserves-sequences-flag' is renamed
-'mh-allowlist-preserves-sequences-flag'.
-
-+++
-*** New names for some faces.
-Face 'mh-folder-blacklisted' is renamed 'mh-folder-blocklisted'.
-Face 'mh-folder-whitelisted' is renamed 'mh-folder-allowlisted'.
-
-** Apropos
-
-*** New commands 'apropos-next-symbol' and 'apropos-previous-symbol'.
-These new navigation commands are bound to 'n' and 'p' in
-'apropos-mode'.
-
-*** New command 'apropos-function'.
-This works like 'C-u M-x apropos-command' but is more discoverable.
-
-*** New face 'apropos-button'.
-Applies to buttons that indicate a face.
-
-** CC Mode
-
-*** Added support for Doxygen documentation style.
-'doxygen' is now a valid 'c-doc-comment-style' which recognises all
-comment styles supported by Doxygen (namely '///', '//!', '/** … */'
-and '/*! … */'. 'gtkdoc' remains the default for C and C++ modes; to
-use 'doxygen' by default one might evaluate:
-
- (setq-default c-doc-comment-style
- '((java-mode . javadoc)
- (pike-mode . autodoc)
- (c-mode . doxygen)
- (c++-mode . doxygen)))
-
-or use it in a custom 'c-style'.
-
-*** Added support to line up '?' and ':' of a ternary operator.
-The new 'c-lineup-ternary-bodies' function can be used as a lineup
-function to align question mark and colon which are part of a ternary
-operator ('?:'). For example:
-
- return arg % 2 == 0 ? arg / 2
- : (3 * arg + 1);
-
-To enable, add it to appropriate entries in 'c-offsets-alist', e.g.:
-
- (c-set-offset 'arglist-cont '(c-lineup-ternary-bodies
- c-lineup-gcc-asm-reg))
- (c-set-offset 'arglist-cont-nonempty '(c-lineup-ternary-bodies
- c-lineup-gcc-asm-reg
- c-lineup-arglist))
- (c-set-offset 'statement-cont '(c-lineup-ternary-bodies +))
-
-** browse-url
-
-*** Added support for custom URL handlers.
-There is a new variable 'browse-url-default-handlers' and a user
-option 'browse-url-handlers' being alists with '(REGEXP-OR-PREDICATE
-. FUNCTION)' entries allowing to define different browsing FUNCTIONs
-depending on the URL to be browsed. The variable is for default
-handlers provided by Emacs itself or external packages, the user
-option is for the user (and allows for overriding the default
-handlers).
-
-Formerly, one could do the same by setting
-'browse-url-browser-function' to such an alist. This usage is still
-supported but deprecated.
-
-*** Categorization of browsing commands in internal vs. external.
-All standard browsing commands such as 'browse-url-firefox',
-'browse-url-mail', or 'eww' have been categorized into internal (URL
-is browsed in Emacs) or external (an external application is spawned
-with the URL). This is done by adding a 'browse-url-browser-kind'
-symbol property to the browsing commands. With a new command
-'browse-url-with-browser-kind', an URL can explicitly be browsed with
-either an internal or external browser.
-
----
-*** Support for browsing of remote files.
-If a remote file is taken, a local temporary copy of that file is
-passed to the browser.
-
-*** Support for the conkeror browser is now obsolete.
-
-*** Support for the Mosaic browser has been removed.
-This support has been obsolete since 25.1.
-
-** SHR
-
----
-*** The command 'shr-browse-url' now supports custom mailto handlers.
-Clicking on or otherwise following a 'mailto:' link in a HTML buffer
-rendered by SHR previously invoked the command 'browse-url-mailto'.
-This is still the case by default, but if you customize
-'browse-url-mailto-function' or 'browse-url-handlers' to call some
-other function, it will now be called instead of the default.
+** Help
-+++
-*** New user option 'shr-max-width'.
-If this user option is non-nil, and 'shr-width' is nil, then SHR will
-use the value of 'shr-max-width' to limit the width of the rendered
-HTML. The default is 120 characters, so even if you have very wide
-frames, HTML text will be rendered more narrowly, which usually leads
-to a more readable text. Set this user option to nil to get the
-previous behavior of rendering as wide as the 'window-width' allows.
-If 'shr-width' is non-nil, it overrides this variable.
+*** New user option 'help-link-key-to-documentation'.
+When this option is non-nil (which is the default), key bindings
+displayed in the "*Help*" buffer will be linked to the documentation
+for the command they are bound to. This does not affect listings of
+key bindings and functions (such as 'C-h b').
-** Images
+** info-look
---
-*** You can explicitly specify base_uri for svg images.
-':base-uri' image property can be used to explicitly specify base_uri
-for embedded images into svg. ':base-uri' is supported for both file
-and data svg images.
+*** info-look specs can now be expanded at run time instead of a load time.
+The new ':doc-spec-function' element can be used to compute the
+':doc-spec' element when the user asks for info on that particular
+mode (instead of at load time).
-+++
-*** 'svg-embed-base-uri-image' added to embed images.
-'svg-embed-base-uri-image' can be used to embed images located
-relatively to 'file-name-directory' of the ':base-uri' svg image property.
-This works much faster then 'svg-embed'.
-
-+++
-*** New function 'image-cache-size'.
-This function returns the size of the current image cache, in bytes.
-
----
-*** Animated images stop automatically under high CPU pressure sooner.
-Previously, an animated image would stop animating if any single image
-took more than two seconds to display. The new algorithm maintains a
-decaying average of delays, and if this number gets too high, the
-animation is stopped.
+** subr-x
+++
-*** The 'n' and 'p' commands (next/previous image) now respect Dired order.
-These commands would previously display the next/previous image in
-lexicographic order, but will now find the "parent" Dired buffer and
-select the next/previous image file according to how the files are
-sorted there. The commands have also been extended to work when the
-"parent" buffer is an archive mode (i.e., zip file or the like) or tar
-mode buffer.
+*** New macro 'with-memoization' provides a very primitive form of memoization.
----
-*** 'image-converter' is now restricted to formats in 'auto-mode-alist'.
-When using external image converters, the external program is queried
-for what formats it supports. This list may contain formats that are
-problematic in some contexts (like PDFs), so this list is now filtered
-based on 'auto-mode-alist'. Only file names that map to 'image-mode'
-are now supported.
+** ansi-color
---
-*** The background and foreground of images now default to face colors.
-When an image doesn't specify a foreground or background color, Emacs
-now uses colors from the face used to draw the surrounding text
-instead of the frame's default colors.
-
-To load images with the default frame colors use the ':foreground' and
-':background' image attributes, for example:
-
- (create-image "filename" nil nil
- :foreground (face-attribute 'default :foreground)
- :background (face-attribute 'default :background))
-
-This change only affects image types that support foreground and
-background colors or transparency, such as xbm, pbm, svg, png and gif.
-
-+++
-*** Image smoothing can now be explicitly enabled or disabled.
-Smoothing applies a bilinear filter while scaling or rotating an image
-to prevent aliasing and other unwanted effects. The new image
-property ':transform-smoothing' can be set to t to force smoothing
-and nil to disable smoothing.
-
-The default behavior of smoothing on down-scaling and not smoothing
-on up-scaling remains unchanged.
-
-+++
-*** New user option 'image-transform-smoothing'.
-This controls whether to use smoothing or not for an image. Values
-include nil (no smoothing), t (do smoothing) or a predicate function
-that's called with the image object and should return nil/t.
-
-+++
-*** SVG images now support user stylesheets.
-The ':css' image attribute can be used to override the default CSS
-stylesheet for an image. The default sets 'font-family' and
-'font-size' to match the current face, so an image with 'height="1em"'
-will match the font size in use where it is embedded.
-
-This feature relies on librsvg 2.48 or above being available.
-
-+++
-*** Image properties support 'em' sizes.
-Size image properties, for example ':height', ':max-height', etc., can
-be given a cons of the form '(SIZE . em)', where SIZE is an integer or
-float which is multiplied by the font size to calculate the image
-size, and 'em' is a symbol.
-
-** EWW
-
-+++
-*** New user option 'eww-use-browse-url'.
-This is a regexp that can be set to alter how links are followed in eww.
-
-+++
-*** New user option 'eww-retrieve-command'.
-This can be used to download data via an external command. If nil
-(the default), then 'url-retrieve' is used.
-
-+++
-*** New Emacs command line convenience command.
-The 'eww-browse' command has been added, which allows you to register
-Emacs as a MIME handler for "text/x-uri", and will call 'eww' on the
-supplied URL. Usage example: "emacs -f eww-browse https://gnu.org".
+*** Support for ANSI 256-color and 24-bit colors.
+256-color and 24-bit color codes are now handled by ANSI color
+filters and displayed with the specified color.
-+++
-*** 'eww-download-directory' will now use the XDG location, if defined.
-However, if "~/Downloads/" already exists, that will continue to be
-used.
+** term-mode
---
-*** The command 'eww-follow-link' now supports custom mailto handlers.
-The function that is invoked when clicking on or otherwise following a
-'mailto:' link in an EWW buffer can now be customized. For more
-information, see the related entry about 'shr-browse-url' above.
-
-** Project
-
-*** New user option 'project-vc-merge-submodules'.
-
-*** Project commands now have their own history.
-Previously used project directories are now suggested by all commands
-that prompt for a project directory.
-
-+++
-*** New prefix keymap 'project-prefix-map'.
-Key sequences that invoke project-related commands start with the
-prefix 'C-x p'. Type "C-x p C-h" to show the full list.
+*** Support for ANSI 256-color and 24-bit colors, italic and other fonts.
+Term-mode can now display 256-color and 24-bit color codes. It can
+also handle ANSI codes for faint, italic and blinking text, displaying
+it with new 'term-{faint,italic,slow-blink,fast-blink}' faces.
-+++
-*** New commands 'project-dired', 'project-vc-dir', 'project-shell',
-'project-eshell'. These commands run Dired/VC-Dir and Shell/Eshell in
-a project's root directory, respectively.
+** Xref
-+++
-*** New command 'project-compile'.
-This command runs compilation in the current project's root
-directory.
+*** 'project-find-file' and 'project-or-external-find-file' now accept
+a prefix argument which is interpreted to mean "include all files".
-+++
-*** New command 'project-switch-project'.
-This command lets you "switch" to another project and run a project
-command chosen from a dispatch menu.
+*** 'project-kill-buffers' can display the list of buffers to kill.
+Customize the user option 'project-kill-buffers-display-buffer-list'
+to enable the display of the buffer list.
+++
-*** New commands 'project-shell-command' and 'project-async-shell-command'.
-These commands run 'shell-command' and 'async-shell-command' in a
-project's root directory, respectively.
+*** New command 'xref-go-forward'.
+It is bound to 'C-M-,' and jumps to the location where 'xref-go-back'
+('M-,', also known as 'xref-pop-marker-stack') was invoked previously.
-+++
-*** New user option 'project-list-file'.
+** File notifications
+++
-*** New command 'project-remove-known-project'.
-This command lets you interactively remove an entry from the list of projects
-in 'project-list-file'.
-
-*** 'project-find-file' now accepts non-existent file names.
-This is to allow easy creation of files inside some nested
-sub-directory.
-
-*** 'project-find-file' doesn't use the string at point as default input.
-Now it's only suggested as part of the "future history".
-
-** xref
-
----
-*** Prefix arg of 'xref-goto-xref' quits the "*xref*" buffer.
-So typing 'C-u RET' in the "*xref*" buffer quits its window
-before navigating to the selected location.
-
-*** New user options 'xref-search-program' and 'xref-search-program-alist'.
-So far 'grep' and 'ripgrep' are supported. 'ripgrep' seems to offer better
-performance in certain cases, in particular for case-insensitive
-searches.
-
-+++
-*** New commands 'xref-prev-group' and 'xref-next-group'.
-These commands are bound respectively to 'P' and 'N', and navigate to
-the first item of the previous or next group in the "*xref*" buffer.
-
-*** New alternative value for 'xref-show-definitions-function':
-'xref-show-definitions-completing-read'.
-
-*** The two existing alternatives for 'xref-show-definitions-function'
-have been renamed to have "proper" public names and documented
-('xref-show-definitions-buffer' and
-'xref-show-definitions-buffer-at-bottom').
-
-*** New command 'xref-quit-and-pop-marker-stack' and a binding for it
-in "*xref*" buffers ('M-,'). This combination is easy to press
-semi-accidentally if the user wants to go back in the middle of
-choosing the exact definition to go to, and this should do TRT.
-
----
-*** New value 'project-relative' for 'xref-file-name-display'.
-If chosen, file names in "*xref*" buffers will be displayed relative
-to the 'project-root' of the current project, when available.
-
-+++
-*** The 'TAB' key binding in "*xref*" buffers is obsolete.
-Use 'C-u RET' instead. The 'TAB' binding in "*xref*" buffers is still
-supported, but we plan on removing it in a future version; at that
-time, the command 'xref-quit-and-goto-xref' will no longer have a key
-binding in 'xref--xref-buffer-mode-map'.
-
-** json.el
+*** The new command 'file-notify-rm-all-watches' removes all file notifications.
----
-*** JSON number parsing is now stricter.
-Numbers with a leading plus sign, leading zeros, or a missing integer
-component are now rejected by 'json-read' and friends. This makes
-them more compliant with the JSON specification and consistent with
-the native JSON parsing functions.
+** Sql
---
-*** Some JSON encoding functions are now obsolete.
-The functions 'json-encode-number', 'json-encode-hash-table',
-'json-encode-key', and 'json-encode-list' are now obsolete.
-
-The first two are kept as aliases of 'json-encode', which should be
-used instead. Uses of 'json-encode-list' should be changed to call
-one of 'json-encode', 'json-encode-alist', 'json-encode-plist', or
-'json-encode-array' instead.
+*** Sql now supports sending of passwords in-process.
+To improve security, if an sql product has ':password-in-comint' set
+to t, a password supplied via the minibuffer will be sent in-process,
+as opposed to via the command-line.
-** json.c
+** Image Mode
+++
-*** New function 'json-available-p'.
-This predicate returns non-nil if Emacs is built with libjansson
-support, and it is available on the current system.
+*** 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
+Image Mode by default.
+++
-*** Native JSON functions now signal an error if libjansson is unavailable.
-This affects 'json-serialize', 'json-insert', 'json-parse-string',
-and 'json-parse-buffer'. This can happen if Emacs was compiled with
-libjansson, but the DLL cannot be found and/or loaded by Emacs at run
-time. Previously, Emacs would display a message and return nil in
-these cases.
-
-*** The JSON functions 'json-serialize', 'json-insert',
-'json-parse-string', and 'json-parse-buffer' now implement some of the
-semantics of RFC 8259 instead of the earlier RFC 4627. In particular,
-these functions now accept top-level JSON values that are neither
-arrays nor objects.
-
-** xml.el
-
-*** XML serialization functions now reject invalid characters.
-Previously 'xml-print' would produce invalid XML when given a string
-with characters that are not valid in XML (see
-https://www.w3.org/TR/xml/#charsets). Now it rejects such strings.
-
-** erc
-
----
-*** erc-services.el now supports NickServ passwords from auth-source.
-The 'erc-use-auth-source-for-nickserv-password' user option enables
-querying auth-source for NickServ passwords. To enable this, add the
-following to your init file:
-
- (setq erc-prompt-for-nickserv-password nil
- erc-use-auth-source-for-nickserv-password t)
+*** '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'.
---
-*** The '/ignore' command will now ask for a timeout to stop ignoring the user.
-Allowed inputs are seconds or ISO8601-like periods like "1h" or "4h30m".
+*** User option 'image-auto-resize' can now be set to 'fit-window'.
+This works like 'image-transform-fit-to-window'.
----
-*** ERC now recognizes 'C-]' for italic text.
-Italic text is displayed in the new 'erc-italic-face'.
+*** New user option 'image-auto-resize-max-scale-percent'.
+The new 'fit-window' option will never scale an image more than this
+much (in percent). It is nil by default, which means no limit.
---
-*** The erc-compat.el library is now marked obsolete.
-This file contained ERC compatibility code for Emacs 21 and XEmacs
-which is no longer needed.
+*** New user option 'image-text-based-formats'.
+This controls whether or not to show a message when opening certain
+image formats saying how to edit it as text. The default is to show
+this message for SVG and XPM.
----
-*** erc-match.el now supports 'message' highlight type (not including the nick).
-The 'erc-current-nick-highlight-type', 'erc-pal-highlight-type',
-'erc-fool-highlight-type', 'erc-keyword-highlight-type', and
-'erc-dangerous-host-highlight-type' variables now support a 'message'
-type for highlighting the entire message but not the sender's nick.
-
-*** erc-status-sidebar.el is now part of ERC.
-The 'erc-status-sidebar' package which provides a HexChat-like
-activity overview sidebar for joined IRC channels is now part of ERC.
+** Image-Dired
+++
-*** erc-tls now supports specifying a TLS client certificate.
-The 'erc-tls' function has been updated to allow specifying a TLS
-client certificate for authentication, as an alternative to NickServ
-password-based authentication. This is referred to as "CertFP" (short
-for Certificate Fingerprint) by several IRC networks. See the Info
-node "(erc) Connecting" in the ERC manual for more details and
-examples on how to specify and use TLS client certificates with
-'erc-tls'.
-
-** Battery
-
----
-*** UPower is now the default battery status backend when available.
-UPower support via the function 'battery-upower' was added in Emacs
-26.1, but was disabled by default. It is now the default value of
-'battery-status-function' when the system provides a UPower D-Bus
-service. The user options 'battery-upower-device' and
-'battery-upower-subscribe' control which power sources to query and
-whether to respond to status change notifications in addition to
-polling, respectively.
+*** 'image-dired-display-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'.
---
-*** A richer syntax can be used to format battery status information.
-The user options 'battery-mode-line-format' and
-'battery-echo-area-format' now support the full formatting syntax of
-the function 'format-spec' documented under node "(elisp) Custom Format
-Strings". The new syntax includes specifiers for padding and
-truncation, amongst other things.
+*** Navigation and marking commands now work in image display buffer.
+The following new bindings have been added:
-** bug-reference.el
+ n / SPC image-dired-display-next-thumbnail-original
+ p / 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
---
-*** Bug reference mode auto-setup. If 'bug-reference-mode' or
-'bug-reference-prog-mode' have been activated, their respective hook
-has been run and still 'bug-reference-bug-regexp' and
-'bug-reference-url-format' aren't both set, it tries to guess
-appropriate values for those two variables. There are three guessing
-mechanisms so far: based on version control information of the current
-buffer's file, based on newsgroup/mail-folder name and several news
-and mail message headers in Gnus buffers, and based on IRC channel and
-network in rcirc and ERC buffers. All mechanisms are extensible with
-custom rules, see the variables 'bug-reference-setup-from-vc-alist',
-'bug-reference-setup-from-mail-alist', and
-'bug-reference-setup-from-irc-alist'.
-
-** HTML Mode
+*** 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.
---
-*** A new skeleton for adding relative URLs has been added.
-It's bound to the 'C-c C-c f' keystroke, and prompts for a local file
-name.
-
-** Recentf
+*** 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.
---
-*** The recentf files are no longer backed up.
-
----
-*** 'recentf-auto-cleanup' time string now repeats.
-When 'recentf-auto-cleanup' is set to a time string, it now repeats
-every day, rather than only running once after the mode is turned on.
-
-** Calc
+*** 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.
---
-*** The behavior when doing forward-delete has been changed.
-Previously, using the 'C-d' command would delete the final number in
-the input field, no matter where point was. This has been changed to
-work more traditionally, with 'C-d' deleting the next character.
-Likewise, point isn't moved to the end of the string before inserting
-digits.
-
-+++
-*** Setting the word size to zero disables word clipping.
-The word size normally clips the results of certain bit-oriented
-operations such as shifts and bitwise XOR. A word size of zero, set
-by 'b w', makes the operation have effect on the whole argument values
-and the result is not truncated in any way.
+*** 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.
---
-*** The '/' operator now has higher precedence in (La)TeX input mode.
-It no longer has lower precedence than '+' and '-'.
+*** New face 'image-dired-thumb-flagged'.
+If 'image-dired-thumb-mark' is non-nil (the default), this face is
+used for images that are flagged for deletion in the Dired buffer
+associated with Image-Dired.
---
-*** Calc now marks its windows dedicated.
-The new user option 'calc-make-windows-dedicated' controls this. It
-is t by default; set to nil to get back the old behavior.
-
-** term-mode
+*** 'image-dired-slideshow-start' is now bound to 'S'.
+It is bound in both the thumbnail and display buffer.
---
-*** New user option 'term-scroll-snap-to-bottom'.
-By default, 'term' and 'ansi-term' will now recenter the buffer so
-that the prompt is on the final line in the window. Setting this new
-user option to nil inhibits this behavior.
+*** 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 user option 'term-set-terminal-size'
-If non-nil, the 'LINES' and 'COLUMNS' environment variables will be set
-based on the current window size. In previous versions of Emacs, this
-was always done (and that could lead to odd displays when resizing the
-window after starting). This variable defaults to nil.
-
-** Widget
-
-+++
-*** 'widget-choose' now supports menus in extended format.
-
----
-*** The 'editable-list' widget now supports moving items up and down.
-You can now move items up and down by deleting and then reinserting
-them, using the 'DEL' and 'INS' buttons respectively. This is useful
-in Custom buffers, for example, to change the order of the elements in
-a list.
-
-** Diff
+*** Support for bookmark.el.
+The command 'bookmark-set' (bound to 'C-x r m') is now supported in
+the thumbnail view, and will create a bookmark that opens the current
+directory in Image-Dired.
---
-*** New face 'diff-changed-unspecified'.
-This is used to highlight "changed" lines (those marked with '!') in
-context diffs, when 'diff-use-changed-face' is non-nil.
+*** 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 'diff-mode' font locking face 'diff-error'.
-This face is used for error messages from 'diff'.
-
-+++
-*** New command 'diff-refresh-hunk'.
-This new command (bound to 'C-c C-l') regenerates the current hunk.
-
-** Buttons
+*** 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.
+++
-*** New minor mode 'button-mode'.
-This minor mode does nothing else than install 'button-buffer-map' as
-a minor mode map (which binds the 'TAB' / 'S-TAB' key bindings to navigate
-to buttons), and can be used in any view-mode-like buffer that has
-buttons in it.
-
-+++
-*** New utility function 'button-buttonize'.
-This function takes a string and returns a string propertized in a way
-that makes it a valid button.
-
-** subr-x
-+++
-*** A number of new string manipulation functions have been added.
-'string-clean-whitespace', 'string-fill', 'string-limit',
-'string-lines', 'string-pad' and 'string-chop-newline'.
-
-*** New macro 'named-let' that provides Scheme's "named let" looping construct.
-
-** thingatpt
-
-+++
-*** New variable 'thing-at-point-provider-alist'.
-This allows mode-specific alterations to how 'thing-at-point' works.
-
-** Enriched mode
+*** 'image-dired-show-all-from-dir-max-files' has been increased to 500.
+This option controls asking for confirmation when starting Image-Dired
+in a directory with many files. However, Image-Dired creates
+thumbnails in the background these days, so this is not as important
+as it used to be, back when entering a large directory could lock up
+Emacs for tens of seconds. In addition, you can now customize this
+option to nil to disable this confirmation completely.
---
-*** 'C-a' is by default no longer bound to 'beginning-of-line-text'.
-This is so 'C-a' works as in other modes, and in particular holding
-Shift while typing 'C-a', i.e. 'C-S-a', will now highlight the text.
-
-** ERT
-
-+++
-*** ERT can now output more verbose test failure reports.
-If the 'EMACS_TEST_VERBOSE' environment variable is set, failure
-summaries will include the failing condition.
+*** Make 'image-dired-rotate-thumbnail-(left|right)' obsolete.
+Instead, use 'M-x image-dired-refresh-thumb' to generate a new
+thumbnail, or 'M-x image-rotate' to rotate the thumbnail without
+updating the thumbnail file.
-** File Locks
-
-+++
-*** New user option 'lock-file-name-transforms'.
-This option allows controlling where lock files are written. It uses
-the same syntax as 'auto-save-file-name-transforms'.
-
-+++
-*** New user option 'remote-file-name-inhibit-locks'.
-When non-nil, this option suppresses lock files for remote files.
-
-+++
-*** New minor mode 'lock-file-mode'.
-This command, called interactively, toggles the local value of
-'create-lockfiles' in the current buffer.
-
-** image-dired
+** Dired
----
-*** 'image-dired-mouse-toggle-mark' now toggles files in the active region.
+*** New user option 'dired-free-space'.
+Dired will now, by default, include the free space in the first line
+instead of having it on a separate line. To get the previous behavior
+back, say:
-+++
-*** New user option 'image-dired-thumb-visible-marks'.
-If non-nil (the default), use 'image-dired-thumb-mark' to say what
-images are marked.
+ (setq dired-free-space 'separate)
---
-*** New command 'image-dired-delete-marked'.
+*** New user option 'dired-make-directory-clickable'.
+If non-nil (which is the default), hitting 'RET' or 'mouse-1' on
+the directory components at the directory displayed at the start of
+the buffer will take you to that directory.
-** Miscellaneous
+** Exif
-+++
-*** New function 'replace-regexp-in-region'.
-
-+++
-*** New function 'replace-string-in-region'.
+*** New function 'exif-field'.
+This is a convenience function to extract the field data from
+'exif-parse-file' and 'exif-parse-buffer'.
----
-*** New function 'mail-header-parse-addresses-lax'.
-This takes a comma-separated string and returns a list of mail/name
-pairs.
+** Xwidgets
---
-*** New function 'mail-header-parse-address-lax'.
-Parse a string as a mail address-like string.
+*** New user option 'xwidget-webkit-buffer-name-format'.
+Using this option you can control how the xwidget-webkit buffers are
+named.
---
-*** 'shell-script-mode' now supports 'outline-minor-mode'.
-The outline headings have lines that start with "###".
+*** New user option 'xwidget-webkit-cookie-file'.
+Using this option you can control whether the xwidget-webkit buffers
+save cookies set by web pages, and if so, in which file to save them.
+++
-*** New command 'revert-buffer-quick'.
-This is bound to 'C-x x g' and is like `revert-buffer', but prompts
-less.
+*** New minor mode 'xwidget-webkit-edit-mode'.
+When this mode is enabled, self-inserting characters and other common
+web browser shortcut keys are redefined to send themselves to the
+WebKit widget.
+++
-*** New user option 'revert-buffer-quick-short-answers'. This
-controls how the new 'revert-buffer-quick' (`C-x x g') command
-prompts.
-
----
-*** fileloop will now skip missing files instead of signalling an error.
+*** New minor mode 'xwidget-webkit-isearch-mode'.
+This mode acts similarly to incremental search, and allows searching
+the contents of a WebKit widget. In xwidget-webkit mode, it is bound
+to 'C-s' and 'C-r'.
+++
-*** ".dir-locals.el" now supports setting 'auto-mode-alist'.
-The new 'auto-mode-alist' specification in ".dir-locals.el" files can
-now be used to override the global 'auto-mode-alist' in the current
-directory tree.
+*** New command 'xwidget-webkit-browse-history'.
+This command displays a buffer containing the page load history of
+the current WebKit widget, and allows you to navigate it.
---
-*** New utility function 'make-separator-line'.
-
----
-*** New face 'separator-line'.
-This is used by 'make-separator-line'.
-
-+++
-*** New user option 'ignored-local-variable-values'.
-This is the opposite of 'safe-local-variable-values' -- it's an alist
-of variable-value pairs that are to be ignored when reading a
-local-variables section of a file.
+*** On X11, the WebKit inspector is now available inside xwidgets.
+To access the inspector, right click on the widget and select "Inspect
+Element".
---
-*** 'indent-tabs-mode' is now a global minor mode instead of just a variable.
+*** "Open in New Window" in a WebKit widget's context menu now works.
+The newly created buffer will be displayed via 'display-buffer', which
+can be customized through the usual mechanism of 'display-buffer-alist'
+and friends.
----
-*** New user option 'save-place-abbreviate-file-names'.
-
----
-*** 'tabulated-list-mode' can now restore original display order.
-Many commands (like 'C-x C-b') are derived from 'tabulated-list-mode',
-and that mode allows the user to sort on any column. There was
-previously no easy way to get back to the original displayed order
-after sorting, but giving a -1 numerical prefix to the sorting command
-will now restore the original order.
+** Tramp
---
-*** 'M-left' and 'M-right' now move between columns in 'tabulated-list-mode'.
+*** Tramp supports abbreviating remote home directories now.
+When calling 'abbreviate-file-name' on a Tramp filename, the result
+will abbreviate the user's home directory, for example by abbreviating
+"/ssh:user@host:/home/user" to "/ssh:user@host:~".
-+++
-*** New utility function 'insert-into-buffer'.
-This is like 'insert-buffer-substring', but works in the opposite
-direction.
-
-+++
-*** New user option 'kill-transform-function'.
-This can be used to transform (and suppress) strings from entering the
-kill ring.
+** Browse URL
---
-*** 'C-u M-x dig' will now prompt for a query type to use.
-
-+++
-*** rcirc now supports SASL authentication.
-
-+++
-*** 'save-interprogram-paste-before-kill' can now be a number.
-In that case, it's interpreted as a limit on the size of the clipboard
-data that will be saved to the 'kill-ring' prior to killing text: if
-the size of the clipboard data is greater than or equal to the limit,
-it will not be saved.
+*** Support for the Netscape web browser has been removed.
+This support has been obsolete since Emacs 25.1. The final version of
+the Netscape web browser was released in February, 2008.
---
-*** New variable 'hl-line-overlay-priority'.
-This can be used to change the priority of the hl-line overlays.
+*** Support for the Galeon web browser has been removed.
+This support has been obsolete since Emacs 25.1. The final version of
+the Galeon web browser was released in September, 2008.
-+++
-*** New command 'mailcap-view-file'.
-This command will open a viewer based on the file type, as determined
-by "~/.mailcap" and related files and variables.
+
+* New Modes and Packages in Emacs 29.1
+++
-*** New command 'C-x C-k Q' to force redisplay in keyboard macros.
+** New mode 'erts-mode'.
+This mode is used to edit files geared towards testing actions in
+Emacs buffers, like indentation and the like. The new ert function
+'ert-test-erts-file' is used to parse these files.
----
-*** New user option 'remember-diary-regexp'.
+
+* Incompatible Lisp Changes in Emacs 29.1
----
-*** New user option 'remember-text-format-function'.
+** User option 'mail-source-ignore-errors' is now obsolete.
+The whole mechanism for prompting users to continue in case of
+mail-source errors has been removed, so this option is no longer
+needed.
-*** New function 'buffer-line-statistics'.
-This function returns some statistics about the line lengths in a buffer.
-
-+++
-*** New variable 'inhibit-interaction' to make user prompts signal an error.
-If this is bound to something non-nil, functions like
-'read-from-minibuffer', 'read-char' (and related) will signal an
-'inhibited-interaction' error.
+** Fonts
---
-*** 'process-attributes' now works under OpenBSD, too.
+*** Emacs now supports 'medium' fonts.
+Emacs previously didn't distinguish between the 'regular'/'normal'
+weight and the 'medium' weight, but it now also supports the (heavier)
+'medium' weight. However, this means that if you previously specified
+a weight of 'normal' and the font doesn't have this weight, Emacs
+won't find the font spec. In these cases, replacing ":weight 'normal"
+with ":weight 'medium" should fix the issue.
-+++
-*** New button face 'flat-button'.
-This is a plain 2D button, but uses the background color instead of
-the foreground color.
+** Keymap descriptions have changed.
+'help--describe-command', 'C-h b' and associated functions that output
+keymap descriptions have changed. In particular, prefix commands are
+not output at all, and instead of "??" for closures/functions,
+"[closure]"/"[lambda]" is output.
---
-*** New face 'shortdoc-heading'.
-Applies to headings of shortdoc sections.
-
-+++
-*** New predicate functions 'length<', 'length>' and 'length='.
-Using these functions may be more efficient than using 'length' (if
-the length of a (long) list is being computed just to compare this
-length to a number).
+** 'downcase' details have changed slightly.
+In certain locales, changing the case of an ASCII-range character may
+turn it into a multibyte character, most notably with "I" in Turkish
+(the lowercase is "ı", 0x0131). Previously, 'downcase' on a unibyte
+string was buggy, and would mistakenly just return the lower byte of
+this, 0x31 (the digit "1"). 'downcase' on a unibyte string has now
+been changed to downcase such characters as if they were ASCII. To
+get proper locale-dependent downcasing, the string has to be converted
+to multibyte first. (This goes for the other case-changing functions,
+too.)
---
-*** 'remove-hook' is now an interactive command.
+** Functions in 'tramp-foreign-file-name-handler-alist' have changed.
+Functions to determine which Tramp file name handler to use are now
+passed a file name in dissected form (via 'tramp-dissect-file-name')
+instead of in string form.
---
-*** New user option 'authinfo-hide-elements'.
-This can be set to nil to inhibit hiding passwords in ".authinfo" files.
+** 'def' indentation changes.
+In 'emacs-lisp-mode', forms with a symbol with a name that start with
+"def" have been automatically indented as if they were 'defun'-like
+forms, for instance:
-+++
-*** New variable 'current-minibuffer-command'.
-This is like 'this-command', but it is bound recursively when entering
-the minibuffer.
+ (defzot 1
+ 2 3)
-+++
-*** New function 'object-intervals'.
-This function returns a copy of the list of intervals (i.e., text
-properties) in the object in question (which must either be a string
-or a buffer).
+This heuristic has now been removed, and all functions/macros that
+want to be indented this way have to be marked with
----
-*** 'hexl-mode' scrolling commands now heed 'next-screen-context-lines'.
-Previously, 'hexl-scroll-down' and 'hexl-scroll-up' would scroll
-up/down an entire window, but they now work more like the standard
-scrolling commands.
+ (declare (indent defun))
----
-*** Errors in 'kill-emacs-hook' no longer prevent Emacs from shutting down.
-If a function in that hook signals an error in an interactive Emacs,
-the user will be prompted on whether to continue. If the user doesn't
-answer within five seconds, Emacs will continue shutting down anyway.
-
----
-*** iso-transl is now preloaded.
-This means that keystrokes like 'Alt-[' are defined by default,
-instead of only becoming available after doing (for instance)
-'C-x 8 <letter>'.
+or the like. If the function/macro definition itself can't be
+changed, the indentation can also be adjusted by saying something
+like:
-*** New user option 'completions-detailed'.
-When non-nil, some commands like 'describe-symbol' show more detailed
-completions with more information in completion prefix and suffix.
+ (put 'defzot 'lisp-indent-function 'defun)
---
-*** User option 'completions-format' supports a new value 'one-column'.
+** The 'inhibit-changing-match-data' variable is now obsolete.
+Instead, functions like 'string-match' and 'looking-at' now take an
+optional 'inhibit-modify' argument.
---
-*** New user option 'bibtex-unify-case-function'.
-This new option allows the user to customize how case is converted
-when unifying entries.
+** 'gnus-define-keys' is now obsolete.
+Use 'define-keymap' instead.
---
-*** The user option 'bibtex-maintain-sorted-entries' now permits
-user-defined sorting schemes.
-
-+++
-*** 'format-seconds' can now be used for sub-second times.
-The new optional "," parameter has been added, and
-'(format-seconds "%mm %,1ss" 66.4)' will now result in "1m 6.4s".
+** MozRepl has been removed from js.el.
+MozRepl was removed from Firefox in 2017, so this code doesn't work
+with recent versions of Firefox.
---
-*** 'global-display-fill-column-indicator-mode' skips some buffers.
-By default, turning on 'global-display-fill-column-indicator-mode'
-doesn't turn on 'display-fill-column-indicator-mode' in special-mode
-buffers. This can be controlled by customizing the variable
-'global-display-fill-column-indicator-modes'.
-
-+++
-*** New user option 'next-error-message-highlight'.
-In addition to a fringe arrow, 'next-error' error may now optionally
-highlight the current error message in the 'next-error' buffer.
-This user option can be also customized to keep highlighting on all
-visited errors, so you can have an overview what errors were already visited.
+** The function 'image-dired-get-exif-data' is now obsolete.
+Use 'exif-parse-file' and 'exif-field' instead.
---
-*** New choice 'next-error-quit-window' for 'next-error-found-function'.
-When 'next-error-found-function' is customized to 'next-error-quit-window',
-then typing the numeric prefix argument 0 before the command 'next-error'
-will quit the source window after visiting the next occurrence.
-
-+++
-*** New user option 'tab-first-completion'.
-If 'tab-always-indent' is 'complete', this new user option can be used to
-further tweak whether to complete or indent.
-
----
-*** 'dired-query' now uses 'read-char-from-minibuffer'.
-Using it instead of 'read-char-choice' allows using 'C-x o'
-to switch to the help window displayed after typing 'C-h'.
-
----
-*** 'zap-up-to-char' now uses 'read-char-from-minibuffer'.
-This allows navigating through the history of characters that have
-been input. This is mostly useful for characters that have complex
-input methods where inputting the character again may involve many
-keystrokes.
-
-+++
-*** Interactive regular expression search now uses faces for sub-groups.
-E.g., 'C-M-s foo-\([0-9]+\)' will now use the 'isearch-group-1' face
-on the part of the regexp that matches the sub-expression "[0-9]+".
-By default, there are two faces for sub-group highlighting, but you
-can define more faces whose names are of the form 'isearch-group-N',
-where N are successive numbers above 2.
-
-This is controlled by the 'search-highlight-submatches' user option.
-This feature is available only on terminals that have enough colors to
-distinguish between sub-expression highlighting.
+** 'insert-directory' alternatives should not change the free disk space line.
+This change is now applied in 'dired-insert-directory'.
-+++
-*** Interactive regular expression replace now uses faces for sub-groups.
-Like 'search-highlight-submatches', this is controlled by the new user option
-'query-replace-highlight-submatches'.
+** Some functions and variables obsolete since Emacs 23 have been removed:
+'find-emacs-lisp-shadows', 'newsticker-cache-filename',
+'unify-8859-on-decoding-mode', 'unify-8859-on-encoding-mode',
+'vc-arch-command'.
----
-*** New user option 'reveal-auto-hide'.
-If non-nil (the default), revealed text is automatically hidden when
-point leaves the text. If nil, the text is not hidden again. Instead
-'M-x reveal-hide-revealed' can be used to hide all the revealed text.
+
+* Lisp Changes in Emacs 29.1
+++
-*** New command 'submit-emacs-patch'.
-This works like 'report-emacs-bug', but is more geared towards sending
-patches to the Emacs issue tracker.
+** New facility for handling session state: 'multisession-value'.
+This can be used as a convenient way to store (simple) application
+state, and 'M-x list-multisession-values' allows users to list
+(and edit) this data.
+++
-*** The user can now customize how "default" values are prompted for.
-The new utility function 'format-prompt' has been added which uses the
-new 'minibuffer-default-prompt-format' user option to format "default"
-prompts. This means that prompts that look like "Enter a number
-(default 10)" can be customized to look like, for instance, "Enter a
-number [10]", or not have the default displayed at all, like "Enter a
-number". (This requires that all callers are altered to use
-'format-prompt', though.)
+** New function 'get-display-property'.
+This is like 'get-text-property', but works on the 'display' text
+property.
+++
-*** New global mode 'global-goto-address-mode'.
-This will enable 'goto-address-mode' in all buffers.
-
----
-*** 'C-s' in 'M-x' now searches over completions again.
-In Emacs 23, typing 'M-x' ('read-extended-command') and then 'C-s' (to
-do an interactive search) would search over possible completions.
-This was lost in Emacs 24, but is now back again.
-
----
-*** 'M-x report-emacs-bug' will no longer include "Recent messages" section.
-These were taken from the "*Messages*" buffer, and may inadvertently
-leak information from the reporting user.
-
----
-*** 'count-windows' now takes an optional parameter ALL-FRAMES.
-The semantics are as with 'walk-windows'.
-
----
-*** New variable 'ffap-file-name-with-spaces'.
-If non-nil, 'find-file-at-point' and friends will try to guess more
-expansively to identify a file name with spaces.
+** New function 'add-text-display-property'.
+This is like 'put-text-property', but works on the 'display' text
+property.
+++
-*** New 'thing-at-point' target: 'existing-filename'.
-This is like 'filename', but is a full path, and is nil if the file
-doesn't exist.
-
----
-*** Two new commands for centering in 'doc-view-mode'.
-The new commands 'doc-view-center-page-horizontally' (bound to 'c h')
-and 'doc-view-center-page-vertically' (bound to 'c v') center the page
-horizontally and vertically, respectively.
-
----
-*** Change in meaning of 'icomplete-show-matches-on-no-input'.
-Previously, choosing a different completion with commands like 'C-.'
-and then hitting 'RET' would choose the default completion. Doing this
-will now choose the completion under point instead. Also when this option
-is nil, completions are not shown when the minibuffer reads a file name
-with initial input as the default directory.
-
----
-*** The width of the buffer-name column in 'list-buffers' is now dynamic.
-The width now depends of the width of the window, but will never be
-wider than the length of the longest buffer name, except that it will
-never be narrower than 19 characters.
-
----
-*** Movement commands in 'gomoku-mode' are fixed.
-'gomoku-move-sw' and 'gomoku-move-ne' now work correctly, and
-horizontal movements now stop at the edge of the board.
-
-** xterm-mouse mode
-
----
-*** TTY menu navigation is now supported in 'xterm-mouse-mode'.
-TTY menus support mouse navigation and selection when 'xterm-mouse-mode'
-is active. When run on a terminal, clicking on the menu bar with the
-mouse now pops up a TTY menu by default instead of running the command
-'tmm-menubar'. To restore the old behavior, set the user option
-'tty-menu-open-use-tmm' to non-nil.
-
-** text-scale-mode
-
----
-*** 'text-scale-mode' can now adjust font size of the header line.
-When the new buffer local variable 'text-scale-remap-header-line'
-is non-nil, 'text-scale-adjust' will also scale the text in the header
-line when displaying that buffer.
-
-This is useful for major modes that arrange their display in a tabular
-form below the header line. It is enabled by default in
-'tabulated-list-mode' and its derived modes.
-
-** xwidget-webkit mode
-
-*** New xwidget commands.
-'xwidget-webkit-uri' (return the current URL), 'xwidget-webkit-title'
-(return the current title), and 'xwidget-webkit-goto-history' (goto a
-point in history).
-
-*** Pixel-based scrolling.
-The 'xwidget-webkit-scroll-up', 'xwidget-webkit-scroll-down' commands
-now supports scrolling arbitrary pixel values. It now treats the
-optional 2nd argument as the pixel values to scroll.
-
-*** New commands for scrolling.
-The new commands 'xwidget-webkit-scroll-up-line',
-'xwidget-webkit-scroll-down-line', 'xwidget-webkit-scroll-forward',
-'xwidget-webkit-scroll-backward' can be used to scroll webkit by the
-height of lines or width of chars.
-
-*** New user option 'xwidget-webkit-bookmark-jump-new-session'.
-When non-nil, use a new xwidget webkit session after bookmark jump.
-Otherwise, it will use 'xwidget-webkit-last-session'.
-
-** ido
-
----
-*** Switching on 'ido-mode' now also overrides 'ffap-file-finder'.
-
----
-*** Killing virtual ido buffers interactively will make them go away.
-Previously, killing a virtual ido buffer with 'ido-kill-buffer' didn't
-do anything. This has now been changed, and killing virtual buffers
-with that command will remove the buffer from recentf.
-
-** Flymake mode
+** New 'min-width' 'display' property.
+This allows setting a minimum display width for a region of text.
+++
-*** New user options to customize Flymake's mode-line.
-The new user option 'flymake-mode-line-format' is a mix of strings and
-symbols like 'flymake-mode-line-title', 'flymake-mode-line-exception'
-and 'flymake-mode-line-counters'. The new user option
-'flymake-mode-line-counter-format' is a mix of strings and symbols
-like 'flymake-mode-line-error-counter',
-'flymake-mode-line-warning-counter' and 'flymake-mode-line-note-counter'.
+** New event type 'touch-end'.
+This event is sent whenever the user's finger moves off the mouse
+wheel on some mice, or when the user's finger moves off the touchpad.
-** Flyspell mode
+** Keymaps and key definitions
+++
-*** Corrections and actions menu can be optionally bound to 'mouse-3'.
-When Flyspell mode highlights a word as misspelled, you can click on
-it to display a menu of possible corrections and actions. You can now
-easily bind this menu to 'down-mouse-3' (usually the right mouse button)
-instead of 'mouse-2' (the default) by customizing the new user option
-'flyspell-use-mouse-3-for-menu'.
-
----
-*** The current dictionary is now displayed in the minor mode lighter.
-Clicking the dictionary name changes the current dictionary.
-
-** Time
-
----
-*** 'display-time-world' has been renamed to 'world-clock'.
-'world-clock' creates a buffer with an updating time display using
-several time zones. It is hoped that the new names are more
-discoverable.
-
-The following commands have been renamed:
-
- 'display-time-world' to 'world-clock'
- 'display-time-world-mode' to 'world-clock-mode'
- 'display-time-world-display' to 'world-clock-display'
- 'display-time-world-timer' to 'world-clock-update'
-
-The following user options have been renamed:
-
- 'display-time-world-list' to 'world-clock-list'
- 'display-time-world-time-format' to 'world-clock-time-format'
- 'display-time-world-buffer-name' to 'world-clock-buffer-name'
- 'display-time-world-timer-enable' to 'world-clock-timer-enable'
- 'display-time-world-timer-second' to 'world-clock-timer-second'
-
-The old names are now obsolete.
-
----
-*** 'world-clock-mode' can no longer be turned on interactively.
-Use 'world-clock' to turn on that mode.
-
-** D-Bus
+*** New functions for defining and manipulating keystrokes have been added.
+These all take just the syntax defined by 'key-valid-p'. None of the
+older functions have been depreciated or altered, but are deemphasised
+in the documentation.
+++
-*** Property values can be typed explicitly.
-'dbus-register-property' and 'dbus-set-property' accept now optional
-type symbols. Both functions propagate D-Bus errors.
+*** Use 'keymap-set' instead of 'define-key'.
+++
-*** Registered properties can have the new access type ':write'.
+*** Use 'keymap-global-set' instead of 'global-set-key'.
+++
-*** In case of problems, handlers can emit proper D-Bus error messages now.
+*** Use 'keymap-local-set' instead of 'local-set-key'.
+++
-*** D-Bus errors, which have been converted from incoming D-Bus error
-messages, contain the error name of that message now.
+*** Use 'keymap-global-unset' instead of 'global-unset-key'.
+++
-*** D-Bus messages can be monitored with the new command 'dbus-monitor'.
+*** Use 'keymap-local-unset' instead of 'local-unset-key'.
+++
-*** D-Bus events have changed their internal structure.
-They carry now the destination and the error-name of an event. They
-also keep the type information of their arguments. Use the
-'dbus-event-*' accessor functions.
-
-** CPerl Mode
-
----
-*** New face 'perl-heredoc', used for heredoc elements.
+*** Use 'keymap-substitute' instead of 'substitute-key-definition'.
+++
-** A function can now be thrown to the 'exit' label in addition to t or nil.
-The command loop will call it with zero arguments before returning.
+*** Use 'keymap-set-after' instead of 'define-key-after'.
+++
-** New error symbol 'minibuffer-quit'.
-Signaling it has almost the same effect as 'quit' except that it
-doesn't cause keyboard macro termination.
-
----
-*** The command 'cperl-set-style' offers the new value "PBP".
-This value customizes Emacs to use the style recommended in Damian
-Conway's book "Perl Best Practices" for indentation and formatting
-of conditionals.
-
-** Abbrev mode
+*** Use 'keymap-lookup' instead of 'lookup-keymap' and 'key-binding'.
+++
-*** Emacs can now suggest to use an abbrev based on text you type.
-A new user option, 'abbrev-suggest', enables the new abbrev suggestion
-feature. When enabled, if a user manually types a piece of text that
-could have saved enough typing by using an abbrev, a hint will be
-displayed in the echo area, mentioning the abbrev that could have been
-used instead.
-
-** Octave Mode
+*** Use 'keymap-local-lookup' instead of 'local-key-binding'.
+++
-*** Line continuations in double-quoted strings now use a backslash.
-Typing 'C-M-j' (bound to 'octave-indent-new-comment-line') now follows
-the behavior introduced in Octave 3.8 of using a backslash as a line
-continuation marker within double-quoted strings, and an ellipsis
-everywhere else.
-
-** Repeat
+*** Use 'keymap-global-lookup' instead of 'global-key-binding'.
+++
-*** New transient mode 'repeat-mode' to allow shorter key sequences.
-You can type 'C-x u u' instead of 'C-x u C-x u' to undo many changes,
-'C-x o o' instead of 'C-x o C-x o' to switch several windows,
-'C-x { { } } ^ ^ v v' to resize the selected window interactively,
-'M-g n n p p' to navigate next-error matches. Any other key exits
-transient mode and then is executed normally. 'repeat-exit-key'
-defines an additional key to exit mode like 'isearch-exit' ('RET').
-The user option 'repeat-exit-timeout' specifies the number of
-seconds of idle time to break the repetition chain automatically.
-With 'repeat-keep-prefix' you can keep the prefix arg of the previous
-command. For example, this can help to reverse the window navigation
-direction with e.g. 'C-x o M-- o o'. Also it can help to set a new
-step with e.g. 'C-x { C-5 { { {', which will set the window resizing
-step to 5 columns.
+*** 'define-key' now takes an optional REMOVE argument.
+If non-nil, remove the definition from the keymap. This is subtly
+different from setting a definition to nil (when the keymap has a
+parent).
+++
-** EasyPG
-GPG key servers can now be queried for keys with the
-'M-x epa-search-keys' command. Keys can then be added to your
-personal key ring.
-
-** So Long
-
----
-*** New 'so-long-predicate' function 'so-long-statistics-excessive-p'
-efficiently detects the presence of a long line anywhere in the buffer
-using 'buffer-line-statistics' (see above). This is now the default
-predicate (replacing 'so-long-detected-long-line-p').
-
----
-*** 'so-long-threshold' and 'so-long-max-lines' have been raised to
-10000 bytes and 500 lines respectively, to reduce the likelihood of
-false-positives when 'global-so-long-mode' is enabled. The latter
-value is now only used by the old predicate, as the new predicate
-knows the longest line in the entire buffer.
-
----
-*** 'so-long-target-modes' now includes 'fundamental-mode' by default,
-meaning that 'global-so-long-mode' will also process files which were
-not recognised. (This only has an effect if 'set-auto-mode' chooses
-'fundamental-mode'; buffers which are simply in 'fundamental-mode' by
-default are unaffected.)
-
----
-*** New user options 'so-long-mode-preserved-minor-modes' and
-'so-long-mode-preserved-variables' allow specified mode and variable
-states to be maintained if 'so-long-mode' replaces the original major
-mode. By default, these new options support 'view-mode'.
-
-
-* New Modes and Packages in Emacs 28.1
-
-** Lisp Data mode
-The new command 'lisp-data-mode' enables a major mode for buffers
-composed of Lisp symbolic expressions that do not form a computer
-program. The ".dir-locals.el" file is automatically set to use this
-mode, as are other data files produced by Emacs.
-
-** hierarchy.el
-It's a library to create, query, navigate and display hierarchy structures.
-
-** New themes 'modus-vivendi' and 'modus-operandi'.
-These themes are designed to conform with the highest standard for
-color-contrast accessibility (WCAG AAA). You can load either of them
-using 'M-x customize-themes' or 'load-theme' from your init file.
-Consult the Modus Themes Info manual for more information on the user
-options they provide.
-
-** Dictionary mode
-This is a mode for searching a RFC 2229 dictionary server.
-'dictionary' opens a buffer for starting operations.
-'dictionary-search' performs a lookup for a word. It also supports a
-'dictionary-tooltip-mode' which performs a lookup of the word under
-the mouse in 'dictionary-tooltip-dictionary' (which must be customized
-first).
-
-** transient.el
-
-This library implements support for powerful keyboard-driven menus.
-Such menus can be used as simple visual command dispatchers. More
-complex menus take advantage of infix arguments, which are somewhat
-similar to prefix arguments, but are more flexible and discoverable.
-
-
-* Incompatible Editing Changes in Emacs 28.1
-
-** 'electric-indent-mode' now also indents inside strings and comments,
-(unless the indentation function doesn't, of course).
-To recover the previous behavior you can use:
-
- (add-hook 'electric-indent-functions
- (lambda (_) (if (nth 8 (syntax-ppss)) 'no-indent)))
-
-** The 'M-o' ('facemenu-keymap') global binding has been removed.
-To restore the old binding, say something like:
-
- (require 'facemenu)
- (define-key global-map "\M-o" 'facemenu-keymap)
- (define-key facemenu-keymap "\es" 'center-line)
- (define-key facemenu-keymap "\eS" 'center-paragraph)
-
-The last two lines are not strictly necessary if you don't care about
-having those two commands on the 'M-o' keymap; see the next section.
-
-** The 'M-o M-s' and 'M-o M-S' global bindings have been removed.
-Use 'M-x center-line' and 'M-x center-paragraph' instead. See the
-previous section for how to get back the old bindings. Alternatively,
-if you only want these two commands to have global bindings they had
-before, you can add the following to your init file:
-
- (define-key global-map "\M-o\M-s" 'center-line)
- (define-key global-map "\M-o\M-S" 'center-paragraph)
-
-** The 'M-o M-o' global binding has been removed.
-Use 'M-x font-lock-fontify-block' instead, or the new 'C-x x f'
-command, which updates the syntax highlighting in the current buffer.
-
-** In 'f90-mode', the backslash character ('\') no longer escapes.
-For about a decade, the backslash character has no longer had a
-special escape syntax in Fortran F90. To get the old behavior back,
-say something like:
-
- (modify-syntax-entry ?\\ "\\" f90-mode-syntax-table)
-
-** In 'nroff-mode', 'center-line' is now bound to 'M-o M-s'.
-The original key binding was 'M-s', which interfered with I-search,
-since the latter uses 'M-s' as a prefix key of the search prefix map.
-
-** 'vc-print-branch-log' shows the change log for BRANCH from its root
-directory instead of the default directory.
+*** New function 'key-valid-p'.
+The 'kbd' function is quite permissive, and will try to return
+something usable even if the syntax of the argument isn't completely
+correct. The 'key-valid-p' predicate does a stricter check of the
+syntax.
---
-** 'project-shell' and 'shell' now use 'pop-to-buffer-same-window'.
-This is to keep the same behavior as Eshell.
-
-
-* Incompatible Lisp Changes in Emacs 28.1
+*** New function 'key-parse'.
+This is like 'kbd', but only returns vectors instead of a mix of
+vectors and strings.
+++
-** 'overlays-in' now handles zero-length overlays slightly differently.
-Previosly, zero-length overlays at the end of the buffer were included
-in the result (if the region queried for stopped at that position).
-The same was not the case if the buffer had been narrowed to exclude
-the real end of the buffer. This has now been changed, and
-zero-length overlays at `point-max' are always included in the results.
-
----
-** 'replace-match' now runs modification hooks slightly later.
-The function is documented to leave point after the replacement text,
-but this was not always the case if a modification hook inserted text
-in front of the replaced text -- 'replace-match' would instead leave
-point where the end of the inserted text would have been before the
-hook ran. 'replace-match' now always leaves point after the
-replacement text.
-
----
-** 'kill-all-local-variables' has changed how it handles non-symbol hooks.
-The function is documented to eliminate all buffer-local bindings
-except variables with a 'permanent-local' property, or hooks that
-have elements with a 'permanent-local-hook' property. In addition, it
-would also keep lambda expressions in hooks sometimes. The latter has
-now been changed: The function will now also remove these.
-
----
-** Some floating-point numbers are now handled differently by the Lisp reader.
-In previous versions of Emacs, numbers with a trailing dot and an exponent
-were read as integers and the exponent ignored: 2.e6 was interpreted as the
-integer 2. Such numerals are now read as floats with the exponent included:
-2.e6 is now read as the floating-point value 2000000.0.
-That is, '(read-from-string "1.e3")' => '(1000.0 . 4)' now.
+** New substitution in docstrings and 'substitute-command-keys'.
+Use \\`KEYSEQ' to insert a literal key sequence "KEYSEQ" (for example
+\\`C-k') in a docstring or when calling 'substitute-command-keys',
+which will use the same face as a command substitution. This should
+be used only when a key sequence has no corresponding command, for
+example when it is read directly with 'read-key-sequence'. It must be
+a valid key sequence according to 'key-valid-p'.
+++
-** The 'lexical-binding' local variable is always enabled.
-Previously, if 'enable-local-variables' was nil, a 'lexical-binding'
-local variable would not be heeded. This has now changed, and a file
-with a 'lexical-binding' cookie is always heeded. To revert to the
-old behavior, set 'permanently-enabled-local-variables' to nil.
+** New function 'file-name-split'.
+This returns a list of all the components of a file name.
+++
-** 'completing-read-default' sets completion variables buffer-locally.
-'minibuffer-completion-table' and related variables are now set buffer-locally
-in the minibuffer instead of being set via a global let-binding.
+** New macro 'with-undo-amalgamate'.
+It records a particular sequence of operations as a single undo step.
+++
-** The use of positional arguments in 'define-minor-mode' is obsolete.
-These were actually rendered obsolete in Emacs 21 but were never
-marked as such.
-
-** 'facemenu-color-alist' is now obsolete, and is not used.
-
-** 'facemenu.el' is no longer preloaded.
-To use functions/variables from the package, you now have to say
-'(require 'facemenu)' or similar.
-
-** 'pcomplete-ignore-case' is now an obsolete alias of 'completion-ignore-case'.
-
-** 'completions-annotations' face is not used when the caller puts own face.
-This affects the suffix specified by completion 'annotation-function'.
-
-** 'set-process-buffer' now updates the process mark.
-The mark will be set to point to the end of the new buffer.
+** New command 'yank-media'.
+This command supports yanking non-plain-text media like images and
+HTML from other applications into Emacs. It is only supported in
+modes that have registered support for it, and only on capable
+platforms.
+++
-** An active minibuffer now has major mode 'minibuffer-mode', not the
-erroneous 'minibuffer-inactive-mode' it formerly had.
+** New command 'yank-media-types'.
+This command lets you examine all data in the current selection and
+the clipboard, and insert it into the buffer.
+++
-** Some properties from completion tables are now preserved.
-If 'minibuffer-allow-text-properties' is non-nil, doing completion
-over a table of strings with properties will no longer remove all the
-properties before returning. This affects things like 'completing-read'.
-
-** 'equal' no longer examines some contents of window configurations.
-Instead, it considers window configurations to be equal only if they
-are 'eq'. To compare contents, use 'compare-window-configurations'
-instead. This change helps fix a bug in 'sxhash-equal', which returned
-incorrect hashes for window configurations and some other objects.
-
-** When its first argument is a string, 'make-text-button' no longer
-modifies the string's text properties; instead, it uses and returns
-a copy of the string. This helps avoid trouble when strings are
-shared or constants.
+** New text property 'inhibit-isearch'.
+If set, 'isearch' will skip these areas, which can be useful (for
+instance) when covering huge amounts of data (that has no meaningful
+searchable data, like image data) with a 'display' text property.
+++
-** Temporary buffers no longer run certain buffer hooks.
-The macros 'with-temp-buffer' and 'with-temp-file' no longer run the
-hooks 'kill-buffer-hook', 'kill-buffer-query-functions', and
-'buffer-list-update-hook' for the temporary buffers they create. This
-avoids slowing them down when a lot of these hooks are defined.
-
-** New face 'child-frame-border' and frame parameter 'child-frame-border-width'.
-The face and width of child frames borders can now be determined
-separately from those of normal frames. To minimize backward
-incompatibility, child frames without a 'child-frame-border-width'
-parameter will fall back to using 'internal-border-width'. However,
-the new 'child-frame-border' face does constitute a breaking change
-since child frames' borders no longer use the 'internal-border' face.
+** 'insert-image' now takes an INHIBIT-ISEARCH optional parameter.
+It marks the image with the 'inhibit-isearch' text property, which
+inhibits 'isearch' matching the STRING parameter.
---
-** The obsolete function 'thread-alive-p' has been removed.
-
-** 'dns-query' now consistently uses Lisp integers to represent integers.
-Formerly it made an exception for integer components of SOA records,
-because SOA serial numbers can exceed fixnum ranges on 32-bit platforms.
-Emacs now supports bignums so this old glitch is no longer needed.
+** New user option 'pp-use-max-width'.
+If non-nil, 'pp' will attempt to limit the line length when formatting
+long lists and vectors.
---
-** The new function 'dns-query-asynchronous' has been added.
-It takes the same parameters as 'dns-query', but adds a callback
-parameter.
-
-** The Lisp variables 'previous-system-messages-locale' and
-'previous-system-time-locale' have been removed, as they were created
-by mistake and were not useful to Lisp code.
-
----
-** The 'load-dangerous-libraries' variable is now obsolete.
-It was used to allow loading Lisp libraries compiled by XEmacs, a
-modified version of Emacs which is no longer actively maintained.
-This is no longer supported, and setting this variable has no effect.
+** New function 'pp-emacs-lisp-code'.
+'pp' formats general Lisp sexps. This function does much the same,
+but applies formatting rules appropriate for Emacs Lisp code.
+++
-** The macro 'with-displayed-buffer-window' is now obsolete.
-Use macro 'with-current-buffer-window' with action alist entry 'body-function'.
-
----
-** The inversion.el library is now obsolete.
-
----
-** The metamail.el library is now obsolete.
-
----
-** Some obsolete variable and function aliases in dbus.el have been removed.
-In Emacs 24.3, the variable 'dbus-event-error-hooks' was renamed to
-'dbus-event-error-functions' and the function
-'dbus-call-method-non-blocking' was renamed to 'dbus-call-method'.
-The old names, which were kept as obsolete aliases of the new names,
-have now been removed.
-
----
-** Some libraries obsolete since Emacs 23 have been removed:
-ledit.el, lmenu.el, lucid.el and old-whitespace.el.
-
----
-** Some functions and variables obsolete since Emacs 23 have been removed:
-'GOLD-map', 'advertised-xscheme-send-previous-expression',
-'allout-init', 'bookmark-jump-noselect',
-'bookmark-read-annotation-text-func', 'buffer-menu-mode-hook',
-'c-forward-into-nomenclature', 'char-coding-system-table',
-'char-valid-p', 'charset-bytes', 'charset-id', 'charset-list',
-'choose-completion-delete-max-match', 'complete-in-turn',
-'completion-base-size', 'completion-common-substring',
-'crm-minibuffer-complete', 'crm-minibuffer-complete-and-exit',
-'crm-minibuffer-completion-help', 'custom-mode', 'custom-mode-hook',
-'define-key-rebound-commands', 'define-mode-overload-implementation',
-'detect-coding-with-priority', 'dirtrack-debug',
-'dirtrack-debug-toggle', 'dynamic-completion-table',
-'easy-menu-precalculate-equivalent-keybindings',
-'epa-display-verify-result', 'epg-passphrase-callback-function',
-'erc-announced-server-name', 'erc-default-coding-system',
-'erc-process', 'erc-send-command', 'eshell-report-bug',
-'eval-next-after-load', 'exchange-dot-and-mark', 'ffap-bug',
-'ffap-submit-bug', 'ffap-version', 'file-cache-mouse-choose-completion',
-'forward-point', 'generic-char-p', 'global-highlight-changes',
-'hi-lock-face-history', 'hi-lock-regexp-history',
-'highlight-changes-active-string', 'highlight-changes-initial-state',
-'highlight-changes-passive-string',
-'icalendar--datetime-to-noneuropean-date', 'image-mode-maybe',
-'imenu-example--name-and-position', 'ispell-aspell-supports-utf8',
-'lisp-mode-auto-fill', 'locate-file-completion', 'make-coding-system',
-'menu-bar-files-menu', 'minibuffer-local-must-match-filename-map',
-'mouse-choose-completion', 'mouse-major-mode-menu',
-'mouse-popup-menubar', 'mouse-popup-menubar-stuff',
-'newsticker-groups-filename', 'nnir-swish-e-index-file',
-'nnmail-fix-eudora-headers', 'non-iso-charset-alist',
-'nonascii-insert-offset', 'nonascii-translation-table',
-'password-read-and-add', 'pre-abbrev-expand-hook', 'princ-list',
-'print-help-return-message', 'process-filter-multibyte-p',
-'read-file-name-predicate', 'remember-buffer', 'rmail-highlight-face',
-'rmail-message-filter', 'semantic-after-idle-scheduler-reparse-hooks',
-'semantic-after-toplevel-bovinate-hook',
-'semantic-before-idle-scheduler-reparse-hooks',
-'semantic-before-toplevel-bovination-hook',
-'semantic-bovinate-from-nonterminal-full',
-'semantic-bovinate-region-until-error', 'semantic-bovinate-toplevel',
-'semantic-bovination-working-type',
-'semantic-decorate-pending-decoration-hooks',
-'semantic-edits-incremental-reparse-failed-hooks',
-'semantic-eldoc-current-symbol-info', 'semantic-expand-nonterminal',
-'semantic-file-token-stream', 'semantic-find-dependency',
-'semantic-find-nonterminal', 'semantic-flex', 'semantic-flex-buffer',
-'semantic-flex-keyword-get', 'semantic-flex-keyword-p',
-'semantic-flex-keyword-put', 'semantic-flex-keywords',
-'semantic-flex-list', 'semantic-flex-make-keyword-table',
-'semantic-flex-map-keywords', 'semantic-flex-token-end',
-'semantic-flex-token-start', 'semantic-flex-token-text',
-'semantic-imenu-bucketize-type-parts',
-'semantic-imenu-expand-type-parts', 'semantic-imenu-expandable-token',
-'semantic-init-db-hooks', 'semantic-init-hooks',
-'semantic-init-mode-hooks', 'semantic-java-prototype-nonterminal',
-'semantic-nonterminal-abstract', 'semantic-nonterminal-full-name',
-'semantic-nonterminal-leaf', 'semantic-nonterminal-protection',
-'semantic-something-to-stream', 'semantic-tag-make-assoc-list',
-'semantic-token-type-parent', 'semantic-toplevel-bovine-cache',
-'semantic-toplevel-bovine-table', 'semanticdb-mode-hooks',
-'set-coding-priority', 'set-process-filter-multibyte',
-'shadows-compare-text-p', 'shell-dirtrack-toggle',
-'speedbar-navigating-speed', 'speedbar-update-speed', 't-mouse-mode',
-'term-dynamic-simple-complete', 'tooltip-hook', 'tpu-have-ispell',
-'url-generate-unique-filename', 'url-temporary-directory',
-'vc-arch-command', 'vc-default-working-revision' (variable),
-'vc-mtn-command', 'vc-revert-buffer', 'vc-workfile-version',
-'vcursor-toggle-vcursor-map', 'w32-focus-frame', 'w32-select-font',
-'wisent-lex-make-token-table'.
-
----
-** Some functions and variables obsolete since Emacs 22 have been removed:
-'gnus-article-hide-pgp-hook', 'gnus-inews-mark-gcc-as-read',
-'gnus-treat-display-xface', 'gnus-treat-strip-pgp',
-'nnmail-spool-file'.
-
-** The WHEN argument of 'make-obsolete' and related functions is mandatory.
-The use of those functions without a WHEN argument was marked obsolete
-back in Emacs 23.1. The affected functions are: 'make-obsolete',
-'define-obsolete-function-alias', 'make-obsolete-variable',
-'define-obsolete-variable-alias'.
-
-** The variable 'keyboard-type' is obsolete and not dynamically scoped any more.
-
-** The 'values' variable is now obsolete.
-
-+++
-** The '&define' keyword in an Edebug specification now disables backtracking.
-The implementation was buggy, and multiple '&define' forms in an '&or'
-form should be exceedingly rare. See the Info node "(elisp) Backtracking" in
-the Emacs Lisp reference manual for background.
-
----
-** 'sql-*-statement-starters' are no longer user options.
-These variables describe facts about the SQL standard and
-product-specific additions. There should be no need for users to
-customize them.
-
----
-** Function 'lm-maintainer' is replaced with 'lm-maintainers'.
-The former is now declared obsolete.
-
-
-* Lisp Changes in Emacs 28.1
-
-+++
-*** New function 'file-name-concat'.
-This appends file name components to a directory name and returns the
-result.
+** New function 'file-has-changed-p'.
+This convenience function is useful when writing code that parses
+files at run-time, and allows Lisp programs to re-parse files only
+when they have changed.
+++
-*** New function 'split-string-shell-command'.
-This splits a shell command string into separate components,
-respecting quoting with single ('like this') and double ("like this")
-quotes, as well as backslash quoting (like\ this).
+** 'abbreviate-file-name' now respects magic file name handlers.
---
-*** ':safe' settings in 'defcustom' are now propagated to the loaddefs files.
+** New function 'font-has-char-p'.
+This can be used to check whether a specific font has a glyph for a
+character.
+++
-** New function 'syntax-class-to-char'.
-This does almost the opposite of 'string-to-syntax' -- it returns the
-syntax descriptor (a character) given a raw syntax descriptor (an
-integer).
-
-+++
-** New function 'buffer-local-boundp'.
-This predicate says whether a symbol is bound in a specific buffer.
-
----
-** Emacs now attempts to test for high-rate subprocess output more fairly.
-When several subprocesses produce output simultaneously at high rate,
-Emacs will now by default attempt to service them all in a round-robin
-fashion. Set the new variable 'process-prioritize-lower-fds' to a
-non-nil value to get back the old behavior, whereby after reading
-from a subprocess, Emacs would check for output of other subprocesses
-in a way that is likely to read from the same process again.
+** 'window-text-pixel-size' now accepts a new argument 'ignore-line-at-end'.
+This controls whether or not the last screen line of the text being
+measured will be counted for the purpose of calculating the text
+dimensions.
-+++
-** New function 'sxhash-equal-including-properties'.
-This is identical to 'sxhash-equal' but accounting also for string
-properties.
-
-+++
-** 'unlock-buffer' displays warnings instead of signaling.
-Instead of signaling 'file-error' conditions for file system level
-errors, the function now calls 'display-warning' and continues as if
-the error did not occur.
-
-+++
-** New function 'always'.
-This is identical to 'ignore', but returns t instead.
-
-+++
-** New forms to declare how completion should happen has been added.
-'(declare (completion PREDICATE))' can be used as a general predicate
-to say whether the command should be present when completing with
-'M-x TAB'. '(declare (modes MODE...))' can be used as a short-hand
-way of saying that the command should be present when completing from
-buffers in major modes derived from MODE..., or, if it's a minor mode,
-whether that minor mode is enabled in the current buffer.
-
-+++
-** The 'interactive' syntax has been extended to allow listing applicable modes.
-Forms like '(interactive "p" dired-mode)' can be used to annotate the
-commands as being applicable for modes derived from 'dired-mode',
-or if the mode is a minor mode, that the current buffer has that
-minor mode activated. Note that using this form will create byte code
-that is not compatible with byte code in previous Emacs versions.
-
-+++
-** New buffer-local variable 'local-minor-modes'.
-This permanently buffer-local variable holds a list of currently
-enabled non-global minor modes in the current buffer (as a list of
-symbols).
-
-+++
-** New variable 'global-minor-modes'.
-This variable holds a list of currently enabled global minor modes (as
-a list of symbols).
+** XDG support
-+++
-** 'define-minor-mode' now takes an ':interactive' argument.
-This can be used for specifying which modes this minor mode is meant
-for, or to make the new minor mode non-interactive. The default value
-is t.
+*** 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
+between (application) restarts, but that is not important or portable
+enough to the user that it should be stored in $XDG_DATA_HOME".
+++
-** 'define-derived-mode' now takes an ':interactive' argument.
-This can be used to control whether the defined mode is a command
-or not, and is useful when defining commands that aren't meant to be
-used by users directly.
-
----
-** The 'easymenu' library is now preloaded.
+** New macro 'with-delayed-message'.
+This macro is like 'progn', but will output the specified message if
+the body takes longer to execute than the specified timeout.
---
-** New variable 'indent-line-ignored-functions'.
-This allows modes to cycle through a set of indentation functions
-appropriate for those modes.
-
-** New function 'garbage-collect-maybe' to trigger GC early.
-
----
-** 'defvar' detects the error of defining a variable currently lexically bound.
-Such mixes are always signs that the outer lexical binding was an
-error and should have used dynamic binding instead.
-
-+++
-** New completion function 'affixation-function' to add prefix/suffix.
-It accepts a list of completions and should return a list where
-each element is a list with three elements: a completion,
-a prefix string, and a suffix string.
-
-+++
-** New completion function 'group-function' for grouping candidates.
-It takes two arguments: a completion candidate and a 'transform' flag.
+** New function 'funcall-with-delayed-message'.
+This function is like 'funcall', but will output the specified message
+if the function takes longer to execute than the specified timeout.
-+++
-** 'read-char-from-minibuffer' and 'y-or-n-p' support 'help-form'.
-If you bind 'help-form' to a non-nil value while calling these functions,
-then pressing 'C-h' ('help-char') causes the function to evaluate 'help-form'
-and display the result.
+** Locale
---
-** New variables 'read-char-choice-use-read-key' and 'y-or-n-p-use-read-key'.
-When non-nil, then functions 'read-char-choice' and 'y-or-n-p' (respectively)
-use the function 'read-key' to read a character instead of using the minibuffer.
+*** New variable 'current-locale-environment'.
+This holds the value of the previous call to 'set-locale-environment'.
---
-** New user option 'use-short-answers'.
-When non-nil, the function 'y-or-n-p' is used instead of
-'yes-or-no-p'. This eliminates the need to define an alias that maps
-one to another in the init file. The same user option also controls
-whether the function 'read-answer' accepts short answers.
+*** New macro 'with-locale-environment'.
+This macro can be used to change the locale temporarily while
+executing code.
-+++
-** 'set-window-configuration' now takes two optional parameters,
-'dont-set-frame' and 'dont-set-miniwindow'. The first of these, when
-non-nil, instructs the function not to select the frame recorded in
-the configuration. The second prevents the current minibuffer being
-replaced by the one stored in the configuration.
-
-+++
-** 'define-globalized-minor-mode' now takes a ':predicate' parameter.
-This can be used to control which major modes the minor mode should be
-used in.
+** Tabulated List Mode
+++
-** 'truncate-string-ellipsis' now uses '…' by default.
-Modes that use 'truncate-string-to-width' with non-nil, non-string
-argument ELLIPSIS, will now indicate truncation using '…' when
-the selected frame can display it, and using "..." otherwise.
+*** A column can now be set to an image descriptor.
+The 'tabulated-list-entries' variable now supports using an image
+descriptor, which means to insert an image in that column instead of
+text. See the documentation string of that variable for details.
+++
-** 'string-width' now accepts two optional arguments FROM and TO.
-This allows calculating the width of a substring without consing a
-new string.
+** :keys in 'menu-item' can now be a function.
+If so, it is called whenever the menu is computed, and can be used to
+calculate the keys dynamically.
+++
-** New command 'make-directory-autoloads'.
-This does the same as the old command 'update-directory-autoloads',
-but has different semantics: Instead of passing in the output file via
-the dynamically bound 'generated-autoload-file' variable, the output
-file is now a explicit parameter.
+** New major mode 'clean-mode'.
+This is a new major mode meant for debugging. It kills absolutely all
+local variables and removes overlays and text properties.
+++
-** New function 'string-search'.
-This function takes two string parameters and returns the position of
-the first instance of the former string in the latter.
+** 'kill-all-local-variables' can now kill all local variables.
+If given the new optional KILL-PERMANENT argument, also kill permanent
+local variables.
+++
-** New function 'string-replace'.
-This function works along the line of 'replace-regexp-in-string', but
-matching on strings instead of regexps, and does not change the global
-match state.
-
-+++
-** New function 'process-lines-ignore-status'.
-This is like 'process-lines', but does not signal an error if the
-return status is non-zero. 'process-lines-handling-status' has also
-been added, and takes a callback to handle the return status.
+** Third 'mapconcat' argument SEPARATOR is now optional.
+An explicit nil always meant the empty string, now it can be left out.
---
-** 'ascii' is now a coding system alias for 'us-ascii'.
-
-+++
-** New function 'file-name-with-extension'.
-This function allows a canonical way to set/replace the extension of a
-file name.
+** Themes can now be made obsolete.
+Using 'make-obsolete' on a theme is now supported. This will make
+'load-theme' issue a warning when loading the theme.
+++
-** New function 'file-backup-file-names'.
-This function returns the list of file names of all the backup files
-of its file argument.
+** New function 'define-keymap'.
+This function allows defining a number of keystrokes with one form.
+++
-** New utility function 'directory-empty-p'.
-This predicate tests whether a given file name is an accessible
-directory and whether it contains no other directories or files.
-
-+++
-** 'directory-files' now takes an additional COUNT parameter.
-The parameter makes 'directory-files' return COUNT first file names
-from a directory. If MATCH is also given, the function will return
-first COUNT file names that match the expression. The same COUNT
-parameter has been added to 'directory-files-and-attributes'.
-
-+++
-** The 'count-lines' function now takes an optional parameter to
-ignore invisible lines.
-
----
-** 'count-words' now crosses field boundaries.
-Originally, 'count-words' would stop counting at the first field
-boundary it encountered; now it keeps counting all the way to the
-region's (or buffer's) end.
+** New macro 'defvar-keymap'.
+This macro allows defining keymap variables more conveniently.
---
-** New function 'custom-add-choice'.
-This function can be used by modes to add elements to the
-'choice' customization type of a variable.
-
-+++
-** New function 'require-theme'.
-This function is like 'require', but searches 'custom-theme-load-path'
-instead of 'load-path'. It can be used by Custom themes to load
-supporting Lisp files when 'require' is unsuitable.
-
-+++
-** New function 'file-modes-number-to-symbolic' to convert a numeric
-file mode specification into symbolic form.
-
-** New macro 'dlet' to dynamically bind variables.
-
-** The variable 'force-new-style-backquotes' has been removed.
-This removes the final remaining trace of old-style backquotes.
-
-** Mode Lines
+** 'kbd' can now be used in built-in, preloaded libraries.
+It no longer depends on edmacro.el and cl-lib.el.
+++
-*** New user options to control the line/column numbers in the mode line.
-'mode-line-position-line-format' is the line number format (when
-'line-number-mode' is on), 'mode-line-position-column-format' is
-the column number format (when 'column-number-mode' is on), and
-'mode-line-position-column-line-format' is the combined format (when
-both modes are on).
+** New function 'image-at-point-p'.
+This function returns t if point is on a valid image, and nil
+otherwise.
+++
-*** New user option 'mode-line-compact'.
-If non-nil, repeating spaces are compressed into a single space. If
-'long', this is only done when the mode line is longer than the
-current window width (in characters).
+** 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
+aren't integer multiples of the default font.
+++
-*** 'global-mode-string' constructs should end with a space.
-This was previously not formalized, which led to combinations of modes
-displaying data "smushed together" on the mode line.
-
-** Changes in handling dynamic modules
-
-*** The module header 'emacs-module.h' now contains type aliases
-'emacs_function' and 'emacs_finalizer' for module functions and
-finalizers, respectively.
-
-*** Module functions can now be made interactive.
-Use 'make_interactive' to give a module function an interactive
-specification.
-
-*** Module functions can now install an optional finalizer that is
-called when the function object is garbage-collected. Use
-'set_function_finalizer' to set the finalizer and
-'get_function_finalizer' to retrieve it.
-
-*** Modules can now open a channel to an existing pipe process using
-the new module function 'open_channel'. Modules can use this
-functionality to asynchronously send data back to Emacs.
-
-*** A new module API 'make_unibyte_string' is provided.
-It can be used to create Lisp strings with arbitrary byte sequences
-(a.k.a. "raw bytes").
-
-** 'file-modes', 'set-file-modes', and 'set-file-times' now have an
-optional argument specifying whether to follow symbolic links.
-
-** 'parse-time-string' can now parse ISO 8601 format strings,
-such as "2020-01-15T16:12:21-08:00".
+** New function 'string-glyph-split'.
+This function splits a string into a list of strings representing
+separate glyphs. This takes into account combining characters and
+grapheme clusters.
---
-** The new function 'decoded-time-period' has been added.
-It interprets a decoded time structure as a period and returns the
-equivalent period in seconds.
+** 'lookup-key' is more permissive when searching for extended menu items.
+In Emacs 28.1, the behavior of 'lookup-key' was changed: when looking
+for a menu item '[menu-bar Foo-Bar]', first try to find an exact
+match, then look for the lowercased '[menu-bar foo-bar]'.
-+++
-** The new function 'dom-remove-attribute' has been added.
+This has been extended, so that when looking for a menu item with a
+symbol containing spaces, as in '[menu-bar Foo\ Bar]', first look for
+an exact match, then the lowercased '[menu-bar foo\ bar]' and finally
+'[menu-bar foo-bar]'. This further improves backwards-compatibility
+when converting menus to use 'easy-menu-define'.
-+++
-** The new function 'dom-print' has been added.
-
----
-** 'make-network-process', 'make-serial-process' ':coding' behavior change.
-Previously, passing ':coding nil' to either of these functions would
-override any non-nil binding for 'coding-system-for-read' and
-'coding-system-for-write'. For consistency with 'make-process' and
-'make-pipe-process', passing ':coding nil' is now ignored. No code in
-Emacs depended on the previous behavior; if you really want the
-process' coding-system to be nil, use 'set-process-coding-system'
-after the process has been created, or pass in ':coding '(nil nil)'.
+** xwidgets
+++
-** 'open-network-stream' now accepts a ':coding' argument.
-This allows specifying the coding systems used by a network process
-for encoding and decoding without having to bind
-'coding-system-for-{read,write}' or call 'set-process-coding-system'.
+*** The function 'make-xwidget' now accepts an optional RELATED argument.
+This argument is used as another widget for the newly created WebKit
+widget to share settings and subprocesses with. It must be another
+WebKit widget.
+++
-** 'open-network-stream' can now take a ':capability-command' that's a function.
-The function is called with the greeting from the server as its only
-parameter, and allows sending different TLS capability commands to the
-server based on that greeting.
+*** New function 'xwidget-perform-lispy-event'.
+This function allows you to send events to xwidgets. Usually, some
+equivalent of the event will be sent, but there is no guarantee of
+what the widget will actually receive.
-+++
-** 'open-gnutls-stream' now also accepts a ':coding' argument.
+On GTK+, only key and function key events are implemented.
+++
-** New user option 'process-file-return-signal-string'.
-It controls, whether 'process-file' returns a string when a remote
-process is interrupted by a signal.
+*** New function 'xwidget-webkit-load-html'.
+This function is used to load HTML text into WebKit xwidgets
+directly, in contrast to creating a temporary file to hold the
+markup, and passing the URI of the file as an argument to
+'xwidget-webkit-goto-uri'.
+++
-** The behavior of 'format-spec' is now closer to that of 'format'.
-In order for the two functions to behave more consistently,
-'format-spec' now pads and truncates based on string width rather than
-length, and also supports format specifications that include a
-truncating precision field, such as "%.2a".
+*** New functions for performing searches on WebKit xwidgets.
+Some new functions, such as 'xwidget-webkit-search', have been added
+for performing searches on WebKit xwidgets.
+++
-** 'format-spec' now takes an optional SPLIT parameter.
-If non-nil, 'format-spec' will split the resulting string into a list
-of strings, based on where the format specs (and expansions) were.
-
----
-** New function 'color-values-from-color-spec'.
-This can be used to parse RGB color specs in several formats and
-convert them to a list '(R G B)' of primary color values.
-
----
-** User option 'uniquify-buffer-name-style' can now be a function.
-This user option can be one of the predefined styles or a function to
-personalize the uniquified buffer name.
+*** New function 'xwidget-webkit-back-forward-list'.
+This function is used to obtain the history of page-loads in a given
+WebKit xwidget.
+++
-** New variable 'tty-menu-calls-mouse-position-function'.
-This controls whether 'mouse-position-function' is called by functions
-that retrieve the mouse position when that happens during TTY menu
-handling. Lisp programs that set 'mouse-position-function' should
-also set this variable non-nil if they are compatible with the tty
-menu handling.
+*** New function 'xwidget-webkit-estimated-load-progress'.
+This function is used to obtain the estimated progress of page loading
+in a given WebKit xwidget.
+++
-** 'inhibit-nul-byte-detection' is renamed to 'inhibit-null-byte-detection'.
-
-** Byte compiler
-
-+++
-*** New byte-compiler check for missing dynamic variable declarations.
-It is meant as an (experimental) aid for converting Emacs Lisp code
-to lexical binding, where dynamic (special) variables bound in one
-file can affect code in another. For details, see the manual section
-"(elisp) Converting to Lexical Binding".
-
-+++
-*** 'byte-recompile-directory' can now compile symlinked ".el" files.
-This is achieved by giving a non-nil FOLLOW-SYMLINKS parameter.
-
-*** The byte-compiler now warns about too wide documentation strings.
-By default, it will warn if a documentation string is wider than the
-largest of 80 characters or 'fill-column'. This is controlled by the
-new user option 'byte-compile-docstring-max-column'.
+*** New function 'xwidget-webkit-stop-loading'.
+This function is used to terminate all data transfer during page loads
+in a given WebKit xwidget.
+++
-*** 'byte-compile-file' optional argument LOAD is now obsolete.
-To load the file after byte-compiling, add a call to 'load' from Lisp
-or use 'M-x emacs-lisp-byte-compile-and-load' interactively.
-
----
-** 'unload-feature' now also tries to undo additions to buffer-local hooks.
-
----
-** Some functions are no longer considered safe by 'unsafep':
-'replace-regexp-in-string', 'catch', 'throw', 'error', 'signal'
-and 'play-sound-file'.
+*** 'load-changed' xwidget events are now more detailed.
+In particular, they can now have different arguments based on the
+state of the WebKit widget. 'load-finished' is sent when a load has
+completed, 'load-started' when a load first starts, 'load-redirected'
+after a redirect, and 'load-committed' when the WebKit widget first
+commits to the load.
+++
-** New variable 'print-integers-as-characters' modifies integer printing.
-If this variable is non-nil, character syntax is used for printing
-numbers when this makes sense, such as '?A' for 65.
+*** New event type 'xwidget-display-event'.
+These events are sent whenever an xwidget requests that Emacs display
+another xwidget. The only arguments to this event are the xwidget
+that should be displayed, and the xwidget that asked to display it.
+++
-** New error 'remote-file-error', a subcategory of 'file-error'.
-It is signaled if a remote file operation fails due to internal
-reasons, and could block Emacs. It does not replace 'file-error'
-signals for the usual cases. Timers, process filters and process
-functions, which run remote file operations, shall protect themselves
-against this error.
+*** New function 'xwidget-webkit-set-cookie-storage-file'.
+This function is used to control where and if an xwidget stores
+cookies set by web pages on disk.
-If such an error occurs, please report this as bug via 'M-x report-emacs-bug'.
-Until it is solved you could ignore such errors by performing
-
- (setq debug-ignored-errors (cons 'remote-file-error debug-ignored-errors))
-
-+++
-** The error 'ftp-error' belongs also to category 'remote-file-error'.
+** New variable 'help-buffer-under-preparation'.
+This variable is bound to t during the preparation of a "*Help*" buffer.
+++
-** Buffers can now be created with certain hooks disabled.
-The functions 'get-buffer-create' and 'generate-new-buffer' accept a
-new optional argument INHIBIT-BUFFER-HOOKS. If non-nil, the new
-buffer does not run the hooks 'kill-buffer-hook',
-'kill-buffer-query-functions', and 'buffer-list-update-hook'. This
-avoids slowing down internal or temporary buffers that are never
-presented to users or passed on to other applications.
-
----
-** 'start-process-shell-command' and 'start-file-process-shell-command'
-do not support the old calling conventions any longer.
-
-** Functions operating on local file names now check that the file names
-don't contain any NUL bytes. This avoids subtle bugs caused by
-silently using only the part of the file name until the first NUL byte.
-
-** New coding-systems for EBCDIC variants.
-New coding-systems 'ibm256', 'ibm273', 'ibm274', 'ibm277', 'ibm278',
-'ibm280', 'ibm281', 'ibm284', 'ibm285', 'ibm290', 'ibm297'. These are
-variants of the EBCDIC encoding tailored to some European and Japanese
-locales. They are also available as aliases 'ebcdic-cp-*' (e.g.,
-'ebcdic-cp-fi' for the Finnish variant 'ibm278'), and 'cp2xx' (e.g.,
-'cp278' for 'ibm278'). There are also new charsets 'ibm2xx' to
-support these coding-systems.
-
----
-** 'while-no-input-ignore-events' accepts more special events.
-The special events 'dbus-event' and 'file-notify' are now ignored in
-'while-no-input' when added to this variable.
+** Timestamps like (1 . 1000) now work without warnings being generated.
+For example, (time-add nil '(1 . 1000)) no longer warns that the
+(1 . 1000) acts like (1000 . 1000000). This warning, which was a
+temporary transition aid for Emacs 27, has served its purpose.
+++
-** 'condition-case' now allows for a success handler.
-It is written as '(:success BODY...)' where BODY is executed
-whenever the protected form terminates without error, with the
-specified variable bound to the the value of the protected form.
+** 'date-to-time' now assumes earliest values if its argument lacks
+month, day, or time. For example, (date-to-time "2021-12-04") now
+assumes a time of 00:00 instead of signaling an error.
+++
-** 'The 'uniquify' argument in 'auto-save-file-name-transforms' can be a symbol.
-If this symbol is one of the members of 'secure-hash-algorithms',
-Emacs constructs the nondirectory part of the auto-save file name by
-applying that 'secure-hash' to the buffer file name. This avoids any
-risk of excessively long file names.
-
----
-** New user option 'etags-xref-prefer-current-file'.
-When non-nil, matches for identifiers in the file visited by the
-current buffer will be shown first in the "*xref*" buffer.
+** New events for taking advantage of touchscreen devices.
+The events 'touchscreen-begin, 'touchscreen-update', and
+'touchscreen-end' have been added to take better advantage of
+touch-capable display panels.
-* Changes in Emacs 28.1 on Non-Free Operating Systems
-
----
-** On macOS, Xwidget is now supported.
-If Emacs was built with xwidget support, you can access the embedded
-webkit browser with 'M-x xwidget-webkit-browse-url'. Viewing two
-instances of xwidget webkit is not supported.
-
-*** Downloading files from xwidget-webkit is now supported.
-The new variable 'xwidget-webkit-download-dir' says where to download to.
+* Changes in Emacs 29.1 on Non-Free Operating Systems
-*** New functions for xwidget-webkit mode
-'xwidget-webkit-clone-and-split-below',
-'xwidget-webkit-clone-and-split-right'.
-
-*** New variable 'xwidget-webkit-enable-plugins'.
-
-+++
-** On macOS, Emacs can now load dynamic modules with a ".dylib" suffix.
-'module-file-suffix' now has the value ".dylib" on macOS, but the
-".so" suffix is supported as well.
+** MS-Windows
+++
-** On MS-Windows, Emacs can now toggle the IME.
-A new function 'w32-set-ime-open-status' can now be used to disable
-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 MS-Windows, Emacs can now use the native image API to display images.
-Emacs can now use the MS-Windows GDI+ library to load and display
-images in JPEG, PNG, GIF and TIFF formats. This support is enabled
-unless Emacs was configured '--without-native-image-api'.
-
-This feature is experimental, and needs to be turned on to be used.
-To turn this on, set the variable 'w32-use-native-image-API' to a
-non-nil value. Please report any bugs you find while using the native
-image API via 'M-x report-emacs-bug'.
-
----
-** The user option 'make-pointer-invisible' is now honored on macOS.
-
---
-** 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-`'.
+*** Emacs now supports system dark mode.
+On Windows 10 (version 1809 and higher) and Windows 11, Emacs will now
+follow the system's dark mode: GUI frames use the appropriate light or
+dark title bar and scroll bars, based on the user's Windows-wide color
+settings.
----------------------------------------------------------------------
diff --git a/etc/NEWS.28 b/etc/NEWS.28
new file mode 100644
index 00000000000..e7d72159023
--- /dev/null
+++ b/etc/NEWS.28
@@ -0,0 +1,4603 @@
+GNU Emacs NEWS -- history of user-visible changes.
+
+Copyright (C) 2019-2021 Free Software Foundation, Inc.
+See the end of the file for license conditions.
+
+Please send Emacs bug reports to 'bug-gnu-emacs@gnu.org'.
+If possible, use 'M-x report-emacs-bug'.
+
+This file is about changes in Emacs version 28.
+
+See file HISTORY for a list of GNU Emacs versions and release dates.
+See files NEWS.27, NEWS.26, ..., NEWS.18, and NEWS.1-17 for changes
+in older Emacs versions.
+
+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'.
+
+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.
+
+
+* Installation Changes in Emacs 28.1
+
+** Emacs now optionally supports native compilation of Lisp files.
+To enable this, configure Emacs with the '--with-native-compilation' option.
+This requires the libgccjit library to be installed and functional,
+and also requires GCC and Binutils to be available when Lisp code is
+natively compiled. See the Info node "(elisp) Native Compilation" for
+more details.
+
+If you build Emacs with native compilation, but without zlib, be sure
+to configure with the '--without-compress-install' option, so that the
+installed *.el files are not compressed; otherwise, you will not be
+able to use JIT native compilation of the installed *.el files.
+
+Note that JIT native compilation is done in a fresh session of Emacs
+that is run in a subprocess, so it can legitimately report some
+warnings and errors that aren't uncovered by byte-compilation. We
+recommend examining any such warnings before you decide they are
+false.
+
+** The Cairo graphics library is now used by default if present.
+'--with-cairo' is now the default, if the appropriate development files
+are found by 'configure'. Note that building with Cairo means using
+Pango instead of libXFT for font support. Since Pango 1.44 has
+removed support for bitmapped fonts, this may require you to adjust
+your font settings.
+
+Note also that 'FontBackend' settings in ".Xdefaults" or
+".Xresources", or 'font-backend' frame parameter settings in your init
+files, may need to be adjusted, as 'xft' is no longer a valid backend
+when using Cairo. Use 'ftcrhb' if your Emacs was built with HarfBuzz
+text shaping support, and 'ftcr' otherwise. You can determine this by
+checking 'system-configuration-features'. The 'ftcr' backend will
+still be available when HarfBuzz is supported, but will not be used by
+default. We strongly recommend building with HarfBuzz support. 'x' is
+still a valid backend.
+
+---
+** 'configure' now warns about building with libXft support.
+libXft is unmaintained, and causes a number of problems with modern
+fonts including but not limited to crashes; support for it may be
+removed in a future version of Emacs. Please consider using
+Cairo + HarfBuzz instead.
+
+---
+** 'configure' now warns about not using HarfBuzz if using Cairo.
+We want to encourage people to use the most modern font features
+available, and this is the Cairo graphics library + HarfBuzz for font
+shaping, so 'configure' now recommends that combination.
+
+---
+** Building without double buffering support.
+'configure --with-xdbe=no' can now be used to disable double buffering
+at build time.
+
+---
+** Support for building with Motif has been removed.
+
+---
+** The configure option '--without-makeinfo' has been removed.
+This was only ever relevant when building from a repository checkout.
+This now requires makeinfo, which is part of the texinfo package.
+
+---
+** New configure option '--disable-year2038'.
+This causes Emacs to use only 32-bit time_t on platforms that have
+both 32- and 64-bit time_t. This may help when linking Emacs with a
+library with an ABI requiring traditional 32-bit time_t. This option
+currently affects only 32-bit ARM and x86 running GNU/Linux with glibc
+2.34 and later. Emacs now defaults to 64-bit time_t on these
+platforms.
+
+---
+** Support for building with '-fcheck-pointer-bounds' has been removed.
+GCC has withdrawn the '-fcheck-pointer-bounds' option and support for
+its implementation has been removed from the Linux kernel.
+
+---
+** The ftx font backend driver has been removed.
+It was declared obsolete in Emacs 27.1.
+
+---
+** Emacs no longer supports old OpenBSD systems.
+OpenBSD 5.3 and older releases are no longer supported, as they lack
+proper pty support that Emacs needs.
+
+
+* Startup Changes in Emacs 28.1
+
+---
+** In GTK builds, Emacs now supports startup notification.
+This means that Emacs won't steal keyboard focus upon startup
+(when started via the Desktop) if the user is typing into another
+application.
+
+---
+** Errors in 'kill-emacs-hook' no longer prevent Emacs from shutting down.
+If a function in that hook signals an error in an interactive Emacs,
+the user will be prompted on whether to continue. If the user doesn't
+answer within five seconds, Emacs will continue shutting down anyway.
+
+** Emacs now supports loading a Secure Computing filter.
+This is supported only on capable GNU/Linux systems. To activate,
+invoke Emacs with the '--seccomp=FILE' command-line option. FILE must
+name a binary file containing an array of 'struct sock_filter'
+structures. Emacs will then install that list of Secure Computing
+filters into its own process early during the startup process. You
+can use this functionality to put an Emacs process in a sandbox to
+avoid security issues when executing untrusted code. See the manual
+page for 'seccomp' system call, for details about Secure Computing
+filters.
+
+** Emacs can support 24-bit color TTY without terminfo database.
+If your text-mode terminal supports 24-bit true color, but your system
+lacks the terminfo database, you can instruct Emacs to support 24-bit
+true color by setting 'COLORTERM=truecolor' in the environment. This is
+useful on systems such as FreeBSD which ships only with "etc/termcap".
+
+---
+** File names given on the command line are now be pushed onto history.
+The file names will be pushed onto 'file-name-history', like the names
+of files visited via 'C-x C-f' and other commands.
+
+
+* Changes in Emacs 28.1
+
+---
+** Emacs now supports Unicode Standard version 14.0.
+
++++
+** Improved support for Emoji.
+On capable systems, Emacs now correctly displays Emoji and Emoji
+sequences by default, provided that a suitable font is available to
+Emacs. With a few exceptions, all of the Emoji sequences specified by
+Unicode 14.0 are automatically composed and displayed as a single
+colorful glyph. This is achieved by changes in the Emacs font
+configuration, and by additional character-composition rules for the
+Emoji codepoints that follow from the Unicode-defined sequences.
+
+If your system lacks a suitable font, we recommend to install "Noto
+Color Emoji"; Emacs will use it automatically if it's installed. If
+you prefer to use another font for Emoji, customize your fontset like
+this:
+
+ (set-fontset-font t 'emoji
+ '("My New Emoji Font" . "iso10646-1") nil 'prepend)
+
+The Emoji characters are now assigned to a special script, 'emoji', so
+as to make it easier to customize fontsets for Emoji display, as in
+the above example. (Previously, the Emoji characters were assigned to
+the 'symbol' script, together with other symbol and punctuation
+characters.)
+
++++
+** 'glyphless-char-display-control' now applies to Variation Selectors.
+VS-1 through VS-16 are now displayed as 'thin-space' by default when
+not composed with previous characters (typically, as part of Emoji
+sequences).
+
++++
+** New command 'execute-extended-command-for-buffer'.
+This new command, bound to 'M-S-x', works like
+'execute-extended-command', but limits the set of commands to the
+commands that have been determined to be particularly useful with the
+current mode.
+
++++
+** New user option 'read-extended-command-predicate'.
+This user option controls how 'M-x' performs completion of commands when
+you type 'TAB'. By default, any command that matches what you have
+typed is considered a completion candidate, but you can customize this
+option to exclude commands that are not applicable to the current
+buffer's major and minor modes, and respect the command's completion
+predicate (if any).
+
++++
+** Completion on 'M-x' shows key bindings for commands.
+When 'suggest-key-bindings' is non-nil (as it is by default), the
+completion list popped up by 'M-x' shows the key bindings for all the
+commands shown in the list of candidate completions that have a key
+binding.
+
++++
+** New user option 'completions-detailed'.
+When non-nil, some commands like 'describe-symbol' show more detailed
+completions with more information in completion prefix and suffix.
+The default is nil.
+
+---
+** 'C-s' in 'M-x' now once again searches over completions.
+In Emacs 23, typing 'M-x' ('read-extended-command') and then 'C-s' (to
+do an interactive search) would search over possible completions.
+This was lost in Emacs 24, but is now back again.
+
++++
+** User option 'completions-format' supports a new value 'one-column'.
+
++++
+** New system for displaying documentation for groups of functions.
+This can either be used by saying 'M-x shortdoc-display-group' and
+choosing a group, or clicking a button in the "*Help*" buffers when
+looking at the doc string of a function that belongs to one of these
+groups.
+
++++
+** New minor mode 'context-menu-mode' for context menus popped by 'mouse-3'.
+When this mode is enabled, clicking 'down-mouse-3' (usually, the
+right mouse button) anywhere in the buffer pops up a menu whose
+contents depends on surrounding context near the mouse click.
+You can change the order of the default sub-menus in the context menu
+by customizing the user option 'context-menu-functions'. You can also
+invoke the context menu by pressing 'S-<F10>' or, on macOS, by
+clicking 'C-down-mouse-1'.
+
++++
+** A new keymap for buffer actions has been added.
+The 'C-x x' keymap now holds keystrokes for various buffer-oriented
+commands. The new keystrokes are 'C-x x g' ('revert-buffer-quick'),
+'C-x x r' ('rename-buffer'), 'C-x x u' ('rename-uniquely'), 'C-x x n'
+('clone-buffer'), 'C-x x i' ('insert-buffer'), 'C-x x t'
+('toggle-truncate-lines') and 'C-x x f' ('font-lock-update').
+
++++
+** Modifiers now go outside angle brackets in pretty-printed key bindings.
+For example, 'RET' with Control and Meta modifiers is now shown as
+'C-M-<return>' instead of '<C-M-return>'. Either variant can be used
+as input; functions such as 'kbd' and 'read-kbd-macro' accept both
+styles as equivalent (they have done so for a long time).
+
+---
+** 'eval-expression' no longer signals an error on incomplete expressions.
+Previously, typing 'M-: ( RET' would result in Emacs saying "End of
+file during parsing" and dropping out of the minibuffer. The user
+would have to type 'M-: M-p' to edit and redo the expression. Now
+Emacs will echo the message and allow the user to continue editing.
+
++++
+** 'eval-last-sexp' now handles 'defvar'/'defcustom'/'defface' specially.
+This command would previously not redefine values defined by these
+forms, but this command has now been changed to work more like
+'eval-defun', and reset the values as specified.
+
+---
+** New user option 'use-short-answers'.
+When non-nil, the function 'y-or-n-p' is used instead of
+'yes-or-no-p'. This eliminates the need to define an alias that maps
+one to another in the init file. The same user option also controls
+whether the function 'read-answer' accepts short answers.
+
++++
+** New user option 'kill-buffer-delete-auto-save-files'.
+If non-nil, killing a buffer that has an auto-save file will prompt
+the user for whether that auto-save file should be deleted. (Note
+that 'delete-auto-save-files', if non-nil, was previously documented
+to result in deletion of auto-save files when killing a buffer without
+unsaved changes, but this has apparently not worked for several
+decades, so the documented semantics of this variable has been changed
+to match the behavior.)
+
++++
+** New user option 'next-error-message-highlight'.
+In addition to a fringe arrow, 'next-error' error may now optionally
+highlight the current error message in the 'next-error' buffer.
+This user option can be also customized to keep highlighting on all
+visited errors, so you can have an overview what errors were already visited.
+
+---
+** New choice 'next-error-quit-window' for 'next-error-found-function'.
+When 'next-error-found-function' is customized to 'next-error-quit-window',
+then typing the numeric prefix argument 0 before the command 'next-error'
+will quit the source window after visiting the next occurrence.
+
++++
+** New user option 'file-preserve-symlinks-on-save'.
+This controls what Emacs does when saving buffers that visit files via
+symbolic links, and 'file-precious-flag' is non-nil.
+
++++
+** New user option 'copy-directory-create-symlink'.
+If non-nil, will make 'copy-directory' (when used on a symbolic
+link) copy the link instead of following the link. The default is
+nil, so the default behavior is unchanged.
+
++++
+** New user option 'ignored-local-variable-values'.
+This is the opposite of 'safe-local-variable-values' -- it's an alist
+of variable-value pairs that are to be ignored when reading a
+local-variables section of a file.
+
+---
+** Specific warnings can now be disabled from the warning buffer.
+When a warning is displayed to the user, the resulting buffer now has
+buttons which allow making permanent changes to the treatment of that
+warning. Automatic showing of the warning can be disabled (although
+it is still logged to the "*Messages*" buffer), or the warning can be
+disabled entirely.
+
++++
+** ".dir-locals.el" now supports setting 'auto-mode-alist'.
+The new 'auto-mode-alist' specification in ".dir-locals.el" files can
+now be used to override the global 'auto-mode-alist' in the current
+directory tree.
+
+---
+** User option 'uniquify-buffer-name-style' can now be a function.
+This user option can be one of the predefined styles or a function to
+personalize the uniquified buffer name.
+
+---
+** 'remove-hook' is now an interactive command.
+
+---
+** 'expand-file-name' now checks for null bytes in filenames.
+The function will now check for null bytes in both NAME and
+DEFAULT-DIRECTORY arguments, as well as in the 'default-directory'
+buffer-local variable, when its value is used. If null bytes are
+found, 'expand-file-name' will signal an error.
+This means that practically all file-related operations will now check
+file names for null bytes, thus avoiding subtle bugs with silently
+using only the part of file name up to the first null byte.
+
+---
+** Frames
+
++++
+*** The key prefix 'C-x 5 5' displays next command buffer in a new frame.
+It's bound to the command 'other-frame-prefix' that requests the buffer
+of the next command to be displayed in a new frame.
+
++++
+*** New command 'clone-frame' (bound to 'C-x 5 c').
+This is like 'C-x 5 2', but uses the window configuration and frame
+parameters of the current frame instead of 'default-frame-alist'.
+When called interactively with a prefix arg, the window configuration
+is not cloned.
+
+---
+*** Default values of 'frame-title-format' and 'icon-title-format' have changed.
+These variables are used to display the title bar of visible frames
+and the title bar of an iconified frame. They now show the name of
+the current buffer and the text "GNU Emacs" instead of the value of
+'invocation-name'. To get the old behavior back, add the following to
+your init file:
+
+ (setq frame-title-format '(multiple-frames "%b"
+ ("" invocation-name "@" system-name)))
+
++++
+*** New frame parameter 'drag-with-tab-line'.
+This parameter, similar to 'drag-with-header-line', allows moving frames
+by dragging the tab lines of their topmost windows with the mouse.
+
++++
+*** New optional behavior of 'delete-other-frames'.
+When invoked with a prefix argument, 'delete-other-frames' now
+iconifies frames, rather than deleting them.
+
+---
+*** Commands 'set-frame-width' and 'set-frame-height' now prompt for values.
+These commands now prompt for the value via the minibuffer, instead of
+requiring the user to specify the value via the prefix argument.
+
+** Windows
+
++++
+*** The key prefix 'C-x 4 1' displays next command buffer in the same window.
+It's bound to the command 'same-window-prefix' that requests the buffer
+of the next command to be displayed in the same window.
+
++++
+*** The key prefix 'C-x 4 4' displays next command buffer in a new window.
+It's bound to the command 'other-window-prefix' that requests the buffer
+of the next command to be displayed in a new window.
+
++++
+*** New command 'recenter-other-window', bound to 'S-M-C-l'.
+Like 'recenter-top-bottom', but acting on the other window.
+
++++
+*** New user option 'delete-window-choose-selected'.
+This allows specifying how Emacs chooses which window will be the
+frame's selected window after the currently selected window is
+deleted.
+
++++
+*** New argument NO-OTHER for some window functions.
+'get-lru-window', 'get-mru-window' and 'get-largest-window' now accept a
+new optional argument NO-OTHER which, if non-nil, avoids returning a
+window whose 'no-other-window' parameter is non-nil.
+
++++
+*** New 'display-buffer' function 'display-buffer-use-least-recent-window'.
+This is like 'display-buffer-use-some-window', but won't reuse the
+current window, and when called repeatedly will try not to reuse a
+previously selected window.
+
++++
+*** New function 'window-bump-use-time'.
+This updates the use time of a window.
+
+** Minibuffer
+
++++
+*** Minibuffer scrolling is now conservative by default.
+This is controlled by the new variable 'scroll-minibuffer-conservatively'.
+It is t by default; setting it to nil will cause scrolling in the
+minibuffer obey the value of 'scroll-conservatively'.
+
++++
+*** Improved handling of minibuffers on switching frames.
+By default, when you switch to another frame, an active minibuffer now
+moves to the newly selected frame. Nevertheless, the effect of what
+you type in the minibuffer happens in the frame where the minibuffer
+was first activated. An alternative behavior is available by
+customizing 'minibuffer-follows-selected-frame' to nil. Here, the
+minibuffer stays in the frame where you first opened it, and you must
+switch back to this frame to continue or abort its command. The old
+behavior, which mixed these two, can be approximated by customizing
+'minibuffer-follows-selected-frame' to a value which is neither nil
+nor t.
+
++++
+*** New user option 'read-minibuffer-restore-windows'.
+When customized to nil, it uses 'minibuffer-restore-windows' in
+'minibuffer-exit-hook' to remove only the window showing the
+"*Completions*" buffer, but keeps all other windows created
+while the minibuffer was active.
+
+---
+*** New variable 'redisplay-adhoc-scroll-in-resize-mini-windows'.
+Customizing it to nil will disable the ad-hoc auto-scrolling of
+minibuffer text shown in mini-windows when resizing those windows.
+The default heuristics of that scrolling can be counter productive in
+some corner cases, though the cure might be worse than the disease.
+This said, the effect should be negligible in the vast majority of
+cases anyway.
+
+** Mode Line
+
++++
+*** New user option 'mode-line-compact'.
+If non-nil, repeating spaces are compressed into a single space. If
+'long', this is only done when the mode line is longer than the
+current window width (in columns).
+
++++
+*** New user options to control format of line/column numbers in the mode line.
+'mode-line-position-line-format' is the line number format (when
+'line-number-mode' is on), 'mode-line-position-column-format' is
+the column number format (when 'column-number-mode' is on), and
+'mode-line-position-column-line-format' is the combined format (when
+both modes are on).
+
+** Tab Bars and Tab Lines
+
++++
+*** The prefix key 'C-x t t' can be used to display a buffer in a new tab.
+Typing 'C-x t t' before a command will cause the buffer shown by that
+command to be displayed in a new tab. 'C-x t t' is bound to the
+command 'other-tab-prefix'.
+
++++
+*** New command 'C-x t C-r' to open file read-only in the other tab.
+
++++
+*** The tab bar now supports more mouse commands.
+Clicking 'mouse-2' closes the tab, 'mouse-3' displays the context menu
+with items that operate on the clicked tab. Dragging the tab with
+'mouse-1' moves it to another position on the tab bar. Mouse wheel
+scrolling switches to the previous/next tab, and holding the Shift key
+during scrolling moves the tab to the left/right.
+
++++
+*** Frame-specific appearance of the tab bar when 'tab-bar-show' is a number.
+When 'tab-bar-show' is a number, the tab bar on different frames can
+be shown or hidden independently, as determined by the number of tabs
+on each frame compared to the numerical value of 'tab-bar-show'.
+
++++
+*** New command 'toggle-frame-tab-bar'.
+It can be used to enable/disable the tab bar on the currently selected
+frame regardless of the values of 'tab-bar-mode' and 'tab-bar-show'.
+This allows enabling/disabling the tab bar independently on different
+frames.
+
++++
+*** New user option 'tab-bar-format' defines a list of tab bar items.
+When it contains 'tab-bar-format-global' (possibly appended after
+'tab-bar-format-align-right'), then after enabling 'display-time-mode'
+(or any other mode that uses 'global-mode-string') it displays time
+aligned to the right on the tab bar instead of on the mode line.
+When 'tab-bar-format-tabs' is replaced with 'tab-bar-format-tabs-groups',
+the tab bar displays tab groups.
+
++++
+*** New optional key binding for 'tab-last'.
+If you customize the user option 'tab-bar-select-tab-modifiers' to
+allow selecting tabs using their index numbers, the '<MODIFIER>-9' key
+is bound to 'tab-last', and switches to the last tab. Here <MODIFIER>
+is any of the modifiers in the list that is the value of
+'tab-bar-select-tab-modifiers'. You can also use positive indices,
+which count from the last tab: 1 is the last tab, 2 the one before
+that, etc.
+
+---
+*** New command 'tab-duplicate' bound to 'C-x t n'.
+
+---
+*** 'C-x t N' creates a new tab at the specified absolute position.
+The position is provided as prefix arg, and specifies an index that
+starts at 1. Negative values count from the end of the tab bar.
+
+---
+*** 'C-x t M' moves the current tab to the specified absolute position.
+The position is provided as prefix arg, whose interpretation is as in
+'C-x t N'.
+
+---
+*** 'C-x t G' assigns a tab to a named group of tabs.
+'tab-close-group' closes all tabs that belong to the selected group.
+The user option 'tab-bar-new-tab-group' defines the default group of
+new tabs. After customizing 'tab-bar-tab-post-change-group-functions'
+to 'tab-bar-move-tab-to-group', changing the group of a tab will also
+move it closer to other tabs in the same group.
+
+---
+*** New user option 'tab-bar-tab-name-format-function'.
+
+---
+*** New user option 'tab-line-tab-name-format-function'.
+
+---
+*** The tabs in the tab line can now be scrolled using horizontal scroll.
+If your mouse or trackpad supports it, you can now scroll tabs when
+the mouse pointer is in the tab line by scrolling left or right.
+
+---
+*** New tab-line faces and user options.
+The face 'tab-line-tab-special' is used for tabs whose buffers are
+special, i.e. buffers that don't visit a file. The face
+'tab-line-tab-modified' is used to display modified, file-backed
+buffers. The face 'tab-line-tab-inactive-alternate' is used to
+display inactive tabs with an alternating background color, making
+them easier to distinguish, especially if the face 'tab-line-tab' is
+configured to not display with a box; this alternate face is only
+applied when the user option 'tab-line-tab-face-functions' is so
+configured. That option may also be used to customize tab-line faces
+in other ways.
+
+** Mouse wheel
+
+---
+*** Mouse wheel scrolling now defaults to one line at a time.
+
+---
+*** Mouse wheel scrolling now works on more parts of frame's display.
+When using 'mouse-wheel-mode', the mouse wheel will now scroll also when
+the mouse cursor is on the scroll bars, fringes, margins, header line,
+and mode line. ('mouse-wheel-mode' is enabled by default on most graphical
+displays.)
+
++++
+*** Mouse wheel scrolling with Shift modifier now scrolls horizontally.
+This works in text buffers and over images. Typing a numeric prefix arg
+(e.g. 'M-5') before starting horizontal scrolling changes its step value.
+The value is saved in the user option 'mouse-wheel-scroll-amount-horizontal'.
+
+** Customize
+
+---
+*** Customize buffers can now be reverted with 'C-x x g'.
+
+---
+*** Most customize commands now hide obsolete user options.
+Obsolete user options are no longer shown in the listings produced by
+the commands 'customize', 'customize-group', 'customize-apropos' and
+'customize-changed'.
+
+To customize obsolete user options, use 'customize-option' or
+'customize-saved'.
+
+---
+*** New SVG icons for checkboxes and arrows.
+They will be used automatically instead of the old icons. If Emacs is
+built without SVG support, the old icons will be used instead.
+
+** Help
+
+---
+*** The order of things displayed in the "*Help*" buffer has been changed.
+The indented "administrative" block (containing the "probably
+introduced" and "other relevant functions" (and similar things) has
+been moved to after the doc string.
+
++++
+*** New command 'describe-command' shows help for a command.
+This can be used instead of 'describe-function' for interactive
+commands and is globally bound to 'C-h x'.
+
++++
+*** New command 'describe-keymap' describes keybindings in a keymap.
+
+---
+*** New command 'apropos-function'.
+This works like 'C-u M-x apropos-command' but is more discoverable.
+
+---
+*** New keybinding 'C-h R' prompts for an Info manual and displays it.
+
+---
+*** Keybindings in 'help-mode' use the new 'help-key-binding' face.
+This face is added by 'substitute-command-keys' to any "\[command]"
+substitution. The return value of that function should consequently
+be assumed to be a propertized string. To prevent the function from
+adding the 'help-key-binding' face, call 'substitute-command-keys'
+with the new optional argument NO-FACE non-nil.
+
+Note that the new face will also be used in tooltips. When using the
+GTK toolkit, this is only true if 'x-gtk-use-system-tooltips' is t.
+
++++
+*** New user option 'help-enable-symbol-autoload'.
+If non-nil, displaying help for an autoloaded function whose
+'autoload' form provides no documentation string will try to load the
+file it's from. This will give more extensive help for such
+functions.
+
+---
+*** The 'help-for-help' ('C-h C-h') screen has been redesigned.
+
++++
+*** New convenience commands with short keys in the Help buffer.
+New command 'help-view-source' ('s') will view the source file (if
+any) of the current help topic. New command 'help-goto-info' ('i')
+will look up the current symbol (if any) in Info. New command
+'help-customize' ('c') will customize the user option or the face
+(if any) whose doc string is being shown in the Help buffer.
+
+---
+*** New user option 'describe-bindings-outline'.
+It enables outlines in the output buffer of 'describe-bindings' that
+can provide a better overview in a long list of available bindings.
+
++++
+*** New commands to describe buttons and widgets.
+'widget-describe' (on a widget) will pop up a help buffer and give a
+description of the properties. Likewise 'button-describe' does the
+same for a button.
+
+---
+*** Improved "find definition" feature of "*Help*" buffers.
+Now clicking on the link to find the definition of functions generated
+by 'cl-defstruct', or variables generated by 'define-derived-mode',
+for example, will go to the exact place where they are defined.
+
+---
+*** New commands 'apropos-next-symbol' and 'apropos-previous-symbol'.
+These new navigation commands are bound to 'n' and 'p' in
+'apropos-mode'.
+
+---
+*** The command 'view-lossage' can now be invoked from the menu bar.
+The menu bar "Help" menu now has a "Show Recent Inputs" item under the
+"Describe" sub-menu.
+
++++
+*** New command 'lossage-size'.
+It allows users to change the maximum number of keystrokes and
+commands recorded for the purpose of 'view-lossage'.
+
+---
+*** Closing the "*Help*" buffer from the toolbar now buries the buffer.
+In previous Emacs versions, the "*Help*" buffer was killed instead when
+clicking the "X" icon in the tool bar.
+
+---
+*** 'g' ('revert-buffer') in 'help-mode' no longer requires confirmation.
+
+** File Locks
+
++++
+*** New user option 'lock-file-name-transforms'.
+This option allows controlling where lock files are written. It uses
+the same syntax as 'auto-save-file-name-transforms'.
+
++++
+*** New user option 'remote-file-name-inhibit-locks'.
+When non-nil, this option suppresses lock files for remote files.
+Default is nil.
+
++++
+*** New minor mode 'lock-file-mode'.
+This command, called interactively, toggles the local value of
+'create-lockfiles' in the current buffer.
+
+** Emacs Server
+
++++
+*** New user option 'server-client-instructions'.
+When emacsclient connects, Emacs will (by default) output a message
+about how to exit the client frame. If 'server-client-instructions'
+is set to nil, this message is inhibited.
+
++++
+*** New command 'server-edit-abort'.
+This command (not bound to any key by default) can be used to abort
+an edit instead of marking it as "Done" (which the 'C-x #' command
+does). The 'emacsclient' program exits with an abnormal status as
+result of this command.
+
++++
+*** New desktop integration for connecting to the server.
+If your operating system’s desktop environment is
+freedesktop.org-compatible (which is true of most GNU/Linux and other
+recent Unix-like desktops), you may use the new "Emacs (Client)"
+desktop menu entry to open files in an existing Emacs instance rather
+than starting a new one. The daemon starts if it is not already
+running.
+
+** Miscellaneous
+
++++
+*** New command 'font-lock-update', bound to 'C-x x f'.
+This command updates the syntax highlighting in this buffer.
+
++++
+*** New command 'memory-report'.
+This command opens a new buffer called "*Memory Report*" and gives a
+summary of where Emacs is using memory currently.
+
++++
+*** New command 'submit-emacs-patch'.
+This works like 'report-emacs-bug', but is more geared towards sending
+patches to the Emacs issue tracker.
+
+---
+*** New face 'apropos-button'.
+Applies to buttons that indicate a face.
+
++++
+*** New face 'font-lock-doc-markup-face'.
+Intended for documentation mark-up syntax and tags inside text that
+uses 'font-lock-doc-face', which it should appropriately stand out
+against and harmonize with. It would typically be used in structured
+documentation comments in program source code by language-specific
+modes, for mark-up conventions like Haddock, Javadoc or Doxygen. By
+default this face inherits from 'font-lock-constant-face'.
+
++++
+*** New face box style 'flat-button'.
+This is a plain 2D button, but uses the background color instead of
+the foreground color.
+
+---
+*** New faces 'shortdoc-heading' and 'shortdoc-section'.
+Applied to shortdoc headings and sections.
+
+---
+*** New face 'separator-line'.
+This is used by 'make-separator-line' (see below).
+
++++
+*** 'redisplay-skip-fontification-on-input' helps Emacs keep up with fast input.
+This is another attempt to solve the problem of handling high key repeat rate
+and other "slow scrolling" situations. It is hoped it behaves better
+than 'fast-but-imprecise-scrolling' and 'jit-lock-defer-time'.
+It is not enabled by default.
+
+---
+*** Obsolete aliases are no longer hidden from command completion.
+Completion of command names now considers obsolete aliases as
+candidates, if they were marked obsolete in the current major version
+of Emacs. Invoking a command via an obsolete alias now mentions the
+obsolescence fact and shows the new name of the command.
+
++++
+*** Support for '(box . SIZE)' 'cursor-type'.
+By default, 'box' cursor always has a filled box shape. But if you
+specify 'cursor-type' to be '(box . SIZE)', the cursor becomes a hollow
+box if the point is on an image larger than SIZE pixels in any
+dimension.
+
++++
+*** The user can now customize how "default" values are prompted for.
+The new utility function 'format-prompt' has been added which uses the
+new 'minibuffer-default-prompt-format' user option to format "default"
+prompts. This means that prompts that look like "Enter a number
+(default 10)" can be customized to look like, for instance, "Enter a
+number [10]", or not have the default displayed at all, like "Enter a
+number". (This only affects callers that were altered to use
+'format-prompt'.)
+
+---
+*** New help window when Emacs prompts before opening a large file.
+Commands like 'find-file' or 'visit-tags-table' ask to visit a file
+normally or literally when the file is larger than a certain size (by
+default, 9.5 MiB). Press '?' or 'C-h' in that prompt to read more
+about the different options to visit a file, how you can disable the
+prompt, and how you can tweak the file size threshold.
+
++++
+*** Emacs now defaults to UTF-8 instead of ISO-8859-1.
+This is only for the default, where the user has set no 'LANG' (or
+similar) variable or environment. This change should lead to no
+user-visible changes for normal usage.
+
+---
+*** 'global-display-fill-column-indicator-mode' skips some buffers.
+By default, turning on 'global-display-fill-column-indicator-mode'
+doesn't turn on 'display-fill-column-indicator-mode' in special-mode
+buffers. This can be controlled by customizing the user option
+'global-display-fill-column-indicator-modes'.
+
++++
+*** 'nobreak-char-display' now also affects all non-ASCII space characters.
+Previously, this was limited only to 'NO-BREAK SPACE' and hyphen
+characters. Now it also covers the rest of the non-ASCII Unicode
+space characters. Also, unlike in previous versions of Emacs, the
+non-ASCII characters are displayed as themselves when
+'nobreak-char-display' is t, i.e. they are not replaced on display
+with the ASCII space and hyphen characters.
+
+---
+*** New backward compatibility variable 'nobreak-char-ascii-display'.
+This variable is nil by default, and non-ASCII space and hyphen
+characters are displayed as themselves, even if 'nobreak-char-display'
+is non-nil. If 'nobreak-char-ascii-display' is set to a non-nil
+value, the non-ASCII space and hyphen characters are instead displayed
+as their ASCII counterparts: spaces and ASCII hyphen (a.k.a. "dash")
+characters. This provides backward compatibility feature for the
+change described above, where the non-ASCII characters are no longer
+replaced with their ASCII counterparts when 'nobreak-char-display' is
+t. You may need this on text-mode terminals that produce messed up
+display when non-ASCII spaces and hyphens are written to the display.
+(This variable is only effective when 'nobreak-char-display' is t.)
+
++++
+*** Improved support for terminal emulators that encode the Meta flag.
+Some terminal emulators set the 8th bit of Meta characters, and then
+encode the resulting character code as if it were non-ASCII character
+above codepoint 127. Previously, the only way of using these in Emacs
+was to set up the terminal emulator to use the 'ESC' characters to send
+Meta characters to Emacs, e.g., send "ESC x" when the user types
+'M-x'. You can now avoid the need for this setup of such terminal
+emulators by using the new input-meta-mode with the special value
+'encoded' with these terminal emulators.
+
+---
+*** 'auto-composition-mode' can now be selectively disabled on some TTYs.
+Some text-mode terminals produce display glitches trying to compose
+characters. The 'auto-composition-mode' can now have a string value
+that names a terminal type; if the value returned by the 'tty-type'
+function compares equal with that string, automatic composition will
+be disabled in windows shown on that terminal. The Linux terminal
+sets this up by default.
+
+---
+*** Support for the 'strike-through' face attribute on TTY frames.
+If your terminal's termcap or terminfo database entry has the 'smxx'
+capability defined, Emacs will now emit the prescribed escape
+sequences necessary to render faces with the 'strike-through'
+attribute on TTY frames.
+
+---
+*** TTY menu navigation is now supported in 'xterm-mouse-mode'.
+TTY menus support mouse navigation and selection when 'xterm-mouse-mode'
+is active. When run on a terminal, clicking on the menu bar with the
+mouse now pops up a TTY menu by default instead of running the command
+'tmm-menubar'. To restore the old behavior, set the user option
+'tty-menu-open-use-tmm' to non-nil.
+
+---
+*** 'M-x report-emacs-bug' will no longer include "Recent messages" section.
+These were taken from the "*Messages*" buffer, and may inadvertently
+leak information from the reporting user.
+
+---
+*** 'C-u M-x dig' will now prompt for a query type to use.
+
+---
+*** Rudimentary support for the 'st' terminal emulator.
+Emacs now supports 256 color display on the 'st' terminal emulator.
+
++++
+*** Update IRC-related references to point to Libera.Chat.
+The Free Software Foundation and the GNU Project have moved their
+official IRC channels from the Freenode network to Libera.Chat. For the
+original announcement and the follow-up update, including more details,
+see:
+
+https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00005.html
+https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00007.html
+
+Given the relocation of GNU and FSF's official IRC channels, as well
+as #emacs and various other Emacs-themed channels (see the link below)
+to Libera.Chat, IRC-related references in the Emacs repository have
+now been updated to point to Libera.Chat.
+
+https://lists.gnu.org/archive/html/info-gnu-emacs/2021-06/msg00000.html
+
+
+* Incompatible Editing Changes in Emacs 28.1
+
+---
+** 'toggle-truncate-lines' now disables 'visual-line-mode'.
+This is for symmetry with 'visual-line-mode', which disables
+'truncate-lines'.
+
+---
+** 'electric-indent-mode' now also indents inside strings and comments.
+(This only happens when indentation function also supports this.)
+
+To recover the previous behavior you can use:
+
+ (add-hook 'electric-indent-functions
+ (lambda (_) (if (nth 8 (syntax-ppss)) 'no-indent)))
+
+---
+** The 'M-o' ('facemenu-keymap') global binding has been removed.
+To restore the old binding, say something like:
+
+ (require 'facemenu)
+ (define-key global-map "\M-o" 'facemenu-keymap)
+ (define-key facemenu-keymap "\es" 'center-line)
+ (define-key facemenu-keymap "\eS" 'center-paragraph)
+
+The last two lines are not strictly necessary if you don't care about
+having those two commands on the 'M-o' keymap; see the next section.
+
+---
+** The 'M-o M-s' and 'M-o M-S' global bindings have been removed.
+Use 'M-x center-line' and 'M-x center-paragraph' instead. See the
+previous section for how to get back the old bindings. Alternatively,
+if you only want these two commands to have the global bindings they
+had before, you can add the following to your init file:
+
+ (define-key global-map "\M-o\M-s" 'center-line)
+ (define-key global-map "\M-o\M-S" 'center-paragraph)
+
+---
+** The 'M-o M-o' global binding has been removed.
+Use 'M-x font-lock-fontify-block' instead, or the new 'C-x x f'
+command, which updates the syntax highlighting in the current buffer.
+
+---
+** The escape sequence '\e[29~' in Xterm is now mapped to 'menu'.
+Xterm sends this sequence for both 'F16' and 'Menu' keys
+It used to be mapped to 'print' but we couldn't find a terminal
+that uses this sequence for any kind of 'Print' key.
+This makes the Menu key (see https://en.wikipedia.org/wiki/Menu_key)
+work for 'context-menu-mode' in Xterm.
+
+---
+** New user option 'xterm-store-paste-on-kill-ring'.
+If non-nil (the default), Emacs pushes pasted text onto the kill ring
+(if using an xterm-like terminal that supports bracketed paste).
+Setting this to nil inhibits that.
+
+---
+** 'vc-print-branch-log' shows the change log from its root directory.
+It previously used to use the default directory.
+
+---
+** 'project-shell' and 'shell' now use 'pop-to-buffer-same-window'.
+This is to keep the same behavior as Eshell.
+
+---
+** In 'nroff-mode', 'center-line' is no longer bound to a key.
+The original key binding was 'M-s', which interfered with I-search,
+since the latter uses 'M-s' as a prefix key of the search prefix map.
+
+---
+** In 'f90-mode', the backslash character ('\') no longer escapes.
+For about a decade, the backslash character has no longer had a
+special escape syntax in Fortran F90. To get the old behavior back,
+say something like:
+
+ (modify-syntax-entry ?\\ "\\" f90-mode-syntax-table)
+
++++
+** Setting 'fill-column' to nil is obsolete.
+This undocumented use of 'fill-column' is now obsolete. To disable
+auto filling, turn off 'auto-fill-mode' instead.
+
+For instance, you could add something like the following to your init
+file:
+
+ (add-hook 'foo-mode-hook (lambda () (auto-fill-mode -1))
+
+
+* Editing Changes in Emacs 28.1
+
+** Input methods
+
++++
+*** Emacs now supports "transient" input methods.
+A transient input method is enabled for inserting a single character,
+and is then automatically disabled. 'C-x \' temporarily enables the
+selected transient input method. Use 'C-u C-x \' to select a
+transient input method (which can be different from the input method
+enabled by 'C-\'). For example, 'C-u C-x \ compose RET' selects the
+'compose' input method; then typing 'C-x \ 1 2' will insert the
+character '½', and disable the 'compose' input method afterwards.
+You can use 'C-x \' in incremental search to insert a single character
+to the search string.
+
+---
+*** New input method 'compose' based on X Multi_key sequences.
+
+---
+*** New input method 'iso-transl' with the same keys as 'C-x 8'.
+After selecting it as a transient input method with 'C-u C-x \
+iso-transl RET', it supports the same key sequences as 'C-x 8',
+so e.g. like 'C-x 8 [' inserts a left single quotation mark,
+'C-x \ [' does the same.
+
+---
+*** New user option 'read-char-by-name-sort'.
+It defines the sorting order of characters for completion of 'C-x 8 RET TAB'
+and can be customized to sort them by codepoints instead of character names.
+Additionally, you can group characters by Unicode blocks after customizing
+'completions-group' and 'completions-group-sort'.
+
+---
+*** Improved language transliteration in Malayalam input methods.
+Added a new Mozhi scheme. The inapplicable ITRANS scheme is now
+deprecated. Errors in the Inscript method were corrected.
+
+---
+*** New input method 'cham'.
+There's also a Cham greeting in "etc/HELLO".
+
+---
+*** New input methods for Lakota language orthographies.
+Two orthographies are represented here, the Suggested Lakota
+Orthography and what is known as the White Hat Orthography. Input
+methods 'lakota-slo-prefix', 'lakota-slo-postfix', and
+'lakota-white-hat-postfix' have been added. There is also a Lakota
+greeting in "etc/HELLO".
+
++++
+** Standalone 'M-y' allows interactive selection from previous kills.
+'M-y' can now be typed after a command that is not a yank command.
+When invoked like that, it prompts in the minibuffer for one of the
+previous kills, offering completion and minibuffer-history navigation
+through previous kills recorded in the kill ring. A similar feature
+in Isearch can be invoked if you bind 'C-s M-y' to the command
+'isearch-yank-pop'. When the user option 'yank-from-kill-ring-rotate'
+is nil the kill ring is not rotated after 'yank-from-kill-ring'.
+
++++
+** New user option 'word-wrap-by-category'.
+When word-wrap is enabled, and this option is non-nil, that allows
+Emacs to break lines after more characters than just whitespace
+characters. In particular, this significantly improves word-wrapping
+for CJK text mixed with Latin text.
+
++++
+** New command 'undo-redo'.
+It undoes previous undo commands, but doesn't record itself as an
+undoable command. It is bound to 'C-?' and 'C-M-_', the first binding
+works well in graphical mode, and the second one is easy to hit on tty.
+
+For full conventional undo/redo behavior, you can also customize the
+user option 'undo-no-redo' to t.
+
++++
+** New commands 'copy-matching-lines' and 'kill-matching-lines'.
+These commands are similar to the command 'flush-lines',
+but add the matching lines to the kill ring as a single string,
+including the newlines that separate the lines.
+
++++
+** New user option 'kill-transform-function'.
+This can be used to transform (and suppress) strings from entering the
+kill ring.
+
++++
+** 'save-interprogram-paste-before-kill' can now be a number.
+In that case, it's interpreted as a limit on the size of the clipboard
+data that will be saved to the 'kill-ring' prior to killing text: if
+the size of the clipboard data is greater than or equal to the limit,
+it will not be saved.
+
++++
+** New user option 'tab-first-completion'.
+If 'tab-always-indent' is 'complete', this new user option can be used to
+further tweak whether to complete or indent.
+
+---
+** 'indent-tabs-mode' is now a global minor mode instead of just a variable.
+
++++
+** New choice 'permanent' for 'shift-select-mode'.
+When the mark was activated by shifted motion keys, non-shifted motion
+keys don't deactivate the mark after customizing 'shift-select-mode'
+to 'permanent'. Similarly, the active mark will not be deactivated by
+typing shifted motion keys.
+
++++
+** The "Edit => Clear" menu item now obeys a rectangular region.
+
++++
+** New command 'revert-buffer-with-fine-grain'.
+Revert a buffer trying to be as non-destructive as possible,
+preserving markers, properties and overlays. The new variable
+'revert-buffer-with-fine-grain-max-seconds' specifies the maximum
+number of seconds that 'revert-buffer-with-fine-grain' should spend
+trying to be non-destructive, with a default value of 2 seconds.
+
++++
+** New command 'revert-buffer-quick'.
+This is bound to 'C-x x g' and is like 'revert-buffer', but prompts
+less.
+
++++
+** New user option 'revert-buffer-quick-short-answers'.
+This controls how the new 'revert-buffer-quick' ('C-x x g') command
+prompts. A non-nil value will make it use 'y-or-n-p' rather than
+'yes-or-no-p'. Defaults to nil.
+
++++
+** New user option 'query-about-changed-file'.
+If non-nil (the default), Emacs prompts as before when re-visiting a
+file that has changed externally after it was visited the first time.
+If nil, Emacs does not prompt, but instead shows the buffer with its
+contents before the change, and provides instructions how to revert
+the buffer.
+
+---
+** New value 'save-some-buffers-root' of 'save-some-buffers-default-predicate'.
+When using this predicate, only buffers under the current project root
+will be considered when saving buffers with 'save-some-buffers'.
+
+---
+** New user option 'save-place-abbreviate-file-names'.
+This can simplify sharing the 'save-place-file' file across
+different hosts.
+
+---
+** New user options 'copy-region-blink-delay' and 'delete-pair-blink-delay'.
+'copy-region-blink-delay' specifies a delay to indicate the region
+copied by 'kill-ring-save'. 'delete-pair-blink-delay' specifies
+a delay to show the paired character to delete.
+
+---
+** 'zap-up-to-char' now uses 'read-char-from-minibuffer'.
+This allows navigating through the history of characters that have
+been input. This is mostly useful for characters that have complex
+input methods where inputting the character again may involve many
+keystrokes.
+
++++
+** Input history for 'goto-line' can now be made local to every buffer.
+In any event, line numbers used with 'goto-line' are kept in their own
+history list. This should help make faster the process of finding
+line numbers that were previously jumped to. By default, all buffers
+share a single history list. To make every buffer have its own
+history list, customize the user option 'goto-line-history-local'.
+
++++
+** New command 'goto-line-relative' for use in a narrowed buffer.
+It moves point to the line relative to the accessible portion of the
+narrowed buffer. 'M-g M-g' in Info is rebound to this command.
+When 'widen-automatically' is non-nil, 'goto-line' widens the narrowed
+buffer to be able to move point to the inaccessible portion.
+'goto-line-relative' is bound to 'C-x n g'.
+
++++
+** 'goto-char' prompts for the character position.
+When called interactively, 'goto-char' now offers the position at
+point as the default.
+
+** Auto-saving via 'auto-save-visited-mode' can now be inhibited.
+Set the variable 'auto-save-visited-mode' buffer-locally to nil to
+achieve that.
+
++++
+** New command 'kdb-macro-redisplay' to force redisplay in keyboard macros.
+This command is bound to 'C-x C-k d'.
+
+---
+** 'blink-cursor-mode' is now enabled by default regardless of the UI.
+It used to be enabled when Emacs is started in GUI mode but not when started
+in text mode. The cursor still only actually blinks in GUI frames.
+
+** 'show-paren-mode' is now enabled by default.
+To go back to the previous behavior, customize the user option of the
+same name to nil.
+
++++
+** New minor mode 'show-paren-local-mode'.
+It serves as a local counterpart for 'show-paren-mode', allowing you
+to toggle it separately in different buffers. To use it only in
+programming modes, for example, add the following to your init file:
+
+ (add-hook 'prog-mode-hook #'show-paren-local-mode)
+
+
+* Changes in Specialized Modes and Packages in Emacs 28.1
+
+** Isearch and Replace
+
++++
+*** Interactive regular expression search now uses faces for sub-groups.
+E.g., 'C-M-s foo-\([0-9]+\)' will now use the 'isearch-group-1' face
+on the part of the regexp that matches the sub-expression "[0-9]+".
+By default, there are two faces for sub-group highlighting, but you
+can define more faces whose names are of the form 'isearch-group-N',
+where N are successive numbers above 2.
+
+This is controlled by the 'search-highlight-submatches' user option.
+This feature is available only on terminals that have enough colors to
+distinguish between sub-expression highlighting.
+
++++
+*** Interactive regular expression replace now uses faces for sub-groups.
+Like 'search-highlight-submatches', this is controlled by the new user option
+'query-replace-highlight-submatches'.
+
++++
+*** New key 'M-s M-.' starts isearch looking for the thing at point.
+This key is bound to the new command 'isearch-forward-thing-at-point'.
+The new user option 'isearch-forward-thing-at-point' defines
+a list of symbols to try to get the "thing" at point. By default,
+the first element of the list is 'region' that tries to yank
+the currently active region to the search string.
+
++++
+*** New user option 'isearch-wrap-pause' defines how to wrap the search.
+There are choices to disable wrapping completely and to wrap immediately.
+When wrapping immediately, it consistently handles the numeric arguments
+of 'C-s' ('isearch-repeat-forward') and 'C-r' ('isearch-repeat-backward'),
+continuing with the remaining count after wrapping.
+
++++
+*** New user option 'isearch-repeat-on-direction-change'.
+When this option is set, direction changes in Isearch move to another
+search match, if there is one, instead of moving point to the other
+end of the current match.
+
++++
+*** New user option 'isearch-allow-motion'.
+When 'isearch-allow-motion' is set, the commands 'beginning-of-buffer',
+'end-of-buffer', 'scroll-up-command' and 'scroll-down-command', when
+invoked during I-search, move respectively to the first occurrence of
+the current search string in the buffer, the last one, the first one
+after the current window, and the last one before the current window.
+Additionally, users can change the meaning of other motion commands
+during I-search by using their 'isearch-motion' property. The user
+option 'isearch-motion-changes-direction' controls whether the
+direction of the search changes after a motion command.
+
++++
+*** New user option 'lazy-highlight-no-delay-length'.
+Lazy highlighting of matches in Isearch now starts immediately if the
+search string is at least this long. 'lazy-highlight-initial-delay'
+still applies for shorter search strings, which avoids flicker in the
+search buffer due to too many matches being highlighted.
+
++++
+*** The default 'search-whitespace-regexp' value has changed.
+This used to be "\\s-+", which meant that it was mode-dependent whether
+newlines were included in the whitespace set. This has now been
+changed to only match spaces and tab characters.
+
+** Dired
+
++++
+*** New user option 'dired-kill-when-opening-new-dired-buffer'.
+If non-nil, Dired will kill the current buffer when selecting a new
+directory to display.
+
++++
+*** Behavior change on 'dired-do-chmod'.
+As a security precaution, Dired's M command no longer follows symbolic
+links. Instead, it changes the symbolic link's own mode; this always
+fails on platforms where such modes are immutable.
+
+---
+*** Behavior change on 'dired-clean-confirm-killing-deleted-buffers'.
+Previously, if 'dired-clean-up-buffers-too' was non-nil, and
+'dired-clean-confirm-killing-deleted-buffers' was nil, the buffers
+wouldn't be killed. This combination will now kill the buffers.
+
++++
+*** New user option 'dired-switches-in-mode-line'.
+This user option controls how 'ls' switches are displayed in the mode
+line, and allows truncating them (to preserve space on the mode line)
+or showing them literally, either instead of, or in addition to,
+displaying "by name" or "by date" sort order.
+
++++
+*** New user option 'dired-compress-directory-default-suffix'.
+This user option controls the default suffix for compressing a
+directory. If it's nil, ".tar.gz" will be used. Refer to
+'dired-compress-files-alist' for a list of supported suffixes.
+
++++
+*** New user option 'dired-compress-file-default-suffix'.
+This user option controls the default suffix for compressing files.
+If it's nil, ".gz" will be used. Refer to 'dired-compress-file-alist'
+for a list of supported suffixes.
+
+---
+*** Broken and circular links are shown with the 'dired-broken-symlink' face.
+
+---
+*** '=' ('dired-diff') will now put all backup files into the 'M-n' history.
+When using '=' on a file with backup files, the default file to use
+for diffing is the newest backup file. You can now use 'M-n' to quickly
+select a different backup file instead.
+
++++
+*** New user option 'dired-maybe-use-globstar'.
+If set, enables globstar (recursive globbing) in shells that support
+this feature, but have it turned off by default. This allows producing
+directory listings with files matching a wildcard in all the
+subdirectories of a given directory. The new variable
+'dired-enable-globstar-in-shell' lists which shells can have globstar
+enabled, and how to enable it.
+
++++
+*** New user option 'dired-copy-dereference'.
+If set to non-nil, Dired will dereference symbolic links when copying.
+This can be switched off on a per-usage basis by providing
+'dired-do-copy' with a 'C-u' prefix.
+
+---
+*** New user option 'dired-do-revert-buffer'.
+Non-nil reverts the destination Dired buffer after performing one
+of these operations: 'dired-do-copy', 'dired-do-rename',
+'dired-do-symlink', 'dired-do-hardlink'.
+
+---
+*** New user option 'dired-mark-region'.
+This option affects all Dired commands that mark files. When non-nil
+and the region is active in Transient Mark mode, then Dired commands
+operate only on files in the active region. The values 'file' and
+'line' of this user option define the details of marking the file at
+the end of the region.
+
++++
+*** State changing VC operations are supported in Dired.
+These operations are supported on files and directories via the new
+command 'dired-vc-next-action'.
+
++++
+*** 'dired-jump' and 'dired-jump-other-window' moved from 'dired-x' to 'dired'.
+The 'dired-jump' and 'dired-jump-other-window' commands have been
+moved from the 'dired-x' package to 'dired'. The user option
+'dired-bind-jump' no longer has any effect and is now obsolete.
+The commands are now bound to 'C-x C-j' and 'C-x 4 C-j' by default.
+
+To get the old behavior of 'dired-bind-jump' back and unbind the above
+keys, add the following to your init file:
+
+ (global-set-key "\C-x\C-j" nil)
+ (global-set-key "\C-x4\C-j" nil)
+
+---
+*** 'dired-query' now uses 'read-char-from-minibuffer'.
+Using it instead of 'read-char-choice' allows using 'C-x o'
+to switch to the help window displayed after typing 'C-h'.
+
++++
+** Emacs 28.1 comes with Org v9.5.
+See the file ORG-NEWS for user-visible changes in Org.
+
+** Outline
+
++++
+*** New commands to cycle heading visibility.
+Typing 'TAB' on a heading line cycles the current section between
+"hide all", "subheadings", and "show all" states. Typing 'S-TAB'
+anywhere in the buffer cycles the whole buffer between "only top-level
+headings", "all headings and subheadings", and "show all" states.
+
++++
+*** New user option 'outline-minor-mode-cycle'.
+This user option customizes 'outline-minor-mode', with the difference
+that 'TAB' and 'S-TAB' on heading lines cycle heading visibility.
+Typing 'TAB' on a heading line cycles the current section between
+"hide all", "subheadings", and "show all" states. Typing 'S-TAB' on a
+heading line cycles the whole buffer between "only top-level
+headings", "all headings and subheadings", and "show all" states.
+
+---
+*** New user option 'outline-minor-mode-highlight'.
+This user option customizes 'outline-minor-mode'. It puts
+highlighting on heading lines using standard outline faces. This
+works well only when there are no conflicts with faces used by the
+major mode.
+
+** Ispell
+
++++
+*** 'ispell-comments-and-strings' now accepts START and END arguments.
+These arguments default to the active region when used interactively.
+
++++
+*** New command 'ispell-comment-or-string-at-point'.
+
+---
+*** New user option 'ispell-help-timeout'.
+This controls how long the ispell help (on the '?' key) is displayed.
+
+** Flyspell mode
+
++++
+*** Corrections and actions menu can be optionally bound to 'mouse-3'.
+When Flyspell mode highlights a word as misspelled, you can click on
+it to display a menu of possible corrections and actions. You can now
+easily bind this menu to 'down-mouse-3' (usually the right mouse button)
+instead of 'mouse-2' (the default) by enabling 'context-menu-mode'.
+
+---
+*** The current dictionary is now displayed in the minor mode lighter.
+Clicking the dictionary name changes the current dictionary.
+
+** Package
+
+*** The new NonGNU ELPA archive is enabled by default alongside GNU ELPA.
+Thus, packages on NonGNU ELPA will appear by default in the list shown
+by 'list-packages'.
+
+---
+*** '/ s' ('package-menu-filter-by-status') changed parameter handling.
+The command was documented to take a comma-separated list of statuses
+to filter by, but instead it used the parameter as a regexp. The
+command has been changed so that it now works as documented, and
+checks statuses not as a regexp, but instead an exact match from the
+comma-separated list.
+
++++
+*** New command 'package-browse-url' and keystroke 'w'.
+
++++
+*** 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-filter-clear
+
+*** Option to automatically native-compile packages upon installation.
+Customize the user option 'package-native-compile' to enable automatic
+native compilation of packages when they are installed. That option
+is nil by default; if set non-nil, and if your Emacs was built with
+native-compilation support, each package will be natively compiled
+when it is installed, by invoking an asynchronous Emacs subprocess to
+run the native-compilation of the package files. (Be sure to leave
+Emacs running until these asynchronous subprocesses exit, or else the
+native-compilation will be aborted when you exit Emacs.)
+
+---
+*** Column widths in 'list-packages' display can now be customized.
+See the new user options 'package-name-column-width',
+'package-version-column-width', 'package-status-column-width', and
+'package-archive-column-width'.
+
+** Info
+
+---
+*** New user option 'Info-warn-on-index-alternatives-wrap'.
+This option affects what happens when using the ',' command after
+looking up an entry with 'i' in info buffers. If non-nil (the
+default), the ',' command will now display a warning when proceeding
+beyond the final index match, and tapping ',' once more will then take
+you to the first match.
+
+** Abbrev mode
+
++++
+*** Emacs can now suggest to use an abbrev based on text you type.
+A new user option, 'abbrev-suggest', enables the new abbrev suggestion
+feature. When enabled, if a user manually types a piece of text that
+could have saved enough typing by using an abbrev, a hint will be
+displayed in the echo area, mentioning the abbrev that could have been
+used instead.
+
+** Bookmarks
+
+---
+*** Bookmarks can now be targets for new tabs.
+When the bookmark.el library is loaded, a customize choice is added
+to 'tab-bar-new-tab-choice' for new tabs to show the bookmark list.
+
+---
+*** New user option 'bookmark-set-fringe-mark'.
+If non-nil, setting a bookmark will set a fringe mark on the current
+line, and jumping to a bookmark will also set this mark.
+
+---
+*** New user option 'bookmark-menu-confirm-deletion'.
+In Bookmark Menu mode, Emacs by default does not prompt for
+confirmation when you type 'x' to execute the deletion of bookmarks
+that have been marked for deletion. However, if this new option is
+non-nil then Emacs will require confirmation with 'yes-or-no-p' before
+deleting.
+
+---
+*** The 'list-bookmarks' menu is now based on 'tabulated-list-mode'.
+The interactive bookmark list will now benefit from features in
+'tabulated-list-mode' like sorting columns or changing column width.
+
+Support for the optional "inline" header line, allowing for a
+header without using 'header-line-format', has been dropped.
+The variables 'bookmark-bmenu-use-header-line' and
+'bookmark-bmenu-inline-header-height' are now obsolete.
+
+** Recentf
+
+---
+*** The recentf files are no longer backed up.
+
+---
+*** 'recentf-auto-cleanup' now repeats daily when set to a time string.
+When 'recentf-auto-cleanup' is set to a time string, it now repeats
+every day, rather than only running once after the mode is turned on.
+
+** Calc
+
+---
+*** The behavior when doing forward-delete has been changed.
+Previously, using the 'C-d' command would delete the final number in
+the input field, no matter where point was. This has been changed to
+work more traditionally, with 'C-d' deleting the next character.
+Likewise, point isn't moved to the end of the string before inserting
+digits.
+
++++
+*** Setting the word size to zero disables word clipping.
+The word size normally clips the results of certain bit-oriented
+operations such as shifts and bitwise XOR. A word size of zero, set
+by 'b w', makes the operation have effect on the whole argument values
+and the result is not truncated in any way.
+
+---
+*** The '/' operator now has higher precedence in (La)TeX input mode.
+It no longer has lower precedence than '+' and '-'.
+
+---
+*** New user option 'calc-make-windows-dedicated'.
+When this user option is non-nil, Calc will mark its windows as
+dedicated.
+
+** Calendar
+
++++
+*** New user option 'calendar-time-zone-style'.
+If 'numeric', calendar functions (eg 'calendar-sunrise-sunset') that display
+time zones will use a form like "+0100" instead of "CET".
+
+** Imenu
+
++++
+*** New user option 'imenu-max-index-time'.
+If creating the imenu index takes longer than specified by this
+option (default 5 seconds), imenu indexing is stopped.
+
+** ido
+
+---
+*** Switching on 'ido-mode' now also overrides 'ffap-file-finder'.
+
+---
+*** Killing virtual ido buffers interactively will make them go away.
+Previously, killing a virtual ido buffer with 'ido-kill-buffer' didn't
+do anything. This has now been changed, and killing virtual buffers
+with that command will remove the buffer from recentf.
+
+** So Long
+
+---
+*** New 'so-long-predicate' function 'so-long-statistics-excessive-p'.
+It efficiently detects the presence of a long line anywhere in the
+buffer using 'buffer-line-statistics' (see above). This is now the
+default predicate (replacing 'so-long-detected-long-line-p').
+
+---
+*** Default values 'so-long-threshold' and 'so-long-max-lines' increased.
+The values of these user options have been raised to 10000 bytes and 500
+lines respectively, to reduce the likelihood of false-positives when
+'global-so-long-mode' is enabled. The latter value is now only used
+by the old predicate, as the new predicate knows the longest line in
+the entire buffer.
+
+---
+*** 'so-long-target-modes' now includes 'fundamental-mode' by default.
+This means that 'global-so-long-mode' will also process files which were
+not recognised. (This only has an effect if 'set-auto-mode' chooses
+'fundamental-mode'; buffers which are simply in 'fundamental-mode' by
+default are unaffected.)
+
+---
+*** New user options to preserve modes and variables.
+The new options 'so-long-mode-preserved-minor-modes' and
+'so-long-mode-preserved-variables' allow specified mode and variable
+states to be maintained if 'so-long-mode' replaces the original major
+mode. By default, these new options support 'view-mode'.
+
+** Grep
+
++++
+*** New user option 'grep-match-regexp' matches grep markers to highlight.
+Grep emits SGR ANSI escape sequences to color its output. The new
+user option 'grep-match-regexp' holds the regular expression to match
+the appropriate markers in order to provide highlighting in the source
+buffer. The user option can be customized to accommodate other
+grep-like tools.
+
+---
+*** The 'lgrep' command now ignores directories.
+On systems where the grep command supports it, directories will be
+skipped.
+
+*** Commands that use 'grep-find' now follow symlinks for command-line args.
+This is because the default value of 'grep-find-template' now includes
+the 'find' option '-H'. Commands that use that variable, including
+indirectly via a call to 'xref-matches-in-directory', might be
+affected. In particular, there should be no need anymore to ensure
+any directory names on the 'find' command lines end in a slash.
+This change is for better compatibility with old versions of non-GNU
+'find', such as the one used on macOS.
+
+---
+*** New utility function 'grep-file-at-point'.
+This returns the name of the file at point (if any) in 'grep-mode'
+buffers.
+
+** Shell
+
+---
+*** New command in 'shell-mode': 'narrow-to-prompt'.
+This is bound to 'C-x n d' in 'shell-mode' buffers, and narrows to the
+command line under point (and any following output).
+
+---
+*** New user option 'shell-has-auto-cd'.
+If non-nil, 'shell-mode' handles implicit "cd" commands, changing the
+directory if the command is a directory. Useful for shells like "zsh"
+that has this feature.
+
+** term-mode
+
+---
+*** New user option 'term-scroll-snap-to-bottom'.
+By default, 'term' and 'ansi-term' will now recenter the buffer so
+that the prompt is on the final line in the window. Setting this new
+user option to nil inhibits this behavior.
+
+---
+*** New user option 'term-set-terminal-size'
+If non-nil, the 'LINES' and 'COLUMNS' environment variables will be set
+based on the current window size. In previous versions of Emacs, this
+was always done (and that could lead to odd displays when resizing the
+window after starting). This variable defaults to nil.
+
+---
+*** 'term-mode' now supports "bright" color codes.
+"Bright" ANSI color codes are now displayed using the color values
+defined in 'term-color-bright-*'. In addition, bold text with regular
+ANSI colors can be displayed as "bright" if 'ansi-color-bold-is-bright'
+is non-nil.
+
+** Eshell
+
+---
+*** 'eshell-hist-ignoredups' can now also be used to mimic "erasedups" in bash.
+
+---
+*** Environment variable 'INSIDE_EMACS' is now copied to subprocesses.
+Its value contains the result of evaluating '(format "%s,eshell"
+emacs-version)'. Other package names, like "tramp", could also be included.
+
+---
+*** Eshell no longer re-initializes its keymap every call.
+This allows users to use (define-key eshell-mode-map ...) as usual.
+Some modules have their own minor mode now to account for these
+changes.
+
+*** Support for bookmark.el.
+The command 'bookmark-set' (bound to 'C-x r m') is now supported, and
+will create a bookmark that opens the current directory in Eshell.
+
+** Archive mode
+
+---
+*** Archive Mode can now parse ".squashfs" files.
+
+*** Can now modify members of 'ar' archives.
+
+*** Display of summaries is unified between backends.
+
+*** New user option and command to control displayed columns.
+New user option 'archive-hidden-columns' and new command
+'archive-hideshow-column' let you control which columns are displayed
+and which are kept hidden.
+
+---
+*** New command bound to 'C': 'archive-copy-file'.
+This command extracts the file at point and writes its data to a
+file.
+
+** browse-url
+
+*** Added support for custom URL handlers.
+There is a new variable 'browse-url-default-handlers' and a user
+option 'browse-url-handlers' being alists with '(REGEXP-OR-PREDICATE
+. FUNCTION)' entries allowing to define different browsing FUNCTIONs
+depending on the URL to be browsed. The variable is for default
+handlers provided by Emacs itself or external packages, the user
+option is for the user (and allows for overriding the default
+handlers).
+
+Formerly, one could do the same by setting
+'browse-url-browser-function' to such an alist. This usage is still
+supported but deprecated.
+
+*** Categorization of browsing commands into internal vs. external.
+All standard browsing commands such as 'browse-url-firefox',
+'browse-url-mail', or 'eww' have been categorized into internal (URL
+is browsed in Emacs) or external (an external application is spawned
+with the URL). This is done by adding a 'browse-url-browser-kind'
+symbol property to the browsing commands. With a new command
+'browse-url-with-browser-kind', an URL can explicitly be browsed with
+either an internal or external browser.
+
+---
+*** Support for browsing of remote files.
+If a remote file is specified, a local temporary copy of that file is
+passed to the browser.
+
+---
+*** Support for the conkeror browser is now obsolete.
+
+---
+*** Support for the Mosaic browser has been removed.
+This support has been obsolete since 25.1.
+
+** Completion List Mode
+
+*** Improved navigation in the "*Completions*" buffer.
+New key bindings have been added to 'completion-list-mode': 'n' and
+'p' now navigate completions, and 'M-g M-c' switches to the
+minibuffer and back to the completion list buffer.
+
++++
+** profiler.el
+The results displayed by 'profiler-report' now have the usage figures
+at the left hand side followed by the function name. This is intended
+to make better use of the horizontal space, in particular eliminating
+the truncation of function names. There is no way to get the former
+layout back.
+
+** Icomplete
+
+---
+*** New user option 'icomplete-matches-format'.
+This allows controlling the current/total number of matches for the
+prompt prefix.
+
++++
+*** New minor modes 'icomplete-vertical-mode' and 'fido-vertical-mode'.
+These modes modify Icomplete ('M-x icomplete-mode') and Fido ('M-x
+fido-mode'), to display completion candidates vertically instead of
+horizontally. In Icomplete, completions are rotated and selection
+kept at the top. In Fido, completions scroll like a typical dropdown
+widget. Both these new minor modes will turn on their non-vertical
+counterparts first, if they are not on already.
+
+---
+*** Default value of 'icomplete-compute-delay' has been changed to 0.15 s.
+
+---
+*** Default value of 'icomplete-max-delay-chars' has been changed to 2.
+
+---
+*** Reduced blinking while completing the next completions set.
+Icomplete doesn't hide the hint with the previously computed
+completions anymore when compute delay is in effect, or the previous
+computation has been aborted by input. Instead it shows the previous
+completions until the new ones are ready.
+
+---
+*** Change in meaning of 'icomplete-show-matches-on-no-input'.
+Previously, choosing a different completion with commands like 'C-.'
+and then hitting 'RET' would choose the default completion. Doing this
+will now choose the completion under point instead. Also when this option
+is nil, completions are not shown when the minibuffer reads a file name
+with initial input as the default directory.
+
+** Windmove
+
++++
+*** New user options to customize windmove keybindings.
+These options include 'windmove-default-keybindings',
+'windmove-display-default-keybindings',
+'windmove-delete-default-keybindings',
+'windmove-swap-states-default-keybindings'.
+Also new mode 'windmove-mode' enables the customized keybindings.
+
+** Occur mode
+
+---
+*** New bindings in occur-mode.
+The command 'next-error-no-select' is now bound to 'n' and
+'previous-error-no-select' is bound to 'p'.
+
+---
+*** New command 'recenter-current-error'.
+It is bound to 'l' in Occur or compilation buffers, and recenters the
+current displayed occurrence/error.
+
+---
+*** Matches in target buffers are now highlighted as in 'compilation-mode'.
+The method of highlighting is specified by the user options
+'next-error-highlight' and 'next-error-highlight-no-select'.
+
+---
+*** A fringe arrow in the "*Occur*" buffer indicates the selected match.
+
+---
+*** Occur mode may use a different type for 'occur-target' property values.
+The value was previously always a marker set to the start of the first
+match on the line but can now also be a list of '(BEGIN . END)' pairs
+of markers delimiting each match on the line.
+This is a fully compatible change to the internal occur-mode
+implementation, and code creating their own occur-mode buffers will
+work as before.
+
+** Emacs Lisp mode
+
+---
+*** The mode-line now indicates whether we're using lexical or dynamic scoping.
+
++++
+*** A space between an open paren and a symbol changes the indentation rule.
+The presence of a space between an open paren and a symbol now is
+taken as a statement by the programmer that this should be indented
+as a data list rather than as a piece of code.
+
+** Lisp Mode
+
+*** New minor mode 'cl-font-lock-built-in-mode' for 'lisp-mode'.
+The mode provides refined highlighting of built-in functions, types,
+and variables.
+
+---
+*** Lisp mode now uses 'common-lisp-indent-function'.
+To revert to the previous behavior,
+'(setq lisp-indent-function 'lisp-indent-function)' from 'lisp-mode-hook'.
+
+** Change Logs and VC
+
++++
+*** 'vc-revert-show-diff' now has a third possible value: 'kill'.
+If this user option is 'kill', then the diff buffer will be killed
+after the 'vc-revert' action instead of buried.
+
+---
+*** More VC commands can be used from non-file buffers.
+The relevant commands are those that don't change the VC state.
+The non-file buffers which can use VC commands are those that have
+their 'default-directory' under VC.
+
+---
+*** New face 'log-view-commit-body'.
+This is used when expanding commit messages from 'vc-print-root-log'
+and similar commands.
+
+---
+*** New faces for 'vc-dir' buffers.
+Those are: 'vc-dir-header', 'vc-dir-header-value', 'vc-dir-directory',
+'vc-dir-file', 'vc-dir-mark-indicator', 'vc-dir-status-warning',
+'vc-dir-status-edited', 'vc-dir-status-up-to-date',
+'vc-dir-status-ignored'.
+
+---
+*** The responsible VC backend is now the most specific one.
+'vc-responsible-backend' loops over the backends in
+'vc-handled-backends' to determine which backend is responsible for a
+specific (unregistered) file. Previously, the first matching backend
+was chosen, but now the one with the most specific path is chosen (in
+case there's a directory handled by one backend inside another).
+
+---
+*** New command 'vc-dir-root' uses the root directory without asking.
+
+---
+*** New commands 'vc-dir-mark-registered-files' (bound to '* r') and
+'vc-dir-mark-unregistered-files'.
+
+---
+*** Support for bookmark.el.
+Bookmark locations can refer to VC directory buffers.
+
+---
+*** New user option 'vc-hg-create-bookmark'.
+It controls whether a bookmark or branch will be created when you
+invoke 'C-u C-x v s' ('vc-create-tag').
+
+---
+*** 'vc-hg' now uses 'hg summary' to populate extra 'vc-dir' headers.
+
+---
+*** New user option 'vc-git-revision-complete-only-branches'.
+If non-nil, only branches and remotes are considered when doing
+completion over Git branch names. The default is nil, which causes
+tags to be considered as well.
+
+---
+*** New user option 'vc-git-log-switches'.
+String or list of strings specifying switches for Git log under VC.
+
+---
+*** Command 'vc-switch-backend' is now obsolete.
+If you are still using it with any regularity, please file a bug
+report with some details.
+
+** Gnus
+
++++
+*** New user option 'gnus-topic-display-predicate'.
+This can be used to inhibit the display of some topics completely.
+
++++
+*** nnimap now supports the oauth2.el library.
+
++++
+*** New Summary buffer sort options for extra headers.
+The extra header sort option ('C-c C-s C-x') prompts for a header
+and fails if no sort function has been defined. Sorting by
+Newsgroups ('C-c C-s C-u') has been pre-defined.
+
++++
+*** The '#' command in the Group and Summary buffer now toggles,
+instead of sets, the process mark.
+
++++
+*** New user option 'gnus-process-mark-toggle'.
+If non-nil (the default), the '#' command in the Group and Summary
+buffers will toggle, instead of set, the process mark.
+
++++
+*** New user option 'gnus-registry-register-all'.
+If non-nil (the default), create registry entries for all messages.
+If nil, don't automatically create entries, they must be created
+manually.
+
++++
+*** New user options to customise the summary line specs "%[" and "%]".
+Four new options introduced in customisation group
+'gnus-summary-format'. These are 'gnus-sum-opening-bracket',
+'gnus-sum-closing-bracket', 'gnus-sum-opening-bracket-adopted', and
+'gnus-sum-closing-bracket-adopted'. Their default values are "[", "]",
+"<", ">" respectively. These options control the appearance of "%["
+and "%]" specs in the summary line format. "%[" will normally display
+the value of 'gnus-sum-opening-bracket', but can also be
+'gnus-sum-opening-bracket-adopted' for the adopted articles. "%]" will
+normally display the value of 'gnus-sum-closing-bracket', but can also
+be 'gnus-sum-closing-bracket-adopted' for the adopted articles.
+
++++
+*** New user option 'gnus-paging-select-next'.
+This controls what happens when using commands like 'SPC' and 'DEL' to
+page the current article. If non-nil (the default), go to the
+next/prev article, but if nil, do nothing at the end/start of the article.
+
++++
+*** New gnus-search library.
+A new unified search syntax which can be used across multiple
+supported search engines. Set 'gnus-search-use-parsed-queries' to
+non-nil to enable.
+
++++
+*** New value for user option 'smiley-style'.
+Smileys can now be rendered with emojis instead of small images when
+using the new 'emoji' value in 'smiley-style'.
+
++++
+*** New user option 'gnus-agent-eagerly-store-articles'.
+If non-nil (which is the default), the Gnus Agent will store all read
+articles in the Agent cache.
+
++++
+*** New user option 'gnus-global-groups'.
+Gnus handles private groups differently from public (i.e., NNTP-like)
+groups. Most importantly, Gnus doesn't download external images from
+mail-like groups. This can be overridden by putting group names in
+'gnus-global-groups': Any group present in that list will be treated
+like a public group.
+
++++
+*** New scoring types for the Date header.
+You can now score based on the relative age of an article with the new
+'<' and '>' date scoring types.
+
++++
+*** User-defined scoring is now possible.
+The new type is 'score-fn'. More information in the Gnus manual node
+"(gnus) Score File Format".
+
++++
+*** New backend 'nnselect'.
+The newly added 'nnselect' backend allows creating groups from an
+arbitrary list of articles that may come from multiple groups and
+servers. These groups generally behave like any other group: they may
+be ephemeral or persistent, and allow article marking, moving,
+deletion, etc. 'nnselect' groups may be created like any other group,
+but there are three convenience functions for the common case of
+obtaining the list of articles as a result of a search:
+'gnus-group-make-search-group' ('G g') that will prompt for an 'nnir'
+search query and create a persistent group for that search;
+'gnus-group-read-ephemeral-search-group' ('G G') that will prompt for
+an 'nnir' search query and create an ephemeral group for that search;
+and 'gnus-summary-make-group-from-search' ('C-c C-p') that will create
+a persistent group with the search parameters of a current ephemeral
+search group.
+
+As part of this addition, the user option 'nnir-summary-line-format'
+has been removed; its functionality is now available directly in the
+'gnus-summary-line-format' specs '%G' and '%g'. The user option
+'gnus-refer-thread-use-nnir' has been renamed to
+'gnus-refer-thread-use-search'.
+
++++
+*** New user option 'gnus-dbus-close-on-sleep'.
+On systems with D-Bus support, it is now possible to register a signal
+to close all Gnus servers before the system sleeps.
+
++++
+*** The key binding of 'gnus-summary-search-article-forward' has changed.
+This command was previously on 'M-s' and shadowed the global 'M-s'
+search prefix. The command has now been moved to 'M-s M-s'. (For
+consistency, the 'M-s M-r' key binding has been added for the
+'gnus-summary-search-article-backward' command.)
+
+---
+*** The value for "all" in the 'large-newsgroup-initial' group parameter has changed.
+It was previously nil, which didn't work, because nil is
+indistinguishable from not being present. The new value for "all" is
+the symbol 'all'.
+
++++
+*** The name of dependent Gnus sessions has changed from "slave" to "child".
+The names of the commands 'gnus-slave', 'gnus-slave-no-server' and
+'gnus-slave-unplugged' have changed to 'gnus-child',
+'gnus-child-no-server' and 'gnus-child-unplugged' respectively.
+
++++
+*** The 'W Q' summary mode command now takes a numerical prefix to
+allow adjusting the fill width.
+
++++
+*** New variable 'mm-inline-font-lock'.
+This variable is supposed to be bound by callers to determine whether
+inline MIME parts (that support it) are supposed to be font-locked or
+not.
+
+** Message
+
+---
+*** Respect 'message-forward-ignored-headers' more.
+Previously, this user option would not be consulted if
+'message-forward-show-mml' was nil and forwarding as MIME.
+
++++
+*** New user option 'message-forward-included-mime-headers'.
+This is used when forwarding messages as MIME, but not using MML.
+
++++
+*** Message now supports the OpenPGP header.
+To generate these headers, add the new function
+'message-add-openpgp-header' to 'message-send-hook'. The header will
+be generated according to the new 'message-openpgp-header' user
+option.
+
+---
+*** A change to how "Mail-Copies-To: never" is handled.
+If a user has specified "Mail-Copies-To: never", and Message was asked
+to do a "wide reply", some other arbitrary recipient would end up in
+the resulting "To" header, while the remaining recipients would be put
+in the "Cc" header. This is somewhat misleading, as it looks like
+you're responding to a specific person in particular. This has been
+changed so that all the recipients are put in the "To" header in these
+instances.
+
++++
+*** New command to start Emacs in Message mode to send an email.
+Emacs can be defined as a handler for the "x-scheme-handler/mailto"
+MIME type with the following command: "emacs -f message-mailto %u".
+An "emacs-mail.desktop" file has been included, suitable for
+installing in desktop directories like "/usr/share/applications" or
+"~/.local/share/applications".
+Clicking on a 'mailto:' link in other applications will then open
+Emacs with headers filled out according to the link, e.g.
+"mailto:larsi@gnus.org?subject=This+is+a+test". If you prefer
+emacsclient, use "emacsclient -e '(message-mailto "%u")'"
+or "emacsclient-mail.desktop".
+
+---
+*** Change to default value of 'message-draft-headers' user option.
+The 'Date' symbol has been removed from the default value, meaning that
+draft or delayed messages will get a date reflecting when the message
+was sent. To restore the original behavior of dating a message
+from when it is first saved or delayed, add the symbol 'Date' back to
+this user option.
+
++++
+*** New command to take screenshots.
+In Message mode buffers, the 'C-c C-p' ('message-insert-screenshot')
+command has been added. It depends on using an external program to
+take the actual screenshot, and defaults to "ImageMagick import".
+
+** Smtpmail
+
++++
+*** smtpmail now supports using the oauth2.el library.
+
++++
+*** New user option 'smtpmail-store-queue-variables'.
+If non-nil, SMTP variables will be stored together with the queued
+messages, and will then be used when sending with
+'M-x smtpmail-send-queued-mail'.
+
++++
+*** Allow direct selection of smtp authentication mechanism.
+A server entry retrieved by auth-source can request a desired smtp
+authentication mechanism by setting a value for the key 'smtp-auth'.
+
+** ElDoc
+
++++
+*** New user option 'eldoc-echo-area-display-truncation-message'.
+If non-nil (the default), eldoc will display a message saying
+something like "(Documentation truncated. Use `M-x eldoc-doc-buffer'
+to see rest)" when a message has been truncated. If nil, truncated
+messages will be marked with just "..." at the end.
+
++++
+*** New hook 'eldoc-documentation-functions'.
+This hook is intended to be used for registering doc string functions.
+These functions don't need to produce the doc string right away, they
+may arrange for it to be produced asynchronously. The results of all
+doc string functions are accessible to the user through the user
+option 'eldoc-documentation-strategy'.
+
+*** New hook 'eldoc-display-functions'.
+This hook is intended to be used for displaying doc strings. The
+functions receive the doc string composed according to
+'eldoc-documentation-strategy' and are tasked with displaying it to
+the user. Examples of such functions would use the echo area, a
+separate buffer, or a tooltip.
+
++++
+*** New user option 'eldoc-documentation-strategy'.
+The built-in choices available for this user option let users compose
+the results of 'eldoc-documentation-functions' in various ways, even
+if some of those functions are synchronous and some asynchronous.
+The user option replaces 'eldoc-documentation-function', which is now
+obsolete.
+
+*** 'eldoc-echo-area-use-multiline-p' is now handled by ElDoc.
+The user option 'eldoc-echo-area-use-multiline-p' is now handled
+by the ElDoc library itself. Functions in
+'eldoc-documentation-functions' don't need to worry about consulting
+it when producing a doc string.
+
+** Tramp
+
++++
+*** New connection method "mtp".
+It allows accessing media devices like cell phones, tablets or
+cameras.
+
++++
+*** New connection method "sshfs".
+It allows accessing remote files via a file system mounted with
+'sshfs'.
+
++++
+*** Tramp supports SSH authentication via a hardware security key now.
+This requires at least OpenSSH 8.2, and a FIDO U2F compatible
+security key, like yubikey, solokey, or nitrokey.
+
++++
+*** Trashed remote files are moved to the local trash directory.
+All remote files that are trashed are moved to the local trash
+directory, except remote encrypted files, which are always deleted.
+
++++
+*** New command 'tramp-crypt-add-directory'.
+This command marks a remote directory to contain only encrypted files.
+See the "(tramp) Keeping files encrypted" node of the Tramp manual for
+details. This feature is experimental.
+
++++
+*** Support of direct asynchronous process invocation.
+When Tramp connection property "direct-async-process" is set to
+non-nil for a given connection, 'make-process' and 'start-file-process'
+calls are performed directly as in "ssh ... <command>". This avoids
+initialization performance penalties. See the "(tramp) Improving
+performance of asynchronous remote processes" node of the Tramp manual
+for details, and also for a discussion or restrictions. This feature
+is experimental.
+
++++
+*** New user option 'tramp-debug-to-file'.
+When non-nil, this user option instructs Tramp to mirror the debug
+buffer to a file under the "/tmp/" directory. This is useful, if (in
+rare cases) Tramp blocks Emacs, and we need further debug information.
+
++++
+*** Tramp supports lock files now.
+In order to deactivate this, set user option
+'remote-file-name-inhibit-locks' to t.
+
++++
+*** Writing sensitive data locally requires confirmation.
+Writing auto-save, backup or lock files to the local temporary
+directory must be confirmed. In order to suppress this confirmation,
+set user option 'tramp-allow-unsafe-temporary-files' to t.
+
++++
+*** 'make-directory' of a remote directory honors the default file modes.
+
+** gdb-mi
+
+*** New user option 'gdb-registers-enable-filter'.
+If non-nil, apply a register filter based on
+'gdb-registers-filter-pattern-list'.
+
++++
+*** gdb-mi can now save and restore window configurations.
+Use 'gdb-save-window-configuration' to save window configuration to a
+file and 'gdb-load-window-configuration' to load from a file. These
+commands can also be accessed through the menu bar under "Gud =>
+GDB-Windows". 'gdb-default-window-configuration-file', when non-nil,
+is loaded when GDB starts up.
+
++++
+*** gdb-mi can now restore window configuration after quitting.
+Set 'gdb-restore-window-configuration-after-quit' to non-nil and Emacs
+will remember the window configuration before GDB started and restore
+it after GDB quits. A toggle button is also provided under "Gud =>
+GDB-Windows" menu item.
+
++++
+*** gdb-mi now has a better logic for displaying source buffers.
+Now GDB only uses one source window to display source file by default.
+Customize 'gdb-max-source-window-count' to use more than one window.
+Control source file display by 'gdb-display-source-buffer-action'.
+
++++
+*** The default value of 'gdb-mi-decode-strings' is now t.
+This means that the default coding-system is now used to decode strings
+and source file names from GDB.
+
+** Compilation mode
+
+---
+*** New function 'ansi-color-compilation-filter'.
+This function is meant to be used in 'compilation-filter-hook'.
+
+---
+*** New user option 'ansi-color-for-compilation-mode'.
+This controls what 'ansi-color-compilation-filter' does.
+
+*** Regexp matching of messages is now case-sensitive by default.
+The variable 'compilation-error-case-fold-search' can be set for
+case-insensitive matching of messages when the old behavior is
+required, but the recommended solution is to use a correctly matching
+regexp instead.
+
+---
+*** New user option 'compilation-search-all-directories'.
+When doing parallel builds, directories and compilation errors may
+arrive in the "*compilation*" buffer out-of-order. If this option is
+non-nil (the default), Emacs will now search backwards in the buffer
+for any directory the file with errors may be in. If nil, this won't
+be done (and this restores how this previously worked).
+
+---
+*** Messages from ShellCheck are now recognized.
+
+---
+*** Messages from Visual Studio that mention column numbers are now recognized.
+
+** Hi Lock mode
+
+---
+*** Matching in 'hi-lock-mode' can be case-sensitive.
+The matching is case-sensitive when a regexp contains upper case
+characters and 'search-upper-case' is non-nil. 'highlight-phrase'
+also uses 'search-whitespace-regexp' to substitute spaces in regexp
+search.
+
+---
+*** The default value of 'hi-lock-highlight-range' was enlarged.
+The new default value is 2000000 (2 megabytes).
+
+** Whitespace mode
+
++++
+*** New style 'missing-newline-at-eof'.
+If present in 'whitespace-style' (as it is by default), the final
+character in the buffer will be highlighted if the buffer doesn't end
+with a newline.
+
+---
+*** The default 'whitespace-enable-predicate' predicate has changed.
+It used to check elements in the list version of
+'whitespace-global-modes' with 'eq', but now uses 'derived-mode-p'.
+
+** Texinfo
+
+---
+*** New user option 'texinfo-texi2dvi-options'.
+This is used when invoking 'texi2dvi' from 'texinfo-tex-buffer'.
+
+---
+*** New commands for moving in and between environments.
+An "environment" is something that ends with '@end'. The commands are
+'C-c C-c C-f' (next end), 'C-c C-c C-b' (previous end),
+'C-c C-c C-n' (next start) and 'C-c C-c C-p' (previous start), as well
+as 'C-c .', which will alternate between the start and the end of the
+current environment.
+
+** Rmail
+
+---
+*** New user option 'rmail-re-abbrevs'.
+Its default value matches localized abbreviations of the "reply"
+prefix on the Subject line in various languages.
+
+---
+*** New user option 'rmail-show-message-set-modified'.
+If set non-nil, showing an unseen message will set the Rmail buffer's
+modified flag. The default is nil, to preserve the old behavior.
+
+** CC Mode
+
++++
+*** Added support for Doxygen documentation style.
+'doxygen' is now a valid 'c-doc-comment-style' which recognises all
+comment styles supported by Doxygen (namely '///', '//!', '/** … */'
+and '/*! … */'. 'gtkdoc' remains the default for C and C++ modes; to
+use 'doxygen' by default one might evaluate:
+
+ (setq-default c-doc-comment-style
+ '((java-mode . javadoc)
+ (pike-mode . autodoc)
+ (c-mode . doxygen)
+ (c++-mode . doxygen)))
+
+or use it in a custom 'c-style'.
+
++++
+*** Added support to line up '?' and ':' of a ternary operator.
+The new 'c-lineup-ternary-bodies' function can be used as a lineup
+function to align question mark and colon which are part of a ternary
+operator ('?:'). For example:
+
+ return arg % 2 == 0 ? arg / 2
+ : (3 * arg + 1);
+
+To enable, add it to appropriate entries in 'c-offsets-alist', e.g.:
+
+ (c-set-offset 'arglist-cont '(c-lineup-ternary-bodies
+ c-lineup-gcc-asm-reg))
+ (c-set-offset 'arglist-cont-nonempty '(c-lineup-ternary-bodies
+ c-lineup-gcc-asm-reg
+ c-lineup-arglist))
+ (c-set-offset 'statement-cont '(c-lineup-ternary-bodies +))
+
+** Images
+
+---
+*** You can explicitly specify base_uri for svg images.
+':base-uri' image property can be used to explicitly specify base_uri
+for embedded images into svg. ':base-uri' is supported for both file
+and data svg images.
+
++++
+*** 'svg-embed-base-uri-image' added to embed images.
+'svg-embed-base-uri-image' can be used to embed images located
+relatively to 'file-name-directory' of the ':base-uri' svg image property.
+This works much faster than 'svg-embed'.
+
++++
+*** New function 'image-cache-size'.
+This function returns the size of the current image cache, in bytes.
+
+---
+*** Animated images stop automatically under high CPU pressure sooner.
+Previously, an animated image would stop animating if any single image
+took more than two seconds to display. The new algorithm maintains a
+decaying average of delays, and if this number gets too high, the
+animation is stopped.
+
++++
+*** The 'n' and 'p' commands (next/previous image) now respect Dired order.
+These commands would previously display the next/previous image in
+lexicographic order, but will now find the "parent" Dired buffer and
+select the next/previous image file according to how the files are
+sorted there. The commands have also been extended to work when the
+"parent" buffer is an archive mode (i.e., zip file or the like) or tar
+mode buffer.
+
+---
+*** 'image-converter' is now restricted to formats in 'auto-mode-alist'.
+When using external image converters, the external program is queried
+for what formats it supports. This list may contain formats that are
+problematic in some contexts (like PDFs), so this list is now filtered
+based on 'auto-mode-alist'. Only file names that map to 'image-mode'
+are now supported.
+
+---
+*** The background and foreground of images now default to face colors.
+When an image doesn't specify a foreground or background color, Emacs
+now uses colors from the face used to draw the surrounding text
+instead of the frame's default colors.
+
+To load images with the default frame colors use the ':foreground' and
+':background' image attributes, for example:
+
+ (create-image "filename" nil nil
+ :foreground (face-attribute 'default :foreground)
+ :background (face-attribute 'default :background))
+
+This change only affects image types that support foreground and
+background colors or transparency, such as xbm, pbm, svg, png and gif.
+
++++
+*** Image smoothing can now be explicitly enabled or disabled.
+Smoothing applies a bilinear filter while scaling or rotating an image
+to prevent aliasing and other unwanted effects. The new image
+property ':transform-smoothing' can be set to t to force smoothing
+and nil to disable smoothing.
+
+The default behavior of smoothing on down-scaling and not smoothing
+on up-scaling remains unchanged.
+
++++
+*** New user option 'image-transform-smoothing'.
+This controls whether to use smoothing or not for an image. Values
+include nil (no smoothing), t (do smoothing) or a predicate function
+that's called with the image object and should return nil/t.
+
++++
+*** SVG images now support user stylesheets.
+The ':css' image attribute can be used to override the default CSS
+stylesheet for an image. The default sets 'font-family' and
+'font-size' to match the current face, so an image with 'height="1em"'
+will match the font size in use where it is embedded.
+
+This feature relies on librsvg 2.48 or above being available.
+
++++
+*** Image properties support 'em' sizes.
+Size image properties, for example ':height', ':max-height', etc., can
+be given a cons of the form '(SIZE . em)', where SIZE is an integer or
+float which is multiplied by the font size to calculate the image
+size, and 'em' is a symbol.
+
+** EWW
+
++++
+*** New user option 'eww-use-browse-url'.
+This is a regexp that can be set to alter how links are followed in eww.
+
++++
+*** New user option 'eww-retrieve-command'.
+This can be used to download data via an external command. If nil
+(the default), then 'url-retrieve' is used. When 'sync', then
+'url-retrieve-synchronously' is used. A list of strings specifies
+an external program with parameters.
+
++++
+*** New Emacs command line convenience command.
+The 'eww-browse' command has been added, which allows you to register
+Emacs as a MIME handler for "text/x-uri", and will call 'eww' on the
+supplied URL. Usage example: "emacs -f eww-browse https://gnu.org".
+
++++
+*** 'eww-download-directory' will now use the XDG location, if defined.
+However, if "~/Downloads/" already exists, that will continue to be
+used.
+
+---
+*** The command 'eww-follow-link' now supports custom mailto: handlers.
+The function that is invoked when clicking on or otherwise following a
+'mailto:' link in an EWW buffer can now be customized. For more
+information, see the related entry about 'shr-browse-url' below.
+
+---
+*** Support for bookmark.el.
+The command 'bookmark-set' (bound to 'C-x r m') is now supported, and
+will create a bookmark that opens the current URL in EWW.
+
+** SHR
+
+---
+*** The command 'shr-browse-url' now supports custom mailto handlers.
+Clicking on or otherwise following a 'mailto:' link in an HTML buffer
+rendered by SHR previously invoked the command 'browse-url-mailto'.
+This is still the case by default, but if you customize
+'browse-url-mailto-function' or 'browse-url-handlers' to call some
+other function, it will now be called instead of the default.
+
+---
+*** New user option 'shr-offer-extend-specpdl'.
+If this is nil, rendering of HTML that requires enlarging
+'max-specpdl-size', the number of Lisp variable bindings, will be
+aborted, and Emacs will not ask you whether to enlarge
+'max-specpdl-size' to complete the rendering. The default is t, which
+preserves the original behavior.
+
++++
+*** New user option 'shr-max-width'.
+If this user option is non-nil, and 'shr-width' is nil, then SHR will
+use the value of 'shr-max-width' to limit the width of the rendered
+HTML. The default is 120 characters, so even if you have very wide
+frames, HTML text will be rendered more narrowly, which usually leads
+to a more readable text. Customize it to nil to get the previous
+behavior of rendering as wide as the 'window-width' allows. If
+'shr-width' is non-nil, it overrides this option.
+
+---
+*** New faces for heading elements.
+Those are 'shr-h1', 'shr-h2', 'shr-h3', 'shr-h4', 'shr-h5', 'shr-h6'.
+
+** Project
+
+---
+*** New user option 'project-vc-merge-submodules'.
+
+---
+*** Project commands now have their own history.
+Previously used project directories are now suggested by all commands
+that prompt for a project directory.
+
++++
+*** New prefix keymap 'project-prefix-map'.
+Key sequences that invoke project-related commands start with the
+prefix 'C-x p'. Type 'C-x p C-h' to show the full list.
+
++++
+*** New commands 'project-dired', 'project-vc-dir', 'project-shell',
+'project-eshell'. These commands run Dired/VC-Dir and Shell/Eshell in
+a project's root directory, respectively.
+
++++
+*** New command 'project-compile'.
+This command runs compilation in the current project's root directory.
+
++++
+*** New command 'project-switch-project'.
+This command lets you "switch" to another project and run a project
+command chosen from a dispatch menu.
+
++++
+*** New commands 'project-shell-command' and 'project-async-shell-command'.
+These commands run 'shell-command' and 'async-shell-command' in a
+project's root directory, respectively.
+
++++
+*** New user option 'project-list-file'.
+This specifies the file in which to save the list of known projects.
+
++++
+*** New command 'project-remember-projects-under'.
+This command can automatically locate and index projects in a
+directory and optionally also its subdirectories, storing them in
+'project-list-file'.
+
++++
+*** New commands 'project-forget-project' and 'project-forget-projects-under'.
+These commands let you interactively remove entries from the list of projects
+in 'project-list-file'.
+
++++
+*** New command 'project-forget-zombie-projects'.
+This command detects indexed projects that have since been deleted,
+and removes them from the list of known projects in 'project-list-file'.
+
+---
+*** 'project-find-file' now accepts non-existent file names.
+This is to allow easy creation of files inside some nested
+sub-directory.
+
++++
+*** 'project-find-file' doesn't use the string at point as default input.
+Now it's only suggested as part of the "future history", accessible
+via 'M-n'.
+
++++
+*** New command 'project-find-dir' runs Dired in a directory inside project.
+
+** Xref
+
++++
+*** New user options to automatically show the first Xref match.
+The new user option 'xref-auto-jump-to-first-definition' controls the
+behavior of 'xref-find-definitions' and its variants, like
+'xref-find-definitions-other-window': if it's t or 'show', the first
+match is automatically displayed; if it's 'move', point in the
+"*xref*" buffer is automatically moved to the first match without
+displaying it.
+The new user option 'xref-auto-jump-to-first-xref' changes the
+behavior of Xref commands such as 'xref-find-references',
+'xref-find-apropos', and 'project-find-regexp', which are expected to
+display many matches that the user would like to
+visit. 'xref-auto-jump-to-first-xref' changes their behavior much in
+the same way as 'xref-auto-jump-to-first-definition' affects the
+"find-definitions" commands.
+
+---
+*** New user options 'xref-search-program' and 'xref-search-program-alist'.
+So far 'grep' and 'ripgrep' are supported. 'ripgrep' seems to offer better
+performance in certain cases, in particular for case-insensitive
+searches.
+
++++
+*** New commands 'xref-prev-group' and 'xref-next-group'.
+These commands are bound respectively to 'P' and 'N', and navigate to
+the first item of the previous or next group in the "*xref*" buffer.
+
+---
+*** New alternative value for 'xref-show-definitions-function':
+'xref-show-definitions-completing-read'.
+
+---
+*** The two existing alternatives for 'xref-show-definitions-function'
+have been renamed to have "proper" public names and documented
+('xref-show-definitions-buffer' and
+'xref-show-definitions-buffer-at-bottom').
+
++++
+*** New command 'xref-quit-and-pop-marker-stack'.
+This command is bound to 'M-,' in "*xref*" buffers. This combination
+is easy to press semi-accidentally if the user wants to go back in the
+middle of choosing the exact definition to go to, and this should do
+TRT.
+
+---
+*** New value 'project-relative' for 'xref-file-name-display'.
+If chosen, file names in "*xref*" buffers will be displayed relative
+to the 'project-root' of the current project, when available.
+
+---
+*** Prefix arg of 'xref-goto-xref' quits the "*xref*" buffer.
+So typing 'C-u RET' in the "*xref*" buffer quits its window
+before navigating to the selected location.
+
++++
+*** The 'TAB' key binding in "*xref*" buffers is obsolete.
+Use 'C-u RET' instead. The 'TAB' binding in "*xref*" buffers is still
+supported, but we plan on removing it in a future version; at that
+time, the command 'xref-quit-and-goto-xref' will no longer have a key
+binding in 'xref--xref-buffer-mode-map'.
+
+---
+*** New user option 'etags-xref-prefer-current-file'.
+When non-nil, matches for identifiers in the file visited by the
+current buffer will be shown first in the "*xref*" buffer.
+
++++
+*** The etags Xref backend now honors 'tags-apropos-additional-actions'.
+You can customize it to augment the output of 'xref-find-apropos',
+like it affected the output of 'tags-apropos', which is obsolete since
+Emacs 25.1.
+
+** Battery
+
+---
+*** UPower is now the default battery status backend when available.
+UPower support via the function 'battery-upower' was added in Emacs
+26.1, but was disabled by default. It is now the default value of
+'battery-status-function' when the system provides a UPower D-Bus
+service. The user options 'battery-upower-device' and
+'battery-upower-subscribe' control which power sources to query and
+whether to respond to status change notifications in addition to
+polling, respectively.
+
+---
+*** A richer syntax can be used to format battery status information.
+The user options 'battery-mode-line-format' and
+'battery-echo-area-format' now support the full formatting syntax of
+the function 'format-spec' documented under node "(elisp) Custom Format
+Strings". The new syntax includes specifiers for padding and
+truncation, amongst other things.
+
+** bug-reference.el
+
+---
+*** Bug reference mode uses auto-setup.
+If 'bug-reference-mode' or 'bug-reference-prog-mode' have been
+activated, their respective hook has been run, and both
+'bug-reference-bug-regexp' and 'bug-reference-url-format' are still
+not set, it tries to guess appropriate values for those two variables.
+There are three guessing mechanisms so far: based on version control
+information of the current buffer's file, based on
+newsgroup/mail-folder name and several news and mail message headers
+in Gnus buffers, and based on IRC channel and network in rcirc and ERC
+buffers. All the mechanisms are extensible with custom rules, see the
+variables 'bug-reference-setup-from-vc-alist',
+'bug-reference-setup-from-mail-alist', and
+'bug-reference-setup-from-irc-alist'.
+
+** HTML Mode
+
+---
+*** A new skeleton for adding relative URLs has been added.
+It's bound to the 'C-c C-c f' keystroke, and prompts for a local file
+name.
+
+** Widget
+
++++
+*** 'widget-choose' now supports menus in extended format.
+
+---
+*** The 'editable-list' widget now supports moving items up and down.
+You can now move items up and down by deleting and then reinserting
+them, using the 'DEL' and 'INS' buttons respectively. This is useful
+in Custom buffers, for example, to change the order of the elements in
+a list.
+
+** Diff
+
+---
+*** New face 'diff-changed-unspecified'.
+This is used to highlight "changed" lines (those marked with '!') in
+context diffs, when 'diff-use-changed-face' is non-nil.
+
+---
+*** New 'diff-mode' font locking face 'diff-error'.
+This face is used for error messages from 'diff'.
+
++++
+*** New command 'diff-refresh-hunk'.
+This new command (bound to 'C-c C-l') regenerates the current hunk.
+
+** thing-at-point
+
++++
+*** New 'thing-at-point' target: 'existing-filename'.
+This is like 'filename', but is a full path, and is nil if the file
+doesn't exist.
+
++++
+*** New 'thing-at-point' target: 'string'.
+If point is inside a string, it returns that string.
+
++++
+*** New variable 'thing-at-point-provider-alist'.
+This allows mode-specific alterations to how 'thing-at-point' works.
+
+---
+*** thing-at-point now respects fields.
+'thing-at-point' (and all functions that use it, like
+'symbol-at-point') will narrow to the current field (if any) before
+trying to identify the thing at point.
+
+---
+*** New function 'thing-at-mouse'.
+This is like 'thing-at-point', but uses the mouse event position instead.
+
+** Image-Dired
+
++++
+*** New user option 'image-dired-thumb-visible-marks'.
+If non-nil (the default), use the new face 'image-dired-thumb-mark'
+for marked images.
+
+---
+*** New command 'image-dired-delete-marked'.
+
+---
+*** 'image-dired-mouse-toggle-mark' is now sensitive to the active region.
+If the region is active, this command now toggles Dired marks of all
+the thumbnails in the region.
+
+** Flymake mode
+
++++
+*** New command 'flymake-show-project-diagnostics'.
+This lists all diagnostics for buffers in the currently active
+project. The listing is similar to the one obtained by
+'flymake-show-buffer-diagnostics', but adds a column for the
+project-relative file name. For backends which support it,
+'flymake-show-project-diagnostics' also lists diagnostics for files
+that have not yet been visited.
+
++++
+*** New user options to customize Flymake's mode-line.
+The new user option 'flymake-mode-line-format' is a mix of strings and
+symbols like 'flymake-mode-line-title', 'flymake-mode-line-exception'
+and 'flymake-mode-line-counters'. The new user option
+'flymake-mode-line-counter-format' is a mix of strings and symbols
+like 'flymake-mode-line-error-counter',
+'flymake-mode-line-warning-counter' and 'flymake-mode-line-note-counter'.
+
+** Time
+
+---
+*** 'display-time-world' has been renamed to 'world-clock'.
+'world-clock' creates a buffer with an updating time display using
+several time zones. It is hoped that the new names are more
+discoverable.
+
+The following commands have been renamed:
+
+ 'display-time-world' to 'world-clock'
+ 'display-time-world-mode' to 'world-clock-mode'
+ 'display-time-world-display' to 'world-clock-display'
+ 'display-time-world-timer' to 'world-clock-update'
+
+The following user options have been renamed:
+
+ 'display-time-world-list' to 'world-clock-list'
+ 'display-time-world-time-format' to 'world-clock-time-format'
+ 'display-time-world-buffer-name' to 'world-clock-buffer-name'
+ 'display-time-world-timer-enable' to 'world-clock-timer-enable'
+ 'display-time-world-timer-second' to 'world-clock-timer-second'
+
+The old names are now obsolete.
+
+---
+*** 'world-clock-mode' can no longer be turned on interactively.
+Use 'world-clock' to turn on that mode.
+
+** Python mode
+
+---
+*** New user option 'python-forward-sexp-function'.
+This allows the user easier customization of whether to use block-based
+navigation or not.
+
+---
+*** 'python-shell-interpreter' now defaults to python3 on systems with python3.
+
+---
+*** 'C-c C-r' can now be used on arbitrary regions.
+The command previously extended the start of the region to the start
+of the line, but will now actually send the marked region, as
+documented.
+
+** Ruby Mode
+
+---
+*** 'ruby-use-smie' is declared obsolete.
+SMIE is now always enabled and 'ruby-use-smie' only controls whether
+indentation is done using SMIE or with the old ad-hoc code.
+
+---
+*** Indentation has changed when 'ruby-align-chained-calls' is non-nil.
+This previously used to align subsequent lines with the last sibling,
+but it now aligns with the first sibling (which is the preferred style
+in Ruby).
+
+** CPerl Mode
+
+---
+*** New face 'perl-heredoc', used for heredoc elements.
+
+---
+*** The command 'cperl-set-style' offers the new value "PBP".
+This value customizes Emacs to use the style recommended in Damian
+Conway's book "Perl Best Practices" for indentation and formatting
+of conditionals.
+
+** Perl mode
+
+---
+*** New face 'perl-non-scalar-variable'.
+This is used to fontify non-scalar variables.
+
+** Octave Mode
+
++++
+*** Line continuations in double-quoted strings now use a backslash.
+Typing 'C-M-j' (bound to 'octave-indent-new-comment-line') now follows
+the behavior introduced in Octave 3.8 of using a backslash as a line
+continuation marker within double-quoted strings, and an ellipsis
+everywhere else.
+
++++
+** EasyPG
+GPG key servers can now be queried for keys with the
+'M-x epa-search-keys' command. Keys can then be added to your
+personal key ring.
+
+** Etags
+
++++
+*** Etags now supports the Mercury programming language.
+See https://mercurylang.org.
+
++++
+*** Etags command line option '--declarations' now has Mercury-specific behavior.
+All Mercury declarations are tagged by default. However, for
+compatibility with 'etags' support for Prolog, predicates and
+functions appearing first in clauses will also be tagged if 'etags' is
+invoked with the '--declarations' command-line option.
+
+** Comint
+
++++
+*** Support for OSC escape sequences.
+Adding the new 'comint-osc-process-output' to
+'comint-output-filter-functions' enables the interpretation of OSC
+("Operating System Command") escape sequences in comint buffers. By
+default, only OSC 8, for hyperlinks, and OSC 7, for directory
+tracking, are acted upon. Adding more entries to
+'comint-osc-handlers' allows a customized treatment of further escape
+sequences.
+
++++
+*** 'comint-delete-output' can now save deleted text in the kill-ring.
+Interactively, 'C-u C-c C-o' triggers this new optional behavior.
+
+** ansi-color.el
+
+---
+*** Colors are now defined by faces.
+ANSI SGR codes now have corresponding faces to describe their
+appearance, e.g. 'ansi-color-bold'.
+
+---
+*** Support for "bright" color codes.
+"Bright" ANSI color codes are now displayed when applying ANSI color
+filters using the color values defined by the faces
+'ansi-color-bright-COLOR'. In addition, bold text with regular ANSI
+colors can be displayed as "bright" if 'ansi-color-bold-is-bright' is
+non-nil.
+
+** ERC
+
+*** Starting with Emacs 28.1 and ERC 5.4, see the ERC-NEWS file for
+user-visible changes in ERC.
+
+** xwidget-webkit mode
+
+---
+*** New xwidget commands.
+'xwidget-webkit-uri' (return the current URL), 'xwidget-webkit-title'
+(return the current title), and 'xwidget-webkit-goto-history' (goto a
+point in history).
+
+---
+*** Downloading files from xwidget-webkit is now supported.
+The new user option 'xwidget-webkit-download-dir' says where to download to.
+
+---
+*** New command 'xwidget-webkit-clone-and-split-below'.
+Open a new window below displaying the current URL.
+
+---
+*** New command 'xwidget-webkit-clone-and-split-right'.
+Open a new window to the right displaying the current URL.
+
+---
+*** Pixel-based scrolling.
+The 'xwidget-webkit-scroll-up', 'xwidget-webkit-scroll-down' commands
+now supports scrolling arbitrary pixel values. It now treats the
+optional 2nd argument as the pixel values to scroll.
+
+---
+*** New commands for scrolling.
+The new commands 'xwidget-webkit-scroll-up-line',
+'xwidget-webkit-scroll-down-line', 'xwidget-webkit-scroll-forward',
+'xwidget-webkit-scroll-backward' can be used to scroll webkit by the
+height of lines or width of chars.
+
+---
+*** New user option 'xwidget-webkit-bookmark-jump-new-session'.
+When non-nil, use a new xwidget webkit session after bookmark jump.
+Otherwise, it will use 'xwidget-webkit-last-session'.
+
+** Checkdoc
+
+---
+*** No longer warns about command substitutions by default.
+Checkdoc used to warn about "too many command substitutions" (as in
+"\\[foo-command]"), even if you only used ten of them in a docstring.
+On modern machines, you can have hundreds or thousands of command
+substitutions before it becomes a performance issue, so this warning
+is now disabled by default. To re-enable this warning, customize the
+user option 'checkdoc-max-keyref-before-warn'.
+
+---
+*** New user option 'checkdoc-column-zero-backslash-before-paren'.
+Checkdoc warns if there is a left parenthesis in column zero of a
+documentation string. That warning can now be disabled by customizing
+this new user option to nil. This is useful if you don't expect
+your code to be edited with an Emacs older than version 27.1.
+
+---
+*** Now checks the prompt format for 'yes-or-no-p'.
+In addition to verifying the format of the prompt for 'y-or-n-p',
+checkdoc will now check the format of 'yes-or-no-p'.
+
+---
+*** New command 'checkdoc-dired'.
+This can be used to run checkdoc on files from a Dired buffer.
+
+---
+*** No longer checks for 'A-' modifiers.
+Checkdoc recommends usage of command substitutions ("\\[foo-command]")
+in favor of writing keybindings like 'C-c f'. It now no longer warns
+about the 'A-' modifier as it is not used very much in practice, and
+this warning therefore mostly led to false positives.
+
+** Enriched mode
+
+---
+*** 'C-a' is by default no longer bound to 'beginning-of-line-text'.
+This is so 'C-a' works as in other modes, and in particular holding
+Shift while typing 'C-a', i.e. 'C-S-a', will now highlight the text.
+
+** Gravatar
+
+---
+*** New user option 'gravatar-service' for host to query for gravatars.
+Defaults to 'libravatar', with 'unicornify' and 'gravatar' as options.
+
+** MH-E mail handler for Emacs
+
+Functions and variables related to handling junk mail have been
+renamed to not associate color with sender quality.
+
++++
+*** New names for mh-junk interactive functions.
+Function 'mh-junk-whitelist' is renamed 'mh-junk-allowlist'.
+Function 'mh-junk-blacklist' is renamed 'mh-junk-blocklist'.
+
++++
+*** New binding for 'mh-junk-allowlist'.
+The key binding for 'mh-junk-allowlist' is changed from 'J w' to 'J a'.
+The old binding is supported but warns that it is obsolete.
+
++++
+*** New names for some hooks.
+'mh-whitelist-msg-hook' is renamed 'mh-allowlist-msg-hook'.
+'mh-blacklist-msg-hook' is renamed 'mh-blocklist-msg-hook'.
+
++++
+*** New names for some user options.
+User option 'mh-whitelist-preserves-sequences-flag' is renamed
+'mh-allowlist-preserves-sequences-flag'.
+
++++
+*** New names for some faces.
+Face 'mh-folder-blacklisted' is renamed 'mh-folder-blocklisted'.
+Face 'mh-folder-whitelisted' is renamed 'mh-folder-allowlisted'.
+
+** Rcirc
+
++++
+*** rcirc now supports SASL authentication.
+
+---
+*** #emacs on Libera.chat has been added to 'rcirc-server-alist'.
+
+---
+*** rcirc connects asynchronously.
+
+---
+*** Integrate formatting into 'rcirc-send-string'.
+The function now accepts a variable number of arguments.
+
++++
+*** Deprecate 'rcirc-command' in favor of 'rcirc-define-command'.
+The new macro handles multiple and optional arguments.
+
+---
+*** Add basic IRCv3 support.
+This includes support for the capabilities: 'server-time', 'batch',
+'message-ids', 'invite-notify', 'multi-prefix' and 'standard-replies'.
+
+---
+*** Add mouse property support to 'rcirc-track-minor-mode'.
+
+---
+*** Improve support for IRC markup codes.
+
+---
+*** Check 'auth-sources' for server passwords.
+
++++
+*** Implement repeated reconnection strategy.
+See 'rcirc-reconnect-attempts'.
+
+** MPC
+
+---
+*** New command 'mpc-goto-playing-song'.
+This command, bound to 'o' in any 'mpc-mode' buffer, moves point to
+the currently playing song in the "*MPC-Songs*" buffer.
+
+---
+*** New user option 'mpc-cover-image-re'.
+If non-nil, it is a regexp that should match a valid cover image.
+
+** Miscellaneous
+
+---
+*** 'shell-script-mode' now supports 'outline-minor-mode'.
+The outline headings have lines that start with "###".
+
+---
+*** fileloop will now skip missing files instead of signalling an error.
+
+---
+*** 'tabulated-list-mode' can now restore original display order.
+Many commands (like 'C-x C-b') are derived from 'tabulated-list-mode',
+and that mode allows the user to sort on any column. There was
+previously no easy way to get back to the original displayed order
+after sorting, but giving a -1 numerical prefix to the sorting command
+will now restore the original order.
+
+---
+*** 'M-left' and 'M-right' now move between columns in 'tabulated-list-mode'.
+
+---
+*** New variable 'hl-line-overlay-priority'.
+This can be used to change the priority of the hl-line overlays.
+
++++
+*** New command 'mailcap-view-file'.
+This command will open a viewer based on the file type, as determined
+by "~/.mailcap" and related files and variables.
+
+---
+*** New user option 'remember-diary-regexp'.
+
+---
+*** New user option 'remember-text-format-function'.
+
+---
+*** New user option 'authinfo-hide-elements'.
+This can be set to nil to inhibit hiding passwords in ".authinfo" files.
+
+---
+*** 'hexl-mode' scrolling commands now heed 'next-screen-context-lines'.
+Previously, 'hexl-scroll-down' and 'hexl-scroll-up' would scroll
+up/down an entire window, but they now work more like the standard
+scrolling commands.
+
+---
+*** New user option 'bibtex-unify-case-function'.
+This new option allows the user to customize how case is converted
+when unifying entries.
+
+---
+*** The user option 'bibtex-maintain-sorted-entries' now permits
+user-defined sorting schemes.
+
+---
+*** New user option 'reveal-auto-hide'.
+If non-nil (the default), revealed text is automatically hidden when
+point leaves the text. If nil, the text is not hidden again. Instead
+'M-x reveal-hide-revealed' can be used to hide all the revealed text.
+
+---
+*** New user option 'ffap-file-name-with-spaces'.
+If non-nil, 'find-file-at-point' and friends will try to guess more
+expansively to identify a file name with spaces. Default value is
+nil.
+
+---
+*** Two new commands for centering in 'doc-view-mode'.
+The new commands 'doc-view-center-page-horizontally' (bound to 'c h')
+and 'doc-view-center-page-vertically' (bound to 'c v') center the page
+horizontally and vertically, respectively.
+
+---
+*** 'tempo-define-template' can now re-assign templates to tags.
+Previously, assigning a new template to an already defined tag had no
+effect.
+
+---
+*** The width of the buffer-name column in 'list-buffers' is now dynamic.
+The width now depends on the width of the window, but will never be
+wider than the length of the longest buffer name, except that it will
+never be narrower than 19 characters.
+
++++
+*** New diary sexp 'diary-offset'.
+It offsets another diary sexp by a number of days. This is useful
+when for example your organization has a committee meeting two days
+after every monthly meeting which takes place on the third Thursday,
+or if you would like to attend a virtual meeting scheduled in a
+different timezone causing a difference in the date.
+
+---
+*** The old non-SMIE indentation of 'sh-mode' has been removed.
+
+---
+*** 'mspools-show' is now autoloaded.
+
+---
+*** Loading dunnet.el in batch mode doesn't start the game any more.
+Instead you need to do "emacs -f dun-batch" to start the game in
+batch mode.
+
+
+* New Modes and Packages in Emacs 28.1
+
++++
+** New mode 'repeat-mode' to allow shorter key sequences.
+Type 'M-x repeat-mode' to enable this mode. You can then type
+'C-x u u' instead of 'C-x u C-x u' to undo many changes, 'C-x o o'
+instead of 'C-x o C-x o' to switch windows, 'C-x { { } } ^ ^ v v' to
+resize the selected window interactively, 'M-g n n p p' to navigate
+next-error matches. Any other key exits this temporarily enabled
+transient mode that supports shorter keys, and then after exiting from
+this mode, the last typed key uses the default key binding.
+
+The user option 'repeat-exit-key' defines an additional key usable to
+exit the mode like 'isearch-exit' ('RET').
+
+The user option 'repeat-exit-timeout' (default nil, which means
+forever) specifies the number of seconds of idle time after which to
+break the repetition chain automatically.
+
+When user option 'repeat-keep-prefix' is non-nil, the prefix arg of
+the previous command is kept. This can be used to e.g. reverse the
+window navigation direction with 'C-x o M-- o o' or to set a new step
+with 'C-x { C-5 { { {', which will set the window resizing step to 5
+columns.
+
+'M-x describe-repeat-maps' will display a buffer showing
+which commands are repeatable in 'repeat-mode'.
+
+---
+** New themes 'modus-vivendi' and 'modus-operandi'.
+These themes are designed to conform with the highest standard for
+color-contrast accessibility (WCAG AAA). You can load either of them
+using 'M-x customize-themes' or 'load-theme' from your init file.
+Consult the Modus Themes Info manual for more information on the user
+options they provide.
+
+** Dictionary mode
+This is a mode for searching a RFC 2229 dictionary server.
+'dictionary' opens a buffer for starting operations.
+'dictionary-search' performs a lookup for a word. It also supports a
+'dictionary-tooltip-mode' which performs a lookup of the word under
+the mouse in 'dictionary-tooltip-dictionary' (which must be customized
+first).
+
+---
+** Lisp Data mode
+The new command 'lisp-data-mode' enables a major mode for buffers
+composed of Lisp symbolic expressions that do not form a computer
+program. The ".dir-locals.el" file is automatically set to use this
+mode, as are other data files produced by Emacs.
+
++++
+** New global mode 'global-goto-address-mode'.
+This will enable 'goto-address-mode' in all buffers.
+
+** transient.el
+This library implements support for powerful keyboard-driven menus.
+Such menus can be used as simple visual command dispatchers. More
+complex menus take advantage of infix arguments, which are somewhat
+similar to prefix arguments, but are more flexible and discoverable.
+
+** hierarchy.el
+This library can create, query, navigate and display hierarchical
+structures.
+
+---
+** New major mode for displaying the "etc/AUTHORS" file.
+This new 'etc-authors-mode' provides font-locking for displaying the
+"etc/AUTHORS" file from the Emacs distribution, and not much else.
+
+
+* Incompatible Lisp Changes in Emacs 28.1
+
++++
+** Emacs now prints a backtrace when signaling an error in batch mode.
+This makes debugging Emacs Lisp scripts run in batch mode easier. To
+get back the old behavior, set the new variable
+'backtrace-on-error-noninteractive' to a nil value.
+
+---
+** Some floating-point numbers are now handled differently by the Lisp reader.
+In previous versions of Emacs, numbers with a trailing dot and an exponent
+were read as integers and the exponent ignored: 2.e6 was interpreted as the
+integer 2. Such numerals are now read as floats with the exponent included:
+2.e6 is now read as the floating-point value 2000000.0.
+That is, '(read-from-string "1.e3")' => '(1000.0 . 4)' now.
+
+---
+** 'equal' no longer examines some contents of window configurations.
+Instead, it considers window configurations to be equal only if they
+are 'eq'. To compare contents, use 'compare-window-configurations'
+instead. This change helps fix a bug in 'sxhash-equal', which returned
+incorrect hashes for window configurations and some other objects.
+
++++
+** The 'lexical-binding' local variable is always enabled.
+Previously, if 'enable-local-variables' was nil, a 'lexical-binding'
+local variable would not be heeded. This has now changed, and a file
+with a 'lexical-binding' cookie is always heeded. To revert to the
+old behavior, set 'permanently-enabled-local-variables' to nil.
+
++++
+** '&rest' in argument lists must always be followed by a variable name.
+Omitting the variable name after '&rest' was previously tolerated in
+some cases but not consistently so; it could lead to crashes or
+outright wrong results. Since the utility was marginal at best, it is
+now an error to omit the variable.
+
+---
+** 'kill-all-local-variables' has changed how it handles non-symbol hooks.
+The function is documented to eliminate all buffer-local bindings
+except variables with a 'permanent-local' property, or hooks that
+have elements with a 'permanent-local-hook' property. In addition, it
+would also keep lambda expressions in hooks sometimes. The latter has
+now been changed: The function will now also remove these.
+
++++
+** Temporary buffers no longer run certain buffer hooks.
+The macros 'with-temp-buffer' and 'with-temp-file' no longer run the
+hooks 'kill-buffer-hook', 'kill-buffer-query-functions', and
+'buffer-list-update-hook' for the temporary buffers they create. This
+avoids slowing them down when a lot of these hooks are defined.
+
++++
+** New face 'child-frame-border' and frame parameter 'child-frame-border-width'.
+The face and width of child frames borders can now be determined
+separately from those of normal frames. To minimize backward
+incompatibility, child frames without a 'child-frame-border-width'
+parameter will fall back to using 'internal-border-width'. However,
+the new 'child-frame-border' face does constitute a breaking change
+since child frames' borders no longer use the 'internal-border' face.
+
+---
+** 'run-at-time' now tries harder to implement the t TIME parameter.
+If TIME is t, the timer runs at an integral multiple of REPEAT.
+(I.e., if given a REPEAT of 60, it'll run at 08:11:00, 08:12:00,
+08:13:00.) However, when a machine goes to sleep (or otherwise didn't
+get a time slot to run when the timer was scheduled), the timer would
+then fire every 60 seconds after the time the timer was fired. This
+has now changed, and the timer code now recomputes the integral
+multiple every time it runs, which means that if the laptop wakes at
+08:16:43, it'll fire at that time, but then at 08:17:00, 08:18:00...
+
+---
+** 'parse-partial-sexp' now signals an error if TO is smaller than FROM.
+Previously, this would lead to the function interpreting FROM as TO and
+vice versa, which would be confusing when passing in OLDSTATE, which
+refers to the old state at FROM.
+
++++
+** 'global-mode-string' constructs should end with a space.
+This was previously not formalized, which led to combinations of modes
+displaying data "smushed together" on the mode line.
+
++++
+** 'overlays-in' now handles zero-length overlays slightly differently.
+Previously, zero-length overlays at the end of the buffer were included
+in the result (if the region queried for stopped at that position).
+The same was not the case if the buffer had been narrowed to exclude
+the real end of the buffer. This has now been changed, and
+zero-length overlays at 'point-max' are always included in the results.
+
+---
+** 'replace-match' now runs modification hooks slightly later.
+The function is documented to leave point after the replacement text,
+but this was not always the case if a modification hook inserted text
+in front of the replaced text -- 'replace-match' would instead leave
+point where the end of the inserted text would have been before the
+hook ran. 'replace-match' now always leaves point after the
+replacement text.
+
++++
+** 'completing-read-default' sets completion variables buffer-locally.
+'minibuffer-completion-table' and related variables are now set buffer-locally
+in the minibuffer instead of being set via a global let-binding.
+
+---
+** XML serialization functions now reject invalid characters.
+Previously, 'xml-print' would produce invalid XML when given a string
+with characters that are not valid in XML (see
+https://www.w3.org/TR/xml/#charsets). Now it rejects such strings.
+
+---
+** JSON
+
+---
+*** JSON number parsing is now stricter.
+Numbers with a leading plus sign, leading zeros, or a missing integer
+component are now rejected by 'json-read' and friends. This makes
+them more compliant with the JSON specification and consistent with
+the native JSON parsing functions.
+
+---
+*** JSON functions support the semantics of RFC 8259.
+The JSON functions 'json-serialize', 'json-insert',
+'json-parse-string', and 'json-parse-buffer' now implement some of the
+semantics of RFC 8259 instead of the earlier RFC 4627. In particular,
+these functions now accept top-level JSON values that are neither
+arrays nor objects.
+
+---
+*** Some JSON encoding functions are now obsolete.
+The functions 'json-encode-number', 'json-encode-hash-table',
+'json-encode-key', and 'json-encode-list' are now obsolete.
+
+The first two are kept as aliases of 'json-encode', which should be
+used instead. Uses of 'json-encode-list' should be changed to call
+one of 'json-encode', 'json-encode-alist', 'json-encode-plist', or
+'json-encode-array' instead.
+
++++
+*** Native JSON functions now signal an error if libjansson is unavailable.
+This affects 'json-serialize', 'json-insert', 'json-parse-string',
+and 'json-parse-buffer'. This can happen if Emacs was compiled with
+libjansson, but the DLL cannot be found and/or loaded by Emacs at run
+time. Previously, Emacs would display a message and return nil in
+these cases.
+
++++
+** The use of positional arguments in 'define-minor-mode' is obsolete.
+These were actually rendered obsolete in Emacs 21 but were never
+marked as such.
+
+---
+** 'pcomplete-ignore-case' is now an obsolete alias of 'completion-ignore-case'.
+
++++
+** 'completions-annotations' face is not used when the caller puts own face.
+This affects the suffix specified by completion 'annotation-function'.
+
++++
+** An active minibuffer now has major mode 'minibuffer-mode'.
+This is instead of the erroneous 'minibuffer-inactive-mode' it
+formerly had.
+
+---
+** 'make-text-button' no longer modifies text properties of its first argument.
+When its first argument is a string, 'make-text-button' no longer
+modifies the string's text properties; instead, it uses and returns
+a copy of the string. This helps avoid trouble when strings are
+shared or constants.
+
++++
+** Some properties from completion tables are now preserved.
+If 'minibuffer-allow-text-properties' is non-nil, doing completion
+over a table of strings with properties will no longer remove all the
+properties before returning. This affects things like 'completing-read'.
+
+---
+** 'dns-query' now consistently uses Lisp integers to represent integers.
+Formerly it made an exception for integer components of SOA records,
+because SOA serial numbers can exceed fixnum ranges on 32-bit platforms.
+Emacs now supports bignums so this old glitch is no longer needed.
+
++++
+** The '&define' keyword in an Edebug specification now disables backtracking.
+The implementation was buggy, and multiple '&define' forms in an '&or'
+form should be exceedingly rare. See the Info node "(elisp) Backtracking" in
+the Emacs Lisp reference manual for background.
+
++++
+** The error 'ftp-error' belongs also to category 'remote-file-error'.
+
++++
+** The WHEN argument of 'make-obsolete' and related functions is mandatory.
+The use of those functions without a WHEN argument was marked obsolete
+back in Emacs 23.1. The affected functions are: 'make-obsolete',
+'define-obsolete-function-alias', 'make-obsolete-variable',
+'define-obsolete-variable-alias'.
+
++++
+** 'inhibit-nul-byte-detection' is renamed to 'inhibit-null-byte-detection'.
+
+---
+** Some functions are no longer considered safe by 'unsafep':
+'replace-regexp-in-string', 'catch', 'throw', 'error', 'signal'
+and 'play-sound-file'.
+
+---
+** 'sql-*-statement-starters' are no longer user options.
+These variables describe facts about the SQL standard and
+product-specific additions. There should be no need for users to
+customize them.
+
+---
+** Some locale-related variables have been removed.
+The Lisp variables 'previous-system-messages-locale' and
+'previous-system-time-locale' have been removed, as they were created
+by mistake and were not useful to Lisp code.
+
+---
+** Function 'lm-maintainer' is replaced with 'lm-maintainers'.
+The former is now declared obsolete.
+
++++
+** facemenu.el is no longer preloaded.
+To use functions/variables from the package, you now have to say
+'(require 'facemenu)' or similar.
+
+---
+** 'facemenu-color-alist' is now obsolete, and is not used.
+
+---
+** The variable 'keyboard-type' is obsolete and not dynamically scoped any more.
+
++++
+** The 'values' variable is now obsolete.
+Using it just contributes to the growth of the Emacs memory
+footprint.
+
+---
+** The 'load-dangerous-libraries' variable is now obsolete.
+It was used to allow loading Lisp libraries compiled by XEmacs, a
+modified version of Emacs which is no longer actively maintained.
+This is no longer supported, and setting this variable has no effect.
+
++++
+** The macro 'with-displayed-buffer-window' is now obsolete.
+Use macro 'with-current-buffer-window' with action alist entry 'body-function'.
+
+---
+** The rfc2368.el library is now obsolete.
+Use rfc6068.el instead. The main difference is that
+'rfc2368-parse-mailto-url' and 'rfc2368-unhexify-string' assumed that
+the strings were all-ASCII, while 'rfc6068-parse-mailto-url' and
+'rfc6068-unhexify-string' parse UTF-8 strings.
+
+---
+** The inversion.el library is now obsolete.
+
+---
+** The metamail.el library is now obsolete.
+
+** Edebug changes
+
+---
+*** 'get-edebug-spec' is obsolete, replaced by 'edebug-get-spec'.
+
++++
+*** The spec operator ':name NAME' is obsolete, use '&name' instead.
+
++++
+*** The spec element 'function-form' is obsolete, use 'form' instead.
+
++++
+*** New function 'def-edebug-elem-spec' to define Edebug spec elements.
+These used to be defined with 'def-edebug-spec' thus conflating the
+two name spaces, which lead to name collisions.
+The use of 'def-edebug-spec' to define Edebug spec elements is
+declared obsolete.
+
+---
+** The sb-image.el library is now obsolete.
+This was a compatibility kludge which is no longer needed.
+
+---
+** Some libraries obsolete since Emacs 23 have been removed:
+ledit.el, lmenu.el, lucid.el and old-whitespace.el.
+
+---
+** Some functions and variables obsolete since Emacs 23 have been removed:
+'GOLD-map', 'advertised-xscheme-send-previous-expression',
+'allout-init', 'bookmark-jump-noselect',
+'bookmark-read-annotation-text-func', 'buffer-menu-mode-hook',
+'c-forward-into-nomenclature', 'char-coding-system-table',
+'char-valid-p', 'charset-bytes', 'charset-id', 'charset-list',
+'choose-completion-delete-max-match', 'complete-in-turn',
+'completion-base-size', 'completion-common-substring',
+'crm-minibuffer-complete', 'crm-minibuffer-complete-and-exit',
+'crm-minibuffer-completion-help', 'custom-mode', 'custom-mode-hook',
+'define-key-rebound-commands', 'define-mode-overload-implementation',
+'detect-coding-with-priority', 'dirtrack-debug',
+'dirtrack-debug-toggle', 'dynamic-completion-table',
+'easy-menu-precalculate-equivalent-keybindings',
+'epa-display-verify-result', 'epg-passphrase-callback-function',
+'erc-announced-server-name', 'erc-default-coding-system',
+'erc-process', 'erc-send-command', 'eshell-report-bug',
+'eval-next-after-load', 'exchange-dot-and-mark', 'ffap-bug',
+'ffap-submit-bug', 'ffap-version', 'file-cache-mouse-choose-completion',
+'forward-point', 'generic-char-p', 'global-highlight-changes',
+'hi-lock-face-history', 'hi-lock-regexp-history',
+'highlight-changes-active-string', 'highlight-changes-initial-state',
+'highlight-changes-passive-string',
+'icalendar--datetime-to-noneuropean-date', 'image-mode-maybe',
+'imenu-example--name-and-position', 'ispell-aspell-supports-utf8',
+'lisp-mode-auto-fill', 'locate-file-completion', 'make-coding-system',
+'menu-bar-files-menu', 'minibuffer-local-must-match-filename-map',
+'mouse-choose-completion', 'mouse-major-mode-menu',
+'mouse-popup-menubar', 'mouse-popup-menubar-stuff',
+'newsticker-groups-filename', 'nnir-swish-e-index-file',
+'nnmail-fix-eudora-headers', 'non-iso-charset-alist',
+'nonascii-insert-offset', 'nonascii-translation-table',
+'password-read-and-add', 'pre-abbrev-expand-hook', 'princ-list',
+'print-help-return-message', 'process-filter-multibyte-p',
+'read-file-name-predicate', 'remember-buffer', 'rmail-highlight-face',
+'rmail-message-filter', 'semantic-after-idle-scheduler-reparse-hooks',
+'semantic-after-toplevel-bovinate-hook',
+'semantic-before-idle-scheduler-reparse-hooks',
+'semantic-before-toplevel-bovination-hook',
+'semantic-bovinate-from-nonterminal-full',
+'semantic-bovinate-region-until-error', 'semantic-bovinate-toplevel',
+'semantic-bovination-working-type',
+'semantic-decorate-pending-decoration-hooks',
+'semantic-edits-incremental-reparse-failed-hooks',
+'semantic-eldoc-current-symbol-info', 'semantic-expand-nonterminal',
+'semantic-file-token-stream', 'semantic-find-dependency',
+'semantic-find-nonterminal', 'semantic-flex', 'semantic-flex-buffer',
+'semantic-flex-keyword-get', 'semantic-flex-keyword-p',
+'semantic-flex-keyword-put', 'semantic-flex-keywords',
+'semantic-flex-list', 'semantic-flex-make-keyword-table',
+'semantic-flex-map-keywords', 'semantic-flex-token-end',
+'semantic-flex-token-start', 'semantic-flex-token-text',
+'semantic-imenu-bucketize-type-parts',
+'semantic-imenu-expand-type-parts', 'semantic-imenu-expandable-token',
+'semantic-init-db-hooks', 'semantic-init-hooks',
+'semantic-init-mode-hooks', 'semantic-java-prototype-nonterminal',
+'semantic-nonterminal-abstract', 'semantic-nonterminal-full-name',
+'semantic-nonterminal-leaf', 'semantic-nonterminal-protection',
+'semantic-something-to-stream', 'semantic-tag-make-assoc-list',
+'semantic-token-type-parent', 'semantic-toplevel-bovine-cache',
+'semantic-toplevel-bovine-table', 'semanticdb-mode-hooks',
+'set-coding-priority', 'set-process-filter-multibyte',
+'shadows-compare-text-p', 'shell-dirtrack-toggle',
+'speedbar-navigating-speed', 'speedbar-update-speed', 't-mouse-mode',
+'term-dynamic-simple-complete', 'tooltip-hook', 'tpu-have-ispell',
+'url-generate-unique-filename', 'url-temporary-directory',
+'vc-arch-command', 'vc-default-working-revision' (variable),
+'vc-mtn-command', 'vc-revert-buffer', 'vc-workfile-version',
+'vcursor-toggle-vcursor-map', 'w32-focus-frame', 'w32-select-font',
+'wisent-lex-make-token-table'.
+
+---
+** Some functions and variables obsolete since Emacs 22 have been removed:
+'erc-current-network', 'gnus-article-hide-pgp-hook',
+'gnus-inews-mark-gcc-as-read', 'gnus-treat-display-xface',
+'gnus-treat-strip-pgp', 'nnmail-spool-file'.
+
+---
+** The obsolete function 'thread-alive-p' has been removed.
+
+---
+** The variable 'force-new-style-backquotes' has been removed.
+This removes the final remaining trace of old-style backquotes.
+
+---
+** Some obsolete variable and function aliases in dbus.el have been removed.
+In Emacs 24.3, the variable 'dbus-event-error-hooks' was renamed to
+'dbus-event-error-functions' and the function
+'dbus-call-method-non-blocking' was renamed to 'dbus-call-method'.
+The old names, which were kept as obsolete aliases of the new names,
+have now been removed.
+
+---
+** 'find-function-source-path' renamed and re-documented.
+The 'find-function' command (and various related commands) were
+documented to respect 'find-function-source-path', and to search for
+objects in files specified by that variable. It's unclear when this
+actually changed, but at some point (perhaps decades ago) these
+commands started using 'load-history' to determine where symbols had
+been defined (which is much faster). The doc strings of all the
+affected function have been updated. 'find-function-source-path' was
+still being used by 'find-library' and related commands, so the
+user option has been renamed to 'find-library-source-path', and
+'find-function-source-path' is now an obsolete variable alias.
+
+---
+** The macro 'vc-call' no longer evaluates its second argument twice.
+
+** Xref migrated from EIEIO to cl-defstruct for its core objects.
+This means that 'oref' and 'with-slots' no longer works on them, and
+'make-instance' can no longer be used to create those instances (which
+wasn't recommended anyway). Packages should restrict themselves to
+using functions like 'xref-make', 'xref-make-match',
+'xref-make-*-location', as well as accessor functions
+'xref-item-summary' and 'xref-item-location'.
+
+Among the benefits are better performance (noticeable when there are a
+lot of matches) and improved flexibility: 'xref-match-item' instances
+do not require that 'location' inherits from 'xref-location' anymore
+(that class was removed), so packages can create new location types to
+use with "match items" without adding EIEIO as a dependency.
+
+
+* Lisp Changes in Emacs 28.1
+
++++
+** The 'interactive' syntax has been extended to allow listing applicable modes.
+Forms like '(interactive "p" dired-mode)' can be used to annotate the
+commands as being applicable for modes derived from 'dired-mode',
+or if the mode is a minor mode, when the current buffer has that
+minor mode activated. Note that using this form will create byte code
+that is not compatible with byte code in previous Emacs versions.
+
++++
+** New forms to declare how completion should happen has been added.
+'(declare (completion PREDICATE))' can be used as a general predicate
+to say whether the command should be present when completing with
+'M-x TAB'. '(declare (modes MODE...))' can be used as a short-hand
+way of saying that the command should be present when completing 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.
+
++++
+** 'define-minor-mode' now takes an ':interactive' argument.
+This can be used for specifying which modes this minor mode is meant
+for, or to make the new minor mode non-interactive. The default value
+is t.
+
++++
+** 'define-derived-mode' now takes an ':interactive' argument.
+This can be used to control whether the defined mode is a command
+or not, and is useful when defining commands that aren't meant to be
+used by users directly.
+
++++
+** 'define-globalized-minor-mode' now takes a ':predicate' parameter.
+This can be used to control which major modes the minor mode should be
+used in.
+
++++
+** 'condition-case' now allows for a success handler.
+It is written as '(:success BODY...)' where BODY is executed
+whenever the protected form terminates without error, with the
+specified variable bound to the value of the protected form.
+
++++
+** New function 'benchmark-call' to measure the execution time of a function.
+Additionally, the number of repetitions can be expressed as a minimal duration
+in seconds.
+
++++
+** The value thrown to the 'exit' label can now be a function.
+This is in addition to values t or nil. If the value is a function,
+the command loop will call it with zero arguments before returning.
+
++++
+** The behavior of 'format-spec' is now closer to that of 'format'.
+In order for the two functions to behave more consistently,
+'format-spec' now pads and truncates based on string width rather than
+length, and also supports format specifications that include a
+truncating precision field, such as "%.2a".
+
+---
+** 'defvar' detects the error of defining a variable currently lexically bound.
+Such mixes are always signs that the outer lexical binding was an
+error and should have used dynamic binding instead.
+
+---
+** New variable 'inhibit-mouse-event-check'.
+If bound to non-nil, a command with '(interactive "e")' doesn't signal
+an error when invoked by input event that is not a mouse click (e.g.,
+a key sequence).
+
+---
+** New variable 'redisplay-skip-initial-frame' to enable batch redisplay tests.
+Setting it to nil forces the redisplay to do its job even in the
+initial frame used in batch mode.
+
++++
+** Doc strings can now link to customization groups.
+Text like "customization group `whitespace'" will be made into a
+button. When clicked, it will open a Custom buffer displaying that
+customization group.
+
++++
+** Doc strings can now link to man pages.
+Text like "man page `chmod(1)'" will be made into a button. When
+clicked, it will open a Man mode buffer displaying that man page.
+
++++
+** Buffers can now be created with certain hooks disabled.
+The functions 'get-buffer-create' and 'generate-new-buffer' accept a
+new optional argument INHIBIT-BUFFER-HOOKS. If non-nil, the new
+buffer does not run the hooks 'kill-buffer-hook',
+'kill-buffer-query-functions', and 'buffer-list-update-hook'. This
+avoids slowing down internal or temporary buffers that are never
+presented to users or passed on to other applications.
+
++++
+** New command 'make-directory-autoloads'.
+This does the same as the old command 'update-directory-autoloads',
+but has different semantics: Instead of passing in the output file via
+the dynamically bound 'generated-autoload-file' variable, the output
+file is now a explicit parameter.
+
+---
+** Dragging a file into Emacs pushes the file name onto 'file-name-history'.
+
+---
+** The 'easymenu' library is now preloaded.
+
+---
+** The 'iso-transl' library is now preloaded.
+This means that keystrokes like 'Alt-[' are defined by default,
+instead of only becoming available after doing (for instance)
+'C-x 8 <letter>'.
+
+---
+** ':safe' settings in 'defcustom' are now propagated to the loaddefs files.
+
++++
+** New ':type' for 'defcustom' for nonnegative integers.
+The new 'natnum' type can be used for options that should be
+nonnegative integers.
+
++++
+** ERT can now output more verbose test failure reports.
+If the 'EMACS_TEST_VERBOSE' environment variable is set, failure
+summaries will include the failing condition.
+
+** Byte compiler changes
+
++++
+*** New byte-compiler check for missing dynamic variable declarations.
+It is meant as an (experimental) aid for converting Emacs Lisp code
+to lexical binding, where dynamic (special) variables bound in one
+file can affect code in another. For details, see the manual section
+"(elisp) Converting to Lexical Binding".
+
++++
+*** 'byte-recompile-directory' can now compile symlinked ".el" files.
+This is achieved by giving a non-nil FOLLOW-SYMLINKS parameter.
+
+---
+*** The byte-compiler now warns about too wide documentation strings.
+By default, it will warn if a documentation string is wider than the
+largest of 'byte-compile-docstring-max-column' or 'fill-column'
+characters.
+
++++
+*** 'byte-compile-file' optional argument LOAD is now obsolete.
+To load the file after byte-compiling, add a call to 'load' from Lisp
+or use 'M-x emacs-lisp-byte-compile-and-load' interactively.
+
+** Macroexp
+
+---
+*** New function 'macroexp-file-name' to know the name of the current file.
+
+---
+*** New function 'macroexp-compiling-p' to know if we're compiling.
+
+---
+*** New function 'macroexp-warn-and-return' to help emit warnings.
+This used to be named 'macroexp--warn-and-return' and has proved useful
+and well-behaved enough to lose the "internal" marker.
+
+** map.el
+
+---
+*** Alist keys are now consistently compared with 'equal' by default.
+Until now, 'map-elt' and 'map-delete' compared alist keys with 'eq' by
+default. They now use 'equal' instead, for consistency with
+'map-put!' and 'map-contains-key'.
+
+*** Pcase 'map' pattern added keyword symbols abbreviation.
+A pattern like '(map :sym)' binds the map's value for ':sym' to 'sym',
+equivalent to '(map (:sym sym))'.
+
+---
+*** The function 'map-copy' now uses 'copy-alist' on alists.
+This is a slightly deeper copy than the previous 'copy-sequence'.
+
+---
+*** The function 'map-contains-key' now supports plists.
+
+---
+*** More consistent duplicate key handling in 'map-merge-with'.
+Until now, 'map-merge-with' promised to call its function argument
+whenever multiple maps contained 'eql' keys. However, this did not
+always coincide with the keys that were actually merged, which could
+be 'equal' instead. The function argument is now called whenever keys
+are merged, for greater consistency with 'map-merge' and 'map-elt'.
+
+** pcase
+
++++
+*** The 'or' pattern now binds the union of the vars of its sub-patterns.
+If a variable is not bound by the subpattern that matched, it gets bound
+to nil. This was already sometimes the case, but it is now guaranteed.
+
++++
+*** The 'pred' pattern can now take the form '(pred (not FUN))'.
+This is like '(pred (lambda (x) (not (FUN x))))' but results
+in better code.
+
+---
+*** New function 'pcase-compile-patterns' to write other macros.
+
++++
+*** Added 'cl-type' pattern.
+The new 'cl-type' pattern compares types using 'cl-typep', which allows
+comparing simple types like '(cl-type integer)', as well as forms like
+'(cl-type (integer 0 10))'.
+
++++
+*** New macro 'pcase-setq'.
+This macro is the 'setq' equivalent of 'pcase-let', which allows for
+destructuring patterns in a 'setq' form.
+
+** Edebug
+
+*** Edebug specification lists can use some new keywords:
+
++++
+**** '&interpose SPEC FUN ARGS..' lets FUN control parsing after SPEC.
+More specifically, FUN is called with 'HEAD PF ARGS..' where
+PF is a parsing function that expects a single argument (the specs to
+use) and HEAD is the code that matched SPEC.
+
++++
+**** '&error MSG' unconditionally aborts the current edebug instrumentation.
+
++++
+**** '&name SPEC FUN' extracts the current name from the code matching SPEC.
+
+** Dynamic modules changes
+
++++
+*** Type aliases for module functions and finalizers.
+The module header 'emacs-module.h' now contains type aliases
+'emacs_function' and 'emacs_finalizer' for module functions and
+finalizers, respectively.
+
++++
+*** Module functions can now be made interactive.
+Use 'make_interactive' to give a module function an interactive
+specification.
+
++++
+*** Module functions can now install an optional finalizer.
+The finalizer is called when the function object is garbage-collected.
+Use 'set_function_finalizer' to set the finalizer and
+'get_function_finalizer' to retrieve it.
+
++++
+*** Modules can now open a channel to an existing pipe process.
+Modules can use the new module function 'open_channel' to do that.
+On capable systems, modules can use this functionality to
+asynchronously send data back to Emacs.
+
++++
+*** A new module API 'make_unibyte_string'.
+It can be used to create Lisp strings with arbitrary byte sequences
+(a.k.a. "raw bytes").
+
++++
+** Shorthands for Lisp symbols.
+Shorthands are a general purpose namespacing system to make Emacs
+Lisp's symbol-naming etiquette easier to use. A shorthand is any
+symbolic form found in Lisp source that "abbreviates" a symbol's print
+name. Among other applications, this feature can be used to avoid
+name clashes and namespace pollution by renaming an entire file's
+worth of symbols with proper and longer prefixes, without actually
+touching the Lisp source. For details, see the manual section
+"(elisp) Shorthands".
+
++++
+** New function 'string-search'.
+This function takes two string parameters and returns the position of
+the first instance of the former string in the latter.
+
++++
+** New function 'string-replace'.
+This function works along the line of 'replace-regexp-in-string', but
+it matches on fixed strings instead of regexps, and does not change
+the global match state.
+
++++
+** New function 'ensure-list'.
+This function makes a list of its object if it's not a list already.
+If it's already a list, the list is returned as is.
+
++++
+** New function 'split-string-shell-command'.
+This splits a shell command string into separate components,
+respecting quoting with single ('like this') and double ("like this")
+quotes, as well as backslash quoting (like\ this).
+
++++
+** New function 'string-clean-whitespace'.
+This removes whitespace from a string.
+
++++
+** New function 'string-fill'.
+Word-wrap a string so that no lines are longer that a specific length.
+
++++
+** New function 'string-limit'.
+Return (up to) a specific substring length.
+
++++
+** New function 'string-lines'.
+Return a list of strings representing the individual lines in a
+string.
+
++++
+** New function 'string-pad'.
+Pad a string to a specific length.
+
++++
+** New function 'string-chop-newline'.
+Remove a trailing newline from a string.
+
++++
+** New function 'replace-regexp-in-region'.
+
++++
+** New function 'replace-string-in-region'.
+
++++
+** New function 'file-name-with-extension'.
+This function allows a canonical way to set/replace the extension of a
+file name.
+
++++
+** New function 'file-modes-number-to-symbolic' to convert a numeric
+file mode specification into symbolic form.
+
++++
+** New function 'file-name-concat'.
+This appends file name components to a directory name and returns the
+result.
+
++++
+** New function 'file-backup-file-names'.
+This function returns the list of file names of all the backup files
+for the specified file.
+
++++
+** New function 'directory-empty-p'.
+This predicate tests whether a given file name is an accessible
+directory and whether it contains no other directories or files.
+
++++
+** New function 'buffer-local-boundp'.
+This predicate says whether a symbol is bound in a specific buffer.
+
++++
+** New function 'always'.
+This is identical to 'ignore', but returns t instead.
+
++++
+** New function 'sxhash-equal-including-properties'.
+This is identical to 'sxhash-equal' but also accounts for string
+properties.
+
+---
+** New function 'buffer-line-statistics'.
+This function returns some statistics about the line lengths in a buffer.
+
+---
+** New function 'color-values-from-color-spec'.
+This can be used to parse RGB color specs in several formats and
+convert them to a list '(R G B)' of primary color values.
+
+---
+** New function 'custom-add-choice'.
+This function can be used by modes to add elements to the
+'choice' customization type of a variable.
+
+---
+** New function 'decoded-time-period'.
+It interprets a decoded time structure as a period and returns the
+equivalent period in seconds.
+
++++
+** New function 'dom-print'.
+
++++
+** New function 'dom-remove-attribute'.
+
+---
+** New function 'dns-query-asynchronous'.
+It takes the same parameters as 'dns-query', but adds a callback
+parameter.
+
+** New function 'garbage-collect-maybe' to trigger GC early.
+
+---
+** New function 'get-locale-names'.
+This utility function returns a list of names of locales available on
+the current system.
+
++++
+** New function 'insert-into-buffer'.
+This inserts the contents of the current buffer into another buffer.
+
++++
+** New function 'json-available-p'.
+This predicate returns non-nil if Emacs is built with libjansson
+support, and it is available on the current system.
+
+---
+** New function 'mail-header-parse-addresses-lax'.
+This takes a comma-separated string and returns a list of mail/name
+pairs.
+
+---
+** New function 'mail-header-parse-address-lax'.
+Parse a string as a mail address-like string.
+
+---
+** New function 'make-separator-line'.
+Make a string appropriate for usage as a visual separator line.
+
++++
+** New function 'num-processors'.
+Return the number of processors on the system.
+
++++
+** New function 'object-intervals'.
+This function returns a copy of the list of intervals (i.e., text
+properties) in the object in question (which must either be a string
+or a buffer).
+
++++
+** New function 'process-lines-ignore-status'.
+This is like 'process-lines', but does not signal an error if the
+return status is non-zero. 'process-lines-handling-status' has also
+been added, and takes a callback to handle the return status.
+
++++
+** New function 'require-theme'.
+This function is like 'require', but searches 'custom-theme-load-path'
+instead of 'load-path'. It can be used by Custom themes to load
+supporting Lisp files when 'require' is unsuitable.
+
++++
+** New function 'seq-union'.
+This function takes two sequences and returns a list of all elements
+that appear in either of them, with no two elements that compare equal
+appearing in the result.
+
++++
+** New function 'syntax-class-to-char'.
+This does almost the opposite of 'string-to-syntax' -- it returns the
+syntax descriptor (a character) given a raw syntax descriptor (an
+integer).
+
++++
+** New functions 'null-device' and 'path-separator'.
+These functions return the connection local value of the respective
+variables. This can be used for remote hosts.
+
++++
+** New predicate functions 'length<', 'length>' and 'length='.
+Using these functions may be more efficient than using 'length' (if
+the length of a (long) list is being computed just to compare this
+length to a number).
+
++++
+** New macro 'dlet' to dynamically bind variables.
+
++++
+** New macro 'with-existing-directory'.
+This macro binds 'default-directory' to some other existing directory
+if 'default-directory' doesn't exist, and then executes the body forms.
+
++++
+** New variable 'current-minibuffer-command'.
+This is like 'this-command', but it is bound recursively when entering
+the minibuffer.
+
++++
+** New variable 'inhibit-interaction' to make user prompts signal an error.
+If this is bound to something non-nil, functions like
+'read-from-minibuffer', 'read-char' (and related) will signal an
+'inhibited-interaction' error.
+
+---
+** New variable 'indent-line-ignored-functions'.
+This allows modes to cycle through a set of indentation functions
+appropriate for those modes.
+
++++
+** New variable 'print-integers-as-characters' modifies integer printing.
+If this variable is non-nil, character syntax is used for printing
+numbers when this makes sense, such as '?A' for 65.
+
++++
+** New variable 'tty-menu-calls-mouse-position-function'.
+This controls whether 'mouse-position-function' is called by functions
+that retrieve the mouse position when that happens during TTY menu
+handling. Lisp programs that set 'mouse-position-function' should
+also set this variable non-nil if they are compatible with the tty
+menu handling.
+
++++
+** New variables that hold default buffer names for shell output.
+The new constants 'shell-command-buffer-name' and
+'shell-command-buffer-name-async' store the default buffer names
+for the output of, respectively, synchronous and async shell
+commands.
+
+---
+** New variables 'read-char-choice-use-read-key' and 'y-or-n-p-use-read-key'.
+When non-nil, then functions 'read-char-choice' and 'y-or-n-p'
+(respectively) use the function 'read-key' to read a character instead
+of using the minibuffer.
+
++++
+** New variable 'global-minor-modes'.
+This variable holds a list of currently enabled global minor modes (as
+a list of symbols).
+
++++
+** New buffer-local variable 'local-minor-modes'.
+This permanently buffer-local variable holds a list of currently
+enabled non-global minor modes in the current buffer (as a list of
+symbols).
+
++++
+** New completion function 'affixation-function' to add prefix/suffix.
+It accepts a list of completions and should return a list where
+each element is a list with three elements: a completion,
+a prefix string, and a suffix string.
+
++++
+** New completion function 'group-function' for grouping candidates.
+It takes two arguments: a completion candidate and a 'transform' flag.
+
++++
+** New error symbol 'minibuffer-quit'.
+Signaling it has almost the same effect as 'quit' except that it
+doesn't cause keyboard macro termination.
+
++++
+** New error 'remote-file-error', a subcategory of 'file-error'.
+It is signaled if a remote file operation fails due to internal
+reasons, and could block Emacs. It does not replace 'file-error'
+signals for the usual cases. Timers, process filters and process
+functions, which run remote file operations, shall protect themselves
+against this error.
+
+If such an error occurs, please report this as bug via 'M-x report-emacs-bug'.
+Until it is solved you could ignore such errors by performing
+
+ (setq debug-ignored-errors (cons 'remote-file-error debug-ignored-errors))
+
++++
+** New macro 'named-let' added to subr-x.el.
+It provides Scheme's "named let" looping construct.
+
+---
+** Emacs now attempts to test for high-rate subprocess output more fairly.
+When several subprocesses produce output simultaneously at high rate,
+Emacs will now by default attempt to service them all in a round-robin
+fashion. Set the new variable 'process-prioritize-lower-fds' to a
+non-nil value to get back the old behavior, whereby after reading
+from a subprocess, Emacs would check for output of other subprocesses
+in a way that is likely to read from the same process again.
+
++++
+** 'set-process-buffer' now updates the process mark.
+The mark will be set to point to the end of the new buffer.
+
++++
+** 'unlock-buffer' displays warnings instead of signaling.
+Instead of signaling 'file-error' conditions for file system level
+errors, the function now calls 'display-warning' and continues as if
+the error did not occur.
+
++++
+** 'read-char-from-minibuffer' and 'y-or-n-p' support 'help-form'.
+If you bind 'help-form' to a non-nil value while calling these functions,
+then pressing 'C-h' ('help-char') causes the function to evaluate 'help-form'
+and display the result.
+
++++
+** 'read-number' now has its own history variable.
+Additionally, the function now accepts a HIST argument which can be
+used to specify a custom history variable.
+
++++
+** 'set-window-configuration' now takes two optional parameters,
+'dont-set-frame' and 'dont-set-miniwindow'. The first of these, when
+non-nil, instructs the function not to select the frame recorded in
+the configuration. The second prevents the current minibuffer being
+replaced by the one stored in the configuration.
+
+---
+** 'count-windows' now takes an optional parameter ALL-FRAMES.
+The semantics are as with 'walk-windows'.
+
++++
+** 'truncate-string-ellipsis' now uses '…' by default.
+Modes that use 'truncate-string-to-width' with non-nil, non-string
+argument ELLIPSIS, will now indicate truncation using '…' when
+the selected frame can display it, and using "..." otherwise.
+
++++
+** 'string-width' now accepts two optional arguments FROM and TO.
+This allows calculating the width of a substring without consing a
+new string.
+
++++
+** 'directory-files' now takes an additional COUNT parameter.
+The parameter makes 'directory-files' return COUNT first file names
+from a directory. If MATCH is also given, the function will return
+first COUNT file names that match the expression. The same COUNT
+parameter has been added to 'directory-files-and-attributes'.
+
++++
+** 'count-lines' can now ignore invisible lines.
+This is controlled by the optional parameter IGNORE-INVISIBLE-LINES.
+
+---
+** 'count-words' now crosses field boundaries.
+Originally, 'count-words' would stop counting at the first field
+boundary it encountered; now it keeps counting all the way to the
+region's (or buffer's) end.
+
++++
+** File-related APIs can optionally follow symlinks.
+The functions 'file-modes', 'set-file-modes', and 'set-file-times' now
+have an optional argument specifying whether to follow symbolic links.
+
++++
+** 'format-seconds' can now be used for sub-second times.
+The new optional "," parameter has been added, and
+'(format-seconds "%mm %,1ss" 66.4)' will now result in "1m 6.4s".
+
++++
+** 'parse-time-string' can now parse ISO 8601 format strings.
+These have a format like "2020-01-15T16:12:21-08:00".
+
+---
+** 'lookup-key' is more allowing when searching for extended menu items.
+When looking for a menu item '[menu-bar Foo-Bar]', first try to find
+an exact match, then look for the lowercased '[menu-bar foo-bar]'.
+It will only try to downcase ASCII characters in the range "A-Z".
+This improves backwards-compatibility when converting menus to use
+'easy-menu-define'.
+
+---
+** 'make-network-process', 'make-serial-process' ':coding' behavior change.
+Previously, passing ':coding nil' to either of these functions would
+override any non-nil binding for 'coding-system-for-read' and
+'coding-system-for-write'. For consistency with 'make-process' and
+'make-pipe-process', passing ':coding nil' is now ignored. No code in
+Emacs depended on the previous behavior; if you really want the
+process' coding-system to be nil, use 'set-process-coding-system'
+after the process has been created, or pass in ':coding '(nil nil)'.
+
++++
+** 'open-network-stream' now accepts a ':coding' argument.
+This allows specifying the coding systems used by a network process
+for encoding and decoding without having to bind
+'coding-system-for-{read,write}' or call 'set-process-coding-system'.
+
++++
+** 'open-network-stream' can now take a ':capability-command' that's a function.
+The function is called with the greeting from the server as its only
+parameter, and allows sending different TLS capability commands to the
+server based on that greeting.
+
++++
+** 'open-gnutls-stream' now also accepts a ':coding' argument.
+
+---
+** 'process-attributes' now works under OpenBSD, too.
+
++++
+** 'format-spec' now takes an optional SPLIT parameter.
+If non-nil, 'format-spec' will split the resulting string into a list
+of strings, based on where the format specs (and expansions) were.
+
+---
+** 'unload-feature' now also tries to undo additions to buffer-local hooks.
+
+---
+** 'while-no-input-ignore-events' accepts more special events.
+The special events 'dbus-event' and 'file-notify' are now ignored in
+'while-no-input' when added to this variable.
+
+---
+** 'start-process-shell-command' and 'start-file-process-shell-command'
+do not support the old calling conventions any longer.
+
++++
+** 'yes-or-no-p' and 'y-or-n-p' PROMPT parameter no longer needs trailing space.
+In other words, the prompt can now end with "?" instead of "? ". This
+has been the case since Emacs 24.4 but was not announced or documented
+until now. (Checkdoc has also been updated to accept this convention.)
+
++++
+** The 'uniquify' argument in 'auto-save-file-name-transforms' can be a symbol.
+If this symbol is one of the members of 'secure-hash-algorithms',
+Emacs constructs the nondirectory part of the auto-save file name by
+applying that 'secure-hash' to the buffer file name. This avoids any
+risk of excessively long file names.
+
++++
+** New user option 'process-file-return-signal-string'.
+It controls, whether 'process-file' returns a string when a remote
+process is interrupted by a signal.
+
+** EIEIO Changes
+
++++
+*** The macro 'oref-default' can now be used with 'setf'.
+It is now defined as a generalized variable that can be used with
+'setf' to modify the value stored in a given class slot.
+
+---
+*** 'form' in '(eql form)' specializers in 'cl-defmethod' is now evaluated.
+This corresponds to the behavior of defmethod in Common Lisp Object System.
+For compatibility, '(eql SYMBOL)' does not evaluate SYMBOL, for now.
+
+** D-Bus
+
++++
+*** Property values can be typed explicitly.
+'dbus-register-property' and 'dbus-set-property' accept now optional
+type symbols. Both functions propagate D-Bus errors.
+
++++
+*** Registered properties can have the new access type ':write'.
+
++++
+*** In case of problems, handlers can emit proper D-Bus error messages now.
+
++++
+*** D-Bus errors, which have been converted from incoming D-Bus error
+messages, contain the error name of that message now.
+
++++
+*** D-Bus messages can be monitored with the new command 'dbus-monitor'.
+
++++
+*** D-Bus events have changed their internal structure.
+They carry now the destination and the error-name of an event. They
+also keep the type information of their arguments. Use the
+'dbus-event-*' accessor functions.
+
+** Buttons
+
++++
+*** New minor mode 'button-mode'.
+This minor mode does nothing except install 'button-buffer-map' as
+a minor mode map (which binds the 'TAB' / 'S-TAB' key bindings to navigate
+to buttons), and can be used in any view-mode-like buffer that has
+buttons in it.
+
++++
+*** New utility function 'button-buttonize'.
+This function takes a string and returns a string propertized in a way
+that makes it a valid button.
+
+---
+** 'text-scale-mode' can now adjust font size of the header line.
+When the new buffer local variable 'text-scale-remap-header-line'
+is non-nil, 'text-scale-adjust' will also scale the text in the header
+line when displaying that buffer.
+
+This is useful for major modes that arrange their display in a tabular
+form below the header line. It is enabled by default in
+'tabulated-list-mode' and its derived modes, and disabled by default
+elsewhere.
+
+---
+** 'ascii' is now a coding system alias for 'us-ascii'.
+
+---
+** New coding-systems for EBCDIC variants.
+New coding-systems 'ibm256', 'ibm273', 'ibm274', 'ibm277', 'ibm278',
+'ibm280', 'ibm281', 'ibm284', 'ibm285', 'ibm290', 'ibm297'. These are
+variants of the EBCDIC encoding tailored to some European and Japanese
+locales. They are also available as aliases 'ebcdic-cp-*' (e.g.,
+'ebcdic-cp-fi' for the Finnish variant 'ibm278'), and 'cp2xx' (e.g.,
+'cp278' for 'ibm278'). There are also new charsets 'ibm2xx' to
+support these coding-systems.
+
++++
+** New 'Bindat type expression' description language.
+This new system is provided by the new macro 'bindat-type' and
+obsoletes the old data layout specifications. It supports
+arbitrary-size integers, recursive types, and more. See the Info node
+"(elisp) Byte Packing" in the ELisp manual for more details.
+
++++
+** New macro 'with-environment-variables'.
+This macro allows setting environment variables temporarily when
+executing a form.
+
+
+* Changes in Emacs 28.1 on Non-Free Operating Systems
+
++++
+** On MS-Windows, Emacs can now use the native image API to display images.
+Emacs can now use the MS-Windows GDI+ library to load and display
+images in JPEG, PNG, GIF and TIFF formats. This support is available
+unless Emacs was configured '--without-native-image-api'.
+
+This feature is experimental, and needs to be turned on to be used.
+To turn this on, set the variable 'w32-use-native-image-API' to a
+non-nil value. Please report any bugs you find while using the native
+image API via 'M-x report-emacs-bug'.
+
++++
+** On MS-Windows, Emacs can now toggle the IME.
+A new function 'w32-set-ime-open-status' can now be used to disable
+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-`'.
+
++++
+** On macOS, Emacs can now load dynamic modules with a ".dylib" suffix.
+'module-file-suffix' now has the value ".dylib" on macOS, but the
+".so" suffix is supported as well.
+
+---
+** On macOS, the user option 'make-pointer-invisible' is now honored.
+
+---
+** On macOS, Xwidget is now supported.
+If Emacs was built with xwidget support, you can access the embedded
+webkit browser with 'M-x xwidget-webkit-browse-url'. Viewing two
+instances of xwidget webkit is not supported.
+
+---
+*** New user option 'xwidget-webkit-enable-plugins'.
+If non-nil, enable plugins in xwidget. (This is only available on
+macOS.)
+
++++
+** New macOS Contacts back-end for EUDC.
+This backend works on newer versions of macOS and is generally
+preferred over the eudcb-mab.el backend.
+
+
+----------------------------------------------------------------------
+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/>.
+
+
+Local variables:
+coding: utf-8
+mode: outline
+paragraph-separate: "[ ]*$"
+end:
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 2b9cbf37c45..5e7813ca7fb 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -3,13 +3,583 @@ ORG NEWS -- history of user-visible changes. -*- mode: org; coding: utf-8 -*-
#+STARTUP: overview
#+LINK: doc https://orgmode.org/worg/doc.html#%s
-#+LINK: git https://code.orgmode.org/bzg/org-mode/commit/%s
+#+LINK: msg https://list.orgmode.org/%s/
+#+LINK: git https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=%s
Copyright (C) 2012-2021 Free Software Foundation, Inc.
See the end of the file for license conditions.
Please send Org bug reports to mailto:emacs-orgmode@gnu.org.
+* Version 9.5
+
+** Important announcements and breaking changes
+
+*** The =contrib/= now lives in a separate repository
+
+Org's repository has been trimmed from the =contrib/= directory.
+
+The old contents of the =contrib/= directory now lives in a separate
+repository at https://git.sr.ht/~bzg/org-contrib.
+
+You can install this repository by cloning it and updating your
+~load-path~ accordingly. You can also install =org-contrib= as a
+[[https://elpa.nongnu.org/nongnu/][NonGNU ELPA]] package.
+
+*** Org ELPA and Org archives won't be available for Org > 9.5
+
+[[https://orgmode.org/elpa.html][Org ELPA]] is still available for installing Org 9.5, either with or
+without contributed packages, but future versions won't be available
+via Org ELPA, as we are deprecating this installation method.
+
+Also, Org 9.5 is available as =tar.gz= and =zip= archives, but this
+installation method is also deprecated.
+
+If you want to install the latest stable versions of Org, please use
+the GNU ELPA package. If you want to install the contributed files,
+please use the NonGNU ELPA package. If you want to keep up with the
+latest unstable Org, please install from the Git repository.
+
+See https://orgmode.org/org.html#Installation for the details.
+
+*** =ditaa.jar= is not bundled with Org anymore
+
+=ditaa.jar= used to be bundled with Org but it is not anymore.
+See [[https://github.com/stathissideris/ditaa][the ditaa repository]] on how to install it.
+
+*** ~org-adapt-indentation~ now defaults to =nil=
+
+If you want to automatically indent headlines' metadata, set it to
+=headline-data=.
+
+If you want to automatically indent every line to the headline's
+current indentation, set it to =t=.
+
+Indent added by =RET= and =C-j= also depends on the value of
+~electric-indent-mode~. Enabling this mode by default in 9.4 revealed
+some bugs caused confusing behavior. If you disabled
+~electric-indent-mode~ for this reason, it is time to try it again.
+Hopefully problems have been fixed. See [[https://orgmode.org/worg/org-faq.html#indentation][this FAQ]] for more details.
+
+*** ~org-speed-commands-user~ is obsolete, use ~org-speed-commands~
+
+Setting ~org-speed-commands-user~ in your configuration won't have any
+effect. Please set ~org-speed-commands~ instead, which see.
+
+*** Some =ob-*.el= files have been moved to the org-contrib repo
+
+These files have been moved to https://git.sr.ht/~bzg/org-contrib:
+
+- ob-abc.el
+- ob-asymptote.el
+- ob-coq.el
+- ob-ebnf.el
+- ob-hledger.el
+- ob-io.el
+- ob-J.el
+- ob-ledger.el
+- ob-mscgen.el
+- ob-picolisp.el
+- ob-shen.el
+- ob-stan.el
+- ob-vala.el
+
+See the discussion [[msg::87bl9rq29m.fsf@gnu.org][here]].
+
+*** Compatibility with Emacs versions
+
+We made it explicit that we aim at keeping the latest stable version
+of Org compatible with at least Emacs V, V-1 and V-2, where V is the
+stable major version of Emacs.
+
+For example, if the current major version of Emacs is 28.x, then the
+latest stable version of Org should be compatible with Emacs 28.x,
+27.x and 26.x – but not with Emacs 25.x.
+
+See [[https://orgmode.org/worg/org-maintenance.html#emacs-compatibility][this note on Worg]] and [[git::519947e508e081e71bf67db99e27b1c171ba4dfe][this commit]].
+
+*** The keybinding for ~org-table-blank-field~ has been removed
+
+If you prefer to keep the keybinding, you can add it back to
+~org-mode-map~ like so:
+
+#+begin_src emacs-lisp
+(define-key org-mode-map (kbd "C-c SPC") #'org-table-blank-field)
+#+end_src
+
+** New features
+
+*** New citation engine
+
+Org 9.5 provides a new library =oc.el= which provides tooling to
+handle citations in Org, e.g., activate, follow, insert, and export
+them, respectively called "activate", "follow", "insert" and "export"
+capabilities. Libraries responsible for providing some, or all, of
+these capabilities are called "citation processors".
+
+The manual contains a few pointers to let you start and you may want
+to check [[https://blog.tecosaur.com/tmio/2021-07-31-citations.html][this blog post]]. If you need help using this new features,
+please ask on the mailing list.
+
+Thanks to Nicolas Goaziou for implementing this, to Bruce D’Arcus for
+helping him and to John Kitchin for paving the way with =org-ref.el=.
+
+*** Async session evaluation
+
+The =:async= header argument can be used for asynchronous evaluation
+in session blocks for certain languages.
+
+Currently, async evaluation is supported in Python. There is also
+functionality to implement async evaluation in other languages that
+use comint, but this needs to be done on a per-language basis.
+
+By default, async evaluation is disabled unless the =:async= header
+argument is present. You can also set =:async no= to force it off
+(for example if you've set =:async= in a property drawer).
+
+Async evaluation is disabled during export.
+*** ~ox-koma-letter.el~ is now part of Org's core
+
+~ox-koma-letter.el~ provides a KOMA scrlttr2 back-end for the Org
+export engine. It used to be in the =contrib/= directory but it is
+now part of Org's core.
+
+*** Support exporting DOI links
+
+Org now supports export for DOI links, through its new =ol-doi.el=
+library. For backward compatibility, it is loaded by default.
+
+*** Add a new ~:refile-targets~ template option
+
+When exiting capture mode via ~org-capture-refile~, the variable
+~org-refile-targets~ will be temporarily bound to the value of this
+template option.
+
+*** New startup options =#+startup: show<n>levels=
+
+These startup options complement the existing =overview=, =content=,
+=showall=, =showeverything= with a way to start the document with n
+levels shown, where n goes from 2 to 5.
+
+Example:
+
+: #+startup: show3levels
+
+*** New =u= table formula flag to enable Calc units simplification mode
+
+A new =u= mode flag for Calc formulas in Org tables has been added to
+enable Calc units simplification mode.
+
+*** Support fontification of inline export snippets
+
+See [[msg:87im57fh8j.fsf@gmail.com][this thread]].
+
+*** New command =org-refile-reverse= bound to =C-c C-M-w=
+
+You can now use =C-c C-M-w= to run ~org-refile-reverse~.
+
+It is almost identical to ~org-refile~, except that it temporarily
+toggles how ~org-reverse-note-order~ applies to the current buffer.
+So if ~org-refile~ would append the entry as the last entry under the
+target heading, ~org-refile-reverse~ will prepend it as the first
+entry, and vice-versa.
+
+*** LaTeX attribute ~:float~ now passes through arbitrary values
+
+LaTeX users are able to define arbitrary float types, e.g. with the
+float package. The Org mode LaTeX exporter is now able to process and
+export arbitrary float types. The user is responsible for ensuring
+that Org mode configures LaTeX to process any new float type.
+
+*** Support verse and quote blocks in LaTeX export
+
+The LaTeX export back-end accepts four attributes for verse blocks:
+=:lines=, =:center=, =:versewidth= and =:latexcode=. The three first
+require the external LaTeX package =verse.sty=, which is an extension
+of the standard LaTeX environment.
+
+The LaTeX export back-end accepts two attributes for quote blocks:
+=:environment=, for an arbitrary quoting environment (the default
+value is that of =org-latex-default-quote-environment=: ="quote"=) and
+=:options=.
+
+*** =org-set-tags-command= selects tags from ~org-global-tags-completion-table~
+
+Let ~org-set-tags-command~ TAB fast tag completion interface complete
+tags including from both buffer local and user defined persistent
+global list (~org-tag-alist~ and ~org-tag-persistent-alist~). Now
+option ~org-complete-tags-always-offer-all-agenda-tags~ is honored.
+
+*** Clocktable option =:formula %= now shows the per-file time percentages
+
+This change only has an effect when multiple files are contributing to
+a given clocktable (such as when =:scope agenda= has been specified).
+The existing behavior is that such tables have an extra 'File' column,
+and each individual file that contributes has its own summary line
+with the headline value '*File time*'. Those summary rows also
+produce a rollup time value for the file in the 'Time' column.
+
+Prior to this change, the built-in =%= formula did not produce a
+calculation for those per-file times in the '%' column (the relevant
+cells in the '%' column were blank). With this change, the percentage
+contribution of each individual file time to the total time is shown.
+
+The more agenda files you have, the more useful this behavior becomes.
+
+*** =ob-python.el= improvements to =:return= header argument
+
+The =:return= header argument in =ob-python= now works for session
+blocks as well as non-session blocks. Also, it now works with the
+=:epilogue= header argument -- previously, setting the =:return=
+header would cause the =:epilogue= to be ignored.
+
+This change allows more easily moving boilerplate out of the main code
+block and into the header. For example, for plotting, we need to add
+boilerplate to save the figure to a file and return the
+filename. Instead of doing this within the code block, we can now
+handle it through the header arguments as follows:
+
+#+BEGIN_SRC org
+,#+header: :var fname="/home/jack/tmp/plot.svg"
+,#+header: :epilogue plt.savefig(fname)
+,#+header: :return fname
+,#+begin_src python :results value file
+ import matplotlib, numpy
+ import matplotlib.pyplot as plt
+ fig=plt.figure(figsize=(4,2))
+ x=numpy.linspace(-15,15)
+ plt.plot(numpy.sin(x)/x)
+ fig.tight_layout()
+,#+end_src
+
+,#+RESULTS:
+[[file:/home/jack/tmp/plot.svg]]
+#+END_SRC
+
+As another example, we can use =:return= with the external [[https://pypi.org/project/tabulate/][tabulate]]
+package, to convert pandas Dataframes into orgmode tables:
+
+#+begin_src org
+,#+header: :prologue from tabulate import tabulate
+,#+header: :return tabulate(table, headers=table.columns, tablefmt="orgtbl")
+,#+begin_src python :results value raw :session
+ import pandas as pd
+ table = pd.DataFrame({
+ "a": [1,2,3],
+ "b": [4,5,6]
+ })
+,#+end_src
+
+,#+RESULTS:
+| | a | b |
+|---+---+---|
+| 0 | 1 | 4 |
+| 1 | 2 | 5 |
+| 2 | 3 | 6 |
+#+end_src
+
+*** Display images with width proportional to the buffer text width
+
+Previously, if you used a =:width= attribute like =#+attr_html: :width 70%= or
+=#+attr_latex: :width 0.7\linewidth= this would be interpreted as a 70px wide and
+0.7px wide width specification respectively.
+
+Now, percentages are transformed into floats (i.e. 70% becomes 0.7),
+and float width specifications between 0.0 and 2.0 are now interpreted
+as that portion of the text width in the buffer. For instance, the
+above examples of =70%= and =0.7\linewidth= will result in an image
+with width equal to the pixel-width of the buffer text multiplied by 0.7.
+
+This functionality is implemented in a new function,
+~org-display-inline-image--width~ which contains the width
+determination logic previously in ~org-display-inline-images~ and the
+new behaviour.
+
+** New options
+*** Option ~org-hidden-keywords~ now also applies to #+SUBTITLE:
+
+The option ~org-hidden-keywords~ previously applied
+to #+TITLE:, #+AUTHOR:, #+DATE:, and #+EMAIL:. Now it can also be
+used to hide the #+SUBTITLE: keyword.
+
+*** New formatting directive ~%L~ for org-capture
+
+The new ~%L~ formatting directive contains the bare link target, and
+may be used to create links with programmatically generated
+descriptions.
+
+*** New option ~org-id-ts-format~
+
+Earlier, IDs generated using =ts= method had a hard-coded format (i.e. =20200923T160237.891616=).
+The new option allows user to customise the format.
+Defaults are unchanged.
+
+*** New argument for ~file-desc~ babel header
+
+It is now possible to provide the =file-desc= header argument for a
+babel source block but omit the description by passing an empty vector
+as an argument (i.e., :file-desc []). This can be useful because
+providing =file-desc= without an argument results in the result of
+=file= being used in the description. Previously, the only way to
+omit a file description was to omit the header argument entirely,
+which made it difficult/impossible to provide a default value for
+=file-desc=.
+
+*** New option to set ~org-link-file-path-type~ to a function
+
+~org-link-file-path-type~ can now be set to a function that takes the
+full filename as an argument and returns the path to link to.
+
+For example, if you use ~project.el~, you can set this function to use
+relative links within a project as follows:
+
+#+begin_src emacs-lisp
+(setq (org-link-file-path-type
+ (lambda (path)
+ (let* ((proj (project-current))
+ (root (if proj (project-root proj) default-directory)))
+ (if (string-prefix-p (expand-file-name root) path)
+ (file-relative-name path)
+ (abbreviate-file-name path))))))
+#+end_src
+
+*** New options and new behavior for babel LaTeX SVG image files
+
+Org babel now uses a two-stage process for converting latex source
+blocks to SVG image files (when the extension of the output file is
+~.svg~). The first stage in the process converts the latex block into
+a PDF file, which is then converted into an SVG file in the second
+stage. The TeX->PDF part uses the existing infrastructure for
+~org-babel-latex-tex-to-pdf~. The PDF->SVG part uses a command
+specified in a new customization,
+~org-babel-latex-pdf-svg-process~. By default, this uses inkscape for
+conversion, but since it is fully customizable, any other command can
+be used in its place. For instance, dvisvgm might be used here. This
+two-part processing replaces the previous use of htlatex to process
+LaTeX directly to SVG (htlatex is still used for HTML conversion).
+
+Conversion to SVG exposes a number of additional customizations that
+give the user full control over the contents of the latex source
+block. ~org-babel-latex-preamble~, ~org-babel-latex-begin-env~ and
+~org-babel-latex-end-env~ are new customization options added to allow
+the user to specify the preamble and code that preceedes and proceeds
+the contents of the source block.
+
+*** New option ~org-html-meta-tags~ allows for HTML meta tags customization
+
+New variable ~org-html-meta-tags~ makes it possible to customize the
+=<meta>= tags used in an HTML export. Accepts either a static list of
+values, or a function that generates such a list (see
+~org-html-meta-tags-default~ as an example of the latter).
+
+*** Option ~org-agenda-bulk-custom-functions~ now supports collecting bulk arguments
+
+When specifying a custom agenda bulk option, you can now also specify
+a function which collects the arguments to be used with each call to
+the custom function.
+
+*** New faces to improve the contextuality of Org agenda views
+
+Four new faces improve certain styles and offer more flexibility for
+some Org agenda views: ~org-agenda-date-weekend-today~,
+~org-imminent-deadline~, ~org-agenda-structure-secondary~,
+~org-agenda-structure-filter~. They inherit from existing faces in
+order to remain backward-compatible.
+
+Quoting from [[https://list.orgmode.org/87lf7q7gpq.fsf@protesilaos.com/][this thread]]:
+
+#+begin_quote
++ The 'org-imminent-deadline' is useful to disambiguate generic
+ warnings from deadlines. For example, a warning could be rendered
+ in a yellow colored text and have a bold weight, whereas a deadline
+ might be red and styled with italics.
+
++ The 'org-agenda-structure-filter' applies to all tag/term filters
+ in agenda views that search for keywords or patterns. It is
+ designed to inherit from 'org-agenda-structure' in addition to the
+ 'org-warning' face that was present before (and removes the
+ generic 'warning' face from one place). This offers the benefit
+ of consistency, as, say, an increase in font height or a change in
+ font family in 'org-agenda-structure' will propagate to the filter
+ as well. The whole header line thus looks part of a singular
+ design.
+
++ The 'org-agenda-structure-secondary' complements the above for those
+ same views where a description follows the header. For instance, the
+ tags view provides information to "Press N r" to filter by a
+ numbered tag. Themes/users may prefer to disambiguate this line
+ from the header above it, such as by using a less intense color or by
+ reducing its height relative to the 'org-agenda-structure'.
+
++ The 'org-agenda-date-weekend-today' provides the option to
+ differentiate the current date on a weekend from the current date on
+ weekdays.
+#+end_quote
+
+*** New option ~org-clock-ask-before-exiting~
+
+By default, a function is now added to ~kill-emacs-query-functions~
+that asks whether to clock out and save when there's a running clock.
+Customize ~org-clock-ask-before-exiting~~ to nil to disable this new
+behavior.
+
+*** Option ~org-html-inline-image-rules~ now includes .webp
+
+By default ox-html now inlines webp images.
+
+*** ~org-html-head-include-scripts~ is now =nil= by default
+
+See [[msg:498dbe2e-0cd2-c81e-7960-4a26c566a1f7@memebeam.org][this thread]].
+
+*** New option ~org-html-content-class~
+
+This is the CSS class name to use for the top level content wrapper.
+
+*** New option ~org-babel-plantuml-svg-text-to-path~
+
+This option, nil by default, allows to add a SVG-specific post-export
+step that runs inkscape text-to-path replacement over the output file.
+
+*** You can now configure ~org-html-scripts~ and ~org-html-style-default~
+
+~org-html-scripts~ and ~org-html-style-default~ used to be constants,
+you can now configure them.
+
+*** New option ~org-attach-git-dir~
+
+~org-attach-git-dir~ will decide whether to use ~org-attach-git-dir~
+(the default) or use the attachment directory of the current node, if
+it is correctly configured as a Git repository.
+
+*** Some faces now use fixed-pitch
+
+See [[msg:875z8njaol.fsf@protesilaos.com][this thread]].
+
+*** New option ~org-attach-sync-delete-empty-dir~
+
+~org-attach-sync-delete-empty-dir~ controls the deletion of an empty
+attachment directory at calls of ~org-attach-sync~. There is
+Never delete, Always delete and Query the user (default).
+
+*** ~org-babel-default-header-args~ can now be specified as closures or strings
+
+~org-babel-default-header-args~ now also accepts closures that
+evaluate to a string. Previously, only direct strings were
+supported. These closures are evaluated when point is at the source
+block, which allows them to make use of contextual information at the
+relevant source block. One example that illustrates the usefulness of
+this addition (also given in the documentation for
+~org-babel-default-header-args~) is:
+
+#+begin_src elisp
+(defun org-src-sha ()
+ (let ((elem (org-element-at-point)))
+ (concat (sha1 (org-element-property :value elem)) \".svg\")))
+
+(setq org-babel-default-header-args:latex
+ `((:results . \"file link replace\")
+ (:file . (lambda () (org-src-sha)))))
+#+end_src
+
+This will set the ~:file~ header argument to the sha1 checksum of the
+contents of the current latex source block.
+
+Finally, the closures are only evaluated if they're not overridden for
+a source block. This improves efficiency in cases where the result of
+a compute-expensive closure would otherwise be discarded.
+
+** Miscellaneous
+*** =org-bibtex= includes =doi= and =url= entries when exporting to BiBTeX
+=doi= and =url= entries have been made optional for some publication
+types and will be exported if present for those types.
+*** Missing or empty placeholders in "eval" macros are now =nil=
+They used to be the empty string.
+*** =org-goto-first-child= now works before first heading
+
+When point is before first heading =org-goto-first-child= will move
+point to the first child heading, or return nil if no heading exist
+in buffer. This is in line with the fact that everything before first
+heading is regarded as outline level 0, i.e. the parent level of all
+headings in the buffer.
+
+Previously =org-goto-first-child= would do nothing before first
+heading, except return nil.
+
+*** Faces of all the heading text elements now conform to the headline face
+
+In the past, faces of todo keywords, emphasised text, tags, and
+priority cookies inherited =default= face. The resulting headline
+fontification was not always consistent, as discussed in [[https://lists.gnu.org/archive/html/emacs-orgmode/2020-09/msg00331.html][this bug
+report]]. Now, the relevant faces adapt to face used to fontify the
+current headline level.
+
+Users who prefer to keep the old behaviour should change their face
+customisation explicitly stating that =default= face is inherited.
+
+Example of old face customisation:
+
+#+begin_src emacs-lisp
+(setq org-todo-keyword-faces '(("TODO"
+ :background "chocolate"
+ :height 0.75)))
+#+end_src
+
+To preserve the old behaviour the above customisation should be
+changed to
+
+#+begin_src emacs-lisp
+(setq org-todo-keyword-faces '(("TODO"
+ :inherit default
+ :background "chocolate"
+ :height 0.75)))
+#+end_src
+
+*** Storing ID-links before first heading uses title as description
+
+Storing links to files using ~org-store-link~ (=<C-c l>=) when
+~org-id-link-to-org-use-id~ is not nil will now store the title as
+description of the link, if available. If no title exists it falls
+back to the filename as before.
+
+*** Change in =org-tags-expand= signature
+
+The function does not allow for a third optional parameter anymore.
+*** LaTeX environment =#+results= are now removed
+
+If a babel src block produces a raw LaTeX environment, it will now be
+recognised as a result, and so replaced when re-evaluated.
+
+*** Tag completion now uses =completing-read-multiple=
+
+Tag completion now uses =completing-read-multiple= with a simple
+completion table, which should allow better interoperability with
+custom completion functions.
+
+*** Providing =directory-empty-p= from Emacs 28 as =org-directory-empty-p=
+
+*** =org-get-last-sibling= marked as obsolete
+
+Use =org-get-previous-sibling= instead. This is just a rename to have
+a more consistent naming. E.g. recall the pair of funtctions
+=next-line= / =previous-line=.
+
+*** Make org-protocol compatible with =URLSearchParams= JavaScript class
+
+Decoder of query part of org-protocol URI recognizes "+" as an encoded
+space characters now, so it is possible to avoid call to =encodeURIComponent=
+for each parameter and use more readable expression in bookmarklet:
+
+#+begin_example
+'org-protocol://store-link?' + new URLSearchParams({
+ url: location.href, title: document.title})
+#+end_example
+
+*** Remove obsolete LaTeX packages from ~org-latex-default-packages-alist~
+
+The LaTeX packages =grffile= and =textcomp= are redundant, with their
+capabilities being merged into =graphicx= and the LaTeX core
+respectively a while ago.
+
* Version 9.4
** Incompatible changes
*** Possibly broken internal file links: please check and fix
@@ -101,6 +671,40 @@ Also, ~org-startup-folded~ now defaults to ~showeverything~.
** New features
+*** =RET= and =C-j= now obey ~electric-indent-mode~
+
+Since Emacs 24.4, ~electric-indent-mode~ is enabled by default. In
+most major modes, this causes =RET= to reindent the current line and
+indent the new line, and =C-j= to insert a newline without indenting.
+
+Org mode now obeys this minor mode: when ~electric-indent-mode~ is
+enabled, and point is neither in a table nor on a timestamp or a link:
+
+- =RET= (bound to ~org-return~) reindents the current line and indents
+ the new line;
+- =C-j= (bound to the new command ~org-return-and-maybe-indent~)
+ merely inserts a newline.
+
+To get the previous behaviour back, disable ~electric-indent-mode~
+explicitly:
+
+#+begin_src emacs-lisp
+(add-hook 'org-mode-hook (lambda () (electric-indent-local-mode -1)))
+#+end_src
+
+Alternatively, if you wish to keep =RET= as the "smart-return" key,
+but dislike Org's default indentation of sections, you may prefer to
+customize ~org-adapt-indentation~ to either nil or =headline-data=.
+
+*** New allowed value for ~org-adapt-indentation~
+
+~org-adapt-indentation~ now accepts a new value, =headline-data=.
+
+When set to this value, Org will only adapt indentation of headline
+data lines, such as planning/clock lines and property/logbook drawers.
+Also, with this setting, =org-indent-mode= will keep these data lines
+correctly aligned with the headline above.
+
*** Looping agenda commands over headlines
~org-agenda-loop-over-headlines-in-active-region~ allows you to loop
@@ -134,15 +738,6 @@ call ~org-toggle-radio-button~.
You can also add =#+ATTR_ORG: :radio t= right before the list to tell
Org to use radio buttons for this list only.
-*** New allowed value for ~org-adapt-indentation~
-
-~org-adapt-indentation~ now accepts a new value, ='headline-data=.
-
-When set to this value, Org will only adapt indentation of headline
-data lines, such as planning/clock lines and property/logbook drawers.
-Also, with this setting, =org-indent-mode= will keep these data lines
-correctly aligned with the headline above.
-
*** Numeric priorities are now allowed (up to 65)
You can now set ~org-priority-highest/lowest/default~ to integers to
@@ -212,31 +807,6 @@ can now be inserted with this prefix argument.
Source code block header argument =:file-mode= can set file
permissions if =:file= argument is provided.
-*** =RET= and =C-j= now obey ~electric-indent-mode~
-
-Since Emacs 24.4, ~electric-indent-mode~ is enabled by default. In
-most major modes, this causes =RET= to reindent the current line and
-indent the new line, and =C-j= to insert a newline without indenting.
-
-Org mode now obeys this minor mode: when ~electric-indent-mode~ is
-enabled, and point is neither in a table nor on a timestamp or a link:
-
-- =RET= (bound to ~org-return~) reindents the current line and indents
- the new line;
-- =C-j= (bound to the new command ~org-return-and-maybe-indent~)
- merely inserts a newline.
-
-To get the previous behaviour back, disable ~electric-indent-mode~
-explicitly:
-
-#+begin_src emacs-lisp
-(add-hook 'org-mode-hook (lambda () (electric-indent-local-mode -1)))
-#+end_src
-
-Alternatively, if you wish to keep =RET= as the "smart-return" key,
-but dislike Org's default indentation of sections, you may prefer to
-customize ~org-adapt-indentation~ to either =nil= or ='headline-data=.
-
*** =ob-C.el= allows the inclusion of non-system header files
In C and C++ blocks, ~:includes~ arguments that do not start with a
@@ -353,7 +923,7 @@ source buffers are displayed by modifying ~display-buffer-alist~ or
*** New option ~org-archive-subtree-save-file-p~
Archiving a subtree used to always save the target archive buffer.
-Commit [[https://code.orgmode.org/bzg/org-mode/commit/b186d1d7][b186d1d7]] changed this behavior by always not saving the target
+Commit [[git::b186d1d7][b186d1d7]] changed this behavior by always not saving the target
buffer, because batch archiving from agenda could take too much time.
This new option ~org-archive-subtree-save-file-p~ defaults to the
@@ -380,14 +950,14 @@ The value of a shell script's execution is its exit code. But most
users expect the results of executing a shell script to be its output,
not its exit code.
-So we introduced this option, that you can set to =nil= if you want
-to stick using ~:results value~ as the implicit header.
+So we introduced this option, that you can set to nil if you want to
+stick using ~:results value~ as the implicit header.
In all Babel libraries, the absence of a ~:results~ header should
produce the same result than setting ~:results value~, unless there is
an option to explicitly create an exception.
-See [[https://orgmode.org/list/CA+A2iZaziAfMeGpBqL6qGrzrWEVvLvC0DUw++T4gCF3NGuW-DQ@mail.gmail.com/][this thread]] for more context.
+See [[msg:CA+A2iZaziAfMeGpBqL6qGrzrWEVvLvC0DUw++T4gCF3NGuW-DQ@mail.gmail.com][this thread]] for more context.
*** New option in ~org-attach-store-link-p~
@@ -1197,7 +1767,7 @@ With this output format, create a link to the file specified in
#+begin_example
,#+begin_src shell :dir "data/tmp" :results link :file "crackzor_1.0.c.gz"
-wget -c "http://ben.akrin.com/crackzor/crackzor_1.0.c.gz"
+wget -c "https://ben.akrin.com/crackzor/crackzor_1.0.c.gz"
,#+end_src
,#+results:
@@ -1537,7 +2107,9 @@ Use "/!" markup when filtering TODO keywords to get only not-done TODO
keywords.
*** ~org-split-string~ returns ~("")~ when called on an empty string
+
It used to return nil.
+
*** Removal of =ob-scala.el=
See [[https://github.com/ensime/emacs-scala-mode/issues/114][this github issue]].
@@ -1605,7 +2177,8 @@ before this let form.
Creation of a new setting to specify the Cider timeout. By setting
the =org-babel-clojure-sync-nrepl-timeout= setting option. The value
-is in seconds and if set to =nil= then no timeout will occur.
+is in seconds and if set to nil then no timeout will occur.
+
**** Clojure: new header ~:show-process~
A new block code header has been created for Org Babel that enables
@@ -1648,7 +2221,7 @@ this ~:prologue "fpprintprec: 2; linel: 50;"~ for presenting Maxima
results in a beamer presentation.
**** PlantUML: add support for header arguments
-[[http://plantuml.com/][Plantuml]] source blocks now support the [[https://orgmode.org/manual/prologue.html#prologue][~:prologue~]], [[https://orgmode.org/manual/epilogue.html#epilogue][~:epilogue~]] and
+[[https://plantuml.com/][Plantuml]] source blocks now support the [[https://orgmode.org/manual/prologue.html#prologue][~:prologue~]], [[https://orgmode.org/manual/epilogue.html#epilogue][~:epilogue~]] and
[[https://orgmode.org/manual/var.html#var][~:var~]] header arguments.
**** SQL: new engine added ~sqsh~
@@ -1821,9 +2394,8 @@ removed from Gnus circa September 2010.
*** ~org-agenda-repeating-timestamp-show-all~ is removed.
-For an equivalent to a =nil= value, set
-~org-agenda-show-future-repeats~ to nil and
-~org-agenda-prefer-last-repeat~ to =t=.
+For an equivalent to a nil value, set ~org-agenda-show-future-repeats~
+to nil and ~org-agenda-prefer-last-repeat~ to =t=.
*** ~org-gnus-nnimap-query-article-no-from-file~ is removed.
@@ -1841,7 +2413,7 @@ equivalent to the removed format string.
*** ~org-enable-table-editor~ is removed.
-Setting it to a =nil= value broke some other features (e.g., speed
+Setting it to a nil value broke some other features (e.g., speed
keys).
*** ~org-export-use-babel~ cannot be set to ~inline-only~
@@ -2284,7 +2856,7 @@ The postgresql engine in a sql code block supports now ~:dbport~ nd
**** Support for additional plantuml output formats
-The support for output formats of [[http://plantuml.com/][plantuml]] has been extended to now
+The support for output formats of [[https://plantuml.com/][plantuml]] has been extended to now
include:
All Diagrams:
@@ -2317,7 +2889,7 @@ Alice <-- Bob: another authentication Response
#+end_src
Please note that *pdf* *does not work out of the box* and needs additional
-setup in addition to plantuml. See [[http://plantuml.com/pdf.html]] for
+setup in addition to plantuml. See [[https://plantuml.com/pdf.html]] for
details and setup information.
*** Rewrite of radio lists
@@ -3447,11 +4019,11 @@ then inline code snippets will be wrapped into the formatting string.
** New contributed packages
- =ox-bibtex.el= by Nicolas Goaziou :: an utility to handle BibTeX
- export to both LaTeX and HTML exports. It uses the [[http://www.lri.fr/~filliatr/bibtex2html/][bibtex2html]]
+ export to both LaTeX and HTML exports. It uses the [[https://www.lri.fr/~filliatr/bibtex2html/][bibtex2html]]
software.
- =org-screenshot.el= by Max Mikhanosha :: an utility to handle
- screenshots easily from Org, using the external tool [[http://freecode.com/projects/scrot][scrot]].
+ screenshots easily from Org, using the external tool [[https://freecode.com/projects/scrot][scrot]].
** Miscellaneous
@@ -3602,7 +4174,7 @@ manual for details and check [[https://orgmode.org/worg/org-8.0.html][this Worg
*** ~ox-md.el~ by Nicolas Goaziou
=ox-md.el= allows you to export Org files to Markdown files, using the
- vanilla [[http://daringfireball.net/projects/markdown/][Markdown syntax]].
+ vanilla [[https://daringfireball.net/projects/markdown/][Markdown syntax]].
*** ~ox-texinfo.el~ by Jonathan Leech-Pepin
@@ -3612,14 +4184,14 @@ manual for details and check [[https://orgmode.org/worg/org-8.0.html][this Worg
*** ~ob-julia.el~ by G. Jay Kerns
- [[http://julialang.org/][Julia]] is a new programming language.
+ [[https://julialang.org/][Julia]] is a new programming language.
=ob-julia.el= provides Org Babel support for evaluating Julia source
code.
*** ~ob-mathomatic.el~ by Luis Anaya
- [[http://www.mathomatic.org/][mathomatic]] a portable, command-line, educational CAS and calculator
+ [[https://www.mathomatic.org/][mathomatic]] a portable, command-line, educational CAS and calculator
software, written entirely in the C programming language.
~ob-mathomatic.el~ provides Org Babel support for evaluating mathomatic
@@ -3627,7 +4199,7 @@ manual for details and check [[https://orgmode.org/worg/org-8.0.html][this Worg
*** ~ob-tcl.el~ by Luis Anaya
- ~ob-tcl.el~ provides Org Babel support for evaluating [[http://www.tcl.tk/][Tcl]] source code.
+ ~ob-tcl.el~ provides Org Babel support for evaluating [[https://www.tcl.tk/][Tcl]] source code.
*** ~org-bullets.el~ by Evgeni Sabof
@@ -3653,7 +4225,7 @@ manual for details and check [[https://orgmode.org/worg/org-8.0.html][this Worg
presentations. ~ox-deck.el~ exports Org files to HTML presentations
using =deck.js=.
- [[http://meyerweb.com/eric/tools/s5/][s5]] is a set of scripts which also allows to display HTML pages as
+ [[https://meyerweb.com/eric/tools/s5/][s5]] is a set of scripts which also allows to display HTML pages as
presentations. ~ox-s5.el~ exports Org files to HTML presentations
using =s5=.
@@ -3760,13 +4332,13 @@ forward and backward.
Now Org will sort this list
-: - [[http://abc.org][B]]
-: - [[http://def.org][A]]
+: - [[https://abc.org][B]]
+: - [[https://def.org][A]]
like this:
-: - [[http://def.org][A]]
-: - [[http://abc.org][B]]
+: - [[https://def.org][A]]
+: - [[https://abc.org][B]]
by comparing the descriptions, not the links.
Same when sorting headlines instead of list items.
@@ -4270,8 +4842,8 @@ found here: https://orgmode.org/worg/org-tutorials/org-outside-org.html
Here are two screencasts demonstrating Thorsten's tools:
-- [[http://youtu.be/nqE6YxlY0rw]["Modern conventions for Emacs Lisp files"]]
-- [[http://www.youtube.com/watch?v%3DII-xYw5VGFM][Exploring Bernt Hansen's Org-mode tutorial with 'navi-mode']]
+- [[https://youtu.be/nqE6YxlY0rw]["Modern conventions for Emacs Lisp files"]]
+- [[https://www.youtube.com/watch?v%3DII-xYw5VGFM][Exploring Bernt Hansen's Org-mode tutorial with 'navi-mode']]
*** MobileOrg for iOS
@@ -4301,7 +4873,7 @@ lines even if `org-use-tag-inheritance' was nil. The default is now
to *never* display inherited tags in agenda lines, but to /know/ about
them when the agenda type is listed in [[doc::org-agenda-use-tag-inheritance][org-agenda-use-tag-inheritance]].
-** New default value nil for [[doc::org-agenda-dim-blocked-tasks][org-agenda-dim-blocked-tasks]]
+** New default value =nil= for [[doc::org-agenda-dim-blocked-tasks][org-agenda-dim-blocked-tasks]]
Using `nil' as the default value speeds up the agenda generation. You
can hit `#' (or `C-u #') in agenda buffers to temporarily dim (or turn
@@ -5130,7 +5702,7 @@ that Calc formulas can operate on them.
The new system has a technically cleaner implementation and more
possibilities for capturing different types of data. See
- [[https://orgmode.org/list/C46F10DC-DE51-43D4-AFFE-F71E440D1E1F@gmail.com][Carsten's announcement]] for more details.
+ [[msg:C46F10DC-DE51-43D4-AFFE-F71E440D1E1F@gmail.com][Carsten's announcement]] for more details.
To switch over to the new system:
@@ -5261,7 +5833,7 @@ that Calc formulas can operate on them.
**** Modified link escaping
- David Maus worked on `org-link-escape'. See [[https://orgmode.org/list/87k4gysacq.wl%dmaus@ictsoc.de][his message]]:
+ David Maus worked on `org-link-escape'. See [[msg:87k4gysacq.wl%dmaus@ictsoc.de][his message]]:
: Percent escaping is used in Org mode to escape certain characters
: in links that would either break the parser (e.g. square brackets
diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index 15e34ea06f8..e70f61b7192 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -123,98 +123,6 @@ load-path.
* Crash bugs
-** Emacs crashes when running in a terminal, if compiled with GCC 4.5.0
-
-This version of GCC is buggy: see
-
- https://debbugs.gnu.org/6031
- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43904
-
-You can work around this error in gcc-4.5 by omitting sibling call
-optimization. To do this, configure Emacs with
-
- ./configure CFLAGS="-g -O2 -fno-optimize-sibling-calls"
-
-** Emacs compiled with GCC 4.6.1 crashes on MS-Windows when C-g is pressed
-
-This is known to happen when Emacs is compiled with MinGW GCC 4.6.1
-with the -O2 option (which is the default in the Windows build). The
-reason is a bug in MinGW GCC 4.6.1; to work around, either add the
-'-fno-omit-frame-pointer' switch to GCC or compile without
-optimizations ('--no-opt' switch to the configure.bat script).
-
-** Emacs crashes in x-popup-dialog.
-
-This can happen if the dialog widget cannot find the font it wants to
-use. You can work around the problem by specifying another font with
-an X resource--for example, 'Emacs.dialog*.font: 9x15' (or any font that
-happens to exist on your X server).
-
-** Emacs crashes when you use Bibtex mode.
-
-This happens if your system puts a small limit on stack size. You can
-prevent the problem by using a suitable shell command (often 'ulimit')
-to raise the stack size limit before you run Emacs.
-
-Patches to raise the stack size limit automatically in 'main'
-(src/emacs.c) on various systems would be greatly appreciated.
-
-** Error message 'Symbol’s value as variable is void: x', followed by
-a segmentation fault and core dump.
-
-This has been tracked to a bug in tar! People report that tar erroneously
-added a line like this at the beginning of files of Lisp code:
-
- x FILENAME, N bytes, B tape blocks
-
-If your tar has this problem, install GNU tar--if you can manage to
-untar it :-).
-
-** Emacs can crash when displaying PNG images with transparency.
-
-This is due to a bug introduced in ImageMagick 6.8.2-3. The bug should
-be fixed in ImageMagick 6.8.3-10. See <URL:https://debbugs.gnu.org/13867>.
-
-** Crashes when displaying GIF images in Emacs built with version
-libungif-4.1.0 are resolved by using version libungif-4.1.0b1.
-Configure checks for the correct version, but this problem could occur
-if a binary built against a shared libungif is run on a system with an
-older version.
-
-** SVG images may be cropped incorrectly with librsvg 2.45 and below.
-Librsvg 2.46 and above have improved geometry code which Emacs is able
-to take advantage of.
-
-** Emacs aborts inside the function 'tparam1'.
-
-This can happen if Emacs was built without terminfo support, but the
-terminal's capabilities use format that is only supported by terminfo.
-If your system has ncurses installed, this might happen if your
-version of ncurses is broken; upgrading to a newer version of ncurses
-and reconfiguring and rebuilding Emacs should solve this.
-
-All modern systems support terminfo, so even if ncurses is not the
-problem, you should look for a way to configure Emacs so that it uses
-terminfo when built.
-
-** Emacs crashes when using some version of the Exceed X server.
-
-Upgrading to a newer version of Exceed has been reported to prevent
-these crashes. You should consider switching to a free X server, such
-as Xming or Cygwin/X.
-
-** Emacs crashes with SIGSEGV in XtInitializeWidgetClass.
-
-It crashes on X, but runs fine when called with option "-nw".
-
-This has been observed when Emacs is linked with GNU ld but without passing
-the -z nocombreloc flag. Emacs normally knows to pass the -z nocombreloc
-flag when needed, so if you come across a situation where the flag is
-necessary but missing, please report it via M-x report-emacs-bug.
-
-On platforms such as Solaris, you can also work around this problem by
-configuring your compiler to use the native linker instead of GNU ld.
-
** When Emacs is compiled with Gtk+, closing a display kills Emacs.
There is a long-standing bug in GTK that prevents it from recovering
@@ -270,11 +178,31 @@ The relevant bug report is here:
A workaround is to set XLIB_SKIP_ARGB_VISUALS=1 in the environment
before starting Emacs, or run Emacs as root.
+** Emacs crashes with SIGTRAP when trying to start a WebKit xwidget.
+
+This could happen if the version of WebKitGTK installed on your system
+is buggy, and errors out trying to start a subprocess through
+Bubblewrap sandboxing. You can avoid the crash by setting the
+environment variables SNAP, SNAP_NAME and SNAP_REVISION, which will
+make WebKit use GLib to launch subprocesses instead. For example,
+invoke Emacs like this (where "..." stands for the other command-line
+arguments you intend to pass to Emacs):
+
+ $ SNAP=1 SNAP_NAME=1 SNAP_REVISION=1 emacs ...
+
** Emacs crashes when you try to view a file with complex characters.
One possible reason for this could be a bug in the libotf or the
libm17n-flt/m17n-db libraries Emacs uses for displaying complex
-scripts. Make sure you have the latest versions of these libraries
+scripts.
+
+The easiest and the recommended way of solving these crashes is to
+build Emacs with HarfBuzz as the shaping engine library instead of
+libm17n-flt. Building with HarfBuzz is the default since Emacs 27.1.
+
+If you must use libm17n-flt, read on.
+
+Make sure you have the latest versions of these libraries
installed. If the problem still persists with the latest released
versions of these libraries, you can try building these libraries from
their CVS repository:
@@ -322,6 +250,94 @@ element from LD_LIBRARY_PATH before starting emacs proper.
Or you could recompile Emacs with an -Wl,-rpath option that
gives the location of the correct libotf.
+** Emacs crashes in x-popup-dialog.
+
+This can happen if the dialog widget cannot find the font it wants to
+use. You can work around the problem by specifying another font with
+an X resource--for example, 'Emacs.dialog*.font: 9x15' (or any font that
+happens to exist on your X server).
+
+** Emacs crashes when you use Bibtex mode.
+
+This happens if your system puts a small limit on stack size. You can
+prevent the problem by using a suitable shell command (often 'ulimit')
+to raise the stack size limit before you run Emacs.
+
+Patches to raise the stack size limit automatically in 'main'
+(src/emacs.c) on various systems would be greatly appreciated.
+
+** Error message 'Symbol’s value as variable is void: x', followed by
+a segmentation fault and core dump.
+
+This has been tracked to a bug in tar! People report that tar erroneously
+added a line like this at the beginning of files of Lisp code:
+
+ x FILENAME, N bytes, B tape blocks
+
+If your tar has this problem, install GNU tar--if you can manage to
+untar it :-).
+
+** Emacs crashes when running in a terminal, if compiled with GCC 4.5.0
+
+This version of GCC is buggy: see
+
+ https://debbugs.gnu.org/6031
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43904
+
+You can work around this error in gcc-4.5 by omitting sibling call
+optimization. To do this, configure Emacs with
+
+ ./configure CFLAGS="-g -O2 -fno-optimize-sibling-calls"
+
+** Emacs compiled with GCC 4.6.1 crashes on MS-Windows when C-g is pressed
+
+This is known to happen when Emacs is compiled with MinGW GCC 4.6.1
+with the -O2 option (which is the default in the Windows build). The
+reason is a bug in MinGW GCC 4.6.1; to work around, either add the
+'-fno-omit-frame-pointer' switch to GCC or compile without
+optimizations ('--no-opt' switch to the configure.bat script).
+
+** Emacs can crash when displaying PNG images with transparency.
+
+This is due to a bug introduced in ImageMagick 6.8.2-3. The bug should
+be fixed in ImageMagick 6.8.3-10. See <URL:https://debbugs.gnu.org/13867>.
+
+** Crashes when displaying GIF images in Emacs built with version
+libungif-4.1.0 are resolved by using version libungif-4.1.0b1.
+Configure checks for the correct version, but this problem could occur
+if a binary built against a shared libungif is run on a system with an
+older version.
+
+** Emacs aborts inside the function 'tparam1'.
+
+This can happen if Emacs was built without terminfo support, but the
+terminal's capabilities use format that is only supported by terminfo.
+If your system has ncurses installed, this might happen if your
+version of ncurses is broken; upgrading to a newer version of ncurses
+and reconfiguring and rebuilding Emacs should solve this.
+
+All modern systems support terminfo, so even if ncurses is not the
+problem, you should look for a way to configure Emacs so that it uses
+terminfo when built.
+
+** Emacs crashes when using some version of the Exceed X server.
+
+Upgrading to a newer version of Exceed has been reported to prevent
+these crashes. You should consider switching to a free X server, such
+as Xming or Cygwin/X.
+
+** Emacs crashes with SIGSEGV in XtInitializeWidgetClass.
+
+It crashes on X, but runs fine when called with option "-nw".
+
+This has been observed when Emacs is linked with GNU ld but without passing
+the -z nocombreloc flag. Emacs normally knows to pass the -z nocombreloc
+flag when needed, so if you come across a situation where the flag is
+necessary but missing, please report it via M-x report-emacs-bug.
+
+On platforms such as Solaris, you can also work around this problem by
+configuring your compiler to use the native linker instead of GNU ld.
+
* Problems when reading or debugging Emacs C code
Because Emacs does not install a copy of its C source code, users
@@ -742,6 +758,11 @@ completed" message that tls.el relies upon, causing affected Emacs
functions to hang. To work around the problem, use older or newer
versions of gnutls-cli, or use Emacs's built-in gnutls support.
+*** SVG images may be cropped incorrectly with librsvg 2.45 or older.
+
+Librsvg 2.46 and above have improved geometry code which Emacs is able
+to take advantage of.
+
* Runtime problems related to font handling
** Characters are displayed as empty boxes or with wrong font under X.
@@ -751,6 +772,18 @@ Try removing or moving aside "$XDG_CONFIG_HOME/fontconfig/conf.d" and
"$XDG_CONFIG_HOME/fontconfig/fonts.conf"
($XDG_CONFIG_HOME is treated as "~/.config" if not set)
+Running Emacs as
+
+ FC_DEBUG=1024 emacs
+
+will cause fontconfig to output information about which configuration
+files it is reading. Running Emacs as
+
+ FC_DEBUG=1 emacs
+
+will result in information about the results of fontconfig's font
+matching (including the filename(s) of the resulting fonts).
+
*** This can occur when two different versions of FontConfig are used.
For example, XFree86 4.3.0 has one version and Gnome usually comes
with a newer version. Emacs compiled with Gtk+ will then use the
@@ -763,7 +796,7 @@ same version of FontConfig as the rest of the system uses. For KDE,
it is sufficient to recompile Qt.
*** Some fonts have a missing glyph and no default character. This is
-known to occur for character number 160 (no-break space) in some
+known to occur for character number 160 (no-break space, U+A0) in some
fonts, such as Lucida but Emacs sets the display table for the unibyte
and Latin-1 version of this character to display a space.
@@ -989,6 +1022,15 @@ modern fonts are used, such as Noto Emoji or Ebrima.
The solution is to switch to a configuration that uses HarfBuzz as its
shaping engine, where these problems don't exist.
+** On Haiku, some proportionally-spaced fonts display with artifacting.
+
+This is a Haiku bug: https://dev.haiku-os.org/ticket/17229, which can
+be remedied by using a different font that does not exhibit this
+problem, or by configuring Emacs '--with-be-cairo'.
+
+So far, Bitstream Charter and Noto Sans have been known to exhibit
+this problem, while Noto Sans Display is known to not do so.
+
* Internationalization problems
** M-{ does not work on a Spanish PC keyboard.
@@ -1054,13 +1096,30 @@ The solution is to remove the corresponding lines from the appropriate
'fonts.alias' file, then run 'mkfontdir' in that directory, and then run
'xset fp rehash'.
-** The 'oc-unicode' package doesn't work with Emacs 21.
+** fcitx input methods don't work with xwidgets.
-This package tries to define more private charsets than there are free
-slots now. The current built-in Unicode support is actually more
-flexible. (Use option 'utf-translate-cjk-mode' if you need CJK
-support.) Files encoded as emacs-mule using oc-unicode aren't
-generally read correctly by Emacs 21.
+fcitx-based input methods might not work when xwidgets are displayed,
+such as inside an xwidget-webkit buffer. This manifests as the pre-edit
+window of the input method disappearing, and the Emacs frame losing
+input focus as soon as you try to type anything. You can work around
+this problem by switching to IBus, or by using a native Emacs input
+method and disabling XIM altogether. For example, you can add the
+following line:
+
+ Emacs.useXIM: false
+
+In your ~/.Xresources file, then run
+
+ $ xrdb ~/.Xresources
+
+And restart Emacs.
+
+** On Haiku, BeCJK doesn't work properly with Emacs
+
+Some popular Haiku input methods such BeCJK are known to behave badly
+when interacting with Emacs, in ways such as stealing input focus and
+displaying popup windows that don't disappear. If you are affected,
+you should use an Emacs input method instead.
* X runtime problems
@@ -1105,20 +1164,6 @@ you want to use fcitx with Emacs, you have two choices. Toggle fcitx
by another key (e.g. C-\) by modifying ~/.fcitx/config, or be
accustomed to use C-@ for 'set-mark-command'.
-*** Link-time optimization with clang doesn't work on Fedora 20.
-
-As of May 2014, Fedora 20 has broken LLVMgold.so plugin support in clang
-(tested with clang-3.4-6.fc20) - 'clang --print-file-name=LLVMgold.so'
-prints 'LLVMgold.so' instead of full path to plugin shared library, and
-'clang -flto' is unable to find the plugin with the following error:
-
-/bin/ld: error: /usr/bin/../lib/LLVMgold.so: could not load plugin library:
-/usr/bin/../lib/LLVMgold.so: cannot open shared object file: No such file
-or directory
-
-The only way to avoid this is to build your own clang from source code
-repositories, as described at http://clang.llvm.org/get_started.html.
-
*** M-SPC seems to be ignored as input.
See if your X server is set up to use this as a command
@@ -1283,6 +1328,12 @@ A better approach might be to avoid navigation from Nautilus to Emacs
for such files, and instead to open the file in Emacs using Tramp
remote file name syntax.
+*** Gnome: GTK builds with XInput2 freeze when making a frame fullscreen.
+
+This problem exists with GTK 3.24.30 in GNOME 41.1 and possibly other
+versions. The solution is to upgrade GNOME Shell to the version that
+comes with GNOME 41.2.
+
*** KDE: When running on KDE, colors or fonts are not as specified for Emacs,
or messed up.
@@ -1632,6 +1683,13 @@ restart the X server after the monitor configuration has been changed.
* Runtime problems on character terminals
+*** With X forwarding, mouse highlighting can make Emacs slow.
+
+If you see slow updates when moving the mouse in an Emacs running on a
+remote X server, try this:
+
+ (setq mouse-highlight nil)
+
** The meta key does not work on xterm.
Typing M-x rings the terminal bell, and inserts a string like ";120~".
@@ -1942,6 +2000,75 @@ To avoid it, set xterm-extra-capabilities to a value other than
'check' (the default). See that variable's documentation (in
term/xterm.el) for more details.
+** Incorrect or corrupted display of some Unicode characters
+
+*** Linux console problems with double-width characters
+
+The Linux console declares UTF-8 encoding, but supports only a limited
+number of Unicode characters, and can cause Emacs produce corrupted or
+garbled display with some unusual characters and sequences. Emacs 28
+and later by default disables 'auto-composition-mode' on this console,
+for that reason, but this might not be enough. One known problem with
+this console is that zero-width and double-width characters are
+displayed incorrectly (as a single-column characters), and that causes
+the cursor to be out of sync with the actual display.
+
+One way of working around this is to use the display-table feature to
+display the problematic characters as some other, less problematic
+ones. Here's an example of setting up the standard display table to
+show the U+01F64F PERSON WITH FOLDED HANDS character as a diamond with
+a special face:
+
+ (or standard-display-table
+ (setq standard-display-table (make-display-table)))
+ (aset standard-display-table
+ #x1f64f (vector (make-glyph-code #xFFFD 'escape-glyph)))
+
+Similar setup can be done with any other problematic character. If
+the console cannot even display the U+FFFD REPLACEMENT CHARACTER, you
+can use some ASCII character instead, like '?'; it will stand out due
+to the 'escape-glyph' face. The disadvantage of this method is that
+all such characters will look the same on display, and the only way of
+knowing what is the real codepoint in the buffer is to go to the
+character and type "C-u C-x =".
+
+*** Messed-up display on the Kitty text terminal
+
+This terminal has its own peculiar ideas about display of unusual
+characters. For example, it hides the U+00AD SOFT HYPHEN characters
+on display, which messes up Emacs cursor addressing, since Emacs
+doesn't know these characters are effectively treated as zero-width
+characters.
+
+One way of working around such "hidden" characters is to tell Emacs to
+display them as zero-width:
+
+ (aset glyphless-char-display #xAD 'zero-width)
+
+Another possibility is to use display-table to display SOFT HYPHEN as
+a regular ASCII dash character '-':
+
+ (or standard-display-table
+ (setq standard-display-table (make-display-table)))
+ (aset standard-display-table
+ #xAD (vector (make-glyph-code ?- 'escape-glyph)))
+
+Another workaround is to set 'nobreak-char-ascii-display' to a non-nil
+value, which will cause any non-ASCII space and hyphen characters to
+be displayed as their ASCII counterparts, with a special face.
+
+Kitty also differs from many other character terminals in how it
+handles character compositions. As one example, Emoji sequences that
+begin with a non-Emoji character and end in U+FE0F VARIATION SELECTOR
+16 should be composed into an Emoji glyph; Kitty assumes that all such
+Emoji glyphs have 2-column width, whereas Emacs and many other text
+terminals display them as 1-column glyphs. Again, this causes cursor
+addressing to get out of sync and eventually messes up the display.
+
+One possible workaround for problems caused by character composition
+is to turn off 'auto-composition-mode' on Kitty terminals.
+
+
* Runtime problems specific to individual Unix variants
** GNU/Linux
@@ -2197,20 +2324,6 @@ are compiling with the system's 'cc' and CFLAGS containing '-O5'. If
so, you have hit a compiler bug. Please make sure to re-configure
Emacs so that it isn't compiled with '-O5'.
-*** AIX 4.3.x or 4.4: Compiling fails.
-
-This could happen if you use /bin/c89 as your compiler, instead of
-the default 'cc'. /bin/c89 treats certain warnings, such as benign
-redefinitions of macros, as errors, and fails the build. A solution
-is to use the default compiler 'cc'.
-
-*** AIX 4: Some programs fail when run in a Shell buffer
-with an error message like No terminfo entry for "unknown".
-
-On AIX, many terminal type definitions are not installed by default.
-'unknown' is one of them. Install the "Special Generic Terminal
-Definitions" to make them defined.
-
** Solaris
We list bugs in current versions here. See also the section on legacy
@@ -2247,7 +2360,7 @@ implementation is only available in UNICOWS.DLL, which implements the
Microsoft Layer for Unicode on Windows 9X, or "MSLU". This article on
MSDN:
- http://msdn.microsoft.com/en-us/goglobal/bb688166.aspx
+ https://web.archive.org/web/20151224032644/https://msdn.microsoft.com/en-us/goglobal/bb688166.aspx
includes a short description of MSLU and a link where it can be
downloaded.
@@ -2262,13 +2375,6 @@ runtime shared library, distributed with Windows 9X.
A workaround is to build Emacs with MinGW runtime 3.x (the latest
version is 3.20).
-** addpm fails to run on Windows NT4, complaining about Shell32.dll
-
-This is likely to happen because Shell32.dll shipped with NT4 lacks
-the updates required by Emacs. Installing Internet Explorer 4 solves
-the problem. Note that it is NOT enough to install IE6, because doing
-so will not install the Shell32.dll update.
-
** A few seconds delay is seen at startup and for many file operations
This happens when the Net Logon service is enabled. During Emacs
@@ -2314,7 +2420,7 @@ dialogs introduced in Windows 7. It is explicitly described in the
MSDN documentation of the GetOpenFileName API used by Emacs to pop up
the file selection dialog. For the details, see
- http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839%28v=vs.85%29.aspx
+ https://msdn.microsoft.com/en-us/library/windows/desktop/ms646839%28v=vs.85%29.aspx
The dialog shows the last directory in which the user selected a file
in a previous invocation of the dialog with the same initial
@@ -2382,15 +2488,6 @@ C:\Users\<UserName>\):
Look for the file 'emacs.lnk' there.
-** Windows 95 and networking.
-
-To support server sockets, Emacs loads ws2_32.dll. If this file is
-missing, all Emacs networking features are disabled.
-
-Old versions of Windows 95 may not have the required DLL. To use
-Emacs's networking features on Windows 95, you must install the
-"Windows Socket 2" update available from MicroSoft's support Web.
-
** Emacs exits with "X protocol error" when run with an X server for MS-Windows.
A certain X server for Windows had a bug which caused this.
@@ -2427,11 +2524,6 @@ other) messages while waiting for a system function, which popped up
the menu/dialog, to return the result of the dialog or pop-up menu
interaction.
-** Help text in tooltips does not work on old Windows versions
-
-Windows 95 and Windows NT up to version 4.0 do not support help text
-for menus. Help text is only available in later versions of Windows.
-
** Display problems with ClearType method of smoothing
When "ClearType" method is selected as the "method to smooth edges of
@@ -2656,10 +2748,55 @@ If you do, please send it to bug-gnu-emacs@gnu.org so we can list it here.
* Runtime problems specific to macOS
+** Error message when opening Emacs on macOS
+
+When opening Emacs, you may see an error message saying something like
+this:
+
+ "Emacs" can't be opened because Apple cannot check it for malicious
+ software. This software needs to be updated. Contact the developer
+ for more information.
+
+The reason is that Apple incorrectly catalogs Emacs as potentially
+malicious software and thus shows this error message.
+
+To avoid this alert, open Finder, go to Applications, control-click
+the Emacs app icon, and then choose Open. This adds a security
+exception for Emacs and from now on you should be able to open it by
+double-clicking on its icon, like any other app.
+
** macOS doesn't come with libxpm, so only XPM3 is supported.
Libxpm is available for macOS as part of the XQuartz project.
+** Synthetic fonts on macOS
+
+Synthetic bold looks thinner if the background is darker than the
+foreground and font smoothing is turned on. In such cases, you can
+turn off synthetic bold for particular fonts and use overstriking
+instead by customizing the variable 'face-ignored-fonts'. For
+instance, if the problem is with the Monaco font, you could put
+something like the following in your init file:
+
+(push "\\`-[^-]*-monaco-bold-" face-ignored-fonts)
+
+** Native Compilation on macOS
+
+Native complitation requires the libgccjit library to be installed and
+its path available to Emacs. Errors such as:
+
+ libgccjit.so: error: error invoking gcc driver
+ Error: Internal native compiler error failed to compile
+
+indicate Emacs can't find the library in running time. One can set
+the "LIBRARY_PATH" environment variable in the early initialization
+file; for example:
+
+(setenv "LIBRARY_PATH"
+ (string-join
+ '("/usr/local/opt/gcc/lib/gcc/11"
+ "/usr/local/opt/libgccjit/lib/gcc/11"
+ "/usr/local/opt/gcc/lib/gcc/11/gcc/x86_64-apple-darwin20/11.2.0") ":"))
* Build-time problems
@@ -2679,6 +2816,20 @@ above example).
** Compilation
+*** Link-time optimization with clang doesn't work on Fedora 20.
+
+As of May 2014, Fedora 20 has broken LLVMgold.so plugin support in clang
+(tested with clang-3.4-6.fc20) - 'clang --print-file-name=LLVMgold.so'
+prints 'LLVMgold.so' instead of full path to plugin shared library, and
+'clang -flto' is unable to find the plugin with the following error:
+
+/bin/ld: error: /usr/bin/../lib/LLVMgold.so: could not load plugin library:
+/usr/bin/../lib/LLVMgold.so: cannot open shared object file: No such file
+or directory
+
+The only way to avoid this is to build your own clang from source code
+repositories, as described at http://clang.llvm.org/get_started.html.
+
*** Building Emacs over NFS fails with "Text file busy".
This was reported to happen when building Emacs on a GNU/Linux system
@@ -2991,15 +3142,6 @@ of PURESIZE in puresize.h.
But in some of the cases listed above, this problem is a consequence
of something else that is wrong. Be sure to check and fix the real problem.
-*** OpenBSD 4.0 macppc: Segfault during dumping.
-
-The build aborts with signal 11 when the command './temacs --batch
---load loadup bootstrap' tries to load files.el. A workaround seems
-to be to reduce the level of compiler optimization used during the
-build (from -O2 to -O1). It is possible this is an OpenBSD
-GCC problem specific to the macppc architecture, possibly only
-occurring with older versions of GCC (e.g. 3.3.5).
-
*** openSUSE 10.3: Segfault in bcopy during dumping.
This is due to a bug in the bcopy implementation in openSUSE 10.3.
@@ -3154,8 +3296,51 @@ should do.
pen@lysator.liu.se says (Feb 1998) that the Compose key does work
if you link with the MIT X11 libraries instead of the Solaris X11 libraries.
+** OpenBSD
+
+*** OpenBSD 4.0 macppc: Segfault during dumping.
+
+The build aborts with signal 11 when the command './temacs --batch
+--load loadup bootstrap' tries to load files.el. A workaround seems
+to be to reduce the level of compiler optimization used during the
+build (from -O2 to -O1). It is possible this is an OpenBSD
+GCC problem specific to the macppc architecture, possibly only
+occurring with older versions of GCC (e.g. 3.3.5).
+
+** AIX
+
+*** AIX 4.3.x or 4.4: Compiling fails.
+
+This could happen if you use /bin/c89 as your compiler, instead of
+the default 'cc'. /bin/c89 treats certain warnings, such as benign
+redefinitions of macros, as errors, and fails the build. A solution
+is to use the default compiler 'cc'.
+
+*** AIX 4: Some programs fail when run in a Shell buffer
+with an error message like No terminfo entry for "unknown".
+
+On AIX, many terminal type definitions are not installed by default.
+'unknown' is one of them. Install the "Special Generic Terminal
+Definitions" to make them defined.
+
** MS-Windows 95, 98, ME, and NT
+*** MS-Windows 95: Networking.
+
+To support server sockets, Emacs loads ws2_32.dll. If this file is
+missing, all Emacs networking features are disabled.
+
+Old versions of Windows 95 may not have the required DLL. To use
+Emacs's networking features on Windows 95, you must install the
+"Windows Socket 2" update available from MicroSoft's support Web.
+
+*** MS-Windows NT4: addpm fails to run, complaining about Shell32.dll
+
+This is likely to happen because Shell32.dll shipped with NT4 lacks
+the updates required by Emacs. Installing Internet Explorer 4 solves
+the problem. Note that it is NOT enough to install IE6, because doing
+so will not install the Shell32.dll update.
+
*** MS-Windows NT/95: Problems running Perl under Emacs
'perl -de 0' just hangs when executed in an Emacs subshell.
@@ -3219,6 +3404,11 @@ For Perl 4:
}
else {
+*** MS-Windows NT/95: Help text in tooltips does not work
+
+Windows 95 and Windows NT up to version 4.0 do not support help text
+for menus. Help text is only available in later versions of Windows.
+
*** MS-Windows 95: Alt-f6 does not get through to Emacs.
This character seems to be trapped by the kernel in Windows 95.
diff --git a/etc/TODO b/etc/TODO
index 1d6824c470a..22f5c099607 100644
--- a/etc/TODO
+++ b/etc/TODO
@@ -29,99 +29,29 @@ are the ones we consider more important, but these also may be
difficult to fix. Bugs with severity "minor" may be simpler, but this
is not always true.
-* Speed up Elisp execution
+* High Priority Items
-** Speed up function calls
-Change src/bytecode.c so that calls from byte-code functions to byte-code
-functions don't go through Ffuncall/funcall_lambda/exec_byte_code but instead
-stay within exec_byte_code.
-
-** Improve the byte-compiler to recognize immutable bindings
-Recognize immutable (lexical) bindings and get rid of them if they're
-used only once and/or they're bound to a constant expression.
-
-Such things aren't present in hand-written code, but macro expansion and
-defsubst can often end up generating things like
-(funcall (lambda (arg) (body)) actual) which then get optimized to
-(let ((arg actual)) (body)) but should additionally get optimized further
-when 'actual' is a constant/copyable expression.
-
-** Add an "indirect goto" byte-code
-Such a byte-code can be used for local lambda expressions.
-E.g. when you have code like
-
- (let ((foo (lambda (x) bar)))
- (dosomething
- (funcall foo toto)
- (blabla (funcall foo titi))))
-
-turn those 'funcalls' into jumps and their return into indirect jumps back.
-
-** Compile efficiently local recursive functions
-Similar to the previous point, we should be able to handle something like
-
- (letrec ((loop () (blabla) (if (toto) (loop))))
- (loop))
-
-which ideally should generate the same byte-code as
-
- (while (progn (blabla) (toto)))
-
-* Things that were planned for Emacs-24
+** Things related to elpa.gnu.org.
+We need to figure out how to best include GNU ELPA packages in the
+Emacs tarball before doing any of the items below.
-** concurrency
-Including it as an "experimental" compile-time option sounds good. Of
-course there might still be big questions around "which form of
-concurrency" we'll want.
-
-** better support for dynamic embedded graphics
-I like this idea (my mpc.el code could use it for the volume widget),
-though I wonder if the resulting efficiency will be sufficient.
-
-** Spread Semantic
-
-** Improve the "code snippets" support
-Consolidate skeleton.el, tempo.el, and expand.el (any other?) and then
-advertise/use/improve it.
-
-** Improve VC
-Yes, there's a lot of work to be done there :-(
-
-** 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.
-
-*** Prog-mode could/should provide a better fill-paragraph default
-That default should use syntax-tables to recognize string/comment
-boundaries.
-
-*** Provide more completion-at-point-functions
-Make existing in-buffer completion use completion-at-point.
-
-*** "Functional" function-key-map
-It would make it easy to add (and remove) mappings like
-"FOO-mouse-4 -> FOO-scroll-down", "FOO-tab -> ?\FOO-\t",
-"uppercase -> lowercase", "[fringe KEY...] -> [KEY]",
-"H-FOO -> M-FOO", "C-x C-y FOO -> H-FOO", ...
-
-* Things related to elpa.gnu.org.
-
-** Move idlwave to elpa.gnu.org
+*** Move idlwave to elpa.gnu.org
Need to sync up the Emacs and external versions.
See <https://lists.gnu.org/r/emacs-devel/2014-07/msg00008.html>
+<https://debbugs.gnu.org/39992>
-** Move Org mode to elpa.gnu.org
+*** Move Org mode to elpa.gnu.org
See <https://lists.gnu.org/r/emacs-devel/2014-08/msg00300.html>
<https://lists.gnu.org/r/emacs-devel/2014-11/msg00257.html>
-** Move verilog-mode to elpa.gnu.org
+*** Move verilog-mode to elpa.gnu.org
See <https://lists.gnu.org/r/emacs-devel/2015-02/msg01180.html>
-** Move vhdl-mode to elpa.gnu.org
+*** Move vhdl-mode to elpa.gnu.org
See <https://lists.gnu.org/r/emacs-devel/2015-02/msg01180.html>
* Simple tasks
-These don't require much Emacs knowledge, they are suitable for anyone
+These don't require much Emacs knowledge and are suitable for anyone
from beginners to experts.
** Convert modes that use view-mode to be derived from special-mode instead
@@ -143,6 +73,17 @@ things in their .emacs.
** See if other files can use generated-autoload-file (see eg ps-print)
+** Do interactive mode tagging for commands
+Change "(interactive)" to "(interactive nil foo-mode)" for command
+completion purposes. Pick a major mode or ELisp library, and check
+all interactive commands to see if they are only relevant in one
+particular mode. This requires care as some commands might be useful
+outside of the mode they were written for.
+
+** Convert defvar foo-mode-map to defvar-keymap
+Verify the conversion by comparing the value of the keymap before
+converting it and after (you can see the value in 'C-h v').
+
** Write more tests
Pick a fixed bug from the database, write a test case to make sure it
stays fixed. Or pick your favorite programming major-mode, and write
@@ -235,6 +176,44 @@ https://lists.gnu.org/r/emacs-devel/2008-08/msg00456.html
* Important features
+** Speed up Elisp execution
+
+*** Speed up function calls
+Change src/bytecode.c so that calls from byte-code functions to byte-code
+functions don't go through Ffuncall/funcall_lambda/exec_byte_code but instead
+stay within exec_byte_code.
+
+*** Improve the byte-compiler to recognize immutable bindings
+Recognize immutable (lexical) bindings and get rid of them if they're
+used only once and/or they're bound to a constant expression.
+
+Such things aren't present in hand-written code, but macro expansion and
+defsubst can often end up generating things like
+(funcall (lambda (arg) (body)) actual) which then get optimized to
+(let ((arg actual)) (body)) but should additionally get optimized further
+when 'actual' is a constant/copyable expression.
+
+** Add an "indirect goto" byte-code
+Such a byte-code can be used for local lambda expressions.
+E.g. when you have code like
+
+ (let ((foo (lambda (x) bar)))
+ (dosomething
+ (funcall foo toto)
+ (blabla (funcall foo titi))))
+
+turn those 'funcalls' into jumps and their return into indirect jumps back.
+
+*** Compile efficiently local recursive functions
+Similar to the previous point, we should be able to handle something like
+
+ (letrec ((loop () (blabla) (if (toto) (loop))))
+ (loop))
+
+which ideally should generate the same byte-code as
+
+ (while (progn (blabla) (toto)))
+
** "Emacs as word processor"
https://lists.gnu.org/r/emacs-devel/2013-11/msg00515.html
rms writes:
@@ -385,38 +364,16 @@ 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.
+** Concurrency
+Stefan Monnier writes: "Including it as an 'experimental' compile-time
+option sounds good. Of course there might still be big questions
+around 'which form of concurrency' we'll want."
+
** Better support for displaying Emoji
Emacs is capable of displaying Emoji and some of the Emoji sequences,
provided that its fontsets are configured with a suitable font. To
make this easier out of the box, the following should be done:
-*** Populate composition-function-table with Emoji rules
-The Unicode Character Database (UCD) includes several data files that
-define the valid Emoji sequences. These files should be imported into
-the Emacs tree, and should be converted by some script at Emacs build
-time to Lisp code that populates composition-function-table with the
-corresponding composition rules.
-
-*** Augment the default fontsets with Emoji-capable fonts
-The default fontsets set up by fontest.el should include known free
-fonts that provide good support for displaying Emoji sequences. In
-addition, the rule that the default face's font is used for symbol and
-punctuation characters, disregarding the fontsets, should be modified
-to exempt Emoji from this rule (since Emoji characters belong to the
-'symbol' script in Emacs), so that use-default-font-for-symbols would
-not have to be tweaked to have Emoji display by default with a capable
-font.
-
-*** Consider changing the default display of Variation Selectors
-Emacs by default displays the Variation Selector (VS) codepoints not
-composed with base characters as hex codes in a box. The Unicode FAQ
-says that if variation sequences cannot be supported, the VS
-characters should not be shown, leaving just the base character of the
-sequence visible. This could be handled via glyphless-char-display,
-by changing the entries for VS codepoints to 'zero-width'. Or we
-could display them as a thin 1-pixel space, as we do with format
-control characters, by using 'thin-space' there.
-
*** Special face for displaying text presentation of Emoji
Emoji-capable fonts support Emoji sequences with the U+FE0F VARIATION
SELECTOR-16 (VS16) for emoji-style display, but usually don't support
@@ -491,6 +448,25 @@ consistency checks that make sure the new code computes the same results
as the old code. And once that works well, we can remove the old code
and old fields.
+** Implement Unicode-compliant display of "default-ignorable" characters
+See the "Characters Ignored for Display" section of paragraph 5.21 in
+the Unicode Standard for the details.
+
+The implementation would import the data from Unicode UCD file
+DerivedCoreProperties.txt, and provide a minor mode that arranges for
+the characters with the Default_Ignorable_Code_Point (DI) property to
+be hidden on display. One way of implementing that could be via
+glyphless-char-display-control; that one is global, but maybe there's
+a way of making it buffer-local. Alternatively, this could be
+implemented in C in the display engine.
+
+An additional aspect of this is the display of U+00AD SOFT HYPHEN as
+invisible except at line boundaries. Note that this would need to
+support hard (physical) newlines in the buffer as well as soft
+wrapping of long lines under 'visual-line-mode'. The algorithm for
+selecting the wrap point may also need be changed to break at the soft
+hyphen.
+
** FFI (foreign function interface)
See eg https://lists.gnu.org/r/emacs-devel/2013-10/msg00246.html
@@ -661,6 +637,13 @@ could also be a button that you could use to view the advice.
** Add a function to get the insertion-type of the markers in an overlay
+** Improve VC
+Yes, there's a lot of work to be done there :-(
+
+** Improve the "code snippets" support
+Consolidate skeleton.el, tempo.el, and expand.el (any other?) and then
+advertise/use/improve it.
+
** ange-ftp
*** Make ange-ftp understand sftp
@@ -828,11 +811,6 @@ gametree, page-ext, refbib, refer, scribe, texinfo, underline,
cmacexp, hideif, pcomplete, xml, cvs-status (should be described in
PCL-CVS manual); other progmodes, probably in separate manual.
-** Deprecate and remove XPM icons
-Convert the XPM bitmaps to PPM, replace the PBMs with them and scrap
-the XPMs so that the color versions work generally. (Requires care
-with the color used for the transparent regions.)
-
** Convenient access to the 'values' variable
It would be nice to have an interface that would show you the printed
reps of the elements of the list in a menu, let you select one of the
@@ -903,6 +881,25 @@ The idea is to add an "X" of some kind, that when clicked deletes the
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."
+
+*** Prog-mode could/should provide a better fill-paragraph default
+That default should use syntax-tables to recognize string/comment
+boundaries.
+
+*** Provide more completion-at-point-functions
+Make existing in-buffer completion use completion-at-point.
+
+*** "Functional" function-key-map
+It would make it easy to add (and remove) mappings like
+"FOO-mouse-4 -> FOO-scroll-down", "FOO-tab -> ?\FOO-\t",
+"uppercase -> lowercase", "[fringe KEY...] -> [KEY]",
+"H-FOO -> M-FOO", "C-x C-y FOO -> H-FOO", ...
+
* Things to be done for specific packages or features
** NeXTstep port
@@ -1183,45 +1180,6 @@ Instead, if B has not been customized it should be re-initialized
See the places where we manually call custom-reevaluate-setting,
such as for mail-host-address and user-mail-address in startup.el.
-** ImageMagick support
-
-*** Image priority
-'image-type-header-regexps' prioritizes the jpeg loader over the
-ImageMagick one. This is not wrong, but how should a user go about
-preferring the ImageMagick loader? The user might like zooming etc in jpegs.
-
-Try (setq image-type-header-regexps nil) for a quick hack to prefer
-ImageMagick over the jpg loader.
-
-*** Slow display
-For some reason it's unbearably slow to look at a page in a large
-image bundle using the :index feature. The ImageMagick "display"
-command is also a bit slow, but nowhere near as slow as the Emacs
-code. It seems ImageMagick tries to unpack every page when loading the
-bundle. This feature is not the primary usecase in Emacs though.
-
-ImageMagick 6.6.2-9 introduced a bugfix for single page djvu load. It
-is now much faster to use the :index feature, but still not very fast.
-
-*** Try to cache the num pages calculation
-It can take a while to calculate the number of pages, and if you need
-to do it for each page view, page-flipping becomes uselessly slow.
-
-*** Integrate with image-dired
-
-*** Integrate with docview
-
-*** Integrate with image-mode
-Some work has been done, e.g. "M-x image-transform-fit-to-height" will
-fit the image to the height of the Emacs window.
-
-*** Look for optimizations for handling images with low depth
-Currently the code seems to default to 24 bit RGB which is costly for
-images with lower bit depth.
-
-*** Decide what to do with some uncommitted imagemagick support
-Functions for image size etc.
-
** nxml mode
*** High priority
@@ -1538,6 +1496,14 @@ cannot represent in Unicode.
*** Performance
+**** Make the implementation of markers more efficient
+Markers are implemented as a non-sorted singly linked list of markers.
+This makes them scale badly when thousands of markers are created in a
+buffer for some purpose, because some low-level primitives in Emacs
+traverse the markers' list (e.g., when converting between character
+and byte positions), and also because searching for a marker (e.g.,
+with 'buffer-has-markers-at') becomes very slow.
+
**** Explore whether overlay-recenter can cure overlays performance problems
**** Cache schemas. Need to have list of files and mtimes
diff --git a/etc/charsets/README b/etc/charsets/README
index 0045a0f638e..96cba7c6139 100644
--- a/etc/charsets/README
+++ b/etc/charsets/README
@@ -27,7 +27,9 @@ character code separated by a space. Both code points and Unicode
character codes are in hexadecimal preceded by "0x". Comments may be
used, starting with "#". Code ranges may also be used, with
(inclusive) start and end code points separated by "-" followed by the
-Unicode of the start of the range
+Unicode of the start of the range.
+Code points for which there's no mapping to Unicode should be skipped,
+i.e. their lines should be omitted.
Examples:
0xA0 0x00A0 # no-break space
diff --git a/etc/compilation.txt b/etc/compilation.txt
index 01d4df1b09d..34d8c53c9a6 100644
--- a/etc/compilation.txt
+++ b/etc/compilation.txt
@@ -310,6 +310,9 @@ G:/cygwin/dev/build-myproj.xml:54: Compiler Adapter 'javac' can't be found.
file:G:/cygwin/dev/build-myproj.xml:54: Compiler Adapter 'javac' can't be found.
{standard input}:27041: Warning: end of file not at end of a line; newline inserted
boost/container/detail/flat_tree.hpp:589:25: [ skipping 5 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
+ |
+ |board.h:60:21:
+ | 60 | #define I(b, C) ((C).y * (b)->width + (C).x)
* Guile backtrace, 2.0.11
diff --git a/etc/e/README b/etc/e/README
index dd2c8d64e25..1293292a878 100644
--- a/etc/e/README
+++ b/etc/e/README
@@ -1,12 +1,12 @@
-eterm-color.ti is a terminfo source file. eterm-color is a compiled
-version produced by the terminfo compiler (tic). The compiled files
-are binary, and depend on the version of tic, but they seem to be
-system-independent and backwardly compatible. So there should be no
-need to recompile the distributed binary version. If it is
-necessary, use:
+eterm-color.ti is a terminfo source file. eterm-color and
+eterm-direct are compiled versions produced by the terminfo compiler
+(tic). The compiled files are binary, and depend on the version of
+tic, but they seem to be system-independent and backwardly compatible.
+So there should be no need to recompile the distributed binary
+version. If it is necessary, use:
tic -o ../ ./eterm-color.ti
-The compiled file is used by lisp/term.el, so if it is moved term.el
-needs to be changed. terminfo requires it to be stored in an 'e'
-subdirectory (the first character of the file name).
+The compiled files are used by lisp/term.el, so if they are moved,
+term.el needs to be changed. terminfo requires them to be stored in
+an 'e' subdirectory (the first character of the file name).
diff --git a/etc/e/eterm-color b/etc/e/eterm-color
index bd3f5003ae6..bf44fa0f36d 100644
--- a/etc/e/eterm-color
+++ b/etc/e/eterm-color
Binary files differ
diff --git a/etc/e/eterm-color.ti b/etc/e/eterm-color.ti
index a6ef8149900..eeb9b0b6e6a 100644
--- a/etc/e/eterm-color.ti
+++ b/etc/e/eterm-color.ti
@@ -9,15 +9,16 @@ eterm-color|Emacs term.el terminal emulator term-protocol-version 0.96,
# Any change to this file should be done at the same time with a
# corresponding change to the TERMCAP environment variable in term.el.
# Comments in term.el specify where each of these capabilities is implemented.
- colors#8,
+ colors#256,
cols#80,
lines#24,
- pairs#64,
+ pairs#32767,
am,
mir,
msgr,
xenl,
bel=^G,
+ blink=\E[5m,
bold=\E[1m,
clear=\E[H\E[J,
cr=\r,
@@ -31,6 +32,7 @@ eterm-color|Emacs term.el terminal emulator term-protocol-version 0.96,
cup=\E[%i%p1%d;%p2%dH,
cuu1=\E[A,
cuu=\E[%p1%dA,
+ dim=\E[2m,
dch1=\E[P,
dch=\E[%p1%dP,
dl1=\E[M,
@@ -60,14 +62,16 @@ eterm-color|Emacs term.el terminal emulator term-protocol-version 0.96,
rc=\E8,
rev=\E[7m,
ri=\EM,
+ ritm=\E[23m,
rmir=\E[4l,
rmso=\E[27m,
rmul=\E[24m,
rs1=\Ec,
sc=\E7,
- setab=\E[%p1%{40}%+%dm,
- setaf=\E[%p1%{30}%+%dm,
+ setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
+ setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
sgr0=\E[m,
+ sitm=\E[3m,
smir=\E[4h,
smul=\E[4m,
smso=\E[7m,
@@ -76,3 +80,10 @@ eterm-color|Emacs term.el terminal emulator term-protocol-version 0.96,
# smcup=\E[?47h,
# rmcup=\E[?47l,
# rs2 may need to be added
+
+eterm-direct|Emacs term.el with direct-color indexing term-protocol-version 0.96,
+ use=eterm-color,
+ colors#0x1000000,
+ pairs#0x10000,
+ setab=\E[%?%p1%{8}%<%t4%p1%d%e48;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%d;%p1%{255}%&%d%;m,
+ setaf=\E[%?%p1%{8}%<%t3%p1%d%e38;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%d;%p1%{255}%&%d%;m,
diff --git a/etc/e/eterm-direct b/etc/e/eterm-direct
new file mode 100644
index 00000000000..c113c371369
--- /dev/null
+++ b/etc/e/eterm-direct
Binary files differ
diff --git a/etc/images/README b/etc/images/README
index 9bbe796cc95..561cfff7653 100644
--- a/etc/images/README
+++ b/etc/images/README
@@ -68,6 +68,7 @@ Emacs images and their source in the GNOME icons stock/ directory:
bookmark_add.xpm actions/bookmark_add
cancel.xpm slightly modified generic/stock_stop
connect.xpm net/stock_connect
+ connect-to-url.xpm net/stock_connect-to-url
contact.xpm net/stock_contact
data-save.xpm data/stock_data-save
delete.xpm generic/stock_delete
diff --git a/etc/images/connect-to-url.pbm b/etc/images/connect-to-url.pbm
new file mode 100644
index 00000000000..f142349f4a9
--- /dev/null
+++ b/etc/images/connect-to-url.pbm
Binary files differ
diff --git a/etc/images/connect-to-url.xpm b/etc/images/connect-to-url.xpm
new file mode 100644
index 00000000000..38fefeaf611
--- /dev/null
+++ b/etc/images/connect-to-url.xpm
@@ -0,0 +1,281 @@
+/* XPM */
+static char *connect_to_url[] = {
+/* columns rows colors chars-per-pixel */
+"24 24 251 2 ",
+" c black",
+". c #010101",
+"X c #000103",
+"o c #010204",
+"O c #010305",
+"+ c #020407",
+"@ c #020609",
+"# c #03070C",
+"$ c #04080D",
+"% c #0F0F0D",
+"& c #030A10",
+"* c #050B10",
+"= c #060C11",
+"- c #070D13",
+"; c #070D14",
+": c #060C15",
+"> c #070E14",
+", c #0B1824",
+"< c #0A1B2B",
+"1 c #0A1C2E",
+"2 c #141A20",
+"3 c #161E25",
+"4 c #181E23",
+"5 c #0D2032",
+"6 c #142534",
+"7 c #1F2830",
+"8 c #1D2933",
+"9 c #102438",
+"0 c #272622",
+"q c #21292F",
+"w c #272F36",
+"e c #282F33",
+"r c #222F3A",
+"t c #2E3337",
+"y c #2D373E",
+"u c #32383C",
+"i c #33383C",
+"p c #343A3E",
+"a c #43423C",
+"s c #112941",
+"d c #102A44",
+"f c #132D47",
+"g c #192F46",
+"h c #17314B",
+"j c #15314F",
+"k c #163351",
+"l c #163554",
+"z c #173554",
+"x c #1F3A53",
+"c c #1D3955",
+"v c #1A3958",
+"b c #1C3B5B",
+"n c #1F3C58",
+"m c #1D3C5C",
+"M c #1E3E5D",
+"N c #1F3F5F",
+"B c #303B44",
+"V c #313C44",
+"C c #313D47",
+"Z c #213C56",
+"A c #233E57",
+"S c #1F405F",
+"D c #374148",
+"F c #2D4050",
+"G c #25405B",
+"H c #25425E",
+"J c #214262",
+"K c #244565",
+"L c #264665",
+"P c #254666",
+"I c #2A4967",
+"U c #284969",
+"Y c #2A4C6C",
+"T c #2C4F6F",
+"R c #33526E",
+"E c #385269",
+"W c #2D5070",
+"Q c #2E5172",
+"! c #335473",
+"~ c #3F5B75",
+"^ c #3D5F7D",
+"/ c #41494F",
+"( c #646056",
+") c #6C685E",
+"_ c #505F6C",
+"` c #48657C",
+"' c #556A7A",
+"] c #5B6C78",
+"[ c #5F6F7B",
+"{ c #5D6F7D",
+"} c #706C62",
+"| c #726D63",
+" . c #78756B",
+".. c #7D786E",
+"X. c #60727F",
+"o. c #807D74",
+"O. c #8A857B",
+"+. c #8B877E",
+"@. c #4E6A83",
+"#. c #4A6A86",
+"$. c #4A7090",
+"%. c #587790",
+"&. c #5F7E95",
+"*. c #587B98",
+"=. c #6F7980",
+"-. c #697F8F",
+";. c #66839B",
+":. c #6A879F",
+">. c #708391",
+",. c #728A9A",
+"<. c #748898",
+"1. c #758A99",
+"2. c #7B8F9F",
+"3. c #708DA4",
+"4. c #7990A1",
+"5. c #7292AB",
+"6. c #7691A8",
+"7. c #7693AB",
+"8. c #7B98AE",
+"9. c #7E98AD",
+"0. c #7E9DB3",
+"q. c #7F9EB4",
+"w. c #8C8981",
+"e. c #989389",
+"r. c #A6A29B",
+"t. c #8093A1",
+"y. c #8598A3",
+"u. c #8498A7",
+"i. c #809AAD",
+"p. c #8F9FAA",
+"a. c #899FAE",
+"s. c #819FB5",
+"d. c #86A2B8",
+"f. c #87A5BB",
+"g. c #88A3B8",
+"h. c #89A5BA",
+"j. c #8FABBF",
+"k. c #97A7B1",
+"l. c #90AABE",
+"z. c #91ABBF",
+"x. c #98ACB9",
+"c. c #AAA7A0",
+"v. c #B1ADA4",
+"b. c #B3B1AA",
+"n. c #B7B3AA",
+"m. c #A3B1BC",
+"M. c #A5B1BC",
+"N. c #A9B6BF",
+"B. c #BEBBB5",
+"V. c #C4C2BD",
+"C. c #94AEC1",
+"Z. c #96AEC1",
+"A. c #94AFC2",
+"S. c #95AFC2",
+"D. c #96B0C3",
+"F. c #98B0C3",
+"G. c #9FB5C3",
+"H. c #99B3C6",
+"J. c #98B3C7",
+"K. c #9AB3C6",
+"L. c #9BB4C7",
+"P. c #9FB8CA",
+"I. c #9FB8CB",
+"U. c #A2B8C9",
+"Y. c #A3B9C9",
+"T. c #A0B9CB",
+"R. c #A3BACB",
+"E. c #A0B9CC",
+"W. c #A2BACC",
+"Q. c #A4BDCE",
+"!. c #A6BECF",
+"~. c #B8BEC2",
+"^. c #B8C3CA",
+"/. c #BCC5CB",
+"(. c #BDC8CE",
+"). c #A8C0D1",
+"_. c #AAC0D0",
+"`. c #ABC1D1",
+"'. c #ACC2D3",
+"]. c #AAC5D7",
+"[. c #B4C8D6",
+"{. c #BDCBD5",
+"}. c #B4C9D8",
+"|. c #B6CAD8",
+" X c #B8CBD9",
+".X c #BBCDDB",
+"XX c #B7D0E0",
+"oX c #BDD3E2",
+"OX c #BCD5E5",
+"+X c #CECAC3",
+"@X c #C5D2C8",
+"#X c #C0D2DE",
+"$X c #C4D3DF",
+"%X c #CCD7DE",
+"&X c #D2D8DC",
+"*X c #E1DFDB",
+"=X c #E2E1DD",
+"-X c #C2D3E0",
+";X c #C2D4E1",
+":X c #C5D5E1",
+">X c #C6D6E1",
+",X c #C4D6E2",
+"<X c #C5D6E3",
+"1X c #C6D7E3",
+"2X c #C3D7E4",
+"3X c #C1D7E6",
+"4X c #C7D8E3",
+"5X c #C5D8E5",
+"6X c #C7D9E5",
+"7X c #CBD9E4",
+"8X c #CBDAE5",
+"9X c #CDDAE4",
+"0X c #CCDBE5",
+"qX c #CFDBE5",
+"wX c #CBDCE7",
+"eX c #C0D9E8",
+"rX c #C2DBEA",
+"tX c #C4DAE8",
+"yX c #D0DEE7",
+"uX c #D1DFE8",
+"iX c #D0DFE9",
+"pX c #D0E0EA",
+"aX c #D1E1EB",
+"sX c #D3E1EA",
+"dX c #D4E1E9",
+"fX c #D4E1EA",
+"gX c #D5E2EA",
+"hX c #D4E2EB",
+"jX c #D6E2EB",
+"kX c #D3E2EC",
+"lX c #D8E3EA",
+"zX c #DFE6EB",
+"xX c #D9E4EC",
+"cX c #D9E5ED",
+"vX c #DAE5ED",
+"bX c #DAE6ED",
+"nX c #DCE7EE",
+"mX c #DBE8EF",
+"MX c #DDE8EF",
+"NX c #DFE8EF",
+"BX c #EAE8E3",
+"VX c #EBEAE6",
+"CX c #ECEBE8",
+"ZX c #E9EEEA",
+"AX c #F0EFEC",
+"SX c #F2F0ED",
+"DX c #E1ECF3",
+"FX c #E4EDF3",
+"GX c #E8EFF4",
+"HX c #F0F3F1",
+"JX c None",
+/* pixels */
+"JXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJX",
+"JXJXJXJXJXJXJXJXu D p t i V w JXJXJXJXJXJXJXJXJX",
+"JXJXJXJXJXJXC X./.&XDXGX%X{.m._ r JXJXJXJXJXJXJX",
+"JXJXJXJXJXi /.DXnXnXFXuX7X$X$XjXM.w JXJXJXJXJXJX",
+"JXJXJXJX/ ^.qXbX1XkX5X5X-X;XsXqXjXN.B JXJXJXJXJX",
+"JXJXJXe (.bXMXDXaXtXtX3XoXbXjXsXyX7Xx.q JXJXJXJX",
+"JXJX7 k.jXbXbX5X3XeXrXOXXX1XsXyXwX$X|.4.3 JXJXJX",
+"JXJXX.:XuXjX'.]._.y. G.sXW.|..X$X[.H.' JXJXJX",
+"JXJXu.$XqXT.H.>. e.o. sXwX}.R.R.`.H.1.- JXJX",
+"JX4 a.9.C.h.] a n.V.BXo. p.!.T.l.4.- JXJX",
+"JX2 F.d.5.7. =XAXc.BXo. @X@XZX !.C.F.@.> JXJX",
+" o.=XAXc.BXo. t.U.z.3.Y $ JXJX",
+"BXBXBXBXVXBXBXAXVXO.CXo. P.C.!.I.J.C.;.L * JXJX",
+"o.o.o.o.o. . .B.b...*X . $.*.T.J.A.h.Y c @ JXJX",
+" .w.r.| +X . 1.C.3.L h JXJX",
+"JXJX6 Q ^ 1.% w.r.| +X . @X@XHX h.:.M , JXJX",
+"JXJXO x T #.] 0 +.} v.) -.s.H 9 O JXJXJX",
+"JXJXJX+ n ! i.X.% % e.( Q Y %.0.&.f O JXJXJX",
+"JXJXJXJX& A s.8.E A % % A K J R ` g @ JXJXJXJX",
+"JXJXJXJXJX@ C ~ m M J N M b v l < O JXJXJXJXJX",
+"JXJXJXJXJXJX : 5 d k z k d 1 & JXJXJXJXJXJX",
+"JXJXJXJXJXJXJXJX JXJXJXJXJXJXJXJX",
+"JXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJX",
+"JXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJXJX"
+};
diff --git a/etc/images/down.svg b/etc/images/down.svg
index e2760427d73..707cd23ea4b 100644
--- a/etc/images/down.svg
+++ b/etc/images/down.svg
@@ -25,7 +25,7 @@
<title id='title8473'>Gnome Symbolic Icons</title>
<defs id='defs7386'/>
<g inkscape:groupmode='layer' id='layer10' inkscape:label='ui' transform='translate(-152.00586,-952)'>
- <path inkscape:connector-curvature='0' d='m 166,957 -5.99414,5.99999 L 154,957 Z' id='path6424' sodipodi:nodetypes='cccc' style='fill:#2e3436;fill-opacity:1;stroke:none'/>
+ <path inkscape:connector-curvature='0' d='m 166,957 -5.99414,5.99999 L 154,957 Z' id='path6424' sodipodi:nodetypes='cccc' style='fill-opacity:1;stroke:none'/>
</g>
<g inkscape:groupmode='layer' id='layer1' inkscape:label='status' transform='translate(-152.00586,-888)'/>
<g inkscape:groupmode='layer' id='layer11' inkscape:label='legacy' transform='translate(-152.00586,-952)'/>
diff --git a/etc/images/left.svg b/etc/images/left.svg
index d6429bc4109..893515d2dfd 100644
--- a/etc/images/left.svg
+++ b/etc/images/left.svg
@@ -25,7 +25,7 @@
<title id='title8473'>Gnome Symbolic Icons</title>
<defs id='defs7386'/>
<g inkscape:groupmode='layer' id='layer10' inkscape:label='ui' transform='translate(-92.005848,-951.99999)'>
- <path inkscape:connector-curvature='0' d='M 103,966 97.00585,959.99999 103,954 Z' id='path6400' sodipodi:nodetypes='cccc' style='fill:#2e3436;fill-opacity:1;stroke:none'/>
+ <path inkscape:connector-curvature='0' d='M 103,966 97.00585,959.99999 103,954 Z' id='path6400' sodipodi:nodetypes='cccc' style='fill-opacity:1;stroke:none'/>
</g>
<g inkscape:groupmode='layer' id='layer1' inkscape:label='status' transform='translate(-92.005848,-887.99999)'/>
<g inkscape:groupmode='layer' id='layer11' inkscape:label='legacy' transform='translate(-92.005848,-951.99999)'/>
diff --git a/etc/images/right.svg b/etc/images/right.svg
index d58cd364359..6c7d715939d 100644
--- a/etc/images/right.svg
+++ b/etc/images/right.svg
@@ -25,7 +25,7 @@
<title id='title8473'>Gnome Symbolic Icons</title>
<defs id='defs7386'/>
<g inkscape:groupmode='layer' id='layer10' inkscape:label='ui' transform='translate(-112.00585,-951.99999)'>
- <path inkscape:connector-curvature='0' d='m 117,966 6.00585,-6.00001 L 117,954 Z' id='path6412' sodipodi:nodetypes='cccc' style='fill:#2e3436;fill-opacity:1;stroke:none'/>
+ <path inkscape:connector-curvature='0' d='m 117,966 6.00585,-6.00001 L 117,954 Z' id='path6412' sodipodi:nodetypes='cccc' style='fill-opacity:1;stroke:none'/>
</g>
<g inkscape:groupmode='layer' id='layer1' inkscape:label='status' transform='translate(-112.00585,-887.99999)'/>
<g inkscape:groupmode='layer' id='layer11' inkscape:label='legacy' transform='translate(-112.00585,-951.99999)'/>
diff --git a/etc/images/up.svg b/etc/images/up.svg
index 9e1a245be74..e358c29912b 100644
--- a/etc/images/up.svg
+++ b/etc/images/up.svg
@@ -25,7 +25,7 @@
<title id='title8473'>Gnome Symbolic Icons</title>
<defs id='defs7386'/>
<g inkscape:groupmode='layer' id='layer10' inkscape:label='ui' transform='translate(-132.00585,-952)'>
- <path inkscape:connector-curvature='0' d='M 146,963 140.00585,956.99999 134,963 Z' id='path6418' sodipodi:nodetypes='cccc' style='fill:#2e3436;fill-opacity:1;stroke:none'/>
+ <path inkscape:connector-curvature='0' d='M 146,963 140.00585,956.99999 134,963 Z' id='path6418' sodipodi:nodetypes='cccc' style='fill-opacity:1;stroke:none'/>
</g>
<g inkscape:groupmode='layer' id='layer1' inkscape:label='status' transform='translate(-132.00585,-888)'/>
<g inkscape:groupmode='layer' id='layer11' inkscape:label='legacy' transform='translate(-132.00585,-952)'/>
diff --git a/etc/org.gnu.emacs.defaults.gschema.xml b/etc/org.gnu.emacs.defaults.gschema.xml
new file mode 100644
index 00000000000..7c700ac0b65
--- /dev/null
+++ b/etc/org.gnu.emacs.defaults.gschema.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019-2020 Free Software Foundation, Inc. -->
+<schemalist>
+
+ <schema id="org.gnu.emacs.defaults">
+
+ <key name='alpha' type='s'><default>''</default></key>
+ <key name='auto-raise-lower' type='s'><default>''</default></key>
+ <key name='auto-lower' type='s'><default>''</default></key>
+ <key name='auto-raise' type='s'><default>''</default></key>
+ <key name='background' type='s'><default>''</default></key>
+ <key name='background-mode' type='s'><default>''</default></key>
+ <key name='bitmap-icon' type='s'><default>''</default></key>
+ <key name='border-color' type='s'><default>''</default></key>
+ <key name='border-width' type='s'><default>''</default></key>
+ <key name='buffer-predicate' type='s'><default>''</default></key>
+ <key name='cursor-blink' type='s'><default>''</default></key>
+ <key name='cursor-type' type='s'><default>''</default></key>
+ <key name='cursor-color' type='s'><default>''</default></key>
+ <key name='font' type='s'><default>''</default></key>
+ <key name='font-backend' type='s'><default>''</default></key>
+ <key name='foreground' type='s'><default>''</default></key>
+ <key name='fullscreen' type='s'><default>''</default></key>
+ <key name='horizontal-scroll-bars' type='s'><default>''</default></key>
+ <key name='icon-name' type='s'><default>''</default></key>
+ <key name='inhibit-double-buffering' type='s'><default>''</default></key>
+ <key name='internal-border' type='s'><default>''</default></key>
+ <key name='internal-border-width' type='s'><default>''</default></key>
+ <key name='left-fringe' type='s'><default>''</default></key>
+ <key name='line-spacing' type='s'><default>''</default></key>
+ <key name='menu-bar' type='s'><default>''</default></key>
+ <key name='minibuffer' type='s'><default>''</default></key>
+ <key name='name' type='s'><default>''</default></key>
+ <key name='pointer-color' type='s'><default>''</default></key>
+ <key name='reverse-video' type='s'><default>''</default></key>
+ <key name='right-fringe' type='s'><default>''</default></key>
+ <key name='screen-gamma' type='s'><default>''</default></key>
+ <key name='scroll-bar' type='s'><default>''</default></key>
+ <key name='scroll-bar-background' type='s'><default>''</default></key>
+ <key name='scroll-bar-foreground' type='s'><default>''</default></key>
+ <key name='scroll-bar-height' type='s'><default>''</default></key>
+ <key name='scroll-bar-width' type='s'><default>''</default></key>
+ <key name='scroll-bars' type='s'><default>''</default></key>
+ <key name='title' type='s'><default>''</default></key>
+ <key name='tool-bar' type='s'><default>''</default></key>
+ <key name='vertical-scroll-bars' type='s'><default>''</default></key>
+ <key name='wait-for-w-m' type='s'><default>''</default></key>
+
+ </schema>
+
+</schemalist>
diff --git a/etc/org/csl/README b/etc/org/csl/README
new file mode 100644
index 00000000000..a9212207ccf
--- /dev/null
+++ b/etc/org/csl/README
@@ -0,0 +1,10 @@
+These data files are used by Org's oc-csl.el library.
+
+LICENSE INFORMATION
+
+chicago-author-date.csl
+locales-en-US.xml
+
+ Both of these files are part of the Citation Style Language (CSL)
+ project (<https://citationstyles.org/>) and are released under the
+ Creative Commons Attribution-ShareAlike 3.0 Unported license.
diff --git a/etc/org/csl/chicago-author-date.csl b/etc/org/csl/chicago-author-date.csl
new file mode 100644
index 00000000000..8c133354b38
--- /dev/null
+++ b/etc/org/csl/chicago-author-date.csl
@@ -0,0 +1,658 @@
+<?xml version="1.0" encoding="utf-8"?>
+<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="display-and-sort" page-range-format="chicago">
+ <info>
+ <title>Chicago Manual of Style 17th edition (author-date)</title>
+ <id>http://www.zotero.org/styles/chicago-author-date</id>
+ <link href="http://www.zotero.org/styles/chicago-author-date" rel="self"/>
+ <link href="http://www.chicagomanualofstyle.org/tools_citationguide.html" rel="documentation"/>
+ <author>
+ <name>Julian Onions</name>
+ <email>julian.onions@gmail.com</email>
+ </author>
+ <contributor>
+ <name>Sebastian Karcher</name>
+ </contributor>
+ <contributor>
+ <name>Richard Karnesky</name>
+ <email>karnesky+zotero@gmail.com</email>
+ <uri>http://arc.nucapt.northwestern.edu/Richard_Karnesky</uri>
+ </contributor>
+ <contributor>
+ <name>Andrew Dunning</name>
+ <email>andrew.dunning@utoronto.ca</email>
+ <uri>https://orcid.org/0000-0003-0464-5036</uri>
+ </contributor>
+ <contributor>
+ <name>Matthew Roth</name>
+ <email>matthew.g.roth@yale.edu</email>
+ <uri> https://orcid.org/0000-0001-7902-6331</uri>
+ </contributor>
+ <contributor>
+ <name>Brenton M. Wiernik</name>
+ </contributor>
+ <category citation-format="author-date"/>
+ <category field="generic-base"/>
+ <summary>The author-date variant of the Chicago style</summary>
+ <updated>2018-01-24T12:00:00+00:00</updated>
+ <rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
+ </info>
+ <locale xml:lang="en">
+ <terms>
+ <term name="editor" form="verb-short">ed.</term>
+ <term name="container-author" form="verb">by</term>
+ <term name="translator" form="verb-short">trans.</term>
+ <term name="editortranslator" form="verb">edited and translated by</term>
+ <term name="translator" form="short">trans.</term>
+ </terms>
+ </locale>
+ <macro name="secondary-contributors">
+ <choose>
+ <if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="none">
+ <group delimiter=". ">
+ <names variable="editor translator" delimiter=". ">
+ <label form="verb" text-case="capitalize-first" suffix=" "/>
+ <name and="text" delimiter=", "/>
+ </names>
+ <names variable="director" delimiter=". ">
+ <label form="verb" text-case="capitalize-first" suffix=" "/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </group>
+ </if>
+ </choose>
+ </macro>
+ <macro name="container-contributors">
+ <choose>
+ <if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="any">
+ <group prefix=", " delimiter=", ">
+ <names variable="container-author" delimiter=", ">
+ <label form="verb" suffix=" "/>
+ <name and="text" delimiter=", "/>
+ </names>
+ <names variable="editor translator" delimiter=", ">
+ <label form="verb" suffix=" "/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </group>
+ </if>
+ </choose>
+ </macro>
+ <macro name="editor">
+ <names variable="editor">
+ <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="short" prefix=", "/>
+ </names>
+ </macro>
+ <macro name="translator">
+ <names variable="translator">
+ <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="short" prefix=", "/>
+ </names>
+ </macro>
+ <macro name="recipient">
+ <choose>
+ <if type="personal_communication">
+ <choose>
+ <if variable="genre">
+ <text variable="genre" text-case="capitalize-first"/>
+ </if>
+ <else>
+ <text term="letter" text-case="capitalize-first"/>
+ </else>
+ </choose>
+ </if>
+ </choose>
+ <names variable="recipient" delimiter=", ">
+ <label form="verb" prefix=" " text-case="lowercase" suffix=" "/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </macro>
+ <macro name="substitute-title">
+ <choose>
+ <if type="article-magazine article-newspaper review review-book" match="any">
+ <text macro="container-title"/>
+ </if>
+ </choose>
+ </macro>
+ <macro name="contributors">
+ <group delimiter=". ">
+ <names variable="author">
+ <name and="text" name-as-sort-order="first" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="short" prefix=", "/>
+ <substitute>
+ <names variable="editor"/>
+ <names variable="translator"/>
+ <names variable="director"/>
+ <text macro="substitute-title"/>
+ <text macro="title"/>
+ </substitute>
+ </names>
+ <text macro="recipient"/>
+ </group>
+ </macro>
+ <macro name="contributors-short">
+ <names variable="author">
+ <name form="short" and="text" delimiter=", " initialize-with=". "/>
+ <substitute>
+ <names variable="editor"/>
+ <names variable="translator"/>
+ <names variable="director"/>
+ <text macro="substitute-title"/>
+ <text macro="title"/>
+ </substitute>
+ </names>
+ </macro>
+ <macro name="interviewer">
+ <names variable="interviewer" delimiter=", ">
+ <label form="verb" prefix=" " text-case="capitalize-first" suffix=" "/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </macro>
+ <macro name="archive">
+ <group delimiter=". ">
+ <text variable="archive_location" text-case="capitalize-first"/>
+ <text variable="archive"/>
+ <text variable="archive-place"/>
+ </group>
+ </macro>
+ <macro name="access">
+ <group delimiter=". ">
+ <choose>
+ <if type="graphic report" match="any">
+ <text macro="archive"/>
+ </if>
+ <else-if type="article-journal bill book chapter legal_case legislation motion_picture paper-conference" match="none">
+ <text macro="archive"/>
+ </else-if>
+ </choose>
+ <choose>
+ <if type="webpage post-weblog" match="any">
+ <date variable="issued" form="text"/>
+ </if>
+ </choose>
+ <choose>
+ <if variable="issued" match="none">
+ <group delimiter=" ">
+ <text term="accessed" text-case="capitalize-first"/>
+ <date variable="accessed" form="text"/>
+ </group>
+ </if>
+ </choose>
+ <choose>
+ <if type="legal_case" match="none">
+ <choose>
+ <if variable="DOI">
+ <text variable="DOI" prefix="https://doi.org/"/>
+ </if>
+ <else>
+ <text variable="URL"/>
+ </else>
+ </choose>
+ </if>
+ </choose>
+ </group>
+ </macro>
+ <macro name="title">
+ <choose>
+ <if variable="title" match="none">
+ <choose>
+ <if type="personal_communication" match="none">
+ <text variable="genre" text-case="capitalize-first"/>
+ </if>
+ </choose>
+ </if>
+ <else-if type="bill book graphic legislation motion_picture song" match="any">
+ <text variable="title" text-case="title" font-style="italic"/>
+ <group prefix=" (" suffix=")" delimiter=" ">
+ <text term="version"/>
+ <text variable="version"/>
+ </group>
+ </else-if>
+ <else-if variable="reviewed-author">
+ <choose>
+ <if variable="reviewed-title">
+ <group delimiter=". ">
+ <text variable="title" text-case="title" quotes="true"/>
+ <group delimiter=", ">
+ <text variable="reviewed-title" text-case="title" font-style="italic" prefix="Review of "/>
+ <names variable="reviewed-author">
+ <label form="verb-short" text-case="lowercase" suffix=" "/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </group>
+ </group>
+ </if>
+ <else>
+ <group delimiter=", ">
+ <text variable="title" text-case="title" font-style="italic" prefix="Review of "/>
+ <names variable="reviewed-author">
+ <label form="verb-short" text-case="lowercase" suffix=" "/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </group>
+ </else>
+ </choose>
+ </else-if>
+ <else-if type="legal_case interview patent" match="any">
+ <text variable="title"/>
+ </else-if>
+ <else>
+ <text variable="title" text-case="title" quotes="true"/>
+ </else>
+ </choose>
+ </macro>
+ <macro name="edition">
+ <choose>
+ <if type="bill book graphic legal_case legislation motion_picture report song" match="any">
+ <choose>
+ <if is-numeric="edition">
+ <group delimiter=" " prefix=". ">
+ <number variable="edition" form="ordinal"/>
+ <text term="edition" form="short" strip-periods="true"/>
+ </group>
+ </if>
+ <else>
+ <text variable="edition" text-case="capitalize-first" prefix=". "/>
+ </else>
+ </choose>
+ </if>
+ <else-if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="any">
+ <choose>
+ <if is-numeric="edition">
+ <group delimiter=" " prefix=", ">
+ <number variable="edition" form="ordinal"/>
+ <text term="edition" form="short"/>
+ </group>
+ </if>
+ <else>
+ <text variable="edition" prefix=", "/>
+ </else>
+ </choose>
+ </else-if>
+ </choose>
+ </macro>
+ <macro name="locators">
+ <choose>
+ <if type="article-journal">
+ <choose>
+ <if variable="volume">
+ <text variable="volume" prefix=" "/>
+ <group prefix=" (" suffix=")">
+ <choose>
+ <if variable="issue">
+ <text variable="issue"/>
+ </if>
+ <else>
+ <date variable="issued">
+ <date-part name="month"/>
+ </date>
+ </else>
+ </choose>
+ </group>
+ </if>
+ <else-if variable="issue">
+ <group delimiter=" " prefix=", ">
+ <text term="issue" form="short"/>
+ <text variable="issue"/>
+ <date variable="issued" prefix="(" suffix=")">
+ <date-part name="month"/>
+ </date>
+ </group>
+ </else-if>
+ <else>
+ <date variable="issued" prefix=", ">
+ <date-part name="month"/>
+ </date>
+ </else>
+ </choose>
+ </if>
+ <else-if type="legal_case">
+ <text variable="volume" prefix=", "/>
+ <text variable="container-title" prefix=" "/>
+ <text variable="page" prefix=" "/>
+ </else-if>
+ <else-if type="bill book graphic legal_case legislation motion_picture report song" match="any">
+ <group prefix=". " delimiter=". ">
+ <group>
+ <text term="volume" form="short" text-case="capitalize-first" suffix=" "/>
+ <number variable="volume" form="numeric"/>
+ </group>
+ <group>
+ <number variable="number-of-volumes" form="numeric"/>
+ <text term="volume" form="short" prefix=" " plural="true"/>
+ </group>
+ </group>
+ </else-if>
+ <else-if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="any">
+ <choose>
+ <if variable="page" match="none">
+ <group prefix=". ">
+ <text term="volume" form="short" text-case="capitalize-first" suffix=" "/>
+ <number variable="volume" form="numeric"/>
+ </group>
+ </if>
+ </choose>
+ </else-if>
+ </choose>
+ </macro>
+ <macro name="locators-chapter">
+ <choose>
+ <if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="any">
+ <choose>
+ <if variable="page">
+ <group prefix=", ">
+ <text variable="volume" suffix=":"/>
+ <text variable="page"/>
+ </group>
+ </if>
+ </choose>
+ </if>
+ </choose>
+ </macro>
+ <macro name="locators-article">
+ <choose>
+ <if type="article-newspaper">
+ <group prefix=", " delimiter=", ">
+ <group delimiter=" ">
+ <text variable="edition"/>
+ <text term="edition"/>
+ </group>
+ <group>
+ <text term="section" form="short" suffix=" "/>
+ <text variable="section"/>
+ </group>
+ </group>
+ </if>
+ <else-if type="article-journal">
+ <choose>
+ <if variable="volume issue" match="any">
+ <text variable="page" prefix=": "/>
+ </if>
+ <else>
+ <text variable="page" prefix=", "/>
+ </else>
+ </choose>
+ </else-if>
+ </choose>
+ </macro>
+ <macro name="point-locators">
+ <choose>
+ <if variable="locator">
+ <choose>
+ <if locator="page" match="none">
+ <choose>
+ <if type="bill book graphic legal_case legislation motion_picture report song" match="any">
+ <choose>
+ <if variable="volume">
+ <group>
+ <text term="volume" form="short" suffix=" "/>
+ <number variable="volume" form="numeric"/>
+ <label variable="locator" form="short" prefix=", " suffix=" "/>
+ </group>
+ </if>
+ <else>
+ <label variable="locator" form="short" suffix=" "/>
+ </else>
+ </choose>
+ </if>
+ <else>
+ <label variable="locator" form="short" suffix=" "/>
+ </else>
+ </choose>
+ </if>
+ <else-if type="bill book graphic legal_case legislation motion_picture report song" match="any">
+ <number variable="volume" form="numeric" suffix=":"/>
+ </else-if>
+ </choose>
+ <text variable="locator"/>
+ </if>
+ </choose>
+ </macro>
+ <macro name="container-prefix">
+ <text term="in" text-case="capitalize-first"/>
+ </macro>
+ <macro name="container-title">
+ <choose>
+ <if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="any">
+ <text macro="container-prefix" suffix=" "/>
+ </if>
+ </choose>
+ <choose>
+ <if type="webpage">
+ <text variable="container-title" text-case="title"/>
+ </if>
+ <else-if type="legal_case" match="none">
+ <group delimiter=" ">
+ <text variable="container-title" text-case="title" font-style="italic"/>
+ <choose>
+ <if type="post-weblog">
+ <text value="(blog)"/>
+ </if>
+ </choose>
+ </group>
+ </else-if>
+ </choose>
+ </macro>
+ <macro name="publisher">
+ <group delimiter=": ">
+ <text variable="publisher-place"/>
+ <text variable="publisher"/>
+ </group>
+ </macro>
+ <macro name="date">
+ <choose>
+ <if variable="issued">
+ <group delimiter=" ">
+ <date variable="original-date" form="text" date-parts="year" prefix="(" suffix=")"/>
+ <date variable="issued">
+ <date-part name="year"/>
+ </date>
+ </group>
+ </if>
+ <else-if variable="status">
+ <text variable="status" text-case="capitalize-first"/>
+ </else-if>
+ <else>
+ <text term="no date" form="short"/>
+ </else>
+ </choose>
+ </macro>
+ <macro name="date-in-text">
+ <choose>
+ <if variable="issued">
+ <group delimiter=" ">
+ <date variable="original-date" form="text" date-parts="year" prefix="[" suffix="]"/>
+ <date variable="issued">
+ <date-part name="year"/>
+ </date>
+ </group>
+ </if>
+ <else-if variable="status">
+ <text variable="status"/>
+ </else-if>
+ <else>
+ <text term="no date" form="short"/>
+ </else>
+ </choose>
+ </macro>
+ <macro name="day-month">
+ <date variable="issued">
+ <date-part name="month"/>
+ <date-part name="day" prefix=" "/>
+ </date>
+ </macro>
+ <macro name="collection-title">
+ <choose>
+ <if match="none" type="article-journal">
+ <choose>
+ <if match="none" is-numeric="collection-number">
+ <group delimiter=", ">
+ <text variable="collection-title" text-case="title"/>
+ <text variable="collection-number"/>
+ </group>
+ </if>
+ <else>
+ <group delimiter=" ">
+ <text variable="collection-title" text-case="title"/>
+ <text variable="collection-number"/>
+ </group>
+ </else>
+ </choose>
+ </if>
+ </choose>
+ </macro>
+ <macro name="collection-title-journal">
+ <choose>
+ <if type="article-journal">
+ <group delimiter=" ">
+ <text variable="collection-title"/>
+ <text variable="collection-number"/>
+ </group>
+ </if>
+ </choose>
+ </macro>
+ <macro name="event">
+ <group delimiter=" ">
+ <choose>
+ <if variable="genre">
+ <text term="presented at"/>
+ </if>
+ <else>
+ <text term="presented at" text-case="capitalize-first"/>
+ </else>
+ </choose>
+ <text variable="event"/>
+ </group>
+ </macro>
+ <macro name="description">
+ <choose>
+ <if variable="interviewer" type="interview" match="any">
+ <group delimiter=". ">
+ <text macro="interviewer"/>
+ <text variable="medium" text-case="capitalize-first"/>
+ </group>
+ </if>
+ <else-if type="patent">
+ <group delimiter=" " prefix=". ">
+ <text variable="authority"/>
+ <text variable="number"/>
+ </group>
+ </else-if>
+ <else>
+ <text variable="medium" text-case="capitalize-first" prefix=". "/>
+ </else>
+ </choose>
+ <choose>
+ <if variable="title" match="none"/>
+ <else-if type="thesis personal_communication speech" match="any"/>
+ <else>
+ <group delimiter=" " prefix=". ">
+ <text variable="genre" text-case="capitalize-first"/>
+ <choose>
+ <if type="report">
+ <text variable="number"/>
+ </if>
+ </choose>
+ </group>
+ </else>
+ </choose>
+ </macro>
+ <macro name="issue">
+ <choose>
+ <if type="legal_case">
+ <text variable="authority" prefix=". "/>
+ </if>
+ <else-if type="speech">
+ <group prefix=". " delimiter=", ">
+ <group delimiter=" ">
+ <text variable="genre" text-case="capitalize-first"/>
+ <text macro="event"/>
+ </group>
+ <text variable="event-place"/>
+ <text macro="day-month"/>
+ </group>
+ </else-if>
+ <else-if type="article-newspaper article-magazine personal_communication" match="any">
+ <date variable="issued" form="text" prefix=", "/>
+ </else-if>
+ <else-if type="patent">
+ <group delimiter=", " prefix=", ">
+ <group delimiter=" ">
+ <!--Needs Localization-->
+ <text value="filed"/>
+ <date variable="submitted" form="text"/>
+ </group>
+ <group delimiter=" ">
+ <choose>
+ <if variable="issued submitted" match="all">
+ <text term="and"/>
+ </if>
+ </choose>
+ <!--Needs Localization-->
+ <text value="issued"/>
+ <date variable="issued" form="text"/>
+ </group>
+ </group>
+ </else-if>
+ <else-if type="article-journal" match="any"/>
+ <else>
+ <group prefix=". " delimiter=", ">
+ <choose>
+ <if type="thesis">
+ <text variable="genre" text-case="capitalize-first"/>
+ </if>
+ </choose>
+ <text macro="publisher"/>
+ </group>
+ </else>
+ </choose>
+ </macro>
+ <citation et-al-min="4" et-al-use-first="1" disambiguate-add-year-suffix="true" disambiguate-add-names="true" disambiguate-add-givenname="true" givenname-disambiguation-rule="primary-name" collapse="year" after-collapse-delimiter="; ">
+ <layout prefix="(" suffix=")" delimiter="; ">
+ <group delimiter=", ">
+ <choose>
+ <if variable="issued accessed" match="any">
+ <group delimiter=" ">
+ <text macro="contributors-short"/>
+ <text macro="date-in-text"/>
+ </group>
+ </if>
+ <!---comma before forthcoming and n.d.-->
+ <else>
+ <group delimiter=", ">
+ <text macro="contributors-short"/>
+ <text macro="date-in-text"/>
+ </group>
+ </else>
+ </choose>
+ <text macro="point-locators"/>
+ </group>
+ </layout>
+ </citation>
+ <bibliography hanging-indent="true" et-al-min="11" et-al-use-first="7" subsequent-author-substitute="&#8212;&#8212;&#8212;" entry-spacing="0">
+ <sort>
+ <key macro="contributors"/>
+ <key variable="issued"/>
+ <key variable="title"/>
+ </sort>
+ <layout suffix=".">
+ <group delimiter=". ">
+ <text macro="contributors"/>
+ <text macro="date"/>
+ <text macro="title"/>
+ </group>
+ <text macro="description"/>
+ <text macro="secondary-contributors" prefix=". "/>
+ <text macro="container-title" prefix=". "/>
+ <text macro="container-contributors"/>
+ <text macro="edition"/>
+ <text macro="locators-chapter"/>
+ <text macro="collection-title-journal" prefix=", " suffix=", "/>
+ <text macro="locators"/>
+ <text macro="collection-title" prefix=". "/>
+ <text macro="issue"/>
+ <text macro="locators-article"/>
+ <text macro="access" prefix=". "/>
+ </layout>
+ </bibliography>
+</style>
diff --git a/etc/org/csl/locales-en-US.xml b/etc/org/csl/locales-en-US.xml
new file mode 100644
index 00000000000..be78c5e81fd
--- /dev/null
+++ b/etc/org/csl/locales-en-US.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="utf-8"?>
+<locale xmlns="http://purl.org/net/xbiblio/csl" version="1.0" xml:lang="en-US">
+ <info>
+ <translator>
+ <name>Andrew Dunning</name>
+ </translator>
+ <translator>
+ <name>Sebastian Karcher</name>
+ </translator>
+ <translator>
+ <name>Rintze M. Zelle</name>
+ </translator>
+ <rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
+ <updated>2015-10-10T23:31:02+00:00</updated>
+ </info>
+ <style-options punctuation-in-quote="true"/>
+ <date form="text">
+ <date-part name="month" suffix=" "/>
+ <date-part name="day" suffix=", "/>
+ <date-part name="year"/>
+ </date>
+ <date form="numeric">
+ <date-part name="month" form="numeric-leading-zeros" suffix="/"/>
+ <date-part name="day" form="numeric-leading-zeros" suffix="/"/>
+ <date-part name="year"/>
+ </date>
+ <terms>
+ <term name="accessed">accessed</term>
+ <term name="and">and</term>
+ <term name="and others">and others</term>
+ <term name="anonymous">anonymous</term>
+ <term name="anonymous" form="short">anon.</term>
+ <term name="at">at</term>
+ <term name="available at">available at</term>
+ <term name="by">by</term>
+ <term name="circa">circa</term>
+ <term name="circa" form="short">c.</term>
+ <term name="cited">cited</term>
+ <term name="edition">
+ <single>edition</single>
+ <multiple>editions</multiple>
+ </term>
+ <term name="edition" form="short">ed.</term>
+ <term name="et-al">et al.</term>
+ <term name="forthcoming">forthcoming</term>
+ <term name="from">from</term>
+ <term name="ibid">ibid.</term>
+ <term name="in">in</term>
+ <term name="in press">in press</term>
+ <term name="internet">internet</term>
+ <term name="interview">interview</term>
+ <term name="letter">letter</term>
+ <term name="no date">no date</term>
+ <term name="no date" form="short">n.d.</term>
+ <term name="online">online</term>
+ <term name="presented at">presented at the</term>
+ <term name="reference">
+ <single>reference</single>
+ <multiple>references</multiple>
+ </term>
+ <term name="reference" form="short">
+ <single>ref.</single>
+ <multiple>refs.</multiple>
+ </term>
+ <term name="retrieved">retrieved</term>
+ <term name="scale">scale</term>
+ <term name="version">version</term>
+
+ <!-- ANNO DOMINI; BEFORE CHRIST -->
+ <term name="ad">AD</term>
+ <term name="bc">BC</term>
+
+ <!-- PUNCTUATION -->
+ <term name="open-quote">“</term>
+ <term name="close-quote">”</term>
+ <term name="open-inner-quote">‘</term>
+ <term name="close-inner-quote">’</term>
+ <term name="page-range-delimiter">–</term>
+
+ <!-- ORDINALS -->
+ <term name="ordinal">th</term>
+ <term name="ordinal-01">st</term>
+ <term name="ordinal-02">nd</term>
+ <term name="ordinal-03">rd</term>
+ <term name="ordinal-11">th</term>
+ <term name="ordinal-12">th</term>
+ <term name="ordinal-13">th</term>
+
+ <!-- LONG ORDINALS -->
+ <term name="long-ordinal-01">first</term>
+ <term name="long-ordinal-02">second</term>
+ <term name="long-ordinal-03">third</term>
+ <term name="long-ordinal-04">fourth</term>
+ <term name="long-ordinal-05">fifth</term>
+ <term name="long-ordinal-06">sixth</term>
+ <term name="long-ordinal-07">seventh</term>
+ <term name="long-ordinal-08">eighth</term>
+ <term name="long-ordinal-09">ninth</term>
+ <term name="long-ordinal-10">tenth</term>
+
+ <!-- LONG LOCATOR FORMS -->
+ <term name="book">
+ <single>book</single>
+ <multiple>books</multiple>
+ </term>
+ <term name="chapter">
+ <single>chapter</single>
+ <multiple>chapters</multiple>
+ </term>
+ <term name="column">
+ <single>column</single>
+ <multiple>columns</multiple>
+ </term>
+ <term name="figure">
+ <single>figure</single>
+ <multiple>figures</multiple>
+ </term>
+ <term name="folio">
+ <single>folio</single>
+ <multiple>folios</multiple>
+ </term>
+ <term name="issue">
+ <single>number</single>
+ <multiple>numbers</multiple>
+ </term>
+ <term name="line">
+ <single>line</single>
+ <multiple>lines</multiple>
+ </term>
+ <term name="note">
+ <single>note</single>
+ <multiple>notes</multiple>
+ </term>
+ <term name="opus">
+ <single>opus</single>
+ <multiple>opera</multiple>
+ </term>
+ <term name="page">
+ <single>page</single>
+ <multiple>pages</multiple>
+ </term>
+ <term name="number-of-pages">
+ <single>page</single>
+ <multiple>pages</multiple>
+ </term>
+ <term name="paragraph">
+ <single>paragraph</single>
+ <multiple>paragraphs</multiple>
+ </term>
+ <term name="part">
+ <single>part</single>
+ <multiple>parts</multiple>
+ </term>
+ <term name="section">
+ <single>section</single>
+ <multiple>sections</multiple>
+ </term>
+ <term name="sub verbo">
+ <single>sub verbo</single>
+ <multiple>sub verbis</multiple>
+ </term>
+ <term name="verse">
+ <single>verse</single>
+ <multiple>verses</multiple>
+ </term>
+ <term name="volume">
+ <single>volume</single>
+ <multiple>volumes</multiple>
+ </term>
+
+ <!-- SHORT LOCATOR FORMS -->
+ <term name="book" form="short">
+ <single>bk.</single>
+ <multiple>bks.</multiple>
+ </term>
+ <term name="chapter" form="short">
+ <single>chap.</single>
+ <multiple>chaps.</multiple>
+ </term>
+ <term name="column" form="short">
+ <single>col.</single>
+ <multiple>cols.</multiple>
+ </term>
+ <term name="figure" form="short">
+ <single>fig.</single>
+ <multiple>figs.</multiple>
+ </term>
+ <term name="folio" form="short">
+ <single>fol.</single>
+ <multiple>fols.</multiple>
+ </term>
+ <term name="issue" form="short">
+ <single>no.</single>
+ <multiple>nos.</multiple>
+ </term>
+ <term name="line" form="short">
+ <single>l.</single>
+ <multiple>ll.</multiple>
+ </term>
+ <term name="note" form="short">
+ <single>n.</single>
+ <multiple>nn.</multiple>
+ </term>
+ <term name="opus" form="short">
+ <single>op.</single>
+ <multiple>opp.</multiple>
+ </term>
+ <term name="page" form="short">
+ <single>p.</single>
+ <multiple>pp.</multiple>
+ </term>
+ <term name="number-of-pages" form="short">
+ <single>p.</single>
+ <multiple>pp.</multiple>
+ </term>
+ <term name="paragraph" form="short">
+ <single>para.</single>
+ <multiple>paras.</multiple>
+ </term>
+ <term name="part" form="short">
+ <single>pt.</single>
+ <multiple>pts.</multiple>
+ </term>
+ <term name="section" form="short">
+ <single>sec.</single>
+ <multiple>secs.</multiple>
+ </term>
+ <term name="sub verbo" form="short">
+ <single>s.v.</single>
+ <multiple>s.vv.</multiple>
+ </term>
+ <term name="verse" form="short">
+ <single>v.</single>
+ <multiple>vv.</multiple>
+ </term>
+ <term name="volume" form="short">
+ <single>vol.</single>
+ <multiple>vols.</multiple>
+ </term>
+
+ <!-- SYMBOL LOCATOR FORMS -->
+ <term name="paragraph" form="symbol">
+ <single>¶</single>
+ <multiple>¶¶</multiple>
+ </term>
+ <term name="section" form="symbol">
+ <single>§</single>
+ <multiple>§§</multiple>
+ </term>
+
+ <!-- LONG ROLE FORMS -->
+ <term name="director">
+ <single>director</single>
+ <multiple>directors</multiple>
+ </term>
+ <term name="editor">
+ <single>editor</single>
+ <multiple>editors</multiple>
+ </term>
+ <term name="editorial-director">
+ <single>editor</single>
+ <multiple>editors</multiple>
+ </term>
+ <term name="illustrator">
+ <single>illustrator</single>
+ <multiple>illustrators</multiple>
+ </term>
+ <term name="translator">
+ <single>translator</single>
+ <multiple>translators</multiple>
+ </term>
+ <term name="editortranslator">
+ <single>editor &amp; translator</single>
+ <multiple>editors &amp; translators</multiple>
+ </term>
+
+ <!-- SHORT ROLE FORMS -->
+ <term name="director" form="short">
+ <single>dir.</single>
+ <multiple>dirs.</multiple>
+ </term>
+ <term name="editor" form="short">
+ <single>ed.</single>
+ <multiple>eds.</multiple>
+ </term>
+ <term name="editorial-director" form="short">
+ <single>ed.</single>
+ <multiple>eds.</multiple>
+ </term>
+ <term name="illustrator" form="short">
+ <single>ill.</single>
+ <multiple>ills.</multiple>
+ </term>
+ <term name="translator" form="short">
+ <single>tran.</single>
+ <multiple>trans.</multiple>
+ </term>
+ <term name="editortranslator" form="short">
+ <single>ed. &amp; tran.</single>
+ <multiple>eds. &amp; trans.</multiple>
+ </term>
+
+ <!-- VERB ROLE FORMS -->
+ <term name="container-author" form="verb">by</term>
+ <term name="director" form="verb">directed by</term>
+ <term name="editor" form="verb">edited by</term>
+ <term name="editorial-director" form="verb">edited by</term>
+ <term name="illustrator" form="verb">illustrated by</term>
+ <term name="interviewer" form="verb">interview by</term>
+ <term name="recipient" form="verb">to</term>
+ <term name="reviewed-author" form="verb">by</term>
+ <term name="translator" form="verb">translated by</term>
+ <term name="editortranslator" form="verb">edited &amp; translated by</term>
+
+ <!-- SHORT VERB ROLE FORMS -->
+ <term name="director" form="verb-short">dir. by</term>
+ <term name="editor" form="verb-short">ed. by</term>
+ <term name="editorial-director" form="verb-short">ed. by</term>
+ <term name="illustrator" form="verb-short">illus. by</term>
+ <term name="translator" form="verb-short">trans. by</term>
+ <term name="editortranslator" form="verb-short">ed. &amp; trans. by</term>
+
+ <!-- LONG MONTH FORMS -->
+ <term name="month-01">January</term>
+ <term name="month-02">February</term>
+ <term name="month-03">March</term>
+ <term name="month-04">April</term>
+ <term name="month-05">May</term>
+ <term name="month-06">June</term>
+ <term name="month-07">July</term>
+ <term name="month-08">August</term>
+ <term name="month-09">September</term>
+ <term name="month-10">October</term>
+ <term name="month-11">November</term>
+ <term name="month-12">December</term>
+
+ <!-- SHORT MONTH FORMS -->
+ <term name="month-01" form="short">Jan.</term>
+ <term name="month-02" form="short">Feb.</term>
+ <term name="month-03" form="short">Mar.</term>
+ <term name="month-04" form="short">Apr.</term>
+ <term name="month-05" form="short">May</term>
+ <term name="month-06" form="short">Jun.</term>
+ <term name="month-07" form="short">Jul.</term>
+ <term name="month-08" form="short">Aug.</term>
+ <term name="month-09" form="short">Sep.</term>
+ <term name="month-10" form="short">Oct.</term>
+ <term name="month-11" form="short">Nov.</term>
+ <term name="month-12" form="short">Dec.</term>
+
+ <!-- SEASONS -->
+ <term name="season-01">Spring</term>
+ <term name="season-02">Summer</term>
+ <term name="season-03">Autumn</term>
+ <term name="season-04">Winter</term>
+ </terms>
+</locale>
diff --git a/etc/publicsuffix.txt b/etc/publicsuffix.txt
index 1ede2b929a0..5529554d82d 100644
--- a/etc/publicsuffix.txt
+++ b/etc/publicsuffix.txt
@@ -175,17 +175,21 @@ it.ao
// aq : https://en.wikipedia.org/wiki/.aq
aq
-// ar : https://nic.ar/nic-argentina/normativa-vigente
+// ar : https://nic.ar/es/nic-argentina/normativa
ar
+bet.ar
com.ar
+coop.ar
edu.ar
gob.ar
gov.ar
int.ar
mil.ar
musica.ar
+mutual.ar
net.ar
org.ar
+senasa.ar
tur.ar
// arpa : https://en.wikipedia.org/wiki/.arpa
@@ -734,7 +738,6 @@ gouv.ci
// cl : https://www.nic.cl
// Confirmed by .CL registry <hsalgado@nic.cl>
cl
-aprendemas.cl
co.cl
gob.cl
gov.cl
@@ -839,7 +842,13 @@ gov.cu
inf.cu
// cv : https://en.wikipedia.org/wiki/.cv
+// cv : http://www.dns.cv/tldcv_portal/do?com=DS;5446457100;111;+PAGE(4000018)+K-CAT-CODIGO(RDOM)+RCNT(100); <- registration rules
cv
+com.cv
+edu.cv
+int.cv
+nome.cv
+org.cv
// cw : http://www.una.cw/cw_registry/
// Confirmed by registry <registry@una.net> 2013-03-26
@@ -1176,6 +1185,7 @@ org.gu
web.gu
// gw : https://en.wikipedia.org/wiki/.gw
+// gw : https://nic.gw/regras/
gw
// gy : https://en.wikipedia.org/wiki/.gy
@@ -4594,15 +4604,17 @@ gob.mx
edu.mx
net.mx
-// my : http://www.mynic.net.my/
+// my : http://www.mynic.my/
+// Available strings: https://mynic.my/resources/domains/buying-a-domain/
my
+biz.my
com.my
-net.my
-org.my
-gov.my
edu.my
+gov.my
mil.my
name.my
+net.my
+org.my
// mz : http://www.uem.mz/
// Submitted by registry <antonio@uem.mz>
@@ -5848,7 +5860,7 @@ com.ps
org.ps
net.ps
-// pt : http://online.dns.pt/dns/start_dns
+// pt : https://www.dns.pt/en/domain/pt-terms-and-conditions-registration-rules/
pt
net.pt
gov.pt
@@ -6085,8 +6097,10 @@ biz.ss
com.ss
edu.ss
gov.ss
+me.ss
net.ss
org.ss
+sch.ss
// st : http://www.nic.st/html/policyrules/
st
@@ -6095,7 +6109,6 @@ com.st
consulado.st
edu.st
embaixada.st
-gov.st
mil.st
net.st
org.st
@@ -6200,29 +6213,22 @@ gov.tm
mil.tm
edu.tm
-// tn : https://en.wikipedia.org/wiki/.tn
-// http://whois.ati.tn/
+// tn : http://www.registre.tn/fr/
+// https://whois.ati.tn/
tn
com.tn
ens.tn
fin.tn
gov.tn
ind.tn
+info.tn
intl.tn
+mincom.tn
nat.tn
net.tn
org.tn
-info.tn
perso.tn
tourism.tn
-edunet.tn
-rnrt.tn
-rns.tn
-rnu.tn
-mincom.tn
-agrinet.tn
-defense.tn
-turen.tn
// to : https://en.wikipedia.org/wiki/.to
// Submitted by registry <egullich@colo.to>
@@ -6712,9 +6718,10 @@ mil.vc
edu.vc
// ve : https://registro.nic.ve/
-// Submitted by registry
+// Submitted by registry nic@nic.ve and nicve@conatel.gob.ve
ve
arts.ve
+bib.ve
co.ve
com.ve
e12.ve
@@ -6726,7 +6733,9 @@ info.ve
int.ve
mil.ve
net.ve
+nom.ve
org.ve
+rar.ve
rec.ve
store.ve
tec.ve
@@ -6805,6 +6814,9 @@ yt
// xn--90ae ("bg", Bulgarian) : BG
бг
+// xn--mgbcpq6gpa1a ("albahrain", Arabic) : BH
+البحرين
+
// xn--90ais ("bel", Belarusian/Russian Cyrillic) : BY
// Operated by .by registry
бел
@@ -6937,6 +6949,9 @@ yt
// xn--80ao21a ("Kaz", Kazakh) : KZ
қаз
+// xn--q7ce6a ("Lao", Lao) : LA
+ລາວ
+
// xn--fzc2c9e2c ("Lanka", Sinhalese-Sinhala) : LK
// https://nic.lk
ලංකා
@@ -7062,7 +7077,13 @@ yt
xxx
// ye : http://www.y.net.ye/services/domain_name.htm
-*.ye
+ye
+com.ye
+edu.ye
+gov.ye
+net.ye
+mil.ye
+org.ye
// za : https://www.zadna.org.za/content/page/domain-information/
ac.za
@@ -7111,7 +7132,7 @@ org.zw
// newGTLDs
-// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2020-11-30T20:26:10Z
+// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2021-11-13T15:12:42Z
// This list is auto-generated, don't edit it manually.
// aaa : 2015-02-26 American Automobile Association, Inc.
aaa
@@ -7137,7 +7158,7 @@ abc
// able : 2015-06-25 Able Inc.
able
-// abogado : 2014-04-24 Minds + Machines Group Limited
+// abogado : 2014-04-24 Registry Services, LLC
abogado
// abudhabi : 2015-07-30 Abu Dhabi Systems and Information Centre
@@ -7335,7 +7356,7 @@ autos
// avianca : 2015-01-08 Avianca Holdings S.A.
avianca
-// aws : 2015-06-25 Amazon Registry Services, Inc.
+// aws : 2015-06-25 AWS Registry LLC
aws
// axa : 2013-12-19 AXA Group Operations SAS
@@ -7413,7 +7434,7 @@ beats
// beauty : 2015-12-03 XYZ.COM LLC
beauty
-// beer : 2014-01-09 Minds + Machines Group Limited
+// beer : 2014-01-09 Registry Services, LLC
beer
// bentley : 2014-12-18 Bentley Motors Limited
@@ -7530,7 +7551,7 @@ bridgestone
// broadway : 2014-12-22 Celebrate Broadway, Inc.
broadway
-// broker : 2014-12-11 Dotbroker Registry Limited
+// broker : 2014-12-11 Dog Beach, LLC
broker
// brother : 2015-01-29 Brother Industries, Ltd.
@@ -7623,15 +7644,12 @@ careers
// cars : 2014-11-13 XYZ.COM LLC
cars
-// casa : 2013-11-21 Minds + Machines Group Limited
+// casa : 2013-11-21 Registry Services, LLC
casa
-// case : 2015-09-03 CNH Industrial N.V.
+// case : 2015-09-03 Helium TLDs Ltd
case
-// caseih : 2015-09-03 CNH Industrial N.V.
-caseih
-
// cash : 2014-03-06 Binky Moon, LLC
cash
@@ -7656,9 +7674,6 @@ cbre
// cbs : 2015-08-06 CBS Domains Inc.
cbs
-// ceb : 2015-04-09 The Corporate Executive Board Company
-ceb
-
// center : 2013-11-07 Binky Moon, LLC
center
@@ -7671,7 +7686,7 @@ cern
// cfa : 2014-08-28 CFA Institute
cfa
-// cfd : 2014-12-11 DotCFD Registry Limited
+// cfd : 2014-12-11 ShortDot SA
cfd
// chanel : 2015-04-09 Chanel International B.V.
@@ -7749,7 +7764,7 @@ clothing
// cloud : 2015-04-16 Aruba PEC S.p.A.
cloud
-// club : 2013-11-08 .CLUB DOMAINS, LLC
+// club : 2013-11-08 Registry Services, LLC
club
// clubmed : 2015-06-25 Club Méditerranée S.A.
@@ -7806,7 +7821,7 @@ contact
// contractors : 2013-09-10 Binky Moon, LLC
contractors
-// cooking : 2013-11-21 Minds + Machines Group Limited
+// cooking : 2013-11-21 Registry Services, LLC
cooking
// cookingchannel : 2015-07-02 Lifestyle Domain Holdings, Inc.
@@ -7839,7 +7854,7 @@ credit
// creditcard : 2014-03-20 Binky Moon, LLC
creditcard
-// creditunion : 2015-01-22 CUNA Performance Resources, LLC
+// creditunion : 2015-01-22 DotCooperation LLC
creditunion
// cricket : 2014-10-09 dot Cricket Limited
@@ -7896,7 +7911,7 @@ day
// dclk : 2014-11-20 Charleston Road Registry Inc.
dclk
-// dds : 2015-05-07 Minds + Machines Group Limited
+// dds : 2015-05-07 Registry Services, LLC
dds
// deal : 2015-06-25 Amazon Registry Services, Inc.
@@ -7935,7 +7950,7 @@ dentist
// desi : 2013-11-14 Desi Networks LLC
desi
-// design : 2014-11-07 Top Level Design, LLC
+// design : 2014-11-07 Registry Services, LLC
design
// dev : 2014-10-16 Charleston Road Registry Inc.
@@ -8007,7 +8022,7 @@ duck
// dunlop : 2015-07-02 The Goodyear Tire & Rubber Company
dunlop
-// dupont : 2015-06-25 E. I. du Pont de Nemours and Company
+// dupont : 2015-06-25 DuPont Specialty Products USA, LLC
dupont
// durban : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
@@ -8124,7 +8139,7 @@ farm
// farmers : 2015-07-09 Farmers Insurance Exchange
farmers
-// fashion : 2014-07-03 Minds + Machines Group Limited
+// fashion : 2014-07-03 Registry Services, LLC
fashion
// fast : 2014-12-18 Amazon Registry Services, Inc.
@@ -8175,10 +8190,10 @@ firmdale
// fish : 2013-12-12 Binky Moon, LLC
fish
-// fishing : 2013-11-21 Minds + Machines Group Limited
+// fishing : 2013-11-21 Registry Services, LLC
fishing
-// fit : 2014-11-07 Minds + Machines Group Limited
+// fit : 2014-11-07 Registry Services, LLC
fit
// fitness : 2014-03-06 Binky Moon, LLC
@@ -8217,7 +8232,7 @@ football
// ford : 2014-11-13 Ford Motor Company
ford
-// forex : 2014-12-11 Dotforex Registry Limited
+// forex : 2014-12-11 Dog Beach, LLC
forex
// forsale : 2014-05-22 Dog Beach, LLC
@@ -8256,10 +8271,7 @@ ftr
// fujitsu : 2015-07-30 Fujitsu Limited
fujitsu
-// fujixerox : 2015-07-23 Xerox DNHC LLC
-fujixerox
-
-// fun : 2016-01-14 DotSpace Inc.
+// fun : 2016-01-14 Radix FZC
fun
// fund : 2014-03-20 Binky Moon, LLC
@@ -8295,7 +8307,7 @@ games
// gap : 2015-07-31 The Gap, Inc.
gap
-// garden : 2014-06-26 Minds + Machines Group Limited
+// garden : 2014-06-26 Registry Services, LLC
garden
// gay : 2019-05-23 Top Level Design, LLC
@@ -8511,13 +8523,13 @@ homesense
// honda : 2014-12-18 Honda Motor Co., Ltd.
honda
-// horse : 2013-11-21 Minds + Machines Group Limited
+// horse : 2013-11-21 Registry Services, LLC
horse
// hospital : 2016-10-20 Binky Moon, LLC
hospital
-// host : 2014-04-17 DotHost Inc.
+// host : 2014-04-17 Radix FZC
host
// hosting : 2014-05-29 UNR Corp.
@@ -8640,9 +8652,6 @@ itau
// itv : 2015-07-09 ITV Services Limited
itv
-// iveco : 2015-09-03 CNH Industrial N.V.
-iveco
-
// jaguar : 2014-11-13 Jaguar Land Rover Ltd
jaguar
@@ -8715,6 +8724,9 @@ kfh
// kia : 2015-07-09 KIA MOTORS CORPORATION
kia
+// kids : 2021-08-13 DotKids Foundation Limited
+kids
+
// kim : 2013-09-23 Afilias Limited
kim
@@ -8793,7 +8805,7 @@ latino
// latrobe : 2014-06-16 La Trobe University
latrobe
-// law : 2015-01-22 LW TLD Limited
+// law : 2015-01-22 Registry Services, LLC
law
// lawyer : 2014-03-20 Dog Beach, LLC
@@ -8922,10 +8934,7 @@ ltda
// lundbeck : 2015-08-06 H. Lundbeck A/S
lundbeck
-// lupin : 2014-11-07 LUPIN LIMITED
-lupin
-
-// luxe : 2014-01-09 Minds + Machines Group Limited
+// luxe : 2014-01-09 Registry Services, LLC
luxe
// luxury : 2013-10-17 Luxury Partners, LLC
@@ -8964,7 +8973,7 @@ market
// marketing : 2013-11-07 Binky Moon, LLC
marketing
-// markets : 2014-12-11 Dotmarkets Registry Limited
+// markets : 2014-12-11 Dog Beach, LLC
markets
// marriott : 2014-10-09 Marriott Worldwide Corporation
@@ -9093,6 +9102,9 @@ mtn
// mtr : 2015-03-12 MTR Corporation Limited
mtr
+// music : 2021-05-04 DotMusic Limited
+music
+
// mutual : 2015-04-02 Northwestern Mutual MU TLD Registry, LLC
mutual
@@ -9102,9 +9114,6 @@ nab
// nagoya : 2013-10-24 GMO Registry, Inc.
nagoya
-// nationwide : 2015-07-23 Nationwide Mutual Insurance Company
-nationwide
-
// natura : 2015-03-12 NATURA COSMÉTICOS S.A.
natura
@@ -9132,9 +9141,6 @@ neustar
// new : 2014-01-30 Charleston Road Registry Inc.
new
-// newholland : 2015-09-03 CNH Industrial N.V.
-newholland
-
// news : 2014-12-18 Dog Beach, LLC
news
@@ -9207,7 +9213,7 @@ nyc
// obi : 2014-09-25 OBI Group Holding SE & Co. KGaA
obi
-// observer : 2015-04-30 Top Level Spectrum, Inc.
+// observer : 2015-04-30 Dog Beach, LLC
observer
// off : 2015-07-23 Johnson Shareholdings, Inc.
@@ -9243,12 +9249,9 @@ ong
// onl : 2013-09-16 iRegistry GmbH
onl
-// online : 2015-01-15 DotOnline Inc.
+// online : 2015-01-15 Radix FZC
online
-// onyourside : 2015-07-23 Nationwide Mutual Insurance Company
-onyourside
-
// ooo : 2014-01-09 INFIBEAM AVENUES LIMITED
ooo
@@ -9402,7 +9405,7 @@ pramerica
// praxi : 2013-12-05 Praxi S.p.A.
praxi
-// press : 2014-04-03 DotPress Inc.
+// press : 2014-04-03 Radix FZC
press
// prime : 2015-06-25 Amazon Registry Services, Inc.
@@ -9453,9 +9456,6 @@ quebec
// quest : 2015-03-26 XYZ.COM LLC
quest
-// qvc : 2015-07-30 QVC, Inc.
-qvc
-
// racing : 2014-12-04 Premier Registry Limited
racing
@@ -9474,7 +9474,7 @@ realestate
// realtor : 2014-05-29 Real Estate Domains LLC
realtor
-// realty : 2015-03-19 Fegistry, LLC
+// realty : 2015-03-19 Dog Beach, LLC
realty
// recipes : 2013-10-17 Binky Moon, LLC
@@ -9555,16 +9555,13 @@ rio
// rip : 2014-07-10 Dog Beach, LLC
rip
-// rmit : 2015-11-19 Royal Melbourne Institute of Technology
-rmit
-
// rocher : 2014-12-18 Ferrero Trading Lux S.A.
rocher
// rocks : 2013-11-14 Dog Beach, LLC
rocks
-// rodeo : 2013-12-19 Minds + Machines Group Limited
+// rodeo : 2013-12-19 Registry Services, LLC
rodeo
// rogers : 2015-08-06 Rogers Communications Canada Inc.
@@ -9642,7 +9639,7 @@ saxo
// sbi : 2015-03-12 STATE BANK OF INDIA
sbi
-// sbs : 2014-11-07 SPECIAL BROADCASTING SERVICE CORPORATION
+// sbs : 2014-11-07 ShortDot SA
sbs
// sca : 2014-03-13 SVENSKA CELLULOSA AKTIEBOLAGET SCA (publ)
@@ -9765,7 +9762,7 @@ sina
// singles : 2013-08-27 Binky Moon, LLC
singles
-// site : 2015-01-15 DotSite Inc.
+// site : 2015-01-15 Radix FZC
site
// ski : 2015-04-09 Afilias Limited
@@ -9825,7 +9822,7 @@ soy
// spa : 2019-09-19 Asia Spa and Wellness Promotion Council Limited
spa
-// space : 2014-04-03 DotSpace Inc.
+// space : 2014-04-03 Radix FZC
space
// sport : 2017-11-16 Global Association of International Sports Federations (GAISF)
@@ -9834,9 +9831,6 @@ sport
// spot : 2015-02-26 Amazon Registry Services, Inc.
spot
-// spreadbetting : 2014-12-11 Dotspreadbetting Registry Limited
-spreadbetting
-
// srl : 2015-05-07 InterNetX, Corp
srl
@@ -9867,7 +9861,7 @@ stockholm
// storage : 2014-12-22 XYZ.COM LLC
storage
-// store : 2015-04-09 DotStore Inc.
+// store : 2015-04-09 Radix FZC
store
// stream : 2016-01-08 dot Stream Limited
@@ -9894,7 +9888,7 @@ supply
// support : 2013-10-24 Binky Moon, LLC
support
-// surf : 2014-01-09 Minds + Machines Group Limited
+// surf : 2014-01-09 Registry Services, LLC
surf
// surgery : 2014-03-20 Binky Moon, LLC
@@ -9906,9 +9900,6 @@ suzuki
// swatch : 2015-01-08 The Swatch Group Ltd
swatch
-// swiftcover : 2015-07-23 Swiftcover Insurance Services Limited
-swiftcover
-
// swiss : 2014-10-16 Swiss Confederation
swiss
@@ -9957,7 +9948,7 @@ tdk
// team : 2015-03-05 Binky Moon, LLC
team
-// tech : 2015-01-30 Personals TLD Inc.
+// tech : 2015-01-30 Radix FZC
tech
// technology : 2013-09-13 Binky Moon, LLC
@@ -9984,7 +9975,7 @@ theatre
// tiaa : 2015-07-23 Teachers Insurance and Annuity Association of America
tiaa
-// tickets : 2015-02-05 Accent Media Limited
+// tickets : 2015-02-05 XYZ.COM LLC
tickets
// tienda : 2013-11-14 Binky Moon, LLC
@@ -10050,7 +10041,7 @@ toys
// trade : 2014-01-23 Elite Registry Limited
trade
-// trading : 2014-12-11 Dottrading Registry Limited
+// trading : 2014-12-11 Dog Beach, LLC
trading
// training : 2013-11-07 Binky Moon, LLC
@@ -10101,7 +10092,7 @@ unicom
// university : 2014-03-06 Binky Moon, LLC
university
-// uno : 2013-09-11 DotSite Inc.
+// uno : 2013-09-11 Radix FZC
uno
// uol : 2014-05-01 UBN INTERNET LTDA.
@@ -10152,7 +10143,7 @@ villas
// vin : 2015-06-18 Binky Moon, LLC
vin
-// vip : 2015-01-22 Minds + Machines Group Limited
+// vip : 2015-01-22 Registry Services, LLC
vip
// virgin : 2014-09-25 Virgin Enterprises Limited
@@ -10173,7 +10164,7 @@ vivo
// vlaanderen : 2014-02-06 DNS.be vzw
vlaanderen
-// vodka : 2013-12-19 Minds + Machines Group Limited
+// vodka : 2013-12-19 Registry Services, LLC
vodka
// volkswagen : 2015-05-14 Volkswagen Group of America Inc.
@@ -10215,7 +10206,7 @@ wanggou
// watch : 2013-11-14 Binky Moon, LLC
watch
-// watches : 2014-12-22 Richemont DNS Inc.
+// watches : 2014-12-22 Afilias Limited
watches
// weather : 2015-01-08 International Business Machines Corporation
@@ -10230,10 +10221,10 @@ webcam
// weber : 2015-06-04 Saint-Gobain Weber SA
weber
-// website : 2014-04-03 DotWebsite Inc.
+// website : 2014-04-03 Radix FZC
website
-// wedding : 2014-04-24 Minds + Machines Group Limited
+// wedding : 2014-04-24 Registry Services, LLC
wedding
// weibo : 2015-03-05 Sina Corporation
@@ -10275,7 +10266,7 @@ wolterskluwer
// woodside : 2015-07-09 Woodside Petroleum Limited
woodside
-// work : 2013-12-19 Minds + Machines Group Limited
+// work : 2013-12-19 Registry Services, LLC
work
// works : 2013-11-14 Binky Moon, LLC
@@ -10326,9 +10317,6 @@ xin
// xn--3ds443g : 2013-09-08 TLD REGISTRY LIMITED OY
在线
-// xn--3oq18vl8pn36a : 2015-07-02 Volkswagen (China) Investment Co., Ltd.
-大众汽车
-
// xn--3pxu8k : 2015-01-15 VeriSign Sarl
点看
@@ -10338,7 +10326,7 @@ xin
// xn--45q11c : 2013-11-21 Zodiac Gemini Ltd
八卦
-// xn--4gbrim : 2013-10-04 Fans TLD Limited
+// xn--4gbrim : 2013-10-04 Helium TLDs Ltd
موقع
// xn--55qw42g : 2013-11-08 China Organizational Name Administration Center
@@ -10593,7 +10581,7 @@ xyz
// yachts : 2014-01-09 XYZ.COM LLC
yachts
-// yahoo : 2015-04-02 Yahoo! Domain Services Inc.
+// yahoo : 2015-04-02 Oath Inc.
yahoo
// yamaxun : 2014-12-18 Amazon Registry Services, Inc.
@@ -10605,7 +10593,7 @@ yandex
// yodobashi : 2014-11-20 YODOBASHI CAMERA CO.,LTD.
yodobashi
-// yoga : 2014-05-29 Minds + Machines Group Limited
+// yoga : 2014-05-29 Registry Services, LLC
yoga
// yokohama : 2013-12-12 GMO Registry, Inc.
@@ -10652,11 +10640,22 @@ ltd.ua
// 611coin : https://611project.org/
611.to
+// Aaron Marais' Gitlab pages: https://lab.aaronleem.co.za
+// Submitted by Aaron Marais <its_me@aaronleem.co.za>
+graphox.us
+
+// accesso Technology Group, plc. : https://accesso.com/
+// Submitted by accesso Team <accessoecommerce@accesso.com>
+*.devcdnaccesso.com
+
// Adobe : https://www.adobe.com/
-// Submitted by Ian Boston <boston@adobe.com>
+// Submitted by Ian Boston <boston@adobe.com> and Lars Trieloff <trieloff@adobe.com>
adobeaemcloud.com
-adobeaemcloud.net
*.dev.adobeaemcloud.com
+hlx.live
+adobeaemcloud.net
+hlx.page
+hlx3.page
// Agnat sp. z o.o. : https://domena.pl
// Submitted by Przemyslaw Plewa <it-admin@domena.pl>
@@ -10722,6 +10721,10 @@ us-west-2.elasticbeanstalk.com
*.elb.amazonaws.com
*.elb.amazonaws.com.cn
+// Amazon Global Accelerator : https://aws.amazon.com/global-accelerator/
+// Submitted by Daniel Massaguer <psl-maintainers@amazon.com>
+awsglobalaccelerator.com
+
// Amazon S3 : https://aws.amazon.com/s3/
// Submitted by Luke Wells <psl-maintainers@amazon.com>
s3.amazonaws.com
@@ -10779,10 +10782,6 @@ s3-website.eu-west-2.amazonaws.com
s3-website.eu-west-3.amazonaws.com
s3-website.us-east-2.amazonaws.com
-// Amsterdam Wireless: https://www.amsterdamwireless.nl/
-// Submitted by Imre Jonk <hostmaster@amsterdamwireless.nl>
-amsw.nl
-
// Amune : https://amune.org/
// Submitted by Team Amune <cert@amune.org>
t3l3p0rt.net
@@ -10792,6 +10791,19 @@ tele.amune.org
// Submitted by Apigee Security Team <security@apigee.com>
apigee.io
+// Apphud : https://apphud.com
+// Submitted by Alexander Selivanov <alex@apphud.com>
+siiites.com
+
+// Appspace : https://www.appspace.com
+// Submitted by Appspace Security Team <security@appspace.com>
+appspacehosted.com
+appspaceusercontent.com
+
+// Appudo UG (haftungsbeschränkt) : https://www.appudo.com
+// Submitted by Alexander Hochbaum <admin@appudo.com>
+appudo.net
+
// Aptible : https://www.aptible.com/
// Submitted by Thomas Orozco <thomas@aptible.com>
on-aptible.com
@@ -10817,15 +10829,27 @@ sweetpepper.org
// Submitted by Vincent Tseng <vincenttseng@asustor.com>
myasustor.com
+// Atlassian : https://atlassian.com
+// Submitted by Sam Smyth <devloop@atlassian.com>
+cdn.prod.atlassian-dev.net
+
// AVM : https://avm.de
// Submitted by Andreas Weise <a.weise@avm.de>
myfritz.net
+// AVStack Pte. Ltd. : https://avstack.io
+// Submitted by Jasper Hugo <jasper@avstack.io>
+onavstack.net
+
// AW AdvisorWebsites.com Software Inc : https://advisorwebsites.com
// Submitted by James Kennedy <domains@advisorwebsites.com>
*.awdev.ca
*.advisor.ws
+// AZ.pl sp. z.o.o: https://az.pl
+// Submited by Krzysztof Wolski <krzysztof.wolski@home.eu>
+ecommerce-shop.pl
+
// b-data GmbH : https://www.b-data.io
// Submitted by Olivier Benz <olivier.benz@b-data.ch>
b-data.io
@@ -10838,6 +10862,11 @@ backplaneapp.io
// Submitted by Petros Angelatos <petrosagg@balena.io>
balena-devices.com
+// University of Banja Luka : https://unibl.org
+// Domains for Republic of Srpska administrative entity.
+// Submitted by Marko Ivanovic <kormang@hotmail.rs>
+rs.ba
+
// Banzai Cloud
// Submitted by Janos Matyas <info@banzaicloud.com>
*.banzai.cloud
@@ -10853,6 +10882,10 @@ betainabox.com
// Submitted by Nathan O'Sullivan <nathan@mammoth.com.au>
bnr.la
+// Bitbucket : http://bitbucket.org
+// Submitted by Andy Ortlieb <aortlieb@atlassian.com>
+bitbucket.io
+
// Blackbaud, Inc. : https://www.blackbaud.com
// Submitted by Paul Crowder <paul.crowder@blackbaud.com>
blackbaudcdn.net
@@ -10861,10 +10894,18 @@ blackbaudcdn.net
// Submitted by Luke Bratch <luke@bratch.co.uk>
of.je
+// Blue Bite, LLC : https://bluebite.com
+// Submitted by Joshua Weiss <admin.engineering@bluebite.com>
+bluebite.io
+
// Boomla : https://boomla.com
// Submitted by Tibor Halter <thalter@boomla.com>
boomla.net
+// Boutir : https://www.boutir.com
+// Submitted by Eric Ng Ka Ka <ngkaka@boutir.com>
+boutir.com
+
// Boxfuse : https://boxfuse.com
// Submitted by Axel Fontaine <axel@boxfuse.com>
boxfuse.io
@@ -10878,6 +10919,10 @@ square7.de
bplaced.net
square7.net
+// Brendly : https://brendly.rs
+// Submitted by Dusan Radovanovic <dusan.radovanovic@brendly.rs>
+shop.brendly.rs
+
// BrowserSafetyMark
// Submitted by Dave Tharp <browsersafetymark.io@quicinc.com>
browsersafetymark.io
@@ -10888,15 +10933,21 @@ uk0.bigv.io
dh.bytemark.co.uk
vm.bytemark.co.uk
+// Caf.js Labs LLC : https://www.cafjs.com
+// Submitted by Antonio Lain <antlai@cafjs.com>
+cafjs.com
+
// callidomus : https://www.callidomus.com/
// Submitted by Marcus Popp <admin@callidomus.com>
mycd.eu
// Carrd : https://carrd.co
// Submitted by AJ <aj@carrd.co>
+drr.ac
+uwu.ai
carrd.co
crd.co
-uwu.ai
+ju.mp
// CentralNic : http://www.centralnic.com/names/domains
// Submitted by registry <gavin.brown@centralnic.com>
@@ -10924,7 +10975,6 @@ za.com
// No longer operated by CentralNic, these entries should be adopted and/or removed by current operators
// Submitted by Gavin Brown <gavin.brown@centralnic.com>
ar.com
-gb.com
hu.com
kr.com
no.com
@@ -10962,11 +11012,6 @@ nz.basketball
radio.am
radio.fm
-// Globe Hosting SRL : https://www.globehosting.com/
-// Submitted by Gavin Brown <gavin.brown@centralnic.com>
-co.ro
-shop.ro
-
// c.la : http://www.c.la/
c.la
@@ -10974,27 +11019,31 @@ c.la
// Submitted by B. Blechschmidt <hostmaster@certmgr.org>
certmgr.org
+// Cityhost LLC : https://cityhost.ua
+// Submitted by Maksym Rivtin <support@cityhost.net.ua>
+cx.ua
+
// Civilized Discourse Construction Kit, Inc. : https://www.discourse.org/
// Submitted by Rishabh Nambiar & Michael Brown <team@discourse.org>
discourse.group
discourse.team
-// ClearVox : http://www.clearvox.nl/
-// Submitted by Leon Rowland <leon@clearvox.nl>
-virtueeldomein.nl
-
// Clever Cloud : https://www.clever-cloud.com/
// Submitted by Quentin Adam <noc@clever-cloud.com>
cleverapps.io
// Clerk : https://www.clerk.dev
-// Submitted by Colin Sidoti <colin@clerk.dev>
+// Submitted by Colin Sidoti <systems@clerk.dev>
+clerk.app
+clerkstage.app
*.lcl.dev
+*.lclstage.dev
*.stg.dev
+*.stgstage.dev
-// Clic2000 : https://clic2000.fr
-// Submitted by Mathilde Blanchemanche <mathilde@clic2000.fr>
-clic2000.net
+// ClickRising : https://clickrising.com/
+// Submitted by Umut Gumeli <infrastructure-publicsuffixlist@clickrising.com>
+clickrising.net
// Cloud66 : https://www.cloud66.com/
// Submitted by Khash Sajadi <khash@cloud66.com>
@@ -11016,8 +11065,8 @@ cloudcontrolled.com
cloudcontrolapp.com
// Cloudera, Inc. : https://www.cloudera.com/
-// Submitted by Philip Langdale <security@cloudera.com>
-cloudera.site
+// Submitted by Kedarnath Waikar <security@cloudera.com>
+*.cloudera.site
// Cloudflare, Inc. : https://www.cloudflare.com/
// Submitted by Cloudflare Team <publicsuffixlist@cloudflare.com>
@@ -11166,18 +11215,37 @@ dyndns.dappnode.io
// Submitted by Paul Biggar <ops@darklang.com>
builtwithdark.com
+// DataDetect, LLC. : https://datadetect.com
+// Submitted by Andrew Banchich <abanchich@sceven.com>
+demo.datadetect.com
+instance.datadetect.com
+
// Datawire, Inc : https://www.datawire.io
// Submitted by Richard Li <secalert@datawire.io>
edgestack.me
+// DDNS5 : https://ddns5.com
+// Submitted by Cameron Elliott <cameron@cameronelliott.com>
+ddns5.com
+
// Debian : https://www.debian.org/
// Submitted by Peter Palfrader / Debian Sysadmin Team <dsa-publicsuffixlist@debian.org>
debian.net
+// Deno Land Inc : https://deno.com/
+// Submitted by Luca Casonato <hostmaster@deno.com>
+deno.dev
+deno-staging.dev
+
// deSEC : https://desec.io/
// Submitted by Peter Thomassen <peter@desec.io>
dedyn.io
+// Diher Solutions : https://diher.solutions
+// Submitted by Didi Hermawan <mail@diher.solutions>
+*.rss.my.id
+*.diher.solutions
+
// DNS Africa Ltd https://dns.business
// Submitted by Calvin Browne <calvin@dns.business>
jozi.biz
@@ -11195,6 +11263,10 @@ shop.th
// Submitted by Paul Fang <mis@draytek.com>
drayddns.com
+// DreamCommerce : https://shoper.pl/
+// Submitted by Konrad Kotarba <konrad.kotarba@dreamcommerce.com>
+shoparena.pl
+
// DreamHost : http://www.dreamhost.com/
// Submitted by Andrew Farmer <andrew.farmer@dreamhost.com>
dreamhosters.com
@@ -11522,10 +11594,14 @@ ddnss.org
definima.net
definima.io
-// DigitalOcean : https://digitalocean.com/
-// Submitted by Braxton Huggins <bhuggins@digitalocean.com>
+// DigitalOcean App Platform : https://www.digitalocean.com/products/app-platform/
+// Submitted by Braxton Huggins <psl-maintainers@digitalocean.com>
ondigitalocean.app
+// DigitalOcean Spaces : https://www.digitalocean.com/products/spaces/
+// Submitted by Robin H. Johnson <psl-maintainers@digitalocean.com>
+*.digitaloceanspaces.com
+
// dnstrace.pro : https://dnstrace.pro/
// Submitted by Chris Partridge <chris@partridge.tech>
bci.dnstrace.pro
@@ -11558,6 +11634,16 @@ dynv6.net
// Submitted by Vladimir Dudr <info@e4you.cz>
e4.cz
+// eero : https://eero.com/
+// Submitted by Yue Kang <eero-dynamic-dns@amazon.com>
+eero.online
+eero-stage.online
+
+// Elementor : Elementor Ltd.
+// Submitted by Anton Barkan <antonb@elementor.com>
+elementor.cloud
+elementor.cool
+
// En root‽ : https://en-root.org
// Submitted by Emmanuel Raviart <emmanuel@raviart.com>
en-root.fr
@@ -11565,21 +11651,13 @@ en-root.fr
// Enalean SAS: https://www.enalean.com
// Submitted by Thomas Cottier <thomas.cottier@enalean.com>
mytuleap.com
+tuleap-partners.com
// ECG Robotics, Inc: https://ecgrobotics.org
// Submitted by <frc1533@ecgrobotics.org>
onred.one
staging.onred.one
-// One.com: https://www.one.com/
-// Submitted by Jacob Bunk Nielsen <jbn@one.com>
-service.one
-
-// Enonic : http://enonic.com/
-// Submitted by Erik Kaareng-Sunde <esu@enonic.com>
-enonic.io
-customer.enonic.io
-
// EU.org https://eu.org/
// Submitted by Pierre Beyssac <hostmaster@eu.org>
eu.org
@@ -11639,6 +11717,10 @@ tr.eu.org
uk.eu.org
us.eu.org
+// Eurobyte : https://eurobyte.ru
+// Submitted by Evgeniy Subbotin <e.subbotin@eurobyte.ru>
+eurodir.ru
+
// Evennode : http://www.evennode.com/
// Submitted by Michal Kralik <support@evennode.com>
eu-1.evennode.com
@@ -11749,6 +11831,7 @@ u.channelsdvr.net
// Fastly Inc. : http://www.fastly.com/
// Submitted by Fastly Security <security@fastly.com>
+edgecompute.app
fastly-terrarium.com
fastlylb.net
map.fastlylb.net
@@ -11768,10 +11851,6 @@ myfast.host
fastvps.site
myfast.space
-// Featherhead : https://featherhead.xyz/
-// Submitted by Simon Menke <simon@featherhead.xyz>
-fhapp.xyz
-
// Fedora : https://fedoraproject.org/
// submitted by Patrick Uiterwijk <puiterwijk@fedoraproject.org>
fedorainfracloud.org
@@ -11782,10 +11861,11 @@ app.os.stg.fedoraproject.org
// FearWorks Media Ltd. : https://fearworksmedia.co.uk
// submitted by Keith Fairley <domains@fearworksmedia.co.uk>
-conn.uk
-copro.uk
couk.me
ukco.me
+conn.uk
+copro.uk
+hosp.uk
// Fermax : https://fermax.com/
// submitted by Koen Van Isterdael <k.vanisterdael@fermax.be>
@@ -11809,6 +11889,19 @@ filegear-sg.me
// Submitted by Chris Raynor <chris@firebase.com>
firebaseapp.com
+// Firewebkit : https://www.firewebkit.com
+// Submitted by Majid Qureshi <mqureshi@amrayn.com>
+fireweb.app
+
+// FLAP : https://www.flap.cloud
+// Submitted by Louis Chemineau <louis@chmn.me>
+flap.id
+
+// FlashDrive : https://flashdrive.io
+// Submitted by Eric Chan <support@flashdrive.io>
+onflashdrive.app
+fldrv.com
+
// fly.io: https://fly.io
// Submitted by Kurt Mackey <kurt@fly.io>
fly.dev
@@ -11819,6 +11912,24 @@ shw.io
// Submitted by Jonathan Rudenberg <jonathan@flynn.io>
flynnhosting.net
+// Forgerock : https://www.forgerock.com
+// Submitted by Roderick Parr <roderick.parr@forgerock.com>
+forgeblocks.com
+id.forgerock.io
+
+// Framer : https://www.framer.com
+// Submitted by Koen Rouwhorst <koenrh@framer.com>
+framer.app
+framercanvas.com
+
+// Frusky MEDIA&PR : https://www.frusky.de
+// Submitted by Victor Pupynin <hallo@frusky.de>
+*.frusky.de
+
+// RavPage : https://www.ravpage.co.il
+// Submitted by Roni Horowitz <roni@responder.co.il>
+ravpage.co.il
+
// Frederik Braun https://frederik-braun.com
// Submitted by Frederik Braun <fb@frederik-braun.com>
0e.vc
@@ -11836,6 +11947,10 @@ freeboxos.fr
// Submitted by Daniel Stone <daniel@fooishbar.org>
freedesktop.org
+// freemyip.com : https://freemyip.com
+// Submitted by Cadence <contact@freemyip.com>
+freemyip.com
+
// FunkFeuer - Verein zur Förderung freier Netze : https://www.funkfeuer.at
// Submitted by Daniel A. Maierhofer <vorstand@funkfeuer.at>
wien.funkfeuer.at
@@ -11867,10 +11982,19 @@ gentlentapis.com
lab.ms
cdn-edges.net
+// Ghost Foundation : https://ghost.org
+// Submitted by Matt Hanley <security@ghost.org>
+ghost.io
+
+// GignoSystemJapan: http://gsj.bz
+// Submitted by GignoSystemJapan <kakutou-ec@gsj.bz>
+gsj.bz
+
// GitHub, Inc.
// Submitted by Patrick Toomey <security@github.com>
-github.io
githubusercontent.com
+githubpreview.dev
+github.io
// GitLab, Inc.
// Submitted by Alex Hanselka <alex@gitlab.com>
@@ -11885,12 +12009,21 @@ gitpage.si
// Submitted by Mads Hartmann <mads@glitch.com>
glitch.me
+// Global NOG Alliance : https://nogalliance.org/
+// Submitted by Sander Steffann <sander@nogalliance.org>
+nog.community
+
+// Globe Hosting SRL : https://www.globehosting.com/
+// Submitted by Gavin Brown <gavin.brown@centralnic.com>
+co.ro
+shop.ro
+
// GMO Pepabo, Inc. : https://pepabo.com/
// Submitted by dojineko <admin@pepabo.com>
lolipop.io
// GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/
-// Submitted by Tom Whitwell <tom.whitwell@digital.cabinet-office.gov.uk>
+// Submitted by Tom Whitwell <gov-uk-paas-support@digital.cabinet-office.gov.uk>
cloudapps.digital
london.cloudapps.digital
@@ -11928,8 +12061,8 @@ withyoutube.com
*.gateway.dev
cloud.goog
translate.goog
+*.usercontent.goog
cloudfunctions.net
-
blogspot.ae
blogspot.al
blogspot.am
@@ -12005,14 +12138,19 @@ blogspot.tw
blogspot.ug
blogspot.vn
-// Aaron Marais' Gitlab pages: https://lab.aaronleem.co.za
-// Submitted by Aaron Marais <its_me@aaronleem.co.za>
-graphox.us
+// Goupile : https://goupile.fr
+// Submitted by Niels Martignene <hello@goupile.fr>
+goupile.fr
// Group 53, LLC : https://www.group53.com
// Submitted by Tyler Todd <noc@nova53.net>
awsmppl.com
+// GünstigBestellen : https://günstigbestellen.de
+// Submitted by Furkan Akkoc <info@hendelzon.de>
+günstigbestellen.de
+günstigliefern.de
+
// Hakaran group: http://hakaran.cz
// Submited by Arseniy Sokolov <security@hakaran.cz>
fin.ci
@@ -12034,6 +12172,10 @@ hashbang.sh
hasura.app
hasura-app.io
+// Heilbronn University of Applied Sciences - Faculty Informatics (GitLab Pages): https://www.hs-heilbronn.de
+// Submitted by Richard Zowalla <mi-admin@hs-heilbronn.de>
+pages.it.hs-heilbronn.de
+
// Hepforge : https://www.hepforge.org
// Submitted by David Grellscheid <admin@hepforge.org>
hepforge.org
@@ -12051,24 +12193,26 @@ ravendb.me
development.run
ravendb.run
+// home.pl S.A.: https://home.pl
+// Submited by Krzysztof Wolski <krzysztof.wolski@home.eu>
+homesklep.pl
+
// Hong Kong Productivity Council: https://www.hkpc.org/
// Submitted by SECaaS Team <summchan@hkpc.org>
secaas.hk
// HOSTBIP REGISTRY : https://www.hostbip.com/
// Submitted by Atanunu Igbunuroghene <publicsuffixlist@hostbip.com>
-bpl.biz
orx.biz
-ng.city
biz.gl
-ng.ink
col.ng
firm.ng
gen.ng
ltd.ng
ngo.ng
-ng.school
+edu.scot
sch.so
+org.yt
// HostyHosting (hostyhosting.com)
hostyhosting.io
@@ -12086,6 +12230,19 @@ moonscale.net
// Submitted by Hannu Aronsson <haa@iki.fi>
iki.fi
+// Impertrix Solutions : <https://impertrixcdn.com>
+// Submitted by Zhixiang Zhao <csuite@impertrix.com>
+impertrixcdn.com
+impertrix.com
+
+// Incsub, LLC: https://incsub.com/
+// Submitted by Aaron Edwards <sysadmins@incsub.com>
+smushcdn.com
+wphostedmail.com
+wpmucdn.com
+tempurl.host
+wpmudev.host
+
// Individual Network Berlin e.V. : https://www.in-berlin.de/
// Submitted by Christian Seitz <chris@in-berlin.de>
dyn-berlin.de
@@ -12178,7 +12335,8 @@ vip.jelastic.cloud
jele.cloud
it1.eur.aruba.jenv-aruba.cloud
it1.jenv-aruba.cloud
-it1-eur.jenv-arubabiz.cloud
+keliweb.cloud
+cs.keliweb.cloud
oxa.cloud
tn.oxa.cloud
uk.oxa.cloud
@@ -12190,13 +12348,9 @@ us.reclaim.cloud
ch.trendhosting.cloud
de.trendhosting.cloud
jele.club
+amscompute.com
clicketcloud.com
-ams.cloudswitches.com
-au.cloudswitches.com
-sg.cloudswitches.com
dopaas.com
-elastyco.com
-nv.elastyco.com
hidora.com
paas.hosted-by-previder.com
rag-cloud.hosteur.com
@@ -12211,29 +12365,26 @@ lon.wafaicloud.com
ryd.wafaicloud.com
j.scaleforce.com.cy
jelastic.dogado.eu
-paas.leviracloud.eu
fi.cloudplatform.fi
demo.datacenter.fi
paas.datacenter.fi
jele.host
mircloud.host
+paas.beebyte.io
+sekd1.beebyteapp.io
jele.io
-ocs.opusinteractive.io
-cloud.unispace.io
-cloud-de.unispace.io
cloud-fr1.unispace.io
jc.neen.it
cloud.jelastic.open.tim.it
jcloud.kz
upaas.kazteleport.kz
-jl.serv.net.mx
cloudjiffy.net
fra1-de.cloudjiffy.net
west1-us.cloudjiffy.net
-ams1.jls.docktera.net
jls-sto1.elastx.net
jls-sto2.elastx.net
jls-sto3.elastx.net
+faststacks.net
fr-1.paas.massivegrid.net
lon-1.paas.massivegrid.net
lon-2.paas.massivegrid.net
@@ -12244,8 +12395,7 @@ jelastic.saveincloud.net
nordeste-idc.saveincloud.net
j.scaleforce.net
jelastic.tsukaeru.net
-atl.jelastic.vps-host.net
-njs.jelastic.vps-host.net
+sdscloud.pl
unicloud.pl
mircloud.ru
jelastic.regruhosting.ru
@@ -12265,6 +12415,10 @@ myjino.ru
*.spectrum.myjino.ru
*.vps.myjino.ru
+// Jotelulu S.L. : https://jotelulu.com
+// Submitted by Daniel Fariña <ingenieria@jotelulu.com>
+jotelulu.cloud
+
// Joyent : https://www.joyent.com/
// Submitted by Brian Bennett <brian.bennett@joyent.com>
*.triton.zone
@@ -12296,10 +12450,20 @@ knightpoint.systems
// Submitted by DisposaBoy <security@oya.to>
oya.to
+// Katholieke Universiteit Leuven: https://www.kuleuven.be
+// Submitted by Abuse KU Leuven <abuse@kuleuven.be>
+kuleuven.cloud
+ezproxy.kuleuven.be
+
// .KRD : http://nic.krd/data/krd/Registration%20Policy.pdf
co.krd
edu.krd
+// Krellian Ltd. : https://krellian.com
+// Submitted by Ben Francis <ben@krellian.com>
+krellian.net
+webthings.io
+
// LCube - Professional hosting e.K. : https://www.lcube-webhosting.de
// Submitted by Lars Laehn <info@lcube.de>
git-repos.de
@@ -12340,6 +12504,7 @@ linkyard-cloud.ch
members.linode.com
*.nodebalancer.linode.com
*.linodeobjects.com
+ip.linodeusercontent.com
// LiquidNet Ltd : http://www.liquidnetlimited.com/
// Submitted by Victor Velchev <admin@liquidnetlimited.com>
@@ -12357,6 +12522,14 @@ loginline.io
loginline.services
loginline.site
+// Lokalized : https://lokalized.nl
+// Submitted by Noah Taheij <noah@lokalized.nl>
+servers.run
+
+// Lõhmus Family, The
+// Submitted by Heiki Lõhmus <hostmaster at lohmus dot me>
+lohmus.me
+
// LubMAN UMCS Sp. z o.o : https://lubman.pl/
// Submitted by Ireneusz Maliszewski <ireneusz.maliszewski@lubman.pl>
krasnik.pl
@@ -12393,6 +12566,7 @@ barsy.online
barsy.org
barsy.pro
barsy.pub
+barsy.ro
barsy.shop
barsy.site
barsy.support
@@ -12411,15 +12585,34 @@ mayfirst.org
// Submitted by Ilya Zaretskiy <zaretskiy@corp.mail.ru>
hb.cldmail.ru
+// Mail Transfer Platform : https://www.neupeer.com
+// Submitted by Li Hui <lihui@neupeer.com>
+cn.vu
+
+// Maze Play: https://www.mazeplay.com
+// Submitted by Adam Humpherys <adam@mws.dev>
+mazeplay.com
+
// mcpe.me : https://mcpe.me
// Submitted by Noa Heyl <hi@noa.dev>
mcpe.me
// McHost : https://mchost.ru
// Submitted by Evgeniy Subbotin <e.subbotin@mchost.ru>
+mcdir.me
mcdir.ru
+mcpre.ru
vps.mcdir.ru
+// Mediatech : https://mediatech.by
+// Submitted by Evgeniy Kozhuhovskiy <ugenk@mediatech.by>
+mediatech.by
+mediatech.dev
+
+// Medicom Health : https://medicomhealth.com
+// Submitted by Michael Olson <molson@medicomhealth.com>
+hra.health
+
// Memset hosting : https://www.memset.com
// Submitted by Tom Whitwell <domains@memset.com>
miniserver.com
@@ -12460,6 +12653,10 @@ westus2.azurestaticapps.net
// Submitted by Robert Böttinger <r@minion.systems>
csx.cc
+// Mintere : https://mintere.com/
+// Submitted by Ben Aubin <security@mintere.com>
+mintere.site
+
// MobileEducation, LLC : https://joinforte.com
// Submitted by Grayson Martin <grayson.martin@mobileeducation.us>
forte.id
@@ -12482,8 +12679,11 @@ pp.ru
// Submitted by Paul Cammish <kelduum@mythic-beasts.com>
hostedpi.com
customer.mythic-beasts.com
+caracal.mythic-beasts.com
+fentiger.mythic-beasts.com
lynx.mythic-beasts.com
ocelot.mythic-beasts.com
+oncilla.mythic-beasts.com
onza.mythic-beasts.com
sphinx.mythic-beasts.com
vs.mythic-beasts.com
@@ -12514,10 +12714,6 @@ that.win
from.work
to.work
-// NCTU.ME : https://nctu.me/
-// Submitted by Tocknicsu <admin@nctu.me>
-nctu.me
-
// Netlify : https://www.netlify.com
// Submitted by Jessica Parsons <jessica@netlify.com>
netlify.app
@@ -12538,6 +12734,20 @@ nh-serv.co.uk
// Submitted by Jeff Wheelhouse <support@nearlyfreespeech.net>
nfshost.com
+// Noop : https://noop.app
+// Submitted by Nathaniel Schweinberg <noop@rearc.io>
+*.developer.app
+noop.app
+
+// Northflank Ltd. : https://northflank.com/
+// Submitted by Marco Suter <marco@northflank.com>
+*.northflank.app
+*.code.run
+
+// Noticeable : https://noticeable.io
+// Submitted by Laurent Pellegrino <security@noticeable.io>
+noticeable.news
+
// Now-DNS : https://now-dns.com
// Submitted by Steve Russell <steve@now-dns.com>
dnsking.ch
@@ -12676,60 +12886,6 @@ pcloud.host
// Submitted by Matthew Brown <mattbrown@nyc.mn>
nyc.mn
-// NymNom : https://nymnom.com/
-// Submitted by NymNom <psl@nymnom.com>
-nom.ae
-nom.af
-nom.ai
-nom.al
-nym.by
-nom.bz
-nym.bz
-nom.cl
-nym.ec
-nom.gd
-nom.ge
-nom.gl
-nym.gr
-nom.gt
-nym.gy
-nym.hk
-nom.hn
-nym.ie
-nom.im
-nom.ke
-nym.kz
-nym.la
-nym.lc
-nom.li
-nym.li
-nym.lt
-nym.lu
-nom.lv
-nym.me
-nom.mk
-nym.mn
-nym.mx
-nom.nu
-nym.nz
-nym.pe
-nym.pt
-nom.pw
-nom.qa
-nym.ro
-nom.rs
-nom.si
-nym.sk
-nom.st
-nym.su
-nym.sx
-nom.tj
-nym.tw
-nom.ug
-nom.uy
-nom.vc
-nom.vg
-
// Observable, Inc. : https://observablehq.com
// Submitted by Mike Bostock <dns@observablehq.com>
static.observableusercontent.com
@@ -12750,6 +12906,10 @@ cloudycluster.net
// Submitted by Vicary Archangel <vicary@omniwe.com>
omniwe.site
+// One.com: https://www.one.com/
+// Submitted by Jacob Bunk Nielsen <jbn@one.com>
+service.one
+
// One Fold Media : http://www.onefoldmedia.com/
// Submitted by Eddie Jones <eddie@onefoldmedia.com>
nid.io
@@ -12762,18 +12922,29 @@ opensocial.site
// Submitted by Sven Marnach <sven@opencraft.com>
opencraft.hosting
+// OpenResearch GmbH: https://openresearch.com/
+// Submitted by Philipp Schmid <ops@openresearch.com>
+orsites.com
+
// Opera Software, A.S.A.
// Submitted by Yngve Pettersen <yngve@opera.com>
operaunite.com
-// Oursky Limited : https://skygear.io/
-// Submited by Skygear Developer <hello@skygear.io>
+// Oursky Limited : https://authgear.com/, https://skygear.io/
+// Submited by Authgear Team <hello@authgear.com>, Skygear Developer <hello@skygear.io>
+authgear-staging.com
+authgearapps.com
skygearapp.com
// OutSystems
// Submitted by Duarte Santos <domain-admin@outsystemscloud.com>
outsystemscloud.com
+// OVHcloud: https://ovhcloud.com
+// Submitted by Vincent Cassé <vincent.casse@ovhcloud.com>
+*.webpaas.ovh.net
+*.hosting.ovh.net
+
// OwnProvider GmbH: http://www.ownprovider.com
// Submitted by Jan Moennich <jan.moennich@ownprovider.com>
ownprovider.com
@@ -12803,6 +12974,10 @@ pagefrontapp.com
// Submitted by Yann Guichard <yann@pagexl.com>
pagexl.com
+// Paywhirl, Inc : https://paywhirl.com/
+// Submitted by Daniel Netzer <dan@paywhirl.com>
+*.paywhirl.com
+
// pcarrier.ca Software Inc: https://pcarrier.ca/
// Submitted by Pierre Carrier <pc@rrier.ca>
bar0.net
@@ -12834,8 +13009,6 @@ perspecta.cloud
// PE Ulyanov Kirill Sergeevich : https://airy.host
// Submitted by Kirill Ulyanov <k.ulyanov@airy.host>
lk3.ru
-ra-ru.ru
-zsew.ru
// Planet-Work : https://www.planet-work.com/
// Submitted by Frédéric VANNIÈRE <f.vanniere@planet-work.com>
@@ -12848,6 +13021,7 @@ ent.platform.sh
eu.platform.sh
us.platform.sh
*.platformsh.site
+*.tst.site
// Platter: https://platter.dev
// Submitted by Patrick Flor <patrick@platter.dev>
@@ -12869,6 +13043,17 @@ dyn53.io
// Submitted by Zulfais <pc@co.bn>
co.bn
+// Postman, Inc : https://postman.com
+// Submitted by Rahul Dhawan <security@postman.com>
+postman-echo.com
+pstmn.io
+mock.pstmn.io
+httpbin.org
+
+//prequalifyme.today : https://prequalifyme.today
+//Submitted by DeepakTiwari deepak@ivylead.io
+prequalifyme.today
+
// prgmr.com : https://prgmr.com/
// Submitted by Sarah Newman <owner@prgmr.com>
xen.prgmr.com
@@ -12898,6 +13083,11 @@ byen.site
// Submitted by Kor Nielsen <kor@pubtls.org>
pubtls.org
+// PythonAnywhere LLP: https://www.pythonanywhere.com
+// Submitted by Giles Thomas <giles@pythonanywhere.com>
+pythonanywhere.com
+eu.pythonanywhere.com
+
// QOTO, Org.
// Submitted by Jeffrey Phillips Freeman <jeffrey.freeman@qoto.org>
qoto.io
@@ -12910,6 +13100,14 @@ qualifioapp.com
// Submitted by Dani Biro <dani@pymet.com>
qbuser.com
+// Rad Web Hosting: https://radwebhosting.com
+// Submitted by Scott Claeys <s.claeys@radwebhosting.com>
+cloudsite.builders
+
+// Redgate Software: https://red-gate.com
+// Submitted by Andrew Farries <andrew.farries@red-gate.com>
+instances.spawn.cc
+
// Redstar Consultants : https://www.redstarconsultants.com/
// Submitted by Jons Slemmer <jons@redstarconsultants.com>
instantcloud.cn
@@ -12973,6 +13171,7 @@ onrender.com
// Repl.it : https://repl.it
// Submitted by Mason Clayton <mason@repl.it>
repl.co
+id.repl.co
repl.run
// Resin.io : https://resin.io
@@ -12989,10 +13188,31 @@ hzc.io
wellbeingzone.eu
wellbeingzone.co.uk
+// Rico Developments Limited : https://adimo.co
+// Submitted by Colin Brown <hello@adimo.co>
+adimo.co.uk
+
+// Riseup Networks : https://riseup.net
+// Submitted by Micah Anderson <micah@riseup.net>
+itcouldbewor.se
+
// Rochester Institute of Technology : http://www.rit.edu/
// Submitted by Jennifer Herting <jchits@rit.edu>
git-pages.rit.edu
+// Rusnames Limited: http://rusnames.ru/
+// Submitted by Sergey Zotov <admin@rusnames.ru>
+биз.рус
+ком.рус
+крым.рус
+мир.рус
+мск.рус
+орг.рус
+самара.рус
+сочи.рус
+спб.рус
+я.рус
+
// Sandstorm Development Group, Inc. : https://sandcats.io/
// Submitted by Asheesh Laroia <asheesh@sandstorm.io>
sandcats.io
@@ -13009,6 +13229,7 @@ schokokeks.net
// Scottish Government: https://www.gov.scot
// Submitted by Martin Ellis <martin.ellis@gov.scot>
gov.scot
+service.gov.scot
// Scry Security : http://www.scrysec.com
// Submitted by Shante Adam <shante@skyhat.io>
@@ -13031,16 +13252,33 @@ spdns.org
// Submitted by Artem Kondratev <accounts@seidat.com>
seidat.net
+// Sellfy : https://sellfy.com
+// Submitted by Yuriy Romadin <contact@sellfy.com>
+sellfy.store
+
// Senseering GmbH : https://www.senseering.de
// Submitted by Felix Mönckemeyer <f.moenckemeyer@senseering.de>
senseering.net
+// Sendmsg: https://www.sendmsg.co.il
+// Submitted by Assaf Stern <domains@comstar.co.il>
+minisite.ms
+
+// Service Magnet : https://myservicemagnet.com
+// Submitted by Dave Sanders <dave@myservicemagnet.com>
+magnet.page
+
// Service Online LLC : http://drs.ua/
// Submitted by Serhii Bulakh <support@drs.ua>
biz.ua
co.ua
pp.ua
+// Shift Crypto AG : https://shiftcrypto.ch
+// Submitted by alex <alex@shiftcrypto.ch>
+shiftcrypto.dev
+shiftcrypto.io
+
// ShiftEdit : https://shiftedit.net/
// Submitted by Adam Jimenez <adam@shiftcreate.com>
shiftedit.io
@@ -13049,6 +13287,10 @@ shiftedit.io
// Submitted by Alex Bowers <alex@shopblocks.com>
myshopblocks.com
+// Shopify : https://www.shopify.com
+// Submitted by Alex Richter <alex.richter@shopify.com>
+myshopify.com
+
// Shopit : https://www.shopitcommerce.com/
// Submitted by Craig McMahon <craig@shopitcommerce.com>
shopitsite.com
@@ -13083,16 +13325,43 @@ beta.bounty-full.com
// Submitted by Aral Balkan <aral@small-tech.org>
small-web.org
+// Smoove.io : https://www.smoove.io/
+// Submitted by Dan Kozak <dan@smoove.io>
+vp4.me
+
+// Snowplow Analytics : https://snowplowanalytics.com/
+// Submitted by Ian Streeter <ian@snowplowanalytics.com>
+try-snowplow.com
+
+// SourceHut : https://sourcehut.org
+// Submitted by Drew DeVault <sir@cmpwn.com>
+srht.site
+
// Stackhero : https://www.stackhero.io
// Submitted by Adrien Gillon <adrien+public-suffix-list@stackhero.io>
stackhero-network.com
+// Staclar : https://staclar.com
+// Submitted by Matthias Merkel <matthias.merkel@staclar.com>
+novecore.site
+
// staticland : https://static.land
// Submitted by Seth Vincent <sethvincent@gmail.com>
static.land
dev.static.land
sites.static.land
+// Storebase : https://www.storebase.io
+// Submitted by Tony Schirmer <tony@storebase.io>
+storebase.store
+
+// Strategic System Consulting (eApps Hosting): https://www.eapps.com/
+// Submitted by Alex Oancea <aoancea@cloudscale365.com>
+vps-host.net
+atl.jelastic.vps-host.net
+njs.jelastic.vps-host.net
+ric.jelastic.vps-host.net
+
// Sony Interactive Entertainment LLC : https://sie.com/
// Submitted by David Coles <david.coles@sony.com>
playstation-cloud.com
@@ -13110,6 +13379,28 @@ spacekit.io
// Submitted by Stefan Neufeind <info@speedpartner.de>
customer.speedpartner.de
+// Spreadshop (sprd.net AG) : https://www.spreadshop.com/
+// Submitted by Martin Breest <security@spreadshop.com>
+myspreadshop.at
+myspreadshop.com.au
+myspreadshop.be
+myspreadshop.ca
+myspreadshop.ch
+myspreadshop.com
+myspreadshop.de
+myspreadshop.dk
+myspreadshop.es
+myspreadshop.fi
+myspreadshop.fr
+myspreadshop.ie
+myspreadshop.it
+myspreadshop.net
+myspreadshop.nl
+myspreadshop.no
+myspreadshop.pl
+myspreadshop.se
+myspreadshop.co.uk
+
// Standard Library : https://stdlib.com
// Submitted by Jacob Lee <jacob@stdlib.com>
api.stdlib.com
@@ -13131,10 +13422,12 @@ user.srcf.net
// Submitted by Dan Miller <dm@sub6.com>
temp-dns.com
-// Swisscom Application Cloud: https://developer.swisscom.com
-// Submitted by Matthias.Winzeler <matthias.winzeler@swisscom.com>
-applicationcloud.io
-scapp.io
+// Supabase : https://supabase.io
+// Submitted by Inian Parameshwaran <security@supabase.io>
+supabase.co
+supabase.in
+supabase.net
+su.paba.se
// Symfony, SAS : https://symfony.com/
// Submitted by Fabien Potencier <fabien@symfony.com>
@@ -13163,10 +13456,19 @@ synology.me
vpnplus.to
direct.quickconnect.to
+// Tabit Technologies Ltd. : https://tabit.cloud/
+// Submitted by Oren Agiv <oren@tabit.cloud>
+tabitorder.co.il
+
// TAIFUN Software AG : http://taifun-software.de
// Submitted by Bjoern Henke <dev-server@taifun-software.de>
taifun-dns.de
+// Tailscale Inc. : https://www.tailscale.com
+// Submitted by David Anderson <danderson@tailscale.com>
+beta.tailscale.net
+ts.net
+
// TASK geographical domains (www.task.gda.pl/uslugi/dns)
gda.pl
gdansk.pl
@@ -13190,13 +13492,21 @@ gwiddle.co.uk
// Thingdust AG : https://thingdust.com/
// Submitted by Adrian Imboden <adi@thingdust.com>
+*.firenet.ch
+*.svc.firenet.ch
+reservd.com
thingdustdata.com
cust.dev.thingdust.io
cust.disrec.thingdust.io
cust.prod.thingdust.io
cust.testing.thingdust.io
-*.firenet.ch
-*.svc.firenet.ch
+reservd.dev.thingdust.io
+reservd.disrec.thingdust.io
+reservd.testing.thingdust.io
+
+// ticket i/O GmbH : https://ticket.io
+// Submitted by Christian Franke <it@ticket.io>
+tickets.io
// Tlon.io : https://tlon.io
// Submitted by Mark Staarink <mark@tlon.io>
@@ -13204,11 +13514,20 @@ arvo.network
azimuth.network
tlon.network
+// Tor Project, Inc. : https://torproject.org
+// Submitted by Antoine Beaupré <anarcat@torproject.org
+torproject.net
+pages.torproject.net
+
// TownNews.com : http://www.townnews.com
// Submitted by Dustin Ward <dward@townnews.com>
bloxcms.com
townnews-staging.com
+// TradableBits: https://tradablebits.com
+// Submitted by Dmitry Khrisanov dmitry@tradablebits.com
+tbits.me
+
// TrafficPlex GmbH : https://www.trafficplex.de/
// Submitted by Phillipp Röll <phillipp.roell@trafficplex.de>
12hp.at
@@ -13274,6 +13593,10 @@ inc.hk
virtualuser.de
virtual-user.de
+// Upli : https://upli.io
+// Submitted by Lenny Bakkalian <lenny.bakkalian@gmail.com>
+upli.io
+
// urown.net : https://urown.net
// Submitted by Hostmaster <hostmaster@urown.net>
urown.cloud
@@ -13336,7 +13659,6 @@ at.md
de.md
jp.md
to.md
-uwu.nu
indie.porn
vxl.sh
ch.tc
@@ -13369,6 +13691,13 @@ fastblog.net
// Submitted by Arnold Hendriks <info@webhare.com>
*.webhare.dev
+// WebHotelier Technologies Ltd: https://www.webhotelier.net/
+// Submitted by Apostolos Tsakpinis <apostolos.tsakpinis@gmail.com>
+reserve-online.net
+reserve-online.com
+bookonline.app
+hotelwithflight.com
+
// WeDeploy by Liferay, Inc. : https://www.wedeploy.com
// Submitted by Henrique Vicente <security@wedeploy.com>
wedeploy.io
@@ -13396,15 +13725,29 @@ daemon.panel.gg
// WoltLab GmbH : https://www.woltlab.com
// Submitted by Tim Düsterhus <security@woltlab.cloud>
+woltlab-demo.com
myforum.community
community-pro.de
diskussionsbereich.de
community-pro.net
meinforum.net
-// www.com.vc : http://www.com.vc
-// Submitted by Li Hui <lihui@sinopub.com>
-cn.vu
+// Woods Valldata : https://www.woodsvalldata.co.uk/
+// Submitted by Chris Whittle <chris.whittle@woodsvalldata.co.uk>
+affinitylottery.org.uk
+raffleentry.org.uk
+weeklylottery.org.uk
+
+// WP Engine : https://wpengine.com/
+// Submitted by Michael Smith <michael.smith@wpengine.com>
+// Submitted by Brandon DuRette <brandon.durette@wpengine.com>
+wpenginepowered.com
+js.wpenginepowered.com
+
+// Wix.com, Inc. : https://www.wix.com
+// Submitted by Shahar Talmi <shahar@wix.com>
+wixsite.com
+editorx.io
// XenonCloud GbR: https://xenoncloud.net
// Submitted by Julian Uphoff <publicsuffixlist@xenoncloud.net>
@@ -13448,6 +13791,7 @@ ybo.trade
// Yunohost : https://yunohost.org
// Submitted by Valentin Grimaud <security@yunohost.org>
+ynh.fr
nohost.me
noho.st
@@ -13466,26 +13810,4 @@ basicserver.io
virtualserver.io
enterprisecloud.nu
-// Mintere : https://mintere.com/
-// Submitted by Ben Aubin <security@mintere.com>
-mintere.site
-
-// Cityhost LLC : https://cityhost.ua
-// Submitted by Maksym Rivtin <support@cityhost.net.ua>
-cx.ua
-
-// WP Engine : https://wpengine.com/
-// Submitted by Michael Smith <michael.smith@wpengine.com>
-// Submitted by Brandon DuRette <brandon.durette@wpengine.com>
-wpenginepowered.com
-js.wpenginepowered.com
-
-// Impertrix Solutions : <https://impertrixcdn.com>
-// Submitted by Zhixiang Zhao <csuite@impertrix.com>
-impertrixcdn.com
-impertrix.com
-
-// GignoSystemJapan: http://gsj.bz
-// Submitted by GignoSystemJapan <kakutou-ec@gsj.bz>
-gsj.bz
// ===END PRIVATE DOMAINS===
diff --git a/etc/refcards/README b/etc/refcards/README
index 30c82bc7140..4102c85ba10 100644
--- a/etc/refcards/README
+++ b/etc/refcards/README
@@ -5,7 +5,7 @@ See the end of the file for license conditions.
REFERENCE CARDS FOR GNU EMACS
To generate these refcards, you need to install the TeX document
-production system. For example, <http://www.tug.org/texlive/>.
+production system. For example, <https://www.tug.org/texlive/>.
All modern GNU/Linux distributions provide TeX packages, so the
easiest way is just to install those. Your distribution may have
@@ -23,6 +23,51 @@ PDF and PS copies of these cards are also available at
<https://www.gnu.org/software/emacs/refcards>. The FSF online
store <https://shop.fsf.org/> sometimes has printed copies for sale.
+List of generated cards:
+
+ calccard.pdf Calc Reference Card
+ dired-ref.pdf Dired Reference Card
+ gnus-booklet.pdf Gnus Reference Booklet
+ gnus-refcard.pdf Gnus Reference Card
+ orgcard.pdf Org-Mode Reference Card
+ refcard.pdf Emacs Reference Card
+ survival.pdf Emacs Survival Card
+ vipcard.pdf VIP Quick Reference Card
+ viperCard.pdf ViperCard: Viper Reference Pal
+
+Brazilian Portuguese
+
+ pt-br-refcard.pdf Reference Card (pt-br)
+
+Czech
+
+ cs-dired-ref.pdf Dired Reference Card (cs)
+ cs-refcard.pdf Emacs Reference Card (cs)
+ cs-survival.pdf Emacs Survival Card (cs)
+
+French
+
+ fr-dired-ref.pdf Dired Reference Card (fr)
+ fr-refcard.pdf Emacs Reference Card (fr)
+ fr-survival.pdf Emacs Survival Card (fr)
+
+German
+
+ de-refcard.pdf Emacs Reference Card (de)
+
+Polish
+
+ pl-refcard.pdf Emacs Reference Card (pl)
+
+Russian
+
+ ru-refcard.pdf Emacs Reference Card (ru)
+
+Slovak
+
+ sk-dired-ref.pdf Dired Reference Card (sk)
+ sk-refcard.pdf Emacs Reference Card (sk)
+ sk-survival.pdf Emacs Survival Card (sk)
COPYRIGHT AND LICENSE INFORMATION FOR IMAGE FILES
diff --git a/etc/refcards/orgcard.tex b/etc/refcards/orgcard.tex
index dc28587b47d..181516172d2 100644
--- a/etc/refcards/orgcard.tex
+++ b/etc/refcards/orgcard.tex
@@ -1,6 +1,6 @@
% Reference Card for Org Mode
-\def\orgversionnumber{9.4.2}
-\def\versionyear{2019} % latest update
+\def\orgversionnumber{9.5.1}
+\def\versionyear{2021} % latest update
\input emacsver.tex
%**start of header
diff --git a/etc/refcards/pl-refcard.tex b/etc/refcards/pl-refcard.tex
index c9d96788c5d..5c12dbfbf57 100644
--- a/etc/refcards/pl-refcard.tex
+++ b/etc/refcards/pl-refcard.tex
@@ -679,7 +679,7 @@ Napisz \kbd{F10} aby uaktywni/c menu w minibuforze.
\key{przestaw {\bf linie}}{C-x C-t}
\key{przestaw {\bf s-wyra/zenia}}{C-M-t}
-% Removed -- there is no Polish disctionary for ispell.
+% Removed -- there is no Polish dictionary for ispell.
%\section{Spelling Check}
%
%\key{check spelling of current word}{M-\$}
diff --git a/etc/refcards/refcard.tex b/etc/refcards/refcard.tex
index ae39a4e9f76..bc057569a7c 100644
--- a/etc/refcards/refcard.tex
+++ b/etc/refcards/refcard.tex
@@ -273,13 +273,15 @@ see the Emacs distribution, or {\tt https://www.gnu.org/software/emacs}
\centerline{(for version \versionemacs)}
-\section{Starting Emacs}
+\section{Key Binding Notation}
-To enter GNU Emacs \versionemacs, just type its name: \kbd{emacs}
+In the Emacs key binding notation, \kbd{C-x}
+is \kbd{Ctrl+X}; \kbd{M-x} is usually \kbd{Alt+X}; \kbd{S-x} is
+\kbd{Shift+X}; and \kbd{C-M-x} is \kbd{Ctrl+Alt+X}, etc.
\section{Leaving Emacs}
-\key{suspend Emacs (or iconify it under X)}{C-z}
+\key{iconify Emacs (or suspend it in terminal)}{C-z}
\key{exit Emacs permanently}{C-x C-c}
\section{Files}
diff --git a/etc/refcards/ru-refcard.tex b/etc/refcards/ru-refcard.tex
index 179be0af885..018be36eb46 100644
--- a/etc/refcards/ru-refcard.tex
+++ b/etc/refcards/ru-refcard.tex
@@ -40,7 +40,7 @@
\newlength{\ColThreeWidth}
\setlength{\ColThreeWidth}{25mm}
-\newcommand{\versionemacs}[0]{28} % version of Emacs this is for
+\newcommand{\versionemacs}[0]{29} % version of Emacs this is for
\newcommand{\cyear}[0]{2021} % copyright year
\newcommand\shortcopyrightnotice[0]{\vskip 1ex plus 2 fill
diff --git a/etc/themes/adwaita-theme.el b/etc/themes/adwaita-theme.el
index c98bec6cfa5..7d297df5260 100644
--- a/etc/themes/adwaita-theme.el
+++ b/etc/themes/adwaita-theme.el
@@ -96,6 +96,9 @@ default look of the Gnome 3 desktop.")
`(gnus-cite-1 ((,class (:foreground "#00578E"))))
`(gnus-cite-2 ((,class (:foreground "#0084C8"))))
+ `(image-dired-thumb-mark ((,class (:background "#CE5C00"))))
+ `(image-dired-thumb-flagged ((,class (:background "#B50000"))))
+
`(diff-added ((,class (:bold t :foreground "#4E9A06"))))
`(diff-removed ((,class (:bold t :foreground "#F5666D"))))))
diff --git a/etc/themes/deeper-blue-theme.el b/etc/themes/deeper-blue-theme.el
index cfe8a5bfb28..5895693386c 100644
--- a/etc/themes/deeper-blue-theme.el
+++ b/etc/themes/deeper-blue-theme.el
@@ -82,6 +82,8 @@
`(ido-first-match ((,class (:weight normal :foreground "orange"))))
`(ido-only-match ((,class (:foreground "green"))))
`(ido-subdir ((,class (:foreground nil :inherit font-lock-keyword-face))))
+ `(image-dired-thumb-flagged ((,class (:background "Red1"))))
+ `(image-dired-thumb-mark ((,class (:background "dodgerblue3"))))
`(info-header-node ((,class (:foreground "DeepSkyBlue1"))))
`(info-header-xref ((,class (:foreground "SeaGreen2"))))
`(info-menu-header ((,class (:family "helv" :weight bold))))
diff --git a/etc/themes/dichromacy-theme.el b/etc/themes/dichromacy-theme.el
index 09f4454f9b1..148ebd434cd 100644
--- a/etc/themes/dichromacy-theme.el
+++ b/etc/themes/dichromacy-theme.el
@@ -101,6 +101,9 @@ Ansi-Color faces are included.")
`(gnus-header-subject ((,class (:foreground ,orange))))
`(gnus-header-name ((,class (:foreground ,skyblue))))
`(gnus-header-newsgroups ((,class (:foreground ,vermillion))))
+ ;; Image-Dired
+ `(image-dired-thumb-flagged ((,class (:background ,vermillion))))
+ `(image-dired-thumb-mark ((,class (:background ,orange))))
;; Message faces
`(message-header-name ((,class (:foreground ,skyblue))))
`(message-header-cc ((,class (:foreground ,vermillion))))
@@ -113,12 +116,34 @@ Ansi-Color faces are included.")
`(flyspell-duplicate ((,class (:weight unspecified :foreground unspecified
:slant unspecified :underline ,orange))))
`(flyspell-incorrect ((,class (:weight unspecified :foreground unspecified
- :slant unspecified :underline ,redpurple)))))
-
- (custom-theme-set-variables
- 'dichromacy
- `(ansi-color-names-vector ["black" ,vermillion ,bluegreen ,yellow
- ,blue ,redpurple ,skyblue "white"])))
+ :slant unspecified :underline ,redpurple))))
+ ;; ANSI color
+ `(ansi-color-black ((,class (:background "black" :foreground "black"))))
+ `(ansi-color-red ((,class (:background ,vermillion
+ :foreground ,vermillion))))
+ `(ansi-color-green ((,class (:background ,bluegreen
+ :foreground ,bluegreen))))
+ `(ansi-color-yellow ((,class (:background ,yellow :foreground ,yellow))))
+ `(ansi-color-blue ((,class (:background ,blue :foreground ,blue))))
+ `(ansi-color-magenta ((,class (:background ,redpurple
+ :foreground ,redpurple))))
+ `(ansi-color-cyan ((,class (:background ,skyblue :foreground ,skyblue))))
+ `(ansi-color-white ((,class (:background "gray90" :foreground "gray90"))))
+ `(ansi-color-bright-black ((,class (:background "black"
+ :foreground "black"))))
+ `(ansi-color-bright-red ((,class (:background ,vermillion
+ :foreground ,vermillion))))
+ `(ansi-color-bright-green ((,class (:background ,bluegreen
+ :foreground ,bluegreen))))
+ `(ansi-color-bright-yellow ((,class (:background ,yellow
+ :foreground ,yellow))))
+ `(ansi-color-bright-blue ((,class (:background ,blue :foreground ,blue))))
+ `(ansi-color-bright-magenta ((,class (:background ,redpurple
+ :foreground ,redpurple))))
+ `(ansi-color-bright-cyan ((,class (:background ,skyblue
+ :foreground ,skyblue))))
+ `(ansi-color-bright-white ((,class (:background "gray90"
+ :foreground "gray90"))))))
(provide-theme 'dichromacy)
diff --git a/etc/themes/leuven-theme.el b/etc/themes/leuven-theme.el
index f643dd560cf..514384ca2af 100644
--- a/etc/themes/leuven-theme.el
+++ b/etc/themes/leuven-theme.el
@@ -287,6 +287,25 @@ more...")
`(message-header-xheader ((,class ,mail-header-other)))
`(message-mml ((,class (:foreground "forest green"))))
+ ;; ANSI colors.
+ `(ansi-color-bold ((,class (:weight bold))))
+ `(ansi-color-black ((,class (:foreground "black" :background "black"))))
+ `(ansi-color-red ((,class (:foreground "red3" :background "red3"))))
+ `(ansi-color-green ((,class (:foreground "forest green" :background "forest green"))))
+ `(ansi-color-yellow ((,class (:foreground "yellow3" :background "yellow3"))))
+ `(ansi-color-blue ((,class (:foreground "blue" :background "blue"))))
+ `(ansi-color-magenta ((,class (:foreground "magenta3" :background "magenta3"))))
+ `(ansi-color-cyan ((,class (:foreground "deep sky blue" :background "deep sky blue"))))
+ `(ansi-color-white ((,class (:foreground "gray60" :background "gray60"))))
+ `(ansi-color-bright-black ((,class (:foreground "gray30" :background "gray30"))))
+ `(ansi-color-bright-red ((,class (:foreground "red1" :background "red1"))))
+ `(ansi-color-bright-green ((,class (:foreground "lime green" :background "lime green"))))
+ `(ansi-color-bright-yellow ((,class (:foreground "yellow2" :background "yellow2"))))
+ `(ansi-color-bright-blue ((,class (:foreground "dodger blue" :background "dodger blue"))))
+ `(ansi-color-bright-magenta ((,class (:foreground "magenta" :background "magenta"))))
+ `(ansi-color-bright-cyan ((,class (:foreground "sky blue" :background "sky blue"))))
+ `(ansi-color-bright-white ((,class (:foreground "gray80" :background "gray80"))))
+
;; Diff.
`(diff-added ((,class ,diff-added)))
`(diff-changed ((,class ,diff-changed)))
@@ -613,6 +632,8 @@ more...")
`(ilog-echo-face ((,class (:height 2.0 :foreground "#006FE0"))))
`(ilog-load-face ((,class (:foreground "#BA36A5"))))
`(ilog-message-face ((,class (:foreground "#808080"))))
+ `(image-dired-thumb-flagged ((,class (:background "red"))))
+ `(image-dired-thumb-mark ((,class :background "#FFAAAA")))
`(indent-guide-face ((,class (:foreground "#D3D3D3"))))
`(info-file ((,class (:family "Sans Serif" :height 1.8 :weight bold :box (:line-width 1 :color "#0000CC") :foreground "cornflower blue" :background "LightSteelBlue1"))))
`(info-header-node ((,class (:underline t :foreground "orange")))) ; nodes in header
@@ -1035,12 +1056,6 @@ more...")
;; highlight-sexp-mode.
'(hl-sexp-background-color "#efebe9")
- '(ansi-color-faces-vector
- [default default default italic underline success warning error])
-
- ;; Colors used in Shell mode.
- '(ansi-color-names-vector
- ["black" "red3" "ForestGreen" "yellow3" "blue" "magenta3" "DeepSkyBlue" "gray50"])
)
;;;###autoload
diff --git a/etc/themes/light-blue-theme.el b/etc/themes/light-blue-theme.el
index 62528856da0..547d2df04c0 100644
--- a/etc/themes/light-blue-theme.el
+++ b/etc/themes/light-blue-theme.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2011-2021 Free Software Foundation, Inc.
;; Author: Drew Adams <drew.adams@oracle.com>
+;; Maintainer: emacs-devel@gnu.org
;; This file is part of GNU Emacs.
@@ -28,6 +29,8 @@
(deftheme light-blue
"Face colors utilizing a light blue background.")
+(make-obsolete 'light-blue nil "29.1")
+
(let ((class '((class color) (min-colors 89))))
(custom-theme-set-faces
'light-blue
diff --git a/etc/themes/manoj-dark-theme.el b/etc/themes/manoj-dark-theme.el
index 5a527111d35..e80403f5b34 100644
--- a/etc/themes/manoj-dark-theme.el
+++ b/etc/themes/manoj-dark-theme.el
@@ -23,11 +23,11 @@
;;; Commentary:
;; I spend a lot of time working in front of a screen (many hours in a
-;; dimly lit room) and eye fatigue is an issue. This is a dark color
-;; theme for emacs, which is easier on the eyes than light themes.
+;; dimly lit room) and eye fatigue is an issue. This is a dark color
+;; theme for Emacs, which is easier on the eyes than light themes.
;; It does not help that I am blue-green color blind, so subtle
-;; variations are often lost on me. I do want to use color contrast to
+;; variations are often lost on me. I do want to use color contrast to
;; increase productivity, but I also want to avoid the jarring angry
;; fruit salad look, and so I am in the process of crafting a logical
;; color scheme that is high contrast enough for me, without being too
@@ -35,7 +35,7 @@
;; In circumstances where there a lot of related faces that can be
;; viewed, for example, the Gnus group buffer, consistent and logical
-;; color choices are the only sane option. Gnus groups can be newa
+;; color choices are the only sane option. Gnus groups can be newa
;; (blueish) or mail (greenish), have states (large number of under
;; messages, normal, and empty). The large number unread groups have
;; highest luminance (appear brighter), and the empty one have lower
@@ -45,25 +45,22 @@
;; constant separation -- so all the related groups have the same
;; brightness ({mail,news}/{unread,normal,empty}), and a graded
;; selection of foreground colors. It sounds more complicated that it
-;; looks. The eye is drawn naturally to the unread groups, and first
-;; to the mail, then USENET groups (which is my preference).
+;; looks. The eye is drawn naturally to the unread groups, and first
+;; to the mail, then Usenet groups (which is my preference).
;; Similar color variations occur for individual messages in a group;
;; high scoring messages bubble to the top, and have a higher
;; luminance. This color schema has made me slightly faster at
-;; reading mail/USENET.
+;; reading mail/Usenet.
;; In the message itself, quoted mail messages from different people
;; are color coordinated, with high contrast between citations that are
;; close to each other in the hierarchy, so it is less likely that one
;; misunderstands who said what in a long conversation.
-;; The following scheme covers programming languages, Gnus, Erc, mail,
-;; org-mode, CUA-mode, apt-utils, bbdb, compilation buffers, changelog
-;; mode, diff and ediff, eshell, and more. You need emacs-goodies
-;; package on Debian to use this. See the wiki page at
-;; https://www.emacswiki.org/cgi-bin/wiki?ColorTheme for details. The
-;; project home page is at https://gna.org/projects/color-theme.
+;; This theme covers programming languages, Gnus, Erc, mail, org-mode,
+;; CUA-mode, apt-utils, bbdb, compilation buffers, changelog mode,
+;; diff and ediff, eshell, and more.
;;; Code:
@@ -224,6 +221,9 @@ jarring angry fruit salad look to reduce eye fatigue.")
'(gnus-group-news-low-empty ((t (:foreground "DarkTurquoise"))))
'(gnus-group-news-low-empty-face ((t (:foreground "DarkTurquoise"))))
+ ;; '(image-dired-thumb-flagged ((t (:background "red"))))
+ ;; '(image-dired-thumb-mark ((t (:background "Pink"))))
+
;;message faces
'(message-cited-text ((t (:foreground "red3"))))
'(message-header-cc ((t (:bold t :foreground "chartreuse1" :weight bold))))
@@ -541,7 +541,6 @@ jarring angry fruit salad look to reduce eye fatigue.")
'(ido-indicator ((t (:background "red1" :foreground "yellow1" :width condensed))))
'(ido-only-match ((t (:foreground "ForestGreen"))))
'(ido-subdir ((t (:foreground "red1"))))
- '(info-menu-5 ((t (:underline t))))
'(info-menu-header ((t (:bold t :weight bold))))
'(info-node ((t (:bold t :italic t :foreground "yellow"))))
'(info-node ((t (:italic t :bold t :foreground "white" :slant italic :weight bold))))
diff --git a/etc/themes/misterioso-theme.el b/etc/themes/misterioso-theme.el
index e7a66c5650d..26a5946d30c 100644
--- a/etc/themes/misterioso-theme.el
+++ b/etc/themes/misterioso-theme.el
@@ -101,12 +101,33 @@
`(message-header-subject ((,class (:foreground "#dbdb95"))))
`(message-header-to ((,class (:foreground "#00ede1"))))
`(message-cited-text ((,class (:foreground "#74af68"))))
- `(message-separator ((,class (:foreground "#23d7d7"))))))
-
-(custom-theme-set-variables
- 'misterioso
- '(ansi-color-names-vector ["#2d3743" "#ff4242" "#74af68" "#dbdb95"
- "#34cae2" "#008b8b" "#00ede1" "#e1e1e0"]))
+ `(message-separator ((,class (:foreground "#23d7d7"))))
+ ;; ANSI colors
+ `(ansi-color-black ((,class (:background "#2d3743" :foreground "#2d3743"))))
+ `(ansi-color-red ((,class (:background "#da3938" :foreground "#da3938"))))
+ `(ansi-color-green ((,class (:background "#74af68" :foreground "#74af68"))))
+ `(ansi-color-yellow ((,class (:background "#dbdb95" :foreground "#dbdb95"))))
+ `(ansi-color-blue ((,class (:background "#34cae2" :foreground "#34cae2"))))
+ `(ansi-color-magenta ((,class (:background "#b33c97"
+ :foreground "#b33c97"))))
+ `(ansi-color-cyan ((,class (:background "#008b8b" :foreground "#008b8b"))))
+ `(ansi-color-white ((,class (:background "#e1e1e0" :foreground "#e1e1e0"))))
+ `(ansi-color-bright-black ((,class (:background "#415160"
+ :foreground "#415160"))))
+ `(ansi-color-bright-red ((,class (:background "#ff4242"
+ :foreground "#ff4242"))))
+ `(ansi-color-bright-green ((,class (:background "#74cd65"
+ :foreground "#74cd65"))))
+ `(ansi-color-bright-yellow ((,class (:background "#ffad29"
+ :foreground "#ffad29"))))
+ `(ansi-color-bright-blue ((,class (:background "#59e9ff"
+ :foreground "#59e9ff"))))
+ `(ansi-color-bright-magenta ((,class (:background "#ed74cd"
+ :foreground "#ed74cd"))))
+ `(ansi-color-bright-cyan ((,class (:background "#00ede1"
+ :foreground "#00ede1"))))
+ `(ansi-color-bright-white ((,class (:background "#eeeeec"
+ :foreground "#eeeeec"))))))
(provide-theme 'misterioso)
diff --git a/etc/themes/modus-operandi-theme.el b/etc/themes/modus-operandi-theme.el
index a946d747e8e..5a73e655f30 100644
--- a/etc/themes/modus-operandi-theme.el
+++ b/etc/themes/modus-operandi-theme.el
@@ -4,8 +4,8 @@
;; Author: Protesilaos Stavrou <info@protesilaos.com>
;; URL: https://gitlab.com/protesilaos/modus-themes
-;; Version: 1.5.0
-;; Package-Requires: ((emacs "26.1"))
+;; Version: 1.7.0
+;; Package-Requires: ((emacs "27.1"))
;; Keywords: faces, theme, accessibility
;; This file is part of GNU Emacs.
diff --git a/etc/themes/modus-themes.el b/etc/themes/modus-themes.el
index b9fe4a32729..f7d38ac2dea 100644
--- a/etc/themes/modus-themes.el
+++ b/etc/themes/modus-themes.el
@@ -4,9 +4,9 @@
;; Author: Protesilaos Stavrou <info@protesilaos.com>
;; URL: https://gitlab.com/protesilaos/modus-themes
-;; Version: 1.5.0
-;; Last-Modified: <2021-07-15 13:21:55 +0300>
-;; Package-Requires: ((emacs "26.1"))
+;; Version: 1.7.0
+;; Last-Modified: <2021-11-18 12:28:22 +0200>
+;; Package-Requires: ((emacs "27.1"))
;; Keywords: faces, theme, accessibility
;; This file is part of GNU Emacs.
@@ -31,34 +31,36 @@
;; This file contains all customization variables, helper functions,
;; interactive commands, and face specifications. Please refer to the
;; official Info manual for further documentation (distributed with the
-;; themes, or available at: <https://protesilaos.com/modus-themes>).
+;; themes, or available at: <https://protesilaos.com/emacs/modus-themes>).
;;
;; The themes share the following customization variables:
;;
+;; modus-themes-headings (alist)
+;; modus-themes-org-agenda (alist)
+;; modus-themes-bold-constructs (boolean)
;; modus-themes-inhibit-reload (boolean)
+;; modus-themes-intense-markup (boolean)
;; modus-themes-italic-constructs (boolean)
-;; modus-themes-bold-constructs (boolean)
-;; modus-themes-variable-pitch-headings (boolean)
-;; modus-themes-variable-pitch-ui (boolean)
+;; modus-themes-mixed-fonts (boolean)
;; modus-themes-scale-headings (boolean)
;; modus-themes-subtle-line-numbers (boolean)
;; modus-themes-success-deuteranopia (boolean)
-;; modus-themes-no-mixed-fonts (boolean)
-;; modus-themes-headings (alist)
+;; modus-themes-variable-pitch-headings (boolean)
+;; modus-themes-variable-pitch-ui (boolean)
+;; modus-themes-completions (choice)
+;; modus-themes-diffs (choice)
;; modus-themes-fringes (choice)
+;; modus-themes-hl-line (choice)
;; modus-themes-lang-checkers (choice)
-;; modus-themes-org-agenda (alist)
-;; modus-themes-org-blocks (choice)
-;; modus-themes-prompts (choice)
+;; modus-themes-links (choice)
+;; modus-themes-mail-citations (choice)
;; modus-themes-mode-line (choice)
-;; modus-themes-diffs (choice)
-;; modus-themes-syntax (choice)
-;; modus-themes-hl-line (choice)
+;; modus-themes-org-blocks (choice)
;; modus-themes-paren-match (choice)
+;; modus-themes-prompts (choice)
;; modus-themes-region (choice)
-;; modus-themes-links (choice)
-;; modus-themes-completions (choice)
-;; modus-themes-mail-citations (choice)
+;; modus-themes-syntax (choice)
+;; modus-themes-mode-line-padding (natnum)
;;
;; The default scale for headings is as follows (it can be customized as
;; well---remember, no scaling takes place by default):
@@ -69,6 +71,11 @@
;; modus-themes-scale-4 1.2
;; modus-themes-scale-title 1.3
;;
+;; There is another scaling-related option, which however is reserved
+;; for special cases and is not used for headings:
+;;
+;; modus-themes-scale-small 0.9
+;;
;; There also exist two unique customization variables for overriding
;; color palette values. The specifics are documented in the manual.
;; The symbols are:
@@ -86,6 +93,7 @@
;; alert
;; all-the-icons
;; annotate
+;; ansi-color
;; anzu
;; apropos
;; apt-sources-list
@@ -125,6 +133,7 @@
;; css-mode
;; csv-mode
;; ctrlf
+;; cursor-flash
;; custom (M-x customize)
;; dap-mode
;; dashboard (emacs-dashboard)
@@ -160,6 +169,7 @@
;; eldoc-box
;; elfeed
;; elfeed-score
+;; elpher
;; embark
;; emms
;; enh-ruby-mode (enhanced-ruby-mode)
@@ -230,6 +240,7 @@
;; ido-mode
;; iedit
;; iflipb
+;; image-dired
;; imenu-list
;; indium
;; info
@@ -270,6 +281,7 @@
;; mu4e
;; mu4e-conversation
;; multiple-cursors
+;; nano-modeline
;; neotree
;; no-emoji
;; notmuch
@@ -370,6 +382,7 @@
;; vc-annotate (C-x v g)
;; vdiff
;; vertico
+;; vertico-quick
;; vimish-fold
;; visible-mark
;; visual-regexp
@@ -615,8 +628,10 @@ cover the blue-cyan-magenta side of the spectrum."
(bg-tab-bar . "#d5d5d5")
(bg-tab-active . "#f6f6f6")
- (bg-tab-inactive . "#bdbdbd")
- (bg-tab-inactive-alt . "#999999")
+ (bg-tab-inactive . "#b7b7b7")
+ (bg-tab-inactive-accent . "#a9b4f6")
+ (bg-tab-inactive-alt . "#9f9f9f")
+ (bg-tab-inactive-alt-accent . "#9fa6d0")
(red-tab . "#680000")
(green-tab . "#003900")
@@ -858,8 +873,10 @@ symbol and the latter as a string.")
(bg-tab-bar . "#2c2c2c")
(bg-tab-active . "#0e0e0e")
- (bg-tab-inactive . "#3d3d3d")
+ (bg-tab-inactive . "#424242")
+ (bg-tab-inactive-accent . "#35398f")
(bg-tab-inactive-alt . "#595959")
+ (bg-tab-inactive-alt-accent . "#505588")
(red-tab . "#ffc0bf")
(green-tab . "#88ef88")
@@ -1463,7 +1480,7 @@ The actual styling of the face is done by `modus-themes-faces'."
(defface modus-themes-variable-pitch nil
"Generic face for applying a conditional `variable-pitch'.
-This behaves in accordance with `modus-themes-no-mixed-fonts',
+This behaves in accordance with `modus-themes-mixed-fonts',
`modus-themes-variable-pitch-headings' for all heading levels,
and `modus-themes-variable-pitch-ui'.
@@ -1472,7 +1489,7 @@ The actual styling of the face is done by `modus-themes-faces'."
(defface modus-themes-fixed-pitch nil
"Generic face for applying a conditional `fixed-pitch'.
-This behaves in accordance with `modus-themes-no-mixed-fonts'.
+This behaves in accordance with `modus-themes-mixed-fonts'.
The actual styling of the face is done by `modus-themes-faces'."
:group 'modus-theme-faces)
@@ -1724,16 +1741,6 @@ For form, see `modus-themes-vivendi-colors'."
(put 'modus-themes-vivendi-color-overrides
'custom-options (copy-sequence colors)))
-(defcustom modus-themes-slanted-constructs nil
- "Use slanted text in more code constructs (italics or oblique)."
- :group 'modus-themes
- :package-version '(modus-themes . "1.0.0")
- :version "28.1"
- :type 'boolean
- :set #'modus-themes--set-option
- :initialize #'custom-initialize-default
- :link '(info-link "(modus-themes) Slanted constructs"))
-
(define-obsolete-variable-alias
'modus-themes-slanted-constructs
'modus-themes-italic-constructs
@@ -1780,30 +1787,43 @@ This includes the mode line, header line, tab bar, and tab line."
:initialize #'custom-initialize-default
:link '(info-link "(modus-themes) UI typeface"))
-(defcustom modus-themes-no-mixed-fonts nil
- "Disable inheritance from `fixed-pitch' in some faces.
-
-This is done by default to allow spacing-sensitive constructs,
-such as Org tables and code blocks, to remain monospaced when
-users opt for something like the command `variable-pitch-mode'.
-The downside with the default is that users need to explicitly
-configure the font family of `fixed-pitch' in order to get a
-consistent experience. That may be something they do not want to
-do. Hence this option to disable any kind of technique for
-mixing fonts."
+(define-obsolete-variable-alias
+ 'modus-themes-no-mixed-fonts
+ 'modus-themes-mixed-fonts "On 2021-10-02 for version 1.7.0")
+
+(defcustom modus-themes-mixed-fonts nil
+ "Non-nil to enable inheritance from `fixed-pitch' in some faces.
+
+This is done to allow spacing-sensitive constructs, such as Org
+tables and code blocks, to remain monospaced when users opt for
+something like the command `variable-pitch-mode'.
+
+Users may need to explicitly configure the font family of
+`fixed-pitch' in order to get a consistent experience."
:group 'modus-themes
- :package-version '(modus-themes . "1.0.0")
- :version "28.1"
+ :package-version '(modus-themes . "1.7.0")
+ :version "29.1"
:type 'boolean
:set #'modus-themes--set-option
:initialize #'custom-initialize-default
- :link '(info-link "(modus-themes) No mixed fonts"))
+ :link '(info-link "(modus-themes) Mixed fonts"))
(defconst modus-themes--headings-choice
'(set :tag "Properties" :greedy t
(const :tag "Background color" background)
(const :tag "Overline" overline)
- (const :tag "No bold weight" no-bold)
+ (choice :tag "Font weight (must be supported by the typeface)"
+ (const :tag "Bold (default)" nil)
+ (const :tag "Thin" thin)
+ (const :tag "Ultra-light" ultralight)
+ (const :tag "Extra-light" extralight)
+ (const :tag "Light" light)
+ (const :tag "Semi-light" semilight)
+ (const :tag "Regular" regular)
+ (const :tag "Medium" medium)
+ (const :tag "Semi-bold" semibold)
+ (const :tag "Extra-bold" extrabold)
+ (const :tag "Ultra-bold" ultrabold))
(choice :tag "Colors"
(const :tag "Subtle colors" nil)
(const :tag "Rainbow colors" rainbow)
@@ -1837,21 +1857,27 @@ heading.
A `background' property adds a subtle tinted color to the
background of the heading.
-A `no-bold' property removes the bold weight from the heading's
-text.
-
A `monochrome' property makes all headings the same base color,
which is that of the default for the active theme (black/white).
When `background' is also set, `monochrome' changes its color to
gray. If both `monochrome' and `rainbow' are set, the former
takes precedence.
+The symbol of a weight attribute adjusts the font of the heading
+accordingly, such as `light', `semibold', etc. Valid symbols are
+defined in the internal variable `modus-themes--heading-weights'.
+The absence of a weight means that bold will be used by virtue of
+inheriting the `bold' face (check the manual for tweaking bold
+and italic faces). For backward compatibility, the `no-bold'
+value is accepted, though users are encouraged to specify a
+`regular' weight instead.
+
Combinations of any of those properties are expressed as a list,
like in these examples:
- (no-bold)
+ (semibold)
(rainbow background)
- (overline monochrome no-bold)
+ (overline monochrome semibold)
The order in which the properties are set is not significant.
@@ -1860,7 +1886,7 @@ In user configuration files the form may look like this:
(setq modus-themes-headings
'((1 . (background overline rainbow))
(2 . (background overline))
- (t . (overline no-bold))))
+ (t . (overline semibold))))
When defining the styles per heading level, it is possible to
pass a non-nil value (t) instead of a list of properties. This
@@ -1873,7 +1899,7 @@ will retain the original aesthetic for that level. For example:
(setq modus-themes-headings
'((1 . (background overline))
- (2 . (rainbow no-bold))
+ (2 . (rainbow semibold))
(t . t))) ; default style for all other levels
For Org users, the extent of the heading depends on the variable
@@ -1885,8 +1911,8 @@ Also read `modus-themes-scale-headings' to change the height of
headings and `modus-themes-variable-pitch-headings' to make them
use a proportionately spaced font."
:group 'modus-themes
- :package-version '(modus-themes . "1.5.0")
- :version "28.1"
+ :package-version '(modus-themes . "1.7.0")
+ :version "29.1"
:type `(alist
:options ,(mapcar (lambda (el)
(list el modus-themes--headings-choice))
@@ -1907,6 +1933,7 @@ combinations:
(setq modus-themes-org-agenda
'((header-block . (variable-pitch scale-title))
(header-date . (grayscale workaholic bold-today))
+ (event . (accented italic varied))
(scheduled . uniform)
(habit . traffic-light)))
@@ -1945,6 +1972,11 @@ that can include any of the following properties:
- `bold-today' to apply a bold typographic weight to the current
date;
- `bold-all' to render all date headings in a bold weight.
+- `scale-heading' increases the height of the date headings to
+ the value of `modus-themes-scale-1' (which is the first step in
+ the scale for regular headings).
+- `underline-today' applies an underline to the current date
+ while removing the background it has by default.
For example:
@@ -1953,6 +1985,44 @@ For example:
(header-date . (grayscale bold-all))
(header-date . (grayscale workaholic))
(header-date . (grayscale workaholic bold-today))
+ (header-date . (grayscale workaholic bold-today scale-heading))
+
+An `event' key covers (i) headings with a plain time stamp that
+are shown on the agenda, also known as events, (ii) entries
+imported from the diary, and (iii) other items that derive from a
+symbolic expression or sexp (phases of the moon, holidays, etc.).
+By default all those look the same and have a subtle foreground
+color (the default is a nil value or an empty list). This key
+accepts a list of properties. Those are:
+
+- `scale-small' reduces the height of the entries to the value of
+ the user option `modus-themes-scale-small' (0.9 the height of
+ the main font size by default). This work best when the
+ relevant entries have no tags associated with them and when the
+ user is interested in reducing their presence in the agenda
+ view.
+- `accented' applies an accent value to the event's foreground,
+ replacing the original gray. It makes all entries stand out more.
+- `italic' adds a slant to the font's forms (italic or oblique
+ forms, depending on the typeface).
+- `varied' differentiates between events with a plain time stamp
+ and entries that are generated from either the diary or a
+ symbolic expression. It generally puts more emphasis on
+ events. When `varied' is combined with `accented', it makes
+ only events use an accent color, while diary/sexp entries
+ retain their original subtle foreground. When `varied' is used
+ in tandem with `italic', it applies a slant only to diary and
+ sexp entries, not events. And when `varied' is the sole
+ property passed to the `event' key, it has the same meaning as
+ the list (italic varied). The combination of `varied',
+ `accented', `italic' covers all of the aforementioned cases.
+
+For example:
+
+ (event . nil)
+ (event . (italic))
+ (event . (accented italic))
+ (event . (accented italic varied))
A `scheduled' key applies to tasks with a scheduled date. By
default (a nil value), these use varying shades of yellow to
@@ -2008,8 +2078,8 @@ For example:
(habit . simplified)
(habit . traffic-light)"
:group 'modus-themes
- :package-version '(modus-themes . "1.5.0")
- :version "28.1"
+ :package-version '(modus-themes . "1.7.0")
+ :version "29.1"
:type '(set
(cons :tag "Block header"
(const header-block)
@@ -2027,7 +2097,16 @@ For example:
(const :tag "Use grayscale for date headers" grayscale)
(const :tag "Do not differentiate weekdays from weekends" workaholic)
(const :tag "Make today bold" bold-today)
- (const :tag "Make all dates bold" bold-all)))
+ (const :tag "Make all dates bold" bold-all)
+ (const :tag "Increase font size (`modus-themes-scale-1')" scale-heading)
+ (const :tag "Make today underlined; remove the background" underline-today)))
+ (cons :tag "Event entry" :greedy t
+ (const event)
+ (set :tag "Text presentation" :greedy t
+ (const :tag "Use smaller font size (`modus-themes-scale-small')" scale-small)
+ (const :tag "Apply an accent color" accented)
+ (const :tag "Italic font slant (oblique forms)" italic)
+ (const :tag "Differentiate events from diary/sexp entries" varied)))
(cons :tag "Scheduled tasks"
(const scheduled)
(choice (const :tag "Yellow colors to distinguish current and future tasks (default)" nil)
@@ -2047,8 +2126,8 @@ For example:
"Use font scaling for headings.
For regular headings the scale is controlled by the variables
-`modus-themes-scale-1' (smallest) and its variants all the way up
-to `modus-themes-scale-4' (larger).
+`modus-themes-scale-1' (smallest increase) and its variants all
+the way up to `modus-themes-scale-4' (largest increase).
While `modus-themes-scale-title' is reserved for special headings
that nominally are the largest on the scale (though that is not a
@@ -2163,12 +2242,14 @@ accordance with it in cases where it changes, such as while using
:initialize #'custom-initialize-default
:link '(info-link "(modus-themes) Scaled heading sizes"))
-(defcustom modus-themes-scale-5 1.3
+(define-obsolete-variable-alias 'modus-themes-scale-5 'modus-themes-scale-title "1.5.0")
+
+(defcustom modus-themes-scale-title 1.3
"Font size slightly larger than `modus-themes-scale-4'.
This size is only used for 'special' top level headings, such as
Org's file title heading, denoted by the #+title key word, and
-the Org agenda structure headers.
+the Org agenda structure headers (see `modus-themes-org-agenda').
The default value is a floating point that is interpreted as a
multiple of the base font size. It is recommended to use such a
@@ -2181,21 +2262,19 @@ This will ignore the base font size and, thus, will not scale in
accordance with it in cases where it changes, such as while using
`text-scale-adjust'."
:group 'modus-themes
- :package-version '(modus-themes . "1.2.0")
+ :package-version '(modus-themes . "1.5.0")
:version "28.1"
:type 'number
:set #'modus-themes--set-option
:initialize #'custom-initialize-default
:link '(info-link "(modus-themes) Scaled heading sizes"))
-(define-obsolete-variable-alias 'modus-themes-scale-5 'modus-themes-scale-title "1.5.0")
+(defcustom modus-themes-scale-small 0.9
+ "Font size smaller than the default value.
-(defcustom modus-themes-scale-title 1.3
- "Font size slightly larger than `modus-themes-scale-4'.
-
-This size is only used for 'special' top level headings, such as
-Org's file title heading, denoted by the #+title key word, and
-the Org agenda structure headers (see `modus-themes-org-agenda').
+This size is only used in special contexts where users are
+presented with the option to have smaller text on display (see
+`modus-themes-org-agenda').
The default value is a floating point that is interpreted as a
multiple of the base font size. It is recommended to use such a
@@ -2208,7 +2287,7 @@ This will ignore the base font size and, thus, will not scale in
accordance with it in cases where it changes, such as while using
`text-scale-adjust'."
:group 'modus-themes
- :package-version '(modus-themes . "1.5.0")
+ :package-version '(modus-themes . "1.6.0")
:version "28.1"
:type 'number
:set #'modus-themes--set-option
@@ -2251,12 +2330,12 @@ to the affected text.
The property `background' adds a color-coded background.
The property `intense' amplifies the applicable colors if
-`background' and/or `text-only' are set. If `intense' is set on
-its own, then it implies `text-only'.
+`background' and/or `text-also' are set. If `intense' is set on
+its own, then it implies `text-also'.
-To disable fringe indicators for Flymake or Flycheck, refer to
-variables `flymake-fringe-indicator-position' and
-`flycheck-indication-mode', respectively.
+The property `faint' uses nuanced colors for the underline and
+for the foreground when `text-also' is included. If both `faint'
+and `intense' are specified, the former takes precedence.
Combinations of any of those properties can be expressed in a
list, as in those examples:
@@ -2274,15 +2353,21 @@ In user configuration files the form may look like this:
NOTE: The placement of the straight underline, though not the
wave style, is controlled by the built-in variables
`underline-minimum-offset', `x-underline-at-descent-line',
-`x-use-underline-position-properties'."
+`x-use-underline-position-properties'.
+
+To disable fringe indicators for Flymake or Flycheck, refer to
+variables `flymake-fringe-indicator-position' and
+`flycheck-indication-mode', respectively."
:group 'modus-themes
- :package-version '(modus-themes . "1.5.0")
- :version "28.1"
+ :package-version '(modus-themes . "1.7.0")
+ :version "29.1"
:type '(set :tag "Properties" :greedy t
(const :tag "Straight underline" straight-underline)
(const :tag "Colorise text as well" text-also)
- (const :tag "Increase color intensity" intense)
- (const :tag "With background" background))
+ (const :tag "With background" background)
+ (choice :tag "Overall coloration"
+ (const :tag "Intense colors" intense)
+ (const :tag "Faint colors" faint)))
:set #'modus-themes--set-option
:initialize #'custom-initialize-default
:link '(info-link "(modus-themes) Language checkers"))
@@ -2404,6 +2489,14 @@ the same as the background, effectively creating some padding.
The `accented' property ensures that the active mode line uses a
colored background instead of the standard shade of gray.
+The `padded' property increases the apparent height of the mode
+line. This is done by applying box effects and combining them
+with an underline and overline. To ensure that the underline is
+placed at the bottom, set `x-underline-at-descent-line' to
+non-nil. The `padded' property has no effect when the `moody'
+property is also used, because Moody already applies its own
+padding.
+
Combinations of any of those properties are expressed as a list,
like in these examples:
@@ -2442,7 +2535,7 @@ Furthermore, because Moody expects an underline and overline
instead of a box style, it is advised to set
`x-underline-at-descent-line' to a non-nil value."
:group 'modus-themes
- :package-version '(modus-themes . "1.5.0")
+ :package-version '(modus-themes . "1.6.0")
:version "28.1"
:type '(set :tag "Properties" :greedy t
(choice :tag "Overall style"
@@ -2450,7 +2543,19 @@ instead of a box style, it is advised to set
(const :tag "3d borders" 3d)
(const :tag "No box effects (Moody-compatible)" moody))
(const :tag "Colored background" accented)
- (const :tag "Without border color" borderless))
+ (const :tag "Without border color" borderless)
+ (const :tag "With extra padding" padded))
+ :set #'modus-themes--set-option
+ :initialize #'custom-initialize-default
+ :link '(info-link "(modus-themes) Mode line"))
+
+(defcustom modus-themes-mode-line-padding 6
+ "Padding for `modus-themes-mode-line'.
+The value is expressed as a positive integer."
+ :group 'modus-themes
+ :package-version '(modus-themes . "1.7.0")
+ :version "29.1"
+ :type 'natnum
:set #'modus-themes--set-option
:initialize #'custom-initialize-default
:link '(info-link "(modus-themes) Mode line"))
@@ -2596,16 +2701,6 @@ In user configuration files the form may look like this:
:initialize #'custom-initialize-default
:link '(info-link "(modus-themes) Command prompts"))
-(defcustom modus-themes-intense-hl-line nil
- "Use a more prominent background for command `hl-line-mode'."
- :group 'modus-themes
- :package-version '(modus-themes . "1.0.0")
- :version "28.1"
- :type 'boolean
- :set #'modus-themes--set-option
- :initialize #'custom-initialize-default
- :link '(info-link "(modus-themes) Line highlighting"))
-
(make-obsolete 'modus-themes-intense-hl-line 'modus-themes-hl-line "1.3.0")
(defcustom modus-themes-hl-line nil
@@ -2661,6 +2756,22 @@ results with underlines."
:initialize #'custom-initialize-default
:link '(info-link "(modus-themes) Line numbers"))
+(defcustom modus-themes-intense-markup nil
+ "Use more intense markup in Org, Markdown, and related.
+The default style for certain markup types like inline code and
+verbatim constructs in Org and related major modes is a subtle
+foreground color combined with a subtle background.
+
+With a non-nil value (t), these constructs will use a more
+prominent background and foreground color combination instead."
+ :group 'modus-themes
+ :package-version '(modus-themes . "1.7.0")
+ :version "29.1"
+ :type 'boolean
+ :set #'modus-themes--set-option
+ :initialize #'custom-initialize-default
+ :link '(info-link "(modus-themes) Intense markup"))
+
(defcustom modus-themes-paren-match nil
"Control the style of matching parentheses or delimiters.
@@ -2866,12 +2977,14 @@ In user configuration files the form may look like this:
This is to account for red-green color deficiency.
-The present customization option should apply to all contexts where
-there can be a color-coded distinction between success and failure,
-to-do and done, and so on.
+The present customization option applies to all contexts where
+there can be a color-coded distinction between success or
+failure, to-do or done, mark for selection or deletion (e.g. in
+Dired), current and lazily highlighted search matches, and so on.
-Diffs, which have a red/green dichotomy by default, can also be
-configured to conform with deuteranopia: `modus-themes-diffs'."
+Diffs, which rely on a red/green dichotomy by default, can also
+be configured to meet the needs of users with deuteranopia via
+the option `modus-themes-diffs'."
:group 'modus-themes
:package-version '(modus-themes . "1.4.0")
:version "28.1"
@@ -2905,6 +3018,18 @@ colored into a uniform shade of shade of gray."
:initialize #'custom-initialize-default
:link '(info-link "(modus-themes) Mail citations"))
+(defcustom modus-themes-tabs-accented nil
+ "Toggle accented tab backgrounds, instead of the default gray.
+This affects the built-in tab-bar mode and tab-line mode, as well
+as the Centaur tabs package."
+ :group 'modus-themes
+ :package-version '(modus-themes . "1.6.0")
+ :version "28.1"
+ :type 'boolean
+ :set #'modus-themes--set-option
+ :initialize #'custom-initialize-default
+ :link '(info-link "(modus-themes) Tab style"))
+
;;; Internal functions
@@ -2965,7 +3090,7 @@ Those are stored in `modus-themes-faces' and
(defun modus-themes--fixed-pitch ()
"Conditional application of `fixed-pitch' inheritance."
- (unless modus-themes-no-mixed-fonts
+ (when modus-themes-mixed-fonts
(list :inherit 'fixed-pitch)))
(defun modus-themes--variable-pitch ()
@@ -2995,14 +3120,23 @@ combines with the theme's primary background (white/black)."
(list :background (or altbg 'unspecified) :foreground altfg)
(list :background mainbg :foreground mainfg)))
-(defun modus-themes--lang-check (underline subtlefg intensefg intensefg-alt subtlebg intensebg)
+(defun modus-themes--markup (mainfg intensefg &optional mainbg intensebg)
+ "Conditional use of colors for markup in Org and others.
+MAINBG is the default background. MAINFG is the default
+foreground. INTENSEBG and INTENSEFG must be more colorful
+variants."
+ (if modus-themes-intense-markup
+ (list :background (or intensebg 'unspecified) :foreground intensefg)
+ (list :background (or mainbg 'unspecified) :foreground mainfg)))
+
+(defun modus-themes--lang-check (underline subtlefg intensefg intensefg-alt subtlebg intensebg faintfg)
"Conditional use of foreground colors for language checkers.
UNDERLINE is a color-code value for the affected text's underline
property. SUBTLEFG and INTENSEFG follow the same color-coding
pattern and represent a value that is faint or vibrant
respectively. INTENSEFG-ALT is used when the intensity is high.
SUBTLEBG and INTENSEBG are color-coded background colors that
-differ in overall intensity."
+differ in overall intensity. FAINTFG is a nuanced color."
(let ((modus-themes-lang-checkers
(if (listp modus-themes-lang-checkers)
modus-themes-lang-checkers
@@ -3015,19 +3149,26 @@ differ in overall intensity."
('straight-underline '(straight-underline))))))
(list :underline
(list :color
- underline
+ (if (memq 'faint modus-themes-lang-checkers)
+ faintfg underline)
:style
(if (memq 'straight-underline modus-themes-lang-checkers)
'line 'wave))
:background
(cond
((and (memq 'background modus-themes-lang-checkers)
+ (memq 'faint modus-themes-lang-checkers))
+ subtlebg)
+ ((and (memq 'background modus-themes-lang-checkers)
(memq 'intense modus-themes-lang-checkers))
intensebg)
((memq 'background modus-themes-lang-checkers)
subtlebg))
:foreground
(cond
+ ((and (memq 'faint modus-themes-lang-checkers)
+ (memq 'text-also modus-themes-lang-checkers))
+ faintfg)
((and (memq 'background modus-themes-lang-checkers)
(memq 'intense modus-themes-lang-checkers))
intensefg-alt)
@@ -3253,6 +3394,18 @@ an alternative to the default value."
"Get cdr of KEY in ALIST."
(cdr (assoc key alist)))
+(defvar modus-themes--heading-weights
+ '( thin ultralight extralight light semilight regular medium
+ semibold bold heavy extrabold ultrabold)
+ "List of font weights used by `modus-themes--heading'.")
+
+(defun modus-themes--heading-weight (list)
+ "Search for `modus-themes--heading' weight in LIST."
+ (catch 'found
+ (dolist (elt list)
+ (when (memq elt modus-themes--heading-weights)
+ (throw 'found elt)))))
+
(defun modus-themes--heading (level fg fg-alt bg bg-gray border)
"Conditional styles for `modus-themes-headings'.
@@ -3264,8 +3417,9 @@ values. BG-GRAY is a gray background. BORDER is a color value
that combines well with the background and foreground."
(let* ((key (modus-themes--key-cdr level modus-themes-headings))
(style (or key (modus-themes--key-cdr t modus-themes-headings)))
+ (style-listp (listp style))
(modus-themes-headings
- (if (listp style)
+ (if style-listp
style
;; translation layer for legacy values
(pcase style
@@ -3286,15 +3440,16 @@ that combines well with the background and foreground."
('rainbow-section-no-bold '(no-bold rainbow background overline))
('section '(background overline))
('section-no-bold '(background overline no-bold)))))
- (var (if modus-themes-variable-pitch-headings
- 'variable-pitch
- 'unspecified))
+ (var (when modus-themes-variable-pitch-headings 'variable-pitch))
(varbold (if var
(append (list 'bold) (list var))
- 'bold)))
+ 'bold))
+ (weight (when style-listp (modus-themes--heading-weight style))))
(list :inherit
(cond
- ((memq 'no-bold modus-themes-headings)
+ ;; `no-bold' is for backward compatibility because we cannot
+ ;; deprecate a variable's value.
+ ((or weight (memq 'no-bold modus-themes-headings))
var)
(varbold))
:background
@@ -3312,6 +3467,8 @@ that combines well with the background and foreground."
((memq 'rainbow modus-themes-headings)
fg-alt)
(fg))
+ :weight
+ (or weight 'unspecified)
:overline
(if (memq 'overline modus-themes-headings)
border
@@ -3333,30 +3490,82 @@ FG is the foreground color to use."
:height height
:foreground fg)))
-(defun modus-themes--agenda-date (defaultfg grayscalefg &optional bold workaholicfg grayscaleworkaholicfg)
+(defun modus-themes--agenda-date (defaultfg grayscalefg &optional workaholicfg grayscaleworkaholicfg bg bold ul)
"Control the style of date headings in Org agenda buffers.
DEFAULTFG is the original accent color for the foreground.
-GRAYSCALEFG is a neutral color. Optional BOLD applies a bold
-weight. Optional WORKAHOLICFG and GRAYSCALEWORKAHOLICFG are
-alternative foreground colors."
- (let* ((properties (modus-themes--key-cdr 'header-date modus-themes-org-agenda))
- (weight (cond ((memq 'bold-all properties)
- 'bold)
- ((and bold (memq 'bold-today properties))
- 'bold)
- (t
- nil)))
- (fg (cond ((and (memq 'grayscale properties)
- (memq 'workaholic properties))
- (or grayscaleworkaholicfg grayscalefg))
- ((memq 'grayscale properties)
- grayscalefg)
- ((memq 'workaholic properties)
- (or workaholicfg defaultfg))
- (t
- defaultfg))))
- (list :inherit weight
- :foreground fg)))
+GRAYSCALEFG is a neutral color. Optional WORKAHOLICFG and
+GRAYSCALEWORKAHOLICFG are alternative foreground colors.
+Optional BG is a background color. Optional BOLD applies a bold
+weight. Optional UL applies an underline."
+ (let ((properties (modus-themes--key-cdr 'header-date modus-themes-org-agenda)))
+ (list :inherit
+ (cond
+ ((or (memq 'bold-all properties)
+ (and bold (memq 'bold-today properties)))
+ 'bold)
+ (t
+ 'unspecified))
+ :background
+ (unless (memq 'underline-today properties)
+ bg)
+ :foreground
+ (cond
+ ((and (memq 'grayscale properties)
+ (memq 'workaholic properties))
+ (or grayscaleworkaholicfg grayscalefg))
+ ((memq 'grayscale properties)
+ grayscalefg)
+ ((memq 'workaholic properties)
+ (or workaholicfg defaultfg))
+ (t
+ defaultfg))
+ :height
+ (if (memq 'scale-heading properties)
+ modus-themes-scale-1
+ 'unspecified)
+ :underline
+ (if (and ul (memq 'underline-today properties))
+ t
+ 'unspecified))))
+
+(defun modus-themes--agenda-event (fg-accent &optional varied)
+ "Control the style of the Org agenda events.
+FG-ACCENT is the accent color to use. Optional VARIED is a
+toggle to behave in accordance with the semantics of the `varied'
+property that the `event' key accepts in
+`modus-themes-org-agenda'."
+ (let ((properties (modus-themes--key-cdr 'event modus-themes-org-agenda)))
+ (list :height
+ (if (memq 'scale-small properties)
+ modus-themes-scale-small
+ 'unspecified)
+ :foreground
+ (cond
+ ((or (and (memq 'varied properties) varied)
+ (and (memq 'accented properties)
+ (memq 'varied properties)
+ varied))
+ 'unspecified)
+ ((memq 'accented properties)
+ fg-accent)
+ ('unspecified))
+ :inherit
+ (cond
+ ((and (memq 'italic properties)
+ (memq 'varied properties)
+ varied)
+ '(shadow italic))
+ ((and (memq 'accented properties)
+ (memq 'varied properties)
+ varied)
+ 'shadow)
+ ((or (and (memq 'varied properties) varied)
+ (and (memq 'italic properties) varied))
+ '(shadow italic))
+ ((and (memq 'italic properties)
+ (not (memq 'varied properties)))
+ '(shadow italic))
+ ('shadow)))))
(defun modus-themes--agenda-scheduled (defaultfg uniformfg rainbowfg)
"Control the style of the Org agenda scheduled tasks.
@@ -3419,8 +3628,15 @@ set to `rainbow'."
('rainbow (list :background bgaccent :foreground fgaccent))
(_ (list :background bg :foreground fg))))
+(defun modus-themes--mode-line-padding ()
+ "Determine mode line padding value.
+See `modus-themes--mode-line-attrs'."
+ (if (natnump modus-themes-mode-line-padding)
+ modus-themes-mode-line-padding
+ 6)) ; the default value
+
(defun modus-themes--mode-line-attrs
- (fg bg fg-alt bg-alt fg-accent bg-accent border border-3d &optional alt-style border-width fg-distant)
+ (fg bg fg-alt bg-alt fg-accent bg-accent border border-3d &optional alt-style fg-distant)
"Color combinations for `modus-themes-mode-line'.
FG and BG are the default colors. FG-ALT and BG-ALT are meant to
@@ -3432,13 +3648,11 @@ three-dimensional effect, where BORDER-3D is used instead.
Optional ALT-STYLE applies an appropriate style to the mode
line's box property.
-Optional BORDER-WIDTH specifies an integer for the width of the
-rectangle that produces the box effect.
-
Optional FG-DISTANT should be close to the main background
values. It is intended to be used as a distant-foreground
property."
- (let ((modus-themes-mode-line
+ (let ((padding (modus-themes--mode-line-padding))
+ (modus-themes-mode-line
(if (listp modus-themes-mode-line)
modus-themes-mode-line
;; translation layer for legacy values
@@ -3462,22 +3676,44 @@ property."
(cons fg-alt bg-alt))
((cons fg bg))))
(box (cond ((memq 'moody modus-themes-mode-line)
- nil)
+ 'unspecified)
+ ((and (memq '3d modus-themes-mode-line)
+ (memq 'padded modus-themes-mode-line))
+ (list :line-width padding
+ :color
+ (cond ((and (memq 'accented modus-themes-mode-line)
+ (memq 'borderless modus-themes-mode-line))
+ bg-accent)
+ ((or (memq 'accented modus-themes-mode-line)
+ (memq 'borderless modus-themes-mode-line))
+ bg)
+ (bg-alt))
+ :style (when alt-style 'released-button)))
+ ((and (memq 'accented modus-themes-mode-line)
+ (memq 'padded modus-themes-mode-line))
+ (list :line-width padding :color bg-accent))
+ ((memq 'padded modus-themes-mode-line)
+ (list :line-width padding :color bg))
((memq '3d modus-themes-mode-line)
- (list :line-width (or border-width 1)
+ (list :line-width 1
:color
(cond ((and (memq 'accented modus-themes-mode-line)
(memq 'borderless modus-themes-mode-line))
bg-accent)
((memq 'borderless modus-themes-mode-line) bg)
(border-3d))
- :style (and alt-style 'released-button)))
- ((or (memq 'borderless modus-themes-mode-line)
- (memq 'moody modus-themes-mode-line))
+ :style (when alt-style 'released-button)))
+ ((and (memq 'accented modus-themes-mode-line)
+ (memq 'borderless modus-themes-mode-line))
+ bg-accent)
+ ((memq 'borderless modus-themes-mode-line)
bg)
+ ((memq 'padded modus-themes-mode-line)
+ (list :line-width padding :color bg))
(border)))
- (line (cond ((not (memq 'moody modus-themes-mode-line))
- nil)
+ (line (cond ((not (or (memq 'moody modus-themes-mode-line)
+ (memq 'padded modus-themes-mode-line)))
+ 'unspecified)
((and (memq 'borderless modus-themes-mode-line)
(memq 'accented modus-themes-mode-line))
bg-accent)
@@ -3490,8 +3726,8 @@ property."
:overline line
:underline line
:distant-foreground
- (and (memq 'moody modus-themes-mode-line)
- fg-distant)))))
+ (when (memq 'moody modus-themes-mode-line)
+ fg-distant)))))
(defun modus-themes--diff
(fg-only-bg fg-only-fg mainbg mainfg altbg altfg &optional deuteranbg deuteranfg bg-only-fg)
@@ -3759,6 +3995,30 @@ desaturated counterpart."
('desaturated (list :foreground subtlefg))
(_ (list :foreground mainfg))))
+(defun modus-themes--tab (bg &optional bgaccent fg fgaccent box-p bold-p var-p)
+ "Helper function for tabs.
+BG is the default background, while BGACCENT is its more colorful
+alternative. Optional FG is a foreground color that combines
+with BG. Same principle FGACCENT.
+
+BOX-P and BOLD-P determine the use of a box property and the
+application of a bold weight, respectively. VAR-P controls the
+application of a variable-pitch font."
+ (let ((background (if modus-themes-tabs-accented (or bgaccent bg) bg))
+ (foreground (if modus-themes-tabs-accented (or fgaccent fg) fg)))
+ (list
+ :inherit (cond
+ ((and bold-p var-p)
+ (if modus-themes-variable-pitch-ui
+ '(variable-pitch bold)
+ '(bold)))
+ (bold-p 'bold)
+ (var-p (when modus-themes-variable-pitch-ui 'variable-pitch))
+ ('unspecified))
+ :background background
+ :foreground (or foreground 'unspecified)
+ :box (if box-p (list :line-width 2 :color background) 'unspecified))))
+
;;;; Utilities for DIY users
@@ -3874,6 +4134,7 @@ as when they are declared in the `:config' phase)."
(defun modus-themes-load-operandi ()
"Load `modus-operandi' and disable `modus-vivendi'.
Also run `modus-themes-after-load-theme-hook'."
+ (interactive)
(disable-theme 'modus-vivendi)
(load-theme 'modus-operandi t)
(run-hooks 'modus-themes-after-load-theme-hook))
@@ -3882,6 +4143,7 @@ Also run `modus-themes-after-load-theme-hook'."
(defun modus-themes-load-vivendi ()
"Load `modus-vivendi' and disable `modus-operandi'.
Also run `modus-themes-after-load-theme-hook'."
+ (interactive)
(disable-theme 'modus-operandi)
(load-theme 'modus-vivendi t)
(run-hooks 'modus-themes-after-load-theme-hook))
@@ -4036,7 +4298,11 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(modus-themes-pseudo-header ((,class :inherit bold :foreground ,fg-main)))
`(modus-themes-mark-alt ((,class :inherit bold :background ,bg-mark-alt :foreground ,fg-mark-alt)))
`(modus-themes-mark-del ((,class :inherit bold :background ,bg-mark-del :foreground ,fg-mark-del)))
- `(modus-themes-mark-sel ((,class :inherit bold :background ,bg-mark-sel :foreground ,fg-mark-sel)))
+ `(modus-themes-mark-sel ((,class :inherit bold
+ :background ,@(modus-themes--success-deuteran
+ cyan-refine-bg
+ bg-mark-sel)
+ :foreground ,fg-mark-sel)))
`(modus-themes-mark-symbol ((,class :inherit bold :foreground ,blue-alt)))
;;;;; heading levels
;; styles for regular headings used in Org, Markdown, Info, etc.
@@ -4092,13 +4358,13 @@ by virtue of calling either of `modus-themes-load-operandi' and
;;;;; language checkers
`(modus-themes-lang-error ((,class ,@(modus-themes--lang-check
fg-lang-underline-error fg-lang-error
- red red-refine-fg red-nuanced-bg red-refine-bg))))
+ red red-refine-fg red-nuanced-bg red-refine-bg red-faint))))
`(modus-themes-lang-note ((,class ,@(modus-themes--lang-check
fg-lang-underline-note fg-lang-note
- blue-alt blue-refine-fg blue-nuanced-bg blue-refine-bg))))
+ blue-alt blue-refine-fg blue-nuanced-bg blue-refine-bg blue-faint))))
`(modus-themes-lang-warning ((,class ,@(modus-themes--lang-check
fg-lang-underline-warning fg-lang-warning
- yellow yellow-refine-fg yellow-nuanced-bg yellow-refine-bg))))
+ yellow yellow-refine-fg yellow-nuanced-bg yellow-refine-bg yellow-faint))))
;;;;; other custom faces
`(modus-themes-bold ((,class ,@(modus-themes--bold-weight))))
`(modus-themes-hl-line ((,class ,@(modus-themes--hl-line
@@ -4107,7 +4373,9 @@ by virtue of calling either of `modus-themes-load-operandi' and
bg-region blue-intense-bg
fg-alt cyan-intense)
:extend t)))
- `(modus-themes-key-binding ((,class :inherit bold :foreground ,blue-alt-other)))
+ `(modus-themes-key-binding ((,class ,@(if (facep 'help-key-binding) ; check emacs28 face
+ (list :inherit 'help-key-binding)
+ (list :inherit 'bold :foreground blue-alt-other)))))
`(modus-themes-prompt ((,class ,@(modus-themes--prompt
cyan-alt-other blue-alt-other fg-alt
cyan-nuanced-bg blue-refine-bg fg-main
@@ -4141,15 +4409,16 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(buffer-menu-buffer ((,class :inherit bold)))
`(comint-highlight-input ((,class :inherit bold)))
`(comint-highlight-prompt ((,class :inherit modus-themes-prompt)))
+ `(confusingly-reordered ((,class :inherit modus-themes-lang-error)))
`(error ((,class :inherit bold :foreground ,red)))
`(escape-glyph ((,class :foreground ,fg-escape-char-construct)))
- `(file-name-shadow ((,class :foreground ,fg-unfocused)))
+ `(file-name-shadow ((,class :inherit (shadow italic))))
`(header-line ((,class ,@(modus-themes--variable-pitch-ui)
:background ,bg-header :foreground ,fg-header)))
`(header-line-highlight ((,class :inherit modus-themes-active-blue)))
`(help-argument-name ((,class :inherit modus-themes-slant :foreground ,cyan)))
- `(help-key-binding ((,class :box (:line-width (1 . -1) :color ,bg-region) ; NOTE: box syntax is for Emacs28
- :background ,bg-inactive)))
+ `(help-key-binding ((,class :box (:line-width (-1 . -1) :color ,bg-active) ; NOTE: box syntax is for Emacs28
+ :background ,bg-alt)))
`(homoglyph ((,class :foreground ,red-alt-faint)))
`(ibuffer-locked-buffer ((,class :foreground ,yellow-alt-other-faint)))
`(italic ((,class :slant italic)))
@@ -4181,7 +4450,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(widget-button-pressed ((,class :inherit widget-button :foreground ,magenta)))
`(widget-documentation ((,class :foreground ,green)))
`(widget-field ((,class :background ,bg-alt :foreground ,fg-dim)))
- `(widget-inactive ((,class :foreground ,fg-alt)))
+ `(widget-inactive ((,class :inherit shadow :background ,bg-dim)))
`(widget-single-line-field ((,class :inherit widget-field)))
;;;;; ag
`(ag-hit-face ((,class :foreground ,fg-special-cold)))
@@ -4233,6 +4502,25 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(annotate-annotation-secondary ((,class :inherit modus-themes-subtle-green)))
`(annotate-highlight ((,class :background ,blue-nuanced-bg :underline ,blue-intense)))
`(annotate-highlight-secondary ((,class :background ,green-nuanced-bg :underline ,green-intense)))
+;;;;; ansi-color
+ ;; Those are in Emacs28.
+ `(ansi-color-black ((,class :background "black" :foreground "black")))
+ `(ansi-color-blue ((,class :background ,blue :foreground ,blue)))
+ `(ansi-color-bold ((,class :inherit bold)))
+ `(ansi-color-bright-black ((,class :background "gray35" :foreground "gray35")))
+ `(ansi-color-bright-blue ((,class :background ,blue-alt :foreground ,blue-alt)))
+ `(ansi-color-bright-cyan ((,class :background ,cyan-alt-other :foreground ,cyan-alt-other)))
+ `(ansi-color-bright-green ((,class :background ,green-alt-other :foreground ,green-alt-other)))
+ `(ansi-color-bright-magenta ((,class :background ,magenta-alt-other :foreground ,magenta-alt-other)))
+ `(ansi-color-bright-red ((,class :background ,red-alt :foreground ,red-alt)))
+ `(ansi-color-bright-white ((,class :background "white" :foreground "white")))
+ `(ansi-color-bright-yellow ((,class :background ,yellow-alt :foreground ,yellow-alt)))
+ `(ansi-color-cyan ((,class :background ,cyan :foreground ,cyan)))
+ `(ansi-color-green ((,class :background ,green :foreground ,green)))
+ `(ansi-color-magenta ((,class :background ,magenta :foreground ,magenta)))
+ `(ansi-color-red ((,class :background ,red :foreground ,red)))
+ `(ansi-color-white ((,class :background "gray65" :foreground "gray65")))
+ `(ansi-color-yellow ((,class :background ,yellow :foreground ,yellow)))
;;;;; anzu
`(anzu-match-1 ((,class :inherit modus-themes-subtle-cyan)))
`(anzu-match-2 ((,class :inherit modus-themes-search-success)))
@@ -4251,7 +4539,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(apropos-keybinding ((,class :inherit modus-themes-key-binding)))
`(apropos-misc-button ((,class :inherit button
,@(modus-themes--link-color
- cyan-alt-other cyan-alt-other-faint))))
+ green-alt-other green-alt-other-faint))))
`(apropos-property ((,class :inherit modus-themes-bold :foreground ,magenta-alt)))
`(apropos-symbol ((,class :inherit modus-themes-pseudo-header)))
`(apropos-user-option-button ((,class :inherit button
@@ -4275,7 +4563,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(font-latex-bold-face ((,class :inherit bold :foreground ,fg-special-calm)))
`(font-latex-doctex-documentation-face ((,class :inherit modus-themes-slant :foreground ,fg-special-cold)))
`(font-latex-doctex-preprocessor-face ((,class :inherit modus-themes-bold :foreground ,red-alt-other)))
- `(font-latex-italic-face ((,class :inherit italic :foreground ,fg-special-calm)))
+ `(font-latex-italic-face ((,class :inherit italic)))
`(font-latex-math-face ((,class :foreground ,cyan-alt-other)))
`(font-latex-script-char-face ((,class :foreground ,cyan-alt-other)))
`(font-latex-sectioning-0-face ((,class :inherit modus-themes-variable-pitch :foreground ,blue-nuanced-fg)))
@@ -4351,7 +4639,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(bongo-marked-track ((,class :foreground ,fg-mark-alt)))
`(bongo-marked-track-line ((,class :background ,bg-mark-alt)))
`(bongo-played-track ((,class :foreground ,fg-unfocused :strike-through t)))
- `(bongo-track-length ((,class :foreground ,fg-alt)))
+ `(bongo-track-length ((,class :inherit shadow)))
`(bongo-track-title ((,class :foreground ,blue-active)))
`(bongo-unfilled-seek-bar ((,class :background ,bg-special-cold :foreground ,fg-main)))
;;;;; boon
@@ -4360,7 +4648,8 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(boon-modeline-off ((,class :inherit modus-themes-active-yellow)))
`(boon-modeline-spc ((,class :inherit modus-themes-active-green)))
;;;;; bookmark
- `(bookmark-face ((,class :inherit modus-themes-special-warm :extend t)))
+ `(bookmark-face ((,class :inherit modus-themes-fringe-cyan)))
+ `(bookmark-menu-bookmark ((,class :inherit bold)))
;;;;; breakpoint (built-in gdb-mi.el)
`(breakpoint-disabled ((,class :inherit shadow)))
`(breakpoint-enabled ((,class :inherit bold :foreground ,red)))
@@ -4406,15 +4695,15 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(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 :foreground ,bg-main)))
- `(centaur-tabs-selected ((,class :inherit bold :background ,bg-tab-active :foreground ,fg-main)))
- `(centaur-tabs-selected-modified ((,class :inherit italic :background ,bg-tab-active :foreground ,fg-main)))
- `(centaur-tabs-unselected ((,class :background ,bg-tab-inactive :foreground ,fg-dim)))
- `(centaur-tabs-unselected-modified ((,class :inherit italic :background ,bg-tab-inactive :foreground ,fg-dim)))
+ `(centaur-tabs-default (( )))
+ `(centaur-tabs-selected ((,class ,@(modus-themes--tab bg-tab-active nil nil nil t t))))
+ `(centaur-tabs-selected-modified ((,class :inherit (italic centaur-tabs-selected))))
+ `(centaur-tabs-unselected ((,class ,@(modus-themes--tab bg-tab-inactive bg-tab-inactive-accent fg-dim nil t))))
+ `(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')
- `(change-log-acknowledgment ((,class :foreground ,fg-alt)))
+ `(change-log-acknowledgment ((,class :inherit shadow)))
`(change-log-conditionals ((,class :foreground ,yellow)))
`(change-log-date ((,class :foreground ,cyan)))
`(change-log-email ((,class :foreground ,cyan-alt-other)))
@@ -4454,7 +4743,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(cider-stacktrace-filter-active-face ((,class :foreground ,cyan-alt :underline t)))
`(cider-stacktrace-filter-inactive-face ((,class :foreground ,cyan-alt)))
`(cider-stacktrace-fn-face ((,class :inherit bold :foreground ,fg-main)))
- `(cider-stacktrace-ns-face ((,class :inherit italic :foreground ,fg-alt)))
+ `(cider-stacktrace-ns-face ((,class :inherit (shadow italic))))
`(cider-stacktrace-promoted-button-face ((,class :box (:line-width 3 :color ,fg-alt :style released-button) :foreground ,red)))
`(cider-stacktrace-suppressed-button-face ((,class :box (:line-width 3 :color ,fg-alt :style pressed-button)
:background ,bg-alt :foreground ,fg-alt)))
@@ -4503,6 +4792,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(company-tooltip-annotation-selection ((,class :inherit bold :foreground ,fg-main)))
`(company-tooltip-common ((,class :inherit bold :foreground ,blue-alt)))
`(company-tooltip-common-selection ((,class :foreground ,fg-main)))
+ `(company-tooltip-deprecated ((,class :inherit company-tooltip :strike-through t)))
`(company-tooltip-mouse ((,class :inherit modus-themes-intense-blue)))
`(company-tooltip-search ((,class :inherit (modus-themes-search-success-lazy bold))))
`(company-tooltip-search-selection ((,class :inherit (modus-themes-search-success bold) :underline t)))
@@ -4543,10 +4833,10 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(consult-preview-error ((,class :inherit modus-themes-intense-red)))
`(consult-preview-line ((,class :background ,bg-hl-alt-intense)))
;;;;; corfu
- `(corfu-background ((,class :background ,bg-alt)))
`(corfu-current ((,class :inherit bold :background ,cyan-subtle-bg)))
`(corfu-bar ((,class :background ,fg-alt)))
`(corfu-border ((,class :background ,bg-active)))
+ `(corfu-default ((,class :background ,bg-alt)))
;;;;; counsel
`(counsel-active-mode ((,class :foreground ,magenta-alt-other)))
`(counsel-application-name ((,class :foreground ,red-alt-other)))
@@ -4590,6 +4880,8 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(ctrlf-highlight-active ((,class :inherit (modus-themes-search-success bold))))
`(ctrlf-highlight-line ((,class :inherit modus-themes-hl-line)))
`(ctrlf-highlight-passive ((,class :inherit modus-themes-search-success-lazy)))
+;;;;; cursor-flash
+ `(cursor-flash-face ((,class :inherit modus-themes-intense-blue)))
;;;;; custom (M-x customize)
`(custom-button ((,class :box (:line-width 2 :color nil :style released-button)
:background ,bg-active :foreground ,fg-main)))
@@ -4601,7 +4893,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(custom-comment ((,class :inherit shadow)))
`(custom-comment-tag ((,class :background ,bg-alt :foreground ,yellow-alt-other)))
`(custom-face-tag ((,class :inherit bold :foreground ,blue-intense)))
- `(custom-group-tag ((,class :inherit bold :foreground ,green-intense)))
+ `(custom-group-tag ((,class :inherit modus-themes-pseudo-header :foreground ,magenta-alt)))
`(custom-group-tag-1 ((,class :inherit modus-themes-special-warm)))
`(custom-invalid ((,class :inherit (modus-themes-intense-red bold))))
`(custom-modified ((,class :inherit modus-themes-subtle-cyan)))
@@ -4657,7 +4949,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(deft-filter-string-face ((,class :foreground ,green-intense)))
`(deft-header-face ((,class :inherit bold :foreground ,fg-special-warm)))
`(deft-separator-face ((,class :inherit shadow)))
- `(deft-summary-face ((,class :inherit modus-themes-slant :foreground ,fg-alt)))
+ `(deft-summary-face ((,class :inherit (shadow modus-themes-slant))))
`(deft-time-face ((,class :foreground ,fg-special-cold)))
`(deft-title-face ((,class :inherit bold :foreground ,fg-main)))
;;;;; dictionary
@@ -4705,7 +4997,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(dir-treeview-audio-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,magenta-alt)))
`(dir-treeview-control-face ((,class :inherit shadow)))
`(dir-treeview-control-mouse-face ((,class :inherit highlight)))
- `(dir-treeview-default-icon-face ((,class :inherit bold :family "Font Awesome" :foreground ,fg-alt)))
+ `(dir-treeview-default-icon-face ((,class :inherit (shadow bold) :family "Font Awesome")))
`(dir-treeview-default-filename-face ((,class :foreground ,fg-main)))
`(dir-treeview-directory-face ((,class :foreground ,blue)))
`(dir-treeview-directory-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,blue-alt)))
@@ -4765,24 +5057,24 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(diredfl-autofile-name ((,class :inherit modus-themes-special-cold)))
`(diredfl-compressed-file-name ((,class :foreground ,fg-special-warm)))
`(diredfl-compressed-file-suffix ((,class :foreground ,red-alt)))
- `(diredfl-date-time ((,class :foreground ,cyan-alt-other)))
+ `(diredfl-date-time ((,class :foreground ,cyan)))
`(diredfl-deletion ((,class :inherit modus-themes-mark-del)))
`(diredfl-deletion-file-name ((,class :inherit modus-themes-mark-del)))
`(diredfl-dir-heading ((,class :inherit modus-themes-pseudo-header)))
`(diredfl-dir-name ((,class :inherit dired-directory)))
`(diredfl-dir-priv ((,class :foreground ,blue-alt)))
- `(diredfl-exec-priv ((,class :foreground ,magenta)))
+ `(diredfl-exec-priv ((,class :foreground ,magenta-alt)))
`(diredfl-executable-tag ((,class :foreground ,magenta-alt)))
`(diredfl-file-name ((,class :foreground ,fg-main)))
- `(diredfl-file-suffix ((,class :foreground ,cyan)))
+ `(diredfl-file-suffix ((,class :foreground ,magenta-alt-other)))
`(diredfl-flag-mark ((,class :inherit modus-themes-mark-sel)))
`(diredfl-flag-mark-line ((,class :inherit modus-themes-mark-sel)))
`(diredfl-ignored-file-name ((,class :inherit shadow)))
`(diredfl-link-priv ((,class :foreground ,blue-alt-other)))
- `(diredfl-no-priv ((,class :inherit shadow)))
- `(diredfl-number ((,class :foreground ,cyan-alt)))
+ `(diredfl-no-priv ((,class :foreground "gray50")))
+ `(diredfl-number ((,class :foreground ,cyan-alt-other-faint)))
`(diredfl-other-priv ((,class :foreground ,yellow)))
- `(diredfl-rare-priv ((,class :foreground ,red-alt)))
+ `(diredfl-rare-priv ((,class :foreground ,red)))
`(diredfl-read-priv ((,class :foreground ,fg-main)))
`(diredfl-symlink ((,class :inherit dired-symlink)))
`(diredfl-tagged-autofile-name ((,class :inherit modus-themes-refine-magenta)))
@@ -4791,27 +5083,27 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(diredp-autofile-name ((,class :inherit modus-themes-special-cold)))
`(diredp-compressed-file-name ((,class :foreground ,fg-special-warm)))
`(diredp-compressed-file-suffix ((,class :foreground ,red-alt)))
- `(diredp-date-time ((,class :foreground ,cyan-alt-other)))
+ `(diredp-date-time ((,class :foreground ,cyan)))
`(diredp-deletion ((,class :inherit modus-themes-mark-del)))
`(diredp-deletion-file-name ((,class :inherit modus-themes-mark-del)))
`(diredp-dir-heading ((,class :inherit modus-themes-pseudo-header)))
`(diredp-dir-name ((,class :inherit dired-directory)))
`(diredp-dir-priv ((,class :foreground ,blue-alt)))
- `(diredp-exec-priv ((,class :foreground ,magenta)))
+ `(diredp-exec-priv ((,class :foreground ,magenta-alt)))
`(diredp-executable-tag ((,class :foreground ,magenta-alt)))
`(diredp-file-name ((,class :foreground ,fg-main)))
- `(diredp-file-suffix ((,class :foreground ,cyan)))
+ `(diredp-file-suffix ((,class :foreground ,magenta-alt-other)))
`(diredp-flag-mark ((,class :inherit modus-themes-mark-sel)))
`(diredp-flag-mark-line ((,class :inherit modus-themes-mark-sel)))
`(diredp-ignored-file-name ((,class :inherit shadow)))
`(diredp-link-priv ((,class :foreground ,blue-alt-other)))
`(diredp-mode-line-flagged ((,class :foreground ,red-active)))
`(diredp-mode-line-marked ((,class :foreground ,green-active)))
- `(diredp-no-priv ((,class :inherit shadow)))
- `(diredp-number ((,class :foreground ,cyan-alt)))
+ `(diredp-no-priv ((,class :foreground "gray50")))
+ `(diredp-number ((,class :foreground ,cyan-alt-other-faint)))
`(diredp-omit-file-name ((,class :inherit shadow :strike-through t)))
`(diredp-other-priv ((,class :foreground ,yellow)))
- `(diredp-rare-priv ((,class :foreground ,red-alt)))
+ `(diredp-rare-priv ((,class :foreground ,red)))
`(diredp-read-priv ((,class :foreground ,fg-main)))
`(diredp-symlink ((,class :inherit dired-symlink)))
`(diredp-tagged-autofile-name ((,class :inherit modus-themes-refine-magenta)))
@@ -4887,13 +5179,13 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(ebdb-phone-default ((,class :foreground ,cyan)))
`(eieio-custom-slot-tag-face ((,class :foreground ,red-alt)))
;;;;; ediff
- `(ediff-current-diff-A ((,class :inherit modus-themes-diff-focus-removed)))
+ `(ediff-current-diff-A ((,class :inherit modus-themes-diff-removed)))
`(ediff-current-diff-Ancestor ((,class ,@(modus-themes--diff
bg-alt fg-special-cold
bg-special-cold fg-special-cold
blue-nuanced-bg blue))))
- `(ediff-current-diff-B ((,class :inherit modus-themes-diff-focus-added)))
- `(ediff-current-diff-C ((,class :inherit modus-themes-diff-focus-changed)))
+ `(ediff-current-diff-B ((,class :inherit modus-themes-diff-added)))
+ `(ediff-current-diff-C ((,class :inherit modus-themes-diff-changed)))
`(ediff-even-diff-A ((,class :background ,bg-alt)))
`(ediff-even-diff-Ancestor ((,class :background ,bg-alt)))
`(ediff-even-diff-B ((,class :background ,bg-alt)))
@@ -4939,9 +5231,19 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(elfeed-score-error-level-face ((,class :foreground ,red)))
`(elfeed-score-info-level-face ((,class :foreground ,cyan)))
`(elfeed-score-warn-level-face ((,class :foreground ,yellow)))
+;;;;; elpher
+ `(elpher-gemini-heading1 ((,class :inherit modus-themes-heading-1)))
+ `(elpher-gemini-heading2 ((,class :inherit modus-themes-heading-2)))
+ `(elpher-gemini-heading3 ((,class :inherit modus-themes-heading-3)))
;;;;; embark
`(embark-keybinding ((,class :inherit modus-themes-key-binding)))
;;;;; emms
+ `(emms-browser-album-face ((,class :foreground ,magenta-alt-other ,@(modus-themes--scale modus-themes-scale-2))))
+ `(emms-browser-artist-face ((,class :foreground ,cyan ,@(modus-themes--scale modus-themes-scale-3))))
+ `(emms-browser-composer-face ((,class :foreground ,magenta-alt ,@(modus-themes--scale modus-themes-scale-3))))
+ `(emms-browser-performer-face ((,class :inherit emms-browser-artist-face)))
+ `(emms-browser-track-face ((,class :inherit emms-playlist-track-face)))
+ `(emms-browser-year/genre-face ((,class :foreground ,cyan-alt-other ,@(modus-themes--scale modus-themes-scale-4))))
`(emms-playlist-track-face ((,class :foreground ,blue-alt)))
`(emms-playlist-selected-face ((,class :inherit bold :foreground ,blue-alt-other)))
`(emms-metaplaylist-mode-current-face ((,class :inherit emms-playlist-selected-face)))
@@ -5317,8 +5619,8 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(git-gutter-fr:modified ((,class :inherit modus-themes-fringe-yellow)))
;;;;; git-{gutter,fringe}+
`(git-gutter+-added ((,class :inherit ,@(modus-themes--diff-deuteran
- 'modus-themes-fringe-blue
- 'modus-themes-fringe-green))))
+ 'modus-themes-fringe-blue
+ 'modus-themes-fringe-green))))
`(git-gutter+-deleted ((,class :inherit modus-themes-fringe-red)))
`(git-gutter+-modified ((,class :inherit modus-themes-fringe-yellow)))
`(git-gutter+-separator ((,class :inherit modus-themes-fringe-cyan)))
@@ -5659,6 +5961,10 @@ by virtue of calling either of `modus-themes-load-operandi' and
,@(modus-themes--standard-completions
magenta bg-alt
bg-active fg-main))))
+ `(icomplete-selected-match ((,class :inherit bold :foreground ,fg-main
+ :background ,@(pcase modus-themes-completions
+ ('opinionated (list bg-active))
+ (_ (list bg-inactive))))))
;;;;; icomplete-vertical
`(icomplete-vertical-separator ((,class :inherit shadow)))
;;;;; ido-mode
@@ -5680,6 +5986,11 @@ by virtue of calling either of `modus-themes-load-operandi' and
;;;;; iflipb
`(iflipb-current-buffer-face ((,class :inherit bold :foreground ,cyan-alt)))
`(iflipb-other-buffer-face ((,class :inherit shadow)))
+;;;;; image-dired
+ `(image-dired-thumb-flagged ((,class :background ,red-intense-bg)))
+ `(image-dired-thumb-mark ((,class :background ,@(modus-themes--success-deuteran
+ cyan-intense-bg
+ green-intense-bg))))
;;;;; imenu-list
`(imenu-list-entry-face-0 ((,class :foreground ,cyan)))
`(imenu-list-entry-face-1 ((,class :foreground ,blue)))
@@ -5691,7 +6002,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(imenu-list-entry-subalist-face-3 ((,class :inherit bold :foreground ,red-alt-other :underline t)))
;;;;; indium
`(indium-breakpoint-face ((,class :foreground ,red-active)))
- `(indium-frame-url-face ((,class :inherit button :foreground ,fg-alt)))
+ `(indium-frame-url-face ((,class :inherit (shadow button))))
`(indium-keyword-face ((,class :inherit font-lock-keyword-face)))
`(indium-litable-face ((,class :inherit modus-themes-slant :foreground ,fg-special-warm)))
`(indium-repl-error-face ((,class :inherit error)))
@@ -5699,8 +6010,9 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(indium-repl-stdout-face ((,class :foreground ,fg-main)))
;;;;; info
`(Info-quoted ((,class :inherit modus-themes-fixed-pitch ; the capitalization is canonical
- :background ,bg-alt :foreground ,fg-special-calm)))
- `(info-header-node ((,class :inherit bold :foreground ,fg-alt)))
+ ,@(modus-themes--markup fg-special-calm magenta-alt
+ bg-alt magenta-nuanced-bg))))
+ `(info-header-node ((,class :inherit (shadow bold))))
`(info-header-xref ((,class :foreground ,blue-active)))
`(info-index-match ((,class :inherit match)))
`(info-menu-header ((,class :inherit modus-themes-heading-3)))
@@ -5711,7 +6023,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(info-title-3 ((,class :inherit modus-themes-heading-3)))
`(info-title-4 ((,class :inherit modus-themes-heading-4)))
;;;;; info-colors
- `(info-colors-lisp-code-block ((,class :inherit fixed-pitch)))
+ `(info-colors-lisp-code-block ((,class :inherit modus-themes-fixed-pitch)))
`(info-colors-ref-item-command ((,class :inherit font-lock-function-name-face)))
`(info-colors-ref-item-constant ((,class :inherit font-lock-constant-face)))
`(info-colors-ref-item-function ((,class :inherit font-lock-function-name-face)))
@@ -5918,7 +6230,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(lsp-face-semhl-variable ((,class :foreground ,cyan)))
`(lsp-face-semhl-variable-local ((,class :foreground ,cyan)))
`(lsp-face-semhl-variable-parameter ((,class :foreground ,cyan-alt-other)))
- `(lsp-lens-face ((,class :height 0.8 :foreground ,fg-alt)))
+ `(lsp-lens-face ((,class :inherit shadow :height 0.8)))
`(lsp-lens-mouse-face ((,class :height 0.8 :foreground ,blue-alt-other :underline t)))
`(lsp-ui-doc-background ((,class :background ,bg-alt)))
`(lsp-ui-doc-header ((,class :background ,bg-header :foreground ,fg-header)))
@@ -6074,27 +6386,41 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(Man-reverse ((,class :inherit modus-themes-subtle-magenta)))
`(Man-underline ((,class :foreground ,cyan :underline t)))
;;;;; marginalia
- `(marginalia-archive ((,class :foreground ,green-nuanced-fg)))
- `(marginalia-date ((,class :foreground ,blue-nuanced-fg)))
- `(marginalia-char ((,class :foreground ,red-active)))
- `(marginalia-documentation ((,class :foreground ,fg-special-cold :inherit modus-themes-slant)))
- `(marginalia-file-modes ((,class :inherit shadow)))
- `(marginalia-file-name ((,class :foreground ,fg-special-mild)))
- `(marginalia-file-owner ((,class :foreground ,red-nuanced-fg)))
+ `(marginalia-archive ((,class :foreground ,cyan-alt-other)))
+ `(marginalia-char ((,class :foreground ,magenta)))
+ `(marginalia-date ((,class :foreground ,cyan)))
+ `(marginalia-documentation ((,class :inherit modus-themes-slant :foreground ,fg-docstring)))
+ `(marginalia-file-name ((,class :foreground ,blue-faint)))
+ `(marginalia-file-owner ((,class :foreground ,red-faint)))
+ `(marginalia-file-priv-dir ((,class :foreground ,blue-alt)))
+ `(marginalia-file-priv-exec ((,class :foreground ,magenta-alt)))
+ `(marginalia-file-priv-link ((,class :foreground ,blue-alt-other)))
+ `(marginalia-file-priv-no ((,class :foreground "gray50")))
+ `(marginalia-file-priv-other ((,class :foreground ,yellow)))
+ `(marginalia-file-priv-rare ((,class :foreground ,red)))
+ `(marginalia-file-priv-read ((,class :foreground ,fg-main)))
+ `(marginalia-file-priv-write ((,class :foreground ,cyan)))
;; Here we make an exception of not applying the bespoke
;; `modus-themes-key-binding' for two reasons: (1) completion
;; highlights can be fairly intense, so we do not want more
;; components to compete with them for attention, (2) the
;; `marginalia-key' may not be used for key bindings specifically,
;; so we might end up applying styles in places we should not.
- `(marginalia-key ((,class :foreground ,magenta-active)))
- `(marginalia-mode ((,class :foreground ,cyan-active)))
- `(marginalia-modified ((,class :foreground ,yellow-active)))
- `(marginalia-number ((,class :foreground ,blue-active)))
- `(marginalia-size ((,class :foreground ,green-active)))
- `(marginalia-type ((,class :foreground ,fg-special-warm)))
- `(marginalia-variable ((,class :foreground ,yellow-nuanced-fg)))
- `(marginalia-version ((,class :foreground ,cyan-active)))
+ `(marginalia-function ((,class :foreground ,magenta-alt-faint)))
+ `(marginalia-key ((,class :foreground ,magenta-alt-other)))
+ `(marginalia-lighter ((,class :foreground ,blue-alt)))
+ `(marginalia-list ((,class :foreground ,magenta-alt-other-faint)))
+ `(marginalia-mode ((,class :foreground ,cyan)))
+ `(marginalia-modified ((,class :foreground ,magenta-alt-faint)))
+ `(marginalia-null ((,class :inherit shadow)))
+ `(marginalia-number ((,class :foreground ,cyan)))
+ `(marginalia-size ((,class :foreground ,cyan-alt-other-faint)))
+ `(marginalia-string ((,class :foreground ,blue-alt)))
+ `(marginalia-symbol ((,class :foreground ,blue-alt-other-faint)))
+ `(marginalia-true ((,class :foreground ,fg-main)))
+ `(marginalia-type ((,class :foreground ,cyan-alt-other)))
+ `(marginalia-value ((,class :foreground ,cyan)))
+ `(marginalia-version ((,class :foreground ,cyan)))
;;;;; markdown-mode
`(markdown-blockquote-face ((,class :inherit modus-themes-slant :foreground ,fg-special-cold)))
`(markdown-bold-face ((,class :inherit bold)))
@@ -6124,13 +6450,14 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(markdown-html-tag-name-face ((,class :inherit modus-themes-fixed-pitch
:foreground ,magenta-alt)))
`(markdown-inline-code-face ((,class :inherit modus-themes-fixed-pitch
- :background ,bg-alt :foreground ,fg-special-calm)))
- `(markdown-italic-face ((,class :inherit italic :foreground ,fg-special-cold)))
+ ,@(modus-themes--markup fg-special-calm magenta-alt
+ bg-alt magenta-nuanced-bg))))
+ `(markdown-italic-face ((,class :inherit italic)))
`(markdown-language-info-face ((,class :inherit modus-themes-fixed-pitch
:foreground ,fg-special-cold)))
`(markdown-language-keyword-face ((,class :inherit modus-themes-fixed-pitch
- :background ,bg-alt
- :foreground ,fg-alt)))
+ ,@(modus-themes--markup fg-alt red-alt
+ bg-alt red-nuanced-bg))))
`(markdown-line-break-face ((,class :inherit modus-themes-refine-cyan :underline t)))
`(markdown-link-face ((,class :inherit button)))
`(markdown-link-title-face ((,class :inherit modus-themes-slant :foreground ,fg-special-cold)))
@@ -6159,12 +6486,12 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(markup-error-face ((,class :inherit error)))
`(markup-gen-face ((,class :foreground ,magenta-alt)))
`(markup-internal-reference-face ((,class :foreground ,fg-alt :underline ,bg-region)))
- `(markup-italic-face ((,class :inherit italic :foreground ,fg-special-cold)))
+ `(markup-italic-face ((,class :inherit italic)))
`(markup-list-face ((,class :inherit modus-themes-special-cold)))
`(markup-meta-face ((,class :inherit shadow)))
`(markup-meta-hide-face ((,class :foreground "gray50")))
`(markup-reference-face ((,class :foreground ,blue-alt :underline ,bg-region)))
- `(markup-replacement-face ((,class :inherit fixed-pitch :foreground ,red-alt)))
+ `(markup-replacement-face ((,class :inherit modus-themes-fixed-pitch :foreground ,red-alt)))
`(markup-secondary-text-face ((,class :height 0.9 :foreground ,cyan-alt-other)))
`(markup-small-face ((,class :inherit markup-gen-face :height 0.9)))
`(markup-strong-face ((,class :inherit markup-bold-face)))
@@ -6236,7 +6563,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
fg-dim bg-active
fg-main bg-active-accent
fg-alt bg-active
- 'alt-style nil bg-main))))
+ 'alt-style bg-main))))
`(mode-line-buffer-id ((,class :inherit bold)))
`(mode-line-emphasis ((,class :inherit bold :foreground ,blue-active)))
`(mode-line-highlight ((,class :inherit modus-themes-active-blue :box (:line-width -1 :style pressed-button))))
@@ -6273,7 +6600,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(mu4e-contact-face ((,class :inherit message-header-to)))
`(mu4e-context-face ((,class :foreground ,blue-active)))
`(mu4e-draft-face ((,class :foreground ,magenta-alt)))
- `(mu4e-flagged-face ((,class :foreground ,red-alt)))
+ `(mu4e-flagged-face ((,class :foreground ,red-alt-other)))
`(mu4e-footer-face ((,class :inherit modus-themes-slant :foreground ,fg-special-cold)))
`(mu4e-forwarded-face ((,class :foreground ,magenta-alt-other)))
`(mu4e-header-face ((,class :inherit shadow)))
@@ -6294,7 +6621,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(mu4e-title-face ((,class :foreground ,fg-main)))
`(mu4e-trashed-face ((,class :foreground ,red)))
`(mu4e-unread-face ((,class :inherit bold)))
- `(mu4e-url-number-face ((,class :foreground ,fg-alt)))
+ `(mu4e-url-number-face ((,class :inherit shadow)))
`(mu4e-view-body-face ((,class :foreground ,fg-main)))
`(mu4e-warning-face ((,class :inherit warning)))
;;;;; mu4e-conversation
@@ -6313,6 +6640,17 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(mc/cursor-bar-face ((,class :height 1 :background ,fg-main)))
`(mc/cursor-face ((,class :inverse-video t)))
`(mc/region-face ((,class :inherit region)))
+;;;;; nano-modeline
+ `(nano-modeline-active-primary ((,class :inherit mode-line :foreground ,fg-special-mild)))
+ `(nano-modeline-active-secondary ((,class :inherit mode-line :foreground ,fg-special-cold)))
+ `(nano-modeline-active-status-** ((,class :inherit mode-line :background ,yellow-subtle-bg)))
+ `(nano-modeline-active-status-RO ((,class :inherit mode-line :background ,red-subtle-bg)))
+ `(nano-modeline-active-status-RW ((,class :inherit mode-line :background ,cyan-subtle-bg)))
+ `(nano-modeline-inactive-primary ((,class :inherit mode-line-inactive :foreground ,fg-inactive)))
+ `(nano-modeline-inactive-secondary ((,class :inherit mode-line-inactive :foreground ,fg-inactive)))
+ `(nano-modeline-inactive-status-** ((,class :inherit mode-line-inactive :foreground ,yellow-active)))
+ `(nano-modeline-inactive-status-RO ((,class :inherit mode-line-inactive :foreground ,red-active)))
+ `(nano-modeline-inactive-status-RW ((,class :inherit mode-line-inactive :foreground ,cyan-active)))
;;;;; neotree
`(neo-banner-face ((,class :foreground ,magenta)))
`(neo-button-face ((,class :inherit button)))
@@ -6322,7 +6660,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(neo-header-face ((,class :inherit bold :foreground ,fg-main)))
`(neo-root-dir-face ((,class :inherit bold :foreground ,cyan-alt)))
`(neo-vc-added-face ((,class :foreground ,@(modus-themes--diff-deuteran blue green))))
- `(neo-vc-conflict-face ((,class :inherit bold :foreground ,red)))
+ `(neo-vc-conflict-face ((,class :inherit error)))
`(neo-vc-default-face ((,class :foreground ,fg-main)))
`(neo-vc-edited-face ((,class :foreground ,yellow)))
`(neo-vc-ignored-face ((,class :foreground ,fg-inactive)))
@@ -6343,10 +6681,11 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(notmuch-crypto-signature-good-key ((,class :inherit bold :foreground ,cyan)))
`(notmuch-crypto-signature-unknown ((,class :inherit warning)))
`(notmuch-hello-logo-background ((,class :background "gray50")))
+ `(notmuch-jump-key ((,class :inherit modus-themes-key-binding)))
`(notmuch-message-summary-face ((,class :inherit (bold modus-themes-nuanced-cyan))))
`(notmuch-search-count ((,class :inherit shadow)))
`(notmuch-search-date ((,class :foreground ,cyan)))
- `(notmuch-search-flagged-face ((,class :foreground ,red-alt)))
+ `(notmuch-search-flagged-face ((,class :foreground ,red-alt-other)))
`(notmuch-search-matching-authors ((,class :foreground ,fg-special-cold)))
`(notmuch-search-non-matching-authors ((,class :inherit shadow)))
`(notmuch-search-subject ((,class :foreground ,fg-main)))
@@ -6414,16 +6753,21 @@ by virtue of calling either of `modus-themes-load-operandi' and
yellow yellow-nuanced-bg
yellow-refine-bg yellow-refine-fg))))
;;;;; org
- `(org-agenda-calendar-event ((,class :inherit shadow)))
- `(org-agenda-calendar-sexp ((,class :inherit (modus-themes-slant shadow))))
+ `(org-agenda-calendar-event ((,class ,@(modus-themes--agenda-event blue-alt))))
+ `(org-agenda-calendar-sexp ((,class ,@(modus-themes--agenda-event blue-alt t))))
`(org-agenda-clocking ((,class :inherit modus-themes-special-cold :extend t)))
`(org-agenda-column-dateline ((,class :background ,bg-alt)))
`(org-agenda-current-time ((,class :foreground ,blue-alt-other-faint)))
- `(org-agenda-date ((,class ,@(modus-themes--agenda-date cyan fg-main nil))))
- `(org-agenda-date-today ((,class :background ,bg-active
- ,@(modus-themes--agenda-date blue-active fg-main t cyan-active))))
- `(org-agenda-date-weekend ((,class ,@(modus-themes--agenda-date cyan-alt-other fg-alt nil cyan fg-main))))
- `(org-agenda-diary ((,class :inherit shadow)))
+ `(org-agenda-date ((,class ,@(modus-themes--agenda-date cyan fg-main))))
+ `(org-agenda-date-today ((,class ,@(modus-themes--agenda-date cyan fg-main
+ nil nil
+ bg-inactive t t))))
+ `(org-agenda-date-weekend ((,class ,@(modus-themes--agenda-date cyan-alt-other-faint fg-alt
+ cyan fg-main))))
+ `(org-agenda-date-weekend-today ((,class ,@(modus-themes--agenda-date cyan-alt-other-faint fg-alt
+ cyan fg-main
+ bg-inactive t t))))
+ `(org-agenda-diary ((,class :inherit org-agenda-calendar-sexp)))
`(org-agenda-dimmed-todo-face ((,class :inherit shadow)))
`(org-agenda-done ((,class :foreground ,@(modus-themes--success-deuteran
blue-nuanced-fg
@@ -6434,6 +6778,8 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(org-agenda-filter-tags ((,class :inherit bold :foreground ,cyan-active)))
`(org-agenda-restriction-lock ((,class :background ,bg-dim :foreground ,fg-dim)))
`(org-agenda-structure ((,class ,@(modus-themes--agenda-structure blue-alt))))
+ `(org-agenda-structure-filter ((,class :inherit org-agenda-structure :foreground ,yellow)))
+ `(org-agenda-structure-secondary ((,class :foreground ,cyan)))
`(org-archived ((,class :background ,bg-alt :foreground ,fg-alt)))
`(org-block ((,class :inherit modus-themes-fixed-pitch
,@(modus-themes--org-block bg-dim fg-main))))
@@ -6448,22 +6794,24 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(org-checkbox-statistics-todo ((,class :inherit org-todo)))
`(org-clock-overlay ((,class :inherit modus-themes-special-cold)))
`(org-code ((,class :inherit modus-themes-fixed-pitch
- :background ,bg-alt :foreground ,fg-special-mild)))
+ ,@(modus-themes--markup fg-special-mild green-alt-other
+ bg-alt green-nuanced-bg)
+ :extend t)))
`(org-column ((,class :background ,bg-alt)))
`(org-column-title ((,class :inherit bold :underline t :background ,bg-alt)))
- `(org-date ((,class :inherit ,(if modus-themes-no-mixed-fonts
- 'button
- '(button fixed-pitch))
+ `(org-date ((,class :inherit ,(if modus-themes-mixed-fonts
+ '(button fixed-pitch)
+ 'button)
,@(modus-themes--link-color
cyan cyan-faint))))
`(org-date-selected ((,class :inherit bold :foreground ,blue-alt :inverse-video t)))
`(org-dispatcher-highlight ((,class :inherit (bold modus-themes-mark-alt))))
`(org-document-info ((,class :foreground ,fg-special-cold)))
- `(org-document-info-keyword ((,class :inherit modus-themes-fixed-pitch :foreground ,fg-alt)))
+ `(org-document-info-keyword ((,class :inherit (shadow modus-themes-fixed-pitch))))
`(org-document-title ((,class :inherit (bold modus-themes-variable-pitch) :foreground ,fg-special-cold
,@(modus-themes--scale modus-themes-scale-title))))
`(org-done ((,class :foreground ,@(modus-themes--success-deuteran blue green))))
- `(org-drawer ((,class :inherit modus-themes-fixed-pitch :foreground ,fg-alt)))
+ `(org-drawer ((,class :inherit (shadow modus-themes-fixed-pitch))))
`(org-ellipsis (())) ; inherits from the heading's color
`(org-footnote ((,class :inherit button
,@(modus-themes--link-color
@@ -6512,6 +6860,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(org-headline-todo ((,class :inherit modus-themes-variable-pitch :foreground ,red-nuanced-fg)))
`(org-hide ((,class :foreground ,bg-main)))
`(org-indent ((,class :inherit (fixed-pitch org-hide))))
+ `(org-imminent-deadline ((,class :foreground ,red-intense)))
`(org-latex-and-related ((,class :foreground ,magenta-refine-fg)))
`(org-level-1 ((,class :inherit modus-themes-heading-1)))
`(org-level-2 ((,class :inherit modus-themes-heading-2)))
@@ -6524,8 +6873,9 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(org-link ((,class :inherit button)))
`(org-list-dt ((,class :inherit bold)))
`(org-macro ((,class :inherit modus-themes-fixed-pitch
- :background ,cyan-nuanced-bg :foreground ,cyan-nuanced-fg)))
- `(org-meta-line ((,class :inherit modus-themes-fixed-pitch :foreground ,fg-alt)))
+ ,@(modus-themes--markup cyan-nuanced-fg cyan
+ cyan-nuanced-bg cyan-nuanced-bg))))
+ `(org-meta-line ((,class :inherit (shadow modus-themes-fixed-pitch))))
`(org-mode-line-clock ((,class :foreground ,fg-main)))
`(org-mode-line-clock-overrun ((,class :inherit bold :foreground ,red-active)))
`(org-priority ((,class :foreground ,magenta)))
@@ -6535,18 +6885,19 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(org-scheduled-previously ((,class ,@(modus-themes--agenda-scheduled yellow fg-special-warm yellow-alt-other))))
`(org-scheduled-today ((,class ,@(modus-themes--agenda-scheduled yellow fg-special-warm magenta-alt-other))))
`(org-sexp-date ((,class :inherit org-date)))
- `(org-special-keyword ((,class :inherit modus-themes-fixed-pitch :foreground ,fg-alt)))
+ `(org-special-keyword ((,class :inherit (shadow modus-themes-fixed-pitch))))
`(org-table ((,class :inherit modus-themes-fixed-pitch :foreground ,fg-special-cold)))
`(org-table-header ((,class :inherit (fixed-pitch modus-themes-intense-neutral))))
`(org-tag ((,class :foreground ,magenta-nuanced-fg)))
`(org-tag-group ((,class :inherit bold :foreground ,cyan-nuanced-fg)))
`(org-target ((,class :underline t)))
- `(org-time-grid ((,class :foreground ,fg-unfocused)))
+ `(org-time-grid ((,class :inherit shadow)))
`(org-todo ((,class :foreground ,red)))
`(org-upcoming-deadline ((,class :foreground ,red-alt-other)))
`(org-upcoming-distant-deadline ((,class :foreground ,red-faint)))
`(org-verbatim ((,class :inherit modus-themes-fixed-pitch
- :background ,bg-alt :foreground ,fg-special-calm)))
+ ,@(modus-themes--markup fg-special-calm magenta-alt
+ bg-alt magenta-nuanced-bg))))
`(org-verse ((,class :inherit org-quote)))
`(org-warning ((,class :inherit bold :foreground ,red-alt-other)))
;;;;; org-journal
@@ -6575,7 +6926,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(org-roam-link-shielded ((,class :inherit button
,@(modus-themes--link-color
yellow yellow-faint))))
- `(org-roam-tag ((,class :inherit italic :foreground ,fg-alt)))
+ `(org-roam-tag ((,class :inherit (shadow italic))))
;;;;; org-superstar
`(org-superstar-item ((,class :foreground ,fg-main)))
`(org-superstar-leading ((,class :foreground ,fg-whitespace)))
@@ -6674,7 +7025,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
;;;;; pomidor
`(pomidor-break-face ((,class :foreground ,blue-alt-other)))
`(pomidor-overwork-face ((,class :foreground ,red-alt-other)))
- `(pomidor-skip-face ((,class :inherit modus-themes-slant :foreground ,fg-alt)))
+ `(pomidor-skip-face ((,class :inherit (shadow modus-themes-slant))))
`(pomidor-work-face ((,class :foreground ,@(modus-themes--success-deuteran
blue-alt
green-alt-other))))
@@ -6708,9 +7059,9 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(proced-marked ((,class :inherit modus-themes-mark-alt)))
`(proced-sort-header ((,class :inherit bold :foreground ,fg-special-calm :underline t)))
;;;;; prodigy
- `(prodigy-green-face ((,class :foreground ,green)))
- `(prodigy-red-face ((,class :foreground ,red)))
- `(prodigy-yellow-face ((,class :foreground ,yellow)))
+ `(prodigy-green-face ((,class :inherit success)))
+ `(prodigy-red-face ((,class :inherit error)))
+ `(prodigy-yellow-face ((,class :inherit warning)))
;;;;; pulse
`(pulse-highlight-start-face ((,class :background ,bg-active-accent :extend t)))
;;;;; quick-peek
@@ -6725,7 +7076,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
:foreground ,green)))
`(racket-here-string-face ((,class :foreground ,blue-alt)))
`(racket-keyword-argument-face ((,class :foreground ,red-alt)))
- `(racket-logger-config-face ((,class :inherit modus-themes-slant :foreground ,fg-alt)))
+ `(racket-logger-config-face ((,class :inherit (shadow modus-themes-slant))))
`(racket-logger-debug-face ((,class :foreground ,blue-alt-other)))
`(racket-logger-info-face ((,class :foreground ,fg-lang-note)))
`(racket-logger-topic-face ((,class :inherit modus-themes-slant :foreground ,magenta)))
@@ -7018,8 +7369,8 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(spray-accent-face ((,class :foreground ,red-intense)))
`(spray-base-face ((,class :inherit default :foreground ,fg-special-cold)))
;;;;; stripes
- `(stripes ((,class :inherit modus-themes-hl-line)))
-;;;;; success
+ `(stripes ((,class :background ,bg-alt)))
+;;;;; suggest
`(suggest-heading ((,class :inherit bold :foreground ,yellow-alt-other)))
;;;;; switch-window
`(switch-window-background ((,class :background ,bg-dim)))
@@ -7066,7 +7417,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(sx-question-mode-score-downvoted ((,class :foreground ,yellow)))
`(sx-question-mode-score-upvoted ((,class :inherit bold :foreground ,magenta)))
`(sx-question-mode-title ((,class :inherit bold :foreground ,fg-main)))
- `(sx-question-mode-title-comments ((,class :inherit bold :foreground ,fg-alt)))
+ `(sx-question-mode-title-comments ((,class :inherit (shadow bold))))
`(sx-tag ((,class :foreground ,magenta-alt)))
`(sx-user-name ((,class :foreground ,blue-alt)))
`(sx-user-reputation ((,class :inherit shadow)))
@@ -7100,24 +7451,24 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(tab-bar-groups-tab-7 ((,class ,@(modus-themes--variable-pitch-ui) :foreground ,yellow-tab)))
`(tab-bar-groups-tab-8 ((,class ,@(modus-themes--variable-pitch-ui) :foreground ,magenta-tab)))
;;;;; tab-bar-mode
- `(tab-bar ((,class ,@(modus-themes--variable-pitch-ui)
- :background ,bg-tab-bar :foreground ,fg-main)))
- `(tab-bar-tab ((,class :inherit bold :box (:line-width 2 :color ,bg-tab-active)
- :background ,bg-tab-active :foreground ,fg-main)))
- `(tab-bar-tab-inactive ((,class :box (:line-width 2 :color ,bg-tab-inactive)
- :background ,bg-tab-inactive :foreground ,fg-dim)))
+ `(tab-bar ((,class ,@(modus-themes--tab bg-active bg-active-accent nil nil nil nil t))))
+ `(tab-bar-tab-group-current ((,class ,@(modus-themes--tab bg-tab-active)
+ :box (:line-width (2 . -2) :color "gray50"))))
+ `(tab-bar-tab-group-inactive ((,class ,@(modus-themes--tab bg-tab-inactive bg-tab-inactive-accent fg-dim)
+ :box (:line-width (2 . -2) :color "gray50"))))
+ `(tab-bar-tab ((,class ,@(modus-themes--tab bg-tab-active nil nil nil t t))))
+ `(tab-bar-tab-inactive ((,class ,@(modus-themes--tab bg-tab-inactive bg-tab-inactive-accent fg-dim nil t))))
;;;;; tab-line-mode
- `(tab-line ((,class ,@(modus-themes--variable-pitch-ui)
- :height 0.95 :background ,bg-tab-bar :foreground ,fg-main)))
+ `(tab-line ((,class ,@(modus-themes--tab bg-active bg-active-accent nil nil nil nil t)
+ :height 0.95)))
`(tab-line-close-highlight ((,class :foreground ,red)))
- `(tab-line-highlight ((,class :background ,blue-subtle-bg :foreground ,fg-dim)))
- `(tab-line-tab ((,class :inherit bold :box (:line-width 2 :color ,bg-tab-active)
- :background ,bg-tab-active :foreground ,fg-main)))
+ `(tab-line-highlight ((,class :inherit modus-themes-active-blue)))
+ `(tab-line-tab ((,class ,@(modus-themes--tab bg-tab-active nil nil nil t t))))
`(tab-line-tab-current ((,class :inherit tab-line-tab)))
- `(tab-line-tab-inactive ((,class :box (:line-width 2 :color ,bg-tab-inactive)
- :background ,bg-tab-inactive :foreground ,fg-dim)))
- `(tab-line-tab-inactive-alternate ((,class :box (:line-width 2 :color ,bg-tab-inactive-alt)
- :background ,bg-tab-inactive-alt :foreground ,fg-main)))
+ `(tab-line-tab-inactive ((,class ,@(modus-themes--tab bg-tab-inactive bg-tab-inactive-accent fg-dim nil t))))
+ `(tab-line-tab-inactive-alternate ((,class ,@(modus-themes--tab bg-tab-inactive-alt
+ bg-tab-inactive-alt-accent fg-main nil t))))
+ `(tab-line-tab-modified ((,class :foreground ,red-alt-other-faint)))
;;;;; table (built-in table.el)
`(table-cell ((,class :background ,blue-nuanced-bg)))
;;;;; telega
@@ -7129,9 +7480,9 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(telega-button-active ((,class :box ,blue-intense-bg :background ,blue-intense-bg :foreground ,fg-main)))
`(telega-button-highlight ((,class :inherit modus-themes-subtle-magenta)))
`(telega-chat-prompt ((,class :inherit bold)))
- `(telega-entity-type-code ((,class :inherit fixed-pitch)))
+ `(telega-entity-type-code ((,class :inherit modus-themes-fixed-pitch)))
`(telega-entity-type-mention ((,class :foreground ,cyan)))
- `(telega-entity-type-pre ((,class :inherit fixed-pitch)))
+ `(telega-entity-type-pre ((,class :inherit modus-themes-fixed-pitch)))
`(telega-msg-heading ((,class :background ,bg-alt)))
`(telega-msg-self-title ((,class :inherit bold)))
`(telega-root-heading ((,class :inherit modus-themes-subtle-neutral)))
@@ -7140,9 +7491,9 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(telega-user-online-status ((,class :foreground ,cyan-active)))
`(telega-username ((,class :foreground ,cyan-alt-other)))
`(telega-webpage-chat-link ((,class :background ,bg-alt)))
- `(telega-webpage-fixed ((,class :inherit fixed-pitch :height 0.85)))
+ `(telega-webpage-fixed ((,class :inherit modus-themes-fixed-pitch :height 0.85)))
`(telega-webpage-header ((,class :inherit modus-themes-variable-pitch :height 1.3)))
- `(telega-webpage-preformatted ((,class :inherit fixed-pitch :background ,bg-alt)))
+ `(telega-webpage-preformatted ((,class :inherit modus-themes-fixed-pitch :background ,bg-alt)))
`(telega-webpage-subheader ((,class :inherit modus-themes-variable-pitch :height 1.15)))
;;;;; telephone-line
`(telephone-line-accent-active ((,class :background ,fg-inactive :foreground ,bg-inactive)))
@@ -7281,10 +7632,10 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(vc-dir-header-value ((,class :foreground ,magenta-alt-other)))
`(vc-dir-mark-indicator ((,class :foreground ,blue-alt-other)))
`(vc-dir-status-edited ((,class :foreground ,yellow)))
- `(vc-dir-status-ignored ((,class :foreground ,fg-unfocused)))
+ `(vc-dir-status-ignored ((,class :inherit shadow)))
`(vc-dir-status-up-to-date ((,class :foreground ,cyan)))
- `(vc-dir-status-warning ((,class :foreground ,red)))
- `(vc-conflict-state ((,class :inherit modus-themes-slant :foreground ,red-active)))
+ `(vc-dir-status-warning ((,class :inherit error)))
+ `(vc-conflict-state ((,class :inherit bold :foreground ,red-active)))
`(vc-edited-state ((,class :foreground ,yellow-active)))
`(vc-locally-added-state ((,class :foreground ,cyan-active)))
`(vc-locked-state ((,class :foreground ,blue-active)))
@@ -7306,6 +7657,9 @@ by virtue of calling either of `modus-themes-load-operandi' and
:background ,@(pcase modus-themes-completions
('opinionated (list bg-active))
(_ (list bg-inactive))))))
+;;;;; vertico-quick
+ `(vertico-quick1 ((,class :inherit (modus-themes-intense-magenta bold))))
+ `(vertico-quick2 ((,class :inherit (modus-themes-refine-cyan bold))))
;;;;; vimish-fold
`(vimish-fold-fringe ((,class :foreground ,cyan-active)))
`(vimish-fold-mouse-face ((,class :inherit modus-themes-intense-blue)))
@@ -7397,7 +7751,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(web-mode-jsx-depth-3-face ((,class :background ,bg-special-cold :foreground ,fg-special-cold)))
`(web-mode-jsx-depth-4-face ((,class :background ,bg-alt :foreground ,blue-refine-fg)))
`(web-mode-jsx-depth-5-face ((,class :background ,bg-alt :foreground ,blue-nuanced-fg)))
- `(web-mode-keyword-face ((,class :inherit :inherit font-lock-keyword-face)))
+ `(web-mode-keyword-face ((,class :inherit font-lock-keyword-face)))
`(web-mode-param-name-face ((,class :inherit font-lock-function-name-face)))
`(web-mode-part-comment-face ((,class :inherit web-mode-comment-face)))
`(web-mode-part-face ((,class :inherit web-mode-block-face)))
@@ -7590,9 +7944,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
(provide 'modus-themes)
;; Local Variables:
-;; time-stamp-start: "Last-Modified:[ \t]+\\\\?[\"<]"
-;; time-stamp-end: "\\\\?[\">]"
-;; time-stamp-format: "%Y-%02m-%02d %02H:%02M:%02S %5z"
+;; time-stamp-pattern: "Last-Modified: <%Y-%02m-%02d %02H:%02M:%02S %5z>"
;; End:
;;; modus-themes.el ends here
diff --git a/etc/themes/modus-vivendi-theme.el b/etc/themes/modus-vivendi-theme.el
index 6ff359d341b..6dffbf07e94 100644
--- a/etc/themes/modus-vivendi-theme.el
+++ b/etc/themes/modus-vivendi-theme.el
@@ -4,8 +4,8 @@
;; Author: Protesilaos Stavrou <info@protesilaos.com>
;; URL: https://gitlab.com/protesilaos/modus-themes
-;; Version: 1.5.0
-;; Package-Requires: ((emacs "26.1"))
+;; Version: 1.7.0
+;; Package-Requires: ((emacs "27.1"))
;; Keywords: faces, theme, accessibility
;; This file is part of GNU Emacs.
diff --git a/etc/themes/tango-dark-theme.el b/etc/themes/tango-dark-theme.el
index a8577108ed3..fe4a24746e6 100644
--- a/etc/themes/tango-dark-theme.el
+++ b/etc/themes/tango-dark-theme.el
@@ -20,7 +20,7 @@
;; 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
+;;; Commentary:
;; The colors in this theme come from the Tango palette, which is in
;; the public domain: http://tango.freedesktop.org/
@@ -45,7 +45,9 @@ Semantic, and Ansi-Color faces are included.")
(alum-4 "#888a85") (alum-5 "#555753") (alum-6 "#2e3436")
;; Not in Tango palette; used for better contrast.
(cham-0 "#b4fa70") (blue-0 "#8cc4ff") (plum-0 "#e9b2e3")
- (red-0 "#ff4b4b") (alum-5.5 "#41423f") (alum-7 "#212526"))
+ (red-0 "#ff4b4b") (alum-5.5 "#41423f") (alum-7 "#212526")
+ ;; Not in Tango palette; used for ANSI cyan.
+ (cyan-1 "#34e2e2") (cyan-2 "#06989a"))
(custom-theme-set-faces
'tango-dark
@@ -162,12 +164,31 @@ Semantic, and Ansi-Color faces are included.")
`(semantic-decoration-on-unparsed-includes
((,class (:background ,alum-5.5))))
`(semantic-tag-boundary-face ((,class (:overline ,blue-1))))
- `(semantic-unmatched-syntax-face ((,class (:underline ,red-1)))))
-
- (custom-theme-set-variables
- 'tango-dark
- `(ansi-color-names-vector [,alum-7 ,red-0 ,cham-0 ,butter-1
- ,blue-1 ,plum-1 ,blue-0 ,alum-1])))
+ `(semantic-unmatched-syntax-face ((,class (:underline ,red-1))))
+ ;; ANSI colors
+ `(ansi-color-black ((,class (:background ,alum-7 :foreground ,alum-7))))
+ `(ansi-color-red ((,class (:background ,red-1 :foreground ,red-1))))
+ `(ansi-color-green ((,class (:background ,cham-2 :foreground ,cham-2))))
+ `(ansi-color-yellow ((,class (:background ,butter-2 :foreground ,butter-2))))
+ `(ansi-color-blue ((,class (:background ,blue-2 :foreground ,blue-2))))
+ `(ansi-color-magenta ((,class (:background ,plum-1 :foreground ,plum-1))))
+ `(ansi-color-cyan ((,class (:background ,cyan-2 :foreground ,cyan-2))))
+ `(ansi-color-white ((,class (:background ,alum-2 :foreground ,alum-2))))
+ `(ansi-color-bright-black ((,class (:background ,alum-5
+ :foreground ,alum-5))))
+ `(ansi-color-bright-red ((,class (:background ,red-0 :foreground ,red-0))))
+ `(ansi-color-bright-green ((,class (:background ,cham-1
+ :foreground ,cham-1))))
+ `(ansi-color-bright-yellow ((,class (:background ,butter-1
+ :foreground ,butter-1))))
+ `(ansi-color-bright-blue ((,class (:background ,blue-0
+ :foreground ,blue-0))))
+ `(ansi-color-bright-magenta ((,class (:background ,plum-0
+ :foreground ,plum-0))))
+ `(ansi-color-bright-cyan ((,class (:background ,cyan-1
+ :foreground ,cyan-1))))
+ `(ansi-color-bright-white ((,class (:background ,alum-1
+ :foreground ,alum-1))))))
(provide-theme 'tango-dark)
diff --git a/etc/themes/tango-theme.el b/etc/themes/tango-theme.el
index 286561eb4e2..5c429b0b70c 100644
--- a/etc/themes/tango-theme.el
+++ b/etc/themes/tango-theme.el
@@ -20,7 +20,7 @@
;; 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
+;;; Commentary:
;; The colors in this theme come from the Tango palette, which is in
;; the public domain: http://tango.freedesktop.org/
@@ -44,7 +44,9 @@ Semantic, and Ansi-Color faces are included.")
(alum-1 "#eeeeec") (alum-2 "#d3d7cf") (alum-3 "#babdb6")
(alum-4 "#888a85") (alum-5 "#5f615c") (alum-6 "#2e3436")
;; Not in Tango palette; used for better contrast.
- (cham-4 "#346604") (blue-0 "#8cc4ff") (orange-4 "#b35000"))
+ (cham-4 "#346604") (blue-0 "#8cc4ff") (orange-4 "#b35000")
+ ;; Not in Tango palette; used for ANSI cyan.
+ (cyan-1 "#34e2e2") (cyan-2 "#06989a"))
(custom-theme-set-faces
'tango
@@ -145,12 +147,31 @@ Semantic, and Ansi-Color faces are included.")
`(semantic-decoration-on-unparsed-includes
((,class (:underline ,orange-3))))
`(semantic-tag-boundary-face ((,class (:overline ,blue-1))))
- `(semantic-unmatched-syntax-face ((,class (:underline ,red-1)))))
-
- (custom-theme-set-variables
- 'tango
- `(ansi-color-names-vector [,alum-6 ,red-3 ,cham-3 ,butter-3
- ,blue-3 ,plum-3 ,blue-1 ,alum-1])))
+ `(semantic-unmatched-syntax-face ((,class (:underline ,red-1))))
+ ;; ANSI colors
+ `(ansi-color-black ((,class (:background ,alum-6 :foreground ,alum-6))))
+ `(ansi-color-red ((,class (:background ,red-2 :foreground ,red-2))))
+ `(ansi-color-green ((,class (:background ,cham-3 :foreground ,cham-3))))
+ `(ansi-color-yellow ((,class (:background ,butter-3 :foreground ,butter-3))))
+ `(ansi-color-blue ((,class (:background ,blue-2 :foreground ,blue-2))))
+ `(ansi-color-magenta ((,class (:background ,plum-2 :foreground ,plum-2))))
+ `(ansi-color-cyan ((,class (:background ,cyan-2 :foreground ,cyan-2))))
+ `(ansi-color-white ((,class (:background ,alum-2 :foreground ,alum-2))))
+ `(ansi-color-bright-black ((,class (:background ,alum-5
+ :foreground ,alum-5))))
+ `(ansi-color-bright-red ((,class (:background ,red-1 :foreground ,red-1))))
+ `(ansi-color-bright-green ((,class (:background ,cham-1
+ :foreground ,cham-1))))
+ `(ansi-color-bright-yellow ((,class (:background ,butter-1
+ :foreground ,butter-1))))
+ `(ansi-color-bright-blue ((,class (:background ,blue-1
+ :foreground ,blue-1))))
+ `(ansi-color-bright-magenta ((,class (:background ,plum-1
+ :foreground ,plum-1))))
+ `(ansi-color-bright-cyan ((,class (:background ,cyan-1
+ :foreground ,cyan-1))))
+ `(ansi-color-bright-white ((,class (:background ,alum-1
+ :foreground ,alum-1))))))
(provide-theme 'tango)
diff --git a/etc/themes/whiteboard-theme.el b/etc/themes/whiteboard-theme.el
index 729c082a331..9cf8e7dfc93 100644
--- a/etc/themes/whiteboard-theme.el
+++ b/etc/themes/whiteboard-theme.el
@@ -63,6 +63,8 @@
`(ido-first-match ((,class (:weight normal :foreground "DarkOrange3"))))
`(ido-only-match ((,class (:foreground "SeaGreen4"))))
`(ido-subdir ((,class (:foreground nil :inherit font-lock-keyword-face))))
+ `(image-dired-thumb-flagged ((,class :background "Red1")))
+ `(image-dired-thumb-mark ((,class :background "dodgerblue3")))
`(info-header-node ((,class (:foreground "DeepSkyBlue1"))))
`(info-header-xref ((,class (:foreground "SeaGreen2"))))
`(info-menu-header ((,class (:family "helv" :weight bold))))
diff --git a/etc/themes/wombat-theme.el b/etc/themes/wombat-theme.el
index 922114fb64a..d769c337214 100644
--- a/etc/themes/wombat-theme.el
+++ b/etc/themes/wombat-theme.el
@@ -95,12 +95,24 @@ are included.")
`(message-header-subject ((,class (:foreground "#cae682"))))
`(message-header-to ((,class (:foreground "#cae682"))))
`(message-cited-text ((,class (:foreground "#99968b"))))
- `(message-separator ((,class (:foreground "#e5786d" :weight bold))))))
-
-(custom-theme-set-variables
- 'wombat
- '(ansi-color-names-vector ["#242424" "#e5786d" "#95e454" "#cae682"
- "#8ac6f2" "#333366" "#ccaa8f" "#f6f3e8"]))
+ `(message-separator ((,class (:foreground "#e5786d" :weight bold))))
+ ;; ANSI colors
+ `(ansi-color-black ((,class (:background "#242424" :foreground "#242424"))))
+ `(ansi-color-red ((,class (:background "#b85149" :foreground "#b85149"))))
+ `(ansi-color-green ((,class (:background "#92a65e" :foreground "#92a65e"))))
+ `(ansi-color-yellow ((,class (:background "#ccaa8f" :foreground "#ccaa8f"))))
+ `(ansi-color-blue ((,class (:background "#5b98c2" :foreground "#5b98c2"))))
+ `(ansi-color-magenta ((,class (:background "#64619a" :foreground "#64619a"))))
+ `(ansi-color-cyan ((,class (:background "#3f9f9e" :foreground "#3f9f9e"))))
+ `(ansi-color-white ((,class (:background "#f6f3e8" :foreground "#f6f3e8"))))
+ `(ansi-color-bright-black ((,class (:background "#444444" :foreground "#444444"))))
+ `(ansi-color-bright-red ((,class (:background "#e5786d" :foreground "#e5786d"))))
+ `(ansi-color-bright-green ((,class (:background "#95e454" :foreground "#95e454"))))
+ `(ansi-color-bright-yellow ((,class (:background "#edc4a3" :foreground "#edc4a3"))))
+ `(ansi-color-bright-blue ((,class (:background "#8ac6f2" :foreground "#8ac6f2"))))
+ `(ansi-color-bright-magenta ((,class (:background "#a6a1de" :foreground "#a6a1de"))))
+ `(ansi-color-bright-cyan ((,class (:background "#70cecc" :foreground "#70cecc"))))
+ `(ansi-color-bright-white ((,class (:background "#ffffff" :foreground "#ffffff"))))))
(provide-theme 'wombat)
diff --git a/etc/tutorials/TUTORIAL b/etc/tutorials/TUTORIAL
index dcdb61f23ec..c5f2e684c42 100644
--- a/etc/tutorials/TUTORIAL
+++ b/etc/tutorials/TUTORIAL
@@ -304,8 +304,8 @@ position, type <DEL>. This is the key on the keyboard usually labeled
"Backspace"--the same one you normally use, outside Emacs, to delete
the last character typed.
-There may also be another key on your keyboard labeled <Delete>, but
-that's not the one we refer to as <DEL>.
+There is usually another key on your keyboard labeled <Delete>, but
+that's not the one we refer to as <DEL> in Emacs.
>> Do this now--type a few characters, then delete them by
typing <DEL> a few times. Don't worry about this file
@@ -1099,6 +1099,20 @@ manual in the node called "Dired".
The manual also describes many other Emacs features.
+* INSTALLING PACKAGES
+---------------------
+
+There's a rich set of packages for Emacs written by the community,
+which extend Emacs' capabilities. These packages include support for
+new languages, additional themes, plugins for integrating with
+external applications, and much, much more.
+
+To see a list of all available packages, type M-x list-packages. In
+the display this shows, you can install or uninstall packages, as well
+as read packages' descriptions. For more information about package
+management, consult the manual.
+
+
* CONCLUSION
------------
diff --git a/etc/tutorials/TUTORIAL.he b/etc/tutorials/TUTORIAL.he
index 2ee4f74c324..fc4b769599e 100644
--- a/etc/tutorials/TUTORIAL.he
+++ b/etc/tutorials/TUTORIAL.he
@@ -1,4 +1,4 @@
-שיעור ראשון בשימוש ב־‫Emacs‬. זכויות שימוש ראה בסוף המסמך.
+שיעור ראשון בשימוש ב־‪Emacs‬. זכויות שימוש ראה בסוף המסמך.
פקודות רבות של Emacs משתמשות במקש CONTROL (בדרך־כלל מסומן ב־CTRL)
או במקש META (בדרך־כלל מסומן ALT). במקום לציין את כל השמות האפשריים
@@ -24,7 +24,7 @@
שימו לב לחפיפה של שתי שורות כאשר אתם עוברים ממסך למסך, מה שמבטיח רציפות
מסוימת בעת קריאת הטקסט.
-הטקסט שלפניכם הינו עותק של שיעור בשימוש ב־‫Emacs‬ שהותאם קלות עבורכם.
+הטקסט שלפניכם הינו עותק של שיעור בשימוש ב־‪Emacs‬ שהותאם קלות עבורכם.
בהמשך תקבלו הוראות לנסות פקודות שונות כדי לבצע שינויים בטקסט הזה. אם
במקרה תשנו את הטקסט לפני שנבקש, אל דאגה: זוהי "עריכה" שהיא יעודו של
Emacs.
@@ -985,6 +985,17 @@ find-file.
בנוסף, מדריך למשתמש מתאר עוד הרבה מאד תכונות של Emacs.
+* התקנת חבילות הרחבה
+--------------------
+קיימות לא מעט חבילות תוכנה עבור Emacs אשר מרחיבות את היכולות שלו. חבילות
+הרחבה אלו נכתבו ע״י קהילת משתמשי Emacs והן מהוות אוסף עשיר של תכונות
+התומכות בשפות תכנות נוספות, ערכות נושא נוספות, תוספים לשילוב יישומים
+חיצוניים, ועוד ועוד.
+
+לצפיה ברשימת חבילות ההרחבה הזמינות, יש להקיש M-x list-packages. בתצוגה
+שתיפתח בעקבות זאת תוכלו לעיין בתיאור של חבילות, לבחור חבילות להתקנה במחשב
+שלכם, להסיר חבילות, ועוד. פרטים נוספים לגבי ניהול חבילות הרחבה ניתן למצוא
+במדריך למשתמש.
* לסיום
-------
diff --git a/etc/tutorials/TUTORIAL.it b/etc/tutorials/TUTORIAL.it
index 68bf40332ef..aa2fb4560a7 100644
--- a/etc/tutorials/TUTORIAL.it
+++ b/etc/tutorials/TUTORIAL.it
@@ -1178,14 +1178,27 @@ quei file. Dired è descritta nel manuale Emacs nel nodo chiamato
Il manuale descrive molte altre funzionalità di Emacs.
+* INSTALLAZIONE DI ULTERIORI PACCHETTI
+
+Ci sono tantissimi pacchetti che estendono le funzionalità di Emacs,
+scritti dalla comunità. Questi pacchetti includono il supporto a
+nuovi linguaggi, aggiungono temi addizionali, rendono possibile
+interoperare con applicazioni esterne e molto, molto altro.
+
+Per vedere una lista di tutti i pacchetti disponibili, inserisci
+M-x list-packages. Nell'elenco che viene mostrato, puoi installare o
+disinstallare pacchetti, o leggerne la descrizione. Consulta il
+manuale per ulteriori informazioni sulla gestione dei pacchetti.
+
+
* CONCLUSIONI
-------------
Per chiudere una sessione di Emacs si usa C-x C-c.
-Questo documento è stato creato per essere utile a tutti i nuovi
-utenti, se qualcosa per te è stato poco chiaro non dare la colpa a te
-stesso: lamentati!
+Questo documento è pensato per essere comprensibile a tutti i nuovi
+utenti, quindi se hai trovato qualcosa di poco chiaro, non dare la
+colpa a te stesso: lamentati!
* COPIA
diff --git a/etc/tutorials/TUTORIAL.sv b/etc/tutorials/TUTORIAL.sv
index dacc66d916f..5c9703f8066 100644
--- a/etc/tutorials/TUTORIAL.sv
+++ b/etc/tutorials/TUTORIAL.sv
@@ -1119,6 +1119,20 @@ Emacs-manualen i noden "Dired".
Manualen beskriver även många andra funktioner i Emacs.
+* INSTALLERA PAKET
+------------------
+
+Det finns en stor mängd paket för Emacs skrivna av användare, som
+utökar Emacs funktionalitet. Detta kan innefatta stöd för nya språk,
+fler teman, insticksmoduler för integration med externa program och
+mycket, mycket annat.
+
+Skriv M-x list-packages för att se en lista över alla tillgängliga
+paket. I detta läge kan du installera eller avinstallera paket samt
+läsa mer om olika paket. Se användarmanualen för mer information om
+pakethantering.
+
+
* SLUTORD
---------
diff --git a/leim/MISC-DIC/README b/leim/MISC-DIC/README
index 74ae75289b2..f205ecd7259 100644
--- a/leim/MISC-DIC/README
+++ b/leim/MISC-DIC/README
@@ -20,7 +20,7 @@ license notice.
They are copies of those distributed with a free package
called CCE at:
- http://archive.debian.org/debian/pool/main/c/cce/cce_0.36.orig.tar.gz
+ https://archive.debian.org/debian/pool/main/c/cce/cce_0.36.orig.tar.gz
As the original files don't contain copyright and license notices, a
proper notice is extracted from the file Copyright and added at the
diff --git a/leim/MISC-DIC/pinyin.map b/leim/MISC-DIC/pinyin.map
index 4809769d1ad..e206564bcd7 100644
--- a/leim/MISC-DIC/pinyin.map
+++ b/leim/MISC-DIC/pinyin.map
@@ -3,7 +3,7 @@
% This file is included in the free package called CCE. It is
% available in:
%
-% http://archive.debian.org/debian/pool/main/c/cce/cce_0.36.orig.tar.gz
+% https://archive.debian.org/debian/pool/main/c/cce/cce_0.36.orig.tar.gz
%
% As the file itself doesn't contain copyright and license notices,
% the following statements of the file cce/Copyright covers it.
diff --git a/leim/MISC-DIC/ziranma.cin b/leim/MISC-DIC/ziranma.cin
index b61aea2b6f4..b276e888a0c 100644
--- a/leim/MISC-DIC/ziranma.cin
+++ b/leim/MISC-DIC/ziranma.cin
@@ -3,7 +3,7 @@
% This file is included in the free package called CCE. It is
% available in:
%
-% http://archive.debian.org/debian/pool/main/c/cce/cce_0.36.orig.tar.gz
+% https://archive.debian.org/debian/pool/main/c/cce/cce_0.36.orig.tar.gz
%
% As the file itself doesn't contain copyright and license notices,
% the following statements of the file cce/Copyright covers it.
diff --git a/leim/SKK-DIC/SKK-JISYO.L b/leim/SKK-DIC/SKK-JISYO.L
index 78d6e08027e..2d4f6198984 100644
--- a/leim/SKK-DIC/SKK-JISYO.L
+++ b/leim/SKK-DIC/SKK-JISYO.L
@@ -46444,7 +46444,9 @@ zyklus /륹/ĥ륹/
󤴤 /Ź;code/Ź;ΰ/
󤴤 /Ź沽/
󤴤 /Ź渰;[]encryption key/
+󤴤 /Ź/
󤴤礦 /ŹĢ/
+󤴤Ĥ /Ź̲/
󤴤Ҥ礦 /Źɽ/
󤴤֤ /Źʸ/
󤵤 /Ż/
@@ -61914,6 +61916,7 @@ zyklus /륹/ĥ륹/
//
礦 //
ޤ /ü/
+Ĥ /̲/
Ƥ /Ū/Ũ;imaginary enemy/
Ƥ /Ũ/
//
@@ -138362,6 +138365,7 @@ zyklus /륹/ĥ륹/
ˤ夦 /󽽻;Make a wish!/
ˤ夦 /󽽻ͻ;󽽰ˡܵܵˡ/
ˤ夦ä /󽽻ᵤ/
+ˤ夦Ϥ餤 /Żʧ/
ˤ夦礦 /ž/
ˤ夦󤫤 /ſͳ/
ˤ夦 /;dualism/;[ŷʸ]double star/
@@ -138476,6 +138480,7 @@ zyklus /륹/ĥ륹/
ˤ /ê/
ˤ //
ˤ󤫤 /ʳ/2ʳ/
+ˤ󤫤ˤ󤷤礦 /ʳǧ/
ˤ󤫤Ĥ褦 /ʳ/
ˤ󤬤 /ʽŤ/
ˤ󤬤ޤ /ʹ;with a fallback/
@@ -143449,7 +143454,7 @@ zyklus /륹/ĥ륹/
Ϥä /ȯDz/
Ϥä /ȯ/
Ϥä /ȯϩ/
-Ϥä /ȯΩ/
+Ϥä /ȯΨ/
Ϥä /ȯս/
Ϥä󤫤 /ȯֳ/
Ϥä /ȯ/
diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in
index 7af89eb380d..c07b678839c 100644
--- a/lib-src/Makefile.in
+++ b/lib-src/Makefile.in
@@ -27,7 +27,9 @@ EMACSOPT = -batch --no-site-file --no-site-lisp
# ==================== Things 'configure' will edit ====================
CC=@CC@
+CXX=@CXX@
CFLAGS=@CFLAGS@
+CXXFLAGS=@CXXFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
@@ -52,6 +54,7 @@ top_builddir = @top_builddir@
# Location to install Emacs.app under GNUstep / macOS.
# Later values may use this.
ns_appbindir=@ns_appbindir@
+ns_applibexecdir=@ns_applibexecdir@
# The default location for installation. Everything is placed in
# subdirectories of this directory. The default values for many of
@@ -129,6 +132,11 @@ MKDIR_P = @MKDIR_P@
# ========================== Lists of Files ===========================
+## Haiku build-time support
+HAVE_BE_APP=@HAVE_BE_APP@
+HAIKU_LIBS=@HAIKU_LIBS@
+HAIKU_CFLAGS=@HAIKU_CFLAGS@
+
# emacsclientw.exe for MinGW, empty otherwise
CLIENTW = @CLIENTW@
@@ -142,7 +150,11 @@ UTILITIES = hexl${EXEEXT} \
$(if $(with_mailutils), , movemail${EXEEXT}) \
$(and $(use_gamedir), update-game-score${EXEEXT})
+ifeq ($(HAVE_BE_APP),yes)
+DONT_INSTALL= make-docfile${EXEEXT} make-fingerprint${EXEEXT} be-resources
+else
DONT_INSTALL= make-docfile${EXEEXT} make-fingerprint${EXEEXT}
+endif
# Like UTILITIES, but they're not system-dependent, and should not be
# deleted by the distclean target.
@@ -183,6 +195,8 @@ LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@
LIB_GETRANDOM = @LIB_GETRANDOM@
## Whatever libraries are needed for euidaccess
LIB_EACCESS=@LIB_EACCESS@
+## Libraries needed for file_has_acl
+LIB_HAS_ACL=@LIB_HAS_ACL@
## empty or -lwsock2 for MinGW
LIB_WSOCK32=@LIB_WSOCK32@
@@ -229,6 +243,10 @@ WINDRES = @WINDRES@
## Some systems define this to request special libraries.
LIBS_SYSTEM = @LIBS_SYSTEM@
+# Flags that could be in WARN_CFLAGS, but are invalid for C++.
+NON_CXX_CFLAGS = -Wmissing-prototypes -Wnested-externs -Wold-style-definition \
+ -Wstrict-prototypes -Wno-override-init
+
BASE_CFLAGS = $(C_SWITCH_SYSTEM) $(C_SWITCH_MACHINE) \
$(WARN_CFLAGS) $(WERROR_CFLAGS) \
-I. -I../src -I../lib \
@@ -237,6 +255,9 @@ BASE_CFLAGS = $(C_SWITCH_SYSTEM) $(C_SWITCH_MACHINE) \
ALL_CFLAGS = ${BASE_CFLAGS} ${PROFILING_CFLAGS} ${LDFLAGS} ${CPPFLAGS} ${CFLAGS}
CPP_CFLAGS = ${BASE_CFLAGS} ${PROFILING_CFLAGS} ${CPPFLAGS} ${CFLAGS}
+ALL_CXXFLAGS = $(filter-out ${NON_CXX_CFLAGS},${BASE_CFLAGS}) \
+ ${PROFILING_CFLAGS} ${LDFLAGS} ${CPPFLAGS} ${CFLAGS} ${CXXFLAGS} ${HAIKU_CFLAGS}
+
# Configuration files for .o files to depend on.
config_h = ../src/config.h $(srcdir)/../src/conf_post.h
@@ -399,13 +420,16 @@ pop.o: ${srcdir}/pop.c ${srcdir}/pop.h ${srcdir}/../lib/min-max.h $(config_h)
emacsclient${EXEEXT}: ${srcdir}/emacsclient.c $(NTLIB) $(config_h)
$(AM_V_CCLD)$(CC) ${ALL_CFLAGS} $< \
$(NTLIB) $(LOADLIBES) \
- $(LIB_WSOCK32) $(LIB_EACCESS) $(LIBS_ECLIENT) -o $@
+ $(LIB_WSOCK32) $(LIB_EACCESS) $(LIB_HAS_ACL) $(LIBS_ECLIENT) -o $@
emacsclientw${EXEEXT}: ${srcdir}/emacsclient.c $(NTLIB) $(CLIENTRES) $(config_h)
$(AM_V_CCLD)$(CC) ${ALL_CFLAGS} $(CLIENTRES) -mwindows $< \
$(LOADLIBES) \
$(LIB_WSOCK32) $(LIB_EACCESS) $(LIBS_ECLIENT) -o $@
+be-resources: ${srcdir}/be_resources.cc ${config_h}
+ $(AM_V_CXXLD)$(CXX) ${ALL_CXXFLAGS} ${HAIKU_LIBS} $< -o $@
+
NTINC = ${srcdir}/../nt/inc
NTDEPS = $(NTINC)/ms-w32.h $(NTINC)/sys/stat.h $(NTINC)/inttypes.h \
$(NTINC)/stdint.h $(NTINC)/pwd.h $(NTINC)/sys/time.h $(NTINC)/stdbool.h \
diff --git a/lib-src/be_resources.cc b/lib-src/be_resources.cc
new file mode 100644
index 00000000000..e6a14f037b6
--- /dev/null
+++ b/lib-src/be_resources.cc
@@ -0,0 +1,144 @@
+/* Haiku window system support
+ Copyright (C) 2021 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/>. */
+
+#include <config.h>
+
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+
+#include <SupportDefs.h>
+#include <Path.h>
+#include <AppFileInfo.h>
+#include <TranslationUtils.h>
+#include <Application.h>
+#include <Catalog.h>
+#include <Roster.h>
+
+using namespace std;
+
+static void
+be_perror (status_t code, char *arg)
+{
+ if (code != B_OK)
+ {
+ switch (code)
+ {
+ case B_BAD_VALUE:
+ fprintf (stderr, "%s: Bad value\n", arg);
+ break;
+ case B_ENTRY_NOT_FOUND:
+ fprintf (stderr, "%s: Not found\n", arg);
+ break;
+ case B_PERMISSION_DENIED:
+ fprintf (stderr, "%s: Permission denied\n", arg);
+ break;
+ case B_NO_MEMORY:
+ fprintf (stderr, "%s: No memory\n", arg);
+ break;
+ case B_LINK_LIMIT:
+ fprintf (stderr, "%s: Link limit reached\n", arg);
+ break;
+ case B_BUSY:
+ fprintf (stderr, "%s: Busy\n", arg);
+ break;
+ case B_NO_MORE_FDS:
+ fprintf (stderr, "%s: No more file descriptors\n", arg);
+ break;
+ case B_FILE_ERROR:
+ fprintf (stderr, "%s: File error\n", arg);
+ break;
+ default:
+ fprintf (stderr, "%s: Unknown error\n", arg);
+ }
+ }
+ else
+ {
+ abort ();
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ BApplication app ("application/x-vnd.GNU-emacs-resource-helper");
+ BFile file;
+ BBitmap *icon;
+ BAppFileInfo info;
+ status_t code;
+ struct version_info vinfo;
+ char *v = strdup (PACKAGE_VERSION);
+
+ if (argc != 3)
+ {
+ printf ("be-resources ICON FILE: make FILE appropriate for Emacs.\n");
+ return EXIT_FAILURE;
+ }
+
+ code = file.SetTo (argv[2], B_READ_WRITE);
+ if (code != B_OK)
+ {
+ be_perror (code, argv[2]);
+ return EXIT_FAILURE;
+ }
+ code = info.SetTo (&file);
+ if (code != B_OK)
+ {
+ be_perror (code, argv[2]);
+ return EXIT_FAILURE;
+ }
+ code = info.SetAppFlags (B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY);
+ if (code != B_OK)
+ {
+ be_perror (code, argv[2]);
+ return EXIT_FAILURE;
+ }
+
+ icon = BTranslationUtils::GetBitmapFile (argv[1], NULL);
+
+ if (!icon)
+ {
+ be_perror (B_ERROR, argv[1]);
+ return EXIT_FAILURE;
+ }
+
+ info.SetIcon (icon, B_MINI_ICON);
+ info.SetIcon (icon, B_LARGE_ICON);
+ info.SetSignature ("application/x-vnd.GNU-emacs");
+
+ v = strtok (v, ".");
+ vinfo.major = atoi (v);
+
+ v = strtok (NULL, ".");
+ vinfo.middle = atoi (v);
+
+ v = strtok (NULL, ".");
+ vinfo.minor = v ? atoi (v) : 0;
+
+ vinfo.variety = 0;
+ vinfo.internal = 0;
+
+ strncpy ((char *) &vinfo.short_info, PACKAGE_VERSION,
+ sizeof vinfo.short_info - 1);
+ strncpy ((char *) &vinfo.long_info, PACKAGE_STRING,
+ sizeof vinfo.long_info - 1);
+
+ info.SetVersionInfo (&vinfo, B_APP_VERSION_KIND);
+
+ return EXIT_SUCCESS;
+}
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index 8346524a3eb..7769e015edc 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -80,9 +80,6 @@ char *w32_getenv (const char *);
#include <sys/stat.h>
#include <unistd.h>
-#ifndef WINDOWSNT
-# include <acl.h>
-#endif
#include <filename.h>
#include <intprops.h>
#include <min-max.h>
@@ -94,10 +91,6 @@ char *w32_getenv (const char *);
# pragma GCC diagnostic ignored "-Wformat-truncation=2"
#endif
-#if !defined O_PATH && !defined WINDOWSNT
-# define O_PATH O_SEARCH
-#endif
-
/* Name used to invoke this program. */
static char const *progname;
@@ -123,6 +116,9 @@ static bool eval;
/* True means open a new frame. --create-frame etc. */
static bool create_frame;
+/* True means reuse a frame if it already exists. */
+static bool reuse_frame;
+
/* The display on which Emacs should work. --display. */
static char const *display;
@@ -172,6 +168,7 @@ static struct option const longopts[] =
{ "tty", no_argument, NULL, 't' },
{ "nw", no_argument, NULL, 't' },
{ "create-frame", no_argument, NULL, 'c' },
+ { "reuse-frame", no_argument, NULL, 'r' },
{ "alternate-editor", required_argument, NULL, 'a' },
{ "frame-parameters", required_argument, NULL, 'F' },
#ifdef SOCKETS_IN_FILE_SYSTEM
@@ -558,6 +555,11 @@ decode_options (int argc, char **argv)
create_frame = true;
break;
+ case 'r':
+ create_frame = true;
+ reuse_frame = true;
+ break;
+
case 'p':
parent_id = optarg;
create_frame = true;
@@ -601,9 +603,16 @@ decode_options (int argc, char **argv)
alt_display = "ns";
#elif defined (HAVE_NTGUI)
alt_display = "w32";
+#elif defined (HAVE_HAIKU)
+ alt_display = "be";
#endif
+#ifdef HAVE_PGTK
+ display = egetenv ("WAYLAND_DISPLAY");
+ alt_display = egetenv ("DISPLAY");
+#else
display = egetenv ("DISPLAY");
+#endif
}
if (!display)
@@ -654,6 +663,8 @@ The following OPTIONS are accepted:\n\
-nw, -t, --tty Open a new Emacs frame on the current terminal\n\
-c, --create-frame Create a new frame instead of trying to\n\
use the current Emacs frame\n\
+-r, --reuse-frame Create a new frame if none exists, otherwise\n\
+ use the current Emacs frame\n\
", "\
-F ALIST, --frame-parameters=ALIST\n\
Set the parameters of a new frame\n\
@@ -1135,6 +1146,12 @@ process_grouping (void)
#ifdef SOCKETS_IN_FILE_SYSTEM
+# include <acl.h>
+
+# ifndef O_PATH
+# define O_PATH O_SEARCH
+# endif
+
/* A local socket address. The union avoids the need to cast. */
union local_sockaddr
{
@@ -1401,10 +1418,8 @@ local_sockname (int s, char sockname[socknamesize], int tmpdirlen,
/* Put the full address name into the buffer, since the caller might
need it for diagnostics. But don't overrun the buffer. */
uintmax_t uidmax = uid;
- int emacsdirlen;
int suffixlen = snprintf (sockname + tmpdirlen, socknamesize - tmpdirlen,
- "/emacs%"PRIuMAX"%n/%s", uidmax, &emacsdirlen,
- server_name);
+ "/emacs%"PRIuMAX"/%s", uidmax, server_name);
if (! (0 <= suffixlen && suffixlen < socknamesize - tmpdirlen))
return ENAMETOOLONG;
@@ -1412,7 +1427,8 @@ local_sockname (int s, char sockname[socknamesize], int tmpdirlen,
this user's directory and does not let others write to it; this
fends off some symlink attacks. To avoid races, keep the parent
directory open while checking. */
- char *emacsdirend = sockname + tmpdirlen + emacsdirlen;
+ char *emacsdirend = sockname + tmpdirlen + suffixlen -
+ strlen(server_name) - 1;
*emacsdirend = '\0';
int dir = openat (AT_FDCWD, sockname,
O_PATH | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
@@ -1458,7 +1474,6 @@ set_local_socket (char const *server_name)
else
{
/* socket_name is a file name component. */
- sock_status = ENOENT;
char const *xdg_runtime_dir = egetenv ("XDG_RUNTIME_DIR");
if (xdg_runtime_dir)
{
@@ -1468,7 +1483,7 @@ set_local_socket (char const *server_name)
? connect_socket (AT_FDCWD, sockname, s, 0)
: ENAMETOOLONG);
}
- if (sock_status == ENOENT)
+ else
{
char const *tmpdir = egetenv ("TMPDIR");
if (tmpdir)
@@ -1747,8 +1762,9 @@ start_daemon_and_retry_set_socket (void)
}
/* Try connecting, the daemon should have started by now. */
- message (true,
- "Emacs daemon should have started, trying to connect again\n");
+ if (!quiet)
+ message (true,
+ "Emacs daemon should have started, trying to connect again\n");
}
else if (dpid < 0)
{
@@ -1839,7 +1855,7 @@ start_daemon_and_retry_set_socket (void)
/* Try connecting, the daemon should have started by now. */
/* It's just a progress message, so don't pop a dialog if this is
emacsclientw. */
- if (!w32_window_app ())
+ if (!quiet && !w32_window_app ())
message (true,
"Emacs daemon should have started, trying to connect again\n");
#endif /* WINDOWSNT */
@@ -1943,7 +1959,7 @@ main (int argc, char **argv)
if (nowait)
send_to_emacs (emacs_socket, "-nowait ");
- if (!create_frame)
+ if (!create_frame || reuse_frame)
send_to_emacs (emacs_socket, "-current-frame ");
if (display)
diff --git a/lib-src/etags.c b/lib-src/etags.c
index 88b49f803e9..71f3464661c 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -5773,7 +5773,7 @@ static void
TEX_decode_env (const char *evarname, const char *defenv)
{
const char *env, *p;
- ptrdiff_t len;
+ ptrdiff_t len = 1;
/* Append default string to environment. */
env = getenv (evarname);
@@ -5782,8 +5782,13 @@ TEX_decode_env (const char *evarname, const char *defenv)
else
env = concat (env, defenv, "");
+ /* If the environment variable doesn't start with a colon, increase
+ the length of the token table. */
+ if (*env != ':')
+ len++;
+
/* Allocate a token table */
- for (len = 1, p = env; (p = strchr (p, ':')); )
+ for (p = env; (p = strchr (p, ':')); )
if (*++p)
len++;
TEX_toktab = xnew (len, linebuffer);
@@ -6259,7 +6264,7 @@ test_objc_is_mercury (char *this_file, language **lang)
}
}
- /* Fallback heuristic test. Not failsafe but errless in pratice. */
+ /* Fallback heuristic test. Not failsafe but errless in practice. */
ratio = ((float) rule_signs + percentage_signs + mercury_dots) / lines;
out:
diff --git a/lib-src/ntlib.c b/lib-src/ntlib.c
index bcbc0064318..c8bcf742fea 100644
--- a/lib-src/ntlib.c
+++ b/lib-src/ntlib.c
@@ -20,6 +20,9 @@ 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/>. */
+#define DEFER_MS_W32_H
+#include <config.h>
+
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
@@ -287,9 +290,6 @@ is_exec (const char * name)
stricmp (p, ".cmd") == 0));
}
-/* FIXME? This is in configure.ac now - is this still needed? */
-#define IS_DIRECTORY_SEP(x) ((x) == '/' || (x) == '\\')
-
/* We need stat/fsfat below because nt/inc/sys/stat.h defines struct
stat that is incompatible with the MS run-time libraries. */
int
diff --git a/lib-src/seccomp-filter.c b/lib-src/seccomp-filter.c
index dc568e035b5..e7496053a86 100644
--- a/lib-src/seccomp-filter.c
+++ b/lib-src/seccomp-filter.c
@@ -131,9 +131,12 @@ export_filter (const char *file,
int (*function) (const scmp_filter_ctx, int),
const char *name)
{
- int fd = TEMP_FAILURE_RETRY (
- open (file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC,
- 0644));
+ int fd;
+ do
+ fd = open (file,
+ O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC,
+ 0644);
+ while (fd < 0 && errno == EINTR);
if (fd < 0)
fail (errno, "open %s", file);
int status = function (ctx, fd);
@@ -348,6 +351,8 @@ main (int argc, char **argv)
calls at startup time to set up thread-local storage. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (execve));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (set_tid_address));
+ RULE (SCMP_ACT_ERRNO (EINVAL), SCMP_SYS (prctl),
+ SCMP_A0_32 (SCMP_CMP_EQ, PR_CAPBSET_READ));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (arch_prctl),
SCMP_A0_32 (SCMP_CMP_EQ, ARCH_SET_FS));
RULE (SCMP_ACT_ERRNO (EINVAL), SCMP_SYS (arch_prctl),
diff --git a/lib/_Noreturn.h b/lib/_Noreturn.h
index fb718bc0691..6fed3c79717 100644
--- a/lib/_Noreturn.h
+++ b/lib/_Noreturn.h
@@ -2,16 +2,16 @@
Copyright (C) 2011-2021 Free Software Foundation, Inc.
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
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
#ifndef _Noreturn
@@ -29,7 +29,7 @@
# elif ((!defined __cplusplus || defined __clang__) \
&& (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
|| (!defined __STRICT_ANSI__ \
- && (__4 < __GNUC__ + (7 <= __GNUC_MINOR__) \
+ && (4 < __GNUC__ + (7 <= __GNUC_MINOR__) \
|| (defined __apple_build_version__ \
? 6000000 <= __apple_build_version__ \
: 3 < __clang_major__ + (5 <= __clang_minor__))))))
diff --git a/lib/af_alg.h b/lib/af_alg.h
index 4c5854cc99b..f0fe7fc0554 100644
--- a/lib/af_alg.h
+++ b/lib/af_alg.h
@@ -1,18 +1,18 @@
/* af_alg.h - Compute message digests from file streams and buffers.
- Copyright (C) 2018-2020 Free Software Foundation, Inc.
+ Copyright (C) 2018-2021 Free Software Foundation, Inc.
- 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 2, or (at your option) any
- later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
/* Written by Matteo Croce <mcroce@redhat.com>, 2018.
Documentation by Bruno Haible <bruno@clisp.org>, 2018. */
diff --git a/lib/alloca.in.h b/lib/alloca.in.h
index 0a6137e037c..65c2d4d9399 100644
--- a/lib/alloca.in.h
+++ b/lib/alloca.in.h
@@ -3,20 +3,18 @@
Copyright (C) 1995, 1999, 2001-2004, 2006-2021 Free Software Foundation,
Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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
- General Public License for more details.
+ 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 General Public
- License along with this program; if not, see
- <https://www.gnu.org/licenses/>.
- */
+ 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/>. */
/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H
means there is a real alloca function. */
diff --git a/lib/allocator.c b/lib/allocator.c
index 2c1a3da03aa..2262de9ff3b 100644
--- a/lib/allocator.c
+++ b/lib/allocator.c
@@ -1,3 +1,20 @@
+/* Memory allocators such as malloc+free.
+
+ Copyright (C) 2011-2021 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/>. */
+
#define _GL_USE_STDLIB_ALLOC 1
#include <config.h>
#include "allocator.h"
diff --git a/lib/allocator.h b/lib/allocator.h
index cfa05357744..f0e8f348963 100644
--- a/lib/allocator.h
+++ b/lib/allocator.h
@@ -2,17 +2,17 @@
Copyright (C) 2011-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Paul Eggert. */
diff --git a/lib/arg-nonnull.h b/lib/arg-nonnull.h
index 5b81b50a87d..b4de241e90f 100644
--- a/lib/arg-nonnull.h
+++ b/lib/arg-nonnull.h
@@ -2,16 +2,16 @@
Copyright (C) 2009-2021 Free Software Foundation, Inc.
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
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools
diff --git a/lib/attribute.h b/lib/attribute.h
index 82245279eb1..eb36188d48a 100644
--- a/lib/attribute.h
+++ b/lib/attribute.h
@@ -2,17 +2,17 @@
Copyright 2020-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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
- General Public License for more details.
+ 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 General Public License
+ 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/>. */
/* Written by Paul Eggert. */
@@ -32,7 +32,7 @@
/* This file defines two types of attributes:
- * C2X standard attributes. These have macro names that do not begin with
+ * C2x standard attributes. These have macro names that do not begin with
'ATTRIBUTE_'.
* Selected GCC attributes; see:
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
@@ -76,6 +76,14 @@
/* Applies to: function, pointer to function, function types. */
#define ATTRIBUTE_ALLOC_SIZE(args) _GL_ATTRIBUTE_ALLOC_SIZE (args)
+/* ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
+ that can be freed by passing them as the Ith argument to the
+ function F.
+ ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that
+ can be freed via 'free'; it can be used only after declaring 'free'. */
+/* Applies to: functions. Cannot be used on inline functions. */
+#define ATTRIBUTE_DEALLOC(f, i) _GL_ATTRIBUTE_DEALLOC(f, i)
+#define ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC_FREE
/* Attributes for variadic functions. */
diff --git a/lib/binary-io.c b/lib/binary-io.c
index f2678972ef7..adc0ae2b0c0 100644
--- a/lib/binary-io.c
+++ b/lib/binary-io.c
@@ -1,17 +1,17 @@
/* Binary mode I/O.
Copyright 2017-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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 <config.h>
diff --git a/lib/binary-io.h b/lib/binary-io.h
index 8654fd2d39f..642f08b1ba3 100644
--- a/lib/binary-io.h
+++ b/lib/binary-io.h
@@ -1,17 +1,17 @@
/* Binary mode I/O.
Copyright (C) 2001, 2003, 2005, 2008-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
#ifndef _BINARY_H
@@ -47,7 +47,7 @@ _GL_INLINE_HEADER_BEGIN
/* Use a function rather than a macro, to avoid gcc warnings
"warning: statement with no effect". */
BINARY_IO_INLINE int
-__gl_setmode (int fd _GL_UNUSED, int mode _GL_UNUSED)
+__gl_setmode (_GL_UNUSED int fd, _GL_UNUSED int mode)
{
return O_BINARY;
}
diff --git a/lib/byteswap.in.h b/lib/byteswap.in.h
index 2b7d5abe1b6..113f8780273 100644
--- a/lib/byteswap.in.h
+++ b/lib/byteswap.in.h
@@ -2,17 +2,17 @@
Copyright (C) 2005, 2007, 2009-2021 Free Software Foundation, Inc.
Written by Oskar Liljeblad <oskar@osk.mine.nu>, 2005.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
#ifndef _GL_BYTESWAP_H
diff --git a/lib/c++defs.h b/lib/c++defs.h
index 39df1bc76bc..a47b61a0098 100644
--- a/lib/c++defs.h
+++ b/lib/c++defs.h
@@ -2,16 +2,16 @@
Copyright (C) 2010-2021 Free Software Foundation, Inc.
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
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
#ifndef _GL_CXXDEFS_H
diff --git a/lib/c-ctype.c b/lib/c-ctype.c
index 5d9d4d87a61..300f97c292f 100644
--- a/lib/c-ctype.c
+++ b/lib/c-ctype.c
@@ -1,3 +1,21 @@
+/* Character handling in C locale.
+
+ Copyright (C) 2003-2021 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/>. */
+
#include <config.h>
+
#define C_CTYPE_INLINE _GL_EXTERN_INLINE
#include "c-ctype.h"
diff --git a/lib/c-ctype.h b/lib/c-ctype.h
index bf24a88310e..3a652ac1f28 100644
--- a/lib/c-ctype.h
+++ b/lib/c-ctype.h
@@ -7,18 +7,18 @@
Copyright (C) 2000-2003, 2006, 2008-2021 Free Software Foundation, Inc.
-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/>. */
+ 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/>. */
#ifndef C_CTYPE_H
#define C_CTYPE_H
diff --git a/lib/c-strcase.h b/lib/c-strcase.h
index 089edfe7ebe..82f99bb06b8 100644
--- a/lib/c-strcase.h
+++ b/lib/c-strcase.h
@@ -2,18 +2,18 @@
Copyright (C) 1995-1996, 2001, 2003, 2005, 2009-2021 Free Software
Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
#ifndef C_STRCASE_H
#define C_STRCASE_H
diff --git a/lib/c-strcasecmp.c b/lib/c-strcasecmp.c
index 55479d6a338..3c224550828 100644
--- a/lib/c-strcasecmp.c
+++ b/lib/c-strcasecmp.c
@@ -1,18 +1,18 @@
/* c-strcasecmp.c -- case insensitive string comparator in C locale
Copyright (C) 1998-1999, 2005-2006, 2009-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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 <config.h>
diff --git a/lib/c-strncasecmp.c b/lib/c-strncasecmp.c
index 02bc0f2ecd5..f3ca786cb33 100644
--- a/lib/c-strncasecmp.c
+++ b/lib/c-strncasecmp.c
@@ -1,18 +1,18 @@
/* c-strncasecmp.c -- case insensitive string comparator in C locale
Copyright (C) 1998-1999, 2005-2006, 2009-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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 <config.h>
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index b7dba08994d..92e96397206 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -3,16 +3,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
@@ -21,7 +21,6 @@
optimizes away the name == NULL test below. */
# define _GL_ARG_NONNULL(params)
-# define _GL_USE_STDLIB_ALLOC 1
# include <libc-config.h>
#endif
@@ -75,7 +74,12 @@
# define __pathconf pathconf
# define __rawmemchr rawmemchr
# define __readlink readlink
-# define __stat stat
+# if IN_RELOCWRAPPER
+ /* When building the relocatable program wrapper, use the system's memmove
+ function, not the gnulib override, otherwise we would get a link error.
+ */
+# undef memmove
+# endif
#endif
/* Suppress bogus GCC -Wmaybe-uninitialized warnings. */
@@ -100,7 +104,7 @@ file_accessible (char const *file)
return __faccessat (AT_FDCWD, file, F_OK, AT_EACCESS) == 0;
# else
struct stat st;
- return __stat (file, &st) == 0 || errno == EOVERFLOW;
+ return stat (file, &st) == 0 || errno == EOVERFLOW;
# endif
}
diff --git a/lib/careadlinkat.c b/lib/careadlinkat.c
index 18cfc114b69..9d0c125ecb9 100644
--- a/lib/careadlinkat.c
+++ b/lib/careadlinkat.c
@@ -3,17 +3,17 @@
Copyright (C) 2001, 2003-2004, 2007, 2009-2021 Free Software Foundation,
Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */
@@ -22,6 +22,9 @@
#include "careadlinkat.h"
+#include "idx.h"
+#include "minmax.h"
+
#include <errno.h>
#include <limits.h>
#include <string.h>
@@ -65,11 +68,6 @@ readlink_stk (int fd, char const *filename,
ssize_t (*preadlinkat) (int, char const *, char *, size_t),
char stack_buf[STACK_BUF_SIZE])
{
- char *buf;
- size_t buf_size;
- size_t buf_size_max =
- SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
-
if (! alloc)
alloc = &stdlib_allocator;
@@ -79,14 +77,14 @@ readlink_stk (int fd, char const *filename,
buffer_size = STACK_BUF_SIZE;
}
- buf = buffer;
- buf_size = buffer_size;
+ char *buf = buffer;
+ idx_t buf_size_max = MIN (IDX_MAX, MIN (SSIZE_MAX, SIZE_MAX));
+ idx_t buf_size = MIN (buffer_size, buf_size_max);
while (buf)
{
/* Attempt to read the link into the current buffer. */
- ssize_t link_length = preadlinkat (fd, filename, buf, buf_size);
- size_t link_size;
+ idx_t link_length = preadlinkat (fd, filename, buf, buf_size);
if (link_length < 0)
{
if (buf != buffer)
@@ -98,7 +96,7 @@ readlink_stk (int fd, char const *filename,
return NULL;
}
- link_size = link_length;
+ idx_t link_size = link_length;
if (link_size < buf_size)
{
@@ -127,17 +125,13 @@ readlink_stk (int fd, char const *filename,
if (buf != buffer)
alloc->free (buf);
- if (buf_size < buf_size_max / 2)
- buf_size = 2 * buf_size + 1;
- else if (buf_size < buf_size_max)
- buf_size = buf_size_max;
- else if (buf_size_max < SIZE_MAX)
+ if (buf_size_max / 2 <= buf_size)
{
errno = ENAMETOOLONG;
return NULL;
}
- else
- break;
+
+ buf_size = 2 * buf_size + 1;
buf = alloc->allocate (buf_size);
}
diff --git a/lib/careadlinkat.h b/lib/careadlinkat.h
index c506fac3cbe..a3517b827a1 100644
--- a/lib/careadlinkat.h
+++ b/lib/careadlinkat.h
@@ -2,17 +2,17 @@
Copyright (C) 2011-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */
diff --git a/lib/cdefs.h b/lib/cdefs.h
index 17a0919cd83..4dac9d264d2 100644
--- a/lib/cdefs.h
+++ b/lib/cdefs.h
@@ -2,16 +2,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
@@ -259,9 +259,7 @@
# define __attribute_const__ /* Ignore */
#endif
-#if defined __STDC_VERSION__ && 201710L < __STDC_VERSION__
-# define __attribute_maybe_unused__ [[__maybe_unused__]]
-#elif __GNUC_PREREQ (2,7) || __glibc_has_attribute (__unused__)
+#if __GNUC_PREREQ (2,7) || __glibc_has_attribute (__unused__)
# define __attribute_maybe_unused__ __attribute__ ((__unused__))
#else
# define __attribute_maybe_unused__ /* Ignore */
@@ -320,16 +318,28 @@
#endif
/* The nonnull function attribute marks pointer parameters that
- must not be NULL. */
-#ifndef __nonnull
+ must not be NULL. This has the name __nonnull in glibc,
+ and __attribute_nonnull__ in files shared with Gnulib to avoid
+ collision with a different __nonnull in DragonFlyBSD 5.9. */
+#ifndef __attribute_nonnull__
# if __GNUC_PREREQ (3,3) || __glibc_has_attribute (__nonnull__)
-# define __nonnull(params) __attribute__ ((__nonnull__ params))
+# define __attribute_nonnull__(params) __attribute__ ((__nonnull__ params))
+# else
+# define __attribute_nonnull__(params)
+# endif
+#endif
+#ifndef __nonnull
+# define __nonnull(params) __attribute_nonnull__ (params)
+#endif
+
+/* The returns_nonnull function attribute marks the return type of the function
+ as always being non-null. */
+#ifndef __returns_nonnull
+# if __GNUC_PREREQ (4, 9) || __glibc_has_attribute (__returns_nonnull__)
+# define __returns_nonnull __attribute__ ((__returns_nonnull__))
# else
-# define __nonnull(params)
+# define __returns_nonnull
# endif
-#elif !defined __GLIBC__
-# undef __nonnull
-# define __nonnull(params) _GL_ATTRIBUTE_NONNULL (params)
#endif
/* If fortification mode, we warn about unused results of certain
@@ -485,9 +495,9 @@
[!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]
#endif
-/* The #ifndef lets Gnulib avoid including these on non-glibc
- platforms, where the includes typically do not exist. */
-#ifndef __WORDSIZE
+/* Gnulib avoids including these, as they don't work on non-glibc or
+ older glibc platforms. */
+#ifndef __GNULIB_CDEFS
# include <bits/wordsize.h>
# include <bits/long-double.h>
#endif
@@ -594,9 +604,26 @@ _Static_assert (0, "IEEE 128-bits long double requires redirection on this platf
array according to access mode, or at least one element when
size-index is not provided:
access (access-mode, <ref-index> [, <size-index>]) */
-#define __attr_access(x) __attribute__ ((__access__ x))
+# define __attr_access(x) __attribute__ ((__access__ x))
+# if __GNUC_PREREQ (11, 0)
+# define __attr_access_none(argno) __attribute__ ((__access__ (__none__, argno)))
+# else
+# define __attr_access_none(argno)
+# endif
#else
# define __attr_access(x)
+# define __attr_access_none(argno)
+#endif
+
+#if __GNUC_PREREQ (11, 0)
+/* Designates dealloc as a function to call to deallocate objects
+ allocated by the declared function. */
+# define __attr_dealloc(dealloc, argno) \
+ __attribute__ ((__malloc__ (dealloc, argno)))
+# define __attr_dealloc_free __attr_dealloc (__builtin_free, 1)
+#else
+# define __attr_dealloc(dealloc, argno)
+# define __attr_dealloc_free
#endif
/* Specify that a function such as setjmp or vfork may return
diff --git a/lib/cloexec.c b/lib/cloexec.c
index 8363ddaa609..7defa934462 100644
--- a/lib/cloexec.c
+++ b/lib/cloexec.c
@@ -2,20 +2,20 @@
Copyright (C) 1991, 2004-2006, 2009-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>.
+ 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/>. */
- The code is taken from glibc/manual/llio.texi */
+/* The code is taken from glibc/manual/llio.texi */
#include <config.h>
diff --git a/lib/cloexec.h b/lib/cloexec.h
index 5ca0e6413e7..97a3659efb6 100644
--- a/lib/cloexec.h
+++ b/lib/cloexec.h
@@ -2,20 +2,18 @@
Copyright (C) 2004, 2009-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>.
-
-*/
+ 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>
diff --git a/lib/close-stream.h b/lib/close-stream.h
index be3d4196b06..8a58a48e61a 100644
--- a/lib/close-stream.h
+++ b/lib/close-stream.h
@@ -1,2 +1,20 @@
+/* Close a stream, with nicer error checking than fclose's.
+
+ Copyright (C) 2006-2021 Free Software Foundation, Inc.
+
+ 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 the Free Software Foundation; either version 3 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 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/>. */
+
#include <stdio.h>
+
int close_stream (FILE *stream);
diff --git a/lib/copy-file-range.c b/lib/copy-file-range.c
index e73c78b5aa7..17df577055f 100644
--- a/lib/copy-file-range.c
+++ b/lib/copy-file-range.c
@@ -1,17 +1,17 @@
/* Stub for copy_file_range
Copyright 2019-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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 <config.h>
diff --git a/lib/count-leading-zeros.c b/lib/count-leading-zeros.c
index d0c0704f582..7cf1ac2ff0c 100644
--- a/lib/count-leading-zeros.c
+++ b/lib/count-leading-zeros.c
@@ -1,3 +1,21 @@
+/* Count the number of leading 0 bits in a word.
+
+ Copyright (C) 2012-2021 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/>. */
+
#include <config.h>
+
#define COUNT_LEADING_ZEROS_INLINE _GL_EXTERN_INLINE
#include "count-leading-zeros.h"
diff --git a/lib/count-leading-zeros.h b/lib/count-leading-zeros.h
index 575ec3b4d0e..cef529ac136 100644
--- a/lib/count-leading-zeros.h
+++ b/lib/count-leading-zeros.h
@@ -1,17 +1,17 @@
/* count-leading-zeros.h -- counts the number of leading 0 bits in a word.
Copyright (C) 2012-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Eric Blake. */
diff --git a/lib/count-one-bits.c b/lib/count-one-bits.c
index 66341d77cda..d9b4f5e848d 100644
--- a/lib/count-one-bits.c
+++ b/lib/count-one-bits.c
@@ -1,4 +1,22 @@
+/* Count the number of 1-bits in a word.
+
+ Copyright (C) 2012-2021 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/>. */
+
#include <config.h>
+
#define COUNT_ONE_BITS_INLINE _GL_EXTERN_INLINE
#include "count-one-bits.h"
diff --git a/lib/count-one-bits.h b/lib/count-one-bits.h
index 1a14f11f152..5e87a572b0a 100644
--- a/lib/count-one-bits.h
+++ b/lib/count-one-bits.h
@@ -1,17 +1,17 @@
/* count-one-bits.h -- counts the number of 1-bits in a word.
Copyright (C) 2007-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Ben Pfaff. */
diff --git a/lib/count-trailing-zeros.c b/lib/count-trailing-zeros.c
index f3da8867428..538b01dc023 100644
--- a/lib/count-trailing-zeros.c
+++ b/lib/count-trailing-zeros.c
@@ -1,3 +1,21 @@
+/* Count the number of trailing 0 bits in a word.
+
+ Copyright 2013-2021 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/>. */
+
#include <config.h>
+
#define COUNT_TRAILING_ZEROS_INLINE _GL_EXTERN_INLINE
#include "count-trailing-zeros.h"
diff --git a/lib/count-trailing-zeros.h b/lib/count-trailing-zeros.h
index 5a8ef563ea2..f81674c571a 100644
--- a/lib/count-trailing-zeros.h
+++ b/lib/count-trailing-zeros.h
@@ -1,17 +1,17 @@
/* count-trailing-zeros.h -- counts the number of trailing 0 bits in a word.
Copyright 2013-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Paul Eggert. */
diff --git a/lib/dirent.in.h b/lib/dirent.in.h
index 4666972b150..4deb0cb466a 100644
--- a/lib/dirent.in.h
+++ b/lib/dirent.in.h
@@ -1,17 +1,17 @@
/* A GNU-like <dirent.h>.
Copyright (C) 2006-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
#ifndef _@GUARD_PREFIX@_DIRENT_H
@@ -55,6 +55,28 @@ typedef struct gl_directory DIR;
# endif
#endif
+/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
+ that can be freed by passing them as the Ith argument to the
+ function F. */
+#ifndef _GL_ATTRIBUTE_DEALLOC
+# if __GNUC__ >= 11
+# define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i)))
+# else
+# define _GL_ATTRIBUTE_DEALLOC(f, i)
+# endif
+#endif
+
+/* _GL_ATTRIBUTE_MALLOC declares that the function returns a pointer to freshly
+ allocated memory. */
+/* Applies to: functions. */
+#ifndef _GL_ATTRIBUTE_MALLOC
+# if __GNUC__ >= 3 || defined __clang__
+# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
+# else
+# define _GL_ATTRIBUTE_MALLOC
+# endif
+#endif
+
/* The __attribute__ feature is available in gcc versions 2.5 and later.
The attribute __pure__ was added in gcc 2.96. */
#ifndef _GL_ATTRIBUTE_PURE
@@ -74,6 +96,30 @@ typedef struct gl_directory DIR;
/* Declare overridden functions. */
+#if @GNULIB_CLOSEDIR@
+# if @REPLACE_CLOSEDIR@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef closedir
+# define closedir rpl_closedir
+# define GNULIB_defined_closedir 1
+# endif
+_GL_FUNCDECL_RPL (closedir, int, (DIR *dirp) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (closedir, int, (DIR *dirp));
+# else
+# if !@HAVE_CLOSEDIR@
+_GL_FUNCDECL_SYS (closedir, int, (DIR *dirp) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (closedir, int, (DIR *dirp));
+# endif
+_GL_CXXALIASWARN (closedir);
+#elif defined GNULIB_POSIXCHECK
+# undef closedir
+# if HAVE_RAW_DECL_CLOSEDIR
+_GL_WARN_ON_USE (closedir, "closedir is not portable - "
+ "use gnulib module closedir for portability");
+# endif
+#endif
+
#if @GNULIB_OPENDIR@
# if @REPLACE_OPENDIR@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
@@ -81,20 +127,36 @@ typedef struct gl_directory DIR;
# define opendir rpl_opendir
# define GNULIB_defined_opendir 1
# endif
-_GL_FUNCDECL_RPL (opendir, DIR *, (const char *dir_name) _GL_ARG_NONNULL ((1)));
+_GL_FUNCDECL_RPL (opendir, DIR *,
+ (const char *dir_name)
+ _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
_GL_CXXALIAS_RPL (opendir, DIR *, (const char *dir_name));
# else
-# if !@HAVE_OPENDIR@
-_GL_FUNCDECL_SYS (opendir, DIR *, (const char *dir_name) _GL_ARG_NONNULL ((1)));
+# if !@HAVE_OPENDIR@ || __GNUC__ >= 11
+_GL_FUNCDECL_SYS (opendir, DIR *,
+ (const char *dir_name)
+ _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
# endif
_GL_CXXALIAS_SYS (opendir, DIR *, (const char *dir_name));
# endif
_GL_CXXALIASWARN (opendir);
-#elif defined GNULIB_POSIXCHECK
-# undef opendir
-# if HAVE_RAW_DECL_OPENDIR
+#else
+# if @GNULIB_CLOSEDIR@ && __GNUC__ >= 11 && !defined opendir
+/* For -Wmismatched-dealloc: Associate opendir with closedir or
+ rpl_closedir. */
+_GL_FUNCDECL_SYS (opendir, DIR *,
+ (const char *dir_name)
+ _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef opendir
+# if HAVE_RAW_DECL_OPENDIR
_GL_WARN_ON_USE (opendir, "opendir is not portable - "
"use gnulib module opendir for portability");
+# endif
# endif
#endif
@@ -126,30 +188,6 @@ _GL_WARN_ON_USE (rewinddir, "rewinddir is not portable - "
# endif
#endif
-#if @GNULIB_CLOSEDIR@
-# if @REPLACE_CLOSEDIR@
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# undef closedir
-# define closedir rpl_closedir
-# define GNULIB_defined_closedir 1
-# endif
-_GL_FUNCDECL_RPL (closedir, int, (DIR *dirp) _GL_ARG_NONNULL ((1)));
-_GL_CXXALIAS_RPL (closedir, int, (DIR *dirp));
-# else
-# if !@HAVE_CLOSEDIR@
-_GL_FUNCDECL_SYS (closedir, int, (DIR *dirp) _GL_ARG_NONNULL ((1)));
-# endif
-_GL_CXXALIAS_SYS (closedir, int, (DIR *dirp));
-# endif
-_GL_CXXALIASWARN (closedir);
-#elif defined GNULIB_POSIXCHECK
-# undef closedir
-# if HAVE_RAW_DECL_CLOSEDIR
-_GL_WARN_ON_USE (closedir, "closedir is not portable - "
- "use gnulib module closedir for portability");
-# endif
-#endif
-
#if @GNULIB_DIRFD@
/* Return the file descriptor associated with the given directory stream,
or -1 if none exists. */
@@ -200,20 +238,33 @@ _GL_WARN_ON_USE (dirfd, "dirfd is unportable - "
# undef fdopendir
# define fdopendir rpl_fdopendir
# endif
-_GL_FUNCDECL_RPL (fdopendir, DIR *, (int fd));
+_GL_FUNCDECL_RPL (fdopendir, DIR *,
+ (int fd)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
_GL_CXXALIAS_RPL (fdopendir, DIR *, (int fd));
# else
-# if !@HAVE_FDOPENDIR@ || !@HAVE_DECL_FDOPENDIR@
-_GL_FUNCDECL_SYS (fdopendir, DIR *, (int fd));
+# if !@HAVE_FDOPENDIR@ || !@HAVE_DECL_FDOPENDIR@ || __GNUC__ >= 11
+_GL_FUNCDECL_SYS (fdopendir, DIR *,
+ (int fd)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
# endif
_GL_CXXALIAS_SYS (fdopendir, DIR *, (int fd));
# endif
_GL_CXXALIASWARN (fdopendir);
-#elif defined GNULIB_POSIXCHECK
-# undef fdopendir
-# if HAVE_RAW_DECL_FDOPENDIR
+#else
+# if @GNULIB_CLOSEDIR@ && __GNUC__ >= 11 && !defined fdopendir
+/* For -Wmismatched-dealloc: Associate fdopendir with closedir or
+ rpl_closedir. */
+_GL_FUNCDECL_SYS (fdopendir, DIR *,
+ (int fd)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef fdopendir
+# if HAVE_RAW_DECL_FDOPENDIR
_GL_WARN_ON_USE (fdopendir, "fdopendir is unportable - "
"use gnulib module fdopendir for portability");
+# endif
# endif
#endif
diff --git a/lib/dirfd.c b/lib/dirfd.c
index ced7531c5e0..640cb4ff13a 100644
--- a/lib/dirfd.c
+++ b/lib/dirfd.c
@@ -2,17 +2,17 @@
Copyright (C) 2001, 2006, 2008-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Jim Meyering. */
diff --git a/lib/dtoastr.c b/lib/dtoastr.c
index aed181d66b1..5baba92922a 100644
--- a/lib/dtoastr.c
+++ b/lib/dtoastr.c
@@ -1,2 +1,19 @@
+/* Convert 'double' to accurate string.
+
+ Copyright (C) 2010-2021 Free Software Foundation, Inc.
+
+ 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 the Free Software Foundation; either version 3 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 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/>. */
+
#define LENGTH 2
#include "ftoastr.c"
diff --git a/lib/dup2.c b/lib/dup2.c
index c4a0a29fbd0..53e5552132c 100644
--- a/lib/dup2.c
+++ b/lib/dup2.c
@@ -2,17 +2,17 @@
Copyright (C) 1999, 2004-2007, 2009-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* written by Paul Eggert */
diff --git a/lib/dynarray.h b/lib/dynarray.h
index 6da3e87e55f..ec64273b3a1 100644
--- a/lib/dynarray.h
+++ b/lib/dynarray.h
@@ -1,31 +1,284 @@
/* Type-safe arrays which grow dynamically.
Copyright 2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
-/* Written by Paul Eggert, 2021. */
+/* Written by Paul Eggert and Bruno Haible, 2021. */
#ifndef _GL_DYNARRAY_H
#define _GL_DYNARRAY_H
-#include <libc-config.h>
+/* Before including this file, you need to define:
+ DYNARRAY_STRUCT
+ The struct tag of dynamic array to be defined.
+
+ DYNARRAY_ELEMENT
+ The type name of the element type. Elements are copied
+ as if by memcpy, and can change address as the dynamic
+ array grows.
+
+ DYNARRAY_PREFIX
+ The prefix of the functions which are defined.
+
+ The following parameters are optional:
+
+ DYNARRAY_ELEMENT_FREE
+ DYNARRAY_ELEMENT_FREE (E) is evaluated to deallocate the
+ contents of elements. E is of type DYNARRAY_ELEMENT *.
+
+ DYNARRAY_ELEMENT_INIT
+ DYNARRAY_ELEMENT_INIT (E) is evaluated to initialize a new
+ element. E is of type DYNARRAY_ELEMENT *.
+ If DYNARRAY_ELEMENT_FREE but not DYNARRAY_ELEMENT_INIT is
+ defined, new elements are automatically zero-initialized.
+ Otherwise, new elements have undefined contents.
+
+ DYNARRAY_INITIAL_SIZE
+ The size of the statically allocated array (default:
+ at least 2, more elements if they fit into 128 bytes).
+ Must be a preprocessor constant. If DYNARRAY_INITIAL_SIZE is 0,
+ there is no statically allocated array at, and all non-empty
+ arrays are heap-allocated.
+
+ DYNARRAY_FINAL_TYPE
+ The name of the type which holds the final array. If not
+ defined, is PREFIX##finalize not provided. DYNARRAY_FINAL_TYPE
+ must be a struct type, with members of type DYNARRAY_ELEMENT and
+ size_t at the start (in this order).
+
+ These macros are undefined after this header file has been
+ included.
+
+ The following types are provided (their members are private to the
+ dynarray implementation):
+
+ struct DYNARRAY_STRUCT
+
+ The following functions are provided:
+ */
+
+/* Initialize a dynamic array object. This must be called before any
+ use of the object. */
+#if 0
+static void
+ DYNARRAY_PREFIX##init (struct DYNARRAY_STRUCT *list);
+#endif
+
+/* Deallocate the dynamic array and its elements. */
+#if 0
+static void
+ DYNARRAY_PREFIX##free (struct DYNARRAY_STRUCT *list);
+#endif
+
+/* Return true if the dynamic array is in an error state. */
+#if 0
+static bool
+ DYNARRAY_PREFIX##has_failed (const struct DYNARRAY_STRUCT *list);
+#endif
+
+/* Mark the dynamic array as failed. All elements are deallocated as
+ a side effect. */
+#if 0
+static void
+ DYNARRAY_PREFIX##mark_failed (struct DYNARRAY_STRUCT *list);
+#endif
+
+/* Return the number of elements which have been added to the dynamic
+ array. */
+#if 0
+static size_t
+ DYNARRAY_PREFIX##size (const struct DYNARRAY_STRUCT *list);
+#endif
+
+/* Return a pointer to the first array element, if any. For a
+ zero-length array, the pointer can be NULL even though the dynamic
+ array has not entered the failure state. */
+#if 0
+static DYNARRAY_ELEMENT *
+ DYNARRAY_PREFIX##begin (const struct DYNARRAY_STRUCT *list);
+#endif
+
+/* Return a pointer one element past the last array element. For a
+ zero-length array, the pointer can be NULL even though the dynamic
+ array has not entered the failure state. */
+#if 0
+static DYNARRAY_ELEMENT *
+ DYNARRAY_PREFIX##end (const struct DYNARRAY_STRUCT *list);
+#endif
+
+/* Return a pointer to the array element at INDEX. Terminate the
+ process if INDEX is out of bounds. */
+#if 0
+static DYNARRAY_ELEMENT *
+ DYNARRAY_PREFIX##at (struct DYNARRAY_STRUCT *list, size_t index);
+#endif
+
+/* Add ITEM at the end of the array, enlarging it by one element.
+ Mark *LIST as failed if the dynamic array allocation size cannot be
+ increased. */
+#if 0
+static void
+ DYNARRAY_PREFIX##add (struct DYNARRAY_STRUCT *list,
+ DYNARRAY_ELEMENT item);
+#endif
+
+/* Allocate a place for a new element in *LIST and return a pointer to
+ it. The pointer can be NULL if the dynamic array cannot be
+ enlarged due to a memory allocation failure. */
+#if 0
+static DYNARRAY_ELEMENT *
+ DYNARRAY_PREFIX##emplace (struct DYNARRAY_STRUCT *list);
+#endif
+
+/* Change the size of *LIST to SIZE. If SIZE is larger than the
+ existing size, new elements are added (which can be initialized).
+ Otherwise, the list is truncated, and elements are freed. Return
+ false on memory allocation failure (and mark *LIST as failed). */
+#if 0
+static bool
+ DYNARRAY_PREFIX##resize (struct DYNARRAY_STRUCT *list, size_t size);
+#endif
+
+/* Remove the last element of LIST if it is present. */
+#if 0
+static void
+ DYNARRAY_PREFIX##remove_last (struct DYNARRAY_STRUCT *list);
+#endif
+
+/* Remove all elements from the list. The elements are freed, but the
+ list itself is not. */
+#if 0
+static void
+ DYNARRAY_PREFIX##clear (struct DYNARRAY_STRUCT *list);
+#endif
+
+#if defined DYNARRAY_FINAL_TYPE
+/* Transfer the dynamic array to a permanent location at *RESULT.
+ Returns true on success on false on allocation failure. In either
+ case, *LIST is re-initialized and can be reused. A NULL pointer is
+ stored in *RESULT if LIST refers to an empty list. On success, the
+ pointer in *RESULT is heap-allocated and must be deallocated using
+ free. */
+#if 0
+static bool
+ DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *list,
+ DYNARRAY_FINAL_TYPE *result);
+#endif
+#else /* !defined DYNARRAY_FINAL_TYPE */
+/* Transfer the dynamic array to a heap-allocated array and return a
+ pointer to it. The pointer is NULL if memory allocation fails, or
+ if the array is empty, so this function should be used only for
+ arrays which are known not be empty (usually because they always
+ have a sentinel at the end). If LENGTHP is not NULL, the array
+ length is written to *LENGTHP. *LIST is re-initialized and can be
+ reused. */
+#if 0
+static DYNARRAY_ELEMENT *
+ DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *list,
+ size_t *lengthp);
+#endif
+#endif
+
+/* A minimal example which provides a growing list of integers can be
+ defined like this:
+
+ struct int_array
+ {
+ // Pointer to result array followed by its length,
+ // as required by DYNARRAY_FINAL_TYPE.
+ int *array;
+ size_t length;
+ };
+
+ #define DYNARRAY_STRUCT dynarray_int
+ #define DYNARRAY_ELEMENT int
+ #define DYNARRAY_PREFIX dynarray_int_
+ #define DYNARRAY_FINAL_TYPE struct int_array
+ #include <malloc/dynarray-skeleton.c>
+
+ To create a three-element array with elements 1, 2, 3, use this
+ code:
+
+ struct dynarray_int dyn;
+ dynarray_int_init (&dyn);
+ for (int i = 1; i <= 3; ++i)
+ {
+ int *place = dynarray_int_emplace (&dyn);
+ assert (place != NULL);
+ *place = i;
+ }
+ struct int_array result;
+ bool ok = dynarray_int_finalize (&dyn, &result);
+ assert (ok);
+ assert (result.length == 3);
+ assert (result.array[0] == 1);
+ assert (result.array[1] == 2);
+ assert (result.array[2] == 3);
+ free (result.array);
+
+ If the elements contain resources which must be freed, define
+ DYNARRAY_ELEMENT_FREE appropriately, like this:
+
+ struct str_array
+ {
+ char **array;
+ size_t length;
+ };
+
+ #define DYNARRAY_STRUCT dynarray_str
+ #define DYNARRAY_ELEMENT char *
+ #define DYNARRAY_ELEMENT_FREE(ptr) free (*ptr)
+ #define DYNARRAY_PREFIX dynarray_str_
+ #define DYNARRAY_FINAL_TYPE struct str_array
+ #include <malloc/dynarray-skeleton.c>
+ */
+
+
+/* The implementation is imported from glibc. */
+
+/* Avoid possible conflicts with symbols exported by the GNU libc. */
#define __libc_dynarray_at_failure gl_dynarray_at_failure
#define __libc_dynarray_emplace_enlarge gl_dynarray_emplace_enlarge
#define __libc_dynarray_finalize gl_dynarray_finalize
#define __libc_dynarray_resize_clear gl_dynarray_resize_clear
#define __libc_dynarray_resize gl_dynarray_resize
-#include <malloc/dynarray.h>
+
+#if defined DYNARRAY_STRUCT || defined DYNARRAY_ELEMENT || defined DYNARRAY_PREFIX
+
+# ifndef _GL_LIKELY
+/* Rely on __builtin_expect, as provided by the module 'builtin-expect'. */
+# define _GL_LIKELY(cond) __builtin_expect ((cond), 1)
+# define _GL_UNLIKELY(cond) __builtin_expect ((cond), 0)
+# endif
+
+/* Define auxiliary structs and declare auxiliary functions, common to all
+ instantiations of dynarray. */
+# include <malloc/dynarray.gl.h>
+
+/* Define the instantiation, specified through
+ DYNARRAY_STRUCT
+ DYNARRAY_ELEMENT
+ DYNARRAY_PREFIX
+ etc. */
+# include <malloc/dynarray-skeleton.gl.h>
+
+#else
+
+/* This file is being included from one of the malloc/dynarray_*.c files. */
+# include <malloc/dynarray.h>
+
+#endif
#endif /* _GL_DYNARRAY_H */
diff --git a/lib/eloop-threshold.h b/lib/eloop-threshold.h
index 27d07a72960..fcd30ab1e62 100644
--- a/lib/eloop-threshold.h
+++ b/lib/eloop-threshold.h
@@ -3,16 +3,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/errno.in.h b/lib/errno.in.h
index c6ab4e88e15..3cad9e2d62b 100644
--- a/lib/errno.in.h
+++ b/lib/errno.in.h
@@ -2,18 +2,18 @@
Copyright (C) 2008-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
#ifndef _@GUARD_PREFIX@_ERRNO_H
diff --git a/lib/euidaccess.c b/lib/euidaccess.c
index ef65961d81d..a86cebd179e 100644
--- a/lib/euidaccess.c
+++ b/lib/euidaccess.c
@@ -5,17 +5,17 @@
This file is part of the GNU C Library.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by David MacKenzie and Torbjorn Granlund.
diff --git a/lib/execinfo.c b/lib/execinfo.c
index 0bcd9f078ba..18a1051b25e 100644
--- a/lib/execinfo.c
+++ b/lib/execinfo.c
@@ -1,3 +1,21 @@
+/* Information about executables.
+
+ Copyright (C) 2012-2021 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/>. */
+
#include <config.h>
+
#define _GL_EXECINFO_INLINE _GL_EXTERN_INLINE
#include "execinfo.h"
diff --git a/lib/execinfo.in.h b/lib/execinfo.in.h
index 790bec087e1..98bb8039b7e 100644
--- a/lib/execinfo.in.h
+++ b/lib/execinfo.in.h
@@ -3,16 +3,16 @@
Copyright (C) 2012-2021 Free Software Foundation, Inc.
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
+ 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 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.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Paul Eggert. */
diff --git a/lib/explicit_bzero.c b/lib/explicit_bzero.c
index f50ed0875d7..2906c04d0fc 100644
--- a/lib/explicit_bzero.c
+++ b/lib/explicit_bzero.c
@@ -3,16 +3,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/fcntl.c b/lib/fcntl.c
index 9d6b10fa303..c744eb91e69 100644
--- a/lib/fcntl.c
+++ b/lib/fcntl.c
@@ -2,17 +2,17 @@
Copyright (C) 2009-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Eric Blake <ebb9@byu.net>. */
diff --git a/lib/fcntl.in.h b/lib/fcntl.in.h
index 0b14467c54d..26dedc30418 100644
--- a/lib/fcntl.in.h
+++ b/lib/fcntl.in.h
@@ -2,17 +2,17 @@
Copyright (C) 2006-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* written by Paul Eggert */
diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c
index c667ae9d24a..800af227ccc 100644
--- a/lib/file-has-acl.c
+++ b/lib/file-has-acl.c
@@ -1,6 +1,6 @@
/* Test whether a file has a nontrivial ACL. -*- coding: utf-8 -*-
- Copyright (C) 2002-2003, 2005-2020 Free Software Foundation, Inc.
+ Copyright (C) 2002-2003, 2005-2021 Free Software Foundation, Inc.
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
@@ -206,9 +206,7 @@ file_has_acl (char const *name, struct stat const *sb)
;
else
{
- int saved_errno = errno;
free (malloced);
- errno = saved_errno;
return -1;
}
}
@@ -281,9 +279,7 @@ file_has_acl (char const *name, struct stat const *sb)
;
else
{
- int saved_errno = errno;
free (malloced);
- errno = saved_errno;
return -1;
}
}
@@ -353,7 +349,7 @@ file_has_acl (char const *name, struct stat const *sb)
{
struct stat statbuf;
- if (stat (name, &statbuf) < 0)
+ if (stat (name, &statbuf) == -1 && errno != EOVERFLOW)
return -1;
return acl_nontrivial (count, entries);
@@ -418,11 +414,7 @@ file_has_acl (char const *name, struct stat const *sb)
if (errno != ENOSPC)
{
if (acl != aclbuf)
- {
- int saved_errno = errno;
- free (acl);
- errno = saved_errno;
- }
+ free (acl);
return -1;
}
aclsize = 2 * aclsize;
diff --git a/lib/filename.h b/lib/filename.h
index 541ffec0d53..dafe3dfddbb 100644
--- a/lib/filename.h
+++ b/lib/filename.h
@@ -3,16 +3,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/filevercmp.c b/lib/filevercmp.c
index 6b7226de6c3..fca23ec4fc2 100644
--- a/lib/filevercmp.c
+++ b/lib/filevercmp.c
@@ -3,18 +3,18 @@
Copyright (C) 2001 Anthony Towns <aj@azure.humbug.org.au>
Copyright (C) 2008-2021 Free Software Foundation, Inc.
- 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 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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 <config.h>
#include "filevercmp.h"
diff --git a/lib/filevercmp.h b/lib/filevercmp.h
index 5de212f4366..c210452938f 100644
--- a/lib/filevercmp.h
+++ b/lib/filevercmp.h
@@ -3,18 +3,18 @@
Copyright (C) 2001 Anthony Towns <aj@azure.humbug.org.au>
Copyright (C) 2008-2021 Free Software Foundation, Inc.
- 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 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
#ifndef FILEVERCMP_H
#define FILEVERCMP_H
diff --git a/lib/flexmember.h b/lib/flexmember.h
index 9f6e1bf1105..1b19a2bfd99 100644
--- a/lib/flexmember.h
+++ b/lib/flexmember.h
@@ -5,16 +5,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>.
diff --git a/lib/free.c b/lib/free.c
index 5c89787aba1..780f03dd119 100644
--- a/lib/free.c
+++ b/lib/free.c
@@ -2,32 +2,36 @@
Copyright (C) 2003, 2006, 2009-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* written by Paul Eggert */
#include <config.h>
+/* Specification. */
#include <stdlib.h>
-#include <errno.h>
+/* A function definition is only needed if HAVE_FREE_POSIX is not defined. */
+#if !HAVE_FREE_POSIX
+
+# include <errno.h>
void
rpl_free (void *p)
-#undef free
+# undef free
{
-#if defined __GNUC__ && !defined __clang__
+# if defined __GNUC__ && !defined __clang__
/* An invalid GCC optimization
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98396>
would optimize away the assignments in the code below, when link-time
@@ -39,9 +43,11 @@ rpl_free (void *p)
errno = 0;
free (p);
errno = err[errno == 0];
-#else
+# else
int err = errno;
free (p);
errno = err;
-#endif
+# endif
}
+
+#endif
diff --git a/lib/fsusage.c b/lib/fsusage.c
index 35de136cd8e..740cdc219a8 100644
--- a/lib/fsusage.c
+++ b/lib/fsusage.c
@@ -3,17 +3,17 @@
Copyright (C) 1991-1992, 1996, 1998-1999, 2002-2006, 2009-2021 Free Software
Foundation, Inc.
- 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 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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 <config.h>
diff --git a/lib/fsusage.h b/lib/fsusage.h
index e0657b3651a..b3f58d9994a 100644
--- a/lib/fsusage.h
+++ b/lib/fsusage.h
@@ -3,17 +3,17 @@
Copyright (C) 1991-1992, 1997, 2003-2006, 2009-2021 Free Software
Foundation, Inc.
- 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 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Space usage statistics for a file system. Blocks are 512-byte. */
diff --git a/lib/fsync.c b/lib/fsync.c
index a5280f281cb..99a932d770f 100644
--- a/lib/fsync.c
+++ b/lib/fsync.c
@@ -9,17 +9,17 @@
Copyright (C) 2008-2021 Free Software Foundation, Inc.
- This library 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 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 library is distributed in the hope that it will be useful,
+ 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
- General Public License for more details.
+ 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 General Public License
+ 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 <config.h>
diff --git a/lib/futimens.c b/lib/futimens.c
index 99eaba95df3..273cc87187c 100644
--- a/lib/futimens.c
+++ b/lib/futimens.c
@@ -1,17 +1,17 @@
/* Set the access and modification time of an open fd.
Copyright (C) 2009-2021 Free Software Foundation, Inc.
- 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 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* written by Eric Blake */
diff --git a/lib/getdtablesize.c b/lib/getdtablesize.c
index 56eaf5d32cf..5006c2d5c5a 100644
--- a/lib/getdtablesize.c
+++ b/lib/getdtablesize.c
@@ -2,17 +2,17 @@
Copyright (C) 2008-2021 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2008.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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 <config.h>
diff --git a/lib/getgroups.c b/lib/getgroups.c
index af602a74d3a..96665257f2e 100644
--- a/lib/getgroups.c
+++ b/lib/getgroups.c
@@ -2,17 +2,17 @@
Copyright (C) 1996, 1999, 2003, 2006-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* written by Jim Meyering */
@@ -30,7 +30,7 @@
/* Provide a stub that fails with ENOSYS, since there is no group
information available on mingw. */
int
-getgroups (int n _GL_UNUSED, GETGROUPS_T *groups _GL_UNUSED)
+getgroups (_GL_UNUSED int n, _GL_UNUSED GETGROUPS_T *groups)
{
errno = ENOSYS;
return -1;
@@ -70,7 +70,6 @@ rpl_getgroups (int n, gid_t *group)
{
int n_groups;
GETGROUPS_T *gbuf;
- int saved_errno;
if (n < 0)
{
@@ -99,9 +98,7 @@ rpl_getgroups (int n, gid_t *group)
while (n--)
group[n] = gbuf[n];
}
- saved_errno = errno;
free (gbuf);
- errno = saved_errno;
return result;
}
@@ -121,10 +118,7 @@ rpl_getgroups (int n, gid_t *group)
n *= 2;
}
- saved_errno = errno;
free (gbuf);
- errno = saved_errno;
-
return n_groups;
}
diff --git a/lib/getopt-cdefs.in.h b/lib/getopt-cdefs.in.h
index 11fe536ff24..33e3d4b3d8c 100644
--- a/lib/getopt-cdefs.in.h
+++ b/lib/getopt-cdefs.in.h
@@ -4,19 +4,18 @@
Unlike most of the getopt implementation, it is NOT shared
with the GNU C Library.
- 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 the Free Software Foundation; either version 3 of
- the License, or (at your option) any later version.
+ 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
- General Public License for more details.
+ 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 General Public
- License along with gnulib; if not, see
- <https://www.gnu.org/licenses/>. */
+ 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/>. */
#ifndef _GETOPT_CDEFS_H
#define _GETOPT_CDEFS_H 1
diff --git a/lib/getopt-core.h b/lib/getopt-core.h
index 05d16b07401..ceb14d05970 100644
--- a/lib/getopt-core.h
+++ b/lib/getopt-core.h
@@ -4,16 +4,16 @@
Patches to this file should be submitted to both projects.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/getopt-ext.h b/lib/getopt-ext.h
index 9b11b47f0fe..f82a8c61297 100644
--- a/lib/getopt-ext.h
+++ b/lib/getopt-ext.h
@@ -4,16 +4,16 @@
Patches to this file should be submitted to both projects.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/getopt-pfx-core.h b/lib/getopt-pfx-core.h
index 78990a345a7..b1733a34978 100644
--- a/lib/getopt-pfx-core.h
+++ b/lib/getopt-pfx-core.h
@@ -4,19 +4,18 @@
Unlike most of the getopt implementation, it is NOT shared
with the GNU C Library.
- 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 the Free Software Foundation; either version 3 of
- the License, or (at your option) any later version.
+ 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
- General Public License for more details.
+ 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 General Public
- License along with gnulib; if not, see
- <https://www.gnu.org/licenses/>. */
+ 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/>. */
#ifndef _GETOPT_PFX_CORE_H
#define _GETOPT_PFX_CORE_H 1
diff --git a/lib/getopt-pfx-ext.h b/lib/getopt-pfx-ext.h
index 61ea8d2b1d3..b9a14ba05a7 100644
--- a/lib/getopt-pfx-ext.h
+++ b/lib/getopt-pfx-ext.h
@@ -4,19 +4,18 @@
Unlike most of the getopt implementation, it is NOT shared
with the GNU C Library.
- 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 the Free Software Foundation; either version 3 of
- the License, or (at your option) any later version.
+ 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
- General Public License for more details.
+ 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 General Public
- License along with gnulib; if not, see
- <https://www.gnu.org/licenses/>. */
+ 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/>. */
#ifndef _GETOPT_PFX_EXT_H
#define _GETOPT_PFX_EXT_H 1
diff --git a/lib/getopt.c b/lib/getopt.c
index dd96c184075..7f3aa5aa3d7 100644
--- a/lib/getopt.c
+++ b/lib/getopt.c
@@ -4,16 +4,16 @@
Patches to this file should be submitted to both projects.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
@@ -378,8 +378,8 @@ process_long_option (int argc, char **argv, const char *optstring,
/* Initialize internal data upon the first call to getopt. */
static const char *
-_getopt_initialize (int argc _GL_UNUSED,
- char **argv _GL_UNUSED, const char *optstring,
+_getopt_initialize (_GL_UNUSED int argc,
+ _GL_UNUSED char **argv, const char *optstring,
struct _getopt_data *d, int posixly_correct)
{
/* Start processing options with ARGV-element 1 (since ARGV-element 0
diff --git a/lib/getopt.in.h b/lib/getopt.in.h
index 541fb9da2e8..bf884f03224 100644
--- a/lib/getopt.in.h
+++ b/lib/getopt.in.h
@@ -5,18 +5,18 @@
with the GNU C Library, which supplies a different version of
this file.
- 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 the Free Software Foundation; either version 3 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
- General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with gnulib; if not, see <https://www.gnu.org/licenses/>. */
+ 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/>. */
#ifndef _@GUARD_PREFIX@_GETOPT_H
diff --git a/lib/getopt1.c b/lib/getopt1.c
index ca24eb811f9..5a928062fd3 100644
--- a/lib/getopt1.c
+++ b/lib/getopt1.c
@@ -4,16 +4,16 @@
Patches to this file should be submitted to both projects.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/getopt_int.h b/lib/getopt_int.h
index b70ff5badf8..91254e487d2 100644
--- a/lib/getopt_int.h
+++ b/lib/getopt_int.h
@@ -4,16 +4,16 @@
Patches to this file should be submitted to both projects.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/getrandom.c b/lib/getrandom.c
index 41212fb329d..a186c4d3bd2 100644
--- a/lib/getrandom.c
+++ b/lib/getrandom.c
@@ -2,17 +2,17 @@
Copyright 2020-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Paul Eggert. */
@@ -178,7 +178,11 @@ getrandom (void *buffer, size_t length, unsigned int flags)
+ (flags & GRND_NONBLOCK ? O_NONBLOCK : 0));
fd = open (randdevice[devrandom], oflags);
if (fd < 0)
- return fd;
+ {
+ if (errno == ENOENT || errno == ENOTDIR)
+ errno = ENOSYS;
+ return -1;
+ }
randfd[devrandom] = fd;
}
diff --git a/lib/gettext.h b/lib/gettext.h
index 3552157efd9..f1c7a240757 100644
--- a/lib/gettext.h
+++ b/lib/gettext.h
@@ -2,18 +2,18 @@
Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2021 Free Software
Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
#ifndef _LIBGETTEXT_H
#define _LIBGETTEXT_H 1
diff --git a/lib/gettime.c b/lib/gettime.c
index fb721b2cda1..8f28a32df16 100644
--- a/lib/gettime.c
+++ b/lib/gettime.c
@@ -2,17 +2,17 @@
Copyright (C) 2002, 2004-2007, 2009-2021 Free Software Foundation, Inc.
- 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 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Paul Eggert. */
diff --git a/lib/gettimeofday.c b/lib/gettimeofday.c
index b1c93e1c3a3..2a222fc5b77 100644
--- a/lib/gettimeofday.c
+++ b/lib/gettimeofday.c
@@ -2,18 +2,18 @@
Copyright (C) 2001-2003, 2005-2007, 2009-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
/* written by Jim Meyering */
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index 0b9aaf6d9ea..c7c7eb455be 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -36,12 +36,12 @@
# --no-vc-files \
# --avoid=btowc \
# --avoid=close \
+# --avoid=crypto/af_alg \
# --avoid=dup \
# --avoid=fchdir \
# --avoid=fstat \
# --avoid=langinfo \
# --avoid=lock \
-# --avoid=malloc-posix \
# --avoid=mbrtowc \
# --avoid=mbsinit \
# --avoid=memchr \
@@ -80,6 +80,7 @@
# count-leading-zeros \
# count-one-bits \
# count-trailing-zeros \
+# crypto/md5 \
# crypto/md5-buffer \
# crypto/sha1-buffer \
# crypto/sha256-buffer \
@@ -128,6 +129,7 @@
# minmax \
# mkostemp \
# mktime \
+# nproc \
# nstrftime \
# pathmax \
# pipe2 \
@@ -172,9 +174,7 @@ ALLOCA = @ALLOCA@
ALLOCA_H = @ALLOCA_H@
ALSA_CFLAGS = @ALSA_CFLAGS@
ALSA_LIBS = @ALSA_LIBS@
-AM_DEFAULT_V = @AM_DEFAULT_V@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AM_V = @AM_V@
APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
AR = @AR@
ARFLAGS = @ARFLAGS@
@@ -213,6 +213,7 @@ DEFS = @DEFS@
DESLIB = @DESLIB@
DOCMISC_W32 = @DOCMISC_W32@
DUMPING = @DUMPING@
+DYNLIB_OBJ = @DYNLIB_OBJ@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -255,297 +256,300 @@ GL_GENERATE_MINI_GMP_H = @GL_GENERATE_MINI_GMP_H@
GL_GENERATE_STDALIGN_H = @GL_GENERATE_STDALIGN_H@
GL_GENERATE_STDDEF_H = @GL_GENERATE_STDDEF_H@
GL_GENERATE_STDINT_H = @GL_GENERATE_STDINT_H@
+GL_GNULIB_ACCESS = @GL_GNULIB_ACCESS@
+GL_GNULIB_ALIGNED_ALLOC = @GL_GNULIB_ALIGNED_ALLOC@
+GL_GNULIB_ALPHASORT = @GL_GNULIB_ALPHASORT@
+GL_GNULIB_ATOLL = @GL_GNULIB_ATOLL@
+GL_GNULIB_CALLOC_POSIX = @GL_GNULIB_CALLOC_POSIX@
+GL_GNULIB_CANONICALIZE_FILE_NAME = @GL_GNULIB_CANONICALIZE_FILE_NAME@
+GL_GNULIB_CHDIR = @GL_GNULIB_CHDIR@
+GL_GNULIB_CHOWN = @GL_GNULIB_CHOWN@
+GL_GNULIB_CLOSE = @GL_GNULIB_CLOSE@
+GL_GNULIB_CLOSEDIR = @GL_GNULIB_CLOSEDIR@
+GL_GNULIB_COPY_FILE_RANGE = @GL_GNULIB_COPY_FILE_RANGE@
+GL_GNULIB_CREAT = @GL_GNULIB_CREAT@
+GL_GNULIB_CTIME = @GL_GNULIB_CTIME@
+GL_GNULIB_DIRFD = @GL_GNULIB_DIRFD@
+GL_GNULIB_DPRINTF = @GL_GNULIB_DPRINTF@
+GL_GNULIB_DUP = @GL_GNULIB_DUP@
+GL_GNULIB_DUP2 = @GL_GNULIB_DUP2@
+GL_GNULIB_DUP3 = @GL_GNULIB_DUP3@
+GL_GNULIB_ENVIRON = @GL_GNULIB_ENVIRON@
+GL_GNULIB_EUIDACCESS = @GL_GNULIB_EUIDACCESS@
+GL_GNULIB_EXECL = @GL_GNULIB_EXECL@
+GL_GNULIB_EXECLE = @GL_GNULIB_EXECLE@
+GL_GNULIB_EXECLP = @GL_GNULIB_EXECLP@
+GL_GNULIB_EXECV = @GL_GNULIB_EXECV@
+GL_GNULIB_EXECVE = @GL_GNULIB_EXECVE@
+GL_GNULIB_EXECVP = @GL_GNULIB_EXECVP@
+GL_GNULIB_EXECVPE = @GL_GNULIB_EXECVPE@
+GL_GNULIB_EXPLICIT_BZERO = @GL_GNULIB_EXPLICIT_BZERO@
+GL_GNULIB_FACCESSAT = @GL_GNULIB_FACCESSAT@
+GL_GNULIB_FCHDIR = @GL_GNULIB_FCHDIR@
+GL_GNULIB_FCHMODAT = @GL_GNULIB_FCHMODAT@
+GL_GNULIB_FCHOWNAT = @GL_GNULIB_FCHOWNAT@
+GL_GNULIB_FCLOSE = @GL_GNULIB_FCLOSE@
+GL_GNULIB_FCNTL = @GL_GNULIB_FCNTL@
+GL_GNULIB_FDATASYNC = @GL_GNULIB_FDATASYNC@
+GL_GNULIB_FDOPEN = @GL_GNULIB_FDOPEN@
+GL_GNULIB_FDOPENDIR = @GL_GNULIB_FDOPENDIR@
+GL_GNULIB_FFLUSH = @GL_GNULIB_FFLUSH@
+GL_GNULIB_FFSL = @GL_GNULIB_FFSL@
+GL_GNULIB_FFSLL = @GL_GNULIB_FFSLL@
+GL_GNULIB_FGETC = @GL_GNULIB_FGETC@
+GL_GNULIB_FGETS = @GL_GNULIB_FGETS@
+GL_GNULIB_FOPEN = @GL_GNULIB_FOPEN@
+GL_GNULIB_FPRINTF = @GL_GNULIB_FPRINTF@
+GL_GNULIB_FPRINTF_POSIX = @GL_GNULIB_FPRINTF_POSIX@
+GL_GNULIB_FPURGE = @GL_GNULIB_FPURGE@
+GL_GNULIB_FPUTC = @GL_GNULIB_FPUTC@
+GL_GNULIB_FPUTS = @GL_GNULIB_FPUTS@
+GL_GNULIB_FREAD = @GL_GNULIB_FREAD@
+GL_GNULIB_FREE_POSIX = @GL_GNULIB_FREE_POSIX@
+GL_GNULIB_FREOPEN = @GL_GNULIB_FREOPEN@
+GL_GNULIB_FSCANF = @GL_GNULIB_FSCANF@
+GL_GNULIB_FSEEK = @GL_GNULIB_FSEEK@
+GL_GNULIB_FSEEKO = @GL_GNULIB_FSEEKO@
+GL_GNULIB_FSTAT = @GL_GNULIB_FSTAT@
+GL_GNULIB_FSTATAT = @GL_GNULIB_FSTATAT@
+GL_GNULIB_FSYNC = @GL_GNULIB_FSYNC@
+GL_GNULIB_FTELL = @GL_GNULIB_FTELL@
+GL_GNULIB_FTELLO = @GL_GNULIB_FTELLO@
+GL_GNULIB_FTRUNCATE = @GL_GNULIB_FTRUNCATE@
+GL_GNULIB_FUTIMENS = @GL_GNULIB_FUTIMENS@
+GL_GNULIB_FWRITE = @GL_GNULIB_FWRITE@
+GL_GNULIB_GETC = @GL_GNULIB_GETC@
+GL_GNULIB_GETCHAR = @GL_GNULIB_GETCHAR@
+GL_GNULIB_GETCWD = @GL_GNULIB_GETCWD@
+GL_GNULIB_GETDELIM = @GL_GNULIB_GETDELIM@
+GL_GNULIB_GETDOMAINNAME = @GL_GNULIB_GETDOMAINNAME@
+GL_GNULIB_GETDTABLESIZE = @GL_GNULIB_GETDTABLESIZE@
+GL_GNULIB_GETENTROPY = @GL_GNULIB_GETENTROPY@
+GL_GNULIB_GETGROUPS = @GL_GNULIB_GETGROUPS@
+GL_GNULIB_GETHOSTNAME = @GL_GNULIB_GETHOSTNAME@
+GL_GNULIB_GETLINE = @GL_GNULIB_GETLINE@
+GL_GNULIB_GETLOADAVG = @GL_GNULIB_GETLOADAVG@
+GL_GNULIB_GETLOGIN = @GL_GNULIB_GETLOGIN@
+GL_GNULIB_GETLOGIN_R = @GL_GNULIB_GETLOGIN_R@
+GL_GNULIB_GETOPT_POSIX = @GL_GNULIB_GETOPT_POSIX@
+GL_GNULIB_GETPAGESIZE = @GL_GNULIB_GETPAGESIZE@
+GL_GNULIB_GETPASS = @GL_GNULIB_GETPASS@
+GL_GNULIB_GETRANDOM = @GL_GNULIB_GETRANDOM@
+GL_GNULIB_GETSUBOPT = @GL_GNULIB_GETSUBOPT@
+GL_GNULIB_GETTIMEOFDAY = @GL_GNULIB_GETTIMEOFDAY@
+GL_GNULIB_GETUMASK = @GL_GNULIB_GETUMASK@
+GL_GNULIB_GETUSERSHELL = @GL_GNULIB_GETUSERSHELL@
+GL_GNULIB_GRANTPT = @GL_GNULIB_GRANTPT@
+GL_GNULIB_GROUP_MEMBER = @GL_GNULIB_GROUP_MEMBER@
+GL_GNULIB_IMAXABS = @GL_GNULIB_IMAXABS@
+GL_GNULIB_IMAXDIV = @GL_GNULIB_IMAXDIV@
+GL_GNULIB_ISATTY = @GL_GNULIB_ISATTY@
+GL_GNULIB_LCHMOD = @GL_GNULIB_LCHMOD@
+GL_GNULIB_LCHOWN = @GL_GNULIB_LCHOWN@
+GL_GNULIB_LINK = @GL_GNULIB_LINK@
+GL_GNULIB_LINKAT = @GL_GNULIB_LINKAT@
+GL_GNULIB_LOCALTIME = @GL_GNULIB_LOCALTIME@
+GL_GNULIB_LSEEK = @GL_GNULIB_LSEEK@
+GL_GNULIB_LSTAT = @GL_GNULIB_LSTAT@
+GL_GNULIB_MALLOC_POSIX = @GL_GNULIB_MALLOC_POSIX@
+GL_GNULIB_MBSCASECMP = @GL_GNULIB_MBSCASECMP@
+GL_GNULIB_MBSCASESTR = @GL_GNULIB_MBSCASESTR@
+GL_GNULIB_MBSCHR = @GL_GNULIB_MBSCHR@
+GL_GNULIB_MBSCSPN = @GL_GNULIB_MBSCSPN@
+GL_GNULIB_MBSLEN = @GL_GNULIB_MBSLEN@
+GL_GNULIB_MBSNCASECMP = @GL_GNULIB_MBSNCASECMP@
+GL_GNULIB_MBSNLEN = @GL_GNULIB_MBSNLEN@
+GL_GNULIB_MBSPBRK = @GL_GNULIB_MBSPBRK@
+GL_GNULIB_MBSPCASECMP = @GL_GNULIB_MBSPCASECMP@
+GL_GNULIB_MBSRCHR = @GL_GNULIB_MBSRCHR@
+GL_GNULIB_MBSSEP = @GL_GNULIB_MBSSEP@
+GL_GNULIB_MBSSPN = @GL_GNULIB_MBSSPN@
+GL_GNULIB_MBSSTR = @GL_GNULIB_MBSSTR@
+GL_GNULIB_MBSTOK_R = @GL_GNULIB_MBSTOK_R@
+GL_GNULIB_MBTOWC = @GL_GNULIB_MBTOWC@
+GL_GNULIB_MDA_ACCESS = @GL_GNULIB_MDA_ACCESS@
+GL_GNULIB_MDA_CHDIR = @GL_GNULIB_MDA_CHDIR@
+GL_GNULIB_MDA_CHMOD = @GL_GNULIB_MDA_CHMOD@
+GL_GNULIB_MDA_CLOSE = @GL_GNULIB_MDA_CLOSE@
+GL_GNULIB_MDA_CREAT = @GL_GNULIB_MDA_CREAT@
+GL_GNULIB_MDA_DUP = @GL_GNULIB_MDA_DUP@
+GL_GNULIB_MDA_DUP2 = @GL_GNULIB_MDA_DUP2@
+GL_GNULIB_MDA_ECVT = @GL_GNULIB_MDA_ECVT@
+GL_GNULIB_MDA_EXECL = @GL_GNULIB_MDA_EXECL@
+GL_GNULIB_MDA_EXECLE = @GL_GNULIB_MDA_EXECLE@
+GL_GNULIB_MDA_EXECLP = @GL_GNULIB_MDA_EXECLP@
+GL_GNULIB_MDA_EXECV = @GL_GNULIB_MDA_EXECV@
+GL_GNULIB_MDA_EXECVE = @GL_GNULIB_MDA_EXECVE@
+GL_GNULIB_MDA_EXECVP = @GL_GNULIB_MDA_EXECVP@
+GL_GNULIB_MDA_EXECVPE = @GL_GNULIB_MDA_EXECVPE@
+GL_GNULIB_MDA_FCLOSEALL = @GL_GNULIB_MDA_FCLOSEALL@
+GL_GNULIB_MDA_FCVT = @GL_GNULIB_MDA_FCVT@
+GL_GNULIB_MDA_FDOPEN = @GL_GNULIB_MDA_FDOPEN@
+GL_GNULIB_MDA_FILENO = @GL_GNULIB_MDA_FILENO@
+GL_GNULIB_MDA_GCVT = @GL_GNULIB_MDA_GCVT@
+GL_GNULIB_MDA_GETCWD = @GL_GNULIB_MDA_GETCWD@
+GL_GNULIB_MDA_GETPID = @GL_GNULIB_MDA_GETPID@
+GL_GNULIB_MDA_GETW = @GL_GNULIB_MDA_GETW@
+GL_GNULIB_MDA_ISATTY = @GL_GNULIB_MDA_ISATTY@
+GL_GNULIB_MDA_LSEEK = @GL_GNULIB_MDA_LSEEK@
+GL_GNULIB_MDA_MEMCCPY = @GL_GNULIB_MDA_MEMCCPY@
+GL_GNULIB_MDA_MKDIR = @GL_GNULIB_MDA_MKDIR@
+GL_GNULIB_MDA_MKTEMP = @GL_GNULIB_MDA_MKTEMP@
+GL_GNULIB_MDA_OPEN = @GL_GNULIB_MDA_OPEN@
+GL_GNULIB_MDA_PUTENV = @GL_GNULIB_MDA_PUTENV@
+GL_GNULIB_MDA_PUTW = @GL_GNULIB_MDA_PUTW@
+GL_GNULIB_MDA_READ = @GL_GNULIB_MDA_READ@
+GL_GNULIB_MDA_RMDIR = @GL_GNULIB_MDA_RMDIR@
+GL_GNULIB_MDA_STRDUP = @GL_GNULIB_MDA_STRDUP@
+GL_GNULIB_MDA_SWAB = @GL_GNULIB_MDA_SWAB@
+GL_GNULIB_MDA_TEMPNAM = @GL_GNULIB_MDA_TEMPNAM@
+GL_GNULIB_MDA_TZSET = @GL_GNULIB_MDA_TZSET@
+GL_GNULIB_MDA_UMASK = @GL_GNULIB_MDA_UMASK@
+GL_GNULIB_MDA_UNLINK = @GL_GNULIB_MDA_UNLINK@
+GL_GNULIB_MDA_WRITE = @GL_GNULIB_MDA_WRITE@
+GL_GNULIB_MEMCHR = @GL_GNULIB_MEMCHR@
+GL_GNULIB_MEMMEM = @GL_GNULIB_MEMMEM@
+GL_GNULIB_MEMPCPY = @GL_GNULIB_MEMPCPY@
+GL_GNULIB_MEMRCHR = @GL_GNULIB_MEMRCHR@
+GL_GNULIB_MKDIR = @GL_GNULIB_MKDIR@
+GL_GNULIB_MKDIRAT = @GL_GNULIB_MKDIRAT@
+GL_GNULIB_MKDTEMP = @GL_GNULIB_MKDTEMP@
+GL_GNULIB_MKFIFO = @GL_GNULIB_MKFIFO@
+GL_GNULIB_MKFIFOAT = @GL_GNULIB_MKFIFOAT@
+GL_GNULIB_MKNOD = @GL_GNULIB_MKNOD@
+GL_GNULIB_MKNODAT = @GL_GNULIB_MKNODAT@
+GL_GNULIB_MKOSTEMP = @GL_GNULIB_MKOSTEMP@
+GL_GNULIB_MKOSTEMPS = @GL_GNULIB_MKOSTEMPS@
+GL_GNULIB_MKSTEMP = @GL_GNULIB_MKSTEMP@
+GL_GNULIB_MKSTEMPS = @GL_GNULIB_MKSTEMPS@
+GL_GNULIB_MKTIME = @GL_GNULIB_MKTIME@
+GL_GNULIB_NANOSLEEP = @GL_GNULIB_NANOSLEEP@
+GL_GNULIB_NONBLOCKING = @GL_GNULIB_NONBLOCKING@
+GL_GNULIB_OBSTACK_PRINTF = @GL_GNULIB_OBSTACK_PRINTF@
+GL_GNULIB_OBSTACK_PRINTF_POSIX = @GL_GNULIB_OBSTACK_PRINTF_POSIX@
+GL_GNULIB_OPEN = @GL_GNULIB_OPEN@
+GL_GNULIB_OPENAT = @GL_GNULIB_OPENAT@
+GL_GNULIB_OPENDIR = @GL_GNULIB_OPENDIR@
+GL_GNULIB_OVERRIDES_STRUCT_STAT = @GL_GNULIB_OVERRIDES_STRUCT_STAT@
+GL_GNULIB_PCLOSE = @GL_GNULIB_PCLOSE@
+GL_GNULIB_PERROR = @GL_GNULIB_PERROR@
+GL_GNULIB_PIPE = @GL_GNULIB_PIPE@
+GL_GNULIB_PIPE2 = @GL_GNULIB_PIPE2@
+GL_GNULIB_POPEN = @GL_GNULIB_POPEN@
+GL_GNULIB_POSIX_MEMALIGN = @GL_GNULIB_POSIX_MEMALIGN@
+GL_GNULIB_POSIX_OPENPT = @GL_GNULIB_POSIX_OPENPT@
+GL_GNULIB_PREAD = @GL_GNULIB_PREAD@
+GL_GNULIB_PRINTF = @GL_GNULIB_PRINTF@
+GL_GNULIB_PRINTF_POSIX = @GL_GNULIB_PRINTF_POSIX@
+GL_GNULIB_PSELECT = @GL_GNULIB_PSELECT@
+GL_GNULIB_PTHREAD_SIGMASK = @GL_GNULIB_PTHREAD_SIGMASK@
+GL_GNULIB_PTSNAME = @GL_GNULIB_PTSNAME@
+GL_GNULIB_PTSNAME_R = @GL_GNULIB_PTSNAME_R@
+GL_GNULIB_PUTC = @GL_GNULIB_PUTC@
+GL_GNULIB_PUTCHAR = @GL_GNULIB_PUTCHAR@
+GL_GNULIB_PUTENV = @GL_GNULIB_PUTENV@
+GL_GNULIB_PUTS = @GL_GNULIB_PUTS@
+GL_GNULIB_PWRITE = @GL_GNULIB_PWRITE@
+GL_GNULIB_QSORT_R = @GL_GNULIB_QSORT_R@
+GL_GNULIB_RAISE = @GL_GNULIB_RAISE@
+GL_GNULIB_RANDOM = @GL_GNULIB_RANDOM@
+GL_GNULIB_RANDOM_R = @GL_GNULIB_RANDOM_R@
+GL_GNULIB_RAWMEMCHR = @GL_GNULIB_RAWMEMCHR@
+GL_GNULIB_READ = @GL_GNULIB_READ@
+GL_GNULIB_READDIR = @GL_GNULIB_READDIR@
+GL_GNULIB_READLINK = @GL_GNULIB_READLINK@
+GL_GNULIB_READLINKAT = @GL_GNULIB_READLINKAT@
+GL_GNULIB_REALLOCARRAY = @GL_GNULIB_REALLOCARRAY@
+GL_GNULIB_REALLOC_POSIX = @GL_GNULIB_REALLOC_POSIX@
+GL_GNULIB_REALPATH = @GL_GNULIB_REALPATH@
+GL_GNULIB_REMOVE = @GL_GNULIB_REMOVE@
+GL_GNULIB_RENAME = @GL_GNULIB_RENAME@
+GL_GNULIB_RENAMEAT = @GL_GNULIB_RENAMEAT@
+GL_GNULIB_REWINDDIR = @GL_GNULIB_REWINDDIR@
+GL_GNULIB_RMDIR = @GL_GNULIB_RMDIR@
+GL_GNULIB_RPMATCH = @GL_GNULIB_RPMATCH@
+GL_GNULIB_SCANDIR = @GL_GNULIB_SCANDIR@
+GL_GNULIB_SCANF = @GL_GNULIB_SCANF@
+GL_GNULIB_SECURE_GETENV = @GL_GNULIB_SECURE_GETENV@
+GL_GNULIB_SELECT = @GL_GNULIB_SELECT@
+GL_GNULIB_SETENV = @GL_GNULIB_SETENV@
+GL_GNULIB_SETHOSTNAME = @GL_GNULIB_SETHOSTNAME@
+GL_GNULIB_SIGABBREV_NP = @GL_GNULIB_SIGABBREV_NP@
+GL_GNULIB_SIGACTION = @GL_GNULIB_SIGACTION@
+GL_GNULIB_SIGDESCR_NP = @GL_GNULIB_SIGDESCR_NP@
+GL_GNULIB_SIGNAL_H_SIGPIPE = @GL_GNULIB_SIGNAL_H_SIGPIPE@
+GL_GNULIB_SIGPROCMASK = @GL_GNULIB_SIGPROCMASK@
+GL_GNULIB_SLEEP = @GL_GNULIB_SLEEP@
+GL_GNULIB_SNPRINTF = @GL_GNULIB_SNPRINTF@
+GL_GNULIB_SPRINTF_POSIX = @GL_GNULIB_SPRINTF_POSIX@
+GL_GNULIB_STAT = @GL_GNULIB_STAT@
+GL_GNULIB_STDIO_H_NONBLOCKING = @GL_GNULIB_STDIO_H_NONBLOCKING@
+GL_GNULIB_STDIO_H_SIGPIPE = @GL_GNULIB_STDIO_H_SIGPIPE@
+GL_GNULIB_STPCPY = @GL_GNULIB_STPCPY@
+GL_GNULIB_STPNCPY = @GL_GNULIB_STPNCPY@
+GL_GNULIB_STRCASESTR = @GL_GNULIB_STRCASESTR@
+GL_GNULIB_STRCHRNUL = @GL_GNULIB_STRCHRNUL@
+GL_GNULIB_STRDUP = @GL_GNULIB_STRDUP@
+GL_GNULIB_STRERROR = @GL_GNULIB_STRERROR@
+GL_GNULIB_STRERRORNAME_NP = @GL_GNULIB_STRERRORNAME_NP@
+GL_GNULIB_STRERROR_R = @GL_GNULIB_STRERROR_R@
+GL_GNULIB_STRFTIME = @GL_GNULIB_STRFTIME@
+GL_GNULIB_STRNCAT = @GL_GNULIB_STRNCAT@
+GL_GNULIB_STRNDUP = @GL_GNULIB_STRNDUP@
+GL_GNULIB_STRNLEN = @GL_GNULIB_STRNLEN@
+GL_GNULIB_STRPBRK = @GL_GNULIB_STRPBRK@
+GL_GNULIB_STRPTIME = @GL_GNULIB_STRPTIME@
+GL_GNULIB_STRSEP = @GL_GNULIB_STRSEP@
+GL_GNULIB_STRSIGNAL = @GL_GNULIB_STRSIGNAL@
+GL_GNULIB_STRSTR = @GL_GNULIB_STRSTR@
+GL_GNULIB_STRTOD = @GL_GNULIB_STRTOD@
+GL_GNULIB_STRTOIMAX = @GL_GNULIB_STRTOIMAX@
+GL_GNULIB_STRTOK_R = @GL_GNULIB_STRTOK_R@
+GL_GNULIB_STRTOL = @GL_GNULIB_STRTOL@
+GL_GNULIB_STRTOLD = @GL_GNULIB_STRTOLD@
+GL_GNULIB_STRTOLL = @GL_GNULIB_STRTOLL@
+GL_GNULIB_STRTOUL = @GL_GNULIB_STRTOUL@
+GL_GNULIB_STRTOULL = @GL_GNULIB_STRTOULL@
+GL_GNULIB_STRTOUMAX = @GL_GNULIB_STRTOUMAX@
+GL_GNULIB_STRVERSCMP = @GL_GNULIB_STRVERSCMP@
+GL_GNULIB_SYMLINK = @GL_GNULIB_SYMLINK@
+GL_GNULIB_SYMLINKAT = @GL_GNULIB_SYMLINKAT@
+GL_GNULIB_SYSTEM_POSIX = @GL_GNULIB_SYSTEM_POSIX@
+GL_GNULIB_TIMEGM = @GL_GNULIB_TIMEGM@
+GL_GNULIB_TIMESPEC_GET = @GL_GNULIB_TIMESPEC_GET@
+GL_GNULIB_TIME_R = @GL_GNULIB_TIME_R@
+GL_GNULIB_TIME_RZ = @GL_GNULIB_TIME_RZ@
+GL_GNULIB_TMPFILE = @GL_GNULIB_TMPFILE@
+GL_GNULIB_TRUNCATE = @GL_GNULIB_TRUNCATE@
+GL_GNULIB_TTYNAME_R = @GL_GNULIB_TTYNAME_R@
+GL_GNULIB_TZSET = @GL_GNULIB_TZSET@
+GL_GNULIB_UNISTD_H_GETOPT = @GL_GNULIB_UNISTD_H_GETOPT@
+GL_GNULIB_UNISTD_H_NONBLOCKING = @GL_GNULIB_UNISTD_H_NONBLOCKING@
+GL_GNULIB_UNISTD_H_SIGPIPE = @GL_GNULIB_UNISTD_H_SIGPIPE@
+GL_GNULIB_UNLINK = @GL_GNULIB_UNLINK@
+GL_GNULIB_UNLINKAT = @GL_GNULIB_UNLINKAT@
+GL_GNULIB_UNLOCKPT = @GL_GNULIB_UNLOCKPT@
+GL_GNULIB_UNSETENV = @GL_GNULIB_UNSETENV@
+GL_GNULIB_USLEEP = @GL_GNULIB_USLEEP@
+GL_GNULIB_UTIMENSAT = @GL_GNULIB_UTIMENSAT@
+GL_GNULIB_VASPRINTF = @GL_GNULIB_VASPRINTF@
+GL_GNULIB_VDPRINTF = @GL_GNULIB_VDPRINTF@
+GL_GNULIB_VFPRINTF = @GL_GNULIB_VFPRINTF@
+GL_GNULIB_VFPRINTF_POSIX = @GL_GNULIB_VFPRINTF_POSIX@
+GL_GNULIB_VFSCANF = @GL_GNULIB_VFSCANF@
+GL_GNULIB_VPRINTF = @GL_GNULIB_VPRINTF@
+GL_GNULIB_VPRINTF_POSIX = @GL_GNULIB_VPRINTF_POSIX@
+GL_GNULIB_VSCANF = @GL_GNULIB_VSCANF@
+GL_GNULIB_VSNPRINTF = @GL_GNULIB_VSNPRINTF@
+GL_GNULIB_VSPRINTF_POSIX = @GL_GNULIB_VSPRINTF_POSIX@
+GL_GNULIB_WCTOMB = @GL_GNULIB_WCTOMB@
+GL_GNULIB_WRITE = @GL_GNULIB_WRITE@
+GL_GNULIB__EXIT = @GL_GNULIB__EXIT@
GMALLOC_OBJ = @GMALLOC_OBJ@
GMP_H = @GMP_H@
-GNULIB_ACCESS = @GNULIB_ACCESS@
-GNULIB_ALIGNED_ALLOC = @GNULIB_ALIGNED_ALLOC@
-GNULIB_ALPHASORT = @GNULIB_ALPHASORT@
-GNULIB_ATOLL = @GNULIB_ATOLL@
-GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@
-GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@
-GNULIB_CHDIR = @GNULIB_CHDIR@
-GNULIB_CHOWN = @GNULIB_CHOWN@
-GNULIB_CLOSE = @GNULIB_CLOSE@
-GNULIB_CLOSEDIR = @GNULIB_CLOSEDIR@
-GNULIB_COPY_FILE_RANGE = @GNULIB_COPY_FILE_RANGE@
-GNULIB_CREAT = @GNULIB_CREAT@
-GNULIB_CTIME = @GNULIB_CTIME@
-GNULIB_DIRFD = @GNULIB_DIRFD@
-GNULIB_DPRINTF = @GNULIB_DPRINTF@
-GNULIB_DUP = @GNULIB_DUP@
-GNULIB_DUP2 = @GNULIB_DUP2@
-GNULIB_DUP3 = @GNULIB_DUP3@
-GNULIB_ENVIRON = @GNULIB_ENVIRON@
-GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@
-GNULIB_EXECL = @GNULIB_EXECL@
-GNULIB_EXECLE = @GNULIB_EXECLE@
-GNULIB_EXECLP = @GNULIB_EXECLP@
-GNULIB_EXECV = @GNULIB_EXECV@
-GNULIB_EXECVE = @GNULIB_EXECVE@
-GNULIB_EXECVP = @GNULIB_EXECVP@
-GNULIB_EXECVPE = @GNULIB_EXECVPE@
-GNULIB_EXPLICIT_BZERO = @GNULIB_EXPLICIT_BZERO@
-GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
-GNULIB_FCHDIR = @GNULIB_FCHDIR@
-GNULIB_FCHMODAT = @GNULIB_FCHMODAT@
-GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
-GNULIB_FCLOSE = @GNULIB_FCLOSE@
-GNULIB_FCNTL = @GNULIB_FCNTL@
-GNULIB_FDATASYNC = @GNULIB_FDATASYNC@
-GNULIB_FDOPEN = @GNULIB_FDOPEN@
-GNULIB_FDOPENDIR = @GNULIB_FDOPENDIR@
-GNULIB_FFLUSH = @GNULIB_FFLUSH@
-GNULIB_FFSL = @GNULIB_FFSL@
-GNULIB_FFSLL = @GNULIB_FFSLL@
-GNULIB_FGETC = @GNULIB_FGETC@
-GNULIB_FGETS = @GNULIB_FGETS@
-GNULIB_FOPEN = @GNULIB_FOPEN@
-GNULIB_FPRINTF = @GNULIB_FPRINTF@
-GNULIB_FPRINTF_POSIX = @GNULIB_FPRINTF_POSIX@
-GNULIB_FPURGE = @GNULIB_FPURGE@
-GNULIB_FPUTC = @GNULIB_FPUTC@
-GNULIB_FPUTS = @GNULIB_FPUTS@
-GNULIB_FREAD = @GNULIB_FREAD@
-GNULIB_FREE_POSIX = @GNULIB_FREE_POSIX@
-GNULIB_FREOPEN = @GNULIB_FREOPEN@
-GNULIB_FSCANF = @GNULIB_FSCANF@
-GNULIB_FSEEK = @GNULIB_FSEEK@
-GNULIB_FSEEKO = @GNULIB_FSEEKO@
-GNULIB_FSTAT = @GNULIB_FSTAT@
-GNULIB_FSTATAT = @GNULIB_FSTATAT@
-GNULIB_FSYNC = @GNULIB_FSYNC@
-GNULIB_FTELL = @GNULIB_FTELL@
-GNULIB_FTELLO = @GNULIB_FTELLO@
-GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
-GNULIB_FUTIMENS = @GNULIB_FUTIMENS@
-GNULIB_FWRITE = @GNULIB_FWRITE@
-GNULIB_GETC = @GNULIB_GETC@
-GNULIB_GETCHAR = @GNULIB_GETCHAR@
-GNULIB_GETCWD = @GNULIB_GETCWD@
-GNULIB_GETDELIM = @GNULIB_GETDELIM@
-GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@
-GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@
-GNULIB_GETENTROPY = @GNULIB_GETENTROPY@
-GNULIB_GETGROUPS = @GNULIB_GETGROUPS@
-GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@
-GNULIB_GETLINE = @GNULIB_GETLINE@
-GNULIB_GETLOADAVG = @GNULIB_GETLOADAVG@
-GNULIB_GETLOGIN = @GNULIB_GETLOGIN@
-GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@
-GNULIB_GETOPT_POSIX = @GNULIB_GETOPT_POSIX@
-GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@
-GNULIB_GETPASS = @GNULIB_GETPASS@
-GNULIB_GETRANDOM = @GNULIB_GETRANDOM@
-GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@
+GNULIBHEADERS_OVERRIDE_WINT_T = @GNULIBHEADERS_OVERRIDE_WINT_T@
GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@
-GNULIB_GETUMASK = @GNULIB_GETUMASK@
-GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@
-GNULIB_GL_UNISTD_H_GETOPT = @GNULIB_GL_UNISTD_H_GETOPT@
-GNULIB_GRANTPT = @GNULIB_GRANTPT@
-GNULIB_GROUP_MEMBER = @GNULIB_GROUP_MEMBER@
-GNULIB_IMAXABS = @GNULIB_IMAXABS@
-GNULIB_IMAXDIV = @GNULIB_IMAXDIV@
-GNULIB_ISATTY = @GNULIB_ISATTY@
-GNULIB_LCHMOD = @GNULIB_LCHMOD@
-GNULIB_LCHOWN = @GNULIB_LCHOWN@
-GNULIB_LINK = @GNULIB_LINK@
-GNULIB_LINKAT = @GNULIB_LINKAT@
-GNULIB_LOCALTIME = @GNULIB_LOCALTIME@
-GNULIB_LSEEK = @GNULIB_LSEEK@
-GNULIB_LSTAT = @GNULIB_LSTAT@
-GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@
-GNULIB_MBSCASECMP = @GNULIB_MBSCASECMP@
-GNULIB_MBSCASESTR = @GNULIB_MBSCASESTR@
-GNULIB_MBSCHR = @GNULIB_MBSCHR@
-GNULIB_MBSCSPN = @GNULIB_MBSCSPN@
-GNULIB_MBSLEN = @GNULIB_MBSLEN@
-GNULIB_MBSNCASECMP = @GNULIB_MBSNCASECMP@
-GNULIB_MBSNLEN = @GNULIB_MBSNLEN@
-GNULIB_MBSPBRK = @GNULIB_MBSPBRK@
-GNULIB_MBSPCASECMP = @GNULIB_MBSPCASECMP@
-GNULIB_MBSRCHR = @GNULIB_MBSRCHR@
-GNULIB_MBSSEP = @GNULIB_MBSSEP@
-GNULIB_MBSSPN = @GNULIB_MBSSPN@
-GNULIB_MBSSTR = @GNULIB_MBSSTR@
-GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@
-GNULIB_MBTOWC = @GNULIB_MBTOWC@
-GNULIB_MDA_ACCESS = @GNULIB_MDA_ACCESS@
-GNULIB_MDA_CHDIR = @GNULIB_MDA_CHDIR@
-GNULIB_MDA_CHMOD = @GNULIB_MDA_CHMOD@
-GNULIB_MDA_CLOSE = @GNULIB_MDA_CLOSE@
-GNULIB_MDA_CREAT = @GNULIB_MDA_CREAT@
-GNULIB_MDA_DUP = @GNULIB_MDA_DUP@
-GNULIB_MDA_DUP2 = @GNULIB_MDA_DUP2@
-GNULIB_MDA_ECVT = @GNULIB_MDA_ECVT@
-GNULIB_MDA_EXECL = @GNULIB_MDA_EXECL@
-GNULIB_MDA_EXECLE = @GNULIB_MDA_EXECLE@
-GNULIB_MDA_EXECLP = @GNULIB_MDA_EXECLP@
-GNULIB_MDA_EXECV = @GNULIB_MDA_EXECV@
-GNULIB_MDA_EXECVE = @GNULIB_MDA_EXECVE@
-GNULIB_MDA_EXECVP = @GNULIB_MDA_EXECVP@
-GNULIB_MDA_EXECVPE = @GNULIB_MDA_EXECVPE@
-GNULIB_MDA_FCLOSEALL = @GNULIB_MDA_FCLOSEALL@
-GNULIB_MDA_FCVT = @GNULIB_MDA_FCVT@
-GNULIB_MDA_FDOPEN = @GNULIB_MDA_FDOPEN@
-GNULIB_MDA_FILENO = @GNULIB_MDA_FILENO@
-GNULIB_MDA_GCVT = @GNULIB_MDA_GCVT@
-GNULIB_MDA_GETCWD = @GNULIB_MDA_GETCWD@
-GNULIB_MDA_GETPID = @GNULIB_MDA_GETPID@
-GNULIB_MDA_GETW = @GNULIB_MDA_GETW@
-GNULIB_MDA_ISATTY = @GNULIB_MDA_ISATTY@
-GNULIB_MDA_LSEEK = @GNULIB_MDA_LSEEK@
-GNULIB_MDA_MEMCCPY = @GNULIB_MDA_MEMCCPY@
-GNULIB_MDA_MKDIR = @GNULIB_MDA_MKDIR@
-GNULIB_MDA_MKTEMP = @GNULIB_MDA_MKTEMP@
-GNULIB_MDA_OPEN = @GNULIB_MDA_OPEN@
-GNULIB_MDA_PUTENV = @GNULIB_MDA_PUTENV@
-GNULIB_MDA_PUTW = @GNULIB_MDA_PUTW@
-GNULIB_MDA_READ = @GNULIB_MDA_READ@
-GNULIB_MDA_RMDIR = @GNULIB_MDA_RMDIR@
-GNULIB_MDA_STRDUP = @GNULIB_MDA_STRDUP@
-GNULIB_MDA_SWAB = @GNULIB_MDA_SWAB@
-GNULIB_MDA_TEMPNAM = @GNULIB_MDA_TEMPNAM@
-GNULIB_MDA_TZSET = @GNULIB_MDA_TZSET@
-GNULIB_MDA_UMASK = @GNULIB_MDA_UMASK@
-GNULIB_MDA_UNLINK = @GNULIB_MDA_UNLINK@
-GNULIB_MDA_WRITE = @GNULIB_MDA_WRITE@
-GNULIB_MEMCHR = @GNULIB_MEMCHR@
-GNULIB_MEMMEM = @GNULIB_MEMMEM@
-GNULIB_MEMPCPY = @GNULIB_MEMPCPY@
-GNULIB_MEMRCHR = @GNULIB_MEMRCHR@
-GNULIB_MKDIR = @GNULIB_MKDIR@
-GNULIB_MKDIRAT = @GNULIB_MKDIRAT@
-GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
-GNULIB_MKFIFO = @GNULIB_MKFIFO@
-GNULIB_MKFIFOAT = @GNULIB_MKFIFOAT@
-GNULIB_MKNOD = @GNULIB_MKNOD@
-GNULIB_MKNODAT = @GNULIB_MKNODAT@
-GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@
-GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@
-GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
-GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@
-GNULIB_MKTIME = @GNULIB_MKTIME@
-GNULIB_NANOSLEEP = @GNULIB_NANOSLEEP@
-GNULIB_NONBLOCKING = @GNULIB_NONBLOCKING@
-GNULIB_OBSTACK_PRINTF = @GNULIB_OBSTACK_PRINTF@
-GNULIB_OBSTACK_PRINTF_POSIX = @GNULIB_OBSTACK_PRINTF_POSIX@
-GNULIB_OPEN = @GNULIB_OPEN@
-GNULIB_OPENAT = @GNULIB_OPENAT@
-GNULIB_OPENDIR = @GNULIB_OPENDIR@
-GNULIB_OVERRIDES_STRUCT_STAT = @GNULIB_OVERRIDES_STRUCT_STAT@
-GNULIB_OVERRIDES_WINT_T = @GNULIB_OVERRIDES_WINT_T@
-GNULIB_PCLOSE = @GNULIB_PCLOSE@
-GNULIB_PERROR = @GNULIB_PERROR@
-GNULIB_PIPE = @GNULIB_PIPE@
-GNULIB_PIPE2 = @GNULIB_PIPE2@
-GNULIB_POPEN = @GNULIB_POPEN@
-GNULIB_POSIX_MEMALIGN = @GNULIB_POSIX_MEMALIGN@
-GNULIB_POSIX_OPENPT = @GNULIB_POSIX_OPENPT@
-GNULIB_PREAD = @GNULIB_PREAD@
-GNULIB_PRINTF = @GNULIB_PRINTF@
-GNULIB_PRINTF_POSIX = @GNULIB_PRINTF_POSIX@
-GNULIB_PSELECT = @GNULIB_PSELECT@
-GNULIB_PTHREAD_SIGMASK = @GNULIB_PTHREAD_SIGMASK@
-GNULIB_PTSNAME = @GNULIB_PTSNAME@
-GNULIB_PTSNAME_R = @GNULIB_PTSNAME_R@
-GNULIB_PUTC = @GNULIB_PUTC@
-GNULIB_PUTCHAR = @GNULIB_PUTCHAR@
-GNULIB_PUTENV = @GNULIB_PUTENV@
-GNULIB_PUTS = @GNULIB_PUTS@
-GNULIB_PWRITE = @GNULIB_PWRITE@
-GNULIB_QSORT_R = @GNULIB_QSORT_R@
-GNULIB_RAISE = @GNULIB_RAISE@
-GNULIB_RANDOM = @GNULIB_RANDOM@
-GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
-GNULIB_RAWMEMCHR = @GNULIB_RAWMEMCHR@
-GNULIB_READ = @GNULIB_READ@
-GNULIB_READDIR = @GNULIB_READDIR@
-GNULIB_READLINK = @GNULIB_READLINK@
-GNULIB_READLINKAT = @GNULIB_READLINKAT@
-GNULIB_REALLOCARRAY = @GNULIB_REALLOCARRAY@
-GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
-GNULIB_REALPATH = @GNULIB_REALPATH@
-GNULIB_REMOVE = @GNULIB_REMOVE@
-GNULIB_RENAME = @GNULIB_RENAME@
-GNULIB_RENAMEAT = @GNULIB_RENAMEAT@
-GNULIB_REWINDDIR = @GNULIB_REWINDDIR@
-GNULIB_RMDIR = @GNULIB_RMDIR@
-GNULIB_RPMATCH = @GNULIB_RPMATCH@
-GNULIB_SCANDIR = @GNULIB_SCANDIR@
-GNULIB_SCANF = @GNULIB_SCANF@
-GNULIB_SECURE_GETENV = @GNULIB_SECURE_GETENV@
-GNULIB_SELECT = @GNULIB_SELECT@
-GNULIB_SETENV = @GNULIB_SETENV@
-GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@
-GNULIB_SIGABBREV_NP = @GNULIB_SIGABBREV_NP@
-GNULIB_SIGACTION = @GNULIB_SIGACTION@
-GNULIB_SIGDESCR_NP = @GNULIB_SIGDESCR_NP@
-GNULIB_SIGNAL_H_SIGPIPE = @GNULIB_SIGNAL_H_SIGPIPE@
-GNULIB_SIGPROCMASK = @GNULIB_SIGPROCMASK@
-GNULIB_SLEEP = @GNULIB_SLEEP@
-GNULIB_SNPRINTF = @GNULIB_SNPRINTF@
-GNULIB_SPRINTF_POSIX = @GNULIB_SPRINTF_POSIX@
-GNULIB_STAT = @GNULIB_STAT@
-GNULIB_STDIO_H_NONBLOCKING = @GNULIB_STDIO_H_NONBLOCKING@
-GNULIB_STDIO_H_SIGPIPE = @GNULIB_STDIO_H_SIGPIPE@
-GNULIB_STPCPY = @GNULIB_STPCPY@
-GNULIB_STPNCPY = @GNULIB_STPNCPY@
-GNULIB_STRCASESTR = @GNULIB_STRCASESTR@
-GNULIB_STRCHRNUL = @GNULIB_STRCHRNUL@
-GNULIB_STRDUP = @GNULIB_STRDUP@
-GNULIB_STRERROR = @GNULIB_STRERROR@
-GNULIB_STRERRORNAME_NP = @GNULIB_STRERRORNAME_NP@
-GNULIB_STRERROR_R = @GNULIB_STRERROR_R@
-GNULIB_STRFTIME = @GNULIB_STRFTIME@
-GNULIB_STRNCAT = @GNULIB_STRNCAT@
-GNULIB_STRNDUP = @GNULIB_STRNDUP@
-GNULIB_STRNLEN = @GNULIB_STRNLEN@
-GNULIB_STRPBRK = @GNULIB_STRPBRK@
-GNULIB_STRPTIME = @GNULIB_STRPTIME@
-GNULIB_STRSEP = @GNULIB_STRSEP@
-GNULIB_STRSIGNAL = @GNULIB_STRSIGNAL@
-GNULIB_STRSTR = @GNULIB_STRSTR@
-GNULIB_STRTOD = @GNULIB_STRTOD@
-GNULIB_STRTOIMAX = @GNULIB_STRTOIMAX@
-GNULIB_STRTOK_R = @GNULIB_STRTOK_R@
-GNULIB_STRTOLD = @GNULIB_STRTOLD@
-GNULIB_STRTOLL = @GNULIB_STRTOLL@
-GNULIB_STRTOULL = @GNULIB_STRTOULL@
-GNULIB_STRTOUMAX = @GNULIB_STRTOUMAX@
-GNULIB_STRVERSCMP = @GNULIB_STRVERSCMP@
-GNULIB_SYMLINK = @GNULIB_SYMLINK@
-GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
-GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@
-GNULIB_TIMEGM = @GNULIB_TIMEGM@
-GNULIB_TIMESPEC_GET = @GNULIB_TIMESPEC_GET@
-GNULIB_TIME_R = @GNULIB_TIME_R@
-GNULIB_TIME_RZ = @GNULIB_TIME_RZ@
-GNULIB_TMPFILE = @GNULIB_TMPFILE@
-GNULIB_TRUNCATE = @GNULIB_TRUNCATE@
-GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
-GNULIB_TZSET = @GNULIB_TZSET@
-GNULIB_UNISTD_H_NONBLOCKING = @GNULIB_UNISTD_H_NONBLOCKING@
-GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@
-GNULIB_UNLINK = @GNULIB_UNLINK@
-GNULIB_UNLINKAT = @GNULIB_UNLINKAT@
-GNULIB_UNLOCKPT = @GNULIB_UNLOCKPT@
-GNULIB_UNSETENV = @GNULIB_UNSETENV@
-GNULIB_USLEEP = @GNULIB_USLEEP@
-GNULIB_UTIMENSAT = @GNULIB_UTIMENSAT@
-GNULIB_VASPRINTF = @GNULIB_VASPRINTF@
-GNULIB_VDPRINTF = @GNULIB_VDPRINTF@
-GNULIB_VFPRINTF = @GNULIB_VFPRINTF@
-GNULIB_VFPRINTF_POSIX = @GNULIB_VFPRINTF_POSIX@
-GNULIB_VFSCANF = @GNULIB_VFSCANF@
-GNULIB_VPRINTF = @GNULIB_VPRINTF@
-GNULIB_VPRINTF_POSIX = @GNULIB_VPRINTF_POSIX@
-GNULIB_VSCANF = @GNULIB_VSCANF@
-GNULIB_VSNPRINTF = @GNULIB_VSNPRINTF@
-GNULIB_VSPRINTF_POSIX = @GNULIB_VSPRINTF_POSIX@
GNULIB_WARN_CFLAGS = @GNULIB_WARN_CFLAGS@
-GNULIB_WCTOMB = @GNULIB_WCTOMB@
-GNULIB_WRITE = @GNULIB_WRITE@
-GNULIB__EXIT = @GNULIB__EXIT@
GNUSTEP_CFLAGS = @GNUSTEP_CFLAGS@
GNU_OBJC_CFLAGS = @GNU_OBJC_CFLAGS@
GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
@@ -653,10 +657,11 @@ HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
HAVE_LCHMOD = @HAVE_LCHMOD@
HAVE_LCHOWN = @HAVE_LCHOWN@
HAVE_LIBGMP = @HAVE_LIBGMP@
+HAVE_LIBSECCOMP = @HAVE_LIBSECCOMP@
HAVE_LINK = @HAVE_LINK@
HAVE_LINKAT = @HAVE_LINKAT@
HAVE_LSTAT = @HAVE_LSTAT@
-HAVE_MAKEINFO = @HAVE_MAKEINFO@
+HAVE_MACPORTS = @HAVE_MACPORTS@
HAVE_MAX_ALIGN_T = @HAVE_MAX_ALIGN_T@
HAVE_MBSLEN = @HAVE_MBSLEN@
HAVE_MBTOWC = @HAVE_MBTOWC@
@@ -673,6 +678,7 @@ HAVE_MKSTEMP = @HAVE_MKSTEMP@
HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
HAVE_MODULES = @HAVE_MODULES@
HAVE_NANOSLEEP = @HAVE_NANOSLEEP@
+HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@
HAVE_OPENAT = @HAVE_OPENAT@
HAVE_OPENDIR = @HAVE_OPENDIR@
HAVE_OS_H = @HAVE_OS_H@
@@ -705,6 +711,7 @@ HAVE_RENAMEAT = @HAVE_RENAMEAT@
HAVE_REWINDDIR = @HAVE_REWINDDIR@
HAVE_RPMATCH = @HAVE_RPMATCH@
HAVE_SCANDIR = @HAVE_SCANDIR@
+HAVE_SECCOMP = @HAVE_SECCOMP@
HAVE_SECURE_GETENV = @HAVE_SECURE_GETENV@
HAVE_SETENV = @HAVE_SETENV@
HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@
@@ -729,8 +736,10 @@ HAVE_STRPBRK = @HAVE_STRPBRK@
HAVE_STRPTIME = @HAVE_STRPTIME@
HAVE_STRSEP = @HAVE_STRSEP@
HAVE_STRTOD = @HAVE_STRTOD@
+HAVE_STRTOL = @HAVE_STRTOL@
HAVE_STRTOLD = @HAVE_STRTOLD@
HAVE_STRTOLL = @HAVE_STRTOLL@
+HAVE_STRTOUL = @HAVE_STRTOUL@
HAVE_STRTOULL = @HAVE_STRTOULL@
HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
HAVE_STRUCT_SIGACTION_SA_SIGACTION = @HAVE_STRUCT_SIGACTION_SA_SIGACTION@
@@ -790,6 +799,8 @@ LD_SWITCH_SYSTEM = @LD_SWITCH_SYSTEM@
LD_SWITCH_SYSTEM_TEMACS = @LD_SWITCH_SYSTEM_TEMACS@
LD_SWITCH_X_SITE = @LD_SWITCH_X_SITE@
LD_SWITCH_X_SITE_RPATH = @LD_SWITCH_X_SITE_RPATH@
+LIBGCCJIT_CFLAGS = @LIBGCCJIT_CFLAGS@
+LIBGCCJIT_LIBS = @LIBGCCJIT_LIBS@
LIBGIF = @LIBGIF@
LIBGMP = @LIBGMP@
LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@
@@ -807,6 +818,8 @@ LIBOTF_LIBS = @LIBOTF_LIBS@
LIBPNG = @LIBPNG@
LIBRESOLV = @LIBRESOLV@
LIBS = @LIBS@
+LIBSECCOMP_CFLAGS = @LIBSECCOMP_CFLAGS@
+LIBSECCOMP_LIBS = @LIBSECCOMP_LIBS@
LIBSELINUX_LIBS = @LIBSELINUX_LIBS@
LIBSOUND = @LIBSOUND@
LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@
@@ -832,6 +845,7 @@ LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@
LIB_EACCESS = @LIB_EACCESS@
LIB_EXECINFO = @LIB_EXECINFO@
LIB_GETRANDOM = @LIB_GETRANDOM@
+LIB_HAS_ACL = @LIB_HAS_ACL@
LIB_MATH = @LIB_MATH@
LIB_PTHREAD = @LIB_PTHREAD@
LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@
@@ -1023,6 +1037,7 @@ REPLACE_READ = @REPLACE_READ@
REPLACE_READLINK = @REPLACE_READLINK@
REPLACE_READLINKAT = @REPLACE_READLINKAT@
REPLACE_REALLOC = @REPLACE_REALLOC@
+REPLACE_REALLOCARRAY = @REPLACE_REALLOCARRAY@
REPLACE_REALPATH = @REPLACE_REALPATH@
REPLACE_REMOVE = @REPLACE_REMOVE@
REPLACE_RENAME = @REPLACE_RENAME@
@@ -1053,7 +1068,11 @@ REPLACE_STRSTR = @REPLACE_STRSTR@
REPLACE_STRTOD = @REPLACE_STRTOD@
REPLACE_STRTOIMAX = @REPLACE_STRTOIMAX@
REPLACE_STRTOK_R = @REPLACE_STRTOK_R@
+REPLACE_STRTOL = @REPLACE_STRTOL@
REPLACE_STRTOLD = @REPLACE_STRTOLD@
+REPLACE_STRTOLL = @REPLACE_STRTOLL@
+REPLACE_STRTOUL = @REPLACE_STRTOUL@
+REPLACE_STRTOULL = @REPLACE_STRTOULL@
REPLACE_STRTOUMAX = @REPLACE_STRTOUMAX@
REPLACE_STRUCT_TIMEVAL = @REPLACE_STRUCT_TIMEVAL@
REPLACE_SYMLINK = @REPLACE_SYMLINK@
@@ -1104,6 +1123,7 @@ UNISTD_H_HAVE_SYS_RANDOM_H = @UNISTD_H_HAVE_SYS_RANDOM_H@
UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@
UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
USE_ACL = @USE_ACL@
+USE_STARTUP_NOTIFICATION = @USE_STARTUP_NOTIFICATION@
VMLIMIT_OBJ = @VMLIMIT_OBJ@
W32_LIBS = @W32_LIBS@
W32_OBJ = @W32_OBJ@
@@ -1172,17 +1192,19 @@ gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7 = @gl_GNULIB_ENABLED_03e0aaad
gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b = @gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b@
gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31 = @gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31@
gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c = @gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c@
+gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4 = @gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4@
gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec = @gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec@
gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c = @gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c@
gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1 = @gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1@
gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36 = @gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36@
gl_GNULIB_ENABLED_cloexec = @gl_GNULIB_ENABLED_cloexec@
+gl_GNULIB_ENABLED_d3b2383720ee0e541357aa2aac598e2b = @gl_GNULIB_ENABLED_d3b2383720ee0e541357aa2aac598e2b@
gl_GNULIB_ENABLED_dirfd = @gl_GNULIB_ENABLED_dirfd@
gl_GNULIB_ENABLED_dynarray = @gl_GNULIB_ENABLED_dynarray@
+gl_GNULIB_ENABLED_ef455225c00f5049c808c2eda3e76866 = @gl_GNULIB_ENABLED_ef455225c00f5049c808c2eda3e76866@
gl_GNULIB_ENABLED_euidaccess = @gl_GNULIB_ENABLED_euidaccess@
gl_GNULIB_ENABLED_getdtablesize = @gl_GNULIB_ENABLED_getdtablesize@
gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@
-gl_GNULIB_ENABLED_idx = @gl_GNULIB_ENABLED_idx@
gl_GNULIB_ENABLED_lchmod = @gl_GNULIB_ENABLED_lchmod@
gl_GNULIB_ENABLED_open = @gl_GNULIB_ENABLED_open@
gl_GNULIB_ENABLED_rawmemchr = @gl_GNULIB_ENABLED_rawmemchr@
@@ -1206,6 +1228,7 @@ libdir = @libdir@
libexecdir = @libexecdir@
liblockfile = @liblockfile@
lispdir = @lispdir@
+lispdirrel = @lispdirrel@
lisppath = @lisppath@
localedir = @localedir@
locallisppath = @locallisppath@
@@ -1213,6 +1236,8 @@ localstatedir = @localstatedir@
mandir = @mandir@
ns_appbindir = @ns_appbindir@
ns_appdir = @ns_appdir@
+ns_applibdir = @ns_applibdir@
+ns_applibexecdir = @ns_applibexecdir@
ns_appresdir = @ns_appresdir@
ns_appsrc = @ns_appsrc@
ns_check_file = @ns_check_file@
@@ -1222,6 +1247,7 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
+runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@@ -1450,6 +1476,14 @@ EXTRA_DIST += count-trailing-zeros.h
endif
## end gnulib module count-trailing-zeros
+## begin gnulib module crypto/md5
+ifeq (,$(OMIT_GNULIB_MODULE_crypto/md5))
+
+libgnu_a_SOURCES += md5-stream.c
+
+endif
+## end gnulib module crypto/md5
+
## begin gnulib module crypto/md5-buffer
ifeq (,$(OMIT_GNULIB_MODULE_crypto/md5-buffer))
@@ -1514,14 +1548,14 @@ dirent.h: dirent.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_DIRENT_H''@|$(NEXT_DIRENT_H)|g' \
- -e 's/@''GNULIB_OPENDIR''@/$(GNULIB_OPENDIR)/g' \
- -e 's/@''GNULIB_READDIR''@/$(GNULIB_READDIR)/g' \
- -e 's/@''GNULIB_REWINDDIR''@/$(GNULIB_REWINDDIR)/g' \
- -e 's/@''GNULIB_CLOSEDIR''@/$(GNULIB_CLOSEDIR)/g' \
- -e 's/@''GNULIB_DIRFD''@/$(GNULIB_DIRFD)/g' \
- -e 's/@''GNULIB_FDOPENDIR''@/$(GNULIB_FDOPENDIR)/g' \
- -e 's/@''GNULIB_SCANDIR''@/$(GNULIB_SCANDIR)/g' \
- -e 's/@''GNULIB_ALPHASORT''@/$(GNULIB_ALPHASORT)/g' \
+ -e 's/@''GNULIB_OPENDIR''@/$(GL_GNULIB_OPENDIR)/g' \
+ -e 's/@''GNULIB_READDIR''@/$(GL_GNULIB_READDIR)/g' \
+ -e 's/@''GNULIB_REWINDDIR''@/$(GL_GNULIB_REWINDDIR)/g' \
+ -e 's/@''GNULIB_CLOSEDIR''@/$(GL_GNULIB_CLOSEDIR)/g' \
+ -e 's/@''GNULIB_DIRFD''@/$(GL_GNULIB_DIRFD)/g' \
+ -e 's/@''GNULIB_FDOPENDIR''@/$(GL_GNULIB_FDOPENDIR)/g' \
+ -e 's/@''GNULIB_SCANDIR''@/$(GL_GNULIB_SCANDIR)/g' \
+ -e 's/@''GNULIB_ALPHASORT''@/$(GL_GNULIB_ALPHASORT)/g' \
-e 's/@''HAVE_OPENDIR''@/$(HAVE_OPENDIR)/g' \
-e 's/@''HAVE_READDIR''@/$(HAVE_READDIR)/g' \
-e 's/@''HAVE_REWINDDIR''@/$(HAVE_REWINDDIR)/g' \
@@ -1596,6 +1630,32 @@ endif
ifeq (,$(OMIT_GNULIB_MODULE_dynarray))
ifneq (,$(gl_GNULIB_ENABLED_dynarray))
+BUILT_SOURCES += malloc/dynarray.gl.h malloc/dynarray-skeleton.gl.h
+
+malloc/dynarray.gl.h: malloc/dynarray.h
+ $(AM_V_at)$(MKDIR_P) malloc
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e '/libc_hidden_proto/d' < $(srcdir)/malloc/dynarray.h; \
+ } > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += malloc/dynarray.gl.h malloc/dynarray.gl.h-t
+
+malloc/dynarray-skeleton.gl.h: malloc/dynarray-skeleton.c
+ $(AM_V_at)$(MKDIR_P) malloc
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's|<malloc/dynarray\.h>|<malloc/dynarray.gl.h>|g' \
+ -e 's|__attribute_maybe_unused__|_GL_ATTRIBUTE_MAYBE_UNUSED|g' \
+ -e 's|__attribute_nonnull__|_GL_ATTRIBUTE_NONNULL|g' \
+ -e 's|__attribute_warn_unused_result__|_GL_ATTRIBUTE_NODISCARD|g' \
+ -e 's|__glibc_likely|_GL_LIKELY|g' \
+ -e 's|__glibc_unlikely|_GL_UNLIKELY|g' \
+ < $(srcdir)/malloc/dynarray-skeleton.c; \
+ } > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += malloc/dynarray-skeleton.gl.h malloc/dynarray-skeleton.gl.h-t
+
libgnu_a_SOURCES += malloc/dynarray_at_failure.c malloc/dynarray_emplace_enlarge.c malloc/dynarray_finalize.c malloc/dynarray_resize.c malloc/dynarray_resize_clear.c
endif
@@ -1752,13 +1812,13 @@ fcntl.h: fcntl.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_FCNTL_H''@|$(NEXT_FCNTL_H)|g' \
- -e 's/@''GNULIB_CREAT''@/$(GNULIB_CREAT)/g' \
- -e 's/@''GNULIB_FCNTL''@/$(GNULIB_FCNTL)/g' \
- -e 's/@''GNULIB_NONBLOCKING''@/$(GNULIB_NONBLOCKING)/g' \
- -e 's/@''GNULIB_OPEN''@/$(GNULIB_OPEN)/g' \
- -e 's/@''GNULIB_OPENAT''@/$(GNULIB_OPENAT)/g' \
- -e 's/@''GNULIB_MDA_CREAT''@/$(GNULIB_MDA_CREAT)/g' \
- -e 's/@''GNULIB_MDA_OPEN''@/$(GNULIB_MDA_OPEN)/g' \
+ -e 's/@''GNULIB_CREAT''@/$(GL_GNULIB_CREAT)/g' \
+ -e 's/@''GNULIB_FCNTL''@/$(GL_GNULIB_FCNTL)/g' \
+ -e 's/@''GNULIB_NONBLOCKING''@/$(GL_GNULIB_NONBLOCKING)/g' \
+ -e 's/@''GNULIB_OPEN''@/$(GL_GNULIB_OPEN)/g' \
+ -e 's/@''GNULIB_OPENAT''@/$(GL_GNULIB_OPENAT)/g' \
+ -e 's/@''GNULIB_MDA_CREAT''@/$(GL_GNULIB_MDA_CREAT)/g' \
+ -e 's/@''GNULIB_MDA_OPEN''@/$(GL_GNULIB_MDA_OPEN)/g' \
-e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \
-e 's|@''HAVE_OPENAT''@|$(HAVE_OPENAT)|g' \
-e 's|@''REPLACE_CREAT''@|$(REPLACE_CREAT)|g' \
@@ -2043,11 +2103,9 @@ endif
## begin gnulib module idx
ifeq (,$(OMIT_GNULIB_MODULE_idx))
-ifneq (,$(gl_GNULIB_ENABLED_idx))
libgnu_a_SOURCES += idx.h
endif
-endif
## end gnulib module idx
## begin gnulib module ieee754-h
@@ -2111,10 +2169,10 @@ inttypes.h: inttypes.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_U
-e 's|@''NEXT_INTTYPES_H''@|$(NEXT_INTTYPES_H)|g' \
-e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \
-e 's/@''PRIPTR_PREFIX''@/$(PRIPTR_PREFIX)/g' \
- -e 's/@''GNULIB_IMAXABS''@/$(GNULIB_IMAXABS)/g' \
- -e 's/@''GNULIB_IMAXDIV''@/$(GNULIB_IMAXDIV)/g' \
- -e 's/@''GNULIB_STRTOIMAX''@/$(GNULIB_STRTOIMAX)/g' \
- -e 's/@''GNULIB_STRTOUMAX''@/$(GNULIB_STRTOUMAX)/g' \
+ -e 's/@''GNULIB_IMAXABS''@/$(GL_GNULIB_IMAXABS)/g' \
+ -e 's/@''GNULIB_IMAXDIV''@/$(GL_GNULIB_IMAXDIV)/g' \
+ -e 's/@''GNULIB_STRTOIMAX''@/$(GL_GNULIB_STRTOIMAX)/g' \
+ -e 's/@''GNULIB_STRTOUMAX''@/$(GL_GNULIB_STRTOUMAX)/g' \
-e 's/@''HAVE_DECL_IMAXABS''@/$(HAVE_DECL_IMAXABS)/g' \
-e 's/@''HAVE_DECL_IMAXDIV''@/$(HAVE_DECL_IMAXDIV)/g' \
-e 's/@''HAVE_DECL_STRTOIMAX''@/$(HAVE_DECL_STRTOIMAX)/g' \
@@ -2232,6 +2290,19 @@ EXTRA_libgnu_a_SOURCES += lstat.c
endif
## end gnulib module lstat
+## begin gnulib module malloc-posix
+ifeq (,$(OMIT_GNULIB_MODULE_malloc-posix))
+
+ifneq (,$(gl_GNULIB_ENABLED_ef455225c00f5049c808c2eda3e76866))
+
+endif
+EXTRA_DIST += malloc.c
+
+EXTRA_libgnu_a_SOURCES += malloc.c
+
+endif
+## end gnulib module malloc-posix
+
## begin gnulib module memmem-simple
ifeq (,$(OMIT_GNULIB_MODULE_memmem-simple))
@@ -2308,6 +2379,16 @@ EXTRA_libgnu_a_SOURCES += mktime.c
endif
## end gnulib module mktime-internal
+## begin gnulib module nproc
+ifeq (,$(OMIT_GNULIB_MODULE_nproc))
+
+libgnu_a_SOURCES += nproc.c
+
+EXTRA_DIST += nproc.h
+
+endif
+## end gnulib module nproc
+
## begin gnulib module nstrftime
ifeq (,$(OMIT_GNULIB_MODULE_nstrftime))
@@ -2424,6 +2505,32 @@ EXTRA_libgnu_a_SOURCES += at-func.c readlinkat.c
endif
## end gnulib module readlinkat
+## begin gnulib module realloc-gnu
+ifeq (,$(OMIT_GNULIB_MODULE_realloc-gnu))
+
+ifneq (,$(gl_GNULIB_ENABLED_d3b2383720ee0e541357aa2aac598e2b))
+
+endif
+EXTRA_DIST += realloc.c
+
+EXTRA_libgnu_a_SOURCES += realloc.c
+
+endif
+## end gnulib module realloc-gnu
+
+## begin gnulib module realloc-posix
+ifeq (,$(OMIT_GNULIB_MODULE_realloc-posix))
+
+ifneq (,$(gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4))
+
+endif
+EXTRA_DIST += realloc.c
+
+EXTRA_libgnu_a_SOURCES += realloc.c
+
+endif
+## end gnulib module realloc-posix
+
## begin gnulib module regex
ifeq (,$(OMIT_GNULIB_MODULE_regex))
@@ -2450,6 +2557,21 @@ endif
ifeq (,$(OMIT_GNULIB_MODULE_scratch_buffer))
ifneq (,$(gl_GNULIB_ENABLED_scratch_buffer))
+BUILT_SOURCES += malloc/scratch_buffer.gl.h
+
+malloc/scratch_buffer.gl.h: malloc/scratch_buffer.h
+ $(AM_V_at)$(MKDIR_P) malloc
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's|__always_inline|inline _GL_ATTRIBUTE_ALWAYS_INLINE|g' \
+ -e 's|__glibc_likely|_GL_LIKELY|g' \
+ -e 's|__glibc_unlikely|_GL_UNLIKELY|g' \
+ -e '/libc_hidden_proto/d' \
+ < $(srcdir)/malloc/scratch_buffer.h; \
+ } > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += malloc/scratch_buffer.gl.h malloc/scratch_buffer.gl.h-t
+
libgnu_a_SOURCES += malloc/scratch_buffer_dupfree.c malloc/scratch_buffer_grow.c malloc/scratch_buffer_grow_preserve.c malloc/scratch_buffer_set_array_size.c
endif
@@ -2495,11 +2617,11 @@ signal.h: signal.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_SIGNAL_H''@|$(NEXT_SIGNAL_H)|g' \
- -e 's/@''GNULIB_PTHREAD_SIGMASK''@/$(GNULIB_PTHREAD_SIGMASK)/g' \
- -e 's/@''GNULIB_RAISE''@/$(GNULIB_RAISE)/g' \
- -e 's/@''GNULIB_SIGNAL_H_SIGPIPE''@/$(GNULIB_SIGNAL_H_SIGPIPE)/g' \
- -e 's/@''GNULIB_SIGPROCMASK''@/$(GNULIB_SIGPROCMASK)/g' \
- -e 's/@''GNULIB_SIGACTION''@/$(GNULIB_SIGACTION)/g' \
+ -e 's/@''GNULIB_PTHREAD_SIGMASK''@/$(GL_GNULIB_PTHREAD_SIGMASK)/g' \
+ -e 's/@''GNULIB_RAISE''@/$(GL_GNULIB_RAISE)/g' \
+ -e 's/@''GNULIB_SIGNAL_H_SIGPIPE''@/$(GL_GNULIB_SIGNAL_H_SIGPIPE)/g' \
+ -e 's/@''GNULIB_SIGPROCMASK''@/$(GL_GNULIB_SIGPROCMASK)/g' \
+ -e 's/@''GNULIB_SIGACTION''@/$(GL_GNULIB_SIGACTION)/g' \
-e 's|@''HAVE_POSIX_SIGNALBLOCKING''@|$(HAVE_POSIX_SIGNALBLOCKING)|g' \
-e 's|@''HAVE_PTHREAD_SIGMASK''@|$(HAVE_PTHREAD_SIGMASK)|g' \
-e 's|@''HAVE_RAISE''@|$(HAVE_RAISE)|g' \
@@ -2685,7 +2807,7 @@ stdint.h: stdint.in.h $(top_builddir)/config.status
-e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \
-e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \
-e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \
- -e 's/@''GNULIB_OVERRIDES_WINT_T''@/$(GNULIB_OVERRIDES_WINT_T)/g' \
+ -e 's/@''GNULIBHEADERS_OVERRIDE_WINT_T''@/$(GNULIBHEADERS_OVERRIDE_WINT_T)/g' \
< $(srcdir)/stdint.in.h; \
} > $@-t && \
mv $@-t $@
@@ -2715,65 +2837,65 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \
- -e 's/@''GNULIB_DPRINTF''@/$(GNULIB_DPRINTF)/g' \
- -e 's/@''GNULIB_FCLOSE''@/$(GNULIB_FCLOSE)/g' \
- -e 's/@''GNULIB_FDOPEN''@/$(GNULIB_FDOPEN)/g' \
- -e 's/@''GNULIB_FFLUSH''@/$(GNULIB_FFLUSH)/g' \
- -e 's/@''GNULIB_FGETC''@/$(GNULIB_FGETC)/g' \
- -e 's/@''GNULIB_FGETS''@/$(GNULIB_FGETS)/g' \
- -e 's/@''GNULIB_FOPEN''@/$(GNULIB_FOPEN)/g' \
- -e 's/@''GNULIB_FPRINTF''@/$(GNULIB_FPRINTF)/g' \
- -e 's/@''GNULIB_FPRINTF_POSIX''@/$(GNULIB_FPRINTF_POSIX)/g' \
- -e 's/@''GNULIB_FPURGE''@/$(GNULIB_FPURGE)/g' \
- -e 's/@''GNULIB_FPUTC''@/$(GNULIB_FPUTC)/g' \
- -e 's/@''GNULIB_FPUTS''@/$(GNULIB_FPUTS)/g' \
- -e 's/@''GNULIB_FREAD''@/$(GNULIB_FREAD)/g' \
- -e 's/@''GNULIB_FREOPEN''@/$(GNULIB_FREOPEN)/g' \
- -e 's/@''GNULIB_FSCANF''@/$(GNULIB_FSCANF)/g' \
- -e 's/@''GNULIB_FSEEK''@/$(GNULIB_FSEEK)/g' \
- -e 's/@''GNULIB_FSEEKO''@/$(GNULIB_FSEEKO)/g' \
- -e 's/@''GNULIB_FTELL''@/$(GNULIB_FTELL)/g' \
- -e 's/@''GNULIB_FTELLO''@/$(GNULIB_FTELLO)/g' \
- -e 's/@''GNULIB_FWRITE''@/$(GNULIB_FWRITE)/g' \
- -e 's/@''GNULIB_GETC''@/$(GNULIB_GETC)/g' \
- -e 's/@''GNULIB_GETCHAR''@/$(GNULIB_GETCHAR)/g' \
- -e 's/@''GNULIB_GETDELIM''@/$(GNULIB_GETDELIM)/g' \
- -e 's/@''GNULIB_GETLINE''@/$(GNULIB_GETLINE)/g' \
- -e 's/@''GNULIB_OBSTACK_PRINTF''@/$(GNULIB_OBSTACK_PRINTF)/g' \
- -e 's/@''GNULIB_OBSTACK_PRINTF_POSIX''@/$(GNULIB_OBSTACK_PRINTF_POSIX)/g' \
- -e 's/@''GNULIB_PCLOSE''@/$(GNULIB_PCLOSE)/g' \
- -e 's/@''GNULIB_PERROR''@/$(GNULIB_PERROR)/g' \
- -e 's/@''GNULIB_POPEN''@/$(GNULIB_POPEN)/g' \
- -e 's/@''GNULIB_PRINTF''@/$(GNULIB_PRINTF)/g' \
- -e 's/@''GNULIB_PRINTF_POSIX''@/$(GNULIB_PRINTF_POSIX)/g' \
- -e 's/@''GNULIB_PUTC''@/$(GNULIB_PUTC)/g' \
- -e 's/@''GNULIB_PUTCHAR''@/$(GNULIB_PUTCHAR)/g' \
- -e 's/@''GNULIB_PUTS''@/$(GNULIB_PUTS)/g' \
- -e 's/@''GNULIB_REMOVE''@/$(GNULIB_REMOVE)/g' \
- -e 's/@''GNULIB_RENAME''@/$(GNULIB_RENAME)/g' \
- -e 's/@''GNULIB_RENAMEAT''@/$(GNULIB_RENAMEAT)/g' \
- -e 's/@''GNULIB_SCANF''@/$(GNULIB_SCANF)/g' \
- -e 's/@''GNULIB_SNPRINTF''@/$(GNULIB_SNPRINTF)/g' \
- -e 's/@''GNULIB_SPRINTF_POSIX''@/$(GNULIB_SPRINTF_POSIX)/g' \
- -e 's/@''GNULIB_STDIO_H_NONBLOCKING''@/$(GNULIB_STDIO_H_NONBLOCKING)/g' \
- -e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GNULIB_STDIO_H_SIGPIPE)/g' \
- -e 's/@''GNULIB_TMPFILE''@/$(GNULIB_TMPFILE)/g' \
- -e 's/@''GNULIB_VASPRINTF''@/$(GNULIB_VASPRINTF)/g' \
- -e 's/@''GNULIB_VDPRINTF''@/$(GNULIB_VDPRINTF)/g' \
- -e 's/@''GNULIB_VFPRINTF''@/$(GNULIB_VFPRINTF)/g' \
- -e 's/@''GNULIB_VFPRINTF_POSIX''@/$(GNULIB_VFPRINTF_POSIX)/g' \
- -e 's/@''GNULIB_VFSCANF''@/$(GNULIB_VFSCANF)/g' \
- -e 's/@''GNULIB_VSCANF''@/$(GNULIB_VSCANF)/g' \
- -e 's/@''GNULIB_VPRINTF''@/$(GNULIB_VPRINTF)/g' \
- -e 's/@''GNULIB_VPRINTF_POSIX''@/$(GNULIB_VPRINTF_POSIX)/g' \
- -e 's/@''GNULIB_VSNPRINTF''@/$(GNULIB_VSNPRINTF)/g' \
- -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GNULIB_VSPRINTF_POSIX)/g' \
- -e 's/@''GNULIB_MDA_FCLOSEALL''@/$(GNULIB_MDA_FCLOSEALL)/g' \
- -e 's/@''GNULIB_MDA_FDOPEN''@/$(GNULIB_MDA_FDOPEN)/g' \
- -e 's/@''GNULIB_MDA_FILENO''@/$(GNULIB_MDA_FILENO)/g' \
- -e 's/@''GNULIB_MDA_GETW''@/$(GNULIB_MDA_GETW)/g' \
- -e 's/@''GNULIB_MDA_PUTW''@/$(GNULIB_MDA_PUTW)/g' \
- -e 's/@''GNULIB_MDA_TEMPNAM''@/$(GNULIB_MDA_TEMPNAM)/g' \
+ -e 's/@''GNULIB_DPRINTF''@/$(GL_GNULIB_DPRINTF)/g' \
+ -e 's/@''GNULIB_FCLOSE''@/$(GL_GNULIB_FCLOSE)/g' \
+ -e 's/@''GNULIB_FDOPEN''@/$(GL_GNULIB_FDOPEN)/g' \
+ -e 's/@''GNULIB_FFLUSH''@/$(GL_GNULIB_FFLUSH)/g' \
+ -e 's/@''GNULIB_FGETC''@/$(GL_GNULIB_FGETC)/g' \
+ -e 's/@''GNULIB_FGETS''@/$(GL_GNULIB_FGETS)/g' \
+ -e 's/@''GNULIB_FOPEN''@/$(GL_GNULIB_FOPEN)/g' \
+ -e 's/@''GNULIB_FPRINTF''@/$(GL_GNULIB_FPRINTF)/g' \
+ -e 's/@''GNULIB_FPRINTF_POSIX''@/$(GL_GNULIB_FPRINTF_POSIX)/g' \
+ -e 's/@''GNULIB_FPURGE''@/$(GL_GNULIB_FPURGE)/g' \
+ -e 's/@''GNULIB_FPUTC''@/$(GL_GNULIB_FPUTC)/g' \
+ -e 's/@''GNULIB_FPUTS''@/$(GL_GNULIB_FPUTS)/g' \
+ -e 's/@''GNULIB_FREAD''@/$(GL_GNULIB_FREAD)/g' \
+ -e 's/@''GNULIB_FREOPEN''@/$(GL_GNULIB_FREOPEN)/g' \
+ -e 's/@''GNULIB_FSCANF''@/$(GL_GNULIB_FSCANF)/g' \
+ -e 's/@''GNULIB_FSEEK''@/$(GL_GNULIB_FSEEK)/g' \
+ -e 's/@''GNULIB_FSEEKO''@/$(GL_GNULIB_FSEEKO)/g' \
+ -e 's/@''GNULIB_FTELL''@/$(GL_GNULIB_FTELL)/g' \
+ -e 's/@''GNULIB_FTELLO''@/$(GL_GNULIB_FTELLO)/g' \
+ -e 's/@''GNULIB_FWRITE''@/$(GL_GNULIB_FWRITE)/g' \
+ -e 's/@''GNULIB_GETC''@/$(GL_GNULIB_GETC)/g' \
+ -e 's/@''GNULIB_GETCHAR''@/$(GL_GNULIB_GETCHAR)/g' \
+ -e 's/@''GNULIB_GETDELIM''@/$(GL_GNULIB_GETDELIM)/g' \
+ -e 's/@''GNULIB_GETLINE''@/$(GL_GNULIB_GETLINE)/g' \
+ -e 's/@''GNULIB_OBSTACK_PRINTF''@/$(GL_GNULIB_OBSTACK_PRINTF)/g' \
+ -e 's/@''GNULIB_OBSTACK_PRINTF_POSIX''@/$(GL_GNULIB_OBSTACK_PRINTF_POSIX)/g' \
+ -e 's/@''GNULIB_PCLOSE''@/$(GL_GNULIB_PCLOSE)/g' \
+ -e 's/@''GNULIB_PERROR''@/$(GL_GNULIB_PERROR)/g' \
+ -e 's/@''GNULIB_POPEN''@/$(GL_GNULIB_POPEN)/g' \
+ -e 's/@''GNULIB_PRINTF''@/$(GL_GNULIB_PRINTF)/g' \
+ -e 's/@''GNULIB_PRINTF_POSIX''@/$(GL_GNULIB_PRINTF_POSIX)/g' \
+ -e 's/@''GNULIB_PUTC''@/$(GL_GNULIB_PUTC)/g' \
+ -e 's/@''GNULIB_PUTCHAR''@/$(GL_GNULIB_PUTCHAR)/g' \
+ -e 's/@''GNULIB_PUTS''@/$(GL_GNULIB_PUTS)/g' \
+ -e 's/@''GNULIB_REMOVE''@/$(GL_GNULIB_REMOVE)/g' \
+ -e 's/@''GNULIB_RENAME''@/$(GL_GNULIB_RENAME)/g' \
+ -e 's/@''GNULIB_RENAMEAT''@/$(GL_GNULIB_RENAMEAT)/g' \
+ -e 's/@''GNULIB_SCANF''@/$(GL_GNULIB_SCANF)/g' \
+ -e 's/@''GNULIB_SNPRINTF''@/$(GL_GNULIB_SNPRINTF)/g' \
+ -e 's/@''GNULIB_SPRINTF_POSIX''@/$(GL_GNULIB_SPRINTF_POSIX)/g' \
+ -e 's/@''GNULIB_STDIO_H_NONBLOCKING''@/$(GL_GNULIB_STDIO_H_NONBLOCKING)/g' \
+ -e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GL_GNULIB_STDIO_H_SIGPIPE)/g' \
+ -e 's/@''GNULIB_TMPFILE''@/$(GL_GNULIB_TMPFILE)/g' \
+ -e 's/@''GNULIB_VASPRINTF''@/$(GL_GNULIB_VASPRINTF)/g' \
+ -e 's/@''GNULIB_VDPRINTF''@/$(GL_GNULIB_VDPRINTF)/g' \
+ -e 's/@''GNULIB_VFPRINTF''@/$(GL_GNULIB_VFPRINTF)/g' \
+ -e 's/@''GNULIB_VFPRINTF_POSIX''@/$(GL_GNULIB_VFPRINTF_POSIX)/g' \
+ -e 's/@''GNULIB_VFSCANF''@/$(GL_GNULIB_VFSCANF)/g' \
+ -e 's/@''GNULIB_VSCANF''@/$(GL_GNULIB_VSCANF)/g' \
+ -e 's/@''GNULIB_VPRINTF''@/$(GL_GNULIB_VPRINTF)/g' \
+ -e 's/@''GNULIB_VPRINTF_POSIX''@/$(GL_GNULIB_VPRINTF_POSIX)/g' \
+ -e 's/@''GNULIB_VSNPRINTF''@/$(GL_GNULIB_VSNPRINTF)/g' \
+ -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GL_GNULIB_VSPRINTF_POSIX)/g' \
+ -e 's/@''GNULIB_MDA_FCLOSEALL''@/$(GL_GNULIB_MDA_FCLOSEALL)/g' \
+ -e 's/@''GNULIB_MDA_FDOPEN''@/$(GL_GNULIB_MDA_FDOPEN)/g' \
+ -e 's/@''GNULIB_MDA_FILENO''@/$(GL_GNULIB_MDA_FILENO)/g' \
+ -e 's/@''GNULIB_MDA_GETW''@/$(GL_GNULIB_MDA_GETW)/g' \
+ -e 's/@''GNULIB_MDA_PUTW''@/$(GL_GNULIB_MDA_PUTW)/g' \
+ -e 's/@''GNULIB_MDA_TEMPNAM''@/$(GL_GNULIB_MDA_TEMPNAM)/g' \
< $(srcdir)/stdio.in.h | \
sed -e 's|@''HAVE_DECL_FCLOSEALL''@|$(HAVE_DECL_FCLOSEALL)|g' \
-e 's|@''HAVE_DECL_FPURGE''@|$(HAVE_DECL_FPURGE)|g' \
@@ -2853,49 +2975,51 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \
- -e 's/@''GNULIB__EXIT''@/$(GNULIB__EXIT)/g' \
- -e 's/@''GNULIB_ALIGNED_ALLOC''@/$(GNULIB_ALIGNED_ALLOC)/g' \
- -e 's/@''GNULIB_ATOLL''@/$(GNULIB_ATOLL)/g' \
- -e 's/@''GNULIB_CALLOC_POSIX''@/$(GNULIB_CALLOC_POSIX)/g' \
- -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GNULIB_CANONICALIZE_FILE_NAME)/g' \
- -e 's/@''GNULIB_FREE_POSIX''@/$(GNULIB_FREE_POSIX)/g' \
- -e 's/@''GNULIB_GETLOADAVG''@/$(GNULIB_GETLOADAVG)/g' \
- -e 's/@''GNULIB_GETSUBOPT''@/$(GNULIB_GETSUBOPT)/g' \
- -e 's/@''GNULIB_GRANTPT''@/$(GNULIB_GRANTPT)/g' \
- -e 's/@''GNULIB_MALLOC_POSIX''@/$(GNULIB_MALLOC_POSIX)/g' \
- -e 's/@''GNULIB_MBTOWC''@/$(GNULIB_MBTOWC)/g' \
- -e 's/@''GNULIB_MKDTEMP''@/$(GNULIB_MKDTEMP)/g' \
- -e 's/@''GNULIB_MKOSTEMP''@/$(GNULIB_MKOSTEMP)/g' \
- -e 's/@''GNULIB_MKOSTEMPS''@/$(GNULIB_MKOSTEMPS)/g' \
- -e 's/@''GNULIB_MKSTEMP''@/$(GNULIB_MKSTEMP)/g' \
- -e 's/@''GNULIB_MKSTEMPS''@/$(GNULIB_MKSTEMPS)/g' \
- -e 's/@''GNULIB_POSIX_MEMALIGN''@/$(GNULIB_POSIX_MEMALIGN)/g' \
- -e 's/@''GNULIB_POSIX_OPENPT''@/$(GNULIB_POSIX_OPENPT)/g' \
- -e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \
- -e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \
- -e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \
- -e 's/@''GNULIB_QSORT_R''@/$(GNULIB_QSORT_R)/g' \
- -e 's/@''GNULIB_RANDOM''@/$(GNULIB_RANDOM)/g' \
- -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \
- -e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \
- -e 's/@''GNULIB_REALLOCARRAY''@/$(GNULIB_REALLOCARRAY)/g' \
- -e 's/@''GNULIB_REALPATH''@/$(GNULIB_REALPATH)/g' \
- -e 's/@''GNULIB_RPMATCH''@/$(GNULIB_RPMATCH)/g' \
- -e 's/@''GNULIB_SECURE_GETENV''@/$(GNULIB_SECURE_GETENV)/g' \
- -e 's/@''GNULIB_SETENV''@/$(GNULIB_SETENV)/g' \
- -e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \
- -e 's/@''GNULIB_STRTOLD''@/$(GNULIB_STRTOLD)/g' \
- -e 's/@''GNULIB_STRTOLL''@/$(GNULIB_STRTOLL)/g' \
- -e 's/@''GNULIB_STRTOULL''@/$(GNULIB_STRTOULL)/g' \
- -e 's/@''GNULIB_SYSTEM_POSIX''@/$(GNULIB_SYSTEM_POSIX)/g' \
- -e 's/@''GNULIB_UNLOCKPT''@/$(GNULIB_UNLOCKPT)/g' \
- -e 's/@''GNULIB_UNSETENV''@/$(GNULIB_UNSETENV)/g' \
- -e 's/@''GNULIB_WCTOMB''@/$(GNULIB_WCTOMB)/g' \
- -e 's/@''GNULIB_MDA_ECVT''@/$(GNULIB_MDA_ECVT)/g' \
- -e 's/@''GNULIB_MDA_FCVT''@/$(GNULIB_MDA_FCVT)/g' \
- -e 's/@''GNULIB_MDA_GCVT''@/$(GNULIB_MDA_GCVT)/g' \
- -e 's/@''GNULIB_MDA_MKTEMP''@/$(GNULIB_MDA_MKTEMP)/g' \
- -e 's/@''GNULIB_MDA_PUTENV''@/$(GNULIB_MDA_PUTENV)/g' \
+ -e 's/@''GNULIB__EXIT''@/$(GL_GNULIB__EXIT)/g' \
+ -e 's/@''GNULIB_ALIGNED_ALLOC''@/$(GL_GNULIB_ALIGNED_ALLOC)/g' \
+ -e 's/@''GNULIB_ATOLL''@/$(GL_GNULIB_ATOLL)/g' \
+ -e 's/@''GNULIB_CALLOC_POSIX''@/$(GL_GNULIB_CALLOC_POSIX)/g' \
+ -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GL_GNULIB_CANONICALIZE_FILE_NAME)/g' \
+ -e 's/@''GNULIB_FREE_POSIX''@/$(GL_GNULIB_FREE_POSIX)/g' \
+ -e 's/@''GNULIB_GETLOADAVG''@/$(GL_GNULIB_GETLOADAVG)/g' \
+ -e 's/@''GNULIB_GETSUBOPT''@/$(GL_GNULIB_GETSUBOPT)/g' \
+ -e 's/@''GNULIB_GRANTPT''@/$(GL_GNULIB_GRANTPT)/g' \
+ -e 's/@''GNULIB_MALLOC_POSIX''@/$(GL_GNULIB_MALLOC_POSIX)/g' \
+ -e 's/@''GNULIB_MBTOWC''@/$(GL_GNULIB_MBTOWC)/g' \
+ -e 's/@''GNULIB_MKDTEMP''@/$(GL_GNULIB_MKDTEMP)/g' \
+ -e 's/@''GNULIB_MKOSTEMP''@/$(GL_GNULIB_MKOSTEMP)/g' \
+ -e 's/@''GNULIB_MKOSTEMPS''@/$(GL_GNULIB_MKOSTEMPS)/g' \
+ -e 's/@''GNULIB_MKSTEMP''@/$(GL_GNULIB_MKSTEMP)/g' \
+ -e 's/@''GNULIB_MKSTEMPS''@/$(GL_GNULIB_MKSTEMPS)/g' \
+ -e 's/@''GNULIB_POSIX_MEMALIGN''@/$(GL_GNULIB_POSIX_MEMALIGN)/g' \
+ -e 's/@''GNULIB_POSIX_OPENPT''@/$(GL_GNULIB_POSIX_OPENPT)/g' \
+ -e 's/@''GNULIB_PTSNAME''@/$(GL_GNULIB_PTSNAME)/g' \
+ -e 's/@''GNULIB_PTSNAME_R''@/$(GL_GNULIB_PTSNAME_R)/g' \
+ -e 's/@''GNULIB_PUTENV''@/$(GL_GNULIB_PUTENV)/g' \
+ -e 's/@''GNULIB_QSORT_R''@/$(GL_GNULIB_QSORT_R)/g' \
+ -e 's/@''GNULIB_RANDOM''@/$(GL_GNULIB_RANDOM)/g' \
+ -e 's/@''GNULIB_RANDOM_R''@/$(GL_GNULIB_RANDOM_R)/g' \
+ -e 's/@''GNULIB_REALLOC_POSIX''@/$(GL_GNULIB_REALLOC_POSIX)/g' \
+ -e 's/@''GNULIB_REALLOCARRAY''@/$(GL_GNULIB_REALLOCARRAY)/g' \
+ -e 's/@''GNULIB_REALPATH''@/$(GL_GNULIB_REALPATH)/g' \
+ -e 's/@''GNULIB_RPMATCH''@/$(GL_GNULIB_RPMATCH)/g' \
+ -e 's/@''GNULIB_SECURE_GETENV''@/$(GL_GNULIB_SECURE_GETENV)/g' \
+ -e 's/@''GNULIB_SETENV''@/$(GL_GNULIB_SETENV)/g' \
+ -e 's/@''GNULIB_STRTOD''@/$(GL_GNULIB_STRTOD)/g' \
+ -e 's/@''GNULIB_STRTOL''@/$(GL_GNULIB_STRTOL)/g' \
+ -e 's/@''GNULIB_STRTOLD''@/$(GL_GNULIB_STRTOLD)/g' \
+ -e 's/@''GNULIB_STRTOLL''@/$(GL_GNULIB_STRTOLL)/g' \
+ -e 's/@''GNULIB_STRTOUL''@/$(GL_GNULIB_STRTOUL)/g' \
+ -e 's/@''GNULIB_STRTOULL''@/$(GL_GNULIB_STRTOULL)/g' \
+ -e 's/@''GNULIB_SYSTEM_POSIX''@/$(GL_GNULIB_SYSTEM_POSIX)/g' \
+ -e 's/@''GNULIB_UNLOCKPT''@/$(GL_GNULIB_UNLOCKPT)/g' \
+ -e 's/@''GNULIB_UNSETENV''@/$(GL_GNULIB_UNSETENV)/g' \
+ -e 's/@''GNULIB_WCTOMB''@/$(GL_GNULIB_WCTOMB)/g' \
+ -e 's/@''GNULIB_MDA_ECVT''@/$(GL_GNULIB_MDA_ECVT)/g' \
+ -e 's/@''GNULIB_MDA_FCVT''@/$(GL_GNULIB_MDA_FCVT)/g' \
+ -e 's/@''GNULIB_MDA_GCVT''@/$(GL_GNULIB_MDA_GCVT)/g' \
+ -e 's/@''GNULIB_MDA_MKTEMP''@/$(GL_GNULIB_MDA_MKTEMP)/g' \
+ -e 's/@''GNULIB_MDA_PUTENV''@/$(GL_GNULIB_MDA_PUTENV)/g' \
< $(srcdir)/stdlib.in.h | \
sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \
-e 's|@''HAVE_ALIGNED_ALLOC''@|$(HAVE_ALIGNED_ALLOC)|g' \
@@ -2931,8 +3055,10 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
-e 's|@''HAVE_SETSTATE''@|$(HAVE_SETSTATE)|g' \
-e 's|@''HAVE_DECL_SETSTATE''@|$(HAVE_DECL_SETSTATE)|g' \
-e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \
+ -e 's|@''HAVE_STRTOL''@|$(HAVE_STRTOL)|g' \
-e 's|@''HAVE_STRTOLD''@|$(HAVE_STRTOLD)|g' \
-e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \
+ -e 's|@''HAVE_STRTOUL''@|$(HAVE_STRTOUL)|g' \
-e 's|@''HAVE_STRTOULL''@|$(HAVE_STRTOULL)|g' \
-e 's|@''HAVE_STRUCT_RANDOM_DATA''@|$(HAVE_STRUCT_RANDOM_DATA)|g' \
-e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \
@@ -2954,11 +3080,16 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
-e 's|@''REPLACE_RANDOM''@|$(REPLACE_RANDOM)|g' \
-e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \
-e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \
+ -e 's|@''REPLACE_REALLOCARRAY''@|$(REPLACE_REALLOCARRAY)|g' \
-e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \
-e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \
-e 's|@''REPLACE_SETSTATE''@|$(REPLACE_SETSTATE)|g' \
-e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \
+ -e 's|@''REPLACE_STRTOL''@|$(REPLACE_STRTOL)|g' \
-e 's|@''REPLACE_STRTOLD''@|$(REPLACE_STRTOLD)|g' \
+ -e 's|@''REPLACE_STRTOLL''@|$(REPLACE_STRTOLL)|g' \
+ -e 's|@''REPLACE_STRTOUL''@|$(REPLACE_STRTOUL)|g' \
+ -e 's|@''REPLACE_STRTOULL''@|$(REPLACE_STRTOULL)|g' \
-e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \
-e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
@@ -3000,49 +3131,50 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|g' \
- -e 's/@''GNULIB_EXPLICIT_BZERO''@/$(GNULIB_EXPLICIT_BZERO)/g' \
- -e 's/@''GNULIB_FFSL''@/$(GNULIB_FFSL)/g' \
- -e 's/@''GNULIB_FFSLL''@/$(GNULIB_FFSLL)/g' \
- -e 's/@''GNULIB_MBSLEN''@/$(GNULIB_MBSLEN)/g' \
- -e 's/@''GNULIB_MBSNLEN''@/$(GNULIB_MBSNLEN)/g' \
- -e 's/@''GNULIB_MBSCHR''@/$(GNULIB_MBSCHR)/g' \
- -e 's/@''GNULIB_MBSRCHR''@/$(GNULIB_MBSRCHR)/g' \
- -e 's/@''GNULIB_MBSSTR''@/$(GNULIB_MBSSTR)/g' \
- -e 's/@''GNULIB_MBSCASECMP''@/$(GNULIB_MBSCASECMP)/g' \
- -e 's/@''GNULIB_MBSNCASECMP''@/$(GNULIB_MBSNCASECMP)/g' \
- -e 's/@''GNULIB_MBSPCASECMP''@/$(GNULIB_MBSPCASECMP)/g' \
- -e 's/@''GNULIB_MBSCASESTR''@/$(GNULIB_MBSCASESTR)/g' \
- -e 's/@''GNULIB_MBSCSPN''@/$(GNULIB_MBSCSPN)/g' \
- -e 's/@''GNULIB_MBSPBRK''@/$(GNULIB_MBSPBRK)/g' \
- -e 's/@''GNULIB_MBSSPN''@/$(GNULIB_MBSSPN)/g' \
- -e 's/@''GNULIB_MBSSEP''@/$(GNULIB_MBSSEP)/g' \
- -e 's/@''GNULIB_MBSTOK_R''@/$(GNULIB_MBSTOK_R)/g' \
- -e 's/@''GNULIB_MEMCHR''@/$(GNULIB_MEMCHR)/g' \
- -e 's/@''GNULIB_MEMMEM''@/$(GNULIB_MEMMEM)/g' \
- -e 's/@''GNULIB_MEMPCPY''@/$(GNULIB_MEMPCPY)/g' \
- -e 's/@''GNULIB_MEMRCHR''@/$(GNULIB_MEMRCHR)/g' \
- -e 's/@''GNULIB_RAWMEMCHR''@/$(GNULIB_RAWMEMCHR)/g' \
- -e 's/@''GNULIB_STPCPY''@/$(GNULIB_STPCPY)/g' \
- -e 's/@''GNULIB_STPNCPY''@/$(GNULIB_STPNCPY)/g' \
- -e 's/@''GNULIB_STRCHRNUL''@/$(GNULIB_STRCHRNUL)/g' \
- -e 's/@''GNULIB_STRDUP''@/$(GNULIB_STRDUP)/g' \
- -e 's/@''GNULIB_STRNCAT''@/$(GNULIB_STRNCAT)/g' \
- -e 's/@''GNULIB_STRNDUP''@/$(GNULIB_STRNDUP)/g' \
- -e 's/@''GNULIB_STRNLEN''@/$(GNULIB_STRNLEN)/g' \
- -e 's/@''GNULIB_STRPBRK''@/$(GNULIB_STRPBRK)/g' \
- -e 's/@''GNULIB_STRSEP''@/$(GNULIB_STRSEP)/g' \
- -e 's/@''GNULIB_STRSTR''@/$(GNULIB_STRSTR)/g' \
- -e 's/@''GNULIB_STRCASESTR''@/$(GNULIB_STRCASESTR)/g' \
- -e 's/@''GNULIB_STRTOK_R''@/$(GNULIB_STRTOK_R)/g' \
- -e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \
- -e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \
- -e 's/@''GNULIB_STRERRORNAME_NP''@/$(GNULIB_STRERRORNAME_NP)/g' \
- -e 's/@''GNULIB_SIGABBREV_NP''@/$(GNULIB_SIGABBREV_NP)/g' \
- -e 's/@''GNULIB_SIGDESCR_NP''@/$(GNULIB_SIGDESCR_NP)/g' \
- -e 's/@''GNULIB_STRSIGNAL''@/$(GNULIB_STRSIGNAL)/g' \
- -e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \
- -e 's/@''GNULIB_MDA_MEMCCPY''@/$(GNULIB_MDA_MEMCCPY)/g' \
- -e 's/@''GNULIB_MDA_STRDUP''@/$(GNULIB_MDA_STRDUP)/g' \
+ -e 's/@''GNULIB_EXPLICIT_BZERO''@/$(GL_GNULIB_EXPLICIT_BZERO)/g' \
+ -e 's/@''GNULIB_FFSL''@/$(GL_GNULIB_FFSL)/g' \
+ -e 's/@''GNULIB_FFSLL''@/$(GL_GNULIB_FFSLL)/g' \
+ -e 's/@''GNULIB_MBSLEN''@/$(GL_GNULIB_MBSLEN)/g' \
+ -e 's/@''GNULIB_MBSNLEN''@/$(GL_GNULIB_MBSNLEN)/g' \
+ -e 's/@''GNULIB_MBSCHR''@/$(GL_GNULIB_MBSCHR)/g' \
+ -e 's/@''GNULIB_MBSRCHR''@/$(GL_GNULIB_MBSRCHR)/g' \
+ -e 's/@''GNULIB_MBSSTR''@/$(GL_GNULIB_MBSSTR)/g' \
+ -e 's/@''GNULIB_MBSCASECMP''@/$(GL_GNULIB_MBSCASECMP)/g' \
+ -e 's/@''GNULIB_MBSNCASECMP''@/$(GL_GNULIB_MBSNCASECMP)/g' \
+ -e 's/@''GNULIB_MBSPCASECMP''@/$(GL_GNULIB_MBSPCASECMP)/g' \
+ -e 's/@''GNULIB_MBSCASESTR''@/$(GL_GNULIB_MBSCASESTR)/g' \
+ -e 's/@''GNULIB_MBSCSPN''@/$(GL_GNULIB_MBSCSPN)/g' \
+ -e 's/@''GNULIB_MBSPBRK''@/$(GL_GNULIB_MBSPBRK)/g' \
+ -e 's/@''GNULIB_MBSSPN''@/$(GL_GNULIB_MBSSPN)/g' \
+ -e 's/@''GNULIB_MBSSEP''@/$(GL_GNULIB_MBSSEP)/g' \
+ -e 's/@''GNULIB_MBSTOK_R''@/$(GL_GNULIB_MBSTOK_R)/g' \
+ -e 's/@''GNULIB_MEMCHR''@/$(GL_GNULIB_MEMCHR)/g' \
+ -e 's/@''GNULIB_MEMMEM''@/$(GL_GNULIB_MEMMEM)/g' \
+ -e 's/@''GNULIB_MEMPCPY''@/$(GL_GNULIB_MEMPCPY)/g' \
+ -e 's/@''GNULIB_MEMRCHR''@/$(GL_GNULIB_MEMRCHR)/g' \
+ -e 's/@''GNULIB_RAWMEMCHR''@/$(GL_GNULIB_RAWMEMCHR)/g' \
+ -e 's/@''GNULIB_STPCPY''@/$(GL_GNULIB_STPCPY)/g' \
+ -e 's/@''GNULIB_STPNCPY''@/$(GL_GNULIB_STPNCPY)/g' \
+ -e 's/@''GNULIB_STRCHRNUL''@/$(GL_GNULIB_STRCHRNUL)/g' \
+ -e 's/@''GNULIB_STRDUP''@/$(GL_GNULIB_STRDUP)/g' \
+ -e 's/@''GNULIB_STRNCAT''@/$(GL_GNULIB_STRNCAT)/g' \
+ -e 's/@''GNULIB_STRNDUP''@/$(GL_GNULIB_STRNDUP)/g' \
+ -e 's/@''GNULIB_STRNLEN''@/$(GL_GNULIB_STRNLEN)/g' \
+ -e 's/@''GNULIB_STRPBRK''@/$(GL_GNULIB_STRPBRK)/g' \
+ -e 's/@''GNULIB_STRSEP''@/$(GL_GNULIB_STRSEP)/g' \
+ -e 's/@''GNULIB_STRSTR''@/$(GL_GNULIB_STRSTR)/g' \
+ -e 's/@''GNULIB_STRCASESTR''@/$(GL_GNULIB_STRCASESTR)/g' \
+ -e 's/@''GNULIB_STRTOK_R''@/$(GL_GNULIB_STRTOK_R)/g' \
+ -e 's/@''GNULIB_STRERROR''@/$(GL_GNULIB_STRERROR)/g' \
+ -e 's/@''GNULIB_STRERROR_R''@/$(GL_GNULIB_STRERROR_R)/g' \
+ -e 's/@''GNULIB_STRERRORNAME_NP''@/$(GL_GNULIB_STRERRORNAME_NP)/g' \
+ -e 's/@''GNULIB_SIGABBREV_NP''@/$(GL_GNULIB_SIGABBREV_NP)/g' \
+ -e 's/@''GNULIB_SIGDESCR_NP''@/$(GL_GNULIB_SIGDESCR_NP)/g' \
+ -e 's/@''GNULIB_STRSIGNAL''@/$(GL_GNULIB_STRSIGNAL)/g' \
+ -e 's/@''GNULIB_STRVERSCMP''@/$(GL_GNULIB_STRVERSCMP)/g' \
+ -e 's/@''GNULIB_MDA_MEMCCPY''@/$(GL_GNULIB_MDA_MEMCCPY)/g' \
+ -e 's/@''GNULIB_MDA_STRDUP''@/$(GL_GNULIB_MDA_STRDUP)/g' \
+ -e 's/@''GNULIB_FREE_POSIX''@/$(GL_GNULIB_FREE_POSIX)/g' \
< $(srcdir)/string.in.h | \
sed -e 's|@''HAVE_EXPLICIT_BZERO''@|$(HAVE_EXPLICIT_BZERO)|g' \
-e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \
@@ -3071,6 +3203,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's|@''REPLACE_FFSLL''@|$(REPLACE_FFSLL)|g' \
-e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \
-e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \
+ -e 's|@''REPLACE_FREE''@|$(REPLACE_FREE)|g' \
-e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \
-e 's|@''REPLACE_STRCHRNUL''@|$(REPLACE_STRCHRNUL)|g' \
-e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \
@@ -3161,7 +3294,7 @@ sys/random.h: sys_random.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_N
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_SYS_RANDOM_H''@|$(NEXT_SYS_RANDOM_H)|g' \
-e 's|@''HAVE_SYS_RANDOM_H''@|$(HAVE_SYS_RANDOM_H)|g' \
- -e 's/@''GNULIB_GETRANDOM''@/$(GNULIB_GETRANDOM)/g' \
+ -e 's/@''GNULIB_GETRANDOM''@/$(GL_GNULIB_GETRANDOM)/g' \
-e 's/@''HAVE_GETRANDOM''@/$(HAVE_GETRANDOM)/g' \
-e 's/@''REPLACE_GETRANDOM''@/$(REPLACE_GETRANDOM)/g' \
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
@@ -3195,8 +3328,8 @@ sys/select.h: sys_select.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_SYS_SELECT_H''@|$(NEXT_SYS_SELECT_H)|g' \
-e 's|@''HAVE_SYS_SELECT_H''@|$(HAVE_SYS_SELECT_H)|g' \
- -e 's/@''GNULIB_PSELECT''@/$(GNULIB_PSELECT)/g' \
- -e 's/@''GNULIB_SELECT''@/$(GNULIB_SELECT)/g' \
+ -e 's/@''GNULIB_PSELECT''@/$(GL_GNULIB_PSELECT)/g' \
+ -e 's/@''GNULIB_SELECT''@/$(GL_GNULIB_SELECT)/g' \
-e 's|@''HAVE_WINSOCK2_H''@|$(HAVE_WINSOCK2_H)|g' \
-e 's|@''HAVE_PSELECT''@|$(HAVE_PSELECT)|g' \
-e 's|@''REPLACE_PSELECT''@|$(REPLACE_PSELECT)|g' \
@@ -3232,25 +3365,25 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
-e 's|@''NEXT_SYS_STAT_H''@|$(NEXT_SYS_STAT_H)|g' \
-e 's|@''WINDOWS_64_BIT_ST_SIZE''@|$(WINDOWS_64_BIT_ST_SIZE)|g' \
-e 's|@''WINDOWS_STAT_TIMESPEC''@|$(WINDOWS_STAT_TIMESPEC)|g' \
- -e 's/@''GNULIB_FCHMODAT''@/$(GNULIB_FCHMODAT)/g' \
- -e 's/@''GNULIB_FSTAT''@/$(GNULIB_FSTAT)/g' \
- -e 's/@''GNULIB_FSTATAT''@/$(GNULIB_FSTATAT)/g' \
- -e 's/@''GNULIB_FUTIMENS''@/$(GNULIB_FUTIMENS)/g' \
- -e 's/@''GNULIB_GETUMASK''@/$(GNULIB_GETUMASK)/g' \
- -e 's/@''GNULIB_LCHMOD''@/$(GNULIB_LCHMOD)/g' \
- -e 's/@''GNULIB_LSTAT''@/$(GNULIB_LSTAT)/g' \
- -e 's/@''GNULIB_MKDIR''@/$(GNULIB_MKDIR)/g' \
- -e 's/@''GNULIB_MKDIRAT''@/$(GNULIB_MKDIRAT)/g' \
- -e 's/@''GNULIB_MKFIFO''@/$(GNULIB_MKFIFO)/g' \
- -e 's/@''GNULIB_MKFIFOAT''@/$(GNULIB_MKFIFOAT)/g' \
- -e 's/@''GNULIB_MKNOD''@/$(GNULIB_MKNOD)/g' \
- -e 's/@''GNULIB_MKNODAT''@/$(GNULIB_MKNODAT)/g' \
- -e 's/@''GNULIB_STAT''@/$(GNULIB_STAT)/g' \
- -e 's/@''GNULIB_UTIMENSAT''@/$(GNULIB_UTIMENSAT)/g' \
- -e 's/@''GNULIB_OVERRIDES_STRUCT_STAT''@/$(GNULIB_OVERRIDES_STRUCT_STAT)/g' \
- -e 's/@''GNULIB_MDA_CHMOD''@/$(GNULIB_MDA_CHMOD)/g' \
- -e 's/@''GNULIB_MDA_MKDIR''@/$(GNULIB_MDA_MKDIR)/g' \
- -e 's/@''GNULIB_MDA_UMASK''@/$(GNULIB_MDA_UMASK)/g' \
+ -e 's/@''GNULIB_FCHMODAT''@/$(GL_GNULIB_FCHMODAT)/g' \
+ -e 's/@''GNULIB_FSTAT''@/$(GL_GNULIB_FSTAT)/g' \
+ -e 's/@''GNULIB_FSTATAT''@/$(GL_GNULIB_FSTATAT)/g' \
+ -e 's/@''GNULIB_FUTIMENS''@/$(GL_GNULIB_FUTIMENS)/g' \
+ -e 's/@''GNULIB_GETUMASK''@/$(GL_GNULIB_GETUMASK)/g' \
+ -e 's/@''GNULIB_LCHMOD''@/$(GL_GNULIB_LCHMOD)/g' \
+ -e 's/@''GNULIB_LSTAT''@/$(GL_GNULIB_LSTAT)/g' \
+ -e 's/@''GNULIB_MKDIR''@/$(GL_GNULIB_MKDIR)/g' \
+ -e 's/@''GNULIB_MKDIRAT''@/$(GL_GNULIB_MKDIRAT)/g' \
+ -e 's/@''GNULIB_MKFIFO''@/$(GL_GNULIB_MKFIFO)/g' \
+ -e 's/@''GNULIB_MKFIFOAT''@/$(GL_GNULIB_MKFIFOAT)/g' \
+ -e 's/@''GNULIB_MKNOD''@/$(GL_GNULIB_MKNOD)/g' \
+ -e 's/@''GNULIB_MKNODAT''@/$(GL_GNULIB_MKNODAT)/g' \
+ -e 's/@''GNULIB_STAT''@/$(GL_GNULIB_STAT)/g' \
+ -e 's/@''GNULIB_UTIMENSAT''@/$(GL_GNULIB_UTIMENSAT)/g' \
+ -e 's/@''GNULIB_OVERRIDES_STRUCT_STAT''@/$(GL_GNULIB_OVERRIDES_STRUCT_STAT)/g' \
+ -e 's/@''GNULIB_MDA_CHMOD''@/$(GL_GNULIB_MDA_CHMOD)/g' \
+ -e 's/@''GNULIB_MDA_MKDIR''@/$(GL_GNULIB_MDA_MKDIR)/g' \
+ -e 's/@''GNULIB_MDA_UMASK''@/$(GL_GNULIB_MDA_UMASK)/g' \
-e 's|@''HAVE_FCHMODAT''@|$(HAVE_FCHMODAT)|g' \
-e 's|@''HAVE_FSTATAT''@|$(HAVE_FSTATAT)|g' \
-e 's|@''HAVE_FUTIMENS''@|$(HAVE_FUTIMENS)|g' \
@@ -3306,7 +3439,7 @@ sys/time.h: sys_time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_SYS_TIME_H''@|$(NEXT_SYS_TIME_H)|g' \
- -e 's/@''GNULIB_GETTIMEOFDAY''@/$(GNULIB_GETTIMEOFDAY)/g' \
+ -e 's/@''GNULIB_GETTIMEOFDAY''@/$(GL_GNULIB_GETTIMEOFDAY)/g' \
-e 's|@''HAVE_WINSOCK2_H''@|$(HAVE_WINSOCK2_H)|g' \
-e 's/@''HAVE_GETTIMEOFDAY''@/$(HAVE_GETTIMEOFDAY)/g' \
-e 's/@''HAVE_STRUCT_TIMEVAL''@/$(HAVE_STRUCT_TIMEVAL)/g' \
@@ -3378,18 +3511,18 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_TIME_H''@|$(NEXT_TIME_H)|g' \
- -e 's/@''GNULIB_CTIME''@/$(GNULIB_CTIME)/g' \
- -e 's/@''GNULIB_LOCALTIME''@/$(GNULIB_LOCALTIME)/g' \
- -e 's/@''GNULIB_MKTIME''@/$(GNULIB_MKTIME)/g' \
- -e 's/@''GNULIB_NANOSLEEP''@/$(GNULIB_NANOSLEEP)/g' \
- -e 's/@''GNULIB_STRFTIME''@/$(GNULIB_STRFTIME)/g' \
- -e 's/@''GNULIB_STRPTIME''@/$(GNULIB_STRPTIME)/g' \
- -e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \
- -e 's/@''GNULIB_TIMESPEC_GET''@/$(GNULIB_TIMESPEC_GET)/g' \
- -e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \
- -e 's/@''GNULIB_TIME_RZ''@/$(GNULIB_TIME_RZ)/g' \
- -e 's/@''GNULIB_TZSET''@/$(GNULIB_TZSET)/g' \
- -e 's/@''GNULIB_MDA_TZSET''@/$(GNULIB_MDA_TZSET)/g' \
+ -e 's/@''GNULIB_CTIME''@/$(GL_GNULIB_CTIME)/g' \
+ -e 's/@''GNULIB_LOCALTIME''@/$(GL_GNULIB_LOCALTIME)/g' \
+ -e 's/@''GNULIB_MKTIME''@/$(GL_GNULIB_MKTIME)/g' \
+ -e 's/@''GNULIB_NANOSLEEP''@/$(GL_GNULIB_NANOSLEEP)/g' \
+ -e 's/@''GNULIB_STRFTIME''@/$(GL_GNULIB_STRFTIME)/g' \
+ -e 's/@''GNULIB_STRPTIME''@/$(GL_GNULIB_STRPTIME)/g' \
+ -e 's/@''GNULIB_TIMEGM''@/$(GL_GNULIB_TIMEGM)/g' \
+ -e 's/@''GNULIB_TIMESPEC_GET''@/$(GL_GNULIB_TIMESPEC_GET)/g' \
+ -e 's/@''GNULIB_TIME_R''@/$(GL_GNULIB_TIME_R)/g' \
+ -e 's/@''GNULIB_TIME_RZ''@/$(GL_GNULIB_TIME_RZ)/g' \
+ -e 's/@''GNULIB_TZSET''@/$(GL_GNULIB_TZSET)/g' \
+ -e 's/@''GNULIB_MDA_TZSET''@/$(GL_GNULIB_MDA_TZSET)/g' \
-e 's|@''HAVE_DECL_LOCALTIME_R''@|$(HAVE_DECL_LOCALTIME_R)|g' \
-e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \
-e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \
@@ -3510,89 +3643,89 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \
-e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \
- -e 's/@''GNULIB_ACCESS''@/$(GNULIB_ACCESS)/g' \
- -e 's/@''GNULIB_CHDIR''@/$(GNULIB_CHDIR)/g' \
- -e 's/@''GNULIB_CHOWN''@/$(GNULIB_CHOWN)/g' \
- -e 's/@''GNULIB_CLOSE''@/$(GNULIB_CLOSE)/g' \
- -e 's/@''GNULIB_COPY_FILE_RANGE''@/$(GNULIB_COPY_FILE_RANGE)/g' \
- -e 's/@''GNULIB_DUP''@/$(GNULIB_DUP)/g' \
- -e 's/@''GNULIB_DUP2''@/$(GNULIB_DUP2)/g' \
- -e 's/@''GNULIB_DUP3''@/$(GNULIB_DUP3)/g' \
- -e 's/@''GNULIB_ENVIRON''@/$(GNULIB_ENVIRON)/g' \
- -e 's/@''GNULIB_EUIDACCESS''@/$(GNULIB_EUIDACCESS)/g' \
- -e 's/@''GNULIB_EXECL''@/$(GNULIB_EXECL)/g' \
- -e 's/@''GNULIB_EXECLE''@/$(GNULIB_EXECLE)/g' \
- -e 's/@''GNULIB_EXECLP''@/$(GNULIB_EXECLP)/g' \
- -e 's/@''GNULIB_EXECV''@/$(GNULIB_EXECV)/g' \
- -e 's/@''GNULIB_EXECVE''@/$(GNULIB_EXECVE)/g' \
- -e 's/@''GNULIB_EXECVP''@/$(GNULIB_EXECVP)/g' \
- -e 's/@''GNULIB_EXECVPE''@/$(GNULIB_EXECVPE)/g' \
- -e 's/@''GNULIB_FACCESSAT''@/$(GNULIB_FACCESSAT)/g' \
- -e 's/@''GNULIB_FCHDIR''@/$(GNULIB_FCHDIR)/g' \
- -e 's/@''GNULIB_FCHOWNAT''@/$(GNULIB_FCHOWNAT)/g' \
- -e 's/@''GNULIB_FDATASYNC''@/$(GNULIB_FDATASYNC)/g' \
- -e 's/@''GNULIB_FSYNC''@/$(GNULIB_FSYNC)/g' \
- -e 's/@''GNULIB_FTRUNCATE''@/$(GNULIB_FTRUNCATE)/g' \
- -e 's/@''GNULIB_GETCWD''@/$(GNULIB_GETCWD)/g' \
- -e 's/@''GNULIB_GETDOMAINNAME''@/$(GNULIB_GETDOMAINNAME)/g' \
- -e 's/@''GNULIB_GETDTABLESIZE''@/$(GNULIB_GETDTABLESIZE)/g' \
- -e 's/@''GNULIB_GETENTROPY''@/$(GNULIB_GETENTROPY)/g' \
- -e 's/@''GNULIB_GETGROUPS''@/$(GNULIB_GETGROUPS)/g' \
- -e 's/@''GNULIB_GETHOSTNAME''@/$(GNULIB_GETHOSTNAME)/g' \
- -e 's/@''GNULIB_GETLOGIN''@/$(GNULIB_GETLOGIN)/g' \
- -e 's/@''GNULIB_GETLOGIN_R''@/$(GNULIB_GETLOGIN_R)/g' \
- -e 's/@''GNULIB_GETOPT_POSIX''@/$(GNULIB_GETOPT_POSIX)/g' \
- -e 's/@''GNULIB_GETPAGESIZE''@/$(GNULIB_GETPAGESIZE)/g' \
- -e 's/@''GNULIB_GETPASS''@/$(GNULIB_GETPASS)/g' \
- -e 's/@''GNULIB_GETUSERSHELL''@/$(GNULIB_GETUSERSHELL)/g' \
- -e 's/@''GNULIB_GROUP_MEMBER''@/$(GNULIB_GROUP_MEMBER)/g' \
- -e 's/@''GNULIB_ISATTY''@/$(GNULIB_ISATTY)/g' \
- -e 's/@''GNULIB_LCHOWN''@/$(GNULIB_LCHOWN)/g' \
- -e 's/@''GNULIB_LINK''@/$(GNULIB_LINK)/g' \
- -e 's/@''GNULIB_LINKAT''@/$(GNULIB_LINKAT)/g' \
- -e 's/@''GNULIB_LSEEK''@/$(GNULIB_LSEEK)/g' \
- -e 's/@''GNULIB_PIPE''@/$(GNULIB_PIPE)/g' \
- -e 's/@''GNULIB_PIPE2''@/$(GNULIB_PIPE2)/g' \
- -e 's/@''GNULIB_PREAD''@/$(GNULIB_PREAD)/g' \
- -e 's/@''GNULIB_PWRITE''@/$(GNULIB_PWRITE)/g' \
- -e 's/@''GNULIB_READ''@/$(GNULIB_READ)/g' \
- -e 's/@''GNULIB_READLINK''@/$(GNULIB_READLINK)/g' \
- -e 's/@''GNULIB_READLINKAT''@/$(GNULIB_READLINKAT)/g' \
- -e 's/@''GNULIB_RMDIR''@/$(GNULIB_RMDIR)/g' \
- -e 's/@''GNULIB_SETHOSTNAME''@/$(GNULIB_SETHOSTNAME)/g' \
- -e 's/@''GNULIB_SLEEP''@/$(GNULIB_SLEEP)/g' \
- -e 's/@''GNULIB_SYMLINK''@/$(GNULIB_SYMLINK)/g' \
- -e 's/@''GNULIB_SYMLINKAT''@/$(GNULIB_SYMLINKAT)/g' \
- -e 's/@''GNULIB_TRUNCATE''@/$(GNULIB_TRUNCATE)/g' \
- -e 's/@''GNULIB_TTYNAME_R''@/$(GNULIB_TTYNAME_R)/g' \
- -e 's/@''GNULIB_UNISTD_H_GETOPT''@/0$(GNULIB_GL_UNISTD_H_GETOPT)/g' \
- -e 's/@''GNULIB_UNISTD_H_NONBLOCKING''@/$(GNULIB_UNISTD_H_NONBLOCKING)/g' \
- -e 's/@''GNULIB_UNISTD_H_SIGPIPE''@/$(GNULIB_UNISTD_H_SIGPIPE)/g' \
- -e 's/@''GNULIB_UNLINK''@/$(GNULIB_UNLINK)/g' \
- -e 's/@''GNULIB_UNLINKAT''@/$(GNULIB_UNLINKAT)/g' \
- -e 's/@''GNULIB_USLEEP''@/$(GNULIB_USLEEP)/g' \
- -e 's/@''GNULIB_WRITE''@/$(GNULIB_WRITE)/g' \
- -e 's/@''GNULIB_MDA_ACCESS''@/$(GNULIB_MDA_ACCESS)/g' \
- -e 's/@''GNULIB_MDA_CHDIR''@/$(GNULIB_MDA_CHDIR)/g' \
- -e 's/@''GNULIB_MDA_CLOSE''@/$(GNULIB_MDA_CLOSE)/g' \
- -e 's/@''GNULIB_MDA_DUP''@/$(GNULIB_MDA_DUP)/g' \
- -e 's/@''GNULIB_MDA_DUP2''@/$(GNULIB_MDA_DUP2)/g' \
- -e 's/@''GNULIB_MDA_EXECL''@/$(GNULIB_MDA_EXECL)/g' \
- -e 's/@''GNULIB_MDA_EXECLE''@/$(GNULIB_MDA_EXECLE)/g' \
- -e 's/@''GNULIB_MDA_EXECLP''@/$(GNULIB_MDA_EXECLP)/g' \
- -e 's/@''GNULIB_MDA_EXECV''@/$(GNULIB_MDA_EXECV)/g' \
- -e 's/@''GNULIB_MDA_EXECVE''@/$(GNULIB_MDA_EXECVE)/g' \
- -e 's/@''GNULIB_MDA_EXECVP''@/$(GNULIB_MDA_EXECVP)/g' \
- -e 's/@''GNULIB_MDA_EXECVPE''@/$(GNULIB_MDA_EXECVPE)/g' \
- -e 's/@''GNULIB_MDA_GETCWD''@/$(GNULIB_MDA_GETCWD)/g' \
- -e 's/@''GNULIB_MDA_GETPID''@/$(GNULIB_MDA_GETPID)/g' \
- -e 's/@''GNULIB_MDA_ISATTY''@/$(GNULIB_MDA_ISATTY)/g' \
- -e 's/@''GNULIB_MDA_LSEEK''@/$(GNULIB_MDA_LSEEK)/g' \
- -e 's/@''GNULIB_MDA_READ''@/$(GNULIB_MDA_READ)/g' \
- -e 's/@''GNULIB_MDA_RMDIR''@/$(GNULIB_MDA_RMDIR)/g' \
- -e 's/@''GNULIB_MDA_SWAB''@/$(GNULIB_MDA_SWAB)/g' \
- -e 's/@''GNULIB_MDA_UNLINK''@/$(GNULIB_MDA_UNLINK)/g' \
- -e 's/@''GNULIB_MDA_WRITE''@/$(GNULIB_MDA_WRITE)/g' \
+ -e 's/@''GNULIB_ACCESS''@/$(GL_GNULIB_ACCESS)/g' \
+ -e 's/@''GNULIB_CHDIR''@/$(GL_GNULIB_CHDIR)/g' \
+ -e 's/@''GNULIB_CHOWN''@/$(GL_GNULIB_CHOWN)/g' \
+ -e 's/@''GNULIB_CLOSE''@/$(GL_GNULIB_CLOSE)/g' \
+ -e 's/@''GNULIB_COPY_FILE_RANGE''@/$(GL_GNULIB_COPY_FILE_RANGE)/g' \
+ -e 's/@''GNULIB_DUP''@/$(GL_GNULIB_DUP)/g' \
+ -e 's/@''GNULIB_DUP2''@/$(GL_GNULIB_DUP2)/g' \
+ -e 's/@''GNULIB_DUP3''@/$(GL_GNULIB_DUP3)/g' \
+ -e 's/@''GNULIB_ENVIRON''@/$(GL_GNULIB_ENVIRON)/g' \
+ -e 's/@''GNULIB_EUIDACCESS''@/$(GL_GNULIB_EUIDACCESS)/g' \
+ -e 's/@''GNULIB_EXECL''@/$(GL_GNULIB_EXECL)/g' \
+ -e 's/@''GNULIB_EXECLE''@/$(GL_GNULIB_EXECLE)/g' \
+ -e 's/@''GNULIB_EXECLP''@/$(GL_GNULIB_EXECLP)/g' \
+ -e 's/@''GNULIB_EXECV''@/$(GL_GNULIB_EXECV)/g' \
+ -e 's/@''GNULIB_EXECVE''@/$(GL_GNULIB_EXECVE)/g' \
+ -e 's/@''GNULIB_EXECVP''@/$(GL_GNULIB_EXECVP)/g' \
+ -e 's/@''GNULIB_EXECVPE''@/$(GL_GNULIB_EXECVPE)/g' \
+ -e 's/@''GNULIB_FACCESSAT''@/$(GL_GNULIB_FACCESSAT)/g' \
+ -e 's/@''GNULIB_FCHDIR''@/$(GL_GNULIB_FCHDIR)/g' \
+ -e 's/@''GNULIB_FCHOWNAT''@/$(GL_GNULIB_FCHOWNAT)/g' \
+ -e 's/@''GNULIB_FDATASYNC''@/$(GL_GNULIB_FDATASYNC)/g' \
+ -e 's/@''GNULIB_FSYNC''@/$(GL_GNULIB_FSYNC)/g' \
+ -e 's/@''GNULIB_FTRUNCATE''@/$(GL_GNULIB_FTRUNCATE)/g' \
+ -e 's/@''GNULIB_GETCWD''@/$(GL_GNULIB_GETCWD)/g' \
+ -e 's/@''GNULIB_GETDOMAINNAME''@/$(GL_GNULIB_GETDOMAINNAME)/g' \
+ -e 's/@''GNULIB_GETDTABLESIZE''@/$(GL_GNULIB_GETDTABLESIZE)/g' \
+ -e 's/@''GNULIB_GETENTROPY''@/$(GL_GNULIB_GETENTROPY)/g' \
+ -e 's/@''GNULIB_GETGROUPS''@/$(GL_GNULIB_GETGROUPS)/g' \
+ -e 's/@''GNULIB_GETHOSTNAME''@/$(GL_GNULIB_GETHOSTNAME)/g' \
+ -e 's/@''GNULIB_GETLOGIN''@/$(GL_GNULIB_GETLOGIN)/g' \
+ -e 's/@''GNULIB_GETLOGIN_R''@/$(GL_GNULIB_GETLOGIN_R)/g' \
+ -e 's/@''GNULIB_GETOPT_POSIX''@/$(GL_GNULIB_GETOPT_POSIX)/g' \
+ -e 's/@''GNULIB_GETPAGESIZE''@/$(GL_GNULIB_GETPAGESIZE)/g' \
+ -e 's/@''GNULIB_GETPASS''@/$(GL_GNULIB_GETPASS)/g' \
+ -e 's/@''GNULIB_GETUSERSHELL''@/$(GL_GNULIB_GETUSERSHELL)/g' \
+ -e 's/@''GNULIB_GROUP_MEMBER''@/$(GL_GNULIB_GROUP_MEMBER)/g' \
+ -e 's/@''GNULIB_ISATTY''@/$(GL_GNULIB_ISATTY)/g' \
+ -e 's/@''GNULIB_LCHOWN''@/$(GL_GNULIB_LCHOWN)/g' \
+ -e 's/@''GNULIB_LINK''@/$(GL_GNULIB_LINK)/g' \
+ -e 's/@''GNULIB_LINKAT''@/$(GL_GNULIB_LINKAT)/g' \
+ -e 's/@''GNULIB_LSEEK''@/$(GL_GNULIB_LSEEK)/g' \
+ -e 's/@''GNULIB_PIPE''@/$(GL_GNULIB_PIPE)/g' \
+ -e 's/@''GNULIB_PIPE2''@/$(GL_GNULIB_PIPE2)/g' \
+ -e 's/@''GNULIB_PREAD''@/$(GL_GNULIB_PREAD)/g' \
+ -e 's/@''GNULIB_PWRITE''@/$(GL_GNULIB_PWRITE)/g' \
+ -e 's/@''GNULIB_READ''@/$(GL_GNULIB_READ)/g' \
+ -e 's/@''GNULIB_READLINK''@/$(GL_GNULIB_READLINK)/g' \
+ -e 's/@''GNULIB_READLINKAT''@/$(GL_GNULIB_READLINKAT)/g' \
+ -e 's/@''GNULIB_RMDIR''@/$(GL_GNULIB_RMDIR)/g' \
+ -e 's/@''GNULIB_SETHOSTNAME''@/$(GL_GNULIB_SETHOSTNAME)/g' \
+ -e 's/@''GNULIB_SLEEP''@/$(GL_GNULIB_SLEEP)/g' \
+ -e 's/@''GNULIB_SYMLINK''@/$(GL_GNULIB_SYMLINK)/g' \
+ -e 's/@''GNULIB_SYMLINKAT''@/$(GL_GNULIB_SYMLINKAT)/g' \
+ -e 's/@''GNULIB_TRUNCATE''@/$(GL_GNULIB_TRUNCATE)/g' \
+ -e 's/@''GNULIB_TTYNAME_R''@/$(GL_GNULIB_TTYNAME_R)/g' \
+ -e 's/@''GNULIB_UNISTD_H_GETOPT''@/0$(GL_GNULIB_UNISTD_H_GETOPT)/g' \
+ -e 's/@''GNULIB_UNISTD_H_NONBLOCKING''@/$(GL_GNULIB_UNISTD_H_NONBLOCKING)/g' \
+ -e 's/@''GNULIB_UNISTD_H_SIGPIPE''@/$(GL_GNULIB_UNISTD_H_SIGPIPE)/g' \
+ -e 's/@''GNULIB_UNLINK''@/$(GL_GNULIB_UNLINK)/g' \
+ -e 's/@''GNULIB_UNLINKAT''@/$(GL_GNULIB_UNLINKAT)/g' \
+ -e 's/@''GNULIB_USLEEP''@/$(GL_GNULIB_USLEEP)/g' \
+ -e 's/@''GNULIB_WRITE''@/$(GL_GNULIB_WRITE)/g' \
+ -e 's/@''GNULIB_MDA_ACCESS''@/$(GL_GNULIB_MDA_ACCESS)/g' \
+ -e 's/@''GNULIB_MDA_CHDIR''@/$(GL_GNULIB_MDA_CHDIR)/g' \
+ -e 's/@''GNULIB_MDA_CLOSE''@/$(GL_GNULIB_MDA_CLOSE)/g' \
+ -e 's/@''GNULIB_MDA_DUP''@/$(GL_GNULIB_MDA_DUP)/g' \
+ -e 's/@''GNULIB_MDA_DUP2''@/$(GL_GNULIB_MDA_DUP2)/g' \
+ -e 's/@''GNULIB_MDA_EXECL''@/$(GL_GNULIB_MDA_EXECL)/g' \
+ -e 's/@''GNULIB_MDA_EXECLE''@/$(GL_GNULIB_MDA_EXECLE)/g' \
+ -e 's/@''GNULIB_MDA_EXECLP''@/$(GL_GNULIB_MDA_EXECLP)/g' \
+ -e 's/@''GNULIB_MDA_EXECV''@/$(GL_GNULIB_MDA_EXECV)/g' \
+ -e 's/@''GNULIB_MDA_EXECVE''@/$(GL_GNULIB_MDA_EXECVE)/g' \
+ -e 's/@''GNULIB_MDA_EXECVP''@/$(GL_GNULIB_MDA_EXECVP)/g' \
+ -e 's/@''GNULIB_MDA_EXECVPE''@/$(GL_GNULIB_MDA_EXECVPE)/g' \
+ -e 's/@''GNULIB_MDA_GETCWD''@/$(GL_GNULIB_MDA_GETCWD)/g' \
+ -e 's/@''GNULIB_MDA_GETPID''@/$(GL_GNULIB_MDA_GETPID)/g' \
+ -e 's/@''GNULIB_MDA_ISATTY''@/$(GL_GNULIB_MDA_ISATTY)/g' \
+ -e 's/@''GNULIB_MDA_LSEEK''@/$(GL_GNULIB_MDA_LSEEK)/g' \
+ -e 's/@''GNULIB_MDA_READ''@/$(GL_GNULIB_MDA_READ)/g' \
+ -e 's/@''GNULIB_MDA_RMDIR''@/$(GL_GNULIB_MDA_RMDIR)/g' \
+ -e 's/@''GNULIB_MDA_SWAB''@/$(GL_GNULIB_MDA_SWAB)/g' \
+ -e 's/@''GNULIB_MDA_UNLINK''@/$(GL_GNULIB_MDA_UNLINK)/g' \
+ -e 's/@''GNULIB_MDA_WRITE''@/$(GL_GNULIB_MDA_WRITE)/g' \
< $(srcdir)/unistd.in.h | \
sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \
-e 's|@''HAVE_COPY_FILE_RANGE''@|$(HAVE_COPY_FILE_RANGE)|g' \
@@ -3699,14 +3832,14 @@ EXTRA_DIST += unistd.in.h
endif
## end gnulib module unistd
-## begin gnulib module unlocked-io
-ifeq (,$(OMIT_GNULIB_MODULE_unlocked-io))
+## begin gnulib module unlocked-io-internal
+ifeq (,$(OMIT_GNULIB_MODULE_unlocked-io-internal))
EXTRA_DIST += unlocked-io.h
endif
-## end gnulib module unlocked-io
+## end gnulib module unlocked-io-internal
## begin gnulib module update-copyright
ifeq (,$(OMIT_GNULIB_MODULE_update-copyright))
diff --git a/lib/group-member.c b/lib/group-member.c
index 52159016eab..24aea3599c5 100644
--- a/lib/group-member.c
+++ b/lib/group-member.c
@@ -3,17 +3,17 @@
Copyright (C) 1994, 1997-1998, 2003, 2005-2006, 2009-2021 Free Software
Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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 <config.h>
@@ -25,7 +25,7 @@
#include <sys/types.h>
#include <stdlib.h>
-#include "xalloc-oversized.h"
+#include "intprops.h"
/* Most processes have no more than this many groups, and for these
processes we can avoid using malloc. */
@@ -53,10 +53,10 @@ get_group_info (struct group_info *gi)
if (n_groups < 0)
{
int n_group_slots = getgroups (0, NULL);
- if (0 <= n_group_slots
- && ! xalloc_oversized (n_group_slots, sizeof *gi->group))
+ size_t nbytes;
+ if (! INT_MULTIPLY_WRAPV (n_group_slots, sizeof *gi->group, &nbytes))
{
- gi->group = malloc (n_group_slots * sizeof *gi->group);
+ gi->group = malloc (nbytes);
if (gi->group)
n_groups = getgroups (n_group_slots, gi->group);
}
diff --git a/lib/idx.h b/lib/idx.h
index 681c8c90f10..54ad5d81fe1 100644
--- a/lib/idx.h
+++ b/lib/idx.h
@@ -3,16 +3,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
@@ -56,6 +56,26 @@
* Because 'size_t' is an unsigned type, and a signed type is better.
See above.
+ Why not use 'ssize_t'?
+
+ * 'ptrdiff_t' is more portable; it is standardized by ISO C
+ whereas 'ssize_t' is standardized only by POSIX.
+
+ * 'ssize_t' is not required to be as wide as 'size_t', and some
+ now-obsolete POSIX platforms had 'size_t' wider than 'ssize_t'.
+
+ * Conversely, some now-obsolete platforms had 'ptrdiff_t' wider
+ than 'size_t', which can be a win and conforms to POSIX.
+
+ Won't this cause a problem with objects larger than PTRDIFF_MAX?
+
+ * Typical modern or large platforms do not allocate such objects,
+ so this is not much of a problem in practice; for example, you
+ can safely write 'idx_t len = strlen (s);'. To port to older
+ small platforms where allocations larger than PTRDIFF_MAX could
+ in theory be a problem, you can use Gnulib's ialloc module, or
+ functions like ximalloc in Gnulib's xalloc module.
+
Why not use 'ptrdiff_t' directly?
* Maintainability: When reading and modifying code, it helps to know that
diff --git a/lib/ieee754.in.h b/lib/ieee754.in.h
index ce13efc918d..ce371cbcea3 100644
--- a/lib/ieee754.in.h
+++ b/lib/ieee754.in.h
@@ -2,16 +2,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/ignore-value.h b/lib/ignore-value.h
index 0a3cf1e95b4..6099abad97b 100644
--- a/lib/ignore-value.h
+++ b/lib/ignore-value.h
@@ -2,17 +2,17 @@
Copyright (C) 2008-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Jim Meyering, Eric Blake and Pádraig Brady. */
diff --git a/lib/intprops.h b/lib/intprops.h
index 2a420ac8319..3fe64e82e9f 100644
--- a/lib/intprops.h
+++ b/lib/intprops.h
@@ -3,19 +3,18 @@
Copyright (C) 2001-2021 Free Software Foundation, Inc.
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
+ 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 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.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
-/* Written by Paul Eggert. */
#ifndef _GL_INTPROPS_H
#define _GL_INTPROPS_H
@@ -133,7 +132,8 @@
operators might not yield numerically correct answers due to
arithmetic overflow. They do not rely on undefined or
implementation-defined behavior. Their implementations are simple
- and straightforward, but they are a bit harder to use than the
+ and straightforward, but they are harder to use and may be less
+ efficient than the INT_<op>_WRAPV, INT_<op>_OK, and
INT_<op>_OVERFLOW macros described below.
Example usage:
@@ -158,6 +158,9 @@
must have minimum value MIN and maximum MAX. Unsigned types should
use a zero MIN of the proper type.
+ Because all arguments are subject to integer promotions, these
+ macros typically do not work on types narrower than 'int'.
+
These macros are tuned for constant MIN and MAX. For commutative
operations such as A + B, they are also tuned for constant B. */
@@ -339,9 +342,15 @@
arguments should not have side effects.
The WRAPV macros are not constant expressions. They support only
- +, binary -, and *. Because the WRAPV macros convert the result,
- they report overflow in different circumstances than the OVERFLOW
- macros do.
+ +, binary -, and *.
+
+ Because the WRAPV macros convert the result, they report overflow
+ in different circumstances than the OVERFLOW macros do. For
+ example, in the typical case with 16-bit 'short' and 32-bit 'int',
+ if A, B and R are all of type 'short' then INT_ADD_OVERFLOW (A, B)
+ returns false because the addition cannot overflow after A and B
+ are converted to 'int', whereas INT_ADD_WRAPV (A, B, &R) returns
+ true or false depending on whether the sum fits into 'short'.
These macros are tuned for their last input argument being a constant.
diff --git a/lib/inttypes.in.h b/lib/inttypes.in.h
index e9ee500e3e6..41cb4220ce6 100644
--- a/lib/inttypes.in.h
+++ b/lib/inttypes.in.h
@@ -2,17 +2,17 @@
Written by Paul Eggert, Bruno Haible, Derek Price.
This file is part of gnulib.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/*
diff --git a/lib/libc-config.h b/lib/libc-config.h
index c0eac707cfd..886c11f37f1 100644
--- a/lib/libc-config.h
+++ b/lib/libc-config.h
@@ -3,16 +3,16 @@
Copyright 2017-2021 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ 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/>. */
@@ -28,14 +28,17 @@
When compiled as part of glibc this is a no-op; when compiled as
part of Gnulib this includes Gnulib's <config.h> and defines macros
- that glibc library code would normally assume. */
+ that glibc library code would normally assume.
+
+ Note: This header file MUST NOT be included by public header files
+ of Gnulib. */
#include <config.h>
/* On glibc this includes <features.h> and <sys/cdefs.h> and #defines
- _FEATURES_H, __WORDSIZE, and __set_errno. On FreeBSD 11 it
- includes <sys/cdefs.h> which defines __nonnull. Elsewhere it
- is harmless. */
+ _FEATURES_H, __WORDSIZE, and __set_errno. On FreeBSD 11 and
+ DragonFlyBSD 5.9 it includes <sys/cdefs.h> which defines __nonnull.
+ Elsewhere it is harmless. */
#include <errno.h>
/* From glibc <errno.h>. */
@@ -71,7 +74,7 @@
# endif
#endif
-#ifndef __attribute_maybe_unused__
+#ifndef __attribute_nonnull__
/* <sys/cdefs.h> either does not exist, or is too old for Gnulib.
Prepare to include <cdefs.h>, which is Gnulib's version of a
more-recent glibc <sys/cdefs.h>. */
@@ -80,13 +83,9 @@
# ifndef _FEATURES_H
# define _FEATURES_H 1
# endif
-/* Define __WORDSIZE so that <cdefs.h> does not attempt to include
- nonexistent files. Make it a syntax error, since Gnulib does not
- use __WORDSIZE now, and if Gnulib uses it later the syntax error
- will let us know that __WORDSIZE needs configuring. */
-# ifndef __WORDSIZE
-# define __WORDSIZE %%%
-# endif
+/* Define __GNULIB_CDEFS so that <cdefs.h> does not attempt to include
+ nonexistent files. */
+# define __GNULIB_CDEFS
/* Undef the macros unconditionally defined by our copy of glibc
<sys/cdefs.h>, so that they do not clash with any system-defined
versions. */
@@ -118,6 +117,9 @@
# undef __THROW
# undef __THROWNL
# undef __attr_access
+# undef __attr_access_none
+# undef __attr_dealloc
+# undef __attr_dealloc_free
# undef __attribute__
# undef __attribute_alloc_size__
# undef __attribute_artificial__
diff --git a/lib/limits.in.h b/lib/limits.in.h
index 076ab9ef548..2ecafebb006 100644
--- a/lib/limits.in.h
+++ b/lib/limits.in.h
@@ -2,18 +2,18 @@
Copyright 2016-2021 Free Software Foundation, Inc.
- 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, or
- (at your option) any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
#if __GNUC__ >= 3
@PRAGMA_SYSTEM_HEADER@
@@ -99,10 +99,11 @@
# endif
#endif
-/* Macros specified by ISO/IEC TS 18661-1:2014. */
+/* Macros specified by C2x and by ISO/IEC TS 18661-1:2014. */
#if (! defined ULLONG_WIDTH \
- && (defined _GNU_SOURCE || defined __STDC_WANT_IEC_60559_BFP_EXT__))
+ && (defined _GNU_SOURCE || defined __STDC_WANT_IEC_60559_BFP_EXT__ \
+ || (defined __STDC_VERSION__ && 201710 < __STDC_VERSION__)))
# define CHAR_WIDTH _GL_INTEGER_WIDTH (CHAR_MIN, CHAR_MAX)
# define SCHAR_WIDTH _GL_INTEGER_WIDTH (SCHAR_MIN, SCHAR_MAX)
# define UCHAR_WIDTH _GL_INTEGER_WIDTH (0, UCHAR_MAX)
@@ -114,7 +115,16 @@
# define ULONG_WIDTH _GL_INTEGER_WIDTH (0, ULONG_MAX)
# define LLONG_WIDTH _GL_INTEGER_WIDTH (LLONG_MIN, LLONG_MAX)
# define ULLONG_WIDTH _GL_INTEGER_WIDTH (0, ULLONG_MAX)
-#endif /* !ULLONG_WIDTH && (_GNU_SOURCE || __STDC_WANT_IEC_60559_BFP_EXT__) */
+#endif
+
+/* Macros specified by C2x. */
+
+#if (! defined BOOL_WIDTH \
+ && (defined _GNU_SOURCE \
+ || (defined __STDC_VERSION__ && 201710 < __STDC_VERSION__)))
+# define BOOL_MAX 1
+# define BOOL_WIDTH 1
+#endif
#endif /* _@GUARD_PREFIX@_LIMITS_H */
#endif /* _@GUARD_PREFIX@_LIMITS_H */
diff --git a/lib/lstat.c b/lib/lstat.c
index a584c6aa069..7de0bf10278 100644
--- a/lib/lstat.c
+++ b/lib/lstat.c
@@ -2,17 +2,17 @@
Copyright (C) 1997-2006, 2008-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* written by Jim Meyering */
diff --git a/lib/malloc.c b/lib/malloc.c
new file mode 100644
index 00000000000..0d8b3596caf
--- /dev/null
+++ b/lib/malloc.c
@@ -0,0 +1,51 @@
+/* malloc() function that is glibc compatible.
+
+ Copyright (C) 1997-1998, 2006-2007, 2009-2021 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/>. */
+
+/* written by Jim Meyering and Bruno Haible */
+
+#define _GL_USE_STDLIB_ALLOC 1
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <errno.h>
+
+#include "xalloc-oversized.h"
+
+/* Allocate an N-byte block of memory from the heap, even if N is 0. */
+
+void *
+rpl_malloc (size_t n)
+{
+ if (n == 0)
+ n = 1;
+
+ if (xalloc_oversized (n, 1))
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ void *result = malloc (n);
+
+#if !HAVE_MALLOC_POSIX
+ if (result == NULL)
+ errno = ENOMEM;
+#endif
+
+ return result;
+}
diff --git a/lib/malloc/dynarray-skeleton.c b/lib/malloc/dynarray-skeleton.c
index 4995fd1c049..48210e32527 100644
--- a/lib/malloc/dynarray-skeleton.c
+++ b/lib/malloc/dynarray-skeleton.c
@@ -3,16 +3,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
@@ -192,7 +192,7 @@ DYNARRAY_NAME (free__array__) (struct DYNARRAY_STRUCT *list)
/* Initialize a dynamic array object. This must be called before any
use of the object. */
-__nonnull ((1))
+__attribute_nonnull__ ((1))
static void
DYNARRAY_NAME (init) (struct DYNARRAY_STRUCT *list)
{
@@ -202,7 +202,7 @@ DYNARRAY_NAME (init) (struct DYNARRAY_STRUCT *list)
}
/* Deallocate the dynamic array and its elements. */
-__attribute_maybe_unused__ __nonnull ((1))
+__attribute_maybe_unused__ __attribute_nonnull__ ((1))
static void
DYNARRAY_FREE (struct DYNARRAY_STRUCT *list)
{
@@ -213,7 +213,7 @@ DYNARRAY_FREE (struct DYNARRAY_STRUCT *list)
}
/* Return true if the dynamic array is in an error state. */
-__nonnull ((1))
+__attribute_nonnull__ ((1))
static inline bool
DYNARRAY_NAME (has_failed) (const struct DYNARRAY_STRUCT *list)
{
@@ -222,7 +222,7 @@ DYNARRAY_NAME (has_failed) (const struct DYNARRAY_STRUCT *list)
/* Mark the dynamic array as failed. All elements are deallocated as
a side effect. */
-__nonnull ((1))
+__attribute_nonnull__ ((1))
static void
DYNARRAY_NAME (mark_failed) (struct DYNARRAY_STRUCT *list)
{
@@ -236,7 +236,7 @@ DYNARRAY_NAME (mark_failed) (struct DYNARRAY_STRUCT *list)
/* Return the number of elements which have been added to the dynamic
array. */
-__nonnull ((1))
+__attribute_nonnull__ ((1))
static inline size_t
DYNARRAY_NAME (size) (const struct DYNARRAY_STRUCT *list)
{
@@ -245,7 +245,7 @@ DYNARRAY_NAME (size) (const struct DYNARRAY_STRUCT *list)
/* Return a pointer to the array element at INDEX. Terminate the
process if INDEX is out of bounds. */
-__nonnull ((1))
+__attribute_nonnull__ ((1))
static inline DYNARRAY_ELEMENT *
DYNARRAY_NAME (at) (struct DYNARRAY_STRUCT *list, size_t index)
{
@@ -257,7 +257,7 @@ DYNARRAY_NAME (at) (struct DYNARRAY_STRUCT *list, size_t index)
/* Return a pointer to the first array element, if any. For a
zero-length array, the pointer can be NULL even though the dynamic
array has not entered the failure state. */
-__nonnull ((1))
+__attribute_nonnull__ ((1))
static inline DYNARRAY_ELEMENT *
DYNARRAY_NAME (begin) (struct DYNARRAY_STRUCT *list)
{
@@ -267,7 +267,7 @@ DYNARRAY_NAME (begin) (struct DYNARRAY_STRUCT *list)
/* Return a pointer one element past the last array element. For a
zero-length array, the pointer can be NULL even though the dynamic
array has not entered the failure state. */
-__nonnull ((1))
+__attribute_nonnull__ ((1))
static inline DYNARRAY_ELEMENT *
DYNARRAY_NAME (end) (struct DYNARRAY_STRUCT *list)
{
@@ -294,7 +294,7 @@ DYNARRAY_NAME (add__) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
/* Add ITEM at the end of the array, enlarging it by one element.
Mark *LIST as failed if the dynamic array allocation size cannot be
increased. */
-__nonnull ((1))
+__attribute_nonnull__ ((1))
static inline void
DYNARRAY_NAME (add) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
{
@@ -348,7 +348,8 @@ DYNARRAY_NAME (emplace__) (struct DYNARRAY_STRUCT *list)
/* Allocate a place for a new element in *LIST and return a pointer to
it. The pointer can be NULL if the dynamic array cannot be
enlarged due to a memory allocation failure. */
-__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1))
+__attribute_maybe_unused__ __attribute_warn_unused_result__
+__attribute_nonnull__ ((1))
static
/* Avoid inlining with the larger initialization code. */
#if !(defined (DYNARRAY_ELEMENT_INIT) || defined (DYNARRAY_ELEMENT_FREE))
@@ -372,7 +373,7 @@ DYNARRAY_NAME (emplace) (struct DYNARRAY_STRUCT *list)
existing size, new elements are added (which can be initialized).
Otherwise, the list is truncated, and elements are freed. Return
false on memory allocation failure (and mark *LIST as failed). */
-__attribute_maybe_unused__ __nonnull ((1))
+__attribute_maybe_unused__ __attribute_nonnull__ ((1))
static bool
DYNARRAY_NAME (resize) (struct DYNARRAY_STRUCT *list, size_t size)
{
@@ -417,7 +418,7 @@ DYNARRAY_NAME (resize) (struct DYNARRAY_STRUCT *list, size_t size)
}
/* Remove the last element of LIST if it is present. */
-__attribute_maybe_unused__ __nonnull ((1))
+__attribute_maybe_unused__ __attribute_nonnull__ ((1))
static void
DYNARRAY_NAME (remove_last) (struct DYNARRAY_STRUCT *list)
{
@@ -434,7 +435,7 @@ DYNARRAY_NAME (remove_last) (struct DYNARRAY_STRUCT *list)
/* Remove all elements from the list. The elements are freed, but the
list itself is not. */
-__attribute_maybe_unused__ __nonnull ((1))
+__attribute_maybe_unused__ __attribute_nonnull__ ((1))
static void
DYNARRAY_NAME (clear) (struct DYNARRAY_STRUCT *list)
{
@@ -452,7 +453,8 @@ DYNARRAY_NAME (clear) (struct DYNARRAY_STRUCT *list)
stored in *RESULT if LIST refers to an empty list. On success, the
pointer in *RESULT is heap-allocated and must be deallocated using
free. */
-__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1, 2))
+__attribute_maybe_unused__ __attribute_warn_unused_result__
+__attribute_nonnull__ ((1, 2))
static bool
DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list,
DYNARRAY_FINAL_TYPE *result)
@@ -483,7 +485,8 @@ DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list,
have a sentinel at the end). If LENGTHP is not NULL, the array
length is written to *LENGTHP. *LIST is re-initialized and can be
reused. */
-__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1))
+__attribute_maybe_unused__ __attribute_warn_unused_result__
+__attribute_nonnull__ ((1))
static DYNARRAY_ELEMENT *
DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list, size_t *lengthp)
{
diff --git a/lib/malloc/dynarray.h b/lib/malloc/dynarray.h
index 84e4394bf32..638c33f9867 100644
--- a/lib/malloc/dynarray.h
+++ b/lib/malloc/dynarray.h
@@ -3,16 +3,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/malloc/dynarray_at_failure.c b/lib/malloc/dynarray_at_failure.c
index a4424593748..8dd68507870 100644
--- a/lib/malloc/dynarray_at_failure.c
+++ b/lib/malloc/dynarray_at_failure.c
@@ -3,22 +3,26 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#ifndef _LIBC
+# include <libc-config.h>
+# include <stdlib.h>
+#endif
+
#include <dynarray.h>
#include <stdio.h>
-#include <stdlib.h>
void
__libc_dynarray_at_failure (size_t size, size_t index)
@@ -28,6 +32,7 @@ __libc_dynarray_at_failure (size_t size, size_t index)
__snprintf (buf, sizeof (buf), "Fatal glibc error: "
"array index %zu not less than array length %zu\n",
index, size);
+ __libc_fatal (buf);
#else
abort ();
#endif
diff --git a/lib/malloc/dynarray_emplace_enlarge.c b/lib/malloc/dynarray_emplace_enlarge.c
index 7ac4b6db403..0f8baf94ad1 100644
--- a/lib/malloc/dynarray_emplace_enlarge.c
+++ b/lib/malloc/dynarray_emplace_enlarge.c
@@ -3,19 +3,23 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#ifndef _LIBC
+# include <libc-config.h>
+#endif
+
#include <dynarray.h>
#include <errno.h>
#include <intprops.h>
diff --git a/lib/malloc/dynarray_finalize.c b/lib/malloc/dynarray_finalize.c
index be9441e313d..c33da41389e 100644
--- a/lib/malloc/dynarray_finalize.c
+++ b/lib/malloc/dynarray_finalize.c
@@ -3,19 +3,23 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#ifndef _LIBC
+# include <libc-config.h>
+#endif
+
#include <dynarray.h>
#include <stdlib.h>
#include <string.h>
diff --git a/lib/malloc/dynarray_resize.c b/lib/malloc/dynarray_resize.c
index 92bbddd4461..5a57166a849 100644
--- a/lib/malloc/dynarray_resize.c
+++ b/lib/malloc/dynarray_resize.c
@@ -3,19 +3,23 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#ifndef _LIBC
+# include <libc-config.h>
+#endif
+
#include <dynarray.h>
#include <errno.h>
#include <intprops.h>
diff --git a/lib/malloc/dynarray_resize_clear.c b/lib/malloc/dynarray_resize_clear.c
index 99c2cc87c31..9c43b00c3a7 100644
--- a/lib/malloc/dynarray_resize_clear.c
+++ b/lib/malloc/dynarray_resize_clear.c
@@ -3,19 +3,23 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#ifndef _LIBC
+# include <libc-config.h>
+#endif
+
#include <dynarray.h>
#include <string.h>
diff --git a/lib/malloc/scratch_buffer.h b/lib/malloc/scratch_buffer.h
index 26e306212d1..36d0bef4bb1 100644
--- a/lib/malloc/scratch_buffer.h
+++ b/lib/malloc/scratch_buffer.h
@@ -3,16 +3,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/malloc/scratch_buffer_dupfree.c b/lib/malloc/scratch_buffer_dupfree.c
index 775bff5609f..07363b9bc86 100644
--- a/lib/malloc/scratch_buffer_dupfree.c
+++ b/lib/malloc/scratch_buffer_dupfree.c
@@ -3,16 +3,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/malloc/scratch_buffer_grow.c b/lib/malloc/scratch_buffer_grow.c
index e7606d81cd7..22c8c7781ee 100644
--- a/lib/malloc/scratch_buffer_grow.c
+++ b/lib/malloc/scratch_buffer_grow.c
@@ -3,16 +3,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/malloc/scratch_buffer_grow_preserve.c b/lib/malloc/scratch_buffer_grow_preserve.c
index 59f8c710001..2b2b819289e 100644
--- a/lib/malloc/scratch_buffer_grow_preserve.c
+++ b/lib/malloc/scratch_buffer_grow_preserve.c
@@ -3,16 +3,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/malloc/scratch_buffer_set_array_size.c b/lib/malloc/scratch_buffer_set_array_size.c
index e2b9f31211a..a47f9276a82 100644
--- a/lib/malloc/scratch_buffer_set_array_size.c
+++ b/lib/malloc/scratch_buffer_set_array_size.c
@@ -3,16 +3,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/malloca.c b/lib/malloca.c
deleted file mode 100644
index d68d233dcb3..00000000000
--- a/lib/malloca.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/* Safe automatic memory allocation.
- Copyright (C) 2003, 2006-2007, 2009-2021 Free Software Foundation,
- Inc.
- Written by Bruno Haible <bruno@clisp.org>, 2003, 2018.
-
- 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, 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/>. */
-
-#define _GL_USE_STDLIB_ALLOC 1
-#include <config.h>
-
-/* Specification. */
-#include "malloca.h"
-
-#include "verify.h"
-
-/* The speed critical point in this file is freea() applied to an alloca()
- result: it must be fast, to match the speed of alloca(). The speed of
- mmalloca() and freea() in the other case are not critical, because they
- are only invoked for big memory sizes.
- Here we use a bit in the address as an indicator, an idea by Ondřej Bílka.
- malloca() can return three types of pointers:
- - Pointers ≡ 0 mod 2*sa_alignment_max come from stack allocation.
- - Pointers ≡ sa_alignment_max mod 2*sa_alignment_max come from heap
- allocation.
- - NULL comes from a failed heap allocation. */
-
-/* Type for holding very small pointer differences. */
-typedef unsigned char small_t;
-/* Verify that it is wide enough. */
-verify (2 * sa_alignment_max - 1 <= (small_t) -1);
-
-void *
-mmalloca (size_t n)
-{
-#if HAVE_ALLOCA
- /* Allocate one more word, used to determine the address to pass to freea(),
- and room for the alignment ≡ sa_alignment_max mod 2*sa_alignment_max. */
- size_t nplus = n + sizeof (small_t) + 2 * sa_alignment_max - 1;
-
- if (nplus >= n)
- {
- char *mem = (char *) malloc (nplus);
-
- if (mem != NULL)
- {
- char *p =
- (char *)((((uintptr_t)mem + sizeof (small_t) + sa_alignment_max - 1)
- & ~(uintptr_t)(2 * sa_alignment_max - 1))
- + sa_alignment_max);
- /* Here p >= mem + sizeof (small_t),
- and p <= mem + sizeof (small_t) + 2 * sa_alignment_max - 1
- hence p + n <= mem + nplus.
- So, the memory range [p, p+n) lies in the allocated memory range
- [mem, mem + nplus). */
- ((small_t *) p)[-1] = p - mem;
- /* p ≡ sa_alignment_max mod 2*sa_alignment_max. */
- return p;
- }
- }
- /* Out of memory. */
- return NULL;
-#else
-# if !MALLOC_0_IS_NONNULL
- if (n == 0)
- n = 1;
-# endif
- return malloc (n);
-#endif
-}
-
-#if HAVE_ALLOCA
-void
-freea (void *p)
-{
- /* Check argument. */
- if ((uintptr_t) p & (sa_alignment_max - 1))
- {
- /* p was not the result of a malloca() call. Invalid argument. */
- abort ();
- }
- /* Determine whether p was a non-NULL pointer returned by mmalloca(). */
- if ((uintptr_t) p & sa_alignment_max)
- {
- void *mem = (char *) p - ((small_t *) p)[-1];
- free (mem);
- }
-}
-#endif
-
-/*
- * Hey Emacs!
- * Local Variables:
- * coding: utf-8
- * End:
- */
diff --git a/lib/malloca.h b/lib/malloca.h
deleted file mode 100644
index a04e54593fa..00000000000
--- a/lib/malloca.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/* Safe automatic memory allocation.
- Copyright (C) 2003-2007, 2009-2021 Free Software Foundation, Inc.
- Written by Bruno Haible <bruno@clisp.org>, 2003.
-
- 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, 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/>. */
-
-#ifndef _MALLOCA_H
-#define _MALLOCA_H
-
-#include <alloca.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include "xalloc-oversized.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* safe_alloca(N) is equivalent to alloca(N) when it is safe to call
- alloca(N); otherwise it returns NULL. It either returns N bytes of
- memory allocated on the stack, that lasts until the function returns,
- or NULL.
- Use of safe_alloca should be avoided:
- - inside arguments of function calls - undefined behaviour,
- - in inline functions - the allocation may actually last until the
- calling function returns.
-*/
-#if HAVE_ALLOCA
-/* The OS usually guarantees only one guard page at the bottom of the stack,
- and a page size can be as small as 4096 bytes. So we cannot safely
- allocate anything larger than 4096 bytes. Also care for the possibility
- of a few compiler-allocated temporary stack slots.
- This must be a macro, not a function. */
-# define safe_alloca(N) ((N) < 4032 ? alloca (N) : NULL)
-#else
-# define safe_alloca(N) ((void) (N), NULL)
-#endif
-
-/* malloca(N) is a safe variant of alloca(N). It allocates N bytes of
- memory allocated on the stack, that must be freed using freea() before
- the function returns. Upon failure, it returns NULL. */
-#if HAVE_ALLOCA
-# define malloca(N) \
- ((N) < 4032 - (2 * sa_alignment_max - 1) \
- ? (void *) (((uintptr_t) (char *) alloca ((N) + 2 * sa_alignment_max - 1) \
- + (2 * sa_alignment_max - 1)) \
- & ~(uintptr_t)(2 * sa_alignment_max - 1)) \
- : mmalloca (N))
-#else
-# define malloca(N) \
- mmalloca (N)
-#endif
-extern void * mmalloca (size_t n);
-
-/* Free a block of memory allocated through malloca(). */
-#if HAVE_ALLOCA
-extern void freea (void *p);
-#else
-# define freea free
-#endif
-
-/* nmalloca(N,S) is an overflow-safe variant of malloca (N * S).
- It allocates an array of N objects, each with S bytes of memory,
- on the stack. S must be positive and N must be nonnegative.
- The array must be freed using freea() before the function returns. */
-#define nmalloca(n, s) (xalloc_oversized (n, s) ? NULL : malloca ((n) * (s)))
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/* ------------------- Auxiliary, non-public definitions ------------------- */
-
-/* Determine the alignment of a type at compile time. */
-#if defined __GNUC__ || defined __clang__ || defined __IBM__ALIGNOF__
-# define sa_alignof __alignof__
-#elif defined __cplusplus
- template <class type> struct sa_alignof_helper { char __slot1; type __slot2; };
-# define sa_alignof(type) offsetof (sa_alignof_helper<type>, __slot2)
-#elif defined __hpux
- /* Work around a HP-UX 10.20 cc bug with enums constants defined as offsetof
- values. */
-# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8)
-#elif defined _AIX
- /* Work around an AIX 3.2.5 xlc bug with enums constants defined as offsetof
- values. */
-# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8)
-#else
-# define sa_alignof(type) offsetof (struct { char __slot1; type __slot2; }, __slot2)
-#endif
-
-enum
-{
-/* The desired alignment of memory allocations is the maximum alignment
- among all elementary types. */
- sa_alignment_long = sa_alignof (long),
- sa_alignment_double = sa_alignof (double),
- sa_alignment_longlong = sa_alignof (long long),
- sa_alignment_longdouble = sa_alignof (long double),
- sa_alignment_max = ((sa_alignment_long - 1) | (sa_alignment_double - 1)
- | (sa_alignment_longlong - 1)
- | (sa_alignment_longdouble - 1)
- ) + 1
-};
-
-#endif /* _MALLOCA_H */
diff --git a/lib/md5-stream.c b/lib/md5-stream.c
new file mode 100644
index 00000000000..fb483b73347
--- /dev/null
+++ b/lib/md5-stream.c
@@ -0,0 +1,141 @@
+/* Functions to compute MD5 message digest of files or memory blocks.
+ according to the definition of MD5 in RFC 1321 from April 1992.
+ Copyright (C) 1995-1997, 1999-2001, 2005-2006, 2008-2021 Free Software
+ Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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/>. */
+
+/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
+
+#include <config.h>
+
+/* Specification. */
+#if HAVE_OPENSSL_MD5
+# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE
+#endif
+#include "md5.h"
+
+#include <stdlib.h>
+
+#if USE_UNLOCKED_IO
+# include "unlocked-io.h"
+#endif
+
+#include "af_alg.h"
+
+#ifdef _LIBC
+# include <endian.h>
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define WORDS_BIGENDIAN 1
+# endif
+/* We need to keep the namespace clean so define the MD5 function
+ protected using leading __ . */
+# define md5_init_ctx __md5_init_ctx
+# define md5_process_block __md5_process_block
+# define md5_process_bytes __md5_process_bytes
+# define md5_finish_ctx __md5_finish_ctx
+# define md5_stream __md5_stream
+#endif
+
+#define BLOCKSIZE 32768
+#if BLOCKSIZE % 64 != 0
+# error "invalid BLOCKSIZE"
+#endif
+
+/* Compute MD5 message digest for bytes read from STREAM. The
+ resulting message digest number will be written into the 16 bytes
+ beginning at RESBLOCK. */
+int
+md5_stream (FILE *stream, void *resblock)
+{
+ switch (afalg_stream (stream, "md5", resblock, MD5_DIGEST_SIZE))
+ {
+ case 0: return 0;
+ case -EIO: return 1;
+ }
+
+ char *buffer = malloc (BLOCKSIZE + 72);
+ if (!buffer)
+ return 1;
+
+ struct md5_ctx ctx;
+ md5_init_ctx (&ctx);
+ size_t sum;
+
+ /* Iterate over full file contents. */
+ while (1)
+ {
+ /* We read the file in blocks of BLOCKSIZE bytes. One call of the
+ computation function processes the whole buffer so that with the
+ next round of the loop another block can be read. */
+ size_t n;
+ sum = 0;
+
+ /* Read block. Take care for partial reads. */
+ while (1)
+ {
+ /* Either process a partial fread() from this loop,
+ or the fread() in afalg_stream may have gotten EOF.
+ We need to avoid a subsequent fread() as EOF may
+ not be sticky. For details of such systems, see:
+ https://sourceware.org/bugzilla/show_bug.cgi?id=1190 */
+ if (feof (stream))
+ goto process_partial_block;
+
+ n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
+
+ sum += n;
+
+ if (sum == BLOCKSIZE)
+ break;
+
+ if (n == 0)
+ {
+ /* Check for the error flag IFF N == 0, so that we don't
+ exit the loop after a partial read due to e.g., EAGAIN
+ or EWOULDBLOCK. */
+ if (ferror (stream))
+ {
+ free (buffer);
+ return 1;
+ }
+ goto process_partial_block;
+ }
+ }
+
+ /* Process buffer with BLOCKSIZE bytes. Note that
+ BLOCKSIZE % 64 == 0
+ */
+ md5_process_block (buffer, BLOCKSIZE, &ctx);
+ }
+
+process_partial_block:
+
+ /* Process any remaining bytes. */
+ if (sum > 0)
+ md5_process_bytes (buffer, sum, &ctx);
+
+ /* Construct result in desired memory. */
+ md5_finish_ctx (&ctx, resblock);
+ free (buffer);
+ return 0;
+}
+
+/*
+ * Hey Emacs!
+ * Local Variables:
+ * coding: utf-8
+ * End:
+ */
diff --git a/lib/md5.c b/lib/md5.c
index e7eeeaab03f..7955665ccdb 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -4,23 +4,24 @@
Foundation, Inc.
This file is part of the GNU C Library.
- 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, or (at your option) any
- later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
#include <config.h>
+/* Specification. */
#if HAVE_OPENSSL_MD5
# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE
#endif
@@ -28,14 +29,9 @@
#include <stdalign.h>
#include <stdint.h>
-#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
-#if USE_UNLOCKED_IO
-# include "unlocked-io.h"
-#endif
-
#ifdef _LIBC
# include <endian.h>
# if __BYTE_ORDER == __BIG_ENDIAN
@@ -48,7 +44,6 @@
# define md5_process_bytes __md5_process_bytes
# define md5_finish_ctx __md5_finish_ctx
# define md5_read_ctx __md5_read_ctx
-# define md5_stream __md5_stream
# define md5_buffer __md5_buffer
#endif
@@ -59,12 +54,8 @@
# define SWAP(n) (n)
#endif
-#define BLOCKSIZE 32768
-#if BLOCKSIZE % 64 != 0
-# error "invalid BLOCKSIZE"
-#endif
-
#if ! HAVE_OPENSSL_MD5
+
/* This array contains the bytes used to pad the buffer to the next
64-byte boundary. (RFC 1321, 3.1: Step 1) */
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
@@ -132,93 +123,7 @@ md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
return md5_read_ctx (ctx, resbuf);
}
-#endif
-
-#if defined _LIBC || defined GL_COMPILE_CRYPTO_STREAM
-
-#include "af_alg.h"
-
-/* Compute MD5 message digest for bytes read from STREAM. The
- resulting message digest number will be written into the 16 bytes
- beginning at RESBLOCK. */
-int
-md5_stream (FILE *stream, void *resblock)
-{
- switch (afalg_stream (stream, "md5", resblock, MD5_DIGEST_SIZE))
- {
- case 0: return 0;
- case -EIO: return 1;
- }
-
- char *buffer = malloc (BLOCKSIZE + 72);
- if (!buffer)
- return 1;
-
- struct md5_ctx ctx;
- md5_init_ctx (&ctx);
- size_t sum;
-
- /* Iterate over full file contents. */
- while (1)
- {
- /* We read the file in blocks of BLOCKSIZE bytes. One call of the
- computation function processes the whole buffer so that with the
- next round of the loop another block can be read. */
- size_t n;
- sum = 0;
-
- /* Read block. Take care for partial reads. */
- while (1)
- {
- /* Either process a partial fread() from this loop,
- or the fread() in afalg_stream may have gotten EOF.
- We need to avoid a subsequent fread() as EOF may
- not be sticky. For details of such systems, see:
- https://sourceware.org/bugzilla/show_bug.cgi?id=1190 */
- if (feof (stream))
- goto process_partial_block;
-
- n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
-
- sum += n;
-
- if (sum == BLOCKSIZE)
- break;
-
- if (n == 0)
- {
- /* Check for the error flag IFF N == 0, so that we don't
- exit the loop after a partial read due to e.g., EAGAIN
- or EWOULDBLOCK. */
- if (ferror (stream))
- {
- free (buffer);
- return 1;
- }
- goto process_partial_block;
- }
- }
-
- /* Process buffer with BLOCKSIZE bytes. Note that
- BLOCKSIZE % 64 == 0
- */
- md5_process_block (buffer, BLOCKSIZE, &ctx);
- }
-
-process_partial_block:
-
- /* Process any remaining bytes. */
- if (sum > 0)
- md5_process_bytes (buffer, sum, &ctx);
-
- /* Construct result in desired memory. */
- md5_finish_ctx (&ctx, resblock);
- free (buffer);
- return 0;
-}
-#endif
-#if ! HAVE_OPENSSL_MD5
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message
@@ -479,6 +384,7 @@ md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
ctx->C = C;
ctx->D = D;
}
+
#endif
/*
diff --git a/lib/md5.h b/lib/md5.h
index aa4b0805d58..bae5960a8c4 100644
--- a/lib/md5.h
+++ b/lib/md5.h
@@ -4,18 +4,18 @@
Foundation, Inc.
This file is part of the GNU C Library.
- 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, or (at your option) any
- later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
#ifndef _MD5_H
#define _MD5_H 1
@@ -124,6 +124,7 @@ extern void *__md5_buffer (const char *buffer, size_t len,
void *restrict resblock) __THROW;
# endif
+
/* Compute MD5 message digest for bytes read from STREAM.
STREAM is an open file stream. Regular files are handled more efficiently.
The contents of STREAM from its current position to its end will be read.
diff --git a/lib/memmem.c b/lib/memmem.c
index 87266fa87af..142de576d93 100644
--- a/lib/memmem.c
+++ b/lib/memmem.c
@@ -2,18 +2,18 @@
Foundation, Inc.
This file is part of the GNU C Library.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
/* This particular implementation was written by Eric Blake, 2008. */
diff --git a/lib/mempcpy.c b/lib/mempcpy.c
index fea618a9e59..cacacdbc62e 100644
--- a/lib/mempcpy.c
+++ b/lib/mempcpy.c
@@ -1,24 +1,27 @@
/* Copy memory area and return pointer after last written byte.
Copyright (C) 2003, 2007, 2009-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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 <config.h>
/* Specification. */
#include <string.h>
+/* A function definition is only needed if HAVE_MEMPCPY is not defined. */
+#if !HAVE_MEMPCPY
+
/* Copy N bytes of SRC to DEST, return pointer to bytes after the
last written byte. */
void *
@@ -26,3 +29,5 @@ mempcpy (void *dest, const void *src, size_t n)
{
return (char *) memcpy (dest, src, n) + n;
}
+
+#endif
diff --git a/lib/memrchr.c b/lib/memrchr.c
index dcd24fafc6e..e0d47d13d79 100644
--- a/lib/memrchr.c
+++ b/lib/memrchr.c
@@ -9,17 +9,17 @@
adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
and implemented by Roland McGrath (roland@ai.mit.edu).
- 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 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
#if defined _LIBC
diff --git a/lib/mini-gmp-gnulib.c b/lib/mini-gmp-gnulib.c
index d46c2b993bc..08aa8f97c17 100644
--- a/lib/mini-gmp-gnulib.c
+++ b/lib/mini-gmp-gnulib.c
@@ -2,18 +2,26 @@
Copyright 2018-2021 Free Software Foundation, Inc.
- 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,
+ This file is free software.
+ It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+".
+ You can redistribute it and/or modify it under either
+ - the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version, or
+ - the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option)
+ any later version, or
+ - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+".
+
+ 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 General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License and 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/>. */
+ You should have received a copy of the GNU Lesser General Public
+ License and of the GNU General Public License along with this
+ program. If not, see <https://www.gnu.org/licenses/>. */
#include <config.h>
diff --git a/lib/mini-gmp.c b/lib/mini-gmp.c
index de061e673ac..8577b59ef6d 100644
--- a/lib/mini-gmp.c
+++ b/lib/mini-gmp.c
@@ -2,21 +2,21 @@
Contributed to the GNU project by Niels Möller
-Copyright 1991-1997, 1999-2020 Free Software Foundation, Inc.
+Copyright 1991-1997, 1999-2021 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
- * the GNU General Public License as published by the Free
+ * the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
- Foundation; either version 3 of the License, or (at your option) any
+ Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
@@ -27,7 +27,7 @@ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
-GNU General Public License along with the GNU MP Library. If not,
+GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
/* NOTE: All functions in this file which are not declared in
@@ -148,6 +148,7 @@ see https://www.gnu.org/licenses/. */
mp_limb_t __x0, __x1, __x2, __x3; \
unsigned __ul, __vl, __uh, __vh; \
mp_limb_t __u = (u), __v = (v); \
+ assert (sizeof (unsigned) * 2 >= sizeof (mp_limb_t)); \
\
__ul = __u & GMP_LLIMB_MASK; \
__uh = __u >> (GMP_LIMB_BITS / 2); \
@@ -783,6 +784,7 @@ mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0)
mp_limb_t p, ql;
unsigned ul, uh, qh;
+ assert (sizeof (unsigned) * 2 >= sizeof (mp_limb_t));
/* For notation, let b denote the half-limb base, so that B = b^2.
Split u1 = b uh + ul. */
ul = u1 & GMP_LLIMB_MASK;
@@ -3198,6 +3200,7 @@ void
mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, unsigned long z)
{
int sgn;
+ mp_bitcnt_t bc;
mpz_t t, u;
sgn = y->_mp_size < 0;
@@ -3216,7 +3219,8 @@ mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, unsigned long z)
mpz_init (u);
mpz_init (t);
- mpz_setbit (t, mpz_sizeinbase (y, 2) / z + 1);
+ bc = (mpz_sizeinbase (y, 2) - 1) / z + 1;
+ mpz_setbit (t, bc);
if (z == 2) /* simplify sqrt loop: z-1 == 1 */
do {
@@ -3523,7 +3527,8 @@ gmp_stronglucas (const mpz_t x, mpz_t Qk)
mpz_init (V);
/* n-(D/n) = n+1 = d*2^{b0}, with d = (n>>b0) | 1 */
- b0 = mpz_scan0 (n, 0);
+ b0 = mpn_common_scan (~ n->_mp_d[0], 0, n->_mp_d, n->_mp_size, GMP_LIMB_MAX);
+ /* b0 = mpz_scan0 (n, 0); */
/* D= P^2 - 4Q; P = 1; Q = (1-D)/4 */
Q = (D & 2) ? (long) (D >> 2) + 1 : -(long) (D >> 2);
@@ -3555,11 +3560,6 @@ gmp_millerrabin (const mpz_t n, const mpz_t nm1, mpz_t y,
mpz_powm_ui (y, y, 2, n);
if (mpz_cmp (y, nm1) == 0)
return 1;
- /* y == 1 means that the previous y was a non-trivial square root
- of 1 (mod n). y == 0 means that n is a power of the base.
- In either case, n is not prime. */
- if (mpz_cmp_ui (y, 1) <= 0)
- return 0;
}
return 0;
}
diff --git a/lib/mini-gmp.h b/lib/mini-gmp.h
index 59a37e64947..59c24cf5111 100644
--- a/lib/mini-gmp.h
+++ b/lib/mini-gmp.h
@@ -1,20 +1,20 @@
/* mini-gmp, a minimalistic implementation of a GNU GMP subset.
-Copyright 2011-2015, 2017, 2019-2020 Free Software Foundation, Inc.
+Copyright 2011-2015, 2017, 2019-2021 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
- * the GNU General Public License as published by the Free
+ * the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
- Foundation; either version 3 of the License, or (at your option) any
+ Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
@@ -25,7 +25,7 @@ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
-GNU General Public License along with the GNU MP Library. If not,
+GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
/* About mini-gmp: This is a minimal implementation of a subset of the
@@ -296,6 +296,7 @@ int mpz_init_set_str (mpz_t, const char *, int);
|| defined (_STDIO_H_INCLUDED) /* QNX4 */ \
|| defined (_ISO_STDIO_ISO_H) /* Sun C++ */ \
|| defined (__STDIO_LOADED) /* VMS */ \
+ || defined (_STDIO) /* HPE NonStop */ \
|| defined (__DEFINED_FILE) /* musl */
size_t mpz_out_str (FILE *, int, const mpz_t);
#endif
diff --git a/lib/minmax.h b/lib/minmax.h
index eb9fb09a540..a03361bafa5 100644
--- a/lib/minmax.h
+++ b/lib/minmax.h
@@ -2,18 +2,18 @@
Copyright (C) 1995, 1998, 2001, 2003, 2005, 2009-2021 Free Software
Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
#ifndef _MINMAX_H
#define _MINMAX_H
diff --git a/lib/mkostemp.c b/lib/mkostemp.c
index 9d733ddd10d..285f1badf8f 100644
--- a/lib/mkostemp.c
+++ b/lib/mkostemp.c
@@ -2,17 +2,17 @@
Foundation, Inc.
This file is derived from the one in the GNU C Library.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
#if !_LIBC
diff --git a/lib/mktime-internal.h b/lib/mktime-internal.h
index 9c447bd7b05..7386625d3de 100644
--- a/lib/mktime-internal.h
+++ b/lib/mktime-internal.h
@@ -4,16 +4,16 @@
Contributed by Paul Eggert <eggert@cs.ucla.edu>.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/mktime.c b/lib/mktime.c
index 2c7cd7ba832..ae721c72e67 100644
--- a/lib/mktime.c
+++ b/lib/mktime.c
@@ -4,16 +4,16 @@
Contributed by Paul Eggert <eggert@twinsun.com>.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/nproc.c b/lib/nproc.c
new file mode 100644
index 00000000000..a9e369dd3f7
--- /dev/null
+++ b/lib/nproc.c
@@ -0,0 +1,403 @@
+/* Detect the number of processors.
+
+ Copyright (C) 2009-2021 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/>. */
+
+/* Written by Glen Lenker and Bruno Haible. */
+
+#include <config.h>
+#include "nproc.h"
+
+#include <limits.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#if HAVE_PTHREAD_GETAFFINITY_NP && 0
+# include <pthread.h>
+# include <sched.h>
+#endif
+#if HAVE_SCHED_GETAFFINITY_LIKE_GLIBC || HAVE_SCHED_GETAFFINITY_NP
+# include <sched.h>
+#endif
+
+#include <sys/types.h>
+
+#if HAVE_SYS_PSTAT_H
+# include <sys/pstat.h>
+#endif
+
+#if HAVE_SYS_SYSMP_H
+# include <sys/sysmp.h>
+#endif
+
+#if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+
+#if HAVE_SYS_SYSCTL_H && ! defined __GLIBC__
+# include <sys/sysctl.h>
+#endif
+
+#if defined _WIN32 && ! defined __CYGWIN__
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
+#include "c-ctype.h"
+
+#include "minmax.h"
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+/* Return the number of processors available to the current process, based
+ on a modern system call that returns the "affinity" between the current
+ process and each CPU. Return 0 if unknown or if such a system call does
+ not exist. */
+static unsigned long
+num_processors_via_affinity_mask (void)
+{
+ /* glibc >= 2.3.3 with NPTL and NetBSD 5 have pthread_getaffinity_np,
+ but with different APIs. Also it requires linking with -lpthread.
+ Therefore this code is not enabled.
+ glibc >= 2.3.4 has sched_getaffinity whereas NetBSD 5 has
+ sched_getaffinity_np. */
+#if HAVE_PTHREAD_GETAFFINITY_NP && defined __GLIBC__ && 0
+ {
+ cpu_set_t set;
+
+ if (pthread_getaffinity_np (pthread_self (), sizeof (set), &set) == 0)
+ {
+ unsigned long count;
+
+# ifdef CPU_COUNT
+ /* glibc >= 2.6 has the CPU_COUNT macro. */
+ count = CPU_COUNT (&set);
+# else
+ size_t i;
+
+ count = 0;
+ for (i = 0; i < CPU_SETSIZE; i++)
+ if (CPU_ISSET (i, &set))
+ count++;
+# endif
+ if (count > 0)
+ return count;
+ }
+ }
+#elif HAVE_PTHREAD_GETAFFINITY_NP && defined __NetBSD__ && 0
+ {
+ cpuset_t *set;
+
+ set = cpuset_create ();
+ if (set != NULL)
+ {
+ unsigned long count = 0;
+
+ if (pthread_getaffinity_np (pthread_self (), cpuset_size (set), set)
+ == 0)
+ {
+ cpuid_t i;
+
+ for (i = 0;; i++)
+ {
+ int ret = cpuset_isset (i, set);
+ if (ret < 0)
+ break;
+ if (ret > 0)
+ count++;
+ }
+ }
+ cpuset_destroy (set);
+ if (count > 0)
+ return count;
+ }
+ }
+#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */
+ {
+ cpu_set_t set;
+
+ if (sched_getaffinity (0, sizeof (set), &set) == 0)
+ {
+ unsigned long count;
+
+# ifdef CPU_COUNT
+ /* glibc >= 2.6 has the CPU_COUNT macro. */
+ count = CPU_COUNT (&set);
+# else
+ size_t i;
+
+ count = 0;
+ for (i = 0; i < CPU_SETSIZE; i++)
+ if (CPU_ISSET (i, &set))
+ count++;
+# endif
+ if (count > 0)
+ return count;
+ }
+ }
+#elif HAVE_SCHED_GETAFFINITY_NP /* NetBSD >= 5 */
+ {
+ cpuset_t *set;
+
+ set = cpuset_create ();
+ if (set != NULL)
+ {
+ unsigned long count = 0;
+
+ if (sched_getaffinity_np (getpid (), cpuset_size (set), set) == 0)
+ {
+ cpuid_t i;
+
+ for (i = 0;; i++)
+ {
+ int ret = cpuset_isset (i, set);
+ if (ret < 0)
+ break;
+ if (ret > 0)
+ count++;
+ }
+ }
+ cpuset_destroy (set);
+ if (count > 0)
+ return count;
+ }
+ }
+#endif
+
+#if defined _WIN32 && ! defined __CYGWIN__
+ { /* This works on native Windows platforms. */
+ DWORD_PTR process_mask;
+ DWORD_PTR system_mask;
+
+ if (GetProcessAffinityMask (GetCurrentProcess (),
+ &process_mask, &system_mask))
+ {
+ DWORD_PTR mask = process_mask;
+ unsigned long count = 0;
+
+ for (; mask != 0; mask = mask >> 1)
+ if (mask & 1)
+ count++;
+ if (count > 0)
+ return count;
+ }
+ }
+#endif
+
+ return 0;
+}
+
+
+/* Return the total number of processors. Here QUERY must be one of
+ NPROC_ALL, NPROC_CURRENT. The result is guaranteed to be at least 1. */
+static unsigned long int
+num_processors_ignoring_omp (enum nproc_query query)
+{
+ /* On systems with a modern affinity mask system call, we have
+ sysconf (_SC_NPROCESSORS_CONF)
+ >= sysconf (_SC_NPROCESSORS_ONLN)
+ >= num_processors_via_affinity_mask ()
+ The first number is the number of CPUs configured in the system.
+ The second number is the number of CPUs available to the scheduler.
+ The third number is the number of CPUs available to the current process.
+
+ Note! On Linux systems with glibc, the first and second number come from
+ the /sys and /proc file systems (see
+ glibc/sysdeps/unix/sysv/linux/getsysstats.c).
+ In some situations these file systems are not mounted, and the sysconf call
+ returns 1 or 2 (<https://sourceware.org/bugzilla/show_bug.cgi?id=21542>),
+ which does not reflect the reality. */
+
+ if (query == NPROC_CURRENT)
+ {
+ /* Try the modern affinity mask system call. */
+ {
+ unsigned long nprocs = num_processors_via_affinity_mask ();
+
+ if (nprocs > 0)
+ return nprocs;
+ }
+
+#if defined _SC_NPROCESSORS_ONLN
+ { /* This works on glibc, Mac OS X 10.5, FreeBSD, AIX, OSF/1, Solaris,
+ Cygwin, Haiku. */
+ long int nprocs = sysconf (_SC_NPROCESSORS_ONLN);
+ if (nprocs > 0)
+ return nprocs;
+ }
+#endif
+ }
+ else /* query == NPROC_ALL */
+ {
+#if defined _SC_NPROCESSORS_CONF
+ { /* This works on glibc, Mac OS X 10.5, FreeBSD, AIX, OSF/1, Solaris,
+ Cygwin, Haiku. */
+ long int nprocs = sysconf (_SC_NPROCESSORS_CONF);
+
+# if __GLIBC__ >= 2 && defined __linux__
+ /* On Linux systems with glibc, this information comes from the /sys and
+ /proc file systems (see glibc/sysdeps/unix/sysv/linux/getsysstats.c).
+ In some situations these file systems are not mounted, and the
+ sysconf call returns 1 or 2. But we wish to guarantee that
+ num_processors (NPROC_ALL) >= num_processors (NPROC_CURRENT). */
+ if (nprocs == 1 || nprocs == 2)
+ {
+ unsigned long nprocs_current = num_processors_via_affinity_mask ();
+
+ if (/* nprocs_current > 0 && */ nprocs_current > nprocs)
+ nprocs = nprocs_current;
+ }
+# endif
+
+ if (nprocs > 0)
+ return nprocs;
+ }
+#endif
+ }
+
+#if HAVE_PSTAT_GETDYNAMIC
+ { /* This works on HP-UX. */
+ struct pst_dynamic psd;
+ if (pstat_getdynamic (&psd, sizeof psd, 1, 0) >= 0)
+ {
+ /* The field psd_proc_cnt contains the number of active processors.
+ In newer releases of HP-UX 11, the field psd_max_proc_cnt includes
+ deactivated processors. */
+ if (query == NPROC_CURRENT)
+ {
+ if (psd.psd_proc_cnt > 0)
+ return psd.psd_proc_cnt;
+ }
+ else
+ {
+ if (psd.psd_max_proc_cnt > 0)
+ return psd.psd_max_proc_cnt;
+ }
+ }
+ }
+#endif
+
+#if HAVE_SYSMP && defined MP_NAPROCS && defined MP_NPROCS
+ { /* This works on IRIX. */
+ /* MP_NPROCS yields the number of installed processors.
+ MP_NAPROCS yields the number of processors available to unprivileged
+ processes. */
+ int nprocs =
+ sysmp (query == NPROC_CURRENT && getuid () != 0
+ ? MP_NAPROCS
+ : MP_NPROCS);
+ if (nprocs > 0)
+ return nprocs;
+ }
+#endif
+
+ /* Finally, as fallback, use the APIs that don't distinguish between
+ NPROC_CURRENT and NPROC_ALL. */
+
+#if HAVE_SYSCTL && ! defined __GLIBC__ && defined HW_NCPU
+ { /* This works on Mac OS X, FreeBSD, NetBSD, OpenBSD. */
+ int nprocs;
+ size_t len = sizeof (nprocs);
+ static int const mib[][2] = {
+# ifdef HW_NCPUONLINE
+ { CTL_HW, HW_NCPUONLINE },
+# endif
+ { CTL_HW, HW_NCPU }
+ };
+ for (int i = 0; i < ARRAY_SIZE (mib); i++)
+ {
+ if (sysctl (mib[i], ARRAY_SIZE (mib[i]), &nprocs, &len, NULL, 0) == 0
+ && len == sizeof (nprocs)
+ && 0 < nprocs)
+ return nprocs;
+ }
+ }
+#endif
+
+#if defined _WIN32 && ! defined __CYGWIN__
+ { /* This works on native Windows platforms. */
+ SYSTEM_INFO system_info;
+ GetSystemInfo (&system_info);
+ if (0 < system_info.dwNumberOfProcessors)
+ return system_info.dwNumberOfProcessors;
+ }
+#endif
+
+ return 1;
+}
+
+/* Parse OMP environment variables without dependence on OMP.
+ Return 0 for invalid values. */
+static unsigned long int
+parse_omp_threads (char const* threads)
+{
+ unsigned long int ret = 0;
+
+ if (threads == NULL)
+ return ret;
+
+ /* The OpenMP spec says that the value assigned to the environment variables
+ "may have leading and trailing white space". */
+ while (*threads != '\0' && c_isspace (*threads))
+ threads++;
+
+ /* Convert it from positive decimal to 'unsigned long'. */
+ if (c_isdigit (*threads))
+ {
+ char *endptr = NULL;
+ unsigned long int value = strtoul (threads, &endptr, 10);
+
+ if (endptr != NULL)
+ {
+ while (*endptr != '\0' && c_isspace (*endptr))
+ endptr++;
+ if (*endptr == '\0')
+ return value;
+ /* Also accept the first value in a nesting level,
+ since we can't determine the nesting level from env vars. */
+ else if (*endptr == ',')
+ return value;
+ }
+ }
+
+ return ret;
+}
+
+unsigned long int
+num_processors (enum nproc_query query)
+{
+ unsigned long int omp_env_limit = ULONG_MAX;
+
+ if (query == NPROC_CURRENT_OVERRIDABLE)
+ {
+ unsigned long int omp_env_threads;
+ /* Honor the OpenMP environment variables, recognized also by all
+ programs that are based on OpenMP. */
+ omp_env_threads = parse_omp_threads (getenv ("OMP_NUM_THREADS"));
+ omp_env_limit = parse_omp_threads (getenv ("OMP_THREAD_LIMIT"));
+ if (! omp_env_limit)
+ omp_env_limit = ULONG_MAX;
+
+ if (omp_env_threads)
+ return MIN (omp_env_threads, omp_env_limit);
+
+ query = NPROC_CURRENT;
+ }
+ /* Here query is one of NPROC_ALL, NPROC_CURRENT. */
+ {
+ unsigned long nprocs = num_processors_ignoring_omp (query);
+ return MIN (nprocs, omp_env_limit);
+ }
+}
diff --git a/lib/nproc.h b/lib/nproc.h
new file mode 100644
index 00000000000..d7659a5cad3
--- /dev/null
+++ b/lib/nproc.h
@@ -0,0 +1,46 @@
+/* Detect the number of processors.
+
+ Copyright (C) 2009-2021 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/>. */
+
+/* Written by Glen Lenker and Bruno Haible. */
+
+/* Allow the use in C++ code. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* A "processor" in this context means a thread execution unit, that is either
+ - an execution core in a (possibly multi-core) chip, in a (possibly multi-
+ chip) module, in a single computer, or
+ - a thread execution unit inside a core
+ (hyper-threading, see <https://en.wikipedia.org/wiki/Hyper-threading>).
+ Which of the two definitions is used, is unspecified. */
+
+enum nproc_query
+{
+ NPROC_ALL, /* total number of processors */
+ NPROC_CURRENT, /* processors available to the current process */
+ NPROC_CURRENT_OVERRIDABLE /* likewise, but overridable through the
+ OMP_NUM_THREADS environment variable */
+};
+
+/* Return the total number of processors. The result is guaranteed to
+ be at least 1. */
+extern unsigned long int num_processors (enum nproc_query query);
+
+#ifdef __cplusplus
+}
+#endif /* C++ */
diff --git a/lib/nstrftime.c b/lib/nstrftime.c
index 2f5e4fbe639..7f258e8727f 100644
--- a/lib/nstrftime.c
+++ b/lib/nstrftime.c
@@ -1,19 +1,18 @@
/* Copyright (C) 1991-2021 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- The GNU C Library 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 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 3 of the
+ License, or (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
+ 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
- General Public License for more details.
+ 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 General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
+ 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/>. */
#ifdef _LIBC
# define USE_IN_EXTENDED_LOCALE_MODEL 1
diff --git a/lib/open.c b/lib/open.c
index 85991853318..372cda88163 100644
--- a/lib/open.c
+++ b/lib/open.c
@@ -1,17 +1,17 @@
/* Open a descriptor to a file.
Copyright (C) 2007-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
diff --git a/lib/pathmax.h b/lib/pathmax.h
index 49cf4629c7c..716f4a9aae1 100644
--- a/lib/pathmax.h
+++ b/lib/pathmax.h
@@ -2,18 +2,18 @@
Copyright (C) 1992, 1999, 2001, 2003, 2005, 2009-2021 Free Software
Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
#ifndef _PATHMAX_H
# define _PATHMAX_H
diff --git a/lib/pipe2.c b/lib/pipe2.c
index adbaa4a1021..9ba8c3b7033 100644
--- a/lib/pipe2.c
+++ b/lib/pipe2.c
@@ -1,18 +1,18 @@
/* Create a pipe, with specific opening flags.
Copyright (C) 2009-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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 <config.h>
@@ -41,7 +41,7 @@ pipe2 (int fd[2], int flags)
{
/* Mingw _pipe() corrupts fd on failure; also, if we succeed at
creating the pipe but later fail at changing fcntl, we want
- to leave fd unchanged: https://austingroupbugs.net/view.php?id=467 */
+ to leave fd unchanged: http://austingroupbugs.net/view.php?id=467 */
int tmp[2];
tmp[0] = fd[0];
tmp[1] = fd[1];
diff --git a/lib/pselect.c b/lib/pselect.c
index 0fda4eef6ec..b5fadc6728f 100644
--- a/lib/pselect.c
+++ b/lib/pselect.c
@@ -4,18 +4,18 @@
This file is part of gnulib.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
/* written by Paul Eggert */
diff --git a/lib/pthread_sigmask.c b/lib/pthread_sigmask.c
index 8a692048a02..11b7091e7fd 100644
--- a/lib/pthread_sigmask.c
+++ b/lib/pthread_sigmask.c
@@ -1,17 +1,17 @@
/* POSIX compatible signal blocking for threads.
Copyright (C) 2011-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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 <config.h>
diff --git a/lib/rawmemchr.c b/lib/rawmemchr.c
index bbb250feb8c..e7a00b80306 100644
--- a/lib/rawmemchr.c
+++ b/lib/rawmemchr.c
@@ -1,17 +1,17 @@
/* Searching in a string.
Copyright (C) 2008-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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 <config.h>
@@ -19,68 +19,57 @@
/* Specification. */
#include <string.h>
+/* A function definition is only needed if HAVE_RAWMEMCHR is not defined. */
+#if !HAVE_RAWMEMCHR
+
+# include <limits.h>
+# include <stdalign.h>
+# include <stdint.h>
+
+# include "verify.h"
+
/* Find the first occurrence of C in S. */
void *
rawmemchr (const void *s, int c_in)
{
- /* On 32-bit hardware, choosing longword to be a 32-bit unsigned
- long instead of a 64-bit uintmax_t tends to give better
- performance. On 64-bit hardware, unsigned long is generally 64
- bits already. Change this typedef to experiment with
- performance. */
- typedef unsigned long int longword;
+ /* Change this typedef to experiment with performance. */
+ 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));
const unsigned char *char_ptr;
- const longword *longword_ptr;
- longword repeated_one;
- longword repeated_c;
- unsigned char c;
-
- c = (unsigned char) c_in;
+ unsigned char c = c_in;
/* Handle the first few bytes by reading one byte at a time.
Do this until CHAR_PTR is aligned on a longword boundary. */
for (char_ptr = (const unsigned char *) s;
- (size_t) char_ptr % sizeof (longword) != 0;
+ (uintptr_t) char_ptr % alignof (longword) != 0;
++char_ptr)
if (*char_ptr == c)
return (void *) char_ptr;
- longword_ptr = (const longword *) char_ptr;
-
- /* All these elucidatory comments refer to 4-byte longwords,
- but the theory applies equally well to any size longwords. */
+ longword const *longword_ptr = s = char_ptr;
/* Compute auxiliary longword values:
repeated_one is a value which has a 1 in every byte.
repeated_c has c in every byte. */
- repeated_one = 0x01010101;
- repeated_c = c | (c << 8);
- repeated_c |= repeated_c << 16;
- if (0xffffffffU < (longword) -1)
- {
- repeated_one |= repeated_one << 31 << 1;
- repeated_c |= repeated_c << 31 << 1;
- if (8 < sizeof (longword))
- {
- size_t i;
-
- for (i = 64; i < sizeof (longword) * 8; i *= 2)
- {
- repeated_one |= repeated_one << i;
- repeated_c |= repeated_c << i;
- }
- }
- }
+ longword repeated_one = (longword) -1 / UCHAR_MAX;
+ longword repeated_c = repeated_one * c;
+ longword repeated_hibit = repeated_one * (UCHAR_MAX / 2 + 1);
/* Instead of the traditional loop which tests each byte, we will
- test a longword at a time. The tricky part is testing if *any of
- the four* bytes in the longword in question are equal to NUL or
+ test a longword at a time. The tricky part is testing if any of
+ the bytes in the longword in question are equal to
c. We first use an xor with repeated_c. This reduces the task
- to testing whether *any of the four* bytes in longword1 is zero.
+ to testing whether any of the bytes in longword1 is zero.
+
+ (The following comments assume 8-bit bytes, as POSIX requires;
+ the code's use of UCHAR_MAX should work even if bytes have more
+ than 8 bits.)
We compute tmp =
- ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7).
+ ((longword1 - repeated_one) & ~longword1) & (repeated_one * 0x80).
That is, we perform the following operations:
1. Subtract repeated_one.
2. & ~longword1.
@@ -114,23 +103,23 @@ rawmemchr (const void *s, int c_in)
{
longword longword1 = *longword_ptr ^ repeated_c;
- if ((((longword1 - repeated_one) & ~longword1)
- & (repeated_one << 7)) != 0)
+ if ((((longword1 - repeated_one) & ~longword1) & repeated_hibit) != 0)
break;
longword_ptr++;
}
- char_ptr = (const unsigned char *) longword_ptr;
+ char_ptr = s = longword_ptr;
/* At this point, we know that one of the sizeof (longword) bytes
- starting at char_ptr is == c. On little-endian machines, we
+ starting at char_ptr is == c. If we knew endianness, we
could determine the first such byte without any further memory
accesses, just by looking at the tmp result from the last loop
- iteration. But this does not work on big-endian machines.
- Choose code that works in both cases. */
+ iteration. However, the following simple and portable code does
+ not attempt this potential optimization. */
- char_ptr = (unsigned char *) longword_ptr;
while (*char_ptr != c)
char_ptr++;
return (void *) char_ptr;
}
+
+#endif
diff --git a/lib/rawmemchr.valgrind b/lib/rawmemchr.valgrind
index 087d5e4178d..d489c320c3d 100644
--- a/lib/rawmemchr.valgrind
+++ b/lib/rawmemchr.valgrind
@@ -2,17 +2,17 @@
# Copyright (C) 2008-2021 Free Software Foundation, Inc.
#
-# 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 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 program is distributed in the hope that it will be useful,
+# 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 General Public License for more details.
+# GNU Lesser General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
+# 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/>.
# This use is OK because it provides only a speedup.
diff --git a/lib/readlink.c b/lib/readlink.c
index c4b635ce712..ad4d51dc645 100644
--- a/lib/readlink.c
+++ b/lib/readlink.c
@@ -1,17 +1,17 @@
/* Read the contents of a symbolic link.
Copyright (C) 2003-2007, 2009-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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 <config.h>
@@ -29,8 +29,8 @@
such as DJGPP 2.03 and mingw32. */
ssize_t
-readlink (char const *file, char *buf _GL_UNUSED,
- size_t bufsize _GL_UNUSED)
+readlink (char const *file, _GL_UNUSED char *buf,
+ _GL_UNUSED size_t bufsize)
{
struct stat statbuf;
diff --git a/lib/realloc.c b/lib/realloc.c
new file mode 100644
index 00000000000..af03f0c577d
--- /dev/null
+++ b/lib/realloc.c
@@ -0,0 +1,63 @@
+/* realloc() function that is glibc compatible.
+
+ Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2021 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/>. */
+
+/* written by Jim Meyering and Bruno Haible */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <errno.h>
+
+#include "xalloc-oversized.h"
+
+/* Call the system's realloc below. This file does not define
+ _GL_USE_STDLIB_ALLOC because it needs Gnulib's malloc if present. */
+#undef realloc
+
+/* Change the size of an allocated block of memory P to N bytes,
+ with error checking. If P is NULL, use malloc. Otherwise if N is zero,
+ free P and return NULL. */
+
+void *
+rpl_realloc (void *p, size_t n)
+{
+ if (p == NULL)
+ return malloc (n);
+
+ if (n == 0)
+ {
+ free (p);
+ return NULL;
+ }
+
+ if (xalloc_oversized (n, 1))
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ void *result = realloc (p, n);
+
+#if !HAVE_MALLOC_POSIX
+ if (result == NULL)
+ errno = ENOMEM;
+#endif
+
+ return result;
+}
diff --git a/lib/regcomp.c b/lib/regcomp.c
index 0c31b0e14cb..887e5b50684 100644
--- a/lib/regcomp.c
+++ b/lib/regcomp.c
@@ -4,16 +4,16 @@
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
@@ -1695,12 +1695,14 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
reg_errcode_t err;
Idx i;
re_node_set eclosure;
- bool ok;
bool incomplete = false;
err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);
if (__glibc_unlikely (err != REG_NOERROR))
return err;
+ /* An epsilon closure includes itself. */
+ eclosure.elems[eclosure.nelem++] = node;
+
/* This indicates that we are calculating this node now.
We reference this value to avoid infinite loop. */
dfa->eclosures[node].nelem = -1;
@@ -1753,10 +1755,6 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
}
}
- /* An epsilon closure includes itself. */
- ok = re_node_set_insert (&eclosure, node);
- if (__glibc_unlikely (! ok))
- return REG_ESPACE;
if (incomplete && !root)
dfa->eclosures[node].nelem = 0;
else
diff --git a/lib/regex.c b/lib/regex.c
index f76a416b3b5..d32863972c7 100644
--- a/lib/regex.c
+++ b/lib/regex.c
@@ -4,16 +4,16 @@
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
@@ -24,6 +24,7 @@
# if __GNUC_PREREQ (4, 6)
# pragma GCC diagnostic ignored "-Wsuggest-attribute=pure"
+# pragma GCC diagnostic ignored "-Wvla"
# endif
# if __GNUC_PREREQ (4, 3)
# pragma GCC diagnostic ignored "-Wold-style-definition"
diff --git a/lib/regex.h b/lib/regex.h
index d291e38793e..adb69768ee5 100644
--- a/lib/regex.h
+++ b/lib/regex.h
@@ -4,16 +4,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
@@ -522,6 +522,30 @@ typedef struct
/* Declarations for routines. */
+#ifndef _REGEX_NELTS
+# if (defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__ \
+ && !defined __STDC_NO_VLA__)
+# define _REGEX_NELTS(n) n
+# else
+# define _REGEX_NELTS(n)
+# endif
+#endif
+
+#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wvla"
+#endif
+
+#ifndef _Attr_access_
+# ifdef __attr_access
+# define _Attr_access_(arg) __attr_access (arg)
+# elif defined __GNUC__ && 10 <= __GNUC__
+# define _Attr_access_(x) __attribute__ ((__access__ x))
+# else
+# define _Attr_access_(x)
+# endif
+#endif
+
#ifdef __USE_GNU
/* Sets the current default syntax to SYNTAX, and return the old syntax.
You can also simply assign to the 're_syntax_options' variable. */
@@ -536,7 +560,8 @@ extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax);
'regcomp', with a malloc'ed value, or set to NULL before calling
'regfree'. */
extern const char *re_compile_pattern (const char *__pattern, size_t __length,
- struct re_pattern_buffer *__buffer);
+ struct re_pattern_buffer *__buffer)
+ _Attr_access_ ((__read_only__, 1, 2));
/* Compile a fastmap for the compiled pattern in BUFFER; used to
@@ -553,7 +578,8 @@ extern int re_compile_fastmap (struct re_pattern_buffer *__buffer);
extern regoff_t re_search (struct re_pattern_buffer *__buffer,
const char *__String, regoff_t __length,
regoff_t __start, regoff_t __range,
- struct re_registers *__regs);
+ struct re_registers *__regs)
+ _Attr_access_ ((__read_only__, 2, 3));
/* Like 're_search', but search in the concatenation of STRING1 and
@@ -563,14 +589,17 @@ extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer,
const char *__string2, regoff_t __length2,
regoff_t __start, regoff_t __range,
struct re_registers *__regs,
- regoff_t __stop);
+ regoff_t __stop)
+ _Attr_access_ ((__read_only__, 2, 3))
+ _Attr_access_ ((__read_only__, 4, 5));
/* Like 're_search', but return how many characters in STRING the regexp
in BUFFER matched, starting at position START. */
extern regoff_t re_match (struct re_pattern_buffer *__buffer,
const char *__String, regoff_t __length,
- regoff_t __start, struct re_registers *__regs);
+ regoff_t __start, struct re_registers *__regs)
+ _Attr_access_ ((__read_only__, 2, 3));
/* Relates to 're_match' as 're_search_2' relates to 're_search'. */
@@ -578,7 +607,9 @@ extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer,
const char *__string1, regoff_t __length1,
const char *__string2, regoff_t __length2,
regoff_t __start, struct re_registers *__regs,
- regoff_t __stop);
+ regoff_t __stop)
+ _Attr_access_ ((__read_only__, 2, 3))
+ _Attr_access_ ((__read_only__, 4, 5));
/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
@@ -647,14 +678,19 @@ extern int regcomp (regex_t *_Restrict_ __preg,
extern int regexec (const regex_t *_Restrict_ __preg,
const char *_Restrict_ __String, size_t __nmatch,
- regmatch_t __pmatch[_Restrict_arr_],
+ regmatch_t __pmatch[_Restrict_arr_
+ _REGEX_NELTS (__nmatch)],
int __eflags);
extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg,
- char *_Restrict_ __errbuf, size_t __errbuf_size);
+ char *_Restrict_ __errbuf, size_t __errbuf_size)
+ _Attr_access_ ((__write_only__, 3, 4));
extern void regfree (regex_t *__preg);
+#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
+# pragma GCC diagnostic pop
+#endif
#ifdef __cplusplus
}
diff --git a/lib/regex_internal.c b/lib/regex_internal.c
index 73087c8610e..aefcfa2f52e 100644
--- a/lib/regex_internal.c
+++ b/lib/regex_internal.c
@@ -4,16 +4,16 @@
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
@@ -1211,6 +1211,10 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
if (__glibc_unlikely (dest->nelem == 0))
{
+ /* Although we already guaranteed above that dest->alloc != 0 and
+ therefore dest->elems != NULL, add a debug assertion to pacify
+ GCC 11.2.1's -fanalyzer. */
+ DEBUG_ASSERT (dest->elems);
dest->nelem = src->nelem;
memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));
return REG_NOERROR;
@@ -1286,7 +1290,10 @@ re_node_set_insert (re_node_set *set, Idx elem)
if (__glibc_unlikely (set->nelem) == 0)
{
- /* We already guaranteed above that set->alloc != 0. */
+ /* Although we already guaranteed above that set->alloc != 0 and
+ therefore set->elems != NULL, add a debug assertion to pacify
+ GCC 11.2 -fanalyzer. */
+ DEBUG_ASSERT (set->elems);
set->elems[0] = elem;
++set->nelem;
return true;
@@ -1314,6 +1321,7 @@ re_node_set_insert (re_node_set *set, Idx elem)
{
for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
set->elems[idx] = set->elems[idx - 1];
+ DEBUG_ASSERT (set->elems[idx - 1] < elem);
}
/* Insert the new element. */
diff --git a/lib/regex_internal.h b/lib/regex_internal.h
index 4c634edcbfa..1245e782ffc 100644
--- a/lib/regex_internal.h
+++ b/lib/regex_internal.h
@@ -4,16 +4,16 @@
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
@@ -32,7 +32,10 @@
#include <stdbool.h>
#include <stdint.h>
-#include <dynarray.h>
+#ifndef _LIBC
+# include <dynarray.h>
+#endif
+
#include <intprops.h>
#include <verify.h>
@@ -50,14 +53,14 @@
# define lock_fini(lock) ((void) 0)
# define lock_lock(lock) __libc_lock_lock (lock)
# define lock_unlock(lock) __libc_lock_unlock (lock)
-#elif defined GNULIB_LOCK && !defined USE_UNLOCKED_IO
+#elif defined GNULIB_LOCK && !defined GNULIB_REGEX_SINGLE_THREAD
# include "glthread/lock.h"
# define lock_define(name) gl_lock_define (, name)
# define lock_init(lock) glthread_lock_init (&(lock))
# define lock_fini(lock) glthread_lock_destroy (&(lock))
# define lock_lock(lock) glthread_lock_lock (&(lock))
# define lock_unlock(lock) glthread_lock_unlock (&(lock))
-#elif defined GNULIB_PTHREAD && !defined USE_UNLOCKED_IO
+#elif defined GNULIB_PTHREAD && !defined GNULIB_REGEX_SINGLE_THREAD
# include <pthread.h>
# define lock_define(name) pthread_mutex_t name;
# define lock_init(lock) pthread_mutex_init (&(lock), 0)
diff --git a/lib/regexec.c b/lib/regexec.c
index 15dc57bd0e6..83e9aaf8cad 100644
--- a/lib/regexec.c
+++ b/lib/regexec.c
@@ -4,16 +4,16 @@
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
@@ -59,7 +59,7 @@ static void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,
Idx cur_idx, Idx nmatch);
static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs,
Idx str_idx, Idx dest_node, Idx nregs,
- regmatch_t *regs,
+ regmatch_t *regs, regmatch_t *prevregs,
re_node_set *eps_via_nodes);
static reg_errcode_t set_regs (const regex_t *preg,
const re_match_context_t *mctx,
@@ -186,11 +186,12 @@ static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len);
REG_NOTBOL is set, then ^ does not match at the beginning of the
string; if REG_NOTEOL is set, then $ does not match at the end.
- We return 0 if we find a match and REG_NOMATCH if not. */
+ Return 0 if a match is found, REG_NOMATCH if not, REG_BADPAT if
+ EFLAGS is invalid. */
int
regexec (const regex_t *__restrict preg, const char *__restrict string,
- size_t nmatch, regmatch_t pmatch[], int eflags)
+ size_t nmatch, regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags)
{
reg_errcode_t err;
Idx start, length;
@@ -234,7 +235,7 @@ int
attribute_compat_text_section
__compat_regexec (const regex_t *__restrict preg,
const char *__restrict string, size_t nmatch,
- regmatch_t pmatch[], int eflags)
+ regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags)
{
return regexec (preg, string, nmatch, pmatch,
eflags & (REG_NOTBOL | REG_NOTEOL));
@@ -269,8 +270,8 @@ compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
strings.)
On success, re_match* functions return the length of the match, re_search*
- return the position of the start of the match. Return value -1 means no
- match was found and -2 indicates an internal error. */
+ return the position of the start of the match. They return -1 on
+ match failure, -2 on error. */
regoff_t
re_match (struct re_pattern_buffer *bufp, const char *string, Idx length,
@@ -1206,27 +1207,30 @@ check_halt_state_context (const re_match_context_t *mctx,
/* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA
corresponding to the DFA).
Return the destination node, and update EPS_VIA_NODES;
- return -1 in case of errors. */
+ return -1 on match failure, -2 on error. */
static Idx
proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
+ regmatch_t *prevregs,
Idx *pidx, Idx node, re_node_set *eps_via_nodes,
struct re_fail_stack_t *fs)
{
const re_dfa_t *const dfa = mctx->dfa;
- Idx i;
- bool ok;
if (IS_EPSILON_NODE (dfa->nodes[node].type))
{
re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes;
re_node_set *edests = &dfa->edests[node];
- Idx dest_node;
- ok = re_node_set_insert (eps_via_nodes, node);
- if (__glibc_unlikely (! ok))
- return -2;
- /* Pick up a valid destination, or return -1 if none
- is found. */
- for (dest_node = -1, i = 0; i < edests->nelem; ++i)
+
+ if (! re_node_set_contains (eps_via_nodes, node))
+ {
+ bool ok = re_node_set_insert (eps_via_nodes, node);
+ if (__glibc_unlikely (! ok))
+ return -2;
+ }
+
+ /* Pick a valid destination, or return -1 if none is found. */
+ Idx dest_node = -1;
+ for (Idx i = 0; i < edests->nelem; i++)
{
Idx candidate = edests->elems[i];
if (!re_node_set_contains (cur_nodes, candidate))
@@ -1244,7 +1248,7 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
/* Otherwise, push the second epsilon-transition on the fail stack. */
else if (fs != NULL
&& push_fail_stack (fs, *pidx, candidate, nregs, regs,
- eps_via_nodes))
+ prevregs, eps_via_nodes))
return -2;
/* We know we are going to exit. */
@@ -1288,7 +1292,7 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
if (naccepted == 0)
{
Idx dest_node;
- ok = re_node_set_insert (eps_via_nodes, node);
+ bool ok = re_node_set_insert (eps_via_nodes, node);
if (__glibc_unlikely (! ok))
return -2;
dest_node = dfa->edests[node].elems[0];
@@ -1317,7 +1321,8 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
static reg_errcode_t
__attribute_warn_unused_result__
push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node,
- Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes)
+ Idx nregs, regmatch_t *regs, regmatch_t *prevregs,
+ re_node_set *eps_via_nodes)
{
reg_errcode_t err;
Idx num = fs->num++;
@@ -1333,25 +1338,30 @@ push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node,
}
fs->stack[num].idx = str_idx;
fs->stack[num].node = dest_node;
- fs->stack[num].regs = re_malloc (regmatch_t, nregs);
+ fs->stack[num].regs = re_malloc (regmatch_t, 2 * nregs);
if (fs->stack[num].regs == NULL)
return REG_ESPACE;
memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);
+ memcpy (fs->stack[num].regs + nregs, prevregs, sizeof (regmatch_t) * nregs);
err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes);
return err;
}
static Idx
pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs,
- regmatch_t *regs, re_node_set *eps_via_nodes)
+ regmatch_t *regs, regmatch_t *prevregs,
+ re_node_set *eps_via_nodes)
{
+ if (fs == NULL || fs->num == 0)
+ return -1;
Idx num = --fs->num;
- DEBUG_ASSERT (num >= 0);
*pidx = fs->stack[num].idx;
memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);
+ memcpy (prevregs, fs->stack[num].regs + nregs, sizeof (regmatch_t) * nregs);
re_node_set_free (eps_via_nodes);
re_free (fs->stack[num].regs);
*eps_via_nodes = fs->stack[num].eps_via_nodes;
+ DEBUG_ASSERT (0 <= fs->stack[num].node);
return fs->stack[num].node;
}
@@ -1407,33 +1417,32 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
{
update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch);
- if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
+ if ((idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
+ || (fs && re_node_set_contains (&eps_via_nodes, cur_node)))
{
Idx reg_idx;
+ cur_node = -1;
if (fs)
{
for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1)
- break;
- if (reg_idx == nmatch)
- {
- re_node_set_free (&eps_via_nodes);
- regmatch_list_free (&prev_match);
- return free_fail_stack_return (fs);
- }
- cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
- &eps_via_nodes);
+ {
+ cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
+ prev_idx_match, &eps_via_nodes);
+ break;
+ }
}
- else
+ if (cur_node < 0)
{
re_node_set_free (&eps_via_nodes);
regmatch_list_free (&prev_match);
- return REG_NOERROR;
+ return free_fail_stack_return (fs);
}
}
/* Proceed to next node. */
- cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node,
+ cur_node = proceed_next_node (mctx, nmatch, pmatch, prev_idx_match,
+ &idx, cur_node,
&eps_via_nodes, fs);
if (__glibc_unlikely (cur_node < 0))
@@ -1445,13 +1454,13 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
free_fail_stack_return (fs);
return REG_ESPACE;
}
- if (fs)
- cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
- &eps_via_nodes);
- else
+ cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
+ prev_idx_match, &eps_via_nodes);
+ if (cur_node < 0)
{
re_node_set_free (&eps_via_nodes);
regmatch_list_free (&prev_match);
+ free_fail_stack_return (fs);
return REG_NOMATCH;
}
}
@@ -1495,10 +1504,10 @@ update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,
}
else if (type == OP_CLOSE_SUBEXP)
{
+ /* We are at the last node of this sub expression. */
Idx reg_num = dfa->nodes[cur_node].opr.idx + 1;
if (reg_num < nmatch)
{
- /* We are at the last node of this sub expression. */
if (pmatch[reg_num].rm_so < cur_idx)
{
pmatch[reg_num].rm_eo = cur_idx;
@@ -2195,6 +2204,7 @@ sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx,
/* Return the next state to which the current state STATE will transit by
accepting the current input byte, and update STATE_LOG if necessary.
+ Return NULL on failure.
If STATE can accept a multibyte char/collating element/back reference
update the destination of STATE_LOG. */
@@ -2395,7 +2405,7 @@ check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes,
#if 0
/* Return the next state to which the current state STATE will transit by
- accepting the current input byte. */
+ accepting the current input byte. Return NULL on failure. */
static re_dfastate_t *
transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx,
@@ -2817,7 +2827,8 @@ find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
/* Check whether the node TOP_NODE at TOP_STR can arrive to the node
LAST_NODE at LAST_STR. We record the path onto PATH since it will be
heavily reused.
- Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise. */
+ Return REG_NOERROR if it can arrive, REG_NOMATCH if it cannot,
+ REG_ESPACE if memory is exhausted. */
static reg_errcode_t
__attribute_warn_unused_result__
@@ -3433,7 +3444,8 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
/* Group all nodes belonging to STATE into several destinations.
Then for all destinations, set the nodes belonging to the destination
to DESTS_NODE[i] and set the characters accepted by the destination
- to DEST_CH[i]. This function return the number of destinations. */
+ to DEST_CH[i]. Return the number of destinations if successful,
+ -1 on internal error. */
static Idx
group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
@@ -4211,7 +4223,8 @@ match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx)
}
/* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches
- at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP. */
+ at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP.
+ Return the new entry if successful, NULL if memory is exhausted. */
static re_sub_match_last_t *
match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx)
diff --git a/lib/root-uid.h b/lib/root-uid.h
index cb74a49c1bb..b367d5ab69c 100644
--- a/lib/root-uid.h
+++ b/lib/root-uid.h
@@ -2,20 +2,20 @@
Copyright 2012-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>.
+ 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/>. */
- Written by Paul Eggert. */
+/* Written by Paul Eggert. */
#ifndef ROOT_UID_H_
#define ROOT_UID_H_
diff --git a/lib/save-cwd.h b/lib/save-cwd.h
index e1e69eceaf5..3cefba58c0a 100644
--- a/lib/save-cwd.h
+++ b/lib/save-cwd.h
@@ -1,7 +1,7 @@
/* Save and restore current working directory.
- Copyright (C) 1995, 1997-1998, 2003, 2009-2021 Free Software
- Foundation, Inc.
+ Copyright (C) 1995, 1997-1998, 2003, 2009-2021 Free Software Foundation,
+ Inc.
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
diff --git a/lib/scratch_buffer.h b/lib/scratch_buffer.h
index 603b0d65d0a..88735771d2d 100644
--- a/lib/scratch_buffer.h
+++ b/lib/scratch_buffer.h
@@ -1,17 +1,17 @@
/* Variable-sized buffer with on-stack default allocation.
Copyright (C) 2017-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Paul Eggert, 2017. */
@@ -19,12 +19,109 @@
#ifndef _GL_SCRATCH_BUFFER_H
#define _GL_SCRATCH_BUFFER_H
-#include <libc-config.h>
+/* Scratch buffers with a default stack allocation and fallback to
+ heap allocation. It is expected that this function is used in this
+ way:
+ struct scratch_buffer tmpbuf;
+ scratch_buffer_init (&tmpbuf);
+
+ while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length))
+ if (!scratch_buffer_grow (&tmpbuf))
+ return -1;
+
+ scratch_buffer_free (&tmpbuf);
+ return 0;
+
+ The allocation functions (scratch_buffer_grow,
+ scratch_buffer_grow_preserve, scratch_buffer_set_array_size) make
+ sure that the heap allocation, if any, is freed, so that the code
+ above does not have a memory leak. The buffer still remains in a
+ state that can be deallocated using scratch_buffer_free, so a loop
+ like this is valid as well:
+
+ struct scratch_buffer tmpbuf;
+ scratch_buffer_init (&tmpbuf);
+
+ while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length))
+ if (!scratch_buffer_grow (&tmpbuf))
+ break;
+
+ scratch_buffer_free (&tmpbuf);
+
+ scratch_buffer_grow and scratch_buffer_grow_preserve are guaranteed
+ to grow the buffer by at least 512 bytes. This means that when
+ using the scratch buffer as a backing store for a non-character
+ array whose element size, in bytes, is 512 or smaller, the scratch
+ buffer only has to grow once to make room for at least one more
+ element.
+*/
+
+/* Scratch buffer. Must be initialized with scratch_buffer_init
+ before its use. */
+struct scratch_buffer;
+
+/* Initializes *BUFFER so that BUFFER->data points to BUFFER->__space
+ and BUFFER->length reflects the available space. */
+#if 0
+extern void scratch_buffer_init (struct scratch_buffer *buffer);
+#endif
+
+/* Deallocates *BUFFER (if it was heap-allocated). */
+#if 0
+extern void scratch_buffer_free (struct scratch_buffer *buffer);
+#endif
+
+/* Grow *BUFFER by some arbitrary amount. The buffer contents is NOT
+ preserved. Return true on success, false on allocation failure (in
+ which case the old buffer is freed). On success, the new buffer is
+ larger than the previous size. On failure, *BUFFER is deallocated,
+ but remains in a free-able state, and errno is set. */
+#if 0
+extern bool scratch_buffer_grow (struct scratch_buffer *buffer);
+#endif
+
+/* Like scratch_buffer_grow, but preserve the old buffer
+ contents on success, as a prefix of the new buffer. */
+#if 0
+extern bool scratch_buffer_grow_preserve (struct scratch_buffer *buffer);
+#endif
+
+/* Grow *BUFFER so that it can store at least NELEM elements of SIZE
+ bytes. The buffer contents are NOT preserved. Both NELEM and SIZE
+ can be zero. Return true on success, false on allocation failure
+ (in which case the old buffer is freed, but *BUFFER remains in a
+ free-able state, and errno is set). It is unspecified whether this
+ function can reduce the array size. */
+#if 0
+extern bool scratch_buffer_set_array_size (struct scratch_buffer *buffer,
+ size_t nelem, size_t size);
+#endif
+
+/* Return a copy of *BUFFER's first SIZE bytes as a heap-allocated block,
+ deallocating *BUFFER if it was heap-allocated. SIZE must be at
+ most *BUFFER's size. Return NULL (setting errno) on memory
+ exhaustion. */
+#if 0
+extern void *scratch_buffer_dupfree (struct scratch_buffer *buffer,
+ size_t size);
+#endif
+
+
+/* The implementation is imported from glibc. */
+
+/* Avoid possible conflicts with symbols exported by the GNU libc. */
#define __libc_scratch_buffer_dupfree gl_scratch_buffer_dupfree
#define __libc_scratch_buffer_grow gl_scratch_buffer_grow
#define __libc_scratch_buffer_grow_preserve gl_scratch_buffer_grow_preserve
#define __libc_scratch_buffer_set_array_size gl_scratch_buffer_set_array_size
-#include <malloc/scratch_buffer.h>
+
+#ifndef _GL_LIKELY
+/* Rely on __builtin_expect, as provided by the module 'builtin-expect'. */
+# define _GL_LIKELY(cond) __builtin_expect ((cond), 1)
+# define _GL_UNLIKELY(cond) __builtin_expect ((cond), 0)
+#endif
+
+#include <malloc/scratch_buffer.gl.h>
#endif /* _GL_SCRATCH_BUFFER_H */
diff --git a/lib/set-permissions.c b/lib/set-permissions.c
index 607983cb93d..5c837f12387 100644
--- a/lib/set-permissions.c
+++ b/lib/set-permissions.c
@@ -775,7 +775,7 @@ chmod_or_fchmod (const char *name, int desc, mode_t mode)
int
set_permissions (struct permission_context *ctx, const char *name, int desc)
{
- bool acls_set _GL_UNUSED = false;
+ _GL_UNUSED bool acls_set = false;
bool early_chmod;
bool must_chmod = false;
int ret = 0;
diff --git a/lib/sha1.c b/lib/sha1.c
index 612d46de827..52b10203194 100644
--- a/lib/sha1.c
+++ b/lib/sha1.c
@@ -3,18 +3,18 @@
Copyright (C) 2000-2001, 2003-2006, 2008-2021 Free Software Foundation, Inc.
- 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, or (at your option) any
- later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
/* Written by Scott G. Miller
Credits:
@@ -23,6 +23,7 @@
#include <config.h>
+/* Specification. */
#if HAVE_OPENSSL_SHA1
# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE
#endif
@@ -30,13 +31,8 @@
#include <stdalign.h>
#include <stdint.h>
-#include <stdlib.h>
#include <string.h>
-#if USE_UNLOCKED_IO
-# include "unlocked-io.h"
-#endif
-
#include <byteswap.h>
#ifdef WORDS_BIGENDIAN
# define SWAP(n) (n)
@@ -44,12 +40,8 @@
# define SWAP(n) bswap_32 (n)
#endif
-#define BLOCKSIZE 32768
-#if BLOCKSIZE % 64 != 0
-# error "invalid BLOCKSIZE"
-#endif
-
#if ! HAVE_OPENSSL_SHA1
+
/* This array contains the bytes used to pad the buffer to the next
64-byte boundary. (RFC 1321, 3.1: Step 1) */
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
@@ -120,93 +112,7 @@ sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
return sha1_read_ctx (ctx, resbuf);
}
-#endif
-
-#ifdef GL_COMPILE_CRYPTO_STREAM
-
-#include "af_alg.h"
-/* Compute SHA1 message digest for bytes read from STREAM. The
- resulting message digest number will be written into the 20 bytes
- beginning at RESBLOCK. */
-int
-sha1_stream (FILE *stream, void *resblock)
-{
- switch (afalg_stream (stream, "sha1", resblock, SHA1_DIGEST_SIZE))
- {
- case 0: return 0;
- case -EIO: return 1;
- }
-
- char *buffer = malloc (BLOCKSIZE + 72);
- if (!buffer)
- return 1;
-
- struct sha1_ctx ctx;
- sha1_init_ctx (&ctx);
- size_t sum;
-
- /* Iterate over full file contents. */
- while (1)
- {
- /* We read the file in blocks of BLOCKSIZE bytes. One call of the
- computation function processes the whole buffer so that with the
- next round of the loop another block can be read. */
- size_t n;
- sum = 0;
-
- /* Read block. Take care for partial reads. */
- while (1)
- {
- /* Either process a partial fread() from this loop,
- or the fread() in afalg_stream may have gotten EOF.
- We need to avoid a subsequent fread() as EOF may
- not be sticky. For details of such systems, see:
- https://sourceware.org/bugzilla/show_bug.cgi?id=1190 */
- if (feof (stream))
- goto process_partial_block;
-
- n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
-
- sum += n;
-
- if (sum == BLOCKSIZE)
- break;
-
- if (n == 0)
- {
- /* Check for the error flag IFF N == 0, so that we don't
- exit the loop after a partial read due to e.g., EAGAIN
- or EWOULDBLOCK. */
- if (ferror (stream))
- {
- free (buffer);
- return 1;
- }
- goto process_partial_block;
- }
- }
-
- /* Process buffer with BLOCKSIZE bytes. Note that
- BLOCKSIZE % 64 == 0
- */
- sha1_process_block (buffer, BLOCKSIZE, &ctx);
- }
-
- process_partial_block:;
-
- /* Process any remaining bytes. */
- if (sum > 0)
- sha1_process_bytes (buffer, sum, &ctx);
-
- /* Construct result in desired memory. */
- sha1_finish_ctx (&ctx, resblock);
- free (buffer);
- return 0;
-}
-#endif
-
-#if ! HAVE_OPENSSL_SHA1
/* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message
@@ -444,6 +350,7 @@ sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx)
e = ctx->E += e;
}
}
+
#endif
/*
diff --git a/lib/sha1.h b/lib/sha1.h
index 94ccd18fda5..e12a23cd4d7 100644
--- a/lib/sha1.h
+++ b/lib/sha1.h
@@ -3,18 +3,18 @@
Copyright (C) 2000-2001, 2003, 2005-2006, 2008-2021 Free Software
Foundation, Inc.
- 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, or (at your option) any
- later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
#ifndef SHA1_H
# define SHA1_H 1
@@ -30,7 +30,7 @@
extern "C" {
# endif
-#define SHA1_DIGEST_SIZE 20
+# define SHA1_DIGEST_SIZE 20
# if HAVE_OPENSSL_SHA1
# define GL_OPENSSL_NAME 1
@@ -88,6 +88,7 @@ extern void *sha1_buffer (const char *buffer, size_t len,
void *restrict resblock);
# endif
+
/* Compute SHA1 message digest for bytes read from STREAM.
STREAM is an open file stream. Regular files are handled more efficiently.
The contents of STREAM from its current position to its end will be read.
diff --git a/lib/sha256.c b/lib/sha256.c
index 129d64b174b..2b8687f1db5 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -3,17 +3,17 @@
Copyright (C) 2005-2006, 2008-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by David Madore, considerably copypasting from
@@ -22,6 +22,7 @@
#include <config.h>
+/* Specification. */
#if HAVE_OPENSSL_SHA256
# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE
#endif
@@ -29,13 +30,8 @@
#include <stdalign.h>
#include <stdint.h>
-#include <stdlib.h>
#include <string.h>
-#if USE_UNLOCKED_IO
-# include "unlocked-io.h"
-#endif
-
#include <byteswap.h>
#ifdef WORDS_BIGENDIAN
# define SWAP(n) (n)
@@ -43,12 +39,8 @@
# define SWAP(n) bswap_32 (n)
#endif
-#define BLOCKSIZE 32768
-#if BLOCKSIZE % 64 != 0
-# error "invalid BLOCKSIZE"
-#endif
-
#if ! HAVE_OPENSSL_SHA256
+
/* This array contains the bytes used to pad the buffer to the next
64-byte boundary. */
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
@@ -167,110 +159,7 @@ sha224_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
sha256_conclude_ctx (ctx);
return sha224_read_ctx (ctx, resbuf);
}
-#endif
-
-#ifdef GL_COMPILE_CRYPTO_STREAM
-
-#include "af_alg.h"
-
-/* Compute message digest for bytes read from STREAM using algorithm ALG.
- Write the message digest into RESBLOCK, which contains HASHLEN bytes.
- The initial and finishing operations are INIT_CTX and FINISH_CTX.
- Return zero if and only if successful. */
-static int
-shaxxx_stream (FILE *stream, char const *alg, void *resblock,
- ssize_t hashlen, void (*init_ctx) (struct sha256_ctx *),
- void *(*finish_ctx) (struct sha256_ctx *, void *))
-{
- switch (afalg_stream (stream, alg, resblock, hashlen))
- {
- case 0: return 0;
- case -EIO: return 1;
- }
-
- char *buffer = malloc (BLOCKSIZE + 72);
- if (!buffer)
- return 1;
-
- struct sha256_ctx ctx;
- init_ctx (&ctx);
- size_t sum;
-
- /* Iterate over full file contents. */
- while (1)
- {
- /* We read the file in blocks of BLOCKSIZE bytes. One call of the
- computation function processes the whole buffer so that with the
- next round of the loop another block can be read. */
- size_t n;
- sum = 0;
-
- /* Read block. Take care for partial reads. */
- while (1)
- {
- /* Either process a partial fread() from this loop,
- or the fread() in afalg_stream may have gotten EOF.
- We need to avoid a subsequent fread() as EOF may
- not be sticky. For details of such systems, see:
- https://sourceware.org/bugzilla/show_bug.cgi?id=1190 */
- if (feof (stream))
- goto process_partial_block;
-
- n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
-
- sum += n;
-
- if (sum == BLOCKSIZE)
- break;
-
- if (n == 0)
- {
- /* Check for the error flag IFF N == 0, so that we don't
- exit the loop after a partial read due to e.g., EAGAIN
- or EWOULDBLOCK. */
- if (ferror (stream))
- {
- free (buffer);
- return 1;
- }
- goto process_partial_block;
- }
- }
-
- /* Process buffer with BLOCKSIZE bytes. Note that
- BLOCKSIZE % 64 == 0
- */
- sha256_process_block (buffer, BLOCKSIZE, &ctx);
- }
-
- process_partial_block:;
-
- /* Process any remaining bytes. */
- if (sum > 0)
- sha256_process_bytes (buffer, sum, &ctx);
-
- /* Construct result in desired memory. */
- finish_ctx (&ctx, resblock);
- free (buffer);
- return 0;
-}
-int
-sha256_stream (FILE *stream, void *resblock)
-{
- return shaxxx_stream (stream, "sha256", resblock, SHA256_DIGEST_SIZE,
- sha256_init_ctx, sha256_finish_ctx);
-}
-
-int
-sha224_stream (FILE *stream, void *resblock)
-{
- return shaxxx_stream (stream, "sha224", resblock, SHA224_DIGEST_SIZE,
- sha224_init_ctx, sha224_finish_ctx);
-}
-#endif
-
-#if ! HAVE_OPENSSL_SHA256
/* Compute SHA256 message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message
@@ -533,6 +422,7 @@ sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx)
h = ctx->state[7] += h;
}
}
+
#endif
/*
diff --git a/lib/sha256.h b/lib/sha256.h
index b4bc082267a..e09b3de8077 100644
--- a/lib/sha256.h
+++ b/lib/sha256.h
@@ -2,17 +2,17 @@
library functions.
Copyright (C) 2005-2006, 2008-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
#ifndef SHA256_H
@@ -93,6 +93,7 @@ extern void *sha224_buffer (const char *buffer, size_t len,
void *restrict resblock);
# endif
+
/* Compute SHA256 (SHA224) message digest for bytes read from STREAM.
STREAM is an open file stream. Regular files are handled more efficiently.
The contents of STREAM from its current position to its end will be read.
diff --git a/lib/sha512.c b/lib/sha512.c
index 4ac3fa3e42d..2865d6e588d 100644
--- a/lib/sha512.c
+++ b/lib/sha512.c
@@ -3,17 +3,17 @@
Copyright (C) 2005-2006, 2008-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by David Madore, considerably copypasting from
@@ -22,6 +22,7 @@
#include <config.h>
+/* Specification. */
#if HAVE_OPENSSL_SHA512
# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE
#endif
@@ -29,13 +30,8 @@
#include <stdalign.h>
#include <stdint.h>
-#include <stdlib.h>
#include <string.h>
-#if USE_UNLOCKED_IO
-# include "unlocked-io.h"
-#endif
-
#include <byteswap.h>
#ifdef WORDS_BIGENDIAN
# define SWAP(n) (n)
@@ -43,12 +39,8 @@
# define SWAP(n) bswap_64 (n)
#endif
-#define BLOCKSIZE 32768
-#if BLOCKSIZE % 128 != 0
-# error "invalid BLOCKSIZE"
-#endif
-
#if ! HAVE_OPENSSL_SHA512
+
/* This array contains the bytes used to pad the buffer to the next
128-byte boundary. */
static const unsigned char fillbuf[128] = { 0x80, 0 /* , 0, 0, ... */ };
@@ -168,110 +160,7 @@ sha384_finish_ctx (struct sha512_ctx *ctx, void *resbuf)
sha512_conclude_ctx (ctx);
return sha384_read_ctx (ctx, resbuf);
}
-#endif
-
-#ifdef GL_COMPILE_CRYPTO_STREAM
-
-#include "af_alg.h"
-
-/* Compute message digest for bytes read from STREAM using algorithm ALG.
- Write the message digest into RESBLOCK, which contains HASHLEN bytes.
- The initial and finishing operations are INIT_CTX and FINISH_CTX.
- Return zero if and only if successful. */
-static int
-shaxxx_stream (FILE *stream, char const *alg, void *resblock,
- ssize_t hashlen, void (*init_ctx) (struct sha512_ctx *),
- void *(*finish_ctx) (struct sha512_ctx *, void *))
-{
- switch (afalg_stream (stream, alg, resblock, hashlen))
- {
- case 0: return 0;
- case -EIO: return 1;
- }
-
- char *buffer = malloc (BLOCKSIZE + 72);
- if (!buffer)
- return 1;
-
- struct sha512_ctx ctx;
- init_ctx (&ctx);
- size_t sum;
-
- /* Iterate over full file contents. */
- while (1)
- {
- /* We read the file in blocks of BLOCKSIZE bytes. One call of the
- computation function processes the whole buffer so that with the
- next round of the loop another block can be read. */
- size_t n;
- sum = 0;
-
- /* Read block. Take care for partial reads. */
- while (1)
- {
- /* Either process a partial fread() from this loop,
- or the fread() in afalg_stream may have gotten EOF.
- We need to avoid a subsequent fread() as EOF may
- not be sticky. For details of such systems, see:
- https://sourceware.org/bugzilla/show_bug.cgi?id=1190 */
- if (feof (stream))
- goto process_partial_block;
-
- n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
-
- sum += n;
-
- if (sum == BLOCKSIZE)
- break;
-
- if (n == 0)
- {
- /* Check for the error flag IFF N == 0, so that we don't
- exit the loop after a partial read due to e.g., EAGAIN
- or EWOULDBLOCK. */
- if (ferror (stream))
- {
- free (buffer);
- return 1;
- }
- goto process_partial_block;
- }
- }
-
- /* Process buffer with BLOCKSIZE bytes. Note that
- BLOCKSIZE % 128 == 0
- */
- sha512_process_block (buffer, BLOCKSIZE, &ctx);
- }
-
- process_partial_block:;
-
- /* Process any remaining bytes. */
- if (sum > 0)
- sha512_process_bytes (buffer, sum, &ctx);
-
- /* Construct result in desired memory. */
- finish_ctx (&ctx, resblock);
- free (buffer);
- return 0;
-}
-int
-sha512_stream (FILE *stream, void *resblock)
-{
- return shaxxx_stream (stream, "sha512", resblock, SHA512_DIGEST_SIZE,
- sha512_init_ctx, sha512_finish_ctx);
-}
-
-int
-sha384_stream (FILE *stream, void *resblock)
-{
- return shaxxx_stream (stream, "sha384", resblock, SHA384_DIGEST_SIZE,
- sha384_init_ctx, sha384_finish_ctx);
-}
-#endif
-
-#if ! HAVE_OPENSSL_SHA512
/* Compute SHA512 message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message
@@ -578,6 +467,7 @@ sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx)
h = ctx->state[7] = u64plus (ctx->state[7], h);
}
}
+
#endif
/*
diff --git a/lib/sha512.h b/lib/sha512.h
index 81b53034c7e..e15afe996ed 100644
--- a/lib/sha512.h
+++ b/lib/sha512.h
@@ -2,17 +2,17 @@
library functions.
Copyright (C) 2005-2006, 2008-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
#ifndef SHA512_H
@@ -96,6 +96,7 @@ extern void *sha384_buffer (const char *buffer, size_t len,
void *restrict resblock);
# endif
+
/* Compute SHA512 (SHA384) message digest for bytes read from STREAM.
STREAM is an open file stream. Regular files are handled more efficiently.
The contents of STREAM from its current position to its end will be read.
diff --git a/lib/sigdescr_np.c b/lib/sigdescr_np.c
index 6c9bf283a8d..bf6abe55c45 100644
--- a/lib/sigdescr_np.c
+++ b/lib/sigdescr_np.c
@@ -1,17 +1,17 @@
/* English descriptions of signals.
Copyright (C) 2020-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Bruno Haible <bruno@clisp.org>, 2020. */
@@ -189,7 +189,7 @@ sigdescr_np (int sig)
return "Instruction emulation needed";
#endif
/* Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix */
- #if defined SIGINFO
+ #if defined SIGINFO && SIGINFO != SIGPWR
case SIGINFO:
return "Information request";
#endif
diff --git a/lib/signal.in.h b/lib/signal.in.h
index ed01d672c9d..275da8c817d 100644
--- a/lib/signal.in.h
+++ b/lib/signal.in.h
@@ -2,17 +2,17 @@
Copyright (C) 2006-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
#if __GNUC__ >= 3
diff --git a/lib/stat-time.c b/lib/stat-time.c
index 81b83ddb4fe..7b927926943 100644
--- a/lib/stat-time.c
+++ b/lib/stat-time.c
@@ -1,3 +1,21 @@
+/* stat-related time functions.
+
+ Copyright (C) 2012-2021 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/>. */
+
#include <config.h>
+
#define _GL_STAT_TIME_INLINE _GL_EXTERN_INLINE
#include "stat-time.h"
diff --git a/lib/stat-time.h b/lib/stat-time.h
index 523ed21b080..6b2cc686ae1 100644
--- a/lib/stat-time.h
+++ b/lib/stat-time.h
@@ -2,17 +2,17 @@
Copyright (C) 2005, 2007, 2009-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Paul Eggert. */
@@ -102,7 +102,7 @@ get_stat_mtime_ns (struct stat const *st)
/* Return the nanosecond component of *ST's birth time. */
_GL_STAT_TIME_INLINE long int _GL_ATTRIBUTE_PURE
-get_stat_birthtime_ns (struct stat const *st _GL_UNUSED)
+get_stat_birthtime_ns (_GL_UNUSED struct stat const *st)
{
# if defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
return STAT_TIMESPEC (st, st_birthtim).tv_nsec;
@@ -158,7 +158,7 @@ get_stat_mtime (struct stat const *st)
/* Return *ST's birth time, if available; otherwise return a value
with tv_sec and tv_nsec both equal to -1. */
_GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE
-get_stat_birthtime (struct stat const *st _GL_UNUSED)
+get_stat_birthtime (_GL_UNUSED struct stat const *st)
{
struct timespec t;
@@ -208,7 +208,7 @@ get_stat_birthtime (struct stat const *st _GL_UNUSED)
errno to EOVERFLOW if normalization overflowed. This function
is intended to be private to this .h file. */
_GL_STAT_TIME_INLINE int
-stat_time_normalize (int result, struct stat *st _GL_UNUSED)
+stat_time_normalize (int result, _GL_UNUSED struct stat *st)
{
#if defined __sun && defined STAT_TIMESPEC
if (result == 0)
diff --git a/lib/stdalign.in.h b/lib/stdalign.in.h
index eae9d132215..592d58e3720 100644
--- a/lib/stdalign.in.h
+++ b/lib/stdalign.in.h
@@ -2,18 +2,18 @@
Copyright 2011-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
/* Written by Paul Eggert and Bruno Haible. */
@@ -104,12 +104,13 @@
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
# if defined __cplusplus && 201103 <= __cplusplus
# define _Alignas(a) alignas (a)
-# elif ((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__)
+# 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))
diff --git a/lib/stddef.in.h b/lib/stddef.in.h
index 0f506a5b18b..42290d448d8 100644
--- a/lib/stddef.in.h
+++ b/lib/stddef.in.h
@@ -2,18 +2,18 @@
Copyright (C) 2009-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
/* Written by Eric Blake. */
@@ -42,6 +42,13 @@
# define _GL_STDDEF_WINT_T
# endif
# @INCLUDE_NEXT@ @NEXT_STDDEF_H@
+ /* On TinyCC, make sure that the macros that indicate the special invocation
+ convention get undefined. */
+# undef __need_wchar_t
+# undef __need_size_t
+# undef __need_ptrdiff_t
+# undef __need_NULL
+# undef __need_wint_t
# endif
#else
@@ -51,7 +58,7 @@
/* On AIX 7.2, with xlc in 64-bit mode, <stddef.h> defines max_align_t to a
type with alignment 4, but 'long' has alignment 8. */
-# if defined _AIX && defined _ARCH_PPC64
+# if defined _AIX && defined __LP64__
# if !GNULIB_defined_max_align_t
# ifdef _MAX_ALIGN_T
/* /usr/include/stddef.h has already defined max_align_t. Override it. */
@@ -109,7 +116,7 @@ typedef long max_align_t;
&& defined __cplusplus
# include <cstddef>
#else
-# if ! (@HAVE_MAX_ALIGN_T@ || defined _GCC_MAX_ALIGN_T)
+# if ! (@HAVE_MAX_ALIGN_T@ || (defined _GCC_MAX_ALIGN_T && !defined __clang__))
# if !GNULIB_defined_max_align_t
/* On the x86, the maximum storage alignment of double, long, etc. is 4,
but GCC's C11 ABI for x86 says that max_align_t has an alignment of 8,
diff --git a/lib/stdint.in.h b/lib/stdint.in.h
index 7a8f27cef7e..85c5418f14a 100644
--- a/lib/stdint.in.h
+++ b/lib/stdint.in.h
@@ -2,18 +2,18 @@
Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood.
This file is part of gnulib.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
/*
* ISO C 99 <stdint.h> for platforms that lack it.
@@ -85,7 +85,7 @@
/* Override WINT_MIN and WINT_MAX if gnulib's <wchar.h> or <wctype.h> overrides
wint_t. */
-#if @GNULIB_OVERRIDES_WINT_T@
+#if @GNULIBHEADERS_OVERRIDE_WINT_T@
# undef WINT_MIN
# undef WINT_MAX
# define WINT_MIN 0x0U
@@ -598,7 +598,7 @@ typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t)
/* wint_t limits */
/* If gnulib's <wchar.h> or <wctype.h> overrides wint_t, @WINT_T_SUFFIX@ is not
accurate, therefore use the definitions from above. */
-# if !@GNULIB_OVERRIDES_WINT_T@
+# if !@GNULIBHEADERS_OVERRIDE_WINT_T@
# undef WINT_MIN
# undef WINT_MAX
# if @HAVE_SIGNED_WINT_T@
diff --git a/lib/stdio-impl.h b/lib/stdio-impl.h
index 2a5db74f283..3fa94b487e4 100644
--- a/lib/stdio-impl.h
+++ b/lib/stdio-impl.h
@@ -1,17 +1,17 @@
/* Implementation details of FILE streams.
Copyright (C) 2007-2008, 2010-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Many stdio implementations have the same logic and therefore can share
diff --git a/lib/stdio.in.h b/lib/stdio.in.h
index a9308405052..0ca2c8e10c5 100644
--- a/lib/stdio.in.h
+++ b/lib/stdio.in.h
@@ -2,18 +2,18 @@
Copyright (C) 2004, 2007-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
#if __GNUC__ >= 3
@PRAGMA_SYSTEM_HEADER@
@@ -56,6 +56,52 @@
May also define off_t to a 64-bit type on native Windows. */
#include <sys/types.h>
+/* Solaris 10 and NetBSD 7.0 declare renameat in <unistd.h>, not in <stdio.h>. */
+/* But in any case avoid namespace pollution on glibc systems. */
+#if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && (defined __sun || defined __NetBSD__) \
+ && ! defined __GLIBC__
+# include <unistd.h>
+#endif
+
+/* Android 4.3 declares renameat in <sys/stat.h>, not in <stdio.h>. */
+/* But in any case avoid namespace pollution on glibc systems. */
+#if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && defined __ANDROID__ \
+ && ! defined __GLIBC__
+# include <sys/stat.h>
+#endif
+
+/* MSVC declares 'perror' in <stdlib.h>, not in <stdio.h>. We must include
+ it before we #define perror rpl_perror. */
+/* But in any case avoid namespace pollution on glibc systems. */
+#if (@GNULIB_PERROR@ || defined GNULIB_POSIXCHECK) \
+ && (defined _WIN32 && ! defined __CYGWIN__) \
+ && ! defined __GLIBC__
+# include <stdlib.h>
+#endif
+
+/* MSVC declares 'remove' in <io.h>, not in <stdio.h>. We must include
+ it before we #define remove rpl_remove. */
+/* MSVC declares 'rename' in <io.h>, not in <stdio.h>. We must include
+ it before we #define rename rpl_rename. */
+/* But in any case avoid namespace pollution on glibc systems. */
+#if (@GNULIB_REMOVE@ || @GNULIB_RENAME@ || defined GNULIB_POSIXCHECK) \
+ && (defined _WIN32 && ! defined __CYGWIN__) \
+ && ! defined __GLIBC__
+# include <io.h>
+#endif
+
+
+/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
+ that can be freed by passing them as the Ith argument to the
+ function F. */
+#ifndef _GL_ATTRIBUTE_DEALLOC
+# if __GNUC__ >= 11
+# define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i)))
+# else
+# define _GL_ATTRIBUTE_DEALLOC(f, i)
+# endif
+#endif
+
/* The __attribute__ feature is available in gcc versions 2.5 and later.
The __-protected variants of the attributes 'format' and 'printf' are
accepted by gcc versions 2.6.4 (effectively 2.7) and later.
@@ -127,41 +173,6 @@
#define _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM(formatstring_parameter, first_argument) \
_GL_ATTRIBUTE_FORMAT ((__scanf__, formatstring_parameter, first_argument))
-/* Solaris 10 and NetBSD 7.0 declare renameat in <unistd.h>, not in <stdio.h>. */
-/* But in any case avoid namespace pollution on glibc systems. */
-#if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && (defined __sun || defined __NetBSD__) \
- && ! defined __GLIBC__
-# include <unistd.h>
-#endif
-
-/* Android 4.3 declares renameat in <sys/stat.h>, not in <stdio.h>. */
-/* But in any case avoid namespace pollution on glibc systems. */
-#if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && defined __ANDROID__ \
- && ! defined __GLIBC__
-# include <sys/stat.h>
-#endif
-
-/* MSVC declares 'perror' in <stdlib.h>, not in <stdio.h>. We must include
- it before we #define perror rpl_perror. */
-/* But in any case avoid namespace pollution on glibc systems. */
-#if (@GNULIB_PERROR@ || defined GNULIB_POSIXCHECK) \
- && (defined _WIN32 && ! defined __CYGWIN__) \
- && ! defined __GLIBC__
-# include <stdlib.h>
-#endif
-
-/* MSVC declares 'remove' in <io.h>, not in <stdio.h>. We must include
- it before we #define remove rpl_remove. */
-/* MSVC declares 'rename' in <io.h>, not in <stdio.h>. We must include
- it before we #define rename rpl_rename. */
-/* But in any case avoid namespace pollution on glibc systems. */
-#if (@GNULIB_REMOVE@ || @GNULIB_RENAME@ || defined GNULIB_POSIXCHECK) \
- && (defined _WIN32 && ! defined __CYGWIN__) \
- && ! defined __GLIBC__
-# include <io.h>
-#endif
-
-
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
/* The definition of _GL_ARG_NONNULL is copied here. */
@@ -242,7 +253,7 @@ _GL_WARN_ON_USE (fclose, "fclose is not always POSIX compliant - "
_GL_CXXALIAS_MDA (fcloseall, int, (void));
# else
# if @HAVE_DECL_FCLOSEALL@
-# if defined __FreeBSD__
+# if defined __FreeBSD__ || defined __DragonFly__
_GL_CXXALIAS_SYS (fcloseall, void, (void));
# else
_GL_CXXALIAS_SYS (fcloseall, int, (void));
@@ -260,8 +271,9 @@ _GL_CXXALIASWARN (fcloseall);
# undef fdopen
# define fdopen rpl_fdopen
# endif
-_GL_FUNCDECL_RPL (fdopen, FILE *, (int fd, const char *mode)
- _GL_ARG_NONNULL ((2)));
+_GL_FUNCDECL_RPL (fdopen, FILE *,
+ (int fd, const char *mode)
+ _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1));
_GL_CXXALIAS_RPL (fdopen, FILE *, (int fd, const char *mode));
# elif defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
@@ -270,28 +282,42 @@ _GL_CXXALIAS_RPL (fdopen, FILE *, (int fd, const char *mode));
# endif
_GL_CXXALIAS_MDA (fdopen, FILE *, (int fd, const char *mode));
# else
+# if __GNUC__ >= 11
+/* For -Wmismatched-dealloc: Associate fdopen with fclose or rpl_fclose. */
+_GL_FUNCDECL_SYS (fdopen, FILE *,
+ (int fd, const char *mode)
+ _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1));
+# endif
_GL_CXXALIAS_SYS (fdopen, FILE *, (int fd, const char *mode));
# endif
_GL_CXXALIASWARN (fdopen);
-#elif defined GNULIB_POSIXCHECK
-# undef fdopen
+#else
+# if @GNULIB_FCLOSE@ && __GNUC__ >= 11 && !defined fdopen
+/* For -Wmismatched-dealloc: Associate fdopen with fclose or rpl_fclose. */
+_GL_FUNCDECL_SYS (fdopen, FILE *,
+ (int fd, const char *mode)
+ _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1));
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef fdopen
/* Assume fdopen is always declared. */
_GL_WARN_ON_USE (fdopen, "fdopen on native Windows platforms is not POSIX compliant - "
"use gnulib module fdopen for portability");
-#elif @GNULIB_MDA_FDOPEN@
+# elif @GNULIB_MDA_FDOPEN@
/* On native Windows, map 'fdopen' to '_fdopen', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::fdopen always. */
-# if defined _WIN32 && !defined __CYGWIN__
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# undef fdopen
-# define fdopen _fdopen
-# endif
+# if defined _WIN32 && !defined __CYGWIN__
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef fdopen
+# define fdopen _fdopen
+# endif
_GL_CXXALIAS_MDA (fdopen, FILE *, (int fd, const char *mode));
-# else
+# else
_GL_CXXALIAS_SYS (fdopen, FILE *, (int fd, const char *mode));
-# endif
+# endif
_GL_CXXALIASWARN (fdopen);
+# endif
#endif
#if @GNULIB_FFLUSH@
@@ -380,21 +406,35 @@ _GL_CXXALIASWARN (fileno);
# endif
_GL_FUNCDECL_RPL (fopen, FILE *,
(const char *restrict filename, const char *restrict mode)
- _GL_ARG_NONNULL ((1, 2)));
+ _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1));
_GL_CXXALIAS_RPL (fopen, FILE *,
(const char *restrict filename, const char *restrict mode));
# else
+# if __GNUC__ >= 11
+/* For -Wmismatched-dealloc: Associate fopen with fclose or rpl_fclose. */
+_GL_FUNCDECL_SYS (fopen, FILE *,
+ (const char *restrict filename, const char *restrict mode)
+ _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1));
+# endif
_GL_CXXALIAS_SYS (fopen, FILE *,
(const char *restrict filename, const char *restrict mode));
# endif
# if __GLIBC__ >= 2
_GL_CXXALIASWARN (fopen);
# endif
-#elif defined GNULIB_POSIXCHECK
-# undef fopen
+#else
+# if @GNULIB_FCLOSE@ && __GNUC__ >= 11 && !defined fopen
+/* For -Wmismatched-dealloc: Associate fopen with fclose or rpl_fclose. */
+_GL_FUNCDECL_SYS (fopen, FILE *,
+ (const char *restrict filename, const char *restrict mode)
+ _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1));
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef fopen
/* Assume fopen is always declared. */
_GL_WARN_ON_USE (fopen, "fopen on native Windows platforms is not POSIX compliant - "
"use gnulib module fopen for portability");
+# endif
#endif
#if @GNULIB_FPRINTF_POSIX@ || @GNULIB_FPRINTF@
@@ -1009,22 +1049,32 @@ _GL_WARN_ON_USE (perror, "perror is not always POSIX compliant - "
# undef popen
# define popen rpl_popen
# endif
-_GL_FUNCDECL_RPL (popen, FILE *, (const char *cmd, const char *mode)
- _GL_ARG_NONNULL ((1, 2)));
+_GL_FUNCDECL_RPL (popen, FILE *,
+ (const char *cmd, const char *mode)
+ _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (pclose, 1));
_GL_CXXALIAS_RPL (popen, FILE *, (const char *cmd, const char *mode));
# else
-# if !@HAVE_POPEN@
-_GL_FUNCDECL_SYS (popen, FILE *, (const char *cmd, const char *mode)
- _GL_ARG_NONNULL ((1, 2)));
+# if !@HAVE_POPEN@ || __GNUC__ >= 11
+_GL_FUNCDECL_SYS (popen, FILE *,
+ (const char *cmd, const char *mode)
+ _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (pclose, 1));
# endif
_GL_CXXALIAS_SYS (popen, FILE *, (const char *cmd, const char *mode));
# endif
_GL_CXXALIASWARN (popen);
-#elif defined GNULIB_POSIXCHECK
-# undef popen
-# if HAVE_RAW_DECL_POPEN
+#else
+# if @GNULIB_PCLOSE@ && __GNUC__ >= 11 && !defined popen
+/* For -Wmismatched-dealloc: Associate popen with pclose or rpl_pclose. */
+_GL_FUNCDECL_SYS (popen, FILE *,
+ (const char *cmd, const char *mode)
+ _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (pclose, 1));
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef popen
+# if HAVE_RAW_DECL_POPEN
_GL_WARN_ON_USE (popen, "popen is buggy on some platforms - "
"use gnulib module popen or pipe for more portability");
+# endif
# endif
#endif
@@ -1257,6 +1307,7 @@ _GL_CXXALIASWARN (scanf);
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define snprintf rpl_snprintf
# endif
+# define GNULIB_overrides_snprintf 1
_GL_FUNCDECL_RPL (snprintf, int,
(char *restrict str, size_t size,
const char *restrict format, ...)
@@ -1302,6 +1353,7 @@ _GL_WARN_ON_USE (snprintf, "snprintf is unportable - "
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define sprintf rpl_sprintf
# endif
+# define GNULIB_overrides_sprintf 1
_GL_FUNCDECL_RPL (sprintf, int,
(char *restrict str, const char *restrict format, ...)
_GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3)
@@ -1344,19 +1396,32 @@ _GL_CXXALIASWARN (tempnam);
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define tmpfile rpl_tmpfile
# endif
-_GL_FUNCDECL_RPL (tmpfile, FILE *, (void));
+_GL_FUNCDECL_RPL (tmpfile, FILE *, (void)
+ _GL_ATTRIBUTE_DEALLOC (fclose, 1));
_GL_CXXALIAS_RPL (tmpfile, FILE *, (void));
# else
+# if __GNUC__ >= 11
+/* For -Wmismatched-dealloc: Associate tmpfile with fclose or rpl_fclose. */
+_GL_FUNCDECL_SYS (tmpfile, FILE *, (void)
+ _GL_ATTRIBUTE_DEALLOC (fclose, 1));
+# endif
_GL_CXXALIAS_SYS (tmpfile, FILE *, (void));
# endif
# if __GLIBC__ >= 2
_GL_CXXALIASWARN (tmpfile);
# endif
-#elif defined GNULIB_POSIXCHECK
-# undef tmpfile
-# if HAVE_RAW_DECL_TMPFILE
+#else
+# if @GNULIB_FCLOSE@ && __GNUC__ >= 11 && !defined tmpfile
+/* For -Wmismatched-dealloc: Associate tmpfile with fclose or rpl_fclose. */
+_GL_FUNCDECL_SYS (tmpfile, FILE *, (void)
+ _GL_ATTRIBUTE_DEALLOC (fclose, 1));
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef tmpfile
+# if HAVE_RAW_DECL_TMPFILE
_GL_WARN_ON_USE (tmpfile, "tmpfile is not usable on mingw - "
"use gnulib module tmpfile for portability");
+# endif
# endif
#endif
@@ -1369,6 +1434,7 @@ _GL_WARN_ON_USE (tmpfile, "tmpfile is not usable on mingw - "
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define asprintf rpl_asprintf
# endif
+# define GNULIB_overrides_asprintf
_GL_FUNCDECL_RPL (asprintf, int,
(char **result, const char *format, ...)
_GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3)
@@ -1390,6 +1456,7 @@ _GL_CXXALIASWARN (asprintf);
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define vasprintf rpl_vasprintf
# endif
+# define GNULIB_overrides_vasprintf 1
_GL_FUNCDECL_RPL (vasprintf, int,
(char **result, const char *format, va_list args)
_GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0)
@@ -1573,6 +1640,7 @@ _GL_CXXALIASWARN (vscanf);
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define vsnprintf rpl_vsnprintf
# endif
+# define GNULIB_overrides_vsnprintf 1
_GL_FUNCDECL_RPL (vsnprintf, int,
(char *restrict str, size_t size,
const char *restrict format, va_list args)
@@ -1609,6 +1677,7 @@ _GL_WARN_ON_USE (vsnprintf, "vsnprintf is unportable - "
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define vsprintf rpl_vsprintf
# endif
+# define GNULIB_overrides_vsprintf 1
_GL_FUNCDECL_RPL (vsprintf, int,
(char *restrict str,
const char *restrict format, va_list args)
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index 49fc44e14a1..0855112d19e 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -2,17 +2,17 @@
Copyright (C) 1995, 2001-2004, 2006-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
#if __GNUC__ >= 3
@@ -99,6 +99,35 @@ struct random_data
# include <unistd.h>
#endif
+/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
+ that can be freed by passing them as the Ith argument to the
+ function F. */
+#ifndef _GL_ATTRIBUTE_DEALLOC
+# if __GNUC__ >= 11
+# define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i)))
+# else
+# define _GL_ATTRIBUTE_DEALLOC(f, i)
+# endif
+#endif
+
+/* _GL_ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that
+ can be freed via 'free'; it can be used only after declaring 'free'. */
+/* Applies to: functions. Cannot be used on inline functions. */
+#ifndef _GL_ATTRIBUTE_DEALLOC_FREE
+# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (free, 1)
+#endif
+
+/* _GL_ATTRIBUTE_MALLOC declares that the function returns a pointer to freshly
+ allocated memory. */
+/* Applies to: functions. */
+#ifndef _GL_ATTRIBUTE_MALLOC
+# if __GNUC__ >= 3 || defined __clang__
+# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
+# else
+# define _GL_ATTRIBUTE_MALLOC
+# endif
+#endif
+
/* The __attribute__ feature is available in gcc versions 2.5 and later.
The attribute __pure__ was added in gcc 2.96. */
#ifndef _GL_ATTRIBUTE_PURE
@@ -149,6 +178,28 @@ _GL_WARN_ON_USE (_Exit, "_Exit is unportable - "
#endif
+#if @GNULIB_FREE_POSIX@
+# if @REPLACE_FREE@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef free
+# define free rpl_free
+# endif
+_GL_FUNCDECL_RPL (free, void, (void *ptr));
+_GL_CXXALIAS_RPL (free, void, (void *ptr));
+# else
+_GL_CXXALIAS_SYS (free, void, (void *ptr));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (free);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef free
+/* Assume free is always declared. */
+_GL_WARN_ON_USE (free, "free is not future POSIX compliant everywhere - "
+ "use gnulib module free for portability");
+#endif
+
+
/* Allocate memory with indefinite extent and specified alignment. */
#if @GNULIB_ALIGNED_ALLOC@
# if @REPLACE_ALIGNED_ALLOC@
@@ -156,21 +207,37 @@ _GL_WARN_ON_USE (_Exit, "_Exit is unportable - "
# undef aligned_alloc
# define aligned_alloc rpl_aligned_alloc
# endif
-_GL_FUNCDECL_RPL (aligned_alloc, void *, (size_t alignment, size_t size));
+_GL_FUNCDECL_RPL (aligned_alloc, void *,
+ (size_t alignment, size_t size)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
_GL_CXXALIAS_RPL (aligned_alloc, void *, (size_t alignment, size_t size));
# else
# if @HAVE_ALIGNED_ALLOC@
+# if __GNUC__ >= 11
+/* For -Wmismatched-dealloc: Associate aligned_alloc with free or rpl_free. */
+_GL_FUNCDECL_SYS (aligned_alloc, void *,
+ (size_t alignment, size_t size)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
_GL_CXXALIAS_SYS (aligned_alloc, void *, (size_t alignment, size_t size));
# endif
# endif
# if @HAVE_ALIGNED_ALLOC@
_GL_CXXALIASWARN (aligned_alloc);
# endif
-#elif defined GNULIB_POSIXCHECK
-# undef aligned_alloc
-# if HAVE_RAW_DECL_ALIGNED_ALLOC
+#else
+# if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined aligned_alloc
+/* For -Wmismatched-dealloc: Associate aligned_alloc with free or rpl_free. */
+_GL_FUNCDECL_SYS (aligned_alloc, void *,
+ (size_t alignment, size_t size)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef aligned_alloc
+# if HAVE_RAW_DECL_ALIGNED_ALLOC
_GL_WARN_ON_USE (aligned_alloc, "aligned_alloc is not portable - "
"use gnulib module aligned_alloc for portability");
+# endif
# endif
#endif
@@ -198,19 +265,35 @@ _GL_WARN_ON_USE (atoll, "atoll is unportable - "
# undef calloc
# define calloc rpl_calloc
# endif
-_GL_FUNCDECL_RPL (calloc, void *, (size_t nmemb, size_t size));
+_GL_FUNCDECL_RPL (calloc, void *,
+ (size_t nmemb, size_t size)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
_GL_CXXALIAS_RPL (calloc, void *, (size_t nmemb, size_t size));
# else
+# if __GNUC__ >= 11
+/* For -Wmismatched-dealloc: Associate calloc with free or rpl_free. */
+_GL_FUNCDECL_SYS (calloc, void *,
+ (size_t nmemb, size_t size)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
_GL_CXXALIAS_SYS (calloc, void *, (size_t nmemb, size_t size));
# endif
# if __GLIBC__ >= 2
_GL_CXXALIASWARN (calloc);
# endif
-#elif defined GNULIB_POSIXCHECK
-# undef calloc
+#else
+# if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined calloc
+/* For -Wmismatched-dealloc: Associate calloc with free or rpl_free. */
+_GL_FUNCDECL_SYS (calloc, void *,
+ (size_t nmemb, size_t size)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef calloc
/* Assume calloc is always declared. */
_GL_WARN_ON_USE (calloc, "calloc is not POSIX compliant everywhere - "
"use gnulib module calloc-posix for portability");
+# endif
#endif
#if @GNULIB_CANONICALIZE_FILE_NAME@
@@ -218,13 +301,17 @@ _GL_WARN_ON_USE (calloc, "calloc is not POSIX compliant everywhere - "
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define canonicalize_file_name rpl_canonicalize_file_name
# endif
-_GL_FUNCDECL_RPL (canonicalize_file_name, char *, (const char *name)
- _GL_ARG_NONNULL ((1)));
+_GL_FUNCDECL_RPL (canonicalize_file_name, char *,
+ (const char *name)
+ _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
_GL_CXXALIAS_RPL (canonicalize_file_name, char *, (const char *name));
# else
-# if !@HAVE_CANONICALIZE_FILE_NAME@
-_GL_FUNCDECL_SYS (canonicalize_file_name, char *, (const char *name)
- _GL_ARG_NONNULL ((1)));
+# if !@HAVE_CANONICALIZE_FILE_NAME@ || __GNUC__ >= 11
+_GL_FUNCDECL_SYS (canonicalize_file_name, char *,
+ (const char *name)
+ _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
# endif
_GL_CXXALIAS_SYS (canonicalize_file_name, char *, (const char *name));
# endif
@@ -233,12 +320,22 @@ _GL_CXXALIAS_SYS (canonicalize_file_name, char *, (const char *name));
(!@HAVE_CANONICALIZE_FILE_NAME@ || @REPLACE_CANONICALIZE_FILE_NAME@)
# endif
_GL_CXXALIASWARN (canonicalize_file_name);
-#elif defined GNULIB_POSIXCHECK
-# undef canonicalize_file_name
-# if HAVE_RAW_DECL_CANONICALIZE_FILE_NAME
+#else
+# if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined canonicalize_file_name
+/* For -Wmismatched-dealloc: Associate canonicalize_file_name with free or
+ rpl_free. */
+_GL_FUNCDECL_SYS (canonicalize_file_name, char *,
+ (const char *name)
+ _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef canonicalize_file_name
+# if HAVE_RAW_DECL_CANONICALIZE_FILE_NAME
_GL_WARN_ON_USE (canonicalize_file_name,
"canonicalize_file_name is unportable - "
"use gnulib module canonicalize-lgpl for portability");
+# endif
# endif
#endif
@@ -288,27 +385,6 @@ _GL_CXXALIASWARN (fcvt);
# endif
#endif
-#if @GNULIB_FREE_POSIX@
-# if @REPLACE_FREE@
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# undef free
-# define free rpl_free
-# endif
-_GL_FUNCDECL_RPL (free, void, (void *ptr));
-_GL_CXXALIAS_RPL (free, void, (void *ptr));
-# else
-_GL_CXXALIAS_SYS (free, void, (void *ptr));
-# endif
-# if __GLIBC__ >= 2
-_GL_CXXALIASWARN (free);
-# endif
-#elif defined GNULIB_POSIXCHECK
-# undef free
-/* Assume free is always declared. */
-_GL_WARN_ON_USE (free, "free is not future POSIX compliant everywhere - "
- "use gnulib module free for portability");
-#endif
-
#if @GNULIB_MDA_GCVT@
/* On native Windows, map 'gcvt' to '_gcvt', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between
@@ -404,19 +480,35 @@ _GL_WARN_ON_USE (grantpt, "grantpt is not portable - "
# undef malloc
# define malloc rpl_malloc
# endif
-_GL_FUNCDECL_RPL (malloc, void *, (size_t size));
+_GL_FUNCDECL_RPL (malloc, void *,
+ (size_t size)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
_GL_CXXALIAS_RPL (malloc, void *, (size_t size));
# else
+# if __GNUC__ >= 11
+/* For -Wmismatched-dealloc: Associate malloc with free or rpl_free. */
+_GL_FUNCDECL_SYS (malloc, void *,
+ (size_t size)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
_GL_CXXALIAS_SYS (malloc, void *, (size_t size));
# endif
# if __GLIBC__ >= 2
_GL_CXXALIASWARN (malloc);
# endif
-#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC
-# undef malloc
+#else
+# if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined malloc
+/* For -Wmismatched-dealloc: Associate malloc with free or rpl_free. */
+_GL_FUNCDECL_SYS (malloc, void *,
+ (size_t size)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
+# if defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC
+# undef malloc
/* Assume malloc is always declared. */
_GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - "
"use gnulib module malloc-posix for portability");
+# endif
#endif
/* Convert a multibyte character to a wide character. */
@@ -1015,29 +1107,53 @@ _GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - "
# undef realloc
# define realloc rpl_realloc
# endif
-_GL_FUNCDECL_RPL (realloc, void *, (void *ptr, size_t size));
+_GL_FUNCDECL_RPL (realloc, void *, (void *ptr, size_t size)
+ _GL_ATTRIBUTE_DEALLOC_FREE);
_GL_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size));
# else
+# if __GNUC__ >= 11
+/* For -Wmismatched-dealloc: Associate realloc with free or rpl_free. */
+_GL_FUNCDECL_SYS (realloc, void *, (void *ptr, size_t size)
+ _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
_GL_CXXALIAS_SYS (realloc, void *, (void *ptr, size_t size));
# endif
# if __GLIBC__ >= 2
_GL_CXXALIASWARN (realloc);
# endif
-#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC
-# undef realloc
+#else
+# if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined realloc
+/* For -Wmismatched-dealloc: Associate realloc with free or rpl_free. */
+_GL_FUNCDECL_SYS (realloc, void *, (void *ptr, size_t size)
+ _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
+# if defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC
+# undef realloc
/* Assume realloc is always declared. */
_GL_WARN_ON_USE (realloc, "realloc is not POSIX compliant everywhere - "
"use gnulib module realloc-posix for portability");
+# endif
#endif
#if @GNULIB_REALLOCARRAY@
-# if ! @HAVE_REALLOCARRAY@
+# if @REPLACE_REALLOCARRAY@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef reallocarray
+# define reallocarray rpl_reallocarray
+# endif
+_GL_FUNCDECL_RPL (reallocarray, void *,
+ (void *ptr, size_t nmemb, size_t size));
+_GL_CXXALIAS_RPL (reallocarray, void *,
+ (void *ptr, size_t nmemb, size_t size));
+# else
+# if ! @HAVE_REALLOCARRAY@
_GL_FUNCDECL_SYS (reallocarray, void *,
(void *ptr, size_t nmemb, size_t size));
-# endif
+# endif
_GL_CXXALIAS_SYS (reallocarray, void *,
(void *ptr, size_t nmemb, size_t size));
+# endif
_GL_CXXALIASWARN (reallocarray);
#elif defined GNULIB_POSIXCHECK
# undef reallocarray
@@ -1202,6 +1318,47 @@ _GL_WARN_ON_USE (strtold, "strtold is unportable - "
# endif
#endif
+#if @GNULIB_STRTOL@
+/* Parse a signed integer whose textual representation starts at STRING.
+ The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,
+ it may be decimal or octal (with prefix "0") or hexadecimal (with prefix
+ "0x").
+ If ENDPTR is not NULL, the address of the first byte after the integer is
+ stored in *ENDPTR.
+ Upon overflow, the return value is LONG_MAX or LONG_MIN, and errno is set
+ to ERANGE. */
+# if @REPLACE_STRTOL@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define strtol rpl_strtol
+# endif
+# define GNULIB_defined_strtol_function 1
+_GL_FUNCDECL_RPL (strtol, long,
+ (const char *restrict string, char **restrict endptr,
+ int base)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtol, long,
+ (const char *restrict string, char **restrict endptr,
+ int base));
+# else
+# if !@HAVE_STRTOL@
+_GL_FUNCDECL_SYS (strtol, long,
+ (const char *restrict string, char **restrict endptr,
+ int base)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (strtol, long,
+ (const char *restrict string, char **restrict endptr,
+ int base));
+# endif
+_GL_CXXALIASWARN (strtol);
+#elif defined GNULIB_POSIXCHECK
+# undef strtol
+# if HAVE_RAW_DECL_STRTOL
+_GL_WARN_ON_USE (strtol, "strtol is unportable - "
+ "use gnulib module strtol for portability");
+# endif
+#endif
+
#if @GNULIB_STRTOLL@
/* Parse a signed integer whose textual representation starts at STRING.
The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,
@@ -1211,15 +1368,29 @@ _GL_WARN_ON_USE (strtold, "strtold is unportable - "
stored in *ENDPTR.
Upon overflow, the return value is LLONG_MAX or LLONG_MIN, and errno is set
to ERANGE. */
-# if !@HAVE_STRTOLL@
+# if @REPLACE_STRTOLL@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define strtoll rpl_strtoll
+# endif
+# define GNULIB_defined_strtoll_function 1
+_GL_FUNCDECL_RPL (strtoll, long long,
+ (const char *restrict string, char **restrict endptr,
+ int base)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtoll, long long,
+ (const char *restrict string, char **restrict endptr,
+ int base));
+# else
+# if !@HAVE_STRTOLL@
_GL_FUNCDECL_SYS (strtoll, long long,
(const char *restrict string, char **restrict endptr,
int base)
_GL_ARG_NONNULL ((1)));
-# endif
+# endif
_GL_CXXALIAS_SYS (strtoll, long long,
(const char *restrict string, char **restrict endptr,
int base));
+# endif
_GL_CXXALIASWARN (strtoll);
#elif defined GNULIB_POSIXCHECK
# undef strtoll
@@ -1229,6 +1400,46 @@ _GL_WARN_ON_USE (strtoll, "strtoll is unportable - "
# endif
#endif
+#if @GNULIB_STRTOUL@
+/* Parse an unsigned integer whose textual representation starts at STRING.
+ The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,
+ it may be decimal or octal (with prefix "0") or hexadecimal (with prefix
+ "0x").
+ If ENDPTR is not NULL, the address of the first byte after the integer is
+ stored in *ENDPTR.
+ Upon overflow, the return value is ULONG_MAX, and errno is set to ERANGE. */
+# if @REPLACE_STRTOUL@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define strtoul rpl_strtoul
+# endif
+# define GNULIB_defined_strtoul_function 1
+_GL_FUNCDECL_RPL (strtoul, unsigned long,
+ (const char *restrict string, char **restrict endptr,
+ int base)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtoul, unsigned long,
+ (const char *restrict string, char **restrict endptr,
+ int base));
+# else
+# if !@HAVE_STRTOUL@
+_GL_FUNCDECL_SYS (strtoul, unsigned long,
+ (const char *restrict string, char **restrict endptr,
+ int base)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (strtoul, unsigned long,
+ (const char *restrict string, char **restrict endptr,
+ int base));
+# endif
+_GL_CXXALIASWARN (strtoul);
+#elif defined GNULIB_POSIXCHECK
+# undef strtoul
+# if HAVE_RAW_DECL_STRTOUL
+_GL_WARN_ON_USE (strtoul, "strtoul is unportable - "
+ "use gnulib module strtoul for portability");
+# endif
+#endif
+
#if @GNULIB_STRTOULL@
/* Parse an unsigned integer whose textual representation starts at STRING.
The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,
@@ -1238,15 +1449,29 @@ _GL_WARN_ON_USE (strtoll, "strtoll is unportable - "
stored in *ENDPTR.
Upon overflow, the return value is ULLONG_MAX, and errno is set to
ERANGE. */
-# if !@HAVE_STRTOULL@
+# if @REPLACE_STRTOULL@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define strtoull rpl_strtoull
+# endif
+# define GNULIB_defined_strtoull_function 1
+_GL_FUNCDECL_RPL (strtoull, unsigned long long,
+ (const char *restrict string, char **restrict endptr,
+ int base)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtoull, unsigned long long,
+ (const char *restrict string, char **restrict endptr,
+ int base));
+# else
+# if !@HAVE_STRTOULL@
_GL_FUNCDECL_SYS (strtoull, unsigned long long,
(const char *restrict string, char **restrict endptr,
int base)
_GL_ARG_NONNULL ((1)));
-# endif
+# endif
_GL_CXXALIAS_SYS (strtoull, unsigned long long,
(const char *restrict string, char **restrict endptr,
int base));
+# endif
_GL_CXXALIASWARN (strtoull);
#elif defined GNULIB_POSIXCHECK
# undef strtoull
diff --git a/lib/stpcpy.c b/lib/stpcpy.c
index a4165ba4bf9..c312fe44ba5 100644
--- a/lib/stpcpy.c
+++ b/lib/stpcpy.c
@@ -5,17 +5,17 @@
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
- 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 any
- later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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 <config.h>
diff --git a/lib/str-two-way.h b/lib/str-two-way.h
index 005a19fb513..fc2db03b7b6 100644
--- a/lib/str-two-way.h
+++ b/lib/str-two-way.h
@@ -3,18 +3,18 @@
This file is part of the GNU C Library.
Written by Eric Blake <ebb9@byu.net>, 2008.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
/* Before including this file, you need to include <config.h> and
<string.h>, and define:
diff --git a/lib/strftime.h b/lib/strftime.h
index 7284f67133c..790a80ed8fe 100644
--- a/lib/strftime.h
+++ b/lib/strftime.h
@@ -2,17 +2,17 @@
Copyright (C) 2002, 2004, 2008-2021 Free Software Foundation, Inc.
- 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 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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 <time.h>
diff --git a/lib/string.in.h b/lib/string.in.h
index c76c1820b36..8d77ae38000 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -2,18 +2,18 @@
Copyright (C) 1995-1996, 2001-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
#if __GNUC__ >= 3
@PRAGMA_SYSTEM_HEADER@
@@ -52,16 +52,6 @@
# include <wchar.h>
#endif
-/* The __attribute__ feature is available in gcc versions 2.5 and later.
- The attribute __pure__ was added in gcc 2.96. */
-#ifndef _GL_ATTRIBUTE_PURE
-# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__
-# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
-# else
-# define _GL_ATTRIBUTE_PURE /* empty */
-# endif
-#endif
-
/* NetBSD 5.0 declares strsignal in <unistd.h>, not in <string.h>. */
/* But in any case avoid namespace pollution on glibc systems. */
#if (@GNULIB_STRSIGNAL@ || defined GNULIB_POSIXCHECK) && defined __NetBSD__ \
@@ -77,12 +67,31 @@
# include <strings.h>
#endif
+/* The __attribute__ feature is available in gcc versions 2.5 and later.
+ The attribute __pure__ was added in gcc 2.96. */
+#ifndef _GL_ATTRIBUTE_PURE
+# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__
+# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
+# else
+# define _GL_ATTRIBUTE_PURE /* empty */
+# endif
+#endif
+
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
/* The definition of _GL_ARG_NONNULL is copied here. */
/* The definition of _GL_WARN_ON_USE is copied here. */
+/* Declare 'free' if needed for _GL_ATTRIBUTE_DEALLOC_FREE. */
+_GL_EXTERN_C void free (void *);
+#if @GNULIB_FREE_POSIX@
+# if (@REPLACE_FREE@ && !defined free \
+ && !(defined __cplusplus && defined GNULIB_NAMESPACE))
+# define free rpl_free
+_GL_EXTERN_C void free (void *);
+# endif
+#endif
/* Clear a block of memory. The compiler will not delete a call to
this function, even if the block is dead after the call. */
@@ -418,7 +427,10 @@ _GL_WARN_ON_USE (strchrnul, "strchrnul is unportable - "
# undef strdup
# define strdup rpl_strdup
# endif
-_GL_FUNCDECL_RPL (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1)));
+_GL_FUNCDECL_RPL (strdup, char *,
+ (char const *__s)
+ _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
_GL_CXXALIAS_RPL (strdup, char *, (char const *__s));
# elif defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
@@ -431,35 +443,47 @@ _GL_CXXALIAS_MDA (strdup, char *, (char const *__s));
/* strdup exists as a function and as a macro. Get rid of the macro. */
# undef strdup
# endif
-# if !(@HAVE_DECL_STRDUP@ || defined strdup)
-_GL_FUNCDECL_SYS (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1)));
+# if (!@HAVE_DECL_STRDUP@ || __GNUC__ >= 11) && !defined strdup
+_GL_FUNCDECL_SYS (strdup, char *,
+ (char const *__s)
+ _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
# endif
_GL_CXXALIAS_SYS (strdup, char *, (char const *__s));
# endif
_GL_CXXALIASWARN (strdup);
-#elif defined GNULIB_POSIXCHECK
-# undef strdup
-# if HAVE_RAW_DECL_STRDUP
+#else
+# if __GNUC__ >= 11 && !defined strdup
+/* For -Wmismatched-dealloc: Associate strdup with free or rpl_free. */
+_GL_FUNCDECL_SYS (strdup, char *,
+ (char const *__s)
+ _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef strdup
+# if HAVE_RAW_DECL_STRDUP
_GL_WARN_ON_USE (strdup, "strdup is unportable - "
"use gnulib module strdup for portability");
-# endif
-#elif @GNULIB_MDA_STRDUP@
+# endif
+# elif @GNULIB_MDA_STRDUP@
/* On native Windows, map 'creat' to '_creat', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between
- platforms by defining GNULIB_NAMESPACE::creat always. */
-# if defined _WIN32 && !defined __CYGWIN__
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# undef strdup
-# define strdup _strdup
-# endif
+ platforms by defining GNULIB_NAMESPACE::strdup always. */
+# if defined _WIN32 && !defined __CYGWIN__
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef strdup
+# define strdup _strdup
+# endif
_GL_CXXALIAS_MDA (strdup, char *, (char const *__s));
-# else
-# if defined __cplusplus && defined GNULIB_NAMESPACE && defined strdup
-# undef strdup
-# endif
+# else
+# if defined __cplusplus && defined GNULIB_NAMESPACE && defined strdup
+# undef strdup
+# endif
_GL_CXXALIAS_SYS (strdup, char *, (char const *__s));
-# endif
+# endif
_GL_CXXALIASWARN (strdup);
+# endif
#endif
/* Append no more than N characters from SRC onto DEST. */
diff --git a/lib/strnlen.c b/lib/strnlen.c
index c27a0392c2b..ded06ce23ff 100644
--- a/lib/strnlen.c
+++ b/lib/strnlen.c
@@ -2,18 +2,18 @@
Copyright (C) 2005-2007, 2009-2021 Free Software Foundation, Inc.
Written by Simon Josefsson.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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 <config.h>
diff --git a/lib/strtoimax.c b/lib/strtoimax.c
index 37a25c31d44..bf8534a7677 100644
--- a/lib/strtoimax.c
+++ b/lib/strtoimax.c
@@ -3,17 +3,17 @@
Copyright (C) 1999, 2001-2004, 2006, 2009-2021 Free Software Foundation,
Inc.
- 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 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Paul Eggert. */
diff --git a/lib/strtol.c b/lib/strtol.c
index 2f2159b6231..c49321ba0cd 100644
--- a/lib/strtol.c
+++ b/lib/strtol.c
@@ -6,17 +6,17 @@
NOTE: The canonical source of this file is maintained with the GNU C
Library. Bugs can be reported to bug-glibc@gnu.org.
- 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 any
- later version.
+ 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
#ifdef _LIBC
@@ -51,6 +51,7 @@
/* Determine the name. */
#ifdef USE_IN_EXTENDED_LOCALE_MODEL
+# undef strtol
# if UNSIGNED
# ifdef USE_WIDE_CHAR
# ifdef QUAD
@@ -82,6 +83,7 @@
# endif
#else
# if UNSIGNED
+# undef strtol
# ifdef USE_WIDE_CHAR
# ifdef QUAD
# define strtol wcstoull
@@ -97,6 +99,7 @@
# endif
# else
# ifdef USE_WIDE_CHAR
+# undef strtol
# ifdef QUAD
# define strtol wcstoll
# else
@@ -104,6 +107,7 @@
# endif
# else
# ifdef QUAD
+# undef strtol
# define strtol strtoll
# endif
# endif
@@ -131,6 +135,12 @@
#endif
+#ifdef USE_NUMBER_GROUPING
+# define GROUP_PARAM_PROTO , int group
+#else
+# define GROUP_PARAM_PROTO
+#endif
+
/* We use this code also for the extended locale handling where the
function gets as an additional argument the locale which has to be
used. To access the values we have to redefine the _NL_CURRENT
@@ -166,19 +176,23 @@
# define UCHAR_TYPE unsigned char
# define STRING_TYPE char
# ifdef USE_IN_EXTENDED_LOCALE_MODEL
-# define ISSPACE(Ch) __isspace_l ((Ch), loc)
-# define ISALPHA(Ch) __isalpha_l ((Ch), loc)
-# define TOUPPER(Ch) __toupper_l ((Ch), loc)
+# define ISSPACE(Ch) __isspace_l ((unsigned char) (Ch), loc)
+# define ISALPHA(Ch) __isalpha_l ((unsigned char) (Ch), loc)
+# define TOUPPER(Ch) __toupper_l ((unsigned char) (Ch), loc)
# else
-# define ISSPACE(Ch) isspace (Ch)
-# define ISALPHA(Ch) isalpha (Ch)
-# define TOUPPER(Ch) toupper (Ch)
+# define ISSPACE(Ch) isspace ((unsigned char) (Ch))
+# define ISALPHA(Ch) isalpha ((unsigned char) (Ch))
+# define TOUPPER(Ch) toupper ((unsigned char) (Ch))
# endif
#endif
-#define INTERNAL(X) INTERNAL1(X)
-#define INTERNAL1(X) __##X##_internal
-#define WEAKNAME(X) WEAKNAME1(X)
+#ifdef USE_NUMBER_GROUPING
+# define INTERNAL(X) INTERNAL1(X)
+# define INTERNAL1(X) __##X##_internal
+# define WEAKNAME(X) WEAKNAME1(X)
+#else
+# define INTERNAL(X) X
+#endif
#ifdef USE_NUMBER_GROUPING
/* This file defines a function to check for correct grouping. */
@@ -196,7 +210,7 @@
INT
INTERNAL (strtol) (const STRING_TYPE *nptr, STRING_TYPE **endptr,
- int base, int group LOCALE_PARAM_PROTO)
+ int base GROUP_PARAM_PROTO LOCALE_PARAM_PROTO)
{
int negative;
register unsigned LONG int cutoff;
@@ -379,15 +393,16 @@ noconv:
return 0L;
}
+#ifdef USE_NUMBER_GROUPING
/* External user entry point. */
-
INT
-#ifdef weak_function
+# ifdef weak_function
weak_function
-#endif
+# endif
strtol (const STRING_TYPE *nptr, STRING_TYPE **endptr,
int base LOCALE_PARAM_PROTO)
{
return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM);
}
+#endif
diff --git a/lib/strtoll.c b/lib/strtoll.c
index 30daefc50f6..8e6f93faeb8 100644
--- a/lib/strtoll.c
+++ b/lib/strtoll.c
@@ -3,17 +3,17 @@
Inc.
This file is part of the GNU C Library.
- 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 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
#define QUAD 1
diff --git a/lib/symlink.c b/lib/symlink.c
index 2f6c0d484b8..4bb0884aca2 100644
--- a/lib/symlink.c
+++ b/lib/symlink.c
@@ -1,17 +1,17 @@
/* Stub for symlink().
Copyright (C) 2009-2021 Free Software Foundation, Inc.
- 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 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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 <config.h>
@@ -47,8 +47,8 @@ rpl_symlink (char const *contents, char const *name)
/* The system does not support symlinks. */
int
-symlink (char const *contents _GL_UNUSED,
- char const *name _GL_UNUSED)
+symlink (_GL_UNUSED char const *contents,
+ _GL_UNUSED char const *name)
{
errno = ENOSYS;
return -1;
diff --git a/lib/sys_random.in.h b/lib/sys_random.in.h
index 5b9280dda36..1abd6c544e0 100644
--- a/lib/sys_random.in.h
+++ b/lib/sys_random.in.h
@@ -1,18 +1,18 @@
/* Substitute for <sys/random.h>.
Copyright (C) 2020-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
# if __GNUC__ >= 3
@PRAGMA_SYSTEM_HEADER@
diff --git a/lib/sys_select.in.h b/lib/sys_select.in.h
index 1dacb21087d..910bea5d12a 100644
--- a/lib/sys_select.in.h
+++ b/lib/sys_select.in.h
@@ -1,18 +1,18 @@
/* Substitute for <sys/select.h>.
Copyright (C) 2007-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
# if __GNUC__ >= 3
@PRAGMA_SYSTEM_HEADER@
@@ -21,7 +21,7 @@
/* On OSF/1 and Solaris 2.6, <sys/types.h> and <sys/time.h>
both include <sys/select.h>.
- On Cygwin, <sys/time.h> includes <sys/select.h>.
+ On Cygwin and OpenBSD, <sys/time.h> includes <sys/select.h>.
Simply delegate to the system's header in this case. */
#if (@HAVE_SYS_SELECT_H@ \
&& !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_H \
@@ -39,6 +39,7 @@
|| (!defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H \
&& ((defined __osf__ && defined _SYS_TIME_H_ \
&& defined _OSF_SOURCE) \
+ || (defined __OpenBSD__ && defined _SYS_TIME_H_) \
|| (defined __sun && defined _SYS_TIME_H \
&& (! (defined _XOPEN_SOURCE \
|| defined _POSIX_C_SOURCE) \
diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h
index 13d12943cd0..babe3dba3e6 100644
--- a/lib/sys_stat.in.h
+++ b/lib/sys_stat.in.h
@@ -1,18 +1,18 @@
/* Provide a more complete sys/stat.h header file.
Copyright (C) 2005-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
/* Written by Eric Blake, Paul Eggert, and Jim Meyering. */
diff --git a/lib/sys_time.in.h b/lib/sys_time.in.h
index 90a67d18426..8035fbe7ecf 100644
--- a/lib/sys_time.in.h
+++ b/lib/sys_time.in.h
@@ -2,18 +2,18 @@
Copyright (C) 2007-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
/* Written by Paul Eggert. */
diff --git a/lib/sys_types.in.h b/lib/sys_types.in.h
index 654e80335fa..2079d72efcf 100644
--- a/lib/sys_types.in.h
+++ b/lib/sys_types.in.h
@@ -2,18 +2,18 @@
Copyright (C) 2011-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
#if __GNUC__ >= 3
@PRAGMA_SYSTEM_HEADER@
diff --git a/lib/tempname.c b/lib/tempname.c
index e243483eaf8..7675aa076db 100644
--- a/lib/tempname.c
+++ b/lib/tempname.c
@@ -2,16 +2,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
@@ -181,13 +181,13 @@ try_file (char *tmpl, void *flags)
}
static int
-try_dir (char *tmpl, void *flags _GL_UNUSED)
+try_dir (char *tmpl, _GL_UNUSED void *flags)
{
return __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
}
static int
-try_nocreate (char *tmpl, void *flags _GL_UNUSED)
+try_nocreate (char *tmpl, _GL_UNUSED void *flags)
{
struct_stat64 st;
diff --git a/lib/tempname.h b/lib/tempname.h
index a8681fc998e..795bb49764f 100644
--- a/lib/tempname.h
+++ b/lib/tempname.h
@@ -2,17 +2,17 @@
Copyright (C) 2006, 2009-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* header written by Eric Blake */
diff --git a/lib/time-internal.h b/lib/time-internal.h
index 067ee729eda..6bbd0a727b8 100644
--- a/lib/time-internal.h
+++ b/lib/time-internal.h
@@ -2,18 +2,18 @@
Copyright 2015-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
/* Written by Paul Eggert. */
diff --git a/lib/time.in.h b/lib/time.in.h
index 1385980cdf5..a73fe59cbb7 100644
--- a/lib/time.in.h
+++ b/lib/time.in.h
@@ -2,18 +2,18 @@
Copyright (C) 2007-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
#if __GNUC__ >= 3
@PRAGMA_SYSTEM_HEADER@
@@ -340,22 +340,60 @@ _GL_CXXALIASWARN (strftime);
# endif
# if defined _GNU_SOURCE && @GNULIB_TIME_RZ@ && ! @HAVE_TIMEZONE_T@
+/* Functions that use a first-class time zone data type, instead of
+ relying on an implicit global time zone.
+ Inspired by NetBSD. */
+
+/* Represents a time zone.
+ (timezone_t) NULL stands for UTC. */
typedef struct tm_zone *timezone_t;
+
+/* tzalloc (name)
+ Returns a time zone object for the given time zone NAME. This object
+ represents the time zone that other functions would use it the TZ
+ environment variable was set to NAME.
+ If NAME is NULL, the result represents the time zone that other functions
+ would use it the TZ environment variable was unset.
+ May return NULL if NAME is invalid (this is platform dependent) or
+ upon memory allocation failure. */
_GL_FUNCDECL_SYS (tzalloc, timezone_t, (char const *__name));
_GL_CXXALIAS_SYS (tzalloc, timezone_t, (char const *__name));
+
+/* tzfree (tz)
+ Frees a time zone object.
+ The argument must have been returned by tzalloc(). */
_GL_FUNCDECL_SYS (tzfree, void, (timezone_t __tz));
_GL_CXXALIAS_SYS (tzfree, void, (timezone_t __tz));
+
+/* localtime_rz (tz, &t, &result)
+ Converts an absolute time T to a broken-down time RESULT, assuming the
+ time zone TZ.
+ This function is like 'localtime_r', but relies on the argument TZ instead
+ of an implicit global time zone. */
_GL_FUNCDECL_SYS (localtime_rz, struct tm *,
(timezone_t __tz, time_t const *restrict __timer,
struct tm *restrict __result) _GL_ARG_NONNULL ((2, 3)));
_GL_CXXALIAS_SYS (localtime_rz, struct tm *,
(timezone_t __tz, time_t const *restrict __timer,
struct tm *restrict __result));
+
+/* mktime_z (tz, &tm)
+ Normalizes the broken-down time TM and converts it to an absolute time,
+ assuming the time zone TZ. Returns the absolute time.
+ This function is like 'mktime', but relies on the argument TZ instead
+ of an implicit global time zone. */
_GL_FUNCDECL_SYS (mktime_z, time_t,
- (timezone_t __tz, struct tm *restrict __result)
+ (timezone_t __tz, struct tm *restrict __tm)
_GL_ARG_NONNULL ((2)));
_GL_CXXALIAS_SYS (mktime_z, time_t,
- (timezone_t __tz, struct tm *restrict __result));
+ (timezone_t __tz, struct tm *restrict __tm));
+
+/* Time zone abbreviation strings (returned by 'localtime_rz' or 'mktime_z'
+ in the 'tm_zone' member of 'struct tm') are valid as long as
+ - the 'struct tm' argument is not destroyed or overwritten,
+ and
+ - the 'timezone_t' argument is not freed through tzfree(). */
+
# endif
/* Convert TM to a time_t value, assuming UTC. */
diff --git a/lib/time_r.c b/lib/time_r.c
index d9089868704..88d3c1c76f9 100644
--- a/lib/time_r.c
+++ b/lib/time_r.c
@@ -2,18 +2,18 @@
Copyright (C) 2003, 2006-2007, 2010-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
/* Written by Paul Eggert. */
diff --git a/lib/time_rz.c b/lib/time_rz.c
index 3ac053c6219..e7722447c06 100644
--- a/lib/time_rz.c
+++ b/lib/time_rz.c
@@ -2,18 +2,18 @@
Copyright 2015-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
/* Written by Paul Eggert. */
diff --git a/lib/timegm.c b/lib/timegm.c
index e4127e71c0b..7e723e1fb87 100644
--- a/lib/timegm.c
+++ b/lib/timegm.c
@@ -4,16 +4,16 @@
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public
+ modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public
+ You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
diff --git a/lib/timespec.c b/lib/timespec.c
index 2b6098ed7bd..957b5fbba49 100644
--- a/lib/timespec.c
+++ b/lib/timespec.c
@@ -1,3 +1,21 @@
+/* Inline functions for <timespec.h>.
+
+ Copyright (C) 2012-2021 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 3 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/>. */
+
#include <config.h>
+
#define _GL_TIMESPEC_INLINE _GL_EXTERN_INLINE
#include "timespec.h"
diff --git a/lib/timespec.h b/lib/timespec.h
index 9a71e9ea893..94a5db751fc 100644
--- a/lib/timespec.h
+++ b/lib/timespec.h
@@ -3,17 +3,17 @@
Copyright (C) 2000, 2002, 2004-2005, 2007, 2009-2021 Free Software
Foundation, Inc.
- 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 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
#if ! defined TIMESPEC_H
diff --git a/lib/u64.c b/lib/u64.c
index 1e3854ddcd7..c905af626fd 100644
--- a/lib/u64.c
+++ b/lib/u64.c
@@ -1,4 +1,22 @@
+/* uint64_t-like operations that work even on hosts lacking uint64_t
+
+ Copyright (C) 2012-2021 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/>. */
+
#include <config.h>
+
#define _GL_U64_INLINE _GL_EXTERN_INLINE
#include "u64.h"
typedef int dummy;
diff --git a/lib/u64.h b/lib/u64.h
index ad719c84f88..8d21ec17edb 100644
--- a/lib/u64.h
+++ b/lib/u64.h
@@ -2,17 +2,17 @@
Copyright (C) 2006, 2009-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Paul Eggert. */
diff --git a/lib/unistd.c b/lib/unistd.c
index 72bad1c0527..0763456021a 100644
--- a/lib/unistd.c
+++ b/lib/unistd.c
@@ -1,4 +1,22 @@
+/* Inline functions for <unistd.h>.
+
+ Copyright (C) 2012-2021 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/>. */
+
#include <config.h>
+
#define _GL_UNISTD_INLINE _GL_EXTERN_INLINE
#include "unistd.h"
typedef int dummy;
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 5e9b47d981e..73c882f97ba 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -1,18 +1,18 @@
/* Substitute for and wrapper around <unistd.h>.
Copyright (C) 2003-2021 Free Software Foundation, Inc.
- 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, or (at your option)
- any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser 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/>. */
+ 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/>. */
#ifndef _@GUARD_PREFIX@_UNISTD_H
@@ -1521,6 +1521,7 @@ _GL_WARN_ON_USE (group_member, "group_member is unportable - "
# undef isatty
# define isatty rpl_isatty
# endif
+# define GNULIB_defined_isatty 1
_GL_FUNCDECL_RPL (isatty, int, (int fd));
_GL_CXXALIAS_RPL (isatty, int, (int fd));
# elif defined _WIN32 && !defined __CYGWIN__
@@ -2027,15 +2028,23 @@ _GL_WARN_ON_USE (sleep, "sleep is unportable - "
#if @GNULIB_MDA_SWAB@
/* On native Windows, map 'swab' to '_swab', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between
- platforms by defining GNULIB_NAMESPACE::creat always. */
+ platforms by defining GNULIB_NAMESPACE::swab always. */
# if defined _WIN32 && !defined __CYGWIN__
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef swab
# define swab _swab
# endif
-_GL_CXXALIAS_MDA (swab, void, (char *from, char *to, int n));
+/* Need to cast, because in old mingw the arguments are
+ (const char *from, char *to, size_t n). */
+_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 */
+_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));
+# endif
# endif
_GL_CXXALIASWARN (swab);
#endif
diff --git a/lib/unlocked-io.h b/lib/unlocked-io.h
index 86b91c19dd2..ca184b31fb6 100644
--- a/lib/unlocked-io.h
+++ b/lib/unlocked-io.h
@@ -33,91 +33,91 @@
# include <stdio.h>
-# if HAVE_DECL_CLEARERR_UNLOCKED
+# if HAVE_DECL_CLEARERR_UNLOCKED || defined clearerr_unlocked
# undef clearerr
# define clearerr(x) clearerr_unlocked (x)
# else
# define clearerr_unlocked(x) clearerr (x)
# endif
-# if HAVE_DECL_FEOF_UNLOCKED
+# if HAVE_DECL_FEOF_UNLOCKED || defined feof_unlocked
# undef feof
# define feof(x) feof_unlocked (x)
# else
# define feof_unlocked(x) feof (x)
# endif
-# if HAVE_DECL_FERROR_UNLOCKED
+# if HAVE_DECL_FERROR_UNLOCKED || defined ferror_unlocked
# undef ferror
# define ferror(x) ferror_unlocked (x)
# else
# define ferror_unlocked(x) ferror (x)
# endif
-# if HAVE_DECL_FFLUSH_UNLOCKED
+# if HAVE_DECL_FFLUSH_UNLOCKED || defined fflush_unlocked
# undef fflush
# define fflush(x) fflush_unlocked (x)
# else
# define fflush_unlocked(x) fflush (x)
# endif
-# if HAVE_DECL_FGETS_UNLOCKED
+# if HAVE_DECL_FGETS_UNLOCKED || defined fgets_unlocked
# undef fgets
# define fgets(x,y,z) fgets_unlocked (x,y,z)
# else
# define fgets_unlocked(x,y,z) fgets (x,y,z)
# endif
-# if HAVE_DECL_FPUTC_UNLOCKED
+# if HAVE_DECL_FPUTC_UNLOCKED || defined fputc_unlocked
# undef fputc
# define fputc(x,y) fputc_unlocked (x,y)
# else
# define fputc_unlocked(x,y) fputc (x,y)
# endif
-# if HAVE_DECL_FPUTS_UNLOCKED
+# if HAVE_DECL_FPUTS_UNLOCKED || defined fputs_unlocked
# undef fputs
# define fputs(x,y) fputs_unlocked (x,y)
# else
# define fputs_unlocked(x,y) fputs (x,y)
# endif
-# if HAVE_DECL_FREAD_UNLOCKED
+# if HAVE_DECL_FREAD_UNLOCKED || defined fread_unlocked
# undef fread
# define fread(w,x,y,z) fread_unlocked (w,x,y,z)
# else
# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
# endif
-# if HAVE_DECL_FWRITE_UNLOCKED
+# if HAVE_DECL_FWRITE_UNLOCKED || defined fwrite_unlocked
# undef fwrite
# define fwrite(w,x,y,z) fwrite_unlocked (w,x,y,z)
# else
# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
# endif
-# if HAVE_DECL_GETC_UNLOCKED
+# if HAVE_DECL_GETC_UNLOCKED || defined get_unlocked
# undef getc
# define getc(x) getc_unlocked (x)
# else
# define getc_unlocked(x) getc (x)
# endif
-# if HAVE_DECL_GETCHAR_UNLOCKED
+# if HAVE_DECL_GETCHAR_UNLOCKED || defined getchar_unlocked
# undef getchar
# define getchar() getchar_unlocked ()
# else
# define getchar_unlocked() getchar ()
# endif
-# if HAVE_DECL_PUTC_UNLOCKED
+# if HAVE_DECL_PUTC_UNLOCKED || defined putc_unlocked
# undef putc
# define putc(x,y) putc_unlocked (x,y)
# else
# define putc_unlocked(x,y) putc (x,y)
# endif
-# if HAVE_DECL_PUTCHAR_UNLOCKED
+# if HAVE_DECL_PUTCHAR_UNLOCKED || defined putchar_unlocked
# undef putchar
# define putchar(x) putchar_unlocked (x)
# else
diff --git a/lib/utimens.c b/lib/utimens.c
index 44d1ea003e2..a34180050ef 100644
--- a/lib/utimens.c
+++ b/lib/utimens.c
@@ -2,17 +2,17 @@
Copyright (C) 2003-2021 Free Software Foundation, Inc.
- 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 any
- later version.
+ 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Paul Eggert. */
@@ -126,14 +126,14 @@ validate_timespec (struct timespec timespec[2])
return result + (utime_omit_count == 1);
}
-/* Normalize any UTIME_NOW or UTIME_OMIT values in *TS, using stat
- buffer STATBUF to obtain the current timestamps of the file. If
+/* Normalize any UTIME_NOW or UTIME_OMIT values in (*TS)[0] and (*TS)[1],
+ using STATBUF to obtain the current timestamps of the file. If
both times are UTIME_NOW, set *TS to NULL (as this can avoid some
permissions issues). If both times are UTIME_OMIT, return true
(nothing further beyond the prior collection of STATBUF is
necessary); otherwise return false. */
static bool
-update_timespec (struct stat const *statbuf, struct timespec *ts[2])
+update_timespec (struct stat const *statbuf, struct timespec **ts)
{
struct timespec *timespec = *ts;
if (timespec[0].tv_nsec == UTIME_OMIT
diff --git a/lib/utimens.h b/lib/utimens.h
index 295d3d71cca..d17953c0523 100644
--- a/lib/utimens.h
+++ b/lib/utimens.h
@@ -2,17 +2,17 @@
Copyright 2012-2021 Free Software Foundation, Inc.
- 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 any
- later version.
+ 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 3 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Paul Eggert. */
diff --git a/lib/verify.h b/lib/verify.h
index 65514c34b9e..a8ca59b0934 100644
--- a/lib/verify.h
+++ b/lib/verify.h
@@ -2,17 +2,17 @@
Copyright (C) 2005-2006, 2009-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */
@@ -25,7 +25,7 @@
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 C2x. 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
@@ -202,7 +202,7 @@ 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 C2x one-argument syntax.
Unfortunately, unlike C11, this implementation must appear as an
ordinary declaration, and cannot appear inside struct { ... }. */
diff --git a/lib/warn-on-use.h b/lib/warn-on-use.h
index 5d5b17f05be..612937abb02 100644
--- a/lib/warn-on-use.h
+++ b/lib/warn-on-use.h
@@ -2,16 +2,16 @@
Copyright (C) 2010-2021 Free Software Foundation, Inc.
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
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
/* _GL_WARN_ON_USE (function, "literal string") issues a declaration
diff --git a/lib/xalloc-oversized.h b/lib/xalloc-oversized.h
index 53daf59663e..4184f339555 100644
--- a/lib/xalloc-oversized.h
+++ b/lib/xalloc-oversized.h
@@ -2,17 +2,17 @@
Copyright (C) 1990-2000, 2003-2004, 2006-2021 Free Software Foundation, Inc.
- 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 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ 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/>. */
#ifndef XALLOC_OVERSIZED_H_
@@ -21,34 +21,39 @@
#include <stddef.h>
#include <stdint.h>
-/* True if N * S would overflow in a size_t calculation,
- or would generate a value larger than PTRDIFF_MAX.
+/* True if N * S does not fit into both ptrdiff_t and size_t.
+ N and S should be nonnegative and free of side effects.
This expands to a constant expression if N and S are both constants.
- By gnulib convention, SIZE_MAX represents overflow in size
+ By gnulib convention, SIZE_MAX represents overflow in size_t
calculations, so the conservative size_t-based dividend to use here
is SIZE_MAX - 1. */
#define __xalloc_oversized(n, s) \
- ((size_t) (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX - 1) / (s) < (n))
+ ((s) != 0 \
+ && ((size_t) (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX - 1) / (s) \
+ < (n)))
-#if PTRDIFF_MAX < SIZE_MAX
-typedef ptrdiff_t __xalloc_count_type;
-#else
-typedef size_t __xalloc_count_type;
-#endif
+/* Return 1 if and only if an array of N objects, each of size S,
+ cannot exist reliably because its total size in bytes would exceed
+ MIN (PTRDIFF_MAX, SIZE_MAX - 1).
+
+ N and S should be nonnegative and free of side effects.
-/* Return 1 if an array of N objects, each of size S, cannot exist
- reliably due to size or ptrdiff_t arithmetic overflow. S must be
- positive and N must be nonnegative. This is a macro, not a
- function, so that it works correctly even when SIZE_MAX < N. */
+ Warning: (xalloc_oversized (N, S) ? NULL : malloc (N * S)) can
+ misbehave if N and S are both narrower than ptrdiff_t and size_t,
+ and can be rewritten as (xalloc_oversized (N, S) ? NULL
+ : malloc (N * (size_t) S)).
-#if 7 <= __GNUC__ && !defined __clang__
+ This is a macro, not a function, so that it works even if an
+ argument exceeds MAX (PTRDIFF_MAX, SIZE_MAX). */
+#if 7 <= __GNUC__ && !defined __clang__ && PTRDIFF_MAX < SIZE_MAX
# define xalloc_oversized(n, s) \
- __builtin_mul_overflow_p (n, s, (__xalloc_count_type) 1)
-#elif 5 <= __GNUC__ && !defined __ICC && !__STRICT_ANSI__
+ __builtin_mul_overflow_p (n, s, (ptrdiff_t) 1)
+#elif (5 <= __GNUC__ && !defined __ICC && !__STRICT_ANSI__ \
+ && PTRDIFF_MAX < SIZE_MAX)
# define xalloc_oversized(n, s) \
(__builtin_constant_p (n) && __builtin_constant_p (s) \
? __xalloc_oversized (n, s) \
- : ({ __xalloc_count_type __xalloc_count; \
+ : ({ ptrdiff_t __xalloc_count; \
__builtin_mul_overflow (n, s, &__xalloc_count); }))
/* Other compilers use integer division; this may be slower but is
diff --git a/lisp/ChangeLog.12 b/lisp/ChangeLog.12
index 5d424570d83..d841a75c5d7 100644
--- a/lisp/ChangeLog.12
+++ b/lisp/ChangeLog.12
@@ -182,7 +182,7 @@
2007-04-19 Glenn Morris <rgm@gnu.org>
- * calendar/todo-mode.el: Fix typo: "threshhold" -> "threshold".
+ * calendar/todo-mode.el: Fix typo for "threshold".
2007-04-18 Glenn Morris <rgm@gnu.org>
diff --git a/lisp/ChangeLog.15 b/lisp/ChangeLog.15
index bd1fbe61ad1..29fbe474891 100644
--- a/lisp/ChangeLog.15
+++ b/lisp/ChangeLog.15
@@ -17307,7 +17307,7 @@
* simple.el (normal-erase-is-backspace-mode): Use input-decode-map
rather than fiddling with global-map bindings, since it should only
affect per-terminal settings.
- See http://bugs.gentoo.org/show_bug.cgi?id=289709.
+ See https://bugs.gentoo.org/show_bug.cgi?id=289709.
* minibuffer.el (completion-table-with-terminator): Allow to specify
the terminator-regexp.
diff --git a/lisp/ChangeLog.17 b/lisp/ChangeLog.17
index 14a6c5d06e4..4dd3df5953b 100644
--- a/lisp/ChangeLog.17
+++ b/lisp/ChangeLog.17
@@ -10766,7 +10766,7 @@
* emacs-lisp/find-gc.el (find-gc-source-directory): Give it a value.
(find-gc-source-files): Update some names.
(trace-call-tree): Simplify and update.
- Avoid predictable temp-file names. (http://bugs.debian.org/747100)
+ Avoid predictable temp-file names. (https://bugs.debian.org/747100)
This is CVE-2014-3422.
2014-05-08 Stefan Monnier <monnier@iro.umontreal.ca>
@@ -17742,7 +17742,7 @@
2013-10-13 Glenn Morris <rgm@gnu.org>
* progmodes/sh-script.el (sh-mark-line, sh-learn-buffer-indent):
- Occur buffers are read-only. http://bugs.debian.org/720775
+ Occur buffers are read-only. https://bugs.debian.org/720775
* emacs-lisp/authors.el (authors-fixed-entries):
Comment out old alpha stuff.
diff --git a/lisp/ChangeLog.7 b/lisp/ChangeLog.7
index 3de3f2f1571..3dd8313c6a3 100644
--- a/lisp/ChangeLog.7
+++ b/lisp/ChangeLog.7
@@ -15867,7 +15867,7 @@
the key line of an entry.
* bibtex.el (bibtex-autokey-year-use-crossref-entry): New variable
- to determine if crossreferenced entry should be used for autokey
+ to determine if cross-referenced entry should be used for autokey
generation, if year field of current entry is absent.
(bibtex-generate-autokey): Use this new variable.
diff --git a/lisp/ChangeLog.8 b/lisp/ChangeLog.8
index 3027463e539..39e757bfff1 100644
--- a/lisp/ChangeLog.8
+++ b/lisp/ChangeLog.8
@@ -1147,7 +1147,7 @@
(bibtex-submit-bug-report): Use bibtex-version and
bibtex-maintainer-salutation.
(bibtex-entry-field-alist): Made booktitle field optional for
- @inproceedings entries when crossreferenced.
+ @inproceedings entries when cross-referenced.
(bibtex-entry-field-alist): Add booktitle field to proceedings
entry type (for cross referencing). Thanks to Wagner Toledo Correa
for the suggestion.
diff --git a/lisp/Makefile.in b/lisp/Makefile.in
index 431217a9dac..df9e5c36ee1 100644
--- a/lisp/Makefile.in
+++ b/lisp/Makefile.in
@@ -60,7 +60,7 @@ BYTE_COMPILE_EXTRA_FLAGS =
# The example above is just for developers, it should not be used by default.
# Those automatically generated autoload files that need special rules
-# to build; ie not including things created via generated-autoload-file
+# to build; i.e. not including things created via generated-autoload-file
# (eg calc/calc-loaddefs.el).
LOADDEFS = $(lisp)/calendar/cal-loaddefs.el \
$(lisp)/calendar/diary-loaddefs.el \
@@ -98,7 +98,7 @@ COMPILE_FIRST += $(lisp)/emacs-lisp/autoload.elc
# Files to compile early in compile-main. Works around bug#25556.
MAIN_FIRST = ./emacs-lisp/eieio.el ./emacs-lisp/eieio-base.el \
- ./cedet/semantic/db.el
+ ./cedet/semantic/db.el ./emacs-lisp/cconv.el
# Prevent any settings in the user environment causing problems.
unexport EMACSDATA EMACSDOC EMACSPATH
@@ -205,6 +205,9 @@ autoloads-force:
rm -f $(lisp)/loaddefs.el
$(MAKE) autoloads
+ldefs-boot.el: autoloads-force
+ cp $(lisp)/loaddefs.el $(lisp)/ldefs-boot.el
+
# This is required by the bootstrap-emacs target in ../src/Makefile, so
# we know that if we have an emacs executable, we also have a subdirs.el.
$(lisp)/subdirs.el:
@@ -281,6 +284,14 @@ else
-f batch-byte-compile $(THEFILE)
endif
+ifeq ($(HAVE_NATIVE_COMP),yes)
+.PHONY: $(THEFILE)n
+$(THEFILE)n:
+ $(AM_V_ELN)$(emacs) $(BYTE_COMPILE_FLAGS) \
+ -l comp -f byte-compile-refresh-preloaded \
+ --eval '(batch-native-compile t)' $(THEFILE)
+endif
+
# Files MUST be compiled one by one. If we compile several files in a
# row (i.e., in the same instance of Emacs) we can't make sure that
# the compilation environment is clean. We also set the load-path of
@@ -327,10 +338,10 @@ endif
# Compile all the Elisp files that need it. Beware: it approximates
# 'no-byte-compile', so watch out for false-positives!
-compile-main: gen-lisp compile-clean
+compile-main: gen-lisp compile-clean main-first
@(cd $(lisp) && \
els=`echo "${SUBDIRS_REL} " | sed -e 's|/\./|/|g' -e 's|/\. | |g' -e 's| |/*.el |g'`; \
- for el in ${MAIN_FIRST} $$els; do \
+ for el in $$els; do \
test -f $$el || continue; \
test ! -f $${el}c && \
GREP_OPTIONS= grep '^;.*[^a-zA-Z]no-byte-compile: *t' $$el > /dev/null && \
@@ -343,6 +354,18 @@ compile-main: gen-lisp compile-clean
TARGETS="$$chunk"; \
done
+# Compile some important files first.
+main-first:
+ @(cd $(lisp) && \
+ for el in ${MAIN_FIRST}; do \
+ echo "$${el}c"; \
+ done | xargs $(XARGS_LIMIT) echo) | \
+ while read chunk; do \
+ $(MAKE) compile-targets \
+ NATIVE_DISABLED=$(NATIVE_SKIP_NONDUMP) \
+ TARGETS="$$chunk"; \
+ done
+
.PHONY: compile-clean
# Erase left-over .elc files that do not have a corresponding .el file.
compile-clean:
diff --git a/lisp/abbrev.el b/lisp/abbrev.el
index 54783db2c3e..386aff16270 100644
--- a/lisp/abbrev.el
+++ b/lisp/abbrev.el
@@ -288,6 +288,10 @@ or zero means the region is the expansion.
A negative argument means to undefine the specified abbrev.
Reads the abbreviation in the minibuffer.
+See also `inverse-add-mode-abbrev', which performs the opposite task:
+if the abbrev text is already in the buffer, use this command to
+define an abbrev by specifying the expansion in the minibuffer.
+
Don't use this function in a Lisp program; use `define-abbrev' instead."
(interactive "p")
(add-abbrev
@@ -304,6 +308,10 @@ expansion; or zero means the region is the expansion.
A negative argument means to undefine the specified abbrev.
This command uses the minibuffer to read the abbreviation.
+See also `inverse-add-global-abbrev', which performs the opposite task:
+if the abbrev text is already in the buffer, use this command to
+define an abbrev by specifying the expansion in the minibuffer.
+
Don't use this function in a Lisp program; use `define-abbrev' instead."
(interactive "p")
(add-abbrev global-abbrev-table "Global" arg))
@@ -330,7 +338,11 @@ Don't use this function in a Lisp program; use `define-abbrev' instead."
"Define last word before point as a mode-specific abbrev.
With prefix argument N, defines the Nth word before point.
This command uses the minibuffer to read the expansion.
-Expands the abbreviation after defining it."
+Expands the abbreviation after defining it.
+
+See also `add-mode-abbrev', which performs the opposite task:
+if the expansion is already in the buffer, use this command
+to define an abbrev by specifying the abbrev in the minibuffer."
(interactive "p")
(inverse-add-abbrev
(if only-global-abbrevs
@@ -343,7 +355,11 @@ Expands the abbreviation after defining it."
"Define last word before point as a global (mode-independent) abbrev.
With prefix argument N, defines the Nth word before point.
This command uses the minibuffer to read the expansion.
-Expands the abbreviation after defining it."
+Expands the abbreviation after defining it.
+
+See also `add-global-abbrev', which performs the opposite task:
+if the expansion is already in the buffer, use this command
+to define an abbrev by specifying the abbrev in the minibuffer."
(interactive "p")
(inverse-add-abbrev global-abbrev-table "Global" n))
@@ -387,7 +403,7 @@ argument."
(defun expand-region-abbrevs (start end &optional noquery)
"For abbrev occurrence in the region, offer to expand it.
-The user is asked to type `y' or `n' for each occurrence.
+The user is asked to type \\`y' or \\`n' for each occurrence.
A prefix argument means don't query; expand all abbrevs."
(interactive "r\nP")
(save-excursion
@@ -567,6 +583,7 @@ PROPS is a property list. The following properties are special:
An obsolete but still supported calling form is:
\(define-abbrev TABLE NAME EXPANSION &optional HOOK COUNT SYSTEM)."
+ (declare (indent defun))
(when (and (consp props) (or (null (car props)) (numberp (car props))))
;; Old-style calling convention.
(setq props `(:count ,(car props)
@@ -957,11 +974,11 @@ full text instead of the abbrevs that expand into that text."
(buf (get-buffer-create "*abbrev-suggest*")))
(set-buffer buf)
(erase-buffer)
- (insert "** Abbrev expansion usage **
+ (insert (substitute-command-keys "** Abbrev expansion usage **
Below is a list of expansions for which abbrevs are defined, and
the number of times the expansion was typed manually. To display
-and edit all abbrevs, type `M-x edit-abbrevs RET'\n\n")
+and edit all abbrevs, type \\[edit-abbrevs].\n\n"))
(dolist (expansion totals)
(insert (format " %s: %d\n" (car expansion) (cdr expansion))))
(display-buffer buf)))
@@ -1123,7 +1140,7 @@ Properties with special meaning:
- `:enable-function' can be set to a function of no argument which returns
non-nil if and only if the abbrevs in this table should be used for this
instance of `expand-abbrev'."
- (declare (doc-string 3))
+ (declare (doc-string 3) (indent defun))
;; We used to manually add the docstring, but we also want to record this
;; location as the definition of the variable (in load-history), so we may
;; as well just use `defvar'.
diff --git a/lisp/align.el b/lisp/align.el
index a0b626a5c43..2fd6dcda6d7 100644
--- a/lisp/align.el
+++ b/lisp/align.el
@@ -553,8 +553,7 @@ The possible settings for `align-region-separate' are:
(modes . align-text-modes)
(repeat . t)
(run-if . ,(lambda ()
- (and current-prefix-arg
- (not (eq '- current-prefix-arg))))))
+ (not (eq '- current-prefix-arg)))))
;; With a negative prefix argument, lists of dollar figures will
;; be aligned.
@@ -787,7 +786,7 @@ See the variable `align-exclude-rules-list' for more details.")
"The current overlays highlighting the text matched by a rule.")
(defvar align-regexp-history nil
- "Input history for the full user-entered regex in `align-regexp'")
+ "Input history for the full user-entered regex in `align-regexp'.")
;; Sample extension rule set for vhdl-mode. This is now obsolete.
(defcustom align-vhdl-rules-list
@@ -836,11 +835,22 @@ See the variable `align-exclude-rules-list' for more details.")
;;;###autoload
(defun align (beg end &optional separate rules exclude-rules)
"Attempt to align a region based on a set of alignment rules.
-BEG and END mark the region. If BEG and END are specifically set to
-nil (this can only be done programmatically), the beginning and end of
-the current alignment section will be calculated based on the location
-of point, and the value of `align-region-separate' (or possibly each
-rule's `separate' attribute).
+Interactively, BEG and END are the mark/point of the current region.
+
+Many modes define specific alignment rules, and some of these
+rules in some modes react to the current prefix argument. For
+instance, in `text-mode', `M-x align' will align into columns
+based on space delimiters, while `C-u - M-x align' will align
+into columns based on the \"$\" character. See the
+`align-rules-list' variable definition for the specific rules.
+
+Also see `align-regexp', which will guide you through various
+parameters for aligning text.
+
+Non-interactively, if BEG and END are nil, the beginning and end
+of the current alignment section will be calculated based on the
+location of point, and the value of `align-region-separate' (or
+possibly each rule's `separate' attribute).
If SEPARATE is non-nil, it overrides the value of
`align-region-separate' for all rules, except those that have their
@@ -889,6 +899,15 @@ on the format of these lists."
BEG and END mark the limits of the region. Interactively, this function
prompts for the regular expression REGEXP to align with.
+Interactively, if you specify a prefix argument, the function
+will guide you through entering the full regular expression, and
+then prompts for which subexpression parenthesis GROUP (default
+1) within REGEXP to modify, the amount of SPACING (default
+`align-default-spacing') to use, and whether or not to REPEAT the
+rule throughout the line.
+
+See `align-rules-list' for more information about these options.
+
For example, let's say you had a list of phone numbers, and wanted to
align them so that the opening parentheses would line up:
@@ -897,24 +916,19 @@ align them so that the opening parentheses would line up:
Mary-Anne (123) 456-7890
Joe (123) 456-7890
-There is no predefined rule to handle this, but you could easily do it
-using a REGEXP like \"(\". Interactively, all you would have to do is
-to mark the region, call `align-regexp' and enter that regular expression.
+There is no predefined rule to handle this, but interactively,
+all you would have to do is to mark the region, call `align-regexp'
+and enter \"(\".
-REGEXP must contain at least one parenthesized subexpression, typically
-whitespace of the form \"\\\\(\\\\s-*\\\\)\". In normal interactive use,
-this is automatically added to the start of your regular expression after
-you enter it. You only need to supply the characters to be lined up, and
-any preceding whitespace is replaced.
+REGEXP must contain at least one parenthesized subexpression,
+typically whitespace of the form \"\\\\(\\\\s-*\\\\)\", but in
+interactive use, this is automatically added to the start of your
+regular expression after you enter it. Interactively, you only
+need to supply the characters to be lined up, and any preceding
+whitespace is replaced.
-If you specify a prefix argument (or use this function non-interactively),
-you must enter the full regular expression, including the subexpression.
-The function also then prompts for which subexpression parenthesis GROUP
-\(default 1) within REGEXP to modify, the amount of SPACING (default
-`align-default-spacing') to use, and whether or not to REPEAT the rule
-throughout the line.
-
-See `align-rules-list' for more information about these options.
+Non-interactively, you must enter the full regular expression,
+including the subexpression.
The non-interactive form of the previous example would look something like:
(align-regexp (point-min) (point-max) \"\\\\(\\\\s-*\\\\)(\")
@@ -926,7 +940,7 @@ construct a rule to pass to `align-region', which does the real work."
(list (region-beginning) (region-end))
(if current-prefix-arg
(list (read-string "Complex align using regexp: "
- "\\(\\s-*\\)" 'align-regexp-history)
+ "\\(\\s-*\\) " 'align-regexp-history)
(string-to-number
(read-string
"Parenthesis group to modify (justify if negative): " "1"))
diff --git a/lisp/allout-widgets.el b/lisp/allout-widgets.el
index 0e127040886..f18d4888543 100644
--- a/lisp/allout-widgets.el
+++ b/lisp/allout-widgets.el
@@ -32,7 +32,7 @@
;; invoke allout-widgets-mode in a particular allout buffer. When
;; auto-enabled, you can inhibit widget operation in particular allout
;; buffers by setting the variable `allout-widgets-mode-inhibit' non-nil in
-;; that file's buffer. Use emacs *file local variables* to generally
+;; that file's buffer. Use Emacs *file local variables* to generally
;; inhibit for a file.
;;
;; See the `allout-widgets-mode' docstring for more details.
@@ -55,7 +55,7 @@
;; bindings for easy outline navigation and exposure control, extending
;; outline hot-spot navigation (see `allout-mode' docstring for details).
;;
-;; Developers note: Our use of emacs widgets is unconventional. We
+;; Developers note: Our use of Emacs widgets is unconventional. We
;; decorate existing text rather than substituting for it, to
;; piggy-back on existing allout operation. This employs the C-coded
;; efficiencies of widget-apply, widget-get, and widget-put, along
@@ -87,7 +87,7 @@
"Allout extension that highlights outline structure graphically.
Customize `allout-widgets-auto-activation' to activate allout-widgets
-with allout-mode."
+with `allout-mode'."
:group 'allout)
;;;_ > defgroup allout-widgets-developer
(defgroup allout-widgets-developer nil
@@ -96,19 +96,19 @@ with allout-mode."
;;;_ ; some functions a bit early, for allout-auto-activation dependency:
;;;_ > allout-widgets-mode-enable
(defun allout-widgets-mode-enable ()
- "Enable allout-widgets-mode in allout-mode buffers.
+ "Enable `allout-widgets-mode' in `allout-mode' buffers.
See `allout-widgets-mode-inhibit' for per-file/per-buffer
-inhibition of allout-widgets-mode."
+inhibition of `allout-widgets-mode'."
(add-hook 'allout-mode-off-hook #'allout-widgets-mode-off)
(add-hook 'allout-mode-on-hook #'allout-widgets-mode-on)
t)
;;;_ > allout-widgets-mode-disable
(defun allout-widgets-mode-disable ()
- "Disable allout-widgets-mode in allout-mode buffers.
+ "Disable `allout-widgets-mode' in `allout-mode' buffers.
See `allout-widgets-mode-inhibit' for per-file/per-buffer
-inhibition of allout-widgets-mode."
+inhibition of `allout-widgets-mode'."
(remove-hook 'allout-mode-off-hook #'allout-widgets-mode-off)
(remove-hook 'allout-mode-on-hook #'allout-widgets-mode-on)
t)
@@ -384,7 +384,7 @@ onto the front.")
)
;;;_ = allout-doing-exposure-undo-processor nil
(defvar allout-undo-exposure-in-progress nil
- "Maintained true during `allout-widgets-exposure-undo-processor'")
+ "Maintained true during `allout-widgets-exposure-undo-processor'.")
;;;_ , Widget-specific outline text format
;;;_ = allout-escaped-prefix-regexp
(defvar-local allout-escaped-prefix-regexp ""
@@ -880,7 +880,7 @@ encompassing condition-case."
;; reraise the error, or one concerning this function if unexpected:
(if (equal mode 'error)
(apply #'signal args)
- (error "%s: unexpected mode, %s %s" this mode args))))
+ (error "%s: Unexpected mode, %s %s" this mode args))))
;;;_ > allout-widgets-changes-exceed-threshold-p ()
(defun allout-widgets-adjusting-message (message)
"Post MESSAGE when pending are likely to make a big enough delay.
@@ -1450,7 +1450,7 @@ recursive operation."
)
;;;_ > allout-new-item-widget ()
(defsubst allout-new-item-widget ()
- "create a new item widget, not yet situated anywhere."
+ "Create a new item widget, not yet situated anywhere."
(if allout-widgets-maintain-tally
;; all the extra overhead is incurred only when doing the
;; maintenance, except the condition, which can't be avoided.
diff --git a/lisp/allout.el b/lisp/allout.el
index 0625ea68abe..f684751a2a4 100644
--- a/lisp/allout.el
+++ b/lisp/allout.el
@@ -26,7 +26,7 @@
;;; Commentary:
;; Allout outline minor mode provides extensive outline formatting and
-;; and manipulation beyond standard emacs outline mode. Some features:
+;; and manipulation beyond standard Emacs outline mode. Some features:
;;
;; - Classic outline-mode topic-oriented navigation and exposure adjustment
;; - Topic-oriented editing including coherent topic and subtopic
@@ -35,7 +35,7 @@
;; - Customizable bullet format -- enables programming-language specific
;; outlining, for code-folding editing. (Allout code itself is to try it;
;; formatted as an outline -- do ESC-x eval-buffer in allout.el; but
-;; emacs local file variables need to be enabled when the
+;; Emacs local file variables need to be enabled when the
;; file was visited -- see `enable-local-variables'.)
;; - Configurable per-file initial exposure settings
;; - Symmetric-key and key-pair topic encryption. Encryption is via the
@@ -116,7 +116,7 @@ Do NOT set the value of this variable. Instead, customize
"Create the allout keymap according to the keybinding specs, and set it.
Useful standalone or to effect customizations of the
-respective allout-mode keybinding variables, `allout-command-prefix',
+respective `allout-mode' keybinding variables, `allout-command-prefix',
`allout-prefixed-keybindings', and `allout-unprefixed-keybindings'"
;; Set the customization variable, if any:
(when varname
@@ -133,19 +133,14 @@ respective allout-mode keybinding variables, `allout-command-prefix',
(when (boundp 'allout-unprefixed-keybindings)
(dolist (entry allout-unprefixed-keybindings)
(define-key map (car (read-from-string (car entry))) (cadr entry))))
- (substitute-key-definition #'beginning-of-line #'allout-beginning-of-line
- map global-map)
- (substitute-key-definition #'move-beginning-of-line
- #'allout-beginning-of-line
- map global-map)
- (substitute-key-definition #'end-of-line #'allout-end-of-line
- map global-map)
- (substitute-key-definition #'move-end-of-line #'allout-end-of-line
- map global-map)
+ (define-key map [remap beginning-of-line] #'allout-beginning-of-line)
+ (define-key map [remap move-beginning-of-line] #'allout-beginning-of-line)
+ (define-key map [remap end-of-line] #'allout-end-of-line)
+ (define-key map [remap move-end-of-line] #'allout-end-of-line)
(allout-institute-keymap map)))
;;;_ > allout-institute-keymap (map)
(defun allout-institute-keymap (map)
- "Associate allout-mode bindings with allout as a minor mode."
+ "Associate `allout-mode' bindings with allout as a minor mode."
;; Architecture:
;; allout-mode-map var is a keymap by virtue of being a defalias for
;; allout-mode-map-value, which has the actual keymap value.
@@ -242,7 +237,7 @@ prevails."
)
"Allout-mode functions bound to keys without any added prefix.
-This is in contrast to the majority of allout-mode bindings on
+This is in contrast to the majority of `allout-mode' bindings on
`allout-prefixed-keybindings', whose bindings are created with a
preceding command key.
@@ -288,7 +283,7 @@ Control whether and how allout outline mode is automatically
activated when files are visited with non-nil buffer-specific
file variable `allout-layout'.
-When allout-auto-activation is \"On\" (t), allout mode is
+When `allout-auto-activation' is \"On\" (t), allout mode is
activated in buffers with non-nil `allout-layout', and the
specified layout is applied.
@@ -358,7 +353,7 @@ Examples:
See `allout-expose-topic' for more about the exposure process.
Also, allout's mode-specific provisions will make topic prefixes default
-to the comment-start string, if any, of the language of the file. This
+to the `comment-start' string, if any, of the language of the file. This
is modulo the setting of `allout-use-mode-specific-leader', which see."
:type 'allout-layout-type
:group 'allout)
@@ -382,7 +377,7 @@ in individual buffers if you want to inhibit auto-fill only in particular
buffers. (You could use a function on `allout-mode-hook' to inhibit
auto-fill according, eg, to the major mode.)
-If you don't set this and auto-fill-mode is enabled, allout will use the
+If you don't set this and `auto-fill-mode' is enabled, allout will use the
value that `normal-auto-fill-function', if any, when allout mode starts, or
else allout's special hanging-indent maintaining auto-fill function,
`allout-auto-fill'."
@@ -429,8 +424,7 @@ those that do not have the variable `comment-start' set. A value of
;;;_ = allout-show-bodies
(defcustom allout-show-bodies nil
- "If non-nil, show entire body when exposing a topic, rather than
-just the header."
+ "If non-nil, show entire body when exposing a topic, rather than just the header."
:type 'boolean
:group 'allout)
(make-variable-buffer-local 'allout-show-bodies)
@@ -460,7 +454,7 @@ advance as follows:
- if the cursor is on the first column of the headline:
then it goes to the start of the headline within the item body.
-In this fashion, you can use the beginning-of-line command to do
+In this fashion, you can use the `beginning-of-line' command to do
its normal job and then, when repeated, advance through the
entry, cycling back to start.
@@ -596,16 +590,16 @@ strings."
"When non-nil, use mode-specific topic-header prefixes.
Allout outline mode will use the mode-specific `allout-mode-leaders' or
-comment-start string, if any, to lead the topic prefix string, so topic
+`comment-start' string, if any, to lead the topic prefix string, so topic
headers look like comments in the programming language. It will also use
-the comment-start string, with an `_' appended, for `allout-primary-bullet'.
+the `comment-start' string, with an `_' appended, for `allout-primary-bullet'.
String values are used as literals, not regular expressions, so
do not escape any regular-expression characters.
Value t means to first check for assoc value in `allout-mode-leaders'
-alist, then use comment-start string, if any, then use default (`.').
-\(See note about use of comment-start strings, below.)
+alist, then use `comment-start' string, if any, then use default (`.').
+\(See note about use of `comment-start' strings, below.)
Set to the symbol for either of `allout-mode-leaders' or
`comment-start' to use only one of them, respectively.
@@ -613,9 +607,9 @@ Set to the symbol for either of `allout-mode-leaders' or
Value nil means to always use the default (`.') and leave
`allout-primary-bullet' unaltered.
-comment-start strings that do not end in spaces are tripled in
+`comment-start' strings that do not end in spaces are tripled in
the header-prefix, and an `_' underscore is tacked on the end, to
-distinguish them from regular comment strings. comment-start
+distinguish them from regular comment strings. `comment-start'
strings that do end in spaces are not tripled, but an underscore
is substituted for the space. [This presumes that the space is
for appearance, not comment syntax. You can use
@@ -633,8 +627,8 @@ undesired.]"
(defvar allout-mode-leaders '()
"Specific allout-prefix leading strings per major modes.
-Use this if the mode's comment-start string isn't what you
-prefer, or if the mode lacks a comment-start string. See
+Use this if the mode's `comment-start' string isn't what you
+prefer, or if the mode lacks a `comment-start' string. See
`allout-use-mode-specific-leader' for more details.
If you're constructing a string that will comment-out outline
@@ -824,12 +818,12 @@ such topics are encrypted.)"
:group 'allout-encryption)
(make-variable-buffer-local 'allout-encrypt-unencrypted-on-saves)
(defvar allout-auto-save-temporarily-disabled nil
- "True while topic encryption is pending and auto-saving was active.
+ "Non-nil while topic encryption is pending and auto-saving was active.
The value of `buffer-saved-size' at the time of decryption is used,
for restoring when all encryptions are established.")
(defvar-local allout-just-did-undo nil
- "True just after undo commands, until allout-post-command-business.")
+ "Non-nil just after undo commands, until allout-post-command-business.")
;;;_ + Developer
;;;_ = allout-developer group
@@ -860,7 +854,7 @@ For details, see `allout-toggle-current-subtree-encryption's docstring."
;;;_ : Version
;;;_ = allout-version
(defvar allout-version "2.3"
- "Version of currently loaded outline package. (allout.el)")
+ "Version of currently loaded allout.el package.")
;;;_ > allout-version
(defun allout-version (&optional here)
"Return string describing the loaded outline version."
@@ -882,7 +876,7 @@ has been customized to enable this behavior), `allout-mode' will be
automatically activated. The layout dictated by the value will be used to
set the initial exposure when `allout-mode' is activated.
-*You should not setq-default this variable non-nil unless you want every
+*You should not `setq-default' this variable non-nil unless you want every
visited file to be treated as an allout file.*
The value would typically be set by a file local variable. For
@@ -1321,21 +1315,21 @@ The settings are stored on `allout-mode-prior-settings'."
(if qualifier
(cond ((eq qualifier 'extend)
(if (not (listp prior-value))
- (error "extension of non-list prior value attempted")
+ (error "Extension of non-list prior value attempted")
(set name (cons value prior-value))))
((eq qualifier 'append)
(if (not (listp prior-value))
- (error "appending of non-list prior value attempted")
+ (error "Appending of non-list prior value attempted")
(set name (append prior-value (list value)))))
- (t (error "unrecognized setting qualifier `%s' encountered"
+ (t (error "Unrecognized setting qualifier `%s' encountered"
qualifier)))
(set name value)))))
;;;_ > allout-do-resumptions ()
(defun allout-do-resumptions ()
"Resume all name/value settings registered by `allout-add-resumptions'.
-This is used when concluding allout-mode, to resume selected variables to
-their settings before allout-mode was started."
+This is used when concluding `allout-mode', to resume selected variables to
+their settings before `allout-mode' was started."
(while allout-mode-prior-settings
(let* ((pair (pop allout-mode-prior-settings))
@@ -1509,7 +1503,7 @@ See `allout-encryption-ciphertext-rejection-regexps' for rejection reasons.")
'allout-mode)
;;;_ > allout-write-contents-hook-handler ()
(defun allout-write-contents-hook-handler ()
- "Implement `allout-encrypt-unencrypted-on-saves' for file writes
+ "Implement `allout-encrypt-unencrypted-on-saves' for file writes.
Return nil if all goes smoothly, or else return an informative
message if an error is encountered. The message will serve as a
@@ -1601,7 +1595,7 @@ So `allout-post-command-business' should not reactivate it...")
;; the _transient_ opening of invisible text during isearch -- is keyed to
;; presence of the isearch-open-invisible property -- even though this
;; property controls the isearch _arrival_ behavior. This is the case at
- ;; least in emacs 21, 22.1, and xemacs 21.4.
+ ;; least in emacs 21, 22.1.
(put 'allout-exposure-category 'isearch-open-invisible
#'allout-isearch-end-handler)
(put 'allout-exposure-category 'insert-in-front-hooks
@@ -2129,7 +2123,7 @@ to return the current depth."
allout-recent-depth)
;;;_ > allout-recent-prefix ()
(defsubst allout-recent-prefix ()
- "Like `allout-recent-depth', but returns text of last encountered prefix.
+ "Like `allout-recent-depth', but return text of last encountered prefix.
All outline functions which directly do string matches to assess
headings set the variables `allout-recent-prefix-beginning' and
@@ -2139,7 +2133,7 @@ to return the current prefix."
allout-recent-prefix-end))
;;;_ > allout-recent-bullet ()
(defmacro allout-recent-bullet ()
- "Like `allout-recent-prefix', but returns bullet of last encountered prefix.
+ "Like `allout-recent-prefix', but return bullet of last encountered prefix.
All outline functions which directly do string matches to assess
headings set the variables `allout-recent-prefix-beginning' and
@@ -3080,6 +3074,8 @@ Move to buffer limit in indicated direction if headings are exhausted."
(backward (if (< arg 0) (setq arg (* -1 arg))))
(step (if backward -1 1))
(progress (allout-current-bullet-pos))
+ ;; Move to the next physical line.
+ (line-move-visual nil)
prev got)
(while (> arg 0)
@@ -3145,7 +3141,7 @@ Returns resulting position, else nil if none found."
(start-arg arg)
(backward (> 0 arg)))
(if (= 0 start-depth)
- (error "No siblings, not in a topic..."))
+ (error "No siblings, not in a topic"))
(if backward (setq arg (* -1 arg)))
(allout-back-to-current-heading)
(while (and (not (zerop arg))
@@ -3185,13 +3181,13 @@ are mapped to the command of the corresponding control-key on the
`allout-mode-map-value'.")
;;;_ = allout-command-counter
(defvar-local allout-command-counter 0
- "Counter that monotonically increases in allout-mode buffers.
+ "Counter that monotonically increases in `allout-mode' buffers.
Set by `allout-pre-command-business', to support allout addons in
coordinating with allout activity.")
;;;_ = allout-this-command-hid-text
(defvar-local allout-this-command-hid-text nil
- "True if the most recent allout-mode command hid any text.")
+ "Non-nil if the most recent `allout-mode' command hid any text.")
;;;_ > allout-post-command-business ()
(defun allout-post-command-business ()
"Outline `post-command-hook' function.
@@ -3325,7 +3321,6 @@ See `allout-auto-activation' for setup instructions."
;;;_ - Topic Format Assessment
;;;_ > allout-solicit-alternate-bullet (depth &optional current-bullet)
(defun allout-solicit-alternate-bullet (depth &optional current-bullet)
-
"Prompt for and return a bullet char as an alternative to the current one.
Offer one suitable for current depth DEPTH as default."
@@ -3999,8 +3994,7 @@ With repeat count, shift topic depth by that amount."
index
do-successors
sans-offspring)
- "Like `allout-rebullet-topic', but on nearest containing topic
-\(visible or not).
+ "Like `allout-rebullet-topic', but on nearest containing topic (visible or not).
See `allout-rebullet-heading' for rebulleting behavior.
@@ -4790,7 +4784,7 @@ Useful for coherently exposing to a random point in a hidden region."
(setq bag-it (1+ bag-it))
(if (> bag-it 1)
(error "allout-show-to-offshoot: %s"
- "Stumped by aberrant nesting.")))
+ "Stumped by aberrant nesting")))
(if (> bag-it 0) (setq bag-it 0))
(allout-show-children)
(goto-char orig-pref)))
@@ -5057,9 +5051,7 @@ Examples:
max-pos)))
;;;_ > allout-old-expose-topic (spec &rest followers)
(defun allout-old-expose-topic (spec &rest followers)
-
- "Deprecated. Use `allout-expose-topic' (with different schema
-format) instead.
+ "Deprecated. Use `allout-expose-topic' (with different schema format) instead.
Dictate wholesale exposure scheme for current topic, according to SPEC.
@@ -5089,7 +5081,7 @@ elements of the list are nested SPECs, dictating the specific exposure
for the corresponding offspring of the topic.
Optional FOLLOWERS arguments dictate exposure for succeeding siblings."
-
+ (declare (obsolete allout-expose-topic "28.1"))
(interactive "xExposure spec: ")
(let ((inhibit-field-text-motion t)
(depth (allout-current-depth))
@@ -5407,7 +5399,7 @@ Defaults:
;; Specified but not a buffer -- get it:
(let ((got (get-buffer frombuf)))
(if (not got)
- (error "allout-process-exposed: source buffer %s not found."
+ (error "allout-process-exposed: Source buffer %s not found"
frombuf)
(setq frombuf got))))
;; not specified -- default it:
@@ -5807,7 +5799,7 @@ See `allout-toggle-current-subtree-encryption' for more details."
(after-bullet-pos (point))
(was-encrypted
(progn (if (= (point-max) after-bullet-pos)
- (error "no body to encrypt"))
+ (error "No body to encrypt"))
(allout-encrypted-topic-p)))
(was-collapsed (if (not (search-forward "\n" nil t))
nil
@@ -6032,7 +6024,7 @@ signal."
;; validate result -- non-empty
(if (not result-text)
- (error "%scryption failed." (if decrypt "De" "En")))
+ (error "%scryption failed" (if decrypt "De" "En")))
(when (eq keypair-mode 'prompt-save)
diff --git a/lisp/ansi-color.el b/lisp/ansi-color.el
index 79dc821ea19..c962cbd4780 100644
--- a/lisp/ansi-color.el
+++ b/lisp/ansi-color.el
@@ -43,7 +43,7 @@
;; The "Graphic Rendition Combination Mode (GRCM)" implemented is
;; "cumulative mode" as defined in section 7.2.8. Cumulative mode
;; means that whenever possible, SGR control sequences are combined
-;; (ie. blue and bold).
+;; (i.e. blue and bold).
;; The basic functions are:
;;
@@ -90,53 +90,168 @@ as a PDF file."
:version "21.1"
:group 'processes)
+(defface ansi-color-bold
+ '((t :inherit bold))
+ "Face used to render bold text."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-faint
+ '((t :weight light))
+ "Face used to render faint text."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-italic
+ '((t :inherit italic))
+ "Face used to render italic text."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-underline
+ '((t :inherit underline))
+ "Face used to render underlined text."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-slow-blink
+ '((t :box (:line-width -1)))
+ "Face used to render slowly blinking text."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-fast-blink
+ '((t :box (:line-width -1)))
+ "Face used to render rapidly blinking text."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-inverse
+ '((t :inverse-video t))
+ "Face used to render inverted video text."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-black
+ '((t :foreground "black" :background "black"))
+ "Face used to render black color code."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-red
+ '((t :foreground "red3" :background "red3"))
+ "Face used to render red color code."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-green
+ '((t :foreground "green3" :background "green3"))
+ "Face used to render green color code."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-yellow
+ '((t :foreground "yellow3" :background "yellow3"))
+ "Face used to render yellow color code."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-blue
+ '((t :foreground "blue2" :background "blue2"))
+ "Face used to render blue color code."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-magenta
+ '((t :foreground "magenta3" :background "magenta3"))
+ "Face used to render magenta color code."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-cyan
+ '((t :foreground "cyan3" :background "cyan3"))
+ "Face used to render cyan color code."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-white
+ '((t :foreground "grey90" :background "gray90"))
+ "Face used to render white color code."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-bright-black
+ '((t :foreground "gray30" :background "gray30"))
+ "Face used to render bright black color code."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-bright-red
+ '((t :foreground "red2" :background "red2"))
+ "Face used to render bright red color code."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-bright-green
+ '((t :foreground "green2" :background "green2"))
+ "Face used to render bright green color code."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-bright-yellow
+ '((t :foreground "yellow2" :background "yellow2"))
+ "Face used to render bright yellow color code."
+ :group 'ansi-colors)
+
+(defface ansi-color-bright-blue
+ '((t :foreground "blue1" :background "blue1"))
+ "Face used to render bright blue color code."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-bright-magenta
+ '((t :foreground "magenta2" :background "magenta2"))
+ "Face used to render bright magenta color code."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-bright-cyan
+ '((t :foreground "cyan2" :background "cyan2"))
+ "Face used to render bright cyan color code."
+ :group 'ansi-colors
+ :version "28.1")
+
+(defface ansi-color-bright-white
+ '((t :foreground "white" :background "white"))
+ "Face used to render bright white color code."
+ :group 'ansi-colors
+ :version "28.1")
+
(defcustom ansi-color-faces-vector
[default bold default italic underline success warning error]
"Faces used for SGR control sequences determining a face.
This vector holds the faces used for SGR control sequence parameters 0
to 7.
-Parameter Description Face used by default
- 0 default default
- 1 bold bold
- 2 faint default
- 3 italic italic
- 4 underlined underline
- 5 slowly blinking success
- 6 rapidly blinking warning
- 7 negative image error
-
-Note that the symbol `default' is special: It will not be combined
-with the current face.
-
-This vector is used by `ansi-color-make-color-map' to create a color
-map. This color map is stored in the variable `ansi-color-map'."
+This variable is obsolete. To customize the display of faces used by
+ansi-color, change 'ansi-color-FACE', e.g. `ansi-color-bold'. To
+customize the actual faces used (e.g. to temporarily display SGR
+control sequences differently), use `ansi-color-basic-faces-vector'."
:type '(vector face face face face face face face face)
- :set 'ansi-color-map-update
- :initialize 'custom-initialize-default
:group 'ansi-colors)
+(make-obsolete-variable 'ansi-color-faces-vector 'ansi-color-basic-faces-vector
+ "28.1")
(defcustom ansi-color-names-vector
["black" "red3" "green3" "yellow3" "blue2" "magenta3" "cyan3" "gray90"]
"Colors used for SGR control sequences determining a color.
-This vector holds the colors used for SGR control sequences parameters
+This vector holds the colors used for SGR control sequence parameters
30 to 37 (foreground colors) and 40 to 47 (background colors).
-Parameter Color
- 30 40 black
- 31 41 red
- 32 42 green
- 33 43 yellow
- 34 44 blue
- 35 45 magenta
- 36 46 cyan
- 37 47 white
-
-This vector is used by `ansi-color-make-color-map' to create a color
-map. This color map is stored in the variable `ansi-color-map'.
-
-Each element may also be a cons cell where the car and cdr specify the
-foreground and background colors, respectively."
+This variable is obsolete. To customize the display of colors used by
+ansi-color, change 'ansi-color-COLOR', e.g. `ansi-color-red'. To
+customize the actual faces used (e.g. to temporarily display SGR
+control sequences differently), use `ansi-color-normal-colors-vector'."
:type '(vector (choice color (cons color color))
(choice color (cons color color))
(choice color (cons color color))
@@ -145,10 +260,87 @@ foreground and background colors, respectively."
(choice color (cons color color))
(choice color (cons color color))
(choice color (cons color color)))
- :set 'ansi-color-map-update
- :initialize 'custom-initialize-default
:version "24.4" ; default colors copied from `xterm-standard-colors'
:group 'ansi-colors)
+(make-obsolete-variable 'ansi-color-faces-vector
+ 'ansi-color-normal-colors-vector "28.1")
+
+(defvar ansi-color-basic-faces-vector
+ [nil
+ ansi-color-bold
+ ansi-color-faint
+ ansi-color-italic
+ ansi-color-underline
+ ansi-color-slow-blink
+ ansi-color-fast-blink
+ ansi-color-inverse]
+ "Faces used for SGR control sequences determining a face.
+This vector holds the faces used for SGR control sequence parameters 0
+to 7.
+
+Parameter Description
+ 0 default
+ 1 bold
+ 2 faint
+ 3 italic
+ 4 underlined
+ 5 slowly blinking
+ 6 rapidly blinking
+ 7 negative image")
+
+(defvar ansi-color-normal-colors-vector
+ [ansi-color-black
+ ansi-color-red
+ ansi-color-green
+ ansi-color-yellow
+ ansi-color-blue
+ ansi-color-magenta
+ ansi-color-cyan
+ ansi-color-white]
+ "Faces used for SGR control sequences determining a color.
+This vector holds the faces used for SGR control sequence parameters
+30 to 37 (foreground colors) and 40 to 47 (background colors).
+
+Parameter Color
+ 30 40 black
+ 31 41 red
+ 32 42 green
+ 33 43 yellow
+ 34 44 blue
+ 35 45 magenta
+ 36 46 cyan
+ 37 47 white")
+
+(defvar ansi-color-bright-colors-vector
+ [ansi-color-bright-black
+ ansi-color-bright-red
+ ansi-color-bright-green
+ ansi-color-bright-yellow
+ ansi-color-bright-blue
+ ansi-color-bright-magenta
+ ansi-color-bright-cyan
+ ansi-color-bright-white]
+ "Faces used for SGR control sequences determining a \"bright\" color.
+This vector holds the faces used for SGR control sequence parameters
+90 to 97 (bright foreground colors) and 100 to 107 (bright background
+colors).
+
+Parameter Color
+ 90 100 bright black
+ 91 101 bright red
+ 92 102 bright green
+ 93 103 bright yellow
+ 94 104 bright blue
+ 95 105 bright magenta
+ 96 106 bright cyan
+ 97 107 bright white")
+
+(defcustom ansi-color-bold-is-bright nil
+ "If set to non-nil, combining ANSI bold and a color produces the bright
+version of that color."
+ :type 'boolean
+ :version "28.1"
+ :group 'ansi-colors)
(defconst ansi-color-control-seq-regexp
;; See ECMA 48, section 5.4 "Control Sequences".
@@ -266,11 +458,18 @@ variable, and is meant to be used in `compilation-filter-hook'."
;; Working with strings
(defvar-local ansi-color-context nil
"Context saved between two calls to `ansi-color-apply'.
-This is a list of the form (CODES FRAGMENT) or nil. CODES
+This is a list of the form (FACE-VEC FRAGMENT) or nil. FACE-VEC
represents the state the last call to `ansi-color-apply' ended
-with, currently a list of ansi codes, and FRAGMENT is a string
-starting with an escape sequence, possibly the start of a new
-escape sequence.")
+with, currently a list of the form:
+
+ (BASIC-FACES FG BG)
+
+BASIC-FACES is a bool-vector that specifies which basic faces
+from `ansi-color-basic-faces-vector' to apply. FG and BG are
+ANSI color codes for the foreground and background color.
+
+FRAGMENT is a string starting with an escape sequence, possibly
+the start of a new escape sequence.")
(defun ansi-color-filter-apply (string)
"Filter out all ANSI control sequences from STRING.
@@ -281,17 +480,17 @@ will be used for the next call to `ansi-color-apply'. Set
`ansi-color-context' to nil if you don't want this.
This function can be added to `comint-preoutput-filter-functions'."
- (let ((start 0) end result)
+ (let ((context (ansi-color--ensure-context 'ansi-color-context nil))
+ (start 0) end result)
;; if context was saved and is a string, prepend it
- (if (cadr ansi-color-context)
- (setq string (concat (cadr ansi-color-context) string)
- ansi-color-context nil))
+ (setq string (concat (cadr context) string))
+ (setcar (cdr context) "")
;; find the next escape sequence
(while (setq end (string-match ansi-color-control-seq-regexp string start))
(push (substring string start end) result)
(setq start (match-end 0)))
;; save context, add the remainder of the string to the result
- (let (fragment)
+ (let ((fragment ""))
(push (substring string start
(if (string-match "\033" string start)
(let ((pos (match-beginning 0)))
@@ -299,31 +498,16 @@ This function can be added to `comint-preoutput-filter-functions'."
pos)
nil))
result)
- (setq ansi-color-context (if fragment (list nil fragment))))
+ (setcar (cdr context) fragment))
(apply #'concat (nreverse result))))
-(defun ansi-color--find-face (codes)
- "Return the face corresponding to CODES."
- (let (faces)
- (while codes
- (let ((face (ansi-color-get-face-1 (pop codes))))
- ;; In the (default underline) face, say, the value of the
- ;; "underline" attribute of the `default' face wins.
- (unless (eq face 'default)
- (push face faces))))
- ;; Avoid some long-lived conses in the common case.
- (if (cdr faces)
- (nreverse faces)
- (car faces))))
-
(defun ansi-color-apply (string)
"Translates SGR control sequences into text properties.
Delete all other control sequences without processing them.
Applies SGR control sequences setting foreground and background colors
-to STRING using text properties and returns the result. The colors used
-are given in `ansi-color-faces-vector' and `ansi-color-names-vector'.
-See function `ansi-color-apply-sequence' for details.
+to STRING using text properties and returns the result. See function
+`ansi-color-apply-sequence' for details.
Every call to this function will set and use the buffer-local variable
`ansi-color-context' to save partial escape sequences and current ansi codes.
@@ -331,49 +515,157 @@ This information will be used for the next call to `ansi-color-apply'.
Set `ansi-color-context' to nil if you don't want this.
This function can be added to `comint-preoutput-filter-functions'."
- (let ((codes (car ansi-color-context))
- (start 0) end result)
+ (let* ((context
+ (ansi-color--ensure-context 'ansi-color-context nil))
+ (face-vec (car context))
+ (start 0)
+ end result)
;; If context was saved and is a string, prepend it.
- (if (cadr ansi-color-context)
- (setq string (concat (cadr ansi-color-context) string)
- ansi-color-context nil))
+ (setq string (concat (cadr context) string))
+ (setcar (cdr context) "")
;; Find the next escape sequence.
(while (setq end (string-match ansi-color-control-seq-regexp string start))
(let ((esc-end (match-end 0)))
;; Colorize the old block from start to end using old face.
- (when codes
+ (when-let ((face (ansi-color--face-vec-face face-vec)))
(put-text-property start end 'font-lock-face
- (ansi-color--find-face codes) string))
+ face string))
(push (substring string start end) result)
(setq start (match-end 0))
;; If this is a color escape sequence,
(when (eq (aref string (1- esc-end)) ?m)
;; create a new face from it.
- (setq codes (ansi-color-apply-sequence
- (substring string end esc-end) codes)))))
+ (let ((cur-pos end))
+ (ansi-color--update-face-vec
+ face-vec
+ (lambda ()
+ (when (string-match ansi-color-parameter-regexp
+ string cur-pos)
+ (setq cur-pos (match-end 0))
+ (when (<= cur-pos esc-end)
+ (string-to-number (match-string 1 string))))))))))
;; if the rest of the string should have a face, put it there
- (when codes
+ (when-let ((face (ansi-color--face-vec-face face-vec)))
(put-text-property start (length string)
- 'font-lock-face (ansi-color--find-face codes) string))
+ 'font-lock-face face string))
;; save context, add the remainder of the string to the result
- (let (fragment)
- (if (string-match "\033" string start)
- (let ((pos (match-beginning 0)))
- (setq fragment (substring string pos))
- (push (substring string start pos) result))
- (push (substring string start) result))
- (setq ansi-color-context (if (or codes fragment) (list codes fragment))))
+ (if (string-match "\033" string start)
+ (let ((pos (match-beginning 0)))
+ (setcar (cdr context) (substring string pos))
+ (push (substring string start pos) result))
+ (push (substring string start) result))
(apply 'concat (nreverse result))))
+(defun ansi-color--ensure-context (context-sym position)
+ "Return CONTEXT-SYM's value as a valid context.
+If it is nil, set CONTEXT-SYM's value to a new context and return
+it. Context is a list of the form as described in
+`ansi-color-context' if POSITION is nil, or
+`ansi-color-context-region' if POSITION is non-nil.
+
+If CONTEXT-SYM's value is already non-nil, return it. If its
+marker doesn't point anywhere yet, position it before character
+number POSITION, if non-nil."
+ (let ((context (symbol-value context-sym)))
+ (if context
+ (if position
+ (let ((marker (cadr context)))
+ (unless (marker-position marker)
+ (set-marker marker position))
+ context)
+ context)
+ (set context-sym
+ (list (list (make-bool-vector 8 nil)
+ nil nil)
+ (if position
+ (copy-marker position)
+ ""))))))
+
+(defun ansi-color--face-vec-face (face-vec)
+ "Return the face corresponding to FACE-VEC.
+FACE-VEC is a list containing information about the ANSI sequence
+code. It is usually stored as the car of the variable
+`ansi-color-context-region'."
+ (let* ((basic-faces (car face-vec))
+ (colors (cdr face-vec))
+ (bright (and ansi-color-bold-is-bright (aref basic-faces 1)))
+ (faces nil))
+
+ (when-let ((fg (car colors)))
+ (push
+ `(:foreground
+ ,(or (ansi-color--code-as-hex fg)
+ (face-foreground
+ (aref (if (or bright (>= fg 8))
+ ansi-color-bright-colors-vector
+ ansi-color-normal-colors-vector)
+ (mod fg 8))
+ nil 'default)))
+ faces))
+ (when-let ((bg (cadr colors)))
+ (push
+ `(:background
+ ,(or (ansi-color--code-as-hex bg)
+ (face-background
+ (aref (if (or bright (>= bg 8))
+ ansi-color-bright-colors-vector
+ ansi-color-normal-colors-vector)
+ (mod bg 8))
+ nil 'default)))
+ faces))
+
+ (let ((i 8))
+ (while (> i 0)
+ (setq i (1- i))
+ (when (aref basic-faces i)
+ (push (aref ansi-color-basic-faces-vector i) faces))))
+ ;; Avoid some long-lived conses in the common case.
+ (if (cdr faces)
+ faces
+ (car faces))))
+
+(defun ansi-color--code-as-hex (color)
+ "Convert COLOR to hexadecimal string representation.
+COLOR is an ANSI color code. If it is between 16 and 255
+inclusive, it corresponds to a color from an 8-bit color cube.
+If it is greater or equal than 256, it is subtracted by 256 to
+directly specify a 24-bit color.
+
+Return a hexadecimal string, specifying the color, or nil, if
+COLOR is less than 16."
+ (cond
+ ((< color 16) nil)
+ ((>= color 256) (format "#%06X" (- color 256)))
+ ((>= color 232) ;; Grayscale
+ (format "#%06X" (* #x010101 (+ 8 (* 10 (- color 232))))))
+ (t ;; 6x6x6 color cube
+ (setq color (- color 16))
+ (let ((res 0)
+ (frac (* 6 6)))
+ (while (<= 1 frac) ; Repeat 3 times
+ (setq res (* res #x000100))
+ (let ((color-num (mod (/ color frac) 6)))
+ (unless (zerop color-num)
+ (setq res (+ res #x37 (* #x28 color-num)))))
+ (setq frac (/ frac 6)))
+ (format "#%06X" res)))))
+
;; Working with regions
(defvar-local ansi-color-context-region nil
"Context saved between two calls to `ansi-color-apply-on-region'.
-This is a list of the form (CODES MARKER) or nil. CODES
+This is a list of the form (FACE-VEC MARKER) or nil. FACE-VEC
represents the state the last call to `ansi-color-apply-on-region'
-ended with, currently a list of ansi codes, and MARKER is a
-buffer position within an escape sequence or the last position
-processed.")
+ended with, currently a list of the form:
+
+ (BASIC-FACES FG BG).
+
+BASIC-FACES is a bool-vector that specifies which basic faces
+from `ansi-color-basic-faces-vector' to apply. FG and BG are
+ANSI color codes for the foreground and background color.
+
+MARKER is a buffer position within an escape sequence or the last
+position processed.")
(defun ansi-color-filter-region (begin end)
"Filter out all ANSI control sequences from region BEGIN to END.
@@ -383,8 +675,10 @@ Every call to this function will set and use the buffer-local variable
used for the next call to `ansi-color-apply-on-region'. Specifically,
it will override BEGIN, the start of the region. Set
`ansi-color-context-region' to nil if you don't want this."
- (let ((end-marker (copy-marker end))
- (start (or (cadr ansi-color-context-region) begin)))
+ (let* ((end-marker (copy-marker end))
+ (context (ansi-color--ensure-context
+ 'ansi-color-context-region begin))
+ (start (cadr context)))
(save-excursion
(goto-char start)
;; Delete escape sequences.
@@ -392,8 +686,8 @@ it will override BEGIN, the start of the region. Set
(delete-region (match-beginning 0) (match-end 0)))
;; save context, add the remainder of the string to the result
(if (re-search-forward "\033" end-marker t)
- (setq ansi-color-context-region (list nil (match-beginning 0)))
- (setq ansi-color-context-region nil)))))
+ (set-marker start (match-beginning 0))
+ (set-marker start nil)))))
(defun ansi-color-apply-on-region (begin end &optional preserve-sequences)
"Translates SGR control sequences into overlays or extents.
@@ -402,8 +696,7 @@ Delete all other control sequences without processing them.
SGR control sequences are applied by calling the function
specified by `ansi-color-apply-face-function'. The default
function sets foreground and background colors to the text
-between BEGIN and END, using overlays. The colors used are given
-in `ansi-color-faces-vector' and `ansi-color-names-vector'. See
+between BEGIN and END, using overlays. See function
`ansi-color-apply-sequence' for details.
Every call to this function will set and use the buffer-local
@@ -416,58 +709,58 @@ this.
If PRESERVE-SEQUENCES is t, the sequences are hidden instead of
being deleted."
- (let ((codes (car ansi-color-context-region))
- (start-marker (or (cadr ansi-color-context-region)
- (copy-marker begin)))
- (end-marker (copy-marker end)))
+ (let* ((context (ansi-color--ensure-context
+ 'ansi-color-context-region begin))
+ (face-vec (car context))
+ (start-marker (cadr context))
+ (end-marker (copy-marker end)))
(save-excursion
(goto-char start-marker)
;; Find the next escape sequence.
(while (re-search-forward ansi-color-control-seq-regexp end-marker t)
;; Extract escape sequence.
- (let ((esc-seq (buffer-substring
- (match-beginning 0) (point))))
- (if preserve-sequences
- ;; Make the escape sequence transparent.
- (overlay-put (make-overlay (match-beginning 0) (point))
- 'invisible t)
- ;; Otherwise, strip.
- (delete-region (match-beginning 0) (point)))
-
+ (let ((esc-beg (match-beginning 0))
+ (esc-end (point)))
;; Colorize the old block from start to end using old face.
(funcall ansi-color-apply-face-function
(prog1 (marker-position start-marker)
;; Store new start position.
- (set-marker start-marker (point)))
- (match-beginning 0) (ansi-color--find-face codes))
+ (set-marker start-marker esc-end))
+ esc-beg (ansi-color--face-vec-face face-vec))
;; If this is a color sequence,
- (when (eq (aref esc-seq (1- (length esc-seq))) ?m)
- ;; update the list of ansi codes.
- (setq codes (ansi-color-apply-sequence esc-seq codes)))))
+ (when (eq (char-before esc-end) ?m)
+ (goto-char esc-beg)
+ (ansi-color--update-face-vec
+ face-vec (lambda ()
+ (when (re-search-forward ansi-color-parameter-regexp
+ esc-end t)
+ (string-to-number (match-string 1))))))
+
+ (if preserve-sequences
+ ;; Make the escape sequence transparent.
+ (overlay-put (make-overlay esc-beg esc-end) 'invisible t)
+ ;; Otherwise, strip.
+ (delete-region esc-beg esc-end))))
;; search for the possible start of a new escape sequence
(if (re-search-forward "\033" end-marker t)
- (progn
- ;; if the rest of the region should have a face, put it there
- (funcall ansi-color-apply-face-function
- start-marker (point) (ansi-color--find-face codes))
- ;; save codes and point
- (setq ansi-color-context-region
- (list codes (copy-marker (match-beginning 0)))))
- ;; if the rest of the region should have a face, put it there
- (funcall ansi-color-apply-face-function
- start-marker end-marker (ansi-color--find-face codes))
- ;; Save a restart position when there are codes active. It's
- ;; convenient for man.el's process filter to pass `begin'
- ;; positions that overlap regions previously colored; these
- ;; `codes' should not be applied to that overlap, so we need
- ;; to know where they should really start.
- (setq ansi-color-context-region
- (if codes (list codes (copy-marker (point)))))))
- ;; Clean up our temporary markers.
- (unless (eq start-marker (cadr ansi-color-context-region))
- (set-marker start-marker nil))
- (unless (eq end-marker (cadr ansi-color-context-region))
- (set-marker end-marker nil))))
+ (progn
+ (while (re-search-forward "\033" end-marker t))
+ (backward-char)
+ (funcall ansi-color-apply-face-function
+ start-marker (point)
+ (ansi-color--face-vec-face face-vec))
+ (set-marker start-marker (point)))
+ (let ((faces (ansi-color--face-vec-face face-vec)))
+ (funcall ansi-color-apply-face-function
+ start-marker end-marker faces)
+ ;; Save a restart position when there are codes active. It's
+ ;; convenient for man.el's process filter to pass `begin'
+ ;; positions that overlap regions previously colored; these
+ ;; `codes' should not be applied to that overlap, so we need
+ ;; to know where they should really start.
+ (set-marker start-marker (when faces end-marker)))))
+ ;; Clean up our temporary marker.
+ (set-marker end-marker nil)))
(defun ansi-color-apply-overlay-face (beg end face)
"Make an overlay from BEG to END, and apply face FACE.
@@ -570,11 +863,12 @@ ESCAPE-SEQUENCE is an escape sequence parsed by
For each new code, the following happens: if it is 1-7, add it to
the list of codes; if it is 21-25 or 27, delete appropriate
-parameters from the list of codes; if it is 30-37 resp. 39, the
-foreground color code is replaced or added resp. deleted; if it
-is 40-47 resp. 49, the background color code is replaced or added
-resp. deleted; any other code is discarded together with the old
-codes. Finally, the so changed list of codes is returned."
+parameters from the list of codes; if it is 30-37 (or 90-97) resp. 39,
+the foreground color code is replaced or added resp. deleted; if it
+is 40-47 (or 100-107) resp. 49, the background color code is replaced
+or added resp. deleted; any other code is discarded together with the
+old codes. Finally, the so changed list of codes is returned."
+ (declare (obsolete ansi-color--update-face-vec "29.1"))
(let ((new-codes (ansi-color-parse-sequence escape-sequence)))
(while new-codes
(let* ((new (pop new-codes))
@@ -591,7 +885,7 @@ codes. Finally, the so changed list of codes is returned."
(22 (remq 1 codes))
(25 (remq 6 codes))
(_ codes)))))
- ((or 3 4) (let ((r (mod new 10)))
+ ((or 3 4 9 10) (let ((r (mod new 10)))
(unless (= r 8)
(let (beg)
(while (and codes (/= q (/ (car codes) 10)))
@@ -603,14 +897,82 @@ codes. Finally, the so changed list of codes is returned."
(_ nil)))))
codes))
+(defun ansi-color--update-face-vec (face-vec iterator)
+ "Apply escape sequences to FACE-VEC.
+
+Destructively modify FACE-VEC, which should be a list containing
+face information. It is described in
+`ansi-color-context-region'. ITERATOR is a function which is
+called repeatedly with zero arguments and should return either
+the next ANSI code in the current sequence as a number or nil if
+there are no more ANSI codes left.
+
+For each new code, the following happens: if it is 1-7, set the
+corresponding properties; if it is 21-25 or 27, unset appropriate
+properties; if it is 30-37 (or 90-97) or resp. 39, set the
+foreground color or resp. unset it; if it is 40-47 (or 100-107)
+resp. 49, set the background color or resp. unset it; if it is 38
+or 48, the following codes are used to set the foreground or
+background color and the correct color mode; any other code will
+unset all properties and colors."
+ (let ((basic-faces (car face-vec))
+ (colors (cdr face-vec))
+ new q do-clear)
+ (while (setq new (funcall iterator))
+ (setq q (/ new 10))
+ (pcase q
+ (0 (if (memq new '(0 8 9))
+ (setq do-clear t)
+ (aset basic-faces new t)))
+ (2 (if (memq new '(20 26 28 29))
+ (setq do-clear t)
+ ;; The standard says `21 doubly underlined' while
+ ;; https://en.wikipedia.org/wiki/ANSI_escape_code claims
+ ;; `21 Bright/Bold: off or Underline: Double'.
+ (aset basic-faces (- new 20) nil)
+ (aset basic-faces (pcase new (22 1) (25 6) (_ 0)) nil)))
+ ((or 3 4 9 10)
+ (let ((r (mod new 10))
+ (cell (if (memq q '(3 9)) colors (cdr colors))))
+ (pcase r
+ (8
+ (pcase (funcall iterator)
+ (5 (setq new (setcar cell (funcall iterator)))
+ (setq do-clear (or (null new) (>= new 256))))
+ (2
+ (let ((red (funcall iterator))
+ (green (funcall iterator))
+ (blue (funcall iterator)))
+ (if (and red green blue
+ (progn
+ (setq new (+ (* #x010000 red)
+ (* #x000100 green)
+ (* #x000001 blue)))
+ (<= new #xFFFFFF)))
+ (setcar cell (+ 256 new))
+ (setq do-clear t))))
+ (_ (setq do-clear t))))
+ (9 (setcar cell nil))
+ (_ (setcar cell (+ (if (memq q '(3 4)) 0 8) r))))))
+ (_ (setq do-clear t)))
+
+ (when do-clear
+ (setq do-clear nil)
+ ;; Zero out our bool vector without any allocation.
+ (bool-vector-intersection basic-faces #&8"\0" basic-faces)
+ (setcar colors nil)
+ (setcar (cdr colors) nil)))))
+
(defun ansi-color-make-color-map ()
- "Creates a vector of face definitions and returns it.
+ "Create a vector of face definitions and return it.
The index into the vector is an ANSI code. See the documentation of
`ansi-color-map' for an example.
The face definitions are based upon the variables
-`ansi-color-faces-vector' and `ansi-color-names-vector'."
+`ansi-color-faces-vector' and `ansi-color-names-vector'.
+
+This function is obsolete, and no longer needed to use ansi-color."
(let ((map (make-vector 50 nil))
(index 0))
;; miscellaneous attributes
@@ -638,34 +1000,58 @@ The face definitions are based upon the variables
(setq index (1+ index)) )
ansi-color-names-vector)
map))
+(make-obsolete 'ansi-color-make-color-map "you can remove it." "28.1")
-(defvar ansi-color-map (ansi-color-make-color-map)
- "A brand new color map suitable for `ansi-color-get-face'.
+(defvar ansi-color-map
+ (with-no-warnings (ansi-color-make-color-map))
+ "A brand new color map, formerly suitable for `ansi-color-get-face'.
The value of this variable is usually constructed by
`ansi-color-make-color-map'. The values in the array are such that the
numbers included in an SGR control sequences point to the correct
foreground or background colors.
-Example: The sequence \\033[34m specifies a blue foreground. Therefore:
- (aref ansi-color-map 34)
- => (foreground-color . \"blue\")")
+This variable is obsolete, and no longer needed to use ansi-color.")
+(make-obsolete-variable 'ansi-color-map "you can remove it." "28.1")
(defun ansi-color-map-update (symbol value)
"Update `ansi-color-map'.
-Whenever the vectors used to construct `ansi-color-map' are changed,
-this function is called. Therefore this function is listed as the :set
-property of `ansi-color-faces-vector' and `ansi-color-names-vector'."
+This function is obsolete, and no longer needed to use ansi-color."
(set-default symbol value)
- (setq ansi-color-map (ansi-color-make-color-map)))
-
-(defun ansi-color-get-face-1 (ansi-code)
- "Get face definition from `ansi-color-map'.
-ANSI-CODE is used as an index into the vector."
- (condition-case nil
- (aref ansi-color-map ansi-code)
- (args-out-of-range nil)))
+ (with-no-warnings
+ (setq ansi-color-map (ansi-color-make-color-map))))
+(make-obsolete 'ansi-color-map-update "you can remove it." "28.1")
+
+(defun ansi-color-get-face-1 (ansi-code &optional bright)
+ "Get face definition for ANSI-CODE.
+BRIGHT, if non-nil, requests \"bright\" ANSI colors, even if ANSI-CODE
+is a normal-intensity color."
+ (declare (obsolete ansi-color--face-vec-face "29.1"))
+ (when (and bright (<= 30 ansi-code 49))
+ (setq ansi-code (+ ansi-code 60)))
+ (cond ((<= 0 ansi-code 7)
+ (aref ansi-color-basic-faces-vector ansi-code))
+ ((<= 30 ansi-code 38)
+ (list :foreground
+ (face-foreground
+ (aref ansi-color-normal-colors-vector (- ansi-code 30))
+ nil 'default)))
+ ((<= 40 ansi-code 48)
+ (list :background
+ (face-background
+ (aref ansi-color-normal-colors-vector (- ansi-code 40))
+ nil 'default)))
+ ((<= 90 ansi-code 98)
+ (list :foreground
+ (face-foreground
+ (aref ansi-color-bright-colors-vector (- ansi-code 90))
+ nil 'default)))
+ ((<= 100 ansi-code 108)
+ (list :background
+ (face-background
+ (aref ansi-color-bright-colors-vector (- ansi-code 100))
+ nil 'default)))))
(provide 'ansi-color)
diff --git a/lisp/apropos.el b/lisp/apropos.el
index a1470537d9a..66a594d588d 100644
--- a/lisp/apropos.el
+++ b/lisp/apropos.el
@@ -78,7 +78,7 @@ This option only controls the default behavior. Each of the above
commands also has an optional argument to request a more extensive search.
Additionally, this option makes the function `apropos-library'
-include key-binding information in its output."
+include keybinding information in its output."
:type 'boolean)
(defface apropos-symbol
@@ -515,9 +515,9 @@ variables, not just user options."
current-prefix-arg))
(apropos-command pattern nil
(if (or do-all apropos-do-all)
- #'(lambda (symbol)
- (and (boundp symbol)
- (get symbol 'variable-documentation)))
+ (lambda (symbol)
+ (and (boundp symbol)
+ (get symbol 'variable-documentation)))
#'custom-variable-p)))
;;;###autoload
@@ -1305,7 +1305,7 @@ as a heading."
(error "There is nothing to follow here"))))
(defun apropos-next-symbol ()
- "Move cursor down to the next symbol in an apropos-mode buffer."
+ "Move cursor down to the next symbol in an `apropos-mode' buffer."
(interactive)
(forward-line)
(while (and (not (eq (face-at-point) 'apropos-symbol))
@@ -1313,7 +1313,7 @@ as a heading."
(forward-line)))
(defun apropos-previous-symbol ()
- "Move cursor back to the last symbol in an apropos-mode buffer."
+ "Move cursor back to the last symbol in an `apropos-mode' buffer."
(interactive)
(forward-line -1)
(while (and (not (eq (face-at-point) 'apropos-symbol))
@@ -1322,17 +1322,18 @@ as a heading."
(defun apropos-describe-plist (symbol)
"Display a pretty listing of SYMBOL's plist."
- (help-setup-xref (list 'apropos-describe-plist symbol)
- (called-interactively-p 'interactive))
- (with-help-window (help-buffer)
- (set-buffer standard-output)
- (princ "Symbol ")
- (prin1 symbol)
- (princ (substitute-command-keys "'s plist is\n ("))
- (put-text-property (+ (point-min) 7) (- (point) 14)
- 'face 'apropos-symbol)
- (insert (apropos-format-plist symbol "\n "))
- (princ ")")))
+ (let ((help-buffer-under-preparation t))
+ (help-setup-xref (list 'apropos-describe-plist symbol)
+ (called-interactively-p 'interactive))
+ (with-help-window (help-buffer)
+ (set-buffer standard-output)
+ (princ "Symbol ")
+ (prin1 symbol)
+ (princ (substitute-command-keys "'s plist is\n ("))
+ (put-text-property (+ (point-min) 7) (- (point) 14)
+ 'face 'apropos-symbol)
+ (insert (apropos-format-plist symbol "\n "))
+ (princ ")"))))
(provide 'apropos)
diff --git a/lisp/arc-mode.el b/lisp/arc-mode.el
index 71ad7bd0c5d..ece30fec003 100644
--- a/lisp/arc-mode.el
+++ b/lisp/arc-mode.el
@@ -431,12 +431,8 @@ be added."
;; Let mouse-1 follow the link.
(define-key map [follow-link] 'mouse-face)
- (if (fboundp 'command-remapping)
- (progn
- (define-key map [remap advertised-undo] 'archive-undo)
- (define-key map [remap undo] 'archive-undo))
- (substitute-key-definition 'advertised-undo 'archive-undo map global-map)
- (substitute-key-definition 'undo 'archive-undo map global-map))
+ (define-key map [remap advertised-undo] #'archive-undo)
+ (define-key map [remap undo] #'archive-undo)
(define-key map [mouse-2] 'archive-extract)
@@ -621,12 +617,8 @@ OLDMODE will be modified accordingly just like chmod(2) would have done."
(defun archive-unixdate (low high)
"Stringify Unix (LOW HIGH) date."
- (let* ((time (list high low))
- (str (current-time-string time)))
- (format "%s-%s-%s"
- (substring str 8 10)
- (substring str 4 7)
- (format-time-string "%Y" time))))
+ (let ((system-time-locale "C"))
+ (format-time-string "%e-%b-%Y" (list high low))))
(defun archive-unixtime (low high)
"Stringify Unix (LOW HIGH) time."
@@ -1759,7 +1751,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself."
neh ;beginning of next extension header (level 1 and 2)
mode uid gid dir prname
gname uname modtime moddate)
- (if (= hdrlvl 3) (error "can't handle lzh level 3 header type"))
+ (if (= hdrlvl 3) (error "Can't handle lzh level 3 header type"))
(when (or (= hdrlvl 0) (= hdrlvl 1))
(setq fnlen (get-byte (+ p 21))) ;filename length
(setq efnname (let ((str (buffer-substring (+ p 22) (+ p 22 fnlen)))) ;filename from offset 22
diff --git a/lisp/array.el b/lisp/array.el
index 6632da55dd4..2c9a6815d25 100644
--- a/lisp/array.el
+++ b/lisp/array.el
@@ -805,8 +805,9 @@ NOT recognized as integers or real numbers.
The array MUST reside at the top of the buffer.
TABs are not respected, and may be converted into spaces at any time.
-Setting the variable `array-respect-tabs' to non-nil will prevent TAB conversion,
-but will cause many functions to give errors if they encounter one.
+Setting the variable `array-respect-tabs' to non-nil will prevent
+TAB conversion, but will cause many functions to give errors if
+they encounter one.
Upon entering array mode, you will be prompted for the values of
several variables. Others will be calculated based on the values you
diff --git a/lisp/auth-source-pass.el b/lisp/auth-source-pass.el
index 914f8d2f1bf..162a3ec23c2 100644
--- a/lisp/auth-source-pass.el
+++ b/lisp/auth-source-pass.el
@@ -176,7 +176,7 @@ CONTENTS is the contents of a password-store formatted file."
lines))))
(defun auth-source-pass--do-debug (&rest msg)
- "Call `auth-source-do-debug` with MSG and a prefix."
+ "Call `auth-source-do-debug' with MSG and a prefix."
(apply #'auth-source-do-debug
(cons (concat "auth-source-pass: " (car msg))
(cdr msg))))
diff --git a/lisp/auth-source.el b/lisp/auth-source.el
index 69197383982..3c1a6feaeeb 100644
--- a/lisp/auth-source.el
+++ b/lisp/auth-source.el
@@ -79,9 +79,8 @@
;;;###autoload
(defcustom auth-source-cache-expiry 7200
- "How many seconds passwords are cached, or nil to disable
-expiring. Overrides `password-cache-expiry' through a
-let-binding."
+ "How many seconds passwords are cached, or nil to disable expiring.
+Overrides `password-cache-expiry' through a let-binding."
:version "24.1"
:type '(choice (const :tag "Never" nil)
(const :tag "All Day" 86400)
@@ -177,7 +176,7 @@ let-binding."
;; TODO: or maybe leave as (setq auth-source-netrc-use-gpg-tokens 'never)
(defcustom auth-source-netrc-use-gpg-tokens 'never
- "Set this to tell auth-source when to create GPG password
+ "Set this to tell `auth-source' when to create GPG password
tokens in netrc files. It's either an alist or `never'.
Note that if EPA/EPG is not available, this should NOT be used."
:version "23.2" ;; No Gnus
@@ -353,7 +352,7 @@ backend starts with the first element on the list and stops as
soon as a function returns non-nil.")
(defun auth-source-backend-parse (entry)
- "Create an auth-source-backend from an ENTRY in `auth-sources'."
+ "Create an `auth-source-backend' from an ENTRY in `auth-sources'."
(let ((backend
(run-hook-with-args-until-success 'auth-source-backend-parser-functions
@@ -504,7 +503,7 @@ soon as a function returns non-nil.")
(add-hook 'auth-source-backend-parser-functions #'auth-source-backends-parser-secrets)
(defun auth-source-backend-parse-parameters (entry backend)
- "Fill in the extra auth-source-backend parameters of ENTRY.
+ "Fill in the extra `auth-source-backend' parameters of ENTRY.
Using the plist ENTRY, get the :host, :port, and :user search
parameters."
(let ((entry (if (stringp entry)
@@ -823,7 +822,7 @@ Returns t or nil for forgotten or not found."
(password-cache-remove (auth-source-format-cache-entry spec)))
(defun auth-source-forget+ (&rest spec)
- "Forget any cached data matching SPEC. Returns forgotten count.
+ "Forget any cached data matching SPEC. Return forgotten count.
This is not a full `auth-source-search' spec but works similarly.
For instance, \(:host \"myhost\" \"yourhost\") would find all the
@@ -1198,7 +1197,7 @@ FILE is the file from which we obtained this token."
(mapcar #'1- string)))
(defun auth-source--pad (string length)
- "Pad string S to a modulo of LENGTH."
+ "Pad STRING to a modulo of LENGTH."
(let ((pad (- length (mod (length string) length))))
(concat string (make-string pad pad))))
@@ -1228,7 +1227,7 @@ FILE is the file from which we obtained this token."
&key backend require create
type max host user port
&allow-other-keys)
- "Given a property list SPEC, return search matches from the :backend.
+ "Given a property list SPEC, return search matches from the `:backend'.
See `auth-source-search' for details on SPEC."
;; just in case, check that the type is correct (null or same as the backend)
(cl-assert (or (null type) (eq type (oref backend type)))
@@ -1283,6 +1282,8 @@ See `auth-source-search' for details on SPEC."
(required (append base-required create-extra))
(file (oref backend source))
(add "")
+ ;; Whether to set save-function.
+ save-function
;; `valist' is an alist
valist
;; `artificial' will be returned if no creation is needed
@@ -1412,6 +1413,8 @@ See `auth-source-search' for details on SPEC."
;; When r is not an empty string...
(when (and (stringp data)
(< 0 (length data)))
+ (when (eq r 'secret)
+ (setq save-function t))
;; this function is not strictly necessary but I think it
;; makes the code clearer -tzz
(let ((printer (lambda ()
@@ -1432,12 +1435,13 @@ See `auth-source-search' for details on SPEC."
data)))))
(setq add (concat add (funcall printer)))))))
- (plist-put
- artificial
- :save-function
- (let ((file file)
- (add add))
- (lambda () (auth-source-netrc-saver file add))))
+ (when save-function
+ (plist-put
+ artificial
+ :save-function
+ (let ((file file)
+ (add add))
+ (lambda () (auth-source-netrc-saver file add)))))
(list artificial)))
@@ -1573,8 +1577,7 @@ collection that's a Google Chrome entry for the git.gnus.org site
authentication tokens:
(let ((auth-sources \\='(\"secrets:Login\")))
- (auth-source-search :max 1 :signon_realm \"https://git.gnus.org/Git\"))
-"
+ (auth-source-search :max 1 :signon_realm \"https://git.gnus.org/Git\"))"
;; TODO
;; (secrets-delete-item coll elt)
@@ -1666,6 +1669,8 @@ authentication tokens:
:port port)))
(required (append base-required create-extra))
(collection (oref backend source))
+ ;; Whether to set save-function.
+ save-function
;; `args' are the arguments for `secrets-create-item'.
args
;; `valist' is an alist
@@ -1780,21 +1785,24 @@ authentication tokens:
;; When r is not an empty string...
(when (and (stringp data)
- (< 0 (length data))
- (not (member r '(secret label))))
- ;; append the key (the symbol name of r)
- ;; and the value in r
- (setq args (append args (list (auth-source--symbol-keyword r) data))))))
-
- (plist-put
- artificial
- :save-function
- (let* ((collection collection)
- (item (plist-get artificial :label))
- (secret (plist-get artificial :secret))
- (secret (if (functionp secret) (funcall secret) secret)))
- (lambda ()
- (auth-source-secrets-saver collection item secret args))))
+ (< 0 (length data)))
+ (if (eq r 'secret)
+ (setq save-function t)
+ (if (not (eq r 'label))
+ ;; append the key (the symbol name of r)
+ ;; and the value in r
+ (setq args (append args (list (auth-source--symbol-keyword r) data))))))))
+
+ (when save-function
+ (plist-put
+ artificial
+ :save-function
+ (let* ((collection collection)
+ (item (plist-get artificial :label))
+ (secret (plist-get artificial :secret))
+ (secret (if (functionp secret) (funcall secret) secret)))
+ (lambda ()
+ (auth-source-secrets-saver collection item secret args)))))
(list artificial)))
@@ -1875,8 +1883,7 @@ And this one looks for the first item in the internet keychain
entries for git.gnus.org:
(let ((auth-sources \\='(macos-keychain-internet\")))
- (auth-source-search :max 1 :host \"git.gnus.org\"))
-"
+ (auth-source-search :max 1 :host \"git.gnus.org\"))"
;; TODO
(cl-assert (not create) nil
"The macOS Keychain auth-source backend doesn't support creation yet")
@@ -1941,7 +1948,7 @@ entries for git.gnus.org:
(defun auth-source--decode-octal-string (string)
- "Convert octal string to utf-8 string. E.g: 'a\134b' to 'a\b'"
+ "Convert octal STRING to utf-8 string. E.g: 'a\134b' to 'a\b'."
(let ((list (string-to-list string))
(size (length string)))
(decode-coding-string
@@ -2267,7 +2274,7 @@ entries for git.gnus.org:
&key backend require
type max host user port
&allow-other-keys)
- "Given a property list SPEC, return search matches from the :backend.
+ "Given a property list SPEC, return search matches from the `:backend'.
See `auth-source-search' for details on SPEC."
;; just in case, check that the type is correct (null or same as the backend)
(cl-assert (or (null type) (eq type (oref backend type)))
diff --git a/lisp/autoarg.el b/lisp/autoarg.el
index 7c2c6f1030d..b52a4305be8 100644
--- a/lisp/autoarg.el
+++ b/lisp/autoarg.el
@@ -104,7 +104,7 @@ For example:
`6 9 a' inserts 69 `a's into the buffer.
`6 9 \\[autoarg-terminate] \\[autoarg-terminate]' inserts `69' into the buffer and
then invokes the normal binding of \\[autoarg-terminate].
-`C-u \\[autoarg-terminate]' invokes the normal binding of \\[autoarg-terminate] four times.
+`\\[universal-argument] \\[autoarg-terminate]' invokes the normal binding of \\[autoarg-terminate] four times.
\\{autoarg-mode-map}"
:lighter" Aarg" :global t :group 'keyboard)
diff --git a/lisp/autoinsert.el b/lisp/autoinsert.el
index 995d9e2e0fe..b448c0f8da9 100644
--- a/lisp/autoinsert.el
+++ b/lisp/autoinsert.el
@@ -83,10 +83,11 @@ When this is `function', only ask when called non-interactively."
(const :tag "Ask if called non-interactively" function)
(other :tag "Ask" t)))
-(defcustom auto-insert-prompt "Perform %s auto-insertion? "
- "Prompt to use when querying whether to auto-insert.
+(defcustom auto-insert-prompt "Perform %s auto-insertion?"
+ "Prompt to use when querying whether to `auto-insert'.
If this contains a %s, that will be replaced by the matching rule."
- :type 'string)
+ :type 'string
+ :version "28.1")
(defcustom auto-insert-alist
@@ -414,6 +415,7 @@ Matches the visited file name against the elements of `auto-insert-alist'."
"Associate CONDITION with (additional) ACTION in `auto-insert-alist'.
Optional AFTER means to insert action after all existing actions for CONDITION,
or if CONDITION had no actions, after all other CONDITIONs."
+ (declare (indent defun))
(let ((elt (assoc condition auto-insert-alist)))
(if elt
(setcdr elt
diff --git a/lisp/autorevert.el b/lisp/autorevert.el
index 9197eadf225..5b1cd322471 100644
--- a/lisp/autorevert.el
+++ b/lisp/autorevert.el
@@ -36,7 +36,7 @@
;; buffer contains no unsaved changes.
;;
;; Auto-Revert Mode can be activated for individual buffers. Global
-;; Auto-Revert Mode applies to all file buffers. (If the user option
+;; Auto-Revert Mode applies to all file buffers. (If the user option
;; `global-auto-revert-non-file-buffers' is non-nil, it also applies
;; to some non-file buffers. This option is disabled by default.)
;;
@@ -72,7 +72,7 @@
;; at the end of the buffer in that window, even if the window is not
;; selected. This way, you can use Auto-Revert Mode to `tail' a file.
;; Just put point at the end of the buffer and it will stay there.
-;; These rules apply to file buffers. For non-file buffers, the
+;; These rules apply to file buffers. For non-file buffers, the
;; behavior may be mode dependent.
;;
;; While you can use Auto-Revert Mode to tail a file, this package
@@ -521,13 +521,12 @@ specifies in the mode line."
;; To track non-file buffers, we need to listen in to buffer
;; creation in general. Listening to major-mode changes is
;; suitable, since we then know whether it's a mode that is tracked.
- (when global-auto-revert-non-file-buffers
- (add-hook 'after-change-major-mode-hook
- #'auto-revert--global-adopt-current-buffer))
+ (add-hook 'after-change-major-mode-hook
+ #'auto-revert--global-possibly-adopt-current-buffer)
(auto-revert-buffers))
;; Turn global-auto-revert-mode OFF.
(remove-hook 'after-change-major-mode-hook
- #'auto-revert--global-adopt-current-buffer)
+ #'auto-revert--global-possibly-adopt-current-buffer)
(remove-hook 'find-file-hook #'auto-revert--global-adopt-current-buffer)
(dolist (buf (buffer-list))
(with-current-buffer buf
@@ -556,6 +555,12 @@ specifies in the mode line."
nil)))
(setq auto-revert--global-mode t)))
+(defun auto-revert--global-possibly-adopt-current-buffer ()
+ "Consider tracking current buffer in a running Global Auto-Revert mode.
+This tracks buffers if `global-auto-revert-non-file-buffers' is non-nil."
+ (when global-auto-revert-non-file-buffers
+ (auto-revert--global-adopt-current-buffer)))
+
(defun auto-revert--global-adopt-current-buffer ()
"Consider tracking current buffer in a running Global Auto-Revert mode."
(auto-revert--global-add-current-buffer)
@@ -853,8 +858,8 @@ This is an internal function used by Auto-Revert Mode."
"Return a prioritized list of buffers to maybe auto-revert.
The differences between this return value and the reference
variable `auto-revert-buffer-list' include: 1) this has more
-entries when in global-auto-revert-mode; 2) this prioritizes
-buffers not reverted last time due to user interruption. "
+entries when in `global-auto-revert-mode'; 2) this prioritizes
+buffers not reverted last time due to user interruption."
(let ((bufs (delq nil
;; Buffers with remote contents shall be reverted only
;; if the connection is established already.
@@ -881,7 +886,7 @@ buffers not reverted last time due to user interruption. "
(nreverse (nconc new remaining))))
(defun auto-revert-buffer (buf)
- "Revert a single buffer.
+ "Revert a single buffer BUF.
This is performed as specified by Auto-Revert and Global
Auto-Revert Modes."
diff --git a/lisp/avoid.el b/lisp/avoid.el
index d3afecf8cc2..03707d10465 100644
--- a/lisp/avoid.el
+++ b/lisp/avoid.el
@@ -43,7 +43,7 @@
;;
;; (if (eq window-system 'x)
;; (mouse-avoidance-set-pointer-shape
-;; (nth (random 4)
+;; (seq-random-elt
;; (list x-pointer-man x-pointer-spider
;; x-pointer-gobbler x-pointer-gumby))))
;;
@@ -125,7 +125,6 @@ TOP-OR-BOTTOM-POS: Distance from top or bottom edge of frame or window."
;; Internal variables
(defvar mouse-avoidance-state nil)
(defvar mouse-avoidance-pointer-shapes nil)
-(defvar mouse-avoidance-n-pointer-shapes 0)
(defvar mouse-avoidance-old-pointer-shape nil)
(defvar mouse-avoidance-animating-pointer nil)
@@ -306,11 +305,8 @@ redefine this function to suit your own tastes."
(all-completions "x-pointer-" obarray
(lambda (x)
(and (boundp x)
- (integerp (symbol-value x)))))))
- (setq mouse-avoidance-n-pointer-shapes
- (length mouse-avoidance-pointer-shapes))))
- (nth (random mouse-avoidance-n-pointer-shapes)
- mouse-avoidance-pointer-shapes))
+ (integerp (symbol-value x)))))))))
+ (seq-random-elt mouse-avoidance-pointer-shapes))
(defun mouse-avoidance-ignore-p ()
(let ((mp (mouse-position)))
diff --git a/lisp/bindings.el b/lisp/bindings.el
index 03459448943..ba3bf81b3e3 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -184,8 +184,8 @@ mouse-3: Remove current window from display"))
(defvar mode-line-front-space '(:eval (if (display-graphic-p) " " "-"))
"Mode line construct to put at the front of the mode line.
By default, this construct is displayed right at the beginning of
-the mode line, except that if there is a memory-full message, it
-is displayed first.")
+the mode line, except that if there is a \"memory full\" message,
+it is displayed first.")
(put 'mode-line-front-space 'risky-local-variable t)
(defun mode-line-mule-info-help-echo (window _object _point)
@@ -288,7 +288,7 @@ mnemonics of the following coding systems:
Value is used for `mode-line-frame-identification', which see."
(if (or (null window-system)
(eq window-system 'pc))
- "-%F "
+ " %F "
" "))
;; We need to defer the call to mode-line-frame-control to the time
@@ -381,7 +381,8 @@ Keymap to display on major mode.")
Keymap to display on minor modes.")
(defvar mode-line-modes
- (let ((recursive-edit-help-echo "Recursive edit, type C-M-c to get out"))
+ (let ((recursive-edit-help-echo
+ "Recursive edit, type M-C-c to get out"))
(list (propertize "%[" 'help-echo recursive-edit-help-echo)
"("
`(:propertize ("" mode-name)
@@ -500,11 +501,12 @@ mouse-1: Display Line and Column Mode Menu"))
(defvar mode-line-position
`((:propertize
- mode-line-percent-position
+ (" " mode-line-percent-position)
local-map ,mode-line-column-line-number-mode-map
+ display (min-width (5.0))
mouse-face mode-line-highlight
;; XXX needs better description
- help-echo "Size indication mode\n\
+ help-echo "Window Scroll Percentage
mouse-1: Display Line and Column Mode Menu")
(size-indication-mode
(8 ,(propertize
@@ -520,26 +522,31 @@ mouse-1: Display Line and Column Mode Menu")))
(10
(:propertize
mode-line-position-column-line-format
+ display (min-width (10.0))
,@mode-line-position--column-line-properties))
(10
(:propertize
(:eval (string-replace
"%c" "%C" (car mode-line-position-column-line-format)))
+ display (min-width (10.0))
,@mode-line-position--column-line-properties)))
(6
(:propertize
mode-line-position-line-format
+ display (min-width (6.0))
,@mode-line-position--column-line-properties))))
(column-number-mode
(column-number-indicator-zero-based
(6
(:propertize
mode-line-position-column-format
+ display (min-width (6.0))
(,@mode-line-position--column-line-properties)))
(6
(:propertize
(:eval (string-replace
"%c" "%C" (car mode-line-position-column-format)))
+ display (min-width (6.0))
,@mode-line-position--column-line-properties))))))
"Mode line construct for displaying the position in the buffer.
Normally displays the buffer percentage and, optionally, the
@@ -596,10 +603,14 @@ By default, this shows the information specified by `global-mode-string'.")
(let ((standard-mode-line-format
(list "%e"
'mode-line-front-space
- 'mode-line-mule-info
- 'mode-line-client
- 'mode-line-modified
- 'mode-line-remote
+ (list
+ :propertize
+ (list ""
+ 'mode-line-mule-info
+ 'mode-line-client
+ 'mode-line-modified
+ 'mode-line-remote)
+ 'display '(min-width (5.0)))
'mode-line-frame-identification
'mode-line-buffer-identification
" "
@@ -614,20 +625,20 @@ By default, this shows the information specified by `global-mode-string'.")
(list `(quote ,standard-mode-line-format))))
-(defun mode-line-unbury-buffer (event) "\
-Call `unbury-buffer' in this window."
+(defun mode-line-unbury-buffer (event)
+ "Call `unbury-buffer' in this window."
(interactive "e")
(with-selected-window (posn-window (event-start event))
(unbury-buffer)))
-(defun mode-line-bury-buffer (event) "\
-Like `bury-buffer', but temporarily select EVENT's window."
+(defun mode-line-bury-buffer (event)
+ "Like `bury-buffer', but temporarily select EVENT's window."
(interactive "e")
(with-selected-window (posn-window (event-start event))
(bury-buffer)))
-(defun mode-line-other-buffer () "\
-Switch to the most recently selected buffer other than the current one."
+(defun mode-line-other-buffer ()
+ "Switch to the most recently selected buffer other than the current one."
(interactive)
(switch-to-buffer (other-buffer) nil t))
@@ -980,7 +991,7 @@ if `inhibit-field-text-motion' is non-nil."
(define-key ctl-x-map "\M-:" 'repeat-complex-command)
(define-key ctl-x-map "u" 'undo)
(put 'undo :advertised-binding [?\C-x ?u])
-;; Many people are used to typing C-/ on X terminals and getting C-_.
+;; Many people are used to typing C-/ on GUI frames and getting C-_.
(define-key global-map [?\C-/] 'undo)
(define-key global-map "\C-_" 'undo)
;; Richard said that we should not use C-x <uppercase letter> and I have
@@ -993,6 +1004,9 @@ if `inhibit-field-text-motion' is non-nil."
"Keymap to repeat undo key sequences `C-x u u'. Used in `repeat-mode'.")
(put 'undo 'repeat-map 'undo-repeat-map)
+(define-key global-map '[(control ??)] 'undo-redo)
+(define-key global-map [?\C-\M-_] 'undo-redo)
+
(define-key esc-map "!" 'shell-command)
(define-key esc-map "|" 'shell-command-on-region)
(define-key esc-map "&" 'async-shell-command)
@@ -1085,7 +1099,7 @@ if `inhibit-field-text-motion' is non-nil."
(define-key map "p" 'previous-error)
(define-key map "\M-p" 'previous-error)
map)
- "Keymap to repeat next-error key sequences. Used in `repeat-mode'.")
+ "Keymap to repeat `next-error' key sequences. Used in `repeat-mode'.")
(put 'next-error 'repeat-map 'next-error-repeat-map)
(put 'previous-error 'repeat-map 'next-error-repeat-map)
@@ -1247,6 +1261,8 @@ if `inhibit-field-text-motion' is non-nil."
;; (define-key global-map [kp-9] 'function-key-error)
;; (define-key global-map [kp-equal] 'function-key-error)
+(define-key global-map [touch-end] 'ignore)
+
;; X11 distinguishes these keys from the non-kp keys.
;; Make them behave like the non-kp keys unless otherwise bound.
;; FIXME: rather than list such mappings for every modifier-combination,
@@ -1434,6 +1450,17 @@ if `inhibit-field-text-motion' is non-nil."
(define-key ctl-x-map "[" 'backward-page)
(define-key ctl-x-map "]" 'forward-page)
+
+(defvar page-navigation-repeat-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "]" #'forward-page)
+ (define-key map "[" #'backward-page)
+ map)
+ "Keymap to repeat page navigation key sequences. Used in `repeat-mode'.")
+
+(put 'forward-page 'repeat-map 'page-navigation-repeat-map)
+(put 'backward-page 'repeat-map 'page-navigation-repeat-map)
+
(define-key ctl-x-map "\C-p" 'mark-page)
(define-key ctl-x-map "l" 'count-lines-page)
(define-key ctl-x-map "np" 'narrow-to-page)
diff --git a/lisp/bookmark.el b/lisp/bookmark.el
index ff9b8ab1388..f35cbc1a5ec 100644
--- a/lisp/bookmark.el
+++ b/lisp/bookmark.el
@@ -27,7 +27,7 @@
;; associates a string with a location in a certain file. Thus, you
;; can navigate your way to that location by providing the string.
;;
-;; Type `M-x customize-group RET boomark RET' for user options.
+;; Type `M-x customize-group RET bookmark RET' for user options.
;;; Code:
@@ -173,10 +173,8 @@ A non-nil value may result in truncated bookmark names."
"Time before `bookmark-bmenu-search' updates the display."
:type 'number)
-(defcustom bookmark-fontify t
- "Whether to colorize a bookmarked line.
-If non-nil, setting a bookmark will colorize the current line with
-`bookmark-face'."
+(defcustom bookmark-set-fringe-mark t
+ "Whether to set a fringe mark at bookmarked lines."
:type 'boolean
:version "28.1")
@@ -189,16 +187,16 @@ If non-nil, setting a bookmark will colorize the current line with
(defface bookmark-face
'((((class grayscale)
(background light))
- :background "DimGray")
+ :foreground "DimGray")
(((class grayscale)
(background dark))
- :background "LightGray")
+ :foreground "LightGray")
(((class color)
(background light))
- :foreground "White" :background "DarkOrange1")
+ :background "White" :foreground "DarkOrange1")
(((class color)
(background dark))
- :foreground "Black" :background "DarkOrange1"))
+ :background "Black" :foreground "DarkOrange1"))
"Face used to highlight current line."
:version "28.1")
@@ -216,31 +214,28 @@ If non-nil, setting a bookmark will colorize the current line with
;;;###autoload (define-key ctl-x-r-map "l" 'bookmark-bmenu-list)
;;;###autoload
-(defvar bookmark-map
- (let ((map (make-sparse-keymap)))
- ;; Read the help on all of these functions for details...
- (define-key map "x" 'bookmark-set)
- (define-key map "m" 'bookmark-set) ;"m"ark
- (define-key map "M" 'bookmark-set-no-overwrite) ;"M"aybe mark
- (define-key map "j" 'bookmark-jump)
- (define-key map "g" 'bookmark-jump) ;"g"o
- (define-key map "o" 'bookmark-jump-other-window)
- (define-key map "5" 'bookmark-jump-other-frame)
- (define-key map "i" 'bookmark-insert)
- (define-key map "e" 'edit-bookmarks)
- (define-key map "f" 'bookmark-insert-location) ;"f"ind
- (define-key map "r" 'bookmark-rename)
- (define-key map "d" 'bookmark-delete)
- (define-key map "D" 'bookmark-delete-all)
- (define-key map "l" 'bookmark-load)
- (define-key map "w" 'bookmark-write)
- (define-key map "s" 'bookmark-save)
- map)
- "Keymap containing bindings to bookmark functions.
+(defvar-keymap bookmark-map
+ :doc "Keymap containing bindings to bookmark functions.
It is not bound to any key by default: to bind it
so that you have a bookmark prefix, just use `global-set-key' and bind a
key of your choice to variable `bookmark-map'. All interactive bookmark
-functions have a binding in this keymap.")
+functions have a binding in this keymap."
+ "x" #'bookmark-set
+ "m" #'bookmark-set ;"m"ark
+ "M" #'bookmark-set-no-overwrite ;"M"aybe mark
+ "j" #'bookmark-jump
+ "g" #'bookmark-jump ;"g"o
+ "o" #'bookmark-jump-other-window
+ "5" #'bookmark-jump-other-frame
+ "i" #'bookmark-insert
+ "e" #'edit-bookmarks
+ "f" #'bookmark-insert-location ;"f"ind
+ "r" #'bookmark-rename
+ "d" #'bookmark-delete
+ "D" #'bookmark-delete-all
+ "l" #'bookmark-load
+ "w" #'bookmark-write
+ "s" #'bookmark-save)
;;;###autoload (fset 'bookmark-map bookmark-map)
@@ -281,7 +276,7 @@ STR-BEFORE-POS is buffer text that immediately precedes POS.
ANNOTATION is a string that describes the bookmark.
See options `bookmark-use-annotations' and
`bookmark-automatically-show-annotations'.
-HANDLER is a function that provides the bookmark-jump behavior for a
+HANDLER is a function that provides the `bookmark-jump' behavior for a
specific kind of bookmark instead of the default `bookmark-default-handler'.
This is the case for Info bookmarks, for instance. HANDLER must accept
a bookmark as its single argument.
@@ -455,18 +450,24 @@ In other words, return all information but the name."
(defvar bookmark-history nil
"The history list for bookmark functions.")
-(defun bookmark--fontify ()
+(define-fringe-bitmap 'bookmark-fringe-mark
+ "\x3c\x7e\xff\xff\xff\xff\x7e\x3c")
+
+(defun bookmark--set-fringe-mark ()
"Apply a colorized overlay to the bookmarked location.
-See user option `bookmark-fontify'."
- (let ((bm (make-overlay (point-at-bol)
- (min (point-max) (1+ (point-at-eol))))))
+See user option `bookmark-set-fringe-mark'."
+ (let ((bm (make-overlay (point-at-bol) (1+ (point-at-bol)))))
(overlay-put bm 'category 'bookmark)
- (overlay-put bm 'face 'bookmark-face)))
+ (overlay-put bm 'evaporate t)
+ (overlay-put bm 'before-string
+ (propertize
+ "x" 'display
+ `(left-fringe bookmark-fringe-mark bookmark-face)))))
-(defun bookmark--unfontify (bm)
+(defun bookmark--remove-fringe-mark (bm)
"Remove a bookmark's colorized overlay.
BM is a bookmark as returned from function `bookmark-get-bookmark'.
-See user option `bookmark-fontify'."
+See user option `bookmark-set-fringe'."
(let ((filename (cdr (assq 'filename bm)))
(pos (cdr (assq 'position bm)))
overlays found temp)
@@ -475,7 +476,10 @@ See user option `bookmark-fontify'."
(dolist (buf (buffer-list))
(with-current-buffer buf
(when (equal filename buffer-file-name)
- (setq overlays (overlays-at pos))
+ (setq overlays
+ (save-excursion
+ (goto-char pos)
+ (overlays-in (point-at-bol) (1+ (point-at-bol)))))
(while (and (not found) (setq temp (pop overlays)))
(when (eq 'bookmark (overlay-get temp 'category))
(delete-overlay (setq found temp))))))))))
@@ -494,11 +498,8 @@ If DEFAULT is nil then return empty string for empty input."
'string-lessp)
(bookmark-all-names)))
(let* ((completion-ignore-case bookmark-completion-ignore-case)
- (default (unless (equal "" default) default))
- (prompt (concat prompt (if default
- (format " (%s): " default)
- ": "))))
- (completing-read prompt
+ (default (unless (equal "" default) default)))
+ (completing-read (format-prompt prompt default)
(lambda (string pred action)
(if (eq action 'metadata)
'(metadata (category . bookmark))
@@ -509,8 +510,9 @@ If DEFAULT is nil then return empty string for empty input."
(defmacro bookmark-maybe-historicize-string (string)
"Put STRING into the bookmark prompt history, if caller non-interactive.
-We need this because sometimes bookmark functions are invoked from
-menus, so `completing-read' never gets a chance to set `bookmark-history'."
+We need this because sometimes bookmark functions are invoked
+from other commands that pass in the bookmark name, so
+`completing-read' never gets a chance to set `bookmark-history'."
`(or
(called-interactively-p 'interactive)
(setq bookmark-history (cons ,string bookmark-history))))
@@ -565,8 +567,8 @@ old one."
;; no prefix arg means just overwrite old bookmark.
(let ((bm (bookmark-get-bookmark stripped-name)))
;; First clean up if previously location was fontified.
- (when bookmark-fontify
- (bookmark--unfontify bm))
+ (when bookmark-set-fringe-mark
+ (bookmark--remove-fringe-mark bm))
;; Modify using the new (NAME . ALIST) format.
(setcdr bm alist))
@@ -809,11 +811,9 @@ CODING is the symbol of the coding-system in which the file is encoded."
(define-obsolete-function-alias 'bookmark-maybe-message 'message "27.1")
-(defvar bookmark-minibuffer-read-name-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map minibuffer-local-map)
- (define-key map "\C-w" 'bookmark-yank-word)
- map))
+(defvar-keymap bookmark-minibuffer-read-name-map
+ :parent minibuffer-local-map
+ "C-w" #'bookmark-yank-word)
(defun bookmark-set-internal (prompt name overwrite-or-push)
"Set a bookmark using specified NAME or prompting with PROMPT.
@@ -882,8 +882,8 @@ still there, in order, if the topmost one is ever deleted."
;; Ask for an annotation buffer for this bookmark
(when bookmark-use-annotations
(bookmark-edit-annotation str))
- (when bookmark-fontify
- (bookmark--fontify))))
+ (when bookmark-set-fringe-mark
+ (bookmark--set-fringe-mark))))
(setq bookmark-yank-point nil)
(setq bookmark-current-buffer nil)))
@@ -901,21 +901,23 @@ others are still there, should the user decide to delete the most
recent one.
To yank words from the text of the buffer and use them as part of the
-bookmark name, type C-w while setting a bookmark. Successive C-w's
+bookmark name, type \\<bookmark-minibuffer-read-name-map>\
+\\[bookmark-yank-word] while setting a bookmark. Successive \
+\\[bookmark-yank-word]'s
yank successive words.
-Typing C-u inserts (at the bookmark name prompt) the name of the last
+Typing \\[universal-argument] inserts (at the bookmark name prompt) the name of the last
bookmark used in the document where the new bookmark is being set;
this helps you use a single bookmark name to track progress through a
large document. If there is no prior bookmark for this document, then
-C-u inserts an appropriate name based on the buffer or file.
+\\[universal-argument] inserts an appropriate name based on the buffer or file.
Use \\[bookmark-delete] to remove bookmarks (you give it a name and
it removes only the first instance of a bookmark with that name from
the list of bookmarks.)"
(interactive (list nil current-prefix-arg))
(let ((prompt
- (if no-overwrite "Set bookmark" "Set bookmark unconditionally")))
+ (if no-overwrite "Append bookmark named" "Set bookmark named")))
(bookmark-set-internal prompt name (if no-overwrite 'push 'overwrite))))
;;;###autoload
@@ -934,14 +936,16 @@ Otherwise, if a bookmark named NAME already exists but PUSH-BOOKMARK
is nil, raise an error.
To yank words from the text of the buffer and use them as part of the
-bookmark name, type C-w while setting a bookmark. Successive C-w's
+bookmark name, type \\<bookmark-minibuffer-read-name-map>\
+\\[bookmark-yank-word] while setting a bookmark. Successive \
+\\[bookmark-yank-word]'s
yank successive words.
-Typing C-u inserts (at the bookmark name prompt) the name of the last
+Typing \\[universal-argument] inserts (at the bookmark name prompt) the name of the last
bookmark used in the document where the new bookmark is being set;
this helps you use a single bookmark name to track progress through a
large document. If there is no prior bookmark for this document, then
-C-u inserts an appropriate name based on the buffer or file.
+\\[universal-argument] inserts an appropriate name based on the buffer or file.
Use \\[bookmark-delete] to remove bookmarks (you give it a name and
it removes only the first instance of a bookmark with that name from
@@ -984,12 +988,10 @@ annotations."
"Function to return default text to use for a bookmark annotation.
It takes one argument, the name of the bookmark, as a string.")
-(defvar bookmark-edit-annotation-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map text-mode-map)
- (define-key map "\C-c\C-c" 'bookmark-send-edited-annotation)
- map)
- "Keymap for editing an annotation of a bookmark.")
+(defvar-keymap bookmark-edit-annotation-mode-map
+ :doc "Keymap for editing an annotation of a bookmark."
+ :parent text-mode-map
+ "C-c C-c" #'bookmark-send-edited-annotation)
(defun bookmark-insert-annotation (bookmark-name-or-record)
"Insert annotation for BOOKMARK-NAME-OR-RECORD at point."
@@ -1152,14 +1154,14 @@ and then show any annotations for this bookmark."
(if win (set-window-point win (point))))
;; FIXME: we used to only run bookmark-after-jump-hook in
;; `bookmark-jump' itself, but in none of the other commands.
- (when bookmark-fontify
- (let ((overlays (overlays-at (point)))
+ (when bookmark-set-fringe-mark
+ (let ((overlays (overlays-in (point) (point)))
temp found)
(while (and (not found) (setq temp (pop overlays)))
(when (eq 'bookmark (overlay-get temp 'category))
(setq found t)))
(unless found
- (bookmark--fontify))))
+ (bookmark--set-fringe-mark))))
(run-hooks 'bookmark-after-jump-hook)
(if bookmark-automatically-show-annotations
;; if there is an annotation for this bookmark,
@@ -1357,7 +1359,8 @@ If called from Lisp, prompt for NEW-NAME if only OLD-NAME was passed
as an argument. If called with two strings, then no prompting is done.
You must pass at least OLD-NAME when calling from Lisp.
-While you are entering the new name, consecutive C-w's insert
+While you are entering the new name, consecutive \
+\\<bookmark-minibuffer-read-name-map>\\[bookmark-yank-word]'s insert
consecutive words from the text of the buffer into the new bookmark
name."
(interactive (list (bookmark-completing-read "Old bookmark name")))
@@ -1423,7 +1426,7 @@ probably because we were called from there."
(bookmark-maybe-historicize-string bookmark-name)
(bookmark-maybe-load-default-file)
(let ((will-go (bookmark-get-bookmark bookmark-name 'noerror)))
- (bookmark--unfontify will-go)
+ (bookmark--remove-fringe-mark will-go)
(setq bookmark-alist (delq will-go bookmark-alist))
;; Added by db, nil bookmark-current-bookmark if the last
;; occurrence has been deleted
@@ -1490,7 +1493,7 @@ is greater than `bookmark-alist-modification-count'."
"Save currently defined bookmarks in FILE.
FILE defaults to `bookmark-default-file'.
With prefix PARG, query user for a file to save in.
-If MAKE-DEFAULT is non-nil (interactively with prefix C-u C-u)
+If MAKE-DEFAULT is non-nil (interactively with prefix \\[universal-argument] \\[universal-argument])
the file we save in becomes the new default in the current Emacs
session (without affecting the value of `bookmark-default-file'.).
@@ -1691,47 +1694,45 @@ unique numeric suffixes \"<2>\", \"<3>\", etc."
(defvar bookmark-bmenu-hidden-bookmarks ())
-
-(defvar bookmark-bmenu-mode-map
- (let ((map (make-keymap)))
- (set-keymap-parent map tabulated-list-mode-map)
- (define-key map "v" 'bookmark-bmenu-select)
- (define-key map "w" 'bookmark-bmenu-locate)
- (define-key map "5" 'bookmark-bmenu-other-frame)
- (define-key map "2" 'bookmark-bmenu-2-window)
- (define-key map "1" 'bookmark-bmenu-1-window)
- (define-key map "j" 'bookmark-bmenu-this-window)
- (define-key map "\C-c\C-c" 'bookmark-bmenu-this-window)
- (define-key map "f" 'bookmark-bmenu-this-window)
- (define-key map "\C-m" 'bookmark-bmenu-this-window)
- (define-key map "o" 'bookmark-bmenu-other-window)
- (define-key map "\C-o" 'bookmark-bmenu-switch-other-window)
- (define-key map "s" 'bookmark-bmenu-save)
- (define-key map "\C-x\C-s" 'bookmark-bmenu-save)
- (define-key map "k" 'bookmark-bmenu-delete)
- (define-key map "\C-d" 'bookmark-bmenu-delete-backwards)
- (define-key map "x" 'bookmark-bmenu-execute-deletions)
- (define-key map "d" 'bookmark-bmenu-delete)
- (define-key map "D" 'bookmark-bmenu-delete-all)
- (define-key map " " 'next-line)
- (define-key map "\177" 'bookmark-bmenu-backup-unmark)
- (define-key map "u" 'bookmark-bmenu-unmark)
- (define-key map "U" 'bookmark-bmenu-unmark-all)
- (define-key map "m" 'bookmark-bmenu-mark)
- (define-key map "M" 'bookmark-bmenu-mark-all)
- (define-key map "l" 'bookmark-bmenu-load)
- (define-key map "r" 'bookmark-bmenu-rename)
- (define-key map "R" 'bookmark-bmenu-relocate)
- (define-key map "t" 'bookmark-bmenu-toggle-filenames)
- (define-key map "a" 'bookmark-bmenu-show-annotation)
- (define-key map "A" 'bookmark-bmenu-show-all-annotations)
- (define-key map "e" 'bookmark-bmenu-edit-annotation)
- (define-key map "/" 'bookmark-bmenu-search)
- (define-key map [mouse-2] 'bookmark-bmenu-other-window-with-mouse)
- map))
-
-(easy-menu-define
- bookmark-menu bookmark-bmenu-mode-map "Bookmark Menu"
+(defvar-keymap bookmark-bmenu-mode-map
+ :doc "Keymap for `bookmark-bmenu-mode'."
+ :parent tabulated-list-mode-map
+ "v" #'bookmark-bmenu-select
+ "w" #'bookmark-bmenu-locate
+ "5" #'bookmark-bmenu-other-frame
+ "2" #'bookmark-bmenu-2-window
+ "1" #'bookmark-bmenu-1-window
+ "j" #'bookmark-bmenu-this-window
+ "C-c C-c" #'bookmark-bmenu-this-window
+ "f" #'bookmark-bmenu-this-window
+ "C-m" #'bookmark-bmenu-this-window
+ "o" #'bookmark-bmenu-other-window
+ "C-o" #'bookmark-bmenu-switch-other-window
+ "s" #'bookmark-bmenu-save
+ "C-x C-s" #'bookmark-bmenu-save
+ "k" #'bookmark-bmenu-delete
+ "C-d" #'bookmark-bmenu-delete-backwards
+ "x" #'bookmark-bmenu-execute-deletions
+ "d" #'bookmark-bmenu-delete
+ "D" #'bookmark-bmenu-delete-all
+ "SPC" #'next-line
+ "DEL" #'bookmark-bmenu-backup-unmark
+ "u" #'bookmark-bmenu-unmark
+ "U" #'bookmark-bmenu-unmark-all
+ "m" #'bookmark-bmenu-mark
+ "M" #'bookmark-bmenu-mark-all
+ "l" #'bookmark-bmenu-load
+ "r" #'bookmark-bmenu-rename
+ "R" #'bookmark-bmenu-relocate
+ "t" #'bookmark-bmenu-toggle-filenames
+ "a" #'bookmark-bmenu-show-annotation
+ "A" #'bookmark-bmenu-show-all-annotations
+ "e" #'bookmark-bmenu-edit-annotation
+ "/" #'bookmark-bmenu-search
+ "<mouse-2>" #'bookmark-bmenu-other-window-with-mouse)
+
+(easy-menu-define bookmark-menu bookmark-bmenu-mode-map
+ "Menu for `bookmark-bmenu'."
'("Bookmark"
["Select Bookmark in This Window" bookmark-bmenu-this-window t]
["Select Bookmark in Full-Frame Window" bookmark-bmenu-1-window t]
@@ -2058,7 +2059,7 @@ You can mark bookmarks with the \\<bookmark-bmenu-mode-map>\\[bookmark-bmenu-mar
(defun bookmark-bmenu-save ()
"Save the current list into a bookmark file.
-With a prefix arg, prompts for a file to save them in.
+With a prefix arg, prompt for a file to save them in.
See also the related behaviors of `bookmark-load' and
`bookmark-bmenu-load'."
@@ -2308,10 +2309,10 @@ Prompt with completion for the new path."
(lambda ()
(setq timer (run-with-idle-timer
bookmark-search-delay 'repeat
- #'(lambda (buf)
- (with-current-buffer buf
- (bookmark-bmenu-filter-alist-by-regexp
- (minibuffer-contents))))
+ (lambda (buf)
+ (with-current-buffer buf
+ (bookmark-bmenu-filter-alist-by-regexp
+ (minibuffer-contents))))
(current-buffer))))
(read-string "Pattern: ")
(when timer (cancel-timer timer) (setq timer nil)))
diff --git a/lisp/bs.el b/lisp/bs.el
index 494bc426188..ccb06bbdba0 100644
--- a/lisp/bs.el
+++ b/lisp/bs.el
@@ -4,6 +4,8 @@
;; Author: Olaf Sylvester <Olaf.Sylvester@netsurf.de>
;; Maintainer: emacs-devel@gnu.org
;; Keywords: convenience
+;; Old-Version: 1.17
+;; URL: http://www.geekware.de/software/emacs
;; This file is part of GNU Emacs.
@@ -22,9 +24,6 @@
;;; Commentary:
-;; Version: 1.17
-;; X-URL: http://www.geekware.de/software/emacs
-;;
;; The bs-package contains a main function bs-show for popping up a
;; buffer in a way similar to `list-buffers' and `electric-buffer-list':
;; The new buffer offers a Buffer Selection Menu for manipulating
diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el
index 340c926f8d6..1013a7c4973 100644
--- a/lisp/buff-menu.el
+++ b/lisp/buff-menu.el
@@ -222,7 +222,7 @@ In Buffer Menu mode, the following commands are defined:
so the Buffer Menu remains visible in its window.
\\[Buffer-menu-view] Select current line's buffer, in View mode.
\\[Buffer-menu-view-other-window] Select that buffer in
- another window, in view-mode.
+ another window, in `view-mode'.
\\[Buffer-menu-switch-other-window] Make another window display that buffer.
\\[Buffer-menu-mark] Mark current line's buffer to be displayed.
\\[Buffer-menu-select] Select current line's buffer.
@@ -233,7 +233,7 @@ In Buffer Menu mode, the following commands are defined:
\\[Buffer-menu-isearch-buffers] Incremental search in the marked buffers.
\\[Buffer-menu-isearch-buffers-regexp] Isearch for regexp in the marked buffers.
\\[Buffer-menu-multi-occur] Show lines matching regexp in the marked buffers.
-\\[Buffer-menu-visit-tags-table] visit-tags-table this buffer.
+\\[Buffer-menu-visit-tags-table] `visit-tags-table' this buffer.
\\[Buffer-menu-not-modified] Clear modified-flag on that buffer.
\\[Buffer-menu-save] Mark that buffer to be saved, and move down.
\\[Buffer-menu-delete] Mark that buffer to be deleted, and move down.
@@ -306,7 +306,7 @@ ARG, show only buffers that are visiting files."
(display-buffer (list-buffers-noselect arg)))
(defun Buffer-menu-toggle-files-only (arg)
- "Toggle whether the current buffer-menu displays only file buffers.
+ "Toggle whether the current `buffer-menu' displays only file buffers.
With a positive ARG, display only file buffers. With zero or
negative ARG, display other buffers as well."
(interactive "P" Buffer-menu-mode)
diff --git a/lisp/button.el b/lisp/button.el
index 74dfb5d5419..dd5a71d116a 100644
--- a/lisp/button.el
+++ b/lisp/button.el
@@ -113,22 +113,24 @@ Mode-specific keymaps may want to use this as their parent keymap.")
;; [this is an internal function]
(defsubst button-category-symbol (type)
- "Return the symbol used by button-type TYPE to store properties.
+ "Return the symbol used by `button-type' TYPE to store properties.
Buttons inherit them by setting their `category' property to that symbol."
(or (get type 'button-category-symbol)
(error "Unknown button type `%s'" type)))
(defun define-button-type (name &rest properties)
"Define a `button type' called NAME (a symbol).
-The remaining arguments form a plist of PROPERTY VALUE pairs,
-specifying properties to use as defaults for buttons with this type
-\(a button's type may be set by giving it a `type' property when
-creating the button, using the :type keyword argument).
+The remaining PROPERTIES arguments form a plist of PROPERTY VALUE
+pairs, specifying properties to use as defaults for buttons with
+this type (a button's type may be set by giving it a `type'
+property when creating the button, using the :type keyword
+argument).
In addition, the keyword argument :supertype may be used to specify a
-button-type from which NAME inherits its default property values
-\(however, the inheritance happens only when NAME is defined; subsequent
+`button-type' from which NAME inherits its default property values
+(however, the inheritance happens only when NAME is defined; subsequent
changes to a supertype are not reflected in its subtypes)."
+ (declare (indent defun))
(let ((catsym (make-symbol (concat (symbol-name name) "-button")))
(super-catsym
(button-category-symbol
@@ -156,15 +158,15 @@ changes to a supertype are not reflected in its subtypes)."
name))
(defun button-type-put (type prop val)
- "Set the button-type TYPE's PROP property to VAL."
+ "Set the `button-type' TYPE's PROP property to VAL."
(put (button-category-symbol type) prop val))
(defun button-type-get (type prop)
- "Get the property of button-type TYPE named PROP."
+ "Get the property of `button-type' TYPE named PROP."
(get (button-category-symbol type) prop))
(defun button-type-subtype-p (type supertype)
- "Return non-nil if button-type TYPE is a subtype of SUPERTYPE."
+ "Return non-nil if `button-type' TYPE is a subtype of SUPERTYPE."
(or (eq type supertype)
(and type
(button-type-subtype-p (button-type-get type 'supertype)
@@ -271,11 +273,11 @@ This function only works when BUTTON is in the current buffer."
(button-end button))))
(defsubst button-type (button)
- "Return BUTTON's button-type."
+ "Return BUTTON's `button-type'."
(button-get button 'type))
(defun button-has-type-p (button type)
- "Return non-nil if BUTTON has button-type TYPE, or one of its subtypes."
+ "Return non-nil if BUTTON has `button-type' TYPE, or one of its subtypes."
(button-type-subtype-p (button-get button 'type) type))
(defun button--area-button-p (b)
@@ -290,10 +292,10 @@ Such area buttons are used for buttons in the mode-line and header-line."
(defun make-button (beg end &rest properties)
"Make a button from BEG to END in the current buffer.
-The remaining arguments form a plist of PROPERTY VALUE pairs,
-specifying properties to add to the button.
+The remaining PROPERTIES arguments form a plist of PROPERTY VALUE
+pairs, specifying properties to add to the button.
In addition, the keyword argument :type may be used to specify a
-button-type from which to inherit other properties; see
+`button-type' from which to inherit other properties; see
`define-button-type'.
Also see `make-text-button', `insert-button'."
@@ -314,7 +316,7 @@ Also see `make-text-button', `insert-button'."
The remaining arguments form a plist of PROPERTY VALUE pairs,
specifying properties to add to the button.
In addition, the keyword argument :type may be used to specify a
-button-type from which to inherit other properties; see
+`button-type' from which to inherit other properties; see
`define-button-type'.
Also see `insert-text-button', `make-button'."
@@ -328,10 +330,10 @@ Also see `insert-text-button', `make-button'."
(defun make-text-button (beg end &rest properties)
"Make a button from BEG to END in the current buffer.
-The remaining arguments form a plist of PROPERTY VALUE pairs,
-specifying properties to add to the button.
+The remaining PROPERTIES arguments form a plist of PROPERTY VALUE
+pairs, specifying properties to add to the button.
In addition, the keyword argument :type may be used to specify a
-button-type from which to inherit other properties; see
+`button-type' from which to inherit other properties; see
`define-button-type'.
This function is like `make-button', except that the button is actually
@@ -382,10 +384,10 @@ Also see `insert-text-button'."
(defun insert-text-button (label &rest properties)
"Insert a button with the label LABEL.
-The remaining arguments form a plist of PROPERTY VALUE pairs,
-specifying properties to add to the button.
+The remaining PROPERTIES arguments form a plist of PROPERTY VALUE
+pairs, specifying properties to add to the button.
In addition, the keyword argument :type may be used to specify a
-button-type from which to inherit other properties; see
+`button-type' from which to inherit other properties; see
`define-button-type'.
This function is like `insert-button', except that the button is
@@ -602,7 +604,8 @@ When called from Lisp, pass BUTTON-OR-POS as the button to describe, or a
buffer position where a button is present. If BUTTON-OR-POS is nil, the
button at point is the button to describe."
(interactive "d")
- (let* ((button (cond ((integer-or-marker-p button-or-pos)
+ (let* ((help-buffer-under-preparation t)
+ (button (cond ((integer-or-marker-p button-or-pos)
(button-at button-or-pos))
((null button-or-pos) (button-at (point)))
((overlayp button-or-pos) button-or-pos)))
@@ -614,13 +617,19 @@ button at point is the button to describe."
(button--describe props)
t)))
-(defun button-buttonize (string callback &optional data)
+(define-obsolete-function-alias 'button-buttonize #'buttonize "29.1")
+
+(defun buttonize (string callback &optional data help-echo)
"Make STRING into a button and return it.
When clicked, CALLBACK will be called with the DATA as the
function argument. If DATA isn't present (or is nil), the button
-itself will be used instead as the function argument."
+itself will be used instead as the function argument.
+
+If HELP-ECHO, use that as the `help-echo' property."
(propertize string
'face 'button
+ 'mouse-face 'highlight
+ 'help-echo help-echo
'button t
'follow-link t
'category t
diff --git a/lisp/calc/calc-aent.el b/lisp/calc/calc-aent.el
index db4751a9fbb..52c024865a7 100644
--- a/lisp/calc/calc-aent.el
+++ b/lisp/calc/calc-aent.el
@@ -49,7 +49,7 @@
(declare-function math-to-percentsigns "calccomp" (x))
(defvar calc-quick-calc-history nil
- "The history list for quick-calc.")
+ "The history list for `quick-calc'.")
;;;###autoload
(defun calc-do-quick-calc (&optional insert)
@@ -537,8 +537,7 @@ The value t means abort and give an error message.")
("₋" "-") ; -
("₍" "(") ; (
("₎" ")")) ; )
- "A list whose elements (old new) indicate replacements to make
-in Calc algebraic input.")
+ "A list indicating replacements to make in Calc algebraic input.")
(defvar math-read-superscripts
"⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁽⁾ⁿⁱ" ; 0123456789+-()ni
diff --git a/lisp/calc/calc-bin.el b/lisp/calc/calc-bin.el
index 503ed777029..a1f4ca43e71 100644
--- a/lisp/calc/calc-bin.el
+++ b/lisp/calc/calc-bin.el
@@ -202,7 +202,7 @@
(defun math-power-of-2 (n) ; [I I] [Public]
(if (natnump n)
(ash 1 n)
- (error "argument must be a natural number")))
+ (error "Argument must be a natural number")))
(defun math-integer-log2 (n) ; [I I] [Public]
(and (natnump n)
diff --git a/lisp/calc/calc-ext.el b/lisp/calc/calc-ext.el
index 45337e187be..93ba8c4b6bb 100644
--- a/lisp/calc/calc-ext.el
+++ b/lisp/calc/calc-ext.el
@@ -1266,27 +1266,23 @@ calc-kill calc-kill-region calc-yank))))
(math-normalize val)))))
-(defvar calc-help-map nil)
-
-(if calc-help-map
- nil
- (setq calc-help-map (make-keymap))
- (define-key calc-help-map "b" 'calc-describe-bindings)
- (define-key calc-help-map "c" 'calc-describe-key-briefly)
- (define-key calc-help-map "f" 'calc-describe-function)
- (define-key calc-help-map "h" 'calc-full-help)
- (define-key calc-help-map "i" 'calc-info)
- (define-key calc-help-map "k" 'calc-describe-key)
- (define-key calc-help-map "n" 'calc-view-news)
- (define-key calc-help-map "s" 'calc-info-summary)
- (define-key calc-help-map "t" 'calc-tutorial)
- (define-key calc-help-map "v" 'calc-describe-variable)
- (define-key calc-help-map "\C-c" 'calc-describe-copying)
- (define-key calc-help-map "\C-d" 'calc-describe-distribution)
- (define-key calc-help-map "\C-n" 'calc-view-news)
- (define-key calc-help-map "\C-w" 'calc-describe-no-warranty)
- (define-key calc-help-map "?" 'calc-help-for-help)
- (define-key calc-help-map "\C-h" 'calc-help-for-help))
+(defvar-keymap calc-help-map
+ "b" 'calc-describe-bindings
+ "c" 'calc-describe-key-briefly
+ "f" 'calc-describe-function
+ "h" 'calc-full-help
+ "i" 'calc-info
+ "k" 'calc-describe-key
+ "n" 'calc-view-news
+ "s" 'calc-info-summary
+ "t" 'calc-tutorial
+ "v" 'calc-describe-variable
+ "C-c" 'calc-describe-copying
+ "C-d" 'calc-describe-distribution
+ "C-n" 'calc-view-news
+ "C-w" 'calc-describe-no-warranty
+ "?" 'calc-help-for-help
+ "C-h" 'calc-help-for-help)
(defvar calc-prefix-help-retry nil)
(defvar calc-prefix-help-phase 0)
@@ -3418,7 +3414,7 @@ If X is not an error form, return 1."
;;; Users can redefine this in their init files.
(defvar calc-keypad-user-menu nil
- "If non-nil, this describes an additional menu for calc-keypad.
+ "If non-nil, this describes an additional menu for `calc-keypad'.
It should contain a list of three rows.
Each row should be a list of six keys.
Each key should be a list of a label string, plus a Calc command name spec.
diff --git a/lisp/calc/calc-forms.el b/lisp/calc/calc-forms.el
index ac57011da04..ce8e3579f48 100644
--- a/lisp/calc/calc-forms.el
+++ b/lisp/calc/calc-forms.el
@@ -703,16 +703,19 @@ in the Gregorian calendar."
fmt))))
(defconst math-julian-date-beginning '(float 17214245 -1)
- "The beginning of the Julian date calendar,
-as measured in the number of days before December 31, 1 BC (Gregorian).")
+ "The beginning of the Julian date calendar.
+This is measured in the number of days before December 31, 1
+BC (Gregorian).")
(defconst math-julian-date-beginning-int 1721425
- "The beginning of the Julian date calendar,
-as measured in the integer number of days before December 31, 1 BC (Gregorian).")
+ "The beginning of the Julian date calendar.
+This is measured in the integer number of days before December
+31, 1 BC (Gregorian).")
(defconst math-unix-epoch 719163
- "The beginning of Unix time: days from December 31, 1 BC (Gregorian)
-to Jan 1, 1970 AD.")
+ "The beginning of Unix time.
+This is measured in the integer number of days from December 31,
+1 BC (Gregorian) to Jan 1, 1970 AD.")
(defun math-format-date-part (x)
(cond ((stringp x)
diff --git a/lisp/calc/calc-graph.el b/lisp/calc/calc-graph.el
index 9ac24bf1889..b6ee124a72f 100644
--- a/lisp/calc/calc-graph.el
+++ b/lisp/calc/calc-graph.el
@@ -391,6 +391,13 @@
((>= calc-gnuplot-version 3)
"dumb")
(t "postscript"))))
+ (unless (equal device calc-graph-last-device)
+ (setq calc-graph-last-device device)
+ (unless (calc-gnuplot-command "set terminal" device)
+ ;; If gnuplot doesn't support the terminal, then set it
+ ;; to "dumb".
+ (calc-gnuplot-command "set terminal dumb")
+ (setq device "dumb")))
(if (equal device "dumb")
(setq device (format "dumb %d %d"
(1- (frame-width)) (1- (frame-height)))))
@@ -404,10 +411,6 @@
(setq tempoutfile (calc-temp-file-name -1)
output tempoutfile))
(setq output (eval output t)))
- (or (equal device calc-graph-last-device)
- (progn
- (setq calc-graph-last-device device)
- (calc-gnuplot-command "set terminal" device)))
(or (equal output calc-graph-last-output)
(progn
(setq calc-graph-last-output output)
@@ -966,7 +969,8 @@ This \"dumb\" driver will be present in Gnuplot 3.0."
(define-key calc-dumb-map "\C-c\C-c" 'exit-recursive-edit)))
(use-local-map calc-dumb-map)
(setq truncate-lines t)
- (message "Type `q' or `C-c C-c' to return to Calc")
+ (message (substitute-command-keys
+ "Type \\`q' or \\`C-c C-c' to return to Calc"))
(recursive-edit)
(bury-buffer "*Gnuplot Trail*")))
@@ -1400,17 +1404,17 @@ This \"dumb\" driver will be present in Gnuplot 3.0."
(or calc-graph-no-auto-view (sit-for 0))))
(defun calc-gnuplot-check-for-errors ()
- (if (save-excursion
- (prog2
- (progn
- (set-buffer calc-gnuplot-buffer)
- (goto-char calc-gnuplot-last-error-pos))
- (re-search-forward "^[ \t]+\\^$" nil t)
- (goto-char (point-max))
- (setq calc-gnuplot-last-error-pos (point-max))))
+ (if (with-current-buffer calc-gnuplot-buffer
+ (goto-char calc-gnuplot-last-error-pos)
+ (prog1
+ (re-search-forward "^[ \t]+\\^$" nil t)
+ (goto-char (point-max))
+ (setq calc-gnuplot-last-error-pos (point-max))))
(calc-graph-view-trail)))
(defun calc-gnuplot-command (&rest args)
+ "Send ARGS to Gnuplot.
+Returns nil if Gnuplot signalled an error."
(calc-graph-init)
(let ((cmd (concat (mapconcat 'identity args " ") "\n")))
(or (calc-graph-w32-p)
@@ -1428,9 +1432,11 @@ This \"dumb\" driver will be present in Gnuplot 3.0."
(or (calc-graph-w32-p)
(accept-process-output (and (not calc-graph-no-wait)
calc-gnuplot-process)))
- (calc-gnuplot-check-for-errors)
- (if (get-buffer-window calc-gnuplot-buffer)
- (calc-graph-view-trail)))))
+ (prog1
+ ;; Return nil if we got an error.
+ (not (calc-gnuplot-check-for-errors))
+ (if (get-buffer-window calc-gnuplot-buffer)
+ (calc-graph-view-trail))))))
(defun calc-graph-init-buffers ()
(or (and calc-gnuplot-buffer
diff --git a/lisp/calc/calc-help.el b/lisp/calc/calc-help.el
index dd5063f27d5..2633d64fe42 100644
--- a/lisp/calc/calc-help.el
+++ b/lisp/calc/calc-help.el
@@ -50,25 +50,25 @@
(beep))))
(defun calc-help-for-help (arg)
- "You have typed `h', the Calc help character. Type a Help option:
+ "You have typed \\`h', the Calc help character. Type a Help option:
-B calc-describe-bindings. Display a table of all key bindings.
-H calc-full-help. Display all `?' key messages at once.
+\\`B' calc-describe-bindings. Display a table of all key bindings.
+\\`H' calc-full-help. Display all \\`?' key messages at once.
-I calc-info. Read the Calc manual using the Info system.
-T calc-tutorial. Read the Calc tutorial using the Info system.
-S calc-info-summary. Read the Calc summary using the Info system.
+\\`I' calc-info. Read the Calc manual using the Info system.
+\\`T' calc-tutorial. Read the Calc tutorial using the Info system.
+\\`S' calc-info-summary. Read the Calc summary using the Info system.
-C calc-describe-key-briefly. Look up the command name for a given key.
-K calc-describe-key. Look up a key's documentation in the manual.
-F calc-describe-function. Look up a function's documentation in the manual.
-V calc-describe-variable. Look up a variable's documentation in the manual.
+\\`C' calc-describe-key-briefly. Look up the command name for a given key.
+\\`K' calc-describe-key. Look up a key's documentation in the manual.
+\\`F' calc-describe-function. Look up a function's documentation in the manual.
+\\`V' calc-describe-variable. Look up a variable's documentation in the manual.
-N calc-view-news. Display Calc history of changes.
+\\`N' calc-view-news. Display Calc history of changes.
-C-c Describe conditions for copying Calc.
-C-d Describe how you can get a new copy of Calc or report a bug.
-C-w Describe how there is no warranty for Calc."
+\\`C-c' Describe conditions for copying Calc.
+\\`C-d' Describe how you can get a new copy of Calc or report a bug.
+\\`C-w' Describe how there is no warranty for Calc."
(interactive "P")
(if calc-dispatch-help
(let (key)
@@ -111,9 +111,6 @@ C-w Describe how there is no warranty for Calc."
(with-current-buffer "*Help*"
(let ((inhibit-read-only t))
(goto-char (point-min))
- (when (search-forward "Major Mode Bindings:" nil t)
- (delete-region (point-min) (point))
- (insert "Calc Mode Bindings:"))
(when (search-forward "Global bindings:" nil t)
(forward-line -1)
(delete-region (point) (point-max)))
diff --git a/lisp/calc/calc-map.el b/lisp/calc/calc-map.el
index 16a2bd89cac..d12d05f3055 100644
--- a/lisp/calc/calc-map.el
+++ b/lisp/calc/calc-map.el
@@ -139,7 +139,7 @@
(defvar calc-verify-arglist t)
(defun calc-map-stack ()
- "This is meant to be called by calc-keypad mode."
+ "This is meant to be called by `calc-keypad' mode."
(interactive)
(let ((calc-verify-arglist nil))
(calc-unread-command ?\$)
diff --git a/lisp/calc/calc-math.el b/lisp/calc/calc-math.el
index 1c2e7bcf2bc..ba2b6b2ca9c 100644
--- a/lisp/calc/calc-math.el
+++ b/lisp/calc/calc-math.el
@@ -618,8 +618,9 @@ If this can't be done, return NIL."
(defun math-nth-root-float (a nrf-n &optional guess)
(math-inexact-result)
(math-with-extra-prec 1
- (let ((math-nrf-nf (math-float nrf-n))
- (math-nrf-nfm1 (math-float (1- nrf-n))))
+ (let ((math-nrf-n nrf-n)
+ (math-nrf-nf (math-float nrf-n))
+ (math-nrf-nfm1 (math-float (1- nrf-n))))
(math-nth-root-float-iter a (or guess
(math-make-float
1 (/ (+ (math-numdigs (nth 1 a))
diff --git a/lisp/calc/calc-menu.el b/lisp/calc/calc-menu.el
index 516f62d7b63..eed20a89a47 100644
--- a/lisp/calc/calc-menu.el
+++ b/lisp/calc/calc-menu.el
@@ -19,6 +19,8 @@
;;; Commentary:
+;;; Code:
+
(defvar calc-arithmetic-menu
(list "Arithmetic"
(list "Basic"
diff --git a/lisp/calc/calc-misc.el b/lisp/calc/calc-misc.el
index b573c53f418..1c4438e7f7a 100644
--- a/lisp/calc/calc-misc.el
+++ b/lisp/calc/calc-misc.el
@@ -102,8 +102,7 @@ Miscellaneous:
0 (zero) calc-reset. Reset Calc stack and modes to default state.
Press `*' twice (`C-x * *') to turn Calc on or off using the same
-Calc user interface as before (either C-x * C or C-x * K; initially C-x * C).
-"
+Calc user interface as before (either C-x * C or C-x * K; initially C-x * C)."
(interactive "P")
(calc-check-defines)
(if calc-dispatch-help
@@ -217,26 +216,28 @@ Calc user interface as before (either C-x * C or C-x * K; initially C-x * C).
(defun calc-help ()
(interactive)
(let ((msgs
- '("Press `h' for complete help; press `?' repeatedly for a summary"
- "Letter keys: Negate; Precision; Yank; Why; Xtended cmd; Quit"
- "Letter keys: SHIFT + Undo, reDo; Inverse, Hyperbolic, Option"
- "Letter keys: SHIFT + sQrt; Sin, Cos, Tan; Exp, Ln, logB"
- "Letter keys: SHIFT + Floor, Round; Abs, conJ, arG; Pi"
- "Letter keys: SHIFT + Num-eval; More-recn; eXec-kbd-macro; Keep-args"
- "Other keys: +, -, *, /, ^, \\ (int div), : (frac div)"
- "Other keys: & (1/x), | (concat), % (modulo), ! (factorial)"
- "Other keys: \\=' (alg-entry), = (eval), \\=` (edit); M-RET (last-args)"
- "Other keys: SPC/RET (enter/dup), LFD (over); < > (scroll horiz)"
- "Other keys: DEL (drop), M-DEL (drop-above); { } (scroll vert)"
- "Other keys: TAB (swap/roll-dn), M-TAB (roll-up)"
- "Other keys: [ , ; ] (vector), ( , ) (complex), ( ; ) (polar)"
- "Prefix keys: Algebra, Binary/business, Convert, Display"
- "Prefix keys: Functions, Graphics, Help, J (select)"
- "Prefix keys: Kombinatorics/statistics, Modes, Store/recall"
- "Prefix keys: Trail/time, Units/statistics, Vector/matrix"
- "Prefix keys: Z (user), SHIFT + Z (define)"
- "Prefix keys: prefix + ? gives further help for that prefix"
- " Calc by Dave Gillespie, daveg@synaptics.com")))
+ ;; FIXME: Change these to `substitute-command-keys' syntax.
+ (mapcar #'substitute-command-keys
+ '("Press \\`h' for complete help; press \\`?' repeatedly for a summary"
+ "Letter keys: Negate; Precision; Yank; Why; Xtended cmd; Quit"
+ "Letter keys: SHIFT + Undo, reDo; Inverse, Hyperbolic, Option"
+ "Letter keys: SHIFT + sQrt; Sin, Cos, Tan; Exp, Ln, logB"
+ "Letter keys: SHIFT + Floor, Round; Abs, conJ, arG; Pi"
+ "Letter keys: SHIFT + Num-eval; More-recn; eXec-kbd-macro; Keep-args"
+ "Other keys: +, -, *, /, ^, \\ (int div), : (frac div)"
+ "Other keys: & (1/x), | (concat), % (modulo), ! (factorial)"
+ "Other keys: \\=' (alg-entry), = (eval), \\=` (edit); M-RET (last-args)"
+ "Other keys: \\`SPC'/\\`RET' (enter/dup), LFD (over); < > (scroll horiz)"
+ "Other keys: \\`DEL' (drop), \\`M-DEL' (drop-above); { } (scroll vert)"
+ "Other keys: \\`TAB' (swap/roll-dn), \\`M-TAB' (roll-up)"
+ "Other keys: [ , ; ] (vector), ( , ) (complex), ( ; ) (polar)"
+ "Prefix keys: Algebra, Binary/business, Convert, Display"
+ "Prefix keys: Functions, Graphics, Help, J (select)"
+ "Prefix keys: Kombinatorics/statistics, Modes, Store/recall"
+ "Prefix keys: Trail/time, Units/statistics, Vector/matrix"
+ "Prefix keys: Z (user), SHIFT + Z (define)"
+ "Prefix keys: prefix + ? gives further help for that prefix"
+ " Calc by Dave Gillespie, daveg@synaptics.com"))))
(if calc-full-help-flag
msgs
(if (or calc-inverse-flag calc-hyperbolic-flag)
diff --git a/lisp/calc/calc-mode.el b/lisp/calc/calc-mode.el
index 68c8b90ac3b..211b8e661fd 100644
--- a/lisp/calc/calc-mode.el
+++ b/lisp/calc/calc-mode.el
@@ -109,11 +109,14 @@
(setq n (and (not (eq calc-auto-why t)) (if calc-auto-why t 1))))
(calc-change-mode 'calc-auto-why n nil)
(cond ((null n)
- (message "User must press `w' to explain unsimplified results"))
+ (message (substitute-command-keys
+ "User must press \\`w' to explain unsimplified results")))
((eq n t)
- (message "Automatically doing `w' to explain unsimplified results"))
+ (message (substitute-command-keys
+ "Automatically doing \\`w' to explain unsimplified results")))
(t
- (message "Automatically doing `w' only for unusual messages")))))
+ (message (substitute-command-keys
+ "Automatically doing \\`w' only for unusual messages"))))))
(defun calc-group-digits (n)
(interactive "P")
diff --git a/lisp/calc/calc-poly.el b/lisp/calc/calc-poly.el
index 77587cc4b86..5d74a8f106b 100644
--- a/lisp/calc/calc-poly.el
+++ b/lisp/calc/calc-poly.el
@@ -454,7 +454,7 @@ This returns only the remainder from the pseudo-division."
(defun math-atomic-factorp (expr)
- "Return true if is a factor containing no sums or quotients."
+ "Return non-nil if is a factor containing no sums or quotients."
(cond ((eq (car-safe expr) '*)
(and (math-atomic-factorp (nth 1 expr))
(math-atomic-factorp (nth 2 expr))))
diff --git a/lisp/calc/calc-prog.el b/lisp/calc/calc-prog.el
index f9dd9eb98a9..b381f8afcf9 100644
--- a/lisp/calc/calc-prog.el
+++ b/lisp/calc/calc-prog.el
@@ -124,7 +124,7 @@
(or (memq (car-safe (car-safe place)) '(error xxxerror))
(setq place (aref (nth 2 (nth 2 (symbol-function 'calc-do))) 27)))
(or (memq (car (car place)) '(error xxxerror))
- (error "foo"))
+ (error "Foo"))
(setcar (car place) 'xxxerror))
(error (error "The calc-do function has been modified; unable to patch"))))
@@ -205,9 +205,8 @@
(progn
(setq cmd-base-default (concat "User-" keyname))
(setq cmd (completing-read
- (concat "Define M-x command name (default calc-"
- cmd-base-default
- "): ")
+ (format-prompt "Define M-x command name"
+ (concat "calc-" cmd-base-default))
obarray 'commandp nil
(if (and odef (symbolp (cdr odef)))
(symbol-name (cdr odef))
@@ -241,8 +240,8 @@
(setq func
(concat "calcFunc-"
(completing-read
- (concat "Define algebraic function name (default "
- cmd-base-default "): ")
+ (format-prompt "Define algebraic function name"
+ cmd-base-default)
(mapcar (lambda (x) (substring x 9))
(all-completions "calcFunc-"
obarray))
diff --git a/lisp/calc/calc-store.el b/lisp/calc/calc-store.el
index ee29c440fe4..817b50951dd 100644
--- a/lisp/calc/calc-store.el
+++ b/lisp/calc/calc-store.el
@@ -163,19 +163,19 @@
tag (and (not val) 1))
(message "Variable \"%s\" changed" (calc-var-name var)))))))
-(defvar calc-var-name-map nil "Keymap for reading Calc variable names.")
-(if calc-var-name-map
- ()
- (setq calc-var-name-map (copy-keymap minibuffer-local-completion-map))
- (define-key calc-var-name-map " " 'self-insert-command)
- (mapc (lambda (x)
- (define-key calc-var-name-map (char-to-string x)
- 'calcVar-digit))
- "0123456789")
- (mapc (lambda (x)
- (define-key calc-var-name-map (char-to-string x)
- 'calcVar-oper))
- "+-*/^|"))
+(defvar calc-var-name-map
+ (let ((map (copy-keymap minibuffer-local-completion-map)))
+ (define-key map " " #'self-insert-command)
+ (mapc (lambda (x)
+ (define-key map (char-to-string x)
+ #'calcVar-digit))
+ "0123456789")
+ (mapc (lambda (x)
+ (define-key map (char-to-string x)
+ #'calcVar-oper))
+ "+-*/^|")
+ map)
+ "Keymap for reading Calc variable names.")
(defvar calc-store-opers)
@@ -188,12 +188,15 @@
(let* ((calc-store-opers store-opers)
(var (concat
"var-"
- (let ((minibuffer-completion-table
- (mapcar (lambda (x) (substring x 4))
- (all-completions "var-" obarray)))
- (minibuffer-completion-predicate
- (lambda (x) (boundp (intern (concat "var-" x)))))
- (minibuffer-completion-confirm t))
+ (minibuffer-with-setup-hook
+ (lambda ()
+ (setq-local minibuffer-completion-table
+ (mapcar (lambda (x) (substring x 4))
+ (all-completions "var-" obarray)))
+ (setq-local minibuffer-completion-predicate
+ (lambda (x)
+ (boundp (intern (concat "var-" x)))))
+ (setq-local minibuffer-completion-confirm t))
(read-from-minibuffer
prompt nil calc-var-name-map nil
'calc-read-var-name-history)))))
@@ -586,7 +589,7 @@
(defun calc-permanent-variable (&optional var)
(interactive)
(calc-wrapper
- (or var (setq var (calc-read-var-name "Save variable (default all): ")))
+ (or var (setq var (calc-read-var-name (format-prompt "Save variable" "all"))))
(let (calc-pv-pos)
(and var (or (and (boundp var) (symbol-value var))
(error "No such variable")))
diff --git a/lisp/calc/calc-units.el b/lisp/calc/calc-units.el
index 8b6f0637035..f6d749db117 100644
--- a/lisp/calc/calc-units.el
+++ b/lisp/calc/calc-units.el
@@ -486,18 +486,13 @@ If COMP or STD is non-nil, put that in the units table instead."
(setq defunits (math-get-default-units expr))
(unless new-units
(setq new-units
- (read-string (concat
+ (read-string (format-prompt
(if (and uoldname (not nouold))
(concat "Old units: "
uoldname
", new units")
"New units")
- (if defunits
- (concat
- " (default "
- defunits
- "): ")
- ": "))))
+ defunits)))
(if (and
(string= new-units "")
defunits)
@@ -529,18 +524,11 @@ If COMP or STD is non-nil, put that in the units table instead."
(calc-slow-wrapper
(let* ((expr (calc-top-n 1)))
(unless (math-units-in-expr-p expr t)
- (error "No units in expression."))
+ (error "No units in expression"))
(let* ((old-units (math-extract-units expr))
(defunits (math-get-default-units expr))
units
- (new-units
- (read-string (concat "New units"
- (if defunits
- (concat
- " (default "
- defunits
- "): ")
- ": ")))))
+ (new-units (read-string (format-prompt "New units" defunits))))
(if (and
(string= new-units "")
defunits)
@@ -596,19 +584,14 @@ If COMP or STD is non-nil, put that in the units table instead."
(setq expr (math-mul expr uold)))
(setq defunits (math-get-default-units expr))
(setq unew (or new-units
- (completing-read
- (concat
- (if uoldname
- (concat "Old temperature units: "
- uoldname
- ", new units")
- "New temperature units")
- (if defunits
- (concat " (default "
- defunits
- "): ")
- ": "))
- tempunits)))
+ (completing-read (format-prompt
+ (if uoldname
+ (concat "Old temperature units: "
+ uoldname
+ ", new units")
+ "New temperature units")
+ defunits)
+ tempunits)))
(setq unew (math-read-expr (if (string= unew "") defunits unew)))
(when (eq (car-safe unew) 'error)
(error "Bad format in units expression: %s" (nth 2 unew)))
diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
index a10b3178302..d426e2829f8 100644
--- a/lisp/calc/calc.el
+++ b/lisp/calc/calc.el
@@ -139,6 +139,7 @@
;;; Code:
(require 'calc-macs)
+(require 'rect)
;; Declare functions which are defined elsewhere.
(declare-function calc-set-language "calc-lang" (lang &optional option no-refresh))
@@ -251,7 +252,7 @@
(defcustom calc-embedded-announce-formula
"%Embed\n\\(% .*\n\\)*"
- "A regular expression which is sure to be followed by a calc-embedded formula."
+ "A regular expression which is sure to be followed by a `calc-embedded' formula."
:type '(regexp))
(defcustom calc-embedded-announce-formula-alist
@@ -277,12 +278,12 @@
(defcustom calc-embedded-close-formula
"\\'\\|\n$\\|\\$\\$?\\|\\\\]\\|^\\\\end[^{].*\n\\|^\\\\end{.*[^x]}.*\n\\|^@.*\n\\|^\\.EN.*\n\\|\\\\)\\|\n%\n\\|^\\.\\\\\"\n"
- "Regexp for the closing delimiter of a formula used by calc-embedded."
+ "Regexp for the closing delimiter of a formula used by `calc-embedded'."
:type '(regexp))
(defcustom calc-embedded-open-close-formula-alist
nil
- "Alist of major modes with pairs of formula delimiters used by calc-embedded."
+ "Alist of major modes with pairs of formula delimiters used by `calc-embedded'."
:type '(alist :key-type (symbol :tag "Major mode")
:value-type (list (regexp :tag "Opening formula delimiter")
(regexp :tag "Closing formula delimiter"))))
@@ -347,13 +348,13 @@ See calc-embedded-open-plain."
(defcustom calc-embedded-open-mode
"% "
- "A string which should precede calc-embedded mode annotations.
+ "A string which should precede `calc-embedded' mode annotations.
This is not required to be present for user-written mode annotations."
:type '(string))
(defcustom calc-embedded-close-mode
"\n"
- "A string which should follow calc-embedded mode annotations.
+ "A string which should follow `calc-embedded' mode annotations.
This is not required to be present for user-written mode annotations."
:type '(string))
@@ -386,43 +387,34 @@ This is not required to be present for user-written mode annotations."
:type '(string)
:version "26.2")
-(defcustom calc-gnuplot-plot-command
- nil
+(defcustom calc-gnuplot-plot-command nil
"Name of command for displaying GNUPLOT output; %s = file name to print."
:type '(choice (string) (sexp)))
-(defcustom calc-gnuplot-print-command
- "lp %s"
+(defcustom calc-gnuplot-print-command "lp %s"
"Name of command for printing GNUPLOT output; %s = file name to print."
:type '(choice (string) (sexp)))
-(defcustom calc-multiplication-has-precedence
- t
- "If non-nil, multiplication has precedence over division
-in normal mode."
+(defcustom calc-multiplication-has-precedence t
+ "If non-nil, multiplication has precedence over division in normal mode."
:type 'boolean)
-(defcustom calc-ensure-consistent-units
- nil
- "If non-nil, make sure new units are consistent with current units
-when converting units."
+(defcustom calc-ensure-consistent-units nil
+ "If non-nil, ensure new units are consistent with current units when converting."
:version "24.3"
:type 'boolean)
-(defcustom calc-context-sensitive-enter
- nil
+(defcustom calc-context-sensitive-enter nil
"If non-nil, the stack element under the cursor will be copied by `calc-enter'
and deleted by `calc-pop'."
:version "24.4"
:type 'boolean)
-(defcustom calc-undo-length
- 100
+(defcustom calc-undo-length 100
"The number of undo steps that will be preserved when Calc is quit."
:type 'integer)
-(defcustom calc-highlight-selections-with-faces
- nil
+(defcustom calc-highlight-selections-with-faces nil
"If non-nil, use a separate face to indicate selected sub-formulas.
If option `calc-show-selections' is non-nil, then selected sub-formulas are
shown by displaying the rest of the formula in `calc-nonselected-face'.
@@ -431,14 +423,12 @@ by displaying the sub-formula in `calc-selected-face'."
:version "24.1"
:type 'boolean)
-(defcustom calc-lu-field-reference
- "20 uPa"
+(defcustom calc-lu-field-reference "20 uPa"
"The default reference level for logarithmic units (field)."
:version "24.1"
:type '(string))
-(defcustom calc-lu-power-reference
- "mW"
+(defcustom calc-lu-power-reference "mW"
"The default reference level for logarithmic units (power)."
:version "24.1"
:type '(string))
@@ -477,11 +467,11 @@ This is 1 unless `calc-truncate-stack' has been used.")
(defvar calc-display-sci-high 0
"Floating-point numbers with this positive exponent or higher above the
-current precision are displayed in scientific notation in calc-mode.")
+current precision are displayed in scientific notation in `calc-mode'.")
(defvar calc-display-sci-low -3
"Floating-point numbers with this negative exponent or lower are displayed
-scientific notation in calc-mode.")
+scientific notation in `calc-mode'.")
(defvar calc-digit-after-point nil
"If t, display at least one digit after the decimal point, as in `12.0'.
@@ -495,16 +485,16 @@ This setting only applies to floats in normal display mode.")
"List of strings for Y prefix help.")
(defvar calc-loaded-settings-file nil
- "t if `calc-settings-file' has been loaded yet.")
+ "Return t if `calc-settings-file' has been loaded yet.")
(defvar calc-mode-var-list '()
"List of variables used in customizing GNU Calc.")
(defmacro defcalcmodevar (var defval &optional doc)
- "Declare VAR as a Calc variable, with default value DEFVAL
-and doc-string DOC.
+ "Declare VAR as a Calc variable, with default value DEFVAL and doc-string DOC.
The variable VAR will be added to `calc-mode-var-list'."
+ (declare (doc-string 3) (indent defun))
`(progn
(defvar ,var ,defval ,doc)
(add-to-list 'calc-mode-var-list (list (quote ,var) ,defval))))
@@ -742,7 +732,7 @@ If nil, symbolic math routines make no assumptions about variables.")
"Initial height of Calculator window.")
(defcalcmodevar calc-display-trail t
- "If non-nil, M-x calc creates a window to display Calculator trail.")
+ "If non-nil, \\[calc] creates a window to display Calculator trail.")
(defcalcmodevar calc-show-selections t
"If non-nil, selected sub-formulas are shown by obscuring rest of formula.
@@ -921,7 +911,7 @@ Used by `calc-user-invocation'.")
(defvar calc-trail-pointer nil
"The \"current\" entry in trail buffer.")
(defvar calc-trail-overlay nil
- "The value of overlay-arrow-string.")
+ "The value of `overlay-arrow-string'.")
(defvar calc-undo-list nil
"The list of previous operations for undo.")
(defvar calc-redo-list nil
@@ -960,7 +950,7 @@ Used by `calc-user-invocation'.")
(defvar calc-lang-allow-percentsigns nil
"A list of languages which allow percent signs in variable names.")
(defvar calc-lang-c-type-hex nil
- "Languages in which octal and hex numbers are written with leading 0 and 0x,")
+ "Languages in which octal and hex numbers are written with leading 0 and 0x.")
(defvar calc-lang-brackets-are-subscripts nil
"Languages in which subscripts are indicated by brackets.")
(defvar calc-lang-parens-are-subscripts nil
@@ -1310,8 +1300,7 @@ Notations: 3.14e6 3.14 * 10^6
<1 jan 91> Date form (enter using \\=' key)
-\\{calc-mode-map}
-"
+\\{calc-mode-map}"
(interactive)
(mapc (lambda (v)
;; FIXME: Why (set-default v (symbol-value v)) ?!?!?
@@ -1382,12 +1371,12 @@ Notations: 3.14e6 3.14 * 10^6
map))
(defun calc--header-line (long short width &optional fudge)
- "Return a Calc header line appropriate for the buffer width.
+ "Return a Calc header line appropriate for the buffer WIDTH.
LONG is a desired text for a wide window, SHORT is a desired
abbreviated text, and width is the buffer width, which will be
some fraction of the 'parent' window width (At the time of
-writing, 2/3 for calc, 1/3 for trail). The optional FUDGE is a
+writing, 2/3 for calc, 1/3 for trail). The optional FUDGE is a
trial-and-error adjustment number for the edge-cases at the
border of the two cases."
;; TODO: This could be called as part of a 'window-resize' hook.
@@ -1409,7 +1398,7 @@ border of the two cases."
This mode is used by the *Calc Trail* buffer, which records all results
obtained by the GNU Emacs Calculator.
-Calculator commands beginning with the `t' key are used to manipulate
+Calculator commands beginning with the t key are used to manipulate
the Trail.
This buffer uses the same key map as the *Calculator* buffer; calculator
@@ -1434,7 +1423,7 @@ commands given here will actually operate on the *Calculator* stack."
(require 'calc-ext)
(calc-set-language calc-language calc-language-option t)))
-(defcustom calc-make-windows-dedicated t
+(defcustom calc-make-windows-dedicated nil
"If non-nil, windows displaying Calc buffers will be marked dedicated.
See `window-dedicated-p' for what that means."
:version "28.1"
@@ -1480,7 +1469,9 @@ See `window-dedicated-p' for what that means."
(with-current-buffer (calc-trail-buffer)
(and calc-display-trail
(calc-trail-display 1 t)))
- (message "Welcome to the GNU Emacs Calculator! Press `?' or `h' for help, `q' to quit")
+ (message (substitute-command-keys
+ (concat "Welcome to the GNU Emacs Calculator! \\<calc-mode-map>"
+ "Press \\[calc-help] or \\[calc-help-prefix] for help, \\[calc-quit] to quit")))
(run-hooks 'calc-start-hook)
(and (windowp full-display)
(window-point full-display)
@@ -1500,7 +1491,7 @@ See `window-dedicated-p' for what that means."
(calc nil t interactive))
(defun calc-same-interface (arg)
- "Invoke the Calculator using the most recent interface (calc or calc-keypad)."
+ "Invoke the Calculator using the most recent interface (`calc' or `calc-keypad')."
(interactive "P")
(if (and (equal (buffer-name) "*Gnuplot Trail*")
(> (recursion-depth) 0))
@@ -1577,7 +1568,7 @@ or a list containing a character position and an error message in string form."
"Invoke the Calculator in \"visual keypad\" mode.
This is most useful in the X window system.
In this mode, click on the Calc \"buttons\" using the left mouse button.
-Or, position the cursor manually and do M-x calc-keypad-press."
+Or, position the cursor manually and do \\[calc-keypad-press]."
(interactive "p")
(require 'calc-ext)
(calc-do-keypad calc-full-mode interactive))
@@ -1630,7 +1621,8 @@ See calc-keypad for details."
(stringp (nth 1 err))
(string-match "max-specpdl-size\\|max-lisp-eval-depth"
(nth 1 err)))
- (error "Computation got stuck or ran too long. Type `M' to increase the limit")
+ (error (substitute-command-keys
+ "Computation got stuck or ran too long. Type \\`M' to increase the limit"))
(setq calc-aborted-prefix nil)
(signal (car err) (cdr err)))))
(when calc-aborted-prefix
@@ -3388,7 +3380,9 @@ and all digits are kept, regardless of Calc's current precision."
"Parse the region as a vector of numbers and push it on the Calculator stack."
(interactive "r\nP")
(require 'calc-ext)
- (calc-do-grab-region top bot arg))
+ (if rectangle-mark-mode
+ (calc-do-grab-rectangle top bot arg)
+ (calc-do-grab-region top bot arg)))
;;;###autoload
(defun calc-grab-rectangle (top bot arg)
@@ -3397,12 +3391,14 @@ and all digits are kept, regardless of Calc's current precision."
(require 'calc-ext)
(calc-do-grab-rectangle top bot arg))
+;;;###autoload
(defun calc-grab-sum-down (top bot arg)
"Parse a rectangle as a matrix of numbers and sum its columns."
(interactive "r\nP")
(require 'calc-ext)
(calc-do-grab-rectangle top bot arg 'calcFunc-reduced))
+;;;###autoload
(defun calc-grab-sum-across (top bot arg)
"Parse a rectangle as a matrix of numbers and sum its rows."
(interactive "r\nP")
@@ -3444,7 +3440,7 @@ The prefix `calcFunc-' is added to the specified name to get the
actual Lisp function name.
See Info node `(calc)Defining Functions'."
- (declare (doc-string 3)) ;; FIXME: Edebug spec?
+ (declare (doc-string 3) (indent defun)) ;; FIXME: Edebug spec?
(require 'calc-ext)
(math-do-defmath func args body))
diff --git a/lisp/calc/calcalg3.el b/lisp/calc/calcalg3.el
index 3cb1886f3bd..a61cdb5d0e6 100644
--- a/lisp/calc/calcalg3.el
+++ b/lisp/calc/calcalg3.el
@@ -1484,7 +1484,7 @@
h (cdr h)))
(setq curh (math-div-float curh '(float 9 0))))
ss
- (math-reject-arg nil (format "*Integral failed to converge"))))))
+ (math-reject-arg nil "*Integral failed to converge")))))
(defun math-ninteg-evaluate (expr x mode)
diff --git a/lisp/calculator.el b/lisp/calculator.el
index 99c9b6290c4..0c255c0cf9d 100644
--- a/lisp/calculator.el
+++ b/lisp/calculator.el
@@ -593,15 +593,15 @@ except when using a non-decimal radix mode for input (in this case `e'
will be the hexadecimal digit).
Here are the editing keys:
-* `RET' `=' evaluate the current expression
-* `C-insert' copy the whole current expression to the `kill-ring'
-* `C-return' evaluate, save result the `kill-ring' and exit
-* `insert' paste a number if the one was copied (normally)
-* `delete' `C-d' clear last argument or whole expression (hit twice)
-* `backspace' delete a digit or a previous expression element
-* `h' `?' pop-up a quick reference help
-* `ESC' `q' exit (`ESC' can be used if `calculator-bind-escape' is
- non-nil, otherwise use three consecutive `ESC's)
+* \\`RET' \\`=' evaluate the current expression
+* \\`C-<insert>' copy the whole current expression to the `kill-ring'
+* \\`C-<return>' evaluate, save result the `kill-ring' and exit
+* \\`<insert>' paste a number if the one was copied (normally)
+* \\`<delete>' \\`C-d' clear last argument or whole expression (hit twice)
+* \\`<backspace>' delete a digit or a previous expression element
+* \\`h' \\`?' pop-up a quick reference help
+* \\`ESC' \\`q' exit (\\`ESC' can be used if `calculator-bind-escape' is
+ non-nil, otherwise use three consecutive \\`ESC's)
These operators are pre-defined:
* `+' `-' `*' `/' the common binary operators
@@ -623,10 +623,10 @@ argument.
hex/oct/bin modes can be set for input and for display separately.
Another toggle-able mode is for using degrees instead of radians for
trigonometric functions.
-The keys to switch modes are (both `H' and `X' are for hex):
-* `D' switch to all-decimal mode, or toggle degrees/radians
-* `B' `O' `H' `X' binary/octal/hexadecimal modes for input & display
-* `i' `o' followed by one of `D' `B' `O' `H' `X' (case
+The keys to switch modes are (both \\`H' and \\`X' are for hex):
+* \\`D' switch to all-decimal mode, or toggle degrees/radians
+* \\`B' \\`O' \\`H' \\`X' binary/octal/hexadecimal modes for input & display
+* \\`i' \\`o' followed by one of \\`D' \\`B' \\`O' \\`H' \\`X' (case
insensitive) sets only the input or display radix mode
The prompt indicates the current modes:
* \"==\": decimal mode (using radians);
@@ -649,17 +649,17 @@ collected data. It is possible to navigate in this list, and if the
value shown is the current one on the list, an indication is displayed
as \"[N]\" if this is the last number and there are N numbers, or
\"[M/N]\" if the M-th value is shown.
-* `SPC' evaluate the current value as usual, but also adds
+* \\`SPC' evaluate the current value as usual, but also adds
the result to the list of saved values
-* `l' `v' computes total / average of saved values
-* `up' `C-p' browse to the previous value in the list
-* `down' `C-n' browse to the next value in the list
-* `delete' `C-d' remove current value from the list (if it is on it)
-* `C-delete' `C-c' delete the whole list
+* \\`l' \\`v' computes total / average of saved values
+* \\`<up>' \\`C-p' browse to the previous value in the list
+* \\`<down>' \\`C-n' browse to the next value in the list
+* \\`<delete>' \\`C-d' remove current value from the list (if it is on it)
+* \\`C-<delete>' \\`C-c' delete the whole list
Registers are variable-like place-holders for values:
-* `s' followed by a character attach the current value to that character
-* `g' followed by a character fetches the attached value
+* \\`s' followed by a character attach the current value to that character
+* \\`g' followed by a character fetches the attached value
There are many variables that can be used to customize the calculator.
Some interesting customization variables are:
@@ -833,8 +833,7 @@ The result should not exceed the screen width."
(concat prompt (if (<= trim 0) expr (substring expr trim)))))
(defun calculator-string-to-number (str)
- "Convert the given STR to a number, according to the value of
-`calculator-input-radix'."
+ "Convert STR to number according to `calculator-input-radix'."
(if calculator-input-radix
(string-to-number str (cadr (assq calculator-input-radix
'((bin 2) (oct 8) (hex 16)))))
@@ -1171,9 +1170,9 @@ arguments."
;;; Input interaction
(defun calculator-last-input (&optional keys)
- "Return the last key sequence that was used to invoke this command, or
-the input KEYS. Uses the `function-key-map' translate keypad numbers to
-plain ones."
+ "Return the last key sequence used to invoke this command, or the input KEYS.
+Uses the `function-key-map' translate keypad numbers to plain
+ones."
(let* ((inp (or keys (this-command-keys)))
(inp (or (and (arrayp inp) (not (stringp inp))
(lookup-key function-key-map inp))
@@ -1475,8 +1474,7 @@ a multiplication."
(calculator-put-value (calculator-string-to-number str)))))
(defun calculator-register-read-with-preview (prompt)
- "Similar to `register-read-with-preview' but for calculator
-registers."
+ "Similar to `register-read-with-preview' but for calculator registers."
(let ((register-alist calculator-registers)
(register-preview-delay 1)
(register-preview-function
diff --git a/lisp/calendar/cal-tex.el b/lisp/calendar/cal-tex.el
index 7b55d420c3b..c5b456c4c23 100644
--- a/lisp/calendar/cal-tex.el
+++ b/lisp/calendar/cal-tex.el
@@ -263,7 +263,7 @@ Optional string ARGS are included as options for the article
document class with inclusion of default values \"12pt\" for
size, and \"a4paper\" for paper unless size or paper are already
specified in ARGS. When ARGS is omitted, by default the option
-\"12pt,a4paper\" is passed. When ARGS has any other value, then
+\"12pt,a4paper\" is passed. When ARGS has any other value, then
no option is passed to the class.
Insert the \"\\usepackage{geometry}\" directive when ARGS
@@ -1648,10 +1648,10 @@ informative header, and run HOOK."
(goto-char (point-min))
;; FIXME auctex equivalents?
(cal-tex-comment
- (format "\tThis buffer was produced by cal-tex.el.
+ "\tThis buffer was produced by cal-tex.el.
\tTo print a calendar, type
\t\tM-x tex-buffer RET
-\t\tM-x tex-print RET")))
+\t\tM-x tex-print RET"))
(defun cal-tex-insert-preamble (weeks &optional class-options append)
"Initialize the output LaTeX calendar buffer, `cal-tex-buffer'.
diff --git a/lisp/calendar/calendar.el b/lisp/calendar/calendar.el
index 76d6132eae1..e06239a5c87 100644
--- a/lisp/calendar/calendar.el
+++ b/lisp/calendar/calendar.el
@@ -119,11 +119,11 @@
;; Calendar has historically relied heavily on dynamic scoping.
;; Concretely, this manifests in the use of references to let-bound variables
;; in Custom vars as well as code in diary files.
-;; `eval` is hence the core of the culprit. It's used on:
+;; 'eval' is hence the core of the culprit. It's used on:
;; - calendar-date-display-form
;; - calendar-time-display-form
;; - calendar-chinese-time-zone
-;; - in cal-dst's there are various calls to `eval' but they seem not to refer
+;; - in cal-dst's there are various calls to 'eval' but they seem not to refer
;; to let-bound variables, surprisingly.
;; - calendar-date-echo-text
;; - calendar-mode-line-format
@@ -1308,7 +1308,9 @@ This function is suitable for execution in an init file."
;; Avoid loading cal-x unless it will be used.
(if (and (memq calendar-setup '(one-frame two-frames calendar-only))
(display-multi-frame-p))
- (calendar-frame-setup calendar-setup arg)
+ ;; Calendar does its own frame setup.
+ (let ((pop-up-frames nil))
+ (calendar-frame-setup calendar-setup arg))
(calendar-basic-setup arg)))
(defun calendar-basic-setup (&optional arg nodisplay)
@@ -1721,7 +1723,8 @@ COMMAND is a command to run, ECHO is the help-echo text, KEY
is COMMAND's keybinding, STRING describes the binding."
(propertize (or key
(substitute-command-keys
- (format "\\<calendar-mode-map>\\[%s] %s" command string)))
+ (format "\\<calendar-mode-map>\\[%s] %s" command string)
+ 'hands-off-my-face))
'help-echo (format "mouse-1: %s" echo)
'mouse-face 'mode-line-highlight
'keymap (make-mode-line-mouse-map 'mouse-1 command)))
diff --git a/lisp/calendar/diary-lib.el b/lisp/calendar/diary-lib.el
index f57fe26058f..2eb7977a164 100644
--- a/lisp/calendar/diary-lib.el
+++ b/lisp/calendar/diary-lib.el
@@ -1223,8 +1223,7 @@ ensure that all relevant variables are set.
\(diary-mail-entries)
-# diary-rem.el ends here
-"
+# diary-rem.el ends here"
(interactive "P")
(if (string-equal diary-mail-addr "")
(user-error "You must set `diary-mail-addr' to use this command")
@@ -1254,10 +1253,10 @@ the regexp with parentheses."
paren))
(defvar diary-marking-entries-flag nil
- "True during the marking of diary entries, nil otherwise.")
+ "Non-nil during the marking of diary entries, nil otherwise.")
(defvar diary-marking-entry-flag nil
- "True during the marking of diary entries, if current entry is marking.")
+ "Non-nil during the marking of diary entries, if current entry is marking.")
;; file-glob-attrs bound in diary-mark-entries.
(defun diary-mark-entries-1 (markfunc &optional months symbol absfunc)
@@ -2014,6 +2013,17 @@ string to use when highlighting the day in the calendar."
(and (>= diff 0) (zerop (% diff n))
(cons mark (format entry cycle (diary-ordinal-suffix cycle))))))
+;; To be called from diary-sexp-entry, where DATE, ENTRY are bound.
+(defun diary-offset (sexp days)
+ "Offsetted diary entry. Offsets SEXP by DAYS days.
+Entry applies if the date is DAYS days after another diary-sexp SEXP."
+ (with-no-warnings (defvar date))
+ (unless (integerp days)
+ (user-error "Days must be an integer"))
+ (let ((date (calendar-gregorian-from-absolute
+ (- (calendar-absolute-from-gregorian date) days))))
+ (eval sexp)))
+
(defun diary-day-of-year ()
"Day of year and number of days remaining in the year of date diary entry."
(with-no-warnings (defvar date))
diff --git a/lisp/calendar/holidays.el b/lisp/calendar/holidays.el
index 3eae2dcc7f1..bda5dc5a6bb 100644
--- a/lisp/calendar/holidays.el
+++ b/lisp/calendar/holidays.el
@@ -482,7 +482,7 @@ The optional LABEL is used to label the buffer created."
(calendar-increment-month displayed-month displayed-year 3)
(setq s (calendar-absolute-from-gregorian
(list displayed-month 1 displayed-year))))
- (save-excursion
+ (save-current-buffer
(calendar-in-read-only-buffer holiday-buffer
(calendar-set-mode-line
(if (= y1 y2)
diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el
index eaee2e9d951..15778ea14bc 100644
--- a/lisp/calendar/icalendar.el
+++ b/lisp/calendar/icalendar.el
@@ -644,13 +644,13 @@ FIXME: multiple comma-separated values should be allowed!"
;; seconds present
(setq second (read (substring isodatetimestring 13 15))))
;; FIXME: Support subseconds.
- (when (and (> (length isodatetimestring) 15)
- ;; UTC specifier present
- (char-equal ?Z (aref isodatetimestring 15)))
- (setq source-zone t
- ;; decode to local time unless result-zone is explicitly given,
- ;; i.e. do not decode to UTC, i.e. do not (setq result-zone t)
- ))
+ (when (> (length isodatetimestring) 15)
+ (pcase (aref isodatetimestring 15)
+ (?Z
+ (setq source-zone t))
+ ((or ?- ?+)
+ (setq source-zone
+ (concat "UTC" (substring isodatetimestring 15))))))
;; shift if necessary
(if day-shift
(let ((mdy (calendar-gregorian-from-absolute
@@ -1749,7 +1749,7 @@ entries. ENTRY-MAIN is the first line of the diary entry."
(defun icalendar--convert-float-to-ical (nonmarker entry-main)
"Convert float diary entry to iCalendar format -- partially unsupported!
- FIXME! DAY from diary-float yet unimplemented.
+ FIXME! DAY from `diary-float' yet unimplemented.
NONMARKER is a regular expression matching the start of non-marking
entries. ENTRY-MAIN is the first line of the diary entry."
@@ -2182,8 +2182,7 @@ written into the buffer `*icalendar-errors*'."
(setq diary-string "")
(mapc (lambda (_datestring)
(setq diary-string
- (concat diary-string
- (format "......"))))
+ (concat diary-string "......")))
(icalendar--split-value rdate)))
;; non-recurring event
;; all-day event
@@ -2528,7 +2527,7 @@ the entry."
summary)))
(when summary
(setq non-marking
- (y-or-n-p (format "Make appointment non-marking? "))))
+ (y-or-n-p "Make appointment non-marking? ")))
(unless diary-filename
(setq diary-filename
(read-file-name "Add appointment to this diary file: ")))
diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el
index 0aa38166bc1..b36171259c0 100644
--- a/lisp/calendar/time-date.el
+++ b/lisp/calendar/time-date.el
@@ -69,7 +69,7 @@ list (HIGH LOW MICRO PICO)."
(pop elt)))
(time-value (car elt))
(gensym (make-symbol "time")))
- `(let* ,(append `((,gensym (or ,time-value (current-time)))
+ `(let* ,(append `((,gensym (or ,time-value (time-convert nil 'list)))
(,gensym
(cond
((integerp ,gensym)
@@ -154,7 +154,10 @@ it is assumed that PICO was omitted and should be treated as zero."
DATE should be in one of the forms recognized by `parse-time-string'.
If DATE lacks timezone information, GMT is assumed."
(condition-case err
- (encode-time (parse-time-string date))
+ (let ((parsed (parse-time-string date)))
+ (when (decoded-time-year parsed)
+ (decoded-time-set-defaults parsed))
+ (encode-time parsed))
(error
(let ((overflow-error '(error "Specified time is not representable")))
(if (equal err overflow-error)
@@ -406,7 +409,11 @@ entries only for the values that should be altered.
For instance, if you want to \"add two months\" to TIME, then
leave all other fields but the month field in DELTA nil, and make
-the month field 2. The values in DELTA can be negative.
+the month field 2. For instance:
+
+ (decoded-time-add (decode-time) (make-decoded-time :month 2))
+
+The values in DELTA can be negative.
If applying a month/year delta leaves the time spec invalid, it
is decreased to be valid (\"add one month\" to January 31st 2019
diff --git a/lisp/calendar/timeclock.el b/lisp/calendar/timeclock.el
index 4a4b65d3745..0b94bcb77fe 100644
--- a/lisp/calendar/timeclock.el
+++ b/lisp/calendar/timeclock.el
@@ -35,14 +35,14 @@
;; working day), and `timeclock-when-to-leave' to calculate when you're free.
;; You'll probably want to bind the timeclock commands to some handy
-;; keystrokes. At the moment, C-x t is unused:
+;; keystrokes. Assuming C-c t is unbound, you might use:
;;
-;; (define-key ctl-x-map "ti" 'timeclock-in)
-;; (define-key ctl-x-map "to" 'timeclock-out)
-;; (define-key ctl-x-map "tc" 'timeclock-change)
-;; (define-key ctl-x-map "tr" 'timeclock-reread-log)
-;; (define-key ctl-x-map "tu" 'timeclock-update-mode-line)
-;; (define-key ctl-x-map "tw" 'timeclock-when-to-leave-string)
+;; (define-key (kbd "C-c t i") 'timeclock-in)
+;; (define-key (kbd "C-c t o") 'timeclock-out)
+;; (define-key (kbd "C-c t c") 'timeclock-change)
+;; (define-key (kbd "C-c t r") 'timeclock-reread-log)
+;; (define-key (kbd "C-c t u") 'timeclock-update-mode-line)
+;; (define-key (kbd "C-c t w") 'timeclock-when-to-leave-string)
;; If you want Emacs to display the amount of time "left" to your
;; workday in the mode-line, you can either set the value of
@@ -88,6 +88,8 @@
"The length of a work period in seconds."
:type 'integer)
+(defvar timeclock--previous-workday nil)
+
(defcustom timeclock-relative t
"Whether to make reported time relative to `timeclock-workday'.
For example, if the length of a normal workday is eight hours, and you
@@ -269,7 +271,10 @@ will be updated whenever the time display is updated. Otherwise,
the timeclock will use its own sixty second timer to do its
updating. With prefix ARG, turn mode line display on if and only
if ARG is positive. Returns the new status of timeclock mode line
-display (non-nil means on)."
+display (non-nil means on).
+
+If using a customized `timeclock-workday' value, this should be
+set before switching this mode on."
:global t
;; cf display-time-mode.
(setq timeclock-mode-string "")
@@ -1058,7 +1063,9 @@ discrepancy, today's discrepancy, and the time worked today."
(first t) (accum 0) (elapsed 0)
event beg last-date
last-date-limited last-date-seconds)
- (unless timeclock-discrepancy
+ (when (or (not timeclock-discrepancy)
+ ;; The length of the workday has changed, so recompute.
+ (not (equal timeclock-workday timeclock--previous-workday)))
(when (file-readable-p timeclock-file)
(setq timeclock-project-list nil
timeclock-last-project nil
@@ -1114,7 +1121,8 @@ discrepancy, today's discrepancy, and the time worked today."
last-date-seconds
timeclock-workday))
(forward-line))
- (setq timeclock-discrepancy accum))))
+ (setq timeclock-discrepancy accum
+ timeclock--previous-workday timeclock-workday))))
(unless timeclock-last-event-workday
(setq timeclock-last-event-workday timeclock-workday))
(setq accum (or timeclock-discrepancy 0)
diff --git a/lisp/calendar/todo-mode.el b/lisp/calendar/todo-mode.el
index 371d10631c5..51a27511320 100644
--- a/lisp/calendar/todo-mode.el
+++ b/lisp/calendar/todo-mode.el
@@ -1846,9 +1846,9 @@ consist of the last todo items and the first done items."
This inserts a new todo item into a category.
With no prefix argument ARG, add the item to the current
-category; with one prefix argument (`C-u'), prompt for a category
-from the current todo file; with two prefix arguments (`C-u
-C-u'), first prompt for a todo file, then a category in that
+category; with one prefix argument (\\[universal-argument]), prompt for a category
+from the current todo file; with two prefix arguments (\\[universal-argument]
+\\[universal-argument]), first prompt for a todo file, then a category in that
file. If a non-existing category is entered, ask whether to add
it to the todo file; if answered affirmatively, add the category
and insert the item there.
@@ -3969,14 +3969,14 @@ See `todo-set-top-priorities' for more details."
The categories can be any of those in the current todo file.
With numerical prefix ARG show at most ARG top priority items
-from each category. With `C-u' as prefix argument show the
+from each category. With \\[universal-argument] as prefix argument show the
numbers of top priority items specified by category in
`todo-top-priorities-overrides', if this has an entry for the file(s);
otherwise show `todo-top-priorities' items per category in the
file(s). With no prefix argument, if a top priorities file for
the current todo file has previously been saved (see
`todo-save-filtered-items-buffer'), visit this file; if there is
-no such file, build the list as with prefix argument `C-u'.
+no such file, build the list as with prefix argument \\[universal-argument].
The prefix ARG regulates how many top priorities from
each category to show, as described above."
@@ -3990,14 +3990,14 @@ in `todo-filter-files', or if this nil, in the files chosen from
a file selection dialog that pops up in this case.
With numerical prefix ARG show at most ARG top priority items
-from each category in each file. With `C-u' as prefix argument
+from each category in each file. With \\[universal-argument] as prefix argument
show the numbers of top priority items specified in
`todo-top-priorities-overrides', if this is non-nil; otherwise show
`todo-top-priorities' items per category. With no prefix
argument, if a top priorities file for the chosen todo files
exists (see `todo-save-filtered-items-buffer'), visit this file;
if there is no such file, do the same as with prefix argument
-`C-u'."
+\\[universal-argument]."
(interactive "P")
(todo-filter-items 'top arg t))
@@ -6543,8 +6543,8 @@ Filtered Items mode following todo (not done) items."
map)
"Todo Filtered Items mode keymap.")
-(easy-menu-define
- todo-menu todo-mode-map "Todo Menu"
+(easy-menu-define todo-menu todo-mode-map
+ "Todo Menu."
'("Todo"
("Navigation"
["Next Item" todo-next-item t]
diff --git a/lisp/cedet/ChangeLog.1 b/lisp/cedet/ChangeLog.1
index fb3dcd23965..0fe55739efb 100644
--- a/lisp/cedet/ChangeLog.1
+++ b/lisp/cedet/ChangeLog.1
@@ -1705,7 +1705,7 @@
2012-07-29 Paul Eggert <eggert@cs.ucla.edu>
- inaccessable -> inaccessible spelling fix (Bug#10052)
+ "inaccessible" spelling fix (Bug#10052)
* semantic/wisent/comp.el (wisent-inaccessible-symbols):
Rename from wisent-inaccessable-symbols, fixing a misspelling.
Caller changed.
diff --git a/lisp/cedet/data-debug.el b/lisp/cedet/data-debug.el
index 428848be04d..d8d1364491f 100644
--- a/lisp/cedet/data-debug.el
+++ b/lisp/cedet/data-debug.el
@@ -413,7 +413,9 @@ PREBUTTONTEXT is some text between prefix and the stuff list button."
)
(defun data-debug-insert-hash-table-button (hash-table prefix prebuttontext)
- "Insert HASH-TABLE as expandable button with recursive prefix PREFIX and PREBUTTONTEXT in front of the button text."
+ "Insert HASH-TABLE as expandable button, using PREFIX and PREBUTTONTEXT.
+PREFIX is a recursive prefix and PREBUTTONTEXT is text to be inserted
+in front of the button text."
(let ((string (propertize (format "%s" hash-table)
'face 'font-lock-keyword-face)))
(insert (propertize
diff --git a/lisp/cedet/ede/auto.el b/lisp/cedet/ede/auto.el
index ee9d0116af3..da6a3f3e903 100644
--- a/lisp/cedet/ede/auto.el
+++ b/lisp/cedet/ede/auto.el
@@ -69,7 +69,7 @@ into memory.")
(let* ((fc (oref dirmatch fromconfig))
(found (cond ((stringp fc) fc)
((functionp fc) (funcall fc))
- (t (error "Unknown dirmatch object match style.")))))
+ (t (error "Unknown dirmatch object match style")))))
(expand-file-name found)
))
@@ -129,7 +129,7 @@ into memory.")
;; Error if none others known
(t
- (error "Unknown dirmatch object match style.")))
+ (error "Unknown dirmatch object match style")))
))
(declare-function ede-directory-safe-p "ede")
diff --git a/lisp/cedet/ede/base.el b/lisp/cedet/ede/base.el
index 103a37045cc..004da6b95de 100644
--- a/lisp/cedet/ede/base.el
+++ b/lisp/cedet/ede/base.el
@@ -212,7 +212,7 @@ You can also use TRAMP for use with rcp & scp.")
:label "Web Page File"
:group name
:documentation
- "A file which contains the home page for this project.
+ "A file which contains the website for this project.
This file can be relative to slot `web-site-directory'.
This can be a local file, use ange-ftp, EFS, or TRAMP.")
(ftp-site :initarg :ftp-site
@@ -267,7 +267,7 @@ and target specific elements such as build variables.")
'(
[ "Update Version" ede-update-version ede-object ]
[ "Version Control Status" ede-vc-project-directory ede-object ]
- [ "Edit Project Homepage" ede-edit-web-page
+ [ "Edit Project Website" ede-edit-web-page
(and ede-object (oref (ede-toplevel) web-site-file)) ]
[ "Browse Project URL" ede-web-browse-home
(and ede-object
diff --git a/lisp/cedet/ede/cpp-root.el b/lisp/cedet/ede/cpp-root.el
index 652d6476f02..fd37e53ed42 100644
--- a/lisp/cedet/ede/cpp-root.el
+++ b/lisp/cedet/ede/cpp-root.el
@@ -103,7 +103,7 @@
;;
;; If the cpp-root project style is right for you, but you want a
;; dynamic loader, instead of hard-coding values in your .emacs, you
-;; can do that too, but you will need to write some lisp code.
+;; can do that too, but you will need to write some Lisp code.
;;
;; To do that, you need to add an entry to the
;; `ede-project-class-files' list, and also provide two functions to
diff --git a/lisp/cedet/ede/makefile-edit.el b/lisp/cedet/ede/makefile-edit.el
index d6965945494..709963d6faf 100644
--- a/lisp/cedet/ede/makefile-edit.el
+++ b/lisp/cedet/ede/makefile-edit.el
@@ -30,7 +30,7 @@
;; Formatting of a makefile
;;
;; 1) Creating an automakefile, stick in a top level comment about
-;; being created by emacs
+;; being created by Emacs.
;; 2) Leave order of variable contents alone, except for SOURCE
;; SOURCE always keep in the order of .c, .h, the other stuff.
diff --git a/lisp/cedet/ede/proj-elisp.el b/lisp/cedet/ede/proj-elisp.el
index 7e0f5a89346..7a3b36f30f6 100644
--- a/lisp/cedet/ede/proj-elisp.el
+++ b/lisp/cedet/ede/proj-elisp.el
@@ -54,8 +54,8 @@ load path."
Each package name will be loaded with `require'.
Each package's directory should also appear in :aux-packages via a package name.")
)
- "This target consists of a group of lisp files.
-A lisp target may be one general program with many separate lisp files in it.")
+ "This target consists of a group of Lisp files.
+A Lisp target may be one general program with many separate Lisp files in it.")
(cl-defmethod ede-proj-makefile-insert-rules :after ((this ede-proj-target-elisp))
"Insert rules needed by THIS target.
diff --git a/lisp/cedet/ede/proj.el b/lisp/cedet/ede/proj.el
index c8c34d092f1..1352e5c193d 100644
--- a/lisp/cedet/ede/proj.el
+++ b/lisp/cedet/ede/proj.el
@@ -562,7 +562,7 @@ Converts all symbols into the objects to be used."
;; Provide a good error msg.
(unless comp
(error "Could not find compiler match for source code extension \"%s\".
-You may need to add support for this type of file."
+You may need to add support for this type of file"
(if sources
(file-name-extension (car sources))
"")))
diff --git a/lisp/cedet/ede/project-am.el b/lisp/cedet/ede/project-am.el
index 258917f01b9..e7f5640c07f 100644
--- a/lisp/cedet/ede/project-am.el
+++ b/lisp/cedet/ede/project-am.el
@@ -130,7 +130,7 @@ other meta-variable based on this name.")
(defclass project-am-program (project-am-objectcode)
((ldadd :initarg :ldadd :documentation "Additional LD args."
:initform nil))
- "A top level program to build")
+ "A top level program to build.")
(defclass project-am-header (project-am-target)
()
@@ -154,7 +154,7 @@ other meta-variable based on this name.")
(defclass project-am-lib (project-am-objectcode)
nil
- "A top level library to build")
+ "A top level library to build.")
(defclass project-am-lisp (project-am-target)
()
@@ -705,7 +705,7 @@ Strip out duplicates, and recurse on variables."
(oset this source (makefile-macro-file-list (project-am-macro this))))
(cl-defmethod project-rescan ((this project-am-lisp))
- "Rescan the lisp sources."
+ "Rescan the Lisp sources."
(oset this source (makefile-macro-file-list (project-am-macro this))))
(cl-defmethod project-rescan ((this project-am-header))
diff --git a/lisp/cedet/ede/source.el b/lisp/cedet/ede/source.el
index 5dbad4fcc00..338b03d25dc 100644
--- a/lisp/cedet/ede/source.el
+++ b/lisp/cedet/ede/source.el
@@ -91,12 +91,12 @@ that they are willing to use.")
(ede-want-file-auxiliary-p this filename)))
(cl-defmethod ede-want-file-source-p ((this ede-sourcecode) filename)
- "Return non-nil if THIS will take FILENAME as an auxiliary ."
+ "Return non-nil if THIS will take FILENAME as an auxiliary."
(let ((case-fold-search nil))
(string-match (oref this sourcepattern) filename)))
(cl-defmethod ede-want-file-auxiliary-p ((this ede-sourcecode) filename)
- "Return non-nil if THIS will take FILENAME as an auxiliary ."
+ "Return non-nil if THIS will take FILENAME as an auxiliary."
(let ((case-fold-search nil))
(and (slot-boundp this 'auxsourcepattern)
(oref this auxsourcepattern)
diff --git a/lisp/cedet/ede/system.el b/lisp/cedet/ede/system.el
index 8ef38f0d33e..1300ba9011e 100644
--- a/lisp/cedet/ede/system.el
+++ b/lisp/cedet/ede/system.el
@@ -34,7 +34,7 @@
;;;###autoload
(defun ede-web-browse-home ()
- "Browse the home page of the current project."
+ "Browse the website of the current project."
(interactive)
(if (not (ede-toplevel))
(error "No project"))
diff --git a/lisp/cedet/mode-local.el b/lisp/cedet/mode-local.el
index 247f78ecff7..e0717fbfe5a 100644
--- a/lisp/cedet/mode-local.el
+++ b/lisp/cedet/mode-local.el
@@ -156,7 +156,7 @@ local variables have been defined."
DOCSTRING is optional and not used.
To work properly, this should be put after PARENT mode local variables
definition."
- (declare (obsolete define-derived-mode "27.1"))
+ (declare (obsolete define-derived-mode "27.1") (indent 2))
`(mode-local--set-parent ',mode ',parent))
(defun mode-local-use-bindings-p (this-mode desired-mode)
@@ -567,6 +567,7 @@ appropriate arguments deduced from ARGS.
OVERARGS is a list of arguments passed to the override and
`NAME-default' function, in place of those deduced from ARGS."
(declare (doc-string 3)
+ (indent defun)
(debug (&define name lambda-list stringp def-body)))
`(eval-and-compile
(defun ,name ,args
@@ -595,21 +596,23 @@ DOCSTRING is the documentation string.
BODY is the implementation of this function."
;; FIXME: Make this obsolete and use cl-defmethod with &context instead.
(declare (doc-string 4)
+ (indent defun)
(debug (&define name symbolp lambda-list stringp def-body)))
(let ((newname (intern (format "%s-%s" name mode))))
`(progn
(eval-and-compile
(defun ,newname ,args
- ,(format "%s\n\nOverride %s in `%s' buffers."
- docstring name mode)
+ ,(concat docstring "\n"
+ (internal--format-docstring-line
+ "Override `%s' in `%s' buffers."
+ name mode))
;; The body for this implementation
,@body)
;; For find-func to locate the definition of NEWNAME.
(put ',newname 'definition-name ',name))
(mode-local-bind '((,name . ,newname))
'(override-flag t)
- ',mode))
- ))
+ ',mode))))
;;; Read/Query Support
(defun mode-local-read-function (prompt &optional initial hist default)
@@ -773,11 +776,11 @@ SYMBOL is a function that can be overridden."
(defconst xref-mode-local-find-overloadable-regexp
"(define-overload\\(able-function\\)? +%s"
"Regexp used by `xref-find-definitions' when searching for a
- mode-local overloadable function definition.")
+mode-local overloadable function definition.")
(defun xref-mode-local-find-override (meta-name)
"Function used by `xref-find-definitions' when searching for an
- override of a mode-local overloadable function.
+override of a mode-local overloadable function.
META-NAME is a cons (OVERLOADABLE-SYMBOL . MAJOR-MODE)."
(let* ((override (car meta-name))
(mode (cdr meta-name))
diff --git a/lisp/cedet/pulse.el b/lisp/cedet/pulse.el
index 7928fa1bf42..b0269440291 100644
--- a/lisp/cedet/pulse.el
+++ b/lisp/cedet/pulse.el
@@ -195,11 +195,13 @@ Optional argument FACE specifies the face to do the highlighting."
(remove-hook 'pre-command-hook #'pulse-momentary-unhighlight))
;;;###autoload
-(defun pulse-momentary-highlight-one-line (point &optional face)
+(defun pulse-momentary-highlight-one-line (&optional point face)
"Highlight the line around POINT, unhighlighting before next command.
+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 point)
+ (goto-char (or point (point)))
(let ((start (point-at-bol))
(end (save-excursion
(end-of-line)
diff --git a/lisp/cedet/semantic.el b/lisp/cedet/semantic.el
index fb443fa4a32..205d6a812a2 100644
--- a/lisp/cedet/semantic.el
+++ b/lisp/cedet/semantic.el
@@ -271,7 +271,7 @@ a parse of the buffer.")
(defsubst semantic-error-if-unparsed ()
"Raise an error if current buffer was not parsed by Semantic."
(unless semantic-new-buffer-fcn-was-run
- (error "Buffer was not parsed by Semantic.")))
+ (error "Buffer was not parsed by Semantic")))
(defsubst semantic--umatched-syntax-needs-refresh-p ()
"Return non-nil if the unmatched syntax cache needs a refresh.
diff --git a/lisp/cedet/semantic/analyze/complete.el b/lisp/cedet/semantic/analyze/complete.el
index ccf405d62e2..5c3228ae166 100644
--- a/lisp/cedet/semantic/analyze/complete.el
+++ b/lisp/cedet/semantic/analyze/complete.el
@@ -70,7 +70,8 @@ context. Passing in a context is useful if the caller also needs
to access parts of the analysis.
The remaining FLAGS arguments are passed to the mode specific completion engine.
Bad flags should be ignored by modes that don't use them.
-See `semantic-analyze-possible-completions-default' for details on the default FLAGS.
+See `semantic-analyze-possible-completions-default' for details
+on the default FLAGS.
Completions run through the following filters:
* Elements currently in scope
@@ -107,7 +108,7 @@ in a buffer."
;; Buffer was not parsed by Semantic.
;; Raise error if called interactively.
(when (called-interactively-p 'any)
- (error "Buffer was not parsed by Semantic."))))
+ (error "Buffer was not parsed by Semantic"))))
(defvar semantic--prefixtypes)
diff --git a/lisp/cedet/semantic/bovine/c.el b/lisp/cedet/semantic/bovine/c.el
index e7ecb61513f..19e2fee2bac 100644
--- a/lisp/cedet/semantic/bovine/c.el
+++ b/lisp/cedet/semantic/bovine/c.el
@@ -1466,36 +1466,32 @@ Override function for `semantic-tag-protection'."
(prot nil))
;; Check the modifiers for protection if we are not a child
;; of some class type.
- (when (or (not parent) (not (eq (semantic-tag-class parent) 'type)))
- (while (and (not prot) mods)
- (if (stringp (car mods))
- (let ((s (car mods)))
- ;; A few silly defaults to get things started.
- (cond ((or (string= s "extern")
- (string= s "export"))
- 'public)
- ((string= s "static")
- 'private))))
- (setq mods (cdr mods))))
- ;; If we have a typed parent, look for :public style labels.
- (when (and parent (eq (semantic-tag-class parent) 'type))
+ (if (not (and parent (eq (semantic-tag-class parent) 'type)))
+ (while (and (not prot) mods)
+ (if (stringp (car mods))
+ (let ((s (car mods)))
+ ;; A few silly defaults to get things started.
+ (setq prot (pcase s
+ ((or "extern" "export") 'public)
+ ("static" 'private)))))
+ (setq mods (cdr mods)))
+ ;; If we have a typed parent, look for :public style labels.
(let ((pp (semantic-tag-type-members parent)))
(while (and pp (not (semantic-equivalent-tag-p (car pp) tag)))
(when (eq (semantic-tag-class (car pp)) 'label)
(setq prot
- (cond ((string= (semantic-tag-name (car pp)) "public")
- 'public)
- ((string= (semantic-tag-name (car pp)) "private")
- 'private)
- ((string= (semantic-tag-name (car pp)) "protected")
- 'protected)))
+ (pcase (semantic-tag-name (car pp))
+ ("public" 'public)
+ ("private" 'private)
+ ("protected" 'protected)))
)
(setq pp (cdr pp)))))
(when (and (not prot) (eq (semantic-tag-class parent) 'type))
(setq prot
- (cond ((string= (semantic-tag-type parent) "class") 'private)
- ((string= (semantic-tag-type parent) "struct") 'public)
- (t 'unknown))))
+ (pcase (semantic-tag-type parent)
+ ("class" 'private)
+ ("struct" 'public)
+ (_ 'unknown))))
(or prot
(if (and parent (semantic-tag-of-class-p parent 'type))
'public
@@ -1937,7 +1933,7 @@ For types with a :parent, create faux namespaces to put TAG into."
(define-mode-local-override semanticdb-find-table-for-include c-mode
(includetag &optional table)
- "For a single INCLUDETAG found in TABLE, find a `semanticdb-table' object
+ "For a single INCLUDETAG found in TABLE, find a `semanticdb-table' object.
INCLUDETAG is a semantic TAG of class `include'.
TABLE is a semanticdb table that identifies where INCLUDETAG came from.
TABLE is optional if INCLUDETAG has an overlay of :filename attribute.
@@ -2034,7 +2030,7 @@ for arguments compared."
(if blankok t (semantic--tag-similar-names-p-default tag1 tag2 nil)))
(define-mode-local-override semantic--tag-similar-types-p c-mode (tag1 tag2)
- "For c-mode, deal with TAG1 and TAG2 being used in different namespaces.
+ "For `c-mode', deal with TAG1 and TAG2 being used in different namespaces.
In this case, one type will be shorter than the other. Instead
of fully resolving all namespaces currently in scope for both
types, we simply compare as many elements as the shorter type
@@ -2064,7 +2060,7 @@ provides."
(define-mode-local-override semantic--tag-attribute-similar-p c-mode
(attr value1 value2 ignorable-attributes)
- "For c-mode, allow function :arguments to ignore the :name attributes."
+ "For `c-mode', allow function :arguments to ignore the :name attributes."
(cond ((eq attr :arguments)
(semantic--tag-attribute-similar-p-default attr value1 value2
(cons :name ignorable-attributes)))
diff --git a/lisp/cedet/semantic/bovine/debug.el b/lisp/cedet/semantic/bovine/debug.el
index 47850a5d1f4..64ccbb45195 100644
--- a/lisp/cedet/semantic/bovine/debug.el
+++ b/lisp/cedet/semantic/bovine/debug.el
@@ -113,7 +113,7 @@ LEXTOKEN, is a token returned by the lexer which is being matched."
:documentation
"An error condition caught in an action.")
)
- "Debugger frame representation of a lisp error thrown during parsing.")
+ "Debugger frame representation of a Lisp error thrown during parsing.")
(defun semantic-create-bovine-debug-error-frame (condition)
"Create an error frame for bovine debugger.
diff --git a/lisp/cedet/semantic/complete.el b/lisp/cedet/semantic/complete.el
index d6ef7960473..375b97a7a5d 100644
--- a/lisp/cedet/semantic/complete.el
+++ b/lisp/cedet/semantic/complete.el
@@ -198,7 +198,7 @@ Argument COLLECTOR is an object which can be used to calculate
a list of possible hits. See `semantic-completion-collector-engine'
for details on COLLECTOR.
Argument DISPLAYER is an object used to display a list of possible
-completions for a given prefix. See`semantic-completion-display-engine'
+completions for a given prefix. See `semantic-completion-display-engine'
for details on DISPLAYER.
PROMPT is a string to prompt with.
DEFAULT-TAG is a semantic tag or string to use as the default value.
@@ -224,11 +224,10 @@ HISTORY is a symbol representing a variable to story the history in."
;; @todo - move from () to into the editable area
(if (string-match ":" prompt)
- (setq prompt (concat
- (substring prompt 0 (match-beginning 0))
- " (default " default-as-string ")"
- (substring prompt (match-beginning 0))))
- (setq prompt (concat prompt " (" default-as-string "): "))))
+ (setq prompt (format-prompt
+ (substring prompt 0 (match-beginning 0))
+ default-as-string))
+ (setq prompt (format-prompt prompt default-as-string))))
;;
;; Perform the Completion
;;
@@ -746,7 +745,7 @@ Argument COLLECTOR is an object which can be used to calculate
a list of possible hits. See `semantic-completion-collector-engine'
for details on COLLECTOR.
Argument DISPLAYER is an object used to display a list of possible
-completions for a given prefix. See`semantic-completion-display-engine'
+completions for a given prefix. See `semantic-completion-display-engine'
for details on DISPLAYER.
BUFFER is the buffer in which completion will take place.
START is a location for the start of the full symbol.
@@ -930,7 +929,7 @@ inserted into the current context.")
(cl-defmethod semantic-collector-calculate-completions-raw
((obj semantic-collector-analyze-completions) prefix _completionlist)
- "calculate the completions for prefix from COMPLETIONLIST."
+ "Calculate the completions for prefix from COMPLETIONLIST."
;; if there are no completions yet, calculate them.
(if (not (slot-boundp obj 'first-pass-completions))
(oset obj first-pass-completions
diff --git a/lisp/cedet/semantic/db-el.el b/lisp/cedet/semantic/db-el.el
index 41e48b0bc30..c9ae68e9fa7 100644
--- a/lisp/cedet/semantic/db-el.el
+++ b/lisp/cedet/semantic/db-el.el
@@ -328,7 +328,7 @@ Like `semanticdb-find-tags-for-completion-method' for Emacs Lisp."
;;
(cl-defmethod semanticdb-find-tags-external-children-of-type-method
((_table semanticdb-table-emacs-lisp) type &optional tags)
- "Find all nonterminals which are child elements of TYPE
+ "Find all nonterminals which are child elements of TYPE.
Optional argument TAGS is a list of tags to search.
Return a list of tags."
(if tags (cl-call-next-method)
diff --git a/lisp/cedet/semantic/db-find.el b/lisp/cedet/semantic/db-find.el
index c96a426280e..e6a7879775e 100644
--- a/lisp/cedet/semantic/db-find.el
+++ b/lisp/cedet/semantic/db-find.el
@@ -315,7 +315,7 @@ Default action as described in `semanticdb-find-translate-path'."
;;;###autoload
(define-overloadable-function semanticdb-find-table-for-include (includetag &optional table)
- "For a single INCLUDETAG found in TABLE, find a `semanticdb-table' object
+ "For a single INCLUDETAG found in TABLE, find a `semanticdb-table' object.
INCLUDETAG is a semantic TAG of class `include'.
TABLE is a semanticdb table that identifies where INCLUDETAG came from.
TABLE is optional if INCLUDETAG has an overlay of :filename attribute."
@@ -914,7 +914,7 @@ but should be good enough for debugging assertions."
(null (car (cdr (car resultp)))))))
(defun semanticdb-find-result-prin1-to-string (result)
- "Presuming RESULT satisfies `semanticdb-find-results-p', provide a short PRIN1 output."
+ "If RESULT satisfies `semanticdb-find-results-p', provide a short PRIN1 output."
(if (< (length result) 2)
(concat "#<FIND RESULT "
(mapconcat (lambda (a)
diff --git a/lisp/cedet/semantic/db-typecache.el b/lisp/cedet/semantic/db-typecache.el
index c0fee3b2bd9..03158171a29 100644
--- a/lisp/cedet/semantic/db-typecache.el
+++ b/lisp/cedet/semantic/db-typecache.el
@@ -547,8 +547,7 @@ found tag to be loaded."
(cl-defmethod semanticdb-typecache-for-database ((db semanticdb-project-database)
&optional mode)
"Return the typecache for the project database DB.
-If there isn't one, create it.
-"
+If there isn't one, create it."
(let ((lmode (or mode major-mode))
(cache (semanticdb-get-typecache db))
(stream nil)
diff --git a/lisp/cedet/semantic/debug.el b/lisp/cedet/semantic/debug.el
index 4f96746166b..c13952265e6 100644
--- a/lisp/cedet/semantic/debug.el
+++ b/lisp/cedet/semantic/debug.el
@@ -108,7 +108,7 @@ These buffers are brought into view when layout occurs.")
:documentation
"Any active overlays being used to show the debug position.")
)
- "Controls action when in `semantic-debug-mode'")
+ "Controls action when in `semantic-debug-mode'.")
;; Methods
(cl-defmethod semantic-debug-set-frame ((iface semantic-debug-interface) frame)
@@ -559,10 +559,8 @@ down to your parser later."
(cl-defmethod semantic-debug-parser-frames ((_parser semantic-debug-parser))
"Return a list of frames for the current parser.
A frame is of the form:
- ( .. .what ? .. )
-"
- (error "Parser has not implemented frame values")
- )
+ ( .. .what ? .. )"
+ (error "Parser has not implemented frame values"))
(provide 'semantic/debug)
diff --git a/lisp/cedet/semantic/decorate/include.el b/lisp/cedet/semantic/decorate/include.el
index a3bf4e252f7..ae2895c2b93 100644
--- a/lisp/cedet/semantic/decorate/include.el
+++ b/lisp/cedet/semantic/decorate/include.el
@@ -66,7 +66,7 @@ Used by the decoration style: `semantic-decoration-on-includes'."
(easy-menu-define
semantic-decoration-on-include-menu
semantic-decoration-on-include-map
- "Include Menu"
+ "Include Menu."
(list
"Include"
["What Is This?" semantic-decoration-include-describe
@@ -124,7 +124,7 @@ Used by the decoration style: `semantic-decoration-on-unknown-includes'."
(easy-menu-define
semantic-decoration-on-unknown-include-menu
semantic-decoration-on-unknown-include-map
- "Unknown Include Menu"
+ "Unknown Include Menu."
(list
"Unknown Include"
["What Is This?" semantic-decoration-unknown-include-describe
@@ -179,7 +179,7 @@ Used by the decoration style: `semantic-decoration-on-fileless-includes'."
(easy-menu-define
semantic-decoration-on-fileless-include-menu
semantic-decoration-on-fileless-include-map
- "Fileless Include Menu"
+ "Fileless Include Menu."
(list
"Fileless Include"
["What Is This?" semantic-decoration-fileless-include-describe
@@ -234,7 +234,7 @@ Used by the decoration style: `semantic-decoration-on-unparsed-includes'."
(easy-menu-define
semantic-decoration-on-unparsed-include-menu
semantic-decoration-on-unparsed-include-map
- "Unparsed Include Menu"
+ "Unparsed Include Menu."
(list
"Unparsed Include"
["What Is This?" semantic-decoration-unparsed-include-describe
@@ -514,9 +514,7 @@ See the Semantic manual node on SemanticDB for more about search paths.")
Argument EVENT describes the event that caused this function to be called."
(interactive "e")
(let* ((startwin (selected-window))
- ;; This line has an issue in XEmacs.
- (win (semantic-event-window event))
- )
+ (win (semantic-event-window event)))
(select-window win t)
(save-excursion
;(goto-char (window-start win))
@@ -557,9 +555,7 @@ searches, but you cannot visit this include.\n\n")
Argument EVENT describes the event that caused this function to be called."
(interactive "e")
(let* ((startwin (selected-window))
- ;; This line has an issue in XEmacs.
- (win (semantic-event-window event))
- )
+ (win (semantic-event-window event)))
(select-window win t)
(save-excursion
;(goto-char (window-start win))
diff --git a/lisp/cedet/semantic/decorate/mode.el b/lisp/cedet/semantic/decorate/mode.el
index c6bf15205fd..0a234b3000d 100644
--- a/lisp/cedet/semantic/decorate/mode.el
+++ b/lisp/cedet/semantic/decorate/mode.el
@@ -391,6 +391,7 @@ etc., found in the semantic-decorate library.
To add other kind of decorations on a tag, `NAME-highlight' must use
`semantic-decorate-tag', and other functions of the semantic
decoration API found in this library."
+ (declare (indent 1))
(let ((predicate (semantic-decorate-style-predicate name))
(highlighter (semantic-decorate-style-highlighter name))
(predicatedef (semantic-decorate-style-predicate-default name))
@@ -409,8 +410,11 @@ decoration API found in this library."
;; Create an override method to specify if a given tag belongs
;; to this type of decoration
(define-overloadable-function ,predicate (tag)
- ,(format "Return non-nil to decorate TAG with `%s' style.\n%s"
- name doc))
+ ,(concat
+ (internal--format-docstring-line
+ "Return non-nil to decorate TAG with `%s' style."
+ name)
+ "\n" doc))
;; Create an override method that will perform the highlight
;; operation if the -p method returns non-nil.
(define-overloadable-function ,highlighter (tag)
diff --git a/lisp/cedet/semantic/dep.el b/lisp/cedet/semantic/dep.el
index efebe21a945..cae38e6f111 100644
--- a/lisp/cedet/semantic/dep.el
+++ b/lisp/cedet/semantic/dep.el
@@ -82,6 +82,7 @@ users will customize.
Creates a customizable variable users can customize that will
keep semantic data structures up to date."
+ (declare (indent defun))
`(progn
;; Create a variable users can customize.
(defcustom ,name ,value
@@ -133,7 +134,7 @@ Changes made by this function are not persistent."
;;;###autoload
(defun semantic-remove-system-include (dir &optional mode)
"Add a system include DIR to path for MODE.
-Modifies a mode-local version of`semantic-dependency-system-include-path'.
+Modifies a mode-local version of `semantic-dependency-system-include-path'.
Changes made by this function are not persistent."
(interactive (list
diff --git a/lisp/cedet/semantic/ede-grammar.el b/lisp/cedet/semantic/ede-grammar.el
index 19d4184fa45..9a4d412d5d3 100644
--- a/lisp/cedet/semantic/ede-grammar.el
+++ b/lisp/cedet/semantic/ede-grammar.el
@@ -185,7 +185,7 @@ max-lisp-eval-depth 700)'\n"
(cl-defmethod ede-proj-makefile-insert-dist-dependencies ((this semantic-ede-proj-target-grammar))
"Insert dist dependencies, or intermediate targets.
-This makes sure that all grammar lisp files are created before the dist
+This makes sure that all grammar Lisp files are created before the dist
runs, so they are always up to date.
Argument THIS is the target that should insert stuff."
(cl-call-next-method)
diff --git a/lisp/cedet/semantic/fw.el b/lisp/cedet/semantic/fw.el
index 4ad70ff7c64..3502cda500e 100644
--- a/lisp/cedet/semantic/fw.el
+++ b/lisp/cedet/semantic/fw.el
@@ -66,8 +66,6 @@
(defalias 'semantic-mode-line-update #'force-mode-line-update)
-;; Since Emacs 22 major mode functions should use `run-mode-hooks' to
-;; run major mode hooks.
(define-obsolete-function-alias 'semantic-run-mode-hooks #'run-mode-hooks "28.1")
;; Fancy compat usage now handled in cedet-compat
@@ -284,7 +282,7 @@ later installation should be done in MODE hook."
(defvar semantic-current-input-throw-symbol nil
"The current throw symbol for `semantic-exit-on-input'.")
(defvar semantic--on-input-start-marker nil
- "The marker when starting a semantic-exit-on-input form.")
+ "The marker when starting a `semantic-exit-on-input' form.")
(defmacro semantic-exit-on-input (symbol &rest forms)
"Using SYMBOL as an argument to `throw', execute FORMS.
diff --git a/lisp/cedet/semantic/grammar.el b/lisp/cedet/semantic/grammar.el
index 4c3bb6c238b..33c66da9a62 100644
--- a/lisp/cedet/semantic/grammar.el
+++ b/lisp/cedet/semantic/grammar.el
@@ -840,7 +840,7 @@ If optional argument FORCE is non-nil, unconditionally re-generate the
Lisp code."
(interactive "P")
(unless (semantic-active-p)
- (error "You have to activate semantic-mode to create a package."))
+ (error "You have to activate semantic-mode to create a package"))
(setq force (or force current-prefix-arg))
(semantic-fetch-tags)
(let* (
diff --git a/lisp/cedet/semantic/grm-wy-boot.el b/lisp/cedet/semantic/grm-wy-boot.el
index a6bf211713a..ce63421fb37 100644
--- a/lisp/cedet/semantic/grm-wy-boot.el
+++ b/lisp/cedet/semantic/grm-wy-boot.el
@@ -149,10 +149,10 @@
((type_decl))
((use_macros_decl)))
(default_prec_decl
- ((DEFAULT-PREC)
- `(wisent-raw-tag
- (semantic-tag "default-prec" 'assoc :value
- '("t")))))
+ ((DEFAULT-PREC)
+ `(wisent-raw-tag
+ (semantic-tag "default-prec" 'assoc :value
+ '("t")))))
(no_default_prec_decl
((NO-DEFAULT-PREC)
`(wisent-raw-tag
diff --git a/lisp/cedet/semantic/idle.el b/lisp/cedet/semantic/idle.el
index b883573a30f..a14994424d7 100644
--- a/lisp/cedet/semantic/idle.el
+++ b/lisp/cedet/semantic/idle.el
@@ -102,7 +102,6 @@ it is unlikely the user would be ready to type again right away."
(defun semantic-idle-scheduler-setup-timers ()
"Lazy initialization of the auto parse idle timer."
- ;; REFRESH THIS FUNCTION for XEMACS FOIBLES
(or (timerp semantic-idle-scheduler-timer)
(setq semantic-idle-scheduler-timer
(run-with-idle-timer
@@ -578,10 +577,11 @@ This routine creates the following functions and variables:"
`(progn
(define-minor-mode ,global
,(concat "Toggle " (symbol-name global) ".
-With ARG, turn the minor mode on if ARG is positive, off otherwise.
-
-When this minor mode is enabled, `" (symbol-name mode) "' is
-turned on in every Semantic-supported buffer.")
+With ARG, turn the minor mode on if ARG is positive, off otherwise.\n\n"
+ (internal--format-docstring-line
+ "When this minor mode is enabled, `%s' is \
+turned on in every Semantic-supported buffer."
+ (symbol-name mode)))
:global t
:group 'semantic
:group 'semantic-modes
@@ -619,8 +619,9 @@ turned on in every Semantic-supported buffer.")
"") ; idle schedulers are quiet?
(defun ,func ()
- ,(concat "Perform idle activity for the minor mode `"
- (symbol-name mode) "'.")
+ ,(internal--format-docstring-line
+ "Perform idle activity for the minor mode `%s'."
+ (symbol-name mode))
,@forms))))
;;; SUMMARY MODE
@@ -1071,7 +1072,7 @@ be called."
(easy-menu-define
semantic-idle-breadcrumbs-popup-menu
semantic-idle-breadcrumbs-popup-map
- "Semantic Breadcrumbs Mode Menu"
+ "Semantic Breadcrumbs Mode Menu."
(list
"Breadcrumb Tag"
(vector
diff --git a/lisp/cedet/semantic/lex-spp.el b/lisp/cedet/semantic/lex-spp.el
index 8073640a8bd..3297367db90 100644
--- a/lisp/cedet/semantic/lex-spp.el
+++ b/lisp/cedet/semantic/lex-spp.el
@@ -1165,7 +1165,8 @@ of type `spp-macro-def' is to be created.
VALFORM are forms that return the value to be saved for this macro, or nil.
When implementing a macro, you can use `semantic-lex-spp-stream-for-macro'
to convert text into a lexical stream for storage in the macro."
- (declare (debug (&define name stringp stringp form def-body)))
+ (declare (debug (&define name stringp stringp form def-body))
+ (indent 1))
(let ((start (make-symbol "start"))
(end (make-symbol "end"))
(val (make-symbol "val"))
@@ -1199,7 +1200,8 @@ REGEXP is a regular expression for the analyzer to match.
See `define-lex-regex-analyzer' for more on regexp.
TOKIDX is an index into REGEXP for which a new lexical token
of type `spp-macro-undef' is to be created."
- (declare (debug (&define name stringp stringp form)))
+ (declare (debug (&define name stringp stringp form))
+ (indent 1))
(let ((start (make-symbol "start"))
(end (make-symbol "end")))
`(define-lex-regex-analyzer ,name
@@ -1260,7 +1262,8 @@ type of include. The return value should be of the form:
(NAME . TYPE)
where NAME is the name of the include, and TYPE is the type of the include,
where a valid symbol is `system', or nil."
- (declare (debug (&define name stringp stringp form def-body)))
+ (declare (debug (&define name stringp stringp form def-body))
+ (indent 1))
(let ((start (make-symbol "start"))
(end (make-symbol "end"))
(val (make-symbol "val"))
diff --git a/lisp/cedet/semantic/lex.el b/lisp/cedet/semantic/lex.el
index 69f20deeb76..d524b733db5 100644
--- a/lisp/cedet/semantic/lex.el
+++ b/lisp/cedet/semantic/lex.el
@@ -760,7 +760,7 @@ If two analyzers can match the same text, it is important to order the
analyzers so that the one you want to match first occurs first. For
example, it is good to put a number analyzer in front of a symbol
analyzer which might mistake a number for a symbol."
- (declare (debug (&define name stringp (&rest symbolp))))
+ (declare (debug (&define name stringp (&rest symbolp))) (indent 1))
`(defun ,name (start end &optional depth length)
,(concat doc "\nSee `semantic-lex' for more information.")
;; Make sure the state of block parsing starts over.
@@ -1096,7 +1096,7 @@ Proper action in FORMS is to move the value of `semantic-lex-end-point' to
after the location of the analyzed entry, and to add any discovered tokens
at the beginning of `semantic-lex-token-stream'.
This can be done by using `semantic-lex-push-token'."
- (declare (debug (&define name stringp form def-body)))
+ (declare (debug (&define name stringp form def-body)) (indent 1))
`(eval-and-compile
;; This is the real info used by `define-lex' (via semantic-lex-one-token).
(defconst ,name '(,condition ,@forms) ,doc)
@@ -1118,7 +1118,7 @@ This can be done by using `semantic-lex-push-token'."
"Create a lexical analyzer with NAME and DOC that will match REGEXP.
FORMS are evaluated upon a successful match.
See `define-lex-analyzer' for more about analyzers."
- (declare (debug (&define name stringp form def-body)))
+ (declare (debug (&define name stringp form def-body)) (indent 1))
`(define-lex-analyzer ,name
,doc
(looking-at ,regexp)
@@ -1137,7 +1137,8 @@ FORMS are evaluated upon a successful match BEFORE the new token is
created. It is valid to ignore FORMS.
See `define-lex-analyzer' for more about analyzers."
(declare (debug
- (&define name stringp form symbolp [ &optional form ] def-body)))
+ (&define name stringp form symbolp [ &optional form ] def-body))
+ (indent 1))
`(define-lex-analyzer ,name
,doc
(looking-at ,regexp)
@@ -1162,7 +1163,8 @@ where BLOCK-SYM is the symbol returned in a block token. OPEN-DELIM
and CLOSE-DELIM are respectively the open and close delimiters
identifying a block. OPEN-SYM and CLOSE-SYM are respectively the
symbols returned in open and close tokens."
- (declare (debug (&define name stringp form (&rest form))))
+ (declare (debug (&define name stringp form (&rest form)))
+ (indent 1))
(let ((specs (cons spec1 specs))
spec open olist clist)
(while specs
@@ -1471,6 +1473,7 @@ syntax as specified by the syntax table."
(defmacro define-lex-keyword-type-analyzer (name doc syntax)
"Define a keyword type analyzer NAME with DOC string.
SYNTAX is the regexp that matches a keyword syntactic expression."
+ (declare (indent 1))
(let ((key (make-symbol "key")))
`(define-lex-analyzer ,name
,doc
@@ -1486,6 +1489,7 @@ SYNTAX is the regexp that matches a keyword syntactic expression."
"Define a sexp type analyzer NAME with DOC string.
SYNTAX is the regexp that matches the beginning of the s-expression.
TOKEN is the lexical token returned when SYNTAX matches."
+ (declare (indent 1))
`(define-lex-regex-analyzer ,name
,doc
,syntax
@@ -1504,6 +1508,7 @@ SYNTAX is the regexp that matches a syntactic expression.
MATCHES is an alist of lexical elements used to refine the syntactic
expression.
DEFAULT is the default lexical token returned when no MATCHES."
+ (declare (indent 1))
(if matches
(let* ((val (make-symbol "val"))
(lst (make-symbol "lst"))
@@ -1536,6 +1541,7 @@ SYNTAX is the regexp that matches a syntactic expression.
MATCHES is an alist of lexical elements used to refine the syntactic
expression.
DEFAULT is the default lexical token returned when no MATCHES."
+ (declare (indent 1))
(if matches
(let* ((val (make-symbol "val"))
(lst (make-symbol "lst"))
@@ -1633,6 +1639,7 @@ When the lexer encounters the open-paren delimiter \"(\":
- If the maximum depth of parenthesis tracking is reached (current
depth >= max depth), it returns the whole parenthesis block as
a (PAREN_BLOCK start . end) token."
+ (declare (indent 1))
(let* ((val (make-symbol "val"))
(lst (make-symbol "lst"))
(elt (make-symbol "elt")))
diff --git a/lisp/cedet/semantic/symref/cscope.el b/lisp/cedet/semantic/symref/cscope.el
index e63b7a7e914..bc3f4a248b7 100644
--- a/lisp/cedet/semantic/symref/cscope.el
+++ b/lisp/cedet/semantic/symref/cscope.el
@@ -43,7 +43,7 @@ the hit list.
See the function `cedet-cscope-search' for more details.")
(cl-defmethod semantic-symref-perform-search ((tool semantic-symref-tool-cscope))
- "Perform a search with GNU Global."
+ "Perform a search with CScope."
(let* ((rootproj (when (and (featurep 'ede) ede-minor-mode)
(ede-toplevel)))
(default-directory (if rootproj
diff --git a/lisp/cedet/semantic/symref/grep.el b/lisp/cedet/semantic/symref/grep.el
index 180d779a780..077a2d48615 100644
--- a/lisp/cedet/semantic/symref/grep.el
+++ b/lisp/cedet/semantic/symref/grep.el
@@ -39,7 +39,7 @@
)
"A symref tool implementation using grep.
This tool uses EDE to find the root of the project, then executes
-find-grep in the project. The output is parsed for hits and
+`find-grep' in the project. The output is parsed for hits and
those hits returned.")
(defvar semantic-symref-filepattern-alist
@@ -87,7 +87,7 @@ Optional argument MODE specifies the `major-mode' to test."
(if (null (cdr pat))
args
`("(" ,@args
- ,@(mapcan (lambda (s) `("-o" "-name" ,s)) pat)
+ ,@(mapcan (lambda (s) `("-o" "-name" ,s)) (cdr pat))
")"))))))
(defvar semantic-symref-grep-flags)
@@ -133,6 +133,12 @@ This shell should support pipe redirect syntax."
:group 'semantic
:type 'string)
+(defun semantic-symref-grep--quote-grep (string)
+ "Quote STRING as a grep-syntax regexp."
+ (replace-regexp-in-string (rx (in ".^$*[\\"))
+ (lambda (s) (concat "\\" s))
+ string nil t))
+
(cl-defmethod semantic-symref-perform-search ((tool semantic-symref-tool-grep))
"Perform a search with Grep."
;; Grep doesn't support some types of searches.
@@ -150,15 +156,11 @@ This shell should support pipe redirect syntax."
"-l ")
((eq (oref tool searchtype) 'regexp)
"-nE ")
- (t "-n ")))
- (greppat (cond ((eq (oref tool searchtype) 'regexp)
- (oref tool searchfor))
- (t
- ;; Can't use the word boundaries: Grep
- ;; doesn't always agree with the language
- ;; syntax on those.
- (format "\\(^\\|\\W\\)%s\\(\\W\\|$\\)"
- (oref tool searchfor)))))
+ (t "-nw ")))
+ (searchfor (oref tool searchfor))
+ (greppat (if (eq (oref tool searchtype) 'regexp)
+ searchfor
+ (semantic-symref-grep--quote-grep searchfor)))
;; Misc
(b (get-buffer-create "*Semantic SymRef*"))
(ans nil)
diff --git a/lisp/cedet/semantic/symref/list.el b/lisp/cedet/semantic/symref/list.el
index 2e447bbc582..b1b36132b35 100644
--- a/lisp/cedet/semantic/symref/list.el
+++ b/lisp/cedet/semantic/symref/list.el
@@ -152,7 +152,7 @@ Display the references in `semantic-symref-results-mode'."
(easy-menu-define semantic-symref-list-menu
semantic-symref-results-mode-map
- "Symref Mode Menu"
+ "Symref Mode Menu."
semantic-symref-list-menu-entries)
(defcustom semantic-symref-auto-expand-results nil
diff --git a/lisp/cedet/semantic/tag-ls.el b/lisp/cedet/semantic/tag-ls.el
index 3aa1a62901c..4bdae58690a 100644
--- a/lisp/cedet/semantic/tag-ls.el
+++ b/lisp/cedet/semantic/tag-ls.el
@@ -130,7 +130,10 @@ are the same.
Similar tags that have sub-tags such as arg lists or type members,
are similar w/out checking the sub-list of tags.
-Optional argument IGNORABLE-ATTRIBUTES are attributes to ignore while comparing similarity.
+
+Optional argument IGNORABLE-ATTRIBUTES are attributes to ignore while comparing
+similarity.
+
By default, `semantic-tag-similar-ignorable-attributes' is referenced for
attributes, and IGNORABLE-ATTRIBUTES will augment this list.
@@ -191,11 +194,14 @@ See `semantic-tag-similar-p' for details."
;; will contain the info needed to determine the full name.
(define-overloadable-function semantic-tag-full-package (tag &optional stream-or-buffer)
"Return the fully qualified package name of TAG in a package hierarchy.
-STREAM-OR-BUFFER can be anything convertible by `semantic-something-to-tag-table',
-but must be a toplevel semantic tag stream that contains TAG.
+STREAM-OR-BUFFER can be anything convertible by
+`semantic-something-to-tag-table', but must be a toplevel
+semantic tag stream that contains TAG.
+
A Package Hierarchy is defined in UML by the way classes and methods
are organized on disk. Some languages use this concept such that a
class can be accessed via it's fully qualified name, (such as Java.)
+
Other languages qualify names within a Namespace (such as C++) which
result in a different package like structure.
@@ -214,11 +220,14 @@ Return the name of the first tag of class `package' in STREAM."
(define-overloadable-function semantic-tag-full-name (tag &optional stream-or-buffer)
"Return the fully qualified name of TAG in the package hierarchy.
-STREAM-OR-BUFFER can be anything convertible by `semantic-something-to-tag-table',
-but must be a toplevel semantic tag stream that contains TAG.
+STREAM-OR-BUFFER can be anything convertible by
+`semantic-something-to-tag-table', but must be a toplevel
+semantic tag stream that contains TAG.
+
A Package Hierarchy is defined in UML by the way classes and methods
are organized on disk. Some languages use this concept such that a
class can be accessed via it's fully qualified name, (such as Java.)
+
Other languages qualify names within a Namespace (such as C++) which
result in a different package like structure.
diff --git a/lisp/cedet/semantic/tag.el b/lisp/cedet/semantic/tag.el
index b6386d71db0..a86ed020bbb 100644
--- a/lisp/cedet/semantic/tag.el
+++ b/lisp/cedet/semantic/tag.el
@@ -119,8 +119,7 @@ Statement that represents a file from which more tags can be found.
Statement that declares this file's package name.
@item code
Code that has not name or binding to any other symbol, such as in a script.
-@end table
-"
+@end table"
(nth 1 tag))
(defsubst semantic-tag-attributes (tag)
@@ -703,7 +702,7 @@ It is safe for FILTER to modify the input tag and return it."
It is safe to modify ATTR, and return a permutation of that list.
-FILTER takes TAG as an argument, and should returns a semantic-tag.
+FILTER takes TAG as an argument, and should return a semantic-tag.
It is safe for FILTER to modify the input tag and return it."
(when (car attrs)
(when (not (symbolp (car attrs))) (error "Bad Attribute List in tag"))
@@ -716,7 +715,7 @@ It is safe for FILTER to modify the input tag and return it."
It is safe to modify VALUE, and return a permutation of that list.
-FILTER takes TAG as an argument, and should returns a semantic-tag.
+FILTER takes TAG as an argument, and should return a semantic-tag.
It is safe for FILTER to modify the input tag and return it."
(cond
;; Another tag.
@@ -735,7 +734,7 @@ It is safe for FILTER to modify the input tag and return it."
It is safe to modify the TAGS list, and return a permutation of that list.
-FILTER takes TAG as an argument, and should returns a semantic-tag.
+FILTER takes TAG as an argument, and should return a semantic-tag.
It is safe for FILTER to modify the input tag and return it."
(when (car tags)
(if (semantic-tag-p (car tags))
@@ -1309,12 +1308,12 @@ This function is overridable with the symbol `insert-foreign-tag'."
;;; Support log modes here
(define-mode-local-override semantic-insert-foreign-tag
log-edit-mode (foreign-tag)
- "Insert foreign tags into log-edit mode."
+ "Insert foreign tags into `log-edit' mode."
(insert (concat "(" (semantic-format-tag-name foreign-tag) "): ")))
(define-mode-local-override semantic-insert-foreign-tag
change-log-mode (foreign-tag)
- "Insert foreign tags into log-edit mode."
+ "Insert foreign tags into `log-edit' mode."
(insert (concat "(" (semantic-format-tag-name foreign-tag) "): ")))
diff --git a/lisp/cedet/semantic/util-modes.el b/lisp/cedet/semantic/util-modes.el
index 106862837a1..5ce1108044a 100644
--- a/lisp/cedet/semantic/util-modes.el
+++ b/lisp/cedet/semantic/util-modes.el
@@ -565,7 +565,7 @@ to indicate a parse in progress."
(easy-menu-define
semantic-stickyfunc-popup-menu
semantic-stickyfunc-mode-map
- "Stickyfunc Menu"
+ "Stickyfunc Menu."
'("Stickyfunc Mode" :visible (progn nil)
[ "Copy Headerline Tag" senator-copy-tag
:active (semantic-current-tag)
@@ -837,7 +837,7 @@ Used by `semantic-highlight-func-mode'.")
(easy-menu-define
semantic-highlight-func-popup-menu
semantic-highlight-func-mode-map
- "Highlight-Func Menu"
+ "Highlight-Func Menu."
'("Highlight-Func Mode" :visible (progn nil)
[ "Copy Tag" senator-copy-tag
:active (semantic-current-tag)
diff --git a/lisp/cedet/semantic/wisent.el b/lisp/cedet/semantic/wisent.el
index f5f381d4079..afcdd142822 100644
--- a/lisp/cedet/semantic/wisent.el
+++ b/lisp/cedet/semantic/wisent.el
@@ -66,7 +66,7 @@ Returned tokens must have the form:
(TOKSYM VALUE START . END)
where VALUE is the buffer substring between START and END positions."
- (declare (debug (&define name stringp def-body)))
+ (declare (debug (&define name stringp def-body)) (indent 1))
`(defun
,name () ,doc
(cond
diff --git a/lisp/cedet/semantic/wisent/python.el b/lisp/cedet/semantic/wisent/python.el
index fb878dde712..2eeade66467 100644
--- a/lisp/cedet/semantic/wisent/python.el
+++ b/lisp/cedet/semantic/wisent/python.el
@@ -118,9 +118,9 @@ curly braces."
;; look-ahead assertions.)
(when (and (= (- end start) 2)
(looking-at "\"\\{3\\}\\|'\\{3\\}"))
- (error "unterminated syntax"))
+ (error "Unterminated syntax"))
(goto-char end))
- (error "unterminated syntax")))
+ (error "Unterminated syntax")))
(defun wisent-python-forward-balanced-expression ()
"Move point to the end of the balanced expression at point.
@@ -145,7 +145,7 @@ triple-quoted string syntax."
;; delimiter (backquote) characters, line continuation, and end
;; of comment characters (AKA newline characters in Python).
((zerop (skip-syntax-forward "-w_.$\\>"))
- (error "can't figure out how to go forward from here"))))
+ (error "Can't figure out how to go forward from here"))))
;; Skip closing character. As a last resort this should raise an
;; error if we hit EOB before we find our closing character..
(forward-char 1)))
diff --git a/lisp/cedet/srecode/ctxt.el b/lisp/cedet/srecode/ctxt.el
index c49237b94cf..fe887c281c3 100644
--- a/lisp/cedet/srecode/ctxt.el
+++ b/lisp/cedet/srecode/ctxt.el
@@ -60,7 +60,7 @@ Some useful context values used by the provided srecode templates are:
\"pure\" - and those virtual items are pure virtual
\"type\" - In or near type declarations.
\"comment\" - In a comment in a block of code
- -- these items show up at the end of the context list. --
+ -- these items show up at the end of the context list. --
\"public\", \"protected\", \"private\" -
In or near a section of public/protected/private entries.
\"code\" - In a block of code.
diff --git a/lisp/cedet/srecode/dictionary.el b/lisp/cedet/srecode/dictionary.el
index 5da045e17f1..e47a09fd846 100644
--- a/lisp/cedet/srecode/dictionary.el
+++ b/lisp/cedet/srecode/dictionary.el
@@ -364,7 +364,7 @@ values but STATE is nil."
;; Value is some other object; create a compound value.
(t
(unless state
- (error "Cannot insert compound values without state."))
+ (error "Cannot insert compound values without state"))
(srecode-dictionary-set-value
dict name
@@ -410,7 +410,7 @@ OTHERDICT."
"Return information about DICT's value for NAME.
DICT is a dictionary, and NAME is a string that is treated as the
name of an entry in the dictionary. If such an entry exists, its
-value is returned. Otherwise, nil is returned. Normally, the
+value is returned. Otherwise, nil is returned. Normally, the
lookup is recursive in the sense that the parent of DICT is
searched for NAME if it is not found in DICT. This recursive
lookup can be disabled by the optional argument NON-RECURSIVE.
diff --git a/lisp/cedet/srecode/semantic.el b/lisp/cedet/srecode/semantic.el
index 101246cae6f..fbb6984dc15 100644
--- a/lisp/cedet/srecode/semantic.el
+++ b/lisp/cedet/srecode/semantic.el
@@ -201,7 +201,7 @@ variable default values, and other things."
(let ((tag (or srecode-semantic-selected-tag
(srecode-semantic-tag-from-kill-ring))))
(when (not tag)
- (error "No tag for current template. Use the semantic kill-ring."))
+ (error "No tag for current template. Use the semantic kill-ring"))
(srecode-semantic-apply-tag-to-dict
(srecode-semantic-tag (semantic-tag-name tag)
:prime tag)
diff --git a/lisp/char-fold.el b/lisp/char-fold.el
index 46a3f93d0af..b8e3d2f6791 100644
--- a/lisp/char-fold.el
+++ b/lisp/char-fold.el
@@ -20,10 +20,13 @@
;; 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:
(eval-and-compile
(put 'char-fold-table 'char-table-extra-slots 1)
+ (defconst char-fold--default-override nil)
(defconst char-fold--default-include
'((?\" """ "“" "”" "”" "„" "⹂" "〞" "‟" "‟" "❞" "❝" "❠" "“" "„" "〝" "〟" "🙷" "🙶" "🙸" "«" "»")
(?' "❟" "❛" "❜" "‘" "’" "‚" "‛" "‚" "󠀢" "❮" "❯" "‹" "›")
@@ -38,7 +41,8 @@
))
(defconst char-fold--default-symmetric nil)
(defvar char-fold--previous
- (list char-fold--default-include
+ (list char-fold--default-override
+ char-fold--default-include
char-fold--default-exclude
char-fold--default-symmetric)))
@@ -65,48 +69,50 @@
;; - A single char of the decomp might be allowed to match the
;; character.
;; Some examples in the comments below.
- (map-char-table
- (lambda (char decomp)
- (when (consp decomp)
- ;; Skip trivial cases like ?a decomposing to (?a).
- (unless (and (not (cdr decomp))
- (eq char (car decomp)))
- (if (symbolp (car decomp))
- ;; Discard a possible formatting tag.
- (setq decomp (cdr decomp))
- ;; If there's no formatting tag, ensure that char matches
- ;; its decomp exactly. This is because we want 'ä' to
- ;; match 'ä', but we don't want '¹' to match '1'.
- (aset equiv char
- (cons (apply #'string decomp)
- (aref equiv char))))
-
- ;; Allow the entire decomp to match char. If decomp has
- ;; multiple characters, this is done by adding an entry
- ;; to the alist of the first character in decomp. This
- ;; allows 'ff' to match 'ff', 'ä' to match 'ä', and '1' to
- ;; match '¹'.
- (let ((make-decomp-match-char
- (lambda (decomp char)
- (if (cdr decomp)
- (aset equiv-multi (car decomp)
- (cons (cons (apply #'string (cdr decomp))
- (regexp-quote (string char)))
- (aref equiv-multi (car decomp))))
- (aset equiv (car decomp)
- (cons (char-to-string char)
- (aref equiv (car decomp))))))))
- (funcall make-decomp-match-char decomp char)
- ;; Check to see if the first char of the decomposition
- ;; has a further decomposition. If so, add a mapping
- ;; back from that second decomposition to the original
- ;; character. This allows e.g. 'ι' (GREEK SMALL LETTER
- ;; IOTA) to match both the Basic Greek block and
- ;; Extended Greek block variants of IOTA +
- ;; diacritical(s). Repeat until there are no more
- ;; decompositions.
- (let ((dec decomp)
- next-decomp)
+ (unless (or (bound-and-true-p char-fold-override)
+ char-fold--default-override)
+ (map-char-table
+ (lambda (char decomp)
+ (when (consp decomp)
+ ;; Skip trivial cases like ?a decomposing to (?a).
+ (unless (and (not (cdr decomp))
+ (eq char (car decomp)))
+ (if (symbolp (car decomp))
+ ;; Discard a possible formatting tag.
+ (setq decomp (cdr decomp))
+ ;; If there's no formatting tag, ensure that char matches
+ ;; its decomp exactly. This is because we want 'ä' to
+ ;; match 'ä', but we don't want '¹' to match '1'.
+ (aset equiv char
+ (cons (apply #'string decomp)
+ (aref equiv char))))
+
+ ;; Allow the entire decomp to match char. If decomp has
+ ;; multiple characters, this is done by adding an entry
+ ;; to the alist of the first character in decomp. This
+ ;; allows 'ff' to match 'ff', 'ä' to match 'ä', and '1' to
+ ;; match '¹'.
+ (let ((make-decomp-match-char
+ (lambda (decomp char)
+ (if (cdr decomp)
+ (aset equiv-multi (car decomp)
+ (cons (cons (apply #'string (cdr decomp))
+ (regexp-quote (string char)))
+ (aref equiv-multi (car decomp))))
+ (aset equiv (car decomp)
+ (cons (char-to-string char)
+ (aref equiv (car decomp))))))))
+ (funcall make-decomp-match-char decomp char)
+ ;; Check to see if the first char of the decomposition
+ ;; has a further decomposition. If so, add a mapping
+ ;; back from that second decomposition to the original
+ ;; character. This allows e.g. 'ι' (GREEK SMALL LETTER
+ ;; IOTA) to match both the Basic Greek block and
+ ;; Extended Greek block variants of IOTA +
+ ;; diacritical(s). Repeat until there are no more
+ ;; decompositions.
+ (let ((dec decomp)
+ next-decomp)
(while dec
(setq next-decomp (char-table-range table (car dec)))
(when (consp next-decomp)
@@ -116,24 +122,24 @@
(car next-decomp)))
(funcall make-decomp-match-char (list (car next-decomp)) char)))
(setq dec next-decomp)))
- ;; Do it again, without the non-spacing characters.
- ;; This allows 'a' to match 'ä'.
- (let ((simpler-decomp nil)
- (found-one nil))
- (dolist (c decomp)
- (if (> (get-char-code-property c 'canonical-combining-class) 0)
- (setq found-one t)
- (push c simpler-decomp)))
- (when (and simpler-decomp found-one)
- (funcall make-decomp-match-char simpler-decomp char)
- ;; Finally, if the decomp only had one spacing
- ;; character, we allow this character to match the
- ;; decomp. This is to let 'a' match 'ä'.
- (unless (cdr simpler-decomp)
- (aset equiv (car simpler-decomp)
- (cons (apply #'string decomp)
- (aref equiv (car simpler-decomp)))))))))))
- table)
+ ;; Do it again, without the non-spacing characters.
+ ;; This allows 'a' to match 'ä'.
+ (let ((simpler-decomp nil)
+ (found-one nil))
+ (dolist (c decomp)
+ (if (> (get-char-code-property c 'canonical-combining-class) 0)
+ (setq found-one t)
+ (push c simpler-decomp)))
+ (when (and simpler-decomp found-one)
+ (funcall make-decomp-match-char simpler-decomp char)
+ ;; Finally, if the decomp only had one spacing
+ ;; character, we allow this character to match the
+ ;; decomp. This is to let 'a' match 'ä'.
+ (unless (cdr simpler-decomp)
+ (aset equiv (car simpler-decomp)
+ (cons (apply #'string decomp)
+ (aref equiv (car simpler-decomp)))))))))))
+ table))
;; Add some entries to default decomposition
(dolist (it (or (bound-and-true-p char-fold-include)
@@ -230,7 +236,9 @@ Exceptionally for the space character (32), ALIST is ignored.")
(defun char-fold-update-table ()
"Update char-fold-table only when one of the options changes its value."
- (let ((new (list (or (bound-and-true-p char-fold-include)
+ (let ((new (list (or (bound-and-true-p char-fold-override)
+ char-fold--default-override)
+ (or (bound-and-true-p char-fold-include)
char-fold--default-include)
(or (bound-and-true-p char-fold-exclude)
char-fold--default-exclude)
@@ -240,6 +248,22 @@ Exceptionally for the space character (32), ALIST is ignored.")
(setq char-fold-table (char-fold--make-table)
char-fold--previous new))))
+(defcustom char-fold-override char-fold--default-override
+ "Non-nil means to override the default definitions of equivalent characters.
+When nil (the default), the table of character equivalences used
+for character-folding is populated with the default set of equivalent
+characters; customize `char-fold-exclude' to remove unneeded equivalences,
+and `char-fold-include' to add your own.
+When this variable is non-nil, the table of equivalences starts empty,
+and you can add your own equivalences by customizing `char-fold-include'."
+ :type 'boolean
+ :initialize #'custom-initialize-default
+ :set (lambda (sym val)
+ (custom-set-default sym val)
+ (char-fold-update-table))
+ :group 'isearch
+ :version "29.1")
+
(defcustom char-fold-include char-fold--default-include
"Additional character foldings to include.
Each entry is a list of a character and the strings that fold into it."
diff --git a/lisp/cmuscheme.el b/lisp/cmuscheme.el
index 18087da9ac9..47113ad8c2e 100644
--- a/lisp/cmuscheme.el
+++ b/lisp/cmuscheme.el
@@ -33,15 +33,15 @@
;; merge them into the master source.
;;
;; NOTE: MIT Cscheme, when invoked with the -emacs flag, has a special user
-;; interface that communicates process state back to the superior emacs by
+;; interface that communicates process state back to the superior Emacs by
;; outputting special control sequences. The Emacs package, xscheme.el, has
;; lots and lots of special purpose code to read these control sequences, and
;; so is very tightly integrated with the cscheme process. The cscheme
;; interrupt handler and debugger read single character commands in cbreak
;; mode; when this happens, xscheme.el switches to special keymaps that bind
-;; the single letter command keys to emacs functions that directly send the
+;; the single letter command keys to Emacs functions that directly send the
;; character to the scheme process. Cmuscheme mode does *not* provide this
-;; functionality. If you are a cscheme user, you may prefer to use the
+;; functionality. If you are a cscheme user, you may prefer to use the
;; xscheme.el/cscheme -emacs interaction.
;;
;; Here's a summary of the pros and cons, as I see them.
@@ -159,7 +159,7 @@
The following commands are available:
\\{inferior-scheme-mode-map}
-A Scheme process can be fired up with M-x run-scheme.
+A Scheme process can be fired up with \\[run-scheme].
Customization: Entry to this mode runs the hooks on `comint-mode-hook' and
`inferior-scheme-mode-hook' (in that order).
@@ -186,7 +186,7 @@ Return before the end of the process' output copies the sexp ending at point
Delete converts tabs to spaces as it moves back.
Tab indents for Scheme; with argument, shifts rest
of expression rigidly with the current line.
-C-M-q does Tab on each line starting within following expression.
+\\[indent-pp-sexp] does Tab on each line starting within following expression.
Paragraphs are separated only by blank lines. Semicolons start comments.
If you accidentally suspend your process, use \\[comint-continue-subjob]
to continue it."
@@ -245,7 +245,8 @@ Search in the directories \"~\" and `user-emacs-directory',
in this order. Return nil if no start file found."
(let* ((progname (file-name-nondirectory prog))
(start-file (concat "~/.emacs_" progname))
- (alt-start-file (concat user-emacs-directory "init_" progname ".scm")))
+ (alt-start-file (locate-user-emacs-file
+ (concat "init_" progname ".scm"))))
(if (file-exists-p start-file)
start-file
(and (file-exists-p alt-start-file) alt-start-file))))
diff --git a/lisp/comint.el b/lisp/comint.el
index 7af8e8fd2a5..5f99f560cf3 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -191,7 +191,7 @@ wish to put something like the following in your init file:
(define-key comint-mode-map [remap kill-whole-line]
\\='comint-kill-whole-line)))
-If you sometimes use comint-mode on text-only terminals or with `emacs -nw',
+If you sometimes use `comint-mode' on text-only terminals or with `emacs -nw',
you might wish to use another binding for `comint-kill-whole-line'."
:type 'boolean
:group 'comint
@@ -372,6 +372,7 @@ This variable is buffer-local."
"\\(^ *\\|"
(regexp-opt
'("Enter" "enter" "Enter same" "enter same" "Enter the" "enter the"
+ "Current"
"Enter Auth" "enter auth" "Old" "old" "New" "new" "'s" "login"
"Kerberos" "CVS" "UNIX" " SMB" "LDAP" "PEM" "SUDO"
"[sudo]" "doas" "Repeat" "Bad" "Retype" "Verify")
@@ -381,10 +382,15 @@ This variable is buffer-local."
"\\(?:" (regexp-opt password-word-equivalents) "\\|Response\\)"
"\\(?:\\(?:, try\\)? *again\\| (empty for no passphrase)\\| (again)\\)?"
;; "[[:alpha:]]" used to be "for", which fails to match non-English.
- "\\(?: [[:alpha:]]+ .+\\)?[[:blank:]]*[::៖][[:space:]]*\\'")
+ "\\(?: [[:alpha:]]+ .+\\)?[[:blank:]]*[::៖][[:space:]]*\\'"
+ ;; The ccrypt encryption dialogue doesn't end with a colon, so
+ ;; treat it specially.
+ "\\|^Enter encryption key: (repeat) *\\'"
+ ;; openssh-8.6p1 format: "(user@host) Password:".
+ "\\|^([^)@ \t\n]+@[^)@ \t\n]+) Password: *\\'")
"Regexp matching prompts for passwords in the inferior process.
This is used by `comint-watch-for-password-prompt'."
- :version "28.1"
+ :version "29.1"
:type 'regexp
:group 'comint)
@@ -479,6 +485,15 @@ executed once, when the buffer is created."
:group 'comint
:version "26.1")
+(defconst comint-max-line-length
+ (pcase system-type
+ ('gnu/linux 4096)
+ ('windows-nt 8196)
+ (_ 1024))
+ "Maximum line length, in bytes, accepted by the inferior process.
+This setting is only meaningful when communicating with subprocesses
+via PTYs.")
+
(defvar comint-mode-map
(let ((map (make-sparse-keymap)))
;; Keys:
@@ -665,7 +680,8 @@ to continue it.
\\{comint-mode-map}
Entry to this mode runs the hooks on `comint-mode-hook'."
- (setq mode-line-process '(":%s"))
+ (setq mode-line-process
+ (list (propertize ":%s" 'help-echo "Process status")))
(setq-local window-point-insertion-type t)
(setq-local comint-last-input-start (point-min-marker))
(setq-local comint-last-input-end (point-min-marker))
@@ -714,6 +730,8 @@ Entry to this mode runs the hooks on `comint-mode-hook'."
(or (file-remote-p default-directory) ""))
(setq-local comint-accum-marker (make-marker))
(setq-local font-lock-defaults '(nil t))
+ (add-function :filter-return (local 'filter-buffer-substring-function)
+ #'comint--unmark-string-as-output)
(add-hook 'change-major-mode-hook 'font-lock-defontify nil t)
(add-hook 'isearch-mode-hook 'comint-history-isearch-setup nil t)
(add-hook 'completion-at-point-functions 'comint-completion-at-point nil t)
@@ -875,12 +893,13 @@ series of processes in the same Comint buffer. The hook
;; and there is no way for us to define it here.
;; Some programs that use terminfo get very confused
;; if TERM is not a valid terminal type.
- (if (and (boundp 'system-uses-terminfo) system-uses-terminfo)
- (list (format "TERM=%s" comint-terminfo-terminal)
- "TERMCAP="
- (format "COLUMNS=%d" (window-width)))
- (list "TERM=emacs"
- (format "TERMCAP=emacs:co#%d:tc=unknown:" (window-width)))))
+ (with-connection-local-variables
+ (if system-uses-terminfo
+ (list (format "TERM=%s" comint-terminfo-terminal)
+ "TERMCAP="
+ (format "COLUMNS=%d" (window-width)))
+ (list "TERM=emacs"
+ (format "TERMCAP=emacs:co#%d:tc=unknown:" (window-width))))))
(defun comint-nonblank-p (str)
"Return non-nil if STR contains non-whitespace syntax."
@@ -1798,7 +1817,8 @@ Ignore duplicates if `comint-input-ignoredups' is non-nil."
(ring-insert comint-input-ring cmd)))
(defconst comint--prompt-rear-nonsticky
- '(field inhibit-line-move-field-capture read-only font-lock-face)
+ '( field inhibit-line-move-field-capture read-only font-lock-face
+ insert-in-front-hooks)
"Text properties we set on the prompt and don't want to leak past it.")
(defun comint-send-input (&optional no-newline artificial)
@@ -1890,6 +1910,14 @@ Similarly for Soar, Scheme, etc."
(delete-region pmark start)
copy))))
+ ;; Delete and reinsert input. This seems like a no-op, except
+ ;; for the resulting entries in the undo list: undoing this
+ ;; insertion will delete the region, moving the process mark
+ ;; back to its original position.
+ (let ((inhibit-read-only t))
+ (delete-region pmark (point))
+ (insert input))
+
(unless no-newline
(insert ?\n))
@@ -1933,7 +1961,7 @@ Similarly for Soar, Scheme, etc."
;; in case we get output amidst sending the input.
(set-marker comint-last-input-start pmark)
(set-marker comint-last-input-end (point))
- (set-marker (process-mark proc) (point))
+ (set-marker pmark (point))
;; clear the "accumulation" marker
(set-marker comint-accum-marker nil)
(let ((comint-input-sender-no-newline no-newline))
@@ -1976,6 +2004,7 @@ Similarly for Soar, Scheme, etc."
;; This used to call comint-output-filter-functions,
;; but that scrolled the buffer in undesirable ways.
+ (set-marker comint-last-output-start pmark)
(run-hook-with-args 'comint-output-filter-functions "")))))
(defvar comint-preoutput-filter-functions nil
@@ -2126,14 +2155,7 @@ Make backspaces delete the previous character."
(goto-char (process-mark process)) ; In case a filter moved it.
(unless comint-use-prompt-regexp
- (with-silent-modifications
- (add-text-properties comint-last-output-start (point)
- `(rear-nonsticky
- ,comint--prompt-rear-nonsticky
- front-sticky
- (field inhibit-line-move-field-capture)
- field output
- inhibit-line-move-field-capture t))))
+ (comint--mark-as-output comint-last-output-start (point)))
;; Highlight the prompt, where we define `prompt' to mean
;; the most recent output that doesn't end with a newline.
@@ -2165,6 +2187,46 @@ Make backspaces delete the previous character."
,comint--prompt-rear-nonsticky)))
(goto-char saved-point)))))))
+(defun comint--mark-as-output (beg end)
+ (with-silent-modifications
+ (add-text-properties
+ beg end
+ `(rear-nonsticky
+ ,comint--prompt-rear-nonsticky
+ front-sticky
+ (field inhibit-line-move-field-capture)
+ field output
+ inhibit-line-move-field-capture t
+ ;; Text inserted by a user in the middle of process output
+ ;; should be marked as output. This is needed for commands
+ ;; such as `yank' or `just-one-space' which don't use
+ ;; `insert-and-inherit' and thus bypass default text property
+ ;; inheritance.
+ insert-in-front-hooks
+ (,#'comint--mark-as-output ,#'comint--mark-yanked-as-output)))))
+
+(defun comint--mark-yanked-as-output (beg end)
+ ;; `yank' removes the field text property from the text it inserts
+ ;; due to `yank-excluded-properties', so arrange for this text
+ ;; property to be reapplied in the `after-change-functions'.
+ (let (fun)
+ (setq
+ fun
+ (lambda (beg1 end1 _len1)
+ (remove-hook 'after-change-functions fun t)
+ (when (and (= beg beg1)
+ (= end end1))
+ (comint--mark-as-output beg1 end1))))
+ (add-hook 'after-change-functions fun nil t)))
+
+(defun comint--unmark-string-as-output (string)
+ (remove-list-of-text-properties
+ 0 (length string)
+ '( rear-nonsticky front-sticky field
+ inhibit-line-move-field-capture insert-in-front-hooks)
+ string)
+ string)
+
(defun comint-preinput-scroll-to-bottom ()
"Go to the end of buffer in all windows showing it.
Movement occurs if point in the selected window is not after the process mark,
@@ -2440,11 +2502,19 @@ This function could be in the list `comint-output-filter-functions'."
(when (let ((case-fold-search t))
(string-match comint-password-prompt-regexp
(string-replace "\r" "" string)))
- (let ((comint--prompt-recursion-depth (1+ comint--prompt-recursion-depth)))
- (if (> comint--prompt-recursion-depth 10)
- (message "Password prompt recursion too deep")
- (comint-send-invisible
- (string-trim string "[ \n\r\t\v\f\b\a]+" "\n+"))))))
+ ;; Use `run-at-time' in order not to pause execution of the
+ ;; process filter with a minibuffer
+ (run-at-time
+ 0 nil
+ (lambda (current-buf)
+ (with-current-buffer current-buf
+ (let ((comint--prompt-recursion-depth
+ (1+ comint--prompt-recursion-depth)))
+ (if (> comint--prompt-recursion-depth 10)
+ (message "Password prompt recursion too deep")
+ (comint-send-invisible
+ (string-trim string "[ \n\r\t\v\f\b\a]+" "\n+"))))))
+ (current-buffer))))
;; Low-level process communication
@@ -2820,7 +2890,7 @@ if necessary."
(when (>= count 0) (comint-update-fence))))
(defun comint-kill-region (beg end)
- "Like `kill-region', but ignores read-only properties, if safe.
+ "Like `kill-region', but ignore read-only properties, if safe.
This command assumes that the buffer contains read-only
\"prompts\" which are regions with front-sticky read-only
properties at the beginning of a line, with the preceding newline
@@ -3494,6 +3564,20 @@ to send all the accumulated input, at once.
The entire accumulated text becomes one item in the input history
when you send it."
(interactive)
+ (when-let* ((proc (get-buffer-process (current-buffer)))
+ (pmark (process-mark proc))
+ ((or (marker-position comint-accum-marker)
+ (set-marker comint-accum-marker pmark)
+ t))
+ ((>= (point) comint-accum-marker pmark)))
+ ;; Delete and reinsert input. This seems like a no-op, except for
+ ;; the resulting entries in the undo list: undoing this insertion
+ ;; will delete the region, moving the accumulation marker back to
+ ;; its original position.
+ (let ((text (buffer-substring comint-accum-marker (point)))
+ (inhibit-read-only t))
+ (delete-region comint-accum-marker (point))
+ (insert text)))
(insert "\n")
(set-marker comint-accum-marker (point))
(if comint-input-ring-index
@@ -3887,6 +3971,112 @@ REGEXP-GROUP is the regular expression group in REGEXP to use."
;; don't advance, so ensure forward progress.
(forward-line 1)))
(nreverse results))))
+
+
+;;; OSC escape sequences (Operating System Commands)
+;;============================================================================
+;; Adding `comint-osc-process-output' to `comint-output-filter-functions'
+;; enables the interpretation of OSC escape sequences. By default, only
+;; OSC 8, for hyperlinks, is acted upon. Adding more entries 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)
+
+(defun comint-osc-process-output (_)
+ "Interpret OSC escape sequences in comint output.
+This function is intended to be added to
+`comint-output-filter-functions' in order to interpret escape
+sequences of the forms
+
+ ESC ] command ; text BEL
+ ESC ] command ; text ESC \\
+
+Specifically, every occurrence of such escape sequences is
+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-parse.el")
+(declare-function url-type "url-parse.el")
+(declare-function url-filename "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)))))
+
;;; Converting process modes to use comint mode
;;============================================================================
diff --git a/lisp/completion.el b/lisp/completion.el
index 93a869e86f4..a77cccde643 100644
--- a/lisp/completion.el
+++ b/lisp/completion.el
@@ -178,7 +178,7 @@
;; Inserts a completion at point
;;
;; completion-initialize
-;; Loads the completions file and sets up so that exiting emacs will
+;; Loads the completions file and sets up so that exiting Emacs will
;; save them.
;;
;; save-completions-to-file &optional filename
@@ -207,7 +207,7 @@
;; Add package prefix smarts (for Common Lisp)
;; Add autoprompting of possible completions after every keystroke (fast
;; terminals only !)
-;; Add doc. to texinfo
+;; Add documentation to texinfo
;;
;;
;;-----------------------------------------------
@@ -492,7 +492,7 @@ Used to decide whether to save completions.")
table))
;; Old name, non-namespace-clean.
-(defvaralias 'cmpl-syntax-table 'completion-syntax-table)
+(define-obsolete-variable-alias 'cmpl-syntax-table 'completion-syntax-table "29.1")
(defvar-local completion-syntax-table completion-standard-syntax-table
"This variable holds the current completion syntax table.")
@@ -1088,7 +1088,8 @@ Must be called after `find-exact-completion'."
#'completion-locate-db-error "27.1")
(defun completion-locate-db-error ()
;; recursive error: really scrod
- (error "Completion database corrupted. Try M-x clear-all-completions. Send bug report"))
+ (error (substitute-command-keys
+ "Completion database corrupted. Try \\[clear-all-completions]. Send bug report")))
;; WRITES
(defun add-completion-to-tail-if-new (string)
@@ -2219,7 +2220,7 @@ TYPE is the type of the wrapper to be added. Can be :before or :under."
(completion-def-wrapper 'delete-backward-char-untabify :backward)
;; Old name, non-namespace-clean.
-(defalias 'initialize-completions #'completion-initialize)
+(define-obsolete-function-alias 'initialize-completions #'completion-initialize "29.1")
(provide 'completion)
diff --git a/lisp/composite.el b/lisp/composite.el
index 6f654df15aa..c2289e8998f 100644
--- a/lisp/composite.el
+++ b/lisp/composite.el
@@ -815,6 +815,35 @@ prepending a space before it."
(setq i (1+ i)))))))
gstring))
+(defun compose-gstring-for-variation-glyph (gstring _direction)
+ "Compose glyph-string GSTRING for graphic display.
+GSTRING must have two glyphs; the first is a glyph for a han character,
+and the second is a glyph for a variation selector."
+ (let* ((font (lgstring-font gstring))
+ (han (lgstring-char gstring 0))
+ (vs (lgstring-char gstring 1))
+ (glyphs (font-variation-glyphs font han))
+ (g0 (lgstring-glyph gstring 0))
+ (g1 (lgstring-glyph gstring 1)))
+ (catch 'tag
+ (dolist (elt glyphs)
+ (if (= (car elt) vs)
+ (progn
+ (lglyph-set-code g0 (cdr elt))
+ (lglyph-set-from-to g0 (lglyph-from g0) (lglyph-to g1))
+ (lgstring-set-glyph gstring 1 nil)
+ (throw 'tag gstring)))))))
+
+;; We explicitly don't handle #xFE0F (VS-16) here, because that's
+;; taken care of by font_range in font.c, which will check for an
+;; emoji font for codepoints used in compositions even if they're not
+;; emoji themselves, and thus choose the Emoji presentation for them
+;; when followed by VS-16. VS-15 *is* handled here, because if it's
+;; handled in font_range, we end up choosing the Emoji presentation
+;; rather than the Text presentation.
+(let ((elt '([".." 1 compose-gstring-for-variation-glyph])))
+ (set-char-table-range composition-function-table '(#xFE00 . #xFE0E) elt)
+ (set-char-table-range composition-function-table '(#xE0100 . #xE01EF) elt))
(defun auto-compose-chars (func from to font-object string direction)
"Compose the characters at FROM by FUNC.
@@ -864,7 +893,7 @@ Auto Composition mode in all buffers (this is the default)."
"Toggle Auto Composition mode in all buffers.
For more information on Auto Composition mode, see
-`auto-composition-mode' ."
+`auto-composition-mode'."
:global t
:variable (default-value 'auto-composition-mode))
@@ -872,6 +901,4 @@ For more information on Auto Composition mode, see
(provide 'composite)
-
-
;;; composite.el ends here
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index 7eae2e416bb..ae71140e262 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -1133,7 +1133,7 @@ for the MODE to customize."
(defun customize-read-group ()
(let ((completion-ignore-case t))
- (completing-read "Customize group (default emacs): "
+ (completing-read (format-prompt "Customize group" "emacs")
obarray
(lambda (symbol)
(or (and (get symbol 'custom-loads)
@@ -1205,7 +1205,7 @@ Show the buffer in another window, but don't select it."
(unless (eq symbol basevar)
(message "`%s' is an alias for `%s'" symbol basevar))))
-(defvar customize-changed-options-previous-release "26.3"
+(defvar customize-changed-options-previous-release "28.1"
"Version for `customize-changed' to refer back to by default.")
;; Packages will update this variable, so make it available.
@@ -2176,7 +2176,7 @@ and `face'."
;;; The `custom' Widget.
(defface custom-button
- '((((type x w32 ns) (class color)) ; Like default mode line
+ '((((type x w32 ns haiku pgtk) (class color)) ; Like default mode line
:box (:line-width 2 :style released-button)
:background "lightgrey" :foreground "black"))
"Face for custom buffer buttons if `custom-raised-buttons' is non-nil."
@@ -2184,7 +2184,7 @@ and `face'."
:group 'custom-faces)
(defface custom-button-mouse
- '((((type x w32 ns) (class color))
+ '((((type x w32 ns haiku pgtk) (class color))
:box (:line-width 2 :style released-button)
:background "grey90" :foreground "black")
(t
@@ -2209,7 +2209,7 @@ and `face'."
(if custom-raised-buttons 'custom-button-mouse 'highlight))
(defface custom-button-pressed
- '((((type x w32 ns) (class color))
+ '((((type x w32 ns haiku pgtk) (class color))
:box (:line-width 2 :style pressed-button)
:background "lightgrey" :foreground "black")
(t :inverse-video t))
@@ -3458,6 +3458,10 @@ MS Windows.")
:sibling-args (:help-echo "\
GNUstep or Macintosh OS Cocoa interface.")
ns)
+ (const :format "PGTK "
+ :sibling-args (:help-echo "\
+Pure-GTK interface.")
+ ns)
(const :format "DOS "
:sibling-args (:help-echo "\
Plain MS-DOS.")
@@ -4646,8 +4650,8 @@ You can set this option through Custom, if you carefully read the
last paragraph below. However, usually it is simpler to write
something like the following in your init file:
-\(setq custom-file \"~/.emacs-custom.el\")
-\(load custom-file)
+(setq custom-file \"~/.config/emacs-custom.el\")
+(load custom-file)
Note that both lines are necessary: the first line tells Custom to
save all customizations in this file, but does not load it.
@@ -5123,8 +5127,8 @@ If several parents are listed, go to the first of them."
The following commands are available:
\\<widget-keymap>\
-Move to next button, link or editable field. \\[widget-forward]
-Move to previous button, link or editable field. \\[widget-backward]
+Move to next button, link or editable field. \\[widget-forward]
+Move to previous button, link or editable field. \\[widget-backward]
\\<custom-field-keymap>\
Complete content of editable text field. \\[widget-complete]
\\<custom-mode-map>\
diff --git a/lisp/cus-face.el b/lisp/cus-face.el
index 6c0052bf860..c78a327fdfa 100644
--- a/lisp/cus-face.el
+++ b/lisp/cus-face.el
@@ -31,6 +31,9 @@
(defun custom-declare-face (face spec doc &rest args)
"Like `defface', but with FACE evaluated as a normal argument."
+ (when (and doc
+ (not (stringp doc)))
+ (error "Invalid (or missing) doc string %S" doc))
(unless (get face 'face-defface-spec)
(face-spec-set face (purecopy spec) 'face-defface-spec)
(push (cons 'defface face) current-load-list)
@@ -51,6 +54,7 @@
(string :tag "Font Foundry"
:help-echo "Font foundry name."))
+ ;; The width, weight, and slant should be in sync with font.c.
(:width
(choice :tag "Width"
:help-echo "Font width."
@@ -60,15 +64,21 @@
(const :tag "demiexpanded" semi-expanded)
(const :tag "expanded" expanded)
(const :tag "extracondensed" extra-condensed)
+ (const :tag "extra-condensed" extra-condensed)
(const :tag "extraexpanded" extra-expanded)
- (const :tag "medium" normal)
+ (const :tag "extra-expanded" extra-expanded)
(const :tag "narrow" condensed)
(const :tag "normal" normal)
+ (const :tag "medium" normal)
(const :tag "regular" normal)
(const :tag "semicondensed" semi-condensed)
+ (const :tag "demicondensed" semi-condensed)
+ (const :tag "semi-condensed" semi-condensed)
(const :tag "semiexpanded" semi-expanded)
(const :tag "ultracondensed" ultra-condensed)
+ (const :tag "ultra-condensed" ultra-condensed)
(const :tag "ultraexpanded" ultra-expanded)
+ (const :tag "ultra-expanded" ultra-expanded)
(const :tag "wide" extra-expanded)))
(:height
@@ -82,22 +92,32 @@
(choice :tag "Weight"
:help-echo "Font weight."
:value normal ; default
+ (const :tag "thin" thin)
(const :tag "ultralight" ultra-light)
- (const :tag "extralight" extra-light)
+ (const :tag "ultra-light" ultra-light)
+ (const :tag "extralight" ultra-light)
+ (const :tag "extra-light" ultra-light)
(const :tag "light" light)
- (const :tag "thin" thin)
(const :tag "semilight" semi-light)
- (const :tag "book" semi-light)
+ (const :tag "semi-light" semi-light)
+ (const :tag "demilight" semi-light)
(const :tag "normal" normal)
- (const :tag "regular" normal)
- (const :tag "medium" normal)
+ (const :tag "regular" regular)
+ (const :tag "book" normal)
+ (const :tag "medium" medium)
(const :tag "semibold" semi-bold)
+ (const :tag "semi-bold" semi-bold)
(const :tag "demibold" semi-bold)
+ (const :tag "demi-bold" semi-bold)
(const :tag "bold" bold)
(const :tag "extrabold" extra-bold)
- (const :tag "heavy" extra-bold)
- (const :tag "ultrabold" ultra-bold)
- (const :tag "black" ultra-bold)))
+ (const :tag "extra-bold" extra-bold)
+ (const :tag "ultrabold" extra-bold)
+ (const :tag "ultra-bold" extra-bold)
+ (const :tag "heavy" heavy)
+ (const :tag "black" heavy)
+ (const :tag "ultra-heavy" ultra-heavy)
+ (const :tag "ultraheavy" ultra-heavy)))
(:slant
(choice :tag "Slant"
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index 19975307894..579beae123f 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -171,6 +171,8 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of
(const :tag "Right to Left" right-to-left)
(const :tag "Dynamic, according to paragraph text" nil))
"24.1")
+ (delete-auto-save-files auto-save boolean)
+ (kill-buffer-delete-auto-save-files auto-save boolean "28.1")
;; callint.c
(mark-even-if-inactive editing-basics boolean)
;; callproc.c
@@ -384,7 +386,7 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of
(const :tag "When sent SIGUSR1" sigusr1)
(const :tag "When sent SIGUSR2" sigusr2))
"24.1")
-
+ (translate-upper-case-key-bindings keyboard boolean "29.1")
;; This is not good news because it will use the wrong
;; version-specific directories when you upgrade. We need
;; customization of the front of the list, maintaining the
@@ -570,8 +572,10 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of
(ns-use-native-fullscreen ns boolean "24.4")
(ns-use-fullscreen-animation ns boolean "25.1")
(ns-use-srgb-colorspace ns boolean "24.4")
+ (ns-scroll-event-delta-factor ns float "29.1")
;; process.c
(delete-exited-processes processes-basics boolean)
+ (process-error-pause-time processes-basics integer "29.1")
;; syntax.c
(parse-sexp-ignore-comments editing-basics boolean)
(words-include-escapes editing-basics boolean)
@@ -824,10 +828,15 @@ since it could result in memory overflow and make Emacs crash."
(x-underline-at-descent-line display boolean "22.1")
(x-stretch-cursor display boolean "21.1")
(scroll-bar-adjust-thumb-portion windows boolean "24.4")
+ (x-scroll-event-delta-factor mouse float "29.1")
;; xselect.c
(x-select-enable-clipboard-manager killing boolean "24.1")
;; xsettings.c
- (font-use-system-font font-selection boolean "23.2")))
+ (font-use-system-font font-selection boolean "23.2")
+ ;; haikuterm.c
+ (haiku-debug-on-fatal-error debug boolean "29.1")
+ ;; haikufns.c
+ (haiku-use-system-tooltips tooltip boolean "29.1")))
(setq ;; If we did not specify any standard value expression above,
;; use the current value as the standard value.
standard (if (setq prop (memq :standard rest))
@@ -844,10 +853,17 @@ since it could result in memory overflow and make Emacs crash."
(eq system-type 'windows-nt))
((string-match "\\`ns-" (symbol-name symbol))
(featurep 'ns))
+ ((string-match "\\`haiku-" (symbol-name symbol))
+ (featurep 'haiku))
((string-match "\\`x-.*gtk" (symbol-name symbol))
(featurep 'gtk))
((string-match "clipboard-manager" (symbol-name symbol))
(boundp 'x-select-enable-clipboard-manager))
+ ((or (equal "scroll-bar-adjust-thumb-portion"
+ (symbol-name symbol))
+ (equal "x-scroll-event-delta-factor"
+ (symbol-name symbol)))
+ (featurep 'x))
((string-match "\\`x-" (symbol-name symbol))
(fboundp 'x-create-frame))
((string-match "selection" (symbol-name symbol))
@@ -868,9 +884,6 @@ since it could result in memory overflow and make Emacs crash."
(symbol-name symbol))
;; Any function from fontset.c will do.
(fboundp 'new-fontset))
- ((equal "scroll-bar-adjust-thumb-portion"
- (symbol-name symbol))
- (featurep 'x))
(t t))))
(if (not (boundp symbol))
;; If variables are removed from C code, give an error here!
diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el
index 7457d9e3236..f618e3341cb 100644
--- a/lisp/cus-theme.el
+++ b/lisp/cus-theme.el
@@ -22,6 +22,8 @@
;; 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 'widget)
@@ -625,22 +627,24 @@ Theme files are named *-theme.el in `"))
(let ((help-echo "mouse-2: Enable this theme for this session")
widget)
(dolist (theme (custom-available-themes))
- (setq widget (widget-create 'checkbox
- :value (custom-theme-enabled-p theme)
- :theme-name theme
- :help-echo help-echo
- :action #'custom-theme-checkbox-toggle))
- (push (cons theme widget) custom--listed-themes)
- (widget-create-child-and-convert widget 'push-button
- :button-face-get 'ignore
- :mouse-face-get 'ignore
- :value (format " %s" theme)
- :action #'widget-parent-action
- :help-echo help-echo)
- (widget-insert " -- "
- (propertize (custom-theme-summary theme)
- 'face 'shadow)
- ?\n)))
+ ;; Don't list obsolete themes.
+ (unless (get theme 'byte-obsolete-info)
+ (setq widget (widget-create 'checkbox
+ :value (custom-theme-enabled-p theme)
+ :theme-name theme
+ :help-echo help-echo
+ :action #'custom-theme-checkbox-toggle))
+ (push (cons theme widget) custom--listed-themes)
+ (widget-create-child-and-convert widget 'push-button
+ :button-face-get 'ignore
+ :mouse-face-get 'ignore
+ :value (format " %s" theme)
+ :action #'widget-parent-action
+ :help-echo help-echo)
+ (widget-insert " -- "
+ (propertize (custom-theme-summary theme)
+ 'face 'shadow)
+ ?\n))))
(goto-char (point-min))
(widget-setup))
diff --git a/lisp/custom.el b/lisp/custom.el
index f392bd8d369..9252e80411f 100644
--- a/lisp/custom.el
+++ b/lisp/custom.el
@@ -364,7 +364,8 @@ call that function directly.
See Info node `(elisp) Customization' in the Emacs Lisp manual
for more information."
- (declare (doc-string 3) (debug (name body)))
+ (declare (doc-string 3) (debug (name body))
+ (indent defun))
;; 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.
@@ -378,7 +379,7 @@ for more information."
;; expression is checked by the byte-compiler, and that
;; lexical-binding is obeyed, so quote the expression with
;; `lambda' rather than with `quote'.
- ``(funcall #',(lambda () ,standard))
+ ``(funcall #',(lambda () "" ,standard))
`',standard)
,doc
,@args))
@@ -447,7 +448,7 @@ In the ATTS property list, possible attributes are `:family',
See Info node `(elisp) Faces' in the Emacs Lisp manual for more
information."
- (declare (doc-string 3))
+ (declare (doc-string 3) (indent defun))
;; 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.
@@ -507,11 +508,15 @@ The remaining arguments should have the form
[KEYWORD VALUE]...
For a list of valid keywords, see the common keywords listed in
-`defcustom'.
+`defcustom'. The keyword :prefix can only be used for
+customization groups, and means that the given string should be
+removed from variable names before creating unlispified names,
+when the user option `custom-unlispify-remove-prefixes' is
+non-nil.
See Info node `(elisp) Customization' in the Emacs Lisp manual
for more information."
- (declare (doc-string 3))
+ (declare (doc-string 3) (indent defun))
;; 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.
@@ -1131,29 +1136,24 @@ list, in which A occurs before B if B was defined with a
;; (provide-theme 'THEME)
-;; The IGNORED arguments to deftheme come from the XEmacs theme code, where
-;; they were used to supply keyword-value pairs like `:immediate',
-;; `:variable-reset-string', etc. We don't use any of these, so ignore them.
-
-(defmacro deftheme (theme &optional doc &rest _ignored)
+(defmacro deftheme (theme &optional doc)
"Declare THEME to be a Custom theme.
The optional argument DOC is a doc string describing the theme.
Any theme `foo' should be defined in a file called `foo-theme.el';
see `custom-make-theme-feature' for more information."
(declare (doc-string 2)
- (advertised-calling-convention (theme &optional doc) "22.1"))
+ (indent 1))
(let ((feature (custom-make-theme-feature theme)))
;; 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)))
-(defun custom-declare-theme (theme feature &optional doc &rest _ignored)
+(defun custom-declare-theme (theme feature &optional doc)
"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'."
- (declare (advertised-calling-convention (theme feature &optional doc) "22.1"))
(unless (custom-theme-name-valid-p theme)
(error "Custom theme cannot be named %S" theme))
(unless (memq theme custom-known-themes)
@@ -1331,6 +1331,13 @@ Return t if THEME was successfully loaded, nil otherwise."
t))))
(t
(error "Unable to load theme `%s'" theme))))
+ (when-let ((obs (get theme 'byte-obsolete-info)))
+ (display-warning 'initialization
+ (format "The `%s' theme is obsolete%s"
+ theme
+ (if (nth 2 obs)
+ (format " since Emacs %s" (nth 2 obs))
+ ""))))
;; Optimization: if the theme changes the `default' face, put that
;; entry first. This avoids some `frame-set-background-mode' rigmarole
;; by assigning the new background immediately.
diff --git a/lisp/dabbrev.el b/lisp/dabbrev.el
index e113cc94c33..037787797bb 100644
--- a/lisp/dabbrev.el
+++ b/lisp/dabbrev.el
@@ -568,8 +568,7 @@ See also `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]."
major-mode)))
(defun dabbrev--goto-start-of-abbrev ()
- "Back over all abbrev type characters and then moves forward over
-all skip characters."
+ "Back over all abbrev type characters then move forward over all skip characters."
;; Move backwards over abbrev chars
(save-match-data
(when (> (point) (minibuffer-prompt-end))
diff --git a/lisp/delim-col.el b/lisp/delim-col.el
index cd945d8de45..ac78e568da2 100644
--- a/lisp/delim-col.el
+++ b/lisp/delim-col.el
@@ -5,7 +5,7 @@
;; Author: Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>
;; Old-Version: 2.1
;; Keywords: convenience text
-;; X-URL: https://www.emacswiki.org/emacs/ViniciusJoseLatorre
+;; URL: https://www.emacswiki.org/emacs/ViniciusJoseLatorre
;; This file is part of GNU Emacs.
@@ -276,7 +276,7 @@ See the `delimit-columns-str-before',
`delimit-columns-before', `delimit-columns-after',
`delimit-columns-separator', `delimit-columns-format' and
`delimit-columns-extra' variables for customization of the
-look. "
+look."
(interactive "*r")
(if rectangle-mark-mode
;; Delegate to delimit-columns-rectangle when called with a
diff --git a/lisp/descr-text.el b/lisp/descr-text.el
index f5e467d37e7..2a239f81002 100644
--- a/lisp/descr-text.el
+++ b/lisp/descr-text.el
@@ -97,7 +97,7 @@ into help buttons that call `describe-text-category' or
;;; Describe-Text Commands.
(defun describe-text-category (category)
- "Describe a text property category."
+ "Describe a text property CATEGORY."
(interactive "SCategory: ")
(help-setup-xref (list #'describe-text-category category)
(called-interactively-p 'interactive))
@@ -417,6 +417,7 @@ The character information includes:
(display-table (or (window-display-table)
buffer-display-table
standard-display-table))
+ (composition-string nil)
(disp-vector (and display-table (aref display-table char)))
(multibyte-p enable-multibyte-characters)
(overlays (mapcar (lambda (o) (overlay-properties o))
@@ -538,7 +539,8 @@ The character information includes:
(setcar composition nil)))
(setcar (cdr composition)
(format "composed to form \"%s\" (see below)"
- (buffer-substring from to)))))
+ (setq composition-string
+ (buffer-substring from to))))))
(setq composition nil)))
(setq item-list
@@ -677,11 +679,16 @@ The character information includes:
(let ((display (describe-char-display pos char)))
(if (display-graphic-p (selected-frame))
(if display
- (concat "by this font (glyph code)\n " display)
+ (concat "by this font (glyph code):\n " display)
"no font available")
(if display
(format "terminal code %s" display)
"not encodable for terminal"))))))
+ ,@(when-let ((composition-name
+ (and composition-string
+ (eq (aref char-script-table char) 'emoji)
+ (emoji-describe composition-string))))
+ (list (list "composition name" composition-name)))
,@(let ((face
(if (not (or disp-vector composition))
(cond
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 0b8c693b29f..5301a3a27ff 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -444,10 +444,10 @@ List has a form of (file-name full-file-name (attribute-list))."
((eq op-symbol 'chgrp)
(file-attribute-group-id
(file-attributes default-file 'string))))))
- (prompt (concat "Change " attribute-name " of %s to"
- (if (eq op-symbol 'touch)
- " (default now): "
- ": ")))
+ (prompt (format-prompt "Change %s of %%s to"
+ (when (eq op-symbol 'touch)
+ "now")
+ attribute-name))
(new-attribute (dired-mark-read-string prompt nil op-symbol
arg files default
(cond ((eq op-symbol 'chown)
@@ -493,8 +493,7 @@ are supported. Type M-n to pull the file attributes of the file
at point into the minibuffer.
See Info node `(coreutils)File permissions' for more information.
-Alternatively, see the man page for \"chmod\", using the command
-\\[man] in Emacs.
+Alternatively, see the man page for \"chmod(1)\".
Note that on MS-Windows only the `w' (write) bit is meaningful:
resetting it makes the file read-only. Changing any other bit
@@ -993,12 +992,14 @@ prompted for the shell command to use interactively."
(defun dired-check-process (msg program &rest arguments)
- "Display MSG while running PROGRAM, and check for output.
-Remaining arguments are strings passed as command arguments to PROGRAM.
-On error, insert output
-in a log buffer and return the offending ARGUMENTS or PROGRAM.
-Caller can cons up a list of failed args.
-Else returns nil for success."
+ "Display MSG, then run PROGRAM, and log any error messages from it.
+ARGUMENTS should be strings to be passed to PROGRAM as command-line
+arguments.
+
+If PROGRAM exits successfully, display \"MSG...done\" and return nil.
+If PROGRAM exits abnormally, save in `dired-log-buffer' the command
+that invoked PROGRAM and the messages it emitted, and return either
+the offending ARGUMENTS or PROGRAM if no ARGUMENTS were provided."
(let (err-buffer err (dir default-directory))
(message "%s..." msg)
(save-excursion
@@ -1008,6 +1009,7 @@ Else returns nil for success."
(erase-buffer)
(setq default-directory dir ; caller's default-directory
err (not (eq 0 (apply #'process-file program nil t nil arguments))))
+ (dired-uncache dir)
(if err
(progn
(dired-log (concat program " " (prin1-to-string arguments) "\n"))
@@ -1033,6 +1035,7 @@ Return the result of `process-file' - zero for success."
nil
shell-command-switch
cmd)))
+ (dired-uncache dir)
(unless (zerop res)
(pop-to-buffer out-buffer))
res))))
@@ -1137,12 +1140,12 @@ present. A FMT of \"\" will suppress the messaging."
("\\.tar\\.gz\\'" "" "gzip -dc %i | tar -xf -")
("\\.tar\\.xz\\'" "" "xz -dc %i | tar -xf -")
("\\.tgz\\'" "" "gzip -dc %i | tar -xf -")
- ("\\.gz\\'" "" "gunzip")
+ ("\\.gz\\'" "" "gzip -d")
("\\.lz\\'" "" "lzip -d")
("\\.Z\\'" "" "uncompress")
;; For .z, try gunzip. It might be an old gzip file,
;; or it might be from compact? pack? (which?) but gunzip handles both.
- ("\\.z\\'" "" "gunzip")
+ ("\\.z\\'" "" "gzip -d")
("\\.dz\\'" "" "dictunzip")
("\\.tbz\\'" ".tar" "bunzip2")
("\\.bz2\\'" "" "bunzip2")
@@ -1245,7 +1248,7 @@ and `dired-compress-files-alist'."
(?i . ,(mapconcat
(lambda (in-file)
(shell-quote-argument
- (file-name-nondirectory in-file)))
+ (file-relative-name in-file)))
in-files " "))))))
(message (ngettext "Compressed %d file to %s"
"Compressed %d files to %s"
@@ -1281,9 +1284,9 @@ Return nil if no change in files."
(prog1 (setq newname (file-name-as-directory newname))
(dired-shell-command
(replace-regexp-in-string
- "%o" (shell-quote-argument newname)
+ "%o" (shell-quote-argument (file-local-name newname))
(replace-regexp-in-string
- "%i" (shell-quote-argument file)
+ "%i" (shell-quote-argument (file-local-name file))
command
nil t)
nil t)))
@@ -1294,10 +1297,10 @@ Return nil if no change in files."
(dired-check-process msg
(substring command 0 match)
(substring command (1+ match))
- file)
+ (file-local-name file))
(dired-check-process msg
command
- file))
+ (file-local-name file)))
newname))))
(t
;; We don't recognize the file as compressed, so compress it.
@@ -1315,7 +1318,8 @@ Return nil if no change in files."
(default-directory (file-name-directory file)))
(dired-shell-command
(replace-regexp-in-string
- "%o" (shell-quote-argument out-name)
+ "%o" (shell-quote-argument
+ (file-local-name out-name))
(replace-regexp-in-string
"%i" (shell-quote-argument
(file-name-nondirectory file))
@@ -1326,7 +1330,7 @@ Return nil if no change in files."
(user-error
"No compression rule found for \
`dired-compress-directory-default-suffix' %s, see `dired-compress-files-alist' for\
- the supported suffixes list."
+ the supported suffixes list"
dired-compress-directory-default-suffix)))
(let* ((suffix (or dired-compress-file-default-suffix ".gz"))
(out-name (concat file suffix))
@@ -1335,7 +1339,7 @@ Return nil if no change in files."
dired-compress-file-alist)))
(if (not rule)
(user-error "No compression rule found for suffix %s, \
-see `dired-compress-file-alist' for the supported suffixes list."
+see `dired-compress-file-alist' for the supported suffixes list"
dired-compress-file-default-suffix)
(and (file-exists-p file)
(or (not (file-exists-p out-name))
@@ -1345,9 +1349,10 @@ see `dired-compress-file-alist' for the supported suffixes list."
out-name)))
(dired-shell-command
(replace-regexp-in-string
- "%o" (shell-quote-argument out-name)
+ "%o" (shell-quote-argument
+ (file-local-name out-name))
(replace-regexp-in-string
- "%i" (shell-quote-argument file)
+ "%i" (shell-quote-argument (file-local-name file))
(cdr rule)
nil t)
nil t))
@@ -1362,7 +1367,8 @@ see `dired-compress-file-alist' for the supported suffixes list."
out-name)))))
(file-error
(if (not (dired-check-process (concat "Compressing " file)
- "compress" "-f" file))
+ "compress" "-f"
+ (file-local-name file)))
;; Don't use NEWNAME with `compress'.
(concat file ".Z"))))))))
@@ -1783,13 +1789,46 @@ Special value `always' suppresses confirmation."
"Whether Dired should create destination dirs when copying/removing files.
If nil, don't create them.
If `always', create them without asking.
-If `ask', ask for user confirmation."
+If `ask', ask for user confirmation.
+
+Also see `dired-create-destination-dirs-on-trailing-dirsep'."
:type '(choice (const :tag "Never create non-existent dirs" nil)
(const :tag "Always create non-existent dirs" always)
(const :tag "Ask for user confirmation" ask))
:group 'dired
:version "27.1")
+(defcustom dired-create-destination-dirs-on-trailing-dirsep nil
+ "If non-nil, treat a trailing slash at queried destination dir specially.
+
+If this variable is non-nil and a single destination filename is
+queried which ends in a directory separator (/), it will be
+treated as a non-existent directory and acted on according to
+`dired-create-destination-dirs'.
+
+This option is only relevant if `dired-create-destination-dirs'
+is non-nil, too.
+
+For example, if both `dired-create-destination-dirs' and this
+option are non-nil, renaming a directory named `old_name' to
+`new_name/' (note the trailing directory separator) where
+`new_name' does not exists already, it will be created and
+`old_name' be moved into it. If only `new_name' (without the
+trailing /) is given or this option or
+`dired-create-destination-dirs' is `nil', `old_name' will be
+renamed to `new_name'."
+ :type '(choice
+ (const :tag
+ (concat "Do not treat destination dirs with a "
+ "trailing directory separator specially")
+ nil)
+ (const :tag
+ (concat "Treat destination dirs with trailing "
+ "directory separator specially")
+ t))
+ :group 'dired
+ :version "29.1")
+
(defun dired-maybe-create-dirs (dir)
"Create DIR if doesn't exist according to `dired-create-destination-dirs'."
(when (and dired-create-destination-dirs (not (file-exists-p dir)))
@@ -1985,11 +2024,12 @@ or with the current marker character if MARKER-CHAR is t."
(let* ((overwrite (file-exists-p to))
(dired-overwrite-confirmed ; for dired-handle-overwrite
(and overwrite
- (let ((help-form (format-message "\
-Type SPC or `y' to overwrite file `%s',
-DEL or `n' to skip to next,
-ESC or `q' to not overwrite any of the remaining files,
-`!' to overwrite all remaining files with no more questions." to)))
+ (let ((help-form (format-message
+ (substitute-command-keys "\
+Type \\`SPC' or \\`y' to overwrite file `%s',
+\\`DEL' or \\`n' to skip to next,
+\\`ESC' or \\`q' to not overwrite any of the remaining files,
+\\`!' to overwrite all remaining files with no more questions.") to)))
(dired-query 'overwrite-query
"Overwrite `%s'?" to))))
;; must determine if FROM is marked before file-creator
@@ -2158,7 +2198,12 @@ Optional arg HOW-TO determines how to treat the target.
target-dir op-symbol arg rfn-list default))))
(into-dir
(progn
- (unless dired-one-file (dired-maybe-create-dirs target))
+ (when
+ (or
+ (not dired-one-file)
+ (and dired-create-destination-dirs-on-trailing-dirsep
+ (directory-name-p target)))
+ (dired-maybe-create-dirs target))
(cond ((null how-to)
;; Allow users to change the letter case of
;; a directory on a case-insensitive
@@ -2340,9 +2385,9 @@ If DIRECTORY already exists, signal an error."
;;;###autoload
(defun dired-create-empty-file (file)
"Create an empty file called FILE.
- Add a new entry for the new file in the Dired buffer.
- Parent directories of FILE are created as needed.
- If FILE already exists, signal an error."
+Add a new entry for the new file in the Dired buffer.
+Parent directories of FILE are created as needed.
+If FILE already exists, signal an error."
(interactive (list (read-file-name "Create empty file: ")))
(let* ((expanded (expand-file-name file))
new)
@@ -2399,7 +2444,9 @@ But if `dired-copy-dereference' is non-nil, the symbolic
links are dereferenced and then copied, similar to the \"-L\"
option for the \"cp\" shell command. If ARG is a cons with
element 4 (`\\[universal-argument]'), the inverted value of
-`dired-copy-dereference' will be used."
+`dired-copy-dereference' will be used.
+
+Also see `dired-do-revert-buffer'."
(interactive "P")
(let ((dired-recursive-copies dired-recursive-copies)
(dired-copy-dereference (if (equal arg '(4))
@@ -2420,7 +2467,9 @@ with the same names that the files currently have. The default
suggested for the target directory depends on the value of
`dired-dwim-target', which see.
-For relative symlinks, use \\[dired-do-relsymlink]."
+For relative symlinks, use \\[dired-do-relsymlink].
+
+Also see `dired-do-revert-buffer'."
(interactive "P")
(dired-do-create-files 'symlink #'make-symbolic-link
"Symlink" arg dired-keep-marker-symlink))
@@ -2433,7 +2482,9 @@ When operating on multiple or marked files, you specify a directory
and new hard links are made in that directory
with the same names that the files currently have. The default
suggested for the target directory depends on the value of
-`dired-dwim-target', which see."
+`dired-dwim-target', which see.
+
+Also see `dired-do-revert-buffer'."
(interactive "P")
(dired-do-create-files 'hardlink #'dired-hardlink
"Hardlink" arg dired-keep-marker-hardlink))
@@ -2452,7 +2503,9 @@ When renaming just the current file, you specify the new name.
When renaming multiple or marked files, you specify a directory.
This command also renames any buffers that are visiting the files.
The default suggested for the target directory depends on the value
-of `dired-dwim-target', which see."
+of `dired-dwim-target', which see.
+
+Also see `dired-do-revert-buffer'."
(interactive "P")
(dired-do-create-files 'move #'dired-rename-file
"Move" arg dired-keep-marker-rename "Rename"))
@@ -2474,11 +2527,12 @@ of `dired-dwim-target', which see."
;; Optional arg MARKER-CHAR as in dired-create-files.
(let* ((fn-list (dired-get-marked-files nil arg))
(operation-prompt (concat operation " `%s' to `%s'?"))
- (rename-regexp-help-form (format-message "\
-Type SPC or `y' to %s one match, DEL or `n' to skip to next,
-`!' to %s all remaining matches with no more questions."
- (downcase operation)
- (downcase operation)))
+ (rename-regexp-help-form (format-message
+ (substitute-command-keys "\
+Type \\`SPC' or \\`y' to %s one match, \\`DEL' or \\`n' to skip to next,
+\\`!' to %s all remaining matches with no more questions.")
+ (downcase operation)
+ (downcase operation)))
(regexp-name-constructor
;; Function to construct new filename using REGEXP and NEWNAME:
(if whole-name ; easy (but rare) case
@@ -2599,11 +2653,12 @@ See function `dired-do-rename-regexp' for more info."
(let ((to (concat (file-name-directory from)
(funcall basename-constructor
(file-name-nondirectory from)))))
- (and (let ((help-form (format-message "\
-Type SPC or `y' to %s one file, DEL or `n' to skip to next,
-`!' to %s all remaining matches with no more questions."
- (downcase operation)
- (downcase operation))))
+ (and (let ((help-form (format-message
+ (substitute-command-keys "\
+Type \\`SPC' or \\`y' to %s one file, \\`DEL' or \\`n' to skip to next,
+\\`!' to %s all remaining matches with no more questions.")
+ (downcase operation)
+ (downcase operation))))
(dired-query 'rename-non-directory-query
(concat operation " `%s' to `%s'")
(dired-make-relative from)
@@ -2729,7 +2784,7 @@ This function takes some pains to conform to `ls -lR' output."
;; Check that it is valid to insert DIRNAME with SWITCHES.
;; Signal an error if invalid (e.g. user typed `i' on `..').
(or (file-in-directory-p dirname (expand-file-name default-directory))
- (error "%s: not in this directory tree" dirname))
+ (error "%s: Not in this directory tree" dirname))
(let ((real-switches (or switches dired-subdir-switches)))
(when real-switches
(let (case-fold-search)
@@ -2853,8 +2908,8 @@ of marked files. If KILL-ROOT is non-nil, kill DIRNAME as well."
;; if dired-actual-switches contained t.
(setq dir1 (file-name-as-directory dir1)
dir2 (file-name-as-directory dir2))
- (let ((components-1 (dired-split "/" dir1))
- (components-2 (dired-split "/" dir2)))
+ (let ((components-1 (split-string dir1 "/"))
+ (components-2 (split-string dir2 "/")))
(while (and components-1
components-2
(equal (car components-1) (car components-2)))
@@ -2873,7 +2928,6 @@ of marked files. If KILL-ROOT is non-nil, kill DIRNAME as well."
nil)
(t (error "This can't happen"))))))
-;; There should be a builtin split function - inverse to mapconcat.
(defun dired-split (pat str &optional limit)
"Splitting on regexp PAT, turn string STR into a list of substrings.
Optional third arg LIMIT (>= 1) is a limit to the length of the
@@ -2883,6 +2937,7 @@ Thus, if SEP is a regexp that only matches itself,
(mapconcat #'identity (dired-split SEP STRING) SEP)
is always equal to STRING."
+ (declare (obsolete split-string "29.1"))
(let* ((start (string-match pat str))
(result (list (substring str 0 start)))
(count 1)
@@ -3245,10 +3300,13 @@ REGEXP should use constructs supported by your local `grep' command."
(list (nth 0 common) (nth 1 common))))
(require 'xref)
(defvar xref-show-xrefs-function)
+ (defvar xref-auto-jump-to-first-xref)
(with-current-buffer
(let ((xref-show-xrefs-function
;; Some future-proofing (bug#44905).
- (custom--standard-value 'xref-show-xrefs-function)))
+ (custom--standard-value 'xref-show-xrefs-function))
+ ;; Disable auto-jumping, it will mess up replacement logic.
+ xref-auto-jump-to-first-xref)
(dired-do-find-regexp from))
(xref-query-replace-in-results from to)))
diff --git a/lisp/dired-x.el b/lisp/dired-x.el
index 380e47786fc..38d8a954a83 100644
--- a/lisp/dired-x.el
+++ b/lisp/dired-x.el
@@ -293,7 +293,7 @@ files"]
\\[dired-omit-mode]\t-- toggle omitting of files
\\[dired-mark-sexp]\t-- mark by Lisp expression
-To see the options you can set, use M-x customize-group RET dired-x RET.
+To see the options you can set, use \\[customize-group] RET dired-x RET.
See also the functions:
`dired-flag-extension'
`dired-virtual'
@@ -340,8 +340,8 @@ A `.' is automatically prepended to EXTENSION when not present.
EXTENSION may also be a list of extensions instead of a single one.
Optional MARKER-CHAR is marker to use.
Interactively, ask for EXTENSION.
-Prefixed with one C-u, unmark files instead.
-Prefixed with two C-u's, prompt for MARKER-CHAR and mark files with it."
+Prefixed with one \\[universal-argument], unmark files instead.
+Prefixed with two \\[universal-argument]'s, prompt for MARKER-CHAR and mark files with it."
(interactive (dired--mark-suffix-interactive-spec))
(unless (listp extension)
(setq extension (list extension)))
@@ -365,8 +365,8 @@ prepends `.' when not present.
SUFFIX may also be a list of suffixes instead of a single one.
Optional MARKER-CHAR is marker to use.
Interactively, ask for SUFFIX.
-Prefixed with one C-u, unmark files instead.
-Prefixed with two C-u's, prompt for MARKER-CHAR and mark files with it."
+Prefixed with one \\[universal-argument], unmark files instead.
+Prefixed with two \\[universal-argument]'s, prompt for MARKER-CHAR and mark files with it."
(interactive (dired--mark-suffix-interactive-spec))
(unless (listp suffix)
(setq suffix (list suffix)))
@@ -554,7 +554,7 @@ If the region is active in Transient Mark mode, operate only on
files in the active region if `dired-mark-region' is non-nil."
(interactive
(list (read-regexp
- "Mark unmarked files matching regexp (default all): "
+ (format-prompt "Mark unmarked files matching regexp" "all")
nil 'dired-regexp-history)
nil current-prefix-arg nil))
(let ((dired-marker-char (if unflag-p ?\s dired-marker-char)))
@@ -580,23 +580,24 @@ files in the active region if `dired-mark-region' is non-nil."
(defalias 'virtual-dired 'dired-virtual)
(defun dired-virtual (dirname &optional switches)
- "Put this Dired buffer into Virtual Dired mode.
+ "Treat the current buffer as a Dired buffer showing directory DIRNAME.
+Interactively, prompt for DIRNAME.
-In Virtual Dired mode, all commands that do not actually consult the
-filesystem will work.
+This command is rarely useful, but may be convenient if you want
+to peruse and move around in the output you got from \"ls
+-lR\" (or something similar), without having access to the actual
+file system.
-This is useful if you want to peruse and move around in an ls -lR
-output file, for example one you got from an ftp server. With
-ange-ftp, you can even Dired a directory containing an ls-lR file,
-visit that file and turn on Virtual Dired mode. But don't try to save
-this file, as dired-virtual indents the listing and thus changes the
-buffer.
+Most Dired commands that don't consult the file system will work
+as advertised, but commands that try to alter the file system
+will usually fail. (However, if the output is from the current
+system, most of those commands will work fine.)
If you have saved a Dired buffer in a file you can use \\[dired-virtual] to
resume it in a later session.
Type \\<dired-mode-map>\\[revert-buffer] \
-in the Virtual Dired buffer and answer `y' to convert
+in the Virtual Dired buffer and answer \\`y' to convert
the virtual to a real Dired buffer again. You don't have to do this, though:
you can relist single subdirs using \\[dired-do-redisplay]."
@@ -956,7 +957,7 @@ as the variable `file'.
If several COMMANDs are given, the first one will be the default
and the rest will be added temporarily to the history and can be retrieved
-with \\[previous-history-element] (M-p) .
+with `previous-history-element' (\\<minibuffer-mode-map>\\[previous-history-element]).
The variable `dired-guess-shell-case-fold-search' controls whether
REGEXP is matched case-sensitively."
@@ -1264,13 +1265,21 @@ sure that a trailing letter in STR is one of BKkMGTPEZY."
(let* ((val (string-to-number str))
(u (unless (zerop val)
(aref str (1- (length str))))))
- (when (and u (> u ?9))
- (when (= u ?k)
- (setq u ?K))
- (let ((units '(?B ?K ?M ?G ?T ?P ?E ?Z ?Y)))
- (while (and units (/= (pop units) u))
- (setq val (* 1024.0 val)))))
- val))
+ ;; If we don't have a unit at the end, but we have some
+ ;; non-numeric strings in the string, then the string may be
+ ;; something like "4.134" or "4,134" meant to represent 4134
+ ;; (seen in some locales).
+ (if (and u
+ (<= ?0 u ?9)
+ (string-match-p "[^0-9]" str))
+ (string-to-number (replace-regexp-in-string "[^0-9]+" "" str))
+ (when (and u (> u ?9))
+ (when (= u ?k)
+ (setq u ?K))
+ (let ((units '(?B ?K ?M ?G ?T ?P ?E ?Z ?Y)))
+ (while (and units (/= (pop units) u))
+ (setq val (* 1024.0 val)))))
+ val)))
(defun dired-mark-sexp (predicate &optional unflag-p)
"Mark files for which PREDICATE returns non-nil.
@@ -1478,12 +1487,12 @@ a prefix argument, when it offers the filename near point as a default."
;;; Internal functions
-;; Fixme: This should probably use `thing-at-point'. -- fx
(define-obsolete-function-alias 'dired-filename-at-point
#'dired-x-guess-file-name-at-point "28.1")
(defun dired-x-guess-file-name-at-point ()
"Return the filename closest to point, expanded.
Point should be in or after a filename."
+ (declare (obsolete "use (thing-at-point 'filename) instead." "29.1"))
(save-excursion
;; First see if just past a filename.
(or (eobp) ; why?
@@ -1515,7 +1524,7 @@ Point should be in or after a filename."
"Return filename prompting with PROMPT with completion.
If `current-prefix-arg' is non-nil, uses name at point as guess."
(if current-prefix-arg
- (let ((guess (dired-x-guess-file-name-at-point)))
+ (let ((guess (thing-at-point 'filename)))
(read-file-name prompt
(file-name-directory guess)
guess
diff --git a/lisp/dired.el b/lisp/dired.el
index 0add0ab3887..a8841214156 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -35,6 +35,7 @@
;;; Code:
(eval-when-compile (require 'subr-x))
+(eval-when-compile (require 'cl-lib))
;; When bootstrapping dired-loaddefs has not been generated.
(require 'dired-loaddefs nil t)
@@ -137,10 +138,9 @@ For more details, see Info node `(emacs)ls in Lisp'."
(const :tag "Do not use --dired" nil)
(other :tag "Always use --dired" t)))
-(defcustom dired-chmod-program "chmod"
- "Name of chmod command (usually `chmod')."
- :group 'dired
- :type 'file)
+(defvar dired-chmod-program "chmod"
+ "Name of chmod command (usually `chmod').")
+(make-obsolete-variable 'dired-chmod-program nil "28.1")
(defcustom dired-touch-program "touch"
"Name of touch command (usually `touch')."
@@ -209,6 +209,18 @@ If a character, new links are unconditionally marked with that character."
(character :tag "Mark"))
:group 'dired-mark)
+(defcustom dired-free-space 'first
+ "Whether and how to display the amount of free disk space in Dired buffers.
+If nil, don't display.
+If `separate', display on a separate line (along with used count).
+If `first', display only the free disk space on the first line,
+following the directory name."
+ :type '(choice (const :tag "On a separate line" separate)
+ (const :tag "On the first line, after directory name" first)
+ (const :tag "Don't display" nil))
+ :version "29.1"
+ :group 'dired)
+
(defcustom dired-dwim-target nil
"If non-nil, Dired tries to guess a default target directory.
This means: if there is a Dired buffer displayed in some window,
@@ -248,7 +260,7 @@ This is similar to the \"-L\" option for the \"cp\" shell command."
:type 'boolean
:group 'dired)
-;; These variables were deleted and the replacements are on files.el.
+;; These variables were deleted and the replacements are in files.el.
;; We leave aliases behind for back-compatibility.
(define-obsolete-variable-alias 'dired-free-space-program
'directory-free-space-program "27.1")
@@ -282,6 +294,11 @@ with the buffer narrowed to the listing."
;; Note this can't simply be run inside function `dired-ls' as the hook
;; functions probably depend on the dired-subdir-alist to be OK.
+(defcustom dired-make-directory-clickable t
+ "When non-nil, make the directory at the start of the dired buffer clickable."
+ :version "29.1"
+ :type 'boolean)
+
(defcustom dired-initial-position-hook nil
"This hook is used to position the point.
It is run by the function `dired-initial-position'."
@@ -316,12 +333,12 @@ new Dired buffers."
(defcustom dired-always-read-filesystem nil
"Non-nil means revert buffers visiting files before searching them.
- By default, commands like `dired-mark-files-containing-regexp' will
- search any buffers visiting the marked files without reverting them,
- even if they were changed on disk. When this option is non-nil, such
- buffers are always reverted in a temporary buffer before searching
- them: the search is performed on the temporary buffer, the original
- buffer visiting the file is not modified."
+By default, commands like `dired-mark-files-containing-regexp' will
+search any buffers visiting the marked files without reverting them,
+even if they were changed on disk. When this option is non-nil, such
+buffers are always reverted in a temporary buffer before searching
+them: the search is performed on the temporary buffer, the original
+buffer visiting the file is not modified."
:type 'boolean
:version "26.1"
:group 'dired)
@@ -340,11 +357,11 @@ When `file', the region marking is based on the file name.
This means don't mark the file if the end of the region is
before the file name displayed on the Dired line, so the file name
is visually outside the region. This behavior is consistent with
-marking files without the region using the key `m' that advances
+marking files without the region using the key \\`m' that advances
point to the next line after marking the file. Thus the number
of keys used to mark files is the same as the number of keys
-used to select the region, e.g. `M-2 m' marks 2 files, and
-`C-SPC M-2 n m' marks 2 files, and `M-2 S-down m' marks 2 files.
+used to select the region, for example \\`M-2 m' marks 2 files, and
+\\`C-SPC M-2 n m' marks 2 files, and \\`M-2 S-<down> m' marks 2 files.
When `line', the region marking is based on Dired lines,
so include the file into marking if the end of the region
@@ -1020,27 +1037,27 @@ If DIRNAME is already in a Dired buffer, that buffer is used without refresh."
;;;###autoload (define-key ctl-x-4-map "d" 'dired-other-window)
;;;###autoload
(defun dired-other-window (dirname &optional switches)
- "\"Edit\" directory DIRNAME. Like `dired' but selects in another window."
+ "\"Edit\" directory DIRNAME. Like `dired' but select in another window."
(interactive (dired-read-dir-and-switches "in other window "))
(switch-to-buffer-other-window (dired-noselect dirname switches)))
;;;###autoload (define-key ctl-x-5-map "d" 'dired-other-frame)
;;;###autoload
(defun dired-other-frame (dirname &optional switches)
- "\"Edit\" directory DIRNAME. Like `dired' but makes a new frame."
+ "\"Edit\" directory DIRNAME. Like `dired' but make a new frame."
(interactive (dired-read-dir-and-switches "in other frame "))
(switch-to-buffer-other-frame (dired-noselect dirname switches)))
;;;###autoload (define-key tab-prefix-map "d" 'dired-other-tab)
;;;###autoload
(defun dired-other-tab (dirname &optional switches)
- "\"Edit\" directory DIRNAME. Like `dired' but makes a new tab."
+ "\"Edit\" directory DIRNAME. Like `dired' but make a new tab."
(interactive (dired-read-dir-and-switches "in other tab "))
(switch-to-buffer-other-tab (dired-noselect dirname switches)))
;;;###autoload
(defun dired-noselect (dir-or-list &optional switches)
- "Like `dired' but returns the Dired buffer as value, does not select it."
+ "Like `dired' but return the Dired buffer as value, do not select it."
(or dir-or-list (setq dir-or-list default-directory))
;; This loses the distinction between "/foo/*/" and "/foo/*" that
;; some shells make:
@@ -1248,8 +1265,7 @@ The return value is the target column for the file names."
;; Don't try to find a wildcard as a subdirectory.
(string-equal dirname (file-name-directory dirname)))
(let* ((cur-buf (current-buffer))
- (buffers (nreverse
- (dired-buffers-for-dir (expand-file-name dirname))))
+ (buffers (nreverse (dired-buffers-for-dir dirname)))
(cur-buf-matches (and (memq cur-buf buffers)
;; Wildcards must match, too:
(equal dired-directory dirname))))
@@ -1327,6 +1343,8 @@ wildcards, erases the buffer, and builds the subdir-alist anew
(set-visited-file-modtime (file-attribute-modification-time
attributes))))
(set-buffer-modified-p nil)
+ (when dired-make-directory-clickable
+ (dired--make-directory-clickable))
;; No need to narrow since the whole buffer contains just
;; dired-readin's output, nothing else. The hook can
;; successfully use dired functions (e.g. dired-get-filename)
@@ -1607,17 +1625,57 @@ see `dired-use-ls-dired' for more details.")
;; by its expansion, so it does not matter whether what we insert
;; here is fully expanded, but it should be absolute.
(insert " " (or (car-safe (insert-directory-wildcard-in-dir-p dir))
- (directory-file-name (file-name-directory dir))) ":\n")
+ (directory-file-name (file-name-directory dir)))
+ ":\n")
(setq content-point (point)))
(when wildcard
;; Insert "wildcard" line where "total" line would be for a full dir.
(insert " wildcard " (or (cdr-safe (insert-directory-wildcard-in-dir-p dir))
(file-name-nondirectory dir))
- "\n")))
+ "\n"))
+ (setq content-point (dired--insert-disk-space opoint dir)))
(dired-insert-set-properties content-point (point)))))
+(defun dired--insert-disk-space (beg file)
+ ;; Try to insert the amount of free space.
+ (save-excursion
+ (goto-char beg)
+ ;; First find the line to put it on.
+ (if (not (re-search-forward "^ *\\(total\\)" nil t))
+ beg
+ (if (or (not dired-free-space)
+ (eq dired-free-space 'first))
+ (delete-region (match-beginning 0) (line-beginning-position 2))
+ ;; Replace "total" with "total used in directory" to
+ ;; avoid confusion.
+ (replace-match "total used in directory" nil nil nil 1))
+ (if-let ((available (get-free-disk-space file)))
+ (cond
+ ((eq dired-free-space 'separate)
+ (end-of-line)
+ (insert " available " available)
+ (forward-line 1)
+ (point))
+ ((eq dired-free-space 'first)
+ (goto-char beg)
+ (when (and (looking-at
+ (if (memq system-type '(windows-nt ms-dos))
+ " *[A-Za-z]:/"
+ " */"))
+ (progn
+ (end-of-line)
+ (eq (char-after (1- (point))) ?:)))
+ (put-text-property (1- (point)) (point)
+ 'display
+ (concat ": (" available " available)")))
+ (forward-line 1)
+ (point))
+ (t
+ beg))
+ beg))))
+
(defun dired-insert-set-properties (beg end)
- "Add various text properties to the lines in the region."
+ "Add various text properties to the lines in the region, from BEG to END."
(save-excursion
(goto-char beg)
(while (< (point) end)
@@ -1644,6 +1702,32 @@ see `dired-use-ls-dired' for more details.")
'invisible 'dired-hide-details-link))))
(forward-line 1))))
+(defun dired--make-directory-clickable ()
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward "^ /" nil t 1)
+ (let ((bound (line-end-position))
+ (segment-start (point))
+ (inhibit-read-only t)
+ (dir "/"))
+ (while (search-forward "/" bound t 1)
+ (setq dir (concat dir (buffer-substring segment-start (point))))
+ (add-text-properties
+ segment-start (1- (point))
+ `( mouse-face highlight
+ help-echo "mouse-1: goto this directory"
+ keymap ,(let* ((current-dir dir)
+ (click (lambda ()
+ (interactive)
+ (if (assoc current-dir dired-subdir-alist)
+ (dired-goto-subdir current-dir)
+ (dired current-dir)))))
+ (define-keymap
+ "<mouse-2>" click
+ "<follow-link>" 'mouse-face
+ "RET" click))))
+ (setq segment-start (point)))))))
+
;;; Reverting a dired buffer
@@ -1836,160 +1920,152 @@ Do so according to the former subdir alist OLD-SUBDIR-ALIST."
;;; Dired mode key bindings and menus
-(defvar dired-mode-map
+(defvar-keymap dired-mode-map
+ :doc "Local keymap for Dired mode buffers."
+ :full t
+ :parent special-mode-map
;; This looks ugly when substitute-command-keys uses C-d instead d:
- ;; (define-key dired-mode-map "\C-d" 'dired-flag-file-deletion)
- (let ((map (make-keymap)))
- (set-keymap-parent map special-mode-map)
- (define-key map [mouse-2] 'dired-mouse-find-file-other-window)
- (define-key map [follow-link] 'mouse-face)
- ;; Commands to mark or flag certain categories of files
- (define-key map "#" 'dired-flag-auto-save-files)
- (define-key map "." 'dired-clean-directory)
- (define-key map "~" 'dired-flag-backup-files)
- ;; Upper case keys (except !) for operating on the marked files
- (define-key map "A" 'dired-do-find-regexp)
- (define-key map "C" 'dired-do-copy)
- (define-key map "B" 'dired-do-byte-compile)
- (define-key map "D" 'dired-do-delete)
- (define-key map "G" 'dired-do-chgrp)
- (define-key map "H" 'dired-do-hardlink)
- (define-key map "L" 'dired-do-load)
- (define-key map "M" 'dired-do-chmod)
- (define-key map "O" 'dired-do-chown)
- (define-key map "P" 'dired-do-print)
- (define-key map "Q" 'dired-do-find-regexp-and-replace)
- (define-key map "R" 'dired-do-rename)
- (define-key map "S" 'dired-do-symlink)
- (define-key map "T" 'dired-do-touch)
- (define-key map "X" 'dired-do-shell-command)
- (define-key map "Z" 'dired-do-compress)
- (define-key map "c" 'dired-do-compress-to)
- (define-key map "!" 'dired-do-shell-command)
- (define-key map "&" 'dired-do-async-shell-command)
- ;; Comparison commands
- (define-key map "=" 'dired-diff)
- ;; Tree Dired commands
- (define-key map "\M-\C-?" 'dired-unmark-all-files)
- (define-key map "\M-\C-d" 'dired-tree-down)
- (define-key map "\M-\C-u" 'dired-tree-up)
- (define-key map "\M-\C-n" 'dired-next-subdir)
- (define-key map "\M-\C-p" 'dired-prev-subdir)
- ;; move to marked files
- (define-key map "\M-{" 'dired-prev-marked-file)
- (define-key map "\M-}" 'dired-next-marked-file)
- ;; Make all regexp commands share a `%' prefix:
- ;; We used to get to the submap via a symbol dired-regexp-prefix,
- ;; but that seems to serve little purpose, and copy-keymap
- ;; does a better job without it.
- (define-key map "%" nil)
- (define-key map "%u" 'dired-upcase)
- (define-key map "%l" 'dired-downcase)
- (define-key map "%d" 'dired-flag-files-regexp)
- (define-key map "%g" 'dired-mark-files-containing-regexp)
- (define-key map "%m" 'dired-mark-files-regexp)
- (define-key map "%r" 'dired-do-rename-regexp)
- (define-key map "%C" 'dired-do-copy-regexp)
- (define-key map "%H" 'dired-do-hardlink-regexp)
- (define-key map "%R" 'dired-do-rename-regexp)
- (define-key map "%S" 'dired-do-symlink-regexp)
- (define-key map "%&" 'dired-flag-garbage-files)
- ;; Commands for marking and unmarking.
- (define-key map "*" nil)
- (define-key map "**" 'dired-mark-executables)
- (define-key map "*/" 'dired-mark-directories)
- (define-key map "*@" 'dired-mark-symlinks)
- (define-key map "*%" 'dired-mark-files-regexp)
- (define-key map "*N" 'dired-number-of-marked-files)
- (define-key map "*c" 'dired-change-marks)
- (define-key map "*s" 'dired-mark-subdir-files)
- (define-key map "*m" 'dired-mark)
- (define-key map "*u" 'dired-unmark)
- (define-key map "*?" 'dired-unmark-all-files)
- (define-key map "*!" 'dired-unmark-all-marks)
- (define-key map "U" 'dired-unmark-all-marks)
- (define-key map "*\177" 'dired-unmark-backward)
- (define-key map "*\C-n" 'dired-next-marked-file)
- (define-key map "*\C-p" 'dired-prev-marked-file)
- (define-key map "*t" 'dired-toggle-marks)
- ;; Lower keys for commands not operating on all the marked files
- (define-key map "a" 'dired-find-alternate-file)
- (define-key map "d" 'dired-flag-file-deletion)
- (define-key map "e" 'dired-find-file)
- (define-key map "f" 'dired-find-file)
- (define-key map "\C-m" 'dired-find-file)
- (put 'dired-find-file :advertised-binding "\C-m")
- (define-key map "g" 'revert-buffer)
- (define-key map "i" 'dired-maybe-insert-subdir)
- (define-key map "j" 'dired-goto-file)
- (define-key map "k" 'dired-do-kill-lines)
- (define-key map "l" 'dired-do-redisplay)
- (define-key map "m" 'dired-mark)
- (define-key map "n" 'dired-next-line)
- (define-key map "o" 'dired-find-file-other-window)
- (define-key map "\C-o" 'dired-display-file)
- (define-key map "p" 'dired-previous-line)
- (define-key map "s" 'dired-sort-toggle-or-edit)
- (define-key map "t" 'dired-toggle-marks)
- (define-key map "u" 'dired-unmark)
- (define-key map "v" 'dired-view-file)
- (define-key map "w" 'dired-copy-filename-as-kill)
- (define-key map "W" 'browse-url-of-dired-file)
- (define-key map "x" 'dired-do-flagged-delete)
- (define-key map "y" 'dired-show-file-type)
- (define-key map "+" 'dired-create-directory)
- ;; moving
- (define-key map "<" 'dired-prev-dirline)
- (define-key map ">" 'dired-next-dirline)
- (define-key map "^" 'dired-up-directory)
- (define-key map " " 'dired-next-line)
- (define-key map [?\S-\ ] 'dired-previous-line)
- (define-key map [remap next-line] 'dired-next-line)
- (define-key map [remap previous-line] 'dired-previous-line)
- ;; hiding
- (define-key map "$" 'dired-hide-subdir)
- (define-key map "\M-$" 'dired-hide-all)
- (define-key map "(" 'dired-hide-details-mode)
- ;; isearch
- (define-key map (kbd "M-s a C-s") 'dired-do-isearch)
- (define-key map (kbd "M-s a M-C-s") 'dired-do-isearch-regexp)
- (define-key map (kbd "M-s f C-s") 'dired-isearch-filenames)
- (define-key map (kbd "M-s f M-C-s") 'dired-isearch-filenames-regexp)
- ;; misc
- (define-key map [remap read-only-mode] 'dired-toggle-read-only)
- ;; `toggle-read-only' is an obsolete alias for `read-only-mode'
- (define-key map [remap toggle-read-only] 'dired-toggle-read-only)
- (define-key map "?" 'dired-summary)
- (define-key map "\177" 'dired-unmark-backward)
- (define-key map [remap undo] 'dired-undo)
- (define-key map [remap advertised-undo] 'dired-undo)
- (define-key map [remap vc-next-action] 'dired-vc-next-action)
- ;; thumbnail manipulation (image-dired)
- (define-key map "\C-td" 'image-dired-display-thumbs)
- (define-key map "\C-tt" 'image-dired-tag-files)
- (define-key map "\C-tr" 'image-dired-delete-tag)
- (define-key map "\C-tj" 'image-dired-jump-thumbnail-buffer)
- (define-key map "\C-ti" 'image-dired-dired-display-image)
- (define-key map "\C-tx" 'image-dired-dired-display-external)
- (define-key map "\C-ta" 'image-dired-display-thumbs-append)
- (define-key map "\C-t." 'image-dired-display-thumb)
- (define-key map "\C-tc" 'image-dired-dired-comment-files)
- (define-key map "\C-tf" 'image-dired-mark-tagged-files)
- (define-key map "\C-t\C-t" 'image-dired-dired-toggle-marked-thumbs)
- (define-key map "\C-te" 'image-dired-dired-edit-comment-and-tags)
- ;; encryption and decryption (epa-dired)
- (define-key map ":d" 'epa-dired-do-decrypt)
- (define-key map ":v" 'epa-dired-do-verify)
- (define-key map ":s" 'epa-dired-do-sign)
- (define-key map ":e" 'epa-dired-do-encrypt)
-
- ;; No need to do this, now that top-level items are fewer.
- ;;;;
- ;; Get rid of the Edit menu bar item to save space.
- ;;(define-key map [menu-bar edit] 'undefined)
-
- map)
- "Local keymap for Dired mode buffers.")
+ ;; "C-d" #'dired-flag-file-deletion
+ "<mouse-2>" #'dired-mouse-find-file-other-window
+ "<follow-link>" 'mouse-face
+ ;; Commands to mark or flag certain categories of files
+ "#" #'dired-flag-auto-save-files
+ "." #'dired-clean-directory
+ "~" #'dired-flag-backup-files
+ ;; Upper case keys (except !) for operating on the marked files
+ "A" #'dired-do-find-regexp
+ "C" #'dired-do-copy
+ "B" #'dired-do-byte-compile
+ "D" #'dired-do-delete
+ "G" #'dired-do-chgrp
+ "H" #'dired-do-hardlink
+ "L" #'dired-do-load
+ "M" #'dired-do-chmod
+ "O" #'dired-do-chown
+ "P" #'dired-do-print
+ "Q" #'dired-do-find-regexp-and-replace
+ "R" #'dired-do-rename
+ "S" #'dired-do-symlink
+ "T" #'dired-do-touch
+ "X" #'dired-do-shell-command
+ "Z" #'dired-do-compress
+ "c" #'dired-do-compress-to
+ "!" #'dired-do-shell-command
+ "&" #'dired-do-async-shell-command
+ ;; Comparison commands
+ "=" #'dired-diff
+ ;; Tree Dired commands
+ "M-DEL" #'dired-unmark-all-files
+ "C-M-d" #'dired-tree-down
+ "C-M-u" #'dired-tree-up
+ "C-M-n" #'dired-next-subdir
+ "C-M-p" #'dired-prev-subdir
+ ;; move to marked files
+ "M-{" #'dired-prev-marked-file
+ "M-}" #'dired-next-marked-file
+ ;; Make all regexp commands share a `%' prefix:
+ ;; We used to get to the submap via a symbol dired-regexp-prefix,
+ ;; but that seems to serve little purpose, and copy-keymap
+ ;; does a better job without it.
+ "% u" #'dired-upcase
+ "% l" #'dired-downcase
+ "% d" #'dired-flag-files-regexp
+ "% g" #'dired-mark-files-containing-regexp
+ "% m" #'dired-mark-files-regexp
+ "% r" #'dired-do-rename-regexp
+ "% C" #'dired-do-copy-regexp
+ "% H" #'dired-do-hardlink-regexp
+ "% R" #'dired-do-rename-regexp
+ "% S" #'dired-do-symlink-regexp
+ "% &" #'dired-flag-garbage-files
+ ;; Commands for marking and unmarking.
+ "* *" #'dired-mark-executables
+ "* /" #'dired-mark-directories
+ "* @" #'dired-mark-symlinks
+ "* %" #'dired-mark-files-regexp
+ "* N" #'dired-number-of-marked-files
+ "* c" #'dired-change-marks
+ "* s" #'dired-mark-subdir-files
+ "* m" #'dired-mark
+ "* u" #'dired-unmark
+ "* ?" #'dired-unmark-all-files
+ "* !" #'dired-unmark-all-marks
+ "U" #'dired-unmark-all-marks
+ "* DEL" #'dired-unmark-backward
+ "* C-n" #'dired-next-marked-file
+ "* C-p" #'dired-prev-marked-file
+ "* t" #'dired-toggle-marks
+ ;; Lower keys for commands not operating on all the marked files
+ "a" #'dired-find-alternate-file
+ "d" #'dired-flag-file-deletion
+ "e" #'dired-find-file
+ "f" #'dired-find-file
+ "C-m" #'dired-find-file
+ "g" #'revert-buffer
+ "i" #'dired-maybe-insert-subdir
+ "j" #'dired-goto-file
+ "k" #'dired-do-kill-lines
+ "l" #'dired-do-redisplay
+ "m" #'dired-mark
+ "n" #'dired-next-line
+ "o" #'dired-find-file-other-window
+ "C-o" #'dired-display-file
+ "p" #'dired-previous-line
+ "s" #'dired-sort-toggle-or-edit
+ "t" #'dired-toggle-marks
+ "u" #'dired-unmark
+ "v" #'dired-view-file
+ "w" #'dired-copy-filename-as-kill
+ "W" #'browse-url-of-dired-file
+ "x" #'dired-do-flagged-delete
+ "y" #'dired-show-file-type
+ "+" #'dired-create-directory
+ ;; moving
+ "<" #'dired-prev-dirline
+ ">" #'dired-next-dirline
+ "^" #'dired-up-directory
+ "SPC" #'dired-next-line
+ "S-SPC" #'dired-previous-line
+ "<remap> <next-line>" #'dired-next-line
+ "<remap> <previous-line>" #'dired-previous-line
+ ;; hiding
+ "$" #'dired-hide-subdir
+ "M-$" #'dired-hide-all
+ "(" #'dired-hide-details-mode
+ ;; isearch
+ "M-s a C-s" #'dired-do-isearch
+ "M-s a C-M-s" #'dired-do-isearch-regexp
+ "M-s f C-s" #'dired-isearch-filenames
+ "M-s f C-M-s" #'dired-isearch-filenames-regexp
+ ;; misc
+ "<remap> <read-only-mode>" #'dired-toggle-read-only
+ ;; `toggle-read-only' is an obsolete alias for `read-only-mode'
+ "<remap> <toggle-read-only>" #'dired-toggle-read-only
+ "?" #'dired-summary
+ "DEL" #'dired-unmark-backward
+ "<remap> <undo>" #'dired-undo
+ "<remap> <advertised-undo>" #'dired-undo
+ "<remap> <vc-next-action>" #'dired-vc-next-action
+ ;; thumbnail manipulation (image-dired)
+ "C-t d" #'image-dired-display-thumbs
+ "C-t t" #'image-dired-tag-files
+ "C-t r" #'image-dired-delete-tag
+ "C-t j" #'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
+ "C-t C-t" #'image-dired-dired-toggle-marked-thumbs
+ "C-t e" #'image-dired-dired-edit-comment-and-tags
+ ;; encryption and decryption (epa-dired)
+ ": d" #'epa-dired-do-decrypt
+ ": v" #'epa-dired-do-verify
+ ": s" #'epa-dired-do-sign
+ ": e" #'epa-dired-do-encrypt)
+
+(put 'dired-find-file :advertised-binding (kbd "RET"))
(easy-menu-define dired-mode-subdir-menu dired-mode-map
"Subdir menu for Dired mode."
@@ -2194,8 +2270,9 @@ Do so according to the former subdir alist OLD-SUBDIR-ALIST."
["Delete Image Tag..." image-dired-delete-tag
:help "Delete image tag from current or marked files"]))
-(defun dired-context-menu (menu)
- (when (mouse-posn-property (event-start last-input-event) 'dired-filename)
+(defun dired-context-menu (menu click)
+ "Populate MENU with Dired mode commands at CLICK."
+ (when (mouse-posn-property (event-start click) 'dired-filename)
(define-key menu [dired-separator] menu-bar-separator)
(let ((easy-menu (make-sparse-keymap "Immediate")))
(easy-menu-define nil easy-menu nil
@@ -2219,8 +2296,7 @@ Do so according to the former subdir alist OLD-SUBDIR-ALIST."
;; Autoload cookie needed by desktop.el
;;;###autoload
(defun dired-mode (&optional dirname switches)
- "\
-Mode for \"editing\" directory listings.
+ "Mode for \"editing\" directory listings.
In Dired, you are \"editing\" a list of the files in a directory and
(optionally) its subdirectories, in the format of `ls -lR'.
Each directory is a page: use \\[backward-page] and \\[forward-page] to move pagewise.
@@ -2416,7 +2492,9 @@ directory in another window."
file-name
(if (file-symlink-p file-name)
(error "File is a symlink to a nonexistent target")
- (error "File no longer exists; type `g' to update Dired buffer")))))
+ (error (substitute-command-keys
+ (concat "File no longer exists; type \\<dired-mode-map>"
+ "\\[revert-buffer] to update Dired buffer")))))))
;; Force C-m keybinding rather than `f' or `e' in the mode doc:
(define-obsolete-function-alias 'dired-advertised-find-file
@@ -2879,8 +2957,8 @@ If SUBDIRS is non-nil, also include the dired buffers of
directories below DIR.
The list is in reverse order of buffer creation, most recent last.
As a side effect, killed dired buffers for DIR are removed from
-dired-buffers."
- (setq dir (file-name-as-directory dir))
+`dired-buffers'."
+ (setq dir (file-name-as-directory (expand-file-name dir)))
(let (result buf)
(dolist (elt dired-buffers)
(setq buf (cdr elt))
@@ -3431,7 +3509,7 @@ If the buffer has a wildcard pattern, check that it matches FILE.
FILE may be nil, in which case ignore it.
Return list of buffers where FUN succeeded (i.e., returned non-nil)."
(let (success-list)
- (dolist (buf (dired-buffers-for-dir (expand-file-name directory) file))
+ (dolist (buf (dired-buffers-for-dir directory file))
(with-current-buffer buf
(when (apply fun args)
(push (buffer-name buf) success-list))))
@@ -3480,8 +3558,7 @@ confirmation. To disable the confirmation, see
(file-name-nondirectory fn))))
(not dired-clean-confirm-killing-deleted-buffers))
(kill-buffer buf)))
- (let ((buf-list (dired-buffers-for-dir (expand-file-name fn)
- nil 'subdirs)))
+ (let ((buf-list (dired-buffers-for-dir fn nil 'subdirs)))
(and buf-list
(or (and dired-clean-confirm-killing-deleted-buffers
(y-or-n-p
@@ -3697,7 +3774,7 @@ no ARGth marked file is found before this line."
(defun dired-mark-files-in-region (start end)
(let ((inhibit-read-only t))
(if (> start end)
- (error "start > end"))
+ (error "Start > End"))
(goto-char start) ; assumed at beginning of line
(while (< (point) end)
;; Skip subdir line and following garbage like the `total' line:
@@ -4067,9 +4144,9 @@ Type \\[help-command] at that time for help."
(inhibit-read-only t) case-fold-search
dired-unmark-all-files-query
(string (format "\n%c" mark))
- (help-form "\
-Type SPC or `y' to unmark one file, DEL or `n' to skip to next,
-`!' to unmark all remaining files with no more questions."))
+ (help-form (substitute-command-keys "\
+Type \\`SPC' or \\`y' to unmark one file, \\`DEL' or \\`n' to skip to next,
+\\`!' to unmark all remaining files with no more questions.")))
(goto-char (point-min))
(while (if (eq mark ?\r)
(re-search-forward dired-re-mark nil t)
@@ -4191,7 +4268,7 @@ The idea is to set this buffer-locally in special Dired buffers.")
(defcustom dired-switches-in-mode-line nil
"How to indicate `dired-actual-switches' in mode-line.
Possible values:
- * `nil': Indicate name-or-date sort order, if possible.
+ * nil: Indicate name-or-date sort order, if possible.
Else show full switches.
* `as-is': Show full switches.
* Integer: Show only the first N chars of full switches.
@@ -4491,15 +4568,22 @@ Ask means pop up a menu for the user to select one of copy, move or link."
(defvar archive-superior-buffer)
(defvar tar-superior-buffer)
+(declare-function dired-omit-mode "dired-x" (&optional arg))
;;;###autoload
(defun dired-jump (&optional other-window file-name)
"Jump to Dired buffer corresponding to current buffer.
-If in a file, Dired the current directory and move to file's line.
+If in a buffer visiting a file, Dired that file's directory and
+move to that file's line in the directory listing.
+
+If the current buffer isn't visiting a file, Dired `default-directory'.
+
If in Dired already, pop up a level and goto old directory's line.
In case the proper Dired file line cannot be found, refresh the dired
buffer and try again.
+
When OTHER-WINDOW is non-nil, jump to Dired buffer in other window.
+
When FILE-NAME is non-nil, jump to its line in Dired.
Interactively with prefix argument, read FILE-NAME."
(interactive
diff --git a/lisp/display-fill-column-indicator.el b/lisp/display-fill-column-indicator.el
index 50252af4533..7e9d62c5d1a 100644
--- a/lisp/display-fill-column-indicator.el
+++ b/lisp/display-fill-column-indicator.el
@@ -45,7 +45,7 @@
;;;###autoload
(define-minor-mode display-fill-column-indicator-mode
- "Toggle display of fill-column indicator.
+ "Toggle display of `fill-column' indicator.
This uses `display-fill-column-indicator' internally.
To change the position of the column displayed by default
diff --git a/lisp/dnd.el b/lisp/dnd.el
index e641b2843a9..44316154b0f 100644
--- a/lisp/dnd.el
+++ b/lisp/dnd.el
@@ -77,7 +77,7 @@ and is the default except for MS-Windows."
(defcustom dnd-open-file-other-window nil
- "If non-nil, always use find-file-other-window to open dropped files."
+ "If non-nil, always use `find-file-other-window' to open dropped files."
:version "22.1"
:type 'boolean)
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index a0ffcac9f80..11559bf2f50 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -41,7 +41,7 @@
;;
;; C-x C-f ~/path/to/document RET
;;
-;; and the document will be converted and displayed, if your emacs supports PNG
+;; and the document will be converted and displayed, if your Emacs supports PNG
;; images. With `C-c C-c' you can toggle between the rendered images
;; representation and the source text representation of the document.
;;
@@ -493,24 +493,69 @@ Typically \"page-%s.png\".")
(easy-menu-define doc-view-menu doc-view-mode-map
"Menu for Doc View mode."
'("DocView"
- ["Toggle display" doc-view-toggle-display]
- ("Continuous"
+ ["Next page" doc-view-next-page
+ :help "Go to the next page"]
+ ["Previous page" doc-view-previous-page
+ :help "Go to the previous page"]
+ ("Other Navigation"
+ ["Go to page..." doc-view-goto-page
+ :help "Go to specific page"]
+ "---"
+ ["First page" doc-view-first-page
+ :help "View the first page"]
+ ["Last page" doc-view-last-page
+ :help "View the last page"]
+ "---"
+ ["Move forward" doc-view-scroll-up-or-next-page
+ :help "Scroll page up or go to next page"]
+ ["Move backward" doc-view-scroll-down-or-previous-page
+ :help "Scroll page down or go to previous page"])
+ ("Continuous Scrolling"
["Off" (setq doc-view-continuous nil)
- :style radio :selected (eq doc-view-continuous nil)]
+ :style radio :selected (eq doc-view-continuous nil)
+ :help "Scrolling stops at page beginning and end"]
["On" (setq doc-view-continuous t)
- :style radio :selected (eq doc-view-continuous t)]
+ :style radio :selected (eq doc-view-continuous t)
+ :help "Scrolling continues to next or previous page"]
"---"
- ["Save as Default"
- (customize-save-variable 'doc-view-continuous doc-view-continuous) t]
+ ["Save as Default" (customize-save-variable 'doc-view-continuous doc-view-continuous)
+ :help "Save current continuous scrolling option as default"]
)
"---"
- ["Set Slice" doc-view-set-slice-using-mouse]
- ["Set Slice (BoundingBox)" doc-view-set-slice-from-bounding-box]
- ["Set Slice (manual)" doc-view-set-slice]
- ["Reset Slice" doc-view-reset-slice]
+ ("Toggle edit/display"
+ ["Edit document" doc-view-toggle-display
+ :style radio :selected (eq major-mode 'doc-view--text-view-mode)]
+ ["Display document" (lambda ()) ; ignore but show no keybinding
+ :style radio :selected (eq major-mode 'doc-view-mode)])
+ ("Adjust Display"
+ ["Fit to window" doc-view-fit-page-to-window
+ :help "Fit the image to the window"]
+ ["Fit width" doc-view-fit-width-to-window
+ :help "Fit the image width to the window width"]
+ ["Fit height" doc-view-fit-height-to-window
+ :help "Fit the image height to the window height"]
+ "---"
+ ["Enlarge" doc-view-enlarge
+ :help "Enlarge the document"]
+ ["Shrink" doc-view-shrink
+ :help "Shrink the document"]
+ "---"
+ ["Set Slice" doc-view-set-slice-using-mouse
+ :help "Set the slice of the images that should be displayed"]
+ ["Set Slice (BoundingBox)" doc-view-set-slice-from-bounding-box
+ :help "Set the slice from the document's BoundingBox information"]
+ ["Set Slice (manual)" doc-view-set-slice
+ :help "Set the slice of the images that should be displayed"]
+ ["Reset Slice" doc-view-reset-slice
+ :help "Reset the current slice"
+ :enabled (image-mode-window-get 'slice)])
"---"
- ["Search" doc-view-search]
- ["Search Backwards" doc-view-search-backward]
+ ["New Search" (doc-view-search t)
+ :help "Initiate a new search"]
+ ["Search Forward" doc-view-search
+ :help "Jump to the next match or initiate a new search"]
+ ["Search Backward" doc-view-search-backward
+ :help "Jump to the previous match or initiate a new search"]
))
(defvar doc-view-minor-mode-map
@@ -520,6 +565,16 @@ Typically \"page-%s.png\".")
map)
"Keymap used by `doc-view-minor-mode'.")
+(easy-menu-define doc-view-minor-mode-menu doc-view-minor-mode-map
+ "Menu for Doc View minor mode."
+ '("DocView (edit)"
+ ("Toggle edit/display"
+ ["Edit document" (lambda ()) ; ignore but show no keybinding
+ :style radio :selected (eq major-mode 'doc-view--text-view-mode)]
+ ["Display document" doc-view-toggle-display
+ :style radio :selected (eq major-mode 'doc-view-mode)])
+ ["Exit DocView Mode" doc-view-minor-mode]))
+
;;;; Navigation Commands
;; FIXME: The doc-view-current-* definitions below are macros because they
@@ -727,7 +782,7 @@ It's a subdirectory of `doc-view-cache-directory'."
(file-name-as-directory
(expand-file-name
(concat (thread-last
- (file-name-nondirectory doc-view--buffer-file-name)
+ (file-name-nondirectory doc-view--buffer-file-name)
;; bug#13679
(subst-char-in-string ?% ?_)
;; arc-mode concatenates archive name and file name
@@ -756,9 +811,10 @@ OpenDocument format)."
(and doc-view-dvipdfm-program
(executable-find doc-view-dvipdfm-program)))))
((memq type '(postscript ps eps pdf))
- ;; FIXME: allow mupdf here
- (and doc-view-ghostscript-program
- (executable-find doc-view-ghostscript-program)))
+ (or (and doc-view-ghostscript-program
+ (executable-find doc-view-ghostscript-program))
+ (and doc-view-pdfdraw-program
+ (executable-find doc-view-pdfdraw-program))))
((eq type 'odf)
(and doc-view-odf->pdf-converter-program
(executable-find doc-view-odf->pdf-converter-program)
@@ -788,7 +844,7 @@ OpenDocument format)."
(doc-view-reconvert-doc)))))
(defun doc-view-shrink (factor)
- "Shrink the document."
+ "Shrink the document by FACTOR."
(interactive (list doc-view-shrink-factor))
(doc-view-enlarge (/ 1.0 factor)))
@@ -809,7 +865,7 @@ OpenDocument format)."
FACTOR defaults to `doc-view-shrink-factor'.
The actual adjustment made depends on the final component of the
-key-binding used to invoke the command, with all modifiers removed:
+keybinding used to invoke the command, with all modifiers removed:
+, = Increase the image scale by FACTOR
- Decrease the image scale by FACTOR
@@ -1197,7 +1253,7 @@ Start by converting PAGES, and then the rest."
(defun doc-view-current-cache-doc-pdf ()
"Return the name of the doc.pdf in the current cache dir.
- This file exists only if the current document isn't a PDF or PS file already."
+This file exists only if the current document isn't a PDF or PS file already."
(expand-file-name "doc.pdf" (doc-view--current-cache-dir)))
(defun doc-view-doc->txt (txt callback)
@@ -1530,16 +1586,16 @@ have the page we want to view."
(overlay-put (doc-view-current-overlay) 'display
(concat (propertize "Welcome to DocView!" 'face 'bold)
"\n"
- "
+ (substitute-command-keys "
If you see this buffer it means that the document you want to view is being
converted to PNG and the conversion of the first page hasn't finished yet or
`doc-view-conversion-refresh-interval' is set to nil.
For now these keys are useful:
-
-`q' : Bury this buffer. Conversion will go on in background.
-`k' : Kill the conversion process and this buffer.
-`K' : Kill the conversion process.\n"))))
+\\<doc-view-mode-map>
+\\[quit-window] : Bury this buffer. Conversion will go on in background.
+\\[image-kill-buffer] : Kill the conversion process and this buffer.
+\\[doc-view-kill-proc] : Kill the conversion process.\n")))))
(declare-function tooltip-show "tooltip" (text &optional use-echo-area))
diff --git a/lisp/dos-fns.el b/lisp/dos-fns.el
index e0a533c637a..07c77faa23b 100644
--- a/lisp/dos-fns.el
+++ b/lisp/dos-fns.el
@@ -290,14 +290,14 @@ and `dos-set-register-value', which see."
;; set screen size.
(defun dos-mode25 ()
- "Changes the number of screen rows to 25."
+ "Change the number of screen rows to 25."
(interactive)
(set-frame-size (selected-frame) 80 25))
(define-obsolete-function-alias 'mode25 'dos-mode25 "24.1")
(defun dos-mode4350 ()
- "Changes the number of rows to 43 or 50.
+ "Change the number of rows to 43 or 50.
Emacs always tries to set the screen height to 50 rows first.
If this fails, it will try to set it to 43 rows, on the assumption
that your video hardware might not support 50-line mode."
diff --git a/lisp/dos-vars.el b/lisp/dos-vars.el
index 2f7b3760e3f..7fcbb56d224 100644
--- a/lisp/dos-vars.el
+++ b/lisp/dos-vars.el
@@ -34,9 +34,9 @@
:type '(repeat string))
(defcustom dos-codepage-setup-hook nil
- "List of functions to be called after the DOS terminal and coding
-systems are set up. This is the place, e.g., to set specific entries
-in `standard-display-table' as appropriate for your codepage, if
+ "List of functions to call after setting up DOS terminal and coding systems.
+This is the place, e.g., to set specific entries in
+`standard-display-table' as appropriate for your codepage, if
`IT-display-table-setup' doesn't do a perfect job."
:type '(hook)
:version "20.3.3")
diff --git a/lisp/edmacro.el b/lisp/edmacro.el
index 9e4a71c336e..29900a9595c 100644
--- a/lisp/edmacro.el
+++ b/lisp/edmacro.el
@@ -108,7 +108,7 @@ With a prefix argument, format the macro in a more concise way."
(memq cmd-noremap '(call-last-kbd-macro kmacro-call-macro kmacro-end-or-call-macro kmacro-end-and-call-macro))
(member keys '("\r" [return])))
(or last-kbd-macro
- (y-or-n-p "No keyboard macro defined. Create one? ")
+ (y-or-n-p "No keyboard macro defined. Create one?")
(keyboard-quit))
(setq mac (or last-kbd-macro ""))
(setq keys nil)
@@ -244,8 +244,9 @@ or nil, use a compact 80-column format."
(and (fboundp cmd) (not (arrayp (symbol-function cmd)))
(not (get cmd 'kmacro))
(not (y-or-n-p
- (format "Command %s is already defined; %s"
- cmd "proceed? ")))
+ (format
+ "Command %s is already defined; proceed?"
+ cmd)))
(keyboard-quit))))
t)
((looking-at "Key:\\(.*\\)$")
@@ -264,9 +265,9 @@ or nil, use a compact 80-column format."
(not (or (arrayp (symbol-function b))
(get b 'kmacro))))
(not (y-or-n-p
- (format "Key %s is already defined; %s"
- (edmacro-format-keys key 1)
- "proceed? ")))
+ (format
+ "Key %s is already defined; proceed?"
+ (edmacro-format-keys key 1))))
(keyboard-quit))))))
t)
((looking-at "Counter:[ \t]*\\([^ \t\n]*\\)[ \t]*$")
@@ -337,7 +338,7 @@ or nil, use a compact 80-column format."
(funcall finish-hook)))))
(defun edmacro-insert-key (key)
- "Insert the written name of a key in the buffer."
+ "Insert the written name of a KEY in the buffer."
(interactive "kKey to insert: ")
(if (bolp)
(insert (edmacro-format-keys key t) "\n")
@@ -600,9 +601,21 @@ This function assumes that the events can be stored in a string."
(setf (aref seq i) (logand (aref seq i) 127))))
seq)
+;; These are needed in a --without-x build.
+(defvar mouse-wheel-down-event)
+(defvar mouse-wheel-up-event)
+(defvar mouse-wheel-right-event)
+(defvar mouse-wheel-left-event)
+
(defun edmacro-fix-menu-commands (macro &optional noerror)
(if (vectorp macro)
(let (result)
+ ;; Not preloaded in without-x builds.
+ (require 'mwheel)
+ (defvar mouse-wheel-down-event)
+ (defvar mouse-wheel-left-event)
+ (defvar mouse-wheel-right-event)
+ (defvar mouse-wheel-up-event)
;; Make a list of the elements.
(setq macro (append macro nil))
(dolist (ev macro)
@@ -612,7 +625,7 @@ This function assumes that the events can be stored in a string."
((eq (car ev) 'switch-frame))
((equal ev '(menu-bar))
(push 'menu-bar result))
- ((equal (cl-cadadr ev) '(menu-bar))
+ ((equal (cadadr ev) '(menu-bar))
(push (vector 'menu-bar (car ev)) result))
;; It would be nice to do pop-up menus, too, but not enough
;; info is recorded in macros to make this possible.
@@ -633,101 +646,10 @@ This function assumes that the events can be stored in a string."
;;; Parsing a human-readable keyboard macro.
(defun edmacro-parse-keys (string &optional need-vector)
- (let ((case-fold-search nil)
- (len (length string)) ; We won't alter string in the loop below.
- (pos 0)
- (res []))
- (while (and (< pos len)
- (string-match "[^ \t\n\f]+" string pos))
- (let* ((word-beg (match-beginning 0))
- (word-end (match-end 0))
- (word (substring string word-beg len))
- (times 1)
- key)
- ;; Try to catch events of the form "<as df>".
- (if (string-match "\\`<[^ <>\t\n\f][^>\t\n\f]*>" word)
- (setq word (match-string 0 word)
- pos (+ word-beg (match-end 0)))
- (setq word (substring string word-beg word-end)
- pos word-end))
- (when (string-match "\\([0-9]+\\)\\*." word)
- (setq times (string-to-number (substring word 0 (match-end 1))))
- (setq word (substring word (1+ (match-end 1)))))
- (cond ((string-match "^<<.+>>$" word)
- (setq key (vconcat (if (eq (key-binding [?\M-x])
- 'execute-extended-command)
- [?\M-x]
- (or (car (where-is-internal
- 'execute-extended-command))
- [?\M-x]))
- (substring word 2 -2) "\r")))
- ((and (string-match "^\\(\\([ACHMsS]-\\)*\\)<\\(.+\\)>$" word)
- (progn
- (setq word (concat (match-string 1 word)
- (match-string 3 word)))
- (not (string-match
- "\\<\\(NUL\\|RET\\|LFD\\|ESC\\|SPC\\|DEL\\)$"
- word))))
- (setq key (list (intern word))))
- ((or (equal word "REM") (string-match "^;;" word))
- (setq pos (string-match "$" string pos)))
- (t
- (let ((orig-word word) (prefix 0) (bits 0))
- (while (string-match "^[ACHMsS]-." word)
- (cl-incf bits (cdr (assq (aref word 0)
- '((?A . ?\A-\^@) (?C . ?\C-\^@)
- (?H . ?\H-\^@) (?M . ?\M-\^@)
- (?s . ?\s-\^@) (?S . ?\S-\^@)))))
- (cl-incf prefix 2)
- (cl-callf substring word 2))
- (when (string-match "^\\^.$" word)
- (cl-incf bits ?\C-\^@)
- (cl-incf prefix)
- (cl-callf substring word 1))
- (let ((found (assoc word '(("NUL" . "\0") ("RET" . "\r")
- ("LFD" . "\n") ("TAB" . "\t")
- ("ESC" . "\e") ("SPC" . " ")
- ("DEL" . "\177")))))
- (when found (setq word (cdr found))))
- (when (string-match "^\\\\[0-7]+$" word)
- (cl-loop for ch across word
- for n = 0 then (+ (* n 8) ch -48)
- finally do (setq word (vector n))))
- (cond ((= bits 0)
- (setq key word))
- ((and (= bits ?\M-\^@) (stringp word)
- (string-match "^-?[0-9]+$" word))
- (setq key (cl-loop for x across word
- collect (+ x bits))))
- ((/= (length word) 1)
- (error "%s must prefix a single character, not %s"
- (substring orig-word 0 prefix) word))
- ((and (/= (logand bits ?\C-\^@) 0) (stringp word)
- ;; We used to accept . and ? here,
- ;; but . is simply wrong,
- ;; and C-? is not used (we use DEL instead).
- (string-match "[@-_a-z]" word))
- (setq key (list (+ bits (- ?\C-\^@)
- (logand (aref word 0) 31)))))
- (t
- (setq key (list (+ bits (aref word 0)))))))))
- (when key
- (cl-loop repeat times do (cl-callf vconcat res key)))))
- (when (and (>= (length res) 4)
- (eq (aref res 0) ?\C-x)
- (eq (aref res 1) ?\()
- (eq (aref res (- (length res) 2)) ?\C-x)
- (eq (aref res (- (length res) 1)) ?\)))
- (setq res (cl-subseq res 2 -2)))
- (if (and (not need-vector)
- (cl-loop for ch across res
- always (and (characterp ch)
- (let ((ch2 (logand ch (lognot ?\M-\^@))))
- (and (>= ch2 0) (<= ch2 127))))))
- (concat (cl-loop for ch across res
- collect (if (= (logand ch ?\M-\^@) 0)
- ch (+ ch 128))))
- res)))
+ (let ((result (kbd string)))
+ (if (and need-vector (stringp result))
+ (seq-into result 'vector)
+ result)))
(provide 'edmacro)
diff --git a/lisp/elec-pair.el b/lisp/elec-pair.el
index d8c377a2ef5..f907bba4c6e 100644
--- a/lisp/elec-pair.el
+++ b/lisp/elec-pair.el
@@ -63,7 +63,7 @@ When inserting a closing paren character right before the same character,
just skip that character instead, so that hitting ( followed by ) results
in \"()\" rather than \"())\".
-This can be convenient for people who find it easier to hit ) than C-f.
+This can be convenient for people who find it easier to hit ) than \\[forward-char].
Can also be a function of one argument (the closer char just
inserted), in which case that function's return value is
@@ -238,9 +238,9 @@ inside a comment or string."
(self-insert-command 1)))
(cl-defmacro electric-pair--with-uncached-syntax ((table &optional start) &rest body)
- "Like `with-syntax-table', but flush the syntax-ppss cache afterwards.
+ "Like `with-syntax-table', but flush the `syntax-ppss' cache afterwards.
Use this instead of (with-syntax-table TABLE BODY) when BODY
-contains code which may update the syntax-ppss cache. This
+contains code which may update the `syntax-ppss' cache. This
includes calling `parse-partial-sexp' and any sexp-based movement
functions when `parse-sexp-lookup-properties' is non-nil. The
cache is flushed from position START, defaulting to point."
@@ -308,51 +308,51 @@ If point is not enclosed by any lists, return ((t) . (t))."
;; called when `scan-sexps' ran perfectly, when it found
;; a parenthesis pointing in the direction of travel.
;; Also when travel started inside a comment and exited it.
- #'(lambda ()
- (setq outermost (list t))
- (unless innermost
- (setq innermost (list t)))))
+ (lambda ()
+ (setq outermost (list t))
+ (unless innermost
+ (setq innermost (list t)))))
(ended-prematurely-fn
;; called when `scan-sexps' crashed against a parenthesis
;; pointing opposite the direction of travel. After
;; traversing that character, the idea is to travel one sexp
;; in the opposite direction looking for a matching
;; delimiter.
- #'(lambda ()
- (let* ((pos (point))
- (matched
- (save-excursion
- (cond ((< direction 0)
- (condition-case nil
- (eq (char-after pos)
- (electric-pair--with-uncached-syntax
- (table)
- (matching-paren
- (char-before
- (scan-sexps (point) 1)))))
- (scan-error nil)))
- (t
- ;; In this case, no need to use
- ;; `scan-sexps', we can use some
- ;; `electric-pair--syntax-ppss' in this
- ;; case (which uses the quicker
- ;; `syntax-ppss' in some cases)
- (let* ((ppss (electric-pair--syntax-ppss
- (1- (point))))
- (start (car (last (nth 9 ppss))))
- (opener (char-after start)))
- (and start
- (eq (char-before pos)
- (or (with-syntax-table table
- (matching-paren opener))
- opener))))))))
- (actual-pair (if (> direction 0)
- (char-before (point))
- (char-after (point)))))
- (unless innermost
- (setq innermost (cons matched actual-pair)))
- (unless matched
- (setq outermost (cons matched actual-pair)))))))
+ (lambda ()
+ (let* ((pos (point))
+ (matched
+ (save-excursion
+ (cond ((< direction 0)
+ (condition-case nil
+ (eq (char-after pos)
+ (electric-pair--with-uncached-syntax
+ (table)
+ (matching-paren
+ (char-before
+ (scan-sexps (point) 1)))))
+ (scan-error nil)))
+ (t
+ ;; In this case, no need to use
+ ;; `scan-sexps', we can use some
+ ;; `electric-pair--syntax-ppss' in this
+ ;; case (which uses the quicker
+ ;; `syntax-ppss' in some cases)
+ (let* ((ppss (electric-pair--syntax-ppss
+ (1- (point))))
+ (start (car (last (nth 9 ppss))))
+ (opener (char-after start)))
+ (and start
+ (eq (char-before pos)
+ (or (with-syntax-table table
+ (matching-paren opener))
+ opener))))))))
+ (actual-pair (if (> direction 0)
+ (char-before (point))
+ (char-after (point)))))
+ (unless innermost
+ (setq innermost (cons matched actual-pair)))
+ (unless matched
+ (setq outermost (cons matched actual-pair)))))))
(save-excursion
(while (not outermost)
(condition-case err
@@ -485,6 +485,27 @@ happened."
(electric-pair-conservative-inhibit char)))
(defun electric-pair-post-self-insert-function ()
+ "Member of `post-self-insert-hook'. Do main work for `electric-pair-mode'.
+If the newly inserted character C has delimiter syntax, this
+function may decide to insert additional paired delimiters, or
+skip the insertion of the new character altogether by jumping
+over an existing identical character, or do nothing.
+
+The decision is taken by order of preference:
+
+* According to `use-region-p'. If this returns non-nil this
+ function will unconditionally \"wrap\" the region in the
+ corresponding delimiter for C;
+
+* According to C alone, by looking C up in the tables
+ `electric-pair-paris' or `electric-pair-text-pairs' (which
+ see);
+
+* According to C's syntax and the syntactic state of the buffer
+ (both as defined by the major mode's syntax table). This is
+ done by looking up up the variables
+ `electric-pair-inhibit-predicate', `electric-pair-skip-self'
+ and `electric-pair-skip-whitespace' (which see)."
(let* ((pos (and electric-pair-mode (electric--after-char-pos)))
(skip-whitespace-info))
(pcase (electric-pair-syntax-info last-command-event)
@@ -551,18 +572,21 @@ happened."
(goto-char pos)
(funcall electric-pair-inhibit-predicate
last-command-event)))))
- (save-excursion (electric-pair--insert pair)))))
- (_
- (when (and (if (functionp electric-pair-open-newline-between-pairs)
- (funcall electric-pair-open-newline-between-pairs)
- electric-pair-open-newline-between-pairs)
- (eq last-command-event ?\n)
- (< (1+ (point-min)) (point) (point-max))
- (eq (save-excursion
- (skip-chars-backward "\t\s")
- (char-before (1- (point))))
- (matching-paren (char-after))))
- (save-excursion (newline 1 t)))))))
+ (save-excursion (electric-pair--insert pair))))))))
+
+(defun electric-pair-open-newline-between-pairs-psif ()
+ "Honour `electric-pair-open-newline-between-pairs'.
+Member of `post-self-insert-hook' if `electric-pair-mode' is on."
+ (when (and (if (functionp electric-pair-open-newline-between-pairs)
+ (funcall electric-pair-open-newline-between-pairs)
+ electric-pair-open-newline-between-pairs)
+ (eq last-command-event ?\n)
+ (< (1+ (point-min)) (point) (point-max))
+ (eq (save-excursion
+ (skip-chars-backward "\t\s")
+ (char-before (1- (point))))
+ (matching-paren (char-after))))
+ (save-excursion (newline 1 t))))
(defun electric-pair-will-use-region ()
(and (use-region-p)
@@ -623,10 +647,15 @@ To toggle the mode in a single buffer, use `electric-pair-local-mode'."
;; `electric-indent-mode' are used together.
;; Use `vc-region-history' on these lines for more info.
50)
+ (add-hook 'post-self-insert-hook
+ #'electric-pair-open-newline-between-pairs-psif
+ 50)
(add-hook 'self-insert-uses-region-functions
#'electric-pair-will-use-region))
(remove-hook 'post-self-insert-hook
#'electric-pair-post-self-insert-function)
+ (remove-hook 'post-self-insert-hook
+ #'electric-pair-open-newline-between-pairs-psif)
(remove-hook 'self-insert-uses-region-functions
#'electric-pair-will-use-region)))
diff --git a/lisp/electric.el b/lisp/electric.el
index 4394fae4366..a2f24ca05c6 100644
--- a/lisp/electric.el
+++ b/lisp/electric.el
@@ -506,11 +506,11 @@ This list's members correspond to left single quote, right single
quote, left double quote, and right double quote, respectively."
:version "26.1"
:type '(list character character character character)
- :safe #'(lambda (x)
- (pcase x
- (`(,(pred characterp) ,(pred characterp)
- ,(pred characterp) ,(pred characterp))
- t)))
+ :safe (lambda (x)
+ (pcase x
+ (`(,(pred characterp) ,(pred characterp)
+ ,(pred characterp) ,(pred characterp))
+ t)))
:group 'electricity)
(defcustom electric-quote-paragraph t
diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el
index 8e8d0e22651..15e413e0e8f 100644
--- a/lisp/emacs-lisp/advice.el
+++ b/lisp/emacs-lisp/advice.el
@@ -36,12 +36,12 @@
;; @ Introduction:
;; ===============
;; This package implements a full-fledged Lisp-style advice mechanism
-;; for Emacs Lisp. Advice is a clean and efficient way to modify the
+;; for Emacs Lisp. Advice is a clean and efficient way to modify the
;; behavior of Emacs Lisp functions without having to keep personal
-;; modified copies of such functions around. A great number of such
+;; modified copies of such functions around. A great number of such
;; modifications can be achieved by treating the original function as a
;; black box and specifying a different execution environment for it
-;; with a piece of advice. Think of a piece of advice as a kind of fancy
+;; with a piece of advice. Think of a piece of advice as a kind of fancy
;; hook that you can attach to any function/macro/subr.
;; @ Highlights:
@@ -95,7 +95,7 @@
;; @ Restrictions:
;; ===============
;; - Advised functions/macros/subrs will only exhibit their advised behavior
-;; when they are invoked via their function cell. This means that advice will
+;; when they are invoked via their function cell. This means that advice will
;; not work for the following:
;; + advised subrs that are called directly from other subrs or C-code
;; + advised subrs that got replaced with their byte-code during
@@ -107,7 +107,7 @@
;; ==========
;; This package is an extension and generalization of packages such as
;; insert-hooks.el written by Noah S. Friedman, and advise.el written by
-;; Raul J. Acevedo. Some ideas used in here come from these packages,
+;; Raul J. Acevedo. Some ideas used in here come from these packages,
;; others come from the various Lisp advice mechanisms I've come across
;; so far, and a few are simply mine.
@@ -235,10 +235,10 @@
;; found in the list of before/around/after advices will be used.
;; <flags> is a list of symbols that specify further information about the
-;; advice. All flags can be specified with unambiguous initial substrings.
+;; advice. All flags can be specified with unambiguous initial substrings.
;; `activate': Specifies that the advice information of the advised
;; function should be activated right after this advice has been
-;; defined. In forward advices `activate' will be ignored.
+;; defined. In forward advices `activate' will be ignored.
;; `protect': Specifies that this advice should be protected against
;; non-local exits and errors in preceding code/advices.
;; `compile': Specifies that the advised function should be byte-compiled.
@@ -347,7 +347,7 @@
;; argument list redefinition given in a piece of advice. While this simple
;; method might be sufficient in many cases, it has the disadvantage that it
;; is not very portable because it hardcodes the argument names into the
-;; advice. If the definition of the original function changes the advice
+;; advice. If the definition of the original function changes the advice
;; might break even though the code might still be correct. Situations like
;; that arise, for example, if one advises a subr like `eval-region' which
;; gets redefined in a non-advice style into a function by the edebug
@@ -443,7 +443,7 @@
;; of the advised function we need a mapping mechanism that maps this
;; argument list onto that of the original function. Hence SYM and
;; NEWDEF have to be properly mapped onto the &rest variable when the
-;; original definition is called. Advice automatically takes care of
+;; original definition is called. Advice automatically takes care of
;; that mapping, hence, the advice programmer can specify an argument
;; list without having to know about the exact structure of the
;; original argument list as long as the new argument list takes a
@@ -467,7 +467,7 @@
;; The advised definition will get compiled either if `ad-activate' was called
;; interactively with a prefix argument, or called explicitly with its second
;; argument as t, or, if `ad-default-compilation-action' justifies it according
-;; to the current system state. If the advised definition was
+;; to the current system state. If the advised definition was
;; constructed during "preactivation" (see below) then that definition will
;; be already compiled because it was constructed during byte-compilation of
;; the file that contained the `defadvice' with the `preactivate' flag.
@@ -707,7 +707,7 @@
;; @@ Adding a piece of advice with `ad-add-advice':
;; =================================================
;; The non-interactive function `ad-add-advice' can be used to add a piece of
-;; advice to some function without using `defadvice'. This is useful if advice
+;; advice to some function without using `defadvice'. This is useful if advice
;; has to be added somewhere by a function (also look at `ad-make-advice').
;; @@ Activation/deactivation advices, file load hooks:
@@ -739,7 +739,7 @@
;; A piece of advice gets defined with `defadvice' and added to the
;; `advice-info' property of a function.
;; - Enablement:
-;; Every piece of advice has an enablement flag associated with it. Only
+;; Every piece of advice has an enablement flag associated with it. Only
;; enabled advices are considered during construction of an advised
;; definition.
;; - Activation:
@@ -808,9 +808,9 @@
;; argument access text macros to get/set the values of
;; actual arguments at a certain position
;; ad-arg-bindings text macro that returns the actual names, values
-;; and types of the arguments as a list of bindings. The
+;; and types of the arguments as a list of bindings. The
;; order of the bindings corresponds to the order of the
-;; arguments. The individual fields of every binding (name,
+;; arguments. The individual fields of every binding (name,
;; value and type) can be accessed with the function
;; `ad-arg-binding-field' (see example above).
;; ad-do-it text macro that identifies the place where the original
@@ -839,20 +839,20 @@
;; use the macro `defadvice' which takes a function name, a list of advice
;; specifiers and a list of body forms as arguments. The first element of
;; the advice specifiers is the class of the advice, the second is its name,
-;; the third its position and the rest are some flags. The class of our
+;; the third its position and the rest are some flags. The class of our
;; first advice is `before', its name is `fg-add2', its position among the
;; currently defined before advices (none so far) is `first', and the advice
-;; will be `activate'ed immediately. Advice names are global symbols, hence,
-;; the name space conventions used for function names should be applied. All
+;; will be `activate'ed immediately. Advice names are global symbols, hence,
+;; the name space conventions used for function names should be applied. All
;; advice names in this tutorial will be prefixed with `fg' for `Foo Games'
;; (because everybody has the right to be inconsistent all the function names
;; used in this tutorial do NOT follow this convention).
;;
;; In the body of an advice we can refer to the argument variables of the
-;; original function by name. Here we add 1 to X so the effect of calling
+;; original function by name. Here we add 1 to X so the effect of calling
;; `foo' will be to actually add 2. All of the advice definitions below only
;; have one body form for simplicity, but there is no restriction to that
-;; extent. Every piece of advice can have a documentation string which will
+;; extent. Every piece of advice can have a documentation string which will
;; be combined with the documentation of the original function.
;;
;; (defadvice foo (before fg-add2 first activate)
@@ -866,11 +866,11 @@
;; @@ Specifying the position of an advice:
;; ========================================
;; Now we define the second before advice which will cancel the effect of
-;; the previous advice. This time we specify the position as 0 which is
-;; equivalent to `first'. A number can be used to specify the zero-based
-;; position of an advice among the list of advices in the same class. This
+;; the previous advice. This time we specify the position as 0 which is
+;; equivalent to `first'. A number can be used to specify the zero-based
+;; position of an advice among the list of advices in the same class. This
;; time we already have one before advice hence the position specification
-;; actually has an effect. So, after the following definition the position
+;; actually has an effect. So, after the following definition the position
;; of the previous advice will be 1 even though we specified it with `first'
;; above, the reason for this is that the position argument is relative to
;; the currently defined pieces of advice which by now has changed.
@@ -886,7 +886,7 @@
;; @@ Redefining a piece of advice:
;; ================================
;; Now we define an advice with the same class and same name but with a
-;; different position. Defining an advice in a class in which an advice with
+;; different position. Defining an advice in a class in which an advice with
;; that name already exists is interpreted as a redefinition of that
;; particular advice, in which case the position argument will be ignored
;; and the previous position of the redefined piece of advice is used.
@@ -919,7 +919,7 @@
;; =================================
;; We can make a function interactive (or change its interactive behavior)
;; by specifying an interactive form in one of the before or around
-;; advices (there could also be body forms in this advice). The particular
+;; advices (there could also be body forms in this advice). The particular
;; definition always assigns 5 as an argument to X which gives us 6 as a
;; result when we call foo interactively:
;;
@@ -945,13 +945,13 @@
;;
;; @@ Around advices:
;; ==================
-;; Now we'll try some `around' advices. An around advice is a wrapper around
-;; the original definition. It can shadow or establish bindings for the
+;; Now we'll try some `around' advices. An around advice is a wrapper around
+;; the original definition. It can shadow or establish bindings for the
;; original definition, and it can look at and manipulate the value returned
-;; by the original function. The position of the special keyword `ad-do-it'
-;; specifies where the code of the original function will be executed. The
+;; by the original function. The position of the special keyword `ad-do-it'
+;; specifies where the code of the original function will be executed. The
;; keyword can appear multiple times which will result in multiple calls of
-;; the original function in the resulting advised code. Note, that if we don't
+;; the original function in the resulting advised code. Note, that if we don't
;; specify a position argument (i.e., `first', `last' or a number), then
;; `first' (or 0) is the default):
;;
@@ -967,7 +967,7 @@
;; Around advices are assembled like onion skins where the around advice
;; with position 0 is the outermost skin and the advice at the last position
;; is the innermost skin which is directly wrapped around the call of the
-;; original definition of the function. Hence, after the next `defadvice' we
+;; original definition of the function. Hence, after the next `defadvice' we
;; will first multiply X by 2 then add 1 and then call the original
;; definition (i.e., add 1 again):
;;
@@ -984,8 +984,8 @@
;; =================================
;; In every `defadvice' so far we have used the flag `activate' to activate
;; the advice immediately after its definition, and that's what we want in
-;; most cases. However, if we define multiple pieces of advice for a single
-;; function then activating every advice immediately is inefficient. A
+;; most cases. However, if we define multiple pieces of advice for a single
+;; function then activating every advice immediately is inefficient. A
;; better way to do this is to only activate the last defined advice.
;; For example:
;;
@@ -1033,7 +1033,7 @@
;;
;; To make sure a certain piece of advice gets executed even if some error or
;; non-local exit occurred in any preceding code, we can protect it by using
-;; the `protect' keyword. (if any of the around advices is protected then the
+;; the `protect' keyword (if any of the around advices is protected then the
;; whole around advice onion will be protected):
;;
;; (defadvice foo (after fg-cleanup prot act)
@@ -1077,7 +1077,7 @@
;; neutralize the effect of the advice of one of the packages.
;;
;; The following disables the after advice `fg-times-x' in the function `foo'.
-;; All that does is to change a flag for this particular advice. All the
+;; All that does is to change a flag for this particular advice. All the
;; other information defining it will be left unchanged (e.g., its relative
;; position in this advice class, etc.).
;;
@@ -1094,9 +1094,9 @@
;; 24
;;
;; If we want to disable all multiplication advices in `foo' we can use a
-;; regular expression that matches the names of such advices. Actually, any
+;; regular expression that matches the names of such advices. Actually, any
;; advice name that contains a match for the regular expression will be
-;; called a match. A special advice class `any' can be used to consider
+;; called a match. A special advice class `any' can be used to consider
;; all advice classes:
;;
;; (ad-disable-advice 'foo 'any "^fg-.*times")
@@ -1122,7 +1122,7 @@
;; 9
;;
;; The following will activate all currently active advised functions that
-;; contain some advice matched by the regular expression. This is a save
+;; contain some advice matched by the regular expression. This is a save
;; way to update the activation of advised functions whose advice changed
;; in some way or other without accidentally also activating currently
;; inactive functions:
@@ -1136,7 +1136,7 @@
;;
;; Another use for the dis/enablement mechanism is to define a piece of advice
;; and keep it "dormant" until a particular condition is satisfied, i.e., until
-;; then the advice will not be used during activation. The `disable' flag lets
+;; then the advice will not be used during activation. The `disable' flag lets
;; one do that with `defadvice':
;;
;; (defadvice foo (before fg-1-more dis)
@@ -1165,7 +1165,7 @@
;; ===========
;; Advised definitions get cached to allow efficient activation/deactivation
;; without having to reconstruct them if nothing in the advice-info of a
-;; function has changed. The following idiom can be used to temporarily
+;; function has changed. The following idiom can be used to temporarily
;; deactivate functions that have a piece of advice defined by a certain
;; package (we save the old definition to check out caching):
;;
@@ -1350,9 +1350,9 @@
;; @@ Portable argument access:
;; ============================
;; So far, we always used the actual argument variable names to access an
-;; argument in a piece of advice. For many advice applications this is
-;; perfectly ok and keeps advices simple. However, it decreases portability
-;; of advices because it assumes specific argument variable names. For example,
+;; argument in a piece of advice. For many advice applications this is
+;; perfectly ok and keeps advices simple. However, it decreases portability
+;; of advices because it assumes specific argument variable names. For example,
;; if one advises a subr such as `eval-region' which then gets redefined by
;; some package (e.g., edebug) into a function with different argument names,
;; then a piece of advice written for `eval-region' that was written with
@@ -1360,7 +1360,7 @@
;;
;; Argument access text macros allow one to access arguments of an advised
;; function in a portable way without having to worry about all these
-;; possibilities. These macros will be translated into the proper access forms
+;; possibilities. These macros will be translated into the proper access forms
;; at activation time, hence, argument access will be as efficient as if
;; the arguments had been used directly in the definition of the advice.
;;
@@ -1386,7 +1386,7 @@
;; (fuu 1 1 1)
;; 6
;;
-;; Now suppose somebody redefines `fuu' with a rest argument. Our advice
+;; Now suppose somebody redefines `fuu' with a rest argument. Our advice
;; will still work because we used access macros (note, that automatic
;; advice activation is still in effect, hence, the redefinition of `fuu'
;; will automatically activate all its advice):
@@ -1444,9 +1444,9 @@
;; give it an extra argument that controls the advised code, for example, one
;; might want to make an interactive function sensitive to a prefix argument.
;; For such cases `defadvice' allows the specification of an argument list
-;; for the advised function. Similar to the redefinition of interactive
+;; for the advised function. Similar to the redefinition of interactive
;; behavior, the first argument list specification found in the list of before/
-;; around/after advices will be used. Of course, the specified argument list
+;; around/after advices will be used. Of course, the specified argument list
;; should be downward compatible with the original argument list, otherwise
;; functions that call the advised function with the original argument list
;; in mind will break.
@@ -1457,9 +1457,9 @@
;; fii
;;
;; Now we advise `fii' to use an optional second argument that controls the
-;; amount of incrementing. A list following the (optional) position
+;; amount of incrementing. A list following the (optional) position
;; argument of the advice will be interpreted as an argument list
-;; specification. This means you cannot specify an empty argument list, and
+;; specification. This means you cannot specify an empty argument list, and
;; why would you want to anyway?
;;
;; (defadvice fii (before fg-inc-x (x &optional incr) act)
@@ -1476,22 +1476,22 @@
;; @@ Advising interactive subrs:
;; ==============================
;; For the most part there is no difference between advising functions and
-;; advising subrs. There is one situation though where one might have to write
-;; slightly different advice code for subrs than for functions. This case
+;; advising subrs. There is one situation though where one might have to write
+;; slightly different advice code for subrs than for functions. This case
;; arises when one wants to access subr arguments in a before/around advice
;; when the arguments were determined by an interactive call to the subr.
;; Advice cannot determine what `interactive' form determines the interactive
;; behavior of the subr, hence, when it calls the original definition in an
;; interactive subr invocation it has to use `call-interactively' to generate
-;; the proper interactive behavior. Thus up to that call the arguments of the
-;; interactive subr will be nil. For example, the following advice for
+;; the proper interactive behavior. Thus up to that call the arguments of the
+;; interactive subr will be nil. For example, the following advice for
;; `kill-buffer' will not work in an interactive invocation...
;;
;; (defadvice kill-buffer (before fg-kill-buffer-hook first act preact comp)
;; (my-before-kill-buffer-hook (ad-get-arg 0)))
;; kill-buffer
;;
-;; ...because the buffer argument will be nil in that case. The way out of
+;; ...because the buffer argument will be nil in that case. The way out of
;; this dilemma is to provide an `interactive' specification that mirrors
;; the interactive behavior of the unadvised subr, for example, the following
;; will do the right thing even when `kill-buffer' is called interactively:
@@ -1508,10 +1508,10 @@
;; For an advised macro instead of evaluating the original definition we
;; use `macroexpand', that is, changing argument values and binding
;; environments by pieces of advice has an affect during macro expansion
-;; but not necessarily during evaluation. In particular, any side effects
+;; but not necessarily during evaluation. In particular, any side effects
;; of pieces of advice will occur during macro expansion. To also affect
;; the behavior during evaluation time one has to change the value of
-;; `ad-return-value' in a piece of after advice. For example:
+;; `ad-return-value' in a piece of after advice. For example:
;;
;; (defmacro foom (x)
;; `(list ,x))
@@ -1562,7 +1562,7 @@
;; because it allows one to influence macro expansion as well as evaluation.
;; In general, advising macros should be a rather rare activity anyway, in
;; particular, because compile-time macro expansion takes away a lot of the
-;; flexibility and effectiveness of the advice mechanism. Macros that were
+;; flexibility and effectiveness of the advice mechanism. Macros that were
;; compile-time expanded before the advice was activated will of course never
;; exhibit the advised behavior.
@@ -3105,7 +3105,7 @@ The syntax of `defadvice' is as follows:
FUNCTION ::= Name of the function to be advised.
CLASS ::= `before' | `around' | `after' | `activation' | `deactivation'.
NAME ::= Non-nil symbol that names this piece of advice.
-POSITION ::= `first' | `last' | NUMBER. Optional, defaults to `first',
+POSITION ::= `first' | `last' | NUMBER. Optional, defaults to `first',
see also `ad-add-advice'.
ARGLIST ::= An optional argument list to be used for the advised function
instead of the argument list of the original. The first one found in
diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el
index e9a20634af8..d8b4c1f8850 100644
--- a/lisp/emacs-lisp/autoload.el
+++ b/lisp/emacs-lisp/autoload.el
@@ -25,14 +25,14 @@
;; This code helps GNU Emacs maintainers keep the loaddefs.el file up to
;; date. It interprets magic cookies of the form ";;;###autoload" in
-;; lisp source files in various useful ways. To learn more, read the
+;; Lisp source files in various useful ways. To learn more, read the
;; source; if you're going to use this, you'd better be able to.
;;; Code:
(require 'lisp-mode) ;for `doc-string-elt' properties.
(require 'lisp-mnt)
-(eval-when-compile (require 'cl-lib))
+(require 'cl-lib)
(defvar generated-autoload-file nil
"File into which to write autoload definitions.
@@ -393,6 +393,8 @@ FILE's name."
(concat ";;; " basename
" --- automatically extracted " (or type "autoloads")
" -*- lexical-binding: t -*-\n"
+ (when (string-match "/lisp/loaddefs\\.el\\'" file)
+ ";; This file will be copied to ldefs-boot.el and checked in periodically.\n")
";;\n"
";;; Code:\n\n"
(if lp
@@ -432,8 +434,10 @@ FILE's name."
file)
(defun autoload-insert-section-header (outbuf autoloads load-name file time)
- "Insert the section-header line,
-which lists the file name and which functions are in it, etc."
+ "Insert into buffer OUTBUF the section-header line for FILE.
+The header line lists the file name, its \"load name\", its autoloads,
+and the time the FILE was last updated (the time is inserted only
+if `autoload-timestamps' is non-nil, otherwise a fixed fake time is inserted)."
;; (cl-assert ;Make sure we don't insert it in the middle of another section.
;; (save-excursion
;; (or (not (re-search-backward
@@ -460,7 +464,7 @@ which lists the file name and which functions are in it, etc."
(insert "\n" generate-autoload-section-continuation))))))
(defun autoload-find-file (file)
- "Fetch file and put it in a temp buffer. Return the buffer."
+ "Fetch FILE and put it in a temp buffer. Return the buffer."
;; It is faster to avoid visiting the file.
(setq file (expand-file-name file))
(with-current-buffer (get-buffer-create " *autoload-file*")
@@ -480,10 +484,10 @@ which lists the file name and which functions are in it, etc."
"File local variable to prevent scanning this file for autoload cookies.")
(defun autoload-file-load-name (file outfile)
- "Compute the name that will be used to load FILE."
- ;; OUTFILE should be the name of the global loaddefs.el file, which
- ;; is expected to be at the root directory of the files we're
- ;; scanning for autoloads and will be in the `load-path'.
+ "Compute the name that will be used to load FILE.
+OUTFILE should be the name of the global loaddefs.el file, which
+is expected to be at the root directory of the files we are
+scanning for autoloads and will be in the `load-path'."
(let* ((name (file-relative-name file (file-name-directory outfile)))
(names '())
(dir (file-name-directory outfile)))
@@ -1192,9 +1196,17 @@ directory or directories specified."
(goto-char (point-max))
(search-backward "\f" nil t)
(autoload-insert-section-header
- (current-buffer) nil nil no-autoloads (if autoload-timestamps
- no-autoloads-time
- autoload--non-timestamp))
+ (current-buffer) nil nil
+ ;; Filter out the other loaddefs files, because it makes
+ ;; the list unstable (and leads to spurious changes in
+ ;; ldefs-boot.el) since the loaddef files can be created in
+ ;; any order.
+ (seq-filter (lambda (file)
+ (not (string-match-p "[/-]loaddefs.el" file)))
+ no-autoloads)
+ (if autoload-timestamps
+ no-autoloads-time
+ autoload--non-timestamp))
(insert generate-autoload-section-trailer)))
;; Don't modify the file if its content has not been changed, so `make'
diff --git a/lisp/emacs-lisp/avl-tree.el b/lisp/emacs-lisp/avl-tree.el
index 4382985eb85..3f803107a17 100644
--- a/lisp/emacs-lisp/avl-tree.el
+++ b/lisp/emacs-lisp/avl-tree.el
@@ -330,8 +330,7 @@ inserted data."
data)))
(if (or (funcall cmpfun newdata data)
(funcall cmpfun data newdata))
- (error "avl-tree-enter:\
- updated data does not match existing data"))
+ (error "avl-tree-enter: Updated data does not match existing data"))
(setf (avl-tree--node-data br) newdata)
(cons nil newdata)) ; return value
))))
diff --git a/lisp/emacs-lisp/backquote.el b/lisp/emacs-lisp/backquote.el
index 173c11644d5..fe39e8d0999 100644
--- a/lisp/emacs-lisp/backquote.el
+++ b/lisp/emacs-lisp/backquote.el
@@ -103,7 +103,10 @@ b => (ba bb bc) ; assume b has this value
\\=`(a ,b c) => (a (ba bb bc) c) ; insert the value of b
\\=`(a ,@b c) => (a ba bb bc c) ; splice in the value of b
-Vectors work just like lists. Nested backquotes are permitted."
+Vectors work just like lists. Nested backquotes are permitted.
+
+Note that some macros, such as `pcase', use this symbol for other
+purposes."
(cdr (backquote-process structure)))
;; GNU Emacs has no reader macros
diff --git a/lisp/emacs-lisp/backtrace.el b/lisp/emacs-lisp/backtrace.el
index ea70baa9532..a8b484aee0b 100644
--- a/lisp/emacs-lisp/backtrace.el
+++ b/lisp/emacs-lisp/backtrace.el
@@ -55,9 +55,9 @@ order to debug the code that does fontification."
(defcustom backtrace-line-length 5000
"Target length for lines in Backtrace buffers.
Backtrace mode will attempt to abbreviate printing of backtrace
-frames to make them shorter than this, but success is not
-guaranteed. If set to nil or zero, Backtrace mode will not
-abbreviate the forms it prints."
+frames by setting `print-level' and `print-length' to make them
+shorter than this, but success is not guaranteed. If set to nil
+or zero, backtrace mode will not abbreviate the forms it prints."
:type 'integer
:group 'backtrace
:version "27.1")
@@ -751,6 +751,13 @@ property for use by navigation."
(insert (make-string (- backtrace--flags-width (- (point) beg)) ?\s))
(put-text-property beg (point) 'backtrace-section 'func)))
+(defun backtrace--line-length-or-nil ()
+ "Return `backtrace-line-length' if valid, nil else."
+ ;; mirror the logic in `cl-print-to-string-with-limits'
+ (and (natnump backtrace-line-length)
+ (not (zerop backtrace-line-length))
+ backtrace-line-length))
+
(defun backtrace--print-func-and-args (frame _view)
"Print the function, arguments and buffer position of a backtrace FRAME.
Format it according to VIEW."
@@ -769,11 +776,16 @@ Format it according to VIEW."
(if (atom fun)
(funcall backtrace-print-function fun)
(insert
- (backtrace--print-to-string fun (when args (/ backtrace-line-length 2)))))
+ (backtrace--print-to-string
+ fun
+ (when (and args (backtrace--line-length-or-nil))
+ (/ backtrace-line-length 2)))))
(if args
(insert (backtrace--print-to-string
- args (max (truncate (/ backtrace-line-length 5))
- (- backtrace-line-length (- (point) beg)))))
+ args
+ (if (backtrace--line-length-or-nil)
+ (max (truncate (/ backtrace-line-length 5))
+ (- backtrace-line-length (- (point) beg))))))
;; The backtrace-form property is so that backtrace-multi-line
;; will find it. backtrace-multi-line doesn't do anything
;; useful with it, just being consistent.
@@ -868,7 +880,7 @@ commands.
\\{backtrace-mode-map}
A mode which inherits from Backtrace mode, or a command which
-creates a backtrace-mode buffer, should usually do the following:
+creates a `backtrace-mode' buffer, should usually do the following:
- Set `backtrace-revert-hook', if the buffer contents need
to be specially recomputed prior to `revert-buffer'.
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 6475f69eded..2bdf1f55111 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -202,7 +202,7 @@
(intern (substring (symbol-name arg) 5))
arg)
(if (integerp (setq c (car arg)))
- (error "non-symbolic byte-op %s" c))
+ (error "Non-symbolic byte-op %s" c))
(if (eq c 'TAG)
(setq c arg)
(setq a (cond ((memq c byte-goto-ops)
@@ -310,13 +310,6 @@ Earlier variables shadow later ones with the same name.")
;;; implementing source-level optimizers
-(defvar byte-optimize--vars-outside-condition nil
- "Alist of variables lexically bound outside conditionally executed code.
-Variables here are sensitive to mutation inside the conditional code,
-since their contents in sequentially later code depends on the path taken
-and may no longer be statically known.
-Same format as `byte-optimize--lexvars', with shared structure and contents.")
-
(defvar byte-optimize--vars-outside-loop nil
"Alist of variables lexically bound outside the innermost `while' loop.
Variables here are sensitive to mutation inside the loop, since this can
@@ -324,9 +317,20 @@ occur an indeterminate number of times and thus have effect on code
sequentially preceding the mutation itself.
Same format as `byte-optimize--lexvars', with shared structure and contents.")
+(defvar byte-optimize--inhibit-outside-loop-constprop nil
+ "If t, don't propagate values for variables declared outside the inner loop.
+This indicates the loop discovery phase.")
+
(defvar byte-optimize--dynamic-vars nil
"List of variables declared as dynamic during optimisation.")
+(defvar byte-optimize--aliased-vars nil
+ "List of variables which may be aliased by other lexical variables.
+If an entry in `byte-optimize--lexvars' has another variable as its VALUE,
+then that other variable must be in this list.
+This variable thus carries no essential information but is maintained
+for speeding up processing.")
+
(defun byte-optimize--substitutable-p (expr)
"Whether EXPR is a constant that can be propagated."
;; Only consider numbers, symbols and strings to be values for substitution
@@ -338,8 +342,12 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.")
(numberp expr)
(stringp expr)
(and (consp expr)
- (memq (car expr) '(quote function))
- (symbolp (cadr expr)))
+ (or (and (memq (car expr) '(quote function))
+ (symbolp (cadr expr)))
+ ;; (internal-get-closed-var N) can be considered constant for
+ ;; const-prop purposes.
+ (and (eq (car expr) 'internal-get-closed-var)
+ (integerp (cadr expr)))))
(keywordp expr)))
(defmacro byte-optimize--pcase (exp &rest cases)
@@ -402,15 +410,13 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.")
(cond
((not lexvar) form)
(for-effect nil)
- ((cddr lexvar) ; Value available?
- (if (assq form byte-optimize--vars-outside-loop)
- ;; Cannot substitute; mark for retention to avoid the
- ;; variable being eliminated.
- (progn
- (setcar (cdr lexvar) t)
- form)
- ;; variable value to use
- (caddr lexvar)))
+ ((and (cddr lexvar) ; substitution available
+ ;; Perform substitution, except during the loop mutation
+ ;; discovery phase if the variable was bound outside the
+ ;; innermost loop.
+ (not (and byte-optimize--inhibit-outside-loop-constprop
+ (assq form byte-optimize--vars-outside-loop))))
+ (caddr lexvar))
(t form))))
(t form)))
(`(quote . ,v)
@@ -425,19 +431,19 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.")
(`(,(or 'let 'let*) . ,rest)
(cons fn (byte-optimize-let-form fn rest for-effect)))
(`(cond . ,clauses)
- ;; The condition in the first clause is always executed, but
- ;; right now we treat all of them as conditional for simplicity.
- (let ((byte-optimize--vars-outside-condition byte-optimize--lexvars))
- (cons fn
- (mapcar (lambda (clause)
- (if (consp clause)
- (cons
- (byte-optimize-form (car clause) nil)
- (byte-optimize-body (cdr clause) for-effect))
- (byte-compile-warn "malformed cond form: `%s'"
- (prin1-to-string clause))
- clause))
- clauses))))
+ ;; FIXME: The condition in the first clause is always executed, and
+ ;; clause bodies are mutually exclusive -- use this for improved
+ ;; optimisation (see comment about `if' below).
+ (cons fn
+ (mapcar (lambda (clause)
+ (if (consp clause)
+ (cons
+ (byte-optimize-form (car clause) nil)
+ (byte-optimize-body (cdr clause) for-effect))
+ (byte-compile-warn "malformed cond form: `%s'"
+ (prin1-to-string clause))
+ clause))
+ clauses)))
(`(progn . ,exps)
;; As an extra added bonus, this simplifies (progn <x>) --> <x>.
(if (cdr exps)
@@ -463,22 +469,15 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.")
;; FIXME: We are conservative here: any variable changed in the
;; THEN branch will be barred from substitution in the ELSE
;; branch, despite the branches being mutually exclusive.
-
- ;; The test is always executed.
(let* ((test-opt (byte-optimize-form test nil))
(const (macroexp-const-p test-opt))
- ;; The branches are traversed unconditionally when possible.
- (byte-optimize--vars-outside-condition
- (if const
- byte-optimize--vars-outside-condition
- byte-optimize--lexvars))
;; Avoid traversing dead branches.
(then-opt (and test-opt (byte-optimize-form then for-effect)))
(else-opt (and (not (and test-opt const))
(byte-optimize-body else for-effect))))
`(if ,test-opt ,then-opt . ,else-opt)))
- (`(,(or 'and 'or) . ,exps) ; Remember, and/or are control structures.
+ (`(,(or 'and 'or) . ,exps)
;; FIXME: We have to traverse the expressions in left-to-right
;; order (because that is the order of evaluation and variable
;; mutations must be found prior to their use), but doing so we miss
@@ -487,34 +486,36 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.")
;; Then A could be optimised in a for-effect context too.
(let ((tail exps)
(args nil))
- (when tail
- ;; The first argument is always unconditional.
+ (while tail
(push (byte-optimize-form
(car tail) (and for-effect (null (cdr tail))))
args)
- (setq tail (cdr tail))
- ;; Remaining arguments are conditional.
- (let ((byte-optimize--vars-outside-condition byte-optimize--lexvars))
- (while tail
- (push (byte-optimize-form
- (car tail) (and for-effect (null (cdr tail))))
- args)
- (setq tail (cdr tail)))))
+ (setq tail (cdr tail)))
(cons fn (nreverse args))))
(`(while ,exp . ,exps)
- ;; FIXME: We conservatively prevent the substitution of any variable
- ;; bound outside the loop in case it is mutated later in the loop,
- ;; but this misses many opportunities: variables not mutated in the
- ;; loop at all, and variables affecting the initial condition (which
- ;; is always executed unconditionally).
- (let* ((byte-optimize--vars-outside-condition byte-optimize--lexvars)
- (byte-optimize--vars-outside-loop byte-optimize--lexvars)
- (condition (byte-optimize-form exp nil))
- (body (byte-optimize-body exps t)))
+ ;; FIXME: If the loop condition is statically nil after substitution
+ ;; of surrounding variables then we can eliminate the whole loop,
+ ;; even if those variables are mutated inside the loop.
+ ;; We currently don't perform this important optimisation.
+ (let* ((byte-optimize--vars-outside-loop byte-optimize--lexvars)
+ (condition-body
+ (if byte-optimize--inhibit-outside-loop-constprop
+ ;; We are already inside the discovery phase of an outer
+ ;; loop so there is no need for traversing this loop twice.
+ (cons exp exps)
+ ;; Discovery phase: run optimisation without substitution
+ ;; of variables bound outside this loop.
+ (let ((byte-optimize--inhibit-outside-loop-constprop t))
+ (cons (byte-optimize-form exp nil)
+ (byte-optimize-body exps t)))))
+ ;; Optimise again, this time with constprop enabled (unless
+ ;; we are in discovery of an outer loop),
+ ;; as mutated variables have been marked as non-substitutable.
+ (condition (byte-optimize-form (car condition-body) nil))
+ (body (byte-optimize-body (cdr condition-body) t)))
`(while ,condition . ,body)))
-
(`(interactive . ,_)
(byte-compile-warn "misplaced interactive spec: `%s'"
(prin1-to-string form))
@@ -526,19 +527,18 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.")
form)
(`(condition-case ,var ,exp . ,clauses)
- (let ((byte-optimize--vars-outside-condition byte-optimize--lexvars))
- `(condition-case ,var ;Not evaluated.
- ,(byte-optimize-form exp for-effect)
- ,@(mapcar (lambda (clause)
- (let ((byte-optimize--lexvars
- (and lexical-binding
- (if var
- (cons (list var t)
- byte-optimize--lexvars)
- byte-optimize--lexvars))))
- (cons (car clause)
- (byte-optimize-body (cdr clause) for-effect))))
- clauses))))
+ `(condition-case ,var ;Not evaluated.
+ ,(byte-optimize-form exp for-effect)
+ ,@(mapcar (lambda (clause)
+ (let ((byte-optimize--lexvars
+ (and lexical-binding
+ (if var
+ (cons (list var t)
+ byte-optimize--lexvars)
+ byte-optimize--lexvars))))
+ (cons (car clause)
+ (byte-optimize-body (cdr clause) for-effect))))
+ clauses)))
(`(unwind-protect ,exp . ,exps)
;; The unwinding part of an unwind-protect is compiled (and thus
@@ -547,8 +547,7 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.")
;; protected part has the same for-effect status as the
;; unwind-protect itself. (The unwinding part is always for effect,
;; but that isn't handled properly yet.)
- (let* ((byte-optimize--vars-outside-condition byte-optimize--lexvars)
- (bodyform (byte-optimize-form exp for-effect)))
+ (let ((bodyform (byte-optimize-form exp for-effect)))
(pcase exps
(`(:fun-body ,f)
`(unwind-protect ,bodyform
@@ -558,16 +557,8 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.")
. ,(byte-optimize-body exps t))))))
(`(catch ,tag . ,exps)
- (let ((byte-optimize--vars-outside-condition byte-optimize--lexvars))
- `(catch ,(byte-optimize-form tag nil)
- . ,(byte-optimize-body exps for-effect))))
-
- (`(ignore . ,exps)
- ;; Don't treat the args to `ignore' as being
- ;; computed for effect. We want to avoid the warnings
- ;; that might occur if they were treated that way.
- ;; However, don't actually bother calling `ignore'.
- `(progn ,@(mapcar #'byte-optimize-form exps) nil))
+ `(catch ,(byte-optimize-form tag nil)
+ . ,(byte-optimize-body exps for-effect)))
;; Needed as long as we run byte-optimize-form after cconv.
(`(internal-make-closure . ,_)
@@ -602,7 +593,15 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.")
(value (byte-optimize-form expr nil)))
(when lexvar
(setcar (cdr lexvar) t) ; Mark variable to be kept.
- (setcdr (cdr lexvar) nil)) ; Inhibit further substitution.
+ (setcdr (cdr lexvar) nil) ; Inhibit further substitution.
+
+ (when (memq var byte-optimize--aliased-vars)
+ ;; Cancel aliasing of variables aliased to this one.
+ (dolist (v byte-optimize--lexvars)
+ (when (eq (nth 2 v) var)
+ ;; V is bound to VAR but VAR is now mutated:
+ ;; cancel aliasing.
+ (setcdr (cdr v) nil)))))
(push var var-expr-list)
(push value var-expr-list))
@@ -673,39 +672,149 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.")
(not (eq new old))))))))
form)
+(defun byte-optimize--rename-var-body (var new-var body)
+ "Replace VAR with NEW-VAR in BODY."
+ (mapcar (lambda (form) (byte-optimize--rename-var var new-var form)) body))
+
+(defun byte-optimize--rename-var (var new-var form)
+ "Replace VAR with NEW-VAR in FORM."
+ (pcase form
+ ((pred symbolp) (if (eq form var) new-var form))
+ (`(setq . ,args)
+ (let ((new-args nil))
+ (while args
+ (push (byte-optimize--rename-var var new-var (car args)) new-args)
+ (push (byte-optimize--rename-var var new-var (cadr args)) new-args)
+ (setq args (cddr args)))
+ `(setq . ,(nreverse new-args))))
+ ;; In binding constructs like `let', `let*' and `condition-case' we
+ ;; rename everything for simplicity, even new bindings named VAR.
+ (`(,(and head (or 'let 'let*)) ,bindings . ,body)
+ `(,head
+ ,(mapcar (lambda (b) (byte-optimize--rename-var-body var new-var b))
+ bindings)
+ ,@(byte-optimize--rename-var-body var new-var body)))
+ (`(condition-case ,res-var ,protected-form . ,handlers)
+ `(condition-case ,(byte-optimize--rename-var var new-var res-var)
+ ,(byte-optimize--rename-var var new-var protected-form)
+ ,@(mapcar (lambda (h)
+ (cons (car h)
+ (byte-optimize--rename-var-body var new-var (cdr h))))
+ handlers)))
+ (`(internal-make-closure ,vars ,env . ,rest)
+ `(internal-make-closure
+ ,vars ,(byte-optimize--rename-var-body var new-var env) . ,rest))
+ (`(defvar ,name . ,rest)
+ ;; NAME is not renamed here; we only care about lexical variables.
+ `(defvar ,name . ,(byte-optimize--rename-var-body var new-var rest)))
+
+ (`(cond . ,clauses)
+ `(cond ,@(mapcar (lambda (c)
+ (byte-optimize--rename-var-body var new-var c))
+ clauses)))
+
+ (`(function . ,_) form)
+ (`(quote . ,_) form)
+ (`(lambda . ,_) form)
+
+ ;; Function calls and special forms not handled above.
+ (`(,head . ,args)
+ `(,head . ,(byte-optimize--rename-var-body var new-var args)))
+ (_ form)))
+
(defun byte-optimize-let-form (head form for-effect)
;; Recursively enter the optimizer for the bindings and body
;; of a let or let*. This for depth-firstness: forms that
;; are more deeply nested are optimized first.
(if lexical-binding
(let* ((byte-optimize--lexvars byte-optimize--lexvars)
+ (byte-optimize--aliased-vars byte-optimize--aliased-vars)
(new-lexvars nil)
- (let-vars nil))
- (dolist (binding (car form))
- (let* ((name (car binding))
- (expr (byte-optimize-form (cadr binding) nil))
- (value (and (byte-optimize--substitutable-p expr)
- (list expr)))
- (lexical (not (or (special-variable-p name)
- (memq name byte-compile-bound-variables)
- (memq name byte-optimize--dynamic-vars))))
- (lexinfo (and lexical (cons name (cons nil value)))))
- (push (cons name (cons expr (cdr lexinfo))) let-vars)
- (when lexinfo
- (push lexinfo (if (eq head 'let*)
- byte-optimize--lexvars
- new-lexvars)))))
+ (new-aliased-vars nil)
+ (let-vars nil)
+ (body (cdr form))
+ (bindings (car form)))
+ (while bindings
+ (let* ((binding (car bindings))
+ (name (car binding))
+ (expr (byte-optimize-form (cadr binding) nil)))
+ (setq bindings (cdr bindings))
+ (when (and (eq head 'let*)
+ (memq name byte-optimize--aliased-vars))
+ ;; New variable shadows an aliased variable -- α-rename
+ ;; it in this and all subsequent bindings.
+ (let ((new-name (make-symbol (symbol-name name))))
+ (setq bindings
+ (mapcar (lambda (b)
+ (list (byte-optimize--rename-var
+ name new-name (car b))
+ (byte-optimize--rename-var
+ name new-name (cadr b))))
+ bindings))
+ (setq body (byte-optimize--rename-var-body name new-name body))
+ (setq name new-name)))
+ (let* ((aliased nil)
+ (value (and
+ (or (byte-optimize--substitutable-p expr)
+ ;; Aliasing another lexvar.
+ (setq aliased
+ (and (symbolp expr)
+ (assq expr byte-optimize--lexvars))))
+ (list expr)))
+ (lexical (not (or (special-variable-p name)
+ (memq name byte-compile-bound-variables)
+ (memq name byte-optimize--dynamic-vars))))
+ (lexinfo (and lexical (cons name (cons nil value)))))
+ (push (cons name (cons expr (cdr lexinfo))) let-vars)
+ (when lexinfo
+ (push lexinfo (if (eq head 'let*)
+ byte-optimize--lexvars
+ new-lexvars)))
+ (when aliased
+ (push expr (if (eq head 'let*)
+ byte-optimize--aliased-vars
+ new-aliased-vars))))))
+
+ (setq byte-optimize--aliased-vars
+ (append new-aliased-vars byte-optimize--aliased-vars))
+ (when (and (eq head 'let) byte-optimize--aliased-vars)
+ ;; Find new variables that shadow aliased variables.
+ (let ((shadowing-vars nil))
+ (dolist (lexvar new-lexvars)
+ (let ((name (car lexvar)))
+ (when (and (memq name byte-optimize--aliased-vars)
+ (not (memq name shadowing-vars)))
+ (push name shadowing-vars))))
+ ;; α-rename them
+ (dolist (name shadowing-vars)
+ (let ((new-name (make-symbol (symbol-name name))))
+ (setq new-lexvars
+ (mapcar (lambda (lexvar)
+ (if (eq (car lexvar) name)
+ (cons new-name (cdr lexvar))
+ lexvar))
+ new-lexvars))
+ (setq let-vars
+ (mapcar (lambda (v)
+ (if (eq (car v) name)
+ (cons new-name (cdr v))
+ v))
+ let-vars))
+ (setq body (byte-optimize--rename-var-body
+ name new-name body))))))
(setq byte-optimize--lexvars
(append new-lexvars byte-optimize--lexvars))
;; Walk the body expressions, which may mutate some of the records,
;; and generate new bindings that exclude unused variables.
(let* ((byte-optimize--dynamic-vars byte-optimize--dynamic-vars)
- (opt-body (byte-optimize-body (cdr form) for-effect))
+ (opt-body (byte-optimize-body body for-effect))
(bindings nil))
(dolist (var let-vars)
;; VAR is (NAME EXPR [KEEP [VALUE]])
- (when (or (not (nthcdr 3 var)) (nth 2 var))
- ;; Value not present, or variable marked to be kept.
+ (when (or (not (nthcdr 3 var)) (nth 2 var)
+ byte-optimize--inhibit-outside-loop-constprop)
+ ;; Value not present, or variable marked to be kept,
+ ;; or we are in the loop discovery phase: keep the binding.
(push (list (nth 0 var) (nth 1 var)) bindings)))
(cons bindings opt-body)))
@@ -734,8 +843,12 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.")
(while rest
(setq fe (or all-for-effect (cdr rest)))
(setq new (and (car rest) (byte-optimize-form (car rest) fe)))
- (if (or new (not fe))
- (setq result (cons new result)))
+ (when (and (consp new) (eq (car new) 'progn))
+ ;; Flatten `progn' form into the body.
+ (setq result (append (reverse (cdr new)) result))
+ (setq new (pop result)))
+ (when (or new (not fe))
+ (setq result (cons new result)))
(setq rest (cdr rest)))
(nreverse result)))
@@ -967,24 +1080,25 @@ See Info node `(elisp) Integer Basics'."
(_ (byte-optimize-binary-predicate form))))
(defun byte-optimize-member (form)
- ;; Replace `member' or `memql' with `memq' if the first arg is a symbol,
- ;; or the second arg is a list of symbols. Same with fixnums.
- (if (= (length (cdr form)) 2)
- (if (or (byte-optimize--constant-symbol-p (nth 1 form))
- (byte-optimize--fixnump (nth 1 form))
- (let ((arg2 (nth 2 form)))
- (and (macroexp-const-p arg2)
- (let ((listval (eval arg2)))
- (and (listp listval)
- (not (memq nil (mapcar
- (lambda (o)
- (or (symbolp o)
- (byte-optimize--fixnump o)))
- listval))))))))
- (cons 'memq (cdr form))
- form)
- ;; Arity errors reported elsewhere.
- form))
+ (cond
+ ((/= (length (cdr form)) 2) form) ; arity error
+ ((null (nth 2 form)) ; empty list
+ `(progn ,(nth 1 form) nil))
+ ;; Replace `member' or `memql' with `memq' if the first arg is a symbol
+ ;; or fixnum, or the second arg is a list of symbols or fixnums.
+ ((or (byte-optimize--constant-symbol-p (nth 1 form))
+ (byte-optimize--fixnump (nth 1 form))
+ (let ((arg2 (nth 2 form)))
+ (and (macroexp-const-p arg2)
+ (let ((listval (eval arg2)))
+ (and (listp listval)
+ (not (memq nil (mapcar
+ (lambda (o)
+ (or (symbolp o)
+ (byte-optimize--fixnump o)))
+ listval))))))))
+ (cons 'memq (cdr form)))
+ (t form)))
(defun byte-optimize-assoc (form)
;; Replace 2-argument `assoc' with `assq', `rassoc' with `rassq',
@@ -992,22 +1106,35 @@ See Info node `(elisp) Integer Basics'."
(cond
((/= (length form) 3)
form)
+ ((null (nth 2 form)) ; empty list
+ `(progn ,(nth 1 form) nil))
((or (byte-optimize--constant-symbol-p (nth 1 form))
(byte-optimize--fixnump (nth 1 form)))
(cons (if (eq (car form) 'assoc) 'assq 'rassq)
(cdr form)))
(t (byte-optimize-constant-args form))))
+(defun byte-optimize-assq (form)
+ (cond
+ ((/= (length form) 3)
+ form)
+ ((null (nth 2 form)) ; empty list
+ `(progn ,(nth 1 form) nil))
+ (t (byte-optimize-constant-args form))))
+
(defun byte-optimize-memq (form)
- ;; (memq foo '(bar)) => (and (eq foo 'bar) '(bar))
(if (= (length (cdr form)) 2)
(let ((list (nth 2 form)))
- (if (and (eq (car-safe list) 'quote)
- (listp (setq list (cadr list)))
- (= (length list) 1))
- `(and (eq ,(nth 1 form) ',(nth 0 list))
- ',list)
- form))
+ (cond
+ ((null list) ; empty list
+ `(progn ,(nth 1 form) nil))
+ ;; (memq foo '(bar)) => (and (eq foo 'bar) '(bar))
+ ((and (eq (car-safe list) 'quote)
+ (listp (setq list (cadr list)))
+ (= (length list) 1))
+ `(and (eq ,(nth 1 form) ',(nth 0 list))
+ ',list))
+ (t form)))
;; Arity errors reported elsewhere.
form))
@@ -1044,6 +1171,8 @@ See Info node `(elisp) Integer Basics'."
(put 'member 'byte-optimizer #'byte-optimize-member)
(put 'assoc 'byte-optimizer #'byte-optimize-assoc)
(put 'rassoc 'byte-optimizer #'byte-optimize-assoc)
+(put 'assq 'byte-optimizer #'byte-optimize-assq)
+(put 'rassq 'byte-optimizer #'byte-optimize-assq)
(put '+ 'byte-optimizer #'byte-optimize-plus)
(put '* 'byte-optimizer #'byte-optimize-multiply)
@@ -1136,7 +1265,7 @@ See Info node `(elisp) Integer Basics'."
(list 'or (car (car clauses))
(byte-optimize-cond
(cons (car form) (cdr (cdr form)))))
- form))
+ (and clauses form)))
form))
(defun byte-optimize-if (form)
@@ -1242,17 +1371,24 @@ See Info node `(elisp) Integer Basics'."
(and (consp binding) (cadr binding)))
bindings)
,const)
- `(let* ,(butlast bindings) ,(cadar (last bindings)) ,const)))
+ `(let* ,(butlast bindings)
+ ,@(and (consp (car (last bindings)))
+ (cdar (last bindings)))
+ ,const)))
;; Body is last variable.
- (`(,head ,bindings ,(and var (pred symbolp) (pred (not keywordp))
- (pred (not booleanp))
- (guard (eq var (caar (last bindings))))))
+ (`(,head ,(and bindings
+ (let last-var (let ((last (car (last bindings))))
+ (if (consp last) (car last) last))))
+ ,(and last-var ; non-linear pattern
+ (pred symbolp) (pred (not keywordp)) (pred (not booleanp))))
(if (eq head 'let)
`(progn ,@(mapcar (lambda (binding)
(and (consp binding) (cadr binding)))
bindings))
- `(let* ,(butlast bindings) ,(cadar (last bindings)))))
+ `(let* ,(butlast bindings)
+ ,@(and (consp (car (last bindings)))
+ (cdar (last bindings))))))
(_ form)))
@@ -1403,7 +1539,9 @@ See Info node `(elisp) Integer Basics'."
fixnump floatp following-char framep
get-largest-window get-lru-window
hash-table-p
- identity ignore integerp integer-or-marker-p interactive-p
+ ;; `ignore' isn't here because we don't want calls to it elided;
+ ;; see `byte-compile-ignore'.
+ identity integerp integer-or-marker-p interactive-p
invocation-directory invocation-name
keymapp keywordp
list listp
@@ -1642,7 +1780,7 @@ See Info node `(elisp) Integer Basics'."
(setq tags (delq tmp tags))
(setq rest (cdr rest))))
(setq rest (cdr rest))))
- (if tags (error "optimizer error: missed tags %s" tags))
+ (if tags (error "Optimizer error: missed tags %s" tags))
;; Remove addrs, lap = ( [ (op . arg) | (TAG tagno) ]* )
(mapcar (lambda (elt)
(if (numberp elt)
diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el
index aca5dcba62c..2ce2efd2aa7 100644
--- a/lisp/emacs-lisp/byte-run.el
+++ b/lisp/emacs-lisp/byte-run.el
@@ -134,6 +134,7 @@ The return value of this function is not used."
:autoload-end
(eval-and-compile
(defun ,cfname (,@(car data) ,@args)
+ (ignore ,@(delq '&rest (delq '&optional (copy-sequence args))))
,@(cdr data))))))))
(defalias 'byte-run--set-doc-string
@@ -380,7 +381,7 @@ You don't need this. (See bytecomp.el commentary for more details.)
"Define an inline function. The syntax is just like that of `defun'.
\(fn NAME ARGLIST &optional DOCSTRING DECL &rest BODY)"
- (declare (debug defun) (doc-string 3))
+ (declare (debug defun) (doc-string 3) (indent 2))
(or (memq (get name 'byte-optimizer)
'(nil byte-compile-inline-expand))
(error "`%s' is a primitive" name))
@@ -422,18 +423,19 @@ was first made obsolete, for example a date or a release number."
&optional docstring)
"Set OBSOLETE-NAME's function definition to CURRENT-NAME and mark it obsolete.
-\(define-obsolete-function-alias \\='old-fun \\='new-fun \"22.1\" \"old-fun's doc.\")
+\(define-obsolete-function-alias \\='old-fun \\='new-fun \"28.1\" \
+\"old-fun's doc.\")
is equivalent to the following two lines of code:
\(defalias \\='old-fun \\='new-fun \"old-fun's doc.\")
-\(make-obsolete \\='old-fun \\='new-fun \"22.1\")
+\(make-obsolete \\='old-fun \\='new-fun \"28.1\")
WHEN should be a string indicating when the function was first
made obsolete, for example a date or a release number.
See the docstrings of `defalias' and `make-obsolete' for more details."
- (declare (doc-string 4))
+ (declare (doc-string 4) (indent defun))
`(progn
(defalias ,obsolete-name ,current-name ,docstring)
(make-obsolete ,obsolete-name ,current-name ,when)))
@@ -462,7 +464,7 @@ made obsolete, for example a date or a release number.
This macro evaluates all its parameters, and both OBSOLETE-NAME
and CURRENT-NAME should be symbols, so a typical usage would look like:
- (define-obsolete-variable-alias 'foo-thing 'bar-thing \"27.1\")
+ (define-obsolete-variable-alias 'foo-thing 'bar-thing \"28.1\")
This macro uses `defvaralias' and `make-obsolete-variable' (which see).
See the Info node `(elisp)Variable Aliases' for more details.
@@ -482,7 +484,7 @@ For the benefit of Customize, if OBSOLETE-NAME has
any of the following properties, they are copied to
CURRENT-NAME, if it does not already have them:
`saved-value', `saved-variable-comment'."
- (declare (doc-string 4))
+ (declare (doc-string 4) (indent defun))
`(progn
(defvaralias ,obsolete-name ,current-name ,docstring)
;; See Bug#4706.
@@ -529,11 +531,11 @@ is enabled."
(list 'quote (eval (cons 'progn body) lexical-binding)))
(defmacro eval-and-compile (&rest body)
- "Like `progn', but evaluates the body at compile time and at
-load time. In interpreted code, this is entirely equivalent to
-`progn', except that the value of the expression may be (but is
-not necessarily) computed at load time if eager macro expansion
-is enabled."
+ "Like `progn', but evaluates the body at compile time and at load time.
+In interpreted code, this is entirely equivalent to `progn',
+except that the value of the expression may be (but is not
+necessarily) computed at load time if eager macro expansion is
+enabled."
(declare (debug (&rest def-form)) (indent 0))
;; When the byte-compiler expands code, this macro is not used, so we're
;; either about to run `body' (plain interpretation) or we're doing eager
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 7bd642d2b23..a98c9197a06 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -26,7 +26,7 @@
;;; Commentary:
-;; The Emacs Lisp byte compiler. This crunches lisp source into a sort
+;; The Emacs Lisp byte compiler. This crunches Lisp source into a sort
;; of p-code (`lapcode') which takes up less space and can be interpreted
;; faster. [`LAP' == `Lisp Assembly Program'.]
;; The user entry points are byte-compile-file and byte-recompile-directory.
@@ -299,7 +299,7 @@ The information is logged to `byte-compile-log-buffer'."
'(redefine callargs free-vars unresolved
obsolete noruntime interactive-only
make-local mapcar constants suspicious lexical lexical-dynamic
- docstrings)
+ docstrings not-unused)
"The list of warning types used when `byte-compile-warnings' is t.")
(defcustom byte-compile-warnings t
"List of warnings that the byte-compiler should issue (t for all).
@@ -319,11 +319,13 @@ Elements of the list may be:
lexical global/dynamic variables lacking a prefix.
lexical-dynamic
lexically bound variable declared dynamic elsewhere
- make-local calls to make-variable-buffer-local that may be incorrect.
+ make-local calls to `make-variable-buffer-local' that may be incorrect.
mapcar mapcar called for effect.
+ not-unused warning about using variables with symbol names starting with _.
constants let-binding of, or assignment to, constants/nonvariables.
- docstrings docstrings that are too wide (longer than 80 characters,
- or `fill-column', whichever is bigger)
+ docstrings docstrings that are too wide (longer than
+ `byte-compile-docstring-max-column' or
+ `fill-column' characters, whichever is bigger).
suspicious constructs that usually don't do what the coder wanted.
If the list begins with `not', then the remaining elements specify warnings to
@@ -342,6 +344,7 @@ suppress. For example, (not mapcar) will suppress warnings about mapcar."
(or (symbolp v)
(null (delq nil (mapcar (lambda (x) (not (symbolp x))) v))))))
+;;;###autoload
(defun byte-compile-warning-enabled-p (warning &optional symbol)
"Return non-nil if WARNING is enabled, according to `byte-compile-warnings'."
(let ((suppress nil))
@@ -550,7 +553,7 @@ has the form (autoload . FILENAME).")
"Alist of undefined functions to which calls have been compiled.
Each element in the list has the form (FUNCTION POSITION . CALLS)
where CALLS is a list whose elements are integers (indicating the
-number of arguments passed in the function call) or the constant `t'
+number of arguments passed in the function call) or the constant t
if the function is called indirectly.
This variable is only significant whilst compiling an entire buffer.
Used for warnings when a function is not known to be defined or is later
@@ -914,7 +917,7 @@ CONST2 may be evaluated multiple times."
,bytes ,pc))
(defun byte-compile-lapcode (lap)
- "Turns lapcode into bytecode. The lapcode is destroyed."
+ "Turn lapcode LAP into bytecode. The lapcode is destroyed."
;; Lapcode modifications: changes the ID of a tag to be the tag's PC.
(let ((pc 0) ; Program counter
op off ; Operation & offset
@@ -1081,7 +1084,7 @@ If STR is something like \"Buffer foo.el\", return #<buffer foo.el>
(defconst emacs-lisp-compilation-parse-errors-filename-function
#'emacs-lisp-compilation-file-name-or-buffer
"The value for `compilation-parse-errors-filename-function' for when
-we go into emacs-lisp-compilation-mode.")
+we go into `emacs-lisp-compilation-mode'.")
(defcustom emacs-lisp-compilation-search-path '(nil)
"Directories to search for files named in byte-compile error messages.
@@ -1648,20 +1651,36 @@ URLs."
(replace-regexp-in-string
(rx (or
;; Ignore some URLs.
- (seq "http" (? "s") "://" (* anychar))
+ (seq "http" (? "s") "://" (* nonl))
;; Ignore these `substitute-command-keys' substitutions.
(seq "\\" (or "="
(seq "<" (* (not ">")) ">")
(seq "{" (* (not "}")) "}")))
;; Ignore the function signature that's stashed at the end of
;; the doc string (in some circumstances).
- (seq bol "(fn (" (* nonl))))
+ (seq bol "(" (+ (any word "-/:[]&"))
+ ;; One or more arguments.
+ (+ " " (or
+ ;; Arguments.
+ (+ (or (syntax symbol)
+ (any word "-/:[]&=().?^\\#'")))
+ ;; Argument that is a list.
+ (seq "(" (* (not ")")) ")")))
+ ")")))
""
- ;; Heuristic: assume these substitutions are of some length N.
+ ;; Heuristic: We can't reliably do `subsititute-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.
(replace-regexp-in-string
- (rx "\\" (or (seq "[" (* (not "]")) "]")))
+ (rx "\\[" (* (not "]")) "]")
(make-string byte-compile--wide-docstring-substitution-len ?x)
- docstring))))
+ ;; For literal key sequence substitutions (e.g. "\\`C-h'"), just
+ ;; remove the markup as `substitute-command-keys' would.
+ (replace-regexp-in-string
+ (rx "\\`" (group (* (not "'"))) "'")
+ "\\1"
+ docstring)))))
(defcustom byte-compile-docstring-max-column 80
"Recommended maximum width of doc string lines.
@@ -1677,13 +1696,6 @@ value, it will override this variable."
"Warn if documentation string of FORM is too wide.
It is too wide if it has any lines longer than the largest of
`fill-column' and `byte-compile-docstring-max-column'."
- ;; This has some limitations that it would be nice to fix:
- ;; 1. We don't try to handle defuns. It is somewhat tricky to get
- ;; it right since `defun' is a macro. Also, some macros
- ;; themselves produce defuns (e.g. `define-derived-mode').
- ;; 2. We assume that any `subsititute-command-keys' command replacement has a
- ;; given length. We can't reliably do these replacements, since the value
- ;; of the keymaps in general can't be known at compile time.
(when (byte-compile-warning-enabled-p 'docstrings)
(let ((col (max byte-compile-docstring-max-column fill-column))
kind name docs)
@@ -1694,18 +1706,16 @@ It is too wide if it has any lines longer than the largest of
(setq kind (nth 0 form))
(setq name (nth 1 form))
(setq docs (nth 3 form)))
- ;; Here is how one could add lambda's here:
- ;; ('lambda
- ;; (setq kind "") ; can't be "function", unfortunately
- ;; (setq docs (and (stringp (nth 2 form))
- ;; (nth 2 form))))
- )
+ ('lambda
+ (setq kind "") ; can't be "function", unfortunately
+ (setq docs (and (stringp (nth 2 form))
+ (nth 2 form)))))
(when (and (consp name) (eq (car name) 'quote))
(setq name (cadr name)))
- (setq name (if name (format " `%s'" name) ""))
+ (setq name (if name (format " `%s' " name) ""))
(when (and kind docs (stringp docs)
(byte-compile--wide-docstring-p docs col))
- (byte-compile-warn "%s%s docstring wider than %s characters"
+ (byte-compile-warn "%s%sdocstring wider than %s characters"
kind name col))))
form)
@@ -1898,7 +1908,7 @@ also be compiled."
"Non-nil to prevent byte-compiling of Emacs Lisp code.
This is normally set in local file variables at the end of the elisp file:
-\;; Local Variables:\n;; no-byte-compile: t\n;; End: ") ;Backslash for compile-main.
+\;; Local Variables:\n;; no-byte-compile: t\n;; End:") ;Backslash for compile-main.
;;;###autoload(put 'no-byte-compile 'safe-local-variable 'booleanp)
(defun byte-recompile-file (filename &optional force arg load)
@@ -2220,8 +2230,7 @@ With argument ARG, insert value in current buffer after the form."
(byte-compile-depth 0)
(byte-compile-maxdepth 0)
(byte-compile-output nil)
- ;; This allows us to get the positions of symbols read; it's
- ;; new in Emacs 22.1.
+ ;; This allows us to get the positions of symbols read.
(read-with-symbol-positions inbuffer)
(read-symbol-positions-list nil)
;; #### This is bound in b-c-close-variables.
@@ -2256,6 +2265,9 @@ With argument ARG, insert value in current buffer after the form."
(push `(native-comp-speed . ,native-comp-speed) byte-native-qualities)
(defvar native-comp-debug)
(push `(native-comp-debug . ,native-comp-debug) byte-native-qualities)
+ (defvar native-comp-compiler-options)
+ (push `(native-comp-compiler-options . ,native-comp-compiler-options)
+ byte-native-qualities)
(defvar native-comp-driver-options)
(push `(native-comp-driver-options . ,native-comp-driver-options)
byte-native-qualities)
@@ -2665,15 +2677,6 @@ list that represents a doc string reference.
(prog1 (byte-compile-keep-pending form)
(apply 'make-obsolete (mapcar 'eval (cdr form)))))
-;; This handler is not necessary, but it makes the output from dont-compile
-;; and similar macros cleaner.
-(put 'eval 'byte-hunk-handler 'byte-compile-file-form-eval)
-(defun byte-compile-file-form-eval (form)
- (if (and (eq (car-safe (nth 1 form)) 'quote)
- (equal (nth 2 form) lexical-binding))
- (nth 1 (nth 1 form))
- (byte-compile-keep-pending form)))
-
(defun byte-compile-file-form-defmumble (name macro arglist body rest)
"Process a `defalias' for NAME.
If MACRO is non-nil, the definition is known to be a macro.
@@ -2804,8 +2807,8 @@ not to take responsibility for the actual compilation of the code."
t)))))
(defun byte-compile-output-as-comment (exp quoted)
- "Print Lisp object EXP in the output file, inside a comment,
-and return the file (byte) position it will have.
+ "Print Lisp object EXP in the output file, inside a comment.
+Return the file (byte) position it will have.
If QUOTED is non-nil, print with quoting; otherwise, print without quoting."
(with-current-buffer byte-compile--outbuffer
(let ((position (point)))
@@ -2926,6 +2929,8 @@ If FORM is a lambda or a macro, byte-compile it as a function."
(macroexp--const-symbol-p arg t))
(error "Invalid lambda variable %s" arg))
((eq arg '&rest)
+ (unless (cdr list)
+ (error "&rest without variable name"))
(when (cddr list)
(error "Garbage following &rest VAR in lambda-list"))
(when (memq (cadr list) '(&optional &rest))
@@ -3558,7 +3563,7 @@ for symbols generated by the byte compiler itself."
"Warn if symbol VAR refers to a free variable.
VAR must not be lexically bound.
If optional argument ASSIGNMENT is non-nil, this is treated as an
-assignment (i.e. `setq'). "
+assignment (i.e. `setq')."
(unless (or (not (byte-compile-warning-enabled-p 'free-vars var))
(boundp var)
(memq var byte-compile-bound-variables)
@@ -4206,6 +4211,7 @@ discarding."
(byte-defop-compiler-1 funcall)
(byte-defop-compiler-1 let)
(byte-defop-compiler-1 let* byte-compile-let)
+(byte-defop-compiler-1 ignore)
(defun byte-compile-progn (form)
(byte-compile-body-do-effect (cdr form)))
@@ -4221,6 +4227,11 @@ discarding."
(if ,discard 'byte-goto-if-nil 'byte-goto-if-nil-else-pop))
,tag))
+(defun byte-compile-ignore (form)
+ (dolist (arg (cdr form))
+ (byte-compile-form arg t))
+ (byte-compile-form nil))
+
;; Return the list of items in CONDITION-PARAM that match PRED-LIST.
;; Only return items that are not in ONLY-IF-NOT-PRESENT.
(defun byte-compile-find-bound-condition (condition-param
@@ -4325,7 +4336,7 @@ that suppresses all warnings during execution of BODY."
(and (symbolp obj2) (macroexp-const-p obj1) (cons obj2 (eval obj1)))))
(defun byte-compile--common-test (test-1 test-2)
- "Most specific common test of `eq', `eql' and `equal'"
+ "Most specific common test of `eq', `eql' and `equal'."
(cond ((or (eq test-1 'equal) (eq test-2 'equal)) 'equal)
((or (eq test-1 'eql) (eq test-2 'eql)) 'eql)
(t 'eq)))
@@ -4407,7 +4418,7 @@ Return (TAIL VAR TEST CASES), where:
(cases (nth 2 switch))
jump-table test-objects body tag default-tag)
;; TODO: Once :linear-search is implemented for `make-hash-table'
- ;; set it to `t' for cond forms with a small number of cases.
+ ;; set it to t for cond forms with a small number of cases.
(let ((nvalues (apply #'+ (mapcar (lambda (case) (length (car case)))
cases))))
(setq jump-table (make-hash-table
@@ -4436,7 +4447,7 @@ Return (TAIL VAR TEST CASES), where:
(byte-compile-out 'byte-switch)
;; When the opcode argument is `byte-goto', `byte-compile-goto' sets
- ;; `byte-compile-depth' to `nil'. However, we need `byte-compile-depth'
+ ;; `byte-compile-depth' to nil. However, we need `byte-compile-depth'
;; to be non-nil for generating tags for all cases. Since
;; `byte-compile-depth' will increase by at most 1 after compiling
;; all of the clause (which is further enforced by cl-assert below)
@@ -5028,6 +5039,8 @@ binding slots have been popped."
nil))
(_ (byte-compile-keep-pending form))))
+
+
;;; tags
diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el
index 3abbf716875..7cec91bfa82 100644
--- a/lisp/emacs-lisp/cconv.el
+++ b/lisp/emacs-lisp/cconv.el
@@ -32,7 +32,7 @@
;; Here is a brief explanation how this code works.
;; Firstly, we analyze the tree by calling cconv-analyze-form.
;; This function finds all mutated variables, all functions that are suitable
-;; for lambda lifting and all variables captured by closure. It passes the tree
+;; for lambda lifting and all variables captured by closure. It passes the tree
;; once, returning a list of three lists.
;;
;; Then we calculate the intersection of the first and third lists returned by
@@ -304,6 +304,25 @@ of converted forms."
`(,@(nreverse special-forms) ,@(macroexp-unprogn body))))
funcbody)))
+(defun cconv--lifted-arg (var env)
+ "The argument to use for VAR in λ-lifted calls according to ENV.
+This is used when VAR is being shadowed; we may still need its value for
+such calls."
+ (let ((mapping (cdr (assq var env))))
+ (pcase-exhaustive mapping
+ (`(internal-get-closed-var . ,_)
+ ;; The variable is captured.
+ mapping)
+ (`(car-safe ,exp)
+ ;; The variable is mutably captured; skip
+ ;; the indirection step because the variable is
+ ;; passed "by reference" to the λ-lifted function.
+ exp)
+ (_
+ ;; The variable is not captured; use the (shadowed) variable value.
+ ;; (If the mapping is `(car-safe SYMBOL)', SYMBOL is always VAR.
+ var))))
+
(defun cconv-convert (form env extend)
;; This function actually rewrites the tree.
"Return FORM with all its lambdas changed so they are closed.
@@ -428,10 +447,11 @@ places where they originally did not directly appear."
;; One of the lambda-lifted vars is shadowed, so add
;; a reference to the outside binding and arrange to use
;; that reference.
- (let ((closedsym (make-symbol (format "closed-%s" var))))
+ (let ((var-def (cconv--lifted-arg var env))
+ (closedsym (make-symbol (format "closed-%s" var))))
(setq new-env (cconv--remap-llv new-env var closedsym))
(setq new-extend (cons closedsym (remq var new-extend)))
- (push `(,closedsym ,var) binders-new)))
+ (push `(,closedsym ,var-def) binders-new)))
;; We push the element after redefined free variables are
;; processed. This is important to avoid the bug when free
@@ -449,14 +469,13 @@ places where they originally did not directly appear."
;; before we know that the var will be in `new-extend' (bug#24171).
(dolist (binder binders-new)
(when (memq (car-safe binder) new-extend)
- ;; One of the lambda-lifted vars is shadowed, so add
- ;; a reference to the outside binding and arrange to use
- ;; that reference.
+ ;; One of the lambda-lifted vars is shadowed.
(let* ((var (car-safe binder))
+ (var-def (cconv--lifted-arg var env))
(closedsym (make-symbol (format "closed-%s" var))))
(setq new-env (cconv--remap-llv new-env var closedsym))
(setq new-extend (cons closedsym (remq var new-extend)))
- (push `(,closedsym ,var) binders-new)))))
+ (push `(,closedsym ,var-def) binders-new)))))
`(,letsym ,(nreverse binders-new)
. ,(mapcar (lambda (form)
@@ -608,10 +627,9 @@ FORM is the parent form that binds this var."
(`((,(and var (guard (eq ?_ (aref (symbol-name var) 0)))) . ,_)
,_ ,_ ,_ ,_)
;; FIXME: Convert this warning to use `macroexp--warn-wrap'
- ;; so as to give better position information and obey
- ;; `byte-compile-warnings'.
- (byte-compile-warn
- "%s `%S' not left unused" varkind var))
+ ;; so as to give better position information.
+ (when (byte-compile-warning-enabled-p 'not-unused var)
+ (byte-compile-warn "%s `%S' not left unused" varkind var)))
((and (let (or 'let* 'let) (car form))
`((,var) ;; (or `(,var nil) : Too many false positives: bug#47080
t nil ,_ ,_))
@@ -794,6 +812,8 @@ This function does not return anything but instead fills the
;; (`(declare . ,_) nil) ;The args don't contain code.
(`(,_ . ,body-forms) ; First element is a function or whatever.
+ (unless (listp body-forms)
+ (signal 'wrong-type-argument (list 'proper-list-p form)))
(dolist (form body-forms) (cconv-analyze-form form env)))
((pred symbolp)
diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el
index bec4ad92503..83a9d3ea6ae 100644
--- a/lisp/emacs-lisp/check-declare.el
+++ b/lisp/emacs-lisp/check-declare.el
@@ -119,7 +119,7 @@ don't know how to recognize (e.g. some macros)."
(autoload 'byte-compile-arglist-signature "bytecomp")
(defgroup check-declare nil
- "Check declare-function statements."
+ "Check `declare-function' statements."
:group 'tools)
(defcustom check-declare-ext-errors nil
@@ -230,8 +230,8 @@ fset\\|\\(?:cl-\\)?defmethod\\)\\>" type)
errlist))
(defun check-declare-sort (alist)
- "Sort a list with elements FILE (FNFILE ...).
-Returned list has elements FNFILE (FILE ...)."
+ "Sort list ALIST with elements FILE (FNFILE ...).
+Return list with elements FNFILE (FILE ...)."
(let (file fnfile rest sort a)
(dolist (e alist)
(setq file (car e))
diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el
index 00cc7777e1a..ab2f34c3104 100644
--- a/lisp/emacs-lisp/checkdoc.el
+++ b/lisp/emacs-lisp/checkdoc.el
@@ -29,11 +29,12 @@
;; to forget. The main checkdoc engine will perform the stylistic
;; checks needed to make sure these styles are remembered.
;;
-;; There are two ways to use checkdoc:
-;; 1) Periodically use `checkdoc' or `checkdoc-current-buffer'.
+;; There are three ways to use checkdoc:
+;; 1) Use `flymake-mode'.
+;; 2) Periodically use `checkdoc' or `checkdoc-current-buffer'.
;; `checkdoc' is a more interactive version of
;; `checkdoc-current-buffer'
-;; 2) Use `checkdoc-minor-mode' to automatically check your
+;; 3) Use `checkdoc-minor-mode' to automatically check your
;; documentation whenever you evaluate Lisp code with C-M-x
;; or [menu-bar emacs-lisp eval-buffer]. Additional key-bindings
;; are also provided under C-c ? KEY
@@ -117,8 +118,7 @@
;; The text that follows the `error' and `y-or-n-p' commands is
;; also checked. The documentation for `error' clearly states some
;; simple style rules to follow which checkdoc will auto-fix for you.
-;; `y-or-n-p' also states that it should end in a space. I added that
-;; it should end in "? " since that is almost always used.
+;; `y-or-n-p' and `yes-or-no-p' should also end in "?".
;;
;; Adding your own checks:
;;
@@ -164,6 +164,8 @@
(require 'cl-lib)
(require 'help-mode) ;; for help-xref-info-regexp
(require 'thingatpt) ;; for handy thing-at-point-looking-at
+(require 'lisp-mode) ;; for lisp-mode-symbol-regexp
+(require 'dired) ;; for dired-get-filename and dired-map-over-marks
(require 'lisp-mnt)
(defvar compilation-error-regexp-alist)
@@ -249,11 +251,18 @@ with these words enabled."
"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)
-(defcustom checkdoc-max-keyref-before-warn 10
- "The number of \\ [command-to-keystroke] tokens allowed in a doc string.
+(defcustom checkdoc-max-keyref-before-warn nil
+ "If non-nil, number of \\\\=[command-to-keystroke] tokens allowed in a doc string.
Any more than this and a warning is generated suggesting that the construct
-\\ {keymap} be used instead."
- :type 'integer)
+\\\\={mapvar} be used instead. If the value is nil, never warn.
+
+It used to not be practical to use `\\\\=[...]' very many times,
+because display of the documentation string would become slow.
+This is not an issue on modern machines, unless you have
+thousands of substitutions."
+ :type '(choice (const nil)
+ integer)
+ :version "28.1")
(defcustom checkdoc-arguments-in-order-flag nil
"Non-nil means warn if arguments appear out of order.
@@ -304,13 +313,56 @@ variable `checkdoc-common-verbs-wrong-voice' if you wish to add your own."
Do not set this by hand, use a function like `checkdoc-current-buffer'
with a universal argument.")
-(defcustom checkdoc-symbol-words nil
+(defcustom checkdoc-symbol-words
+ '("beginning-of-buffer" "beginning-of-line" "byte-code"
+ "byte-compile" "command-line" "end-of-buffer" "end-of-line"
+ "major-mode" "point-max" "point-min" "syntax-table"
+ "top-level" "user-error" "version-control" "window-system")
"A list of symbol names (strings) which also happen to make good words.
These words are ignored when unquoted symbols are searched for.
This should be set in an Emacs Lisp file's local variables."
- :type '(repeat (symbol :tag "Word")))
+ :type '(repeat (string :tag "Word"))
+ :version "28.1")
;;;###autoload(put 'checkdoc-symbol-words 'safe-local-variable #'checkdoc-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.
+This backslash is no longer needed on Emacs 27.1 or later.
+
+See Info node `(elisp) Documentation Tips' for background."
+ :type 'boolean
+ :version "28.1")
+
+;; This is how you can use checkdoc to make mass fixes on the Emacs
+;; source tree:
+;;
+;; (setq checkdoc--argument-missing-flag nil) ; optional
+;; (setq checkdoc--disambiguate-symbol-flag nil) ; optional
+;; (setq checkdoc--interactive-docstring-flag nil) ; optional
+;; (setq checkdoc-verb-check-experimental-flag nil)
+;; Then use `M-x find-dired' ("-name '*.el'") and `M-x checkdoc-dired'
+
+(defvar checkdoc--argument-missing-flag t
+ "Non-nil means warn if arguments are missing from docstring.
+This variable is intended for use on Emacs itself, where the
+large number of libraries means it is impractical to fix all
+of these warnings en masse. In almost any other case, setting
+this to anything but t is likely to be counter-productive.")
+
+(defvar checkdoc--disambiguate-symbol-flag t
+ "Non-nil means ask to disambiguate Lisp symbol.
+This variable is intended for use on Emacs itself, where the
+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.")
+
+(defvar checkdoc--interactive-docstring-flag t
+ "Non-nil means warn if interactive function has no docstring.
+This variable is intended for use on Emacs itself, where the
+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."
@@ -320,7 +372,7 @@ This should be set in an Emacs Lisp file's local variables."
(not (memq nil (mapcar #'stringp obj)))))
(defvar checkdoc-proper-noun-list
- '("ispell" "xemacs" "emacs" "lisp")
+ '("emacs" "lisp" "dired")
"List of words (not capitalized) which should be capitalized.")
(defvar checkdoc-proper-noun-regexp
@@ -351,9 +403,13 @@ This should be set in an Emacs Lisp file's local variables."
("contains" . "contain")
("converts" . "convert")
("creates" . "create")
+ ("defines" . "define")
("destroys" . "destroy")
+ ("determines" . "determine")
("disables" . "disable")
+ ("echoes" . "echo")
("executes" . "execute")
+ ("extends" . "extend")
("evals" . "evaluate")
("evaluates" . "evaluate")
("finds" . "find")
@@ -378,7 +434,7 @@ This should be set in an Emacs Lisp file's local variables."
("looks" . "look")
("makes" . "make")
("marks" . "mark")
- ("matches" . "match")
+ ;;("matches" . "match") ; Leads to almost only false positives.
("moves" . "move")
("notifies" . "notify")
("offers" . "offer")
@@ -386,6 +442,7 @@ This should be set in an Emacs Lisp file's local variables."
("performs" . "perform")
("prepares" . "prepare")
("prepends" . "prepend")
+ ("prompts" . "prompt")
("reads" . "read")
("raises" . "raise")
("removes" . "remove")
@@ -404,6 +461,7 @@ This should be set in an Emacs Lisp file's local variables."
("signifies" . "signify")
("sorts" . "sort")
("starts" . "start")
+ ("steps" . "step")
("stores" . "store")
("switches" . "switch")
("tells" . "tell")
@@ -433,6 +491,12 @@ be re-created.")
st)
"Syntax table used by checkdoc in document strings.")
+(defconst checkdoc--help-buffer "*Checkdoc Help*"
+ "Name of buffer used for Checkdoc Help.")
+
+(defvar checkdoc-commentary-header-string "\n;;; Commentary:\n;; \n\n"
+ "String inserted as commentary marker in `checkdoc-file-comments-engine'.")
+
;;; User level commands
;;
;;;###autoload
@@ -440,7 +504,7 @@ be re-created.")
"Interactively check the entire buffer for style errors.
The current status of the check will be displayed in a buffer which
the users will view as each check is completed."
- (interactive)
+ (interactive nil emacs-lisp-mode)
(let ((status (list "Checking..." "-" "-" "-"))
(checkdoc-spellcheck-documentation-flag
(car (memq checkdoc-spellcheck-documentation-flag
@@ -507,7 +571,7 @@ buffer. Allows navigation forward and backwards through document
errors. Does not check for comment or space warnings.
Optional argument SHOWSTATUS indicates that we should update the
checkdoc status window instead of the usual behavior."
- (interactive "P")
+ (interactive "P" emacs-lisp-mode)
(let ((checkdoc-spellcheck-documentation-flag
(car (memq checkdoc-spellcheck-documentation-flag
'(interactive t)))))
@@ -528,7 +592,7 @@ buffer. Allows navigation forward and backwards through document
errors. Does not check for comment or space warnings.
Optional argument SHOWSTATUS indicates that we should update the
checkdoc status window instead of the usual behavior."
- (interactive "P")
+ (interactive "P" emacs-lisp-mode)
(let ((checkdoc-spellcheck-documentation-flag
(car (memq checkdoc-spellcheck-documentation-flag
'(interactive t)))))
@@ -680,31 +744,30 @@ style."
begin (point)))
;; Goofy stuff
(t
- (if (get-buffer-window "*Checkdoc Help*")
+ (if (get-buffer-window checkdoc--help-buffer)
(progn
- (delete-window (get-buffer-window "*Checkdoc Help*"))
- (kill-buffer "*Checkdoc Help*"))
- (with-output-to-temp-buffer "*Checkdoc Help*"
+ (delete-window (get-buffer-window checkdoc--help-buffer))
+ (kill-buffer checkdoc--help-buffer))
+ (with-output-to-temp-buffer checkdoc--help-buffer
(with-current-buffer standard-output
(insert
"Checkdoc Keyboard Summary:\n"
(if (checkdoc-error-unfixable (car (car err-list)))
""
(concat
- "f, y - auto Fix this warning without asking (if\
- available.)\n"
- " Very complex operations will still query.\n")
- )
+ "f, y - auto Fix this warning without asking"
+ " (if available.)\n"
+ " Very complex operations will still query.\n"))
"e - Enter recursive Edit. Press C-M-c to exit.\n"
"SPC, n - skip to the Next error.\n"
"DEL, p - skip to the Previous error.\n"
"q - Quit checkdoc.\n"
"C-h - Toggle this help buffer.")))
(shrink-window-if-larger-than-buffer
- (get-buffer-window "*Checkdoc Help*"))))))
+ (get-buffer-window checkdoc--help-buffer))))))
(if cdo (delete-overlay cdo)))))
(goto-char begin)
- (if (get-buffer "*Checkdoc Help*") (kill-buffer "*Checkdoc Help*"))
+ (if (get-buffer checkdoc--help-buffer) (kill-buffer checkdoc--help-buffer))
(message "Checkdoc: Done.")
returnme))
@@ -798,19 +861,21 @@ assumes that the cursor is already positioned to perform the fix."
(defun checkdoc-recursive-edit (msg)
"Enter recursive edit to permit a user to fix some error checkdoc has found.
MSG is the error that was found, which is displayed in a help buffer."
- (with-output-to-temp-buffer "*Checkdoc Help*"
- (mapc #'princ
- (list "Error message:\n " msg
- "\n\nEdit to fix this problem, and press C-M-c to continue.")))
+ (with-output-to-temp-buffer checkdoc--help-buffer
+ (with-current-buffer standard-output
+ (insert "Error message:\n " msg "\n\n"
+ (substitute-command-keys
+ "Edit to fix this problem, and press \\[exit-recursive-edit] to continue."))))
(shrink-window-if-larger-than-buffer
- (get-buffer-window "*Checkdoc Help*"))
- (message "When you're done editing press C-M-c to continue.")
+ (get-buffer-window checkdoc--help-buffer))
+ (message (substitute-command-keys
+ "When you're done editing press \\[exit-recursive-edit] to continue."))
(unwind-protect
(recursive-edit)
- (if (get-buffer-window "*Checkdoc Help*")
+ (if (get-buffer-window checkdoc--help-buffer)
(progn
- (delete-window (get-buffer-window "*Checkdoc Help*"))
- (kill-buffer "*Checkdoc Help*")))))
+ (delete-window (get-buffer-window checkdoc--help-buffer))
+ (kill-buffer checkdoc--help-buffer)))))
;;;###autoload
(defun checkdoc-eval-current-buffer ()
@@ -828,7 +893,7 @@ spacing are all verified."
With a prefix argument (in Lisp, the argument TAKE-NOTES),
store all errors found in a warnings buffer,
otherwise stop after the first error."
- (interactive "P")
+ (interactive "P" emacs-lisp-mode)
(if (called-interactively-p 'interactive)
(message "Checking buffer for style..."))
;; Assign a flag to spellcheck flag
@@ -867,7 +932,7 @@ Only documentation strings are checked.
Use `checkdoc-continue' to continue checking if an error cannot be fixed.
Prefix argument TAKE-NOTES means to collect all the warning messages into
a separate buffer."
- (interactive "P")
+ (interactive "P" emacs-lisp-mode)
(let ((p (point)))
(goto-char (point-min))
(if (and take-notes (called-interactively-p 'interactive))
@@ -882,7 +947,7 @@ a separate buffer."
"Find the next doc string in the current buffer which has a style error.
Prefix argument TAKE-NOTES means to continue through the whole
buffer and save warnings in a separate buffer."
- (interactive "P")
+ (interactive "P" emacs-lisp-mode)
(let ((wrong nil) (msg nil)
;; Assign a flag to spellcheck flag
(checkdoc-spellcheck-documentation-flag
@@ -951,7 +1016,7 @@ don't move point."
Prefix argument TAKE-NOTES non-nil means to save warnings in a
separate buffer. Otherwise print a message. This returns the error
if there is one."
- (interactive "P")
+ (interactive "P" emacs-lisp-mode)
(if take-notes (checkdoc-start-section "checkdoc-comments"))
(if (not buffer-file-name)
(error "Can only check comments for a file buffer"))
@@ -973,7 +1038,7 @@ Prefix argument TAKE-NOTES non-nil means to save warnings in a
separate buffer. Otherwise print a message. This returns the error
if there is one.
Optional argument INTERACT permits more interactive fixing."
- (interactive "P")
+ (interactive "P" emacs-lisp-mode)
(if take-notes (checkdoc-start-section "checkdoc-rogue-spaces"))
(let* ((checkdoc-autofix-flag (if take-notes 'never checkdoc-autofix-flag))
(e (checkdoc-rogue-space-check-engine nil nil interact))
@@ -990,7 +1055,7 @@ Optional argument INTERACT permits more interactive fixing."
(defun checkdoc-message-text (&optional take-notes)
"Scan the buffer for occurrences of the error function, and verify text.
Optional argument TAKE-NOTES causes all errors to be logged."
- (interactive "P")
+ (interactive "P" emacs-lisp-mode)
(if take-notes (checkdoc-start-section "checkdoc-message-text"))
(let* ((p (point)) e
(checkdoc-autofix-flag (if take-notes 'never checkdoc-autofix-flag))
@@ -1042,6 +1107,40 @@ space at the end of each line."
(if (called-interactively-p 'interactive)
(message "Checkdoc: done."))))))
+(defconst checkdoc--dired-skip-lines-re
+ (rx (or (seq bol
+ (or ";; Generated from Unicode data files by unidat"
+ ";; This file is automatically generated from"
+ ";; Generated by the command "))
+ ".el --- automatically extracted autoloads -*- lexical-binding: t -*-"
+ ";;; lisp/trampver.el. Generated from trampver.el.in by configure."))
+ "Regexp that when it matches tells `checkdoc-dired' to skip a file.")
+
+;;;###autoload
+(defun checkdoc-dired (files)
+ "In Dired, run `checkdoc' on marked files.
+Skip anything that doesn't have the Emacs Lisp library file
+extension (\".el\").
+When called from Lisp, FILES is a list of filenames."
+ (interactive
+ (list
+ (delq nil
+ (mapcar
+ ;; skip anything that doesn't look like an Emacs Lisp library
+ (lambda (f) (if (equal (file-name-extension f) "el") f nil))
+ (nreverse (dired-map-over-marks (dired-get-filename) nil)))))
+ dired-mode)
+ (if (null files)
+ (error "No files to run checkdoc on")
+ (save-window-excursion
+ (dolist (fil files)
+ (find-file fil)
+ (unless (and
+ (goto-char (point-min))
+ (re-search-forward checkdoc--dired-skip-lines-re nil t))
+ (checkdoc)))))
+ (message "checkdoc-dired: Successfully checked %d files" (length files)))
+
;;; Ispell interface for forcing a spell check
;;
@@ -1204,8 +1303,8 @@ TEXT, START, END and UNFIXABLE conform to
;; Add in a menubar with easy-menu
-(easy-menu-define
- nil checkdoc-minor-mode-map "Checkdoc Minor Mode Menu"
+(easy-menu-define nil checkdoc-minor-mode-map
+ "Checkdoc Minor Mode Menu."
'("CheckDoc"
["Interactive Buffer Style Check" checkdoc t]
["Interactive Buffer Style and Spelling Check" checkdoc-ispell t]
@@ -1247,8 +1346,6 @@ checking of documentation strings.
;;; Subst utils
;;
-(define-obsolete-function-alias 'checkdoc-run-hooks
- #'run-hook-with-args-until-success "28.1")
(defsubst checkdoc-create-common-verbs-regexp ()
"Rebuild the contents of `checkdoc-common-verbs-regexp'."
@@ -1325,7 +1422,7 @@ buffer, otherwise stop after the first error."
(if (or (eq checkdoc-autofix-flag
'automatic-then-never)
(checkdoc-y-or-n-p
- "Convert comment to documentation? "))
+ "Convert comment to documentation?"))
(save-excursion
;; Our point is at the beginning of the comment!
;; Insert a quote, then remove the comment chars.
@@ -1355,12 +1452,13 @@ buffer, otherwise stop after the first error."
(checkdoc-create-error
"You should convert this comment to documentation"
(point) (line-end-position)))
- (checkdoc-create-error
- (if (nth 2 fp)
- "All interactive functions should have documentation"
- "All variables and subroutines might as well have a \
+ (when checkdoc--interactive-docstring-flag
+ (checkdoc-create-error
+ (if (nth 2 fp)
+ "All interactive functions should have documentation"
+ "All variables and subroutines might as well have a \
documentation string")
- (point) (+ (point) 1) t)))))
+ (point) (+ (point) 1) t))))))
(if (and (not err) (= (following-char) ?\"))
(with-syntax-table checkdoc-syntax-table
(checkdoc-this-string-valid-engine fp take-notes))
@@ -1394,7 +1492,7 @@ buffer, otherwise stop after the first error."
(looking-at "\\([ \t]+\\)[^ \t\n]"))
(if (checkdoc-autofix-ask-replace (match-beginning 1)
(match-end 1)
- "Remove this whitespace? "
+ "Remove this whitespace?"
"")
nil
(checkdoc-create-error
@@ -1402,16 +1500,17 @@ buffer, otherwise stop after the first error."
(match-beginning 1)
(match-end 1)))))
;; * Check for '(' in column 0.
- (save-excursion
- (when (re-search-forward "^(" e t)
- (if (checkdoc-autofix-ask-replace (match-beginning 0)
- (match-end 0)
- (format-message "Escape this `('? ")
- "\\(")
- nil
- (checkdoc-create-error
- "Open parenthesis in column 0 should be escaped"
- (match-beginning 0) (match-end 0)))))
+ (when checkdoc-column-zero-backslash-before-paren
+ (save-excursion
+ (when (re-search-forward "^(" e t)
+ (if (checkdoc-autofix-ask-replace (match-beginning 0)
+ (match-end 0)
+ (format-message "Escape this `('?")
+ "\\(")
+ nil
+ (checkdoc-create-error
+ "Open parenthesis in column 0 should be escaped"
+ (match-beginning 0) (match-end 0))))))
;; * Do not start or end a documentation string with whitespace.
(let (start end)
(if (or (if (looking-at "\"\\([ \t\n]+\\)")
@@ -1424,7 +1523,7 @@ buffer, otherwise stop after the first error."
(setq start (point)
end (1- e)))))
(if (checkdoc-autofix-ask-replace
- start end "Remove this whitespace? " "")
+ start end "Remove this whitespace?" "")
nil
(checkdoc-create-error
"Documentation strings should not start or end with whitespace"
@@ -1449,7 +1548,7 @@ buffer, otherwise stop after the first error."
nil
(forward-char 1)
(if (checkdoc-autofix-ask-replace
- (point) (1+ (point)) "Add period to sentence? "
+ (point) (1+ (point)) "Add period to sentence?"
".\"" t)
nil
(checkdoc-create-error
@@ -1470,7 +1569,7 @@ buffer, otherwise stop after the first error."
;; Here we have found a complete sentence, but no break.
(if (checkdoc-autofix-ask-replace
(1+ (match-beginning 0)) (match-end 0)
- "First line not a complete sentence. Add RET here? "
+ "First line not a complete sentence. Add RET here?"
"\n" t)
(let (l1 l2)
(end-of-line 2)
@@ -1497,7 +1596,7 @@ may require more formatting")
(< (current-column) numc))
(when (checkdoc-autofix-ask-replace
p (1+ p)
- "1st line not a complete sentence. Join these lines? "
+ "First line not a complete sentence. Join these lines?"
" " t)
(setq msg nil)))))
(if msg
@@ -1510,7 +1609,7 @@ may require more formatting")
(if (looking-at "[a-z]")
(if (checkdoc-autofix-ask-replace
(match-beginning 0) (match-end 0)
- "Capitalize your sentence? " (upcase (match-string 0))
+ "Capitalize your sentence?" (upcase (match-string 0))
t)
nil
(checkdoc-create-error
@@ -1521,7 +1620,9 @@ may require more formatting")
;; Instead, use the `\\[...]' construct to stand for them.
(save-excursion
(let ((f nil) (m nil) (start (point))
- (re "[^`‘A-Za-z0-9_]\\([CMA]-[a-zA-Z]\\|\\(\\([CMA]-\\)?\
+ ;; Ignore the "A-" modifier: it is uncommon in practice,
+ ;; and leads to false positives in regexp ranges.
+ (re "[^`‘A-Za-z0-9_]\\([CMs]-[a-zA-Z]\\|\\(\\([CMs]-\\)?\
mouse-[0-3]\\)\\)\\>"))
;; Find the first key sequence not in a sample
(while (and (not f) (setq m (re-search-forward re e t)))
@@ -1530,24 +1631,22 @@ mouse-[0-3]\\)\\)\\>"))
(checkdoc-create-error
(concat
"Keycode " (match-string 1)
- " embedded in doc string. Use \\\\<keymap> & \\\\[function] "
+ " embedded in doc string. Use \\\\<mapvar> & \\\\[command] "
"instead")
(match-beginning 1) (match-end 1) t))))
- ;; It is not practical to use `\\[...]' very many times, because
- ;; display of the documentation string will become slow. So use this
- ;; to describe the most important commands in your major mode, and
- ;; then use `\\{...}' to display the rest of the mode's keymap.
- (save-excursion
- (if (and (re-search-forward "\\\\\\\\\\[\\w+" e t
- (1+ checkdoc-max-keyref-before-warn))
- (not (re-search-forward "\\\\\\\\{\\w+}" e t)))
- (checkdoc-create-error
- "Too many occurrences of \\[function]. Use \\{keymap} instead"
- s (marker-position e))))
+ ;; Optionally warn about too many command substitutions.
+ (when checkdoc-max-keyref-before-warn
+ (save-excursion
+ (if (and (re-search-forward "\\\\\\\\\\[\\w+" e t
+ (1+ checkdoc-max-keyref-before-warn))
+ (not (re-search-forward "\\\\\\\\{\\w+}" e t)))
+ (checkdoc-create-error
+ "Too many occurrences of \\[command]. Use \\{mapvar} instead"
+ s (marker-position e)))))
;; Ambiguous quoted symbol. When a symbol is both bound and fbound,
;; and is referred to in documentation, it should be prefixed with
;; something to disambiguate it. This check must be before the
- ;; 80 column check because it will probably break that.
+ ;; 80 column check because it might break that.
(save-excursion
(let ((case-fold-search t)
(ret nil) mb me)
@@ -1559,13 +1658,17 @@ mouse-[0-3]\\)\\)\\>"))
(setq mb (match-beginning 1)
me (match-end 1))
(if (and sym (boundp sym) (fboundp sym)
- (save-excursion
+ checkdoc--disambiguate-symbol-flag
+ ;; Mode names do not need disambiguating. (Bug#4110)
+ (not (string-match (rx "-mode" string-end)
+ (symbol-name sym)))
+ (save-excursion
(goto-char mb)
(forward-word-strictly -1)
(not (looking-at
"variable\\|option\\|function\\|command\\|symbol"))))
(if (checkdoc-autofix-ask-replace
- mb me "Prefix this ambiguous symbol? " ms1 t)
+ mb me "Prefix this ambiguous symbol?" ms1 t)
;; We didn't actually replace anything. Here we find
;; out what special word form they wish to use as
;; a prefix.
@@ -1591,20 +1694,28 @@ function,command,variable,option or symbol." ms1))))))
;; first line can be wider if necessary to fit the
;; information that ought to be there.
(save-excursion
- (let ((start (point))
- (eol nil))
+ (let* ((start (point))
+ (eol nil)
+ ;; Respect this file local variable.
+ (max-column (max 80 byte-compile-docstring-max-column))
+ ;; Allow the first line to be three characters longer, to
+ ;; fit the leading ` "' while still having a docstring
+ ;; shorter than e.g. 80 characters.
+ (first t)
+ (get-max-column (lambda () (+ max-column (if first 3 0)))))
(while (and (< (point) e)
(or (progn (end-of-line) (setq eol (point))
- (< (current-column) 80))
+ (< (current-column) (funcall get-max-column)))
(progn (beginning-of-line)
(re-search-forward "\\\\\\\\[[<{]"
eol t))
- (checkdoc-in-sample-code-p start e)))
+ (checkdoc-in-sample-code-p start e)))
+ (setq first nil)
(forward-line 1))
(end-of-line)
- (if (and (< (point) e) (> (current-column) 80))
+ (if (and (< (point) e) (> (current-column) (funcall get-max-column)))
(checkdoc-create-error
- "Some lines are over 80 columns wide"
+ (format "Some lines are over %d columns wide" max-column)
s (save-excursion (goto-char s) (line-end-position))))))
;; Here we deviate to tests based on a variable or function.
;; We must do this before checking for symbols in quotes because there
@@ -1624,7 +1735,7 @@ function,command,variable,option or symbol." ms1))))))
(when (looking-at "\"\\*?\\(True\\)\\b")
(if (checkdoc-autofix-ask-replace
(match-beginning 1) (match-end 1)
- "Say \"Non-nil\" instead of \"True\"? "
+ "Say \"Non-nil\" instead of \"True\"?"
"Non-nil")
nil
(checkdoc-create-error
@@ -1649,7 +1760,7 @@ function,command,variable,option or symbol." ms1))))))
;; (concat (car fp) "-flag"))))
;; (if (checkdoc-y-or-n-p
;; (format
- ;; "Rename to %s and Query-Replace all occurrences? "
+ ;; "Rename to %s and Query-Replace all occurrences?"
;; newname))
;; (progn
;; (beginning-of-defun)
@@ -1712,7 +1823,7 @@ function,command,variable,option or symbol." ms1))))))
(if (checkdoc-autofix-ask-replace
(match-beginning 1) (match-end 1)
(format-message
- "If this is the argument `%s', it should appear as %s. Fix? "
+ "If this is the argument `%s', it should appear as %s. Fix?"
(car args) (upcase (car args)))
(upcase (car args)) t)
(setq found (match-beginning 1))))))
@@ -1722,7 +1833,7 @@ function,command,variable,option or symbol." ms1))))))
;; to the end of the documentation string.
(if (checkdoc-y-or-n-p
(format
- "Add %s documentation to end of doc string? "
+ "Add %s documentation to end of doc string?"
(upcase (car args))))
;; Now do some magic and invent a doc string.
(save-excursion
@@ -1736,11 +1847,12 @@ function,command,variable,option or symbol." ms1))))))
(looking-at "[.?!]")))
(insert "."))
nil)
- (checkdoc-create-error
- (format-message
- "Argument `%s' should appear (as %s) in the doc string"
- (car args) (upcase (car args)))
- s (marker-position e)))
+ (when checkdoc--argument-missing-flag
+ (checkdoc-create-error
+ (format-message
+ "Argument `%s' should appear (as %s) in the doc string"
+ (car args) (upcase (car args)))
+ s (marker-position e))))
(if (or (and order (eq order 'yes))
(and (not order) checkdoc-arguments-in-order-flag))
(if (< found last-pos)
@@ -1784,7 +1896,7 @@ function,command,variable,option or symbol." ms1))))))
(if (checkdoc-autofix-ask-replace
(match-beginning 1) (match-end 1)
(format "Use the imperative for \"%s\". \
-Replace with \"%s\"? " original replace)
+Replace with \"%s\"?" original replace)
replace t)
(setq rs nil)))
(if rs
@@ -1798,7 +1910,7 @@ Replace with \"%s\"? " original replace)
(when (looking-at "\"Return \\(true\\)\\b")
(if (checkdoc-autofix-ask-replace
(match-beginning 1) (match-end 1)
- "Say \"non-nil\" instead of \"true\"? "
+ "Say \"non-nil\" instead of \"true\"?"
"non-nil")
nil
(checkdoc-create-error
@@ -1832,7 +1944,7 @@ Replace with \"%s\"? " original replace)
(or (boundp found) (fboundp found)))
(progn
(setq msg (format-message
- "Add quotes around Lisp symbol `%s'? " ms))
+ "Add quotes around Lisp symbol `%s'?" ms))
(if (checkdoc-autofix-ask-replace
(match-beginning 1) (+ (match-beginning 1)
(length ms))
@@ -1851,7 +1963,7 @@ Replace with \"%s\"? " original replace)
(if (re-search-forward "\\([`‘]\\(t\\|nil\\)['’]\\)" e t)
(if (checkdoc-autofix-ask-replace
(match-beginning 1) (match-end 1)
- (format "%s should not appear in quotes. Remove? "
+ (format "%s should not appear in quotes. Remove?"
(match-string 2))
(match-string 2) t)
nil
@@ -1867,9 +1979,7 @@ Replace with \"%s\"? " original replace)
;; and reliance on the Ispell program.
(checkdoc-ispell-docstring-engine e take-notes)
;; User supplied checks
- (save-excursion (run-hook-with-args-until-success 'checkdoc-style-functions fp e))
- ;; Done!
- )))
+ (save-excursion (run-hook-with-args-until-success 'checkdoc-style-functions fp e)))))
(defun checkdoc-defun-info nil
"Return a list of details about the current sexp.
@@ -1998,6 +2108,39 @@ The text checked is between START and LIMIT."
(setq c (1+ c)))
(and (< 0 c) (= (% c 2) 0))))))
+(defun checkdoc-in-abbreviation-p (begin)
+ "Return non-nil if point is at an abbreviation.
+Examples of recognized abbreviations: \"e.g.\", \"i.e.\", \"cf.\"."
+ (save-excursion
+ (goto-char begin)
+ (condition-case nil
+ (let (single-letter)
+ (forward-word -1)
+ ;; Skip over all dots backwards, as `forward-word' will only
+ ;; go one dot at a time in a string like "e.g.".
+ (while (save-excursion (forward-char -1)
+ (looking-at (rx ".")))
+ (forward-word -1))
+ (when (= (point) (1- begin))
+ (setq single-letter t))
+ ;; Piece of an abbreviation.
+ (looking-at
+ (if single-letter
+ ;; Handle a single letter, as in "a.", as this might be
+ ;; a part of a list.
+ (rx letter ".")
+ (rx (or
+ ;; The abbreviations (a trailing dot is added below).
+ (seq (any "cC") "f") ; cf.
+ (seq (any "eE") ".g") ; e.g.
+ (seq (any "iI") "." (any "eE")) ; i.e.
+ "a.k.a" "etc" "vs" "N.B"
+ ;; Some non-standard or less common ones that we
+ ;; might as well accept.
+ "Inc" "Univ" "misc" "resp")
+ "."))))
+ (error t))))
+
(defun checkdoc-proper-noun-region-engine (begin end)
"Check all text between BEGIN and END for lower case proper nouns.
These are Emacs centric proper nouns which should be capitalized for
@@ -2027,7 +2170,7 @@ If the offending word is in a piece of quoted text, then it is skipped."
(not (thing-at-point-looking-at
help-xref-url-regexp)))
(if (checkdoc-autofix-ask-replace
- b e (format "Text %s should be capitalized. Fix? "
+ b e (format "Text %s should be capitalized. Fix?"
text)
(capitalize text) t)
nil
@@ -2060,19 +2203,10 @@ If the offending word is in a piece of quoted text, then it is skipped."
(e (match-end 1)))
(unless (or (checkdoc-in-sample-code-p begin end)
(checkdoc-in-example-string-p begin end)
- (save-excursion
- (goto-char b)
- (condition-case nil
- (progn
- (forward-sexp -1)
- ;; piece of an abbreviation
- ;; FIXME etc
- (looking-at
- "\\([a-zA-Z]\\|[iI]\\.?e\\|[eE]\\.?g\\|[cC]f\\)\\."))
- (error t))))
+ (checkdoc-in-abbreviation-p b))
(if (checkdoc-autofix-ask-replace
b e
- "There should be two spaces after a period. Fix? "
+ "There should be two spaces after a period. Fix?"
". ")
nil
(if errtxt
@@ -2189,7 +2323,7 @@ Optional argument INTERACT may permit the user to fix problems on the fly."
News agents may remove it"
s (match-beginning 0) e (match-end 0) f t)
;; If interactive is passed down, give them a chance to fix things.
- (if (and interact (y-or-n-p (concat msg ". Fix? ")))
+ (if (and interact (y-or-n-p (concat msg ". Fix?")))
(progn
(checkdoc-recursive-edit msg)
(setq msg nil)
@@ -2205,7 +2339,7 @@ News agents may remove it"
;; This is not a complex activity
(if (checkdoc-autofix-ask-replace
(match-beginning 1) (match-end 1)
- "White space at end of line. Remove? " "")
+ "White space at end of line. Remove?" "")
nil
(setq msg "White space found at end of line"
s (match-beginning 1) e (match-end 1))))))
@@ -2242,7 +2376,7 @@ Code:, and others referenced in the style guide."
(if (not (lm-summary))
;; This certifies as very complex so always ask unless
;; it's set to never
- (if (checkdoc-y-or-n-p "There is no first line summary! Add one? ")
+ (if (checkdoc-y-or-n-p "There is no first line summary! Add one?")
(progn
(goto-char (point-min))
(insert ";;; " fn fe " --- " (read-string "Summary: ") "\n"))
@@ -2255,8 +2389,13 @@ Code:, and others referenced in the style guide."
err
(or
;; * Commentary Section
- (if (not (lm-commentary-mark))
- (progn
+ (if (and (not (lm-commentary-mark))
+ ;; No need for a commentary section in test files.
+ (not (string-match
+ (rx (or (seq (or "-test.el" "-tests.el") string-end)
+ "/test/" "/tests/"))
+ (buffer-file-name))))
+ (progn
(goto-char (point-min))
(cond
((re-search-forward
@@ -2273,8 +2412,8 @@ Code:, and others referenced in the style guide."
"You should have a summary line (\";;; .* --- .*\")"
nil nil t)))
(if (checkdoc-y-or-n-p
- "You should have a \";;; Commentary:\", add one? ")
- (insert "\n;;; Commentary:\n;; \n\n")
+ "You should have a \";;; Commentary:\", add one?")
+ (insert checkdoc-commentary-header-string)
(checkdoc-create-error
"You should have a section marked \";;; Commentary:\""
nil nil t)))
@@ -2301,7 +2440,7 @@ Code:, and others referenced in the style guide."
(re-search-forward "^(" nil t))
(beginning-of-line)))
(if (checkdoc-y-or-n-p
- "You should have a \";;; History:\", add one? ")
+ "You should have a \";;; History:\", add one?")
(insert "\n;;; History:\n;; \n\n")
(checkdoc-create-error
"You should have a section marked \";;; History:\" or use a ChangeLog"
@@ -2327,7 +2466,7 @@ Code:, and others referenced in the style guide."
cont (looking-at "require\\s-+")))
(if (and (not cont)
(checkdoc-y-or-n-p
- "There is no ;;; Code: marker. Insert one? "))
+ "There is no ;;; Code: marker. Insert one?"))
(progn (goto-char pos)
(insert ";;; Code:\n\n")
nil)
@@ -2344,12 +2483,11 @@ Code:, and others referenced in the style guide."
(save-excursion
(goto-char (point-max))
(if (not (re-search-backward
- (concat "^;;;[ \t]+" (regexp-quote fn) "\\(" (regexp-quote fe)
- "\\)?[ \t]+ends here[ \t]*$"
- "\\|^;;;[ \t]+ End of file[ \t]+"
- (regexp-quote fn) "\\(" (regexp-quote fe) "\\)?")
+ ;; This should match the requirement in
+ ;; `package-buffer-info'.
+ (concat "^;;; " (regexp-quote (concat fn fe)) " ends here")
nil t))
- (if (checkdoc-y-or-n-p "No identifiable footer! Add one? ")
+ (if (checkdoc-y-or-n-p "No identifiable footer! Add one?")
(progn
(goto-char (point-max))
(insert "\n(provide '" fn ")\n\n;;; " fn fe " ends here\n"))
@@ -2413,10 +2551,18 @@ Return the message classification.
Argument END is the maximum bounds to search in."
(let ((return nil))
(while (and (not return)
- (re-search-forward
- "(\\s-*\\(\\(\\w\\|\\s_\\)*error\\|\
-\\(\\w\\|\\s_\\)*y-or-n-p\\(-with-timeout\\)?\
-\\|checkdoc-autofix-ask-replace\\)[ \t\n]+" end t))
+ (re-search-forward
+ (rx "("
+ (* (syntax whitespace))
+ (group
+ (or (seq (* (group (or wordchar (syntax symbol))))
+ "error")
+ (seq (* (group (or wordchar (syntax symbol))))
+ (or "y-or-n-p" "yes-or-no-p")
+ (? (group "-with-timeout")))
+ "checkdoc-autofix-ask-replace"))
+ (+ (any "\n\t ")))
+ end t))
(let* ((fn (match-string 1))
(type (cond ((string-match "error" fn)
'error)
@@ -2425,7 +2571,7 @@ Argument END is the maximum bounds to search in."
(progn (forward-sexp 2)
(skip-chars-forward " \t\n")))
(if (and (eq type 'y-or-n-p)
- (looking-at "(format[ \t\n]+"))
+ (looking-at (rx "(format" (? "-message") (+ (any " \t\n")))))
(goto-char (match-end 0)))
(skip-chars-forward " \t\n")
(if (not (looking-at "\""))
@@ -2433,6 +2579,55 @@ Argument END is the maximum bounds to search in."
(setq return type))))
return))
+(defun checkdoc--error-bad-format-p ()
+ "Return non-nil if the start of error message at point has the wrong format.
+The correct format is \"Foo\" or \"some-symbol: Foo\". See also
+`error' and Info node `(elisp) Documentation Tips'."
+ (save-excursion
+ ;; Skip the first quote character in string.
+ (forward-char 1)
+ ;; A capital letter is always okay.
+ (unless (let ((case-fold-search nil))
+ (looking-at (rx (or upper-case "%s"))))
+ ;; A defined Lisp symbol is always okay.
+ (unless (and (looking-at (rx (group (regexp lisp-mode-symbol-regexp))))
+ (or (fboundp (intern (match-string 1)))
+ (boundp (intern (match-string 1)))))
+ ;; Other Lisp symbols are sometimes okay.
+ (rx-let ((c (? "\\\n"))) ; `c' is for a continued line
+ (let ((case-fold-search nil)
+ (some-symbol (rx (regexp lisp-mode-symbol-regexp)
+ c ":" c (+ (any " \t\n"))))
+ (lowercase-str (rx c (group (any "a-z") (+ wordchar)))))
+ (if (looking-at some-symbol)
+ (looking-at (concat some-symbol lowercase-str))
+ (looking-at lowercase-str))))))))
+
+(defun checkdoc--fix-y-or-n-p ()
+ "Fix `y-or-n-p' prompt to end with \"?\" or \"? \".
+The space is technically redundant, but also more compatible with
+Emacs versions before Emacs 24.1. In the future, we might treat
+a space as a style error."
+ (when (and (save-excursion (forward-sexp 1)
+ (forward-char -3)
+ (not (looking-at "\\? ")))
+ (save-excursion (forward-sexp 1)
+ (forward-char -2)
+ (not (looking-at "\\?"))))
+ (if (and
+ (save-excursion (forward-sexp 1)
+ (forward-char -1)
+ (looking-at "\""))
+ (checkdoc-autofix-ask-replace
+ (match-beginning 0) (match-end 0)
+ (format-message
+ "`y-or-n-p' argument should end with \"? \". Fix?")
+ "?\"" t))
+ nil
+ (checkdoc-create-error
+ "`y-or-n-p' argument should end with \"?\""
+ (match-beginning 0) (match-end 0)))))
+
(defun checkdoc-message-text-engine (&optional type)
"Return or fix errors found in strings passed to a message display function.
According to the documentation for the function `error', the error list
@@ -2455,16 +2650,14 @@ Argument TYPE specifies the type of question, such as `error' or `y-or-n-p'."
;; In Emacs, the convention is that error messages start with a capital
;; letter but *do not* end with a period. Please follow this convention
;; for the sake of consistency.
- (if (and (save-excursion (forward-char 1)
- (looking-at "[a-z]\\w+"))
+ (if (and (checkdoc--error-bad-format-p)
(not (checkdoc-autofix-ask-replace
- (match-beginning 0) (match-end 0)
- "Capitalize your message text? "
- (capitalize (match-string 0))
+ (match-beginning 1) (match-end 1)
+ "Capitalize your message text?"
+ (capitalize (match-string 1))
t)))
- (checkdoc-create-error
- "Messages should start with a capital letter"
- (match-beginning 0) (match-end 0))
+ (checkdoc-create-error "Messages should start with a capital letter"
+ (match-beginning 1) (match-end 1))
nil)
;; In general, sentences should have two spaces after the period.
(checkdoc-sentencespace-region-engine (point)
@@ -2481,64 +2674,21 @@ Argument TYPE specifies the type of question, such as `error' or `y-or-n-p'."
(looking-at "\\."))
(not (checkdoc-autofix-ask-replace (match-beginning 0)
(match-end 0)
- "Remove period from error? "
+ "Remove period from error?"
""
t)))
(checkdoc-create-error
"Error messages should *not* end with a period"
(match-beginning 0) (match-end 0))
nil)
- ;; `y-or-n-p' documentation explicitly says:
- ;; It should end in a space; `y-or-n-p' adds `(y or n) ' to it.
- ;; I added the ? requirement. Without it, it is unclear that we
- ;; ask a question and it appears to be an undocumented style.
- (if (eq type 'y-or-n-p)
- (if (not (save-excursion (forward-sexp 1)
- (forward-char -3)
- (not (looking-at "\\? "))))
- nil
- (if (save-excursion (forward-sexp 1)
- (forward-char -2)
- (looking-at "\\?"))
- ;; If we see a ?, then replace with "? ".
- (if (checkdoc-autofix-ask-replace
- (match-beginning 0) (match-end 0)
- (format-message
- "`y-or-n-p' argument should end with \"? \". Fix? ")
- "? " t)
- nil
- (checkdoc-create-error
- "`y-or-n-p' argument should end with \"? \""
- (match-beginning 0) (match-end 0)))
- (if (save-excursion (forward-sexp 1)
- (forward-char -2)
- (looking-at " "))
- (if (checkdoc-autofix-ask-replace
- (match-beginning 0) (match-end 0)
- (format-message
- "`y-or-n-p' argument should end with \"? \". Fix? ")
- "? " t)
- nil
- (checkdoc-create-error
- "`y-or-n-p' argument should end with \"? \""
- (match-beginning 0) (match-end 0)))
- (if (and ;; if this isn't true, we have a problem.
- (save-excursion (forward-sexp 1)
- (forward-char -1)
- (looking-at "\""))
- (checkdoc-autofix-ask-replace
- (match-beginning 0) (match-end 0)
- (format-message
- "`y-or-n-p' argument should end with \"? \". Fix? ")
- "? \"" t))
- nil
- (checkdoc-create-error
- "`y-or-n-p' argument should end with \"? \""
- (match-beginning 0) (match-end 0)))))))
+ ;; From `(elisp) Programming Tips': "A question asked in the
+ ;; minibuffer with `yes-or-no-p' or `y-or-n-p' should start with
+ ;; a capital letter and end with '?'."
+ (when (eq type 'y-or-n-p)
+ (checkdoc--fix-y-or-n-p))
;; Now, let's just run the spell checker on this guy.
(checkdoc-ispell-docstring-engine (save-excursion (forward-sexp 1)
- (point)))
- )))
+ (point))))))
;;; Auto-fix helper functions
;;
@@ -2708,6 +2858,8 @@ function called to create the messages."
;; Obsolete
+(define-obsolete-function-alias 'checkdoc-run-hooks
+ #'run-hook-with-args-until-success "28.1")
(defvar checkdoc-version "0.6.2"
"Release version of checkdoc you are currently running.")
(make-obsolete-variable 'checkdoc-version 'emacs-version "28.1")
diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el
index 3840d13ecff..499d26b737b 100644
--- a/lisp/emacs-lisp/cl-extra.el
+++ b/lisp/emacs-lisp/cl-extra.el
@@ -336,7 +336,7 @@ non-nil value.
;;;###autoload
(defun cl-isqrt (x)
- "Return the integer square root of the (integer) argument."
+ "Return the integer square root of the (integer) argument X."
(if (and (integerp x) (> x 0))
(let ((g (ash 2 (/ (logb x) 2)))
g2)
@@ -455,7 +455,7 @@ as an integer unless JUNK-ALLOWED is non-nil."
;;;###autoload
(defun cl-random (lim &optional state)
- "Return a random nonnegative number less than LIM, an integer or float.
+ "Return a pseudo-random nonnegative number less than LIM, an integer or float.
Optional second arg STATE is a random-state object."
(or state (setq state cl--random-state))
;; Inspired by "ran3" from Numerical Recipes. Additive congruential method.
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 4a69df15bc8..9de47e4987d 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -86,6 +86,14 @@
;;; Code:
+;; We provide a mechanism to define new specializers.
+;; Related work can be found in:
+;; - http://www.p-cos.net/documents/filtered-dispatch.pdf
+;; - Generalizers: New metaobjects for generalized dispatch
+;; http://research.gold.ac.uk/9924/1/els-specializers.pdf
+;; 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!
@@ -100,6 +108,7 @@
(eval-when-compile (require 'cl-lib))
(eval-when-compile (require 'cl-macs)) ;For cl--find-class.
(eval-when-compile (require 'pcase))
+(eval-when-compile (require 'subr-x))
(cl-defstruct (cl--generic-generalizer
(:constructor nil)
@@ -589,19 +598,10 @@ The set of acceptable TYPEs (also called \"specializers\") is defined
;; e.g. for tracing/debug-on-entry.
(defalias sym gfun)))))
-(defmacro cl--generic-with-memoization (place &rest code)
- (declare (indent 1) (debug t))
- (gv-letplace (getter setter) place
- `(or ,getter
- ,(macroexp-let2 nil val (macroexp-progn code)
- `(progn
- ,(funcall setter val)
- ,val)))))
-
(defvar cl--generic-dispatchers (make-hash-table :test #'equal))
(defun cl--generic-get-dispatcher (dispatch)
- (cl--generic-with-memoization
+ (with-memoization
(gethash dispatch cl--generic-dispatchers)
;; (message "cl--generic-get-dispatcher (%S)" dispatch)
(let* ((dispatch-arg (car dispatch))
@@ -644,10 +644,13 @@ The set of acceptable TYPEs (also called \"specializers\") is defined
;; overkill: better just use a `cl-typep' test.
(byte-compile
`(lambda (generic dispatches-left methods)
+ ;; FIXME: We should find a way to expand `with-memoize' once
+ ;; and forall so we don't need `subr-x' when we get here.
+ (eval-when-compile (require 'subr-x))
(let ((method-cache (make-hash-table :test #'eql)))
(lambda (,@fixedargs &rest args)
(let ,bindings
- (apply (cl--generic-with-memoization
+ (apply (with-memoization
(gethash ,tag-exp method-cache)
(cl--generic-cache-miss
generic ',dispatch-arg dispatches-left methods
@@ -684,14 +687,14 @@ This is particularly useful when many different tags select the same set
of methods, since this table then allows us to share a single combined-method
for all those different tags in the method-cache.")
-(define-error 'cl--generic-cyclic-definition "Cyclic definition: %S")
+(define-error 'cl--generic-cyclic-definition "Cyclic definition")
(defun cl--generic-build-combined-method (generic methods)
(if (null methods)
;; Special case needed to fix a circularity during bootstrap.
(cl--generic-standard-method-combination generic methods)
(let ((f
- (cl--generic-with-memoization
+ (with-memoization
;; FIXME: Since the fields of `generic' are modified, this
;; hash-table won't work right, because the hashes will change!
;; It's not terribly serious, but reduces the effectiveness of
@@ -960,7 +963,7 @@ Can only be used from within the lexical body of a primary or around method."
;;; Add support for describe-function
(defun cl--generic-search-method (met-name)
- "For `find-function-regexp-alist'. Searches for a cl-defmethod.
+ "For `find-function-regexp-alist'. Search for a `cl-defmethod'.
MET-NAME is as returned by `cl--generic-load-hist-format'."
(let ((base-re (concat "(\\(?:cl-\\)?defmethod[ \t]+"
(regexp-quote (format "%s" (car met-name)))
@@ -1026,7 +1029,10 @@ MET-NAME is as returned by `cl--generic-load-hist-format'."
(when generic
(require 'help-mode) ;Needed for `help-function-def' button!
(save-excursion
- (insert "\n\nThis is a generic function.\n\n")
+ ;; Ensure that we have two blank lines (but not more).
+ (unless (looking-back "\n\n" (- (point) 2))
+ (insert "\n"))
+ (insert "This is a generic function.\n\n")
(insert (propertize "Implementations:\n\n" 'face 'bold))
;; Loop over fanciful generics
(dolist (method (cl--generic-method-table generic))
@@ -1140,7 +1146,7 @@ These match if the argument is a cons cell whose car is `eql' to VAL."
;; since we can't use the `head' specializer to implement itself.
(if (not (eq (car-safe specializer) 'head))
(cl-call-next-method)
- (cl--generic-with-memoization
+ (with-memoization
(gethash (cadr specializer) cl--generic-head-used)
specializer)
(list cl--generic-head-generalizer)))
diff --git a/lisp/emacs-lisp/cl-indent.el b/lisp/emacs-lisp/cl-indent.el
index c88e15d5a8b..9d8aae28441 100644
--- a/lisp/emacs-lisp/cl-indent.el
+++ b/lisp/emacs-lisp/cl-indent.el
@@ -162,9 +162,9 @@ is set to `defun'.")
(error t)))
(defun lisp-indent-find-method (symbol &optional no-compat)
- "Find the lisp indentation function for SYMBOL.
+ "Find the Lisp indentation function for SYMBOL.
If NO-COMPAT is non-nil, do not retrieve indenters intended for
-the standard lisp indent package."
+the standard Lisp indent package."
(or (and (derived-mode-p 'emacs-lisp-mode)
(get symbol 'common-lisp-indent-function-for-elisp))
(get symbol 'common-lisp-indent-function)
diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el
index 317a4c62309..b01a32ca60c 100644
--- a/lisp/emacs-lisp/cl-lib.el
+++ b/lisp/emacs-lisp/cl-lib.el
@@ -560,4 +560,9 @@ of record objects."
(t
(advice-remove 'type-of #'cl--old-struct-type-of))))
+(defun cl-constantly (value)
+ "Return a function that takes any number of arguments, but returns VALUE."
+ (lambda (&rest _)
+ value))
+
;;; cl-lib.el ends here
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 4ef1948b0fe..f78fdcf0085 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -1762,7 +1762,7 @@ Once the END-TEST becomes true, the RESULT forms are evaluated (with
the VARs still bound to their values) to produce the result
returned by `cl-do'.
-Note that the entire loop is enclosed in an implicit `nil' block, so
+Note that the entire loop is enclosed in an implicit nil block, so
that you can use `cl-return' to exit at any time.
Also note that END-TEST is checked before evaluating BODY. If END-TEST
@@ -1791,7 +1791,7 @@ Once the END-TEST becomes true, the RESULT forms are evaluated (with
the VARs still bound to their values) to produce the result
returned by `cl-do*'.
-Note that the entire loop is enclosed in an implicit `nil' block, so
+Note that the entire loop is enclosed in an implicit nil block, so
that you can use `cl-return' to exit at any time.
Also note that END-TEST is checked before evaluating BODY. If END-TEST
@@ -2071,7 +2071,7 @@ Like `cl-flet' but the definitions can refer to previous ones.
;; even handle mutually recursive functions.
(letrec
((done nil) ;; Non-nil if some TCO happened.
- ;; This var always holds the value `nil' until (just before) we
+ ;; This var always holds the value nil until (just before) we
;; exit the loop.
(retvar (make-symbol "retval"))
(ofargs (mapcar (lambda (s) (if (memq s cl--lambda-list-keywords) s
@@ -2868,21 +2868,29 @@ in SLOTs. It defines a `make-NAME' constructor, a `copy-NAME'
copier, a `NAME-p' predicate, and slot accessors named `NAME-SLOT'.
You can use the accessors to set the corresponding slots, via `setf'.
-NAME may instead take the form (NAME OPTIONS...), where each
-OPTION is either a single keyword or (KEYWORD VALUE) where
-KEYWORD can be one of `:conc-name', `:constructor', `:copier',
-`:predicate', `:type', `:named', `:initial-offset',
-`:print-function', `:noinline', or `:include'. See Info
-node `(cl)Structures' for the description of the options.
+NAME is usually a symbol, but may instead take the form (NAME
+OPTIONS...), where each OPTION is either a single keyword
+or (KEYWORD VALUE) where KEYWORD can be one of `:conc-name',
+`:constructor', `:copier', `:predicate', `:type', `:named',
+`:initial-offset', `:print-function', `:noinline', or `:include'.
+See Info node `(cl)Structures' for the description of the
+options.
+
+The first element in SLOTS can be a doc string.
+
+The rest of the elements in SLOTS is a list of SLOT elements,
+each of which should either be a symbol, or take the form (SNAME
+SDEFAULT SOPTIONS...), where SDEFAULT is the default value of
+that slot and SOPTIONS are keyword-value pairs for that slot.
-Each SLOT may instead take the form (SNAME SDEFAULT SOPTIONS...), where
-SDEFAULT is the default value of that slot and SOPTIONS are keyword-value
-pairs for that slot.
Supported keywords for slots are:
- `:read-only': If this has a non-nil value, that slot cannot be set via `setf'.
- `:documentation': this is a docstring describing the slot.
- `:type': the type of the field; currently only used for documentation.
+To see the documentation for a defined struct type, use
+\\[describe-symbol] or \\[cl-describe-type].
+
\(fn NAME &optional DOCSTRING &rest SLOTS)"
(declare (doc-string 2) (indent 1)
(debug
@@ -3042,7 +3050,7 @@ Supported keywords for slots are:
`(,predicate cl-x))))
(when pred-form
(push `(,defsym ,predicate (cl-x)
- (declare (side-effect-free error-free))
+ (declare (side-effect-free error-free) (pure t))
,(if (eq (car pred-form) 'and)
(append pred-form '(t))
`(and ,pred-form t)))
@@ -3075,12 +3083,21 @@ Supported keywords for slots are:
`(nth ,pos cl-x))))))
(push slot slots)
(push default-value defaults)
- ;; The arg "cl-x" is referenced by name in eg pred-form
+ ;; The arg "cl-x" is referenced by name in e.g. pred-form
;; and pred-check, so changing it is not straightforward.
(push `(,defsym ,accessor (cl-x)
- ,(format "Access slot \"%s\" of `%s' struct CL-X.%s"
- slot name
- (if doc (concat "\n" doc) ""))
+ ,(concat
+ ;; NB. This will produce incorrect results
+ ;; in some cases, as our coding conventions
+ ;; says that the first line must be a full
+ ;; sentence. However, if we don't word wrap
+ ;; we will have byte-compiler warnings about
+ ;; overly long docstrings. So we can't have
+ ;; a perfect result here, and choose to avoid
+ ;; the byte-compiler warnings.
+ (internal--format-docstring-line
+ "Access slot \"%s\" of `%s' struct CL-X." slot name)
+ (if doc (concat "\n" doc) ""))
(declare (side-effect-free t))
,access-body)
forms)
@@ -3272,7 +3289,7 @@ the form NAME which is a shorthand for (NAME NAME)."
(defun cl-struct-sequence-type (struct-type)
"Return the sequence used to build STRUCT-TYPE.
STRUCT-TYPE is a symbol naming a struct type. Return `record',
-`vector`, or `list' if STRUCT-TYPE is a struct type, nil otherwise."
+`vector', or `list' if STRUCT-TYPE is a struct type, nil otherwise."
(declare (side-effect-free t) (pure t))
(cl--struct-class-type (cl--struct-get-class struct-type)))
@@ -3283,6 +3300,7 @@ STRUCT-TYPE is a symbol naming a struct type. Return `record',
(push (cdr x) res))
(nreverse res)))
+;;;###autoload
(defun cl-struct-slot-info (struct-type)
"Return a list of slot names of struct STRUCT-TYPE.
Each entry is a list (SLOT-NAME . OPTS), where SLOT-NAME is a
@@ -3347,6 +3365,7 @@ Of course, we really can't know that for sure, so it's just a heuristic."
(integer . integerp)
(keyword . keywordp)
(list . listp)
+ (natnum . natnump)
(number . numberp)
(null . null)
(real . numberp)
diff --git a/lisp/emacs-lisp/comp-cstr.el b/lisp/emacs-lisp/comp-cstr.el
index 3c5578217aa..3e816195209 100644
--- a/lisp/emacs-lisp/comp-cstr.el
+++ b/lisp/emacs-lisp/comp-cstr.el
@@ -70,7 +70,7 @@
(irange &aux
(range (list irange))
(typeset ())))
- (:copier comp-cstr-shallow-copy))
+ (:copier nil))
"Internal representation of a type/value constraint."
(typeset '(t) :type list
:documentation "List of possible types the mvar can assume.
@@ -133,8 +133,16 @@ Integer values are handled in the `range' slot.")
:range (copy-tree (range cstr))
:neg (neg cstr))))
+(defsubst comp-cstr-shallow-copy (dst src)
+ "Copy the content of SRC into DST."
+ (with-comp-cstr-accessors
+ (setf (range dst) (range src)
+ (valset dst) (valset src)
+ (typeset dst) (typeset src)
+ (neg dst) (neg src))))
+
(defsubst comp-cstr-empty-p (cstr)
- "Return t if CSTR is equivalent to the `nil' type specifier or nil otherwise."
+ "Return t if CSTR is equivalent to the nil type specifier or nil otherwise."
(with-comp-cstr-accessors
(and (null (typeset cstr))
(null (valset cstr))
@@ -152,7 +160,7 @@ Integer values are handled in the `range' slot.")
(defun comp-cstrs-homogeneous (cstrs)
"Check if constraints CSTRS are all homogeneously negated or non-negated.
Return `pos' if they are all positive, `neg' if they are all
-negated or nil othewise."
+negated or nil otherwise."
(cl-loop
for cstr in cstrs
unless (comp-cstr-neg cstr)
@@ -438,10 +446,7 @@ Return them as multiple value."
ext-range)
ext-range)
(neg dst) nil)
- (setf (typeset dst) (typeset old-dst)
- (valset dst) (valset old-dst)
- (range dst) (range old-dst)
- (neg dst) (neg old-dst)))))
+ (comp-cstr-shallow-copy dst old-dst))))
(defmacro comp-cstr-set-range-for-arithm (dst src1 src2 &rest range-body)
;; Prevent some code duplication for `comp-cstr-add-2'
@@ -581,10 +586,8 @@ DST is returned."
(when (range pos)
'(integer)))))
(typeset neg)))
- (setf (typeset dst) (typeset pos)
- (valset dst) (valset pos)
- (range dst) (range pos)
- (neg dst) nil)
+ (comp-cstr-shallow-copy dst pos)
+ (setf (neg dst) nil)
(cl-return-from comp-cstr-union-1-no-mem dst))
;; Verify disjoint condition between positive types and
@@ -631,15 +634,9 @@ DST is returned."
(comp-range-negation (range neg))
(range pos))))))
- (if (comp-cstr-empty-p neg)
- (setf (typeset dst) (typeset pos)
- (valset dst) (valset pos)
- (range dst) (range pos)
- (neg dst) nil)
- (setf (typeset dst) (typeset neg)
- (valset dst) (valset neg)
- (range dst) (range neg)
- (neg dst) (neg neg)))))
+ (comp-cstr-shallow-copy dst (if (comp-cstr-empty-p neg)
+ pos
+ neg))))
;; (not null) => t
(when (and (neg dst)
@@ -663,10 +660,7 @@ DST is returned."
(mapcar #'comp-cstr-copy srcs)
(apply #'comp-cstr-union-1-no-mem range srcs)
mem-h))))
- (setf (typeset dst) (typeset res)
- (valset dst) (valset res)
- (range dst) (range res)
- (neg dst) (neg res))
+ (comp-cstr-shallow-copy dst res)
res)))
(cl-defun comp-cstr-intersection-homogeneous (dst &rest srcs)
@@ -753,10 +747,8 @@ Non memoized version of `comp-cstr-intersection-no-mem'."
;; In case pos is not relevant return directly the content
;; of neg.
(when (equal (typeset pos) '(t))
- (setf (typeset dst) (typeset neg)
- (valset dst) (valset neg)
- (range dst) (range neg)
- (neg dst) t)
+ (comp-cstr-shallow-copy dst neg)
+ (setf (neg dst) t)
;; (not t) => nil
(when (and (null (valset dst))
@@ -800,10 +792,8 @@ Non memoized version of `comp-cstr-intersection-no-mem'."
(cl-set-difference (valset pos) (valset neg)))
;; Return a non negated form.
- (setf (typeset dst) (typeset pos)
- (valset dst) (valset pos)
- (range dst) (range pos)
- (neg dst) nil)))
+ (comp-cstr-shallow-copy dst pos)
+ (setf (neg dst) nil)))
dst))))
@@ -883,7 +873,7 @@ Non memoized version of `comp-cstr-intersection-no-mem'."
"Constraint OP1 being = OP2 setting the result into DST."
(with-comp-cstr-accessors
(cl-flet ((relax-cstr (cstr)
- (setf cstr (comp-cstr-shallow-copy cstr))
+ (setf cstr (copy-sequence cstr))
;; If can be any float extend it to all integers.
(when (memq 'float (typeset cstr))
(setf (range cstr) '((- . +))))
@@ -1008,10 +998,7 @@ DST is returned."
(mapcar #'comp-cstr-copy srcs)
(apply #'comp-cstr-intersection-no-mem srcs)
mem-h))))
- (setf (typeset dst) (typeset res)
- (valset dst) (valset res)
- (range dst) (range res)
- (neg dst) (neg res))
+ (comp-cstr-shallow-copy dst res)
res)))
(defun comp-cstr-intersection-no-hashcons (dst &rest srcs)
@@ -1067,10 +1054,9 @@ DST is returned."
(valset dst) ()
(range dst) nil
(neg dst) nil))
- (t (setf (typeset dst) (typeset src)
- (valset dst) (valset src)
- (range dst) (range src)
- (neg dst) (not (neg src)))))
+ (t
+ (comp-cstr-shallow-copy dst src)
+ (setf (neg dst) (not (neg src)))))
dst))
(defun comp-cstr-value-negation (dst src)
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index 7bbe63c3e15..b51224088f1 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -116,9 +116,9 @@ or one if there's just one execution unit."
:version "28.1")
(defcustom native-comp-async-cu-done-functions nil
- "List of functions to call after asynchronously compiling one compilation unit.
-Called with one argument FILE, the filename used as input to
-compilation."
+ "List of functions to call when asynchronous compilation of a file is done.
+Each function is called with one argument FILE, the filename whose
+compilation has completed."
:type 'hook
:version "28.1")
@@ -166,6 +166,16 @@ if `confirm-kill-processes' is non-nil."
:type 'boolean
:version "28.1")
+(defcustom native-comp-compiler-options nil
+ "Command line options passed verbatim to GCC compiler.
+Note that not all options are meaningful and some options might even
+break your Emacs. Use at your own risk.
+
+Passing these options is only available in libgccjit version 9
+and above."
+ :type '(repeat string)
+ :version "28.1")
+
(defcustom native-comp-driver-options nil
"Options passed verbatim to the native compiler's back-end driver.
Note that not all options are meaningful; typically only the options
@@ -755,6 +765,8 @@ Returns ELT."
:documentation "Default speed for this compilation unit.")
(debug native-comp-debug :type number
:documentation "Default debug level for this compilation unit.")
+ (compiler-options native-comp-compiler-options :type list
+ :documentation "Options for the GCC compiler.")
(driver-options native-comp-driver-options :type list
:documentation "Options for the GCC driver.")
(top-level-forms () :type list
@@ -889,8 +901,8 @@ non local exit (ends with an `unreachable' insn)."))
(lap () :type list
:documentation "LAP assembly representation.")
(ssa-status nil :type symbol
- :documentation "SSA status either: 'nil', 'dirty' or 't'.
-Once in SSA form this *must* be set to 'dirty' every time the topology of the
+ :documentation "SSA status either: nil, `dirty' or t.
+Once in SSA form this *must* be set to `dirty' every time the topology of the
CFG is mutated by a pass.")
(frame-size nil :type integer)
(vframe-size 0 :type integer)
@@ -1347,6 +1359,8 @@ clashes."
byte-native-qualities)
(comp-ctxt-debug comp-ctxt) (alist-get 'native-comp-debug
byte-native-qualities)
+ (comp-ctxt-compiler-options comp-ctxt) (alist-get 'native-comp-compiler-options
+ byte-native-qualities)
(comp-ctxt-driver-options comp-ctxt) (alist-get 'native-comp-driver-options
byte-native-qualities)
(comp-ctxt-top-level-forms comp-ctxt)
@@ -3072,13 +3086,6 @@ Forward propagate immediate involed in assignments." ; FIXME: Typo. Involved or
(`(setimm ,lval ,v)
(setf (comp-cstr-imm lval) v))))))
-(defun comp-mvar-propagate (lval rval)
- "Propagate into LVAL properties of RVAL."
- (setf (comp-mvar-typeset lval) (comp-mvar-typeset rval)
- (comp-mvar-valset lval) (comp-mvar-valset rval)
- (comp-mvar-range lval) (comp-mvar-range rval)
- (comp-mvar-neg lval) (comp-mvar-neg rval)))
-
(defun comp-function-foldable-p (f args)
"Given function F called with ARGS, return non-nil when optimizable."
(and (comp-function-pure-p f)
@@ -3128,10 +3135,7 @@ Fold the call in case."
(when (comp-cstr-empty-p cstr)
;; Store it to be rewritten as non local exit.
(setf (comp-block-lap-non-ret-insn comp-block) insn))
- (setf (comp-mvar-range lval) (comp-cstr-range cstr)
- (comp-mvar-valset lval) (comp-cstr-valset cstr)
- (comp-mvar-typeset lval) (comp-cstr-typeset cstr)
- (comp-mvar-neg lval) (comp-cstr-neg cstr))))
+ (comp-cstr-shallow-copy lval cstr)))
(cl-case f
(+ (comp-cstr-add lval args))
(- (comp-cstr-sub lval args))
@@ -3149,9 +3153,9 @@ Fold the call in case."
(let ((f (comp-func-name (gethash f (comp-ctxt-funcs-h comp-ctxt)))))
(comp-fwprop-call insn lval f args)))
(_
- (comp-mvar-propagate lval rval))))
+ (comp-cstr-shallow-copy lval rval))))
(`(assume ,lval ,(and (pred comp-mvar-p) rval))
- (comp-mvar-propagate lval rval))
+ (comp-cstr-shallow-copy lval rval))
(`(assume ,lval (,kind . ,operands))
(cl-case kind
(and
@@ -3639,6 +3643,9 @@ Prepare every function for final compilation and drive the C back-end."
(defvar comp-async-compilation nil
"Non-nil while executing an asynchronous native compilation.")
+(defvar comp-running-batch-compilation nil
+ "Non-nil when compilation is driven by any `batch-*-compile' function.")
+
(defun comp-final (_)
"Final pass driving the C back-end for code emission."
(maphash #'comp-compute-function-type (comp-ctxt-funcs-h comp-ctxt))
@@ -3647,7 +3654,7 @@ Prepare every function for final compilation and drive the C back-end."
;; unless during bootstrap or async compilation (bug#45056). GCC
;; leaks memory but also interfere with the ability of Emacs to
;; detect when a sub-process completes (TODO understand why).
- (if (or byte+native-compile comp-async-compilation)
+ (if (or comp-running-batch-compilation comp-async-compilation)
(comp-final1)
;; Call comp-final1 in a child process.
(let* ((output (comp-ctxt-output comp-ctxt))
@@ -3663,6 +3670,8 @@ Prepare every function for final compilation and drive the C back-end."
comp-libgccjit-reproducer ,comp-libgccjit-reproducer
comp-ctxt ,comp-ctxt
native-comp-eln-load-path ',native-comp-eln-load-path
+ native-comp-compiler-options
+ ',native-comp-compiler-options
native-comp-driver-options
',native-comp-driver-options
load-path ',load-path)
@@ -3762,15 +3771,18 @@ Return the trampoline if found or nil otherwise."
for arg in lambda-list
unless (memq arg '(&optional &rest))
collect arg)))))
- ;; Use speed 0 to maximize compilation speed and not to
- ;; optimize away funcall calls!
+ ;; Use speed 1 for compilation speed and not to optimize away
+ ;; funcall calls!
(byte-optimize nil)
(native-comp-speed 1)
(lexical-binding t))
(comp--native-compile
form nil
(cl-loop
- for dir in (comp-eln-load-path-eff)
+ 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)
@@ -3788,8 +3800,9 @@ Return the trampoline if found or nil otherwise."
;;;###autoload
(defun comp-clean-up-stale-eln (file)
- "Given FILE remove all its *.eln files in `native-comp-eln-load-path'
-sharing the original source filename (including FILE)."
+ "Remove all FILE*.eln* files found in `native-comp-eln-load-path'.
+The files to be removed are those produced from the original source
+filename (including FILE)."
(when (string-match (rx "-" (group-n 1 (1+ hex)) "-" (1+ hex) ".eln" eos)
file)
(cl-loop
@@ -3856,26 +3869,13 @@ processes from `comp-async-compilations'"
do (remhash file-name comp-async-compilations))
(hash-table-count comp-async-compilations))
-(declare-function w32-get-nproc "w32.c")
(defvar comp-num-cpus nil)
(defun comp-effective-async-max-jobs ()
"Compute the effective number of async jobs."
(if (zerop native-comp-async-jobs-number)
(or comp-num-cpus
(setf comp-num-cpus
- ;; FIXME: we already have a function to determine
- ;; the number of processors, see get_native_system_info in w32.c.
- ;; The result needs to be exported to Lisp.
- (max 1 (/ (cond ((eq 'windows-nt system-type)
- (w32-get-nproc))
- ((executable-find "nproc")
- (string-to-number
- (shell-command-to-string "nproc")))
- ((eq 'berkeley-unix system-type)
- (string-to-number
- (shell-command-to-string "sysctl -n hw.ncpu")))
- (t 1))
- 2))))
+ (max 1 (/ (num-processors) 2))))
native-comp-async-jobs-number))
(defvar comp-last-scanned-async-output nil)
@@ -3918,13 +3918,16 @@ display a message."
do (let* ((expr `((require 'comp)
,(when (boundp 'backtrace-line-length)
`(setf backtrace-line-length ,backtrace-line-length))
- (setf native-compile-target-directory ,native-compile-target-directory
+ (setf comp-file-preloaded-p ,comp-file-preloaded-p
+ native-compile-target-directory ,native-compile-target-directory
native-comp-speed ,native-comp-speed
native-comp-debug ,native-comp-debug
native-comp-verbose ,native-comp-verbose
comp-libgccjit-reproducer ,comp-libgccjit-reproducer
comp-async-compilation t
native-comp-eln-load-path ',native-comp-eln-load-path
+ native-comp-compiler-options
+ ',native-comp-compiler-options
native-comp-driver-options
',native-comp-driver-options
load-path ',load-path
@@ -4171,19 +4174,28 @@ form, return the compiled function."
(comp--native-compile function-or-file nil output))
;;;###autoload
-(defun batch-native-compile ()
- "Perform native compilation on remaining command-line arguments.
-Use this from the command line, with ‘-batch’;
-it won’t work in an interactive Emacs.
-Native compilation equivalent to `batch-byte-compile'."
+(defun batch-native-compile (&optional for-tarball)
+ "Perform batch native compilation of remaining command-line arguments.
+
+Native compilation equivalent of `batch-byte-compile'.
+Use this from the command line, with `-batch'; it won't work
+in an interactive Emacs session.
+Optional argument FOR-TARBALL non-nil means the file being compiled
+as part of building the source tarball, in which case the .eln file
+will be placed under the native-lisp/ directory (actually, in the
+last directory in `native-comp-eln-load-path')."
(comp-ensure-native-compiler)
- (cl-loop for file in command-line-args-left
- if (or (null byte+native-compile)
- (cl-notany (lambda (re) (string-match re file))
- native-comp-bootstrap-deny-list))
- do (comp--native-compile file)
- else
- do (byte-compile-file file)))
+ (let ((comp-running-batch-compilation t)
+ (native-compile-target-directory
+ (if for-tarball
+ (car (last native-comp-eln-load-path)))))
+ (cl-loop for file in command-line-args-left
+ if (or (null byte+native-compile)
+ (cl-notany (lambda (re) (string-match re file))
+ native-comp-bootstrap-deny-list))
+ do (comp--native-compile file)
+ else
+ do (byte-compile-file file))))
;;;###autoload
(defun batch-byte+native-compile ()
diff --git a/lisp/emacs-lisp/copyright.el b/lisp/emacs-lisp/copyright.el
index d2e4891acee..9da370a725d 100644
--- a/lisp/emacs-lisp/copyright.el
+++ b/lisp/emacs-lisp/copyright.el
@@ -120,7 +120,7 @@ When this is `function', only ask when called non-interactively."
(re-search-forward regexp bound noerror count)))
(defun copyright-start-point ()
- "Return point-min or point-max, depending on `copyright-at-end-flag'."
+ "Return `point-min' or `point-max', depending on `copyright-at-end-flag'."
(if copyright-at-end-flag
(point-max)
(point-min)))
@@ -135,7 +135,7 @@ When this is `function', only ask when called non-interactively."
(defun copyright-find-copyright ()
"Return non-nil if a copyright header suitable for updating is found.
The header must match `copyright-regexp' and `copyright-names-regexp', if set.
-This function sets the match-data that `copyright-update-year' uses."
+This function sets the match data that `copyright-update-year' uses."
(widen)
(goto-char (copyright-start-point))
;; In case the regexp is rejected. This is useful because
diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el
index d24ea355a51..59cbc0e50d5 100644
--- a/lisp/emacs-lisp/crm.el
+++ b/lisp/emacs-lisp/crm.el
@@ -244,30 +244,29 @@ contents of the minibuffer are \"alice,bob,eve\" and point is between
This function returns a list of the strings that were read,
with empty strings removed."
- (unwind-protect
- (progn
- (add-hook 'choose-completion-string-functions
- 'crm--choose-completion-string)
- (let* ((minibuffer-completion-table #'crm--collection-fn)
- (minibuffer-completion-predicate predicate)
- ;; see completing_read in src/minibuf.c
- (minibuffer-completion-confirm
- (unless (eq require-match t) require-match))
- (crm-completion-table table)
- (map (if require-match
- crm-local-must-match-map
- crm-local-completion-map))
- ;; If the user enters empty input, `read-from-minibuffer'
- ;; returns the empty string, not DEF.
- (input (read-from-minibuffer
- prompt initial-input map
- nil hist def inherit-input-method)))
- (when (and def (string-equal input ""))
- (setq input (if (consp def) (car def) def)))
- ;; Remove empty strings in the list of read strings.
- (split-string input crm-separator t)))
- (remove-hook 'choose-completion-string-functions
- 'crm--choose-completion-string)))
+ (let* ((map (if require-match
+ crm-local-must-match-map
+ crm-local-completion-map))
+ input)
+ (minibuffer-with-setup-hook
+ (lambda ()
+ (add-hook 'choose-completion-string-functions
+ 'crm--choose-completion-string nil 'local)
+ (setq-local minibuffer-completion-table #'crm--collection-fn)
+ (setq-local minibuffer-completion-predicate predicate)
+ ;; see completing_read in src/minibuf.c
+ (setq-local minibuffer-completion-confirm
+ (unless (eq require-match t) require-match))
+ (setq-local crm-completion-table table))
+ (setq input (read-from-minibuffer
+ prompt initial-input map
+ nil hist def inherit-input-method)))
+ ;; If the user enters empty input, `read-from-minibuffer'
+ ;; returns the empty string, not DEF.
+ (when (and def (string-equal input ""))
+ (setq input (if (consp def) (car def) def)))
+ ;; Remove empty strings in the list of read strings.
+ (split-string input crm-separator t)))
;; testing and debugging
;; (defun crm-init-test-environ ()
diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el
index 2007f79634d..163528acf6f 100644
--- a/lisp/emacs-lisp/debug.el
+++ b/lisp/emacs-lisp/debug.el
@@ -119,7 +119,7 @@ This is to optimize `debugger-make-xrefs'.")
(defvar debugger-jumping-flag nil
"Non-nil means that `debug-on-entry' is disabled.
This variable is used by `debugger-jump', `debugger-step-through',
-and `debugger-reenable' to temporarily disable debug-on-entry.")
+and `debugger-reenable' to temporarily disable `debug-on-entry'.")
(defvar inhibit-trace) ;Not yet implemented.
@@ -128,7 +128,7 @@ and `debugger-reenable' to temporarily disable debug-on-entry.")
It is a list expected to take the form (CAUSE . REST)
where CAUSE can be:
- debug: called for entry to a flagged function.
-- t: called because of debug-on-next-call.
+- t: called because of `debug-on-next-call'.
- lambda: same thing but via `funcall'.
- exit: called because of exit of a flagged function.
- error: called because of `debug-on-error'.")
@@ -266,16 +266,15 @@ the debugger will not be entered."
(window-frame debugger-previous-window)))
`((previous-window . ,debugger-previous-window))))))
(setq debugger-window (selected-window))
- (if (eq debugger-previous-window debugger-window)
- (when debugger-jumping-flag
- ;; Try to restore previous height of debugger
- ;; window.
- (condition-case nil
- (window-resize
- debugger-window
- (- debugger-previous-window-height
- (window-total-height debugger-window)))
- (error nil)))
+ (when debugger-jumping-flag
+ ;; Try to restore previous height of debugger
+ ;; window.
+ (condition-case nil
+ (window-resize
+ debugger-window
+ (- debugger-previous-window-height
+ (window-total-height debugger-window)))
+ (error nil))
(setq debugger-previous-window debugger-window))
(message "")
(let ((standard-output nil)
@@ -336,7 +335,7 @@ Make functions into cross-reference buttons if DO-XREFS is non-nil."
(defun debugger-setup-buffer (args)
"Initialize the `*Backtrace*' buffer for entry to the debugger.
-That buffer should be current already and in debugger-mode."
+That buffer should be current already and in `debugger-mode'."
(setq backtrace-frames (nthcdr
;; Remove debug--implement-debug-on-entry and the
;; advice's `apply' frame.
@@ -391,7 +390,7 @@ Include the reason for debugger entry from ARGS."
(`(set ,buffer) (format "setting %s in buffer %s to %s"
symbol buffer
(backtrace-print-to-string newval)))
- (_ (error "unrecognized watchpoint triggered %S" (cdr args))))
+ (_ (error "Unrecognized watchpoint triggered %S" (cdr args))))
": ")
(insert ?\n))
;; Debugger entered for an error.
@@ -455,7 +454,7 @@ will be used, such as in a debug on exit from a frame."
(exit-recursive-edit))
(defun debugger-jump ()
- "Continue to exit from this frame, with all debug-on-entry suspended."
+ "Continue to exit from this frame, with all `debug-on-entry' suspended."
(interactive)
(debugger-frame)
(setq debugger-jumping-flag t)
@@ -465,7 +464,7 @@ will be used, such as in a debug on exit from a frame."
(exit-recursive-edit))
(defun debugger-reenable ()
- "Turn all debug-on-entry functions back on.
+ "Turn all `debug-on-entry' functions back on.
This function is put on `post-command-hook' by `debugger-jump' and
removes itself from that hook."
(setq debugger-jumping-flag nil)
@@ -696,13 +695,14 @@ Redefining FUNCTION also cancels it."
;;;###autoload
(defun cancel-debug-on-entry (&optional function)
"Undo effect of \\[debug-on-entry] on FUNCTION.
-If FUNCTION is nil, cancel debug-on-entry for all functions.
+If FUNCTION is nil, cancel `debug-on-entry' for all functions.
When called interactively, prompt for FUNCTION in the minibuffer.
To specify a nil argument interactively, exit with an empty minibuffer."
(interactive
(list (let ((name
(completing-read
- "Cancel debug on entry to function (default all functions): "
+ (format-prompt "Cancel debug on entry to function"
+ "all functions")
(mapcar #'symbol-name (debug--function-list)) nil t)))
(when name
(unless (string= name "")
@@ -799,13 +799,14 @@ another symbol also cancels it."
;;;###autoload
(defun cancel-debug-on-variable-change (&optional variable)
"Undo effect of \\[debug-on-variable-change] on VARIABLE.
-If VARIABLE is nil, cancel debug-on-variable-change for all variables.
+If VARIABLE is nil, cancel `debug-on-variable-change' for all variables.
When called interactively, prompt for VARIABLE in the minibuffer.
To specify a nil argument interactively, exit with an empty minibuffer."
(interactive
(list (let ((name
(completing-read
- "Cancel debug on set for variable (default all variables): "
+ (format-prompt "Cancel debug on set for variable"
+ "all variables")
(mapcar #'symbol-name (debug--variable-list)) nil t)))
(when name
(unless (string= name "")
diff --git a/lisp/emacs-lisp/derived.el b/lisp/emacs-lisp/derived.el
index 43d6dfd3c81..af5eecc22a5 100644
--- a/lisp/emacs-lisp/derived.el
+++ b/lisp/emacs-lisp/derived.el
@@ -94,19 +94,19 @@
;;; PRIVATE: defsubst must be defined before they are first used
(defsubst derived-mode-hook-name (mode)
- "Construct a mode-hook name based on a MODE name."
+ "Construct a mode-hook name based on the symbol MODE."
(intern (concat (symbol-name mode) "-hook")))
(defsubst derived-mode-map-name (mode)
- "Construct a map name based on a MODE name."
+ "Construct a map name based on the symbol MODE."
(intern (concat (symbol-name mode) "-map")))
(defsubst derived-mode-syntax-table-name (mode)
- "Construct a syntax-table name based on a MODE name."
+ "Construct a syntax-table name based on the symbol MODE."
(intern (concat (symbol-name mode) "-syntax-table")))
(defsubst derived-mode-abbrev-table-name (mode)
- "Construct an abbrev-table name based on a MODE name."
+ "Construct an abbrev-table name based on the symbol MODE."
(intern (concat (symbol-name mode) "-abbrev-table")))
;; PUBLIC: define a new major mode which inherits from an existing one.
@@ -120,7 +120,7 @@ The arguments are as follows:
CHILD: the name of the command for the derived mode.
PARENT: the name of the command for the parent mode (e.g. `text-mode')
or nil if there is no parent.
-NAME: a string which will appear in the status line (e.g. \"Hypertext\")
+NAME: a string that will appear in the mode line (e.g. \"HTML\")
DOCSTRING: an optional documentation string--if you do not supply one,
the function will attempt to invent something useful.
KEYWORD-ARGS:
@@ -139,7 +139,7 @@ KEYWORD-ARGS:
A nil value means to simply use the same abbrev-table
as the parent.
:after-hook FORM
- A single lisp form which is evaluated after the mode
+ A single Lisp form which is evaluated after the mode
hooks have been run. It should not be quoted.
:interactive BOOLEAN
Whether the derived mode should be `interactive' or not.
@@ -166,8 +166,8 @@ the parent, and then sets the variable `case-fold-search' to nil:
Note that if the documentation string had been left out, it would have
been generated automatically, with a reference to the keymap.
-The new mode runs the hook constructed by the function
-`derived-mode-hook-name'.
+The new mode runs the hook named MODE-hook. For `foo-mode',
+the hook will be named `foo-mode-hook'.
See Info node `(elisp)Derived Modes' for more details.
@@ -175,12 +175,7 @@ See Info node `(elisp)Derived Modes' for more details.
(declare (debug (&define name symbolp sexp [&optional stringp]
[&rest keywordp sexp] def-body))
(doc-string 4)
- ;; Ask not what
- ;;(indent 3)
- ;; can do for you, ask what it can do to others. IOW, the
- ;; missing of indentation setting here is the indentation
- ;; setting and not an oversight.
- )
+ (indent defun))
(when (and docstring (not (stringp docstring)))
;; Some trickiness, since what appears to be the docstring may really be
@@ -321,7 +316,7 @@ No problems result if this variable is not bound.
(format "Major mode derived from `%s' by `define-derived-mode'.
It inherits all of the parent's attributes, but has its own keymap%s:
- `%s'%s
+%s
which more-or-less shadow%s %s's corresponding table%s."
parent
@@ -330,12 +325,14 @@ which more-or-less shadow%s %s's corresponding table%s."
(abbrev "\nand abbrev table")
(syntax "\nand syntax table")
(t ""))
- map
- (cond ((and abbrev syntax)
- (format ", `%s' and `%s'" abbrev syntax))
- ((or abbrev syntax)
- (format " and `%s'" (or abbrev syntax)))
- (t ""))
+ (internal--format-docstring-line
+ " `%s'%s"
+ map
+ (cond ((and abbrev syntax)
+ (format ", `%s' and `%s'" abbrev syntax))
+ ((or abbrev syntax)
+ (format " and `%s'" (or abbrev syntax)))
+ (t "")))
(if (or abbrev syntax) "" "s")
parent
(if (or abbrev syntax) "s" "")))))
diff --git a/lisp/emacs-lisp/disass.el b/lisp/emacs-lisp/disass.el
index 712fa511707..6c019e7387c 100644
--- a/lisp/emacs-lisp/disass.el
+++ b/lisp/emacs-lisp/disass.el
@@ -114,7 +114,7 @@ redefine OBJECT if it is a symbol."
(if (eq (car-safe obj) 'byte-code)
(setq obj `(lambda () ,obj)))
(when (consp obj)
- (unless (functionp obj) (error "not a function"))
+ (unless (functionp obj) (error "Not a function"))
(if (assq 'byte-code obj)
nil
(if interactive-p (message (if name
@@ -183,7 +183,7 @@ redefine OBJECT if it is a symbol."
(defun disassemble-1 (obj indent)
- "Prints the byte-code call OBJ in the current buffer.
+ "Print the byte-code call OBJ in the current buffer.
OBJ should be a call to BYTE-CODE generated by the byte compiler."
(let (bytes constvec)
(if (consp obj)
diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el
index d9b5ea74f6e..db86e0e0292 100644
--- a/lisp/emacs-lisp/easy-mmode.el
+++ b/lisp/emacs-lisp/easy-mmode.el
@@ -32,7 +32,7 @@
;; natural for the minor-mode end-users.
;; For each mode, easy-mmode defines the following:
-;; <mode> : The minor mode predicate. A buffer-local variable.
+;; <mode> : The minor mode predicate. A buffer-local variable.
;; <mode>-map : The keymap possibly associated to <mode>.
;; see `define-minor-mode' documentation
;;
@@ -93,7 +93,7 @@ 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 `%S'.
+evaluate `%s'.
The mode's hook is called both when the mode is enabled and when
it is disabled.")
@@ -109,7 +109,9 @@ it is disabled.")
(docs-fc (bound-and-true-p emacs-lisp-docstring-fill-column))
(fill-column (if (integerp docs-fc) docs-fc 65))
(argdoc (format easy-mmode--arg-docstring mode-pretty-name
- getter))
+ ;; Avoid having quotes turn into pretty quotes.
+ (string-replace "'" "\\\\='"
+ (format "%S" getter))))
(filled (if (fboundp 'fill-region)
(with-temp-buffer
(insert argdoc)
@@ -163,8 +165,8 @@ BODY contains code to execute each time the mode is enabled or disabled.
Not used if you also specify :variable.
:lighter SPEC Text displayed in the mode line when the mode is on.
:keymap MAP Keymap bound to the mode keymap. Defaults to `MODE-map'.
- If non-nil, it should be a variable name (whose value is
- a keymap), or an expression that returns either a keymap or
+ If non-nil, it should be an unquoted variable name (whose value
+ is a keymap), or an expression that returns either a keymap or
a list of (KEY . BINDING) pairs where KEY and BINDING are
suitable for `define-key'. If you supply a KEYMAP argument
that is not a symbol, this macro defines the variable MODE-map
@@ -182,7 +184,7 @@ BODY contains code to execute each time the mode is enabled or disabled.
be assigned to PLACE. If you specify a :variable, this function
does not define a MODE variable (nor any of the terms used
in :variable).
-:after-hook A single lisp form which is evaluated after the mode hooks
+:after-hook A single Lisp form which is evaluated after the mode hooks
have been run. It should not be quoted.
For example, you could write
@@ -196,6 +198,7 @@ INIT-VALUE LIGHTER KEYMAP.
\(fn MODE DOC [KEYWORD VAL ... &rest BODY])"
(declare (doc-string 2)
+ (indent defun)
(debug (&define name string-or-null-p
[&optional [&not keywordp] sexp
&optional [&not keywordp] sexp
@@ -448,7 +451,7 @@ after running the major mode's hook. However, MODE is not turned
on if the hook has explicitly disabled it.
\(fn GLOBAL-MODE MODE TURN-ON [KEY VALUE]... BODY...)"
- (declare (doc-string 2))
+ (declare (doc-string 2) (indent defun))
(let* ((global-mode-name (symbol-name global-mode))
(mode-name (symbol-name mode))
(pretty-name (easy-mmode-pretty-mode-name mode))
@@ -496,15 +499,17 @@ on if the hook has explicitly disabled it.
(define-minor-mode ,global-mode
,(concat (format "Toggle %s in all buffers.\n" pretty-name)
(internal--format-docstring-line
- "With prefix ARG, enable %s if ARG is positive; otherwise, \
-disable it.\n\n"
+ (concat "With prefix ARG, enable %s if ARG is positive; "
+ "otherwise, disable it.")
pretty-global-name)
+ "\n\n"
"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.\n\n"
(internal--format-docstring-line
- "%s is enabled in all buffers where `%s' would do it.\n\n"
+ "%s is enabled in all buffers where `%s' would do it."
pretty-name turn-on)
+ "\n\n"
(internal--format-docstring-line
"See `%s' for more information on %s."
mode pretty-name)
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index 7def9ff96a7..ac1cd22ac27 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -469,7 +469,7 @@ just FUNCTION is printed."
(funcall orig-fun nil)))
(defun edebug-eval-defun (edebug-it)
- (declare (obsolete "use eval-defun or edebug--eval-defun instead" "28.1"))
+ (declare (obsolete "use `eval-defun' or `edebug--eval-defun' instead" "28.1"))
(interactive "P")
(if (advice-member-p #'edebug--eval-defun 'eval-defun)
(eval-defun edebug-it)
@@ -3519,7 +3519,8 @@ The removes the effect of `edebug-on-entry'. If FUNCTION is
nil, remove `edebug-on-entry' on all functions."
(interactive
(list (let ((name (completing-read
- "Cancel edebug on entry to (default all functions): "
+ (format-prompt "Cancel edebug on entry to"
+ "all functions")
(let ((functions (edebug--edebug-on-entry-functions)))
(unless functions
(user-error "No functions have `edebug-on-entry'"))
@@ -3571,7 +3572,7 @@ This is useful for exiting even if `unwind-protect' code may be executed."
(defun edebug-set-initial-mode ()
"Set the initial execution mode of Edebug.
The mode is requested via the key that would be used to set the mode in
-edebug-mode."
+`edebug-mode'."
(interactive)
(let* ((old-mode edebug-initial-mode)
(key (read-key-sequence
@@ -4468,7 +4469,7 @@ With prefix argument, make it a temporary breakpoint."
'read-expression-history)))))))
(edebug-modify-breakpoint t condition arg))
-(easy-menu-define edebug-menu edebug-mode-map "Edebug menus" edebug-mode-menus)
+(easy-menu-define edebug-menu edebug-mode-map "Edebug menus." edebug-mode-menus)
;;; Finalize Loading
@@ -4548,7 +4549,8 @@ instrumentation for, defaulting to all functions."
(user-error "Found no functions to remove instrumentation from"))
(let ((name
(completing-read
- "Remove instrumentation from (default all functions): "
+ (format-prompt "Remove instrumentation from"
+ "all functions")
functions)))
(if (and name
(not (equal name "")))
diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el
index ec7c899bddc..5414c32c340 100644
--- a/lisp/emacs-lisp/eieio-base.el
+++ b/lisp/emacs-lisp/eieio-base.el
@@ -252,7 +252,7 @@ This is used with the `object-write' method.")
:documentation
"Saving this object should make backup files.
Setting to nil will mean no backups are made."))
- "This special class enables persistence through save files
+ "This special class enables persistence through save files.
Use the `object-write' method to write this object to disk. The save
format is Emacs Lisp code which calls the constructor for the saved
object. For this reason, only slots which do not have an `:initarg'
diff --git a/lisp/emacs-lisp/eieio-compat.el b/lisp/emacs-lisp/eieio-compat.el
index 6d84839c341..a5f37500092 100644
--- a/lisp/emacs-lisp/eieio-compat.el
+++ b/lisp/emacs-lisp/eieio-compat.el
@@ -5,6 +5,7 @@
;; Author: Eric M. Ludlam <zappo@gnu.org>
;; Keywords: OO, lisp
;; Package: eieio
+;; Obsolete-Since: 25.1
;; This file is part of GNU Emacs.
@@ -70,7 +71,8 @@ is appropriate to use. Uses `defmethod' to create methods, and calls
`defgeneric' for you. With this implementation the ARGS are
currently ignored. You can use `defgeneric' to apply specialized
top level documentation to a method."
- (declare (doc-string 3) (obsolete cl-defgeneric "25.1"))
+ (declare (doc-string 3) (obsolete cl-defgeneric "25.1")
+ (indent defun))
`(eieio--defalias ',method
(eieio--defgeneric-init-form
',method
@@ -103,6 +105,7 @@ Summary:
\"doc-string\"
body)"
(declare (doc-string 3) (obsolete cl-defmethod "25.1")
+ (indent defun)
(debug
(&define ; this means we are defining something
[&name sexp] ;Allow (setf ...) additionally to symbols.
diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el
index b11ed3333f0..ca47ec77f76 100644
--- a/lisp/emacs-lisp/eieio-core.el
+++ b/lisp/emacs-lisp/eieio-core.el
@@ -450,7 +450,7 @@ See `defclass' for more information."
))
;; Now that everything has been loaded up, all our lists are backwards!
- ;; Fix that up now and then them into vectors.
+ ;; Fix that up now and turn them into vectors.
(cl-callf (lambda (slots) (apply #'vector (nreverse slots)))
(eieio--class-slots newc))
(cl-callf nreverse (eieio--class-initarg-tuples newc))
@@ -478,7 +478,8 @@ See `defclass' for more information."
;; (dotimes (cnt (length cslots))
;; (setf (gethash (cl--slot-descriptor-name (aref cslots cnt)) oa) (- -1 cnt)))
(dotimes (cnt (length slots))
- (setf (gethash (cl--slot-descriptor-name (aref slots cnt)) oa) cnt))
+ (setf (gethash (cl--slot-descriptor-name (aref slots cnt)) oa)
+ (+ (eval-when-compile eieio--object-num-slots) cnt)))
(setf (eieio--class-index-table newc) oa))
;; Set up a specialized doc string.
@@ -508,6 +509,7 @@ See `defclass' for more information."
;; Create the cached default object.
(let ((cache (make-record newc
(+ (length (eieio--class-slots newc))
+ ;; FIXME: Why +1 -1 ?
(eval-when-compile eieio--object-num-slots)
-1)
nil)))
@@ -702,11 +704,15 @@ an error."
nil
;; Trim off object IDX junk added in for the object index.
(setq slot-idx (- slot-idx (eval-when-compile eieio--object-num-slots)))
- (let ((st (cl--slot-descriptor-type (aref (eieio--class-slots class)
- slot-idx))))
- (if (not (eieio--perform-slot-validation st value))
- (signal 'invalid-slot-type
- (list (eieio--class-name class) slot st value))))))
+ (let* ((sd (aref (eieio--class-slots class)
+ slot-idx))
+ (st (cl--slot-descriptor-type sd)))
+ (cond
+ ((not (eieio--perform-slot-validation st value))
+ (signal 'invalid-slot-type
+ (list (eieio--class-name class) slot st value)))
+ ((alist-get :read-only (cl--slot-descriptor-props sd))
+ (signal 'eieio-read-only (list (eieio--class-name class) slot)))))))
(defun eieio--validate-class-slot-value (class slot-idx value slot)
"Make sure that for CLASS referencing SLOT-IDX, VALUE is valid.
@@ -747,7 +753,7 @@ Argument FN is the function calling this verifier."
(_ exp))))
(gv-setter eieio-oset))
(cl-check-type slot symbol)
- (cl-check-type obj (or eieio-object class))
+ (cl-check-type obj (or eieio-object class cl-structure-object))
(let* ((class (cond ((symbolp obj)
(error "eieio-oref called on a class: %s" obj)
(eieio--full-class-object obj))
@@ -763,7 +769,7 @@ Argument FN is the function calling this verifier."
;; to intercept missing slot definitions. Since it is also the LAST
;; thing called in this fn, its return value would be retrieved.
(slot-missing obj slot 'oref))
- (cl-check-type obj eieio-object)
+ (cl-check-type obj (or eieio-object cl-structure-object))
(eieio-barf-if-slot-unbound (aref obj c) obj slot 'oref))))
@@ -811,7 +817,7 @@ Fills in CLASS's SLOT with its default value."
(defun eieio-oset (obj slot value)
"Do the work for the macro `oset'.
Fills in OBJ's SLOT with VALUE."
- (cl-check-type obj eieio-object)
+ (cl-check-type obj (or eieio-object cl-structure-object))
(cl-check-type slot symbol)
(let* ((class (eieio--object-class obj))
(c (eieio--slot-name-index class slot)))
@@ -892,7 +898,7 @@ reverse-lookup that name, and recurse with the associated slot value."
;; Removed checks to outside this call
(let* ((fsi (gethash slot (eieio--class-index-table class))))
(if (integerp fsi)
- (+ (eval-when-compile eieio--object-num-slots) fsi)
+ fsi
(let ((fn (eieio--initarg-to-attribute class slot)))
(if fn
;; Accessing a slot via its :initarg is accepted by EIEIO
@@ -953,7 +959,7 @@ need be... May remove that later...)"
class))
(defun eieio--c3-merge-lists (reversed-partial-result remaining-inputs)
- "Merge REVERSED-PARTIAL-RESULT REMAINING-INPUTS in a consistent order, if possible.
+ "Try to merge REVERSED-PARTIAL-RESULT REMAINING-INPUTS in a consistent order.
If a consistent order does not exist, signal an error."
(setq remaining-inputs (delq nil remaining-inputs))
(if (null remaining-inputs)
@@ -1061,6 +1067,7 @@ method invocation orders of the involved classes."
;;
(define-error 'invalid-slot-name "Invalid slot name")
(define-error 'invalid-slot-type "Invalid slot type")
+(define-error 'eieio-read-only "Read-only slot")
(define-error 'unbound-slot "Unbound slot")
(define-error 'inconsistent-class-hierarchy "Inconsistent class hierarchy")
diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el
index d7d078b2d94..4813ce8c33f 100644
--- a/lisp/emacs-lisp/eieio-custom.el
+++ b/lisp/emacs-lisp/eieio-custom.el
@@ -333,7 +333,7 @@ Optional argument GROUP is the sub-group of slots to display."
(let ((map (make-sparse-keymap)))
(set-keymap-parent map widget-keymap)
map)
- "Keymap for EIEIO Custom mode")
+ "Keymap for EIEIO Custom mode.")
(define-derived-mode eieio-custom-mode fundamental-mode "EIEIO Custom"
"Major mode for customizing EIEIO objects.
diff --git a/lisp/emacs-lisp/eieio-opt.el b/lisp/emacs-lisp/eieio-opt.el
index 9c842f46829..680395387c2 100644
--- a/lisp/emacs-lisp/eieio-opt.el
+++ b/lisp/emacs-lisp/eieio-opt.el
@@ -130,6 +130,7 @@ are not abstract."
;;;###autoload
(defun eieio-help-constructor (ctr)
"Describe CTR if it is a class constructor."
+ (declare (obsolete "use `describe-function' or `cl--describe-class'." "29.1"))
(when (class-p ctr)
(erase-buffer)
(let ((location (find-lisp-object-file-name ctr 'define-type))
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el
index c16d8e110ec..2850c91ecdf 100644
--- a/lisp/emacs-lisp/eieio.el
+++ b/lisp/emacs-lisp/eieio.el
@@ -110,7 +110,7 @@ Options in CLOS not supported in EIEIO:
Due to the way class options are set up, you can add any tags you wish,
and reference them using the function `class-option'."
- (declare (doc-string 4))
+ (declare (doc-string 4) (indent defun))
(cl-check-type superclasses list)
(cond ((and (stringp (car options-and-doc))
@@ -205,7 +205,7 @@ and reference them using the function `class-option'."
(eieio-oset this ',sname value))
accessors)
(push `(cl-defmethod ,acces ((this ,name))
- ,(format
+ ,(internal--format-docstring-line
"Retrieve the slot `%S' from an object of class `%S'."
sname name)
;; FIXME: Why is this different from the :reader case?
@@ -285,7 +285,8 @@ This method is obsolete."
;; Non-abstract classes need a constructor.
`(defun ,name (&rest slots)
- ,(format "Create a new object of class type `%S'." name)
+ ,(internal--format-docstring-line
+ "Create a new object of class type `%S'." name)
(declare (compiler-macro
(lambda (whole)
(if (not (stringp (car slots)))
@@ -358,9 +359,7 @@ variable name of the same name as the slot."
(defun eieio-pcase-slot-index-from-index-table (index-table slot)
"Find the index to pass to `aref' to access SLOT."
- (let ((index (gethash slot index-table)))
- (if index (+ (eval-when-compile eieio--object-num-slots)
- index))))
+ (gethash slot index-table))
(pcase-defmacro eieio (&rest fields)
"Pcase patterns that match EIEIO object EXPVAL.
@@ -993,11 +992,6 @@ of `eq'."
(error "EIEIO: `change-class' is unimplemented"))
(define-obsolete-function-alias 'change-class #'eieio-change-class "26.1")
-;; Hook ourselves into help system for describing classes and methods.
-;; FIXME: This is not actually needed any more since we can click on the
-;; hyperlink from the constructor's docstring to see the type definition.
-(add-hook 'help-fns-describe-function-functions #'eieio-help-constructor)
-
(provide 'eieio)
;;; eieio.el ends here
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index cec89cf3bc5..cd0e7dca7cf 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -380,7 +380,15 @@ Also store it in `eldoc-last-message' and return that value."
;; it undesirable to print eldoc messages right this instant.
(defun eldoc-display-message-no-interference-p ()
"Return nil if displaying a message would cause interference."
- (not (or executing-kbd-macro (bound-and-true-p edebug-active))))
+ (not (or executing-kbd-macro
+ (bound-and-true-p edebug-active)
+ ;; The following configuration shows "Matches..." in the
+ ;; echo area when point is after a closing bracket, which
+ ;; conflicts with eldoc.
+ (and (boundp 'show-paren-context-when-offscreen)
+ show-paren-context-when-offscreen
+ (not (pos-visible-in-window-p
+ (overlay-end show-paren--overlay)))))))
(defvar eldoc-documentation-functions nil
@@ -437,7 +445,7 @@ return any documentation.")
(defvar eldoc-display-functions
'(eldoc-display-in-echo-area eldoc-display-in-buffer)
"Hook of functions tasked with displaying ElDoc results.
-Each function is passed two arguments: DOCS and INTERACTIVE. DOCS
+Each function is passed two arguments: DOCS and INTERACTIVE. DOCS
is a list (DOC ...) where DOC looks like (STRING :KEY VALUE :KEY2
VALUE2 ...). STRING is a string containing the documentation's
text and the remainder of DOC is an optional list of
@@ -477,6 +485,7 @@ This holds the results of the last documentation request."
(let ((inhibit-read-only t)
(things-reported-on))
(erase-buffer) (setq buffer-read-only t)
+ (setq-local nobreak-char-display nil)
(local-set-key "q" 'quit-window)
(cl-loop for (docs . rest) on docs
for (this-doc . plist) = docs
diff --git a/lisp/emacs-lisp/elint.el b/lisp/emacs-lisp/elint.el
index 0fba5938f3d..32b2cbdb45a 100644
--- a/lisp/emacs-lisp/elint.el
+++ b/lisp/emacs-lisp/elint.el
@@ -1035,7 +1035,7 @@ Insert HEADER followed by a blank line if non-nil."
(sit-for 0)))
(defun elint-set-mode-line (&optional on)
- "Set the mode-line-process of the Elint log buffer."
+ "Set the `mode-line-process' of the Elint log buffer."
(with-current-buffer (elint-get-log-buffer)
(and (eq major-mode 'compilation-mode)
(setq mode-line-process
diff --git a/lisp/emacs-lisp/elp.el b/lisp/emacs-lisp/elp.el
index c2b026dc822..fde7947a273 100644
--- a/lisp/emacs-lisp/elp.el
+++ b/lisp/emacs-lisp/elp.el
@@ -202,14 +202,13 @@ This variable is set by the master function.")
(defvar elp-not-profilable
;; First, the functions used inside each instrumented function:
'(called-interactively-p
- ;; Then the functions used by the above functions. I used
- ;; (delq nil (mapcar (lambda (x) (and (symbolp x) (fboundp x) x))
- ;; (aref (symbol-function 'elp-wrapper) 2)))
- ;; to help me find this list.
- error call-interactively apply current-time
+ ;; (delq
+ ;; nil (mapcar
+ ;; (lambda (x) (and (symbolp x) (fboundp x) x))
+ ;; (aref (aref (aref (symbol-function 'elp--make-wrapper) 2) 1) 2)))
+ error apply current-time float-time time-subtract
;; Andreas Politz reports problems profiling these (Bug#4233):
- + byte-code-function-p functionp byte-code subrp
- indirect-function fboundp)
+ + byte-code-function-p functionp byte-code subrp fboundp)
"List of functions that cannot be profiled.
Those functions are used internally by the profiling code and profiling
them would thus lead to infinite recursion.")
@@ -407,11 +406,11 @@ original definition, use \\[elp-restore-function] or \\[elp-restore-all]."
(>= (aref vec1 0) (aref vec2 0)))
(defun elp-sort-by-total-time (vec1 vec2)
- "Predicate to sort by highest total time spent in function. See `sort'."
+ "Predicate to sort by highest total time spent in function. See `sort'."
(>= (aref vec1 1) (aref vec2 1)))
(defun elp-sort-by-average-time (vec1 vec2)
- "Predicate to sort by highest average time spent in function. See `sort'."
+ "Predicate to sort by highest average time spent in function. See `sort'."
(>= (aref vec1 2) (aref vec2 2)))
(defsubst elp-pack-number (number width)
diff --git a/lisp/emacs-lisp/ert-x.el b/lisp/emacs-lisp/ert-x.el
index 59ec4d24849..7fc316d1469 100644
--- a/lisp/emacs-lisp/ert-x.el
+++ b/lisp/emacs-lisp/ert-x.el
@@ -352,7 +352,6 @@ convert it to a string and pass it to COLLECTOR first."
(defvar ert-resource-directory-trim-right-regexp "\\(-tests?\\)?\\.el"
"Regexp for `string-trim' (right) used by `ert-resource-directory'.")
-;; Has to be a macro for `load-file-name'.
(defmacro ert-resource-directory ()
"Return absolute file name of the resource (test data) directory.
@@ -361,30 +360,121 @@ in the same directory as the test file this is called from.
If that directory doesn't exist, find a directory based on the
test file name. If the file is named \"foo-tests.el\", return
-the absolute file name for \"foo-resources\". If you want a
-different resource directory naming scheme, set the variable
-`ert-resource-directory-format'. Before formatting, the file
-name will be trimmed using `string-trim' with arguments
+the absolute file name for \"foo-resources\".
+
+If you want a different resource directory naming scheme, set the
+variable `ert-resource-directory-format'. Before formatting, the
+file name will be trimmed using `string-trim' with arguments
`ert-resource-directory-trim-left-regexp' and
`ert-resource-directory-trim-right-regexp'."
- `(let* ((testfile ,(or (macroexp-file-name)
- buffer-file-name))
- (default-directory (file-name-directory testfile)))
- (file-truename
- (if (file-accessible-directory-p "resources/")
- (expand-file-name "resources/")
- (expand-file-name
- (format ert-resource-directory-format
- (string-trim testfile
- ert-resource-directory-trim-left-regexp
- ert-resource-directory-trim-right-regexp)))))))
+ `(when-let ((testfile ,(or (macroexp-file-name)
+ buffer-file-name)))
+ (let ((default-directory (file-name-directory testfile)))
+ (file-truename
+ (if (file-accessible-directory-p "resources/")
+ (expand-file-name "resources/")
+ (expand-file-name
+ (format ert-resource-directory-format
+ (string-trim testfile
+ ert-resource-directory-trim-left-regexp
+ ert-resource-directory-trim-right-regexp))))))))
(defmacro ert-resource-file (file)
- "Return file name of resource file named FILE.
-A resource file is in the resource directory as per
-`ert-resource-directory'."
+ "Return absolute file name of resource (test data) file named FILE.
+A resource file is defined as any file placed in the resource
+directory as returned by `ert-resource-directory'."
`(expand-file-name ,file (ert-resource-directory)))
+(defvar ert-temp-file-prefix "emacs-test-"
+ "Prefix used by `ert-with-temp-file' and `ert-with-temp-directory'.")
+
+(defvar ert-temp-file-suffix nil
+ "Suffix used by `ert-with-temp-file' and `ert-with-temp-directory'.")
+
+(defun ert--with-temp-file-generate-suffix (filename)
+ "Generate temp file suffix from FILENAME."
+ (thread-last
+ (file-name-base filename)
+ (replace-regexp-in-string (rx string-start
+ (group (+? not-newline))
+ (regexp "-?tests?")
+ string-end)
+ "\\1")
+ (concat "-")))
+
+(defmacro ert-with-temp-file (name &rest body)
+ "Bind NAME to the name of a new temporary file and evaluate BODY.
+Delete the temporary file after BODY exits normally or
+non-locally. NAME will be bound to the file name of the temporary
+file.
+
+The following keyword arguments are supported:
+
+:prefix STRING If non-nil, pass STRING to `make-temp-file' as
+ the PREFIX argument. Otherwise, use the value of
+ `ert-temp-file-prefix'.
+
+:suffix STRING If non-nil, pass STRING to `make-temp-file' as the
+ SUFFIX argument. Otherwise, use the value of
+ `ert-temp-file-suffix'; if the value of that
+ variable is nil, generate a suffix based on the
+ name of the file that `ert-with-temp-file' is
+ called from.
+
+:text STRING If non-nil, pass STRING to `make-temp-file' as
+ the TEXT argument.
+
+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)
+ (while (keywordp (setq keyw (car body)))
+ (setq body (cdr body))
+ (pcase keyw
+ (:prefix (setq prefix (pop body)))
+ (:suffix (setq suffix (pop body)))
+ (:directory (setq directory (pop body)))
+ (:text (setq text (pop body)))
+ (_ (push keyw extra-keywords) (pop body))))
+ (when extra-keywords
+ (error "Invalid keywords: %s" (mapconcat #'symbol-name extra-keywords " ")))
+ (let ((temp-file (make-symbol "temp-file"))
+ (prefix (or prefix ert-temp-file-prefix))
+ (suffix (or suffix ert-temp-file-suffix
+ (ert--with-temp-file-generate-suffix
+ (or (macroexp-file-name) buffer-file-name)))))
+ `(let* ((,temp-file (,(if directory 'file-name-as-directory 'identity)
+ (make-temp-file ,prefix ,directory ,suffix ,text)))
+ (,name ,(if directory
+ `(file-name-as-directory ,temp-file)
+ temp-file)))
+ (unwind-protect
+ (progn ,@body)
+ (ignore-errors
+ ,(if directory
+ `(delete-directory ,temp-file :recursive)
+ `(delete-file ,temp-file))))))))
+
+(defmacro ert-with-temp-directory (name &rest body)
+ "Bind NAME to the name of a new temporary directory and evaluate BODY.
+Delete the temporary directory after BODY exits normally or
+non-locally.
+
+NAME is bound to the directory name, not the directory file
+name. (In other words, it will end with the directory delimiter;
+on Unix-like systems, it will end with \"/\".)
+
+The same keyword arguments are supported as in
+`ert-with-temp-file' (which see), except for :text."
+ (declare (indent 1) (debug (symbolp body)))
+ (let ((tail body) keyw)
+ (while (keywordp (setq keyw (car tail)))
+ (setq tail (cddr tail))
+ (pcase keyw (:text (error "Invalid keyword for directory: :text")))))
+ `(ert-with-temp-file ,name
+ :directory t
+ ,@body))
+
(provide 'ert-x)
;;; ert-x.el ends here
diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el
index 92acfe7246f..cc464a0f819 100644
--- a/lisp/emacs-lisp/ert.el
+++ b/lisp/emacs-lisp/ert.el
@@ -63,6 +63,9 @@
(require 'ewoc)
(require 'find-func)
(require 'pp)
+(require 'map)
+
+(autoload 'xml-escape-string "xml.el")
;;; UI customization options.
@@ -76,6 +79,35 @@
Use nil for no limit (caution: backtrace lines can be very long)."
:type '(choice (const :tag "No truncation" nil) integer))
+(defvar ert-batch-print-length 10
+ "`print-length' setting used in `ert-run-tests-batch'.
+
+When formatting lists in test conditions, `print-length' will be
+temporarily set to this value. See also
+`ert-batch-backtrace-line-length' for its effect on stack
+traces.")
+
+(defvar ert-batch-print-level 5
+ "`print-level' setting used in `ert-run-tests-batch'.
+
+When formatting lists in test conditions, `print-level' will be
+temporarily set to this value. See also
+`ert-batch-backtrace-line-length' for its effect on stack
+traces.")
+
+(defvar ert-batch-backtrace-line-length t
+ "Target length for lines in ERT batch backtraces.
+
+Even modest settings for `print-length' and `print-level' can
+produce extremely long lines in backtraces and lengthy delays in
+forming them. This variable governs the target maximum line
+length by manipulating these two variables while printing stack
+traces. Setting this variable to t will re-use the value of
+`backtrace-line-length' while printing stack traces in ERT batch
+mode. Any other value will be temporarily bound to
+`backtrace-line-length' when producing stack traces in batch
+mode.")
+
(defface ert-test-result-expected '((((class color) (background light))
:background "green1")
(((class color) (background dark))
@@ -88,23 +120,6 @@ Use nil for no limit (caution: backtrace lines can be very long)."
:background "red3"))
"Face used for unexpected results in the ERT results buffer.")
-
-;;; Copies/reimplementations of cl functions.
-
-(defun ert-equal-including-properties (a b)
- "Return t if A and B have similar structure and contents.
-
-This is like `equal-including-properties' except that it compares
-the property values of text properties structurally (by
-recursing) rather than with `eq'. Perhaps this is what
-`equal-including-properties' should do in the first place; see
-Emacs bug 6581 at URL `https://debbugs.gnu.org/cgi/bugreport.cgi?bug=6581'."
- ;; This implementation is inefficient. Rather than making it
- ;; efficient, let's hope bug 6581 gets fixed so that we can delete
- ;; it altogether.
- (not (ert--explain-equal-including-properties a b)))
-
-
;;; Defining and locating tests.
;; The data structure that represents a test case.
@@ -136,6 +151,10 @@ Emacs bug 6581 at URL `https://debbugs.gnu.org/cgi/bugreport.cgi?bug=6581'."
;; Note that nil is still a valid value for the `name' slot in
;; ert-test objects. It designates an anonymous test.
(error "Attempt to define a test named nil"))
+ (when (and noninteractive (get symbol 'ert--test))
+ ;; Make sure duplicated tests are discovered since the older test would
+ ;; be ignored silently otherwise.
+ (error "Test `%s' redefined" symbol))
(define-symbol-prop symbol 'ert--test definition)
definition)
@@ -191,6 +210,9 @@ Macros in BODY are expanded when the test is defined, not when it
is run. If a macro (possibly with side effects) is to be tested,
it has to be wrapped in `(eval (quote ...))'.
+If NAME is already defined as a test and Emacs is running
+in batch mode, an error is signalled.
+
\(fn NAME () [DOCSTRING] [:expected-result RESULT-TYPE] \
[:tags \\='(TAG...)] BODY...)"
(declare (debug (&define [&name "test@" symbolp]
@@ -227,7 +249,6 @@ it has to be wrapped in `(eval (quote ...))'.
"%s\\(\\s-\\|$\\)")
"The regexp the `find-function' mechanisms use for finding test definitions.")
-
(define-error 'ert-test-failed "Test failed")
(define-error 'ert-test-skipped "Test skipped")
@@ -258,7 +279,7 @@ DATA is displayed to the user and should state the reason for skipping."
;; See Bug#24402 for why this exists
(defun ert--should-signal-hook (error-symbol data)
"Stupid hack to stop `condition-case' from catching ert signals.
-It should only be stopped when ran from inside ert--run-test-internal."
+It should only be stopped when ran from inside `ert--run-test-internal'."
(when (and (not (symbolp debugger)) ; only run on anonymous debugger
(memq error-symbol '(ert-test-failed ert-test-skipped)))
(funcall debugger 'error (cons error-symbol data))))
@@ -465,7 +486,7 @@ Errors during evaluation are caught and handled like nil."
(defun ert--explain-equal-rec (a b)
"Return a programmer-readable explanation of why A and B are not `equal'.
-Returns nil if they are."
+Return nil if they are."
(if (not (eq (type-of a) (type-of b)))
`(different-types ,a ,b)
(pcase a
@@ -536,6 +557,16 @@ Returns nil if they are."
(ert--explain-equal-rec a b)))
(put 'equal 'ert-explainer 'ert--explain-equal)
+(defun ert--explain-string-equal (a b)
+ "Explainer function for `string-equal'."
+ ;; Convert if they are symbols.
+ (if (string-equal a b)
+ nil
+ (let ((as (if (symbolp a) (symbol-name a) a))
+ (bs (if (symbolp b) (symbol-name b) b)))
+ (ert--explain-equal-rec as bs))))
+(put 'string-equal 'ert-explainer 'ert--explain-string-equal)
+
(defun ert--significant-plist-keys (plist)
"Return the keys of PLIST that have non-null values, in order."
(cl-assert (zerop (mod (length plist) 2)) t)
@@ -588,14 +619,9 @@ If SUFFIXP is non-nil, returns a suffix of S, otherwise a prefix."
(t
(substring s 0 len)))))
-;; TODO(ohler): Once bug 6581 is fixed, rename this to
-;; `ert--explain-equal-including-properties-rec' and add a fast-path
-;; wrapper like `ert--explain-equal'.
-(defun ert--explain-equal-including-properties (a b)
- "Explainer function for `ert-equal-including-properties'.
-
-Returns a programmer-readable explanation of why A and B are not
-`ert-equal-including-properties', or nil if they are."
+(defun ert--explain-equal-including-properties-rec (a b)
+ "Return explanation of why A and B are not `equal-including-properties'.
+Return nil if they are."
(if (not (equal a b))
(ert--explain-equal a b)
(cl-assert (stringp a) t)
@@ -617,15 +643,17 @@ Returns a programmer-readable explanation of why A and B are not
,(ert--abbreviate-string
(substring-no-properties a (1+ i))
10 nil))))
- ;; TODO(ohler): Get `equal-including-properties' fixed in
- ;; Emacs, delete `ert-equal-including-properties', and
- ;; re-enable this assertion.
- ;;finally (cl-assert (equal-including-properties a b) t)
- )))
-(put 'ert-equal-including-properties
- 'ert-explainer
- 'ert--explain-equal-including-properties)
+ finally (cl-assert (equal-including-properties a b) t))))
+(defun ert--explain-equal-including-properties (a b)
+ "Explainer function for `equal-including-properties'."
+ ;; Do a quick comparison in C to avoid running our expensive
+ ;; comparison when possible.
+ (if (equal-including-properties a b)
+ nil
+ (ert--explain-equal-including-properties-rec a b)))
+(put 'equal-including-properties 'ert-explainer
+ 'ert--explain-equal-including-properties)
;;; Implementation of `ert-info'.
@@ -650,7 +678,6 @@ and is displayed in front of the value of MESSAGE-FORM."
,@body))
-
;;; Facilities for running a single test.
(defvar ert-debug-on-error nil
@@ -765,10 +792,15 @@ This mainly sets up debugger-related bindings."
;; handle ert errors. Once that's done, remove
;; `ert--should-signal-hook'. See Bug#24402 and Bug#11218 for
;; details.
- (let ((debugger (lambda (&rest args)
+ (let ((lexical-binding t)
+ (debugger (lambda (&rest args)
(ert--run-test-debugger test-execution-info
args)))
(debug-on-error t)
+ ;; Don't infloop if the error being called is erroring
+ ;; out, and we have `debug-on-error' bound to nil inside
+ ;; the test.
+ (backtrace-on-error-noninteractive nil)
(debug-on-quit t)
;; FIXME: Do we need to store the old binding of this
;; and consider it in `ert--run-test-debugger'?
@@ -1405,9 +1437,10 @@ Returns the stats object."
(if (getenv "EMACS_TEST_VERBOSE")
(ert-reason-for-test-result result)
""))))
- (message "%s" "")))))
- (test-started
- )
+ (message "%s" ""))
+ (when (getenv "EMACS_TEST_JUNIT_REPORT")
+ (ert-write-junit-test-report stats)))))
+ (test-started)
(test-ended
(cl-destructuring-bind (stats test result) event-args
(unless (ert-test-result-expected-p test result)
@@ -1417,8 +1450,14 @@ Returns the stats object."
(ert-test-result-with-condition
(message "Test %S backtrace:" (ert-test-name test))
(with-temp-buffer
- (insert (backtrace-to-string
- (ert-test-result-with-condition-backtrace result)))
+ (let ((backtrace-line-length
+ (if (eq ert-batch-backtrace-line-length t)
+ backtrace-line-length
+ ert-batch-backtrace-line-length))
+ (print-level ert-batch-print-level)
+ (print-length ert-batch-print-length))
+ (insert (backtrace-to-string
+ (ert-test-result-with-condition-backtrace result))))
(if (not ert-batch-backtrace-right-margin)
(message "%s"
(buffer-substring-no-properties (point-min)
@@ -1437,8 +1476,8 @@ Returns the stats object."
(ert--insert-infos result)
(insert " ")
(let ((print-escape-newlines t)
- (print-level 5)
- (print-length 10))
+ (print-level ert-batch-print-level)
+ (print-length ert-batch-print-length))
(ert--pp-with-indentation-and-newline
(ert-test-result-with-condition-condition result)))
(goto-char (1- (point-max)))
@@ -1488,6 +1527,183 @@ the tests)."
(backtrace))
(kill-emacs 2))))
+(defvar ert-load-file-name nil
+ "The name of the loaded ERT test file, a string.
+Usually, it is not needed to be defined, but if different ERT
+test packages depend on each other, it might be helpful.")
+
+(defun ert-write-junit-test-report (stats)
+ "Write a JUnit test report, generated from STATS."
+ ;; https://www.ibm.com/docs/en/developer-for-zos/14.1.0?topic=formats-junit-xml-format
+ ;; https://llg.cubic.org/docs/junit/
+ (when-let ((symbol (car (apropos-internal "" #'ert-test-boundp)))
+ (test-file (symbol-file symbol 'ert--test))
+ (test-report
+ (file-name-with-extension
+ (or ert-load-file-name test-file) "xml")))
+ (with-temp-file test-report
+ (insert "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
+ (insert (format "<testsuites name=\"%s\" tests=\"%s\" errors=\"%s\" failures=\"%s\" skipped=\"%s\" time=\"%s\">\n"
+ (file-name-nondirectory test-report)
+ (ert-stats-total stats)
+ (if (ert--stats-aborted-p stats) 1 0)
+ (ert-stats-completed-unexpected stats)
+ (ert-stats-skipped stats)
+ (float-time
+ (time-subtract
+ (ert--stats-end-time stats)
+ (ert--stats-start-time stats)))))
+ (insert (format " <testsuite id=\"0\" name=\"%s\" tests=\"%s\" errors=\"%s\" failures=\"%s\" skipped=\"%s\" time=\"%s\" timestamp=\"%s\">\n"
+ (file-name-nondirectory test-report)
+ (ert-stats-total stats)
+ (if (ert--stats-aborted-p stats) 1 0)
+ (ert-stats-completed-unexpected stats)
+ (ert-stats-skipped stats)
+ (float-time
+ (time-subtract
+ (ert--stats-end-time stats)
+ (ert--stats-start-time stats)))
+ (ert--format-time-iso8601 (ert--stats-end-time stats))))
+ ;; If the test has aborted, `ert--stats-selector' might return
+ ;; huge junk. Skip this.
+ (when (< (length (format "%s" (ert--stats-selector stats))) 1024)
+ (insert " <properties>\n"
+ (format " <property name=\"selector\" value=\"%s\"/>\n"
+ (xml-escape-string
+ (format "%s" (ert--stats-selector stats)) 'noerror))
+ " </properties>\n"))
+ (cl-loop for test across (ert--stats-tests stats)
+ for result = (ert-test-most-recent-result test) do
+ (insert (format " <testcase name=\"%s\" status=\"%s\" time=\"%s\""
+ (xml-escape-string
+ (symbol-name (ert-test-name test)) 'noerror)
+ (ert-string-for-test-result
+ result
+ (ert-test-result-expected-p test result))
+ (ert-test-result-duration result)))
+ (if (and (ert-test-result-expected-p test result)
+ (not (ert-test-aborted-with-non-local-exit-p result))
+ (not (ert-test-skipped-p result))
+ (zerop (length (ert-test-result-messages result))))
+ (insert "/>\n")
+ (insert ">\n")
+ (cond
+ ((ert-test-skipped-p result)
+ (insert (format " <skipped message=\"%s\" type=\"%s\">\n"
+ (xml-escape-string
+ (string-trim
+ (ert-reason-for-test-result result))
+ 'noerror)
+ (ert-string-for-test-result
+ result
+ (ert-test-result-expected-p
+ test result)))
+ (xml-escape-string
+ (string-trim
+ (ert-reason-for-test-result result))
+ 'noerror)
+ "\n"
+ " </skipped>\n"))
+ ((ert-test-aborted-with-non-local-exit-p result)
+ (insert (format " <error message=\"%s\" type=\"%s\">\n"
+ (file-name-nondirectory test-report)
+ (ert-string-for-test-result
+ result
+ (ert-test-result-expected-p
+ test result)))
+ (format "Test %s aborted with non-local exit\n"
+ (xml-escape-string
+ (symbol-name (ert-test-name test)) 'noerror))
+ " </error>\n"))
+ ((not (ert-test-result-type-p
+ result (ert-test-expected-result-type test)))
+ (insert (format " <failure message=\"%s\" type=\"%s\">\n"
+ (xml-escape-string
+ (string-trim
+ (ert-reason-for-test-result result))
+ 'noerror)
+ (ert-string-for-test-result
+ result
+ (ert-test-result-expected-p
+ test result)))
+ (xml-escape-string
+ (string-trim
+ (ert-reason-for-test-result result))
+ 'noerror)
+ "\n"
+ " </failure>\n")))
+ (unless (zerop (length (ert-test-result-messages result)))
+ (insert " <system-out>\n"
+ (xml-escape-string
+ (ert-test-result-messages result) 'noerror)
+ " </system-out>\n"))
+ (insert " </testcase>\n")))
+ (insert " </testsuite>\n")
+ (insert "</testsuites>\n"))))
+
+(defun ert-write-junit-test-summary-report (&rest logfiles)
+ "Write a JUnit summary test report, generated from LOGFILES."
+ (let ((report (file-name-with-extension
+ (getenv "EMACS_TEST_JUNIT_REPORT") "xml"))
+ (tests 0) (errors 0) (failures 0) (skipped 0) (time 0) (id 0))
+ (with-temp-file report
+ (dolist (logfile logfiles)
+ (let ((test-report (file-name-with-extension logfile "xml")))
+ (if (not (file-readable-p test-report))
+ (let* ((logfile (file-name-with-extension logfile "log"))
+ (logfile-contents
+ (when (file-readable-p logfile)
+ (with-temp-buffer
+ (insert-file-contents-literally logfile)
+ (buffer-string)))))
+ (unless
+ ;; No defined tests, perhaps a helper file.
+ (and logfile-contents
+ (string-match-p "^Running 0 tests" logfile-contents))
+ (insert (format " <testsuite id=\"%s\" name=\"%s\" tests=\"1\" errors=\"1\" failures=\"0\" skipped=\"0\" time=\"0\" timestamp=\"%s\">\n"
+ id test-report
+ (ert--format-time-iso8601 (current-time))))
+ (insert (format " <testcase name=\"Test report missing %s\" status=\"error\" time=\"0\">\n"
+ (file-name-nondirectory test-report)))
+ (insert (format " <error message=\"Test report missing %s\" type=\"error\">\n"
+ (file-name-nondirectory test-report)))
+ (when logfile-contents
+ (insert (xml-escape-string logfile-contents 'noerror)))
+ (insert " </error>\n"
+ " </testcase>\n"
+ " </testsuite>\n")
+ (cl-incf errors 1)
+ (cl-incf id 1)))
+
+ (insert-file-contents-literally test-report)
+ (when (looking-at-p
+ (regexp-quote "<?xml version=\"1.0\" encoding=\"utf-8\"?>"))
+ (delete-region (point) (line-beginning-position 2)))
+ (when (looking-at
+ "<testsuites name=\".+\" tests=\"\\(.+\\)\" errors=\"\\(.+\\)\" failures=\"\\(.+\\)\" skipped=\"\\(.+\\)\" time=\"\\(.+\\)\">")
+ (cl-incf tests (string-to-number (match-string 1)))
+ (cl-incf errors (string-to-number (match-string 2)))
+ (cl-incf failures (string-to-number (match-string 3)))
+ (cl-incf skipped (string-to-number (match-string 4)))
+ (cl-incf time (string-to-number (match-string 5)))
+ (delete-region (point) (line-beginning-position 2)))
+ (when (looking-at " <testsuite id=\"\\(0\\)\"")
+ (replace-match (number-to-string id) nil nil nil 1)
+ (cl-incf id 1))
+ (goto-char (point-max))
+ (beginning-of-line 0)
+ (when (looking-at-p "</testsuites>")
+ (delete-region (point) (line-beginning-position 2))))
+
+ (narrow-to-region (point-max) (point-max))))
+
+ (insert "</testsuites>\n")
+ (widen)
+ (goto-char (point-min))
+ (insert "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
+ (insert (format "<testsuites name=\"%s\" tests=\"%s\" errors=\"%s\" failures=\"%s\" skipped=\"%s\" time=\"%s\">\n"
+ (file-name-nondirectory report)
+ tests errors failures skipped time)))))
(defun ert-summarize-tests-batch-and-exit (&optional high)
"Summarize the results of testing.
@@ -1503,6 +1719,8 @@ If HIGH is a natural number, the HIGH long lasting tests are summarized."
;; behavior.
(setq attempt-stack-overflow-recovery nil
attempt-orderly-shutdown-on-fatal-signal nil)
+ (when (getenv "EMACS_TEST_JUNIT_REPORT")
+ (apply #'ert-write-junit-test-summary-report command-line-args-left))
(let ((nlogs (length command-line-args-left))
(ntests 0) (nrun 0) (nexpected 0) (nunexpected 0) (nskipped 0)
nnotrun logfile notests badtests unexpected skipped tests)
@@ -1818,7 +2036,6 @@ Also sets `ert--results-progress-bar-button-begin'."
;; should test it again.)
"\n")))
-
(defvar ert-test-run-redisplay-interval-secs .1
"How many seconds ERT should wait between redisplays while running tests.
@@ -1958,21 +2175,21 @@ non-nil, returns the face for expected results.."
nil)
(defun ert--results-font-lock-function (enabledp)
- "Redraw the ERT results buffer after font-lock-mode was switched on or off.
+ "Redraw the ERT results buffer after `font-lock-mode' was switched on or off.
-ENABLEDP is true if font-lock-mode is switched on, false
+ENABLEDP is true if `font-lock-mode' is switched on, false
otherwise."
(ert--results-update-ewoc-hf ert--results-ewoc ert--results-stats)
(ewoc-refresh ert--results-ewoc)
(font-lock-default-function enabledp))
-(defun ert--setup-results-buffer (stats listener buffer-name)
+(defvar ert--output-buffer-name "*ert*")
+
+(defun ert--setup-results-buffer (stats listener)
"Set up a test results buffer.
-STATS is the stats object; LISTENER is the results listener;
-BUFFER-NAME, if non-nil, is the buffer name to use."
- (unless buffer-name (setq buffer-name "*ert*"))
- (let ((buffer (get-buffer-create buffer-name)))
+STATS is the stats object; LISTENER is the results listener."
+ (let ((buffer (get-buffer-create ert--output-buffer-name)))
(with-current-buffer buffer
(let ((inhibit-read-only t))
(buffer-disable-undo)
@@ -2000,22 +2217,14 @@ BUFFER-NAME, if non-nil, is the buffer name to use."
(goto-char (1- (point-max)))
buffer)))))
-
(defvar ert--selector-history nil
"List of recent test selectors read from terminal.")
-;; Should OUTPUT-BUFFER-NAME and MESSAGE-FN really be arguments here?
-;; They are needed only for our automated self-tests at the moment.
-;; Or should there be some other mechanism?
;;;###autoload
-(defun ert-run-tests-interactively (selector
- &optional output-buffer-name message-fn)
+(defun ert-run-tests-interactively (selector)
"Run the tests specified by SELECTOR and display the results in a buffer.
-SELECTOR works as described in `ert-select-tests'.
-OUTPUT-BUFFER-NAME and MESSAGE-FN should normally be nil; they
-are used for automated self-tests and specify which buffer to use
-and how to display message."
+SELECTOR works as described in `ert-select-tests'."
(interactive
(list (let ((default (if ert--selector-history
;; Can't use `first' here as this form is
@@ -2026,25 +2235,18 @@ and how to display message."
(read
(completing-read (format-prompt "Run tests" default)
obarray #'ert-test-boundp nil nil
- 'ert--selector-history default nil)))
- nil))
- (unless message-fn (setq message-fn 'message))
- (let ((output-buffer-name output-buffer-name)
- buffer
- listener
- (message-fn message-fn))
+ 'ert--selector-history default nil)))))
+ (let (buffer listener)
(setq listener
(lambda (event-type &rest event-args)
(cl-ecase event-type
(run-started
(cl-destructuring-bind (stats) event-args
- (setq buffer (ert--setup-results-buffer stats
- listener
- output-buffer-name))
+ (setq buffer (ert--setup-results-buffer stats listener))
(pop-to-buffer buffer)))
(run-ended
(cl-destructuring-bind (stats abortedp) event-args
- (funcall message-fn
+ (message
"%sRan %s tests, %s results were as expected%s%s"
(if (not abortedp)
""
@@ -2398,7 +2600,7 @@ To be used in the ERT results buffer."
(interactive nil ert-results-mode)
(cl-assert (eql major-mode 'ert-results-mode))
(let ((selector (ert--stats-selector ert--results-stats)))
- (ert-run-tests-interactively selector (buffer-name))))
+ (ert-run-tests-interactively selector)))
(defun ert-results-rerun-test-at-point ()
"Re-run the test at point.
@@ -2647,9 +2849,135 @@ To be used in the ERT results buffer."
'ert--activate-font-lock-keywords)
nil)
+(defun ert-test-erts-file (file &optional transform)
+ "Parse FILE as a file containing before/after parts.
+TRANSFORM will be called to get from before to after."
+ (with-temp-buffer
+ (insert-file-contents file)
+ (let ((gen-specs (list (cons 'dummy t)
+ (cons 'code transform))))
+ ;; Find the start of a test.
+ (while (re-search-forward "^=-=\n" nil t)
+ (setq gen-specs (ert-test--erts-test gen-specs file))
+ ;; Search to the end of the test.
+ (re-search-forward "^=-=-=\n")))))
+
+(defun ert-test--erts-test (gen-specs file)
+ (let* ((file-buffer (current-buffer))
+ (specs (ert--erts-specifications (match-beginning 0)))
+ (name (cdr (assq 'name specs)))
+ (start-before (point))
+ (end-after (if (re-search-forward "^=-=-=\n" nil t)
+ (match-beginning 0)
+ (point-max)))
+ (skip (cdr (assq 'skip specs)))
+ end-before start-after
+ after after-point)
+ (unless name
+ (error "No name for test case"))
+ (if (and skip
+ (eval (car (read-from-string skip))))
+ ;; Skipping this test.
+ ()
+ ;; Do the test.
+ (goto-char end-after)
+ ;; We have a separate after section.
+ (if (re-search-backward "^=-=\n" start-before t)
+ (setq end-before (match-beginning 0)
+ start-after (match-end 0))
+ (setq end-before end-after
+ start-after start-before))
+ ;; Update persistent specs.
+ (when-let ((point-char (assq 'point-char specs)))
+ (setq gen-specs
+ (map-insert gen-specs 'point-char (cdr point-char))))
+ (when-let ((code (cdr (assq 'code specs))))
+ (setq gen-specs
+ (map-insert gen-specs 'code (car (read-from-string code)))))
+ ;; Get the "after" strings.
+ (with-temp-buffer
+ (insert-buffer-substring file-buffer start-after end-after)
+ (ert--erts-unquote)
+ ;; Remove the newline at the end of the buffer.
+ (when-let ((no-newline (cdr (assq 'no-after-newline specs))))
+ (goto-char (point-min))
+ (when (re-search-forward "\n\\'" nil t)
+ (delete-region (match-beginning 0) (match-end 0))))
+ ;; Get the expected "after" point.
+ (when-let ((point-char (cdr (assq 'point-char gen-specs))))
+ (goto-char (point-min))
+ (when (search-forward point-char nil t)
+ (delete-region (match-beginning 0) (match-end 0))
+ (setq after-point (point))))
+ (setq after (buffer-string)))
+ ;; Do the test.
+ (with-temp-buffer
+ (insert-buffer-substring file-buffer start-before end-before)
+ (ert--erts-unquote)
+ ;; Remove the newline at the end of the buffer.
+ (when-let ((no-newline (cdr (assq 'no-before-newline specs))))
+ (goto-char (point-min))
+ (when (re-search-forward "\n\\'" nil t)
+ (delete-region (match-beginning 0) (match-end 0))))
+ (goto-char (point-min))
+ ;; Place point in the specified place.
+ (when-let ((point-char (cdr (assq 'point-char gen-specs))))
+ (when (search-forward point-char nil t)
+ (delete-region (match-beginning 0) (match-end 0))))
+ (let ((code (cdr (assq 'code gen-specs))))
+ (unless code
+ (error "No code to run the transform"))
+ (funcall code))
+ (unless (equal (buffer-string) after)
+ (ert-fail (list (format "Mismatch in test \"%s\", file %s"
+ name file)
+ (buffer-string)
+ after)))
+ (when (and after-point
+ (not (= after-point (point))))
+ (ert-fail (list (format "Point wrong in test \"%s\", expected point %d, actual %d, file %s"
+ name
+ after-point (point)
+ file)
+ (buffer-string)))))))
+ ;; Return the new value of the general specifications.
+ gen-specs)
+
+(defun ert--erts-unquote ()
+ (goto-char (point-min))
+ (while (re-search-forward "^\\=-=\\(-=\\)$" nil t)
+ (delete-region (match-beginning 0) (1+ (match-beginning 0)))))
+
+(defun ert--erts-specifications (end)
+ "Find specifications before point (back to the previous test)."
+ (save-excursion
+ (goto-char end)
+ (goto-char
+ (if (re-search-backward "^=-=-=\n" nil t)
+ (match-end 0)
+ (point-min)))
+ (let ((specs nil))
+ (while (< (point) end)
+ (if (looking-at "\\([^ \n\t:]+\\):\\([ \t]+\\)?\\(.*\\)")
+ (let ((name (intern (downcase (match-string 1))))
+ (value (match-string 3)))
+ (forward-line 1)
+ (while (looking-at "[ \t]+\\(.*\\)")
+ (setq value (concat value (match-string 1)))
+ (forward-line 1))
+ (push (cons name (substring-no-properties value)) specs))
+ (forward-line 1)))
+ (nreverse specs))))
+
(defvar ert-unload-hook ())
(add-hook 'ert-unload-hook #'ert--unload-function)
+;;; Obsolete
+
+(define-obsolete-function-alias 'ert-equal-including-properties
+ #'equal-including-properties "29.1")
+(put 'ert-equal-including-properties 'ert-explainer
+ 'ert--explain-equal-including-properties)
(provide 'ert)
diff --git a/lisp/emacs-lisp/ewoc.el b/lisp/emacs-lisp/ewoc.el
index d3ace97945f..8636dc92a1c 100644
--- a/lisp/emacs-lisp/ewoc.el
+++ b/lisp/emacs-lisp/ewoc.el
@@ -49,13 +49,13 @@
;;
;; Ewoc is a package that implements a connection between an
;; dll (a doubly linked list) and the contents of a buffer.
-;; Possible uses are dired (have all files in a list, and show them),
+;; Possible uses are Dired (have all files in a list, and show them),
;; buffer-list, kom-prioritize (in the LysKOM elisp client) and
;; others. pcl-cvs.el and vc.el use ewoc.el.
;;
;; Ewoc can be considered as the `view' part of a model-view-controller.
;;
-;; A `element' can be any lisp object. When you use the ewoc
+;; An `element' can be any Lisp object. When you use the ewoc
;; package you specify a pretty-printer, a function that inserts
;; a printable representation of the element in the buffer. (The
;; pretty-printer should use "insert" and not
@@ -67,7 +67,7 @@
;; fixed when the ewoc is created). The header and the footer
;; are constant strings. They appear before and after the elements.
;;
-;; Ewoc does not affect the mode of the buffer in any way. It
+;; Ewoc does not affect the mode of the buffer in any way. It
;; merely makes it easy to connect an underlying data representation
;; to the buffer contents.
;;
@@ -117,7 +117,7 @@
(unless (eq dll L) L)))
(defun ewoc--node-nth (dll n)
- "Return the Nth node from the doubly linked list `dll'.
+ "Return the Nth node from the doubly linked list DLL.
N counts from zero. If N is negative, return the -(N+1)th last element.
If N is out of range, return nil.
Thus, (ewoc--node-nth dll 0) returns the first node,
@@ -147,7 +147,7 @@ and (ewoc--node-nth dll -1) returns the last node."
buffer pretty-printer header footer dll last-node hf-pp)
(defmacro ewoc--set-buffer-bind-dll-let* (ewoc varlist &rest forms)
- "Execute FORMS with ewoc--buffer selected as current buffer,
+ "Execute FORMS with `ewoc--buffer' selected as current buffer,
`dll' bound to the dll, and VARLIST bound as in a let*.
`dll' will be bound when VARLIST is initialized, but
the current buffer will *not* have been changed.
@@ -381,7 +381,7 @@ arguments will be passed to MAP-FUNCTION."
(defun ewoc-filter (ewoc predicate &rest args)
"Remove all elements in EWOC for which PREDICATE returns nil.
-Note that the buffer for EWOC will be current-buffer when PREDICATE
+Note that the buffer for EWOC will be the current buffer when PREDICATE
is called. PREDICATE must restore the current buffer before it returns
if it changes it.
The PREDICATE is called with the element as its first argument. If any
diff --git a/lisp/emacs-lisp/faceup.el b/lisp/emacs-lisp/faceup.el
index 162c39634ed..629029aabc5 100644
--- a/lisp/emacs-lisp/faceup.el
+++ b/lisp/emacs-lisp/faceup.el
@@ -795,7 +795,7 @@ See `faceup-properties' for a list of tracked properties."
nil
(if (and (null pos)
(faceup-has-any-text-property (point-min)))
- ;; `pos' is `nil' and the character at `point-min' contains a
+ ;; `pos' is nil and the character at `point-min' contains a
;; tracked property, return `point-min'.
(point-min)
(unless pos
diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el
index 7bc3e6b25ff..303039d6534 100644
--- a/lisp/emacs-lisp/find-func.el
+++ b/lisp/emacs-lisp/find-func.el
@@ -145,13 +145,16 @@ in which case the function is called with one argument (the object
we're looking for) and it should search for it.")
(put 'find-function-regexp-alist 'risky-local-variable t)
-(defcustom find-function-source-path nil
- "The default list of directories where `find-function' searches.
+(define-obsolete-variable-alias 'find-function-source-path
+ 'find-library-source-path "28.1")
+(defcustom find-library-source-path nil
+ "The default list of directories where `find-library' searches.
-If this variable is nil then `find-function' searches `load-path' by
+If this variable is nil then `find-library' searches `load-path' by
default."
:type '(repeat directory)
- :group 'find-function)
+ :group 'find-function
+ :version "28.1")
(defcustom find-function-recenter-line 1
"The window line-number from which to start displaying a symbol definition.
@@ -200,20 +203,20 @@ LIBRARY should be a string (the name of the library)."
(setq library (gethash (file-name-nondirectory library) comp-eln-to-el-h))))
(or
(locate-file library
- (or find-function-source-path load-path)
+ (or find-library-source-path load-path)
(find-library-suffixes))
(locate-file library
- (or find-function-source-path load-path)
+ (or find-library-source-path load-path)
load-file-rep-suffixes)
(when (file-name-absolute-p library)
(let ((rel (find-library--load-name library)))
(when rel
(or
(locate-file rel
- (or find-function-source-path load-path)
+ (or find-library-source-path load-path)
(find-library-suffixes))
(locate-file rel
- (or find-function-source-path load-path)
+ (or find-library-source-path load-path)
load-file-rep-suffixes)))))
(find-library--from-load-history library)
(signal 'file-error (list "Can't find library" library))))
@@ -286,7 +289,10 @@ TYPE should be nil to find a function, or `defvar' to find a variable."
(defun find-library (library)
"Find the Emacs Lisp source of LIBRARY.
-Interactively, prompt for LIBRARY using the one at or near point."
+Interactively, prompt for LIBRARY using the one at or near point.
+
+This function searches `find-library-source-path' if non-nil, and
+`load-path' otherwise."
(interactive (list (read-library-name)))
(prog1
(switch-to-buffer (find-file-noselect (find-library-name library)))
@@ -297,9 +303,9 @@ Interactively, prompt for LIBRARY using the one at or near point."
"Read and return a library name, defaulting to the one near point.
A library name is the filename of an Emacs Lisp library located
-in a directory under `load-path' (or `find-function-source-path',
+in a directory under `load-path' (or `find-library-source-path',
if non-nil)."
- (let* ((dirs (or find-function-source-path load-path))
+ (let* ((dirs (or find-library-source-path load-path))
(suffixes (find-library-suffixes))
(table (apply-partially 'locate-file-completion-table
dirs suffixes))
@@ -521,11 +527,7 @@ the buffer, returns (BUFFER).
If FUNCTION is a built-in function, this function normally
attempts to find it in the Emacs C sources; however, if LISP-ONLY
-is non-nil, signal an error instead.
-
-If the file where FUNCTION is defined is not known, then it is
-searched for in `find-function-source-path' if non-nil, otherwise
-in `load-path'."
+is non-nil, signal an error instead."
(if (not function)
(error "You didn't specify a function"))
(let ((func-lib (find-function-library function lisp-only t)))
@@ -589,8 +591,6 @@ near point (selected by `function-called-at-point') in a buffer and
places point before the definition.
Set mark before moving, if the buffer already existed.
-The library where FUNCTION is defined is searched for in
-`find-function-source-path', if non-nil, otherwise in `load-path'.
See also `find-function-recenter-line' and `find-function-after-hook'."
(interactive (find-function-read))
(find-function-do-it function nil 'switch-to-buffer))
@@ -617,10 +617,7 @@ See `find-function' for more details."
Finds the library containing the definition of VARIABLE in a buffer and
the point of the definition. The buffer is not selected.
-If the variable's definition can't be found in the buffer, return (BUFFER).
-
-The library where VARIABLE is defined is searched for in FILE or
-`find-function-source-path', if non-nil, otherwise in `load-path'."
+If the variable's definition can't be found in the buffer, return (BUFFER)."
(if (not variable)
(error "You didn't specify a variable")
(let ((library (or file
@@ -638,8 +635,6 @@ places point before the definition.
Set mark before moving, if the buffer already existed.
-The library where VARIABLE is defined is searched for in
-`find-function-source-path', if non-nil, otherwise in `load-path'.
See also `find-function-recenter-line' and `find-function-after-hook'."
(interactive (find-function-read 'defvar))
(find-function-do-it variable 'defvar 'switch-to-buffer))
@@ -666,10 +661,7 @@ See `find-variable' for more details."
If the definition can't be found in the buffer, return (BUFFER).
TYPE says what type of definition: nil for a function, `defvar' for a
variable, `defface' for a face. This function does not switch to the
-buffer nor display it.
-
-The library where SYMBOL is defined is searched for in FILE or
-`find-function-source-path', if non-nil, otherwise in `load-path'."
+buffer nor display it."
(cond
((not symbol)
(error "You didn't specify a symbol"))
@@ -693,8 +685,6 @@ places point before the definition.
Set mark before moving, if the buffer already existed.
-The library where FACE is defined is searched for in
-`find-function-source-path', if non-nil, otherwise in `load-path'.
See also `find-function-recenter-line' and `find-function-after-hook'."
(interactive (find-function-read 'defface))
(find-function-do-it face 'defface 'switch-to-buffer))
@@ -765,7 +755,7 @@ See `find-function-on-key'."
;;;###autoload
(defun find-function-setup-keys ()
- "Define some key bindings for the find-function family of functions."
+ "Define some key bindings for the `find-function' family of functions."
(define-key ctl-x-map "F" 'find-function)
(define-key ctl-x-4-map "F" 'find-function-other-window)
(define-key ctl-x-5-map "F" 'find-function-other-frame)
diff --git a/lisp/emacs-lisp/generator.el b/lisp/emacs-lisp/generator.el
index 4ae20ba4205..ac1412704b0 100644
--- a/lisp/emacs-lisp/generator.el
+++ b/lisp/emacs-lisp/generator.el
@@ -143,8 +143,7 @@ the CPS state machinery."
(setf ,static-var ,dynamic-var)))))
(defmacro cps--with-dynamic-binding (dynamic-var static-var &rest body)
- "Evaluate BODY such that generated atomic evaluations run with
-DYNAMIC-VAR bound to STATIC-VAR."
+ "Run BODY's atomic evaluations run with DYNAMIC-VAR bound to STATIC-VAR."
(declare (indent 2))
`(cps--with-value-wrapper
(cps--make-dynamic-binding-wrapper ,dynamic-var ,static-var)
@@ -291,22 +290,28 @@ DYNAMIC-VAR bound to STATIC-VAR."
(cps--transform-1 `(progn ,@rest)
next-state)))
- ;; Process `let' in a helper function that transforms it into a
- ;; let* with temporaries.
+ (`(,(or 'let 'let*) () . ,body)
+ (cps--transform-1 `(progn ,@body) next-state))
+
+ ;; Transform multi-variable `let' into `let*':
+ ;; (let ((v1 e1) ... (vN eN)) BODY)
+ ;; -> (let* ((t1 e1) ... (tN-1 eN-1) (vN eN) (v1 t1) (vN-1 tN-1)) BODY)
(`(let ,bindings . ,body)
(let* ((bindings (cl-loop for binding in bindings
collect (if (symbolp binding)
(list binding nil)
binding)))
- (temps (cl-loop for (var _value-form) in bindings
+ (butlast-bindings (butlast bindings))
+ (temps (cl-loop for (var _value-form) in butlast-bindings
collect (cps--add-binding var))))
(cps--transform-1
`(let* ,(append
- (cl-loop for (_var value-form) in bindings
+ (cl-loop for (_var value-form) in butlast-bindings
for temp in temps
collect (list temp value-form))
- (cl-loop for (var _binding) in bindings
+ (last bindings)
+ (cl-loop for (var _binding) in butlast-bindings
for temp in temps
collect (list var temp)))
,@body)
@@ -315,9 +320,6 @@ DYNAMIC-VAR bound to STATIC-VAR."
;; Process `let*' binding: process one binding at a time. Flatten
;; lexical bindings.
- (`(let* () . ,body)
- (cps--transform-1 `(progn ,@body) next-state))
-
(`(let* (,binding . ,more-bindings) . ,body)
(let* ((var (if (symbolp binding) binding (car binding)))
(value-form (car (cdr-safe binding)))
@@ -467,7 +469,7 @@ DYNAMIC-VAR bound to STATIC-VAR."
(guard (cps--special-form-p name))
(guard (not (memq name cps-standard-special-forms))))
name ; Shut up byte compiler
- (error "special form %S incorrect or not supported" form))
+ (error "Special form %S incorrect or not supported" form))
;; Process regular function applications with nontrivial
;; parameters, converting them to applications of trivial
@@ -633,7 +635,7 @@ modified copy."
;; If we're exiting non-locally (error, quit,
;; etc.) close the iterator.
,(cps--make-close-iterator-form terminal-state)))))
- (t (error "unknown iterator operation %S" op))))))
+ (t (error "Unknown iterator operation %S" op))))))
,(when finalizer-symbol
'(funcall iterator
:stash-finalizer
@@ -642,12 +644,11 @@ modified copy."
(iter-close iterator)))))
iterator))))
-(defun iter-yield (value)
+(defun iter-yield (_value)
"When used inside a generator, yield control to caller.
The caller of `iter-next' receives VALUE, and the next call to
`iter-next' resumes execution with the form immediately following this
`iter-yield' call."
- (identity value)
(error "`iter-yield' used outside a generator"))
(defmacro iter-yield-from (value)
@@ -668,7 +669,7 @@ sub-iterator function returns via `iter-end-of-sequence'."
(iter-close ,valsym)))))
(defmacro iter-defun (name arglist &rest body)
- "Creates a generator NAME.
+ "Create a generator NAME that accepts ARGLIST as its arguments.
When called as a function, NAME returns an iterator value that
encapsulates the state of a computation that produces a sequence
of values. Callers can retrieve each value using `iter-next'."
@@ -711,7 +712,7 @@ iterator cannot supply more values."
(defun iter-close (iterator)
"Terminate an iterator early.
-Run any unwind-protect handlers in scope at the point ITERATOR
+Run any `unwind-protect' handlers in scope at the point ITERATOR
is blocked."
(funcall iterator :close nil))
diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el
index d6272a52469..ebcc63cc2a5 100644
--- a/lisp/emacs-lisp/gv.el
+++ b/lisp/emacs-lisp/gv.el
@@ -74,7 +74,7 @@
;; (defvar gv--macro-environment nil
;; "Macro expanders for generalized variables.")
-(define-error 'gv-invalid-place "%S is not a valid place expression")
+(define-error 'gv-invalid-place "Invalid place expression")
;;;###autoload
(defun gv-get (place do)
diff --git a/lisp/emacs-lisp/hierarchy.el b/lisp/emacs-lisp/hierarchy.el
index 7466fc85df1..58234852a00 100644
--- a/lisp/emacs-lisp/hierarchy.el
+++ b/lisp/emacs-lisp/hierarchy.el
@@ -1,4 +1,4 @@
-;;; hierarchy.el --- Library to create and display hierarchy structures -*- lexical-binding: t; -*-
+;;; hierarchy.el --- Library to create and display hierarchical structures -*- lexical-binding: t; -*-
;; Copyright (C) 2020-2021 Free Software Foundation, Inc.
@@ -22,7 +22,8 @@
;;; Commentary:
-;; Library to create, query, navigate and display hierarchy structures.
+;; Library to create, query, navigate and display hierarchical
+;; structures.
;; Creation: After having created a hierarchy with `hierarchy-new',
;; populate it by calling `hierarchy-add-tree' or
diff --git a/lisp/emacs-lisp/let-alist.el b/lisp/emacs-lisp/let-alist.el
index 433b37d7923..2d634b7b037 100644
--- a/lisp/emacs-lisp/let-alist.el
+++ b/lisp/emacs-lisp/let-alist.el
@@ -57,7 +57,7 @@
;; .site.contents))
;;
;; If you nest `let-alist' invocations, the inner one can't access
-;; the variables of the outer one. You can, however, access alists
+;; the variables of the outer one. You can, however, access alists
;; inside the original alist by using dots inside the symbol, as
;; displayed in the example above by the `.site.contents'.
;;
@@ -137,7 +137,7 @@ essentially expands to
.site.contents))
If you nest `let-alist' invocations, the inner one can't access
-the variables of the outer one. You can, however, access alists
+the variables of the outer one. You can, however, access alists
inside the original alist by using dots inside the symbol, as
displayed in the example above."
(declare (indent 1) (debug t))
diff --git a/lisp/emacs-lisp/lisp-mnt.el b/lisp/emacs-lisp/lisp-mnt.el
index df14a5cd499..96ac054a7d7 100644
--- a/lisp/emacs-lisp/lisp-mnt.el
+++ b/lisp/emacs-lisp/lisp-mnt.el
@@ -498,13 +498,14 @@ absent, return nil."
"" (buffer-substring-no-properties
start (lm-commentary-end))))))))
-(defun lm-homepage (&optional file)
- "Return the homepage in file FILE, or current buffer if FILE is nil."
+(defun lm-website (&optional file)
+ "Return the website in file FILE, or current buffer if FILE is nil."
(let ((page (lm-with-file file
- (lm-header "\\(?:x-\\)?\\(?:homepage\\|url\\)"))))
- (if (and page (string-match "^<.+>$" page))
- (substring page 1 -1)
+ (lm-header (rx (? "x-") (or "url" "homepage"))))))
+ (if (and page (string-match (rx bol "<" (+ nonl) ">" eol) page))
+ (substring page 1 -1)
page)))
+(defalias 'lm-homepage 'lm-website) ; for backwards-compatibility
;;; Verification and synopses
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index 51fb88502ab..416d64558d9 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -29,6 +29,7 @@
;;; Code:
(eval-when-compile (require 'cl-lib))
+(eval-when-compile (require 'subr-x))
(defvar font-lock-comment-face)
(defvar font-lock-doc-face)
@@ -462,8 +463,8 @@ This will generate compile-time constants from BINDINGS."
;; Ineffective backslashes (typically in need of doubling).
("\\(\\\\\\)\\([^\"\\]\\)"
(1 (elisp--font-lock-backslash) prepend))
- ;; Words inside ‘’ and `' tend to be symbol names.
- (,(concat "[`‘]\\(" lisp-mode-symbol-regexp "\\)['’]")
+ ;; Words inside ‘’, '' and `' tend to be symbol names.
+ (,(concat "[`‘']\\(" lisp-mode-symbol-regexp "\\)['’]")
(1 font-lock-constant-face prepend))
;; Constant values.
(,(concat "\\_<:" lisp-mode-symbol-regexp "\\_>")
@@ -556,7 +557,7 @@ This will generate compile-time constants from BINDINGS."
"Gaudy highlighting from Emacs Lisp mode used in Backtrace mode.")
(defun lisp-string-in-doc-position-p (listbeg startpos)
- "Return true if a doc string may occur at STARTPOS inside a list.
+ "Return non-nil if a doc string may occur at STARTPOS inside a list.
LISTBEG is the position of the start of the innermost list
containing STARTPOS."
(let* ((firstsym (and listbeg
@@ -589,7 +590,9 @@ containing STARTPOS."
(= (point) startpos))))))
(defun lisp-string-after-doc-keyword-p (listbeg startpos)
- "Return true if `:documentation' symbol ends at STARTPOS inside a list.
+ "Return non-nil if `:documentation' symbol ends at STARTPOS inside a list.
+`:doc' can also be used.
+
LISTBEG is the position of the start of the innermost list
containing STARTPOS."
(and listbeg ; We are inside a Lisp form.
@@ -597,7 +600,7 @@ containing STARTPOS."
(goto-char startpos)
(ignore-errors
(progn (backward-sexp 1)
- (looking-at ":documentation\\_>"))))))
+ (looking-at ":documentation\\_>\\|:doc\\_>"))))))
(defun lisp-font-lock-syntactic-face-function (state)
"Return syntactic face function for the position represented by STATE.
@@ -624,10 +627,10 @@ Value for `adaptive-fill-function'."
(if (looking-at "\\s-+\"[^\n\"]+\"\\s-*$") ""))
;; Maybe this should be discouraged/obsoleted and users should be
-;; encouraged to use `lisp-data-mode` instead.
+;; encouraged to use 'lisp-data-mode' instead.
(defun lisp-mode-variables (&optional lisp-syntax keywords-case-insensitive
elisp)
- "Common initialization routine for lisp modes.
+ "Common initialization routine for Lisp modes.
The LISP-SYNTAX argument is used by code in inf-lisp.el and is
\(uselessly) passed from pp.el, chistory.el, gnus-kill.el and
score-mode.el. KEYWORDS-CASE-INSENSITIVE non-nil means that for
@@ -824,7 +827,7 @@ function is `common-lisp-indent-function'."
"Return Parse-Partial-Sexp State at POS, defaulting to point.
Like `syntax-ppss' but includes the character address of the last
complete sexp in the innermost containing list at position
-2 (counting from 0). This is important for lisp indentation."
+2 (counting from 0). This is important for Lisp indentation."
(unless pos (setq pos (point)))
(let ((pss (syntax-ppss pos)))
(if (nth 9 pss)
@@ -1075,10 +1078,11 @@ is the buffer position of the start of the containing expression."
;; Handle prefix characters and whitespace
;; following an open paren. (Bug#1012)
(backward-prefix-chars)
- (while (not (or (looking-back "^[ \t]*\\|([ \t]+"
- (line-beginning-position))
- (and containing-sexp
- (>= (1+ containing-sexp) (point)))))
+ (while (not (save-excursion
+ (skip-chars-backward " \t")
+ (or (= (point) (line-beginning-position))
+ (and containing-sexp
+ (= (point) (1+ containing-sexp))))))
(forward-sexp -1)
(backward-prefix-chars))
(setq calculate-lisp-indent-last-sexp (point)))
@@ -1105,6 +1109,53 @@ is the buffer position of the start of the containing expression."
(t
normal-indent))))))
+(defun lisp--local-defform-body-p (state)
+ "Return non-nil when at local definition body according to STATE.
+STATE is the `parse-partial-sexp' state for current position."
+ (when-let ((start-of-innermost-containing-list (nth 1 state)))
+ (let* ((parents (nth 9 state))
+ (first-cons-after (cdr parents))
+ (second-cons-after (cdr first-cons-after))
+ first-order-parent second-order-parent)
+ (while second-cons-after
+ (when (= start-of-innermost-containing-list
+ (car second-cons-after))
+ (setq second-order-parent (pop parents)
+ first-order-parent (pop parents)
+ ;; Leave the loop.
+ second-cons-after nil))
+ (pop second-cons-after)
+ (pop parents))
+ (when second-order-parent
+ (let (local-definitions-starting-point)
+ (and (save-excursion
+ (goto-char (1+ second-order-parent))
+ (when-let ((head (ignore-errors
+ ;; FIXME: This does not distinguish
+ ;; between reading nil and a read error.
+ ;; We don't care but still, better fix this.
+ (read (current-buffer)))))
+ (when (memq head '( cl-flet cl-labels cl-macrolet cl-flet*
+ cl-symbol-macrolet))
+ ;; In what follows, we rely on (point) returning non-nil.
+ (setq local-definitions-starting-point
+ (progn
+ (parse-partial-sexp
+ (point) first-order-parent nil
+ ;; From docstring of `parse-partial-sexp':
+ ;; Fourth arg non-nil means stop
+ ;; when we come to any character
+ ;; that starts a sexp.
+ t)
+ (point))))))
+ (save-excursion
+ (when (ignore-errors
+ ;; We rely on `backward-up-list' working
+ ;; even when sexp is incomplete “to the right”.
+ (backward-up-list 2)
+ t)
+ (= local-definitions-starting-point (point))))))))))
+
(defun lisp-indent-function (indent-point state)
"This function is the normal value of the variable `lisp-indent-function'.
The function `calculate-lisp-indent' calls this to determine
@@ -1138,16 +1189,19 @@ Lisp function does not specify a special indentation."
(if (and (elt state 2)
(not (looking-at "\\sw\\|\\s_")))
;; car of form doesn't seem to be a symbol
- (progn
+ (if (lisp--local-defform-body-p state)
+ ;; We nevertheless check whether we are in flet-like form
+ ;; as we presume local function names could be non-symbols.
+ (lisp-indent-defform state indent-point)
(if (not (> (save-excursion (forward-line 1) (point))
calculate-lisp-indent-last-sexp))
- (progn (goto-char calculate-lisp-indent-last-sexp)
- (beginning-of-line)
- (parse-partial-sexp (point)
- calculate-lisp-indent-last-sexp 0 t)))
- ;; Indent under the list or under the first sexp on the same
- ;; line as calculate-lisp-indent-last-sexp. Note that first
- ;; thing on that line has to be complete sexp since we are
+ (progn (goto-char calculate-lisp-indent-last-sexp)
+ (beginning-of-line)
+ (parse-partial-sexp (point)
+ calculate-lisp-indent-last-sexp 0 t)))
+ ;; Indent under the list or under the first sexp on the same
+ ;; line as calculate-lisp-indent-last-sexp. Note that first
+ ;; thing on that line has to be complete sexp since we are
;; inside the innermost containing sexp.
(backward-prefix-chars)
(current-column))
@@ -1158,15 +1212,14 @@ Lisp function does not specify a special indentation."
'lisp-indent-function)
(get (intern-soft function) 'lisp-indent-hook)))
(cond ((or (eq method 'defun)
- (and (null method)
- (> (length function) 3)
- (string-match "\\`def" function)))
+ ;; Check whether we are in flet-like form.
+ (lisp--local-defform-body-p state))
(lisp-indent-defform state indent-point))
((integerp method)
(lisp-indent-specform method state
indent-point normal-indent))
(method
- (funcall method indent-point state)))))))
+ (funcall method indent-point state)))))))
(defcustom lisp-body-indent 2
"Number of columns to indent the second line of a `(def...)' form."
@@ -1234,6 +1287,13 @@ Lisp function does not specify a special indentation."
(put 'autoload 'lisp-indent-function 'defun) ;Elisp
(put 'progn 'lisp-indent-function 0)
+(put 'defvar 'lisp-indent-function 'defun)
+(put 'defalias 'lisp-indent-function 'defun)
+(put 'defvaralias 'lisp-indent-function 'defun)
+(put 'defconst 'lisp-indent-function 'defun)
+(put 'define-category 'lisp-indent-function 'defun)
+(put 'define-charset-internal 'lisp-indent-function 'defun)
+(put 'define-fringe-bitmap 'lisp-indent-function 'defun)
(put 'prog1 'lisp-indent-function 1)
(put 'save-excursion 'lisp-indent-function 0) ;Elisp
(put 'save-restriction 'lisp-indent-function 0) ;Elisp
@@ -1248,6 +1308,7 @@ Lisp function does not specify a special indentation."
(put 'handler-bind 'lisp-indent-function 1) ;CL
(put 'unwind-protect 'lisp-indent-function 1)
(put 'with-output-to-temp-buffer 'lisp-indent-function 1)
+(put 'closure 'lisp-indent-function 2)
(defun indent-sexp (&optional endpos)
"Indent each line of the list starting just after point.
diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el
index 2495277ba23..9b38d86e2c7 100644
--- a/lisp/emacs-lisp/lisp.el
+++ b/lisp/emacs-lisp/lisp.el
@@ -186,12 +186,16 @@ report errors as appropriate for this kind of usage."
This command will also work on other parentheses-like expressions
defined by the current language mode. With ARG, do this that
many times. A negative argument means move forward but still to
-a less deep spot. If ESCAPE-STRINGS is non-nil (as it is
-interactively), move out of enclosing strings as well. If
-NO-SYNTAX-CROSSING is non-nil (as it is interactively), prefer to
-break out of any enclosing string instead of moving to the start
-of a list broken across multiple strings. On error, location of
-point is unspecified."
+a less deep spot.
+
+If ESCAPE-STRINGS is non-nil (as it is interactively), move out
+of enclosing strings as well.
+
+If NO-SYNTAX-CROSSING is non-nil (as it is interactively), prefer
+to break out of any enclosing string instead of moving to the
+start of a list broken across multiple strings.
+
+On error, location of point is unspecified."
(interactive "^p\nd\nd")
(up-list (- (or arg 1)) escape-strings no-syntax-crossing))
@@ -200,12 +204,16 @@ point is unspecified."
This command will also work on other parentheses-like expressions
defined by the current language mode. With ARG, do this that
many times. A negative argument means move backward but still to
-a less deep spot. If ESCAPE-STRINGS is non-nil (as it is
-interactively), move out of enclosing strings as well. If
-NO-SYNTAX-CROSSING is non-nil (as it is interactively), prefer to
-break out of any enclosing string instead of moving to the start
-of a list broken across multiple strings. On error, location of
-point is unspecified."
+a less deep spot.
+
+If ESCAPE-STRINGS is non-nil (as it is interactively), move out
+of enclosing strings as well.
+
+If NO-SYNTAX-CROSSING is non-nil (as it is interactively), prefer
+to break out of any enclosing string instead of moving to the
+end of a list broken across multiple strings.
+
+On error, location of point is unspecified."
(interactive "^p\nd\nd")
(or arg (setq arg 1))
(let ((inc (if (> arg 0) 1 -1))
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index 61c1ea490f0..a20c424e2bd 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -136,9 +136,12 @@ Other uses risk returning non-nil value that point to the wrong file."
(defvar macroexp--warned (make-hash-table :test #'equal :weakness 'key))
(defun macroexp--warn-wrap (msg form category)
- (let ((when-compiled (lambda ()
- (when (byte-compile-warning-enabled-p category)
- (byte-compile-warn "%s" msg)))))
+ (let ((when-compiled
+ (lambda ()
+ (when (if (consp category)
+ (apply #'byte-compile-warning-enabled-p category)
+ (byte-compile-warning-enabled-p category))
+ (byte-compile-warn "%s" msg)))))
`(progn
(macroexp--funcall-if-compiled ',when-compiled)
,form)))
@@ -220,7 +223,7 @@ is executed without being compiled first."
fun obsolete
(if (symbolp (symbol-function fun))
"alias" "macro"))
- new-form 'obsolete))
+ new-form (list 'obsolete fun)))
new-form)))
(defun macroexp--unfold-lambda (form &optional name)
@@ -243,19 +246,19 @@ is executed without being compiled first."
(while arglist
(cond ((eq (car arglist) '&optional)
;; ok, I'll let this slide because funcall_lambda() does...
- ;; (if optionalp (error "multiple &optional keywords in %s" name))
+ ;; (if optionalp (error "Multiple &optional keywords in %s" name))
(if restp (error "&optional found after &rest in %s" name))
(if (null (cdr arglist))
- (error "nothing after &optional in %s" name))
+ (error "Nothing after &optional in %s" name))
(setq optionalp t))
((eq (car arglist) '&rest)
;; ...but it is by no stretch of the imagination a reasonable
;; thing that funcall_lambda() allows (&rest x y) and
;; (&rest x &optional y) in arglists.
(if (null (cdr arglist))
- (error "nothing after &rest in %s" name))
+ (error "Nothing after &rest in %s" name))
(if (cdr (cdr arglist))
- (error "multiple vars after &rest in %s" name))
+ (error "Multiple vars after &rest in %s" name))
(setq restp t))
(restp
(setq bindings (cons (list (car arglist)
diff --git a/lisp/emacs-lisp/map-ynp.el b/lisp/emacs-lisp/map-ynp.el
index 0522b31f577..2f2f96ca0da 100644
--- a/lisp/emacs-lisp/map-ynp.el
+++ b/lisp/emacs-lisp/map-ynp.el
@@ -79,7 +79,7 @@ of the alist has the form (KEY FUNCTION HELP), where KEY is a character;
FUNCTION is a function of one argument (an object from LIST); and HELP
is a string. When the user presses KEY, FUNCTION is called; if it
returns non-nil, the object is considered to have been \"acted upon\",
-and `map-y-or-n-p' proceeeds to the next object from LIST. If
+and `map-y-or-n-p' proceeds to the next object from LIST. If
FUNCTION returns nil, the prompt is re-issued for the same object: this
comes in handy if FUNCTION produces some display that will allow the
user to make an intelligent decision whether the object in question
@@ -215,12 +215,12 @@ The function's value is the number of actions taken."
(action (or (nth 2 help) "act on")))
(concat
(format-message
- "\
-Type SPC or `y' to %s the current %s;
-DEL or `n' to skip the current %s;
-RET or `q' to skip the current and all remaining %s;
-C-g to quit (cancel the whole command);
-! to %s all remaining %s;\n"
+ (substitute-command-keys "\
+Type \\`SPC' or \\`y' to %s the current %s;
+\\`DEL' or \\`n' to skip the current %s;
+\\`RET' or \\`q' to skip the current and all remaining %s;
+\\`C-g' to quit (cancel the whole command);
+\\`!' to %s all remaining %s;\n")
action object object objects action objects)
(mapconcat (lambda (elt)
(format "%s to %s;\n"
diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
index 988a62a4e34..da4502f9ed8 100644
--- a/lisp/emacs-lisp/map.el
+++ b/lisp/emacs-lisp/map.el
@@ -5,7 +5,7 @@
;; Author: Nicolas Petton <nicolas@petton.fr>
;; Maintainer: emacs-devel@gnu.org
;; Keywords: extensions, lisp
-;; Version: 3.1
+;; Version: 3.2.1
;; Package-Requires: ((emacs "26"))
;; This file is part of GNU Emacs.
@@ -103,10 +103,14 @@ Returns the result of evaluating the form associated with MAP-VAR's type."
(and (consp list) (atom (car list))))
(cl-defgeneric map-elt (map key &optional default testfn)
- "Lookup KEY in MAP and return its associated value.
+ "Look up KEY in MAP and return its associated value.
If KEY is not found, return DEFAULT which defaults to nil.
-TESTFN is deprecated. Its default depends on the MAP argument.
+TESTFN is the function to use for comparing keys. It is
+deprecated because its default and valid values depend on the MAP
+argument. Generally, alist keys are compared with `equal', plist
+keys with `eq', and hash-table keys with the hash-table's test
+function.
In the base definition, MAP can be an alist, plist, hash-table,
or array."
@@ -119,14 +123,16 @@ or array."
((key key) (default default) (testfn testfn))
(funcall do `(map-elt ,mgetter ,key ,default)
(lambda (v)
- `(condition-case nil
- ;; Silence warnings about the hidden 4th arg.
- (with-no-warnings (map-put! ,mgetter ,key ,v ,testfn))
- (map-not-inplace
- ,(funcall msetter
- `(map-insert ,mgetter ,key ,v))
- ;; Always return the value.
- ,v))))))))
+ (macroexp-let2 nil v v
+ `(condition-case nil
+ ;; Silence warnings about the hidden 4th arg.
+ (with-no-warnings
+ (map-put! ,mgetter ,key ,v ,testfn))
+ (map-not-inplace
+ ,(funcall msetter
+ `(map-insert ,mgetter ,key ,v))
+ ;; Always return the value.
+ ,v)))))))))
;; `testfn' is deprecated.
(advertised-calling-convention (map key &optional default) "27.1"))
;; Can't use `cl-defmethod' with `advertised-calling-convention'.
@@ -134,7 +140,7 @@ or array."
:list (if (map--plist-p map)
(let ((res (plist-member map key)))
(if res (cadr res) default))
- (alist-get key map default nil testfn))
+ (alist-get key map default nil (or testfn #'equal)))
:hash-table (gethash key map default)
:array (if (map-contains-key map key)
(aref map key)
@@ -145,7 +151,7 @@ or array."
If KEY is already present in MAP, replace the associated value
with VALUE.
When MAP is an alist, test equality with TESTFN if non-nil,
-otherwise use `eql'.
+otherwise use `equal'.
MAP can be an alist, plist, hash-table, or array."
(declare (obsolete "use map-put! or (setf (map-elt ...) ...) instead" "27.1"))
@@ -155,7 +161,7 @@ MAP can be an alist, plist, hash-table, or array."
(let ((tail map) last)
(while (consp tail)
(cond
- ((not (equal key (car tail)))
+ ((not (eq key (car tail)))
(setq last tail)
(setq tail (cddr last)))
(last
@@ -175,7 +181,7 @@ Keys not present in MAP are ignored.")
;; FIXME: Signal map-not-inplace i.s.o returning a different list?
(if (map--plist-p map)
(map--plist-delete map key)
- (setf (alist-get key map nil t) nil)
+ (setf (alist-get key map nil t #'equal) nil)
map))
(cl-defmethod map-delete ((map hash-table) key)
@@ -421,15 +427,15 @@ See `map-into' for all supported values of TYPE."
"Convert MAP into a map of TYPE.")
;; FIXME: I wish there was a way to avoid this η-redex!
-(cl-defmethod map-into (map (_type (eql 'list)))
+(cl-defmethod map-into (map (_type (eql list)))
"Convert MAP into an alist."
(map-pairs map))
-(cl-defmethod map-into (map (_type (eql 'alist)))
+(cl-defmethod map-into (map (_type (eql alist)))
"Convert MAP into an alist."
(map-pairs map))
-(cl-defmethod map-into (map (_type (eql 'plist)))
+(cl-defmethod map-into (map (_type (eql plist)))
"Convert MAP into a plist."
(let (plist)
(map-do (lambda (k v) (setq plist `(,v ,k ,@plist))) map)
@@ -524,7 +530,7 @@ KEYWORD-ARGS are forwarded to `make-hash-table'."
map)
ht))
-(cl-defmethod map-into (map (_type (eql 'hash-table)))
+(cl-defmethod map-into (map (_type (eql hash-table)))
"Convert MAP into a hash-table with keys compared with `equal'."
(map--into-hash map (list :size (map-length map) :test #'equal)))
diff --git a/lisp/emacs-lisp/memory-report.el b/lisp/emacs-lisp/memory-report.el
index aee2a0079ca..450cdaa7a84 100644
--- a/lisp/emacs-lisp/memory-report.el
+++ b/lisp/emacs-lisp/memory-report.el
@@ -29,9 +29,9 @@
(require 'seq)
(require 'subr-x)
-(eval-when-compile (require 'cl-lib))
+(require 'cl-lib)
-(defvar memory-report--type-size (make-hash-table))
+(defvar memory-report--type-size nil)
;;;###autoload
(defun memory-report ()
@@ -84,6 +84,7 @@ by counted more than once."
(gethash 'object memory-report--type-size)))
(defun memory-report--set-size (elems)
+ (setq memory-report--type-size (make-hash-table))
(setf (gethash 'string memory-report--type-size)
(cadr (assq 'strings elems)))
(setf (gethash 'cons memory-report--type-size)
@@ -243,6 +244,19 @@ by counted more than once."
value)
total))
+;; All cl-defstruct types.
+(cl-defmethod memory-report--object-size-1 (counted (value cl-structure-object))
+ (let ((struct-type (type-of value)))
+ (apply #'+
+ (memory-report--size 'vector)
+ (mapcar (lambda (slot)
+ (if (eq (car slot) 'cl-tag-slot)
+ 0
+ (memory-report--object-size
+ counted
+ (cl-struct-slot-value struct-type (car slot) value))))
+ (cl-struct-slot-info struct-type)))))
+
(defun memory-report--format (bytes)
(setq bytes (/ bytes 1024.0))
(let ((units '("KiB" "MiB" "GiB" "TiB")))
@@ -269,7 +283,7 @@ by counted more than once."
buffers)
do (insert (memory-report--format size)
" "
- (button-buttonize
+ (buttonize
(buffer-name buffer)
#'memory-report--buffer-details buffer)
"\n"))
diff --git a/lisp/emacs-lisp/multisession.el b/lisp/emacs-lisp/multisession.el
new file mode 100644
index 00000000000..6ef0da10f77
--- /dev/null
+++ b/lisp/emacs-lisp/multisession.el
@@ -0,0 +1,446 @@
+;;; multisession.el --- Multisession storage for variables -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 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 'cl-lib)
+(require 'eieio)
+(require 'sqlite)
+(require 'tabulated-list)
+
+(defcustom multisession-storage 'files
+ "Storage method for multisession variables.
+Valid methods are `sqlite' and `files'."
+ :type '(choice (const :tag "SQLite" sqlite)
+ (const :tag "Files" files))
+ :version "29.1"
+ :group 'files)
+
+(defcustom multisession-directory (expand-file-name "multisession/"
+ user-emacs-directory)
+ "Directory to store multisession variables."
+ :type 'file
+ :version "29.1"
+ :group 'files)
+
+;;;###autoload
+(defmacro define-multisession-variable (name initial-value &optional doc
+ &rest args)
+ "Make NAME into a multisession variable initialized from INITIAL-VALUE.
+DOC should be a doc string, and ARGS are keywords as applicable to
+`make-multisession'."
+ (declare (indent defun))
+ (unless (plist-get args :package)
+ (setq args (nconc (list :package
+ (replace-regexp-in-string "-.*" ""
+ (symbol-name name)))
+ args)))
+ `(defvar ,name
+ (make-multisession :key ,(symbol-name name)
+ :initial-value ,initial-value
+ ,@args)
+ ,@(list doc)))
+
+(defconst multisession--unbound (make-symbol "unbound"))
+
+(cl-defstruct (multisession
+ (:constructor nil)
+ (:constructor multisession--create)
+ (:conc-name multisession--))
+ "A persistent variable that will live across Emacs invocations."
+ key
+ (initial-value nil)
+ package
+ (storage multisession-storage)
+ (synchronized nil)
+ (cached-value multisession--unbound)
+ (cached-sequence 0))
+
+(cl-defun make-multisession (&key key initial-value package synchronized
+ storage)
+ "Create a multisession object."
+ (unless package
+ (error "No package for the multisession object"))
+ (unless key
+ (error "No key for the multisession object"))
+ (unless (stringp package)
+ (error "The package has to be a string"))
+ (unless (stringp key)
+ (error "The key has to be a string"))
+ (multisession--create
+ :key key
+ :synchronized synchronized
+ :initial-value initial-value
+ :package package
+ :storage (or storage multisession-storage)))
+
+(defun multisession-value (object)
+ "Return the value of the multisession OBJECT."
+ (if (null user-init-file)
+ ;; If we don't have storage, then just return the value from the
+ ;; object.
+ (if (eq (multisession--cached-value object) multisession--unbound)
+ (multisession--initial-value object)
+ (multisession--cached-value object))
+ ;; We have storage, so we update from storage.
+ (multisession-backend-value (multisession--storage object) object)))
+
+(defun multisession--set-value (object value)
+ "Set the stored value of OBJECT to VALUE."
+ (if (null user-init-file)
+ ;; We have no backend, so just store the value.
+ (setf (multisession--cached-value object) value)
+ ;; We have a backend.
+ (multisession--backend-set-value (multisession--storage object)
+ object value)))
+
+(defun multisession-delete (object)
+ "Delete OBJECT from the backend storage."
+ (multisession--backend-delete (multisession--storage object) object))
+
+(gv-define-simple-setter multisession-value multisession--set-value)
+
+;; SQLite Backend
+
+(declare-function sqlite-execute "sqlite.c")
+(declare-function sqlite-select "sqlite.c")
+(declare-function sqlite-open "sqlite.c")
+(declare-function sqlite-pragma "sqlite.c")
+(declare-function sqlite-transaction "sqlite.c")
+(declare-function sqlite-commit "sqlite.c")
+
+(defvar multisession--db nil)
+
+(defun multisession--ensure-db ()
+ (unless multisession--db
+ (let* ((file (expand-file-name "sqlite/multisession.sqlite"
+ multisession-directory))
+ (dir (file-name-directory file)))
+ (unless (file-exists-p dir)
+ (make-directory dir t))
+ (setq multisession--db (sqlite-open file)))
+ (with-sqlite-transaction multisession--db
+ ;; Use a write-ahead-log (available since 2010), which makes
+ ;; writes a lot faster.
+ (sqlite-pragma multisession--db "journal_mode = WAL")
+ (sqlite-pragma multisession--db "synchronous = NORMAL")
+ (unless (sqlite-select
+ multisession--db
+ "select name from sqlite_master where type = 'table' and name = 'multisession'")
+ ;; Tidy up the database automatically.
+ (sqlite-pragma multisession--db "auto_vacuum = FULL")
+ ;; Create the table.
+ (sqlite-execute
+ multisession--db
+ "create table multisession (package text not null, key text not null, sequence number not null default 1, value text not null)")
+ (sqlite-execute
+ multisession--db
+ "create unique index multisession_idx on multisession (package, key)")))))
+
+(cl-defmethod multisession-backend-value ((_type (eql 'sqlite)) object)
+ (multisession--ensure-db)
+ (let ((id (list (multisession--package object)
+ (multisession--key object))))
+ (cond
+ ;; We have no value yet; check the database.
+ ((eq (multisession--cached-value object) multisession--unbound)
+ (let ((stored
+ (car
+ (sqlite-select
+ multisession--db
+ "select value, sequence from multisession where package = ? and key = ?"
+ id))))
+ (if stored
+ (let ((value (car (read-from-string (car stored)))))
+ (setf (multisession--cached-value object) value
+ (multisession--cached-sequence object) (cadr stored))
+ value)
+ ;; Nothing; return the initial value.
+ (multisession--initial-value object))))
+ ;; We have a value, but we want to update in case some other
+ ;; Emacs instance has updated.
+ ((multisession--synchronized object)
+ (let ((stored
+ (car
+ (sqlite-select
+ multisession--db
+ "select value, sequence from multisession where sequence > ? and package = ? and key = ?"
+ (cons (multisession--cached-sequence object) id)))))
+ (if stored
+ (let ((value (car (read-from-string (car stored)))))
+ (setf (multisession--cached-value object) value
+ (multisession--cached-sequence object) (cadr stored))
+ value)
+ ;; Nothing, return the cached value.
+ (multisession--cached-value object))))
+ ;; Just return the cached value.
+ (t
+ (multisession--cached-value object)))))
+
+(cl-defmethod multisession--backend-set-value ((_type (eql 'sqlite))
+ object value)
+ (catch 'done
+ (let ((i 0))
+ (while (< i 10)
+ (condition-case nil
+ (throw 'done (multisession--set-value-sqlite object value))
+ (sqlite-locked-error
+ (setq i (1+ i))
+ (sleep-for (+ 0.1 (/ (float (random 10)) 10))))))
+ (signal 'sqlite-locked-error "Database is locked"))))
+
+(defun multisession--set-value-sqlite (object value)
+ (multisession--ensure-db)
+ (with-sqlite-transaction multisession--db
+ (let ((id (list (multisession--package object)
+ (multisession--key object)))
+ (pvalue
+ (let ((print-length nil)
+ (print-circle t)
+ (print-level nil))
+ (prin1-to-string value))))
+ (condition-case nil
+ (ignore (read-from-string pvalue))
+ (error (error "Unable to store unreadable value: %s" pvalue)))
+ (sqlite-execute
+ multisession--db
+ "insert into multisession(package, key, sequence, value) values(?, ?, 1, ?) on conflict(package, key) do update set sequence = sequence + 1, value = ?"
+ (append id (list pvalue pvalue)))
+ (setf (multisession--cached-sequence object)
+ (caar (sqlite-select
+ multisession--db
+ "select sequence from multisession where package = ? and key = ?"
+ id)))
+ (setf (multisession--cached-value object) value))))
+
+(cl-defmethod multisession--backend-values ((_type (eql 'sqlite)))
+ (multisession--ensure-db)
+ (sqlite-select
+ multisession--db
+ "select package, key, value from multisession order by package, key"))
+
+(cl-defmethod multisession--backend-delete ((_type (eql 'sqlite)) object)
+ (sqlite-execute multisession--db
+ "delete from multisession where package = ? and key = ?"
+ (list (multisession--package object)
+ (multisession--key object))))
+
+;; Files Backend
+
+(defun multisession--encode-file-name (name)
+ (url-hexify-string name))
+
+(defun multisession--read-file-value (file object)
+ (catch 'done
+ (let ((i 0)
+ last-error)
+ (while (< i 10)
+ (condition-case err
+ (throw 'done
+ (with-temp-buffer
+ (let* ((time (file-attribute-modification-time
+ (file-attributes file)))
+ (coding-system-for-read 'utf-8))
+ (insert-file-contents file)
+ (let ((stored (read (current-buffer))))
+ (setf (multisession--cached-value object) stored
+ (multisession--cached-sequence object) time)
+ stored))))
+ ;; Windows uses OS-level file locking that may preclude
+ ;; reading the file in some circumstances. So when that
+ ;; happens, wait a bit and try again.
+ (file-error
+ (setq i (1+ i)
+ last-error err)
+ (sleep-for (+ 0.1 (/ (float (random 10)) 10))))))
+ (signal (car last-error) (cdr last-error)))))
+
+(defun multisession--object-file-name (object)
+ (expand-file-name
+ (concat "files/"
+ (multisession--encode-file-name (multisession--package object))
+ "/"
+ (multisession--encode-file-name (multisession--key object))
+ ".value")
+ multisession-directory))
+
+(cl-defmethod multisession-backend-value ((_type (eql 'files)) object)
+ (let ((file (multisession--object-file-name object)))
+ (cond
+ ;; We have no value yet; see whether it's stored.
+ ((eq (multisession--cached-value object) multisession--unbound)
+ (if (file-exists-p file)
+ (multisession--read-file-value file object)
+ ;; Nope; return the initial value.
+ (multisession--initial-value object)))
+ ;; We have a value, but we want to update in case some other
+ ;; Emacs instance has updated.
+ ((multisession--synchronized object)
+ (if (and (file-exists-p file)
+ (time-less-p (multisession--cached-sequence object)
+ (file-attribute-modification-time
+ (file-attributes file))))
+ (multisession--read-file-value file object)
+ ;; Nothing, return the cached value.
+ (multisession--cached-value object)))
+ ;; Just return the cached value.
+ (t
+ (multisession--cached-value object)))))
+
+(cl-defmethod multisession--backend-set-value ((_type (eql 'files))
+ object value)
+ (let ((file (multisession--object-file-name object))
+ (time (current-time)))
+ ;; Ensure that the directory exists.
+ (let ((dir (file-name-directory file)))
+ (unless (file-exists-p dir)
+ (make-directory dir t)))
+ (with-temp-buffer
+ (let ((print-length nil)
+ (print-circle t)
+ (print-level nil))
+ (prin1 value (current-buffer)))
+ (goto-char (point-min))
+ (condition-case nil
+ (read (current-buffer))
+ (error (error "Unable to store unreadable value: %s" (buffer-string))))
+ ;; Write to a temp file in the same directory and rename to the
+ ;; file for somewhat better atomicity.
+ (let ((coding-system-for-write 'utf-8)
+ (create-lockfiles nil)
+ (temp (make-temp-name file))
+ (write-region-inhibit-fsync nil))
+ (write-region (point-min) (point-max) temp nil 'silent)
+ (set-file-times temp time)
+ (rename-file temp file t)))
+ (setf (multisession--cached-sequence object) time
+ (multisession--cached-value object) value)))
+
+(cl-defmethod multisession--backend-values ((_type (eql 'files)))
+ (mapcar (lambda (file)
+ (let ((bits (file-name-split file)))
+ (list (url-unhex-string (car (last bits 2)))
+ (url-unhex-string
+ (file-name-sans-extension (car (last bits))))
+ (with-temp-buffer
+ (let ((coding-system-for-read 'utf-8))
+ (insert-file-contents file)
+ (read (current-buffer)))))))
+ (directory-files-recursively
+ (expand-file-name "files" multisession-directory)
+ "\\.value\\'")))
+
+(cl-defmethod multisession--backend-delete ((_type (eql 'files)) object)
+ (let ((file (multisession--object-file-name object)))
+ (when (file-exists-p file)
+ (delete-file file))))
+
+;; Mode for editing.
+
+(defvar-keymap multisession-edit-mode-map
+ :parent tabulated-list-mode-map
+ "d" #'multisession-delete-value
+ "e" #'multisession-edit-value)
+
+(define-derived-mode multisession-edit-mode special-mode "Multisession"
+ "This mode lists all elements in the \"multisession\" database."
+ :interactive nil
+ (buffer-disable-undo)
+ (setq-local buffer-read-only t
+ truncate-lines t)
+ (setq tabulated-list-format
+ [("Package" 10)
+ ("Key" 30)
+ ("Value" 30)])
+ (setq-local revert-buffer-function #'multisession-edit-mode--revert))
+
+;;;###autoload
+(defun list-multisession-values (&optional choose-storage)
+ "List all values in the \"multisession\" database.
+If CHOOSE-STORAGE (interactively, the prefix), query for the
+storage method to list."
+ (interactive "P")
+ (let ((storage
+ (if choose-storage
+ (intern (completing-read "Storage method: " '(sqlite files) nil t))
+ multisession-storage)))
+ (pop-to-buffer (get-buffer-create (format "*Multisession %s*" storage)))
+ (multisession-edit-mode)
+ (setq-local multisession-storage storage)
+ (multisession-edit-mode--revert)
+ (goto-char (point-min))))
+
+(defun multisession-edit-mode--revert (&rest _)
+ (let ((inhibit-read-only t)
+ (id (get-text-property (point) 'tabulated-list-id)))
+ (erase-buffer)
+ (tabulated-list-init-header)
+ (setq tabulated-list-entries
+ (mapcar (lambda (elem)
+ (list
+ (cons (car elem) (cadr elem))
+ (vector (car elem) (cadr elem)
+ (string-replace "\n" "\\n"
+ (format "%s" (caddr elem))))))
+ (multisession--backend-values multisession-storage)))
+ (tabulated-list-print t)
+ (goto-char (point-min))
+ (when id
+ (when-let ((match
+ (text-property-search-forward 'tabulated-list-id id t)))
+ (goto-char (prop-match-beginning match))))))
+
+(defun multisession-delete-value (id)
+ "Delete the value at point."
+ (interactive (list (get-text-property (point) 'tabulated-list-id))
+ multisession-edit-mode)
+ (unless id
+ (error "No value on the current line"))
+ (unless (yes-or-no-p "Really delete this item? ")
+ (user-error "Not deleting"))
+ (multisession--backend-delete multisession-storage
+ (make-multisession :package (car id)
+ :key (cdr id)))
+ (let ((inhibit-read-only t))
+ (beginning-of-line)
+ (delete-region (point) (progn (forward-line 1) (point)))))
+
+(defun multisession-edit-value (id)
+ "Edit the value at point."
+ (interactive (list (get-text-property (point) 'tabulated-list-id))
+ multisession-edit-mode)
+ (unless id
+ (error "No value on the current line"))
+ (let* ((object (make-multisession
+ :package (car id)
+ :key (cdr id)
+ :storage multisession-storage))
+ (value (multisession-value object)))
+ (setf (multisession-value object)
+ (car (read-from-string
+ (read-string "New value: " (prin1-to-string value))))))
+ (multisession-edit-mode--revert))
+
+(provide 'multisession)
+
+;;; multisession.el ends here
diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el
index 4804e859ebe..8fc2986ab41 100644
--- a/lisp/emacs-lisp/nadvice.el
+++ b/lisp/emacs-lisp/nadvice.el
@@ -85,42 +85,50 @@ Each element has the form (WHERE BYTECODE STACK) where:
(if (eq bytecode (cadr elem)) (setq where (car elem))))
where))
+(defun advice--make-single-doc (flist function macrop)
+ (let ((where (advice--where flist)))
+ (concat
+ (format "This %s has %s advice: "
+ (if macrop "macro" "function")
+ where)
+ (let ((fun (advice--car flist)))
+ (if (symbolp fun) (format-message "`%S'." fun)
+ (let* ((name (cdr (assq 'name (advice--props flist))))
+ (doc (documentation fun t))
+ (usage (help-split-fundoc doc function)))
+ (if usage (setq doc (cdr usage)))
+ (if name
+ (if doc
+ (format "%s\n%s" name doc)
+ (format "%s" name))
+ (or doc "No documentation")))))
+ "\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))
- (if macrop (setq flist (cdr flist)))
- (while (advice--p flist)
- (let ((doc (aref flist 4))
- (where (advice--where flist)))
+ (when macrop
+ (setq flist (cdr flist)))
+ (if (and (autoloadp flist)
+ (get function 'advice--pending))
+ (setq docstring
+ (advice--make-single-doc (get function 'advice--pending)
+ function macrop))
+ (while (advice--p flist)
;; Hack attack! For advices installed before calling
;; Snarf-documentation, the integer offset into the DOC file will not
;; be installed in the "core unadvised function" but in the advice
;; object instead! So here we try to undo the damage.
- (if (integerp doc) (setq docfun flist))
- (setq docstring
- (concat
- docstring
- (format "This %s has %s advice: "
- (if macrop "macro" "function")
- where)
- (let ((fun (advice--car flist)))
- (if (symbolp fun) (format-message "`%S'." fun)
- (let* ((name (cdr (assq 'name (advice--props flist))))
- (doc (documentation fun t))
- (usage (help-split-fundoc doc function)))
- (if usage (setq doc (cdr usage)))
- (if name
- (if doc
- (format "%s\n%s" name doc)
- (format "%s" name))
- (or doc "No documentation")))))
- "\n")))
- (setq flist (advice--cdr flist)))
- (if docstring (setq docstring (concat docstring "\n")))
- (unless docfun (setq docfun flist))
+ (when (integerp (aref flist 4))
+ (setq docfun flist))
+ (setq docstring (concat docstring (advice--make-single-doc
+ flist function macrop))
+ flist (advice--cdr flist))))
+ (unless docfun
+ (setq docfun flist))
(let* ((origdoc (unless (eq function docfun) ;Avoid inf-loops.
(documentation docfun t)))
(usage (help-split-fundoc origdoc function)))
@@ -131,7 +139,12 @@ Each element has the form (WHERE BYTECODE STACK) where:
(if (stringp arglist) t
(help--make-usage-docstring function arglist)))
(setq origdoc (cdr usage)) (car usage)))
- (help-add-fundoc-usage (concat docstring origdoc) usage))))
+ (help-add-fundoc-usage (concat origdoc
+ (if (string-suffix-p "\n" origdoc)
+ "\n"
+ "\n\n")
+ docstring)
+ usage))))
(defun advice-eval-interactive-spec (spec)
"Evaluate the interactive spec SPEC."
@@ -147,7 +160,7 @@ Each element has the form (WHERE BYTECODE STACK) where:
(t (eval spec))))
(defun advice--interactive-form (function)
- ;; Like `interactive-form' but tries to avoid autoloading functions.
+ "Like `interactive-form' but tries to avoid autoloading functions."
(when (commandp function)
(if (not (and (symbolp function) (autoloadp (indirect-function function))))
(interactive-form function)
@@ -232,7 +245,7 @@ WHERE is a symbol to select an entry in `advice--where-alist'."
(list (advice--remove-function rest function)))))))
(defvar advice--buffer-local-function-sample nil
- "keeps an example of the special \"run the default value\" functions.
+ "Keeps an example of the special \"run the default value\" functions.
These functions play the same role as t in buffer-local hooks, and to recognize
them, we keep a sample here against which to compare. Each instance is
different, but `function-equal' will hopefully ignore those differences.")
diff --git a/lisp/emacs-lisp/package-x.el b/lisp/emacs-lisp/package-x.el
index 2e327d16de4..0175857b7f5 100644
--- a/lisp/emacs-lisp/package-x.el
+++ b/lisp/emacs-lisp/package-x.el
@@ -34,7 +34,7 @@
;; (possibly one on a remote machine, accessed via Tramp).
;; Then call M-x package-upload-file, which prompts for a file to
-;; upload. Alternatively, M-x package-upload-buffer uploads the
+;; upload. Alternatively, M-x package-upload-buffer uploads the
;; current buffer, if it's visiting a package file.
;; Once a package is uploaded, users can access it via the Package
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 9ed23862e92..1596b5a1bf4 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -427,7 +427,7 @@ synchronously."
:version "28.1")
(defcustom package-archive-column-width 8
- "Column width for the Package status in the package menu."
+ "Column width for the Package archive in the package menu."
:type 'number
:version "28.1")
@@ -715,6 +715,7 @@ REQUIREMENTS is a list of dependencies on other packages.
where OTHER-VERSION is a string.
EXTRA-PROPERTIES is currently unused."
+ (declare (indent defun))
;; FIXME: Placeholder! Should we keep it?
(error "Don't call me!"))
@@ -758,47 +759,47 @@ PKG-DESC is a `package-desc' object."
(format "%s-autoloads" (package-desc-name pkg-desc))
(package-desc-dir pkg-desc)))
-(defun package--activate-autoloads-and-load-path (pkg-desc)
- "Load the autoloads file and add package dir to `load-path'.
-PKG-DESC is a `package-desc' object."
- (let* ((old-lp load-path)
- (pkg-dir (package-desc-dir pkg-desc))
- (pkg-dir-dir (file-name-as-directory pkg-dir)))
- (with-demoted-errors "Error loading autoloads: %s"
- (load (package--autoloads-file-name pkg-desc) nil t))
- (when (and (eq old-lp load-path)
- (not (or (member pkg-dir load-path)
- (member pkg-dir-dir load-path))))
- ;; Old packages don't add themselves to the `load-path', so we have to
- ;; do it ourselves.
- (push pkg-dir load-path))))
-
(defvar Info-directory-list)
(declare-function info-initialize "info" ())
(defvar package--quickstart-pkgs t
"If set to a list, we're computing the set of pkgs to activate.")
-(defun package--load-files-for-activation (pkg-desc reload)
- "Load files for activating a package given by PKG-DESC.
-Load the autoloads file, and ensure `load-path' is setup. If
-RELOAD is non-nil, also load all files in the package that
-correspond to previously loaded files."
- (let* ((loaded-files-list
- (when reload
- (package--list-loaded-files (package-desc-dir pkg-desc)))))
- ;; Add to load path, add autoloads, and activate the package.
- (package--activate-autoloads-and-load-path pkg-desc)
- ;; Call `load' on all files in `package-desc-dir' already present in
- ;; `load-history'. This is done so that macros in these files are updated
- ;; to their new definitions. If another package is being installed which
- ;; depends on this new definition, not doing this update would cause
- ;; compilation errors and break the installation.
- (with-demoted-errors "Error in package--load-files-for-activation: %s"
- (mapc (lambda (feature) (load feature nil t))
- ;; Skip autoloads file since we already evaluated it above.
- (remove (file-truename (package--autoloads-file-name pkg-desc))
- loaded-files-list)))))
+(defsubst package--library-stem (file)
+ (catch 'done
+ (let (result)
+ (dolist (suffix (get-load-suffixes) file)
+ (setq result (string-trim file nil suffix))
+ (unless (equal file result)
+ (throw 'done result))))))
+
+(defun package--reload-previously-loaded (pkg-desc)
+ "Force reimportation of files in PKG-DESC already present in `load-history'.
+New editions of files contain macro definitions and
+redefinitions, the overlooking of which would cause
+byte-compilation of the new package to fail."
+ (with-demoted-errors "Error in package--load-files-for-activation: %s"
+ (let* (result
+ (dir (package-desc-dir pkg-desc))
+ (load-path-sans-dir
+ (cl-remove-if (apply-partially #'string= dir)
+ (or (bound-and-true-p find-function-source-path)
+ load-path)))
+ (files (directory-files-recursively dir "\\`[^\\.].*\\.el\\'"))
+ (history (mapcar #'file-truename
+ (cl-remove-if-not #'stringp
+ (mapcar #'car load-history)))))
+ (dolist (file files)
+ (when-let ((library (package--library-stem
+ (file-relative-name file dir)))
+ (canonical (locate-library library nil load-path-sans-dir))
+ (found (member (file-truename canonical) history))
+ (recent-index (length found)))
+ (unless (equal (file-name-base library)
+ (format "%s-autoloads" (package-desc-name pkg-desc)))
+ (push (cons (expand-file-name library dir) recent-index) result))))
+ (mapc (lambda (c) (load (car c) nil t))
+ (sort result (lambda (x y) (< (cdr x) (cdr y))))))))
(defun package-activate-1 (pkg-desc &optional reload deps)
"Activate package given by PKG-DESC, even if it was already active.
@@ -825,7 +826,11 @@ correspond to previously loaded files (those returned by
(if (listp package--quickstart-pkgs)
;; We're only collecting the set of packages to activate!
(push pkg-desc package--quickstart-pkgs)
- (package--load-files-for-activation pkg-desc reload))
+ (when reload
+ (package--reload-previously-loaded pkg-desc))
+ (with-demoted-errors "Error loading autoloads: %s"
+ (load (package--autoloads-file-name pkg-desc) nil t))
+ (add-to-list 'load-path (directory-file-name pkg-dir)))
;; Add info node.
(when (file-exists-p (expand-file-name "dir" pkg-dir))
;; FIXME: not the friendliest, but simple.
@@ -836,48 +841,6 @@ correspond to previously loaded files (those returned by
;; Don't return nil.
t)))
-(defun package--files-load-history ()
- (delq nil
- (mapcar (lambda (x)
- (let ((f (car x)))
- (and (stringp f)
- (file-name-sans-extension (file-truename f)))))
- load-history)))
-
-(defun package--list-of-conflicts (dir history)
- (require 'find-func)
- (declare-function find-library-name "find-func" (library))
- (delq
- nil
- (mapcar
- (lambda (x) (let* ((file (file-relative-name x dir))
- ;; Previously loaded file, if any.
- (previous
- (ignore-error file-error ;"Can't find library"
- (file-name-sans-extension
- (file-truename (find-library-name file)))))
- (pos (when previous (member previous history))))
- ;; Return (RELATIVE-FILENAME . HISTORY-POSITION)
- (when pos
- (cons (file-name-sans-extension file) (length pos)))))
- (directory-files-recursively dir "\\`[^\\.].*\\.el\\'"))))
-
-(defun package--list-loaded-files (dir)
- "Recursively list all files in DIR which correspond to loaded features.
-Returns the `file-name-sans-extension' of each file, relative to
-DIR, sorted by most recently loaded last."
- (let* ((history (package--files-load-history))
- (dir (file-truename dir))
- ;; List all files that have already been loaded.
- (list-of-conflicts (package--list-of-conflicts dir history)))
- ;; Turn the list of (FILENAME . POS) back into a list of features. Files in
- ;; subdirectories are returned relative to DIR (so not actually features).
- (let ((default-directory (file-name-as-directory dir)))
- (mapcar (lambda (x) (file-truename (car x)))
- (sort list-of-conflicts
- ;; Sort the files by ascending HISTORY-POSITION.
- (lambda (x y) (< (cdr x) (cdr y))))))))
-
;;;; `package-activate'
(defun package--get-activatable-pkg (pkg-name)
@@ -996,7 +959,7 @@ untar into a directory named DIR; otherwise, signal an error."
(package--native-compile-async new-desc))
;; After compilation, load again any files loaded by
;; `activate-1', so that we use the byte-compiled definitions.
- (package--load-files-for-activation new-desc :reload)))
+ (package--reload-previously-loaded new-desc)))
pkg-dir))
(defun package-generate-description-file (pkg-desc pkg-file)
@@ -1082,8 +1045,7 @@ This assumes that `pkg-desc' has already been activated with
"Native compile installed package PKG-DESC asynchronously.
This assumes that `pkg-desc' has already been activated with
`package-activate-1'."
- (when (and (featurep 'native-compile)
- (native-comp-available-p))
+ (when (native-comp-available-p)
(let ((warning-minimum-level :error))
(native-compile-async (package-desc-dir pkg-desc) t))))
@@ -1119,7 +1081,7 @@ is wrapped around any parts requiring it."
(declare-function lm-header "lisp-mnt" (header))
(declare-function lm-header-multiline "lisp-mnt" (header))
-(declare-function lm-homepage "lisp-mnt" (&optional file))
+(declare-function lm-website "lisp-mnt" (&optional file))
(declare-function lm-keywords-list "lisp-mnt" (&optional file))
(declare-function lm-maintainers "lisp-mnt" (&optional file))
(declare-function lm-authors "lisp-mnt" (&optional file))
@@ -1154,7 +1116,7 @@ boundaries."
(or (lm-header "package-version") (lm-header "version")))
(pkg-version (package-strip-rcs-id version-info))
(keywords (lm-keywords-list))
- (homepage (lm-homepage)))
+ (website (lm-website)))
(unless pkg-version
(if version-info
(error "Unrecognized package version: %s" version-info)
@@ -1165,7 +1127,7 @@ boundaries."
(package--prepare-dependencies
(package-read-from-string (mapconcat #'identity require-lines " "))))
:kind 'single
- :url homepage
+ :url website
:keywords keywords
:maintainer
;; For backward compatibility, use a single string if there's only
@@ -1220,13 +1182,17 @@ The return result is a `package-desc'."
info)
(while files
(with-temp-buffer
- (insert-file-contents (pop files))
- ;; When we find the file with the data,
- (when (setq info (ignore-errors (package-buffer-info)))
- ;; stop looping,
- (setq files nil)
- ;; set the 'dir kind,
- (setf (package-desc-kind info) 'dir))))
+ (let ((file (pop files)))
+ ;; The file may be a link to a nonexistent file; e.g., a
+ ;; lock file.
+ (when (file-exists-p file)
+ (insert-file-contents file)
+ ;; When we find the file with the data,
+ (when (setq info (ignore-errors (package-buffer-info)))
+ ;; stop looping,
+ (setq files nil)
+ ;; set the 'dir kind,
+ (setf (package-desc-kind info) 'dir))))))
(unless info
(error "No .el files with package headers in `%s'" default-directory))
;; and return the info.
@@ -1587,7 +1553,7 @@ If the archive version is too new, signal an error."
(if package
(package--add-to-archive-contents package archive)
(lwarn '(package refresh) :warning
- "Ignoring `nil' package on `%s' package archive" archive))))))
+ "Ignoring nil package on `%s' package archive" archive))))))
(defvar package--old-archive-priorities nil
"Store currently used `package-archive-priorities'.
@@ -2171,7 +2137,7 @@ Otherwise return nil."
;; to make sure we use a "canonical name"!
(if l (package-version-join l)))))
-(declare-function lm-homepage "lisp-mnt" (&optional file))
+(declare-function lm-website "lisp-mnt" (&optional file))
;;;###autoload
(defun package-install-from-buffer ()
@@ -2241,6 +2207,7 @@ directory."
(dired-mode))
(insert-file-contents-literally file)
(set-visited-file-name file)
+ (set-buffer-modified-p nil)
(when (string-match "\\.tar\\'" file) (tar-mode)))
(package-install-from-buffer)))
@@ -2269,7 +2236,9 @@ confirmation to install packages."
(mapconcat #'symbol-name available " "))))
(mapc (lambda (p) (package-install p 'dont-select)) available)))
((> difference 0)
- (message "Packages that are not available: %d (the rest is already installed), maybe you need to `M-x package-refresh-contents'"
+ (message (substitute-command-keys
+ "Packages that are not available: %d (the rest is already \
+installed), maybe you need to \\[package-refresh-contents]")
difference))
(t
(message "All your packages are already installed"))))))
@@ -2487,6 +2456,15 @@ The description is read from the installed package files."
(format "%s.el" (package-desc-name desc)) srcdir))
"")))
+(defun package--describe-add-library-links ()
+ "Add links to library names in package description."
+ (while (re-search-forward "\\<\\([-[:alnum:]]+\\.el\\)\\>" nil t)
+ (if (locate-library (match-string 1))
+ (make-text-button (match-beginning 1) (match-end 1)
+ 'xref (match-string-no-properties 1)
+ 'help-echo "Read this file's commentary"
+ :type 'package--finder-xref))))
+
(defun describe-package-1 (pkg)
"Insert the package description for PKG.
Helper function for `describe-package'."
@@ -2505,7 +2483,7 @@ Helper function for `describe-package'."
(version (if desc (package-desc-version desc)))
(archive (if desc (package-desc-archive desc)))
(extras (and desc (package-desc-extras desc)))
- (homepage (cdr (assoc :url extras)))
+ (website (cdr (assoc :url extras)))
(commit (cdr (assoc :commit extras)))
(keywords (if desc (package-desc--keywords desc)))
(built-in (eq pkg-dir 'builtin))
@@ -2618,15 +2596,20 @@ Helper function for `describe-package'."
(help-insert-xref-button text 'help-package
(package-desc-name pkg))))
(insert "\n")))
- (when homepage
- ;; Prefer https for the homepage of packages on gnu.org.
- (if (string-match-p "^http://\\(elpa\\|www\\)\\.gnu\\.org/" homepage)
- (let ((gnu (cdr (assoc "gnu" package-archives))))
- (and gnu (string-match-p "^https" gnu)
- (setq homepage
- (replace-regexp-in-string "^http" "https" homepage)))))
- (package--print-help-section "Homepage")
- (help-insert-xref-button homepage 'help-url homepage)
+ (when website
+ ;; Prefer https for the website of packages on common domains.
+ (when (string-match-p (rx bol "http://" (or "elpa." "www." "git." "")
+ (or "nongnu.org" "gnu.org" "sr.ht"
+ "emacswiki.org" "gitlab.com" "github.com")
+ "/")
+ website)
+ ;; But only if the user has "https" in `package-archives'.
+ (let ((gnu (cdr (assoc "gnu" package-archives))))
+ (and gnu (string-match-p "^https" gnu)
+ (setq website
+ (replace-regexp-in-string "^http" "https" website)))))
+ (package--print-help-section "Website")
+ (help-insert-xref-button website 'help-url website)
(insert "\n"))
(when keywords
(package--print-help-section "Keywords")
@@ -2708,6 +2691,9 @@ Helper function for `describe-package'."
t)
(insert (or readme-string
"This package does not provide a description.")))))
+ ;; Make library descriptions into links.
+ (goto-char start-of-description)
+ (package--describe-add-library-links)
;; Make URLs in the description into links.
(goto-char start-of-description)
(browse-url-add-buttons))))
@@ -2753,6 +2739,15 @@ function is a convenience wrapper used by `describe-package-1'."
(apply #'insert-text-button button-text 'face button-face 'follow-link t
properties)))
+(defun package--finder-goto-xref (button)
+ "Jump to a Lisp file for the BUTTON at point."
+ (let* ((file (button-get button 'xref))
+ (lib (locate-library file)))
+ (if lib (finder-commentary lib)
+ (message "Unable to locate `%s'" file))))
+
+(define-button-type 'package--finder-xref 'action #'package--finder-goto-xref)
+
(defun package--print-email-button (recipient)
"Insert a button whose action will send an email to RECIPIENT.
NAME should have the form (FULLNAME . EMAIL) where FULLNAME is
@@ -2774,42 +2769,40 @@ either a full name or nil, and EMAIL is a valid email address."
;;;; Package menu mode.
-(defvar package-menu-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map tabulated-list-mode-map)
- (define-key map "\C-m" 'package-menu-describe-package)
- (define-key map "u" 'package-menu-mark-unmark)
- (define-key map "\177" 'package-menu-backup-unmark)
- (define-key map "d" 'package-menu-mark-delete)
- (define-key map "i" 'package-menu-mark-install)
- (define-key map "U" 'package-menu-mark-upgrades)
- (define-key map "r" 'revert-buffer)
- (define-key map "~" 'package-menu-mark-obsolete-for-deletion)
- (define-key map "w" 'package-browse-url)
- (define-key map "x" 'package-menu-execute)
- (define-key map "h" 'package-menu-quick-help)
- (define-key map "H" #'package-menu-hide-package)
- (define-key map "?" 'package-menu-describe-package)
- (define-key map "(" #'package-menu-toggle-hiding)
- (define-key map (kbd "/ /") 'package-menu-clear-filter)
- (define-key map (kbd "/ a") 'package-menu-filter-by-archive)
- (define-key map (kbd "/ d") 'package-menu-filter-by-description)
- (define-key map (kbd "/ k") 'package-menu-filter-by-keyword)
- (define-key map (kbd "/ N") 'package-menu-filter-by-name-or-description)
- (define-key map (kbd "/ n") 'package-menu-filter-by-name)
- (define-key map (kbd "/ s") 'package-menu-filter-by-status)
- (define-key map (kbd "/ v") 'package-menu-filter-by-version)
- (define-key map (kbd "/ m") 'package-menu-filter-marked)
- (define-key map (kbd "/ u") 'package-menu-filter-upgradable)
- map)
- "Local keymap for `package-menu-mode' buffers.")
+(defvar-keymap package-menu-mode-map
+ :doc "Local keymap for `package-menu-mode' buffers."
+ :parent tabulated-list-mode-map
+ "C-m" #'package-menu-describe-package
+ "u" #'package-menu-mark-unmark
+ "DEL" #'package-menu-backup-unmark
+ "d" #'package-menu-mark-delete
+ "i" #'package-menu-mark-install
+ "U" #'package-menu-mark-upgrades
+ "r" #'revert-buffer
+ "~" #'package-menu-mark-obsolete-for-deletion
+ "w" #'package-browse-url
+ "x" #'package-menu-execute
+ "h" #'package-menu-quick-help
+ "H" #'package-menu-hide-package
+ "?" #'package-menu-describe-package
+ "(" #'package-menu-toggle-hiding
+ "/ /" #'package-menu-clear-filter
+ "/ 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)
(easy-menu-define package-menu-mode-menu package-menu-mode-map
"Menu for `package-menu-mode'."
'("Package"
["Describe Package" package-menu-describe-package :help "Display information about this package"]
- ["Open Package Homepage" package-browse-url
- :help "Open the homepage of this package"]
+ ["Open Package Website" package-browse-url
+ :help "Open the website of this package"]
["Help" package-menu-quick-help :help "Show short key binding help for package-menu-mode"]
"--"
["Refresh Package List" revert-buffer
@@ -3602,8 +3595,10 @@ packages list, respectively."
(defun package-menu-execute (&optional noquery)
"Perform marked Package Menu actions.
-Packages marked for installation are downloaded and installed;
-packages marked for deletion are removed.
+Packages marked for installation are downloaded and installed,
+packages marked for deletion are removed,
+and packages marked for upgrading are downloaded and upgraded.
+
Optional argument NOQUERY non-nil means do not ask the user to confirm."
(interactive nil package-menu-mode)
(package--ensure-package-menu-mode)
@@ -4187,6 +4182,7 @@ activations need to be changed, such as when `package-load-list' is modified."
(replace-match (if (match-end 1) "" pfile) t t)))
(unless (bolp) (insert "\n"))
(insert ")\n")))
+ (pp `(defvar package-activated-list) (current-buffer))
(pp `(setq package-activated-list
(append ',(mapcar #'package-desc-name package--quickstart-pkgs)
package-activated-list))
@@ -4204,6 +4200,7 @@ activations need to be changed, such as when `package-load-list' is modified."
;; Local\sVariables:
;; version-control: never
;; no-update-autoloads: t
+;; byte-compile-warnings: (not make-local)
;; End:
"))
;; FIXME: Do it asynchronously in an Emacs subprocess, and
@@ -4229,7 +4226,7 @@ beginning of the line."
(package-desc-summary package-desc))))
(defun package-browse-url (desc &optional secondary)
- "Open the home page of the package under point in a browser.
+ "Open the website of the package under point in a browser.
`browse-url' is used to determine the browser to be used.
If SECONDARY (interactively, the prefix), use the secondary browser."
(interactive (list (tabulated-list-get-id)
@@ -4239,7 +4236,7 @@ If SECONDARY (interactively, the prefix), use the secondary browser."
(user-error "No package here"))
(let ((url (cdr (assoc :url (package-desc-extras desc)))))
(unless url
- (user-error "No home page for %s" (package-desc-name desc)))
+ (user-error "No website for %s" (package-desc-name desc)))
(if secondary
(funcall browse-url-secondary-browser-function url)
(browse-url url))))
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 63b187be02b..a3498d2da8d 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -86,7 +86,7 @@
(funcall pf (and me (symbolp me) (edebug-get-spec me))))))
(defun pcase--get-macroexpander (s)
- "Return the macroexpander for pcase pattern head S, or nil"
+ "Return the macroexpander for pcase pattern head S, or nil."
(get s 'pcase-macroexpander))
;;;###autoload
@@ -201,7 +201,11 @@ Emacs Lisp manual for more information and examples."
;;;###autoload
(defmacro pcase-exhaustive (exp &rest cases)
"The exhaustive version of `pcase' (which see).
-If EXP fails to match any of the patterns in CASES, an error is signaled."
+If EXP fails to match any of the patterns in CASES, an error is
+signaled.
+
+In contrast, `pcase' will return nil if there is no match, but
+not signal an error."
(declare (indent 1) (debug pcase))
(let* ((x (gensym "x"))
(pcase--dontwarn-upats (cons x pcase--dontwarn-upats)))
diff --git a/lisp/emacs-lisp/pp.el b/lisp/emacs-lisp/pp.el
index 0bf774dffd8..8464b5a5198 100644
--- a/lisp/emacs-lisp/pp.el
+++ b/lisp/emacs-lisp/pp.el
@@ -33,22 +33,43 @@
(defcustom pp-escape-newlines t
"Value of `print-escape-newlines' used by pp-* functions."
+ :type 'boolean)
+
+(defcustom pp-max-width t
+ "Max width to use when formatting.
+If nil, there's no max width. If t, use the window width.
+Otherwise this should be a number."
+ :type '(choice (const :tag "none" nil)
+ (const :tag "window width" t)
+ number)
+ :version "29.1")
+
+(defcustom pp-use-max-width nil
+ "If non-nil, `pp'-related functions will try to fold lines.
+The target width is given by the `pp-max-width' variable."
:type 'boolean
- :group 'pp)
+ :version "29.1")
+
+(defvar pp--inhibit-function-formatting nil)
;;;###autoload
(defun pp-to-string (object)
"Return a string containing the pretty-printed representation of OBJECT.
OBJECT can be any Lisp object. Quoting characters are used as needed
to make output that `read' can handle, whenever this is possible."
- (with-temp-buffer
- (lisp-mode-variables nil)
- (set-syntax-table emacs-lisp-mode-syntax-table)
- (let ((print-escape-newlines pp-escape-newlines)
- (print-quoted t))
- (prin1 object (current-buffer)))
- (pp-buffer)
- (buffer-string)))
+ (if pp-use-max-width
+ (let ((pp--inhibit-function-formatting t))
+ (with-temp-buffer
+ (pp-emacs-lisp-code object)
+ (buffer-string)))
+ (with-temp-buffer
+ (lisp-mode-variables nil)
+ (set-syntax-table emacs-lisp-mode-syntax-table)
+ (let ((print-escape-newlines pp-escape-newlines)
+ (print-quoted t))
+ (prin1 object (current-buffer)))
+ (pp-buffer)
+ (buffer-string))))
;;;###autoload
(defun pp-buffer ()
@@ -56,7 +77,6 @@ to make output that `read' can handle, whenever this is possible."
(interactive)
(goto-char (point-min))
(while (not (eobp))
- ;; (message "%06d" (- (point-max) (point)))
(cond
((ignore-errors (down-list 1) t)
(save-excursion
@@ -82,11 +102,21 @@ to make output that `read' can handle, whenever this is possible."
"Output the pretty-printed representation of OBJECT, any Lisp object.
Quoting characters are printed as needed to make output that `read'
can handle, whenever this is possible.
+
+This function does not apply special formatting rules for Emacs
+Lisp code. See `pp-emacs-lisp-code' instead.
+
+By default, this function won't limit the line length of lists
+and vectors. Bind `pp-use-max-width' to a non-nil value to do so.
+
Output stream is STREAM, or value of `standard-output' (which see)."
(princ (pp-to-string object) (or stream standard-output)))
-(defun pp-display-expression (expression out-buffer-name)
+;;;###autoload
+(defun pp-display-expression (expression out-buffer-name &optional lisp)
"Prettify and display EXPRESSION in an appropriate way, depending on length.
+If LISP, format with `pp-emacs-lisp-code'; use `pp' otherwise.
+
If a temporary buffer is needed for representation, it will be named
after OUT-BUFFER-NAME."
(let* ((old-show-function temp-buffer-show-function)
@@ -110,11 +140,13 @@ after OUT-BUFFER-NAME."
(select-window window)
(run-hooks 'temp-buffer-show-hook))
(when (window-live-p old-selected)
- (select-window old-selected))
- (message "See buffer %s." out-buffer-name)))
+ (select-window old-selected))))
(message "%s" (buffer-substring (point-min) (point))))))))
(with-output-to-temp-buffer out-buffer-name
- (pp expression)
+ (if lisp
+ (with-current-buffer standard-output
+ (pp-emacs-lisp-code expression))
+ (pp expression))
(with-current-buffer standard-output
(emacs-lisp-mode)
(setq buffer-read-only nil)
@@ -179,6 +211,188 @@ Ignores leading comment characters."
(insert (pp-to-string (macroexpand-1 (pp-last-sexp))))
(pp-macroexpand-expression (pp-last-sexp))))
+;;;###autoload
+(defun pp-emacs-lisp-code (sexp)
+ "Insert SEXP into the current buffer, formatted as Emacs Lisp code.
+Use the `pp-max-width' variable to control the desired line length."
+ (require 'edebug)
+ (let ((obuf (current-buffer)))
+ (with-temp-buffer
+ (emacs-lisp-mode)
+ (pp--insert-lisp sexp)
+ (insert "\n")
+ (goto-char (point-min))
+ (indent-sexp)
+ (while (re-search-forward " +$" nil t)
+ (replace-match ""))
+ (insert-into-buffer obuf))))
+
+(defun pp--insert-lisp (sexp)
+ (cl-case (type-of sexp)
+ (vector (pp--format-vector sexp))
+ (cons (cond
+ ((consp (cdr sexp))
+ (if (and (length= sexp 2)
+ (eq (car sexp) 'quote))
+ (cond
+ ((symbolp (cadr sexp))
+ (let ((print-quoted t))
+ (prin1 sexp (current-buffer))))
+ ((consp (cadr sexp))
+ (insert "'")
+ (pp--format-list (cadr sexp)
+ (set-marker (make-marker) (1- (point))))))
+ (pp--format-list sexp)))
+ (t
+ (princ sexp (current-buffer)))))
+ ;; Print some of the smaller integers as characters, perhaps?
+ (integer
+ (if (<= ?0 sexp ?z)
+ (let ((print-integers-as-characters t))
+ (princ sexp (current-buffer)))
+ (princ sexp (current-buffer))))
+ (string
+ (let ((print-escape-newlines t))
+ (prin1 sexp (current-buffer))))
+ (otherwise (princ sexp (current-buffer)))))
+
+(defun pp--format-vector (sexp)
+ (insert "[")
+ (cl-loop for i from 0
+ for element across sexp
+ do (pp--insert (and (> i 0) " ") element))
+ (insert "]"))
+
+(defun pp--format-list (sexp &optional start)
+ (if (and (symbolp (car sexp))
+ (not pp--inhibit-function-formatting)
+ (not (keywordp (car sexp))))
+ (pp--format-function sexp)
+ (insert "(")
+ (pp--insert start (pop sexp))
+ (while sexp
+ (pp--insert " " (pop sexp)))
+ (insert ")")))
+
+(defun pp--format-function (sexp)
+ (let* ((sym (car sexp))
+ (edebug (get sym 'edebug-form-spec))
+ (indent (get sym 'lisp-indent-function))
+ (doc (get sym 'doc-string-elt)))
+ (when (eq indent 'defun)
+ (setq indent 2))
+ ;; We probably want to keep all the elements before the doc string
+ ;; on a single line.
+ (when doc
+ (setq indent (1- doc)))
+ ;; Special-case closures -- these shouldn't really exist in actual
+ ;; source code, so there's no indentation information. But make
+ ;; them output slightly better.
+ (when (and (not indent)
+ (eq sym 'closure))
+ (setq indent 0))
+ (pp--insert "(" sym)
+ (pop sexp)
+ ;; Get the first entries on the first line.
+ (if indent
+ (pp--format-definition sexp indent edebug)
+ (let ((prev 0))
+ (while sexp
+ (let ((start (point)))
+ ;; Don't put sexps on the same line as a multi-line sexp
+ ;; preceding it.
+ (pp--insert (if (> prev 1) "\n" " ")
+ (pop sexp))
+ (setq prev (count-lines start (point)))))))
+ (insert ")")))
+
+(defun pp--format-definition (sexp indent edebug)
+ (while (and (cl-plusp indent)
+ sexp)
+ (insert " ")
+ ;; We don't understand all the edebug specs.
+ (unless (consp edebug)
+ (setq edebug nil))
+ (if (and (consp (car edebug))
+ (eq (caar edebug) '&rest))
+ (pp--insert-binding (pop sexp))
+ (if (null (car sexp))
+ (insert "()")
+ (pp--insert-lisp (car sexp)))
+ (pop sexp))
+ (pop edebug)
+ (cl-decf indent))
+ (when (stringp (car sexp))
+ (insert "\n")
+ (prin1 (pop sexp) (current-buffer)))
+ ;; Then insert the rest with line breaks before each form.
+ (while sexp
+ (insert "\n")
+ (if (keywordp (car sexp))
+ (progn
+ (pp--insert-lisp (pop sexp))
+ (when sexp
+ (pp--insert " " (pop sexp))))
+ (pp--insert-lisp (pop sexp)))))
+
+(defun pp--insert-binding (sexp)
+ (insert "(")
+ (while sexp
+ (if (consp (car sexp))
+ ;; Newlines after each (...) binding.
+ (progn
+ (pp--insert-lisp (car sexp))
+ (when (cdr sexp)
+ (insert "\n")))
+ ;; Keep plain symbols on the same line.
+ (pp--insert " " (car sexp)))
+ (pop sexp))
+ (insert ")"))
+
+(defun pp--insert (delim &rest things)
+ (let ((start (if (markerp delim)
+ (prog1
+ delim
+ (setq delim nil))
+ (point-marker))))
+ (when delim
+ (insert delim))
+ (dolist (thing things)
+ (pp--insert-lisp thing))
+ ;; We need to indent what we have so far to see if we have to fold.
+ (pp--indent-buffer)
+ (when (> (current-column) (pp--max-width))
+ (save-excursion
+ (goto-char start)
+ (unless (looking-at "[ \t]+$")
+ (insert "\n"))
+ (pp--indent-buffer)
+ (goto-char (point-max))
+ ;; If we're still too wide, then go up one step and try to
+ ;; insert a newline there.
+ (when (> (current-column) (pp--max-width))
+ (condition-case ()
+ (backward-up-list 1)
+ (:success (when (looking-back " " 2)
+ (insert "\n")))
+ (error nil)))))))
+
+(defun pp--max-width ()
+ (cond ((numberp pp-max-width)
+ pp-max-width)
+ ((null pp-max-width)
+ most-positive-fixnum)
+ ((eq pp-max-width t)
+ (window-width))
+ (t
+ (error "Invalid pp-max-width value: %s" pp-max-width))))
+
+(defun pp--indent-buffer ()
+ (goto-char (point-min))
+ (while (not (eobp))
+ (lisp-indent-line)
+ (forward-line 1)))
+
(provide 'pp) ; so (require 'pp) works
;;; pp.el ends here
diff --git a/lisp/emacs-lisp/re-builder.el b/lisp/emacs-lisp/re-builder.el
index aec438ed994..9be6ac649f3 100644
--- a/lisp/emacs-lisp/re-builder.el
+++ b/lisp/emacs-lisp/re-builder.el
@@ -274,8 +274,8 @@ Except for Lisp syntax this is the same as `reb-regexp'.")
emacs-lisp-mode "RE Builder Lisp"
"Major mode for interactively building symbolic Regular Expressions."
;; Pull in packages as needed
- (cond ((memq reb-re-syntax '(sregex rx)) ; rx-to-string is autoloaded
- (require 'rx))) ; require rx anyway
+ (when (eq reb-re-syntax 'rx) ; rx-to-string is autoloaded
+ (require 'rx)) ; require rx anyway
(reb-mode-common))
(defvar reb-subexp-mode-map
@@ -307,8 +307,8 @@ Except for Lisp syntax this is the same as `reb-regexp'.")
(eq 'color (frame-parameter nil 'display-type)))
(defsubst reb-lisp-syntax-p ()
- "Return non-nil if RE Builder uses a Lisp syntax."
- (memq reb-re-syntax '(sregex rx)))
+ "Return non-nil if RE Builder uses `rx' syntax."
+ (eq reb-re-syntax 'rx))
(defmacro reb-target-binding (symbol)
"Return binding for SYMBOL in the RE Builder target buffer."
@@ -448,7 +448,8 @@ provided in the Commentary section of this library."
(setq reb-subexp-mode t)
(reb-update-modestring)
(use-local-map reb-subexp-mode-map)
- (message "`0'-`9' to display subexpressions `q' to quit subexp mode"))
+ (message (substitute-command-keys
+ "\\`0'-\\`9' to display subexpressions \\`q' to quit subexp mode")))
(defun reb-show-subexp (subexp &optional pause)
"Visually show limit of subexpression SUBEXP of recent search.
@@ -482,11 +483,11 @@ Optional argument SYNTAX must be specified if called non-interactively."
(list (intern
(completing-read
(format-prompt "Select syntax" reb-re-syntax)
- '(read string sregex rx)
+ '(read string rx)
nil t nil nil (symbol-name reb-re-syntax)
'reb-change-syntax-hist))))
- (if (memq syntax '(read string sregex rx))
+ (if (memq syntax '(read string rx))
(let ((buffer (get-buffer reb-buffer)))
(setq reb-re-syntax syntax)
(when buffer
@@ -605,9 +606,9 @@ optional fourth argument FORCE is non-nil."
(defun reb-cook-regexp (re)
"Return RE after processing it according to `reb-re-syntax'."
- (cond ((memq reb-re-syntax '(sregex rx))
- (rx-to-string (eval (car (read-from-string re)))))
- (t re)))
+ (if (eq reb-re-syntax 'rx)
+ (rx-to-string (eval (car (read-from-string re))))
+ re))
(defun reb-update-regexp ()
"Update the regexp for the target buffer.
diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el
index 071d390f0e4..c48052dee9e 100644
--- a/lisp/emacs-lisp/rx.el
+++ b/lisp/emacs-lisp/rx.el
@@ -1266,7 +1266,8 @@ Zero-width assertions: these all match the empty string in specific places.
(literal EXPR) Match the literal string from evaluating EXPR at run time.
(regexp EXPR) Match the string regexp from evaluating EXPR at run time.
-(eval EXPR) Match the rx sexp from evaluating EXPR at compile time.
+(eval EXPR) Match the rx sexp from evaluating EXPR at macro-expansion
+ (compile) time.
Additional constructs can be defined using `rx-define' and `rx-let',
which see.
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index f0dc283f57d..451ff196316 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -4,7 +4,7 @@
;; Author: Nicolas Petton <nicolas@petton.fr>
;; Keywords: sequences
-;; Version: 2.22
+;; Version: 2.23
;; Package: seq
;; Maintainer: emacs-devel@gnu.org
@@ -468,6 +468,18 @@ negative integer or 0, nil is returned."
(nreverse result))))
;;;###autoload
+(cl-defgeneric seq-union (sequence1 sequence2 &optional testfn)
+ "Return a list of all elements that appear in either SEQUENCE1 or SEQUENCE2.
+Equality is defined by TESTFN if non-nil or by `equal' if nil."
+ (let* ((accum (lambda (acc elt)
+ (if (seq-contains-p acc elt testfn)
+ acc
+ (cons elt acc))))
+ (result (seq-reduce accum sequence2
+ (seq-reduce accum sequence1 '()))))
+ (nreverse result)))
+
+;;;###autoload
(cl-defgeneric seq-intersection (sequence1 sequence2 &optional testfn)
"Return a list of the elements that appear in both SEQUENCE1 and SEQUENCE2.
Equality is defined by TESTFN if non-nil or by `equal' if nil."
@@ -478,7 +490,6 @@ Equality is defined by TESTFN if non-nil or by `equal' if nil."
(seq-reverse sequence1)
'()))
-;;;###autoload
(cl-defgeneric seq-difference (sequence1 sequence2 &optional testfn)
"Return a list of the elements that appear in SEQUENCE1 but not in SEQUENCE2.
Equality is defined by TESTFN if non-nil or by `equal' if nil."
@@ -517,7 +528,7 @@ SEQUENCE must be a sequence of numbers or markers."
(apply #'max (seq-into sequence 'list)))
(defun seq--count-successive (pred sequence)
- "Return the number of successive elements for which (PRED element) is non-nil in SEQUENCE."
+ "Count successive elements for which (PRED element) is non-nil in SEQUENCE."
(let ((n 0)
(len (seq-length sequence)))
(while (and (< n len)
@@ -526,7 +537,7 @@ SEQUENCE must be a sequence of numbers or markers."
n))
(defun seq--make-pcase-bindings (args)
- "Return a list of bindings of the variables in ARGS to the elements of a sequence."
+ "Return list of bindings of the variables in ARGS to the elements of a sequence."
(let ((bindings '())
(index 0)
(rest-marker nil))
@@ -558,6 +569,7 @@ SEQUENCE must be a sequence of numbers or markers."
If no element is found, return nil."
(ignore-errors (seq-elt sequence n)))
+;;;###autoload
(cl-defgeneric seq-random-elt (sequence)
"Return a random element from SEQUENCE.
Signal an error if SEQUENCE is empty."
diff --git a/lisp/emacs-lisp/shadow.el b/lisp/emacs-lisp/shadow.el
index 02f2ad3d816..1fbe946a7f9 100644
--- a/lisp/emacs-lisp/shadow.el
+++ b/lisp/emacs-lisp/shadow.el
@@ -31,13 +31,13 @@
;; a file with the same name in a later load-path directory. When
;; this is unintentional, it may result in problems that could have
;; been easily avoided. This occurs often (to me) when installing a
-;; new version of emacs and something in the site-lisp directory
-;; has been updated and added to the emacs distribution. The old
-;; version, now outdated, shadows the new one. This is obviously
+;; new version of Emacs and something in the site-lisp directory
+;; has been updated and added to the Emacs distribution. The old
+;; version, now outdated, shadows the new one. This is obviously
;; undesirable.
;;
;; The `list-load-path-shadows' function was run when you installed
-;; this version of emacs. To run it by hand in emacs:
+;; this version of Emacs. To run it by hand in emacs:
;;
;; M-x list-load-path-shadows
;;
@@ -151,9 +151,6 @@ See the documentation for `list-load-path-shadows' for further information."
;; Return the list of shadowings.
shadows))
-(define-obsolete-function-alias 'find-emacs-lisp-shadows
- 'load-path-shadows-find "23.3")
-
;; Return true if neither file exists, or if both exist and have identical
;; contents.
(defun load-path-shadows-same-file-or-nonexistent (f1 f2)
@@ -181,7 +178,7 @@ See the documentation for `list-load-path-shadows' for further information."
"Keywords to highlight in `load-path-shadows-mode'.")
(define-derived-mode load-path-shadows-mode fundamental-mode "LP-Shadows"
- "Major mode for load-path shadows buffer."
+ "Major mode for `load-path' shadows buffer."
(setq-local font-lock-defaults
'((load-path-shadows-font-lock-keywords)))
(setq buffer-undo-list t
diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el
index 7d4a69f42a9..b9e000cc05f 100644
--- a/lisp/emacs-lisp/shortdoc.el
+++ b/lisp/emacs-lisp/shortdoc.el
@@ -71,6 +71,7 @@ string, it'll be inserted as is, then the string will be `read',
and then evaluated.
There can be any number of :example/:result elements."
+ (declare (indent defun))
`(progn
(setq shortdoc--groups (delq (assq ',group shortdoc--groups)
shortdoc--groups))
@@ -195,6 +196,13 @@ There can be any number of :example/:result elements."
:eval (substring-no-properties (propertize "foobar" 'face 'bold) 0 3))
(try-completion
:eval (try-completion "foo" '("foobar" "foozot" "gazonk")))
+ "Unicode Strings"
+ (string-glyph-split
+ :eval (string-glyph-split "Hello, 👼🏻🧑🏼‍🤝‍🧑🏻"))
+ (string-glyph-compose
+ :eval (string-glyph-compose "Å"))
+ (string-glyph-decompose
+ :eval (string-glyph-decompose "Å"))
"Predicates for Strings"
(string-equal
:eval (string-equal "foo" "foo"))
@@ -241,7 +249,14 @@ There can be any number of :example/:result elements."
:eval (number-to-string 42))
"Data About Strings"
(length
- :eval (length "foo"))
+ :eval (length "foo")
+ :eval (length "avocado: 🥑"))
+ (string-width
+ :eval (string-width "foo")
+ :eval (string-width "avocado: 🥑"))
+ (string-pixel-width
+ :eval (string-pixel-width "foo")
+ :eval (string-pixel-width "avocado: 🥑"))
(string-search
:eval (string-search "bar" "foobarzot"))
(assoc-string
@@ -271,6 +286,9 @@ There can be any number of :example/:result elements."
:eval (file-name-base "/tmp/foo.txt"))
(file-relative-name
:eval (file-relative-name "/tmp/foo" "/tmp"))
+ (file-name-split
+ :eval (file-name-split "/tmp/foo")
+ :eval (file-name-split "foo/bar"))
(make-temp-name
:eval (make-temp-name "/tmp/foo-"))
(file-name-concat
@@ -348,6 +366,9 @@ There can be any number of :example/:result elements."
(file-newer-than-file-p
:no-eval (file-newer-than-file-p "/tmp/foo" "/tmp/bar")
:eg-result nil)
+ (file-has-changed-p
+ :no-eval (file-has-changed-p "/tmp/foo")
+ :eg-result t)
(file-equal-p
:no-eval (file-equal-p "/tmp/foo" "/tmp/bar")
:eg-result nil)
@@ -495,6 +516,9 @@ There can be any number of :example/:result elements."
:eval (list 1 2 3))
(number-sequence
:eval (number-sequence 5 8))
+ (ensure-list
+ :eval (ensure-list "foo")
+ :eval (ensure-list '(1 2 3)))
"Operations on Lists"
(append
:eval (append '("foo" "bar") '("zot")))
@@ -644,10 +668,12 @@ There can be any number of :example/:result elements."
(define-short-documentation-group vector
+ "Making Vectors"
(make-vector
:eval (make-vector 5 "foo"))
(vector
:eval (vector 1 "b" 3))
+ "Operations on Vectors"
(vectorp
:eval (vectorp [1])
:eval (vectorp "1"))
@@ -657,13 +683,16 @@ There can be any number of :example/:result elements."
:eval (append [1 2] nil))
(length
:eval (length [1 2 3]))
- (mapcar
- :eval (mapcar #'identity [1 2 3]))
- (reduce
- :eval (reduce #'+ [1 2 3]))
+ (seq-reduce
+ :eval (seq-reduce #'+ [1 2 3] 0))
(seq-subseq
:eval (seq-subseq [1 2 3 4 5] 1 3)
- :eval (seq-subseq [1 2 3 4 5] 1)))
+ :eval (seq-subseq [1 2 3 4 5] 1))
+ "Mapping Over Vectors"
+ (mapcar
+ :eval (mapcar #'identity [1 2 3]))
+ (mapc
+ :eval (mapc #'insert ["1" "2" "3"])))
(define-short-documentation-group regexp
"Matching Strings"
@@ -809,6 +838,8 @@ There can be any number of :example/:result elements."
:eval (seq-remove #'numberp '(1 2 c d 5)))
(seq-group-by
:eval (seq-group-by #'cl-plusp '(-1 2 3 -4 -5 6)))
+ (seq-union
+ :eval (seq-union '(1 2 3) '(3 5)))
(seq-difference
:eval (seq-difference '(1 2 3) '(2 3 4)))
(seq-intersection
@@ -889,6 +920,9 @@ There can be any number of :example/:result elements."
:eg-result 67)
(char-after
:eval (char-after 45))
+ (get-byte
+ :no-eval (get-byte 45)
+ :eg-result-string "#xff")
"Altering Buffers"
(delete-region
:no-value (delete-region (point-min) (point-max)))
@@ -1150,6 +1184,82 @@ There can be any number of :example/:result elements."
(sqrt
:eval (sqrt -1)))
+(define-short-documentation-group text-properties
+ "Examining Text Properties"
+ (get-text-property
+ :eval (get-text-property 0 'foo (propertize "x" 'foo t)))
+ (get-char-property
+ :eval (get-char-property 0 'foo (propertize "x" 'foo t)))
+ (get-pos-property
+ :eval (get-pos-property 0 'foo (propertize "x" 'foo t)))
+ (get-char-property-and-overlay
+ :eval (get-char-property-and-overlay 0 'foo (propertize "x" 'foo t)))
+ (text-properties-at
+ :eval (text-properties-at (point)))
+ "Changing Text Properties"
+ (put-text-property
+ :eval (let ((s "abc")) (put-text-property 0 1 'foo t s) s)
+ :no-eval (put-text-property (point) (1+ (point)) 'face 'error))
+ (add-text-properties
+ :no-eval (add-text-properties (point) (1+ (point)) '(face error)))
+ (remove-text-properties
+ :no-eval (remove-text-properties (point) (1+ (point)) '(face nil)))
+ (remove-list-of-text-properties
+ :no-eval (remove-list-of-text-properties (point) (1+ (point)) '(face font-lock-face)))
+ (set-text-properties
+ :no-eval (set-text-properties (point) (1+ (point)) '(face error)))
+ (add-face-text-property
+ (add-face-text-property START END '(:foreground "green")))
+ (propertize
+ :eval (propertize "foo" 'face 'italic 'mouse-face 'bold-italic))
+ "Searching for Text Properties"
+ (next-property-change
+ :no-eval (next-property-change (point) (current-buffer)))
+ (previous-property-change
+ :no-eval (previous-property-change (point) (current-buffer)))
+ (next-single-property-change
+ :no-eval (next-single-property-change (point) 'face (current-buffer)))
+ (previous-single-property-change
+ :no-eval (previous-single-property-change (point) 'face (current-buffer)))
+ ;; TODO: There are some more that could be added here.
+ (text-property-search-forward
+ :no-eval (text-property-search-forward 'face nil t))
+ (text-property-search-backward
+ :no-eval (text-property-search-backward 'face nil t)))
+
+(define-short-documentation-group keymaps
+ "Defining keymaps"
+ (define-keymap
+ :no-eval (define-keymap "C-c C-c" #'quit-buffer))
+ (defvar-keymap
+ :no-eval (defvar-keymap my-keymap "C-c C-c" #'quit-buffer))
+ "Setting keys"
+ (keymap-set
+ :no-eval (keymap-set map "C-c C-c" #'quit-buffer))
+ (keymap-local-set
+ :no-eval (keymap-local-set "C-c C-c" #'quit-buffer))
+ (keymap-global-set
+ :no-eval (keymap-global-set "C-c C-c" #'quit-buffer))
+ (keymap-unset
+ :no-eval (keymap-unset map "C-c C-c"))
+ (keymap-local-unset
+ :no-eval (keymap-local-unset "C-c C-c"))
+ (keymap-global-unset
+ :no-eval (keymap-global-unset "C-c C-c"))
+ (keymap-substitute
+ :no-eval (keymap-substitute map "C-c C-c" "M-a"))
+ (keymap-set-after
+ :no-eval (keymap-set-after map "<separator-2>" menu-bar-separator))
+ "Predicates"
+ (keymapp
+ :eval (keymapp (define-keymap)))
+ (key-valid-p
+ :eval (key-valid-p "C-c C-c")
+ :eval (key-valid-p "C-cC-c"))
+ "Lookup"
+ (keymap-lookup
+ :eval (keymap-lookup (current-global-map) "C-x x g")))
+
;;;###autoload
(defun shortdoc-display-group (group &optional function)
"Pop to a buffer with short documentation summary for functions in GROUP.
@@ -1268,11 +1378,11 @@ function's documentation in the Info manual")))
(princ value (current-buffer))
(insert "\n"))
(:eg-result
- (insert " eg. " double-arrow " ")
+ (insert " e.g. " double-arrow " ")
(prin1 value (current-buffer))
(insert "\n"))
(:eg-result-string
- (insert " eg. " double-arrow " ")
+ (insert " e.g. " double-arrow " ")
(princ value (current-buffer))
(insert "\n")))))
;; Insert the arglist after doing the evals, in case that's pulled
@@ -1313,14 +1423,12 @@ Example:
(setq slist (cdr slist)))
(setcdr slist (cons elem (cdr slist))))))
-(defvar shortdoc-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd "n") 'shortdoc-next)
- (define-key map (kbd "p") 'shortdoc-previous)
- (define-key map (kbd "C-c C-n") 'shortdoc-next-section)
- (define-key map (kbd "C-c C-p") 'shortdoc-previous-section)
- map)
- "Keymap for `shortdoc-mode'.")
+(defvar-keymap shortdoc-mode-map
+ :doc "Keymap for `shortdoc-mode'."
+ "n" #'shortdoc-next
+ "p" #'shortdoc-previous
+ "C-c C-n" #'shortdoc-next-section
+ "C-c C-p" #'shortdoc-previous-section)
(define-derived-mode shortdoc-mode special-mode "shortdoc"
"Mode for shortdoc."
diff --git a/lisp/emacs-lisp/shorthands.el b/lisp/emacs-lisp/shorthands.el
new file mode 100644
index 00000000000..e9f5880ab29
--- /dev/null
+++ b/lisp/emacs-lisp/shorthands.el
@@ -0,0 +1,80 @@
+;;; shorthands.el --- Read code considering Elisp shorthands -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: João Távora <joaotavora@gmail.com>
+;; Keywords: lisp
+
+;; 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:
+
+;; Basic helpers for loading files with Shorthands.
+
+;;; Code:
+(require 'files)
+(require 'mule)
+(eval-when-compile (require 'cl-lib))
+
+(defun hack-read-symbol-shorthands ()
+ "Compute `read-symbol-shorthands' from Local Variables section."
+ ;; FIXME: relies on the `hack-local-variables--find-variables'
+ ;; detail of files.el. That function should be exported,
+ ;; possibly be refactored into two parts, since we're only
+ ;; interested in basic "Local Variables" parsing.
+ (alist-get 'read-symbol-shorthands (hack-local-variables--find-variables)))
+
+(setq hack-read-symbol-shorthands-function #'hack-read-symbol-shorthands)
+
+
+;; FIXME: move this all to progmodes/elisp-mode.el? OTOH it'd make
+;; more sense there, OTOH all the elisp font-lock stuff is actually in
+;; lisp/emacs-lisp/lisp-mode.el, which isn't right either. So
+;; shorthand font-locking logic is probably better here for now.
+
+(defface elisp-shorthand-font-lock-face
+ '((t :inherit font-lock-keyword-face :foreground "cyan"))
+ "Face for highlighting shorthands in Emacs Lisp."
+ :version "28.1"
+ :group 'font-lock-faces)
+
+(defun shorthands--mismatch-from-end (str1 str2)
+ (cl-loop with l1 = (length str1) with l2 = (length str2)
+ for i from 1
+ for i1 = (- l1 i) for i2 = (- l2 i)
+ while (and (>= i1 0) (>= i2 0) (eq (aref str1 i1) (aref str2 i2)))
+ finally (return (1- i))))
+
+(defun shorthands-font-lock-shorthands (limit)
+ (when read-symbol-shorthands
+ (while (re-search-forward
+ (eval-when-compile
+ (concat "\\_<\\(" lisp-mode-symbol-regexp "\\)\\_>"))
+ limit t)
+ (let* ((existing (get-text-property (match-beginning 1) 'face))
+ (probe (and (not (memq existing '(font-lock-comment-face
+ font-lock-string-face)))
+ (intern-soft (match-string 1))))
+ (sname (and probe (symbol-name probe)))
+ (mm (and sname (shorthands--mismatch-from-end
+ (match-string 1) sname))))
+ (unless (or (null mm) (= mm (length sname)))
+ (add-face-text-property (match-beginning 1) (1+ (- (match-end 1) mm))
+ 'elisp-shorthand-font-lock-face))))))
+
+(font-lock-add-keywords 'emacs-lisp-mode '((shorthands-font-lock-shorthands)) t)
+
+;;; shorthands.el ends here
diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el
index d775f152b36..8e14faea3a4 100644
--- a/lisp/emacs-lisp/smie.el
+++ b/lisp/emacs-lisp/smie.el
@@ -1302,7 +1302,7 @@ Only meaningful when called from within `smie-rules-function'."
(let ((tok (funcall smie-forward-token-function)))
(unless tok
(with-demoted-errors
- (error "smie-rule-separator: can't skip token %s"
+ (error "smie-rule-separator: Can't skip token %s"
smie--token))))
(skip-chars-forward " ")
(unless (eolp) (point)))))
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index 4204d20249d..b53245b9b5f 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -62,7 +62,7 @@ Is equivalent to:
(+ (- (/ (+ 5 20) 25)) 40)
Note how the single `-' got converted into a list before
threading."
- (declare (indent 1)
+ (declare (indent 0)
(debug (form &rest [&or symbolp (sexp &rest form)])))
`(internal--thread-argument t ,@forms))
@@ -79,7 +79,7 @@ Is equivalent to:
(+ 40 (- (/ 25 (+ 20 5))))
Note how the single `-' got converted into a list before
threading."
- (declare (indent 1) (debug thread-first))
+ (declare (indent 0) (debug thread-first))
`(internal--thread-argument nil ,@forms))
(defsubst internal--listify (elt)
@@ -107,7 +107,7 @@ If ELT is of the form ((EXPR)), listify (EXPR) with a dummy symbol."
(defun internal--build-binding (binding prev-var)
"Check and build a single BINDING with PREV-VAR."
(thread-first
- binding
+ binding
internal--listify
internal--check-binding
(internal--build-binding-value-form prev-var)))
@@ -208,7 +208,9 @@ The variable list SPEC is the same as in `if-let'."
(string= string ""))
(defsubst string-join (strings &optional separator)
- "Join all STRINGS using 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))
(define-obsolete-function-alias 'string-reverse 'reverse "25.1")
@@ -264,13 +266,13 @@ result will have lines that are longer than LENGTH."
(buffer-string)))
(defun string-limit (string length &optional end coding-system)
- "Return (up to) a LENGTH substring of STRING.
-If STRING is shorter than or equal to LENGTH, the entire string
-is returned unchanged.
+ "Return a substring of STRING that is (up to) LENGTH characters long.
+If STRING is shorter than or equal to LENGTH characters, return the
+entire string unchanged.
-If STRING is longer than LENGTH, return a substring consisting of
-the first LENGTH characters of STRING. If END is non-nil, return
-the last LENGTH characters instead.
+If STRING is longer than LENGTH characters, return a substring
+consisting of the first LENGTH characters of STRING. If END is
+non-nil, return the last LENGTH characters instead.
If CODING-SYSTEM is non-nil, STRING will be encoded before
limiting, and LENGTH is interpreted as the number of bytes to
@@ -400,6 +402,114 @@ as the new values of the bound variables in the recursive invocation."
(cl-labels ((,name ,fargs . ,body)) #',name)
. ,aargs)))
+(defmacro with-memoization (place &rest code)
+ "Return the value of CODE and stash it in PLACE.
+If PLACE's value is non-nil, then don't bother evaluating CODE
+and return the value found in PLACE instead."
+ (declare (indent 1) (debug (gv-place body)))
+ (gv-letplace (getter setter) place
+ `(or ,getter
+ ,(macroexp-let2 nil val (macroexp-progn code)
+ `(progn
+ ,(funcall setter val)
+ ,val)))))
+
+;;;###autoload
+(defun ensure-empty-lines (&optional lines)
+ "Ensure that there are LINES number of empty lines before point.
+If LINES is nil or omitted, ensure that there is a single empty
+line before point.
+
+If called interactively, LINES is given by the prefix argument.
+
+If there are more than LINES empty lines before point, the number
+of empty lines is reduced to LINES.
+
+If point is not at the beginning of a line, a newline character
+is inserted before adjusting the number of empty lines."
+ (interactive "p")
+ (unless (bolp)
+ (insert "\n"))
+ (let ((lines (or lines 1))
+ (start (save-excursion
+ (if (re-search-backward "[^\n]" nil t)
+ (+ (point) 2)
+ (point-min)))))
+ (cond
+ ((> (- (point) start) lines)
+ (delete-region (point) (- (point) (- (point) start lines))))
+ ((< (- (point) start) lines)
+ (insert (make-string (- lines (- (point) start)) ?\n))))))
+
+;;;###autoload
+(defun string-pixel-width (string)
+ "Return the width of STRING in pixels."
+ (with-temp-buffer
+ (insert string)
+ (car (buffer-text-pixel-size nil nil t))))
+
+;;;###autoload
+(defun string-glyph-split (string)
+ "Split STRING into a list of strings representing separate glyphs.
+This takes into account combining characters and grapheme clusters."
+ (let ((result nil)
+ (start 0)
+ comp)
+ (while (< start (length string))
+ (if (setq comp (find-composition-internal
+ start
+ ;; Don't search backward in the string for the
+ ;; start of the composition.
+ (min (length string) (1+ start))
+ string nil))
+ (progn
+ (push (substring string (car comp) (cadr comp)) result)
+ (setq start (cadr comp)))
+ (push (substring string start (1+ start)) result)
+ (setq start (1+ start))))
+ (nreverse result)))
+
+;;;###autoload
+(defun add-display-text-property (start end prop value
+ &optional object)
+ "Add display property PROP with VALUE to the text from START to END.
+If any text in the region has a non-nil `display' property, those
+properties are retained.
+
+If OBJECT is non-nil, it should be a string or a buffer. If nil,
+this defaults to the current buffer."
+ (let ((sub-start start)
+ (sub-end 0)
+ disp)
+ (while (< sub-end end)
+ (setq sub-end (next-single-property-change sub-start 'display object
+ (if (stringp object)
+ (min (length object) end)
+ (min end (point-max)))))
+ (if (not (setq disp (get-text-property sub-start 'display object)))
+ ;; No old properties in this range.
+ (put-text-property sub-start sub-end 'display (list prop value))
+ ;; We have old properties.
+ (let ((vector nil))
+ ;; Make disp into a list.
+ (setq disp
+ (cond
+ ((vectorp disp)
+ (setq vector t)
+ (seq-into disp 'list))
+ ((not (consp (car disp)))
+ (list disp))
+ (t
+ disp)))
+ ;; Remove any old instances.
+ (when-let ((old (assoc prop disp)))
+ (setq disp (delete old disp)))
+ (setq disp (cons (list prop value) disp))
+ (when vector
+ (setq disp (seq-into disp 'vector)))
+ ;; Finally update the range.
+ (put-text-property sub-start sub-end 'display disp)))
+ (setq sub-start sub-end))))
(provide 'subr-x)
diff --git a/lisp/emacs-lisp/tabulated-list.el b/lisp/emacs-lisp/tabulated-list.el
index f0ee78745ac..075fe836f6b 100644
--- a/lisp/emacs-lisp/tabulated-list.el
+++ b/lisp/emacs-lisp/tabulated-list.el
@@ -115,16 +115,25 @@ where:
This should be either a function, or a list.
If a list, each element has the form (ID [DESC1 ... DESCN]),
where:
+
- ID is nil, or a Lisp object uniquely identifying this entry,
which is used to keep the cursor on the \"same\" entry when
rearranging the list. Comparison is done with `equal'.
- Each DESC is a column descriptor, one for each column
- specified in `tabulated-list-format'. A descriptor is either
- a string, which is printed as-is, or a list (LABEL . PROPS),
- which means to use `insert-text-button' to insert a text
- button with label LABEL and button properties PROPS.
- The string, or button label, must not contain any newline.
+ specified in `tabulated-list-format'. The descriptor DESC is
+ one of:
+
+ - A string, which is printed as-is, and must not contain any
+ newlines.
+
+ - An image descriptor (a list), which is used to insert an
+ image (see Info node `(elisp) Image Descriptors').
+
+ - A list (LABEL . PROPS), which means to use
+ `insert-text-button' to insert a text button with label
+ LABEL and button properties PROPS. LABEL must not contain
+ any newlines.
If `tabulated-list-entries' is a function, it is called with no
arguments and must return a list of the above form.")
@@ -256,7 +265,7 @@ Populated by `tabulated-list-init-header'.")
(defvar tabulated-list--header-overlay nil)
(defun tabulated-list-line-number-width ()
- "Return the width taken by display-line-numbers in the current buffer."
+ "Return the width taken by `display-line-numbers' in the current buffer."
;; line-number-display-width returns the value for the selected
;; window, which might not be the window in which the current buffer
;; is displayed.
@@ -271,12 +280,15 @@ Populated by `tabulated-list-init-header'.")
(defun tabulated-list-init-header ()
"Set up header line for the Tabulated List buffer."
;; FIXME: Should share code with tabulated-list-print-col!
- (let ((x (max tabulated-list-padding 0))
- (button-props `(help-echo "Click to sort by column"
- mouse-face header-line-highlight
- keymap ,tabulated-list-sort-button-map))
- (len (length tabulated-list-format))
- (cols nil))
+ (let* ((x (max tabulated-list-padding 0))
+ (button-props `(help-echo "Click to sort by column"
+ mouse-face header-line-highlight
+ keymap ,tabulated-list-sort-button-map))
+ (len (length tabulated-list-format))
+ ;; Pre-compute width for available-space compution.
+ (hcols (mapcar #'car tabulated-list-format))
+ (tabulated-list--near-rows (list hcols hcols))
+ (cols nil))
(if display-line-numbers
(setq x (+ x (tabulated-list-line-number-width))))
(push (propertize " " 'display `(space :align-to ,x)) cols)
@@ -290,9 +302,17 @@ Populated by `tabulated-list-init-header'.")
(props (nthcdr 3 col))
(pad-right (or (plist-get props :pad-right) 1))
(right-align (plist-get props :right-align))
- (next-x (+ x pad-right width)))
- (when (and (>= lablen 3) (> lablen width) not-last-col)
- (setq label (truncate-string-to-width label (- lablen 1) nil nil t)))
+ (next-x (+ x pad-right width))
+ (available-space
+ (and not-last-col
+ (if right-align
+ width
+ (tabulated-list--available-space width n)))))
+ (when (and (>= lablen 3)
+ not-last-col
+ (> lablen available-space))
+ (setq label (truncate-string-to-width label available-space
+ nil nil t)))
(push
(cond
;; An unsortable column
@@ -481,6 +501,8 @@ changing `tabulated-list-sort-key'."
(forward-line 1)
(delete-region old (point))))))
(setq entries (cdr entries)))
+ (when update
+ (delete-region (point) (point-max)))
(set-buffer-modified-p nil)
;; If REMEMBER-POS was specified, move to the "old" location.
(if saved-pt
@@ -512,6 +534,17 @@ of column descriptors."
beg (point)
`(tabulated-list-id ,id tabulated-list-entry ,cols))))
+(defun tabulated-list--available-space (width n)
+ (let* ((next-col-format (aref tabulated-list-format (1+ n)))
+ (next-col-right-align (plist-get (nthcdr 3 next-col-format)
+ :right-align))
+ (next-col-width (nth 1 next-col-format)))
+ (if next-col-right-align
+ (- (+ width next-col-width)
+ (min next-col-width
+ (tabulated-list--col-local-max-widths (1+ n))))
+ width)))
+
(defun tabulated-list-print-col (n col-desc x)
"Insert a specified Tabulated List entry at point.
N is the column number, COL-DESC is a column descriptor (see
@@ -523,25 +556,17 @@ Return the column number after insertion."
(props (nthcdr 3 format))
(pad-right (or (plist-get props :pad-right) 1))
(right-align (plist-get props :right-align))
- (label (if (stringp col-desc) col-desc (car col-desc)))
+ (label (cond ((stringp col-desc) col-desc)
+ ((eq (car col-desc) 'image) " ")
+ (t (car col-desc))))
(label-width (string-width label))
(help-echo (concat (car format) ": " label))
(opoint (point))
(not-last-col (< (1+ n) (length tabulated-list-format)))
- available-space)
- (when not-last-col
- (let* ((next-col-format (aref tabulated-list-format (1+ n)))
- (next-col-right-align (plist-get (nthcdr 3 next-col-format)
- :right-align))
- (next-col-width (nth 1 next-col-format)))
- (setq available-space
- (if (and (not right-align)
- next-col-right-align)
- (-
- (+ width next-col-width)
- (min next-col-width
- (tabulated-list--col-local-max-widths (1+ n))))
- width))))
+ (available-space (and not-last-col
+ (if right-align
+ width
+ (tabulated-list--available-space width n)))))
;; Truncate labels if necessary (except last column).
;; Don't truncate to `width' if the next column is align-right
;; and has some space left, truncate to `available-space' instead.
@@ -557,17 +582,22 @@ Return the column number after insertion."
'display `(space :align-to ,(+ x shift))))
(setq width (- width shift))
(setq x (+ x shift))))
- (if (stringp col-desc)
- (insert (if (get-text-property 0 'help-echo label)
- label
- (propertize label 'help-echo help-echo)))
- (apply 'insert-text-button label (cdr col-desc)))
+ (cond ((stringp col-desc)
+ (insert (if (get-text-property 0 'help-echo label)
+ label
+ (propertize label 'help-echo help-echo))))
+ ((eq (car col-desc) 'image)
+ (insert (propertize " "
+ 'display col-desc
+ 'help-echo help-echo)))
+ ((apply 'insert-text-button label (cdr col-desc))))
(let ((next-x (+ x pad-right width)))
;; No need to append any spaces if this is the last column.
(when not-last-col
(when (> pad-right 0) (insert (make-string pad-right ?\s)))
(insert (propertize
- (make-string (- width (min width label-width)) ?\s)
+ ;; We need at least one space to align correctly.
+ (make-string (- width (min 1 width label-width)) ?\s)
'display `(space :align-to ,next-x))))
(put-text-property opoint (point) 'tabulated-list-column-name name)
next-x)))
@@ -654,6 +684,10 @@ With a numeric prefix argument N, sort the Nth column.
If the numeric prefix is -1, restore order the list was
originally displayed in."
(interactive "P")
+ (when (and n
+ (or (>= n (length tabulated-list-format))
+ (< n -1)))
+ (user-error "Invalid column number"))
(if (equal n -1)
;; Restore original order.
(progn
diff --git a/lisp/emacs-lisp/testcover.el b/lisp/emacs-lisp/testcover.el
index e75f15140aa..cdd966e51c0 100644
--- a/lisp/emacs-lisp/testcover.el
+++ b/lisp/emacs-lisp/testcover.el
@@ -20,7 +20,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/>.
-
;;; Commentary:
;; * Use `testcover-start' to instrument a Lisp file for coverage testing.
@@ -62,6 +61,8 @@
;; error if these "potentially" 1-valued forms actually return differing
;; values.
+;;; Code:
+
(eval-when-compile (require 'cl-lib))
(require 'edebug)
(provide 'testcover)
@@ -80,8 +81,9 @@
(defcustom testcover-constants
'(nil t emacs-build-time emacs-version emacs-major-version
emacs-minor-version)
- "Variables whose values never change. No brown splotch is shown for
-these. This list is quite incomplete!"
+ "Variables whose values never change.
+No brown splotch is shown for these. This list is quite
+incomplete!"
:group 'testcover
:type '(repeat variable))
@@ -103,8 +105,8 @@ incomplete! Notes: Nobody ever changes the current global map."
(defcustom testcover-noreturn-functions
'(error noreturn throw signal)
- "Subset of `testcover-1value-functions' -- these never return. We mark
-them as having returned nil just before calling them."
+ "Subset of `testcover-1value-functions' -- these never return.
+We mark them as having returned nil just before calling them."
:group 'testcover
:type '(repeat symbol))
@@ -126,25 +128,26 @@ side-effect-free functions should be here."
set set-default set-marker-insertion-type setq setq-default
with-current-buffer with-output-to-temp-buffer with-syntax-table
with-temp-buffer with-temp-file with-temp-message with-timeout)
- "Functions whose return value is the same as their last argument. No
-brown splotch is shown for these if the last argument is a constant or a
-call to one of the `testcover-1value-functions'. This list is probably
-incomplete!"
+ "Functions whose return value is the same as their last argument.
+No brown splotch is shown for these if the last argument is a
+constant or a call to one of the `testcover-1value-functions'.
+This list is probably incomplete!"
:group 'testcover
:type '(repeat symbol))
(defcustom testcover-prog1-functions
'(prog1 unwind-protect)
- "Functions whose return value is the same as their first argument. No
-brown splotch is shown for these if the first argument is a constant or a
-call to one of the `testcover-1value-functions'."
+ "Functions whose return value is the same as their first argument.
+No brown splotch is shown for these if the first argument is a
+constant or a call to one of the `testcover-1value-functions'."
:group 'testcover
:type '(repeat symbol))
(defcustom testcover-potentially-1value-functions
'(add-hook and beep or remove-hook unless when)
- "Functions that are potentially 1-valued. No brown splotch if actually
-1-valued, no error if actually multi-valued."
+ "Functions that are potentially 1-valued.
+No brown splotch if actually 1-valued, no error if actually
+multi-valued."
:group 'testcover
:type '(repeat symbol))
@@ -164,8 +167,7 @@ call to one of the `testcover-1value-functions'."
;;;=========================================================================
(defvar testcover-module-constants nil
- "Symbols declared with defconst in the last file processed by
-`testcover-start'.")
+ "Symbols declared with defconst in the last file processed by `testcover-start'.")
(defvar testcover-module-1value-functions nil
"Symbols declared with defun in the last file processed by
@@ -331,7 +333,7 @@ vectors as well as conses."
;;;=========================================================================
(defun testcover-mark (def)
- "Marks one DEF (a function or macro symbol) to highlight its contained forms
+ "Mark one DEF (a function or macro symbol) to highlight its contained forms
that did not get completely tested during coverage tests.
A marking with the face `testcover-nohits' (default = red) indicates that the
form was never evaluated. A marking using the `testcover-1value' face
@@ -388,7 +390,7 @@ coverage tests. This function creates many overlays."
(error nil))) ;Ignore "No such buffer" errors
(defun testcover-next-mark ()
- "Moves point to next line in current buffer that has a splotch."
+ "Move point to next line in current buffer that has a splotch."
(interactive)
(goto-char (next-overlay-change (point)))
(end-of-line))
diff --git a/lisp/emacs-lisp/thunk.el b/lisp/emacs-lisp/thunk.el
index 7e349d22a49..6f2e42af50b 100644
--- a/lisp/emacs-lisp/thunk.el
+++ b/lisp/emacs-lisp/thunk.el
@@ -30,7 +30,7 @@
;; forms.
;;
;; Use `thunk-delay' to delay the evaluation of a form (requires
-;; lexical-binding), and `thunk-force' to evaluate it. The result of
+;; lexical-binding), and `thunk-force' to evaluate it. The result of
;; the evaluation is cached, and only happens once.
;;
;; Here is an example of a form which evaluation is delayed:
diff --git a/lisp/emacs-lisp/timer.el b/lisp/emacs-lisp/timer.el
index 36de29a73a8..c7d02cc7487 100644
--- a/lisp/emacs-lisp/timer.el
+++ b/lisp/emacs-lisp/timer.el
@@ -29,10 +29,12 @@
(eval-when-compile (require 'cl-lib))
+;; If you change this structure, you also have to change `timerp'
+;; (below) and decode_timer in keyboard.c.
(cl-defstruct (timer
(:constructor nil)
(:copier nil)
- (:constructor timer-create ())
+ (:constructor timer--create ())
(:type vector)
(:conc-name timer--))
;; nil if the timer is active (waiting to be triggered),
@@ -46,11 +48,25 @@
repeat-delay
function args ;What to do when triggered.
idle-delay ;If non-nil, this is an idle-timer.
- psecs)
+ psecs
+ ;; A timer may be created with t as the TIME, which means that we
+ ;; want to run at specific integral multiples of `repeat-delay'. We
+ ;; then have to recompute this (because the machine may have gone to
+ ;; sleep, etc).
+ integral-multiple)
+
+(defun timer-create ()
+ ;; BEWARE: This is not an eta-redex, because `timer--create' is inlinable
+ ;; whereas `timer-create' should not be because we don't want to
+ ;; hardcode the shape of timers in other .elc files.
+ (timer--create))
(defun timerp (object)
"Return t if OBJECT is a timer."
- (and (vectorp object) (= (length object) 9)))
+ (and (vectorp object)
+ ;; Timers are now ten elements, but old .elc code may have
+ ;; shorter versions of `timer-create'.
+ (<= 9 (length object) 10)))
(defsubst timer--check (timer)
(or (timerp timer) (signal 'wrong-type-argument (list #'timerp timer))))
@@ -109,9 +125,12 @@ of SECS seconds since the epoch. SECS may be a fraction."
(time-convert (cons (- more-ticks (% more-ticks trunc-s-ticks)) hz)))))
(defun timer-relative-time (time secs &optional usecs psecs)
- "Advance TIME by SECS seconds and optionally USECS microseconds
-and PSECS picoseconds. SECS may be either an integer or a
-floating point number."
+ "Advance TIME by SECS seconds.
+
+Optionally also advance it by USECS microseconds and PSECS
+picoseconds.
+
+SECS may be either an integer or a floating point number."
(let ((delta secs))
(if (or usecs psecs)
(setq delta (time-add delta (list 0 0 (or usecs 0) (or psecs 0)))))
@@ -122,9 +141,13 @@ floating point number."
(time-less-p (timer--time t1) (timer--time t2)))
(defun timer-inc-time (timer secs &optional usecs psecs)
- "Increment the time set in TIMER by SECS seconds, USECS microseconds,
-and PSECS picoseconds. SECS may be a fraction. If USECS or PSECS are
-omitted, they are treated as zero."
+ "Increment the time set in TIMER by SECS seconds.
+
+Optionally also increment it by USECS microseconds, and PSECS
+picoseconds. If USECS or PSECS are omitted, they are treated as
+zero.
+
+SECS may be a fraction."
(setf (timer--time timer)
(timer-relative-time (timer--time timer) secs usecs psecs)))
@@ -284,6 +307,14 @@ This function is called, by name, directly by the C code."
(if (> repeats timer-max-repeats)
(timer-inc-time timer (* (timer--repeat-delay timer)
repeats)))))
+ ;; If we want integral multiples, we have to recompute
+ ;; the repetition.
+ (when (and (> (length timer) 9) ; Backwards compatible.
+ (timer--integral-multiple timer)
+ (not (timer--idle-delay timer)))
+ (setf (timer--time timer)
+ (timer-next-integral-multiple-of-time
+ nil (timer--repeat-delay timer))))
;; Place it back on the timer-list before running
;; timer--function, so it can cancel-timer itself.
(timer-activate timer t cell)
@@ -320,19 +351,27 @@ This function is called, by name, directly by the C code."
Repeat the action every REPEAT seconds, if REPEAT is non-nil.
REPEAT may be an integer or floating point number.
TIME should be one of:
+
- a string giving today's time like \"11:23pm\"
(the acceptable formats are HHMM, H:MM, HH:MM, HHam, HHAM,
HHpm, HHPM, HH:MMam, HH:MMAM, HH:MMpm, or HH:MMPM;
a period `.' can be used instead of a colon `:' to separate
the hour and minute parts);
+
- a string giving a relative time like \"90\" or \"2 hours 35 minutes\"
(the acceptable forms are a number of seconds without units
or some combination of values using units in `timer-duration-words');
+
- nil, meaning now;
+
- a number of seconds from now;
+
- a value from `encode-time';
-- or t (with non-nil REPEAT) meaning the next integral
- multiple of REPEAT.
+
+- or t (with non-nil REPEAT) meaning the next integral multiple
+ of REPEAT. This is handy when you want the function to run at
+ a certain \"round\" number. For instance, (run-at-time t 60 ...)
+ will run at 11:04:00, 11:05:00, etc.
The action is to call FUNCTION with arguments ARGS.
@@ -340,45 +379,44 @@ This function returns a timer object which you can use in
`cancel-timer'."
(interactive "sRun at time: \nNRepeat interval: \naFunction: ")
- (or (null repeat)
- (and (numberp repeat) (< 0 repeat))
- (error "Invalid repetition interval"))
+ (when (and repeat
+ (numberp repeat)
+ (< repeat 0))
+ (error "Invalid repetition interval"))
- ;; Special case: nil means "now" and is useful when repeating.
- (if (null time)
+ (let ((timer (timer-create)))
+ ;; Special case: nil means "now" and is useful when repeating.
+ (unless time
(setq time (current-time)))
- ;; Special case: t means the next integral multiple of REPEAT.
- (if (and (eq time t) repeat)
- (setq time (timer-next-integral-multiple-of-time (current-time) repeat)))
+ ;; Special case: t means the next integral multiple of REPEAT.
+ (when (and (eq time t) repeat)
+ (setq time (timer-next-integral-multiple-of-time nil repeat))
+ (setf (timer--integral-multiple timer) t))
- ;; Handle numbers as relative times in seconds.
- (if (numberp time)
+ ;; Handle numbers as relative times in seconds.
+ (when (numberp time)
(setq time (timer-relative-time nil time)))
- ;; Handle relative times like "2 hours 35 minutes"
- (if (stringp time)
- (let ((secs (timer-duration time)))
- (if secs
- (setq time (timer-relative-time nil secs)))))
-
- ;; Handle "11:23pm" and the like. Interpret it as meaning today
- ;; which admittedly is rather stupid if we have passed that time
- ;; already. (Though only Emacs hackers hack Emacs at that time.)
- (if (stringp time)
- (progn
- (require 'diary-lib)
- (let ((hhmm (diary-entry-time time))
- (now (decode-time)))
- (if (>= hhmm 0)
- (setq time
- (encode-time 0 (% hhmm 100) (/ hhmm 100)
- (decoded-time-day now)
- (decoded-time-month now)
- (decoded-time-year now)
- (decoded-time-zone now)))))))
+ ;; Handle relative times like "2 hours 35 minutes".
+ (when (stringp time)
+ (when-let ((secs (timer-duration time)))
+ (setq time (timer-relative-time nil secs))))
+
+ ;; Handle "11:23pm" and the like. Interpret it as meaning today
+ ;; which admittedly is rather stupid if we have passed that time
+ ;; already. (Though only Emacs hackers hack Emacs at that time.)
+ (when (stringp time)
+ (require 'diary-lib)
+ (let ((hhmm (diary-entry-time time))
+ (now (decode-time)))
+ (when (>= hhmm 0)
+ (setq time (encode-time 0 (% hhmm 100) (/ hhmm 100)
+ (decoded-time-day now)
+ (decoded-time-month now)
+ (decoded-time-year now)
+ (decoded-time-zone now))))))
- (let ((timer (timer-create)))
(timer-set-time timer time repeat)
(timer-set-function timer function args)
(timer-activate timer)
diff --git a/lisp/emacs-lisp/warnings.el b/lisp/emacs-lisp/warnings.el
index 36b275e2d3c..1d061364a03 100644
--- a/lisp/emacs-lisp/warnings.el
+++ b/lisp/emacs-lisp/warnings.el
@@ -307,7 +307,9 @@ entirely by setting `warning-suppress-types' or
'type 'warning-suppress-log-warning
'warning-type type))
(funcall newline)
- (when (and warning-fill-prefix (not (string-search "\n" message)))
+ (when (and warning-fill-prefix
+ (not (string-search "\n" message))
+ (not noninteractive))
(let ((fill-prefix warning-fill-prefix)
(fill-column warning-fill-column))
(fill-region start (point))))
diff --git a/lisp/emulation/cua-base.el b/lisp/emulation/cua-base.el
index 54f881bde8a..befcb423823 100644
--- a/lisp/emulation/cua-base.el
+++ b/lisp/emulation/cua-base.el
@@ -67,7 +67,7 @@
;; In addition to using the shifted movement keys, you can also use
;; [C-space] to start the region and use unshifted movement keys to extend
-;; it. To cancel the region, use [C-space] or [C-g].
+;; it. To cancel the region, use [C-space] or [C-g].
;; If you prefer to use the standard Emacs cut, copy, paste, and undo
;; bindings, customize cua-enable-cua-keys to nil.
@@ -116,7 +116,7 @@
;; "register commands".
;;
;; CUA's register support is activated by providing a numeric
-;; prefix argument to the C-x, C-c, and C-v commands. For example,
+;; prefix argument to the C-x, C-c, and C-v commands. For example,
;; to copy the selected region to register 2, enter [M-2 C-c].
;; Or if you have activated the keypad prefix mode, enter [kp-2 C-c].
;;
@@ -182,7 +182,7 @@
;; If you type a normal (self-inserting) character when the rectangle is
;; active, the character is inserted on the "current side" of every line
;; of the rectangle. The "current side" is the side on which the cursor
-;; is currently located. If the rectangle is only 1 column wide,
+;; is currently located. If the rectangle is only 1 column wide,
;; insertion will be performed to the left when the cursor is at the
;; bottom of the rectangle. So, for example, to comment out an entire
;; paragraph like this one, just place the cursor on the first character
@@ -330,9 +330,9 @@ See `cua-set-mark' for details."
"If non-nil, registers are supported via numeric prefix arg.
If the value is t, any numeric prefix arg in the range 0 to 9 will be
interpreted as a register number.
-If the value is `not-ctrl-u', using C-u to enter a numeric prefix is not
+If the value is `not-ctrl-u', using \\[universal-argument] to enter a numeric prefix is not
interpreted as a register number.
-If the value is `ctrl-u-only', only numeric prefix entered with C-u is
+If the value is `ctrl-u-only', only numeric prefix entered with \\[universal-argument] is
interpreted as a register number."
:type '(choice (const :tag "Disabled" nil)
(const :tag "Enabled, but C-u arg is not a register" not-ctrl-u)
@@ -360,7 +360,7 @@ managers, so try setting this to nil, if prefix override doesn't work."
:type 'boolean)
(defcustom cua-paste-pop-rotate-temporarily nil
- "If non-nil, \\[cua-paste-pop] only rotates the kill-ring temporarily.
+ "If non-nil, \\[cua-paste-pop] only rotates the kill ring temporarily.
This means that both \\[yank] and the first \\[yank-pop] in a sequence always
insert the most recently killed text. Each immediately following \\[cua-paste-pop]
replaces the previous text with the next older element on the `kill-ring'.
@@ -396,17 +396,17 @@ and after the region marked by the rectangle to search."
(defcustom cua-rectangle-mark-key [(control return)]
"Global key used to toggle the cua rectangle mark."
- :set #'(lambda (symbol value)
- (set symbol value)
- (when (and (boundp 'cua--keymaps-initialized)
- cua--keymaps-initialized)
- (define-key cua-global-keymap value
- #'cua-set-rectangle-mark)
- (when (boundp 'cua--rectangle-keymap)
- (define-key cua--rectangle-keymap value
- #'cua-clear-rectangle-mark)
- (define-key cua--region-keymap value
- #'cua-toggle-rectangle-mark))))
+ :set (lambda (symbol value)
+ (set symbol value)
+ (when (and (boundp 'cua--keymaps-initialized)
+ cua--keymaps-initialized)
+ (define-key cua-global-keymap value
+ #'cua-set-rectangle-mark)
+ (when (boundp 'cua--rectangle-keymap)
+ (define-key cua--rectangle-keymap value
+ #'cua-clear-rectangle-mark)
+ (define-key cua--region-keymap value
+ #'cua-toggle-rectangle-mark))))
:type 'key-sequence)
(defcustom cua-rectangle-modifier-key 'meta
@@ -699,6 +699,11 @@ Repeating prefix key when region is active works as a single prefix key."
(interactive)
(cua--prefix-override-replay 0))
+;; These aliases are so that we can look up the commands and find the
+;; correct keys when generating menus.
+(defalias 'cua-cut-handler #'cua--prefix-override-handler)
+(defalias 'cua-copy-handler #'cua--prefix-override-handler)
+
(defun cua--prefix-repeat-handler ()
"Repeating prefix key when region is active works as a single prefix key."
(interactive)
@@ -1140,7 +1145,7 @@ If ARG is the atom `-', scroll upward by nearly full screen."
def nil))
(defvar cua-global-keymap (make-sparse-keymap)
- "Global keymap for cua-mode; users may add to this keymap.")
+ "Global keymap for `cua-mode'; users may add to this keymap.")
(defvar cua--cua-keys-keymap (make-sparse-keymap))
(defvar cua--prefix-override-keymap (make-sparse-keymap))
@@ -1258,10 +1263,8 @@ If ARG is the atom `-', scroll upward by nearly full screen."
(define-key cua--cua-keys-keymap [(meta v)]
#'delete-selection-repeat-replace-region))
- (define-key cua--prefix-override-keymap [(control x)]
- #'cua--prefix-override-handler)
- (define-key cua--prefix-override-keymap [(control c)]
- #'cua--prefix-override-handler)
+ (define-key cua--prefix-override-keymap [(control x)] #'cua-cut-handler)
+ (define-key cua--prefix-override-keymap [(control c)] #'cua-copy-handler)
(define-key cua--prefix-repeat-keymap [(control x) (control x)]
#'cua--prefix-repeat-handler)
diff --git a/lisp/emulation/cua-rect.el b/lisp/emulation/cua-rect.el
index 0039092fd6e..7df45e705d3 100644
--- a/lisp/emulation/cua-rect.el
+++ b/lisp/emulation/cua-rect.el
@@ -486,10 +486,8 @@ Activates the region if needed. Only lasts until the region is deactivated."
(cua--deactivate t))
(setq cua--last-rectangle nil)
(mouse-set-point event)
- ;; FIX ME -- need to calculate virtual column.
- (cua-set-rectangle-mark)
- (setq cua--buffer-and-point-before-command nil)
- (setq cua--mouse-last-pos nil))
+ (activate-mark)
+ (cua-rectangle-mark-mode))
(defun cua-mouse-save-then-kill-rectangle (event arg)
"Expand rectangle to mouse click position and copy rectangle.
@@ -710,9 +708,11 @@ Mark is kept if keep-clear is 'keep and cleared if keep-clear is 'clear."
(nreverse rect)))
(defun cua--insert-rectangle (rect &optional below paste-column line-count)
- "Insert rectangle as insert-rectangle, but don't set mark and exit with
+ "Insert rectangle RECT similarly to `insert-rectangle'.
+In contrast to `insert-rectangle', don't set mark and exit with
point at either next to top right or below bottom left corner
-Notice: In overwrite mode, the rectangle is inserted as separate text lines."
+
+Note: In overwrite mode, the rectangle is inserted as separate text lines."
(if (eq below 'auto)
(setq below (and (bolp)
(or (eolp) (eobp) (= (1+ (point)) (point-max))))))
diff --git a/lisp/emulation/edt-mapper.el b/lisp/emulation/edt-mapper.el
index a723dbdbb90..8a42f893152 100644
--- a/lisp/emulation/edt-mapper.el
+++ b/lisp/emulation/edt-mapper.el
@@ -55,7 +55,7 @@
;; Usage:
-;; Simply load this file into emacs and run the function edt-mapper,
+;; Simply load this file into Emacs and run the function edt-mapper,
;; using the following command.
;; emacs -q -l edt-mapper -f edt-mapper
@@ -82,8 +82,8 @@
;; Sometimes, edt-mapper will ignore a key you press, and just
;; continue to prompt for the same key. This can happen when your
-;; window manager sucks up the key and doesn't pass it on to emacs,
-;; or it could be an emacs bug. Either way, there's nothing that
+;; window manager sucks up the key and doesn't pass it on to Emacs,
+;; or it could be an Emacs bug. Either way, there's nothing that
;; edt-mapper can do about it. You must press RETURN, to skip the
;; current key and continue. Later, you and/or your local Emacs guru
;; can try to figure out why the key is being ignored.
diff --git a/lisp/emulation/keypad.el b/lisp/emulation/keypad.el
index 56202c7fff8..4500faae57b 100644
--- a/lisp/emulation/keypad.el
+++ b/lisp/emulation/keypad.el
@@ -27,7 +27,7 @@
;;
;; With the following setup, the keypad can be used for numeric data
;; entry when NumLock is off, and to give numeric prefix arguments to
-;; emacs commands, when NumLock is on.
+;; Emacs commands, when NumLock is on.
;;
;; keypad-setup => Plain Numeric Keypad
;; keypad-numlock-setup => Prefix numeric args
@@ -203,7 +203,7 @@ keys are bound.
`S-cursor' Bind shifted keypad keys to the shifted cursor movement keys.
`cursor' Bind keypad keys to the cursor movement keys.
`numeric' Plain numeric keypad, i.e. 0 .. 9 and . (or DECIMAL arg)
- `none' Removes all bindings for keypad keys in function-key-map;
+ `none' Removes all bindings for keypad keys in `function-key-map';
this enables any user-defined bindings for the keypad keys
in the global and local keymaps.
diff --git a/lisp/emulation/viper-cmd.el b/lisp/emulation/viper-cmd.el
index 728f790a962..849ad3d8241 100644
--- a/lisp/emulation/viper-cmd.el
+++ b/lisp/emulation/viper-cmd.el
@@ -35,9 +35,7 @@
(defvar viper--key-maps)
(defvar viper--intercept-key-maps)
(defvar iso-accents-mode)
-(defvar quail-mode)
(defvar quail-current-str)
-(defvar mark-even-if-inactive)
(defvar viper--init-message)
(defvar viper-initial)
(defvar undo-beg-posn)
@@ -69,8 +67,7 @@
(nm-p (intern (concat snm "-p")))
(nms (intern (concat snm "s"))))
`(defun ,nm-p (com)
- (consp (viper-memq-char com ,nms)
- ))))
+ (consp (memq com ,nms)))))
;; Variables for defining VI commands
@@ -91,7 +88,7 @@
space return
delete backspace
)
- "Movement commands")
+ "Movement commands.")
;; define viper-movement-command-p
(viper-test-com-defun viper-movement-command)
@@ -487,7 +484,7 @@
(viper-change-state-to-vi))
(defun viper-set-mode-vars-for (state)
- "Sets Viper minor mode variables to put Viper's state STATE in effect."
+ "Set Viper minor mode variables to put Viper's state STATE in effect."
;; Emacs state
(setq viper-vi-minibuffer-minor-mode nil
@@ -1035,23 +1032,23 @@ as a Meta key and any number of multiple escapes are allowed."
cmd-info
cmd-to-exec-at-end)
(while (and cont
- (viper-memq-char char
- (list ?c ?d ?y ?! ?< ?> ?= ?# ?r ?R ?\"
- viper-buffer-search-char)))
+ (memq char
+ (list ?c ?d ?y ?! ?< ?> ?= ?# ?r ?R ?\"
+ viper-buffer-search-char)))
(if com
;; this means that we already have a command character, so we
;; construct a com list and exit while. however, if char is "
;; it is an error.
(progn
;; new com is (CHAR . OLDCOM)
- (if (viper-memq-char char '(?# ?\")) (user-error viper-ViperBell))
+ (if (memq char '(?# ?\")) (user-error viper-ViperBell))
(setq com (cons char com))
(setq cont nil))
;; If com is nil we set com as char, and read more. Again, if char is
;; ", we read the name of register and store it in viper-use-register.
;; if char is !, =, or #, a complete com is formed so we exit the while
;; loop.
- (cond ((viper-memq-char char '(?! ?=))
+ (cond ((memq char '(?! ?=))
(setq com char)
(setq char (read-char))
(setq cont nil))
@@ -1091,7 +1088,7 @@ as a Meta key and any number of multiple escapes are allowed."
`(key-binding (char-to-string ,char)))))
;; as com is non-nil, this means that we have a command to execute
- (if (viper-memq-char (car com) '(?r ?R))
+ (if (memq (car com) '(?r ?R))
;; execute appropriate region command.
(let ((char (car com)) (com (cdr com)))
(setq prefix-arg (cons value com))
@@ -1197,7 +1194,7 @@ as a Meta key and any number of multiple escapes are allowed."
)
(defsubst viper-yank-last-insertion ()
- "Inserts the text saved by the previous viper-save-last-insertion command."
+ "Insert the text saved by the previous viper-save-last-insertion command."
(condition-case nil
(insert viper-last-insertion)
(error nil)))
@@ -1500,7 +1497,7 @@ Doesn't change viper-command-ring in any way, so `.' will work as before
executing this command.
This command is supposed to be bound to a two-character Vi macro where
the second character is a digit 0 to 9. The digit indicates which
-history command to execute. `<char>0' is equivalent to `.', `<char>1'
+history command to execute. `<char>0' is equivalent to `.', `<char>1'
invokes the command before that, etc."
(interactive)
(let* ((viper-intermediate-command 'repeating-display-destructive-command)
@@ -2314,7 +2311,6 @@ problems."
(viper-downgrade-to-insert))
(defun viper-start-R-mode ()
- ;; Leave arg as 1, not t: XEmacs insists that it must be a pos number
(overwrite-mode 1)
(add-hook
'viper-post-command-hooks #'viper-R-state-post-command-sentinel t 'local)
@@ -2603,12 +2599,12 @@ On reaching beginning of line, stop and signal error."
(let ((prev-char (viper-char-at-pos 'backward))
(saved-point (point)))
;; skip non-newline separators backward
- (while (and (not (viper-memq-char prev-char '(nil \n)))
+ (while (and (not (memq prev-char '(nil \n)))
(< lim (point))
;; must be non-newline separator
(if (eq viper-syntax-preference 'strict-vi)
- (viper-memq-char prev-char '(?\ ?\t))
- (viper-memq-char (char-syntax prev-char) '(?\ ?-))))
+ (memq prev-char '(?\ ?\t))
+ (memq (char-syntax prev-char) '(?\ ?-))))
(viper-backward-char-carefully)
(setq prev-char (viper-char-at-pos 'backward)))
@@ -2622,12 +2618,12 @@ On reaching beginning of line, stop and signal error."
;; skip again, but make sure we don't overshoot the limit
(if twice
- (while (and (not (viper-memq-char prev-char '(nil \n)))
+ (while (and (not (memq prev-char '(nil \n)))
(< lim (point))
;; must be non-newline separator
(if (eq viper-syntax-preference 'strict-vi)
- (viper-memq-char prev-char '(?\ ?\t))
- (viper-memq-char (char-syntax prev-char) '(?\ ?-))))
+ (memq prev-char '(?\ ?\t))
+ (memq (char-syntax prev-char) '(?\ ?-))))
(viper-backward-char-carefully)
(setq prev-char (viper-char-at-pos 'backward))))
@@ -2645,10 +2641,10 @@ On reaching beginning of line, stop and signal error."
(viper-forward-word-kernel val)
(if com
(progn
- (cond ((viper-char-equal com ?c)
+ (cond ((eq com ?c)
(viper-separator-skipback-special 'twice viper-com-point))
;; Yank words including the whitespace, but not newline
- ((viper-char-equal com ?y)
+ ((eq com ?y)
(viper-separator-skipback-special nil viper-com-point))
((viper-dotable-command-p com)
(viper-separator-skipback-special nil viper-com-point)))
@@ -2666,10 +2662,10 @@ On reaching beginning of line, stop and signal error."
(viper-skip-nonseparators 'forward)
(viper-skip-separators t))
(if com (progn
- (cond ((viper-char-equal com ?c)
+ (cond ((eq com ?c)
(viper-separator-skipback-special 'twice viper-com-point))
;; Yank words including the whitespace, but not newline
- ((viper-char-equal com ?y)
+ ((eq com ?y)
(viper-separator-skipback-special nil viper-com-point))
((viper-dotable-command-p com)
(viper-separator-skipback-special nil viper-com-point)))
@@ -3546,10 +3542,11 @@ If MODE is set, set the macros only in that major mode."
(defun viper-set-parsing-style-toggling-macro (unset)
- "Set `%%%' to be a macro that toggles whether comment fields should be parsed for matching parentheses.
+ "Set or unset `%%%' as a macro that toggles comment parsing for parentheses.
This is used in conjunction with the `%' command.
-
-With a prefix argument, unsets the macro."
+By default, sets the macro which will toggle whether comment fields should
+be parsed for matching parentheses. With a prefix argument, unsets the
+macro instead."
(interactive "P")
(or noninteractive
(if (not unset)
@@ -3766,7 +3763,7 @@ Null string will repeat previous search."
(define-key viper-vi-basic-map
(cond ((characterp viper-buffer-search-char)
(char-to-string viper-buffer-search-char))
- (t (error "viper-buffer-search-char: wrong value type, %S"
+ (t (error "viper-buffer-search-char: Wrong value type, %S"
viper-buffer-search-char)))
#'viper-command-argument)
(aset viper-exec-array viper-buffer-search-char #'viper-exec-buffer-search)
@@ -3838,7 +3835,7 @@ Null string will repeat previous search."
;; yank and pop
(defsubst viper-yank (text)
- "Yank TEXT silently. This works correctly with Emacs's yank-pop command."
+ "Yank TEXT silently. This works correctly with Emacs's `yank-pop' command."
(insert text)
(setq this-command 'yank))
@@ -4510,7 +4507,7 @@ One can use \\=`\\=` and \\='\\=' to temporarily jump 1 step back."
(defun viper-set-expert-level (&optional dont-change-unless)
- "Sets the expert level for a Viper user.
+ "Set the expert level for a Viper user.
Can be called interactively to change (temporarily or permanently) the
current expert level.
@@ -4713,15 +4710,15 @@ Please, specify your level now: "))
(defun viper-submit-report ()
"Submit bug report on Viper."
(interactive)
- (defvar viper-color-display-p)
+ (defvar x-display-color-p)
(defvar viper-frame-parameters)
(defvar viper-minibuffer-emacs-face)
(defvar viper-minibuffer-vi-face)
(defvar viper-minibuffer-insert-face)
(let ((reporter-prompt-for-summary-p t)
- (viper-color-display-p (if (viper-window-display-p)
- (viper-color-display-p)
- 'non-x))
+ (x-display-color-p (if (viper-window-display-p)
+ (x-display-color-p)
+ 'non-x))
(viper-frame-parameters (frame-parameters (selected-frame)))
(viper-minibuffer-emacs-face (if (viper-has-face-support-p)
(facep
@@ -4779,7 +4776,7 @@ Please, specify your level now: "))
'viper-expert-level
'major-mode
'window-system
- 'viper-color-display-p
+ 'x-display-color-p
'viper-frame-parameters
'viper-minibuffer-vi-face
'viper-minibuffer-insert-face
diff --git a/lisp/emulation/viper-ex.el b/lisp/emulation/viper-ex.el
index 55930e7e6bc..85c8b87b9a1 100644
--- a/lisp/emulation/viper-ex.el
+++ b/lisp/emulation/viper-ex.el
@@ -25,7 +25,6 @@
;;; Code:
;; Compiler pacifier
-(defvar read-file-name-map)
(defvar viper-use-register)
(defvar viper-s-string)
(defvar viper-shift-width)
@@ -1798,7 +1797,7 @@ reversed."
set-cmd var auto-cmd-label)))
(if (and ask-if-save
- (y-or-n-p (format "Do you want to save this setting in %s "
+ (y-or-n-p (format "Do you want to save this setting in %s?"
viper-custom-file-name)))
(progn
(viper-save-string-in-file
@@ -1876,11 +1875,11 @@ reversed."
(message "Type `i' to search for a specific topic"))
(error (beep 1)
(with-output-to-temp-buffer " *viper-info*"
- (princ (format "
+ (princ "
The Info file for Viper does not seem to be installed.
This file is part of the standard distribution of Emacs.
-Please contact your system administrator. "))))))
+Please contact your system administrator. ")))))
;; Ex source command.
;; Loads the file specified as argument or viper-custom-file-name.
@@ -2176,7 +2175,7 @@ Please contact your system administrator. "))))))
(goto-char beg)))))
(defun ex-compile ()
- "Reads args from the command line, then runs make with the args.
+ "Read args from the command line, then run make with the args.
If no args are given, then it runs the last compile command.
Type `mak ' (including the space) to run make with no args."
(let (args)
diff --git a/lisp/emulation/viper-init.el b/lisp/emulation/viper-init.el
index 8188971c0d0..368a5dc40a6 100644
--- a/lisp/emulation/viper-init.el
+++ b/lisp/emulation/viper-init.el
@@ -25,16 +25,12 @@
;;; Code:
;; compiler pacifier
-(defvar mark-even-if-inactive)
-(defvar quail-mode)
(defvar iso-accents-mode)
(defvar viper-current-state)
(defvar viper-version)
(defvar viper-expert-level)
(defvar current-input-method)
(defvar default-input-method)
-(defvar describe-current-input-method-function)
-(defvar bar-cursor)
(defvar cursor-type)
;; end pacifier
@@ -48,12 +44,6 @@
(define-obsolete-function-alias 'viper-device-type #'window-system "27.1")
-(defun viper-color-display-p ()
- (condition-case nil
- (display-color-p)
- (error nil)))
-
-;; in XEmacs: device-type is tty on tty and stream in batch.
(defun viper-window-display-p ()
(and window-system (not (memq window-system '(tty stream pc)))))
@@ -81,7 +71,7 @@ In all likelihood, you don't need to bother with this setting."
(defun viper-has-face-support-p ()
(cond ((viper-window-display-p))
(viper-force-faces)
- ((viper-color-display-p))
+ ((x-display-color-p))
(t (memq window-system '(pc)))))
@@ -246,19 +236,19 @@ that deletes a file.")
;; Some common error messages
-(defconst viper-SpuriousText "Spurious text after command" "")
-(defconst viper-BadExCommand "Not an editor command" "")
-(defconst viper-InvalidCommandArgument "Invalid command argument" "")
-(defconst viper-NoPrevSearch "No previous search string" "")
-(defconst viper-EmptyRegister "`%c': Nothing in this register" "")
-(defconst viper-InvalidRegister "`%c': Invalid register" "")
-(defconst viper-EmptyTextmarker "`%c': Text marker doesn't point anywhere" "")
-(defconst viper-InvalidTextmarker "`%c': Invalid text marker" "")
-(defconst viper-InvalidViCommand "Invalid command" "")
-(defconst viper-BadAddress "Ill-formed address" "")
-(defconst viper-FirstAddrExceedsSecond "First address exceeds second" "")
-(defconst viper-NoFileSpecified "No file specified" "")
-(defconst viper-ViperBell "Viper bell" "")
+(defconst viper-SpuriousText "Spurious text after command")
+(defconst viper-BadExCommand "Not an editor command")
+(defconst viper-InvalidCommandArgument "Invalid command argument")
+(defconst viper-NoPrevSearch "No previous search string")
+(defconst viper-EmptyRegister "`%c': Nothing in this register")
+(defconst viper-InvalidRegister "`%c': Invalid register")
+(defconst viper-EmptyTextmarker "`%c': Text marker doesn't point anywhere")
+(defconst viper-InvalidTextmarker "`%c': Invalid text marker")
+(defconst viper-InvalidViCommand "Invalid command")
+(defconst viper-BadAddress "Ill-formed address")
+(defconst viper-FirstAddrExceedsSecond "First address exceeds second")
+(defconst viper-NoFileSpecified "No file specified")
+(defconst viper-ViperBell "Viper bell")
;; Is t until viper-mode executes for the very first time.
;; Prevents recursive descend into startup messages.
@@ -282,7 +272,7 @@ Use `\\[viper-set-expert-level]' to change this.")
;; If non-nil, ISO accents will be turned on in insert/replace emacs states and
;; turned off in vi-state. For some users, this behavior may be too
;; primitive. In this case, use insert/emacs/vi state hooks.
-(defvar-local viper-automatic-iso-accents nil "")
+(defvar-local viper-automatic-iso-accents nil)
;; Set iso-accents-mode to ARG. Check if it is bound first
(defsubst viper-set-iso-accents-mode (arg)
(if (boundp 'iso-accents-mode)
@@ -292,7 +282,7 @@ Use `\\[viper-set-expert-level]' to change this.")
;; Don't change this!
(defvar viper-mule-hook-flag t)
;; If non-nil, the default intl. input method is turned on.
-(defvar-local viper-special-input-method nil "")
+(defvar-local viper-special-input-method nil)
;; viper hook to run on input-method activation
(defun viper-activate-input-method-action ()
@@ -355,7 +345,7 @@ it better fits your working style."
;; Replace mode and changing text
;; Hack used to pass global states around for short period of time
-(defvar-local viper-intermediate-command nil "")
+(defvar-local viper-intermediate-command nil)
;; This is used to pass the right Vi command key sequence to
;; viper-set-destructive-command whenever (this-command-keys) doesn't give the
@@ -365,7 +355,7 @@ it better fits your working style."
(defconst viper-this-command-keys nil)
;; Indicates that the current destructive command has started in replace mode.
-(defvar-local viper-began-as-replace nil "")
+(defvar-local viper-began-as-replace nil)
(defcustom viper-allow-multiline-replace-regions t
"If non-nil, Viper will allow multi-line replace regions.
@@ -396,7 +386,7 @@ delete the text being replaced, as in standard Vi."
;; internal var, used to remember the default cursor color of emacs frames
(defvar viper-vi-state-cursor-color nil)
-(defvar-local viper-replace-overlay nil "")
+(defvar-local viper-replace-overlay nil)
(put 'viper-replace-overlay 'permanent-local t)
(defcustom viper-replace-region-end-delimiter "$"
@@ -434,18 +424,18 @@ color displays. By default, the delimiters are used only on TTYs."
(put 'viper-last-posn-in-replace-region 'permanent-local t)
(put 'viper-last-posn-while-in-insert-state 'permanent-local t)
-(defvar-local viper-sitting-in-replace nil "")
+(defvar-local viper-sitting-in-replace nil)
(put 'viper-sitting-in-replace 'permanent-local t)
;; Remember the number of characters that have to be deleted in replace
;; mode to compensate for the inserted characters.
-(defvar-local viper-replace-chars-to-delete 0 "")
+(defvar-local viper-replace-chars-to-delete 0)
;; This variable is used internally by the before/after changed functions to
;; determine how many chars were deleted by the change. This can't be
;; determined inside after-change-functions because those get the length of the
;; deleted region, not the number of chars deleted (which are two different
;; things under MULE).
-(defvar-local viper-replace-region-chars-deleted 0 "")
+(defvar-local viper-replace-region-chars-deleted 0)
;; Insertion ring and command ring
(defcustom viper-insertion-ring-size 14
@@ -494,7 +484,7 @@ will make it hard to use Vi-style timeout macros."
;; Autoindent in insert
;; Variable that keeps track of whether C-t has been pressed.
-(defvar-local viper-cted nil "")
+(defvar-local viper-cted nil)
;; Preserve the indent value, used by C-d in insert mode.
(defvar-local viper-current-indent 0)
@@ -502,14 +492,14 @@ will make it hard to use Vi-style timeout macros."
;; Whether to preserve the indent, used by C-d in insert mode.
(defvar-local viper-preserve-indent nil)
-(defvar-local viper-auto-indent nil "")
+(defvar-local viper-auto-indent nil)
(defcustom viper-auto-indent nil
"Enable autoindent, if t.
This is a buffer-local variable."
:type 'boolean
:group 'viper)
-(defvar-local viper-electric-mode t "")
+(defvar-local viper-electric-mode t)
(defcustom viper-electric-mode t
"If t, electrify Viper.
Currently, this only electrifies auto-indentation, making it appropriate to the
@@ -595,7 +585,7 @@ to a new place after repeating previous Vi command."
;;; Variables for Moves and Searches
(defgroup viper-search nil
- "Variables that define the search and query-replace behavior of Viper."
+ "Variables that define the search and `query-replace' behavior of Viper."
:prefix "viper-"
:group 'viper)
@@ -658,14 +648,14 @@ negative number."
:type 'boolean
:group 'viper)
-(defvar-local viper-ex-style-motion t "")
+(defvar-local viper-ex-style-motion t)
(defcustom viper-ex-style-motion t
"If t, the commands l,h do not cross lines, etc (Ex-style).
If nil, these commands cross line boundaries."
:type 'boolean
:group 'viper)
-(defvar-local viper-ex-style-editing t "")
+(defvar-local viper-ex-style-editing t)
(defcustom viper-ex-style-editing t
"If t, Ex-style behavior while editing in Vi command and insert states.
`Backspace' and `Delete' don't cross line boundaries in insert.
@@ -677,14 +667,14 @@ If nil, the above commands can work across lines."
:type 'boolean
:group 'viper)
-(defvar-local viper-ESC-moves-cursor-back viper-ex-style-editing "")
+(defvar-local viper-ESC-moves-cursor-back viper-ex-style-editing)
(defcustom viper-ESC-moves-cursor-back nil
"If t, ESC moves cursor back when changing from insert to vi state.
If nil, the cursor stays where it was when ESC was hit."
:type 'boolean
:group 'viper)
-(defvar-local viper-delete-backwards-in-replace nil "")
+(defvar-local viper-delete-backwards-in-replace nil)
(defcustom viper-delete-backwards-in-replace nil
"If t, DEL key will delete characters while moving the cursor backwards.
If nil, the cursor will move backwards without deleting anything."
@@ -702,7 +692,7 @@ If nil, the cursor will move backwards without deleting anything."
:tag "Search Wraps Around"
:group 'viper-search)
-(defvar-local viper-related-files-and-buffers-ring nil "")
+(defvar-local viper-related-files-and-buffers-ring nil)
(defcustom viper-related-files-and-buffers-ring nil
"List of file and buffer names to consider related to the current buffer.
Related buffers can be cycled through via :R and :P commands."
@@ -839,8 +829,7 @@ to customize the actual face object `viper-minibuffer-vi'
this variable represents.")
;; the current face to be used in the minibuffer
-(defvar-local
- viper-minibuffer-current-face viper-minibuffer-emacs-face "")
+(defvar-local viper-minibuffer-current-face viper-minibuffer-emacs-face)
;;; Miscellaneous
@@ -933,7 +922,9 @@ Should be set in `viper-custom-file-name'."
(setq cursor-type '(bar . 2)))
(defun viper-ESC-keyseq-timeout ()
- "Key sequence beginning with ESC and separated by no more than this many milliseconds is considered to be generated by a keyboard function key.
+ "Return the timeout for considering an ESC sequence to be a function key.
+Sequences of keys beginning with ESC and separated by no more than this many
+milliseconds are considered to be generated by a keyboard function key.
Setting this too high may slow down switching from insert to vi state. Setting
this value too low will make it impossible to use function keys in insert mode
on a dumb terminal."
diff --git a/lisp/emulation/viper-keym.el b/lisp/emulation/viper-keym.el
index 4a9070e84be..2f7d17351dc 100644
--- a/lisp/emulation/viper-keym.el
+++ b/lisp/emulation/viper-keym.el
@@ -69,7 +69,8 @@ major mode in effect."
:group 'viper)
(defcustom viper-want-ctl-h-help nil
- "If non-nil, bind C-h to help-command; otherwise, C-h gets the usual Vi bindings."
+ "If non-nil, bind C-h to `help-command'.
+If nil, C-h gets the usual Vi bindings."
:type 'boolean
:group 'viper)
@@ -86,8 +87,8 @@ major mode in effect."
"Keymap for user-defined local bindings.
Useful for changing bindings such as ZZ in certain major modes.
For instance, in letter-mode, one may want to bind ZZ to
-mh-send-letter. In a newsreader such as gnus, tin, or rn, ZZ could be bound
-to save-buffers-kill-emacs then post article, etc.")
+`mh-send-letter'. In a newsreader such as gnus, tin, or rn, ZZ could be bound
+to `save-buffers-kill-emacs' then post article, etc.")
(put 'viper-vi-local-user-map 'permanent-local t)
(defvar viper-vi-global-user-map (make-sparse-keymap)
@@ -181,7 +182,7 @@ In insert mode, this key also functions as Meta."
:type 'string
:group 'viper)
-(defconst viper-ESC-key (kbd "ESC")
+(defconst viper-ESC-key [escape]
"Key used to ESC.")
@@ -211,17 +212,17 @@ In insert mode, this key also functions as Meta."
;; Tells viper-add-local-keys to create a new viper-vi-local-user-map for new
;; buffers. Not a user option.
-(defvar-local viper-need-new-vi-local-map t "")
+(defvar-local viper-need-new-vi-local-map t)
(put 'viper-need-new-vi-local-map 'permanent-local t)
;; Tells viper-add-local-keys to create a new viper-insert-local-user-map for
;; new buffers. Not a user option.
-(defvar-local viper-need-new-insert-local-map t "")
+(defvar-local viper-need-new-insert-local-map t)
(put 'viper-need-new-insert-local-map 'permanent-local t)
;; Tells viper-add-local-keys to create a new viper-emacs-local-user-map for
;; new buffers. Not a user option.
-(defvar-local viper-need-new-emacs-local-map t "")
+(defvar-local viper-need-new-emacs-local-map t)
(put 'viper-need-new-emacs-local-map 'permanent-local t)
@@ -491,7 +492,7 @@ ALIST is of the form ((KEY . FUNC) (KEY . FUNC) ...)
Normally, this would be called from a hook to a major mode or
on a per buffer basis.
Usage:
- (viper-add-local-keys state \\='((key-str . func) (key-str . func)...)) "
+ (viper-add-local-keys state \\='((key-str . func) (key-str . func)...))"
(let (map)
(cond ((eq state 'vi-state)
@@ -520,7 +521,7 @@ Usage:
(defun viper-zap-local-keys ()
"Unconditionally reset Viper viper-*-local-user-map's.
Rarely useful, but if you made a mistake by switching to a mode that adds
-undesirable local keys, e.g., comint-mode, then this function can restore
+undesirable local keys, e.g., `comint-mode', then this function can restore
sanity."
(interactive)
(setq viper-vi-local-user-map (make-sparse-keymap)
diff --git a/lisp/emulation/viper-macs.el b/lisp/emulation/viper-macs.el
index 94ab8178925..fb60f6a5458 100644
--- a/lisp/emulation/viper-macs.el
+++ b/lisp/emulation/viper-macs.el
@@ -166,7 +166,7 @@ a key is a symbol, e.g., `a', `\\1', `f2', etc., or a list, e.g.,
(if (member
key
'(?\b ?\d '^? '^H (control h) (control \?) backspace delete))
- (setq key-seq (viper-subseq key-seq 0 (- (length key-seq) 2))))
+ (setq key-seq (seq-subseq key-seq 0 (- (length key-seq) 2))))
(setq message
(format
":map%s %s"
@@ -230,9 +230,9 @@ a key is a symbol, e.g., `a', `\\1', `f2', etc., or a list, e.g.,
(cond ((member
key
'(?\b ?\d '^? '^H (control h) (control \?) backspace delete))
- (setq key-seq (viper-subseq key-seq 0 (- (length key-seq) 2))))
+ (setq key-seq (cl-subseq key-seq 0 (- (length key-seq) 2))))
((member key '(tab (control i) ?\t))
- (setq key-seq (viper-subseq key-seq 0 (1- (length key-seq))))
+ (setq key-seq (cl-subseq key-seq 0 (1- (length key-seq))))
(setq message
(format
":unmap%s %s"
@@ -611,7 +611,7 @@ mistakes in macro names to be passed to this function is to use
(if (null macro-alist-elt)
(setq macro-alist-elt (car next-best-match)
- unmatched-suffix (viper-subseq event-seq (cdr next-best-match))))
+ unmatched-suffix (cl-subseq event-seq (cdr next-best-match))))
(cond ((null macro-alist-elt))
((setq macro-body (viper-kbd-buf-definition macro-alist-elt)))
@@ -693,7 +693,7 @@ mistakes in macro names to be passed to this function is to use
(let ((len1 (length seq1))
(len2 (length seq2)))
(if (<= len1 len2)
- (equal seq1 (viper-subseq seq2 0 len1)))))
+ (equal seq1 (cl-subseq seq2 0 len1)))))
;; find the longest common prefix
(defun viper-common-seq-prefix (&rest seqs)
@@ -757,7 +757,7 @@ mistakes in macro names to be passed to this function is to use
(setq macro-def (car lis)
def-len (length (car macro-def)))
(if (and (>= str-len def-len)
- (equal (car macro-def) (viper-subseq str 0 def-len)))
+ (equal (car macro-def) (cl-subseq str 0 def-len)))
(if (or (viper-kbd-buf-definition macro-def)
(viper-kbd-mode-definition macro-def)
(viper-kbd-global-definition macro-def))
diff --git a/lisp/emulation/viper-mous.el b/lisp/emulation/viper-mous.el
index 83fc5afafa5..879d8edca6f 100644
--- a/lisp/emulation/viper-mous.el
+++ b/lisp/emulation/viper-mous.el
@@ -26,7 +26,6 @@
;; compiler pacifier
(defvar double-click-time)
-(defvar mouse-track-multi-click-time)
(defvar viper-search-start-marker)
(defvar viper-local-search-start-marker)
(defvar viper-search-history)
@@ -65,8 +64,7 @@ or a triple-click."
(defcustom viper-multiclick-timeout (if (viper-window-display-p)
double-click-time
500)
- "Time interval in millisecond within which successive mouse clicks are
-considered related."
+ "Time interval in milliseconds for mouse clicks to be considered related."
:type 'integer)
;; Local variable used to toggle wraparound search on click.
@@ -77,8 +75,8 @@ considered related."
;; remembers prefix argument to pass along to commands invoked by second
;; click.
-;; This is needed because in Emacs (not XEmacs), assigning to prefix-arg
-;; causes Emacs to count the second click as if it was a single click
+;; This is needed because assigning to prefix-arg causes Emacs to
+;; count the second click as if it was a single click
(defvar viper-global-prefix-argument nil)
@@ -116,7 +114,7 @@ considered related."
(buffer-name (viper-mouse-click-window-buffer click)))
(defsubst viper-mouse-click-posn (click)
- "Returns position of a click."
+ "Return position of a click."
(declare (obsolete nil "27.1"))
(posn-point (event-start click)))
@@ -200,8 +198,7 @@ is ignored."
(setq result (buffer-substring word-beg (point))))
) ; if
- ;; XEmacs doesn't have set-text-properties, but there buffer-substring
- ;; doesn't return properties together with the string, so it's not needed.
+ ;; FIXME: Use `buffer-substring-no-properties' above instead?
(set-text-properties 0 (length result) nil result)
result))
diff --git a/lisp/emulation/viper-util.el b/lisp/emulation/viper-util.el
index 51f7406ad26..0af54b37432 100644
--- a/lisp/emulation/viper-util.el
+++ b/lisp/emulation/viper-util.el
@@ -25,12 +25,10 @@
;;; Code:
(require 'seq)
+(require 'cl-lib)
;; Compiler pacifier
(defvar viper-minibuffer-current-face)
-(defvar viper-minibuffer-insert-face)
-(defvar viper-minibuffer-vi-face)
-(defvar viper-minibuffer-emacs-face)
(defvar viper-replace-overlay-face)
(defvar viper-fast-keyseq-timeout)
(defvar ex-unix-type-shell)
@@ -63,22 +61,8 @@
(define-obsolete-function-alias 'viper-iconify
#'iconify-or-deiconify-frame "27.1")
-
-;; CHAR is supposed to be a char or an integer (positive or negative)
-;; LIST is a list of chars, nil, and negative numbers
-;; Check if CHAR is a member by trying to convert in characters, if necessary.
-;; Introduced for compatibility with XEmacs, where integers are not the same as
-;; chars.
-(defun viper-memq-char (char list)
- (cond ((and (integerp char) (>= char 0))
- (memq char list))
- ((memq char list))))
-
-;; Check if char-or-int and char are the same as characters
-(defun viper-char-equal (char-or-int char)
- (cond ((and (integerp char-or-int) (>= char-or-int 0))
- (= char-or-int char))
- ((eq char-or-int char))))
+(define-obsolete-function-alias 'viper-memq-char #'memq "29.1")
+(define-obsolete-function-alias 'viper-char-equal #'eq "29.1")
;; Like =, but accommodates null and also is t for eq-objects
(defun viper= (char char1)
@@ -87,8 +71,7 @@
(= char char1))
(t nil)))
-(defsubst viper-color-display-p ()
- (x-display-color-p))
+(define-obsolete-function-alias 'viper-color-display-p #'x-display-color-p "29.1")
(defun viper-get-cursor-color (&optional _frame)
(cdr (assoc 'cursor-color (frame-parameters))))
@@ -96,9 +79,6 @@
(defmacro viper-frame-value (variable)
"Return the value of VARIABLE local to the current frame, if there is one.
Otherwise return the normal value."
- ;; Frame-local variables are obsolete from Emacs 22.2 onwards,
- ;; so we do it by hand instead.
- ;; Buffer-local values take precedence over frame-local ones.
`(if (local-variable-p ',variable)
,variable
;; Distinguish between no frame parameter and a frame parameter
@@ -109,7 +89,7 @@ Otherwise return the normal value."
;; cursor colors
(defun viper-change-cursor-color (new-color &optional frame)
- (if (and (viper-window-display-p) (viper-color-display-p)
+ (if (and (viper-window-display-p) (x-display-color-p)
(stringp new-color) (x-color-defined-p new-color)
(not (string= new-color (viper-get-cursor-color))))
(modify-frame-parameters
@@ -141,7 +121,7 @@ Otherwise return the normal value."
;; By default, saves current frame cursor color before changing viper state
(defun viper-save-cursor-color (before-which-mode)
- (if (and (viper-window-display-p) (viper-color-display-p))
+ (if (and (viper-window-display-p) (x-display-color-p))
(let ((color (viper-get-cursor-color)))
(if (and (stringp color) (x-color-defined-p color)
;; there is something fishy in that the color is not saved if
@@ -927,7 +907,7 @@ Otherwise return the normal value."
(t key)))
((listp key)
- (setq modifiers (viper-subseq key 0 (1- (length key)))
+ (setq modifiers (cl-subseq key 0 (1- (length key)))
base-key (viper-seq-last-elt key)
base-key-name (symbol-name base-key)
char-p (= (length base-key-name) 1))
@@ -1091,14 +1071,11 @@ In addition, the symbol `_' may be considered alphanumeric if
`viper-syntax-preference' is `strict-vi' or `reformed-vi'.")
(defconst viper-strict-ALPHA-chars "a-zA-Z0-9_"
- "Regexp matching the set of alphanumeric characters acceptable to strict
-Vi.")
+ "Regexp matching the set of alphanumeric characters acceptable to strict Vi.")
(defconst viper-strict-SEP-chars " \t\n"
- "Regexp matching the set of alphanumeric characters acceptable to strict
-Vi.")
+ "Regexp matching the set of alphanumeric characters acceptable to strict Vi.")
(defconst viper-strict-SEP-chars-sans-newline " \t"
- "Regexp matching the set of alphanumeric characters acceptable to strict
-Vi.")
+ "Regexp matching the set of alphanumeric characters acceptable to strict Vi.")
(defconst viper-SEP-char-class " -"
"String of syntax classes for Vi separators.
@@ -1185,25 +1162,23 @@ This option is appropriate if you like Emacs-style words."
(looking-at (concat "[" viper-strict-ALPHA-chars addl-chars "]"))
(or
;; or one of the additional chars being asked to include
- (viper-memq-char char (viper-string-to-list addl-chars))
+ (memq char (viper-string-to-list addl-chars))
(and
;; not one of the excluded word chars (note:
;; viper-non-word-characters is a list)
- (not (viper-memq-char char viper-non-word-characters))
+ (not (memq char viper-non-word-characters))
;; char of the Viper-word syntax class
- (viper-memq-char (char-syntax char)
- (viper-string-to-list viper-ALPHA-char-class))))))
- ))
+ (memq (char-syntax char)
+ (viper-string-to-list viper-ALPHA-char-class))))))))
(defun viper-looking-at-separator ()
(let ((char (char-after (point))))
(if char
(if (eq viper-syntax-preference 'strict-vi)
- (viper-memq-char char (viper-string-to-list viper-strict-SEP-chars))
+ (memq char (viper-string-to-list viper-strict-SEP-chars))
(or (eq char ?\n) ; RET is always a separator in Vi
- (viper-memq-char (char-syntax char)
- (viper-string-to-list viper-SEP-char-class)))))
- ))
+ (memq (char-syntax char)
+ (viper-string-to-list viper-SEP-char-class)))))))
(defsubst viper-looking-at-alphasep (&optional addl-chars)
(or (viper-looking-at-separator) (viper-looking-at-alpha addl-chars)))
@@ -1329,8 +1304,7 @@ This option is appropriate if you like Emacs-style words."
;; of the excluded characters
(if (and (eq syntax-of-char-looked-at ?w)
(not negated-syntax))
- (not (viper-memq-char
- char-looked-at viper-non-word-characters))
+ (not (memq char-looked-at viper-non-word-characters))
t))
(funcall skip-syntax-func 1)
0)
@@ -1345,32 +1319,7 @@ This option is appropriate if you like Emacs-style words."
(not (eq (get-char-property (point) 'field)
(get-char-property (1- (point)) 'field)))))
-
-;; this is copied from cl-extra.el
-;; Return the subsequence of SEQ from START to END.
-;; If END is omitted, it defaults to the length of the sequence.
-;; If START or END is negative, it counts from the end.
-(defun viper-subseq (seq start &optional end)
- (if (stringp seq) (substring seq start end)
- (let (len)
- (and end (< end 0) (setq end (+ end (setq len (length seq)))))
- (if (< start 0) (setq start (+ start (or len (setq len (length seq))))))
- (cond ((listp seq)
- (if (> start 0) (setq seq (nthcdr start seq)))
- (if end
- (let ((res nil))
- (while (>= (setq end (1- end)) start)
- (push (pop seq) res))
- (nreverse res))
- (copy-sequence seq)))
- (t
- (or end (setq end (or len (length seq))))
- (let ((res (make-vector (max (- end start) 0) nil))
- (i 0))
- (while (< start end)
- (aset res i (aref seq start))
- (setq i (1+ i) start (1+ start)))
- res))))))
+(define-obsolete-function-alias 'viper-subseq #'cl-subseq "28.1")
(provide 'viper-util)
;;; viper-util.el ends here
diff --git a/lisp/emulation/viper.el b/lisp/emulation/viper.el
index cce51174336..1ee53651264 100644
--- a/lisp/emulation/viper.el
+++ b/lisp/emulation/viper.el
@@ -15,7 +15,7 @@
;; of the bug report be sent to the maintainer's email address.
(defconst viper-version "3.14.2 of July 4, 2013"
- "The current version of Viper")
+ "The current version of Viper.")
;; This file is part of GNU Emacs.
@@ -304,7 +304,6 @@
;; compiler pacifier
(defvar mark-even-if-inactive)
-(defvar quail-mode)
(defvar viper-expert-level)
(defvar viper-mode-string)
(defvar viper-major-mode-modifier-list)
@@ -516,7 +515,7 @@ If Viper is enabled, turn it off. Otherwise, turn it on."
;;;###autoload
(defun viper-mode ()
- "Turn on Viper emulation of Vi in Emacs. See Info node `(viper)Top'."
+ "Turn on Viper emulation of Vi in Emacs. See Info node `(viper)Top'."
(interactive)
(if (not noninteractive)
(progn
@@ -577,7 +576,7 @@ For more information on Viper:
To submit a bug report or to contact the author, type :submitReport in Vi
command mode. To shoo Viper away and return to pure Emacs (horror!), type:
- M-x viper-go-away
+ \\[viper-go-away]
This startup message appears whenever you load Viper, unless you type `y' now."
))
diff --git a/lisp/env.el b/lisp/env.el
index 83f43d1006b..fc48059cfd3 100644
--- a/lisp/env.el
+++ b/lisp/env.el
@@ -218,6 +218,23 @@ in the environment list of the selected frame."
(message "%s" (if value value "Not set")))
value))
+;;;###autoload
+(defmacro with-environment-variables (variables &rest body)
+ "Set VARIABLES in the environment and execute BODY.
+VARIABLES is a list of variable settings of the form (VAR VALUE),
+where VAR is the name of the variable (a string) and VALUE
+is its value (also a string).
+
+The previous values will be be restored upon exit."
+ (declare (indent 1) (debug (sexp body)))
+ (unless (consp variables)
+ (error "Invalid VARIABLES: %s" variables))
+ `(let ((process-environment (copy-sequence process-environment)))
+ ,@(mapcar (lambda (elem)
+ `(setenv ,(car elem) ,(cadr elem)))
+ variables)
+ ,@body))
+
(provide 'env)
;;; env.el ends here
diff --git a/lisp/epa-dired.el b/lisp/epa-dired.el
index 8a4f8933bf8..18f3f055745 100644
--- a/lisp/epa-dired.el
+++ b/lisp/epa-dired.el
@@ -21,6 +21,8 @@
;; 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 'epa)
diff --git a/lisp/epa-file.el b/lisp/epa-file.el
index 33bf5adabe6..fe187589aa7 100644
--- a/lisp/epa-file.el
+++ b/lisp/epa-file.el
@@ -21,8 +21,9 @@
;; 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:
-;;; Dependencies
(require 'epa)
(require 'epa-hook)
diff --git a/lisp/epa-hook.el b/lisp/epa-hook.el
index 9ad952c6813..5b250af6d70 100644
--- a/lisp/epa-hook.el
+++ b/lisp/epa-hook.el
@@ -21,10 +21,12 @@
;; 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:
(defgroup epa-file nil
- "The EasyPG Assistant hooks for transparent file encryption"
+ "The EasyPG Assistant hooks for transparent file encryption."
:version "23.1"
:group 'epa)
@@ -54,15 +56,15 @@ through Custom does that automatically."
May either be a string or a list of strings.")
(put 'epa-file-encrypt-to 'safe-local-variable
- #'(lambda (val)
- (or (stringp val)
- (and (listp val)
- (catch 'safe
- (mapc (lambda (elt)
- (unless (stringp elt)
- (throw 'safe nil)))
- val)
- t)))))
+ (lambda (val)
+ (or (stringp val)
+ (and (listp val)
+ (catch 'safe
+ (mapc (lambda (elt)
+ (unless (stringp elt)
+ (throw 'safe nil)))
+ val)
+ t)))))
(put 'epa-file-encrypt-to 'permanent-local t)
diff --git a/lisp/epa-ks.el b/lisp/epa-ks.el
index ebdb1274218..186b0ac9d1c 100644
--- a/lisp/epa-ks.el
+++ b/lisp/epa-ks.el
@@ -149,8 +149,7 @@ If EXACT is non-nil, don't accept approximate matches."
(cond ((null epa-keyserver)
(user-error "Empty keyserver pool"))
((listp epa-keyserver)
- (nth (random (length epa-keyserver))
- epa-keyserver))
+ (seq-random-elt epa-keyserver))
((stringp epa-keyserver)
epa-keyserver)
((error "Invalid type for `epa-keyserver'")))
@@ -211,7 +210,8 @@ KEYS is a list of `epa-ks-key' structures, as parsed by
(with-current-buffer buf
(setq tabulated-list-entries entries)
(tabulated-list-print t t))
- (message "Press `f' to mark a key, `x' to fetch all marked keys."))))
+ (message (substitute-command-keys
+ "Press \\`f' to mark a key, \\`x' to fetch all marked keys.")))))
(defun epa-ks--restart-search ()
(when epa-ks-last-query
@@ -295,12 +295,12 @@ enough, since keyservers have strict timeout settings."
:created
(and (match-string 4)
(not (string-empty-p (match-string 4)))
- (seconds-to-time
+ (time-convert
(string-to-number (match-string 4))))
:expires
(and (match-string 5)
(not (string-empty-p (match-string 5)))
- (seconds-to-time
+ (time-convert
(string-to-number (match-string 5))))
:flags
(mapcar (lambda (flag)
@@ -319,15 +319,11 @@ enough, since keyservers have strict timeout settings."
:created
(and (match-string 2)
(not (string-empty-p (match-string 2)))
- (decode-time (seconds-to-time
- (string-to-number
- (match-string 2)))))
+ (decode-time (string-to-number (match-string 2))))
:expires
(and (match-string 3)
(not (string-empty-p (match-string 3)))
- (decode-time (seconds-to-time
- (string-to-number
- (match-string 3)))))
+ (decode-time (string-to-number (match-string 3))))
:flags
(mapcar (lambda (flag)
(cdr (assq flag '((?r revoked)
diff --git a/lisp/epa-mail.el b/lisp/epa-mail.el
index b9dd437ed12..9b3aa0c7fd3 100644
--- a/lisp/epa-mail.el
+++ b/lisp/epa-mail.el
@@ -21,8 +21,9 @@
;; 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:
-;;; Dependencies
(require 'epa)
(require 'mail-utils)
diff --git a/lisp/epa.el b/lisp/epa.el
index 2698b39ffe3..93c85bfd37c 100644
--- a/lisp/epa.el
+++ b/lisp/epa.el
@@ -20,8 +20,9 @@
;; 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:
-;;; Dependencies
(require 'epg)
(eval-when-compile (require 'subr-x))
@@ -30,7 +31,7 @@
;;; Options
(defgroup epa nil
- "The EasyPG Assistant"
+ "The EasyPG Assistant."
:version "23.1"
:link '(custom-manual "(epa) Top")
:group 'epg)
@@ -461,7 +462,7 @@ q trust status questionable. - trust status unspecified.
;;;###autoload
(defun epa-select-keys (context prompt &optional names secret)
"Display a user's keyring and ask him to select keys.
-CONTEXT is an epg-context.
+CONTEXT is an `epg-context'.
PROMPT is a string to prompt with.
NAMES is a list of strings to be matched with keys. If it is nil, all
the keys are listed.
@@ -606,7 +607,11 @@ If SECRET is non-nil, list secret keys instead of public keys."
(_ "Error while executing \"%s\":\n\n"))
(epg-context-program context))
"\n\n"
- (epg-context-error-output context)))
+ (epg-context-error-output context)
+ (if (string-search "Unexpected error"
+ (epg-context-error-output context))
+ "\n(File possibly not an encrypted file, but is perhaps a key ring file?)\n"
+ "")))
(epa-info-mode)
(goto-char (point-min)))
(display-buffer buffer)))))
@@ -647,7 +652,7 @@ If SECRET is non-nil, list secret keys instead of public keys."
(setq input (file-name-sans-extension (expand-file-name input)))
(expand-file-name
(read-file-name
- (concat "To file (default " (file-name-nondirectory input) ") ")
+ (format-prompt "To file" (file-name-nondirectory input))
(file-name-directory input)
input)))
@@ -968,8 +973,7 @@ For example:
;;;###autoload
(defun epa-verify-cleartext-in-region (start end)
- "Verify OpenPGP cleartext signed messages in the current region
-between START and END.
+ "Verify OpenPGP cleartext signed messages in current region from START to END.
Don't use this command in Lisp programs!
See the reason described in the `epa-verify-region' documentation."
@@ -1202,8 +1206,7 @@ If no one is selected, symmetric encryption will be performed. ")
;;;###autoload
(defun epa-import-armor-in-region (start end)
- "Import keys in the OpenPGP armor format in the current region
-between START and END."
+ "Import keys in the OpenPGP armor format in the current region from START to END."
(interactive "r")
(save-excursion
(save-restriction
@@ -1237,9 +1240,7 @@ between START and END."
(list keys
(expand-file-name
(read-file-name
- (concat "To file (default "
- (file-name-nondirectory default-name)
- ") ")
+ (format-prompt "To file" (file-name-nondirectory default-name))
(file-name-directory default-name)
default-name)))))
(let ((context (epg-make-context epa-protocol)))
diff --git a/lisp/epg.el b/lisp/epg.el
index 9d6295594fd..3354eb2c1ed 100644
--- a/lisp/epg.el
+++ b/lisp/epg.el
@@ -21,10 +21,13 @@
;; 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:
;;; Prelude
(require 'epg-config)
+(require 'rfc6068)
(eval-when-compile (require 'cl-lib))
(define-error 'epg-error "GPG error")
@@ -331,6 +334,7 @@ callback data (if any)."
(cl-defstruct (epg-key
(:constructor nil)
+ (:copier epg--copy-key)
(:constructor epg-make-key (owner-trust))
(:predicate nil))
(owner-trust nil :read-only t)
@@ -432,7 +436,11 @@ callback data (if any)."
(and user-id
(concat " "
(if (stringp user-id)
- (epg--decode-percent-escape-as-utf-8 user-id)
+ (if (= (length user-id) (string-bytes user-id))
+ ;; This is ASCII, possibly %-encoded.
+ (rfc6068-unhexify-string user-id)
+ ;; Non-ASCII, return as is.
+ user-id)
(epg-decode-dn user-id))))
(and (epg-signature-validity signature)
(format " (trust %s)" (epg-signature-validity signature)))
@@ -656,16 +664,17 @@ callback data (if any)."
:sentinel #'ignore
:noquery t))
(setf (epg-context-error-buffer context) (process-buffer error-process))
- (with-file-modes 448
- (setq process (make-process :name "epg"
- :buffer buffer
- :command (cons (epg-context-program context)
- args)
- :connection-type 'pipe
- :coding 'raw-text
- :filter #'epg--process-filter
- :stderr error-process
- :noquery t)))
+ (with-existing-directory
+ (with-file-modes 448
+ (setq process (make-process :name "epg"
+ :buffer buffer
+ :command (cons (epg-context-program context)
+ args)
+ :connection-type 'pipe
+ :coding 'raw-text
+ :filter #'epg--process-filter
+ :stderr error-process
+ :noquery t))))
(setf (epg-context-process context) process)))
(defun epg--process-filter (process input)
@@ -777,7 +786,7 @@ callback data (if any)."
(user-id (match-string 2 string))
(entry (assoc key-id epg-user-id-alist)))
(condition-case nil
- (setq user-id (epg--decode-percent-escape-as-utf-8 user-id))
+ (setq user-id (rfc6068-unhexify-string user-id))
(error))
(if entry
(setcdr entry user-id)
@@ -798,7 +807,7 @@ callback data (if any)."
(when (and epg-key-id
(string-match "\\`passphrase\\." string))
(unless (epg-context-passphrase-callback context)
- (error "passphrase-callback not set"))
+ (error "Variable `passphrase-callback' not set"))
(let (inhibit-quit
passphrase
passphrase-with-new-line
@@ -906,7 +915,7 @@ callback data (if any)."
(condition-case nil
(if (eq (epg-context-protocol context) 'CMS)
(setq user-id (epg-dn-from-string user-id))
- (setq user-id (epg--decode-percent-escape-as-utf-8 user-id)))
+ (setq user-id (rfc6068-unhexify-string user-id)))
(error))
(if entry
(setcdr entry user-id)
@@ -1182,7 +1191,7 @@ callback data (if any)."
(user-id (match-string 2 string))
(entry (assoc key-id epg-user-id-alist)))
(condition-case nil
- (setq user-id (epg--decode-percent-escape-as-utf-8 user-id))
+ (setq user-id (rfc6068-unhexify-string user-id))
(error))
(if entry
(setcdr entry user-id)
@@ -1381,7 +1390,7 @@ NAME is either a string or a list of strings."
(if (seq-find (lambda (user)
(eq (epg-user-id-validity user) 'revoked))
(epg-key-user-id-list key))
- (let ((copy (copy-epg-key key)))
+ (let ((copy (epg--copy-key key)))
(setf (epg-key-user-id-list copy)
(seq-remove (lambda (user)
(eq (epg-user-id-validity user) 'revoked))
@@ -2061,9 +2070,11 @@ If you are unsure, use synchronous version of this function
string))
(defun epg--decode-percent-escape-as-utf-8 (string)
+ (declare (obsolete rfc6068-unhexify-string "28.1"))
(decode-coding-string (epg--decode-percent-escape string) 'utf-8))
(defun epg--decode-hexstring (string)
+ (declare (obsolete rfc6068-unhexify-string "28.1"))
(let ((index 0))
(while (eq index (string-match "[[:xdigit:]][[:xdigit:]]" string index))
(setq string (replace-match (string (string-to-number
@@ -2114,7 +2125,7 @@ The return value is an alist mapping from types to values."
value (epg--decode-quotedstring (match-string 0 string)))
(if (eq index (string-match "#\\([[:xdigit:]]+\\)" string index))
(setq index (match-end 0)
- value (epg--decode-hexstring (match-string 1 string)))
+ value (rfc6068-unhexify-string (match-string 1 string) t))
(if (eq index (string-match "\"\\([^\\\"]\\|\\\\.\\)*\""
string index))
(setq index (match-end 0)
diff --git a/lisp/erc/erc-autoaway.el b/lisp/erc/erc-autoaway.el
index 1a13aa95cd2..f7de61ce797 100644
--- a/lisp/erc/erc-autoaway.el
+++ b/lisp/erc/erc-autoaway.el
@@ -43,8 +43,7 @@ This is only used when `erc-autoaway-idle-method' is set to `emacs'.")
"The last time the user sent something.")
(defvar erc-autoaway-caused-away nil
- "Indicates whether this module was responsible for setting the
-user's away status.")
+ "Non-nil if this module was responsible for setting the user's away status.")
(defvar erc-autoaway-idle-seconds)
@@ -183,7 +182,7 @@ See `erc-auto-discard-away'."
(defcustom erc-autoaway-idle-seconds 1800
"Number of seconds after which ERC will set you automatically away.
-If you are changing this variable using lisp instead of customizing it,
+If you are changing this variable using Lisp instead of customizing it,
you have to run `erc-autoaway-reestablish-idletimer' afterwards."
:set (lambda (sym val)
(set-default sym val)
@@ -228,8 +227,7 @@ NONE-ALIVE-FUNC is the function to call if no ERC processes are alive."
(when none-alive-func (funcall none-alive-func)))))
(defun erc-autoaway-some-open-server-buffer ()
- "Return some ERC server buffer if its connection is alive and the
-user is not away.
+ "Return some ERC server buffer if its connection is alive and user is not away.
If none is found, return nil."
(car (erc-buffer-list (lambda ()
(and (erc-open-server-buffer-p)
diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el
index 6d84665873e..69f63dfbc44 100644
--- a/lisp/erc/erc-backend.el
+++ b/lisp/erc/erc-backend.el
@@ -199,6 +199,11 @@ active, use the `erc-server-process-alive' function instead.")
(defvar-local erc-server-reconnecting nil
"Non-nil if the user requests an explicit reconnect, and the
current IRC process is still alive.")
+(make-obsolete-variable 'erc-server-reconnecting
+ "see `erc--server-reconnecting'" "29.1")
+
+(defvar-local erc--server-reconnecting nil
+ "Non-nil when reconnecting.")
(defvar-local erc-server-timed-out nil
"Non-nil if the IRC server failed to respond to a ping.")
@@ -233,8 +238,7 @@ This is useful for detecting hung connections.")
This variable is only set in a server buffer.")
(defvar-local erc-server-filter-data nil
- "The data that arrived from the server
-but has not been processed yet.")
+ "The data that arrived from the server but has not been processed yet.")
(defvar-local erc-server-duplicates (make-hash-table :test 'equal)
"Internal variable used to track duplicate messages.")
@@ -278,16 +282,15 @@ Reconnection will happen automatically for any unexpected disconnection."
:type 'boolean)
(defcustom erc-server-reconnect-attempts 2
- "The number of times that ERC will attempt to reestablish a
-broken connection, or t to always attempt to reconnect.
+ "Number of times that ERC will attempt to reestablish a broken connection.
+If t, always attempt to reconnect.
This only has an effect if `erc-server-auto-reconnect' is non-nil."
:type '(choice (const :tag "Always reconnect" t)
integer))
(defcustom erc-server-reconnect-timeout 1
- "The amount of time, in seconds, that ERC will wait between
-successive reconnect attempts.
+ "Number of seconds to wait between successive reconnect attempts.
If a key is pressed while ERC is waiting, it will stop waiting."
:type 'number)
@@ -446,7 +449,7 @@ Currently this is called by `erc-send-input'."
(defun erc-forward-word ()
"Move forward one word, ignoring any subword settings.
-If no subword-mode is active, then this is (forward-word)."
+If no `subword-mode' is active, then this is (forward-word)."
(skip-syntax-forward "^w")
(> (skip-syntax-forward "w") 0))
@@ -460,7 +463,7 @@ If POS is out of range, the value is nil."
(defun erc-bounds-of-word-at-point ()
"Return the bounds of word at point, or nil if we're not at a word.
-If no subword-mode is active, then this is
+If no `subword-mode' is active, then this is
\(bounds-of-thing-at-point 'word)."
(if (or (erc-word-at-arg-p (point))
(erc-word-at-arg-p (1- (point))))
@@ -535,7 +538,8 @@ TLS (see `erc-session-client-certificate' for more details)."
(with-current-buffer buffer
(setq erc-server-process process)
(setq erc-server-quitting nil)
- (setq erc-server-reconnecting nil)
+ (setq erc-server-reconnecting nil
+ erc--server-reconnecting nil)
(setq erc-server-timed-out nil)
(setq erc-server-banned nil)
(setq erc-server-error-occurred nil)
@@ -618,36 +622,42 @@ Make sure you are in an ERC buffer when running this."
(erc-log-irc-protocol line nil)
(erc-parse-server-response process line)))))))
-(define-inline erc-server-reconnect-p (event)
+(defun erc--server-reconnect-p (event)
+ "Return non-nil when ERC should attempt to reconnect.
+EVENT is the message received from the closed connection process."
+ (and erc-server-auto-reconnect
+ (not erc-server-banned)
+ ;; make sure we don't infinitely try to reconnect, unless the
+ ;; user wants that
+ (or (eq erc-server-reconnect-attempts t)
+ (and (integerp erc-server-reconnect-attempts)
+ (< erc-server-reconnect-count
+ erc-server-reconnect-attempts)))
+ (or erc-server-timed-out
+ (not (string-match "^deleted" event)))
+ ;; open-network-stream-nowait error for connection refused
+ (if (string-match "^failed with code 111" event) 'nonblocking t)))
+
+(defun erc-server-reconnect-p (event)
"Return non-nil if ERC should attempt to reconnect automatically.
EVENT is the message received from the closed connection process."
- (inline-letevals (event)
- (inline-quote
- (or erc-server-reconnecting
- (and erc-server-auto-reconnect
- (not erc-server-banned)
- ;; make sure we don't infinitely try to reconnect, unless the
- ;; user wants that
- (or (eq erc-server-reconnect-attempts t)
- (and (integerp erc-server-reconnect-attempts)
- (< erc-server-reconnect-count
- erc-server-reconnect-attempts)))
- (or erc-server-timed-out
- (not (string-match "^deleted" ,event)))
- ;; open-network-stream-nowait error for connection refused
- (if (string-match "^failed with code 111" ,event) 'nonblocking t))))))
+ (declare (obsolete "see `erc--server-reconnect-p'" "29.1"))
+ (or (with-suppressed-warnings ((obsolete erc-server-reconnecting))
+ erc-server-reconnecting)
+ (erc--server-reconnect-p event)))
(defun erc-process-sentinel-2 (event buffer)
"Called when `erc-process-sentinel-1' has detected an unexpected disconnect."
(if (not (buffer-live-p buffer))
(erc-update-mode-line)
(with-current-buffer buffer
- (let ((reconnect-p (erc-server-reconnect-p event)) message delay)
+ (let ((reconnect-p (erc--server-reconnect-p event)) message delay)
(setq message (if reconnect-p 'disconnected 'disconnected-noreconnect))
(erc-display-message nil 'error (current-buffer) message)
(if (not reconnect-p)
;; terminate, do not reconnect
(progn
+ (setq erc--server-reconnecting nil)
(erc-display-message nil 'error (current-buffer)
'terminated ?e event)
;; Update mode line indicators
@@ -656,7 +666,8 @@ EVENT is the message received from the closed connection process."
;; reconnect
(condition-case nil
(progn
- (setq erc-server-reconnecting nil
+ (setq erc-server-reconnecting nil
+ erc--server-reconnecting t
erc-server-reconnect-count (1+ erc-server-reconnect-count))
(setq delay erc-server-reconnect-timeout)
(run-at-time delay nil
@@ -950,15 +961,22 @@ PROCs `process-buffer' is `current-buffer' when this function is called."
(unless (string= string "") ;; Ignore empty strings
(save-match-data
(let* ((tag-list (when (eq (aref string 0) ?@)
- (substring string 1 (string-search " " string))))
+ (substring string 1
+ (if (>= emacs-major-version 28)
+ (string-search " " string)
+ (string-match " " string)))))
(msg (make-erc-response :unparsed string :tags (when tag-list
(erc-parse-tags
tag-list))))
(string (if tag-list
- (substring string (+ 1 (string-search " " string)))
+ (substring string (+ 1 (if (>= emacs-major-version 28)
+ (string-search " " string)
+ (string-match " " string))))
string))
(posn (if (eq (aref string 0) ?:)
- (string-search " " string)
+ (if (>= emacs-major-version 28)
+ (string-search " " string)
+ (string-match " " string))
0)))
(setf (erc-response.sender msg)
@@ -968,7 +986,9 @@ PROCs `process-buffer' is `current-buffer' when this function is called."
(setf (erc-response.command msg)
(let* ((bposn (string-match "[^ \n]" string posn))
- (eposn (string-search " " string bposn)))
+ (eposn (if (>= emacs-major-version 28)
+ (string-search " " string bposn)
+ (string-match " " string bposn))))
(setq posn (and eposn
(string-match "[^ \n]" string eposn)))
(substring string bposn eposn)))
@@ -976,7 +996,9 @@ PROCs `process-buffer' is `current-buffer' when this function is called."
(while (and posn
(not (eq (aref string posn) ?:)))
(push (let* ((bposn posn)
- (eposn (string-search " " string bposn)))
+ (eposn (if (>= emacs-major-version 28)
+ (string-search " " string bposn)
+ (string-match " " string bposn))))
(setq posn (and eposn
(string-match "[^ \n]" string eposn)))
(substring string bposn eposn))
@@ -1160,7 +1182,8 @@ Would expand to:
\(fn (NAME &rest ALIASES) &optional EXTRA-FN-DOC EXTRA-VAR-DOC &rest FN-BODY)"
(declare (debug (&define [&name "erc-response-handler@"
(symbolp &rest symbolp)]
- &optional sexp sexp def-body)))
+ &optional sexp sexp def-body))
+ (indent defun))
(if (numberp name) (setq name (intern (format "%03i" name))))
(setq aliases (mapcar (lambda (a)
(if (numberp a)
@@ -1523,7 +1546,8 @@ add things to `%s' instead."
'WALLOPS ?n nick ?m message))))
(define-erc-response-handler (001)
- "Set `erc-server-current-nick' to reflect server settings and display the welcome message."
+ "Set `erc-server-current-nick' to reflect server settings.
+Then display the welcome message."
nil
(erc-set-current-nick (car (erc-response.command-args parsed)))
(erc-update-mode-line) ; needed here?
diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el
index 5953471ae8e..69972856d19 100644
--- a/lisp/erc/erc-button.el
+++ b/lisp/erc/erc-button.el
@@ -24,7 +24,7 @@
;;; Commentary:
-;; Heavily borrowed from gnus-art.el. Thanks to the original authors.
+;; Heavily borrowed from gnus-art.el. Thanks to the original authors.
;; This buttonizes nicks and other stuff to make it all clickable.
;; To enable, add to your init file:
;; (require 'erc-button)
@@ -130,7 +130,7 @@ longer than `erc-fill-column'."
("<URL: *\\([^<> ]+\\) *>" 0 t browse-url-button-open-url 1)
;;; ("(\\(\\([^~\n \t@][^\n \t@]*\\)@\\([a-zA-Z0-9.:-]+\\)\\)" 1 t finger 2 3)
;; emacs internal
- ("[`]\\([a-zA-Z][-a-zA-Z_0-9!*<=>+]+\\)[']"
+ ("[`‘]\\([a-zA-Z][-a-zA-Z_0-9!*<=>+]+\\)['’]"
1 t erc-button-describe-symbol 1)
;; pseudo links
("\\bInfo:[\"]\\([^\"]+\\)[\"]" 0 t Info-goto-node 1)
@@ -165,7 +165,7 @@ REGEXP is the string matching text around the button or a symbol
BUTTON is the number of the regexp grouping actually matching the
button. This is ignored if REGEXP is \\='nicknames.
-FORM is a lisp expression which must eval to true for the button to
+FORM is a Lisp expression which must eval to true for the button to
be added.
CALLBACK is the function to call when the user push this button.
@@ -194,9 +194,10 @@ PAR is a number of a regexp grouping whose text will be passed to
:inline t
(integer :tag "Regexp section number")))))
-(defcustom erc-emacswiki-url "https://www.emacswiki.org/cgi-bin/wiki.pl?"
- "URL of the EmacsWiki Homepage."
- :type 'string)
+(defcustom erc-emacswiki-url "https://www.emacswiki.org/emacs/"
+ "URL of the EmacsWiki website."
+ :type 'string
+ :version "28.1")
(defcustom erc-emacswiki-lisp-url "https://www.emacswiki.org/elisp/"
"URL of the EmacsWiki ELisp area."
@@ -388,12 +389,11 @@ REGEXP is the regular expression which matched for this button."
(mouse-set-point event)
(erc-button-press-button)))
-;; XEmacs calls this via widget-button-press with a bunch of arguments
-;; which we don't care about.
(defun erc-button-press-button (&rest _ignore)
"Check text at point for a callback function.
If the text at point has a `erc-callback' property,
call it with the value of the `erc-data' text property."
+ (declare (advertised-calling-convention () "28.1"))
(interactive)
(let* ((data (get-text-property (point) 'erc-data))
(fun (get-text-property (point) 'erc-callback)))
diff --git a/lisp/obsolete/erc-compat.el b/lisp/erc/erc-compat.el
index 9972e927e61..9bbc1f6a0d1 100644
--- a/lisp/obsolete/erc-compat.el
+++ b/lisp/erc/erc-compat.el
@@ -1,11 +1,10 @@
-;;; erc-compat.el --- ERC compatibility code for XEmacs -*- lexical-binding: t; -*-
+;;; erc-compat.el --- ERC compatibility code for older Emacsen -*- lexical-binding: t; -*-
;; Copyright (C) 2002-2003, 2005-2021 Free Software Foundation, Inc.
;; Author: Alex Schroeder <alex@gnu.org>
;; Maintainer: Amin Bandali <bandali@gnu.org>
;; URL: https://www.emacswiki.org/emacs/ERC
-;; Obsolete-since: 28.1
;; This file is part of GNU Emacs.
@@ -28,19 +27,20 @@
;;; Code:
-(require 'format-spec)
-
;;;###autoload(autoload 'erc-define-minor-mode "erc-compat")
-(defalias 'erc-define-minor-mode #'define-minor-mode)
+(define-obsolete-function-alias 'erc-define-minor-mode
+ #'define-minor-mode "28.1")
(defun erc-decode-coding-string (s coding-system)
"Decode S using CODING-SYSTEM."
+ (declare (obsolete decode-coding-string "28.1"))
(decode-coding-string s coding-system t))
(defun erc-encode-coding-string (s coding-system)
"Encode S using CODING-SYSTEM.
Return the same string, if the encoding operation is trivial.
See `erc-encoding-coding-alist'."
+ (declare (obsolete encode-coding-string "28.1"))
(encode-coding-string s coding-system t))
(define-obsolete-function-alias 'erc-propertize #'propertize "28.1")
@@ -51,6 +51,7 @@ See `erc-encoding-coding-alist'."
(define-obsolete-function-alias 'erc-replace-regexp-in-string #'replace-regexp-in-string "28.1")
(defun erc-set-write-file-functions (new-val)
+ (declare (obsolete nil "28.1"))
(set (make-local-variable 'write-file-functions) new-val))
(defvar erc-emacs-build-time
@@ -58,18 +59,8 @@ See `erc-encoding-coding-alist'."
emacs-build-time
(format-time-string "%Y-%m-%d" emacs-build-time))
"Time at which Emacs was dumped out, or nil if not available.")
-
-;; Emacs 21 and XEmacs do not have user-emacs-directory, but XEmacs
-;; has user-init-directory.
-(defvar erc-user-emacs-directory
- (cond ((boundp 'user-emacs-directory)
- user-emacs-directory)
- ((boundp 'user-init-directory)
- user-init-directory)
- (t "~/.emacs.d/"))
- "Directory beneath which additional per-user Emacs-specific files
-are placed.
-Note that this should end with a directory separator.")
+(make-obsolete-variable 'erc-emacs-build-time 'emacs-build-time "28.1")
+(define-obsolete-variable-alias 'erc-user-emacs-directory 'user-emacs-directory "28.1")
(defun erc-replace-match-subexpression-in-string
(newtext string _match subexp _start &optional fixedcase literal)
@@ -77,6 +68,7 @@ Note that this should end with a directory separator.")
MATCH is the text which matched the subexpression (see `match-string').
START is the beginning position of the last match (see `match-beginning').
See `replace-match' for explanations of FIXEDCASE and LITERAL."
+ (declare (obsolete replace-match "28.1"))
(replace-match newtext fixedcase literal string subexp))
(define-obsolete-function-alias 'erc-with-selected-window
@@ -86,10 +78,11 @@ See `replace-match' for explanations of FIXEDCASE and LITERAL."
(define-obsolete-function-alias 'erc-make-obsolete-variable
#'make-obsolete-variable "28.1")
-;; Provide a simpler replacement for `member-if'
+;; Provide a simpler replacement for `cl-member-if'
(defun erc-member-if (predicate list)
"Find the first item satisfying PREDICATE in LIST.
Return the sublist of LIST whose car matches."
+ (declare (obsolete cl-member-if "28.1"))
(let ((ptr list))
(catch 'found
(while ptr
@@ -97,11 +90,12 @@ Return the sublist of LIST whose car matches."
(throw 'found ptr))
(setq ptr (cdr ptr))))))
-;; Provide a simpler replacement for `delete-if'
+;; Provide a simpler replacement for `cl-delete-if'
(defun erc-delete-if (predicate seq)
"Remove all items satisfying PREDICATE in SEQ.
This is a destructive function: it reuses the storage of SEQ
whenever possible."
+ (declare (obsolete cl-delete-if "28.1"))
;; remove from car
(while (when (funcall predicate (car seq))
(setq seq (cdr seq))))
@@ -117,11 +111,12 @@ whenever possible."
(setq next (cdr ptr))))
seq)
-;; Provide a simpler replacement for `remove-if-not'
+;; Provide a simpler replacement for `cl-remove-if-not'
(defun erc-remove-if-not (predicate seq)
"Remove all items not satisfying PREDICATE in SEQ.
This is a non-destructive function; it makes a copy of SEQ to
avoid corrupting the original SEQ."
+ (declare (obsolete cl-remove-if-not "28.1"))
(let (newseq)
(dolist (el seq)
(when (funcall predicate el)
@@ -133,6 +128,7 @@ avoid corrupting the original SEQ."
"Return the subsequence of SEQ from START to END.
If END is omitted, it defaults to the length of the sequence.
If START or END is negative, it counts from the end."
+ (declare (obsolete cl-subseq "28.1"))
(if (stringp seq) (substring seq start end)
(let (len)
(and end (< end 0) (setq end (+ end (setq len (length seq)))))
diff --git a/lisp/erc/erc-dcc.el b/lisp/erc/erc-dcc.el
index de72624aaa1..f27425ac8a1 100644
--- a/lisp/erc/erc-dcc.el
+++ b/lisp/erc/erc-dcc.el
@@ -1,7 +1,6 @@
;;; erc-dcc.el --- CTCP DCC module for ERC -*- lexical-binding: t; -*-
-;; Copyright (C) 1993-1995, 1998, 2002-2004, 2006-2021 Free Software
-;; Foundation, Inc.
+;; Copyright (C) 1993-2021 Free Software Foundation, Inc.
;; Author: Ben A. Mesander <ben@gnu.ai.mit.edu>
;; Noah Friedman <friedman@prep.ai.mit.edu>
@@ -81,7 +80,8 @@ IRC users."
All values of the list must be uppercase strings.")
(defvar erc-dcc-list nil
- "List of DCC connections. Looks like:
+ "List of DCC connections.
+Looks like:
((:nick \"nick!user@host\" :type GET :peer proc
:parent proc :size size :file file)
(:nick \"nick!user@host\" :type CHAT :peer proc :parent proc)
@@ -163,8 +163,8 @@ All values of the list must be uppercase strings.")
;;; Misc macros and utility functions
(defun erc-dcc-member (&rest args)
- "Return the first matching entry in `erc-dcc-list' which satisfies the
-constraints given as a plist in ARGS. Returns nil on no match.
+ "Return first matching entry in `erc-dcc-list' satisfying constraints in ARGS.
+ARGS is a plist. Return nil on no match.
The property :nick is treated specially, if it contains a `!' character,
it is treated as a nick!user@host string, and compared with the :nick property
@@ -182,12 +182,12 @@ compared with `erc-nick-equal-p' which is IRC case-insensitive."
(let ((prop (car prem))
(val (cadr prem)))
(setq prem (cddr prem)
- ;; plist-member is a predicate in xemacs
- test (and (plist-member elt prop)
- (plist-get elt prop)))
+ test (cadr (plist-member elt prop)))
;; if the property exists and is equal, we continue, else, try the
;; next element of the list
- (or (and (eq prop :nick) (string-search "!" val)
+ (or (and (eq prop :nick) (if (>= emacs-major-version 28)
+ (string-search "!" val)
+ (string-match "!" val))
test (string-equal test val))
(and (eq prop :nick)
test val
@@ -203,8 +203,7 @@ compared with `erc-nick-equal-p' which is IRC case-insensitive."
result))
(defun erc-pack-int (value)
- "Convert an integer into a packed string in network byte order,
-which is big-endian."
+ "Convert integer into a packed string in network byte order, which is big-endian."
;; make sure value is not negative
(when (< value 0)
(error "ERC-DCC (erc-pack-int): packet size is negative"))
@@ -630,8 +629,13 @@ that subcommand."
(define-inline erc-dcc-unquote-filename (filename)
(inline-quote
- (string-replace "\\\\" "\\"
- (string-replace "\\\"" "\"" ,filename))))
+ (if (>= emacs-major-version 28)
+ (string-replace
+ "\\\\" "\\"
+ (string-replace "\\\"" "\"" ,filename))
+ (replace-regexp-in-string
+ "\\\\\\\\" "\\"
+ (replace-regexp-in-string "\\\\\"" "\"" ,filename t t) t t))))
(defun erc-dcc-handle-ctcp-send (proc query nick login host to)
"This is called if a CTCP DCC SEND subcommand is sent to the client.
@@ -753,8 +757,7 @@ the matching regexp, or nil if none found."
:type 'integer)
(defcustom erc-dcc-pump-bytes nil
- "If set to an integer, keep sending until that number of bytes are
-unconfirmed."
+ "If an integer, keep sending until that number of bytes are unconfirmed."
:type '(choice (const nil) integer))
(define-inline erc-dcc-get-parent (proc)
@@ -826,8 +829,7 @@ bytes sent."
(defcustom erc-dcc-send-connect-hook
'(erc-dcc-display-send erc-dcc-send-block)
- "Hook run whenever the remote end of a DCC SEND offer connected to your
-listening port."
+ "Hook run when remote end of a DCC SEND offer connected to your listening port."
:type 'hook)
(defun erc-dcc-nick (plist)
@@ -858,7 +860,7 @@ listening port."
(buffer-string)))
(defun erc-dcc-send-file (nick file &optional pproc)
- "Open a socket for incoming connections, and send a CTCP send request to the
+ "Open socket for incoming connections and send a CTCP send request to the
other client."
(interactive "sNick: \nfFile: ")
(when (null pproc) (if (processp erc-server-process)
@@ -1021,11 +1023,11 @@ transfer is complete."
:type 'hook)
(defcustom erc-dcc-chat-connect-hook nil
- ""
+ "" ; FIXME
:type 'hook)
(defcustom erc-dcc-chat-exit-hook nil
- ""
+ "" ; FIXME
:type 'hook)
(defun erc-cmd-CREQ (line &optional _force)
diff --git a/lisp/erc/erc-fill.el b/lisp/erc/erc-fill.el
index 41256682c00..9f29b9dad9f 100644
--- a/lisp/erc/erc-fill.el
+++ b/lisp/erc/erc-fill.el
@@ -97,15 +97,15 @@ function is called."
function))
(defcustom erc-fill-static-center 27
- "Column around which all statically filled messages will be
-centered. This column denotes the point where the ` ' character
-between <nickname> and the entered text will be put, thus aligning
-nick names right and text left."
+ "Column around which all statically filled messages will be centered.
+This column denotes the point where the ` ' character between
+<nickname> and the entered text will be put, thus aligning nick
+names right and text left."
:type 'integer)
(defcustom erc-fill-variable-maximum-indentation 17
- "If we indent a line after a long nick, don't indent more then this
-characters. Set to nil to disable."
+ "Don't indent a line after a long nick more than this many characters.
+Set to nil to disable."
:type 'integer)
(defcustom erc-fill-column 78
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index fc9a8d39ef4..683ac2d37c5 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -137,7 +137,7 @@ Put this function on `erc-insert-post-hook' and/or `erc-send-post-hook'."
(goto-char (point-max))))
(defun erc-move-to-prompt-setup ()
- "Initialize the move-to-prompt module for XEmacs."
+ "Initialize the move-to-prompt module."
(add-hook 'pre-command-hook #'erc-move-to-prompt nil t))
;;; Keep place in unvisited channels
diff --git a/lisp/erc/erc-ibuffer.el b/lisp/erc/erc-ibuffer.el
index 31e59a6d3e4..95eab040449 100644
--- a/lisp/erc/erc-ibuffer.el
+++ b/lisp/erc/erc-ibuffer.el
@@ -38,17 +38,16 @@
:group 'erc)
(defcustom erc-ibuffer-keyword-char ?k
- "Char used to indicate a channel which had keyword traffic lately (hidden)."
+ "Char indicating a channel which had keyword traffic lately (hidden)."
:type 'character)
(defcustom erc-ibuffer-pal-char ?p
- "Char used to indicate a channel which had pal traffic lately (hidden)."
+ "Char indicating a channel which had pal traffic lately (hidden)."
:type 'character)
(defcustom erc-ibuffer-fool-char ?f
- "Char used to indicate a channel which had fool traffic lately (hidden)."
+ "Char indicating a channel which had fool traffic lately (hidden)."
:type 'character)
(defcustom erc-ibuffer-dangerous-host-char ?d
- "Char used to indicate a channel which had dangerous-host traffic lately
-\(hidden)."
+ "Char indicating a channel which had dangerous-host traffic lately (hidden)."
:type 'character)
(define-ibuffer-filter erc-server
diff --git a/lisp/erc/erc-identd.el b/lisp/erc/erc-identd.el
index 3821e298cda..80039005520 100644
--- a/lisp/erc/erc-identd.el
+++ b/lisp/erc/erc-identd.el
@@ -46,7 +46,8 @@
:group 'erc)
(defcustom erc-identd-port 8113
- "Port to run the identd server on if not specified in the argument for
+ "Port to run the identd server on.
+This can be overridden by specifying an argument for
`erc-identd-start'.
This can be either a string or a number."
diff --git a/lisp/erc/erc-imenu.el b/lisp/erc/erc-imenu.el
index dcf6db7407a..522bc805f8d 100644
--- a/lisp/erc/erc-imenu.el
+++ b/lisp/erc/erc-imenu.el
@@ -1,7 +1,6 @@
;;; erc-imenu.el --- Imenu support for ERC -*- lexical-binding: t; -*-
-;; Copyright (C) 2001-2002, 2004, 2006-2021 Free Software Foundation,
-;; Inc.
+;; Copyright (C) 2001-2021 Free Software Foundation, Inc.
;; Author: Mario Lang <mlang@delysid.org>
;; Maintainer: Amin Bandali <bandali@gnu.org>
diff --git a/lisp/erc/erc-join.el b/lisp/erc/erc-join.el
index 2ad9c8bd941..2ed8622b856 100644
--- a/lisp/erc/erc-join.el
+++ b/lisp/erc/erc-join.el
@@ -34,6 +34,7 @@
(require 'erc)
(require 'auth-source)
+(require 'erc-networks)
(defgroup erc-autojoin nil
"Enable autojoining."
@@ -54,8 +55,12 @@
(defcustom erc-autojoin-channels-alist nil
"Alist of channels to autojoin on IRC networks.
Every element in the alist has the form (SERVER . CHANNELS).
-SERVER is a regexp matching the server, and channels is the
-list of channels to join.
+SERVER is a regexp matching the server, and channels is the list
+of channels to join. SERVER can also be a symbol, in which case
+it is matched against the value of `erc-network' instead of
+`erc-server-announced-name' or `erc-session-server' (this can be
+useful when connecting to an IRC proxy that relays several
+networks under the same server).
If the channel(s) require channel keys for joining, the passwords
are found via auth-source. For instance, if you use ~/.authinfo
@@ -117,6 +122,15 @@ This is called from a timer set up by `erc-autojoin-channels'."
(erc-log "Delayed autojoin started (no ident success detected yet)")
(erc-autojoin-channels server nick))))
+(defun erc-autojoin-server-match (candidate)
+ "Match the current network or server against CANDIDATE.
+This should be a key from `erc-autojoin-channels-alist'."
+ (or (eq candidate (erc-network))
+ (and (stringp candidate)
+ (string-match-p candidate
+ (or erc-server-announced-name
+ erc-session-server)))))
+
(defun erc-autojoin-after-ident (_network _nick)
"Autojoin channels in `erc-autojoin-channels-alist'.
This function is run from `erc-nickserv-identified-hook'."
@@ -131,7 +145,7 @@ This function is run from `erc-nickserv-identified-hook'."
;; We may already be in these channels, e.g. because the
;; autojoin timer went off.
(dolist (l erc-autojoin-channels-alist)
- (when (string-match (car l) server)
+ (when (erc-autojoin-server-match (car l))
(dolist (chan (cdr l))
(unless (erc-member-ignore-case chan joined)
(erc-server-join-channel server chan)))))))
@@ -150,15 +164,14 @@ This function is run from `erc-nickserv-identified-hook'."
;; `erc-autojoin-timing' is `connect':
(let ((server (or erc-session-server erc-server-announced-name)))
(dolist (l erc-autojoin-channels-alist)
- (when (string-match-p (car l) server)
+ (when (erc-autojoin-server-match (car l))
(dolist (chan (cdr l))
(let ((buffer
(car (erc-buffer-filter
(lambda ()
(let ((current (erc-default-target)))
(and (stringp current)
- (string-match-p (car l)
- (or erc-session-server erc-server-announced-name))
+ (erc-autojoin-server-match (car l))
(string-equal (erc-downcase chan)
(erc-downcase current)))))))))
(when (or (not buffer)
@@ -168,20 +181,30 @@ This function is run from `erc-nickserv-identified-hook'."
;; Return nil to avoid stomping on any other hook funcs.
nil)
+(defun erc-autojoin-current-server ()
+ "Compute the current server for lookup in `erc-autojoin-channels-alist'.
+Respects `erc-autojoin-domain-only'."
+ (let ((server (or erc-server-announced-name erc-session-server)))
+ (if (and erc-autojoin-domain-only
+ (string-match "[^.\n]+\\.\\([^.\n]+\\.[^.\n]+\\)$" server))
+ (match-string 1 server)
+ server)))
+
(defun erc-autojoin-add (proc parsed)
"Add the channel being joined to `erc-autojoin-channels-alist'."
(let* ((chnl (erc-response.contents parsed))
(nick (car (erc-parse-user (erc-response.sender parsed))))
(server (with-current-buffer (process-buffer proc)
- (or erc-session-server erc-server-announced-name))))
+ (erc-autojoin-current-server))))
(when (erc-current-nick-p nick)
- (when (and erc-autojoin-domain-only
- (string-match "[^.\n]+\\.\\([^.\n]+\\.[^.\n]+\\)$" server))
- (setq server (match-string 1 server)))
- (let ((elem (assoc server erc-autojoin-channels-alist)))
+ (let ((elem (or (assoc (erc-network) erc-autojoin-channels-alist)
+ (assoc server erc-autojoin-channels-alist))))
(if elem
(unless (member chnl (cdr elem))
(setcdr elem (cons chnl (cdr elem))))
+ ;; This always keys on server, not network -- user can
+ ;; override by simply adding a network to
+ ;; `erc-autojoin-channels-alist'
(setq erc-autojoin-channels-alist
(cons (list server chnl)
erc-autojoin-channels-alist))))))
@@ -196,12 +219,10 @@ This function is run from `erc-nickserv-identified-hook'."
(let* ((chnl (car (erc-response.command-args parsed)))
(nick (car (erc-parse-user (erc-response.sender parsed))))
(server (with-current-buffer (process-buffer proc)
- (or erc-session-server erc-server-announced-name))))
+ (erc-autojoin-current-server))))
(when (erc-current-nick-p nick)
- (when (and erc-autojoin-domain-only
- (string-match "[^.\n]+\\.\\([^.\n]+\\.[^.\n]+\\)$" server))
- (setq server (match-string 1 server)))
- (let ((elem (assoc server erc-autojoin-channels-alist)))
+ (let ((elem (or (assoc (erc-network) erc-autojoin-channels-alist)
+ (assoc server erc-autojoin-channels-alist))))
(when elem
(setcdr elem (delete chnl (cdr elem)))
(unless (cdr elem)
diff --git a/lisp/erc/erc-log.el b/lisp/erc/erc-log.el
index ddd00afd73b..7c5c495f9e1 100644
--- a/lisp/erc/erc-log.el
+++ b/lisp/erc/erc-log.el
@@ -180,8 +180,7 @@ If you set this to nil, you may want to enable both
:type 'boolean)
(defcustom erc-log-write-after-insert nil
- "If non-nil, write to log file when new text is added to a
-logged ERC buffer.
+ "If non-nil, write to log file when new text is added to a logged ERC buffer.
If you set this to nil, you may want to enable both
`erc-save-buffer-on-part' and `erc-save-queries-on-quit'."
@@ -195,8 +194,7 @@ This should ideally, be a \"catch-all\" coding system, like
:type 'coding-system)
(defcustom erc-log-filter-function nil
- "If non-nil, pass text through the given function before writing it to
-a log file.
+ "If non-nil, pass text to this function before writing it to a log file.
The function should take one argument, which is the text to filter."
:type '(choice (function "Function")
@@ -361,7 +359,7 @@ function is a possible value for
(concat (buffer-name buffer) ".txt"))
(defun erc-generate-log-file-name-long (_buffer target nick server port)
- "Generates a log-file name in the way ERC always did it.
+ "Generate a log-file name in the way ERC always did it.
This results in a file name of the form #channel!nick@server:port.txt.
This function is a possible value for `erc-generate-log-file-name-function'."
(let ((file (concat
@@ -375,7 +373,7 @@ This function is a possible value for `erc-generate-log-file-name-function'."
(declare-function erc-network-name "erc-networks" ())
(defun erc-generate-log-file-name-network (buffer target nick server _port)
- "Generates a log-file name using the network name rather than server name.
+ "Generate a log-file name using the network name rather than server name.
This results in a file name of the form #channel!nick@network.txt.
This function is a possible value for `erc-generate-log-file-name-function'."
(require 'erc-networks)
diff --git a/lisp/erc/erc-match.el b/lisp/erc/erc-match.el
index 43fbca3e666..01d6e44d594 100644
--- a/lisp/erc/erc-match.el
+++ b/lisp/erc/erc-match.el
@@ -24,7 +24,7 @@
;;; Commentary:
-;; This file includes stuff to work with pattern matching in ERC. If
+;; This file includes stuff to work with pattern matching in ERC. If
;; you were used to customizing erc-fools, erc-keywords, erc-pals,
;; erc-dangerous-hosts and the like, this file contains these
;; customizable variables.
@@ -79,7 +79,7 @@ Useful to mark nicks from dangerous hosts."
:type '(repeat regexp))
(defcustom erc-current-nick-highlight-type 'keyword
- "Determines how to highlight text in which your current nickname appears
+ "Determine how to highlight text in which your current nickname appears
\(does not apply to text sent by you).
The following values are allowed:
@@ -234,9 +234,9 @@ current-nick, keyword, pal, dangerous-host, fool."
:type 'hook)
(defcustom erc-match-exclude-server-buffer nil
- "If true, don't perform match on the server buffer; this is
-useful for excluding all the things like MOTDs from the server
-and other miscellaneous functions."
+ "If true, don't perform match on the server buffer.
+This is useful for excluding all the things like MOTDs from the
+server and other miscellaneous functions."
:version "24.3"
:type 'boolean)
diff --git a/lisp/erc/erc-menu.el b/lisp/erc/erc-menu.el
index 1bee6ff2a67..2da1abb29a7 100644
--- a/lisp/erc/erc-menu.el
+++ b/lisp/erc/erc-menu.el
@@ -103,8 +103,7 @@
"ERC menu definition.")
(defvar erc-menu-defined nil
- "Internal variable used to keep track of whether we've defined the
-ERC menu yet.")
+ "Internal variable used to keep track of whether we've defined the ERC menu yet.")
;;;###autoload(autoload 'erc-menu-mode "erc-menu" nil t)
(define-erc-module menu nil
diff --git a/lisp/erc/erc-netsplit.el b/lisp/erc/erc-netsplit.el
index 9cfb947003c..994f2d07c30 100644
--- a/lisp/erc/erc-netsplit.el
+++ b/lisp/erc/erc-netsplit.el
@@ -52,7 +52,7 @@ netsplits, so that it can filter the JOIN messages on a netjoin too."
(remove-hook 'erc-timer-hook #'erc-netsplit-timer)))
(defcustom erc-netsplit-show-server-mode-changes-flag nil
- "Set to t to enable display of server mode changes."
+ "Non-nil means to enable display of server mode changes."
:type 'boolean)
(defcustom erc-netsplit-debug nil
@@ -61,8 +61,7 @@ netsplits, so that it can filter the JOIN messages on a netjoin too."
(defcustom erc-netsplit-regexp
"^[^ @!\"\n]+\\.[^ @!\n]+ [^ @!\n]+\\.[^ @!\"\n]+$"
- "This regular expression should match quit reasons produced
-by netsplits."
+ "This regular expression should match quit reasons produced by netsplits."
:type 'regexp)
(defcustom erc-netsplit-hook nil
diff --git a/lisp/erc/erc-networks.el b/lisp/erc/erc-networks.el
index 54502b2df05..678c596760b 100644
--- a/lisp/erc/erc-networks.el
+++ b/lisp/erc/erc-networks.el
@@ -45,7 +45,7 @@
;; Variables
(defgroup erc-networks nil
- "IRC Networks"
+ "IRC Networks."
:group 'erc)
(defcustom erc-server-alist
@@ -720,7 +720,7 @@ NET is a symbol naming that IRC network and
MATCHER is used to find a corresponding network to a server while
connected to it. If it is regexp, it's used to match against
`erc-server-announced-name'. It can also be a function (predicate).
- Then it is executed with the server buffer as current-buffer."
+ Then it is executed with the server buffer as current buffer."
:type '(repeat
(list :tag "Network"
(symbol :tag "Network name")
@@ -755,15 +755,6 @@ server name and search for a match in `erc-networks-alist'."
"Return the value of `erc-network' for the current server."
(erc-with-server-buffer erc-network))
-(defun erc-current-network ()
- "Deprecated. Use `erc-network' instead.
-Return the name of this server's network as a symbol."
- (erc-with-server-buffer
- (intern (downcase (symbol-name erc-network)))))
-
-(make-obsolete 'erc-current-network 'erc-network
- "Obsolete since erc-networks 1.5")
-
(defun erc-network-name ()
"Return the name of the current network as a string."
(erc-with-server-buffer (symbol-name erc-network)))
@@ -833,7 +824,7 @@ As an example:
(ports (if (listp (nth 3 srv))
(erc-ports-list (nth 3 srv))
(list (nth 3 srv))))
- (port (nth (random (length ports)) ports)))
+ (port (and ports (seq-random-elt ports))))
(erc :server host :port port)))
;;; The following experimental
diff --git a/lisp/erc/erc-notify.el b/lisp/erc/erc-notify.el
index 1ed056c277d..d4f22ca0f5a 100644
--- a/lisp/erc/erc-notify.el
+++ b/lisp/erc/erc-notify.el
@@ -40,13 +40,11 @@
:group 'erc)
(defcustom erc-notify-list nil
- "List of nicknames you want to be notified about online/offline
-status change."
+ "List of nicknames you want to be notified about online/offline status change."
:type '(repeat string))
(defcustom erc-notify-interval 60
- "Time interval (in seconds) for checking online status of notified
-people."
+ "Time interval (in seconds) for checking online status of notified people."
:type 'integer)
(defcustom erc-notify-signon-hook nil
diff --git a/lisp/erc/erc-pcomplete.el b/lisp/erc/erc-pcomplete.el
index 8ea37c7f290..c846a1f003f 100644
--- a/lisp/erc/erc-pcomplete.el
+++ b/lisp/erc/erc-pcomplete.el
@@ -44,7 +44,7 @@
(require 'time-date)
(defgroup erc-pcomplete nil
- "Programmable completion for ERC"
+ "Programmable completion for ERC."
:group 'erc)
(defcustom erc-pcomplete-nick-postfix ":"
@@ -53,8 +53,7 @@ add this string to nicks completed."
:type 'string)
(defcustom erc-pcomplete-order-nickname-completions t
- "If t, channel nickname completions will be ordered such that
-the most recent speakers are listed first."
+ "If t, order nickname completions with the most recent speakers first."
:type 'boolean)
;;;###autoload(autoload 'erc-completion-mode "erc-pcomplete" nil t)
diff --git a/lisp/erc/erc-replace.el b/lisp/erc/erc-replace.el
index 3f69c4cb9cc..b2e9047ce77 100644
--- a/lisp/erc/erc-replace.el
+++ b/lisp/erc/erc-replace.el
@@ -1,7 +1,6 @@
;;; erc-replace.el --- wash and massage messages inserted into the buffer -*- lexical-binding: t; -*-
-;; Copyright (C) 2001-2002, 2004, 2006-2021 Free Software Foundation,
-;; Inc.
+;; Copyright (C) 2001-2021 Free Software Foundation, Inc.
;; Author: Andreas Fuchs <asf@void.at>
;; Maintainer: Amin Bandali <bandali@gnu.org>
@@ -37,7 +36,7 @@
(require 'erc)
(defgroup erc-replace nil
- "Replace text from incoming messages"
+ "Replace text from incoming messages."
:group 'erc)
(defcustom erc-replace-alist nil
diff --git a/lisp/erc/erc-ring.el b/lisp/erc/erc-ring.el
index 666fd585926..52285a8343a 100644
--- a/lisp/erc/erc-ring.el
+++ b/lisp/erc/erc-ring.el
@@ -79,7 +79,7 @@ STATE-OR-STRING should be a string or an erc-input object."
(setq erc-input-ring-index nil))
(defun erc-clear-input-ring ()
- "Remove all entries from the input ring, then call garbage-collect.
+ "Remove all entries from the input ring, then call `garbage-collect'.
You might use this for security purposes if you have typed a command
containing a password."
(interactive)
diff --git a/lisp/erc/erc-services.el b/lisp/erc/erc-services.el
index 61006e0c028..5e4cef5253a 100644
--- a/lisp/erc/erc-services.el
+++ b/lisp/erc/erc-services.el
@@ -169,9 +169,8 @@ You can also use \\[erc-nickserv-identify-mode] to change modes."
(defcustom erc-use-auth-source-for-nickserv-password nil
"Query auth-source for a password when identifiying to NickServ.
-This option has an no effect if `erc-prompt-for-nickserv-password'
-is non-nil, and passwords from `erc-nickserv-passwords' take
-precedence."
+Passwords from `erc-nickserv-passwords' take precedence. See
+function `erc-nickserv-get-password'."
:version "28.1"
:type 'boolean)
@@ -405,85 +404,114 @@ password for this nickname, otherwise try to send it automatically."
identify-regex
(string-match identify-regex msg))
(erc-log "NickServ IDENTIFY request detected")
- (erc-nickserv-call-identify-function nick)
+ (erc-nickserv-identify nil nick)
nil))))
(defun erc-nickserv-identify-on-connect (_server nick)
"Identify to Nickserv after the connection to the server is established."
- (unless (or (and (null erc-nickserv-passwords)
- (null erc-prompt-for-nickserv-password)
- (null erc-use-auth-source-for-nickserv-password))
- (and (eq erc-nickserv-identify-mode 'both)
- (erc-nickserv-alist-regexp (erc-network))))
- (erc-nickserv-call-identify-function nick)))
+ (unless (and (eq erc-nickserv-identify-mode 'both)
+ (erc-nickserv-alist-regexp (erc-network)))
+ (erc-nickserv-identify nil nick)))
(defun erc-nickserv-identify-on-nick-change (nick _old-nick)
"Identify to Nickserv whenever your nick changes."
- (unless (or (and (null erc-nickserv-passwords)
- (null erc-prompt-for-nickserv-password)
- (null erc-use-auth-source-for-nickserv-password))
- (and (eq erc-nickserv-identify-mode 'both)
- (erc-nickserv-alist-regexp (erc-network))))
- (erc-nickserv-call-identify-function nick)))
-
-(defun erc-nickserv-get-password (nickname)
- "Return the password for NICKNAME from configured sources.
-
-It uses `erc-nickserv-passwords' and additionally auth-source
-when `erc-use-auth-source-for-nickserv-password' is not nil."
- (or
- (when erc-nickserv-passwords
- (cdr (assoc nickname
- (nth 1 (assoc (erc-network)
- erc-nickserv-passwords)))))
- (when erc-use-auth-source-for-nickserv-password
- (let* ((secret (nth 0 (auth-source-search
- :max 1 :require '(:secret)
- :host (erc-with-server-buffer erc-session-server)
- :port (format ; ensure we have a string
- "%s" (erc-with-server-buffer erc-session-port))
- :user nickname))))
- (when secret
- (let ((passwd (plist-get secret :secret)))
- (if (functionp passwd) (funcall passwd) passwd)))))))
-
-(defun erc-nickserv-call-identify-function (nickname)
- "Call `erc-nickserv-identify'.
-Either call it interactively or run it with NICKNAME's password,
-depending on the value of `erc-prompt-for-nickserv-password'."
- (if erc-prompt-for-nickserv-password
- (call-interactively 'erc-nickserv-identify)
- (erc-nickserv-identify (erc-nickserv-get-password nickname))))
+ (unless (and (eq erc-nickserv-identify-mode 'both)
+ (erc-nickserv-alist-regexp (erc-network)))
+ (erc-nickserv-identify nil nick)))
+
+(defun erc-nickserv-get-password (nick)
+ "Return the password for NICK from configured sources.
+First, a password for NICK is looked up in
+`erc-nickserv-passwords'. Then, it is looked up in auth-source
+if `erc-use-auth-source-for-nickserv-password' is not nil.
+Finally, interactively prompt the user, if
+`erc-prompt-for-nickserv-password' is true.
+
+As soon as some source returns a password, the sequence of
+lookups stops and this function returns it (or returns nil if it
+is empty). Otherwise, no corresponding password was found, and
+it returns nil."
+ (let (network server port)
+ ;; Fill in local vars, switching to the server buffer once only
+ (erc-with-server-buffer
+ (setq network erc-network
+ server erc-session-server
+ port erc-session-port))
+ (let ((ret
+ (or
+ (when erc-nickserv-passwords
+ (cdr (assoc nick
+ (cl-second (assoc network
+ erc-nickserv-passwords)))))
+ (when erc-use-auth-source-for-nickserv-password
+ (let ((secret (cl-first (auth-source-search
+ :max 1 :require '(:secret)
+ :host server
+ ;; Ensure a string for :port
+ :port (format "%s" port)
+ :user nick))))
+ (when secret
+ (let ((passwd (plist-get secret :secret)))
+ (if (functionp passwd) (funcall passwd) passwd)))))
+ (when erc-prompt-for-nickserv-password
+ (read-passwd
+ (format "NickServ password for %s on %s (RET to cancel): "
+ nick network))))))
+ (when (and ret (not (string= ret "")))
+ ret))))
(defvar erc-auto-discard-away)
-;;;###autoload
-(defun erc-nickserv-identify (password)
+(defun erc-nickserv-send-identify (nick password)
"Send an \"identify <PASSWORD>\" message to NickServ.
-When called interactively, read the password using `read-passwd'."
+Returns t if the message could be sent, nil otherwise."
+ (let* ((erc-auto-discard-away nil)
+ (network (erc-network))
+ (nickserv-info (assoc network erc-nickserv-alist))
+ (nickserv (or (erc-nickserv-alist-nickserv nil nickserv-info)
+ "NickServ"))
+ (identify-word (or (erc-nickserv-alist-ident-keyword
+ nil nickserv-info)
+ "IDENTIFY"))
+ (nick (if (erc-nickserv-alist-use-nick-p nil nickserv-info)
+ (concat nick " ")
+ ""))
+ (msgtype (or (erc-nickserv-alist-ident-command nil nickserv-info)
+ "PRIVMSG")))
+ (erc-message msgtype
+ (concat nickserv " " identify-word " " nick password))))
+
+(defun erc-nickserv-call-identify-function (nickname)
+ "Call `erc-nickserv-identify' with NICKNAME."
+ (declare (obsolete erc-nickserv-identify "28.1"))
+ (erc-nickserv-identify nil nickname))
+
+;;;###autoload
+(defun erc-nickserv-identify (&optional password nick)
+ "Identify to NickServ immediately.
+Identification will either use NICK or the current nick if not
+provided, and some password obtained through
+`erc-nickserv-get-password' (which see). If no password can be
+found, an error is reported through `erc-error'.
+
+Interactively, the user will be prompted for NICK, an empty
+string meaning to default to the current nick.
+
+Returns t if the identify message could be sent, nil otherwise."
(interactive
- (list (read-passwd
- (format "NickServ password for %s on %s (RET to cancel): "
- (erc-current-nick)
- (or (and (erc-network)
- (symbol-name (erc-network)))
- "Unknown network")))))
- (when (and password (not (string= "" password)))
- (let* ((erc-auto-discard-away nil)
- (network (erc-network))
- (nickserv-info (assoc network erc-nickserv-alist))
- (nickserv (or (erc-nickserv-alist-nickserv nil nickserv-info)
- "NickServ"))
- (identify-word (or (erc-nickserv-alist-ident-keyword
- nil nickserv-info)
- "IDENTIFY"))
- (nick (if (erc-nickserv-alist-use-nick-p nil nickserv-info)
- (concat (erc-current-nick) " ")
- ""))
- (msgtype (or (erc-nickserv-alist-ident-command nil nickserv-info)
- "PRIVMSG")))
- (erc-message msgtype
- (concat nickserv " " identify-word " " nick password)))))
+ (list
+ nil
+ (read-from-minibuffer "Nickname: " nil nil nil
+ 'erc-nick-history-list (erc-current-nick))))
+ (unless (and nick (not (string= nick "")))
+ (setq nick (erc-current-nick)))
+ (unless password
+ (setq password (erc-nickserv-get-password nick)))
+ (if password
+ (erc-nickserv-send-identify nick password)
+ (erc-error "Cannot find a password for nickname %s"
+ nick)
+ nil))
(provide 'erc-services)
diff --git a/lisp/erc/erc-sound.el b/lisp/erc/erc-sound.el
index 92759d206a3..cb4c232aba8 100644
--- a/lisp/erc/erc-sound.el
+++ b/lisp/erc/erc-sound.el
@@ -128,8 +128,9 @@ See also `play-sound-file'."
(erc-log (format "Playing sound file %S" filepath))))
(defun erc-toggle-sound (&optional arg)
- "Toggles playing sounds on and off. With positive argument,
- turns them on. With any other argument turns sounds off."
+ "Toggle playing sounds on and off.
+With positive argument, turns them on. With any other argument
+turns sounds off."
(interactive "P")
(cond ((and (numberp arg) (> arg 0))
(setq erc-play-sound t))
diff --git a/lisp/erc/erc-speedbar.el b/lisp/erc/erc-speedbar.el
index e61e741302d..84854e3be52 100644
--- a/lisp/erc/erc-speedbar.el
+++ b/lisp/erc/erc-speedbar.el
@@ -139,7 +139,9 @@ This will add a speedbar major display mode."
t))))
(defun erc-speedbar-expand-server (text server indent)
- (cond ((string-search "+" text)
+ (cond ((if (>= emacs-major-version 28)
+ (string-search "+" text)
+ (string-match "\\+" text))
(speedbar-change-expand-button-char ?-)
(if (speedbar-with-writable
(save-excursion
@@ -147,7 +149,10 @@ This will add a speedbar major display mode."
(erc-speedbar-channel-buttons nil (1+ indent) server)))
(speedbar-change-expand-button-char ?-)
(speedbar-change-expand-button-char ??)))
- ((string-search "-" text) ;we have to contract this node
+ (;; we have to contract this node
+ (if (>= emacs-major-version 28)
+ (string-search "-" text)
+ (string-match "-" text))
(speedbar-change-expand-button-char ?+)
(speedbar-delete-subblock indent))
(t (error "Ooops... not sure what to do")))
@@ -184,7 +189,9 @@ This will add a speedbar major display mode."
"For the line matching TEXT, in CHANNEL, expand or contract a line.
INDENT is the current indentation level."
(cond
- ((string-search "+" text)
+ ((if (>= emacs-major-version 28)
+ (string-search "+" text)
+ (string-match "\\+" text))
(speedbar-change-expand-button-char ?-)
(speedbar-with-writable
(save-excursion
@@ -233,7 +240,9 @@ INDENT is the current indentation level."
(speedbar-with-writable
(dolist (entry names)
(erc-speedbar-insert-user entry ?+ (1+ indent))))))))))
- ((string-search "-" text)
+ ((if (>= emacs-major-version 28)
+ (string-search "-" text)
+ (string-match "-" text))
(speedbar-change-expand-button-char ?+)
(speedbar-delete-subblock indent))
(t (error "Ooops... not sure what to do")))
@@ -284,7 +293,9 @@ The update is only done when the channel is actually expanded already."
(erc-speedbar-expand-channel "+" buffer 1)))))
(defun erc-speedbar-expand-user (text token indent)
- (cond ((string-search "+" text)
+ (cond ((if (>= emacs-major-version 28)
+ (string-search "+" text)
+ (string-match "\\+" text))
(speedbar-change-expand-button-char ?-)
(speedbar-with-writable
(save-excursion
@@ -307,7 +318,9 @@ The update is only done when the channel is actually expanded already."
nil nil nil nil
info nil nil nil
(1+ indent)))))))
- ((string-search "-" text)
+ ((if (>= emacs-major-version 28)
+ (string-search "-" text)
+ (string-match "-" text))
(speedbar-change-expand-button-char ?+)
(speedbar-delete-subblock indent))
(t (error "Ooops... not sure what to do")))
diff --git a/lisp/erc/erc-spelling.el b/lisp/erc/erc-spelling.el
index 950a821e3c4..ddfaafb0483 100644
--- a/lisp/erc/erc-spelling.el
+++ b/lisp/erc/erc-spelling.el
@@ -24,7 +24,7 @@
;;; Commentary:
-;; This is an ERC module to enable flyspell mode in ERC buffers. This
+;; This is an ERC module to enable flyspell mode in ERC buffers. This
;; ensures correct behavior of flyspell, and even sets up a
;; channel-local dictionary if so required.
diff --git a/lisp/erc/erc-stamp.el b/lisp/erc/erc-stamp.el
index dde2556ddb7..7d31bc971e3 100644
--- a/lisp/erc/erc-stamp.el
+++ b/lisp/erc/erc-stamp.el
@@ -182,9 +182,9 @@ or `erc-send-modify-hook'."
(erc-echo-timestamp dir ct))))))))
(defvar-local erc-timestamp-last-window-width nil
- "Stores the width of the last window that showed the current
-buffer. This is used by `erc-insert-timestamp-right' when the
-current buffer is not shown in any window.")
+ "The width of the last window that showed the current buffer.
+his is used by `erc-insert-timestamp-right' when the current
+buffer is not shown in any window.")
(defvar-local erc-timestamp-last-inserted nil
"Last timestamp inserted into the buffer.")
@@ -200,7 +200,7 @@ This is used when `erc-insert-timestamp-function' is set to
`erc-timestamp-left-and-right'")
(defcustom erc-timestamp-only-if-changed-flag t
- "Insert timestamp only if its value changed since last insertion.
+ "Non-nil means insert timestamp only if its value changed since last insertion.
If `erc-insert-timestamp-function' is `erc-insert-timestamp-left', a
string of spaces which is the same size as the timestamp is added to
the beginning of the line in its place. If you use
@@ -316,10 +316,10 @@ printed just after each line's text (no alignment)."
(erc-put-text-property from (1+ (point)) 'cursor-intangible t)))))
(defun erc-insert-timestamp-left-and-right (_string)
- "This is another function that can be assigned to
-`erc-insert-timestamp-function'. If the date is changed, it will
-print a blank line, the date, and another blank line. If the time is
-changed, it will then print it off to the right."
+ "This is another function that can be used with `erc-insert-timestamp-function'.
+If the date is changed, it will print a blank line, the date, and
+another blank line. If the time is changed, it will then print
+it off to the right."
(let* ((ct (current-time))
(ts-left (erc-format-timestamp ct erc-timestamp-format-left))
(ts-right (erc-format-timestamp ct erc-timestamp-format-right)))
diff --git a/lisp/erc/erc-status-sidebar.el b/lisp/erc/erc-status-sidebar.el
index a75a74bb6fd..a6ad856bfd7 100644
--- a/lisp/erc/erc-status-sidebar.el
+++ b/lisp/erc/erc-status-sidebar.el
@@ -274,7 +274,7 @@ to the `window-configuration-change-hook'."
(apply #'window-preserve-size (selected-window) t t nil))))
(define-derived-mode erc-status-sidebar-mode special-mode "ERC Sidebar"
- "Major mode for ERC status sidebar"
+ "Major mode for ERC status sidebar."
;; Don't scroll the buffer horizontally, if a channel name is
;; obscured then the window can be resized.
(setq-local auto-hscroll-mode nil)
diff --git a/lisp/erc/erc-track.el b/lisp/erc/erc-track.el
index 2364d45d6f3..57553844900 100644
--- a/lisp/erc/erc-track.el
+++ b/lisp/erc/erc-track.el
@@ -104,14 +104,13 @@ channel (353)."
:type 'erc-message-type)
(defcustom erc-track-exclude-server-buffer nil
- "If true, don't perform tracking on the server buffer; this is
-useful for excluding all the things like MOTDs from the server and
-other miscellaneous functions."
+ "If true, don't perform tracking on the server buffer.
+This is useful for excluding all the things like MOTDs from the
+server and other miscellaneous functions."
:type 'boolean)
(defcustom erc-track-shorten-start 1
- "This number specifies the minimum number of characters a channel name in
-the mode-line should be reduced to."
+ "Minimum number of characters for a channel name in the mode-line."
:type 'number)
(defcustom erc-track-shorten-cutoff 4
@@ -149,8 +148,7 @@ If nil instead of a function, shortening is disabled."
function))
(defcustom erc-track-list-changed-hook nil
- "Hook that is run whenever the contents of
-`erc-modified-channels-alist' changes.
+ "Hook run when the contents of `erc-modified-channels-alist' changes.
This is useful for people that don't use the default mode-line
notification but instead use a separate mechanism to provide
@@ -262,14 +260,22 @@ nil - don't add to mode line."
(defvar erc-modified-channels-alist nil
"An ALIST used for tracking channel modification activity.
-Each element looks like (BUFFER COUNT FACE) where BUFFER is a buffer
-object of the channel the entry corresponds to, COUNT is a number
-indicating how often activity was noticed, and FACE is the face to use
-when displaying the buffer's name. See `erc-track-faces-priority-list',
-and `erc-track-showcount'.
-
-Entries in this list should only happen for buffers where activity occurred
-while the buffer was not visible.")
+Each element is a list of the form (BUFFER COUNT . FACE) where
+BUFFER is a buffer object of the channel the entry corresponds
+to, COUNT is a number indicating how often activity was noticed,
+and FACE is a face (or a list of faces, combined as usual) to use
+when displaying the buffer's name in the mode line.
+
+Entries in this list are only added/updated for buffers that were
+not visible when activity occurred in them, and are removed for
+each buffer as soon as it becomes visible again (or if the server
+is disconnected, provided `erc-track-remove-disconnected-buffers'
+is true).
+
+For how the face is chosen for a buffer, see
+`erc-track-select-mode-line-face' and
+`erc-track-priority-faces-only'. For how buffers are then
+displayed in the mode line, see `erc-modified-channels-display'.")
(defcustom erc-track-showcount nil
"If non-nil, count of unseen messages will be shown for each channel."
@@ -538,8 +544,7 @@ keybindings will not do anything useful."
(erc-track-minor-mode -1)))))
(defcustom erc-track-when-inactive nil
- "Enable channel tracking even for visible buffers, if you are
-inactive."
+ "Enable channel tracking even for visible buffers, if you are inactive."
:type 'boolean
:set (lambda (sym val)
(if erc-track-mode
@@ -590,15 +595,15 @@ only consider active buffers visible.")
(erc-modified-channels-update)))
(defvar erc-modified-channels-update-inside nil
- "Variable to prevent running `erc-modified-channels-update' multiple
-times. Without it, you cannot debug `erc-modified-channels-display',
-because the debugger also causes changes to the window-configuration.")
+ "Variable to prevent running `erc-modified-channels-update' multiple times.
+Without it, you cannot debug `erc-modified-channels-display',
+because the debugger also causes changes to the
+window-configuration.")
(defun erc-modified-channels-update (&rest _args)
- "This function updates the information in `erc-modified-channels-alist'
-according to buffer visibility. It calls
-`erc-modified-channels-display' at the end. This should usually be
-called via `window-configuration-change-hook'.
+ "Update `erc-modified-channels-alist' according to buffer visibility.
+It calls `erc-modified-channels-display' at the end. This should
+usually be called via `window-configuration-change-hook'.
ARGS are ignored."
(interactive)
(unless erc-modified-channels-update-inside
@@ -622,8 +627,14 @@ ARGS are ignored."
"The face to use when mouse is over channel names in the mode line.")
(defun erc-make-mode-line-buffer-name (string buffer &optional faces count)
- "Return STRING as a button that switches to BUFFER when clicked.
-If FACES are provided, color STRING with them."
+ "Return a button that switches to BUFFER when clicked.
+STRING is the string in the button. It is possibly suffixed with
+the number of unread messages, according to variables
+`erc-track-showcount' and `erc-track-showcount-string'.
+
+If `erc-track-use-faces' is true and FACES are provided, format
+STRING with them. When the mouse hovers above the button, STRING
+is displayed according to `erc-track-mouse-face'."
;; We define a new sparse keymap every time, because 1. this data
;; structure is very small, the alternative would require us to
;; defvar a keymap, 2. the user is not interested in customizing it
@@ -661,8 +672,7 @@ If FACES are provided, color STRING with them."
name))
(defun erc-modified-channels-display ()
- "Set `erc-modified-channels-object'
-according to `erc-modified-channels-alist'.
+ "Set `erc-modified-channels-object' according to `erc-modified-channels-alist'.
Use `erc-make-mode-line-buffer-name' to create buttons."
(cond ((or (eq 'mostactive erc-track-switch-direction)
(eq 'leastactive erc-track-switch-direction))
@@ -720,43 +730,55 @@ Use `erc-make-mode-line-buffer-name' to create buttons."
(erc-modified-channels-display)))
(defun erc-track-find-face (faces)
- "Return the face to use in the mode line from the faces in FACES.
-If `erc-track-faces-priority-list' is set, the one from FACES who
-is first in that list will be used. If nothing matches or if
-`erc-track-faces-priority-list' is not set, the default mode-line
-faces will be used.
-
-If `erc-track-faces-normal-list' is non-nil, use it to produce a
-blinking effect that indicates channel activity when the first
-element in FACES and the highest-ranking face among the rest of
-FACES are both members of `erc-track-faces-normal-list'.
-
-If one of the faces is a list, then it will be ranked according
-to its highest-tanking face member. A list of faces including
-that member will take priority over just the single member
-element."
+ "Return the face to use in the mode line."
+ (declare (obsolete erc-track-select-mode-line-face "28.1"))
+ (erc-track-select-mode-line-face (car faces) (cdr faces)))
+
+(defun erc-track-select-mode-line-face (cur-face new-faces)
+ "Return the face to use in the mode line.
+
+CUR-FACE is the face currently used in the mode line (for the
+current buffer). NEW-FACES is the list of new faces that have
+just been seen (in the current buffer).
+
+Initially, the selected face is the one with highest priority in
+`erc-track-faces-priority-list' (i.e., the one closest to the
+front of the list) among CUR-FACE and NEW-FACES. If nothing
+matches (including if `erc-track-faces-priority-list' is not
+set), the default mode-line faces will be used (NIL is returned).
+
+If the selected face is still CUR-FACE (highest priority), and
+the highest priority face in NEW-FACES alone is different (which
+necessarily means it has lower priority than CUR-FACE), and both
+are in `erc-track-faces-normal-list', then the latter is selected
+instead. This has the effect of allowing the current mode line
+face, if a member of `erc-track-faces-normal-list', to be
+replaced with another with lower priority face from NEW-FACES, if
+that face with highest priority in NEW-FACES is also a member of
+`erc-track-faces-normal-list'."
(let ((choice (catch 'face
- (dolist (candidate erc-track-faces-priority-list)
- (when (member candidate faces)
- (throw 'face candidate)))))
- (no-first (and erc-track-faces-normal-list
- (catch 'face
- (dolist (candidate erc-track-faces-priority-list)
- (when (member candidate (cdr faces))
- (throw 'face candidate)))))))
- (cond ((null choice)
- nil)
- ((and (member choice erc-track-faces-normal-list)
- (member no-first erc-track-faces-normal-list))
- no-first)
- (t
- choice))))
+ (dolist (candidate erc-track-faces-priority-list)
+ (when (or (equal candidate cur-face)
+ (member candidate new-faces))
+ (throw 'face candidate))))))
+ (when choice
+ (if (and (equal choice cur-face)
+ (member choice erc-track-faces-normal-list))
+ (let ((only-in-new
+ (catch 'face
+ (dolist (candidate erc-track-faces-priority-list)
+ (when (member candidate new-faces)
+ (throw 'face candidate))))))
+ (if (member only-in-new erc-track-faces-normal-list)
+ only-in-new
+ choice))
+ choice))))
(defun erc-track-modified-channels ()
- "Hook function for `erc-insert-post-hook' to check if the current
-buffer should be added to the mode line as a hidden, modified
-channel. Assumes it will only be called when current-buffer
-is in `erc-mode'."
+ "Hook function for `erc-insert-post-hook'.
+Check if the current buffer should be added to the mode line as a
+hidden, modified channel. Assumes it will only be called when
+the current buffer is in `erc-mode'."
(let ((this-channel (or (erc-default-target)
(buffer-name (current-buffer)))))
(if (and (not (erc-buffer-visible (current-buffer)))
@@ -790,17 +812,17 @@ is in `erc-mode'."
;; Add buffer, faces and counts
(setq erc-modified-channels-alist
(cons (cons (current-buffer)
- (cons 1 (erc-track-find-face faces)))
+ (cons
+ 1 (erc-track-select-mode-line-face
+ nil faces)))
erc-modified-channels-alist))
;; Else modify the face for the buffer, if necessary.
(when faces
(let* ((cell (assq (current-buffer)
erc-modified-channels-alist))
(old-face (cddr cell))
- (new-face (erc-track-find-face
- (if old-face
- (cons old-face faces)
- faces))))
+ (new-face (erc-track-select-mode-line-face
+ old-face faces)))
(setcdr cell (cons (1+ (cadr cell)) new-face)))))
;; And display it
(erc-modified-channels-display)))
@@ -832,8 +854,7 @@ is in `erc-mode'."
;;; Buffer switching
(defvar erc-track-last-non-erc-buffer nil
- "Stores the name of the last buffer you were in before activating
-`erc-track-switch-buffer'.")
+ "Name of the last buffer before activating `erc-track-switch-buffer'.")
(defun erc-track-sort-by-activest ()
"Sort erc-modified-channels-alist by activity.
@@ -843,9 +864,8 @@ That means the number of unseen messages in a channel."
(lambda (a b) (> (nth 1 a) (nth 1 b))))))
(defun erc-track-face-priority (face)
- "Return a number indicating the priority of FACE in
-`erc-track-faces-priority-list'. Lower number means higher
-priority.
+ "Return priority (a number) of FACE in `erc-track-faces-priority-list'.
+Lower number means higher priority.
If face is not in `erc-track-faces-priority-list', it will have a
higher number than any other face in that list."
diff --git a/lisp/erc/erc-truncate.el b/lisp/erc/erc-truncate.el
index ff33fbc5570..2c4002f0ee0 100644
--- a/lisp/erc/erc-truncate.el
+++ b/lisp/erc/erc-truncate.el
@@ -25,8 +25,8 @@
;;; Commentary:
;; This implements buffer truncation (and optional log file writing
-;; support for the Emacs IRC client. Use `erc-truncate-mode' to switch
-;; on. Use `erc-enable-logging' to enable logging of the stuff which
+;; support for the Emacs IRC client. Use `erc-truncate-mode' to switch
+;; on. Use `erc-enable-logging' to enable logging of the stuff which
;; is getting truncated.
;;; Code:
@@ -34,7 +34,7 @@
(require 'erc)
(defgroup erc-truncate nil
- "Truncate buffers when they reach a certain size"
+ "Truncate buffers when they reach a certain size."
:group 'erc)
(defcustom erc-max-buffer-size 30000
diff --git a/lisp/erc/erc-xdcc.el b/lisp/erc/erc-xdcc.el
index e1b9f0de3a7..c17eb59da31 100644
--- a/lisp/erc/erc-xdcc.el
+++ b/lisp/erc/erc-xdcc.el
@@ -68,7 +68,7 @@ being evaluated and should return strings."
;;;###autoload
(defun erc-xdcc-add-file (file)
- "Add a file to `erc-xdcc-files'."
+ "Add FILE to `erc-xdcc-files'."
(interactive "fFilename to add to XDCC: ")
(if (file-exists-p file)
(add-to-list 'erc-xdcc-files file)))
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 73202016ba7..df6c3c09d90 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -3,6 +3,7 @@
;; Copyright (C) 1997-2021 Free Software Foundation, Inc.
;; Author: Alexander L. Belikoff (alexander@belikoff.net)
+;; Maintainer: Amin Bandali <bandali@gnu.org>
;; Contributors: Sergey Berezin (sergey.berezin@cs.cmu.edu),
;; Mario Lang (mlang@delysid.org),
;; Alex Schroeder (alex@gnu.org)
@@ -11,10 +12,10 @@
;; David Edmondson (dme@dme.org)
;; Michael Olson (mwolson@gnu.org)
;; Kelvin White (kwhite@gnu.org)
-;; Maintainer: Amin Bandali <bandali@gnu.org>
+;; Version: 5.4.1
+;; Package-Requires: ((emacs "27.1"))
;; Keywords: IRC, chat, client, Internet
-
-;; Version: 5.3
+;; URL: https://www.gnu.org/software/emacs/erc.html
;; This file is part of GNU Emacs.
@@ -57,7 +58,7 @@
;;; Code:
-(load "erc-loaddefs" nil t)
+(load "erc-loaddefs" 'noerror 'nomessage)
(require 'cl-lib)
(require 'format-spec)
@@ -68,10 +69,23 @@
(require 'iso8601)
(eval-when-compile (require 'subr-x))
+(defconst erc-version "5.4.1"
+ "This version of ERC.")
+
(defvar erc-official-location
"https://www.gnu.org/software/emacs/erc.html (mailing list: emacs-erc@gnu.org)"
"Location of the ERC client on the Internet.")
+;; Map each :package-version to the associated Emacs version.
+;; (This eliminates the need for explicit :version keywords on the
+;; custom definitions.)
+(add-to-list
+ 'customize-package-emacs-version-alist
+ '(ERC ("5.2" . "22.1")
+ ("5.3" . "23.1")
+ ("5.4" . "28.1")
+ ("5.4.1" . "29.1")))
+
(defgroup erc nil
"Emacs Internet Relay Chat client."
:link '(url-link "https://www.gnu.org/software/emacs/erc.html")
@@ -80,32 +94,32 @@
:group 'applications)
(defgroup erc-buffers nil
- "Creating new ERC buffers"
+ "Creating new ERC buffers."
:group 'erc)
(defgroup erc-display nil
- "Settings for how various things are displayed"
+ "Settings for how various things are displayed."
:group 'erc)
(defgroup erc-mode-line-and-header nil
- "Displaying information in the mode-line and header"
+ "Displaying information in the mode-line and header."
:group 'erc-display)
(defgroup erc-ignore nil
- "Ignoring certain messages"
+ "Ignoring certain messages."
:group 'erc)
(defgroup erc-lurker nil
- "Hide specified message types sent by lurkers"
+ "Hide specified message types sent by lurkers."
:version "24.3"
:group 'erc-ignore)
(defgroup erc-query nil
- "Using separate buffers for private discussions"
+ "Using separate buffers for private discussions."
:group 'erc)
(defgroup erc-quit-and-part nil
- "Quitting and parting channels"
+ "Quitting and parting channels."
:group 'erc)
(defgroup erc-paranoia nil
@@ -113,7 +127,7 @@
:group 'erc)
(defgroup erc-scripts nil
- "Running scripts at startup and with /LOAD"
+ "Running scripts at startup and with /LOAD."
:group 'erc)
(require 'erc-backend)
@@ -157,9 +171,7 @@ parameters and authentication."
:type 'string)
(defcustom erc-try-new-nick-p t
- "If the nickname you chose isn't available, and this option is non-nil,
-ERC should automatically attempt to connect with another nickname.
-
+ "Non-nil means attempt to connect with another nickname if nickname unavailable.
You can manually set another nickname with the /NICK command."
:group 'erc
:type 'boolean)
@@ -189,10 +201,12 @@ parameters and authentication."
It is not strictly necessary to provide this, since ERC will
prompt you for it.")
-(defcustom erc-user-mode nil
+(defcustom erc-user-mode "+i"
+ ;; +i "Invisible". Hides user from global /who and /names.
"Initial user modes to be set after a connection is established."
:group 'erc
- :type '(choice (const nil) string function))
+ :type '(choice (const nil) string function)
+ :version "28.1")
(defcustom erc-prompt-for-password t
@@ -280,9 +294,9 @@ indicate it has handled the input."
:type 'hook)
(defcustom erc-join-hook nil
- "Hook run when we join a channel. Hook functions are called
-without arguments, with the current buffer set to the buffer of
-the new channel.
+ "Hook run when we join a channel.
+Hook functions are called without arguments, with the current
+buffer set to the buffer of the new channel.
See also `erc-server-JOIN-functions', `erc-part-hook'."
:group 'erc-hooks
@@ -328,15 +342,15 @@ Functions are passed a buffer as the first argument."
(defvar-local erc-channel-users nil
- "A hash table of members in the current channel, which
-associates nicknames with cons cells of the form:
+ "Hash table of members in the current channel.
+It associates nicknames with cons cells of the form:
\(USER . MEMBER-DATA) where USER is a pointer to an
erc-server-user struct, and MEMBER-DATA is a pointer to an
erc-channel-user struct.")
(defvar-local erc-server-users nil
- "A hash table of users on the current server, which associates
-nicknames with erc-server-user struct instances.")
+ "Hash table of users on the current server.
+It associates nicknames with `erc-server-user' struct instances.")
(defun erc-downcase (string)
"Convert STRING to IRC standard conforming downcase."
@@ -380,13 +394,11 @@ If no server buffer exists, return nil."
(last-message-time nil))
(define-inline erc-get-channel-user (nick)
- "Find the (USER . CHANNEL-DATA) element corresponding to NICK
-in the current buffer's `erc-channel-users' hash table."
+ "Find NICK in the current buffer's `erc-channel-users' hash table."
(inline-quote (gethash (erc-downcase ,nick) erc-channel-users)))
(define-inline erc-get-server-user (nick)
- "Find the USER corresponding to NICK in the current server's
-`erc-server-users' hash table."
+ "Find NICK in the current server's `erc-server-users' hash table."
(inline-letevals (nick)
(inline-quote (erc-with-server-buffer
(gethash (erc-downcase ,nick) erc-server-users)))))
@@ -533,10 +545,10 @@ Removes all users in the current channel. This is called by
(erc-channel-user-voice (cdr cdata))))))))
(defun erc-get-channel-user-list ()
- "Return a list of users in the current channel. Each element
-of the list is of the form (USER . CHANNEL-DATA), where USER is
-an erc-server-user struct, and CHANNEL-DATA is either nil or an
-erc-channel-user struct.
+ "Return a list of users in the current channel.
+Each element of the list is of the form (USER . CHANNEL-DATA),
+where USER is an erc-server-user struct, and CHANNEL-DATA is
+either nil or an erc-channel-user struct.
See also: `erc-sort-channel-users-by-activity'."
(let (users)
@@ -816,7 +828,7 @@ set if some hacker is trying to flood you away."
(defcustom erc-system-name nil
"Use this as the name of your system.
-If nil, ERC will call `system-name' to get this information."
+If nil, ERC will call function `system-name' to get this information."
:group 'erc
:type '(choice (const :tag "Default system name" nil)
string))
@@ -860,8 +872,8 @@ See `erc-server-flood-margin' for other flood-related parameters.")
;; Script parameters
(defcustom erc-startup-file-list
- (list (concat user-emacs-directory ".ercrc.el")
- (concat user-emacs-directory ".ercrc")
+ (list (locate-user-emacs-file ".ercrc.el")
+ (locate-user-emacs-file ".ercrc")
"~/.ercrc.el" "~/.ercrc" ".ercrc.el" ".ercrc")
"List of files to try for a startup script.
The first existent and readable one will get executed.
@@ -1280,7 +1292,7 @@ Example:
#\\='erc-replace-insert))
((remove-hook \\='erc-insert-modify-hook
#\\='erc-replace-insert)))"
- (declare (doc-string 3))
+ (declare (doc-string 3) (indent defun))
(let* ((sn (symbol-name name))
(mode (intern (format "erc-%s-mode" (downcase sn))))
(group (intern (format "erc-%s" (downcase sn))))
@@ -1383,8 +1395,7 @@ If BUFFER is nil, the current buffer is used."
(null (erc-default-target)))))
(defun erc-open-server-buffer-p (&optional buffer)
- "Return non-nil if argument BUFFER is an ERC server buffer that
-has an open IRC process.
+ "Return non-nil if BUFFER is an ERC server buffer with an open IRC process.
If BUFFER is nil, the current buffer is used."
(and (erc-server-buffer-p buffer)
@@ -1468,6 +1479,7 @@ Defaults to the server buffer."
(define-derived-mode erc-mode fundamental-mode "ERC"
"Major mode for Emacs IRC."
+ :interactive nil
(setq local-abbrev-table erc-mode-abbrev-table)
(setq-local next-line-add-newlines nil)
(setq line-move-ignore-invisible t)
@@ -1487,8 +1499,8 @@ Defaults to the server buffer."
"IRC port to use if it cannot be detected otherwise.")
(defconst erc-default-port-tls 6697
- "IRC port to use for encrypted connections if it cannot be
- detected otherwise.")
+ "IRC port to use for encrypted connections if it cannot be \
+detected otherwise.")
(defcustom erc-join-buffer 'buffer
"Determines how to display a newly created IRC buffer.
@@ -1732,20 +1744,11 @@ FORMS will be evaluated in all buffers having the process PROCESS and
where PRED matches or in all buffers of the server process if PRED is
nil."
(declare (indent 1) (debug (form form body)))
- ;; Make the evaluation have the correct order
- (let ((pre (make-symbol "pre"))
- (pro (make-symbol "pro")))
- `(let* ((,pro ,process)
- (,pre ,pred)
- (res (mapcar (lambda (buffer)
- (with-current-buffer buffer
- ,@forms))
- (erc-buffer-list ,pre
- ,pro))))
- ;; Silence the byte-compiler by binding the result of mapcar to
- ;; a variable.
- (ignore res)
- res)))
+ (macroexp-let2 nil pred pred
+ `(erc-buffer-filter (lambda ()
+ (when (or (not ,pred) (funcall ,pred))
+ ,@forms))
+ ,process)))
(define-obsolete-function-alias 'erc-iswitchb #'erc-switch-to-buffer "25.1")
(defun erc--switch-to-buffer (&optional arg)
@@ -2271,7 +2274,7 @@ first element is the certificate key file name, and the second
element is the certificate file name itself, or t, which means
that `auth-source' will be queried for the key and the
certificate. Authenticating using a TLS client certificate is
-also refered to as \"CertFP\" (Certificate Fingerprint)
+also referred to as \"CertFP\" (Certificate Fingerprint)
authentication by various IRC networks.
Example usage:
@@ -2312,6 +2315,22 @@ message instead, to make debugging easier."
;;; Debugging the protocol
+(defvar erc-debug-irc-protocol-time-format "%FT%T.%6N%z "
+ "Timestamp format string for protocol logger.")
+
+(defconst erc-debug-irc-protocol-version "1"
+ "Protocol log format version number.
+This exists to help tooling track changes to the format.
+
+In version 1, everything before and including the first double CRLF is
+front matter, which must also be CRLF terminated. Lines beginning with
+three asterisks must be ignored as comments. Other lines should be
+interpreted as email-style headers. Folding is not supported. A second
+double CRLF, if present, signals the end of a log. Session resumption
+is not supported. Logger lines must adhere to the following format:
+TIMESTAMP PEER-NAME FLOW-INDICATOR IRC-MESSAGE CRLF. Outgoing messages
+are indicated with a >> and incoming with a <<.")
+
(defvar erc-debug-irc-protocol nil
"If non-nil, log all IRC protocol traffic to the buffer \"*erc-protocol*\".
@@ -2333,32 +2352,32 @@ This only has any effect if `erc-debug-irc-protocol' is non-nil.
The buffer is created if it doesn't exist.
-If OUTBOUND is non-nil, STRING is being sent to the IRC server
-and appears in face `erc-input-face' in the buffer."
+If OUTBOUND is non-nil, STRING is being sent to the IRC server and
+appears in face `erc-input-face' in the buffer. Lines must already
+contain CRLF endings. Peer is identified by the most precise label
+available at run time, starting with the network name, followed by the
+announced host name, and falling back to the dialed <server>:<port>."
(when erc-debug-irc-protocol
- (let ((network-name (or (ignore-errors (erc-network-name))
- "???")))
+ (let ((esid (or (and (fboundp 'erc-network)
+ (erc-network)
+ (erc-network-name))
+ erc-server-announced-name
+ (format "%s:%s" erc-session-server erc-session-port)))
+ (ts (when erc-debug-irc-protocol-time-format
+ (format-time-string erc-debug-irc-protocol-time-format))))
(with-current-buffer (get-buffer-create "*erc-protocol*")
(save-excursion
(goto-char (point-max))
(let ((inhibit-read-only t))
- (insert (if (not outbound)
- ;; Cope with the fact that string might
- ;; contain multiple lines of text.
- (let ((lines (delete "" (split-string string
- "\n\\|\r\n")))
- (result ""))
- (dolist (line lines)
- (setq result (concat result network-name
- " << " line "\n")))
- result)
- (propertize
- (concat network-name " >> " string
- (if (/= ?\n
- (aref string
- (1- (length string))))
- "\n"))
- 'font-lock-face 'erc-input-face)))))
+ (insert (if outbound
+ (concat ts esid " >> " string)
+ ;; Cope with multi-line messages
+ (let ((lines (split-string string "[\r\n]+" t))
+ result)
+ (dolist (line lines)
+ (setq result (concat result ts esid
+ " << " line "\r\n")))
+ result)))))
(let ((orig-win (selected-window))
(debug-buffer-window (get-buffer-window (current-buffer) t)))
(when debug-buffer-window
@@ -2377,9 +2396,18 @@ If ARG is non-nil, show the *erc-protocol* buffer."
(with-current-buffer buf
(view-mode-enter)
(when (null (current-local-map))
- (let ((inhibit-read-only t))
- (insert (erc-make-notice "This buffer displays all IRC protocol traffic exchanged with each server.\n"))
- (insert (erc-make-notice "Kill this buffer to terminate protocol logging.\n\n")))
+ (let ((inhibit-read-only t)
+ (msg (list
+ (concat "Version: " erc-debug-irc-protocol-version)
+ (concat "ERC-Version: " erc-version)
+ (concat "Emacs-Version: " emacs-version)
+ (erc-make-notice
+ (concat "This buffer displays all IRC protocol "
+ "traffic exchanged with servers."))
+ (erc-make-notice "Kill it to disable logging.")
+ (erc-make-notice (substitute-command-keys
+ "Press \\`t' to toggle.")))))
+ (insert (string-join msg "\r\n")))
(use-local-map (make-sparse-keymap))
(local-set-key (kbd "t") 'erc-toggle-debug-irc-protocol))
(add-hook 'kill-buffer-hook
@@ -2387,10 +2415,12 @@ If ARG is non-nil, show the *erc-protocol* buffer."
nil 'local)
(goto-char (point-max))
(let ((inhibit-read-only t))
- (insert (erc-make-notice
- (format "IRC protocol logging %s at %s -- Press `t' to toggle logging.\n"
+ (insert (if erc-debug-irc-protocol "\r\n" "")
+ (erc-make-notice
+ (format "IRC protocol logging %s at %s"
(if erc-debug-irc-protocol "disabled" "enabled")
- (current-time-string))))))
+ (current-time-string)))
+ (if erc-debug-irc-protocol "\r\n" "\r\n\r\n"))))
(setq erc-debug-irc-protocol (not erc-debug-irc-protocol))
(if (and arg
(not (get-buffer-window "*erc-protocol*" t)))
@@ -2583,9 +2613,8 @@ See also `erc-lurker-trim-nicks'."
Returns NICK unmodified unless `erc-lurker-trim-nicks' is
non-nil."
(if erc-lurker-trim-nicks
- (replace-regexp-in-string
- (regexp-opt-charset (string-to-list erc-lurker-ignore-chars))
- "" nick)
+ (string-trim-right
+ nick (rx-to-string `(+ (in ,@(string-to-list erc-lurker-ignore-chars)))))
nick))
(defcustom erc-lurker-hide-list nil
@@ -2709,9 +2738,8 @@ displayed hostnames."
:type 'alist)
(defun erc-canonicalize-server-name (server)
- "Return the canonical network name for SERVER if any,
-otherwise `erc-server-announced-name'. SERVER is matched against
-`erc-common-server-suffixes'."
+ "Return canonical network name for SERVER or `erc-server-announced-name'.
+SERVER is matched against `erc-common-server-suffixes'."
(when server
(or (cdar (cl-remove-if-not
(lambda (net) (string-match (car net) server))
@@ -2791,20 +2819,17 @@ present."
(let ((prop-val (erc-get-parsed-vector position)))
(and prop-val (member (erc-response.command prop-val) list))))
-(defvar-local erc-send-input-line-function 'erc-send-input-line)
+(defvar-local erc-send-input-line-function 'erc-send-input-line
+ "Function for sending lines lacking a leading user command.
+When a line typed into a buffer contains an explicit command, like /msg,
+a corresponding handler (here, erc-cmd-MSG) is called. But lines typed
+into a channel or query buffer already have an implicit target and
+command (PRIVMSG). This function is called on such occasions and also
+for special purposes (see erc-dcc.el).")
(defun erc-send-input-line (target line &optional force)
- "Send LINE to TARGET.
-
-See also `erc-server-send'."
- (setq line (format "PRIVMSG %s :%s"
- target
- ;; If the line is empty, we still want to
- ;; send it - i.e. an empty pasted line.
- (if (string= line "\n")
- " \n"
- line)))
- (erc-server-send line force target))
+ "Send LINE to TARGET."
+ (erc-message "PRIVMSG" (concat target " " line) force))
(defun erc-get-arglist (fun)
"Return the argument list of a function without the parens."
@@ -2942,7 +2967,7 @@ Commands for which no erc-cmd-xxx exists, are tunneled through
this function. LINE is sent to the server verbatim, and
therefore has to contain the command itself as well."
(erc-log (format "cmd: DEFAULT: %s" line))
- (erc-server-send (substring line 1))
+ (erc-server-send (string-trim-right (substring line 1) "[\r\n]"))
t)
(defvar erc--read-time-period-history nil)
@@ -3288,19 +3313,39 @@ a script after exceeding the flood threshold."
t)
(t nil)))
-(defun erc-cmd-WHOIS (user &optional server)
- "Display whois information for USER.
+(defun erc-cmd-WHOIS (first &optional second)
+ "Display whois information for the given user.
+
+With one argument, FIRST is the nickname of the user to request
+whois information for.
-If SERVER is non-nil, use that, rather than the current server."
- ;; FIXME: is the above docstring correct? -- Lawrence 2004-01-08
- (let ((send (if server
- (format "WHOIS %s %s" user server)
- (format "WHOIS %s" user))))
+With two arguments, FIRST is the server, and SECOND is the user
+nickname.
+
+Specifying the server is useful for getting the time the user has
+been idle for, when the user is connected to a different server
+on the same IRC network. (Only the server a user is connected to
+knows how long the user has been idle for.)"
+ (let ((send (if second
+ (format "WHOIS %s %s" first second)
+ (format "WHOIS %s" first))))
(erc-log (format "cmd: %s" send))
(erc-server-send send)
t))
(defalias 'erc-cmd-WI #'erc-cmd-WHOIS)
+(defun erc-cmd-WII (nick)
+ "Display whois information for NICK, including idle time.
+
+This is a convenience function which calls `erc-cmd-WHOIS' with
+the given NICK for both arguments. Using NICK in place of the
+server argument -- effectively delegating to the IRC network the
+looking up of the server to which NICK is connected -- is not
+standardized, but is widely supported across IRC networks.
+
+See `erc-cmd-WHOIS' for more details."
+ (erc-cmd-WHOIS nick nick))
+
(defun erc-cmd-WHOAMI ()
"Display whois information about yourself."
(erc-cmd-WHOIS (erc-current-nick))
@@ -3545,8 +3590,7 @@ just as you provided it. Use this command with care!"
(put 'erc-cmd-QUOTE 'do-not-parse-args t)
(defcustom erc-query-display 'window
- "Indicates how to display query buffers when using the /QUERY
-command to talk to someone.
+ "How to display query buffers when using the /QUERY command to talk to someone.
The default behavior is to display the message in a new window
and bring it to the front. See the documentation for
@@ -3564,11 +3608,13 @@ other people should be displayed."
(defun erc-cmd-QUERY (&optional user)
"Open a query with USER.
-The type of query window/frame/etc will depend on the value of
-`erc-query-display'.
-
-If USER is omitted, close the current query buffer if one exists
-- except this is broken now ;-)"
+How the query is displayed (in a new window, frame, etc.) depends
+on the value of `erc-query-display'."
+ ;; FIXME: The doc string used to say at the end:
+ ;; "If USER is omitted, close the current query buffer if one exists
+ ;; - except this is broken now ;-)"
+ ;; Does it make sense to have that functionality? What's wrong with
+ ;; `kill-buffer'? If it makes sense, re-add it. -- SK @ 2021-11-11
(interactive
(list (read-string "Start a query with: ")))
(let ((session-buffer (erc-server-buffer))
@@ -3582,7 +3628,7 @@ If USER is omitted, close the current query buffer if one exists
(defun erc-quit/part-reason-default ()
"Default quit/part message."
- (format "\C-bERC\C-b (IRC client for Emacs %s)" emacs-version))
+ (erc-version nil 'bold-erc))
(defun erc-quit-reason-normal (&optional s)
@@ -3597,7 +3643,9 @@ If S is non-nil, it will be used as the quit reason."
If S is non-nil, it will be used as the quit reason."
(or s
(if (fboundp 'yow)
- (string-replace "\n" "" (yow))
+ (if (>= emacs-major-version 28)
+ (string-replace "\n" "" (yow))
+ (replace-regexp-in-string "\n" "" (yow)))
(erc-quit/part-reason-default))))
(make-obsolete 'erc-quit-reason-zippy "it will be removed." "24.4")
@@ -3624,7 +3672,9 @@ If S is non-nil, it will be used as the part reason."
If S is non-nil, it will be used as the quit reason."
(or s
(if (fboundp 'yow)
- (string-replace "\n" "" (yow))
+ (if (>= emacs-major-version 28)
+ (string-replace "\n" "" (yow))
+ (replace-regexp-in-string "\n" "" (yow)))
(erc-quit/part-reason-default))))
(make-obsolete 'erc-part-reason-zippy "it will be removed." "24.4")
@@ -3706,13 +3756,17 @@ the message given by REASON."
(setq buffer (current-buffer)))
(with-current-buffer buffer
(setq erc-server-quitting nil)
- (setq erc-server-reconnecting t)
+ (with-suppressed-warnings ((obsolete erc-server-reconnecting))
+ (setq erc-server-reconnecting t))
+ (setq erc--server-reconnecting t)
(setq erc-server-reconnect-count 0)
(setq process (get-buffer-process (erc-server-buffer)))
(if process
(delete-process process)
(erc-server-reconnect))
- (setq erc-server-reconnecting nil)))
+ (with-suppressed-warnings ((obsolete erc-server-reconnecting))
+ (setq erc-server-reconnecting nil))
+ (setq erc--server-reconnecting nil)))
t)
(put 'erc-cmd-RECONNECT 'process-not-needed t)
@@ -3722,7 +3776,7 @@ the message given by REASON."
(condition-case nil
(erc :server server :nick (erc-current-nick))
(error
- (erc-error "Cannot find host %s." server)))
+ (erc-error "Cannot find host: `%s'" server)))
t)
(put 'erc-cmd-SERVER 'process-not-needed t)
@@ -3731,7 +3785,8 @@ the message given by REASON."
(defun erc-cmd-SV ()
"Say the current ERC and Emacs version into channel."
- (erc-send-message (format "I'm using ERC with GNU Emacs %s (%s%s)%s."
+ (erc-send-message (format "I'm using ERC %s with GNU Emacs %s (%s%s)%s."
+ erc-version
emacs-version
system-configuration
(concat
@@ -3783,6 +3838,24 @@ the message given by REASON."
(mapconcat #'identity people " ")))
t))
+(defun erc-cmd-OPME ()
+ "Ask ChanServ to op the current nick in the current channel.
+
+This command assumes a ChanServ (channel service) available on
+the IRC network which accepts an \"op\" command that takes the
+channel name and the user's nick, and that the current nick is
+allowed to become an operator in the current channel (typically
+means that the user has a +o flag in the channel's access list)."
+ (erc-message "PRIVMSG"
+ (format "ChanServ op %s %s"
+ (erc-default-target)
+ (erc-current-nick))
+ nil))
+
+(defun erc-cmd-DEOPME ()
+ "Deop the current nick in the current channel."
+ (erc-cmd-DEOP (erc-current-nick)))
+
(defun erc-cmd-TIME (&optional line)
"Request the current time and date from the current server."
(cond
@@ -4280,8 +4353,8 @@ disconnected, you should set this option to t."
:type 'boolean)
(defcustom erc-format-query-as-channel-p t
- "If non-nil, format text from others in a query buffer like in a channel,
-otherwise format like a private message."
+ "If non-nil, format text from others in a query buffer like in a channel.
+Otherwise format like a private message."
:group 'erc-query
:type 'boolean)
@@ -4471,7 +4544,7 @@ also `erc-format-nick-function'."
(propertize prefix 'font-lock-face 'erc-default-face))))
(defun erc-echo-notice-in-default-buffer (s parsed buffer _sender)
- "Echos a private notice in the default buffer, namely the
+ "Echo a private notice in the default buffer, namely the
target buffer specified by BUFFER, or there is no target buffer,
the server buffer. This function is designed to be added to
either `erc-echo-notice-hook' or `erc-echo-notice-always-hook',
@@ -4480,30 +4553,32 @@ and always returns t."
t)
(defun erc-echo-notice-in-target-buffer (s parsed buffer _sender)
- "Echos a private notice in BUFFER, if BUFFER is non-nil. This
-function is designed to be added to either `erc-echo-notice-hook'
-or `erc-echo-notice-always-hook', and returns non-nil if BUFFER
-is non-nil."
+ "Echo a private notice in BUFFER, if BUFFER is non-nil.
+This function is designed to be added to either
+`erc-echo-notice-hook' or `erc-echo-notice-always-hook', and
+returns non-nil if BUFFER is non-nil."
(if buffer
(progn (erc-display-message parsed nil buffer s) t)
nil))
(defun erc-echo-notice-in-minibuffer (s _parsed _buffer _sender)
- "Echos a private notice in the minibuffer. This function is
-designed to be added to either `erc-echo-notice-hook' or
-`erc-echo-notice-always-hook', and always returns t."
+ "Echo a private notice in the minibuffer.
+This function is designed to be added to either
+`erc-echo-notice-hook' or `erc-echo-notice-always-hook', and
+always returns t."
(message "%s" (concat "NOTICE: " s))
t)
(defun erc-echo-notice-in-server-buffer (s parsed _buffer _sender)
- "Echos a private notice in the server buffer. This function is
-designed to be added to either `erc-echo-notice-hook' or
-`erc-echo-notice-always-hook', and always returns t."
+ "Echo a private notice in the server buffer.
+This function is designed to be added to either
+`erc-echo-notice-hook' or `erc-echo-notice-always-hook', and
+always returns t."
(erc-display-message parsed nil nil s)
t)
(defun erc-echo-notice-in-active-non-server-buffer (s parsed _buffer _sender)
- "Echos a private notice in the active buffer if the active
+ "Echo a private notice in the active buffer if the active
buffer is not the server buffer. This function is designed to be
added to either `erc-echo-notice-hook' or
`erc-echo-notice-always-hook', and returns non-nil if the active
@@ -4513,15 +4588,16 @@ buffer is not the server buffer."
nil))
(defun erc-echo-notice-in-active-buffer (s parsed _buffer _sender)
- "Echos a private notice in the active buffer. This function is
-designed to be added to either `erc-echo-notice-hook' or
-`erc-echo-notice-always-hook', and always returns t."
+ "Echo a private notice in the active buffer.
+This function is designed to be added to either
+`erc-echo-notice-hook' or `erc-echo-notice-always-hook', and
+always returns t."
(erc-display-message parsed nil 'active s)
t)
(defun erc-echo-notice-in-user-buffers (s parsed _buffer sender)
- "Echos a private notice in all of the buffers for which SENDER
-is a member. This function is designed to be added to either
+ "Echo a private notice in all of the buffers for which SENDER is a member.
+This function is designed to be added to either
`erc-echo-notice-hook' or `erc-echo-notice-always-hook', and
returns non-nil if there is at least one buffer for which the
sender is a member.
@@ -4534,12 +4610,11 @@ See also: `erc-echo-notice-in-first-user-buffer',
nil)))
(defun erc-echo-notice-in-user-and-target-buffers (s parsed buffer sender)
- "Echos a private notice in BUFFER and in all of the buffers for
-which SENDER is a member. This function is designed to be added
-to either `erc-echo-notice-hook' or
-`erc-echo-notice-always-hook', and returns non-nil if there is
-at least one buffer for which the sender is a member or the
-default target.
+ "Echo a private notice in BUFFER and in all buffers for which SENDER is a member.
+This function is designed to be added to either
+`erc-echo-notice-hook' or `erc-echo-notice-always-hook', and
+returns non-nil if there is at least one buffer for which the
+sender is a member or the default target.
See also: `erc-echo-notice-in-user-buffers',
`erc-buffer-list-with-nick'."
@@ -4550,8 +4625,8 @@ See also: `erc-echo-notice-in-user-buffers',
nil)))
(defun erc-echo-notice-in-first-user-buffer (s parsed _buffer sender)
- "Echos a private notice in one of the buffers for which SENDER
-is a member. This function is designed to be added to either
+ "Echo a private notice in one of the buffers for which SENDER is a member.
+This function is designed to be added to either
`erc-echo-notice-hook' or `erc-echo-notice-always-hook', and
returns non-nil if there is at least one buffer for which the
sender is a member.
@@ -4790,8 +4865,8 @@ See also `erc-display-message'."
(unless erc-disable-ctcp-replies
(erc-send-ctcp-notice
nick (format
- "VERSION \C-bERC\C-b - an IRC client for Emacs %s (\C-b%s\C-b)"
- emacs-version
+ "VERSION %s (\C-b%s\C-b)"
+ (erc-version nil 'bold-erc)
erc-official-location)))
nil)
@@ -5011,10 +5086,11 @@ See also: `erc-update-user'."
(defun erc-update-user (user &optional new-nick
host login full-name info)
- "Update user info for USER. USER must be an erc-server-user
-struct. Any of NEW-NICK, HOST, LOGIN, FULL-NAME, INFO which are
-non-nil and not equal to the existing values for USER are used to
-replace the stored values in USER.
+ "Update user info for USER.
+USER must be an erc-server-user struct. Any of NEW-NICK, HOST,
+LOGIN, FULL-NAME, INFO which are non-nil and not equal to the
+existing values for USER are used to replace the stored values in
+USER.
If, and only if, a change is made,
`erc-channel-members-changed-hook' is run for each channel for
@@ -5159,8 +5235,7 @@ See also: `erc-update-user' and `erc-update-channel-member'."
(defun erc-update-channel-member (channel nick new-nick
&optional add voice halfop op admin owner host login
full-name info update-message-time)
- "Update user and channel information for the user with
-nickname NICK in channel CHANNEL.
+ "Update user and channel for user with nickname NICK in channel CHANNEL.
See also: `erc-update-current-channel-member'."
(erc-with-buffer
@@ -5551,9 +5626,9 @@ submitted line to be intentional."
string insertp sendp)
(defun erc-send-input (input)
- "Treat INPUT as typed in by the user. It is assumed that the input
-and the prompt is already deleted.
-This returns non-nil only if we actually send anything."
+ "Treat INPUT as typed in by the user.
+It is assumed that the input and the prompt is already deleted.
+Return non-nil only if we actually send anything."
;; Handle different kinds of inputs
(cond
;; Ignore empty input
@@ -5587,7 +5662,9 @@ This returns non-nil only if we actually send anything."
(when (and (erc-input-sendp state)
erc-send-this)
(let ((string (erc-input-string state)))
- (if (or (string-search "\n" string)
+ (if (or (if (>= emacs-major-version 28)
+ (string-search "\n" string)
+ (string-match "\n" string))
(not (string-match erc-command-regexp string)))
(mapc
(lambda (line)
@@ -5626,8 +5703,7 @@ This returns non-nil only if we actually send anything."
;; (run-hooks 'erc-send-post-hook))))))
(defun erc-display-msg (line)
- "Display LINE as a message of the user to the current target at the
-current position."
+ "Display LINE as a message of the user to the current target at point."
(when erc-insert-this
(let ((insert-position (point)))
(insert (erc-format-my-nick))
@@ -6359,8 +6435,8 @@ See `erc-mode-line-format' for which characters are can be used."
:type 'boolean)
(defcustom erc-header-line-uses-help-echo-p t
- "Show the contents of the header line in the echo area or as a tooltip
-when you move point into the header line."
+ "Show header line in echo area or as a tooltip
+when point moves to the header line."
:group 'erc-mode-line-and-header
:type 'boolean)
@@ -6449,8 +6525,7 @@ shortened server name instead."
(t (buffer-name (current-buffer))))))
(defun erc-format-away-status ()
- "Return a formatted `erc-mode-line-away-status-format'
-if `erc-away' is non-nil."
+ "Return a formatted `erc-mode-line-away-status-format' if `erc-away' is non-nil."
(let ((a (erc-away-time)))
(if a
(format-time-string erc-mode-line-away-status-format a)
@@ -6528,13 +6603,21 @@ if `erc-away' is non-nil."
(fill-region (point-min) (point-max))
(buffer-string))))
(setq header-line-format
- (string-replace
- "%"
- "%%"
- (if face
- (propertize header 'help-echo help-echo
- 'face face)
- (propertize header 'help-echo help-echo))))))
+ (if (>= emacs-major-version 28)
+ (string-replace
+ "%"
+ "%%"
+ (if face
+ (propertize header 'help-echo help-echo
+ 'face face)
+ (propertize header 'help-echo help-echo)))
+ (replace-regexp-in-string
+ "%"
+ "%%"
+ (if face
+ (propertize header 'help-echo help-echo
+ 'face face)
+ (propertize header 'help-echo help-echo)))))))
(t (setq header-line-format
(if face
(propertize header 'face face)
@@ -6553,6 +6636,15 @@ If BUFFER is nil, update the mode line in all ERC buffers."
;; Miscellaneous
+(defun erc-bug (subject)
+ "Send a bug report to the Emacs bug tracker and ERC mailing list."
+ (interactive "sBug Subject: ")
+ (report-emacs-bug
+ (format "ERC %s: %s" erc-version subject))
+ (save-excursion
+ (goto-char (point-min))
+ (insert "X-Debbugs-CC: emacs-erc@gnu.org\n")))
+
(defun erc-port-to-string (p)
"Convert port P to a string.
P may be an integer or a service name."
@@ -6569,12 +6661,18 @@ P may be an integer or a service name."
s
n))))
-(defun erc-version (&optional here)
+(defun erc-version (&optional here bold-erc)
"Show the version number of ERC in the minibuffer.
-If optional argument HERE is non-nil, insert version number at point."
+If optional argument HERE is non-nil, insert version number at point.
+If optional argument BOLD-ERC is non-nil, display \"ERC\" as bold."
(interactive "P")
(let ((version-string
- (format "ERC (IRC client for Emacs %s)" emacs-version)))
+ (format "%s %s (IRC client for GNU Emacs %s)"
+ (if bold-erc
+ "\C-bERC\C-b"
+ "ERC")
+ erc-version
+ emacs-version)))
(if here
(insert version-string)
(if (called-interactively-p 'interactive)
@@ -6804,7 +6902,9 @@ functions."
nick user host channel
(if (not (string= reason ""))
(format ": %s"
- (string-replace "%" "%%" reason))
+ (if (>= emacs-major-version 28)
+ (string-replace "%" "%%" reason)
+ (replace-regexp-in-string "%" "%%" reason)))
"")))))
diff --git a/lisp/eshell/em-basic.el b/lisp/eshell/em-basic.el
index 64fc7e7f03b..af5550b11df 100644
--- a/lisp/eshell/em-basic.el
+++ b/lisp/eshell/em-basic.el
@@ -164,7 +164,7 @@ or `eshell-printn' for display."
(set-default-file-modes
(- 511 (car (read-from-string
(concat "?\\" (number-to-string (car args)))))))
- (error "setting umask symbolically is not yet implemented"))
+ (error "Setting umask symbolically is not yet implemented"))
(eshell-print
"Warning: umask changed for all new files created by Emacs.\n"))
nil))
diff --git a/lisp/eshell/em-cmpl.el b/lisp/eshell/em-cmpl.el
index cbfe0b81545..4fd0afbeb88 100644
--- a/lisp/eshell/em-cmpl.el
+++ b/lisp/eshell/em-cmpl.el
@@ -72,6 +72,7 @@
(require 'esh-mode)
(require 'esh-util)
+(require 'em-dirs)
(eval-when-compile
(require 'cl-lib)
@@ -377,8 +378,12 @@ to writing a completion function."
(cl-assert (eq (car result) 'quote))
(cadr result))
arg)))
- (if (numberp val)
- (setq val (number-to-string val)))
+ (cond ((numberp val)
+ (setq val (number-to-string val)))
+ ;; expand .../ etc that only eshell understands to
+ ;; standard ../../
+ ((string-match "\\.\\.\\.+/" val)
+ (setq val (eshell-expand-multiple-dots val))))
(or val "")))
args)
posns)))
diff --git a/lisp/eshell/em-glob.el b/lisp/eshell/em-glob.el
index e36f2d0c7fe..ba12e43a3c2 100644
--- a/lisp/eshell/em-glob.el
+++ b/lisp/eshell/em-glob.el
@@ -91,7 +91,7 @@ This option slows down recursive glob processing by quite a bit."
(defcustom eshell-error-if-no-glob nil
"If non-nil, it is an error for a glob pattern not to match.
- This mimics the behavior of zsh if non-nil, but bash if nil."
+This mimics the behavior of zsh if non-nil, but bash if nil."
:type 'boolean
:group 'eshell-glob)
@@ -266,7 +266,7 @@ the form:
;; FIXME does this really need to abuse eshell-glob-matches, message-shown?
(defun eshell-glob-entries (path globs &optional recurse-p)
- "Glob the entries in PATHS, possibly recursing if RECURSE-P is non-nil."
+ "Glob the entries in PATH, possibly recursing if RECURSE-P is non-nil."
(let* ((entries (ignore-errors
(file-name-all-completions "" path)))
(case-fold-search eshell-glob-case-insensitive)
diff --git a/lisp/eshell/em-hist.el b/lisp/eshell/em-hist.el
index d82946add00..aa158fa24cc 100644
--- a/lisp/eshell/em-hist.el
+++ b/lisp/eshell/em-hist.el
@@ -402,7 +402,7 @@ variable `eshell-input-filter' returns non-nil when called on the
command.
This function is supposed to be called from the minibuffer, presumably
-as a minibuffer-exit-hook."
+as a `minibuffer-exit-hook'."
(eshell-add-input-to-history
(buffer-substring (minibuffer-prompt-end) (point-max))))
diff --git a/lisp/eshell/em-ls.el b/lisp/eshell/em-ls.el
index 3d7c43b404b..57146bb126d 100644
--- a/lisp/eshell/em-ls.el
+++ b/lisp/eshell/em-ls.el
@@ -35,10 +35,10 @@
;;;###autoload
(progn
(defgroup eshell-ls nil
- "This module implements the \"ls\" utility fully in Lisp. If it is
-passed any unrecognized command switches, it will revert to the
-operating system's version. This version of \"ls\" uses text
-properties to colorize its output based on the setting of
+ "This module implements the \"ls\" utility fully in Lisp.
+If it is passed any unrecognized command switches, it will revert
+to the operating system's version. This version of \"ls\" uses
+text properties to colorize its output based on the setting of
`eshell-ls-use-colors'."
:tag "Implementation of `ls' in Lisp"
:group 'eshell-module))
@@ -476,9 +476,9 @@ name should be displayed as, etc. Think of it as cooking a FILEINFO."
fileinfo)
(defun eshell-ls-file (fileinfo &optional size-width copy-fileinfo)
- "Output FILE in long format.
-FILE may be a string, or a cons cell whose car is the filename and
-whose cdr is the list of file attributes."
+ "Output FILEINFO in long format.
+FILEINFO may be a string, or a cons cell whose car is the
+filename and whose cdr is the list of file attributes."
(if (not (cdr fileinfo))
(funcall error-func (format "%s: No such file or directory\n"
(car fileinfo)))
diff --git a/lisp/eshell/em-pred.el b/lisp/eshell/em-pred.el
index def52f42e55..75a803d3ad4 100644
--- a/lisp/eshell/em-pred.el
+++ b/lisp/eshell/em-pred.el
@@ -258,7 +258,7 @@ EXAMPLES:
(eshell-pred-mode))
(defun eshell-apply-modifiers (lst predicates modifiers)
- "Apply to LIST a series of PREDICATES and MODIFIERS."
+ "Apply to list LST a series of PREDICATES and MODIFIERS."
(let (stringified)
(if (stringp lst)
(setq lst (list lst)
@@ -553,7 +553,7 @@ that `ls -l' will show in the first column of its display."
lst)))))
(defun eshell-include-members (&optional invert-p)
- "Include only lisp members matching a regexp."
+ "Include only Lisp members matching a regexp."
(let ((delim (char-after))
regexp end)
(forward-char)
diff --git a/lisp/eshell/em-rebind.el b/lisp/eshell/em-rebind.el
index fa61fffaec8..d70444ea109 100644
--- a/lisp/eshell/em-rebind.el
+++ b/lisp/eshell/em-rebind.el
@@ -168,7 +168,7 @@ This is default behavior of shells like bash."
(defun eshell-lock-local-map (&optional arg)
"Lock or unlock the current local keymap.
-Within a prefix arg, set the local keymap to its normal value, and
+With prefix ARG, set the local keymap to its normal value, and
lock it at that."
(interactive "P")
(if (or arg (not eshell-lock-keymap))
diff --git a/lisp/eshell/em-smart.el b/lisp/eshell/em-smart.el
index d1c83db188a..dffc8f804b7 100644
--- a/lisp/eshell/em-smart.el
+++ b/lisp/eshell/em-smart.el
@@ -131,7 +131,7 @@ only if that output can be presented in its entirely in the Eshell window."
:group 'eshell-smart)
(defcustom eshell-smart-space-goes-to-end t
- "If non-nil, space will go to end of buffer when point-max is visible.
+ "If non-nil, space will go to end of buffer when `point-max' is visible.
That is, if a command is running and the user presses SPACE at a time
when the end of the buffer is visible, point will go to the end of the
buffer and smart-display will be turned off (that is, subsequently
@@ -195,7 +195,7 @@ The options are `begin', `after' or `end'."
;; This is called by window-scroll-functions with two arguments.
(defun eshell-smart-scroll-window (wind _start)
- "Scroll the given Eshell window accordingly."
+ "Scroll the given Eshell window WIND accordingly."
(unless eshell-currently-handling-window
(let ((inhibit-point-motion-hooks t)
(eshell-currently-handling-window t))
diff --git a/lisp/eshell/em-term.el b/lisp/eshell/em-term.el
index d199a939a31..f9d8acccf26 100644
--- a/lisp/eshell/em-term.el
+++ b/lisp/eshell/em-term.el
@@ -92,13 +92,13 @@ See also `eshell-visual-commands' and `eshell-visual-options'."
(defcustom eshell-visual-options
nil
- "An alist of the form
+ "An alist of commands that present their output in a visual fashion.
+It has this form:
((COMMAND1 OPTION1 OPTION2...)
(COMMAND2 OPTION1 ...))
-of commands with options that present their output in a visual
-fashion. For example, a sensible entry would be
+For example, a sensible entry would be
(\"git\" \"--help\" \"--paginate\")
diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el
index 7e48a9c7578..e71edaf4765 100644
--- a/lisp/eshell/em-unix.el
+++ b/lisp/eshell/em-unix.el
@@ -165,7 +165,8 @@ Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine."
(put 'eshell/man 'eshell-no-numeric-conversions t)
(defun eshell/info (&rest args)
- "Run the info command in-frame with the same behavior as command-line `info', ie:
+ "Run the info command in-frame with the same behavior as command-line `info'.
+For example:
`info' => goes to top info window
`info arg1' => IF arg1 is a file, then visits arg1
`info arg1' => OTHERWISE goes to top info window and then menu item arg1
@@ -968,7 +969,7 @@ Show wall-clock time elapsed during execution of COMMAND.")
(set-window-configuration eshell-diff-window-config)))
(defun nil-blank-string (string)
- "Return STRING, or nil if STRING contains only non-blank characters."
+ "Return STRING, or nil if STRING contains only blank characters."
(cond
((string-match "[^[:blank:]]" string) string)
(nil)))
diff --git a/lisp/eshell/esh-arg.el b/lisp/eshell/esh-arg.el
index 3cf80e45187..1990c0cfa55 100644
--- a/lisp/eshell/esh-arg.el
+++ b/lisp/eshell/esh-arg.el
@@ -203,7 +203,7 @@ treated as a literal character."
(setq eshell-current-modifiers nil))
(defun eshell-finish-arg (&optional argument)
- "Finish the current argument being processed."
+ "Finish the current ARGUMENT being processed."
(if argument
(setq eshell-current-argument argument))
(throw 'eshell-arg-done t))
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index daca035ea49..213b7ab2893 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -116,9 +116,9 @@
(&optional form stub paring form-only))
(defgroup eshell-cmd nil
- "Executing an Eshell command is as simple as typing it in and
-pressing <RET>. There are several different kinds of commands,
-however."
+ "Executing an Eshell command is as simple as typing it in and \
+pressing \\<eshell-mode-map>\\[eshell-send-input].
+There are several different kinds of commands, however."
:tag "Command invocation"
;; :link '(info-link "(eshell)Command invocation")
:group 'eshell)
@@ -923,10 +923,10 @@ at the moment are:
(defun eshell-eval-command (command &optional input)
"Evaluate the given COMMAND iteratively."
(if eshell-current-command
- ;; we can just stick the new command at the end of the current
- ;; one, and everything will happen as it should
+ ;; We can just stick the new command at the end of the current
+ ;; one, and everything will happen as it should.
(setcdr (last (cdr eshell-current-command))
- (list `(let ((here (and (eobp) (point))))
+ (list `(let ((here (and (eobp) (point))))
,(and input
`(insert-and-inherit ,(concat input "\n")))
(if here
@@ -937,14 +937,20 @@ at the moment are:
(erase-buffer)
(insert "command: \"" input "\"\n")))
(setq eshell-current-command command)
- (let ((delim (catch 'eshell-incomplete
- (eshell-resume-eval))))
- ;; On systems that don't support async subprocesses, eshell-resume
- ;; can return t. Don't treat that as an error.
- (if (listp delim)
- (setq delim (car delim)))
- (if (and delim (not (eq delim t)))
- (error "Unmatched delimiter: %c" delim)))))
+ (let* ((delim (catch 'eshell-incomplete
+ (eshell-resume-eval)))
+ (val (car-safe delim)))
+ ;; If the return value of `eshell-resume-eval' is wrapped in a
+ ;; list, it indicates that the command was run asynchronously.
+ ;; In that case, unwrap the value before checking the delimiter
+ ;; value.
+ (if (and val
+ (not (eshell-processp val))
+ (not (eq val t)))
+ (error "Unmatched delimiter: %S" val)
+ ;; Eshell-command expect a list like (<process>) to know if the
+ ;; command should be async or not.
+ (or (and (eshell-processp val) delim) val)))))
(defun eshell-resume-command (proc status)
"Resume the current command when a process ends."
@@ -1230,10 +1236,10 @@ or an external command."
(eshell-external-command command args))))
(defun eshell-exec-lisp (printer errprint func-or-form args form-p)
- "Execute a lisp FUNC-OR-FORM, maybe passing ARGS.
+ "Execute a Lisp FUNC-OR-FORM, maybe passing ARGS.
PRINTER and ERRPRINT are functions to use for printing regular
messages, and errors. FORM-P should be non-nil if FUNC-OR-FORM
-represent a lisp form; ARGS will be ignored in that case."
+represent a Lisp form; ARGS will be ignored in that case."
(eshell-condition-case err
(let ((result
(save-current-buffer
diff --git a/lisp/eshell/esh-ext.el b/lisp/eshell/esh-ext.el
index 9930e0884cb..fa149dd46e3 100644
--- a/lisp/eshell/esh-ext.el
+++ b/lisp/eshell/esh-ext.el
@@ -110,7 +110,7 @@ wholly ignored."
(autoload 'eshell-parse-command "esh-cmd")
(defsubst eshell-invoke-batch-file (&rest args)
- "Invoke a .BAT or .CMD file on DOS/Windows systems."
+ "Invoke a .BAT or .CMD file on MS-DOS/MS-Windows systems."
;; since CMD.EXE can't handle forward slashes in the initial
;; argument...
(setcar args (subst-char-in-string ?/ ?\\ (car args)))
diff --git a/lisp/eshell/esh-io.el b/lisp/eshell/esh-io.el
index 0e98aa0049e..c2471912ab8 100644
--- a/lisp/eshell/esh-io.el
+++ b/lisp/eshell/esh-io.el
@@ -34,7 +34,7 @@
;;;_* Redirect to a Buffer or Process
;;
;; Buffers and processes can be named with '#<buffer buffer-name>' and
-;; '#<process process-name>', respectively. As a shorthand,
+;; '#<process process-name>', respectively. As a shorthand,
;; '#<buffer-name>' without the explicit "buffer" arg is equivalent to
;; '#<buffer buffer-name>'.
;;
@@ -94,7 +94,7 @@ though they were files."
Currently this is standard input, output and error. But even all of
these Emacs does not currently support with asynchronous processes
\(which is what eshell uses so that you can continue doing work in
-other buffers) ."
+other buffers)."
:type 'integer
:group 'eshell-io)
diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el
index f9dbce9770d..cae5236d894 100644
--- a/lisp/eshell/esh-mode.el
+++ b/lisp/eshell/esh-mode.el
@@ -308,13 +308,15 @@ and the hook `eshell-exit-hook'."
(make-local-variable 'eshell-command-running-string)
(let ((fmt (copy-sequence mode-line-format)))
(setq-local mode-line-format fmt))
- (let ((mode-line-elt (memq 'mode-line-modified mode-line-format)))
+ (let ((mode-line-elt (cdr (memq 'mode-line-front-space mode-line-format))))
(if mode-line-elt
(setcar mode-line-elt 'eshell-command-running-string))))
(setq-local bookmark-make-record-function #'eshell-bookmark-make-record)
(setq local-abbrev-table eshell-mode-abbrev-table)
+ (setq-local window-point-insertion-type t)
+
(setq-local list-buffers-directory (expand-file-name default-directory))
;; always set the tab width to 8 in Eshell buffers, since external
@@ -499,7 +501,7 @@ and the hook `eshell-exit-hook'."
(yank)))
(defun eshell-bol ()
- "Goes to the beginning of line, then skips past the prompt, if any."
+ "Go to the beginning of line, then skip past the prompt, if any."
(interactive)
(beginning-of-line)
(and eshell-skip-prompt-function
@@ -614,6 +616,14 @@ newline."
(and eshell-send-direct-to-subprocesses
proc-running-p))
(insert-before-markers-and-inherit ?\n))
+ ;; Delete and reinsert input. This seems like a no-op, except
+ ;; for the resulting entries in the undo list: undoing this
+ ;; insertion will delete the region, moving the process mark
+ ;; back to its original position.
+ (let ((text (buffer-substring eshell-last-output-end (point)))
+ (inhibit-read-only t))
+ (delete-region eshell-last-output-end (point))
+ (insert text))
(if proc-running-p
(progn
(eshell-update-markers eshell-last-output-end)
@@ -696,13 +706,10 @@ This is done after all necessary filtering has been done."
(setq oend (+ oend nchars)))
;; Let the ansi-color overlay hooks run.
(let ((inhibit-modification-hooks nil))
- (insert-before-markers string))
+ (insert string))
(if (= (window-start) (point))
(set-window-start (selected-window)
(- (point) nchars)))
- (if (= (point) eshell-last-input-end)
- (set-marker eshell-last-input-end
- (- eshell-last-input-end nchars)))
(set-marker eshell-last-output-start ostart)
(set-marker eshell-last-output-end (point))
(force-mode-line-update))
@@ -940,7 +947,14 @@ This function could be in the list `eshell-output-filter-functions'."
(beginning-of-line)
(if (re-search-forward eshell-password-prompt-regexp
eshell-last-output-end t)
- (eshell-send-invisible))))))
+ ;; Use `run-at-time' in order not to pause execution of
+ ;; the process filter with a minibuffer
+ (run-at-time
+ 0 nil
+ (lambda (current-buf)
+ (with-current-buffer current-buf
+ (eshell-send-invisible)))
+ (current-buffer)))))))
(custom-add-option 'eshell-output-filter-functions
'eshell-watch-for-password-prompt)
@@ -993,8 +1007,6 @@ This function could be in the list `eshell-output-filter-functions'."
;;; Bookmark support:
-(declare-function bookmark-make-record-default
- "bookmark" (&optional no-file no-context posn))
(declare-function bookmark-prop-get "bookmark" (bookmark prop))
(defun eshell-bookmark-name ()
diff --git a/lisp/eshell/esh-module.el b/lisp/eshell/esh-module.el
index 703179504c1..97ffedae62a 100644
--- a/lisp/eshell/esh-module.el
+++ b/lisp/eshell/esh-module.el
@@ -20,6 +20,8 @@
;; 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 'esh-util)
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el
index 72de6b13e2e..0eef45e0efb 100644
--- a/lisp/eshell/esh-util.el
+++ b/lisp/eshell/esh-util.el
@@ -63,11 +63,11 @@ has no effect."
Setting this to nil is offered as an aid to debugging only."
:type 'boolean)
-(defcustom eshell-private-file-modes 384 ; umask 177
+(defcustom eshell-private-file-modes #o600 ; umask 177
"The file-modes value to use for creating \"private\" files."
:type 'integer)
-(defcustom eshell-private-directory-modes 448 ; umask 077
+(defcustom eshell-private-directory-modes #o700 ; umask 077
"The file-modes value to use for creating \"private\" directories."
:type 'integer)
diff --git a/lisp/eshell/esh-var.el b/lisp/eshell/esh-var.el
index 5dc6a193050..fa9853ae00a 100644
--- a/lisp/eshell/esh-var.el
+++ b/lisp/eshell/esh-var.el
@@ -45,7 +45,7 @@
;;
;; $(lisp)
;;
-;; Returns result of lisp evaluation. Note: Used alone like this, it
+;; Returns result of Lisp evaluation. Note: Used alone like this, it
;; is identical to just saying (lisp); but with the variable expansion
;; form, the result may be interpolated a larger string, such as
;; '$(lisp)/other'.
diff --git a/lisp/eshell/eshell.el b/lisp/eshell/eshell.el
index 101ac860346..c66ad000722 100644
--- a/lisp/eshell/eshell.el
+++ b/lisp/eshell/eshell.el
@@ -33,15 +33,15 @@
;; @ A high degree of configurability
;;
;; @ The ability to have the same shell on every system Emacs has been
-;; ported to. Since Eshell imposes no external requirements, and
+;; ported to. Since Eshell imposes no external requirements, and
;; relies upon only the Lisp functions exposed by Emacs, it is quite
-;; operating system independent. Several of the common UNIX
+;; operating system independent. Several of the common UNIX
;; commands, such as ls, mv, rm, ln, etc., have been implemented in
;; Lisp in order to provide a more consistent work environment.
;;
;; For those who might be using an older version of Eshell, version
-;; 2.1 represents an entirely new, module-based architecture. It
-;; supports most of the features offered by modern shells. Here is a
+;; 2.1 represents an entirely new, module-based architecture. It
+;; supports most of the features offered by modern shells. Here is a
;; brief list of some of its more visible features:
;;
;; @ Command argument completion (tcsh, zsh)
@@ -136,7 +136,7 @@
;; errors, such as 'dri' for `dir'. Since executing non-existent
;; programs is rarely the intention of the user, eshell could prompt
;; for the replacement string, and then record that in a database of
-;; known misspellings. (Note: The typo at the beginning of this
+;; known misspellings. (Note: The typo at the beginning of this
;; paragraph wasn't discovered until two months after I wrote the
;; text; it was not intentional).
;;
@@ -240,7 +240,7 @@ session. Return the buffer selected (or created).
With a nonnumeric prefix arg, create a new session.
-With a numeric prefix arg (as in `C-u 42 M-x eshell RET'), switch
+With a numeric prefix arg (as in `\\[universal-argument] 42 \\[eshell]'), switch
to the session with that number, or create it if it doesn't
already exist.
diff --git a/lisp/expand.el b/lisp/expand.el
index 1b722014f89..deeec8c59dc 100644
--- a/lisp/expand.el
+++ b/lisp/expand.el
@@ -88,7 +88,7 @@
;;; Samples:
-(define-skeleton expand-c-for-skeleton "For loop skeleton"
+(define-skeleton expand-c-for-skeleton "For loop skeleton."
"Loop var: "
"for(" str _ @ "=0; " str @ "; " str @ ") {" \n
@ _ \n
diff --git a/lisp/ezimage.el b/lisp/ezimage.el
index 13f5c039a7f..57033cde058 100644
--- a/lisp/ezimage.el
+++ b/lisp/ezimage.el
@@ -45,6 +45,7 @@
(defmacro defezimage (variable imagespec docstring)
"Define VARIABLE as an image if `defimage' is not available.
IMAGESPEC is the image data, and DOCSTRING is documentation for the image."
+ (declare (indent defun))
`(progn
(defimage ,variable ,imagespec ,docstring)
(put (quote ,variable) 'ezimage t)))
diff --git a/lisp/face-remap.el b/lisp/face-remap.el
index 5914ee4a202..50302b9682c 100644
--- a/lisp/face-remap.el
+++ b/lisp/face-remap.el
@@ -23,7 +23,6 @@
;;; Commentary:
-;;
;; This file defines some simple operations that can be used for
;; maintaining the `face-remapping-alist' in a cooperative way. This is
;; especially important for the `default' face.
@@ -52,8 +51,6 @@
;; mode setting face remappings, e.g., of the default face.
;;
;; All modifications cause face-remapping-alist to be made buffer-local.
-;;
-
;;; Code:
@@ -218,13 +215,13 @@ Each positive or negative step scales the default face height by this amount."
:version "23.1")
(defvar-local text-scale-mode-remapping nil
- "Current remapping cookie for text-scale-mode.")
+ "Current remapping cookie for `text-scale-mode'.")
(defvar-local text-scale-mode-lighter "+0"
- "Lighter displayed for text-scale-mode in mode-line minor-mode list.")
+ "Lighter displayed for `text-scale-mode' in mode-line minor-mode list.")
(defvar-local text-scale-mode-amount 0
- "Number of steps that text-scale-mode will increase/decrease text height.")
+ "Number of steps that `text-scale-mode' will increase/decrease text height.")
(defvar-local text-scale-remap-header-line nil
"If non-nil, text scaling may change font size of header lines too.")
@@ -352,7 +349,7 @@ See `text-scale-increase' for more details."
INC may be passed as a numeric prefix argument.
The actual adjustment made depends on the final component of the
-key-binding used to invoke the command, with all modifiers removed:
+keybinding used to invoke the command, with all modifiers removed:
+, = Increase the height of the default face by one step
- Decrease the height of the default face by one step
@@ -400,7 +397,7 @@ a top-level keymap, `text-scale-increase' or
(defcustom buffer-face-mode-face 'variable-pitch
"The face specification used by `buffer-face-mode'.
It may contain any value suitable for a `face' text property,
-including a face name, a list of face names, a face-attribute
+including a face name, a list of face names, a face attribute
plist, etc."
:type '(choice (face)
(repeat :tag "List of faces" face)
diff --git a/lisp/facemenu.el b/lisp/facemenu.el
index 7229d6163df..fe458b8c07b 100644
--- a/lisp/facemenu.el
+++ b/lisp/facemenu.el
@@ -541,17 +541,18 @@ If the optional argument LIST is non-nil, it should be a list of
colors to display. Otherwise, this command computes a list of
colors that the current display can handle. Customize
`list-colors-sort' to change the order in which colors are shown.
-Type `g' or \\[revert-buffer] after customizing `list-colors-sort'
-to redisplay colors in the new order.
+Type \\<help-mode-map>\\[revert-buffer] after customizing \
+`list-colors-sort' to redisplay colors in
+the new order.
-If the optional argument BUFFER-NAME is nil, it defaults to *Colors*.
+If the optional argument BUFFER-NAME is nil, it defaults to \"*Colors*\".
If the optional argument CALLBACK is non-nil, it should be a
function to call each time the user types RET or clicks on a
color. The function should accept a single argument, the color name."
(interactive)
- (when (and (null list) (> (display-color-cells) 0))
- (setq list (list-colors-duplicates (defined-colors)))
+ (when (> (display-color-cells) 0)
+ (setq list (list-colors-duplicates (or list (defined-colors))))
(when list-colors-sort
;; Schwartzian transform with `(color key1 key2 key3 ...)'.
(setq list (mapcar
diff --git a/lisp/faces.el b/lisp/faces.el
index a3a6f1b78dd..97579877efa 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -88,9 +88,9 @@ a font height that isn't optimal."
:tag "Font selection order"
:type '(list symbol symbol symbol symbol)
:group 'font-selection
- :set #'(lambda (symbol value)
- (set-default symbol value)
- (internal-set-font-selection-order value)))
+ :set (lambda (symbol value)
+ (set-default symbol value)
+ (internal-set-font-selection-order value)))
;; In the absence of Fontconfig support, Monospace and Sans Serif are
@@ -140,9 +140,9 @@ ALTERNATIVE2 etc."
:tag "Alternative font families to try"
:type '(repeat (repeat string))
:group 'font-selection
- :set #'(lambda (symbol value)
- (set-default symbol value)
- (internal-set-alternative-font-family-alist value)))
+ :set (lambda (symbol value)
+ (set-default symbol value)
+ (internal-set-alternative-font-family-alist value)))
;; This is defined originally in xfaces.c.
@@ -167,9 +167,9 @@ REGISTRY, ALTERNATIVE1, ALTERNATIVE2, and etc."
:type '(repeat (repeat string))
:version "21.1"
:group 'font-selection
- :set #'(lambda (symbol value)
- (set-default symbol value)
- (internal-set-alternative-font-registry-alist value)))
+ :set (lambda (symbol value)
+ (set-default symbol value)
+ (internal-set-alternative-font-registry-alist value)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -702,9 +702,10 @@ for it to be relative to).
`:weight'
-VALUE specifies the weight of the font to use. It must be one of the
-symbols `ultra-bold', `extra-bold', `bold', `semi-bold', `normal',
-`semi-light', `light', `extra-light', `ultra-light'.
+VALUE specifies the weight of the font to use. It must be one of
+the symbols `ultra-heavy', `heavy', `ultra-bold', `extra-bold',
+`bold', `semi-bold', `medium', `normal', `book', `semi-light',
+`light', `extra-light', `ultra-light', or `thin'.
`:slant'
@@ -861,8 +862,8 @@ is specified, `:italic' is ignored."
(defun make-face-bold (face &optional frame _noerror)
"Make the font of FACE be bold, if possible.
FRAME nil or not specified means change face on all frames.
-Argument NOERROR is ignored and retained for compatibility.
Use `set-face-attribute' for finer control of the font weight."
+ (declare (advertised-calling-convention (face &optional frame) "29.1"))
(interactive (list (read-face-name "Make which face bold"
(face-at-point t))))
(set-face-attribute face frame :weight 'bold))
@@ -870,8 +871,8 @@ Use `set-face-attribute' for finer control of the font weight."
(defun make-face-unbold (face &optional frame _noerror)
"Make the font of FACE be non-bold, if possible.
-FRAME nil or not specified means change face on all frames.
-Argument NOERROR is ignored and retained for compatibility."
+FRAME nil or not specified means change face on all frames."
+ (declare (advertised-calling-convention (face &optional frame) "29.1"))
(interactive (list (read-face-name "Make which face non-bold"
(face-at-point t))))
(set-face-attribute face frame :weight 'normal))
@@ -880,8 +881,8 @@ Argument NOERROR is ignored and retained for compatibility."
(defun make-face-italic (face &optional frame _noerror)
"Make the font of FACE be italic, if possible.
FRAME nil or not specified means change face on all frames.
-Argument NOERROR is ignored and retained for compatibility.
Use `set-face-attribute' for finer control of the font slant."
+ (declare (advertised-calling-convention (face &optional frame) "29.1"))
(interactive (list (read-face-name "Make which face italic"
(face-at-point t))))
(set-face-attribute face frame :slant 'italic))
@@ -889,8 +890,8 @@ Use `set-face-attribute' for finer control of the font slant."
(defun make-face-unitalic (face &optional frame _noerror)
"Make the font of FACE be non-italic, if possible.
-FRAME nil or not specified means change face on all frames.
-Argument NOERROR is ignored and retained for compatibility."
+FRAME nil or not specified means change face on all frames."
+ (declare (advertised-calling-convention (face &optional frame) "29.1"))
(interactive (list (read-face-name "Make which face non-italic"
(face-at-point t))))
(set-face-attribute face frame :slant 'normal))
@@ -899,8 +900,8 @@ Argument NOERROR is ignored and retained for compatibility."
(defun make-face-bold-italic (face &optional frame _noerror)
"Make the font of FACE be bold and italic, if possible.
FRAME nil or not specified means change face on all frames.
-Argument NOERROR is ignored and retained for compatibility.
Use `set-face-attribute' for finer control of font weight and slant."
+ (declare (advertised-calling-convention (face &optional frame) "29.1"))
(interactive (list (read-face-name "Make which face bold-italic"
(face-at-point t))))
(set-face-attribute face frame :weight 'bold :slant 'italic))
@@ -1100,7 +1101,7 @@ returned. Otherwise, DEFAULT is returned verbatim."
;; prompt. If so, remove it.
(setq prompt (replace-regexp-in-string ": ?\\'" "" prompt))
(let ((prompt (if default
- (format-message "%s (default `%s'): " prompt default)
+ (format-prompt prompt default)
(format "%s: " prompt)))
aliasfaces nonaliasfaces faces)
;; Build up the completion tables.
@@ -1146,42 +1147,42 @@ an integer value."
(:foundry
(list nil))
(:width
- (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
+ (mapcar (lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
font-width-table))
(:weight
- (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
+ (mapcar (lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
font-weight-table))
(:slant
- (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
+ (mapcar (lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
font-slant-table))
((or :inverse-video :extend)
- (mapcar #'(lambda (x) (cons (symbol-name x) x))
+ (mapcar (lambda (x) (cons (symbol-name x) x))
(internal-lisp-face-attribute-values attribute)))
((or :underline :overline :strike-through :box)
(if (window-system frame)
- (nconc (mapcar #'(lambda (x) (cons (symbol-name x) x))
+ (nconc (mapcar (lambda (x) (cons (symbol-name x) x))
(internal-lisp-face-attribute-values attribute))
- (mapcar #'(lambda (c) (cons c c))
+ (mapcar (lambda (c) (cons c c))
(defined-colors frame)))
- (mapcar #'(lambda (x) (cons (symbol-name x) x))
+ (mapcar (lambda (x) (cons (symbol-name x) x))
(internal-lisp-face-attribute-values attribute))))
((or :foreground :background)
- (mapcar #'(lambda (c) (cons c c))
+ (mapcar (lambda (c) (cons c c))
(defined-colors frame)))
(:height
'integerp)
(:stipple
- (and (memq (window-system frame) '(x ns)) ; No stipple on w32
+ (and (memq (window-system frame) '(x ns pgtk)) ; No stipple on w32 or haiku
(mapcar #'list
(apply #'nconc
(mapcar (lambda (dir)
(and (file-readable-p dir)
(file-directory-p dir)
- (directory-files dir)))
+ (directory-files dir 'full)))
x-bitmap-file-path)))))
(:inherit
(cons '("none" . nil)
- (mapcar #'(lambda (c) (cons (symbol-name c) c))
+ (mapcar (lambda (c) (cons (symbol-name c) c))
(face-list))))
(_
(error "Internal error")))))
@@ -1515,7 +1516,7 @@ If FRAME is nil, the current FRAME is used."
match (cond ((eq req 'type)
(or (memq (window-system frame) options)
(and (memq 'graphic options)
- (memq (window-system frame) '(x w32 ns)))
+ (memq (window-system frame) '(x w32 ns pgtk)))
;; FIXME: This should be revisited to use
;; display-graphic-p, provided that the
;; color selection depends on the number
@@ -1795,18 +1796,21 @@ If FRAME is nil, that stands for the selected frame."
(mapcar 'car (tty-color-alist frame))))
(defalias 'x-defined-colors 'defined-colors)
-(defun defined-colors-with-face-attributes (&optional frame)
- "Return a list of colors supported for a particular frame.
-See `defined-colors' for arguments and return value. In contrast
+(defun defined-colors-with-face-attributes (&optional frame foreground)
+ "Return a list of colors supported for a particular FRAME.
+See `defined-colors' for arguments and return value. In contrast
to `defined-colors' the elements of the returned list are color
strings with text properties, that make the color names render
-with the color they represent as background color."
+with the color they represent as background color (if FOREGROUND
+is nil; otherwise use the foreground color)."
(mapcar
(lambda (color-name)
- (let ((foreground (readable-foreground-color color-name))
- (color (copy-sequence color-name)))
- (propertize color 'face (list :foreground foreground
- :background color))))
+ (let ((color (copy-sequence color-name)))
+ (propertize color 'face
+ (if foreground
+ (list :foreground color)
+ (list :foreground (readable-foreground-color color-name)
+ :background color)))))
(defined-colors frame)))
(defun readable-foreground-color (color)
@@ -1915,7 +1919,8 @@ If omitted or nil, that stands for the selected frame's display."
(x-display-grayscale-p display)
(> (tty-color-gray-shades display) 2)))
-(defun read-color (&optional prompt convert-to-RGB allow-empty-name msg)
+(defun read-color (&optional prompt convert-to-RGB allow-empty-name msg
+ foreground)
"Read a color name or RGB triplet.
Completion is available for color names, but not for RGB triplets.
@@ -1942,13 +1947,18 @@ If optional arg ALLOW-EMPTY-NAME is non-nil, the user is allowed
to enter an empty color name (the empty string).
Interactively, or with optional arg MSG non-nil, print the
-resulting color name in the echo area."
+resulting color name in the echo area.
+
+Interactively, displays a list of colored completions. If optional
+argument FOREGROUND is non-nil, shows them as foregrounds, otherwise
+as backgrounds."
(interactive "i\np\ni\np") ; Always convert to RGB interactively.
(let* ((completion-ignore-case t)
(colors (append '("foreground at point" "background at point")
(if allow-empty-name '(""))
(if (display-color-p)
- (defined-colors-with-face-attributes)
+ (defined-colors-with-face-attributes
+ nil foreground)
(defined-colors))))
(color (completing-read
(or prompt "Color (name or #RGB triplet): ")
@@ -2276,17 +2286,19 @@ If you set `term-file-prefix' to nil, this function does nothing."
(let* (term-init-func)
;; First, load the terminal initialization file, if it is
;; available and it hasn't been loaded already.
- (tty-find-type #'(lambda (type)
- (let ((file (locate-library (concat term-file-prefix type))))
- (and file
- (or (assoc file load-history)
- (load (file-name-sans-extension file)
- t t)))))
- type)
+ (tty-find-type (lambda (type)
+ (let ((file (locate-library (concat term-file-prefix type))))
+ (and file
+ (or (assoc file load-history)
+ (load (replace-regexp-in-string
+ "\\.el\\(\\.gz\\)?\\'" ""
+ file)
+ t t)))))
+ type)
;; Next, try to find a matching initialization function, and call it.
- (tty-find-type #'(lambda (type)
- (fboundp (setq term-init-func
- (intern (concat "terminal-init-" type)))))
+ (tty-find-type (lambda (type)
+ (fboundp (setq term-init-func
+ (intern (concat "terminal-init-" type)))))
type)
(when (fboundp term-init-func)
(funcall term-init-func))
@@ -2369,6 +2381,15 @@ If you set `term-file-prefix' to nil, this function does nothing."
"The basic variable-pitch face."
:group 'basic-faces)
+(defface variable-pitch-text
+ '((t :inherit variable-pitch
+ :height 1.1))
+ "The proportional face used for longer texts.
+This is like the `variable-pitch' face, but is slightly bigger by
+default."
+ :version "29.1"
+ :group 'basic-faces)
+
(defface shadow
'((((class color grayscale) (min-colors 88) (background light))
:foreground "grey50")
@@ -2602,14 +2623,23 @@ non-nil."
:background "grey75" :foreground "black")
(t
:inverse-video t))
- "Basic mode line face for selected window."
+ "Face for the mode lines (for the selected window) as well as header lines.
+See `mode-line-display' for the face used on mode lines."
:version "21.1"
:group 'mode-line-faces
:group 'basic-faces)
+(defface mode-line-active
+ '((t :inherit (mode-line variable-pitch)))
+ "Face for the selected mode line.
+This inherits from the `mode-line' face."
+ :version "29.1"
+ :group 'mode-line-faces
+ :group 'basic-faces)
+
(defface mode-line-inactive
'((default
- :inherit mode-line)
+ :inherit (mode-line variable-pitch))
(((class color) (min-colors 88) (background light))
:weight light
:box (:line-width -1 :color "grey75" :style nil)
@@ -2810,7 +2840,7 @@ Note: Other faces cannot inherit from the cursor face."
'((default
:box (:line-width 1 :style released-button)
:foreground "black")
- (((type x w32 ns) (class color))
+ (((type x w32 ns haiku pgtk) (class color))
:background "grey75")
(((type x) (class mono))
:background "grey"))
@@ -2866,14 +2896,22 @@ Note: Other faces cannot inherit from the cursor face."
:background "grey96" :foreground "DarkBlue"
;; We use negative thickness of the horizontal box border line to
;; avoid enlarging the height of the echo-area display, which
- ;; would then move the mode line a few pixels up.
- :box (:line-width (1 . -1) :color "grey80"))
+ ;; would then move the mode line a few pixels up. We use
+ ;; negative thickness for the vertical border line to avoid
+ ;; making the characters wider, which then would cause unpleasant
+ ;; horizontal shifts of the cursor during C-n/C-p movement
+ ;; through a line with this face.
+ :box (:line-width (-1 . -1) :color "grey80")
+ :inherit fixed-pitch)
(((class color) (min-colors 88) (background dark))
:background "grey19" :foreground "LightBlue"
- :box (:line-width (1 . -1) :color "grey35"))
- (((class color grayscale) (background light)) :background "grey90")
- (((class color grayscale) (background dark)) :background "grey25")
- (t :background "grey90"))
+ :box (:line-width (-1 . -1) :color "grey35")
+ :inherit fixed-pitch)
+ (((class color grayscale) (background light)) :background "grey90"
+ :inherit fixed-pitch)
+ (((class color grayscale) (background dark)) :background "grey25"
+ :inherit fixed-pitch)
+ (t :background "grey90" :inherit fixed-pitch))
"Face for keybindings in *Help* buffers.
This face is added by `substitute-command-keys', which see.
diff --git a/lisp/ffap.el b/lisp/ffap.el
index 84dcc04a712..5d3cee591be 100644
--- a/lisp/ffap.el
+++ b/lisp/ffap.el
@@ -465,11 +465,11 @@ Returned values:
mesg) nil)
((string-match "not responding$" mesg) mesg)
;; v19:
- ;; (file-error "connection failed" "permission denied"
+ ;; (file-error "Connection failed" "permission denied"
;; "nonesuch" "ffap-machine-p")
- ;; (file-error "connection failed" "host is unreachable"
+ ;; (file-error "Connection failed" "host is unreachable"
;; "gopher.house.gov" "ffap-machine-p")
- ;; (file-error "connection failed" "address already in use"
+ ;; (file-error "Connection failed" "address already in use"
;; "ftp.uu.net" "ffap-machine-p")
((equal mesg "connection failed")
(if (string= (downcase (nth 2 error)) "permission denied")
@@ -651,7 +651,7 @@ also is substituted for the first empty-string component, if there is one.
Uses `path-separator' to separate the path into substrings."
;; We cannot use parse-colon-path (files.el), since it kills
;; "//" entries using file-name-as-directory.
- ;; Similar: dired-split, TeX-split-string, and RHOGEE's psg-list-env
+ ;; Similar: TeX-split-string, and RHOGEE's psg-list-env
;; in ff-paths and bib-cite. The EMPTY arg may help mimic kpathsea.
(if (or empty (getenv env)) ; should return something
(let ((start 0) match dir ret)
@@ -1088,8 +1088,8 @@ If a given RFC isn't in these then `ffap-rfc-path' is offered."
(latex-mode "--:\\\\$+<>@-Z_[:alpha:]~*?" "<@" "@>;.,!:")
(tex-mode "--:\\\\$+<>@-Z_[:alpha:]~*?" "<@" "@>;.,!:")
)
- "Alist of (MODE CHARS BEG END), where MODE is a symbol,
-possibly a major-mode name, or one of the symbols
+ "Alist of (MODE CHARS BEG END), where MODE is a symbol.
+This is possibly a major-mode name, or one of the symbols
`file', `url', `machine', and `nocolon'.
Function `ffap-string-at-point' uses the data fields as follows:
1. find a maximal string of CHARS around point,
@@ -1114,7 +1114,7 @@ like)."
(defun ffap-search-backward-file-end (&optional dir-separator end)
"Search backward position point where file would probably end.
-Optional DIR-SEPARATOR defaults to \"/\". The search maximum is
+Optional DIR-SEPARATOR defaults to \"/\". The search maximum is
`line-end-position' or optional END point.
Suppose the cursor is somewhere that might be near end of file,
@@ -1190,7 +1190,7 @@ Call `ffap-search-backward-file-end' to refine the ending point."
(defun ffap-dir-separator-near-point ()
"Search backward and forward for closest slash or backlash in line.
-Return string slash or backslash. Point is moved to closest position."
+Return string slash or backslash. Point is moved to closest position."
(let ((point (point))
str pos)
(when (looking-at ".*?/")
@@ -1639,8 +1639,9 @@ If `ffap-url-regexp' is not nil, the FILENAME may also be an URL.
With a prefix, this command behaves exactly like `ffap-file-finder'.
If `ffap-require-prefix' is set, the prefix meaning is reversed.
See also the variables `ffap-dired-wildcards', `ffap-newfile-prompt',
-`ffap-url-unwrap-local', `ffap-url-unwrap-remote', and the functions
-`ffap-file-at-point' and `ffap-url-at-point'."
+`ffap-url-unwrap-local', `ffap-url-unwrap-remote',
+`ffap-file-name-with-spaces', and the functions `ffap-file-at-point'
+and `ffap-url-at-point'."
(interactive)
(if (and (called-interactively-p 'interactive)
(if ffap-require-prefix (not current-prefix-arg)
diff --git a/lisp/fileloop.el b/lisp/fileloop.el
index 45b9cea9397..cd60600a250 100644
--- a/lisp/fileloop.el
+++ b/lisp/fileloop.el
@@ -44,6 +44,7 @@
(defcustom fileloop-revert-buffers 'silent
"Whether to revert files during fileloop operation.
+This can be one of:
`silent' means to only do it if `revert-without-query' is applicable;
t means to offer to do it for all applicable files;
nil means never to do it"
diff --git a/lisp/filenotify.el b/lisp/filenotify.el
index 4fc7f0a8ec0..26954cc73f2 100644
--- a/lisp/filenotify.el
+++ b/lisp/filenotify.el
@@ -19,7 +19,7 @@
;; 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
+;;; Commentary:
;; This package is an abstraction layer from the different low-level
;; file notification packages `inotify', `kqueue', `gfilenotify' and
@@ -76,16 +76,17 @@ struct.")
"Remove DESCRIPTOR from `file-notify-descriptors'.
DESCRIPTOR should be an object returned by `file-notify-add-watch'.
If it is registered in `file-notify-descriptors', a `stopped' event is sent."
- (when-let* ((watch (gethash descriptor file-notify-descriptors)))
- (let ((callback (file-notify--watch-callback watch)))
- ;; Make sure this is the last time the callback is invoked.
+ (when-let ((watch (gethash descriptor file-notify-descriptors)))
+ (unwind-protect
+ ;; Send `stopped' event.
+ (file-notify-handle-event
+ (make-file-notify
+ :-event `(,descriptor stopped
+ ,(file-notify--watch-absolute-filename watch))
+ :-callback (file-notify--watch-callback watch)))
+ ;; Make sure this is the last time the callback was invoked.
(setf (file-notify--watch-callback watch) nil)
- ;; Send `stopped' event.
- (unwind-protect
- (funcall
- callback
- `(,descriptor stopped ,(file-notify--watch-absolute-filename watch)))
- (remhash descriptor file-notify-descriptors)))))
+ (remhash descriptor file-notify-descriptors))))
(cl-defstruct (file-notify (:type list) :named)
"A file system monitoring event, coming from the backends."
@@ -389,7 +390,9 @@ include the following symbols:
permissions or modification time
If FILE is a directory, `change' watches for file creation or
-deletion in that directory. This does not work recursively.
+deletion in that directory. Some of the file notification
+backends report also file changes. This does not work
+recursively.
When any event happens, Emacs will call the CALLBACK function passing
it a single argument EVENT, which is of the form
@@ -477,6 +480,14 @@ DESCRIPTOR should be an object returned by `file-notify-add-watch'."
;; Modify `file-notify-descriptors' and send a `stopped' event.
(file-notify--rm-descriptor descriptor))))
+(defun file-notify-rm-all-watches ()
+ "Remove all existing file notification watches from Emacs."
+ (interactive)
+ (maphash
+ (lambda (key _value)
+ (file-notify-rm-watch key))
+ file-notify-descriptors))
+
(defun file-notify-valid-p (descriptor)
"Check a watch specified by its DESCRIPTOR.
DESCRIPTOR should be an object returned by `file-notify-add-watch'."
diff --git a/lisp/files-x.el b/lisp/files-x.el
index 9e1954256a6..c7cc076f844 100644
--- a/lisp/files-x.el
+++ b/lisp/files-x.el
@@ -673,7 +673,7 @@ in order."
(defun hack-connection-local-variables (criteria)
"Read connection-local variables according to CRITERIA.
Store the connection-local variables in buffer local
-variable`connection-local-variables-alist'.
+variable `connection-local-variables-alist'.
This does nothing if `enable-connection-local-variables' is nil."
(when enable-connection-local-variables
diff --git a/lisp/files.el b/lisp/files.el
index 77977f14116..9ed63a60f81 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -42,15 +42,6 @@
"Finding files."
:group 'files)
-
-(defcustom delete-auto-save-files t
- "Non-nil means delete auto-save file when a buffer is saved or killed.
-
-Note that the auto-save file will not be deleted if the buffer is killed
-when it has unsaved changes."
- :type 'boolean
- :group 'auto-save)
-
(defcustom directory-abbrev-alist
nil
"Alist of abbreviations for file directories.
@@ -77,6 +68,31 @@ a regexp matching the name it is linked to."
:group 'abbrev
:group 'find-file)
+(defun directory-abbrev-make-regexp (directory)
+ "Create a regexp to match DIRECTORY for `directory-abbrev-alist'."
+ (let ((regexp
+ ;; We include a slash at the end, to avoid spurious
+ ;; matches such as `/usr/foobar' when the home dir is
+ ;; `/usr/foo'.
+ (concat "\\`" (regexp-quote directory) "\\(/\\|\\'\\)")))
+ ;; The value of regexp could be multibyte or unibyte. In the
+ ;; latter case, we need to decode it.
+ (if (multibyte-string-p regexp)
+ regexp
+ (decode-coding-string regexp
+ (if (eq system-type 'windows-nt)
+ 'utf-8
+ locale-coding-system)))))
+
+(defun directory-abbrev-apply (filename)
+ "Apply the abbreviations in `directory-abbrev-alist' to FILENAME.
+Note that when calling this, you should set `case-fold-search' as
+appropriate for the filesystem used for FILENAME."
+ (dolist (dir-abbrev directory-abbrev-alist filename)
+ (when (string-match (car dir-abbrev) filename)
+ (setq filename (concat (cdr dir-abbrev)
+ (substring filename (match-end 0)))))))
+
(defcustom make-backup-files t
"Non-nil means make a backup of a file the first time it is saved.
This can be done by renaming the file or by copying.
@@ -257,7 +273,7 @@ This feature is advisory: for example, if the directory in which the
file is being saved is not writable, Emacs may ignore a non-nil value
of `file-precious-flag' and write directly into the file.
-See also: `break-hardlink-on-save'."
+See also: `break-hardlink-on-save' and `file-preserve-symlinks-on-save'."
:type 'boolean
:group 'backup)
@@ -1068,8 +1084,10 @@ the function needs to examine, starting with FILE."
(if root (file-name-as-directory root))))
(defcustom user-emacs-directory-warning t
- "Non-nil means warn if cannot access `user-emacs-directory'.
-Set this to nil at your own risk..."
+ "Non-nil means warn if unable to access or create `user-emacs-directory'.
+Set this to nil at your own risk, as it might lead to data loss
+when Emacs tries to write something to a non-existent or
+inaccessible location."
:type 'boolean
:group 'initialization
:version "24.4")
@@ -1117,7 +1135,7 @@ customize the variable `user-emacs-directory-warning'."
(defun exec-path ()
"Return list of directories to search programs to run in remote subprocesses.
The remote host is identified by `default-directory'. For remote
-hosts that do not support subprocesses, this returns `nil'.
+hosts that do not support subprocesses, this returns nil.
If `default-directory' is a local directory, this function returns
the value of the variable `exec-path'."
(let ((handler (find-file-name-handler default-directory 'exec-path)))
@@ -1573,6 +1591,7 @@ This implementation works on magic file names."
(defun make-nearby-temp-file (prefix &optional dir-flag suffix)
"Create a temporary file as close as possible to `default-directory'.
+Return the absolute file name of the created file.
If PREFIX is a relative file name, and `default-directory' is a
remote file name or located on a mounted file systems, the
temporary file is created in the directory returned by the
@@ -1593,7 +1612,7 @@ Signals a `file-already-exists' error if a file of the new name
already exists unless optional fourth argument OK-IF-ALREADY-EXISTS
is non-nil. A number as fourth arg means request confirmation if
the new name already exists. This is what happens in interactive
-use with M-x."
+use with \\[execute-extended-command]."
(interactive
(let ((default-coding (or file-name-coding-system
default-file-name-coding-system))
@@ -2021,73 +2040,54 @@ if you want to permanently change your home directory after having
started Emacs, set `abbreviated-home-dir' to nil so it will be recalculated)."
;; Get rid of the prefixes added by the automounter.
(save-match-data ;FIXME: Why?
- (if (and automount-dir-prefix
- (string-match automount-dir-prefix filename)
- (file-exists-p (file-name-directory
- (substring filename (1- (match-end 0))))))
- (setq filename (substring filename (1- (match-end 0)))))
- ;; Avoid treating /home/foo as /home/Foo during `~' substitution.
- (let ((case-fold-search (file-name-case-insensitive-p filename)))
- ;; If any elt of directory-abbrev-alist matches this name,
- ;; abbreviate accordingly.
- (dolist (dir-abbrev directory-abbrev-alist)
- (if (string-match (car dir-abbrev) filename)
- (setq filename
- (concat (cdr dir-abbrev)
- (substring filename (match-end 0))))))
- ;; Compute and save the abbreviated homedir name.
- ;; We defer computing this until the first time it's needed, to
- ;; give time for directory-abbrev-alist to be set properly.
- ;; We include a slash at the end, to avoid spurious matches
- ;; such as `/usr/foobar' when the home dir is `/usr/foo'.
- (unless abbreviated-home-dir
- (put 'abbreviated-home-dir 'home (expand-file-name "~"))
- (setq abbreviated-home-dir
- (let* ((abbreviated-home-dir "\\`\\'.") ;Impossible regexp.
- (regexp
- (concat "\\`"
- (regexp-quote
- (abbreviate-file-name
- (get 'abbreviated-home-dir 'home)))
- "\\(/\\|\\'\\)")))
- ;; Depending on whether default-directory does or
- ;; doesn't include non-ASCII characters, the value
- ;; of abbreviated-home-dir could be multibyte or
- ;; unibyte. In the latter case, we need to decode
- ;; it. Note that this function is called for the
- ;; first time (from startup.el) when
- ;; locale-coding-system is already set up.
- (if (multibyte-string-p regexp)
- regexp
- (decode-coding-string regexp
- (if (eq system-type 'windows-nt)
- 'utf-8
- locale-coding-system))))))
-
- ;; If FILENAME starts with the abbreviated homedir,
- ;; and ~ hasn't changed since abbreviated-home-dir was set,
- ;; make it start with `~' instead.
- ;; If ~ has changed, we ignore abbreviated-home-dir rather than
- ;; invalidating it, on the assumption that a change in HOME
- ;; is likely temporary (eg for testing).
- ;; FIXME Is it even worth caching abbreviated-home-dir?
- ;; Ref: https://debbugs.gnu.org/19657#20
- (let (mb1)
- (if (and (string-match abbreviated-home-dir filename)
- (setq mb1 (match-beginning 1))
- ;; If the home dir is just /, don't change it.
- (not (and (= (match-end 0) 1)
- (= (aref filename 0) ?/)))
- ;; MS-DOS root directories can come with a drive letter;
- ;; Novell Netware allows drive letters beyond `Z:'.
- (not (and (memq system-type '(ms-dos windows-nt cygwin))
- (string-match "\\`[a-zA-`]:/\\'" filename)))
- (equal (get 'abbreviated-home-dir 'home)
- (expand-file-name "~")))
- (setq filename
- (concat "~"
- (substring filename mb1))))
- filename))))
+ (if-let ((handler (find-file-name-handler filename 'abbreviate-file-name)))
+ (funcall handler 'abbreviate-file-name filename)
+ (if (and automount-dir-prefix
+ (string-match automount-dir-prefix filename)
+ (file-exists-p (file-name-directory
+ (substring filename (1- (match-end 0))))))
+ (setq filename (substring filename (1- (match-end 0)))))
+ ;; Avoid treating /home/foo as /home/Foo during `~' substitution.
+ (let ((case-fold-search (file-name-case-insensitive-p filename)))
+ ;; If any elt of directory-abbrev-alist matches this name,
+ ;; abbreviate accordingly.
+ (setq filename (directory-abbrev-apply filename))
+
+ ;; Compute and save the abbreviated homedir name.
+ ;; We defer computing this until the first time it's needed, to
+ ;; give time for directory-abbrev-alist to be set properly.
+ (unless abbreviated-home-dir
+ (put 'abbreviated-home-dir 'home (expand-file-name "~"))
+ (setq abbreviated-home-dir
+ (directory-abbrev-make-regexp
+ (let ((abbreviated-home-dir "\\`\\'.")) ;Impossible regexp.
+ (abbreviate-file-name
+ (get 'abbreviated-home-dir 'home))))))
+
+ ;; If FILENAME starts with the abbreviated homedir,
+ ;; and ~ hasn't changed since abbreviated-home-dir was set,
+ ;; make it start with `~' instead.
+ ;; If ~ has changed, we ignore abbreviated-home-dir rather than
+ ;; invalidating it, on the assumption that a change in HOME
+ ;; is likely temporary (eg for testing).
+ ;; FIXME Is it even worth caching abbreviated-home-dir?
+ ;; Ref: https://debbugs.gnu.org/19657#20
+ (let (mb1)
+ (if (and (string-match abbreviated-home-dir filename)
+ (setq mb1 (match-beginning 1))
+ ;; If the home dir is just /, don't change it.
+ (not (and (= (match-end 0) 1)
+ (= (aref filename 0) ?/)))
+ ;; MS-DOS root directories can come with a drive letter;
+ ;; Novell Netware allows drive letters beyond `Z:'.
+ (not (and (memq system-type '(ms-dos windows-nt cygwin))
+ (string-match "\\`[a-zA-`]:/\\'" filename)))
+ (equal (get 'abbreviated-home-dir 'home)
+ (expand-file-name "~")))
+ (setq filename
+ (concat "~"
+ (substring filename mb1))))
+ filename)))))
(defun find-buffer-visiting (filename &optional predicate)
"Return the buffer visiting file FILENAME (a string).
@@ -2360,7 +2360,7 @@ the various files."
((not query-about-changed-file)
(message
(substitute-command-keys
- "File %s changed on disk. \\[revert-buffer] to load new contents%s")
+ "File %s changed on disk. \\[revert-buffer-quick] to load new contents%s")
(file-name-nondirectory filename)
(if (buffer-modified-p buf)
" and discard your edits"
@@ -2529,13 +2529,20 @@ Do you want to revisit the file normally now? ")))
(current-buffer))))
(defun insert-file-contents-literally (filename &optional visit beg end replace)
- "Like `insert-file-contents', but only reads in the file literally.
+ "Like `insert-file-contents', but only read in the file literally.
See `insert-file-contents' for an explanation of the parameters.
A buffer may be modified in several ways after reading into the buffer,
due to Emacs features such as format decoding, character code
conversion, `find-file-hook', automatic uncompression, etc.
-This function ensures that none of these modifications will take place."
+This function ensures that none of these modifications will take place.
+
+Unlike `find-file-literally', this function does not make the
+buffer unibyte, so if this function is used when handling
+binary (non-character) data, it can be convenient to make the
+buffer unibyte first. This isn't, strictly speaking, necessary,
+because multibyte buffers can also deal with raw bytes. See info
+node `(elisp)Character Codes' for details."
(let ((format-alist nil)
(after-insert-file-functions nil)
(coding-system-for-read 'no-conversion)
@@ -2760,6 +2767,7 @@ since only a single case-insensitive search through the alist is made."
("\\.gif\\'" . image-mode)
("\\.png\\'" . image-mode)
("\\.jpe?g\\'" . image-mode)
+ ("\\.webp\\'" . image-mode)
("\\.te?xt\\'" . text-mode)
("\\.[tT]e[xX]\\'" . tex-mode)
("\\.ins\\'" . tex-mode) ;Installation files for TeX packages.
@@ -2885,6 +2893,7 @@ ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|CBR\\|7Z\\|SQUASHFS\\)\\'" .
("\\.[ds]?va?h?\\'" . verilog-mode)
("\\.by\\'" . bovine-grammar-mode)
("\\.wy\\'" . wisent-grammar-mode)
+ ("\\.erts\\'" . erts-mode)
;; .emacs or .gnus or .viper following a directory delimiter in
;; Unix or MS-DOS syntax.
("[:/\\]\\..*\\(emacs\\|gnus\\|viper\\)\\'" . emacs-lisp-mode)
@@ -2977,6 +2986,7 @@ ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|CBR\\|7Z\\|SQUASHFS\\)\\'" .
("\\.dng\\'" . image-mode)
("\\.dpx\\'" . image-mode)
("\\.fax\\'" . image-mode)
+ ("\\.heic\\'" . image-mode)
("\\.hrz\\'" . image-mode)
("\\.icb\\'" . image-mode)
("\\.icc\\'" . image-mode)
@@ -3898,7 +3908,7 @@ inhibited."
(hack-local-variables-apply))))))
(defun hack-local-variables--find-variables (&optional handle-mode)
- "Return all local variables in the ucrrent buffer.
+ "Return all local variables in the current buffer.
If HANDLE-MODE is nil, we gather all the specified local
variables. If HANDLE-MODE is neither nil nor t, we do the same,
except that any settings of `mode' are ignored.
@@ -4434,8 +4444,8 @@ variables will override modes."
(t -2))))
(defun dir-locals--sort-variables (variables)
- "Sorts VARIABLES so that applying them in order has the right effect.
-The variables are compared by dir-locals--get-sort-score.
+ "Sort VARIABLES so that applying them in order has the right effect.
+The variables are compared by `dir-locals--get-sort-score'.
Directory entries are then recursively sorted using the same
criteria."
(setq variables (sort variables
@@ -4735,7 +4745,6 @@ using \\<minibuffer-local-map>\\[next-history-element].
If optional second arg CONFIRM is non-nil, this function
asks for confirmation before overwriting an existing file.
Interactively, confirmation is required unless you supply a prefix argument."
-;; (interactive "FWrite file: ")
(interactive
(list (if buffer-file-name
(read-file-name "Write file: "
@@ -4746,33 +4755,44 @@ Interactively, confirmation is required unless you supply a prefix argument."
default-directory)
nil nil))
(not current-prefix-arg)))
- (or (null filename) (string-equal filename "")
- (progn
- ;; If arg is a directory name,
- ;; use the default file name, but in that directory.
- (if (directory-name-p filename)
- (setq filename (concat filename
- (file-name-nondirectory
- (or buffer-file-name (buffer-name))))))
- (and confirm
- (file-exists-p filename)
- ;; NS does its own confirm dialog.
- (not (and (eq (framep-on-display) 'ns)
- (listp last-nonmenu-event)
- use-dialog-box))
- (or (y-or-n-p (format-message
- "File `%s' exists; overwrite? " filename))
- (user-error "Canceled")))
- (set-visited-file-name filename (not confirm))))
- (set-buffer-modified-p t)
- ;; Make buffer writable if file is writable.
- (and buffer-file-name
- (file-writable-p buffer-file-name)
- (setq buffer-read-only nil))
- (save-buffer)
- ;; It's likely that the VC status at the new location is different from
- ;; the one at the old location.
- (vc-refresh-state))
+ (let ((old-modes
+ (and buffer-file-name
+ ;; File may have gone away; ignore errors in that case.
+ (ignore-errors (file-modes buffer-file-name)))))
+ (or (null filename) (string-equal filename "")
+ (progn
+ ;; If arg is a directory name,
+ ;; use the default file name, but in that directory.
+ (if (directory-name-p filename)
+ (setq filename (concat filename
+ (file-name-nondirectory
+ (or buffer-file-name (buffer-name))))))
+ (and confirm
+ (file-exists-p filename)
+ ;; NS does its own confirm dialog.
+ (not (and (eq (framep-on-display) 'ns)
+ (listp last-nonmenu-event)
+ use-dialog-box))
+ (or (y-or-n-p (format-message
+ "File `%s' exists; overwrite? " filename))
+ (user-error "Canceled")))
+ (set-visited-file-name filename (not confirm))))
+ (set-buffer-modified-p t)
+ ;; Make buffer writable if file is writable.
+ (and buffer-file-name
+ (file-writable-p buffer-file-name)
+ (setq buffer-read-only nil))
+ (save-buffer)
+ ;; If the old file was executable, then make the new file
+ ;; executable, too.
+ (when (and old-modes
+ (not (zerop (logand #o111 old-modes))))
+ (set-file-modes buffer-file-name
+ (logior (logand #o111 old-modes)
+ (file-modes buffer-file-name))))
+ ;; It's likely that the VC status at the new location is different from
+ ;; the one at the old location.
+ (vc-refresh-state)))
(defun file-extended-attributes (filename)
"Return an alist of extended attributes of file FILENAME.
@@ -5033,7 +5053,7 @@ FILENAME has the format of a directory.
See also `file-name-sans-extension'."
(let ((extn (string-trim-left extension "[.]")))
(cond ((string-empty-p filename)
- (error "Empty filename: %s" filename))
+ (error "Empty filename"))
((string-empty-p extn)
(error "Malformed extension: %s" extension))
((directory-name-p filename)
@@ -5047,6 +5067,29 @@ See also `file-name-sans-extension'."
(file-name-sans-extension
(file-name-nondirectory (or filename (buffer-file-name)))))
+(defun file-name-split (filename)
+ "Return a list of all the components of FILENAME.
+On most systems, this will be true:
+
+ (equal (string-join (file-name-split filename) \"/\") filename)"
+ (let ((components nil))
+ ;; If this is a directory file name, then we have a null file name
+ ;; at the end.
+ (when (directory-name-p filename)
+ (push "" components)
+ (setq filename (directory-file-name filename)))
+ ;; Loop, chopping off components.
+ (while (length> filename 0)
+ (push (file-name-nondirectory filename) components)
+ (let ((dir (file-name-directory filename)))
+ (setq filename (and dir (directory-file-name dir)))
+ ;; If there's nothing left to peel off, we're at the root and
+ ;; we can stop.
+ (when (and dir (equal dir filename))
+ (push "" components)
+ (setq filename nil))))
+ components))
+
(defcustom make-backup-file-name-function
#'make-backup-file-name--default-function
"A function that `make-backup-file-name' uses to create backup file names.
@@ -5437,6 +5480,23 @@ Used only by `save-buffer'."
:type 'hook
:group 'files)
+(defcustom copy-directory-create-symlink nil
+ "This option influences the handling of symbolic links in `copy-directory'.
+If non-nil, `copy-directory' will create a symbolic link if the
+source directory is a symbolic link. If nil, it'll follow the
+symbolic link and copy the contents instead."
+ :type 'boolean
+ :version "28.1"
+ :group 'files)
+
+(defcustom file-preserve-symlinks-on-save nil
+ "If non-nil, saving a buffer visited via a symlink won't overwrite the symlink.
+This is only relevant if `file-precious-flag' is non-nil -- if
+this is nil, Emacs will preserve the symlinks anyway."
+ :type 'boolean
+ :version "28.1"
+ :group 'files)
+
(defvar-local save-buffer-coding-system nil
"If non-nil, use this coding system for saving the buffer.
More precisely, use this coding system in place of the
@@ -5582,7 +5642,7 @@ Before and after saving the buffer, this function runs
(if (not (file-directory-p dir))
(if (file-exists-p dir)
(error "%s is not a directory" dir)
- (error "%s: no such directory" dir))
+ (error "%s: No such directory" dir))
(if (not (file-exists-p buffer-file-name))
(error "Directory %s write-protected" dir)
(if (yes-or-no-p
@@ -5639,7 +5699,14 @@ Before and after saving the buffer, this function runs
buffer-file-name)))
;; We succeeded in writing the temp file,
;; so rename it.
- (rename-file tempname buffer-file-name t))
+ (rename-file tempname
+ (if (and file-preserve-symlinks-on-save
+ (file-symlink-p buffer-file-name))
+ ;; Write to the file that the symlink
+ ;; points to.
+ (file-chase-links buffer-file-name)
+ buffer-file-name)
+ t))
;; If file not writable, see if we can make it writable
;; temporarily while we write it.
;; But no need to do so if we have just backed it up
@@ -5723,7 +5790,9 @@ This allows you to stop `save-some-buffers' from asking
about certain files that you'd usually rather not save.
This function is called (with no parameters) from the buffer to
-be saved."
+be saved. When the function's symbol has the property
+`save-some-buffers-function', the higher-order function is supposed
+to return a predicate used to check buffers."
:group 'auto-save
;; FIXME nil should not be a valid option, let alone the default,
;; eg so that add-function can be used.
@@ -5734,7 +5803,7 @@ be saved."
:version "26.1")
(defun save-some-buffers-root ()
- "A predicate to check whether the buffer is under the root directory.
+ "A predicate to check whether the buffer is under the project root directory.
Can be used as a value of `save-some-buffers-default-predicate'
to save buffers only under the project root or in subdirectories
of the directory that was default during command invocation."
@@ -5743,16 +5812,17 @@ of the directory that was default during command invocation."
(project-root (project-current)))
default-directory)))
(lambda () (file-in-directory-p default-directory root))))
+(put 'save-some-buffers-root 'save-some-buffers-function t)
(defun save-some-buffers (&optional arg pred)
"Save some modified file-visiting buffers. Asks user about each one.
-You can answer `y' or SPC to save, `n' or DEL not to save, `C-r'
+You can answer \\`y' or \\`SPC' to save, \\`n' or \\`DEL' not to save, \\`C-r'
to look at the buffer in question with `view-buffer' before
-deciding, `d' to view the differences using
-`diff-buffer-with-file', `!' to save the buffer and all remaining
-buffers without any further querying, `.' to save only the
-current buffer and skip the remaining ones and `q' or RET to exit
-the function without saving any more buffers. `C-h' displays a
+deciding, \\`d' to view the differences using
+`diff-buffer-with-file', \\`!' to save the buffer and all remaining
+buffers without any further querying, \\`.' to save only the
+current buffer and skip the remaining ones and \\`q' or \\`RET' to exit
+the function without saving any more buffers. \\`C-h' displays a
help message describing these options.
This command first saves any buffers where `buffer-save-without-query' is
@@ -5774,9 +5844,10 @@ change the additional actions you can take on files."
(setq pred save-some-buffers-default-predicate))
;; Allow `pred' to be a function that returns a predicate
;; with lexical bindings in its original environment (bug#46374).
- (let ((pred-fun (and (functionp pred) (funcall pred))))
- (when (functionp pred-fun)
- (setq pred pred-fun)))
+ (when (and (symbolp pred) (get pred 'save-some-buffers-function))
+ (let ((pred-fun (and (functionp pred) (funcall pred))))
+ (when (functionp pred-fun)
+ (setq pred pred-fun))))
(let* ((switched-buffer nil)
(save-some-buffers--switch-window-callback
(lambda (buffer)
@@ -6151,6 +6222,29 @@ Return nil if DIR is not an existing directory."
(unless mismatch
(file-equal-p root dir)))))))
+(defvar file-has-changed-p--hash-table (make-hash-table :test #'equal)
+ "Internal variable used by `file-has-changed-p'.")
+
+(defun file-has-changed-p (file &optional tag)
+ "Return non-nil if FILE has changed.
+The size and modification time of FILE are compared to the size
+and modification time of the same FILE during a previous
+invocation of `file-has-changed-p'. Thus, the first invocation
+of `file-has-changed-p' always returns non-nil when FILE exists.
+The optional argument TAG, which must be a symbol, can be used to
+limit the comparison to invocations with identical tags; it can be
+the symbol of the calling function, for example."
+ (let* ((file (directory-file-name (expand-file-name file)))
+ (remote-file-name-inhibit-cache t)
+ (fileattr (file-attributes file 'integer))
+ (attr (and fileattr
+ (cons (file-attribute-size fileattr)
+ (file-attribute-modification-time fileattr))))
+ (sym (concat (symbol-name tag) "@" file))
+ (cachedattr (gethash sym file-has-changed-p--hash-table)))
+ (when (not (equal attr cachedattr))
+ (puthash sym attr file-has-changed-p--hash-table))))
+
(defun copy-directory (directory newname &optional keep-time parents copy-contents)
"Copy DIRECTORY to NEWNAME. Both args must be strings.
This function always sets the file modes of the output files to match
@@ -6165,6 +6259,9 @@ Noninteractively, the PARENTS argument says whether to create
parent directories if they don't exist. Interactively, this
happens by default.
+If DIRECTORY is a symlink and `copy-directory-create-symlink' is
+non-nil, create a symlink with the same target as DIRECTORY.
+
If NEWNAME is a directory name, copy DIRECTORY as a subdirectory
there. However, if called from Lisp with a non-nil optional
argument COPY-CONTENTS, copy the contents of DIRECTORY directly
@@ -6193,42 +6290,53 @@ into NEWNAME instead."
(setq directory (directory-file-name (expand-file-name directory))
newname (expand-file-name newname))
- (cond ((not (directory-name-p newname))
- ;; If NEWNAME is not a directory name, create it;
- ;; that is where we will copy the files of DIRECTORY.
- (make-directory newname parents))
- ;; NEWNAME is a directory name. If COPY-CONTENTS is non-nil,
- ;; create NEWNAME if it is not already a directory;
- ;; otherwise, create NEWNAME/[DIRECTORY-BASENAME].
- ((if copy-contents
- (or parents (not (file-directory-p newname)))
- (setq newname (concat newname
- (file-name-nondirectory directory))))
- (make-directory (directory-file-name newname) parents))
- (t (setq follow t)))
-
- ;; Copy recursively.
- (dolist (file
- ;; We do not want to copy "." and "..".
- (directory-files directory 'full
- directory-files-no-dot-files-regexp))
- (let ((target (concat (file-name-as-directory newname)
- (file-name-nondirectory file)))
- (filetype (car (file-attributes file))))
- (cond
- ((eq filetype t) ; Directory but not a symlink.
- (copy-directory file target keep-time parents t))
- ((stringp filetype) ; Symbolic link
- (make-symbolic-link filetype target t))
- ((copy-file file target t keep-time)))))
-
- ;; Set directory attributes.
- (let ((modes (file-modes directory))
- (times (and keep-time (file-attribute-modification-time
- (file-attributes directory))))
- (follow-flag (unless follow 'nofollow)))
- (if modes (set-file-modes newname modes follow-flag))
- (if times (set-file-times newname times follow-flag))))))
+ ;; If DIRECTORY is a symlink, create a symlink with the same target.
+ (if (and (file-symlink-p directory)
+ copy-directory-create-symlink)
+ (let ((target (car (file-attributes directory))))
+ (if (directory-name-p newname)
+ (make-symbolic-link target
+ (concat newname
+ (file-name-nondirectory directory))
+ t)
+ (make-symbolic-link target newname t)))
+ ;; Else proceed to copy as a regular directory
+ (cond ((not (directory-name-p newname))
+ ;; If NEWNAME is not a directory name, create it;
+ ;; that is where we will copy the files of DIRECTORY.
+ (make-directory newname parents))
+ ;; NEWNAME is a directory name. If COPY-CONTENTS is non-nil,
+ ;; create NEWNAME if it is not already a directory;
+ ;; otherwise, create NEWNAME/[DIRECTORY-BASENAME].
+ ((if copy-contents
+ (or parents (not (file-directory-p newname)))
+ (setq newname (concat newname
+ (file-name-nondirectory directory))))
+ (make-directory (directory-file-name newname) parents))
+ (t (setq follow t)))
+
+ ;; Copy recursively.
+ (dolist (file
+ ;; We do not want to copy "." and "..".
+ (directory-files directory 'full
+ directory-files-no-dot-files-regexp))
+ (let ((target (concat (file-name-as-directory newname)
+ (file-name-nondirectory file)))
+ (filetype (car (file-attributes file))))
+ (cond
+ ((eq filetype t) ; Directory but not a symlink.
+ (copy-directory file target keep-time parents t))
+ ((stringp filetype) ; Symbolic link
+ (make-symbolic-link filetype target t))
+ ((copy-file file target t keep-time)))))
+
+ ;; Set directory attributes.
+ (let ((modes (file-modes directory))
+ (times (and keep-time (file-attribute-modification-time
+ (file-attributes directory))))
+ (follow-flag (unless follow 'nofollow)))
+ (if modes (set-file-modes newname modes follow-flag))
+ (if times (set-file-times newname times follow-flag)))))))
;; At time of writing, only info uses this.
@@ -7089,16 +7197,16 @@ default directory. However, if FULL is non-nil, they are absolute."
(let ((this-dir-contents
;; Filter out "." and ".."
(delq nil
- (mapcar #'(lambda (name)
- (unless (string-match "\\`\\.\\.?\\'"
- (file-name-nondirectory name))
- name))
+ (mapcar (lambda (name)
+ (unless (string-match "\\`\\.\\.?\\'"
+ (file-name-nondirectory name))
+ name))
(directory-files (or dir ".") full
(wildcard-to-regexp nondir))))))
(setq contents
(nconc
(if (and dir (not full))
- (mapcar #'(lambda (name) (concat dir name))
+ (mapcar (lambda (name) (concat dir name))
this-dir-contents)
this-dir-contents)
contents)))))
@@ -7113,11 +7221,18 @@ DIRNAME is globbed by the shell if necessary.
Prefix arg (second arg if noninteractive) means supply -l switch to `ls'.
Actions controlled by variables `list-directory-brief-switches'
and `list-directory-verbose-switches'."
- (interactive (let ((pfx current-prefix-arg))
- (list (read-directory-name (if pfx "List directory (verbose): "
- "List directory (brief): ")
- nil default-directory nil)
- pfx)))
+ (interactive
+ (let ((pfx current-prefix-arg))
+ (list (read-file-name
+ (if pfx "List directory (verbose): "
+ "List directory (brief): ")
+ nil default-directory t
+ nil
+ (lambda (file)
+ (or (file-directory-p file)
+ (insert-directory-wildcard-in-dir-p
+ (expand-file-name file)))))
+ pfx)))
(let ((switches (if verbose list-directory-verbose-switches
list-directory-brief-switches))
buffer)
@@ -7463,7 +7578,7 @@ normally equivalent short `-D' option is just passed on to
(unless (equal switches "")
;; Split the switches at any spaces so we can
;; pass separate options as separate args.
- (split-string-shell-command switches)))
+ (split-string-and-unquote switches)))
;; Avoid lossage if FILE starts with `-'.
'("--")
(list file))))))
@@ -7568,21 +7683,7 @@ normally equivalent short `-D' option is just passed on to
(if val coding-no-eol coding))
(if val
(put-text-property pos (point)
- 'dired-filename t)))))))
-
- (if full-directory-p
- ;; Try to insert the amount of free space.
- (save-excursion
- (goto-char beg)
- ;; First find the line to put it on.
- (when (re-search-forward "^ *\\(total\\)" nil t)
- ;; Replace "total" with "total used in directory" to
- ;; avoid confusion.
- (replace-match "total used in directory" nil nil nil 1)
- (let ((available (get-free-disk-space ".")))
- (when available
- (end-of-line)
- (insert " available " available))))))))))
+ 'dired-filename t)))))))))))
(defun insert-directory-adj-pos (pos error-lines)
"Convert `ls --dired' file name position value POS to a buffer position.
@@ -7743,10 +7844,11 @@ only these files will be asked to be saved."
;; Get a list of the indices of the args that are file names.
(file-arg-indices
(cdr (or (assq operation
- '(;; The first seven are special because they
+ '(;; The first eight are special because they
;; return a file name. We want to include
;; the /: in the return value. So just
;; avoid stripping it in the first place.
+ (abbreviate-file-name)
(directory-file-name)
(expand-file-name)
(file-name-as-directory)
@@ -7912,7 +8014,7 @@ for the specified category of users."
((= char ?g) #o2070)
((= char ?o) #o1007)
((= char ?a) #o7777)
- (t (error "%c: bad `who' character" char))))
+ (t (error "%c: Bad `who' character" char))))
(defun file-modes-char-to-right (char &optional from)
"Convert CHAR to a numeric value of mode bits.
@@ -7935,7 +8037,7 @@ If CHAR is in [Xugo], the value is taken from FROM (or 0 if omitted)."
(+ gright (/ gright #o10) (* gright #o10))))
((= char ?o) (let ((oright (logand #o1007 from)))
(+ oright (* oright #o10) (* oright #o100))))
- (t (error "%c: bad right character" char))))
+ (t (error "%c: Bad right character" char))))
(defun file-modes-rights-to-number (rights who-mask &optional from)
"Convert a symbolic mode string specification to an equivalent number.
diff --git a/lisp/filesets.el b/lisp/filesets.el
index 8e9fae80f69..9182c539452 100644
--- a/lisp/filesets.el
+++ b/lisp/filesets.el
@@ -112,7 +112,8 @@
(defvar filesets-updated-buffers nil
"A list of buffers with updated menu bars.")
(defvar filesets-menu-use-cached-flag nil
- "Use cached data. See `filesets-menu-ensure-use-cached' for details.")
+ "Non-nil means use cached data.
+See `filesets-menu-ensure-use-cached' for details.")
(defvar filesets-update-cache-file-flag nil
"Non-nil means the cache needs updating.")
(defvar filesets-ignore-next-set-default nil
@@ -607,8 +608,8 @@ the filename."
(:ignore-on-read-text t)
;; (:constraintp ,pic-cmd)
))))
- "Association list of file patterns and external viewers for use with
-`filesets-find-or-display-file'.
+ "Alist of file patterns and external viewers.
+This is intended for use with `filesets-find-or-display-file'.
Has the form ((FILE-PATTERN VIEWER PROPERTIES) ...), VIEWER being either a
function or a command name as string.
@@ -1770,7 +1771,7 @@ User will be queried, if no fileset name is provided."
filesets-data nil)))
(entry (or (assoc name filesets-data)
(when (y-or-n-p
- (format "Fileset %s does not exist. Create it? "
+ (format "Fileset %s does not exist. Create it?"
name))
(progn
(add-to-list 'filesets-data (list name '(:files)))
@@ -1848,7 +1849,7 @@ User will be queried, if no fileset name is provided."
(filesets-goto-homepage)))
(defun filesets-goto-homepage ()
- "Show filesets's homepage."
+ "Show filesets's website."
(interactive)
(browse-url filesets-homepage))
@@ -2198,8 +2199,9 @@ FS is a fileset's name. FLIST is a list returned by
nil))
(defun filesets-build-dir-submenu (entry lookup-name dir patt)
- "Build a :tree submenu named LOOKUP-NAME with base directory DIR including
-all files matching PATT for filesets ENTRY."
+ "Build a `:tree' submenu named LOOKUP-NAME.
+It has base directory DIR including all files matching PATT for
+filesets ENTRY."
(let ((fd (filesets-entry-get-filter-dirs-flag entry))
(depth (or (filesets-entry-get-tree-max-level entry)
filesets-tree-max-level)))
diff --git a/lisp/find-dired.el b/lisp/find-dired.el
index 87a7407a866..ebdb10ae9fc 100644
--- a/lisp/find-dired.el
+++ b/lisp/find-dired.el
@@ -266,7 +266,7 @@ it finishes, type \\[kill-find]."
;;;###autoload
(defun find-name-dired (dir pattern)
- "Search DIR recursively for files matching the globbing pattern PATTERN,
+ "Search DIR recursively for files matching the globbing PATTERN,
and run Dired on those files.
PATTERN is a shell wildcard (not an Emacs regexp) and need not be quoted.
The default command run (after changing into DIR) is
diff --git a/lisp/find-file.el b/lisp/find-file.el
index 4fd4f4e06b8..afe6cb51502 100644
--- a/lisp/find-file.el
+++ b/lisp/find-file.el
@@ -32,7 +32,7 @@
;;
;; Many people maintain their include file in a directory separate to their
;; src directory, and very often you may be editing a file and have a need to
-;; visit the "other file". This package searches through a set of directories
+;; visit the "other file". This package searches through a set of directories
;; to find that file.
;;
;; THE "OTHER FILE", or "corresponding file", generally has the same basename,
@@ -44,14 +44,14 @@
;;
;; If the current file has a .cc extension, ff-find-other-file will attempt
;; to look for a .hh file, and then a .h file in some directory as described
-;; below. The mechanism here is to replace the matched part of the original
+;; below. The mechanism here is to replace the matched part of the original
;; filename with each of the corresponding extensions in turn.
;;
;; Alternatively, there are situations where the filename of the other file
-;; cannot be determined easily with regexps. For example, a .c file may
+;; cannot be determined easily with regexps. For example, a .c file may
;; have two corresponding .h files, for its public and private parts, or
;; the filename for the .c file contains part of the pathname of the .h
-;; file, as between src/fooZap.cc and include/FOO/zap.hh. In that case, the
+;; file, as between src/fooZap.cc and include/FOO/zap.hh. In that case, the
;; format above can be changed to include a function to be called when the
;; current file matches the regexp:
;;
@@ -59,7 +59,7 @@
;; ("\\.hh\\'" hh-function))
;;
;; These functions must return a list consisting of the possible names of the
-;; corresponding file, with or without path. There is no real need for more
+;; corresponding file, with or without path. There is no real need for more
;; than one function, and one could imagine the following value for cc-other-
;; file-alist:
;;
@@ -78,13 +78,13 @@
;;
;; This means that the corresponding file will be searched for first in
;; the current directory, then in ../../src, then in one of the directories
-;; under ../include, and so on. The star is _not_ a general wildcard
+;; under ../include, and so on. The star is _not_ a general wildcard
;; character: it just indicates that the subdirectories of this directory
-;; must each be searched in turn. Environment variables will be expanded in
+;; must each be searched in turn. Environment variables will be expanded in
;; the ff-search-directories variable.
;;
;; If the point is on a #include line, the file to be #included is searched
-;; for in the same manner. This can be disabled with the ff-ignore-include
+;; for in the same manner. This can be disabled with the ff-ignore-include
;; variable, or by calling ff-get-other-file instead of ff-find-other-file.
;;
;; If the file was not found, ff-find-other-file will prompt you for where
@@ -356,7 +356,7 @@ Variables of interest include:
List of functions to be called if the other file has been created."
(interactive (list current-prefix-arg nil last-nonmenu-event))
;; We want to preserve point in the current buffer. But the point of
- ;; ff-find-the-other-file is to make the the other file buffer
+ ;; ff-find-the-other-file is to make the other file buffer
;; current, so we can't use save-excursion here (see bug 48535).
(let ((start-buffer (current-buffer))
(start-point (point)))
diff --git a/lisp/find-lisp.el b/lisp/find-lisp.el
index 2f432936033..6062bd26432 100644
--- a/lisp/find-lisp.el
+++ b/lisp/find-lisp.el
@@ -24,21 +24,21 @@
;;; Commentary:
;;
;; This is a very generalized form of find; it basically implements a
-;; recursive directory descent. The conditions which bound the search
+;; recursive directory descent. The conditions which bound the search
;; are expressed as predicates, and I have not addressed the question
;; of how to wrap up the common chores that find does in a simpler
;; format than writing code for all the various predicates.
;;
;; Some random thoughts are to express simple queries directly with
;; user-level functions, and perhaps use some kind of forms interface
-;; for medium-level queries. Really complicated queries can be
+;; for medium-level queries. Really complicated queries can be
;; expressed in Lisp.
;;
;;; Todo
;;
;; It would be nice if we could sort the results without running the find
-;; again. Maybe that could work by storing the original file attributes?
+;; again. Maybe that could work by storing the original file attributes?
;;; Code:
diff --git a/lisp/finder.el b/lisp/finder.el
index c2d5806c0cd..00f321b8028 100644
--- a/lisp/finder.el
+++ b/lisp/finder.el
@@ -247,7 +247,7 @@ from; the default is `load-path'."
;; The idea here is that eg calc.el gets to define
;; the description of the calc package.
;; This does not work for eg nxml-mode.el.
- ((or (eq base-name package) version)
+ ((eq base-name package)
(setq desc (cdr entry))
(aset desc 0 version)
(aset desc 2 summary)))
@@ -362,24 +362,18 @@ not `finder-known-keywords'."
(let ((package-list-unversioned t))
(package-show-package-list packages))))
-(define-button-type 'finder-xref 'action #'finder-goto-xref)
-
-(defun finder-goto-xref (button)
- "Jump to a Lisp file for the BUTTON at point."
- (let* ((file (button-get button 'xref))
- (lib (locate-library file)))
- (if lib (finder-commentary lib)
- (message "Unable to locate `%s'" file))))
-
;;;###autoload
(defun finder-commentary (file)
"Display FILE's commentary section.
FILE should be in a form suitable for passing to `locate-library'."
+ ;; FIXME: Merge this function into `describe-package', which is
+ ;; strictly better as it has links to URL's and is in a proper help
+ ;; buffer with navigation forward and backward, etc.
(interactive
(list
(completing-read "Library name: "
(apply-partially 'locate-file-completion-table
- (or find-function-source-path load-path)
+ (or find-library-source-path load-path)
(find-library-suffixes)))))
(let ((str (lm-commentary (find-library-name file))))
(or str (error "Can't find any Commentary section"))
@@ -391,12 +385,7 @@ FILE should be in a form suitable for passing to `locate-library'."
(erase-buffer)
(insert str)
(goto-char (point-min))
- (while (re-search-forward "\\<\\([-[:alnum:]]+\\.el\\)\\>" nil t)
- (if (locate-library (match-string 1))
- (make-text-button (match-beginning 1) (match-end 1)
- 'xref (match-string-no-properties 1)
- 'help-echo "Read this file's commentary"
- :type 'finder-xref)))
+ (package--describe-add-library-links)
(goto-char (point-min))
(setq buffer-read-only t)
(set-buffer-modified-p nil)
@@ -469,6 +458,9 @@ Quit the window and kill all Finder-related buffers."
;; continue standard unloading
nil)
+(define-obsolete-function-alias 'finder-goto-xref
+ #'package--finder-goto-xref "29.1")
+
(provide 'finder)
diff --git a/lisp/foldout.el b/lisp/foldout.el
index cadf2746ba1..8925241df32 100644
--- a/lisp/foldout.el
+++ b/lisp/foldout.el
@@ -239,7 +239,7 @@ An end marker of nil means the fold ends after (point-max).")
Normally the body and the immediate subheadings are exposed, but
optional arg EXPOSURE \(interactively with prefix arg) changes this:-
- EXPOSURE > 0 exposes n levels of subheadings (c.f. show-children)
+ EXPOSURE > 0 exposes n levels of subheadings (c.f. `show-children')
EXPOSURE < 0 exposes only the body
EXPOSURE = 0 exposes the entire subtree"
(interactive "P")
diff --git a/lisp/follow.el b/lisp/follow.el
index dde140d0fd5..3761275bbf6 100644
--- a/lisp/follow.el
+++ b/lisp/follow.el
@@ -667,22 +667,32 @@ Works like `scroll-down' when not in Follow mode."
(scroll-down-command arg))
(arg (follow-scroll-down-arg arg))
(t
- (let* ((windows (follow-all-followers))
- (win (car (reverse windows)))
- (start (window-start (car windows))))
+ (let* ((orig-point (point))
+ (windows (follow-all-followers))
+ (start (window-start (car windows)))
+ (lines 0))
(if (eq start (point-min))
(if (or (null scroll-error-top-bottom)
(bobp))
(signal 'beginning-of-buffer nil)
(goto-char (point-min)))
- (select-window win)
- (goto-char start)
- (vertical-motion (- (- (window-height win)
- (if header-line-format 2 1)
- next-screen-context-lines)))
- (set-window-start win (point))
- (goto-char start)
- (vertical-motion (- next-screen-context-lines 1))
+ (select-window (car windows))
+ (dolist (win windows)
+ (setq lines
+ (+ lines
+ (- (window-height win)
+ (if header-line-format 2 1) ; Count mode-line, too.
+ (if tab-line-format 1 0)))))
+ (setq lines (- lines next-screen-context-lines))
+ (goto-char start)
+ (let ((at-top (> (vertical-motion (- lines)) (- lines))))
+ (set-window-start (car windows) (point))
+ (if at-top
+ (goto-char orig-point)
+ (goto-char start)
+ (vertical-motion (- next-screen-context-lines 1))
+ (if (< orig-point (point))
+ (goto-char orig-point))))
(setq follow-internal-force-redisplay t))))))
(put 'follow-scroll-down 'scroll-command t)
@@ -858,8 +868,11 @@ from the bottom."
(windows (follow-all-followers))
(win (nth (/ (- (length windows) 1) 2) windows)))
(select-window win)
- (goto-char dest)
- (recenter))))
+ (let ((win-s (window-start)))
+ (goto-char dest)
+ (recenter)
+ (when (< dest win-s)
+ (setq follow-internal-force-redisplay t))))))
(defun follow-redraw ()
@@ -944,7 +957,11 @@ used."
(let* ((win (or win (selected-window)))
(edges (window-inside-pixel-edges win))
(ht (- (nth 3 edges) (nth 1 edges)))
- (last-line-pos (posn-point (posn-at-x-y 0 (1- ht) win))))
+ (last-line-pos (posn-point
+ (posn-at-x-y 0 (+ (window-header-line-height win)
+ (window-tab-line-height win)
+ (1- ht))
+ win))))
(if (pos-visible-in-window-p last-line-pos win)
(let ((end (window-end win t)))
(list end (pos-visible-in-window-p (point-max) win)))
diff --git a/lisp/font-core.el b/lisp/font-core.el
index db06a607660..95bf46c9b8b 100644
--- a/lisp/font-core.el
+++ b/lisp/font-core.el
@@ -21,6 +21,8 @@
;; 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:
;; This variable is used by mode packages that support Font Lock mode by
diff --git a/lisp/font-lock.el b/lisp/font-lock.el
index c00a62a1607..c2590eb3c11 100644
--- a/lisp/font-lock.el
+++ b/lisp/font-lock.el
@@ -697,7 +697,7 @@ comments, and to fontify `and', `or' and `not' words as keywords.
The above procedure will only add the keywords for C mode, not
for modes derived from C mode. To add them for derived modes too,
-pass nil for MODE and add the call to c-mode-hook.
+pass nil for MODE and add the call to `c-mode-hook'.
For example:
@@ -1039,7 +1039,7 @@ The function is given three parameters, the standard BEG, END, and OLD-LEN
from `after-change-functions'. It should return either a cons of the beginning
and end buffer positions \(in that order) of the region to refontify, or nil
\(which directs the caller to fontify a default region).
-This function should preserve the match-data.
+This function should preserve the match data.
The region it returns may start or end in the middle of a line.")
(defun font-lock-fontify-buffer (&optional interactively)
@@ -1103,7 +1103,7 @@ Called with two arguments BEG and END.")
(defun font-lock-debug-fontify ()
"Reinitialize the font-lock machinery and (re-)fontify the buffer.
This functions is a convenience functions when developing font
-locking for a mode, and is not meant to be called from lisp functions."
+locking for a mode, and is not meant to be called from Lisp functions."
(declare (interactive-only t))
(interactive)
;; Make font-lock recalculate all the mode-specific data.
@@ -1124,7 +1124,7 @@ portion of the buffer."
(or beg (point-min)) (or end (point-max)))))
(defun font-lock-update (&optional arg)
- "Updates the syntax highlighting in this buffer.
+ "Update the syntax highlighting in this buffer.
Refontify the accessible portion of this buffer, or enable Font Lock mode
in this buffer if it is currently disabled. With prefix ARG, toggle Font
Lock mode."
@@ -2075,7 +2075,7 @@ as the constructs of Haddock, Javadoc and similar systems."
(((class color) (min-colors 16) (background dark)) :foreground "PaleGreen")
(((class color) (min-colors 8)) :foreground "green")
(t :weight bold :underline t))
- "Font Lock mode face used to highlight type and classes."
+ "Font Lock mode face used to highlight type and class names."
:group 'font-lock-faces)
(defface font-lock-constant-face
@@ -2341,7 +2341,7 @@ This should be an integer. Used in `cpp-font-lock-keywords'.")
"Font lock keywords for C preprocessor directives.
`c-mode', `c++-mode' and `objc-mode' have their own font lock keywords
for C preprocessor directives. This definition is for the other modes
-in which C preprocessor directives are used. e.g. `asm-mode' and
+in which C preprocessor directives are used, e.g. `asm-mode' and
`ld-script-mode'.")
(provide 'font-lock)
diff --git a/lisp/format.el b/lisp/format.el
index 71cf885d417..8ae51f19ebc 100644
--- a/lisp/format.el
+++ b/lisp/format.el
@@ -320,7 +320,7 @@ If the format is not specified, attempt a regexp-based guess.
Set `buffer-file-format' to the format used, and call any
format-specific mode functions."
(interactive
- (list (format-read "Translate buffer from format (default guess): ")))
+ (list (format-read (format-prompt "Translate buffer from format" "guess"))))
(save-excursion
(goto-char (point-min))
(format-decode format (buffer-size) t)))
@@ -331,7 +331,7 @@ Arg FORMAT is optional; if omitted the format will be determined by looking
for identifying regular expressions at the beginning of the region."
(interactive
(list (region-beginning) (region-end)
- (format-read "Translate region from format (default guess): ")))
+ (format-read (format-prompt "Translate region from format" "guess"))))
(save-excursion
(goto-char from)
(format-decode format (- to from) nil)))
@@ -519,7 +519,7 @@ the value of `foo'."
(cdr list)
(let ((p list))
(while (not (eq (cdr p) cons))
- (if (null p) (error "format-delq-cons: not an element"))
+ (if (null p) (error "format-delq-cons: Not an element"))
(setq p (cdr p)))
;; Now (cdr p) is the cons to delete
(setcdr p (cdr cons))
diff --git a/lisp/forms.el b/lisp/forms.el
index 46f4df9b6c4..551a1ba3c97 100644
--- a/lisp/forms.el
+++ b/lisp/forms.el
@@ -88,7 +88,7 @@
;; constructed. The current fields are available to the function
;; in the variable `forms-fields', they should *NOT* be modified.
;;
-;; - a lisp symbol, that must evaluate to one of the above.
+;; - a Lisp symbol, that must evaluate to one of the above.
;;
;; Optional variables which may be set in the control file:
;;
@@ -357,7 +357,7 @@ This variable is for use by the filter routines only.
The contents may NOT be modified.")
(defcustom forms-use-text-properties t
- "Non-nil means to use text properties. "
+ "Non-nil means to use text properties."
:type 'boolean)
(defcustom forms-insert-after nil
@@ -376,7 +376,7 @@ Also, initial position is at last record."
;;; Internal variables.
(defvar forms--file-buffer nil
- "Buffer which holds the file data")
+ "Buffer which holds the file data.")
(defvar forms--total-records 0
"Total number of records in the data file.")
@@ -410,7 +410,7 @@ Also, initial position is at last record."
"Forms parser routine.")
(defvar-local forms--mode-setup nil
- "To keep track of forms-mode being set-up.")
+ "To keep track of `forms-mode' being set-up.")
(defvar forms--dynamic-text nil
"Array that holds dynamic texts to insert between fields.")
@@ -453,8 +453,7 @@ Commands: Equivalent keys in read-only mode:
C-c C-p forms-prev-record p
C-c C-r forms-search-reverse r
C-c C-s forms-search-forward s
- C-c C-x forms-exit x
-"
+ C-c C-x forms-exit x"
(interactive)
;; This is not a simple major mode, as usual. Therefore, forms-mode
@@ -1392,8 +1391,7 @@ Commands: Equivalent keys in read-only mode:
(define-key map [prior] #'forms-prev-record)
(define-key map [begin] #'forms-first-record)
(define-key map [last] #'forms-last-record)
- (define-key map [backtab] #'forms-prev-field)
- )
+ (define-key map [backtab] #'forms-prev-field))
;;; Changed functions
@@ -1435,8 +1433,8 @@ Commands: Equivalent keys in read-only mode:
" \\[describe-mode]:help"))))
(defun forms--trans (subj arg rep)
- "Translate in SUBJ all chars ARG into char REP. ARG and REP should
- be single-char strings."
+ "Translate in SUBJ all chars ARG into char REP.
+ARG and REP should be single-char strings."
(let ((i 0)
(re (regexp-quote arg))
(k (string-to-char rep)))
@@ -1707,7 +1705,7 @@ As a side effect: re-calculates the number of records in the data file."
;;; Other commands
(defun forms-toggle-read-only (arg)
- "Toggles read-only mode of a forms mode buffer.
+ "Toggle read-only mode of a forms mode buffer.
With an argument, enables read-only mode if the argument is positive.
Otherwise enables edit mode if the visited file is writable."
@@ -1880,7 +1878,7 @@ after the current record."
(setq forms--search-regexp regexp))
(defun forms-save-buffer (&optional args)
- "Forms mode replacement for save-buffer.
+ "Forms mode replacement for `save-buffer'.
It saves the data buffer instead of the forms buffer.
Calls `forms-write-file-filter' before, and `forms-read-file-filter'
after writing out the data."
diff --git a/lisp/frame.el b/lisp/frame.el
index 146fe278b3e..13929047d08 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -701,9 +701,8 @@ Return nil if we don't know how to interpret DISPLAY."
"Make a frame on display DISPLAY.
The optional argument PARAMETERS specifies additional frame parameters."
(interactive (if (fboundp 'x-display-list)
- (list (completing-read
- (format "Make frame on display: ")
- (x-display-list)))
+ (list (completing-read "Make frame on display: "
+ (x-display-list)))
(user-error "This Emacs build does not support X displays")))
(make-frame (cons (cons 'display display) parameters)))
@@ -787,13 +786,38 @@ When called from Lisp, returns the new frame."
(make-frame)
(select-frame (make-frame))))
+(defun clone-frame (&optional frame no-windows)
+ "Make a new frame with the same parameters and windows as FRAME.
+With a prefix arg NO-WINDOWS, don't clone the window configuration.
+
+FRAME defaults to the selected frame. The frame is created on the
+same terminal as FRAME. If the terminal is a text-only terminal then
+also select the new frame."
+ (interactive (list (selected-frame) current-prefix-arg))
+ (let* ((frame (or frame (selected-frame)))
+ (windows (unless no-windows
+ (window-state-get (frame-root-window frame))))
+ (default-frame-alist
+ (seq-remove (lambda (elem) (eq (car elem) 'name))
+ (frame-parameters frame)))
+ (new-frame (make-frame)))
+ (when windows
+ (window-state-put windows (frame-root-window new-frame) 'safe))
+ (unless (display-graphic-p)
+ (select-frame new-frame))
+ new-frame))
+
(defvar before-make-frame-hook nil
- "Functions to run before `make-frame' creates a new frame.")
+ "Functions to run before `make-frame' creates a new frame.
+Note that these functions are usually not run for the initial
+frame, unless you add them to the hook in your early-init file.")
(defvar after-make-frame-functions nil
"Functions to run after `make-frame' created a new frame.
The functions are run with one argument, the newly created
-frame.")
+frame.
+Note that these functions are usually not run for the initial
+frame, unless you add them to the hook in your early-init file.")
(defvar after-setting-font-hook nil
"Functions to run after a frame's font has been changed.")
@@ -1507,7 +1531,7 @@ To get the frame's current background color, use `frame-parameters'."
"Set the foreground color of the selected frame to COLOR-NAME.
When called interactively, prompt for the name of the color to use.
To get the frame's current foreground color, use `frame-parameters'."
- (interactive (list (read-color "Foreground color: ")))
+ (interactive (list (read-color "Foreground color: " nil nil nil t)))
(modify-frame-parameters (selected-frame)
(list (cons 'foreground-color color-name)))
(or window-system
@@ -1613,6 +1637,8 @@ live frame and defaults to the selected one."
(declare-function x-frame-geometry "xfns.c" (&optional frame))
(declare-function w32-frame-geometry "w32fns.c" (&optional frame))
(declare-function ns-frame-geometry "nsfns.m" (&optional frame))
+(declare-function pgtk-frame-geometry "pgtkfns.c" (&optional frame))
+(declare-function haiku-frame-geometry "haikufns.c" (&optional frame))
(defun frame-geometry (&optional frame)
"Return geometric attributes of FRAME.
@@ -1662,6 +1688,10 @@ and width values are in pixels.
(w32-frame-geometry frame))
((eq frame-type 'ns)
(ns-frame-geometry frame))
+ ((eq frame-type 'pgtk)
+ (pgtk-frame-geometry frame))
+ ((eq frame-type 'haiku)
+ (haiku-frame-geometry frame))
(t
(list
'(outer-position 0 . 0)
@@ -1786,6 +1816,8 @@ of frames like calls to map a frame or change its visibility."
(declare-function x-frame-edges "xfns.c" (&optional frame type))
(declare-function w32-frame-edges "w32fns.c" (&optional frame type))
(declare-function ns-frame-edges "nsfns.m" (&optional frame type))
+(declare-function pgtk-frame-edges "pgtkfns.c" (&optional frame type))
+(declare-function haiku-frame-edges "haikufns.c" (&optional frame type))
(defun frame-edges (&optional frame type)
"Return coordinates of FRAME's edges.
@@ -1809,12 +1841,18 @@ FRAME."
(w32-frame-edges frame type))
((eq frame-type 'ns)
(ns-frame-edges frame type))
+ ((eq frame-type 'pgtk)
+ (pgtk-frame-edges frame type))
+ ((eq frame-type 'haiku)
+ (haiku-frame-edges frame type))
(t
(list 0 0 (frame-width frame) (frame-height frame))))))
(declare-function w32-mouse-absolute-pixel-position "w32fns.c")
(declare-function x-mouse-absolute-pixel-position "xfns.c")
(declare-function ns-mouse-absolute-pixel-position "nsfns.m")
+(declare-function pgtk-mouse-absolute-pixel-position "pgtkfns.c")
+(declare-function haiku-mouse-absolute-pixel-position "haikufns.c")
(defun mouse-absolute-pixel-position ()
"Return absolute position of mouse cursor in pixels.
@@ -1829,12 +1867,18 @@ position (0, 0) of the selected frame's terminal."
(w32-mouse-absolute-pixel-position))
((eq frame-type 'ns)
(ns-mouse-absolute-pixel-position))
+ ((eq frame-type 'pgtk)
+ (pgtk-mouse-absolute-pixel-position))
+ ((eq frame-type 'haiku)
+ (haiku-mouse-absolute-pixel-position))
(t
(cons 0 0)))))
+(declare-function pgtk-set-mouse-absolute-pixel-position "pgtkfns.c" (x y))
(declare-function ns-set-mouse-absolute-pixel-position "nsfns.m" (x y))
(declare-function w32-set-mouse-absolute-pixel-position "w32fns.c" (x y))
(declare-function x-set-mouse-absolute-pixel-position "xfns.c" (x y))
+(declare-function haiku-set-mouse-absolute-pixel-position "haikufns.c" (x y))
(defun set-mouse-absolute-pixel-position (x y)
"Move mouse pointer to absolute pixel position (X, Y).
@@ -1842,12 +1886,16 @@ The coordinates X and Y are interpreted in pixels relative to a
position (0, 0) of the selected frame's terminal."
(let ((frame-type (framep-on-display)))
(cond
+ ((eq frame-type 'pgtk)
+ (pgtk-set-mouse-absolute-pixel-position x y))
((eq frame-type 'ns)
(ns-set-mouse-absolute-pixel-position x y))
((eq frame-type 'x)
(x-set-mouse-absolute-pixel-position x y))
((eq frame-type 'w32)
- (w32-set-mouse-absolute-pixel-position x y)))))
+ (w32-set-mouse-absolute-pixel-position x y))
+ ((eq frame-type 'haiku)
+ (haiku-set-mouse-absolute-pixel-position x y)))))
(defun frame-monitor-attributes (&optional frame)
"Return the attributes of the physical monitor dominating FRAME.
@@ -1940,6 +1988,8 @@ workarea attribute."
(declare-function x-frame-list-z-order "xfns.c" (&optional display))
(declare-function w32-frame-list-z-order "w32fns.c" (&optional display))
(declare-function ns-frame-list-z-order "nsfns.m" (&optional display))
+(declare-function pgtk-frame-list-z-order "pgtkfns.c" (&optional display))
+(declare-function haiku-frame-list-z-order "haikufns.c" (&optional display))
(defun frame-list-z-order (&optional display)
"Return list of Emacs' frames, in Z (stacking) order.
@@ -1959,11 +2009,16 @@ Return nil if DISPLAY contains no Emacs frame."
((eq frame-type 'w32)
(w32-frame-list-z-order display))
((eq frame-type 'ns)
- (ns-frame-list-z-order display)))))
+ (ns-frame-list-z-order display))
+ ((eq frame-type 'pgtk)
+ (pgtk-frame-list-z-order display))
+ ((eq frame-type 'haiku)
+ (haiku-frame-list-z-order display)))))
(declare-function x-frame-restack "xfns.c" (frame1 frame2 &optional above))
(declare-function w32-frame-restack "w32fns.c" (frame1 frame2 &optional above))
(declare-function ns-frame-restack "nsfns.m" (frame1 frame2 &optional above))
+(declare-function pgtk-frame-restack "pgtkfns.c" (frame1 frame2 &optional above))
(defun frame-restack (frame1 frame2 &optional above)
"Restack FRAME1 below FRAME2.
@@ -1993,7 +2048,9 @@ Some window managers may refuse to restack windows."
((eq frame-type 'w32)
(w32-frame-restack frame1 frame2 above))
((eq frame-type 'ns)
- (ns-frame-restack frame1 frame2 above))))
+ (ns-frame-restack frame1 frame2 above))
+ ((eq frame-type 'pgtk)
+ (pgtk-frame-restack frame1 frame2 above))))
(error "Cannot restack frames")))
(defun frame-size-changed-p (&optional frame)
@@ -2040,8 +2097,8 @@ frame's display)."
((eq frame-type 'w32)
(with-no-warnings
(> w32-num-mouse-buttons 0)))
- ((memq frame-type '(x ns))
- t) ;; We assume X and NeXTstep *always* have a pointing device
+ ((memq frame-type '(x ns haiku pgtk))
+ t) ;; We assume X, NeXTstep, GTK, and Haiku *always* have a pointing device
(t
(or (and (featurep 'xt-mouse)
xterm-mouse-mode)
@@ -2066,7 +2123,7 @@ frames and several different fonts at once. This is true for displays
that use a window system such as X, and false for text-only terminals.
DISPLAY can be a display name, a frame, or nil (meaning the selected
frame's display)."
- (not (null (memq (framep-on-display display) '(x w32 ns)))))
+ (not (null (memq (framep-on-display display) '(x w32 ns pgtk haiku)))))
(defun display-images-p (&optional display)
"Return non-nil if DISPLAY can display images.
@@ -2094,7 +2151,7 @@ frame's display)."
;; a Windows DOS Box.
(with-no-warnings
(not (null dos-windows-version))))
- ((memq frame-type '(x w32 ns))
+ ((memq frame-type '(x w32 ns pgtk))
t)
(t
nil))))
@@ -2104,7 +2161,7 @@ frame's display)."
This means that, for example, DISPLAY can differentiate between
the keybinding RET and [return]."
(let ((frame-type (framep-on-display display)))
- (or (memq frame-type '(x w32 ns pc))
+ (or (memq frame-type '(x w32 ns pc pgtk))
;; MS-DOS and MS-Windows terminals have built-in support for
;; function (symbol) keys
(memq system-type '(ms-dos windows-nt)))))
@@ -2117,7 +2174,7 @@ DISPLAY should be either a frame or a display name (a string).
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(let ((frame-type (framep-on-display display)))
(cond
- ((memq frame-type '(x w32 ns))
+ ((memq frame-type '(x w32 ns haiku pgtk))
(x-display-screens display))
(t
1))))
@@ -2137,7 +2194,7 @@ with DISPLAY. To get information for each physical monitor, use
`display-monitor-attributes-list'."
(let ((frame-type (framep-on-display display)))
(cond
- ((memq frame-type '(x w32 ns))
+ ((memq frame-type '(x w32 ns haiku pgtk))
(x-display-pixel-height display))
(t
(frame-height (if (framep display) display (selected-frame)))))))
@@ -2157,7 +2214,7 @@ with DISPLAY. To get information for each physical monitor, use
`display-monitor-attributes-list'."
(let ((frame-type (framep-on-display display)))
(cond
- ((memq frame-type '(x w32 ns))
+ ((memq frame-type '(x w32 ns haiku pgtk))
(x-display-pixel-width display))
(t
(frame-width (if (framep display) display (selected-frame)))))))
@@ -2195,7 +2252,7 @@ For graphical terminals, note that on \"multi-monitor\" setups this
refers to the height in millimeters for all physical monitors
associated with DISPLAY. To get information for each physical
monitor, use `display-monitor-attributes-list'."
- (and (memq (framep-on-display display) '(x w32 ns))
+ (and (memq (framep-on-display display) '(x w32 ns haiku pgtk))
(or (cddr (assoc (or display (frame-parameter nil 'display))
display-mm-dimensions-alist))
(cddr (assoc t display-mm-dimensions-alist))
@@ -2216,7 +2273,7 @@ For graphical terminals, note that on \"multi-monitor\" setups this
refers to the width in millimeters for all physical monitors
associated with DISPLAY. To get information for each physical
monitor, use `display-monitor-attributes-list'."
- (and (memq (framep-on-display display) '(x w32 ns))
+ (and (memq (framep-on-display display) '(x w32 ns haiku pgtk))
(or (cadr (assoc (or display (frame-parameter nil 'display))
display-mm-dimensions-alist))
(cadr (assoc t display-mm-dimensions-alist))
@@ -2234,7 +2291,7 @@ DISPLAY can be a display name or a frame.
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(let ((frame-type (framep-on-display display)))
(cond
- ((memq frame-type '(x w32 ns))
+ ((memq frame-type '(x w32 ns haiku pgtk))
(x-display-backing-store display))
(t
'not-useful))))
@@ -2247,7 +2304,7 @@ DISPLAY can be a display name or a frame.
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(let ((frame-type (framep-on-display display)))
(cond
- ((memq frame-type '(x w32 ns))
+ ((memq frame-type '(x w32 ns haiku pgtk))
(x-display-save-under display))
(t
'not-useful))))
@@ -2260,7 +2317,7 @@ DISPLAY can be a display name or a frame.
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(let ((frame-type (framep-on-display display)))
(cond
- ((memq frame-type '(x w32 ns))
+ ((memq frame-type '(x w32 ns haiku pgtk))
(x-display-planes display))
((eq frame-type 'pc)
4)
@@ -2275,7 +2332,7 @@ DISPLAY can be a display name or a frame.
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(let ((frame-type (framep-on-display display)))
(cond
- ((memq frame-type '(x w32 ns))
+ ((memq frame-type '(x w32 ns haiku pgtk))
(x-display-color-cells display))
((eq frame-type 'pc)
16)
@@ -2292,7 +2349,7 @@ DISPLAY can be a display name or a frame.
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(let ((frame-type (framep-on-display display)))
(cond
- ((memq frame-type '(x w32 ns))
+ ((memq frame-type '(x w32 ns haiku pgtk))
(x-display-visual-class display))
((and (memq frame-type '(pc t))
(tty-display-color-p display))
@@ -2306,6 +2363,8 @@ If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(&optional display))
(declare-function ns-display-monitor-attributes-list "nsfns.m"
(&optional terminal))
+(declare-function pgtk-display-monitor-attributes-list "pgtkfns.c"
+ (&optional terminal))
(defun display-monitor-attributes-list (&optional display)
"Return a list of physical monitor attributes on DISPLAY.
@@ -2323,6 +2382,7 @@ of attribute keys and values as follows:
mm-size -- Width and height in millimeters in the form of
(WIDTH HEIGHT)
frames -- List of frames dominated by the physical monitor
+ scale-factor (*) -- Scale factor (float)
name (*) -- Name of the physical monitor as a string
source (*) -- Source of multi-monitor information as a string
@@ -2354,6 +2414,8 @@ monitors."
(w32-display-monitor-attributes-list display))
((eq frame-type 'ns)
(ns-display-monitor-attributes-list display))
+ ((eq frame-type 'pgtk)
+ (pgtk-display-monitor-attributes-list display))
(t
(let ((geometry (list 0 0 (display-pixel-width display)
(display-pixel-height display))))
@@ -2807,6 +2869,7 @@ See also `toggle-frame-maximized'."
(define-key ctl-x-5-map "0" #'delete-frame)
(define-key ctl-x-5-map "o" #'other-frame)
(define-key ctl-x-5-map "5" #'other-frame-prefix)
+(define-key ctl-x-5-map "c" #'clone-frame)
(define-key global-map [f11] #'toggle-frame-fullscreen)
(define-key global-map [(meta f10)] #'toggle-frame-maximized)
(define-key esc-map [f10] #'toggle-frame-maximized)
diff --git a/lisp/frameset.el b/lisp/frameset.el
index 6aa94f8be5a..998f4fb4ca4 100644
--- a/lisp/frameset.el
+++ b/lisp/frameset.el
@@ -882,7 +882,7 @@ For the description of FORCE-ONSCREEN, see `frameset-restore'.
When forced onscreen, frames wider than the monitor's workarea are converted
to fullwidth, and frames taller than the workarea are converted to fullheight.
NOTE: This only works for non-iconified frames."
- (pcase-let* ((`(,left ,top ,width ,height) (cl-cdadr (frame-monitor-attributes frame)))
+ (pcase-let* ((`(,left ,top ,width ,height) (cdadr (frame-monitor-attributes frame)))
(right (+ left width -1))
(bottom (+ top height -1))
(fr-left (frameset-compute-pos (frame-parameter frame 'left) left right))
@@ -1178,7 +1178,8 @@ FORCE-ONSCREEN can be:
- a list (LEFT TOP WIDTH HEIGHT), describing the workarea.
It must return non-nil to force the frame onscreen, nil otherwise.
-CLEANUP-FRAMES allows \"cleaning up\" the frame list after restoring a frameset:
+CLEANUP-FRAMES allows \"cleaning up\" the frame list after
+restoring a frameset:
t Delete all frames that were not created or restored upon.
nil Keep all frames.
FUNC A function called with two arguments:
diff --git a/lisp/gnus/ChangeLog.2 b/lisp/gnus/ChangeLog.2
index 35402dffd07..26ecaada5e5 100644
--- a/lisp/gnus/ChangeLog.2
+++ b/lisp/gnus/ChangeLog.2
@@ -1759,7 +1759,7 @@
* pgg-gpg.el, pgg-pgp.el, pgg-pgp5.el, pgg.el: Reapply changes
from 2003-04-03 to fix security problem.
- See http://www.debian.org/security/2003/dsa-339.
+ See https://www.debian.org/security/2003/dsa-339.
2003-07-23 Teodor Zlatanov <tzz@lifelogs.com>
diff --git a/lisp/gnus/ChangeLog.3 b/lisp/gnus/ChangeLog.3
index 2aba3a5706f..836cca87ffb 100644
--- a/lisp/gnus/ChangeLog.3
+++ b/lisp/gnus/ChangeLog.3
@@ -655,7 +655,7 @@
2014-05-08 Glenn Morris <rgm@gnu.org>
* gnus-fun.el (gnus-grab-cam-face):
- Do not use predictable temp-file name. (http://bugs.debian.org/747100)
+ Do not use predictable temp-file name. (https://bugs.debian.org/747100)
This is CVE-2014-3421.
2014-05-04 Glenn Morris <rgm@gnu.org>
diff --git a/lisp/gnus/gmm-utils.el b/lisp/gnus/gmm-utils.el
index bcf8dd014bc..68a90989046 100644
--- a/lisp/gnus/gmm-utils.el
+++ b/lisp/gnus/gmm-utils.el
@@ -239,6 +239,7 @@ DEFAULT-MAP specifies the default key map for ICON-LIST."
"Create function NAME.
If FUNCTION exists, then NAME becomes an alias for FUNCTION.
Otherwise, create function NAME with ARG-LIST and BODY."
+ (declare (indent defun))
(let ((defined-p (fboundp function)))
(if defined-p
`(defalias ',name ',function)
diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el
index cbe3505cd10..169a351c2c7 100644
--- a/lisp/gnus/gnus-agent.el
+++ b/lisp/gnus/gnus-agent.el
@@ -161,7 +161,7 @@ enable expiration per categories, topics, and groups."
(defcustom gnus-agent-expire-unagentized-dirs t
"Whether expiration should expire in unagentized directories.
-Have gnus-agent-expire scan the directories under
+Have `gnus-agent-expire' scan the directories under
\(gnus-agent-directory) for groups that are no longer agentized.
When found, offer to remove them."
:version "22.1"
@@ -475,17 +475,16 @@ manipulated as follows:
(gnus-run-hooks 'gnus-agent-mode-hook
(intern (format "gnus-agent-%s-mode-hook" buffer)))))
-(defvar gnus-agent-group-mode-map (make-sparse-keymap))
-(gnus-define-keys gnus-agent-group-mode-map
- "Ju" gnus-agent-fetch-groups
- "Jc" gnus-enter-category-buffer
- "Jj" gnus-agent-toggle-plugged
- "Js" gnus-agent-fetch-session
- "JY" gnus-agent-synchronize-flags
- "JS" gnus-group-send-queue
- "Ja" gnus-agent-add-group
- "Jr" gnus-agent-remove-group
- "Jo" gnus-agent-toggle-group-plugged)
+(defvar-keymap gnus-agent-group-mode-map
+ "J u" #'gnus-agent-fetch-groups
+ "J c" #'gnus-enter-category-buffer
+ "J j" #'gnus-agent-toggle-plugged
+ "J s" #'gnus-agent-fetch-session
+ "J Y" #'gnus-agent-synchronize-flags
+ "J S" #'gnus-group-send-queue
+ "J a" #'gnus-agent-add-group
+ "J r" #'gnus-agent-remove-group
+ "J o" #'gnus-agent-toggle-group-plugged)
(defun gnus-agent-group-make-menu-bar ()
(unless (boundp 'gnus-agent-group-menu)
@@ -504,16 +503,15 @@ manipulated as follows:
["Synchronize flags" gnus-agent-synchronize-flags t]
))))
-(defvar gnus-agent-summary-mode-map (make-sparse-keymap))
-(gnus-define-keys gnus-agent-summary-mode-map
- "Jj" gnus-agent-toggle-plugged
- "Ju" gnus-agent-summary-fetch-group
- "JS" gnus-agent-fetch-group
- "Js" gnus-agent-summary-fetch-series
- "J#" gnus-agent-mark-article
- "J\M-#" gnus-agent-unmark-article
- "@" gnus-agent-toggle-mark
- "Jc" gnus-agent-catchup)
+(defvar-keymap gnus-agent-summary-mode-map
+ "J j" #'gnus-agent-toggle-plugged
+ "J u" #'gnus-agent-summary-fetch-group
+ "J S" #'gnus-agent-fetch-group
+ "J s" #'gnus-agent-summary-fetch-series
+ "J #" #'gnus-agent-mark-article
+ "J M-#" #'gnus-agent-unmark-article
+ "@" #'gnus-agent-toggle-mark
+ "J c" #'gnus-agent-catchup)
(defun gnus-agent-summary-make-menu-bar ()
(unless (boundp 'gnus-agent-summary-menu)
@@ -527,11 +525,10 @@ manipulated as follows:
["Fetch downloadable" gnus-agent-summary-fetch-group t]
["Catchup undownloaded" gnus-agent-catchup t]))))
-(defvar gnus-agent-server-mode-map (make-sparse-keymap))
-(gnus-define-keys gnus-agent-server-mode-map
- "Jj" gnus-agent-toggle-plugged
- "Ja" gnus-agent-add-server
- "Jr" gnus-agent-remove-server)
+(defvar-keymap gnus-agent-server-mode-map
+ "J j" #'gnus-agent-toggle-plugged
+ "J a" #'gnus-agent-add-server
+ "J r" #'gnus-agent-remove-server)
(defun gnus-agent-server-make-menu-bar ()
(unless (boundp 'gnus-agent-server-menu)
@@ -622,7 +619,7 @@ manipulated as follows:
The gnus-agentize function is now called internally by gnus when
gnus-agent is set. If you wish to avoid calling gnus-agentize,
-customize gnus-agent to nil.
+customize `gnus-agent' to nil.
This will modify the `gnus-setup-news-hook', and
`message-send-mail-real-function' variables, and install the Gnus agent
@@ -1323,7 +1320,7 @@ downloaded into the agent."
(gnus-agent-set-local group agent-min (1- active-min)))))))
(defun gnus-agent-save-group-info (method group active)
- "Update a single group's active range in the agent's copy of the server's active file."
+ "Update single group's active range in agent's copy of server's active file."
(when (gnus-agent-method-p method)
(let* ((gnus-command-method (or method gnus-command-method))
(coding-system-for-write nnheader-file-coding-system)
@@ -1356,7 +1353,7 @@ downloaded into the agent."
(delete-char 1)))))))
(defun gnus-agent-get-group-info (method group)
- "Get a single group's active range in the agent's copy of the server's active file."
+ "Get single group's active range in agent's copy of server's active file."
(when (gnus-agent-method-p method)
(let* ((gnus-command-method (or method gnus-command-method))
(coding-system-for-write nnheader-file-coding-system)
@@ -1703,8 +1700,8 @@ and that there are no duplicates."
(defun gnus-agent-flush-server (&optional server-or-method)
"Flush all agent index files for every subscribed group within
- the given SERVER-OR-METHOD. When called with nil, the current
- value of gnus-command-method identifies the server."
+the given SERVER-OR-METHOD. When called with nil, the current
+value of gnus-command-method identifies the server."
(let* ((gnus-command-method (if server-or-method
(gnus-server-to-method server-or-method)
gnus-command-method))
@@ -2153,8 +2150,9 @@ doesn't exist, to valid the overview buffer."
(defvar gnus-agent-file-loading-local nil)
(defun gnus-agent-load-local (&optional method)
- "Load the METHOD'S local file. The local file contains min/max
-article counts for each of the method's subscribed groups."
+ "Load the METHOD'S local file.
+The local file contains min/max article counts for each of the
+method's subscribed groups."
(let ((gnus-command-method (or method gnus-command-method)))
(when (or (null gnus-agent-article-local-times)
(zerop gnus-agent-article-local-times)
@@ -2171,9 +2169,9 @@ article counts for each of the method's subscribed groups."
gnus-agent-article-local))
(defun gnus-agent-read-and-cache-local (file)
- "Load and read FILE then bind its contents to
-gnus-agent-article-local. If that variable had `dirty' (also known as
-modified) original contents, they are first saved to their own file."
+ "Load and read FILE then bind its contents to `gnus-agent-article-local'.
+If that variable had `dirty' (also known as modified) original
+contents, they are first saved to their own file."
(if (and gnus-agent-article-local
(gethash "+dirty" gnus-agent-article-local))
(gnus-agent-save-local))
@@ -2224,7 +2222,7 @@ modified) original contents, they are first saved to their own file."
hashtb))
(defun gnus-agent-save-local (&optional force)
- "Save gnus-agent-article-local under it method's agent.lib directory."
+ "Save `gnus-agent-article-local' under it method's agent.lib directory."
(let ((hashtb gnus-agent-article-local))
(when (and hashtb
(or force (gethash "+dirty" hashtb)))
@@ -2596,25 +2594,20 @@ General format specifiers can also be used. See Info node
(defvar gnus-category-line-format-spec nil)
(defvar gnus-category-mode-line-format-spec nil)
-(defvar gnus-category-mode-map nil)
-
-(unless gnus-category-mode-map
- (setq gnus-category-mode-map (make-sparse-keymap))
- (suppress-keymap gnus-category-mode-map)
-
- (gnus-define-keys gnus-category-mode-map
- "q" gnus-category-exit
- "k" gnus-category-kill
- "c" gnus-category-copy
- "a" gnus-category-add
- "e" gnus-agent-customize-category
- "p" gnus-category-edit-predicate
- "g" gnus-category-edit-groups
- "s" gnus-category-edit-score
- "l" gnus-category-list
-
- "\C-c\C-i" gnus-info-find-node
- "\C-c\C-b" gnus-bug))
+(defvar-keymap gnus-category-mode-map
+ :suppress t
+ "q" #'gnus-category-exit
+ "k" #'gnus-category-kill
+ "c" #'gnus-category-copy
+ "a" #'gnus-category-add
+ "e" #'gnus-agent-customize-category
+ "p" #'gnus-category-edit-predicate
+ "g" #'gnus-category-edit-groups
+ "s" #'gnus-category-edit-score
+ "l" #'gnus-category-list
+
+ "C-c C-i" #'gnus-info-find-node
+ "C-c C-b" #'gnus-bug)
(defcustom gnus-category-menu-hook nil
"Hook run after the creation of the menu."
@@ -3552,32 +3545,13 @@ articles in every agentized group? "))
(when (and to-remove
(or gnus-expert-user
(gnus-y-or-n-p
- "gnus-agent-expire has identified local directories that are\
- not currently required by any agentized group. Do you wish to consider\
- deleting them?")))
- (while to-remove
- (let ((dir (pop to-remove)))
- (if (or gnus-expert-user
+ "gnus-agent-expire has identified local directories that are
+not currently required by any agentized group. Do you wish to consider
+deleting them?")))
+ (dolist (dir to-remove)
+ (when (or gnus-expert-user
(gnus-y-or-n-p (format "Delete %s? " dir)))
- (let* (delete-recursive
- files f
- (delete-recursive
- (lambda (f-or-d)
- (ignore-errors
- (if (file-directory-p f-or-d)
- (condition-case nil
- (delete-directory f-or-d)
- (file-error
- (setq files (directory-files f-or-d))
- (while files
- (setq f (pop files))
- (or (member f '("." ".."))
- (funcall delete-recursive
- (nnheader-concat
- f-or-d f))))
- (delete-directory f-or-d)))
- (delete-file f-or-d))))))
- (funcall delete-recursive dir)))))))))
+ (delete-directory dir t)))))))
;;;###autoload
(defun gnus-agent-batch ()
diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el
index 3c1403e1551..b7701f10a5e 100644
--- a/lisp/gnus/gnus-art.el
+++ b/lisp/gnus/gnus-art.el
@@ -610,17 +610,17 @@ The recommended coding systems are `utf-8', `iso-2022-7bit' and so on,
which can safely encode any characters in text. This is used by the
commands including:
-* gnus-summary-save-article-file
-* gnus-summary-save-article-body-file
-* gnus-summary-write-article-file
-* gnus-summary-write-article-body-file
+* `gnus-summary-save-article-file'
+* `gnus-summary-save-article-body-file'
+* `gnus-summary-write-article-file'
+* `gnus-summary-write-article-body-file'
and the functions to which you may set `gnus-default-article-saver':
-* gnus-summary-save-in-file
-* gnus-summary-save-body-in-file
-* gnus-summary-write-to-file
-* gnus-summary-write-body-to-file
+* `gnus-summary-save-in-file'
+* `gnus-summary-save-body-in-file'
+* `gnus-summary-write-to-file'
+* `gnus-summary-write-body-to-file'
Those commands and functions save just text displayed in the article
buffer to a file if the value of this variable is non-nil. Note that
@@ -768,28 +768,37 @@ Obsolete; use the face `gnus-signature' for customizations instead."
:group 'gnus-article-highlight
:group 'gnus-article-signature)
+(defface gnus-header
+ '((t :inherit variable-pitch-text))
+ "Base face used for all Gnus header faces.
+All the other `gnus-header-' faces inherit from this face."
+ :version "29.1"
+ :group 'gnus-article-headers
+ :group 'gnus-article-highlight)
+
(defface gnus-header-from
'((((class color)
(background dark))
- (:foreground "PaleGreen1"))
+ (:foreground "PaleGreen1" :inherit gnus-header))
(((class color)
(background light))
- (:foreground "red3"))
+ (:foreground "red3" :inherit gnus-header))
(t
- (:italic t)))
+ (:italic t :inherit gnus-header)))
"Face used for displaying from headers."
+ :version "29.1"
:group 'gnus-article-headers
:group 'gnus-article-highlight)
(defface gnus-header-subject
'((((class color)
(background dark))
- (:foreground "SeaGreen1"))
+ (:foreground "SeaGreen1" :inherit gnus-header))
(((class color)
(background light))
- (:foreground "red4"))
+ (:foreground "red4" :inherit gnus-header))
(t
- (:bold t :italic t)))
+ (:bold t :italic t :inherit gnus-header)))
"Face used for displaying subject headers."
:group 'gnus-article-headers
:group 'gnus-article-highlight)
@@ -797,7 +806,7 @@ Obsolete; use the face `gnus-signature' for customizations instead."
(defface gnus-header-newsgroups
'((((class color)
(background dark))
- (:foreground "yellow" :italic t))
+ (:foreground "yellow" :italic t :inherit gnus-header))
(((class color)
(background light))
(:foreground "MidnightBlue" :italic t))
@@ -812,12 +821,12 @@ articles."
(defface gnus-header-name
'((((class color)
(background dark))
- (:foreground "SpringGreen2"))
+ (:foreground "SpringGreen2" :inherit gnus-header))
(((class color)
(background light))
- (:foreground "maroon"))
+ (:foreground "maroon" :inherit gnus-header))
(t
- (:bold t)))
+ (:bold t :inherit gnus-header)))
"Face used for displaying header names."
:group 'gnus-article-headers
:group 'gnus-article-highlight)
@@ -825,12 +834,13 @@ articles."
(defface gnus-header-content
'((((class color)
(background dark))
- (:foreground "SpringGreen1" :italic t))
+ (:foreground "SpringGreen1" :italic t :inherit gnus-header))
(((class color)
(background light))
- (:foreground "indianred4" :italic t))
+ (:foreground "indianred4" :italic t :inherit gnus-header))
(t
- (:italic t))) "Face used for displaying header content."
+ (:italic t :inherit gnus-header)))
+ "Face used for displaying header content."
:group 'gnus-article-headers
:group 'gnus-article-highlight)
@@ -1167,6 +1177,19 @@ predicate. See Info node `(gnus)Customizing Articles'."
:link '(custom-manual "(gnus)Customizing Articles")
:type gnus-article-treat-custom)
+(defcustom gnus-treat-emojize-symbols nil
+ "Display emoji versions of symbol.
+Some symbols have both a non-emoji presentation and an emoji
+presentation. This treatment will make Gnus display the latter
+as emojis even when they weren't sent as such.
+
+Valid values are nil, t, `head', `first', `last', an integer or a
+predicate. See Info node `(gnus)Customizing Articles'."
+ :version "29.1"
+ :group 'gnus-article-treat
+ :link '(custom-manual "(gnus)Customizing Articles")
+ :type gnus-article-treat-custom)
+
(defcustom gnus-treat-unsplit-urls nil
"Remove newlines from within URLs.
Valid values are nil, t, `head', `first', `last', an integer or a
@@ -1360,11 +1383,11 @@ This variable has no effect if `gnus-treat-unfold-headers' is nil."
(const :tag "all" t)
(regexp)))
-(defcustom gnus-treat-fold-headers nil
+(defcustom gnus-treat-fold-headers 'head
"Fold headers.
Valid values are nil, t, `head', `first', `last', an integer or a
predicate. See Info node `(gnus)Customizing Articles'."
- :version "22.1"
+ :version "29.1"
:group 'gnus-article-treat
:link '(custom-manual "(gnus)Customizing Articles")
:type gnus-article-treat-custom)
@@ -1650,6 +1673,7 @@ regexp."
(defvar gnus-article-mime-handle-alist-1 nil)
(defvar gnus-treatment-function-alist
'((gnus-treat-strip-cr gnus-article-remove-cr)
+ (gnus-treat-emojize-symbols gnus-article-emojize-symbols)
(gnus-treat-x-pgp-sig gnus-article-verify-x-pgp-sig)
(gnus-treat-strip-banner gnus-article-strip-banner)
(gnus-treat-strip-headers-in-body gnus-article-strip-headers-in-body)
@@ -2188,6 +2212,14 @@ unfolded."
(replace-match " " t t))))
(goto-char (point-max)))))))
+(defun gnus--variable-pitch-p (face)
+ (when face
+ (or (eq face 'variable-pitch)
+ (let ((parent (face-attribute face :inherit)))
+ (if (eq parent 'unspecified)
+ nil
+ (seq-some #'gnus--variable-pitch-p (ensure-list parent)))))))
+
(defun gnus-article-treat-fold-headers ()
"Fold message headers."
(interactive nil gnus-article-mode gnus-summary-mode)
@@ -2195,7 +2227,10 @@ unfolded."
(while (not (eobp))
(save-restriction
(mail-header-narrow-to-field)
- (mail-header-fold-field)
+ (if (not (gnus--variable-pitch-p (get-text-property (point) 'face)))
+ (mail-header-fold-field)
+ (forward-char 1)
+ (pixel-fill-region (point) (point-max) (pixel-fill-width)))
(goto-char (point-max))))))
(defun gnus-treat-smiley ()
@@ -2243,6 +2278,14 @@ This only works if the article in question is HTML."
(funcall function (get-text-property start 'image-url)
start end)))))))
+(defun gnus-article-toggle-fonts ()
+ "Toggle the use of proportional fonts for HTML articles."
+ (interactive nil gnus-article-mode gnus-summary-mode)
+ (gnus-with-article-buffer
+ (when (eq mm-text-html-renderer 'shr)
+ (setq-local shr-use-fonts (not shr-use-fonts))
+ (gnus-summary-show-article))))
+
(defun gnus-article-treat-fold-newsgroups ()
"Fold the Newsgroups and Followup-To message headers."
(interactive nil gnus-article-mode gnus-summary-mode)
@@ -2352,6 +2395,20 @@ fill width."
(while (search-forward "\r" nil t)
(replace-match "\n" t t)))))
+(defun article-emojize-symbols ()
+ "Display symbols (that have an emoji version) as emojis."
+ (interactive nil gnus-article-mode)
+ (when-let ((font (and (display-multi-font-p)
+ (car (internal-char-font nil ?😀)))))
+ (save-excursion
+ (let ((inhibit-read-only t))
+ (goto-char (point-min))
+ (while (re-search-forward "[[:multibyte:]]" nil t)
+ ;; If there's already a grapheme cluster here, skip it.
+ (when (and (not (find-composition (point)))
+ (font-has-char-p font (char-after (match-beginning 0))))
+ (insert "\N{VARIATION SELECTOR-16}")))))))
+
(defun article-remove-trailing-blank-lines ()
"Remove all trailing blank lines from the article."
(interactive nil gnus-article-mode)
@@ -3925,8 +3982,8 @@ This format is defined by the `gnus-article-time-format' variable."
;; No split name was found.
((null split-name)
(read-file-name
- (concat prompt " (default "
- (file-name-nondirectory default-name) "): ")
+ (format-prompt prompt
+ (file-name-nondirectory default-name))
(file-name-directory default-name)
default-name))
;; A single group name is returned.
@@ -3935,8 +3992,8 @@ This format is defined by the `gnus-article-time-format' variable."
(funcall function split-name headers
(symbol-value variable)))
(read-file-name
- (concat prompt " (default "
- (file-name-nondirectory default-name) "): ")
+ (format-prompt prompt
+ (file-name-nondirectory default-name))
(file-name-directory default-name)
default-name))
;; A single split name was found
@@ -3948,9 +4005,8 @@ This format is defined by the `gnus-article-time-format' variable."
(file-name-as-directory name))
((file-exists-p name) name)
(t gnus-article-save-directory))))
- (read-file-name
- (concat prompt " (default " name "): ")
- dir name)))
+ (read-file-name (format-prompt prompt name)
+ dir name)))
;; A list of splits was found.
(t
(setq split-name (nreverse split-name))
@@ -4271,7 +4327,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is
(insert "Version: " (car items) "\n\n")
(insert (mapconcat #'identity (cddr items) "\n"))
(insert "\n-----END PGP SIGNATURE-----\n")
- (let ((mm-security-handle (list (format "multipart/signed"))))
+ (let ((mm-security-handle (list (substring "multipart/signed"))))
(mml2015-clean-buffer)
(let ((coding-system-for-write (or gnus-newsgroup-charset
'iso-8859-1)))
@@ -4334,6 +4390,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is
article-fill-long-lines
article-capitalize-sentences
article-remove-cr
+ article-emojize-symbols
article-remove-leading-whitespace
article-display-x-face
article-display-face
@@ -4379,44 +4436,44 @@ If variable `gnus-use-long-file-name' is non-nil, it is
;;; Gnus article mode
;;;
-(set-keymap-parent gnus-article-mode-map button-buffer-map)
-
-(gnus-define-keys gnus-article-mode-map
- " " gnus-article-goto-next-page
- [?\S-\ ] gnus-article-goto-prev-page
- "\177" gnus-article-goto-prev-page
- [delete] gnus-article-goto-prev-page
- "\C-c^" gnus-article-refer-article
- "h" gnus-article-show-summary
- "s" gnus-article-show-summary
- "\C-c\C-m" gnus-article-mail
- "?" gnus-article-describe-briefly
- "<" beginning-of-buffer
- ">" end-of-buffer
- "\C-c\C-i" gnus-info-find-node
- "\C-c\C-b" gnus-bug
- "R" gnus-article-reply-with-original
- "F" gnus-article-followup-with-original
- "\C-hk" gnus-article-describe-key
- "\C-hc" gnus-article-describe-key-briefly
- "\C-hb" gnus-article-describe-bindings
-
- "e" gnus-article-read-summary-keys
- "\C-d" gnus-article-read-summary-keys
- "\C-c\C-f" gnus-summary-mail-forward
- "\M-*" gnus-article-read-summary-keys
- "\M-#" gnus-article-read-summary-keys
- "\M-^" gnus-article-read-summary-keys
- "\M-g" gnus-article-read-summary-keys)
+(defvar gnus-article-send-map nil)
+
+(define-keymap :keymap gnus-article-mode-map :suppress t
+ :parent button-buffer-map
+ "SPC" #'gnus-article-goto-next-page
+ "S-SPC" #'gnus-article-goto-prev-page
+ "DEL" #'gnus-article-goto-prev-page
+ "<delete>" #'gnus-article-goto-prev-page
+ "C-c ^" #'gnus-article-refer-article
+ "h" #'gnus-article-show-summary
+ "s" #'gnus-article-show-summary
+ "C-c C-m" #'gnus-article-mail
+ "?" #'gnus-article-describe-briefly
+ "<" #'beginning-of-buffer
+ ">" #'end-of-buffer
+ "C-c C-i" #'gnus-info-find-node
+ "C-c C-b" #'gnus-bug
+ "R" #'gnus-article-reply-with-original
+ "F" #'gnus-article-followup-with-original
+ "C-h k" #'gnus-article-describe-key
+ "C-h c" #'gnus-article-describe-key-briefly
+ "C-h b" #'gnus-article-describe-bindings
+
+ "e" #'gnus-article-read-summary-keys
+ "C-d" #'gnus-article-read-summary-keys
+ "C-c C-f" #'gnus-summary-mail-forward
+ "M-*" #'gnus-article-read-summary-keys
+ "M-#" #'gnus-article-read-summary-keys
+ "M-^" #'gnus-article-read-summary-keys
+ "M-g" #'gnus-article-read-summary-keys
+
+ "S" (define-keymap :prefix 'gnus-article-send-map
+ "W" #'gnus-article-wide-reply-with-original
+ "<t>" #'gnus-article-read-summary-send-keys))
(substitute-key-definition
#'undefined #'gnus-article-read-summary-keys gnus-article-mode-map)
-(defvar gnus-article-send-map)
-(gnus-define-keys (gnus-article-send-map "S" gnus-article-mode-map)
- "W" gnus-article-wide-reply-with-original
- [t] gnus-article-read-summary-send-keys)
-
(defun gnus-article-make-menu-bar ()
(unless (boundp 'gnus-article-commands-menu)
(gnus-summary-make-menu-bar))
@@ -4441,6 +4498,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is
["Treat overstrike" gnus-article-treat-overstrike t]
["Treat ANSI sequences" gnus-article-treat-ansi-sequences t]
["Remove carriage return" gnus-article-remove-cr t]
+ ["Emojize Symbols" gnus-article-emojize-symbols t]
["Remove leading whitespace" gnus-article-remove-leading-whitespace t]
["Remove quoted-unreadable" gnus-article-de-quoted-unreadable t]
["Remove base64" gnus-article-de-base64-unreadable t]
@@ -4499,6 +4557,10 @@ commands:
(gnus-set-default-directory)
(buffer-disable-undo)
(setq show-trailing-whitespace nil)
+ ;; Arrange a callback from `mm-inline-message' if we're
+ ;; displaying a message/rfc822 part.
+ (setq-local mm-inline-message-prepare-function
+ #'gnus-mime--inline-message-function)
(mm-enable-multibyte))
(defun gnus-article-setup-buffer ()
@@ -4538,7 +4600,6 @@ commands:
(let ((summary gnus-summary-buffer))
(with-current-buffer name
(setq-local gnus-article-edit-mode nil)
- (gnus-article-stop-animations)
(when gnus-article-mime-handles
(mm-destroy-parts gnus-article-mime-handles)
(setq gnus-article-mime-handles nil))
@@ -4564,6 +4625,7 @@ commands:
(current-buffer))))))
(defun gnus-article-stop-animations ()
+ (declare (obsolete nil "29.1"))
(cancel-function-timers 'image-animate-timeout))
(defun gnus-stop-downloads ()
@@ -6034,31 +6096,29 @@ If nil, don't show those extra buttons."
(defun gnus-mime-display-mixed (handles)
(mapcar #'gnus-mime-display-part handles))
+(defun gnus-mime--inline-message-function (handle charset)
+ (let ((handles
+ (let (gnus-article-mime-handles
+ ;; disable prepare hook
+ gnus-article-prepare-hook
+ (gnus-newsgroup-charset
+ ;; mm-uu might set it.
+ (unless (eq charset 'gnus-decoded)
+ (or charset gnus-newsgroup-charset))))
+ (let ((gnus-original-article-buffer
+ (mm-handle-buffer handle)))
+ (run-hooks 'gnus-article-decode-hook))
+ (gnus-article-prepare-display)
+ gnus-article-mime-handles)))
+ (when handles
+ (setq gnus-article-mime-handles
+ (mm-merge-handles gnus-article-mime-handles handles)))))
+
(defun gnus-mime-display-single (handle)
(let ((type (mm-handle-media-type handle))
(ignored gnus-ignored-mime-types)
(mm-inline-font-lock (gnus-visual-p 'article-highlight 'highlight))
(not-attachment t)
- ;; Arrange a callback from `mm-inline-message' if we're
- ;; displaying a message/rfc822 part.
- (mm-inline-message-prepare-function
- (lambda (charset)
- (let ((handles
- (let (gnus-article-mime-handles
- ;; disable prepare hook
- gnus-article-prepare-hook
- (gnus-newsgroup-charset
- ;; mm-uu might set it.
- (unless (eq charset 'gnus-decoded)
- (or charset gnus-newsgroup-charset))))
- (let ((gnus-original-article-buffer
- (mm-handle-buffer handle)))
- (run-hooks 'gnus-article-decode-hook))
- (gnus-article-prepare-display)
- gnus-article-mime-handles)))
- (when handles
- (setq gnus-article-mime-handles
- (mm-merge-handles gnus-article-mime-handles handles))))))
display text
gnus-displaying-mime)
(catch 'ignored
@@ -6858,7 +6918,9 @@ KEY is a string or a vector."
unread-command-events))
(let ((cursor-in-echo-area t)
gnus-pick-mode)
- (describe-key (read-key-sequence nil t))))
+ (describe-key (list (cons (read-key-sequence nil t)
+ (this-single-command-raw-keys)))
+ (current-buffer))))
(describe-key key)))
(defun gnus-article-describe-key-briefly (key &optional insert)
@@ -6881,7 +6943,9 @@ KEY is a string or a vector."
unread-command-events))
(let ((cursor-in-echo-area t)
gnus-pick-mode)
- (describe-key-briefly (read-key-sequence nil t) insert)))
+ (describe-key-briefly (list (cons (read-key-sequence nil t)
+ (this-single-command-raw-keys)))
+ insert (current-buffer))))
(describe-key-briefly key insert)))
;;`gnus-agent-mode' in gnus-agent.el will define it.
@@ -7209,50 +7273,42 @@ other groups."
(defvar gnus-article-edit-done-function nil)
-(defvar gnus-article-edit-mode-map nil)
-
-;; Should we be using derived.el for this?
-(unless gnus-article-edit-mode-map
- (setq gnus-article-edit-mode-map (make-keymap))
- (set-keymap-parent gnus-article-edit-mode-map text-mode-map)
-
- (gnus-define-keys gnus-article-edit-mode-map
- "\C-c?" describe-mode
- "\C-c\C-c" gnus-article-edit-done
- "\C-c\C-k" gnus-article-edit-exit
- "\C-c\C-f\C-t" message-goto-to
- "\C-c\C-f\C-o" message-goto-from
- "\C-c\C-f\C-b" message-goto-bcc
- ;;"\C-c\C-f\C-w" message-goto-fcc
- "\C-c\C-f\C-c" message-goto-cc
- "\C-c\C-f\C-s" message-goto-subject
- "\C-c\C-f\C-r" message-goto-reply-to
- "\C-c\C-f\C-n" message-goto-newsgroups
- "\C-c\C-f\C-d" message-goto-distribution
- "\C-c\C-f\C-f" message-goto-followup-to
- "\C-c\C-f\C-m" message-goto-mail-followup-to
- "\C-c\C-f\C-k" message-goto-keywords
- "\C-c\C-f\C-u" message-goto-summary
- "\C-c\C-f\C-i" message-insert-or-toggle-importance
- "\C-c\C-f\C-a" message-generate-unsubscribed-mail-followup-to
- "\C-c\C-b" message-goto-body
- "\C-c\C-i" message-goto-signature
-
- "\C-c\C-t" message-insert-to
- "\C-c\C-n" message-insert-newsgroups
- "\C-c\C-o" message-sort-headers
- "\C-c\C-e" message-elide-region
- "\C-c\C-v" message-delete-not-region
- "\C-c\C-z" message-kill-to-signature
- "\M-\r" message-newline-and-reformat
- "\C-c\C-a" mml-attach-file
- "\C-a" message-beginning-of-line
- "\t" message-tab
- "\M-;" comment-region)
-
- (gnus-define-keys (gnus-article-edit-wash-map
- "\C-c\C-w" gnus-article-edit-mode-map)
- "f" gnus-article-edit-full-stops))
+(defvar-keymap gnus-article-edit-mode-map
+ :full t :parent text-mode-map
+ "C-c ?" #'describe-mode
+ "C-c C-c" #'gnus-article-edit-done
+ "C-c C-k" #'gnus-article-edit-exit
+ "C-c C-f C-t" #'message-goto-to
+ "C-c C-f C-o" #'message-goto-from
+ "C-c C-f C-b" #'message-goto-bcc
+ "C-c C-f C-c" #'message-goto-cc
+ "C-c C-f C-s" #'message-goto-subject
+ "C-c C-f C-r" #'message-goto-reply-to
+ "C-c C-f C-n" #'message-goto-newsgroups
+ "C-c C-f C-d" #'message-goto-distribution
+ "C-c C-f C-f" #'message-goto-followup-to
+ "C-c C-f RET" #'message-goto-mail-followup-to
+ "C-c C-f C-k" #'message-goto-keywords
+ "C-c C-f C-u" #'message-goto-summary
+ "C-c C-f TAB" #'message-insert-or-toggle-importance
+ "C-c C-f C-a" #'message-generate-unsubscribed-mail-followup-to
+ "C-c C-b" #'message-goto-body
+ "C-c TAB" #'message-goto-signature
+
+ "C-c C-t" #'message-insert-to
+ "C-c C-n" #'message-insert-newsgroups
+ "C-c C-o" #'message-sort-headers
+ "C-c C-e" #'message-elide-region
+ "C-c C-v" #'message-delete-not-region
+ "C-c C-z" #'message-kill-to-signature
+ "M-RET" #'message-newline-and-reformat
+ "C-c C-a" #'mml-attach-file
+ "C-a" #'message-beginning-of-line
+ "TAB" #'message-tab
+ "M-;" #'comment-region
+
+ "C-c C-w" (define-keymap :prefix 'gnus-article-edit-wash-map
+ "f" #'gnus-article-edit-full-stops))
(easy-menu-define
gnus-article-edit-mode-field-menu gnus-article-edit-mode-map ""
@@ -8511,8 +8567,7 @@ whose names match REGEXP.
For example:
\((\"chinese\" . gnus-decode-encoded-word-region-by-guess)
mail-decode-encoded-word-region
- (\"chinese\" . rfc1843-decode-region))
-")
+ (\"chinese\" . rfc1843-decode-region))")
(defvar gnus-decode-header-methods-cache nil)
diff --git a/lisp/gnus/gnus-bookmark.el b/lisp/gnus/gnus-bookmark.el
index 8c2a928ab98..e9696b66a9f 100644
--- a/lisp/gnus/gnus-bookmark.el
+++ b/lisp/gnus/gnus-bookmark.el
@@ -198,7 +198,9 @@ So the cdr of each bookmark is an alist too.")
(defun gnus-bookmark-make-record
(group message-id author date subject annotation)
- "Return the record part of a new bookmark, given GROUP MESSAGE-ID AUTHOR DATE SUBJECT and ANNOTATION."
+ "Return the record part of a new bookmark.
+Arguments GROUP MESSAGE-ID AUTHOR DATE SUBJECT and ANNOTATION
+will be saved in the bookmark."
(let ((the-record
`((group . ,(substring-no-properties group))
(message-id . ,(substring-no-properties message-id))
@@ -416,32 +418,29 @@ That is, all information but the name."
(defvar gnus-bookmark-bmenu-bookmark-column nil)
(defvar gnus-bookmark-bmenu-hidden-bookmarks ())
-(defvar gnus-bookmark-bmenu-mode-map nil)
-
-(if gnus-bookmark-bmenu-mode-map
- nil
- (setq gnus-bookmark-bmenu-mode-map (make-keymap))
- (suppress-keymap gnus-bookmark-bmenu-mode-map t)
- (define-key gnus-bookmark-bmenu-mode-map "q" 'quit-window)
- (define-key gnus-bookmark-bmenu-mode-map "\C-m" 'gnus-bookmark-bmenu-select)
- (define-key gnus-bookmark-bmenu-mode-map "v" 'gnus-bookmark-bmenu-select)
- (define-key gnus-bookmark-bmenu-mode-map "d" 'gnus-bookmark-bmenu-delete)
- (define-key gnus-bookmark-bmenu-mode-map "k" 'gnus-bookmark-bmenu-delete)
- (define-key gnus-bookmark-bmenu-mode-map "\C-d" 'gnus-bookmark-bmenu-delete-backwards)
- (define-key gnus-bookmark-bmenu-mode-map "x" 'gnus-bookmark-bmenu-execute-deletions)
- (define-key gnus-bookmark-bmenu-mode-map " " 'next-line)
- (define-key gnus-bookmark-bmenu-mode-map "n" 'next-line)
- (define-key gnus-bookmark-bmenu-mode-map "p" 'previous-line)
- (define-key gnus-bookmark-bmenu-mode-map "\177" 'gnus-bookmark-bmenu-backup-unmark)
- (define-key gnus-bookmark-bmenu-mode-map "?" 'describe-mode)
- (define-key gnus-bookmark-bmenu-mode-map "u" 'gnus-bookmark-bmenu-unmark)
- (define-key gnus-bookmark-bmenu-mode-map "m" 'gnus-bookmark-bmenu-mark)
- (define-key gnus-bookmark-bmenu-mode-map "l" 'gnus-bookmark-bmenu-load)
- (define-key gnus-bookmark-bmenu-mode-map "s" 'gnus-bookmark-bmenu-save)
- (define-key gnus-bookmark-bmenu-mode-map "t" 'gnus-bookmark-bmenu-toggle-infos)
- (define-key gnus-bookmark-bmenu-mode-map "a" 'gnus-bookmark-bmenu-show-details)
- (define-key gnus-bookmark-bmenu-mode-map [mouse-2]
- 'gnus-bookmark-bmenu-select-by-mouse))
+
+(defvar-keymap gnus-bookmark-bmenu-mode-map
+ :full t
+ :suppress 'nodigits
+ "q" #'quit-window
+ "RET" #'gnus-bookmark-bmenu-select
+ "v" #'gnus-bookmark-bmenu-select
+ "d" #'gnus-bookmark-bmenu-delete
+ "k" #'gnus-bookmark-bmenu-delete
+ "C-d" #'gnus-bookmark-bmenu-delete-backwards
+ "x" #'gnus-bookmark-bmenu-execute-deletions
+ "SPC" #'next-line
+ "n" #'next-line
+ "p" #'previous-line
+ "DEL" #'gnus-bookmark-bmenu-backup-unmark
+ "?" #'describe-mode
+ "u" #'gnus-bookmark-bmenu-unmark
+ "m" #'gnus-bookmark-bmenu-mark
+ "l" #'gnus-bookmark-bmenu-load
+ "s" #'gnus-bookmark-bmenu-save
+ "t" #'gnus-bookmark-bmenu-toggle-infos
+ "a" #'gnus-bookmark-bmenu-show-details
+ "<mouse-2>" #'gnus-bookmark-bmenu-select-by-mouse)
;; Bookmark Buffer Menu mode is suitable only for specially formatted
;; data.
diff --git a/lisp/gnus/gnus-cite.el b/lisp/gnus/gnus-cite.el
index 34947cece89..e9c912109e2 100644
--- a/lisp/gnus/gnus-cite.el
+++ b/lisp/gnus/gnus-cite.el
@@ -839,7 +839,7 @@ See also the documentation for `gnus-article-highlight-citation'."
(setq current (car loop)
loop (cdr loop))
(setcdr current
- (seq-difference (cdr current) numbers #'eq)))))))))
+ (gnus-set-difference (cdr current) numbers)))))))))
(defun gnus-cite-parse-attributions ()
(let (al-alist)
@@ -999,7 +999,7 @@ See also the documentation for `gnus-article-highlight-citation'."
loop (cdr loop))
(if (eq current best)
()
- (setcdr current (seq-difference (cdr current) numbers #'eq))
+ (setcdr current (gnus-set-difference (cdr current) numbers))
(when (null (cdr current))
(setq gnus-cite-loose-prefix-alist
(delq current gnus-cite-loose-prefix-alist)
diff --git a/lisp/gnus/gnus-diary.el b/lisp/gnus/gnus-diary.el
index e2cbca9007d..7ecc97262a0 100644
--- a/lisp/gnus/gnus-diary.el
+++ b/lisp/gnus/gnus-diary.el
@@ -21,15 +21,11 @@
;; 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:
;; Contents management by FCM version 0.1.
-;; Description:
-;; ===========
-
-;; gnus-diary is a utility toolkit used on top of the nndiary back end. It is
+;; gnus-diary is a utility toolkit used on top of the nndiary back end. It is
;; now fully documented in the Gnus manual.
;;; Code:
diff --git a/lisp/gnus/gnus-dired.el b/lisp/gnus/gnus-dired.el
index af0b782202a..00769a5da6e 100644
--- a/lisp/gnus/gnus-dired.el
+++ b/lisp/gnus/gnus-dired.el
@@ -53,12 +53,10 @@
(autoload 'message-buffers "message")
(autoload 'gnus-print-buffer "gnus-sum")
-(defvar gnus-dired-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\C-c\C-m\C-a" 'gnus-dired-attach)
- (define-key map "\C-c\C-m\C-l" 'gnus-dired-find-file-mailcap)
- (define-key map "\C-c\C-m\C-p" 'gnus-dired-print)
- map))
+(defvar-keymap gnus-dired-mode-map
+ "C-c C-m C-a" #'gnus-dired-attach
+ "C-c C-m C-l" #'gnus-dired-find-file-mailcap
+ "C-c C-m C-p" #'gnus-dired-print)
;; FIXME: Make it customizable, change the default to `mail-user-agent' when
;; this file is renamed (e.g. to `dired-mime.el').
@@ -92,7 +90,7 @@ See `mail-user-agent' for more information."
;;;###autoload
(defun turn-on-gnus-dired-mode ()
- "Convenience method to turn on gnus-dired-mode."
+ "Convenience method to turn on `gnus-dired-mode'."
(interactive)
(gnus-dired-mode 1))
@@ -206,7 +204,8 @@ If ARG is non-nil, open it in a new buffer."
(find-file file-name)))
(if (file-symlink-p file-name)
(error "File is a symlink to a nonexistent target")
- (error "File no longer exists; type `g' to update Dired buffer"))))
+ (error (substitute-command-keys
+ "File no longer exists; type \\`g' to update Dired buffer")))))
(defun gnus-dired-print (&optional file-name print-to)
"In dired, print FILE-NAME according to the mailcap file.
@@ -246,9 +245,10 @@ of the file to save in."
(error "MIME print only implemented via Gnus")))
(ps-despool print-to))))
((file-symlink-p file-name)
- (error "File is a symlink to a nonexistent target"))
- (t
- (error "File no longer exists; type `g' to update Dired buffer"))))
+ (error "File is a symlink to a nonexistent target"))
+ (t
+ (error (substitute-command-keys
+ "File no longer exists; type \\`g' to update Dired buffer")))))
(provide 'gnus-dired)
diff --git a/lisp/gnus/gnus-draft.el b/lisp/gnus/gnus-draft.el
index 9a0f21359f8..7c56db0ba45 100644
--- a/lisp/gnus/gnus-draft.el
+++ b/lisp/gnus/gnus-draft.el
@@ -33,15 +33,12 @@
;;; Draft minor mode
-(defvar gnus-draft-mode-map
- (let ((map (make-sparse-keymap)))
- (gnus-define-keys map
- "Dt" gnus-draft-toggle-sending
- "e" gnus-draft-edit-message ;; Use `B w' for `gnus-summary-edit-article'
- "De" gnus-draft-edit-message
- "Ds" gnus-draft-send-message
- "DS" gnus-draft-send-all-messages)
- map))
+(defvar-keymap gnus-draft-mode-map
+ "D t" #'gnus-draft-toggle-sending
+ "e" #' gnus-draft-edit-message ;; Use `B w' for `gnus-summary-edit-article'
+ "D e" #'gnus-draft-edit-message
+ "D s" #'gnus-draft-send-message
+ "D S" #'gnus-draft-send-all-messages)
(defun gnus-draft-make-menu-bar ()
(unless (boundp 'gnus-draft-menu)
diff --git a/lisp/gnus/gnus-eform.el b/lisp/gnus/gnus-eform.el
index 3fd8bf51de4..c727926731b 100644
--- a/lisp/gnus/gnus-eform.el
+++ b/lisp/gnus/gnus-eform.el
@@ -48,13 +48,10 @@
(defvar gnus-edit-form-buffer "*Gnus edit form*")
(defvar gnus-edit-form-done-function nil)
-(defvar gnus-edit-form-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map emacs-lisp-mode-map)
- (gnus-define-keys map
- "\C-c\C-c" gnus-edit-form-done
- "\C-c\C-k" gnus-edit-form-exit)
- map))
+(defvar-keymap gnus-edit-form-mode-map
+ :parent emacs-lisp-mode-map
+ "C-c C-c" #'gnus-edit-form-done
+ "C-c C-k" #'gnus-edit-form-exit)
(defun gnus-edit-form-make-menu-bar ()
(unless (boundp 'gnus-edit-form-menu)
diff --git a/lisp/gnus/gnus-fun.el b/lisp/gnus/gnus-fun.el
index 8bca4ffe38f..0754d7aa7b8 100644
--- a/lisp/gnus/gnus-fun.el
+++ b/lisp/gnus/gnus-fun.el
@@ -97,13 +97,14 @@ PNG format."
;;;###autoload
(defun gnus--random-face-with-type (dir ext omit fun)
- "Return file from DIR with extension EXT, omitting matches of OMIT, processed by FUN."
+ "Return file from DIR with extension EXT.
+Omit matches of OMIT, and process them by FUN."
(when (file-exists-p dir)
(let* ((files
(remove nil (mapcar
(lambda (f) (unless (string-match (or omit "^$") f) f))
(directory-files dir t ext))))
- (file (nth (random (length files)) files)))
+ (file (and files (seq-random-elt files))))
(when file
(funcall fun file)))))
@@ -315,7 +316,7 @@ colors of the displayed X-Faces."
(let* ((possibilities '("%02x0000" "00%02x00" "0000%02x"
"%02x%02x00" "00%02x%02x" "%02x00%02x"))
(format (concat "'#%02x%02x%02x' '#"
- (nth (random 6) possibilities)
+ (seq-random-elt possibilities)
"'"))
(values nil))
(dotimes (i 255)
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el
index b1134397e55..2ec001faee7 100644
--- a/lisp/gnus/gnus-group.el
+++ b/lisp/gnus/gnus-group.el
@@ -62,7 +62,7 @@
(defcustom gnus-keep-same-level nil
"Non-nil means that the newsgroup after this one will be on the same level.
-When you type, for instance, `n' after reading the last article in the
+When you type, for instance, \\`n' after reading the last article in the
current newsgroup, you will go to the next newsgroup. If this variable
is nil, the next newsgroup will be the next from the group
buffer.
@@ -118,7 +118,9 @@ If nil, only list groups that have unread articles."
(defcustom gnus-group-default-list-level gnus-level-subscribed
"Default listing level.
-Ignored if `gnus-group-use-permanent-levels' is non-nil."
+When `gnus-group-use-permanent-levels' is non-nil, this level is
+used as the starting level until the user sets a different level,
+and is ignored afterwards."
:group 'gnus-group-listing
:type '(choice (integer :tag "Level")
(function :tag "Function returning level")))
@@ -571,209 +573,209 @@ simple manner."
;;; Gnus group mode
;;;
-(gnus-define-keys gnus-group-mode-map
- " " gnus-group-read-group
- "=" gnus-group-select-group
- "\r" gnus-group-select-group
- "\M-\r" gnus-group-quick-select-group
- "\M- " gnus-group-visible-select-group
- [(meta control return)] gnus-group-select-group-ephemerally
- "j" gnus-group-jump-to-group
- "n" gnus-group-next-unread-group
- "p" gnus-group-prev-unread-group
- "\177" gnus-group-prev-unread-group
- [delete] gnus-group-prev-unread-group
- "N" gnus-group-next-group
- "P" gnus-group-prev-group
- "\M-n" gnus-group-next-unread-group-same-level
- "\M-p" gnus-group-prev-unread-group-same-level
- "," gnus-group-best-unread-group
- "." gnus-group-first-unread-group
- "u" gnus-group-toggle-subscription-at-point
- "U" gnus-group-toggle-subscription
- "c" gnus-group-catchup-current
- "C" gnus-group-catchup-current-all
- "\M-c" gnus-group-clear-data
- "l" gnus-group-list-groups
- "L" gnus-group-list-all-groups
- "m" gnus-group-mail
- "i" gnus-group-news
- "g" gnus-group-get-new-news
- "\M-g" gnus-group-get-new-news-this-group
- "R" gnus-group-restart
- "r" gnus-group-read-init-file
- "B" gnus-group-browse-foreign-server
- "b" gnus-group-check-bogus-groups
- "F" gnus-group-find-new-groups
- "\C-c\C-d" gnus-group-describe-group
- "\M-d" gnus-group-describe-all-groups
- "\C-c\C-a" gnus-group-apropos
- "\C-c\M-\C-a" gnus-group-description-apropos
- "a" gnus-group-post-news
- "\ek" gnus-group-edit-local-kill
- "\eK" gnus-group-edit-global-kill
- "\C-k" gnus-group-kill-group
- "\C-y" gnus-group-yank-group
- "\C-w" gnus-group-kill-region
- "\C-x\C-t" gnus-group-transpose-groups
- "\C-c\C-l" gnus-group-list-killed
- "\C-c\C-x" gnus-group-expire-articles
- "\C-c\M-\C-x" gnus-group-expire-all-groups
- "V" gnus-version
- "s" gnus-group-save-newsrc
- "z" gnus-group-suspend
- "q" gnus-group-exit
- "Q" gnus-group-quit
- "?" gnus-group-describe-briefly
- "\C-c\C-i" gnus-info-find-node
- "\M-e" gnus-group-edit-group-method
- "^" gnus-group-enter-server-mode
- [mouse-2] gnus-mouse-pick-group
- [follow-link] mouse-face
- "<" beginning-of-buffer
- ">" end-of-buffer
- "\C-c\C-b" gnus-bug
- "\C-c\C-s" gnus-group-sort-groups
- "t" gnus-topic-mode
- "\C-c\M-g" gnus-activate-all-groups
- "\M-&" gnus-group-universal-argument
- "#" gnus-group-mark-group
- "\M-#" gnus-group-unmark-group)
-
-(gnus-define-keys (gnus-group-cloud-map "~" gnus-group-mode-map)
- "u" gnus-cloud-upload-all-data
- "~" gnus-cloud-upload-all-data
- "d" gnus-cloud-download-all-data
- "\r" gnus-cloud-download-all-data)
-
-(gnus-define-keys (gnus-group-mark-map "M" gnus-group-mode-map)
- "m" gnus-group-mark-group
- "u" gnus-group-unmark-group
- "w" gnus-group-mark-region
- "b" gnus-group-mark-buffer
- "r" gnus-group-mark-regexp
- "U" gnus-group-unmark-all-groups)
-
-(gnus-define-keys (gnus-group-sieve-map "D" gnus-group-mode-map)
- "u" gnus-sieve-update
- "g" gnus-sieve-generate)
-
-(gnus-define-keys (gnus-group-group-map "G" gnus-group-mode-map)
- "d" gnus-group-make-directory-group
- "h" gnus-group-make-help-group
- "u" gnus-group-make-useful-group
- "l" gnus-group-nnimap-edit-acl
- "m" gnus-group-make-group
- "E" gnus-group-edit-group
- "e" gnus-group-edit-group-method
- "p" gnus-group-edit-group-parameters
- "v" gnus-group-add-to-virtual
- "V" gnus-group-make-empty-virtual
- "D" gnus-group-enter-directory
- "f" gnus-group-make-doc-group
- "w" gnus-group-make-web-group
- "G" gnus-group-read-ephemeral-search-group
- "g" gnus-group-make-search-group
- "M" gnus-group-read-ephemeral-group
- "r" gnus-group-rename-group
- "R" gnus-group-make-rss-group
- "c" gnus-group-customize
- "z" gnus-group-compact-group
- "x" gnus-group-expunge-group
- "\177" gnus-group-delete-group
- [delete] gnus-group-delete-group)
-
-(gnus-define-keys (gnus-group-sort-map "S" gnus-group-group-map)
- "s" gnus-group-sort-groups
- "a" gnus-group-sort-groups-by-alphabet
- "u" gnus-group-sort-groups-by-unread
- "l" gnus-group-sort-groups-by-level
- "v" gnus-group-sort-groups-by-score
- "r" gnus-group-sort-groups-by-rank
- "m" gnus-group-sort-groups-by-method
- "n" gnus-group-sort-groups-by-real-name)
-
-(gnus-define-keys (gnus-group-sort-selected-map "P" gnus-group-group-map)
- "s" gnus-group-sort-selected-groups
- "a" gnus-group-sort-selected-groups-by-alphabet
- "u" gnus-group-sort-selected-groups-by-unread
- "l" gnus-group-sort-selected-groups-by-level
- "v" gnus-group-sort-selected-groups-by-score
- "r" gnus-group-sort-selected-groups-by-rank
- "m" gnus-group-sort-selected-groups-by-method
- "n" gnus-group-sort-selected-groups-by-real-name)
-
-(gnus-define-keys (gnus-group-list-map "A" gnus-group-mode-map)
- "k" gnus-group-list-killed
- "z" gnus-group-list-zombies
- "s" gnus-group-list-groups
- "u" gnus-group-list-all-groups
- "A" gnus-group-list-active
- "a" gnus-group-apropos
- "d" gnus-group-description-apropos
- "m" gnus-group-list-matching
- "M" gnus-group-list-all-matching
- "l" gnus-group-list-level
- "c" gnus-group-list-cached
- "?" gnus-group-list-dormant
- "!" gnus-group-list-ticked)
-
-(gnus-define-keys (gnus-group-list-limit-map "/" gnus-group-list-map)
- "k" gnus-group-list-limit
- "z" gnus-group-list-limit
- "s" gnus-group-list-limit
- "u" gnus-group-list-limit
- "A" gnus-group-list-limit
- "m" gnus-group-list-limit
- "M" gnus-group-list-limit
- "l" gnus-group-list-limit
- "c" gnus-group-list-limit
- "?" gnus-group-list-limit
- "!" gnus-group-list-limit)
-
-(gnus-define-keys (gnus-group-list-flush-map "f" gnus-group-list-map)
- "k" gnus-group-list-flush
- "z" gnus-group-list-flush
- "s" gnus-group-list-flush
- "u" gnus-group-list-flush
- "A" gnus-group-list-flush
- "m" gnus-group-list-flush
- "M" gnus-group-list-flush
- "l" gnus-group-list-flush
- "c" gnus-group-list-flush
- "?" gnus-group-list-flush
- "!" gnus-group-list-flush)
-
-(gnus-define-keys (gnus-group-list-plus-map "p" gnus-group-list-map)
- "k" gnus-group-list-plus
- "z" gnus-group-list-plus
- "s" gnus-group-list-plus
- "u" gnus-group-list-plus
- "A" gnus-group-list-plus
- "m" gnus-group-list-plus
- "M" gnus-group-list-plus
- "l" gnus-group-list-plus
- "c" gnus-group-list-plus
- "?" gnus-group-list-plus
- "!" gnus-group-list-plus)
-
-(gnus-define-keys (gnus-group-score-map "W" gnus-group-mode-map)
- "f" gnus-score-flush-cache
- "e" gnus-score-edit-all-score)
-
-(gnus-define-keys (gnus-group-help-map "H" gnus-group-mode-map)
- "d" gnus-group-describe-group
- "v" gnus-version)
-
-(gnus-define-keys (gnus-group-sub-map "S" gnus-group-mode-map)
- "l" gnus-group-set-current-level
- "t" gnus-group-toggle-subscription-at-point
- "s" gnus-group-toggle-subscription
- "k" gnus-group-kill-group
- "y" gnus-group-yank-group
- "w" gnus-group-kill-region
- "\C-k" gnus-group-kill-level
- "z" gnus-group-kill-all-zombies)
+(define-keymap :keymap gnus-group-mode-map
+ "SPC" #'gnus-group-read-group
+ "=" #'gnus-group-select-group
+ "RET" #'gnus-group-select-group
+ "M-RET" #'gnus-group-quick-select-group
+ "M-SPC" #'gnus-group-visible-select-group
+ "C-M-<return>" #'gnus-group-select-group-ephemerally
+ "j" #'gnus-group-jump-to-group
+ "n" #'gnus-group-next-unread-group
+ "p" #'gnus-group-prev-unread-group
+ "DEL" #'gnus-group-prev-unread-group
+ "<delete>" #'gnus-group-prev-unread-group
+ "N" #'gnus-group-next-group
+ "P" #'gnus-group-prev-group
+ "M-n" #'gnus-group-next-unread-group-same-level
+ "M-p" #'gnus-group-prev-unread-group-same-level
+ "," #'gnus-group-best-unread-group
+ "." #'gnus-group-first-unread-group
+ "u" #'gnus-group-toggle-subscription-at-point
+ "U" #'gnus-group-toggle-subscription
+ "c" #'gnus-group-catchup-current
+ "C" #'gnus-group-catchup-current-all
+ "M-c" #'gnus-group-clear-data
+ "l" #'gnus-group-list-groups
+ "L" #'gnus-group-list-all-groups
+ "m" #'gnus-group-mail
+ "i" #'gnus-group-news
+ "g" #'gnus-group-get-new-news
+ "M-g" #'gnus-group-get-new-news-this-group
+ "R" #'gnus-group-restart
+ "r" #'gnus-group-read-init-file
+ "B" #'gnus-group-browse-foreign-server
+ "b" #'gnus-group-check-bogus-groups
+ "F" #'gnus-group-find-new-groups
+ "C-c C-d" #'gnus-group-describe-group
+ "M-d" #'gnus-group-describe-all-groups
+ "C-c C-a" #'gnus-group-apropos
+ "C-c C-M-a" #'gnus-group-description-apropos
+ "a" #'gnus-group-post-news
+ "ESC k" #'gnus-group-edit-local-kill
+ "ESC K" #'gnus-group-edit-global-kill
+ "C-k" #'gnus-group-kill-group
+ "C-y" #'gnus-group-yank-group
+ "C-w" #'gnus-group-kill-region
+ "C-x C-t" #'gnus-group-transpose-groups
+ "C-c C-l" #'gnus-group-list-killed
+ "C-c C-x" #'gnus-group-expire-articles
+ "C-c C-M-x" #'gnus-group-expire-all-groups
+ "V" #'gnus-version
+ "s" #'gnus-group-save-newsrc
+ "z" #'gnus-group-suspend
+ "q" #'gnus-group-exit
+ "Q" #'gnus-group-quit
+ "?" #'gnus-group-describe-briefly
+ "C-c C-i" #'gnus-info-find-node
+ "M-e" #'gnus-group-edit-group-method
+ "^" #'gnus-group-enter-server-mode
+ "<mouse-2>" #'gnus-mouse-pick-group
+ "<follow-link>" 'mouse-face
+ "<" #'beginning-of-buffer
+ ">" #'end-of-buffer
+ "C-c C-b" #'gnus-bug
+ "C-c C-s" #'gnus-group-sort-groups
+ "t" #'gnus-topic-mode
+ "C-c M-g" #'gnus-activate-all-groups
+ "M-&" #'gnus-group-universal-argument
+ "#" #'gnus-group-mark-group
+ "M-#" #'gnus-group-unmark-group
+
+ "~" (define-keymap :prefix 'gnus-group-cloud-map
+ "u" #'gnus-cloud-upload-all-data
+ "~" #'gnus-cloud-upload-all-data
+ "d" #'gnus-cloud-download-all-data
+ "RET" #'gnus-cloud-download-all-data)
+
+ "M" (define-keymap :prefix 'gnus-group-mark-map
+ "m" #'gnus-group-mark-group
+ "u" #'gnus-group-unmark-group
+ "w" #'gnus-group-mark-region
+ "b" #'gnus-group-mark-buffer
+ "r" #'gnus-group-mark-regexp
+ "U" #'gnus-group-unmark-all-groups)
+
+ "D" (define-keymap :prefix 'gnus-group-sieve-map
+ "u" #'gnus-sieve-update
+ "g" #'gnus-sieve-generate)
+
+ "G" (define-keymap :prefix 'gnus-group-group-map
+ "d" #'gnus-group-make-directory-group
+ "h" #'gnus-group-make-help-group
+ "u" #'gnus-group-make-useful-group
+ "l" #'gnus-group-nnimap-edit-acl
+ "m" #'gnus-group-make-group
+ "E" #'gnus-group-edit-group
+ "e" #'gnus-group-edit-group-method
+ "p" #'gnus-group-edit-group-parameters
+ "v" #'gnus-group-add-to-virtual
+ "V" #'gnus-group-make-empty-virtual
+ "D" #'gnus-group-enter-directory
+ "f" #'gnus-group-make-doc-group
+ "w" #'gnus-group-make-web-group
+ "G" #'gnus-group-read-ephemeral-search-group
+ "g" #'gnus-group-make-search-group
+ "M" #'gnus-group-read-ephemeral-group
+ "r" #'gnus-group-rename-group
+ "R" #'gnus-group-make-rss-group
+ "c" #'gnus-group-customize
+ "z" #'gnus-group-compact-group
+ "x" #'gnus-group-expunge-group
+ "DEL" #'gnus-group-delete-group
+ "<delete>" #'gnus-group-delete-group
+
+ "S" (define-keymap :prefix 'gnus-group-sort-map
+ "s" #'gnus-group-sort-groups
+ "a" #'gnus-group-sort-groups-by-alphabet
+ "u" #'gnus-group-sort-groups-by-unread
+ "l" #'gnus-group-sort-groups-by-level
+ "v" #'gnus-group-sort-groups-by-score
+ "r" #'gnus-group-sort-groups-by-rank
+ "m" #'gnus-group-sort-groups-by-method
+ "n" #'gnus-group-sort-groups-by-real-name)
+
+ "P" (define-keymap :prefix 'gnus-group-sort-selected-map
+ "s" #'gnus-group-sort-selected-groups
+ "a" #'gnus-group-sort-selected-groups-by-alphabet
+ "u" #'gnus-group-sort-selected-groups-by-unread
+ "l" #'gnus-group-sort-selected-groups-by-level
+ "v" #'gnus-group-sort-selected-groups-by-score
+ "r" #'gnus-group-sort-selected-groups-by-rank
+ "m" #'gnus-group-sort-selected-groups-by-method
+ "n" #'gnus-group-sort-selected-groups-by-real-name))
+
+ "A" (define-keymap :prefix 'gnus-group-list-map
+ "k" #'gnus-group-list-killed
+ "z" #'gnus-group-list-zombies
+ "s" #'gnus-group-list-groups
+ "u" #'gnus-group-list-all-groups
+ "A" #'gnus-group-list-active
+ "a" #'gnus-group-apropos
+ "d" #'gnus-group-description-apropos
+ "m" #'gnus-group-list-matching
+ "M" #'gnus-group-list-all-matching
+ "l" #'gnus-group-list-level
+ "c" #'gnus-group-list-cached
+ "?" #'gnus-group-list-dormant
+ "!" #'gnus-group-list-ticked
+
+ "/" (define-keymap :prefix 'gnus-group-list-limit-map
+ "k" #'gnus-group-list-limit
+ "z" #'gnus-group-list-limit
+ "s" #'gnus-group-list-limit
+ "u" #'gnus-group-list-limit
+ "A" #'gnus-group-list-limit
+ "m" #'gnus-group-list-limit
+ "M" #'gnus-group-list-limit
+ "l" #'gnus-group-list-limit
+ "c" #'gnus-group-list-limit
+ "?" #'gnus-group-list-limit
+ "!" #'gnus-group-list-limit)
+
+ "f" (define-keymap :prefix 'gnus-group-list-flush-map
+ "k" #'gnus-group-list-flush
+ "z" #'gnus-group-list-flush
+ "s" #'gnus-group-list-flush
+ "u" #'gnus-group-list-flush
+ "A" #'gnus-group-list-flush
+ "m" #'gnus-group-list-flush
+ "M" #'gnus-group-list-flush
+ "l" #'gnus-group-list-flush
+ "c" #'gnus-group-list-flush
+ "?" #'gnus-group-list-flush
+ "!" #'gnus-group-list-flush)
+
+ "p" (define-keymap :prefix 'gnus-group-list-plus-map
+ "k" #'gnus-group-list-plus
+ "z" #'gnus-group-list-plus
+ "s" #'gnus-group-list-plus
+ "u" #'gnus-group-list-plus
+ "A" #'gnus-group-list-plus
+ "m" #'gnus-group-list-plus
+ "M" #'gnus-group-list-plus
+ "l" #'gnus-group-list-plus
+ "c" #'gnus-group-list-plus
+ "?" #'gnus-group-list-plus
+ "!" #'gnus-group-list-plus))
+
+ "W" (define-keymap :prefix 'gnus-group-score-map
+ "f" #'gnus-score-flush-cache
+ "e" #'gnus-score-edit-all-score)
+
+ "H" (define-keymap :prefix 'gnus-group-help-map
+ "d" #'gnus-group-describe-group
+ "v" #'gnus-version)
+
+ "S" (define-keymap :prefix 'gnus-group-sub-map
+ "l" #'gnus-group-set-current-level
+ "t" #'gnus-group-toggle-subscription-at-point
+ "s" #'gnus-group-toggle-subscription
+ "k" #'gnus-group-kill-group
+ "y" #'gnus-group-yank-group
+ "w" #'gnus-group-kill-region
+ "C-k" #'gnus-group-kill-level
+ "z" #'gnus-group-kill-all-zombies))
(defun gnus-topic-mode-p ()
"Return non-nil in `gnus-topic-mode'."
@@ -1176,11 +1178,11 @@ The following commands are available:
(defun gnus-group-default-level (&optional level number-or-nil)
(cond
(gnus-group-use-permanent-levels
- (or (setq gnus-group-use-permanent-levels
- (or level (if (numberp gnus-group-use-permanent-levels)
- gnus-group-use-permanent-levels
- (or (gnus-group-default-list-level)
- gnus-level-subscribed))))
+ (or level
+ (if (numberp gnus-group-use-permanent-levels)
+ gnus-group-use-permanent-levels
+ (or (gnus-group-default-list-level)
+ gnus-level-subscribed))
(gnus-group-default-list-level) gnus-level-subscribed))
(number-or-nil
level)
@@ -1228,20 +1230,23 @@ The following commands are available:
(let ((charset (gnus-group-name-charset nil string)))
(gnus-group-name-decode string charset)))
-(defun gnus-group-list-groups (&optional level unread lowest)
+(defun gnus-group-list-groups (&optional level unread lowest update-level)
"List newsgroups with level LEVEL or lower that have unread articles.
Default is all subscribed groups.
If argument UNREAD is non-nil, groups with no unread articles are also
listed.
-Also see the `gnus-group-use-permanent-levels' variable."
+Also see the `gnus-group-use-permanent-levels' variable. If this
+variable is non-nil, and UPDATE-LEVEL is non-nil (which is the
+case interactively), the level will be updated by this command."
(interactive
(list (if current-prefix-arg
(prefix-numeric-value current-prefix-arg)
(or
(gnus-group-default-level nil t)
(gnus-group-default-list-level)
- gnus-level-subscribed)))
+ gnus-level-subscribed))
+ nil nil t)
gnus-group-mode)
(unless level
(setq level (car gnus-group-list-mode)
@@ -1288,7 +1293,9 @@ Also see the `gnus-group-use-permanent-levels' variable."
(goto-char (point-max))
(forward-line -1)))))))
;; Adjust cursor point.
- (gnus-group-position-point)))
+ (gnus-group-position-point)
+ (when (and update-level gnus-group-use-permanent-levels)
+ (setq gnus-group-use-permanent-levels level))))
(defun gnus-group-list-level (level &optional all)
"List groups on LEVEL.
@@ -4055,7 +4062,8 @@ of groups killed."
(if (< (length out) 2) (car out) (nreverse out))))
(defun gnus-group-yank-group (&optional arg)
- "Yank the last newsgroups killed with \\[gnus-group-kill-group], inserting it before the current newsgroup.
+ "Yank the last newsgroups killed with \\[gnus-group-kill-group], inserting it
+before the current newsgroup.
The numeric ARG specifies how many newsgroups are to be yanked. The
name of the newsgroup yanked is returned, or (if several groups are
yanked) a list of yanked groups is returned."
@@ -4205,8 +4213,9 @@ otherwise all levels below ARG will be scanned too."
(gnus-check-reasonable-setup)
(gnus-run-hooks 'gnus-after-getting-new-news-hook)
- (gnus-group-list-groups (and (numberp arg)
- (max (car gnus-group-list-mode) arg)))))
+ (gnus-group-list-groups (and (numberp arg) arg))
+ (when gnus-group-use-permanent-levels
+ (setq gnus-group-use-permanent-levels (gnus-group-default-level arg)))))
(defun gnus-group-get-new-news-this-group (&optional n dont-scan)
"Check for newly arrived news in the current group (and the N-1 next groups).
@@ -4390,8 +4399,7 @@ If FORCE, force saving whether it is necessary or not."
(defun gnus-group-restart (&optional _arg)
"Force Gnus to read the .newsrc file."
(interactive nil gnus-group-mode)
- (when (gnus-yes-or-no-p
- (format "Are you sure you want to restart Gnus? "))
+ (when (gnus-yes-or-no-p "Are you sure you want to restart Gnus? ")
(gnus-save-newsrc-file)
(gnus-clear-system)
(gnus)))
@@ -4413,9 +4421,9 @@ group."
(defun gnus-group-find-new-groups (&optional arg)
"Search for new groups and add them.
Each new group will be treated with `gnus-subscribe-newsgroup-method'.
-With 1 C-u, use the `ask-server' method to query the server for new
+With 1 \\[universal-argument], use the `ask-server' method to query the server for new
groups.
-With 2 C-u's, use most complete method possible to query the server
+With 2 \\[universal-argument]'s, use most complete method possible to query the server
for new groups, and subscribe the new groups as zombies."
(interactive "p" gnus-group-mode)
(let ((new-groups (gnus-find-new-newsgroups (or arg 1)))
@@ -4466,7 +4474,7 @@ The hook `gnus-suspend-gnus-hook' is called before actually suspending."
(gnus-kill-buffer buf)))
(setq gnus-backlog-articles nil)
(gnus-kill-gnus-frames)
- ;; Closing all the backends is useful (for instance) when when the
+ ;; Closing all the backends is useful (for instance) when the
;; IP addresses have changed and you need to reconnect.
(dolist (elem gnus-opened-servers)
(gnus-close-server (car elem)))
@@ -4709,7 +4717,8 @@ or `gnus-group-catchup-group-hook'."
(gnus-group-get-parameter group 'timestamp t))
(defun gnus-group-timestamp-delta (group)
- "Return the offset in seconds from the timestamp for GROUP to the current time, as a floating point number."
+ "Return the offset in seconds from the timestamp for GROUP to the current time.
+Return value is a floating point number."
;; FIXME: This should return a Lisp integer, not a Lisp float,
;; since it is always an integer.
(let* ((time (or (gnus-group-timestamp group) 0))
diff --git a/lisp/gnus/gnus-html.el b/lisp/gnus/gnus-html.el
index be62bfd81f5..ef376f138e7 100644
--- a/lisp/gnus/gnus-html.el
+++ b/lisp/gnus/gnus-html.el
@@ -71,21 +71,17 @@ fit these criteria."
:group 'gnus-art
:type 'float)
-(defvar gnus-html-image-map
- (let ((map (make-sparse-keymap)))
- (define-key map "u" 'gnus-article-copy-string)
- (define-key map "i" 'gnus-html-insert-image)
- (define-key map "v" 'gnus-html-browse-url)
- map))
-
-(defvar gnus-html-displayed-image-map
- (let ((map (make-sparse-keymap)))
- (define-key map "a" 'gnus-html-show-alt-text)
- (define-key map "i" 'gnus-html-browse-image)
- (define-key map "\r" 'gnus-html-browse-url)
- (define-key map "u" 'gnus-article-copy-string)
- (define-key map [tab] 'button-forward)
- map))
+(defvar-keymap gnus-html-image-map
+ "u" #'gnus-article-copy-string
+ "i" #'gnus-html-insert-image
+ "v" #'gnus-html-browse-url)
+
+(defvar-keymap gnus-html-displayed-image-map
+ "a" #'gnus-html-show-alt-text
+ "i" #'gnus-html-browse-image
+ "RET" #'gnus-html-browse-url
+ "u" #'gnus-article-copy-string
+ "<tab>" #'forward-button)
(defun gnus-html-encode-url (url)
"Encode URL."
diff --git a/lisp/gnus/gnus-icalendar.el b/lisp/gnus/gnus-icalendar.el
index 5294b83d9e9..81e46d7a51e 100644
--- a/lisp/gnus/gnus-icalendar.el
+++ b/lisp/gnus/gnus-icalendar.el
@@ -107,19 +107,19 @@
:accessor gnus-icalendar-event:opt-participants
:initform nil
:type (or null t)))
- "generic iCalendar Event class")
+ "Generic iCalendar Event class.")
(defclass gnus-icalendar-event-request (gnus-icalendar-event)
nil
- "iCalendar class for REQUEST events")
+ "iCalendar class for REQUEST events.")
(defclass gnus-icalendar-event-cancel (gnus-icalendar-event)
nil
- "iCalendar class for CANCEL events")
+ "iCalendar class for CANCEL events.")
(defclass gnus-icalendar-event-reply (gnus-icalendar-event)
nil
- "iCalendar class for REPLY events")
+ "iCalendar class for REPLY events.")
(cl-defmethod gnus-icalendar-event:recurring-p ((event gnus-icalendar-event))
"Return t if EVENT is recurring."
@@ -194,7 +194,11 @@
(caddr event))))
(cl-labels
- ((attendee-role (prop) (plist-get (cadr prop) 'ROLE))
+ ((attendee-role (prop)
+ ;; RFC5546: default ROLE is REQ-PARTICIPANT
+ (and prop
+ (or (plist-get (cadr prop) 'ROLE)
+ "REQ-PARTICIPANT")))
(attendee-name
(prop)
(or (plist-get (cadr prop) 'CN)
@@ -225,7 +229,10 @@
(gnus-icalendar-event--find-attendee
ical attendee-name-or-email)))
(attendee-names (gnus-icalendar-event--get-attendee-names ical))
- (role (plist-get (cadr attendee) 'ROLE))
+ ;; RFC5546: default ROLE is REQ-PARTICIPANT
+ (role (and attendee
+ (or (plist-get (cadr attendee) 'ROLE)
+ "REQ-PARTICIPANT")))
(participation-type (pcase role
("REQ-PARTICIPANT" 'required)
("OPT-PARTICIPANT" 'optional)
@@ -345,10 +352,16 @@ status will be retrieved from the first matching attendee record."
(mapc #'process-event-line (split-string ical-request "\n"))
+ ;; RFC5546 refers to uninvited attendees as "party crashers".
+ ;; This situation is common if the invitation is sent to a group
+ ;; of people via a mailing list.
(unless (gnus-icalendar-find-if (lambda (x) (string-match "^ATTENDEE" x))
reply-event-lines)
(lwarn 'gnus-icalendar :warning
- "Could not find an event attendee matching given identity"))
+ "Could not find an event attendee matching given identity")
+ (push (format "ATTENDEE;RSVP=TRUE;PARTSTAT=%s;CN=%s:MAILTO:%s"
+ attendee-status user-full-name user-mail-address)
+ reply-event-lines))
(mapconcat #'identity `("BEGIN:VEVENT"
,@(nreverse reply-event-lines)
@@ -847,10 +860,14 @@ These will be used to retrieve the RSVP information from ical events."
button t
gnus-data ,data))))
-(defun gnus-icalendar-send-buffer-by-mail (buffer-name subject)
+(defun gnus-icalendar-send-buffer-by-mail (buffer-name subject organizer)
(let ((message-signature nil))
(with-current-buffer gnus-summary-buffer
(gnus-summary-reply)
+ ;; Reply to the organizer, not to whoever sent the invitation. person
+ ;; Some calendar systems use specific email address as organizer to
+ ;; receive these responses.
+ (message-replace-header "To" organizer)
(message-goto-body)
(mml-insert-multipart "alternative")
(mml-insert-empty-tag 'part 'type "text/plain")
@@ -866,7 +883,8 @@ These will be used to retrieve the RSVP information from ical events."
(event (caddr data))
(reply (gnus-icalendar-with-decoded-handle handle
(gnus-icalendar-event-reply-from-buffer
- (current-buffer) status (gnus-icalendar-identities)))))
+ (current-buffer) status (gnus-icalendar-identities))))
+ (organizer (gnus-icalendar-event:organizer event)))
(when reply
(cl-labels
@@ -883,7 +901,7 @@ These will be used to retrieve the RSVP information from ical events."
(delete-region (point-min) (point-max))
(insert reply)
(fold-icalendar-buffer)
- (gnus-icalendar-send-buffer-by-mail (buffer-name) subject))
+ (gnus-icalendar-send-buffer-by-mail (buffer-name) subject organizer))
;; Back in article buffer
(setq-local gnus-icalendar-reply-status status)
@@ -897,10 +915,16 @@ These will be used to retrieve the RSVP information from ical events."
(gnus-icalendar-event:sync-to-org event gnus-icalendar-reply-status))
(cl-defmethod gnus-icalendar-event:inline-reply-buttons ((event gnus-icalendar-event) handle)
- (when (gnus-icalendar-event:rsvp event)
- `(("Accept" gnus-icalendar-reply (,handle accepted ,event))
- ("Tentative" gnus-icalendar-reply (,handle tentative ,event))
- ("Decline" gnus-icalendar-reply (,handle declined ,event)))))
+ (let ((accept-btn "Accept")
+ (tentative-btn "Tentative")
+ (decline-btn "Decline"))
+ (unless (gnus-icalendar-event:rsvp event)
+ (setq accept-btn "Uninvited Accept"
+ tentative-btn "Uninvited Tentative"
+ decline-btn "Uninvited Decline"))
+ `((,accept-btn gnus-icalendar-reply (,handle accepted ,event))
+ (,tentative-btn gnus-icalendar-reply (,handle tentative ,event))
+ (,decline-btn gnus-icalendar-reply (,handle declined ,event)))))
(cl-defmethod gnus-icalendar-event:inline-reply-buttons ((_event gnus-icalendar-event-reply) _handle)
"No buttons for REPLY events."
@@ -1038,13 +1062,14 @@ These will be used to retrieve the RSVP information from ical events."
(add-to-list 'mm-automatic-display "text/calendar")
(add-to-list 'mm-inline-media-tests '("text/calendar" gnus-icalendar-mm-inline identity))
- (gnus-define-keys (gnus-summary-calendar-map "i" gnus-summary-mode-map)
- "a" gnus-icalendar-reply-accept
- "t" gnus-icalendar-reply-tentative
- "d" gnus-icalendar-reply-decline
- "c" gnus-icalendar-event-check-agenda
- "e" gnus-icalendar-event-export
- "s" gnus-icalendar-event-show)
+ (define-key gnus-summary-mode-map "i"
+ (define-keymap :prefix 'gnus-summary-calendar-map
+ "a" #'gnus-icalendar-reply-accept
+ "t" #'gnus-icalendar-reply-tentative
+ "d" #'gnus-icalendar-reply-decline
+ "c" #'gnus-icalendar-event-check-agenda
+ "e" #'gnus-icalendar-event-export
+ "s" #'gnus-icalendar-event-show))
(require 'gnus-art)
(add-to-list 'gnus-mime-action-alist
diff --git a/lisp/gnus/gnus-int.el b/lisp/gnus/gnus-int.el
index 01053797b3a..255c11f137c 100644
--- a/lisp/gnus/gnus-int.el
+++ b/lisp/gnus/gnus-int.el
@@ -613,8 +613,7 @@ If BUFFER, insert the article in that group."
Returns the article number of the message.
If GROUP is not already selected, the message will be the only one in
-the group's summary.
-"
+the group's summary."
;; TODO: is there a way to know at this point whether the group will
;; be newly-selected? If so we could clean up the logic at the end
;;
diff --git a/lisp/gnus/gnus-kill.el b/lisp/gnus/gnus-kill.el
index 525823e72ce..7137efd7309 100644
--- a/lisp/gnus/gnus-kill.el
+++ b/lisp/gnus/gnus-kill.el
@@ -66,18 +66,15 @@ of time."
;;; Gnus Kill File Mode
;;;
-(defvar gnus-kill-file-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map emacs-lisp-mode-map)
- (gnus-define-keymap map
- "\C-c\C-k\C-s" gnus-kill-file-kill-by-subject
- "\C-c\C-k\C-a" gnus-kill-file-kill-by-author
- "\C-c\C-k\C-t" gnus-kill-file-kill-by-thread
- "\C-c\C-k\C-x" gnus-kill-file-kill-by-xref
- "\C-c\C-a" gnus-kill-file-apply-buffer
- "\C-c\C-e" gnus-kill-file-apply-last-sexp
- "\C-c\C-c" gnus-kill-file-exit)
- map))
+(defvar-keymap gnus-kill-file-mode-map
+ :parent emacs-lisp-mode-map
+ "C-c C-k C-s" #'gnus-kill-file-kill-by-subject
+ "C-c C-k C-a" #'gnus-kill-file-kill-by-author
+ "C-c C-k C-t" #'gnus-kill-file-kill-by-thread
+ "C-c C-k C-x" #'gnus-kill-file-kill-by-xref
+ "C-c C-a" #'gnus-kill-file-apply-buffer
+ "C-c C-e" #'gnus-kill-file-apply-last-sexp
+ "C-c C-c" #'gnus-kill-file-exit)
(define-derived-mode gnus-kill-file-mode emacs-lisp-mode "Kill"
"Major mode for editing kill files.
diff --git a/lisp/gnus/gnus-ml.el b/lisp/gnus/gnus-ml.el
index 3b2b5a07c1d..a5358e9ff42 100644
--- a/lisp/gnus/gnus-ml.el
+++ b/lisp/gnus/gnus-ml.el
@@ -31,16 +31,13 @@
;;; Mailing list minor mode
-(defvar gnus-mailing-list-mode-map
- (let ((map (make-sparse-keymap)))
- (gnus-define-keys map
- "\C-c\C-nh" gnus-mailing-list-help
- "\C-c\C-ns" gnus-mailing-list-subscribe
- "\C-c\C-nu" gnus-mailing-list-unsubscribe
- "\C-c\C-np" gnus-mailing-list-post
- "\C-c\C-no" gnus-mailing-list-owner
- "\C-c\C-na" gnus-mailing-list-archive)
- map))
+(defvar-keymap gnus-mailing-list-mode-map
+ "C-c C-n h" #'gnus-mailing-list-help
+ "C-c C-n s" #'gnus-mailing-list-subscribe
+ "C-c C-n u" #'gnus-mailing-list-unsubscribe
+ "C-c C-n p" #'gnus-mailing-list-post
+ "C-c C-n o" #'gnus-mailing-list-owner
+ "C-c C-n a" #'gnus-mailing-list-archive)
(defvar gnus-mailing-list-menu)
@@ -127,7 +124,7 @@ If FORCE is non-nil, replace the old ones."
(t (gnus-message 1 "no list-unsubscribe in this group")))))
(defun gnus-mailing-list-post ()
- "Post message (really useful ?)"
+ "Post message (really useful ?)."
(interactive)
(let ((list-post
(with-current-buffer gnus-original-article-buffer
diff --git a/lisp/gnus/gnus-mlspl.el b/lisp/gnus/gnus-mlspl.el
index 6adda2ed147..878e879cd70 100644
--- a/lisp/gnus/gnus-mlspl.el
+++ b/lisp/gnus/gnus-mlspl.el
@@ -75,7 +75,7 @@ match any of the group-specified splitting rules. See
;;;###autoload
(defun gnus-group-split-update (&optional catch-all)
- "Computes nnmail-split-fancy from group params and CATCH-ALL.
+ "Computes `nnmail-split-fancy' from group params and CATCH-ALL.
It does this by calling (gnus-group-split-fancy nil nil CATCH-ALL).
If CATCH-ALL is nil, `gnus-group-split-default-catch-all-group' is used
diff --git a/lisp/gnus/gnus-msg.el b/lisp/gnus/gnus-msg.el
index ef89e6e9fcb..c60faa13263 100644
--- a/lisp/gnus/gnus-msg.el
+++ b/lisp/gnus/gnus-msg.el
@@ -33,7 +33,7 @@
(require 'gnus-util)
(defcustom gnus-post-method 'current
- "Preferred method for posting USENET news.
+ "Preferred method for posting Usenet news.
If this variable is `current' (which is the default), Gnus will use
the \"current\" select method when posting. If it is `native', Gnus
@@ -303,7 +303,7 @@ If nil, the address field will always be empty after invoking
(defcustom gnus-message-highlight-citation
t ;; gnus-treat-highlight-citation ;; gnus-cite dependency
- "Enable highlighting of different citation levels in message-mode."
+ "Enable highlighting of different citation levels in `message-mode'."
:version "23.1" ;; No Gnus
:group 'gnus-cite
:group 'gnus-message
@@ -349,39 +349,39 @@ only affect the Gcc copy, but not the original message."
;;; Gnus Posting Functions
;;;
-(gnus-define-keys (gnus-summary-send-map "S" gnus-summary-mode-map)
- "p" gnus-summary-post-news
- "i" gnus-summary-news-other-window
- "f" gnus-summary-followup
- "F" gnus-summary-followup-with-original
- "c" gnus-summary-cancel-article
- "s" gnus-summary-supersede-article
- "r" gnus-summary-reply
- "y" gnus-summary-yank-message
- "R" gnus-summary-reply-with-original
- "L" gnus-summary-reply-to-list-with-original
- "w" gnus-summary-wide-reply
- "W" gnus-summary-wide-reply-with-original
- "v" gnus-summary-very-wide-reply
- "V" gnus-summary-very-wide-reply-with-original
- "n" gnus-summary-followup-to-mail
- "N" gnus-summary-followup-to-mail-with-original
- "m" gnus-summary-mail-other-window
- "u" gnus-uu-post-news
- "A" gnus-summary-attach-article
- "\M-c" gnus-summary-mail-crosspost-complaint
- "Br" gnus-summary-reply-broken-reply-to
- "BR" gnus-summary-reply-broken-reply-to-with-original
- "om" gnus-summary-mail-forward
- "op" gnus-summary-post-forward
- "Om" gnus-uu-digest-mail-forward
- "Op" gnus-uu-digest-post-forward)
-
-(gnus-define-keys (gnus-send-bounce-map "D" gnus-summary-send-map)
- "b" gnus-summary-resend-bounced-mail
- ;; "c" gnus-summary-send-draft
- "r" gnus-summary-resend-message
- "e" gnus-summary-resend-message-edit)
+(define-keymap :prefix 'gnus-summary-send-map
+ "p" #'gnus-summary-post-news
+ "i" #'gnus-summary-news-other-window
+ "f" #'gnus-summary-followup
+ "F" #'gnus-summary-followup-with-original
+ "c" #'gnus-summary-cancel-article
+ "s" #'gnus-summary-supersede-article
+ "r" #'gnus-summary-reply
+ "y" #'gnus-summary-yank-message
+ "R" #'gnus-summary-reply-with-original
+ "L" #'gnus-summary-reply-to-list-with-original
+ "w" #'gnus-summary-wide-reply
+ "W" #'gnus-summary-wide-reply-with-original
+ "v" #'gnus-summary-very-wide-reply
+ "V" #'gnus-summary-very-wide-reply-with-original
+ "n" #'gnus-summary-followup-to-mail
+ "N" #'gnus-summary-followup-to-mail-with-original
+ "m" #'gnus-summary-mail-other-window
+ "u" #'gnus-uu-post-news
+ "A" #'gnus-summary-attach-article
+ "M-c" #'gnus-summary-mail-crosspost-complaint
+ "B r" #'gnus-summary-reply-broken-reply-to
+ "B R" #'gnus-summary-reply-broken-reply-to-with-original
+ "o m" #'gnus-summary-mail-forward
+ "o p" #'gnus-summary-post-forward
+ "O m" #'gnus-uu-digest-mail-forward
+ "O p" #'gnus-uu-digest-post-forward
+
+ "D" (define-keymap :prefix 'gnus-send-bounce-map
+ "b" #'gnus-summary-resend-bounced-mail
+ ;; "c" gnus-summary-send-draft
+ "r" #'gnus-summary-resend-message
+ "e" #'gnus-summary-resend-message-edit))
;;; Internal functions.
@@ -1303,15 +1303,9 @@ For the \"inline\" alternatives, also see the variable
(defun gnus-summary-resend-message-insert-gcc ()
"Insert Gcc header according to `gnus-gcc-self-resent-messages'."
(gnus-inews-insert-gcc)
- (let ((gcc (mapcar
- (lambda (group)
- (encode-coding-string
- group
- (gnus-group-name-charset (gnus-inews-group-method group)
- group)))
- (message-unquote-tokens
+ (let ((gcc (message-unquote-tokens
(message-tokenize-header (mail-fetch-field "gcc" nil t)
- " ,"))))
+ ",")))
(self (with-current-buffer gnus-summary-buffer
gnus-gcc-self-resent-messages)))
(message-remove-header "gcc")
@@ -1322,12 +1316,9 @@ For the \"inline\" alternatives, also see the variable
(insert "Gcc: \"" gnus-newsgroup-name "\"\n"))
((stringp self)
(insert "Gcc: "
- (encode-coding-string
- (if (string-search " " self)
- (concat "\"" self "\"")
- self)
- (gnus-group-name-charset (gnus-inews-group-method self)
- self))
+ (if (string-search " " self)
+ (concat "\"" self "\"")
+ self)
"\n"))
((null self)
(insert "Gcc: " (mapconcat #'identity gcc ", ") "\n"))
@@ -1581,13 +1572,10 @@ this is a reply."
(message-remove-header "gcc")
(widen)
(setq groups (message-unquote-tokens
- (message-tokenize-header gcc " ,\n\t")))
+ (message-tokenize-header gcc ",\n\t")))
;; Copy the article over to some group(s).
(while (setq group (pop groups))
- (setq method (gnus-inews-group-method group)
- group (encode-coding-string
- group
- (gnus-group-name-charset method group)))
+ (setq method (gnus-inews-group-method group))
(unless (gnus-check-server method)
(error "Can't open server %s" (if (stringp method) method
(car method))))
@@ -1760,7 +1748,7 @@ this is a reply."
(concat "\"" str "\"")
str)))
(when groups
- (insert " ")))
+ (insert ",")))
(insert "\n")))))))
(defun gnus-mailing-list-followup-to ()
diff --git a/lisp/gnus/gnus-range.el b/lisp/gnus/gnus-range.el
index 7d12ae9fdcc..a8f09b63711 100644
--- a/lisp/gnus/gnus-range.el
+++ b/lisp/gnus/gnus-range.el
@@ -40,10 +40,17 @@ If RANGE is a single range, return (RANGE). Otherwise, return RANGE."
(define-obsolete-function-alias 'gnus-copy-sequence 'copy-tree "27.1")
+;;; We could be using `seq-difference' here, but it's much slower
+;;; on these data sets. See bug#50877.
(defun gnus-set-difference (list1 list2)
"Return a list of elements of LIST1 that do not appear in LIST2."
- (declare (obsolete seq-difference "28.1"))
- (seq-difference list1 list2 #'eq))
+ (let ((hash2 (make-hash-table :test 'eq))
+ (result nil))
+ (dolist (elt list2) (puthash elt t hash2))
+ (dolist (elt list1)
+ (unless (gethash elt hash2)
+ (setq result (cons elt result))))
+ (nreverse result)))
(defun gnus-range-nconcat (&rest ranges)
"Return a range comprising all the RANGES, which are pre-sorted.
diff --git a/lisp/gnus/gnus-registry.el b/lisp/gnus/gnus-registry.el
index 0468d72edd0..163d543afd1 100644
--- a/lisp/gnus/gnus-registry.el
+++ b/lisp/gnus/gnus-registry.el
@@ -772,7 +772,7 @@ possible. Uses `gnus-registry-split-strategy'."
nil))))
(defun gnus-registry-follow-group-p (group)
- "Determines if a group name should be followed.
+ "Determine if a group name should be followed.
Consults `gnus-registry-unfollowed-groups' and
`nnmail-split-fancy-with-parent-ignore-groups'."
(and group
@@ -789,7 +789,7 @@ Consults `gnus-registry-unfollowed-groups' and
;; we do special logic for ignoring to accept regular expressions and
;; nnmail-split-fancy-with-parent-ignore-groups as well
(defun gnus-registry-ignore-group-p (group)
- "Determines if a group name should be ignored.
+ "Determine if a group name should be ignored.
Consults `gnus-registry-ignored-groups' and
`nnmail-split-fancy-with-parent-ignore-groups'."
(and group
@@ -847,7 +847,8 @@ Overrides existing keywords with FORCE set non-nil."
(defun gnus-registry-register-message-ids ()
"Register the Message-ID of every article in the group."
(unless (or (gnus-parameter-registry-ignore gnus-newsgroup-name)
- (null gnus-registry-register-all))
+ (null gnus-registry-register-all)
+ (null (eieio-object-p gnus-registry-db)))
(dolist (article gnus-newsgroup-articles)
(let* ((id (gnus-registry-fetch-message-id-fast article))
(groups (gnus-registry-get-id-key id 'group)))
@@ -990,9 +991,9 @@ Uses `gnus-registry-marks' to find what shortcuts to install."
gnus-registry-misc-menus)
(gnus-message 9 "Defined mark handling function %s"
function-name))))))
- (gnus-define-keys-1
- '(gnus-registry-mark-map "M" gnus-summary-mark-map)
- keys-plist)
+ (define-key gnus-summary-mark-map "M"
+ (apply #'define-keymap :prefix 'gnus-summary-mark-map
+ keys-plist))
(add-hook 'gnus-summary-menu-hook
(lambda ()
(easy-menu-add-item
@@ -1142,7 +1143,7 @@ non-nil."
entry)
(while (car-safe old)
(cl-incf count)
- ;; don't use progress reporters for backwards compatibility
+ ;; todo: use progress reporters.
(when (and (< 0 expected)
(= 0 (mod count 100)))
(message "importing: %d of %d (%.2f%%)"
diff --git a/lisp/gnus/gnus-salt.el b/lisp/gnus/gnus-salt.el
index 5b746a8efa9..205e936bc7e 100644
--- a/lisp/gnus/gnus-salt.el
+++ b/lisp/gnus/gnus-salt.el
@@ -51,7 +51,7 @@
(defcustom gnus-pick-elegant-flow t
"If non-nil, `gnus-pick-start-reading' runs
- `gnus-summary-next-group' when no articles have been picked."
+`gnus-summary-next-group' when no articles have been picked."
:type 'boolean
:group 'gnus-summary-pick)
@@ -64,15 +64,12 @@ It accepts the same format specs that `gnus-summary-line-format' does."
;;; Internal variables.
-(defvar gnus-pick-mode-map
- (let ((map (make-sparse-keymap)))
- (gnus-define-keys map
- " " gnus-pick-next-page
- "u" gnus-pick-unmark-article-or-thread
- "." gnus-pick-article-or-thread
- [down-mouse-2] gnus-pick-mouse-pick-region
- "\r" gnus-pick-start-reading)
- map))
+(defvar-keymap gnus-pick-mode-map
+ "SPC" #'gnus-pick-next-page
+ "u" #'gnus-pick-unmark-article-or-thread
+ "." #'gnus-pick-article-or-thread
+ "<down-mouse-2>" #'gnus-pick-mouse-pick-region
+ "RET" #'gnus-pick-start-reading)
(defun gnus-pick-make-menu-bar ()
(unless (boundp 'gnus-pick-menu)
@@ -315,11 +312,8 @@ This must be bound to a button-down mouse event."
(defvar gnus-binary-mode-hook nil
"Hook run in summary binary mode buffers.")
-(defvar gnus-binary-mode-map
- (let ((map (make-sparse-keymap)))
- (gnus-define-keys map
- "g" gnus-binary-show-article)
- map))
+(defvar-keymap gnus-binary-mode-map
+ "g" #'gnus-binary-show-article)
(defun gnus-binary-make-menu-bar ()
(unless (boundp 'gnus-binary-menu)
@@ -424,21 +418,17 @@ Two predefined functions are available:
(defvar gnus-tree-displayed-thread nil)
(defvar gnus-tree-inhibit nil)
-(defvar gnus-tree-mode-map
- (let ((map (make-keymap)))
- (suppress-keymap map)
- (gnus-define-keys
- map
- "\r" gnus-tree-select-article
- [mouse-2] gnus-tree-pick-article
- "\C-?" gnus-tree-read-summary-keys
- "h" gnus-tree-show-summary
-
- "\C-c\C-i" gnus-info-find-node)
-
- (substitute-key-definition
- 'undefined 'gnus-tree-read-summary-keys map)
- map))
+(defvar-keymap gnus-tree-mode-map
+ :full t :suppress t
+ "RET" #'gnus-tree-select-article
+ "<mouse-2>" #'gnus-tree-pick-article
+ "DEL" #'gnus-tree-read-summary-keys
+ "h" #'gnus-tree-show-summary
+
+ "C-c C-i" #'gnus-info-find-node)
+
+(substitute-key-definition 'undefined #'gnus-tree-read-summary-keys
+ gnus-tree-mode-map)
(defun gnus-tree-make-menu-bar ()
(unless (boundp 'gnus-tree-menu)
diff --git a/lisp/gnus/gnus-score.el b/lisp/gnus/gnus-score.el
index f40da9e9c4c..a25673a0e75 100644
--- a/lisp/gnus/gnus-score.el
+++ b/lisp/gnus/gnus-score.el
@@ -502,19 +502,20 @@ of the last successful match.")
;;; Summary mode score maps.
-(gnus-define-keys (gnus-summary-score-map "V" gnus-summary-mode-map)
- "s" gnus-summary-set-score
- "S" gnus-summary-current-score
- "c" gnus-score-change-score-file
- "C" gnus-score-customize
- "m" gnus-score-set-mark-below
- "x" gnus-score-set-expunge-below
- "R" gnus-summary-rescore
- "e" gnus-score-edit-current-scores
- "f" gnus-score-edit-file
- "F" gnus-score-flush-cache
- "t" gnus-score-find-trace
- "w" gnus-score-find-favorite-words)
+(define-key gnus-summary-mode-map "V"
+ (define-keymap :prefix 'gnus-summary-score-map
+ "s" #'gnus-summary-set-score
+ "S" #'gnus-summary-current-score
+ "c" #'gnus-score-change-score-file
+ "C" #'gnus-score-customize
+ "m" #'gnus-score-set-mark-below
+ "x" #'gnus-score-set-expunge-below
+ "R" #'gnus-summary-rescore
+ "e" #'gnus-score-edit-current-scores
+ "f" #'gnus-score-edit-file
+ "F" #'gnus-score-flush-cache
+ "t" #'gnus-score-find-trace
+ "w" #'gnus-score-find-favorite-words))
;; Summary score file commands
@@ -1093,7 +1094,7 @@ EXTRA is the possible non-standard header."
(defun gnus-summary-current-score (arg)
"Return the score of the current article.
- With prefix ARG, return the total score of the current (sub)thread."
+With prefix ARG, return the total score of the current (sub)thread."
(interactive "P" gnus-article-mode gnus-summary-mode)
(message "%s" (if arg
(gnus-thread-total-score
@@ -1748,7 +1749,7 @@ score in `gnus-newsgroup-scored' by SCORE."
(setq type 'after
match-func 'string<
match (gnus-time-iso8601
- (time-subtract (current-time)
+ (time-subtract nil
(* 86400 (nth 0 kill))))))
((eq type 'before)
(setq match-func 'gnus-string>
@@ -1757,7 +1758,7 @@ score in `gnus-newsgroup-scored' by SCORE."
(setq type 'before
match-func 'gnus-string>
match (gnus-time-iso8601
- (time-subtract (current-time)
+ (time-subtract nil
(* 86400 (nth 0 kill))))))
((eq type 'at)
(setq match-func 'string=
@@ -2561,16 +2562,17 @@ score in `gnus-newsgroup-scored' by SCORE."
(or (caddr s)
gnus-score-interactive-default-score))
trace))))
- (insert
- "\n\nQuick help:
+ (insert
+ (substitute-command-keys
+ "\n\nQuick help:
-Type `e' to edit score file corresponding to the score rule on current line,
-`f' to format (pretty print) the score file and edit it,
-`t' toggle to truncate long lines in this buffer,
-`q' to quit, `k' to kill score trace buffer.
+Type \\`e' to edit score file corresponding to the score rule on current line,
+\\`f' to format (pretty print) the score file and edit it,
+\\`t' toggle to truncate long lines in this buffer,
+\\`q' to quit, \\`k' to kill score trace buffer.
The first sexp on each line is the score rule, followed by the file name of
-the score file and its full name, including the directory.")
+the score file and its full name, including the directory."))
(goto-char (point-min))
(gnus-configure-windows 'score-trace)))
(set-buffer gnus-summary-buffer)
@@ -3115,7 +3117,9 @@ If ADAPT, return the home adaptive file instead."
;;;
(defun gnus-decay-score (score)
- "Decay SCORE according to `gnus-score-decay-constant' and `gnus-score-decay-scale'."
+ "Decay SCORE according to decay variables.
+The decay variables are `gnus-score-decay-constant' and
+`gnus-score-decay-scale'."
(floor (- score
(* (if (< score 0) -1 1)
(min (abs score)
diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el
index 2a8069d400c..46dc1cf6c1f 100644
--- a/lisp/gnus/gnus-search.el
+++ b/lisp/gnus/gnus-search.el
@@ -105,9 +105,13 @@
(gnus-add-shutdown #'gnus-search-shutdown 'gnus)
-(define-error 'gnus-search-parse-error "Gnus search parsing error")
+(define-error 'gnus-search-error "Gnus search error")
-(define-error 'gnus-search-config-error "Gnus search configuration error")
+(define-error 'gnus-search-parse-error "Gnus search parsing error"
+ 'gnus-search-error)
+
+(define-error 'gnus-search-config-error "Gnus search configuration error"
+ 'gnus-search-error)
;;; User Customizable Variables:
@@ -132,7 +136,7 @@ transformed."
(defcustom gnus-search-ignored-newsgroups ""
"A regexp to match newsgroups in the active file that should
- be skipped when searching."
+be skipped when searching."
:version "24.1"
:type 'regexp)
@@ -172,8 +176,7 @@ This variable can also be set per-server."
:type 'regexp)
(defcustom gnus-search-swish++-raw-queries-p nil
- "If t, all Swish++ engines will only accept raw search query
- strings."
+ "If t, all Swish++ engines will only accept raw search query strings."
:type 'boolean
:version "28.1")
@@ -217,8 +220,7 @@ This variable can also be set per-server."
:version "28.1")
(defcustom gnus-search-swish-e-raw-queries-p nil
- "If t, all Swish-e engines will only accept raw search query
- strings."
+ "If t, all Swish-e engines will only accept raw search query strings."
:type 'boolean
:version "28.1")
@@ -266,8 +268,7 @@ This variable can also be set per-server."
:version "28.1")
(defcustom gnus-search-namazu-raw-queries-p nil
- "If t, all Namazu engines will only accept raw search query
- strings."
+ "If t, all Namazu engines will only accept raw search query strings."
:type 'boolean
:version "28.1")
@@ -305,14 +306,12 @@ This variable can also be set per-server."
:version "28.1")
(defcustom gnus-search-notmuch-raw-queries-p nil
- "If t, all Notmuch engines will only accept raw search query
- strings."
+ "If t, all Notmuch engines will only accept raw search query strings."
:type 'boolean
:version "28.1")
(defcustom gnus-search-imap-raw-queries-p nil
- "If t, all IMAP engines will only accept raw search query
- strings."
+ "If t, all IMAP engines will only accept raw search query strings."
:version "28.1"
:type 'boolean)
@@ -350,8 +349,7 @@ This variable can also be set per-server."
:type 'regexp)
(defcustom gnus-search-mairix-raw-queries-p nil
- "If t, all Mairix engines will only accept raw search query
- strings."
+ "If t, all Mairix engines will only accept raw search query strings."
:version "28.1"
:type 'boolean)
@@ -403,7 +401,7 @@ expressions. Key is most often a mail header, but there are
other keys. Value is a string, quoted if it contains spaces.
Key and value are separated by a colon, no space. Expressions
are implicitly ANDed; the \"or\" keyword can be used to
-OR. \"not\" will negate the following expression, or keys can be
+OR. \"not\" will negate the following expression, or keys can be
prefixed with a \"-\". The \"near\" operator will work for
engines that understand it; other engines will convert it to
\"or\". Parenthetical groups work as expected.
@@ -413,7 +411,7 @@ header.
Search keys can be expanded with TAB during entry, or left
abbreviated so long as they remain unambiguous, ie \"f\" will
-search the \"from\" header. \"s\" will raise an error.
+search the \"from\" header. \"s\" will raise an error.
Other keys:
@@ -433,7 +431,7 @@ It's also possible to use Gnus' internal marks, ie \"mark:R\"
will be interpreted as mark:read.
\"tag\" will search tags -- right now that's translated to
-\"keyword\" in IMAP, and left as \"tag\" for notmuch. At some
+\"keyword\" in IMAP, and left as \"tag\" for notmuch. At some
point this should also be used to search marks in the Gnus
registry.
@@ -574,15 +572,13 @@ REL-DATE, or (current-time) if REL-DATE is nil."
;; Time parsing doesn't seem to work with slashes.
(let ((value (string-replace "/" "-" value))
(now (append '(0 0 0)
- (seq-subseq (decode-time (or rel-date
- (current-time)))
- 3))))
+ (seq-subseq (decode-time rel-date) 3))))
;; Check for relative time parsing.
(if (string-match "\\([[:digit:]]+\\)\\([dwmy]\\)" value)
(seq-subseq
(decode-time
(time-subtract
- (apply #'encode-time now)
+ (encode-time now)
(days-to-time
(* (string-to-number (match-string 1 value))
(cdr (assoc (match-string 2 value)
@@ -601,7 +597,7 @@ REL-DATE, or (current-time) if REL-DATE is nil."
;; If DOW is given, handle that specially.
(if (and (seq-elt d-time 6) (null (seq-elt d-time 3)))
(decode-time
- (time-subtract (apply #'encode-time now)
+ (time-subtract (encode-time now)
(days-to-time
(+ (if (> (seq-elt d-time 6)
(seq-elt now 6))
@@ -1024,7 +1020,7 @@ Responsible for handling and, or, and parenthetical expressions.")
(single-search (gnus-search-single-p query))
(grouplist (or groups (gnus-search-get-active srv)))
q-string artlist group)
- (message "Opening server %s" server)
+ (gnus-message 7 "Opening server %s" server)
(gnus-open-server srv)
;; We should only be doing this once, in
;; `nnimap-open-connection', but it's too frustrating to try to
@@ -1068,7 +1064,7 @@ Responsible for handling and, or, and parenthetical expressions.")
(when (nnimap-change-group
(gnus-group-short-name group) server)
(with-current-buffer (nnimap-buffer)
- (message "Searching %s..." group)
+ (gnus-message 7 "Searching %s..." group)
(let ((result
(gnus-search-imap-search-command engine q-string)))
(when (car result)
@@ -1081,7 +1077,7 @@ Responsible for handling and, or, and parenthetical expressions.")
(vector group artn 100))))
(cdr (assoc "SEARCH" (cdr result))))
artlist))))
- (message "Searching %s...done" group))))
+ (gnus-message 7 "Searching %s...done" group))))
(nreverse artlist))))
(cl-defmethod gnus-search-imap-search-command ((engine gnus-search-imap)
@@ -1090,7 +1086,8 @@ Responsible for handling and, or, and parenthetical expressions.")
Currently takes into account support for the LITERAL+ capability.
Other capabilities could be tested here."
(with-slots (literal-plus) engine
- (when literal-plus
+ (when (and literal-plus
+ (string-match-p "\n" query))
(setq query (split-string query "\n")))
(cond
((consp query)
@@ -1240,8 +1237,7 @@ nil (except that (dd nil yyyy) is not allowed). Massage those
numbers into the most recent past occurrence of whichever date
elements are present."
(pcase-let ((`(,nday ,nmonth ,nyear)
- (seq-subseq (decode-time (current-time))
- 3 6))
+ (seq-subseq (decode-time) 3 6))
(`(,dday ,dmonth ,dyear) date))
(unless (and dday dmonth dyear)
(unless dday (setq dday 1))
@@ -1261,9 +1257,7 @@ elements are present."
(setq dmonth 1))))
(format-time-string
"%e-%b-%Y"
- (apply #'encode-time
- (append '(0 0 0)
- (list dday dmonth dyear))))))
+ (encode-time 0 0 0 dday dmonth dyear))))
(cl-defmethod gnus-search-imap-handle-string ((engine gnus-search-imap)
(str string))
@@ -1335,8 +1329,8 @@ Returns a list of [group article score] vectors."
(erase-buffer)
(if groups
- (message "Doing %s query on %s..." program groups)
- (message "Doing %s query..." program))
+ (gnus-message 7 "Doing %s query on %s..." program groups)
+ (gnus-message 7 "Doing %s query..." program))
(setq proc (apply #'start-process (format "search-%s" server)
buffer program cp-list))
(while (process-live-p proc)
@@ -1842,8 +1836,8 @@ Assume \"size\" key is equal to \"larger\"."
(mapcar (lambda (x)
(let ((group x)
artlist)
- (message "Searching %s using find-grep..."
- (or group server))
+ (gnus-message 7 "Searching %s using find-grep..."
+ (or group server))
(save-window-excursion
(set-buffer buffer)
(if (> gnus-verbose 6)
@@ -1898,8 +1892,8 @@ Assume \"size\" key is equal to \"larger\"."
(vector (gnus-group-full-name group server) art 0)
artlist))
(forward-line 1)))
- (message "Searching %s using find-grep...done"
- (or group server))
+ (gnus-message 7 "Searching %s using find-grep...done"
+ (or group server))
artlist)))
grouplist))))
@@ -1932,7 +1926,7 @@ Assume \"size\" key is equal to \"larger\"."
(apply #'nnheader-message 4
"Search engine for %s improperly configured: %s"
server (cdr err))
- (signal 'gnus-search-config-error err)))))
+ (signal (car err) (cdr err))))))
(alist-get 'search-group-spec specs))
;; Some search engines do their own limiting, but some don't, so
;; do it again here. This is bad because, if the user is
diff --git a/lisp/gnus/gnus-sieve.el b/lisp/gnus/gnus-sieve.el
index eeedf7ff35c..d173decbb6a 100644
--- a/lisp/gnus/gnus-sieve.el
+++ b/lisp/gnus/gnus-sieve.el
@@ -61,8 +61,9 @@ For example: \"nnimap:mailbox\""
:type 'boolean)
(defcustom gnus-sieve-update-shell-command "echo put %f | sieveshell %s"
- "Shell command to execute after updating your Sieve script. The following
-formatting characters are recognized:
+ "Shell command to execute after updating your Sieve script.
+
+The following formatting characters are recognized:
%f Script's file name (gnus-sieve-file)
%s Server name (from gnus-sieve-select-method)"
diff --git a/lisp/gnus/gnus-srvr.el b/lisp/gnus/gnus-srvr.el
index 1c75abb6f4b..fa880b7eddb 100644
--- a/lisp/gnus/gnus-srvr.el
+++ b/lisp/gnus/gnus-srvr.el
@@ -103,7 +103,43 @@ If nil, a faster, but more primitive, buffer is used instead."
(defvar gnus-server-mode-line-format-spec nil)
(defvar gnus-server-killed-servers nil)
-(defvar gnus-server-mode-map nil)
+(defvar-keymap gnus-server-mode-map
+ :full t :suppress t
+ "SPC" #'gnus-server-read-server-in-server-buffer
+ "RET" #'gnus-server-read-server
+ "<mouse-2>" #'gnus-server-pick-server
+ "q" #'gnus-server-exit
+ "l" #'gnus-server-list-servers
+ "k" #'gnus-server-kill-server
+ "y" #'gnus-server-yank-server
+ "c" #'gnus-server-copy-server
+ "a" #'gnus-server-add-server
+ "e" #'gnus-server-edit-server
+ "S" #'gnus-server-show-server
+ "s" #'gnus-server-scan-server
+
+ "O" #'gnus-server-open-server
+ "M-o" #'gnus-server-open-all-servers
+ "C" #'gnus-server-close-server
+ "M-c" #'gnus-server-close-all-servers
+ "D" #'gnus-server-deny-server
+ "L" #'gnus-server-offline-server
+ "R" #'gnus-server-remove-denials
+
+ "n" #'next-line
+ "p" #'previous-line
+
+ "g" #'gnus-server-regenerate-server
+
+ "G" #'gnus-group-read-ephemeral-search-group
+
+ "z" #'gnus-server-compact-server
+
+ "i" #'gnus-server-toggle-cloud-server
+ "I" #'gnus-server-set-cloud-method-server
+
+ "C-c C-i" #'gnus-info-find-node
+ "C-c C-b" #'gnus-bug)
(defcustom gnus-server-menu-hook nil
"Hook run after the creation of the server mode menu."
@@ -145,47 +181,6 @@ If nil, a faster, but more primitive, buffer is used instead."
(gnus-run-hooks 'gnus-server-menu-hook)))
-(unless gnus-server-mode-map
- (setq gnus-server-mode-map (make-keymap))
- (suppress-keymap gnus-server-mode-map)
-
- (gnus-define-keys gnus-server-mode-map
- " " gnus-server-read-server-in-server-buffer
- "\r" gnus-server-read-server
- [mouse-2] gnus-server-pick-server
- "q" gnus-server-exit
- "l" gnus-server-list-servers
- "k" gnus-server-kill-server
- "y" gnus-server-yank-server
- "c" gnus-server-copy-server
- "a" gnus-server-add-server
- "e" gnus-server-edit-server
- "S" gnus-server-show-server
- "s" gnus-server-scan-server
-
- "O" gnus-server-open-server
- "\M-o" gnus-server-open-all-servers
- "C" gnus-server-close-server
- "\M-c" gnus-server-close-all-servers
- "D" gnus-server-deny-server
- "L" gnus-server-offline-server
- "R" gnus-server-remove-denials
-
- "n" next-line
- "p" previous-line
-
- "g" gnus-server-regenerate-server
-
- "G" gnus-group-read-ephemeral-search-group
-
- "z" gnus-server-compact-server
-
- "i" gnus-server-toggle-cloud-server
- "I" gnus-server-set-cloud-method-server
-
- "\C-c\C-i" gnus-info-find-node
- "\C-c\C-b" gnus-bug))
-
(defface gnus-server-agent
'((((class color) (background light)) (:foreground "PaleTurquoise" :bold t))
(((class color) (background dark)) (:foreground "PaleTurquoise" :bold t))
@@ -204,7 +199,7 @@ If nil, a faster, but more primitive, buffer is used instead."
'((((class color) (background light)) (:foreground "ForestGreen" :inverse-video t :italic t))
(((class color) (background dark)) (:foreground "PaleGreen" :inverse-video t :italic t))
(t (:inverse-video t :italic t)))
- "Face used for displaying the Cloud Host"
+ "Face used for displaying the Cloud Host."
:group 'gnus-server-visual)
(defface gnus-server-opened
@@ -570,7 +565,7 @@ The following commands are available:
(when (assoc to gnus-server-alist)
(error "%s already exists" to))
(unless (gnus-server-to-method from)
- (error "%s: no such server" from))
+ (error "%s: No such server" from))
(let ((to-entry (cons from (copy-tree
(gnus-server-to-method from)))))
(setcar to-entry to)
@@ -697,37 +692,31 @@ claim them."
function
(repeat function)))
-(defvar gnus-browse-mode-map nil)
-
-(unless gnus-browse-mode-map
- (setq gnus-browse-mode-map (make-keymap))
- (suppress-keymap gnus-browse-mode-map)
-
- (gnus-define-keys
- gnus-browse-mode-map
- " " gnus-browse-read-group
- "=" gnus-browse-select-group
- "n" gnus-browse-next-group
- "p" gnus-browse-prev-group
- "\177" gnus-browse-prev-group
- [delete] gnus-browse-prev-group
- "N" gnus-browse-next-group
- "P" gnus-browse-prev-group
- "\M-n" gnus-browse-next-group
- "\M-p" gnus-browse-prev-group
- "\r" gnus-browse-select-group
- "u" gnus-browse-toggle-subscription-at-point
- "l" gnus-browse-exit
- "L" gnus-browse-exit
- "q" gnus-browse-exit
- "Q" gnus-browse-exit
- "d" gnus-browse-describe-group
- [delete] gnus-browse-delete-group
- "\C-c\C-c" gnus-browse-exit
- "?" gnus-browse-describe-briefly
-
- "\C-c\C-i" gnus-info-find-node
- "\C-c\C-b" gnus-bug))
+(defvar-keymap gnus-browse-mode-map
+ :full t :suppress t
+ "SPC" #'gnus-browse-read-group
+ "=" #'gnus-browse-select-group
+ "n" #'gnus-browse-next-group
+ "p" #'gnus-browse-prev-group
+ "DEL" #'gnus-browse-prev-group
+ "<delete>" #'gnus-browse-prev-group
+ "N" #'gnus-browse-next-group
+ "P" #'gnus-browse-prev-group
+ "M-n" #'gnus-browse-next-group
+ "M-p" #'gnus-browse-prev-group
+ "RET" #'gnus-browse-select-group
+ "u" #'gnus-browse-toggle-subscription-at-point
+ "l" #'gnus-browse-exit
+ "L" #'gnus-browse-exit
+ "q" #'gnus-browse-exit
+ "Q" #'gnus-browse-exit
+ "d" #'gnus-browse-describe-group
+ "<delete>" #'gnus-browse-delete-group
+ "C-c C-c" #'gnus-browse-exit
+ "?" #'gnus-browse-describe-briefly
+
+ "C-c C-i" #'gnus-info-find-node
+ "C-c C-b" #'gnus-bug)
(defun gnus-browse-make-menu-bar ()
(gnus-turn-off-edit-menu 'browse)
@@ -1128,7 +1117,7 @@ Requesting compaction of %s... (this may take a long time)"
(customize-set-variable 'gnus-cloud-method server)
;; Note we can't use `Custom-save' here.
(when (gnus-yes-or-no-p
- (format "The new cloud host server is %S now. Save it? " server))
+ (format "The new cloud host server is `%S' now. Save it?" server))
(customize-save-variable 'gnus-cloud-method server)))
(when (gnus-yes-or-no-p (format "Upload Cloud data to %S now? " server))
(gnus-message 1 "Uploading all data to Emacs Cloud server %S" server)
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el
index 02bbe19e7fe..606bd3a39a4 100644
--- a/lisp/gnus/gnus-start.el
+++ b/lisp/gnus/gnus-start.el
@@ -663,6 +663,7 @@ the first newsgroup."
(defvar mail-sources)
(defvar nnmail-scan-directory-mail-source-once)
(defvar nnmail-split-history)
+(defvar gnus-save-newsrc-file-last-timestamp nil)
(defun gnus-close-all-servers ()
"Close all servers."
@@ -707,6 +708,7 @@ the first newsgroup."
gnus-current-select-method nil
nnmail-split-history nil
gnus-extended-servers nil
+ gnus-save-newsrc-file-last-timestamp nil
gnus-ephemeral-servers nil)
(gnus-shutdown 'gnus)
;; Kill the startup file.
@@ -715,6 +717,9 @@ the first newsgroup."
(kill-buffer (get-file-buffer gnus-current-startup-file)))
;; Clear the dribble buffer.
(gnus-dribble-clear)
+ ;; Reset the level when Gnus is restarted.
+ (when (numberp gnus-group-use-permanent-levels)
+ (setq gnus-group-use-permanent-levels t))
;; Kill global KILL file buffer.
(when (get-file-buffer (gnus-newsgroup-kill-file nil))
(kill-buffer (get-file-buffer (gnus-newsgroup-kill-file nil))))
@@ -1065,9 +1070,9 @@ If no function returns `non-nil', call `gnus-subscribe-zombies'."
Each new newsgroup will be treated with `gnus-subscribe-newsgroup-method'.
The `-n' option line from .newsrc is respected.
-With 1 C-u, use the `ask-server' method to query the server for new
+With 1 \\[universal-argument], use the `ask-server' method to query the server for new
groups.
-With 2 C-u's, use most complete method possible to query the server
+With 2 \\[universal-argument]'s, use most complete method possible to query the server
for new groups, and subscribe the new groups as zombies."
(interactive "p" gnus-group-mode)
(let* ((gnus-subscribe-newsgroup-method
@@ -2337,9 +2342,9 @@ If FORCE is non-nil, the .newsrc file is read."
(defun gnus-convert-mark-converter-prompt (converter no-prompt)
"Indicate whether CONVERTER requires `gnus-convert-old-newsrc' to
- display the conversion prompt. NO-PROMPT may be nil (prompt),
- t (no prompt), or any form that can be called as a function.
- The form should return either t or nil."
+display the conversion prompt. NO-PROMPT may be nil (prompt),
+t (no prompt), or any form that can be called as a function.
+The form should return either t or nil."
(put converter 'gnus-convert-no-prompt no-prompt))
(defun gnus-convert-converter-needs-prompt (converter)
@@ -2728,7 +2733,6 @@ If FORCE is non-nil, the .newsrc file is read."
'msdos-long-file-names
(lambda () t))))
-(defvar gnus-save-newsrc-file-last-timestamp nil)
(defun gnus-save-newsrc-file (&optional force)
"Save .newsrc file.
Use the group string names in `gnus-group-list' to pull info
@@ -2931,7 +2935,7 @@ SPECIFIC-VARIABLES, or those in `gnus-variable-list'."
(nreverse olist)))
(defun gnus-gnus-to-newsrc-format (&optional foreign-ok)
- (interactive (list (gnus-y-or-n-p "write foreign groups too? ")))
+ (interactive (list (gnus-y-or-n-p "Write foreign groups too?")))
;; Generate and save the .newsrc file.
(with-current-buffer (create-file-buffer gnus-current-startup-file)
(let ((standard-output (current-buffer))
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index 856e95c0ba0..1bd0e8847e2 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -1723,8 +1723,7 @@ For example:
\(setq gnus-newsgroup-variables
\\='(message-use-followup-to
(gnus-visible-headers .
- \"^From:\\\\|^Newsgroups:\\\\|^Subject:\\\\|^Date:\\\\|^To:\")))
-")
+ \"^From:\\\\|^Newsgroups:\\\\|^Subject:\\\\|^Date:\\\\|^To:\")))")
(eval-when-compile
;; Bind features so that require will believe that gnus-sum has
@@ -1908,484 +1907,483 @@ increase the score of each group you read."
;; Non-orthogonal keys
-(gnus-define-keys gnus-summary-mode-map
- " " gnus-summary-next-page
- [?\S-\ ] gnus-summary-prev-page
- "\177" gnus-summary-prev-page
- [delete] gnus-summary-prev-page
- "\r" gnus-summary-scroll-up
- "\M-\r" gnus-summary-scroll-down
- "n" gnus-summary-next-unread-article
- "p" gnus-summary-prev-unread-article
- "N" gnus-summary-next-article
- "P" gnus-summary-prev-article
- "\M-\C-n" gnus-summary-next-same-subject
- "\M-\C-p" gnus-summary-prev-same-subject
- "\M-n" gnus-summary-next-unread-subject
- "\M-p" gnus-summary-prev-unread-subject
- "." gnus-summary-first-unread-article
- "," gnus-summary-best-unread-article
- "[" gnus-summary-prev-unseen-article
- "]" gnus-summary-next-unseen-article
- "\M-s\M-s" gnus-summary-search-article-forward
- "\M-s\M-r" gnus-summary-search-article-backward
- "\M-r" gnus-summary-search-article-backward
- "\M-S" gnus-summary-repeat-search-article-forward
- "\M-R" gnus-summary-repeat-search-article-backward
- "<" gnus-summary-beginning-of-article
- ">" gnus-summary-end-of-article
- "j" gnus-summary-goto-article
- "^" gnus-summary-refer-parent-article
- "\M-^" gnus-summary-refer-article
- "u" gnus-summary-tick-article-forward
- "!" gnus-summary-tick-article-forward
- "U" gnus-summary-tick-article-backward
- "d" gnus-summary-mark-as-read-forward
- "D" gnus-summary-mark-as-read-backward
- "E" gnus-summary-mark-as-expirable
- "\M-u" gnus-summary-clear-mark-forward
- "\M-U" gnus-summary-clear-mark-backward
- "k" gnus-summary-kill-same-subject-and-select
- "\C-k" gnus-summary-kill-same-subject
- "\M-\C-k" gnus-summary-kill-thread
- "\M-\C-l" gnus-summary-lower-thread
- "e" gnus-summary-edit-article
- "#" gnus-summary-mark-as-processable
- "\M-#" gnus-summary-unmark-as-processable
- "\M-\C-t" gnus-summary-toggle-threads
- "\M-\C-s" gnus-summary-show-thread
- "\M-\C-h" gnus-summary-hide-thread
- "\M-\C-f" gnus-summary-next-thread
- "\M-\C-b" gnus-summary-prev-thread
- [(meta down)] gnus-summary-next-thread
- [(meta up)] gnus-summary-prev-thread
- "\M-\C-u" gnus-summary-up-thread
- "\M-\C-d" gnus-summary-down-thread
- "&" gnus-summary-execute-command
- "c" gnus-summary-catchup-and-exit
- "\C-w" gnus-summary-mark-region-as-read
- "\C-t" toggle-truncate-lines
- "?" gnus-summary-mark-as-dormant
- "\C-c\M-\C-s" gnus-summary-limit-include-expunged
- "\C-c\C-s\C-n" gnus-summary-sort-by-number
- "\C-c\C-s\C-m\C-n" gnus-summary-sort-by-most-recent-number
- "\C-c\C-s\C-l" gnus-summary-sort-by-lines
- "\C-c\C-s\C-c" gnus-summary-sort-by-chars
- "\C-c\C-s\C-m\C-m" gnus-summary-sort-by-marks
- "\C-c\C-s\C-a" gnus-summary-sort-by-author
- "\C-c\C-s\C-t" gnus-summary-sort-by-recipient
- "\C-c\C-s\C-s" gnus-summary-sort-by-subject
- "\C-c\C-s\C-d" gnus-summary-sort-by-date
- "\C-c\C-s\C-m\C-d" gnus-summary-sort-by-most-recent-date
- "\C-c\C-s\C-i" gnus-summary-sort-by-score
- "\C-c\C-s\C-o" gnus-summary-sort-by-original
- "\C-c\C-s\C-r" gnus-summary-sort-by-random
- "\C-c\C-s\C-u" gnus-summary-sort-by-newsgroups
- "\C-c\C-s\C-x" gnus-summary-sort-by-extra
- "=" gnus-summary-expand-window
- "\C-x\C-s" gnus-summary-reselect-current-group
- "\M-g" gnus-summary-rescan-group
- "\C-c\C-r" gnus-summary-caesar-message
- "f" gnus-summary-followup
- "F" gnus-summary-followup-with-original
- "C" gnus-summary-cancel-article
- "r" gnus-summary-reply
- "R" gnus-summary-reply-with-original
- "\C-c\C-f" gnus-summary-mail-forward
- "o" gnus-summary-save-article
- "\C-o" gnus-summary-save-article-mail
- "|" gnus-summary-pipe-output
- "\M-k" gnus-summary-edit-local-kill
- "\M-K" gnus-summary-edit-global-kill
+(define-keymap :keymap gnus-summary-mode-map
+ "SPC" #'gnus-summary-next-page
+ "S-SPC" #'gnus-summary-prev-page
+ "DEL" #'gnus-summary-prev-page
+ "<delete>" #'gnus-summary-prev-page
+ "RET" #'gnus-summary-scroll-up
+ "M-RET" #'gnus-summary-scroll-down
+ "n" #'gnus-summary-next-unread-article
+ "p" #'gnus-summary-prev-unread-article
+ "N" #'gnus-summary-next-article
+ "P" #'gnus-summary-prev-article
+ "C-M-n" #'gnus-summary-next-same-subject
+ "C-M-p" #'gnus-summary-prev-same-subject
+ "M-n" #'gnus-summary-next-unread-subject
+ "M-p" #'gnus-summary-prev-unread-subject
+ "." #'gnus-summary-first-unread-article
+ "," #'gnus-summary-best-unread-article
+ "[" #'gnus-summary-prev-unseen-article
+ "]" #'gnus-summary-next-unseen-article
+ "M-s M-s" #'gnus-summary-search-article-forward
+ "M-s M-r" #'gnus-summary-search-article-backward
+ "M-r" #'gnus-summary-search-article-backward
+ "M-S" #'gnus-summary-repeat-search-article-forward
+ "M-R" #'gnus-summary-repeat-search-article-backward
+ "<" #'gnus-summary-beginning-of-article
+ ">" #'gnus-summary-end-of-article
+ "j" #'gnus-summary-goto-article
+ "^" #'gnus-summary-refer-parent-article
+ "M-^" #'gnus-summary-refer-article
+ "u" #'gnus-summary-tick-article-forward
+ "!" #'gnus-summary-tick-article-forward
+ "U" #'gnus-summary-tick-article-backward
+ "d" #'gnus-summary-mark-as-read-forward
+ "D" #'gnus-summary-mark-as-read-backward
+ "E" #'gnus-summary-mark-as-expirable
+ "M-u" #'gnus-summary-clear-mark-forward
+ "M-U" #'gnus-summary-clear-mark-backward
+ "k" #'gnus-summary-kill-same-subject-and-select
+ "C-k" #'gnus-summary-kill-same-subject
+ "C-M-k" #'gnus-summary-kill-thread
+ "C-M-l" #'gnus-summary-lower-thread
+ "e" #'gnus-summary-edit-article
+ "#" #'gnus-summary-mark-as-processable
+ "M-#" #'gnus-summary-unmark-as-processable
+ "C-M-t" #'gnus-summary-toggle-threads
+ "C-M-s" #'gnus-summary-show-thread
+ "C-M-h" #'gnus-summary-hide-thread
+ "C-M-f" #'gnus-summary-next-thread
+ "C-M-b" #'gnus-summary-prev-thread
+ "M-<down>" #'gnus-summary-next-thread
+ "M-<up>" #'gnus-summary-prev-thread
+ "C-M-u" #'gnus-summary-up-thread
+ "C-M-d" #'gnus-summary-down-thread
+ "&" #'gnus-summary-execute-command
+ "c" #'gnus-summary-catchup-and-exit
+ "C-w" #'gnus-summary-mark-region-as-read
+ "C-t" #'toggle-truncate-lines
+ "?" #'gnus-summary-mark-as-dormant
+ "C-c C-M-s" #'gnus-summary-limit-include-expunged
+ "C-c C-s C-n" #'gnus-summary-sort-by-number
+ "C-c C-s C-m C-n" #'gnus-summary-sort-by-most-recent-number
+ "C-c C-s C-l" #'gnus-summary-sort-by-lines
+ "C-c C-s C-c" #'gnus-summary-sort-by-chars
+ "C-c C-s C-m C-m" #'gnus-summary-sort-by-marks
+ "C-c C-s C-a" #'gnus-summary-sort-by-author
+ "C-c C-s C-t" #'gnus-summary-sort-by-recipient
+ "C-c C-s C-s" #'gnus-summary-sort-by-subject
+ "C-c C-s C-d" #'gnus-summary-sort-by-date
+ "C-c C-s C-m C-d" #'gnus-summary-sort-by-most-recent-date
+ "C-c C-s C-i" #'gnus-summary-sort-by-score
+ "C-c C-s C-o" #'gnus-summary-sort-by-original
+ "C-c C-s C-r" #'gnus-summary-sort-by-random
+ "C-c C-s C-u" #'gnus-summary-sort-by-newsgroups
+ "C-c C-s C-x" #'gnus-summary-sort-by-extra
+ "=" #'gnus-summary-expand-window
+ "C-x C-s" #'gnus-summary-reselect-current-group
+ "M-g" #'gnus-summary-rescan-group
+ "C-c C-r" #'gnus-summary-caesar-message
+ "f" #'gnus-summary-followup
+ "F" #'gnus-summary-followup-with-original
+ "C" #'gnus-summary-cancel-article
+ "r" #'gnus-summary-reply
+ "R" #'gnus-summary-reply-with-original
+ "C-c C-f" #'gnus-summary-mail-forward
+ "o" #'gnus-summary-save-article
+ "C-o" #'gnus-summary-save-article-mail
+ "|" #'gnus-summary-pipe-output
+ "M-k" #'gnus-summary-edit-local-kill
+ "M-K" #'gnus-summary-edit-global-kill
;; "V" gnus-version
- "\C-c\C-d" gnus-summary-describe-group
- "\C-c\C-p" gnus-summary-make-group-from-search
- "q" gnus-summary-exit
- "Q" gnus-summary-exit-no-update
- "\C-c\C-i" gnus-info-find-node
- [mouse-2] gnus-mouse-pick-article
- [follow-link] mouse-face
- "m" gnus-summary-mail-other-window
- "a" gnus-summary-post-news
- "x" gnus-summary-limit-to-unread
- "s" gnus-summary-isearch-article
- "\t" gnus-summary-button-forward
- [backtab] gnus-summary-button-backward
- "w" gnus-summary-browse-url
- "t" gnus-summary-toggle-header
- "g" gnus-summary-show-article
- "l" gnus-summary-goto-last-article
- "\C-c\C-v\C-v" gnus-uu-decode-uu-view
- "\C-d" gnus-summary-enter-digest-group
- "\M-\C-d" gnus-summary-read-document
- "\M-\C-e" gnus-summary-edit-parameters
- "\M-\C-a" gnus-summary-customize-parameters
- "\C-c\C-b" gnus-bug
- "*" gnus-cache-enter-article
- "\M-*" gnus-cache-remove-article
- "\M-&" gnus-summary-universal-argument
- "\C-l" gnus-recenter
- "I" gnus-summary-increase-score
- "L" gnus-summary-lower-score
- "\M-i" gnus-symbolic-argument
- "h" gnus-summary-select-article-buffer
-
- "b" gnus-article-view-part
- "\M-t" gnus-summary-toggle-display-buttonized
-
- "V" gnus-summary-score-map
- "X" gnus-uu-extract-map
- "S" gnus-summary-send-map)
-
-;; Sort of orthogonal keymap
-(gnus-define-keys (gnus-summary-mark-map "M" gnus-summary-mode-map)
- "t" gnus-summary-tick-article-forward
- "!" gnus-summary-tick-article-forward
- "d" gnus-summary-mark-as-read-forward
- "r" gnus-summary-mark-as-read-forward
- "c" gnus-summary-clear-mark-forward
- " " gnus-summary-clear-mark-forward
- "e" gnus-summary-mark-as-expirable
- "x" gnus-summary-mark-as-expirable
- "?" gnus-summary-mark-as-dormant
- "b" gnus-summary-set-bookmark
- "B" gnus-summary-remove-bookmark
- "#" gnus-summary-mark-as-processable
- "\M-#" gnus-summary-unmark-as-processable
- "S" gnus-summary-limit-include-expunged
- "C" gnus-summary-catchup
- "H" gnus-summary-catchup-to-here
- "h" gnus-summary-catchup-from-here
- "\C-c" gnus-summary-catchup-all
- "k" gnus-summary-kill-same-subject-and-select
- "K" gnus-summary-kill-same-subject
- "P" gnus-uu-mark-map)
-
-(gnus-define-keys (gnus-summary-mscore-map "V" gnus-summary-mark-map)
- "c" gnus-summary-clear-above
- "u" gnus-summary-tick-above
- "m" gnus-summary-mark-above
- "k" gnus-summary-kill-below)
-
-(gnus-define-keys (gnus-summary-limit-map "/" gnus-summary-mode-map)
- "/" gnus-summary-limit-to-subject
- "n" gnus-summary-limit-to-articles
- "b" gnus-summary-limit-to-bodies
- "h" gnus-summary-limit-to-headers
- "w" gnus-summary-pop-limit
- "s" gnus-summary-limit-to-subject
- "a" gnus-summary-limit-to-author
- "u" gnus-summary-limit-to-unread
- "m" gnus-summary-limit-to-marks
- "M" gnus-summary-limit-exclude-marks
- "v" gnus-summary-limit-to-score
- "*" gnus-summary-limit-include-cached
- "D" gnus-summary-limit-include-dormant
- "T" gnus-summary-limit-include-thread
- "d" gnus-summary-limit-exclude-dormant
- "t" gnus-summary-limit-to-age
- "." gnus-summary-limit-to-unseen
- "x" gnus-summary-limit-to-extra
- "p" gnus-summary-limit-to-display-predicate
- "E" gnus-summary-limit-include-expunged
- "c" gnus-summary-limit-exclude-childless-dormant
- "C" gnus-summary-limit-mark-excluded-as-read
- "o" gnus-summary-insert-old-articles
- "N" gnus-summary-insert-new-articles
- "S" gnus-summary-limit-to-singletons
- "r" gnus-summary-limit-to-replied
- "R" gnus-summary-limit-to-recipient
- "A" gnus-summary-limit-to-address)
-
-(gnus-define-keys (gnus-summary-goto-map "G" gnus-summary-mode-map)
- "n" gnus-summary-next-unread-article
- "p" gnus-summary-prev-unread-article
- "N" gnus-summary-next-article
- "P" gnus-summary-prev-article
- "\C-n" gnus-summary-next-same-subject
- "\C-p" gnus-summary-prev-same-subject
- "\M-n" gnus-summary-next-unread-subject
- "\M-p" gnus-summary-prev-unread-subject
- "f" gnus-summary-first-unread-article
- "b" gnus-summary-best-unread-article
- "u" gnus-summary-next-unseen-article
- "U" gnus-summary-prev-unseen-article
- "j" gnus-summary-goto-article
- "g" gnus-summary-goto-subject
- "l" gnus-summary-goto-last-article
- "o" gnus-summary-pop-article)
-
-(gnus-define-keys (gnus-summary-thread-map "T" gnus-summary-mode-map)
- "k" gnus-summary-kill-thread
- "E" gnus-summary-expire-thread
- "l" gnus-summary-lower-thread
- "i" gnus-summary-raise-thread
- "T" gnus-summary-toggle-threads
- "t" gnus-summary-rethread-current
- "^" gnus-summary-reparent-thread
- "\M-^" gnus-summary-reparent-children
- "s" gnus-summary-show-thread
- "S" gnus-summary-show-all-threads
- "h" gnus-summary-hide-thread
- "H" gnus-summary-hide-all-threads
- "n" gnus-summary-next-thread
- "p" gnus-summary-prev-thread
- "u" gnus-summary-up-thread
- "o" gnus-summary-top-thread
- "d" gnus-summary-down-thread
- "#" gnus-uu-mark-thread
- "\M-#" gnus-uu-unmark-thread)
-
-(gnus-define-keys (gnus-summary-buffer-map "Y" gnus-summary-mode-map)
- "g" gnus-summary-prepare
- "c" gnus-summary-insert-cached-articles
- "d" gnus-summary-insert-dormant-articles
- "t" gnus-summary-insert-ticked-articles)
-
-(gnus-define-keys (gnus-summary-exit-map "Z" gnus-summary-mode-map)
- "c" gnus-summary-catchup-and-exit
- "C" gnus-summary-catchup-all-and-exit
- "E" gnus-summary-exit-no-update
- "Q" gnus-summary-exit
- "Z" gnus-summary-exit
- "n" gnus-summary-catchup-and-goto-next-group
- "p" gnus-summary-catchup-and-goto-prev-group
- "R" gnus-summary-reselect-current-group
- "G" gnus-summary-rescan-group
- "N" gnus-summary-next-group
- "s" gnus-summary-save-newsrc
- "P" gnus-summary-prev-group)
-
-(gnus-define-keys (gnus-summary-article-map "A" gnus-summary-mode-map)
- " " gnus-summary-next-page
- "n" gnus-summary-next-page
- [?\S-\ ] gnus-summary-prev-page
- "\177" gnus-summary-prev-page
- [delete] gnus-summary-prev-page
- "p" gnus-summary-prev-page
- "\r" gnus-summary-scroll-up
- "\M-\r" gnus-summary-scroll-down
- "<" gnus-summary-beginning-of-article
- ">" gnus-summary-end-of-article
- "b" gnus-summary-beginning-of-article
- "e" gnus-summary-end-of-article
- "^" gnus-summary-refer-parent-article
- "r" gnus-summary-refer-parent-article
- "C" gnus-summary-show-complete-article
- "D" gnus-summary-enter-digest-group
- "R" gnus-summary-refer-references
- "T" gnus-summary-refer-thread
- "W" gnus-warp-to-article
- "g" gnus-summary-show-article
- "s" gnus-summary-isearch-article
- "\t" gnus-summary-button-forward
- [backtab] gnus-summary-button-backward
- "w" gnus-summary-browse-url
- "P" gnus-summary-print-article
- "S" gnus-sticky-article
- "M" gnus-mailing-list-insinuate
- "t" gnus-article-babel)
-
-(gnus-define-keys (gnus-summary-wash-map "W" gnus-summary-mode-map)
- "b" gnus-article-add-buttons
- "B" gnus-article-add-buttons-to-head
- "o" gnus-article-treat-overstrike
- "e" gnus-article-emphasize
- "w" gnus-article-fill-cited-article
- "Q" gnus-article-fill-long-lines
- "L" gnus-article-toggle-truncate-lines
- "C" gnus-article-capitalize-sentences
- "c" gnus-article-remove-cr
- "q" gnus-article-de-quoted-unreadable
- "6" gnus-article-de-base64-unreadable
- "Z" gnus-article-decode-HZ
- "A" gnus-article-treat-ansi-sequences
- "h" gnus-article-wash-html
- "u" gnus-article-unsplit-urls
- "s" gnus-summary-force-verify-and-decrypt
- "f" gnus-article-display-x-face
- "l" gnus-summary-stop-page-breaking
- "r" gnus-summary-caesar-message
- "m" gnus-summary-morse-message
- "t" gnus-summary-toggle-header
- "g" gnus-treat-smiley
- "v" gnus-summary-verbose-headers
- "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
- "p" gnus-article-verify-x-pgp-sig
- "d" gnus-article-treat-smartquotes
- "U" gnus-article-treat-non-ascii
- "i" gnus-summary-idna-message)
-
-(gnus-define-keys (gnus-summary-wash-deuglify-map "Y" gnus-summary-wash-map)
- ;; mnemonic: deuglif*Y*
- "u" gnus-article-outlook-unwrap-lines
- "a" gnus-article-outlook-repair-attribution
- "c" gnus-article-outlook-rearrange-citation
- "f" gnus-article-outlook-deuglify-article) ;; mnemonic: full deuglify
-
-(gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
- "a" gnus-article-hide
- "h" gnus-article-hide-headers
- "b" gnus-article-hide-boring-headers
- "s" gnus-article-hide-signature
- "c" gnus-article-hide-citation
- "C" gnus-article-hide-citation-in-followups
- "l" gnus-article-hide-list-identifiers
- "B" gnus-article-strip-banner
- "P" gnus-article-hide-pem
- "\C-c" gnus-article-hide-citation-maybe)
-
-(gnus-define-keys (gnus-summary-wash-highlight-map "H" gnus-summary-wash-map)
- "a" gnus-article-highlight
- "h" gnus-article-highlight-headers
- "c" gnus-article-highlight-citation
- "s" gnus-article-highlight-signature)
-
-(gnus-define-keys (gnus-summary-wash-header-map "G" gnus-summary-wash-map)
- "f" gnus-article-treat-fold-headers
- "u" gnus-article-treat-unfold-headers
- "n" gnus-article-treat-fold-newsgroups)
-
-(gnus-define-keys (gnus-summary-wash-display-map "D" gnus-summary-wash-map)
- "x" gnus-article-display-x-face
- "d" gnus-article-display-face
- "s" gnus-treat-smiley
- "D" gnus-article-remove-images
- "W" gnus-article-show-images
- "f" gnus-treat-from-picon
- "m" gnus-treat-mail-picon
- "n" gnus-treat-newsgroups-picon
- "g" gnus-treat-from-gravatar
- "h" gnus-treat-mail-gravatar)
-
-(gnus-define-keys (gnus-summary-wash-mime-map "M" gnus-summary-wash-map)
- "w" gnus-article-decode-mime-words
- "c" gnus-article-decode-charset
- "h" gnus-mime-buttonize-attachments-in-header
- "v" gnus-mime-view-all-parts
- "b" gnus-article-view-part)
-
-(gnus-define-keys (gnus-summary-wash-time-map "T" gnus-summary-wash-map)
- "z" gnus-article-date-ut
- "u" gnus-article-date-ut
- "l" gnus-article-date-local
- "p" gnus-article-date-english
- "e" gnus-article-date-lapsed
- "o" gnus-article-date-original
- "i" gnus-article-date-iso8601
- "s" gnus-article-date-user)
-
-(gnus-define-keys (gnus-summary-wash-empty-map "E" gnus-summary-wash-map)
- "t" gnus-article-remove-trailing-blank-lines
- "l" gnus-article-strip-leading-blank-lines
- "m" gnus-article-strip-multiple-blank-lines
- "a" gnus-article-strip-blank-lines
- "A" gnus-article-strip-all-blank-lines
- "s" gnus-article-strip-leading-space
- "e" gnus-article-strip-trailing-space
- "w" gnus-article-remove-leading-whitespace)
-
-(gnus-define-keys (gnus-summary-help-map "H" gnus-summary-mode-map)
- "v" gnus-version
- "d" gnus-summary-describe-group
- "h" gnus-summary-describe-briefly
- "i" gnus-info-find-node)
-
-(gnus-define-keys (gnus-summary-backend-map "B" gnus-summary-mode-map)
- "e" gnus-summary-expire-articles
- "\M-\C-e" gnus-summary-expire-articles-now
- "\177" gnus-summary-delete-article
- [delete] gnus-summary-delete-article
- [backspace] gnus-summary-delete-article
- "m" gnus-summary-move-article
- "r" gnus-summary-respool-article
- "w" gnus-summary-edit-article
- "c" gnus-summary-copy-article
- "B" gnus-summary-crosspost-article
- "q" gnus-summary-respool-query
- "t" gnus-summary-respool-trace
- "i" gnus-summary-import-article
- "I" gnus-summary-create-article
- "p" gnus-summary-article-posted-p)
-
-(gnus-define-keys (gnus-summary-save-map "O" gnus-summary-mode-map)
- "o" gnus-summary-save-article
- "m" gnus-summary-save-article-mail
- "F" gnus-summary-write-article-file
- "r" gnus-summary-save-article-rmail
- "f" gnus-summary-save-article-file
- "b" gnus-summary-save-article-body-file
- "B" gnus-summary-write-article-body-file
- "h" gnus-summary-save-article-folder
- "v" gnus-summary-save-article-vm
- "p" gnus-summary-pipe-output
- "P" gnus-summary-muttprint)
-
-(gnus-define-keys (gnus-summary-mime-map "K" gnus-summary-mode-map)
- "b" gnus-summary-display-buttonized
- "m" gnus-summary-repair-multipart
- "v" gnus-article-view-part
- "o" gnus-article-save-part
- "O" gnus-article-save-part-and-strip
- "r" gnus-article-replace-part
- "d" gnus-article-delete-part
- "t" gnus-article-view-part-as-type
- "j" gnus-article-jump-to-part
- "c" gnus-article-copy-part
- "C" gnus-article-view-part-as-charset
- "e" gnus-article-view-part-externally
- "H" gnus-article-browse-html-article
- "E" gnus-article-encrypt-body
- "i" gnus-article-inline-part
- "|" gnus-article-pipe-part)
-
-(gnus-define-keys (gnus-uu-mark-map "P" gnus-summary-mark-map)
- "p" gnus-summary-mark-as-processable
- "u" gnus-summary-unmark-as-processable
- "U" gnus-summary-unmark-all-processable
- "v" gnus-uu-mark-over
- "s" gnus-uu-mark-series
- "r" gnus-uu-mark-region
- "g" gnus-uu-unmark-region
- "R" gnus-uu-mark-by-regexp
- "G" gnus-uu-unmark-by-regexp
- "t" gnus-uu-mark-thread
- "T" gnus-uu-unmark-thread
- "a" gnus-uu-mark-all
- "b" gnus-uu-mark-buffer
- "S" gnus-uu-mark-sparse
- "k" gnus-summary-kill-process-mark
- "y" gnus-summary-yank-process-mark
- "w" gnus-summary-save-process-mark
- "i" gnus-uu-invert-processable)
-
-(gnus-define-keys (gnus-uu-extract-map "X" gnus-summary-mode-map)
- ;;"x" gnus-uu-extract-any
- "m" gnus-summary-save-parts
- "u" gnus-uu-decode-uu
- "U" gnus-uu-decode-uu-and-save
- "s" gnus-uu-decode-unshar
- "S" gnus-uu-decode-unshar-and-save
- "o" gnus-uu-decode-save
- "O" gnus-uu-decode-save
- "b" gnus-uu-decode-binhex
- "B" gnus-uu-decode-binhex
- "Y" gnus-uu-decode-yenc
- "p" gnus-uu-decode-postscript
- "P" gnus-uu-decode-postscript-and-save)
-
-(gnus-define-keys
- (gnus-uu-extract-view-map "v" gnus-uu-extract-map)
- "u" gnus-uu-decode-uu-view
- "U" gnus-uu-decode-uu-and-save-view
- "s" gnus-uu-decode-unshar-view
- "S" gnus-uu-decode-unshar-and-save-view
- "o" gnus-uu-decode-save-view
- "O" gnus-uu-decode-save-view
- "b" gnus-uu-decode-binhex-view
- "B" gnus-uu-decode-binhex-view
- "p" gnus-uu-decode-postscript-view
- "P" gnus-uu-decode-postscript-and-save-view)
+ "C-c C-d" #'gnus-summary-describe-group
+ "C-c C-p" #'gnus-summary-make-group-from-search
+ "q" #'gnus-summary-exit
+ "Q" #'gnus-summary-exit-no-update
+ "C-c C-i" #'gnus-info-find-node
+ "<mouse-2>" #'gnus-mouse-pick-article
+ "<follow-link>" 'mouse-face
+ "m" #'gnus-summary-mail-other-window
+ "a" #'gnus-summary-post-news
+ "x" #'gnus-summary-limit-to-unread
+ "s" #'gnus-summary-isearch-article
+ "TAB" #'gnus-summary-button-forward
+ "<backtab>" #'gnus-summary-button-backward
+ "w" #'gnus-summary-browse-url
+ "t" #'gnus-summary-toggle-header
+ "g" #'gnus-summary-show-article
+ "l" #'gnus-summary-goto-last-article
+ "C-c C-v C-v" #'gnus-uu-decode-uu-view
+ "C-d" #'gnus-summary-enter-digest-group
+ "C-M-d" #'gnus-summary-read-document
+ "C-M-e" #'gnus-summary-edit-parameters
+ "C-M-a" #'gnus-summary-customize-parameters
+ "C-c C-b" #'gnus-bug
+ "*" #'gnus-cache-enter-article
+ "M-*" #'gnus-cache-remove-article
+ "M-&" #'gnus-summary-universal-argument
+ "C-l" #'gnus-recenter
+ "I" #'gnus-summary-increase-score
+ "L" #'gnus-summary-lower-score
+ "M-i" #'gnus-symbolic-argument
+ "h" #'gnus-summary-select-article-buffer
+
+ "b" #'gnus-article-view-part
+ "M-t" #'gnus-summary-toggle-display-buttonized
+
+ "S" #'gnus-summary-send-map
+
+ ;; Sort of orthogonal keymaps.
+ "M" (define-keymap :prefix 'gnus-summary-mark-map
+ "t" #'gnus-summary-tick-article-forward
+ "!" #'gnus-summary-tick-article-forward
+ "d" #'gnus-summary-mark-as-read-forward
+ "r" #'gnus-summary-mark-as-read-forward
+ "c" #'gnus-summary-clear-mark-forward
+ "SPC" #'gnus-summary-clear-mark-forward
+ "e" #'gnus-summary-mark-as-expirable
+ "x" #'gnus-summary-mark-as-expirable
+ "?" #'gnus-summary-mark-as-dormant
+ "b" #'gnus-summary-set-bookmark
+ "B" #'gnus-summary-remove-bookmark
+ "#" #'gnus-summary-mark-as-processable
+ "M-#" #'gnus-summary-unmark-as-processable
+ "S" #'gnus-summary-limit-include-expunged
+ "C" #'gnus-summary-catchup
+ "H" #'gnus-summary-catchup-to-here
+ "h" #'gnus-summary-catchup-from-here
+ "C-c" #'gnus-summary-catchup-all
+ "k" #'gnus-summary-kill-same-subject-and-select
+ "K" #'gnus-summary-kill-same-subject
+
+ "P" (define-keymap :prefix 'gnus-uu-mark-map
+ "p" #'gnus-summary-mark-as-processable
+ "u" #'gnus-summary-unmark-as-processable
+ "U" #'gnus-summary-unmark-all-processable
+ "v" #'gnus-uu-mark-over
+ "s" #'gnus-uu-mark-series
+ "r" #'gnus-uu-mark-region
+ "g" #'gnus-uu-unmark-region
+ "R" #'gnus-uu-mark-by-regexp
+ "G" #'gnus-uu-unmark-by-regexp
+ "t" #'gnus-uu-mark-thread
+ "T" #'gnus-uu-unmark-thread
+ "a" #'gnus-uu-mark-all
+ "b" #'gnus-uu-mark-buffer
+ "S" #'gnus-uu-mark-sparse
+ "k" #'gnus-summary-kill-process-mark
+ "y" #'gnus-summary-yank-process-mark
+ "w" #'gnus-summary-save-process-mark
+ "i" #'gnus-uu-invert-processable)
+
+ "V" (define-keymap :prefix 'gnus-summary-mscore-map
+ "c" #'gnus-summary-clear-above
+ "u" #'gnus-summary-tick-above
+ "m" #'gnus-summary-mark-above
+ "k" #'gnus-summary-kill-below))
+
+ "/" (define-keymap :prefix 'gnus-summary-limit-map
+ "/" #'gnus-summary-limit-to-subject
+ "n" #'gnus-summary-limit-to-articles
+ "b" #'gnus-summary-limit-to-bodies
+ "h" #'gnus-summary-limit-to-headers
+ "w" #'gnus-summary-pop-limit
+ "s" #'gnus-summary-limit-to-subject
+ "a" #'gnus-summary-limit-to-author
+ "u" #'gnus-summary-limit-to-unread
+ "m" #'gnus-summary-limit-to-marks
+ "M" #'gnus-summary-limit-exclude-marks
+ "v" #'gnus-summary-limit-to-score
+ "*" #'gnus-summary-limit-include-cached
+ "D" #'gnus-summary-limit-include-dormant
+ "T" #'gnus-summary-limit-include-thread
+ "d" #'gnus-summary-limit-exclude-dormant
+ "t" #'gnus-summary-limit-to-age
+ "." #'gnus-summary-limit-to-unseen
+ "x" #'gnus-summary-limit-to-extra
+ "p" #'gnus-summary-limit-to-display-predicate
+ "E" #'gnus-summary-limit-include-expunged
+ "c" #'gnus-summary-limit-exclude-childless-dormant
+ "C" #'gnus-summary-limit-mark-excluded-as-read
+ "o" #'gnus-summary-insert-old-articles
+ "N" #'gnus-summary-insert-new-articles
+ "S" #'gnus-summary-limit-to-singletons
+ "r" #'gnus-summary-limit-to-replied
+ "R" #'gnus-summary-limit-to-recipient
+ "A" #'gnus-summary-limit-to-address)
+
+ "G" (define-keymap :prefix 'gnus-summary-goto-map
+ "n" #'gnus-summary-next-unread-article
+ "p" #'gnus-summary-prev-unread-article
+ "N" #'gnus-summary-next-article
+ "P" #'gnus-summary-prev-article
+ "C-n" #'gnus-summary-next-same-subject
+ "C-p" #'gnus-summary-prev-same-subject
+ "M-n" #'gnus-summary-next-unread-subject
+ "M-p" #'gnus-summary-prev-unread-subject
+ "f" #'gnus-summary-first-unread-article
+ "b" #'gnus-summary-best-unread-article
+ "u" #'gnus-summary-next-unseen-article
+ "U" #'gnus-summary-prev-unseen-article
+ "j" #'gnus-summary-goto-article
+ "g" #'gnus-summary-goto-subject
+ "l" #'gnus-summary-goto-last-article
+ "o" #'gnus-summary-pop-article)
+
+ "T" (define-keymap :prefix 'gnus-summary-thread-map
+ "k" #'gnus-summary-kill-thread
+ "E" #'gnus-summary-expire-thread
+ "l" #'gnus-summary-lower-thread
+ "i" #'gnus-summary-raise-thread
+ "T" #'gnus-summary-toggle-threads
+ "t" #'gnus-summary-rethread-current
+ "^" #'gnus-summary-reparent-thread
+ "M-^" #'gnus-summary-reparent-children
+ "s" #'gnus-summary-show-thread
+ "S" #'gnus-summary-show-all-threads
+ "h" #'gnus-summary-hide-thread
+ "H" #'gnus-summary-hide-all-threads
+ "n" #'gnus-summary-next-thread
+ "p" #'gnus-summary-prev-thread
+ "u" #'gnus-summary-up-thread
+ "o" #'gnus-summary-top-thread
+ "d" #'gnus-summary-down-thread
+ "#" #'gnus-uu-mark-thread
+ "M-#" #'gnus-uu-unmark-thread)
+
+ "Y" (define-keymap :prefix 'gnus-summary-buffer-map
+ "g" #'gnus-summary-prepare
+ "c" #'gnus-summary-insert-cached-articles
+ "d" #'gnus-summary-insert-dormant-articles
+ "t" #'gnus-summary-insert-ticked-articles)
+
+ "Z" (define-keymap :prefix 'gnus-summary-exit-map
+ "c" #'gnus-summary-catchup-and-exit
+ "C" #'gnus-summary-catchup-all-and-exit
+ "E" #'gnus-summary-exit-no-update
+ "Q" #'gnus-summary-exit
+ "Z" #'gnus-summary-exit
+ "n" #'gnus-summary-catchup-and-goto-next-group
+ "p" #'gnus-summary-catchup-and-goto-prev-group
+ "R" #'gnus-summary-reselect-current-group
+ "G" #'gnus-summary-rescan-group
+ "N" #'gnus-summary-next-group
+ "s" #'gnus-summary-save-newsrc
+ "P" #'gnus-summary-prev-group)
+
+ "A" (define-keymap :prefix 'gnus-summary-article-map
+ "SPC" #'gnus-summary-next-page
+ "n" #'gnus-summary-next-page
+ "S-SPC" #'gnus-summary-prev-page
+ "DEL" #'gnus-summary-prev-page
+ "<delete>" #'gnus-summary-prev-page
+ "p" #'gnus-summary-prev-page
+ "RET" #'gnus-summary-scroll-up
+ "M-RET" #'gnus-summary-scroll-down
+ "<" #'gnus-summary-beginning-of-article
+ ">" #'gnus-summary-end-of-article
+ "b" #'gnus-summary-beginning-of-article
+ "e" #'gnus-summary-end-of-article
+ "^" #'gnus-summary-refer-parent-article
+ "r" #'gnus-summary-refer-parent-article
+ "C" #'gnus-summary-show-complete-article
+ "D" #'gnus-summary-enter-digest-group
+ "R" #'gnus-summary-refer-references
+ "T" #'gnus-summary-refer-thread
+ "W" #'gnus-warp-to-article
+ "g" #'gnus-summary-show-article
+ "s" #'gnus-summary-isearch-article
+ "TAB" #'gnus-summary-button-forward
+ "<backtab>" #'gnus-summary-button-backward
+ "w" #'gnus-summary-browse-url
+ "P" #'gnus-summary-print-article
+ "S" #'gnus-sticky-article
+ "M" #'gnus-mailing-list-insinuate
+ "t" #'gnus-article-babel)
+
+ "W" (define-keymap :prefix 'gnus-summary-wash-map
+ "b" #'gnus-article-add-buttons
+ "B" #'gnus-article-add-buttons-to-head
+ "o" #'gnus-article-treat-overstrike
+ "e" #'gnus-article-emphasize
+ "w" #'gnus-article-fill-cited-article
+ "Q" #'gnus-article-fill-long-lines
+ "L" #'gnus-article-toggle-truncate-lines
+ "C" #'gnus-article-capitalize-sentences
+ "c" #'gnus-article-remove-cr
+ "q" #'gnus-article-de-quoted-unreadable
+ "6" #'gnus-article-de-base64-unreadable
+ "Z" #'gnus-article-decode-HZ
+ "A" #'gnus-article-treat-ansi-sequences
+ "h" #'gnus-article-wash-html
+ "u" #'gnus-article-unsplit-urls
+ "s" #'gnus-summary-force-verify-and-decrypt
+ "f" #'gnus-article-display-x-face
+ "l" #'gnus-summary-stop-page-breaking
+ "r" #'gnus-summary-caesar-message
+ "m" #'gnus-summary-morse-message
+ "t" #'gnus-summary-toggle-header
+ "g" #'gnus-treat-smiley
+ "v" #'gnus-summary-verbose-headers
+ "a" #'gnus-article-strip-headers-in-body ;; mnemonic: wash archive
+ "p" #'gnus-article-verify-x-pgp-sig
+ "d" #'gnus-article-treat-smartquotes
+ "U" #'gnus-article-treat-non-ascii
+ "i" #'gnus-summary-idna-message
+
+ "Y" (define-keymap :prefix 'gnus-summary-wash-deuglify-map
+ ;; mnemonic: deuglif*Y*
+ "u" #'gnus-article-outlook-unwrap-lines
+ "a" #'gnus-article-outlook-repair-attribution
+ "c" #'gnus-article-outlook-rearrange-citation
+ ;; mnemonic: full deuglify
+ "f" #'gnus-article-outlook-deuglify-article)
+
+ "W" (define-keymap :prefix 'gnus-summary-wash-hide-map
+ "a" #'gnus-article-hide
+ "h" #'gnus-article-hide-headers
+ "b" #'gnus-article-hide-boring-headers
+ "s" #'gnus-article-hide-signature
+ "c" #'gnus-article-hide-citation
+ "C" #'gnus-article-hide-citation-in-followups
+ "l" #'gnus-article-hide-list-identifiers
+ "B" #'gnus-article-strip-banner
+ "P" #'gnus-article-hide-pem
+ "C-c" #'gnus-article-hide-citation-maybe)
+
+ "H" (define-keymap :prefix 'gnus-summary-wash-highlight-map
+ "a" #'gnus-article-highlight
+ "h" #'gnus-article-highlight-headers
+ "c" #'gnus-article-highlight-citation
+ "s" #'gnus-article-highlight-signature)
+
+ "G" (define-keymap :prefix 'gnus-summary-wash-header-map
+ "f" #'gnus-article-treat-fold-headers
+ "u" #'gnus-article-treat-unfold-headers
+ "n" #'gnus-article-treat-fold-newsgroups)
+
+ "D" (define-keymap :prefix 'gnus-summary-wash-display-map
+ "x" #'gnus-article-display-x-face
+ "d" #'gnus-article-display-face
+ "s" #'gnus-treat-smiley
+ "e" #'gnus-article-emojize-symbols
+ "D" #'gnus-article-remove-images
+ "W" #'gnus-article-show-images
+ "F" #'gnus-article-toggle-fonts
+ "f" #'gnus-treat-from-picon
+ "m" #'gnus-treat-mail-picon
+ "n" #'gnus-treat-newsgroups-picon
+ "g" #'gnus-treat-from-gravatar
+ "h" #'gnus-treat-mail-gravatar)
+
+ "M" (define-keymap :prefix 'gnus-summary-wash-mime-map
+ "w" #'gnus-article-decode-mime-words
+ "c" #'gnus-article-decode-charset
+ "h" #'gnus-mime-buttonize-attachments-in-header
+ "v" #'gnus-mime-view-all-parts
+ "b" #'gnus-article-view-part)
+
+ "T" (define-keymap :prefix 'gnus-summary-wash-time-map
+ "z" #'gnus-article-date-ut
+ "u" #'gnus-article-date-ut
+ "l" #'gnus-article-date-local
+ "p" #'gnus-article-date-english
+ "e" #'gnus-article-date-lapsed
+ "o" #'gnus-article-date-original
+ "i" #'gnus-article-date-iso8601
+ "s" #'gnus-article-date-user)
+
+ "E" (define-keymap :prefix 'gnus-summary-wash-empty-map
+ "t" #'gnus-article-remove-trailing-blank-lines
+ "l" #'gnus-article-strip-leading-blank-lines
+ "m" #'gnus-article-strip-multiple-blank-lines
+ "a" #'gnus-article-strip-blank-lines
+ "A" #'gnus-article-strip-all-blank-lines
+ "s" #'gnus-article-strip-leading-space
+ "e" #'gnus-article-strip-trailing-space
+ "w" #'gnus-article-remove-leading-whitespace))
+
+ "H" (define-keymap :prefix 'gnus-summary-help-map
+ "v" #'gnus-version
+ "d" #'gnus-summary-describe-group
+ "h" #'gnus-summary-describe-briefly
+ "i" #'gnus-info-find-node)
+
+ "B" (define-keymap :prefix 'gnus-summary-backend-map
+ "e" #'gnus-summary-expire-articles
+ "C-M-e" #'gnus-summary-expire-articles-now
+ "DEL" #'gnus-summary-delete-article
+ "<delete>" #'gnus-summary-delete-article
+ "<backspace>" #'gnus-summary-delete-article
+ "m" #'gnus-summary-move-article
+ "r" #'gnus-summary-respool-article
+ "w" #'gnus-summary-edit-article
+ "c" #'gnus-summary-copy-article
+ "B" #'gnus-summary-crosspost-article
+ "q" #'gnus-summary-respool-query
+ "t" #'gnus-summary-respool-trace
+ "i" #'gnus-summary-import-article
+ "I" #'gnus-summary-create-article
+ "p" #'gnus-summary-article-posted-p)
+
+ "O" (define-keymap :prefix 'gnus-summary-save-map
+ "o" #'gnus-summary-save-article
+ "m" #'gnus-summary-save-article-mail
+ "F" #'gnus-summary-write-article-file
+ "r" #'gnus-summary-save-article-rmail
+ "f" #'gnus-summary-save-article-file
+ "b" #'gnus-summary-save-article-body-file
+ "B" #'gnus-summary-write-article-body-file
+ "h" #'gnus-summary-save-article-folder
+ "v" #'gnus-summary-save-article-vm
+ "p" #'gnus-summary-pipe-output
+ "P" #'gnus-summary-muttprint)
+
+ "K" (define-keymap :prefix 'gnus-summary-mime-map
+ "b" #'gnus-summary-display-buttonized
+ "m" #'gnus-summary-repair-multipart
+ "v" #'gnus-article-view-part
+ "o" #'gnus-article-save-part
+ "O" #'gnus-article-save-part-and-strip
+ "r" #'gnus-article-replace-part
+ "d" #'gnus-article-delete-part
+ "t" #'gnus-article-view-part-as-type
+ "j" #'gnus-article-jump-to-part
+ "c" #'gnus-article-copy-part
+ "C" #'gnus-article-view-part-as-charset
+ "e" #'gnus-article-view-part-externally
+ "H" #'gnus-article-browse-html-article
+ "E" #'gnus-article-encrypt-body
+ "i" #'gnus-article-inline-part
+ "|" #'gnus-article-pipe-part)
+
+ "X" (define-keymap :prefix 'gnus-uu-extract-map
+ ;;"x" gnus-uu-extract-any
+ "m" #'gnus-summary-save-parts
+ "u" #'gnus-uu-decode-uu
+ "U" #'gnus-uu-decode-uu-and-save
+ "s" #'gnus-uu-decode-unshar
+ "S" #'gnus-uu-decode-unshar-and-save
+ "o" #'gnus-uu-decode-save
+ "O" #'gnus-uu-decode-save
+ "b" #'gnus-uu-decode-binhex
+ "B" #'gnus-uu-decode-binhex
+ "Y" #'gnus-uu-decode-yenc
+ "p" #'gnus-uu-decode-postscript
+ "P" #'gnus-uu-decode-postscript-and-save
+
+ "v" (define-keymap :prefix 'gnus-uu-extract-view-map
+ "u" #'gnus-uu-decode-uu-view
+ "U" #'gnus-uu-decode-uu-and-save-view
+ "s" #'gnus-uu-decode-unshar-view
+ "S" #'gnus-uu-decode-unshar-and-save-view
+ "o" #'gnus-uu-decode-save-view
+ "O" #'gnus-uu-decode-save-view
+ "b" #'gnus-uu-decode-binhex-view
+ "B" #'gnus-uu-decode-binhex-view
+ "p" #'gnus-uu-decode-postscript-view
+ "P" #'gnus-uu-decode-postscript-and-save-view)))
(defvar gnus-article-post-menu nil)
@@ -2561,6 +2559,7 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs))))
["Unfold headers" gnus-article-treat-unfold-headers t]
["Fold newsgroups" gnus-article-treat-fold-newsgroups t]
["Html" gnus-article-wash-html t]
+ ["Toggle HTML fonts" gnus-article-toggle-fonts t]
["Unsplit URLs" gnus-article-unsplit-urls t]
["Verify X-PGP-Sig" gnus-article-verify-x-pgp-sig t]
["Decode HZ" gnus-article-decode-HZ t]
@@ -3144,8 +3143,9 @@ You can also post articles and send mail from this buffer. To
follow up an article, type `\\[gnus-summary-followup]'. To mail a reply to the author
of an article, type `\\[gnus-summary-reply]'.
-There are approx. one gazillion commands you can execute in this
-buffer; read the Info manual for more information (`\\[gnus-info-find-node]').
+There are approximately one gazillion commands you can execute in
+this buffer; read the Info manual for more
+information (`\\[gnus-info-find-node]').
The following commands are available:
@@ -3968,10 +3968,9 @@ Returns \" ? \" if there's bad input or if another error occurs.
Input should look like this: \"Sun, 14 Oct 2001 13:34:39 +0200\"."
(condition-case ()
(let* ((messy-date (gnus-date-get-time messy-date))
- (now (current-time))
;;If we don't find something suitable we'll use this one
(my-format "%b %d '%y"))
- (let* ((difference (time-subtract now messy-date))
+ (let* ((difference (time-subtract nil messy-date))
(templist gnus-user-date-format-alist)
(top (eval (caar templist) t)))
(while (if (numberp top) (time-less-p top difference) (not top))
@@ -4355,7 +4354,8 @@ If SELECT-ARTICLES, only select those articles from GROUP."
result))
(defun gnus-sort-gathered-threads (threads)
- "Sort subthreads inside each gathered thread by `gnus-sort-gathered-threads-function'."
+ "Sort subthreads inside each gathered thread.
+Sorting is done by `gnus-sort-gathered-threads-function'."
(let ((result threads))
(while threads
(when (stringp (caar threads))
@@ -5001,23 +5001,13 @@ If LINE, insert the rebuilt thread starting on line LINE."
gnus-article-sort-functions)))
(gnus-message 7 "Sorting articles...done"))))
-;; Written by Hallvard B Furuseth <h.b.furuseth@usit.uio.no>.
-(defmacro gnus-thread-header (thread)
- "Return header of first article in THREAD.
-Note that THREAD must never, ever be anything else than a variable -
-using some other form will lead to serious barfage."
- (or (symbolp thread) (signal 'wrong-type-argument '(symbolp thread)))
- ;; (8% speedup to gnus-summary-prepare, just for fun :-)
- (cond
- ((and (boundp 'lexical-binding) lexical-binding)
- ;; FIXME: This version could be a "defsubst" rather than a macro.
- `(#[257 "\211:\203\16\0\211@;\203\15\0A@@\207"
- [] 2]
- ,thread))
- (t
- ;; Not sure how XEmacs handles these things, so let's keep the old code.
- (list 'byte-code "\10\211:\203\17\0\211@;\203\16\0A@@\207"
- (vector thread) 2))))
+(defsubst gnus-thread-header (thread)
+ "Return header of first article in THREAD."
+ (if (consp thread)
+ (car (if (stringp (car thread))
+ (cadr thread)
+ thread))
+ thread))
(defsubst gnus-article-sort-by-number (h1 h2)
"Sort articles by article number."
@@ -5171,7 +5161,7 @@ Unscored articles will be counted as having a score of zero."
(gnus-article-sort-by-number h1 h2))
(defun gnus-thread-sort-by-most-recent-number (h1 h2)
- "Sort threads such that the thread with the most recently arrived article comes first."
+ "Sort threads such that the thread with most recently arrived article is first."
(> (gnus-thread-highest-number h1) (gnus-thread-highest-number h2)))
(defun gnus-thread-highest-number (thread)
@@ -5185,7 +5175,7 @@ Unscored articles will be counted as having a score of zero."
(gnus-article-sort-by-date h1 h2))
(defun gnus-thread-sort-by-most-recent-date (h1 h2)
- "Sort threads such that the thread with the most recently dated article comes first."
+ "Sort threads such that the thread with most recently dated article is first."
(> (gnus-thread-latest-date h1) (gnus-thread-latest-date h2)))
(defsubst gnus-article-sort-by-newsgroups (h1 h2)
@@ -5649,7 +5639,7 @@ or a straight list of headers."
gnus-list-identifiers)))
(defun gnus-summary-remove-list-identifiers ()
- "Remove list identifiers in `gnus-list-identifiers' from articles in the current group."
+ "Remove identifiers in `gnus-list-identifiers' from articles in current group."
(let ((regexp (gnus-group-get-list-identifiers gnus-newsgroup-name))
changed subject)
(when regexp
@@ -6841,7 +6831,7 @@ Also do horizontal recentering."
(defun gnus-forward-line-ignore-invisible (n)
"Move N lines forward (backward if N is negative).
-Like forward-line, but skip over (and don't count) invisible lines."
+Like `forward-line', but skip over (and don't count) invisible lines."
(let (done)
(while (and (> n 0) (not done))
;; If the following character is currently invisible,
@@ -7205,7 +7195,6 @@ If FORCE (the prefix), also save the .newsrc file(s)."
(gnus-dribble-save)))
(declare-function gnus-cache-write-active "gnus-cache" (&optional force))
-(declare-function gnus-article-stop-animations "gnus-art" ())
(defun gnus-summary-exit (&optional temporary leave-hidden)
"Exit reading current newsgroup, and then return to group selection mode.
@@ -7269,7 +7258,6 @@ If FORCE (the prefix), also save the .newsrc file(s)."
(not (string= group (gnus-group-group-name))))
(gnus-group-next-unread-group 1))
(setq group-point (point))
- (gnus-article-stop-animations)
(unless leave-hidden
(gnus-configure-windows 'group 'force))
(if temporary
@@ -7329,7 +7317,6 @@ If FORCE (the prefix), also save the .newsrc file(s)."
(run-hooks 'gnus-summary-prepare-exit-hook)
(when (gnus-buffer-live-p gnus-article-buffer)
(with-current-buffer gnus-article-buffer
- (gnus-article-stop-animations)
(gnus-stop-downloads)
(mm-destroy-parts gnus-article-mime-handles)
;; Set it to nil for safety reason.
@@ -7361,7 +7348,6 @@ If FORCE (the prefix), also save the .newsrc file(s)."
(gnus-group-update-group group nil t))
(when (gnus-group-goto-group group)
(gnus-group-next-unread-group 1))
- (gnus-article-stop-animations)
(when quit-config
(gnus-handle-ephemeral-exit quit-config)))))
@@ -8064,9 +8050,7 @@ Return nil if there are no unread articles."
Return nil if there are no unread articles."
(interactive nil gnus-summary-mode)
(prog1
- (when (gnus-summary-first-subject t)
- (gnus-summary-show-thread)
- (gnus-summary-first-subject t))
+ (gnus-summary--goto-and-possibly-unhide t)
(gnus-summary-position-point)))
(defun gnus-summary-next-unseen-article (&optional backward)
@@ -8100,23 +8084,27 @@ Return nil if there are no unread articles."
Return nil if there are no unseen articles."
(interactive nil gnus-summary-mode)
(prog1
- (when (gnus-summary-first-subject nil nil t)
- (gnus-summary-show-thread)
- (gnus-summary-first-subject nil nil t))
+ (gnus-summary--goto-and-possibly-unhide)
(gnus-summary-position-point)))
+(defun gnus-summary--goto-and-possibly-unhide (&optional unread undownloaded
+ unseen)
+ (let ((first (gnus-summary-first-subject unread undownloaded unseen)))
+ (if (and first
+ (not (= first (gnus-summary-article-number))))
+ (progn
+ (gnus-summary-show-thread)
+ (gnus-summary-first-subject unread undownloaded unseen))
+ first)))
+
(defun gnus-summary-first-unseen-or-unread-subject ()
"Place the point on the subject line of the first unseen and unread article.
If all articles have been seen, on the subject line of the first unread
article."
(interactive nil gnus-summary-mode)
(prog1
- (unless (when (gnus-summary-first-subject nil nil t)
- (gnus-summary-show-thread)
- (gnus-summary-first-subject nil nil t))
- (when (gnus-summary-first-subject t)
- (gnus-summary-show-thread)
- (gnus-summary-first-subject t)))
+ (unless (gnus-summary--goto-and-possibly-unhide nil nil t)
+ (gnus-summary-first-subject t))
(gnus-summary-position-point)))
(defun gnus-summary-first-article ()
@@ -8587,9 +8575,8 @@ If UNREPLIED (the prefix), limit to unreplied articles."
(interactive "P" gnus-summary-mode)
(if unreplied
(gnus-summary-limit
- (seq-difference gnus-newsgroup-articles
- gnus-newsgroup-replied
- #'eq))
+ (gnus-set-difference gnus-newsgroup-articles
+ gnus-newsgroup-replied))
(gnus-summary-limit gnus-newsgroup-replied))
(gnus-summary-position-point))
@@ -9837,11 +9824,11 @@ article currently."
"Force redisplaying of the current article.
If ARG (the prefix) is a number, show the article with the charset
defined in `gnus-summary-show-article-charset-alist', or the charset
-input.
+input.\\<gnus-summary-mode-map>
If ARG (the prefix) is non-nil and not a number, show the article,
but without running any of the article treatment functions
-article. Normally, the keystroke is `C-u g'. When using `C-u
-C-u g', show the raw article."
+article. Normally, the keystroke is `\\[universal-argument] \\[gnus-summary-show-article]'. When using `\\[universal-argument]
+\\[universal-argument] \\[gnus-summary-show-article]', show the raw article."
(interactive "P" gnus-summary-mode)
(cond
((numberp arg)
@@ -9906,7 +9893,6 @@ C-u g', show the raw article."
;; Destroy any MIME parts.
(when (gnus-buffer-live-p gnus-article-buffer)
(with-current-buffer gnus-article-buffer
- (gnus-article-stop-animations)
(gnus-stop-downloads)
(mm-destroy-parts gnus-article-mime-handles)
;; Set it to nil for safety reason.
@@ -10499,7 +10485,6 @@ latter case, they will be copied into the relevant groups."
"Create an article in a mail newsgroup."
(interactive nil gnus-summary-mode)
(let ((group gnus-newsgroup-name)
- (now (current-time))
group-art)
(unless (gnus-check-backend-function 'request-accept-article group)
(error "%s does not support article importing" group))
@@ -10509,7 +10494,7 @@ latter case, they will be copied into the relevant groups."
;; This doesn't look like an article, so we fudge some headers.
(insert "From: " (read-string "From: ") "\n"
"Subject: " (read-string "Subject: ") "\n"
- "Date: " (message-make-date now) "\n"
+ "Date: " (message-make-date) "\n"
"Message-ID: " (message-make-message-id) "\n")
(setq group-art (gnus-request-accept-article group nil t))
(kill-buffer (current-buffer)))
diff --git a/lisp/gnus/gnus-topic.el b/lisp/gnus/gnus-topic.el
index c8bcccdfdde..0855e98917f 100644
--- a/lisp/gnus/gnus-topic.el
+++ b/lisp/gnus/gnus-topic.el
@@ -1056,63 +1056,56 @@ articles in the topic and its subtopics."
;;; Topic mode, commands and keymap.
-(defvar gnus-topic-mode-map nil)
-(defvar gnus-group-topic-map nil)
-
-(unless gnus-topic-mode-map
- (setq gnus-topic-mode-map (make-sparse-keymap))
-
+(defvar-keymap gnus-topic-mode-map
;; Override certain group mode keys.
- (gnus-define-keys gnus-topic-mode-map
- "=" gnus-topic-select-group
- "\r" gnus-topic-select-group
- " " gnus-topic-read-group
- "\C-c\C-x" gnus-topic-expire-articles
- "c" gnus-topic-catchup-articles
- "\C-k" gnus-topic-kill-group
- "\C-y" gnus-topic-yank-group
- "\M-g" gnus-topic-get-new-news-this-topic
- "AT" gnus-topic-list-active
- "Gp" gnus-topic-edit-parameters
- "#" gnus-topic-mark-topic
- "\M-#" gnus-topic-unmark-topic
- [tab] gnus-topic-indent
- [(meta tab)] gnus-topic-unindent
- "\C-i" gnus-topic-indent
- "\M-\C-i" gnus-topic-unindent
- [mouse-2] gnus-mouse-pick-topic)
-
- ;; Define a new submap.
- (gnus-define-keys (gnus-group-topic-map "T" gnus-group-mode-map)
- "#" gnus-topic-mark-topic
- "\M-#" gnus-topic-unmark-topic
- "n" gnus-topic-create-topic
- "m" gnus-topic-move-group
- "D" gnus-topic-remove-group
- "c" gnus-topic-copy-group
- "h" gnus-topic-hide-topic
- "s" gnus-topic-show-topic
- "j" gnus-topic-jump-to-topic
- "M" gnus-topic-move-matching
- "C" gnus-topic-copy-matching
- "\M-p" gnus-topic-goto-previous-topic
- "\M-n" gnus-topic-goto-next-topic
- "\C-i" gnus-topic-indent
- [tab] gnus-topic-indent
- "r" gnus-topic-rename
- "\177" gnus-topic-delete
- [delete] gnus-topic-delete
- "H" gnus-topic-toggle-display-empty-topics)
-
- (gnus-define-keys (gnus-topic-sort-map "S" gnus-group-topic-map)
- "s" gnus-topic-sort-groups
- "a" gnus-topic-sort-groups-by-alphabet
- "u" gnus-topic-sort-groups-by-unread
- "l" gnus-topic-sort-groups-by-level
- "e" gnus-topic-sort-groups-by-server
- "v" gnus-topic-sort-groups-by-score
- "r" gnus-topic-sort-groups-by-rank
- "m" gnus-topic-sort-groups-by-method))
+ "=" #'gnus-topic-select-group
+ "RET" #'gnus-topic-select-group
+ "SPC" #'gnus-topic-read-group
+ "C-c C-x" #'gnus-topic-expire-articles
+ "c" #'gnus-topic-catchup-articles
+ "C-k" #'gnus-topic-kill-group
+ "C-y" #'gnus-topic-yank-group
+ "M-g" #'gnus-topic-get-new-news-this-topic
+ "A T" #'gnus-topic-list-active
+ "G p" #'gnus-topic-edit-parameters
+ "#" #'gnus-topic-mark-topic
+ "M-#" #'gnus-topic-unmark-topic
+ "<tab>" #'gnus-topic-indent
+ "M-<tab>" #'gnus-topic-unindent
+ "TAB" #'gnus-topic-indent
+ "C-M-i" #'gnus-topic-unindent
+ "<mouse-2>" #'gnus-mouse-pick-topic
+
+ "T" (define-keymap :prefix 'gnus-group-topic-map
+ "#" #'gnus-topic-mark-topic
+ "M-#" #'gnus-topic-unmark-topic
+ "n" #'gnus-topic-create-topic
+ "m" #'gnus-topic-move-group
+ "D" #'gnus-topic-remove-group
+ "c" #'gnus-topic-copy-group
+ "h" #'gnus-topic-hide-topic
+ "s" #'gnus-topic-show-topic
+ "j" #'gnus-topic-jump-to-topic
+ "M" #'gnus-topic-move-matching
+ "C" #'gnus-topic-copy-matching
+ "M-p" #'gnus-topic-goto-previous-topic
+ "M-n" #'gnus-topic-goto-next-topic
+ "TAB" #'gnus-topic-indent
+ "<tab>" #'gnus-topic-indent
+ "r" #'gnus-topic-rename
+ "DEL" #'gnus-topic-delete
+ "<delete>" #'gnus-topic-delete
+ "H" #'gnus-topic-toggle-display-empty-topics
+
+ "S" (define-keymap :prefix 'gnus-topic-sort-map
+ "s" #'gnus-topic-sort-groups
+ "a" #'gnus-topic-sort-groups-by-alphabet
+ "u" #'gnus-topic-sort-groups-by-unread
+ "l" #'gnus-topic-sort-groups-by-level
+ "e" #'gnus-topic-sort-groups-by-server
+ "v" #'gnus-topic-sort-groups-by-score
+ "r" #'gnus-topic-sort-groups-by-rank
+ "m" #'gnus-topic-sort-groups-by-method)))
(defun gnus-topic-make-menu-bar ()
(unless (boundp 'gnus-topic-menu)
diff --git a/lisp/gnus/gnus-undo.el b/lisp/gnus/gnus-undo.el
index 64ed2bbad6b..a82b1f87a3e 100644
--- a/lisp/gnus/gnus-undo.el
+++ b/lisp/gnus/gnus-undo.el
@@ -75,15 +75,12 @@
;;; Minor mode definition.
-(defvar gnus-undo-mode-map
- (let ((map (make-sparse-keymap)))
- (gnus-define-keys map
- "\M-\C-_" gnus-undo
- "\C-_" gnus-undo
- "\C-xu" gnus-undo
- ;; many people are used to type `C-/' on X terminals and get `C-_'.
- [(control /)] gnus-undo)
- map))
+(defvar-keymap gnus-undo-mode-map
+ "C-M-_" #'gnus-undo
+ "C-_" #'gnus-undo
+ "C-x u" #'gnus-undo
+ ;; many people are used to type `C-/' on GUI frames and get `C-_'.
+ "C-/" #'gnus-undo)
(defun gnus-undo-make-menu-bar ()
;; This is disabled for the time being.
diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el
index 70ae81d95ea..a777157f894 100644
--- a/lisp/gnus/gnus-util.el
+++ b/lisp/gnus/gnus-util.el
@@ -300,25 +300,26 @@ Symbols are also allowed; their print names are used instead."
(defmacro gnus-local-set-keys (&rest plist)
"Set the keys in PLIST in the current keymap."
- (declare (indent 1))
+ (declare (obsolete define-keymap "29.1") (indent 1))
`(gnus-define-keys-1 (current-local-map) ',plist))
(defmacro gnus-define-keys (keymap &rest plist)
"Define all keys in PLIST in KEYMAP."
- (declare (indent 1))
+ (declare (obsolete define-keymap "29.1") (indent 1))
`(gnus-define-keys-1 ,(if (symbolp keymap) keymap `',keymap) (quote ,plist)))
(defmacro gnus-define-keys-safe (keymap &rest plist)
"Define all keys in PLIST in KEYMAP without overwriting previous definitions."
- (declare (indent 1))
+ (declare (obsolete define-keymap "29.1") (indent 1))
`(gnus-define-keys-1 (quote ,keymap) (quote ,plist) t))
(defmacro gnus-define-keymap (keymap &rest plist)
"Define all keys in PLIST in KEYMAP."
- (declare (indent 1))
+ (declare (obsolete define-keymap "29.1") (indent 1))
`(gnus-define-keys-1 ,keymap (quote ,plist)))
(defun gnus-define-keys-1 (keymap plist &optional safe)
+ (declare (obsolete define-keymap "29.1"))
(when (null keymap)
(error "Can't set keys in a null keymap"))
(cond ((symbolp keymap) (error "First arg should be a keymap object"))
@@ -533,7 +534,7 @@ ARGS are passed to `message'."
(defun gnus-extract-references (references)
"Return a list of Message-IDs in REFERENCES (in In-Reply-To
- format), trimmed to only contain the Message-IDs."
+format), trimmed to only contain the Message-IDs."
(let ((ids (gnus-split-references references))
refs)
(dolist (id ids)
@@ -1310,9 +1311,7 @@ SPEC is a predicate specifier that contains stuff like `or', `and',
initial-input history def)
"Call `gnus-completing-read-function'."
(funcall gnus-completing-read-function
- (concat prompt (when def
- (concat " (default " def ")"))
- ": ")
+ (format-prompt prompt def)
collection require-match initial-input history def))
(defun gnus-emacs-completing-read (prompt collection &optional require-match
@@ -1528,8 +1527,8 @@ sequence, this is like `mapcar'. With several, it is like the Common Lisp
(t emacs-version))))
(defun gnus-rename-file (old-path new-path &optional trim)
- "Rename OLD-PATH as NEW-PATH. If TRIM, recursively delete
-empty directories from OLD-PATH."
+ "Rename OLD-PATH as NEW-PATH.
+If TRIM, recursively delete empty directories from OLD-PATH."
(when (file-exists-p old-path)
(let* ((old-dir (file-name-directory old-path))
;; (old-name (file-name-nondirectory old-path))
@@ -1549,7 +1548,7 @@ empty directories from OLD-PATH."
(concat old-dir "..")))))))))
(defun gnus-set-file-modes (filename mode &optional flag)
- "Wrapper for set-file-modes."
+ "Wrapper for `set-file-modes'."
(ignore-errors
(set-file-modes filename mode flag)))
diff --git a/lisp/gnus/gnus-uu.el b/lisp/gnus/gnus-uu.el
index 6c926384c97..778a8a3ea03 100644
--- a/lisp/gnus/gnus-uu.el
+++ b/lisp/gnus/gnus-uu.el
@@ -354,12 +354,12 @@ didn't work, and overwrite existing files. Otherwise, ask each time."
;; Commands.
(defun gnus-uu-decode-uu (&optional n)
- "Uudecodes the current article."
+ "Uudecode the current article."
(interactive "P" gnus-article-mode gnus-summary-mode)
(gnus-uu-decode-with-method #'gnus-uu-uustrip-article n))
(defun gnus-uu-decode-uu-and-save (n dir)
- "Decodes and saves the resulting file."
+ "Decode and save the resulting file."
(interactive
(list current-prefix-arg
(file-name-as-directory
@@ -370,12 +370,12 @@ didn't work, and overwrite existing files. Otherwise, ask each time."
(gnus-uu-decode-with-method #'gnus-uu-uustrip-article n dir nil nil t))
(defun gnus-uu-decode-unshar (&optional n)
- "Unshars the current article."
+ "Unshar the current article."
(interactive "P" gnus-article-mode gnus-summary-mode)
(gnus-uu-decode-with-method #'gnus-uu-unshar-article n nil nil 'scan t))
(defun gnus-uu-decode-unshar-and-save (n dir)
- "Unshars and saves the current article."
+ "Unshar and save the current article."
(interactive
(list current-prefix-arg
(file-name-as-directory
@@ -386,7 +386,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time."
(gnus-uu-decode-with-method #'gnus-uu-unshar-article n dir nil 'scan t))
(defun gnus-uu-decode-save (n file)
- "Saves the current article."
+ "Save the current article."
(interactive
(list current-prefix-arg
(if gnus-uu-save-separate-articles
@@ -399,7 +399,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time."
(gnus-uu-decode-with-method #'gnus-uu-save-article n nil t))
(defun gnus-uu-decode-binhex (n dir)
- "Unbinhexes the current article."
+ "Unbinhex the current article."
(interactive
(list current-prefix-arg
(file-name-as-directory
@@ -425,13 +425,13 @@ didn't work, and overwrite existing files. Otherwise, ask each time."
(gnus-uu-decode-with-method #'gnus-uu-yenc-article n dir nil t))
(defun gnus-uu-decode-uu-view (&optional n)
- "Uudecodes and views the current article."
+ "Uudecode and view the current article."
(interactive "P" gnus-article-mode gnus-summary-mode)
(let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic)))
(gnus-uu-decode-uu n)))
(defun gnus-uu-decode-uu-and-save-view (n dir)
- "Decodes, views and saves the resulting file."
+ "Decode, view and save the resulting file."
(interactive
(list current-prefix-arg
(read-file-name "Uudecode, view and save in dir: "
@@ -442,13 +442,13 @@ didn't work, and overwrite existing files. Otherwise, ask each time."
(gnus-uu-decode-uu-and-save n dir)))
(defun gnus-uu-decode-unshar-view (&optional n)
- "Unshars and views the current article."
+ "Unshar and view the current article."
(interactive "P" gnus-article-mode gnus-summary-mode)
(let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic)))
(gnus-uu-decode-unshar n)))
(defun gnus-uu-decode-unshar-and-save-view (n dir)
- "Unshars and saves the current article."
+ "Unshar and save the current article."
(interactive
(list current-prefix-arg
(read-file-name "Unshar, view and save in dir: "
@@ -459,7 +459,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time."
(gnus-uu-decode-unshar-and-save n dir)))
(defun gnus-uu-decode-save-view (n file)
- "Saves and views the current article."
+ "Save and view the current article."
(interactive
(list current-prefix-arg
(if gnus-uu-save-separate-articles
@@ -472,7 +472,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time."
(gnus-uu-decode-save n file)))
(defun gnus-uu-decode-binhex-view (n file)
- "Unbinhexes and views the current article."
+ "Unbinhex and view the current article."
(interactive
(list current-prefix-arg
(read-file-name "Unbinhex, view and save in dir: "
@@ -488,7 +488,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time."
;; Digest and forward articles
(defun gnus-uu-digest-mail-forward (&optional n post)
- "Digests and forwards all articles in this series."
+ "Digest and forward all articles in this series."
(interactive "P" gnus-article-mode gnus-summary-mode)
(gnus-uu-initialize)
(let ((gnus-uu-save-in-digest t)
@@ -579,7 +579,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time."
(defun gnus-new-processable (unmarkp articles)
(if unmarkp
(nreverse (seq-intersection gnus-newsgroup-processable articles #'eq))
- (seq-difference articles gnus-newsgroup-processable #'eq)))
+ (gnus-set-difference articles gnus-newsgroup-processable)))
(defun gnus-uu-mark-by-regexp (regexp &optional unmark)
"Set the process mark on articles whose subjects match REGEXP.
@@ -643,7 +643,7 @@ When called interactively, prompt for REGEXP."
(gnus-uu-mark-region (point-min) (point-max) t))
(defun gnus-uu-mark-thread ()
- "Marks all articles downwards in this thread."
+ "Mark all articles downwards in this thread."
(interactive nil gnus-article-mode gnus-summary-mode)
(gnus-save-hidden-threads
(let ((level (gnus-summary-thread-level)))
@@ -654,7 +654,7 @@ When called interactively, prompt for REGEXP."
(gnus-summary-position-point))
(defun gnus-uu-unmark-thread ()
- "Unmarks all articles downwards in this thread."
+ "Unmark all articles downwards in this thread."
(interactive nil gnus-article-mode gnus-summary-mode)
(let ((level (gnus-summary-thread-level)))
(while (and (gnus-summary-remove-process-mark
@@ -747,7 +747,7 @@ When called interactively, prompt for REGEXP."
(gnus-uu-decode-postscript n)))
(defun gnus-uu-decode-postscript-and-save (n dir)
- "Extracts PostScript and saves the current article."
+ "Extract PostScript and save the current article."
(interactive (list current-prefix-arg
(file-name-as-directory
(read-directory-name "Save in dir: "
@@ -758,7 +758,7 @@ When called interactively, prompt for REGEXP."
n dir nil nil t))
(defun gnus-uu-decode-postscript-and-save-view (n dir)
- "Decodes, views and saves the resulting file."
+ "Decode, view and save the resulting file."
(interactive (list current-prefix-arg
(read-file-name "Where do you want to save the file(s)? "
gnus-uu-default-dir
@@ -1606,7 +1606,7 @@ Gnus might fail to display all of it.")
gnus-uu-unshar-warning))
(goto-char (point-min))
(display-buffer buffer)
- (yes-or-no-p "This is a shell archive, unshar it? "))
+ (yes-or-no-p "This is a shell archive, unshar it?"))
(kill-buffer buffer))
(setq state (list 'error))))))
(unless (memq 'error state)
@@ -1925,7 +1925,7 @@ is t."
(gnus-uu-post-insert-binary)))))
(defun gnus-uu-post-insert-binary-in-article ()
- "Inserts an encoded file in the buffer.
+ "Insert an encoded file in the buffer.
The user will be asked for a file name."
(interactive)
(save-excursion
diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el
index d52bd26a2cb..afe07ee46f9 100644
--- a/lisp/gnus/gnus.el
+++ b/lisp/gnus/gnus.el
@@ -798,7 +798,7 @@ be used directly.")
(goto-char (point-min))
t)))
(insert
- (format "
+ "
_ ___ _ _
_ ___ __ ___ __ _ ___
__ _ ___ __ ___
@@ -817,7 +817,7 @@ be used directly.")
_
__
-"))
+")
;; And then hack it.
(gnus-indent-rigidly (point-min) (point-max)
(/ (max (- (window-width) (or x 46)) 0) 2))
@@ -1114,7 +1114,7 @@ that case, just return a fully prefixed name of the group --
(defcustom gnus-secondary-servers nil
"List of NNTP servers that the user can choose between interactively.
To make Gnus query you for a server, you have to give `gnus' a
-non-numeric prefix - `C-u M-x gnus', in short."
+non-numeric prefix - `\\[universal-argument] \\[gnus]', in short."
:group 'gnus-server
:type '(repeat string))
(make-obsolete-variable 'gnus-secondary-servers 'gnus-select-method "24.1")
@@ -1467,11 +1467,11 @@ address was listed in gnus-group-split Addresses (see below).")
:variable-group gnus-group-parameter
:parameter-type '(gnus-email-address :tag "To List")
:parameter-document "\
-This address will be used when doing a `a' in the group.
+This address will be used when doing a \\`a' in the group.
It is totally ignored when doing a followup--except that if it is
present in a news group, you'll get mail group semantics when doing
-`f'.
+\\`f'.
The gnus-group-split mail splitting mechanism will behave as if this
address was listed in gnus-group-split Addresses (see below).")
@@ -2140,8 +2140,9 @@ instance, to switch off all visual things except menus, you can say:
Valid elements include `summary-highlight', `group-highlight',
`article-highlight', `mouse-face', `summary-menu', `group-menu',
-`article-menu', `tree-highlight', `menu', `highlight', `browse-menu',
-`server-menu', `page-marker', `tree-menu', `binary-menu', and`pick-menu'."
+`article-menu', `tree-highlight', `menu', `highlight',
+`browse-menu', `server-menu', `page-marker', `tree-menu',
+`binary-menu', and `pick-menu'."
:group 'gnus-meta
:group 'gnus-visual
:type '(set (const summary-highlight)
@@ -2216,7 +2217,7 @@ covered by that variable."
(defcustom gnus-agent t
"Whether we want to use the Gnus agent or not.
-You may customize gnus-agent to disable its use. However, some
+You may customize `gnus-agent' to disable its use. However, some
back ends have started to use the agent as a client-side cache.
Disabling the agent may result in noticeable loss of performance."
:version "22.1"
@@ -2536,7 +2537,7 @@ are always t.")
;; Only used in gnus-util, which has an autoload.
("rmailsum" rmail-update-summary)
("gnus-xmas" gnus-xmas-splash)
- ("score-mode" :interactive t gnus-score-mode)
+ ("score-mode" :interactive t gnus-score-mode gnus-score-edit-all-score)
("gnus-mh" gnus-summary-save-article-folder
gnus-Folder-save-name gnus-folder-save-name)
("gnus-mh" :interactive (gnus-summary-mode) gnus-summary-save-in-folder)
@@ -2608,7 +2609,11 @@ are always t.")
gnus-uu-decode-uu-and-save-view gnus-uu-decode-unshar-view
gnus-uu-decode-unshar-and-save-view gnus-uu-decode-save-view
gnus-uu-decode-binhex-view gnus-uu-unmark-thread
- gnus-uu-mark-over gnus-uu-post-news gnus-uu-invert-processable)
+ gnus-uu-mark-over gnus-uu-post-news gnus-uu-invert-processable
+ gnus-uu-decode-postscript-and-save-view
+ gnus-uu-decode-postscript-view gnus-uu-decode-postscript-and-save
+ gnus-uu-decode-yenc gnus-uu-unmark-by-regexp gnus-uu-unmark-region
+ gnus-uu-decode-postscript)
("gnus-uu" gnus-uu-delete-work-dir gnus-uu-unmark-thread)
("gnus-msg" (gnus-summary-send-map keymap)
gnus-article-mail gnus-copy-article-buffer gnus-extended-version)
@@ -2655,6 +2660,7 @@ are always t.")
gnus-article-hide-headers gnus-article-hide-boring-headers
gnus-article-treat-overstrike
gnus-article-remove-cr gnus-article-remove-trailing-blank-lines
+ gnus-article-emojize-symbols
gnus-article-display-x-face gnus-article-de-quoted-unreadable
gnus-article-de-base64-unreadable
gnus-article-decode-HZ
@@ -2666,7 +2672,34 @@ are always t.")
gnus-article-edit-mode gnus-article-edit-article
gnus-article-edit-done gnus-article-decode-encoded-words
gnus-start-date-timer gnus-stop-date-timer
- gnus-mime-view-all-parts)
+ gnus-mime-view-all-parts gnus-article-pipe-part
+ gnus-article-inline-part gnus-article-encrypt-body
+ gnus-article-browse-html-article gnus-article-view-part-externally
+ gnus-article-view-part-as-charset gnus-article-copy-part
+ gnus-article-jump-to-part gnus-article-view-part-as-type
+ gnus-article-delete-part gnus-article-replace-part
+ gnus-article-save-part-and-strip gnus-article-save-part
+ gnus-article-remove-leading-whitespace gnus-article-strip-trailing-space
+ gnus-article-strip-leading-space gnus-article-strip-all-blank-lines
+ gnus-article-strip-blank-lines gnus-article-strip-multiple-blank-lines
+ gnus-article-date-user gnus-article-date-iso8601
+ gnus-article-date-english gnus-article-date-ut
+ gnus-article-decode-charset gnus-article-decode-mime-words
+ gnus-article-toggle-fonts gnus-article-show-images
+ gnus-article-remove-images gnus-article-display-face
+ gnus-article-treat-fold-newsgroups gnus-article-treat-unfold-headers
+ gnus-article-treat-fold-headers gnus-article-highlight-signature
+ gnus-article-highlight-headers gnus-article-highlight
+ gnus-article-strip-banner gnus-article-hide-list-identifiers
+ gnus-article-hide gnus-article-outlook-rearrange-citation
+ gnus-article-treat-non-ascii gnus-article-treat-smartquotes
+ gnus-article-verify-x-pgp-sig gnus-article-strip-headers-in-body
+ gnus-treat-smiley gnus-article-treat-ansi-sequences
+ gnus-article-capitalize-sentences gnus-article-toggle-truncate-lines
+ gnus-article-fill-long-lines gnus-article-emphasize
+ gnus-article-add-buttons-to-head gnus-article-add-button
+ gnus-article-babel gnus-sticky-article gnus-article-view-part
+ gnus-article-add-buttons)
("gnus-int" gnus-request-type)
("gnus-start" gnus-newsrc-parse-options gnus-1 gnus-no-server-1
gnus-dribble-enter gnus-read-init-file gnus-dribble-touch
@@ -2716,7 +2749,7 @@ with some simple extensions.
%F Contents of the From: header (string)
%f Contents of the From: or To: headers (string)
%x Contents of the Xref: header (string)
-%D Date of the article (string)
+%D Contents of the Date: header article (string)
%d Date of the article (string) in DD-MMM format
%o Date of the article (string) in YYYYMMDD`T'HHMMSS
format
@@ -3117,9 +3150,9 @@ g -- Group name."
"Check whether GROUP supports function FUNC.
GROUP can either be a string (a group name) or a select method."
(ignore-errors
- (let ((method (if (stringp group)
- (car (gnus-find-method-for-group group))
- group)))
+ (when-let ((method (if (stringp group)
+ (car (gnus-find-method-for-group group))
+ group)))
(unless (featurep method)
(require method))
(fboundp (intern (format "%s-%s" method func))))))
@@ -3753,6 +3786,8 @@ just the host name."
(setq foreign server
group (substring group (+ 1 colon))))
(setq foreign (concat foreign ":")))
+ ;; Remove braces from name (common in IMAP groups).
+ (setq group (replace-regexp-in-string "[][]+" "" group))
;; Collapse group name leaving LEVELS uncollapsed elements
(let* ((slist (split-string group "/"))
(slen (length slist))
diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el
index af0a1983766..efdddea69f6 100644
--- a/lisp/gnus/mail-source.el
+++ b/lisp/gnus/mail-source.el
@@ -224,12 +224,9 @@ Leave mails for this many days" :value 14)))))
(const :format "" :value :plugged)
(boolean :tag "Plugged"))))))))
-(defcustom mail-source-ignore-errors nil
- "Ignore errors when querying mail sources.
-If nil, the user will be prompted when an error occurs. If non-nil,
-the error will be ignored."
- :version "22.1"
- :type 'boolean)
+(make-obsolete-variable 'mail-source-ignore-errors
+ "configure `gnus-verbose' instead"
+ "29.1")
(defcustom mail-source-primary-source nil
"Primary source for incoming mail.
@@ -554,18 +551,16 @@ Return the number of files that were found."
(condition-case err
(funcall function source callback)
(error
- (if (and (not mail-source-ignore-errors)
- (not
- (yes-or-no-p
- (format "Mail source %s error (%s). Continue? "
+ (gnus-error
+ 5
+ (format "Mail source %s error (%s)"
(if (memq ':password source)
(let ((s (copy-sequence source)))
(setcar (cdr (memq ':password s))
"********")
s)
source)
- (cadr err)))))
- (error "Cannot get new mail"))
+ (cadr err)))
0)))))))))
(declare-function gnus-message "gnus-util" (level &rest args))
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index bff1b2a60d9..c2d14296f94 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -48,6 +48,8 @@
(require 'puny)
(require 'rmc) ; read-multiple-choice
(require 'subr-x)
+(require 'yank-media)
+(require 'mailcap)
(autoload 'mailclient-send-it "mailclient")
@@ -2395,6 +2397,8 @@ If VERBATIM, use slrn style verbatim marks (\"#v+\" and \"#v-\")."
(save-excursion
;; add to the end of the region first, otherwise end would be invalid
(goto-char end)
+ (unless (bolp)
+ (insert "\n"))
(insert (if verbatim "#v-\n" message-mark-insert-end))
(goto-char beg)
(insert (if verbatim "#v+\n" message-mark-insert-begin))))
@@ -2868,84 +2872,78 @@ Consider adding this function to `message-header-setup-hook'"
;;; Set up keymap.
-(defvar message-mode-map nil)
-
-(unless message-mode-map
- (setq message-mode-map (make-keymap))
- (set-keymap-parent message-mode-map text-mode-map)
- (define-key message-mode-map "\C-c?" #'describe-mode)
-
- (define-key message-mode-map "\C-c\C-f\C-t" #'message-goto-to)
- (define-key message-mode-map "\C-c\C-f\C-o" #'message-goto-from)
- (define-key message-mode-map "\C-c\C-f\C-b" #'message-goto-bcc)
- (define-key message-mode-map "\C-c\C-f\C-w" #'message-goto-fcc)
- (define-key message-mode-map "\C-c\C-f\C-c" #'message-goto-cc)
- (define-key message-mode-map "\C-c\C-f\C-s" #'message-goto-subject)
- (define-key message-mode-map "\C-c\C-f\C-r" #'message-goto-reply-to)
- (define-key message-mode-map "\C-c\C-f\C-n" #'message-goto-newsgroups)
- (define-key message-mode-map "\C-c\C-f\C-d" #'message-goto-distribution)
- (define-key message-mode-map "\C-c\C-f\C-f" #'message-goto-followup-to)
- (define-key message-mode-map "\C-c\C-f\C-m" #'message-goto-mail-followup-to)
- (define-key message-mode-map "\C-c\C-f\C-k" #'message-goto-keywords)
- (define-key message-mode-map "\C-c\C-f\C-u" #'message-goto-summary)
- (define-key message-mode-map "\C-c\C-f\C-i"
- #'message-insert-or-toggle-importance)
- (define-key message-mode-map "\C-c\C-f\C-a"
- #'message-generate-unsubscribed-mail-followup-to)
+(defvar-keymap message-mode-map
+ :full t :parent text-mode-map
+ :doc "Message Mode keymap."
+ "C-c ?" #'describe-mode
+
+ "C-c C-f C-t" #'message-goto-to
+ "C-c C-f C-o" #'message-goto-from
+ "C-c C-f C-b" #'message-goto-bcc
+ "C-c C-f C-w" #'message-goto-fcc
+ "C-c C-f C-c" #'message-goto-cc
+ "C-c C-f C-s" #'message-goto-subject
+ "C-c C-f C-r" #'message-goto-reply-to
+ "C-c C-f C-n" #'message-goto-newsgroups
+ "C-c C-f C-d" #'message-goto-distribution
+ "C-c C-f C-f" #'message-goto-followup-to
+ "C-c C-f C-m" #'message-goto-mail-followup-to
+ "C-c C-f C-k" #'message-goto-keywords
+ "C-c C-f C-u" #'message-goto-summary
+ "C-c C-f C-i" #'message-insert-or-toggle-importance
+ "C-c C-f C-a" #'message-generate-unsubscribed-mail-followup-to
;; modify headers (and insert notes in body)
- (define-key message-mode-map "\C-c\C-fs" #'message-change-subject)
+ "C-c C-f s" #'message-change-subject
;;
- (define-key message-mode-map "\C-c\C-fx" #'message-cross-post-followup-to)
+ "C-c C-f x" #'message-cross-post-followup-to
;; prefix+message-cross-post-followup-to = same w/o cross-post
- (define-key message-mode-map "\C-c\C-ft" #'message-reduce-to-to-cc)
- (define-key message-mode-map "\C-c\C-fa" #'message-add-archive-header)
+ "C-c C-f t" #'message-reduce-to-to-cc
+ "C-c C-f a" #'message-add-archive-header
;; mark inserted text
- (define-key message-mode-map "\C-c\M-m" #'message-mark-inserted-region)
- (define-key message-mode-map "\C-c\M-f" #'message-mark-insert-file)
-
- (define-key message-mode-map "\C-c\C-b" #'message-goto-body)
- (define-key message-mode-map "\C-c\C-i" #'message-goto-signature)
-
- (define-key message-mode-map "\C-c\C-t" #'message-insert-to)
- (define-key message-mode-map "\C-c\C-fw" #'message-insert-wide-reply)
- (define-key message-mode-map "\C-c\C-n" #'message-insert-newsgroups)
- (define-key message-mode-map "\C-c\C-l" #'message-to-list-only)
- (define-key message-mode-map "\C-c\C-f\C-e" #'message-insert-expires)
-
- (define-key message-mode-map "\C-c\C-u" #'message-insert-or-toggle-importance)
- (define-key message-mode-map "\C-c\M-n"
- #'message-insert-disposition-notification-to)
-
- (define-key message-mode-map "\C-c\C-y" #'message-yank-original)
- (define-key message-mode-map "\C-c\M-\C-y" #'message-yank-buffer)
- (define-key message-mode-map "\C-c\C-q" #'message-fill-yanked-message)
- (define-key message-mode-map "\C-c\C-w" #'message-insert-signature)
- (define-key message-mode-map "\C-c\M-h" #'message-insert-headers)
- (define-key message-mode-map "\C-c\C-r" #'message-caesar-buffer-body)
- (define-key message-mode-map "\C-c\C-o" #'message-sort-headers)
- (define-key message-mode-map "\C-c\M-r" #'message-rename-buffer)
-
- (define-key message-mode-map "\C-c\C-c" #'message-send-and-exit)
- (define-key message-mode-map "\C-c\C-s" #'message-send)
- (define-key message-mode-map "\C-c\C-k" #'message-kill-buffer)
- (define-key message-mode-map "\C-c\C-d" #'message-dont-send)
- (define-key message-mode-map "\C-c\n" #'gnus-delay-article)
-
- (define-key message-mode-map "\C-c\M-k" #'message-kill-address)
- (define-key message-mode-map "\C-c\C-e" #'message-elide-region)
- (define-key message-mode-map "\C-c\C-v" #'message-delete-not-region)
- (define-key message-mode-map "\C-c\C-z" #'message-kill-to-signature)
- (define-key message-mode-map "\M-\r" #'message-newline-and-reformat)
- (define-key message-mode-map [remap split-line] #'message-split-line)
-
- (define-key message-mode-map "\C-c\C-a" #'mml-attach-file)
- (define-key message-mode-map "\C-c\C-p" #'message-insert-screenshot)
-
- (define-key message-mode-map "\C-a" #'message-beginning-of-line)
- (define-key message-mode-map "\t" #'message-tab)
-
- (define-key message-mode-map "\M-n" #'message-display-abbrev))
+ "C-c M-m" #'message-mark-inserted-region
+ "C-c M-f" #'message-mark-insert-file
+
+ "C-c C-b" #'message-goto-body
+ "C-c C-i" #'message-goto-signature
+
+ "C-c C-t" #'message-insert-to
+ "C-c C-f w" #'message-insert-wide-reply
+ "C-c C-n" #'message-insert-newsgroups
+ "C-c C-l" #'message-to-list-only
+ "C-c C-f C-e" #'message-insert-expires
+ "C-c C-u" #'message-insert-or-toggle-importance
+ "C-c M-n" #'message-insert-disposition-notification-to
+
+ "C-c C-y" #'message-yank-original
+ "C-c C-M-y" #'message-yank-buffer
+ "C-c C-q" #'message-fill-yanked-message
+ "C-c C-w" #'message-insert-signature
+ "C-c M-h" #'message-insert-headers
+ "C-c C-r" #'message-caesar-buffer-body
+ "C-c C-o" #'message-sort-headers
+ "C-c M-r" #'message-rename-buffer
+
+ "C-c C-c" #'message-send-and-exit
+ "C-c C-s" #'message-send
+ "C-c C-k" #'message-kill-buffer
+ "C-c C-d" #'message-dont-send
+ "C-c C-j" #'gnus-delay-article
+
+ "C-c M-k" #'message-kill-address
+ "C-c C-e" #'message-elide-region
+ "C-c C-v" #'message-delete-not-region
+ "C-c C-z" #'message-kill-to-signature
+ "M-RET" #'message-newline-and-reformat
+ "<remap> <split-line>" #'message-split-line
+
+ "C-c C-a" #'mml-attach-file
+ "C-c C-p" #'message-insert-screenshot
+
+ "C-a" #'message-beginning-of-line
+ "TAB" #'message-tab
+
+ "M-n" #'message-display-abbrev)
(easy-menu-define
message-mode-menu message-mode-map "Message Menu."
@@ -3159,6 +3157,7 @@ Like `text-mode', but with these additional commands:
(setq-local message-checksum nil)
(setq-local message-mime-part 0)
(message-setup-fill-variables)
+ (yank-media-handler "image/.*" #'message--yank-media-image-handler)
(when message-fill-column
(setq fill-column message-fill-column)
(turn-on-auto-fill))
@@ -3572,8 +3571,18 @@ Prefix arg means justify as well."
(when (looking-at message-cite-prefix-regexp)
(setq quoted (match-string 0))
(goto-char (match-end 0))
- (looking-at "[ \t]*")
- (setq leading-space (match-string 0)))
+ (let ((after (point)))
+ ;; This is a line with no text after the cite prefix. In that
+ ;; case, the trailing space is commonly not present, so look
+ ;; around for other lines that have some data.
+ (when (looking-at-p "\n")
+ (let ((regexp (concat "^" message-cite-prefix-regexp "[ \t]")))
+ (when (or (re-search-backward regexp nil t)
+ (re-search-forward regexp nil t))
+ (goto-char (1- (match-end 0))))))
+ (looking-at "[ \t]*")
+ (setq leading-space (match-string 0))
+ (goto-char after)))
(if (and quoted
(not not-break)
(not bolp)
@@ -3590,7 +3599,7 @@ Prefix arg means justify as well."
(equal quoted (match-string 0)))
(goto-char (match-end 0))
(looking-at "[ \t]*")
- (when (< (length leading-space) (length (match-string 0)))
+ (when (> (length leading-space) (length (match-string 0)))
(setq leading-space (match-string 0)))
(forward-line 1))
(setq end (point))
@@ -3841,7 +3850,7 @@ text was killed."
"Caesar rotate all letters in the current buffer by 13 places.
Used to encode/decode possibly offensive messages (commonly in rec.humor).
With prefix arg, specifies the number of places to rotate each letter forward.
-Mail and USENET news headers are not rotated unless WIDE is non-nil."
+Mail and Usenet news headers are not rotated unless WIDE is non-nil."
(interactive (if current-prefix-arg
(list (prefix-numeric-value current-prefix-arg))
(list nil))
@@ -4754,23 +4763,25 @@ Valid types are `send', `return', `exit', `kill' and `postpone'."
t
"\
The message size, "
- (/ (buffer-size) 1000) "KB, is too large.
+ (/ (buffer-size) 1000)
+ (substitute-command-keys "KB, is too large.
Some mail gateways (MTA's) bounce large messages. To avoid the
-problem, answer `y', and the message will be split into several
-smaller pieces, the size of each is about "
+problem, answer \\`y', and the message will be split into several
+smaller pieces, the size of each is about ")
(/ message-send-mail-partially-limit 1000)
- "KB except the last
+ (substitute-command-keys
+ "KB except the last
one.
However, some mail readers (MUA's) can't read split messages, i.e.,
-mails in message/partially format. Answer `n', and the message
+mails in message/partially format. Answer \\`n', and the message
will be sent in one piece.
The size limit is controlled by `message-send-mail-partially-limit'.
If you always want Gnus to send messages in one piece, set
`message-send-mail-partially-limit' to nil.
-")))
+"))))
(progn
(message "Sending via mail...")
(if message-send-mail-real-function
@@ -5346,7 +5357,7 @@ Otherwise, generate and save a value for `canlock-password' first."
(zerop
(length
(setq to (completing-read
- "Followups to (default no Followup-To header): "
+ (format-prompt "Followups to" "no Followup-To header")
(mapcar #'list
(cons "poster"
(message-tokenize-header
@@ -5817,15 +5828,15 @@ In posting styles use `(\"Expires\" (make-expires-date 30))'."
;; You might for example insert a "." somewhere (not next to another dot
;; or string boundary), or modify the "fsf" string.
(defun message-unique-id ()
- ;; Don't use microseconds from (current-time), they may be unsupported.
+ ;; Don't use fractional seconds from timestamp; they may be unsupported.
;; Instead we use this randomly inited counter.
(setq message-unique-id-char
- (% (1+ (or message-unique-id-char
- (random (ash 1 20))))
- ;; (current-time) returns 16-bit ints,
- ;; and 2^16*25 just fits into 4 digits i base 36.
- (* 25 25)))
- (let ((tm (current-time)))
+ ;; 2^16 * 25 just fits into 4 digits i base 36.
+ (let ((base (* 25 25)))
+ (if message-unique-id-char
+ (% (1+ message-unique-id-char) base)
+ (random base))))
+ (let ((tm (time-convert nil 'integer)))
(concat
(if (or (eq system-type 'ms-dos)
;; message-number-base36 doesn't handle bigints.
@@ -5835,10 +5846,12 @@ In posting styles use `(\"Expires\" (make-expires-date 30))'."
(aset user (match-beginning 0) ?_))
user)
(message-number-base36 (user-uid) -1))
- (message-number-base36 (+ (car tm)
- (ash (% message-unique-id-char 25) 16)) 4)
- (message-number-base36 (+ (nth 1 tm)
- (ash (/ message-unique-id-char 25) 16)) 4)
+ (message-number-base36 (+ (ash tm -16)
+ (ash (% message-unique-id-char 25) 16))
+ 4)
+ (message-number-base36 (+ (logand tm #xffff)
+ (ash (/ message-unique-id-char 25) 16))
+ 4)
;; Append a given name, because while the generated ID is unique
;; to this newsreader, other newsreaders might otherwise generate
;; the same ID via another algorithm.
@@ -5935,12 +5948,9 @@ In posting styles use `(\"Expires\" (make-expires-date 30))'."
(defun message-make-expires ()
"Return an Expires header based on `message-expires'."
- (let ((current (current-time))
- (future (* 1.0 message-expires 60 60 24)))
+ (let ((future (* 60 60 24 message-expires)))
;; Add the future to current.
- (setcar current (+ (car current) (round (/ future (expt 2 16)))))
- (setcar (cdr current) (+ (nth 1 current) (% (round future) (expt 2 16))))
- (message-make-date current)))
+ (message-make-date (time-add nil future))))
(defun message-make-path ()
"Return uucp path."
@@ -8867,24 +8877,29 @@ used to take the screenshot."
(car message-screenshot-command) nil (current-buffer) nil
(cdr message-screenshot-command))
(buffer-string))))
- (set-mark (point))
- (insert-image
- (create-image image 'png t
- :max-width (truncate (* (frame-pixel-width) 0.8))
- :max-height (truncate (* (frame-pixel-height) 0.8))
- :scale 1)
- (format "<#part type=\"image/png\" disposition=inline data-encoding=base64 raw=t>\n%s\n<#/part>"
- ;; 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))))
- (insert "\n\n")
+ (message--yank-media-image-handler 'image/png image)
(message "")))
+(defun message--yank-media-image-handler (type image)
+ (set-mark (point))
+ (insert-image
+ (create-image image (mailcap-mime-type-to-extension type) t
+ :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)))
+ nil nil t)
+ (insert "\n\n"))
+
(declare-function gnus-url-unhex-string "gnus-util")
(defun message-parse-mailto-url (url)
diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el
index 82d1de25f3d..d781407cdcd 100644
--- a/lisp/gnus/mm-decode.el
+++ b/lisp/gnus/mm-decode.el
@@ -446,10 +446,11 @@ If not set, `default-directory' will be used."
:type 'integer
:group 'mime-display)
-(defcustom mm-external-terminal-program "xterm"
- "The program to start an external terminal."
- :version "22.1"
- :type 'string
+(defcustom mm-external-terminal-program '("xterm" "-e")
+ "The program to start an external terminal.
+This should be a list of strings."
+ :version "29.1"
+ :type '(choice string (repeat string))
:group 'mime-display)
;;; Internal variables.
@@ -957,10 +958,16 @@ external if displayed external."
(unwind-protect
(if window-system
(set-process-sentinel
- (start-process "*display*" nil
- mm-external-terminal-program
- "-e" shell-file-name
- shell-command-switch command)
+ (apply #'start-process "*display*" nil
+ (append
+ (if (listp mm-external-terminal-program)
+ mm-external-terminal-program
+ ;; Be backwards-compatible.
+ (list mm-external-terminal-program
+ "-e"))
+ (list shell-file-name
+ shell-command-switch
+ command)))
(lambda (process _state)
(if (eq 'exit (process-status process))
(run-at-time
@@ -1676,8 +1683,7 @@ If RECURSIVE, search recursively."
((eq mm-decrypt-option 'never) nil)
((eq mm-decrypt-option 'always) t)
((eq mm-decrypt-option 'known) t)
- (t (y-or-n-p
- (format "Decrypt (S/MIME) part? "))))
+ (t (y-or-n-p "Decrypt (S/MIME) part? ")))
(mm-view-pkcs7 parts from))
(goto-char (point-min))
;; The encrypted document is a MIME part, and may use either
diff --git a/lisp/gnus/mm-util.el b/lisp/gnus/mm-util.el
index 92e04f9d2ee..ddc228e4900 100644
--- a/lisp/gnus/mm-util.el
+++ b/lisp/gnus/mm-util.el
@@ -31,7 +31,7 @@
(defun mm-ucs-to-char (codepoint)
"Convert Unicode codepoint to character."
- (or (decode-char 'ucs codepoint) ?#))
+ (or codepoint ?#))
(defvar mm-coding-system-list nil)
(defun mm-get-coding-system-list ()
diff --git a/lisp/gnus/mm-uu.el b/lisp/gnus/mm-uu.el
index 9d4c4bfead7..a52613a092c 100644
--- a/lisp/gnus/mm-uu.el
+++ b/lisp/gnus/mm-uu.el
@@ -145,6 +145,14 @@ This can be either \"inline\" or \"attachment\".")
,#'mm-uu-pgp-key-extract
,#'mm-uu-gpg-key-skip-to-last
nil)
+ (markdown-emacs-sources
+ "^```\\(?:elisp\\|emacs-lisp\\|\n(\\)"
+ "^```$"
+ ,#'mm-uu-emacs-sources-extract)
+ (markdown-diff ;; this should be higher than `git-format-patch'
+ "^```\\(?:diff\\|patch\\|\ndiff --git \\)"
+ "^```$"
+ ,#'mm-uu-diff-extract)
(emacs-sources
"^;;;?[ \t]*[^ \t]+\\.el[ \t]*--"
"^;;;?[ \t]*\\([^ \t]+\\.el\\)[ \t]+ends here"
@@ -511,7 +519,7 @@ apply the face `mm-uu-extract'."
(list (mm-make-handle buf mm-uu-text-plain-type)))))
(defun mm-uu-pgp-signed-extract ()
- (let ((mm-security-handle (list (format "multipart/signed"))))
+ (let ((mm-security-handle (list (substring "multipart/signed"))))
(mm-set-handle-multipart-parameter
mm-security-handle 'protocol "application/x-gnus-pgp-signature")
(save-restriction
@@ -579,7 +587,7 @@ apply the face `mm-uu-extract'."
(list (mm-make-handle buf '("application/pgp-encrypted")))))))
(defun mm-uu-pgp-encrypted-extract ()
- (let ((mm-security-handle (list (format "multipart/encrypted"))))
+ (let ((mm-security-handle (list (substring "multipart/encrypted"))))
(mm-set-handle-multipart-parameter
mm-security-handle 'protocol "application/x-gnus-pgp-encrypted")
(save-restriction
diff --git a/lisp/gnus/mm-view.el b/lisp/gnus/mm-view.el
index 2ec75a0bc59..d2a6d2cf5d3 100644
--- a/lisp/gnus/mm-view.el
+++ b/lisp/gnus/mm-view.el
@@ -50,9 +50,7 @@
(w3m . mm-inline-text-html-render-with-w3m)
(w3m-standalone . mm-inline-text-html-render-with-w3m-standalone)
(gnus-w3m . gnus-article-html)
- (links mm-inline-render-with-file
- mm-links-remove-leading-blank
- "links" "-dump" file)
+ (links . mm-inline-render-with-links)
(lynx mm-inline-render-with-stdin nil
"lynx" "-dump" "-force_html" "-stdin" "-nolist")
(html2text mm-inline-render-with-function html2text))
@@ -264,6 +262,7 @@ This is only used if `mm-inline-large-images' is set to
(mm-inline-render-with-stdin handle nil "w3m" "-dump" "-T" "text/html")))
(defun mm-links-remove-leading-blank ()
+ (declare (obsolete nil "28.1"))
;; Delete the annoying three spaces preceding each line of links
;; output.
(goto-char (point-min))
@@ -271,15 +270,18 @@ This is only used if `mm-inline-large-images' is set to
(delete-region (match-beginning 0) (match-end 0))))
(defun mm-inline-wash-with-file (post-func cmd &rest args)
- (let ((file (make-temp-file
- (expand-file-name "mm" mm-tmp-directory))))
- (let ((coding-system-for-write 'binary))
- (write-region (point-min) (point-max) file nil 'silent))
- (delete-region (point-min) (point-max))
- (unwind-protect
- (apply #'call-process cmd nil t nil (mapcar (lambda (e) (eval e t)) args))
- (delete-file file))
- (and post-func (funcall post-func))))
+ (declare (obsolete nil "28.1"))
+ (with-suppressed-warnings ((lexical file))
+ (dlet ((file (make-temp-file
+ (expand-file-name "mm" mm-tmp-directory))))
+ (let ((coding-system-for-write 'binary))
+ (write-region (point-min) (point-max) file nil 'silent))
+ (delete-region (point-min) (point-max))
+ (unwind-protect
+ (apply #'call-process cmd nil t nil
+ (mapcar (lambda (e) (eval e t)) args))
+ (delete-file file))
+ (and post-func (funcall post-func)))))
(defun mm-inline-wash-with-stdin (post-func cmd &rest args)
(let ((coding-system-for-write 'binary))
@@ -288,12 +290,41 @@ This is only used if `mm-inline-large-images' is set to
(and post-func (funcall post-func)))
(defun mm-inline-render-with-file (handle post-func cmd &rest args)
+ (declare (obsolete nil "28.1"))
(let ((source (mm-get-part handle)))
(mm-insert-inline
handle
(mm-with-unibyte-buffer
(insert source)
- (apply #'mm-inline-wash-with-file post-func cmd args)
+ (with-suppressed-warnings ((obsolete mm-inline-wash-with-file))
+ (apply #'mm-inline-wash-with-file post-func cmd args))
+ (buffer-string)))))
+
+(defun mm-inline-render-with-links (handle)
+ (let ((source (mm-get-part handle))
+ file charset)
+ (mm-insert-inline
+ handle
+ (with-temp-buffer
+ (setq charset (mail-content-type-get (mm-handle-type handle) 'charset))
+ (insert source)
+ (unwind-protect
+ (progn
+ (setq file (make-temp-file (expand-file-name
+ "mm" mm-tmp-directory)))
+ (let ((coding-system-for-write 'binary))
+ (write-region (point-min) (point-max) file nil 'silent))
+ (delete-region (point-min) (point-max))
+ (if charset
+ (with-environment-variables (("LANG" (format "en-US.%s"
+ charset)))
+ (call-process "links" nil t nil "-dump" file))
+ (call-process "links" nil t nil "-dump" file))
+ (goto-char (point-min))
+ (while (re-search-forward "^ " nil t)
+ (delete-region (match-beginning 0) (match-end 0))))
+ (when (and file (file-exists-p file))
+ (delete-file file)))
(buffer-string)))))
(defun mm-inline-render-with-stdin (handle post-func cmd &rest args)
@@ -420,7 +451,7 @@ This is only used if `mm-inline-large-images' is set to
(defvar mm-inline-message-prepare-function nil
"Function called by `mm-inline-message' to do client specific setup.
-It is called with one parameter -- the charset.")
+It is called with two parameters -- the MIME handle and the charset.")
(defun mm-inline-message (handle)
"Insert HANDLE (a message/rfc822 part) into the current buffer.
@@ -440,7 +471,7 @@ after inserting the part."
(narrow-to-region b b)
(mm-insert-part handle)
(when mm-inline-message-prepare-function
- (funcall mm-inline-message-prepare-function charset))
+ (funcall mm-inline-message-prepare-function handle charset))
(goto-char (point-min))
(unless bolp
(insert "\n"))
diff --git a/lisp/gnus/mml-sec.el b/lisp/gnus/mml-sec.el
index b49793509fc..f72d76ac02b 100644
--- a/lisp/gnus/mml-sec.el
+++ b/lisp/gnus/mml-sec.el
@@ -238,7 +238,7 @@ You can also customize or set `mml-signencrypt-style-alist' instead."
(goto-char (match-end 0))
(apply #'mml-insert-tag 'part (cons (if sign 'sign 'encrypt)
(cons method tags))))
- (t (error "The message is corrupted. No mail header separator"))))))
+ (t (error "The message is corrupted. No mail header separator"))))))
(defvar mml-secure-method
(if (equal mml-default-encrypt-method mml-default-sign-method)
@@ -328,7 +328,7 @@ either an error is raised or not."
(unless (yes-or-no-p "Message for encryption contains Bcc header.\
This may give away all Bcc'ed identities to all recipients.\
Are you sure that this is safe?\
- (Customize `mml-secure-safe-bcc-list' to avoid this warning.) ")
+ (Customize `mml-secure-safe-bcc-list' to avoid this warning.)")
(error "Aborted"))))))))
;; defuns that add the proper <#secure ...> tag to the top of the message body
@@ -352,7 +352,7 @@ either an error is raised or not."
(apply #'mml-insert-tag
'secure 'method method 'mode mode tags)))
(t (error
- "The message is corrupted. No mail header separator"))))
+ "The message is corrupted. No mail header separator"))))
(when (eql insert-loc (point))
(forward-line 1))))
diff --git a/lisp/gnus/mml-smime.el b/lisp/gnus/mml-smime.el
index 959de0902e2..b81dd2dae4c 100644
--- a/lisp/gnus/mml-smime.el
+++ b/lisp/gnus/mml-smime.el
@@ -314,7 +314,6 @@ Whether the passphrase is cached at all is controlled by
(defvar epg-user-id-alist)
(defvar epg-digest-algorithm-alist)
-(defvar inhibit-redisplay)
(defvar password-cache-expiry)
(eval-when-compile
@@ -369,9 +368,7 @@ Content-Disposition: attachment; filename=smime.p7s
(goto-char (point-max)))))
(defun mml-smime-epg-encrypt (cont)
- (let* ((inhibit-redisplay t) ;FIXME: Why?
- ;; (boundary (mml-compute-boundary cont))
- (cipher (mml-secure-epg-encrypt 'CMS cont)))
+ (let* ((cipher (mml-secure-epg-encrypt 'CMS cont)))
(delete-region (point-min) (point-max))
(goto-char (point-min))
(insert "\
@@ -387,8 +384,7 @@ Content-Disposition: attachment; filename=smime.p7m
(defun mml-smime-epg-verify (handle ctl)
(catch 'error
- (let ((inhibit-redisplay t)
- context part signature) ;; plain signature-file
+ (let (context part signature) ;; plain signature-file
(when (or (null (setq part (mm-find-raw-part-by-type
ctl (or (mm-handle-multipart-ctl-parameter
ctl 'protocol)
diff --git a/lisp/gnus/mml.el b/lisp/gnus/mml.el
index 5f35e73cd7c..e60d777e0d2 100644
--- a/lisp/gnus/mml.el
+++ b/lisp/gnus/mml.el
@@ -1143,48 +1143,40 @@ If HANDLES is non-nil, use it instead reparsing the buffer."
;;; Mode for inserting and editing MML forms
;;;
-(defvar mml-mode-map
- (let ((sign (make-sparse-keymap))
- (encrypt (make-sparse-keymap))
- (signpart (make-sparse-keymap))
- (encryptpart (make-sparse-keymap))
- (map (make-sparse-keymap))
- (main (make-sparse-keymap)))
- (define-key map "\C-s" 'mml-secure-message-sign)
- (define-key map "\C-c" 'mml-secure-message-encrypt)
- (define-key map "\C-e" 'mml-secure-message-sign-encrypt)
- (define-key map "\C-p\C-s" 'mml-secure-sign)
- (define-key map "\C-p\C-c" 'mml-secure-encrypt)
- (define-key sign "p" 'mml-secure-message-sign-pgpmime)
- (define-key sign "o" 'mml-secure-message-sign-pgp)
- (define-key sign "s" 'mml-secure-message-sign-smime)
- (define-key signpart "p" 'mml-secure-sign-pgpmime)
- (define-key signpart "o" 'mml-secure-sign-pgp)
- (define-key signpart "s" 'mml-secure-sign-smime)
- (define-key encrypt "p" 'mml-secure-message-encrypt-pgpmime)
- (define-key encrypt "o" 'mml-secure-message-encrypt-pgp)
- (define-key encrypt "s" 'mml-secure-message-encrypt-smime)
- (define-key encryptpart "p" 'mml-secure-encrypt-pgpmime)
- (define-key encryptpart "o" 'mml-secure-encrypt-pgp)
- (define-key encryptpart "s" 'mml-secure-encrypt-smime)
- (define-key map "\C-n" 'mml-unsecure-message)
- (define-key map "f" 'mml-attach-file)
- (define-key map "b" 'mml-attach-buffer)
- (define-key map "e" 'mml-attach-external)
- (define-key map "q" 'mml-quote-region)
- (define-key map "m" 'mml-insert-multipart)
- (define-key map "p" 'mml-insert-part)
- (define-key map "v" 'mml-validate)
- (define-key map "P" 'mml-preview)
- (define-key map "s" sign)
- (define-key map "S" signpart)
- (define-key map "c" encrypt)
- (define-key map "C" encryptpart)
- ;;(define-key map "n" 'mml-narrow-to-part)
- ;; `M-m' conflicts with `back-to-indentation'.
- ;; (define-key main "\M-m" map)
- (define-key main "\C-c\C-m" map)
- main))
+(defvar-keymap mml-mode-map
+ "C-c C-m"
+ (define-keymap
+ "C-s" #'mml-secure-message-sign
+ "C-c" #'mml-secure-message-encrypt
+ "C-e" #'mml-secure-message-sign-encrypt
+ "C-p C-s" #'mml-secure-sign
+ "C-p C-c" #'mml-secure-encrypt
+
+ "s" (define-keymap
+ "p" #'mml-secure-message-sign-pgpmime
+ "o" #'mml-secure-message-sign-pgp
+ "s" #'mml-secure-message-sign-smime)
+ "S" (define-keymap
+ "p" #'mml-secure-sign-pgpmime
+ "o" #'mml-secure-sign-pgp
+ "s" #'mml-secure-sign-smime)
+ "c" (define-keymap
+ "p" #'mml-secure-message-encrypt-pgpmime
+ "o" #'mml-secure-message-encrypt-pgp
+ "s" #'mml-secure-message-encrypt-smime)
+ "C" (define-keymap
+ "p" #'mml-secure-encrypt-pgpmime
+ "o" #'mml-secure-encrypt-pgp
+ "s" #'mml-secure-encrypt-smime)
+ "C-n" #'mml-unsecure-message
+ "f" #'mml-attach-file
+ "b" #'mml-attach-buffer
+ "e" #'mml-attach-external
+ "q" #'mml-quote-region
+ "m" #'mml-insert-multipart
+ "p" #'mml-insert-part
+ "v" #'mml-validate
+ "P" #'mml-preview))
(easy-menu-define
mml-menu mml-mode-map ""
@@ -1409,6 +1401,13 @@ to specify options."
:version "22.1" ;; Gnus 5.10.9
:group 'message)
+(defcustom mml-attach-file-at-the-end nil
+ "If non-nil, \\[mml-attach-file] attaches files at the end of the message.
+If nil, files are attached at point."
+ :type 'boolean
+ :version "29.1"
+ :group 'message)
+
;;;###autoload
(defun mml-attach-file (file &optional type description disposition)
"Attach a file to the outgoing MIME message.
@@ -1423,6 +1422,8 @@ specifies how the attachment is intended to be displayed. It can
be either \"inline\" (displayed automatically within the message
body) or \"attachment\" (separate from the body).
+Also see the `mml-attach-file-at-the-end' variable.
+
If given a prefix interactively, no prompting will be done for
the TYPE, DESCRIPTION or DISPOSITION values. Instead defaults
will be computed and used."
@@ -1440,8 +1441,11 @@ will be computed and used."
(mml-minibuffer-read-disposition type nil file))))
(list file type description disposition)))
;; If in the message header, attach at the end and leave point unchanged.
- (let ((head (unless (message-in-body-p) (point))))
- (if head (goto-char (point-max)))
+ (let ((at-end (and (or (not (message-in-body-p))
+ mml-attach-file-at-the-end)
+ (point))))
+ (when at-end
+ (goto-char (point-max)))
(mml-insert-empty-tag 'part
'type type
;; icicles redefines read-file-name and returns a
@@ -1451,13 +1455,13 @@ will be computed and used."
'description description)
;; When using Mail mode, make sure it does the mime encoding
;; when you send the message.
- (or (eq mail-user-agent 'message-user-agent)
- (setq mail-encode-mml t))
- (when head
+ (unless (eq mail-user-agent 'message-user-agent)
+ (setq mail-encode-mml t))
+ (when at-end
(unless (pos-visible-in-window-p)
(message "The file \"%s\" has been attached at the end of the message"
(file-name-nondirectory file)))
- (goto-char head))))
+ (goto-char at-end))))
(defun mml-dnd-attach-file (uri _action)
"Attach a drag and drop file.
diff --git a/lisp/gnus/mml1991.el b/lisp/gnus/mml1991.el
index 05f44a1cbd8..55ef9cf7b37 100644
--- a/lisp/gnus/mml1991.el
+++ b/lisp/gnus/mml1991.el
@@ -259,8 +259,7 @@ Whether the passphrase is cached at all is controlled by
(autoload 'epg-expand-group "epg-config")
(defun mml1991-epg-sign (_cont)
- (let ((inhibit-redisplay t)
- headers cte)
+ (let (headers cte)
;; Don't sign headers.
(goto-char (point-min))
(when (re-search-forward "^$" nil t)
diff --git a/lisp/gnus/mml2015.el b/lisp/gnus/mml2015.el
index 8c40fc79f00..239738114b6 100644
--- a/lisp/gnus/mml2015.el
+++ b/lisp/gnus/mml2015.el
@@ -700,7 +700,6 @@ If set, it overrides the setting of `mml2015-sign-with-sender'."
(defvar epg-user-id-alist)
(defvar epg-digest-algorithm-alist)
(defvar epg-gpg-program)
-(defvar inhibit-redisplay)
(autoload 'epg-make-context "epg")
(autoload 'epg-context-set-armor "epg")
@@ -773,8 +772,7 @@ If set, it overrides the setting of `mml2015-sign-with-sender'."
(defun mml2015-epg-decrypt (handle _ctl)
(catch 'error
- (let ((inhibit-redisplay t)
- context plain child handles) ;; decrypt-status result
+ (let (context plain child handles) ;; decrypt-status result
(unless (setq child (mm-find-part-by-type
(cdr handle)
"application/octet-stream" nil t))
@@ -818,8 +816,7 @@ If set, it overrides the setting of `mml2015-sign-with-sender'."
(list handles)))))
(defun mml2015-epg-clear-decrypt ()
- (let ((inhibit-redisplay t)
- (context (epg-make-context))
+ (let ((context (epg-make-context))
plain)
(if (or mml2015-cache-passphrase mml-secure-cache-passphrase)
(epg-context-set-passphrase-callback
@@ -851,8 +848,7 @@ If set, it overrides the setting of `mml2015-sign-with-sender'."
(defun mml2015-epg-verify (handle ctl)
(catch 'error
- (let ((inhibit-redisplay t)
- context part signature) ;; plain signature-file
+ (let (context part signature) ;; plain signature-file
(when (or (null (setq part (mm-find-raw-part-by-type
ctl (or (mm-handle-multipart-ctl-parameter
ctl 'protocol)
@@ -881,8 +877,7 @@ If set, it overrides the setting of `mml2015-sign-with-sender'."
handle)))
(defun mml2015-epg-clear-verify ()
- (let ((inhibit-redisplay t)
- (context (epg-make-context))
+ (let ((context (epg-make-context))
(signature (encode-coding-string (buffer-string)
coding-system-for-write))
plain)
@@ -904,8 +899,7 @@ If set, it overrides the setting of `mml2015-sign-with-sender'."
(mml2015-extract-cleartext-signature))))
(defun mml2015-epg-sign (cont)
- (let ((inhibit-redisplay t)
- (boundary (mml-compute-boundary cont)))
+ (let ((boundary (mml-compute-boundary cont)))
;; Signed data must end with a newline (RFC 3156, 5).
(goto-char (point-max))
(unless (bolp)
@@ -934,8 +928,7 @@ If set, it overrides the setting of `mml2015-sign-with-sender'."
(goto-char (point-max)))))
(defun mml2015-epg-encrypt (cont &optional sign)
- (let* ((inhibit-redisplay t)
- (boundary (mml-compute-boundary cont))
+ (let* ((boundary (mml-compute-boundary cont))
(cipher (mml-secure-epg-encrypt 'OpenPGP cont sign)))
(delete-region (point-min) (point-max))
(goto-char (point-min))
diff --git a/lisp/gnus/nndiary.el b/lisp/gnus/nndiary.el
index adf4427523f..6f8917e2528 100644
--- a/lisp/gnus/nndiary.el
+++ b/lisp/gnus/nndiary.el
@@ -416,6 +416,11 @@ all. This may very well take some time.")
(deffoo nndiary-open-server (server &optional defs)
(nnoo-change-server 'nndiary server defs)
+ (dolist (header nndiary-headers)
+ (setq header (intern (format "X-Diary-%s" (car header))))
+ ;; Required for building NOV databases and some other stuff.
+ (add-to-list 'gnus-extra-headers header)
+ (add-to-list 'nnmail-extra-headers header))
(when (not (file-exists-p nndiary-directory))
(ignore-errors (make-directory nndiary-directory t)))
(cond
@@ -1303,7 +1308,7 @@ all. This may very well take some time.")
(let ((minute (nndiary-max (nth 0 sched)))
(hour (nndiary-max (nth 1 sched)))
(year (nndiary-max (nth 4 sched)))
- (time-zone (or (and (nth 6 sched) (car (nth 6 sched)))
+ (time-zone (or (car (nth 6 sched))
(current-time-zone))))
(when year
(or minute (setq minute 59))
@@ -1400,7 +1405,7 @@ all. This may very well take some time.")
t))
(dow-list (nth 5 sched))
(year (1- this-year))
- (time-zone (or (and (nth 6 sched) (car (nth 6 sched)))
+ (time-zone (or (car (nth 6 sched))
(current-time-zone))))
;; Special case: an asterisk in one of the days specifications means that
;; only the other should be taken into account. If both are unspecified,
@@ -1557,12 +1562,6 @@ all. This may very well take some time.")
;; The end... ===============================================================
-(dolist (header nndiary-headers)
- (setq header (intern (format "X-Diary-%s" (car header))))
- ;; Required for building NOV databases and some other stuff.
- (add-to-list 'gnus-extra-headers header)
- (add-to-list 'nnmail-extra-headers header))
-
(unless (assoc "nndiary" gnus-valid-select-methods)
(gnus-declare-backend "nndiary" 'post-mail 'respool 'address))
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 8a48cd87dba..b7082696b2c 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -429,8 +429,18 @@ during splitting, which may be slow."
now
(nnimap-last-command-time nnimap-object))))
(with-local-quit
- (ignore-errors ;E.g. "buffer foo has no process".
- (nnimap-send-command "NOOP")))))))))
+ (ignore-errors ;E.g. "buffer foo has no process".
+ (nnimap-send-command "NOOP"))
+ ;; If our connection has died in the meantime, clean it
+ ;; and its buffer up.
+ (unless (process-live-p (get-buffer-process buffer))
+ (setq nnimap-process-buffers
+ (delq buffer nnimap-process-buffers))
+ (setq nnimap-connection-alist
+ (seq-filter (lambda (elt)
+ (null (eq buffer (cdr elt))))
+ nnimap-connection-alist))
+ (kill-buffer buffer)))))))))
(defun nnimap-open-connection (buffer)
;; Be backwards-compatible -- the earlier value of nnimap-stream was
@@ -662,10 +672,17 @@ during splitting, which may be slow."
(deffoo nnimap-close-server (&optional server defs)
(when (nnoo-change-server 'nnimap server defs)
- (ignore-errors
- (delete-process (get-buffer-process (nnimap-buffer))))
- (nnoo-close-server 'nnimap server)
- t))
+ (let ((buf (nnimap-buffer)))
+ (ignore-errors
+ (delete-process (get-buffer-process buf)))
+ (setq nnimap-process-buffers
+ (delq buf nnimap-process-buffers)
+ nnimap-connection-alist
+ (seq-filter (lambda (elt)
+ (null (eq buf (cdr elt))))
+ nnimap-connection-alist))
+ (nnoo-close-server 'nnimap server)
+ t)))
(deffoo nnimap-request-close ()
t)
@@ -1638,15 +1655,13 @@ If LIMIT, first try to limit the search to the N last articles."
(setq start-article 1))
(let* ((unread
(gnus-compress-sequence
- (seq-difference
- (seq-difference
+ (gnus-set-difference
+ (gnus-set-difference
existing
(gnus-sorted-union
(cdr (assoc '%Seen flags))
- (cdr (assoc '%Deleted flags)))
- #'eq)
- (cdr (assoc '%Flagged flags))
- #'eq)))
+ (cdr (assoc '%Deleted flags))))
+ (cdr (assoc '%Flagged flags)))))
(read (gnus-range-difference
(cons start-article high) unread)))
(when (> start-article 1)
@@ -1939,10 +1954,13 @@ Return the server's response to the SELECT or EXAMINE command."
(when entry
(if (and (buffer-live-p (cadr entry))
(get-buffer-process (cadr entry))
- (memq (process-status (get-buffer-process (cadr entry)))
- '(open run)))
+ (process-live-p (get-buffer-process (cadr entry))))
(get-buffer-process (cadr entry))
- (setq nnimap-connection-alist (delq entry nnimap-connection-alist))
+ (setq nnimap-connection-alist (delq entry nnimap-connection-alist)
+ nnimap-process-buffers
+ (delq (cadr entry) nnimap-process-buffers))
+ (when (buffer-live-p (cadr entry))
+ (kill-buffer (cadr entry)))
nil))))
;; Leave room for `open-network-stream' to issue a couple of IMAP
@@ -2289,7 +2307,7 @@ Return the server's response to the SELECT or EXAMINE command."
nnimap-incoming-split-list)))
(defun nnimap-make-thread-query (header)
- (let* ((id (mail-header-id header))
+ (let* ((id (substring-no-properties (mail-header-id header)))
(refs (split-string
(or (mail-header-references header)
"")))
diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el
index 171f0813b38..690761a2d6c 100644
--- a/lisp/gnus/nnmaildir.el
+++ b/lisp/gnus/nnmaildir.el
@@ -194,7 +194,15 @@ This variable is set by `nnmaildir-request-article'.")
(article-file (concat curdir prefix suffix))
(new-name (concat curdir prefix new-suffix)))
(unless (file-exists-p article-file)
- (error "Couldn't find article file %s" article-file))
+ (let ((possible (file-expand-wildcards (concat curdir prefix "*"))))
+ (cond ((length= possible 1)
+ (unless (string-match-p "\\`\\(.+\\):2,.*?\\'" (car possible))
+ (error "Couldn't find updated article file %s" article-file))
+ (setq article-file (car possible)))
+ ((length> possible 1)
+ (error "Couldn't determine exact article file %s" article-file))
+ ((null possible)
+ (error "Couldn't find article file %s" article-file)))))
(rename-file article-file new-name 'replace)
(setf (nnmaildir--art-suffix article) new-suffix)))
diff --git a/lisp/gnus/nnrss.el b/lisp/gnus/nnrss.el
index 97c9f18a602..59a22f725a9 100644
--- a/lisp/gnus/nnrss.el
+++ b/lisp/gnus/nnrss.el
@@ -450,7 +450,7 @@ nnrss: %s: Not valid XML %s and libxml-parse-html-region doesn't work %s"
This function handles the ISO 8601 date format described in
URL `https://www.w3.org/TR/NOTE-datetime', and also the RFC 822 style
which RSS 2.0 allows."
- (let (case-fold-search vector year month day time zone cts given)
+ (let (case-fold-search vector year month day time zone given)
(cond ((null date)) ; do nothing for this case
;; if the date is just digits (unix time stamp):
((string-match "^[0-9]+$" date)
@@ -481,13 +481,13 @@ which RSS 2.0 allows."
0
(decoded-time-zone decoded))))))
(if month
- (progn
- (setq cts (current-time-string (encode-time 0 0 0 day month year)))
- (format "%s, %02d %s %04d %s%s"
- (substring cts 0 3) day (substring cts 4 7) year time
- (if zone
- (concat " " (format-time-string "%z" nil zone))
- "")))
+ (concat (let ((system-time-locale "C"))
+ (format-time-string "%a, %d %b %Y "
+ (encode-time 0 0 0 day month year)))
+ time
+ (if zone
+ (format-time-string " %z" nil zone)
+ ""))
(message-make-date given))))
;;; data functions
@@ -715,7 +715,7 @@ Read the file and attempt to subscribe to each Feed in the file."
(when (and xmlurl
(not (string-match "\\`[\t ]*\\'" xmlurl))
(prog1
- (y-or-n-p (format "Subscribe to %s " xmlurl))
+ (y-or-n-p (format "Subscribe to %s?" xmlurl))
(message "")))
(condition-case err
(progn
diff --git a/lisp/gnus/nnselect.el b/lisp/gnus/nnselect.el
index ecec705b326..252e9f66838 100644
--- a/lisp/gnus/nnselect.el
+++ b/lisp/gnus/nnselect.el
@@ -779,6 +779,10 @@ Return an article list."
(args (alist-get 'nnselect-args specs)))
(condition-case-unless-debug err
(funcall func args)
+ ;; Don't swallow gnus-search errors; the user should be made
+ ;; aware of them.
+ (gnus-search-error
+ (signal (car err) (cdr err)))
(error (gnus-error 3 "nnselect-run: %s on %s gave error %s" func args err)
[]))))
diff --git a/lisp/gnus/nntp.el b/lisp/gnus/nntp.el
index 615a3c931bf..25289655bf2 100644
--- a/lisp/gnus/nntp.el
+++ b/lisp/gnus/nntp.el
@@ -331,9 +331,7 @@ retried once before actually displaying the error report."
(when nntp-record-commands
(nntp-record-command "*** CALLED nntp-report ***"))
- (nnheader-report 'nntp args)
-
- (apply #'error args)))
+ (nnheader-report 'nntp args)))
(defsubst nntp-copy-to-buffer (buffer start end)
"Copy string from unibyte current buffer to multibyte buffer."
diff --git a/lisp/gnus/nnvirtual.el b/lisp/gnus/nnvirtual.el
index 03a0ff296f2..41a2da958a0 100644
--- a/lisp/gnus/nnvirtual.el
+++ b/lisp/gnus/nnvirtual.el
@@ -382,7 +382,10 @@ It is computed from the marks of individual component groups.")
(defun nnvirtual-update-xref-header (group article prefix sysname)
- "Edit current NOV header in current buffer to have an xref to the component group, and also server prefix any existing xref lines."
+ "Edit current NOV header to have xref to component group and correct prefix.
+This function edits the current NOV header in current buffer so that it
+has an xref to the component group, and also ensures any existing xref
+lines have the correct component server prefix."
;; Move to beginning of Xref field, creating a slot if needed.
(beginning-of-line)
(looking-at
@@ -569,7 +572,9 @@ If UPDATE-P is not nil, call gnus-group-update-group on the components."
;; unique reverse mapping.
(defun nnvirtual-map-article (article)
- "Return a cons of the component group and article corresponding to the given virtual ARTICLE."
+ "Return the component group and article corresponding to virtual ARTICLE.
+Value is a cons of the component group and article corresponding to the given
+virtual ARTICLE."
(let ((table nnvirtual-mapping-table)
entry group-pos)
(while (and table
@@ -590,7 +595,7 @@ If UPDATE-P is not nil, call gnus-group-update-group on the components."
(defun nnvirtual-reverse-map-article (group article)
- "Return the virtual article number corresponding to the given component GROUP and ARTICLE."
+ "Return virtual article number corresponding to component GROUP and ARTICLE."
(when (numberp article)
(let ((table nnvirtual-mapping-table)
(group-pos 0)
diff --git a/lisp/gnus/spam.el b/lisp/gnus/spam.el
index 3f978918b9a..508ef5424ea 100644
--- a/lisp/gnus/spam.el
+++ b/lisp/gnus/spam.el
@@ -663,13 +663,13 @@ order for SpamAssassin to recognize the new registered spam."
;;; Key bindings for spam control.
-(gnus-define-keys gnus-summary-mode-map
- "St" spam-generic-score
- "Sx" gnus-summary-mark-as-spam
- "Mst" spam-generic-score
- "Msx" gnus-summary-mark-as-spam
- "\M-d" gnus-summary-mark-as-spam
- "$" gnus-summary-mark-as-spam)
+(define-keymap :keymap gnus-summary-mode-map
+ "S t" #'spam-generic-score
+ "S x" #'gnus-summary-mark-as-spam
+ "M s t" #'spam-generic-score
+ "M s x" #'gnus-summary-mark-as-spam
+ "M-d" #'gnus-summary-mark-as-spam
+ "$" #'gnus-summary-mark-as-spam)
(defvar spam-cache-lookups t
"Whether spam.el will try to cache lookups using `spam-caches'.")
@@ -710,8 +710,16 @@ finds ham or spam.")
(defun spam-set-difference (list1 list2)
"Return a set difference of LIST1 and LIST2.
When either list is nil, the other is returned."
- (declare (obsolete seq-difference "28.1"))
- (seq-difference list1 list2 #'eq))
+ (if (and list1 list2)
+ ;; we have two non-nil lists
+ (progn
+ (dolist (item (append list1 list2))
+ (when (and (memq item list1) (memq item list2))
+ (setq list1 (delq item list1))
+ (setq list2 (delq item list2))))
+ (append list1 list2))
+ ;; if either of the lists was nil, return the other one
+ (if list1 list1 list2)))
(defun spam-group-ham-mark-p (group mark &optional spam)
"Checks if MARK is considered a ham mark in GROUP."
@@ -1319,7 +1327,7 @@ In the case of mover backends, checks the setting of
(new-articles (spam-list-articles
gnus-newsgroup-articles
classification))
- (changed-articles (seq-difference new-articles old-articles #'eq)))
+ (changed-articles (spam-set-difference new-articles old-articles)))
;; now that we have the changed articles, we go through the processors
(dolist (backend (spam-backend-list))
(let (unregister-list)
diff --git a/lisp/help-at-pt.el b/lisp/help-at-pt.el
index 233c50504bf..8eb397bc82d 100644
--- a/lisp/help-at-pt.el
+++ b/lisp/help-at-pt.el
@@ -229,11 +229,11 @@ this option, or use \"In certain situations\" and specify no text
properties, to enable buffer local values."
never))
:initialize 'custom-initialize-default
- :set #'(lambda (variable value)
- (set-default variable value)
- (if (eq value 'never)
- (help-at-pt-cancel-timer)
- (help-at-pt-set-timer)))
+ :set (lambda (variable value)
+ (set-default variable value)
+ (if (eq value 'never)
+ (help-at-pt-cancel-timer)
+ (help-at-pt-set-timer)))
:set-after '(help-at-pt-timer-delay)
:require 'help-at-pt)
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index 2c7956d9680..32698420e1f 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -64,6 +64,12 @@ described in `help-fns-describe-variable-functions', except that
the functions are called with two parameters: The face and the
frame.")
+(defvar help-fns--activated-functions nil
+ "Internal variable let-bound to help functions that have triggered.
+Help functions can check the contents of this list to see whether
+a specific previous help function has inserted something in the
+current help buffer.")
+
;; Functions
(defvar help-definition-prefixes nil
@@ -126,6 +132,12 @@ with the current prefix. The files are chosen according to
:group 'help
:version "26.3")
+(defcustom help-enable-symbol-autoload nil
+ "Perform autoload if docs are missing from autoload objects."
+ :type 'boolean
+ :group 'help
+ :version "28.1")
+
(defun help--symbol-class (s)
"Return symbol class characters for symbol S."
(when (stringp s)
@@ -164,8 +176,11 @@ with the current prefix. The files are chosen according to
completions))
(defun help--symbol-completion-table (string pred action)
- (if (and completions-detailed (eq action 'metadata))
- '(metadata (affixation-function . help--symbol-completion-table-affixation))
+ (if (eq action 'metadata)
+ `(metadata
+ ,@(when completions-detailed
+ '((affixation-function . help--symbol-completion-table-affixation)))
+ (category . symbol-help))
(when help-enable-completion-autoload
(let ((prefixes (radix-tree-prefixes (help-definition-prefixes) string)))
(help--load-prefixes prefixes)))
@@ -221,7 +236,10 @@ interactive command."
;;;###autoload
(defun describe-function (function)
"Display the full documentation of FUNCTION (a symbol).
-When called from lisp, FUNCTION may also be a function object."
+When called from Lisp, FUNCTION may also be a function object.
+
+See the `help-enable-symbol-autoload' variable for special
+handling of autoloaded functions."
(interactive (help-fns--describe-function-or-command-prompt))
;; We save describe-function-orig-buffer on the help xref stack, so
@@ -231,7 +249,8 @@ When called from lisp, FUNCTION may also be a function object."
;; calling that.
(let ((describe-function-orig-buffer
(or describe-function-orig-buffer
- (current-buffer))))
+ (current-buffer)))
+ (help-buffer-under-preparation t))
(help-setup-xref
(list (lambda (function buffer)
@@ -257,7 +276,7 @@ When called from lisp, FUNCTION may also be a function object."
;;;###autoload
(defun describe-command (command)
"Display the full documentation of COMMAND (a symbol).
-When called from lisp, COMMAND may also be a function object."
+When called from Lisp, COMMAND may also be a function object."
(interactive (help-fns--describe-function-or-command-prompt 'is-command))
(describe-function command))
@@ -723,8 +742,12 @@ FILE is the file where FUNCTION was probably defined."
(add-hook 'help-fns-describe-variable-functions
#'help-fns--mention-first-release)
(defun help-fns--mention-first-release (object)
- (let ((first (if (symbolp object) (help-fns--first-release object))))
- (when first
+ ;; Don't output anything if we've already output the :version from
+ ;; the `defcustom'.
+ (unless (memq 'help-fns--customize-variable-version
+ help-fns--activated-functions)
+ (when-let ((first (and (symbolp object)
+ (help-fns--first-release object))))
(with-current-buffer standard-output
(insert (format " Probably introduced at or before Emacs version %s.\n"
first))))))
@@ -801,7 +824,7 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)."
;; Advised & aliased function.
(and advised (symbolp real-function)
(not (eq 'autoload (car-safe def))))
- (and (subrp def)
+ (and (subrp def) (symbolp function)
(not (string= (subr-name def)
(symbol-name function)))))))
(real-def (cond
@@ -813,6 +836,16 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)."
f))
((subrp def) (intern (subr-name def)))
(t def))))
+
+ ;; If we don't have a doc string, then try to load the file.
+ (when (and help-enable-symbol-autoload
+ (autoloadp real-def)
+ ;; Empty documentation slot.
+ (not (nth 2 real-def)))
+ (condition-case err
+ (autoload-do-load real-def)
+ (error (message "Error while autoloading: %S" err))))
+
(list real-function def aliased real-def)))
(defun help-fns-function-description-header (function)
@@ -950,9 +983,9 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)."
;; E.g. an alias for a not yet defined function.
((invalid-function void-function) doc-raw))))
(help-fns--ensure-empty-line)
- (run-hook-with-args 'help-fns-describe-function-functions function)
- (help-fns--ensure-empty-line)
- (insert (or doc "Not documented.")))
+ (insert (or doc "Not documented."))
+ (help-fns--run-describe-functions
+ help-fns-describe-function-functions function))
;; Avoid asking the user annoying questions if she decides
;; to save the help buffer, when her locale's codeset
;; isn't UTF-8.
@@ -1046,7 +1079,8 @@ it is displayed along with the global value."
(if (symbolp v) (symbol-name v))))
(list (if (equal val "")
v (intern val)))))
- (let (file-name)
+ (let (file-name
+ (help-buffer-under-preparation t))
(unless (buffer-live-p buffer) (setq buffer (current-buffer)))
(unless (frame-live-p frame) (setq frame (selected-frame)))
(if (not (symbolp variable))
@@ -1152,7 +1186,7 @@ it is displayed along with the global value."
(princ (format "Local in buffer %s; "
(buffer-name buffer))))
((terminal-live-p locus)
- (princ (format "It is a terminal-local variable; ")))
+ (princ "It is a terminal-local variable; "))
(t
(princ (format "It is local to %S" locus))))
(if (not (default-boundp variable))
@@ -1186,10 +1220,6 @@ it is displayed along with the global value."
;; of a symbol.
(set-syntax-table emacs-lisp-mode-syntax-table)
(goto-char val-start-pos)
- ;; The line below previously read as
- ;; (delete-region (point) (progn (end-of-line) (point)))
- ;; which suppressed display of the buffer local value for
- ;; large values.
(when (looking-at "value is") (replace-match ""))
(save-excursion
(insert "\n\nValue:")
@@ -1210,19 +1240,40 @@ it is displayed along with the global value."
(documentation-property
alias 'variable-documentation))))
+ (with-current-buffer standard-output
+ (insert (or doc "Not documented as a variable.")))
+
+ ;; Output the indented administrative bits.
(with-current-buffer buffer
- (run-hook-with-args 'help-fns-describe-variable-functions
- variable))
+ (help-fns--run-describe-functions
+ help-fns-describe-variable-functions variable))
(with-current-buffer standard-output
- (help-fns--ensure-empty-line))
- (with-current-buffer standard-output
- (insert (or doc "Not documented as a variable."))))
+ ;; If we have the long value of the variable at the
+ ;; end, remove superfluous empty lines before it.
+ (unless (eobp)
+ (while (looking-at-p "\n")
+ (delete-char 1)))))
(with-current-buffer standard-output
;; Return the text we displayed.
(buffer-string))))))))
+(defun help-fns--run-describe-functions (functions &rest args)
+ (with-current-buffer standard-output
+ (unless (bolp)
+ (insert "\n"))
+ (help-fns--ensure-empty-line))
+ (let ((help-fns--activated-functions nil))
+ (dolist (func functions)
+ (let ((size (buffer-size standard-output)))
+ (apply func args)
+ ;; This function inserted something, so register it.
+ (when (> (buffer-size standard-output) size)
+ (push func help-fns--activated-functions)))))
+ (with-current-buffer standard-output
+ (help-fns--ensure-empty-line)))
+
(add-hook 'help-fns-describe-variable-functions #'help-fns--customize-variable)
(defun help-fns--customize-variable (variable &optional text)
;; Make a link to customize if this variable can be customized.
@@ -1234,13 +1285,15 @@ it is displayed along with the global value."
(re-search-backward
(concat "\\(" customize-label "\\)") nil t)
(help-xref-button 1 'help-customize-variable variable)))
- (terpri))
+ (terpri))))
+
+(add-hook 'help-fns-describe-variable-functions
+ #'help-fns--customize-variable-version)
+(defun help-fns--customize-variable-version (variable)
+ (when (custom-variable-p variable)
;; Note variable's version or package version.
- (let ((output (describe-variable-custom-version-info variable)))
- (when output
- ;; (terpri)
- ;; (terpri)
- (princ output)))))
+ (when-let ((output (describe-variable-custom-version-info variable)))
+ (princ output))))
(add-hook 'help-fns-describe-variable-functions #'help-fns--var-safe-local)
(defun help-fns--var-safe-local (variable)
@@ -1410,76 +1463,78 @@ If FRAME is omitted or nil, use the selected frame."
(interactive (list (read-face-name "Describe face"
(or (face-at-point t) 'default)
t)))
- (help-setup-xref (list #'describe-face face)
- (called-interactively-p 'interactive))
- (unless face
- (setq face 'default))
- (if (not (listp face))
- (setq face (list face)))
- (with-help-window (help-buffer)
- (with-current-buffer standard-output
- (dolist (f face (buffer-string))
- (if (stringp f) (setq f (intern f)))
- ;; We may get called for anonymous faces (i.e., faces
- ;; expressed using prop-value plists). Those can't be
- ;; usefully customized, so ignore them.
- (when (symbolp f)
- (insert "Face: " (symbol-name f))
- (if (not (facep f))
- (insert " undefined face.\n")
- (let ((customize-label "customize this face")
- file-name)
- (insert (concat " (" (propertize "sample" 'font-lock-face f) ")"))
- (princ (concat " (" customize-label ")\n"))
- ;; FIXME not sure how much of this belongs here, and
- ;; how much in `face-documentation'. The latter is
- ;; not used much, but needs to return nil for
- ;; undocumented faces.
- (let ((alias (get f 'face-alias))
- (face f)
- obsolete)
- (when alias
- (setq face alias)
- (insert
- (format-message
- "\n %s is an alias for the face `%s'.\n%s"
- f alias
- (if (setq obsolete (get f 'obsolete-face))
- (format-message
- " This face is obsolete%s; use `%s' instead.\n"
- (if (stringp obsolete)
- (format " since %s" obsolete)
- "")
- alias)
- ""))))
- (insert "\nDocumentation:\n"
- (substitute-command-keys
- (or (face-documentation face)
- "Not documented as a face."))
- "\n\n"))
- (with-current-buffer standard-output
- (save-excursion
- (re-search-backward
- (concat "\\(" customize-label "\\)") nil t)
- (help-xref-button 1 'help-customize-face f)))
- (setq file-name (find-lisp-object-file-name f 'defface))
- (if (not file-name)
- (setq help-mode--current-data (list :symbol f))
- (setq help-mode--current-data (list :symbol f
- :file file-name))
- (princ (substitute-command-keys "Defined in `"))
- (princ (help-fns-short-filename file-name))
- (princ (substitute-command-keys "'"))
- ;; Make a hyperlink to the library.
- (save-excursion
- (re-search-backward
- (substitute-command-keys "`\\([^`']+\\)'") nil t)
- (help-xref-button 1 'help-face-def f file-name))
- (princ ".")
- (terpri)
- (terpri))))
- (terpri)
- (run-hook-with-args 'help-fns-describe-face-functions f frame))))))
+ (let ((help-buffer-under-preparation t))
+ (help-setup-xref (list #'describe-face face)
+ (called-interactively-p 'interactive))
+ (unless face
+ (setq face 'default))
+ (if (not (listp face))
+ (setq face (list face)))
+ (with-help-window (help-buffer)
+ (with-current-buffer standard-output
+ (dolist (f face (buffer-string))
+ (if (stringp f) (setq f (intern f)))
+ ;; We may get called for anonymous faces (i.e., faces
+ ;; expressed using prop-value plists). Those can't be
+ ;; usefully customized, so ignore them.
+ (when (symbolp f)
+ (insert "Face: " (symbol-name f))
+ (if (not (facep f))
+ (insert " undefined face.\n")
+ (let ((customize-label "customize this face")
+ file-name)
+ (insert (concat " (" (propertize "sample" 'font-lock-face f) ")"))
+ (princ (concat " (" customize-label ")\n"))
+ ;; FIXME not sure how much of this belongs here, and
+ ;; how much in `face-documentation'. The latter is
+ ;; not used much, but needs to return nil for
+ ;; undocumented faces.
+ (let ((alias (get f 'face-alias))
+ (face f)
+ obsolete)
+ (when alias
+ (setq face alias)
+ (insert
+ (format-message
+ "\n %s is an alias for the face `%s'.\n%s"
+ f alias
+ (if (setq obsolete (get f 'obsolete-face))
+ (format-message
+ " This face is obsolete%s; use `%s' instead.\n"
+ (if (stringp obsolete)
+ (format " since %s" obsolete)
+ "")
+ alias)
+ ""))))
+ (insert "\nDocumentation:\n"
+ (substitute-command-keys
+ (or (face-documentation face)
+ "Not documented as a face."))
+ "\n\n"))
+ (with-current-buffer standard-output
+ (save-excursion
+ (re-search-backward
+ (concat "\\(" customize-label "\\)") nil t)
+ (help-xref-button 1 'help-customize-face f)))
+ (setq file-name (find-lisp-object-file-name f 'defface))
+ (if (not file-name)
+ (setq help-mode--current-data (list :symbol f))
+ (setq help-mode--current-data (list :symbol f
+ :file file-name))
+ (princ (substitute-command-keys "Defined in `"))
+ (princ (help-fns-short-filename file-name))
+ (princ (substitute-command-keys "'"))
+ ;; Make a hyperlink to the library.
+ (save-excursion
+ (re-search-backward
+ (substitute-command-keys "`\\([^`']+\\)'") nil t)
+ (help-xref-button 1 'help-face-def f file-name))
+ (princ ".")
+ (terpri)
+ (terpri))))
+ (terpri)
+ (help-fns--run-describe-functions
+ help-fns-describe-face-functions f frame)))))))
(add-hook 'help-fns-describe-face-functions
#'help-fns--face-custom-version-info)
@@ -1509,7 +1564,7 @@ If FRAME is omitted or nil, use the selected frame."
(:fontset . "Fontset")
(:extend . "Extend")
(:inherit . "Inherit")))
- (max-width (apply #'max (mapcar #'(lambda (x) (length (cdr x)))
+ (max-width (apply #'max (mapcar (lambda (x) (length (cdr x)))
attrs))))
(dolist (a attrs)
(let ((attr (face-attribute face (car a) frame)))
@@ -1550,43 +1605,44 @@ current buffer and the selected frame, respectively."
(if found (symbol-name v-or-f)))))
(list (if (equal val "")
(or v-or-f "") (intern val)))))
- (if (not (symbolp symbol))
- (user-error "You didn't specify a function or variable"))
- (unless (buffer-live-p buffer) (setq buffer (current-buffer)))
- (unless (frame-live-p frame) (setq frame (selected-frame)))
- (with-current-buffer (help-buffer)
- ;; Push the previous item on the stack before clobbering the output buffer.
- (help-setup-xref nil nil)
- (let* ((docs
- (nreverse
- (delq nil
- (mapcar (pcase-lambda (`(,name ,testfn ,descfn))
- (when (funcall testfn symbol)
- ;; Don't record the current entry in the stack.
- (setq help-xref-stack-item nil)
- (cons name
- (funcall descfn symbol buffer frame))))
- describe-symbol-backends))))
- (single (null (cdr docs))))
- (while (cdr docs)
- (goto-char (point-min))
- (let ((inhibit-read-only t)
- (name (caar docs)) ;Name of doc currently at BOB.
- (doc (cdr (cadr docs)))) ;Doc to add at BOB.
- (when doc
- (insert doc)
- (delete-region (point)
- (progn (skip-chars-backward " \t\n") (point)))
- (insert "\n\n" (make-separator-line) "\n")
- (when name
- (insert (symbol-name symbol)
- " is also a " name "." "\n\n"))))
- (setq docs (cdr docs)))
- (unless single
- ;; Don't record the `describe-variable' item in the stack.
- (setq help-xref-stack-item nil)
- (help-setup-xref (list #'describe-symbol symbol) nil))
- (goto-char (point-min)))))
+ (let ((help-buffer-under-preparation t))
+ (if (not (symbolp symbol))
+ (user-error "You didn't specify a function or variable"))
+ (unless (buffer-live-p buffer) (setq buffer (current-buffer)))
+ (unless (frame-live-p frame) (setq frame (selected-frame)))
+ (with-current-buffer (help-buffer)
+ ;; Push the previous item on the stack before clobbering the output buffer.
+ (help-setup-xref nil nil)
+ (let* ((docs
+ (nreverse
+ (delq nil
+ (mapcar (pcase-lambda (`(,name ,testfn ,descfn))
+ (when (funcall testfn symbol)
+ ;; Don't record the current entry in the stack.
+ (setq help-xref-stack-item nil)
+ (cons name
+ (funcall descfn symbol buffer frame))))
+ describe-symbol-backends))))
+ (single (null (cdr docs))))
+ (while (cdr docs)
+ (goto-char (point-min))
+ (let ((inhibit-read-only t)
+ (name (caar docs)) ;Name of doc currently at BOB.
+ (doc (cdr (cadr docs)))) ;Doc to add at BOB.
+ (when doc
+ (insert doc)
+ (delete-region (point)
+ (progn (skip-chars-backward " \t\n") (point)))
+ (insert "\n\n" (make-separator-line) "\n")
+ (when name
+ (insert (symbol-name symbol)
+ " is also a " name "." "\n\n"))))
+ (setq docs (cdr docs)))
+ (unless single
+ ;; Don't record the `describe-variable' item in the stack.
+ (setq help-xref-stack-item nil)
+ (help-setup-xref (list #'describe-symbol symbol) nil))
+ (goto-char (point-min))))))
;;;###autoload
(defun describe-syntax (&optional buffer)
@@ -1595,15 +1651,16 @@ The descriptions are inserted in a help buffer, which is then displayed.
BUFFER defaults to the current buffer."
(interactive)
(setq buffer (or buffer (current-buffer)))
- (help-setup-xref (list #'describe-syntax buffer)
- (called-interactively-p 'interactive))
- (with-help-window (help-buffer)
- (let ((table (with-current-buffer buffer (syntax-table))))
- (with-current-buffer standard-output
- (describe-vector table 'internal-describe-syntax-value)
- (while (setq table (char-table-parent table))
- (insert "\nThe parent syntax table is:")
- (describe-vector table 'internal-describe-syntax-value))))))
+ (let ((help-buffer-under-preparation t))
+ (help-setup-xref (list #'describe-syntax buffer)
+ (called-interactively-p 'interactive))
+ (with-help-window (help-buffer)
+ (let ((table (with-current-buffer buffer (syntax-table))))
+ (with-current-buffer standard-output
+ (describe-vector table 'internal-describe-syntax-value)
+ (while (setq table (char-table-parent table))
+ (insert "\nThe parent syntax table is:")
+ (describe-vector table 'internal-describe-syntax-value)))))))
(defun help-describe-category-set (value)
(insert (cond
@@ -1611,7 +1668,7 @@ BUFFER defaults to the current buffer."
((char-table-p value) "deeper char-table ...")
(t (condition-case nil
(category-set-mnemonics value)
- (error "invalid"))))))
+ (error "Invalid"))))))
;;;###autoload
(defun describe-categories (&optional buffer)
@@ -1620,59 +1677,60 @@ The descriptions are inserted in a buffer, which is then displayed.
If BUFFER is non-nil, then describe BUFFER's category table instead.
BUFFER should be a buffer or a buffer name."
(interactive)
- (setq buffer (or buffer (current-buffer)))
- (help-setup-xref (list #'describe-categories buffer)
- (called-interactively-p 'interactive))
- (with-help-window (help-buffer)
- (let* ((table (with-current-buffer buffer (category-table)))
- (docs (char-table-extra-slot table 0)))
- (if (or (not (vectorp docs)) (/= (length docs) 95))
- (error "Invalid first extra slot in this category table\n"))
- (with-current-buffer standard-output
- (setq-default help-button-cache (make-marker))
- (insert "Legend of category mnemonics ")
- (insert-button "(longer descriptions at the bottom)"
- 'action help-button-cache
- 'follow-link t
- 'help-echo "mouse-2, RET: show full legend")
- (insert "\n")
- (let ((pos (point)) (items 0) lines n)
- (dotimes (i 95)
- (if (aref docs i) (setq items (1+ items))))
- (setq lines (1+ (/ (1- items) 4)))
- (setq n 0)
+ (let ((help-buffer-under-preparation t))
+ (setq buffer (or buffer (current-buffer)))
+ (help-setup-xref (list #'describe-categories buffer)
+ (called-interactively-p 'interactive))
+ (with-help-window (help-buffer)
+ (let* ((table (with-current-buffer buffer (category-table)))
+ (docs (char-table-extra-slot table 0)))
+ (if (or (not (vectorp docs)) (/= (length docs) 95))
+ (error "Invalid first extra slot in this category table\n"))
+ (with-current-buffer standard-output
+ (setq-default help-button-cache (make-marker))
+ (insert "Legend of category mnemonics ")
+ (insert-button "(longer descriptions at the bottom)"
+ 'action help-button-cache
+ 'follow-link t
+ 'help-echo "mouse-2, RET: show full legend")
+ (insert "\n")
+ (let ((pos (point)) (items 0) lines n)
+ (dotimes (i 95)
+ (if (aref docs i) (setq items (1+ items))))
+ (setq lines (1+ (/ (1- items) 4)))
+ (setq n 0)
+ (dotimes (i 95)
+ (let ((elt (aref docs i)))
+ (when elt
+ (string-match ".*" elt)
+ (setq elt (match-string 0 elt))
+ (if (>= (length elt) 17)
+ (setq elt (concat (substring elt 0 14) "...")))
+ (if (< (point) (point-max))
+ (move-to-column (* 20 (/ n lines)) t))
+ (insert (+ i ?\s) ?: elt)
+ (if (< (point) (point-max))
+ (forward-line 1)
+ (insert "\n"))
+ (setq n (1+ n))
+ (if (= (% n lines) 0)
+ (goto-char pos))))))
+ (goto-char (point-max))
+ (insert "\n"
+ "character(s)\tcategory mnemonics\n"
+ "------------\t------------------")
+ (describe-vector table 'help-describe-category-set)
+ (set-marker help-button-cache (point))
+ (insert "Legend of category mnemonics:\n")
(dotimes (i 95)
(let ((elt (aref docs i)))
(when elt
- (string-match ".*" elt)
- (setq elt (match-string 0 elt))
- (if (>= (length elt) 17)
- (setq elt (concat (substring elt 0 14) "...")))
- (if (< (point) (point-max))
- (move-to-column (* 20 (/ n lines)) t))
- (insert (+ i ?\s) ?: elt)
- (if (< (point) (point-max))
- (forward-line 1)
- (insert "\n"))
- (setq n (1+ n))
- (if (= (% n lines) 0)
- (goto-char pos))))))
- (goto-char (point-max))
- (insert "\n"
- "character(s)\tcategory mnemonics\n"
- "------------\t------------------")
- (describe-vector table 'help-describe-category-set)
- (set-marker help-button-cache (point))
- (insert "Legend of category mnemonics:\n")
- (dotimes (i 95)
- (let ((elt (aref docs i)))
- (when elt
- (if (string-match "\n" elt)
- (setq elt (substring elt (match-end 0))))
- (insert (+ i ?\s) ": " elt "\n"))))
- (while (setq table (char-table-parent table))
- (insert "\nThe parent category table is:")
- (describe-vector table 'help-describe-category-set))))))
+ (if (string-match "\n" elt)
+ (setq elt (substring elt (match-end 0))))
+ (insert (+ i ?\s) ": " elt "\n"))))
+ (while (setq table (char-table-parent table))
+ (insert "\nThe parent category table is:")
+ (describe-vector table 'help-describe-category-set)))))))
(defun help-fns-find-keymap-name (keymap)
"Find the name of the variable with value KEYMAP.
@@ -1726,7 +1784,8 @@ keymap value."
(unless (and km (keymapp (symbol-value km)))
(user-error "Not a keymap: %s" km))
(list km)))
- (let (used-gentemp)
+ (let (used-gentemp
+ (help-buffer-under-preparation t))
(unless (and (symbolp keymap)
(boundp keymap)
(keymapp (symbol-value keymap)))
@@ -1792,106 +1851,107 @@ whose documentation describes the minor mode.
If called from Lisp with a non-nil BUFFER argument, display
documentation for the major and minor modes of that buffer."
(interactive "@")
- (unless buffer (setq buffer (current-buffer)))
- (help-setup-xref (list #'describe-mode buffer)
- (called-interactively-p 'interactive))
- ;; For the sake of help-do-xref and help-xref-go-back,
- ;; don't switch buffers before calling `help-buffer'.
- (with-help-window (help-buffer)
- (with-current-buffer buffer
- (let (minors)
- ;; Older packages do not register in minor-mode-list but only in
- ;; minor-mode-alist.
- (dolist (x minor-mode-alist)
- (setq x (car x))
- (unless (memq x minor-mode-list)
- (push x minor-mode-list)))
- ;; Find enabled minor mode we will want to mention.
- (dolist (mode minor-mode-list)
- ;; Document a minor mode if it is listed in minor-mode-alist,
- ;; non-nil, and has a function definition.
- (let ((fmode (or (get mode :minor-mode-function) mode)))
- (and (boundp mode) (symbol-value mode)
- (fboundp fmode)
- (let ((pretty-minor-mode
- (if (string-match "\\(\\(-minor\\)?-mode\\)?\\'"
- (symbol-name fmode))
- (capitalize
- (substring (symbol-name fmode)
- 0 (match-beginning 0)))
- fmode)))
- (push (list fmode pretty-minor-mode
- (format-mode-line (assq mode minor-mode-alist)))
- minors)))))
- ;; Narrowing is not a minor mode, but its indicator is part of
- ;; mode-line-modes.
- (when (buffer-narrowed-p)
- (push '(narrow-to-region "Narrow" " Narrow") minors))
- (setq minors
- (sort minors
- (lambda (a b) (string-lessp (cadr a) (cadr b)))))
- (when minors
- (princ "Enabled minor modes:\n")
- (make-local-variable 'help-button-cache)
- (with-current-buffer standard-output
- (dolist (mode minors)
- (let ((mode-function (nth 0 mode))
- (pretty-minor-mode (nth 1 mode))
- (indicator (nth 2 mode)))
- (save-excursion
- (goto-char (point-max))
- (princ "\n\f\n")
- (push (point-marker) help-button-cache)
- ;; Document the minor modes fully.
- (insert-text-button
- pretty-minor-mode 'type 'help-function
- 'help-args (list mode-function)
- 'button '(t))
- (princ (format " minor mode (%s):\n"
- (if (zerop (length indicator))
- "no indicator"
- (format "indicator%s"
- indicator))))
- (princ (help-split-fundoc (documentation mode-function)
- nil 'doc)))
- (insert-button pretty-minor-mode
- 'action (car help-button-cache)
- 'follow-link t
- 'help-echo "mouse-2, RET: show full information")
- (newline)))
- (forward-line -1)
- (fill-paragraph nil)
- (forward-line 1))
-
- (princ "\n(Information about these minor modes follows the major mode info.)\n\n"))
- ;; Document the major mode.
- (let ((mode mode-name))
- (with-current-buffer standard-output
- (let ((start (point)))
- (insert (format-mode-line mode nil nil buffer))
- (add-text-properties start (point) '(face bold)))))
- (princ " mode")
- (let* ((mode major-mode)
- (file-name (find-lisp-object-file-name mode nil)))
- (if (not file-name)
- (setq help-mode--current-data (list :symbol mode))
- (princ (format-message " defined in `%s'"
- (help-fns-short-filename file-name)))
- ;; Make a hyperlink to the library.
+ (let ((help-buffer-under-preparation t))
+ (unless buffer (setq buffer (current-buffer)))
+ (help-setup-xref (list #'describe-mode buffer)
+ (called-interactively-p 'interactive))
+ ;; For the sake of help-do-xref and help-xref-go-back,
+ ;; don't switch buffers before calling `help-buffer'.
+ (with-help-window (help-buffer)
+ (with-current-buffer buffer
+ (let (minors)
+ ;; Older packages do not register in minor-mode-list but only in
+ ;; minor-mode-alist.
+ (dolist (x minor-mode-alist)
+ (setq x (car x))
+ (unless (memq x minor-mode-list)
+ (push x minor-mode-list)))
+ ;; Find enabled minor mode we will want to mention.
+ (dolist (mode minor-mode-list)
+ ;; Document a minor mode if it is listed in minor-mode-alist,
+ ;; non-nil, and has a function definition.
+ (let ((fmode (or (get mode :minor-mode-function) mode)))
+ (and (boundp mode) (symbol-value mode)
+ (fboundp fmode)
+ (let ((pretty-minor-mode
+ (if (string-match "\\(\\(-minor\\)?-mode\\)?\\'"
+ (symbol-name fmode))
+ (capitalize
+ (substring (symbol-name fmode)
+ 0 (match-beginning 0)))
+ fmode)))
+ (push (list fmode pretty-minor-mode
+ (format-mode-line (assq mode minor-mode-alist)))
+ minors)))))
+ ;; Narrowing is not a minor mode, but its indicator is part of
+ ;; mode-line-modes.
+ (when (buffer-narrowed-p)
+ (push '(narrow-to-region "Narrow" " Narrow") minors))
+ (setq minors
+ (sort minors
+ (lambda (a b) (string-lessp (cadr a) (cadr b)))))
+ (when minors
+ (princ "Enabled minor modes:\n")
+ (make-local-variable 'help-button-cache)
(with-current-buffer standard-output
- (save-excursion
- (re-search-backward (substitute-command-keys "`\\([^`']+\\)'")
- nil t)
- (setq help-mode--current-data (list :symbol mode
- :file file-name))
- (help-xref-button 1 'help-function-def mode file-name)))))
- (let ((fundoc (help-split-fundoc (documentation major-mode) nil 'doc)))
- (with-current-buffer standard-output
- (insert ":\n")
- (insert fundoc)
- (insert (help-fns--list-local-commands)))))))
- ;; For the sake of IELM and maybe others
- nil)
+ (dolist (mode minors)
+ (let ((mode-function (nth 0 mode))
+ (pretty-minor-mode (nth 1 mode))
+ (indicator (nth 2 mode)))
+ (save-excursion
+ (goto-char (point-max))
+ (princ "\n\f\n")
+ (push (point-marker) help-button-cache)
+ ;; Document the minor modes fully.
+ (insert-text-button
+ pretty-minor-mode 'type 'help-function
+ 'help-args (list mode-function)
+ 'button '(t))
+ (princ (format " minor mode (%s):\n"
+ (if (zerop (length indicator))
+ "no indicator"
+ (format "indicator%s"
+ indicator))))
+ (princ (help-split-fundoc (documentation mode-function)
+ nil 'doc)))
+ (insert-button pretty-minor-mode
+ 'action (car help-button-cache)
+ 'follow-link t
+ 'help-echo "mouse-2, RET: show full information")
+ (newline)))
+ (forward-line -1)
+ (fill-paragraph nil)
+ (forward-line 1))
+
+ (princ "\n(Information about these minor modes follows the major mode info.)\n\n"))
+ ;; Document the major mode.
+ (let ((mode mode-name))
+ (with-current-buffer standard-output
+ (let ((start (point)))
+ (insert (format-mode-line mode nil nil buffer))
+ (add-text-properties start (point) '(face bold)))))
+ (princ " mode")
+ (let* ((mode major-mode)
+ (file-name (find-lisp-object-file-name mode nil)))
+ (if (not file-name)
+ (setq help-mode--current-data (list :symbol mode))
+ (princ (format-message " defined in `%s'"
+ (help-fns-short-filename file-name)))
+ ;; Make a hyperlink to the library.
+ (with-current-buffer standard-output
+ (save-excursion
+ (re-search-backward (substitute-command-keys "`\\([^`']+\\)'")
+ nil t)
+ (setq help-mode--current-data (list :symbol mode
+ :file file-name))
+ (help-xref-button 1 'help-function-def mode file-name)))))
+ (let ((fundoc (help-split-fundoc (documentation major-mode) nil 'doc)))
+ (with-current-buffer standard-output
+ (insert ":\n")
+ (insert fundoc)
+ (insert (help-fns--list-local-commands))))))))
+ ;; For the sake of IELM and maybe others
+ nil)
(defun help-fns--list-local-commands ()
(let ((functions nil))
@@ -1946,7 +2006,8 @@ one of them returns non-nil."
(event-end key))
((eq key ?\C-g) (signal 'quit nil))
(t (user-error "You didn't specify a widget"))))))
- (let (buf)
+ (let (buf
+ (help-buffer-under-preparation t))
;; Allow describing a widget in a different window.
(when (posnp pos)
(setq buf (window-buffer (posn-window pos))
diff --git a/lisp/help-macro.el b/lisp/help-macro.el
index 1fa9d82afd8..ecc7ebab412 100644
--- a/lisp/help-macro.el
+++ b/lisp/help-macro.el
@@ -93,7 +93,8 @@ and then returns."
"Help command."
(interactive)
(let ((line-prompt
- (substitute-command-keys ,help-line)))
+ (substitute-command-keys ,help-line))
+ (help-buffer-under-preparation t))
(when three-step-help
(message "%s" line-prompt))
(let* ((help-screen ,help-text)
@@ -140,6 +141,7 @@ and then returns."
(insert (substitute-command-keys help-screen)))
(let ((minor-mode-map-alist new-minor-mode-map-alist))
(help-mode)
+ (variable-pitch-mode)
(setq new-minor-mode-map-alist minor-mode-map-alist))
(goto-char (point-min))
(while (or (memq char (append help-event-list
@@ -165,14 +167,18 @@ and then returns."
(let ((cursor-in-echo-area t)
(overriding-local-map local-map))
(setq key (read-key-sequence
- (format "Type one of the options listed%s: "
+ (format "Type one of listed options%s: "
(if (pos-visible-in-window-p
(point-max))
""
(concat ", or "
(help--key-description-fontified (kbd "<PageDown>"))
- " or "
+ "/"
(help--key-description-fontified (kbd "<PageUp>"))
+ "/"
+ (help--key-description-fontified (kbd "SPC"))
+ "/"
+ (help--key-description-fontified (kbd "DEL"))
" to scroll"))))
char (aref key 0)))
diff --git a/lisp/help-mode.el b/lisp/help-mode.el
index 87f26651e01..792f2e5af33 100644
--- a/lisp/help-mode.el
+++ b/lisp/help-mode.el
@@ -35,6 +35,8 @@
(let ((map (make-sparse-keymap)))
(set-keymap-parent map (make-composed-keymap button-buffer-map
special-mode-map))
+ (define-key map "n" 'help-goto-next-page)
+ (define-key map "p" 'help-goto-previous-page)
(define-key map "l" 'help-go-back)
(define-key map "r" 'help-go-forward)
(define-key map "\C-c\C-b" 'help-go-back)
@@ -70,7 +72,8 @@
["Customize" help-customize
:help "Customize variable or face"]))
-(defun help-mode-context-menu (menu)
+(defun help-mode-context-menu (menu click)
+ "Populate MENU with Help mode commands at CLICK."
(define-key menu [help-mode-separator] menu-bar-separator)
(let ((easy-menu (make-sparse-keymap "Help-Mode")))
(easy-menu-define nil easy-menu nil
@@ -85,12 +88,7 @@
(when (consp item)
(define-key menu (vector (car item)) (cdr item)))))
- (when (and
- ;; First check if `help-fns--list-local-commands'
- ;; used `where-is-internal' to call this function
- ;; with wrong `last-input-event'.
- (eq (current-buffer) (window-buffer (posn-window (event-start last-input-event))))
- (mouse-posn-property (event-start last-input-event) 'mouse-face))
+ (when (mouse-posn-property (event-start click) 'mouse-face)
(define-key menu [help-mode-push-button]
'(menu-item "Follow Link" (lambda (event)
(interactive "e")
@@ -228,6 +226,16 @@ The format is (FUNCTION ARGS...).")
'help-function #'info
'help-echo (purecopy "mouse-2, RET: read this Info node"))
+(define-button-type 'help-man
+ :supertype 'help-xref
+ 'help-function #'man
+ 'help-echo (purecopy "mouse-2, RET: read this man page"))
+
+(define-button-type 'help-customization-group
+ :supertype 'help-xref
+ 'help-function #'customize-group
+ 'help-echo (purecopy "mouse-2, RET: display this customization group"))
+
(define-button-type 'help-url
:supertype 'help-xref
'help-function #'browse-url
@@ -267,6 +275,10 @@ The format is (FUNCTION ARGS...).")
(when (or (< position (point-min))
(> position (point-max)))
(widen))
+ ;; Save mark for the old location, unless the point is not
+ ;; actually going to move.
+ (unless (= (point) position)
+ (push-mark nil t))
(goto-char position))
(message "Unable to find location in file")))))
@@ -366,6 +378,13 @@ The format is (FUNCTION ARGS...).")
(view-buffer-other-window (find-file-noselect file))
(goto-char pos))
'help-echo (purecopy "mouse-2, RET: show corresponding NEWS announcement"))
+
+;;;###autoload
+(defun help-mode--add-function-link (str fun)
+ (make-text-button (copy-sequence str) nil
+ 'type 'help-function
+ 'help-args (list fun)))
+
(defvar bookmark-make-record-function)
(defvar help-mode--current-data nil)
@@ -437,6 +456,15 @@ when help commands related to multilingual environment (e.g.,
"\\<[Ii]nfo[ \t\n]+\\(node\\|anchor\\)[ \t\n]+['`‘]\\([^'’]+\\)['’]")
"Regexp matching doc string references to an Info node.")
+(defconst help-xref-man-regexp
+ (purecopy
+ "\\<[Mm]an[ \t\n]+page[ \t\n]+\\(?:for[ \t\n]+\\)?['`‘\"]\\([^'’\"]+\\)['’\"]")
+ "Regexp matching doc string references to a man page.")
+
+(defconst help-xref-customization-group-regexp
+ (purecopy "\\<[Cc]ustomization[ \t\n]+[Gg]roup[ \t\n]+['`‘]\\([^'’]+\\)['’]")
+ "Regexp matching doc string references to a customization group.")
+
(defconst help-xref-url-regexp
(purecopy "\\<[Uu][Rr][Ll][ \t\n]+['`‘]\\([^'’]+\\)['’]")
"Regexp matching doc string references to a URL.")
@@ -543,6 +571,16 @@ that."
(setq data ;; possible newlines if para filled
(replace-regexp-in-string "[ \t\n]+" " " data t t)))
(help-xref-button 2 'help-info data))))
+ ;; Man references
+ (save-excursion
+ (while (re-search-forward help-xref-man-regexp nil t)
+ (help-xref-button 1 'help-man (match-string 1))))
+ ;; Customization groups.
+ (save-excursion
+ (while (re-search-forward
+ help-xref-customization-group-regexp nil t)
+ (help-xref-button 1 'help-customization-group
+ (intern (match-string 1)))))
;; URLs
(save-excursion
(while (re-search-forward help-xref-url-regexp nil t)
@@ -606,34 +644,7 @@ that."
"\\<M-x\\s-+\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)" nil t)
(let ((sym (intern-soft (match-string 1))))
(if (fboundp sym)
- (help-xref-button 1 'help-function sym)))))
- ;; Look for commands in whole keymap substitutions:
- (save-excursion
- ;; Make sure to find the first keymap.
- (goto-char (point-min))
- ;; Find a header and the column at which the command
- ;; name will be found.
-
- ;; If the keymap substitution isn't the last thing in
- ;; the doc string, and if there is anything on the same
- ;; line after it, this code won't recognize the end of it.
- (while (re-search-forward "^key +binding\n\\(-+ +\\)-+\n\n"
- nil t)
- (let ((col (- (match-end 1) (match-beginning 1))))
- (while
- (and (not (eobp))
- ;; Stop at a pair of blank lines.
- (not (looking-at-p "\n\\s-*\n")))
- ;; Skip a single blank line.
- (and (eolp) (forward-line))
- (end-of-line)
- (skip-chars-backward "^ \t\n")
- (if (and (>= (current-column) col)
- (looking-at "\\(\\sw\\|\\s_\\)+$"))
- (let ((sym (intern-soft (match-string 0))))
- (if (fboundp sym)
- (help-xref-button 0 'help-function sym))))
- (forward-line))))))
+ (help-xref-button 1 'help-function sym))))))
(set-syntax-table stab))
;; Delete extraneous newlines at the end of the docstring
(goto-char (point-max))
@@ -770,6 +781,26 @@ See `help-make-xrefs'."
(help-xref-go-forward (current-buffer))
(user-error "No next help buffer")))
+(defun help-goto-next-page ()
+ "Go to the next page (if any) in the current buffer.
+The help buffers are divided into \"pages\" by the ^L character."
+ (interactive nil help-mode)
+ (push-mark)
+ (forward-page)
+ (unless (eobp)
+ (forward-line 1)))
+
+(defun help-goto-previous-page ()
+ "Go to the previous page (if any) in the current buffer.
+(If not at the start of a page, go to the start of the current page.)
+
+The help buffers are divided into \"pages\" by the ^L character."
+ (interactive nil help-mode)
+ (push-mark)
+ (backward-page (if (looking-back "\f\n" (- (point) 5)) 2 1))
+ (unless (bobp)
+ (forward-line 1)))
+
(defun help-view-source ()
"View the source of the current help item."
(interactive nil help-mode)
@@ -800,7 +831,7 @@ See `help-make-xrefs'."
(defun help-do-xref (_pos function args)
"Call the help cross-reference function FUNCTION with args ARGS.
-Things are set up properly so that the resulting help-buffer has
+Things are set up properly so that the resulting help buffer has
a proper [back] button."
;; There is a reference at point. Follow it.
(let ((help-xref-following t))
diff --git a/lisp/help.el b/lisp/help.el
index 29ae3404813..5114ddefba1 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -50,6 +50,11 @@
(defvar help-window-old-frame nil
"Frame selected at the time `with-help-window' is invoked.")
+(defvar help-buffer-under-preparation nil
+ "Whether a *Help* buffer is being prepared.
+This variable is bound to t during the preparation of a *Help*
+buffer.")
+
(defvar help-map
(let ((map (make-sparse-keymap)))
(define-key map (char-to-string help-char) 'help-for-help)
@@ -524,30 +529,31 @@ See `lossage-size' to update the number of recorded keystrokes.
To record all your input, use `open-dribble-file'."
(interactive)
- (help-setup-xref (list #'view-lossage)
- (called-interactively-p 'interactive))
- (with-help-window (help-buffer)
- (princ " ")
- (princ (mapconcat (lambda (key)
- (cond
- ((and (consp key) (null (car key)))
- (format ";; %s\n" (if (symbolp (cdr key)) (cdr key)
- "anonymous-command")))
- ((or (integerp key) (symbolp key) (listp key))
- (single-key-description key))
- (t
- (prin1-to-string key nil))))
- (recent-keys 'include-cmds)
- " "))
- (with-current-buffer standard-output
- (goto-char (point-min))
- (let ((comment-start ";; ")
- (comment-column 24))
- (while (not (eobp))
- (comment-indent)
- (forward-line 1)))
- ;; Show point near the end of "lossage", as we did in Emacs 24.
- (set-marker help-window-point-marker (point)))))
+ (let ((help-buffer-under-preparation t))
+ (help-setup-xref (list #'view-lossage)
+ (called-interactively-p 'interactive))
+ (with-help-window (help-buffer)
+ (princ " ")
+ (princ (mapconcat (lambda (key)
+ (cond
+ ((and (consp key) (null (car key)))
+ (format ";; %s\n" (if (symbolp (cdr key)) (cdr key)
+ "anonymous-command")))
+ ((or (integerp key) (symbolp key) (listp key))
+ (single-key-description key))
+ (t
+ (prin1-to-string key nil))))
+ (recent-keys 'include-cmds)
+ " "))
+ (with-current-buffer standard-output
+ (goto-char (point-min))
+ (let ((comment-start ";; ")
+ (comment-column 24))
+ (while (not (eobp))
+ (comment-indent)
+ (forward-line 1)))
+ ;; Show point near the end of "lossage", as we did in Emacs 24.
+ (set-marker help-window-point-marker (point))))))
;; Key bindings
@@ -561,11 +567,13 @@ To record all your input, use `open-dribble-file'."
'font-lock-face 'help-key-binding
'face 'help-key-binding))
-(defcustom describe-bindings-outline nil
+(defcustom describe-bindings-outline t
"Non-nil enables outlines in the output buffer of `describe-bindings'."
:type 'boolean
:group 'help
- :version "28.1")
+ :version "29.1")
+
+(declare-function outline-hide-subtree "outline")
(defun describe-bindings (&optional prefix buffer)
"Display a buffer showing a list of all defined keys, and their definitions.
@@ -577,33 +585,32 @@ The optional argument BUFFER specifies which buffer's bindings
to display (default, the current buffer). BUFFER can be a buffer
or a buffer name."
(interactive)
- (or buffer (setq buffer (current-buffer)))
- (help-setup-xref (list #'describe-bindings prefix buffer)
- (called-interactively-p 'interactive))
- (with-help-window (help-buffer)
- ;; Be aware that `describe-buffer-bindings' puts its output into
- ;; the current buffer.
- (with-current-buffer (help-buffer)
- (describe-buffer-bindings buffer prefix)
-
- (when describe-bindings-outline
- (setq-local outline-regexp ".*:$")
- (setq-local outline-heading-end-regexp ":\n")
- (setq-local outline-level (lambda () 1))
- (setq-local outline-minor-mode-cycle t
- outline-minor-mode-highlight t)
- (outline-minor-mode 1)
- (save-excursion
- (let ((inhibit-read-only t))
+ (let ((help-buffer-under-preparation t))
+ (or buffer (setq buffer (current-buffer)))
+ (help-setup-xref (list #'describe-bindings prefix buffer)
+ (called-interactively-p 'interactive))
+ (with-help-window (help-buffer)
+ (with-current-buffer (help-buffer)
+ (describe-buffer-bindings buffer prefix)
+
+ (when describe-bindings-outline
+ (setq-local outline-regexp ".*:$")
+ (setq-local outline-heading-end-regexp ":\n")
+ (setq-local outline-level (lambda () 1))
+ (setq-local outline-minor-mode-cycle t
+ outline-minor-mode-highlight t)
+ (setq-local outline-minor-mode-use-buttons t)
+ (outline-minor-mode 1)
+ (save-excursion
(goto-char (point-min))
- (insert (substitute-command-keys
- (concat "\\<outline-mode-cycle-map>Type "
- "\\[outline-cycle] or \\[outline-cycle-buffer] "
- "on headings to cycle their visibility.\n\n")))
- ;; Hide the longest body
- (when (and (re-search-forward "Key translations" nil t)
- (fboundp 'outline-cycle))
- (outline-cycle))))))))
+ (let ((inhibit-read-only t))
+ ;; Hide the longest body.
+ (when (re-search-forward "Key translations" nil t)
+ (outline-hide-subtree))
+ ;; Hide ^Ls.
+ (while (search-forward "\n\f\n" nil t)
+ (put-text-property (1+ (match-beginning 0)) (1- (match-end 0))
+ 'invisible t)))))))))
(defun where-is (definition &optional insert)
"Print message listing key sequences that invoke the command DEFINITION.
@@ -677,9 +684,11 @@ If INSERT (the prefix arg) is non-nil, insert the message in the buffer."
(defun help--binding-undefined-p (defn)
(or (null defn) (integerp defn) (equal defn 'undefined)))
-(defun help--analyze-key (key untranslated)
+(defun help--analyze-key (key untranslated &optional buffer)
"Get information about KEY its corresponding UNTRANSLATED events.
-Returns a list of the form (BRIEF-DESC DEFN EVENT MOUSE-MSG)."
+Returns a list of the form (BRIEF-DESC DEFN EVENT MOUSE-MSG).
+When BUFFER is nil, it defaults to the buffer displayed
+in the selected window."
(if (numberp untranslated)
(error "Missing `untranslated'!"))
(let* ((event (when (> (length key) 0)
@@ -695,7 +704,14 @@ Returns a list of the form (BRIEF-DESC DEFN EVENT MOUSE-MSG)."
(mouse-msg (if (or (memq 'click modifiers) (memq 'down modifiers)
(memq 'drag modifiers))
" at that spot" ""))
- (defn (key-binding key t)))
+ ;; Use `posn-set-point' to handle the case when a menu item
+ ;; is selected from the context menu that should describe KEY
+ ;; at the position of mouse click that opened the context menu.
+ ;; When no mouse was involved, don't use `posn-set-point'.
+ (defn (if buffer
+ (key-binding key t)
+ (save-excursion (posn-set-point (event-end event))
+ (key-binding key t)))))
;; Handle the case where we faked an entry in "Select and Paste" menu.
(when (and (eq defn nil)
(stringp (aref key (1- (length key))))
@@ -725,7 +741,7 @@ Returns a list of the form (BRIEF-DESC DEFN EVENT MOUSE-MSG)."
;; If nothing left, then keep one (the last one).
(last info-list)))
-(defun describe-key-briefly (&optional key-list insert untranslated)
+(defun describe-key-briefly (&optional key-list insert buffer)
"Print the name of the functions KEY-LIST invokes.
KEY-LIST is a list of pairs (SEQ . RAW-SEQ) of key sequences, where
RAW-SEQ is the untranslated form of the key sequence SEQ.
@@ -733,8 +749,10 @@ If INSERT (the prefix arg) is non-nil, insert the message in the buffer.
While reading KEY-LIST interactively, this command temporarily enables
menu items or tool-bar buttons that are disabled to allow getting help
-on them."
- (declare (advertised-calling-convention (key-list &optional insert) "27.1"))
+on them.
+
+BUFFER is the buffer in which to lookup those keys; it defaults to the
+current buffer."
(interactive
;; Ignore mouse movement events because it's too easy to miss the
;; message while moving the mouse.
@@ -742,15 +760,13 @@ on them."
`(,key-list ,current-prefix-arg)))
(when (arrayp key-list)
;; Old calling convention, changed
- (setq key-list (list (cons key-list
- (if (numberp untranslated)
- (this-single-command-raw-keys)
- untranslated)))))
- (let* ((info-list (mapcar (lambda (kr)
- (help--analyze-key (car kr) (cdr kr)))
- key-list))
- (msg (mapconcat #'car (help--filter-info-list info-list 1) "\n")))
- (if insert (insert msg) (message "%s" msg))))
+ (setq key-list (list (cons key-list nil))))
+ (with-current-buffer (if (buffer-live-p buffer) buffer (current-buffer))
+ (let* ((info-list (mapcar (lambda (kr)
+ (help--analyze-key (car kr) (cdr kr) buffer))
+ key-list))
+ (msg (mapconcat #'car (help--filter-info-list info-list 1) "\n")))
+ (if insert (insert msg) (message "%s" msg)))))
(defun help--key-binding-keymap (key &optional accept-default no-remap position)
"Return a keymap holding a binding for KEY within current keymaps.
@@ -894,7 +910,8 @@ current buffer."
(let ((raw (if (numberp buffer) (this-single-command-raw-keys) buffer)))
(setf (cdar (last key-list)) raw)))
(setq buffer nil))
- (let* ((buf (or buffer (current-buffer)))
+ (let* ((help-buffer-under-preparation t)
+ (buf (or buffer (current-buffer)))
(on-link
(mapcar (lambda (kr)
(let ((raw (cdr kr)))
@@ -910,7 +927,7 @@ current buffer."
(mapcar (lambda (x)
(pcase-let* ((`(,seq . ,raw-seq) x)
(`(,brief-desc ,defn ,event ,_mouse-msg)
- (help--analyze-key seq raw-seq))
+ (help--analyze-key seq raw-seq buffer))
(locus
(help--binding-locus
seq (event-start event))))
@@ -952,8 +969,11 @@ current buffer."
(describe-function-1 defn)))))))
(defun search-forward-help-for-help ()
- "Search forward \"help window\"."
+ "Search forward in the help-for-help window.
+This command is meant to be used after issuing the `C-h C-h' command."
(interactive)
+ (unless (get-buffer help-for-help-buffer-name)
+ (error "No %s buffer; use `C-h C-h' first" help-for-help-buffer-name))
;; Move cursor to the "help window".
(pop-to-buffer help-for-help-buffer-name)
;; Do incremental search forward.
@@ -1048,11 +1068,23 @@ is currently activated with completion."
result))
-(defun substitute-command-keys (string)
+(defcustom help-link-key-to-documentation t
+ "Non-nil means link keys to their command in *Help* buffers.
+This affects \\\\=\\[command] substitutions in documentation
+strings done by `substitute-command-keys'."
+ :type 'boolean
+ :version "29.1"
+ :group 'help)
+
+(defun substitute-command-keys (string &optional no-face)
"Substitute key descriptions for command names in STRING.
Each substring of the form \\\\=[COMMAND] is replaced by either a
keystroke sequence that invokes COMMAND, or \"M-x COMMAND\" if COMMAND
-is not on any keys. Keybindings will use the face `help-key-binding'.
+is not on any keys. Keybindings will use the face `help-key-binding',
+unless the optional argument NO-FACE is non-nil.
+
+Each substring of the form \\\\=`KEYBINDING' will be replaced by
+KEYBINDING and use the `help-key-binding' face.
Each substring of the form \\\\={MAPVAR} is replaced by a summary of
the value of MAPVAR as a keymap. This summary is similar to the one
@@ -1106,6 +1138,23 @@ Otherwise, return a new string."
(delete-char 2)
(ignore-errors
(forward-char 1)))
+ ((and (= (following-char) ?`)
+ (save-excursion
+ (prog1 (search-forward "'" nil t)
+ (setq end-point (- (point) 2)))))
+ (goto-char orig-point)
+ (delete-char 2)
+ (goto-char (1- end-point))
+ (delete-char 1)
+ ;; (backward-char 1)
+ (let ((k (buffer-substring-no-properties orig-point (point))))
+ (cond ((= (length k) 0)
+ (error "Empty key sequence in substitution"))
+ ((not (key-valid-p k))
+ (error "Invalid key sequence in substitution: `%s'" k))))
+ (add-text-properties orig-point (point)
+ '( face help-key-binding
+ font-lock-face help-key-binding)))
;; 1C. \[foo] is replaced with the keybinding.
((and (= (following-char) ?\[)
(save-excursion
@@ -1129,13 +1178,27 @@ Otherwise, return a new string."
(let ((op (point)))
(insert "M-x ")
(goto-char (+ end-point 3))
- (add-text-properties op (point)
- '( face help-key-binding
- font-lock-face help-key-binding))
+ (or no-face
+ (add-text-properties
+ op (point)
+ '( face help-key-binding
+ font-lock-face help-key-binding)))
(delete-char 1))
;; Function is on a key.
(delete-char (- end-point (point)))
- (insert (help--key-description-fontified key)))))
+
+ (insert
+ (if no-face
+ (key-description key)
+ (let ((key (help--key-description-fontified key)))
+ (if (and help-link-key-to-documentation
+ help-buffer-under-preparation
+ (functionp fun))
+ ;; The `fboundp' fixes bootstrap.
+ (if (fboundp 'help-mode--add-function-link)
+ (help-mode--add-function-link key fun)
+ key)
+ key)))))))
;; 1D. \{foo} is replaced with a summary of the keymap
;; (symbol-value foo).
;; \<foo> just sets the keymap used for \[cmd].
@@ -1195,8 +1258,8 @@ Otherwise, return a new string."
(buffer-string)))))
(defvar help--keymaps-seen nil)
-(defun describe-map-tree (startmap partial shadow prefix title no-menu
- transl always-title mention-shadow)
+(defun describe-map-tree (startmap &optional partial shadow prefix title
+ no-menu transl always-title mention-shadow)
"Insert a description of the key bindings in STARTMAP.
This is followed by the key bindings of all maps reachable
through STARTMAP.
@@ -1217,15 +1280,12 @@ If NOMENU is non-nil, then omit menu-bar commands.
If TRANSL is non-nil, the definitions are actually key
translations so print strings and vectors differently.
-If ALWAYS_TITLE is non-nil, print the title even if there are no
+If ALWAYS-TITLE is non-nil, print the title even if there are no
maps to look through.
-If MENTION_SHADOW is non-nil, then when something is shadowed by
+If MENTION-SHADOW is non-nil, then when something is shadowed by
SHADOW, don't omit it; instead, mention it but say it is
-shadowed.
-
-Any inserted text ends in two newlines (used by
-`help-make-xrefs')."
+shadowed."
(let* ((amaps (accessible-keymaps startmap prefix))
(orig-maps (if no-menu
(progn
@@ -1242,17 +1302,8 @@ Any inserted text ends in two newlines (used by
result))
amaps))
(maps orig-maps)
- (print-title (or maps always-title)))
- ;; Print title.
- (when print-title
- (insert (concat (if title
- (concat title
- (if prefix
- (concat " Starting With "
- (help--key-description-fontified prefix)))
- ":\n"))
- "key binding\n"
- "--- -------\n")))
+ (print-title (or maps always-title))
+ (start-point (point)))
;; Describe key bindings.
(setq help--keymaps-seen nil)
(while (consp maps)
@@ -1277,8 +1328,24 @@ Any inserted text ends in two newlines (used by
(describe-map (cdr elt) elt-prefix transl partial
sub-shadows no-menu mention-shadow)))
(setq maps (cdr maps)))
- (when print-title
- (insert "\n"))))
+ ;; Print title...
+ (when (and print-title
+ ;; ... unless the keymap was empty.
+ (/= (point) start-point))
+ (save-excursion
+ (goto-char start-point)
+ (when (eolp)
+ (delete-region (point) (1+ (point))))
+ (insert
+ (concat
+ (if title
+ (concat title
+ (if prefix
+ (concat " Starting With "
+ (help--key-description-fontified prefix)))
+ ":\n"))
+ "\nKey Binding\n"
+ (make-separator-line)))))))
(defun help--shadow-lookup (keymap key accept-default remap)
"Like `lookup-key', but with command remapping.
@@ -1291,48 +1358,37 @@ Return nil if the key sequence is too long."
value))
(t value))))
-(defvar help--previous-description-column 0)
-(defun help--describe-command (definition)
- ;; Converted from describe_command in keymap.c.
- ;; If column 16 is no good, go to col 32;
- ;; but don't push beyond that--go to next line instead.
- (let* ((column (current-column))
- (description-column (cond ((> column 30)
- (insert "\n")
- 32)
- ((or (> column 14)
- (and (> column 10)
- (= help--previous-description-column 32)))
- 32)
- (t 16))))
- ;; Avoid using the `help-keymap' face.
- (let ((op (point)))
- (indent-to description-column 1)
- (set-text-properties op (point) '( face nil
- font-lock-face nil)))
- (setq help--previous-description-column description-column)
- (cond ((symbolp definition)
- (insert (symbol-name definition) "\n"))
- ((or (stringp definition) (vectorp definition))
- (insert "Keyboard Macro\n"))
- ((keymapp definition)
- (insert "Prefix Command\n"))
- (t (insert "??\n")))))
-
-(defun help--describe-translation (definition)
- ;; Converted from describe_translation in keymap.c.
- ;; Avoid using the `help-keymap' face.
- (let ((op (point)))
- (indent-to 16 1)
- (set-text-properties op (point) '( face nil
- font-lock-face nil)))
+(defun help--describe-command (definition &optional translation)
(cond ((symbolp definition)
- (insert (symbol-name definition) "\n"))
+ (if (and (fboundp definition)
+ help-buffer-under-preparation)
+ (insert-text-button (symbol-name definition)
+ 'type 'help-function
+ 'help-args (list definition))
+ (insert (symbol-name definition)))
+ (insert "\n"))
((or (stringp definition) (vectorp definition))
- (insert (key-description definition nil) "\n"))
+ (if translation
+ (insert (key-description definition nil) "\n")
+ (insert "Keyboard Macro\n")))
((keymapp definition)
(insert "Prefix Command\n"))
- (t (insert "??\n"))))
+ ((byte-code-function-p definition)
+ (insert "[%s]\n" (buttonize "byte-code" #'disassemble definition)))
+ ((and (consp definition)
+ (memq (car definition) '(closure lambda)))
+ (insert (format "[%s]\n"
+ (buttonize
+ (symbol-name (car definition))
+ (lambda (_)
+ (pp-display-expression
+ definition "*Help Source*" t))
+ nil "View definition"))))
+ (t
+ (insert "??\n"))))
+
+(define-obsolete-function-alias 'help--describe-translation
+ #'help--describe-command "29.1")
(defun help--describe-map-compare (a b)
(let ((a (car a))
@@ -1346,7 +1402,8 @@ Return nil if the key sequence is too long."
(string-version-lessp (symbol-name a) (symbol-name b)))
(t nil))))
-(defun describe-map (map prefix transl partial shadow nomenu mention-shadow)
+(defun describe-map (map &optional prefix transl partial shadow
+ nomenu mention-shadow)
"Describe the contents of keymap MAP.
Assume that this keymap itself is reached by the sequence of
prefix keys PREFIX (a string or vector).
@@ -1358,14 +1415,22 @@ TRANSL, PARTIAL, SHADOW, NOMENU, MENTION-SHADOW are as in
(map (keymap-canonicalize map))
(tail map)
(first t)
- (describer (if transl
- #'help--describe-translation
- #'help--describe-command))
done vect)
(while (and (consp tail) (not done))
(cond ((or (vectorp (car tail)) (char-table-p (car tail)))
- (help--describe-vector (car tail) prefix describer partial
- shadow map mention-shadow))
+ (let ((columns ()))
+ (help--describe-vector
+ (car tail) prefix
+ (lambda (def)
+ (let ((start-line (line-beginning-position))
+ (end-key (point))
+ (column (current-column)))
+ (help--describe-command def transl)
+ (push (list column start-line end-key (1- (point)))
+ columns)))
+ partial shadow map mention-shadow)
+ (when columns
+ (describe-map--align-section columns))))
((consp (car tail))
(let ((event (caar tail))
definition this-shadowed)
@@ -1408,7 +1473,9 @@ TRANSL, PARTIAL, SHADOW, NOMENU, MENTION-SHADOW are as in
(push (cons tail prefix) help--keymaps-seen)))))
(setq tail (cdr tail)))
;; If we found some sparse map events, sort them.
- (let ((vect (sort vect 'help--describe-map-compare)))
+ (let ((vect (sort vect 'help--describe-map-compare))
+ (columns ())
+ line-start key-end column)
;; Now output them in sorted order.
(while vect
(let* ((elem (car vect))
@@ -1416,10 +1483,6 @@ TRANSL, PARTIAL, SHADOW, NOMENU, MENTION-SHADOW are as in
(definition (cadr elem))
(shadowed (caddr elem))
(end start))
- (when first
- (setq help--previous-description-column 0)
- (insert "\n")
- (setq first nil))
;; Find consecutive chars that are identically defined.
(when (fixnump start)
(while (and (cdr vect)
@@ -1434,26 +1497,80 @@ TRANSL, PARTIAL, SHADOW, NOMENU, MENTION-SHADOW are as in
(eq this-shadowed next-shadowed))))
(setq vect (cdr vect))
(setq end (caar vect))))
- ;; Now START .. END is the range to describe next.
- ;; Insert the string to describe the event START.
- (insert (help--key-description-fontified (vector start) prefix))
- (when (not (eq start end))
- (insert " .. " (help--key-description-fontified (vector end) prefix)))
- ;; Print a description of the definition of this character.
- ;; Called function will take care of spacing out far enough
- ;; for alignment purposes.
- (if transl
- (help--describe-translation definition)
- (help--describe-command definition))
- ;; Print a description of the definition of this character.
- ;; elt_describer will take care of spacing out far enough for
- ;; alignment purposes.
- (when shadowed
- (goto-char (max (1- (point)) (point-min)))
- (insert "\n (this binding is currently shadowed)")
- (goto-char (min (1+ (point)) (point-max)))))
+ (when (or (not (eq start end))
+ ;; Don't output keymap prefixes.
+ (not (keymapp definition)))
+ (when first
+ (insert "\n")
+ (setq first nil))
+ ;; Now START .. END is the range to describe next.
+ ;; Insert the string to describe the event START.
+ (setq line-start (point))
+ (insert (help--key-description-fontified (vector start) prefix))
+ (when (not (eq start end))
+ (insert " .. " (help--key-description-fontified (vector end)
+ prefix)))
+ (setq key-end (point)
+ column (current-column))
+ ;; Print a description of the definition of this character.
+ ;; Called function will take care of spacing out far enough
+ ;; for alignment purposes.
+ (help--describe-command definition transl)
+ (push (list column line-start key-end (1- (point))) columns)
+ ;; Print a description of the definition of this character.
+ ;; elt_describer will take care of spacing out far enough for
+ ;; alignment purposes.
+ (when shadowed
+ (goto-char (max (1- (point)) (point-min)))
+ (insert "\n (this binding is currently shadowed)")
+ (goto-char (min (1+ (point)) (point-max))))))
;; Next item in list.
- (setq vect (cdr vect))))))
+ (setq vect (cdr vect)))
+ (when columns
+ (describe-map--align-section columns)))))
+
+(defun describe-map--align-section (columns)
+ (save-excursion
+ (let ((max-key (apply #'max (mapcar #'car columns))))
+ (cond
+ ;; It's fine to use the minimum, so just do it, but quantize to
+ ;; two different widths, because having each block align slightly
+ ;; differently looks untidy.
+ ((< max-key 16)
+ (describe-map--fill-columns columns 16))
+ ((< max-key 24)
+ (describe-map--fill-columns columns 24))
+ ((< max-key 32)
+ (describe-map--fill-columns columns 32))
+ ;; We have some really wide ones in this block.
+ (t
+ (let ((window-width (window-width))
+ (max-def (apply #'max (mapcar
+ (lambda (elem)
+ (- (nth 3 elem) (nth 2 elem)))
+ columns))))
+ (if (< (+ max-def (max 16 max-key)) window-width)
+ ;; Can we do the block without continuation lines? Then do that.
+ (describe-map--fill-columns columns (1+ (max 16 max-key)))
+ ;; No, do continuation lines for some definitions.
+ (dolist (elem columns)
+ (goto-char (caddr elem))
+ (if (< (+ (car elem) (- (nth 3 elem) (nth 2 elem))) window-width)
+ ;; Indent.
+ (insert-char ?\s (- (1+ max-key) (car elem)))
+ ;; Continuation.
+ (insert "\n")
+ (insert-char ?\t 2))))))))))
+
+(defun describe-map--fill-columns (columns width)
+ (dolist (elem columns)
+ (goto-char (caddr elem))
+ (let ((tabs (- (/ width tab-width)
+ (/ (car elem) tab-width))))
+ (insert-char ?\t tabs)
+ (insert-char ?\s (if (zerop tabs)
+ (- width (car elem))
+ (mod width tab-width))))))
;;;; This Lisp version is 100 times slower than its C equivalent:
;;
@@ -1589,10 +1706,16 @@ and some others."
(add-hook 'temp-buffer-show-hook 'resize-temp-buffer-window 'append)
(remove-hook 'temp-buffer-show-hook 'resize-temp-buffer-window)))
+(defvar resize-temp-buffer-window-inhibit nil
+ "Non-nil means `resize-temp-buffer-window' should not resize.")
+
(defun resize-temp-buffer-window (&optional window)
"Resize WINDOW to fit its contents.
WINDOW must be a live window and defaults to the selected one.
-Do not resize if WINDOW was not created by `display-buffer'.
+Do not resize if WINDOW was not created by `display-buffer'. Do
+not resize either if a `window-height', `window-width' or
+`window-size' entry in `display-buffer-alist' prescribes some
+alternative resizing for WINDOW's buffer.
If WINDOW is part of a vertical combination, restrain its new
size by `temp-buffer-max-height' and do not resize if its minimum
@@ -1607,27 +1730,33 @@ provided `fit-frame-to-buffer' is non-nil.
This function may call `preserve-window-size' to preserve the
size of WINDOW."
(setq window (window-normalize-window window t))
- (let ((height (if (functionp temp-buffer-max-height)
+ (let* ((buffer (window-buffer window))
+ (height (if (functionp temp-buffer-max-height)
+ (with-selected-window window
+ (funcall temp-buffer-max-height buffer))
+ temp-buffer-max-height))
+ (width (if (functionp temp-buffer-max-width)
(with-selected-window window
- (funcall temp-buffer-max-height (window-buffer)))
- temp-buffer-max-height))
- (width (if (functionp temp-buffer-max-width)
- (with-selected-window window
- (funcall temp-buffer-max-width (window-buffer)))
- temp-buffer-max-width))
- (quit-cadr (cadr (window-parameter window 'quit-restore))))
- ;; Resize WINDOW iff it was made by `display-buffer'.
+ (funcall temp-buffer-max-width buffer))
+ temp-buffer-max-width))
+ (quit-cadr (cadr (window-parameter window 'quit-restore))))
+ ;; Resize WINDOW only if it was made by `display-buffer'.
(when (or (and (eq quit-cadr 'window)
(or (and (window-combined-p window)
(not (eq fit-window-to-buffer-horizontally
'only))
- (pos-visible-in-window-p (point-min) window))
+ (pos-visible-in-window-p
+ (with-current-buffer buffer (point-min))
+ window)
+ (not resize-temp-buffer-window-inhibit))
(and (window-combined-p window t)
- fit-window-to-buffer-horizontally)))
+ fit-window-to-buffer-horizontally
+ (not resize-temp-buffer-window-inhibit))))
(and (eq quit-cadr 'frame)
fit-frame-to-buffer
- (eq window (frame-root-window window))))
- (fit-window-to-buffer window height nil width nil t))))
+ (eq window (frame-root-window window))
+ (not resize-temp-buffer-window-inhibit)))
+ (fit-window-to-buffer window height nil width nil t))))
;;; Help windows.
(defcustom help-window-select nil
@@ -1737,13 +1866,13 @@ Return VALUE."
(cond
((eq help-setup 'window)
;; ... and is new, ...
- "Type \"q\" to delete help window")
+ "Type \\<help-map>\\[help-quit] to delete help window")
((eq help-setup 'frame)
;; ... on a new frame, ...
- "Type \"q\" to quit the help frame")
+ "Type \\<help-map>\\[help-quit] to quit the help frame")
((eq help-setup 'other)
;; ... or displayed some other buffer before.
- "Type \"q\" to restore previous buffer"))
+ "Type \\<help-map>\\[help-quit] to restore previous buffer"))
window t))
((and (eq (window-frame window) help-window-old-frame)
(= (length (window-list nil 'no-mini)) 2))
@@ -1754,7 +1883,7 @@ Return VALUE."
((eq help-setup 'window)
"Type \\[delete-other-windows] to delete the help window")
((eq help-setup 'other)
- "Type \"q\" in help window to restore its previous buffer"))
+ "Type \\<help-map>\\[help-quit] in help window to restore its previous buffer"))
window 'other))
(t
;; The help window is not selected ...
@@ -1762,10 +1891,10 @@ Return VALUE."
(cond
((eq help-setup 'window)
;; ... and is new, ...
- "Type \"q\" in help window to delete it")
+ "Type \\<help-map>\\[help-quit] in help window to delete it")
((eq help-setup 'other)
;; ... or displayed some other buffer before.
- "Type \"q\" in help window to restore previous buffer"))
+ "Type \\<help-map>\\[help-quit] in help window to restore previous buffer"))
window))))
;; Return VALUE.
value))
diff --git a/lisp/hexl.el b/lisp/hexl.el
index 8bfc1fb89e4..79dd5c40c69 100644
--- a/lisp/hexl.el
+++ b/lisp/hexl.el
@@ -93,7 +93,7 @@ as that will override any bit grouping options set here."
"Face used in address area of Hexl mode buffer.")
(defface hexl-ascii-region
- ;; Copied from `header-line`. We used to inherit from it, but that
+ ;; Copied from 'header-line'. We used to inherit from it, but that
;; looks awful when the headerline is given a variable-pitch font or
;; (even worse) a 3D look.
'((((class color grayscale) (background light))
@@ -539,7 +539,7 @@ This function is intended to be used as eldoc callback."
(+ N (/ N (/ hexl-bits 4))) )) ) ; char offset into hexl display line
(defun hexl-goto-address (address)
- "Go to hexl-mode (decimal) address ADDRESS.
+ "Go to `hexl-mode' (decimal) address ADDRESS.
Signal error if ADDRESS is out of range."
(interactive "nAddress: ")
(if (or (< address 0) (> address hexl-max-address))
@@ -1165,7 +1165,7 @@ This function is assumed to be used as callback function for `hl-line-mode'."
;; startup stuff.
-(easy-menu-define hexl-menu hexl-mode-map "Hexl Mode menu"
+(easy-menu-define hexl-menu hexl-mode-map "Hexl Mode menu."
'("Hexl"
:help "Hexl-specific Features"
diff --git a/lisp/hi-lock.el b/lisp/hi-lock.el
index 37b88b318de..7d126cb558e 100644
--- a/lisp/hi-lock.el
+++ b/lisp/hi-lock.el
@@ -244,7 +244,7 @@ by cycling through the faces in `hi-lock-face-defaults'."
"String used to identify hi-lock patterns at the start of files.")
(defvar hi-lock-archaic-interface-message-used nil
- "True if user alerted that `global-hi-lock-mode' is now the global switch.
+ "Non-nil if user alerted that `global-hi-lock-mode' is now the global switch.
Earlier versions of hi-lock used `hi-lock-mode' as the global switch;
the message is issued if it appears that `hi-lock-mode' is used assuming
that older functionality. This variable avoids multiple reminders.")
@@ -344,9 +344,9 @@ which can be called interactively, are:
When hi-lock is started and if the mode is not excluded or patterns
rejected, the beginning of the buffer is searched for lines of the
form:
- Hi-lock: FOO
+ Hi-lock: (FOO ...)
-where FOO is a list of patterns. The patterns must start before
+where (FOO ...) is a list of patterns. The patterns must start before
position \(number of characters into buffer)
`hi-lock-file-patterns-range'. Patterns will be read until
Hi-lock: end is found. A mode is excluded if it's in the list
@@ -818,7 +818,7 @@ SPACES-REGEXP is a regexp to substitute spaces in font-lock search."
(not (looking-at "\\s-*end")))
(condition-case nil
(setq all-patterns (append (read (current-buffer)) all-patterns))
- (error (message "Invalid pattern list expression at %d"
+ (error (message "Invalid pattern list expression at line %d"
(line-number-at-pos)))))))
(when (and all-patterns
hi-lock-mode
diff --git a/lisp/hilit-chg.el b/lisp/hilit-chg.el
index 8919e982383..d9fab6b8753 100644
--- a/lisp/hilit-chg.el
+++ b/lisp/hilit-chg.el
@@ -444,7 +444,7 @@ This is the opposite of `hilit-chg-hide-changes'."
;; We set the change property so we can tell this is one
;; of our overlays (so we don't delete someone else's).
(overlay-put ov 'hilit-chg t))
- (error "hilit-chg-make-ov: no face for prop: %s" prop))))
+ (error "hilit-chg-make-ov: No face for prop: %s" prop))))
(defun hilit-chg-hide-changes (&optional beg end)
"Remove face information for Highlight Changes mode.
diff --git a/lisp/hippie-exp.el b/lisp/hippie-exp.el
index 4fadbbe4180..97207090388 100644
--- a/lisp/hippie-exp.el
+++ b/lisp/hippie-exp.el
@@ -38,7 +38,7 @@
;;
;; If the variable `hippie-expand-verbose' is non-nil, `hippie-expand'
;; outputs in a message which try-function in the list that is used
-;; currently (ie. was used currently and will be tried first the next
+;; currently (i.e. was used currently and will be tried first the next
;; time).
;; The variable `hippie-expand-max-buffers' determines in how many
;; buffers, apart from the current, to search for expansions in. It
diff --git a/lisp/htmlfontify.el b/lisp/htmlfontify.el
index 3b961989e3e..8dc4cce3239 100644
--- a/lisp/htmlfontify.el
+++ b/lisp/htmlfontify.el
@@ -77,6 +77,7 @@
;; Changes: moved to changelog (CHANGES) file.
;;; Code:
+
(eval-when-compile (require 'cl-lib))
(require 'cus-edit)
@@ -90,23 +91,30 @@
"The generator meta tag for this version of htmlfontify.")
(defconst htmlfontify-manual "Htmlfontify Manual"
- "Copy and convert buffers and files to HTML, adding hyperlinks between files
-\(driven by etags) if requested.
-\nInteractive functions:
+ "Copy and convert buffers and files to HTML.
+Add hyperlinks between files driven by etags) if requested.
+
+Interactive functions:
`htmlfontify-buffer'
`htmlfontify-run-etags'
`htmlfontify-copy-and-link-dir'
`htmlfontify-load-rgb-file'
- `htmlfontify-unload-rgb-file'\n
-In order to:\n
+ `htmlfontify-unload-rgb-file'
+
+In order to:
+
fontify a file you have open: \\[htmlfontify-buffer]
prepare the etags map for a directory: \\[htmlfontify-run-etags]
-copy a directory, fontifying as you go: \\[htmlfontify-copy-and-link-dir]\n
+copy a directory, fontifying as you go: \\[htmlfontify-copy-and-link-dir]
+
The following might be useful when running non-windowed or in batch mode:
-\(note that they shouldn't be necessary - we have a built in map)\n
+\(note that they shouldn't be necessary - we have a built in map)
+
load an X11 style rgb.txt file: \\[htmlfontify-load-rgb-file]
-unload the current rgb.txt file: \\[htmlfontify-unload-rgb-file]\n
-And here's a programmatic example:\n
+unload the current rgb.txt file: \\[htmlfontify-unload-rgb-file]
+
+And here's a programmatic example:
+
\(defun rtfm-build-page-header (file style)
(format \"#define TEMPLATE red+black.html
#define DEBUG 1
@@ -148,7 +156,8 @@ This is called with two arguments (the filename relative to the top
level source directory being etag'd and fontified), and a string containing
the <style>...</style> text to embed in the document.
It should return a string that will be used as the header for the
-htmlfontified version of the source file.\n
+htmlfontified version of the source file.
+
See also `hfy-page-footer'."
;; FIXME: Why place such a :tag everywhere? Isn't it imposing your
;; own Custom preference on your users? --Stef
@@ -233,8 +242,10 @@ These functions will be called with the HTML buffer as the current buffer."
"Fallback `defface' specification for the face `default', used when
`hfy-display-class' has been set (the normal htmlfontify way of extracting
potentially non-current face information doesn't necessarily work for
-`default').\n
-Example: I customize this to:\n
+`default').
+
+Example: I customize this to:
+
\((t :background \"black\" :foreground \"white\" :family \"misc-fixed\"))"
:tag "default-face-definition"
:type '(alist))
@@ -244,8 +255,9 @@ Example: I customize this to:\n
"\x01" "\\([0-9]+\\)"
"," "\\([0-9]+\\)$"
"\\|" ".*\x7f[0-9]+,[0-9]+$")
- "Regex used to parse an etags entry: must have 3 subexps, corresponding,
-in order, to:\n
+ "Regex used to parse an etags entry.
+This must have 3 subexps, corresponding, in order, to:
+
1 - The tag
2 - The line
3 - The char (point) at which the tag occurs."
@@ -302,7 +314,8 @@ done;")
:type '(alist :key-type (string) :value-type (string)))
(defcustom hfy-etags-bin "etags"
- "Location of etags binary (we begin by assuming it's in your path).\n
+ "Location of etags binary (we begin by assuming it's in your path).
+
Note that if etags is not in your path, you will need to alter the shell
commands in `hfy-etags-cmd-alist'."
:tag "etags-bin"
@@ -346,7 +359,8 @@ commands in `hfy-etags-cmd-alist'."
(cdr (assoc (hfy-which-etags) hfy-etags-cmd-alist))
"The etags equivalent command to run in a source directory to generate a tags
file for the whole source tree from there on down. The command should emit
-the etags output on stdout.\n
+the etags output on stdout.
+
Two canned commands are provided - they drive Emacs's etags and
exuberant-ctags' etags respectively."
:tag "etags-command"
@@ -356,9 +370,10 @@ exuberant-ctags' etags respectively."
(cons 'choice clist)))
(defcustom hfy-istext-command "file %s | sed -e 's@^[^:]*:[ \t]*@@'"
- "Command to run with the name of a file, to see whether it is a text file
-or not. The command should emit a string containing the word `text' if
-the file is a text file, and a string not containing `text' otherwise."
+ "Command to run with the name of a file, to see if it is a text file or not.
+The command should emit a string containing the word `text' if
+the file is a text file, and a string not containing `text'
+otherwise."
:tag "istext-command"
:type '(string))
@@ -372,8 +387,10 @@ the file is a text file, and a string not containing `text' otherwise."
"Display class to use to determine which display class to use when
calculating a face's attributes. This is useful when, for example, you
are running Emacs on a tty or in batch mode, and want htmlfontify to have
-access to the face spec you would use if you were connected to an X display.\n
-Some valid class specification elements are:\n
+access to the face spec you would use if you were connected to an X display.
+
+Some valid class specification elements are:
+
(class color)
(class grayscale)
(background dark)
@@ -383,14 +400,17 @@ Some valid class specification elements are:\n
(type motif)
(type lucid)
Multiple values for a tag may be combined, to indicate that any one or more
-of these values in the specification key constitutes a match, eg:\n
-\((class color grayscale) (type tty)) would match any of:\n
+of these values in the specification key constitutes a match, eg:
+
+\((class color grayscale) (type tty)) would match any of:
+
((class color))
((class grayscale))
((class color grayscale))
((class color foo))
((type tty))
- ((type tty) (class color))\n
+ ((type tty) (class color))
+
and so on."
:type '(alist :key-type (symbol) :value-type (symbol))
:tag "display-class"
@@ -407,7 +427,9 @@ and so on."
(define-obsolete-variable-alias 'hfy-optimisations 'hfy-optimizations "25.1")
(defcustom hfy-optimizations (list 'keep-overlays)
- "Optimizations to turn on: So far, the following have been implemented:\n
+ "Optimizations to turn on.
+So far, the following have been implemented:
+
merge-adjacent-tags: If two (or more) span tags are adjacent, identical and
separated by nothing more than whitespace, they will
be merged into one span.
@@ -417,16 +439,19 @@ and so on."
output.
keep-overlays : More of a bell (or possibly whistle) than an
optimization - If on, preserve overlay highlighting
- (cf ediff or goo-font-lock) as well as basic faces.\n
+ (cf ediff or goo-font-lock) as well as basic faces.
+
body-text-only : Emit only body-text. In concrete terms,
1. Suppress calls to `hfy-page-header' and
`hfy-page-footer'
2. Pretend that `div-wrapper' option above is
turned off
3. Don't enclose output in <pre> </pre> tags
- And the following are planned but not yet available:\n
+ And the following are planned but not yet available:
+
kill-context-leak : Suppress hyperlinking between files highlighted by
- different modes.\n
+ different modes.
+
Note: like compiler optimizations, these optimize the _output_ of the code,
not the processing of the source itself, and are therefore likely to slow
htmlfontify down, at least a little. Except for skip-refontification,
@@ -442,20 +467,28 @@ which can never slow you down, but may result in incomplete fontification."
:tag "optimizations")
(defvar hfy-tags-cache nil
- "Alist of the form:\n
-\((\"/src/dir/0\" . tag-hash0) (\"/src/dir/1\" tag-hash1) ...)\n
-Each tag hash entry then contains entries of the form:\n
-\"tag_string\" => ((\"file/name.ext\" line char) ... )\n
-ie an alist mapping (relative) file paths to line and character offsets.\n
+ "Alist of the form:
+
+\((\"/src/dir/0\" . tag-hash0) (\"/src/dir/1\" tag-hash1) ...)
+
+Each tag hash entry then contains entries of the form:
+
+\"tag_string\" => ((\"file/name.ext\" line char) ... )
+
+ie an alist mapping (relative) file paths to line and character offsets.
+
See also `hfy-load-tags-cache'.")
(defvar hfy-tags-sortl nil
- "Alist of the form ((\"/src/dir\" . (tag0 tag1 tag2)) ... )\n
-where the tags are stored in descending order of length.\n
+ "Alist of the form ((\"/src/dir\" . (tag0 tag1 tag2)) ... )
+
+where the tags are stored in descending order of length.
+
See also `hfy-load-tags-cache'.")
(defvar hfy-tags-rmap nil
- "Alist of the form ((\"/src/dir\" . tag-rmap-hash))\n
+ "Alist of the form ((\"/src/dir\" . tag-rmap-hash))
+
where tag-rmap-hash has entries of the form:
\"tag_string\" => ( \"file/name.ext\" line char )
Unlike `hfy-tags-cache' these are the locations of occurrences of
@@ -467,8 +500,10 @@ Properties may be repeated, in which case later properties should be
treated as if they were inherited from a `parent' font.
\(For some properties, only the first encountered value is of any importance,
for others the values might be cumulative, and for others they might be
-cumulative in a complex way.)\n
-Some examples:\n
+cumulative in a complex way.)
+
+Some examples:
+
\(hfy-face-to-style \\='default) =>
((\"background\" . \"rgb(0, 0, 0)\")
(\"color\" . \"rgb(255, 255, 255)\")
@@ -477,27 +512,31 @@ Some examples:\n
(\"font-stretch\" . \"normal\")
(\"font-family\" . \"misc-fixed\")
(\"font-size\" . \"13pt\")
- (\"text-decoration\" . \"none\"))\n
+ (\"text-decoration\" . \"none\"))
+
\(hfy-face-to-style \\='Info-title-3-face) =>
((\"font-weight\" . \"700\")
(\"font-family\" . \"helv\")
(\"font-size\" . \"120%\")
- (\"text-decoration\" . \"none\"))\n")
+ (\"text-decoration\" . \"none\"))")
(defvar hfy-sheet-assoc 'please-ignore-this-line
- "An assoc with elements of the form (face-name style-name . style-string):\n
+ "An assoc with elements of the form (face-name style-name . style-string):
+
\((default \"default\" . \"{background: black; color: white}\")
(font-lock-string-face \"string\" . \"{color: rgb(64,224,208)}\"))" )
(defvar hfy-facemap-assoc 'please-ignore-this-line
"An assoc of (point . FACE-SYMBOL) or (point . DEFFACE-LIST)
and (point . \\='end) elements, in descending order of point value
-\(ie from the file's end to its beginning).\n
+\(ie from the file's end to its beginning).
+
The map is in reverse order because inserting a <style> tag (or any other
string) at `point' invalidates the map for all entries with a greater value of
point. By traversing the map from greatest to least point, we still invalidate
the map as we go, but only those points we have already dealt with (and
-therefore no longer care about) will be invalid at any time.\n
+therefore no longer care about) will be invalid at any time.
+
\\='((64820 . end)
(64744 . font-lock-comment-face)
(64736 . end)
@@ -529,8 +568,9 @@ therefore no longer care about) will be invalid at any time.\n
(group xdigit xdigit)))
(defun hfy-color-vals (color)
- "Where COLOR is a color name or #XXXXXX style triplet, return a
-list of three (16 bit) rgb values for said color.\n
+ "Return a list of three (16 bit) rgb values for COLOR.
+COLOR is a color name or #XXXXXX style triplet.
+
If a window system is unavailable, calls `hfy-fallback-color-values'."
(if (string-match hfy-triplet-regex color)
(mapcar
@@ -826,16 +866,20 @@ precedence."
"Return the face attributes for FACE.
If CLASS is set, it must be a `defface' alist key [see below],
in which case the first face specification returned by `hfy-combined-face-spec'
-which *doesn't* clash with CLASS is returned.\n
+which *doesn't* clash with CLASS is returned.
+
\(A specification with a class of t is considered to match any class you
specify - this matches Emacs's behavior when deciding on which face attributes
-to use, to the best of my understanding).\n
+to use, to the best of my understanding).
+
If CLASS is nil, then you just get whatever `face-attr-construct' returns,
-ie the current specification in effect for FACE.\n
+ie the current specification in effect for FACE.
+
*NOTE*: This function forces any face that is not `default' and which has
no :inherit property to inherit from `default' (this is because `default'
is magical in that Emacs's fonts behave as if they inherit implicitly from
-`default', but no such behavior exists in HTML/CSS).\n
+`default', but no such behavior exists in HTML/CSS).
+
See also `hfy-display-class' for details of valid values for CLASS."
(let ((face-spec
(if class
@@ -924,12 +968,13 @@ See also `hfy-display-class' for details of valid values for CLASS."
;; nil :overline nil :underline nil :slant normal :weight normal
;; :height 98 :width normal :family "outline-courier new")
(defun hfy-face-to-style-i (fn)
- "The guts of `hfy-face-to-style': FN should be a `defface' font spec,
-as returned by `face-attr-construct' or `hfy-face-attr-for-class'.
-Note that this function does not get font-sizes right if they are based
-on inherited modifiers (via the :inherit) attribute, and any other
-modifiers that are cumulative if they appear multiple times need to be
-merged by the user - `hfy-flatten-style' should do this."
+ "The guts of `hfy-face-to-style'.
+FN should be a `defface' font spec, as returned by
+`face-attr-construct' or `hfy-face-attr-for-class'. Note that
+this function does not get font-sizes right if they are based on
+inherited modifiers (via the :inherit) attribute, and any other
+modifiers that are cumulative if they appear multiple times need
+to be merged by the user - `hfy-flatten-style' should do this."
;;(message "hfy-face-to-style-i");;DBUG
;; fn's value could be something like
@@ -990,10 +1035,13 @@ Used while merging multiple font-size attributes."
;; we have to trawl the inheritance path, accumulating modifiers,
;; _until_ we get to an absolute (pt) specifier, then combine the lot
(defun hfy-flatten-style (style)
- "Take STYLE (see `hfy-face-to-style-i', `hfy-face-to-style') and merge
-any multiple attributes appropriately. Currently only font-size is merged
-down to a single occurrence - others may need special handling, but I
-haven't encountered them yet. Returns a `hfy-style-assoc'."
+ "Take STYLE and merge any multiple attributes appropriately.
+For the format of STYLE, see `hfy-face-to-style-i' and
+`hfy-face-to-style'. Return a `hfy-style-assoc'.
+
+Currently only font-size is merged down to a single occurrence -
+others may need special handling, but I haven't encountered them
+yet."
;;(message "(hfy-flatten-style %S)" style) ;;DBUG
(let ((m (list 1))
(x nil)
@@ -1027,7 +1075,8 @@ then the specification is returned unchanged."
(defun hfy-face-to-style (fn)
"Take FN, a font or `defface' style font specification,
\(as returned by `face-attr-construct' or `hfy-face-attr-for-class')
-and return a `hfy-style-assoc'.\n
+and return a `hfy-style-assoc'.
+
See also `hfy-face-to-style-i', `hfy-flatten-style'."
;;(message "hfy-face-to-style");;DBUG
(let* ((face-def (hfy-face-resolve-face fn))
@@ -1238,7 +1287,7 @@ return a `defface' style list of face properties instead of a face symbol."
(setq fprops (cdr fprops)))
;; ((prop val))
(setq p (caar fprops))
- (setq v (cl-cadar fprops))
+ (setq v (cadar fprops))
(setq fprops (cdr fprops)))
(if (listp (cdr fprops))
(progn
@@ -1341,10 +1390,14 @@ variable `font-lock-mode' and variable `font-lock-fontified' for truth."
(defun hfy-merge-adjacent-spans (face-map)
"Where FACE-MAP is a `hfy-facemap-assoc' for the current buffer,
this function merges adjacent style blocks which are of the same value
-and are separated by nothing more interesting than whitespace.\n
- <span class=\"foo\">narf</span> <span class=\"foo\">brain</span>\n
-\(as interpreted from FACE-MAP) would become:\n
- <span class=\"foo\">narf brain</span>\n
+and are separated by nothing more interesting than whitespace.
+
+ <span class=\"foo\">narf</span> <span class=\"foo\">brain</span>
+
+\(as interpreted from FACE-MAP) would become:
+
+ <span class=\"foo\">narf brain</span>
+
Returns a modified copy of FACE-MAP."
(let ((tmp-map face-map)
(map-buf nil)
@@ -1358,8 +1411,8 @@ Returns a modified copy of FACE-MAP."
;;(push (car tmp-map) reduced-map)
;;(push (cadr tmp-map) reduced-map)
(while tmp-map
- (setq first-start (cl-cadddr tmp-map)
- first-stop (cl-caddr tmp-map)
+ (setq first-start (cadddr tmp-map)
+ first-stop (caddr tmp-map)
last-start (cadr tmp-map)
last-stop (car tmp-map)
map-buf tmp-map
@@ -1372,8 +1425,8 @@ Returns a modified copy of FACE-MAP."
(not (re-search-forward "[^ \t\n\r]" (car last-start) t))))
(setq map-buf (cddr map-buf)
span-start first-start
- first-start (cl-cadddr map-buf)
- first-stop (cl-caddr map-buf)
+ first-start (cadddr map-buf)
+ first-stop (caddr map-buf)
last-start (cadr map-buf)
last-stop (car map-buf)))
(push span-stop reduced-map)
@@ -1467,7 +1520,8 @@ Uses `hfy-link-style-fun' to do this."
;; tag all the dangerous characters we want to escape
;; (ie any "<> chars we _didn't_ put there explicitly for css markup)
(defun hfy-html-enkludge-buffer ()
- "Mark dangerous [\"<>] characters with the `hfy-quoteme' property.\n
+ "Mark dangerous [\"<>] characters with the `hfy-quoteme' property.
+
See also `hfy-html-dekludge-buffer'."
;;(message "hfy-html-enkludge-buffer");;DBUG
(save-excursion
@@ -1488,7 +1542,8 @@ See also `hfy-html-dekludge-buffer'."
;; map of offsets, which would be tedious...
(defun hfy-html-dekludge-buffer ()
"Transform all dangerous characters marked with the `hfy-quoteme' property
-using `hfy-html-quote'.\n
+using `hfy-html-quote'.
+
See also `hfy-html-enkludge-buffer'."
;;(message "hfy-html-dekludge-buffer");;DBUG
(save-excursion
@@ -1820,14 +1875,14 @@ Hardly bombproof, but good enough in the context in which it is being used."
;; create a directory, cf mkdir -p
(defun hfy-make-directory (dir)
- "Approx. equivalent of mkdir -p DIR."
+ "Approximate equivalent of \"mkdir -p DIR\"."
;;(message "hfy-make-directory");;DBUG
(if (file-exists-p dir)
(if (file-directory-p dir) t)
(make-directory dir t)))
(defun hfy-text-p (srcdir file)
- "Is SRCDIR/FILE text? Uses `hfy-istext-command' to determine this."
+ "Is SRCDIR/FILE text? Use `hfy-istext-command' to determine this."
(let* ((cmd (format hfy-istext-command (expand-file-name file srcdir)))
(rsp (shell-command-to-string cmd)))
(string-match "text" rsp)))
@@ -1888,7 +1943,7 @@ property, with a value of \"tag.line-number\"."
(lambda (TLIST)
(if (string= file (car TLIST))
(let* ((line (cadr TLIST) )
- (chr (cl-caddr TLIST))
+ (chr (caddr TLIST))
(link (format "%s.%d" TAG line) ))
(put-text-property (+ 1 chr)
(+ 2 chr)
@@ -1910,12 +1965,15 @@ START is the offset at which to start looking for the / character in FILE."
"Return an href stub for a tag href in THIS-FILE.
If DEF-FILES (list of files containing definitions for the tag in question)
contains only one entry, the href should link straight to that file.
-Otherwise, the link should be to the index file.\n
+Otherwise, the link should be to the index file.
+
We are not yet concerned with the file extensions/tag line number and so on at
-this point.\n
+this point.
+
If `hfy-split-index' is set, and the href wil be to an index file rather than
a source file, append a .X to `hfy-index-file', where X is the uppercased
-first character of TAG.\n
+first character of TAG.
+
See also `hfy-relstub', `hfy-index-file'."
;;(message "hfy-href-stub");;DBUG
;; FIXME: Why not use something like
@@ -1927,8 +1985,10 @@ See also `hfy-relstub', `hfy-index-file'."
(concat hfy-index-file "." (upcase (substring tag 0 1)))))) )
(defun hfy-href (this-file def-files tag tag-map)
- "Return a relative href to the tag in question, based on\n
-THIS-FILE `hfy-link-extn' `hfy-extn' DEF-FILES TAG and TAG-MAP\n
+ "Return a relative href to the tag in question, based on
+
+THIS-FILE `hfy-link-extn' `hfy-extn' DEF-FILES TAG and TAG-MAP
+
THIS-FILE is the current source file
DEF-FILES is a list of file containing possible link endpoints for TAG
TAG is the tag in question
@@ -1949,8 +2009,10 @@ word characters on either side."
;; mark all tags for hyperlinking, except the tags at
;; their own points of definition, iyswim:
(defun hfy-mark-tag-hrefs (srcdir file)
- "Mark href start points with the `hfy-link' prop (value: href string).\n
-Mark href end points with the `hfy-endl' prop (value t).\n
+ "Mark href start points with the `hfy-link' prop (value: href string).
+
+Mark href end points with the `hfy-endl' prop (value t).
+
Avoid overlapping links, and mark links in descending length of
tag name in order to prevent subtags from usurping supertags,
\(eg \"term\" for \"terminal\").
@@ -2107,9 +2169,11 @@ FILE is the specific file we are rendering."
"Prepare a tags index buffer for SRCDIR.
`hfy-tags-cache' must already have an entry for SRCDIR for this to work.
`hfy-page-header', `hfy-page-footer', `hfy-link-extn' and `hfy-extn'
-all play a part here.\n
+all play a part here.
+
If STUB is set, prepare an (appropriately named) index buffer
-specifically for entries beginning with STUB.\n
+specifically for entries beginning with STUB.
+
If MAP is set, use that instead of `hfy-tags-cache'.
FILENAME is the name of the file being indexed.
DSTDIR is the output directory, where files will be written."
@@ -2185,7 +2249,8 @@ SRCDIR and DSTDIR are the source and output directories respectively."
(defun hfy-prepare-tag-map (srcdir dstdir)
"Prepare the counterpart(s) to the index buffer(s) - a list of buffers
with the same structure, but listing (and linking to) instances of tags
-\(as opposed to their definitions).\n
+\(as opposed to their definitions).
+
SRCDIR and DSTDIR are the source and output directories respectively.
See also `hfy-prepare-index', `hfy-split-index'."
(if (not hfy-split-index)
@@ -2243,10 +2308,6 @@ See also `hfy-load-tags-cache'."
(interactive "D source directory: ")
(hfy-load-tags-cache (directory-file-name srcdir)))
-;;(defun hfy-test-read-args (foo bar)
-;; (interactive "D source directory: \nD target directory: ")
-;; (message "foo: %S\nbar: %S" foo bar))
-
(defun hfy-save-kill-buffers (buffer-list &optional dstdir)
(dolist (B buffer-list)
(set-buffer B)
@@ -2257,7 +2318,8 @@ See also `hfy-load-tags-cache'."
;;;###autoload
(defun htmlfontify-copy-and-link-dir (srcdir dstdir &optional f-ext l-ext)
"Trawl SRCDIR and write fontified-and-hyperlinked output in DSTDIR.
-F-EXT and L-EXT specify values for `hfy-extn' and `hfy-link-extn'.\n
+F-EXT and L-EXT specify values for `hfy-extn' and `hfy-link-extn'.
+
You may also want to set `hfy-page-header' and `hfy-page-footer'."
(interactive "D source directory: \nD output directory: ")
;;(message "htmlfontify-copy-and-link-dir")
@@ -2297,9 +2359,7 @@ You may also want to set `hfy-page-header' and `hfy-page-footer'."
;; (and (string-match "-hook\\'" (symbol-name H))
;; (boundp H)
;; (symbol-value H)
-;; (insert (format "\n '(%S %S)" H (symbol-value H)))
-;; )
-;; )
+;; (insert (format "\n '(%S %S)" H (symbol-value H)))))
;; (defun hfy-save-hooks ()
;; (let ((custom-file (hfy-initfile)))
@@ -2307,10 +2367,7 @@ You may also want to set `hfy-page-header' and `hfy-page-footer'."
;; (let ((standard-output (current-buffer)))
;; (princ "(hfy-set-hooks\n;;auto-generated, only one copy allowed\n")
;; (mapatoms #'hfy-pp-hook)
-;; (insert "\n)")
-;; )
-;; )
-;; )
+;; (insert "\n)"))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defalias 'hfy-init-progn 'progn)
diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el
index 907ee8d63fc..2d2365dc34d 100644
--- a/lisp/ibuf-ext.el
+++ b/lisp/ibuf-ext.el
@@ -693,7 +693,7 @@ To evaluate a form without viewing the buffer, see `ibuffer-do-eval'."
(defun ibuffer-included-in-filters-p (buf filters)
"Return non-nil if BUF passes all FILTERS.
-BUF is a lisp buffer object, and FILTERS is a list of filter
+BUF is a Lisp buffer object, and FILTERS is a list of filter
specifications with the same structure as
`ibuffer-filtering-qualifiers'."
(not
@@ -714,7 +714,7 @@ where operand d is itself a cons cell, or nil. Returns d."
(defun ibuffer-included-in-filter-p (buf filter)
"Return non-nil if BUF pass FILTER.
-BUF is a lisp buffer object, and FILTER is a filter
+BUF is a Lisp buffer object, and FILTER is a filter
specification, with the same structure as an element of the list
`ibuffer-filtering-qualifiers'."
(if (eq (car filter) 'not)
@@ -1210,7 +1210,7 @@ Interactively, prompt for NAME, and use the current filters."
(_
(let ((type (assq (car qualifier) ibuffer-filtering-alist)))
(unless qualifier
- (error "Ibuffer: bad qualifier %s" qualifier))
+ (error "Ibuffer: Bad qualifier %s" qualifier))
(concat " [" (cadr type) ": " (format "%s]" (cdr qualifier)))))))
(defun ibuffer-list-buffer-modes (&optional include-parents)
@@ -1597,7 +1597,10 @@ to move by. The default is `ibuffer-marked-char'."
"Hide all of the currently marked lines."
(interactive)
(if (= (ibuffer-count-marked-lines) 0)
- (message "No buffers marked; use `m' to mark a buffer")
+ (message (substitute-command-keys
+ (concat
+ "No buffers marked; use \\<ibuffer-mode-map>"
+ "\\[ibuffer-mark-forward] to mark a buffer")))
(let ((count
(ibuffer-map-marked-lines
(lambda (_buf _mark)
diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el
index 6c0180590b9..b461197abe9 100644
--- a/lisp/ibuffer.el
+++ b/lisp/ibuffer.el
@@ -1079,7 +1079,8 @@ a new window in the current frame, splitting vertically."
;; Make sure that redisplay is performed, otherwise there can be a
;; bad interaction with code in the window-scroll-functions hook
(redisplay t)
- (when (buffer-local-value 'ibuffer-auto-mode (window-buffer))
+ (when (with-current-buffer (window-buffer)
+ (eq major-mode 'ibuffer-mode))
(fit-window-to-buffer
nil (and owin
(/ (frame-height)
@@ -1256,7 +1257,9 @@ Otherwise, toggle lock status."
"Unmark all buffers with mark MARK."
(interactive "cRemove marks (RET means all):")
(if (= (ibuffer-count-marked-lines t) 0)
- (message "No buffers marked; use `m' to mark a buffer")
+ (message (substitute-command-keys
+ "No buffers marked; use \\<ibuffer-mode-map>\
+\\[ibuffer-mark-forward] to mark a buffer"))
(let ((fn (lambda (_buf mk)
(unless (eq mk ?\s)
(ibuffer-set-mark-1 ?\s)) t)))
@@ -2483,6 +2486,7 @@ Other commands:
`\\[ibuffer-update]' - Regenerate the list of all buffers.
Prefix arg means to toggle whether buffers that match
`ibuffer-maybe-show-predicates' should be displayed.
+ `\\[ibuffer-auto-mode]' - Toggle automatic updates.
`\\[ibuffer-switch-format]' - Change the current display format.
`\\[forward-line]' - Move point to the next line.
diff --git a/lisp/icomplete.el b/lisp/icomplete.el
index 03616f9b6aa..f909a3b1771 100644
--- a/lisp/icomplete.el
+++ b/lisp/icomplete.el
@@ -165,7 +165,7 @@ icompletion is occurring."
"Overlay used to display the list of completions.")
(defvar icomplete--initial-input nil
- "Initial input in the minibuffer when icomplete-mode was activated.
+ "Initial input in the minibuffer when `icomplete-mode' was activated.
Used to implement the option `icomplete-show-matches-on-no-input'.")
(defun icomplete-post-command-hook ()
@@ -380,13 +380,17 @@ if that doesn't produce a completion match."
(defun icomplete-fido-backward-updir ()
"Delete char before or go up directory, like `ido-mode'."
(interactive)
- (if (and (eq (char-before) ?/)
- (eq (icomplete--category) 'file))
- (save-excursion
- (goto-char (1- (point)))
- (when (search-backward "/" (point-min) t)
- (delete-region (1+ (point)) (point-max))))
- (call-interactively 'backward-delete-char)))
+ (cond ((and (eq (char-before) ?/)
+ (eq (icomplete--category) 'file))
+ (when (string-equal (icomplete--field-string) "~/")
+ (delete-region (icomplete--field-beg) (icomplete--field-end))
+ (insert (expand-file-name "~/"))
+ (goto-char (line-end-position)))
+ (save-excursion
+ (goto-char (1- (point)))
+ (when (search-backward "/" (point-min) t)
+ (delete-region (1+ (point)) (point-max)))))
+ (t (call-interactively 'backward-delete-char))))
(defvar icomplete-fido-mode-map
(let ((map (make-sparse-keymap)))
@@ -716,11 +720,6 @@ See `icomplete-mode' and `minibuffer-setup-hook'."
(delete-region (overlay-start rfn-eshadow-overlay)
(overlay-end rfn-eshadow-overlay)))
(let* ((field-string (icomplete--field-string))
- ;; Not sure why, but such requests seem to come
- ;; every once in a while. It's not fully
- ;; deterministic but `C-x C-f M-DEL M-DEL ...'
- ;; seems to trigger it fairly often!
- (while-no-input-ignore-events '(selection-request))
(text (while-no-input
(icomplete-completions
field-string
@@ -760,7 +759,8 @@ by `group-function''s second \"transformation\" protocol."
(plist-get completion-extra-properties :affixation-function)))
(ann-fun (or (completion-metadata-get md 'annotation-function)
(plist-get completion-extra-properties :annotation-function)))
- (grp-fun (completion-metadata-get md 'group-function))
+ (grp-fun (and completions-group
+ (completion-metadata-get md 'group-function)))
(annotated
(cond (aff-fun
(funcall aff-fun prospects))
diff --git a/lisp/ido.el b/lisp/ido.el
index b81a9db5eb9..6767d669880 100644
--- a/lisp/ido.el
+++ b/lisp/ido.el
@@ -354,8 +354,8 @@ The following values are possible:
Setting this variable directly does not take effect;
use either \\[customize] or the function `ido-mode'."
- :set #'(lambda (_symbol value)
- (ido-mode (or value 0)))
+ :set (lambda (_symbol value)
+ (ido-mode (or value 0)))
:initialize #'custom-initialize-default
:require 'ido
:link '(emacs-commentary-link "ido.el")
@@ -620,9 +620,9 @@ hosts on first use of UNC path."
(function-item :tag "Use `NET VIEW'"
:value ido-unc-hosts-net-view)
(function :tag "Your own function"))
- :set #'(lambda (symbol value)
- (set symbol value)
- (setq ido-unc-hosts-cache t)))
+ :set (lambda (symbol value)
+ (set symbol value)
+ (setq ido-unc-hosts-cache t)))
(defcustom ido-downcase-unc-hosts t
"Non-nil if UNC host names should be downcased."
@@ -834,7 +834,7 @@ Each function on the list may modify the dynamically bound variable
:type 'hook)
(defcustom ido-rewrite-file-prompt-functions nil
- "List of functions to run when the find-file prompt is created.
+ "List of functions to run when the `find-file' prompt is created.
Each function on the list may modify the following dynamically bound
variables:
dirname - the (abbreviated) directory name
@@ -3620,7 +3620,7 @@ Uses and updates `ido-dir-file-cache'."
(defun ido-make-file-list-1 (dir &optional merged)
- "Return list of non-ignored files in DIR
+ "Return list of non-ignored files in DIR.
If MERGED is non-nil, each file is cons'ed with DIR."
(and (or (ido-is-tramp-root dir) (ido-is-unc-root dir)
(file-directory-p dir))
@@ -4397,7 +4397,7 @@ For details of keybindings, see `ido-find-file'."
;;;###autoload
(defun ido-dired-other-window ()
- "\"Edit\" a directory. Like `ido-dired' but selects in another window.
+ "\"Edit\" a directory. Like `ido-dired' but select in another window.
The directory is selected interactively by typing a substring.
For details of keybindings, see `ido-find-file'."
(interactive)
@@ -4408,7 +4408,7 @@ For details of keybindings, see `ido-find-file'."
;;;###autoload
(defun ido-dired-other-frame ()
- "\"Edit\" a directory. Like `ido-dired' but makes a new frame.
+ "\"Edit\" a directory. Like `ido-dired' but make a new frame.
The directory is selected interactively by typing a substring.
For details of keybindings, see `ido-find-file'."
(interactive)
diff --git a/lisp/ielm.el b/lisp/ielm.el
index fd8dac74b74..ec7f010a4d5 100644
--- a/lisp/ielm.el
+++ b/lisp/ielm.el
@@ -148,28 +148,28 @@ such as `edebug-defun' to work with such inputs."
This variable is buffer-local.")
(defvar ielm-header
- "*** Welcome to IELM *** Type (describe-mode) for help.\n"
+ (substitute-command-keys
+ "*** Welcome to IELM *** Type (describe-mode) or press \
+\\[describe-mode] for help.\n")
"Message to display when IELM is started.")
(defvaralias 'inferior-emacs-lisp-mode-map 'ielm-map)
-(defvar ielm-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\t" 'ielm-tab)
- (define-key map "\C-m" 'ielm-return)
- (define-key map "\e\C-m" 'ielm-return-for-effect)
- (define-key map "\C-j" 'ielm-send-input)
- (define-key map "\e\C-x" 'eval-defun) ; for consistency with
- (define-key map "\e\t" 'completion-at-point) ; lisp-interaction-mode
- ;; These bindings are from `lisp-mode-shared-map' -- can you inherit
- ;; from more than one keymap??
- (define-key map "\e\C-q" 'indent-sexp)
- (define-key map "\177" 'backward-delete-char-untabify)
- ;; Some convenience bindings for setting the working buffer
- (define-key map "\C-c\C-b" 'ielm-change-working-buffer)
- (define-key map "\C-c\C-f" 'ielm-display-working-buffer)
- (define-key map "\C-c\C-v" 'ielm-print-working-buffer)
- map)
- "Keymap for IELM mode.")
+(defvar-keymap ielm-map
+ :doc "Keymap for IELM mode."
+ "TAB" #'ielm-tab
+ "RET" #'ielm-return
+ "M-RET" #'ielm-return-for-effect
+ "C-j" #'ielm-send-input
+ "C-M-x" #'eval-defun ; for consistency with
+ "M-TAB" #'completion-at-point ; lisp-interaction-mode
+ ;; These bindings are from `lisp-mode-shared-map' -- can you inherit
+ ;; from more than one keymap??
+ "C-M-q" #'indent-sexp
+ "DEL" #'backward-delete-char-untabify
+ ;; Some convenience bindings for setting the working buffer
+ "C-c C-b" #'ielm-change-working-buffer
+ "C-c C-f" #'ielm-display-working-buffer
+ "C-c C-v" #'ielm-print-working-buffer)
(easy-menu-define ielm-menu ielm-map
"IELM mode menu."
@@ -440,8 +440,7 @@ nonempty, then flushes the buffer."
(concat (buffer-string) aux))))))
(error
(setq error-type "IELM Error")
- (setq result (format "Error during pretty-printing (bug in pp): %S"
- err)))
+ (setq result (format "Error during pretty-printing: %S" err)))
(quit (setq error-type "IELM Error")
(setq result "Quit during pretty-printing"))))
(if error-type
diff --git a/lisp/iimage.el b/lisp/iimage.el
index 192530a8e6a..b18dd841fcb 100644
--- a/lisp/iimage.el
+++ b/lisp/iimage.el
@@ -50,7 +50,7 @@
:group 'image)
(defcustom iimage-mode-image-search-path nil
- "List of directories to search for image files for iimage-mode."
+ "List of directories to search for image files for `iimage-mode'."
:type '(choice (const nil) (repeat directory)))
(defvar iimage-mode-image-filename-regex
diff --git a/lisp/image-dired.el b/lisp/image-dired.el
index cf878ae1223..6ca0cd8831d 100644
--- a/lisp/image-dired.el
+++ b/lisp/image-dired.el
@@ -1,7 +1,7 @@
;;; image-dired.el --- use dired to browse and manipulate your images -*- lexical-binding: t -*-
-;;
+
;; Copyright (C) 2005-2021 Free Software Foundation, Inc.
-;;
+
;; Version: 0.4.11
;; Keywords: multimedia
;; Author: Mathias Dahl <mathias.rem0veth1s.dahl@gmail.com>
@@ -22,7 +22,7 @@
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
-;;
+
;; BACKGROUND
;; ==========
;;
@@ -41,11 +41,11 @@
;;
;; I briefly tried out thumbs.el, and although it seemed more
;; powerful than this package, it did not work the way I wanted to. It
-;; was too slow to created thumbnails of all files in a directory (I
+;; was too slow to create thumbnails of all files in a directory (I
;; currently keep all my 2000+ images in the same directory) and
;; 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
+;; quickly and easily in Dired. I copied a great deal of ideas and
;; code from there though... :)
;;
;; `image-dired' stores the thumbnail files in `image-dired-dir'
@@ -59,19 +59,22 @@
;; PREREQUISITES
;; =============
;;
-;; * The ImageMagick package. Currently, `convert' and `mogrify' are
-;; used. Find it here: https://www.imagemagick.org.
+;; * The GraphicsMagick or ImageMagick package; Image-Dired uses
+;; whichever is available.
+;;
+;; A) For GraphicsMagick, `gm' is used.
+;; Find it here: http://www.graphicsmagick.org/
+;;
+;; B) For ImageMagick, `convert' and `mogrify' are used.
+;; Find it here: https://www.imagemagick.org.
;;
;; * For non-lossy rotation of JPEG images, the JpegTRAN program is
-;; needed.
+;; needed.
;;
-;; * For `image-dired-get-exif-data' and `image-dired-set-exif-data' to work,
-;; the command line tool `exiftool' is needed. It can be found here:
-;; https://exiftool.org/. These two functions are, among other
-;; things, used for writing comments to image files using
-;; `image-dired-thumbnail-set-image-description' and to create
-;; "unique" file names using `image-dired-get-exif-file-name' (used by
-;; `image-dired-copy-with-exif-file-name').
+;; * For `image-dired-set-exif-data' to work, the command line tool `exiftool' is
+;; needed. It can be found here: https://exiftool.org/. This
+;; function is, among other things, used for writing comments to
+;; image files using `image-dired-thumbnail-set-image-description'.
;;
;;
;; USAGE
@@ -89,179 +92,168 @@
;; ===========
;;
;; * Supports all image formats that Emacs and convert supports, but
-;; the thumbnails are hard-coded to JPEG format.
+;; the thumbnails are hard-coded to JPEG or PNG format. It uses
+;; JPEG by default, but can optionally follow the Thumbnail Managing
+;; Standard (v0.9.0, Dec 2020), which mandates PNG. See the user
+;; 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.
-;;
-;; * `image-dired-display-image-mode' does not support animation
+;; backup of `image-dired-db-file' when testing new versions.
;;
;; TODO
;; ====
;;
-;; * Support gallery creation when using per-directory thumbnail
-;; storage.
-;;
-;; * Some sort of auto-rotate function based on rotate info in the
-;; EXIF data.
-;;
;; * Investigate if it is possible to also write the tags to the image
-;; files.
+;; files.
;;
;; * From thumbs.el: Add an option for clean-up/max-size functionality
;; for thumbnail directory.
;;
;; * From thumbs.el: Add setroot function.
;;
-;; * From thumbs.el: Add image resizing, if useful (image-dired's automatic
-;; "image fit" might be enough)
-;;
-;; * From thumbs.el: Add the "modify" commands (emboss, negate,
-;; monochrome etc).
-;;
-;; * 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 it
-;; probably needs rewriting `image-dired-display-thumbs' to be more general.
+;; * 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
+;; it probably needs rewriting `image-dired-display-thumbs' to be more general.
;;
;; * Find some way of toggling on and off really nice keybindings in
-;; dired (for example, using C-n or <down> instead of C-S-n). Richard
-;; suggested that we could keep C-t as prefix for image-dired commands
-;; as it is currently not used in dired. He also suggested that
-;; `dired-next-line' and `dired-previous-line' figure out if
-;; image-dired is enabled in the current buffer and, if it is, call
-;; `image-dired-dired-next-line' and
-;; `image-dired-dired-previous-line', respectively. Update: This is
-;; partly done; some bindings have now been added to dired.
-;;
-;; * Enhanced gallery creation with basic CSS-support and pagination
-;; of tag pages with many pictures.
-;;
-;; * Rewrite `image-dired-modify-mark-on-thumb-original-file' to be
-;; less ugly.
+;; Dired (for example, using C-n or <down> instead of C-S-n).
+;; Richard suggested that we could keep C-t as prefix for
+;; image-dired commands as it is currently not used in Dired. He
+;; also suggested that `dired-next-line' and `dired-previous-line'
+;; figure out if image-dired is enabled in the current buffer and,
+;; if it is, call `image-dired-dired-next-line' and `image-dired-dired-previous-line',
+;; respectively. Update: This is partly done; some bindings have
+;; now been added to Dired.
;;
;; * In some way keep track of buffers and windows and stuff so that
-;; it works as the user expects.
-;;
-;; * More/better documentation
-;;
+;; it works as the user expects.
;;
+;; * More/better documentation.
+
;;; Code:
(require 'dired)
+(require 'exif)
(require 'image-mode)
(require 'widget)
+(require 'xdg)
(eval-when-compile
(require 'cl-lib)
(require 'wid-edit))
+
+;;; Customizable variables
+
(defgroup image-dired nil
- "Use dired to browse your images as thumbnails, and more."
+ "Use Dired to browse your images as thumbnails, and more."
:prefix "image-dired-"
:link '(info-link "(emacs) Image-Dired")
:group 'multimedia)
(defcustom image-dired-dir (locate-user-emacs-file "image-dired/")
- "Directory where thumbnail images are stored."
+ "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
+`image-dired-thumbnail-storage'."
:type 'directory)
(defcustom image-dired-thumbnail-storage 'use-image-dired-dir
- "How to store image-dired's thumbnail files.
-Image-Dired can store thumbnail files in one of two ways and this is
-controlled by this variable. \"Use image-dired dir\" means that the
-thumbnails are stored in a central directory. \"Per directory\"
-means that each thumbnail is stored in a subdirectory called
-\".image-dired\" in the same directory where the image file is.
-\"Thumbnail Managing Standard\" means that the thumbnails are
-stored and generated according to the Thumbnail Managing Standard
-that allows sharing of thumbnails across different programs."
+ "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:
+
+- `use-image-dired-dir' means that the thumbnails are stored in a
+ central directory.
+
+- `per-directory' means that each thumbnail is stored in a
+ subdirectory called \".image-dired\" in the same directory
+ where the image file is.
+
+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:
+
+- `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.
+
+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 "Thumbnail Managing Standard (normal 128x128)" standard)
- (const :tag "Thumbnail Managing Standard (large 256x256)" standard-large)
- (const :tag "Per-directory" per-directory)))
+ (const :tag "Thumbnail Managing Standard (normal 128x128)"
+ standard)
+ (const :tag "Thumbnail Managing Standard (large 256x256)"
+ standard-large)
+ (const :tag "Thumbnail Managing Standard (larger 512x512)"
+ standard-x-large)
+ (const :tag "Thumbnail Managing Standard (extra large 1024x1024)"
+ standard-xx-large)
+ (const :tag "Per-directory" per-directory))
+ :version "29.1")
+
+(defconst image-dired--thumbnail-standard-sizes
+ '( standard standard-large
+ standard-x-large standard-xx-large)
+ "List of symbols representing thumbnail sizes in Thumbnail Managing Standard.")
(defcustom image-dired-db-file
(expand-file-name ".image-dired_db" image-dired-dir)
"Database file where file names and their associated tags are stored."
:type 'file)
-(defcustom image-dired-temp-image-file
- (expand-file-name ".image-dired_temp" image-dired-dir)
- "Name of temporary image file used by various commands."
- :type 'file)
-
-(defcustom image-dired-gallery-dir
- (expand-file-name ".image-dired_gallery" image-dired-dir)
- "Directory to store generated gallery html pages.
-This path needs to be \"shared\" to the public so that it can access
-the index.html page that image-dired creates."
- :type 'directory)
-
-(defcustom image-dired-gallery-image-root-url
-"https://your.own.server/image-diredpics"
- "URL where the full size images are to be found.
-Note that this path has to be configured in your web server. Image-Dired
-expects to find pictures in this directory."
- :type 'string)
-
-(defcustom image-dired-gallery-thumb-image-root-url
-"https://your.own.server/image-diredthumbs"
- "URL where the thumbnail images are to be found.
-Note that this path has to be configured in your web server. Image-Dired
-expects to find pictures in this directory."
- :type 'string)
-
(defcustom image-dired-cmd-create-thumbnail-program
- "convert"
+ (if (executable-find "gm") "gm" "convert")
"Executable used to create thumbnail.
Used together with `image-dired-cmd-create-thumbnail-options'."
- :type 'file)
+ :type 'file
+ :version "29.1")
(defcustom image-dired-cmd-create-thumbnail-options
- '("-size" "%wx%h" "%f[0]" "-resize" "%wx%h>" "-strip" "jpeg:%t")
+ (let ((opts '("-size" "%wx%h" "%f[0]"
+ "-resize" "%wx%h>"
+ "-strip" "jpeg:%t")))
+ (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 "26.1"
- :type '(repeat (string :tag "Argument")))
-
-(defcustom image-dired-cmd-create-temp-image-program "convert"
- "Executable used to create temporary image.
-Used together with `image-dired-cmd-create-temp-image-options'."
- :type 'file)
-
-(defcustom image-dired-cmd-create-temp-image-options
- '("-size" "%wx%h" "%f[0]" "-resize" "%wx%h>" "-strip" "jpeg:%t")
- "Options of command used to create temporary image for display window.
-Used together with `image-dired-cmd-create-temp-image-program',
-Available format specifiers are: %w and %h which are replaced by
-the calculated max size for width and height in the image display window,
-%f which is replaced by the file name of the original image and %t which
-is replaced by the file name of the temporary file."
- :version "26.1"
+ :version "29.1"
:type '(repeat (string :tag "Argument")))
(defcustom image-dired-cmd-pngnq-program
- (or (executable-find "pngnq")
- (executable-find "pngnq-s9"))
- "The file name of the `pngnq' program.
+ ;; Prefer pngquant to pngnq-s9 as it is faster on my machine.
+ ;; The project also seems more active than the alternatives.
+ ;; Prefer pngnq-s9 to pngnq as it fixes bugs in pngnq.
+ ;; The pngnq project seems dead (?) since 2011 or so.
+ (or (executable-find "pngquant")
+ (executable-find "pngnq-s9")
+ (executable-find "pngnq"))
+ "The file name of the `pngquant' or `pngnq' program.
It quantizes colors of PNG images down to 256 colors or fewer
using the NeuQuant algorithm."
- :version "26.1"
+ :version "29.1"
:type '(choice (const :tag "Not Set" nil) file))
(defcustom image-dired-cmd-pngnq-options
- '("-f" "%t")
+ (if (executable-find "pngquant")
+ '("--ext" "-nq8.png" "%t") ; same extension as "pngnq"
+ '("-f" "%t"))
"Arguments to pass `image-dired-cmd-pngnq-program'.
Available format specifiers are the same as in
`image-dired-cmd-create-thumbnail-options'."
- :version "26.1"
- :type '(repeat (string :tag "Argument")))
+ :type '(repeat (string :tag "Argument"))
+ :version "29.1")
(defcustom image-dired-cmd-pngcrush-program (executable-find "pngcrush")
"The file name of the `pngcrush' program.
@@ -316,23 +308,6 @@ Available format specifiers are the same as in
:version "26.1"
:type '(repeat (string :tag "Argument")))
-(defcustom image-dired-cmd-rotate-thumbnail-program
- "mogrify"
- "Executable used to rotate thumbnail.
-Used together with `image-dired-cmd-rotate-thumbnail-options'."
- :type 'file)
-
-(defcustom image-dired-cmd-rotate-thumbnail-options
- '("-rotate" "%d" "%t")
- "Arguments of command used to rotate thumbnail image.
-Used with `image-dired-cmd-rotate-thumbnail-program'.
-Available format specifiers are: %d which is replaced by the
-number of (positive) degrees to rotate the image, normally 90 or 270
-\(for 90 degrees right and left), %t which is replaced by the file name
-of the thumbnail file."
- :version "26.1"
- :type '(repeat (string :tag "Argument")))
-
(defcustom image-dired-cmd-rotate-original-program
"jpegtran"
"Executable used to rotate original image.
@@ -378,35 +353,20 @@ which is replaced by the tag value."
:version "26.1"
:type '(repeat (string :tag "Argument")))
-(defcustom image-dired-cmd-read-exif-data-program
- "exiftool"
- "Program used to read EXIF data to image.
-Used together with `image-dired-cmd-read-exif-data-options'."
- :type 'file)
-
-(defcustom image-dired-cmd-read-exif-data-options
- '("-s" "-s" "-s" "-%t" "%f")
- "Arguments of command used to read EXIF data.
-Used with `image-dired-cmd-read-exif-data-program'.
-Available format specifiers are: %f which is replaced
-by the image file name and %t which is replaced by the tag name."
- :version "26.1"
- :type '(repeat (string :tag "Argument")))
-
-(defcustom image-dired-gallery-hidden-tags
- (list "private" "hidden" "pending")
- "List of \"hidden\" tags.
-Used by `image-dired-gallery-generate' to leave out \"hidden\" images."
- :type '(repeat string))
-
(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'."
+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
@@ -427,17 +387,28 @@ This is where you see the cursor."
:type 'integer)
(defcustom image-dired-thumb-visible-marks t
- "Make marks visible in thumbnail buffer.
+ "Make marks and flags visible in thumbnail buffer.
If non-nil, apply the `image-dired-thumb-mark' face to marked
-images."
+images and `image-dired-thumb-flagged' to images flagged for
+deletion."
:type 'boolean
:version "28.1")
(defface image-dired-thumb-mark
- '((t (:background "orange")))
- "Background-color for marked images in thumbnail buffer."
- :group 'image-dired
- :version "28.1")
+ '((((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.
@@ -456,18 +427,6 @@ and No line-up means that no automatic line-up will be done."
"Number of thumbnails to display per row in thumb buffer."
:type 'integer)
-(defcustom image-dired-display-window-width-correction 1
- "Number to be used to correct image display window width.
-Change if the default (1) does not work (i.e. if the image does not
-completely fit)."
- :type 'integer)
-
-(defcustom image-dired-display-window-height-correction 0
- "Number to be used to correct image display window height.
-Change if the default (0) does not work (i.e. if the image does not
-completely fit)."
- :type 'integer)
-
(defcustom image-dired-track-movement t
"The current state of the tracking and mirroring.
For more information, see the documentation for
@@ -485,18 +444,18 @@ This value can be toggled using `image-dired-toggle-append-browsing'."
:type 'boolean)
(defcustom image-dired-dired-disp-props t
- "If non-nil, display properties for dired file when browsing.
+ "If non-nil, display properties for Dired file when browsing.
Used by `image-dired-next-line-and-display',
`image-dired-previous-line-and-display' and `image-dired-mark-and-display-next'.
If the database file is large, this can slow down image browsing in
-dired and you might want to turn it off."
+Dired and you might want to turn it off."
:type 'boolean)
(defcustom image-dired-display-properties-format "%b: %f (%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."
+%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)
(defcustom image-dired-external-viewer
@@ -504,23 +463,54 @@ with the comment."
;; dired-view-command-alist.
(cond ((executable-find "display"))
((executable-find "xli"))
- ((executable-find "qiv") "qiv -t"))
+ ((executable-find "qiv") "qiv -t")
+ ((executable-find "feh") "feh"))
"Name of external viewer.
Including parameters. Used when displaying original image from
`image-dired-thumbnail-mode'."
- :version "27.1"
+ :version "28.1"
:type '(choice string
(const :tag "Not Set" nil)))
-(defcustom image-dired-main-image-directory "~/pics/"
+(defcustom image-dired-main-image-directory
+ (or (xdg-user-dir "PICTURES") "~/pics/")
"Name of main image directory, if any.
Used by `image-dired-copy-with-exif-file-name'."
- :type 'string)
+ :type 'string
+ :version "29.1")
+
+(defcustom image-dired-show-all-from-dir-max-files 500
+ "Maximum number of files in directory before prompting.
+
+If there are more image files than this in a selected directory,
+the `image-dired-show-all-from-dir' command will ask for
+confirmation before creating the thumbnail buffer. If this
+variable is nil, it will never ask."
+ :type '(choice integer
+ (const :tag "Disable warning" nil))
+ :version "29.1")
+
+(defcustom image-dired-marking-shows-next t
+ "If non-nil, marking, unmarking or flagging an image shows the next image.
+
+This affects the following commands:
+\\<image-dired-thumbnail-mode-map>
+ `image-dired-flag-thumb-original-file' (bound to \\[image-dired-flag-thumb-original-file])
+ `image-dired-mark-thumb-original-file' (bound to \\[image-dired-mark-thumb-original-file])
+ `image-dired-unmark-thumb-original-file' (bound to \\[image-dired-unmark-thumb-original-file])"
+ :type 'boolean
+ :version "29.1")
-(defcustom image-dired-show-all-from-dir-max-files 50
- "Maximum number of files to show using `image-dired-show-all-from-dir'
-before warning the user."
- :type 'integer)
+
+;;; Util functions
+
+(defvar image-dired-debug nil
+ "Non-nil means enable debug messages.")
+
+(defun image-dired-debug-message (&rest args)
+ "Display debug message ARGS when `image-dired-debug' is non-nil."
+ (when image-dired-debug
+ (apply #'message args)))
(defmacro image-dired--with-db-file (&rest body)
"Run BODY in a temp buffer containing `image-dired-db-file'.
@@ -532,13 +522,14 @@ Return the last form in BODY."
,@body))
(defun image-dired-dir ()
- "Return the current thumbnails directory (from variable `image-dired-dir').
-Create the thumbnails directory if it does not exist."
+ "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))))
+ (expand-file-name image-dired-dir))))
(unless (file-directory-p image-dired-dir)
- (make-directory image-dired-dir t)
- (message "Creating thumbnails directory"))
+ (with-file-modes #o700
+ (make-directory image-dired-dir t))
+ (message "Thumbnail directory created: %s" image-dired-dir))
image-dired-dir))
(defun image-dired-insert-image (file type relief margin)
@@ -551,7 +542,7 @@ Create the thumbnails directory if it does not exist."
(defun image-dired-get-thumbnail-image (file)
"Return the image descriptor for a thumbnail of image file FILE."
- (unless (string-match (image-file-name-regexp) file)
+ (unless (string-match-p (image-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)))
@@ -560,11 +551,7 @@ Create the thumbnails directory if it does not exist."
(file-attribute-modification-time
(file-attributes file))))
(image-dired-create-thumb file thumb-file))
- (create-image thumb-file)
-;; (list 'image :type 'jpeg
-;; :file thumb-file
-;; :relief image-dired-thumb-relief :margin image-dired-thumb-margin)
- ))
+ (create-image thumb-file)))
(defun image-dired-insert-thumbnail (file original-file-name
associated-dired-buffer)
@@ -572,13 +559,19 @@ Create the thumbnails directory if it does not exist."
Add text properties ORIGINAL-FILE-NAME and ASSOCIATED-DIRED-BUFFER."
(let (beg end)
(setq beg (point))
- (image-dired-insert-image file
- ;; TODO: this should depend on the real file type
- (if (memq image-dired-thumbnail-storage
- '(standard standard-large))
- 'png 'jpeg)
- image-dired-thumb-relief
- image-dired-thumb-margin)
+ (image-dired-insert-image
+ file
+ ;; Thumbnails are created asynchronously, so we might not yet
+ ;; have a file. But if it exists, it might have been cached from
+ ;; before and we should use it instead of our current settings.
+ (or (and (file-exists-p file)
+ (image-type-from-file-header file))
+ (and (memq image-dired-thumbnail-storage
+ image-dired--thumbnail-standard-sizes)
+ 'png)
+ 'jpeg)
+ image-dired-thumb-relief
+ image-dired-thumb-margin)
(setq end (point))
(add-text-properties
beg end
@@ -590,35 +583,39 @@ Add text properties ORIGINAL-FILE-NAME and ASSOCIATED-DIRED-BUFFER."
'comment (image-dired-get-comment original-file-name)))))
(defun image-dired-thumb-name (file)
- "Return thumbnail file name for FILE.
-Depending on the value of `image-dired-thumbnail-storage', the file
-name will vary. For central thumbnail file storage, make a
-MD5-hash of the image file's directory name and add that to make
-the thumbnail file name unique. For per-directory storage, just
-add a subdirectory. For standard storage, produce the file name
-according to the Thumbnail Managing Standard."
- (cond ((memq image-dired-thumbnail-storage '(standard standard-large))
- (let* ((xdg (getenv "XDG_CACHE_HOME"))
- (dir (if (and xdg (file-name-absolute-p xdg))
- xdg "~/.cache"))
- (thumbdir (cl-case image-dired-thumbnail-storage
- (standard "thumbnails/normal")
- (standard-large "thumbnails/large"))))
+ "Return absolute file name for thumbnail FILE.
+Depending on the value of `image-dired-thumbnail-storage', the
+file name of the thumbnail will vary:
+- For `use-image-dired-dir', make a SHA1-hash of the image file's
+ directory name and add that to make the thumbnail file name
+ unique.
+- For `per-directory' storage, just add a subdirectory.
+- For `standard' storage, produce the file name according to the
+ Thumbnail Managing Standard. Among other things, an MD5-hash
+ 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 dir))))
+ (expand-file-name thumbdir (xdg-cache-home)))))
((eq 'use-image-dired-dir image-dired-thumbnail-storage)
(let* ((f (expand-file-name file))
- (md5-hash
- ;; Is MD5 hashes fast enough? The checksum of a
- ;; thumbnail file name need not be that
- ;; "cryptographically" good so a faster one could
- ;; be used here.
- (md5 (file-name-as-directory (file-name-directory f)))))
+ (hash
+ ;; SHA1 is slightly faster than MD5, so let's use it.
+ ;; (We don't need anything crytographically strong.)
+ (sha1 (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 md5-hash (concat "_" md5-hash) "")
+ (if hash (concat "_" hash) "")
(file-name-extension f))))
((eq 'per-directory image-dired-thumbnail-storage)
(let ((f (expand-file-name file)))
@@ -631,16 +628,24 @@ according to the Thumbnail Managing Standard."
(unless (executable-find (symbol-value executable))
(error "Executable %S not found" executable)))
+
+;;; 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)))))
+(defvar image-dired--generate-thumbs-start nil
+ "Time when `display-thumbs' was called.")
+
(defvar image-dired-queue nil
"List of items in the queue.
Each item has the form (ORIGINAL-FILE TARGET-FILE).")
@@ -648,11 +653,12 @@ Each item has the form (ORIGINAL-FILE TARGET-FILE).")
(defvar image-dired-queue-active-jobs 0
"Number of active jobs in `image-dired-queue'.")
-(defvar image-dired-queue-active-limit 2
+(defvar image-dired-queue-active-limit (min 4 (max 2 (/ (num-processors) 2)))
"Maximum number of concurrent jobs permitted for generating images.
-Increase at own risk.")
-
-(defvar image-dired-tag-history nil "Variable holding the tag history.")
+Increase at own risk. If you want to experiment with this,
+consider setting `image-dired-debug' to a non-nil value to see
+the time spent on generating thumbnails. Run `image-clear-cache'
+and remove the cached thumbnail files between each trial run.")
(defun image-dired-pngnq-thumb (spec)
"Quantize thumbnail described by format SPEC with pngnq(1)."
@@ -739,9 +745,9 @@ Increase at own risk.")
(thumbnail-dir (file-name-directory thumbnail-file))
process)
(when (not (file-exists-p thumbnail-dir))
- (message "Creating thumbnail directory")
(with-file-modes #o700
- (make-directory thumbnail-dir t)))
+ (make-directory thumbnail-dir t))
+ (message "Thumbnail directory created: %s" thumbnail-dir))
;; Thumbnail file creation processes begin here and are marshaled
;; in a queue by `image-dired-create-thumb'.
@@ -751,7 +757,7 @@ Increase at own risk.")
(mapcar
(lambda (arg) (format-spec arg spec))
(if (memq image-dired-thumbnail-storage
- '(standard standard-large))
+ image-dired--thumbnail-standard-sizes)
image-dired-cmd-create-standard-thumbnail-options
image-dired-cmd-create-thumbnail-options))))
@@ -760,6 +766,12 @@ Increase at own risk.")
;; Trigger next in queue once a thumbnail has been created
(cl-decf image-dired-queue-active-jobs)
(image-dired-thumb-queue-run)
+ (when (= image-dired-queue-active-jobs 0)
+ (image-dired-debug-message
+ (format-time-string
+ "Generated thumbnails in %s.%3N seconds"
+ (time-subtract nil
+ image-dired--generate-thumbs-start))))
(if (not (and (eq (process-status process) 'exit)
(zerop (process-exit-status process))))
(message "Thumb could not be created for %s: %s"
@@ -770,7 +782,7 @@ Increase at own risk.")
;; PNG thumbnail has been created since we are
;; following the XDG thumbnail spec, so try to optimize
(when (memq image-dired-thumbnail-storage
- '(standard standard-large))
+ image-dired--thumbnail-standard-sizes)
(cond
((and image-dired-cmd-pngnq-program
(executable-find image-dired-cmd-pngnq-program))
@@ -793,7 +805,8 @@ Queued items live in `image-dired-queue'."
(apply #'image-dired-create-thumb-1 (pop image-dired-queue))))
(defun image-dired-create-thumb (original-file thumbnail-file)
- "Add a job for generating thumbnail to `image-dired-queue'."
+ "Add a job for generating ORIGINAL-FILE thumbnail to `image-dired-queue'.
+The new file will be named THUMBNAIL-FILE."
(setq image-dired-queue
(nconc image-dired-queue
(list (list original-file thumbnail-file))))
@@ -817,7 +830,7 @@ thumbnail."
;;;###autoload
(defun image-dired-dired-toggle-marked-thumbs (&optional arg)
- "Toggle thumbnails in front of file names in the dired buffer.
+ "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
@@ -848,7 +861,7 @@ previous -ARG, if ARG<0) files."
'image-dired-dired-after-readin-hook nil t))
(defun image-dired-dired-after-readin-hook ()
- "Relocate existing thumbnail overlays in dired buffer after reverting.
+ "Relocate existing thumbnail overlays in Dired buffer after reverting.
Move them to their corresponding files if they still exist.
Otherwise, delete overlays."
(mapc (lambda (overlay)
@@ -861,7 +874,7 @@ Otherwise, delete overlays."
(overlays-in (point-min) (point-max))))
(defun image-dired-next-line-and-display ()
- "Move to next dired line and display thumbnail image."
+ "Move to next Dired line and display thumbnail image."
(interactive)
(dired-next-line 1)
(image-dired-display-thumbs
@@ -870,7 +883,7 @@ Otherwise, delete overlays."
(image-dired-dired-display-properties)))
(defun image-dired-previous-line-and-display ()
- "Move to previous dired line and display thumbnail image."
+ "Move to previous Dired line and display thumbnail image."
(interactive)
(dired-previous-line 1)
(image-dired-display-thumbs
@@ -883,13 +896,13 @@ Otherwise, delete overlays."
(interactive)
(setq image-dired-append-when-browsing
(not image-dired-append-when-browsing))
- (message "Append browsing %s."
+ (message "Append browsing %s"
(if image-dired-append-when-browsing
"on"
"off")))
(defun image-dired-mark-and-display-next ()
- "Mark current file in dired and display next thumbnail image."
+ "Mark current file in Dired and display next thumbnail image."
(interactive)
(dired-mark 1)
(image-dired-display-thumbs
@@ -922,15 +935,6 @@ Otherwise, delete overlays."
(defvar image-dired-display-image-buffer "*image-dired-display-image*"
"Where larger versions of the images are display.")
-(defun image-dired-create-display-image-buffer ()
- "Create image display buffer and set `image-dired-display-image-mode'."
- (let ((buf (get-buffer-create image-dired-display-image-buffer)))
- (with-current-buffer buf
- (setq buffer-read-only t)
- (if (not (eq major-mode 'image-dired-display-image-mode))
- (image-dired-display-image-mode)))
- buf))
-
(defvar image-dired-saved-window-configuration nil
"Saved window configuration.")
@@ -940,12 +944,12 @@ Otherwise, delete overlays."
Convenience command that:
- - Opens dired in folder DIR
+ - Opens Dired in folder DIR
- Splits windows in most useful (?) way
- - Set `truncate-lines' to t
+ - Sets `truncate-lines' to t
After the command has finished, you would typically mark some
-image files in dired and type
+image files in Dired and type
\\[image-dired-display-thumbs] (`image-dired-display-thumbs').
If called with prefix argument ARG, skip splitting of windows.
@@ -954,7 +958,7 @@ The current window configuration is saved and can be restored by
calling `image-dired-restore-window-configuration'."
(interactive "DDirectory: \nP")
(let ((buf (image-dired-create-thumbnail-buffer))
- (buf2 (image-dired-create-display-image-buffer)))
+ (buf2 (get-buffer-create image-dired-display-image-buffer)))
(setq image-dired-saved-window-configuration
(current-window-configuration))
(dired dir)
@@ -973,7 +977,7 @@ calling `image-dired-restore-window-configuration'."
"Restore window configuration.
Restore any changes to the window configuration made by calling
`image-dired-dired-with-window-configuration'."
- (interactive)
+ (interactive nil image-dired-thumbnail-mode)
(if image-dired-saved-window-configuration
(set-window-configuration image-dired-saved-window-configuration)
(message "No saved window configuration")))
@@ -1000,7 +1004,7 @@ point (this is useful if you have marked some files but want to show
another one).
Recommended usage is to split the current frame horizontally so that
-you have the dired buffer in the left window and the
+you have the Dired buffer in the left window and the
`image-dired-thumbnail-buffer' buffer in the right window.
With optional argument APPEND, append thumbnail to thumbnail buffer
@@ -1013,6 +1017,7 @@ 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."
(interactive "P")
+ (setq image-dired--generate-thumbs-start (current-time))
(let ((buf (image-dired-create-thumbnail-buffer))
thumb-name files dired-buf)
(if arg
@@ -1036,30 +1041,38 @@ thumbnail buffer to be selected."
;;;###autoload
(defun image-dired-show-all-from-dir (dir)
- "Make a preview buffer for all images in DIR and display it.
-If the number of files in DIR matching `image-file-name-regexp'
-exceeds `image-dired-show-all-from-dir-max-files', a warning will be
-displayed."
- (interactive "DImage 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.
+
+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: ")
(dired dir)
(dired-mark-files-regexp (image-file-name-regexp))
- (let ((files (dired-get-marked-files)))
- (if (or (<= (length files) image-dired-show-all-from-dir-max-files)
- (and (> (length files) image-dired-show-all-from-dir-max-files)
- (y-or-n-p
- (format
- "Directory contains more than %d image files. Proceed? "
- image-dired-show-all-from-dir-max-files))))
- (progn
- (image-dired-display-thumbs)
- (pop-to-buffer image-dired-thumbnail-buffer))
- (message "Canceled."))))
+ (let ((files (dired-get-marked-files nil nil nil t)))
+ (cond ((and (null (cdr files)))
+ (message "No image files in directory"))
+ ((or (not image-dired-show-all-from-dir-max-files)
+ (<= (length (cdr files)) image-dired-show-all-from-dir-max-files)
+ (and (> (length (cdr files)) image-dired-show-all-from-dir-max-files)
+ (y-or-n-p
+ (format
+ "Directory contains more than %d image files. Proceed?"
+ image-dired-show-all-from-dir-max-files))))
+ (image-dired-display-thumbs)
+ (pop-to-buffer image-dired-thumbnail-buffer)
+ (setq default-directory dir)
+ (image-dired-unmark-all-marks))
+ (t (message "Image-Dired canceled")))))
;;;###autoload
(defalias 'image-dired 'image-dired-show-all-from-dir)
-;;;###autoload
-(define-obsolete-function-alias 'tumme 'image-dired "24.4")
+
+;;; Tags
(defun image-dired-sane-db-file ()
"Check if `image-dired-db-file' exists.
@@ -1069,14 +1082,18 @@ Signal error if there are problems creating it."
(let (dir buf)
(unless (file-directory-p (setq dir (file-name-directory
image-dired-db-file)))
- (make-directory dir t))
+ (with-file-modes #o700
+ (make-directory dir t)))
(with-current-buffer (setq buf (create-file-buffer
image-dired-db-file))
- (write-file image-dired-db-file))
+ (with-file-modes #o600
+ (write-file image-dired-db-file)))
(kill-buffer buf)
(file-exists-p image-dired-db-file))
(error "Could not create %s" image-dired-db-file)))
+(defvar image-dired-tag-history nil "Variable holding the tag history.")
+
(defun image-dired-write-tags (file-tags)
"Write file tags to database.
Write each file and tag in FILE-TAGS to the database.
@@ -1147,7 +1164,7 @@ FILE-TAGS is an alist in the following form:
;;;###autoload
(defun image-dired-tag-files (arg)
- "Tag marked file(s) in dired. With prefix ARG, tag file at point."
+ "Tag marked file(s) in Dired. With prefix ARG, tag file at point."
(interactive "P")
(let ((tag (completing-read
"Tags to add (separate tags with a semicolon): "
@@ -1197,6 +1214,9 @@ With prefix argument ARG, remove tag from file at point."
(image-dired-update-property
'tags (image-dired-list-tags (image-dired-original-file-name))))))
+
+;;; Thumbnail mode (cont.)
+
(defun image-dired-original-file-name ()
"Get original file name for thumbnail or display image at point."
(get-text-property (point) 'original-file-name))
@@ -1208,7 +1228,7 @@ With prefix argument ARG, remove tag from file at point."
(abbreviate-file-name f))))
(defun image-dired-associated-dired-buffer ()
- "Get associated dired buffer at point."
+ "Get associated Dired buffer at point."
(get-text-property (point) 'associated-dired-buffer))
(defun image-dired-get-buffer-window (buf)
@@ -1219,7 +1239,7 @@ With prefix argument ARG, remove tag from file at point."
nil t))
(defun image-dired-track-original-file ()
- "Track the original file in the associated dired buffer.
+ "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)
@@ -1234,16 +1254,16 @@ Interactive use only useful if `image-dired-track-movement' is nil."
(defun image-dired-toggle-movement-tracking ()
"Turn on and off `image-dired-track-movement'.
-Tracking of the movements between thumbnail and dired buffer so that
+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)
(setq image-dired-track-movement (not image-dired-track-movement))
- (message "Tracking %s" (if image-dired-track-movement "on" "off")))
+ (message "Movement tracking %s" (if image-dired-track-movement "on" "off")))
(defun image-dired-track-thumbnail ()
- "Track current dired file's thumb in `image-dired-thumbnail-buffer'.
+ "Track current Dired file's thumb in `image-dired-thumbnail-buffer'.
This is almost the same as what `image-dired-track-original-file' does,
but the other way around."
(let ((file (dired-get-filename))
@@ -1262,7 +1282,7 @@ but the other way around."
(when found
(if (setq window (image-dired-thumbnail-window))
(set-window-point window (point)))
- (image-dired-display-thumb-properties))))))
+ (image-dired-update-header-line))))))
(defun image-dired-dired-next-line (&optional arg)
"Call `dired-next-line', then track thumbnail.
@@ -1282,51 +1302,59 @@ With prefix argument, move ARG lines."
(if image-dired-track-movement
(image-dired-track-thumbnail)))
-(defun image-dired-forward-image (&optional arg)
+(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))))))
+
+(defun image-dired-forward-image (&optional arg wrap-around)
"Move to next image and display properties.
-Optional prefix ARG says how many images to move; default is one
-image."
+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.
+
+If optional argument WRAP-AROUND is non-nil, wrap around: if
+point is on the last image, move to the last one and vice versa."
(interactive "p")
- (let (pos (steps (or arg 1)))
- (dotimes (_ steps)
- (if (and (not (eobp))
+ (setq arg (or arg 1))
+ (let (pos)
+ (dotimes (_ (abs arg))
+ (if (and (not (if (> arg 0) (eobp) (bobp)))
(save-excursion
- (forward-char)
- (while (and (not (eobp))
+ (forward-char (if (> arg 0) 1 -1))
+ (while (and (not (if (> arg 0) (eobp) (bobp)))
(not (image-dired-image-at-point-p)))
- (forward-char))
+ (forward-char (if (> arg 0) 1 -1)))
(setq pos (point))
(image-dired-image-at-point-p)))
- (goto-char pos)
- (error "At last image"))))
+ (progn (goto-char pos)
+ (image-dired-update-header-line))
+ (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))))))
(when image-dired-track-movement
- (image-dired-track-original-file))
- (image-dired-display-thumb-properties))
+ (image-dired-track-original-file)))
(defun image-dired-backward-image (&optional arg)
"Move to previous image and display properties.
-Optional prefix ARG says how many images to move; default is one
-image."
+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")
- (let (pos (steps (or arg 1)))
- (dotimes (_ steps)
- (if (and (not (bobp))
- (save-excursion
- (backward-char)
- (while (and (not (bobp))
- (not (image-dired-image-at-point-p)))
- (backward-char))
- (setq pos (point))
- (image-dired-image-at-point-p)))
- (goto-char pos)
- (error "At first image"))))
- (when image-dired-track-movement
- (image-dired-track-original-file))
- (image-dired-display-thumb-properties))
+ (image-dired-forward-image (- (or arg 1))))
(defun image-dired-next-line ()
"Move to next line and display properties."
- (interactive)
+ (interactive nil image-dired-thumbnail-mode)
(let ((goal-column (current-column)))
(forward-line 1)
(move-to-column goal-column))
@@ -1335,12 +1363,12 @@ image."
(image-dired-backward-image))
(if image-dired-track-movement
(image-dired-track-original-file))
- (image-dired-display-thumb-properties))
+ (image-dired-update-header-line))
(defun image-dired-previous-line ()
"Move to previous line and display properties."
- (interactive)
+ (interactive nil image-dired-thumbnail-mode)
(let ((goal-column (current-column)))
(forward-line -1)
(move-to-column goal-column))
@@ -1352,11 +1380,33 @@ image."
(image-dired-backward-image))
(if image-dired-track-movement
(image-dired-track-original-file))
- (image-dired-display-thumb-properties))
+ (image-dired-update-header-line))
+
+(defun image-dired-beginning-of-buffer ()
+ "Move to the first image in the buffer and display properties."
+ (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))
+
+(defun image-dired-end-of-buffer ()
+ "Move to the last image in the buffer and display properties."
+ (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))
(defun image-dired-format-properties-string (buf file props comment)
"Format display properties.
-BUF is the associated dired buffer, FILE is the original image file
+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
comment."
(format-spec
@@ -1367,77 +1417,115 @@ comment."
(cons ?t (or props ""))
(cons ?c (or comment "")))))
-(defun image-dired-display-thumb-properties ()
- "Display thumbnail properties in the echo area."
- (if (not (eobp))
- (let ((file-name (file-name-nondirectory (image-dired-original-file-name)))
- (dired-buf (buffer-name (image-dired-associated-dired-buffer)))
- (props (mapconcat #'identity (get-text-property (point) 'tags) ", "))
- (comment (get-text-property (point) 'comment))
- (message-log-max nil))
- (if file-name
- (message "%s"
- (image-dired-format-properties-string
- dired-buf
- file-name
- props
- comment))))))
-
-(defun image-dired-dired-file-marked-p ()
- "Check whether file on current line is marked or not."
+(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)))
+ (dired-buf (buffer-name (image-dired-associated-dired-buffer)))
+ (props (mapconcat #'identity (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))))))
+
+(defun image-dired-dired-file-marked-p (&optional marker)
+ "In Dired, return t if file on current line is marked.
+If optional argument MARKER is non-nil, it is a character to look
+for. The default is to look for `dired-marker-char'."
+ (setq marker (or marker dired-marker-char))
(save-excursion
(beginning-of-line)
- (not (looking-at "^ .*$"))))
-
-(defun image-dired-modify-mark-on-thumb-original-file (command)
- "Modify mark in dired buffer.
-COMMAND is one of `mark' for marking file in dired, `unmark' for
-unmarking file in dired or `flag' for flagging file for delete in
-dired."
- (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
- (message "%s" file-name)
- (when (dired-goto-file file-name)
- (cond ((eq command 'mark) (dired-mark 1))
- ((eq command 'unmark) (dired-unmark 1))
- ((eq command 'toggle)
- (if (image-dired-dired-file-marked-p)
- (dired-unmark 1)
- (dired-mark 1)))
- ((eq command 'flag) (dired-flag-file-deletion 1)))
- (image-dired-thumb-update-marks))))))
+ (and (looking-at dired-re-mark)
+ (= (aref (match-string 0) 0) marker))))
+
+(defun image-dired-dired-file-flagged-p ()
+ "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--with-thumbnail-buffer (&rest body)
+ (declare (indent defun) (debug t))
+ `(if-let ((buf (get-buffer image-dired-thumbnail-buffer)))
+ (with-current-buffer buf
+ (if-let ((win (get-buffer-window buf)))
+ (with-selected-window win
+ ,@body)
+ ,@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'."
+ (declare (indent defun) (debug t))
+ `(image-dired--with-thumbnail-buffer
+ (image-dired--on-file-in-dired-buffer
+ ,@body)
+ ,(when maybe-next
+ '(if image-dired-marking-shows-next
+ (image-dired-display-next-thumbnail-original)
+ (image-dired-next-line)))))
(defun image-dired-mark-thumb-original-file ()
- "Mark original image file in associated dired buffer."
- (interactive)
- (image-dired-modify-mark-on-thumb-original-file 'mark)
- (image-dired-forward-image))
+ "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
+ (dired-mark 1)))
(defun image-dired-unmark-thumb-original-file ()
- "Unmark original image file in associated dired buffer."
- (interactive)
- (image-dired-modify-mark-on-thumb-original-file 'unmark)
- (image-dired-forward-image))
+ "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
+ (dired-unmark 1)))
(defun image-dired-flag-thumb-original-file ()
- "Flag original image file for deletion in associated dired buffer."
- (interactive)
- (image-dired-modify-mark-on-thumb-original-file 'flag)
- (image-dired-forward-image))
+ "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
+ (dired-flag-file-deletion 1)))
(defun image-dired-toggle-mark-thumb-original-file ()
- "Toggle mark on original image file in associated dired buffer."
- (interactive)
- (image-dired-modify-mark-on-thumb-original-file 'toggle))
+ "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
+ (dired-unmark-all-marks))
+ (image-dired--with-thumbnail-buffer
+ (image-dired-thumb-update-marks)))
(defun image-dired-jump-original-dired-buffer ()
- "Jump to the dired buffer associated with the current image file.
+ "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)
+ (interactive nil image-dired-thumbnail-mode)
(let ((buf (image-dired-associated-dired-buffer))
window frame)
(setq window (image-dired-get-buffer-window buf))
@@ -1464,240 +1552,217 @@ You probably want to use this together with
(defvar image-dired-thumbnail-mode-line-up-map
(let ((map (make-sparse-keymap)))
;; map it to "g" so that the user can press it more quickly
- (define-key map "g" 'image-dired-line-up-dynamic)
+ (define-key map "g" #'image-dired-line-up-dynamic)
;; "f" for "fixed" number of thumbs per row
- (define-key map "f" 'image-dired-line-up)
+ (define-key map "f" #'image-dired-line-up)
;; "i" for "interactive"
- (define-key map "i" 'image-dired-line-up-interactive)
+ (define-key map "i" #'image-dired-line-up-interactive)
map)
"Keymap for line-up commands in `image-dired-thumbnail-mode'.")
(defvar image-dired-thumbnail-mode-tag-map
(let ((map (make-sparse-keymap)))
;; map it to "t" so that the user can press it more quickly
- (define-key map "t" 'image-dired-tag-thumbnail)
+ (define-key map "t" #'image-dired-tag-thumbnail)
;; "r" for "remove"
- (define-key map "r" 'image-dired-tag-thumbnail-remove)
+ (define-key map "r" #'image-dired-tag-thumbnail-remove)
map)
"Keymap for tag commands in `image-dired-thumbnail-mode'.")
(defvar image-dired-thumbnail-mode-map
(let ((map (make-sparse-keymap)))
- (define-key map [right] 'image-dired-forward-image)
- (define-key map [left] 'image-dired-backward-image)
- (define-key map [up] 'image-dired-previous-line)
- (define-key map [down] 'image-dired-next-line)
- (define-key map "\C-f" 'image-dired-forward-image)
- (define-key map "\C-b" 'image-dired-backward-image)
- (define-key map "\C-p" 'image-dired-previous-line)
- (define-key map "\C-n" 'image-dired-next-line)
-
- (define-key map "d" 'image-dired-flag-thumb-original-file)
- (define-key map [delete] 'image-dired-flag-thumb-original-file)
- (define-key map "m" 'image-dired-mark-thumb-original-file)
- (define-key map "u" 'image-dired-unmark-thumb-original-file)
- (define-key map "." 'image-dired-track-original-file)
- (define-key map [tab] 'image-dired-jump-original-dired-buffer)
+ (define-key map [right] #'image-dired-forward-image)
+ (define-key map [left] #'image-dired-backward-image)
+ (define-key map [up] #'image-dired-previous-line)
+ (define-key map [down] #'image-dired-next-line)
+ (define-key map "\C-f" #'image-dired-forward-image)
+ (define-key map "\C-b" #'image-dired-backward-image)
+ (define-key map "\C-p" #'image-dired-previous-line)
+ (define-key map "\C-n" #'image-dired-next-line)
+
+ (define-key map "<" #'image-dired-beginning-of-buffer)
+ (define-key map ">" #'image-dired-end-of-buffer)
+ (define-key map (kbd "M-<") #'image-dired-beginning-of-buffer)
+ (define-key map (kbd "M->") #'image-dired-end-of-buffer)
+
+ (define-key map "d" #'image-dired-flag-thumb-original-file)
+ (define-key map [delete] #'image-dired-flag-thumb-original-file)
+ (define-key map "m" #'image-dired-mark-thumb-original-file)
+ (define-key map "u" #'image-dired-unmark-thumb-original-file)
+ (define-key map "U" #'image-dired-unmark-all-marks)
+ (define-key map "." #'image-dired-track-original-file)
+ (define-key map [tab] #'image-dired-jump-original-dired-buffer)
;; add line-up map
(define-key map "g" image-dired-thumbnail-mode-line-up-map)
;; add tag map
(define-key map "t" image-dired-thumbnail-mode-tag-map)
- (define-key map "\C-m" 'image-dired-display-thumbnail-original-image)
- (define-key map [C-return] 'image-dired-thumbnail-display-external)
+ (define-key map "\C-m" #'image-dired-display-thumbnail-original-image)
+ (define-key map [C-return] #'image-dired-thumbnail-display-external)
- (define-key map "l" 'image-dired-rotate-thumbnail-left)
- (define-key map "r" 'image-dired-rotate-thumbnail-right)
- (define-key map "L" 'image-dired-rotate-original-left)
- (define-key map "R" 'image-dired-rotate-original-right)
+ (define-key map "L" #'image-dired-rotate-original-left)
+ (define-key map "R" #'image-dired-rotate-original-right)
- (define-key map "D" 'image-dired-thumbnail-set-image-description)
- (define-key map "\C-d" 'image-dired-delete-char)
- (define-key map " " 'image-dired-display-next-thumbnail-original)
- (define-key map (kbd "DEL") 'image-dired-display-previous-thumbnail-original)
- (define-key map "c" 'image-dired-comment-thumbnail)
+ (define-key map "D" #'image-dired-thumbnail-set-image-description)
+ (define-key map "S" #'image-dired-slideshow-start)
+ (define-key map "\C-d" #'image-dired-delete-char)
+ (define-key map " " #'image-dired-display-next-thumbnail-original)
+ (define-key map (kbd "DEL") #'image-dired-display-previous-thumbnail-original)
+ (define-key map "c" #'image-dired-comment-thumbnail)
;; Mouse
- (define-key map [mouse-2] 'image-dired-mouse-display-image)
- (define-key map [mouse-1] 'image-dired-mouse-select-thumbnail)
+ (define-key map [mouse-2] #'image-dired-mouse-display-image)
+ (define-key map [mouse-1] #'image-dired-mouse-select-thumbnail)
+ (define-key map [mouse-3] #'image-dired-mouse-select-thumbnail)
+ (define-key map [down-mouse-1] #'image-dired-mouse-select-thumbnail)
+ (define-key map [down-mouse-2] #'image-dired-mouse-select-thumbnail)
+ (define-key map [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.
- (define-key map [C-down-mouse-1] 'undefined)
- (define-key map [C-mouse-1] 'image-dired-mouse-toggle-mark)
-
- ;; Menu
- (easy-menu-define nil map
- "Menu for `image-dired-thumbnail-mode'."
- '("Image-Dired"
- ["Quit" quit-window]
- ["Delete thumbnail from buffer" image-dired-delete-char]
- ["Delete marked images" image-dired-delete-marked]
- ["Remove tag from current or marked thumbnails"
- image-dired-tag-thumbnail-remove]
- ["Tag current or marked thumbnails" image-dired-tag-thumbnail]
- ["Comment thumbnail" image-dired-comment-thumbnail]
- ["Refresh thumb" image-dired-refresh-thumb]
- ["Dynamic line up" image-dired-line-up-dynamic]
- ["Line up thumbnails" image-dired-line-up]
-
- ["Rotate thumbnail left" image-dired-rotate-thumbnail-left]
- ["Rotate thumbnail right" image-dired-rotate-thumbnail-right]
- ["Rotate original left" image-dired-rotate-original-left]
- ["Rotate original right" image-dired-rotate-original-right]
-
- ["Toggle movement tracking on/off" image-dired-toggle-movement-tracking]
-
- ["Jump to dired buffer" image-dired-jump-original-dired-buffer]
- ["Track original" image-dired-track-original-file]
-
- ["Flag original for deletion" image-dired-flag-thumb-original-file]
- ["Unmark original" image-dired-unmark-thumb-original-file]
- ["Mark original" image-dired-mark-thumb-original-file]
-
- ["Display in external viewer" image-dired-thumbnail-display-external]
- ["Display image" image-dired-display-thumbnail-original-image]))
+ (define-key map [C-down-mouse-1] #'undefined)
+ (define-key map [C-mouse-1] #'image-dired-mouse-toggle-mark)
map)
"Keymap for `image-dired-thumbnail-mode'.")
+(easy-menu-define image-dired-thumbnail-mode-menu image-dired-thumbnail-mode-map
+ "Menu for `image-dired-thumbnail-mode'."
+ '("Image-Dired"
+ ["Display image" image-dired-display-thumbnail-original-image]
+ ["Display in external viewer" image-dired-thumbnail-display-external]
+ ["Jump to Dired buffer" image-dired-jump-original-dired-buffer]
+ "---"
+ ["Mark image" image-dired-mark-thumb-original-file]
+ ["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]
+ "---"
+ ["Rotate original right" image-dired-rotate-original-right]
+ ["Rotate original left" image-dired-rotate-original-left]
+ "---"
+ ["Comment thumbnail" image-dired-comment-thumbnail]
+ ["Tag current or marked thumbnails" image-dired-tag-thumbnail]
+ ["Remove tag from current or marked thumbnails"
+ image-dired-tag-thumbnail-remove]
+ ["Start slideshow" image-dired-slideshow-start]
+ "---"
+ ("View Options"
+ ["Toggle movement tracking" image-dired-toggle-movement-tracking
+ :style toggle
+ :selected image-dired-track-movement]
+ "---"
+ ["Line up thumbnails" image-dired-line-up]
+ ["Dynamic line up" image-dired-line-up-dynamic]
+ ["Refresh thumb" image-dired-refresh-thumb])
+ ["Quit" quit-window]))
+
(defvar image-dired-display-image-mode-map
(let ((map (make-sparse-keymap)))
- ;; `image-mode-map' has bindings that do not make sense in image-dired
- ;; (set-keymap-parent map image-mode-map)
- (define-key map "f" 'image-dired-display-current-image-full)
- (define-key map "s" 'image-dired-display-current-image-sized)
- (define-key map "g" nil)
-
- ;; Useful bindings from `image-mode-map'
- (define-key map [remap forward-char] 'image-forward-hscroll)
- (define-key map [remap backward-char] 'image-backward-hscroll)
- (define-key map [remap right-char] 'image-forward-hscroll)
- (define-key map [remap left-char] 'image-backward-hscroll)
- (define-key map [remap previous-line] 'image-previous-line)
- (define-key map [remap next-line] 'image-next-line)
- (define-key map [remap scroll-up] 'image-scroll-up)
- (define-key map [remap scroll-down] 'image-scroll-down)
- (define-key map [remap scroll-up-command] 'image-scroll-up)
- (define-key map [remap scroll-down-command] 'image-scroll-down)
- (define-key map [remap scroll-left] 'image-scroll-left)
- (define-key map [remap scroll-right] 'image-scroll-right)
- (define-key map [remap move-beginning-of-line] 'image-bol)
- (define-key map [remap move-end-of-line] 'image-eol)
- (define-key map [remap beginning-of-buffer] 'image-bob)
- (define-key map [remap end-of-buffer] 'image-eob)
-
- (easy-menu-define nil map
- "Menu for `image-dired-display-image-mode-map'."
- '("Image-Dired"
- ["Quit" quit-window]
- ["Display original, sized to fit" image-dired-display-current-image-sized]
- ["Display original, full size" image-dired-display-current-image-full]))
+ (define-key map "S" #'image-dired-slideshow-start)
+ (define-key map (kbd "SPC") #'image-dired-display-next-thumbnail-original)
+ (define-key map (kbd "DEL") #'image-dired-display-previous-thumbnail-original)
+ (define-key map "n" #'image-dired-display-next-thumbnail-original)
+ (define-key map "p" #'image-dired-display-previous-thumbnail-original)
+ (define-key map "m" #'image-dired-mark-thumb-original-file)
+ (define-key map "d" #'image-dired-flag-thumb-original-file)
+ (define-key map "u" #'image-dired-unmark-thumb-original-file)
+ (define-key map "U" #'image-dired-unmark-all-marks)
+ ;; Disable keybindings from `image-mode-map' that doesn't make sense here.
+ (define-key map "o" nil) ; image-save
map)
"Keymap for `image-dired-display-image-mode'.")
-(defun image-dired-display-current-image-full ()
- "Display current image in full size."
- (interactive)
- (let ((file (image-dired-original-file-name)))
- (if file
- (progn
- (image-dired-display-image file t)
- (message "Full size image displayed"))
- (error "No original file name at point"))))
-
-(defun image-dired-display-current-image-sized ()
- "Display current image in sized to fit window dimensions."
- (interactive)
- (let ((file (image-dired-original-file-name)))
- (if file
- (progn
- (image-dired-display-image file)
- (message "Fitted image displayed"))
- (error "No original file name at point"))))
-
(define-derived-mode image-dired-thumbnail-mode
special-mode "image-dired-thumbnail"
- "Browse and manipulate thumbnail images using dired.
+ "Browse and manipulate thumbnail images using Dired.
Use `image-dired-minor-mode' to get a nice setup."
+ :interactive nil
(buffer-disable-undo)
- (add-hook 'file-name-at-point-functions 'image-dired-file-name-at-point nil t))
+ (add-hook 'file-name-at-point-functions 'image-dired-file-name-at-point nil t)
+ (setq-local window-resize-pixelwise t)
+ (setq-local bookmark-make-record-function #'image-dired-bookmark-make-record)
+ ;; Use approximately as much vertical spacing as horizontal.
+ (setq-local line-spacing (frame-char-width)))
+
+
+;;; Display image mode
(define-derived-mode image-dired-display-image-mode
- special-mode "image-dired-image-display"
+ image-mode "image-dired-image-display"
"Mode for displaying and manipulating original image.
Resized or in full-size."
- (buffer-disable-undo)
- (image-mode-setup-winprops)
- (setq cursor-type nil)
- (add-hook 'file-name-at-point-functions 'image-dired-file-name-at-point nil t))
+ :interactive nil
+ (add-hook 'file-name-at-point-functions #'image-dired-file-name-at-point nil t))
(defvar image-dired-minor-mode-map
(let ((map (make-sparse-keymap)))
;; (set-keymap-parent map dired-mode-map)
;; Hijack previous and next line movement. Let C-p and C-b be
;; though...
- (define-key map "p" 'image-dired-dired-previous-line)
- (define-key map "n" 'image-dired-dired-next-line)
- (define-key map [up] 'image-dired-dired-previous-line)
- (define-key map [down] 'image-dired-dired-next-line)
-
- (define-key map (kbd "C-S-n") 'image-dired-next-line-and-display)
- (define-key map (kbd "C-S-p") 'image-dired-previous-line-and-display)
- (define-key map (kbd "C-S-m") 'image-dired-mark-and-display-next)
-
- (define-key map "\C-td" 'image-dired-display-thumbs)
- (define-key map [tab] 'image-dired-jump-thumbnail-buffer)
- (define-key map "\C-ti" 'image-dired-dired-display-image)
- (define-key map "\C-tx" 'image-dired-dired-display-external)
- (define-key map "\C-ta" 'image-dired-display-thumbs-append)
- (define-key map "\C-t." 'image-dired-display-thumb)
- (define-key map "\C-tc" 'image-dired-dired-comment-files)
- (define-key map "\C-tf" 'image-dired-mark-tagged-files)
-
- ;; Menu for dired
- (easy-menu-define nil map
- "Menu for `image-dired-minor-mode'."
- '("Image-dired"
- ["Copy with EXIF file name" image-dired-copy-with-exif-file-name]
- ["Comment files" image-dired-dired-comment-files]
- ["Mark tagged files" image-dired-mark-tagged-files]
- ["Jump to thumbnail buffer" image-dired-jump-thumbnail-buffer]
-
- ["Toggle movement tracking" image-dired-toggle-movement-tracking]
- ["Toggle append browsing" image-dired-toggle-append-browsing]
- ["Toggle display properties" image-dired-toggle-dired-display-properties]
-
- ["Display in external viewer" image-dired-dired-display-external]
- ["Display image" image-dired-dired-display-image]
- ["Display this thumbnail" image-dired-display-thumb]
- ["Display thumbnails append" image-dired-display-thumbs-append]
-
- ["Create thumbnails for marked files" image-dired-create-thumbs]
-
- ["Mark and display next" image-dired-mark-and-display-next]
- ["Display thumb for previous file" image-dired-previous-line-and-display]
- ["Display thumb for next file" image-dired-next-line-and-display]))
+ (define-key map "p" #'image-dired-dired-previous-line)
+ (define-key map "n" #'image-dired-dired-next-line)
+ (define-key map [up] #'image-dired-dired-previous-line)
+ (define-key map [down] #'image-dired-dired-next-line)
+
+ (define-key map (kbd "C-S-n") #'image-dired-next-line-and-display)
+ (define-key map (kbd "C-S-p") #'image-dired-previous-line-and-display)
+ (define-key map (kbd "C-S-m") #'image-dired-mark-and-display-next)
+
+ (define-key map "\C-td" #'image-dired-display-thumbs)
+ (define-key map [tab] #'image-dired-jump-thumbnail-buffer)
+ (define-key map "\C-ti" #'image-dired-dired-display-image)
+ (define-key map "\C-tx" #'image-dired-dired-display-external)
+ (define-key map "\C-ta" #'image-dired-display-thumbs-append)
+ (define-key map "\C-t." #'image-dired-display-thumb)
+ (define-key map "\C-tc" #'image-dired-dired-comment-files)
+ (define-key map "\C-tf" #'image-dired-mark-tagged-files)
map)
"Keymap for `image-dired-minor-mode'.")
+(easy-menu-define image-dired-minor-mode-menu image-dired-minor-mode-map
+ "Menu for `image-dired-minor-mode'."
+ '("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]
+ "---"
+ ["Create thumbnails for marked files" image-dired-create-thumbs]
+ "---"
+ ["Display thumbnails append" image-dired-display-thumbs-append]
+ ["Display this thumbnail" image-dired-display-thumb]
+ ["Display image" image-dired-dired-display-image]
+ ["Display in external viewer" image-dired-dired-display-external]
+ "---"
+ ["Toggle display properties" image-dired-toggle-dired-display-properties
+ :style toggle
+ :selected image-dired-dired-disp-props]
+ ["Toggle append browsing" image-dired-toggle-append-browsing
+ :style toggle
+ :selected image-dired-append-when-browsing]
+ ["Toggle movement tracking" image-dired-toggle-movement-tracking
+ :style toggle
+ :selected image-dired-track-movement]
+ "---"
+ ["Jump to thumbnail buffer" image-dired-jump-thumbnail-buffer]
+ ["Mark tagged files" image-dired-mark-tagged-files]
+ ["Comment files" image-dired-dired-comment-files]
+ ["Copy with EXIF file name" image-dired-copy-with-exif-file-name]))
+
;;;###autoload
(define-minor-mode image-dired-minor-mode
- "Setup easy-to-use keybindings for the commands to be used in dired 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-x-line'."
+`image-dired-dired-next-line' and `image-dired-dired-previous-line'."
:keymap image-dired-minor-mode-map)
-;;;###autoload
-(define-obsolete-function-alias 'image-dired-setup-dired-keybindings 'image-dired-minor-mode
- "26.1")
-
(declare-function clear-image-cache "image.c" (&optional filter))
(defun image-dired-create-thumbs (&optional arg)
- "Create thumbnail images for all marked files in dired.
+ "Create thumbnail images for all marked files in Dired.
With prefix argument ARG, create thumbnails even if they already exist
\(i.e. use this to refresh your thumbnails)."
(interactive "P")
@@ -1713,46 +1778,69 @@ With prefix argument ARG, create thumbnails even if they already exist
arg)
(image-dired-create-thumb curr-file thumb-name)))))
-(defvar image-dired-slideshow-timer nil
- "Slideshow timer.")
+
+;;; Slideshow
-(defvar image-dired-slideshow-count 0
- "Keeping track on number of images in slideshow.")
+(defcustom image-dired-slideshow-delay 5.0
+ "Seconds to wait before showing the next image in a slideshow.
+This is used by `image-dired-slideshow-start'."
+ :type 'float
+ :version "29.1")
-(defvar image-dired-slideshow-times 0
- "Number of pictures to display in slideshow.")
+(define-obsolete-variable-alias 'image-dired-slideshow-timer
+ 'image-dired--slideshow-timer "29.1")
+(defvar image-dired--slideshow-timer nil
+ "Slideshow timer.")
+
+(defvar image-dired--slideshow-initial nil)
(defun image-dired-slideshow-step ()
- "Step to next file, if `image-dired-slideshow-times' has not been reached."
- (if (< image-dired-slideshow-count image-dired-slideshow-times)
- (progn
- (message "%s" (1+ image-dired-slideshow-count))
- (setq image-dired-slideshow-count (1+ image-dired-slideshow-count))
- (image-dired-next-line-and-display))
+ "Step to 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)))
-(defun image-dired-slideshow-start ()
- "Start slideshow.
-Ask user for number of images to show and the delay in between."
- (interactive)
- (setq image-dired-slideshow-count 0)
- (setq image-dired-slideshow-times (string-to-number (read-string "How many: ")))
- (let ((repeat (string-to-number
- (read-string
- "Delay, in seconds. Decimals are accepted : " "1"))))
- (setq image-dired-slideshow-timer
+(defun image-dired-slideshow-start (&optional arg)
+ "Start a slideshow, waiting `image-dired-slideshow-delay' 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 repeat
- 'image-dired-slideshow-step))))
+ 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."
- (interactive)
- (cancel-timer image-dired-slideshow-timer))
+ ;; 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))
+
+
+;;; Thumbnail mode (cont. 3)
(defun image-dired-delete-char ()
"Remove current thumbnail from thumbnail buffer and line up."
- (interactive)
+ (interactive nil image-dired-thumbnail-mode)
(let ((inhibit-read-only t))
(delete-char 1)
(when (= (following-char) ?\s)
@@ -1785,18 +1873,26 @@ See also `image-dired-line-up-dynamic'."
(not (eobp)))
(delete-char 1)))
(goto-char (point-min))
- (let ((count 0))
+ (let ((seen 0)
+ (thumb-prev-pos 0)
+ (thumb-width-chars
+ (ceiling (/ (+ (* 2 image-dired-thumb-relief)
+ (* 2 image-dired-thumb-margin)
+ (image-dired-thumb-size 'width))
+ (float (frame-char-width))))))
(while (not (eobp))
(forward-char)
(if (= image-dired-thumbs-per-row 1)
(insert "\n")
- (insert " ")
- (setq count (1+ count))
- (when (and (= count (- image-dired-thumbs-per-row 1))
+ (cl-incf thumb-prev-pos thumb-width-chars)
+ (insert (propertize " " 'display `(space :align-to ,thumb-prev-pos)))
+ (cl-incf seen)
+ (when (and (= seen (- image-dired-thumbs-per-row 1))
(not (eobp)))
(forward-char)
(insert "\n")
- (setq count 0)))))
+ (setq seen 0)
+ (setq thumb-prev-pos 0)))))
(goto-char (point-min))))
(defun image-dired-line-up-dynamic ()
@@ -1846,11 +1942,6 @@ Ask user how many thumbnails should be displayed per row."
"Calculate WINDOW width in pixels."
(* (window-width window) (frame-char-width)))
-(defun image-dired-window-height-pixels (window)
- "Calculate WINDOW height in pixels."
- ;; Note: The mode-line consumes one line
- (* (- (window-height window) 1) (frame-char-height)))
-
(defun image-dired-display-window ()
"Return window where `image-dired-display-image-buffer' is visible."
(get-window-with-predicate
@@ -1866,7 +1957,7 @@ Ask user how many thumbnails should be displayed per row."
nil t))
(defun image-dired-associated-dired-buffer-window ()
- "Return window where associated dired buffer is visible."
+ "Return window where associated Dired buffer is visible."
(let (buf)
(if (image-dired-image-at-point-p)
(progn
@@ -1876,59 +1967,24 @@ Ask user how many thumbnails should be displayed per row."
(equal (window-buffer window) buf))))
(error "No thumbnail image at point"))))
-(defun image-dired-display-window-width (window)
- "Return width, in pixels, of WINDOW."
- (- (image-dired-window-width-pixels window)
- image-dired-display-window-width-correction))
-
-(defun image-dired-display-window-height (window)
- "Return height, in pixels, of WINDOW."
- (- (image-dired-window-height-pixels window)
- image-dired-display-window-height-correction))
-
-(defun image-dired-display-image (file &optional original-size)
+(defun image-dired-display-image (file &optional _ignored)
"Display image FILE in image buffer.
-Use this when you want to display the image, semi sized, in a new
-window. The image is sized to fit the display window (using a
-temporary file, don't worry). Because of this, it will not be as
-quick as opening it directly, but on most modern systems it
-should feel snappy enough.
-
-If optional argument ORIGINAL-SIZE is non-nil, display image in its
-original size."
- (image-dired--check-executable-exists
- 'image-dired-cmd-create-temp-image-program)
- (let ((new-file (expand-file-name image-dired-temp-image-file))
- (window (image-dired-display-window))
- (image-type 'jpeg))
- (setq file (expand-file-name file))
- (if (not original-size)
- (let* ((spec
- (list
- (cons ?p image-dired-cmd-create-temp-image-program)
- (cons ?w (image-dired-display-window-width window))
- (cons ?h (image-dired-display-window-height window))
- (cons ?f file)
- (cons ?t new-file)))
- (ret
- (apply #'call-process
- image-dired-cmd-create-temp-image-program nil nil nil
- (mapcar
- (lambda (arg) (format-spec arg spec))
- image-dired-cmd-create-temp-image-options))))
- (when (not (zerop ret))
- (error "Could not resize image")))
- (setq image-type (image-type-from-file-name file))
- (copy-file file new-file t))
- (with-current-buffer (image-dired-create-display-image-buffer)
- (let ((inhibit-read-only t))
- (erase-buffer)
- (clear-image-cache)
- (image-dired-insert-image image-dired-temp-image-file image-type 0 0)
- (goto-char (point-min))
- (set-window-vscroll window 0)
- (set-window-hscroll window 0)
- (image-dired-update-property 'original-file-name file)))))
+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'."
+ (declare (advertised-calling-convention (file) "29.1"))
+ (setq file (expand-file-name file))
+ (when (not (file-exists-p file))
+ (error "No such file: %s" file))
+ (let ((buf (get-buffer image-dired-display-image-buffer))
+ (cur-win (selected-window)))
+ (when buf
+ (kill-buffer buf))
+ (when-let ((buf (find-file-other-window file)))
+ (display-buffer buf)
+ (rename-buffer image-dired-display-image-buffer)
+ (image-dired-display-image-mode)
+ (select-window cur-win))))
(defun image-dired-display-thumbnail-original-image (&optional arg)
"Display current thumbnail's original image in display buffer.
@@ -1942,8 +1998,6 @@ With prefix argument ARG, display image in its original size."
(message "No thumbnail at point")
(if (not file)
(message "No original file name found")
- (image-dired-create-display-image-buffer)
- (display-buffer image-dired-display-image-buffer)
(image-dired-display-image file arg))))))
@@ -1953,41 +2007,15 @@ With prefix argument ARG, display image in its original size."
See documentation for `image-dired-display-image' for more information.
With prefix argument ARG, display image in its original size."
(interactive "P")
- (image-dired-create-display-image-buffer)
- (display-buffer image-dired-display-image-buffer)
(image-dired-display-image (dired-get-filename) arg))
(defun image-dired-image-at-point-p ()
- "Return true if there is an image-dired thumbnail at point."
+ "Return non-nil if there is an `image-dired' thumbnail at point."
(get-text-property (point) 'image-dired-thumbnail))
-(defun image-dired-rotate-thumbnail (degrees)
- "Rotate thumbnail DEGREES degrees."
- (image-dired--check-executable-exists
- 'image-dired-cmd-rotate-thumbnail-program)
- (if (not (image-dired-image-at-point-p))
- (message "No thumbnail at point")
- (let* ((file (image-dired-thumb-name (image-dired-original-file-name)))
- (thumb (expand-file-name file))
- (spec (list (cons ?d degrees) (cons ?t thumb))))
- (apply #'call-process image-dired-cmd-rotate-thumbnail-program nil nil nil
- (mapcar (lambda (arg) (format-spec arg spec))
- image-dired-cmd-rotate-thumbnail-options))
- (clear-image-cache thumb))))
-
-(defun image-dired-rotate-thumbnail-left ()
- "Rotate thumbnail left (counter clockwise) 90 degrees."
- (interactive)
- (image-dired-rotate-thumbnail "270"))
-
-(defun image-dired-rotate-thumbnail-right ()
- "Rotate thumbnail counter right (clockwise) 90 degrees."
- (interactive)
- (image-dired-rotate-thumbnail "90"))
-
(defun image-dired-refresh-thumb ()
"Force creation of new image for current thumbnail."
- (interactive)
+ (interactive nil image-dired-thumbnail-mode)
(let* ((file (image-dired-original-file-name))
(thumb (expand-file-name (image-dired-thumb-name file))))
(clear-image-cache (expand-file-name thumb))
@@ -2006,7 +2034,7 @@ With prefix argument ARG, display image in its original size."
(cons ?o (expand-file-name file))
(cons ?t image-dired-temp-rotate-image-file))))
(unless (eq 'jpeg (image-type file))
- (error "Only JPEG images can be rotated!"))
+ (user-error "Only JPEG images can be rotated"))
(if (not (= 0 (apply #'call-process image-dired-cmd-rotate-original-program
nil nil nil
(mapcar (lambda (arg) (format-spec arg spec))
@@ -2040,6 +2068,9 @@ overwritten. This confirmation can be turned off using
(interactive)
(image-dired-rotate-original "90"))
+
+;;; EXIF support
+
(defun image-dired-get-exif-file-name (file)
"Use the image's EXIF information to return a unique file name.
The file name should be unique as long as you do not take more than
@@ -2054,8 +2085,8 @@ YYYY_MM_DD_HH_MM_DD_ORIG_FILE_NAME.jpg. Used from
"%Y:%m:%d %H:%M:%S"
(file-attribute-modification-time
(file-attributes (expand-file-name file)))))
- (setq data (image-dired-get-exif-data (expand-file-name file)
- "DateTimeOriginal")))
+ (setq data (exif-field 'date-time (exif-parse-file
+ (expand-file-name file)))))
(while (string-match "[ :]" data)
(setq data (replace-match "_" nil nil data)))
(format "%s%s%s" data
@@ -2072,7 +2103,7 @@ default value at the prompt."
(if (not (image-dired-image-at-point-p))
(message "No thumbnail at point")
(let* ((file (image-dired-original-file-name))
- (old-value (image-dired-get-exif-data file "ImageDescription")))
+ (old-value (or (exif-field 'description (exif-parse-file file)) "")))
(if (eq 0
(image-dired-set-exif-data file "ImageDescription"
(read-string "Value of ImageDescription: "
@@ -2093,33 +2124,9 @@ default value at the prompt."
(mapcar (lambda (arg) (format-spec arg spec))
image-dired-cmd-write-exif-data-options))))
-(defun image-dired-get-exif-data (file tag-name)
- "From FILE, return EXIF tag TAG-NAME."
- (image-dired--check-executable-exists
- 'image-dired-cmd-read-exif-data-program)
- (let ((buf (get-buffer-create "*image-dired-get-exif-data*"))
- (spec (list (cons ?f file) (cons ?t tag-name)))
- tag-value)
- (with-current-buffer buf
- (delete-region (point-min) (point-max))
- (if (not (eq (apply #'call-process image-dired-cmd-read-exif-data-program
- nil t nil
- (mapcar
- (lambda (arg) (format-spec arg spec))
- image-dired-cmd-read-exif-data-options))
- 0))
- (error "Could not get EXIF tag")
- (goto-char (point-min))
- ;; Clean buffer from newlines and carriage returns before
- ;; getting final info
- (while (search-forward-regexp "[\n\r]" nil t)
- (replace-match "" nil t))
- (setq tag-value (buffer-substring (point-min) (point-max)))))
- tag-value))
-
(defun image-dired-copy-with-exif-file-name ()
"Copy file with unique name to main image directory.
-Copy current or all marked files in dired to a new file in your
+Copy current or all marked files in Dired to a new file in your
main image directory, using a file name generated by
`image-dired-get-exif-file-name'. A typical usage for this if when
copying images from a digital camera into the image directory.
@@ -2144,17 +2151,24 @@ function. The result is a couple of new files in
(copy-file curr-file new-name))
files)))
-(defun image-dired-display-next-thumbnail-original ()
- "In thumbnail buffer, move to next thumbnail and display the image."
- (interactive)
- (image-dired-forward-image)
- (image-dired-display-thumbnail-original-image))
+;;; Thumbnail mode (cont.)
-(defun image-dired-display-previous-thumbnail-original ()
- "Move to previous thumbnail and display image."
- (interactive)
- (image-dired-backward-image)
- (image-dired-display-thumbnail-original-image))
+(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-write-comments (file-comments)
"Write file comments to database.
@@ -2203,7 +2217,7 @@ FILE-COMMENTS is an alist on the following form:
;;;###autoload
(defun image-dired-dired-comment-files ()
- "Add comment to current or marked files in dired."
+ "Add comment to current or marked files in Dired."
(interactive)
(let ((comment (image-dired-read-comment)))
(image-dired-write-comments
@@ -2219,7 +2233,7 @@ FILE-COMMENTS is an alist on the following form:
(comment (image-dired-read-comment file)))
(image-dired-write-comments (list (cons file comment)))
(image-dired-update-property 'comment comment))
- (image-dired-display-thumb-properties))
+ (image-dired-update-header-line))
(defun image-dired-read-comment (&optional file)
"Read comment for an image.
@@ -2255,7 +2269,7 @@ 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
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."
+matching tag will be marked in the Dired buffer."
(interactive)
(image-dired-sane-db-file)
(let ((tag (read-string "Mark tagged files (regexp): "))
@@ -2282,50 +2296,69 @@ matching tag will be marked in the dired buffer."
(dired-mark 1))))
(message "%d files with matching tag marked." hits)))
+
+
+;;; Mouse support
+
(defun image-dired-mouse-display-image (event)
"Use mouse EVENT, call `image-dired-display-image' to display image.
-Track this in associated dired buffer if `image-dired-track-movement' is
+Track this in associated Dired buffer if `image-dired-track-movement' is
non-nil."
(interactive "e")
(mouse-set-point event)
(goto-char (posn-point (event-end event)))
+ (unless (image-at-point-p)
+ (image-dired-backward-image))
(let ((file (image-dired-original-file-name)))
(when file
(if image-dired-track-movement
(image-dired-track-original-file))
- (image-dired-create-display-image-buffer)
- (display-buffer image-dired-display-image-buffer)
(image-dired-display-image file))))
(defun image-dired-mouse-select-thumbnail (event)
"Use mouse EVENT to select thumbnail image.
-Track this in associated dired buffer if `image-dired-track-movement' is
+Track this in associated Dired buffer if `image-dired-track-movement' is
non-nil."
(interactive "e")
(mouse-set-point event)
(goto-char (posn-point (event-end event)))
+ (unless (image-at-point-p)
+ (image-dired-backward-image))
(if image-dired-track-movement
(image-dired-track-original-file))
- (image-dired-display-thumb-properties))
+ (image-dired-update-header-line))
+
-(defun image-dired-thumb-file-marked-p ()
- "Check if file is marked in associated dired buffer."
+
+;;; Dired marks and tags
+
+(defun image-dired-thumb-file-marked-p (&optional flagged)
+ "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
- (when (dired-goto-file file-name)
- (image-dired-dired-file-marked-p))))))
+ (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."
(interactive)
- (with-current-buffer (image-dired-associated-dired-buffer)
- (dired-do-delete))
(image-dired--with-marked
(image-dired-delete-char)
(backward-char))
- (image-dired--line-up-with-method))
+ (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."
@@ -2336,26 +2369,29 @@ non-nil."
(let ((inhibit-read-only t))
(while (not (eobp))
(with-silent-modifications
- (if (image-dired-thumb-file-marked-p)
- (add-face-text-property (point) (1+ (point))
- 'image-dired-thumb-mark)
- (remove-text-properties (point) (1+ (point))
- '(face image-dired-thumb-mark))))
+ (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)))))))
(defun image-dired-mouse-toggle-mark-1 ()
- "Toggle dired mark for current thumbnail.
-Track this in associated dired buffer if `image-dired-track-movement' is
-non-nil."
+ "Toggle Dired mark for current thumbnail.
+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))
(defun image-dired-mouse-toggle-mark (event)
- "Use mouse EVENT to toggle dired mark for thumbnail.
+ "Use mouse EVENT to toggle Dired mark for thumbnail.
Toggle marks of all thumbnails in region, if it's active.
-Track this in associated dired buffer if `image-dired-track-movement' is
-non-nil."
+Track this in associated Dired buffer if
+`image-dired-track-movement' is non-nil."
(interactive "e")
(if (use-region-p)
(let ((end (region-end)))
@@ -2371,7 +2407,7 @@ non-nil."
(image-dired-thumb-update-marks))
(defun image-dired-dired-display-properties ()
- "Display properties for dired file in the echo area."
+ "Display properties for Dired file in the echo area."
(interactive)
(let* ((file (dired-get-filename))
(file-name (file-name-nondirectory file))
@@ -2387,6 +2423,53 @@ non-nil."
props
comment)))))
+
+
+;;; Gallery support
+
+;; TODO:
+;; * Support gallery creation when using per-directory thumbnail
+;; storage.
+;; * Enhanced gallery creation with basic CSS-support and pagination
+;; of tag pages with many pictures.
+
+(defgroup image-dired-gallery nil
+ "Image-Dired support for generating a HTML gallery."
+ :prefix "image-dired-"
+ :group 'image-dired
+ :version "29.1")
+
+(defcustom image-dired-gallery-dir
+ (expand-file-name ".image-dired_gallery" image-dired-dir)
+ "Directory to store generated gallery html pages.
+The name of this directory needs to be \"shared\" to the public
+so that it can access the index.html page that image-dired creates."
+ :type 'directory)
+
+(defcustom image-dired-gallery-image-root-url
+ "https://example.org/image-diredpics"
+ "URL where the full size images are to be found on your web server.
+Note that this URL has to be configured on your web server.
+Image-Dired expects to find pictures in this directory.
+This is used by `image-dired-gallery-generate'."
+ :type 'string
+ :version "29.1")
+
+(defcustom image-dired-gallery-thumb-image-root-url
+ "https://example.org/image-diredthumbs"
+ "URL where the thumbnail images are to be found on your web server.
+Note that URL path has to be configured on your web server.
+Image-Dired expects to find pictures in this directory.
+This is used by `image-dired-gallery-generate'."
+ :type 'string
+ :version "29.1")
+
+(defcustom image-dired-gallery-hidden-tags
+ (list "private" "hidden" "pending")
+ "List of \"hidden\" tags.
+Used by `image-dired-gallery-generate' to leave out \"hidden\" images."
+ :type '(repeat string))
+
(defvar image-dired-tag-file-list nil
"List to store tag-file structure.")
@@ -2396,19 +2479,8 @@ non-nil."
(defvar image-dired-file-comment-list nil
"List to store file comments.")
-(defun image-dired-add-to-tag-file-list (tag file)
- "Add relation between TAG and FILE."
- (let (curr)
- (if image-dired-tag-file-list
- (if (setq curr (assoc tag image-dired-tag-file-list))
- (if (not (member file curr))
- (setcdr curr (cons file (cdr curr))))
- (setcdr image-dired-tag-file-list
- (cons (list tag file) (cdr image-dired-tag-file-list))))
- (setq image-dired-tag-file-list (list (list tag file))))))
-
-(defun image-dired-add-to-tag-file-lists (tag file)
- "Helper function used from `image-dired-create-gallery-lists'.
+(defun image-dired--add-to-tag-file-lists (tag file)
+ "Helper function used from `image-dired--create-gallery-lists'.
Add TAG to FILE in one list and FILE to TAG in the other.
@@ -2442,8 +2514,8 @@ image-dired-tag-file-list:
(cons (list tag file) (cdr image-dired-tag-file-list))))
(setq image-dired-tag-file-list (list (list tag file))))))
-(defun image-dired-add-to-file-comment-list (file comment)
- "Helper function used from `image-dired-create-gallery-lists'.
+(defun image-dired--add-to-file-comment-list (file comment)
+ "Helper function used from `image-dired--create-gallery-lists'.
For FILE, add COMMENT to list.
@@ -2461,7 +2533,7 @@ image-dired-file-comment-list:
(cdr image-dired-file-comment-list))))
(setq image-dired-file-comment-list (list (cons file comment)))))
-(defun image-dired-create-gallery-lists ()
+(defun image-dired--create-gallery-lists ()
"Create temporary lists used by `image-dired-gallery-generate'."
(image-dired-sane-db-file)
(image-dired--with-db-file
@@ -2482,15 +2554,15 @@ image-dired-file-comment-list:
(setq file (car row-tags))
(dolist (x (cdr row-tags))
(if (not (string-match "^comment:\\(.*\\)" x))
- (image-dired-add-to-tag-file-lists x file)
- (image-dired-add-to-file-comment-list file (match-string 1 x)))))))
+ (image-dired--add-to-tag-file-lists x file)
+ (image-dired--add-to-file-comment-list file (match-string 1 x)))))))
;; Sort tag-file list
(setq image-dired-tag-file-list
(sort image-dired-tag-file-list
(lambda (x y)
(string< (car x) (car y))))))
-(defun image-dired-hidden-p (file)
+(defun image-dired--hidden-p (file)
"Return t if image FILE has a \"hidden\" tag."
(cl-loop for tag in (cdr (assoc file image-dired-file-tag-list))
if (member tag image-dired-gallery-hidden-tags) return t))
@@ -2504,7 +2576,7 @@ it easier to generate, then HTML-files are created in
(if (eq 'per-directory image-dired-thumbnail-storage)
(error "Currently, gallery generation is not supported \
when using per-directory thumbnail file storage"))
- (image-dired-create-gallery-lists)
+ (image-dired--create-gallery-lists)
(let ((tags image-dired-tag-file-list)
(index-file (format "%s/index.html" image-dired-gallery-dir))
count tag tag-file
@@ -2513,6 +2585,7 @@ when using per-directory thumbnail file storage"))
(if (file-exists-p image-dired-gallery-dir)
(if (not (file-directory-p image-dired-gallery-dir))
(error "Variable image-dired-gallery-dir is not a directory"))
+ ;; FIXME: Should we set umask to 077 here, as we do for thumbnails?
(make-directory image-dired-gallery-dir))
;; Open index file
(with-temp-file index-file
@@ -2585,6 +2658,9 @@ when using per-directory thumbnail file storage"))
(insert " </body>\n")
(insert "</html>"))))
+
+;;; Tag support
+
(defvar image-dired-widget-list nil
"List to keep track of meta data in edit buffer.")
@@ -2686,6 +2762,285 @@ tags to their respective image file. Internal function used by
(dolist (tag tag-list)
(push (cons file tag) lst))))))
+
+;;; bookmark.el support
+
+(declare-function bookmark-make-record-default
+ "bookmark" (&optional no-file no-context posn))
+(declare-function bookmark-prop-get "bookmark" (bookmark prop))
+
+(defun image-dired-bookmark-name ()
+ "Create a default bookmark name for the current EWW buffer."
+ (file-name-nondirectory
+ (directory-file-name
+ (file-name-directory (image-dired-original-file-name)))))
+
+(defun image-dired-bookmark-make-record ()
+ "Create a bookmark for the current EWW buffer."
+ `(,(image-dired-bookmark-name)
+ ,@(bookmark-make-record-default t)
+ (location . ,(file-name-directory (image-dired-original-file-name)))
+ (image-dired-file . ,(file-name-nondirectory (image-dired-original-file-name)))
+ (handler . image-dired-bookmark-jump)))
+
+;;;###autoload
+(defun image-dired-bookmark-jump (bookmark)
+ "Default bookmark handler for Image-Dired buffers."
+ ;; User already cached thumbnails, so disable any checking.
+ (let ((image-dired-show-all-from-dir-max-files nil))
+ (image-dired (bookmark-prop-get bookmark 'location))
+ ;; TODO: Go to the bookmarked file, if it exists.
+ ;; (bookmark-prop-get bookmark 'image-dired-file)
+ (goto-char (point-min))))
+
+
+;;; Obsolete
+
+;;;###autoload
+(define-obsolete-function-alias 'tumme #'image-dired "24.4")
+
+;;;###autoload
+(define-obsolete-function-alias 'image-dired-setup-dired-keybindings
+ #'image-dired-minor-mode "26.1")
+
+(defcustom image-dired-temp-image-file
+ (expand-file-name ".image-dired_temp" image-dired-dir)
+ "Name of temporary image file used by various commands."
+ :type 'file)
+(make-obsolete-variable 'image-dired-temp-image-file
+ "no longer used." "29.1")
+
+(defcustom image-dired-cmd-create-temp-image-program
+ (if (executable-find "gm") "gm" "convert")
+ "Executable used to create temporary image.
+Used together with `image-dired-cmd-create-temp-image-options'."
+ :type 'file
+ :version "29.1")
+(make-obsolete-variable 'image-dired-cmd-create-temp-image-program
+ "no longer used." "29.1")
+
+(defcustom image-dired-cmd-create-temp-image-options
+ (let ((opts '("-size" "%wx%h" "%f[0]"
+ "-resize" "%wx%h>"
+ "-strip" "jpeg:%t")))
+ (if (executable-find "gm") (cons "convert" opts) opts))
+ "Options of command used to create temporary image for display window.
+Used together with `image-dired-cmd-create-temp-image-program',
+Available format specifiers are: %w and %h which are replaced by
+the calculated max size for width and height in the image display window,
+%f which is replaced by the file name of the original image and %t which
+is replaced by the file name of the temporary file."
+ :version "29.1"
+ :type '(repeat (string :tag "Argument")))
+(make-obsolete-variable 'image-dired-cmd-create-temp-image-options
+ "no longer used." "29.1")
+
+(defcustom image-dired-display-window-width-correction 1
+ "Number to be used to correct image display window width.
+Change if the default (1) does not work (i.e. if the image does not
+completely fit)."
+ :type 'integer)
+(make-obsolete-variable 'image-dired-display-window-width-correction
+ "no longer used." "29.1")
+
+(defcustom image-dired-display-window-height-correction 0
+ "Number to be used to correct image display window height.
+Change if the default (0) does not work (i.e. if the image does not
+completely fit)."
+ :type 'integer)
+(make-obsolete-variable 'image-dired-display-window-height-correction
+ "no longer used." "29.1")
+
+(defun image-dired-display-window-width (window)
+ "Return width, in pixels, of WINDOW."
+ (declare (obsolete nil "29.1"))
+ (- (image-dired-window-width-pixels window)
+ image-dired-display-window-width-correction))
+
+(defun image-dired-display-window-height (window)
+ "Return height, in pixels, of WINDOW."
+ (declare (obsolete nil "29.1"))
+ (- (image-dired-window-height-pixels window)
+ image-dired-display-window-height-correction))
+
+(defun image-dired-window-height-pixels (window)
+ "Calculate WINDOW height in pixels."
+ (declare (obsolete nil "29.1"))
+ ;; Note: The mode-line consumes one line
+ (* (- (window-height window) 1) (frame-char-height)))
+
+(defcustom image-dired-cmd-read-exif-data-program "exiftool"
+ "Program used to read EXIF data to image.
+Used together with `image-dired-cmd-read-exif-data-options'."
+ :type 'file)
+(make-obsolete-variable 'image-dired-cmd-read-exif-data-program
+ "use `exif-parse-file' and `exif-field' instead." "29.1")
+
+(defcustom image-dired-cmd-read-exif-data-options '("-s" "-s" "-s" "-%t" "%f")
+ "Arguments of command used to read EXIF data.
+Used with `image-dired-cmd-read-exif-data-program'.
+Available format specifiers are: %f which is replaced
+by the image file name and %t which is replaced by the tag name."
+ :version "26.1"
+ :type '(repeat (string :tag "Argument")))
+(make-obsolete-variable 'image-dired-cmd-read-exif-data-options
+ "use `exif-parse-file' and `exif-field' instead." "29.1")
+
+(defun image-dired-get-exif-data (file tag-name)
+ "From FILE, return EXIF tag TAG-NAME."
+ (declare (obsolete "use `exif-parse-file' and `exif-field' instead." "29.1"))
+ (image-dired--check-executable-exists
+ 'image-dired-cmd-read-exif-data-program)
+ (let ((buf (get-buffer-create "*image-dired-get-exif-data*"))
+ (spec (list (cons ?f file) (cons ?t tag-name)))
+ tag-value)
+ (with-current-buffer buf
+ (delete-region (point-min) (point-max))
+ (if (not (eq (apply #'call-process image-dired-cmd-read-exif-data-program
+ nil t nil
+ (mapcar
+ (lambda (arg) (format-spec arg spec))
+ image-dired-cmd-read-exif-data-options))
+ 0))
+ (error "Could not get EXIF tag")
+ (goto-char (point-min))
+ ;; Clean buffer from newlines and carriage returns before
+ ;; getting final info
+ (while (search-forward-regexp "[\n\r]" nil t)
+ (replace-match "" nil t))
+ (setq tag-value (buffer-substring (point-min) (point-max)))))
+ tag-value))
+
+(defcustom image-dired-cmd-rotate-thumbnail-program
+ (if (executable-find "gm") "gm" "mogrify")
+ "Executable used to rotate thumbnail.
+Used together with `image-dired-cmd-rotate-thumbnail-options'."
+ :type 'file
+ :version "29.1")
+(make-obsolete-variable 'image-dired-cmd-rotate-thumbnail-program nil "29.1")
+
+(defcustom image-dired-cmd-rotate-thumbnail-options
+ (let ((opts '("-rotate" "%d" "%t")))
+ (if (executable-find "gm") (cons "mogrify" opts) opts))
+ "Arguments of command used to rotate thumbnail image.
+Used with `image-dired-cmd-rotate-thumbnail-program'.
+Available format specifiers are: %d which is replaced by the
+number of (positive) degrees to rotate the image, normally 90 or 270
+\(for 90 degrees right and left), %t which is replaced by the file name
+of the thumbnail file."
+ :version "29.1"
+ :type '(repeat (string :tag "Argument")))
+(make-obsolete-variable 'image-dired-cmd-rotate-thumbnail-options nil "29.1")
+
+(defun image-dired-rotate-thumbnail (degrees)
+ "Rotate thumbnail DEGREES degrees."
+ (declare (obsolete image-dired-refresh-thumb "29.1"))
+ (image-dired--check-executable-exists
+ 'image-dired-cmd-rotate-thumbnail-program)
+ (if (not (image-dired-image-at-point-p))
+ (message "No thumbnail at point")
+ (let* ((file (image-dired-thumb-name (image-dired-original-file-name)))
+ (thumb (expand-file-name file))
+ (spec (list (cons ?d degrees) (cons ?t thumb))))
+ (apply #'call-process image-dired-cmd-rotate-thumbnail-program nil nil nil
+ (mapcar (lambda (arg) (format-spec arg spec))
+ image-dired-cmd-rotate-thumbnail-options))
+ (clear-image-cache thumb))))
+
+(defun image-dired-rotate-thumbnail-left ()
+ "Rotate thumbnail left (counter clockwise) 90 degrees."
+ (declare (obsolete image-dired-refresh-thumb "29.1"))
+ (interactive)
+ (with-suppressed-warnings ((obsolete image-dired-rotate-thumbnail))
+ (image-dired-rotate-thumbnail "270")))
+
+(defun image-dired-rotate-thumbnail-right ()
+ "Rotate thumbnail counter right (clockwise) 90 degrees."
+ (declare (obsolete image-dired-refresh-thumb "29.1"))
+ (interactive)
+ (with-suppressed-warnings ((obsolete image-dired-rotate-thumbnail))
+ (image-dired-rotate-thumbnail "90")))
+
+(defun image-dired-modify-mark-on-thumb-original-file (command)
+ "Modify mark in Dired buffer.
+COMMAND is one of `mark' for marking file in Dired, `unmark' for
+unmarking file in Dired or `flag' for flagging file for delete in
+Dired."
+ (declare (obsolete image-dired--on-file-in-dired-buffer "29.1"))
+ (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
+ (message "%s" file-name)
+ (when (dired-goto-file file-name)
+ (cond ((eq command 'mark) (dired-mark 1))
+ ((eq command 'unmark) (dired-unmark 1))
+ ((eq command 'toggle)
+ (if (image-dired-dired-file-marked-p)
+ (dired-unmark 1)
+ (dired-mark 1)))
+ ((eq command 'flag) (dired-flag-file-deletion 1)))
+ (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"))
+ (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)))
+ (error "No original file name at point"))))
+
+(defun image-dired-display-current-image-sized ()
+ "Display current image in sized to fit window dimensions."
+ (declare (obsolete image-mode-fit-frame "29.1"))
+ (interactive nil image-dired-thumbnail-mode)
+ (let ((file (image-dired-original-file-name)))
+ (if file
+ (progn
+ (image-dired-display-image file))
+ (error "No original file name at point"))))
+
+(defun image-dired-add-to-tag-file-list (tag file)
+ "Add relation between TAG and FILE."
+ (declare (obsolete nil "29.1"))
+ (let (curr)
+ (if image-dired-tag-file-list
+ (if (setq curr (assoc tag image-dired-tag-file-list))
+ (if (not (member file curr))
+ (setcdr curr (cons file (cdr curr))))
+ (setcdr image-dired-tag-file-list
+ (cons (list tag file) (cdr image-dired-tag-file-list))))
+ (setq image-dired-tag-file-list (list (list tag file))))))
+
+(defun image-dired-display-thumb-properties ()
+ "Display thumbnail properties in the echo area."
+ (declare (obsolete image-dired-update-header-line "29.1"))
+ (image-dired-update-header-line))
+
+(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")
+
+(defvar image-dired-slideshow-times 0
+ "Number of pictures to display in slideshow.")
+(make-obsolete-variable 'image-dired-slideshow-times "no longer used." "29.1")
+
+(define-obsolete-function-alias 'image-dired-create-display-image-buffer
+ #'ignore "29.1")
+(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
+ #'image-dired--add-to-file-comment-list "29.1")
+(define-obsolete-function-alias 'image-dired-add-to-tag-file-lists
+ #'image-dired--add-to-tag-file-lists "29.1")
+(define-obsolete-function-alias 'image-dired-hidden-p
+ #'image-dired--hidden-p "29.1")
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;; TEST-SECTION ;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2717,23 +3072,6 @@ tags to their respective image file. Internal function used by
;; (setq dirsize (- dirsize (car (cdar files))))
;; (setq files (cdr files)))))
-;;;;;;;;;;;;;;;;;;;;;;,
-
-;; (defun dired-speedbar-buttons (dired-buffer)
-;; (when (and (boundp 'image-dired-use-speedbar)
-;; image-dired-use-speedbar)
-;; (let ((filename (with-current-buffer dired-buffer
-;; (dired-get-filename))))
-;; (when (and (not (string-equal filename (buffer-string)))
-;; (string-match (image-file-name-regexp) filename))
-;; (erase-buffer)
-;; (insert (propertize
-;; filename
-;; 'display
-;; (image-dired-get-thumbnail-image filename)))))))
-
-;; (setq image-dired-use-speedbar t)
-
(provide 'image-dired)
;;; image-dired.el ends here
diff --git a/lisp/image-file.el b/lisp/image-file.el
index fbc9eaaf94e..6df43f737dd 100644
--- a/lisp/image-file.el
+++ b/lisp/image-file.el
@@ -37,7 +37,7 @@
;;;###autoload
(defcustom image-file-name-extensions
- (purecopy '("png" "jpeg" "jpg" "gif" "tiff" "tif" "xbm" "xpm" "pbm" "pgm" "ppm" "pnm" "svg"))
+ (purecopy '("png" "jpeg" "jpg" "gif" "tiff" "tif" "xbm" "xpm" "pbm" "pgm" "ppm" "pnm" "svg" "webp"))
"A list of image-file filename extensions.
Filenames having one of these extensions are considered image files,
in addition to those matching `image-file-name-regexps'.
diff --git a/lisp/image-mode.el b/lisp/image-mode.el
index 69ef7015cce..6ff7859c835 100644
--- a/lisp/image-mode.el
+++ b/lisp/image-mode.el
@@ -58,16 +58,25 @@ It is called with one argument, the initial WINPROPS.")
"Non-nil to resize the image upon first display.
Its value should be one of the following:
- nil, meaning no resizing.
- - t, meaning to fit the image to the window height and width.
- - `fit-height', meaning to fit the image to the window height.
- - `fit-width', meaning to fit the image to the window width.
- - A number, which is a scale factor (the default size is 1)."
+ - t, meaning to scale the image down to fit in the window.
+ - `fit-window', meaning to fit the image to the window.
+ - A number, which is a scale factor (the default size is 1).
+
+Resizing will always preserve the aspect ratio of the image."
:type '(choice (const :tag "No resizing" nil)
- (other :tag "Fit height and width" t)
- (const :tag "Fit height" fit-height)
- (const :tag "Fit width" fit-width)
+ (const :tag "Fit to window" fit-window)
+ (other :tag "Scale down to fit window" t)
(number :tag "Scale factor" 1))
- :version "27.1"
+ :version "29.1"
+ :group 'image)
+
+(defcustom image-auto-resize-max-scale-percent nil
+ "Max size (in percent) to scale up to when `image-auto-resize' is `fit-window'.
+Can be either a number larger than 100, or nil, which means no
+max size."
+ :type '(choice (const :tag "No max" nil)
+ natnum)
+ :version "29.1"
:group 'image)
(defcustom image-auto-resize-on-window-resize 1
@@ -82,12 +91,18 @@ resizing according to the value specified in `image-auto-resize'."
(defvar-local image-transform-resize nil
"The image resize operation.
+Non-nil to resize the image upon first display.
Its value should be one of the following:
- nil, meaning no resizing.
- - t, meaning to fit the image to the window height and width.
+ - t, meaning to scale the image down to fit in the window.
+ - `fit-window', meaning to fit the image to the window.
+ - A number, which is a scale factor (the default size is 1).
+
+There is also support for these values, obsolete since Emacs 29.1:
- `fit-height', meaning to fit the image to the window height.
- `fit-width', meaning to fit the image to the window width.
- - A number, which is a scale factor (the default size is 1).")
+
+Resizing will always preserve the aspect ratio of the image.")
(defvar-local image-transform-scale 1.0
"The scale factor of the image being displayed.")
@@ -440,6 +455,15 @@ call."
;;; Image Mode setup
+(defcustom image-text-based-formats '(svg xpm)
+ "List of image formats that use a plain text format.
+For such formats, display a message that explains how to edit the
+image as text, when opening such images in `image-mode'."
+ :type '(choice (const :tag "Disable completely" nil)
+ (repeat :tag "List of formats" sexp))
+ :version "29.1"
+ :group 'image)
+
(defvar-local image-type nil
"The image type for the current Image mode buffer.")
@@ -455,8 +479,9 @@ call."
;; Transformation keys
(define-key map "sf" 'image-mode-fit-frame)
+ (define-key map "sw" 'image-transform-fit-to-window)
(define-key map "sh" 'image-transform-fit-to-height)
- (define-key map "sw" 'image-transform-fit-to-width)
+ (define-key map "si" 'image-transform-fit-to-width)
(define-key map "sb" 'image-transform-fit-both)
(define-key map "ss" 'image-transform-set-scale)
(define-key map "sr" 'image-transform-set-rotation)
@@ -511,12 +536,10 @@ call."
"--"
["Fit Frame to Image" image-mode-fit-frame :active t
:help "Resize frame to match image"]
- ["Fit Image to Window (Best Fit)" image-transform-fit-both
- :help "Resize image to match the window height and width"]
- ["Fit to Window Height" image-transform-fit-to-height
- :help "Resize image to match the window height"]
- ["Fit to Window Width" image-transform-fit-to-width
- :help "Resize image to match the window width"]
+ ["Fit Image to Window" image-transform-fit-to-window
+ :help "Resize image to match the window height and width"]
+ ["Fit Image to Window (Scale down only)" image-transform-fit-both
+ :help "Scale image down to match the window height and width"]
["Zoom In" image-increase-size
:help "Enlarge the image"]
["Zoom Out" image-decrease-size
@@ -605,8 +628,9 @@ call."
;;;###autoload
(defun image-mode ()
"Major mode for image files.
-You can use \\<image-mode-map>\\[image-toggle-display] or \\<image-mode-map>\\[image-toggle-hex-display]
-to toggle between display as an image and display as text or hex.
+You can use \\<image-mode-map>\\[image-toggle-display] or \
+\\[image-toggle-hex-display] to toggle between display
+as an image and display as text or hex.
Key bindings:
\\{image-mode-map}"
@@ -678,12 +702,10 @@ Key bindings:
(run-mode-hooks 'image-mode-hook)
(let ((image (image-get-display-property))
- (msg1 (substitute-command-keys
- "Type \\[image-toggle-display] or \\[image-toggle-hex-display] to view the image as "))
- animated)
+ msg animated)
(cond
((null image)
- (message "%s" (concat msg1 "an image.")))
+ (setq msg "an image"))
((setq animated (image-multi-frame-p image))
(setq image-multi-frame t
mode-line-process
@@ -701,10 +723,13 @@ Key bindings:
keymap
(down-mouse-1 . image-next-frame)
(down-mouse-3 . image-previous-frame)))))))
- (message "%s"
- (concat msg1 "text. This image has multiple frames.")))
+ (setq msg "text. This image has multiple frames"))
(t
- (message "%s" (concat msg1 "text or hex."))))))
+ (setq msg "text")))
+ (when (memq (plist-get (cdr image) :type) image-text-based-formats)
+ (message (substitute-command-keys
+ "Type \\[image-toggle-display] to view the image as %s")
+ msg))))
;;;###autoload
(define-minor-mode image-minor-mode
@@ -751,11 +776,11 @@ on these modes."
(image-mode-to-text)
;; Turn on hexl-mode
(hexl-mode)
- (message "%s" (concat
- (substitute-command-keys
- "Type \\[image-toggle-hex-display] or \\[image-toggle-display] to view the image as ")
- (if (image-get-display-property)
- "hex" "an image or text") ".")))
+ (message (substitute-command-keys
+ "Type \\[image-toggle-hex-display] or \
+\\[image-toggle-display] to view the image as %s")
+ (if (image-get-display-property)
+ "hex" "an image or text")))
(defun image-mode-as-text ()
"Set a non-image mode as major mode in combination with image minor mode.
@@ -771,11 +796,10 @@ See commands `image-mode' and `image-minor-mode' for more information
on these modes."
(interactive)
(image-mode-to-text)
- (message "%s" (concat
- (substitute-command-keys
- "Type \\[image-toggle-display] or \\[image-toggle-hex-display] to view the image as ")
- (if (image-get-display-property)
- "text" "an image or hex") ".")))
+ (message (substitute-command-keys
+ "Type \\[image-toggle-display] to view the image as %s")
+ (if (image-get-display-property)
+ "text" "an image")))
(defun image-toggle-display-text ()
"Show the image file as text.
@@ -803,6 +827,21 @@ Remove text properties that display the image."
(defvar tar-superior-buffer)
(declare-function image-flush "image.c" (spec &optional frame))
+(defun image--scale-within-limits-p (image)
+ "Return t if `fit-window' will scale image within the customized limits.
+The limits are given by the user option
+`image-auto-resize-max-scale-percent'."
+ (or (not image-auto-resize-max-scale-percent)
+ (let ((scale (/ image-auto-resize-max-scale-percent 100))
+ (mw (plist-get (cdr image) :max-width))
+ (mh (plist-get (cdr image) :max-height))
+ ;; Note: `image-size' looks up and thus caches the
+ ;; untransformed image. There's no easy way to
+ ;; prevent that.
+ (size (image-size image t)))
+ (or (<= mw (* (car size) scale))
+ (<= mh (* (cdr size) scale))))))
+
(defun image-toggle-display-image ()
"Show the image of the image file.
Turn the image data into a real image, but only if the whole file
@@ -837,7 +876,8 @@ was inserted."
filename))
;; If we have a `fit-width' or a `fit-height', don't limit
;; the size of the image to the window size.
- (edges (when (eq image-transform-resize t)
+ (edges (when (or (eq image-transform-resize t)
+ (eq image-transform-resize 'fit-window))
(window-inside-pixel-edges (get-buffer-window))))
(max-width (when edges
(- (nth 2 edges) (nth 0 edges))))
@@ -884,6 +924,14 @@ was inserted."
;; Type hint.
:format (and filename data-p))))
+ ;; Handle `fit-window'.
+ (when (and (eq image-transform-resize 'fit-window)
+ (image--scale-within-limits-p image))
+ (setq image
+ (cons (car image)
+ (plist-put (cdr image) :width
+ (plist-get (cdr image) :max-width)))))
+
;; Discard any stale image data before looking it up again.
(image-flush image)
(setq image (append image (image-transform-properties image)))
@@ -1241,7 +1289,7 @@ will have the line where the image appears (if any) marked.
If no such buffer exists, it will be opened."
(interactive)
(unless buffer-file-name
- (error "The current buffer doesn't visit a file."))
+ (error "Current buffer is not visiting a file"))
(image-mode--mark-file buffer-file-name #'dired-mark "marked"))
(defun image-mode-unmark-file ()
@@ -1253,7 +1301,7 @@ any).
If no such buffer exists, it will be opened."
(interactive)
(unless buffer-file-name
- (error "The current buffer doesn't visit a file."))
+ (error "Current buffer is not visiting a file"))
(image-mode--mark-file buffer-file-name #'dired-unmark "unmarked"))
(declare-function dired-mark "dired" (arg &optional interactive))
@@ -1494,21 +1542,29 @@ return value is suitable for appending to an image spec."
(defun image-transform-fit-to-height ()
"Fit the current image to the height of the current window."
(interactive)
+ (declare (obsolete nil "29.1"))
(setq image-transform-resize 'fit-height)
(image-toggle-display-image))
(defun image-transform-fit-to-width ()
"Fit the current image to the width of the current window."
+ (declare (obsolete nil "29.1"))
(interactive)
(setq image-transform-resize 'fit-width)
(image-toggle-display-image))
(defun image-transform-fit-both ()
- "Fit the current image both to the height and width of the current window."
+ "Scale the current image down to fit in the current window."
(interactive)
(setq image-transform-resize t)
(image-toggle-display-image))
+(defun image-transform-fit-to-window ()
+ "Fit the current image to the height and width of the current window."
+ (interactive)
+ (setq image-transform-resize 'fit-window)
+ (image-toggle-display-image))
+
(defun image-transform-set-rotation (rotation)
"Prompt for an angle ROTATION, and rotate the image by that amount.
ROTATION should be in degrees."
diff --git a/lisp/image.el b/lisp/image.el
index 494c26a8a33..cedefc038f0 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -27,6 +27,8 @@
(defgroup image ()
"Image support."
+ :prefix "image-"
+ :link '(info-link "(emacs) Image Mode")
:group 'multimedia)
(declare-function image-flush "image.c" (spec &optional frame))
@@ -48,6 +50,7 @@ static \\(unsigned \\)?char \\1_bits" . xbm)
("\\`\\(?:MM\0\\*\\|II\\*\0\\)" . tiff)
("\\`[\t\n\r ]*%!PS" . postscript)
("\\`\xff\xd8" . jpeg) ; used to be (image-jpeg-p . jpeg)
+ ("\\`RIFF....WEBPVP8" . webp)
(,(let* ((incomment-re "\\(?:[^-]\\|-[^-]\\)")
(comment-re (concat "\\(?:!--" incomment-re "*-->[ \t\r\n]*<\\)")))
(concat "\\(?:<\\?xml[ \t\r\n]+[^>]*>\\)?[ \t\r\n]*<"
@@ -67,6 +70,7 @@ a non-nil value, TYPE is the image's type.")
'(("\\.png\\'" . png)
("\\.gif\\'" . gif)
("\\.jpe?g\\'" . jpeg)
+ ("\\.webp\\'" . webp)
("\\.bmp\\'" . bmp)
("\\.xpm\\'" . xpm)
("\\.pbm\\'" . pbm)
@@ -92,6 +96,7 @@ be of image type IMAGE-TYPE.")
(jpeg . maybe)
(tiff . maybe)
(svg . maybe)
+ (webp . maybe)
(postscript . nil))
"Alist of (IMAGE-TYPE . AUTODETECT) pairs used to auto-detect image files.
\(See `image-type-auto-detected-p').
@@ -556,7 +561,12 @@ If VALUE is nil, PROPERTY is removed from IMAGE."
(declare (gv-setter image--set-property))
(plist-get (cdr image) property))
-(defun image-compute-scaling-factor (scaling)
+(defun image-compute-scaling-factor (&optional scaling)
+ "Compute the scaling factor based on SCALING.
+If a number, use that. If it's `auto', compute the factor.
+If nil, use the `image-scaling-factor' variable."
+ (unless scaling
+ (setq scaling image-scaling-factor))
(cond
((numberp scaling) scaling)
((eq scaling 'auto)
@@ -600,7 +610,7 @@ means display it in the right marginal area."
;;;###autoload
-(defun insert-image (image &optional string area slice)
+(defun insert-image (image &optional string area slice inhibit-isearch)
"Insert IMAGE into current buffer at point.
IMAGE is displayed by inserting STRING into the current buffer
with a `display' property whose value is the image.
@@ -617,7 +627,11 @@ SLICE specifies slice of IMAGE to insert. SLICE nil or omitted
means insert whole image. SLICE is a list (X Y WIDTH HEIGHT)
specifying the X and Y positions and WIDTH and HEIGHT of image area
to insert. A float value 0.0 - 1.0 means relative to the width or
-height of the image; integer values are taken as pixel values."
+height of the image; integer values are taken as pixel values.
+
+Normally `isearch' is able to search for STRING in the buffer
+even if it's hidden behind a displayed image. If INHIBIT-ISEARCH
+is non-nil, this is inhibited."
;; Use a space as least likely to cause trouble when it's a hidden
;; character in the buffer.
(unless string (setq string " "))
@@ -641,6 +655,7 @@ height of the image; integer values are taken as pixel values."
(list (cons 'slice slice) image)
image)
rear-nonsticky t
+ inhibit-isearch ,inhibit-isearch
keymap ,image-map))))
@@ -791,7 +806,7 @@ Example:
(defimage test-image ((:type xpm :file \"~/test1.xpm\")
(:type xbm :file \"~/test1.xbm\")))"
- (declare (doc-string 3))
+ (declare (doc-string 3) (indent defun))
`(defvar ,symbol (find-image ',specs) ,doc))
@@ -817,21 +832,24 @@ in which case you might want to use `image-default-frame-delay'."
(cons images delay)))))
(defun image-animated-p (image)
- "Like `image-multi-frame-p', but returns nil if no delay is specified."
+ "Like `image-multi-frame-p', but return nil if no delay is specified."
(let ((multi (image-multi-frame-p image)))
(and (cdr multi) multi)))
(make-obsolete 'image-animated-p 'image-multi-frame-p "24.4")
-;; "Destructively"?
-(defun image-animate (image &optional index limit)
+(defun image-animate (image &optional index limit position)
"Start animating IMAGE.
Animation occurs by destructively altering the IMAGE spec list.
With optional INDEX, begin animating from that animation frame.
LIMIT specifies how long to animate the image. If omitted or
nil, play the animation until the end. If t, loop forever. If a
-number, play until that number of seconds has elapsed."
+number, play until that number of seconds has elapsed.
+
+If POSITION (which should be buffer position where the image is
+displayed), stop the animation if the image is no longer
+displayed."
(let ((animation (image-multi-frame-p image))
timer)
(when animation
@@ -839,6 +857,9 @@ number, play until that number of seconds has elapsed."
(cancel-timer timer))
(plist-put (cdr image) :animate-buffer (current-buffer))
(plist-put (cdr image) :animate-tardiness 0)
+ (when position
+ (plist-put (cdr image) :animate-position
+ (set-marker (make-marker) position (current-buffer))))
;; Stash the data about the animation here so that we don't
;; trigger image recomputation unnecessarily later.
(plist-put (cdr image) :animate-multi-frame-data animation)
@@ -912,40 +933,54 @@ for the animation speed. A negative value means to animate in reverse."
(plist-put (cdr image) :animate-tardiness
(+ (* (plist-get (cdr image) :animate-tardiness) 0.9)
(float-time (time-since target-time))))
- (when (and (buffer-live-p (plist-get (cdr image) :animate-buffer))
- ;; Cumulatively delayed two seconds more than expected.
- (or (< (plist-get (cdr image) :animate-tardiness) 2)
- (progn
- (message "Stopping animation; animation possibly too big")
- nil)))
- (image-show-frame image n t)
- (let* ((speed (image-animate-get-speed image))
- (time (current-time))
- (time-to-load-image (time-since time))
- (stated-delay-time
- (/ (or (cdr (plist-get (cdr image) :animate-multi-frame-data))
- image-default-frame-delay)
- (float (abs speed))))
- ;; Subtract off the time we took to load the image from the
- ;; stated delay time.
- (delay (max (float-time (time-subtract stated-delay-time
- time-to-load-image))
- image-minimum-frame-delay))
- done)
- (setq n (if (< speed 0)
- (1- n)
- (1+ n)))
- (if limit
- (cond ((>= n count) (setq n 0))
- ((< n 0) (setq n (1- count))))
- (and (or (>= n count) (< n 0)) (setq done t)))
- (setq time-elapsed (+ delay time-elapsed))
- (if (numberp limit)
- (setq done (>= time-elapsed limit)))
- (unless done
- (run-with-timer delay nil #'image-animate-timeout
- image n count time-elapsed limit
- (+ (float-time) delay))))))
+ (let ((buffer (plist-get (cdr image) :animate-buffer))
+ (position (plist-get (cdr image) :animate-position)))
+ (when (and (buffer-live-p buffer)
+ ;; If we have a :animate-position setting, the caller
+ ;; has requested that the animation be stopped if the
+ ;; image is no longer displayed in the buffer.
+ (or (null position)
+ (with-current-buffer buffer
+ (let ((disp (get-text-property position 'display)))
+ (and (consp disp)
+ (eq (car disp) 'image)
+ ;; We can't check `eq'-ness of the image
+ ;; itself, since that may change.
+ (eq position
+ (plist-get (cdr disp) :animate-position))))))
+ ;; Cumulatively delayed two seconds more than expected.
+ (or (< (plist-get (cdr image) :animate-tardiness) 2)
+ (progn
+ (message "Stopping animation; animation possibly too big")
+ nil)))
+ (let* ((time (prog1 (current-time)
+ (image-show-frame image n t)))
+ (speed (image-animate-get-speed image))
+ (time-to-load-image (time-since time))
+ (stated-delay-time
+ (/ (or (cdr (plist-get (cdr image) :animate-multi-frame-data))
+ image-default-frame-delay)
+ (float (abs speed))))
+ ;; Subtract off the time we took to load the image from the
+ ;; stated delay time.
+ (delay (max (float-time (time-subtract stated-delay-time
+ time-to-load-image))
+ image-minimum-frame-delay))
+ done)
+ (setq n (if (< speed 0)
+ (1- n)
+ (1+ n)))
+ (if limit
+ (cond ((>= n count) (setq n 0))
+ ((< n 0) (setq n (1- count))))
+ (and (or (>= n count) (< n 0)) (setq done t)))
+ (setq time-elapsed (+ delay time-elapsed))
+ (if (numberp limit)
+ (setq done (>= time-elapsed limit)))
+ (unless done
+ (run-with-timer delay nil #'image-animate-timeout
+ image n count time-elapsed limit
+ (+ (float-time) delay)))))))
(defvar imagemagick-types-inhibit)
@@ -1137,6 +1172,13 @@ default is 20%."
(error "No image under point"))
image))
+;;;###autoload
+(defun image-at-point-p ()
+ "Return non-nil if there is an image at point."
+ (condition-case nil
+ (prog1 t (image--get-image))
+ (error nil)))
+
(defun image--get-imagemagick-and-warn (&optional position)
(declare-function image-transforms-p "image.c" (&optional frame))
(unless (or (fboundp 'imagemagick-types) (image-transforms-p))
diff --git a/lisp/image/exif.el b/lisp/image/exif.el
index c2cf2346408..372e2d25553 100644
--- a/lisp/image/exif.el
+++ b/lisp/image/exif.el
@@ -58,6 +58,9 @@
;; (:tag 306 :tag-name date-time :format 2 :format-type ascii
;; :value "2019:09:21 16:22:13")
;; ...)
+;;
+;; (exif-field 'date-time (exif-parse-file "test.jpg")) =>
+;; "2022:09:14 18:46:19"
;;; Code:
@@ -65,6 +68,7 @@
(defvar exif-tag-alist
'((11 processing-software)
+ (270 description)
(271 make)
(272 model)
(274 orientation)
@@ -73,7 +77,8 @@
(296 resolution-unit)
(305 software)
(306 date-time)
- (315 artist))
+ (315 artist)
+ (33432 copyright))
"Alist of tag values and their names.")
(defconst exif--orientation
@@ -122,13 +127,20 @@ If the data is invalid, an `exif-error' is signaled."
(when-let ((app1 (cdr (assq #xffe1 (exif--parse-jpeg)))))
(exif--parse-exif-chunk app1))))))
+(defun exif-field (field data)
+ "Return raw FIELD from EXIF.
+If FIELD is not present in the data, return nil.
+FIELD is a symbol in the cdr of `exif-tag-alist'.
+DATA is the result of calling `exif-parse-file'."
+ (plist-get (seq-find (lambda (e)
+ (eq field (plist-get e :tag-name)))
+ data)
+ :value))
+
(defun exif-orientation (exif)
"Return the orientation (in degrees) in EXIF.
If the orientation isn't present in the data, return nil."
- (let ((code (plist-get (cl-find 'orientation exif
- :key (lambda (e)
- (plist-get e :tag-name)))
- :value)))
+ (let ((code (exif-field 'orientation exif)))
(cadr (assq code exif--orientation))))
(defun exif--parse-jpeg ()
diff --git a/lisp/image/gravatar.el b/lisp/image/gravatar.el
index f6f056a2baf..87726a9b8c8 100644
--- a/lisp/image/gravatar.el
+++ b/lisp/image/gravatar.el
@@ -277,7 +277,7 @@ where GRAVATAR is either an image descriptor, or the symbol
;; Store the image in the cache.
(when image
(setf (gethash mail-address gravatar--cache)
- (cons (time-convert (current-time) 'integer)
+ (cons (time-convert nil 'integer)
image)))
(prog1
(apply callback (if data image 'error) cbargs)
@@ -286,7 +286,7 @@ where GRAVATAR is either an image descriptor, or the symbol
(defun gravatar--prune-cache ()
(let ((expired nil)
- (time (- (time-convert (current-time) 'integer)
+ (time (- (time-convert nil 'integer)
;; Twelve hours.
(* 12 60 60))))
(maphash (lambda (key val)
diff --git a/lisp/imenu.el b/lisp/imenu.el
index 2024bb1e066..22412d5f88b 100644
--- a/lisp/imenu.el
+++ b/lisp/imenu.el
@@ -85,7 +85,8 @@ This might not yet be honored by all index-building functions."
:type 'boolean)
(defcustom imenu-auto-rescan-maxout 600000
- "Imenu auto-rescan is disabled in buffers larger than this size (in bytes)."
+ "Imenu auto-rescan is disabled in buffers larger than this size (in bytes).
+Also see `imenu-max-index-time'."
:type 'integer
:version "26.2")
@@ -153,6 +154,11 @@ uses `imenu--generic-function')."
:type 'boolean
:version "24.4")
+(defcustom imenu-max-index-time 5
+ "Max time to use when creating imenu indices."
+ :type 'number
+ :version "28.1")
+
;;;###autoload
(defvar-local imenu-generic-expression nil
"List of definition matchers for creating an Imenu index.
@@ -520,10 +526,13 @@ The alternate method, which is the one most often used, is to call
(cond ((and imenu-prev-index-position-function
imenu-extract-index-name-function)
(let ((index-alist '()) (pos (point-max))
+ (start (float-time))
name)
(goto-char pos)
;; Search for the function
- (while (funcall imenu-prev-index-position-function)
+ (while (and (funcall imenu-prev-index-position-function)
+ ;; Don't use an excessive amount of time.
+ (< (- (float-time) start) imenu-max-index-time))
(unless (< (point) pos)
(error "Infinite loop at %s:%d: imenu-prev-index-position-function does not move point" (buffer-name) pos))
(setq pos (point))
@@ -576,6 +585,7 @@ depending on PATTERNS."
(not (local-variable-p 'font-lock-defaults)))
imenu-case-fold-search
(nth 2 font-lock-defaults)))
+ (start-time (float-time))
(old-table (syntax-table))
(table (copy-syntax-table (syntax-table)))
(slist imenu-syntax-alist))
@@ -618,7 +628,13 @@ depending on PATTERNS."
(not invis))))))
;; Exit the loop if we get an empty match,
;; because it means a bad regexp was specified.
- (not (= (match-beginning 0) (match-end 0))))
+ (not (= (match-beginning 0) (match-end 0)))
+ ;; Don't take an excessive amount of time.
+ (or (< (- (float-time) start-time)
+ imenu-max-index-time)
+ (progn
+ (message "`imenu-max-index-time' exceeded")
+ nil)))
(setq start (point))
;; Record the start of the line in which the match starts.
;; That's the official position of this definition.
@@ -813,8 +829,7 @@ A trivial interface to `imenu-add-to-menubar' suitable for use in a hook."
(defvar imenu-buffer-menubar nil)
(defvar-local imenu-menubar-modified-tick 0
- "The value of (buffer-chars-modified-tick) as of the last call
-to `imenu-update-menubar'.")
+ "Value of (buffer-chars-modified-tick) when `imenu-update-menubar' was called.")
(defun imenu-update-menubar ()
(when (and (current-local-map)
diff --git a/lisp/indent.el b/lisp/indent.el
index a33d9620098..ec01733d123 100644
--- a/lisp/indent.el
+++ b/lisp/indent.el
@@ -81,23 +81,27 @@ This variable has no effect unless `tab-always-indent' is `complete'."
(const :tag "Unless looking at a word" 'word)
(const :tag "Unless at a word or parenthesis" 'word-or-paren)
(const :tag "Unless at a word, parenthesis, or punctuation." 'word-or-paren-or-punct))
- :version "27.1")
+ :version "28.1")
(defvar indent-line-ignored-functions '(indent-relative
indent-relative-maybe
indent-relative-first-indent-point)
"Values that are ignored by `indent-according-to-mode'.")
-(defun indent-according-to-mode ()
+(defun indent-according-to-mode (&optional inhibit-widen)
"Indent line in proper way for current major mode.
Normally, this is done by calling the function specified by the
variable `indent-line-function'. However, if the value of that
variable is present in the `indent-line-ignored-functions' variable,
handle it specially (since those functions are used for tabbing);
-in that case, indent by aligning to the previous non-blank line."
+in that case, indent by aligning to the previous non-blank line.
+
+Ignore restriction, unless the optional argument INHIBIT-WIDEN is
+non-nil."
(interactive)
(save-restriction
- (widen)
+ (unless inhibit-widen
+ (widen))
(syntax-propertize (line-end-position))
(if (memq indent-line-function indent-line-ignored-functions)
;; These functions are used for tabbing, but can't be used for
@@ -463,7 +467,7 @@ Optional fifth argument OBJECT specifies the string or buffer to operate on."
(put-text-property begin to prop (funcall func val) object))))
(defun increase-left-margin (from to inc)
- "Increase or decrease the left-margin of the region.
+ "Increase or decrease the `left-margin' of the region.
With no prefix argument, this adds `standard-indent' of indentation.
A prefix arg (optional third arg INC noninteractively) specifies the amount
to change the margin by, in characters.
@@ -520,11 +524,14 @@ If `auto-fill-mode' is active, re-fills region to fit in new margin."
(defun beginning-of-line-text (&optional n)
"Move to the beginning of the text on this line.
-With optional argument, move forward N-1 lines first.
-From the beginning of the line, moves past the left-margin indentation, the
-fill-prefix, and any indentation used for centering or right-justifying the
-line, but does not move past any whitespace that was explicitly inserted
-\(such as a tab used to indent the first line of a paragraph)."
+
+With optional argument N, move forward N-1 lines first.
+
+From the beginning of the line, moves past the `left-margin'
+indentation, the `fill-prefix', and any indentation used for
+centering or right-justifying the line, but does not move past
+any whitespace that was explicitly inserted (such as a tab used
+to indent the first line of a paragraph)."
(interactive "^p")
(beginning-of-line n)
(skip-chars-forward " \t")
@@ -598,7 +605,10 @@ column to indent to; if it is nil, use one of the three methods above."
(funcall indent-region-function start end)))
;; Else, use a default implementation that calls indent-line-function on
;; each line.
- (t (indent-region-line-by-line start end)))
+ (t
+ (save-restriction
+ (widen)
+ (indent-region-line-by-line start end))))
;; In most cases, reindenting modifies the buffer, but it may also
;; leave it unmodified, in which case we have to deactivate the mark
;; by hand.
@@ -612,7 +622,7 @@ column to indent to; if it is nil, use one of the three methods above."
(make-progress-reporter "Indenting region..." (point) end))))
(while (< (point) end)
(or (and (bolp) (eolp))
- (indent-according-to-mode))
+ (indent-according-to-mode t))
(forward-line 1)
(and pr (progress-reporter-update pr (point))))
(and pr (progress-reporter-done pr))
diff --git a/lisp/info-look.el b/lisp/info-look.el
index 33f15a34e99..48120359193 100644
--- a/lisp/info-look.el
+++ b/lisp/info-look.el
@@ -124,6 +124,14 @@ OTHER-MODES is a list of cross references to other help modes.")
(defsubst info-lookup->mode-value (topic mode)
(assoc mode (info-lookup->topic-value topic)))
+(defun info-lookup--expand-info (info)
+ ;; We have a dynamic doc-spec function.
+ (when (and (null (nth 3 info))
+ (nth 6 info))
+ (setf (nth 3 info) (funcall (nth 6 info))
+ (nth 6 info) nil))
+ info)
+
(defsubst info-lookup->regexp (topic mode)
(nth 1 (info-lookup->mode-value topic mode)))
@@ -146,7 +154,11 @@ Function arguments are specified as keyword/argument pairs:
(KEYWORD . ARGUMENT)
KEYWORD is either `:topic', `:mode', `:regexp', `:ignore-case',
- `:doc-spec', `:parse-rule', or `:other-modes'.
+ `:doc-spec', `:parse-rule', `:other-modes' or `:doc-spec-function'.
+ `:doc-spec-function' is used to compute a `:doc-spec', but instead of
+ doing so at load time, this is done when the user asks for info on
+ the mode in question.
+
ARGUMENT has a value as explained in the documentation of the
variable `info-lookup-alist'.
@@ -162,7 +174,8 @@ for more details."
(defun info-lookup-add-help* (maybe &rest arg)
(let (topic mode regexp ignore-case doc-spec
- parse-rule other-modes keyword value)
+ parse-rule other-modes keyword value
+ doc-spec-function)
(setq topic 'symbol
mode major-mode
regexp "\\w+")
@@ -185,6 +198,8 @@ for more details."
(setq ignore-case value))
((eq keyword :doc-spec)
(setq doc-spec value))
+ ((eq keyword :doc-spec-function)
+ (setq doc-spec-function value))
((eq keyword :parse-rule)
(setq parse-rule value))
((eq keyword :other-modes)
@@ -192,7 +207,8 @@ for more details."
(t
(error "Unknown keyword \"%S\"" keyword))))
(or (and maybe (info-lookup->mode-value topic mode))
- (let* ((data (list regexp ignore-case doc-spec parse-rule other-modes))
+ (let* ((data (list regexp ignore-case doc-spec parse-rule other-modes
+ doc-spec-function))
(topic-cell (or (assoc topic info-lookup-alist)
(car (setq info-lookup-alist
(cons (cons topic nil)
@@ -262,7 +278,8 @@ system."
(defun info-lookup-symbol (symbol &optional mode)
"Display the definition of SYMBOL, as found in the relevant manual.
When this command is called interactively, it reads SYMBOL from the
-minibuffer. In the minibuffer, use M-n to yank the default argument
+minibuffer. In the minibuffer, use \\<minibuffer-local-completion-map>\
+\\[next-history-element] to yank the default argument
value into the minibuffer so you can edit it. The default symbol is the
one found at point.
@@ -276,7 +293,8 @@ With prefix arg MODE a query for the symbol help mode is offered."
(defun info-lookup-file (file &optional mode)
"Display the documentation of a file.
When this command is called interactively, it reads FILE from the minibuffer.
-In the minibuffer, use M-n to yank the default file name
+In the minibuffer, use \\<minibuffer-local-completion-map>\
+\\[next-history-element] to yank the default file name
into the minibuffer so you can edit it.
The default file name is the one found at point.
@@ -340,11 +358,22 @@ If optional argument QUERY is non-nil, query for the help mode."
(error "No %s help available for `%s'" topic mode))
(setq info-lookup-mode mode)))
+(defun info-lookup--item-to-mode (item mode)
+ (let ((spec (cons mode (car (split-string (if (stringp item)
+ item
+ (symbol-name item))
+ "-")))))
+ (if (assoc spec (cdr (assq 'symbol info-lookup-alist)))
+ spec
+ mode)))
+
(defun info-lookup (topic item mode)
"Display the documentation of a help item."
(or mode (setq mode (info-lookup-select-mode)))
- (or (info-lookup->mode-value topic mode)
- (error "No %s help available for `%s'" topic mode))
+ (setq mode (info-lookup--item-to-mode item mode))
+ (if-let ((info (info-lookup->mode-value topic mode)))
+ (info-lookup--expand-info info)
+ (error "No %s help available for `%s'" topic mode))
(let* ((completions (info-lookup->completions topic mode))
(ignore-case (info-lookup->ignore-case topic mode))
(entry (or (assoc (if ignore-case (downcase item) item) completions)
@@ -723,6 +752,8 @@ Return nil if there is nothing appropriate in the buffer near point."
(defun info-complete (topic mode)
"Try to complete a help item."
(barf-if-buffer-read-only)
+ (when-let ((info (info-lookup->mode-value topic mode)))
+ (info-lookup--expand-info info))
(let ((data (info-lookup-completions-at-point topic mode)))
(if (null data)
(error "No %s completion available for `%s' at point" topic mode)
@@ -905,11 +936,14 @@ Return nil if there is nothing appropriate in the buffer near point."
:mode 'python-mode
;; Debian includes Python info files, but they're version-named
;; instead of having a symlink.
- :doc-spec `((,(cl-loop for version from 20 downto 7
- for name = (format "python3.%d" version)
- if (Info-find-file name t)
- return (format "(%s)Index" name)
- finally return "(python)Index"))))
+ :doc-spec-function (lambda ()
+ (list
+ (list
+ (cl-loop for version from 20 downto 7
+ for name = (format "python3.%d" version)
+ if (Info-find-file name t)
+ return (format "(%s)Index" name)
+ finally return "(python)Index")))))
(info-lookup-maybe-add-help
:mode 'cperl-mode
@@ -947,6 +981,67 @@ Return nil if there is nothing appropriate in the buffer near point."
("(cl)Function Index" nil "^ -+ .*: " "\\( \\|$\\)")
("(cl)Variable Index" nil "^ -+ .*: " "\\( \\|$\\)")))
+(mapc
+ (lambda (elem)
+ (let* ((prefix (car elem)))
+ (info-lookup-add-help
+ :mode (cons 'emacs-lisp-mode prefix)
+ :regexp (concat "\\b" prefix "-[^][()`'‘’,\" \t\n]+")
+ :doc-spec (cl-loop for node in (cdr elem)
+ collect
+ (list (if (string-match-p "^(" node)
+ node
+ (format "(%s)%s" prefix node))
+ nil "^ -+ .*: " "\\( \\|$\\)")))))
+ ;; Below we have a list of prefixes (used to match on symbols in
+ ;; `emacs-lisp-mode') and the nodes where the function/variable
+ ;; indices live. If the prefix is different than the name of the
+ ;; manual, then the full "(manual)Node" name has to be used.
+ '(("auth" "Function Index" "Variable Index")
+ ("autotype" "Command Index" "Variable Index")
+ ("calc" "Lisp Function Index" "Variable Index")
+ ;;("cc-mode" "Variable Index" "Command and Function Index")
+ ("dbus" "Index")
+ ("ediff" "Index")
+ ("eieio" "Function Index")
+ ("gnutls" "(emacs-gnutls)Variable Index" "(emacs-gnutls)Function Index")
+ ("mm" "(emacs-mime)Index")
+ ("epa" "Variable Index" "Function Index")
+ ("ert" "Index")
+ ("eshell" "Function and Variable Index")
+ ("eudc" "Index")
+ ("eww" "Variable Index" "Lisp Function Index")
+ ("flymake" "Index")
+ ("forms" "Index")
+ ("gnus" "Index")
+ ("htmlfontify" "Functions" "Variables & Customization")
+ ("idlwave" "Index")
+ ("ido" "Variable Index" "Function Index")
+ ("info" "Index")
+ ("mairix" "(mairix-el)Variable Index" "(mairix-el)Function Index")
+ ("message" "Index")
+ ("mh" "(mh-e)Option Index" "(mh-e)Command Index")
+ ("newsticker" "Index")
+ ("octave" "(octave-mode)Variable Index" "(octave-mode)Lisp Function Index")
+ ("org" "Variable Index" "Command and Function Index")
+ ("pgg" "Variable Index" "Function Index")
+ ("rcirc" "Variable Index" "Index")
+ ("reftex" "Index")
+ ("sasl" "Variable Index" "Function Index")
+ ("sc" "Variable Index")
+ ("semantic" "Index")
+ ("ses" "Index")
+ ("sieve" "Index")
+ ("smtpmail" "Function and Variable Index")
+ ("srecode" "Index")
+ ("tramp" "Variable Index" "Function Index")
+ ("url" "Variable Index" "Function Index")
+ ("vhdl" "(vhdl-mode)Variable Index" "(vhdl-mode)Command Index")
+ ("viper" "Variable Index" "Function Index")
+ ("widget" "Index")
+ ("wisent" "Index")
+ ("woman" "Variable Index" "Command Index")))
+
;; docstrings talk about elisp, so have apropos-mode follow emacs-lisp-mode
(info-lookup-maybe-add-help
:mode 'apropos-mode
diff --git a/lisp/info-xref.el b/lisp/info-xref.el
index e2e3e30ca21..f791927ee1d 100644
--- a/lisp/info-xref.el
+++ b/lisp/info-xref.el
@@ -242,18 +242,18 @@ buffer's line and column of point."
node t t))
(if (not (string-match "\\`([^)]*)" node))
- (info-xref-output-error "no `(file)' part at start of node: %s\n" node)
+ (info-xref-output-error "No `(file)' part at start of node: %s\n" node)
(let ((file (match-string 0 node)))
(if (string-equal "()" file)
- (info-xref-output-error "empty filename part: %s" node)
+ (info-xref-output-error "Empty filename part: %s" node)
;; see if the file exists, if haven't looked before
(unless (assoc file info-xref-xfile-alist)
(let ((found (info-xref-goto-node-p file)))
(push (cons file found) info-xref-xfile-alist)
(unless found
- (info-xref-output-error "not available to check: %s\n (this reported once per file)" file))))
+ (info-xref-output-error "Not available to check: %s\n (this reported once per file)" file))))
;; if the file exists, try the node
(cond ((not (cdr (assoc file info-xref-xfile-alist)))
@@ -262,7 +262,7 @@ buffer's line and column of point."
(cl-incf info-xref-good))
(t
(cl-incf info-xref-bad)
- (info-xref-output-error "no such node: %s" node)))))))
+ (info-xref-output-error "No such node: %s" node)))))))
;;-----------------------------------------------------------------------------
diff --git a/lisp/info.el b/lisp/info.el
index e6b5f3e5a7c..559460e8d2c 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -115,7 +115,9 @@ The Lisp code is executed when the node is selected.")
(defface info-menu-star
'((((class color)) :foreground "red1")
(t :underline t))
- "Face for every third `*' in an Info menu.")
+ "Face used to emphasize `*' in an Info menu.
+The face is assigned to the third, sixth, and ninth `*' for easier
+orientation. See `Info-nth-menu-item'.")
(defface info-xref
'((t :inherit link))
@@ -1455,6 +1457,7 @@ is non-nil)."
(defvar Info-streamline-headings
'(("Emacs" . "Emacs")
("Software development\\|Programming" . "Software development")
+ ("Compression\\|Data Compression" . "Compression")
("Libraries" . "Libraries")
("Network applications\\|World Wide Web\\|Net Utilities"
. "Network applications"))
@@ -1731,22 +1734,26 @@ escaped (\\\",\\\\)."
(list
(concat
" ("
- (if (stringp Info-current-file)
- (string-replace
- "%" "%%"
- (file-name-sans-extension
- (file-name-nondirectory Info-current-file)))
- (format "*%S*" Info-current-file))
- ") "
- (if Info-current-node
- (propertize (string-replace
- "%" "%%" Info-current-node)
- 'face 'mode-line-buffer-id
- 'help-echo
- "mouse-1: scroll forward, mouse-3: scroll back"
- 'mouse-face 'mode-line-highlight
- 'local-map Info-mode-line-node-keymap)
- ""))))))
+ (propertize
+ (if (stringp Info-current-file)
+ (string-replace
+ "%" "%%"
+ ;; Remove trailing ".info" and ".info.gz", etc.
+ (replace-regexp-in-string
+ "\\..*\\'" ""
+ (file-name-nondirectory Info-current-file)))
+ (format "*%S*" Info-current-file))
+ 'help-echo "Manual name")
+ ") ")
+ (if Info-current-node
+ (propertize (string-replace
+ "%" "%%" Info-current-node)
+ 'face 'mode-line-buffer-id
+ 'help-echo
+ "mouse-1: scroll forward, mouse-3: scroll back"
+ 'mouse-face 'mode-line-highlight
+ 'local-map Info-mode-line-node-keymap)
+ "")))))
;; Go to an Info node specified with a filename-and-nodename string
;; of the sort that is found in pointers in nodes.
@@ -1787,7 +1794,46 @@ of NODENAME; if none is found it then tries a case-insensitive match
(if trim (setq nodename (substring nodename 0 trim))))
(if transient-mark-mode (deactivate-mark))
(Info-find-node (if (equal filename "") nil filename)
- (if (equal nodename "") "Top" nodename) nil strict-case)))
+ (if (equal nodename "") "Top" nodename) nil strict-case)))
+
+(defun Info-goto-node-web (node)
+ "Use `browse-url' to go to the gnu.org web server's version of NODE.
+By default, go to the current Info node."
+ (interactive (list (Info-read-node-name
+ "Go to node (default current page): " Info-current-node))
+ Info-mode)
+ (browse-url-button-open-url
+ (Info-url-for-node (format "(%s)%s" (file-name-sans-extension
+ (file-name-nondirectory
+ Info-current-file))
+ node))))
+
+(defun Info-url-for-node (node)
+ "Return a URL for NODE, a node in the GNU Emacs or Elisp manual.
+NODE should be a string on the form \"(manual)Node\". Only emacs
+and elisp manuals are supported."
+ (unless (string-match "\\`(\\(.+\\))\\(.+\\)\\'" node)
+ (error "Invalid node name %s" node))
+ (let ((manual (match-string 1 node))
+ (node (match-string 2 node)))
+ (unless (member manual '("emacs" "elisp"))
+ (error "Only emacs/elisp manuals are supported"))
+ ;; Encode a bunch of characters the way that makeinfo does.
+ (setq node
+ (mapconcat (lambda (ch)
+ (if (or (< ch 32) ; ^@^A-^Z^[^\^]^^^-
+ (<= 33 ch 47) ; !"#$%&'()*+,-./
+ (<= 58 ch 64) ; :;<=>?@
+ (<= 91 ch 96) ; [\]_`
+ (<= 123 ch 127)) ; {|}~ DEL
+ (format "_00%x" ch)
+ (char-to-string ch)))
+ node
+ ""))
+ (concat "https://www.gnu.org/software/emacs/manual/html_node/"
+ manual "/"
+ (url-hexify-string (string-replace " " "-" node))
+ ".html")))
(defvar Info-read-node-completion-table)
@@ -1872,7 +1918,7 @@ See `completing-read' for a description of arguments and usage."
code Info-read-node-completion-table string predicate))))
;; Arrange to highlight the proper letters in the completion list buffer.
-(defun Info-read-node-name (prompt)
+(defun Info-read-node-name (prompt &optional default)
"Read an Info node name with completion, prompting with PROMPT.
A node name can have the form \"NODENAME\", referring to a node
in the current Info file, or \"(FILENAME)NODENAME\", referring to
@@ -1880,7 +1926,8 @@ a node in FILENAME. \"(FILENAME)\" is a short format to go to
the Top node in FILENAME."
(let* ((completion-ignore-case t)
(Info-read-node-completion-table (Info-build-node-completions))
- (nodename (completing-read prompt #'Info-read-node-name-1 nil t)))
+ (nodename (completing-read prompt #'Info-read-node-name-1 nil t nil
+ 'Info-minibuf-history default)))
(if (equal nodename "")
(Info-read-node-name prompt)
nodename)))
@@ -2599,12 +2646,9 @@ new buffer."
(if (eq (length completions) 1)
(setq default (car completions)))
(if completions
- (let ((input (completing-read (if default
- (concat
- "Follow reference named (default "
- default "): ")
- "Follow reference named: ")
- completions nil t)))
+ (let ((input (completing-read (format-prompt "Follow reference named"
+ default)
+ completions nil t)))
(list (if (equal input "")
default input)
current-prefix-arg))
@@ -4044,6 +4088,7 @@ If FORK is non-nil, it is passed to `Info-goto-node'."
(define-key map "e" 'end-of-buffer)
(define-key map "f" 'Info-follow-reference)
(define-key map "g" 'Info-goto-node)
+ (define-key map "G" 'Info-goto-node-web)
(define-key map "h" 'Info-help)
;; This is for compatibility with standalone info (>~ version 5.2).
;; Though for some time, standalone info had H and h reversed.
@@ -4146,7 +4191,8 @@ If FORK is non-nil, it is passed to `Info-goto-node'."
"---"
["Exit" quit-window :help "Stop reading Info"]))
-(defun Info-context-menu (menu)
+(defun Info-context-menu (menu click)
+ "Populate MENU with Info commands at CLICK."
(define-key menu [Info-separator] menu-bar-separator)
(let ((easy-menu (make-sparse-keymap "Info")))
(easy-menu-define nil easy-menu nil
@@ -4159,7 +4205,7 @@ If FORK is non-nil, it is passed to `Info-goto-node'."
(when (consp item)
(define-key menu (vector (car item)) (cdr item)))))
- (when (mouse-posn-property (event-start last-input-event) 'mouse-face)
+ (when (mouse-posn-property (event-start click) 'mouse-face)
(define-key menu [Info-mouse-follow-nearest-node]
'(menu-item "Follow Link" Info-mouse-follow-nearest-node
:help "Follow a link where you click")))
@@ -4852,9 +4898,16 @@ first line or header line, and for breadcrumb links.")
;; an end of sentence
(skip-syntax-backward " ("))
(setq other-tag
- (cond ((save-match-data (looking-back "\\(^\\| \\)see"
+ (cond ((save-match-data (looking-back "\\(^\\|[ (]\\)see"
(- (point) 4)))
"")
+ ;; We want "Also *note" to produce
+ ;; "Also see", but "See also *note" to produce
+ ;; "See also", so match case-sensitively.
+ ((save-match-data (let ((case-fold-search nil))
+ (looking-back "\\(^\\| \\)also"
+ (- (point) 5))))
+ "")
((save-match-data (looking-back "\\(^\\| \\)in"
(- (point) 3)))
"")
diff --git a/lisp/informat.el b/lisp/informat.el
index bac09752b70..b552e8532aa 100644
--- a/lisp/informat.el
+++ b/lisp/informat.el
@@ -446,7 +446,7 @@ Check that every node pointer points to an existing node."
;;;###autoload
(defun batch-info-validate ()
- "Runs `Info-validate' on the files remaining on the command line.
+ "Run `Info-validate' on the files remaining on the command line.
Must be used only with -batch, and kills Emacs on completion.
Each file will be processed even if an error occurred previously.
For example, invoke \"emacs -batch -f batch-info-validate $info/ ~/*.info\""
diff --git a/lisp/international/ccl.el b/lisp/international/ccl.el
index 0eb009fa526..883b0b60fc9 100644
--- a/lisp/international/ccl.el
+++ b/lisp/international/ccl.el
@@ -213,8 +213,7 @@ proper index number for SYMBOL. PROP should be
(ccl-embed-data (cons symbol prop)))
(defun ccl-embed-string (len str)
- "Embed string STR of length LEN in `ccl-program-vector' at
-`ccl-current-ic'."
+ "Embed string STR of length LEN in `ccl-program-vector' at `ccl-current-ic'."
(if (> len #xFFFFF)
(error "CCL: String too long: %d" len))
(if (> (string-bytes str) len)
@@ -282,8 +281,7 @@ changed to a relative jump address."
(defvar ccl-loop-head nil
"If non-nil, index of the start of the current loop.")
(defvar ccl-breaks nil
- "If non-nil, list of absolute addresses of the breaking points of
-the current loop.")
+ "If non-nil, list of absolute addresses of breaking points of the current loop.")
;;;###autoload
(defun ccl-compile (ccl-program)
@@ -512,7 +510,7 @@ If READ-FLAG is non-nil, this statement has the form
(arg (nth 2 condition)))
(ccl-check-register rrr cmd)
(or (integerp op)
- (error "CCL: invalid operator: %s" (nth 1 condition)))
+ (error "CCL: Invalid operator: %s" (nth 1 condition)))
(if (integerp arg)
(progn
(ccl-embed-code (if read-flag 'read-jump-cond-expr-const
@@ -568,8 +566,8 @@ If READ-FLAG is non-nil, this statement has the form
(cdr (cdr cmd))))
(defun ccl-compile-branch-expression (expr cmd)
- "Compile EXPRESSION part of BRANCH statement and return register
-which holds a value of the expression."
+ "Compile EXPRESSION part of BRANCH statement.
+Return register which holds a value of the expression."
(if (listp expr)
;; EXPR has the form `(EXPR2 OP ARG)'. Compile it as SET
;; statement of the form `(r7 = (EXPR2 OP ARG))'.
@@ -864,7 +862,7 @@ is a list of CCL-BLOCKs."
rrr RRR 0)
(ccl-embed-symbol Rrr 'translation-hash-table-id))
(t
- (error "CCL: non-constant table: %s" cmd)
+ (error "CCL: Non-constant table: %s" cmd)
;; not implemented:
(ccl-check-register Rrr cmd)
(ccl-embed-extended-command 'lookup-int rrr RRR 0))))
@@ -884,7 +882,7 @@ is a list of CCL-BLOCKs."
rrr RRR 0)
(ccl-embed-symbol Rrr 'translation-hash-table-id))
(t
- (error "CCL: non-constant table: %s" cmd)
+ (error "CCL: Non-constant table: %s" cmd)
;; not implemented:
(ccl-check-register Rrr cmd)
(ccl-embed-extended-command 'lookup-char rrr RRR 0))))
@@ -1554,9 +1552,8 @@ MAP :=
MAP-IDs := MAP-ID ...
MAP-SET := MAP-IDs | (MAP-IDs) MAP-SET
-MAP-ID := integer
-"
- (declare (doc-string 3))
+MAP-ID := integer"
+ (declare (doc-string 3) (indent defun))
`(let ((prog ,(unwind-protect
(progn
;; To make ,(charset-id CHARSET) works well.
diff --git a/lisp/international/characters.el b/lisp/international/characters.el
index 97bf31acfc3..a2156ee01aa 100644
--- a/lisp/international/characters.el
+++ b/lisp/international/characters.el
@@ -116,11 +116,11 @@ Base characters (Unicode General Category L,N,P,S,Zs)")
Combining diacritic or mark (Unicode General Category M)")
;; bidi types
-(define-category ?R "Right-to-left (strong)
+(define-category ?R "Strong R2L
Characters with \"strong\" right-to-left directionality, i.e.
with R, AL, RLE, or RLO Unicode bidi character type.")
-(define-category ?L "Left-to-right (strong)
+(define-category ?L "Strong L2R
Characters with \"strong\" left-to-right directionality, i.e.
with L, LRE, or LRO Unicode bidi character type.")
@@ -214,6 +214,9 @@ with L, LRE, or LRO Unicode bidi character type.")
(modify-category-entry '(#x31F0 . #x31FF) ?K)
(modify-category-entry '(#x30A0 . #x30FA) ?\|)
(modify-category-entry #x30FF ?\|)
+(modify-category-entry '(#x1AFF0 . #x1B000) ?K)
+(modify-category-entry '(#x1B120 . #x1B122) ?K)
+(modify-category-entry '(#x1B164 . #x1B167) ?K)
;; Hiragana block
(modify-category-entry '(#x3040 . #x309F) ?H)
@@ -221,8 +224,12 @@ with L, LRE, or LRO Unicode bidi character type.")
(modify-category-entry #x309F ?\|)
(modify-category-entry #x30A0 ?H)
(modify-category-entry #x30FC ?H)
+(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 '(#x1B000 . #x1B1FF) ?j)
+(modify-category-entry '(#x1AFF0 . #x1B1FF) ?j)
;; JISX0208
@@ -295,7 +302,7 @@ with L, LRE, or LRO Unicode bidi character type.")
(map-charset-chars #'modify-category-entry (car charsets) ?b)
(setq charsets (cdr charsets))))
(modify-category-entry '(#x600 . #x6ff) ?b)
-(modify-category-entry '(#x8a0 . #x8ff) ?b)
+(modify-category-entry '(#x870 . #x8ff) ?b)
(modify-category-entry '(#xfb50 . #xfdff) ?b)
(modify-category-entry '(#xfe70 . #xfefe) ?b)
@@ -306,7 +313,9 @@ with L, LRE, or LRO Unicode bidi character type.")
;; Ethiopic character set
(modify-category-entry '(#x1200 . #x1399) ?e)
-(modify-category-entry '(#x2d80 . #x2dde) ?e)
+(modify-category-entry '(#X2D80 . #X2DDE) ?e)
+(modify-category-entry '(#xAB01 . #xAB2E) ?e)
+(modify-category-entry '(#x1E7E0 . #x1E7FE) ?e)
(let ((chars '(?፡ ?። ?፣ ?፤ ?፥ ?፦ ?፧ ?፨)))
(while chars
(modify-syntax-entry (car chars) ".")
@@ -580,6 +589,12 @@ with L, LRE, or LRO Unicode bidi character type.")
(modify-category-entry c ?l)
(setq c (1+ c)))
+ ;; Latin Extended-G
+ (setq c #x1DF00)
+ (while (<= c #x1DFFF)
+ (modify-category-entry c ?l)
+ (setq c (1+ c)))
+
;; Greek
(modify-category-entry '(#x0370 . #x03FF) ?g)
@@ -1016,7 +1031,7 @@ with L, LRE, or LRO Unicode bidi character type.")
(#x0D41 . #x0D44)
(#x0D4D . #x0D4D)
(#x0D62 . #x0D63)
- (#x0D81 . #x0D81)
+ (#x0D81 . #x0D81)
(#x0DCA . #x0DCA)
(#x0DD2 . #x0DD6)
(#x0E31 . #x0E31)
@@ -1045,7 +1060,7 @@ with L, LRE, or LRO Unicode bidi character type.")
(#x1085 . #x1086)
(#x108D . #x108D)
(#x109D . #x109D)
- (#x1160 . #x11FF)
+ (#x1160 . #x11FF)
(#x135D . #x135F)
(#x1712 . #x1714)
(#x1732 . #x1734)
@@ -1111,7 +1126,7 @@ with L, LRE, or LRO Unicode bidi character type.")
(#xA806 . #xA806)
(#xA80B . #xA80B)
(#xA825 . #xA826)
- (#xA82C . #xA82C)
+ (#xA82C . #xA82C)
(#xA8C4 . #xA8C5)
(#xA8E0 . #xA8F1)
(#xA926 . #xA92D)
@@ -1136,7 +1151,7 @@ with L, LRE, or LRO Unicode bidi character type.")
(#xABE5 . #xABE5)
(#xABE8 . #xABE8)
(#xABED . #xABED)
- (#xD7B0 . #xD7FB)
+ (#xD7B0 . #xD7FB)
(#xFB1E . #xFB1E)
(#xFE00 . #xFE0F)
(#xFE20 . #xFE2F)
@@ -1148,7 +1163,7 @@ with L, LRE, or LRO Unicode bidi character type.")
(#x10A01 . #x10A0F)
(#x10A38 . #x10A3F)
(#x10AE5 . #x10AE6)
- (#x10EAB . #x10EAC)
+ (#x10EAB . #x10EAC)
(#x11001 . #x11001)
(#x11038 . #x11046)
(#x1107F . #x11081)
@@ -1162,7 +1177,7 @@ with L, LRE, or LRO Unicode bidi character type.")
(#x11180 . #x11181)
(#x111B6 . #x111BE)
(#x111CA . #x111CC)
- (#x111CF . #x111CF)
+ (#x111CF . #x111CF)
(#x1122F . #x11231)
(#x11234 . #x11234)
(#x11236 . #x11237)
@@ -1194,9 +1209,9 @@ with L, LRE, or LRO Unicode bidi character type.")
(#x1171D . #x1171F)
(#x11722 . #x11725)
(#x11727 . #x1172B)
- (#x1193B . #x1193C)
- (#x1193E . #x1193E)
- (#x11943 . #x11943)
+ (#x1193B . #x1193C)
+ (#x1193E . #x1193E)
+ (#x11943 . #x11943)
(#x11C30 . #x11C36)
(#x11C38 . #x11C3D)
(#x11C92 . #x11CA7)
@@ -1206,7 +1221,7 @@ with L, LRE, or LRO Unicode bidi character type.")
(#x16AF0 . #x16AF4)
(#x16B30 . #x16B36)
(#x16F8F . #x16F92)
- (#x16FE4 . #x16FE4)
+ (#x16FE4 . #x16FE4)
(#x1BC9D . #x1BC9E)
(#x1BCA0 . #x1BCA3)
(#x1D167 . #x1D169)
@@ -1280,18 +1295,19 @@ with L, LRE, or LRO Unicode bidi character type.")
(#xFF01 . #xFF60)
(#xFFE0 . #xFFE6)
(#x16FE0 . #x16FE4)
- (#x16FF0 . #x16FF1)
+ (#x16FF0 . #x16FF1)
(#x17000 . #x187F7)
(#x18800 . #x18AFF)
- (#x18B00 . #x18CD5)
+ (#x18B00 . #x18CD5)
+ (#x1AFF0 . #x1AFFF)
(#x1B000 . #x1B152)
- (#x1B164 . #x1B167)
- (#x1B170 . #x1B2FB)
+ (#x1B164 . #x1B167)
+ (#x1B170 . #x1B2FB)
(#x1F004 . #x1F004)
(#x1F0CF . #x1F0CF)
(#x1F18E . #x1F18E)
(#x1F191 . #x1F19A)
- (#x1F1AD . #x1F1AD)
+ (#x1F1AD . #x1F1AD)
(#x1F200 . #x1F320)
(#x1F32D . #x1F335)
(#x1F337 . #x1F37C)
@@ -1316,27 +1332,26 @@ with L, LRE, or LRO Unicode bidi character type.")
(#x1F680 . #x1F6C5)
(#x1F6CC . #x1F6CC)
(#x1F6D0 . #x1F6D2)
- (#x1F6D5 . #x1F6D7)
+ (#x1F6D5 . #x1F6D7)
+ (#x1F6DD . #x1F6DF)
(#x1F6EB . #x1F6EC)
(#x1F6F4 . #x1F6FC)
- (#x1F7E0 . #x1F7EB)
+ (#x1F7E0 . #x1F7F0)
(#x1F90C . #x1F93A)
- (#x1F93C . #x1F945)
- (#x1F947 . #x1F978)
- (#x1F97A . #x1F9CB)
- (#x1F9A5 . #x1F9AA)
- (#x1F9AE . #x1F9CA)
- (#x1F9CD . #x1F9FF)
- (#x1FA00 . #x1FA53)
- (#x1FA60 . #x1FA6D)
- (#x1FA70 . #x1FA74)
- (#x1FA78 . #x1FA7A)
- (#x1FA80 . #x1FA86)
- (#x1FA90 . #x1FAA8)
- (#x1FAB0 . #x1FAB6)
- (#x1FAC0 . #x1FAC2)
- (#x1FAD0 . #x1FAD6)
- (#x1FB00 . #x1FB92)
+ (#x1F93C . #x1F945)
+ (#x1F947 . #x1F9FF)
+ (#x1FA00 . #x1FA53)
+ (#x1FA60 . #x1FA6D)
+ (#x1FA70 . #x1FA74)
+ (#x1FA78 . #x1FA7C)
+ (#x1FA80 . #x1FA86)
+ (#x1FA90 . #x1FAAC)
+ (#x1FAB0 . #x1FABA)
+ (#x1FAC0 . #x1FAC5)
+ (#x1FAD0 . #x1FAD9)
+ (#x1FAE0 . #x1FAE7)
+ (#x1FAF0 . #x1FAF6)
+ (#x1FB00 . #x1FB92)
(#x20000 . #x2FFFF)
(#x30000 . #x3FFFF))))
(dolist (elt l)
@@ -1401,7 +1416,7 @@ with L, LRE, or LRO Unicode bidi character type.")
(defun use-default-char-width-table ()
"Internal use only.
-Setup char-width-table appropriate for non-CJK language environment."
+Setup `char-width-table' appropriate for non-CJK language environment."
(while (char-table-parent char-width-table)
(setq char-width-table (char-table-parent char-width-table))))
@@ -1413,8 +1428,12 @@ Setup char-width-table appropriate for non-CJK language environment."
(if dump-mode
;; While dumping, we can't use require, and international is not
;; in load-path.
- (load "international/charscript")
- (require 'charscript))
+ (progn
+ (load "international/charscript")
+ (load "international/emoji-zwj"))
+ (progn
+ (require 'charscript)
+ (require 'emoji-zwj)))
(map-charset-chars
(lambda (range _ignore)
@@ -1474,6 +1493,9 @@ Setup char-width-table appropriate for non-CJK language environment."
(aset char-acronym-table #x202D "LRO") ; LEFT-TO-RIGHT OVERRIDE
(aset char-acronym-table #x202E "RLO") ; RIGHT-TO-LEFT OVERRIDE
(aset char-acronym-table #x2060 "WJ") ; WORD JOINER
+(aset char-acronym-table #x2066 "LRI") ; LEFT-TO-RIGHT ISOLATE
+(aset char-acronym-table #x2067 "RLI") ; RIGHT-TO-LEFT ISOLATE
+(aset char-acronym-table #x2069 "PDI") ; POP DIRECTIONAL ISOLATE
(aset char-acronym-table #x206A "ISS") ; INHIBIT SYMMETRIC SWAPPING
(aset char-acronym-table #x206B "ASS") ; ACTIVATE SYMMETRIC SWAPPING
(aset char-acronym-table #x206C "IAFS") ; INHIBIT ARABIC FORM SHAPING
@@ -1498,18 +1520,32 @@ Setup char-width-table appropriate for non-CJK language environment."
(aset char-acronym-table (+ #xE0021 i) (format " %c TAG" (+ 33 i))))
(aset char-acronym-table #xE007F "->|TAG") ; CANCEL TAG
+;; We can't use the \N{name} things here, because this file is used
+;; too early in the build process.
+(defvar glyphless--bidi-control-characters
+ '(#x202a ; ?\N{left-to-right embedding}
+ #x202b ; ?\N{right-to-left embedding}
+ #x202d ; ?\N{left-to-right override}
+ #x202e ; ?\N{right-to-left override}
+ #x2066 ; ?\N{left-to-right isolate}
+ #x2067 ; ?\N{right-to-left isolate}
+ #x2068 ; ?\N{first strong isolate}
+ #x202c ; ?\N{pop directional formatting}
+ #x2069)) ; ?\N{pop directional isolate})
+
(defun update-glyphless-char-display (&optional variable value)
"Make the setting of `glyphless-char-display-control' take effect.
This function updates the char-table `glyphless-char-display',
and is intended to be used in the `:set' attribute of the
option `glyphless-char-display'."
- (when value
+ (when variable
(set-default variable value))
(dolist (elt value)
(let ((target (car elt))
(method (cdr elt)))
- (or (memq method '(zero-width thin-space empty-box acronym hex-code))
- (error "Invalid glyphless character display method: %s" method))
+ (unless (memq method '( zero-width thin-space empty-box
+ acronym hex-code bidi-control))
+ (error "Invalid glyphless character display method: %s" method))
(cond ((eq target 'c0-control)
(glyphless-set-char-table-range glyphless-char-display
#x00 #x1F method)
@@ -1521,24 +1557,32 @@ option `glyphless-char-display'."
((eq target 'c1-control)
(glyphless-set-char-table-range glyphless-char-display
#x80 #x9F method))
- ((eq target 'format-control)
+ ((eq target 'variation-selectors)
+ (glyphless-set-char-table-range glyphless-char-display
+ #xFE00 #xFE0F method))
+ ((or (eq target 'format-control)
+ (eq target 'bidi-control))
(when unicode-category-table
(map-char-table
(lambda (char category)
- (if (eq category 'Cf)
- (let ((this-method method)
- from to)
- (if (consp char)
- (setq from (car char) to (cdr char))
- (setq from char to char))
- (while (<= from to)
- (when (/= from #xAD)
- (if (eq method 'acronym)
- (setq this-method
- (aref char-acronym-table from)))
+ (when (eq category 'Cf)
+ (let ((this-method method)
+ from to)
+ (if (consp char)
+ (setq from (car char) to (cdr char))
+ (setq from char to char))
+ (while (<= from to)
+ (when (/= from #xAD)
+ (when (eq method 'acronym)
+ (setq this-method
+ (or (aref char-acronym-table from)
+ "UNK")))
+ (when (or (eq target 'format-control)
+ (memq from
+ glyphless--bidi-control-characters))
(set-char-table-range glyphless-char-display
- from this-method))
- (setq from (1+ from))))))
+ from this-method)))
+ (setq from (1+ from))))))
unicode-category-table)))
((eq target 'no-font)
(set-char-table-extra-slot glyphless-char-display 0 method))
@@ -1554,8 +1598,22 @@ option `glyphless-char-display'."
(set-char-table-range chartable (cons from to) method)))
;;; Control of displaying glyphless characters.
+(define-widget 'glyphless-char-display-method 'lazy
+ "Display method for glyphless characters."
+ :group 'mule
+ :format "%v"
+ :value 'thin-space
+ :type
+ '(choice
+ (const :tag "Don't display" zero-width)
+ (const :tag "Display as thin space" thin-space)
+ (const :tag "Display as empty box" empty-box)
+ (const :tag "Display acronym" acronym)
+ (const :tag "Display hex code in a box" hex-code)))
+
(defcustom glyphless-char-display-control
'((format-control . thin-space)
+ (variation-selectors . thin-space)
(no-font . hex-code))
"List of directives to control display of glyphless characters.
@@ -1571,9 +1629,17 @@ GROUP must be one of these symbols:
such as U+200C (ZWNJ), U+200E (LRM), but
excluding characters that have graphic images,
such as U+00AD (SHY).
- `no-font': characters for which no suitable font is found.
- For character terminals, characters that cannot
- be encoded by `terminal-coding-system'.
+ `bidi-control': A subset of `format-control', but only characters
+ that are relevant for bidirectional formatting control,
+ like U+2069 (PDI) and U+202B (RLE).
+ `variation-selectors':
+ Characters in the range U+FE00..U+FE0F, used for
+ selecting alternate glyph presentations, such as
+ Emoji vs Text presentation, of the preceding
+ character(s).
+ `no-font': For GUI frames, characters for which no suitable
+ font is found; for text-mode frames, characters
+ that cannot be encoded by `terminal-coding-system'.
METHOD must be one of these symbols:
`zero-width': don't display.
@@ -1588,33 +1654,15 @@ Do not set its value directly from Lisp; the value takes effect
only via a custom `:set'
function (`update-glyphless-char-display'), which updates
`glyphless-char-display'."
- :version "24.1"
+ :version "28.1"
:type '(alist :key-type (symbol :tag "Character Group")
:value-type (symbol :tag "Display Method"))
- :options '((c0-control
- (choice (const :tag "Don't display" zero-width)
- (const :tag "Display as thin space" thin-space)
- (const :tag "Display as empty box" empty-box)
- (const :tag "Display acronym" acronym)
- (const :tag "Display hex code in a box" hex-code)))
- (c1-control
- (choice (const :tag "Don't display" zero-width)
- (const :tag "Display as thin space" thin-space)
- (const :tag "Display as empty box" empty-box)
- (const :tag "Display acronym" acronym)
- (const :tag "Display hex code in a box" hex-code)))
- (format-control
- (choice (const :tag "Don't display" zero-width)
- (const :tag "Display as thin space" thin-space)
- (const :tag "Display as empty box" empty-box)
- (const :tag "Display acronym" acronym)
- (const :tag "Display hex code in a box" hex-code)))
- (no-font
- (choice (const :tag "Don't display" zero-width)
- (const :tag "Display as thin space" thin-space)
- (const :tag "Display as empty box" empty-box)
- (const :tag "Display acronym" acronym)
- (const :tag "Display hex code in a box" hex-code))))
+ :options '((c0-control glyphless-char-display-method)
+ (c1-control glyphless-char-display-method)
+ (format-control glyphless-char-display-method)
+ (bidi-control glyphless-char-display-method)
+ (variation-selectors glyphless-char-display-method)
+ (no-font (glyphless-char-display-method :value hex-code)))
:set 'update-glyphless-char-display
:group 'display)
diff --git a/lisp/international/emoji.el b/lisp/international/emoji.el
new file mode 100644
index 00000000000..1202571b320
--- /dev/null
+++ b/lisp/international/emoji.el
@@ -0,0 +1,657 @@
+;;; emoji.el --- Inserting emojis -*- lexical-binding:t -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Lars Ingebrigtsen <larsi@gnus.org>
+;; Keywords: fun
+
+;; Package-Requires: ((emacs "28.0") (transient "0.3.7"))
+;; Package-Version: 0.1
+
+;; 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 'cl-lib)
+(require 'cl-extra)
+(require 'transient)
+(require 'multisession)
+
+(defgroup emoji nil
+ "Inserting Emojis."
+ :version "29.1"
+ :group 'play)
+
+(defface emoji-list-header
+ '((default :weight bold :inherit variable-pitch))
+ "Face for emoji list headers."
+ :version "29.1")
+
+(defface emoji
+ '((t :height 2.0))
+ "Face used when displaying an emoji."
+ :version "29.1")
+
+(defface emoji-with-derivations
+ '((((background dark))
+ (:background "#202020" :inherit emoji))
+ (((background light))
+ (:background "#e0e0e0" :inherit emoji)))
+ "Face for emojis that have derivations."
+ :version "29.1")
+
+(defvar emoji--labels nil)
+(defvar emoji--all-bases nil)
+(defvar emoji--derived nil)
+(defvar emoji--names (make-hash-table :test #'equal))
+(defvar emoji--done-derived nil)
+(define-multisession-variable emoji--recent (list "😀" "😖"))
+(defvar emoji--insert-buffer)
+
+;;;###autoload
+(defun emoji-insert (&optional text)
+ "Choose and insert an emoji glyph.
+If TEXT (interactively, the prefix argument), choose the emoji
+by typing its Unicode Standard name (with completion), instead
+of selecting from emoji display."
+ (interactive "*P")
+ (emoji--init)
+ (if text
+ (emoji--choose-emoji)
+ (unless (fboundp 'emoji--command-Emoji)
+ (emoji--define-transient))
+ (funcall (intern "emoji--command-Emoji"))))
+
+;;;###autoload
+(defun emoji-recent ()
+ "Choose and insert one of the recently-used emoji glyphs."
+ (interactive "*")
+ (emoji--init)
+ (unless (fboundp 'emoji--command-Emoji)
+ (emoji--define-transient))
+ (funcall (emoji--define-transient
+ (cons "Recent" (multisession-value emoji--recent)) t)))
+
+;;;###autoload
+(defun emoji-search ()
+ "Choose and insert an emoji glyph by typing its Unicode name.
+This command prompts for an emoji name, with completion, and inserts it.
+It recognizes the Unicode Standard names of emoji."
+ (interactive "*")
+ (emoji--init)
+ (emoji--choose-emoji))
+
+;;;###autoload
+(defun emoji-list ()
+ "List emojis and insert the one that's selected.
+Select the emoji by typing \\<emoji-list-mode-map>\\[emoji-list-select] on its picture.
+The glyph will be inserted into the buffer that was current
+when the command was invoked."
+ (interactive "*")
+ (let ((buf (current-buffer)))
+ (emoji--init)
+ (switch-to-buffer (get-buffer-create "*Emoji*"))
+ ;; Don't regenerate the buffer if it already exists -- this will
+ ;; leave point where it was the last time it was used.
+ (when (zerop (buffer-size))
+ (let ((inhibit-read-only t))
+ (emoji-list-mode)
+ (setq-local emoji--insert-buffer buf)
+ (emoji--list-generate nil (cons nil emoji--labels))
+ (goto-char (point-min))))))
+
+;;;###autoload
+(defun emoji-describe (glyph &optional interactive)
+ "Display the name of the grapheme cluster composed from GLYPH.
+GLYPH should be a string of one or more characters which together
+produce an emoji. Interactively, GLYPH is the emoji at point (it
+could also be any character, not just emoji).
+
+If called from Lisp, return the name as a string; return nil if
+the name is not known."
+ (interactive
+ (list (if (eobp)
+ (error "No glyph under point")
+ (let ((comp (find-composition (point) (1+ (point)))))
+ (if comp
+ (buffer-substring-no-properties (car comp) (cadr comp))
+ (buffer-substring-no-properties (point) (1+ (point))))))
+ t))
+ (require 'emoji-labels)
+ (if (not interactive)
+ ;; Don't return a name for non-compositions when called
+ ;; non-interactively.
+ (gethash glyph emoji--names)
+ ;; Give a name for (pretty much) any glyph, including non-emojis.
+ (let ((name (emoji--name glyph)))
+ (if (not name)
+ (message "No known name for \"%s\"" glyph)
+ (message "The name of \"%s\" is \"%s\"" glyph name)))))
+
+(defun emoji--list-generate (name alist)
+ (let ((width (/ (window-width) 5))
+ (mname (pop alist)))
+ (if (consp (car alist))
+ ;; Recurse.
+ (mapcar (lambda (elem)
+ (emoji--list-generate (if name
+ (concat name " > " mname)
+ mname)
+ elem))
+ alist)
+ ;; Output this block of emojis.
+ (insert (propertize
+ (if (zerop (length name))
+ mname
+ (concat name " > " mname))
+ 'face 'emoji-list-header)
+ "\n\n")
+ (cl-loop for i from 0
+ for glyph in alist
+ do
+ (when (and (cl-plusp i)
+ (zerop (mod i width)))
+ (insert "\n"))
+ (insert
+ (propertize
+ (emoji--fontify-glyph glyph)
+ 'emoji-glyph glyph
+ 'help-echo (emoji--name glyph))))
+ (insert "\n\n"))))
+
+(defun emoji--fontify-glyph (glyph &optional inhibit-derived)
+ (propertize glyph 'face
+ (if (and (not inhibit-derived)
+ (or (null emoji--done-derived)
+ (not (gethash glyph emoji--done-derived)))
+ (gethash glyph emoji--derived))
+ ;; If this emoji has derivations, use a special face
+ ;; to tell the user.
+ 'emoji-with-derivations
+ ;; Normal emoji.
+ 'emoji)))
+
+(defun emoji--name (glyph)
+ (or (gethash glyph emoji--names)
+ (get-char-code-property (aref glyph 0) 'name)))
+
+(defvar-keymap emoji-list-mode-map
+ "RET" #'emoji-list-select
+ "<mouse-2>" #'emoji-list-select
+ "h" #'emoji-list-help
+ "<follow-link>" 'mouse-face)
+
+(define-derived-mode emoji-list-mode special-mode "Emoji"
+ "Mode to display emojis."
+ :interactive nil
+ (setq-local truncate-lines t))
+
+(defun emoji-list-select (event)
+ "Select the emoji under point."
+ (interactive (list last-nonmenu-event) emoji-list-mode)
+ (mouse-set-point event)
+ (let ((glyph (get-text-property (point) 'emoji-glyph)))
+ (unless glyph
+ (error "No emoji under point"))
+ (let ((derived (gethash glyph emoji--derived))
+ (end-func
+ (lambda ()
+ (let ((buf emoji--insert-buffer))
+ (quit-window)
+ (if (buffer-live-p buf)
+ (switch-to-buffer buf)
+ (error "Buffer disappeared"))))))
+ (if (not derived)
+ ;; Glyph without derivations.
+ (progn
+ (emoji--add-recent glyph)
+ (funcall end-func)
+ (insert glyph))
+ ;; Pop up a transient to choose between derivations.
+ (let ((emoji--done-derived (make-hash-table :test #'equal)))
+ (setf (gethash glyph emoji--done-derived) t)
+ (funcall
+ (emoji--define-transient (cons "Choose Emoji" (cons glyph derived))
+ nil end-func)))))))
+
+(defun emoji-list-help ()
+ "Display the name of the emoji at point."
+ (interactive nil emoji-list-mode)
+ (let ((glyph (get-text-property (point) 'emoji-glyph)))
+ (unless glyph
+ (error "No emoji here"))
+ (let ((name (emoji--name glyph)))
+ (if (not name)
+ (error "Emoji name is unknown")
+ (message "%s" name)))))
+
+(defun emoji--init (&optional force inhibit-adjust)
+ (when (or (not emoji--labels)
+ force)
+ (unless force
+ (ignore-errors (require 'emoji-labels)))
+ ;; The require should define the variable, but in case the .el
+ ;; file doesn't exist (yet), parse the file now.
+ (when (or force
+ (not emoji--labels))
+ (setq emoji--derived (make-hash-table :test #'equal))
+ (emoji--parse-emoji-test)))
+ (when (and (not inhibit-adjust)
+ (not emoji--all-bases))
+ (setq emoji--all-bases (make-hash-table :test #'equal))
+ (emoji--adjust-displayable (cons "Emoji" emoji--labels))))
+
+(defvar emoji--font nil)
+
+(defun emoji--adjust-displayable (alist)
+ "Remove glyphs we don't have fonts for."
+ (let ((emoji--font nil))
+ (emoji--adjust-displayable-1 alist)))
+
+(defun emoji--adjust-displayable-1 (alist)
+ (if (consp (caddr alist))
+ (dolist (child (cdr alist))
+ (emoji--adjust-displayable-1 child))
+ (while (cdr alist)
+ (let ((glyph (cadr alist)))
+ ;; Store all the emojis for later retrieval by
+ ;; the search feature.
+ (when-let ((name (emoji--name glyph)))
+ (setf (gethash (downcase name) emoji--all-bases) glyph))
+ (if (display-graphic-p)
+ ;; Remove glyphs we don't have in graphical displays.
+ (if (let ((char (elt glyph 0)))
+ (if emoji--font
+ (font-has-char-p emoji--font char)
+ (when-let ((font (car (internal-char-font nil char))))
+ (setq emoji--font font))))
+ (setq alist (cdr alist))
+ ;; Remove the element.
+ (setcdr alist (cddr alist)))
+ ;; We don't have font info on non-graphical displays.
+ (if (let ((char (elt glyph 0)))
+ ;; FIXME. Some grapheme clusters display more or less
+ ;; correctly in the terminal, but we don't really know
+ ;; which ones. None of these display totally
+ ;; correctly, though, so should they be filtered out?
+ (char-displayable-p char))
+ (setq alist (cdr alist))
+ ;; Remove the element.
+ (setcdr alist (cddr alist))))))))
+
+(defun emoji--parse-emoji-test ()
+ (setq emoji--labels nil)
+ (with-temp-buffer
+ (insert-file-contents (expand-file-name "../admin/unidata/emoji-test.txt"
+ data-directory))
+ (unless (re-search-forward "^# +group:" nil t)
+ (error "Can't find start of data"))
+ (beginning-of-line)
+ (setq emoji--names (make-hash-table :test #'equal))
+ (let ((derivations (make-hash-table :test #'equal))
+ (case-fold-search t)
+ group subgroup)
+ (while (not (eobp))
+ (cond
+ ((looking-at "# +group: \\(.*\\)")
+ (setq group (match-string 1)
+ subgroup nil))
+ ((looking-at "# +subgroup: \\(.*\\)")
+ (setq subgroup (match-string 1)))
+ ((looking-at
+ "\\([[:xdigit:] \t]+\\); *\\([^ \t]+\\)[ \t]+#.*?E[.0-9]+ +\\(.*\\)")
+ (let* ((codes (match-string 1))
+ (qualification (match-string 2))
+ (name (match-string 3))
+ (base (emoji--base-name name derivations))
+ (glyph (mapconcat
+ (lambda (code)
+ (string (string-to-number code 16)))
+ (split-string codes))))
+ ;; Special-case flags.
+ (when (equal base "flag")
+ (setq base name))
+ ;; Register all glyphs to that we can look up their names
+ ;; later.
+ (setf (gethash glyph emoji--names) name)
+ ;; For the interface, we only care about the fully qualified
+ ;; emojis.
+ (when (equal qualification "fully-qualified")
+ (when (equal base name)
+ (emoji--add-to-group group subgroup glyph))
+ ;; Create mapping from base glyph name to name of
+ ;; derived glyphs.
+ (setf (gethash base derivations)
+ (nconc (gethash base derivations) (list glyph)))))))
+ (forward-line 1))
+ ;; Finally create the mapping from the base glyphs to derived ones.
+ (setq emoji--derived (make-hash-table :test #'equal))
+ (maphash (lambda (_k v)
+ (setf (gethash (car v) emoji--derived)
+ (cdr v)))
+ derivations))))
+
+(defun emoji--add-to-group (group subgroup glyph)
+ ;; "People & Body" is very large; split it up.
+ (cond
+ ((equal group "People & Body")
+ (if (or (string-match "\\`person" subgroup)
+ (equal subgroup "family"))
+ (emoji--add-glyph glyph "People"
+ (if (equal subgroup "family")
+ (list subgroup)
+ ;; Avoid "Person person".
+ (cdr (emoji--split-subgroup subgroup))))
+ (emoji--add-glyph glyph "Body" (emoji--split-subgroup subgroup))))
+ ;; "Smileys & Emotion" also seems sub-optimal.
+ ((equal group "Smileys & Emotion")
+ (if (equal subgroup "emotion")
+ (emoji--add-glyph glyph "Emotion" nil)
+ (let ((subs (emoji--split-subgroup subgroup)))
+ ;; Remove one level of menus in the face case.
+ (when (equal (car subs) "face")
+ (pop subs))
+ (emoji--add-glyph glyph "Smileys" subs))))
+ ;; Don't modify the rest.
+ (t
+ (emoji--add-glyph glyph group (emoji--split-subgroup subgroup)))))
+
+(defun emoji--generate-file (&optional file)
+ "Generate an .el file with emoji mapping data and write it to FILE."
+ ;; Running from Makefile.
+ (unless file
+ (setq file (pop command-line-args-left)))
+ (emoji--init t t)
+ ;; Weed out the elements that are empty.
+ (let ((glyphs nil))
+ (maphash (lambda (k v)
+ (unless v
+ (push k glyphs)))
+ emoji--derived)
+ (dolist (glyph glyphs)
+ (remhash glyph emoji--derived)))
+ (with-temp-buffer
+ (insert ";; Generated file -- do not edit. -*- lexical-binding:t -*-
+;; Copyright © 1991-2021 Unicode, Inc.
+;; Generated from Unicode data files by emoji.el.
+;; The source for this file is found in the admin/unidata/emoji-test.txt
+;; file in the Emacs sources. The Unicode data files are used under the
+;; Unicode Terms of Use, as contained in the file copyright.html in that
+;; same directory.\n\n")
+ (dolist (var '(emoji--labels emoji--derived emoji--names))
+ (insert (format "(defconst %s '" var))
+ (pp (symbol-value var) (current-buffer))
+ (insert (format "\n) ;; End %s\n\n" var)))
+ (insert ";; Local" " Variables:
+;; coding: utf-8
+;; version-control: never
+;; no-byte-"
+ ;; Obfuscate to not inhibit compilation of this file, too.
+ "compile: t
+;; no-update-autoloads: t
+;; End:
+
+(provide 'emoji-labels)
+
+;;; emoji-labels.el ends here\n")
+ (write-region (point-min) (point-max) file)))
+
+(defun emoji--base-name (name derivations)
+ (let* ((base (replace-regexp-in-string ":.*" "" name))
+ (non-binary (replace-regexp-in-string "\\`\\(man\\|woman\\) " ""
+ base)))
+ ;; If we have (for instance) "person golfing", and we're adding
+ ;; "man golfing", make the latter a derivation of the former.
+ (if (or (gethash (concat "person " non-binary) derivations)
+ (gethash non-binary derivations))
+ non-binary
+ base)))
+
+(defun emoji--split-subgroup (subgroup)
+ (let ((prefixes '("face" "hand" "person" "animal" "plant"
+ "food" "place")))
+ (cond
+ ((string-match (concat "\\`" (regexp-opt prefixes) "-") subgroup)
+ ;; Split these subgroups into hierarchies.
+ (list (substring subgroup 0 (1- (match-end 0)))
+ (substring subgroup (match-end 0))))
+ ((equal subgroup "person")
+ (list "person" "age"))
+ (t
+ (list subgroup)))))
+
+(defun emoji--add-glyph (glyph main subs)
+ (let (parent elem)
+ ;; Useless category.
+ (unless (member main '("Component"))
+ (unless (setq parent (assoc main emoji--labels))
+ (setq emoji--labels (append emoji--labels
+ (list (setq parent (list main))))))
+ (setq elem parent)
+ (while subs
+ (unless (setq elem (assoc (car subs) parent))
+ (nconc parent (list (setq elem (list (car subs))))))
+ (pop subs)
+ (setq parent elem))
+ (nconc elem (list glyph)))))
+
+(defun emoji--define-transient (&optional alist inhibit-derived
+ end-function)
+ (unless alist
+ (setq alist (cons "Emoji" emoji--labels)))
+ (let* ((mname (pop alist))
+ (name (intern (format "emoji--command-%s" mname)))
+ (emoji--done-derived (or emoji--done-derived
+ (make-hash-table :test #'equal)))
+ (has-subs (consp (cadr alist)))
+ (layout
+ (if has-subs
+ ;; Define sub-maps.
+ (cl-loop for entry in
+ (emoji--compute-prefix
+ (if (equal mname "Emoji")
+ (cons (list "Recent") alist)
+ alist))
+ collect (list
+ (car entry)
+ (emoji--compute-name (cdr entry))
+ (if (equal (cadr entry) "Recent")
+ (emoji--recent-transient end-function)
+ (emoji--define-transient
+ (cons (concat mname " > " (cadr entry))
+ (cddr entry))))))
+ ;; Insert an emoji.
+ (cl-loop for glyph in alist
+ for i in (append (number-sequence ?a ?z)
+ (number-sequence ?A ?Z)
+ (number-sequence ?0 ?9)
+ (number-sequence ?! ?/))
+ collect (let ((this-glyph glyph))
+ (list
+ (string i)
+ (emoji--fontify-glyph
+ glyph inhibit-derived)
+ (let ((derived
+ (and (not inhibit-derived)
+ (not (gethash glyph
+ emoji--done-derived))
+ (gethash glyph emoji--derived))))
+ (if derived
+ ;; We have a derived glyph, so add
+ ;; another level.
+ (progn
+ (setf (gethash glyph
+ emoji--done-derived)
+ t)
+ (emoji--define-transient
+ (cons (concat mname " " glyph)
+ (cons glyph derived))
+ t end-function))
+ ;; Insert the emoji.
+ (lambda ()
+ (interactive)
+ ;; Allow switching to the correct
+ ;; buffer.
+ (when end-function
+ (funcall end-function))
+ (emoji--add-recent this-glyph)
+ (insert this-glyph)))))))))
+ (args (apply #'vector mname
+ (emoji--columnize layout
+ (if has-subs 2 8)))))
+ ;; There's probably a better way to do this...
+ (setf (symbol-function name)
+ (lambda ()
+ (interactive)
+ (transient-setup name)))
+ (pcase-let ((`(,class ,slots ,suffixes ,docstr ,_body)
+ (transient--expand-define-args (list args))))
+ (put name 'interactive-only t)
+ (put name 'function-documentation docstr)
+ (put name 'transient--prefix
+ (apply (or class 'transient-prefix) :command name
+ (cons :variable-pitch (cons t slots))))
+ (put name 'transient--layout
+ (cl-mapcan (lambda (s) (transient--parse-child name s))
+ suffixes)))
+ name))
+
+(defun emoji--recent-transient (end-function)
+ "Create a function to display a dynamically generated menu."
+ (lambda ()
+ (interactive)
+ (funcall (emoji--define-transient
+ (cons "Recent" (multisession-value emoji--recent))
+ t end-function))))
+
+(defun emoji--add-recent (glyph)
+ "Add GLYPH to the set of recently used emojis."
+ (let ((recent (multisession-value emoji--recent)))
+ (setq recent (delete glyph recent))
+ (push glyph recent)
+ ;; Shorten the list.
+ (when-let ((tail (nthcdr 30 recent)))
+ (setcdr tail nil))
+ (setf (multisession-value emoji--recent) recent)))
+
+(defun emoji--columnize (list columns)
+ "Split LIST into COLUMN columns."
+ (cl-loop with length = (ceiling (/ (float (length list)) columns))
+ for i upto columns
+ for part on list by (lambda (l) (nthcdr length l))
+ collect (apply #'vector (seq-take part length))))
+
+(defun emoji--compute-prefix (alist)
+ "Compute characters to use for entries in ALIST.
+We prefer the earliest unique letter."
+ (cl-loop with taken = (make-hash-table)
+ for entry in alist
+ for name = (car entry)
+ collect (cons (cl-loop for char across (concat
+ (downcase name)
+ (upcase name))
+ while (gethash char taken)
+ finally (progn
+ (setf (gethash char taken) t)
+ (cl-return (string char))))
+ entry)))
+
+(defun emoji--compute-name (entry)
+ "Add example emojis to the name."
+ (let* ((name (concat (car entry) " "))
+ (children (emoji--flatten entry))
+ (length (length name))
+ (max 30))
+ (cl-loop for i from 0 upto 20
+ ;; Choose from all the children.
+ while (< length max)
+ do (cl-loop for child in children
+ for glyph = (elt child i)
+ while (< length max)
+ when glyph
+ do (setq name (concat name glyph)
+ length (+ length 2))))
+ (if (= (length name) max)
+ ;; Make an ellipsis signal that we've not exhausted the
+ ;; possibilities.
+ (concat name "…")
+ name)))
+
+(defun emoji--flatten (alist)
+ (pop alist)
+ (if (consp (cadr alist))
+ (cl-loop for child in alist
+ append (emoji--flatten child))
+ (list alist)))
+
+(defun emoji--split-long-lists (alist)
+ (let ((whole alist))
+ (pop alist)
+ (if (consp (cadr alist))
+ ;; Descend.
+ (cl-loop for child in alist
+ do (emoji--split-long-lists child))
+ ;; We have a list.
+ (when (length> alist 77)
+ (setcdr whole
+ (cl-loop for prefix from ?a
+ for bit on alist by (lambda (l) (nthcdr 77 l))
+ collect (cons (concat (string prefix) "-group")
+ (seq-take bit 77))))))))
+
+(defun emoji--choose-emoji ()
+ ;; Use the list of names.
+ (let ((name
+ (completing-read
+ "Insert emoji: "
+ (lambda (string pred action)
+ (if (eq action 'metadata)
+ (list 'metadata
+ (cons
+ 'affixation-function
+ ;; Add the glyphs to the start of the displayed
+ ;; strings when TAB-ing.
+ (lambda (strings)
+ (mapcar
+ (lambda (name)
+ (list name
+ (concat
+ (or (gethash name emoji--all-bases) " ")
+ "\t")
+ ""))
+ strings))))
+ (complete-with-action action emoji--all-bases string pred)))
+ nil t)))
+ (when (cl-plusp (length name))
+ (let* ((glyph (gethash name emoji--all-bases))
+ (derived (gethash glyph emoji--derived)))
+ (if (not derived)
+ ;; Simple glyph with no derivations.
+ (progn
+ (emoji--add-recent glyph)
+ (insert glyph))
+ ;; Choose a derived version.
+ (let ((emoji--done-derived (make-hash-table :test #'equal)))
+ (setf (gethash glyph emoji--done-derived) t)
+ (funcall
+ (emoji--define-transient
+ (cons "Choose Emoji" (cons glyph derived))))))))))
+
+(provide 'emoji)
+
+;;; emoji.el ends here
diff --git a/lisp/international/fontset.el b/lisp/international/fontset.el
index 3deaff96774..7c3a7cd1a9e 100644
--- a/lisp/international/fontset.el
+++ b/lisp/international/fontset.el
@@ -157,7 +157,9 @@
(armenian #x531)
(hebrew #x5D0)
(vai #xA500)
- (arabic #x628)
+ ;; U+06C1 prevents us from using bad fonts, like DejaVu Sans,
+ ;; for Arabic text.
+ (arabic #x628 #x6C1)
(syriac #x710)
(thaana #x78C)
(devanagari #x915)
@@ -191,7 +193,7 @@
(kanbun #x319D)
(han #x5B57)
(yi #xA288)
- (javanese #xA980)
+ (javanese #xA980)
(cham #xAA00)
(tai-viet #xAA80)
(hangul #xAC00)
@@ -209,9 +211,10 @@
(deseret #x10400)
(shavian #x10450)
(osmanya #x10480)
- (osage #x104B0)
+ (osage #x104B0)
(elbasan #x10500)
(caucasian-albanian #x10530)
+ (vithkuqi #x10570)
(linear-a #x10600)
(cypriot-syllabary #x10800)
(palmyrene #x10860)
@@ -220,79 +223,85 @@
(lydian #x10920)
(kharoshthi #x10A00)
(manichaean #x10AC0)
- (hanifi-rohingya #x10D00)
- (yezidi #x10E80)
- (old-sogdian #x10F00)
- (sogdian #x10F30)
- (chorasmian #x10FB0)
- (elymaic #x10FE0)
+ (hanifi-rohingya #x10D00)
+ (yezidi #x10E80)
+ (old-sogdian #x10F00)
+ (sogdian #x10F30)
+ (chorasmian #x10FB0)
+ (elymaic #x10FE0)
+ (old-uyghur #x10F70)
(mahajani #x11150)
(sinhala-archaic-number #x111E1)
(khojki #x11200)
(khudawadi #x112B0)
(grantha #x11305)
- (newa #x11400)
+ (newa #x11400)
(tirhuta #x11481)
(siddham #x11580)
(modi #x11600)
(takri #x11680)
- (dogra #x11800)
+ (dogra #x11800)
(warang-citi #x118A1)
- (dives-akuru #x11900)
- (nandinagari #x119a0)
- (zanabazar-square #x11A00)
- (soyombo #x11A50)
+ (dives-akuru #x11900)
+ (nandinagari #x119a0)
+ (zanabazar-square #x11A00)
+ (soyombo #x11A50)
(pau-cin-hau #x11AC0)
- (bhaiksuki #x11C00)
- (marchen #x11C72)
- (masaram-gondi #x11D00)
- (gunjala-gondi #x11D60)
- (makasar #x11EE0)
+ (bhaiksuki #x11C00)
+ (marchen #x11C72)
+ (masaram-gondi #x11D00)
+ (gunjala-gondi #x11D60)
+ (makasar #x11EE0)
(cuneiform #x12000)
(cuneiform-numbers-and-punctuation #x12400)
+ (cypro-minoan #x12F90)
(egyptian #x13000)
(mro #x16A40)
+ (tangsa #x16A70 #x16AC0)
(bassa-vah #x16AD0)
(pahawh-hmong #x16B11)
- (medefaidrin #x16E40)
- (tangut #x17000)
- (tangut-components #x18800)
- (khitan-small-script #x18B00)
- (nushu #x1B170)
+ (medefaidrin #x16E40)
+ (tangut #x17000)
+ (tangut-components #x18800)
+ (khitan-small-script #x18B00)
+ (nushu #x1B170)
(duployan-shorthand #x1BC20)
+ (znamenny-musical-notation #x1CF00 #x1CF42 #x1CF50)
(byzantine-musical-symbol #x1D000)
(musical-symbol #x1D100)
(ancient-greek-musical-notation #x1D200)
(tai-xuan-jing-symbol #x1D300)
(counting-rod-numeral #x1D360)
- (nyiakeng-puachue-hmong #x1e100)
- (wancho #x1e2c0)
+ (nyiakeng-puachue-hmong #x1e100)
+ (toto #x1E290)
+ (wancho #x1e2c0)
(mende-kikakui #x1E810)
- (adlam #x1E900)
- (indic-siyaq-number #x1ec71)
- (ottoman-siyaq-number #x1ed01)
+ (adlam #x1E900)
+ (indic-siyaq-number #x1ec71)
+ (ottoman-siyaq-number #x1ed01)
(mahjong-tile #x1F000)
- (domino-tile #x1F030)))
+ (domino-tile #x1F030)
+ (emoji #x1F300 #x1F600)))
(defvar otf-script-alist)
-;; The below was synchronized with the latest Aug 16, 2018 version of
+;; The below was synchronized with the latest Oct 8, 2020 version of
;; https://docs.microsoft.com/en-us/typography/opentype/spec/scripttags
(setq otf-script-alist
'((adlm . adlam)
- (ahom . ahom)
- (hluw . anatolian)
- (arab . arabic)
+ (ahom . ahom)
+ (hluw . anatolian)
+ (arab . arabic)
(armi . aramaic)
(armn . armenian)
(avst . avestan)
(bali . balinese)
(bamu . bamum)
- (bass . bassa-vah)
+ (bass . bassa-vah)
(batk . batak)
(bng2 . bengali)
(beng . bengali)
- (bhks . bhaiksuki)
+ (bhks . bhaiksuki)
(bopo . bopomofo)
(brah . brahmi)
(brai . braille)
@@ -301,10 +310,11 @@
(byzm . byzantine-musical-symbol)
(cans . canadian-aboriginal)
(cari . carian)
- (aghb . caucasian-albanian)
+ (aghb . caucasian-albanian)
(cakm . chakma)
(cham . cham)
(cher . cherokee)
+ (chrs . chorasmian)
(copt . coptic)
(xsux . cuneiform)
(cprt . cypriot)
@@ -312,29 +322,31 @@
(dsrt . deseret)
(deva . devanagari)
(dev2 . devanagari)
- (dogr . dogra)
- (dupl . duployan-shorthand)
+ (diak . dives-akuru)
+ (dogr . dogra)
+ (dupl . duployan-shorthand)
(egyp . egyptian)
- (elba . elbasan)
+ (elba . elbasan)
+ (elym . elymaic)
(ethi . ethiopic)
(geor . georgian)
(glag . glagolitic)
(goth . gothic)
- (gran . grantha)
+ (gran . grantha)
(grek . greek)
(gujr . gujarati)
(gjr2 . gujarati)
- (gong . gunjala-gondi)
+ (gong . gunjala-gondi)
(guru . gurmukhi)
(gur2 . gurmukhi)
(hani . han)
(hang . hangul)
(jamo . hangul)
- (rohg . hanifi-rohingya)
+ (rohg . hanifi-rohingya)
(hano . hanunoo)
- (hatr . hatran)
+ (hatr . hatran)
(hebr . hebrew)
- (hung . old-hungarian)
+ (hung . old-hungarian)
(phli . inscriptional-pahlavi)
(prti . inscriptional-parthian)
(java . javanese)
@@ -344,77 +356,79 @@
(kana . kana) ; Hiragana
(kali . kayah-li)
(khar . kharoshthi)
+ (kits . khitan-small-script)
(khmr . khmer)
- (khoj . khojki)
- (sind . khudawadi)
+ (khoj . khojki)
+ (sind . khudawadi)
(lao\ . lao)
(latn . latin)
(lepc . lepcha)
(limb . limbu)
(lina . linear_a)
(linb . linear_b)
- (lisu . lisu)
- (lyci . lycian)
- (lydi . lydian)
- (mahj . mahajani)
- (maka . makasar)
- (marc . marchen)
+ (lisu . lisu)
+ (lyci . lycian)
+ (lydi . lydian)
+ (mahj . mahajani)
+ (maka . makasar)
+ (marc . marchen)
(mlym . malayalam)
(mlm2 . malayalam)
(mand . mandaic)
- (mani . manichaean)
- (gonm . masaram-gondi)
+ (mani . manichaean)
+ (gonm . masaram-gondi)
(math . mathematical)
- (medf . medefaidrin)
+ (medf . medefaidrin)
(mtei . meetei-mayek)
- (mend . mende-kikakui)
+ (mend . mende-kikakui)
(merc . meroitic)
(mero . meroitic)
- (plrd . miao)
- (modi . modi)
+ (plrd . miao)
+ (modi . modi)
(mong . mongolian)
- (mroo . mro)
- (mult . multani)
+ (mroo . mro)
+ (mult . multani)
(musc . musical-symbol)
(mym2 . burmese)
(mymr . burmese)
- (nbat . nabataean)
- (newa . newa)
+ (nbat . nabataean)
+ (newa . newa)
(nko\ . nko)
- (nshu . nushu)
+ (nshu . nushu)
+ (hmnp . nyiakeng-puachue-hmong)
(ogam . ogham)
(olck . ol-chiki)
- (ital . old_italic)
- (xpeo . old_persian)
- (narb . old-north-arabian)
- (perm . old-permic)
- (sogo . old-sogdian)
+ (ital . old-italic)
+ (xpeo . old-persian)
+ (narb . old-north-arabian)
+ (perm . old-permic)
+ (sogo . old-sogdian)
(sarb . old-south-arabian)
(orkh . old-turkic)
(orya . oriya)
(ory2 . oriya)
- (osge . osage)
+ (osge . osage)
(osma . osmanya)
- (hmng . pahawh-hmong)
- (palm . palmyrene)
- (pauc . pau-cin-hau)
+ (hmng . pahawh-hmong)
+ (palm . palmyrene)
+ (pauc . pau-cin-hau)
(phag . phags-pa)
- (phli . inscriptional-pahlavi)
+ (phli . inscriptional-pahlavi)
(phnx . phoenician)
- (phlp . psalter-pahlavi)
- (prti . inscriptional-parthian)
+ (phlp . psalter-pahlavi)
+ (prti . inscriptional-parthian)
(rjng . rejang)
(runr . runic)
(samr . samaritan)
(saur . saurashtra)
(shrd . sharada)
(shaw . shavian)
- (sidd . siddham)
- (sgnw . sutton-sign-writing)
+ (sidd . siddham)
+ (sgnw . sutton-sign-writing)
(sinh . sinhala)
- (sogd . sogdian)
+ (sogd . sogdian)
(sora . sora-sompeng)
- (soyo . soyombo)
+ (soyo . soyombo)
(sund . sundanese)
(sylo . syloti_nagri)
(syrc . syriac)
@@ -427,19 +441,21 @@
(takr . takri)
(taml . tamil)
(tml2 . tamil)
- (tang . tangut)
+ (tang . tangut)
(telu . telugu)
(tel2 . telugu)
(thaa . thaana)
(thai . thai)
(tibt . tibetan)
(tfng . tifinagh)
- (tirh . tirhuta)
+ (tirh . tirhuta)
(ugar . ugaritic)
(vai\ . vai)
- (wara . warang-citi)
- (yi\ \ . yi)
- (zanb . zanabazar-square)))
+ (wcho . wancho)
+ (wara . warang-citi)
+ (yezi . yezidi)
+ (yi\ \ . yi)
+ (zanb . zanabazar-square)))
;; Set standard fontname specification of characters in the default
;; fontset to find an appropriate font for each script/charset. The
@@ -740,6 +756,7 @@
shavian
osmanya
osage
+ vithkuqi
cypriot-syllabary
phoenician
lydian
@@ -748,22 +765,27 @@
manichaean
chorasmian
elymaic
+ old-uyghur
makasar
dives-akuru
cuneiform-numbers-and-punctuation
cuneiform
egyptian
+ tangsa
bassa-vah
pahawh-hmong
medefaidrin
+ znamenny-musical-notation
byzantine-musical-symbol
musical-symbol
ancient-greek-musical-notation
tai-xuan-jing-symbol
counting-rod-numeral
+ toto
adlam
mahjong-tile
- domino-tile))
+ domino-tile
+ emoji))
(set-fontset-font "fontset-default"
script (font-spec :registry "iso10646-1" :script script)
nil 'append))
@@ -794,11 +816,16 @@
(#x1D7EC #x1D7F5 mathematical-sans-serif-bold)
(#x1D7F6 #x1D7FF mathematical-monospace)))
(let ((slot (assq (nth 2 math-subgroup) script-representative-chars)))
+ ;; Add both ends of each subgroup to help filter out some
+ ;; incomplete fonts, e.g. those that cover MATHEMATICAL SCRIPT
+ ;; CAPITAL glyphs but not MATHEMATICAL SCRIPT SMALL ones.
(if slot
- (if (vectorp (cdr slot))
- (setcdr slot (vconcat (cdr slot) (vector (car math-subgroup))))
- (setcdr slot (vector (cadr slot) (car math-subgroup))))
- (setq slot (list (nth 2 math-subgroup) (car math-subgroup)))
+ (setcdr slot (append (list (nth 0 math-subgroup)
+ (nth 1 math-subgroup))
+ (cdr slot)))
+ (setq slot (list (nth 2 math-subgroup)
+ (nth 0 math-subgroup)
+ (nth 1 math-subgroup)))
(nconc script-representative-chars (list slot))))
(set-fontset-font
"fontset-default"
@@ -904,6 +931,9 @@
(set-fontset-font "fontset-default" symbol-subgroup
"-*-fixed-medium-*-*-*-*-*-*-*-*-*-iso10646-1"
nil 'prepend))
+ ;; This sets up the Emoji codepoints to use prettier fonts.
+ (set-fontset-font "fontset-default" 'emoji
+ '("Noto Color Emoji" . "iso10646-1") nil 'prepend)
;; Append CJK fonts for characters other than han, kana, cjk-misc.
;; Append fonts for scripts whose name is also a charset name.
diff --git a/lisp/international/iso-cvt.el b/lisp/international/iso-cvt.el
index ead7c8aa619..f0bfe9f6825 100644
--- a/lisp/international/iso-cvt.el
+++ b/lisp/international/iso-cvt.el
@@ -22,7 +22,7 @@
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
-;; This lisp code is a general framework for translating various
+;; This Lisp code is a general framework for translating various
;; representations of the same data.
;; among other things it can be used to translate TeX, HTML, and compressed
;; files to ISO 8859-1. It can also be used to translate different charsets
@@ -37,7 +37,7 @@
;; SEE ALSO:
; If you are interested in questions related to using the ISO 8859-1
-; characters set (configuring emacs, Unix, etc. to use ISO), then you
+; characters set (configuring Emacs, Unix, etc. to use ISO), then you
; can get the ISO 8859-1 FAQ via anonymous ftp from
; ftp.vlsivie.tuwien.ac.at in /pub/8bit/FAQ-ISO-8859-1
diff --git a/lisp/international/iso-transl.el b/lisp/international/iso-transl.el
index 2c7da2b7cdf..aea12179170 100644
--- a/lisp/international/iso-transl.el
+++ b/lisp/international/iso-transl.el
@@ -86,33 +86,46 @@
("\"y" . [?ÿ])
("''" . [?´])
("'A" . [?Á])
+ ("'C" . [?Ć])
("'E" . [?É])
("'I" . [?Í])
+ ("'N" . [?Ń])
("'O" . [?Ó])
+ ("'S" . [?Ś])
("'U" . [?Ú])
("'Y" . [?Ý])
+ ("'Z" . [?Ź])
("'a" . [?á])
+ ("'c" . [?ć])
("'e" . [?é])
("'i" . [?í])
+ ("'n" . [?ń])
("'o" . [?ó])
+ ("'s" . [?ś])
("'u" . [?ú])
("'y" . [?ý])
+ ("'z" . [?ź])
("*$" . [?¤])
("$" . [?¤])
("*+" . [?±])
("+" . [?±])
(",," . [?¸])
+ (",A" . [?Ą])
(",C" . [?Ç])
+ (",a" . [?ą])
(",c" . [?ç])
("*-" . [?­])
("-" . [?­])
("*." . [?·])
- ("." . [?·])
+ (".." . [?·])
+ (".z" . [?ż])
("//" . [?÷])
("/A" . [?Å])
+ ("/L" . [?Ł])
("/E" . [?Æ])
("/O" . [?Ø])
("/a" . [?å])
+ ("/l" . [?ł])
("/e" . [?æ])
("/o" . [?ø])
("1/2" . [?½])
@@ -294,6 +307,14 @@ sequence VECTOR. (VECTOR is normally one character long.)")
(setq alist (cdr alist))))
(defun iso-transl-set-language (lang)
+ "Set shorter key bindings for some characters relevant for LANG.
+This affects the `C-x 8' prefix.
+
+Note that only a few languages are supported, and for more
+rigorous support it is recommended to use an input method
+instead. Also note that many of these characters can be input
+with the regular `C-x 8' map without having to specify a language
+here."
(interactive (list (let ((completion-ignore-case t))
(completing-read "Set which language? "
iso-transl-language-alist nil t))))
diff --git a/lisp/international/latexenc.el b/lisp/international/latexenc.el
index ff7cddcb26e..9449b3bb851 100644
--- a/lisp/international/latexenc.el
+++ b/lisp/international/latexenc.el
@@ -31,13 +31,13 @@
;; If this fails it will search for AUCTeX's TeX-master or tex-mode's
;; tex-main-file variable in the local variables section and visit
-;; that file to get the coding system from the master file. This check
+;; that file to get the coding system from the master file. This check
;; can be disabled by setting `latexenc-dont-use-TeX-master-flag' to
;; t.
;; If we have still not found a coding system we will try to use the
;; standard tex-mode's `tex-guess-main-file' and get the coding system
-;; from the main file. This check can be disabled by setting
+;; from the main file. This check can be disabled by setting
;; `latexenc-dont-use-tex-guess-main-file-flag' to t.
;; The functionality is enabled by adding the function
diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el
index 71e2653ffe9..7f9b14bdfd9 100644
--- a/lisp/international/mule-cmds.el
+++ b/lisp/international/mule-cmds.el
@@ -88,7 +88,7 @@
(bindings--define-key map [separator-3] menu-bar-separator)
(bindings--define-key map [set-terminal-coding-system]
'(menu-item "For Terminal" set-terminal-coding-system
- :enable (null (memq initial-window-system '(x w32 ns)))
+ :enable (null (memq initial-window-system '(x w32 ns haiku pgtk)))
:help "How to encode terminal output"))
(bindings--define-key map [set-keyboard-coding-system]
'(menu-item "For Keyboard" set-keyboard-coding-system
@@ -662,6 +662,26 @@ overrides that argument.")
(delq 'no-conversion (copy-sequence codings))))
codings))
+(defun select-safe-coding-system--format-list (list)
+ (let ((spec1 " %-20s %6s %-10s %s\n")
+ (spec2 " %-20s %6s #x%-8X %c\n")
+ (nmax 5))
+ (insert (format spec1 "Coding System" "Pos" "Codepoint" "Char"))
+ (cl-loop for (coding . pairs) in list
+ do (cl-loop for pair in pairs
+ ;; If there's a lot, only do the first five.
+ for i from 1 upto nmax
+ do (insert
+ (format spec2
+ (if (= i 1) coding "")
+ (car pair)
+ (cdr pair)
+ (cdr pair))))
+ (if (> (length pairs) nmax)
+ (insert (format spec1 "" "..." "" "")))))
+
+ (insert "\n"))
+
(defun select-safe-coding-system-interactively (from to codings unsafe
&optional rejected default)
"Select interactively a coding system for the region FROM ... TO.
@@ -720,21 +740,18 @@ DEFAULT is the coding system to use by default in the query."
(concat " \"" (if (> (length from) 10)
(concat (substring from 0 10) "...\"")
(concat from "\"")))
- (format-message " text\nin the buffer `%s'" bufname))
+ (format-message
+ " the following\nproblematic characters in the buffer `%s'"
+ bufname))
":\n")
- (let ((pos (point))
- (fill-prefix " "))
- (dolist (x (append rejected unsafe))
- (princ " ") (princ x))
- (insert "\n")
- (fill-region-as-paragraph pos (point)))
+ (select-safe-coding-system--format-list unsafe)
(when rejected
(insert "These safely encode the text in the buffer,
but are not recommended for encoding text in this context,
e.g., for sending an email message.\n ")
- (dolist (x rejected)
- (princ " ") (princ x))
- (insert "\n"))
+ (dolist (x rejected)
+ (princ " ") (princ x))
+ (insert "\n"))
(when unsafe
(insert (if rejected "The other coding systems"
"However, each of them")
@@ -1621,30 +1638,31 @@ If `default-transient-input-method' was not yet defined, prompt for it."
(interactive
(list (read-input-method-name
(format-prompt "Describe input method" current-input-method))))
- (if (and input-method (symbolp input-method))
- (setq input-method (symbol-name input-method)))
- (help-setup-xref (list #'describe-input-method
- (or input-method current-input-method))
- (called-interactively-p 'interactive))
-
- (if (null input-method)
- (describe-current-input-method)
- (let ((current current-input-method))
- (condition-case nil
- (progn
- (save-excursion
- (activate-input-method input-method)
- (describe-current-input-method))
- (activate-input-method current))
- (error
- (activate-input-method current)
- (help-setup-xref (list #'describe-input-method input-method)
- (called-interactively-p 'interactive))
- (with-output-to-temp-buffer (help-buffer)
- (let ((elt (assoc input-method input-method-alist)))
- (princ (format-message
- "Input method: %s (`%s' in mode line) for %s\n %s\n"
- input-method (nth 3 elt) (nth 1 elt) (nth 4 elt))))))))))
+ (let ((help-buffer-under-preparation t))
+ (if (and input-method (symbolp input-method))
+ (setq input-method (symbol-name input-method)))
+ (help-setup-xref (list #'describe-input-method
+ (or input-method current-input-method))
+ (called-interactively-p 'interactive))
+
+ (if (null input-method)
+ (describe-current-input-method)
+ (let ((current current-input-method))
+ (condition-case nil
+ (progn
+ (save-excursion
+ (activate-input-method input-method)
+ (describe-current-input-method))
+ (activate-input-method current))
+ (error
+ (activate-input-method current)
+ (help-setup-xref (list #'describe-input-method input-method)
+ (called-interactively-p 'interactive))
+ (with-output-to-temp-buffer (help-buffer)
+ (let ((elt (assoc input-method input-method-alist)))
+ (princ (format-message
+ "Input method: %s (`%s' in mode line) for %s\n %s\n"
+ input-method (nth 3 elt) (nth 1 elt) (nth 4 elt)))))))))))
(defun describe-current-input-method ()
"Describe the input method currently in use.
@@ -2145,89 +2163,90 @@ See `set-language-info-alist' for use in programs."
(list (read-language-name
'documentation
(format-prompt "Describe language environment" current-language-environment))))
- (if (null language-name)
- (setq language-name current-language-environment))
- (if (or (null language-name)
- (null (get-language-info language-name 'documentation)))
- (error "No documentation for the specified language"))
- (if (symbolp language-name)
- (setq language-name (symbol-name language-name)))
- (dolist (feature (get-language-info language-name 'features))
- (require feature))
- (let ((doc (get-language-info language-name 'documentation)))
- (help-setup-xref (list #'describe-language-environment language-name)
- (called-interactively-p 'interactive))
- (with-output-to-temp-buffer (help-buffer)
- (with-current-buffer standard-output
- (insert language-name " language environment\n\n")
- (if (stringp doc)
- (insert (substitute-command-keys doc) "\n\n"))
- (condition-case nil
- (let ((str (eval (get-language-info language-name 'sample-text))))
- (if (stringp str)
- (insert "Sample text:\n "
- (string-replace "\n" "\n " str)
- "\n\n")))
- (error nil))
- (let ((input-method (get-language-info language-name 'input-method))
- (l (copy-sequence input-method-alist))
- (first t))
- (when (and input-method
- (setq input-method (assoc input-method l)))
- (insert "Input methods (default " (car input-method) ")\n")
- (setq l (cons input-method (delete input-method l))
- first nil))
- (dolist (elt l)
- (when (or (eq input-method elt)
- (eq t (compare-strings language-name nil nil
- (nth 1 elt) nil nil t)))
- (when first
- (insert "Input methods:\n")
- (setq first nil))
- (insert " " (car elt))
- (search-backward (car elt))
- (help-xref-button 0 'help-input-method (car elt))
- (goto-char (point-max))
- (insert " (\""
- (if (stringp (nth 3 elt)) (nth 3 elt) (car (nth 3 elt)))
- "\" in mode line)\n")))
- (or first
- (insert "\n")))
- (insert "Character sets:\n")
- (let ((l (get-language-info language-name 'charset)))
- (if (null l)
- (insert " nothing specific to " language-name "\n")
- (while l
- (insert " " (symbol-name (car l)))
- (search-backward (symbol-name (car l)))
- (help-xref-button 0 'help-character-set (car l))
- (goto-char (point-max))
- (insert ": " (charset-description (car l)) "\n")
- (setq l (cdr l)))))
- (insert "\n")
- (insert "Coding systems:\n")
- (let ((l (get-language-info language-name 'coding-system)))
- (if (null l)
- (insert " nothing specific to " language-name "\n")
- (while l
- (insert " " (symbol-name (car l)))
- (search-backward (symbol-name (car l)))
- (help-xref-button 0 'help-coding-system (car l))
- (goto-char (point-max))
- (insert (substitute-command-keys " (`")
- (coding-system-mnemonic (car l))
- (substitute-command-keys "' in mode line):\n\t")
- (substitute-command-keys
- (coding-system-doc-string (car l)))
- "\n")
- (let ((aliases (coding-system-aliases (car l))))
- (when aliases
- (insert "\t(alias:")
- (while aliases
- (insert " " (symbol-name (car aliases)))
- (setq aliases (cdr aliases)))
- (insert ")\n")))
- (setq l (cdr l)))))))))
+ (let ((help-buffer-under-preparation t))
+ (if (null language-name)
+ (setq language-name current-language-environment))
+ (if (or (null language-name)
+ (null (get-language-info language-name 'documentation)))
+ (error "No documentation for the specified language"))
+ (if (symbolp language-name)
+ (setq language-name (symbol-name language-name)))
+ (dolist (feature (get-language-info language-name 'features))
+ (require feature))
+ (let ((doc (get-language-info language-name 'documentation)))
+ (help-setup-xref (list #'describe-language-environment language-name)
+ (called-interactively-p 'interactive))
+ (with-output-to-temp-buffer (help-buffer)
+ (with-current-buffer standard-output
+ (insert language-name " language environment\n\n")
+ (if (stringp doc)
+ (insert (substitute-command-keys doc) "\n\n"))
+ (condition-case nil
+ (let ((str (eval (get-language-info language-name 'sample-text))))
+ (if (stringp str)
+ (insert "Sample text:\n "
+ (string-replace "\n" "\n " str)
+ "\n\n")))
+ (error nil))
+ (let ((input-method (get-language-info language-name 'input-method))
+ (l (copy-sequence input-method-alist))
+ (first t))
+ (when (and input-method
+ (setq input-method (assoc input-method l)))
+ (insert "Input methods (default " (car input-method) ")\n")
+ (setq l (cons input-method (delete input-method l))
+ first nil))
+ (dolist (elt l)
+ (when (or (eq input-method elt)
+ (eq t (compare-strings language-name nil nil
+ (nth 1 elt) nil nil t)))
+ (when first
+ (insert "Input methods:\n")
+ (setq first nil))
+ (insert " " (car elt))
+ (search-backward (car elt))
+ (help-xref-button 0 'help-input-method (car elt))
+ (goto-char (point-max))
+ (insert " (\""
+ (if (stringp (nth 3 elt)) (nth 3 elt) (car (nth 3 elt)))
+ "\" in mode line)\n")))
+ (or first
+ (insert "\n")))
+ (insert "Character sets:\n")
+ (let ((l (get-language-info language-name 'charset)))
+ (if (null l)
+ (insert " nothing specific to " language-name "\n")
+ (while l
+ (insert " " (symbol-name (car l)))
+ (search-backward (symbol-name (car l)))
+ (help-xref-button 0 'help-character-set (car l))
+ (goto-char (point-max))
+ (insert ": " (charset-description (car l)) "\n")
+ (setq l (cdr l)))))
+ (insert "\n")
+ (insert "Coding systems:\n")
+ (let ((l (get-language-info language-name 'coding-system)))
+ (if (null l)
+ (insert " nothing specific to " language-name "\n")
+ (while l
+ (insert " " (symbol-name (car l)))
+ (search-backward (symbol-name (car l)))
+ (help-xref-button 0 'help-coding-system (car l))
+ (goto-char (point-max))
+ (insert (substitute-command-keys " (`")
+ (coding-system-mnemonic (car l))
+ (substitute-command-keys "' in mode line):\n\t")
+ (substitute-command-keys
+ (coding-system-doc-string (car l)))
+ "\n")
+ (let ((aliases (coding-system-aliases (car l))))
+ (when aliases
+ (insert "\t(alias:")
+ (while aliases
+ (insert " " (symbol-name (car aliases)))
+ (setq aliases (cdr aliases)))
+ (insert ")\n")))
+ (setq l (cdr l))))))))))
;;; Locales.
@@ -2610,6 +2629,31 @@ is returned. Thus, for instance, if charset \"ISO8859-2\",
(declare-function w32-get-console-codepage "w32proc.c" ())
(declare-function w32-get-console-output-codepage "w32proc.c" ())
+(defun get-locale-names ()
+ "Return a list of locale names."
+ (cond
+ ;; On Windows we have a built-in method to get the names.
+ ((and (fboundp 'w32-get-locale-info)
+ (fboundp 'w32-get-valid-locale-ids))
+ (delete-dups (mapcar #'w32-get-locale-info (w32-get-valid-locale-ids))))
+ ;; Unix-ey hosts should have a command to output locales currently
+ ;; defined by the OS.
+ ((executable-find "locale")
+ (split-string (shell-command-to-string "locale -a")))
+ ;; Fall back on the list of all defined locales.
+ ((and locale-translation-file-name
+ (file-exists-p locale-translation-file-name))
+ (with-temp-buffer
+ (insert-file-contents locale-translation-file-name)
+ (let ((locales nil))
+ (while (not (eobp))
+ (unless (looking-at-p "#")
+ (push (cadr (split-string (buffer-substring
+ (point) (line-end-position))))
+ locales))
+ (forward-line 1))
+ (nreverse locales))))))
+
(defun locale-translate (locale)
"Expand LOCALE according to `locale-translation-file-name', if possible.
For example, translate \"swedish\" into \"sv_SE.ISO8859-1\"."
@@ -2623,6 +2667,20 @@ For example, translate \"swedish\" into \"sv_SE.ISO8859-1\"."
locale))
locale))
+(defvar current-locale-environment nil
+ "The currently set locale environment.")
+
+(defmacro with-locale-environment (locale-name &rest body)
+ "Execute BODY with the locale set to LOCALE-NAME."
+ (declare (indent 1) (debug (sexp def-body)))
+ (let ((current (gensym)))
+ `(let ((,current current-locale-environment))
+ (unwind-protect
+ (progn
+ (set-locale-environment ,locale-name)
+ ,@body)
+ (set-locale-environment ,current)))))
+
(defun set-locale-environment (&optional locale-name frame)
"Set up multilingual environment for using LOCALE-NAME.
This sets the language environment, the coding system priority,
@@ -2648,10 +2706,14 @@ If FRAME is non-nil, only set the keyboard coding system and the
terminal coding system for the terminal of that frame, and don't
touch session-global parameters like the language environment.
+This function sets the `current-locale-environment' variable. To
+change the locale temporarily, `with-locale-environment' can be
+used.
+
See also `locale-charset-language-names', `locale-language-names',
`locale-preferred-coding-systems' and `locale-coding-system'."
- (interactive "sSet environment for locale: ")
-
+ (interactive (list (completing-read "Set environment for locale: "
+ (get-locale-names))))
;; Do this at runtime for the sake of binaries possibly transported
;; to a system without X.
(setq locale-translation-file-name
@@ -2681,6 +2743,7 @@ See also `locale-charset-language-names', `locale-language-names',
(when locale
(setq locale (locale-translate locale))
+ (setq current-locale-environment locale)
;; Leave the system locales alone if the caller did not specify
;; an explicit locale name, as their defaults are set from
@@ -2885,6 +2948,7 @@ Optional 3rd argument DOCSTRING is a documentation string of the property.
See also the documentation of `get-char-code-property' and
`put-char-code-property'."
+ (declare (indent defun))
(or (symbolp name)
(error "Not a symbol: %s" name))
(if (char-table-p table)
@@ -3013,22 +3077,6 @@ on encoding."
0))
(substring enc2 i0 i2)))))
-;; Backwards compatibility. These might be better with :init-value t,
-;; but that breaks loadup.
-(define-minor-mode unify-8859-on-encoding-mode
- "Exists only for backwards compatibility."
- :group 'mule
- :global t)
-;; Doc said "obsolete" in 23.1, this statement only added in 24.1.
-(make-obsolete 'unify-8859-on-encoding-mode "don't use it." "23.1")
-
-(define-minor-mode unify-8859-on-decoding-mode
- "Exists only for backwards compatibility."
- :group 'mule
- :global t)
-;; Doc said "obsolete" in 23.1, this statement only added in 24.1.
-(make-obsolete 'unify-8859-on-decoding-mode "don't use it." "23.1")
-
(defvar ucs-names nil
"Hash table of cached CHAR-NAME keys to CHAR-CODE values.")
@@ -3052,15 +3100,15 @@ on encoding."
;; (#x18800 . #x18AFF) Tangut Components
;; (#x18B00 . #x18CFF) Khitan Small Script
;; (#x18D00 . #x18D0F) Tangut Ideograph Supplement
- ;; (#x18D10 . #x1AFFF) unused
- (#x1B000 . #x1B11F)
- ;; (#x1B120 . #x1B14F) unused
+ ;; (#x18D10 . #x1AFEF) unused
+ (#x1AFF0 . #x1B12F)
+ ;; (#x1B130 . #x1B14F) unused
(#x1B150 . #x1B16F)
(#x1B170 . #x1B2FF)
;; (#x1B300 . #x1BBFF) unused
(#x1BC00 . #x1BCAF)
- ;; (#x1BCB0 . #x1CFFF) unused
- (#x1D000 . #x1FFFF)
+ ;; (#x1BCB0 . #x1CEFF) unused
+ (#x1CF00 . #x1FFFF)
;; (#x20000 . #xDFFFF) CJK Ideograph Extension A, B, etc, unused
(#xE0000 . #xE01FF)))
(gc-cons-threshold (max gc-cons-threshold 10000000))
@@ -3196,5 +3244,116 @@ as names, not numbers."
(define-obsolete-function-alias 'ucs-insert 'insert-char "24.3")
(define-key ctl-x-map "8\r" 'insert-char)
+(define-key ctl-x-map "8e"
+ (define-keymap
+ "e" #'emoji-insert
+ "i" #'emoji-insert
+ "s" #'emoji-search
+ "d" #'emoji-describe
+ "r" #'emoji-recent
+ "l" #'emoji-list))
+
+(defface confusingly-reordered
+ '((((supports :underline (:style wave)))
+ :underline (:style wave :color "Red1"))
+ (t
+ :inherit warning))
+ "Face for highlighting text that was bidi-reordered in confusing ways."
+ :version "29.1")
+
+(defvar reorder-starters "[\u202A\u202B\u202D\u202E\u2066-\u2068]+"
+ "Regular expression for characters that start forced-reordered text.")
+(defvar reorder-enders "[\u202C\u2069]+\\|\n"
+ "Regular expression for characters that end forced-reordered text.")
+
+(autoload 'text-property-search-forward "text-property-search")
+(autoload 'prop-match-beginning "text-property-search")
+(autoload 'prop-match-end "text-property-search")
+
+(defun highlight-confusing-reorderings (beg end &optional remove)
+ "Highlight text in region that might be bidi-reordered in suspicious ways.
+This command find and highlights segments of buffer text that could have
+been reordered on display by using directional control characters, such
+as RLO and LRI, in a way that their display is deliberately meant to
+confuse the reader. These techniques can be used for obfuscating
+malicious source code. The suspicious stretches of buffer text are
+highlighted using the `confusingly-reordered' face.
+
+If the region is active, check the text inside the region. Otherwise
+check the entire buffer. When called from Lisp, pass BEG and END to
+specify the portion of the buffer to check.
+
+Optional argument REMOVE, if non-nil (interactively, prefix argument),
+means remove the highlighting from the region between BEG and END,
+or the active region if that is set."
+ (interactive
+ (if (use-region-p)
+ (list (region-beginning) (region-end) current-prefix-arg)
+ (list (point-min) (point-max) current-prefix-arg)))
+ (save-excursion
+ (if remove
+ (let (prop-match)
+ (goto-char beg)
+ (while (and
+ (setq prop-match
+ (text-property-search-forward 'font-lock-face
+ 'confusingly-reordered t))
+ (< (prop-match-beginning prop-match) end))
+ (with-silent-modifications
+ (remove-list-of-text-properties (prop-match-beginning prop-match)
+ (prop-match-end prop-match)
+ '(font-lock-face face mouse-face
+ help-echo)))))
+ (let ((count 0)
+ next)
+ (goto-char beg)
+ (while (setq next
+ (bidi-find-overridden-directionality
+ (point) end nil
+ (current-bidi-paragraph-direction)))
+ (goto-char next)
+ ;; We detect the problematic parts by watching directional
+ ;; properties of strong L2R and R2L characters. But
+ ;; malicious reordering in source buffers can, and usuually
+ ;; does, include syntactically-important punctuation
+ ;; characters. Those have "weak" directionality, so we
+ ;; cannot easily detect when they are affected in malicious
+ ;; ways. Therefore, once we find a strong directional
+ ;; character whose directionality was tweaked, we highlight
+ ;; the text around it, between the first bidi control
+ ;; character we find before it that starts an
+ ;; override/embedding/isolate, and the first control after
+ ;; it that ends these. This could sometimes highlight only
+ ;; part of the affected text. An alternative would be to
+ ;; find the first "starter" following BOL and the last
+ ;; "ender" before EOL, and highlight everything in between
+ ;; them -- this could sometimes highlight too much.
+ (let ((start
+ (save-excursion
+ (re-search-backward reorder-starters nil t)))
+ (finish
+ (save-excursion
+ (let ((fin (re-search-forward reorder-enders nil t)))
+ (if fin (1- fin)
+ (point-max))))))
+ (with-silent-modifications
+ (add-text-properties start finish
+ '(font-lock-face
+ confusingly-reordered
+ face confusingly-reordered
+ mouse-face highlight
+ help-echo "\
+This text is reordered on display in a way that could change its semantics;
+use \\[forward-char] and \\[backward-char] to see the actual order of characters.")))
+ (goto-char finish)
+ (setq count (1+ count))))
+ (message
+ (if (> count 0)
+ (ngettext
+ "Highlighted %d confusingly-reordered text string"
+ "Highlighted %d confusingly-reordered text strings"
+ count)
+ "No confusingly-reordered text strings were found")
+ count)))))
;;; mule-cmds.el ends here
diff --git a/lisp/international/mule-conf.el b/lisp/international/mule-conf.el
index 2d36dab6320..ec027e9a932 100644
--- a/lisp/international/mule-conf.el
+++ b/lisp/international/mule-conf.el
@@ -148,6 +148,7 @@
(defmacro define-iso-single-byte-charset (symbol iso-symbol name nickname
iso-ir iso-final
emacs-mule-id map)
+ (declare (indent defun))
`(progn
(define-charset ,symbol
,name
@@ -1679,6 +1680,7 @@ for decoding and encoding files, process I/O, etc."
(defcustom password-word-equivalents
'("password" "passcode" "passphrase" "pass phrase" "pin"
+ "decryption key" "encryption key" ; From ccrypt.
; These are sorted according to the GNU en_US locale.
"암호" ; ko
"パスワード" ; ja
diff --git a/lisp/international/mule-diag.el b/lisp/international/mule-diag.el
index 02169ceb689..efb9296c110 100644
--- a/lisp/international/mule-diag.el
+++ b/lisp/international/mule-diag.el
@@ -299,65 +299,66 @@ meanings of these arguments."
(defun describe-character-set (charset)
"Display information about built-in character set CHARSET."
(interactive (list (read-charset "Charset: ")))
- (or (charsetp charset)
- (error "Invalid charset: %S" charset))
- (help-setup-xref (list #'describe-character-set charset)
- (called-interactively-p 'interactive))
- (with-output-to-temp-buffer (help-buffer)
- (with-current-buffer standard-output
- (insert "Character set: " (symbol-name charset))
- (let ((name (get-charset-property charset :name)))
- (if (not (eq name charset))
- (insert " (alias of " (symbol-name name) ?\))))
- (insert "\n\n" (charset-description charset) "\n\n")
- (insert "Number of contained characters: ")
- (dotimes (i (charset-dimension charset))
- (unless (= i 0)
- (insert ?x))
- (insert (format "%d" (charset-chars charset (1+ i)))))
- (insert ?\n)
- (let ((char (charset-iso-final-char charset)))
- (when (> char 0)
- (insert "Final char of ISO2022 designation sequence: ")
- (insert (format-message "`%c'\n" char))))
- (let (aliases)
- (dolist (c charset-list)
- (if (and (not (eq c charset))
- (eq charset (get-charset-property c :name)))
- (push c aliases)))
- (if aliases
- (insert "Aliases: " (mapconcat #'symbol-name aliases ", ") ?\n)))
-
- (dolist (elt `((:ascii-compatible-p "ASCII compatible." nil)
- (:map "Map file: " identity)
- (:unify-map "Unification map file: " identity)
- (:invalid-code
- nil
- ,(lambda (c)
- (format "Invalid character: %c (code %d)" c c)))
- (:emacs-mule-id "Id in emacs-mule coding system: "
- number-to-string)
- (:parents "Parents: "
- (lambda (parents)
- (mapconcat ,(lambda (elt)
- (format "%s" elt))
- parents
- ", ")))
- (:code-space "Code space: " ,(lambda (c)
- (format "%s" c)))
- (:code-offset "Code offset: " number-to-string)
- (:iso-revision-number "ISO revision number: "
- number-to-string)
- (:supplementary-p
- "Used only as a parent or a subset of some other charset,
+ (let ((help-buffer-under-preparation t))
+ (or (charsetp charset)
+ (error "Invalid charset: %S" charset))
+ (help-setup-xref (list #'describe-character-set charset)
+ (called-interactively-p 'interactive))
+ (with-output-to-temp-buffer (help-buffer)
+ (with-current-buffer standard-output
+ (insert "Character set: " (symbol-name charset))
+ (let ((name (get-charset-property charset :name)))
+ (if (not (eq name charset))
+ (insert " (alias of " (symbol-name name) ?\))))
+ (insert "\n\n" (charset-description charset) "\n\n")
+ (insert "Number of contained characters: ")
+ (dotimes (i (charset-dimension charset))
+ (unless (= i 0)
+ (insert ?x))
+ (insert (format "%d" (charset-chars charset (1+ i)))))
+ (insert ?\n)
+ (let ((char (charset-iso-final-char charset)))
+ (when (> char 0)
+ (insert "Final char of ISO2022 designation sequence: ")
+ (insert (format-message "`%c'\n" char))))
+ (let (aliases)
+ (dolist (c charset-list)
+ (if (and (not (eq c charset))
+ (eq charset (get-charset-property c :name)))
+ (push c aliases)))
+ (if aliases
+ (insert "Aliases: " (mapconcat #'symbol-name aliases ", ") ?\n)))
+
+ (dolist (elt `((:ascii-compatible-p "ASCII compatible." nil)
+ (:map "Map file: " identity)
+ (:unify-map "Unification map file: " identity)
+ (:invalid-code
+ nil
+ ,(lambda (c)
+ (format "Invalid character: %c (code %d)" c c)))
+ (:emacs-mule-id "Id in emacs-mule coding system: "
+ number-to-string)
+ (:parents "Parents: "
+ (lambda (parents)
+ (mapconcat ,(lambda (elt)
+ (format "%s" elt))
+ parents
+ ", ")))
+ (:code-space "Code space: " ,(lambda (c)
+ (format "%s" c)))
+ (:code-offset "Code offset: " number-to-string)
+ (:iso-revision-number "ISO revision number: "
+ number-to-string)
+ (:supplementary-p
+ "Used only as a parent or a subset of some other charset,
or provided just for backward compatibility." nil)))
- (let ((val (get-charset-property charset (car elt))))
- (when val
- (if (cadr elt) (insert (cadr elt)))
- (if (nth 2 elt)
- (let ((print-length 10) (print-level 2))
- (princ (funcall (nth 2 elt) val) (current-buffer))))
- (insert ?\n)))))))
+ (let ((val (get-charset-property charset (car elt))))
+ (when val
+ (if (cadr elt) (insert (cadr elt)))
+ (if (nth 2 elt)
+ (let ((print-length 10) (print-level 2))
+ (princ (funcall (nth 2 elt) val) (current-buffer))))
+ (insert ?\n))))))))
;;; CODING-SYSTEM
@@ -406,89 +407,90 @@ or provided just for backward compatibility." nil)))
(defun describe-coding-system (coding-system)
"Display information about CODING-SYSTEM."
(interactive "zDescribe coding system (default current choices): ")
- (if (null coding-system)
- (describe-current-coding-system)
- (help-setup-xref (list #'describe-coding-system coding-system)
- (called-interactively-p 'interactive))
- (with-output-to-temp-buffer (help-buffer)
- (print-coding-system-briefly coding-system 'doc-string)
- (let ((type (coding-system-type coding-system))
- ;; Fixme: use this
- ;; (extra-spec (coding-system-plist coding-system))
- )
- (princ "Type: ")
- (princ type)
- (cond ((eq type 'undecided)
- (princ " (do automatic conversion)"))
- ((eq type 'utf-8)
- (princ " (UTF-8: Emacs internal multibyte form)"))
- ((eq type 'utf-16)
- ;; (princ " (UTF-16)")
- )
- ((eq type 'shift-jis)
- (princ " (Shift-JIS, MS-KANJI)"))
- ((eq type 'iso-2022)
- (princ " (variant of ISO-2022)\n")
- (princ "Initial designations:\n")
- (print-designation (coding-system-get coding-system
- :designation))
-
- (when (coding-system-get coding-system :flags)
- (princ "Other specifications: \n ")
- (apply #'print-list
- (coding-system-get coding-system :flags))))
- ((eq type 'charset)
- (princ " (charset)"))
- ((eq type 'ccl)
- (princ " (do conversion by CCL program)"))
- ((eq type 'raw-text)
- (princ " (text with random binary characters)"))
- ((eq type 'emacs-mule)
- (princ " (Emacs 21 internal encoding)"))
- ((eq type 'big5))
- (t (princ ": invalid coding-system.")))
- (princ "\nEOL type: ")
- (let ((eol-type (coding-system-eol-type coding-system)))
- (cond ((vectorp eol-type)
- (princ "Automatic selection from:\n\t")
- (princ eol-type)
- (princ "\n"))
- ((or (null eol-type) (eq eol-type 0)) (princ "LF\n"))
- ((eq eol-type 1) (princ "CRLF\n"))
- ((eq eol-type 2) (princ "CR\n"))
- (t (princ "invalid\n")))))
- (let ((postread (coding-system-get coding-system :post-read-conversion)))
- (when postread
- (princ "After decoding text normally,")
- (princ " perform post-conversion using the function: ")
- (princ "\n ")
- (princ postread)
- (princ "\n")))
- (let ((prewrite (coding-system-get coding-system :pre-write-conversion)))
- (when prewrite
- (princ "Before encoding text normally,")
- (princ " perform pre-conversion using the function: ")
- (princ "\n ")
- (princ prewrite)
- (princ "\n")))
- (with-current-buffer standard-output
- (let ((charsets (coding-system-charset-list coding-system)))
- (when (and (not (eq (coding-system-base coding-system) 'raw-text))
- charsets)
- (cond
- ((eq charsets 'iso-2022)
- (insert "This coding system can encode all ISO 2022 charsets."))
- ((eq charsets 'emacs-mule)
- (insert "This coding system can encode all emacs-mule charsets\
+ (let ((help-buffer-under-preparation t))
+ (if (null coding-system)
+ (describe-current-coding-system)
+ (help-setup-xref (list #'describe-coding-system coding-system)
+ (called-interactively-p 'interactive))
+ (with-output-to-temp-buffer (help-buffer)
+ (print-coding-system-briefly coding-system 'doc-string)
+ (let ((type (coding-system-type coding-system))
+ ;; Fixme: use this
+ ;; (extra-spec (coding-system-plist coding-system))
+ )
+ (princ "Type: ")
+ (princ type)
+ (cond ((eq type 'undecided)
+ (princ " (do automatic conversion)"))
+ ((eq type 'utf-8)
+ (princ " (UTF-8: Emacs internal multibyte form)"))
+ ((eq type 'utf-16)
+ ;; (princ " (UTF-16)")
+ )
+ ((eq type 'shift-jis)
+ (princ " (Shift-JIS, MS-KANJI)"))
+ ((eq type 'iso-2022)
+ (princ " (variant of ISO-2022)\n")
+ (princ "Initial designations:\n")
+ (print-designation (coding-system-get coding-system
+ :designation))
+
+ (when (coding-system-get coding-system :flags)
+ (princ "Other specifications: \n ")
+ (apply #'print-list
+ (coding-system-get coding-system :flags))))
+ ((eq type 'charset)
+ (princ " (charset)"))
+ ((eq type 'ccl)
+ (princ " (do conversion by CCL program)"))
+ ((eq type 'raw-text)
+ (princ " (text with random binary characters)"))
+ ((eq type 'emacs-mule)
+ (princ " (Emacs 21 internal encoding)"))
+ ((eq type 'big5))
+ (t (princ ": invalid coding-system.")))
+ (princ "\nEOL type: ")
+ (let ((eol-type (coding-system-eol-type coding-system)))
+ (cond ((vectorp eol-type)
+ (princ "Automatic selection from:\n\t")
+ (princ eol-type)
+ (princ "\n"))
+ ((or (null eol-type) (eq eol-type 0)) (princ "LF\n"))
+ ((eq eol-type 1) (princ "CRLF\n"))
+ ((eq eol-type 2) (princ "CR\n"))
+ (t (princ "invalid\n")))))
+ (let ((postread (coding-system-get coding-system :post-read-conversion)))
+ (when postread
+ (princ "After decoding text normally,")
+ (princ " perform post-conversion using the function: ")
+ (princ "\n ")
+ (princ postread)
+ (princ "\n")))
+ (let ((prewrite (coding-system-get coding-system :pre-write-conversion)))
+ (when prewrite
+ (princ "Before encoding text normally,")
+ (princ " perform pre-conversion using the function: ")
+ (princ "\n ")
+ (princ prewrite)
+ (princ "\n")))
+ (with-current-buffer standard-output
+ (let ((charsets (coding-system-charset-list coding-system)))
+ (when (and (not (eq (coding-system-base coding-system) 'raw-text))
+ charsets)
+ (cond
+ ((eq charsets 'iso-2022)
+ (insert "This coding system can encode all ISO 2022 charsets."))
+ ((eq charsets 'emacs-mule)
+ (insert "This coding system can encode all emacs-mule charsets\
."""))
- (t
- (insert "This coding system encodes the following charsets:\n ")
- (while charsets
- (insert " " (symbol-name (car charsets)))
- (search-backward (symbol-name (car charsets)))
- (help-xref-button 0 'help-character-set (car charsets))
- (goto-char (point-max))
- (setq charsets (cdr charsets)))))))))))
+ (t
+ (insert "This coding system encodes the following charsets:\n ")
+ (while charsets
+ (insert " " (symbol-name (car charsets)))
+ (search-backward (symbol-name (car charsets)))
+ (help-xref-button 0 'help-character-set (car charsets))
+ (goto-char (point-max))
+ (setq charsets (cdr charsets))))))))))))
;;;###autoload
(defun describe-current-coding-system-briefly ()
@@ -833,7 +835,7 @@ The IGNORED argument is ignored."
"Display information about a font whose name is FONTNAME."
(interactive
(list (completing-read
- "Font name (default current choice for ASCII chars): "
+ (format-prompt "Font name" "current choice for ASCII chars")
(and window-system
;; Implied by `window-system'.
(fboundp 'x-list-fonts)
@@ -845,7 +847,8 @@ The IGNORED argument is ignored."
(or (and window-system (fboundp 'fontset-list))
(error "No fonts being used"))
(let ((xref-item (list #'describe-font fontname))
- font-info)
+ font-info
+ (help-buffer-under-preparation t))
(if (or (not fontname) (= (length fontname) 0))
(setq fontname (face-attribute 'default :font)))
(setq font-info (font-info fontname))
@@ -862,15 +865,28 @@ The IGNORED argument is ignored."
(defvar mule--print-opened)
+(defun mule--kbd-at (point)
+ (save-excursion
+ (goto-char point)
+ (elt
+ (kbd (buffer-substring
+ (point)
+ (progn
+ ;; Might be a space, in which case we want it.
+ (if (zerop (skip-chars-forward "^ "))
+ (1+ (point))
+ (point)))))
+ 0)))
+
(defun print-fontset-element (val)
;; VAL has this format:
;; ((REQUESTED-FONT-NAME OPENED-FONT-NAME ...) ...)
;; CHAR RANGE is already inserted. Get character codes from
;; the current line.
(beginning-of-line)
- (let ((from (following-char))
- (to (if (looking-at "[^.]*[.]* ")
- (char-after (match-end 0)))))
+ (let ((from (mule--kbd-at (point)))
+ (to (if (looking-at "[^.]+[.][.] ")
+ (mule--kbd-at (match-end 0)))))
(if (re-search-forward "[ \t]*$" nil t)
(delete-region (match-beginning 0) (match-end 0)))
@@ -991,16 +1007,17 @@ This shows which font is used for which character(s)."
(mapcar 'cdr fontset-alias-alist)))
(completion-ignore-case t))
(list (completing-read
- "Fontset (default used by the current frame): "
+ (format-prompt "Fontset" "used by the current frame")
fontset-list nil t)))))
- (if (= (length fontset) 0)
- (setq fontset (face-attribute 'default :fontset))
- (setq fontset (query-fontset fontset)))
- (help-setup-xref (list #'describe-fontset fontset)
- (called-interactively-p 'interactive))
- (with-output-to-temp-buffer (help-buffer)
- (with-current-buffer standard-output
- (print-fontset fontset t))))
+ (let ((help-buffer-under-preparation t))
+ (if (= (length fontset) 0)
+ (setq fontset (face-attribute 'default :fontset))
+ (setq fontset (query-fontset fontset)))
+ (help-setup-xref (list #'describe-fontset fontset)
+ (called-interactively-p 'interactive))
+ (with-output-to-temp-buffer (help-buffer)
+ (with-current-buffer standard-output
+ (print-fontset fontset t)))))
(declare-function fontset-plain-name "fontset" (fontset))
@@ -1011,39 +1028,41 @@ This shows the name, size, and style of each fontset.
With prefix arg, also list the fonts contained in each fontset;
see the function `describe-fontset' for the format of the list."
(interactive "P")
- (if (not (and window-system (fboundp 'fontset-list)))
- (error "No fontsets being used")
- (help-setup-xref (list #'list-fontsets arg)
- (called-interactively-p 'interactive))
- (with-output-to-temp-buffer (help-buffer)
- (with-current-buffer standard-output
- ;; This code is duplicated near the end of mule-diag.
- (let ((fontsets
- (sort (fontset-list)
- (lambda (x y)
- (string< (fontset-plain-name x)
- (fontset-plain-name y))))))
- (while fontsets
- (if arg
- (print-fontset (car fontsets) nil)
- (insert "Fontset: " (car fontsets) "\n"))
- (setq fontsets (cdr fontsets))))))))
+ (let ((help-buffer-under-preparation t))
+ (if (not (and window-system (fboundp 'fontset-list)))
+ (error "No fontsets being used")
+ (help-setup-xref (list #'list-fontsets arg)
+ (called-interactively-p 'interactive))
+ (with-output-to-temp-buffer (help-buffer)
+ (with-current-buffer standard-output
+ ;; This code is duplicated near the end of mule-diag.
+ (let ((fontsets
+ (sort (fontset-list)
+ (lambda (x y)
+ (string< (fontset-plain-name x)
+ (fontset-plain-name y))))))
+ (while fontsets
+ (if arg
+ (print-fontset (car fontsets) nil)
+ (insert "Fontset: " (car fontsets) "\n"))
+ (setq fontsets (cdr fontsets)))))))))
;;;###autoload
(defun list-input-methods ()
"Display information about all input methods."
(interactive)
- (help-setup-xref '(list-input-methods)
- (called-interactively-p 'interactive))
- (with-output-to-temp-buffer (help-buffer)
- (list-input-methods-1)
- (with-current-buffer standard-output
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward
- (substitute-command-keys "^ \\([^ ]+\\) (`.*' in mode line)$")
- nil t)
- (help-xref-button 1 'help-input-method (match-string 1)))))))
+ (let ((help-buffer-under-preparation t))
+ (help-setup-xref '(list-input-methods)
+ (called-interactively-p 'interactive))
+ (with-output-to-temp-buffer (help-buffer)
+ (list-input-methods-1)
+ (with-current-buffer standard-output
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward
+ (substitute-command-keys "^ \\([^ ]+\\) (`.*' in mode line)$")
+ nil t)
+ (help-xref-button 1 'help-input-method (match-string 1))))))))
(defun list-input-methods-1 ()
(if (not input-method-alist)
diff --git a/lisp/international/mule-util.el b/lisp/international/mule-util.el
index 38d29cb2385..c2f91e77e7c 100644
--- a/lisp/international/mule-util.el
+++ b/lisp/international/mule-util.el
@@ -67,10 +67,15 @@ decide whether the selected frame can display that Unicode character."
ellipsis-text-property)
"Truncate string STR to end at column END-COLUMN.
The optional 3rd arg START-COLUMN, if non-nil, specifies the starting
-column; that means to return the characters occupying columns
-START-COLUMN ... END-COLUMN of STR. Both END-COLUMN and START-COLUMN
-are specified in terms of character display width in the current
-buffer; see also `char-width'.
+column (default: zero); that means to return the characters occupying
+columns START-COLUMN ... END-COLUMN of STR. Both END-COLUMN and
+START-COLUMN are specified in terms of character display width in the
+current buffer; see `char-width'.
+
+Since character composition on display can produce glyphs whose
+width is smaller than the sum of `char-width' values of the
+composed characters, this function can produce inaccurate results
+when used in such cases.
The optional 4th arg PADDING, if non-nil, specifies a padding
character (which should have a display width of 1) to add at the end
diff --git a/lisp/international/mule.el b/lisp/international/mule.el
index 9cd38afd8be..3e45a64dc9a 100644
--- a/lisp/international/mule.el
+++ b/lisp/international/mule.el
@@ -218,6 +218,7 @@ corresponding Unicode character code.
If it is a string, it is a name of file that contains the above
information. The file format is the same as what described for `:map'
attribute."
+ (declare (indent defun))
(when (vectorp (car props))
;; Old style code:
;; (define-charset CHARSET-ID CHARSET-SYMBOL INFO-VECTOR)
@@ -294,6 +295,8 @@ attribute."
(apply 'define-charset-internal name (mapcar 'cdr attrs))))
+(defvar hack-read-symbol-shorthands-function nil
+ "Holds function to compute `read-symbol-shorthands'.")
(defun load-with-code-conversion (fullname file &optional noerror nomessage)
"Execute a file of Lisp code named FILE whose absolute name is FULLNAME.
@@ -320,7 +323,8 @@ Return t if file exists."
(let ((load-true-file-name fullname)
(load-file-name fullname)
(set-auto-coding-for-load t)
- (inhibit-file-name-operation nil))
+ (inhibit-file-name-operation nil)
+ shorthands)
(with-current-buffer buffer
;; So that we don't get completely screwed if the
;; file is encoded in some complicated character set,
@@ -329,6 +333,13 @@ Return t if file exists."
;; Don't let deactivate-mark remain set.
(let (deactivate-mark)
(insert-file-contents fullname))
+ (setq shorthands
+ ;; We need this indirection because hacking local
+ ;; variables in too early seems to have cause
+ ;; recursive load loops (bug#50946). Thus it
+ ;; remains nil until it is save to do so.
+ (and hack-read-symbol-shorthands-function
+ (funcall hack-read-symbol-shorthands-function)))
;; If the loaded file was inserted with no-conversion or
;; raw-text coding system, make the buffer unibyte.
;; Otherwise, eval-buffer might try to interpret random
@@ -339,11 +350,13 @@ Return t if file exists."
(set-buffer-multibyte nil))
;; Make `kill-buffer' quiet.
(set-buffer-modified-p nil))
- ;; Have the original buffer current while we eval.
- (eval-buffer buffer nil
- ;; This is compatible with what `load' does.
- (if dump-mode file fullname)
- nil t))
+ ;; Have the original buffer current while we eval,
+ ;; but consider shorthands of the eval'ed one.
+ (let ((read-symbol-shorthands shorthands))
+ (eval-buffer buffer nil
+ ;; This is compatible with what `load' does.
+ (if dump-mode file fullname)
+ nil t)))
(let (kill-buffer-hook kill-buffer-query-functions)
(kill-buffer buffer)))
(do-after-load-evaluation fullname)
@@ -878,6 +891,7 @@ non-nil.
VALUE non-nil means Emacs prefers UTF-8 on code detection for
non-ASCII files. This attribute is meaningful only when
`:coding-type' is `undecided'."
+ (declare (indent defun))
(let* ((common-attrs (mapcar 'list
'(:mnemonic
:coding-type
@@ -1148,7 +1162,7 @@ Value is a list of transformed arguments."
(,(plist-get props 'decode) . ,(plist-get props 'encode))
,properties ,eol-type))
(t
- (error "unsupported XEmacs style make-coding-style arguments: %S"
+ (error "Unsupported XEmacs style make-coding-style arguments: %S"
`(,name ,type ,doc-string ,props))))))
(defun merge-coding-systems (first second)
@@ -1380,8 +1394,11 @@ If CODING-SYSTEM is nil or the coding-type of CODING-SYSTEM is
`raw-text', the decoding of keyboard input is disabled.
TERMINAL may be a terminal object, a frame, or nil for the
-selected frame's terminal. The setting has no effect on
-graphical terminals."
+selected frame's terminal.
+
+The setting has no effect on graphical terminals. It also
+has no effect on MS-Windows text-mode terminals, except on
+Windows 9X systems. For Windows 9X, see also `w32-set-console-codepage'."
(interactive
(list (let* ((coding (keyboard-coding-system nil))
(default (if (eq (coding-system-type coding) 'raw-text)
@@ -2305,6 +2322,7 @@ This function sets properties `translation-table' and
`translation-table-id' of SYMBOL to the created table itself and the
identification number of the table respectively. It also registers
the table in `translation-table-vector'."
+ (declare (indent defun))
(let ((table (if (and (char-table-p (car args))
(eq (char-table-subtype (car args))
'translation-table))
@@ -2379,6 +2397,7 @@ Value is what BODY returns."
Analogous to `define-translation-table', but updates
`translation-hash-table-vector' and the table is for use in the CCL
`lookup-integer' and `lookup-character' functions."
+ (declare (indent defun))
(unless (and (symbolp symbol)
(hash-table-p table))
(error "Bad args to define-translation-hash-table"))
diff --git a/lisp/international/quail.el b/lisp/international/quail.el
index 5d1311530a5..5cdd6d6242b 100644
--- a/lisp/international/quail.el
+++ b/lisp/international/quail.el
@@ -471,7 +471,8 @@ conversion region is active. It is an alist of single key character
vs. corresponding command to be called.
If SIMPLE is non-nil, then we do not alter the meanings of
-commands such as C-f, C-b, C-n, C-p and TAB; they are treated as
+commands such as \\[forward-char], \\[backward-char], \\[next-line], \
+\\[previous-line] and \\[indent-for-tab-command]; they are treated as
non-Quail commands."
(let (translation-keymap conversion-keymap)
(if deterministic (setq forget-last-selection t))
@@ -916,7 +917,7 @@ The format of KBD-LAYOUT is the same as `quail-keyboard-layout'."
The variable `quail-keyboard-layout-type' holds the currently selected
keyboard type."
(interactive
- (list (completing-read "Keyboard type (default current choice): "
+ (list (completing-read (format-prompt "Keyboard type" "current choice")
quail-keyboard-layout-alist
nil t)))
(or (and keyboard-type (> (length keyboard-type) 0))
@@ -1381,6 +1382,8 @@ a cons cell of the form (no-record . KEY).
If KEY is a vector of events, the events in the vector are prepended
to `unread-command-events', after converting each event to a cons cell
of the form (no-record . EVENT).
+If KEY is an event, it is prepended to `unread-command-events' as a cons
+cell of the form (no-record . EVENT).
If RESET is non-nil, the events in `unread-command-events' are first
discarded, i.e. in this case KEY will end up being the only key
in `unread-command-events'."
@@ -1389,7 +1392,7 @@ in `unread-command-events'."
(if (characterp key)
(cons (cons 'no-record key) unread-command-events)
(append (mapcan (lambda (e) (list (cons 'no-record e)))
- (append key nil))
+ (append (if (vectorp key) key (vector key)) nil))
unread-command-events))))
(defun quail-start-translation (key)
@@ -2020,7 +2023,7 @@ minibuffer and the selected frame has no other windows)."
(bury-buffer quail-completion-buf)
;; Then, show the guidance.
- (when (and
+ (when (and
;; Don't try to display guidance on an expired minibuffer. This
;; would go into an infinite wait rather than executing the user's
;; command. Bug #45792.
diff --git a/lisp/international/robin.el b/lisp/international/robin.el
index e4a11801c38..4c498d7f923 100644
--- a/lisp/international/robin.el
+++ b/lisp/international/robin.el
@@ -276,8 +276,7 @@ this robin package will be the following.
(?c \"AC\"
(?d \"ACD\")
(?e \"ACE\")))
- (?b \"B\"))
-")
+ (?b \"B\"))")
;;;###autoload
(defmacro robin-define-package (name docstring &rest rules)
@@ -530,10 +529,10 @@ Use the longest match method to select a rule."
(insert (cadr tree))
(delete-char (- end begin)))))
-;; for backward compatibility
-
-(fset 'robin-transliterate-region 'robin-convert-region)
-(fset 'robin-transliterate-buffer 'robin-convert-buffer)
+(define-obsolete-function-alias 'robin-transliterate-region
+ #'robin-convert-region "29.1")
+(define-obsolete-function-alias 'robin-transliterate-buffer
+ #'robin-convert-buffer "29.1")
;;; Reverse conversion
diff --git a/lisp/international/titdic-cnv.el b/lisp/international/titdic-cnv.el
index ccb4c8390bb..4ac0100746e 100644
--- a/lisp/international/titdic-cnv.el
+++ b/lisp/international/titdic-cnv.el
@@ -627,8 +627,8 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"."
py-converter
"\
;; \"pinyin.map\" is included in a free package called CCE. It is
-;; available at:
-;; http://ftp.debian.org/debian/dists/potato/main
+;; available at: [link needs updating -- SK 2021-09-27]
+;; https://ftp.debian.org/debian/dists/potato/main
;; /source/utils/cce_0.36.orig.tar.gz
;; This package contains the following copyright notice.
;;
@@ -655,8 +655,8 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"."
ziranma-converter
"\
;; \"ziranma.cin\" is included in a free package called CCE. It is
-;; available at:
-;; http://ftp.debian.org/debian/dists/potato/main
+;; available at: [link needs updating -- SK 2021-09-27]
+;; https://ftp.debian.org/debian/dists/potato/main
;; /source/utils/cce_0.36.orig.tar.gz
;; This package contains the following copyright notice.
;;
@@ -748,7 +748,7 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"."
[Q 手] [W 田] [E 水] [R 口] [T 廿] [Y 卜] [U 山] [I 戈] [O 人] [P 心]
- [A 日] [S 尸] [D 木] [F 火] [G 土] [H 竹] [J 十] [L 中]
+ [A 日] [S 尸] [D 木] [F 火] [G 土] [H 竹] [J 十] [K 大] [L 中]
[Z ] [X 難] [C 金] [V 女] [B 月] [N 弓] [M 一]
diff --git a/lisp/international/ucs-normalize.el b/lisp/international/ucs-normalize.el
index 0f8dedfc09b..3da47e701ab 100644
--- a/lisp/international/ucs-normalize.el
+++ b/lisp/international/ucs-normalize.el
@@ -536,74 +536,124 @@ COMPOSITION-PREDICATE will be used to compose region."
(,ucs-normalize-region (point-min) (point-max))
(buffer-string)))
-;;;###autoload
(defun ucs-normalize-NFD-region (from to)
- "Normalize the current region by the Unicode NFD."
+ "Decompose the region between FROM and TO according to the Unicode NFD.
+This replaces the text between FROM and TO with its canonical decomposition,
+a.k.a. the \"Unicode Normalization Form D\"."
(interactive "r")
(ucs-normalize-region from to
ucs-normalize-nfd-quick-check-regexp
'ucs-normalize-nfd-table nil))
-;;;###autoload
+
(defun ucs-normalize-NFD-string (str)
- "Normalize the string STR by the Unicode NFD."
+ "Decompose the string STR according to the Unicode NFD.
+This returns a new string that is the canonical decomposition of STR,
+a.k.a. the \"Unicode Normalization Form D\" of STR. For instance:
+
+ (ucs-normalize-NFD-string \"Å\") => \"Å\""
(ucs-normalize-string ucs-normalize-NFD-region))
-;;;###autoload
(defun ucs-normalize-NFC-region (from to)
- "Normalize the current region by the Unicode NFC."
+ "Compose the region between FROM and TO according to the Unicode NFC.
+This replaces the text between FROM and TO with the result of its
+canonical decomposition (see `ucs-normalize-NFD-region') followed by
+canonical composition, a.k.a. the \"Unicode Normalization Form C\"."
(interactive "r")
(ucs-normalize-region from to
ucs-normalize-nfc-quick-check-regexp
'ucs-normalize-nfd-table t))
+
;;;###autoload
+(defun string-glyph-compose (string)
+ "Compose STRING according to the Unicode NFC.
+This returns a new string obtained by canonical decomposition
+of STRING (see `ucs-normalize-NFC-string') followed by canonical
+composition, a.k.a. the \"Unicode Normalization Form C\" of STRING.
+For instance:
+
+ (string-glyph-compose \"Å\") => \"Å\""
+ (ucs-normalize-NFC-string string))
+
+;;;###autoload
+(defun string-glyph-decompose (string)
+ "Decompose STRING according to the Unicode NFD.
+This returns a new string that is the canonical decomposition of STRING,
+a.k.a. the \"Unicode Normalization Form D\" of STRING. For instance:
+
+ (ucs-normalize-NFD-string \"Å\") => \"Å\""
+ (ucs-normalize-NFD-string string))
+
(defun ucs-normalize-NFC-string (str)
- "Normalize the string STR by the Unicode NFC."
+ "Compose STR according to the Unicode NFC.
+This returns a new string obtained by canonical decomposition
+of STR (see `ucs-normalize-NFC-string') followed by canonical
+composition, a.k.a. the \"Unicode Normalization Form C\" of STR.
+For instance:
+
+ (string-glyph-compose \"Å\") => \"Å\""
(ucs-normalize-string ucs-normalize-NFC-region))
-;;;###autoload
(defun ucs-normalize-NFKD-region (from to)
- "Normalize the current region by the Unicode NFKD."
+ "Decompose the region between FROM and TO according to the Unicode NFKD.
+This replaces the text between FROM and TO with its compatibility
+decomposition, a.k.a. \"Unicode Normalization Form KD\"."
(interactive "r")
(ucs-normalize-region from to
ucs-normalize-nfkd-quick-check-regexp
'ucs-normalize-nfkd-table nil))
-;;;###autoload
+
(defun ucs-normalize-NFKD-string (str)
- "Normalize the string STR by the Unicode NFKD."
+ "Decompose the string STR according to the Unicode NFKD.
+This returns a new string obtained by compatibility decomposition
+of STR. This is much like the NFD (canonical decomposition) form,
+see `ucs-normalize-NFD-string', but mainly differs for precomposed
+characters. For instance:
+
+ (ucs-normalize-NFD-string \"fi\") => \"fi\"
+ (ucs-normalize-NFKD-string \"fi\") = \"fi\""
(ucs-normalize-string ucs-normalize-NFKD-region))
-;;;###autoload
(defun ucs-normalize-NFKC-region (from to)
- "Normalize the current region by the Unicode NFKC."
+ "Compose the region between FROM and TO according to the Unicode NFKC.
+This replaces the text between FROM and TO with the result of its
+compatibility decomposition (see `ucs-normalize-NFC-region') followed by
+canonical composition, a.k.a. the \"Unicode Normalization Form KC\"."
(interactive "r")
(ucs-normalize-region from to
ucs-normalize-nfkc-quick-check-regexp
'ucs-normalize-nfkd-table t))
-;;;###autoload
+
(defun ucs-normalize-NFKC-string (str)
- "Normalize the string STR by the Unicode NFKC."
+ "Compose STR according to the Unicode NFC.
+This returns a new string obtained by compatibility decomposition
+of STR (see `ucs-normalize-NFKD-string') followed by canonical
+composition, a.k.a. the \"Unicode Normalization Form KC\" of STR.
+This is much like the NFC (canonical composition) form, but mainly
+differs for precomposed characters. For instance:
+
+ (ucs-normalize-NFC-string \"fi\") => \"fi\"
+ (ucs-normalize-NFKC-string \"fi\") = \"fi\""
(ucs-normalize-string ucs-normalize-NFKC-region))
-;;;###autoload
(defun ucs-normalize-HFS-NFD-region (from to)
- "Normalize the current region by the Unicode NFD and Mac OS's HFS Plus."
+ "Normalize region between FROM and TO by Unicode NFD and Mac OS's HFS Plus."
(interactive "r")
(ucs-normalize-region from to
ucs-normalize-hfs-nfd-quick-check-regexp
'ucs-normalize-hfs-nfd-table
'ucs-normalize-hfs-nfd-comp-p))
-;;;###autoload
+
(defun ucs-normalize-HFS-NFD-string (str)
"Normalize the string STR by the Unicode NFD and Mac OS's HFS Plus."
(ucs-normalize-string ucs-normalize-HFS-NFD-region))
-;;;###autoload
+
(defun ucs-normalize-HFS-NFC-region (from to)
- "Normalize the current region by the Unicode NFC and Mac OS's HFS Plus."
+ "Normalize region between FROM and TO by Unicode NFC and Mac OS's HFS Plus."
(interactive "r")
(ucs-normalize-region from to
ucs-normalize-hfs-nfc-quick-check-regexp
'ucs-normalize-hfs-nfd-table t))
-;;;###autoload
+
(defun ucs-normalize-HFS-NFC-string (str)
"Normalize the string STR by the Unicode NFC and Mac OS's HFS Plus."
(ucs-normalize-string ucs-normalize-HFS-NFC-region))
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 922ab0f6ad4..8815cb4f2d6 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -114,7 +114,7 @@ is called to let you enter the search string, and RET terminates editing
and does a nonincremental search.)"
:type 'boolean)
-(defcustom search-whitespace-regexp (purecopy "\\s-+")
+(defcustom search-whitespace-regexp (purecopy "[ \t]+")
"If non-nil, regular expression to match a sequence of whitespace chars.
When you enter a space or spaces in the incremental search, it
will match any sequence matched by this regexp. As an exception,
@@ -133,8 +133,10 @@ tab, a carriage return (control-M), a newline, and `]+'. Don't
add any capturing groups into this value; that can change the
numbering of existing capture groups in unexpected ways."
:type '(choice (const :tag "Match Spaces Literally" nil)
+ (const :tag "Tabs and spaces" "[ \t]+")
+ (const :tag "Tabs, spaces and line breaks" "[ \t\n]+")
regexp)
- :version "24.3")
+ :version "28.1")
(defcustom search-invisible 'open
"If t incremental search/query-replace can match hidden text.
@@ -174,11 +176,11 @@ command history."
(defcustom isearch-wrap-pause t
"Define the behavior of wrapping when there are no more matches.
-When `t' (by default), signal an error when no more matches are found.
+When t (by default), signal an error when no more matches are found.
Then after repeating the search, wrap with `isearch-wrap-function'.
When `no', wrap immediately after reaching the last match.
When `no-ding', wrap immediately without flashing the screen.
-When `nil', never wrap, just stop at the last match."
+When nil, never wrap, just stop at the last match."
:type '(choice (const :tag "Pause before wrapping" t)
(const :tag "No pause before wrapping" no)
(const :tag "No pause and no flashing" no-ding)
@@ -187,9 +189,9 @@ When `nil', never wrap, just stop at the last match."
(defcustom isearch-repeat-on-direction-change nil
"Whether a direction change should move to another match.
-When `nil', the default, a direction change moves point to the other
+When nil, the default, a direction change moves point to the other
end of the current search match.
-When `t', a direction change moves to another search match, if there
+When t, a direction change moves to another search match, if there
is one."
:type '(choice (const :tag "Remain on the same match" nil)
(const :tag "Move to another match" t))
@@ -486,9 +488,9 @@ and doesn't remove full-buffer highlighting after a search."
"You have typed %THIS-KEY%, the help character. Type a Help option:
\(Type \\<isearch-help-map>\\[help-quit] to exit the Help command.)
-\\[isearch-describe-bindings] Display all Isearch key bindings.
-\\[isearch-describe-key] KEYS Display full documentation of Isearch key sequence.
-\\[isearch-describe-mode] Display documentation of Isearch mode.
+ \\[isearch-describe-bindings] Display all Isearch key bindings.
+ \\[isearch-describe-key] Display full documentation of Isearch key sequence.
+ \\[isearch-describe-mode] Display documentation of Isearch mode.
You can't type here other help keys available in the global help map,
but outside of this help window when you type them in Isearch mode,
@@ -519,14 +521,14 @@ This is like `describe-bindings', but displays only Isearch keys."
(interactive)
(let ((display-buffer-overriding-action isearch--display-help-action))
(call-interactively 'describe-key))
- (isearch-update))
+ (when isearch-mode (isearch-update)))
(defun isearch-describe-mode ()
"Display documentation of Isearch mode."
(interactive)
(let ((display-buffer-overriding-action isearch--display-help-action))
(describe-function 'isearch-forward))
- (isearch-update))
+ (when isearch-mode (isearch-update)))
(defalias 'isearch-mode-help 'isearch-describe-mode)
@@ -869,7 +871,8 @@ When you enter a space or spaces in ordinary incremental search, it
will match any sequence matched by the regexp defined by the variable
`search-whitespace-regexp'. If the value is nil, each space you type
matches literally, against one space. You can toggle the value of this
-variable by the command `isearch-toggle-lax-whitespace'.")
+variable by the command `isearch-toggle-lax-whitespace', usually bound to
+`M-s SPC' during isearch.")
(defvar isearch-regexp-lax-whitespace nil
"If non-nil, a space will match a sequence of whitespace chars.
@@ -877,7 +880,8 @@ When you enter a space or spaces in regexp incremental search, it
will match any sequence matched by the regexp defined by the variable
`search-whitespace-regexp'. If the value is nil, each space you type
matches literally, against one space. You can toggle the value of this
-variable by the command `isearch-toggle-lax-whitespace'.")
+variable by the command `isearch-toggle-lax-whitespace', usually bound to
+`M-s SPC' during isearch.")
(defvar isearch-cmds nil
"Stack of search status elements.
@@ -1092,7 +1096,8 @@ as a regexp. See the command `isearch-forward' for more information.
In incremental searches, a space or spaces normally matches any
whitespace defined by the variable `search-whitespace-regexp'.
To search for a literal space and nothing else, enter C-q SPC.
-To toggle whitespace matching, use `isearch-toggle-lax-whitespace'.
+To toggle whitespace matching, use `isearch-toggle-lax-whitespace',
+usually bound to `M-s SPC' during isearch.
This command does not support character folding."
(interactive "P\np")
(isearch-mode t (null not-regexp) nil (not no-recursive-edit)))
@@ -1217,7 +1222,7 @@ is processed. (It is not called after characters that exit the search.)
When the arg RECURSIVE-EDIT is non-nil, this function behaves modally and
does not return to the calling function until the search is completed.
-To behave this way it enters a recursive-edit and exits it when done
+To behave this way it enters a recursive edit and exits it when done
isearching.
The arg REGEXP-FUNCTION, if non-nil, should be a function. It is
@@ -1999,7 +2004,8 @@ Move point to the beginning of the buffer and search forwards from the top.
\\<isearch-mode-map>
With a numeric argument, go to the ARGth absolute occurrence counting from
the beginning of the buffer. To find the next relative occurrence forwards,
-type \\[isearch-repeat-forward] with a numeric argument."
+type \\[isearch-repeat-forward] with a numeric argument.
+You might want to use `isearch-allow-motion' instead of this command."
(interactive "p")
(if (and arg (< arg 0))
(isearch-end-of-buffer (abs arg))
@@ -2007,7 +2013,11 @@ type \\[isearch-repeat-forward] with a numeric argument."
;; don't forward char in isearch-repeat
(setq isearch-just-started t)
(goto-char (point-min))
- (isearch-repeat 'forward arg)))
+ (let ((current-direction (if isearch-forward 'forward 'backward))
+ (isearch-repeat-on-direction-change nil))
+ (isearch-repeat 'forward arg)
+ (unless (eq current-direction (if isearch-forward 'forward 'backward))
+ (isearch-repeat current-direction)))))
(defun isearch-end-of-buffer (&optional arg)
"Go to the last occurrence of the current search string.
@@ -2015,13 +2025,18 @@ Move point to the end of the buffer and search backwards from the bottom.
\\<isearch-mode-map>
With a numeric argument, go to the ARGth absolute occurrence counting from
the end of the buffer. To find the next relative occurrence backwards,
-type \\[isearch-repeat-backward] with a numeric argument."
+type \\[isearch-repeat-backward] with a numeric argument.
+You might want to use `isearch-allow-motion' instead of this command."
(interactive "p")
(if (and arg (< arg 0))
(isearch-beginning-of-buffer (abs arg))
(setq isearch-just-started t)
(goto-char (point-max))
- (isearch-repeat 'backward arg)))
+ (let ((current-direction (if isearch-forward 'forward 'backward))
+ (isearch-repeat-on-direction-change nil))
+ (isearch-repeat 'backward arg)
+ (unless (eq current-direction (if isearch-forward 'forward 'backward))
+ (isearch-repeat current-direction)))))
;;; Toggles for `isearch-regexp-function' and `search-default-mode'.
@@ -2463,8 +2478,8 @@ The arguments passed to `highlight-regexp' are the regexp from
the last search and the face from `hi-lock-read-face-name'."
(interactive)
(isearch--highlight-regexp-or-lines
- #'(lambda (regexp face lighter)
- (highlight-regexp regexp face nil lighter))))
+ (lambda (regexp face lighter)
+ (highlight-regexp regexp face nil lighter))))
(defun isearch-highlight-lines-matching-regexp ()
"Exit Isearch mode and call `highlight-lines-matching-regexp'.
@@ -2472,8 +2487,8 @@ The arguments passed to `highlight-lines-matching-regexp' are the
regexp from the last search and the face from `hi-lock-read-face-name'."
(interactive)
(isearch--highlight-regexp-or-lines
- #'(lambda (regexp face _lighter)
- (highlight-lines-matching-regexp regexp face))))
+ (lambda (regexp face _lighter)
+ (highlight-lines-matching-regexp regexp face))))
(defun isearch-delete-char ()
@@ -2489,6 +2504,11 @@ If no input items have been entered yet, just beep."
(if (null (cdr isearch-cmds))
(ding)
(isearch-pop-state))
+ ;; When going back to the hidden match, reopen it.
+ (when (and (eq search-invisible 'open) isearch-hide-immediately
+ isearch-other-end)
+ (isearch-range-invisible (min (point) isearch-other-end)
+ (max (point) isearch-other-end)))
(isearch-update))
(defun isearch-del-char (&optional arg)
@@ -2923,12 +2943,49 @@ If non-nil, scrolling commands can be used in Isearch mode.
However, you cannot scroll far enough that the current match is
no longer visible (is off screen). But if the value is `unlimited'
that limitation is removed and you can scroll any distance off screen.
-If nil, scrolling commands exit Isearch mode."
+If nil, scrolling commands exit Isearch mode.
+See also the related option `isearch-allow-motion'."
:type '(choice (const :tag "Scrolling exits Isearch" nil)
(const :tag "Scrolling with current match on screen" t)
(const :tag "Scrolling with current match off screen" unlimited))
:group 'isearch)
+(put 'beginning-of-buffer 'isearch-motion
+ (cons (lambda () (goto-char (point-min))) 'forward))
+(put 'end-of-buffer 'isearch-motion
+ (cons (lambda () (goto-char (point-max)) (recenter -1 t)) 'backward))
+(put 'scroll-up-command 'isearch-motion
+ (cons (lambda () (goto-char (window-end)) (recenter 0 t)) 'forward))
+(put 'scroll-down-command 'isearch-motion
+ (cons (lambda () (goto-char (window-start)) (recenter -1 t)) 'backward))
+
+(defcustom isearch-allow-motion nil
+ "Whether to allow movement between isearch matches by cursor motion commands.
+If non-nil, the four motion commands \\[beginning-of-buffer], \\[end-of-buffer], \
+\\[scroll-up-command] and \\[scroll-down-command], when invoked during
+Isearch, move respectively to the first occurrence of the current search string
+in the buffer, the last one, the first one after the current window, and the
+last one before the current window.
+If nil, these motion commands normally exit Isearch and are executed.
+See also the related options `isearch-motion-changes-direction' and
+`isearch-allow-scroll'."
+ :type '(choice (const :tag "Off" nil)
+ (const :tag "On" t))
+ :group 'isearch
+ :version "28.1")
+
+(defcustom isearch-motion-changes-direction nil
+ "Whether motion commands during incremental search change search direction.
+If nil, the search direction (forward or backward) does not change when
+motion commands are used during incremental search, except when wrapping.
+If non-nil, the search direction is forward after \\[beginning-of-buffer] and \
+\\[scroll-up-command], and
+backward after \\[end-of-buffer] and \\[scroll-down-command]."
+ :type '(choice (const :tag "Off" nil)
+ (const :tag "On" t))
+ :group 'isearch
+ :version "28.1")
+
(defcustom isearch-allow-prefix t
"Whether prefix arguments are allowed during incremental search.
If non-nil, entering a prefix argument will not terminate the
@@ -3030,6 +3087,27 @@ See more for options in `search-exit-option'."
;; Optionally edit the search string instead of exiting.
((eq search-exit-option 'edit)
(setq this-command 'isearch-edit-string))
+ ;; Handle motion command functions.
+ ((and isearch-allow-motion
+ (symbolp this-command)
+ (get this-command 'isearch-motion)
+ ;; Don't override `isearch-yank-on-move' used below.
+ (not (and (eq isearch-yank-on-move 'shift)
+ this-command-keys-shift-translated)))
+ (let* ((property (get this-command 'isearch-motion))
+ (function (car property))
+ (current-direction (if isearch-forward 'forward 'backward))
+ (direction (or (cdr property)
+ (if isearch-forward 'forward 'backward))))
+ (funcall function)
+ (setq isearch-just-started t)
+ (let ((isearch-repeat-on-direction-change nil))
+ (isearch-repeat direction))
+ (when (and isearch-success (not isearch-motion-changes-direction))
+ (unless (eq direction current-direction)
+ (let ((isearch-repeat-on-direction-change nil))
+ (isearch-repeat current-direction))))
+ (setq this-command 'ignore)))
;; Handle a scrolling function or prefix argument.
((or (and isearch-allow-prefix
(memq this-command '(universal-argument universal-argument-more
@@ -3714,8 +3792,9 @@ Isearch, at least partially, as determined by `isearch-range-invisible'.
If `search-invisible' is t, which allows Isearch matches inside
invisible text, this function will always return non-nil, regardless
of what `isearch-range-invisible' says."
- (or (eq search-invisible t)
- (not (isearch-range-invisible beg end))))
+ (and (not (text-property-not-all beg end 'inhibit-isearch nil))
+ (or (eq search-invisible t)
+ (not (isearch-range-invisible beg end)))))
;; General utilities
diff --git a/lisp/jit-lock.el b/lisp/jit-lock.el
index a1287926eb9..bb2df2b1ffa 100644
--- a/lisp/jit-lock.el
+++ b/lisp/jit-lock.el
@@ -44,10 +44,13 @@ Preserves the `buffer-modified-p' state of the current buffer."
:version "21.1"
:group 'font-lock)
-(defcustom jit-lock-chunk-size 500
+(defcustom jit-lock-chunk-size 1500
"Jit-lock fontifies chunks of at most this many characters at a time.
-This variable controls both display-time and stealth fontification."
+This variable controls both `display-time' and stealth fontification.
+
+The optimum value is a little over the typical number of buffer
+characters which fit in a typical window."
:type 'integer)
@@ -150,7 +153,10 @@ If 0, then fontification is only deferred while there is input pending."
(defvar jit-lock-functions nil
"Special hook run to do the actual fontification.
The functions are called with two arguments:
-the START and END of the region to fontify.")
+the START and END of the region to fontify.
+Each function can return a list of the form (jit-lock-bounds BEG . END),
+to indicate the bounds of the region it actually fontified;
+JIT font-lock will use this information to optimize redisplay cycles.")
(defvar-local jit-lock-context-unfontify-pos nil
"Consider text after this position as contextually unfontified.
@@ -332,7 +338,10 @@ like `debug-on-error' and Edebug can be used."
"Register FUN as a fontification function to be called in this buffer.
FUN will be called with two arguments START and END indicating the region
that needs to be (re)fontified.
-If non-nil, CONTEXTUAL means that a contextual fontification would be useful."
+If non-nil, CONTEXTUAL means that a contextual fontification would be useful.
+FUN can return a list of the form (jit-lock-bounds BEG . END),
+to indicate the bounds of the region it actually fontified; JIT
+font-lock will use this information to optimize redisplay cycles."
(add-hook 'jit-lock-functions fun nil t)
(when (and contextual jit-lock-contextually)
(setq-local jit-lock-contextually t))
diff --git a/lisp/jka-cmpr-hook.el b/lisp/jka-cmpr-hook.el
index 6933a7c1d06..ed00caedb51 100644
--- a/lisp/jka-cmpr-hook.el
+++ b/lisp/jka-cmpr-hook.el
@@ -203,7 +203,7 @@ options through Custom does this automatically."
;; can-append strip-extension-flag file-magic-bytes
;; uncompress-function]
(mapcar 'purecopy
- '(["\\.Z\\'"
+ `(["\\.Z\\'"
"compressing" "compress" ("-c")
;; gzip is more common than uncompress. It can only read, not write.
"uncompressing" "gzip" ("-c" "-q" "-d")
@@ -239,7 +239,8 @@ options through Custom does this automatically."
"LZMA uncompressing" "lzma" ("-c" "-q" "-d")
t t ""]
["\\.xz\\'"
- "XZ compressing" "xz" ("-c" "-q")
+ ;; On MacOS, gzip can uncompress xz files.
+ "XZ compressing" ,(if (featurep 'ns) "gzip" "xz") ("-c" "-q")
"XZ uncompressing" "xz" ("-c" "-q" "-d")
t t "\3757zXZ\0"]
["\\.txz\\'"
diff --git a/lisp/jsonrpc.el b/lisp/jsonrpc.el
index f1fb6c1ddaf..02db199c7f7 100644
--- a/lisp/jsonrpc.el
+++ b/lisp/jsonrpc.el
@@ -219,7 +219,7 @@ object, using the keywords `:code', `:message' and `:data'."
(jsonrpc-error-message . ,msg))))
(cl-destructuring-bind (&key code message data) args
(signal 'jsonrpc-error
- `(,(format "[jsonrpc] error ")
+ `("[jsonrpc] error "
(jsonrpc-error-code . ,code)
(jsonrpc-error-message . ,message)
(jsonrpc-error-data . ,data))))))
@@ -239,7 +239,7 @@ The caller can expect SUCCESS-FN or ERROR-FN to be called with a
JSONRPC `:result' or `:error' object, respectively. If this
doesn't happen after TIMEOUT seconds (defaults to
`jrpc-default-request-timeout'), the caller can expect TIMEOUT-FN
-to be called with no arguments. The default values of SUCCESS-FN,
+to be called with no arguments. The default values of SUCCESS-FN,
ERROR-FN and TIMEOUT-FN simply log the events into
`jsonrpc-events-buffer'.
@@ -363,7 +363,7 @@ expected to understand JSONRPC messages with basic HTTP-style
enveloping headers such as \"Content-Length:\".
:ON-SHUTDOWN (optional), a function of one argument, the
-connection object, called when the process dies .")
+connection object, called when the process dies.")
(cl-defmethod initialize-instance ((conn jsonrpc-process-connection) slots)
(cl-call-next-method)
diff --git a/lisp/kermit.el b/lisp/kermit.el
index fdab7e5a505..25f1f300f35 100644
--- a/lisp/kermit.el
+++ b/lisp/kermit.el
@@ -29,7 +29,7 @@
;; is that I can log onto machines with primitive operating systems (VMS and
;; ATT system V :-), and still have the features of shell-mode available for
;; command history, etc. It's also handy to be able to run a file transfer in
-;; an emacs window. The transfer is in the "background", but you can also
+;; an Emacs window. The transfer is in the "background", but you can also
;; monitor or stop it easily.
;; The ^\ key is bound to a function for sending escape sequences to kermit,
diff --git a/lisp/keymap.el b/lisp/keymap.el
new file mode 100644
index 00000000000..fd91689f887
--- /dev/null
+++ b/lisp/keymap.el
@@ -0,0 +1,457 @@
+;;; keymap.el --- Keymap functions -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 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:
+
+;; This library deals with the "new" keymap binding interface: The
+;; only key syntax allowed by these functions is the `kbd' one.
+
+;;; Code:
+
+
+
+(defun keymap--check (key)
+ "Signal an error if KEY doesn't have a valid syntax."
+ (unless (key-valid-p key)
+ (error "%S is not a valid key definition; see `key-valid-p'" key)))
+
+(defun keymap--compile-check (&rest keys)
+ (dolist (key keys)
+ (when (or (vectorp key)
+ (and (stringp key) (not (key-valid-p key))))
+ (byte-compile-warn "Invalid `kbd' syntax: %S" key))))
+
+(defun keymap-set (keymap key definition)
+ "Set key sequence KEY to DEFINITION in KEYMAP.
+KEY is a string that satisfies `key-valid-p'.
+
+DEFINITION is anything that can be a key's definition:
+ nil (means key is undefined in this keymap),
+ a command (a Lisp function suitable for interactive calling),
+ a string (treated as a keyboard macro),
+ a keymap (to define a prefix key),
+ a symbol (when the key is looked up, the symbol will stand for its
+ function definition, which should at that time be one of the above,
+ or another symbol whose function definition is used, etc.),
+ a cons (STRING . DEFN), meaning that DEFN is the definition
+ (DEFN should be a valid definition in its own right) and
+ STRING is the menu item name (which is used only if the containing
+ keymap has been created with a menu name, see `make-keymap'),
+ or a cons (MAP . CHAR), meaning use definition of CHAR in keymap MAP,
+ or an extended menu item definition.
+ (See info node `(elisp)Extended Menu Items'.)"
+ (declare (compiler-macro (lambda (form) (keymap--compile-check key) form)))
+ (keymap--check key)
+ ;; If we're binding this key to another key, then parse that other
+ ;; key, too.
+ (when (stringp definition)
+ (keymap--check definition)
+ (setq definition (key-parse definition)))
+ (define-key keymap (key-parse key) definition))
+
+(defun keymap-global-set (key command)
+ "Give KEY a global binding as COMMAND.
+COMMAND is the command definition to use; usually it is
+a symbol naming an interactively-callable function.
+
+KEY is a string that satisfies `key-valid-p'.
+
+Note that if KEY has a local binding in the current buffer,
+that local binding will continue to shadow any global binding
+that you make with this function."
+ (declare (compiler-macro (lambda (form) (keymap--compile-check key) form)))
+ (interactive
+ (let* ((menu-prompting nil)
+ (key (read-key-sequence "Set key globally: " nil t)))
+ (list key
+ (read-command (format "Set key %s to command: "
+ (key-description key))))))
+ (keymap-set (current-global-map) key command))
+
+(defun keymap-local-set (key command)
+ "Give KEY a local binding as COMMAND.
+COMMAND is the command definition to use; usually it is
+a symbol naming an interactively-callable function.
+
+KEY is a string that satisfies `key-valid-p'.
+
+The binding goes in the current buffer's local map, which in most
+cases is shared with all other buffers in the same major mode."
+ (declare (compiler-macro (lambda (form) (keymap--compile-check key) form)))
+ (interactive "KSet key locally: \nCSet key %s locally to command: ")
+ (let ((map (current-local-map)))
+ (unless map
+ (use-local-map (setq map (make-sparse-keymap))))
+ (keymap-set map key command)))
+
+(defun keymap-global-unset (key &optional remove)
+ "Remove global binding of KEY (if any).
+KEY is a string that satisfies `key-valid-p'.
+
+If REMOVE (interactively, the prefix arg), remove the binding
+instead of unsetting it. See `keymap-unset' for details."
+ (declare (compiler-macro (lambda (form) (keymap--compile-check key) form)))
+ (interactive
+ (list (key-description (read-key-sequence "Set key locally: "))
+ current-prefix-arg))
+ (keymap-unset (current-global-map) key remove))
+
+(defun keymap-local-unset (key &optional remove)
+ "Remove local binding of KEY (if any).
+KEY is a string that satisfies `key-valid-p'.
+
+If REMOVE (interactively, the prefix arg), remove the binding
+instead of unsetting it. See `keymap-unset' for details."
+ (declare (compiler-macro (lambda (form) (keymap--compile-check key) form)))
+ (interactive
+ (list (key-description (read-key-sequence "Unset key locally: "))
+ current-prefix-arg))
+ (when (current-local-map)
+ (keymap-unset (current-local-map) key remove)))
+
+(defun keymap-unset (keymap key &optional remove)
+ "Remove key sequence KEY from KEYMAP.
+KEY is a string that satisfies `key-valid-p'.
+
+If REMOVE, remove the binding instead of unsetting it. This only
+makes a difference when there's a parent keymap. When unsetting
+a key in a child map, it will still shadow the same key in the
+parent keymap. Removing the binding will allow the key in the
+parent keymap to be used."
+ (declare (compiler-macro (lambda (form) (keymap--compile-check key) form)))
+ (keymap--check key)
+ (define-key keymap (key-parse key) nil remove))
+
+(defun keymap-substitute (keymap olddef newdef &optional oldmap prefix)
+ "Replace OLDDEF with NEWDEF for any keys in KEYMAP now defined as OLDDEF.
+In other words, OLDDEF is replaced with NEWDEF wherever it appears.
+Alternatively, if optional fourth argument OLDMAP is specified, we redefine
+in KEYMAP as NEWDEF those keys that are defined as OLDDEF in OLDMAP.
+
+If you don't specify OLDMAP, you can usually get the same results
+in a cleaner way with command remapping, like this:
+ (define-key KEYMAP [remap OLDDEF] NEWDEF)
+\n(fn OLDDEF NEWDEF KEYMAP &optional OLDMAP)"
+ ;; Don't document PREFIX in the doc string because we don't want to
+ ;; advertise it. It's meant for recursive calls only. Here's its
+ ;; meaning
+
+ ;; If optional argument PREFIX is specified, it should be a key
+ ;; prefix, a string. Redefined bindings will then be bound to the
+ ;; original key, with PREFIX added at the front.
+ (unless prefix
+ (setq prefix ""))
+ (let* ((scan (or oldmap keymap))
+ (prefix1 (vconcat prefix [nil]))
+ (key-substitution-in-progress
+ (cons scan key-substitution-in-progress)))
+ ;; Scan OLDMAP, finding each char or event-symbol that
+ ;; has any definition, and act on it with hack-key.
+ (map-keymap
+ (lambda (char defn)
+ (aset prefix1 (length prefix) char)
+ (substitute-key-definition-key defn olddef newdef prefix1 keymap))
+ scan)))
+
+(defun keymap-set-after (keymap key definition &optional after)
+ "Add binding in KEYMAP for KEY => DEFINITION, right after AFTER's binding.
+This is like `keymap-set' except that the binding for KEY is placed
+just after the binding for the event AFTER, instead of at the beginning
+of the map. Note that AFTER must be an event type (like KEY), NOT a command
+\(like DEFINITION).
+
+If AFTER is t or omitted, the new binding goes at the end of the keymap.
+AFTER should be a single event type--a symbol or a character, not a sequence.
+
+Bindings are always added before any inherited map.
+
+The order of bindings in a keymap matters only when it is used as
+a menu, so this function is not useful for non-menu keymaps."
+ (declare (indent defun)
+ (compiler-macro (lambda (form) (keymap--compile-check key) form)))
+ (keymap--check key)
+ (when after
+ (keymap--check after))
+ (define-key-after keymap (key-parse key) definition
+ (and after (key-parse after))))
+
+(defun key-parse (keys)
+ "Convert KEYS to the internal Emacs key representation.
+See `kbd' for a descripion of KEYS."
+ (declare (pure t) (side-effect-free t))
+ ;; A pure function is expected to preserve the match data.
+ (save-match-data
+ (let ((case-fold-search nil)
+ (len (length keys)) ; We won't alter keys in the loop below.
+ (pos 0)
+ (res []))
+ (while (and (< pos len)
+ (string-match "[^ \t\n\f]+" keys pos))
+ (let* ((word-beg (match-beginning 0))
+ (word-end (match-end 0))
+ (word (substring keys word-beg len))
+ (times 1)
+ key)
+ ;; Try to catch events of the form "<as df>".
+ (if (string-match "\\`<[^ <>\t\n\f][^>\t\n\f]*>" word)
+ (setq word (match-string 0 word)
+ pos (+ word-beg (match-end 0)))
+ (setq word (substring keys word-beg word-end)
+ pos word-end))
+ (when (string-match "\\([0-9]+\\)\\*." word)
+ (setq times (string-to-number (substring word 0 (match-end 1))))
+ (setq word (substring word (1+ (match-end 1)))))
+ (cond ((string-match "^<<.+>>$" word)
+ (setq key (vconcat (if (eq (key-binding [?\M-x])
+ 'execute-extended-command)
+ [?\M-x]
+ (or (car (where-is-internal
+ 'execute-extended-command))
+ [?\M-x]))
+ (substring word 2 -2) "\r")))
+ ((and (string-match "^\\(\\([ACHMsS]-\\)*\\)<\\(.+\\)>$" word)
+ (progn
+ (setq word (concat (match-string 1 word)
+ (match-string 3 word)))
+ (not (string-match
+ "\\<\\(NUL\\|RET\\|LFD\\|ESC\\|SPC\\|DEL\\)$"
+ word))))
+ (setq key (list (intern word))))
+ ((or (equal word "REM") (string-match "^;;" word))
+ (setq pos (string-match "$" keys pos)))
+ (t
+ (let ((orig-word word) (prefix 0) (bits 0))
+ (while (string-match "^[ACHMsS]-." word)
+ (setq bits (+ bits
+ (cdr
+ (assq (aref word 0)
+ '((?A . ?\A-\^@) (?C . ?\C-\^@)
+ (?H . ?\H-\^@) (?M . ?\M-\^@)
+ (?s . ?\s-\^@) (?S . ?\S-\^@))))))
+ (setq prefix (+ prefix 2))
+ (setq word (substring word 2)))
+ (when (string-match "^\\^.$" word)
+ (setq bits (+ bits ?\C-\^@))
+ (setq prefix (1+ prefix))
+ (setq word (substring word 1)))
+ (let ((found (assoc word '(("NUL" . "\0") ("RET" . "\r")
+ ("LFD" . "\n") ("TAB" . "\t")
+ ("ESC" . "\e") ("SPC" . " ")
+ ("DEL" . "\177")))))
+ (when found (setq word (cdr found))))
+ (when (string-match "^\\\\[0-7]+$" word)
+ (let ((n 0))
+ (dolist (ch (cdr (string-to-list word)))
+ (setq n (+ (* n 8) ch -48)))
+ (setq word (vector n))))
+ (cond ((= bits 0)
+ (setq key word))
+ ((and (= bits ?\M-\^@) (stringp word)
+ (string-match "^-?[0-9]+$" word))
+ (setq key (mapcar (lambda (x) (+ x bits))
+ (append word nil))))
+ ((/= (length word) 1)
+ (error "%s must prefix a single character, not %s"
+ (substring orig-word 0 prefix) word))
+ ((and (/= (logand bits ?\C-\^@) 0) (stringp word)
+ ;; We used to accept . and ? here,
+ ;; but . is simply wrong,
+ ;; and C-? is not used (we use DEL instead).
+ (string-match "[@-_a-z]" word))
+ (setq key (list (+ bits (- ?\C-\^@)
+ (logand (aref word 0) 31)))))
+ (t
+ (setq key (list (+ bits (aref word 0)))))))))
+ (when key
+ (dolist (_ (number-sequence 1 times))
+ (setq res (vconcat res key))))))
+ (if (and (>= (length res) 4)
+ (eq (aref res 0) ?\C-x)
+ (eq (aref res 1) ?\()
+ (eq (aref res (- (length res) 2)) ?\C-x)
+ (eq (aref res (- (length res) 1)) ?\)))
+ (apply #'vector (let ((lres (append res nil)))
+ ;; Remove the first and last two elements.
+ (setq lres (cdr (cdr lres)))
+ (nreverse lres)
+ (setq lres (cdr (cdr lres)))
+ (nreverse lres)))
+ res))))
+
+(defun key-valid-p (keys)
+ "Say whether KEYS is a valid `kbd' sequence.
+A `kbd' sequence is a string consisting of one and more key
+strokes. The key strokes are separated by a space character.
+
+Each key stroke is either a single character, or the name of an
+event, surrounded by angle brackets. In addition, any key stroke
+may be preceded by one or more modifier keys. Finally, a limited
+number of characters have a special shorthand syntax.
+
+Here's some example key sequences.
+
+ \"f\" (the key 'f')
+ \"S o m\" (a three key sequence of the keys 'S', 'o' and 'm')
+ \"C-c o\" (a two key sequence of the keys 'c' with the control modifier
+ and then the key 'o')
+ \"H-<left>\" (the key named \"left\" with the hyper modifier)
+ \"M-RET\" (the \"return\" key with a meta modifier)
+ \"C-M-<space>\" (the \"space\" key with both the control and meta modifiers)
+
+These are the characters that have shorthand syntax:
+NUL, RET, TAB, LFD, ESC, SPC, DEL.
+
+Modifiers have to be specified in this order:
+
+ A-C-H-M-S-s
+
+which is
+
+ Alt-Control-Hyper-Meta-Shift-super"
+ (declare (pure t) (side-effect-free t))
+ (and
+ (stringp keys)
+ (string-match-p "\\`[^ ]+\\( [^ ]+\\)*\\'" keys)
+ (save-match-data
+ (catch 'exit
+ (let ((prefixes
+ "\\(A-\\)?\\(C-\\)?\\(H-\\)?\\(M-\\)?\\(S-\\)?\\(s-\\)?")
+ (case-fold-search nil))
+ (dolist (key (split-string keys " "))
+ ;; Every key might have these modifiers, and they should be
+ ;; in this order.
+ (when (string-match (concat "\\`" prefixes) key)
+ (setq key (substring key (match-end 0))))
+ (unless (or (and (= (length key) 1)
+ ;; Don't accept control characters as keys.
+ (not (< (aref key 0) ?\s))
+ ;; Don't accept Meta'd characters as keys.
+ (or (multibyte-string-p key)
+ (not (<= 127 (aref key 0) 255))))
+ (and (string-match-p "\\`<[-_A-Za-z0-9]+>\\'" key)
+ ;; Don't allow <M-C-down>.
+ (= (progn
+ (string-match
+ (concat "\\`<" prefixes) key)
+ (match-end 0))
+ 1))
+ (string-match-p
+ "\\`\\(NUL\\|RET\\|TAB\\|LFD\\|ESC\\|SPC\\|DEL\\)\\'"
+ key))
+ ;; Invalid.
+ (throw 'exit nil)))
+ t)))))
+
+(defun key-translate (from to)
+ "Translate character FROM to TO on the current terminal.
+This function creates a `keyboard-translate-table' if necessary
+and then modifies one entry in it.
+
+Both KEY and TO are strings that satisfy `key-valid-p'."
+ (declare (compiler-macro
+ (lambda (form) (keymap--compile-check from to) form)))
+ (keymap--check from)
+ (keymap--check to)
+ (or (char-table-p keyboard-translate-table)
+ (setq keyboard-translate-table
+ (make-char-table 'keyboard-translate-table nil)))
+ (aset keyboard-translate-table (key-parse from) (key-parse to)))
+
+(defun keymap-lookup (keymap key &optional accept-default no-remap position)
+ "Return the binding for command KEY.
+KEY is a string that satisfies `key-valid-p'.
+
+If KEYMAP is nil, look up in the current keymaps. If non-nil, it
+should either be a keymap or a list of keymaps, and only these
+keymap(s) will be consulted.
+
+The binding is probably a symbol with a function definition.
+
+Normally, `keymap-lookup' ignores bindings for t, which act as
+default bindings, used when nothing else in the keymap applies;
+this makes it usable as a general function for probing keymaps.
+However, if the optional second argument ACCEPT-DEFAULT is
+non-nil, `keymap-lookup' does recognize the default bindings,
+just as `read-key-sequence' does.
+
+Like the normal command loop, `keymap-lookup' will remap the
+command resulting from looking up KEY by looking up the command
+in the current keymaps. However, if the optional third argument
+NO-REMAP is non-nil, `keymap-lookup' returns the unmapped
+command.
+
+If KEY is a key sequence initiated with the mouse, the used keymaps
+will depend on the clicked mouse position with regard to the buffer
+and possible local keymaps on strings.
+
+If the optional argument POSITION is non-nil, it specifies a mouse
+position as returned by `event-start' and `event-end', and the lookup
+occurs in the keymaps associated with it instead of KEY. It can also
+be a number or marker, in which case the keymap properties at the
+specified buffer position instead of point are used."
+ (declare (compiler-macro (lambda (form) (keymap--compile-check key) form)))
+ (keymap--check key)
+ (when (and keymap position)
+ (error "Can't pass in both keymap and position"))
+ (if keymap
+ (let ((value (lookup-key keymap (key-parse key) accept-default)))
+ (if (and (not no-remap)
+ (symbolp value))
+ (or (command-remapping value) value)
+ value))
+ (key-binding (kbd key) accept-default no-remap position)))
+
+(defun keymap-local-lookup (keys &optional accept-default)
+ "Return the binding for command KEYS in current local keymap only.
+KEY is a string that satisfies `key-valid-p'.
+
+The binding is probably a symbol with a function definition.
+
+If optional argument ACCEPT-DEFAULT is non-nil, recognize default
+bindings; see the description of `keymap-lookup' for more details
+about this."
+ (declare (compiler-macro (lambda (form) (keymap--compile-check keys) form)))
+ (when-let ((map (current-local-map)))
+ (keymap-lookup map keys accept-default)))
+
+(defun keymap-global-lookup (keys &optional accept-default message)
+ "Return the binding for command KEYS in current global keymap only.
+KEY is a string that satisfies `key-valid-p'.
+
+The binding is probably a symbol with a function definition.
+This function's return values are the same as those of `keymap-lookup'
+\(which see).
+
+If optional argument ACCEPT-DEFAULT is non-nil, recognize default
+bindings; see the description of `keymap-lookup' for more details
+about this.
+
+If MESSAGE (and interactively), message the result."
+ (declare (compiler-macro (lambda (form) (keymap--compile-check keys) form)))
+ (interactive
+ (list (key-description (read-key-sequence "Look up key in global keymap: "))
+ nil t))
+ (let ((def (keymap-lookup (current-global-map) keys accept-default)))
+ (when message
+ (message "%s is bound to %s globally" keys def))
+ def))
+
+(provide 'keymap)
+
+;;; keymap.el ends here
diff --git a/lisp/kmacro.el b/lisp/kmacro.el
index 8821e35c2d1..3f492a851ea 100644
--- a/lisp/kmacro.el
+++ b/lisp/kmacro.el
@@ -22,7 +22,7 @@
;;; Commentary:
-;; The kmacro package provides the user interface to emacs' basic
+;; The kmacro package provides the user interface to Emacs' basic
;; keyboard macro functionality. With kmacro, two function keys are
;; dedicated to keyboard macros, by default F3 and F4.
@@ -144,7 +144,7 @@ macro to be executed before appending to it."
(defcustom kmacro-repeat-no-prefix t
- "Allow repeating certain macro commands without entering the C-x C-k prefix."
+ "Allow repeating certain macro commands without entering the \\[kmacro-keymap] prefix."
:type 'boolean)
(defcustom kmacro-call-repeat-key t
@@ -172,7 +172,7 @@ macro to be executed before appending to it."
(define-key map "\C-k" #'kmacro-end-or-call-macro-repeat)
(define-key map "r" #'apply-macro-to-region-lines)
(define-key map "q" #'kbd-macro-query) ;; Like C-x q
- (define-key map "Q" #'kdb-macro-redisplay)
+ (define-key map "d" #'kdb-macro-redisplay)
;; macro ring
(define-key map "\C-n" #'kmacro-cycle-ring-next)
@@ -260,8 +260,12 @@ Can be set directly via `kmacro-set-format', which see.")
Interactively, ARG defaults to 1. With \\[universal-argument], insert
the previous value of `kmacro-counter', and do not increment the
current value.
+
The previous value of the counter is the one it had before
-the last increment."
+the last increment.
+
+See Info node `(emacs) Keyboard Macro Counter' for more
+information."
(interactive "P")
(if kmacro-initial-counter-value
(setq kmacro-counter kmacro-initial-counter-value
@@ -273,7 +277,24 @@ the last increment."
(defun kmacro-set-format (format)
- "Set the format of `kmacro-counter' to FORMAT."
+ "Set the format of `kmacro-counter' to FORMAT.
+
+The default format is \"%d\", which means to insert the number in
+decimal without any padding. You can specify any format string
+that the `format' function accepts and that makes sense with a
+single integer extra argument.
+
+If you run this command while no keyboard macro is being defined,
+the new format affects all subsequent macro definitions.
+
+If you run this command while defining a keyboard macro, it
+affects only that macro, from that point on.
+
+Do not put the format string inside double quotes when you insert
+it in the minibuffer.
+
+See Info node `(emacs) Keyboard Macro Counter' for more
+information."
(interactive "sMacro Counter Format: ")
(setq kmacro-counter-format
(if (equal format "") "%d" format))
@@ -283,7 +304,10 @@ the last increment."
(defun kmacro-display-counter (&optional value)
- "Display current counter value."
+ "Display current counter value.
+
+See Info node `(emacs) Keyboard Macro Counter' for more
+information."
(unless value (setq value kmacro-counter))
(message "New macro counter value: %s (%d)"
(format kmacro-counter-format value) value))
@@ -291,7 +315,10 @@ the last increment."
(defun kmacro-set-counter (arg)
"Set the value of `kmacro-counter' to ARG, or prompt for value if no argument.
With \\[universal-argument] prefix, reset counter to its value prior to this iteration of the
-macro."
+macro.
+
+See Info node `(emacs) Keyboard Macro Counter' for more
+information."
(interactive "NMacro counter value: ")
(if (not (or defining-kbd-macro executing-kbd-macro))
(kmacro-display-counter (setq kmacro-initial-counter-value arg))
@@ -305,7 +332,10 @@ macro."
(defun kmacro-add-counter (arg)
"Add the value of numeric prefix arg (prompt if missing) to `kmacro-counter'.
-With \\[universal-argument], restore previous counter value."
+With \\[universal-argument], restore previous counter value.
+
+See Info node `(emacs) Keyboard Macro Counter' for more
+information."
(interactive "NAdd to macro counter: ")
(if kmacro-initial-counter-value
(setq kmacro-counter kmacro-initial-counter-value
@@ -728,7 +758,7 @@ With \\[universal-argument], call second macro in macro ring."
(defun kmacro-end-or-call-macro-repeat (arg)
- "As `kmacro-end-or-call-macro' but allows repeat without repeating prefix."
+ "As `kmacro-end-or-call-macro' but allow repeat without repeating prefix."
(interactive "P")
(let ((keys (kmacro-get-repeat-prefix)))
(kmacro-end-or-call-macro arg t)
@@ -820,8 +850,8 @@ If kbd macro currently being defined end it before activating it."
(defun kmacro-bind-to-key (_arg)
"When not defining or executing a macro, offer to bind last macro to a key.
-The key sequences [C-x C-k 0] through [C-x C-k 9] and [C-x C-k A]
-through [C-x C-k Z] are reserved for user bindings, and to bind to
+The key sequences `C-x C-k 0' through `C-x C-k 9' and `C-x C-k A'
+through `C-x C-k Z' are reserved for user bindings, and to bind to
one of these sequences, just enter the digit or letter, rather than
the whole sequence.
diff --git a/lisp/language/burmese.el b/lisp/language/burmese.el
index ade3566717b..96ba7752684 100644
--- a/lisp/language/burmese.el
+++ b/lisp/language/burmese.el
@@ -24,7 +24,7 @@
;;; Commentary:
;; The murderous generals say to call it "Myanmar".
-;; We will call it "Burma". -- rms, Chief GNUisance.
+;; We will call it "Burma". -- rms, Chief GNUisance.
;;; Code:
diff --git a/lisp/language/cyril-util.el b/lisp/language/cyril-util.el
index 04e681d743d..e404288ddca 100644
--- a/lisp/language/cyril-util.el
+++ b/lisp/language/cyril-util.el
@@ -60,7 +60,7 @@ If the argument is nil, we return the display table to its standard state."
(list
(let* ((completion-ignore-case t))
(completing-read
- "Cyrillic language (default nil): "
+ (format-prompt "Cyrillic language" "nil")
cyrillic-language-alist nil t nil nil nil))))
(or standard-display-table
diff --git a/lisp/language/ethio-util.el b/lisp/language/ethio-util.el
index dc385b07d3e..2de6602ced1 100644
--- a/lisp/language/ethio-util.el
+++ b/lisp/language/ethio-util.el
@@ -2098,6 +2098,10 @@ mark."
;; The ethiopic-tex package is not used for keyboard input, therefore
;; not registered with the register-input-method function.
+;; Local Variables:
+;; checkdoc-symbol-words: ("-->")
+;; End:
+
(provide 'ethio-util)
;;; ethio-util.el ends here
diff --git a/lisp/language/hanja-util.el b/lisp/language/hanja-util.el
index 9e9213536cb..fe6323d42ba 100644
--- a/lisp/language/hanja-util.el
+++ b/lisp/language/hanja-util.el
@@ -6573,8 +6573,8 @@ The value is a hanja character that is selected interactively."
(hanja-filter (lambda (x) (car x))
(mapcar (lambda (c)
(if (listp c)
- (cons (decode-char 'ucs (car c)) (cdr c))
- (list (decode-char 'ucs c))))
+ (cons (car c) (cdr c))
+ (list c)))
(aref hanja-table char)))))
(unwind-protect
(when (aref hanja-conversions 2)
diff --git a/lisp/language/ind-util.el b/lisp/language/ind-util.el
index 8d4b2a826e6..6f579f23833 100644
--- a/lisp/language/ind-util.el
+++ b/lisp/language/ind-util.el
@@ -487,7 +487,7 @@
c trans-c))
(defun indian-make-hash (table trans-table)
- "Indian Transliteration Hash for decode/encode"
+ "Indian Transliteration Hash for decode/encode."
(let* ((encode-hash (make-hash-table :test 'equal))
(decode-hash (make-hash-table :test 'equal))
(hashtbls (cons encode-hash decode-hash))
@@ -809,11 +809,11 @@
;; only Devanagari is supported now.
(concat "[" (char-to-string #x0900)
"-" (char-to-string #x097f) "]")
- "Regexp that matches to conversion")
+ "Regexp that matches to conversion.")
(defun indian-ucs-to-iscii-region (from to)
- "Converts the indian UCS characters in the region to ISCII.
-Returns new end position."
+ "Convert the indian UCS characters in the region to ISCII.
+Return new end position."
(interactive "r")
;; only Devanagari is supported now.
(save-excursion
@@ -828,8 +828,8 @@ Returns new end position."
(point-max))))
(defun indian-iscii-to-ucs-region (from to)
- "Converts the ISCII characters in the region to UCS.
-Returns new end position."
+ "Convert the ISCII characters in the region to UCS.
+Return new end position."
(interactive "r")
;; only Devanagari is supported now.
(save-excursion
diff --git a/lisp/language/japan-util.el b/lisp/language/japan-util.el
index f3e3590645b..cad34e99046 100644
--- a/lisp/language/japan-util.el
+++ b/lisp/language/japan-util.el
@@ -108,7 +108,7 @@ HANKAKU-KATAKANA belongs to `japanese-jisx0201-kana'.")
;; cp932-2-byte
(#x2015 ?-) (#xFF5E ?~) (#xFF0D ?-))
"Japanese JISX0208 and CP932 symbol character table.
- Each element is of the form (SYMBOL ASCII HANKAKU), where SYMBOL
+Each element is of the form (SYMBOL ASCII HANKAKU), where SYMBOL
belongs to `japanese-jisx0208' or `cp932', ASCII belongs to `ascii',
and HANKAKU belongs to `japanese-jisx0201-kana'.")
@@ -145,7 +145,7 @@ and HANKAKU belongs to `japanese-jisx0201-kana'.")
(?p . ?p) (?q . ?q) (?r . ?r) (?s . ?s) (?t . ?t)
(?u . ?u) (?v . ?v) (?w . ?w) (?x . ?x) (?y . ?y) (?z . ?z))
"Japanese JISX0208 alpha numeric character table.
-Each element is of the form (ALPHA-NUMERIC . ASCII), where ALPHA-NUMERIC
+Each element is of the form (ALPHANUMERIC . ASCII), where ALPHANUMERIC
belongs to `japanese-jisx0208', ASCII belongs to `ascii'.")
;; Put properties 'jisx0208 and 'ascii to each Japanese alpha numeric
diff --git a/lisp/language/japanese.el b/lisp/language/japanese.el
index bd8ef6ec857..d9bd42093a0 100644
--- a/lisp/language/japanese.el
+++ b/lisp/language/japanese.el
@@ -264,29 +264,6 @@ eucJP-ms is defined in <http://www.opengroup.or.jp/jvc/cde/appendix.html>."
(define-translation-table 'unicode-to-jisx0213
(char-table-extra-slot table 0)))
-(defun compose-gstring-for-variation-glyph (gstring _direction)
- "Compose glyph-string GSTRING for graphic display.
-GSTRING must have two glyphs; the first is a glyph for a han character,
-and the second is a glyph for a variation selector."
- (let* ((font (lgstring-font gstring))
- (han (lgstring-char gstring 0))
- (vs (lgstring-char gstring 1))
- (glyphs (font-variation-glyphs font han))
- (g0 (lgstring-glyph gstring 0))
- (g1 (lgstring-glyph gstring 1)))
- (catch 'tag
- (dolist (elt glyphs)
- (if (= (car elt) vs)
- (progn
- (lglyph-set-code g0 (cdr elt))
- (lglyph-set-from-to g0 (lglyph-from g0) (lglyph-to g1))
- (lgstring-set-glyph gstring 1 nil)
- (throw 'tag gstring)))))))
-
-(let ((elt '([".." 1 compose-gstring-for-variation-glyph])))
- (set-char-table-range composition-function-table '(#xFE00 . #xFE0F) elt)
- (set-char-table-range composition-function-table '(#xE0100 . #xE01EF) elt))
-
(provide 'japanese)
;;; japanese.el ends here
diff --git a/lisp/language/khmer.el b/lisp/language/khmer.el
index 471af401656..12737edc73f 100644
--- a/lisp/language/khmer.el
+++ b/lisp/language/khmer.el
@@ -21,6 +21,8 @@
;; 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:
(set-language-info-alist
diff --git a/lisp/language/lao.el b/lisp/language/lao.el
index c699d57c15a..93849461eae 100644
--- a/lisp/language/lao.el
+++ b/lisp/language/lao.el
@@ -59,11 +59,11 @@
(let* ((chars (car l))
(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)
- (t (string c))))
+ (regexp (mapconcat (lambda (c)
+ (cond ((= c ?c) consonant)
+ ((= c ?t) tone)
+ ((= c ?v) vowel-upper-lower)
+ (t (string c))))
(cdr l) ""))
;; Element of composition-function-table.
(elt (list (vector regexp 1 #'lao-composition-function)
diff --git a/lisp/language/misc-lang.el b/lisp/language/misc-lang.el
index a2ca678b2be..c8a4821abf7 100644
--- a/lisp/language/misc-lang.el
+++ b/lisp/language/misc-lang.el
@@ -192,7 +192,25 @@ thin (i.e. 1-dot width) space."
composition-function-table
#x13437
(list (vector "\U00013437[\U00013000-\U0001343F]+"
- 0 #'egyptian-shape-grouping))))
+ 0 #'egyptian-shape-grouping)))
+ ;; "Normal" hieroglyphs, for fonts that don't support the above
+ ;; controls, but do shape sequences of hieroglyphs without the
+ ;; controls.
+ ;; FIXME: As of late 2021, Egyptian Hieroglyph Format Controls are
+ ;; not yet supported in existing fonts and/or shaping engines, but
+ ;; some fonts do provide ligatures with which texts in Egyptian
+ ;; Hieroglyphs are correctly displayed. If and when these format
+ ;; controls are supported, as described in section 11.4 "Egyptian
+ ;; Hieroglyphs" of the Unicode Standard, the five lines below (which
+ ;; allow composition of hieroglyphs without formatting controls
+ ;; around) can be removed, and the entry in etc/HELLO can be
+ ;; restored to:
+ ;; Egyptian Hieroglyphs (𓂋𓐰𓏤𓈖𓆎𓅓𓏏𓐰𓊖) 𓅓𓊵𓐰𓐷𓏏𓊪𓐸, 𓇍𓇋𓂻𓍘𓇋
+ (set-char-table-range
+ composition-function-table
+ '(#x13000 . #x1342E)
+ (list (vector "[\U00013000-\U0001342E]+"
+ 0 #'font-shape-gstring))))
(provide 'misc-lang)
diff --git a/lisp/language/sinhala.el b/lisp/language/sinhala.el
index 89392ad6c50..bf320506001 100644
--- a/lisp/language/sinhala.el
+++ b/lisp/language/sinhala.el
@@ -21,6 +21,8 @@
;; 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:
(set-language-info-alist
diff --git a/lisp/language/thai-word.el b/lisp/language/thai-word.el
index 5d0389c28df..d12064958e1 100644
--- a/lisp/language/thai-word.el
+++ b/lisp/language/thai-word.el
@@ -64,7 +64,6 @@
;; the sale, use or other dealings in this Software without prior
;; written authorization of the copyright holder.
-
;;; Commentary:
;; This file implements an algorithm to find Thai word breaks using a
@@ -76,6 +75,8 @@
;; which means that you can easily index the list character by
;; character.
+;;; Code:
+
(defvar thai-word-table
(let ((table (list 'thai-words)))
(dolist (elt
@@ -10740,8 +10741,8 @@
(defun thai-update-word-table (file &optional append)
- "Update Thai word table by replacing the current word list with
-FILE. If called with a prefix argument, FILE is appended instead to
+ "Update Thai word table by replacing the current word list with FILE.
+If called with a prefix argument, FILE is appended instead to
the current word list."
(interactive "FThai word table file: \nP")
(let ((buf (generate-new-buffer "*thai-work*"))
@@ -11041,20 +11042,20 @@ If COUNT is negative, move point forward (- COUNT) words."
(defun thai-kill-word (arg)
- "Like kill-word but pay attention to Thai word boundaries.
+ "Like `kill-word' but pay attention to Thai word boundaries.
With argument, do this that many times."
(interactive "p")
(kill-region (point) (progn (thai-forward-word arg) (point))))
(defun thai-backward-kill-word (arg)
- "Like backward-kill-word but pay attention to Thai word boundaries."
+ "Like `backward-kill-word' but pay attention to Thai word boundaries."
(interactive "p")
(thai-kill-word (- arg)))
(defun thai-transpose-words (arg)
- "Like transpose-words but pay attention to Thai word boundaries."
+ "Like `transpose-words' but pay attention to Thai word boundaries."
(interactive "*p")
(transpose-subr 'thai-forward-word arg))
diff --git a/lisp/language/tibet-util.el b/lisp/language/tibet-util.el
index ddf4a0c0fb1..1f7a1edcad3 100644
--- a/lisp/language/tibet-util.el
+++ b/lisp/language/tibet-util.el
@@ -281,8 +281,9 @@ The returned string has no composition information."
;;;###autoload
(defun tibetan-decompose-region (from to)
"Decompose Tibetan text in the region FROM and TO.
-This is different from decompose-region because precomposed Tibetan characters
-are decomposed into normal Tibetan character sequences."
+This is different from `decompose-region' because precomposed
+Tibetan characters are decomposed into normal Tibetan character
+sequences."
(interactive "r")
(save-restriction
(narrow-to-region from to)
@@ -301,8 +302,9 @@ are decomposed into normal Tibetan character sequences."
;;;###autoload
(defun tibetan-decompose-string (str)
"Decompose Tibetan string STR.
-This is different from decompose-string because precomposed Tibetan characters
-are decomposed into normal Tibetan character sequences."
+This is different from `decompose-string' because precomposed
+Tibetan characters are decomposed into normal Tibetan character
+sequences."
(let ((new "")
(len (length str))
(idx 0)
@@ -332,7 +334,7 @@ See also the documentation of the function `tibetan-decompose-region'."
;;;###autoload
(defun tibetan-compose-buffer ()
"Composes Tibetan character components in the buffer.
-See also docstring of the function tibetan-compose-region."
+See also docstring of the function `tibetan-compose-region'."
(interactive)
(make-local-variable 'tibetan-decomposed)
(tibetan-compose-region (point-min) (point-max))
diff --git a/lisp/language/tibetan.el b/lisp/language/tibetan.el
index 48c7638948c..dc37fc90ac2 100644
--- a/lisp/language/tibetan.el
+++ b/lisp/language/tibetan.el
@@ -593,8 +593,8 @@ from an input method is converted to the corresponding precomposed glyph.")
(setq temp (concat temp "\\|" (car (car l))))
(setq l (cdr l)))
(concat temp "\\)")))
- "Regexp string to match a sequence of Tibetan consonantic components, i.e.,
-one base consonant and one or more subjoined consonants.
+ "Regexp string to match a sequence of Tibetan consonantic components.
+That is, one base consonant and one or more subjoined consonants.
The result of matching is to be used for indexing alist when the component
sequence is converted to the corresponding precomposed glyph.
This also matches some punctuation characters which need conversion.")
diff --git a/lisp/language/tv-util.el b/lisp/language/tv-util.el
index 207d76f47c1..b0527060db0 100644
--- a/lisp/language/tv-util.el
+++ b/lisp/language/tv-util.el
@@ -21,12 +21,13 @@
;; 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
+;;; Commentary:
-;; Regexp matching with a sequence of Tai Viet characters.
-(defconst tai-viet-re "[\xaa80-\xaac2\xaadb-\xaadf]+")
+;;; Code:
+
+(defconst tai-viet-re "[\xaa80-\xaac2\xaadb-\xaadf]+"
+ "Regexp matching with a sequence of Tai Viet characters.")
-;; Char-table of information about glyph type of Tai Viet characters.
(defconst tai-viet-glyph-info
(let ((table (make-char-table nil))
(specials '((right-overhang . "ꪊꪋꪌꪍꪏꪓꪖꪜꪞꪡꪤꪨ")
@@ -43,7 +44,8 @@
(chars (cdr elt)))
(dotimes (i (length chars))
(aset table (aref chars i) category))))
- table))
+ table)
+ "Char-table of information about glyph type of Tai Viet characters.")
(defun tai-viet-compose-string (from to string)
"Compose Tai Viet characters in STRING between indices FROM and TO."
diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el
index e6ac5d54fc7..0fbae8508a0 100644
--- a/lisp/ldefs-boot.el
+++ b/lisp/ldefs-boot.el
@@ -1,4 +1,5 @@
;;; loaddefs.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;; This file will be copied to ldefs-boot.el and checked in periodically.
;;
;;; Code:
@@ -48,7 +49,7 @@ Mutate the result." t nil)
(autoload '5x5-crack "5x5" "\
Attempt to find a solution for 5x5.
-5x5-crack takes the argument BREEDER which should be a function that takes
+`5x5-crack' takes the argument BREEDER which should be a function that takes
two parameters, the first will be a grid vector array that is the current
solution and the second will be the best solution so far. The function
should return a grid vector array that is the new solution.
@@ -288,7 +289,7 @@ The syntax of `defadvice' is as follows:
FUNCTION ::= Name of the function to be advised.
CLASS ::= `before' | `around' | `after' | `activation' | `deactivation'.
NAME ::= Non-nil symbol that names this piece of advice.
-POSITION ::= `first' | `last' | NUMBER. Optional, defaults to `first',
+POSITION ::= `first' | `last' | NUMBER. Optional, defaults to `first',
see also `ad-add-advice'.
ARGLIST ::= An optional argument list to be used for the advised function
instead of the argument list of the original. The first one found in
@@ -338,11 +339,22 @@ usage: (defadvice FUNCTION (CLASS NAME [POSITION] [ARGLIST] FLAG...)
(autoload 'align "align" "\
Attempt to align a region based on a set of alignment rules.
-BEG and END mark the region. If BEG and END are specifically set to
-nil (this can only be done programmatically), the beginning and end of
-the current alignment section will be calculated based on the location
-of point, and the value of `align-region-separate' (or possibly each
-rule's `separate' attribute).
+Interactively, BEG and END are the mark/point of the current region.
+
+Many modes define specific alignment rules, and some of these
+rules in some modes react to the current prefix argument. For
+instance, in `text-mode', `M-x align' will align into columns
+based on space delimiters, while `C-u - M-x align' will align
+into columns based on the \"$\" character. See the
+`align-rules-list' variable definition for the specific rules.
+
+Also see `align-regexp', which will guide you through various
+parameters for aligning text.
+
+Non-interactively, if BEG and END are nil, the beginning and end
+of the current alignment section will be calculated based on the
+location of point, and the value of `align-region-separate' (or
+possibly each rule's `separate' attribute).
If SEPARATE is non-nil, it overrides the value of
`align-region-separate' for all rules, except those that have their
@@ -360,6 +372,15 @@ Align the current region using an ad-hoc rule read from the minibuffer.
BEG and END mark the limits of the region. Interactively, this function
prompts for the regular expression REGEXP to align with.
+Interactively, if you specify a prefix argument, the function
+will guide you through entering the full regular expression, and
+then prompts for which subexpression parenthesis GROUP (default
+1) within REGEXP to modify, the amount of SPACING (default
+`align-default-spacing') to use, and whether or not to REPEAT the
+rule throughout the line.
+
+See `align-rules-list' for more information about these options.
+
For example, let's say you had a list of phone numbers, and wanted to
align them so that the opening parentheses would line up:
@@ -368,24 +389,19 @@ align them so that the opening parentheses would line up:
Mary-Anne (123) 456-7890
Joe (123) 456-7890
-There is no predefined rule to handle this, but you could easily do it
-using a REGEXP like \"(\". Interactively, all you would have to do is
-to mark the region, call `align-regexp' and enter that regular expression.
+There is no predefined rule to handle this, but interactively,
+all you would have to do is to mark the region, call `align-regexp'
+and enter \"(\".
-REGEXP must contain at least one parenthesized subexpression, typically
-whitespace of the form \"\\\\(\\\\s-*\\\\)\". In normal interactive use,
-this is automatically added to the start of your regular expression after
-you enter it. You only need to supply the characters to be lined up, and
-any preceding whitespace is replaced.
+REGEXP must contain at least one parenthesized subexpression,
+typically whitespace of the form \"\\\\(\\\\s-*\\\\)\", but in
+interactive use, this is automatically added to the start of your
+regular expression after you enter it. Interactively, you only
+need to supply the characters to be lined up, and any preceding
+whitespace is replaced.
-If you specify a prefix argument (or use this function non-interactively),
-you must enter the full regular expression, including the subexpression.
-The function also then prompts for which subexpression parenthesis GROUP
-\(default 1) within REGEXP to modify, the amount of SPACING (default
-`align-default-spacing') to use, and whether or not to REPEAT the rule
-throughout the line.
-
-See `align-rules-list' for more information about these options.
+Non-interactively, you must enter the full regular expression,
+including the subexpression.
The non-interactive form of the previous example would look something like:
(align-regexp (point-min) (point-max) \"\\\\(\\\\s-*\\\\)(\")
@@ -463,7 +479,7 @@ Control whether and how allout outline mode is automatically
activated when files are visited with non-nil buffer-specific
file variable `allout-layout'.
-When allout-auto-activation is \"On\" (t), allout mode is
+When `allout-auto-activation' is \"On\" (t), allout mode is
activated in buffers with non-nil `allout-layout', and the
specified layout is applied.
@@ -1201,8 +1217,9 @@ NOT recognized as integers or real numbers.
The array MUST reside at the top of the buffer.
TABs are not respected, and may be converted into spaces at any time.
-Setting the variable `array-respect-tabs' to non-nil will prevent TAB conversion,
-but will cause many functions to give errors if they encounter one.
+Setting the variable `array-respect-tabs' to non-nil will prevent
+TAB conversion, but will cause many functions to give errors if
+they encounter one.
Upon entering array mode, you will be prompted for the values of
several variables. Others will be calculated based on the values you
@@ -1392,7 +1409,7 @@ Drawing with keys
\\[artist-key-set-point] Does one of the following:
For lines/rectangles/squares: sets the first/second endpoint
- For poly-lines: sets a point (use C-u \\[artist-key-set-point] to set last point)
+ For poly-lines: sets a point (use \\[universal-argument] \\[artist-key-set-point] to set last point)
When erase characters: toggles erasing
When cutting/copying: Sets first/last endpoint of rect/square
When pasting: Pastes
@@ -1517,9 +1534,8 @@ Special commands:
;;; Generated autoloads from auth-source.el
(defvar auth-source-cache-expiry 7200 "\
-How many seconds passwords are cached, or nil to disable
-expiring. Overrides `password-cache-expiry' through a
-let-binding.")
+How many seconds passwords are cached, or nil to disable expiring.
+Overrides `password-cache-expiry' through a let-binding.")
(custom-autoload 'auth-source-cache-expiry "auth-source" t)
@@ -1592,7 +1608,7 @@ For example:
`6 9 a' inserts 69 `a's into the buffer.
`6 9 \\[autoarg-terminate] \\[autoarg-terminate]' inserts `69' into the buffer and
then invokes the normal binding of \\[autoarg-terminate].
-`C-u \\[autoarg-terminate]' invokes the normal binding of \\[autoarg-terminate] four times.
+`\\[universal-argument] \\[autoarg-terminate]' invokes the normal binding of \\[autoarg-terminate] four times.
\\{autoarg-mode-map}
@@ -1620,7 +1636,7 @@ 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 `(default-value 'autoarg-kp-mode)'.
+evaluate `(default-value \\='autoarg-kp-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -1663,6 +1679,8 @@ or if CONDITION had no actions, after all other CONDITIONs.
\(fn CONDITION ACTION &optional AFTER)" nil nil)
+(function-put 'define-auto-insert 'lisp-indent-function 'defun)
+
(defvar auto-insert-mode nil "\
Non-nil if Auto-Insert mode is enabled.
See the `auto-insert-mode' command
@@ -1685,7 +1703,7 @@ 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 `(default-value 'auto-insert-mode)'.
+evaluate `(default-value \\='auto-insert-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -1871,7 +1889,7 @@ 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 `(default-value 'global-auto-revert-mode)'.
+evaluate `(default-value \\='global-auto-revert-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -1967,7 +1985,6 @@ Output stream used is value of `standard-output'." nil nil)
(autoload 'bat-mode "bat-mode" "\
Major mode for editing DOS/Windows batch files.
-
Start a new script from `bat-template'. Read help pages for DOS commands
with `bat-cmd-help'. Navigate between sections using `imenu'.
Run script using `bat-run' and `bat-run-args'.
@@ -2011,7 +2028,7 @@ 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 `(default-value 'display-battery-mode)'.
+evaluate `(default-value \\='display-battery-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -2365,12 +2382,7 @@ a reflection.
(define-key ctl-x-r-map "M" 'bookmark-set-no-overwrite)
(define-key ctl-x-r-map "l" 'bookmark-bmenu-list)
-(defvar bookmark-map (let ((map (make-sparse-keymap))) (define-key map "x" 'bookmark-set) (define-key map "m" 'bookmark-set) (define-key map "M" 'bookmark-set-no-overwrite) (define-key map "j" 'bookmark-jump) (define-key map "g" 'bookmark-jump) (define-key map "o" 'bookmark-jump-other-window) (define-key map "5" 'bookmark-jump-other-frame) (define-key map "i" 'bookmark-insert) (define-key map "e" 'edit-bookmarks) (define-key map "f" 'bookmark-insert-location) (define-key map "r" 'bookmark-rename) (define-key map "d" 'bookmark-delete) (define-key map "D" 'bookmark-delete-all) (define-key map "l" 'bookmark-load) (define-key map "w" 'bookmark-write) (define-key map "s" 'bookmark-save) map) "\
-Keymap containing bindings to bookmark functions.
-It is not bound to any key by default: to bind it
-so that you have a bookmark prefix, just use `global-set-key' and bind a
-key of your choice to variable `bookmark-map'. All interactive bookmark
-functions have a binding in this keymap.")
+(defvar-keymap bookmark-map :doc "Keymap containing bindings to bookmark functions.\nIt is not bound to any key by default: to bind it\nso that you have a bookmark prefix, just use `global-set-key' and bind a\nkey of your choice to variable `bookmark-map'. All interactive bookmark\nfunctions have a binding in this keymap." "x" #'bookmark-set "m" #'bookmark-set "M" #'bookmark-set-no-overwrite "j" #'bookmark-jump "g" #'bookmark-jump "o" #'bookmark-jump-other-window "5" #'bookmark-jump-other-frame "i" #'bookmark-insert "e" #'edit-bookmarks "f" #'bookmark-insert-location "r" #'bookmark-rename "d" #'bookmark-delete "D" #'bookmark-delete-all "l" #'bookmark-load "w" #'bookmark-write "s" #'bookmark-save)
(fset 'bookmark-map bookmark-map)
(autoload 'bookmark-set "bookmark" "\
@@ -2385,14 +2397,14 @@ others are still there, should the user decide to delete the most
recent one.
To yank words from the text of the buffer and use them as part of the
-bookmark name, type C-w while setting a bookmark. Successive C-w's
+bookmark name, type \\<bookmark-minibuffer-read-name-map>\\[bookmark-yank-word] while setting a bookmark. Successive \\[bookmark-yank-word]'s
yank successive words.
-Typing C-u inserts (at the bookmark name prompt) the name of the last
+Typing \\[universal-argument] inserts (at the bookmark name prompt) the name of the last
bookmark used in the document where the new bookmark is being set;
this helps you use a single bookmark name to track progress through a
large document. If there is no prior bookmark for this document, then
-C-u inserts an appropriate name based on the buffer or file.
+\\[universal-argument] inserts an appropriate name based on the buffer or file.
Use \\[bookmark-delete] to remove bookmarks (you give it a name and
it removes only the first instance of a bookmark with that name from
@@ -2415,14 +2427,14 @@ Otherwise, if a bookmark named NAME already exists but PUSH-BOOKMARK
is nil, raise an error.
To yank words from the text of the buffer and use them as part of the
-bookmark name, type C-w while setting a bookmark. Successive C-w's
+bookmark name, type \\<bookmark-minibuffer-read-name-map>\\[bookmark-yank-word] while setting a bookmark. Successive \\[bookmark-yank-word]'s
yank successive words.
-Typing C-u inserts (at the bookmark name prompt) the name of the last
+Typing \\[universal-argument] inserts (at the bookmark name prompt) the name of the last
bookmark used in the document where the new bookmark is being set;
this helps you use a single bookmark name to track progress through a
large document. If there is no prior bookmark for this document, then
-C-u inserts an appropriate name based on the buffer or file.
+\\[universal-argument] inserts an appropriate name based on the buffer or file.
Use \\[bookmark-delete] to remove bookmarks (you give it a name and
it removes only the first instance of a bookmark with that name from
@@ -2489,7 +2501,7 @@ If called from Lisp, prompt for NEW-NAME if only OLD-NAME was passed
as an argument. If called with two strings, then no prompting is done.
You must pass at least OLD-NAME when calling from Lisp.
-While you are entering the new name, consecutive C-w's insert
+While you are entering the new name, consecutive \\<bookmark-minibuffer-read-name-map>\\[bookmark-yank-word]'s insert
consecutive words from the text of the buffer into the new bookmark
name.
@@ -2534,7 +2546,7 @@ Write bookmarks to a file (reading the file name with the minibuffer)." t nil)
Save currently defined bookmarks in FILE.
FILE defaults to `bookmark-default-file'.
With prefix PARG, query user for a file to save in.
-If MAKE-DEFAULT is non-nil (interactively with prefix C-u C-u)
+If MAKE-DEFAULT is non-nil (interactively with prefix \\[universal-argument] \\[universal-argument])
the file we save in becomes the new default in the current Emacs
session (without affecting the value of `bookmark-default-file'.).
@@ -2799,6 +2811,13 @@ used instead of `browse-url-new-window-flag'.
(make-obsolete 'browse-url-galeon 'nil '"25.1")
+(autoload 'browse-url-webpositive "browse-url" "\
+Ask the WebPositive WWW browser to load URL.
+Default to the URL around or before point.
+The optional argument NEW-WINDOW is not used.
+
+\(fn URL &optional NEW-WINDOW)" t nil)
+
(autoload 'browse-url-emacs "browse-url" "\
Ask Emacs to load URL into a buffer and show it in another window.
Optional argument SAME-WINDOW non-nil means show the URL in the
@@ -2938,6 +2957,13 @@ from `browse-url-elinks-wrapper'.
\(fn URL &optional NEW-WINDOW)" t nil)
+(autoload 'browse-url-button-open "browse-url" "\
+Follow the link under point using `browse-url'.
+If EXTERNAL (the prefix if used interactively), open with the
+external browser instead of the default one.
+
+\(fn &optional EXTERNAL MOUSE-EVENT)" t nil)
+
(autoload 'browse-url-button-open-url "browse-url" "\
Open URL using `browse-url'.
If `current-prefix-arg' is non-nil, use
@@ -2951,7 +2977,6 @@ If `current-prefix-arg' is non-nil, use
;;;### (autoloads nil "bs" "bs.el" (0 0 0 0))
;;; Generated autoloads from bs.el
-(push (purecopy '(bs 1 17)) package--builtin-versions)
(autoload 'bs-cycle-next "bs" "\
Select next buffer defined by buffer cycling.
@@ -3075,6 +3100,11 @@ disabled.
(put 'byte-compile-warnings 'safe-local-variable (lambda (v) (or (symbolp v) (null (delq nil (mapcar (lambda (x) (not (symbolp x))) v))))))
+(autoload 'byte-compile-warning-enabled-p "bytecomp" "\
+Return non-nil if WARNING is enabled, according to `byte-compile-warnings'.
+
+\(fn WARNING &optional SYMBOL)" nil nil)
+
(autoload 'byte-compile-disable-warning "bytecomp" "\
Change `byte-compile-warnings' to disable WARNING.
If `byte-compile-warnings' is t, set it to `(not WARNING)'.
@@ -3374,7 +3404,7 @@ or a list containing a character position and an error message in string form.
Invoke the Calculator in \"visual keypad\" mode.
This is most useful in the X window system.
In this mode, click on the Calc \"buttons\" using the left mouse button.
-Or, position the cursor manually and do M-x calc-keypad-press.
+Or, position the cursor manually and do \\[calc-keypad-press].
\(fn &optional INTERACTIVE)" t nil)
@@ -3394,6 +3424,16 @@ Parse a rectangle as a matrix of numbers and push it on the Calculator stack.
\(fn TOP BOT ARG)" t nil)
+(autoload 'calc-grab-sum-down "calc" "\
+Parse a rectangle as a matrix of numbers and sum its columns.
+
+\(fn TOP BOT ARG)" t nil)
+
+(autoload 'calc-grab-sum-across "calc" "\
+Parse a rectangle as a matrix of numbers and sum its rows.
+
+\(fn TOP BOT ARG)" t nil)
+
(autoload 'calc-embedded "calc" "\
Start Calc Embedded mode on the formula surrounding point.
@@ -3421,6 +3461,8 @@ See Info node `(calc)Defining Functions'.
(function-put 'defmath 'doc-string-elt '3)
+(function-put 'defmath 'lisp-indent-function 'defun)
+
(register-definition-prefixes "calc" '("calc" "defcalcmodevar" "inexact-result" "math-" "var-"))
;;;***
@@ -3965,7 +4007,7 @@ control). See \"cc-mode.el\" for more info.
Major mode for editing C code.
To submit a problem report, enter `\\[c-submit-bug-report]' from a
-c-mode buffer. This automatically sets up a mail buffer with version
+`c-mode' buffer. This automatically sets up a mail buffer with version
information already added. You just need to add a description of the
problem, including a reproducible test case, and send the message.
@@ -4013,7 +4055,7 @@ Key bindings:
(autoload 'objc-mode "cc-mode" "\
Major mode for editing Objective C code.
To submit a problem report, enter `\\[c-submit-bug-report]' from an
-objc-mode buffer. This automatically sets up a mail buffer with
+`objc-mode' buffer. This automatically sets up a mail buffer with
version information already added. You just need to add a description
of the problem, including a reproducible test case, and send the
message.
@@ -4032,7 +4074,7 @@ Key bindings:
(autoload 'java-mode "cc-mode" "\
Major mode for editing Java code.
To submit a problem report, enter `\\[c-submit-bug-report]' from a
-java-mode buffer. This automatically sets up a mail buffer with
+`java-mode' buffer. This automatically sets up a mail buffer with
version information already added. You just need to add a description
of the problem, including a reproducible test case, and send the
message.
@@ -4051,7 +4093,7 @@ Key bindings:
(autoload 'idl-mode "cc-mode" "\
Major mode for editing CORBA's IDL, PSDL and CIDL code.
To submit a problem report, enter `\\[c-submit-bug-report]' from an
-idl-mode buffer. This automatically sets up a mail buffer with
+`idl-mode' buffer. This automatically sets up a mail buffer with
version information already added. You just need to add a description
of the problem, including a reproducible test case, and send the
message.
@@ -4071,7 +4113,7 @@ Key bindings:
(autoload 'pike-mode "cc-mode" "\
Major mode for editing Pike code.
To submit a problem report, enter `\\[c-submit-bug-report]' from a
-pike-mode buffer. This automatically sets up a mail buffer with
+`pike-mode' buffer. This automatically sets up a mail buffer with
version information already added. You just need to add a description
of the problem, including a reproducible test case, and send the
message.
@@ -4094,7 +4136,7 @@ Key bindings:
(autoload 'awk-mode "cc-mode" "\
Major mode for editing AWK code.
To submit a problem report, enter `\\[c-submit-bug-report]' from an
-awk-mode buffer. This automatically sets up a mail buffer with version
+`awk-mode' buffer. This automatically sets up a mail buffer with version
information already added. You just need to add a description of the
problem, including a reproducible test case, and send the message.
@@ -4142,7 +4184,7 @@ a null operation.
\(fn STYLENAME &optional DONT-OVERRIDE)" t nil)
(autoload 'c-add-style "cc-styles" "\
-Adds a style to `c-style-alist', or updates an existing one.
+Add a style to `c-style-alist', or update an existing one.
STYLE is a string identifying the style to add or update. DESCRIPTION
is an association list describing the style and must be of the form:
@@ -4450,6 +4492,8 @@ MAP-ID := integer
(function-put 'define-ccl-program 'doc-string-elt '3)
+(function-put 'define-ccl-program 'lisp-indent-function 'defun)
+
(autoload 'check-ccl-program "ccl" "\
Check validity of CCL-PROGRAM.
If CCL-PROGRAM is a symbol denoting a CCL program, return
@@ -4639,7 +4683,7 @@ Return t when OBJ is a list of strings.
(autoload 'checkdoc "checkdoc" "\
Interactively check the entire buffer for style errors.
The current status of the check will be displayed in a buffer which
-the users will view as each check is completed." t nil)
+the users will view as each check is completed." '(emacs-lisp-mode) nil)
(autoload 'checkdoc-interactive "checkdoc" "\
Interactively check the current buffer for doc string errors.
@@ -4650,7 +4694,7 @@ errors. Does not check for comment or space warnings.
Optional argument SHOWSTATUS indicates that we should update the
checkdoc status window instead of the usual behavior.
-\(fn &optional START-HERE SHOWSTATUS)" t nil)
+\(fn &optional START-HERE SHOWSTATUS)" '(emacs-lisp-mode) nil)
(autoload 'checkdoc-message-interactive "checkdoc" "\
Interactively check the current buffer for message string errors.
@@ -4661,7 +4705,7 @@ errors. Does not check for comment or space warnings.
Optional argument SHOWSTATUS indicates that we should update the
checkdoc status window instead of the usual behavior.
-\(fn &optional START-HERE SHOWSTATUS)" t nil)
+\(fn &optional START-HERE SHOWSTATUS)" '(emacs-lisp-mode) nil)
(autoload 'checkdoc-eval-current-buffer "checkdoc" "\
Evaluate and check documentation for the current buffer.
@@ -4675,7 +4719,7 @@ With a prefix argument (in Lisp, the argument TAKE-NOTES),
store all errors found in a warnings buffer,
otherwise stop after the first error.
-\(fn &optional TAKE-NOTES)" t nil)
+\(fn &optional TAKE-NOTES)" '(emacs-lisp-mode) nil)
(autoload 'checkdoc-file "checkdoc" "\
Check FILE for document, comment, error style, and rogue spaces.
@@ -4689,14 +4733,14 @@ Use `checkdoc-continue' to continue checking if an error cannot be fixed.
Prefix argument TAKE-NOTES means to collect all the warning messages into
a separate buffer.
-\(fn &optional TAKE-NOTES)" t nil)
+\(fn &optional TAKE-NOTES)" '(emacs-lisp-mode) nil)
(autoload 'checkdoc-continue "checkdoc" "\
Find the next doc string in the current buffer which has a style error.
Prefix argument TAKE-NOTES means to continue through the whole
buffer and save warnings in a separate buffer.
-\(fn &optional TAKE-NOTES)" t nil)
+\(fn &optional TAKE-NOTES)" '(emacs-lisp-mode) nil)
(autoload 'checkdoc-comments "checkdoc" "\
Find missing comment sections in the current Emacs Lisp file.
@@ -4704,7 +4748,7 @@ Prefix argument TAKE-NOTES non-nil means to save warnings in a
separate buffer. Otherwise print a message. This returns the error
if there is one.
-\(fn &optional TAKE-NOTES)" t nil)
+\(fn &optional TAKE-NOTES)" '(emacs-lisp-mode) nil)
(autoload 'checkdoc-rogue-spaces "checkdoc" "\
Find extra spaces at the end of lines in the current file.
@@ -4713,13 +4757,13 @@ separate buffer. Otherwise print a message. This returns the error
if there is one.
Optional argument INTERACT permits more interactive fixing.
-\(fn &optional TAKE-NOTES INTERACT)" t nil)
+\(fn &optional TAKE-NOTES INTERACT)" '(emacs-lisp-mode) nil)
(autoload 'checkdoc-message-text "checkdoc" "\
Scan the buffer for occurrences of the error function, and verify text.
Optional argument TAKE-NOTES causes all errors to be logged.
-\(fn &optional TAKE-NOTES)" t nil)
+\(fn &optional TAKE-NOTES)" '(emacs-lisp-mode) nil)
(autoload 'checkdoc-eval-defun "checkdoc" "\
Evaluate the current form with `eval-defun' and check its documentation.
@@ -4736,6 +4780,14 @@ space at the end of each line.
\(fn &optional NO-ERROR)" t nil)
+(autoload 'checkdoc-dired "checkdoc" "\
+In Dired, run `checkdoc' on marked files.
+Skip anything that doesn't have the Emacs Lisp library file
+extension (\".el\").
+When called from Lisp, FILES is a list of filenames.
+
+\(fn FILES)" '(dired-mode) nil)
+
(autoload 'checkdoc-ispell "checkdoc" "\
Check the style and spelling of everything interactively.
Calls `checkdoc' with spell-checking turned on.
@@ -4913,7 +4965,7 @@ 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 `(default-value 'cl-font-lock-built-in-mode)'.
+evaluate `(default-value \\='cl-font-lock-built-in-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -5148,7 +5200,7 @@ 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 `(default-value 'cl-old-struct-compat-mode)'.
+evaluate `(default-value \\='cl-old-struct-compat-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -5406,8 +5458,9 @@ clashes.
\(fn NAME PREFIX &optional FIRST)" nil nil)
(autoload 'comp-clean-up-stale-eln "comp" "\
-Given FILE remove all its *.eln files in `native-comp-eln-load-path'
-sharing the original source filename (including FILE).
+Remove all FILE*.eln* files found in `native-comp-eln-load-path'.
+The files to be removed are those produced from the original source
+filename (including FILE).
\(fn FILE)" nil nil)
@@ -5432,10 +5485,17 @@ form, return the compiled function.
\(fn FUNCTION-OR-FILE &optional OUTPUT)" nil nil)
(autoload 'batch-native-compile "comp" "\
-Perform native compilation on remaining command-line arguments.
-Use this from the command line, with ‘-batch’;
-it won’t work in an interactive Emacs.
-Native compilation equivalent to `batch-byte-compile'." nil nil)
+Perform batch native compilation of remaining command-line arguments.
+
+Native compilation equivalent of `batch-byte-compile'.
+Use this from the command line, with `-batch'; it won't work
+in an interactive Emacs session.
+Optional argument FOR-TARBALL non-nil means the file being compiled
+as part of building the source tarball, in which case the .eln file
+will be placed under the native-lisp/ directory (actually, in the
+last directory in `native-comp-eln-load-path').
+
+\(fn &optional FOR-TARBALL)" nil nil)
(autoload 'batch-byte+native-compile "comp" "\
Like `batch-native-compile', but used for bootstrap.
@@ -5495,7 +5555,7 @@ If both windows display the same buffer,
the mark is pushed twice in that buffer:
first in the other window, then in the selected window.
-A prefix arg means reverse the value of variable
+A prefix arg IGNORE-WHITESPACE, means reverse the value of variable
`compare-ignore-whitespace'. If `compare-ignore-whitespace' is
nil, then a prefix arg means ignore changes in whitespace. If
`compare-ignore-whitespace' is non-nil, then a prefix arg means
@@ -5751,7 +5811,7 @@ 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 `(default-value 'dynamic-completion-mode)'.
+evaluate `(default-value \\='dynamic-completion-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -5957,8 +6017,8 @@ of load, ENDMSG at the end.
\(fn PHRASE-FILE &optional COUNT STARTMSG ENDMSG)" nil nil)
(autoload 'cookie-snarf "cookie1" "\
-Reads in the PHRASE-FILE, returns it as a vector of strings.
-Emit STARTMSG and ENDMSG before and after. Caches the result; second
+Read the PHRASE-FILE, return it as a vector of strings.
+Emit STARTMSG and ENDMSG before and after. Cache the result; second
and subsequent calls on the same file won't go to disk.
\(fn PHRASE-FILE &optional STARTMSG ENDMSG)" nil nil)
@@ -6085,7 +6145,7 @@ into
\\{cperl-mode-map}
-Setting the variable `cperl-font-lock' to t switches on font-lock-mode
+Setting the variable `cperl-font-lock' to t switches on `font-lock-mode'
\(even with older Emacsen), `cperl-electric-lbrace-space' to t switches
on electric space between $ and {, `cperl-electric-parens-string' is
the string that contains parentheses that should be electric in CPerl
@@ -6320,7 +6380,7 @@ 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 `(default-value 'cua-mode)'.
+evaluate `(default-value \\='cua-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -6711,7 +6771,7 @@ You can set this option through Custom, if you carefully read the
last paragraph below. However, usually it is simpler to write
something like the following in your init file:
-\(setq custom-file \"~/.emacs-custom.el\")
+\(setq custom-file \"~/.config/emacs-custom.el\")
\(load custom-file)
Note that both lines are necessary: the first line tells Custom to
@@ -6852,8 +6912,11 @@ or call the function `global-cwarn-mode'.")
(autoload 'global-cwarn-mode "cwarn" "\
Toggle Cwarn mode in all buffers.
With prefix ARG, enable Global Cwarn mode if ARG is positive;
-otherwise, disable it. If called from Lisp, enable the mode if ARG is
-omitted or nil.
+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.
Cwarn mode is enabled in all buffers where
`turn-on-cwarn-mode-if-enabled' would do it.
@@ -7063,7 +7126,7 @@ Variables controlling indentation style and extra features:
These variables control the look of expanded templates.
dcl-imenu-generic-expression
- Default value for imenu-generic-expression. The default includes
+ Default value for `imenu-generic-expression'. The default includes
SUBROUTINE labels in the main listing and sub-listings for
other labels, CALL, GOTO and GOSUB statements.
@@ -7149,7 +7212,7 @@ Redefining FUNCTION also cancels it.
(autoload 'cancel-debug-on-entry "debug" "\
Undo effect of \\[debug-on-entry] on FUNCTION.
-If FUNCTION is nil, cancel debug-on-entry for all functions.
+If FUNCTION is nil, cancel `debug-on-entry' for all functions.
When called interactively, prompt for FUNCTION in the minibuffer.
To specify a nil argument interactively, exit with an empty minibuffer.
@@ -7179,7 +7242,7 @@ another symbol also cancels it.
(autoload 'cancel-debug-on-variable-change "debug" "\
Undo effect of \\[debug-on-variable-change] on VARIABLE.
-If VARIABLE is nil, cancel debug-on-variable-change for all variables.
+If VARIABLE is nil, cancel `debug-on-variable-change' for all variables.
When called interactively, prompt for VARIABLE in the minibuffer.
To specify a nil argument interactively, exit with an empty minibuffer.
@@ -7246,7 +7309,7 @@ See the `delimit-columns-str-before',
`delimit-columns-before', `delimit-columns-after',
`delimit-columns-separator', `delimit-columns-format' and
`delimit-columns-extra' variables for customization of the
-look.
+look.
\(fn START END)" t nil)
@@ -7290,7 +7353,7 @@ 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 `(default-value 'delete-selection-mode)'.
+evaluate `(default-value \\='delete-selection-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -7326,7 +7389,7 @@ The arguments are as follows:
CHILD: the name of the command for the derived mode.
PARENT: the name of the command for the parent mode (e.g. `text-mode')
or nil if there is no parent.
-NAME: a string which will appear in the status line (e.g. \"Hypertext\")
+NAME: a string that will appear in the mode line (e.g. \"HTML\")
DOCSTRING: an optional documentation string--if you do not supply one,
the function will attempt to invent something useful.
KEYWORD-ARGS:
@@ -7345,7 +7408,7 @@ KEYWORD-ARGS:
A nil value means to simply use the same abbrev-table
as the parent.
:after-hook FORM
- A single lisp form which is evaluated after the mode
+ A single Lisp form which is evaluated after the mode
hooks have been run. It should not be quoted.
:interactive BOOLEAN
Whether the derived mode should be `interactive' or not.
@@ -7372,8 +7435,8 @@ the parent, and then sets the variable `case-fold-search' to nil:
Note that if the documentation string had been left out, it would have
been generated automatically, with a reference to the keymap.
-The new mode runs the hook constructed by the function
-`derived-mode-hook-name'.
+The new mode runs the hook named MODE-hook. For `foo-mode',
+the hook will be named `foo-mode-hook'.
See Info node `(elisp)Derived Modes' for more details.
@@ -7381,6 +7444,8 @@ See Info node `(elisp)Derived Modes' for more details.
(function-put 'define-derived-mode 'doc-string-elt '4)
+(function-put 'define-derived-mode 'lisp-indent-function 'defun)
+
(autoload 'derived-mode-init-mode-variables "derived" "\
Initialize variables for a new MODE.
Right now, if they don't already exist, set up a blank keymap, an
@@ -7478,7 +7543,7 @@ 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 `(default-value 'desktop-save-mode)'.
+evaluate `(default-value \\='desktop-save-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -7834,16 +7899,24 @@ active it will overwrite that mode for the current buffer.
\(fn &optional ARG)" t nil)
(autoload 'global-dictionary-tooltip-mode "dictionary" "\
-Enable/disable dictionary-tooltip-mode for all buffers.
+Enable/disable `dictionary-tooltip-mode' for all buffers.
-Internally it provides a default for the dictionary-tooltip-mode.
-It can be overwritten for each buffer using dictionary-tooltip-mode.
+Internally it provides a default for the `dictionary-tooltip-mode'.
+It can be overwritten for each buffer using `dictionary-tooltip-mode'.
Note: (global-dictionary-tooltip-mode 0) will not disable the mode
any buffer where (dictionary-tooltip-mode 1) has been called.
\(fn &optional ARG)" t nil)
+(autoload 'context-menu-dictionary "dictionary" "\
+Populate MENU with dictionary commands at CLICK.
+When you add this function to `context-menu-functions',
+the context menu will contain an item that searches
+the word at mouse click.
+
+\(fn MENU CLICK)" nil nil)
+
(register-definition-prefixes "dictionary" '("dictionary-" "global-dictionary-tooltip-mode"))
;;;***
@@ -7881,10 +7954,10 @@ minibuffer. The default for NEW is the current buffer's file
name, and the default for OLD is a backup file for NEW, if one
exists. If NO-ASYNC is non-nil, call diff synchronously.
-When called interactively with a prefix argument, prompt
+When called interactively with a prefix argument SWITCHES, prompt
interactively for diff switches. Otherwise, the switches
-specified in the variable `diff-switches' are passed to the
-diff command.
+specified in the variable `diff-switches' are passed to the diff
+command.
Non-interactively, OLD and NEW may each be a file or a buffer.
@@ -7895,12 +7968,12 @@ Diff this file with its backup file or vice versa.
Uses the latest backup, if there are several numerical backups.
If this file is a backup, diff it with its original.
The backup file is the first file given to `diff'.
-With prefix arg, prompt for diff switches.
+With prefix arg SWITCHES, prompt for diff switches.
\(fn FILE &optional SWITCHES)" t nil)
(autoload 'diff-latest-backup-file "diff" "\
-Return the latest existing backup of FILE, or nil.
+Return the latest existing backup of file FN, or nil.
\(fn FN)" nil nil)
@@ -7940,7 +8013,7 @@ Supports unified and context diffs as well as (to a lesser extent)
normal diffs.
When the buffer is read-only, the ESC prefix is not necessary.
-If you edit the buffer manually, diff-mode will try to update the hunk
+If you edit the buffer manually, `diff-mode' will try to update the hunk
headers for you on-the-fly.
You can also switch between context diff and unified diff with \\[diff-context->unified],
@@ -8045,24 +8118,24 @@ If DIRNAME is already in a Dired buffer, that buffer is used without refresh.
(define-key ctl-x-4-map "d" 'dired-other-window)
(autoload 'dired-other-window "dired" "\
-\"Edit\" directory DIRNAME. Like `dired' but selects in another window.
+\"Edit\" directory DIRNAME. Like `dired' but select in another window.
\(fn DIRNAME &optional SWITCHES)" t nil)
(define-key ctl-x-5-map "d" 'dired-other-frame)
(autoload 'dired-other-frame "dired" "\
-\"Edit\" directory DIRNAME. Like `dired' but makes a new frame.
+\"Edit\" directory DIRNAME. Like `dired' but make a new frame.
\(fn DIRNAME &optional SWITCHES)" t nil)
(define-key tab-prefix-map "d" 'dired-other-tab)
(autoload 'dired-other-tab "dired" "\
-\"Edit\" directory DIRNAME. Like `dired' but makes a new tab.
+\"Edit\" directory DIRNAME. Like `dired' but make a new tab.
\(fn DIRNAME &optional SWITCHES)" t nil)
(autoload 'dired-noselect "dired" "\
-Like `dired' but returns the Dired buffer as value, does not select it.
+Like `dired' but return the Dired buffer as value, do not select it.
\(fn DIR-OR-LIST &optional SWITCHES)" nil nil)
@@ -8121,11 +8194,17 @@ Keybindings:
(autoload 'dired-jump "dired" "\
Jump to Dired buffer corresponding to current buffer.
-If in a file, Dired the current directory and move to file's line.
+If in a buffer visiting a file, Dired that file's directory and
+move to that file's line in the directory listing.
+
+If the current buffer isn't visiting a file, Dired `default-directory'.
+
If in Dired already, pop up a level and goto old directory's line.
In case the proper Dired file line cannot be found, refresh the dired
buffer and try again.
+
When OTHER-WINDOW is non-nil, jump to Dired buffer in other window.
+
When FILE-NAME is non-nil, jump to its line in Dired.
Interactively with prefix argument, read FILE-NAME.
@@ -8323,7 +8402,7 @@ in `.emacs'.
;;; Generated autoloads from display-fill-column-indicator.el
(autoload 'display-fill-column-indicator-mode "display-fill-column-indicator" "\
-Toggle display of fill-column indicator.
+Toggle display of `fill-column' indicator.
This uses `display-fill-column-indicator' internally.
This is a minor mode. If called interactively, toggle the
@@ -8365,8 +8444,11 @@ or call the function `global-display-fill-column-indicator-mode'.")
(autoload 'global-display-fill-column-indicator-mode "display-fill-column-indicator" "\
Toggle Display-Fill-Column-Indicator mode in all buffers.
With prefix ARG, enable Global Display-Fill-Column-Indicator mode if
-ARG is positive; otherwise, disable it. If called from Lisp, enable
-the mode if ARG is omitted or nil.
+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.
Display-Fill-Column-Indicator mode is enabled in all buffers where
`display-fill-column-indicator--turn-on' would do it.
@@ -8374,8 +8456,8 @@ Display-Fill-Column-Indicator mode is enabled in all buffers where
See `display-fill-column-indicator-mode' for more information on
Display-Fill-Column-Indicator mode.
-`global-display-fill-column-indicator-modes' is used to control
-which modes this minor mode is used in.
+`global-display-fill-column-indicator-modes' is used to control which
+modes this minor mode is used in.
\(fn &optional ARG)" t nil)
@@ -8442,8 +8524,11 @@ or call the function `global-display-line-numbers-mode'.")
(autoload 'global-display-line-numbers-mode "display-line-numbers" "\
Toggle Display-Line-Numbers mode in all buffers.
With prefix ARG, enable Global Display-Line-Numbers mode if ARG is
-positive; otherwise, disable it. If called from Lisp, enable the mode
-if ARG is omitted or nil.
+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.
Display-Line-Numbers mode is enabled in all buffers where
`display-line-numbers--turn-on' would do it.
@@ -8718,8 +8803,8 @@ BODY contains code to execute each time the mode is enabled or disabled.
Not used if you also specify :variable.
:lighter SPEC Text displayed in the mode line when the mode is on.
:keymap MAP Keymap bound to the mode keymap. Defaults to `MODE-map'.
- If non-nil, it should be a variable name (whose value is
- a keymap), or an expression that returns either a keymap or
+ If non-nil, it should be an unquoted variable name (whose value
+ is a keymap), or an expression that returns either a keymap or
a list of (KEY . BINDING) pairs where KEY and BINDING are
suitable for `define-key'. If you supply a KEYMAP argument
that is not a symbol, this macro defines the variable MODE-map
@@ -8733,11 +8818,11 @@ BODY contains code to execute each time the mode is enabled or disabled.
named variable, or a generalized variable.
PLACE can also be of the form (GET . SET), where GET is
an expression that returns the current state, and SET is
- a function that takes one argument, the new state, and
- sets it. If you specify a :variable, this function does
- not define a MODE variable (nor any of the terms used
+ a function that takes one argument, the new state, which should
+ be assigned to PLACE. If you specify a :variable, this function
+ does not define a MODE variable (nor any of the terms used
in :variable).
-:after-hook A single lisp form which is evaluated after the mode hooks
+:after-hook A single Lisp form which is evaluated after the mode hooks
have been run. It should not be quoted.
For example, you could write
@@ -8753,6 +8838,8 @@ INIT-VALUE LIGHTER KEYMAP.
(function-put 'define-minor-mode 'doc-string-elt '2)
+(function-put 'define-minor-mode 'lisp-indent-function 'defun)
+
(defalias 'easy-mmode-define-global-mode #'define-globalized-minor-mode)
(defalias 'define-global-minor-mode #'define-globalized-minor-mode)
@@ -8790,6 +8877,8 @@ on if the hook has explicitly disabled it.
(function-put 'define-globalized-minor-mode 'doc-string-elt '2)
+(function-put 'define-globalized-minor-mode 'lisp-indent-function 'defun)
+
(autoload 'easy-mmode-define-keymap "easy-mmode" "\
Return a keymap built from bindings BS.
BS must be a list of (KEY . BINDING) where
@@ -9340,7 +9429,7 @@ 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 `(default-value 'global-ede-mode)'.
+evaluate `(default-value \\='global-ede-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -9638,9 +9727,11 @@ symbol describing the Ediff job type; it defaults to
(defalias 'ebuffers3 #'ediff-buffers3)
(autoload 'ediff-directories "ediff" "\
-Run Ediff on a pair of directories, DIR1 and DIR2, comparing files that have
-the same name in both. The third argument, REGEXP, is nil or a regular
-expression; only file names that match the regexp are considered.
+Run Ediff on directories DIR1 and DIR2, comparing files.
+Consider only files that have the same name in both directories.
+
+REGEXP is nil or a regular expression; only file names that match
+the regexp are considered.
\(fn DIR1 DIR2 REGEXP)" t nil)
@@ -9656,9 +9747,11 @@ names. Only the files that are under revision control are taken into account.
(defalias 'edir-revisions #'ediff-directory-revisions)
(autoload 'ediff-directories3 "ediff" "\
-Run Ediff on three directories, DIR1, DIR2, and DIR3, comparing files that
-have the same name in all three. The last argument, REGEXP, is nil or a
-regular expression; only file names that match the regexp are considered.
+Run Ediff on directories DIR1, DIR2, and DIR3, comparing files.
+Consider only files that have the same name in all three directories.
+
+REGEXP is nil or a regular expression; only file names that match
+the regexp are considered.
\(fn DIR1 DIR2 DIR3 REGEXP)" t nil)
@@ -9675,7 +9768,7 @@ MERGE-AUTOSTORE-DIR is the directory in which to store merged files.
(defalias 'edirs-merge #'ediff-merge-directories)
(autoload 'ediff-merge-directories-with-ancestor "ediff" "\
-Merge files in directories DIR1 and DIR2 using files in ANCESTOR-DIR as ancestors.
+Merge files in DIR1 and DIR2 using files in ANCESTOR-DIR as ancestors.
Ediff merges files that have identical names in DIR1, DIR2. If a pair of files
in DIR1 and DIR2 doesn't have an ancestor in ANCESTOR-DIR, Ediff will merge
without ancestor. The fourth argument, REGEXP, is nil or a regular expression;
@@ -9695,7 +9788,7 @@ MERGE-AUTOSTORE-DIR is the directory in which to store merged files.
(defalias 'edir-merge-revisions #'ediff-merge-directory-revisions)
(autoload 'ediff-merge-directory-revisions-with-ancestor "ediff" "\
-Run Ediff on a directory, DIR1, merging its files with their revisions and ancestors.
+Run Ediff on DIR1 and merge its files with their revisions and ancestors.
The second argument, REGEXP, is a regular expression that filters the file
names. Only the files that are under revision control are taken into account.
MERGE-AUTOSTORE-DIR is the directory in which to store merged files.
@@ -9880,7 +9973,7 @@ Call `ediff3-files' with the next three command line arguments." nil nil)
Call `ediff-merge-files' with the next two command line arguments." nil nil)
(autoload 'ediff-merge-with-ancestor-command "ediff" "\
-Call `ediff-merge-files-with-ancestor' with the next three command line arguments." nil nil)
+Call `ediff-merge-files-with-ancestor' with next three command line arguments." nil nil)
(autoload 'ediff-directories-command "ediff" "\
Call `ediff-directories' with the next three command line arguments." nil nil)
@@ -9892,7 +9985,8 @@ Call `ediff-directories3' with the next four command line arguments." nil nil)
Call `ediff-merge-directories' with the next three command line arguments." nil nil)
(autoload 'ediff-merge-directories-with-ancestor-command "ediff" "\
-Call `ediff-merge-directories-with-ancestor' with the next four command line arguments." nil nil)
+Call `ediff-merge-directories-with-ancestor' with the next four command line
+arguments." nil nil)
(register-definition-prefixes "ediff" '("ediff-"))
@@ -10197,7 +10291,7 @@ 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 `(default-value 'electric-pair-mode)'.
+evaluate `(default-value \\='electric-pair-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -10224,7 +10318,8 @@ 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 `(buffer-local-value 'electric-pair-mode (current-buffer))'.
+evaluate `(buffer-local-value \\='electric-pair-mode
+\(current-buffer))'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -10381,7 +10476,7 @@ Message buffer where you can explain more about the patch.
;;; Generated autoloads from vc/emerge.el
(autoload 'emerge-files "emerge" "\
-Run Emerge on two files.
+Run Emerge on two files FILE-A and FILE-B.
\(fn ARG FILE-A FILE-B FILE-OUT &optional STARTUP-HOOKS QUIT-HOOKS)" t nil)
@@ -10391,7 +10486,7 @@ Run Emerge on two files, giving another file as the ancestor.
\(fn ARG FILE-A FILE-B FILE-ANCESTOR FILE-OUT &optional STARTUP-HOOKS QUIT-HOOKS)" t nil)
(autoload 'emerge-buffers "emerge" "\
-Run Emerge on two buffers.
+Run Emerge on two buffers BUFFER-A and BUFFER-B.
\(fn BUFFER-A BUFFER-B &optional STARTUP-HOOKS QUIT-HOOKS)" t nil)
@@ -10433,6 +10528,40 @@ Emerge two RCS revisions of a file, with another revision as ancestor.
;;;***
+;;;### (autoloads nil "emoji" "international/emoji.el" (0 0 0 0))
+;;; Generated autoloads from international/emoji.el
+
+(autoload 'emoji-insert "emoji" "\
+Choose and insert an emoji glyph.
+If TEXT (interactively, the prefix), use a textual search instead
+of a visual interface.
+
+\(fn &optional TEXT)" t nil)
+
+(autoload 'emoji-recent "emoji" "\
+Choose and insert a recently used emoji glyph." t nil)
+
+(autoload 'emoji-search "emoji" "\
+Choose and insert an emoji glyph by searching for an emoji name." t nil)
+
+(autoload 'emoji-list "emoji" "\
+List emojis and insert the one that's selected.
+The character will be inserted into the buffer that was selected
+when the command was issued." t nil)
+
+(autoload 'emoji-describe "emoji" "\
+Say what the name of the composed grapheme cluster GLYPH is.
+If it's not known, this function returns nil.
+
+Interactively, it will message what the name of the emoji (or
+character) under point is.
+
+\(fn GLYPH &optional INTERACTIVE)" t nil)
+
+(register-definition-prefixes "emoji" '("emoji-"))
+
+;;;***
+
;;;### (autoloads nil "enriched" "textmodes/enriched.el" (0 0 0 0))
;;; Generated autoloads from textmodes/enriched.el
@@ -10495,7 +10624,7 @@ List all keys matched with NAME from the private keyring.
(autoload 'epa-select-keys "epa" "\
Display a user's keyring and ask him to select keys.
-CONTEXT is an epg-context.
+CONTEXT is an `epg-context'.
PROMPT is a string to prompt with.
NAMES is a list of strings to be matched with keys. If it is nil, all
the keys are listed.
@@ -10582,8 +10711,7 @@ For example:
(function-put 'epa-verify-region 'interactive-only 't)
(autoload 'epa-verify-cleartext-in-region "epa" "\
-Verify OpenPGP cleartext signed messages in the current region
-between START and END.
+Verify OpenPGP cleartext signed messages in current region from START to END.
Don't use this command in Lisp programs!
See the reason described in the `epa-verify-region' documentation.
@@ -10651,8 +10779,7 @@ Import keys from the region.
\(fn START END)" t nil)
(autoload 'epa-import-armor-in-region "epa" "\
-Import keys in the OpenPGP armor format in the current region
-between START and END.
+Import keys in the OpenPGP armor format in the current region from START to END.
\(fn START END)" t nil)
@@ -10811,7 +10938,7 @@ 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 `(default-value 'epa-global-mail-mode)'.
+evaluate `(default-value \\='epa-global-mail-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -10877,7 +11004,7 @@ Look at CONFIG and try to expand GROUP.
;;;### (autoloads nil "erc" "erc/erc.el" (0 0 0 0))
;;; Generated autoloads from erc/erc.el
-(push (purecopy '(erc 5 3)) package--builtin-versions)
+(push (purecopy '(erc 5 4 1)) package--builtin-versions)
(autoload 'erc-select-read-args "erc" "\
Prompt the user for values of nick, server, port, and password." nil nil)
@@ -10935,7 +11062,7 @@ first element is the certificate key file name, and the second
element is the certificate file name itself, or t, which means
that `auth-source' will be queried for the key and the
certificate. Authenticating using a TLS client certificate is
-also refered to as \"CertFP\" (Certificate Fingerprint)
+also referred to as \"CertFP\" (Certificate Fingerprint)
authentication by various IRC networks.
Example usage:
@@ -11024,6 +11151,9 @@ Macros in BODY are expanded when the test is defined, not when it
is run. If a macro (possibly with side effects) is to be tested,
it has to be wrapped in `(eval (quote ...))'.
+If NAME is already defined as a test and Emacs is running
+in batch mode, an error is signalled.
+
\(fn NAME () [DOCSTRING] [:expected-result RESULT-TYPE] [:tags \\='(TAG...)] BODY...)" nil t)
(function-put 'ert-deftest 'doc-string-elt '3)
@@ -11056,11 +11186,8 @@ the tests).
Run the tests specified by SELECTOR and display the results in a buffer.
SELECTOR works as described in `ert-select-tests'.
-OUTPUT-BUFFER-NAME and MESSAGE-FN should normally be nil; they
-are used for automated self-tests and specify which buffer to use
-and how to display message.
-\(fn SELECTOR &optional OUTPUT-BUFFER-NAME MESSAGE-FN)" t nil)
+\(fn SELECTOR)" t nil)
(defalias 'ert #'ert-run-tests-interactively)
@@ -11083,6 +11210,22 @@ Kill all test buffers that are still live." t nil)
;;;***
+;;;### (autoloads nil "erts-mode" "progmodes/erts-mode.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from progmodes/erts-mode.el
+
+(autoload 'erts-mode "erts-mode" "\
+Major mode for editing erts (Emacs testing) files.
+This mode mainly provides some font locking.
+
+\\{erts-mode-map}
+
+\(fn)" t nil)
+
+(register-definition-prefixes "erts-mode" '("erts-"))
+
+;;;***
+
;;;### (autoloads nil "esh-arg" "eshell/esh-arg.el" (0 0 0 0))
;;; Generated autoloads from eshell/esh-arg.el
@@ -11175,7 +11318,7 @@ session. Return the buffer selected (or created).
With a nonnumeric prefix arg, create a new session.
-With a numeric prefix arg (as in `C-u 42 M-x eshell RET'), switch
+With a numeric prefix arg (as in `\\[universal-argument] 42 \\[eshell]'), switch
to the session with that number, or create it if it doesn't
already exist.
@@ -11427,7 +11570,7 @@ See documentation of variable `tags-file-name'.
(make-obsolete 'find-tag-regexp 'xref-find-apropos '"25.1")
-(defalias 'pop-tag-mark 'xref-pop-marker-stack)
+(defalias 'pop-tag-mark 'xref-go-back)
(defalias 'next-file 'tags-next-file)
@@ -11508,7 +11651,21 @@ for \\[find-tag] (which see)." t nil)
(autoload 'etags--xref-backend "etags" nil nil nil)
-(register-definition-prefixes "etags" '("default-tags-table-function" "etags-" "file-of-tag" "find-tag-" "goto-tag-location-function" "initialize-new-tags-table" "last-tag" "list-tags-function" "select-tags-table-" "snarf-tag-function" "tag" "verify-tags-table-function" "xref-"))
+(register-definition-prefixes "etags" '("default-tags-table-function" "etags-" "file-of-tag" "find-tag-" "goto-tag-location-function" "initialize-new-tags-table" "last-tag" "list-tags-function" "select-tags-table-" "snarf-tag-function" "tag" "verify-tags-table-function"))
+
+;;;***
+
+;;;### (autoloads nil "etc-authors-mode" "textmodes/etc-authors-mode.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from textmodes/etc-authors-mode.el
+
+(autoload 'etc-authors-mode "etc-authors-mode" "\
+Major mode for viewing \"etc/AUTHORS\" from the Emacs distribution.
+Provides some basic font locking and not much else.
+
+\(fn)" t nil)
+
+(register-definition-prefixes "etc-authors-mode" '("etc-authors-"))
;;;***
@@ -11707,8 +11864,9 @@ see `eudc-inline-expansion-servers'.
Query the directory server, and return the matching responses.
The variable `eudc-inline-query-format' controls how to associate the
individual QUERY-WORDS with directory attribute names.
-After querying the server for the given string, the expansion specified by
-`eudc-inline-expansion-format' is applied to the matches before returning them.inserted in the buffer at point.
+After querying the server for the given string, the expansion
+specified by `eudc-inline-expansion-format' is applied to the
+matches before returning them.inserted in the buffer at point.
Multiple servers can be tried with the same query until one finds a match,
see `eudc-inline-expansion-servers'.
@@ -11889,14 +12047,14 @@ Fetch URL and render the page.
If the input doesn't look like an URL or a domain name, the
word(s) will be searched for via `eww-search-prefix'.
-If called with a prefix ARG, use a new buffer instead of reusing
-the default EWW buffer.
+If NEW-BUFFER is non-nil (interactively, the prefix arg), use a
+new buffer instead of reusing the default EWW buffer.
If BUFFER, the data to be rendered is in that buffer. In that
case, this function doesn't actually fetch URL. BUFFER will be
killed after rendering.
-\(fn URL &optional ARG BUFFER)" t nil)
+\(fn URL &optional NEW-BUFFER BUFFER)" t nil)
(defalias 'browse-web 'eww)
(autoload 'eww-open-file "eww" "\
@@ -11914,6 +12072,8 @@ for the search engine used." t nil)
(autoload 'eww-mode "eww" "\
Mode for browsing the web.
+\\{eww-mode-map}
+
\(fn)" t nil)
(autoload 'eww-browse-url "eww" "\
@@ -11936,6 +12096,11 @@ instead of `browse-url-new-window-flag'.
(autoload 'eww-list-bookmarks "eww" "\
Display the bookmarks." t nil)
+(autoload 'eww-bookmark-jump "eww" "\
+Default bookmark handler for EWW buffers.
+
+\(fn BOOKMARK)" nil nil)
+
(register-definition-prefixes "eww" '("erc--download-directory" "eww-"))
;;;***
@@ -12192,7 +12357,7 @@ Adjust the height of the default face by INC.
INC may be passed as a numeric prefix argument.
The actual adjustment made depends on the final component of the
-key-binding used to invoke the command, with all modifiers removed:
+keybinding used to invoke the command, with all modifiers removed:
+, = Increase the height of the default face by one step
- Decrease the height of the default face by one step
@@ -12290,10 +12455,10 @@ If the optional argument LIST is non-nil, it should be a list of
colors to display. Otherwise, this command computes a list of
colors that the current display can handle. Customize
`list-colors-sort' to change the order in which colors are shown.
-Type `g' or \\[revert-buffer] after customizing `list-colors-sort'
-to redisplay colors in the new order.
+Type \\<help-mode-map>\\[revert-buffer] after customizing `list-colors-sort' to redisplay colors in
+the new order.
-If the optional argument BUFFER-NAME is nil, it defaults to *Colors*.
+If the optional argument BUFFER-NAME is nil, it defaults to \"*Colors*\".
If the optional argument CALLBACK is non-nil, it should be a
function to call each time the user types RET or clicks on a
@@ -12422,8 +12587,9 @@ If `ffap-url-regexp' is not nil, the FILENAME may also be an URL.
With a prefix, this command behaves exactly like `ffap-file-finder'.
If `ffap-require-prefix' is set, the prefix meaning is reversed.
See also the variables `ffap-dired-wildcards', `ffap-newfile-prompt',
-`ffap-url-unwrap-local', `ffap-url-unwrap-remote', and the functions
-`ffap-file-at-point' and `ffap-url-at-point'.
+`ffap-url-unwrap-local', `ffap-url-unwrap-remote',
+`ffap-file-name-with-spaces', and the functions `ffap-file-at-point'
+and `ffap-url-at-point'.
\(fn &optional FILENAME)" t nil)
@@ -12743,7 +12909,7 @@ it finishes, type \\[kill-find].
\(fn DIR ARGS)" t nil)
(autoload 'find-name-dired "find-dired" "\
-Search DIR recursively for files matching the globbing pattern PATTERN,
+Search DIR recursively for files matching the globbing PATTERN,
and run Dired on those files.
PATTERN is a shell wildcard (not an Emacs regexp) and need not be quoted.
The default command run (after changing into DIR) is
@@ -12874,13 +13040,16 @@ Find the Emacs Lisp source of LIBRARY.
Interactively, prompt for LIBRARY using the one at or near point.
+This function searches `find-library-source-path' if non-nil, and
+`load-path' otherwise.
+
\(fn LIBRARY)" t nil)
(autoload 'read-library-name "find-func" "\
Read and return a library name, defaulting to the one near point.
A library name is the filename of an Emacs Lisp library located
-in a directory under `load-path' (or `find-function-source-path',
+in a directory under `load-path' (or `find-library-source-path',
if non-nil)." nil nil)
(autoload 'find-library-other-window "find-func" "\
@@ -12921,10 +13090,6 @@ If FUNCTION is a built-in function, this function normally
attempts to find it in the Emacs C sources; however, if LISP-ONLY
is non-nil, signal an error instead.
-If the file where FUNCTION is defined is not known, then it is
-searched for in `find-function-source-path' if non-nil, otherwise
-in `load-path'.
-
\(fn FUNCTION &optional LISP-ONLY)" nil nil)
(autoload 'find-function "find-func" "\
@@ -12935,8 +13100,6 @@ near point (selected by `function-called-at-point') in a buffer and
places point before the definition.
Set mark before moving, if the buffer already existed.
-The library where FUNCTION is defined is searched for in
-`find-function-source-path', if non-nil, otherwise in `load-path'.
See also `find-function-recenter-line' and `find-function-after-hook'.
\(fn FUNCTION)" t nil)
@@ -12962,9 +13125,6 @@ Finds the library containing the definition of VARIABLE in a buffer and
the point of the definition. The buffer is not selected.
If the variable's definition can't be found in the buffer, return (BUFFER).
-The library where VARIABLE is defined is searched for in FILE or
-`find-function-source-path', if non-nil, otherwise in `load-path'.
-
\(fn VARIABLE &optional FILE)" nil nil)
(autoload 'find-variable "find-func" "\
@@ -12976,8 +13136,6 @@ places point before the definition.
Set mark before moving, if the buffer already existed.
-The library where VARIABLE is defined is searched for in
-`find-function-source-path', if non-nil, otherwise in `load-path'.
See also `find-function-recenter-line' and `find-function-after-hook'.
\(fn VARIABLE)" t nil)
@@ -13003,9 +13161,6 @@ TYPE says what type of definition: nil for a function, `defvar' for a
variable, `defface' for a face. This function does not switch to the
buffer nor display it.
-The library where SYMBOL is defined is searched for in FILE or
-`find-function-source-path', if non-nil, otherwise in `load-path'.
-
\(fn SYMBOL TYPE &optional FILE)" nil nil)
(autoload 'find-face-definition "find-func" "\
@@ -13017,8 +13172,6 @@ places point before the definition.
Set mark before moving, if the buffer already existed.
-The library where FACE is defined is searched for in
-`find-function-source-path', if non-nil, otherwise in `load-path'.
See also `find-function-recenter-line' and `find-function-after-hook'.
\(fn FACE)" t nil)
@@ -13048,7 +13201,7 @@ Find directly the function at point in the other window." t nil)
Find directly the variable at point in the other window." t nil)
(autoload 'find-function-setup-keys "find-func" "\
-Define some key bindings for the find-function family of functions." nil nil)
+Define some key bindings for the `find-function' family of functions." nil nil)
(register-definition-prefixes "find-func" '("find-"))
@@ -13141,7 +13294,7 @@ lines.
;;;### (autoloads nil "flymake" "progmodes/flymake.el" (0 0 0 0))
;;; Generated autoloads from progmodes/flymake.el
-(push (purecopy '(flymake 1 1 1)) package--builtin-versions)
+(push (purecopy '(flymake 1 2 1)) package--builtin-versions)
(autoload 'flymake-log "flymake" "\
Log, at level LEVEL, the message MSG formatted with ARGS.
@@ -13153,23 +13306,32 @@ generated it.
\(fn LEVEL MSG &rest ARGS)" nil t)
(autoload 'flymake-make-diagnostic "flymake" "\
-Make a Flymake diagnostic for BUFFER's region from BEG to END.
+Make a Flymake diagnostic for LOCUS's region from BEG to END.
+LOCUS is a buffer object or a string designating a file name.
+
TYPE is a diagnostic symbol and TEXT is string describing the
problem detected in this region. DATA is any object that the
caller wishes to attach to the created diagnostic for later
-retrieval.
+retrieval with `flymake-diagnostic-data'.
+
+If LOCUS is a buffer BEG and END should be buffer positions
+inside it. If LOCUS designates a file, BEG and END should be a
+cons (LINE . COL) indicating a file position. In this second
+case, END may be omitted in which case the region is computed
+using `flymake-diag-region' if the diagnostic is appended to an
+actual buffer.
OVERLAY-PROPERTIES is an alist of properties attached to the
created diagnostic, overriding the default properties and any
-properties of `flymake-overlay-control' of the diagnostic's
-type.
+properties listed in the `flymake-overlay-control' property of
+the diagnostic's type symbol.
-\(fn BUFFER BEG END TYPE TEXT &optional DATA OVERLAY-PROPERTIES)" nil nil)
+\(fn LOCUS BEG END TYPE TEXT &optional DATA OVERLAY-PROPERTIES)" nil nil)
(autoload 'flymake-diagnostics "flymake" "\
Get Flymake diagnostics in region determined by BEG and END.
-If neither BEG or END is supplied, use the whole buffer,
+If neither BEG or END is supplied, use whole accessible buffer,
otherwise if BEG is non-nil and END is nil, consider only
diagnostics at BEG.
@@ -13646,7 +13808,7 @@ Variables controlling indentation style and extra features:
`fortran-comment-line-extra-indent'
Amount of extra indentation for text in full-line comments (default 0).
`fortran-comment-indent-style'
- How to indent the text in full-line comments. Allowed values are:
+ How to indent the text in full-line comments. Allowed values are:
nil don't change the indentation
`fixed' indent to `fortran-comment-line-extra-indent' beyond the
value of either
@@ -13892,7 +14054,8 @@ FORCE-ONSCREEN can be:
- a list (LEFT TOP WIDTH HEIGHT), describing the workarea.
It must return non-nil to force the frame onscreen, nil otherwise.
-CLEANUP-FRAMES allows \"cleaning up\" the frame list after restoring a frameset:
+CLEANUP-FRAMES allows \"cleaning up\" the frame list after
+restoring a frameset:
t Delete all frames that were not created or restored upon.
nil Keep all frames.
FUNC A function called with two arguments:
@@ -13977,7 +14140,7 @@ 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 `(default-value 'gdb-enable-debug)'.
+evaluate `(default-value \\='gdb-enable-debug)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -13993,7 +14156,7 @@ becomes the initial working directory and source-file directory
for your debugger.
If COMMAND-LINE requests that gdb attaches to a process PID, gdb
will run in *gud-PID*, otherwise it will run in *gud*; in these
-cases the initial working directory is the default-directory of
+cases the initial working directory is the `default-directory' of
the buffer in which this command was invoked.
COMMAND-LINE should include \"-i=mi\" to use gdb's MI text interface.
@@ -14319,7 +14482,7 @@ Allow Gnus to be an offline newsreader.
The gnus-agentize function is now called internally by gnus when
gnus-agent is set. If you wish to avoid calling gnus-agentize,
-customize gnus-agent to nil.
+customize `gnus-agent' to nil.
This will modify the `gnus-setup-news-hook', and
`message-send-mail-real-function' variables, and install the Gnus agent
@@ -14384,7 +14547,7 @@ CLEAN is obsolete and ignored.
(autoload 'gnus-article-prepare-display "gnus-art" "\
Make the current buffer look like a nice article." nil nil)
-(register-definition-prefixes "gnus-art" '("article-" "gnus-"))
+(register-definition-prefixes "gnus-art" '(":keymap" "article-" "gnus-"))
;;;***
@@ -14560,7 +14723,7 @@ Checking delayed messages is skipped if optional arg NO-CHECK is non-nil.
;;; Generated autoloads from gnus/gnus-dired.el
(autoload 'turn-on-gnus-dired-mode "gnus-dired" "\
-Convenience method to turn on gnus-dired-mode." t nil)
+Convenience method to turn on `gnus-dired-mode'." t nil)
(register-definition-prefixes "gnus-dired" '("gnus-dired-"))
@@ -14594,7 +14757,8 @@ Reminder user if there are unsent drafts." t nil)
;;; Generated autoloads from gnus/gnus-fun.el
(autoload 'gnus--random-face-with-type "gnus-fun" "\
-Return file from DIR with extension EXT, omitting matches of OMIT, processed by FUN.
+Return file from DIR with extension EXT.
+Omit matches of OMIT, and process them by FUN.
\(fn DIR EXT OMIT FUN)" nil nil)
@@ -14691,7 +14855,7 @@ The arguments have the same meaning as those of
\(fn IDS &optional WINDOW-CONF)" t nil)
-(register-definition-prefixes "gnus-group" '("gnus-"))
+(register-definition-prefixes "gnus-group" '(":keymap" "gnus-"))
;;;***
@@ -14823,7 +14987,7 @@ match any of the group-specified splitting rules. See
\(fn &optional AUTO-UPDATE CATCH-ALL)" t nil)
(autoload 'gnus-group-split-update "gnus-mlspl" "\
-Computes nnmail-split-fancy from group params and CATCH-ALL.
+Computes `nnmail-split-fancy' from group params and CATCH-ALL.
It does this by calling (gnus-group-split-fancy nil nil CATCH-ALL).
If CATCH-ALL is nil, `gnus-group-split-default-catch-all-group' is used
@@ -14918,7 +15082,7 @@ Like `message-reply'.
(define-mail-user-agent 'gnus-user-agent 'gnus-msg-mail 'message-send-and-exit 'message-kill-buffer 'message-send-hook)
-(register-definition-prefixes "gnus-msg" '("gnus-"))
+(register-definition-prefixes "gnus-msg" '(":prefix" "gnus-"))
;;;***
@@ -15132,7 +15296,7 @@ BOOKMARK is a bookmark name or a bookmark record.
\(fn BOOKMARK)" nil nil)
-(register-definition-prefixes "gnus-sum" '("gnus-"))
+(register-definition-prefixes "gnus-sum" '(":keymap" "gnus-"))
;;;***
@@ -15274,8 +15438,11 @@ or call the function `global-goto-address-mode'.")
(autoload 'global-goto-address-mode "goto-addr" "\
Toggle Goto-Address mode in all buffers.
With prefix ARG, enable Global Goto-Address mode if ARG is positive;
-otherwise, disable it. If called from Lisp, enable the mode if ARG
-is omitted or nil.
+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.
Goto-Address mode is enabled in all buffers where
`goto-addr-mode--turn-on' would do it.
@@ -15401,7 +15568,7 @@ This variable's value takes effect when `grep-compute-defaults' is called.")
History list for grep.")
(defvar grep-find-history nil "\
-History list for grep-find.")
+History list for `grep-find'.")
(autoload 'grep-process-setup "grep" "\
Setup compilation variables and buffer for `grep'.
@@ -15540,7 +15707,7 @@ becomes the initial working directory and source-file directory
for your debugger.
If COMMAND-LINE requests that gdb attaches to a process PID, gdb
will run in *gud-PID*, otherwise it will run in *gud*; in these
-cases the initial working directory is the default-directory of
+cases the initial working directory is the `default-directory' of
the buffer in which this command was invoked.
\(fn COMMAND-LINE)" t nil)
@@ -15570,9 +15737,14 @@ directories if your program contains sources from more than one directory.
\(fn COMMAND-LINE)" t nil)
(autoload 'perldb "gud" "\
-Run perldb on program FILE in buffer *gud-FILE*.
-The directory containing FILE becomes the initial working directory
-and source-file directory for your debugger.
+Debug a perl program with gud.
+Interactively, this will prompt you for a command line.
+
+Noninteractively, COMMAND-LINE should be on the form
+\"perl -d perl-file.pl\".
+
+The directory containing the perl program becomes the initial
+working directory and source-file directory for your debugger.
\(fn COMMAND-LINE)" t nil)
@@ -15639,7 +15811,7 @@ 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 `(default-value 'gud-tooltip-mode)'.
+evaluate `(default-value \\='gud-tooltip-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -15764,7 +15936,7 @@ binding mode.
;;; Generated autoloads from play/handwrite.el
(autoload 'handwrite "handwrite" "\
-Turns the buffer into a \"handwritten\" document.
+Turn the buffer into a \"handwritten\" document.
The functions `handwrite-10pt', `handwrite-11pt', `handwrite-12pt'
and `handwrite-13pt' set up for various sizes of output.
@@ -15801,9 +15973,9 @@ second since 1970-01-01 00:00:00 GMT.
Repent before ring 31 moves." t nil)
(autoload 'hanoi-unix-64 "hanoi" "\
-Like hanoi-unix, but pretend to have a 64-bit clock.
+Like `hanoi-unix', but pretend to have a 64-bit clock.
This is, necessarily (as of Emacs 20.3), a crock. When the
-current-time interface is made s2G-compliant, hanoi.el will need
+`current-time' interface is made s2G-compliant, hanoi.el will need
to be updated." t nil)
(register-definition-prefixes "hanoi" '("hanoi-"))
@@ -15989,13 +16161,16 @@ different regions. With numeric argument ARG, behaves like
(autoload 'describe-function "help-fns" "\
Display the full documentation of FUNCTION (a symbol).
-When called from lisp, FUNCTION may also be a function object.
+When called from Lisp, FUNCTION may also be a function object.
+
+See the `help-enable-symbol-autoload' variable for special
+handling of autoloaded functions.
\(fn FUNCTION)" t nil)
(autoload 'describe-command "help-fns" "\
Display the full documentation of COMMAND (a symbol).
-When called from lisp, COMMAND may also be a function object.
+When called from Lisp, COMMAND may also be a function object.
\(fn COMMAND)" t nil)
@@ -16148,6 +16323,11 @@ gives the window that lists the options.")
;;;### (autoloads nil "help-mode" "help-mode.el" (0 0 0 0))
;;; Generated autoloads from help-mode.el
+(autoload 'help-mode--add-function-link "help-mode" "\
+
+
+\(fn STR FUN)" nil nil)
+
(autoload 'help-mode "help-mode" "\
Major mode for viewing help text and navigating references in it.
Entry to this mode runs the normal hook `help-mode-hook'.
@@ -16437,9 +16617,9 @@ which can be called interactively, are:
When hi-lock is started and if the mode is not excluded or patterns
rejected, the beginning of the buffer is searched for lines of the
form:
- Hi-lock: FOO
+ Hi-lock: (FOO ...)
-where FOO is a list of patterns. The patterns must start before
+where (FOO ...) is a list of patterns. The patterns must start before
position (number of characters into buffer)
`hi-lock-file-patterns-range'. Patterns will be read until
Hi-lock: end is found. A mode is excluded if it's in the list
@@ -16462,8 +16642,11 @@ or call the function `global-hi-lock-mode'.")
(autoload 'global-hi-lock-mode "hi-lock" "\
Toggle Hi-Lock mode in all buffers.
With prefix ARG, enable Global Hi-Lock mode if ARG is positive;
-otherwise, disable it. If called from Lisp, enable the mode if ARG is
-omitted or nil.
+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.
Hi-Lock mode is enabled in all buffers where
`turn-on-hi-lock-if-enabled' would do it.
@@ -16860,14 +17043,17 @@ or call the function `global-highlight-changes-mode'.")
(autoload 'global-highlight-changes-mode "hilit-chg" "\
Toggle Highlight-Changes mode in all buffers.
With prefix ARG, enable Global Highlight-Changes mode if ARG is
-positive; otherwise, disable it. If called from Lisp, enable the mode if
-ARG is omitted or nil.
+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.
Highlight-Changes mode is enabled in all buffers where
`highlight-changes-mode-turn-on' would do it.
-See `highlight-changes-mode' for more information on
-Highlight-Changes mode.
+See `highlight-changes-mode' for more information on Highlight-Changes
+mode.
\(fn &optional ARG)" t nil)
@@ -16962,7 +17148,7 @@ 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 `(default-value 'global-hl-line-mode)'.
+evaluate `(default-value \\='global-hl-line-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -17383,7 +17569,7 @@ 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 `(default-value 'fido-mode)'.
+evaluate `(default-value \\='fido-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -17415,7 +17601,7 @@ 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 `(default-value 'icomplete-mode)'.
+evaluate `(default-value \\='icomplete-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -17457,22 +17643,55 @@ 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 `(default-value 'icomplete-vertical-mode)'.
+evaluate `(default-value \\='icomplete-vertical-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
+If none of these modes are on, turn on `icomplete-mode'.
+
As many completion candidates as possible are displayed, depending on
the value of `max-mini-window-height', and the way the mini-window is
resized depends on `resize-mini-windows'.
\(fn &optional ARG)" t nil)
+
+(defvar fido-vertical-mode nil "\
+Non-nil if Fido-Vertical mode is enabled.
+See the `fido-vertical-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 `fido-vertical-mode'.")
+
+(custom-autoload 'fido-vertical-mode "icomplete" nil)
+
+(autoload 'fido-vertical-mode "icomplete" "\
+Toggle vertical candidate display in `fido-mode'.
+When turning on, if non-vertical `fido-mode' is off, turn it on.
+If it's on, just add the vertical display.
+
+This is a minor mode. If called interactively, toggle the
+`Fido-Vertical 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 `(default-value \\='fido-vertical-mode)'.
+
+The mode's hook is called both when the mode is enabled and when it is
+disabled.
+
+\(fn &optional ARG)" t nil)
(when (locate-library "obsolete/iswitchb")
(autoload 'iswitchb-mode "iswitchb" "Toggle Iswitchb mode." t)
(make-obsolete 'iswitchb-mode
"use `icomplete-mode' or `ido-mode' instead." "24.4"))
-(register-definition-prefixes "icomplete" '("fido-vertical-mode" "icomplete-"))
+(register-definition-prefixes "icomplete" '("icomplete-"))
;;;***
@@ -17682,7 +17901,7 @@ The main features of this mode are
Info documentation for this package is available. Use
\\[idlwave-info] to display (complain to your sysadmin if that does
not work). For Postscript, PDF, and HTML versions of the
- documentation, check IDLWAVE's homepage at URL
+ documentation, check IDLWAVE's website at URL
`https://github.com/jdtsmith/idlwave'.
IDLWAVE has customize support - see the group `idlwave'.
@@ -17904,12 +18123,12 @@ The directory is selected interactively by typing a substring.
For details of keybindings, see `ido-find-file'." t nil)
(autoload 'ido-dired-other-window "ido" "\
-\"Edit\" a directory. Like `ido-dired' but selects in another window.
+\"Edit\" a directory. Like `ido-dired' but select in another window.
The directory is selected interactively by typing a substring.
For details of keybindings, see `ido-find-file'." t nil)
(autoload 'ido-dired-other-frame "ido" "\
-\"Edit\" a directory. Like `ido-dired' but makes a new frame.
+\"Edit\" a directory. Like `ido-dired' but make a new frame.
The directory is selected interactively by typing a substring.
For details of keybindings, see `ido-find-file'." t nil)
@@ -18133,7 +18352,11 @@ specifying the X and Y positions and WIDTH and HEIGHT of image area
to insert. A float value 0.0 - 1.0 means relative to the width or
height of the image; integer values are taken as pixel values.
-\(fn IMAGE &optional STRING AREA SLICE)" nil nil)
+Normally `isearch' is able to search for STRING in the buffer
+even if it's hidden behind a displayed image. If INHIBIT-ISEARCH
+is non-nil, this is inhibited.
+
+\(fn IMAGE &optional STRING AREA SLICE INHIBIT-ISEARCH)" nil nil)
(autoload 'insert-sliced-image "image" "\
Insert IMAGE into current buffer at point.
@@ -18202,6 +18425,8 @@ Example:
(function-put 'defimage 'doc-string-elt '3)
+(function-put 'defimage 'lisp-indent-function 'defun)
+
(autoload 'imagemagick-register-types "image" "\
Register file types that can be handled by ImageMagick.
This function is called at startup, after loading the init file.
@@ -18214,6 +18439,9 @@ recognizes these files as having image type `imagemagick'.
If Emacs is compiled without ImageMagick support, this does nothing." nil nil)
+(autoload 'image-at-point-p "image" "\
+Return non-nil if there is an image at point." nil nil)
+
(register-definition-prefixes "image" '("find-image--cache" "image" "unknown-image-type"))
;;;***
@@ -18231,7 +18459,7 @@ If Emacs is compiled without ImageMagick support, this does nothing." nil nil)
(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.
+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
@@ -18244,12 +18472,12 @@ Open directory DIR and create a default window configuration.
Convenience command that:
- - Opens dired in folder DIR
+ - Opens Dired in folder DIR
- Splits windows in most useful (?) way
- - Set `truncate-lines' to t
+ - Sets `truncate-lines' to t
After the command has finished, you would typically mark some
-image files in dired and type
+image files in Dired and type
\\[image-dired-display-thumbs] (`image-dired-display-thumbs').
If called with prefix argument ARG, skip splitting of windows.
@@ -18267,7 +18495,7 @@ point (this is useful if you have marked some files but want to show
another one).
Recommended usage is to split the current frame horizontally so that
-you have the dired buffer in the left window and the
+you have the Dired buffer in the left window and the
`image-dired-thumbnail-buffer' buffer in the right window.
With optional argument APPEND, append thumbnail to thumbnail buffer
@@ -18283,19 +18511,21 @@ thumbnail buffer to be selected.
\(fn &optional ARG APPEND DO-NOT-POP)" t nil)
(autoload 'image-dired-show-all-from-dir "image-dired" "\
-Make a preview buffer for all images in DIR and display it.
-If the number of files in DIR matching `image-file-name-regexp'
-exceeds `image-dired-show-all-from-dir-max-files', a warning will be
-displayed.
+Make a thumbnail buffer for all images in DIR and display it.
+Any file matching `image-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.
\(fn DIR)" t nil)
(defalias 'image-dired 'image-dired-show-all-from-dir)
-(define-obsolete-function-alias 'tumme 'image-dired "24.4")
-
(autoload 'image-dired-tag-files "image-dired" "\
-Tag marked file(s) in dired. With prefix ARG, tag file at point.
+Tag marked file(s) in Dired. With prefix ARG, tag file at point.
\(fn ARG)" t nil)
@@ -18309,9 +18539,9 @@ With prefix argument ARG, remove tag from file at point.
Jump to thumbnail buffer." t nil)
(autoload 'image-dired-minor-mode "image-dired" "\
-Setup easy-to-use keybindings for the commands to be used in dired 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-x-line'.
+`image-dired-dired-next-line' and `image-dired-dired-previous-line'.
This is a minor mode. If called interactively, toggle the
`Image-Dired minor mode' mode. If the prefix argument is positive,
@@ -18329,8 +18559,6 @@ disabled.
\(fn &optional ARG)" t nil)
-(define-obsolete-function-alias 'image-dired-setup-dired-keybindings 'image-dired-minor-mode "26.1")
-
(autoload 'image-dired-display-thumbs-append "image-dired" "\
Append thumbnails to `image-dired-thumbnail-buffer'." t nil)
@@ -18348,7 +18576,7 @@ With prefix argument ARG, display image in its original size.
\(fn &optional ARG)" t nil)
(autoload 'image-dired-dired-comment-files "image-dired" "\
-Add comment to current or marked files in dired." t nil)
+Add comment to current or marked files in Dired." t nil)
(autoload 'image-dired-mark-tagged-files "image-dired" "\
Use regexp to mark files with matching tag.
@@ -18356,13 +18584,22 @@ 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
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." t nil)
+matching tag will be marked in the Dired buffer." t nil)
(autoload 'image-dired-dired-edit-comment-and-tags "image-dired" "\
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 nil)
+(autoload 'image-dired-bookmark-jump "image-dired" "\
+Default bookmark handler for Image-Dired buffers.
+
+\(fn BOOKMARK)" nil nil)
+
+(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-"))
;;;***
@@ -18370,7 +18607,7 @@ easy-to-use form." t nil)
;;;### (autoloads nil "image-file" "image-file.el" (0 0 0 0))
;;; Generated autoloads from image-file.el
-(defvar image-file-name-extensions (purecopy '("png" "jpeg" "jpg" "gif" "tiff" "tif" "xbm" "xpm" "pbm" "pgm" "ppm" "pnm" "svg")) "\
+(defvar image-file-name-extensions (purecopy '("png" "jpeg" "jpg" "gif" "tiff" "tif" "xbm" "xpm" "pbm" "pgm" "ppm" "pnm" "svg" "webp")) "\
A list of image-file filename extensions.
Filenames having one of these extensions are considered image files,
in addition to those matching `image-file-name-regexps'.
@@ -18427,7 +18664,7 @@ 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 `(default-value 'auto-image-file-mode)'.
+evaluate `(default-value \\='auto-image-file-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -18914,7 +19151,7 @@ system." t nil)
(autoload 'info-lookup-symbol "info-look" "\
Display the definition of SYMBOL, as found in the relevant manual.
When this command is called interactively, it reads SYMBOL from the
-minibuffer. In the minibuffer, use M-n to yank the default argument
+minibuffer. In the minibuffer, use \\<minibuffer-local-completion-map>\\[next-history-element] to yank the default argument
value into the minibuffer so you can edit it. The default symbol is the
one found at point.
@@ -18926,7 +19163,7 @@ With prefix arg MODE a query for the symbol help mode is offered.
(autoload 'info-lookup-file "info-look" "\
Display the documentation of a file.
When this command is called interactively, it reads FILE from the minibuffer.
-In the minibuffer, use M-n to yank the default file name
+In the minibuffer, use \\<minibuffer-local-completion-map>\\[next-history-element] to yank the default file name
into the minibuffer so you can edit it.
The default file name is the one found at point.
@@ -19061,7 +19298,7 @@ Check current buffer for validity as an Info file.
Check that every node pointer points to an existing node." t nil)
(autoload 'batch-info-validate "informat" "\
-Runs `Info-validate' on the files remaining on the command line.
+Run `Info-validate' on the files remaining on the command line.
Must be used only with -batch, and kills Emacs on completion.
Each file will be processed even if an error occurred previously.
For example, invoke \"emacs -batch -f batch-info-validate $info/ ~/*.info\"" nil nil)
@@ -19317,24 +19554,24 @@ Display a list of the options available when a misspelling is encountered.
Selections are:
-DIGIT: Replace the word with a digit offered in the *Choices* buffer.
-SPC: Accept word this time.
-`i': Accept word and insert into private dictionary.
-`a': Accept word for this session.
-`A': Accept word and place in `buffer-local dictionary'.
-`r': Replace word with typed-in value. Rechecked.
-`R': Replace word with typed-in value. Query-replaced in buffer. Rechecked.
-`?': Show these commands.
-`x': Exit spelling buffer. Move cursor to original point.
-`X': Exit spelling buffer. Leaves cursor at the current point, and permits
+\\`0'..\\`9' Replace the word with a digit offered in the *Choices* buffer.
+\\`SPC' Accept word this time.
+\\`i' Accept word and insert into private dictionary.
+\\`a' Accept word for this session.
+\\`A' Accept word and place in `buffer-local dictionary'.
+\\`r' Replace word with typed-in value. Rechecked.
+\\`R' Replace word with typed-in value. Query-replaced in buffer. Rechecked.
+\\`?' Show these commands.
+\\`x' Exit spelling buffer. Move cursor to original point.
+\\`X' Exit spelling buffer. Leaves cursor at the current point, and permits
the aborted check to be completed later.
-`q': Quit spelling session (Kills ispell process).
-`l': Look up typed-in replacement in alternate dictionary. Wildcards okay.
-`u': Like `i', but the word is lower-cased first.
-`m': Place typed-in value in personal dictionary, then recheck current word.
-`C-l': Redraw screen.
-`C-r': Recursive edit.
-`C-z': Suspend Emacs or iconify frame." nil nil)
+\\`q' Quit spelling session (Kills ispell process).
+\\`l' Look up typed-in replacement in alternate dictionary. Wildcards okay.
+\\`u' Like \\`i', but the word is lower-cased first.
+\\`m' Place typed-in value in personal dictionary, then recheck current word.
+\\`C-l' Redraw screen.
+\\`C-r' Recursive edit.
+\\`C-z' Suspend Emacs or iconify frame." nil nil)
(autoload 'ispell-kill-ispell "ispell" "\
Kill current Ispell process (so that you may start a fresh one).
@@ -19441,8 +19678,8 @@ Don't check spelling of message headers except the Subject field.
Don't check included messages.
To abort spell checking of a message region and send the message anyway,
-use the `x' command. (Any subsequent regions will be checked.)
-The `X' command aborts sending the message so that you can edit the buffer.
+use the \\`x' command. (Any subsequent regions will be checked.)
+The \\`X' command aborts sending the message so that you can edit the buffer.
To spell-check whenever a message is sent, include the appropriate lines
in your init file:
@@ -19602,7 +19839,7 @@ one of the aforementioned options instead of using this mode.
(dolist (name (list "node" "nodejs" "gjs" "rhino")) (add-to-list 'interpreter-mode-alist (cons (purecopy name) 'js-mode)))
-(register-definition-prefixes "js" '("js-" "with-js"))
+(register-definition-prefixes "js" '("js-"))
;;;***
@@ -19673,7 +19910,7 @@ keys are bound.
`S-cursor' Bind shifted keypad keys to the shifted cursor movement keys.
`cursor' Bind keypad keys to the cursor movement keys.
`numeric' Plain numeric keypad, i.e. 0 .. 9 and . (or DECIMAL arg)
- `none' Removes all bindings for keypad keys in function-key-map;
+ `none' Removes all bindings for keypad keys in `function-key-map';
this enables any user-defined bindings for the keypad keys
in the global and local keymaps.
@@ -19860,7 +20097,7 @@ Create lambda form for macro bound to symbol or key.
;;;;;; 0 0))
;;; Generated autoloads from language/korea-util.el
-(defvar default-korean-keyboard (purecopy (if (string-match "3" (or (getenv "HANGUL_KEYBOARD_TYPE") "")) "3" "")) "\
+(defvar default-korean-keyboard (purecopy (if (string-search "3" (or (getenv "HANGUL_KEYBOARD_TYPE") "")) "3" "")) "\
The kind of Korean keyboard for Korean (Hangul) input method.
\"\" for 2, \"3\" for 3, and \"3f\" for 3f.")
@@ -19992,7 +20229,7 @@ use either \\[customize] or the function `latin1-display'.")
;;; Generated autoloads from progmodes/ld-script.el
(autoload 'ld-script-mode "ld-script" "\
-A major mode to edit GNU ld script files
+A major mode to edit GNU ld script files.
\(fn)" t nil)
@@ -20069,7 +20306,7 @@ essentially expands to
.site.contents))
If you nest `let-alist' invocations, the inner one can't access
-the variables of the outer one. You can, however, access alists
+the variables of the outer one. You can, however, access alists
inside the original alist by using dots inside the symbol, as
displayed in the example above.
@@ -20139,8 +20376,11 @@ or call the function `global-linum-mode'.")
(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, enable the mode if ARG is
-omitted or nil.
+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.
@@ -20447,11 +20687,16 @@ use this command, and then save the file.
(autoload 'kbd-macro-query "macros" "\
Query user during kbd macro execution.
- With prefix argument, enters recursive edit, reading keyboard
-commands even within a kbd macro. You can give different commands
-each time the macro executes.
- Without prefix argument, asks whether to continue running the macro.
+
+With prefix argument FLAG, enter recursive edit, reading
+keyboard commands even within a kbd macro. You can give
+different commands each time the macro executes.
+
+Without prefix argument, ask whether to continue running the
+macro.
+
Your options are: \\<query-replace-map>
+
\\[act] Finish this iteration normally and continue with the next.
\\[skip] Skip the rest of this iteration, and start the next.
\\[exit] Stop the macro entirely right now.
@@ -20534,7 +20779,10 @@ This function is primarily meant for when you're displaying the
result to the user: Many prettifications are applied to the
result returned. If you want to decode an address for further
non-display use, you should probably use
-`mail-header-parse-address' instead.
+`mail-header-parse-address' instead. Also see
+`mail-header-parse-address-lax' for a function that's less strict
+than `mail-header-parse-address', but does less post-processing
+to the results.
\(fn ADDRESS &optional ALL)" nil nil)
@@ -20696,7 +20944,7 @@ 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 `(default-value 'mail-abbrevs-mode)'.
+evaluate `(default-value \\='mail-abbrevs-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -20788,6 +21036,12 @@ current header, calls `mail-complete-function' and passes prefix ARG if any.
;;;### (autoloads nil "mailcap" "net/mailcap.el" (0 0 0 0))
;;; Generated autoloads from net/mailcap.el
+(autoload 'mailcap-mime-type-to-extension "mailcap" "\
+Return a file name extension based on a MIME-TYPE.
+For instance, `image/png' will result in `png'.
+
+\(fn MIME-TYPE)" nil nil)
+
(register-definition-prefixes "mailcap" '("mailcap-"))
;;;***
@@ -21057,7 +21311,7 @@ Default bookmark handler for Man buffers.
;;;### (autoloads nil "map" "emacs-lisp/map.el" (0 0 0 0))
;;; Generated autoloads from emacs-lisp/map.el
-(push (purecopy '(map 3 0)) package--builtin-versions)
+(push (purecopy '(map 3 2 1)) package--builtin-versions)
(register-definition-prefixes "map" '("map-"))
@@ -21124,7 +21378,7 @@ 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 `(default-value 'minibuffer-depth-indicate-mode)'.
+evaluate `(default-value \\='minibuffer-depth-indicate-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -21525,7 +21779,7 @@ perform the operation on all messages in that region.
\(fn)" t nil)
-(register-definition-prefixes "mh-folder" '("mh-"))
+(register-definition-prefixes "mh-folder" '(":keymap" "mh-"))
;;;***
@@ -21561,7 +21815,7 @@ perform the operation on all messages in that region.
;;;### (autoloads nil "mh-letter" "mh-e/mh-letter.el" (0 0 0 0))
;;; Generated autoloads from mh-e/mh-letter.el
-(register-definition-prefixes "mh-letter" '("mh-"))
+(register-definition-prefixes "mh-letter" '(":keymap" "mh-"))
;;;***
@@ -21596,7 +21850,7 @@ perform the operation on all messages in that region.
;;;### (autoloads nil "mh-search" "mh-e/mh-search.el" (0 0 0 0))
;;; Generated autoloads from mh-e/mh-search.el
-(register-definition-prefixes "mh-search" '("mh-"))
+(register-definition-prefixes "mh-search" '(":keymap" "mh-"))
;;;***
@@ -21610,14 +21864,14 @@ perform the operation on all messages in that region.
;;;### (autoloads nil "mh-show" "mh-e/mh-show.el" (0 0 0 0))
;;; Generated autoloads from mh-e/mh-show.el
-(register-definition-prefixes "mh-show" '("mh-"))
+(register-definition-prefixes "mh-show" '(":keymap" "mh-"))
;;;***
;;;### (autoloads nil "mh-speed" "mh-e/mh-speed.el" (0 0 0 0))
;;; Generated autoloads from mh-e/mh-speed.el
-(register-definition-prefixes "mh-speed" '("mh-"))
+(register-definition-prefixes "mh-speed" '(":keymap" "mh-"))
;;;***
@@ -21692,7 +21946,7 @@ 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 `(default-value 'midnight-mode)'.
+evaluate `(default-value \\='midnight-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -21748,7 +22002,7 @@ 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 `(default-value 'minibuffer-electric-default-mode)'.
+evaluate `(default-value \\='minibuffer-electric-default-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -22080,6 +22334,8 @@ specifies how the attachment is intended to be displayed. It can
be either \"inline\" (displayed automatically within the message
body) or \"attachment\" (separate from the body).
+Also see the `mml-attach-file-at-the-end' variable.
+
If given a prefix interactively, no prompting will be done for
the TYPE, DESCRIPTION or DISPOSITION values. Instead defaults
will be computed and used.
@@ -22332,7 +22588,7 @@ 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 `(default-value 'msb-mode)'.
+evaluate `(default-value \\='msb-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -22479,7 +22735,7 @@ The default is 20. If LIMIT is negative, do not limit the listing.
\(fn &optional LIMIT)" t nil)
-(register-definition-prefixes "mule-diag" '("charset-history" "describe-font-internal" "insert-section" "list-" "print-" "sort-listed-character-sets"))
+(register-definition-prefixes "mule-diag" '("charset-history" "describe-font-internal" "insert-section" "list-" "mule--kbd-at" "print-" "sort-listed-character-sets"))
;;;***
@@ -22495,10 +22751,15 @@ Embed OBJ (string or character) at index IDX of STRING.
(autoload 'truncate-string-to-width "mule-util" "\
Truncate string STR to end at column END-COLUMN.
The optional 3rd arg START-COLUMN, if non-nil, specifies the starting
-column; that means to return the characters occupying columns
-START-COLUMN ... END-COLUMN of STR. Both END-COLUMN and START-COLUMN
-are specified in terms of character display width in the current
-buffer; see also `char-width'.
+column (default: zero); that means to return the characters occupying
+columns START-COLUMN ... END-COLUMN of STR. Both END-COLUMN and
+START-COLUMN are specified in terms of character display width in the
+current buffer; see `char-width'.
+
+Since character composition on display can produce glyphs whose
+width is smaller than the sum of `char-width' values of the
+composed characters, this function can produce inaccurate results
+when used in such cases.
The optional 4th arg PADDING, if non-nil, specifies a padding
character (which should have a display width of 1) to add at the end
@@ -22603,7 +22864,9 @@ QUALITY can be:
`approximate', in which case we may cut some corners to avoid
excessive work.
`exact', in which case we may end up re-(en/de)coding a large
- part of the file/buffer, this can be expensive and slow.
+ part of the file/buffer, this can be expensive and slow. (It
+ is an error to request the `exact' method when the buffer's
+ EOL format is not yet decided.)
nil, in which case we may return nil rather than an approximation.
\(fn BYTE &optional QUALITY CODING-SYSTEM)" nil nil)
@@ -22617,7 +22880,9 @@ QUALITY can be:
`approximate', in which case we may cut some corners to avoid
excessive work.
`exact', in which case we may end up re-(en/de)coding a large
- part of the file/buffer, this can be expensive and slow.
+ part of the file/buffer, this can be expensive and slow. (It
+ is an error to request the `exact' method when the buffer's
+ EOL format is not yet decided.)
nil, in which case we may return nil rather than an approximation.
\(fn POSITION &optional QUALITY CODING-SYSTEM)" nil nil)
@@ -22629,13 +22894,13 @@ QUALITY can be:
;;;### (autoloads nil "mwheel" "mwheel.el" (0 0 0 0))
;;; Generated autoloads from mwheel.el
-(defcustom mouse-wheel-mode t "\
+(defvar mouse-wheel-mode t "\
Non-nil if Mouse-Wheel mode is enabled.
See the `mouse-wheel-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 `mouse-wheel-mode'." :set #'custom-set-minor-mode :initialize 'custom-initialize-delay :type 'boolean :group 'mouse)
+or call the function `mouse-wheel-mode'.")
(custom-autoload 'mouse-wheel-mode "mwheel" nil)
@@ -22651,7 +22916,7 @@ 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 `(default-value 'mouse-wheel-mode)'.
+evaluate `(default-value \\='mouse-wheel-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -23300,8 +23565,9 @@ closing requests for requests that are used in matched pairs.
(autoload 'nxml-mode "nxml-mode" "\
Major mode for editing XML.
-
+\\<nxml-mode-map>
\\[nxml-finish-element] finishes the current element by inserting an end-tag.
+
C-c C-i closes a start-tag with `>' and then inserts a balancing end-tag
leaving point between the start-tag and end-tag.
\\[nxml-balanced-close-start-tag-block] is similar but for block rather than inline elements:
@@ -23398,32 +23664,10 @@ Many aspects this mode can be customized using
;;;***
-;;;### (autoloads nil "ob-J" "org/ob-J.el" (0 0 0 0))
-;;; Generated autoloads from org/ob-J.el
-
-(register-definition-prefixes "ob-J" '("obj-" "org-babel-"))
-
-;;;***
-
;;;### (autoloads nil "ob-R" "org/ob-R.el" (0 0 0 0))
;;; Generated autoloads from org/ob-R.el
-(register-definition-prefixes "ob-R" '("ob-R-" "org-babel-"))
-
-;;;***
-
-;;;### (autoloads nil "ob-abc" "org/ob-abc.el" (0 0 0 0))
-;;; Generated autoloads from org/ob-abc.el
-
-(register-definition-prefixes "ob-abc" '("org-babel-"))
-
-;;;***
-
-;;;### (autoloads nil "ob-asymptote" "org/ob-asymptote.el" (0 0 0
-;;;;;; 0))
-;;; Generated autoloads from org/ob-asymptote.el
-
-(register-definition-prefixes "ob-asymptote" '("org-babel-"))
+(register-definition-prefixes "ob-R" '("ob-" "org-babel-"))
;;;***
@@ -23455,13 +23699,6 @@ Many aspects this mode can be customized using
;;;***
-;;;### (autoloads nil "ob-coq" "org/ob-coq.el" (0 0 0 0))
-;;; Generated autoloads from org/ob-coq.el
-
-(register-definition-prefixes "ob-coq" '("coq-program-name" "org-babel-"))
-
-;;;***
-
;;;### (autoloads nil "ob-css" "org/ob-css.el" (0 0 0 0))
;;; Generated autoloads from org/ob-css.el
@@ -23483,13 +23720,6 @@ Many aspects this mode can be customized using
;;;***
-;;;### (autoloads nil "ob-ebnf" "org/ob-ebnf.el" (0 0 0 0))
-;;; Generated autoloads from org/ob-ebnf.el
-
-(register-definition-prefixes "ob-ebnf" '("org-babel-"))
-
-;;;***
-
;;;### (autoloads nil "ob-emacs-lisp" "org/ob-emacs-lisp.el" (0 0
;;;;;; 0 0))
;;; Generated autoloads from org/ob-emacs-lisp.el
@@ -23554,20 +23784,6 @@ Many aspects this mode can be customized using
;;;***
-;;;### (autoloads nil "ob-hledger" "org/ob-hledger.el" (0 0 0 0))
-;;; Generated autoloads from org/ob-hledger.el
-
-(register-definition-prefixes "ob-hledger" '("org-babel-"))
-
-;;;***
-
-;;;### (autoloads nil "ob-io" "org/ob-io.el" (0 0 0 0))
-;;; Generated autoloads from org/ob-io.el
-
-(register-definition-prefixes "ob-io" '("org-babel-"))
-
-;;;***
-
;;;### (autoloads nil "ob-java" "org/ob-java.el" (0 0 0 0))
;;; Generated autoloads from org/ob-java.el
@@ -23582,24 +23798,24 @@ Many aspects this mode can be customized using
;;;***
-;;;### (autoloads nil "ob-latex" "org/ob-latex.el" (0 0 0 0))
-;;; Generated autoloads from org/ob-latex.el
+;;;### (autoloads nil "ob-julia" "org/ob-julia.el" (0 0 0 0))
+;;; Generated autoloads from org/ob-julia.el
-(register-definition-prefixes "ob-latex" '("org-babel-"))
+(register-definition-prefixes "ob-julia" '("org-babel-"))
;;;***
-;;;### (autoloads nil "ob-ledger" "org/ob-ledger.el" (0 0 0 0))
-;;; Generated autoloads from org/ob-ledger.el
+;;;### (autoloads nil "ob-latex" "org/ob-latex.el" (0 0 0 0))
+;;; Generated autoloads from org/ob-latex.el
-(register-definition-prefixes "ob-ledger" '("org-babel-"))
+(register-definition-prefixes "ob-latex" '("org-babel-"))
;;;***
;;;### (autoloads nil "ob-lilypond" "org/ob-lilypond.el" (0 0 0 0))
;;; Generated autoloads from org/ob-lilypond.el
-(register-definition-prefixes "ob-lilypond" '("lilypond-mode" "org-babel-"))
+(register-definition-prefixes "ob-lilypond" '("lilypond-mode" "ob-lilypond-header-args" "org-babel-"))
;;;***
@@ -23631,13 +23847,6 @@ Many aspects this mode can be customized using
;;;***
-;;;### (autoloads nil "ob-mscgen" "org/ob-mscgen.el" (0 0 0 0))
-;;; Generated autoloads from org/ob-mscgen.el
-
-(register-definition-prefixes "ob-mscgen" '("org-babel-"))
-
-;;;***
-
;;;### (autoloads nil "ob-ocaml" "org/ob-ocaml.el" (0 0 0 0))
;;; Generated autoloads from org/ob-ocaml.el
@@ -23666,13 +23875,6 @@ Many aspects this mode can be customized using
;;;***
-;;;### (autoloads nil "ob-picolisp" "org/ob-picolisp.el" (0 0 0 0))
-;;; Generated autoloads from org/ob-picolisp.el
-
-(register-definition-prefixes "ob-picolisp" '("org-babel-"))
-
-;;;***
-
;;;### (autoloads nil "ob-plantuml" "org/ob-plantuml.el" (0 0 0 0))
;;; Generated autoloads from org/ob-plantuml.el
@@ -23744,13 +23946,6 @@ Many aspects this mode can be customized using
;;;***
-;;;### (autoloads nil "ob-shen" "org/ob-shen.el" (0 0 0 0))
-;;; Generated autoloads from org/ob-shen.el
-
-(register-definition-prefixes "ob-shen" '("org-babel-"))
-
-;;;***
-
;;;### (autoloads nil "ob-sql" "org/ob-sql.el" (0 0 0 0))
;;; Generated autoloads from org/ob-sql.el
@@ -23765,24 +23960,52 @@ Many aspects this mode can be customized using
;;;***
-;;;### (autoloads nil "ob-stan" "org/ob-stan.el" (0 0 0 0))
-;;; Generated autoloads from org/ob-stan.el
+;;;### (autoloads nil "ob-table" "org/ob-table.el" (0 0 0 0))
+;;; Generated autoloads from org/ob-table.el
+
+(register-definition-prefixes "ob-table" '("org-"))
+
+;;;***
+
+;;;### (autoloads nil "oc" "org/oc.el" (0 0 0 0))
+;;; Generated autoloads from org/oc.el
+
+(autoload 'org-cite-insert "oc" "\
+Insert a citation at point.
+Insertion is done according to the processor set in `org-cite-insert-processor'.
+ARG is the prefix argument received when calling interactively the function.
-(register-definition-prefixes "ob-stan" '("org-babel-"))
+\(fn ARG)" t nil)
+
+(register-definition-prefixes "oc" '("org-cite-"))
;;;***
-;;;### (autoloads nil "ob-table" "org/ob-table.el" (0 0 0 0))
-;;; Generated autoloads from org/ob-table.el
+;;;### (autoloads nil "oc-basic" "org/oc-basic.el" (0 0 0 0))
+;;; Generated autoloads from org/oc-basic.el
-(register-definition-prefixes "ob-table" '("org-"))
+(register-definition-prefixes "oc-basic" '("org-cite-basic-"))
+
+;;;***
+
+;;;### (autoloads nil "oc-biblatex" "org/oc-biblatex.el" (0 0 0 0))
+;;; Generated autoloads from org/oc-biblatex.el
+
+(register-definition-prefixes "oc-biblatex" '("org-cite-biblatex-"))
;;;***
-;;;### (autoloads nil "ob-vala" "org/ob-vala.el" (0 0 0 0))
-;;; Generated autoloads from org/ob-vala.el
+;;;### (autoloads nil "oc-csl" "org/oc-csl.el" (0 0 0 0))
+;;; Generated autoloads from org/oc-csl.el
-(register-definition-prefixes "ob-vala" '("org-babel-"))
+(register-definition-prefixes "oc-csl" '("org-cite-csl-"))
+
+;;;***
+
+;;;### (autoloads nil "oc-natbib" "org/oc-natbib.el" (0 0 0 0))
+;;; Generated autoloads from org/oc-natbib.el
+
+(register-definition-prefixes "oc-natbib" '("org-cite-natbib-"))
;;;***
@@ -23850,6 +24073,13 @@ startup file, `~/.emacs-octave'.
;;;***
+;;;### (autoloads nil "ol-doi" "org/ol-doi.el" (0 0 0 0))
+;;; Generated autoloads from org/ol-doi.el
+
+(register-definition-prefixes "ol-doi" '("org-link-doi-"))
+
+;;;***
+
;;;### (autoloads nil "ol-eshell" "org/ol-eshell.el" (0 0 0 0))
;;; Generated autoloads from org/ol-eshell.el
@@ -23878,6 +24108,13 @@ startup file, `~/.emacs-octave'.
;;;***
+;;;### (autoloads nil "ol-man" "org/ol-man.el" (0 0 0 0))
+;;; Generated autoloads from org/ol-man.el
+
+(register-definition-prefixes "ol-man" '("org-man-"))
+
+;;;***
+
;;;### (autoloads nil "ol-mhe" "org/ol-mhe.el" (0 0 0 0))
;;; Generated autoloads from org/ol-mhe.el
@@ -23905,7 +24142,8 @@ startup file, `~/.emacs-octave'.
(define-obsolete-function-alias 'delphi-mode #'opascal-mode "24.4")
(autoload 'opascal-mode "opascal" "\
-Major mode for editing OPascal code.\\<opascal-mode-map>
+Major mode for editing OPascal code.
+\\<opascal-mode-map>
\\[opascal-find-unit] - Search for a OPascal source file.
\\[opascal-fill-comment] - Fill the current comment.
\\[opascal-new-comment-line] - If in a // comment, do a new comment line.
@@ -23938,7 +24176,7 @@ Coloring:
;;;### (autoloads nil "org" "org/org.el" (0 0 0 0))
;;; Generated autoloads from org/org.el
-(push (purecopy '(org 9 4 4)) package--builtin-versions)
+(push (purecopy '(org 9 5 1)) package--builtin-versions)
(autoload 'org-babel-do-load-languages "org" "\
Load the languages defined in `org-babel-load-languages'.
@@ -24178,7 +24416,7 @@ first press `<' once to indicate that the agenda should be temporarily
Pressing `<' twice means to restrict to the current subtree or region
\(if active).
-\(fn &optional ARG ORG-KEYS RESTRICTION)" t nil)
+\(fn &optional ARG KEYS RESTRICTION)" t nil)
(autoload 'org-batch-agenda "org-agenda" "\
Run an agenda command in batch mode and send the result to STDOUT.
@@ -24364,7 +24602,7 @@ When in a restricted subtree, remove it.
The restriction will span over the entire file if TYPE is `file',
or if type is '(4), or if the cursor is before the first headline
-in the file. Otherwise, only apply the restriction to the current
+in the file. Otherwise, only apply the restriction to the current
subtree.
\(fn &optional TYPE)" t nil)
@@ -24640,6 +24878,109 @@ See the command `outline-mode' for more information on this mode.
;;;***
+;;;### (autoloads nil "ox-koma-letter" "org/ox-koma-letter.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from org/ox-koma-letter.el
+
+(autoload 'org-koma-letter-export-as-latex "ox-koma-letter" "\
+Export current buffer as a KOMA Scrlttr2 letter.
+
+If narrowing is active in the current buffer, only export its
+narrowed part.
+
+If a region is active, export that region.
+
+A non-nil optional argument ASYNC means the process should happen
+asynchronously. The resulting buffer should be accessible
+through the `org-export-stack' interface.
+
+When optional argument SUBTREEP is non-nil, export the sub-tree
+at point, extracting information from the headline properties
+first.
+
+When optional argument VISIBLE-ONLY is non-nil, don't export
+contents of hidden elements.
+
+When optional argument BODY-ONLY is non-nil, only write code
+between \"\\begin{letter}\" and \"\\end{letter}\".
+
+EXT-PLIST, when provided, is a property list with external
+parameters overriding Org default settings, but still inferior to
+file-local settings.
+
+Export is done in a buffer named \"*Org KOMA-LETTER Export*\". It
+will be displayed if `org-export-show-temporary-export-buffer' is
+non-nil.
+
+\(fn &optional ASYNC SUBTREEP VISIBLE-ONLY BODY-ONLY EXT-PLIST)" t nil)
+
+(autoload 'org-koma-letter-export-to-latex "ox-koma-letter" "\
+Export current buffer as a KOMA Scrlttr2 letter (tex).
+
+If narrowing is active in the current buffer, only export its
+narrowed part.
+
+If a region is active, export that region.
+
+A non-nil optional argument ASYNC means the process should happen
+asynchronously. The resulting file should be accessible through
+the `org-export-stack' interface.
+
+When optional argument SUBTREEP is non-nil, export the sub-tree
+at point, extracting information from the headline properties
+first.
+
+When optional argument VISIBLE-ONLY is non-nil, don't export
+contents of hidden elements.
+
+When optional argument BODY-ONLY is non-nil, only write code
+between \"\\begin{letter}\" and \"\\end{letter}\".
+
+EXT-PLIST, when provided, is a property list with external
+parameters overriding Org default settings, but still inferior to
+file-local settings.
+
+When optional argument PUB-DIR is set, use it as the publishing
+directory.
+
+Return output file's name.
+
+\(fn &optional ASYNC SUBTREEP VISIBLE-ONLY BODY-ONLY EXT-PLIST)" t nil)
+
+(autoload 'org-koma-letter-export-to-pdf "ox-koma-letter" "\
+Export current buffer as a KOMA Scrlttr2 letter (pdf).
+
+If narrowing is active in the current buffer, only export its
+narrowed part.
+
+If a region is active, export that region.
+
+A non-nil optional argument ASYNC means the process should happen
+asynchronously. The resulting file should be accessible through
+the `org-export-stack' interface.
+
+When optional argument SUBTREEP is non-nil, export the sub-tree
+at point, extracting information from the headline properties
+first.
+
+When optional argument VISIBLE-ONLY is non-nil, don't export
+contents of hidden elements.
+
+When optional argument BODY-ONLY is non-nil, only write code
+between \"\\begin{letter}\" and \"\\end{letter}\".
+
+EXT-PLIST, when provided, is a property list with external
+parameters overriding Org default settings, but still inferior to
+file-local settings.
+
+Return PDF file's name.
+
+\(fn &optional ASYNC SUBTREEP VISIBLE-ONLY BODY-ONLY EXT-PLIST)" t nil)
+
+(register-definition-prefixes "ox-koma-letter" '("org-koma-letter-"))
+
+;;;***
+
;;;### (autoloads nil "ox-man" "org/ox-man.el" (0 0 0 0))
;;; Generated autoloads from org/ox-man.el
@@ -24846,46 +25187,6 @@ archive).
;;;***
-;;;### (autoloads nil "paren" "paren.el" (0 0 0 0))
-;;; Generated autoloads from paren.el
-
-(defvar show-paren-mode nil "\
-Non-nil if Show-Paren mode is enabled.
-See the `show-paren-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 `show-paren-mode'.")
-
-(custom-autoload 'show-paren-mode "paren" nil)
-
-(autoload 'show-paren-mode "paren" "\
-Toggle visualization of matching parens (Show Paren mode).
-
-This is a minor mode. If called interactively, toggle the `Show-Paren
-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 `(default-value 'show-paren-mode)'.
-
-The mode's hook is called both when the mode is enabled and when it is
-disabled.
-
-Show Paren mode is a global minor mode. When enabled, any
-matching parenthesis is highlighted in `show-paren-style' after
-`show-paren-delay' seconds of Emacs idle time.
-
-\(fn &optional ARG)" t nil)
-
-(register-definition-prefixes "paren" '("show-paren-"))
-
-;;;***
-
;;;### (autoloads nil "parse-time" "calendar/parse-time.el" (0 0
;;;;;; 0 0))
;;; Generated autoloads from calendar/parse-time.el
@@ -25036,7 +25337,11 @@ Emacs Lisp manual for more information and examples.
(autoload 'pcase-exhaustive "pcase" "\
The exhaustive version of `pcase' (which see).
-If EXP fails to match any of the patterns in CASES, an error is signaled.
+If EXP fails to match any of the patterns in CASES, an error is
+signaled.
+
+In contrast, `pcase' will return nil if there is no match, but
+not signal an error.
\(fn EXP &rest CASES)" nil t)
@@ -25099,6 +25404,19 @@ of the elements of LIST is performed as if by `pcase-let'.
(function-put 'pcase-dolist 'lisp-indent-function '1)
+(autoload 'pcase-setq "pcase" "\
+Assign values to variables by destructuring with `pcase'.
+PATTERNS are normal `pcase' patterns, and VALUES are expression.
+
+Evaluation happens sequentially as in `setq' (not in parallel).
+
+An example: (pcase-setq `((,a) [(,b)]) '((1) [(2)]))
+
+VAL is presumed to match PAT. Failure to match may signal an error or go
+undetected, binding variables to arbitrary values, such as nil.
+
+\(fn PATTERNS VALUE PATTERN VALUES ...)" nil t)
+
(autoload 'pcase-defmacro "pcase" "\
Define a new kind of pcase PATTERN, by macro expansion.
Patterns of the form (NAME ...) will be expanded according
@@ -25414,10 +25732,10 @@ Global menu used by PCL-CVS.")
(put 'perl-label-offset 'safe-local-variable 'integerp)
(autoload 'perl-flymake "perl-mode" "\
-Perl backend for Flymake. Launches
-`perl-flymake-command' (which see) and passes to its standard
-input the contents of the current buffer. The output of this
-command is analyzed for error and warning messages.
+Perl backend for Flymake.
+Launch `perl-flymake-command' (which see) and pass to its
+standard input the contents of the current buffer. The output of
+this command is analyzed for error and warning messages.
\(fn REPORT-FN &rest ARGS)" nil nil)
@@ -25494,10 +25812,10 @@ afterwards settable by these commands:
Move southwest (sw) after insertion: \\[picture-movement-sw]
Move southeast (se) after insertion: \\[picture-movement-se]
- Move westnorthwest (wnw) after insertion: C-u \\[picture-movement-nw]
- Move eastnortheast (ene) after insertion: C-u \\[picture-movement-ne]
- Move westsouthwest (wsw) after insertion: C-u \\[picture-movement-sw]
- Move eastsoutheast (ese) after insertion: C-u \\[picture-movement-se]
+ Move westnorthwest (wnw) after insertion: \\[universal-argument] \\[picture-movement-nw]
+ Move eastnortheast (ene) after insertion: \\[universal-argument] \\[picture-movement-ne]
+ Move westsouthwest (wsw) after insertion: \\[universal-argument] \\[picture-movement-sw]
+ Move eastsoutheast (ese) after insertion: \\[universal-argument] \\[picture-movement-se]
The current direction is displayed in the mode line. The initial
direction is right. Whitespace is inserted and tabs are changed to
@@ -25562,6 +25880,14 @@ they are not by default assigned to keys." t nil)
;;;***
+;;;### (autoloads nil "pixel-fill" "textmodes/pixel-fill.el" (0 0
+;;;;;; 0 0))
+;;; Generated autoloads from textmodes/pixel-fill.el
+
+(register-definition-prefixes "pixel-fill" '("pixel-fill-"))
+
+;;;***
+
;;;### (autoloads nil "pixel-scroll" "pixel-scroll.el" (0 0 0 0))
;;; Generated autoloads from pixel-scroll.el
@@ -25587,7 +25913,39 @@ 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 `(default-value 'pixel-scroll-mode)'.
+evaluate `(default-value \\='pixel-scroll-mode)'.
+
+The mode's hook is called both when the mode is enabled and when it is
+disabled.
+
+\(fn &optional ARG)" t nil)
+
+(defvar pixel-scroll-precision-mode nil "\
+Non-nil if Pixel-Scroll-Precision mode is enabled.
+See the `pixel-scroll-precision-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 `pixel-scroll-precision-mode'.")
+
+(custom-autoload 'pixel-scroll-precision-mode "pixel-scroll" nil)
+
+(autoload 'pixel-scroll-precision-mode "pixel-scroll" "\
+Toggle pixel scrolling.
+When enabled, this minor mode allows to scroll the display
+precisely, according to the turning of the mouse wheel.
+
+This is a minor mode. If called interactively, toggle the
+`Pixel-Scroll-Precision 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 `(default-value \\='pixel-scroll-precision-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -25674,10 +26032,26 @@ Prettify the current buffer with printed representation of a Lisp object." t nil
Output the pretty-printed representation of OBJECT, any Lisp object.
Quoting characters are printed as needed to make output that `read'
can handle, whenever this is possible.
+
+This function does not apply special formatting rules for Emacs
+Lisp code. See `pp-emacs-lisp-code' instead.
+
+By default, this function won't limit the line length of lists
+and vectors. Bind `pp-use-max-width' to a non-nil value to do so.
+
Output stream is STREAM, or value of `standard-output' (which see).
\(fn OBJECT &optional STREAM)" nil nil)
+(autoload 'pp-display-expression "pp" "\
+Prettify and display EXPRESSION in an appropriate way, depending on length.
+If LISP, format with `pp-emacs-lisp-code'; use `pp' otherwise.
+
+If a temporary buffer is needed for representation, it will be named
+after OUT-BUFFER-NAME.
+
+\(fn EXPRESSION OUT-BUFFER-NAME &optional LISP)" nil nil)
+
(autoload 'pp-eval-expression "pp" "\
Evaluate EXPRESSION and pretty-print its value.
Also add the value to the front of the list in the variable `values'.
@@ -25703,6 +26077,12 @@ Ignores leading comment characters.
\(fn ARG)" t nil)
+(autoload 'pp-emacs-lisp-code "pp" "\
+Insert SEXP into the current buffer, formatted as Emacs Lisp code.
+Use the `pp-max-width' variable to control the desired line length.
+
+\(fn SEXP)" nil nil)
+
(register-definition-prefixes "pp" '("pp-"))
;;;***
@@ -25724,7 +26104,7 @@ For more information, type \\[pr-interface-help].
Preview directory using ghostview.
Interactively, the command prompts for N-UP printing number, a directory, a
-file name regexp for matching and, when you use a prefix argument (C-u), the
+file name regexp for matching and, when you use a prefix argument (\\[universal-argument]), the
command prompts the user for a file name, and saves the PostScript image in
that file instead of saving it in a temporary file.
@@ -25743,7 +26123,7 @@ See also documentation for `pr-list-directory'.
Print directory using PostScript through ghostscript.
Interactively, the command prompts for N-UP printing number, a directory, a
-file name regexp for matching and, when you use a prefix argument (C-u), the
+file name regexp for matching and, when you use a prefix argument (\\[universal-argument]), the
command prompts the user for a file name, and saves the PostScript image in
that file instead of saving it in a temporary file.
@@ -25762,7 +26142,7 @@ See also documentation for `pr-list-directory'.
Print directory using PostScript printer.
Interactively, the command prompts for N-UP printing number, a directory, a
-file name regexp for matching and, when you use a prefix argument (C-u), the
+file name regexp for matching and, when you use a prefix argument (\\[universal-argument]), the
command prompts the user for a file name, and saves the PostScript image in
that file instead of saving it in a temporary file.
@@ -25783,7 +26163,7 @@ Print directory using PostScript printer or through ghostscript.
It depends on `pr-print-using-ghostscript'.
Interactively, the command prompts for N-UP printing number, a directory, a
-file name regexp for matching and, when you use a prefix argument (C-u), the
+file name regexp for matching and, when you use a prefix argument (\\[universal-argument]), the
command prompts the user for a file name, and saves the PostScript image in
that file instead of saving it in a temporary file.
@@ -25802,7 +26182,7 @@ See also documentation for `pr-list-directory'.
Preview buffer using ghostview.
Interactively, the command prompts for N-UP printing number and, when you use a
-prefix argument (C-u), the command prompts the user for a file name, and saves
+prefix argument (\\[universal-argument]), the command prompts the user for a file name, and saves
the PostScript image in that file instead of saving it in a temporary file.
Noninteractively, if N-UP is nil, prompts for N-UP printing number. The
@@ -25816,7 +26196,7 @@ with that name. If FILENAME is t, prompts for a file name.
Print buffer using PostScript through ghostscript.
Interactively, the command prompts for N-UP printing number and, when you use a
-prefix argument (C-u), the command prompts the user for a file name, and saves
+prefix argument (\\[universal-argument]), the command prompts the user for a file name, and saves
the PostScript image in that file instead of sending it to the printer.
Noninteractively, if N-UP is nil, prompts for N-UP printing number. The
@@ -25830,7 +26210,7 @@ that name. If FILENAME is t, prompts for a file name.
Print buffer using PostScript printer.
Interactively, the command prompts for N-UP printing number and, when you use a
-prefix argument (C-u), the command prompts the user for a file name, and saves
+prefix argument (\\[universal-argument]), the command prompts the user for a file name, and saves
the PostScript image in that file instead of sending it to the printer.
Noninteractively, if N-UP is nil, prompts for N-UP printing number. The
@@ -25846,7 +26226,7 @@ Print buffer using PostScript printer or through ghostscript.
It depends on `pr-print-using-ghostscript'.
Interactively, the command prompts for N-UP printing number and, when you use a
-prefix argument (C-u), the command prompts the user for a file name, and saves
+prefix argument (\\[universal-argument]), the command prompts the user for a file name, and saves
the PostScript image in that file instead of sending it to the printer.
Noninteractively, if N-UP is nil, prompts for N-UP printing number. The
@@ -25962,7 +26342,7 @@ Print major mode using text printer." t nil)
(autoload 'pr-despool-preview "printing" "\
Preview spooled PostScript.
-Interactively, when you use a prefix argument (C-u), the command prompts the
+Interactively, when you use a prefix argument (\\[universal-argument]), the command prompts the
user for a file name, and saves the spooled PostScript image in that file
instead of saving it in a temporary file.
@@ -25975,7 +26355,7 @@ PostScript image in a file with that name.
(autoload 'pr-despool-using-ghostscript "printing" "\
Print spooled PostScript using ghostscript.
-Interactively, when you use a prefix argument (C-u), the command prompts the
+Interactively, when you use a prefix argument (\\[universal-argument]), the command prompts the
user for a file name, and saves the spooled PostScript image in that file
instead of sending it to the printer.
@@ -25988,7 +26368,7 @@ image in a file with that name.
(autoload 'pr-despool-print "printing" "\
Send the spooled PostScript to the printer.
-Interactively, when you use a prefix argument (C-u), the command prompts the
+Interactively, when you use a prefix argument (\\[universal-argument]), the command prompts the
user for a file name, and saves the spooled PostScript image in that file
instead of sending it to the printer.
@@ -26001,7 +26381,7 @@ image in a file with that name.
(autoload 'pr-despool-ps-print "printing" "\
Send the spooled PostScript to the printer or use ghostscript to print it.
-Interactively, when you use a prefix argument (C-u), the command prompts the
+Interactively, when you use a prefix argument (\\[universal-argument]), the command prompts the
user for a file name, and saves the spooled PostScript image in that file
instead of sending it to the printer.
@@ -26040,7 +26420,7 @@ Send PostScript file FILENAME to printer or use ghostscript to print it.
Process a PostScript file IFILENAME and send it to printer.
Interactively, the command prompts for N-UP printing number, for an input
-PostScript file IFILENAME and, when you use a prefix argument (C-u), the
+PostScript file IFILENAME and, when you use a prefix argument (\\[universal-argument]), the
command prompts the user for an output PostScript file name OFILENAME, and
saves the PostScript image in that file instead of sending it to the printer.
@@ -26165,22 +26545,22 @@ printed using `pr-ps-mode-ps-print'.
Interactively, you have the following situations:
- M-x pr-ps-fast-fire RET
+ \\[pr-ps-fast-fire]
The command prompts the user for a N-UP value and printing will
immediately be done using the current active printer.
- C-u M-x pr-ps-fast-fire RET
- C-u 0 M-x pr-ps-fast-fire RET
+ \\[universal-argument] \\[pr-ps-fast-fire]
+ \\[universal-argument] 0 \\[pr-ps-fast-fire]
The command prompts the user for a N-UP value and also for a current
PostScript printer, then printing will immediately be done using the new
current active printer.
- C-u 1 M-x pr-ps-fast-fire RET
+ \\[universal-argument] 1 \\[pr-ps-fast-fire]
The command prompts the user for a N-UP value and also for a file name,
and saves the PostScript image in that file instead of sending it to the
printer.
- C-u 2 M-x pr-ps-fast-fire RET
+ \\[universal-argument] 2 \\[pr-ps-fast-fire]
The command prompts the user for a N-UP value, then for a current
PostScript printer and, finally, for a file name. Then change the active
printer to that chosen by user and saves the PostScript image in
@@ -26225,7 +26605,7 @@ Also if the current major-mode is defined in `pr-mode-alist', the settings in
`pr-mode-alist' will be used, that is, the current buffer or region will be
printed using `pr-txt-mode'.
-Interactively, when you use a prefix argument (C-u), the command prompts the
+Interactively, when you use a prefix argument (\\[universal-argument]), the command prompts the
user for a new active text printer.
Noninteractively, the argument SELECT-PRINTER is treated as follows:
@@ -26303,7 +26683,7 @@ Open profile FILENAME.
;;;### (autoloads nil "project" "progmodes/project.el" (0 0 0 0))
;;; Generated autoloads from progmodes/project.el
-(push (purecopy '(project 0 6 0)) package--builtin-versions)
+(push (purecopy '(project 0 8 1)) package--builtin-versions)
(autoload 'project-current "project" "\
Return the project instance in DIRECTORY, defaulting to `default-directory'.
@@ -26324,7 +26704,7 @@ of the project instance object.
\(fn &optional MAYBE-PROMPT DIRECTORY)" nil nil)
-(defvar project-prefix-map (let ((map (make-sparse-keymap))) (define-key map "!" 'project-shell-command) (define-key map "&" 'project-async-shell-command) (define-key map "f" 'project-find-file) (define-key map "F" 'project-or-external-find-file) (define-key map "b" 'project-switch-to-buffer) (define-key map "s" 'project-shell) (define-key map "d" 'project-dired) (define-key map "v" 'project-vc-dir) (define-key map "c" 'project-compile) (define-key map "e" 'project-eshell) (define-key map "k" 'project-kill-buffers) (define-key map "p" 'project-switch-project) (define-key map "g" 'project-find-regexp) (define-key map "G" 'project-or-external-find-regexp) (define-key map "r" 'project-query-replace-regexp) (define-key map "x" 'project-execute-extended-command) map) "\
+(defvar project-prefix-map (let ((map (make-sparse-keymap))) (define-key map "!" 'project-shell-command) (define-key map "&" 'project-async-shell-command) (define-key map "f" 'project-find-file) (define-key map "F" 'project-or-external-find-file) (define-key map "b" 'project-switch-to-buffer) (define-key map "s" 'project-shell) (define-key map "d" 'project-find-dir) (define-key map "D" 'project-dired) (define-key map "v" 'project-vc-dir) (define-key map "c" 'project-compile) (define-key map "e" 'project-eshell) (define-key map "k" 'project-kill-buffers) (define-key map "p" 'project-switch-project) (define-key map "g" 'project-find-regexp) (define-key map "G" 'project-or-external-find-regexp) (define-key map "r" 'project-query-replace-regexp) (define-key map "x" 'project-execute-extended-command) map) "\
Keymap for project commands.")
(define-key ctl-x-map "p" project-prefix-map)
@@ -26376,14 +26756,29 @@ pattern to search for.
(autoload 'project-find-file "project" "\
Visit a file (with completion) in the current project.
-The completion default is the filename at point, determined by
-`thing-at-point' (whether such file exists or not)." t nil)
+The filename at point (determined by `thing-at-point'), if any,
+is available as part of \"future history\".
+
+If INCLUDE-ALL is non-nil, or with prefix argument when called
+interactively, include all files under the project root, except
+for VCS directories listed in `vc-directory-exclusion-list'.
+
+\(fn &optional INCLUDE-ALL)" t nil)
(autoload 'project-or-external-find-file "project" "\
Visit a file (with completion) in the current project or external roots.
-The completion default is the filename at point, determined by
-`thing-at-point' (whether such file exists or not)." t nil)
+The filename at point (determined by `thing-at-point'), if any,
+is available as part of \"future history\".
+
+If INCLUDE-ALL is non-nil, or with prefix argument when called
+interactively, include all files under the project root, except
+for VCS directories listed in `vc-directory-exclusion-list'.
+
+\(fn &optional INCLUDE-ALL)" t nil)
+
+(autoload 'project-find-dir "project" "\
+Start Dired in a directory inside the current project." t nil)
(autoload 'project-dired "project" "\
Start Dired in the current project's root." t nil)
@@ -26426,8 +26821,8 @@ command \\[fileloop-continue].
(autoload 'project-query-replace-regexp "project" "\
Query-replace REGEXP in all the files of the project.
Stops when a match is found and prompts for whether to replace it.
-If you exit the query-replace, you can later continue the query-replace
-loop using the command \\[fileloop-continue].
+If you exit the `query-replace', you can later continue the
+`query-replace' loop using the command \\[fileloop-continue].
\(fn FROM TO)" t nil)
@@ -26484,11 +26879,12 @@ interactively.
(autoload 'project-remember-project "project" "\
Add project PR to the front of the project list.
-Save the result in `project-list-file' if the list of projects has changed.
+Save the result in `project-list-file' if the list of projects
+has changed, and NO-WRITE is nil.
-\(fn PR)" nil nil)
+\(fn PR &optional NO-WRITE)" nil nil)
-(autoload 'project-remove-known-project "project" "\
+(autoload 'project-forget-project "project" "\
Remove directory PROJECT-ROOT from the project list.
PROJECT-ROOT is the root directory of a known project listed in
the project list.
@@ -26822,9 +27218,11 @@ If EXTENSION is any other symbol, it is ignored.
(autoload 'pulse-momentary-highlight-one-line "pulse" "\
Highlight the line around POINT, unhighlighting before next command.
+If POINT is nil or missing, the current point is used instead.
+
Optional argument FACE specifies the face to do the highlighting.
-\(fn POINT &optional FACE)" nil nil)
+\(fn &optional POINT FACE)" nil nil)
(autoload 'pulse-momentary-highlight-region "pulse" "\
Highlight between START and END, unhighlighting before next command.
@@ -26845,7 +27243,7 @@ Optional argument FACE specifies the face to do the highlighting.
;;;### (autoloads nil "python" "progmodes/python.el" (0 0 0 0))
;;; Generated autoloads from progmodes/python.el
-(push (purecopy '(python 0 27 1)) package--builtin-versions)
+(push (purecopy '(python 0 28)) package--builtin-versions)
(add-to-list 'auto-mode-alist (cons (purecopy "\\.py[iw]?\\'") 'python-mode))
@@ -26995,7 +27393,7 @@ conversion region is active. It is an alist of single key character
vs. corresponding command to be called.
If SIMPLE is non-nil, then we do not alter the meanings of
-commands such as C-f, C-b, C-n, C-p and TAB; they are treated as
+commands such as \\[forward-char], \\[backward-char], \\[next-line], \\[previous-line] and \\[indent-for-tab-command]; they are treated as
non-Quail commands.
\(fn NAME LANGUAGE TITLE &optional GUIDANCE DOCSTRING TRANSLATION-KEYS FORGET-LAST-SELECTION DETERMINISTIC KBD-TRANSLATE SHOW-LAYOUT CREATE-DECODE-MAP MAXIMUM-SHORTEST OVERLAY-PLIST UPDATE-TRANSLATION-FUNCTION CONVERSION-KEYS SIMPLE)" nil nil)
@@ -27334,11 +27732,11 @@ If ARG is non-nil, instead prompt for connection parameters.
(autoload 'rcirc-connect "rcirc" "\
Connect to SERVER.
The arguments PORT, NICK, USER-NAME, FULL-NAME, PASSWORD,
-ENCRYPTION, SERVER-ALIAS are interpreted as in
+ENCRYPTION, CERTFP, SERVER-ALIAS are interpreted as in
`rcirc-server-alist'. STARTUP-CHANNELS is a list of channels
that are joined after authentication.
-\(fn SERVER &optional PORT NICK USER-NAME FULL-NAME STARTUP-CHANNELS PASSWORD ENCRYPTION SERVER-ALIAS)" nil nil)
+\(fn SERVER &optional PORT NICK USER-NAME FULL-NAME STARTUP-CHANNELS PASSWORD ENCRYPTION CERTFP SERVER-ALIAS)" nil nil)
(defvar rcirc-track-minor-mode nil "\
Non-nil if Rcirc-Track minor mode is enabled.
@@ -27362,7 +27760,7 @@ 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 `(default-value 'rcirc-track-minor-mode)'.
+evaluate `(default-value \\='rcirc-track-minor-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -27422,7 +27820,7 @@ 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 `(default-value 'recentf-mode)'.
+evaluate `(default-value \\='recentf-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -27877,7 +28275,7 @@ recently executed command not bound to an input event\".
\(fn REPEAT-ARG)" t nil)
(defvar repeat-map nil "\
-The value of the repeating map for the next command.
+The value of the repeating transient map for the next command.
A command called from the map can set it again to the same map when
the map can't be set on the command symbol property `repeat-map'.")
@@ -27895,6 +28293,7 @@ or call the function `repeat-mode'.")
Toggle Repeat mode.
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.
This is a minor mode. If called interactively, toggle the `Repeat
mode' mode. If the prefix argument is positive, enable the mode, and
@@ -27905,7 +28304,7 @@ 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 `(default-value 'repeat-mode)'.
+evaluate `(default-value \\='repeat-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -28029,7 +28428,7 @@ 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 `(default-value 'global-reveal-mode)'.
+evaluate `(default-value \\='global-reveal-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -28076,10 +28475,10 @@ disabled.
;;;***
-;;;### (autoloads nil "rfc2368" "mail/rfc2368.el" (0 0 0 0))
-;;; Generated autoloads from mail/rfc2368.el
+;;;### (autoloads nil "rfc6068" "mail/rfc6068.el" (0 0 0 0))
+;;; Generated autoloads from mail/rfc6068.el
-(register-definition-prefixes "rfc2368" '("rfc2368-"))
+(register-definition-prefixes "rfc6068" '("rfc6068-"))
;;;***
@@ -28919,7 +29318,8 @@ Zero-width assertions: these all match the empty string in specific places.
\(literal EXPR) Match the literal string from evaluating EXPR at run time.
\(regexp EXPR) Match the string regexp from evaluating EXPR at run time.
-\(eval EXPR) Match the rx sexp from evaluating EXPR at compile time.
+\(eval EXPR) Match the rx sexp from evaluating EXPR at macro-expansion
+ (compile) time.
Additional constructs can be defined using `rx-define' and `rx-let',
which see.
@@ -29072,7 +29472,7 @@ 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 `(default-value 'savehist-mode)'.
+evaluate `(default-value \\='savehist-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -29136,7 +29536,7 @@ 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 `(default-value 'save-place-mode)'.
+evaluate `(default-value \\='save-place-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -29255,7 +29655,7 @@ 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 `(default-value 'scroll-all-mode)'.
+evaluate `(default-value \\='scroll-all-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -29370,7 +29770,7 @@ 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 `(default-value 'semantic-mode)'.
+evaluate `(default-value \\='semantic-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -29867,7 +30267,7 @@ Like `mail' command, but display mail buffer in another frame.
;;;### (autoloads nil "seq" "emacs-lisp/seq.el" (0 0 0 0))
;;; Generated autoloads from emacs-lisp/seq.el
-(push (purecopy '(seq 2 22)) package--builtin-versions)
+(push (purecopy '(seq 2 23)) package--builtin-versions)
(autoload 'seq-subseq "seq" "\
Return the sequence of elements of SEQUENCE from START to END.
@@ -29953,14 +30353,14 @@ TESTFN is used to compare elements, or `equal' if TESTFN is nil.
\(fn SEQUENCE &optional TESTFN)" nil nil)
-(autoload 'seq-intersection "seq" "\
-Return a list of the elements that appear in both SEQUENCE1 and SEQUENCE2.
+(autoload 'seq-union "seq" "\
+Return a list of all elements that appear in either SEQUENCE1 or SEQUENCE2.
Equality is defined by TESTFN if non-nil or by `equal' if nil.
\(fn SEQUENCE1 SEQUENCE2 &optional TESTFN)" nil nil)
-(autoload 'seq-difference "seq" "\
-Return a list of the elements that appear in SEQUENCE1 but not in SEQUENCE2.
+(autoload 'seq-intersection "seq" "\
+Return a list of the elements that appear in both SEQUENCE1 and SEQUENCE2.
Equality is defined by TESTFN if non-nil or by `equal' if nil.
\(fn SEQUENCE1 SEQUENCE2 &optional TESTFN)" nil nil)
@@ -29978,6 +30378,12 @@ SEQUENCE must be a sequence of numbers or markers.
\(fn SEQUENCE)" nil nil)
+(autoload 'seq-random-elt "seq" "\
+Return a random element from SEQUENCE.
+Signal an error if SEQUENCE is empty.
+
+\(fn SEQUENCE)" nil nil)
+
(register-definition-prefixes "seq" '("seq-"))
;;;***
@@ -30042,7 +30448,7 @@ 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 `(default-value 'server-mode)'.
+evaluate `(default-value \\='server-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -30062,6 +30468,29 @@ only these files will be asked to be saved.
\(fn ARG)" nil nil)
+(autoload 'server-stop-automatically "server" "\
+Automatically stop server as specified by ARG.
+
+If ARG is the symbol `empty', stop the server when it has no
+remaining clients, no remaining unsaved file-visiting buffers,
+and no running processes with a `query-on-exit' flag.
+
+If ARG is the symbol `delete-frame', ask the user when the last
+frame is deleted whether each unsaved file-visiting buffer must
+be saved and each running process with a `query-on-exit' flag
+can be stopped, and if so, stop the server itself.
+
+If ARG is the symbol `kill-terminal', ask the user when the
+terminal is killed with \\[save-buffers-kill-terminal] whether each unsaved file-visiting
+buffer must be saved and each running process with a `query-on-exit'
+flag can be stopped, and if so, stop the server itself.
+
+Any other value of ARG will cause this function to signal an error.
+
+This function is meant to be called from the user init file.
+
+\(fn ARG)" nil nil)
+
(register-definition-prefixes "server" '("server-"))
;;;***
@@ -30153,10 +30582,11 @@ can also view with a browser to see what happens:
have <h1>Very Major Headlines</h1> through <h6>Very Minor Headlines</h6>
<hr> Parts can be separated with horizontal rules.
-<p>Paragraphs only need an opening tag. Line breaks and multiple spaces are
-ignored unless the text is <pre>preformatted.</pre> Text can be marked as
-<strong>bold</strong>, <em>italic</em> or <u>underlined</u> using the normal M-o
-or Edit/Text Properties/Face commands.
+<p>Paragraphs only need an opening tag. Line breaks and multiple
+spaces are ignored unless the text is <pre>preformatted.</pre>
+Text can be marked as <strong>bold</strong>, <em>italic</em> or
+<u>underlined</u> using the facemenu M-o or Edit/Text
+Properties/Face commands.
Pages can have <a name=\"SOMENAME\">named points</a> and can link other points
to them with <a href=\"#SOMENAME\">see also somename</a>. In the same way <a
@@ -30397,7 +30827,7 @@ If FUNCTION is non-nil, place point on the entry for FUNCTION (if any).
\(fn GROUP &optional FUNCTION)" t nil)
-(register-definition-prefixes "shortdoc" '("alist" "buffer" "define-short-documentation-group" "file" "hash-table" "list" "number" "overlay" "process" "regexp" "sequence" "shortdoc-" "string" "vector"))
+(register-definition-prefixes "shortdoc" '("alist" "buffer" "define-short-documentation-group" "file" "hash-table" "keymaps" "list" "number" "overlay" "process" "regexp" "sequence" "shortdoc-" "string" "text-properties" "vector"))
;;;***
@@ -30537,6 +30967,8 @@ SKELETON is as defined under `skeleton-insert'.
(function-put 'define-skeleton 'doc-string-elt '2)
+(function-put 'define-skeleton 'lisp-indent-function 'defun)
+
(autoload 'skeleton-proxy-new "skeleton" "\
Insert SKELETON.
Prefix ARG allows wrapping around words or regions (see `skeleton-insert').
@@ -30780,7 +31212,7 @@ Tab indents for C code.
Comments start with -- and end with newline or another --.
Delete converts tabs to spaces as it moves back.
\\{snmp-mode-map}
-Turning on snmp-mode runs the hooks in `snmp-common-mode-hook', then
+Turning on `snmp-mode' runs the hooks in `snmp-common-mode-hook', then
`snmp-mode-hook'." t nil)
(autoload 'snmpv2-mode "snmp-mode" "\
@@ -30790,7 +31222,7 @@ Tab indents for C code.
Comments start with -- and end with newline or another --.
Delete converts tabs to spaces as it moves back.
\\{snmp-mode-map}
-Turning on snmp-mode runs the hooks in `snmp-common-mode-hook',
+Turning on `snmp-mode' runs the hooks in `snmp-common-mode-hook',
then `snmpv2-mode-hook'." t nil)
(register-definition-prefixes "snmp-mode" '("snmp"))
@@ -30799,13 +31231,13 @@ then `snmpv2-mode-hook'." t nil)
;;;### (autoloads nil "so-long" "so-long.el" (0 0 0 0))
;;; Generated autoloads from so-long.el
-(push (purecopy '(so-long 1 0)) package--builtin-versions)
+(push (purecopy '(so-long 1 1 2)) package--builtin-versions)
(autoload 'so-long-commentary "so-long" "\
-View the so-long documentation in `outline-mode'." t nil)
+View the `so-long' library's documentation in `outline-mode'." t nil)
(autoload 'so-long-customize "so-long" "\
-Open the so-long `customize' group." t nil)
+Open the customization group `so-long'." t nil)
(autoload 'so-long-minor-mode "so-long" "\
This is the minor mode equivalent of `so-long-mode'.
@@ -30856,7 +31288,8 @@ values), despite potential performance issues, type \\[so-long-revert].
Use \\[so-long-commentary] for more information.
-Use \\[so-long-customize] to configure the behaviour.
+Use \\[so-long-customize] to open the customization group `so-long' to
+configure the behaviour.
\(fn)" t nil)
@@ -30878,7 +31311,7 @@ invoking the new action.
\(fn &optional ACTION)" t nil)
(autoload 'so-long-enable "so-long" "\
-Enable the so-long library's functionality.
+Enable the `so-long' library's functionality.
Equivalent to calling (global-so-long-mode 1)" t nil)
@@ -30904,7 +31337,7 @@ 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 `(default-value 'global-so-long-mode)'.
+evaluate `(default-value \\='global-so-long-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -30921,7 +31354,8 @@ When such files are detected by `so-long-predicate', we invoke the selected
Use \\[so-long-commentary] for more information.
-Use \\[so-long-customize] to configure the behaviour.
+Use \\[so-long-customize] to open the customization group `so-long' to
+configure the behaviour.
\(fn &optional ARG)" t nil)
@@ -31065,12 +31499,12 @@ The variable `sort-fold-case' determines whether alphabetic case affects
the sort order.
The next four arguments are functions to be called to move point
-across a sort record. They will be called many times from within sort-subr.
+across a sort record. They will be called many times from within `sort-subr'.
NEXTRECFUN is called with point at the end of the previous record.
It moves point to the start of the next record.
It should move point to the end of the buffer if there are no more records.
-The first record is assumed to start at the position of point when sort-subr
+The first record is assumed to start at the position of point when `sort-subr'
is called.
ENDRECFUN is called with point within the record.
@@ -31208,16 +31642,16 @@ Delete all but one copy of any identical lines in the region.
Non-interactively, arguments BEG and END delimit the region.
Normally it searches forwards, keeping the first instance of
each identical line. If REVERSE is non-nil (interactively, with
-a C-u prefix), it searches backwards and keeps the last instance of
+a \\[universal-argument] prefix), it searches backwards and keeps the last instance of
each repeated line.
Identical lines need not be adjacent, unless the argument
-ADJACENT is non-nil (interactively, with a C-u C-u prefix).
+ADJACENT is non-nil (interactively, with a \\[universal-argument] \\[universal-argument] prefix).
This is a more efficient mode of operation, and may be useful
on large regions that have already been sorted.
If the argument KEEP-BLANKS is non-nil (interactively, with a
-C-u C-u C-u prefix), it retains repeated blank lines.
+\\[universal-argument] \\[universal-argument] \\[universal-argument] prefix), it retains repeated blank lines.
Returns the number of deleted lines. Interactively, or if INTERACTIVE
is non-nil, it also prints a message describing the number of deletions.
@@ -31247,7 +31681,7 @@ installed through `spam-necessary-extra-headers'.
\(fn &rest SYMBOLS)" t nil)
-(register-definition-prefixes "spam" '("spam-"))
+(register-definition-prefixes "spam" '(":keymap" "spam-"))
;;;***
@@ -31334,7 +31768,7 @@ selected. If the speedbar frame is active, then select the attached frame." t n
;;; Generated autoloads from play/spook.el
(autoload 'spook "spook" "\
-Adds that special touch of class to your outgoing mail." t nil)
+Add that special touch of class to your outgoing mail." t nil)
(autoload 'snarf-spooks "spook" "\
Return a vector containing the lines from `spook-phrases-file'." nil nil)
@@ -32025,7 +32459,7 @@ 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 `(default-value 'strokes-mode)'.
+evaluate `(default-value \\='strokes-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -32117,13 +32551,57 @@ Truncate STRING to LENGTH, replacing initial surplus with \"...\".
\(fn STRING LENGTH)" nil nil)
+(autoload 'string-clean-whitespace "subr-x" "\
+Clean up whitespace in STRING.
+All sequences of whitespaces in STRING are collapsed into a
+single space character, and leading/trailing whitespace is
+removed.
+
+\(fn STRING)" nil nil)
+
(autoload 'string-lines "subr-x" "\
Split STRING into a list of lines.
If OMIT-NULLS, empty lines will be removed from the results.
\(fn STRING &optional OMIT-NULLS)" nil nil)
-(register-definition-prefixes "subr-x" '("and-let*" "hash-table-" "if-let*" "internal--" "named-let" "replace-region-contents" "string-" "thread-" "when-let*"))
+(autoload 'ensure-empty-lines "subr-x" "\
+Ensure that there are LINES number of empty lines before point.
+If LINES is nil or omitted, ensure that there is a single empty
+line before point.
+
+If called interactively, LINES is given by the prefix argument.
+
+If there are more than LINES empty lines before point, the number
+of empty lines is reduced to LINES.
+
+If point is not at the beginning of a line, a newline character
+is inserted before adjusting the number of empty lines.
+
+\(fn &optional LINES)" t nil)
+
+(autoload 'string-pixel-width "subr-x" "\
+Return the width of STRING in pixels.
+
+\(fn STRING)" nil nil)
+
+(autoload 'string-glyph-split "subr-x" "\
+Split STRING into a list of strings representing separate glyphs.
+This takes into account combining characters and grapheme clusters.
+
+\(fn STRING)" nil nil)
+
+(autoload 'add-display-text-property "subr-x" "\
+Add display property PROP with VALUE to the text from START to END.
+If any text in the region has a non-nil `display' property, those
+properties are retained.
+
+If OBJECT is non-nil, it should be a string or a buffer. If nil,
+this defaults to the current buffer.
+
+\(fn START END PROP VALUE &optional OBJECT)" nil nil)
+
+(register-definition-prefixes "subr-x" '("and-let*" "hash-table-" "if-let*" "internal--" "named-let" "replace-region-contents" "string-" "thread-" "when-let*" "with-memoization"))
;;;***
@@ -32184,8 +32662,11 @@ or call the function `global-subword-mode'.")
(autoload 'global-subword-mode "subword" "\
Toggle Subword mode in all buffers.
With prefix ARG, enable Global Subword mode if ARG is positive;
-otherwise, disable it. If called from Lisp, enable the mode if ARG is
-omitted or nil.
+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.
Subword mode is enabled in all buffers where `(lambda nil
\(subword-mode 1))' would do it.
@@ -32235,8 +32716,11 @@ or call the function `global-superword-mode'.")
(autoload 'global-superword-mode "subword" "\
Toggle Superword mode in all buffers.
With prefix ARG, enable Global Superword mode if ARG is positive;
-otherwise, disable it. If called from Lisp, enable the mode if ARG is
-omitted or nil.
+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.
Superword mode is enabled in all buffers where `(lambda nil
\(superword-mode 1))' would do it.
@@ -32314,7 +32798,7 @@ 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 `(default-value 'gpm-mouse-mode)'.
+evaluate `(default-value \\='gpm-mouse-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -32337,7 +32821,7 @@ GPM. This is due to limitations in GPM and the Linux kernel.
;;; Generated autoloads from tab-line.el
(autoload 'tab-line-mode "tab-line" "\
-Toggle display of window tab line in the buffer.
+Toggle display of tab line in the windows displaying the current buffer.
This is a minor mode. If called interactively, toggle the `Tab-Line
mode' mode. If the prefix argument is positive, enable the mode, and
@@ -32372,11 +32856,14 @@ or call the function `global-tab-line-mode'.")
(autoload 'global-tab-line-mode "tab-line" "\
Toggle Tab-Line mode in all buffers.
With prefix ARG, enable Global Tab-Line mode if ARG is positive;
-otherwise, disable it. If called from Lisp, enable the mode if ARG is
-omitted or nil.
+otherwise, disable it.
-Tab-Line mode is enabled in all buffers where
-`tab-line-mode--turn-on' would do 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.
+
+Tab-Line mode is enabled in all buffers where `tab-line-mode--turn-on'
+would do it.
See `tab-line-mode' for more information on Tab-Line mode.
@@ -32653,7 +33140,9 @@ table's rectangle structure.
Move point forward to the beginning of the next cell.
With argument ARG, do it ARG times;
a negative argument ARG = -N means move backward N cells.
-Do not specify NO-RECOGNIZE and UNRECOGNIZE. They are for internal use only.
+
+Do not specify NO-RECOGNIZE and UNRECOGNIZE. They are for
+internal use only.
Sample Cell Traveling Order (In Irregular Table Cases)
@@ -33209,7 +33698,7 @@ Shapes drop from the top of the screen, and the user has to move and
rotate the shape to fit in with those at the bottom of the screen so
as to form complete rows.
-tetris-mode keybindings:
+`tetris-mode' keybindings:
\\<tetris-mode-map>
\\[tetris-start-game] Start a new game of Tetris
\\[tetris-end-game] Terminate the current game
@@ -33590,7 +34079,7 @@ and also to be turned into Info files with \\[makeinfo-buffer] or
the `makeinfo' program. These files must be written in a very restricted and
modified version of TeX input format.
- Editing commands are like text-mode except that the syntax table is
+ Editing commands are like `text-mode' except that the syntax table is
set up so expression commands skip Texinfo bracket groups. To see
what the Info version of a region of the Texinfo file will look like,
use \\[makeinfo-region], which runs `makeinfo' on the current region.
@@ -33618,15 +34107,15 @@ updating menus and node pointers. These functions
Here are the functions:
- texinfo-update-node \\[texinfo-update-node]
- texinfo-every-node-update \\[texinfo-every-node-update]
- texinfo-sequential-node-update
+ `texinfo-update-node' \\[texinfo-update-node]
+ `texinfo-every-node-update' \\[texinfo-every-node-update]
+ `texinfo-sequential-node-update'
- texinfo-make-menu \\[texinfo-make-menu]
- texinfo-all-menus-update \\[texinfo-all-menus-update]
- texinfo-master-menu
+ `texinfo-make-menu' \\[texinfo-make-menu]
+ `texinfo-all-menus-update' \\[texinfo-all-menus-update]
+ `texinfo-master-menu'
- texinfo-indent-menu-description (column &optional region-p)
+ `texinfo-indent-menu-description' (column &optional region-p)
The `texinfo-column-for-description' variable specifies the column to
which menu descriptions are indented.
@@ -33727,17 +34216,35 @@ positions of the thing found.
Return the THING at point.
THING should be a symbol specifying a type of syntactic entity.
Possibilities include `symbol', `list', `sexp', `defun',
-`filename', `url', `email', `uuid', `word', `sentence', `whitespace',
-`line', `number', and `page'.
+`filename', `existing-filename', `url', `email', `uuid', `word',
+`sentence', `whitespace', `line', `number', and `page'.
When the optional argument NO-PROPERTIES is non-nil,
strip text properties from the return value.
+If the current buffer uses fields (see Info node `(elisp)Fields'),
+this function will narrow to the field before identifying the
+thing at point.
+
See the file `thingatpt.el' for documentation on how to define
a symbol as a valid THING.
\(fn THING &optional NO-PROPERTIES)" nil nil)
+(autoload 'bounds-of-thing-at-mouse "thingatpt" "\
+Determine start and end locations for THING at mouse click given by EVENT.
+Like `bounds-of-thing-at-point', but tries to use the position in EVENT
+where the mouse button is clicked to find the thing nearby.
+
+\(fn EVENT THING)" nil nil)
+
+(autoload 'thing-at-mouse "thingatpt" "\
+Return the THING at mouse click specified by EVENT.
+Like `thing-at-point', but tries to use the position in EVENT
+where the mouse button is clicked to find the thing nearby.
+
+\(fn EVENT THING &optional NO-PROPERTIES)" nil nil)
+
(autoload 'sexp-at-point "thingatpt" "\
Return the sexp at point, or nil if none is found." nil nil)
@@ -33849,15 +34356,17 @@ Compose Tibetan text the region BEG and END.
(autoload 'tibetan-decompose-region "tibet-util" "\
Decompose Tibetan text in the region FROM and TO.
-This is different from decompose-region because precomposed Tibetan characters
-are decomposed into normal Tibetan character sequences.
+This is different from `decompose-region' because precomposed
+Tibetan characters are decomposed into normal Tibetan character
+sequences.
\(fn FROM TO)" t nil)
(autoload 'tibetan-decompose-string "tibet-util" "\
Decompose Tibetan string STR.
-This is different from decompose-string because precomposed Tibetan characters
-are decomposed into normal Tibetan character sequences.
+This is different from `decompose-string' because precomposed
+Tibetan characters are decomposed into normal Tibetan character
+sequences.
\(fn STR)" nil nil)
@@ -33867,7 +34376,7 @@ See also the documentation of the function `tibetan-decompose-region'." t nil)
(autoload 'tibetan-compose-buffer "tibet-util" "\
Composes Tibetan character components in the buffer.
-See also docstring of the function tibetan-compose-region." t nil)
+See also docstring of the function `tibetan-compose-region'." t nil)
(autoload 'tibetan-post-read-conversion "tibet-util" "\
@@ -34006,7 +34515,7 @@ 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 `(default-value 'display-time-mode)'.
+evaluate `(default-value \\='display-time-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -34037,7 +34546,7 @@ point.
(autoload 'emacs-init-time "time" "\
Return a string giving the duration of the Emacs initialization.
-FORMAT is a string to format the result, using `format'. If nil,
+FORMAT is a string to format the result, using `format'. If nil,
the default format \"%f seconds\" is used.
\(fn &optional FORMAT)" t nil)
@@ -34153,7 +34662,7 @@ Convert the time interval in seconds to a short string.
(put 'time-stamp-time-zone 'safe-local-variable 'time-stamp-zone-type-p)
(autoload 'time-stamp-zone-type-p "time-stamp" "\
-Return whether or not ZONE is of the correct type for a timezone rule.
+Return non-nil if ZONE is of the correct type for a timezone rule.
Valid ZONE values are described in the documentation of `format-time-string'.
\(fn ZONE)" nil nil)
@@ -34165,25 +34674,37 @@ Valid ZONE values are described in the documentation of `format-time-string'.
(put 'time-stamp-pattern 'safe-local-variable 'stringp)
(autoload 'time-stamp "time-stamp" "\
-Update the time stamp string(s) in the buffer.
-A template in a file can be automatically updated with a new time stamp
-every time you save the file. Add this line to your init file:
- (add-hook \\='before-save-hook \\='time-stamp)
-or customize option `before-save-hook'.
-Normally the template must appear in the first 8 lines of a file and
-look like one of the following:
+Update any time stamp string(s) in the buffer.
+This function looks for a time stamp template and updates it with
+the current date, time, and/or other info.
+
+The template, which you manually create on one of the first 8 lines
+of the file before running this function, by default can look like
+one of the following (your choice):
Time-stamp: <>
Time-stamp: \" \"
-The time stamp is written between the brackets or quotes:
+This function writes the current time between the brackets or quotes,
+by default formatted like this:
Time-stamp: <2020-08-07 17:10:21 gildea>
-The time stamp is updated only if the variable
-`time-stamp-active' is non-nil.
-The format of the time stamp is set by the variable
-`time-stamp-pattern' or `time-stamp-format'.
-The variables `time-stamp-pattern', `time-stamp-line-limit',
-`time-stamp-start', `time-stamp-end', `time-stamp-count', and
-`time-stamp-inserts-lines' control finding the template." t nil)
+Although you can run this function manually to update a time stamp
+once, usually you want automatic time stamp updating.
+
+A time stamp can be automatically updated with current information
+every time you save a file. To enable time-stamping for all files,
+customize option `before-save-hook' or add this line to your init file:
+ (add-hook \\='before-save-hook \\='time-stamp)
+
+To enable automatic time-stamping for only a specific file, add
+this line to a local variables list near the end of the file:
+ eval: (add-hook \\='before-save-hook \\='time-stamp nil t)
+
+If the file has no time-stamp template, this function does nothing.
+
+You can set `time-stamp-pattern' in a file's local variables list
+to customize the information in the time stamp and where it is written.
+
+The time stamp is updated only if `time-stamp-active' is non-nil." t nil)
(autoload 'time-stamp-toggle-active "time-stamp" "\
Toggle `time-stamp-active', setting whether \\[time-stamp] updates a buffer.
@@ -34219,6 +34740,9 @@ updating. With prefix ARG, turn mode line display on if and only
if ARG is positive. Returns the new status of timeclock mode line
display (non-nil means on).
+If using a customized `timeclock-workday' value, this should be
+set before switching this mode on.
+
\(fn &optional ARG)" t nil)
(autoload 'timeclock-in "timeclock" "\
@@ -34680,7 +35204,7 @@ It must be supported by libarchive(3).")
Regular expression matching archive file names." '(concat "\\`" "\\(" ".+" "\\." (regexp-opt tramp-archive-suffixes) "\\(?:" "\\." (regexp-opt tramp-archive-compression-suffixes) "\\)*" "\\)" "\\(" "/" ".*" "\\)" "\\'"))
(defun tramp-archive-autoload-file-name-handler (operation &rest args) "\
-Load Tramp archive file name handler, and perform OPERATION." (when tramp-archive-enabled (let ((default-directory temporary-file-directory) (tramp-archive-autoload t)) tramp-archive-autoload (apply #'tramp-autoload-file-name-handler operation args))))
+Load Tramp archive file name handler, and perform OPERATION." (defvar tramp-archive-autoload) (when tramp-archive-enabled (let ((default-directory temporary-file-directory) (tramp-archive-autoload t)) (apply #'tramp-autoload-file-name-handler operation args))))
(defun tramp-register-archive-file-name-handler nil "\
Add archive file name handler to `file-name-handler-alist'." (when tramp-archive-enabled (add-to-list 'file-name-handler-alist (cons (tramp-archive-autoload-file-name-regexp) #'tramp-archive-autoload-file-name-handler)) (put #'tramp-archive-autoload-file-name-handler 'safe-magic t)))
@@ -34711,7 +35235,7 @@ Add archive file name handler to `file-name-handler-alist'." (when tramp-archive
;;;;;; 0))
;;; Generated autoloads from net/tramp-compat.el
-(register-definition-prefixes "tramp-compat" '("tramp-"))
+(register-definition-prefixes "tramp-compat" '("tramp-compat-"))
;;;***
@@ -34797,7 +35321,7 @@ Add archive file name handler to `file-name-handler-alist'." (when tramp-archive
;;;### (autoloads nil "trampver" "net/trampver.el" (0 0 0 0))
;;; Generated autoloads from net/trampver.el
-(push (purecopy '(tramp 2 5 2 -1)) package--builtin-versions)
+(push (purecopy '(tramp 2 6 0 -1)) package--builtin-versions)
(register-definition-prefixes "trampver" '("tramp-"))
@@ -34860,7 +35384,7 @@ See info node `(transient)Modifying Existing Transients'.
(function-put 'transient-remove-suffix 'lisp-indent-function 'defun)
-(register-definition-prefixes "transient" '("transient-"))
+(register-definition-prefixes "transient" '("magit--fit-window-to-buffer" "transient-"))
;;;***
@@ -34985,7 +35509,7 @@ 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 `(default-value 'type-break-mode)'.
+evaluate `(default-value \\='type-break-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -35120,65 +35644,25 @@ You might need to set `uce-mail-reader' before using this.
;;;;;; (0 0 0 0))
;;; Generated autoloads from international/ucs-normalize.el
-(autoload 'ucs-normalize-NFD-region "ucs-normalize" "\
-Normalize the current region by the Unicode NFD.
-
-\(fn FROM TO)" t nil)
-
-(autoload 'ucs-normalize-NFD-string "ucs-normalize" "\
-Normalize the string STR by the Unicode NFD.
-
-\(fn STR)" nil nil)
-
-(autoload 'ucs-normalize-NFC-region "ucs-normalize" "\
-Normalize the current region by the Unicode NFC.
-
-\(fn FROM TO)" t nil)
-
-(autoload 'ucs-normalize-NFC-string "ucs-normalize" "\
-Normalize the string STR by the Unicode NFC.
-
-\(fn STR)" nil nil)
-
-(autoload 'ucs-normalize-NFKD-region "ucs-normalize" "\
-Normalize the current region by the Unicode NFKD.
-
-\(fn FROM TO)" t nil)
-
-(autoload 'ucs-normalize-NFKD-string "ucs-normalize" "\
-Normalize the string STR by the Unicode NFKD.
-
-\(fn STR)" nil nil)
-
-(autoload 'ucs-normalize-NFKC-region "ucs-normalize" "\
-Normalize the current region by the Unicode NFKC.
-
-\(fn FROM TO)" t nil)
-
-(autoload 'ucs-normalize-NFKC-string "ucs-normalize" "\
-Normalize the string STR by the Unicode NFKC.
-
-\(fn STR)" nil nil)
-
-(autoload 'ucs-normalize-HFS-NFD-region "ucs-normalize" "\
-Normalize the current region by the Unicode NFD and Mac OS's HFS Plus.
-
-\(fn FROM TO)" t nil)
-
-(autoload 'ucs-normalize-HFS-NFD-string "ucs-normalize" "\
-Normalize the string STR by the Unicode NFD and Mac OS's HFS Plus.
+(autoload 'string-glyph-compose "ucs-normalize" "\
+Compose STRING according to the Unicode NFC.
+This returns a new string obtained by canonical decomposition
+of STRING (see `ucs-normalize-NFC-string') followed by canonical
+composition, a.k.a. the \"Unicode Normalization Form C\" of STRING.
+For instance:
-\(fn STR)" nil nil)
+ (string-glyph-compose \"Å\") => \"Å\"
-(autoload 'ucs-normalize-HFS-NFC-region "ucs-normalize" "\
-Normalize the current region by the Unicode NFC and Mac OS's HFS Plus.
+\(fn STRING)" nil nil)
-\(fn FROM TO)" t nil)
+(autoload 'string-glyph-decompose "ucs-normalize" "\
+Decompose STRING according to the Unicode NFD.
+This returns a new string that is the canonical decomposition of STRING,
+a.k.a. the \"Unicode Normalization Form D\" of STRING. For instance:
-(autoload 'ucs-normalize-HFS-NFC-string "ucs-normalize" "\
-Normalize the string STR by the Unicode NFC and Mac OS's HFS Plus.
+ (ucs-normalize-NFD-string \"Å\") => \"Å\"
-\(fn STR)" nil nil)
+\(fn STRING)" nil nil)
(register-definition-prefixes "ucs-normalize" '("ucs-normalize-" "utf-8-hfs"))
@@ -35306,8 +35790,7 @@ how long to wait for a response before giving up.
;;; Generated autoloads from url/url-auth.el
(autoload 'url-get-authentication "url-auth" "\
-Return an authorization string suitable for use in the WWW-Authenticate
-header in an HTTP/1.0 request.
+Return authorization string for the WWW-Authenticate header in HTTP/1.0 request.
URL is the url you are requesting authorization to. This can be either a
string representing the URL, or the parsed representation returned by
@@ -35508,7 +35991,9 @@ or call the function `url-handler-mode'.")
(custom-autoload 'url-handler-mode "url-handlers" nil)
(autoload 'url-handler-mode "url-handlers" "\
-Toggle using `url' library for URL filenames (URL Handler mode).
+Handle URLs as if they were file names throughout Emacs.
+After switching on this minor mode, Emacs file primitives handle
+URLs. For instance:
This is a minor mode. If called interactively, toggle the
`Url-Handler mode' mode. If the prefix argument is positive, enable
@@ -35519,11 +36004,17 @@ 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 `(default-value 'url-handler-mode)'.
+evaluate `(default-value \\='url-handler-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
+ (file-exists-p \"https://www.gnu.org/\")
+ => t
+
+and `C-x C-f https://www.gnu.org/ RET' will give you the HTML at
+that URL in a buffer.
+
\(fn &optional ARG)" t nil)
(autoload 'url-file-handler "url-handlers" "\
@@ -35909,7 +36400,7 @@ Given a QUERY in the form:
\(This is the same format as produced by `url-parse-query-string')
This will return a string
-\"key1=val1&key2=val2&key3=val1&key3=val2&key4&key5\". Keys may
+\"key1=val1&key2=val2&key3=val1&key3=val2&key4&key5\". Keys may
be strings or symbols; if they are symbols, the symbol name will
be used.
@@ -36035,7 +36526,7 @@ Report an ERROR that occurred while unlocking a file.
\(fn ERROR)" nil nil)
-(register-definition-prefixes "userlock" '("ask-user-about-" "file-" "userlock--"))
+(register-definition-prefixes "userlock" '("ask-user-about-" "file-" "userlock--check-content-unchanged"))
;;;***
@@ -36165,6 +36656,10 @@ For old-style locking-based version control systems, like RCS:
If every file is locked by you and unchanged, unlock them.
If every file is locked by someone else, offer to steal the lock.
+When using this command to register a new file (or files), it
+will automatically deduce which VC repository to register it
+with, using the most specific one.
+
\(fn VERBOSE)" t nil)
(autoload 'vc-register "vc" "\
@@ -36357,13 +36852,13 @@ Show the change log for BRANCH root in a window.
\(fn BRANCH)" t nil)
(autoload 'vc-log-incoming "vc" "\
-Show a log of changes that will be received with a pull operation from 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.
\(fn &optional REMOTE-LOCATION)" t nil)
(autoload 'vc-log-outgoing "vc" "\
-Show a log of changes that will be sent with a push operation to 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.
\(fn &optional REMOTE-LOCATION)" t nil)
@@ -36441,6 +36936,8 @@ To get a prompt, use a prefix argument.
\(fn FILE BACKEND)" t nil)
+(make-obsolete 'vc-switch-backend 'nil '"28.1")
+
(autoload 'vc-transfer-file "vc" "\
Transfer FILE to another version control system NEW-BACKEND.
If NEW-BACKEND has a higher precedence than FILE's current backend
@@ -36483,11 +36980,6 @@ log entries should be gathered.
\(fn &rest ARGS)" t nil)
-(autoload 'vc-branch-part "vc" "\
-Return the branch part of a revision number REV.
-
-\(fn REV)" nil nil)
-
(register-definition-prefixes "vc" '("vc-" "with-vc-properties"))
;;;***
@@ -36599,7 +37091,7 @@ These are the commands available for use in the file status buffer:
\(fn DIR &optional BACKEND)" t nil)
(autoload 'vc-dir-bookmark-jump "vc-dir" "\
-Provides the bookmark-jump behavior for a `vc-dir' buffer.
+Provide the `bookmark-jump' behavior for a `vc-dir' buffer.
This implements the `handler' function interface for the record
type returned by `vc-dir-bookmark-make-record'.
@@ -36822,7 +37314,7 @@ Key bindings:
;;;### (autoloads nil "verilog-mode" "progmodes/verilog-mode.el"
;;;;;; (0 0 0 0))
;;; Generated autoloads from progmodes/verilog-mode.el
-(push (purecopy '(verilog-mode 2021 4 12 188864585)) package--builtin-versions)
+(push (purecopy '(verilog-mode 2021 10 14 127365406)) package--builtin-versions)
(autoload 'verilog-mode "verilog-mode" "\
Major mode for editing Verilog code.
@@ -36935,9 +37427,12 @@ Some other functions are:
\\[verilog-sk-repeat] Insert a repeat (..) begin .. end block.
\\[verilog-sk-specify] Insert a specify .. endspecify block.
\\[verilog-sk-task] Insert a task .. begin .. end endtask block.
- \\[verilog-sk-while] Insert a while (...) begin .. end block, prompting for details.
- \\[verilog-sk-casex] Insert a casex (...) item: begin.. end endcase block, prompting for details.
- \\[verilog-sk-casez] Insert a casez (...) item: begin.. end endcase block, prompting for details.
+ \\[verilog-sk-while] Insert a while (...) begin .. end block,
+ prompting for details.
+ \\[verilog-sk-casex] Insert a casex (...) item: begin.. end endcase block,
+ prompting for details.
+ \\[verilog-sk-casez] Insert a casez (...) item: begin.. end endcase block,
+ prompting for details.
\\[verilog-sk-if] Insert an if (..) begin .. end block.
\\[verilog-sk-else-if] Insert an else if (..) begin .. end block.
\\[verilog-sk-comment] Insert a comment block.
@@ -37328,7 +37823,7 @@ Usage:
`vhdl-project-alist'.
- SPECIAL MENUES:
+ SPECIAL MENUS:
As an alternative to the speedbar, an index menu can be added (set
option `vhdl-index-menu' to non-nil) or made accessible as a mouse menu
(e.g. add \"(global-set-key [S-down-mouse-3] \\='imenu)\" to your start-up
@@ -37836,7 +38331,7 @@ Toggle Viper on/off.
If Viper is enabled, turn it off. Otherwise, turn it on." t nil)
(autoload 'viper-mode "viper" "\
-Turn on Viper emulation of Vi in Emacs. See Info node `(viper)Top'." t nil)
+Turn on Viper emulation of Vi in Emacs. See Info node `(viper)Top'." t nil)
(register-definition-prefixes "viper" '("set-viper-state-in-major-mode" "this-major-mode-requires-vi-state" "viper-"))
@@ -38087,7 +38582,7 @@ 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 `(default-value 'which-function-mode)'.
+evaluate `(default-value \\='which-function-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -38126,6 +38621,9 @@ disabled.
See also `whitespace-style', `whitespace-newline' and
`whitespace-display-mappings'.
+This mode uses a number of faces to visualize the whitespace; see
+the customization group `whitespace' for details.
+
\(fn &optional ARG)" t nil)
(autoload 'whitespace-newline-mode "whitespace" "\
@@ -38176,7 +38674,7 @@ 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 `(default-value 'global-whitespace-mode)'.
+evaluate `(default-value \\='global-whitespace-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -38208,7 +38706,7 @@ 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 `(default-value 'global-whitespace-newline-mode)'.
+evaluate `(default-value \\='global-whitespace-newline-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -38707,28 +39205,28 @@ Default value of MODIFIERS is `shift-meta'.
(autoload 'windmove-delete-left "windmove" "\
Delete the window to the left of the current one.
-If prefix ARG is `C-u', delete the selected window and
+If prefix ARG is \\[universal-argument], delete the selected window and
select the window that was to the left of the current one.
\(fn &optional ARG)" t nil)
(autoload 'windmove-delete-up "windmove" "\
Delete the window above the current one.
-If prefix ARG is `C-u', delete the selected window and
+If prefix ARG is \\[universal-argument], delete the selected window and
select the window that was above the current one.
\(fn &optional ARG)" t nil)
(autoload 'windmove-delete-right "windmove" "\
Delete the window to the right of the current one.
-If prefix ARG is `C-u', delete the selected window and
+If prefix ARG is \\[universal-argument], delete the selected window and
select the window that was to the right of the current one.
\(fn &optional ARG)" t nil)
(autoload 'windmove-delete-down "windmove" "\
Delete the window below the current one.
-If prefix ARG is `C-u', delete the selected window and
+If prefix ARG is \\[universal-argument], delete the selected window and
select the window that was below the current one.
\(fn &optional ARG)" t nil)
@@ -38739,9 +39237,9 @@ Keys are bound to commands that delete windows in the specified
direction. Keybindings are of the form PREFIX MODIFIERS-{left,right,up,down},
where PREFIX is a prefix key and MODIFIERS is either a list of modifiers or
a single modifier.
-If PREFIX is `none', no prefix is used. If MODIFIERS is `none', the keybindings
-are directly bound to the arrow keys.
-Default value of PREFIX is `C-x' and MODIFIERS is `shift'.
+If PREFIX is `none', no prefix is used. If MODIFIERS is `none',
+the keybindings are directly bound to the arrow keys.
+Default value of PREFIX is \\`C-x' and MODIFIERS is `shift'.
\(fn &optional PREFIX MODIFIERS)" t nil)
@@ -38798,7 +39296,7 @@ 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 `(default-value 'winner-mode)'.
+evaluate `(default-value \\='winner-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -38964,15 +39462,24 @@ If LIMIT is non-nil, then do not consider characters beyond LIMIT.
;;;### (autoloads nil "xref" "progmodes/xref.el" (0 0 0 0))
;;; Generated autoloads from progmodes/xref.el
-(push (purecopy '(xref 1 1 0)) package--builtin-versions)
+(push (purecopy '(xref 1 3 2)) package--builtin-versions)
(autoload 'xref-find-backend "xref" nil nil nil)
-(autoload 'xref-pop-marker-stack "xref" "\
-Pop back to where \\[xref-find-definitions] was last invoked." t nil)
+(define-obsolete-function-alias 'xref-pop-marker-stack #'xref-go-back "29.1")
+
+(autoload 'xref-go-back "xref" "\
+Go back to the previous position in xref history.
+To undo, use \\[xref-go-forward]." t nil)
+
+(autoload 'xref-go-forward "xref" "\
+Got to the point where a previous \\[xref-go-back] was invoked." t nil)
(autoload 'xref-marker-stack-empty-p "xref" "\
-Return t if the marker stack is empty; nil otherwise." nil nil)
+Whether the xref back-history is empty." nil nil)
+
+(autoload 'xref-forward-history-empty-p "xref" "\
+Whether the xref forward-history is empty." nil nil)
(autoload 'xref-find-definitions "xref" "\
Find the definition of the identifier at point.
@@ -38984,6 +39491,8 @@ definition for IDENTIFIER, display it in the selected window.
Otherwise, display the list of the possible definitions in a
buffer where the user can select from the list.
+Use \\[xref-go-back] to return back to where you invoked this command.
+
\(fn IDENTIFIER)" t nil)
(autoload 'xref-find-definitions-other-window "xref" "\
@@ -39012,13 +39521,22 @@ This command is intended to be bound to a mouse event.
\(fn EVENT)" t nil)
+(autoload 'xref-find-references-at-mouse "xref" "\
+Find references to the identifier at or around mouse click.
+This command is intended to be bound to a mouse event.
+
+\(fn EVENT)" t nil)
+
(autoload 'xref-find-apropos "xref" "\
Find all meaningful symbols that match PATTERN.
The argument has the same meaning as in `apropos'.
+See `tags-apropos-additional-actions' for how to augment the
+output of this command when the backend is etags.
\(fn PATTERN)" t nil)
(define-key esc-map "." #'xref-find-definitions)
- (define-key esc-map "," #'xref-pop-marker-stack)
+ (define-key esc-map "," #'xref-go-back)
+ (define-key esc-map [?\C-,] #'xref-go-forward)
(define-key esc-map "?" #'xref-find-references)
(define-key esc-map [?\C-.] #'xref-find-apropos)
(define-key ctl-x-4-map "." #'xref-find-definitions-other-window)
@@ -39048,6 +39566,9 @@ Find all matches for REGEXP in FILES.
Return a list of xref values.
FILES must be a list of absolute file names.
+See `xref-search-program' and `xref-search-program-alist' for how
+to control which program to use when looking for matches.
+
\(fn REGEXP FILES)" nil nil)
(register-definition-prefixes "xref" '("xref-"))
@@ -39093,7 +39614,7 @@ 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 `(default-value 'xterm-mouse-mode)'.
+evaluate `(default-value \\='xterm-mouse-mode)'.
The mode's hook is called both when the mode is enabled and when it is
disabled.
@@ -39125,6 +39646,33 @@ Interactively, URL defaults to the string looking like a url around point.
;;;***
+;;;### (autoloads nil "yank-media" "yank-media.el" (0 0 0 0))
+;;; Generated autoloads from yank-media.el
+
+(autoload 'yank-media "yank-media" "\
+Yank media (images, HTML and the like) from the clipboard.
+This command depends on the current major mode having support for
+accepting the media type. The mode has to register itself using
+the `yank-media-handler' mechanism.
+
+Also see `yank-media-types' for a command that lets you explore
+all the different selection types." t nil)
+
+(autoload 'yank-media-handler "yank-media" "\
+Register HANDLER for dealing with `yank-media' actions for TYPES.
+TYPES should be a MIME media type symbol, a regexp, or a list
+that can contain both symbols and regexps.
+
+HANDLER is a function that will be called with two arguments: The
+MIME type (a symbol on the form `image/png') and the selection
+data (a string).
+
+\(fn TYPES HANDLER)" nil nil)
+
+(register-definition-prefixes "yank-media" '("yank-media-"))
+
+;;;***
+
;;;### (autoloads nil "yenc" "mail/yenc.el" (0 0 0 0))
;;; Generated autoloads from mail/yenc.el
@@ -39159,12 +39707,10 @@ Zone out, completely." t nil)
;;;### (autoloads nil nil ("abbrev.el" "bindings.el" "buff-menu.el"
;;;;;; "button.el" "calc/calc-aent.el" "calc/calc-embed.el" "calc/calc-misc.el"
-;;;;;; "calc/calc-yank.el" "calendar/cal-loaddefs.el" "calendar/diary-loaddefs.el"
-;;;;;; "calendar/hol-loaddefs.el" "case-table.el" "cedet/ede/base.el"
-;;;;;; "cedet/ede/config.el" "cedet/ede/cpp-root.el" "cedet/ede/custom.el"
-;;;;;; "cedet/ede/dired.el" "cedet/ede/emacs.el" "cedet/ede/files.el"
-;;;;;; "cedet/ede/generic.el" "cedet/ede/linux.el" "cedet/ede/locate.el"
-;;;;;; "cedet/ede/make.el" "cedet/ede/shell.el" "cedet/ede/speedbar.el"
+;;;;;; "calc/calc-yank.el" "case-table.el" "cedet/ede/cpp-root.el"
+;;;;;; "cedet/ede/custom.el" "cedet/ede/dired.el" "cedet/ede/emacs.el"
+;;;;;; "cedet/ede/files.el" "cedet/ede/generic.el" "cedet/ede/linux.el"
+;;;;;; "cedet/ede/locate.el" "cedet/ede/make.el" "cedet/ede/speedbar.el"
;;;;;; "cedet/ede/system.el" "cedet/ede/util.el" "cedet/semantic/analyze.el"
;;;;;; "cedet/semantic/analyze/complete.el" "cedet/semantic/analyze/refs.el"
;;;;;; "cedet/semantic/bovine.el" "cedet/semantic/bovine/c-by.el"
@@ -39196,15 +39742,16 @@ Zone out, completely." t nil)
;;;;;; "cedet/srecode/insert.el" "cedet/srecode/java.el" "cedet/srecode/map.el"
;;;;;; "cedet/srecode/mode.el" "cedet/srecode/srt-wy.el" "cedet/srecode/srt.el"
;;;;;; "cedet/srecode/template.el" "cedet/srecode/texi.el" "composite.el"
-;;;;;; "cus-face.el" "cus-start.el" "custom.el" "dired-aux.el" "dired-x.el"
-;;;;;; "electric.el" "emacs-lisp/backquote.el" "emacs-lisp/byte-run.el"
+;;;;;; "cus-face.el" "cus-load.el" "cus-start.el" "custom.el" "dired-aux.el"
+;;;;;; "dired-x.el" "electric.el" "emacs-lisp/backquote.el" "emacs-lisp/byte-run.el"
;;;;;; "emacs-lisp/cl-extra.el" "emacs-lisp/cl-macs.el" "emacs-lisp/cl-preloaded.el"
;;;;;; "emacs-lisp/cl-seq.el" "emacs-lisp/easymenu.el" "emacs-lisp/eieio-compat.el"
;;;;;; "emacs-lisp/eieio-custom.el" "emacs-lisp/eieio-opt.el" "emacs-lisp/float-sup.el"
;;;;;; "emacs-lisp/lisp-mode.el" "emacs-lisp/lisp.el" "emacs-lisp/macroexp.el"
-;;;;;; "emacs-lisp/map-ynp.el" "emacs-lisp/nadvice.el" "emacs-lisp/syntax.el"
-;;;;;; "emacs-lisp/timer.el" "env.el" "epa-hook.el" "erc/erc-autoaway.el"
-;;;;;; "erc/erc-button.el" "erc/erc-capab.el" "erc/erc-dcc.el" "erc/erc-desktop-notifications.el"
+;;;;;; "emacs-lisp/map-ynp.el" "emacs-lisp/nadvice.el" "emacs-lisp/shorthands.el"
+;;;;;; "emacs-lisp/syntax.el" "emacs-lisp/timer.el" "env.el" "epa-hook.el"
+;;;;;; "erc/erc-autoaway.el" "erc/erc-button.el" "erc/erc-capab.el"
+;;;;;; "erc/erc-compat.el" "erc/erc-dcc.el" "erc/erc-desktop-notifications.el"
;;;;;; "erc/erc-ezbounce.el" "erc/erc-fill.el" "erc/erc-identd.el"
;;;;;; "erc/erc-imenu.el" "erc/erc-join.el" "erc/erc-list.el" "erc/erc-log.el"
;;;;;; "erc/erc-match.el" "erc/erc-menu.el" "erc/erc-netsplit.el"
@@ -39218,12 +39765,24 @@ Zone out, completely." t nil)
;;;;;; "eshell/em-ls.el" "eshell/em-pred.el" "eshell/em-prompt.el"
;;;;;; "eshell/em-rebind.el" "eshell/em-script.el" "eshell/em-smart.el"
;;;;;; "eshell/em-term.el" "eshell/em-tramp.el" "eshell/em-unix.el"
-;;;;;; "eshell/em-xtra.el" "faces.el" "files.el" "font-core.el"
-;;;;;; "font-lock.el" "format.el" "frame.el" "help.el" "hfy-cmap.el"
-;;;;;; "ibuf-ext.el" "indent.el" "international/characters.el" "international/charscript.el"
-;;;;;; "international/cp51932.el" "international/eucjp-ms.el" "international/iso-transl.el"
+;;;;;; "eshell/em-xtra.el" "eshell/esh-groups.el" "faces.el" "files.el"
+;;;;;; "finder-inf.el" "font-core.el" "font-lock.el" "format.el"
+;;;;;; "frame.el" "help.el" "hfy-cmap.el" "ibuf-ext.el" "indent.el"
+;;;;;; "international/characters.el" "international/charprop.el"
+;;;;;; "international/charscript.el" "international/cp51932.el"
+;;;;;; "international/emoji-labels.el" "international/emoji-zwj.el"
+;;;;;; "international/eucjp-ms.el" "international/iso-transl.el"
;;;;;; "international/mule-cmds.el" "international/mule-conf.el"
-;;;;;; "international/mule.el" "isearch.el" "jit-lock.el" "jka-cmpr-hook.el"
+;;;;;; "international/mule.el" "international/uni-bidi.el" "international/uni-brackets.el"
+;;;;;; "international/uni-category.el" "international/uni-combining.el"
+;;;;;; "international/uni-comment.el" "international/uni-decimal.el"
+;;;;;; "international/uni-decomposition.el" "international/uni-digit.el"
+;;;;;; "international/uni-lowercase.el" "international/uni-mirrored.el"
+;;;;;; "international/uni-name.el" "international/uni-numeric.el"
+;;;;;; "international/uni-old-name.el" "international/uni-special-lowercase.el"
+;;;;;; "international/uni-special-titlecase.el" "international/uni-special-uppercase.el"
+;;;;;; "international/uni-titlecase.el" "international/uni-uppercase.el"
+;;;;;; "isearch.el" "jit-lock.el" "jka-cmpr-hook.el" "keymap.el"
;;;;;; "language/burmese.el" "language/cham.el" "language/chinese.el"
;;;;;; "language/cyrillic.el" "language/czech.el" "language/english.el"
;;;;;; "language/ethiopic.el" "language/european.el" "language/georgian.el"
@@ -39254,20 +39813,19 @@ Zone out, completely." t nil)
;;;;;; "loadup.el" "mail/blessmail.el" "mail/rmailedit.el" "mail/rmailkwd.el"
;;;;;; "mail/rmailmm.el" "mail/rmailmsc.el" "mail/rmailsort.el"
;;;;;; "mail/rmailsum.el" "mail/undigest.el" "menu-bar.el" "mh-e/mh-gnus.el"
-;;;;;; "mh-e/mh-loaddefs.el" "minibuffer.el" "mouse.el" "net/tramp-loaddefs.el"
-;;;;;; "newcomment.el" "obarray.el" "org/ob-core.el" "org/ob-lob.el"
-;;;;;; "org/ob-matlab.el" "org/ob-tangle.el" "org/ob.el" "org/ol-bbdb.el"
-;;;;;; "org/ol-irc.el" "org/ol.el" "org/org-archive.el" "org/org-attach.el"
-;;;;;; "org/org-clock.el" "org/org-colview.el" "org/org-compat.el"
-;;;;;; "org/org-datetree.el" "org/org-duration.el" "org/org-element.el"
-;;;;;; "org/org-feed.el" "org/org-footnote.el" "org/org-goto.el"
-;;;;;; "org/org-id.el" "org/org-indent.el" "org/org-install.el"
+;;;;;; "minibuffer.el" "mouse.el" "newcomment.el" "obarray.el" "org/ob-core.el"
+;;;;;; "org/ob-lob.el" "org/ob-matlab.el" "org/ob-tangle.el" "org/ob.el"
+;;;;;; "org/ol-bbdb.el" "org/ol-irc.el" "org/ol.el" "org/org-archive.el"
+;;;;;; "org/org-attach.el" "org/org-clock.el" "org/org-colview.el"
+;;;;;; "org/org-compat.el" "org/org-datetree.el" "org/org-duration.el"
+;;;;;; "org/org-element.el" "org/org-feed.el" "org/org-footnote.el"
+;;;;;; "org/org-goto.el" "org/org-id.el" "org/org-indent.el" "org/org-install.el"
;;;;;; "org/org-keys.el" "org/org-lint.el" "org/org-list.el" "org/org-macs.el"
;;;;;; "org/org-mobile.el" "org/org-num.el" "org/org-plot.el" "org/org-refile.el"
;;;;;; "org/org-table.el" "org/org-timer.el" "org/ox-ascii.el" "org/ox-beamer.el"
;;;;;; "org/ox-html.el" "org/ox-icalendar.el" "org/ox-latex.el"
;;;;;; "org/ox-md.el" "org/ox-odt.el" "org/ox-org.el" "org/ox-publish.el"
-;;;;;; "org/ox-texinfo.el" "org/ox.el" "progmodes/elisp-mode.el"
+;;;;;; "org/ox-texinfo.el" "org/ox.el" "paren.el" "progmodes/elisp-mode.el"
;;;;;; "progmodes/prog-mode.el" "ps-mule.el" "register.el" "replace.el"
;;;;;; "rfn-eshadow.el" "select.el" "simple.el" "startup.el" "subdirs.el"
;;;;;; "subr.el" "tab-bar.el" "textmodes/fill.el" "textmodes/makeinfo.el"
diff --git a/lisp/leim/quail/hangul.el b/lisp/leim/quail/hangul.el
index c03e86b33c0..d069b5b68e1 100644
--- a/lisp/leim/quail/hangul.el
+++ b/lisp/leim/quail/hangul.el
@@ -429,7 +429,7 @@ When a Korean input method is off, convert the following hangul character."
(hangul3-input-method-jong char))
(t
(setq hangul-queue (make-vector 6 0))
- (insert (decode-char 'ucs char))
+ (insert char)
(move-overlay quail-overlay (point) (point))))))
(defun hangul3-input-method (key)
@@ -476,7 +476,7 @@ When a Korean input method is off, convert the following hangul character."
(hangul3-input-method-jong char))
(t
(setq hangul-queue (make-vector 6 0))
- (insert (decode-char 'ucs char))
+ (insert char)
(move-overlay quail-overlay (point) (point))))))
(defun hangul390-input-method (key)
diff --git a/lisp/leim/quail/ipa.el b/lisp/leim/quail/ipa.el
index c25687574ed..ba6ea938425 100644
--- a/lisp/leim/quail/ipa.el
+++ b/lisp/leim/quail/ipa.el
@@ -278,10 +278,10 @@ string."
(list
(apply #'vector
(mapcar
- #'(lambda (entry)
- (cl-assert (char-or-string-p entry) t)
- (format "%s%s" to-prepend
- (if (integerp entry) (string entry) entry)))
+ (lambda (entry)
+ (cl-assert (char-or-string-p entry) t)
+ (format "%s%s" to-prepend
+ (if (integerp entry) (string entry) entry)))
quail-keymap))))
(defun ipa-x-sampa-underscore-implosive (input-string length)
diff --git a/lisp/leim/quail/latin-post.el b/lisp/leim/quail/latin-post.el
index 8329fff82ed..0e1afba1a34 100644
--- a/lisp/leim/quail/latin-post.el
+++ b/lisp/leim/quail/latin-post.el
@@ -215,7 +215,15 @@ Doubling the postfix separates the letter and postfix: e.g. a\\='\\=' -> a\\='
others | / | s/ -> ß
Doubling the postfix separates the letter and postfix: e.g. a\\='\\=' -> a\\='
-" nil t nil nil nil nil nil nil nil nil t)
+"
+ '(("\C-?" . quail-delete-last-char)
+ (">" . quail-next-translation)
+ ("\C-f" . quail-next-translation)
+ ([right] . quail-next-translation)
+ ("<" . quail-prev-translation)
+ ("\C-b" . quail-prev-translation)
+ ([left] . quail-prev-translation))
+ t nil nil nil nil nil nil nil nil t)
(quail-define-rules
("A'" ?Á)
@@ -246,9 +254,9 @@ Doubling the postfix separates the letter and postfix: e.g. a\\='\\=' -> a\\='
("R'" ?Ŕ)
("R~" ?Ř)
("S'" ?Ś)
- ("S," ?Ş)
+ ("S," "ŞȘ") ; the second variant is for Romanian
("S~" ?Š)
- ("T," ?Ţ)
+ ("T," "ŢȚ") ; the second variant is for Romanian
("T~" ?Ť)
("U'" ?Ú)
("U:" ?Ű)
@@ -286,10 +294,10 @@ Doubling the postfix separates the letter and postfix: e.g. a\\='\\=' -> a\\='
("r'" ?ŕ)
("r~" ?ř)
("s'" ?ś)
- ("s," ?ş)
+ ("s," "şș") ; the second variant is for Romanian
("s/" ?ß)
("s~" ?š)
- ("t," ?ţ)
+ ("t," "ţț") ; the second variant is for Romanian
("t~" ?ť)
("u'" ?ú)
("u:" ?ű)
diff --git a/lisp/leim/quail/latin-pre.el b/lisp/leim/quail/latin-pre.el
index 3b9c942a8c1..3492de5fbae 100644
--- a/lisp/leim/quail/latin-pre.el
+++ b/lisp/leim/quail/latin-pre.el
@@ -497,7 +497,15 @@ Key translation rules are:
cedilla | \\=` | \\=`c -> ç \\=`e -> ?ę
misc | \\=' \\=` ~ | \\='d -> đ \\=`l -> ł \\=`z -> ż ~o -> ő ~u -> ű
symbol | ~ | \\=`. -> ˙ ~~ -> ˘ ~. -> ?¸
-" nil t nil nil nil nil nil nil nil nil t)
+"
+ '(("\C-?" . quail-delete-last-char)
+ (">" . quail-next-translation)
+ ("\C-f" . quail-next-translation)
+ ([right] . quail-next-translation)
+ ("<" . quail-prev-translation)
+ ("\C-b" . quail-prev-translation)
+ ([left] . quail-prev-translation))
+ t nil nil nil nil nil nil nil nil t)
(quail-define-rules
("'A" ?Á)
@@ -532,15 +540,15 @@ Key translation rules are:
("`C" ?Ç)
("`E" ?Ę)
("`L" ?Ł)
- ("`S" ?Ş)
- ("`T" ?Ţ)
+ ("`S" "ŞȘ")
+ ("`T" "ŢȚ") ; the second variant is for Romanian
("`Z" ?Ż)
("`a" ?ą)
("`l" ?ł)
("`c" ?ç)
("`e" ?ę)
- ("`s" ?ş)
- ("`t" ?ţ)
+ ("`s" "şș")
+ ("`t" "ţț") ; the second variant is for Romanian
("`z" ?ż)
("``" ?Ş)
("`." ?˙)
diff --git a/lisp/leim/quail/persian.el b/lisp/leim/quail/persian.el
index cb1f6e3c78b..d058cfa61c4 100644
--- a/lisp/leim/quail/persian.el
+++ b/lisp/leim/quail/persian.el
@@ -3,7 +3,7 @@
;; Copyright (C) 2011-2021 Free Software Foundation, Inc.
;; Author: Mohsen BANAN <libre@mohsen.1.banan.byname.net>
-;; X-URL: http://mohsen.1.banan.byname.net/contact
+;; URL: http://mohsen.1.banan.byname.net/contact
;; Keywords: multilingual, input method, Farsi, Persian, keyboard
diff --git a/lisp/leim/quail/sami.el b/lisp/leim/quail/sami.el
index 6c9b2d99cc0..0f0bae9eca8 100644
--- a/lisp/leim/quail/sami.el
+++ b/lisp/leim/quail/sami.el
@@ -33,7 +33,7 @@
;; - skolt-sami-prefix
;; - kildin-sami-prefix
-;;; Code
+;;; Code:
(require 'quail)
diff --git a/lisp/leim/quail/vnvni.el b/lisp/leim/quail/vnvni.el
index faccc0afc53..57e0dfd8205 100644
--- a/lisp/leim/quail/vnvni.el
+++ b/lisp/leim/quail/vnvni.el
@@ -303,3 +303,5 @@ and postfix: E66 -> E6, a55 -> a5, etc.
;; Local Variables:
;; coding: utf-8
;; End:
+
+;;; vnvni.el ends here
diff --git a/lisp/linum.el b/lisp/linum.el
index c78f596d768..1e029e508ef 100644
--- a/lisp/linum.el
+++ b/lisp/linum.el
@@ -28,6 +28,9 @@
;;
;; Toggle display of line numbers with M-x linum-mode. To enable
;; line numbering in all buffers, use M-x global-linum-mode.
+;;
+;; Consider using native line numbers instead:
+;; M-x display-line-numbers-mode
;;; Code:
diff --git a/lisp/loadhist.el b/lisp/loadhist.el
index 0b12bdad058..4a7946a212b 100644
--- a/lisp/loadhist.el
+++ b/lisp/loadhist.el
@@ -168,8 +168,7 @@ documentation of `unload-feature' for details.")
;; So we use this auxiliary variable to keep track of the last (t . SYMBOL)
;; that occurred.
(defvar loadhist--restore-autoload nil
- "If non-nil, this is a symbol for which we should
-restore a previous autoload if possible.")
+ "If non-nil, is a symbol for which to try to restore a previous autoload.")
(cl-defmethod loadhist-unload-element ((x (head t)))
(setq loadhist--restore-autoload (cdr x)))
diff --git a/lisp/loadup.el b/lisp/loadup.el
index 158c02eceaa..b87c0550fc5 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -131,6 +131,7 @@
(load "emacs-lisp/byte-run")
(load "emacs-lisp/backquote")
(load "subr")
+(load "keymap")
;; Do it after subr, since both after-load-functions and add-hook are
;; implemented in subr.el.
@@ -275,7 +276,6 @@
(load "textmodes/paragraphs")
(load "progmodes/prog-mode")
(load "emacs-lisp/lisp-mode")
-(load "progmodes/elisp-mode")
(load "textmodes/text-mode")
(load "textmodes/fill")
(load "newcomment")
@@ -303,6 +303,11 @@
(load "term/common-win")
(load "term/x-win")))
+(if (featurep 'haiku)
+ (progn
+ (load "term/common-win")
+ (load "term/haiku-win")))
+
(if (or (eq system-type 'windows-nt)
(featurep 'w32))
(progn
@@ -335,10 +340,24 @@
(load "international/mule-util")
(load "international/ucs-normalize")
(load "term/ns-win"))))
+(if (featurep 'pgtk)
+ (progn
+ (load "term/common-win")
+ ;; Don't load ucs-normalize.el unless uni-*.el files were
+ ;; already produced, because it needs uni-*.el files that might
+ ;; not be built early enough during bootstrap.
+ (load "term/pgtk-win")))
(if (fboundp 'x-create-frame)
;; Do it after loading term/foo-win.el since the value of the
;; mouse-wheel-*-event vars depends on those files being loaded or not.
(load "mwheel"))
+
+;; progmodes/elisp-mode.el must be after w32-fns.el, to avoid this:
+;;"Eager macro-expansion failure: (void-function w32-convert-standard-filename)"
+;; which happens while processing 'elisp-flymake-byte-compile', when
+;; elisp-mode.elc is outdated.
+(load "progmodes/elisp-mode")
+
;; Preload some constants and floating point functions.
(load "emacs-lisp/float-sup")
@@ -346,6 +365,10 @@
(load "vc/ediff-hook")
(load "uniquify")
(load "electric")
+(load "paren")
+
+(load "emacs-lisp/shorthands")
+
(load "emacs-lisp/eldoc")
(load "cus-start") ;Late to reduce customize-rogue (needs loaddefs.el anyway)
(if (not (eq system-type 'ms-dos))
@@ -520,7 +543,7 @@ lost after dumping")))
((equal dump-mode "dump") "emacs")
((equal dump-mode "bootstrap") "emacs")
((equal dump-mode "pbootstrap") "bootstrap-emacs.pdmp")
- (t (error "unrecognized dump mode %s" dump-mode)))))
+ (t (error "Unrecognized dump mode %s" dump-mode)))))
(when (and (featurep 'native-compile)
(equal dump-mode "pdump"))
;; Don't enable this before bootstrap is completed, as the
@@ -535,10 +558,13 @@ lost after dumping")))
(let (success)
(unwind-protect
(let ((tmp-dump-mode dump-mode)
- (dump-mode nil))
+ (dump-mode nil)
+ (lexical-binding nil))
(if (member tmp-dump-mode '("pdump" "pbootstrap"))
(dump-emacs-portable (expand-file-name output invocation-directory))
- (dump-emacs output "temacs")
+ (dump-emacs output (if (eq system-type 'ms-dos)
+ "temacs.exe"
+ "temacs"))
(message "%d pure bytes used" pure-bytes-used))
(setq success t))
(unless success
@@ -546,6 +572,7 @@ lost after dumping")))
(delete-file output)))))
;; Recompute NAME now, so that it isn't set when we dump.
(if (not (or (eq system-type 'ms-dos)
+ (eq system-type 'haiku) ;; BFS doesn't support hard links
;; Don't bother adding another name if we're just
;; building bootstrap-emacs.
(member dump-mode '("pbootstrap" "bootstrap"))))
diff --git a/lisp/locate.el b/lisp/locate.el
index c4dbe2af02b..6190fc6302a 100644
--- a/lisp/locate.el
+++ b/lisp/locate.el
@@ -25,7 +25,7 @@
;; Search a database of files and use dired commands on the result.
;;
;; Locate.el provides an interface to a program which searches a
-;; database of file names. By default, this program is the GNU locate
+;; database of file names. By default, this program is the GNU locate
;; command, but it could also be the BSD-style find command, or even a
;; user specified command.
;;
@@ -39,7 +39,7 @@
;; To use a more complicated expression, create a function which
;; takes a string (the name to find) as input and returns a list.
;; The first element should be the command to be executed, the remaining
-;; elements should be the arguments (including the name to find). Then put
+;; elements should be the arguments (including the name to find). Then put
;;
;; (setq locate-make-command-line 'my-locate-command-line)
;;
@@ -47,25 +47,25 @@
;; my-locate-command-line.
;;
;; You should make sure that whichever command you use works correctly
-;; from a shell prompt. GNU locate and BSD find expect the file databases
+;; from a shell prompt. GNU locate and BSD find expect the file databases
;; to either be in standard places or located via environment variables.
;; If the latter, make sure these environment variables are set in
-;; your emacs process.
+;; your Emacs process.
;;
;; Locate-mode assumes that each line output from the locate-command
;; consists exactly of a file name, possibly preceded or trailed by
-;; whitespace. If your file database has other information on the line (for
+;; whitespace. If your file database has other information on the line (for
;; example, the file size), you will need to redefine the function
;; `locate-get-file-positions' to return a list consisting of the first
;; character in the file name and the last character in the file name.
;;
;; To use locate-mode, simply type M-x locate and then the string
-;; you wish to find. You can use almost all of the dired commands in
+;; you wish to find. You can use almost all of the dired commands in
;; the resulting *Locate* buffer. It is worth noting that your commands
-;; do not, of course, affect the file database. For example, if you
+;; do not, of course, affect the file database. For example, if you
;; compress a file in the locate buffer, the actual file will be
;; compressed, but the entry in the file database will not be
-;; affected. Consequently, the database and the filesystem will be out
+;; affected. Consequently, the database and the filesystem will be out
;; of sync until the next time the database is updated.
;;
;; The command `locate-with-filter' keeps only lines matching a
diff --git a/lisp/ls-lisp.el b/lisp/ls-lisp.el
index 9041b9ac0f9..25d196392ab 100644
--- a/lisp/ls-lisp.el
+++ b/lisp/ls-lisp.el
@@ -283,6 +283,7 @@ are also supported; unsupported long options are silently ignored."
(funcall orig-fun
file switches wildcard full-directory-p)
;; We need the directory in order to find the right handler.
+ (setq switches (or switches ""))
(let ((handler (find-file-name-handler (expand-file-name file)
'insert-directory))
(orig-file file)
@@ -336,18 +337,7 @@ are also supported; unsupported long options are silently ignored."
(ls-lisp-insert-directory
file switches (ls-lisp-time-index switches)
nil full-directory-p))
- (signal (car err) (cdr err)))))
- ;; Try to insert the amount of free space.
- (save-excursion
- (goto-char (point-min))
- ;; First find the line to put it on.
- (when (re-search-forward "^total" nil t)
- (let ((available (get-free-disk-space ".")))
- (when available
- ;; Replace "total" with "total used", to avoid confusion.
- (replace-match "total used in directory")
- (end-of-line)
- (insert " available " available)))))))))
+ (signal (car err) (cdr err)))))))))
(advice-add 'insert-directory :around #'ls-lisp--insert-directory)
(defun ls-lisp-insert-directory
@@ -599,7 +589,7 @@ to a non-nil value."
"Return t if versioned string S1 should sort before versioned string S2.
Case is significant if `ls-lisp-ignore-case' is nil.
-This is the same as string-lessp (with the exception of case
+This is the same as `string-lessp' (with the exception of case
insensitivity), but sequences of digits are compared numerically,
as a whole, in the same manner as the `strverscmp' function available
in some standard C libraries does."
diff --git a/lisp/macros.el b/lisp/macros.el
index faa1f0bd35d..89e38abab2d 100644
--- a/lisp/macros.el
+++ b/lisp/macros.el
@@ -26,7 +26,7 @@
;; Extension commands for keyboard macros. These permit you to assign
;; a name to the last-defined keyboard macro, expand and insert the
-;; lisp corresponding to a macro, query the user from within a macro,
+;; Lisp corresponding to a macro, query the user from within a macro,
;; or apply a macro to each line in the reason.
;;; Code:
@@ -148,11 +148,16 @@ use this command, and then save the file."
;;;###autoload
(defun kbd-macro-query (flag)
"Query user during kbd macro execution.
- With prefix argument, enters recursive edit, reading keyboard
-commands even within a kbd macro. You can give different commands
-each time the macro executes.
- Without prefix argument, asks whether to continue running the macro.
+
+With prefix argument FLAG, enter recursive edit, reading
+keyboard commands even within a kbd macro. You can give
+different commands each time the macro executes.
+
+Without prefix argument, ask whether to continue running the
+macro.
+
Your options are: \\<query-replace-map>
+
\\[act] Finish this iteration normally and continue with the next.
\\[skip] Skip the rest of this iteration, and start the next.
\\[exit] Stop the macro entirely right now.
diff --git a/lisp/mail/blessmail.el b/lisp/mail/blessmail.el
index f380f0df290..23fddfd1679 100644
--- a/lisp/mail/blessmail.el
+++ b/lisp/mail/blessmail.el
@@ -27,7 +27,7 @@
;; which (on systems that need it) is used during installation
;; to give appropriate permissions to movemail.
;;
-;; It has to be done from lisp in order to be sure of getting the
+;; It has to be done from Lisp in order to be sure of getting the
;; correct value of rmail-spool-directory.
;;; Code:
diff --git a/lisp/mail/emacsbug.el b/lisp/mail/emacsbug.el
index 14c93f2fc8e..7c3f6ba5e6d 100644
--- a/lisp/mail/emacsbug.el
+++ b/lisp/mail/emacsbug.el
@@ -340,7 +340,7 @@ usually do not have translators for other languages.\n\n")))
(insert (format "\nFeatures:\n%s\n" features))
(fill-region (line-beginning-position 0) (point))
- (insert (format "\nMemory information:\n"))
+ (insert "\nMemory information:\n")
(pp (garbage-collect) (current-buffer))
;; This is so the user has to type something in order to send easily.
@@ -426,7 +426,7 @@ usually do not have translators for other languages.\n\n")))
(with-output-to-temp-buffer "*Bug Help*"
(princ (substitute-command-keys
(format "\
-You invoked the command M-x report-emacs-bug,
+You invoked the command \\[report-emacs-bug],
but you decided not to mail the bug report to the Emacs maintainers.
If you want to mail it to someone else instead,
diff --git a/lisp/mail/feedmail.el b/lisp/mail/feedmail.el
index cec573642ec..32edc292619 100644
--- a/lisp/mail/feedmail.el
+++ b/lisp/mail/feedmail.el
@@ -7,7 +7,7 @@
;; Author: Bill Carpenter <bill@carpenter.ORG>
;; Version: 11
;; Keywords: email, queue, mail, sendmail, message, spray, smtp, draft
-;; X-URL: <URL:http://www.carpenter.org/feedmail/feedmail.html>
+;; URL: http://www.carpenter.org/feedmail/feedmail.html
;;; Commentary:
@@ -47,7 +47,7 @@
;; A NOTE TO THOSE WHO WOULD CHANGE THIS CODE... Since it is PD,
;; you're within your rights to do whatever you want. If you do
;; publish a new version with your changes in it, please (1) insert
-;; lisp comments describing the changes, (2) insert lisp comments
+;; Lisp comments describing the changes, (2) insert Lisp comments
;; that clearly delimit where your changes are, (3) email me a copy
;; (I can't always consistently follow the relevant usenet groups),
;; and (4) use a version number that is based on the version you're
@@ -128,7 +128,7 @@
;; --- you can generate/modify an X-Mailer: message header
;;
;; After a long list of options below, you will find the function
-;; feedmail-send-it. Hers's the best way to use the stuff in this
+;; feedmail-send-it. Hers's the best way to use the stuff in this
;; file:
;;
;; Save this file as feedmail.el somewhere on your elisp loadpath;
@@ -157,7 +157,7 @@
;; If you are wondering how to send your messages to some SMTP server
;; (which is not really a feedmail-specific issue), you are probably
;; looking for smtpmail.el, and it is probably already present in your
-;; emacs installation. Look at smtpmail.el for how to set that up, and
+;; Emacs installation. Look at smtpmail.el for how to set that up, and
;; then do this to hook it into feedmail:
;;
;; (autoload 'feedmail-buffer-to-smtpmail "feedmail" nil t)
@@ -939,7 +939,7 @@ a message you see a bit later.
There is a separate queue for draft messages, intended to prevent
you from accidentally sending incomplete messages. The queues are
disk-based and intended for later transmission. The messages are
-queued in their raw state as they appear in the mail-mode buffer and
+queued in their raw state as they appear in the `mail-mode' buffer and
can be arbitrarily edited later, before sending, by visiting the
appropriate file in the queue directory (and setting the buffer to
mail-mode or whatever). If you visit a file in the queue directory
@@ -1286,7 +1286,7 @@ of casual real use only to the feedmail developer."
"Duration of pause after feedmail-debug messages.
After some messages are divulged, it may be helpful to pause before
something else obliterates them. This value controls the duration of
-the pause. If the value is nil or 0, the sit-for is not done, which
+the pause. If the value is nil or 0, the `sit-for' is not done, which
has the effect of not pausing at all. Debug messages can be seen after
the fact in the messages buffer."
:version "24.1"
@@ -2020,7 +2020,7 @@ backup file names and the like)."
;; if can't find EOH, this is no message!
(unless (feedmail-find-eoh t)
(feedmail-say-chatter "Skipping %s; no mail-header-separator" maybe-file)
- (error "FQM: you should never see this message"))
+ (error "FQM: You should never see this message"))
(feedmail-say-debug "Prepping %s" maybe-file)
;; the catch is a way out for users to voluntarily skip sending a message
(catch 'skip-me-q (funcall feedmail-queue-runner-message-sender arg))
@@ -2336,19 +2336,14 @@ mapped to mostly alphanumerics for safety."
;; from a similar function in mail-utils.el
(defun feedmail-rfc822-time-zone (time)
+ (declare (obsolete format-time-string "29.1"))
(feedmail-say-debug ">in-> feedmail-rfc822-time-zone %s" time)
- (let* ((sec (or (car (current-time-zone time)) 0))
- (absmin (/ (abs sec) 60)))
- (format "%c%02d%02d" (if (< sec 0) ?- ?+) (/ absmin 60) (% absmin 60))))
+ (format-time-string "%z" time))
(defun feedmail-rfc822-date (arg-time)
(feedmail-say-debug ">in-> feedmail-rfc822-date %s" arg-time)
- (let ((time (or arg-time (current-time)))
- (system-time-locale "C"))
- (concat
- (format-time-string "%a, %e %b %Y %T " time)
- (feedmail-rfc822-time-zone time)
- )))
+ (let ((system-time-locale "C"))
+ (format-time-string "%a, %e %b %Y %T %z" arg-time)))
(defun feedmail-send-it-immediately-wrapper ()
"Wrapper to catch skip-me-i."
@@ -2847,10 +2842,9 @@ probably not appropriate for you."
(if (and (not feedmail-queue-use-send-time-for-message-id) maybe-file)
(setq date-time (file-attribute-modification-time
(file-attributes maybe-file))))
- (format "<%d-%s%s%s>"
+ (format "<%d-%s%s>"
(mod (random) 10000)
- (format-time-string "%a%d%b%Y%H%M%S" date-time)
- (feedmail-rfc822-time-zone date-time)
+ (format-time-string "%a%d%b%Y%H%M%S%z" date-time)
end-stuff))
)
@@ -3149,7 +3143,7 @@ been weeded out."
(sit-for feedmail-queue-chatty-sit-for))))
(defun feedmail-find-eoh (&optional noerror)
- "Internal; finds the end of message header fields, returns mark just before it."
+ "Internal; find the end of message header fields, return mark just before it."
;; all this funny business with line endings is to account for CRLF
;; weirdness that I don't think I'll ever figure out
(feedmail-say-debug ">in-> feedmail-find-eoh %s" noerror)
diff --git a/lisp/mail/footnote.el b/lisp/mail/footnote.el
index 995ae5f9160..ef040ca90b3 100644
--- a/lisp/mail/footnote.el
+++ b/lisp/mail/footnote.el
@@ -39,15 +39,15 @@
;; commands.
;; + more language styles.
;; + The key sequence 'C-c ! a C-y C-c ! b' should auto-fill the
-;; footnote in adaptive fill mode. This does not seem to be a bug in
+;; footnote in adaptive fill mode. This does not seem to be a bug in
;; `adaptive-fill' because it behaves that way on all point movements
;; + Handle footmode mode elegantly in all modes, even if that means refuses to
-;; accept the burden. For example, in a programming language mode, footnotes
+;; accept the burden. For example, in a programming language mode, footnotes
;; should be commented.
;; + Manually autofilling the a first footnote should not cause it to
;; wrap into the footnote section tag
;; + Current solution adds a second newline after the section tag, so it is
-;; clearly a separate paragraph. There may be stylistic objections to this.
+;; clearly a separate paragraph. There may be stylistic objections to this.
;; + Footnotes with multiple paragraphs should not have their first
;; line out-dented.
;; + Upon leaving footnote area, perform an auto-fill on an entire
@@ -55,7 +55,7 @@
;; + fill-paragraph takes arg REGION, but seemingly only when called
;; interactively.
;; + At some point, it became necessary to change `footnote-section-tag-regexp'
-;; to remove its trailing space. (Adaptive fill side-effect?)
+;; to remove its trailing space. (Adaptive fill side-effect?)
;; + useful for lazy testing
;; (setq footnote-narrow-to-footnotes-when-editing t)
;; (setq footnote-section-tag "Footnotes: ")
@@ -151,7 +151,7 @@ has no effect on buffers already displaying footnotes."
(defcustom footnote-align-to-fn-text t
"How to left-align footnote text.
If nil, footnote text is to be aligned flush left with left side
-of the footnote number. If non-nil, footnote text is to be aligned
+of the footnote number. If non-nil, footnote text is to be aligned
left with the first character of footnote text."
:type 'boolean)
@@ -243,7 +243,7 @@ Wrapping around the alphabet implies successive repetitions of letters."
"List of roman numerals with their values.")
(defconst footnote-roman-upper-regexp (upcase footnote-roman-lower-regexp)
- "Regexp of roman numerals. Not complete")
+ "Regexp of roman numerals. Not complete.")
(defun footnote--roman-upper (n)
"Generic Roman number footnoting."
@@ -380,8 +380,8 @@ Use Unicode characters for footnoting."
(concat "[" (apply #'concat footnote-hebrew-symbolic) "]"))
(defun footnote--hebrew-symbolic (n)
- "Only 22 elements, per the style of eg. 'פירוש שפתי חכמים על רש״י'.
-Proceeds from `י' to `כ', from `צ' to `ק'. After `ת', rolls over to `א'."
+ "Only 22 elements, per the style of e.g. 'פירוש שפתי חכמים על רש״י'.
+Proceeds from `י' to `כ', from `צ' to `ק'. After `ת', rolls over to `א'."
(nth (mod (1- n) 22) footnote-hebrew-symbolic))
;;; list of all footnote styles
@@ -679,7 +679,7 @@ instead, if applicable."
(defun footnote--get-area-point-max ()
"Return the end of footnote area.
This is either `point-max' or the start of a `.signature' string, as
-defined by variable `footnote-signature-separator'. If there is no
+defined by variable `footnote-signature-separator'. If there is no
footnote area, returns `point-max'."
(save-excursion (footnote--goto-char-point-max)))
@@ -713,7 +713,7 @@ Return the footnote number to use."
(save-excursion
(let (rc)
(dolist (alist-elem footnote--markers-alist)
- (when (<= (point) (cl-caddr alist-elem))
+ (when (<= (point) (caddr alist-elem))
(unless rc
(setq rc (car alist-elem)))
(save-excursion
@@ -835,7 +835,7 @@ being set it is automatically widened."
(when note
(when footnote-narrow-to-footnotes-when-editing
(widen))
- (goto-char (cl-caddr (assq note footnote--markers-alist)))
+ (goto-char (caddr (assq note footnote--markers-alist)))
(when (looking-at (footnote--current-regexp))
(goto-char (match-end 0))))))
@@ -898,7 +898,7 @@ play around with the following keys:
(make-local-variable 'footnote-end-tag)
(make-local-variable 'adaptive-fill-function)
- ;; Filladapt was an XEmacs package which is now in GNU ELPA.
+ ;; Filladapt is a GNU ELPA package.
(when (boundp 'filladapt-token-table)
;; add tokens to filladapt to match footnotes
;; 1] xxxxxxxxxxx x x x or [1] x x x x x x x
diff --git a/lisp/mail/mail-utils.el b/lisp/mail/mail-utils.el
index 3eb3ccb93de..f1b0590bec7 100644
--- a/lisp/mail/mail-utils.el
+++ b/lisp/mail/mail-utils.el
@@ -368,19 +368,12 @@ matches may be returned from the message body."
labels)
(defun mail-rfc822-time-zone (time)
- (let* ((sec (or (car (current-time-zone time)) 0))
- (absmin (/ (abs sec) 60)))
- (format "%c%02d%02d" (if (< sec 0) ?- ?+) (/ absmin 60) (% absmin 60))))
+ (declare (obsolete format-time-string "29.1"))
+ (format-time-string "%z" time))
(defun mail-rfc822-date ()
- (let* ((time (current-time))
- (s (current-time-string time)))
- (string-match "[^ ]+ +\\([^ ]+\\) +\\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)" s)
- (concat (substring s (match-beginning 2) (match-end 2)) " "
- (substring s (match-beginning 1) (match-end 1)) " "
- (substring s (match-beginning 4) (match-end 4)) " "
- (substring s (match-beginning 3) (match-end 3)) " "
- (mail-rfc822-time-zone time))))
+ (let ((system-time-locale "C"))
+ (format-time-string "%-d %b %Y %T %z")))
(defun mail-mbox-from ()
"Return an mbox \"From \" line for the current message.
diff --git a/lisp/mail/mailabbrev.el b/lisp/mail/mailabbrev.el
index 5cb4a7469a9..62d9b12bb26 100644
--- a/lisp/mail/mailabbrev.el
+++ b/lisp/mail/mailabbrev.el
@@ -76,10 +76,10 @@
;; should make sure your version does before including verbose addresses like
;; this. One solution to this, if you are on a system whose /bin/mail doesn't
;; work that way, (and you still want to be able to /bin/mail to send mail in
-;; addition to emacs) is to define minimal aliases (without full names) in
+;; addition to Emacs) is to define minimal aliases (without full names) in
;; your .mailrc file, and use define-mail-abbrev to redefine them when sending
-;; mail from emacs; this way, mail sent from /bin/mail will work, and mail
-;; sent from emacs will be pretty.
+;; mail from Emacs; this way, mail sent from /bin/mail will work, and mail
+;; sent from Emacs will be pretty.
;;
;; Aliases in the mailrc file may be nested. If you define aliases like
;; alias group1 fred ethel
@@ -98,7 +98,7 @@
;; normally cannot contain hyphens, but this code works around that for the
;; specific case of mail-alias word-abbrevs.
;;
-;; To read in the contents of another .mailrc-type file from emacs, use the
+;; To read in the contents of another .mailrc-type file from Emacs, use the
;; command Meta-X merge-mail-abbrevs. The rebuild-mail-abbrevs command is
;; similar, but will delete existing aliases first.
;;
@@ -363,7 +363,7 @@ double-quotes."
(defun mail-resolve-all-aliases-1 (sym &optional so-far)
(if (memq sym so-far)
- (error "mail alias loop detected: %s"
+ (error "Mail alias loop detected: %s"
(mapconcat #'symbol-name (cons sym so-far) " <- ")))
(let ((definition (and (boundp sym) (symbol-value sym))))
(if definition
@@ -388,7 +388,7 @@ double-quotes."
(defun mail-abbrev-expand-hook ()
"For use as the fourth arg to `define-abbrev'.
After expanding a mail-abbrev, if Auto Fill mode is on and we're past the
-fill-column, break the line at the previous comma, and indent the next line
+`fill-column', break the line at the previous comma, and indent the next line
with a space."
(when auto-fill-function
(let (p)
diff --git a/lisp/mail/mailclient.el b/lisp/mail/mailclient.el
index 5c153ce1c1f..e6833806d92 100644
--- a/lisp/mail/mailclient.el
+++ b/lisp/mail/mailclient.el
@@ -198,7 +198,7 @@ The mail client is taken to be the handler of mailto URLs."
((string= character-coding "quoted-printable")
(mail-unquote-printable-region (point-min) (point-max)
nil nil t))
- (t (error "unsupported Content-Transfer-Encoding: %s"
+ (t (error "Unsupported Content-Transfer-Encoding: %s"
character-coding)))
(decode-coding-region (point-min) (point-max) coding-system))
(mailclient-encode-string-as-url
diff --git a/lisp/mail/mspools.el b/lisp/mail/mspools.el
index 6d834140582..a36ccd98dcb 100644
--- a/lisp/mail/mspools.el
+++ b/lisp/mail/mspools.el
@@ -29,7 +29,7 @@
;; to be read in them. It assumes that new mail for the file `folder'
;; is written by the filter to a file called `folder.spool'. (If the
;; file writes directly to `folder' you may lose mail if new mail
-;; arrives whilst you are reading the folder in emacs, hence the use
+;; arrives whilst you are reading the folder in Emacs, hence the use
;; of a spool file.) For example, the following procmail recipe puts
;; any mail with `emacs' in the subject line into the spool file
;; `emacs.spool', ready to go into the folder `emacs'.
@@ -342,7 +342,7 @@ This is useful if `mspools-update' is nil."
(kill-buffer mspools-buffer))
(define-derived-mode mspools-mode special-mode "MSpools"
- "Major mode for output from mspools-show.
+ "Major mode for output from `mspools-show'.
\\<mspools-mode-map>Move point to one of the items in this buffer, then use
\\[mspools-visit-spool] to go to the spool that the current line refers to.
\\[revert-buffer] to regenerate the list of spools.
diff --git a/lisp/mail/reporter.el b/lisp/mail/reporter.el
index 4b70582a261..2983a11d749 100644
--- a/lisp/mail/reporter.el
+++ b/lisp/mail/reporter.el
@@ -36,7 +36,7 @@
;; reporter.el was written primarily for Emacs Lisp package authors so
;; that their users can more easily report bugs. When invoked,
;; `reporter-submit-bug-report' will set up an outgoing mail buffer
-;; with the appropriate bug report address, including a lisp
+;; with the appropriate bug report address, including a Lisp
;; expression the maintainer of the package can evaluate to completely
;; reproduce the environment in which the bug was observed (e.g. by
;; using `eval-last-sexp'). This package proved especially useful
@@ -158,7 +158,7 @@ composed.")
(error indent-enclosing-p))))
(defun reporter-lisp-indent (_indent-point state)
- "A better lisp indentation style for bug reporting."
+ "A better Lisp indentation style for bug reporting."
(save-excursion
(goto-char (1+ (nth 1 state)))
(current-column)))
diff --git a/lisp/mail/rfc6068.el b/lisp/mail/rfc6068.el
new file mode 100644
index 00000000000..34fd7b5df4e
--- /dev/null
+++ b/lisp/mail/rfc6068.el
@@ -0,0 +1,83 @@
+;;; rfc6068.el --- support for rfc6068 -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Keywords: mail
+
+;; 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:
+
+(defun rfc6068-unhexify-string (string &optional inhibit-decode)
+ "Unhexify STRING -- e.g. `hello%20there' -> `hello there'.
+STRING is assumed to be a percentage-encoded utf-8 string.
+
+If INHIBIT-DECODE is non-nil, return the resulting raw byte
+string instead of decoding as utf-8."
+ (let ((string
+ (with-temp-buffer
+ (set-buffer-multibyte nil)
+ (insert string)
+ (goto-char (point-min))
+ (while (re-search-forward "%\\([[:xdigit:]]\\{2\\}\\)" nil t)
+ (replace-match (string (string-to-number (match-string 1) 16))
+ t t))
+ (buffer-string))))
+ (if inhibit-decode
+ string
+ (decode-coding-string string 'utf-8))))
+
+(defun rfc6068-parse-mailto-url (mailto-url)
+ "Parse MAILTO-URL, and return an alist of header-name, header-value pairs.
+MAILTO-URL should be a RFC 6068 (mailto) compliant url. A cons cell w/ a
+key of `Body' is a special case and is considered a header for this purpose.
+The returned alist is intended for use w/ the `compose-mail' interface.
+Note: make sure MAILTO-URL has been \"unhtmlized\" (e.g., &amp; -> &), before
+calling this function."
+ (let ((case-fold-search t)
+ headers-alist)
+ (setq mailto-url (string-replace "\n" " " mailto-url))
+ (when (string-match "^\\(mailto:\\)\\([^?]+\\)?\\(\\?\\(.*\\)\\)*"
+ mailto-url)
+ (let ((address (match-string 2 mailto-url))
+ (query (match-string 4 mailto-url)))
+ ;; Build alist of header name-value pairs.
+ (when query
+ (setq headers-alist
+ (mapcar
+ (lambda (x)
+ (let* ((pair (split-string x "="))
+ (name (car pair))
+ (value (cadr pair)))
+ ;; Return ("Header-Name" . "header-value").
+ (cons
+ (capitalize (rfc6068-unhexify-string name))
+ (rfc6068-unhexify-string value))))
+ (split-string query "&"))))
+
+ (when address
+ (setq address (rfc6068-unhexify-string address))
+ ;; Deal with multiple 'To' recipients.
+ (if-let ((elem (assoc "To" headers-alist)))
+ (setcdr elem (concat address ", " (cdr elem)))
+ (push (cons "To" address) headers-alist)))
+
+ headers-alist))))
+
+(provide 'rfc6068)
+
+;;; rfc6068.el ends here
diff --git a/lisp/mail/rmail-spam-filter.el b/lisp/mail/rmail-spam-filter.el
index fbac9e0cc0c..75a6c723695 100644
--- a/lisp/mail/rmail-spam-filter.el
+++ b/lisp/mail/rmail-spam-filter.el
@@ -72,6 +72,8 @@
;;; rmail-spam-filter such that the spam is rejected by
;;; rmail-spam-filter itself.
+;;; Code:
+
(require 'rmail)
(require 'rmailsum)
diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el
index 8a38337773e..afcb7f39bf2 100644
--- a/lisp/mail/rmail.el
+++ b/lisp/mail/rmail.el
@@ -207,8 +207,7 @@ or `-k' to enable Kerberos authentication."
(defvar rmail-remote-password-error "invalid usercode or password\\|
unknown user name or bad password\\|Authentication failed\\|MU_ERR_AUTH_FAILURE"
- "Regular expression matching incorrect-password POP or IMAP server error
-messages.
+ "Regexp matching incorrect-password POP or IMAP server error messages.
If you get an incorrect-password error that this expression does not match,
please report it with \\[report-emacs-bug].")
@@ -4126,10 +4125,8 @@ typically for purposes of moderating a list."
"A regexp that matches the separator before the text of a failed message.")
(defvar mail-mime-unsent-header "^Content-Type: message/rfc822 *$"
- "A regexp that matches the header of a MIME body part with a failed message.")
+ "A regexp that matches the header of a MIME body part with a failed message.")
-;; This is a cut-down version of rmail-clear-headers from Emacs 22.
-;; It doesn't have the same functionality, hence the name change.
(defun rmail-delete-headers (regexp)
"Delete any mail headers matching REGEXP.
The message should be narrowed to just the headers."
@@ -4137,10 +4134,6 @@ The message should be narrowed to just the headers."
(goto-char (point-min))
(while (re-search-forward regexp nil t)
(beginning-of-line)
- ;; This code from Emacs 22 doesn't seem right, since r-n-h is
- ;; just for display.
-;;; (if (looking-at rmail-nonignored-headers)
-;;; (forward-line 1)
(delete-region (point)
(save-excursion
(if (re-search-forward "\n[^ \t]" nil t)
@@ -4483,7 +4476,7 @@ TEXT and INDENT are not used."
(defun rmail-get-remote-password (imap user host)
"Get the password for retrieving mail from a POP or IMAP server.
-If none has been set, the password is found via auth-source. If
+If none has been set, the password is found via auth-source. If
you use ~/.authinfo as your auth-source backend, then put
something like the following in that file:
diff --git a/lisp/mail/rmailkwd.el b/lisp/mail/rmailkwd.el
index 58a8eb7a370..d8fcc1c0a99 100644
--- a/lisp/mail/rmailkwd.el
+++ b/lisp/mail/rmailkwd.el
@@ -74,12 +74,9 @@ according to the choice made, and returns a symbol."
(rmail-summary-exists)
(and (setq old (rmail-get-keywords))
(mapc #'rmail-make-label (split-string old ", "))))
- (completing-read (concat prompt
- (if rmail-last-label
- (concat " (default "
- (symbol-name rmail-last-label)
- "): ")
- ": "))
+ (completing-read (format-prompt prompt
+ (and rmail-last-label
+ (symbol-name rmail-last-label)))
rmail-label-obarray
nil
nil))))
diff --git a/lisp/mail/rmailmm.el b/lisp/mail/rmailmm.el
index 99bff66657b..66a1e9a4dbd 100644
--- a/lisp/mail/rmailmm.el
+++ b/lisp/mail/rmailmm.el
@@ -254,7 +254,7 @@ TRUNCATED is non-nil if the text of this entity was truncated."))
(unless (y-or-n-p "This entity is truncated; save anyway? ")
(error "Aborted")))
(setq filename (expand-file-name
- (read-file-name (format "Save as (default: %s): " filename)
+ (read-file-name (format-prompt "Save as" filename)
directory
(expand-file-name filename directory))
directory))
diff --git a/lisp/mail/rmailout.el b/lisp/mail/rmailout.el
index 4c23686909c..1f5bb2d9f1b 100644
--- a/lisp/mail/rmailout.el
+++ b/lisp/mail/rmailout.el
@@ -107,9 +107,8 @@ error: %S\n"
(read-file
(expand-file-name
(read-file-name
- (concat "Output message to mail file (default "
- (file-name-nondirectory default-file)
- "): ")
+ (format-prompt "Output message to mail file"
+ (file-name-nondirectory default-file))
(file-name-directory default-file)
(abbreviate-file-name default-file))
(file-name-directory default-file))))
@@ -434,7 +433,7 @@ AS-SEEN is non-nil if we are copying the message \"as seen\"."
(defun rmail-output-to-rmail-buffer (tembuf msg)
"Copy message in TEMBUF into the current Rmail buffer.
-Do what is necessary to make Rmail know about the new message. then
+Do what is necessary to make Rmail know about the new message, then
display message number MSG."
(save-excursion
(rmail-swap-buffers-maybe)
diff --git a/lisp/mail/rmailsum.el b/lisp/mail/rmailsum.el
index 9dd9573a9fc..8fc3fc095cc 100644
--- a/lisp/mail/rmailsum.el
+++ b/lisp/mail/rmailsum.el
@@ -1480,13 +1480,11 @@ argument says to read a file name and use that file as the inbox."
(declare-function rmail-output-read-file-name "rmailout" ())
(declare-function mail-send-and-exit "sendmail" (&optional arg))
-(defvar rmail-summary-edit-map nil)
-(if rmail-summary-edit-map
- nil
- (setq rmail-summary-edit-map
- (nconc (make-sparse-keymap) text-mode-map))
- (define-key rmail-summary-edit-map "\C-c\C-c" 'rmail-cease-edit)
- (define-key rmail-summary-edit-map "\C-c\C-]" 'rmail-abort-edit))
+(defvar rmail-summary-edit-map
+ (let ((map (nconc (make-sparse-keymap) text-mode-map)))
+ (define-key map "\C-c\C-c" #'rmail-cease-edit)
+ (define-key map "\C-c\C-]" #'rmail-abort-edit)
+ map))
(defun rmail-summary-edit-current-message ()
"Edit the contents of this message."
diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el
index fee11c06aa7..d1e8a2f3c69 100644
--- a/lisp/mail/sendmail.el
+++ b/lisp/mail/sendmail.el
@@ -277,6 +277,7 @@ The default value matches citations like `foo-bar>' plus whitespace."
(define-key map "\C-c\C-f\C-r" 'mail-reply-to)
(define-key map "\C-c\C-f\C-a" 'mail-mail-reply-to) ; author
(define-key map "\C-c\C-f\C-l" 'mail-mail-followup-to) ; list
+ (define-key map "\C-c\C-f\C-d" 'mail-insert-disposition-notification-to)
(define-key map "\C-c\C-t" 'mail-text)
(define-key map "\C-c\C-y" 'mail-yank-original)
(define-key map "\C-c\C-r" 'mail-yank-region)
@@ -325,6 +326,9 @@ The default value matches citations like `foo-bar>' plus whitespace."
(define-key map [menu-bar headers expand-aliases]
'("Expand Aliases" . expand-mail-aliases))
+ (define-key map [menu-bar headers disposition-notification]
+ '("Disposition-Notification-To" . mail-insert-disposition-notification-to))
+
(define-key map [menu-bar headers mail-reply-to]
'("Mail-Reply-To" . mail-mail-reply-to))
@@ -1387,8 +1391,7 @@ just append to the file, in Babyl format if necessary."
(unless (markerp header-end)
(error "Value of `header-end' must be a marker"))
(let (fcc-list
- (mailbuf (current-buffer))
- (time (current-time)))
+ (mailbuf (current-buffer)))
(save-excursion
(goto-char (point-min))
(let ((case-fold-search t))
@@ -1404,14 +1407,11 @@ just append to the file, in Babyl format if necessary."
(with-temp-buffer
;; This initial newline is not written out if we create a new
;; file (see below).
- (insert "\nFrom " (user-login-name) " " (current-time-string time) "\n")
- ;; Insert the time zone before the year.
- (forward-char -1)
- (forward-word-strictly -1)
(require 'mail-utils)
- (insert (mail-rfc822-time-zone time) " ")
- (goto-char (point-max))
- (insert "Date: " (message-make-date) "\n")
+ (insert "\nFrom " (user-login-name) " "
+ (let ((system-time-locale "C"))
+ (format-time-string "%a %b %e %T %z %Y"))
+ "\nDate: " (message-make-date) "\n")
(insert-buffer-substring mailbuf)
;; Make sure messages are separated.
(goto-char (point-max))
@@ -1598,6 +1598,25 @@ Returns non-nil if FIELD was originally present."
(interactive)
(expand-abbrev)
(goto-char (mail-text-start)))
+
+(defun mail-insert-disposition-notification-to ()
+ "Insert a Disposition-Notification-To header, if it doesn't already exist."
+ (interactive)
+ (expand-abbrev)
+ (save-excursion
+ (or (mail-position-on-field "Disposition-Notification-To")
+ (insert
+ (format
+ "%s"
+ (save-excursion
+ (save-restriction
+ (message-narrow-to-headers)
+ (or (mail-fetch-field "Reply-To")
+ (mail-fetch-field "From")
+ (with-temp-buffer
+ (mail-insert-from-field)
+ (substring (buffer-string) (length "From: ") -1))))))))))
+
(defun mail-signature (&optional atpoint)
"Sign letter with signature.
@@ -1927,7 +1946,8 @@ The seventh argument ACTIONS is a list of actions to take
(setq initialized t)))
(if (and buffer-auto-save-file-name
(file-exists-p buffer-auto-save-file-name))
- (message "Auto save file for draft message exists; consider M-x mail-recover"))
+ (message (substitute-command-keys
+ "Auto save file for draft message exists; consider \\[mail-recover]")))
initialized))
(declare-function dired-view-file "dired" ())
diff --git a/lisp/mail/smtpmail.el b/lisp/mail/smtpmail.el
index ec9f340db86..bd8aa611e94 100644
--- a/lisp/mail/smtpmail.el
+++ b/lisp/mail/smtpmail.el
@@ -829,15 +829,15 @@ Returns an error if the server cannot be contacted."
(when (or (member 'onex supported-extensions)
(member 'xone supported-extensions))
- (smtpmail-command-or-throw process (format "ONEX")))
+ (smtpmail-command-or-throw process "ONEX"))
(when (and smtpmail-debug-verb
(or (member 'verb supported-extensions)
(member 'xvrb supported-extensions)))
- (smtpmail-command-or-throw process (format "VERB")))
+ (smtpmail-command-or-throw process "VERB"))
(when (member 'xusr supported-extensions)
- (smtpmail-command-or-throw process (format "XUSR")))
+ (smtpmail-command-or-throw process "XUSR"))
;; MAIL FROM:<sender>
(let ((size-part
diff --git a/lisp/mail/supercite.el b/lisp/mail/supercite.el
index d545b0c3f15..b3080ac416b 100644
--- a/lisp/mail/supercite.el
+++ b/lisp/mail/supercite.el
@@ -1299,7 +1299,7 @@ use it instead of `sc-citation-root-regexp'."
(defvar sc-fill-begin 1
"Buffer position to begin filling.")
(defvar sc-fill-line-prefix ""
- "Fill prefix of previous line")
+ "Fill prefix of previous line.")
;; filling
(defun sc-fill-if-different (&optional prefix)
@@ -1767,7 +1767,7 @@ is determined non-interactively. The value is queried for in the
minibuffer exactly the same way that `set-variable' does it.
You can see the current value of the variable when the minibuffer is
-querying you by typing `C-h'. Note that the format is changed
+querying you by typing \\`C-h'. Note that the format is changed
slightly from that used by `set-variable' -- the current value is
printed just after the variable's name instead of at the bottom of the
help window."
diff --git a/lisp/mail/uce.el b/lisp/mail/uce.el
index b07004de38c..4347ff14022 100644
--- a/lisp/mail/uce.el
+++ b/lisp/mail/uce.el
@@ -30,6 +30,9 @@
;; uce-reply-to-uce. Please let me know about your changes so I can
;; incorporate them. I'd appreciate it.
+;; NOTE: We don't recommend using this feature; see the message in
+;; 'uce-reply-to-uce' for the reasons.
+
;; The command uce-reply-to-uce, if called when the current message
;; buffer is a UCE, will setup a reply *mail* buffer as follows. It
;; scans the full headers of the message for: 1) the normal return
@@ -213,6 +216,8 @@ These are mostly meant for headers that prevent delivery errors reporting."
(declare-function rmail-maybe-set-message-counters "rmail" ())
(declare-function rmail-toggle-header "rmail" (&optional arg))
+(defvar uce--usage-warning-displayed nil)
+
;;;###autoload
(defun uce-reply-to-uce (&optional _ignored)
"Compose a reply to unsolicited commercial email (UCE).
@@ -358,7 +363,32 @@ You might need to set `uce-mail-reader' before using this."
;; Run hooks before we leave buffer for editing. Reasonable usage
;; might be to set up special key bindings, replace standard
;; functions in mail-mode, etc.
- (run-hooks 'mail-setup-hook 'uce-setup-hook))))
+ (run-hooks 'mail-setup-hook 'uce-setup-hook)))
+ (unless uce--usage-warning-displayed
+ (setq uce--usage-warning-displayed t)
+ (pop-to-buffer (get-buffer-create "uce-reply-to-uce warning"))
+ (insert "\
+-- !!! NOTE !!! ---------------------------------------------
+
+Replying to spam is at best pointless, but most likely actively
+harmful.
+
+- You will confirm that your email address is valid, thus ensuring
+ you get more spam.
+
+- You will leak information and open yourself up for further
+ attack. For example, they could use your \"geolocation\" to find
+ your home address and phone number.
+
+- The sender address is likely fake.
+
+- You help them refine their methods of spamming.
+
+Therefore, we strongly recommend that you do not use this package.
+Use a spam filter instead, or just delete the spam.
+
+-------------------------------------------------------------
+")))
(defun uce-insert-ranting (&optional _ignored)
"Insert text of the usual reply to UCE into current buffer."
diff --git a/lisp/man.el b/lisp/man.el
index 6009a319198..fff31baa5f3 100644
--- a/lisp/man.el
+++ b/lisp/man.el
@@ -141,11 +141,21 @@ the manpage buffer."
:group 'man
:version "24.3")
-(defvar Man-ansi-color-map (let ((ansi-color-faces-vector
- [ default Man-overstrike default Man-underline
- Man-underline default default Man-reverse ]))
- (ansi-color-make-color-map))
- "The value used here for `ansi-color-map'.")
+(defvar Man-ansi-color-basic-faces-vector
+ [nil Man-overstrike nil Man-underline Man-underline nil nil Man-reverse]
+ "The value used here for `ansi-color-basic-faces-vector'.")
+
+(defvar Man-ansi-color-map
+ (with-no-warnings
+ (let ((ansi-color-faces-vector
+ [ default Man-overstrike default Man-underline
+ Man-underline default default Man-reverse ]))
+ (ansi-color-make-color-map)))
+ "The value formerly used here for `ansi-color-map'.
+This variable is obsolete. To customize the faces used by ansi-color,
+set `Man-ansi-color-basic-faces-vector'.")
+(make-obsolete-variable 'Man-ansi-color-map
+ 'Man-ansi-color-basic-faces-vector "28.1")
(defcustom Man-notify-method 'friendly
"Selects the behavior when manpage is ready.
@@ -1243,7 +1253,7 @@ Same for the ANSI bold and normal escape sequences."
(goto-char (point-min))
;; Fontify ANSI escapes.
(let ((ansi-color-apply-face-function #'ansi-color-apply-text-property-face)
- (ansi-color-map Man-ansi-color-map))
+ (ansi-color-basic-faces-vector Man-ansi-color-basic-faces-vector))
(ansi-color-apply-on-region (point-min) (point-max)))
;; Other highlighting.
(let ((buffer-undo-list t))
@@ -1324,7 +1334,7 @@ default type, `Man-xref-man-page' is used for the buttons."
(defun Man-highlight-references0 (start-section regexp button-pos target type)
;; Based on `Man-build-references-alist'
- (when (or (null start-section) ;; Search regardless of sections.
+ (when (or (null start-section) ;; Search regardless of sections.
;; Section header is in this chunk.
(Man-find-section start-section))
(let ((end (if start-section
@@ -1337,18 +1347,24 @@ default type, `Man-xref-man-page' is used for the buttons."
(goto-char (point-min))
nil)))
(while (re-search-forward regexp end t)
- ;; An overlay button is preferable because the underlying text
- ;; may have text property highlights (Bug#7881).
- (make-button
- (match-beginning button-pos)
- (match-end button-pos)
- 'type type
- 'Man-target-string (cond
- ((numberp target)
- (match-string target))
- ((functionp target)
- target)
- (t nil)))))))
+ (let ((b (match-beginning button-pos))
+ (e (match-end button-pos))
+ (match (match-string button-pos)))
+ ;; Some lists of references end with ", and ...". Chop the
+ ;; "and" bit off before making a button.
+ (when (string-match "\\`and +" match)
+ (setq b (+ b (- (match-end 0) (match-beginning 0)))))
+ ;; An overlay button is preferable because the underlying text
+ ;; may have text property highlights (Bug#7881).
+ (make-button
+ b e
+ 'type type
+ 'Man-target-string (cond
+ ((numberp target)
+ (match-string target))
+ ((functionp target)
+ target)
+ (t nil))))))))
(defun Man-cleanup-manpage (&optional interactive)
"Remove overstriking and underlining from the current buffer.
@@ -1776,7 +1792,7 @@ Returns t if section is found, nil otherwise."
Man--last-section
(car Man--sections)))
(completion-ignore-case t)
- (prompt (concat "Go to section (default " default "): "))
+ (prompt (format-prompt "Go to section" default))
(chosen (completing-read prompt Man--sections
nil nil nil nil default)))
(list chosen))
@@ -1840,7 +1856,7 @@ Specify which REFERENCE to use; default is based on word at point."
(defaults
(mapcar 'substring-no-properties
(cons default Man--refpages)))
- (prompt (concat "Refer to (default " default "): "))
+ (prompt (format-prompt "Refer to" default))
(chosen (completing-read prompt Man--refpages
nil nil nil nil defaults)))
chosen)))
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el
index 8def1575b24..bd110226618 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -413,8 +413,14 @@
(bindings--define-key menu [separator-tag-file]
'(menu-item "--" nil :visible (menu-bar-goto-uses-etags-p)))
+ (bindings--define-key menu [xref-forward]
+ '(menu-item "Forward" xref-go-forward
+ :visible (and (featurep 'xref)
+ (not (xref-forward-history-empty-p)))
+ :help "Forward to the position gone Back from"))
+
(bindings--define-key menu [xref-pop]
- '(menu-item "Back" xref-pop-marker-stack
+ '(menu-item "Back" xref-go-back
:visible (and (featurep 'xref)
(not (xref-marker-stack-empty-p)))
:help "Back to the position of the last search"))
@@ -514,7 +520,11 @@
(cdr yank-menu)
kill-ring))
(not buffer-read-only))))
- :help "Paste (yank) text most recently cut/copied"))
+ :help "Paste (yank) text most recently cut/copied"
+ :keys ,(lambda ()
+ (if cua-mode
+ "\\[cua-paste]"
+ "\\[yank]"))))
(bindings--define-key menu [copy]
;; ns-win.el said: Substitute a Copy function that works better
;; under X (for GNUstep).
@@ -523,14 +533,23 @@
'kill-ring-save)
:enable mark-active
:help "Copy text in region between mark and current position"
- :keys ,(if (featurep 'ns)
- "\\[ns-copy-including-secondary]"
- "\\[kill-ring-save]")))
+ :keys ,(lambda ()
+ (cond
+ ((featurep 'ns)
+ "\\[ns-copy-including-secondary]")
+ ((and cua-mode mark-active)
+ "\\[cua-copy-handler]")
+ (t
+ "\\[kill-ring-save]")))))
(bindings--define-key menu [cut]
- '(menu-item "Cut" kill-region
+ `(menu-item "Cut" kill-region
:enable (and mark-active (not buffer-read-only))
:help
- "Cut (kill) text in region between mark and current position"))
+ "Cut (kill) text in region between mark and current position"
+ :keys ,(lambda ()
+ (if (and cua-mode mark-active)
+ "\\[cua-cut-handler]"
+ "\\[kill-region]"))))
;; ns-win.el said: Separate undo from cut/paste section.
(if (featurep 'ns)
(bindings--define-key menu [separator-undo] menu-bar-separator))
@@ -1315,6 +1334,11 @@ mail status in mode line"))
:visible (and (display-graphic-p) (fboundp 'x-show-tip))
:button (:toggle . tooltip-mode)))
+ (bindings--define-key menu [showhide-context-menu]
+ '(menu-item "Context Menus" context-menu-mode
+ :help "Turn mouse-3 context menus on/off"
+ :button (:toggle . context-menu-mode)))
+
(bindings--define-key menu [menu-bar-mode]
'(menu-item "Menu Bar" toggle-menu-bar-mode-from-frame
:help "Turn menu bar on/off"
@@ -1323,14 +1347,13 @@ mail status in mode line"))
(frame-parameter (menu-bar-frame-for-menubar)
'menu-bar-lines)))))
- (unless (featurep 'ns)
- (bindings--define-key menu [showhide-tab-bar]
- '(menu-item "Tab Bar" toggle-tab-bar-mode-from-frame
- :help "Turn tab bar on/off"
- :button
- (:toggle . (menu-bar-positive-p
- (frame-parameter (menu-bar-frame-for-menubar)
- 'tab-bar-lines))))))
+ (bindings--define-key menu [showhide-tab-bar]
+ '(menu-item "Tab Bar" toggle-tab-bar-mode-from-frame
+ :help "Turn tab bar on/off"
+ :button
+ (:toggle . (menu-bar-positive-p
+ (frame-parameter (menu-bar-frame-for-menubar)
+ 'tab-bar-lines)))))
(if (and (boundp 'menu-bar-showhide-tool-bar-menu)
(keymapp menu-bar-showhide-tool-bar-menu))
@@ -1913,10 +1936,7 @@ key, a click, or a menu-item"))
(let* ((default (thing-at-point 'sexp))
(topic
(read-from-minibuffer
- (format "Subject to look up%s: "
- (if default
- (format " (default \"%s\")" default)
- ""))
+ (format-prompt "Subject to look up" default)
nil nil nil nil default)))
(list (if (zerop (length topic))
default
@@ -1955,6 +1975,9 @@ key, a click, or a menu-item"))
:help "Find commands whose names match a regexp"))
(bindings--define-key menu [sep1]
menu-bar-separator)
+ (bindings--define-key menu [lookup-symbol-in-manual]
+ '(menu-item "Look Up Symbol in Manual..." info-lookup-symbol
+ :help "Display manual section that describes a symbol"))
(bindings--define-key menu [lookup-command-in-manual]
'(menu-item "Look Up Command in User Manual..." Info-goto-emacs-command-node
:help "Display manual section that describes a command"))
@@ -2151,10 +2174,16 @@ otherwise it could decide to silently do nothing."
(> count 1)))
(defcustom yank-menu-length 20
- "Maximum length to display in the yank-menu."
+ "Text of items in `yank-menu' longer than this will be truncated."
:type 'integer
:group 'menu)
+(defcustom yank-menu-max-items 60
+ "Maximum number of entries to display in the `yank-menu'."
+ :type 'integer
+ :group 'menu
+ :version "29.1")
+
(defun menu-bar-update-yank-menu (string old)
(let ((front (car (cdr yank-menu)))
(menu-string (if (<= (length string) yank-menu-length)
@@ -2178,8 +2207,9 @@ otherwise it could decide to silently do nothing."
(cons
(cons string (cons menu-string 'menu-bar-select-yank))
(cdr yank-menu)))))
- (if (> (length (cdr yank-menu)) kill-ring-max)
- (setcdr (nthcdr kill-ring-max yank-menu) nil)))
+ (let ((max-items (min yank-menu-max-items kill-ring-max)))
+ (if (> (length (cdr yank-menu)) max-items)
+ (setcdr (nthcdr max-items yank-menu) nil))))
(put 'menu-bar-select-yank 'apropos-inhibit t)
(defun menu-bar-select-yank ()
@@ -2284,7 +2314,7 @@ Buffers menu is regenerated."
It must accept a buffer as its only required argument.")
(defun menu-bar-buffer-vector (alist)
- ;; turn ((name . buffer) ...) into a menu
+ "Turn ((name . buffer) ...) into a menu."
(let ((buffers-vec (make-vector (length alist) nil))
(i (length alist)))
(dolist (pair alist)
@@ -2298,7 +2328,7 @@ It must accept a buffer as its only required argument.")
buffers-vec))
(defun menu-bar-update-buffers (&optional force)
- ;; If user discards the Buffers item, play along.
+ "If user discards the Buffers item, play along."
(and (lookup-key (current-global-map) [menu-bar buffer])
(or force (frame-or-buffer-changed-p))
(let ((buffers (buffer-list))
@@ -2482,7 +2512,9 @@ created in the future."
;; after this function returns, overwriting any message we do here.
(when (and (called-interactively-p 'interactive) (not menu-bar-mode))
(run-with-idle-timer 0 nil 'message
- "Menu Bar mode disabled. Use M-x menu-bar-mode to make the menu bar appear.")))
+ (substitute-command-keys
+ "Menu Bar mode disabled. \
+Use \\[menu-bar-mode] to make the menu bar appear."))))
;;;###autoload
;; (This does not work right unless it comes after the above definition.)
@@ -2507,6 +2539,8 @@ See `menu-bar-mode' for more information."
(declare-function x-menu-bar-open "term/x-win" (&optional frame))
(declare-function w32-menu-bar-open "term/w32-win" (&optional frame))
+(declare-function pgtk-menu-bar-open "term/pgtk-win" (&optional frame))
+(declare-function haiku-menu-bar-open "haikumenu.c" (&optional frame))
(defun lookup-key-ignore-too-long (map key)
"Call `lookup-key' and convert numeric values to nil."
@@ -2632,9 +2666,10 @@ first TTY menu-bar menu to be dropped down. Interactively,
this is the numeric argument to the command.
This function decides which method to use to access the menu
depending on FRAME's terminal device. On X displays, it calls
-`x-menu-bar-open'; on Windows, `w32-menu-bar-open'; otherwise it
-calls either `popup-menu' or `tmm-menubar' depending on whether
-`tty-menu-open-use-tmm' is nil or not.
+`x-menu-bar-open'; on Windows, `w32-menu-bar-open'; on Haiku,
+`haiku-menu-bar-open'; otherwise it calls either `popup-menu'
+or `tmm-menubar' depending on whether `tty-menu-open-use-tmm'
+is nil or not.
If FRAME is nil or not given, use the selected frame."
(interactive
@@ -2643,6 +2678,8 @@ If FRAME is nil or not given, use the selected frame."
(cond
((eq type 'x) (x-menu-bar-open frame))
((eq type 'w32) (w32-menu-bar-open frame))
+ ((eq type 'haiku) (haiku-menu-bar-open frame))
+ ((eq type 'pgtk) (pgtk-menu-bar-open frame))
((and (null tty-menu-open-use-tmm)
(not (zerop (or (frame-parameter nil 'menu-bar-lines) 0))))
;; Make sure the menu bar is up to date. One situation where
@@ -2686,10 +2723,13 @@ This command is to be used when you click the mouse in the menubar."
(cdr menu-bar-item-cons)
0))))
-(defun menu-bar-keymap ()
+(defun menu-bar-keymap (&optional keymap)
"Return the current menu-bar keymap.
+The ordering of the return value respects `menu-bar-final-items'.
-The ordering of the return value respects `menu-bar-final-items'."
+It's possible to use the KEYMAP argument to override the default keymap
+that is the currently active maps. For example, the argument KEYMAP
+could provide `global-map' where items are limited to the global map only."
(let ((menu-bar '())
(menu-end '()))
(map-keymap
@@ -2702,7 +2742,7 @@ The ordering of the return value respects `menu-bar-final-items'."
;; sorting.
(push (cons pos menu-item) menu-end)
(push menu-item menu-bar))))
- (lookup-key (menu-bar-current-active-maps) [menu-bar]))
+ (or keymap (lookup-key (menu-bar-current-active-maps) [menu-bar])))
`(keymap ,@(nreverse menu-bar)
,@(mapcar #'cdr (sort menu-end
(lambda (a b)
@@ -2772,7 +2812,7 @@ This is the keyboard interface to \\[mouse-buffer-menu]."
km))
(defun menu-bar-define-mouse-key (map key def)
- "Like `define-key', but adds all possible prefixes for the mouse."
+ "Like `define-key', but add all possible prefixes for the mouse."
(define-key map (vector key) def)
(mapc (lambda (prefix) (define-key map (vector prefix key) def))
;; This list only needs to contain special window areas that
diff --git a/lisp/mh-e/ChangeLog.1 b/lisp/mh-e/ChangeLog.1
index b0fdd02e3b3..2201ce22a26 100644
--- a/lisp/mh-e/ChangeLog.1
+++ b/lisp/mh-e/ChangeLog.1
@@ -10218,7 +10218,7 @@
it can fail if the user's MH environment is not setup correctly).
I now set the value of mh-folder-unseen-seq-name at runtime when I
first need it. This should fix Debian bugs
- http://bugs.debian.org/140232 and http://bugs.debian.org/140817
+ https://bugs.debian.org/140232 and https://bugs.debian.org/140817
2002-03-25 Peter S Galbraith <psg@debian.org>
@@ -10471,7 +10471,7 @@
mh-header-subject-font-lock instead of regexp for subject headers,
which may go multiple lines.
(mh-header-subject-font-lock): New function.
- Fix typos (hightlight -> highlight).
+ Fix typos ("highlight").
2001-12-04 Eric Ding <ericding@alum.mit.edu>
@@ -10881,7 +10881,7 @@
loop in emacs20 font-locking.
(mh-header-field-font-lock): Preventive fix with similar change.
- * mh-comp.el (mh-reply-show-message-p): Typo. diplayed -> displayed.
+ * mh-comp.el (mh-reply-show-message-p): Fix typo for "displayed".
* MH-E-NEWS: Same.
* mh-e.el (mh-folder-tool-bar-map): Bug fix. I had
diff --git a/lisp/mh-e/mh-acros.el b/lisp/mh-e/mh-acros.el
index 8fdcf3c62b4..25fff6a8e1b 100644
--- a/lisp/mh-e/mh-acros.el
+++ b/lisp/mh-e/mh-acros.el
@@ -47,19 +47,20 @@
;;;###mh-autoload
(defmacro mh-do-in-gnu-emacs (&rest body)
"Execute BODY if in GNU Emacs."
- (declare (debug t) (indent defun))
+ (declare (obsolete progn "29.1") (debug t) (indent defun))
(unless (featurep 'xemacs) `(progn ,@body)))
;;;###mh-autoload
(defmacro mh-do-in-xemacs (&rest body)
"Execute BODY if in XEmacs."
- (declare (debug t) (indent defun))
+ (declare (obsolete ignore "29.1") (debug t) (indent defun))
(when (featurep 'xemacs) `(progn ,@body)))
;;;###mh-autoload
(defmacro mh-funcall-if-exists (function &rest args)
"Call FUNCTION with ARGS as parameters if it exists."
- (declare (debug (symbolp body)))
+ (declare (obsolete "use `(when (fboundp 'foo) (foo))' instead." "29.1")
+ (debug (symbolp body)))
;; FIXME: Not clear when this should be used. If the function happens
;; not to exist at compile-time (e.g. because the corresponding package
;; wasn't loaded), then it won't ever be used :-(
@@ -72,7 +73,8 @@
"Create function NAME.
If FUNCTION exists, then NAME becomes an alias for FUNCTION.
Otherwise, create function NAME with ARG-LIST and BODY."
- (declare (indent defun) (doc-string 4)
+ (declare (obsolete defun "29.1")
+ (indent defun) (doc-string 4)
(debug (&define name symbolp sexp def-body)))
`(defalias ',name
(if (fboundp ',function)
@@ -84,7 +86,8 @@ Otherwise, create function NAME with ARG-LIST and BODY."
"Create macro NAME.
If MACRO exists, then NAME becomes an alias for MACRO.
Otherwise, create macro NAME with ARG-LIST and BODY."
- (declare (indent defun) (doc-string 4)
+ (declare (obsolete defmacro "29.1")
+ (indent defun) (doc-string 4)
(debug (&define name symbolp sexp def-body)))
(let ((defined-p (fboundp macro)))
(if defined-p
@@ -99,22 +102,20 @@ Otherwise, create macro NAME with ARG-LIST and BODY."
"Make HOOK local if needed.
XEmacs and versions of GNU Emacs before 21.1 require
`make-local-hook' to be called."
+ (declare (obsolete nil "29.1"))
(when (and (fboundp 'make-local-hook)
(not (get 'make-local-hook 'byte-obsolete-info)))
`(make-local-hook ,hook)))
;;;###mh-autoload
(defmacro mh-mark-active-p (check-transient-mark-mode-flag)
- "A macro that expands into appropriate code in XEmacs and nil in GNU Emacs.
-In GNU Emacs if CHECK-TRANSIENT-MARK-MODE-FLAG is non-nil then
-check if variable `transient-mark-mode' is active."
- (cond ((featurep 'xemacs) ;XEmacs
- '(and (boundp 'zmacs-regions) zmacs-regions (region-active-p)))
- ((not check-transient-mark-mode-flag) ;GNU Emacs
- '(and (boundp 'mark-active) mark-active))
- (t ;GNU Emacs
- '(and (boundp 'transient-mark-mode) transient-mark-mode
- (boundp 'mark-active) mark-active))))
+ "If CHECK-TRANSIENT-MARK-MODE-FLAG is non-nil then check if
+variable `transient-mark-mode' is active."
+ (declare (obsolete nil "29.1"))
+ (cond ((not check-transient-mark-mode-flag)
+ 'mark-active)
+ (t
+ '(and transient-mark-mode mark-active))))
;;;###mh-autoload
(defmacro with-mh-folder-updating (save-modification-flag &rest body)
@@ -164,12 +165,8 @@ preserved."
(original-position (make-symbol "original-position"))
(modified-flag (make-symbol "modified-flag")))
`(save-excursion
- (let* ((,event-window
- (or (mh-funcall-if-exists posn-window (event-start ,event))
- (mh-funcall-if-exists event-window ,event)))
- (,event-position
- (or (mh-funcall-if-exists posn-point (event-start ,event))
- (mh-funcall-if-exists event-closest-point ,event)))
+ (let* ((,event-window (posn-window (event-start ,event)))
+ (,event-position (posn-point (event-start ,event)))
(,original-window (selected-window))
(,original-position (progn
(set-buffer (window-buffer ,event-window))
diff --git a/lisp/mh-e/mh-alias.el b/lisp/mh-e/mh-alias.el
index 37fdb166011..d2666211002 100644
--- a/lisp/mh-e/mh-alias.el
+++ b/lisp/mh-e/mh-alias.el
@@ -67,8 +67,7 @@ Return t if any file listed in the Aliasfile MH profile component has
been modified since the timestamp.
If ARG is non-nil, set timestamp with the current time."
(if arg
- (let ((time (current-time)))
- (setq mh-alias-tstamp (list (nth 0 time) (nth 1 time))))
+ (setq mh-alias-tstamp (current-time))
(let ((stamp))
(car (memq t (mapcar
(lambda (file)
@@ -112,10 +111,10 @@ COMMA-SEPARATOR is non-nil."
(setq res (match-string 1 res)))
;; Replace "&" with capitalized username
(if (string-search "&" res)
- (setq res (mh-replace-regexp-in-string "&" (capitalize username) res)))
+ (setq res (replace-regexp-in-string "&" (capitalize username) res)))
;; Remove " character
(if (string-search "\"" res)
- (setq res (mh-replace-regexp-in-string "\"" "" res)))
+ (setq res (replace-regexp-in-string "\"" "" res)))
;; If empty string, use username instead
(if (string-equal "" res)
(setq res username))
@@ -155,7 +154,7 @@ Exclude all aliases already in `mh-alias-alist' from \"ali\""
(if (string-equal username realname)
(concat "<" username ">")
(concat realname " <" username ">"))))
- (when (not (mh-assoc-string alias-name mh-alias-alist t))
+ (when (not (assoc-string alias-name mh-alias-alist t))
(setq passwd-alist (cons (list alias-name alias-translation)
passwd-alist)))))))
(forward-line 1)))
@@ -184,12 +183,12 @@ been loaded."
(cond
((looking-at "^[ \t]")) ;Continuation line
((looking-at "\\(.+\\): .+: .*$") ; A new -blind- MH alias
- (when (not (mh-assoc-string (match-string 1) mh-alias-blind-alist t))
+ (when (not (assoc-string (match-string 1) mh-alias-blind-alist t))
(setq mh-alias-blind-alist
(cons (list (match-string 1)) mh-alias-blind-alist))
(setq mh-alias-alist (cons (list (match-string 1)) mh-alias-alist))))
((looking-at "\\(.+\\): .*$") ; A new MH alias
- (when (not (mh-assoc-string (match-string 1) mh-alias-alist t))
+ (when (not (assoc-string (match-string 1) mh-alias-alist t))
(setq mh-alias-alist
(cons (list (match-string 1)) mh-alias-alist)))))
(forward-line 1)))
@@ -200,7 +199,7 @@ been loaded."
user)
(while local-users
(setq user (car local-users))
- (if (not (mh-assoc-string (car user) mh-alias-alist t))
+ (if (not (assoc-string (car user) mh-alias-alist t))
(setq mh-alias-alist (append mh-alias-alist (list user))))
(setq local-users (cdr local-users)))))
(run-hooks 'mh-alias-reloaded-hook)
@@ -239,16 +238,16 @@ done here."
"Return expansion for ALIAS.
Blind aliases or users from /etc/passwd are not expanded."
(cond
- ((mh-assoc-string alias mh-alias-blind-alist t)
+ ((assoc-string alias mh-alias-blind-alist t)
alias) ; Don't expand a blind alias
- ((mh-assoc-string alias mh-alias-passwd-alist t)
- (cadr (mh-assoc-string alias mh-alias-passwd-alist t)))
+ ((assoc-string alias mh-alias-passwd-alist t)
+ (cadr (assoc-string alias mh-alias-passwd-alist t)))
(t
(mh-alias-ali alias))))
(eval-and-compile
- (mh-require 'crm nil t) ; completing-read-multiple
- (mh-require 'multi-prompt nil t))
+ (require 'crm nil t) ; completing-read-multiple
+ (require 'multi-prompt nil t))
;;;###mh-autoload
(defun mh-read-address (prompt)
@@ -258,15 +257,7 @@ Blind aliases or users from /etc/passwd are not expanded."
(read-string prompt)
(let* ((minibuffer-local-completion-map mh-alias-read-address-map)
(completion-ignore-case mh-alias-completion-ignore-case-flag)
- (the-answer
- (cond ((fboundp 'completing-read-multiple)
- (mh-funcall-if-exists
- completing-read-multiple prompt mh-alias-alist nil nil))
- ((featurep 'multi-prompt)
- (mh-funcall-if-exists
- multi-prompt "," nil prompt mh-alias-alist nil nil))
- (t (split-string
- (completing-read prompt mh-alias-alist nil nil) ",")))))
+ (the-answer (completing-read-multiple prompt mh-alias-alist nil nil)))
(if (not mh-alias-expand-aliases-flag)
(mapconcat #'identity the-answer ", ")
;; Loop over all elements, checking if in passwd alias or blind first
@@ -281,7 +272,7 @@ Blind aliases or users from /etc/passwd are not expanded."
(let* ((case-fold-search t)
(beg (mh-beginning-of-word))
(the-name (buffer-substring-no-properties beg (point))))
- (if (mh-assoc-string the-name mh-alias-alist t)
+ (if (assoc-string the-name mh-alias-alist t)
(message "%s -> %s" the-name (mh-alias-expand the-name))
;; Check if it was a single word likely to be an alias
(if (and (equal mh-alias-flash-on-comma 1)
@@ -313,7 +304,7 @@ Blind aliases or users from /etc/passwd are not expanded."
res)
res)))
((t) (all-completions string mh-alias-alist pred))
- ((lambda) (mh-test-completion string mh-alias-alist pred)))))))))
+ ((lambda) (test-completion string mh-alias-alist pred)))))))))
;;; Alias File Updating
diff --git a/lisp/mh-e/mh-comp.el b/lisp/mh-e/mh-comp.el
index 4fae69defaf..a47a6f9cca9 100644
--- a/lisp/mh-e/mh-comp.el
+++ b/lisp/mh-e/mh-comp.el
@@ -38,6 +38,7 @@
(require 'sendmail)
(autoload 'easy-menu-add "easymenu")
+(autoload 'mail-header-parse-address "mail-parse")
(autoload 'mml-insert-tag "mml")
@@ -176,9 +177,8 @@ Used by the \\[mh-edit-again] and \\[mh-extract-rejected-mail] commands.")
"Messages annotated, either a sequence name or a list of message numbers.
This variable can be used by `mh-annotate-msg-hook'.")
-(defvar mh-insert-auto-fields-done-local nil
+(defvar-local mh-insert-auto-fields-done-local nil
"Buffer-local variable set when `mh-insert-auto-fields' called successfully.")
-(make-variable-buffer-local 'mh-insert-auto-fields-done-local)
@@ -303,21 +303,7 @@ message and scan line."
(let ((draft-buffer (current-buffer))
(file-name buffer-file-name)
(config mh-previous-window-config)
- ;; FIXME this is subtly different to select-message-coding-system.
- (coding-system-for-write
- (if (fboundp 'select-message-coding-system)
- (select-message-coding-system) ; Emacs has this since at least 21.1
- (if (and (local-variable-p 'buffer-file-coding-system
- (current-buffer)) ;XEmacs needs two args
- ;; We're not sure why, but buffer-file-coding-system
- ;; tends to get set to undecided-unix.
- (not (memq buffer-file-coding-system
- '(undecided undecided-unix undecided-dos))))
- buffer-file-coding-system
- (or (and (boundp 'sendmail-coding-system) sendmail-coding-system)
- (and (default-boundp 'buffer-file-coding-system)
- (default-value 'buffer-file-coding-system))
- 'utf-8)))))
+ (coding-system-for-write (select-message-coding-system)))
;; Older versions of spost do not support -msgid and -mime.
(unless mh-send-uses-spost-flag
;; Adding a Message-ID field looks good, makes it easier to search for
@@ -432,7 +418,7 @@ See also `mh-send'."
(mh-clean-msg-header (point-min) mh-new-draft-cleaned-headers nil)
(mh-insert-header-separator)
;; Merge in components
- (mh-mapc
+ (mapc
(lambda (header-field)
(let ((field (car header-field))
(value (cdr header-field))
@@ -452,7 +438,7 @@ See also `mh-send'."
;; Header field exists and we have a value
(let (address mailbox (alias (mh-alias-expand value)))
(and alias
- (setq address (ietf-drums-parse-address alias))
+ (setq address (mail-header-parse-address alias))
(setq mailbox (car address)))
;; XXX - Need to parse all addresses out of field
(if (and
@@ -592,11 +578,12 @@ See also `mh-compose-forward-as-mime-flag',
(goto-char (point-min))
;; Set the local value of mh-mail-header-separator according to what is
;; present in the buffer...
- (set (make-local-variable 'mh-mail-header-separator)
- (save-excursion
- (goto-char (mh-mail-header-end))
- (buffer-substring-no-properties (point) (mh-line-end-position))))
- (set (make-local-variable 'mail-header-separator) mh-mail-header-separator) ;override sendmail.el
+ (setq-local mh-mail-header-separator
+ (save-excursion
+ (goto-char (mh-mail-header-end))
+ (buffer-substring-no-properties (point)
+ (line-end-position))))
+ (setq-local mail-header-separator mh-mail-header-separator) ;override sendmail.el
;; If using MML, translate MH-style directive
(if (equal mh-compose-insertion 'mml)
(save-excursion
@@ -637,6 +624,8 @@ See also `mh-compose-forward-as-mime-flag',
(defun mh-forwarded-letter-subject (from subject)
"Return a Subject suitable for a forwarded message.
Original message has headers FROM and SUBJECT."
+ ;; Join continued lines.
+ (setq from (replace-regexp-in-string "\\s *\n\\s +" " " from))
(let ((addr-start (string-search "<" from))
(comment (string-search "(" from)))
(cond ((and addr-start (> addr-start 0))
@@ -696,7 +685,7 @@ message and scan line."
;; For "From", the first value wins, with the identity's "From"
;; trumping anything in the distcomps file.
(let ((components-file (mh-bare-components mh-dist-formfile)))
- (mh-mapc
+ (mapc
(lambda (header-field)
(let ((field (car header-field))
(value (cdr header-field))
@@ -1076,7 +1065,6 @@ letter."
;; Insert identity.
(mh-insert-identity mh-identity-default t)
(mh-identity-make-menu)
- (mh-identity-add-menu)
;; Cleanup possibly RFC2047 encoded subject header
(mh-decode-message-subject)
@@ -1095,7 +1083,6 @@ letter."
(setq mh-previous-window-config config)
(setq mode-line-buffer-identification (list " {%b}"))
(mh-logo-display)
- (mh-make-local-hook 'kill-buffer-hook)
(add-hook 'kill-buffer-hook #'mh-tidy-draft-buffer nil t)
(run-hook-with-args 'mh-compose-letter-function to subject cc))
@@ -1106,18 +1093,8 @@ The versions of MH-E, Emacs, and MH are shown."
;; Lazily initialize mh-x-mailer-string.
(when (and mh-insert-x-mailer-flag (null mh-x-mailer-string))
(setq mh-x-mailer-string
- (format "MH-E %s; %s; %sEmacs %s"
- mh-version mh-variant-in-use
- (if (featurep 'xemacs) "X" "GNU ")
- (cond ((not (featurep 'xemacs))
- (string-match "[0-9]+\\.[0-9]+\\(\\.[0-9]+\\)?"
- emacs-version)
- (match-string 0 emacs-version))
- ((string-match "[0-9.]*\\( +([ a-z]+[0-9]+)\\)?"
- emacs-version)
- (match-string 0 emacs-version))
- (t (format "%s.%s" emacs-major-version
- emacs-minor-version))))))
+ (format "MH-E %s; %s; Emacs %s"
+ mh-version mh-variant-in-use emacs-version)))
;; Insert X-Mailer, but only if it doesn't already exist.
(save-excursion
(when (and mh-insert-x-mailer-flag
@@ -1244,7 +1221,7 @@ discarded."
(cond ((and overwrite-flag
(mh-goto-header-field (concat field ":")))
(insert " " value)
- (delete-region (point) (mh-line-end-position)))
+ (delete-region (point) (line-end-position)))
((and (not overwrite-flag)
(mh-regexp-in-field-p (concat "\\b" (regexp-quote value) "\\b") field))
;; Already there, do nothing.
@@ -1287,11 +1264,8 @@ discarded."
(set-syntax-table old-syntax-table))))
(defun mh-ascii-buffer-p ()
- "Check if current buffer is entirely composed of ASCII.
-The function doesn't work for XEmacs since `find-charset-region'
-doesn't exist there."
- (cl-loop for charset in (mh-funcall-if-exists
- find-charset-region (point-min) (point-max))
+ "Check if current buffer is entirely composed of ASCII."
+ (cl-loop for charset in (find-charset-region (point-min) (point-max))
unless (eq charset 'ascii) return nil
finally return t))
diff --git a/lisp/mh-e/mh-compat.el b/lisp/mh-e/mh-compat.el
index ade80e8b95e..23dc48a574c 100644
--- a/lisp/mh-e/mh-compat.el
+++ b/lisp/mh-e/mh-compat.el
@@ -34,53 +34,21 @@
;; Please use mh-gnus.el when providing compatibility with different
;; versions of Gnus.
-;; Items are listed alphabetically (except for mh-require which is
-;; needed sooner it would normally appear).
+;; Items are listed alphabetically.
(eval-when-compile (require 'mh-acros))
-(mh-do-in-gnu-emacs
- (defalias 'mh-require #'require))
-
-(mh-do-in-xemacs
- (defun mh-require (feature &optional filename noerror)
- "If feature FEATURE is not loaded, load it from FILENAME.
-If FEATURE is not a member of the list `features', then the feature
-is not loaded; so load the file FILENAME.
-If FILENAME is omitted, the printname of FEATURE is used as the file name.
-If the optional third argument NOERROR is non-nil,
-then return nil if the file is not found instead of signaling an error.
-
-Simulate NOERROR argument in XEmacs which lacks it."
- (if (not (featurep feature))
- (if filename
- (load filename noerror t)
- (load (format "%s" feature) noerror t)))))
-
-(defun-mh mh-assoc-string assoc-string (key list case-fold)
- "Like `assoc' but specifically for strings.
-Case is ignored if CASE-FOLD is non-nil.
-This function is used by Emacs versions that lack `assoc-string',
-introduced in Emacs 22."
- ;; Test for fboundp is solely to silence compiler for Emacs >= 22.1.
- (if (and case-fold (fboundp 'assoc-ignore-case))
- (assoc-ignore-case key list)
- (assoc key list)))
-
-;; For XEmacs.
-(defalias 'mh-cancel-timer
- (if (fboundp 'cancel-timer)
- 'cancel-timer
- 'delete-itimer))
+(define-obsolete-function-alias 'mh-require #'require "29.1")
+(define-obsolete-function-alias 'mh-assoc-string #'assoc-string "29.1")
+(define-obsolete-function-alias 'mh-cancel-timer #'cancel-timer "29.1")
;; Emacs 24 made flet obsolete and suggested either cl-flet or
;; cl-letf. This macro is based upon gmm-flet from Gnus.
(defmacro mh-flet (bindings &rest body)
"Make temporary overriding function definitions.
-This is an analogue of a dynamically scoped `let' that operates on
-the function cell of FUNCs rather than their value cell.
-
-\(fn ((FUNC ARGLIST BODY...) ...) FORM...)"
+That is, temporarily rebind the functions listed in BINDINGS and then
+execute BODY. BINDINGS is a list containing one or more lists of the
+form (FUNCNAME ARGLIST BODY...), similar to defun."
(declare (indent 1) (debug ((&rest (sexp sexp &rest form)) &rest form)))
(if (fboundp 'cl-letf)
`(cl-letf ,(mapcar (lambda (binding)
@@ -90,17 +58,8 @@ the function cell of FUNCs rather than their value cell.
,@body)
`(flet ,bindings ,@body)))
-(defun mh-display-color-cells (&optional display)
- "Return the number of color cells supported by DISPLAY.
-This function is used by XEmacs to return 2 when `device-color-cells'
-or `display-color-cells' returns nil. This happens when compiling or
-running on a tty and causes errors since `display-color-cells' is
-expected to return an integer."
- (cond ((fboundp 'display-color-cells) ; GNU Emacs, XEmacs 21.5b28
- (or (display-color-cells display) 2))
- ((fboundp 'device-color-cells) ; XEmacs 21.4
- (or (device-color-cells display) 2))
- (t 2)))
+(define-obsolete-function-alias 'mh-display-color-cells
+ #'display-color-cells "29.1")
(defmacro mh-display-completion-list (completions &optional common-substring)
"Display the list of COMPLETIONS.
@@ -110,209 +69,54 @@ The optional argument COMMON-SUBSTRING, if non-nil, should be a string
specifying a common substring for adding the faces
`completions-first-difference' and `completions-common-part' to
the completions."
- (cond ((< emacs-major-version 22) `(display-completion-list ,completions))
- ((fboundp 'completion-hilit-commonality) ; Emacs 23.1 and later
- `(display-completion-list
- (completion-hilit-commonality ,completions
- ,(length common-substring) nil)))
- (t ; Emacs 22
- `(display-completion-list ,completions ,common-substring))))
-
-(defmacro mh-face-foreground (face &optional frame inherit)
- "Return the foreground color name of FACE, or nil if unspecified.
-See documentation for `face-foreground' for a description of the
-arguments FACE, FRAME, and perhaps INHERIT.
-This macro is used by Emacs versions that lack an INHERIT argument,
-introduced in Emacs 22."
- (if (< emacs-major-version 22)
- `(face-foreground ,face ,frame)
- `(face-foreground ,face ,frame ,inherit)))
-
-(defmacro mh-face-background (face &optional frame inherit)
- "Return the background color name of face, or nil if unspecified.
-See documentation for `face-background' for a description of the
-arguments FACE, FRAME, and INHERIT.
-This macro is used by Emacs versions that lack an INHERIT argument,
-introduced in Emacs 22."
- (if (< emacs-major-version 22)
- `(face-background ,face ,frame)
- `(face-background ,face ,frame ,inherit)))
-
-(defun-mh mh-font-lock-add-keywords font-lock-add-keywords
- (_mode _keywords &optional _how)
- "XEmacs does not have `font-lock-add-keywords'.
-This function returns nil on that system.")
-
-(defun-mh mh-image-load-path-for-library
- image-load-path-for-library (library image &optional path no-error)
- "Return a suitable search path for images used by LIBRARY.
-
-It searches for IMAGE in `image-load-path' (excluding
-\"`data-directory'/images\") and `load-path', followed by a path
-suitable for LIBRARY, which includes \"../../etc/images\" and
-\"../etc/images\" relative to the library file itself, and then
-in \"`data-directory'/images\".
-
-Then this function returns a list of directories which contains
-first the directory in which IMAGE was found, followed by the
-value of `load-path'. If PATH is given, it is used instead of
-`load-path'.
-
-If NO-ERROR is non-nil and a suitable path can't be found, don't
-signal an error. Instead, return a list of directories as before,
-except that nil appears in place of the image directory.
-
-Here is an example that uses a common idiom to provide
-compatibility with versions of Emacs that lack the variable
-`image-load-path':
-
- ;; Shush compiler.
- (defvar image-load-path)
-
- (let* ((load-path (image-load-path-for-library \"mh-e\" \"mh-logo.xpm\"))
- (image-load-path (cons (car load-path)
- (when (boundp \\='image-load-path)
- image-load-path))))
- (mh-tool-bar-folder-buttons-init))"
- (unless library (error "No library specified"))
- (unless image (error "No image specified"))
- (let (image-directory image-directory-load-path)
- ;; Check for images in image-load-path or load-path.
- (let ((img image)
- (dir (or
- ;; Images in image-load-path.
- (mh-image-search-load-path image)
- ;; Images in load-path.
- (locate-library image)))
- parent)
- ;; Since the image might be in a nested directory (for
- ;; example, mail/attach.pbm), adjust `image-directory'
- ;; accordingly.
- (when dir
- (setq dir (file-name-directory dir))
- (while (setq parent (file-name-directory img))
- (setq img (directory-file-name parent)
- dir (expand-file-name "../" dir))))
- (setq image-directory-load-path dir))
-
- ;; If `image-directory-load-path' isn't Emacs's image directory,
- ;; it's probably a user preference, so use it. Then use a
- ;; relative setting if possible; otherwise, use
- ;; `image-directory-load-path'.
- (cond
- ;; User-modified image-load-path?
- ((and image-directory-load-path
- (not (equal image-directory-load-path
- (file-name-as-directory
- (expand-file-name "images" data-directory)))))
- (setq image-directory image-directory-load-path))
- ;; Try relative setting.
- ((let (library-name d1ei d2ei)
- ;; First, find library in the load-path.
- (setq library-name (locate-library library))
- (if (not library-name)
- (error "Cannot find library %s in load-path" library))
- ;; And then set image-directory relative to that.
- (setq
- ;; Go down 2 levels.
- d2ei (file-name-as-directory
- (expand-file-name
- (concat (file-name-directory library-name) "../../etc/images")))
- ;; Go down 1 level.
- d1ei (file-name-as-directory
- (expand-file-name
- (concat (file-name-directory library-name) "../etc/images"))))
- (setq image-directory
- ;; Set it to nil if image is not found.
- (cond ((file-exists-p (expand-file-name image d2ei)) d2ei)
- ((file-exists-p (expand-file-name image d1ei)) d1ei)))))
- ;; Use Emacs's image directory.
- (image-directory-load-path
- (setq image-directory image-directory-load-path))
- (no-error
- (message "Could not find image %s for library %s" image library))
- (t
- (error "Could not find image %s for library %s" image library)))
-
- ;; Return an augmented `path' or `load-path'.
- (nconc (list image-directory)
- (delete image-directory (copy-sequence (or path load-path))))))
-
-(defun-mh mh-image-search-load-path
- image-search-load-path (_file &optional _path)
- "Emacs 21 and XEmacs don't have `image-search-load-path'.
-This function returns nil on those systems."
- nil)
-
-;; For XEmacs.
-(defalias 'mh-line-beginning-position
- (if (fboundp 'line-beginning-position)
- 'line-beginning-position
- 'point-at-bol))
-
-;; For XEmacs.
-(defalias 'mh-line-end-position
- (if (fboundp 'line-end-position)
- 'line-end-position
- 'point-at-eol))
-
-(mh-require 'mailabbrev nil t)
-(defun-mh mh-mail-abbrev-make-syntax-table
- mail-abbrev-make-syntax-table ()
- "Emacs 21 and XEmacs don't have `mail-abbrev-make-syntax-table'.
-This function returns nil on those systems."
- nil)
-
-(defmacro mh-define-obsolete-variable-alias
- (obsolete-name current-name &optional when docstring)
- "Make OBSOLETE-NAME a variable alias for CURRENT-NAME and mark it obsolete.
-See documentation for `define-obsolete-variable-alias' for a description
-of the arguments OBSOLETE-NAME, CURRENT-NAME, and perhaps WHEN
-and DOCSTRING. This macro is used by XEmacs that lacks WHEN and
-DOCSTRING arguments."
- (if (featurep 'xemacs)
- `(define-obsolete-variable-alias ,obsolete-name ,current-name)
- `(define-obsolete-variable-alias ,obsolete-name ,current-name ,when ,docstring)))
-
-(defmacro mh-make-obsolete-variable (obsolete-name current-name &optional when access-type)
- "Make the byte-compiler warn that OBSOLETE-NAME is obsolete.
-See documentation for `make-obsolete-variable' for a description
-of the arguments OBSOLETE-NAME, CURRENT-NAME, and perhaps WHEN
-and ACCESS-TYPE. This macro is used by XEmacs that lacks WHEN and
-ACCESS-TYPE arguments and by Emacs versions that lack ACCESS-TYPE,
-introduced in Emacs 24."
- (if (featurep 'xemacs)
- `(make-obsolete-variable ,obsolete-name ,current-name)
- (if (< emacs-major-version 24)
- `(make-obsolete-variable ,obsolete-name ,current-name ,when)
- `(make-obsolete-variable ,obsolete-name ,current-name ,when ,access-type))))
-
-(defun-mh mh-match-string-no-properties
- match-string-no-properties (num &optional _string)
- "Return string of text matched by last search, without text properties.
-This function is used by XEmacs that lacks `match-string-no-properties'.
-The function `buffer-substring-no-properties' is used instead.
-The argument STRING is ignored."
- (buffer-substring-no-properties
- (match-beginning num) (match-end num)))
-
-(defun-mh mh-replace-regexp-in-string replace-regexp-in-string
- (regexp rep string &optional _fixedcase literal _subexp _start)
- "Replace REGEXP with REP everywhere in STRING and return result.
-This function is used by XEmacs that lacks `replace-regexp-in-string'.
-The function `replace-in-string' is used instead.
-The arguments FIXEDCASE, SUBEXP, and START, used by
-`replace-in-string' are ignored."
- (if (featurep 'xemacs) ; silence Emacs compiler
- (replace-in-string string regexp rep literal)))
-
-(defun-mh mh-test-completion
- test-completion (_string _collection &optional _predicate)
- "Return non-nil if STRING is a valid completion.
-XEmacs does not have `test-completion'. This function returns nil
-on that system." nil)
-
-;; Copy of constant from url-util.el in Emacs 22; needed by Emacs 21.
+ `(display-completion-list
+ (completion-hilit-commonality ,completions
+ ,(length common-substring) nil)))
+
+(define-obsolete-function-alias 'mh-face-foreground
+ #'face-foreground "29.1")
+
+(define-obsolete-function-alias 'mh-face-background
+ #'face-background "29.1")
+
+(define-obsolete-function-alias 'mh-font-lock-add-keywords
+ #'font-lock-add-keywords "29.1")
+
+;; Not preloaded in without-x builds.
+(declare-function image-load-path-for-library "image")
+(define-obsolete-function-alias 'mh-image-load-path-for-library
+ #'image-load-path-for-library "29.1")
+
+;; Not preloaded in without-x builds.
+(declare-function image-search-load-path "image")
+(define-obsolete-function-alias 'mh-image-search-load-path
+ #'image-search-load-path "29.1")
+
+(define-obsolete-function-alias 'mh-line-beginning-position
+ #'line-beginning-position "29.1")
+
+(define-obsolete-function-alias 'mh-line-end-position
+ #'line-end-position "29.1")
+
+(require 'mailabbrev nil t)
+(define-obsolete-function-alias 'mh-mail-abbrev-make-syntax-table
+ #'mail-abbrev-make-syntax-table "29.1")
+
+(define-obsolete-function-alias 'mh-define-obsolete-variable-alias
+ #'define-obsolete-variable-alias "29.1")
+
+(define-obsolete-function-alias 'mh-make-obsolete-variable
+ #'make-obsolete-variable "29.1")
+
+(define-obsolete-function-alias 'mh-match-string-no-properties
+ #'match-string-no-properties "29.1")
+
+(define-obsolete-function-alias 'mh-replace-regexp-in-string
+ #'replace-regexp-in-string "29.1")
+
+(define-obsolete-function-alias 'mh-test-completion
+ #'test-completion "29.1")
+
(defconst mh-url-unreserved-chars
'(
?a ?b ?c ?d ?e ?f ?g ?h ?i ?j ?k ?l ?m ?n ?o ?p ?q ?r ?s ?t ?u ?v ?w ?x ?y ?z
@@ -321,51 +125,21 @@ on that system." nil)
?- ?_ ?. ?! ?~ ?* ?' ?\( ?\))
"A list of characters that are _NOT_ reserved in the URL spec.
This is taken from RFC 2396.")
+(make-obsolete-variable 'mh-url-unreserved-chars 'url-unreserved-chars "29.1")
+
+(define-obsolete-function-alias 'mh-url-hexify-string
+ #'url-hexify-string "29.1")
+
+(define-obsolete-function-alias 'mh-view-mode-enter
+ #'view-mode-enter "29.1")
-(defun-mh mh-url-hexify-string url-hexify-string (str)
- "Escape characters in a string.
-This is a copy of `url-hexify-string' from url-util.el in Emacs
-22; needed by Emacs 21."
- (mapconcat
- (lambda (char)
- ;; Fixme: use a char table instead.
- (if (not (memq char mh-url-unreserved-chars))
- (if (> char 255)
- (error "Hexifying multibyte character %s" str)
- (format "%%%02X" char))
- (char-to-string char)))
- str ""))
-
-(defun-mh mh-view-mode-enter
- view-mode-enter (&optional return-to exit-action)
- "Enter View mode.
-This function is used by XEmacs that lacks `view-mode-enter'.
-The function `view-mode' is used instead.
-The arguments RETURN-TO and EXIT-ACTION are ignored."
- ;; Shush compiler.
- (if return-to nil)
- (if exit-action nil)
- (view-mode 1))
-
-(defun-mh mh-window-full-height-p
- window-full-height-p (&optional _window)
- "Return non-nil if WINDOW is not the result of a vertical split.
-This function is defined in XEmacs as it lacks
-`window-full-height-p'. The values of the functions
-`window-height' and `frame-height' are compared instead. The
-argument WINDOW is ignored."
- (= (1+ (window-height))
- (frame-height)))
+(define-obsolete-function-alias 'mh-window-full-height-p
+ #'window-full-height-p "29.1")
(defmacro mh-write-file-functions ()
- "Return `write-file-functions' if it exists.
-Otherwise return `local-write-file-hooks'.
-This macro exists purely for compatibility. The former symbol is used
-in Emacs 22 onward while the latter is used in previous versions and
-XEmacs."
- (if (boundp 'write-file-functions)
- ''write-file-functions ;Emacs 22 on
- ''local-write-file-hooks)) ;XEmacs
+ "Return `write-file-functions'."
+ (declare (obsolete nil "29.1"))
+ ''write-file-functions)
(provide 'mh-compat)
diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el
index 949787a2501..17faff0716c 100644
--- a/lisp/mh-e/mh-e.el
+++ b/lisp/mh-e/mh-e.el
@@ -26,14 +26,11 @@
;; MH-E is an Emacs interface to the MH mail system.
-;; MH-E is supported in GNU Emacs 21 and higher, as well as XEmacs 21
-;; (except for versions 21.5.9-21.5.16). It is compatible with MH
-;; versions 6.8.4 and higher, all versions of nmh, and GNU mailutils
-;; 1.0 and higher. Gnus is also required; version 5.10 or higher is
-;; recommended.
+;; MH-E is compatible with MH versions 6.8.4 and higher, all versions
+;; of nmh, and GNU mailutils 1.0 and higher.
;; MH (Message Handler) is a powerful mail reader. See
-;; http://rand-mh.sourceforge.net/.
+;; https://rand-mh.sourceforge.io/.
;; N.B. MH must have been compiled with the MHE compiler flag or several
;; features necessary for MH-E will be missing from MH commands, specifically
@@ -49,12 +46,6 @@
;; (global-set-key "\C-xm" 'mh-smail)
;; (global-set-key "\C-x4m" 'mh-smail-other-window)
-;; If Emacs can't find mh-rmail or mh-smail, add the following to ~/.emacs:
-;; (require 'mh-autoloads)
-
-;; If you want to customize MH-E before explicitly loading it, add this:
-;; (require 'mh-cus-load)
-
;; Mailing Lists:
;; mh-e-users@lists.sourceforge.net
;; mh-e-announce@lists.sourceforge.net
@@ -82,7 +73,8 @@
;; Rewritten for GNU Emacs, James Larus, 1985.
;; Modified by Stephen Gildea, 1988.
;; Maintenance picked up by Bill Wohler and the
-;; SourceForge Crew <http://mh-e.sourceforge.net/>, 2001.
+;; SourceForge Crew <https://mh-e.sourceforge.io/>, 2001.
+;; Since 2016, MH-E development occurs within the Emacs repository.
;;; Code:
@@ -96,29 +88,6 @@
(require 'mh-buffers)
(require 'mh-compat)
-(mh-do-in-xemacs
- (require 'mh-xemacs))
-
-(mh-font-lock-add-keywords
- 'emacs-lisp-mode
- (eval-when-compile
- `((,(concat "(\\("
- ;; Function declarations (use font-lock-function-name-face).
- "\\(def\\(un\\|macro\\)-mh\\)\\|"
- ;; Variable declarations (use font-lock-variable-name-face).
- "\\(def\\(custom\\|face\\)-mh\\)\\|"
- ;; Group declarations (use font-lock-type-face).
- "\\(defgroup-mh\\)"
- "\\)\\>"
- ;; Any whitespace and defined object.
- "[ \t'(]*"
- "\\(setf[ \t]+\\sw+)\\|\\sw+\\)?")
- (1 font-lock-keyword-face)
- (7 (cond ((match-beginning 2) font-lock-function-name-face)
- ((match-beginning 4) font-lock-variable-name-face)
- (t font-lock-type-face))
- nil t)))))
-
;;; Global Variables
@@ -376,15 +345,13 @@ when searching for a separator.")
"This regular expression matches the signature separator.
See `mh-signature-separator'.")
-(defvar mh-thread-scan-line-map nil
+(defvar-local mh-thread-scan-line-map nil
"Map of message index to various parts of the scan line.")
-(make-variable-buffer-local 'mh-thread-scan-line-map)
-(defvar mh-thread-scan-line-map-stack nil
+(defvar-local mh-thread-scan-line-map-stack nil
"Old map of message index to various parts of the scan line.
This is the original map that is stored when the folder is
narrowed.")
-(make-variable-buffer-local 'mh-thread-scan-line-map-stack)
(defcustom mh-x-mailer-string nil
"String containing the contents of the X-Mailer header field.
@@ -494,7 +461,7 @@ all the strings have been used."
(count 0))
(while (and (not (eobp)) (< count mh-index-max-cmdline-args))
(push (buffer-substring-no-properties (point)
- (mh-line-end-position))
+ (line-end-position))
arg-list)
(cl-incf count)
(forward-line))
@@ -627,23 +594,18 @@ Output is expected to be shown to user, not parsed by MH-E."
;; The bug wasn't seen in emacs21 but still occurred in XEmacs21.4.
(mh-exchange-point-and-mark-preserving-active-mark))
-;; Shush compiler.
-(mh-do-in-xemacs
- (defvar mark-active))
-
(defun mh-exchange-point-and-mark-preserving-active-mark ()
"Put the mark where point is now, and point where the mark is now.
This command works even when the mark is not active, and
preserves whether the mark is active or not."
(interactive nil)
- (let ((is-active (and (boundp 'mark-active) mark-active)))
+ (let ((is-active mark-active))
(let ((omark (mark t)))
(if (null omark)
(error "No mark set in this buffer"))
(set-mark (point))
(goto-char omark)
- (if (boundp 'mark-active)
- (setq mark-active is-active))
+ (setq mark-active is-active)
nil)))
(defun mh-exec-lib-cmd-output (command &rest args)
@@ -671,56 +633,39 @@ Set mark after inserted text."
;;; MH-E Customization Support Routines
-;; Shush compiler (Emacs 21 and XEmacs).
-(defvar customize-package-emacs-version-alist)
-
;; Temporary function and data structure used customization.
;; These will be unbound after the options are defined.
(defmacro mh-strip-package-version (args)
- "Strip :package-version keyword and its value from ARGS.
-In Emacs versions that support the :package-version keyword,
-ARGS is returned unchanged."
- `(if (boundp 'customize-package-emacs-version-alist)
- ,args
- (let (seen)
- (cl-loop for keyword in ,args
- if (cond ((eq keyword ':package-version) (setq seen t) nil)
- (seen (setq seen nil) nil)
- (t t))
- collect keyword))))
+ "ARGS is returned unchanged."
+ (declare (obsolete identity "29.1"))
+ args)
(defmacro defgroup-mh (symbol members doc &rest args)
"Declare SYMBOL as a customization group containing MEMBERS.
See documentation for `defgroup' for a description of the arguments
-SYMBOL, MEMBERS, DOC and ARGS.
-This macro is used by Emacs versions that lack the :package-version
-keyword, introduced in Emacs 22."
- (declare (doc-string 3) (indent defun))
- `(defgroup ,symbol ,members ,doc ,@(mh-strip-package-version args)))
+SYMBOL, MEMBERS, DOC and ARGS."
+ (declare (obsolete defgroup "29.1") (doc-string 3) (indent defun))
+ `(defgroup ,symbol ,members ,doc ,args))
(defmacro defcustom-mh (symbol value doc &rest args)
"Declare SYMBOL as a customizable variable that defaults to VALUE.
See documentation for `defcustom' for a description of the arguments
-SYMBOL, VALUE, DOC and ARGS.
-This macro is used by Emacs versions that lack the :package-version
-keyword, introduced in Emacs 22."
- (declare (doc-string 3) (indent defun))
- `(defcustom ,symbol ,value ,doc ,@(mh-strip-package-version args)))
+SYMBOL, VALUE, DOC and ARGS."
+ (declare (obsolete defcustom "29.1") (doc-string 3) (indent defun))
+ `(defcustom ,symbol ,value ,doc ,args))
(defmacro defface-mh (face spec doc &rest args)
"Declare FACE as a customizable face that defaults to SPEC.
See documentation for `defface' for a description of the arguments
-FACE, SPEC, DOC and ARGS.
-This macro is used by Emacs versions that lack the :package-version
-keyword, introduced in Emacs 22."
- (declare (doc-string 3) (indent defun))
- `(defface ,face ,spec ,doc ,@(mh-strip-package-version args)))
+FACE, SPEC, DOC and ARGS."
+ (declare (obsolete defface "29.1") (doc-string 3) (indent defun))
+ `(defface ,face ,spec ,doc ,args))
;;; Variant Support
-(defcustom-mh mh-path nil
+(defcustom mh-path nil
"Additional list of directories to search for MH.
See `mh-variant'."
:group 'mh-e
@@ -793,14 +738,16 @@ is described by the variable `mh-variants'."
(defun mh-variant-gnu-mh-info (dir)
"Return info for GNU mailutils MH variant in DIR.
This assumes that a temporary buffer is set up."
- ;; 'mhparam -version' output:
+ ;; Sample '-version' outputs:
;; mhparam (GNU mailutils 0.3.2)
- (let ((mhparam (expand-file-name "mhparam" dir)))
- (when (mh-file-command-p mhparam)
+ ;; install-mh (GNU Mailutils 2.2)
+ ;; install-mh (GNU Mailutils 3.7)
+ (let ((install-mh (expand-file-name "install-mh" dir)))
+ (when (mh-file-command-p install-mh)
(erase-buffer)
- (call-process mhparam nil '(t nil) nil "-version")
+ (call-process install-mh nil '(t nil) nil "-version")
(goto-char (point-min))
- (when (search-forward-regexp "mhparam (\\(GNU [Mm]ailutils \\S +\\))"
+ (when (search-forward-regexp "install-mh (\\(GNU [Mm]ailutils \\S +\\))"
nil t)
(let ((version (match-string 1))
(mh-progs dir))
@@ -814,14 +761,15 @@ This assumes that a temporary buffer is set up."
(defun mh-variant-nmh-info (dir)
"Return info for nmh variant in DIR assuming a temporary buffer is set up."
- ;; `mhparam -version' outputs:
+ ;; Sample '-version' outputs:
;; mhparam -- nmh-1.1-RC1 [compiled on chaak at Fri Jun 20 11:03:28 PDT 2003]
- (let ((mhparam (expand-file-name "mhparam" dir)))
- (when (mh-file-command-p mhparam)
+ ;; install-mh -- nmh-1.7.1 built October 26, 2019 on build-server-000
+ (let ((install-mh (expand-file-name "install-mh" dir)))
+ (when (mh-file-command-p install-mh)
(erase-buffer)
- (call-process mhparam nil '(t nil) nil "-version")
+ (call-process install-mh nil '(t nil) nil "-version")
(goto-char (point-min))
- (when (search-forward-regexp "mhparam -- nmh-\\(\\S +\\)" nil t)
+ (when (search-forward-regexp "install-mh -- nmh-\\(\\S +\\)" nil t)
(let ((version (format "nmh %s" (match-string 1)))
(mh-progs dir))
`(,version
@@ -952,7 +900,7 @@ finally GNU mailutils MH."
(mapconcat (lambda (x) (format "%s" (car x)))
(mh-variants) " or "))))))
-(defcustom-mh mh-variant 'autodetect
+(defcustom mh-variant 'autodetect
"Specifies the variant used by MH-E.
The default setting of this option is \"Auto-detect\" which means
@@ -1028,19 +976,18 @@ windows in the frame are removed."
(when delete-other-windows-flag
(delete-other-windows)))
-(if (boundp 'customize-package-emacs-version-alist)
- (add-to-list 'customize-package-emacs-version-alist
- '(MH-E ("6.0" . "22.1") ("6.1" . "22.1") ("7.0" . "22.1")
- ("7.1" . "22.1") ("7.2" . "22.1") ("7.3" . "22.1")
- ("7.4" . "22.1") ("8.0" . "22.1") ("8.1" . "23.1")
- ("8.2" . "23.1") ("8.3" . "24.1") ("8.4" . "24.4")
- ("8.5" . "24.4") ("8.6" . "24.4"))))
+(add-to-list 'customize-package-emacs-version-alist
+ '(MH-E ("6.0" . "22.1") ("6.1" . "22.1") ("7.0" . "22.1")
+ ("7.1" . "22.1") ("7.2" . "22.1") ("7.3" . "22.1")
+ ("7.4" . "22.1") ("8.0" . "22.1") ("8.1" . "23.1")
+ ("8.2" . "23.1") ("8.3" . "24.1") ("8.4" . "24.4")
+ ("8.5" . "24.4") ("8.6" . "24.4")))
;;; MH-E Customization Groups
-(defgroup-mh mh-e nil
+(defgroup mh-e nil
"Emacs interface to the MH mail system.
MH is the Rand Mail Handler. Other implementations include nmh
and GNU mailutils."
@@ -1048,126 +995,126 @@ and GNU mailutils."
:group 'mail
:package-version '(MH-E . "8.0"))
-(defgroup-mh mh-alias nil
+(defgroup mh-alias nil
"Aliases."
:link '(custom-manual "(mh-e)Aliases")
:prefix "mh-alias-"
:group 'mh-e
:package-version '(MH-E . "7.1"))
-(defgroup-mh mh-folder nil
+(defgroup mh-folder nil
"Organizing your mail with folders."
:prefix "mh-"
:link '(custom-manual "(mh-e)Folders")
:group 'mh-e
:package-version '(MH-E . "7.1"))
-(defgroup-mh mh-folder-selection nil
+(defgroup mh-folder-selection nil
"Folder selection."
:prefix "mh-"
:link '(custom-manual "(mh-e)Folder Selection")
:group 'mh-e
:package-version '(MH-E . "8.0"))
-(defgroup-mh mh-identity nil
+(defgroup mh-identity nil
"Identities."
:link '(custom-manual "(mh-e)Identities")
:prefix "mh-identity-"
:group 'mh-e
:package-version '(MH-E . "7.1"))
-(defgroup-mh mh-inc nil
+(defgroup mh-inc nil
"Incorporating your mail."
:prefix "mh-inc-"
:link '(custom-manual "(mh-e)Incorporating Mail")
:group 'mh-e
:package-version '(MH-E . "8.0"))
-(defgroup-mh mh-junk nil
+(defgroup mh-junk nil
"Dealing with junk mail."
:link '(custom-manual "(mh-e)Junk")
:prefix "mh-junk-"
:group 'mh-e
:package-version '(MH-E . "7.3"))
-(defgroup-mh mh-letter nil
+(defgroup mh-letter nil
"Editing a draft."
:prefix "mh-"
:link '(custom-manual "(mh-e)Editing Drafts")
:group 'mh-e
:package-version '(MH-E . "7.1"))
-(defgroup-mh mh-ranges nil
+(defgroup mh-ranges nil
"Ranges."
:prefix "mh-"
:link '(custom-manual "(mh-e)Ranges")
:group 'mh-e
:package-version '(MH-E . "8.0"))
-(defgroup-mh mh-scan-line-formats nil
+(defgroup mh-scan-line-formats nil
"Scan line formats."
:link '(custom-manual "(mh-e)Scan Line Formats")
:prefix "mh-"
:group 'mh-e
:package-version '(MH-E . "8.0"))
-(defgroup-mh mh-search nil
+(defgroup mh-search nil
"Searching."
:link '(custom-manual "(mh-e)Searching")
:prefix "mh-search-"
:group 'mh-e
:package-version '(MH-E . "8.0"))
-(defgroup-mh mh-sending-mail nil
+(defgroup mh-sending-mail nil
"Sending mail."
:prefix "mh-"
:link '(custom-manual "(mh-e)Sending Mail")
:group 'mh-e
:package-version '(MH-E . "8.0"))
-(defgroup-mh mh-sequences nil
+(defgroup mh-sequences nil
"Sequences."
:prefix "mh-"
:link '(custom-manual "(mh-e)Sequences")
:group 'mh-e
:package-version '(MH-E . "8.0"))
-(defgroup-mh mh-show nil
+(defgroup mh-show nil
"Reading your mail."
:prefix "mh-"
:link '(custom-manual "(mh-e)Reading Mail")
:group 'mh-e
:package-version '(MH-E . "7.1"))
-(defgroup-mh mh-speedbar nil
+(defgroup mh-speedbar nil
"The speedbar."
:prefix "mh-speed-"
:link '(custom-manual "(mh-e)Speedbar")
:group 'mh-e
:package-version '(MH-E . "8.0"))
-(defgroup-mh mh-thread nil
+(defgroup mh-thread nil
"Threading."
:prefix "mh-thread-"
:link '(custom-manual "(mh-e)Threading")
:group 'mh-e
:package-version '(MH-E . "8.0"))
-(defgroup-mh mh-tool-bar nil
+(defgroup mh-tool-bar nil
"The tool bar"
:link '(custom-manual "(mh-e)Tool Bar")
:prefix "mh-"
:group 'mh-e
:package-version '(MH-E . "8.0"))
-(defgroup-mh mh-hooks nil
+(defgroup mh-hooks nil
"MH-E hooks."
:link '(custom-manual "(mh-e)Top")
:prefix "mh-"
:group 'mh-e
:package-version '(MH-E . "7.1"))
-(defgroup-mh mh-faces nil
+(defgroup mh-faces nil
"Faces used in MH-E."
:link '(custom-manual "(mh-e)Top")
:prefix "mh-"
@@ -1183,7 +1130,7 @@ and GNU mailutils."
;;; Aliases (:group 'mh-alias)
-(defcustom-mh mh-alias-completion-ignore-case-flag t
+(defcustom mh-alias-completion-ignore-case-flag t
"Non-nil means don't consider case significant in MH alias completion.
As MH ignores case in the aliases, so too does MH-E. However, you
@@ -1194,7 +1141,7 @@ lowercase for mailing lists and uppercase for people."
:group 'mh-alias
:package-version '(MH-E . "7.1"))
-(defcustom-mh mh-alias-expand-aliases-flag nil
+(defcustom mh-alias-expand-aliases-flag nil
"Non-nil means to expand aliases entered in the minibuffer.
In other words, aliases entered in the minibuffer will be
@@ -1204,7 +1151,7 @@ this expansion is not performed."
:group 'mh-alias
:package-version '(MH-E . "7.1"))
-(defcustom-mh mh-alias-flash-on-comma t
+(defcustom mh-alias-flash-on-comma t
"Specify whether to flash address or warn on translation.
This option controls the behavior when a [comma] is pressed while
@@ -1217,7 +1164,7 @@ does not display a warning if the alias is not found."
:group 'mh-alias
:package-version '(MH-E . "7.1"))
-(defcustom-mh mh-alias-insert-file nil
+(defcustom mh-alias-insert-file nil
"Filename used to store a new MH-E alias.
The default setting of this option is \"Use Aliasfile Profile
@@ -1231,7 +1178,7 @@ name, MH-E will prompt for one of them when MH-E adds an alias."
:group 'mh-alias
:package-version '(MH-E . "7.1"))
-(defcustom-mh mh-alias-insertion-location 'sorted
+(defcustom mh-alias-insertion-location 'sorted
"Specifies where new aliases are entered in alias files.
This option is set to \"Alphabetical\" by default. If you organize
@@ -1243,7 +1190,7 @@ or \"Bottom\" of your alias file might be more appropriate."
:group 'mh-alias
:package-version '(MH-E . "7.1"))
-(defcustom-mh mh-alias-local-users t
+(defcustom mh-alias-local-users t
"Non-nil means local users are added to alias completion.
Aliases are created from \"/etc/passwd\" entries with a user ID
@@ -1264,7 +1211,7 @@ NIS password file."
:group 'mh-alias
:package-version '(MH-E . "7.1"))
-(defcustom-mh mh-alias-local-users-prefix "local."
+(defcustom mh-alias-local-users-prefix "local."
"String prefixed to the real names of users from the password file.
This option can also be set to \"Use Login\".
@@ -1286,7 +1233,7 @@ turned off."
:group 'mh-alias
:package-version '(MH-E . "7.4"))
-(defcustom-mh mh-alias-passwd-gecos-comma-separator-flag t
+(defcustom mh-alias-passwd-gecos-comma-separator-flag t
"Non-nil means the gecos field in the password file uses a comma separator.
In the example in `mh-alias-local-users-prefix', commas are used
@@ -1300,7 +1247,7 @@ whose contents may contain commas, you can turn this option off."
;;; Organizing Your Mail with Folders (:group 'mh-folder)
-(defcustom-mh mh-new-messages-folders t
+(defcustom mh-new-messages-folders t
"Folders searched for the \"unseen\" sequence.
Set this option to \"Inbox\" to search the \"+inbox\" folder or
@@ -1315,7 +1262,7 @@ See also `mh-recursive-folders-flag'."
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-ticked-messages-folders t
+(defcustom mh-ticked-messages-folders t
"Folders searched for `mh-tick-seq'.
Set this option to \"Inbox\" to search the \"+inbox\" folder or
@@ -1330,7 +1277,7 @@ See also `mh-recursive-folders-flag'."
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-large-folder 200
+(defcustom mh-large-folder 200
"The number of messages that indicates a large folder.
If a folder is deemed to be large, that is the number of messages
@@ -1342,7 +1289,7 @@ folders are treated as if they are small."
:group 'mh-folder
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-recenter-summary-flag nil
+(defcustom mh-recenter-summary-flag nil
"Non-nil means to recenter the summary window.
If this option is turned on, recenter the summary window when the
@@ -1351,13 +1298,13 @@ show window is toggled off."
:group 'mh-folder
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-recursive-folders-flag nil
+(defcustom mh-recursive-folders-flag nil
"Non-nil means that commands which operate on folders do so recursively."
:type 'boolean
:group 'mh-folder
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-sortm-args nil
+(defcustom mh-sortm-args nil
"Additional arguments for \"sortm\"\\<mh-folder-mode-map>.
This option is consulted when a prefix argument is used with
@@ -1371,7 +1318,7 @@ an alternate view. For example, (\"-nolimit\" \"-textfield\"
;;; Folder Selection (:group 'mh-folder-selection)
-(defcustom-mh mh-default-folder-for-message-function nil
+(defcustom mh-default-folder-for-message-function nil
"Function to select a default folder for refiling or \"Fcc:\".
When this function is called, the current buffer contains the message
@@ -1383,7 +1330,7 @@ the default, or an empty string to suppress the default entirely."
:group 'mh-folder-selection
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-default-folder-list nil
+(defcustom mh-default-folder-list nil
"List of addresses and folders.
The folder name associated with the first address found in this
@@ -1401,7 +1348,7 @@ for more information."
:group 'mh-folder-selection
:package-version '(MH-E . "7.2"))
-(defcustom-mh mh-default-folder-must-exist-flag t
+(defcustom mh-default-folder-must-exist-flag t
"Non-nil means guessed folder name must exist to be used.
If the derived folder does not exist, and this option is on, then
@@ -1415,7 +1362,7 @@ for more information."
:group 'mh-folder-selection
:package-version '(MH-E . "7.2"))
-(defcustom-mh mh-default-folder-prefix ""
+(defcustom mh-default-folder-prefix ""
"Prefix used for folder names generated from aliases.
The prefix is used to prevent clutter in your mail directory.
@@ -1434,7 +1381,7 @@ for more information."
Real definition will take effect when mh-identity is loaded."
nil)))
-(defcustom-mh mh-identity-list nil
+(defcustom mh-identity-list nil
"List of identities.
To customize this option, click on the \"INS\" button and enter a label
@@ -1503,7 +1450,7 @@ fashion."
:group 'mh-identity
:package-version '(MH-E . "7.1"))
-(defcustom-mh mh-auto-fields-list nil
+(defcustom mh-auto-fields-list nil
"List of recipients for which header lines are automatically inserted.
This option can be used to set the identity depending on the
@@ -1564,14 +1511,14 @@ as the result is undefined."
:group 'mh-identity
:package-version '(MH-E . "7.3"))
-(defcustom-mh mh-auto-fields-prompt-flag t
+(defcustom mh-auto-fields-prompt-flag t
"Non-nil means to prompt before sending if fields inserted.
See `mh-auto-fields-list'."
:type 'boolean
:group 'mh-identity
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-identity-default nil
+(defcustom mh-identity-default nil
"Default identity to use when `mh-letter-mode' is called.
See `mh-identity-list'."
:type (append
@@ -1582,7 +1529,7 @@ See `mh-identity-list'."
:group 'mh-identity
:package-version '(MH-E . "7.1"))
-(defcustom-mh mh-identity-handlers
+(defcustom mh-identity-handlers
'(("From" . mh-identity-handler-top)
(":default" . mh-identity-handler-bottom)
(":attribution-verb" . mh-identity-handler-attribution-verb)
@@ -1618,7 +1565,7 @@ containing the VALUE for the field is given."
;;; Incorporating Your Mail (:group 'mh-inc)
-(defcustom-mh mh-inc-prog "inc"
+(defcustom mh-inc-prog "inc"
"Program to incorporate new mail into a folder.
This program generates a one-line summary for each of the new
@@ -1637,7 +1584,7 @@ several scan line format variables appropriately."
Real definition will take effect when mh-inc is loaded."
nil)))
-(defcustom-mh mh-inc-spool-list nil
+(defcustom mh-inc-spool-list nil
"Alternate spool files.
You can use the `mh-inc-spool-list' variable to direct MH-E to
@@ -1660,17 +1607,14 @@ on the \"INS\" button. Enter a \"Spool File\" of \"~/mail/mh-e\", a
\"Folder\" of \"mh-e\", and a \"Key Binding\" of \"m\".
You can use \"xbuffy\" to automate the incorporation of this mail
-using the Emacs 22 command \"emacsclient\" as follows:
+using \"emacsclient\" as follows:
box ~/mail/mh-e
title mh-e
origMode
polltime 10
headertime 0
- command emacsclient --eval \\='(mh-inc-spool-mh-e)\\='
-
-In XEmacs, the command \"gnuclient\" is used in a similar
-fashion."
+ command emacsclient --eval \\='(mh-inc-spool-mh-e)\\='"
:type '(repeat (list (file :tag "Spool File")
(string :tag "Folder")
(character :tag "Key Binding")))
@@ -1710,7 +1654,7 @@ The function is always called with SYMBOL bound to
until (executable-find (symbol-name (car element)))
finally return (car element)))))
-(defcustom-mh mh-junk-background nil
+(defcustom mh-junk-background nil
"If on, spam programs are run in background.
By default, the programs are run in the foreground, but this can
@@ -1728,14 +1672,14 @@ may be useful for debugging."
:group 'mh-junk
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-junk-disposition nil
+(defcustom mh-junk-disposition nil
"Disposition of junk mail."
:type '(choice (const :tag "Delete Spam" nil)
(string :tag "Spam Folder"))
:group 'mh-junk
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-junk-program nil
+(defcustom mh-junk-program nil
"Spam program that MH-E should use.
The default setting of this option is \"Auto-detect\" which means
@@ -1753,7 +1697,7 @@ bogofilter, then you can set this option to \"Bogofilter\"."
;;; Editing a Draft (:group 'mh-letter)
-(defcustom-mh mh-compose-insertion (if (locate-library "mml") 'mml 'mh)
+(defcustom mh-compose-insertion (if (locate-library "mml") 'mml 'mh)
"Type of tags used when composing MIME messages.
In addition to MH-style directives, MH-E also supports MML (MIME
@@ -1767,7 +1711,7 @@ MH-style directives are preferred."
:group 'mh-letter
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-compose-skipped-header-fields
+(defcustom mh-compose-skipped-header-fields
'("From" "Organization" "References" "In-Reply-To"
"X-Face" "Face" "X-Image-URL" "X-Mailer")
"List of header fields to skip over when navigating in draft."
@@ -1775,13 +1719,13 @@ MH-style directives are preferred."
:group 'mh-letter
:package-version '(MH-E . "7.4"))
-(defcustom-mh mh-compose-space-does-completion-flag nil
+(defcustom mh-compose-space-does-completion-flag nil
"Non-nil means \\<mh-letter-mode-map>\\[mh-letter-complete-or-space] does completion in message header."
:type 'boolean
:group 'mh-letter
:package-version '(MH-E . "7.4"))
-(defcustom-mh mh-delete-yanked-msg-window-flag nil
+(defcustom mh-delete-yanked-msg-window-flag nil
"Non-nil means delete any window displaying the message.
This deletes the window containing the original message after
@@ -1791,7 +1735,7 @@ more room on your screen for your reply."
:group 'mh-letter
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-extract-from-attribution-verb "wrote:"
+(defcustom mh-extract-from-attribution-verb "wrote:"
"Verb to use for attribution when a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg].
The attribution consists of the sender's name and email address
@@ -1805,7 +1749,7 @@ followed by the content of this option. This option can be set to
:group 'mh-letter
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-ins-buf-prefix "> "
+(defcustom mh-ins-buf-prefix "> "
"String to put before each line of a yanked or inserted message.
The prefix \"> \" is the default setting of this option. I
@@ -1821,17 +1765,17 @@ flavors of `mh-yank-behavior' or you have added a
:group 'mh-letter
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-letter-complete-function 'ispell-complete-word
+(defcustom mh-letter-complete-function 'ispell-complete-word
"Function to call when completing outside of address or folder fields.
In the body of the message,
-\\<mh-letter-mode-map>\\[mh-letter-complete] runs this function,
+\\<mh-letter-mode-map>\\[completion-at-point] runs this function,
which is set to \"ispell-complete-word\" by default."
:type '(choice function (const nil))
:group 'mh-letter
:package-version '(MH-E . "7.1"))
-(defcustom-mh mh-letter-fill-column 72
+(defcustom mh-letter-fill-column 72
"Fill column to use in MH Letter mode.
By default, this option is 72 to allow others to quote your
@@ -1840,7 +1784,7 @@ message without line wrapping."
:group 'mh-letter
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-mml-method-default (if mh-pgp-support-flag "pgpmime" "none")
+(defcustom mh-mml-method-default (if mh-pgp-support-flag "pgpmime" "none")
"Default method to use in security tags.
This option is used to select between a variety of mail security
@@ -1863,7 +1807,7 @@ you write!"
:group 'mh-letter
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-signature-file-name "~/.signature"
+(defcustom mh-signature-file-name "~/.signature"
"Source of user's signature.
By default, the text of your signature is taken from the file
@@ -1886,7 +1830,7 @@ The signature is inserted into your message with the command
:group 'mh-letter
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-signature-separator-flag t
+(defcustom mh-signature-separator-flag t
"Non-nil means a signature separator should be inserted.
It is not recommended that you change this option since various
@@ -1897,7 +1841,7 @@ replying or yanking a letter into a draft."
:group 'mh-letter
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-x-face-file "~/.face"
+(defcustom mh-x-face-file "~/.face"
"File containing face header field to insert in outgoing mail.
If the file starts with either of the strings \"X-Face:\", \"Face:\"
@@ -1926,7 +1870,7 @@ this option doesn't exist."
:group 'mh-letter
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-yank-behavior 'attribution
+(defcustom mh-yank-behavior 'attribution
"Controls which part of a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg].
To include the entire message, including the entire header, use
@@ -1973,7 +1917,7 @@ inserted."
;;; Ranges (:group 'mh-ranges)
-(defcustom-mh mh-interpret-number-as-range-flag t
+(defcustom mh-interpret-number-as-range-flag t
"Non-nil means interpret a number as a range.
Since one of the most frequent ranges used is \"last:N\", MH-E
@@ -1993,7 +1937,7 @@ message 200, then use the range \"200:200\"."
Real definition, below, uses variables that aren't defined yet."
(set-default symbol value))))
-(defcustom-mh mh-adaptive-cmd-note-flag t
+(defcustom mh-adaptive-cmd-note-flag t
"Non-nil means that the message number width is determined dynamically.
If you've created your own format to handle long message numbers,
@@ -2022,7 +1966,7 @@ set SYMBOL to VALUE."
"unless you use \"Use MH-E scan Format\"")
(set-default symbol value)))
-(defcustom-mh mh-scan-format-file t
+(defcustom mh-scan-format-file t
"Specifies the format file to pass to the scan program.
The default setting for this option is \"Use MH-E scan Format\". This
@@ -2061,7 +2005,7 @@ Otherwise, set SYMBOL to VALUE."
"is set to \"Use MH-E scan Format\"")
(set-default symbol value)))
-(defcustom-mh mh-scan-prog "scan"
+(defcustom mh-scan-prog "scan"
"Program used to scan messages.
The name of the program that generates a listing of one line per
@@ -2076,7 +2020,7 @@ directory. You may link another program to `scan' (see
;;; Searching (:group 'mh-search)
-(defcustom-mh mh-search-program nil
+(defcustom mh-search-program nil
"Search program that MH-E shall use.
The default setting of this option is \"Auto-detect\" which means
@@ -2099,7 +2043,7 @@ MH-E can be found in the documentation of `mh-search'."
;;; Sending Mail (:group 'mh-sending-mail)
-(defcustom-mh mh-compose-forward-as-mime-flag t
+(defcustom mh-compose-forward-as-mime-flag t
"Non-nil means that messages are forwarded as attachments.
By default, this option is on which means that the forwarded
@@ -2115,7 +2059,7 @@ regardless of the settings of this option."
:group 'mh-sending-mail
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-compose-letter-function nil
+(defcustom mh-compose-letter-function nil
"Invoked when starting a new draft.
However, it is the last function called before you edit your
@@ -2127,13 +2071,13 @@ fields."
:group 'mh-sending-mail
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-compose-prompt-flag nil
+(defcustom mh-compose-prompt-flag nil
"Non-nil means prompt for header fields when composing a new draft."
:type 'boolean
:group 'mh-sending-mail
:package-version '(MH-E . "7.4"))
-(defcustom-mh mh-forward-subject-format "%s: %s"
+(defcustom mh-forward-subject-format "%s: %s"
"Format string for forwarded message subject.
This option is a string which includes two escapes (\"%s\"). The
@@ -2143,7 +2087,7 @@ and the second one is replaced with the original \"Subject:\"."
:group 'mh-sending-mail
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-insert-x-mailer-flag t
+(defcustom mh-insert-x-mailer-flag t
"Non-nil means append an \"X-Mailer:\" header field to the header.
This header field includes the version of MH-E and Emacs that you
@@ -2153,7 +2097,7 @@ can turn this option off."
:group 'mh-sending-mail
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-redist-full-contents-flag nil
+(defcustom mh-redist-full-contents-flag nil
"Non-nil means the \"dist\" command needs entire letter for redistribution.
This option must be turned on if \"dist\" requires the whole
@@ -2165,7 +2109,7 @@ has been redistributed before, turn off this option."
:group 'mh-sending-mail
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-reply-default-reply-to nil
+(defcustom mh-reply-default-reply-to nil
"Sets the person or persons to whom a reply will be sent.
This option is set to \"Prompt\" by default so that you are
@@ -2181,7 +2125,7 @@ this option to \"cc\". Other choices include \"from\", \"to\", or
:group 'mh-sending-mail
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-reply-show-message-flag t
+(defcustom mh-reply-show-message-flag t
"Non-nil means the MH-Show buffer is displayed when replying.
If you include the message automatically, you can hide the
@@ -2198,7 +2142,7 @@ See also `mh-reply'."
;; the docstring: "Additional sequences that should not to be preserved can be
;; specified by setting `mh-unpropagated-sequences' appropriately." XXX
-(defcustom-mh mh-refile-preserves-sequences-flag t
+(defcustom mh-refile-preserves-sequences-flag t
"Non-nil means that sequences are preserved when messages are refiled.
If a message is in any sequence (except \"Previous-Sequence:\"
@@ -2209,7 +2153,7 @@ desired, then turn off this option."
:group 'mh-sequences
:package-version '(MH-E . "7.4"))
-(defcustom-mh mh-tick-seq 'tick
+(defcustom mh-tick-seq 'tick
"The name of the MH sequence for ticked messages.
You can customize this option if you already use the \"tick\"
@@ -2221,7 +2165,7 @@ there isn't much advantage to that."
:group 'mh-sequences
:package-version '(MH-E . "7.3"))
-(defcustom-mh mh-update-sequences-after-mh-show-flag t
+(defcustom mh-update-sequences-after-mh-show-flag t
"Non-nil means flush MH sequences to disk after message is shown\\<mh-folder-mode-map>.
Three sequences are maintained internally by MH-E and pushed out
@@ -2236,7 +2180,7 @@ commands."
:group 'mh-sequences
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-allowlist-preserves-sequences-flag t
+(defcustom mh-allowlist-preserves-sequences-flag t
"Non-nil means that sequences are preserved when messages are allowlisted.
If a message is in any sequence (except \"Previous-Sequence:\"
@@ -2249,7 +2193,7 @@ not desired, then turn off this option."
;;; Reading Your Mail (:group 'mh-show)
-(defcustom-mh mh-bury-show-buffer-flag t
+(defcustom mh-bury-show-buffer-flag t
"Non-nil means show buffer is buried.
One advantage of not burying the show buffer is that one can
@@ -2260,7 +2204,7 @@ running \\[electric-buffer-list] to see what I mean."
:group 'mh-show
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-clean-message-header-flag t
+(defcustom mh-clean-message-header-flag t
"Non-nil means remove extraneous header fields.
See also `mh-invisible-header-fields-default' and
@@ -2269,7 +2213,7 @@ See also `mh-invisible-header-fields-default' and
:group 'mh-show
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-decode-mime-flag (not (not (locate-library "mm-decode")))
+(defcustom mh-decode-mime-flag (not (not (locate-library "mm-decode")))
"Non-nil means attachments are handled\\<mh-folder-mode-map>.
MH-E can handle attachments as well if the Gnus `mm-decode'
@@ -2287,7 +2231,7 @@ messages and other graphical widgets. See the options
:group 'mh-show
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-display-buttons-for-alternatives-flag nil
+(defcustom mh-display-buttons-for-alternatives-flag nil
"Non-nil means display buttons for all alternative attachments.
Sometimes, a mail program will produce multiple alternatives of
@@ -2299,7 +2243,7 @@ inline and buttons are shown for each of the other alternatives."
:group 'mh-show
:package-version '(MH-E . "7.4"))
-(defcustom-mh mh-display-buttons-for-inline-parts-flag nil
+(defcustom mh-display-buttons-for-inline-parts-flag nil
"Non-nil means display buttons for all inline attachments\\<mh-folder-mode-map>.
The sender can request that attachments should be viewed inline so
@@ -2322,7 +2266,7 @@ text (including HTML) and images."
:group 'mh-show
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-do-not-confirm-flag nil
+(defcustom mh-do-not-confirm-flag nil
"Non-nil means non-reversible commands do not prompt for confirmation.
Commands such as `mh-pack-folder' prompt to confirm whether to
@@ -2334,7 +2278,7 @@ retracted--without question."
:group 'mh-show
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-fetch-x-image-url nil
+(defcustom mh-fetch-x-image-url nil
"Control fetching of \"X-Image-URL:\" header field image.
This option controls the fetching of the \"X-Image-URL:\" header
@@ -2370,7 +2314,7 @@ turned on."
:group 'mh-show
:package-version '(MH-E . "7.3"))
-(defcustom-mh mh-graphical-smileys-flag t
+(defcustom mh-graphical-smileys-flag t
"Non-nil means graphical smileys are displayed.
It is a long standing custom to inject body language using a
@@ -2385,7 +2329,7 @@ turned off."
:group 'mh-show
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-graphical-emphasis-flag t
+(defcustom mh-graphical-emphasis-flag t
"Non-nil means graphical emphasis is displayed.
A few typesetting features are indicated in ASCII text with
@@ -2402,7 +2346,7 @@ turned off."
:group 'mh-show
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-highlight-citation-style 'gnus
+(defcustom mh-highlight-citation-style 'gnus
"Style for highlighting citations.
If the sender of the message has cited other messages in his
@@ -2824,7 +2768,7 @@ Because the function `mh-invisible-headers' uses both
`mh-invisible-header-fields' and `mh-invisible-header-fields', it
cannot be run until both variables have been initialized.")
-(defcustom-mh mh-invisible-header-fields nil
+(defcustom mh-invisible-header-fields nil
"Additional header fields to hide.
Header fields that you would like to hide that aren't listed in
@@ -2847,7 +2791,7 @@ See also `mh-clean-message-header-flag'."
:group 'mh-show
:package-version '(MH-E . "7.1"))
-(defcustom-mh mh-invisible-header-fields-default nil
+(defcustom mh-invisible-header-fields-default nil
"List of hidden header fields.
The header fields listed in this option are hidden, although you
@@ -2904,7 +2848,7 @@ removed and entries from `mh-invisible-header-fields' are added."
;; Compile invisible header fields.
(mh-invisible-headers)
-(defcustom-mh mh-lpr-command-format "lpr -J '%s'"
+(defcustom mh-lpr-command-format "lpr -J '%s'"
"Command used to print\\<mh-folder-mode-map>.
This option contains the Unix command line which performs the
@@ -2921,7 +2865,7 @@ This option is not used by the commands \\[mh-ps-print-msg] or
:group 'mh-show
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-max-inline-image-height nil
+(defcustom mh-max-inline-image-height nil
"Maximum inline image height if \"Content-Disposition:\" is not present.
Some older mail programs do not insert this needed plumbing to
@@ -2937,7 +2881,7 @@ these numbers."
:group 'mh-show
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-max-inline-image-width nil
+(defcustom mh-max-inline-image-width nil
"Maximum inline image width if \"Content-Disposition:\" is not present.
Some older mail programs do not insert this needed plumbing to
@@ -2953,7 +2897,7 @@ these numbers."
:group 'mh-show
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-mhl-format-file nil
+(defcustom mh-mhl-format-file nil
"Specifies the format file to pass to the \"mhl\" program.
Normally MH-E takes care of displaying messages itself (rather than
@@ -2977,7 +2921,7 @@ file."
:group 'mh-show
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-mime-save-parts-default-directory t
+(defcustom mh-mime-save-parts-default-directory t
"Default directory to use for \\<mh-folder-mode-map>\\[mh-mime-save-parts].
The default value for this option is \"Prompt Always\" so that
@@ -2993,7 +2937,7 @@ directory's name."
:group 'mh-show
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-print-background-flag nil
+(defcustom mh-print-background-flag nil
"Non-nil means messages should be printed in the background\\<mh-folder-mode-map>.
Normally messages are printed in the foreground. If this is slow on
@@ -3009,7 +2953,7 @@ This option is not used by the commands \\[mh-ps-print-msg] or
:group 'mh-show
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-show-maximum-size 0
+(defcustom mh-show-maximum-size 0
"Maximum size of message (in bytes) to display automatically.
This option provides an opportunity to skip over large messages
@@ -3019,7 +2963,7 @@ message are shown regardless of size."
:group 'mh-show
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-show-use-xface-flag (>= emacs-major-version 21)
+(defcustom mh-show-use-xface-flag (>= emacs-major-version 21)
"Non-nil means display face images in MH-show buffers.
MH-E can display the content of \"Face:\", \"X-Face:\", and
@@ -3034,15 +2978,12 @@ and off. This feature will be turned on by default if your system
supports it.
The first header field used, if present, is the Gnus-specific
-\"Face:\" field. The \"Face:\" field appeared in GNU Emacs 21 and
-XEmacs. For more information, see URL
+\"Face:\" field. The \"Face:\" field appeared in Emacs 21.
+For more information, see URL
`https://quimby.gnus.org/circus/face/'. Next is the traditional
\"X-Face:\" header field. The display of this field requires the
\"uncompface\" program (see URL
-`ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.z'). Recent
-versions of XEmacs have internal support for \"X-Face:\" images. If
-your version of XEmacs does not, then you'll need both \"uncompface\"
-and the x-face package (see URL `https://www.jpl.org/ftp/pub/elisp/').
+`ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.z').
Finally, MH-E will display images referenced by the \"X-Image-URL:\"
header field if neither the \"Face:\" nor the \"X-Face:\" fields are
@@ -3059,7 +3000,7 @@ The option `mh-fetch-x-image-url' controls the fetching of the
:group 'mh-show
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-store-default-directory nil
+(defcustom mh-store-default-directory nil
"Default directory for \\<mh-folder-mode-map>\\[mh-store-msg].
If you would like to change the initial default directory,
@@ -3071,7 +3012,7 @@ the content of these messages."
:group 'mh-show
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-summary-height nil
+(defcustom mh-summary-height nil
"Number of lines in MH-Folder buffer (including the mode line).
The default value of this option is \"Automatic\" which means
@@ -3086,7 +3027,7 @@ lines you'd like to see."
;;; The Speedbar (:group 'mh-speedbar)
-(defcustom-mh mh-speed-update-interval 60
+(defcustom mh-speed-update-interval 60
"Time between speedbar updates in seconds.
Set to 0 to disable automatic update."
:type 'integer
@@ -3095,7 +3036,7 @@ Set to 0 to disable automatic update."
;;; Threading (:group 'mh-thread)
-(defcustom-mh mh-show-threads-flag nil
+(defcustom mh-show-threads-flag nil
"Non-nil means new folders start in threaded mode.
Threading large number of messages can be time consuming so this
@@ -3111,7 +3052,7 @@ threaded is less than `mh-large-folder'."
;; mh-tool-bar-folder-buttons and mh-tool-bar-letter-buttons defined
;; dynamically in mh-tool-bar.el.
-(defcustom-mh mh-tool-bar-search-function 'mh-search
+(defcustom mh-tool-bar-search-function 'mh-search
"Function called by the tool bar search button.
By default, this is set to `mh-search'. You can also choose
@@ -3122,47 +3063,11 @@ of your own choosing."
:group 'mh-tool-bar
:package-version '(MH-E . "7.0"))
-;; XEmacs has a couple of extra customizations...
-(mh-do-in-xemacs
- (defcustom-mh mh-xemacs-use-tool-bar-flag mh-xemacs-has-tool-bar-flag
- "If non-nil, use tool bar.
-
-This option controls whether to show the MH-E icons at all. By
-default, this option is turned on if the window system supports
-tool bars. If your system doesn't support tool bars, then you
-won't be able to turn on this option."
- :type 'boolean
- :group 'mh-tool-bar
- :set (lambda (symbol value)
- (if (and (eq value t)
- (not mh-xemacs-has-tool-bar-flag))
- (error "Tool bar not supported"))
- (set-default symbol value))
- :package-version '(MH-E . "7.3"))
-
- (defcustom-mh mh-xemacs-tool-bar-position nil
- "Tool bar location.
-
-This option controls the placement of the tool bar along the four
-edges of the frame. You can choose from one of \"Same As Default
-Tool Bar\", \"Top\", \"Bottom\", \"Left\", or \"Right\". If this
-variable is set to anything other than \"Same As Default Tool
-Bar\" and the default tool bar is in a different location, then
-two tool bars will be displayed: the MH-E tool bar and the
-default tool bar."
- :type '(radio (const :tag "Same As Default Tool Bar" :value nil)
- (const :tag "Top" :value top)
- (const :tag "Bottom" :value bottom)
- (const :tag "Left" :value left)
- (const :tag "Right" :value right))
- :group 'mh-tool-bar
- :package-version '(MH-E . "7.3")))
-
;;; Hooks (:group 'mh-hooks + group where hook described)
-(defcustom-mh mh-after-commands-processed-hook nil
+(defcustom mh-after-commands-processed-hook nil
"Hook run by \\<mh-folder-mode-map>\\[mh-execute-commands] after performing outstanding refile and delete requests.
Variables that are useful in this hook include
@@ -3174,14 +3079,14 @@ folder, which is also available in `mh-current-folder'."
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-alias-reloaded-hook nil
+(defcustom mh-alias-reloaded-hook nil
"Hook run by `mh-alias-reload' after loading aliases."
:type 'hook
:group 'mh-hooks
:group 'mh-alias
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-annotate-msg-hook nil
+(defcustom mh-annotate-msg-hook nil
"Hook run when a message is sent and after annotating the scan lines and message.
Hook functions can access the current folder name with
`mh-current-folder' and obtain the message numbers of the
@@ -3191,7 +3096,7 @@ annotated messages with `mh-annotate-list'."
:group 'mh-sending-mail
:package-version '(MH-E . "8.1"))
-(defcustom-mh mh-before-commands-processed-hook nil
+(defcustom mh-before-commands-processed-hook nil
"Hook run by \\<mh-folder-mode-map>\\[mh-execute-commands] before performing outstanding refile and delete requests.
Variables that are useful in this hook include `mh-delete-list',
@@ -3203,7 +3108,7 @@ used to see which changes will be made to the current folder,
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-before-quit-hook nil
+(defcustom mh-before-quit-hook nil
"Hook run by \\<mh-folder-mode-map>\\[mh-quit] before quitting MH-E.
This hook is called before the quit occurs, so you might use it
@@ -3216,7 +3121,7 @@ See also `mh-quit-hook'."
:group 'mh-folder
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-before-send-letter-hook nil
+(defcustom mh-before-send-letter-hook nil
"Hook run at the beginning of the \\<mh-letter-mode-map>\\[mh-send-letter] command.
For example, if you want to check your spelling in your message
@@ -3227,14 +3132,14 @@ before sending, add the `ispell-message' function."
:group 'mh-letter
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-blocklist-msg-hook nil
+(defcustom mh-blocklist-msg-hook nil
"Hook run by \\<mh-letter-mode-map>\\[mh-junk-blocklist] after marking each message for blocklisting."
:type 'hook
:group 'mh-hooks
:group 'mh-show
:package-version '(MH-E . "8.4"))
-(defcustom-mh mh-delete-msg-hook nil
+(defcustom mh-delete-msg-hook nil
"Hook run by \\<mh-letter-mode-map>\\[mh-delete-msg] after marking each message for deletion.
For example, a past maintainer of MH-E used this once when he
@@ -3244,7 +3149,7 @@ kept statistics on his mail usage."
:group 'mh-show
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-find-path-hook nil
+(defcustom mh-find-path-hook nil
"Hook run by `mh-find-path' after reading the user's MH profile.
This hook can be used the change the value of the variables that
@@ -3255,28 +3160,28 @@ between MH and MH-E."
:group 'mh-e
:package-version '(MH-E . "7.0"))
-(defcustom-mh mh-folder-mode-hook nil
+(defcustom mh-folder-mode-hook nil
"Hook run by `mh-folder-mode' when visiting a new folder."
:type 'hook
:group 'mh-hooks
:group 'mh-folder
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-forward-hook nil
+(defcustom mh-forward-hook nil
"Hook run by `mh-forward' on a forwarded letter."
:type 'hook
:group 'mh-hooks
:group 'mh-sending-mail
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-inc-folder-hook nil
+(defcustom mh-inc-folder-hook nil
"Hook run by \\<mh-folder-mode-map>\\[mh-inc-folder] after incorporating mail into a folder."
:type 'hook
:group 'mh-hooks
:group 'mh-inc
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-insert-signature-hook nil
+(defcustom mh-insert-signature-hook nil
"Hook run by \\<mh-letter-mode-map>\\[mh-insert-signature] after signature has been inserted.
Hook functions may access the actual name of the file or the
@@ -3287,9 +3192,9 @@ function used to insert the signature with
:group 'mh-letter
:package-version '(MH-E . "8.0"))
-(mh-define-obsolete-variable-alias 'mh-kill-folder-suppress-prompt-hooks
+(define-obsolete-variable-alias 'mh-kill-folder-suppress-prompt-hooks
'mh-kill-folder-suppress-prompt-functions "24.3")
-(defcustom-mh mh-kill-folder-suppress-prompt-functions '(mh-search-p)
+(defcustom mh-kill-folder-suppress-prompt-functions '(mh-search-p)
"Abnormal hook run at the beginning of \\<mh-folder-mode-map>\\[mh-kill-folder].
The hook functions are called with no arguments and should return
@@ -3307,7 +3212,7 @@ accident in the \"+inbox\" folder, you will not be happy."
:group 'mh-folder
:package-version '(MH-E . "7.4"))
-(defcustom-mh mh-letter-mode-hook nil
+(defcustom mh-letter-mode-hook nil
"Hook run by `mh-letter-mode' on a new letter.
This hook allows you to do some processing before editing a
@@ -3320,14 +3225,14 @@ go."
:group 'mh-sending-mail
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-mh-to-mime-hook nil
+(defcustom mh-mh-to-mime-hook nil
"Hook run on the formatted letter by \\<mh-letter-mode-map>\\[mh-mh-to-mime]."
:type 'hook
:group 'mh-hooks
:group 'mh-letter
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-search-mode-hook nil
+(defcustom mh-search-mode-hook nil
"Hook run upon entry to `mh-search-mode'\\<mh-folder-mode-map>.
If you find that you do the same thing over and over when editing
@@ -3339,7 +3244,7 @@ This can be done with this hook which is called when
:group 'mh-search
:package-version '(MH-E . "8.0"))
-(defcustom-mh mh-pack-folder-hook nil
+(defcustom mh-pack-folder-hook nil
"Hook run by \\<mh-folder-mode-map>\\[mh-pack-folder] after renumbering the messages.
Hook functions can access the current folder name with `mh-current-folder'."
:type 'hook
@@ -3347,7 +3252,7 @@ Hook functions can access the current folder name with `mh-current-folder'."
:group 'mh-folder
:package-version '(MH-E . "8.2"))
-(defcustom-mh mh-quit-hook nil
+(defcustom mh-quit-hook nil
"Hook run by \\<mh-folder-mode-map>\\[mh-quit] after quitting MH-E.
This hook is not run in an MH-E context, so you might use it to
@@ -3359,14 +3264,14 @@ See also `mh-before-quit-hook'."
:group 'mh-folder
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-refile-msg-hook nil
+(defcustom mh-refile-msg-hook nil
"Hook run by \\<mh-folder-mode-map>\\[mh-refile-msg] after marking each message for refiling."
:type 'hook
:group 'mh-hooks
:group 'mh-folder
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-show-hook nil
+(defcustom mh-show-hook nil
"Hook run after \\<mh-folder-mode-map>\\[mh-show] shows a message.
It is the last thing called after messages are displayed. It's
@@ -3377,7 +3282,7 @@ used to affect the behavior of MH-E in general or when
:group 'mh-show
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-show-mode-hook nil
+(defcustom mh-show-mode-hook nil
"Hook run upon entry to `mh-show-mode'.
This hook is called early on in the process of the message display,
@@ -3389,7 +3294,7 @@ buffer itself. See also `mh-show-hook'."
:group 'mh-show
:package-version '(MH-E . "8.7"))
-(defcustom-mh mh-unseen-updated-hook nil
+(defcustom mh-unseen-updated-hook nil
"Hook run after the unseen sequence has been updated.
The variable `mh-seen-list' can be used by this hook to obtain
@@ -3400,7 +3305,7 @@ sequence."
:group 'mh-sequences
:package-version '(MH-E . "6.0"))
-(defcustom-mh mh-allowlist-msg-hook nil
+(defcustom mh-allowlist-msg-hook nil
"Hook run by \\<mh-letter-mode-map>\\[mh-junk-allowlist] after marking each message for allowlisting."
:type 'hook
:group 'mh-hooks
@@ -3411,15 +3316,10 @@ sequence."
;;; Faces (:group 'mh-faces + group where faces described)
-(if (boundp 'facemenu-unlisted-faces)
- ;; This variable was removed in Emacs 22.1.
- (add-to-list 'facemenu-unlisted-faces "^mh-"))
-
;; To add a new face:
;; 1. Add entry to variable mh-face-data.
-;; 2. Create face using defface-mh (which removes min-color spec and
-;; :package-version keyword where these are not supported),
-;; accessing face data with function mh-face-data.
+;; 2. Create face using defface, accessing face data with function
+;; mh-face-data.
;; 3. Add inherit argument to function mh-face-data if applicable.
(defvar mh-face-data
'((mh-folder-followup
@@ -3566,18 +3466,17 @@ sequence."
(:underline t)))))
"MH-E face data.
Used by function `mh-face-data' which returns spec that is
-consumed by `defface-mh'.")
+consumed by `defface'.")
(require 'cus-face)
-(defvar mh-inherit-face-flag (assq :inherit custom-face-attributes)
- "Non-nil means that the `defface' :inherit keyword is available.
-The :inherit keyword is available on all supported versions of
-GNU Emacs and XEmacs from at least 21.5.23 on.")
+(defvar mh-inherit-face-flag t
+ "Non-nil means that the `defface' :inherit keyword is available.")
+(make-obsolete-variable 'mh-inherit-face-flag nil "29.1")
-(defvar mh-min-colors-defined-flag (and (not (featurep 'xemacs))
- (>= emacs-major-version 22))
+(defvar mh-min-colors-defined-flag t
"Non-nil means `defface' supports min-colors display requirement.")
+(make-obsolete-variable 'mh-min-colors-defined-flag nil "29.1")
(defun mh-face-data (face &optional inherit)
"Return spec for FACE.
@@ -3588,53 +3487,26 @@ keyword, return INHERIT literally; otherwise, return spec for
FACE from the variable `mh-face-data'. This isn't a perfect
implementation. In the case that the :inherit keyword is not
supported, any additional attributes in the inherit parameter are
-not added to the returned spec.
-
-Furthermore, when `mh-min-colors-defined-flag' is nil, this
-function finds display entries with \"min-colors\" requirements
-and either removes the \"min-colors\" requirement or strips the
-display entirely if the display does not support the number of
-specified colors."
- (let ((spec
- (if (and inherit mh-inherit-face-flag)
- inherit
- (or (cadr (assq face mh-face-data))
- (error "Could not find %s in mh-face-data" face)))))
-
- (if mh-min-colors-defined-flag
- spec
- (let ((cells (mh-display-color-cells))
- new-spec)
- ;; Remove entries with min-colors, or delete them if we have
- ;; fewer colors than they specify.
- (cl-loop
- for entry in (reverse spec) do
- (let ((requirement (if (eq (car entry) t)
- nil
- (assq 'min-colors (car entry)))))
- (if requirement
- (when (>= cells (nth 1 requirement))
- (setq new-spec (cons (cons (delq requirement (car entry))
- (cdr entry))
- new-spec)))
- (setq new-spec (cons entry new-spec)))))
- new-spec))))
-
-(defface-mh mh-folder-address
+not added to the returned spec."
+ (or inherit
+ (cadr (assq face mh-face-data))
+ (error "Could not find %s in mh-face-data" face)))
+
+(defface mh-folder-address
(mh-face-data 'mh-folder-subject '((t (:inherit mh-folder-subject))))
"Recipient face."
:group 'mh-faces
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defface-mh mh-folder-blocklisted
+(defface mh-folder-blocklisted
(mh-face-data 'mh-folder-msg-number '((t (:inherit mh-folder-msg-number))))
"Blocklisted message face."
:group 'mh-faces
:group 'mh-folder
:package-version '(MH-E . "8.4"))
-(defface-mh mh-folder-body
+(defface mh-folder-body
(mh-face-data 'mh-folder-msg-number
'((((class color))
(:inherit mh-folder-msg-number))
@@ -3645,7 +3517,7 @@ specified colors."
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defface-mh mh-folder-cur-msg-number
+(defface mh-folder-cur-msg-number
(mh-face-data 'mh-folder-msg-number
'((t (:inherit mh-folder-msg-number :bold t))))
"Current message number face."
@@ -3653,39 +3525,39 @@ specified colors."
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defface-mh mh-folder-date
+(defface mh-folder-date
(mh-face-data 'mh-folder-msg-number '((t (:inherit mh-folder-msg-number))))
"Date face."
:group 'mh-faces
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defface-mh mh-folder-deleted
+(defface mh-folder-deleted
(mh-face-data 'mh-folder-msg-number '((t (:inherit mh-folder-msg-number))))
"Deleted message face."
:group 'mh-faces
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defface-mh mh-folder-followup (mh-face-data 'mh-folder-followup)
+(defface mh-folder-followup (mh-face-data 'mh-folder-followup)
"\"Re:\" face."
:group 'mh-faces
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defface-mh mh-folder-msg-number (mh-face-data 'mh-folder-msg-number)
+(defface mh-folder-msg-number (mh-face-data 'mh-folder-msg-number)
"Message number face."
:group 'mh-faces
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defface-mh mh-folder-refiled (mh-face-data 'mh-folder-refiled)
+(defface mh-folder-refiled (mh-face-data 'mh-folder-refiled)
"Refiled message face."
:group 'mh-faces
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defface-mh mh-folder-sent-to-me-hint
+(defface mh-folder-sent-to-me-hint
(mh-face-data 'mh-folder-msg-number '((t (:inherit mh-folder-date))))
"Fontification hint face in messages sent directly to us.
The detection of messages sent to us is governed by the scan
@@ -3695,7 +3567,7 @@ format `mh-scan-format-nmh' and the regular expression
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defface-mh mh-folder-sent-to-me-sender
+(defface mh-folder-sent-to-me-sender
(mh-face-data 'mh-folder-followup '((t (:inherit mh-folder-followup))))
"Sender face in messages sent directly to us.
The detection of messages sent to us is governed by the scan
@@ -3705,105 +3577,105 @@ format `mh-scan-format-nmh' and the regular expression
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defface-mh mh-folder-subject (mh-face-data 'mh-folder-subject)
+(defface mh-folder-subject (mh-face-data 'mh-folder-subject)
"Subject face."
:group 'mh-faces
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defface-mh mh-folder-tick (mh-face-data 'mh-folder-tick)
+(defface mh-folder-tick (mh-face-data 'mh-folder-tick)
"Ticked message face."
:group 'mh-faces
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defface-mh mh-folder-to (mh-face-data 'mh-folder-to)
+(defface mh-folder-to (mh-face-data 'mh-folder-to)
"\"To:\" face."
:group 'mh-faces
:group 'mh-folder
:package-version '(MH-E . "8.0"))
-(defface-mh mh-folder-allowlisted
+(defface mh-folder-allowlisted
(mh-face-data 'mh-folder-refiled '((t (:inherit mh-folder-refiled))))
"Allowlisted message face."
:group 'mh-faces
:group 'mh-folder
:package-version '(MH-E . "8.4"))
-(defface-mh mh-letter-header-field (mh-face-data 'mh-letter-header-field)
+(defface mh-letter-header-field (mh-face-data 'mh-letter-header-field)
"Editable header field value face in draft buffers."
:group 'mh-faces
:group 'mh-letter
:package-version '(MH-E . "8.0"))
-(defface-mh mh-search-folder (mh-face-data 'mh-search-folder)
+(defface mh-search-folder (mh-face-data 'mh-search-folder)
"Folder heading face in MH-Folder buffers created by searches."
:group 'mh-faces
:group 'mh-search
:package-version '(MH-E . "8.0"))
-(defface-mh mh-show-cc (mh-face-data 'mh-show-cc)
+(defface mh-show-cc (mh-face-data 'mh-show-cc)
"Face used to highlight \"cc:\" header fields."
:group 'mh-faces
:group 'mh-show
:package-version '(MH-E . "8.0"))
-(defface-mh mh-show-date (mh-face-data 'mh-show-date)
+(defface mh-show-date (mh-face-data 'mh-show-date)
"Face used to highlight \"Date:\" header fields."
:group 'mh-faces
:group 'mh-show
:package-version '(MH-E . "8.0"))
-(defface-mh mh-show-from (mh-face-data 'mh-show-from)
+(defface mh-show-from (mh-face-data 'mh-show-from)
"Face used to highlight \"From:\" header fields."
:group 'mh-faces
:group 'mh-show
:package-version '(MH-E . "8.0"))
-(defface-mh mh-show-header (mh-face-data 'mh-show-header)
+(defface mh-show-header (mh-face-data 'mh-show-header)
"Face used to deemphasize less interesting header fields."
:group 'mh-faces
:group 'mh-show
:package-version '(MH-E . "8.0"))
-(defface-mh mh-show-pgg-bad (mh-face-data 'mh-show-pgg-bad)
+(defface mh-show-pgg-bad (mh-face-data 'mh-show-pgg-bad)
"Bad PGG signature face."
:group 'mh-faces
:group 'mh-show
:package-version '(MH-E . "8.0"))
-(defface-mh mh-show-pgg-good (mh-face-data 'mh-show-pgg-good)
+(defface mh-show-pgg-good (mh-face-data 'mh-show-pgg-good)
"Good PGG signature face."
:group 'mh-faces
:group 'mh-show
:package-version '(MH-E . "8.0"))
-(defface-mh mh-show-pgg-unknown (mh-face-data 'mh-show-pgg-unknown)
+(defface mh-show-pgg-unknown (mh-face-data 'mh-show-pgg-unknown)
"Unknown or untrusted PGG signature face."
:group 'mh-faces
:group 'mh-show
:package-version '(MH-E . "8.0"))
-(defface-mh mh-show-signature (mh-face-data 'mh-show-signature)
+(defface mh-show-signature (mh-face-data 'mh-show-signature)
"Signature face."
:group 'mh-faces
:group 'mh-show
:package-version '(MH-E . "8.0"))
-(defface-mh mh-show-subject
+(defface mh-show-subject
(mh-face-data 'mh-folder-subject '((t (:inherit mh-folder-subject))))
"Face used to highlight \"Subject:\" header fields."
:group 'mh-faces
:group 'mh-show
:package-version '(MH-E . "8.0"))
-(defface-mh mh-show-to (mh-face-data 'mh-show-to)
+(defface mh-show-to (mh-face-data 'mh-show-to)
"Face used to highlight \"To:\" header fields."
:group 'mh-faces
:group 'mh-show
:package-version '(MH-E . "8.0"))
-(defface-mh mh-show-xface
+(defface mh-show-xface
(mh-face-data 'mh-show-from '((t (:inherit (mh-show-from highlight)))))
"X-Face image face.
The background and foreground are used in the image."
@@ -3811,13 +3683,13 @@ The background and foreground are used in the image."
:group 'mh-show
:package-version '(MH-E . "8.0"))
-(defface-mh mh-speedbar-folder (mh-face-data 'mh-speedbar-folder)
+(defface mh-speedbar-folder (mh-face-data 'mh-speedbar-folder)
"Basic folder face."
:group 'mh-faces
:group 'mh-speedbar
:package-version '(MH-E . "8.0"))
-(defface-mh mh-speedbar-folder-with-unseen-messages
+(defface mh-speedbar-folder-with-unseen-messages
(mh-face-data 'mh-speedbar-folder
'((t (:inherit mh-speedbar-folder :bold t))))
"Folder face when folder contains unread messages."
@@ -3825,14 +3697,14 @@ The background and foreground are used in the image."
:group 'mh-speedbar
:package-version '(MH-E . "8.0"))
-(defface-mh mh-speedbar-selected-folder
+(defface mh-speedbar-selected-folder
(mh-face-data 'mh-speedbar-selected-folder)
"Selected folder face."
:group 'mh-faces
:group 'mh-speedbar
:package-version '(MH-E . "8.0"))
-(defface-mh mh-speedbar-selected-folder-with-unseen-messages
+(defface mh-speedbar-selected-folder-with-unseen-messages
(mh-face-data 'mh-speedbar-selected-folder
'((t (:inherit mh-speedbar-selected-folder :bold t))))
"Selected folder face when folder contains unread messages."
diff --git a/lisp/mh-e/mh-folder.el b/lisp/mh-e/mh-folder.el
index 35277ae46a1..132ac33d269 100644
--- a/lisp/mh-e/mh-folder.el
+++ b/lisp/mh-e/mh-folder.el
@@ -72,10 +72,8 @@ the MH mail system."
;;; Desktop Integration
-;; desktop-buffer-mode-handlers appeared in Emacs 22.
-(if (boundp 'desktop-buffer-mode-handlers)
- (add-to-list 'desktop-buffer-mode-handlers
- '(mh-folder-mode . mh-restore-desktop-buffer)))
+(add-to-list 'desktop-buffer-mode-handlers
+ '(mh-folder-mode . mh-restore-desktop-buffer))
(defun mh-restore-desktop-buffer (_file-name name _misc)
"Restore an MH folder buffer specified in a desktop file.
@@ -213,141 +211,137 @@ annotation.")
(defalias 'mh-alt-visit-folder #'mh-visit-folder)
;; Save the "b" binding for a future `back'. Maybe?
-(gnus-define-keys mh-folder-mode-map
- " " mh-page-msg
- "!" mh-refile-or-write-again
- "'" mh-toggle-tick
- "," mh-header-display
- "." mh-alt-show
- ":" mh-show-preferred-alternative
- ";" mh-toggle-mh-decode-mime-flag
- ">" mh-write-msg-to-file
- "?" mh-help
- "E" mh-extract-rejected-mail
- "M" mh-modify
- "\177" mh-previous-page
- "\C-d" mh-delete-msg-no-motion
- "\t" mh-index-next-folder
- [backtab] mh-index-previous-folder
- "\M-\t" mh-index-previous-folder
- "\e<" mh-first-msg
- "\e>" mh-last-msg
- "\ed" mh-redistribute
- "\r" mh-show
- "^" mh-alt-refile-msg
- "c" mh-copy-msg
- "d" mh-delete-msg
- "e" mh-edit-again
- "f" mh-forward
- "g" mh-goto-msg
- "i" mh-inc-folder
- "k" mh-delete-subject-or-thread
- "m" mh-alt-send
- "n" mh-next-undeleted-msg
- "\M-n" mh-next-unread-msg
- "o" mh-refile-msg
- "p" mh-previous-undeleted-msg
- "\M-p" mh-previous-unread-msg
- "q" mh-quit
- "r" mh-reply
- "s" mh-send
- "t" mh-toggle-showing
- "u" mh-undo
- "v" mh-index-visit-folder
- "x" mh-execute-commands
- "|" mh-pipe-msg)
-
-(gnus-define-keys (mh-folder-map "F" mh-folder-mode-map)
- "?" mh-prefix-help
- "'" mh-index-ticked-messages
- "S" mh-sort-folder
- "c" mh-catchup
- "f" mh-alt-visit-folder
- "k" mh-kill-folder
- "l" mh-list-folders
- "n" mh-index-new-messages
- "o" mh-alt-visit-folder
- "p" mh-pack-folder
- "q" mh-index-sequenced-messages
- "r" mh-rescan-folder
- "s" mh-search
- "u" mh-undo-folder
- "v" mh-visit-folder)
-
-(define-key mh-folder-mode-map "I" mh-inc-spool-map)
-
-(gnus-define-keys (mh-junk-map "J" mh-folder-mode-map)
- "?" mh-prefix-help
- "a" mh-junk-allowlist
- "b" mh-junk-blocklist
- "w" mh-junk-whitelist)
-
-(gnus-define-keys (mh-ps-print-map "P" mh-folder-mode-map)
- "?" mh-prefix-help
- "C" mh-ps-print-toggle-color
- "F" mh-ps-print-toggle-faces
- "f" mh-ps-print-msg-file
- "l" mh-print-msg
- "p" mh-ps-print-msg)
-
-(gnus-define-keys (mh-sequence-map "S" mh-folder-mode-map)
- "'" mh-narrow-to-tick
- "?" mh-prefix-help
- "d" mh-delete-msg-from-seq
- "k" mh-delete-seq
- "l" mh-list-sequences
- "n" mh-narrow-to-seq
- "p" mh-put-msg-in-seq
- "s" mh-msg-is-in-seq
- "w" mh-widen)
-
-(gnus-define-keys (mh-thread-map "T" mh-folder-mode-map)
- "?" mh-prefix-help
- "u" mh-thread-ancestor
- "p" mh-thread-previous-sibling
- "n" mh-thread-next-sibling
- "t" mh-toggle-threads
- "d" mh-thread-delete
- "o" mh-thread-refile)
-
-(gnus-define-keys (mh-limit-map "/" mh-folder-mode-map)
- "'" mh-narrow-to-tick
- "?" mh-prefix-help
- "c" mh-narrow-to-cc
- "g" mh-narrow-to-range
- "m" mh-narrow-to-from
- "s" mh-narrow-to-subject
- "t" mh-narrow-to-to
- "w" mh-widen)
-
-(gnus-define-keys (mh-extract-map "X" mh-folder-mode-map)
- "?" mh-prefix-help
- "s" mh-store-msg ;shar
- "u" mh-store-msg) ;uuencode
-
-(gnus-define-keys (mh-digest-map "D" mh-folder-mode-map)
- " " mh-page-digest
- "?" mh-prefix-help
- "\177" mh-page-digest-backwards
- "b" mh-burst-digest)
-
-(gnus-define-keys (mh-mime-map "K" mh-folder-mode-map)
- "?" mh-prefix-help
- "a" mh-mime-save-parts
- "e" mh-display-with-external-viewer
- "i" mh-folder-inline-mime-part
- "o" mh-folder-save-mime-part
- "t" mh-toggle-mime-buttons
- "v" mh-folder-toggle-mime-part
- "\t" mh-next-button
- [backtab] mh-prev-button
- "\M-\t" mh-prev-button)
-
-(cond
- ((featurep 'xemacs)
- (define-key mh-folder-mode-map [button2] 'mh-show-mouse))
- (t
- (define-key mh-folder-mode-map [mouse-2] 'mh-show-mouse)))
+(define-keymap :keymap mh-folder-mode-map
+ "SPC" #'mh-page-msg
+ "!" #'mh-refile-or-write-again
+ "'" #'mh-toggle-tick
+ "," #'mh-header-display
+ "." #'mh-alt-show
+ ":" #'mh-show-preferred-alternative
+ ";" #'mh-toggle-mh-decode-mime-flag
+ ">" #'mh-write-msg-to-file
+ "?" #'mh-help
+ "E" #'mh-extract-rejected-mail
+ "M" #'mh-modify
+ "DEL" #'mh-previous-page
+ "C-d" #'mh-delete-msg-no-motion
+ "TAB" #'mh-index-next-folder
+ "<backtab>" #'mh-index-previous-folder
+ "C-M-i" #'mh-index-previous-folder
+ "ESC <" #'mh-first-msg
+ "ESC >" #'mh-last-msg
+ "ESC d" #'mh-redistribute
+ "RET" #'mh-show
+ "^" #'mh-alt-refile-msg
+ "c" #'mh-copy-msg
+ "d" #'mh-delete-msg
+ "e" #'mh-edit-again
+ "f" #'mh-forward
+ "g" #'mh-goto-msg
+ "i" #'mh-inc-folder
+ "k" #'mh-delete-subject-or-thread
+ "m" #'mh-alt-send
+ "n" #'mh-next-undeleted-msg
+ "M-n" #'mh-next-unread-msg
+ "o" #'mh-refile-msg
+ "p" #'mh-previous-undeleted-msg
+ "M-p" #'mh-previous-unread-msg
+ "q" #'mh-quit
+ "r" #'mh-reply
+ "s" #'mh-send
+ "t" #'mh-toggle-showing
+ "u" #'mh-undo
+ "v" #'mh-index-visit-folder
+ "x" #'mh-execute-commands
+ "|" #'mh-pipe-msg
+
+ "F" (define-keymap :prefix 'mh-folder-map
+ "?" #'mh-prefix-help
+ "'" #'mh-index-ticked-messages
+ "S" #'mh-sort-folder
+ "c" #'mh-catchup
+ "f" #'mh-alt-visit-folder
+ "k" #'mh-kill-folder
+ "l" #'mh-list-folders
+ "n" #'mh-index-new-messages
+ "o" #'mh-alt-visit-folder
+ "p" #'mh-pack-folder
+ "q" #'mh-index-sequenced-messages
+ "r" #'mh-rescan-folder
+ "s" #'mh-search
+ "u" #'mh-undo-folder
+ "v" #'mh-visit-folder)
+
+ "I" mh-inc-spool-map
+
+ "J" (define-keymap :prefix 'mh-junk-map
+ "?" #'mh-prefix-help
+ "a" #'mh-junk-allowlist
+ "b" #'mh-junk-blocklist
+ "w" #'mh-junk-whitelist)
+
+ "P" (define-keymap :prefix 'mh-ps-print-map
+ "?" #'mh-prefix-help
+ "C" #'mh-ps-print-toggle-color
+ "F" #'mh-ps-print-toggle-faces
+ "f" #'mh-ps-print-msg-file
+ "l" #'mh-print-msg
+ "p" #'mh-ps-print-msg)
+
+ "S" (define-keymap :prefix 'mh-sequence-map
+ "'" #'mh-narrow-to-tick
+ "?" #'mh-prefix-help
+ "d" #'mh-delete-msg-from-seq
+ "k" #'mh-delete-seq
+ "l" #'mh-list-sequences
+ "n" #'mh-narrow-to-seq
+ "p" #'mh-put-msg-in-seq
+ "s" #'mh-msg-is-in-seq
+ "w" #'mh-widen)
+
+ "T" (define-keymap :prefix 'mh-thread-map
+ "?" #'mh-prefix-help
+ "u" #'mh-thread-ancestor
+ "p" #'mh-thread-previous-sibling
+ "n" #'mh-thread-next-sibling
+ "t" #'mh-toggle-threads
+ "d" #'mh-thread-delete
+ "o" #'mh-thread-refile)
+
+ "/" (define-keymap :prefix 'mh-limit-map
+ "'" #'mh-narrow-to-tick
+ "?" #'mh-prefix-help
+ "c" #'mh-narrow-to-cc
+ "g" #'mh-narrow-to-range
+ "m" #'mh-narrow-to-from
+ "s" #'mh-narrow-to-subject
+ "t" #'mh-narrow-to-to
+ "w" #'mh-widen)
+
+ "X" (define-keymap :prefix 'mh-extract-map
+ "?" #'mh-prefix-help
+ "s" #'mh-store-msg ;shar
+ "u" #'mh-store-msg) ;uuencode
+
+ "D" (define-keymap :prefix 'mh-digest-map
+ "SPC" #'mh-page-digest
+ "?" #'mh-prefix-help
+ "DEL" #'mh-page-digest-backwards
+ "b" #'mh-burst-digest)
+
+ "K" (define-keymap :prefix 'mh-mime-map
+ "?" #'mh-prefix-help
+ "a" #'mh-mime-save-parts
+ "e" #'mh-display-with-external-viewer
+ "i" #'mh-folder-inline-mime-part
+ "o" #'mh-folder-save-mime-part
+ "t" #'mh-toggle-mime-buttons
+ "v" #'mh-folder-toggle-mime-part
+ "TAB" #'mh-next-button
+ "<backtab>" #'mh-prev-button
+ "C-M-i" #'mh-prev-button)
+
+ "<mouse-2>" #'mh-show-mouse)
;; "C-c /" prefix is used in mh-folder-mode by pgp.el and mailcrypt
@@ -512,24 +506,14 @@ font-lock is done highlighting.")
;;; MH-Folder Mode
(defmacro mh-remove-xemacs-horizontal-scrollbar ()
- "Get rid of the horizontal scrollbar that XEmacs insists on putting in."
- (when (featurep 'xemacs)
- '(if (and (featurep 'scrollbar)
- (fboundp 'set-specifier))
- (set-specifier horizontal-scrollbar-visible-p nil
- (cons (current-buffer) nil)))))
+ (declare (obsolete nil "29.1"))
+ nil)
;; Register mh-folder-mode as supporting which-function-mode...
-(eval-and-compile (mh-require 'which-func nil t))
+(eval-and-compile (require 'which-func nil t))
(when (and (boundp 'which-func-modes) (listp which-func-modes))
(add-to-list 'which-func-modes 'mh-folder-mode))
-;; Shush compiler.
-(defvar desktop-save-buffer)
-(defvar font-lock-auto-fontify)
-(mh-do-in-xemacs
- (defvar font-lock-defaults))
-
;; Ensure new buffers won't get this mode if default major-mode is nil.
(put 'mh-folder-mode 'mode-class 'special)
@@ -590,80 +574,68 @@ region in the MH-Folder buffer, then the MH-E command will
perform the operation on all messages in that region.
\\{mh-folder-mode-map}"
- (mh-do-in-gnu-emacs
- (unless mh-folder-tool-bar-map
- (mh-tool-bar-folder-buttons-init))
- (if (boundp 'tool-bar-map)
- (set (make-local-variable 'tool-bar-map) mh-folder-tool-bar-map)))
- (mh-do-in-xemacs
- (mh-tool-bar-init :folder))
+ (unless mh-folder-tool-bar-map
+ (mh-tool-bar-folder-buttons-init))
+ (if (boundp 'tool-bar-map)
+ (setq-local tool-bar-map mh-folder-tool-bar-map))
(make-local-variable 'font-lock-defaults)
(setq font-lock-defaults '(mh-folder-font-lock-keywords t))
(make-local-variable 'desktop-save-buffer)
(setq desktop-save-buffer t)
- (mh-make-local-vars
- 'mh-colors-available-flag (mh-colors-available-p)
+ (setq-local
+ mh-colors-available-flag (mh-colors-available-p)
; Do we have colors available
- 'mh-current-folder (buffer-name) ; Name of folder, a string
- 'mh-show-buffer (format "show-%s" (buffer-name)) ; Buffer that displays msgs
- 'mh-folder-filename ; e.g. "/usr/foobar/Mail/inbox/"
+ mh-current-folder (buffer-name) ; Name of folder, a string
+ mh-show-buffer (format "show-%s" (buffer-name)) ; Buffer that displays msgs
+ mh-folder-filename ; e.g. "/usr/foobar/Mail/inbox/"
(file-name-as-directory (mh-expand-file-name (buffer-name)))
- 'mh-display-buttons-for-inline-parts-flag
+ mh-display-buttons-for-inline-parts-flag
mh-display-buttons-for-inline-parts-flag ; Allow for display of buttons to
; be toggled.
- 'mh-arrow-marker (make-marker) ; Marker where arrow is displayed
- 'overlay-arrow-position nil ; Allow for simultaneous display in
- 'overlay-arrow-string ">" ; different MH-E buffers.
- 'mh-showing-mode nil ; Show message also?
- 'mh-refile-list nil ; List of folder names in mh-seq-list
- 'mh-delete-list nil ; List of msgs nums to delete
- 'mh-blocklist nil ; List of messages to process as spam
- 'mh-allowlist nil ; List of messages to process as ham
- 'mh-seq-list nil ; Alist of (seq . msgs) nums
- 'mh-seen-list nil ; List of displayed messages
- 'mh-next-direction 'forward ; Direction to move to next message
- 'mh-view-ops () ; Stack that keeps track of the order
+ mh-arrow-marker (make-marker) ; Marker where arrow is displayed
+ overlay-arrow-position nil ; Allow for simultaneous display in
+ overlay-arrow-string ">" ; different MH-E buffers.
+ mh-showing-mode nil ; Show message also?
+ mh-refile-list nil ; List of folder names in mh-seq-list
+ mh-delete-list nil ; List of msgs nums to delete
+ mh-blocklist nil ; List of messages to process as spam
+ mh-allowlist nil ; List of messages to process as ham
+ mh-seq-list nil ; Alist of (seq . msgs) nums
+ mh-seen-list nil ; List of displayed messages
+ mh-next-direction 'forward ; Direction to move to next message
+ mh-view-ops () ; Stack that keeps track of the order
; in which narrowing/threading has been
; carried out.
- 'mh-folder-view-stack () ; Stack of previous views of the
+ mh-folder-view-stack () ; Stack of previous views of the
; folder.
- 'mh-index-data nil ; If the folder was created by a call
+ mh-index-data nil ; If the folder was created by a call
; to mh-search, this contains info
; about the search results.
- 'mh-index-previous-search nil ; folder, indexer, search-regexp
- 'mh-index-msg-checksum-map nil ; msg -> checksum map
- 'mh-index-checksum-origin-map nil ; checksum -> ( orig-folder, orig-msg )
- 'mh-index-sequence-search-flag nil ; folder resulted from sequence search
- 'mh-first-msg-num nil ; Number of first msg in buffer
- 'mh-last-msg-num nil ; Number of last msg in buffer
- 'mh-msg-count nil ; Number of msgs in buffer
- 'mh-mode-line-annotation nil ; Indicates message range
- 'mh-sequence-notation-history (make-hash-table)
+ mh-index-previous-search nil ; folder, indexer, search-regexp
+ mh-index-msg-checksum-map nil ; msg -> checksum map
+ mh-index-checksum-origin-map nil ; checksum -> ( orig-folder, orig-msg )
+ mh-index-sequence-search-flag nil ; folder resulted from sequence search
+ mh-first-msg-num nil ; Number of first msg in buffer
+ mh-last-msg-num nil ; Number of last msg in buffer
+ mh-msg-count nil ; Number of msgs in buffer
+ mh-mode-line-annotation nil ; Indicates message range
+ mh-sequence-notation-history (make-hash-table)
; Remember what is overwritten by
; mh-note-seq.
- 'imenu-create-index-function 'mh-index-create-imenu-index
+ imenu-create-index-function 'mh-index-create-imenu-index
; Setup imenu support
- 'mh-previous-window-config nil) ; Previous window configuration
- (mh-remove-xemacs-horizontal-scrollbar)
+ mh-previous-window-config nil) ; Previous window configuration
(setq truncate-lines t)
(auto-save-mode -1)
(setq buffer-offer-save t)
- (mh-make-local-hook (mh-write-file-functions))
- (add-hook (mh-write-file-functions) #'mh-execute-commands nil t)
+ (add-hook 'write-file-functions #'mh-execute-commands nil t)
(make-local-variable 'revert-buffer-function)
(make-local-variable 'hl-line-mode) ; avoid pollution
- (mh-funcall-if-exists hl-line-mode 1)
+ (hl-line-mode 1)
(setq revert-buffer-function #'mh-undo-folder)
(add-to-list 'minor-mode-alist '(mh-showing-mode " Show"))
- (mh-do-in-xemacs
- (easy-menu-add mh-folder-sequence-menu)
- (easy-menu-add mh-folder-message-menu)
- (easy-menu-add mh-folder-folder-menu))
(mh-inc-spool-make)
- (mh-set-help mh-folder-mode-help-messages)
- (if (and (featurep 'xemacs)
- font-lock-auto-fontify)
- (turn-on-font-lock))) ; Force font-lock in XEmacs.
+ (mh-set-help mh-folder-mode-help-messages))
@@ -1571,35 +1543,35 @@ after the commands are processed."
(append folders-changed (mh-index-execute-commands))))
;; Then refile messages
- (mh-mapc #'(lambda (folder-msg-list)
- (let* ((dest-folder (symbol-name (car folder-msg-list)))
- (last (car (mh-translate-range dest-folder "last")))
- (msgs (cdr folder-msg-list)))
- (push dest-folder folders-changed)
- (setq redraw-needed-flag t)
- (apply #'mh-exec-cmd
- "refile" "-src" folder dest-folder
- (mh-coalesce-msg-list msgs))
- (mh-delete-scan-msgs msgs)
- ;; Preserve sequences in destination folder...
- (when mh-refile-preserves-sequences-flag
- (clrhash dest-map)
- (cl-loop
- for i from (1+ (or last 0))
- for msg in (sort (copy-sequence msgs) #'<)
- do (cl-loop for seq-name in (gethash msg seq-map)
- do (push i (gethash seq-name dest-map))))
- (maphash
- #'(lambda (seq msgs)
- ;; Can't be run in the background, since the
- ;; current folder is changed by mark this could
- ;; lead to a race condition with the next refile.
- (apply #'mh-exec-cmd "mark"
- "-sequence" (symbol-name seq) dest-folder
- "-add" (mapcar #'(lambda (x) (format "%s" x))
- (mh-coalesce-msg-list msgs))))
- dest-map))))
- mh-refile-list)
+ (mapc (lambda (folder-msg-list)
+ (let* ((dest-folder (symbol-name (car folder-msg-list)))
+ (last (car (mh-translate-range dest-folder "last")))
+ (msgs (cdr folder-msg-list)))
+ (push dest-folder folders-changed)
+ (setq redraw-needed-flag t)
+ (apply #'mh-exec-cmd
+ "refile" "-src" folder dest-folder
+ (mh-coalesce-msg-list msgs))
+ (mh-delete-scan-msgs msgs)
+ ;; Preserve sequences in destination folder...
+ (when mh-refile-preserves-sequences-flag
+ (clrhash dest-map)
+ (cl-loop
+ for i from (1+ (or last 0))
+ for msg in (sort (copy-sequence msgs) #'<)
+ do (cl-loop for seq-name in (gethash msg seq-map)
+ do (push i (gethash seq-name dest-map))))
+ (maphash
+ #'(lambda (seq msgs)
+ ;; Can't be run in the background, since the
+ ;; current folder is changed by mark this could
+ ;; lead to a race condition with the next refile.
+ (apply #'mh-exec-cmd "mark"
+ "-sequence" (symbol-name seq) dest-folder
+ "-add" (mapcar #'(lambda (x) (format "%s" x))
+ (mh-coalesce-msg-list msgs))))
+ dest-map))))
+ mh-refile-list)
(setq mh-refile-list ())
;; Now delete messages
@@ -1642,14 +1614,14 @@ after the commands are processed."
do (cl-loop for seq-name in (gethash msg seq-map)
do (push i (gethash seq-name allow-map))))
(maphash
- #'(lambda (seq msgs)
- ;; Can't be run in background, since the current
- ;; folder is changed by mark this could lead to a
- ;; race condition with the next refile/allowlist.
- (apply #'mh-exec-cmd "mark"
- "-sequence" (symbol-name seq) mh-inbox
- "-add" (mapcar #'(lambda(x) (format "%s" x))
- (mh-coalesce-msg-list msgs))))
+ (lambda (seq msgs)
+ ;; Can't be run in background, since the current
+ ;; folder is changed by mark this could lead to a
+ ;; race condition with the next refile/allowlist.
+ (apply #'mh-exec-cmd "mark"
+ "-sequence" (symbol-name seq) mh-inbox
+ "-add" (mapcar #'(lambda(x) (format "%s" x))
+ (mh-coalesce-msg-list msgs))))
allow-map))
(setq mh-allowlist nil)))
diff --git a/lisp/mh-e/mh-funcs.el b/lisp/mh-e/mh-funcs.el
index 4a5e670c1ef..0c73aae0d79 100644
--- a/lisp/mh-e/mh-funcs.el
+++ b/lisp/mh-e/mh-funcs.el
@@ -147,7 +147,7 @@ Display the results only if something went wrong."
"-recurse"
"-norecurse"))
(goto-char (point-min))
- (mh-view-mode-enter)
+ (view-mode-enter)
(setq view-exit-action 'kill-buffer)
(message "Listing folders...done")))))
diff --git a/lisp/mh-e/mh-gnus.el b/lisp/mh-e/mh-gnus.el
index cc60f7b6640..0e1bde71f20 100644
--- a/lisp/mh-e/mh-gnus.el
+++ b/lisp/mh-e/mh-gnus.el
@@ -29,110 +29,49 @@
(require 'mh-e)
(eval-and-compile
- (mh-require 'gnus-util nil t)
- (mh-require 'mm-bodies nil t)
- (mh-require 'mm-decode nil t)
- (mh-require 'mm-view nil t)
- (mh-require 'mml nil t))
-
-;; Copy of function from gnus-util.el.
-;; TODO This is not in Gnus 5.11.
-(defun-mh mh-gnus-local-map-property gnus-local-map-property (map)
+ (require 'gnus-util nil t)
+ (require 'mm-bodies nil t)
+ (require 'mm-decode nil t)
+ (require 'mm-view nil t)
+ (require 'mml nil t))
+
+(defun mh-gnus-local-map-property (map)
"Return a list suitable for a text property list specifying keymap MAP."
- (cond ((featurep 'xemacs) (list 'keymap map))
- ((>= emacs-major-version 21) (list 'keymap map))
- (t (list 'local-map map))))
-
-;; Copy of function from mm-decode.el.
-(defun-mh mh-mm-merge-handles mm-merge-handles (handles1 handles2)
- (append
- (if (listp (car handles1))
- handles1
- (list handles1))
- (if (listp (car handles2))
- handles2
- (list handles2))))
-
-;; Copy of function from mm-decode.el.
-(defun-mh mh-mm-set-handle-multipart-parameter
- mm-set-handle-multipart-parameter (handle parameter value)
- ;; HANDLE could be a CTL.
- (when handle
- (put-text-property 0 (length (car handle)) parameter value
- (car handle))))
-
-;; Copy of function from mm-view.el.
-(defun-mh mh-mm-inline-text-vcard mm-inline-text-vcard (handle)
- (let ((inhibit-read-only t))
- (mm-insert-inline
- handle
- (concat "\n-- \n"
- (ignore-errors
- (if (fboundp 'vcard-pretty-print)
- (vcard-pretty-print (mm-get-part handle))
- (vcard-format-string
- (vcard-parse-string (mm-get-part handle)
- 'vcard-standard-filter))))))))
-
-;; Function from mm-decode.el used in PGP messages. Just define it with older
-;; Gnus to avoid compiler warning.
-(defun-mh mh-mm-possibly-verify-or-decrypt
- mm-possibly-verify-or-decrypt (_parts _ctl)
- nil)
-
-;; Copy of macro in mm-decode.el.
-(defmacro-mh mh-mm-handle-multipart-ctl-parameter
- mm-handle-multipart-ctl-parameter (handle parameter)
- `(get-text-property 0 ,parameter (car ,handle)))
-
-;; Copy of function in mm-decode.el.
-(defun-mh mh-mm-readable-p mm-readable-p (handle)
- "Say whether the content of HANDLE is readable."
- (and (< (with-current-buffer (mm-handle-buffer handle)
- (buffer-size)) 10000)
- (mm-with-unibyte-buffer
- (mm-insert-part handle)
- (and (eq (mm-body-7-or-8) '7bit)
- (not (mh-mm-long-lines-p 76))))))
-
-;; Copy of function in mm-bodies.el.
-(defun-mh mh-mm-long-lines-p mm-long-lines-p (length)
- "Say whether any of the lines in the buffer is longer than LENGTH."
- (save-excursion
- (goto-char (point-min))
- (end-of-line)
- (while (and (not (eobp))
- (not (> (current-column) length)))
- (forward-line 1)
- (end-of-line))
- (and (> (current-column) length)
- (current-column))))
-
-(defun-mh mh-mm-keep-viewer-alive-p mm-keep-viewer-alive-p (_handle)
- ;; Released Gnus doesn't keep handles associated with externally displayed
- ;; MIME parts. So this will always return nil.
- nil)
-
-(defun-mh mh-mm-destroy-parts mm-destroy-parts (_list)
- "Older versions of Emacs don't have this function."
- nil)
-
-(defun-mh mh-mm-uu-dissect-text-parts mm-uu-dissect-text-parts (_handles)
- "Emacs 21 and XEmacs don't have this function."
- nil)
-
-;; Copy of function in mml.el.
-(defun-mh mh-mml-minibuffer-read-disposition
- mml-minibuffer-read-disposition (type &optional default filename)
- (unless default
- (setq default (mml-content-disposition type filename)))
- (let ((disposition (completing-read
- (format-prompt "Disposition" default)
- '(("attachment") ("inline") (""))
- nil t nil nil default)))
- (if (not (equal disposition ""))
- disposition
- default)))
+ (declare (obsolete nil "29.1"))
+ (list 'keymap map))
+
+(define-obsolete-function-alias 'mh-mm-merge-handles
+ #'mm-merge-handles "29.1")
+
+(define-obsolete-function-alias 'mh-mm-set-handle-multipart-parameter
+ #'mm-set-handle-multipart-parameter "29.1")
+
+(define-obsolete-function-alias 'mh-mm-inline-text-vcard
+ #'mm-inline-text-vcard "29.1")
+
+(define-obsolete-function-alias 'mh-mm-possibly-verify-or-decrypt
+ #'mm-possibly-verify-or-decrypt "29.1")
+
+(define-obsolete-function-alias 'mh-mm-handle-multipart-ctl-parameter
+ #'mm-handle-multipart-ctl-parameter "29.1")
+
+(define-obsolete-function-alias 'mh-mm-readable-p
+ #'mm-readable-p "29.1")
+
+(define-obsolete-function-alias 'mh-mm-long-lines-p
+ #'mm-long-lines-p "29.1")
+
+(define-obsolete-function-alias 'mh-mm-keep-viewer-alive-p
+ #'mm-keep-viewer-alive-p "29.1")
+
+(define-obsolete-function-alias 'mh-mm-destroy-parts
+ #'mm-destroy-parts "29.1")
+
+(define-obsolete-function-alias 'mh-mm-uu-dissect-text-parts
+ #'mm-uu-dissect-text-parts "29.1")
+
+(define-obsolete-function-alias 'mh-mml-minibuffer-read-disposition
+ #'mml-minibuffer-read-disposition "29.1")
;; This is mm-save-part from Gnus 5.11 since that function in Emacs
;; 21.2 is buggy (the args to read-file-name are incorrect) and the
@@ -163,8 +102,8 @@ PROMPT overrides the default one used to ask user for a file name."
(defun mh-mm-text-html-renderer ()
"Find the renderer Gnus is using to display text/html MIME parts."
- (or (and (boundp 'mm-inline-text-html-renderer) mm-inline-text-html-renderer)
- (and (boundp 'mm-text-html-renderer) mm-text-html-renderer)))
+ (declare (obsolete mm-text-html-renderer "29.1"))
+ mm-text-html-renderer)
(provide 'mh-gnus)
diff --git a/lisp/mh-e/mh-identity.el b/lisp/mh-e/mh-identity.el
index ceede0d07cb..994ab713915 100644
--- a/lisp/mh-e/mh-identity.el
+++ b/lisp/mh-e/mh-identity.el
@@ -39,11 +39,10 @@
(autoload 'mml-insert-tag "mml")
-(defvar mh-identity-pgg-default-user-id nil
+(defvar-local mh-identity-pgg-default-user-id nil
"Holds the GPG key ID to be used by pgg.el.
This is normally set as part of an Identity in
`mh-identity-list'.")
-(make-variable-buffer-local 'mh-identity-pgg-default-user-id)
(defvar mh-identity-menu nil
"The Identity menu.")
@@ -54,8 +53,7 @@ This is normally set as part of an Identity in
(defun mh-identity-make-menu ()
"Build the Identity menu.
This should be called any time `mh-identity-list' or
-`mh-auto-fields-list' change.
-See `mh-identity-add-menu'."
+`mh-auto-fields-list' change."
(easy-menu-define mh-identity-menu mh-letter-mode-map
"MH-E identity menu"
(append
@@ -88,12 +86,11 @@ See `mh-identity-add-menu'."
(defun mh-identity-add-menu ()
"Add the current Identity menu.
See `mh-identity-make-menu'."
- (if mh-identity-menu
- (mh-do-in-xemacs (easy-menu-add mh-identity-menu))))
+ (declare (obsolete nil "29.1"))
+ nil)
-(defvar mh-identity-local nil
+(defvar-local mh-identity-local nil
"Buffer-local variable that holds the identity currently in use.")
-(make-variable-buffer-local 'mh-identity-local)
(defun mh-header-field-delete (field value-only)
"Delete header FIELD, or only its value if VALUE-ONLY is t.
@@ -122,7 +119,7 @@ The field name is downcased. If the FIELD begins with the
character \":\", then it must have a special handler defined in
`mh-identity-handlers', else return an error since it is not a
valid header field."
- (or (cdr (mh-assoc-string field mh-identity-handlers t))
+ (or (cdr (assoc-string field mh-identity-handlers t))
(and (eq (aref field 0) ?:)
(error "Field %s not found in `mh-identity-handlers'" field))
(cdr (assoc ":default" mh-identity-handlers))
@@ -235,11 +232,9 @@ added."
(if (null value)
(mh-insert-signature)
(mh-insert-signature value))
- (set (make-local-variable 'mh-identity-signature-start)
- (point-min-marker))
+ (setq-local mh-identity-signature-start (point-min-marker))
(set-marker-insertion-type mh-identity-signature-start t)
- (set (make-local-variable 'mh-identity-signature-end)
- (point-max-marker)))))))
+ (setq-local mh-identity-signature-end (point-max-marker)))))))
(defvar mh-identity-attribution-verb-start nil
"Marker for the beginning of the attribution verb.")
@@ -271,11 +266,9 @@ If VALUE is nil, use `mh-extract-from-attribution-verb'."
(if (null value)
(insert mh-extract-from-attribution-verb)
(insert value))
- (set (make-local-variable 'mh-identity-attribution-verb-start)
- (point-min-marker))
+ (setq-local mh-identity-attribution-verb-start (point-min-marker))
(set-marker-insertion-type mh-identity-attribution-verb-start t)
- (set (make-local-variable 'mh-identity-attribution-verb-end)
- (point-max-marker))))
+ (setq-local mh-identity-attribution-verb-end (point-max-marker))))
(defun mh-identity-handler-default (field action top &optional value)
"Process header FIELD.
diff --git a/lisp/mh-e/mh-junk.el b/lisp/mh-e/mh-junk.el
index 6c3674811b0..2097bcbe1e8 100644
--- a/lisp/mh-e/mh-junk.el
+++ b/lisp/mh-e/mh-junk.el
@@ -31,6 +31,8 @@
(require 'mh-e)
(require 'mh-scan)
+(autoload 'mail-header-parse-address "mail-parse")
+
;;;###mh-autoload
(defun mh-junk-blocklist (range)
"Blocklist RANGE as spam.
@@ -108,8 +110,15 @@ message(s) as specified by the option `mh-junk-disposition'."
;;;###mh-autoload
(defun mh-junk-whitelist (range)
"Old name for `mh-junk-allowlist'; use \\[mh-junk-allowlist] instead."
- (declare (obsolete mh-junk-allowlist "28.1"))
(interactive (list (mh-interactive-range "Allowlist")))
+ ;; We do our own message here instead of using "declare obsolete"
+ ;; in order to talk about keys instead of function names. Also, it
+ ;; lets us bind "J w" to this without the Emacs 29 compiler complaining.
+ (when (not (get 'mh-junk-whitelist 'command-execute-obsolete-warned))
+ (message "%s is an obsolete key (as of 28.1); use %s instead"
+ (substitute-command-keys "\\[mh-junk-whitelist]")
+ (substitute-command-keys "\\[mh-junk-allowlist]"))
+ (put 'mh-junk-whitelist 'command-execute-obsolete-warned t))
(mh-junk-allowlist range))
;;;###mh-autoload
@@ -312,8 +321,7 @@ See `mh-spamassassin-blocklist' for more information."
"--ham" "--local" "--no-sync")))
(message "Allowlisting sender of message %d..." msg)
(setq from
- (car (mh-funcall-if-exists
- ietf-drums-parse-address (mh-get-header-field "From:"))))
+ (car (mail-header-parse-address (mh-get-header-field "From:"))))
(kill-buffer nil)
(if (or (null from) (equal from ""))
(message "Allowlisting sender of message %d...%s"
diff --git a/lisp/mh-e/mh-letter.el b/lisp/mh-e/mh-letter.el
index ae5b80d5807..ebe94a7af83 100644
--- a/lisp/mh-e/mh-letter.el
+++ b/lisp/mh-e/mh-letter.el
@@ -114,68 +114,68 @@
;;; MH-Letter Keys
;; If this changes, modify mh-letter-mode-help-messages accordingly, above.
-(gnus-define-keys mh-letter-mode-map
- " " mh-letter-complete-or-space
- "," mh-letter-confirm-address
- "\C-c?" mh-help
- "\C-c\C-\\" mh-fully-kill-draft ;if no C-q
- "\C-c\C-^" mh-insert-signature ;if no C-s
- "\C-c\C-c" mh-send-letter
- "\C-c\C-d" mh-insert-identity
- "\C-c\C-e" mh-mh-to-mime
- "\C-c\C-f\C-a" mh-to-field
- "\C-c\C-f\C-b" mh-to-field
- "\C-c\C-f\C-c" mh-to-field
- "\C-c\C-f\C-d" mh-to-field
- "\C-c\C-f\C-f" mh-to-fcc
- "\C-c\C-f\C-l" mh-to-field
- "\C-c\C-f\C-m" mh-to-field
- "\C-c\C-f\C-r" mh-to-field
- "\C-c\C-f\C-s" mh-to-field
- "\C-c\C-f\C-t" mh-to-field
- "\C-c\C-fa" mh-to-field
- "\C-c\C-fb" mh-to-field
- "\C-c\C-fc" mh-to-field
- "\C-c\C-fd" mh-to-field
- "\C-c\C-ff" mh-to-fcc
- "\C-c\C-fl" mh-to-field
- "\C-c\C-fm" mh-to-field
- "\C-c\C-fr" mh-to-field
- "\C-c\C-fs" mh-to-field
- "\C-c\C-ft" mh-to-field
- "\C-c\C-i" mh-insert-letter
- "\C-c\C-m\C-e" mh-mml-secure-message-encrypt
- "\C-c\C-m\C-f" mh-compose-forward
- "\C-c\C-m\C-g" mh-mh-compose-anon-ftp
- "\C-c\C-m\C-i" mh-compose-insertion
- "\C-c\C-m\C-m" mh-mml-to-mime
- "\C-c\C-m\C-n" mh-mml-unsecure-message
- "\C-c\C-m\C-s" mh-mml-secure-message-sign
- "\C-c\C-m\C-t" mh-mh-compose-external-compressed-tar
- "\C-c\C-m\C-u" mh-mh-to-mime-undo
- "\C-c\C-m\C-x" mh-mh-compose-external-type
- "\C-c\C-mee" mh-mml-secure-message-encrypt
- "\C-c\C-mes" mh-mml-secure-message-signencrypt
- "\C-c\C-mf" mh-compose-forward
- "\C-c\C-mg" mh-mh-compose-anon-ftp
- "\C-c\C-mi" mh-compose-insertion
- "\C-c\C-mm" mh-mml-to-mime
- "\C-c\C-mn" mh-mml-unsecure-message
- "\C-c\C-mse" mh-mml-secure-message-signencrypt
- "\C-c\C-mss" mh-mml-secure-message-sign
- "\C-c\C-mt" mh-mh-compose-external-compressed-tar
- "\C-c\C-mu" mh-mh-to-mime-undo
- "\C-c\C-mx" mh-mh-compose-external-type
- "\C-c\C-o" mh-open-line
- "\C-c\C-q" mh-fully-kill-draft
- "\C-c\C-s" mh-insert-signature
- "\C-c\C-t" mh-letter-toggle-header-field-display
- "\C-c\C-w" mh-check-whom
- "\C-c\C-y" mh-yank-cur-msg
- "\C-c\M-d" mh-insert-auto-fields
- "\M-\t" mh-letter-complete
- "\t" mh-letter-next-header-field-or-indent
- [backtab] mh-letter-previous-header-field)
+(define-keymap :keymap mh-letter-mode-map
+ "SPC" #'mh-letter-complete-or-space
+ "," #'mh-letter-confirm-address
+ "C-c ?" #'mh-help
+ "C-c C-\\" #'mh-fully-kill-draft ;if no C-q
+ "C-c C-^" #'mh-insert-signature ;if no C-s
+ "C-c C-c" #'mh-send-letter
+ "C-c C-d" #'mh-insert-identity
+ "C-c C-e" #'mh-mh-to-mime
+ "C-c C-f C-a" #'mh-to-field
+ "C-c C-f C-b" #'mh-to-field
+ "C-c C-f C-c" #'mh-to-field
+ "C-c C-f C-d" #'mh-to-field
+ "C-c C-f C-f" #'mh-to-fcc
+ "C-c C-f C-l" #'mh-to-field
+ "C-c C-f C-m" #'mh-to-field
+ "C-c C-f C-r" #'mh-to-field
+ "C-c C-f C-s" #'mh-to-field
+ "C-c C-f C-t" #'mh-to-field
+ "C-c C-f a" #'mh-to-field
+ "C-c C-f b" #'mh-to-field
+ "C-c C-f c" #'mh-to-field
+ "C-c C-f d" #'mh-to-field
+ "C-c C-f f" #'mh-to-fcc
+ "C-c C-f l" #'mh-to-field
+ "C-c C-f m" #'mh-to-field
+ "C-c C-f r" #'mh-to-field
+ "C-c C-f s" #'mh-to-field
+ "C-c C-f t" #'mh-to-field
+ "C-c C-i" #'mh-insert-letter
+ "C-c C-m C-e" #'mh-mml-secure-message-encrypt
+ "C-c C-m C-f" #'mh-compose-forward
+ "C-c C-m C-g" #'mh-mh-compose-anon-ftp
+ "C-c C-m TAB" #'mh-compose-insertion
+ "C-c C-m C-m" #'mh-mml-to-mime
+ "C-c C-m C-n" #'mh-mml-unsecure-message
+ "C-c C-m C-s" #'mh-mml-secure-message-sign
+ "C-c C-m C-t" #'mh-mh-compose-external-compressed-tar
+ "C-c C-m C-u" #'mh-mh-to-mime-undo
+ "C-c C-m C-x" #'mh-mh-compose-external-type
+ "C-c C-m e e" #'mh-mml-secure-message-encrypt
+ "C-c C-m e s" #'mh-mml-secure-message-signencrypt
+ "C-c C-m f" #'mh-compose-forward
+ "C-c C-m g" #'mh-mh-compose-anon-ftp
+ "C-c C-m i" #'mh-compose-insertion
+ "C-c C-m m" #'mh-mml-to-mime
+ "C-c C-m n" #'mh-mml-unsecure-message
+ "C-c C-m s e" #'mh-mml-secure-message-signencrypt
+ "C-c C-m s s" #'mh-mml-secure-message-sign
+ "C-c C-m t" #'mh-mh-compose-external-compressed-tar
+ "C-c C-m u" #'mh-mh-to-mime-undo
+ "C-c C-m x" #'mh-mh-compose-external-type
+ "C-c C-o" #'mh-open-line
+ "C-c C-q" #'mh-fully-kill-draft
+ "C-c C-s" #'mh-insert-signature
+ "C-c C-t" #'mh-letter-toggle-header-field-display
+ "C-c C-w" #'mh-check-whom
+ "C-c C-y" #'mh-yank-cur-msg
+ "C-c M-d" #'mh-insert-auto-fields
+ "C-M-i" #'completion-at-point
+ "TAB" #'mh-letter-next-header-field-or-indent
+ "<backtab>" #'mh-letter-previous-header-field)
;; "C-c /" prefix is used in mh-letter-mode by pgp.el and mailcrypt.el.
@@ -253,17 +253,13 @@ searching for `mh-mail-header-separator' in the buffer."
(goto-char (point-min))
(cond ((equal mh-mail-header-separator "") (point-min))
((search-forward (format "\n%s\n" mh-mail-header-separator) nil t)
- (mh-line-beginning-position 0))
+ (line-beginning-position 0))
(t (point-min)))))
;;; MH-Letter Mode
-;; Shush compiler.
-(mh-do-in-xemacs
- (defvar font-lock-defaults))
-
;; Ensure new buffers won't get this mode if default major-mode is nil.
(put 'mh-letter-mode 'mode-class 'special)
@@ -295,24 +291,21 @@ order).
(make-local-variable 'mh-previous-window-config)
(make-local-variable 'mh-sent-from-folder)
(make-local-variable 'mh-sent-from-msg)
- (mh-do-in-gnu-emacs
- (unless mh-letter-tool-bar-map
- (mh-tool-bar-letter-buttons-init))
- (if (boundp 'tool-bar-map)
- (set (make-local-variable 'tool-bar-map) mh-letter-tool-bar-map)))
- (mh-do-in-xemacs
- (mh-tool-bar-init :letter))
+ (unless mh-letter-tool-bar-map
+ (mh-tool-bar-letter-buttons-init))
+ (if (boundp 'tool-bar-map)
+ (setq-local tool-bar-map mh-letter-tool-bar-map))
;; Set the local value of mh-mail-header-separator according to what is
;; present in the buffer...
- (set (make-local-variable 'mh-mail-header-separator)
- (save-excursion
- (goto-char (mh-mail-header-end))
- (buffer-substring-no-properties (point) (mh-line-end-position))))
+ (setq-local mh-mail-header-separator
+ (save-excursion
+ (goto-char (mh-mail-header-end))
+ (buffer-substring-no-properties (point) (line-end-position))))
(make-local-variable 'mail-header-separator)
(setq mail-header-separator mh-mail-header-separator) ;override sendmail.el
(mh-set-help mh-letter-mode-help-messages)
(setq buffer-invisibility-spec '((vanish . t) t))
- (set (make-local-variable 'line-move-ignore-invisible) t)
+ (setq-local line-move-ignore-invisible t)
;; Enable undo since a show-mode buffer might have been reused.
(buffer-enable-undo)
@@ -328,12 +321,10 @@ order).
(t
;; ...or the header only
(setq font-lock-defaults '((mh-show-font-lock-keywords) t))))
- (mh-do-in-xemacs (easy-menu-add mh-letter-menu))
;; Maybe we want to use the existing Mail menu from mail-mode in
;; 9.0; in the mean time, let's remove it since the redundancy will
;; only produce confusion.
(define-key mh-letter-mode-map [menu-bar mail] #'undefined)
- (mh-do-in-xemacs (easy-menu-remove mail-menubar-menu))
(setq fill-column mh-letter-fill-column)
(add-hook 'completion-at-point-functions
#'mh-letter-completion-at-point nil 'local)
@@ -488,29 +479,8 @@ This provides alias and folder completion in header fields according to
(or (funcall func) #'ignore)
mh-letter-complete-function)))
-;; TODO Now that completion-at-point performs the task of
-;; mh-letter-complete, perhaps mh-letter-complete along with
-;; mh-complete-word should be rewritten as a more general function for
-;; XEmacs, renamed to mh-completion-at-point, and moved to
-;; mh-compat.el.
-(defun-mh mh-letter-complete completion-at-point ()
- "Perform completion on header field or word preceding point.
-
-If the field contains addresses (for example, \"To:\" or \"Cc:\")
-or folders (for example, \"Fcc:\") then this command will provide
-alias completion. In the body of the message, this command runs
-`mh-letter-complete-function' instead, which is set to
-`ispell-complete-word' by default."
- (interactive)
- (let ((data (mh-letter-completion-at-point)))
- (cond
- ((functionp data) (funcall data))
- ((consp data)
- (let ((start (nth 0 data))
- (end (nth 1 data))
- (table (nth 2 data)))
- (mh-complete-word (buffer-substring-no-properties start end)
- table start end))))))
+(define-obsolete-function-alias 'mh-letter-complete
+ #'completion-at-point "29.1")
(defun mh-letter-complete-or-space (arg)
"Perform completion or insert space.
@@ -530,7 +500,7 @@ one space."
((> (point) end-of-prev) (self-insert-command arg))
((let ((mh-letter-complete-function nil))
(mh-letter-completion-at-point))
- (mh-letter-complete))
+ (completion-at-point))
(t (self-insert-command arg)))))
(defun mh-letter-confirm-address ()
@@ -722,7 +692,7 @@ and `mh-ins-buf-prefix' is not inserted."
;; Find displayed message
(with-current-buffer show-buffer
(let* ((from-attr (mh-extract-from-attribution))
- (yank-region (mh-mark-active-p nil))
+ (yank-region mark-active)
(mh-ins-str
(cond ((and yank-region
(or (eq 'supercite mh-yank-behavior)
@@ -834,7 +804,7 @@ body."
((< (point) (progn
(beginning-of-line)
(re-search-forward mh-letter-header-field-regexp
- (mh-line-end-position) t)
+ (line-end-position) t)
(point)))
(beginning-of-line))
(t (end-of-line)))
diff --git a/lisp/mh-e/mh-limit.el b/lisp/mh-e/mh-limit.el
index 39cf7c5d271..a00252284af 100644
--- a/lisp/mh-e/mh-limit.el
+++ b/lisp/mh-e/mh-limit.el
@@ -124,7 +124,7 @@ Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command."
(setq pick-expr
(let ((case-fold-search t))
(cl-loop for s in pick-expr
- collect (mh-replace-regexp-in-string "re: *" "" s))))
+ collect (replace-regexp-in-string "re: *" "" s))))
(mh-narrow-to-header-field 'subject pick-expr))
;;;###mh-autoload
@@ -214,7 +214,7 @@ Return number of messages put in the sequence:
(string-equal "" (match-string 3)))
(progn (message "No subject line")
nil)
- (let ((subject (mh-match-string-no-properties 3))
+ (let ((subject (match-string-no-properties 3))
(list))
(if (> (length subject) mh-limit-max-subject-size)
(setq subject (substring subject 0 mh-limit-max-subject-size)))
@@ -222,7 +222,7 @@ Return number of messages put in the sequence:
(if all
(goto-char (point-min)))
(while (re-search-forward mh-scan-subject-regexp nil t)
- (let ((this-subject (mh-match-string-no-properties 3)))
+ (let ((this-subject (match-string-no-properties 3)))
(if (> (length this-subject) mh-limit-max-subject-size)
(setq this-subject (substring this-subject
0 mh-limit-max-subject-size)))
@@ -313,7 +313,7 @@ The MH command pick is used to do the match."
(while (not (eobp))
(let ((num (ignore-errors
(string-to-number
- (buffer-substring (point) (mh-line-end-position))))))
+ (buffer-substring (point) (line-end-position))))))
(when num (push num msg-list))
(forward-line))))
(if (null msg-list)
diff --git a/lisp/mh-e/mh-mime.el b/lisp/mh-e/mh-mime.el
index ef702525b7b..714bf029bb7 100644
--- a/lisp/mh-e/mh-mime.el
+++ b/lisp/mh-e/mh-mime.el
@@ -39,6 +39,7 @@
;;; Code:
(require 'mh-e)
+(require 'mh-acros)
(require 'mh-gnus) ;needed because mh-gnus.el not compiled
(require 'font-lock)
@@ -51,6 +52,7 @@
(autoload 'article-emphasize "gnus-art")
(autoload 'gnus-eval-format "gnus-spec")
(autoload 'mail-content-type-get "mail-parse")
+(autoload 'mail-decode-encoded-word-region "mail-parse")
(autoload 'mail-decode-encoded-word-string "mail-parse")
(autoload 'mail-header-parse-content-type "mail-parse")
(autoload 'mail-header-strip-cte "mail-parse")
@@ -61,7 +63,6 @@
(autoload 'mm-decode-body "mm-bodies")
(autoload 'mm-uu-dissect "mm-uu")
(autoload 'mml-unsecure-message "mml-sec")
-(autoload 'rfc2047-decode-region "rfc2047")
(autoload 'widget-convert-button "wid-edit")
@@ -135,13 +136,11 @@
("application/emacs-lisp" mm-display-elisp-inline identity)
("application/x-emacs-lisp" mm-display-elisp-inline identity)
("text/html"
- ,(if (fboundp 'mm-inline-text-html) 'mm-inline-text-html 'mm-inline-text)
+ mm-inline-text-html
(lambda (handle)
- (or (and (boundp 'mm-inline-text-html-renderer)
- mm-inline-text-html-renderer)
- (and (boundp 'mm-text-html-renderer) mm-text-html-renderer))))
+ mm-text-html-renderer))
("text/x-vcard"
- mh-mm-inline-text-vcard
+ mm-inline-text-vcard
(lambda (handle)
(or (featurep 'vcard)
(locate-library "vcard"))))
@@ -171,7 +170,7 @@
("audio/.*" ignore ignore)
("image/.*" ignore ignore)
;; Default to displaying as text
- (".*" mm-inline-text mh-mm-readable-p))
+ (".*" mm-inline-text mm-readable-p))
"Alist of media types/tests saying whether types can be displayed inline.")
(defvar mh-mime-save-parts-directory nil
@@ -184,13 +183,7 @@ Set from last use.")
'((mh-press-button "\r" "Toggle Display")))
(defvar mh-mime-button-map
(let ((map (make-sparse-keymap)))
- (unless (>= (string-to-number emacs-version) 21)
- ;; XEmacs doesn't care.
- (set-keymap-parent map mh-show-mode-map))
- (mh-do-in-gnu-emacs
- (define-key map [mouse-2] #'mh-push-button))
- (mh-do-in-xemacs
- (define-key map '(button2) #'mh-push-button))
+ (define-key map [mouse-2] #'mh-push-button)
(dolist (c mh-mime-button-commands)
(define-key map (cadr c) (car c)))
map))
@@ -210,13 +203,8 @@ Set from last use.")
(?D pressed-details ?s)))
(defvar mh-mime-security-button-map
(let ((map (make-sparse-keymap)))
- (unless (>= (string-to-number emacs-version) 21)
- (set-keymap-parent map mh-show-mode-map))
(define-key map "\r" #'mh-press-button)
- (mh-do-in-gnu-emacs
- (define-key map [mouse-2] #'mh-push-button))
- (mh-do-in-xemacs
- (define-key map '(button2) #'mh-push-button))
+ (define-key map [mouse-2] #'mh-push-button)
map))
@@ -251,24 +239,24 @@ usually reads the file \"/etc/mailcap\"."
(when (consp part-index) (setq part-index (car part-index)))
(mh-folder-mime-action
part-index
- #'(lambda ()
- (let* ((part (get-text-property (point) 'mh-data))
- (type (mm-handle-media-type part))
- (methods (mapcar (lambda (x) (list (cdr (assoc 'viewer x))))
- (mailcap-mime-info type 'all)))
- (def (caar methods))
- (prompt (format-prompt "Viewer" def))
- (method (completing-read prompt methods nil nil nil nil def))
- (folder mh-show-folder-buffer)
- (buffer-read-only nil))
- (when (string-match "^[^% \t]+$" method)
- (setq method (concat method " %s")))
- (mh-flet
- ((mm-handle-set-external-undisplayer
- (handle function)
- (mh-handle-set-external-undisplayer folder handle function)))
- (unwind-protect (mm-display-external part method)
- (set-buffer-modified-p nil)))))
+ (lambda ()
+ (let* ((part (get-text-property (point) 'mh-data))
+ (type (mm-handle-media-type part))
+ (methods (mapcar (lambda (x) (list (cdr (assoc 'viewer x))))
+ (mailcap-mime-info type 'all)))
+ (def (caar methods))
+ (prompt (format-prompt "Viewer" def))
+ (method (completing-read prompt methods nil nil nil nil def))
+ (folder mh-show-folder-buffer)
+ (buffer-read-only nil))
+ (when (string-match "^[^% \t]+$" method)
+ (setq method (concat method " %s")))
+ (mh-flet
+ ((mm-handle-set-external-undisplayer
+ (handle function)
+ (mh-handle-set-external-undisplayer folder handle function)))
+ (unwind-protect (mm-display-external part method)
+ (set-buffer-modified-p nil)))))
nil))
;;;###mh-autoload
@@ -299,14 +287,14 @@ the attachment labeled with that number."
start end)
(cond ((and data (not inserted-flag) (not displayed-flag))
(let ((contents (mm-get-part data)))
- (add-text-properties (mh-line-beginning-position)
- (mh-line-end-position) '(mh-mime-inserted t))
+ (add-text-properties (line-beginning-position)
+ (line-end-position) '(mh-mime-inserted t))
(setq start (point-marker))
(forward-line 1)
(mm-insert-inline data contents)
(setq end (point-marker))
(add-text-properties
- start (progn (goto-char start) (mh-line-end-position))
+ start (progn (goto-char start) (line-end-position))
`(mh-region (,start . ,end)))))
((and data (or inserted-flag displayed-flag))
(mh-press-button)
@@ -458,10 +446,10 @@ decoding the same message multiple times."
(setf (gethash handle (mh-mime-handles-cache (mh-buffer-data)))
(let ((handles (mm-dissect-buffer nil)))
(if handles
- (mh-mm-uu-dissect-text-parts handles)
+ (mm-uu-dissect-text-parts handles)
(setq handles (mm-uu-dissect)))
(setf (mh-mime-handles (mh-buffer-data))
- (mh-mm-merge-handles
+ (mm-merge-handles
handles (mh-mime-handles (mh-buffer-data))))
handles))))
@@ -496,7 +484,7 @@ decoding the same message multiple times."
"Decode RFC2047 encoded message header fields."
(when mh-decode-mime-flag
(let ((buffer-read-only nil))
- (rfc2047-decode-region (point-min) (mh-mail-header-end)))))
+ (mail-decode-encoded-word-region (point-min) (mh-mail-header-end)))))
;;;###mh-autoload
(defun mh-decode-message-subject ()
@@ -504,8 +492,9 @@ decoding the same message multiple times."
(when mh-decode-mime-flag
(save-excursion
(let ((buffer-read-only nil))
- (rfc2047-decode-region (progn (mh-goto-header-field "Subject:") (point))
- (progn (mh-header-field-end) (point)))))))
+ (mail-decode-encoded-word-region
+ (progn (mh-goto-header-field "Subject:") (point))
+ (progn (mh-header-field-end) (point)))))))
;;;###mh-autoload
(defun mh-mime-display (&optional pre-dissected-handles)
@@ -531,10 +520,10 @@ parsed and then displayed."
(if pre-dissected-handles
(setq handles pre-dissected-handles)
(if (setq handles (mm-dissect-buffer nil))
- (mh-mm-uu-dissect-text-parts handles)
+ (mm-uu-dissect-text-parts handles)
(setq handles (mm-uu-dissect)))
(setf (mh-mime-handles (mh-buffer-data))
- (mh-mm-merge-handles handles
+ (mm-merge-handles handles
(mh-mime-handles (mh-buffer-data))))
(unless handles
(mh-decode-message-body)))
@@ -640,7 +629,7 @@ buttons for alternative parts that are usually suppressed."
(let ((mh-mime-security-button-line-format
mh-mime-security-button-end-line-format))
(mh-insert-mime-security-button handle))
- (mh-mm-set-handle-multipart-parameter
+ (mm-set-handle-multipart-parameter
handle 'mh-region (cons (point-min-marker) (point-max-marker)))))
(defun mh-mime-display-single (handle)
@@ -712,8 +701,7 @@ buttons for alternative parts that are usually suppressed."
;; Delete the button and displayed part (if any)
(let ((region (get-text-property point 'mh-region)))
(when region
- (mh-funcall-if-exists
- remove-images (car region) (cdr region)))
+ (remove-images (car region) (cdr region)))
(mm-display-part handle)
(when region
(delete-region (car region) (cdr region))))
@@ -751,8 +739,8 @@ buttons for alternative parts that are usually suppressed."
(mh-insert-mime-button handle id (mm-handle-displayed-p handle))
(goto-char point)
(when region
- (add-text-properties (mh-line-beginning-position)
- (mh-line-end-position)
+ (add-text-properties (line-beginning-position)
+ (line-end-position)
`(mh-region ,region)))))))
(defun mh-mime-part-index (handle)
@@ -776,20 +764,12 @@ This is only useful if a Content-Disposition header is not present."
; this only tells us if the image is
; something that emacs can display
(let ((image (mm-get-image handle)))
- (or (mh-do-in-xemacs
- (and (mh-funcall-if-exists glyphp image)
- (< (glyph-width image)
- (or mh-max-inline-image-width (window-pixel-width)))
- (< (glyph-height image)
- (or mh-max-inline-image-height
- (window-pixel-height)))))
- (mh-do-in-gnu-emacs
- (let ((size (and (fboundp 'image-size) (image-size image))))
- (and size
- (< (cdr size) (or mh-max-inline-image-height
- (1- (window-height))))
- (< (car size) (or mh-max-inline-image-width
- (window-width)))))))))))
+ (let ((size (and (fboundp 'image-size) (image-size image))))
+ (and size
+ (< (cdr size) (or mh-max-inline-image-height
+ (1- (window-height))))
+ (< (car size) (or mh-max-inline-image-width
+ (window-width)))))))))
(defun mh-inline-vcard-p (handle)
"Decide if HANDLE is a vcard that must be displayed inline."
@@ -812,27 +792,19 @@ being used to highlight the signature in a MIME part."
((not (and (equal (mm-handle-media-supertype handle) "text")
(equal (mm-handle-media-subtype handle) "html")))
"^-- $")
- ((eq (mh-mm-text-html-renderer) 'lynx) "^ --$")
+ ((eq mm-text-html-renderer 'lynx) "^ --$")
(t "^--$"))))
(save-excursion
(goto-char (point-max))
(when (re-search-backward regexp nil t)
- (mh-do-in-gnu-emacs
- (let ((ov (make-overlay (point) (point-max))))
- (overlay-put ov 'face 'mh-show-signature)
- (overlay-put ov 'evaporate t)))
- (mh-do-in-xemacs
- (set-extent-property (make-extent (point) (point-max))
- 'face 'mh-show-signature))))))
+ (let ((ov (make-overlay (point) (point-max))))
+ (overlay-put ov 'face 'mh-show-signature)
+ (overlay-put ov 'evaporate t))))))
;;; Button Display
-;; Shush compiler.
-(mh-do-in-xemacs
- (defvar ov))
-
(defun mh-insert-mime-button (handle index displayed)
"Insert MIME button for HANDLE.
INDEX is the part number that will be DISPLAYED. It is also used
@@ -864,10 +836,10 @@ by commands like \"K v\" which operate on individual MIME parts."
(setq begin (point))
(gnus-eval-format
mh-mime-button-line-format mh-mime-button-line-format-alist
- `(,@(mh-gnus-local-map-property mh-mime-button-map)
- mh-callback mh-mm-display-part
- mh-part ,index
- mh-data ,handle)))
+ `(keymap ,mh-mime-button-map
+ mh-callback mh-mm-display-part
+ mh-part ,index
+ mh-data ,handle)))
(setq end (point))
(widget-convert-button
'link begin end
@@ -876,16 +848,12 @@ by commands like \"K v\" which operate on individual MIME parts."
:button-keymap mh-mime-button-map
:help-echo
"Mouse-2 click or press RET (in show buffer) to toggle display")
- (dolist (ov (mh-funcall-if-exists overlays-in begin end))
- (mh-funcall-if-exists overlay-put ov 'evaporate t))))
-
-;; Shush compiler.
-(defvar mm-verify-function-alist) ; < Emacs 22
-(defvar mm-decrypt-function-alist) ; < Emacs 22
+ (dolist (ov (overlays-in begin end))
+ (overlay-put ov 'evaporate t))))
(defun mh-insert-mime-security-button (handle)
"Display buttons for PGP message, HANDLE."
- (let* ((protocol (mh-mm-handle-multipart-ctl-parameter handle 'protocol))
+ (let* ((protocol (mm-handle-multipart-ctl-parameter handle 'protocol))
(crypto-type (or (nth 2 (assoc protocol mm-verify-function-alist))
(nth 2 (assoc protocol mm-decrypt-function-alist))
"Unknown"))
@@ -896,10 +864,10 @@ by commands like \"K v\" which operate on individual MIME parts."
(if (equal (car handle) "multipart/signed")
" Signed" " Encrypted")
" Part"))
- (info (or (mh-mm-handle-multipart-ctl-parameter
+ (info (or (mm-handle-multipart-ctl-parameter
handle 'gnus-info)
"Undecided"))
- (details (mh-mm-handle-multipart-ctl-parameter
+ (details (mm-handle-multipart-ctl-parameter
handle 'gnus-details))
pressed-details)
(setq details (if details (concat "\n" details) ""))
@@ -910,11 +878,11 @@ by commands like \"K v\" which operate on individual MIME parts."
(gnus-eval-format
mh-mime-security-button-line-format
mh-mime-security-button-line-format-alist
- `(,@(mh-gnus-local-map-property mh-mime-security-button-map)
- mh-button-pressed ,mh-mime-security-button-pressed
- mh-callback mh-mime-security-press-button
- mh-line-format ,mh-mime-security-button-line-format
- mh-data ,handle))
+ `(keymap ,mh-mime-security-button-map
+ mh-button-pressed ,mh-mime-security-button-pressed
+ mh-callback mh-mime-security-press-button
+ mh-line-format ,mh-mime-security-button-line-format
+ mh-data ,handle))
(setq end (point))
(widget-convert-button 'link begin end
:mime-handle handle
@@ -922,8 +890,8 @@ by commands like \"K v\" which operate on individual MIME parts."
:button-keymap mh-mime-security-button-map
:button-face face
:help-echo "Mouse-2 click or press RET (in show buffer) to see security details.")
- (dolist (ov (mh-funcall-if-exists overlays-in begin end))
- (mh-funcall-if-exists overlay-put ov 'evaporate t))
+ (dolist (ov (overlays-in begin end))
+ (overlay-put ov 'evaporate t))
(when (equal info "Failed")
(let* ((type (if (equal (car handle) "multipart/signed")
"verification" "decryption"))
@@ -1080,7 +1048,7 @@ This is only called in recent versions of Gnus. The MIME handles
are stored in data structures corresponding to MH-E folder buffer
FOLDER instead of in Gnus (as in the original). The MIME part,
HANDLE is associated with the undisplayer FUNCTION."
- (if (mh-mm-keep-viewer-alive-p handle)
+ (if (mm-keep-viewer-alive-p handle)
(let ((new-handle (copy-sequence handle)))
(mm-handle-set-undisplayer new-handle function)
(mm-handle-set-undisplayer handle nil)
@@ -1090,19 +1058,19 @@ HANDLE is associated with the undisplayer FUNCTION."
(defun mh-mime-security-press-button (handle)
"Callback from security button for part HANDLE."
- (if (mh-mm-handle-multipart-ctl-parameter handle 'gnus-info)
+ (if (mm-handle-multipart-ctl-parameter handle 'gnus-info)
(mh-mime-security-show-details handle)
- (let ((region (mh-mm-handle-multipart-ctl-parameter handle 'mh-region))
+ (let ((region (mm-handle-multipart-ctl-parameter handle 'mh-region))
point)
(setq point (point))
(goto-char (car region))
(delete-region (car region) (cdr region))
- (with-current-buffer (mh-mm-handle-multipart-ctl-parameter handle 'buffer)
+ (with-current-buffer (mm-handle-multipart-ctl-parameter handle 'buffer)
(let* ((mm-verify-option 'known)
(mm-decrypt-option 'known)
- (new (mh-mm-possibly-verify-or-decrypt (cdr handle) handle)))
+ (new (mm-possibly-verify-or-decrypt (cdr handle) handle)))
(unless (eq new (cdr handle))
- (mh-mm-destroy-parts (cdr handle))
+ (mm-destroy-parts (cdr handle))
(setcdr handle new))))
(mh-mime-display-security handle)
(goto-char point))))
@@ -1112,7 +1080,7 @@ HANDLE is associated with the undisplayer FUNCTION."
;; to be no way of getting rid of the inserted text.
(defun mh-mime-security-show-details (handle)
"Toggle display of detailed security info for HANDLE."
- (let ((details (mh-mm-handle-multipart-ctl-parameter handle 'gnus-details)))
+ (let ((details (mm-handle-multipart-ctl-parameter handle 'gnus-details)))
(when details
(let ((mh-mime-security-button-pressed
(not (get-text-property (point) 'mh-button-pressed)))
@@ -1157,7 +1125,7 @@ this ;-)"
(defun mh-display-smileys ()
"Display smileys."
(when (and mh-graphical-smileys-flag (mh-small-show-buffer-p))
- (mh-funcall-if-exists smiley-region (point-min) (point-max))))
+ (smiley-region (point-min) (point-max))))
;;;###mh-autoload
(defun mh-display-emphasis ()
@@ -1174,6 +1142,7 @@ this ;-)"
This is used to decide if smileys and graphical emphasis should be
displayed."
(let ((max nil))
+ ;; FIXME: font-lock-maximum-size is obsolete.
(when (and (boundp 'font-lock-maximum-size) font-lock-maximum-size)
(cond ((numberp font-lock-maximum-size)
(setq max font-lock-maximum-size))
@@ -1302,7 +1271,7 @@ automatically."
(type (mh-minibuffer-read-type file))
(description (mml-minibuffer-read-description))
(dispos (or disposition
- (mh-mml-minibuffer-read-disposition type))))
+ (mml-minibuffer-read-disposition type))))
(mml-insert-empty-tag 'part 'type type 'filename file
'disposition dispos 'description description)))
@@ -1506,9 +1475,9 @@ This function will quote all such characters."
(goto-char (point-min))
(while (re-search-forward "^#" nil t)
(beginning-of-line)
- (unless (mh-mh-directive-present-p (point) (mh-line-end-position))
+ (unless (mh-mh-directive-present-p (point) (line-end-position))
(insert "#"))
- (goto-char (mh-line-end-position)))))
+ (goto-char (line-end-position)))))
;;;###mh-autoload
(defun mh-mh-to-mime-undo (noconfirm)
@@ -1694,7 +1663,7 @@ buffer, while END defaults to the end of the buffer."
(goto-char begin)
(while (re-search-forward "^#" end t)
(let ((s (buffer-substring-no-properties
- (point) (mh-line-end-position))))
+ (point) (line-end-position))))
(cond ((equal s ""))
((string-match "^forw[ \t\n]+" s)
(cl-return-from search-for-mh-directive t))
@@ -1798,8 +1767,7 @@ initialized. Always use the command `mh-have-file-command'.")
'file -i' is used to get MIME type of composition insertion."
(when (eq mh-have-file-command 'undefined)
(setq mh-have-file-command
- (and (fboundp 'executable-find)
- (executable-find "file") ; file command exists
+ (and (executable-find "file") ; file command exists
; and accepts -i and -b args.
(zerop (call-process "file" nil nil nil "-i" "-b"
(expand-file-name "inc" mh-progs))))))
@@ -1813,10 +1781,9 @@ initialized. Always use the command `mh-have-file-command'.")
(defun mh-mime-cleanup ()
"Free the decoded MIME parts."
(let ((mime-data (gethash (current-buffer) mh-globals-hash)))
- ;; This is for Emacs, what about XEmacs?
- (mh-funcall-if-exists remove-images (point-min) (point-max))
+ (remove-images (point-min) (point-max))
(when mime-data
- (mh-mm-destroy-parts (mh-mime-handles mime-data))
+ (mm-destroy-parts (mh-mime-handles mime-data))
(remhash (current-buffer) mh-globals-hash))))
;;;###mh-autoload
@@ -1824,7 +1791,7 @@ initialized. Always use the command `mh-have-file-command'.")
"Free MIME data for externally displayed MIME parts."
(let ((mime-data (mh-buffer-data)))
(when mime-data
- (mh-mm-destroy-parts (mh-mime-handles mime-data)))
+ (mm-destroy-parts (mh-mime-handles mime-data)))
(remhash (current-buffer) mh-globals-hash)))
(provide 'mh-mime)
diff --git a/lisp/mh-e/mh-scan.el b/lisp/mh-e/mh-scan.el
index 10235209dce..9ac251e8b71 100644
--- a/lisp/mh-e/mh-scan.el
+++ b/lisp/mh-e/mh-scan.el
@@ -103,15 +103,21 @@ non-empty Newsgroups: field is present."
;; Alphabetical.
-(defvar mh-scan-body-regexp "\\(<<\\([^\n]+\\)?\\)"
- "This regular expression matches the message body fragment.
+(defvar mh-scan-allowlisted-msg-regexp "^\\( *[0-9]+\\)A"
+ "This regular expression matches allowlisted (non-spam) messages.
-Note that the default setting of `mh-folder-font-lock-keywords'
-expects this expression to contain at least one parenthesized
-expression which matches the body text as in the default of
-\"\\\\(<<\\\\([^\\n]+\\\\)?\\\\)\". If this regular expression is
-not correct, the body fragment will not be highlighted with the
-face `mh-folder-body'.")
+It must match from the beginning of the line. Note that the
+default setting of `mh-folder-font-lock-keywords' expects this
+expression to contain at least one parenthesized expression which
+matches the message number as in the default of
+
+ \"^\\\\( *[0-9]+\\\\)A\".
+
+This expression includes the leading space within parenthesis
+since it looks better to highlight it as well. The highlighting
+is done with the face `mh-folder-allowlisted'. This regular
+expression should be correct as it is needed by non-fontification
+functions. See also `mh-note-allowlisted'.")
(defvar mh-scan-blocklisted-msg-regexp "^\\( *[0-9]+\\)B"
"This regular expression matches blocklisted (spam) messages.
@@ -129,6 +135,16 @@ is done with the face `mh-folder-blocklisted'. This regular
expression should be correct as it is needed by non-fontification
functions. See also `mh-note-blocklisted'.")
+(defvar mh-scan-body-regexp "\\(<<\\([^\n]+\\)?\\)"
+ "This regular expression matches the message body fragment.
+
+Note that the default setting of `mh-folder-font-lock-keywords'
+expects this expression to contain at least one parenthesized
+expression which matches the body text as in the default of
+\"\\\\(<<\\\\([^\\n]+\\\\)?\\\\)\". If this regular expression is
+not correct, the body fragment will not be highlighted with the
+face `mh-folder-body'.")
+
(defvar mh-scan-cur-msg-number-regexp "^\\( *[0-9]+\\+\\).*"
"This regular expression matches the current message.
@@ -173,7 +189,7 @@ is done with the face `mh-folder-deleted'. This regular
expression should be correct as it is needed by non-fontification
functions. See also `mh-note-deleted'.")
-(defvar mh-scan-good-msg-regexp "^\\( *[0-9]+\\)[^^DBW0-9]"
+(defvar mh-scan-good-msg-regexp "^\\( *[0-9]+\\)[^^DBA0-9]"
"This regular expression matches \"good\" messages.
It must match from the beginning of the line. Note that the
@@ -181,7 +197,7 @@ default setting of `mh-folder-font-lock-keywords' expects this
expression to contain at least one parenthesized expression which
matches the message number as in the default of
- \"^\\\\( *[0-9]+\\\\)[^^DBW0-9]\".
+ \"^\\\\( *[0-9]+\\\\)[^^DBA0-9]\".
This expression includes the leading space within the parenthesis
since it looks better to highlight it as well. The highlighting
@@ -295,27 +311,11 @@ non-fontification functions.")
This is used to eliminate error messages that are occasionally
produced by \"inc\".")
-(defvar mh-scan-allowlisted-msg-regexp "^\\( *[0-9]+\\)A"
- "This regular expression matches allowlisted (non-spam) messages.
-
-It must match from the beginning of the line. Note that the
-default setting of `mh-folder-font-lock-keywords' expects this
-expression to contain at least one parenthesized expression which
-matches the message number as in the default of
-
- \"^\\\\( *[0-9]+\\\\)A\".
-
-This expression includes the leading space within parenthesis
-since it looks better to highlight it as well. The highlighting
-is done with the face `mh-folder-allowlisted'. This regular
-expression should be correct as it is needed by non-fontification
-functions. See also `mh-note-allowlisted'.")
-
;;; Widths, Offsets and Columns
-(defvar mh-cmd-note 4
+(defvar-local mh-cmd-note 4
"Column for notations.
This variable should be set with the function `mh-set-cmd-note'.
@@ -323,12 +323,15 @@ This variable may be updated dynamically if
`mh-adaptive-cmd-note-flag' is on.
Note that columns in Emacs start with 0.")
-(make-variable-buffer-local 'mh-cmd-note)
(defvar mh-scan-cmd-note-width 1
"Number of columns consumed by the cmd-note field in `mh-scan-format'.
-This column will have one of the values: \" \", \"^\", \"D\", \"B\", \"W\", \"+\", where
+This column will have one of the values:
+
+ \" \", \"^\", \"D\", \"B\", \"A\", \"+\"
+
+where
\" \" is the default value,
\"^\" is the `mh-note-refiled' character,
@@ -399,17 +402,21 @@ This column will only ever have spaces in it.")
;; Alphabetical.
+(defvar mh-note-allowlisted ?A
+ "Messages that have been allowlisted are marked by this character.
+See also `mh-scan-allowlisted-msg-regexp'.")
+
(defvar mh-note-blocklisted ?B
"Messages that have been blocklisted are marked by this character.
See also `mh-scan-blocklisted-msg-regexp'.")
+(defvar mh-note-copied ?C
+ "Messages that have been copied are marked by this character.")
+
(defvar mh-note-cur ?+
"The current message (in MH, not in MH-E) is marked by this character.
See also `mh-scan-cur-msg-number-regexp'.")
-(defvar mh-note-copied ?C
- "Messages that have been copied are marked by this character.")
-
(defvar mh-note-deleted ?D
"Messages that have been deleted are marked by this character.
See also `mh-scan-deleted-msg-regexp'.")
@@ -436,10 +443,6 @@ See also `mh-scan-refiled-msg-regexp'.")
Messages in the \"search\" sequence are marked by this character as
well.")
-(defvar mh-note-allowlisted ?A
- "Messages that have been allowlisted are marked by this character.
-See also `mh-scan-allowlisted-msg-regexp'.")
-
;;; Utilities
@@ -510,7 +513,7 @@ with `mh-scan-msg-format-string'."
Note that columns in Emacs start with 0.
If `mh-scan-format-file' is set to \"Use MH-E scan Format\" this
-means that either `mh-scan-format-mh' or `mh-scan-format-nmh' are
+means that either `mh-scan-format-mh' or `mh-scan-format-nmh' is
in use. This function therefore assumes that the first column is
empty (to provide room for the cursor), the following WIDTH
columns contain the message number, and the column for notations
diff --git a/lisp/mh-e/mh-search.el b/lisp/mh-e/mh-search.el
index e03c9dc83f7..8012e624f16 100644
--- a/lisp/mh-e/mh-search.el
+++ b/lisp/mh-e/mh-search.el
@@ -42,6 +42,7 @@
;;; Code:
(require 'mh-e)
+(require 'mh-letter)
(require 'gnus-util)
(require 'imenu)
@@ -318,10 +319,6 @@ folder containing the index search results."
(cl-loop for msg-hash being the hash-values of mh-index-data
count (> (hash-table-count msg-hash) 0)))))))
-;; Shush compiler.
-(mh-do-in-xemacs
- (defvar pick-folder)) ;FIXME: Why?
-
(defun mh-search-folder (folder window-config)
"Search FOLDER for messages matching a pattern.
@@ -336,8 +333,8 @@ configuration and is used when the search folder is dismissed."
(not (y-or-n-p "Reuse pattern? ")))
(mh-make-pick-template)
(message ""))
- (mh-make-local-vars 'mh-current-folder folder
- 'mh-previous-window-config window-config)
+ (setq-local mh-current-folder folder
+ mh-previous-window-config window-config)
(message "%s" (substitute-command-keys
(concat "Type \\[mh-index-do-search] to search messages, "
"\\[mh-pick-do-search] to use pick, "
@@ -356,13 +353,13 @@ configuration and is used when the search folder is dismissed."
(goto-char (point-min))
(dotimes (_ 5)
(add-text-properties (point) (1+ (point)) '(front-sticky t))
- (add-text-properties (- (mh-line-end-position) 2)
- (1- (mh-line-end-position))
+ (add-text-properties (- (line-end-position) 2)
+ (1- (line-end-position))
'(rear-nonsticky t))
- (add-text-properties (point) (1- (mh-line-end-position)) '(read-only t))
+ (add-text-properties (point) (1- (line-end-position)) '(read-only t))
(forward-line))
(add-text-properties (point) (1+ (point)) '(front-sticky t))
- (add-text-properties (point) (1- (mh-line-end-position)) '(read-only t))
+ (add-text-properties (point) (1- (line-end-position)) '(read-only t))
(goto-char (point-max)))
;; Sequence Searches
@@ -522,10 +519,10 @@ group of results."
(cond ((and (bolp) (eolp))
(ignore-errors (forward-line -1))
(setq msg (mh-get-msg-num t)))
- ((equal (char-after (mh-line-beginning-position)) ?+)
+ ((equal (char-after (line-beginning-position)) ?+)
(setq folder (buffer-substring-no-properties
- (mh-line-beginning-position)
- (mh-line-end-position))))
+ (line-beginning-position)
+ (line-end-position))))
(t (setq msg (mh-get-msg-num t)))))
(when (not folder)
(setq folder (car (gethash (gethash msg mh-index-msg-checksum-map)
@@ -552,20 +549,20 @@ group of results."
;;; MH-Search Keys
;; If this changes, modify mh-search-mode-help-messages accordingly, below.
-(gnus-define-keys mh-search-mode-map
- "\C-c?" mh-help
- "\C-c\C-c" mh-index-do-search
- "\C-c\C-p" mh-pick-do-search
- "\C-c\C-f\C-b" mh-to-field
- "\C-c\C-f\C-c" mh-to-field
- "\C-c\C-f\C-m" mh-to-field
- "\C-c\C-f\C-s" mh-to-field
- "\C-c\C-f\C-t" mh-to-field
- "\C-c\C-fb" mh-to-field
- "\C-c\C-fc" mh-to-field
- "\C-c\C-fm" mh-to-field
- "\C-c\C-fs" mh-to-field
- "\C-c\C-ft" mh-to-field)
+(define-keymap :keymap mh-search-mode-map
+ "C-c ?" #'mh-help
+ "C-c C-c" #'mh-index-do-search
+ "C-c C-p" #'mh-pick-do-search
+ "C-c C-f C-b" #'mh-to-field
+ "C-c C-f C-c" #'mh-to-field
+ "C-c C-f C-m" #'mh-to-field
+ "C-c C-f C-s" #'mh-to-field
+ "C-c C-f C-t" #'mh-to-field
+ "C-c C-f b" #'mh-to-field
+ "C-c C-f c" #'mh-to-field
+ "C-c C-f m" #'mh-to-field
+ "C-c C-f s" #'mh-to-field
+ "C-c C-f t" #'mh-to-field)
@@ -616,7 +613,6 @@ The hook `mh-search-mode-hook' is called upon entry to this mode.
\\{mh-search-mode-map}"
- (mh-do-in-xemacs (easy-menu-add mh-pick-menu))
(mh-set-help mh-search-mode-help-messages))
@@ -653,13 +649,13 @@ The cdr of the element is the pattern to search."
start begin)
(goto-char (point-min))
(while (not (eobp))
- (if (search-forward "--------" (mh-line-end-position) t)
+ (if (search-forward "--------" (line-end-position) t)
(setq in-body-flag t)
(beginning-of-line)
(setq begin (point))
(setq start (if in-body-flag
(point)
- (search-forward ":" (mh-line-end-position) t)
+ (search-forward ":" (line-end-position) t)
(point)))
(push (cons (and (not in-body-flag)
(intern (downcase
@@ -667,7 +663,7 @@ The cdr of the element is the pattern to search."
begin (1- start)))))
(mh-index-parse-search-regexp
(buffer-substring-no-properties
- start (mh-line-end-position))))
+ start (line-end-position))))
pattern-list))
(forward-line))
pattern-list)))
@@ -977,8 +973,8 @@ is used to search."
(cl-return nil))
(when (equal (char-after (point)) ?#)
(cl-return 'error))
- (let* ((start (search-forward " " (mh-line-end-position) t))
- (end (search-forward " " (mh-line-end-position) t)))
+ (let* ((start (search-forward " " (line-end-position) t))
+ (end (search-forward " " (line-end-position) t)))
(unless (and start end)
(cl-return 'error))
(setq end (1- end))
@@ -1056,7 +1052,7 @@ SEARCH-REGEXP-LIST is used to search."
(cl-return 'error))
(let ((start (point))
end msg-start)
- (setq end (mh-line-end-position))
+ (setq end (line-end-position))
(unless (search-forward mh-mairix-folder end t)
(cl-return 'error))
(goto-char (match-beginning 0))
@@ -1197,7 +1193,7 @@ is used to search."
(cl-block nil
(when (eobp) (cl-return nil))
(let ((file-name (buffer-substring-no-properties
- (point) (mh-line-end-position))))
+ (point) (line-end-position))))
(unless (equal (string-match mh-namazu-folder file-name) 0)
(cl-return 'error))
(unless (file-exists-p file-name)
@@ -1245,17 +1241,17 @@ is used to search."
(prog1
(cl-block nil
(when (eobp) (cl-return nil))
- (when (search-forward-regexp "^\\+" (mh-line-end-position) t)
+ (when (search-forward-regexp "^\\+" (line-end-position) t)
(setq mh-index-pick-folder
- (buffer-substring-no-properties (mh-line-beginning-position)
- (mh-line-end-position)))
+ (buffer-substring-no-properties (line-beginning-position)
+ (line-end-position)))
(cl-return 'error))
- (unless (search-forward-regexp "^[1-9][0-9]*$" (mh-line-end-position) t)
+ (unless (search-forward-regexp "^[1-9][0-9]*$" (line-end-position) t)
(cl-return 'error))
(list mh-index-pick-folder
(string-to-number
- (buffer-substring-no-properties (mh-line-beginning-position)
- (mh-line-end-position)))
+ (buffer-substring-no-properties (line-beginning-position)
+ (line-end-position)))
nil))
(forward-line)))
@@ -1332,8 +1328,8 @@ record is invalid return `error'."
(cl-block nil
(when (eobp)
(cl-return nil))
- (let ((eol-pos (mh-line-end-position))
- (bol-pos (mh-line-beginning-position))
+ (let ((eol-pos (line-end-position))
+ (bol-pos (line-beginning-position))
folder-start msg-end)
(goto-char bol-pos)
(unless (search-forward mh-user-path eol-pos t)
@@ -1415,10 +1411,7 @@ being the list of messages originally from that folder."
(when cur-msg (mh-goto-msg cur-msg t t))
(set-buffer-modified-p old-buffer-modified-flag)))
-(eval-and-compile (mh-require 'which-func nil t))
-
-;; Shush compiler.
-(defvar which-func-mode) ; < Emacs 22, XEmacs
+(eval-and-compile (require 'which-func nil t))
;;;###mh-autoload
(defun mh-index-create-imenu-index ()
@@ -1432,7 +1425,7 @@ being the list of messages originally from that folder."
(save-excursion
(beginning-of-line)
(push (cons (buffer-substring-no-properties
- (point) (mh-line-end-position))
+ (point) (line-end-position))
(point-marker))
alist)))
(setq imenu--index-alist (nreverse alist)))))
@@ -1717,7 +1710,7 @@ folder, is removed from `mh-index-data'."
"-format" "%{x-mhe-checksum}\n" folder msg)
(goto-char (point-min))
(string-equal (buffer-substring-no-properties
- (point) (mh-line-end-position))
+ (point) (line-end-position))
checksum)))
@@ -1826,8 +1819,8 @@ PROC is used to convert the value to actual data."
(defun mh-md5sum-parser ()
"Parse md5sum output."
- (let ((begin (mh-line-beginning-position))
- (end (mh-line-end-position))
+ (let ((begin (line-beginning-position))
+ (end (line-end-position))
first-space last-slash)
(setq first-space (search-forward " " end t))
(goto-char end)
@@ -1840,8 +1833,8 @@ PROC is used to convert the value to actual data."
(defun mh-openssl-parser ()
"Parse openssl output."
- (let ((begin (mh-line-beginning-position))
- (end (mh-line-end-position))
+ (let ((begin (line-beginning-position))
+ (end (line-end-position))
last-space last-slash)
(goto-char end)
(setq last-space (search-backward " " begin t))
@@ -1874,7 +1867,7 @@ origin-index) map is updated too."
(let (msg checksum)
(while (not (eobp))
(setq msg (buffer-substring-no-properties
- (point) (mh-line-end-position)))
+ (point) (line-end-position)))
(forward-line)
(save-excursion
(cond ((not (string-match "^[0-9]*$" msg)))
@@ -1885,7 +1878,7 @@ origin-index) map is updated too."
(t
;; update maps
(setq checksum (buffer-substring-no-properties
- (point) (mh-line-end-position)))
+ (point) (line-end-position)))
(let ((msg (string-to-number msg)))
(set-buffer folder)
(mh-index-update-single-msg msg checksum origin-map)))))
diff --git a/lisp/mh-e/mh-seq.el b/lisp/mh-e/mh-seq.el
index 9cdf39f7f1e..077e289c01d 100644
--- a/lisp/mh-e/mh-seq.el
+++ b/lisp/mh-e/mh-seq.el
@@ -38,9 +38,8 @@
(defvar mh-last-seq-used nil
"Name of seq to which a msg was last added.")
-(defvar mh-non-seq-mode-line-annotation nil
+(defvar-local mh-non-seq-mode-line-annotation nil
"Saved value of `mh-mode-line-annotation' when narrowed to a seq.")
-(make-variable-buffer-local 'mh-non-seq-mode-line-annotation)
(defvar mh-internal-seqs '(answered cur deleted forwarded printed))
@@ -167,7 +166,7 @@ The list appears in a buffer named \"*MH-E Sequences*\"."
(insert "\n"))
(setq seq-list (cdr seq-list)))
(goto-char (point-min))
- (mh-view-mode-enter)
+ (view-mode-enter)
(setq view-exit-action 'kill-buffer)
(message "Listing sequences...done")))))
@@ -187,17 +186,12 @@ MESSAGE appears."
(message "Message %d%s is in sequences: %s"
message
(cond (dest-folder (format " (to be refiled to %s)" dest-folder))
- (deleted-flag (format " (to be deleted)"))
+ (deleted-flag " (to be deleted)")
(t ""))
(mapconcat #'concat
(mh-list-to-string (mh-seq-containing-msg message t))
" "))))
-;; Shush compiler.
-(mh-do-in-xemacs
- (defvar tool-bar-mode))
-(defvar tool-bar-map)
-
;;;###mh-autoload
(defun mh-narrow-to-seq (sequence)
"Restrict display to messages in SEQUENCE.
@@ -229,12 +223,12 @@ When you want to widen the view to all your messages again, use
(mh-make-folder-mode-line)
(mh-recenter nil)
(when (and (boundp 'tool-bar-mode) tool-bar-mode)
- (set (make-local-variable 'tool-bar-map)
- mh-folder-seq-tool-bar-map)
+ (setq-local tool-bar-map
+ mh-folder-seq-tool-bar-map)
(when (buffer-live-p (get-buffer mh-show-buffer))
(with-current-buffer mh-show-buffer
- (set (make-local-variable 'tool-bar-map)
- mh-show-seq-tool-bar-map))))
+ (setq-local tool-bar-map
+ mh-show-seq-tool-bar-map))))
(push 'widen mh-view-ops)))
(t
(error "No messages in sequence %s" (symbol-name sequence))))))
@@ -362,10 +356,10 @@ remove all limits and sequence restrictions."
(mh-notate-cur)
(mh-recenter nil)))
(when (and (null mh-folder-view-stack) (boundp 'tool-bar-mode) tool-bar-mode)
- (set (make-local-variable 'tool-bar-map) mh-folder-tool-bar-map)
+ (setq-local tool-bar-map mh-folder-tool-bar-map)
(when (buffer-live-p (get-buffer mh-show-buffer))
(with-current-buffer mh-show-buffer
- (set (make-local-variable 'tool-bar-map) mh-show-tool-bar-map)))))
+ (setq-local tool-bar-map mh-show-tool-bar-map)))))
@@ -582,7 +576,7 @@ Otherwise, the message number at point is returned.
This function is usually used with `mh-iterate-on-range' in order to
provide a uniform interface to MH-E functions."
- (cond ((mh-mark-active-p t) (cons (region-beginning) (region-end)))
+ (cond ((and transient-mark-mode mark-active) (cons (region-beginning) (region-end)))
(current-prefix-arg (mh-read-range range-prompt nil nil t t))
(default default)
(t (mh-get-msg-num t))))
@@ -736,7 +730,7 @@ completion is over."
(cl-multiple-value-bind (folder unseen total)
(cl-values-list
(mh-parse-flist-output-line
- (buffer-substring (point) (mh-line-end-position))))
+ (buffer-substring (point) (line-end-position))))
(list total unseen folder))))
(defun mh-folder-size-folder (folder)
@@ -764,7 +758,7 @@ folders whose names end with a `+' character."
(when (search-backward " out of " (point-min) t)
(setq total (string-to-number
(buffer-substring-no-properties
- (match-end 0) (mh-line-end-position))))
+ (match-end 0) (line-end-position))))
(when (search-backward " in sequence " (point-min) t)
(setq p (point))
(when (search-backward " has " (point-min) t)
@@ -786,10 +780,10 @@ If SAVE-REFILES is non-nil, then keep the sequences
that note messages to be refiled."
(let ((seqs ()))
(cond (save-refiles
- (mh-mapc (lambda (seq) ; Save the refiling sequences
- (if (mh-folder-name-p (mh-seq-name seq))
- (setq seqs (cons seq seqs))))
- mh-seq-list)))
+ (mapc (lambda (seq) ; Save the refiling sequences
+ (if (mh-folder-name-p (mh-seq-name seq))
+ (setq seqs (cons seq seqs))))
+ mh-seq-list)))
(save-excursion
(if (eq 0 (mh-exec-cmd-quiet nil "mark" folder "-list"))
(progn
@@ -942,7 +936,7 @@ font-lock is turned on."
;; the case of user sequences.
(mh-notate nil nil mh-cmd-note)
(when font-lock-mode
- (font-lock-fontify-region (point) (mh-line-end-position))))
+ (font-lock-fontify-region (point) (line-end-position))))
(forward-char (+ mh-cmd-note mh-scan-field-destination-offset))
(let ((stack (gethash msg mh-sequence-notation-history)))
(setf (gethash msg mh-sequence-notation-history)
diff --git a/lisp/mh-e/mh-show.el b/lisp/mh-e/mh-show.el
index 803f07e02b2..16489bf0172 100644
--- a/lisp/mh-e/mh-show.el
+++ b/lisp/mh-e/mh-show.el
@@ -144,7 +144,7 @@ displayed."
(if (not clean-message-header)
(mh-start-of-uncleaned-message)))
(mh-display-msg msg folder)))
- (unless (mh-window-full-height-p) ; not vertically split
+ (unless (window-full-height-p) ; not vertically split
(shrink-window (- (window-height) (or mh-summary-height
(mh-summary-height)))))
(mh-recenter nil)
@@ -328,17 +328,15 @@ ignored if VISIBLE-HEADERS is non-nil."
(defun mh-summary-height ()
"Return ideal value for the variable `mh-summary-height'.
The current frame height is taken into consideration."
- (or (and (fboundp 'frame-height)
- (> (frame-height) 24)
+ (or (and (> (frame-height) 24)
(min 10 (/ (frame-height) 6)))
4))
-;; Infrastructure to generate show-buffer functions from folder functions
-;; XEmacs does not have deactivate-mark? What is the equivalent of
-;; transient-mark-mode for XEmacs? Should we be restoring the mark in the
-;; folder buffer after the operation has been carried out.
+;; Infrastructure to generate show-buffer functions from folder functions.
+;; Should we be restoring the mark in the folder buffer after the
+;; operation has been carried out?
(defmacro mh-defun-show-buffer (function original-function
&optional dont-return)
"Define FUNCTION to run ORIGINAL-FUNCTION in folder buffer.
@@ -363,13 +361,14 @@ still visible.\n")
folder-buffer)
(delete-other-windows))
(mh-goto-cur-msg t)
- (mh-funcall-if-exists deactivate-mark)
+ (deactivate-mark)
(unwind-protect
(prog1 (call-interactively (function ,original-function))
(setq normal-exit t))
- (mh-funcall-if-exists deactivate-mark)
+ (deactivate-mark)
(when (eq major-mode 'mh-folder-mode)
- (mh-funcall-if-exists hl-line-highlight))
+ (when (fboundp 'hl-line-highlight)
+ (hl-line-highlight)))
(cond ((not normal-exit)
(set-window-configuration config))
,(if dont-return
@@ -464,8 +463,7 @@ still visible.\n")
(mh-defun-show-buffer mh-show-toggle-tick mh-toggle-tick)
(mh-defun-show-buffer mh-show-narrow-to-tick mh-narrow-to-tick)
(mh-defun-show-buffer mh-show-junk-allowlist mh-junk-allowlist)
-(mh-defun-show-buffer mh-show-junk-whitelist mh-junk-allowlist)
-(make-obsolete 'mh-show-junk-whitelist 'mh-show-junk-allowlist "28.1")
+(mh-defun-show-buffer mh-show-junk-whitelist mh-junk-whitelist)
(mh-defun-show-buffer mh-show-junk-blocklist mh-junk-blocklist)
(mh-defun-show-buffer mh-show-index-new-messages mh-index-new-messages)
(mh-defun-show-buffer mh-show-index-ticked-messages mh-index-ticked-messages)
@@ -562,132 +560,132 @@ still visible.\n")
;;; MH-Show Keys
-(gnus-define-keys mh-show-mode-map
- " " mh-show-page-msg
- "!" mh-show-refile-or-write-again
- "'" mh-show-toggle-tick
- "," mh-show-header-display
- "." mh-show-show
- ":" mh-show-show-preferred-alternative
- ">" mh-show-write-message-to-file
- "?" mh-help
- "E" mh-show-extract-rejected-mail
- "M" mh-show-modify
- "\177" mh-show-previous-page
- "\C-d" mh-show-delete-msg-no-motion
- "\t" mh-show-next-button
- [backtab] mh-show-prev-button
- "\M-\t" mh-show-prev-button
- "\ed" mh-show-redistribute
- "^" mh-show-refile-msg
- "c" mh-show-copy-msg
- "d" mh-show-delete-msg
- "e" mh-show-edit-again
- "f" mh-show-forward
- "g" mh-show-goto-msg
- "i" mh-show-inc-folder
- "k" mh-show-delete-subject-or-thread
- "m" mh-show-send
- "n" mh-show-next-undeleted-msg
- "\M-n" mh-show-next-unread-msg
- "o" mh-show-refile-msg
- "p" mh-show-previous-undeleted-msg
- "\M-p" mh-show-previous-unread-msg
- "q" mh-show-quit
- "r" mh-show-reply
- "s" mh-show-send
- "t" mh-show-toggle-showing
- "u" mh-show-undo
- "x" mh-show-execute-commands
- "v" mh-show-index-visit-folder
- "|" mh-show-pipe-msg)
-
-(gnus-define-keys (mh-show-folder-map "F" mh-show-mode-map)
- "?" mh-prefix-help
- "'" mh-index-ticked-messages
- "S" mh-show-sort-folder
- "c" mh-show-catchup
- "f" mh-show-visit-folder
- "k" mh-show-kill-folder
- "l" mh-show-list-folders
- "n" mh-index-new-messages
- "o" mh-show-visit-folder
- "p" mh-show-pack-folder
- "q" mh-show-index-sequenced-messages
- "r" mh-show-rescan-folder
- "s" mh-search
- "t" mh-show-toggle-threads
- "u" mh-show-undo-folder
- "v" mh-show-visit-folder)
-
-(gnus-define-keys (mh-show-sequence-map "S" mh-show-mode-map)
- "'" mh-show-narrow-to-tick
- "?" mh-prefix-help
- "d" mh-show-delete-msg-from-seq
- "k" mh-show-delete-seq
- "l" mh-show-list-sequences
- "n" mh-show-narrow-to-seq
- "p" mh-show-put-msg-in-seq
- "s" mh-show-msg-is-in-seq
- "w" mh-show-widen)
-
-(define-key mh-show-mode-map "I" mh-inc-spool-map)
-
-(gnus-define-keys (mh-show-junk-map "J" mh-show-mode-map)
- "?" mh-prefix-help
- "a" mh-show-junk-allowlist
- "b" mh-show-junk-blocklist
- "w" mh-show-junk-whitelist)
-
-(gnus-define-keys (mh-show-ps-print-map "P" mh-show-mode-map)
- "?" mh-prefix-help
- "C" mh-show-ps-print-toggle-color
- "F" mh-show-ps-print-toggle-faces
- "f" mh-show-ps-print-msg-file
- "l" mh-show-print-msg
- "p" mh-show-ps-print-msg)
-
-(gnus-define-keys (mh-show-thread-map "T" mh-show-mode-map)
- "?" mh-prefix-help
- "u" mh-show-thread-ancestor
- "p" mh-show-thread-previous-sibling
- "n" mh-show-thread-next-sibling
- "t" mh-show-toggle-threads
- "d" mh-show-thread-delete
- "o" mh-show-thread-refile)
-
-(gnus-define-keys (mh-show-limit-map "/" mh-show-mode-map)
- "'" mh-show-narrow-to-tick
- "?" mh-prefix-help
- "c" mh-show-narrow-to-cc
- "g" mh-show-narrow-to-range
- "m" mh-show-narrow-to-from
- "s" mh-show-narrow-to-subject
- "t" mh-show-narrow-to-to
- "w" mh-show-widen)
-
-(gnus-define-keys (mh-show-extract-map "X" mh-show-mode-map)
- "?" mh-prefix-help
- "s" mh-show-store-msg
- "u" mh-show-store-msg)
-
-(gnus-define-keys (mh-show-digest-map "D" mh-show-mode-map)
- "?" mh-prefix-help
- " " mh-show-page-digest
- "\177" mh-show-page-digest-backwards
- "b" mh-show-burst-digest)
-
-(gnus-define-keys (mh-show-mime-map "K" mh-show-mode-map)
- "?" mh-prefix-help
- "a" mh-mime-save-parts
- "e" mh-show-display-with-external-viewer
- "v" mh-show-toggle-mime-part
- "o" mh-show-save-mime-part
- "i" mh-show-inline-mime-part
- "t" mh-show-toggle-mime-buttons
- "\t" mh-show-next-button
- [backtab] mh-show-prev-button
- "\M-\t" mh-show-prev-button)
+(define-keymap :keymap mh-show-mode-map
+ "SPC" #'mh-show-page-msg
+ "!" #'mh-show-refile-or-write-again
+ "'" #'mh-show-toggle-tick
+ "," #'mh-show-header-display
+ "." #'mh-show-show
+ ":" #'mh-show-show-preferred-alternative
+ ">" #'mh-show-write-message-to-file
+ "?" #'mh-help
+ "E" #'mh-show-extract-rejected-mail
+ "M" #'mh-show-modify
+ "DEL" #'mh-show-previous-page
+ "C-d" #'mh-show-delete-msg-no-motion
+ "TAB" #'mh-show-next-button
+ "<backtab>" #'mh-show-prev-button
+ "C-M-i" #'mh-show-prev-button
+ "ESC d" #'mh-show-redistribute
+ "^" #'mh-show-refile-msg
+ "c" #'mh-show-copy-msg
+ "d" #'mh-show-delete-msg
+ "e" #'mh-show-edit-again
+ "f" #'mh-show-forward
+ "g" #'mh-show-goto-msg
+ "i" #'mh-show-inc-folder
+ "k" #'mh-show-delete-subject-or-thread
+ "m" #'mh-show-send
+ "n" #'mh-show-next-undeleted-msg
+ "M-n" #'mh-show-next-unread-msg
+ "o" #'mh-show-refile-msg
+ "p" #'mh-show-previous-undeleted-msg
+ "M-p" #'mh-show-previous-unread-msg
+ "q" #'mh-show-quit
+ "r" #'mh-show-reply
+ "s" #'mh-show-send
+ "t" #'mh-show-toggle-showing
+ "u" #'mh-show-undo
+ "x" #'mh-show-execute-commands
+ "v" #'mh-show-index-visit-folder
+ "|" #'mh-show-pipe-msg
+
+ "F" (define-keymap :prefix 'mh-show-folder-map
+ "?" #'mh-prefix-help
+ "'" #'mh-index-ticked-messages
+ "S" #'mh-show-sort-folder
+ "c" #'mh-show-catchup
+ "f" #'mh-show-visit-folder
+ "k" #'mh-show-kill-folder
+ "l" #'mh-show-list-folders
+ "n" #'mh-index-new-messages
+ "o" #'mh-show-visit-folder
+ "p" #'mh-show-pack-folder
+ "q" #'mh-show-index-sequenced-messages
+ "r" #'mh-show-rescan-folder
+ "s" #'mh-search
+ "t" #'mh-show-toggle-threads
+ "u" #'mh-show-undo-folder
+ "v" #'mh-show-visit-folder)
+
+ "S" (define-keymap :prefix 'mh-show-sequence-map
+ "'" #'mh-show-narrow-to-tick
+ "?" #'mh-prefix-help
+ "d" #'mh-show-delete-msg-from-seq
+ "k" #'mh-show-delete-seq
+ "l" #'mh-show-list-sequences
+ "n" #'mh-show-narrow-to-seq
+ "p" #'mh-show-put-msg-in-seq
+ "s" #'mh-show-msg-is-in-seq
+ "w" #'mh-show-widen)
+
+ "I" mh-inc-spool-map
+
+ "J" (define-keymap :prefix 'mh-show-junk-map
+ "?" #'mh-prefix-help
+ "a" #'mh-show-junk-allowlist
+ "b" #'mh-show-junk-blocklist
+ "w" #'mh-show-junk-whitelist)
+
+ "P" (define-keymap :prefix 'mh-show-ps-print-map
+ "?" #'mh-prefix-help
+ "C" #'mh-show-ps-print-toggle-color
+ "F" #'mh-show-ps-print-toggle-faces
+ "f" #'mh-show-ps-print-msg-file
+ "l" #'mh-show-print-msg
+ "p" #'mh-show-ps-print-msg)
+
+ "T" (define-keymap :prefix 'mh-show-thread-map
+ "?" #'mh-prefix-help
+ "u" #'mh-show-thread-ancestor
+ "p" #'mh-show-thread-previous-sibling
+ "n" #'mh-show-thread-next-sibling
+ "t" #'mh-show-toggle-threads
+ "d" #'mh-show-thread-delete
+ "o" #'mh-show-thread-refile)
+
+ "/" (define-keymap :prefix 'mh-show-limit-map
+ "'" #'mh-show-narrow-to-tick
+ "?" #'mh-prefix-help
+ "c" #'mh-show-narrow-to-cc
+ "g" #'mh-show-narrow-to-range
+ "m" #'mh-show-narrow-to-from
+ "s" #'mh-show-narrow-to-subject
+ "t" #'mh-show-narrow-to-to
+ "w" #'mh-show-widen)
+
+ "X" (define-keymap :prefix 'mh-show-extract-map
+ "?" #'mh-prefix-help
+ "s" #'mh-show-store-msg
+ "u" #'mh-show-store-msg)
+
+ "D" (define-keymap :prefix 'mh-show-digest-map
+ "?" #'mh-prefix-help
+ "SPC" #'mh-show-page-digest
+ "DEL" #'mh-show-page-digest-backwards
+ "b" #'mh-show-burst-digest)
+
+ "K" (define-keymap :prefix 'mh-show-mime-map
+ "?" #'mh-prefix-help
+ "a" #'mh-mime-save-parts
+ "e" #'mh-show-display-with-external-viewer
+ "v" #'mh-show-toggle-mime-part
+ "o" #'mh-show-save-mime-part
+ "i" #'mh-show-inline-mime-part
+ "t" #'mh-show-toggle-mime-buttons
+ "TAB" #'mh-show-next-button
+ "<backtab>" #'mh-show-prev-button
+ "C-M-i" #'mh-show-prev-button))
@@ -817,9 +815,6 @@ operation."
;; Ensure new buffers won't get this mode if default major-mode is nil.
(put 'mh-show-mode 'mode-class 'special)
-;; Shush compiler.
-(defvar font-lock-auto-fontify)
-
;;;###mh-autoload
(define-derived-mode mh-show-mode text-mode "MH-Show"
"Major mode for showing messages in MH-E.\\<mh-show-mode-map>
@@ -836,17 +831,14 @@ The hook `mh-show-mode-hook' is called upon entry to this mode.
See also `mh-folder-mode'.
\\{mh-show-mode-map}"
- (mh-do-in-gnu-emacs
- (if (boundp 'tool-bar-map)
- (set (make-local-variable 'tool-bar-map) mh-show-tool-bar-map)))
- (mh-do-in-xemacs
- (mh-tool-bar-init :show))
- (set (make-local-variable 'mail-header-separator) mh-mail-header-separator)
+ (if (boundp 'tool-bar-map)
+ (setq-local tool-bar-map mh-show-tool-bar-map))
+ (setq-local mail-header-separator mh-mail-header-separator)
(setq paragraph-start (default-value 'paragraph-start))
(setq buffer-invisibility-spec '((vanish . t) t))
- (set (make-local-variable 'line-move-ignore-invisible) t)
+ (setq-local line-move-ignore-invisible t)
(make-local-variable 'font-lock-defaults)
- ;;(set (make-local-variable 'font-lock-support-mode) nil)
+ ;;(setq-local font-lock-support-mode nil)
(cond
((equal mh-highlight-citation-style 'font-lock)
(setq font-lock-defaults '(mh-show-font-lock-keywords-with-cite t)))
@@ -858,16 +850,8 @@ See also `mh-folder-mode'.
(mh-gnus-article-highlight-citation))
(t
(setq font-lock-defaults '(mh-show-font-lock-keywords t))))
- (if (and (featurep 'xemacs)
- font-lock-auto-fontify)
- (turn-on-font-lock))
(when mh-decode-mime-flag
- (mh-make-local-hook 'kill-buffer-hook)
(add-hook 'kill-buffer-hook #'mh-mime-cleanup nil t))
- (mh-do-in-xemacs
- (easy-menu-add mh-show-sequence-menu)
- (easy-menu-add mh-show-message-menu)
- (easy-menu-add mh-show-folder-menu))
(make-local-variable 'mh-show-folder-buffer)
(buffer-disable-undo)
(use-local-map mh-show-mode-map))
diff --git a/lisp/mh-e/mh-speed.el b/lisp/mh-e/mh-speed.el
index 76ef990d825..d9909a034d9 100644
--- a/lisp/mh-e/mh-speed.el
+++ b/lisp/mh-e/mh-speed.el
@@ -63,13 +63,13 @@
'("--"
["Visit Folder" mh-speed-view
(with-current-buffer speedbar-buffer
- (get-text-property (mh-line-beginning-position) 'mh-folder))]
+ (get-text-property (line-beginning-position) 'mh-folder))]
["Expand Nested Folders" mh-speed-expand-folder
- (and (get-text-property (mh-line-beginning-position) 'mh-children-p)
- (not (get-text-property (mh-line-beginning-position) 'mh-expanded)))]
+ (and (get-text-property (line-beginning-position) 'mh-children-p)
+ (not (get-text-property (line-beginning-position) 'mh-expanded)))]
["Contract Nested Folders" mh-speed-contract-folder
- (and (get-text-property (mh-line-beginning-position) 'mh-children-p)
- (get-text-property (mh-line-beginning-position) 'mh-expanded))]
+ (and (get-text-property (line-beginning-position) 'mh-children-p)
+ (get-text-property (line-beginning-position) 'mh-expanded))]
["Refresh Speedbar" mh-speed-refresh t])
"Extra menu items for speedbar.")
@@ -83,11 +83,11 @@
(defvar mh-folder-speedbar-key-map (speedbar-make-specialized-keymap)
"Specialized speedbar keymap for MH-E buffers.")
-(gnus-define-keys mh-folder-speedbar-key-map
- "+" mh-speed-expand-folder
- "-" mh-speed-contract-folder
- "\r" mh-speed-view
- "r" mh-speed-refresh)
+(define-keymap :keymap mh-folder-speedbar-key-map
+ "+" #'mh-speed-expand-folder
+ "-" #'mh-speed-contract-folder
+ "RET" #'mh-speed-view
+ "r" #'mh-speed-refresh)
(defvar mh-show-speedbar-key-map mh-folder-speedbar-key-map)
(defvar mh-letter-speedbar-key-map mh-folder-speedbar-key-map)
@@ -150,7 +150,7 @@ The optional arguments from speedbar are IGNORED."
(forward-line -1)
(speedbar-change-expand-button-char ?+)
(add-text-properties
- (mh-line-beginning-position) (1+ (line-beginning-position))
+ (line-beginning-position) (1+ (line-beginning-position))
'(mh-expanded nil)))
(t
(forward-line)
@@ -158,14 +158,14 @@ The optional arguments from speedbar are IGNORED."
(goto-char point)
(speedbar-change-expand-button-char ?-)
(add-text-properties
- (mh-line-beginning-position) (1+ (line-beginning-position))
+ (line-beginning-position) (1+ (line-beginning-position))
'(mh-expanded t)))))))
(defun mh-speed-view (&rest _ignored)
"Visits the selected folder just as if you had used \\<mh-folder-mode-map>\\[mh-visit-folder].
The optional arguments from speedbar are IGNORED."
(interactive)
- (let* ((folder (get-text-property (mh-line-beginning-position) 'mh-folder))
+ (let* ((folder (get-text-property (line-beginning-position) 'mh-folder))
(range (and (stringp folder)
(mh-read-range "Scan" folder t nil nil
mh-interpret-number-as-range-flag))))
@@ -191,9 +191,9 @@ created."
(forward-line -1)
(setf (gethash nil mh-speed-folder-map)
(set-marker (or (gethash nil mh-speed-folder-map) (make-marker))
- (1+ (mh-line-beginning-position))))
+ (1+ (line-beginning-position))))
(add-text-properties
- (mh-line-beginning-position) (1+ (line-beginning-position))
+ (line-beginning-position) (1+ (line-beginning-position))
'(mh-folder nil mh-expanded nil mh-children-p t mh-level 0))
(mh-speed-stealth-update t)
(when (> mh-speed-update-interval 0)
@@ -260,12 +260,12 @@ The update is always carried out if FORCE is non-nil."
(speedbar-with-writable
(goto-char (gethash folder mh-speed-folder-map (point)))
(beginning-of-line)
- (if (re-search-forward "([1-9][0-9]*/[0-9]+)" (mh-line-end-position) t)
+ (if (re-search-forward "([1-9][0-9]*/[0-9]+)" (line-end-position) t)
(setq face (mh-speed-bold-face face))
(setq face (mh-speed-normal-face face)))
(beginning-of-line)
- (when (re-search-forward "\\[.\\] " (mh-line-end-position) t)
- (put-text-property (point) (mh-line-end-position) 'face face)))))
+ (when (re-search-forward "\\[.\\] " (line-end-position) t)
+ (put-text-property (point) (line-end-position) 'face face)))))
(defun mh-speed-normal-face (face)
"Return normal face for given FACE."
@@ -305,7 +305,7 @@ The function will expand out parent folders of FOLDER if needed."
(while suffix-list
;; We always need at least one toggle. We need two if the directory list
;; is stale since a folder was added.
- (when (equal prefix (get-text-property (mh-line-beginning-position)
+ (when (equal prefix (get-text-property (line-beginning-position)
'mh-folder))
(mh-speed-toggle)
(unless (get-text-property (point) 'mh-expanded)
@@ -359,9 +359,9 @@ uses."
(setf (gethash folder-name mh-speed-folder-map)
(set-marker (or (gethash folder-name mh-speed-folder-map)
(make-marker))
- (1+ (mh-line-beginning-position))))
+ (1+ (line-beginning-position))))
(add-text-properties
- (mh-line-beginning-position) (1+ (mh-line-beginning-position))
+ (line-beginning-position) (1+ (line-beginning-position))
`(mh-folder ,folder-name
mh-expanded nil
mh-children-p ,(not (not (cdr f)))
@@ -374,12 +374,9 @@ uses."
(defvar mh-speed-flists-folder nil)
(defmacro mh-process-kill-without-query (process)
- "PROCESS can be killed without query on Emacs exit.
-Avoid using `process-kill-without-query' if possible since it is
-now obsolete."
- (if (fboundp 'set-process-query-on-exit-flag)
- `(set-process-query-on-exit-flag ,process nil)
- `(process-kill-without-query ,process)))
+ "PROCESS can be killed without query on Emacs exit."
+ (declare (obsolete set-process-query-on-exit-flag "29.1"))
+ `(set-process-query-on-exit-flag ,process nil))
;;;###mh-autoload
(defun mh-speed-flists (force &rest folders)
@@ -391,7 +388,7 @@ flists is run only for that one folder."
(interactive (list t))
(when force
(when mh-speed-flists-timer
- (mh-cancel-timer mh-speed-flists-timer)
+ (cancel-timer mh-speed-flists-timer)
(setq mh-speed-flists-timer nil))
(when (and (processp mh-speed-flists-process)
(not (eq (process-status mh-speed-flists-process) 'exit)))
@@ -427,7 +424,7 @@ flists is run only for that one folder."
(or mh-speed-flists-folder '("-recurse"))))
;; Run flists on all folders the next time around...
(setq mh-speed-flists-folder nil)
- (mh-process-kill-without-query mh-speed-flists-process)
+ (set-process-query-on-exit-flag mh-speed-flists-process nil)
(set-process-filter mh-speed-flists-process
#'mh-speed-parse-flists-output)))))))
@@ -462,25 +459,25 @@ be handled next."
face)
(when pos
(goto-char pos)
- (goto-char (mh-line-beginning-position))
+ (goto-char (line-beginning-position))
(cond
((null (get-text-property (point) 'mh-count))
- (goto-char (mh-line-end-position))
+ (goto-char (line-end-position))
(setq face (get-text-property (1- (point)) 'face))
(insert (format " (%s/%s)" unseen total))
(mh-speed-highlight 'unknown face)
- (goto-char (mh-line-beginning-position))
+ (goto-char (line-beginning-position))
(add-text-properties (point) (1+ (point))
`(mh-count (,unseen . ,total))))
((not (equal (get-text-property (point) 'mh-count)
(cons unseen total)))
- (goto-char (mh-line-end-position))
+ (goto-char (line-end-position))
(setq face (get-text-property (1- (point)) 'face))
- (re-search-backward " " (mh-line-beginning-position) t)
- (delete-region (point) (mh-line-end-position))
+ (re-search-backward " " (line-beginning-position) t)
+ (delete-region (point) (line-end-position))
(insert (format " (%s/%s)" unseen total))
(mh-speed-highlight 'unknown face)
- (goto-char (mh-line-beginning-position))
+ (goto-char (line-beginning-position))
(add-text-properties
(point) (1+ (point))
`(mh-count (,unseen . ,total))))))))))))
@@ -509,15 +506,15 @@ be handled next."
(caar parent-kids)))
(setq parent-change ? ))))
(goto-char parent-position)
- (when (equal (get-text-property (mh-line-beginning-position) 'mh-folder)
+ (when (equal (get-text-property (line-beginning-position) 'mh-folder)
parent)
- (when (get-text-property (mh-line-beginning-position) 'mh-expanded)
+ (when (get-text-property (line-beginning-position) 'mh-expanded)
(mh-speed-toggle))
(when parent-change
(speedbar-with-writable
(mh-speedbar-change-expand-button-char parent-change)
(add-text-properties
- (mh-line-beginning-position) (1+ (mh-line-beginning-position))
+ (line-beginning-position) (1+ (line-beginning-position))
`(mh-children-p ,(equal parent-change ?+)))))
(mh-speed-highlight mh-speed-last-selected-folder 'mh-speedbar-folder)
(setq mh-speed-last-selected-folder nil)
@@ -531,15 +528,15 @@ be handled next."
"Change the expansion button character to CHAR for the current line."
(save-excursion
(beginning-of-line)
- (if (re-search-forward "\\[.\\]" (mh-line-end-position) t)
+ (if (re-search-forward "\\[.\\]" (line-end-position) t)
(speedbar-with-writable
(backward-char 2)
(delete-char 1)
(insert-char char 1 t)
(put-text-property (point) (1- (point)) 'invisible nil)
;; make sure we fix the image on the text here.
- (mh-funcall-if-exists
- speedbar-insert-image-button-maybe (- (point) 2) 3)))))
+ (when (fboundp 'speedbar-insert-image-button-maybe)
+ (speedbar-insert-image-button-maybe (- (point) 2) 3))))))
;;;###mh-autoload
(defun mh-speed-add-folder (folder)
@@ -562,9 +559,9 @@ The function invalidates the latest ancestor that is present."
(speedbar-with-writable
(mh-speedbar-change-expand-button-char ?+)
(add-text-properties
- (mh-line-beginning-position) (1+ (mh-line-beginning-position))
+ (line-beginning-position) (1+ (line-beginning-position))
'(mh-children-p t)))
- (when (get-text-property (mh-line-beginning-position) 'mh-expanded)
+ (when (get-text-property (line-beginning-position) 'mh-expanded)
(mh-speed-toggle))
(setq mh-speed-refresh-flag t))))
diff --git a/lisp/mh-e/mh-thread.el b/lisp/mh-e/mh-thread.el
index 89b0dbd9798..1be2185ecdf 100644
--- a/lisp/mh-e/mh-thread.el
+++ b/lisp/mh-e/mh-thread.el
@@ -86,41 +86,33 @@
message parent children
(real-child-p t))
-(defvar mh-thread-id-hash nil
+(defvar-local mh-thread-id-hash nil
"Hash table used to canonicalize message identifiers.")
-(make-variable-buffer-local 'mh-thread-id-hash)
-(defvar mh-thread-subject-hash nil
+(defvar-local mh-thread-subject-hash nil
"Hash table used to canonicalize subject strings.")
-(make-variable-buffer-local 'mh-thread-subject-hash)
-(defvar mh-thread-id-table nil
+(defvar-local mh-thread-id-table nil
"Thread ID table maps from message identifiers to message containers.")
-(make-variable-buffer-local 'mh-thread-id-table)
-(defvar mh-thread-index-id-map nil
+(defvar-local mh-thread-index-id-map nil
"Table to look up message identifier from message index.")
-(make-variable-buffer-local 'mh-thread-index-id-map)
-(defvar mh-thread-id-index-map nil
+(defvar-local mh-thread-id-index-map nil
"Table to look up message index number from message identifier.")
-(make-variable-buffer-local 'mh-thread-id-index-map)
-(defvar mh-thread-subject-container-hash nil
+(defvar-local mh-thread-subject-container-hash nil
"Hash table used to group messages by subject.")
-(make-variable-buffer-local 'mh-thread-subject-container-hash)
-(defvar mh-thread-duplicates nil
+(defvar-local mh-thread-duplicates nil
"Hash table used to associate messages with the same message identifier.")
-(make-variable-buffer-local 'mh-thread-duplicates)
-(defvar mh-thread-history ()
+(defvar-local mh-thread-history ()
"Variable to remember the transformations to the thread tree.
When new messages are added, these transformations are rewound,
then the links are added from the newly seen messages. Finally
the transformations are redone to get the new thread tree. This
makes incremental threading easier.")
-(make-variable-buffer-local 'mh-thread-history)
(defvar mh-thread-body-width nil
"Width of scan substring that contains subject and body of message.")
@@ -147,7 +139,7 @@ to the message that started everything."
(cond (thread-root-flag
(while (mh-thread-immediate-ancestor))
(mh-maybe-show))
- ((equal current-level 1)
+ ((equal current-level 0)
(message "Message has no ancestor"))
(t (mh-thread-immediate-ancestor)
(mh-maybe-show)))))
@@ -250,8 +242,8 @@ sibling."
(defun mh-thread-current-indentation-level ()
"Find the number of spaces by which current message is indented."
(save-excursion
- (let ((address-start-offset (+ mh-cmd-note mh-scan-date-flag-width
- mh-scan-date-width 1))
+ (let ((address-start-offset (+ mh-cmd-note
+ mh-scan-field-from-start-offset))
(level 0))
(beginning-of-line)
(forward-char address-start-offset)
@@ -283,8 +275,8 @@ at the end."
(beginning-of-line)
(if (eobp)
nil
- (let ((address-start-offset (+ mh-cmd-note mh-scan-date-flag-width
- mh-scan-date-width 1))
+ (let ((address-start-offset (+ mh-cmd-note
+ mh-scan-field-from-start-offset))
(level (mh-thread-current-indentation-level))
spaces begin)
(setq begin (point))
@@ -294,7 +286,7 @@ at the end."
(while (not (eobp))
(forward-char address-start-offset)
(unless (equal (string-match spaces (buffer-substring-no-properties
- (point) (mh-line-end-position)))
+ (point) (line-end-position)))
0)
(beginning-of-line)
(backward-char)
@@ -455,8 +447,8 @@ If optional argument STRING is given then that is assumed to be
the scan line. Otherwise uses the line at point as the scan line
to parse."
(let* ((string (or string (buffer-substring-no-properties
- (mh-line-beginning-position)
- (mh-line-end-position))))
+ (line-beginning-position)
+ (line-end-position))))
(address-start (+ mh-cmd-note mh-scan-field-from-start-offset))
(body-start (+ mh-cmd-note mh-scan-field-from-end-offset))
(first-string (substring string 0 address-start)))
@@ -597,20 +589,20 @@ Only information about messages in MSG-LIST are added to the tree."
(while (not (eobp))
(cl-block process-message
(let* ((index-line
- (prog1 (buffer-substring (point) (mh-line-end-position))
+ (prog1 (buffer-substring (point) (line-end-position))
(forward-line)))
(index (string-to-number index-line))
- (id (prog1 (buffer-substring (point) (mh-line-end-position))
+ (id (prog1 (buffer-substring (point) (line-end-position))
(forward-line)))
(refs (prog1
- (buffer-substring (point) (mh-line-end-position))
+ (buffer-substring (point) (line-end-position))
(forward-line)))
(in-reply-to (prog1 (buffer-substring (point)
- (mh-line-end-position))
+ (line-end-position))
(forward-line)))
(subject (prog1
(buffer-substring
- (point) (mh-line-end-position))
+ (point) (line-end-position))
(forward-line)))
(subject-re-p nil))
(unless (gethash index mh-thread-scan-line-map)
diff --git a/lisp/mh-e/mh-tool-bar.el b/lisp/mh-e/mh-tool-bar.el
index 94aa8dd4a92..d451ae34d29 100644
--- a/lisp/mh-e/mh-tool-bar.el
+++ b/lisp/mh-e/mh-tool-bar.el
@@ -27,10 +27,8 @@
;;; Code:
(require 'mh-e)
-(mh-do-in-gnu-emacs
- (require 'tool-bar))
-(mh-do-in-xemacs
- (require 'toolbar))
+(require 'mh-acros)
+(require 'tool-bar)
;;; Tool Bar Commands
@@ -79,9 +77,6 @@ When INCLUDE-FLAG is non-nil, include message body being replied to."
;;; Tool Bar Creation
-;; Shush compiler.
-(defvar image-load-path)
-
(defmacro mh-tool-bar-define (defaults &rest buttons)
"Define a tool bar for MH-E.
DEFAULTS is the list of buttons that are present by default. It
@@ -145,8 +140,6 @@ where,
(let* ((name (nth 0 button))
(name-str (symbol-name name))
(icon (nth 2 button))
- (xemacs-icon (mh-do-in-xemacs
- `(cdr (assoc (quote ,(intern icon)) mh-xemacs-icon-map))))
(full-doc (nth 3 button))
(doc (if (string-match "\\(.*\\)\n" full-doc)
(match-string 1 full-doc)
@@ -186,11 +179,10 @@ where,
(t 'folder-buttons)))
(docs (cond ((eq mbuttons 'letter-buttons) 'letter-docs)
((eq mbuttons 'folder-buttons) 'folder-docs))))
- (add-to-list vector-list `(vector ,xemacs-icon ',function t ,full-doc))
+ (add-to-list vector-list `(vector nil ',function t ,full-doc))
(add-to-list
setter `(when (member ',name ,list)
- (mh-funcall-if-exists
- tool-bar-add-item ,icon ',function ',key
+ (tool-bar-add-item ,icon ',function ',key
:help ,doc :enable ',enable-expr)))
(add-to-list mbuttons name)
(if docs (add-to-list docs doc))))))
@@ -209,145 +201,69 @@ where,
(unless (memq x letter-buttons)
(error "Letter defaults contains unknown button %s" x)))
`(eval-and-compile
- ;; GNU Emacs tool bar specific code
- (mh-do-in-gnu-emacs
- (defun mh-buffer-exists-p (mode)
- "Test whether a buffer with major mode MODE is present."
- (cl-loop for buf in (buffer-list)
- when (with-current-buffer buf
- (eq major-mode mode))
- return t))
- ;; Tool bar initialization functions
- (defun mh-tool-bar-folder-buttons-init ()
- (when (mh-buffer-exists-p 'mh-folder-mode)
- (let* ((load-path (mh-image-load-path-for-library "mh-e"
- "mh-logo.xpm"))
- (image-load-path (cons (car load-path)
- (when (boundp 'image-load-path)
- image-load-path))))
- (setq mh-folder-tool-bar-map
- (let ((tool-bar-map (make-sparse-keymap)))
- ,@(nreverse folder-button-setter)
- tool-bar-map))
- (setq mh-folder-seq-tool-bar-map
- (let ((tool-bar-map (copy-keymap mh-folder-tool-bar-map)))
- ,@(nreverse sequence-button-setter)
- tool-bar-map))
- (setq mh-show-tool-bar-map
- (let ((tool-bar-map (make-sparse-keymap)))
- ,@(nreverse show-button-setter)
- tool-bar-map))
- (setq mh-show-seq-tool-bar-map
- (let ((tool-bar-map (copy-keymap mh-show-tool-bar-map)))
- ,@(nreverse show-seq-button-setter)
- tool-bar-map)))))
- (defun mh-tool-bar-letter-buttons-init ()
- (when (mh-buffer-exists-p 'mh-letter-mode)
- (let* ((load-path (mh-image-load-path-for-library "mh-e"
- "mh-logo.xpm"))
- (image-load-path (cons (car load-path)
- (when (boundp 'image-load-path)
- image-load-path))))
- (setq mh-letter-tool-bar-map
- (let ((tool-bar-map (make-sparse-keymap)))
- ,@(nreverse letter-button-setter)
- tool-bar-map)))))
- ;; Custom setter functions
- (defun mh-tool-bar-update (mode default-map sequence-map)
- "Update `tool-bar-map' in all buffers of MODE.
+ (defun mh-buffer-exists-p (mode)
+ "Test whether a buffer with major mode MODE is present."
+ (cl-loop for buf in (buffer-list)
+ when (with-current-buffer buf
+ (eq major-mode mode))
+ return t))
+ ;; Tool bar initialization functions
+ (defun mh-tool-bar-folder-buttons-init ()
+ (when (mh-buffer-exists-p 'mh-folder-mode)
+ (mh--with-image-load-path
+ (setq mh-folder-tool-bar-map
+ (let ((tool-bar-map (make-sparse-keymap)))
+ ,@(nreverse folder-button-setter)
+ tool-bar-map))
+ (setq mh-folder-seq-tool-bar-map
+ (let ((tool-bar-map (copy-keymap mh-folder-tool-bar-map)))
+ ,@(nreverse sequence-button-setter)
+ tool-bar-map))
+ (setq mh-show-tool-bar-map
+ (let ((tool-bar-map (make-sparse-keymap)))
+ ,@(nreverse show-button-setter)
+ tool-bar-map))
+ (setq mh-show-seq-tool-bar-map
+ (let ((tool-bar-map (copy-keymap mh-show-tool-bar-map)))
+ ,@(nreverse show-seq-button-setter)
+ tool-bar-map)))))
+ (defun mh-tool-bar-letter-buttons-init ()
+ (when (mh-buffer-exists-p 'mh-letter-mode)
+ (mh--with-image-load-path
+ (setq mh-letter-tool-bar-map
+ (let ((tool-bar-map (make-sparse-keymap)))
+ ,@(nreverse letter-button-setter)
+ tool-bar-map)))))
+ ;; Custom setter functions
+ (defun mh-tool-bar-update (mode default-map sequence-map)
+ "Update `tool-bar-map' in all buffers of MODE.
Use SEQUENCE-MAP if display is limited; DEFAULT-MAP otherwise."
- (cl-loop for buf in (buffer-list)
- do (with-current-buffer buf
- (when (eq mode major-mode) ;FIXME: derived-mode-p?
- (let ((map (if mh-folder-view-stack
- sequence-map
- default-map)))
- ;; Yes, make-local-variable is necessary since we
- ;; get here during initialization when loading
- ;; mh-e.el, after the +inbox buffer has been
- ;; created, but before mh-folder-mode has run and
- ;; created the local map.
- (set (make-local-variable 'tool-bar-map) map))))))
- (defun mh-tool-bar-folder-buttons-set (symbol value)
- "Construct tool bar for `mh-folder-mode' and `mh-show-mode'."
- (set-default symbol value)
- (mh-tool-bar-folder-buttons-init)
- (mh-tool-bar-update 'mh-folder-mode mh-folder-tool-bar-map
- mh-folder-seq-tool-bar-map)
- (mh-tool-bar-update 'mh-show-mode mh-show-tool-bar-map
- mh-show-seq-tool-bar-map))
- (defun mh-tool-bar-letter-buttons-set (symbol value)
- "Construct tool bar for `mh-letter-mode'."
- (set-default symbol value)
- (mh-tool-bar-letter-buttons-init)
- (mh-tool-bar-update 'mh-letter-mode mh-letter-tool-bar-map
- mh-letter-tool-bar-map)))
- ;; XEmacs specific code
- (mh-do-in-xemacs
- (defvar mh-tool-bar-folder-vector-map
- (list ,@(cl-loop for button in folder-buttons
- for vector in folder-vectors
- collect `(cons ',button ,vector))))
- (defvar mh-tool-bar-show-vector-map
- (list ,@(cl-loop for button in show-buttons
- for vector in show-vectors
- collect `(cons ',button ,vector))))
- (defvar mh-tool-bar-letter-vector-map
- (list ,@(cl-loop for button in letter-buttons
- for vector in letter-vectors
- collect `(cons ',button ,vector))))
- (defvar mh-tool-bar-folder-buttons)
- (defvar mh-tool-bar-show-buttons)
- (defvar mh-tool-bar-letter-buttons)
- ;; Custom setter functions
- (defun mh-tool-bar-letter-buttons-set (symbol value)
- (set-default symbol value)
- (when mh-xemacs-has-tool-bar-flag
- (setq mh-tool-bar-letter-buttons
- (cl-loop
- for b in value
- collect (cdr (assoc b mh-tool-bar-letter-vector-map))))))
- (defun mh-tool-bar-folder-buttons-set (symbol value)
- (set-default symbol value)
- (when mh-xemacs-has-tool-bar-flag
- (setq mh-tool-bar-folder-buttons
- (cl-loop
- for b in value
- collect (cdr (assoc b mh-tool-bar-folder-vector-map))))
- (setq mh-tool-bar-show-buttons
- (cl-loop
- for b in value
- collect (cdr (assoc b mh-tool-bar-show-vector-map))))))
- (defun mh-tool-bar-init (mode)
- "Install tool bar in MODE."
- (when mh-xemacs-use-tool-bar-flag
- (let ((tool-bar (cond ((eq mode :folder)
- mh-tool-bar-folder-buttons)
- ((eq mode :letter)
- mh-tool-bar-letter-buttons)
- ((eq mode :show)
- mh-tool-bar-show-buttons)))
- (height 37)
- (width 40)
- (buffer (current-buffer)))
- (cond
- ((eq mh-xemacs-tool-bar-position 'top)
- (set-specifier top-toolbar tool-bar buffer)
- (set-specifier top-toolbar-visible-p t)
- (set-specifier top-toolbar-height height))
- ((eq mh-xemacs-tool-bar-position 'bottom)
- (set-specifier bottom-toolbar tool-bar buffer)
- (set-specifier bottom-toolbar-visible-p t)
- (set-specifier bottom-toolbar-height height))
- ((eq mh-xemacs-tool-bar-position 'left)
- (set-specifier left-toolbar tool-bar buffer)
- (set-specifier left-toolbar-visible-p t)
- (set-specifier left-toolbar-width width))
- ((eq mh-xemacs-tool-bar-position 'right)
- (set-specifier right-toolbar tool-bar buffer)
- (set-specifier right-toolbar-visible-p t)
- (set-specifier right-toolbar-width width))
- (t (set-specifier default-toolbar tool-bar buffer)))))))
+ (cl-loop for buf in (buffer-list)
+ do (with-current-buffer buf
+ (when (eq mode major-mode) ;FIXME: derived-mode-p?
+ (let ((map (if mh-folder-view-stack
+ sequence-map
+ default-map)))
+ ;; Yes, make-local-variable is necessary since we
+ ;; get here during initialization when loading
+ ;; mh-e.el, after the +inbox buffer has been
+ ;; created, but before mh-folder-mode has run and
+ ;; created the local map.
+ (setq-local tool-bar-map map))))))
+ (defun mh-tool-bar-folder-buttons-set (symbol value)
+ "Construct tool bar for `mh-folder-mode' and `mh-show-mode'."
+ (set-default symbol value)
+ (mh-tool-bar-folder-buttons-init)
+ (mh-tool-bar-update 'mh-folder-mode mh-folder-tool-bar-map
+ mh-folder-seq-tool-bar-map)
+ (mh-tool-bar-update 'mh-show-mode mh-show-tool-bar-map
+ mh-show-seq-tool-bar-map))
+ (defun mh-tool-bar-letter-buttons-set (symbol value)
+ "Construct tool bar for `mh-letter-mode'."
+ (set-default symbol value)
+ (mh-tool-bar-letter-buttons-init)
+ (mh-tool-bar-update 'mh-letter-mode mh-letter-tool-bar-map
+ mh-letter-tool-bar-map))
;; Declare customizable tool bars
(custom-declare-variable
'mh-tool-bar-folder-buttons
@@ -372,7 +288,6 @@ Use SEQUENCE-MAP if display is limited; DEFAULT-MAP otherwise."
;;:package-version '(MH-E "7.1")
))))
-;; The icon names are duplicated in the Makefile and mh-xemacs.el.
(mh-tool-bar-define
((:folder mh-inc-folder mh-mime-save-parts
mh-previous-undeleted-msg mh-page-msg
diff --git a/lisp/mh-e/mh-utils.el b/lisp/mh-e/mh-utils.el
index bbce17013b1..b75025d6a4d 100644
--- a/lisp/mh-e/mh-utils.el
+++ b/lisp/mh-e/mh-utils.el
@@ -52,7 +52,7 @@ used in lieu of `search' in the CL package."
(let ((syntax-table (syntax-table)))
(unwind-protect
(save-excursion
- (mh-mail-abbrev-make-syntax-table)
+ (mail-abbrev-make-syntax-table)
(set-syntax-table mail-abbrev-syntax-table)
(backward-word n)
(point))
@@ -61,9 +61,9 @@ used in lieu of `search' in the CL package."
;;;###mh-autoload
(defun mh-colors-available-p ()
"Check if colors are available in the Emacs being used."
- (or (featurep 'xemacs)
- (let ((color-cells (mh-display-color-cells)))
- (and (numberp color-cells) (>= color-cells 8)))))
+ ;; FIXME: Can this be replaced with `display-color-p'?
+ (let ((color-cells (display-color-cells)))
+ (and (numberp color-cells) (>= color-cells 8))))
;;;###mh-autoload
(defun mh-colors-in-use-p ()
@@ -78,16 +78,13 @@ used in lieu of `search' in the CL package."
;;;###mh-autoload
(defun mh-make-local-vars (&rest pairs)
"Initialize local variables according to the variable-value PAIRS."
+ (declare (obsolete setq-local "29.1"))
(while pairs
(set (make-local-variable (car pairs)) (car (cdr pairs)))
(setq pairs (cdr (cdr pairs)))))
;;;###mh-autoload
-(defun mh-mapc (function list)
- "Apply FUNCTION to each element of LIST for side effects only."
- (while list
- (funcall function (car list))
- (setq list (cdr list))))
+(define-obsolete-function-alias 'mh-mapc #'mapc "29.1")
(defvar mh-pick-regexp-chars ".*$["
"List of special characters in pick regular expressions.")
@@ -102,7 +99,7 @@ PICK-EXPR is a list of strings. Return nil if PICK-EXPR is nil."
(not (string-equal string "")))
(cl-loop for i from 0 to (1- (length mh-pick-regexp-chars)) do
(let ((s (string ?\\ (aref mh-pick-regexp-chars i))))
- (setq string (mh-replace-regexp-in-string s s string t t))))
+ (setq string (replace-regexp-in-string s s string t t))))
(setq quoted-pick-expr (append quoted-pick-expr (list string)))))
quoted-pick-expr))
@@ -119,34 +116,32 @@ Ignores case when searching for OLD."
;;; Logo Display
-(defvar mh-logo-cache nil)
+;;;###mh-autoload
+(defmacro mh--with-image-load-path (&rest body)
+ "Load `image' and eval BODY with `image-load-path' set appropriately."
+ (declare (debug t) (indent 0))
+ `(progn
+ ;; Not preloaded in without-x builds.
+ (require 'image)
+ (defvar image-load-path)
+ (declare-function image-load-path-for-library "image")
+ (let* ((load-path (image-load-path-for-library "mh-e" "mh-logo.xpm"))
+ (image-load-path (cons (car load-path) image-load-path)))
+ ,@body)))
-;; Shush compiler.
-(defvar image-load-path)
+(defvar mh-logo-cache nil)
;;;###mh-autoload
(defun mh-logo-display ()
"Modify mode line to display MH-E logo."
- (mh-do-in-gnu-emacs
- (let* ((load-path (mh-image-load-path-for-library "mh-e" "mh-logo.xpm"))
- (image-load-path (cons (car load-path)
- (when (boundp 'image-load-path)
- image-load-path))))
- (add-text-properties
- 0 2
- `(display ,(or mh-logo-cache
- (setq mh-logo-cache
- (mh-funcall-if-exists
- find-image '((:type xpm :ascent center
- :file "mh-logo.xpm"))))))
- (car mode-line-buffer-identification))))
- (mh-do-in-xemacs
- (setq modeline-buffer-identification
- (list
- (if mh-modeline-glyph
- (cons modeline-buffer-id-left-extent mh-modeline-glyph)
- (cons modeline-buffer-id-left-extent "XEmacs%N:"))
- (cons modeline-buffer-id-right-extent " %17b")))))
+ (mh--with-image-load-path
+ (add-text-properties
+ 0 2
+ `(display ,(or mh-logo-cache
+ (setq mh-logo-cache
+ (find-image '(( :type xpm :ascent center
+ :file "mh-logo.xpm" ))))))
+ (car mode-line-buffer-identification))))
@@ -509,8 +504,8 @@ they will not be returned."
;; folder is specified, ensure it is nil to avoid adding the
;; folder to the folder-list and adding a slash to it.
(when folder
- (setq folder (mh-replace-regexp-in-string "^\\+" "" folder))
- (setq folder (mh-replace-regexp-in-string "/+$" "" folder))
+ (setq folder (replace-regexp-in-string "^\\+" "" folder))
+ (setq folder (replace-regexp-in-string "/+$" "" folder))
(if (equal folder "")
(setq folder nil)))
;; Add provided folder to list, unless all folders are asked for.
@@ -535,7 +530,12 @@ results of the actual folders call.
If optional argument ADD-TRAILING-SLASH-FLAG is non-nil then a
slash is added to each of the sub-folder names that may have
nested folders within them."
- (let* ((folder (mh-normalize-folder-name folder nil nil t))
+ ;; In most cases we want to remove a trailing slash. We keep the
+ ;; slash for "+/", because it refers to folders in the system root
+ ;; directory, whereas "+" refers to the user's top-level folders.
+ (let* ((folder (mh-normalize-folder-name folder nil
+ (string= folder "+/")
+ t))
(match (gethash folder mh-sub-folders-cache 'no-result))
(sub-folders (cond ((eq match 'no-result)
(setf (gethash folder mh-sub-folders-cache)
@@ -562,7 +562,6 @@ Expects FOLDER to have already been normalized with
(let ((arg-list `(,(expand-file-name "folders" mh-progs)
nil (t nil) nil "-noheader" "-norecurse" "-nototal"
,@(if (stringp folder) (list folder) ())))
- (results ())
(current-folder (concat
(with-temp-buffer
(call-process (expand-file-name "folder" mh-progs)
@@ -571,33 +570,48 @@ Expects FOLDER to have already been normalized with
"+")))
(with-temp-buffer
(apply #'call-process arg-list)
- (goto-char (point-min))
- (while (not (and (eolp) (bolp)))
- (goto-char (mh-line-end-position))
- (let ((start-pos (mh-line-beginning-position))
- (has-pos (search-backward " has "
- (mh-line-beginning-position) t)))
- (when (integerp has-pos)
- (while (equal (char-after has-pos) ? )
- (cl-decf has-pos))
- (cl-incf has-pos)
- (while (equal (char-after start-pos) ? )
- (cl-incf start-pos))
- (let* ((name (buffer-substring start-pos has-pos))
- (first-char (aref name 0))
- (last-char (aref name (1- (length name)))))
- (unless (member first-char '(?. ?# ?,))
- (when (and (equal last-char ?+) (equal name current-folder))
- (setq name (substring name 0 (1- (length name)))))
- (push
- (cons name
- (search-forward "(others)" (mh-line-end-position) t))
- results))))
- (forward-line 1))))
+ (mh-sub-folders-parse folder current-folder))))
+
+(defun mh-sub-folders-parse (folder current-folder)
+ "Parse the results of \"folders FOLDER\" and return a list of sub-folders.
+CURRENT-FOLDER is the result of \"folder -fast\".
+FOLDER will be nil or start with '+'; CURRENT-FOLDER will end with '+'.
+This function is a testable helper of `mh-sub-folders-actual'."
+ (let ((results ()))
+ (goto-char (point-min))
+ (while (not (and (eolp) (bolp)))
+ (goto-char (line-end-position))
+ (let ((start-pos (line-beginning-position))
+ (has-pos (search-backward " has "
+ (line-beginning-position) t)))
+ (when (integerp has-pos)
+ (while (equal (char-after has-pos) ? )
+ (cl-decf has-pos))
+ (cl-incf has-pos)
+ (while (equal (char-after start-pos) ? )
+ (cl-incf start-pos))
+ (let* ((name (buffer-substring start-pos has-pos))
+ (first-char (aref name 0))
+ (second-char (and (length> name 1) (aref name 1)))
+ (last-char (aref name (1- (length name)))))
+ (unless (member first-char '(?. ?# ?,))
+ (when (and (equal last-char ?+) (equal name current-folder))
+ (setq name (substring name 0 (1- (length name)))))
+ ;; nmh outputs double slash in root folder, e.g., "//tmp"
+ (when (and (equal first-char ?/) (equal second-char ?/))
+ (setq name (substring name 1)))
+ (push
+ (cons name
+ (search-forward "(others)" (line-end-position) t))
+ results))))
+ (forward-line 1)))
(setq results (nreverse results))
(when (stringp folder)
(setq results (cdr results))
(let ((folder-name-len (length (format "%s/" (substring folder 1)))))
+ (when (equal "+/" folder)
+ ;; folder "+/" includes a trailing slash
+ (cl-decf folder-name-len))
(setq results (mapcar (lambda (f)
(cons (substring (car f) folder-name-len)
(cdr f)))
@@ -727,16 +741,12 @@ See Info node `(elisp) Programmed Completion' for details."
((equal path mh-user-path) nil)
(t (file-directory-p path))))))))
-;; Shush compiler.
-(defvar completion-root-regexp) ;; Apparently used in XEmacs
-
(defun mh-folder-completing-read (prompt default allow-root-folder-flag)
"Read folder name with PROMPT and default result DEFAULT.
If ALLOW-ROOT-FOLDER-FLAG is non-nil then \"+\" is allowed to be
a folder name corresponding to `mh-user-path'."
(mh-normalize-folder-name
- (let ((completion-root-regexp "^[+/]") ;FIXME: Who/what uses that?
- (minibuffer-local-completion-map mh-folder-completion-map)
+ (let ((minibuffer-local-completion-map mh-folder-completion-map)
(mh-allow-root-folder-flag allow-root-folder-flag))
(completing-read prompt 'mh-folder-completion-function nil nil nil
'mh-folder-hist default))
@@ -920,11 +930,7 @@ Handle RFC 822 (or later) continuation lines."
(defvar mh-hidden-header-keymap
(let ((map (make-sparse-keymap)))
- (mh-do-in-gnu-emacs
- (define-key map [mouse-2] #'mh-letter-toggle-header-field-display-button))
- (mh-do-in-xemacs
- (define-key map '(button2)
- #'mh-letter-toggle-header-field-display-button))
+ (define-key map [mouse-2] #'mh-letter-toggle-header-field-display-button)
map))
;;;###mh-autoload
@@ -958,9 +964,9 @@ is hidden, if positive then the field is displayed."
(and (numberp arg)
(>= arg 0))
(and (eq arg 'long)
- (> (mh-line-beginning-position 5) end)))
+ (> (line-beginning-position 5) end)))
(remove-text-properties begin end '(invisible nil))
- (search-forward ":" (mh-line-end-position) t)
+ (search-forward ":" (line-end-position) t)
(mh-letter-skip-leading-whitespace-in-header-field))
;; XXX Redesign to make usable by user. Perhaps use a positive
;; numeric prefix to make that many lines visible.
diff --git a/lisp/mh-e/mh-xface.el b/lisp/mh-e/mh-xface.el
index d4d5c5c3784..8350f3d0fbb 100644
--- a/lisp/mh-e/mh-xface.el
+++ b/lisp/mh-e/mh-xface.el
@@ -27,19 +27,14 @@
(require 'mh-e)
+(autoload 'mail-header-parse-address "mail-parse")
(autoload 'message-fetch-field "message")
-(defvar mh-show-xface-function
- (cond ((and (featurep 'xemacs) (locate-library "x-face") (not (featurep 'xface)))
- (load "x-face" t t)
- #'mh-face-display-function)
- ((>= emacs-major-version 21)
- #'mh-face-display-function)
- (t #'ignore))
+(defvar mh-show-xface-function #'mh-face-display-function
"Determine at run time what function should be called to display X-Face.")
+(make-obsolete-variable 'mh-show-xface-function nil "29.1")
-(defvar mh-uncompface-executable
- (and (fboundp 'executable-find) (executable-find "uncompface")))
+(defvar mh-uncompface-executable (executable-find "uncompface"))
@@ -51,7 +46,7 @@
(when (and window-system mh-show-use-xface-flag
(or mh-decode-mime-flag mh-mhl-format-file
mh-clean-message-header-flag))
- (funcall mh-show-xface-function)))
+ (mh-face-display-function)))
(defun mh-face-display-function ()
"Display a Face, X-Face, or X-Image-URL header field.
@@ -76,53 +71,20 @@ in this order is used."
(when type
(goto-char (point-min))
(when (re-search-forward "^from:" (point-max) t)
- ;; GNU Emacs
- (mh-do-in-gnu-emacs
- (if (eq type 'url)
- (mh-x-image-url-display url)
- (mh-funcall-if-exists
- insert-image (create-image
- raw type t
- :foreground
- (mh-face-foreground 'mh-show-xface nil t)
- :background
- (mh-face-background 'mh-show-xface nil t))
- " ")))
- ;; XEmacs
- (mh-do-in-xemacs
- (cond
- ((eq type 'url)
- (mh-x-image-url-display url))
- ((eq type 'png)
- (when (featurep 'png)
- (set-extent-begin-glyph
- (make-extent (point) (point))
- (make-glyph (vector 'png ':data (mh-face-to-png face))))))
- ;; Try internal xface support if available...
- ((and (eq type 'pbm) (featurep 'xface))
- (set-glyph-face
- (set-extent-begin-glyph
- (make-extent (point) (point))
- (make-glyph (vector 'xface ':data (concat "X-Face: " x-face))))
- 'mh-show-xface))
- ;; Otherwise try external support with x-face...
- ((and (eq type 'pbm)
- (fboundp 'x-face-xmas-wl-display-x-face)
- (fboundp 'executable-find) (executable-find "uncompface"))
- (mh-funcall-if-exists x-face-xmas-wl-display-x-face))
- ;; Picon display
- ((and raw (member type '(xpm xbm gif)))
- (when (featurep type)
- (set-extent-begin-glyph
- (make-extent (point) (point))
- (make-glyph (vector type ':data raw))))))
- (when raw (insert " "))))))))
+ (if (eq type 'url)
+ (mh-x-image-url-display url)
+ (insert-image (create-image
+ raw type t
+ :foreground
+ (face-foreground 'mh-show-xface nil t)
+ :background
+ (face-background 'mh-show-xface nil t))
+ " ")))))))
(defun mh-face-to-png (data)
"Convert base64 encoded DATA to png image."
(with-temp-buffer
- (if (fboundp 'set-buffer-multibyte)
- (set-buffer-multibyte nil))
+ (set-buffer-multibyte nil)
(insert data)
(ignore-errors (base64-decode-region (point-min) (point-max)))
(buffer-string)))
@@ -130,8 +92,7 @@ in this order is used."
(defun mh-uncompface (data)
"Run DATA through `uncompface' to generate bitmap."
(with-temp-buffer
- (if (fboundp 'set-buffer-multibyte)
- (set-buffer-multibyte nil))
+ (set-buffer-multibyte nil)
(insert data)
(when (and mh-uncompface-executable
(equal (call-process-region (point-min) (point-max)
@@ -175,10 +136,8 @@ The directories are searched for in the order they appear in the list.")
(defvar mh-picon-image-types
(cl-loop for type in '(xpm xbm gif)
- when (or (mh-do-in-gnu-emacs
- (ignore-errors
- (mh-funcall-if-exists image-type-available-p type)))
- (mh-do-in-xemacs (featurep type)))
+ when (ignore-errors
+ (image-type-available-p type))
collect type))
(autoload 'message-tokenize-header "sendmail")
@@ -190,11 +149,7 @@ The directories are searched for in the order they appear in the list.")
(let* ((from-field (ignore-errors (car (message-tokenize-header
(mh-get-header-field "from:")))))
(from (car (ignore-errors
- ;; Don't use mh-funcall-if-exists because
- ;; ietf-drums-parse-address might exist at run-time but
- ;; not at compile-time.
- (when (fboundp 'ietf-drums-parse-address)
- (ietf-drums-parse-address from-field)))))
+ (mail-header-parse-address from-field))))
(host (and from
(string-match "\\([^+]*\\)\\(\\+.*\\)?@\\(.*\\)" from)
(downcase (match-string 3 from))))
@@ -273,8 +228,7 @@ file contents as a string is returned. If FILE is nil, then both
elements of the list are nil."
(if (stringp file)
(with-temp-buffer
- (if (fboundp 'set-buffer-multibyte)
- (set-buffer-multibyte nil))
+ (set-buffer-multibyte nil)
(let ((type (and (string-match ".*\\.\\(...\\)$" file)
(intern (match-string 1 file)))))
(insert-file-contents-literally file)
@@ -324,7 +278,7 @@ If the URL isn't present in the cache then it is fetched with wget."
(let* ((cache-filename (mh-x-image-url-cache-canonicalize url))
(state (mh-x-image-get-download-state cache-filename))
(marker (point-marker)))
- (set (make-local-variable 'mh-x-image-marker) marker)
+ (setq-local mh-x-image-marker marker)
(cond ((not (mh-x-image-url-sane-p url)))
((eq state 'ok)
(mh-x-image-display cache-filename marker))
@@ -360,14 +314,14 @@ This is only done if `mh-x-image-cache-directory' is nil."
(defun mh-x-image-url-cache-canonicalize (url)
"Canonicalize URL.
Replace the ?/ character with a ?! character and append .png.
-Also replaces special characters with `mh-url-hexify-string'
+Also replaces special characters with `url-hexify-string'
since not all characters, such as :, are valid within Windows
filenames. In addition, replaces * with %2a. See URL
`https://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/ifaces/iitemnamelimits/GetValidCharacters.asp'."
(format "%s/%s.png" mh-x-image-cache-directory
- (mh-replace-regexp-in-string
+ (replace-regexp-in-string
"\\*" "%2a"
- (mh-url-hexify-string
+ (url-hexify-string
(with-temp-buffer
(insert url)
(mh-replace-string "/" "!")
@@ -391,10 +345,12 @@ filenames. In addition, replaces * with %2a. See URL
(defun mh-x-image-url-sane-p (url)
"Check if URL is something sensible."
(let ((len (length url)))
- (cond ((< len 5) nil)
- ((not (equal (substring url 0 5) "http:")) nil)
- ((> len 100) nil)
- (t t))))
+ (cond ((> len 100) nil)
+ ((and (>= len 5)
+ (equal (substring url 0 5) "http:") t))
+ ((and (>= len 6)
+ (equal (substring url 0 6) "https:") t))
+ (t nil))))
(defun mh-x-image-display (image marker)
"Display IMAGE at MARKER."
@@ -405,16 +361,7 @@ filenames. In addition, replaces * with %2a. See URL
(when (and (file-readable-p image) (not (file-symlink-p image))
(eq marker mh-x-image-marker))
(goto-char marker)
- (mh-do-in-gnu-emacs
- (mh-funcall-if-exists insert-image (create-image image 'png)))
- (mh-do-in-xemacs
- (when (featurep 'png)
- (set-extent-begin-glyph
- (make-extent (point) (point))
- (make-glyph
- (vector 'png ':data (with-temp-buffer
- (insert-file-contents-literally image)
- (buffer-string))))))))
+ (insert-image (create-image image 'png)))
(set-buffer-modified-p buffer-modified-flag)))))
(defun mh-x-image-url-fetch-image (url cache-file marker sentinel)
@@ -424,12 +371,11 @@ be displayed in a buffer and position specified by MARKER. The
actual display is carried out by the SENTINEL function."
(if mh-wget-executable
(let ((buffer (generate-new-buffer mh-temp-fetch-buffer))
- (filename (or (mh-funcall-if-exists make-temp-file "mhe-fetch")
- (expand-file-name (make-temp-name "~/mhe-fetch")))))
+ (filename (make-temp-file "mhe-fetch")))
(with-current-buffer buffer
- (set (make-local-variable 'mh-x-image-url-cache-file) cache-file)
- (set (make-local-variable 'mh-x-image-marker) marker)
- (set (make-local-variable 'mh-x-image-temp-file) filename))
+ (setq-local mh-x-image-url-cache-file cache-file)
+ (setq-local mh-x-image-marker marker)
+ (setq-local mh-x-image-temp-file filename))
(set-process-sentinel
(start-process "*mh-x-image-url-fetch*" buffer
mh-wget-executable mh-wget-option filename url)
diff --git a/lisp/midnight.el b/lisp/midnight.el
index 8b798926c1c..51173e7429f 100644
--- a/lisp/midnight.el
+++ b/lisp/midnight.el
@@ -26,7 +26,7 @@
;; To use the file, put (require 'midnight) into your .emacs. Then, at
;; midnight, Emacs will run the normal hook `midnight-hook'. You can
;; put whatever you like there, say, `calendar'; by default there is
-;; only one function there - `clean-buffer-list'. It will kill the
+;; only one function there - `clean-buffer-list'. It will kill the
;; buffers matching `clean-buffer-list-kill-buffer-names' and
;; `clean-buffer-list-kill-regexps' and the buffers which where last
;; displayed more than `clean-buffer-list-delay-general' days ago,
@@ -159,7 +159,7 @@ the current date/time, buffer name, how many seconds ago it was
displayed (can be nil if the buffer was never displayed) and its
lifetime, i.e., its \"age\" when it will be purged."
(interactive)
- (let ((tm (current-time)) bts (ts (format-time-string "%Y-%m-%d %T"))
+ (let* ((tm (current-time)) bts (ts (format-time-string "%Y-%m-%d %T" tm))
delay cbld bn)
(dolist (buf (buffer-list))
(when (buffer-live-p buf)
diff --git a/lisp/minibuf-eldef.el b/lisp/minibuf-eldef.el
index 30273fab1b8..f67ec353c88 100644
--- a/lisp/minibuf-eldef.el
+++ b/lisp/minibuf-eldef.el
@@ -160,7 +160,7 @@ The prompt and initial input should already have been inserted."
;; post-command-hook to swap prompts when necessary
(defun minibuf-eldef-update-minibuffer ()
"Update a minibuffer's prompt to include a default only when applicable.
-This is intended to be used as a minibuffer post-command-hook for
+This is intended to be used as a minibuffer `post-command-hook' for
`minibuffer-electric-default-mode'; the minibuffer should have already
been set up by `minibuf-eldef-setup-minibuffer'."
(unless (eq minibuf-eldef-showing-default-in-prompt
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index ffcd5d88abe..28bd1df59ab 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -1,4 +1,4 @@
-;;; minibuffer.el --- Minibuffer completion functions -*- lexical-binding: t -*-
+;;; minibuffer.el --- Minibuffer and completion functions -*- lexical-binding: t -*-
;; Copyright (C) 2008-2021 Free Software Foundation, Inc.
@@ -283,8 +283,9 @@ the form (concat S2 S)."
((eq (car-safe action) 'boundaries)
(let ((beg (or (and (eq (car-safe res) 'boundaries) (cadr res)) 0)))
`(boundaries
- ,(max (length s1)
- (+ beg (- (length s1) (length s2))))
+ ,(min (length string)
+ (max (length s1)
+ (+ beg (- (length s1) (length s2)))))
. ,(and (eq (car-safe res) 'boundaries) (cddr res)))))
((stringp res)
(if (string-prefix-p s2 res completion-ignore-case)
@@ -848,7 +849,7 @@ via `set-message-function'."
(run-with-timer minibuffer-message-clear-timeout nil
#'clear-minibuffer-message)))
- ;; Return `t' telling the caller that the message
+ ;; Return t telling the caller that the message
;; was handled specially by this function.
t))))
@@ -943,7 +944,12 @@ When completing \"foo\" the glob \"*f*o*o*\" is used, so that
completion-initials-try-completion completion-initials-all-completions
"Completion of acronyms and initialisms.
E.g. can complete M-x lch to list-command-history
-and C-x C-f ~/sew to ~/src/emacs/work."))
+and C-x C-f ~/sew to ~/src/emacs/work.")
+ (shorthand
+ completion-shorthand-try-completion completion-shorthand-all-completions
+ "Completion of symbol shorthands setup in `read-symbol-shorthands'.
+E.g. can complete \"x-foo\" to \"xavier-foo\" if the shorthand
+((\"x-\" . \"xavier-\")) is set up in the buffer of origin."))
"List of available completion styles.
Each element has the form (NAME TRY-COMPLETION ALL-COMPLETIONS DOC):
where NAME is the name that should be used in `completion-styles',
@@ -990,7 +996,8 @@ styles for specific categories, such as files, buffers, etc."
;; e.g. one that does not anchor to bos.
(project-file (styles . (substring)))
(xref-location (styles . (substring)))
- (info-menu (styles . (basic substring))))
+ (info-menu (styles . (basic substring)))
+ (symbol-help (styles . (basic shorthand substring))))
"Default settings for specific completion categories.
Each entry has the shape (CATEGORY . ALIST) where ALIST is
an association list that can specify properties such as:
@@ -1496,7 +1503,8 @@ Remove completion BASE prefix string from history elements."
base-size md
minibuffer-completion-table
minibuffer-completion-predicate))
- (sort-fun (completion-metadata-get all-md 'cycle-sort-function)))
+ (sort-fun (completion-metadata-get all-md 'cycle-sort-function))
+ (group-fun (completion-metadata-get all-md 'group-function)))
(when last
(setcdr last nil)
@@ -1506,17 +1514,25 @@ Remove completion BASE prefix string from history elements."
(setq all (delete-dups all))
(setq last (last all))
- (if sort-fun
- (setq all (funcall sort-fun all))
- ;; Sort first by length and alphabetically.
+ (cond
+ (sort-fun (setq all (funcall sort-fun all)))
+ ((and completions-group group-fun)
+ ;; TODO: experiment with re-grouping here. Might be slow
+ ;; if the group-fun (given by the table and out of our
+ ;; control) is slow and/or allocates too much.
+ )
+ (t
+ ;; If the table doesn't stipulate a sorting function or a
+ ;; group function, sort first by length and
+ ;; alphabetically.
(setq all (minibuffer--sort-by-length-alpha all))
- ;; Sort by history position, put the default, if it
+ ;; Then sort by history position, and put the default, if it
;; exists, on top.
(when (minibufferp)
(setq all (minibuffer--sort-by-position
(minibuffer--sort-preprocess-history
(substring string 0 base-size))
- all))))
+ all)))))
;; Cache the result. This is not just for speed, but also so that
;; repeated calls to minibuffer-force-complete can cycle through
@@ -1609,6 +1625,9 @@ DONT-CYCLE tells the function not to setup cycling."
(defvar minibuffer--require-match nil
"Value of REQUIRE-MATCH passed to `completing-read'.")
+(defvar minibuffer--original-buffer nil
+ "Buffer that was current when `completing-read' was called.")
+
(defun minibuffer-complete-and-exit ()
"Exit if the minibuffer contains a valid completion.
Otherwise, try to complete the minibuffer contents. If
@@ -1798,7 +1817,9 @@ Return nil if there is no valid completion, else t."
(_ t)))
(defface completions-annotations '((t :inherit (italic shadow)))
- "Face to use for annotations in the *Completions* buffer.")
+ "Face to use for annotations in the *Completions* buffer.
+This face is only used if the strings used for completions
+doesn't already specify a face.")
(defcustom completions-format 'horizontal
"Define the appearance and sorting of completions.
@@ -1813,8 +1834,9 @@ in one column."
(defcustom completions-detailed nil
"When non-nil, display completions with details added as prefix/suffix.
-Some commands might provide a detailed view with more information prepended
-or appended to completions."
+This makes some commands (for instance, \\[describe-symbol]) provide a
+detailed view with more information prepended or appended to
+completions."
:type 'boolean
:version "28.1")
@@ -2338,14 +2360,18 @@ that displays the \"*Completions*\" buffer."
(add-hook 'minibuffer-exit-hook 'minibuffer-restore-windows)
-(defun minibuffer-quit-recursive-edit ()
- "Quit the command that requested this recursive edit without error.
-Like `abort-recursive-edit' without aborting keyboard macro
-execution."
- ;; See Info node `(elisp)Recursive Editing' for an explanation of
- ;; throwing a function to `exit'.
- (throw 'exit (lambda ()
- (signal 'minibuffer-quit nil))))
+(defun minibuffer-quit-recursive-edit (&optional levels)
+ "Quit the command that requested this recursive edit or minibuffer input.
+Do so without terminating keyboard macro recording or execution.
+LEVELS specifies the number of nested recursive edits to quit.
+If nil, it defaults to 1."
+ (unless levels
+ (setq levels 1))
+ (if (> levels 1)
+ ;; See Info node `(elisp)Recursive Editing' for an explanation
+ ;; of throwing a function to `exit'.
+ (throw 'exit (lambda () (minibuffer-quit-recursive-edit (1- levels))))
+ (throw 'exit (lambda () (signal 'minibuffer-quit nil)))))
(defun self-insert-and-exit ()
"Terminate minibuffer input."
@@ -2674,12 +2700,12 @@ Such values are treated as in `read-from-minibuffer', but are normally
not useful in this function.)
Third arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits
-the current input method and the setting of`enable-multibyte-characters'.
+the current input method and the setting of `enable-multibyte-characters'.
If `inhibit-interaction' is non-nil, this function will signal an
`inhibited-interaction' error."
(read-from-minibuffer prompt initial minibuffer-local-ns-map
- nil minibuffer-history nil inherit-input-method))
+ nil 'minibuffer-history nil inherit-input-method))
;;; Major modes for the minibuffer
@@ -2709,7 +2735,7 @@ not active.")
This is only used when the minibuffer area has no active minibuffer.
Note that the minibuffer may change to this mode more often than
-you might expect. For instance, typing `M-x' may change the
+you might expect. For instance, typing \\`M-x' may change the
buffer to this mode, then to a different mode, and then back
again to this mode upon exit. Code running from
`minibuffer-inactive-mode-hook' has to be prepared to run
@@ -3189,7 +3215,6 @@ See `read-file-name' for the meaning of the arguments."
(unless val (error "No file name specified"))
(if (and default-filename
- (not (file-remote-p dir))
(string-equal val (if (consp insdef) (car insdef) insdef)))
(setq val default-filename))
(setq val (substitute-in-file-name val))
@@ -3520,7 +3545,8 @@ string in COMPLETIONS. Return a deep copy of COMPLETIONS where
each string is propertized with `completion-score', a number
between 0 and 1, and with faces `completions-common-part',
`completions-first-difference' in the relevant segments."
- (when completions
+ (cond
+ ((and completions (cl-loop for e in pattern thereis (stringp e)))
(let* ((re (completion-pcm--pattern->regex pattern 'group))
(point-idx (completion-pcm--pattern-point-idx pattern))
(case-fold-search completion-ignore-case)
@@ -3554,12 +3580,13 @@ between 0 and 1, and with faces `completions-common-part',
;; "hole" in the middle of the string is indicated by
;; "-". Note that there are no "holes" near the edges
;; of the string. The completion score is a number
- ;; bound by ]0..1]: the higher the better and only a
- ;; perfect match (pattern equals string) will have
- ;; score 1. The formula takes the form of a quotient.
- ;; For the numerator, we use the number of +, i.e. the
- ;; length of the pattern. For the denominator, it
- ;; first computes
+ ;; bound by (0..1] (i.e., larger than (but not equal
+ ;; to) zero, and smaller or equal to one): the higher
+ ;; the better and only a perfect match (pattern equals
+ ;; string) will have score 1. The formula takes the
+ ;; form of a quotient. For the numerator, we use the
+ ;; number of +, i.e. the length of the pattern. For
+ ;; the denominator, it first computes
;;
;; hole_i_contrib = 1 + (Li-1)^(1/tightness)
;;
@@ -3611,7 +3638,8 @@ between 0 and 1, and with faces `completions-common-part',
0 1 'completion-score
(/ score-numerator (* end (1+ score-denominator)) 1.0) str)))
str)
- completions))))
+ completions)))
+ (t completions)))
(defun completion-pcm--find-all-completions (string table pred point
&optional filter)
@@ -4062,6 +4090,40 @@ which is at the core of flex logic. The extra
(let ((newstr (completion-initials-expand string table pred)))
(when newstr
(completion-pcm-try-completion newstr table pred (length newstr)))))
+
+;; Shorthand completion
+;;
+;; Iff there is a (("x-" . "string-library-")) shorthand setup and
+;; string-library-foo is in candidates, complete x-foo to it.
+
+(defun completion-shorthand-try-completion (string table pred point)
+ "Try completion with `read-symbol-shorthands' of original buffer."
+ (cl-loop with expanded
+ for (short . long) in
+ (with-current-buffer minibuffer--original-buffer
+ read-symbol-shorthands)
+ for probe =
+ (and (> point (length short))
+ (string-prefix-p short string)
+ (try-completion (setq expanded
+ (concat long
+ (substring
+ string
+ (length short))))
+ table pred))
+ when probe
+ do (message "Shorthand expansion")
+ and return (cons expanded (max (length long)
+ (+ (- point (length short))
+ (length long))))))
+
+(defun completion-shorthand-all-completions (_string _table _pred _point)
+ ;; no-op: For now, we don't want shorthands to list all the possible
+ ;; locally active longhands. For the completion categories where
+ ;; this style is active, it could hide other more interesting
+ ;; matches from subsequent styles.
+ nil)
+
(defvar completing-read-function #'completing-read-default
"The function called by `completing-read' to do its work.
@@ -4093,6 +4155,7 @@ See `completing-read' for the meaning of the arguments."
;; in minibuffer-local-filename-completion-map can
;; override bindings in base-keymap.
base-keymap)))
+ (buffer (current-buffer))
(result
(minibuffer-with-setup-hook
(lambda ()
@@ -4101,7 +4164,8 @@ See `completing-read' for the meaning of the arguments."
;; FIXME: Remove/rename this var, see the next one.
(setq-local minibuffer-completion-confirm
(unless (eq require-match t) require-match))
- (setq-local minibuffer--require-match require-match))
+ (setq-local minibuffer--require-match require-match)
+ (setq-local minibuffer--original-buffer buffer))
(read-from-minibuffer prompt initial-input keymap
nil hist def inherit-input-method))))
(when (and (equal result "") def)
diff --git a/lisp/mouse-copy.el b/lisp/mouse-copy.el
index 14fbb51b27e..38c85064f3b 100644
--- a/lisp/mouse-copy.el
+++ b/lisp/mouse-copy.el
@@ -75,7 +75,7 @@
;; <http://www.zip.com.au/~cs/app/wily/auug.html>. I'd like
;; to incorporate some of these ideas into mouse-copy. The only
;; lose is that this is not the current Emacs Way Of Doing Things, so
-;; there would be a learning curve for existing emacs users.
+;; there would be a learning curve for existing Emacs users.
;;
;;
;; Thanks:
@@ -110,7 +110,7 @@ The problem occurs under XFree86-3.1.1 (X11R6pl11) but not under X11R5,
and under post-19.29 but not early versions of Emacs.
19.29 and 19.30 seems to drop mouse drag events
-sometimes. (Reproducible under XFree86-3.1.1 (X11R6pl11) and
+sometimes. (Reproducible under XFree86-3.1.1 (X11R6pl11) and
XFree86-3.1.2 under Linux 1.2.x. Doesn't occur under X11R5 and SunOS
4.1.1.)
diff --git a/lisp/mouse-drag.el b/lisp/mouse-drag.el
index b424b6edfe8..0cdba6b4d01 100644
--- a/lisp/mouse-drag.el
+++ b/lisp/mouse-drag.el
@@ -147,7 +147,7 @@ Keep the cursor on the screen as needed."
(= (cdr start-col-row) (cdr end-col-row)))))
(defvar mouse-drag-electric-col-scrolling t
- "If non-nil, mouse-drag on a long line enables truncate-lines.")
+ "If non-nil, mouse-drag on a long line enables `truncate-lines'.")
(defun mouse-drag-should-do-col-scrolling ()
"Determine if it's wise to enable col-scrolling for the current window.
@@ -282,6 +282,8 @@ To test this function, evaluate:
(setq window-last-row (- (window-height) 2)
window-last-col (- (window-width) 2))
(track-mouse
+ ;; Set 'track-mouse' to something neither nil nor t (Bug#51794).
+ (setq track-mouse 'drag-dragging)
(while (progn
(setq event (read--potential-mouse-event)
end (event-end event)
diff --git a/lisp/mouse.el b/lisp/mouse.el
index d2a5200d8de..11fdd3f6391 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -46,7 +46,7 @@
:type 'boolean)
(defcustom mouse-drag-copy-region nil
- "If non-nil, copy to kill-ring upon mouse adjustments of the region.
+ "If non-nil, copy to kill ring upon mouse adjustments of the region.
This affects `mouse-save-then-kill' (\\[mouse-save-then-kill]) in
addition to mouse drags.
@@ -184,8 +184,8 @@ items `Turn Off' and `Help'."
"-" " " (format "%S" minor-mode))))
(turn-off menu-item "Turn off minor mode" ,mm-fun)
(help menu-item "Help for minor mode"
- (lambda () (interactive)
- (describe-function ',mm-fun)))))))
+ ,(lambda () (interactive)
+ (describe-function mm-fun)))))))
(if menu
(popup-menu menu)
(message "No menu available")))))
@@ -271,7 +271,7 @@ not it is actually displayed."
;; FIXME: We have a problem here: we have to use the global/local/minor
;; so they're displayed in the expected order, but later on in the command
;; loop, they're actually looked up in the opposite order.
- (apply 'append
+ (apply #'append
global-menu
local-menu
minor-mode-menus)))
@@ -281,17 +281,21 @@ not it is actually displayed."
(defcustom context-menu-functions '(context-menu-undo
context-menu-region
+ context-menu-middle-separator
context-menu-local
context-menu-minor)
"List of functions that produce the contents of the context menu.
-Each function receives the menu as its argument and should return
-the same menu with changes such as added new menu items."
+Each function receives the menu and the mouse click event as its arguments
+and should return the same menu with changes such as added new menu items."
:type '(repeat
(choice (function-item context-menu-undo)
(function-item context-menu-region)
+ (function-item context-menu-middle-separator)
+ (function-item context-menu-toolbar)
(function-item context-menu-global)
(function-item context-menu-local)
(function-item context-menu-minor)
+ (function-item context-menu-buffers)
(function-item context-menu-vc)
(function-item context-menu-ffap)
(function :tag "Custom function")))
@@ -302,30 +306,79 @@ the same menu with changes such as added new menu items."
:type '(choice (const nil) function)
:version "28.1")
-(defun context-menu-map ()
- "Return composite menu map."
- (let ((menu (make-sparse-keymap)))
- (run-hook-wrapped 'context-menu-functions
- (lambda (fun)
- (setq menu (funcall fun menu))
- nil))
+(defun context-menu-map (&optional click)
+ "Return menu map constructed for context near mouse CLICK.
+The menu is populated by calling functions from `context-menu-functions'.
+Each function receives the menu and the mouse click event
+and returns the same menu after adding own menu items to the composite menu.
+When there is a text property `context-menu-function' at CLICK,
+it overrides all functions from `context-menu-functions'.
+At the end, it's possible to modify the final menu by specifying
+the function `context-menu-filter-function'."
+ (let* ((menu (make-sparse-keymap (propertize "Context Menu" 'hide t)))
+ (click (or click last-input-event))
+ (fun (mouse-posn-property (event-start click)
+ 'context-menu-function)))
+
+ (if (functionp fun)
+ (setq menu (funcall fun menu click))
+ (run-hook-wrapped 'context-menu-functions
+ (lambda (fun)
+ (setq menu (funcall fun menu click))
+ nil)))
+
+ ;; Remove duplicate separators as well as ones at the beginning or
+ ;; end of the menu.
+ (let ((l menu) saw-first-item)
+ (while (and (consp l)
+ (consp (cdr l)))
+ ;; If the next item is a separator, remove it if 1) we haven't
+ ;; seen any other items yet, or 2) it's followed by either
+ ;; another separator or the end of the list.
+ (if (and (equal (cdr-safe (cadr l)) menu-bar-separator)
+ (or (not saw-first-item)
+ (null (caddr l))
+ (equal (cdr-safe (caddr l)) menu-bar-separator)))
+ (setcdr l (cddr l))
+ ;; The "first item" is any cons cell; this excludes the
+ ;; `keymap' symbol and the menu name.
+ (when (consp (cadr l)) (setq saw-first-item t))
+ (setq l (cdr l)))))
+
(when (functionp context-menu-filter-function)
- (setq menu (funcall context-menu-filter-function menu)))
+ (setq menu (funcall context-menu-filter-function menu click)))
menu))
-(defun context-menu-global (menu)
- "Global submenus."
+(defun context-menu-middle-separator (menu _click)
+ "Add separator to the middle of the context menu.
+Some context functions add menu items below the separator."
+ (define-key-after menu [middle-separator] menu-bar-separator)
+ menu)
+
+(defun context-menu-toolbar (menu _click)
+ "Populate MENU with submenus from the tool bar."
+ (run-hooks 'activate-menubar-hook 'menu-bar-update-hook)
+ (define-key-after menu [separator-toolbar] menu-bar-separator)
+ (map-keymap (lambda (key binding)
+ (when (consp binding)
+ (define-key-after menu (vector key)
+ (copy-sequence binding))))
+ (lookup-key global-map [tool-bar]))
+ menu)
+
+(defun context-menu-global (menu _click)
+ "Populate MENU with submenus from the global menu."
(run-hooks 'activate-menubar-hook 'menu-bar-update-hook)
(define-key-after menu [separator-global] menu-bar-separator)
(map-keymap (lambda (key binding)
(when (consp binding)
(define-key-after menu (vector key)
(copy-sequence binding))))
- (lookup-key global-map [menu-bar]))
+ (menu-bar-keymap (lookup-key global-map [menu-bar])))
menu)
-(defun context-menu-local (menu)
- "Major mode submenus."
+(defun context-menu-local (menu _click)
+ "Populate MENU with submenus provided by major mode."
(run-hooks 'activate-menubar-hook 'menu-bar-update-hook)
(define-key-after menu [separator-local] menu-bar-separator)
(let ((keymap (local-key-binding [menu-bar])))
@@ -334,11 +387,11 @@ the same menu with changes such as added new menu items."
(when (consp binding)
(define-key-after menu (vector key)
(copy-sequence binding))))
- keymap)))
+ (menu-bar-keymap keymap))))
menu)
-(defun context-menu-minor (menu)
- "Minor modes submenus."
+(defun context-menu-minor (menu _click)
+ "Populate MENU with submenus provided by minor modes."
(run-hooks 'activate-menubar-hook 'menu-bar-update-hook)
(define-key-after menu [separator-minor] menu-bar-separator)
(dolist (mode (reverse (minor-mode-key-binding [menu-bar])))
@@ -350,126 +403,190 @@ the same menu with changes such as added new menu items."
(cdr mode))))
menu)
-(defun context-menu-vc (menu)
- "Version Control menu."
+(defun context-menu-buffers (menu _click)
+ "Populate MENU with the buffer submenus to buffer switching."
+ (run-hooks 'activate-menubar-hook 'menu-bar-update-hook)
+ (define-key-after menu [separator-buffers] menu-bar-separator)
+ (map-keymap (lambda (key binding)
+ (when (consp binding)
+ (define-key-after menu (vector key)
+ (copy-sequence binding))))
+ (mouse-buffer-menu-keymap))
+ menu)
+
+(defun context-menu-vc (menu _click)
+ "Populate MENU with Version Control commands."
(define-key-after menu [separator-vc] menu-bar-separator)
(define-key-after menu [vc-menu] vc-menu-entry)
menu)
-(defun context-menu-undo (menu)
- "Undo menu."
- (when (cddr menu)
- (define-key-after menu [separator-undo] menu-bar-separator))
- (define-key-after menu [undo]
- '(menu-item "Undo" undo
- :visible (and (not buffer-read-only)
- (not (eq t buffer-undo-list))
- (if (eq last-command 'undo)
- (listp pending-undo-list)
- (consp buffer-undo-list)))
- :help "Undo last edits"))
- (define-key-after menu [undo-redo]
- '(menu-item "Redo" undo-redo
- :visible (and (not buffer-read-only)
- (undo--last-change-was-undo-p buffer-undo-list))
- :help "Redo last undone edits"))
+(defun context-menu-undo (menu _click)
+ "Populate MENU with undo commands."
+ (define-key-after menu [separator-undo] menu-bar-separator)
+ (when (and (not buffer-read-only)
+ (not (eq t buffer-undo-list))
+ (if (eq last-command 'undo)
+ (listp pending-undo-list)
+ (consp buffer-undo-list)))
+ (define-key-after menu [undo]
+ `(menu-item ,(if (region-active-p) "Undo in Region" "Undo") undo
+ :help "Undo last edits")))
+ (when (and (not buffer-read-only)
+ (undo--last-change-was-undo-p buffer-undo-list))
+ (define-key-after menu [undo-redo]
+ `(menu-item (if undo-in-region "Redo in Region" "Redo") undo-redo
+ :help "Redo last undone edits")))
menu)
-(defun context-menu-region (menu)
- "Region commands menu."
- (when (cddr menu)
- (define-key-after menu [separator-region] menu-bar-separator))
- (define-key-after menu [cut]
- '(menu-item "Cut" kill-region
- :visible (and mark-active (not buffer-read-only))
- :help
- "Cut (kill) text in region between mark and current position"))
- (define-key-after menu [copy]
- ;; ns-win.el said: Substitute a Copy function that works better
- ;; under X (for GNUstep).
- `(menu-item "Copy" ,(if (featurep 'ns)
- 'ns-copy-including-secondary
- 'kill-ring-save)
- :visible mark-active
- :help "Copy text in region between mark and current position"
- :keys ,(if (featurep 'ns)
- "\\[ns-copy-including-secondary]"
- "\\[kill-ring-save]")))
- (define-key-after menu [paste]
- `(menu-item "Paste" mouse-yank-primary
- :visible (funcall
- ',(lambda ()
- (and (or
- (gui-backend-selection-exists-p 'CLIPBOARD)
- (if (featurep 'ns) ; like paste-from-menu
- (cdr yank-menu)
- kill-ring))
- (not buffer-read-only))))
- :help "Paste (yank) text most recently cut/copied"))
- (define-key-after menu (if (featurep 'ns) [select-paste]
- [paste-from-menu])
- ;; ns-win.el said: Change text to be more consistent with
- ;; surrounding menu items `paste', etc."
- `(menu-item ,(if (featurep 'ns) "Select and Paste" "Paste from Kill Menu")
- yank-menu
- :visible (and (cdr yank-menu) (not buffer-read-only))
- :help "Choose a string from the kill ring and paste it"))
- (define-key-after menu [clear]
- '(menu-item "Clear" delete-active-region
- :visible (and mark-active
- (not buffer-read-only))
- :help
- "Delete the text in region between mark and current position"))
- (define-key-after menu [mark-whole-buffer]
- '(menu-item "Select All" mark-whole-buffer
- :help "Mark the whole buffer for a subsequent cut/copy"))
+(defun context-menu-region (menu click)
+ "Populate MENU with region commands."
+ (define-key-after menu [separator-region] menu-bar-separator)
+ (when (and mark-active (not buffer-read-only))
+ (define-key-after menu [cut]
+ '(menu-item "Cut" kill-region
+ :help
+ "Cut (kill) text in region between mark and current position")))
+ (when mark-active
+ (define-key-after menu [copy]
+ ;; ns-win.el said: Substitute a Copy function that works better
+ ;; under X (for GNUstep).
+ `(menu-item "Copy" ,(if (featurep 'ns)
+ 'ns-copy-including-secondary
+ 'kill-ring-save)
+ :help "Copy text in region between mark and current position"
+ :keys ,(if (featurep 'ns)
+ "\\[ns-copy-including-secondary]"
+ "\\[kill-ring-save]"))))
+ (when (and (or (gui-backend-selection-exists-p 'CLIPBOARD)
+ (if (featurep 'ns) ; like paste-from-menu
+ (cdr yank-menu)
+ kill-ring))
+ (not buffer-read-only))
+ (define-key-after menu [paste]
+ `(menu-item "Paste" mouse-yank-at-click
+ :help "Paste (yank) text most recently cut/copied")))
+ (when (and (cdr yank-menu) (not buffer-read-only))
+ (let ((submenu (make-sparse-keymap (propertize "Paste from Kill Menu")))
+ (i 0))
+ (dolist (item (reverse yank-menu))
+ (when (consp item)
+ (define-key submenu (vector (setq i (1+ i)))
+ `(menu-item ,(cadr item)
+ ,(lambda () (interactive)
+ (mouse-yank-from-menu click (car item)))))))
+ (define-key-after menu (if (featurep 'ns) [select-paste] [paste-from-menu])
+ `(menu-item ,(if (featurep 'ns) "Select and Paste" "Paste from Kill Menu")
+ ,submenu
+ :help "Choose a string from the kill ring and paste it"))))
+ (when (and mark-active (not buffer-read-only))
+ (define-key-after menu [clear]
+ '(menu-item "Clear" delete-active-region
+ :help
+ "Delete text in region between mark and current position")))
+
+ (let ((submenu (make-sparse-keymap (propertize "Select"))))
+ (define-key-after submenu [mark-whole-buffer]
+ `(menu-item "All"
+ ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'buffer))
+ :help "Mark the whole buffer for a subsequent cut/copy"))
+ (with-current-buffer (window-buffer (posn-window (event-end click)))
+ (when (let* ((pos (posn-point (event-end click)))
+ (char (when pos (char-after pos))))
+ (or (and char (eq (char-syntax char) ?\"))
+ (nth 3 (save-excursion (syntax-ppss pos)))))
+ (define-key-after submenu [mark-string]
+ `(menu-item "String"
+ ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'string))
+ :help "Mark the string at click for a subsequent cut/copy"))))
+ (define-key-after submenu [mark-line]
+ `(menu-item "Line"
+ ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'line))
+ :help "Mark the line at click for a subsequent cut/copy"))
+ (when (region-active-p)
+ (define-key-after submenu [mark-none]
+ `(menu-item "None"
+ ,(lambda (_e) (interactive "e") (deactivate-mark))
+ :help "Deactivate the region")))
+
+ (define-key-after menu [select-region]
+ `(menu-item "Select" ,submenu)))
menu)
-(defun context-menu-ffap (menu)
- "File at point menu."
+(defun context-menu-ffap (menu click)
+ "Populate MENU with commands that find file at point."
(save-excursion
- (mouse-set-point last-input-event)
+ (mouse-set-point click)
(when (ffap-guess-file-name-at-point)
(define-key menu [ffap-separator] menu-bar-separator)
(define-key menu [ffap-at-mouse]
'(menu-item "Find File or URL" ffap-at-mouse
- :help "Find file or URL guessed from text around mouse click"))))
+ :help "Find file or URL from text around mouse click"))))
menu)
(defvar context-menu-entry
- `(menu-item ,(purecopy "Context Menu") ignore
- :filter (lambda (_) (context-menu-map))))
-
-(defvar context-menu--old-down-mouse-3 nil)
-(defvar context-menu--old-mouse-3 nil)
+ `(menu-item ,(purecopy "Context Menu") ,(make-sparse-keymap)
+ :filter ,(lambda (_) (context-menu-map)))
+ "Menu item that creates the context menu and can be bound to a mouse key.")
+
+(defvar context-menu-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [mouse-3] nil)
+ (define-key map [down-mouse-3] context-menu-entry)
+ (define-key map [menu] #'context-menu-open)
+ (if (featurep 'w32)
+ (define-key map [apps] #'context-menu-open))
+ (when (featurep 'ns)
+ (define-key map [C-mouse-1] nil)
+ (define-key map [C-down-mouse-1] context-menu-entry))
+ map)
+ "Context Menu mode map.")
(define-minor-mode context-menu-mode
"Toggle Context Menu mode.
When Context Menu mode is enabled, clicking the mouse button down-mouse-3
activates the menu whose contents depends on its surrounding context."
- :global t :group 'mouse
- (cond
- (context-menu-mode
- (setq context-menu--old-mouse-3 (global-key-binding [mouse-3]))
- (global-unset-key [mouse-3])
- (setq context-menu--old-down-mouse-3 (global-key-binding [down-mouse-3]))
- (global-set-key [down-mouse-3] context-menu-entry))
- (t
- (if (not context-menu--old-down-mouse-3)
- (global-unset-key [down-mouse-3])
- (global-set-key [down-mouse-3] context-menu--old-down-mouse-3)
- (setq context-menu--old-down-mouse-3 nil))
- (when context-menu--old-mouse-3
- (global-set-key [mouse-3] context-menu--old-mouse-3)
- (setq context-menu--old-mouse-3 nil)))))
+ :global t)
+
+(defun context-menu-open ()
+ "Start key navigation of the context menu.
+This is the keyboard interface to \\[context-menu-map]."
+ (interactive)
+ (let ((inhibit-mouse-event-check t)
+ (map (context-menu-map)))
+ (if (commandp map)
+ (call-interactively map)
+ (popup-menu map (point)))))
+
+(global-set-key [S-f10] #'context-menu-open)
+
+(defun mark-thing-at-mouse (click thing)
+ "Activate the region around THING found near the mouse CLICK."
+ (let ((bounds (bounds-of-thing-at-mouse click thing)))
+ (when bounds
+ (goto-char (if mouse-select-region-move-to-beginning
+ (car bounds) (cdr bounds)))
+ (push-mark (if mouse-select-region-move-to-beginning
+ (cdr bounds) (car bounds))
+ t 'activate))))
+
+(defun mouse-yank-from-menu (click string)
+ "Insert STRING at mouse CLICK."
+ ;; Give temporary modes such as isearch a chance to turn off.
+ (run-hooks 'mouse-leave-buffer-hook)
+ (when select-active-regions
+ (deactivate-mark))
+ (or mouse-yank-at-point (mouse-set-point click))
+ (push-mark)
+ (insert string))
;; Commands that operate on windows.
(defun mouse-minibuffer-check (event)
(let ((w (posn-window (event-start event))))
- (and (window-minibuffer-p w)
+ (and (windowp w)
+ (window-minibuffer-p w)
(not (minibuffer-window-active-p w))
(user-error "Minibuffer window is not active")))
;; Give temporary modes such as isearch a chance to turn off.
@@ -496,7 +613,7 @@ This command must be bound to a mouse click."
(or (eq frame oframe)
(set-mouse-position (selected-frame) (1- (frame-width)) 0))))
-(define-obsolete-function-alias 'mouse-tear-off-window 'tear-off-window "24.4")
+(define-obsolete-function-alias 'mouse-tear-off-window #'tear-off-window "24.4")
(defun tear-off-window (click)
"Delete the selected window, and create a new frame displaying its buffer."
(interactive (list last-nonmenu-event))
@@ -572,7 +689,6 @@ must be one of the symbols `header', `mode', or `vertical'."
;; previously sampled position. The difference of `position'
;; and `last-position' determines the size change of WINDOW.
(last-position position)
- (draggable t)
posn-window growth dragged)
;; Decide on whether we are allowed to track at all and whose
;; window's edge we drag.
@@ -625,7 +741,7 @@ must be one of the symbols `header', `mode', or `vertical'."
(setq dragged t)
(adjust-window-trailing-edge window growth t t))
(setq last-position position))
- (draggable
+ (t
;; Drag bottom edge of `window'.
(setq start (event-start event))
;; Set `posn-window' to the window where `event' was recorded.
@@ -1374,9 +1490,10 @@ its value is returned."
;; Mouse clicks in the fringe come with a position in
;; (nth 5). This is useful but is not exactly where we clicked, so
;; don't look up that position's properties!
- (and pt (not (memq (posn-area pos) '(left-fringe right-fringe
- left-margin right-margin)))
- (get-char-property pt property w))))
+ (and pt (not (memq (posn-area pos)
+ '(left-fringe right-fringe
+ left-margin right-margin tab-bar)))
+ (get-char-property pt property w))))
(get-char-property pos property)))
(defun mouse-on-link-p (pos)
@@ -1465,8 +1582,7 @@ The region will be defined with mark and point."
(mouse-minibuffer-check start-event)
(setq mouse-selection-click-count-buffer (current-buffer))
(deactivate-mark)
- (let* ((scroll-margin 0) ; Avoid margin scrolling (Bug#9541).
- (start-posn (event-start start-event))
+ (let* ((start-posn (event-start start-event))
(start-point (posn-point start-posn))
(start-window (posn-window start-posn))
(_ (with-current-buffer (window-buffer start-window)
@@ -1488,65 +1604,88 @@ The region will be defined with mark and point."
;; Don't count the mode line.
(1- (nth 3 bounds))))
(click-count (1- (event-click-count start-event)))
- ;; Suppress automatic hscrolling, because that is a nuisance
- ;; when setting point near the right fringe (but see below).
+ ;; Save original automatic scrolling behavior (see below).
(auto-hscroll-mode-saved auto-hscroll-mode)
- (old-track-mouse track-mouse))
+ (scroll-margin-saved scroll-margin)
+ (old-track-mouse track-mouse)
+ (cleanup (lambda ()
+ (setq track-mouse old-track-mouse)
+ (setq auto-hscroll-mode auto-hscroll-mode-saved)
+ (setq scroll-margin scroll-margin-saved))))
+ (condition-case err
+ (progn
+ (setq mouse-selection-click-count click-count)
+
+ ;; Suppress automatic scrolling near the edges while tracking
+ ;; movement, as it interferes with the natural dragging behavior
+ ;; (point will unexpectedly be moved beneath the pointer, making
+ ;; selections in auto-scrolling margins impossible).
+ (setq auto-hscroll-mode nil)
+ (setq scroll-margin 0)
+
+ ;; In case the down click is in the middle of some intangible text,
+ ;; use the end of that text, and put it in START-POINT.
+ (if (< (point) start-point)
+ (goto-char start-point))
+ (setq start-point (point))
+
+ ;; Activate the region, using `mouse-start-end' to determine where
+ ;; to put point and mark (e.g., double-click will select a word).
+ (setq-local transient-mark-mode
+ (if (eq transient-mark-mode 'lambda)
+ '(only)
+ (cons 'only transient-mark-mode)))
+ (let ((range (mouse-start-end start-point start-point click-count)))
+ (push-mark (nth 0 range) t t)
+ (goto-char (nth 1 range)))
- (setq mouse-selection-click-count click-count)
- ;; In case the down click is in the middle of some intangible text,
- ;; use the end of that text, and put it in START-POINT.
- (if (< (point) start-point)
- (goto-char start-point))
- (setq start-point (point))
+ (setf (terminal-parameter nil 'mouse-drag-start) start-event)
+ ;; Set 'track-mouse' to something neither nil nor t, so that mouse
+ ;; events are not reported to have happened on the tool bar or the
+ ;; tab bar, as that breaks drag events that originate on the window
+ ;; body below these bars; see make_lispy_position and bug#51794.
+ (setq track-mouse 'drag-tracking)
- ;; Activate the region, using `mouse-start-end' to determine where
- ;; to put point and mark (e.g., double-click will select a word).
- (setq-local transient-mark-mode
- (if (eq transient-mark-mode 'lambda)
- '(only)
- (cons 'only transient-mark-mode)))
- (let ((range (mouse-start-end start-point start-point click-count)))
- (push-mark (nth 0 range) t t)
- (goto-char (nth 1 range)))
-
- (setf (terminal-parameter nil 'mouse-drag-start) start-event)
- (setq track-mouse t)
- (setq auto-hscroll-mode nil)
-
- (set-transient-map
- (let ((map (make-sparse-keymap)))
- (define-key map [switch-frame] #'ignore)
- (define-key map [select-window] #'ignore)
- (define-key map [mouse-movement]
- (lambda (event) (interactive "e")
- (let* ((end (event-end event))
- (end-point (posn-point end)))
- (unless (eq end-point start-point)
- ;; As soon as the user moves, we can re-enable auto-hscroll.
- (setq auto-hscroll-mode auto-hscroll-mode-saved)
- ;; And remember that we have moved, so mouse-set-region can know
- ;; its event is really a drag event.
- (setcar start-event 'mouse-movement))
- (if (and (eq (posn-window end) start-window)
- (integer-or-marker-p end-point))
- (mouse--drag-set-mark-and-point start-point
- end-point click-count)
- (let ((mouse-row (cdr (cdr (mouse-position)))))
- (cond
- ((null mouse-row))
- ((< mouse-row top)
- (mouse-scroll-subr start-window (- mouse-row top)
- nil start-point))
- ((>= mouse-row bottom)
- (mouse-scroll-subr start-window (1+ (- mouse-row bottom))
- nil start-point))))))))
- map)
- t (lambda ()
- (setq track-mouse old-track-mouse)
- (setq auto-hscroll-mode auto-hscroll-mode-saved)
- (deactivate-mark)
- (pop-mark)))))
+ (set-transient-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [switch-frame] #'ignore)
+ (define-key map [select-window] #'ignore)
+ (define-key map [mouse-movement]
+ (lambda (event) (interactive "e")
+ (let* ((end (event-end event))
+ (end-point (posn-point end)))
+ (unless (eq end-point start-point)
+ ;; And remember that we have moved, so mouse-set-region can know
+ ;; its event is really a drag event.
+ (setcar start-event 'mouse-movement))
+ (if (and (eq (posn-window end) start-window)
+ (integer-or-marker-p end-point))
+ (mouse--drag-set-mark-and-point start-point
+ end-point click-count)
+ (let ((mouse-row (cdr (cdr (mouse-position)))))
+ (cond
+ ((null mouse-row))
+ ((< mouse-row top)
+ (mouse-scroll-subr start-window (- mouse-row top)
+ nil start-point))
+ ((>= mouse-row bottom)
+ (mouse-scroll-subr start-window (1+ (- mouse-row bottom))
+ nil start-point))))))))
+ map)
+ t (lambda ()
+ (funcall cleanup)
+ ;; Don't deactivate the mark when the context menu was invoked
+ ;; by down-mouse-3 immediately after down-mouse-1 and without
+ ;; releasing the mouse button with mouse-1. This allows to use
+ ;; region-related context menu to operate on the selected region.
+ (unless (and context-menu-mode
+ (eq (car-safe (aref (this-command-keys-vector) 0))
+ 'down-mouse-3))
+ (deactivate-mark)
+ (pop-mark)))))
+ ;; Cleanup on errors
+ (error (funcall cleanup)
+ (signal (car err) (cdr err))))))
(defun mouse--drag-set-mark-and-point (start click click-count)
(let* ((range (mouse-start-end start click click-count))
@@ -1702,7 +1841,7 @@ If MODE is 2 then do the same for lines."
event)))
(setcar last new)
(if (and (not (equal modifiers old-modifiers))
- (key-binding (apply 'vector events)))
+ (key-binding (apply #'vector events)))
t
(setcar last event)
nil)))
@@ -1756,12 +1895,12 @@ regardless of where you click."
(setq mouse-selection-click-count 0)
(yank arg))
-(defun mouse-yank-primary (click)
- "Insert the primary selection at the position clicked on.
+(defun mouse-yank-primary (&optional event)
+ "Insert the primary selection,
Move point to the end of the inserted text, and set mark at
beginning. If `mouse-yank-at-point' is non-nil, insert at point
-regardless of where you click."
- (interactive "e")
+otherwise insert it at the position of EVENT."
+ (interactive (list last-nonmenu-event))
;; Give temporary modes such as isearch a chance to turn off.
(run-hooks 'mouse-leave-buffer-hook)
;; Without this, confusing things happen upon e.g. inserting into
@@ -1769,7 +1908,7 @@ regardless of where you click."
(when select-active-regions
(let (select-active-regions)
(deactivate-mark)))
- (or mouse-yank-at-point (mouse-set-point click))
+ (or mouse-yank-at-point (mouse-set-point event))
(let ((primary (gui-get-primary-selection)))
(push-mark)
(insert-for-yank primary)))
@@ -1909,11 +2048,11 @@ if `mouse-drag-copy-region' is non-nil)."
(setq mouse-save-then-kill-posn click-pt)))))
-(global-set-key [M-mouse-1] 'mouse-start-secondary)
-(global-set-key [M-drag-mouse-1] 'mouse-set-secondary)
-(global-set-key [M-down-mouse-1] 'mouse-drag-secondary)
-(global-set-key [M-mouse-3] 'mouse-secondary-save-then-kill)
-(global-set-key [M-mouse-2] 'mouse-yank-secondary)
+(global-set-key [M-mouse-1] #'mouse-start-secondary)
+(global-set-key [M-drag-mouse-1] #'mouse-set-secondary)
+(global-set-key [M-down-mouse-1] #'mouse-drag-secondary)
+(global-set-key [M-mouse-3] #'mouse-secondary-save-then-kill)
+(global-set-key [M-mouse-2] #'mouse-yank-secondary)
(defconst mouse-secondary-overlay
(let ((ol (make-overlay (point-min) (point-min))))
@@ -2355,7 +2494,7 @@ a large number if you prefer a mixed multitude. The default is 4."
("Text" . "Text")
("Outline" . "Text")
("\\(HT\\|SG\\|X\\|XHT\\)ML" . "SGML")
- ("log\\|diff\\|vc\\|cvs\\|Git\\|Annotate" . "Version Control")
+ ("\\blog\\b\\|diff\\|\\bvc\\b\\|cvs\\|Git\\|Annotate" . "Version Control")
("Threads\\|Memory\\|Disassembly\\|Breakpoints\\|Frames\\|Locals\\|Registers\\|Inferior I/O\\|Debugger"
. "GDB")
("Lisp" . "Lisp")))
@@ -3073,78 +3212,78 @@ is copied instead of being cut."
;;; Bindings for mouse commands.
-(global-set-key [down-mouse-1] 'mouse-drag-region)
-(global-set-key [mouse-1] 'mouse-set-point)
-(global-set-key [drag-mouse-1] 'mouse-set-region)
+(global-set-key [down-mouse-1] #'mouse-drag-region)
+(global-set-key [mouse-1] #'mouse-set-point)
+(global-set-key [drag-mouse-1] #'mouse-set-region)
(defun mouse--strip-first-event (_prompt)
(substring (this-single-command-raw-keys) 1))
-(define-key function-key-map [left-fringe mouse-1] 'mouse--strip-first-event)
-(define-key function-key-map [right-fringe mouse-1] 'mouse--strip-first-event)
+(define-key function-key-map [left-fringe mouse-1] #'mouse--strip-first-event)
+(define-key function-key-map [right-fringe mouse-1] #'mouse--strip-first-event)
-(global-set-key [mouse-2] 'mouse-yank-primary)
+(global-set-key [mouse-2] #'mouse-yank-primary)
;; Allow yanking also when the corresponding cursor is "in the fringe".
-(define-key function-key-map [right-fringe mouse-2] 'mouse--strip-first-event)
-(define-key function-key-map [left-fringe mouse-2] 'mouse--strip-first-event)
-(global-set-key [mouse-3] 'mouse-save-then-kill)
-(define-key function-key-map [right-fringe mouse-3] 'mouse--strip-first-event)
-(define-key function-key-map [left-fringe mouse-3] 'mouse--strip-first-event)
+(define-key function-key-map [right-fringe mouse-2] #'mouse--strip-first-event)
+(define-key function-key-map [left-fringe mouse-2] #'mouse--strip-first-event)
+(global-set-key [mouse-3] #'mouse-save-then-kill)
+(define-key function-key-map [right-fringe mouse-3] #'mouse--strip-first-event)
+(define-key function-key-map [left-fringe mouse-3] #'mouse--strip-first-event)
;; By binding these to down-going events, we let the user use the up-going
;; event to make the selection, saving a click.
-(global-set-key [C-down-mouse-1] 'mouse-buffer-menu)
+(global-set-key [C-down-mouse-1] #'mouse-buffer-menu)
(if (not (eq system-type 'ms-dos))
- (global-set-key [S-down-mouse-1] 'mouse-appearance-menu))
+ (global-set-key [S-down-mouse-1] #'mouse-appearance-menu))
;; C-down-mouse-2 is bound in facemenu.el.
(global-set-key [C-down-mouse-3]
`(menu-item ,(purecopy "Menu Bar") ignore
- :filter (lambda (_)
- (if (zerop (or (frame-parameter nil 'menu-bar-lines) 0))
- (mouse-menu-bar-map)
- (mouse-menu-major-mode-map)))))
+ :filter ,(lambda (_)
+ (if (zerop (or (frame-parameter nil 'menu-bar-lines) 0))
+ (mouse-menu-bar-map)
+ (mouse-menu-major-mode-map)))))
;; Binding mouse-1 to mouse-select-window when on mode-, header-, or
;; vertical-line prevents Emacs from signaling an error when the mouse
;; button is released after dragging these lines, on non-toolkit
;; versions.
-(global-set-key [header-line down-mouse-1] 'mouse-drag-header-line)
-(global-set-key [header-line mouse-1] 'mouse-select-window)
-(global-set-key [tab-line down-mouse-1] 'mouse-drag-tab-line)
-(global-set-key [tab-line mouse-1] 'mouse-select-window)
+(global-set-key [header-line down-mouse-1] #'mouse-drag-header-line)
+(global-set-key [header-line mouse-1] #'mouse-select-window)
+(global-set-key [tab-line down-mouse-1] #'mouse-drag-tab-line)
+(global-set-key [tab-line mouse-1] #'mouse-select-window)
;; (global-set-key [mode-line drag-mouse-1] 'mouse-select-window)
-(global-set-key [mode-line down-mouse-1] 'mouse-drag-mode-line)
-(global-set-key [mode-line mouse-1] 'mouse-select-window)
-(global-set-key [mode-line mouse-2] 'mouse-delete-other-windows)
-(global-set-key [mode-line mouse-3] 'mouse-delete-window)
-(global-set-key [mode-line C-mouse-2] 'mouse-split-window-horizontally)
-(global-set-key [vertical-scroll-bar C-mouse-2] 'mouse-split-window-vertically)
-(global-set-key [horizontal-scroll-bar C-mouse-2] 'mouse-split-window-horizontally)
-(global-set-key [vertical-line down-mouse-1] 'mouse-drag-vertical-line)
-(global-set-key [vertical-line mouse-1] 'mouse-select-window)
-(global-set-key [vertical-line C-mouse-2] 'mouse-split-window-vertically)
-(global-set-key [right-divider down-mouse-1] 'mouse-drag-vertical-line)
-(global-set-key [right-divider mouse-1] 'ignore)
-(global-set-key [right-divider C-mouse-2] 'mouse-split-window-vertically)
-(global-set-key [bottom-divider down-mouse-1] 'mouse-drag-mode-line)
-(global-set-key [bottom-divider mouse-1] 'ignore)
-(global-set-key [bottom-divider C-mouse-2] 'mouse-split-window-horizontally)
-(global-set-key [left-edge down-mouse-1] 'mouse-drag-left-edge)
-(global-set-key [left-edge mouse-1] 'ignore)
-(global-set-key [top-left-corner down-mouse-1] 'mouse-drag-top-left-corner)
-(global-set-key [top-left-corner mouse-1] 'ignore)
-(global-set-key [top-edge down-mouse-1] 'mouse-drag-top-edge)
-(global-set-key [top-edge mouse-1] 'ignore)
-(global-set-key [top-right-corner down-mouse-1] 'mouse-drag-top-right-corner)
-(global-set-key [top-right-corner mouse-1] 'ignore)
-(global-set-key [right-edge down-mouse-1] 'mouse-drag-right-edge)
-(global-set-key [right-edge mouse-1] 'ignore)
-(global-set-key [bottom-right-corner down-mouse-1] 'mouse-drag-bottom-right-corner)
-(global-set-key [bottom-right-corner mouse-1] 'ignore)
-(global-set-key [bottom-edge down-mouse-1] 'mouse-drag-bottom-edge)
-(global-set-key [bottom-edge mouse-1] 'ignore)
-(global-set-key [bottom-left-corner down-mouse-1] 'mouse-drag-bottom-left-corner)
-(global-set-key [bottom-left-corner mouse-1] 'ignore)
+(global-set-key [mode-line down-mouse-1] #'mouse-drag-mode-line)
+(global-set-key [mode-line mouse-1] #'mouse-select-window)
+(global-set-key [mode-line mouse-2] #'mouse-delete-other-windows)
+(global-set-key [mode-line mouse-3] #'mouse-delete-window)
+(global-set-key [mode-line C-mouse-2] #'mouse-split-window-horizontally)
+(global-set-key [vertical-scroll-bar C-mouse-2] #'mouse-split-window-vertically)
+(global-set-key [horizontal-scroll-bar C-mouse-2] #'mouse-split-window-horizontally)
+(global-set-key [vertical-line down-mouse-1] #'mouse-drag-vertical-line)
+(global-set-key [vertical-line mouse-1] #'mouse-select-window)
+(global-set-key [vertical-line C-mouse-2] #'mouse-split-window-vertically)
+(global-set-key [right-divider down-mouse-1] #'mouse-drag-vertical-line)
+(global-set-key [right-divider mouse-1] #'ignore)
+(global-set-key [right-divider C-mouse-2] #'mouse-split-window-vertically)
+(global-set-key [bottom-divider down-mouse-1] #'mouse-drag-mode-line)
+(global-set-key [bottom-divider mouse-1] #'ignore)
+(global-set-key [bottom-divider C-mouse-2] #'mouse-split-window-horizontally)
+(global-set-key [left-edge down-mouse-1] #'mouse-drag-left-edge)
+(global-set-key [left-edge mouse-1] #'ignore)
+(global-set-key [top-left-corner down-mouse-1] #'mouse-drag-top-left-corner)
+(global-set-key [top-left-corner mouse-1] #'ignore)
+(global-set-key [top-edge down-mouse-1] #'mouse-drag-top-edge)
+(global-set-key [top-edge mouse-1] #'ignore)
+(global-set-key [top-right-corner down-mouse-1] #'mouse-drag-top-right-corner)
+(global-set-key [top-right-corner mouse-1] #'ignore)
+(global-set-key [right-edge down-mouse-1] #'mouse-drag-right-edge)
+(global-set-key [right-edge mouse-1] #'ignore)
+(global-set-key [bottom-right-corner down-mouse-1] #'mouse-drag-bottom-right-corner)
+(global-set-key [bottom-right-corner mouse-1] #'ignore)
+(global-set-key [bottom-edge down-mouse-1] #'mouse-drag-bottom-edge)
+(global-set-key [bottom-edge mouse-1] #'ignore)
+(global-set-key [bottom-left-corner down-mouse-1] #'mouse-drag-bottom-left-corner)
+(global-set-key [bottom-left-corner mouse-1] #'ignore)
(provide 'mouse)
diff --git a/lisp/mpc.el b/lisp/mpc.el
index 029f0ca8f42..c47d4336e5e 100644
--- a/lisp/mpc.el
+++ b/lisp/mpc.el
@@ -197,10 +197,10 @@ numerically rather than lexicographically."
(defcustom mpc-host
(concat (or (getenv "MPD_HOST") "localhost")
(if (getenv "MPD_PORT") (concat ":" (getenv "MPD_PORT"))))
- "Host (and port) where the Music Player Daemon is running. The
-format is \"HOST\", \"HOST:PORT\", \"PASSWORD@HOST\" or
-\"PASSWORD@HOST:PORT\" where PASSWORD defaults to no password, PORT
-defaults to 6600 and HOST defaults to localhost."
+ "Host (and port) where the Music Player Daemon is running.
+The format is \"HOST\", \"HOST:PORT\", \"PASSWORD@HOST\" or
+\"PASSWORD@HOST:PORT\" where PASSWORD defaults to no password,
+PORT defaults to 6600 and HOST defaults to localhost."
:type 'string)
(defvar mpc-proc nil)
@@ -962,6 +962,11 @@ If PLAYLIST is t or nil or missing, use the main playlist."
;;; Formatter ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defcustom mpc-cover-image-re nil ; (rx (or ".jpg" ".jpeg" ".png") string-end)
+ "If non-nil, it is a regexp that should match a valid cover image."
+ :type '(choice (const nil) regexp)
+ :version "28.1")
+
(defun mpc-secs-to-time (secs)
;; We could use `format-seconds', but it doesn't seem worth the trouble
;; because we'd still need to check (>= secs (* 60 100)) since the special
@@ -1034,15 +1039,18 @@ If PLAYLIST is t or nil or missing, use the main playlist."
(and (funcall oldpred info)
(equal dir (file-name-directory
(cdr (assq 'file info))))))))
- (if-let* ((covers '(".folder.png" "cover.jpg" "folder.jpg"))
+ (if-let* ((covers '(".folder.png" "folder.png" "cover.jpg" "folder.jpg"))
(cover (cl-loop for file in (directory-files (mpc-file-local-copy dir))
- if (member (downcase file) covers)
+ if (or (member (downcase file) covers)
+ (and mpc-cover-image-re
+ (string-match mpc-cover-image-re file)))
return (concat dir file)))
(file (with-demoted-errors "MPC: %s"
(mpc-file-local-copy cover))))
(let (image)
(if (null size) (setq image (create-image file))
(let ((tempfile (make-temp-file "mpc" nil ".jpg")))
+ ;; FIXME: Use native image scaling instead.
(call-process "convert" nil nil nil
"-scale" size file tempfile)
(setq image (create-image tempfile))
@@ -1111,6 +1119,9 @@ If PLAYLIST is t or nil or missing, use the main playlist."
(if (null size) (setq col (+ col textwidth postwidth))
(insert space)
(setq col (+ col size))))))
+ ;; Print the rest of format-spec, in case there is text after the
+ ;; last actual format specifier.
+ (insert (substring format-spec pos))
(put-text-property start (point) 'mpc--uptodate-p pred)))
;;; The actual UI code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1139,6 +1150,7 @@ If PLAYLIST is t or nil or missing, use the main playlist."
(define-key map ">" #'mpc-next)
(define-key map "<" #'mpc-prev)
(define-key map "g" #'mpc-seek-current)
+ (define-key map "o" #'mpc-goto-playing-song)
map))
(easy-menu-define mpc-mode-menu mpc-mode-map
@@ -1870,7 +1882,8 @@ A value of t means the main playlist.")
(when (buffer-live-p status-buf)
(with-current-buffer status-buf (force-mode-line-update)))))
-(defvar mpc-volume-step 5)
+(defvar mpc-volume-step 5
+ "Change volume in increments of this integer.")
(defun mpc-volume-mouse-set (&optional event)
"Change volume setting."
@@ -1884,7 +1897,7 @@ A value of t means the main playlist.")
'(?◁ ?<))
(- mpc-volume-step) mpc-volume-step))
(curvol (string-to-number (cdr (assq 'volume mpc-status))))
- (newvol (max 0 (min 100 (+ curvol diff)))))
+ (newvol (max 0 (min 100 (+ (- curvol (mod curvol diff)) diff)))))
(if (= newvol curvol)
(progn
(message "MPD volume already at %s%%" newvol)
@@ -2658,6 +2671,18 @@ If stopped, start playback."
(mpc-select event)
(mpc-play))
+(defun mpc-goto-playing-song ()
+ "Move point to the currently playing song in the \"*Songs*\" buffer."
+ (interactive)
+ (let* ((buf (mpc-proc-buffer (mpc-proc) 'songs))
+ (win (get-buffer-window buf)))
+ (when (and (buffer-live-p buf) win)
+ (select-window win)
+ (with-current-buffer buf
+ (when (and overlay-arrow-position
+ (eq (marker-buffer overlay-arrow-position) buf))
+ (goto-char (marker-position overlay-arrow-position)))))))
+
;; (defun mpc-play-tagval ()
;; "Play all the songs of the tag at point."
;; (interactive)
diff --git a/lisp/mwheel.el b/lisp/mwheel.el
index def77587747..fbe8daa77f8 100644
--- a/lisp/mwheel.el
+++ b/lisp/mwheel.el
@@ -55,7 +55,8 @@
(mouse-wheel-mode 1)))
(defcustom mouse-wheel-down-event
- (if (or (featurep 'w32-win) (featurep 'ns-win))
+ (if (or (featurep 'w32-win) (featurep 'ns-win)
+ (featurep 'haiku-win) (featurep 'pgtk-win))
'wheel-up
'mouse-4)
"Event used for scrolling down."
@@ -63,8 +64,20 @@
:type 'symbol
:set 'mouse-wheel-change-button)
+(defcustom mouse-wheel-down-alternate-event
+ (if (featurep 'xinput2)
+ 'wheel-up
+ (unless (featurep 'x)
+ 'mouse-4))
+ "Alternative wheel down event to consider."
+ :group 'mouse
+ :type 'symbol
+ :version "29.1"
+ :set 'mouse-wheel-change-button)
+
(defcustom mouse-wheel-up-event
- (if (or (featurep 'w32-win) (featurep 'ns-win))
+ (if (or (featurep 'w32-win) (featurep 'ns-win)
+ (featurep 'haiku-win) (featurep 'pgtk-win))
'wheel-down
'mouse-5)
"Event used for scrolling up."
@@ -72,6 +85,17 @@
:type 'symbol
:set 'mouse-wheel-change-button)
+(defcustom mouse-wheel-up-alternate-event
+ (if (featurep 'xinput2)
+ 'wheel-down
+ (unless (featurep 'x)
+ 'mouse-5))
+ "Alternative wheel up event to consider."
+ :group 'mouse
+ :type 'symbol
+ :version "29.1"
+ :set 'mouse-wheel-change-button)
+
(defcustom mouse-wheel-click-event 'mouse-2
"Event that should be temporarily inhibited after mouse scrolling.
The mouse wheel is typically on the mouse-2 button, so it may easily
@@ -103,7 +127,7 @@ less than a full screen.
If AMOUNT is the symbol 'hscroll', this means that with MODIFIER,
the mouse wheel will scroll horizontally instead of vertically.
-If AMOUNT is the symbol text-scale, this means that with
+If AMOUNT is the symbol 'text-scale', this means that with
MODIFIER, the mouse wheel will change the face height instead of
scrolling."
:group 'mouse
@@ -221,17 +245,33 @@ Also see `mouse-wheel-tilt-scroll'."
"Function that does the job of scrolling right.")
(defvar mouse-wheel-left-event
- (if (or (featurep 'w32-win) (featurep 'ns-win))
+ (if (or (featurep 'w32-win) (featurep 'ns-win)
+ (featurep 'haiku-win) (featurep 'pgtk-win))
'wheel-left
'mouse-6)
"Event used for scrolling left.")
+(defvar mouse-wheel-left-alternate-event
+ (if (featurep 'xinput2)
+ 'wheel-left
+ (unless (featurep 'x)
+ 'mouse-6))
+ "Alternative wheel left event to consider.")
+
(defvar mouse-wheel-right-event
- (if (or (featurep 'w32-win) (featurep 'ns-win))
+ (if (or (featurep 'w32-win) (featurep 'ns-win)
+ (featurep 'haiku-win) (featurep 'pgtk-win))
'wheel-right
'mouse-7)
"Event used for scrolling right.")
+(defvar mouse-wheel-right-alternate-event
+ (if (featurep 'xinput2)
+ 'wheel-right
+ (unless (featurep 'x)
+ 'mouse-7))
+ "Alternative wheel right event to consider.")
+
(defun mouse-wheel--get-scroll-window (event)
"Return window for mouse wheel event EVENT.
If `mouse-wheel-follow-mouse' is non-nil, return the window that
@@ -296,14 +336,16 @@ value of ARG, and the command uses it in subsequent scrolls."
(condition-case nil
(unwind-protect
(let ((button (mwheel-event-button event)))
- (cond ((and (eq amt 'hscroll) (eq button mouse-wheel-down-event))
+ (cond ((and (eq amt 'hscroll) (memq button (list mouse-wheel-down-event
+ mouse-wheel-down-alternate-event)))
(when (and (natnump arg) (> arg 0))
(setq mouse-wheel-scroll-amount-horizontal arg))
(funcall (if mouse-wheel-flip-direction
mwheel-scroll-left-function
mwheel-scroll-right-function)
mouse-wheel-scroll-amount-horizontal))
- ((eq button mouse-wheel-down-event)
+ ((memq button (list mouse-wheel-down-event
+ mouse-wheel-down-alternate-event))
(condition-case nil (funcall mwheel-scroll-down-function amt)
;; Make sure we do indeed scroll to the beginning of
;; the buffer.
@@ -318,23 +360,27 @@ value of ARG, and the command uses it in subsequent scrolls."
;; for a reason that escapes me. This problem seems
;; to only affect scroll-down. --Stef
(set-window-start (selected-window) (point-min))))))
- ((and (eq amt 'hscroll) (eq button mouse-wheel-up-event))
+ ((and (eq amt 'hscroll) (memq button (list mouse-wheel-up-event
+ mouse-wheel-up-alternate-event)))
(when (and (natnump arg) (> arg 0))
(setq mouse-wheel-scroll-amount-horizontal arg))
(funcall (if mouse-wheel-flip-direction
mwheel-scroll-right-function
mwheel-scroll-left-function)
mouse-wheel-scroll-amount-horizontal))
- ((eq button mouse-wheel-up-event)
+ ((memq button (list mouse-wheel-up-event
+ mouse-wheel-up-alternate-event))
(condition-case nil (funcall mwheel-scroll-up-function amt)
;; Make sure we do indeed scroll to the end of the buffer.
(end-of-buffer (while t (funcall mwheel-scroll-up-function)))))
- ((eq button mouse-wheel-left-event) ; for tilt scroll
+ ((memq button (list mouse-wheel-left-event
+ mouse-wheel-left-alternate-event)) ; for tilt scroll
(when mouse-wheel-tilt-scroll
(funcall (if mouse-wheel-flip-direction
mwheel-scroll-right-function
mwheel-scroll-left-function) amt)))
- ((eq button mouse-wheel-right-event) ; for tilt scroll
+ ((memq button (list mouse-wheel-right-event
+ mouse-wheel-right-alternate-event)) ; for tilt scroll
(when mouse-wheel-tilt-scroll
(funcall (if mouse-wheel-flip-direction
mwheel-scroll-left-function
@@ -378,9 +424,11 @@ value of ARG, and the command uses it in subsequent scrolls."
(button (mwheel-event-button event)))
(select-window scroll-window 'mark-for-redisplay)
(unwind-protect
- (cond ((eq button mouse-wheel-down-event)
+ (cond ((memq button (list mouse-wheel-down-event
+ mouse-wheel-down-alternate-event))
(text-scale-increase 1))
- ((eq button mouse-wheel-up-event)
+ ((memq button (list mouse-wheel-up-event
+ mouse-wheel-up-alternate-event))
(text-scale-decrease 1)))
(select-window selected-window))))
@@ -432,15 +480,23 @@ an event used for scrolling, such as `mouse-wheel-down-event'."
(cond
;; Bindings for changing font size.
((and (consp binding) (eq (cdr binding) 'text-scale))
- (dolist (event (list mouse-wheel-down-event mouse-wheel-up-event))
- (mouse-wheel--add-binding `[,(list (caar binding) event)]
- 'mouse-wheel-text-scale)))
+ (dolist (event (list mouse-wheel-down-event mouse-wheel-up-event
+ mouse-wheel-down-alternate-event
+ mouse-wheel-up-alternate-event))
+ (when event
+ (mouse-wheel--add-binding `[,(list (caar binding) event)]
+ 'mouse-wheel-text-scale))))
;; Bindings for scrolling.
(t
(dolist (event (list mouse-wheel-down-event mouse-wheel-up-event
- mouse-wheel-left-event mouse-wheel-right-event))
- (dolist (key (mouse-wheel--create-scroll-keys binding event))
- (mouse-wheel--add-binding key 'mwheel-scroll)))))))
+ mouse-wheel-left-event mouse-wheel-right-event
+ mouse-wheel-down-alternate-event
+ mouse-wheel-up-alternate-event
+ mouse-wheel-left-alternate-event
+ mouse-wheel-right-alternate-event))
+ (when event
+ (dolist (key (mouse-wheel--create-scroll-keys binding event))
+ (mouse-wheel--add-binding key 'mwheel-scroll))))))))
(when mouse-wheel-mode
(mouse-wheel--setup-bindings))
diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el
index e302aa89f30..a6c256eeba8 100644
--- a/lisp/net/ange-ftp.el
+++ b/lisp/net/ange-ftp.el
@@ -230,7 +230,7 @@
;;
;; 1. For dired to work on a host which marks symlinks with a trailing @ in
;; an ls -alF listing, you need to (setq dired-ls-F-marks-symlinks t).
-;; Most UNIX systems do not do this, but ULTRIX does. If you think that
+;; Most UNIX systems do not do this, but ULTRIX does. If you think that
;; there is a chance you might connect to an ULTRIX machine (such as
;; prep.ai.mit.edu), then set this variable accordingly. This will have
;; the side effect that dired will have problems with symlinks whose names
@@ -241,34 +241,34 @@
;; frequently, and ange-ftp seems to be unable to guess its host-type,
;; then setting the appropriate host-type regexp
;; (ange-ftp-vms-host-regexp, ange-ftp-mts-host-regexp, or
-;; ange-ftp-cms-host-regexp) accordingly should help. Also, please report
+;; ange-ftp-cms-host-regexp) accordingly should help. Also, please report
;; ange-ftp's inability to recognize the host-type as a bug.
;;
;; 3. For slow connections, you might get "listing unreadable" error
;; messages, or get an empty buffer for a file that you know has something
-;; in it. The solution is to increase the value of ange-ftp-retry-time.
+;; in it. The solution is to increase the value of ange-ftp-retry-time.
;; Its default value is 5 which is plenty for reasonable connections.
;; However, for some transatlantic connections I set this to 20.
;;
-;; 4. Beware of compressing files on non-UNIX hosts. Ange-ftp will do it by
+;; 4. Beware of compressing files on non-UNIX hosts. Ange-ftp will do it by
;; copying the file to the local machine, compressing it there, and then
-;; sending it back. Binary file transfers between machines of different
-;; architectures can be a risky business. Test things out first on some
-;; test files. See "Bugs" below. Also, note that ange-ftp copies files by
-;; moving them through the local machine. Again, be careful when doing
+;; sending it back. Binary file transfers between machines of different
+;; architectures can be a risky business. Test things out first on some
+;; test files. See "Bugs" below. Also, note that ange-ftp copies files by
+;; moving them through the local machine. Again, be careful when doing
;; this with binary files on non-Unix machines.
;;
;; 5. Beware that dired over ftp will use your setting of dired-no-confirm
;; (list of dired commands for which confirmation is not asked). You
;; might want to reconsider your setting of this variable, because you
;; might want confirmation for more commands on remote direds than on
-;; local direds. For example, I strongly recommend that you not include
-;; compress and uncompress in this list. If there is enough demand it
+;; local direds. For example, I strongly recommend that you not include
+;; compress and uncompress in this list. If there is enough demand it
;; might be a good idea to have an alist ange-ftp-dired-no-confirm of
;; pairs ( TYPE . LIST ), where TYPE is an operating system type and LIST
;; is a list of commands for which confirmation would be suppressed. Then
;; remote dired listings would take their (buffer-local) value of
-;; dired-no-confirm from this alist. Who votes for this?
+;; dired-no-confirm from this alist. Who votes for this?
;; ---------------------------------------------------------------------
;; Non-UNIX support:
@@ -277,7 +277,7 @@
;; VMS support:
;;
;; Ange-ftp has full support for VMS hosts. It should be able to
-;; automatically recognize any VMS machine. However, if it fails to do
+;; automatically recognize any VMS machine. However, if it fails to do
;; this, you can use the command ange-ftp-add-vms-host. Also, you can
;; set the variable ange-ftp-vms-host-regexp in your init file. We
;; would be grateful if you would report any failures to automatically
@@ -308,46 +308,46 @@
;; Therefore, to access a VMS file, you must enter the filename with upper
;; case letters.
;; 2. To access the latest version of file under VMS, you use the filename
-;; without the ";" and version number. You should always edit the latest
-;; version of a file. If you want to edit an earlier version, copy it to a
-;; new file first. This has nothing to do with ange-ftp, but is simply
-;; good VMS operating practice. Therefore, to edit FILE.TXT;3 (say 3 is
-;; latest version), do C-x C-f /ymir.claremont.edu:FILE.TXT. If you
+;; without the ";" and version number. You should always edit the latest
+;; version of a file. If you want to edit an earlier version, copy it to a
+;; new file first. This has nothing to do with ange-ftp, but is simply
+;; good VMS operating practice. Therefore, to edit FILE.TXT;3 (say 3 is
+;; latest version), do C-x C-f /ymir.claremont.edu:FILE.TXT. If you
;; inadvertently do C-x C-f /ymir.claremont.edu:FILE.TXT;3, you will find
;; that VMS will not allow you to save the file because it will refuse to
;; overwrite FILE.TXT;3, but instead will want to create FILE.TXT;4, and
-;; attach the buffer to this file. To get out of this situation, M-x
+;; attach the buffer to this file. To get out of this situation, M-x
;; write-file /ymir.claremont.edu:FILE.TXT will attach the buffer to
-;; latest version of the file. For this reason, in dired "f"
+;; latest version of the file. For this reason, in dired "f"
;; (dired-find-file), always loads the file sans version, whereas "v",
-;; (dired-view-file), always loads the explicit version number. The
+;; (dired-view-file), always loads the explicit version number. The
;; reasoning being that it reasonable to view old versions of a file, but
;; not to edit them.
;; 3. EMACS has a feature in which it does environment variable substitution
-;; in filenames. Therefore, to enter a $ in a filename, you must quote it
+;; in filenames. Therefore, to enter a $ in a filename, you must quote it
;; by typing $$.
;; MTS support:
;;
;; Ange-ftp has full support for hosts running
;; the Michigan terminal system. It should be able to automatically
-;; recognize any MTS machine. However, if it fails to do this, you can use
+;; recognize any MTS machine. However, if it fails to do this, you can use
;; the command ange-ftp-add-mts-host. As well, you can set the variable
-;; ange-ftp-mts-host-regexp in your init file. We would be grateful if you
+;; ange-ftp-mts-host-regexp in your init file. We would be grateful if you
;; would report any failures to automatically recognize a MTS host as a bug.
;;
;; Filename syntax:
;;
-;; MTS filenames are entered in a UNIX-y way. For example, if your account
+;; MTS filenames are entered in a UNIX-y way. For example, if your account
;; was YYYY, the file FILE in the account XXXX: on mtsg.ubc.ca would be
;; entered as
;; /YYYY@mtsg.ubc.ca:/XXXX:/FILE
-;; In other words, MTS accounts are treated as UNIX directories. Of course,
+;; In other words, MTS accounts are treated as UNIX directories. Of course,
;; to access a file in another account, you must have access permission for
;; it. If FILE were in your own account, then you could enter it in a
;; relative name fashion as
;; /YYYY@mtsg.ubc.ca:FILE
-;; MTS filenames can be up to 12 characters. Like UNIX, the structure of the
+;; MTS filenames can be up to 12 characters. Like UNIX, the structure of the
;; filename does not contain a TYPE (i.e. it can have as many "."'s as you
;; like.) MTS filenames are always in upper case, and hence be sure to enter
;; them as such! MTS is not case sensitive, but an EMACS running under UNIX
@@ -359,37 +359,37 @@
;; CMS. It should be able to automatically recognize any CMS machine.
;; However, if it fails to do this, you can use the command
;; ange-ftp-add-cms-host. As well, you can set the variable
-;; ange-ftp-cms-host-regexp in your init file. We would be grateful if you
+;; ange-ftp-cms-host-regexp in your init file. We would be grateful if you
;; would report any failures to automatically recognize a CMS host as a bug.
;;
;; Filename syntax:
;;
-;; CMS filenames are entered in a UNIX-y way. In other words, minidisks are
-;; treated as UNIX directories. For example to access the file READ.ME in
+;; CMS filenames are entered in a UNIX-y way. In other words, minidisks are
+;; treated as UNIX directories. For example to access the file READ.ME in
;; minidisk *.311 on cuvmb.cc.columbia.edu, you would enter
;; /anonymous@cuvmb.cc.columbia.edu:/*.311/READ.ME
;; If *.301 is the default minidisk for this account, you could access
;; FOO.BAR on this minidisk as
;; /anonymous@cuvmb.cc.columbia.edu:FOO.BAR
;; CMS filenames are of the form FILE.TYPE, where both FILE and TYPE can be
-;; up to 8 characters. Again, beware that CMS filenames are always upper
+;; up to 8 characters. Again, beware that CMS filenames are always upper
;; case, and hence must be entered as such.
;;
;; Tips:
;; 1. CMS machines, with the exception of anonymous accounts, nearly always
-;; need an account password. To have ange-ftp send an account password,
+;; need an account password. To have ange-ftp send an account password,
;; you can either include it in your .netrc file, or use
;; ange-ftp-set-account.
-;; 2. Ange-ftp cannot send "write passwords" for a minidisk. Hopefully, we
+;; 2. Ange-ftp cannot send "write passwords" for a minidisk. Hopefully, we
;; can fix this.
;;
;; BS2000 support:
;;
;; Ange-ftp has full support for BS2000 hosts. It should be able to
-;; automatically recognize any BS2000 machine. However, if it fails to
+;; automatically recognize any BS2000 machine. However, if it fails to
;; do this, you can use the command ange-ftp-add-bs2000-host. As well,
;; you can set the variable ange-ftp-bs2000-host-regexp in your .emacs
-;; file. We would be grateful if you would report any failures to auto-
+;; file. We would be grateful if you would report any failures to auto-
;; matically recognize a BS2000 host as a bug.
;;
;; If you want to access the POSIX subsystem on BS2000 you MUST use
@@ -436,10 +436,10 @@
;; Therefore, to access a BS2000 file, you must enter the filename with
;; upper case letters.
;; 2. EMACS has a feature in which it does environment variable substitution
-;; in filenames. Therefore, to enter a $ in a filename, you must quote it
+;; in filenames. Therefore, to enter a $ in a filename, you must quote it
;; by typing $$.
;; 3. BS2000 machines, with the exception of anonymous accounts, nearly
-;; always need an account password. To have ange-ftp send an account
+;; always need an account password. To have ange-ftp send an account
;; password, you can either include it in your .netrc file, or use
;; ange-ftp-set-account.
;;
@@ -457,15 +457,15 @@
;;
;; 2. Some combinations of FTP clients and servers break and get out of sync
;; when asked to list a non-existent directory. Some of the ai.mit.edu
-;; machines cause this problem for some FTP clients. Using
+;; machines cause this problem for some FTP clients. Using
;; ange-ftp-kill-ftp-process can restart the ftp process, which
;; should get things back in sync.
;;
;; 3. Ange-ftp does not check to make sure that when creating a new file,
;; you provide a valid filename for the remote operating system.
;; If you do not, then the remote FTP server will most likely
-;; translate your filename in some way. This may cause ange-ftp to
-;; get confused about what exactly is the name of the file. The
+;; translate your filename in some way. This may cause ange-ftp to
+;; get confused about what exactly is the name of the file. The
;; most common causes of this are using lower case filenames on systems
;; which support only upper case, and using filenames which are too
;; long.
@@ -479,39 +479,39 @@
;; disgusting way around this problem is to talk to the FTP process via
;; rlogin which does the 'right' things with pty's.
;;
-;; 6. For CMS support, we send too many cd's. Since cd's are cheap, I haven't
-;; worried about this too much. Eventually, we should have some caching
+;; 6. For CMS support, we send too many cd's. Since cd's are cheap, I haven't
+;; worried about this too much. Eventually, we should have some caching
;; of the current minidisk.
;;
;; 7. Some CMS machines do not assign a default minidisk when you ftp them as
-;; anonymous. It is then necessary to guess a valid minidisk name, and cd
-;; to it. This is (understandably) beyond ange-ftp.
+;; anonymous. It is then necessary to guess a valid minidisk name, and cd
+;; to it. This is (understandably) beyond ange-ftp.
;;
;; 8. Remote to remote copying of files on non-Unix machines can be risky.
;; Depending on the variable ange-ftp-binary-file-name-regexp, ange-ftp
-;; will use binary mode for the copy. Between systems of different
+;; will use binary mode for the copy. Between systems of different
;; architecture, this still may not be enough to guarantee the integrity
-;; of binary files. Binary file transfers from VMS machines are
-;; particularly problematical. Should ange-ftp-binary-file-name-regexp be
+;; of binary files. Binary file transfers from VMS machines are
+;; particularly problematical. Should ange-ftp-binary-file-name-regexp be
;; an alist of OS type, regexp pairs?
;;
;; 9. The code to do compression of files over ftp is not as careful as it
-;; should be. It deletes the old remote version of the file, before
+;; should be. It deletes the old remote version of the file, before
;; actually checking if the local to remote transfer of the compressed
-;; file succeeds. Of course to delete the original version of the file
+;; file succeeds. Of course to delete the original version of the file
;; after transferring the compressed version back is also dangerous,
;; because some OS's have severe restrictions on the length of filenames,
;; and when the compressed version is copied back the "-Z" or ".Z" may be
-;; truncated. Then, ange-ftp would delete the only remaining version of
+;; truncated. Then, ange-ftp would delete the only remaining version of
;; the file. Maybe ange-ftp should make backups when it compresses files
;; (of course, the backup "~" could also be truncated off, sigh...).
;; Suggestions?
;;
;; 10. If a dir listing is attempted for an empty directory on (at least
-;; some) VMS hosts, an ftp error is given. This is really an ftp bug, and
+;; some) VMS hosts, an ftp error is given. This is really an ftp bug, and
;; I don't know how to get ange-ftp work to around it.
;;
-;; 11. Bombs on filenames that start with a space. Deals well with filenames
+;; 11. Bombs on filenames that start with a space. Deals well with filenames
;; containing spaces, but beware that the remote ftpd may not like them
;; much.
;;
@@ -519,13 +519,13 @@
;; It needs to be reimplemented by modifying the parse-...-listing
;; functions to convert the directory listing to ls -l format.
;;
-;; 13. The famous @ bug. As mentioned above in TIPS, ULTRIX marks symlinks
-;; with a trailing @ in a ls -alF listing. In order to account for this
+;; 13. The famous @ bug. As mentioned above in TIPS, ULTRIX marks symlinks
+;; with a trailing @ in a ls -alF listing. In order to account for this
;; ange-ftp looks to chop trailing @'s off of symlink names when it is
-;; parsing a listing with the F switch. This will cause ange-ftp to
+;; parsing a listing with the F switch. This will cause ange-ftp to
;; incorrectly get the name of a symlink on a non-ULTRIX host if its name
-;; ends in an @. ange-ftp will correct itself if you take F out of the
-;; dired ls switches (C-u s will allow you to edit the switches). The
+;; ends in an @. ange-ftp will correct itself if you take F out of the
+;; dired ls switches (C-u s will allow you to edit the switches). The
;; dired buffer will be automatically reverted, which will allow ange-ftp
;; to fix its files hashtable. A cookie to anyone who can think of a
;; fast, sure-fire way to recognize ULTRIX over ftp.
@@ -576,26 +576,26 @@
;; and the current code should eventually be made compliant.
;;
;; nil = local host type, whatever that is (probably unix).
-;; Think nil as in "not a remote host". This value is used by
+;; Think nil as in "not a remote host". This value is used by
;; ange-ftp-dired-host-type for local buffers.
;;
-;; t = a remote host of unknown type. Think t as in true, it's remote.
+;; t = a remote host of unknown type. Think t as in true, it's remote.
;; Currently, `unix' is used as the default remote host type.
;; Maybe we should use t.
;;
;; TYPE = a remote host of TYPE type.
;;
;; TYPE:LIST = a remote host of TYPE type, using a specialized ftp listing
-;; program called list. This is currently only used for Unix
+;; program called list. This is currently only used for Unix
;; dl (descriptive listings), when ange-ftp-dired-host-type
;; is set to `unix:dl'.
;; Bug report codes:
;;
;; Because of their naive faith in this code, there are certain situations
-;; which the writers of this program believe could never happen. However,
+;; which the writers of this program believe could never happen. However,
;; being realists they have put calls to `error' in the program at these
-;; points. These errors provide a code, which is an integer, greater than 1.
+;; points. These errors provide a code, which is an integer, greater than 1.
;; To aid debugging. the error codes, and the functions in which they reside
;; are listed below.
;;
@@ -1025,7 +1025,7 @@ or nil meaning don't change it."
"Buffer name to hold directory listing data received from FTP process.")
(defvar ange-ftp-netrc-modtime nil
- "Last modified time of the netrc file from file-attributes.")
+ "Last modified time of the netrc file from `file-attributes'.")
(defvar ange-ftp-user-hashtable (make-hash-table :test 'equal)
"Hash table holding associations between HOST, USER pairs.")
@@ -1230,8 +1230,9 @@ only return the directory part of FILE."
;; found another machine with the same user.
;; Try that account.
(read-passwd
- (format "passwd for %s@%s (default same as %s@%s): "
- user host user other)
+ (format-prompt "passwd for %s@%s"
+ (format "same as %s@%s" user other)
+ user host)
nil
(ange-ftp-lookup-passwd other user))
@@ -1357,7 +1358,7 @@ only return the directory part of FILE."
(defun ange-ftp-parse-netrc ()
;; We set this before actually doing it to avoid the possibility
- ;; of an infinite loop if ange-ftp-netrc-filename is an FTP file.
+ ;; of an infinite loop if `ange-ftp-netrc-filename' is an FTP file.
(interactive)
(let (file attr)
(let ((default-directory "/"))
@@ -2641,7 +2642,7 @@ away in the internal cache."
(ange-ftp-error host user
(concat "DIR failed: " (cdr result)))))
(ange-ftp-del-tmp-name temp))))
- (error "Should never happen. Please report. Bug ref. no.: 1"))))
+ (error "This should never happen; please report this as a bug"))))
;;;; ------------------------------------------------------------
;;;; Directory information caching support.
@@ -3591,11 +3592,11 @@ Value is (0 0) if the modification time cannot be determined."
(ange-ftp-real-verify-visited-file-modtime buf))))
(defun ange-ftp-file-size (file &optional ascii-mode)
- "Return the size of remote file FILE. Return -1 if can't get it.
-If ascii-mode is non-nil, return the size with the extra octets that
+ "Return the size of remote file FILE. Return -1 if can't get it.
+If ASCII-MODE is non-nil, return the size with the extra octets that
need to be inserted, one at the end of each line, to provide correct
-end-of-line semantics for a transfer using TYPE=A. The default is nil,
-so return the size on the remote host exactly. See RFC 3659."
+end-of-line semantics for a transfer using TYPE=A. The default is nil,
+so return the size on the remote host exactly. See RFC 3659."
(let* ((parsed (ange-ftp-ftp-name file))
(host (nth 0 parsed))
(user (nth 1 parsed))
@@ -4704,8 +4705,7 @@ NEWNAME should be the name to give the new compressed or uncompressed file.")
;; Can't use ange-ftp-dired-host-type here because the current
;; buffer is *dired-check-process output*
(condition-case oops
- (cond ((equal (or (bound-and-true-p dired-chmod-program) "chmod")
- program)
+ (cond ((equal "chmod" program)
(ange-ftp-call-chmod arguments))
;; ((equal "chgrp" program))
;; ((equal dired-chown-program program))
@@ -4724,7 +4724,7 @@ NEWNAME should be the name to give the new compressed or uncompressed file.")
;; by using the ftp chmod command.
(defun ange-ftp-call-chmod (args)
(if (< (length args) 2)
- (error "ange-ftp-call-chmod: missing mode and/or filename: %s" args))
+ (error "ange-ftp-call-chmod: Missing mode and/or filename: %s" args))
(let ((mode (car args))
(rest (cdr args)))
(if (equal "--" (car rest))
@@ -5135,7 +5135,7 @@ NEWNAME should be the name to give the new compressed or uncompressed file.")
(concat "/" drive "/"))
dir (and dir "/")
file))
- (error "name %s didn't match" name))
+ (error "Name %s didn't match" name))
(let (drive dir file tmp quote)
(if (string-match "\\`\".+\"\\'" name)
(setq name (substring name 1 -1)
@@ -5663,7 +5663,7 @@ Other orders of $ and _ seem to all work just fine.")
(setq file (match-string 2 name))
(concat (and acct (concat "/" acct "/"))
file))
- (error "name %s didn't match" name))
+ (error "Name %s didn't match" name))
(if (string-match "\\`/\\([^:]+:\\)/\\(.*\\)\\'" name)
(concat (match-string 1 name) (match-string 2 name))
;; Let's hope that mts will recognize it anyway.
@@ -6097,7 +6097,7 @@ Other orders of $ and _ seem to all work just fine.")
(and pubset (concat "_/" pubset "/"))
(and userid (concat userid "/"))
filename))
- (error "name %s didn't match" name))
+ (error "Name %s didn't match" name))
;; and here we (maybe) have to remove the inserted "_/" 'cause
;; of our prevention of the special escape prefix above:
(if (string-match (concat "^/_/") name)
diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el
index f739cd72cc3..b7840f05890 100644
--- a/lisp/net/browse-url.el
+++ b/lisp/net/browse-url.el
@@ -38,7 +38,8 @@
;; browse-url-firefox Firefox Don't know (tried with 1.0.1)
;; browse-url-chrome Chrome 47.0.2526.111
;; browse-url-chromium Chromium 3.0
-;; browse-url-epiphany Epiphany Don't know
+;; browse-url-epiphany GNOME Web (Epiphany) Don't know
+;; browse-url-webpositive WebPositive 1.2-alpha (Haiku R1/beta3)
;; browse-url-w3 w3 0
;; browse-url-text-* Any text browser 0
;; browse-url-generic arbitrary
@@ -155,7 +156,8 @@
(function-item :tag "Firefox" :value browse-url-firefox)
(function-item :tag "Google Chrome" :value browse-url-chrome)
(function-item :tag "Chromium" :value browse-url-chromium)
- (function-item :tag "Epiphany" :value browse-url-epiphany)
+ (function-item :tag "GNOME Web (Epiphany)" :value browse-url-epiphany)
+ (function-item :tag "WebPositive" :value browse-url-webpositive)
(function-item :tag "Text browser in an xterm window"
:value browse-url-text-xterm)
(function-item :tag "Text browser in an Emacs window"
@@ -219,7 +221,7 @@ be used instead."
(defcustom browse-url-button-regexp
(concat
- "\\b\\(\\(www\\.\\|\\(s?https?\\|ftp\\|file\\|gopher\\|"
+ "\\b\\(\\(www\\.\\|\\(s?https?\\|ftp\\|file\\|gopher\\|gemini\\|"
"nntp\\|news\\|telnet\\|wais\\|mailto\\|info\\):\\)"
"\\(//[-a-z0-9_.]+:[0-9]*\\)?"
(let ((chars "-a-z0-9_=#$@~%&*+\\/[:word:]")
@@ -238,33 +240,6 @@ be used instead."
:version "27.1"
:type 'regexp)
-(defcustom browse-url-netscape-program "netscape"
- ;; Info about netscape-remote from Karl Berry.
- "The name by which to invoke Netscape.
-
-The free program `netscape-remote' from
-<URL:http://home.netscape.com/newsref/std/remote.c> is said to start
-up very much quicker than `netscape'. Reported to compile on a GNU
-system, given vroot.h from the same directory, with cc flags
- -DSTANDALONE -L/usr/X11R6/lib -lXmu -lX11."
- :type 'string)
-
-(make-obsolete-variable 'browse-url-netscape-program nil "25.1")
-
-(defcustom browse-url-netscape-arguments nil
- "A list of strings to pass to Netscape as arguments."
- :type '(repeat (string :tag "Argument")))
-
-(make-obsolete-variable 'browse-url-netscape-arguments nil "25.1")
-
-(defcustom browse-url-netscape-startup-arguments browse-url-netscape-arguments
- "A list of strings to pass to Netscape when it starts up.
-Defaults to the value of `browse-url-netscape-arguments' at the time
-`browse-url' is loaded."
- :type '(repeat (string :tag "Argument")))
-
-(make-obsolete-variable 'browse-url-netscape-startup-arguments nil "25.1")
-
(defcustom browse-url-browser-display nil
"The X display for running the browser, if not same as Emacs's."
:type '(choice string (const :tag "Default" nil)))
@@ -283,11 +258,13 @@ Defaults to the value of `browse-url-mozilla-arguments' at the time
`browse-url' is loaded."
:type '(repeat (string :tag "Argument")))
+(defun browse-url--find-executable (candidates default)
+ (while (and candidates (not (executable-find (car candidates))))
+ (setq candidates (cdr candidates)))
+ (or (car candidates) default))
+
(defcustom browse-url-firefox-program
- (let ((candidates '("icecat" "iceweasel" "firefox")))
- (while (and candidates (not (executable-find (car candidates))))
- (setq candidates (cdr candidates)))
- (or (car candidates) "firefox"))
+ (browse-url--find-executable '("icecat" "iceweasel") "firefox")
"The name by which to invoke Firefox or a variant of it."
:type 'string)
@@ -305,10 +282,8 @@ Defaults to the value of `browse-url-firefox-arguments' at the time
"it no longer has any effect." "24.5")
(defcustom browse-url-chrome-program
- (let ((candidates '("google-chrome-stable" "google-chrome")))
- (while (and candidates (not (executable-find (car candidates))))
- (setq candidates (cdr candidates)))
- (or (car candidates) "chromium"))
+ (browse-url--find-executable '("google-chrome-stable" "google-chrome")
+ "chromium")
"The name by which to invoke the Chrome browser."
:type 'string
:version "25.1")
@@ -319,10 +294,7 @@ Defaults to the value of `browse-url-firefox-arguments' at the time
:version "25.1")
(defcustom browse-url-chromium-program
- (let ((candidates '("chromium" "chromium-browser")))
- (while (and candidates (not (executable-find (car candidates))))
- (setq candidates (cdr candidates)))
- (or (car candidates) "chromium"))
+ (browse-url--find-executable '("chromium" "chromium-browser") "chromium")
"The name by which to invoke Chromium."
:type 'string
:version "24.1")
@@ -332,41 +304,26 @@ Defaults to the value of `browse-url-firefox-arguments' at the time
:type '(repeat (string :tag "Argument"))
:version "24.1")
-(defcustom browse-url-galeon-program "galeon"
- "The name by which to invoke Galeon."
- :type 'string)
-
-(make-obsolete-variable 'browse-url-galeon-program nil "25.1")
-
-(defcustom browse-url-galeon-arguments nil
- "A list of strings to pass to Galeon as arguments."
- :type '(repeat (string :tag "Argument")))
-
-(make-obsolete-variable 'browse-url-galeon-arguments nil "25.1")
-
-(defcustom browse-url-galeon-startup-arguments browse-url-galeon-arguments
- "A list of strings to pass to Galeon when it starts up.
-Defaults to the value of `browse-url-galeon-arguments' at the time
-`browse-url' is loaded."
- :type '(repeat (string :tag "Argument")))
-
-(make-obsolete-variable 'browse-url-galeon-startup-arguments nil "25.1")
-
(defcustom browse-url-epiphany-program "epiphany"
- "The name by which to invoke Epiphany."
+ "The name by which to invoke GNOME Web (Epiphany)."
:type 'string)
(defcustom browse-url-epiphany-arguments nil
- "A list of strings to pass to Epiphany as arguments."
+ "A list of strings to pass to GNOME Web (Epiphany) as arguments."
:type '(repeat (string :tag "Argument")))
(defcustom browse-url-epiphany-startup-arguments browse-url-epiphany-arguments
- "A list of strings to pass to Epiphany when it starts up.
+ "A list of strings to pass to GNOME Web (Epiphany) when it starts up.
Defaults to the value of `browse-url-epiphany-arguments' at the time
`browse-url' is loaded."
:type '(repeat (string :tag "Argument")))
-;; GNOME means of invoking either Mozilla or Netscape.
+(defcustom browse-url-webpositive-program "WebPositive"
+ "The name by which to invoke WebPositive."
+ :type 'string
+ :version "29.1")
+
+;; GNOME means of invoking Mozilla.
(defvar browse-url-gnome-moz-program "gnome-moz-remote")
(make-obsolete-variable 'browse-url-gnome-moz-program nil "25.1")
@@ -399,29 +356,12 @@ If non-nil, then open the URL in a new buffer rather than a new window if
(make-obsolete-variable 'browse-url-conkeror-new-window-is-buffer nil "28.1")
-(defcustom browse-url-galeon-new-window-is-tab nil
- "Whether to open up new windows in a tab or a new window.
-If non-nil, then open the URL in a new tab rather than a new window if
-`browse-url-galeon' is asked to open it in a new window."
- :type 'boolean)
-
-(make-obsolete-variable 'browse-url-galeon-new-window-is-tab nil "25.1")
-
(defcustom browse-url-epiphany-new-window-is-tab nil
"Whether to open up new windows in a tab or a new window.
If non-nil, then open the URL in a new tab rather than a new window if
`browse-url-epiphany' is asked to open it in a new window."
:type 'boolean)
-(defcustom browse-url-netscape-new-window-is-tab nil
- "Whether to open up new windows in a tab or a new window.
-If non-nil, then open the URL in a new tab rather than a new
-window if `browse-url-netscape' is asked to open it in a new
-window."
- :type 'boolean)
-
-(make-obsolete-variable 'browse-url-netscape-new-window-is-tab nil "25.1")
-
(defcustom browse-url-new-window-flag nil
"Non-nil means always open a new browser window with appropriate browsers.
Passing an interactive argument to \\[browse-url], or specific browser
@@ -518,14 +458,6 @@ You might want to set this to somewhere with restricted read permissions
for privacy's sake."
:type 'string)
-(defcustom browse-url-netscape-version 3
- "The version of Netscape you are using.
-This affects how URL reloading is done; the mechanism changed
-incompatibly at version 4."
- :type 'number)
-
-(make-obsolete-variable 'browse-url-netscape-version nil "25.1")
-
(defcustom browse-url-text-browser "lynx"
"The name of the text browser to invoke."
:type 'string
@@ -692,16 +624,11 @@ alist is deprecated. Use `browse-url-handlers' instead.")
(defun browse-url-url-encode-chars (text chars)
"URL-encode the chars in TEXT that match CHARS.
-CHARS is a regexp-like character alternative (e.g., \"[)$]\")."
- (let ((encoded-text (copy-sequence text))
- (s 0))
- (while (setq s (string-match chars encoded-text s))
- (setq encoded-text
- (replace-match (format "%%%X"
- (string-to-char (match-string 0 encoded-text)))
- t t encoded-text)
- s (1+ s)))
- encoded-text))
+CHARS is a regexp that matches a character."
+ (replace-regexp-in-string chars
+ (lambda (s)
+ (format "%%%X" (string-to-char s)))
+ text))
(defun browse-url-encode-url (url)
"Escape annoying characters in URL.
@@ -710,7 +637,7 @@ regarding its parameter treatment."
;; FIXME: Is there an actual example of a web browser getting
;; confused? (This used to encode commas, but at least Firefox
;; handles commas correctly and doesn't accept encoded commas.)
- (browse-url-url-encode-chars url "[\")$] "))
+ (browse-url-url-encode-chars url "[\"()$ ]"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; URL input
@@ -735,7 +662,7 @@ position clicked before acting.
This function returns a list (URL NEW-WINDOW-FLAG)
for use in `interactive'."
(let ((event (elt (this-command-keys) 0)))
- (and (listp event) (mouse-set-point event)))
+ (mouse-set-point event))
(list (read-string prompt (or (and transient-mark-mode mark-active
;; rfc2396 Appendix E.
(replace-regexp-in-string
@@ -860,6 +787,8 @@ See `browse-url' for details."
;; A generic command to call the current browse-url-browser-function
+(declare-function pgtk-backend-display-class "pgtkfns.c" (&optional terminal))
+
;;;###autoload
(defun browse-url (url &rest args)
"Open URL using a configurable method.
@@ -897,8 +826,17 @@ If ARGS are omitted, the default is to pass
;; When connected to various displays, be careful to use the display of
;; the currently selected frame, rather than the original start display,
;; which may not even exist any more.
- (if (stringp (frame-parameter nil 'display))
- (setenv "DISPLAY" (frame-parameter nil 'display)))
+ (let ((dpy (frame-parameter nil 'display))
+ classname)
+ (if (stringp dpy)
+ (cond
+ ((featurep 'pgtk)
+ (setq classname (pgtk-backend-display-class))
+ (if (equal classname "GdkWaylandDisplay")
+ (setenv "WAYLAND_DISPLAY" dpy)
+ (setenv "DISPLAY" dpy)))
+ (t
+ (setenv "DISPLAY" dpy)))))
(if (functionp function)
(apply function url args)
(error "No suitable browser for URL %s" url))))
@@ -971,6 +909,7 @@ click but point is not changed."
"Invoke the MS-Windows system's default Web browser.
The optional NEW-WINDOW argument is not used."
(interactive (browse-url-interactive-arg "URL: "))
+ (setq url (browse-url-encode-url url))
(cond ((eq system-type 'ms-dos)
(if dos-windows-version
(shell-command (concat "start " (shell-quote-argument url)))
@@ -1000,13 +939,12 @@ The optional NEW-WINDOW argument is not used."
"Invoke the macOS system's default Web browser.
The optional NEW-WINDOW argument is not used."
(interactive (browse-url-interactive-arg "URL: "))
+ (setq url (browse-url-encode-url url))
(start-process (concat "open " url) nil "open" url))
(function-put 'browse-url-default-macosx-browser 'browse-url-browser-kind
'external)
-;; --- Netscape ---
-
(defun browse-url-process-environment ()
"Set DISPLAY in the environment to the X display the browser will use.
This is either the value of variable `browse-url-browser-display' if
@@ -1049,10 +987,9 @@ instead of `browse-url-new-window-flag'."
((executable-find browse-url-mozilla-program) 'browse-url-mozilla)
((executable-find browse-url-firefox-program) 'browse-url-firefox)
((executable-find browse-url-chromium-program) 'browse-url-chromium)
-;;; ((executable-find browse-url-galeon-program) 'browse-url-galeon)
((executable-find browse-url-kde-program) 'browse-url-kde)
-;;; ((executable-find browse-url-netscape-program) 'browse-url-netscape)
((executable-find browse-url-chrome-program) 'browse-url-chrome)
+ ((executable-find browse-url-webpositive-program) 'browse-url-webpositive)
((executable-find browse-url-xterm-program) 'browse-url-text-xterm)
((locate-library "w3") 'browse-url-w3)
(t
@@ -1085,82 +1022,6 @@ The optional argument IGNORED is not used."
(function-put 'browse-url-xdg-open 'browse-url-browser-kind 'external)
;;;###autoload
-(defun browse-url-netscape (url &optional new-window)
- "Ask the Netscape WWW browser to load URL.
-Default to the URL around or before point. The strings in variable
-`browse-url-netscape-arguments' are also passed to Netscape.
-
-When called interactively, if variable `browse-url-new-window-flag' is
-non-nil, load the document in a new Netscape window, otherwise use a
-random existing one. A non-nil interactive prefix argument reverses
-the effect of `browse-url-new-window-flag'.
-
-If `browse-url-netscape-new-window-is-tab' is non-nil, then
-whenever a document would otherwise be loaded in a new window, it
-is loaded in a new tab in an existing window instead.
-
-When called non-interactively, optional second argument NEW-WINDOW is
-used instead of `browse-url-new-window-flag'."
- (declare (obsolete nil "25.1"))
- (interactive (browse-url-interactive-arg "URL: "))
- (setq url (browse-url-encode-url url))
- (let* ((process-environment (browse-url-process-environment))
- (process
- (apply #'start-process
- (concat "netscape " url) nil
- browse-url-netscape-program
- (append
- browse-url-netscape-arguments
- (if (eq window-system 'w32)
- (list url)
- (append
- (if new-window '("-noraise"))
- (list "-remote"
- (concat "openURL(" url
- (if (browse-url-maybe-new-window
- new-window)
- (if browse-url-netscape-new-window-is-tab
- ",new-tab"
- ",new-window"))
- ")"))))))))
- (set-process-sentinel process
- (lambda (process _change)
- (browse-url-netscape-sentinel process url)))))
-
-(function-put 'browse-url-netscape 'browse-url-browser-kind 'external)
-
-(defun browse-url-netscape-sentinel (process url)
- "Handle a change to the process communicating with Netscape."
- (declare (obsolete nil "25.1"))
- (or (eq (process-exit-status process) 0)
- (let* ((process-environment (browse-url-process-environment)))
- ;; Netscape not running - start it
- (message "Starting %s..." browse-url-netscape-program)
- (apply #'start-process (concat "netscape" url) nil
- browse-url-netscape-program
- (append browse-url-netscape-startup-arguments (list url))))))
-
-(defun browse-url-netscape-reload ()
- "Ask Netscape to reload its current document.
-How depends on `browse-url-netscape-version'."
- (declare (obsolete nil "25.1"))
- (interactive)
- ;; Backwards incompatibility reported by
- ;; <peter.kruse@psychologie.uni-regensburg.de>.
- (browse-url-netscape-send (if (>= browse-url-netscape-version 4)
- "xfeDoCommand(reload)"
- "reload")))
-
-(defun browse-url-netscape-send (command)
- "Send a remote control command to Netscape."
- (declare (obsolete nil "25.1"))
- (let* ((process-environment (browse-url-process-environment)))
- (apply #'start-process "netscape" nil
- browse-url-netscape-program
- (append browse-url-netscape-arguments
- (list "-remote" command)))))
-
-;;;###autoload
(defun browse-url-mozilla (url &optional new-window)
"Ask the Mozilla WWW browser to load URL.
Default to the URL around or before point. The strings in variable
@@ -1280,63 +1141,13 @@ The optional argument NEW-WINDOW is not used."
(function-put 'browse-url-chrome 'browse-url-browser-kind 'external)
-;;;###autoload
-(defun browse-url-galeon (url &optional new-window)
- "Ask the Galeon WWW browser to load URL.
-Default to the URL around or before point. The strings in variable
-`browse-url-galeon-arguments' are also passed to Galeon.
-
-When called interactively, if variable `browse-url-new-window-flag' is
-non-nil, load the document in a new Galeon window, otherwise use a
-random existing one. A non-nil interactive prefix argument reverses
-the effect of `browse-url-new-window-flag'.
-
-If `browse-url-galeon-new-window-is-tab' is non-nil, then whenever a
-document would otherwise be loaded in a new window, it is loaded in a
-new tab in an existing window instead.
-
-When called non-interactively, optional second argument NEW-WINDOW is
-used instead of `browse-url-new-window-flag'."
- (declare (obsolete nil "25.1"))
- (interactive (browse-url-interactive-arg "URL: "))
- (setq url (browse-url-encode-url url))
- (let* ((process-environment (browse-url-process-environment))
- (process (apply #'start-process
- (concat "galeon " url)
- nil
- browse-url-galeon-program
- (append
- browse-url-galeon-arguments
- (if (browse-url-maybe-new-window new-window)
- (if browse-url-galeon-new-window-is-tab
- '("--new-tab")
- '("--new-window" "--noraise"))
- '("--existing"))
- (list url)))))
- (set-process-sentinel process
- (lambda (process _change)
- (browse-url-galeon-sentinel process url)))))
-
-(function-put 'browse-url-galeon 'browse-url-browser-kind 'external)
-
-(defun browse-url-galeon-sentinel (process url)
- "Handle a change to the process communicating with Galeon."
- (declare (obsolete nil "25.1"))
- (or (eq (process-exit-status process) 0)
- (let* ((process-environment (browse-url-process-environment)))
- ;; Galeon is not running - start it
- (message "Starting %s..." browse-url-galeon-program)
- (apply #'start-process (concat "galeon " url) nil
- browse-url-galeon-program
- (append browse-url-galeon-startup-arguments (list url))))))
-
(defun browse-url-epiphany (url &optional new-window)
- "Ask the Epiphany WWW browser to load URL.
+ "Ask the GNOME Web (Epiphany) WWW browser to load URL.
Default to the URL around or before point. The strings in variable
-`browse-url-galeon-arguments' are also passed to Epiphany.
+`browse-url-epiphany-arguments' are also passed to GNOME Web.
When called interactively, if variable `browse-url-new-window-flag' is
-non-nil, load the document in a new Epiphany window, otherwise use a
+non-nil, load the document in a new GNOME Web window, otherwise use a
random existing one. A non-nil interactive prefix argument reverses
the effect of `browse-url-new-window-flag'.
@@ -1368,10 +1179,10 @@ used instead of `browse-url-new-window-flag'."
(function-put 'browse-url-epiphany 'browse-url-browser-kind 'external)
(defun browse-url-epiphany-sentinel (process url)
- "Handle a change to the process communicating with Epiphany."
+ "Handle a change to the process communicating with GNOME Web (Epiphany)."
(or (eq (process-exit-status process) 0)
(let* ((process-environment (browse-url-process-environment)))
- ;; Epiphany is not running - start it
+ ;; GNOME Web is not running - start it
(message "Starting %s..." browse-url-epiphany-program)
(apply #'start-process (concat "epiphany " url) nil
browse-url-epiphany-program
@@ -1380,6 +1191,18 @@ used instead of `browse-url-new-window-flag'."
(defvar url-handler-regexp)
;;;###autoload
+(defun browse-url-webpositive (url &optional _new-window)
+ "Ask the WebPositive WWW browser to load URL.
+Default to the URL around or before point.
+The optional argument NEW-WINDOW is not used."
+ (interactive (browse-url-interactive-arg "URL: "))
+ (setq url (browse-url-encode-url url))
+ (let* ((process-environment (browse-url-process-environment)))
+ (start-process (concat "WebPositive " url) nil "WebPositive" url)))
+
+(function-put 'browse-url-webpositive 'browse-url-browser-kind 'external)
+
+;;;###autoload
(defun browse-url-emacs (url &optional same-window)
"Ask Emacs to load URL into a buffer and show it in another window.
Optional argument SAME-WINDOW non-nil means show the URL in the
@@ -1401,7 +1224,7 @@ currently selected window instead."
;;;###autoload
(defun browse-url-gnome-moz (url &optional new-window)
- "Ask Mozilla/Netscape to load URL via the GNOME program `gnome-moz-remote'.
+ "Ask Mozilla to load URL via the GNOME program `gnome-moz-remote'.
Default to the URL around or before point. The strings in variable
`browse-url-gnome-moz-arguments' are also passed.
@@ -1603,7 +1426,7 @@ used instead of `browse-url-new-window-flag'."
;; --- mailto ---
-(autoload 'rfc2368-parse-mailto-url "rfc2368")
+(autoload 'rfc6068-parse-mailto-url "rfc6068")
;;;###autoload
(defun browse-url-mail (url &optional new-window)
@@ -1622,7 +1445,7 @@ When called non-interactively, optional second argument NEW-WINDOW is
used instead of `browse-url-new-window-flag'."
(interactive (browse-url-interactive-arg "Mailto URL: "))
(save-excursion
- (let* ((alist (rfc2368-parse-mailto-url url))
+ (let* ((alist (rfc6068-parse-mailto-url url))
(to (assoc "To" alist))
(subject (assoc "Subject" alist))
(body (assoc "Body" alist))
@@ -1757,11 +1580,11 @@ from `browse-url-elinks-wrapper'."
(define-key map [mouse-2] #'browse-url-button-open)
(define-key map "w" #'browse-url-button-copy)
map)
- "The keymap used for browse-url buttons.")
+ "The keymap used for `browse-url' buttons.")
(defface browse-url-button
'((t :inherit link))
- "Face for browse-url buttons (i.e., links)."
+ "Face for `browse-url' buttons (i.e., links)."
:version "27.1")
(defun browse-url-add-buttons ()
@@ -1780,6 +1603,7 @@ clickable and will use `browse-url' to open the URLs in question."
category browse-url
browse-url-data ,(match-string 0)))))))
+;;;###autoload
(defun browse-url-button-open (&optional external mouse-event)
"Follow the link under point using `browse-url'.
If EXTERNAL (the prefix if used interactively), open with the
diff --git a/lisp/net/dbus.el b/lisp/net/dbus.el
index 4116d293e1b..411249767f5 100644
--- a/lisp/net/dbus.el
+++ b/lisp/net/dbus.el
@@ -2073,7 +2073,8 @@ either a method name, a signal name, or an error name."
(goto-char point)))
(defun dbus-monitor-handler (&rest _args)
- "Default handler for the \"org.freedesktop.DBus.Monitoring.BecomeMonitor\" interface.
+ "Default handler for the \"Monitoring.BecomeMonitor\" interface.
+Its full name is \"org.freedesktop.DBus.Monitoring.BecomeMonitor\".
It will be applied for all objects created by `dbus-register-monitor'
which don't declare an own handler. The printed timestamps do
not reflect the time the D-Bus message has passed the D-Bus
@@ -2101,7 +2102,7 @@ has been handled by this function."
(interface (dbus-event-interface-name event))
(member (dbus-event-member-name event))
(arguments (dbus-event-arguments event))
- (time (time-to-seconds (current-time))))
+ (time (float-time)))
(save-excursion
;; Check for matching method-call.
(goto-char (point-max))
@@ -2251,15 +2252,19 @@ keywords `:system-private' or `:session-private', respectively."
bus nil dbus-path-local dbus-interface-local
"Disconnected" #'dbus-handle-bus-disconnect)))
-
-;; Initialize `:system' and `:session' buses. This adds their file
-;; descriptors to input_wait_mask, in order to detect incoming
-;; messages immediately.
-(when (featurep 'dbusbind)
- (dbus-ignore-errors
- (dbus-init-bus :system))
- (dbus-ignore-errors
- (dbus-init-bus :session)))
+
+(defun dbus--init ()
+ ;; Initialize `:system' and `:session' buses. This adds their file
+ ;; descriptors to input_wait_mask, in order to detect incoming
+ ;; messages immediately.
+ (when (featurep 'dbusbind)
+ (dbus-ignore-errors
+ (dbus-init-bus :system))
+ (dbus-ignore-errors
+ (dbus-init-bus :session))))
+
+(add-hook 'after-pdump-load-hook #'dbus--init)
+(dbus--init)
(provide 'dbus)
diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el
index f33cbaf1126..1d07989ef57 100644
--- a/lisp/net/dictionary.el
+++ b/lisp/net/dictionary.el
@@ -25,9 +25,9 @@
;; dictionary allows you to interact with dictionary servers.
;; Use M-x customize-group dictionary to modify user settings.
;;
-;; Main functions for interaction are:
-;; dictionary - opens a new dictionary buffer
-;; dictionary-search - search for the definition of a word
+;; Main commands for interaction are:
+;; M-x dictionary - opens a new dictionary buffer
+;; M-x dictionary-search - search for the definition of a word
;;
;; You can find more information in the README file of the GitHub
;; repository https://github.com/myrkr/dictionary-el
@@ -58,11 +58,11 @@ the existing connection."
(set-default name value))
(defgroup dictionary nil
- "Client for accessing the dictd server based dictionaries"
+ "Client for accessing the dictd server based dictionaries."
:group 'hypermedia)
(defgroup dictionary-proxy nil
- "Proxy configuration options for the dictionary client"
+ "Proxy configuration options for the dictionary client."
:group 'dictionary)
(defcustom dictionary-server
@@ -86,7 +86,7 @@ You can specify here:
(defcustom dictionary-port
2628
"The port of the dictionary server.
-This port is propably always 2628 so there should be no need to modify it."
+This port is probably always 2628 so there should be no need to modify it."
:group 'dictionary
:set #'dictionary-set-server-var
:type 'number
@@ -943,7 +943,6 @@ If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
(defun dictionary-set-dictionary (param &optional more)
"Select the dictionary which is the car of PARAM as new default."
-
(if more
(dictionary-display-more-info param)
(let ((dictionary (car param)))
@@ -1050,8 +1049,7 @@ If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
'dictionary-display-match-result)))
(defun dictionary-do-matching (word dictionary strategy function)
- "Find matches for WORD with STRATEGY in DICTIONARY and display them with FUNCTION."
-
+ "Search for WORD with STRATEGY in DICTIONARY and display them with FUNCTION."
(message "Lookup matching words for %s in %s using %s"
word dictionary strategy)
(dictionary-send-command
@@ -1211,7 +1209,6 @@ allows editing it."
(save-excursion
(mouse-set-point event)
(current-word)))))
- (selected-window)
(dictionary-popup-matching-words word)))
;;;###autoload
@@ -1315,9 +1312,9 @@ allows editing it."
"Turn off or on support for the dictionary tooltip mode.
It is normally internally called with 1 to enable support for the
-tooltip mode. The hook function will check the value of the
-variable dictionary-tooltip-mode to decide if some action must be
-taken. When disabling the tooltip mode the value of this variable
+tooltip mode. The hook function will check the value of the
+variable `dictionary-tooltip-mode' to decide if some action must be
+taken. When disabling the tooltip mode the value of this variable
will be set to nil."
(interactive)
(tooltip-mode on)
@@ -1348,10 +1345,10 @@ active it will overwrite that mode for the current buffer."
;;;###autoload
(defun global-dictionary-tooltip-mode (&optional arg)
- "Enable/disable dictionary-tooltip-mode for all buffers.
+ "Enable/disable `dictionary-tooltip-mode' for all buffers.
-Internally it provides a default for the dictionary-tooltip-mode.
-It can be overwritten for each buffer using dictionary-tooltip-mode.
+Internally it provides a default for the `dictionary-tooltip-mode'.
+It can be overwritten for each buffer using `dictionary-tooltip-mode'.
Note: (global-dictionary-tooltip-mode 0) will not disable the mode
any buffer where (dictionary-tooltip-mode 1) has been called."
@@ -1368,5 +1365,30 @@ any buffer where (dictionary-tooltip-mode 1) has been called."
(if on #'dictionary-tooltip-track-mouse #'ignore))
on))
+;;; Context menu support
+
+(defun dictionary-search-word-at-mouse (event)
+ (interactive "e")
+ (let ((word (save-window-excursion
+ (save-excursion
+ (mouse-set-point event)
+ (current-word)))))
+ (dictionary-search word)))
+
+;;;###autoload
+(defun context-menu-dictionary (menu click)
+ "Populate MENU with dictionary commands at CLICK.
+When you add this function to `context-menu-functions',
+the context menu will contain an item that searches
+the word at mouse click."
+ (when (thing-at-mouse click 'word)
+ (define-key-after menu [dictionary-separator] menu-bar-separator
+ 'middle-separator)
+ (define-key-after menu [dictionary-search-word-at-mouse]
+ '(menu-item "Dictionary Search" dictionary-search-word-at-mouse
+ :help "Search the word at mouse click in dictionary")
+ 'dictionary-separator))
+ menu)
+
(provide 'dictionary)
;;; dictionary.el ends here
diff --git a/lisp/net/eudc-bob.el b/lisp/net/eudc-bob.el
index 1d7af7f5b5f..7ad92b22af7 100644
--- a/lisp/net/eudc-bob.el
+++ b/lisp/net/eudc-bob.el
@@ -252,17 +252,14 @@ display a button."
;; If the first arguments can be nil here, then these 3 can be
;; defconsts once more.
-(easy-menu-define eudc-bob-generic-menu
- eudc-bob-generic-keymap
- ""
+(easy-menu-define eudc-bob-generic-menu eudc-bob-generic-keymap
+ "EUDC Binary Object Menu."
eudc-bob-generic-menu)
-(easy-menu-define eudc-bob-image-menu
- eudc-bob-image-keymap
- ""
+(easy-menu-define eudc-bob-image-menu eudc-bob-image-keymap
+ "EUDC Image Menu."
eudc-bob-image-menu)
-(easy-menu-define eudc-bob-sound-menu
- eudc-bob-sound-keymap
- ""
+(easy-menu-define eudc-bob-sound-menu eudc-bob-sound-keymap
+ "EUDC Sound Menu."
eudc-bob-sound-menu)
;;;###autoload
diff --git a/lisp/net/eudc-hotlist.el b/lisp/net/eudc-hotlist.el
index a737a99ce95..43c1a2886f6 100644
--- a/lisp/net/eudc-hotlist.el
+++ b/lisp/net/eudc-hotlist.el
@@ -174,9 +174,8 @@ These are the special commands of this mode:
["Save and Quit" eudc-hotlist-quit-edit t]
["Exit without Saving" kill-this-buffer t]))
-(easy-menu-define eudc-hotlist-emacs-menu
- eudc-hotlist-mode-map
- ""
+(easy-menu-define eudc-hotlist-emacs-menu eudc-hotlist-mode-map
+ "EUDC hotlist Menu."
eudc-hotlist-menu)
;;; eudc-hotlist.el ends here
diff --git a/lisp/net/eudc.el b/lisp/net/eudc.el
index 6459c52afee..62c2913b50a 100644
--- a/lisp/net/eudc.el
+++ b/lisp/net/eudc.el
@@ -25,7 +25,7 @@
;;; Commentary:
;; This package provides a common interface to query directory servers using
;; different protocols such as LDAP, CCSO PH/QI or BBDB. Queries can be
-;; made through an interactive form or inline. Inline query strings in
+;; made through an interactive form or inline. Inline query strings in
;; buffers are expanded with appropriately formatted query results
;; (especially used to expand email addresses in message buffers). EUDC
;; also interfaces with the BBDB package to let you register query results
@@ -46,16 +46,9 @@
;;; Code:
(require 'wid-edit)
-
(require 'cl-lib)
-
-(unless (fboundp 'custom-menu-create)
- (autoload 'custom-menu-create "cus-edit"))
-
(require 'eudc-vars)
-
-
;;{{{ Internal cooking
;;{{{ Internal variables and compatibility tricks
@@ -664,7 +657,7 @@ If ERROR is non-nil, report an error if there is none."
(let ((result (eudc-query (list (cons 'name name)) '(email)))
email)
(if (null (cdr result))
- (setq email (cl-cdaar result))
+ (setq email (cdaar result))
(error "Multiple match--use the query form"))
(if error
(if email
@@ -682,7 +675,7 @@ If ERROR is non-nil, report an error if there is none."
(let ((result (eudc-query (list (cons 'name name)) '(phone)))
phone)
(if (null (cdr result))
- (setq phone (cl-cdaar result))
+ (setq phone (cdaar result))
(error "Multiple match--use the query form"))
(if error
(if phone
@@ -798,8 +791,9 @@ see `eudc-inline-expansion-servers'."
"Query the directory server, and return the matching responses.
The variable `eudc-inline-query-format' controls how to associate the
individual QUERY-WORDS with directory attribute names.
-After querying the server for the given string, the expansion specified by
-`eudc-inline-expansion-format' is applied to the matches before returning them.inserted in the buffer at point.
+After querying the server for the given string, the expansion
+specified by `eudc-inline-expansion-format' is applied to the
+matches before returning them.inserted in the buffer at point.
Multiple servers can be tried with the same query until one finds a match,
see `eudc-inline-expansion-servers'."
(cond
diff --git a/lisp/net/eudcb-ldap.el b/lisp/net/eudcb-ldap.el
index 0aff276475e..fc486567265 100644
--- a/lisp/net/eudcb-ldap.el
+++ b/lisp/net/eudcb-ldap.el
@@ -202,7 +202,7 @@ attribute names are returned. Default to `person'."
"Check if the current LDAP server has a configured search base."
(unless (or (eudc-ldap-get-host-parameter eudc-server 'base)
ldap-default-base
- (null (y-or-n-p "No search base defined. Configure it now? ")))
+ (null (y-or-n-p "No search base defined. Configure it now?")))
;; If the server is not in ldap-host-parameters-alist we add it for the
;; user
(if (null (assoc eudc-server ldap-host-parameters-alist))
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index 90301e92acf..0c66cf3a0d7 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -36,7 +36,7 @@
(eval-when-compile (require 'subr-x))
(defgroup eww nil
- "Emacs Web Wowser"
+ "Emacs Web Wowser."
:version "25.1"
:link '(custom-manual "(eww) Top")
:group 'web
@@ -57,7 +57,7 @@
:type 'string)
(defcustom eww-use-browse-url "\\`mailto:"
- "eww will use `browse-url' when following links that match this regexp.
+ "EWW will use `browse-url' when following links that match this regexp.
The action to be taken can be further customized via
`browse-url-handlers'."
:version "28.1"
@@ -143,12 +143,14 @@ The string will be passed through `substitute-command-keys'."
(defcustom eww-retrieve-command nil
"Command to retrieve an URL via an external program.
-If nil, `url-retrieve' is used to download the data. If non-nil,
-this should be a list where the first item is the program, and
-the rest are the arguments."
+If nil, `url-retrieve' is used to download the data.
+If `sync', `url-retrieve-synchronously' is used.
+For other non-nil values, this should be a list of strings where
+the first item is the program, and the rest are the arguments."
:version "28.1"
:type '(choice (const :tag "Use `url-retrieve'" nil)
- (repeat string)))
+ (const :tag "Use `url-retrieve-synchronously'" sync)
+ (repeat :tag "Command/args" string )))
(defcustom eww-use-external-browser-for-content-type
"\\`\\(video/\\|audio/\\|application/ogg\\)"
@@ -176,6 +178,40 @@ the tab bar is enabled."
:group 'eww
:type 'hook)
+(defcustom eww-auto-rename-buffer nil
+ "Automatically rename EWW buffers once the page is rendered.
+
+When nil, do not rename the buffer. With a non-nil value
+determine the renaming scheme, as follows:
+
+- `title': Use the web page's title.
+- `url': Use the web page's URL.
+- a function's symbol: Run a user-defined function that returns a
+ string with which to rename the buffer. Sample of a
+ user-defined function:
+
+ (defun my-eww-rename-buffer ()
+ (when (eq major-mode 'eww-mode)
+ (when-let ((string (or (plist-get eww-data :title)
+ (plist-get eww-data :url))))
+ (format \"*%s*\" string))))
+
+The string of `title' and `url' is always truncated to the value
+of `eww-buffer-name-length'."
+ :version "29.1"
+ :type '(choice
+ (const :tag "Do not rename buffers (default)" nil)
+ (const :tag "Rename buffer to web page title" title)
+ (const :tag "Rename buffer to web page URL" url)
+ (function :tag "A user-defined function to rename the buffer"))
+ :group 'eww)
+
+(defcustom eww-buffer-name-length 40
+ "Length of renamed buffer name, per `eww-auto-rename-buffer'."
+ :type 'natnum
+ :version "29.1"
+ :group 'eww)
+
(defcustom eww-form-checkbox-selected-symbol "[X]"
"Symbol used to represent a selected checkbox.
See also `eww-form-checkbox-symbol'."
@@ -195,8 +231,15 @@ See also `eww-form-checkbox-selected-symbol'."
(const "☐") ; Unicode BALLOT BOX
string))
+(defcustom eww-url-transformers '(eww-remove-tracking)
+ "This is a list of transforming functions applied to an URL before usage.
+The functions will be called with the URL as the single
+parameter, and should return the (possibly) transformed URL."
+ :type '(repeat function)
+ :version "29.1")
+
(defface eww-form-submit
- '((((type x w32 ns) (class color)) ; Like default mode line
+ '((((type x w32 ns haiku pgtk) (class color)) ; Like default mode line
:box (:line-width 2 :style released-button)
:background "#808080" :foreground "black"))
"Face for eww buffer buttons."
@@ -204,7 +247,7 @@ See also `eww-form-checkbox-selected-symbol'."
:group 'eww)
(defface eww-form-file
- '((((type x w32 ns) (class color)) ; Like default mode line
+ '((((type x w32 ns haiku pgtk) (class color)) ; Like default mode line
:box (:line-width 2 :style released-button)
:background "#808080" :foreground "black"))
"Face for eww buffer buttons."
@@ -212,7 +255,7 @@ See also `eww-form-checkbox-selected-symbol'."
:group 'eww)
(defface eww-form-checkbox
- '((((type x w32 ns) (class color)) ; Like default mode line
+ '((((type x w32 ns haiku pgtk) (class color)) ; Like default mode line
:box (:line-width 2 :style released-button)
:background "lightgrey" :foreground "black"))
"Face for eww buffer buttons."
@@ -220,7 +263,7 @@ See also `eww-form-checkbox-selected-symbol'."
:group 'eww)
(defface eww-form-select
- '((((type x w32 ns) (class color)) ; Like default mode line
+ '((((type x w32 ns haiku pgtk) (class color)) ; Like default mode line
:box (:line-width 2 :style released-button)
:background "lightgrey" :foreground "black"))
"Face for eww buffer buttons."
@@ -269,15 +312,13 @@ See also `eww-form-checkbox-selected-symbol'."
"text/html, text/plain, text/sgml, text/css, application/xhtml+xml, */*;q=0.01"
"Value used for the HTTP 'Accept' header.")
-(defvar eww-link-keymap
- (let ((map (copy-keymap shr-map)))
- (define-key map "\r" 'eww-follow-link)
- map))
+(defvar-keymap eww-link-keymap
+ :parent shr-map
+ "RET" #'eww-follow-link)
-(defvar eww-image-link-keymap
- (let ((map (copy-keymap shr-image-map)))
- (define-key map "\r" 'eww-follow-link)
- map))
+(defvar-keymap eww-image-link-keymap
+ :parent shr-map
+ "RET" #'eww-follow-link)
(defun eww-suggested-uris nil
"Return the list of URIs to suggest at the `eww' prompt.
@@ -311,13 +352,13 @@ will start Emacs and browse the GNU web site."
;;;###autoload
-(defun eww (url &optional arg buffer)
+(defun eww (url &optional new-buffer buffer)
"Fetch URL and render the page.
If the input doesn't look like an URL or a domain name, the
word(s) will be searched for via `eww-search-prefix'.
-If called with a prefix ARG, use a new buffer instead of reusing
-the default EWW buffer.
+If NEW-BUFFER is non-nil (interactively, the prefix arg), use a
+new buffer instead of reusing the default EWW buffer.
If BUFFER, the data to be rendered is in that buffer. In that
case, this function doesn't actually fetch URL. BUFFER will be
@@ -327,11 +368,11 @@ killed after rendering."
(list (read-string (format-prompt "Enter URL or keywords"
(and uris (car uris)))
nil 'eww-prompt-history uris)
- (prefix-numeric-value current-prefix-arg))))
+ current-prefix-arg)))
(setq url (eww--dwim-expand-url url))
(pop-to-buffer-same-window
(cond
- ((eq arg 4)
+ (new-buffer
(generate-new-buffer "*eww*"))
((eq major-mode 'eww-mode)
(current-buffer))
@@ -351,9 +392,10 @@ killed after rendering."
(while (string-match "\\`/[.][.]/" (url-filename parsed))
(setf (url-filename parsed) (substring (url-filename parsed) 3))))
(setq url (url-recreate-url parsed)))
+ (setq url (eww--transform-url url))
(plist-put eww-data :url url)
(plist-put eww-data :title "")
- (eww-update-header-line-format)
+ (eww--after-page-change)
(let ((inhibit-read-only t))
(insert (format "Loading %s..." url))
(goto-char (point-min)))
@@ -366,9 +408,16 @@ killed after rendering."
(list url nil (current-buffer))))))
(defun eww-retrieve (url callback cbargs)
- (if (null eww-retrieve-command)
- (url-retrieve url #'eww-render
- (list url nil (current-buffer)))
+ (cond
+ ((null eww-retrieve-command)
+ (url-retrieve url #'eww-render
+ (list url nil (current-buffer))))
+ ((eq eww-retrieve-command 'sync)
+ (let ((orig-buffer (current-buffer))
+ (data-buffer (url-retrieve-synchronously url)))
+ (with-current-buffer data-buffer
+ (eww-render nil url nil orig-buffer))))
+ (t
(let ((buffer (generate-new-buffer " *eww retrieve*"))
(error-buffer (generate-new-buffer " *eww error*")))
(with-current-buffer buffer
@@ -388,7 +437,7 @@ killed after rendering."
(with-current-buffer buffer
(goto-char (point-min))
(insert "Content-type: text/html; charset=utf-8\n\n")
- (apply #'funcall callback nil cbargs))))))))))
+ (apply #'funcall callback nil cbargs)))))))))))
(function-put 'eww 'browse-url-browser-kind 'internal)
@@ -495,6 +544,30 @@ Currently this means either text/html or application/xhtml+xml."
(member content-type '("text/html"
"application/xhtml+xml")))
+(defun eww--rename-buffer ()
+ "Rename the current EWW buffer.
+The renaming scheme is performed in accordance with
+`eww-auto-rename-buffer'."
+ (let ((rename-string)
+ (formatter
+ (lambda (string)
+ (format "*%s # eww*" (truncate-string-to-width
+ string eww-buffer-name-length))))
+ (site-title (plist-get eww-data :title))
+ (site-url (plist-get eww-data :url)))
+ (cond ((null eww-auto-rename-buffer))
+ ((eq eww-auto-rename-buffer 'url)
+ (setq rename-string (funcall formatter site-url)))
+ ((functionp eww-auto-rename-buffer)
+ (setq rename-string (funcall eww-auto-rename-buffer)))
+ (t (setq rename-string
+ (funcall formatter (if (or (equal site-title "")
+ (null site-title))
+ "Untitled"
+ site-title)))))
+ (when rename-string
+ (rename-buffer rename-string t))))
+
(defun eww-render (status url &optional point buffer encode)
(let* ((headers (eww-parse-headers))
(content-type
@@ -545,7 +618,7 @@ Currently this means either text/html or application/xhtml+xml."
(eww-display-raw buffer (or encode charset 'utf-8))))
(with-current-buffer buffer
(plist-put eww-data :url url)
- (eww-update-header-line-format)
+ (eww--after-page-change)
(setq eww-history-position 0)
(and last-coding-system-used
(set-buffer-file-coding-system last-coding-system-used))
@@ -629,7 +702,8 @@ Currently this means either text/html or application/xhtml+xml."
(meta . eww-tag-meta)
(a . eww-tag-a)))))
(erase-buffer)
- (shr-insert-document document)
+ (with-delayed-message (2 "Rendering HTML...")
+ (shr-insert-document document))
(cond
(point
(goto-char point))
@@ -668,9 +742,12 @@ Currently this means either text/html or application/xhtml+xml."
("home" . :home)
("contents" . :contents)
("up" . :up)))))
- (and href
- where
- (plist-put eww-data (cdr where) href))))
+ (when (and href where)
+ (when (memq (cdr where) '(:next :previous))
+ ;; Multi-page isearch support.
+ (setq-local multi-isearch-next-buffer-function
+ #'eww-isearch-next-buffer))
+ (plist-put eww-data (cdr where) href))))
(defvar eww-redirect-level 1)
@@ -786,12 +863,16 @@ Currently this means either text/html or application/xhtml+xml."
`((?u . ,(or url ""))
(?t . ,title))))))))
+(defun eww--after-page-change ()
+ (eww-update-header-line-format)
+ (eww--rename-buffer))
+
(defun eww-tag-title (dom)
(plist-put eww-data :title
(replace-regexp-in-string
"^ \\| $" ""
(replace-regexp-in-string "[ \t\r\n]+" " " (dom-text dom))))
- (eww-update-header-line-format))
+ (eww--after-page-change))
(defun eww-display-raw (buffer &optional encode)
(let ((data (buffer-substring (point) (point-max))))
@@ -840,6 +921,8 @@ Currently this means either text/html or application/xhtml+xml."
(remove-overlays)
(erase-buffer))
(setq bidi-paragraph-direction nil)
+ ;; 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)))
@@ -917,7 +1000,7 @@ the like."
nil (current-buffer))
(dolist (elem '(:source :url :title :next :previous :up))
(plist-put eww-data elem (plist-get old-data elem)))
- (eww-update-header-line-format)))
+ (eww--after-page-change)))
(defun eww-score-readability (node)
(let ((score -1))
@@ -959,69 +1042,70 @@ the like."
(setq result highest))))
result))
-(defvar eww-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "g" 'eww-reload) ;FIXME: revert-buffer-function instead!
- (define-key map "G" 'eww)
- (define-key map [?\M-\r] 'eww-open-in-new-buffer)
- (define-key map [?\t] 'shr-next-link)
- (define-key map [?\M-\t] 'shr-previous-link)
- (define-key map [backtab] 'shr-previous-link)
- (define-key map [delete] 'scroll-down-command)
- (define-key map "l" 'eww-back-url)
- (define-key map "r" 'eww-forward-url)
- (define-key map "n" 'eww-next-url)
- (define-key map "p" 'eww-previous-url)
- (define-key map "u" 'eww-up-url)
- (define-key map "t" 'eww-top-url)
- (define-key map "&" 'eww-browse-with-external-browser)
- (define-key map "d" 'eww-download)
- (define-key map "w" 'eww-copy-page-url)
- (define-key map "C" 'url-cookie-list)
- (define-key map "v" 'eww-view-source)
- (define-key map "R" 'eww-readable)
- (define-key map "H" 'eww-list-histories)
- (define-key map "E" 'eww-set-character-encoding)
- (define-key map "s" 'eww-switch-to-buffer)
- (define-key map "S" 'eww-list-buffers)
- (define-key map "F" 'eww-toggle-fonts)
- (define-key map "D" 'eww-toggle-paragraph-direction)
- (define-key map [(meta C)] 'eww-toggle-colors)
- (define-key map [(meta I)] 'eww-toggle-images)
-
- (define-key map "b" 'eww-add-bookmark)
- (define-key map "B" 'eww-list-bookmarks)
- (define-key map [(meta n)] 'eww-next-bookmark)
- (define-key map [(meta p)] 'eww-previous-bookmark)
-
- (easy-menu-define nil map ""
- '("Eww"
- ["Exit" quit-window t]
- ["Close browser" quit-window t]
- ["Reload" eww-reload t]
- ["Follow URL in new buffer" eww-open-in-new-buffer]
- ["Back to previous page" eww-back-url
- :active (not (zerop (length eww-history)))]
- ["Forward to next page" eww-forward-url
- :active (not (zerop eww-history-position))]
- ["Browse with external browser" eww-browse-with-external-browser t]
- ["Download" eww-download t]
- ["View page source" eww-view-source]
- ["Copy page URL" eww-copy-page-url t]
- ["List histories" eww-list-histories t]
- ["Switch to buffer" eww-switch-to-buffer t]
- ["List buffers" eww-list-buffers t]
- ["Add bookmark" eww-add-bookmark t]
- ["List bookmarks" eww-list-bookmarks t]
- ["List cookies" url-cookie-list t]
- ["Toggle fonts" eww-toggle-fonts t]
- ["Toggle colors" eww-toggle-colors t]
- ["Toggle images" eww-toggle-images t]
- ["Character Encoding" eww-set-character-encoding]
- ["Toggle Paragraph Direction" eww-toggle-paragraph-direction]))
- map))
-
-(defun eww-context-menu (menu)
+(defvar-keymap eww-mode-map
+ "g" #'eww-reload ;FIXME: revert-buffer-function instead!
+ "G" #'eww
+ "M-RET" #'eww-open-in-new-buffer
+ "TAB" #'shr-next-link
+ "C-M-i" #'shr-previous-link
+ "<backtab>" #'shr-previous-link
+ "<delete>" #'scroll-down-command
+ "l" #'eww-back-url
+ "r" #'eww-forward-url
+ "n" #'eww-next-url
+ "p" #'eww-previous-url
+ "u" #'eww-up-url
+ "t" #'eww-top-url
+ "&" #'eww-browse-with-external-browser
+ "d" #'eww-download
+ "w" #'eww-copy-page-url
+ "C" #'url-cookie-list
+ "v" #'eww-view-source
+ "R" #'eww-readable
+ "H" #'eww-list-histories
+ "E" #'eww-set-character-encoding
+ "s" #'eww-switch-to-buffer
+ "S" #'eww-list-buffers
+ "F" #'eww-toggle-fonts
+ "D" #'eww-toggle-paragraph-direction
+ "M-C" #'eww-toggle-colors
+ "M-I" #'eww-toggle-images
+
+ "b" #'eww-add-bookmark
+ "B" #'eww-list-bookmarks
+ "M-n" #'eww-next-bookmark
+ "M-p" #'eww-previous-bookmark
+
+ "<mouse-8>" #'eww-back-url
+ "<mouse-9>" #'eww-forward-url
+
+ :menu '("Eww"
+ ["Exit" quit-window t]
+ ["Close browser" quit-window t]
+ ["Reload" eww-reload t]
+ ["Follow URL in new buffer" eww-open-in-new-buffer]
+ ["Back to previous page" eww-back-url
+ :active (not (zerop (length eww-history)))]
+ ["Forward to next page" eww-forward-url
+ :active (not (zerop eww-history-position))]
+ ["Browse with external browser" eww-browse-with-external-browser t]
+ ["Download" eww-download t]
+ ["View page source" eww-view-source]
+ ["Copy page URL" eww-copy-page-url t]
+ ["List histories" eww-list-histories t]
+ ["Switch to buffer" eww-switch-to-buffer t]
+ ["List buffers" eww-list-buffers t]
+ ["Add bookmark" eww-add-bookmark t]
+ ["List bookmarks" eww-list-bookmarks t]
+ ["List cookies" url-cookie-list t]
+ ["Toggle fonts" eww-toggle-fonts t]
+ ["Toggle colors" eww-toggle-colors t]
+ ["Toggle images" eww-toggle-images t]
+ ["Character Encoding" eww-set-character-encoding]
+ ["Toggle Paragraph Direction" eww-toggle-paragraph-direction]))
+
+(defun eww-context-menu (menu click)
+ "Populate MENU with eww commands at CLICK."
(define-key menu [eww-separator] menu-bar-separator)
(let ((easy-menu (make-sparse-keymap "Eww")))
(easy-menu-define nil easy-menu nil
@@ -1035,8 +1119,8 @@ the like."
(when (consp item)
(define-key menu (vector (car item)) (cdr item)))))
- (when (or (mouse-posn-property (event-start last-input-event) 'shr-url)
- (mouse-posn-property (event-start last-input-event) 'image-url))
+ (when (or (mouse-posn-property (event-start click) 'shr-url)
+ (mouse-posn-property (event-start click) 'image-url))
(define-key menu [shr-mouse-browse-url-new-window]
`(menu-item "Follow URL in new window" ,(if browse-url-new-window-flag
'shr-mouse-browse-url
@@ -1068,7 +1152,9 @@ the like."
;; Autoload cookie needed by desktop.el.
;;;###autoload
(define-derived-mode eww-mode special-mode "eww"
- "Mode for browsing the web."
+ "Mode for browsing the web.
+
+\\{eww-mode-map}"
:interactive nil
(setq-local eww-data (list :title ""))
(setq-local browse-url-browser-function #'eww-browse-url)
@@ -1080,12 +1166,11 @@ the like."
(setq-local tool-bar-map eww-tool-bar-map))
;; desktop support
(setq-local desktop-save-buffer #'eww-desktop-misc-data)
- ;; multi-page isearch support
- (setq-local multi-isearch-next-buffer-function #'eww-isearch-next-buffer)
(setq truncate-lines t)
(setq-local thing-at-point-provider-alist
(append thing-at-point-provider-alist
'((url . eww--url-at-point))))
+ (setq-local bookmark-make-record-function #'eww-bookmark-make-record)
(buffer-disable-undo)
(setq buffer-read-only t))
@@ -1150,7 +1235,7 @@ instead of `browse-url-new-window-flag'."
(goto-char (plist-get elem :point))
;; Make buffer listings more informative.
(setq list-buffers-directory (plist-get elem :url))
- (eww-update-header-line-format))))
+ (eww--after-page-change))))
(defun eww-next-url ()
"Go to the page marked `next'.
@@ -1214,54 +1299,43 @@ just re-display the HTML already fetched."
(defvar eww-form nil)
-(defvar eww-submit-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\r" 'eww-submit)
- (define-key map [(control c) (control c)] 'eww-submit)
- map))
-
-(defvar eww-submit-file
- (let ((map (make-sparse-keymap)))
- (define-key map "\r" 'eww-select-file)
- (define-key map [(control c) (control c)] 'eww-submit)
- map))
-
-(defvar eww-checkbox-map
- (let ((map (make-sparse-keymap)))
- (define-key map " " 'eww-toggle-checkbox)
- (define-key map "\r" 'eww-toggle-checkbox)
- (define-key map [(control c) (control c)] 'eww-submit)
- map))
-
-(defvar eww-text-map
- (let ((map (make-keymap)))
- (set-keymap-parent map text-mode-map)
- (define-key map "\r" 'eww-submit)
- (define-key map [(control a)] 'eww-beginning-of-text)
- (define-key map [(control c) (control c)] 'eww-submit)
- (define-key map [(control e)] 'eww-end-of-text)
- (define-key map [?\t] 'shr-next-link)
- (define-key map [?\M-\t] 'shr-previous-link)
- (define-key map [backtab] 'shr-previous-link)
- map))
-
-(defvar eww-textarea-map
- (let ((map (make-keymap)))
- (set-keymap-parent map text-mode-map)
- (define-key map "\r" 'forward-line)
- (define-key map [(control c) (control c)] 'eww-submit)
- (define-key map [?\t] 'shr-next-link)
- (define-key map [?\M-\t] 'shr-previous-link)
- (define-key map [backtab] 'shr-previous-link)
- map))
-
-(defvar eww-select-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\r" 'eww-change-select)
- (define-key map [follow-link] 'mouse-face)
- (define-key map [mouse-2] 'eww-change-select)
- (define-key map [(control c) (control c)] 'eww-submit)
- map))
+(defvar-keymap eww-submit-map
+ "RET" #'eww-submit
+ "C-c C-c" #'eww-submit)
+
+(defvar-keymap eww-submit-file
+ "RET" #'eww-select-file
+ "C-c C-c" #'eww-submit)
+
+(defvar-keymap eww-checkbox-map
+ "SPC" #'eww-toggle-checkbox
+ "RET" #'eww-toggle-checkbox
+ "C-c C-c" #'eww-submit)
+
+(defvar-keymap eww-text-map
+ :full t :parent text-mode-map
+ "RET" #'eww-submit
+ "C-a" #'eww-beginning-of-text
+ "C-c C-c" #'eww-submit
+ "C-e" #'eww-end-of-text
+ "TAB" #'shr-next-link
+ "M-TAB" #'shr-previous-link
+ "<backtab>" #'shr-previous-link)
+
+(defvar-keymap eww-textarea-map
+ :full t :parent text-mode-map
+ "RET" #'forward-line
+ "C-c C-c" #'eww-submit
+ "TAB" #'shr-next-link
+ "M-TAB" #'shr-previous-link
+ "<backtab>" #'shr-previous-link)
+
+(defvar-keymap eww-select-map
+ :doc "Map for select buttons"
+ "RET" #'eww-change-select
+ "<follow-link>" 'mouse-face
+ "<mouse-2>" #'eww-change-select
+ "C-c C-c" #'eww-submit)
(defun eww-beginning-of-text ()
"Move to the start of the input field."
@@ -1768,6 +1842,17 @@ The browser to used is specified by the
(funcall browse-url-secondary-browser-function
(or url (plist-get eww-data :url))))
+(defun eww-remove-tracking (url)
+ "Remove the commong utm_ tracking cookies from URLs."
+ (replace-regexp-in-string ".utm_.*" "" url))
+
+(defun eww--transform-url (url)
+ "Appy `eww-url-transformers'."
+ (when url
+ (dolist (func eww-url-transformers)
+ (setq url (funcall func url)))
+ url))
+
(defun eww-follow-link (&optional external mouse-event)
"Browse the URL under point.
If EXTERNAL is single prefix, browse the URL using
@@ -1778,7 +1863,8 @@ If EXTERNAL is double prefix, browse in new buffer."
(list current-prefix-arg last-nonmenu-event)
eww-mode)
(mouse-set-point mouse-event)
- (let ((url (get-text-property (point) 'shr-url)))
+ (let* ((orig-url (get-text-property (point) 'shr-url))
+ (url (eww--transform-url orig-url)))
(cond
((not url)
(message "No link under point"))
@@ -1797,7 +1883,7 @@ If EXTERNAL is double prefix, browse in new buffer."
(plist-put eww-data :url url)
(eww-display-html 'utf-8 url dom nil (current-buffer))))
(t
- (eww-browse-url url external)))))
+ (eww-browse-url orig-url external)))))
(defun eww-same-page-p (url1 url2)
"Return non-nil if URL1 and URL2 represent the same page.
@@ -1885,7 +1971,7 @@ Use link at point if there is one, else the current page's URL."
(defun eww-set-character-encoding (charset)
"Set character encoding to CHARSET.
If CHARSET is nil then use UTF-8."
- (interactive "zUse character set (default utf-8): " eww-mode)
+ (interactive "zUse character set (default `utf-8'): " eww-mode)
(if (null charset)
(eww-reload nil 'utf-8)
(eww-reload nil charset)))
@@ -2084,23 +2170,18 @@ If ERROR-OUT, signal user-error if there are no bookmarks."
'eww-bookmark)))
(eww-browse-url (plist-get bookmark :url))))
-(defvar eww-bookmark-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [(control k)] 'eww-bookmark-kill)
- (define-key map [(control y)] 'eww-bookmark-yank)
- (define-key map "\r" 'eww-bookmark-browse)
-
- (easy-menu-define nil map
- "Menu for `eww-bookmark-mode-map'."
- '("Eww Bookmark"
- ["Exit" quit-window t]
- ["Browse" eww-bookmark-browse
- :active (get-text-property (line-beginning-position) 'eww-bookmark)]
- ["Kill" eww-bookmark-kill
- :active (get-text-property (line-beginning-position) 'eww-bookmark)]
- ["Yank" eww-bookmark-yank
- :active eww-bookmark-kill-ring]))
- map))
+(defvar-keymap eww-bookmark-mode-map
+ "C-k" #'eww-bookmark-kill
+ "C-y" #'eww-bookmark-yank
+ "RET" #'eww-bookmark-browse
+ :menu '("Eww Bookmark"
+ ["Exit" quit-window t]
+ ["Browse" eww-bookmark-browse
+ :active (get-text-property (line-beginning-position) 'eww-bookmark)]
+ ["Kill" eww-bookmark-kill
+ :active (get-text-property (line-beginning-position) 'eww-bookmark)]
+ ["Yank" eww-bookmark-yank
+ :active eww-bookmark-kill-ring]))
(define-derived-mode eww-bookmark-mode special-mode "eww bookmarks"
"Mode for listing bookmarks.
@@ -2165,19 +2246,15 @@ If ERROR-OUT, signal user-error if there are no bookmarks."
(pop-to-buffer-same-window buffer)))
(eww-restore-history history)))
-(defvar eww-history-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\r" 'eww-history-browse)
- (define-key map "n" 'next-line)
- (define-key map "p" 'previous-line)
-
- (easy-menu-define nil map
- "Menu for `eww-history-mode-map'."
- '("Eww History"
- ["Exit" quit-window t]
- ["Browse" eww-history-browse
- :active (get-text-property (line-beginning-position) 'eww-history)]))
- map))
+(defvar-keymap eww-history-mode-map
+ "RET" #'eww-history-browse
+ "n" #'next-line
+ "p" #'previous-line
+ :menu '("Eww History"
+ ["Exit" quit-window t]
+ ["Browse" eww-history-browse
+ :active (get-text-property (line-beginning-position)
+ 'eww-history)]))
(define-derived-mode eww-history-mode special-mode "eww history"
"Mode for listing eww-histories.
@@ -2288,22 +2365,18 @@ If ERROR-OUT, signal user-error if there are no bookmarks."
(forward-line -1))
(eww-buffer-show))
-(defvar eww-buffers-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [(control k)] 'eww-buffer-kill)
- (define-key map "\r" 'eww-buffer-select)
- (define-key map "n" 'eww-buffer-show-next)
- (define-key map "p" 'eww-buffer-show-previous)
-
- (easy-menu-define nil map
- "Menu for `eww-buffers-mode-map'."
- '("Eww Buffers"
- ["Exit" quit-window t]
- ["Select" eww-buffer-select
- :active (get-text-property (line-beginning-position) 'eww-buffer)]
- ["Kill" eww-buffer-kill
- :active (get-text-property (line-beginning-position) 'eww-buffer)]))
- map))
+(defvar-keymap eww-buffers-mode-map
+ "C-k" #'eww-buffer-kill
+ "RET" #'eww-buffer-select
+ "n" #'eww-buffer-show-next
+ "p" #'eww-buffer-show-previous
+ :menu '("Eww Buffers"
+ ["Exit" quit-window t]
+ ["Select" eww-buffer-select
+ :active (get-text-property (line-beginning-position) 'eww-buffer)]
+ ["Kill" eww-buffer-kill
+ :active (get-text-property (line-beginning-position)
+ 'eww-buffer)]))
(define-derived-mode eww-buffers-mode special-mode "eww buffers"
"Mode for listing buffers.
@@ -2394,15 +2467,38 @@ Otherwise, the restored buffer will contain a prompt to do so by using
(defun eww-isearch-next-buffer (&optional _buffer wrap)
"Go to the next page to search using `rel' attribute for navigation."
- (if wrap
- (condition-case nil
- (eww-top-url)
- (error nil))
- (if isearch-forward
- (eww-next-url)
- (eww-previous-url)))
+ (let ((eww-retrieve-command 'sync))
+ (if wrap
+ (condition-case nil
+ (eww-top-url)
+ (error nil))
+ (if isearch-forward
+ (eww-next-url)
+ (eww-previous-url))))
(current-buffer))
+;;; bookmark.el support
+
+(declare-function bookmark-make-record-default
+ "bookmark" (&optional no-file no-context posn))
+(declare-function bookmark-prop-get "bookmark" (bookmark prop))
+
+(defun eww-bookmark-name ()
+ "Create a default bookmark name for the current EWW buffer."
+ (plist-get eww-data :title))
+
+(defun eww-bookmark-make-record ()
+ "Create a bookmark for the current EWW buffer."
+ `(,(eww-bookmark-name)
+ ,@(bookmark-make-record-default t)
+ (location . ,(plist-get eww-data :url))
+ (handler . eww-bookmark-jump)))
+
+;;;###autoload
+(defun eww-bookmark-jump (bookmark)
+ "Default bookmark handler for EWW buffers."
+ (eww (bookmark-prop-get bookmark 'location)))
+
(provide 'eww)
;;; eww.el ends here
diff --git a/lisp/net/gnutls.el b/lisp/net/gnutls.el
index 43dd9dc15cd..7b1ea2e765e 100644
--- a/lisp/net/gnutls.el
+++ b/lisp/net/gnutls.el
@@ -226,7 +226,7 @@ trust and key files, and priority string."
trustfiles crlfiles keylist min-prime-bits
verify-flags verify-error verify-hostname-error
&allow-other-keys)
- "Negotiate a SSL/TLS connection. Returns proc. Signals gnutls-error.
+ "Negotiate a SSL/TLS connection. Return proc. Signal gnutls-error.
Note that arguments are passed CL style, :type TYPE instead of just TYPE.
diff --git a/lisp/net/goto-addr.el b/lisp/net/goto-addr.el
index 2c43d0f7532..848bad3b0d6 100644
--- a/lisp/net/goto-addr.el
+++ b/lisp/net/goto-addr.el
@@ -124,8 +124,9 @@ will have no effect.")
m)
"Keymap to hold goto-addr's mouse key defs under highlighted URLs.")
-(defun goto-address-context-menu (menu)
- (when (mouse-posn-property (event-start last-input-event) 'goto-address)
+(defun goto-address-context-menu (menu click)
+ "Populate MENU with `goto-address' commands at CLICK."
+ (when (mouse-posn-property (event-start click) 'goto-address)
(define-key menu [goto-address-separator] menu-bar-separator)
(define-key menu [goto-address-at-mouse]
'(menu-item "Follow Link" goto-address-at-mouse
diff --git a/lisp/net/hmac-def.el b/lisp/net/hmac-def.el
index 5ea8839699d..5778857ff80 100644
--- a/lisp/net/hmac-def.el
+++ b/lisp/net/hmac-def.el
@@ -34,9 +34,10 @@ HMAC function is H(KEY XOR opad, H(KEY XOR ipad, TEXT)):
H is a cryptographic hash function, such as SHA1 and MD5, which takes
a string and return a digest of it (in binary form).
-B is a byte-length of a block size of H. (B=64 for both SHA1 and MD5.)
-L is a byte-length of hash outputs. (L=16 for MD5, L=20 for SHA1.)
+B is a byte length of a block size of H. (B=64 for both SHA1 and MD5.)
+L is a byte length of hash outputs. (L=16 for MD5, L=20 for SHA1.)
If BIT is non-nil, truncate output to specified bits."
+ (declare (indent defun))
`(defun ,name (text key)
,(concat "Compute "
(upcase (symbol-name name))
diff --git a/lisp/net/ldap.el b/lisp/net/ldap.el
index 7997bf3c90b..8b35a2d8e16 100644
--- a/lisp/net/ldap.el
+++ b/lisp/net/ldap.el
@@ -51,7 +51,8 @@ a separator."
(defcustom ldap-default-port nil
"Default TCP port for LDAP connections.
-Initialized from the LDAP library at build time. Default value is 389."
+Initialized from the LDAP library at build time.
+Default value is 389."
:type '(choice (const :tag "Use library default" nil)
(integer :tag "Port number")))
@@ -153,8 +154,7 @@ Valid properties include:
(string :tag "Argument")))
(defcustom ldap-ldapsearch-password-prompt-regexp "Enter LDAP Password: "
- "A regular expression used to recognize the `ldapsearch'
-program's password prompt."
+ "Regexp used to recognize the `ldapsearch' program's password prompt."
:type 'regexp
:version "25.1")
diff --git a/lisp/net/mailcap.el b/lisp/net/mailcap.el
index 5473ba7e697..14d49251f55 100644
--- a/lisp/net/mailcap.el
+++ b/lisp/net/mailcap.el
@@ -55,7 +55,7 @@ you have an entry for \"image/*\" in your ~/.mailcap file."
"A syntax table for parsing SGML attributes.")
(defvar mailcap-print-command
- (mapconcat 'identity
+ (mapconcat #'identity
(cons (if (boundp 'lpr-command)
lpr-command
"lpr")
@@ -93,7 +93,7 @@ The elements of the list are alists of the following structure
(type . MIME-TYPE)
(test . TEST))
-where VIEWER is either a lisp command, e.g., a major-mode, or a
+where VIEWER is either a Lisp command, e.g., a major mode, or a
string containing a shell command for viewing files of the
defined MIME-TYPE. In case of a shell command, %s will be
replaced with the file.
@@ -101,7 +101,7 @@ replaced with the file.
MIME-TYPE is a regular expression being matched against the
actual MIME type. It is implicitly surrounded with ^ and $.
-TEST is a lisp form which is evaluated in order to test if the
+TEST is a Lisp form which is evaluated in order to test if the
entry should be chosen. The `test' entry is optional.
When selecting a viewer for a given MIME type, the first viewer
@@ -116,8 +116,7 @@ is consulted."
(regexp :tag "MIME Type")
(sexp :tag "Test (optional)")))
:get #'mailcap--get-user-mime-data
- :set #'mailcap--set-user-mime-data
- :group 'mailcap)
+ :set #'mailcap--set-user-mime-data)
;; Postpone using defcustom for this as it's so big and we essentially
;; have to have two copies of the data around then. Perhaps just
@@ -344,8 +343,7 @@ Same format as `mailcap-mime-data'.")
"Directory to which `mailcap-save-binary-file' downloads files by default.
nil means your home directory."
:type '(choice (const :tag "Home directory" nil)
- directory)
- :group 'mailcap)
+ directory))
(defvar mailcap-poor-system-types
'(ms-dos windows-nt)
@@ -423,14 +421,6 @@ MAILCAPS if set; otherwise (on Unix) use the path from RFC 1524, plus
(interactive (list nil t))
(when (or (not mailcap-parsed-p)
force)
- ;; Clear out all old data.
- (setq mailcap--computed-mime-data nil)
- ;; Add the Emacs-distributed defaults (which will be used as
- ;; fallbacks). Do it this way instead of just copying the list,
- ;; since entries are destructively modified.
- (cl-loop for (major . minors) in mailcap-mime-data
- do (cl-loop for (minor . entry) in minors
- do (mailcap-add-mailcap-entry major minor entry)))
(cond
(path nil)
((getenv "MAILCAPS")
@@ -447,18 +437,26 @@ MAILCAPS if set; otherwise (on Unix) use the path from RFC 1524, plus
("/etc/mailcap" system)
("/usr/etc/mailcap" system)
("/usr/local/etc/mailcap" system)))))
- ;; The ~/.mailcap entries will end up first in the resulting data.
- (dolist (spec (reverse
- (if (stringp path)
- (split-string path path-separator t)
- path)))
- (let ((source (and (consp spec) (cadr spec)))
- (file-name (if (stringp spec)
- spec
- (car spec))))
- (when (and (file-readable-p file-name)
- (file-regular-p file-name))
- (mailcap-parse-mailcap file-name source))))
+ (when (stringp path)
+ (setq path (mapcar #'list (split-string path path-separator t))))
+ (when (seq-some (lambda (f)
+ (file-has-changed-p (car f) 'mail-parse-mailcaps))
+ path)
+ ;; Clear out all old data.
+ (setq mailcap--computed-mime-data nil)
+ ;; Add the Emacs-distributed defaults (which will be used as
+ ;; fallbacks). Do it this way instead of just copying the list,
+ ;; since entries are destructively modified.
+ (cl-loop for (major . minors) in mailcap-mime-data
+ do (cl-loop for (minor . entry) in minors
+ do (mailcap-add-mailcap-entry major minor entry)))
+ ;; The ~/.mailcap entries will end up first in the resulting data.
+ (dolist (spec (reverse path))
+ (let ((source (cadr spec))
+ (file-name (car spec)))
+ (when (and (file-readable-p file-name)
+ (file-regular-p file-name))
+ (mailcap-parse-mailcap file-name source)))))
(setq mailcap-parsed-p t)))
(defun mailcap-parse-mailcap (fname &optional source)
@@ -636,7 +634,7 @@ the test clause will be unchanged."
((and (listp test) (symbolp (car test))) test)
((or (stringp test)
(and (listp test) (stringp (car test))
- (setq test (mapconcat 'identity test " "))))
+ (setq test (mapconcat #'identity test " "))))
(with-temp-buffer
(insert test)
(goto-char (point-min))
@@ -707,12 +705,12 @@ to supply to the test."
(symbol-value test))
((and (listp test) ; List to be eval'd
(symbolp (car test)))
- (eval test))
+ (eval test t))
(t
(setq test (mailcap-unescape-mime-test test type-info)
test (list shell-file-name nil nil nil
shell-command-switch test)
- status (apply 'call-process test))
+ status (apply #'call-process test))
(eq 0 status))))
(push (list otest result) mailcap-viewer-test-cache)
result))))
@@ -837,7 +835,7 @@ If NO-DECODE is non-nil, don't decode STRING."
(dolist (entry viewers)
(when (mailcap-viewer-passes-test entry info)
(push entry passed)))
- (setq passed (sort (nreverse passed) 'mailcap-viewer-lessp))
+ (setq passed (sort (nreverse passed) #'mailcap-viewer-lessp))
;; When we want to prefer entries from the user's
;; ~/.mailcap file, then we filter out the system entries
;; and see whether we have anything left.
@@ -1065,12 +1063,21 @@ For instance, \"foo.png\" will result in \"image/png\"."
(match-string 1 file-name)
"")))
+;;;###autoload
+(defun mailcap-mime-type-to-extension (mime-type)
+ "Return a file name extension based on a MIME-TYPE.
+For instance, `image/png' will result in `png'."
+ (intern (cadr (split-string (if (symbolp mime-type)
+ (symbol-name mime-type)
+ mime-type)
+ "/"))))
+
(defun mailcap-mime-types ()
"Return a list of MIME media types."
(mailcap-parse-mimetypes)
(delete-dups
(nconc
- (mapcar 'cdr mailcap-mime-extensions)
+ (mapcar #'cdr mailcap-mime-extensions)
(let (res type)
(dolist (data mailcap--computed-mime-data)
(dolist (info (cdr data))
diff --git a/lisp/net/mairix.el b/lisp/net/mairix.el
index 727aa55de58..3feb089ad05 100644
--- a/lisp/net/mairix.el
+++ b/lisp/net/mairix.el
@@ -24,7 +24,7 @@
;; This is an interface to the mairix mail search engine. Mairix is
;; written by Richard Curnow and is licensed under the GPL. See the
-;; home page for details:
+;; Mairix website for details:
;;
;; http://www.rpcurnow.force9.co.uk/mairix/
;;
diff --git a/lisp/net/net-utils.el b/lisp/net/net-utils.el
index 90cca7d415c..6f44d9844ef 100644
--- a/lisp/net/net-utils.el
+++ b/lisp/net/net-utils.el
@@ -885,9 +885,9 @@ and `network-connection-service-alist', which see."
:type '(repeat (cons string string)))
(defcustom whois-guess-server t
- "If non-nil then whois will try to deduce the appropriate whois
-server from the query. If the query doesn't look like a domain or hostname
-then the server named by `whois-server-name' is used."
+ "If non-nil, try to deduce the appropriate whois server from the query.
+If the query doesn't look like a domain or hostname then the
+server named by `whois-server-name' is used."
:type 'boolean)
(defun whois-get-tld (host)
@@ -943,7 +943,7 @@ The port is deduced from `network-connection-service-alist'."
;; Using a derived mode gives us keymaps, hooks, etc.
(define-derived-mode
network-connection-mode comint-mode "Network-Connection"
- "Major mode for interacting with the network-connection program.")
+ "Major mode for interacting with the `network-connection' program.")
(defun network-connection-mode-setup (host service)
(setq-local network-connection-host host)
diff --git a/lisp/net/newst-backend.el b/lisp/net/newst-backend.el
index dc541943587..d51f8c0189f 100644
--- a/lisp/net/newst-backend.el
+++ b/lisp/net/newst-backend.el
@@ -4,7 +4,7 @@
;; Author: Ulf Jasper <ulf.jasper@web.de>
;; Filename: newst-backend.el
-;; URL: http://www.nongnu.org/newsticker
+;; URL: https://www.nongnu.org/newsticker
;; Keywords: News, RSS, Atom
;; Package: newsticker
@@ -402,13 +402,6 @@ headline after it has been retrieved for the first time."
"Miscellaneous newsticker settings."
:group 'newsticker)
-(defcustom newsticker-cache-filename
- "~/.newsticker-cache"
- "Name of the newsticker cache file."
- :type 'string
- :group 'newsticker-miscellaneous)
-(make-obsolete-variable 'newsticker-cache-filename 'newsticker-dir "23.1")
-
(defcustom newsticker-dir
(locate-user-emacs-file "newsticker/" ".newsticker/")
"Directory where newsticker saves data."
@@ -1211,8 +1204,7 @@ URL `http://www.atompub.org/2005/08/17/draft-ietf-atompub-format-11.html'"
Return value as well as arguments NAME, TIME, and TOPNODE are the
same as in `newsticker--parse-atom-1.0'.
-For the RSS 0.91 specification see URL `http://backend.userland.com/rss091'
-or URL `http://my.netscape.com/publish/formats/rss-spec-0.91.html'."
+For the RSS 0.91 specification see URL `http://backend.userland.com/rss091'."
(newsticker--debug-msg "Parsing RSS 0.91 feed %s" name)
(let* ((channelnode (car (xml-get-children topnode 'channel)))
is-new-feed has-new-items)
@@ -2115,28 +2107,6 @@ well."
(throw 'result t)))))
(< (or (newsticker--pos item1) 0) (or (newsticker--pos item2) 0))))
-(defun newsticker--cache-save-version1 ()
- "Update and save newsticker cache file."
- (interactive)
- (newsticker--cache-update t))
-
-(defun newsticker--cache-update (&optional save)
- "Update newsticker cache file.
-If optional argument SAVE is not nil the cache file is saved to disk."
- (save-excursion
- (unless (file-directory-p newsticker-dir)
- (make-directory newsticker-dir t))
- (let ((coding-system-for-write 'utf-8)
- (buf (find-file-noselect newsticker-cache-filename)))
- (when buf
- (set-buffer buf)
- (setq buffer-undo-list t)
- (erase-buffer)
- (insert ";; -*- coding: utf-8 -*-\n")
- (insert (prin1-to-string newsticker--cache))
- (when save
- (save-buffer))))))
-
(defun newsticker--cache-get-feed (feed)
"Return the cached data for the feed FEED.
FEED is a symbol!"
@@ -2163,30 +2133,11 @@ FEED is a symbol!"
(insert ";; -*- coding: utf-8 -*-\n")
(insert (prin1-to-string (cdr feed)))))))
-(defun newsticker--cache-read-version1 ()
- "Read version1 cache data."
- (let ((coding-system-for-read 'utf-8))
- (when (file-exists-p newsticker-cache-filename)
- (with-temp-buffer
- (insert-file-contents newsticker-cache-filename)
- (goto-char (point-min))
- (condition-case nil
- (setq newsticker--cache (read (current-buffer)))
- (error
- (message "Error while reading newsticker cache file!")
- (setq newsticker--cache nil)))))))
-
(defun newsticker--cache-read ()
"Read cache data."
(setq newsticker--cache nil)
- (if (file-exists-p newsticker-cache-filename)
- (progn
- (when (y-or-n-p "Old newsticker cache file exists. Read it? ")
- (newsticker--cache-read-version1))
- (when (y-or-n-p (format "Delete old newsticker cache file? "))
- (delete-file newsticker-cache-filename)))
- (dolist (f (append newsticker-url-list-defaults newsticker-url-list))
- (newsticker--cache-read-feed (car f)))))
+ (dolist (f (append newsticker-url-list-defaults newsticker-url-list))
+ (newsticker--cache-read-feed (car f))))
(defun newsticker--cache-read-feed (feed-name)
"Read cache data for feed named FEED-NAME."
diff --git a/lisp/net/newst-plainview.el b/lisp/net/newst-plainview.el
index 420cf82e4d8..82977b000b6 100644
--- a/lisp/net/newst-plainview.el
+++ b/lisp/net/newst-plainview.el
@@ -589,7 +589,7 @@ calls `w3m-toggle-inline-image'. It works only if
(defun newsticker-close-buffer ()
"Close the newsticker buffer."
(interactive)
- (newsticker--cache-update t)
+ (newsticker--cache-save)
(bury-buffer))
(defun newsticker-next-new-item (&optional do-not-wrap-at-eob)
@@ -748,7 +748,7 @@ Return new buffer position."
(newsticker--cache-replace-age newsticker--cache feed 'new 'old)
(newsticker--cache-replace-age newsticker--cache feed 'obsolete
'old)
- (newsticker--cache-update)
+ (newsticker--cache-save)
(newsticker--buffer-set-uptodate nil)
(newsticker--ticker-text-setup)
(newsticker-buffer-update)
@@ -879,7 +879,7 @@ not get changed."
(newsticker--cache-replace-age newsticker--cache 'any 'new 'old)
(newsticker--buffer-set-uptodate nil)
(newsticker--ticker-text-setup)
- (newsticker--cache-update)
+ (newsticker--cache-save)
(newsticker-buffer-update)))
(defun newsticker-hide-extra ()
diff --git a/lisp/net/newst-reader.el b/lisp/net/newst-reader.el
index 40e304402ad..b228ea9a60f 100644
--- a/lisp/net/newst-reader.el
+++ b/lisp/net/newst-reader.el
@@ -4,7 +4,7 @@
;; Author: Ulf Jasper <ulf.jasper@web.de>
;; Filename: newst-reader.el
-;; URL: http://www.nongnu.org/newsticker
+;; URL: https://www.nongnu.org/newsticker
;; Package: newsticker
;; ======================================================================
diff --git a/lisp/net/newst-ticker.el b/lisp/net/newst-ticker.el
index 8cfafb5bfe4..068b862b694 100644
--- a/lisp/net/newst-ticker.el
+++ b/lisp/net/newst-ticker.el
@@ -4,7 +4,7 @@
;; Author: Ulf Jasper <ulf.jasper@web.de>
;; Filename: newst-ticker.el
-;; URL: http://www.nongnu.org/newsticker
+;; URL: https://www.nongnu.org/newsticker
;; Keywords: News, RSS, Atom
;; Package: newsticker
diff --git a/lisp/net/newsticker.el b/lisp/net/newsticker.el
index 34e94acd12c..52576c936a3 100644
--- a/lisp/net/newsticker.el
+++ b/lisp/net/newsticker.el
@@ -4,7 +4,7 @@
;; Author: Ulf Jasper <ulf.jasper@web.de>
;; Filename: newsticker.el
-;; URL: http://www.nongnu.org/newsticker
+;; URL: https://www.nongnu.org/newsticker
;; Created: 17. June 2003
;; Keywords: News, RSS, Atom
@@ -43,8 +43,7 @@
;; are contained in "RSS" (RDF Site Summary) or "Atom" files. Newsticker
;; should work with the following RSS formats:
;; * RSS 0.91
-;; (see http://backend.userland.com/rss091 or
-;; http://my.netscape.com/publish/formats/rss-spec-0.91.html)
+;; (see http://backend.userland.com/rss091)
;; * RSS 0.92
;; (see http://backend.userland.com/rss092)
;; * RSS 1.0
diff --git a/lisp/net/nsm.el b/lisp/net/nsm.el
index 1d9ee6db86c..b067b23f8ff 100644
--- a/lisp/net/nsm.el
+++ b/lisp/net/nsm.el
@@ -34,7 +34,7 @@
(defvar nsm-temporary-host-settings nil)
(defgroup nsm nil
- "Network Security Manager"
+ "Network Security Manager."
:version "25.1"
:group 'comm)
@@ -79,8 +79,7 @@ option."
(const :tag "Off" nil)
(function :tag "Custom function")))
-(defcustom nsm-settings-file (expand-file-name "network-security.data"
- user-emacs-directory)
+(defcustom nsm-settings-file (locate-user-emacs-file "network-security.data")
"The file the security manager settings will be stored in."
:version "25.1"
:type 'file)
@@ -446,8 +445,8 @@ this check has no effect on GnuTLS >= 3.2.0.
Reference:
-[1]: Schneier, Bruce (1996). Applied Cryptography (Second ed.). John
-Wiley & Sons. ISBN 0-471-11709-9.
+[1]: Schneier, Bruce (1996). Applied Cryptography (Second ed.).
+John Wiley & Sons. ISBN 0-471-11709-9.
[2]: N. Mavrogiannopoulos, FSF (Apr 2015). \"GnuTLS NEWS -- History
of user-visible changes.\" Version 3.4.0,
`https://gitlab.com/gnutls/gnutls/blob/master/NEWS'"
@@ -466,7 +465,7 @@ man-in-the-middle attacks.
Reference:
-GnuTLS authors (2018). \"GnuTLS Manual 4.3.3 Anonymous
+GnuTLS authors (2018). \"GnuTLS Manual 4.3.3 Anonymous
authentication\",
`https://www.gnutls.org/manual/gnutls.html#Anonymous-authentication'"
(let ((kx (plist-get status :key-exchange)))
diff --git a/lisp/net/ntlm.el b/lisp/net/ntlm.el
index 0450c80c2ec..0e0146df969 100644
--- a/lisp/net/ntlm.el
+++ b/lisp/net/ntlm.el
@@ -405,8 +405,8 @@ by PASSWORD-HASHES. PASSWORD-HASHES should be a return value of
(ntlm-md4hash password)))
(defun ntlm-ascii2unicode (str len)
- "Convert an ASCII string into a NT Unicode string, which is
-little-endian utf16."
+ "Convert an ASCII string STR of length LEN into a NT Unicode string.
+NT Unicode strings are little-endian utf16."
;; FIXME: Can't we use encode-coding-string with a `utf-16le' coding system?
(let ((utf (make-string (* 2 len) 0))
(i 0)
@@ -428,25 +428,24 @@ little-endian utf16."
buf))
(defun ntlm-smb-passwd-hash (passwd)
- "Return the SMB password hash string of 16 bytes long for the given password
-string PASSWD. PASSWD is truncated to 14 bytes if longer."
+ "Return SMB password hash string of 16 bytes long for password string PASSWD.
+PASSWD is truncated to 14 bytes if longer."
(let ((len (min (length passwd) 14)))
(ntlm-smb-des-e-p16
(concat (substring (upcase passwd) 0 len) ;fill top 14 bytes with passwd
(make-string (- 15 len) 0)))))
(defun ntlm-smb-owf-encrypt (passwd c8)
- "Return the response string of 24 bytes long for the given password
-string PASSWD based on the DES encryption. PASSWD is of at most 14
-bytes long and the challenge string C8 of 8 bytes long."
+ "Return response string of 24 bytes long for PASSWD based on DES encryption.
+PASSWD is of at most 14 bytes long and the challenge string C8 of
+8 bytes long."
(let* ((len (min (length passwd) 16))
(p22 (concat (substring passwd 0 len) ;Fill top 16 bytes with passwd.
(make-string (- 22 len) 0))))
(ntlm-smb-des-e-p24 p22 c8)))
(defun ntlm-smb-des-e-p24 (p22 c8)
- "Return a 24 bytes hashed string for a 21 bytes string P22 and a 8 bytes
-string C8."
+ "Return 24 bytes hashed string for a 21 bytes string P22 and a 8 bytes string C8."
(concat (ntlm-smb-hash c8 p22 t) ;hash first 8 bytes of p22
(ntlm-smb-hash c8 (substring p22 7) t)
(ntlm-smb-hash c8 (substring p22 14) t)))
@@ -460,8 +459,8 @@ string C8."
(substring p15 7) t)))
(defun ntlm-smb-hash (in key forw)
- "Return the hash string of length 8 for a string IN of length 8 and
-a string KEY of length 8. FORW is t or nil."
+ "Return hash string of length 8 for IN of length 8 and KEY of length 8.
+FORW is t or nil."
(let ((out (make-string 8 0))
(inb (make-string 64 0))
(keyb (make-string 64 0))
@@ -603,8 +602,8 @@ a string KEY of length 8. FORW is t or nil."
[ 2 1 14 7 4 10 8 13 15 12 9 0 3 5 6 11]]])
(defsubst ntlm-string-permute (in perm n)
- "Return a string of length N for a string IN and a permutation vector
-PERM of size N. The length of IN should be height of PERM."
+ "Return string of length N for string IN and permutation vector PERM of size N.
+The length of IN should be height of PERM."
(let ((i 0) (out (make-string n 0)))
(while (< i n)
(aset out i (aref in (- (aref perm i) 1)))
@@ -701,8 +700,8 @@ backward."
(ntlm-string-permute rl ntlm-smb-perm6 64)))
(defun ntlm-md4hash (passwd)
- "Return the 16 bytes MD4 hash of a string PASSWD after converting it
-into a Unicode string. PASSWD is truncated to 128 bytes if longer."
+ "Return 16 bytes MD4 hash of string PASSWD after converting it to Unicode.
+PASSWD is truncated to 128 bytes if longer."
(let* ((len (min (length passwd) 128)) ;Pwd can't be > than 128 characters.
;; Password must be converted to NT Unicode.
(wpwd (ntlm-ascii2unicode passwd len)))
diff --git a/lisp/net/puny.el b/lisp/net/puny.el
index 42a7e796798..c1833ffdb0b 100644
--- a/lisp/net/puny.el
+++ b/lisp/net/puny.el
@@ -43,6 +43,7 @@ For instance, \"fśf.org\" => \"xn--ff-2sa.org\"."
"Encode STRING according to the IDNA/punycode algorithm.
This is used to encode non-ASCII domain names.
For instance, \"bücher\" => \"xn--bcher-kva\"."
+ (setq string (downcase (string-glyph-compose string)))
(let ((ascii (seq-filter (lambda (char)
(< char 128))
string)))
diff --git a/lisp/net/quickurl.el b/lisp/net/quickurl.el
index 2574c8cb63e..ed7d7e53a96 100644
--- a/lisp/net/quickurl.el
+++ b/lisp/net/quickurl.el
@@ -24,19 +24,19 @@
;;; Commentary:
;;
;; This package provides a simple method of inserting a URL based on the
-;; text at point in the current buffer. This is part of an on-going effort
+;; text at point in the current buffer. This is part of an on-going effort
;; to increase the information I provide people while reducing the amount
-;; of typing I need to do. No-doubt there are undiscovered Emacs packages
+;; of typing I need to do. No-doubt there are undiscovered Emacs packages
;; out there that do all of this and do it better, feel free to point me to
;; them, in the mean time I'm having fun playing with Emacs Lisp.
;;
;; The URLs are stored in an external file as a list of either cons cells,
-;; or lists. A cons cell entry looks like this:
+;; or lists. A cons cell entry looks like this:
;;
;; (<Lookup> . <URL>)
;;
;; where <Lookup> is a string that acts as the keyword lookup and <URL> is
-;; the URL associated with it. An example might be:
+;; the URL associated with it. An example might be:
;;
;; ("GNU" . "https://www.gnu.org/")
;;
@@ -45,8 +45,8 @@
;; (<Lookup> <URL> <Comment>)
;;
;; where <Lookup> and <URL> are the same as with the cons cell and <Comment>
-;; is any text you like that describes the URL. This description will be
-;; used when presenting a list of URLS using `quickurl-list'. An example
+;; is any text you like that describes the URL. This description will be
+;; used when presenting a list of URLS using `quickurl-list'. An example
;; might be:
;;
;; ("FSF" "https://www.fsf.org/" "The Free Software Foundation")
@@ -55,7 +55,7 @@
;;
;; (("GNU" . "https://www.gnu.org/")
;; ("FSF" "https://www.fsf.org/" "The Free Software Foundation")
-;; ("emacs" . "http://www.emacs.org/")
+;; ("emacs" . "https://www.emacs.org/")
;; ("davep" "http://www.davep.org/" "Dave's homepage"))
;;
;; In case you're wondering about the mixture of cons cells and lists,
@@ -215,8 +215,8 @@ Note that this function is a setfable place."
(defun quickurl-url-comment (url)
"Get the comment from a URL.
-If the URL has no comment an empty string is returned. Also note that this
-function is a setfable place."
+If the URL has no comment an empty string is returned. Also note
+that this function is a setfable place."
(declare
(gv-setter (lambda (store)
`(if (quickurl-url-commented-p ,url)
@@ -284,7 +284,7 @@ It also restores point after the `read'."
"Return URL associated with key LOOKUP.
The lookup is done by looking in the alist `quickurl-urls' and the `cons'
-for the URL is returned. The actual method used to look into the alist
+for the URL is returned. The actual method used to look into the alist
depends on the setting of the variable `quickurl-assoc-function'."
(funcall quickurl-assoc-function lookup quickurl-urls))
diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index e7aec505b0b..2375b14cca2 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -4,7 +4,8 @@
;; Author: Ryan Yeske <rcyeske@gmail.com>
;; Maintainers: Ryan Yeske <rcyeske@gmail.com>,
-;; Leo Liu <sdl.web@gmail.com>
+;; Leo Liu <sdl.web@gmail.com>,
+;; Philip Kaludercic <philipk@posteo.net>
;; Keywords: comm
;; This file is part of GNU Emacs.
@@ -60,9 +61,9 @@
(defcustom rcirc-server-alist
(if (gnutls-available-p)
- '(("irc.libera.chat" :channels ("#rcirc")
+ '(("irc.libera.chat" :channels ("#emacs" "#rcirc")
:port 6697 :encryption tls))
- '(("irc.libera.chat" :channels ("#rcirc"))))
+ '(("irc.libera.chat" :channels ("#emacs" "#rcirc"))))
"An alist of IRC connections to establish when running `rcirc'.
Each element looks like (SERVER-NAME PARAMETERS).
@@ -189,22 +190,24 @@ If nil, no maximum is applied."
(defvar-local rcirc-low-priority-flag nil
"Non-nil means activity in this buffer is considered low priority.")
+(defvar-local rcirc-pending-requests '()
+ "List of pending requests.
+See `rcirc-omit-unless-requested'.")
+
+(defcustom rcirc-omit-unless-requested '()
+ "List of commands to only be requested if preceded by a command.
+For example, if \"TOPIC\" is added to this list, TOPIC commands
+will only be displayed if `rcirc-cmd-TOPIC' was previously
+invoked. Commands will only be hidden if `rcirc-omit-mode' is
+enabled."
+ :version "28.1"
+ :type '(repeat string))
+
(defcustom rcirc-omit-responses
'("JOIN" "PART" "QUIT" "NICK")
"Responses which will be hidden when `rcirc-omit-mode' is enabled."
:type '(repeat string))
-(defcustom rcirc-omit-after-reconnect
- '("JOIN" "TOPIC" "NAMES")
- "Types of messages to hide right after reconnecting."
- :type '(repeat string)
- :version "28.1")
-
-(defvar-local rcirc-reconncting nil
- "Non-nil means we have just reconnected.
-This is used to hide the message types enumerated in
-`rcirc-supress-after-reconnect'.")
-
(defvar-local rcirc-prompt-start-marker nil
"Marker indicating the beginning of the message prompt.")
@@ -215,11 +218,8 @@ Uninteresting lines are those whose responses are listed in
`rcirc-omit-responses'."
:lighter " Omit"
(if rcirc-omit-mode
- (progn
- (add-to-invisibility-spec '(rcirc-omit . nil))
- (message "Rcirc-Omit mode enabled"))
- (remove-from-invisibility-spec '(rcirc-omit . nil))
- (message "Rcirc-Omit mode disabled"))
+ (add-to-invisibility-spec '(rcirc-omit . nil))
+ (remove-from-invisibility-spec '(rcirc-omit . nil)))
(dolist (window (get-buffer-window-list (current-buffer)))
(with-selected-window window
(recenter (when (> (point) rcirc-prompt-start-marker) -1)))))
@@ -262,6 +262,7 @@ The ARGUMENTS for each METHOD symbol are:
`bitlbee': NICK PASSWORD
`quakenet': ACCOUNT PASSWORD
`sasl': NICK PASSWORD
+ `certfp': KEY CERT
Examples:
((\"Libera.Chat\" nickserv \"bob\" \"p455w0rd\")
@@ -291,7 +292,11 @@ Examples:
(list :tag "SASL"
(const sasl)
(string :tag "Nick")
- (string :tag "Password")))))
+ (string :tag "Password"))
+ (list :tag "CertFP"
+ (const certfp)
+ (string :tag "Key")
+ (string :tag "Certificate")))))
(defcustom rcirc-auto-authenticate-flag t
"Non-nil means automatically send authentication string to server.
@@ -413,6 +418,21 @@ will be killed."
:version "28.1"
:type 'function)
+(defcustom rcirc-channel-filter #'identity
+ "Function applied to channels before displaying."
+ :version "28.1"
+ :type 'function)
+
+(defcustom rcirc-track-ignore-server-buffer-flag nil
+ "Non-nil means activities in the server buffer are not traced."
+ :version "28.1"
+ :type 'boolean)
+
+(defcustom rcirc-display-server-buffer t
+ "Non-nil means the server buffer should be shown on connecting."
+ :version "28.1"
+ :type 'boolean)
+
(defvar-local rcirc-nick nil
"The nickname used for the current connection.")
@@ -512,10 +532,12 @@ If ARG is non-nil, instead prompt for connection parameters."
:channels)
" "))
"[, ]+" t))
- (encryption (rcirc-prompt-for-encryption server-plist)))
- (rcirc-connect server port nick user-name
- rcirc-default-full-name
- channels password encryption))
+ (encryption (rcirc-prompt-for-encryption server-plist))
+ (process (rcirc-connect server port nick user-name
+ rcirc-default-full-name
+ channels password encryption)))
+ (when rcirc-display-server-buffer
+ (pop-to-buffer-same-window (process-buffer process))))
;; connect to servers in `rcirc-server-alist'
(let (connected-servers)
(dolist (c rcirc-server-alist)
@@ -530,6 +552,9 @@ If ARG is non-nil, instead prompt for connection parameters."
(password (plist-get (cdr c) :password))
(encryption (plist-get (cdr c) :encryption))
(server-alias (plist-get (cdr c) :server-alias))
+ (client-cert (when (eq (rcirc-get-server-method (car c))
+ 'certfp)
+ (rcirc-get-server-cert (car c))))
contact)
(when-let (((not password))
(auth (auth-source-search :host server
@@ -544,9 +569,11 @@ If ARG is non-nil, instead prompt for connection parameters."
(setq connected p)))
(if (not connected)
(condition-case nil
- (rcirc-connect server port nick user-name
- full-name channels password encryption
- server-alias)
+ (let ((process (rcirc-connect server port nick user-name
+ full-name channels password encryption
+ client-cert server-alias)))
+ (when rcirc-display-server-buffer
+ (pop-to-buffer-same-window (process-buffer process))))
(quit (message "Quit connecting to %s"
(or server-alias server))))
(with-current-buffer (process-buffer connected)
@@ -595,6 +622,8 @@ FULL-NAME STARTUP-CHANNELS PASSWORD ENCRYPTION SERVER-ALIAS).
See `rcirc-connect' for more details on these variables.")
(defvar-local rcirc-process nil
"Network process for the current connection.")
+(defvar-local rcirc-last-connect-time nil
+ "The last time the buffer was connected.")
;;; IRCv3 capability negotiation (https://ircv3.net/specs/extensions/capability-negotiation)
(defvar rcirc-implemented-capabilities
@@ -604,6 +633,16 @@ See `rcirc-connect' for more details on these variables.")
"message-ids" ;https://ircv3.net/specs/extensions/message-ids
"invite-notify" ;https://ircv3.net/specs/extensions/invite-notify
"sasl" ;https://ircv3.net/specs/extensions/sasl-3.1
+ "multi-prefix" ;https://ircv3.net/specs/extensions/multi-prefix
+ "standard-replies" ;https://ircv3.net/specs/extensions/standard-replies
+ ;; The following capabilities should be implemented as soon as
+ ;; their specifications are undrafted:
+ ;;
+ ;; "reply" ;https://ircv3.net/specs/client-tags/reply
+ ;; "react" ;https://ircv3.net/specs/client-tags/react
+ ;; "multiline" ;https://ircv3.net/specs/extensions/multiline
+ ;; "chathistory" ;https://ircv3.net/specs/extensions/chathistory
+ ;; "channel-rename" ;https://ircv3.net/specs/extensions/channel-rename
)
"A list of capabilities that rcirc supports.")
(defvar-local rcirc-requested-capabilities nil
@@ -611,102 +650,89 @@ See `rcirc-connect' for more details on these variables.")
(defvar-local rcirc-acked-capabilities nil
"A list of capabilities that the server supports.")
(defvar-local rcirc-finished-sasl t
- "Check whether SASL authentication has completed")
+ "Check whether SASL authentication has completed.")
(defun rcirc-get-server-method (server)
"Return authentication method for SERVER."
- (catch 'method
- (dolist (i rcirc-authinfo)
- (let ((server-i (car i))
- (method (cadr i)))
- (when (string-match server-i server)
- (throw 'method method))))))
+ (cadr (assoc server rcirc-authinfo #'string-match)))
(defun rcirc-get-server-password (server)
"Return password for SERVER."
- (catch 'pass
- (dolist (i rcirc-authinfo)
- (let ((server-i (car i))
- (args (cdddr i)))
- (when (string-match server-i server)
- (throw 'pass (car args)))))))
+ (cadddr (assoc server rcirc-authinfo #'string-match)))
+
+(defun rcirc-get-server-cert (server)
+ "Return a list of key and certificate for SERVER."
+ (cddr (assoc server rcirc-authinfo #'string-match)))
;;;###autoload
(defun rcirc-connect (server &optional port nick user-name
full-name startup-channels password encryption
- server-alias)
+ certfp server-alias)
"Connect to SERVER.
The arguments PORT, NICK, USER-NAME, FULL-NAME, PASSWORD,
-ENCRYPTION, SERVER-ALIAS are interpreted as in
+ENCRYPTION, CERTFP, SERVER-ALIAS are interpreted as in
`rcirc-server-alist'. STARTUP-CHANNELS is a list of channels
that are joined after authentication."
(save-excursion
(message "Connecting to %s..." (or server-alias server))
(let* ((inhibit-eol-conversion)
(port-number (if port
- (if (stringp port)
- (string-to-number port)
- port)
- rcirc-default-port))
- (nick (or nick rcirc-default-nick))
- (user-name (or user-name rcirc-default-user-name))
- (full-name (or full-name rcirc-default-full-name))
- (startup-channels startup-channels)
- (use-sasl (eq (rcirc-get-server-method server) 'sasl))
- (process (open-network-stream
+ (if (stringp port)
+ (string-to-number port)
+ port)
+ rcirc-default-port))
+ (nick (or nick rcirc-default-nick))
+ (user-name (or user-name rcirc-default-user-name))
+ (full-name (or full-name rcirc-default-full-name))
+ (startup-channels startup-channels)
+
+ process)
+
+ ;; Ensure any previous process is killed
+ (when-let ((old-process (get-process (or server-alias server))))
+ (set-process-sentinel old-process #'ignore)
+ (delete-process process))
+
+ ;; Set up process
+ (setq process (open-network-stream
(or server-alias server) nil server port-number
- :type (or encryption 'plain))))
- ;; set up process
+ :type (or encryption 'plain)
+ :client-certificate certfp
+ :nowait t))
(set-process-coding-system process 'raw-text 'raw-text)
- (switch-to-buffer (rcirc-generate-new-buffer-name process nil))
- (set-process-buffer process (current-buffer))
- (unless (eq major-mode 'rcirc-mode)
- (rcirc-mode process nil))
- (set-process-sentinel process 'rcirc-sentinel)
- (set-process-filter process 'rcirc-filter)
-
- (setq rcirc-connection-info
- (list server port nick user-name full-name startup-channels
- password encryption server-alias))
- (setq rcirc-process process)
- (setq rcirc-server server)
- (setq rcirc-server-name (or server-alias server)) ; Update when we get 001 response.
- (setq rcirc-nick-table (make-hash-table :test 'equal))
- (setq rcirc-nick nick)
- (setq rcirc-startup-channels startup-channels)
- (setq rcirc-last-server-message-time (current-time))
-
- (setq rcirc-connecting t)
-
- (add-hook 'auto-save-hook 'rcirc-log-write)
- (when use-sasl
- (rcirc-send-string process "CAP REQ sasl"))
-
- (when use-sasl
- (setq-local rcirc-finished-sasl nil))
- ;; identify
- (dolist (cap rcirc-implemented-capabilities)
- (rcirc-send-string process "CAP" "REQ" : cap)
- (push cap rcirc-requested-capabilities))
- (unless (zerop (length password))
- (rcirc-send-string process "PASS" password))
- (rcirc-send-string process "NICK" nick)
- (rcirc-send-string process "USER" user-name "0" "*" : full-name)
- ;; Setup sasl, and initiate authentication.
- (when (and rcirc-auto-authenticate-flag
- use-sasl)
- (rcirc-send-string process "AUTHENTICATE" "PLAIN"))
-
- ;; setup ping timer if necessary
- (unless rcirc-keepalive-timer
- (setq rcirc-keepalive-timer
- (run-at-time 0 (/ rcirc-timeout-seconds 2) 'rcirc-keepalive)))
-
- (message "Connecting to %s...done" (or server-alias server))
- (setq mode-line-process nil)
-
- ;; return process object
- process)))
+ (with-current-buffer (get-buffer-create (rcirc-generate-new-buffer-name process nil))
+ (set-process-buffer process (current-buffer))
+ (unless (eq major-mode 'rcirc-mode)
+ (rcirc-mode process nil))
+ (set-process-sentinel process #'rcirc-sentinel)
+ (set-process-filter process #'rcirc-filter)
+
+ (setq rcirc-connection-info
+ (list server port nick user-name full-name startup-channels
+ password encryption server-alias))
+ (setq rcirc-process process)
+ (setq rcirc-server server)
+ (setq rcirc-server-name (or server-alias server)) ; Update when we get 001 response.
+ (setq rcirc-nick-table (make-hash-table :test 'equal))
+ (setq rcirc-nick nick)
+ (setq rcirc-startup-channels startup-channels)
+ (setq rcirc-last-connect-time (current-time))
+ (setq rcirc-last-server-message-time rcirc-last-connect-time)
+
+ ;; Check if the immediate process state
+ (sit-for .1)
+ (cond
+ ((eq (process-status process) 'failed)
+ (setq mode-line-process ":disconnected")
+ (setq rcirc-connecting nil))
+ ((eq (process-status process) 'connect)
+ (setq mode-line-process ":connecting")
+ (setq rcirc-connecting t)))
+
+ (add-hook 'auto-save-hook #'rcirc-log-write)
+
+ ;; return process object
+ process))))
(defmacro with-rcirc-process-buffer (process &rest body)
"Evaluate BODY in the buffer of PROCESS."
@@ -795,31 +821,114 @@ When 0, do not auto-reconnect."
:version "25.1"
:type 'integer)
-(defvar-local rcirc-last-connect-time nil
- "The last time the buffer was connected.")
+(defcustom rcirc-reconnect-attempts 3
+ "Number of times a reconnection should be attempted."
+ :version "28.1"
+ :type 'integer)
+
+(defvar-local rcirc-failed-attempts 0
+ "Number of times reconnecting has failed.")
+
+(defvar-local rcirc-reconnection-timer nil
+ "Timer used for reconnecting.")
+
+(defun rcirc-reconnect (process &optional quiet)
+ "Attempt to reconnect connection to PROCESS.
+If QUIET is non-nil, no not emit a message."
+ (with-rcirc-process-buffer process
+ (catch 'exit
+ (if (rcirc--connection-open-p process)
+ (throw 'exit (or quiet (message "Server process is alive")))
+ (delete-process process))
+ (let ((conn-info rcirc-connection-info))
+ (setf (nth 5 conn-info)
+ (cl-remove-if-not #'rcirc-channel-p
+ (mapcar #'car rcirc-buffer-alist)))
+ (dolist (buffer (mapcar #'cdr rcirc-buffer-alist))
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (setq mode-line-process ":connecting"))))
+ (let ((nprocess (apply #'rcirc-connect conn-info)))
+ (when (and (< rcirc-failed-attempts rcirc-reconnect-attempts)
+ (eq (process-status nprocess) 'failed))
+ (setq rcirc-failed-attempts (1+ rcirc-failed-attempts))
+ (rcirc-print nprocess "*rcirc*" "ERROR" nil
+ (format "Failed to reconnect (%d/%d)..."
+ rcirc-failed-attempts
+ rcirc-reconnect-attempts))
+ (setq rcirc-reconnection-timer
+ (run-at-time rcirc-reconnect-delay nil
+ #'rcirc-reconnect process t))))))))
(defun rcirc-sentinel (process sentinel)
- "Called when PROCESS receives SENTINEL."
- (let ((sentinel (string-replace "\n" "" sentinel)))
+ "Called on a change of the state of PROCESS.
+SENTINEL describes the change in form of a string."
+ (let ((status (process-status process)))
(rcirc-debug process (format "SENTINEL: %S %S\n" process sentinel))
(with-rcirc-process-buffer process
- (dolist (buffer (cons nil (mapcar 'cdr rcirc-buffer-alist)))
- (with-current-buffer (or buffer (current-buffer))
- (rcirc-print process "rcirc.el" "ERROR" rcirc-target
- (format "%s: %s (%S)"
- (process-name process)
- sentinel
- (process-status process))
- (not rcirc-target))
- (rcirc-disconnect-buffer)))
- (when (and (string= sentinel "deleted")
- (< 0 rcirc-reconnect-delay))
+ (cond
+ ((eq status 'open)
+ (let* ((server (nth 0 rcirc-connection-info))
+ (user-name (nth 3 rcirc-connection-info))
+ (full-name (nth 4 rcirc-connection-info))
+ (password (nth 6 rcirc-connection-info))
+ (server-alias (nth 8 rcirc-connection-info))
+ (use-sasl (eq (rcirc-get-server-method server) 'sasl)))
+
+ ;; Prepare SASL authentication
+ (when use-sasl
+ (rcirc-send-string process "CAP REQ sasl")
+ (setq-local rcirc-finished-sasl nil))
+
+ ;; Capability negotiation
+ (dolist (cap rcirc-implemented-capabilities)
+ (rcirc-send-string process "CAP" "REQ" : cap)
+ (push cap rcirc-requested-capabilities))
+
+ ;; Identify user
+ (unless (zerop (length password))
+ (rcirc-send-string process "PASS" password))
+ (rcirc-send-string process "NICK" rcirc-nick)
+ (rcirc-send-string process "USER" user-name "0" "*" : full-name)
+
+ ;; Setup sasl, and initiate authentication.
+ (when (and rcirc-auto-authenticate-flag
+ use-sasl)
+ (rcirc-send-string process "AUTHENTICATE" "PLAIN"))
+
+ ;; Setup ping timer if necessary
+ (unless rcirc-keepalive-timer
+ (setq rcirc-keepalive-timer
+ (run-at-time 0 (/ rcirc-timeout-seconds 2) #'rcirc-keepalive)))
+
+ ;; Reset previous reconnection attempts
+ (setq rcirc-failed-attempts 0)
+ (when rcirc-reconnection-timer
+ (cancel-timer rcirc-reconnection-timer)
+ (setq rcirc-reconnection-timer nil))
+
+ (message "Connecting to %s...done" (or server-alias server))
+ (dolist (buffer (cons nil (mapcar 'cdr rcirc-buffer-alist)))
+ (with-current-buffer (or buffer (current-buffer))
+ (setq mode-line-process nil)))))
+ ((eq status 'closed)
(let ((now (current-time)))
- (when (or (null rcirc-last-connect-time)
- (time-less-p rcirc-reconnect-delay
- (time-subtract now rcirc-last-connect-time)))
- (setq rcirc-last-connect-time now)
- (rcirc-cmd-reconnect nil))))
+ (with-rcirc-process-buffer process
+ (when (and (< 0 rcirc-reconnect-delay)
+ (time-less-p rcirc-reconnect-delay
+ (time-subtract now rcirc-last-connect-time)))
+ (setq rcirc-last-connect-time now)
+ (rcirc-reconnect process)))))
+ ((eq status 'failed)
+ (dolist (buffer (cons nil (mapcar 'cdr rcirc-buffer-alist)))
+ (with-current-buffer (or buffer (current-buffer))
+ (rcirc-print process "*rcirc*" "ERROR" rcirc-target
+ (format "%s: %s (%S)"
+ (process-name process)
+ sentinel
+ (process-status process))
+ (not rcirc-target))
+ (rcirc-disconnect-buffer)))))
(run-hook-with-args 'rcirc-sentinel-functions process sentinel))))
(defun rcirc-disconnect-buffer (&optional buffer)
@@ -879,7 +988,7 @@ Function is called with PROCESS, COMMAND, SENDER, ARGS and LINE.")
(condition-case err
(rcirc-process-server-response-1 process text)
(error
- (rcirc-print process "RCIRC" "ERROR" nil
+ (rcirc-print process "*rcirc*" "ERROR" nil
(format "\"%s\" %s" text err) t)))
(rcirc-process-server-response-1 process text)))
@@ -1054,7 +1163,7 @@ With no argument or nil as argument, use the current buffer."
(let ((buffer (or buffer (and (buffer-live-p rcirc-server-buffer)
rcirc-server-buffer))))
(if buffer
- (with-current-buffer buffer rcirc-process)
+ (buffer-local-value 'rcirc-process buffer)
rcirc-process)))
(defun rcirc-server-name (process)
@@ -1258,7 +1367,8 @@ Each element looks like (FILENAME . TEXT).")
This number is independent of the number of lines in the buffer.")
(defun rcirc-mode (process target)
- "Major mode for IRC channel buffers.
+ "Initialize an IRC buffer for writing with TARGET.
+PROCESS is the process object used for communication.
\\{rcirc-mode-map}"
;; FIXME: Use define-derived-mode.
@@ -1281,7 +1391,6 @@ This number is independent of the number of lines in the buffer.")
(setq rcirc-last-post-time (current-time))
(setq-local fill-paragraph-function 'rcirc-fill-paragraph)
(setq rcirc-current-line 0)
- (setq rcirc-last-connect-time (current-time))
(use-hard-newlines t)
@@ -1320,8 +1429,7 @@ This number is independent of the number of lines in the buffer.")
(when target ; skip server buffer
(let ((buffer (current-buffer)))
(with-rcirc-process-buffer process
- (setq rcirc-buffer-alist (cons (cons target buffer)
- rcirc-buffer-alist))))
+ (push (cons target buffer) rcirc-buffer-alist)))
(rcirc-update-short-buffer-names))
(add-hook 'completion-at-point-functions
@@ -1464,10 +1572,10 @@ Create the buffer if it doesn't exist."
(rcirc-generate-new-buffer-name process target))))
(with-current-buffer new-buffer
(unless (eq major-mode 'rcirc-mode)
- (rcirc-mode process target)))
- (setq mode-line-process nil)
- (rcirc-put-nick-channel process (rcirc-nick process) target
- rcirc-current-line)
+ (rcirc-mode process target))
+ (setq mode-line-process nil))
+ (rcirc-put-nick-channel process (rcirc-nick process) target
+ rcirc-current-line)
new-buffer)))))
(defun rcirc-send-input ()
@@ -1522,6 +1630,11 @@ The argument JUSTIFY is passed on to `fill-region'."
(defun rcirc-process-message (line)
"Process LINE as a message to be sent."
+ (when (and (null rcirc-target)
+ (string-match
+ (rx bos (group (+? nonl)) "@" (+ nonl) eos)
+ (buffer-name)))
+ (setq rcirc-target (match-string 1 (buffer-name))))
(if (not rcirc-target)
(message "Not joined (no target)")
(delete-region rcirc-prompt-end-marker (point))
@@ -1625,6 +1738,9 @@ extracted."
("ACTION" . "[%N %m]")
("COMMAND" . "%m")
("ERROR" . "%fw!!! %m")
+ ("FAIL" . "(%fwFAIL%f-) %m")
+ ("WARN" . "(%fwWARN%f-) %m")
+ ("NOTE" . "(%fwNOTE%f-) %m")
(t . "%fp*** %fs%n %r %m"))
"An alist of formats used for printing responses.
The format is looked up using the response-type as a key;
@@ -1742,8 +1858,9 @@ Returns nil if the information is not recorded.
PROCESS is the process object for the current connection."
(let ((chanbuf (rcirc-get-buffer process target)))
(when chanbuf
- (cdr (assoc-string nick (with-current-buffer chanbuf
- rcirc-recent-quit-alist))))))
+ (cdr (assoc-string nick (buffer-local-value
+ 'rcirc-recent-quit-alist
+ chanbuf))))))
(defun rcirc-last-line (process nick target)
"Return the line from the last activity from NICK in TARGET.
@@ -1857,12 +1974,15 @@ connection."
;; make text omittable
(let ((last-activity-lines (rcirc-elapsed-lines process sender target)))
(if (and (not (string= (rcirc-nick process) sender))
- (or (member response rcirc-omit-responses)
- (if (member response rcirc-omit-after-reconnect)
- rcirc-reconncting
- (setq rcirc-reconncting nil)))
- (or (not last-activity-lines)
- (< rcirc-omit-threshold last-activity-lines)))
+ (or (member response rcirc-omit-responses)
+ (and (member response rcirc-omit-unless-requested)
+ (if (member response rcirc-pending-requests)
+ (ignore (setq rcirc-pending-requests
+ (delete response rcirc-pending-requests)))
+ t)))
+ (or (member response rcirc-omit-unless-requested)
+ (not last-activity-lines)
+ (< rcirc-omit-threshold last-activity-lines)))
(put-text-property (point-min) (point-max)
'invisible 'rcirc-omit)
;; otherwise increment the line count
@@ -2008,7 +2128,8 @@ PROCESS is the process object for the current connection."
"Return the nick from USER. Remove any non-nick junk."
(save-match-data
(if (string-match (concat "^[" rcirc-nick-prefix-chars
- "]?\\([^! ]+\\)!?") (or user ""))
+ "]*\\([^! ]+\\)!?")
+ (or user ""))
(match-string 1 user)
user)))
@@ -2119,6 +2240,11 @@ This function does not alter the INPUT string."
map)
"Keymap for rcirc track minor mode.")
+(defcustom rcirc-track-abbrevate-flag t
+ "Non-nil means `rcirc-track-minor-mode' should abbreviate names."
+ :version "28.1"
+ :type 'boolean)
+
;;;###autoload
(define-minor-mode rcirc-track-minor-mode
"Global minor mode for tracking activity in rcirc buffers."
@@ -2176,7 +2302,7 @@ This function does not alter the INPUT string."
"Bury all RCIRC buffers."
(interactive)
(dolist (buf (buffer-list))
- (when (eq 'rcirc-mode (with-current-buffer buf major-mode))
+ (when (eq 'rcirc-mode (buffer-local-value 'major-mode buf))
(bury-buffer buf) ; buffers not shown
(quit-windows-on buf)))) ; buffers shown in a window
@@ -2216,13 +2342,15 @@ activity. Only run if the buffer is not visible and
(with-current-buffer buffer
(let ((old-activity rcirc-activity)
(old-types rcirc-activity-types))
- (when (not (get-buffer-window (current-buffer) t))
+ (when (and (not (get-buffer-window (current-buffer) t))
+ (not (and rcirc-track-ignore-server-buffer-flag
+ (eq rcirc-server-buffer (current-buffer)))))
(setq rcirc-activity
(sort (if (memq (current-buffer) rcirc-activity) rcirc-activity
(cons (current-buffer) rcirc-activity))
(lambda (b1 b2)
- (let ((t1 (with-current-buffer b1 rcirc-last-post-time))
- (t2 (with-current-buffer b2 rcirc-last-post-time)))
+ (let ((t1 (buffer-local-value 'rcirc-last-post-time b1))
+ (t2 (buffer-local-value 'rcirc-last-post-time b2)))
(time-less-p t2 t1)))))
(cl-pushnew type rcirc-activity-types)
(unless (and (equal rcirc-activity old-activity)
@@ -2299,7 +2427,12 @@ activity. Only run if the buffer is not visible and
(defun rcirc-short-buffer-name (buffer)
"Return a short name for BUFFER to use in the mode line indicator."
(with-current-buffer buffer
- (or rcirc-short-buffer-name (buffer-name))))
+ (funcall rcirc-channel-filter
+ (replace-regexp-in-string
+ "@.*?\\'" ""
+ (or (and rcirc-track-abbrevate-flag
+ rcirc-short-buffer-name)
+ (buffer-name))))))
(defun rcirc-visible-buffers ()
"Return a list of the visible buffers that are in `rcirc-mode'."
@@ -2408,7 +2541,7 @@ prefix with another element in PAIRS."
(when (and (listp x) (listp (cadr x)))
(setcdr x (if (> (length (cdr x)) 1)
(rcirc-make-trees (cdr x))
- (setcdr x (list (cl-cdadr x)))))))
+ (setcdr x (list (cdadr x)))))))
alist)))
;;; /commands these are called with 3 args: PROCESS, TARGET, which is
@@ -2441,23 +2574,24 @@ that, an interactive form can specified."
(insert "\\(.*?\\)")
(insert "[[:space:]]*\\'")
(buffer-string)))
- (argument (gensym))
+ (argument (make-symbol "arglist"))
documentation
interactive-spec)
(when (stringp (car body))
(setq documentation (pop body)))
(when (eq (car-safe (car-safe body)) 'interactive)
- (setq interactive-spec (cdr (pop body))))
+ (setq interactive-spec (cadr (pop body))))
`(progn
(defun ,fn-name (,argument &optional process target)
,(concat documentation
"\n\nNote: If PROCESS or TARGET are nil, the values given"
"\nby `rcirc-buffer-process' and `rcirc-target' will be used.")
- (interactive (list ,@interactive-spec))
+ (interactive (list ,interactive-spec))
(unless (if (listp ,argument)
(<= ,required (length ,argument) ,total)
(string-match ,regexp ,argument))
- (user-error "Malformed input (%s): %S" ',command ',argument))
+ (user-error "Malformed input (%s): %S" ',command ,argument))
+ (push ,(upcase (symbol-name command)) rcirc-pending-requests)
(let ((process (or process (rcirc-buffer-process)))
(target (or target rcirc-target)))
(ignore target process)
@@ -2533,18 +2667,8 @@ to `rcirc-default-part-reason'."
(rcirc-define-command reconnect ()
"Reconnect to current server."
(interactive "i")
- (with-rcirc-server-buffer
- (cond
- (rcirc-connecting (message "Already connecting"))
- ((process-live-p process) (message "Server process is alive"))
- (t (let ((conn-info rcirc-connection-info))
- (setf (nth 5 conn-info)
- (cl-remove-if-not #'rcirc-channel-p
- (mapcar #'car rcirc-buffer-alist)))
- (dolist (buf (nth 5 conn-info))
- (with-current-buffer (cdr (assoc buf rcirc-buffer-alist))
- (setq rcirc-reconncting t)))
- (apply #'rcirc-connect conn-info))))))
+ (setq rcirc-failed-attempts 0)
+ (rcirc-reconnect process))
(rcirc-define-command nick (nick)
"Change nick to NICK."
@@ -2564,8 +2688,8 @@ With a prefix arg, prompt for new topic."
(interactive (list (and current-prefix-arg
(read-string "List names in channel: "))))
(if (> (length topic) 0)
- (rcirc-send-string process "TOPIC" : topic)
- (rcirc-send-string process "TOPIC")))
+ (rcirc-send-string process "TOPIC" target : topic)
+ (rcirc-send-string process "TOPIC" target)))
(rcirc-define-command whois (nick)
"Request information from server about NICK."
@@ -2706,24 +2830,9 @@ keywords when no KEYWORD is given."
string))
(defvar rcirc-url-regexp
- (concat
- "\\b\\(\\(www\\.\\|\\(s?https?\\|ftp\\|file\\|gopher\\|"
- "nntp\\|news\\|telnet\\|wais\\|mailto\\|info\\):\\)"
- "\\(//[-a-z0-9_.]+:[0-9]*\\)?"
- (if (string-match "[[:digit:]]" "1") ;; Support POSIX?
- (let ((chars "-a-z0-9_=#$@~%&*+\\/[:word:]")
- (punct "!?:;.,"))
- (concat
- "\\(?:"
- ;; Match paired parentheses, e.g. in Wikipedia URLs:
- "[" chars punct "]+" "(" "[" chars punct "]+" ")" "[" chars "]"
- "\\|"
- "[" chars punct "]+" "[" chars "]"
- "\\)"))
- (concat ;; XEmacs 21.4 doesn't support POSIX.
- "\\([-a-z0-9_=!?#$@~%&*+\\/:;.,]\\|\\w\\)+"
- "\\([-a-z0-9_=#$@~%&*+\\/]\\|\\w\\)"))
- "\\)")
+ (eval-when-compile
+ (require 'browse-url)
+ browse-url-button-regexp)
"Regexp matching URLs. Set to nil to disable URL features in rcirc.")
;; cf cl-remove-if-not
@@ -3046,11 +3155,11 @@ connection."
;; already open buffer (after getting kicked e.g.)
(setq mode-line-process nil))
- (rcirc-print process sender "JOIN" channel "")
+ (rcirc-print process sender "JOIN" (funcall rcirc-channel-filter channel) "")
;; print in private chat buffer if it exists
(when (rcirc-get-buffer (rcirc-buffer-process) sender)
- (rcirc-print process sender "JOIN" sender channel))))
+ (rcirc-print process sender "JOIN" sender (funcall rcirc-channel-filter channel)))))
;; PART and KICK are handled the same way
(defun rcirc-handler-PART-or-KICK (process _response channel _sender nick _args)
@@ -3079,10 +3188,10 @@ PROCESS is the process object for the current connection."
(let* ((channel (car args))
(reason (cadr args))
(message (concat channel " " reason)))
- (rcirc-print process sender "PART" channel message)
+ (rcirc-print process sender "PART" (funcall rcirc-channel-filter channel) message)
;; print in private chat buffer if it exists
(when (rcirc-get-buffer (rcirc-buffer-process) sender)
- (rcirc-print process sender "PART" sender message))
+ (rcirc-print process sender "PART" (funcall rcirc-channel-filter channel) message))
(rcirc-handler-PART-or-KICK process "PART" channel sender sender reason)))
@@ -3094,7 +3203,7 @@ PROCESS is the process object for the current connection."
(nick (cadr args))
(reason (nth 2 args))
(message (concat nick " " channel " " reason)))
- (rcirc-print process sender "KICK" channel message t)
+ (rcirc-print process sender "KICK" (funcall rcirc-channel-filter channel) message t)
;; print in private chat buffer if it exists
(when (rcirc-get-buffer (rcirc-buffer-process) nick)
(rcirc-print process sender "KICK" nick message))
@@ -3124,7 +3233,7 @@ PROCESS is the process object for the current connection."
(rcirc-ignore-update-automatic sender)
(mapc (lambda (channel)
;; broadcast quit message each channel
- (rcirc-print process sender "QUIT" channel (apply 'concat args))
+ (rcirc-print process sender "QUIT" (funcall rcirc-channel-filter channel) (apply 'concat args))
;; record nick in quit table if they recently spoke
(rcirc-maybe-remember-nick-quit process sender channel))
(rcirc-nick-channels process sender))
@@ -3145,13 +3254,16 @@ PROCESS is the process object for the current connection."
;; print message to nick's channels
(dolist (target channels)
(rcirc-print process sender "NICK" target new-nick))
- ;; update private chat buffer, if it exists
- (let ((chat-buffer (rcirc-get-buffer process old-nick)))
- (when chat-buffer
- (with-current-buffer chat-buffer
- (rcirc-print process sender "NICK" old-nick new-nick)
- (setq rcirc-target new-nick)
- (rename-buffer (rcirc-generate-new-buffer-name process new-nick)))))
+ ;; update chat buffer, if it exists
+ (when-let ((chat-buffer (rcirc-get-buffer process old-nick)))
+ (with-current-buffer chat-buffer
+ (rcirc-print process sender "NICK" old-nick new-nick)
+ (setq rcirc-target new-nick)
+ (rename-buffer (rcirc-generate-new-buffer-name process new-nick)))
+ (setf rcirc-buffer-alist
+ (cons (cons new-nick chat-buffer)
+ (delq (assoc-string old-nick rcirc-buffer-alist t)
+ rcirc-buffer-alist))))
;; remove old nick and add new one
(with-rcirc-process-buffer process
(let ((v (gethash old-nick rcirc-nick-table)))
@@ -3234,7 +3346,7 @@ RFC1459."
(with-current-buffer buffer
(let ((setter (nth 2 args))
(time (current-time-string
- (string-to-number (cl-cadddr args)))))
+ (string-to-number (cadddr args)))))
(rcirc-print process sender "TOPIC" (cadr args)
(format "%s (%s on %s)" rcirc-topic setter time))))))
@@ -3344,7 +3456,7 @@ Passwords are stored in `rcirc-authinfo' (which see)."
(server (car i))
(nick (nth 2 i))
(method (cadr i))
- (args (cl-cdddr i)))
+ (args (cdddr i)))
(when (and (string-match server rcirc-server))
(if (and (memq method '(nickserv chanserv bitlbee))
(string-match nick rcirc-nick))
@@ -3381,6 +3493,8 @@ process object for the current connection."
(let ((self (buffer-local-value 'rcirc-nick rcirc-process))
(target (car args))
(chan (cadr args)))
+ ;; `rcirc-channel-filter' is not used here because joining
+ ;; requires an unfiltered name.
(if (string= target self)
(rcirc-print process sender "INVITE" nil
(format "%s invited you to %s"
@@ -3451,7 +3565,7 @@ is the process object for the current connection."
(let ((subcmd (cadr args)))
(dolist (cap (cddr args))
(cond ((string= subcmd "ACK")
- (push cap rcirc-acked-capabilities)
+ (push (intern (downcase cap)) rcirc-acked-capabilities)
(setq rcirc-requested-capabilities
(delete cap rcirc-requested-capabilities)))
((string= subcmd "NAK")
@@ -3525,13 +3639,36 @@ PROCESS is the process object for the current connection."
"\0" (rcirc-get-server-password rcirc-server)))))
(defun rcirc-handler-900 (process sender args _text)
- "Respond to a successful authentication response."
+ "Respond to a successful authentication response.
+SENDER is passed on to `rcirc-handler-generic'. PROCESS is the
+process object for the current connection."
(rcirc-handler-generic process "900" sender args nil)
(when (not rcirc-finished-sasl)
(setq-local rcirc-finished-sasl t)
(rcirc-send-string process "CAP" "END"))
(rcirc-join-channels-post-auth process))
+(defun rcirc-handler-FAIL (process _sender args _text)
+ "Display a FAIL message, as indicated by ARGS.
+PROCESS is the process object for the current connection."
+ (rcirc-print process nil "FAIL" nil
+ (mapconcat #'identity args " ")
+ t))
+
+(defun rcirc-handler-WARN (process _sender args _text)
+ "Display a WARN message, as indicated by ARGS.
+PROCESS is the process object for the current connection."
+ (rcirc-print process nil "WARN" nil
+ (mapconcat #'identity args " ")
+ t))
+
+(defun rcirc-handler-NOTE (process _sender args _text)
+ "Display a NOTE message, as indicated by ARGS.
+PROCESS is the process object for the current connection."
+ (rcirc-print process nil "NOTE" nil
+ (mapconcat #'identity args " ")
+ t))
+
(defgroup rcirc-faces nil
"Faces for rcirc."
diff --git a/lisp/net/rlogin.el b/lisp/net/rlogin.el
index 3136e53b80b..a7001c1310e 100644
--- a/lisp/net/rlogin.el
+++ b/lisp/net/rlogin.el
@@ -238,8 +238,8 @@ ange-ftp. If called as a function, give it no argument.
If called with a negative prefix argument, disable directory tracking
entirely.
-If called with a positive, numeric prefix argument, e.g.
-`\\[universal-argument] 1 M-x rlogin-directory-tracking-mode',
+If called with a positive, numeric prefix argument, for example
+\\[universal-argument] 1 \\[rlogin-directory-tracking-mode],
then do directory tracking but assume the remote filesystem is the same as
the local system. This only works in general if the remote machine and the
local one share the same directories (e.g. through NFS)."
diff --git a/lisp/net/sasl-cram.el b/lisp/net/sasl-cram.el
index 4022a35b391..2427f4976e3 100644
--- a/lisp/net/sasl-cram.el
+++ b/lisp/net/sasl-cram.el
@@ -24,6 +24,8 @@
;;; Commentary:
+;;; Code:
+
(require 'sasl)
(require 'hmac-md5)
diff --git a/lisp/net/sasl-digest.el b/lisp/net/sasl-digest.el
index 5afc195d4b4..3696f526b5d 100644
--- a/lisp/net/sasl-digest.el
+++ b/lisp/net/sasl-digest.el
@@ -29,9 +29,9 @@
;; It is caller's responsibility to base64-decode challenges and
;; base64-encode responses in IMAP4 AUTHENTICATE command.
;;
-;; Passphrase should be longer than 16 bytes. (See RFC 2195)
+;; Passphrase should be longer than 16 bytes. (See RFC 2195)
-;;; Commentary:
+;;; Code:
(require 'sasl)
(require 'hmac-md5)
diff --git a/lisp/net/sasl-ntlm.el b/lisp/net/sasl-ntlm.el
index dfb7e713302..9a5bba5b292 100644
--- a/lisp/net/sasl-ntlm.el
+++ b/lisp/net/sasl-ntlm.el
@@ -37,8 +37,8 @@
'(ignore ;nothing to do before making
sasl-ntlm-request ;authentication request
sasl-ntlm-response) ;response to challenge
- "A list of functions to be called in sequence for the NTLM
-authentication steps. They are called by `sasl-next-step'.")
+ "List of functions to call in sequence for the NTLM authentication steps.
+They are called by `sasl-next-step'.")
(defun sasl-ntlm-request (client _step)
"SASL step function to generate a NTLM authentication request to the server.
diff --git a/lisp/net/sasl.el b/lisp/net/sasl.el
index b7f814f7237..0a3ecf9f534 100644
--- a/lisp/net/sasl.el
+++ b/lisp/net/sasl.el
@@ -174,21 +174,24 @@ It contain at least 64 bits of entropy."
;; stolen (and renamed) from message.el
(defun sasl-unique-id-function ()
- ;; Don't use microseconds from (current-time), they may be unsupported.
+ ;; Don't use fractional seconds from timestamp; they may be unsupported.
;; Instead we use this randomly inited counter.
(setq sasl-unique-id-char
- (% (1+ (or sasl-unique-id-char (logand (random) (1- (ash 1 20)))))
- ;; (current-time) returns 16-bit ints,
- ;; and 2^16*25 just fits into 4 digits i base 36.
- (* 25 25)))
- (let ((tm (current-time)))
+ ;; 2^16 * 25 just fits into 4 digits i base 36.
+ (let ((base (* 25 25)))
+ (if sasl-unique-id-char
+ (% (1+ sasl-unique-id-char) base)
+ (random base))))
+ (let ((tm (time-convert nil 'integer)))
(concat
(sasl-unique-id-number-base36
- (+ (car tm)
- (ash (% sasl-unique-id-char 25) 16)) 4)
+ (+ (ash tm -16)
+ (ash (% sasl-unique-id-char 25) 16))
+ 4)
(sasl-unique-id-number-base36
- (+ (nth 1 tm)
- (ash (/ sasl-unique-id-char 25) 16)) 4))))
+ (+ (logand tm #xffff)
+ (ash (/ sasl-unique-id-char 25) 16))
+ 4))))
(defun sasl-unique-id-number-base36 (num len)
(if (if (< len 0)
diff --git a/lisp/net/secrets.el b/lisp/net/secrets.el
index 4102b9d322a..4217c219ad9 100644
--- a/lisp/net/secrets.el
+++ b/lisp/net/secrets.el
@@ -159,7 +159,7 @@
"Whether there is a daemon offering the Secret Service API.")
(defvar secrets-debug nil
- "Write debug messages")
+ "Write debug messages.")
(defconst secrets-service "org.freedesktop.secrets"
"The D-Bus name used to talk to Secret Service.")
diff --git a/lisp/net/shr-color.el b/lisp/net/shr-color.el
index eb78a259a8c..aa92c365f87 100644
--- a/lisp/net/shr-color.el
+++ b/lisp/net/shr-color.el
@@ -30,7 +30,7 @@
(eval-when-compile (require 'cl-lib))
(defgroup shr-color nil
- "Simple HTML Renderer colors"
+ "Simple HTML Renderer colors."
:group 'shr)
(defcustom shr-color-visible-luminance-min 40
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index 85d81b6bbcc..5f31f034303 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -40,10 +40,11 @@
(require 'image)
(require 'puny)
(require 'url-cookie)
+(require 'pixel-fill)
(require 'text-property-search)
(defgroup shr nil
- "Simple HTML Renderer"
+ "Simple HTML Renderer."
:version "25.1"
:group 'web)
@@ -162,6 +163,10 @@ cid: URL as the argument.")
(defvar shr-put-image-function #'shr-put-image
"Function called to put image and alt string.")
+(defface shr-text '((t :inherit variable-pitch-text))
+ "Face used for rendering text."
+ :version "29.1")
+
(defface shr-strike-through '((t :strike-through t))
"Face for <s> elements."
:version "24.1")
@@ -183,6 +188,11 @@ temporarily blinks with this face."
"Face for <abbr> elements."
:version "27.1")
+(defface shr-sup
+ '((t :height 0.8))
+ "Face for <sup> and <sub> elements."
+ :version "29.1")
+
(defface shr-h1
'((t :height 1.3 :weight bold))
"Face for <h1> elements."
@@ -231,7 +241,6 @@ and other things:
(defvar shr-internal-width nil)
(defvar shr-list-mode nil)
(defvar shr-content-cache nil)
-(defvar shr-kinsoku-shorten nil)
(defvar shr-table-depth 0)
(defvar shr-stylesheet nil)
(defvar shr-base nil)
@@ -247,23 +256,21 @@ and other things:
(defvar shr-target-id nil
"Target fragment identifier anchor.")
-(defvar shr-map
- (let ((map (make-sparse-keymap)))
- (define-key map "a" #'shr-show-alt-text)
- (define-key map "i" #'shr-browse-image)
- (define-key map "z" #'shr-zoom-image)
- (define-key map [?\t] #'shr-next-link)
- (define-key map [?\M-\t] #'shr-previous-link)
- (define-key map [follow-link] 'mouse-face)
- (define-key map [mouse-2] #'shr-browse-url)
- (define-key map [C-down-mouse-1] #'shr-mouse-browse-url-new-window)
- (define-key map "I" #'shr-insert-image)
- (define-key map "w" #'shr-maybe-probe-and-copy-url)
- (define-key map "u" #'shr-maybe-probe-and-copy-url)
- (define-key map "v" #'shr-browse-url)
- (define-key map "O" #'shr-save-contents)
- (define-key map "\r" #'shr-browse-url)
- map))
+(defvar-keymap shr-map
+ "a" #'shr-show-alt-text
+ "i" #'shr-browse-image
+ "z" #'shr-zoom-image
+ "TAB" #'shr-next-link
+ "C-M-i" #'shr-previous-link
+ "<follow-link>" 'mouse-face
+ "<mouse-2>" #'shr-browse-url
+ "C-<down-mouse-1>" #'shr-mouse-browse-url-new-window
+ "I" #'shr-insert-image
+ "w" #'shr-maybe-probe-and-copy-url
+ "u" #'shr-maybe-probe-and-copy-url
+ "v" #'shr-browse-url
+ "O" #'shr-save-contents
+ "RET" #'shr-browse-url)
(defvar shr-image-map
(let ((map (copy-keymap shr-map)))
@@ -305,6 +312,18 @@ and other things:
(or (not (zerop (fringe-columns 'right)))
(not (zerop (fringe-columns 'left))))))
+(defun shr--window-width ()
+ ;; Compute the width based on the window width. We need to
+ ;; adjust the available width for when the user disables
+ ;; the fringes, which will cause the display engine usurp
+ ;; one column for the continuation glyph.
+ (if (not shr-use-fonts)
+ (- (window-body-width) 1
+ (if (shr--have-one-fringe-p)
+ 1
+ 0))
+ (pixel-fill-width)))
+
;;;###autoload
(defun shr-insert-document (dom)
"Render the parsed document DOM into the current buffer.
@@ -326,21 +345,7 @@ DOM should be a parse tree as generated by
(if (not shr-use-fonts)
shr-width
(* shr-width (frame-char-width)))
- ;; Compute the width based on the window width. We need to
- ;; adjust the available width for when the user disables
- ;; the fringes, which will cause the display engine usurp
- ;; one column for the continuation glyph.
- (if (not shr-use-fonts)
- (- (window-body-width) 1
- (if (shr--have-one-fringe-p)
- 1
- 0))
- (- (window-body-width nil t)
- (* 2 (frame-char-width))
- (if (shr--have-one-fringe-p)
- 0
- (* (frame-char-width) 2))
- 1))))
+ (shr--window-width)))
(max-specpdl-size max-specpdl-size)
;; `bidi-display-reordering' is supposed to be only used for
;; debugging purposes, but Shr's naïve filling algorithm
@@ -577,7 +582,7 @@ size, and full-buffer size."
(setq shr-warning
"Not rendering the complete page because of too-deep nesting")
(when style
- (if (string-match "color\\|display\\|border-collapse" style)
+ (if (string-match-p "color\\|display\\|border-collapse" style)
(setq shr-stylesheet (nconc (shr-parse-style style)
shr-stylesheet))
(setq style nil)))
@@ -605,7 +610,7 @@ size, and full-buffer size."
(insert ? )
(shr-mark-fill start))
(put-text-property (1- (point)) (point) 'display ""))
- (put-text-property start (1+ start) 'shr-target-id id))
+ (put-text-property (1- (point)) (point) 'shr-target-id id))
;; If style is set, then this node has set the color.
(when style
(shr-colorize-region
@@ -619,43 +624,11 @@ size, and full-buffer size."
(with-temp-buffer
(let ((shr-indentation 0)
(shr-start nil)
- (shr-internal-width (- (window-body-width nil t)
- (* 2 (frame-char-width))
- ;; Adjust the window width for when
- ;; the user disables the fringes,
- ;; which causes the display engine
- ;; to usurp one column for the
- ;; continuation glyph.
- (if (and (null shr-width)
- (not (shr--have-one-fringe-p)))
- (* (frame-char-width) 2)
- 0))))
+ (shr-internal-width (shr--window-width)))
(shr-insert text)
(shr-fill-lines (point-min) (point-max))
(buffer-string)))))
-(define-inline shr-char-breakable-p (char)
- "Return non-nil if a line can be broken before and after CHAR."
- (inline-quote (aref fill-find-break-point-function-table ,char)))
-(define-inline shr-char-nospace-p (char)
- "Return non-nil if no space is required before and after CHAR."
- (inline-quote (aref fill-nospace-between-words-table ,char)))
-
-;; KINSOKU is a Japanese word meaning a rule that should not be violated.
-;; In Emacs, it is a term used for characters, e.g. punctuation marks,
-;; parentheses, and so on, that should not be placed in the beginning
-;; of a line or the end of a line.
-(define-inline shr-char-kinsoku-bol-p (char)
- "Return non-nil if a line ought not to begin with CHAR."
- (inline-letevals (char)
- (inline-quote (and (not (eq ,char ?'))
- (aref (char-category-set ,char) ?>)))))
-(define-inline shr-char-kinsoku-eol-p (char)
- "Return non-nil if a line ought not to end with CHAR."
- (inline-quote (aref (char-category-set ,char) ?<)))
-(unless (shr-char-kinsoku-bol-p (make-char 'japanese-jisx0208 33 35))
- (load "kinsoku" nil t))
-
(defun shr-pixel-column ()
(if (not shr-use-fonts)
(current-column)
@@ -669,6 +642,7 @@ size, and full-buffer size."
(car (window-text-pixel-size nil (line-beginning-position) (point))))))
(defun shr-pixel-region ()
+ (declare (obsolete nil "29.1"))
(- (shr-pixel-column)
(save-excursion
(goto-char (mark))
@@ -711,7 +685,7 @@ size, and full-buffer size."
(goto-char (point-max)))))
(t
(let ((font-start (point)))
- (when (and (string-match "\\`[ \t\n\r]" text)
+ (when (and (string-match-p "\\`[ \t\n\r]" text)
(not (bolp))
(not (eq (char-after (1- (point))) ? )))
(insert " "))
@@ -739,7 +713,7 @@ size, and full-buffer size."
(when shr-use-fonts
(put-text-property font-start (point)
'face
- (or shr-current-font 'variable-pitch)))))))))
+ (or shr-current-font 'shr-text)))))))))
(defun shr-fill-lines (start end)
(if (<= shr-internal-width 0)
@@ -788,7 +762,7 @@ size, and full-buffer size."
(while (not (eolp))
;; We have to do some folding. First find the first
;; previous point suitable for folding.
- (if (or (not (shr-find-fill-point (line-beginning-position)))
+ (if (or (not (pixel-fill-find-fill-point (line-beginning-position)))
(= (point) start))
;; We had unbreakable text (for this width), so just go to
;; the first space and carry on.
@@ -829,84 +803,6 @@ size, and full-buffer size."
(when (looking-at " $")
(delete-region (point) (line-end-position)))))))
-(defun shr-find-fill-point (start)
- (let ((bp (point))
- (end (point))
- failed)
- (while (not (or (setq failed (<= (point) start))
- (eq (preceding-char) ? )
- (eq (following-char) ? )
- (shr-char-breakable-p (preceding-char))
- (shr-char-breakable-p (following-char))
- (and (shr-char-kinsoku-bol-p (preceding-char))
- (shr-char-breakable-p (following-char))
- (not (shr-char-kinsoku-bol-p (following-char))))
- (shr-char-kinsoku-eol-p (following-char))
- (bolp)))
- (backward-char 1))
- (if failed
- ;; There's no breakable point, so we give it up.
- (let (found)
- (goto-char bp)
- ;; Don't overflow the window edge, even if
- ;; shr-kinsoku-shorten is nil.
- (unless (or shr-kinsoku-shorten (null shr-width))
- (while (setq found (re-search-forward
- "\\(\\c>\\)\\| \\|\\c<\\|\\c|"
- (line-end-position) 'move)))
- (if (and found
- (not (match-beginning 1)))
- (goto-char (match-beginning 0)))))
- (or
- (eolp)
- ;; Don't put kinsoku-bol characters at the beginning of a line,
- ;; or kinsoku-eol characters at the end of a line.
- (cond
- ;; Don't overflow the window edge, even if shr-kinsoku-shorten
- ;; is nil.
- ((or shr-kinsoku-shorten (null shr-width))
- (while (and (not (memq (preceding-char) (list ?\C-@ ?\n ? )))
- (or (shr-char-kinsoku-eol-p (preceding-char))
- (shr-char-kinsoku-bol-p (following-char))))
- (backward-char 1))
- (when (setq failed (<= (point) start))
- ;; There's no breakable point that doesn't violate kinsoku,
- ;; so we look for the second best position.
- (while (and (progn
- (forward-char 1)
- (<= (point) end))
- (progn
- (setq bp (point))
- (shr-char-kinsoku-eol-p (following-char)))))
- (goto-char bp)))
- ((shr-char-kinsoku-eol-p (preceding-char))
- ;; Find backward the point where kinsoku-eol characters begin.
- (let ((count 4))
- (while
- (progn
- (backward-char 1)
- (and (> (setq count (1- count)) 0)
- (not (memq (preceding-char) (list ?\C-@ ?\n ? )))
- (or (shr-char-kinsoku-eol-p (preceding-char))
- (shr-char-kinsoku-bol-p (following-char)))))))
- (when (setq failed (<= (point) start))
- ;; There's no breakable point that doesn't violate kinsoku,
- ;; so we go to the second best position.
- (if (looking-at "\\(\\c<+\\)\\c<")
- (goto-char (match-end 1))
- (forward-char 1))))
- ((shr-char-kinsoku-bol-p (following-char))
- ;; Find forward the point where kinsoku-bol characters end.
- (let ((count 4))
- (while (progn
- (forward-char 1)
- (and (>= (setq count (1- count)) 0)
- (shr-char-kinsoku-bol-p (following-char))
- (shr-char-breakable-p (following-char))))))))
- (when (eq (following-char) ? )
- (forward-char 1))))
- (not failed)))
-
(defun shr-parse-base (url)
;; Always chop off anchors.
(when (string-match "#.*" url)
@@ -947,7 +843,7 @@ size, and full-buffer size."
(cond ((zerop (length url))
(nth 3 base))
((or (not base)
- (string-match "\\`[a-z]*:" url))
+ (string-match-p "\\`[a-z]*:" url))
;; Absolute or empty URI
url)
((eq (aref url 0) ?/)
@@ -1132,14 +1028,14 @@ the mouse click event."
(let ((param (match-string 4 data))
(payload (url-unhex-string (match-string 5 data))))
(when (and param
- (string-match "^.*\\(;[ \t]*base64\\)$" param))
+ (string-match-p "^.*\\(;[ \t]*base64\\)$" param))
(setq payload (ignore-errors
(base64-decode-string payload))))
payload)))
;; Behind display-graphic-p test.
(declare-function image-size "image.c" (spec &optional pixels frame))
-(declare-function image-animate "image" (image &optional index limit))
+(declare-function image-animate "image" (image &optional index limit position))
(defun shr-put-image (spec alt &optional flags)
"Insert image SPEC with a string ALT. Return image.
@@ -1176,13 +1072,14 @@ element is the data blob and the second element is the content-type."
(when (and (> (current-column) 0)
(> (car (image-size image t)) 400))
(insert "\n"))
- (if (eq size 'original)
- (insert-sliced-image image (or alt "*") nil 20 1)
- (insert-image image (or alt "*")))
- (put-text-property start (point) 'image-size size)
- (when (and shr-image-animate
- (cdr (image-multi-frame-p image)))
- (image-animate image nil 60)))
+ (let ((image-pos (point)))
+ (if (eq size 'original)
+ (insert-sliced-image image (or alt "*") nil 20 1)
+ (insert-image image (or alt "*")))
+ (put-text-property start (point) 'image-size size)
+ (when (and shr-image-animate
+ (cdr (image-multi-frame-p image)))
+ (image-animate image nil 60 image-pos))))
image)
(insert (or alt ""))))
@@ -1448,7 +1345,7 @@ ones, in case fg and bg are nil."
;; Filter out blocked elements inside the SVG image.
(not (setq url (dom-attr elem ':xlink:href)))
(not shr-blocked-images)
- (not (string-match shr-blocked-images url)))
+ (not (string-match-p shr-blocked-images url)))
(insert " ")
(shr-dom-print elem)))))
(insert (format "</%s>" (dom-tag dom))))
@@ -1465,12 +1362,14 @@ ones, in case fg and bg are nil."
(defun shr-tag-sup (dom)
(let ((start (point)))
(shr-generic dom)
- (put-text-property start (point) 'display '(raise 0.2))))
+ (put-text-property start (point) 'display '(raise 0.2))
+ (add-face-text-property start (point) 'shr-sup)))
(defun shr-tag-sub (dom)
(let ((start (point)))
(shr-generic dom)
- (put-text-property start (point) 'display '(raise -0.2))))
+ (put-text-property start (point) 'display '(raise -0.2))
+ (add-face-text-property start (point) 'shr-sup)))
(defun shr-tag-p (dom)
(shr-ensure-paragraph)
@@ -1532,9 +1431,7 @@ ones, in case fg and bg are nil."
(defun shr-parse-style (style)
(when style
- (save-match-data
- (when (string-match "\n" style)
- (setq style (replace-match " " t t style))))
+ (setq style (replace-regexp-in-string "\n" " " style))
(let ((plist nil))
(dolist (elem (split-string style ";"))
(when elem
@@ -1574,15 +1471,14 @@ ones, in case fg and bg are nil."
(shr-urlify (or shr-start start) (shr-expand-url url) title))))
(defun shr-tag-abbr (dom)
- (when-let* ((title (dom-attr dom 'title))
- (start (point)))
+ (let ((title (dom-attr dom 'title))
+ (start (point)))
(shr-generic dom)
(shr-add-font start (point) 'shr-abbreviation)
- (add-text-properties
- start (point)
- (list
- 'help-echo title
- 'mouse-face 'highlight))))
+ (when title
+ (add-text-properties start (point)
+ (list 'help-echo title
+ 'mouse-face 'highlight)))))
(defun shr-tag-acronym (dom)
;; `acronym' is deprecated in favor of `abbr'.
@@ -1593,7 +1489,7 @@ ones, in case fg and bg are nil."
(let ((start (point))
url multimedia image)
(when-let* ((type (dom-attr dom 'type)))
- (when (string-match "\\`image/svg" type)
+ (when (string-match-p "\\`image/svg" type)
(setq url (dom-attr dom 'data)
image t)))
(dolist (child (dom-non-text-children dom))
@@ -1629,6 +1525,14 @@ url if no type is specified. The value should be a float in the range 0.0 to
:version "24.4"
:type '(alist :key-type regexp :value-type float))
+(defcustom shr-use-xwidgets-for-media nil
+ "If non-nil, use xwidgets to display video and audio elements.
+This also depends on Emacs being built with xwidgets capability.
+Note that this is experimental, and may lead to instability on
+some platforms."
+ :type 'boolean
+ :version "29.1")
+
(defun shr--get-media-pref (elem)
"Determine the preference for ELEM.
The preference is a float determined from `shr-prefer-media-type'."
@@ -1665,16 +1569,39 @@ The preference is a float determined from `shr-prefer-media-type'."
pref (cdr ret)))))))))
(cons url pref))
+(declare-function xwidget-webkit-execute-script "xwidget.c"
+ (xwidget script &optional callback))
+
(defun shr-tag-video (dom)
(let ((image (dom-attr dom 'poster))
(url (dom-attr dom 'src))
(start (point)))
(unless url
(setq url (car (shr--extract-best-source dom))))
- (if (> (length image) 0)
- (shr-indirect-call 'img nil image)
- (shr-insert " [video] "))
- (shr-urlify start (shr-expand-url url))))
+ (if (and shr-use-xwidgets-for-media
+ (fboundp 'make-xwidget))
+ ;; Play the video.
+ (progn
+ (require 'xwidget)
+ (let ((widget (make-xwidget
+ 'webkit
+ "Video"
+ (truncate (* (window-pixel-width) 0.8))
+ (truncate (* (window-pixel-width) 0.8 0.75)))))
+ (insert
+ (propertize
+ " [video] "
+ 'display (list 'xwidget :xwidget widget)))
+ (xwidget-webkit-execute-script
+ widget (format "document.body.innerHTML = %S;"
+ (format
+ "<style>body { margin: 0px; }</style><div style='background: black; height: 100%%; display: flex; align-items: center; justify-content: center;'><video autoplay loop muted controls style='max-width: 100%%; max-height: 100%%;'><source src=%S type='video/mp4'></source></video></div>"
+ url)))))
+ ;; No xwidgets.
+ (if (> (length image) 0)
+ (shr-indirect-call 'img nil image)
+ (shr-insert " [video] "))
+ (shr-urlify start (shr-expand-url url)))))
(defun shr-tag-audio (dom)
(let ((url (dom-attr dom 'src))
@@ -1725,7 +1652,7 @@ The preference is a float determined from `shr-prefer-media-type'."
(list :width width :height height)))))
((or shr-inhibit-images
(and shr-blocked-images
- (string-match shr-blocked-images url)))
+ (string-match-p shr-blocked-images url)))
(setq shr-start (point))
(shr-insert alt))
((and (not shr-ignore-cache)
@@ -2037,7 +1964,8 @@ BASE is the URL of the HTML being rendered."
(setq dom (or (dom-child-by-tag dom 'tbody) dom))
(let* ((shr-inhibit-images t)
(shr-table-depth (1+ shr-table-depth))
- (shr-kinsoku-shorten t)
+ ;; Fill hard in CJK languages.
+ (pixel-fill-respect-kinsoku nil)
;; Find all suggested widths.
(columns (shr-column-specs dom))
;; Compute how many pixels wide each TD should be.
@@ -2533,7 +2461,7 @@ flags that control whether to collect or render objects."
(max-width 0)
natural-width)
(when style
- (setq style (and (string-match "color" style)
+ (setq style (and (string-search "color" style)
(shr-parse-style style))))
(when bgcolor
(setq style (nconc (list (cons 'background-color bgcolor))
diff --git a/lisp/net/sieve-manage.el b/lisp/net/sieve-manage.el
index 1f08a15e570..64544bcf154 100644
--- a/lisp/net/sieve-manage.el
+++ b/lisp/net/sieve-manage.el
@@ -410,7 +410,7 @@ If BUFFER is nil, the current buffer is used."
(defun sieve-manage-capability (&optional name value buffer)
"Check if capability NAME of server BUFFER match VALUE.
-If it does, return the server value of NAME. If not returns nil.
+If it does, return the server value of NAME. If not return nil.
If VALUE is nil, do not check VALUE and return server value.
If NAME is nil, return the full server list of capabilities."
(with-current-buffer (or buffer (current-buffer))
diff --git a/lisp/net/sieve-mode.el b/lisp/net/sieve-mode.el
index 0e8fdc0a905..70cebd30396 100644
--- a/lisp/net/sieve-mode.el
+++ b/lisp/net/sieve-mode.el
@@ -132,7 +132,7 @@
(modify-syntax-entry ?\} "){" st)
(modify-syntax-entry ?\" "\"" st)
st)
- "Syntax table in use in sieve-mode buffers.")
+ "Syntax table in use in `sieve-mode' buffers.")
;; Key map definition
diff --git a/lisp/net/sieve.el b/lisp/net/sieve.el
index 6d571a0a30f..99bc0a7acd2 100644
--- a/lisp/net/sieve.el
+++ b/lisp/net/sieve.el
@@ -224,7 +224,7 @@ require \"fileinto\";
(substitute-command-keys "\\[sieve-upload]"))))
(defmacro sieve-change-region (&rest body)
- "Turns off sieve-region before executing BODY, then re-enables it after.
+ "Turn off sieve-region before executing BODY, then re-enables it after.
Used to bracket operations which move point in the sieve-buffer."
(declare (indent 0) (debug t))
`(progn
diff --git a/lisp/net/snmp-mode.el b/lisp/net/snmp-mode.el
index ae878ef3a51..10892ebf611 100644
--- a/lisp/net/snmp-mode.el
+++ b/lisp/net/snmp-mode.el
@@ -328,7 +328,7 @@ Tab indents for C code.
Comments start with -- and end with newline or another --.
Delete converts tabs to spaces as it moves back.
\\{snmp-mode-map}
-Turning on snmp-mode runs the hooks in `snmp-common-mode-hook', then
+Turning on `snmp-mode' runs the hooks in `snmp-common-mode-hook', then
`snmp-mode-hook'."
(interactive)
@@ -361,7 +361,7 @@ Tab indents for C code.
Comments start with -- and end with newline or another --.
Delete converts tabs to spaces as it moves back.
\\{snmp-mode-map}
-Turning on snmp-mode runs the hooks in `snmp-common-mode-hook',
+Turning on `snmp-mode' runs the hooks in `snmp-common-mode-hook',
then `snmpv2-mode-hook'."
(interactive)
diff --git a/lisp/net/soap-client.el b/lisp/net/soap-client.el
index de1cd9d320f..6f915e97452 100644
--- a/lisp/net/soap-client.el
+++ b/lisp/net/soap-client.el
@@ -8,7 +8,7 @@
;; Version: 3.2.0
;; Keywords: soap, web-services, comm, hypermedia
;; Package: soap-client
-;; Homepage: https://github.com/alex-hhh/emacs-soap-client
+;; URL: https://github.com/alex-hhh/emacs-soap-client
;; Package-Requires: ((cl-lib "0.6.1"))
;;FIXME: Put in `Package-Requires:' the Emacs version we expect.
@@ -718,10 +718,9 @@ representing leap seconds."
second)
minute hour day month year second-fraction datatype time-zone)
(let ((time
- (apply
- #'encode-time (list
- (if new-decode-time new-decode-time-second second)
- minute hour day month year nil nil time-zone))))
+ (encode-time (list
+ (if new-decode-time new-decode-time-second second)
+ minute hour day month year nil nil time-zone))))
(if new-decode-time
(with-no-warnings (decode-time time nil t))
(decode-time time))))))
@@ -860,7 +859,7 @@ contains a reference, retrieve the type of the reference."
(if complex-type
(setq type (soap-xs-parse-complex-type (car complex-type)))
;; else
- (error "Soap-xs-parse-element: missing type or ref"))))))
+ (error "soap-xs-parse-element: Missing type or ref"))))))
(make-soap-xs-element :name name
;; Use the full namespace name for now, we will
@@ -2874,7 +2873,7 @@ decode function to perform the actual decoding."
(unless wtype
;; The node has type info encoded in it, but we don't know how to
;; decode it...
- (error "Soap-decode-array: node has unknown type: %s" type)))
+ (error "soap-decode-array: Node has unknown type: %s" type)))
(dolist (e contents)
(when (consp e)
(push (if wtype
diff --git a/lisp/net/soap-inspect.el b/lisp/net/soap-inspect.el
index 6f9ce6a2d69..eca338eb22d 100644
--- a/lisp/net/soap-inspect.el
+++ b/lisp/net/soap-inspect.el
@@ -6,7 +6,7 @@
;; Created: October 2010
;; Keywords: soap, web-services, comm, hypermedia
;; Package: soap-client
-;; Homepage: https://github.com/alex-hhh/emacs-soap-client
+;; URL: https://github.com/alex-hhh/emacs-soap-client
;; This file is part of GNU Emacs.
@@ -114,7 +114,7 @@ This is a specialization of `soap-sample-value' for
(cond
((soap-xs-simple-type-enumeration type)
(let ((enumeration (soap-xs-simple-type-enumeration type)))
- (nth (random (length enumeration)) enumeration)))
+ (and enumeration (seq-random-elt enumeration))))
((soap-xs-simple-type-pattern type)
(format "a string matching %s" (soap-xs-simple-type-pattern type)))
((soap-xs-simple-type-length-range type)
@@ -124,7 +124,7 @@ This is a specialization of `soap-sample-value' for
(format "a string between %d and %d chars long" low high))
(low (format "a string at least %d chars long" low))
(high (format "a string at most %d chars long" high))
- (t (format "a string OOPS")))))
+ (t "a string OOPS"))))
((soap-xs-simple-type-integer-range type)
(cl-destructuring-bind (min . max) (soap-xs-simple-type-integer-range type)
(cond
@@ -134,7 +134,7 @@ This is a specialization of `soap-sample-value' for
(t (random 100)))))
((consp (soap-xs-simple-type-base type)) ; an union of values
(let ((base (soap-xs-simple-type-base type)))
- (soap-sample-value (nth (random (length base)) base))))
+ (soap-sample-value (and base (seq-random-elt base)))))
((soap-xs-basic-type-p (soap-xs-simple-type-base type))
(soap-sample-value (soap-xs-simple-type-base type))))))
@@ -220,7 +220,7 @@ to its sub elements. If ELEMENT is the WSDL document itself, the
entire WSDL can be inspected."
(let ((inspect (get (soap-type-of element) 'soap-inspect)))
(unless inspect
- (error "Soap-inspect: no inspector for element"))
+ (error "soap-inspect: No inspector for element"))
(with-current-buffer (get-buffer-create "*soap-inspect*")
(setq buffer-read-only t)
diff --git a/lisp/net/socks.el b/lisp/net/socks.el
index 78a261fd83e..be299603a8c 100644
--- a/lisp/net/socks.el
+++ b/lisp/net/socks.el
@@ -154,7 +154,7 @@
(defcustom socks-server
(list "Default server" "socks" 1080 5)
- ""
+ "Socks server."
:type '(list
(string :format "" :value "Default server")
(string :tag "Server")
@@ -453,7 +453,7 @@ When ATYPE indicates an IP, param ADDRESS must be given as raw bytes."
;; Replacement functions for open-network-stream, etc.
(defvar socks-noproxy nil
- "List of regexps matching hosts that we should not socksify connections to")
+ "List of regexps matching hosts that we should not socksify connections to.")
(defun socks-find-route (host _service)
(let ((route socks-server)
diff --git a/lisp/net/telnet.el b/lisp/net/telnet.el
index bb65ecaa981..1cf07a5ccec 100644
--- a/lisp/net/telnet.el
+++ b/lisp/net/telnet.el
@@ -73,8 +73,9 @@ LOGIN-NAME, which is optional, says what to log in as on that machine.")
(defvar telnet-prompt-pattern "^[^#$%>\n]*[#$%>] *")
(defvar telnet-replace-c-g nil)
(defvar-local telnet-remote-echoes t
- "True if the telnet process will echo input.")
-(defvar-local telnet-interrupt-string "\C-c" "String sent by C-c.")
+ "Non-nil if the telnet process will echo input.")
+(defvar-local telnet-interrupt-string "\C-c"
+ "String sent by C-c.")
(defvar-local telnet-count 0
"Number of output strings from telnet process while looking for password.")
@@ -83,8 +84,9 @@ LOGIN-NAME, which is optional, says what to log in as on that machine.")
"Program to run to open a telnet connection.")
(defvar telnet-initial-count -50
- "Initial value of `telnet-count'. Should be set to the negative of the
-number of terminal writes telnet will make setting up the host connection.")
+ "Initial value of `telnet-count'.
+Should be set to the negative of the number of terminal writes
+telnet will make setting up the host connection.")
(defvar telnet-maximum-count 4
"Maximum value `telnet-count' can have.
@@ -105,7 +107,7 @@ rejecting one login and prompting again for a username and password.")
(let (revert-buffer-function)
(revert-buffer ignore-auto noconfirm))
(if (or noconfirm
- (yes-or-no-p (format "Restart connection? ")))
+ (yes-or-no-p "Restart connection? "))
(apply telnet-connect-command))))
(defun telnet-c-z ()
@@ -122,7 +124,7 @@ rejecting one login and prompting again for a username and password.")
;;maybe should have a flag for when have found type
(defun telnet-check-software-type-initialize (string)
- "Tries to put correct initializations in. Needs work."
+ "Try to put correct initializations in. Needs work."
(let ((case-fold-search t))
(cond ((string-match "unix" string)
(setq telnet-prompt-pattern comint-prompt-regexp)
@@ -245,7 +247,7 @@ Normally input is edited in Emacs and sent a line at a time."
(define-derived-mode telnet-mode comint-mode "Telnet"
"This mode is for using telnet (or rsh) from a buffer to another host.
-It has most of the same commands as comint-mode.
+It has most of the same commands as `comint-mode'.
There is a variable `telnet-interrupt-string' which is the character
sent to try to stop execution of a job on the remote host.
Data is sent to the remote host when RET is typed."
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index c16e232c6d5..b662e0bf6cf 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -107,7 +107,8 @@ It is used for TCP/IP devices."
;;;###tramp-autoload
(defconst tramp-adb-file-name-handler-alist
- '((access-file . tramp-handle-access-file)
+ '(;; `abbreviate-file-name' performed by default handler.
+ (access-file . tramp-handle-access-file)
(add-name-to-file . tramp-handle-add-name-to-file)
;; `byte-compiler-base-file-name' performed by default handler.
(copy-directory . tramp-handle-copy-directory)
@@ -128,8 +129,7 @@ It is used for TCP/IP devices."
(file-attributes . tramp-adb-handle-file-attributes)
(file-directory-p . tramp-handle-file-directory-p)
(file-equal-p . tramp-handle-file-equal-p)
- ;; FIXME: This is too sloppy.
- (file-executable-p . tramp-handle-file-exists-p)
+ (file-executable-p . tramp-adb-handle-file-executable-p)
(file-exists-p . tramp-handle-file-exists-p)
(file-in-directory-p . tramp-handle-file-in-directory-p)
(file-local-copy . tramp-adb-handle-file-local-copy)
@@ -147,7 +147,7 @@ It is used for TCP/IP devices."
(file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
(file-notify-valid-p . tramp-handle-file-notify-valid-p)
(file-ownership-preserved-p . ignore)
- (file-readable-p . tramp-handle-file-exists-p)
+ (file-readable-p . tramp-adb-handle-file-readable-p)
(file-regular-p . tramp-handle-file-regular-p)
(file-remote-p . tramp-handle-file-remote-p)
(file-selinux-context . tramp-handle-file-selinux-context)
@@ -192,11 +192,10 @@ It is used for TCP/IP devices."
;; It must be a `defsubst' in order to push the whole code into
;; tramp-loaddefs.el. Otherwise, there would be recursive autoloading.
;;;###tramp-autoload
-(defsubst tramp-adb-file-name-p (filename)
- "Check if it's a FILENAME for ADB."
- (and (tramp-tramp-file-p filename)
- (string= (tramp-file-name-method (tramp-dissect-file-name filename))
- tramp-adb-method)))
+(defsubst tramp-adb-file-name-p (vec-or-filename)
+ "Check if it's a VEC-OR-FILENAME for ADB."
+ (when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
+ (string= (tramp-file-name-method vec) tramp-adb-method)))
;;;###tramp-autoload
(defun tramp-adb-file-name-handler (operation &rest args)
@@ -307,7 +306,7 @@ arguments to pass to the OPERATION."
(directory &optional full match nosort id-format count)
"Like `directory-files-and-attributes' for Tramp files."
(unless (file-exists-p directory)
- (tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
+ (tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
(when (file-directory-p directory)
(with-parsed-tramp-file-name (expand-file-name directory) nil
(copy-tree
@@ -361,7 +360,7 @@ arguments to pass to the OPERATION."
(tramp-message vec 5 "Finding a suitable `ls' command")
(cond
;; Support Android derived systems where "ls" command is provided
- ;; by GNU Coreutils. Force "ls" to print one column and set
+ ;; by GNU Coreutils. Force "ls" to print one column and set
;; time-style to imitate other "ls" flavors.
((tramp-adb-send-command-and-check
vec (concat "ls --time-style=long-iso "
@@ -416,6 +415,8 @@ Emacs dired can't find files."
(defun tramp-adb-ls-output-time-less-p (a b)
"Sort \"ls\" output by time, descending."
(let (time-a time-b)
+ ;; Once we can assume Emacs 27 or later, the two calls
+ ;; (apply #'encode-time X) can be replaced by (encode-time X).
(string-match tramp-adb-ls-date-regexp a)
(setq time-a (apply #'encode-time (parse-time-string (match-string 0 a))))
(string-match tramp-adb-ls-date-regexp b)
@@ -442,7 +443,9 @@ Emacs dired can't find files."
(make-directory par parents))))
(tramp-flush-directory-properties v localname)
(unless (or (tramp-adb-send-command-and-check
- v (format "mkdir %s" (tramp-shell-quote-argument localname)))
+ v (format "mkdir -m %#o %s"
+ (default-file-modes)
+ (tramp-shell-quote-argument localname)))
(and parents (file-directory-p dir)))
(tramp-error v 'file-error "Couldn't make directory %s" dir))))
@@ -498,7 +501,7 @@ Emacs dired can't find files."
"Like `file-local-copy' for Tramp files."
(with-parsed-tramp-file-name filename nil
(unless (file-exists-p (file-truename filename))
- (tramp-compat-file-missing v filename))
+ (tramp-error v 'file-missing filename))
(let ((tmpfile (tramp-compat-make-temp-file filename)))
(with-tramp-progress-reporter
v 3 (format "Fetching %s to tmp file %s" filename tmpfile)
@@ -513,28 +516,31 @@ Emacs dired can't find files."
(set-file-modes tmpfile (logior (or (file-modes filename) 0) #o0400)))
tmpfile)))
+(defun tramp-adb-handle-file-executable-p (filename)
+ "Like `file-executable-p' for Tramp files."
+ (with-parsed-tramp-file-name filename nil
+ (with-tramp-file-property v localname "file-executable-p"
+ (tramp-adb-send-command-and-check
+ v (format "test -x %s" (tramp-shell-quote-argument localname))))))
+
+(defun tramp-adb-handle-file-readable-p (filename)
+ "Like `file-readable-p' for Tramp files."
+ (with-parsed-tramp-file-name filename nil
+ (with-tramp-file-property v localname "file-readable-p"
+ (or (tramp-handle-file-readable-p filename)
+ (tramp-adb-send-command-and-check
+ v (format "test -r %s" (tramp-shell-quote-argument localname)))))))
+
(defun tramp-adb-handle-file-writable-p (filename)
- "Like `file-writable-p' for Tramp files.
-But handle the case, if the \"test\" command is not available."
+ "Like `file-writable-p' for Tramp files."
(with-parsed-tramp-file-name filename nil
(with-tramp-file-property v localname "file-writable-p"
- (if (tramp-adb-find-test-command v)
- (if (file-exists-p filename)
- (tramp-adb-send-command-and-check
- v (format "test -w %s" (tramp-shell-quote-argument localname)))
- (and
- (file-directory-p (file-name-directory filename))
- (file-writable-p (file-name-directory filename))))
-
- ;; Missing "test" command on Android < 4.
- (let ((rw-path "/data/data"))
- (tramp-message
- v 5
- "Not implemented yet (assuming \"/data/data\" is writable): %s"
- localname)
- (and (>= (length localname) (length rw-path))
- (string= (substring localname 0 (length rw-path))
- rw-path)))))))
+ (if (file-exists-p filename)
+ (tramp-adb-send-command-and-check
+ v (format "test -w %s" (tramp-shell-quote-argument localname)))
+ (and
+ (file-directory-p (file-name-directory filename))
+ (file-writable-p (file-name-directory filename)))))))
(defun tramp-adb-handle-write-region
(start end filename &optional append visit lockname mustbenew)
@@ -546,7 +552,7 @@ But handle the case, if the \"test\" command is not available."
(or (eq mustbenew 'excl)
(not
(y-or-n-p
- (format "File %s exists; overwrite anyway? " filename)))))
+ (format "File %s exists; overwrite anyway?" filename)))))
(tramp-error v 'file-already-exists filename))
(let ((file-locked (eq (file-locked-p lockname) t))
@@ -587,8 +593,7 @@ But handle the case, if the \"test\" command is not available."
;; Set file modification time.
(when (or (eq visit t) (stringp visit))
(set-visited-file-modtime
- (or (tramp-compat-file-attribute-modification-time
- (file-attributes filename))
+ (or (file-attribute-modification-time (file-attributes filename))
(current-time))))
;; Unlock file.
@@ -598,7 +603,7 @@ But handle the case, if the \"test\" command is not available."
;; The end.
(when (and (null noninteractive)
- (or (eq visit t) (null visit) (stringp visit)))
+ (or (eq visit t) (string-or-null-p visit)))
(tramp-message v 0 "Wrote %s" filename))
(run-hooks 'tramp-handle-write-region-hook))))
@@ -656,7 +661,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(jka-compr-inhibit t))
(with-parsed-tramp-file-name (if t1 filename newname) nil
(unless (file-exists-p filename)
- (tramp-compat-file-missing v filename))
+ (tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@@ -716,8 +721,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(when keep-date
(tramp-compat-set-file-times
newname
- (tramp-compat-file-attribute-modification-time
- (file-attributes filename))
+ (file-attribute-modification-time (file-attributes filename))
(unless ok-if-already-exists 'nofollow)))))
(defun tramp-adb-handle-rename-file
@@ -738,7 +742,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(jka-compr-inhibit t))
(with-parsed-tramp-file-name (if t1 filename newname) nil
(unless (file-exists-p filename)
- (tramp-compat-file-missing v filename))
+ (tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@@ -925,16 +929,14 @@ implementation will be used."
(coding (plist-get args :coding))
(noquery (plist-get args :noquery))
(connection-type
- (if (plist-member args :connection-type)
- (plist-get args :connection-type)
- tramp-process-connection-type))
+ (or (plist-get args :connection-type) process-connection-type))
(filter (plist-get args :filter))
(sentinel (plist-get args :sentinel))
(stderr (plist-get args :stderr)))
(unless (stringp name)
(signal 'wrong-type-argument (list #'stringp name)))
- (unless (or (null buffer) (bufferp buffer) (stringp buffer))
- (signal 'wrong-type-argument (list #'stringp buffer)))
+ (unless (or (bufferp buffer) (string-or-null-p buffer))
+ (signal 'wrong-type-argument (list #'bufferp buffer)))
(unless (consp command)
(signal 'wrong-type-argument (list #'consp command)))
(unless (or (null coding)
@@ -943,13 +945,15 @@ implementation will be used."
(memq (car coding) coding-system-list)
(memq (cdr coding) coding-system-list)))
(signal 'wrong-type-argument (list #'symbolp coding)))
- (unless (memq connection-type '(nil pipe t pty))
+ (when (eq connection-type t)
+ (setq connection-type 'pty))
+ (unless (memq connection-type '(nil pipe pty))
(signal 'wrong-type-argument (list #'symbolp connection-type)))
- (unless (or (null filter) (functionp filter))
+ (unless (or (null filter) (eq filter t) (functionp filter))
(signal 'wrong-type-argument (list #'functionp filter)))
(unless (or (null sentinel) (functionp sentinel))
(signal 'wrong-type-argument (list #'functionp sentinel)))
- (unless (or (null stderr) (bufferp stderr) (stringp stderr))
+ (unless (or (bufferp stderr) (string-or-null-p stderr))
(signal 'wrong-type-argument (list #'bufferp stderr)))
(when (and (stringp stderr) (tramp-tramp-file-p stderr)
(not (tramp-equal-remote default-directory stderr)))
@@ -1041,12 +1045,13 @@ implementation will be used."
(rename-file remote-tmpstderr stderr))))
;; Read initial output. Remove the first
;; line, which is the command echo.
- (while
- (progn
- (goto-char (point-min))
- (not (re-search-forward "[\n]" nil t)))
- (tramp-accept-process-output p 0))
- (delete-region (point-min) (point))
+ (unless (eq filter t)
+ (while
+ (progn
+ (goto-char (point-min))
+ (not (re-search-forward "[\n]" nil t)))
+ (tramp-accept-process-output p 0))
+ (delete-region (point-min) (point)))
;; Provide error buffer. This shows only
;; initial error messages; messages arriving
;; later on will be inserted when the
@@ -1139,12 +1144,6 @@ error and non-nil on success."
(let ((inhibit-read-only t)) (delete-region (point-min) (point-max)))
(zerop (apply #'tramp-call-process vec tramp-adb-program nil t nil args))))
-(defun tramp-adb-find-test-command (vec)
- "Check whether the ash has a builtin \"test\" command.
-This happens for Android >= 4.0."
- (with-tramp-connection-property vec "test"
- (tramp-adb-send-command-and-check vec "type test")))
-
;; Connection functions
(defun tramp-adb-send-command (vec command &optional neveropen nooutput)
@@ -1271,7 +1270,7 @@ connection if a previous connection has died for some reason."
(list "-s" device "shell")
(list "shell")))
(p (let ((default-directory
- (tramp-compat-temporary-file-directory)))
+ tramp-compat-temporary-file-directory))
(apply #'start-process (tramp-get-connection-name vec) buf
tramp-adb-program args)))
(prompt (md5 (concat (prin1-to-string process-environment)
@@ -1350,22 +1349,18 @@ connection if a previous connection has died for some reason."
;; Mark it as connected.
(tramp-set-connection-property p "connected" t)))))))
-;;; Default connection-local variables for Tramp:
-;; `connection-local-set-profile-variables' and
-;; `connection-local-set-profiles' exists since Emacs 26.1.
+;;; Default connection-local variables for Tramp.
(defconst tramp-adb-connection-local-default-shell-variables
'((shell-file-name . "/system/bin/sh")
(shell-command-switch . "-c"))
"Default connection-local shell variables for remote adb connections.")
-(tramp-compat-funcall
- 'connection-local-set-profile-variables
+(connection-local-set-profile-variables
'tramp-adb-connection-local-default-shell-profile
tramp-adb-connection-local-default-shell-variables)
(with-eval-after-load 'shell
- (tramp-compat-funcall
- 'connection-local-set-profiles
+ (connection-local-set-profiles
`(:application tramp :protocol ,tramp-adb-method)
'tramp-adb-connection-local-default-shell-profile))
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el
index 67798e892ab..b44a4e86aad 100644
--- a/lisp/net/tramp-archive.el
+++ b/lisp/net/tramp-archive.el
@@ -54,6 +54,7 @@
;; * ".ar" - UNIX archiver formats
;; * ".cab", ".CAB" - Microsoft Windows cabinets
;; * ".cpio" - CPIO archives
+;; * ".crate" - Cargo (Rust) packages
;; * ".deb" - Debian packages
;; * ".depot" - HP-UX SD depots
;; * ".exe" - Self extracting Microsoft Windows EXE files
@@ -103,7 +104,7 @@
;; It is even possible to access file archives in file archives, as
;; (find-file
-;; "http://ftp.debian.org/debian/pool/main/c/coreutils/coreutils_8.28-1_amd64.deb/control.tar.gz/control")
+;; "https://ftp.debian.org/debian/pool/main/c/coreutils/coreutils_8.28-1_amd64.deb/control.tar.gz/control")
;;; Code:
@@ -141,6 +142,7 @@
"ar" ;; UNIX archiver formats.
"cab" "CAB" ;; Microsoft Windows cabinets.
"cpio" ;; CPIO archives.
+ "crate" ;; Cargo (Rust) packages. Not in libarchive testsuite.
"deb" ;; Debian packages. Not in libarchive testsuite.
"depot" ;; HP-UX SD depot. Not in libarchive testsuite.
"exe" ;; Self extracting Microsoft Windows EXE files.
@@ -190,7 +192,7 @@ It must be supported by libarchive(3).")
;; In older Emacsen (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-loaddefs.el. But it exists, when tramp-archive.el is loaded.
;;;###tramp-autoload
(defconst tramp-archive-file-name-regexp
(ignore-errors (tramp-archive-autoload-file-name-regexp))
@@ -211,7 +213,8 @@ It must be supported by libarchive(3).")
;; New handlers should be added here.
;;;###tramp-autoload
(defconst tramp-archive-file-name-handler-alist
- '((access-file . tramp-archive-handle-access-file)
+ '(;; `abbreviate-file-name' performed by default handler.
+ (access-file . tramp-archive-handle-access-file)
(add-name-to-file . tramp-archive-handle-not-implemented)
;; `byte-compiler-base-file-name' performed by default handler.
;; `copy-directory' performed by default handler.
@@ -353,6 +356,7 @@ arguments to pass to the OPERATION."
;;;###autoload
(progn (defun tramp-archive-autoload-file-name-handler (operation &rest args)
"Load Tramp archive file name handler, and perform OPERATION."
+ (defvar tramp-archive-autoload)
(when tramp-archive-enabled
;; We cannot use `tramp-compat-temporary-file-directory' here due
;; to autoload. When installing Tramp's GNU ELPA package, there
@@ -360,7 +364,6 @@ arguments to pass to the OPERATION."
;; overload this.
(let ((default-directory temporary-file-directory)
(tramp-archive-autoload t))
- tramp-archive-autoload ; Silence byte compiler.
(apply #'tramp-autoload-file-name-handler operation args)))))
;;;###autoload
@@ -618,7 +621,7 @@ offered."
(defun tramp-archive-handle-file-system-info (filename)
"Like `file-system-info' for file archives."
(with-parsed-tramp-archive-file-name filename nil
- (list (tramp-compat-file-attribute-size (file-attributes archive)) 0 0)))
+ (list (file-attribute-size (file-attributes archive)) 0 0)))
(defun tramp-archive-handle-file-truename (filename)
"Like `file-truename' for file archives."
@@ -658,7 +661,7 @@ offered."
;; mounted directory, it is returned as it. Not what we want.
(with-parsed-tramp-archive-file-name default-directory nil
(let ((default-directory (file-name-directory archive)))
- (tramp-compat-temporary-file-directory))))
+ (temporary-file-directory))))
(defun tramp-archive-handle-not-implemented (operation &rest args)
"Generic handler for operations not implemented for file archives."
diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el
index 5a00915f4f0..b909c5706d6 100644
--- a/lisp/net/tramp-cache.el
+++ b/lisp/net/tramp-cache.el
@@ -49,8 +49,6 @@
;; an open connection. Examples: "scripts" keeps shell script
;; definitions already sent to the remote shell, "last-cmd-time" is
;; the time stamp a command has been sent to the remote process.
-;; "lock-pid" is the timestamp a (network) process is created, it is
-;; used instead of the pid in file locks.
;;
;; - The key is nil. These are temporary properties related to the
;; local machine. Examples: "parse-passwd" and "parse-group" keep
@@ -101,8 +99,7 @@ details see the info pages."
(choice :tag " Value" sexp))))
;;;###tramp-autoload
-(defcustom tramp-persistency-file-name
- (expand-file-name (locate-user-emacs-file "tramp"))
+(defcustom tramp-persistency-file-name (locate-user-emacs-file "tramp")
"File which keeps connection history for Tramp connections."
:group 'tramp
:type 'file)
@@ -225,7 +222,9 @@ Return VALUE."
(defun tramp-flush-file-upper-properties (key file)
"Remove some properties of FILE's upper directory."
(when (file-name-absolute-p file)
- (let ((file (directory-file-name (file-name-directory file))))
+ ;; `file-name-directory' can return nil, for example for "~".
+ (when-let ((file (file-name-directory file))
+ (file (directory-file-name file)))
;; Unify localname. Remove hop from `tramp-file-name' structure.
(setq file (tramp-compat-file-name-unquote file)
key (copy-tramp-file-name key))
@@ -319,12 +318,7 @@ KEY identifies the connection, it is either a process or a
used to cache connection properties of the local machine.
If KEY is `tramp-cache-undefined', or if the value is not set for
the connection, return DEFAULT."
- ;; Unify key by removing localname and hop from `tramp-file-name'
- ;; structure. Work with a copy in order to avoid side effects.
- (when (tramp-file-name-p key)
- (setq key (copy-tramp-file-name key))
- (setf (tramp-file-name-localname key) nil
- (tramp-file-name-hop key) nil))
+ (setq key (tramp-file-name-unify key))
(let* ((hash (tramp-get-hash-table key))
(cached (if (hash-table-p hash)
(gethash property hash tramp-cache-undefined)
@@ -350,12 +344,7 @@ used to cache connection properties of the local machine. If KEY
is `tramp-cache-undefined', nothing is set.
PROPERTY is set persistent when KEY is a `tramp-file-name' structure.
Return VALUE."
- ;; Unify key by removing localname and hop from `tramp-file-name'
- ;; structure. Work with a copy in order to avoid side effects.
- (when (tramp-file-name-p key)
- (setq key (copy-tramp-file-name key))
- (setf (tramp-file-name-localname key) nil
- (tramp-file-name-hop key) nil))
+ (setq key (tramp-file-name-unify key))
(when-let ((hash (tramp-get-hash-table key)))
(puthash property value hash))
(setq tramp-cache-data-changed
@@ -379,12 +368,7 @@ KEY identifies the connection, it is either a process or a
`tramp-file-name' structure. A special case is nil, which is
used to cache connection properties of the local machine.
PROPERTY is set persistent when KEY is a `tramp-file-name' structure."
- ;; Unify key by removing localname and hop from `tramp-file-name'
- ;; structure. Work with a copy in order to avoid side effects.
- (when (tramp-file-name-p key)
- (setq key (copy-tramp-file-name key))
- (setf (tramp-file-name-localname key) nil
- (tramp-file-name-hop key) nil))
+ (setq key (tramp-file-name-unify key))
(when-let ((hash (tramp-get-hash-table key)))
(remhash property hash))
(setq tramp-cache-data-changed
@@ -397,12 +381,7 @@ PROPERTY is set persistent when KEY is a `tramp-file-name' structure."
KEY identifies the connection, it is either a process or a
`tramp-file-name' structure. A special case is nil, which is
used to cache connection properties of the local machine."
- ;; Unify key by removing localname and hop from `tramp-file-name'
- ;; structure. Work with a copy in order to avoid side effects.
- (when (tramp-file-name-p key)
- (setq key (copy-tramp-file-name key))
- (setf (tramp-file-name-localname key) nil
- (tramp-file-name-hop key) nil))
+ (setq key (tramp-file-name-unify key))
(tramp-message
key 7 "%s %s" key
(when-let ((hash (gethash key tramp-cache-data)))
diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el
index 6278fd302af..2eaebebed9f 100644
--- a/lisp/net/tramp-cmds.el
+++ b/lisp/net/tramp-cmds.el
@@ -67,7 +67,7 @@ SYNTAX can be one of the symbols `default' (default),
nil
(mapcar
(lambda (x)
- (with-current-buffer x (when (tramp-tramp-file-p default-directory) x)))
+ (when (tramp-tramp-file-p (tramp-get-default-directory x)) x))
(buffer-list))))
;;;###tramp-autoload
@@ -131,6 +131,8 @@ When called interactively, a Tramp connection has to be selected."
(buf (list (get-buffer (tramp-buffer-name vec))
(unless keep-debug
(get-buffer (tramp-debug-buffer-name vec)))
+ (unless keep-debug
+ (get-buffer (tramp-trace-buffer-name vec)))
(tramp-get-connection-property vec "process-buffer" nil)))
(when (bufferp buf) (kill-buffer buf)))
@@ -312,7 +314,7 @@ The remote connection identified by SOURCE is flushed by
(if (null connections)
(tramp-user-error nil "There are no remote connections.")
(setq source
- ;; Likely, the source remote connection is broken. So we
+ ;; Likely, the source remote connection is broken. So we
;; shall avoid any action on it.
(let (non-essential)
(completing-read-default
@@ -591,9 +593,8 @@ buffer in your bug report.
(defun tramp-reporter-dump-variable (varsym mailbuf)
"Pretty-print the value of the variable in symbol VARSYM."
- (let* ((reporter-eval-buffer (symbol-value 'reporter-eval-buffer))
- (val (with-current-buffer reporter-eval-buffer
- (symbol-value varsym))))
+ (when-let ((reporter-eval-buffer reporter-eval-buffer)
+ (val (buffer-local-value varsym reporter-eval-buffer)))
(if (hash-table-p val)
;; Pretty print the cache.
@@ -717,7 +718,7 @@ the debug buffer(s).")
(setq buffer-read-only t)
(goto-char (point-min))
- (when (y-or-n-p "Do you want to append the buffer(s)? ")
+ (when (y-or-n-p "Do you want to append the buffer(s)?")
;; OK, let's send. First we delete the buffer list.
(kill-buffer nil)
(switch-to-buffer curbuf)
diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el
index b713d5eae82..627ff1edaec 100644
--- a/lisp/net/tramp-compat.el
+++ b/lisp/net/tramp-compat.el
@@ -23,17 +23,12 @@
;;; Commentary:
-;; Tramp's main Emacs version for development is Emacs 28. This
-;; package provides compatibility functions for Emacs 25, Emacs 26 and
-;; Emacs 27.
+;; Tramp's main Emacs version for development is Emacs 29. This
+;; package provides compatibility functions for Emacs 26, Emacs 27 and
+;; Emacs 28.
;;; Code:
-;; In Emacs 25, `tramp-unload-file-name-handlers' is not autoloaded.
-;; So we declare it here in order to avoid recursive load. This will
-;; be overwritten in tramp.el.
-(defun tramp-unload-file-name-handlers () ".")
-
(require 'auth-source)
(require 'format-spec)
(require 'ls-lisp) ;; Due to `tramp-handle-insert-directory'.
@@ -42,8 +37,6 @@
(require 'subr-x)
(declare-function tramp-error "tramp")
-;; `temporary-file-directory' as function is introduced with Emacs 26.1.
-(declare-function tramp-handle-temporary-file-directory "tramp")
(declare-function tramp-tramp-file-p "tramp")
(defvar tramp-temp-name-prefix)
@@ -63,154 +56,39 @@
`(when (functionp ,function)
(with-no-warnings (funcall ,function ,@arguments))))
-(defsubst tramp-compat-temporary-file-directory ()
- "Return name of directory for temporary files.
-It is the default value of `temporary-file-directory'."
- ;; We must return a local directory. If it is remote, we could run
- ;; into an infloop.
- (eval (car (get 'temporary-file-directory 'standard-value)) t))
+;; We must use a local directory. If it is remote, we could run into
+;; an infloop.
+(defconst tramp-compat-temporary-file-directory
+ (eval (car (get 'temporary-file-directory 'standard-value)) t)
+ "The default value of `temporary-file-directory'.")
(defsubst tramp-compat-make-temp-name ()
"Generate a local temporary file name (compat function)."
(make-temp-name
(expand-file-name
- tramp-temp-name-prefix (tramp-compat-temporary-file-directory))))
+ tramp-temp-name-prefix tramp-compat-temporary-file-directory)))
(defsubst tramp-compat-make-temp-file (f &optional dir-flag)
"Create a local temporary file (compat function).
Add the extension of F, if existing."
(make-temp-file
(expand-file-name
- tramp-temp-name-prefix (tramp-compat-temporary-file-directory))
+ tramp-temp-name-prefix tramp-compat-temporary-file-directory)
dir-flag (file-name-extension f t)))
-;; `temporary-file-directory' as function is introduced with Emacs 26.1.
-(defalias 'tramp-compat-temporary-file-directory-function
- (if (fboundp 'temporary-file-directory)
- #'temporary-file-directory
- #'tramp-handle-temporary-file-directory))
-
-;; `file-attribute-*' are introduced in Emacs 26.1.
-
-(defalias 'tramp-compat-file-attribute-type
- (if (fboundp 'file-attribute-type)
- #'file-attribute-type
- (lambda (attributes)
- "The type field in ATTRIBUTES returned by `file-attributes'.
-The value is either t for directory, string (name linked to) for
-symbolic link, or nil."
- (nth 0 attributes))))
-
-(defalias 'tramp-compat-file-attribute-link-number
- (if (fboundp 'file-attribute-link-number)
- #'file-attribute-link-number
- (lambda (attributes)
- "Return the number of links in ATTRIBUTES returned by `file-attributes'."
- (nth 1 attributes))))
-
-(defalias 'tramp-compat-file-attribute-user-id
- (if (fboundp 'file-attribute-user-id)
- #'file-attribute-user-id
- (lambda (attributes)
- "The UID field in ATTRIBUTES returned by `file-attributes'.
-This is either a string or a number. If a string value cannot be
-looked up, a numeric value, either an integer or a float, is
-returned."
- (nth 2 attributes))))
-
-(defalias 'tramp-compat-file-attribute-group-id
- (if (fboundp 'file-attribute-group-id)
- #'file-attribute-group-id
- (lambda (attributes)
- "The GID field in ATTRIBUTES returned by `file-attributes'.
-This is either a string or a number. If a string value cannot be
-looked up, a numeric value, either an integer or a float, is
-returned."
- (nth 3 attributes))))
-
-(defalias 'tramp-compat-file-attribute-access-time
- (if (fboundp 'file-attribute-access-time)
- #'file-attribute-access-time
- (lambda (attributes)
- "The last access time in ATTRIBUTES returned by `file-attributes'.
-This a Lisp timestamp in the style of `current-time'."
- (nth 4 attributes))))
-
-(defalias 'tramp-compat-file-attribute-modification-time
- (if (fboundp 'file-attribute-modification-time)
- #'file-attribute-modification-time
- (lambda (attributes)
- "The modification time in ATTRIBUTES returned by `file-attributes'.
-This is the time of the last change to the file's contents, and
-is a Lisp timestamp in the style of `current-time'."
- (nth 5 attributes))))
-
-(defalias 'tramp-compat-file-attribute-status-change-time
- (if (fboundp 'file-attribute-status-change-time)
- #'file-attribute-status-change-time
- (lambda (attributes)
- "The status modification time in ATTRIBUTES returned by `file-attributes'.
-This is the time of last change to the file's attributes: owner
-and group, access mode bits, etc., and is a Lisp timestamp in the
-style of `current-time'."
- (nth 6 attributes))))
-
-(defalias 'tramp-compat-file-attribute-size
- (if (fboundp 'file-attribute-size)
- #'file-attribute-size
- (lambda (attributes)
- "The size (in bytes) in ATTRIBUTES returned by `file-attributes'.
-If the size is too large for a fixnum, this is a bignum in Emacs 27
-and later, and is a float in Emacs 26 and earlier."
- (nth 7 attributes))))
-
-(defalias 'tramp-compat-file-attribute-modes
- (if (fboundp 'file-attribute-modes)
- #'file-attribute-modes
- (lambda (attributes)
- "The file modes in ATTRIBUTES returned by `file-attributes'.
-This is a string of ten letters or dashes as in ls -l."
- (nth 8 attributes))))
-
-;; `file-missing' is introduced in Emacs 26.1.
-(defconst tramp-file-missing
- (if (get 'file-missing 'error-conditions) 'file-missing 'file-error)
- "The error symbol for the `file-missing' error.")
-
-(defsubst tramp-compat-file-missing (vec file)
- "Emit the `file-missing' error."
- (if (get 'file-missing 'error-conditions)
- (tramp-error vec tramp-file-missing file)
- (tramp-error vec tramp-file-missing "No such file or directory: %s" file)))
-
-;; `file-local-name', `file-name-quoted-p', `file-name-quote' and
-;; `file-name-unquote' are introduced in Emacs 26.1.
-(defalias 'tramp-compat-file-local-name
- (if (fboundp 'file-local-name)
- #'file-local-name
- (lambda (name)
- "Return the local name component of NAME.
-It returns a file name which can be used directly as argument of
-`process-file', `start-file-process', or `shell-command'."
- (or (file-remote-p name 'localname) name))))
-
;; `file-name-quoted-p', `file-name-quote' and `file-name-unquote' got
;; a second argument in Emacs 27.1.
(defalias 'tramp-compat-file-name-quoted-p
- (if (and
- (fboundp 'file-name-quoted-p)
- (equal (tramp-compat-funcall 'func-arity #'file-name-quoted-p) '(1 . 2)))
+ (if (equal (func-arity #'file-name-quoted-p) '(1 . 2))
#'file-name-quoted-p
(lambda (name &optional top)
"Whether NAME is quoted with prefix \"/:\".
If NAME is a remote file name and TOP is nil, check the local part of NAME."
(let ((file-name-handler-alist (unless top file-name-handler-alist)))
- (string-prefix-p "/:" (tramp-compat-file-local-name name))))))
+ (string-prefix-p "/:" (file-local-name name))))))
(defalias 'tramp-compat-file-name-quote
- (if (and
- (fboundp 'file-name-quote)
- (equal (tramp-compat-funcall 'func-arity #'file-name-quote) '(1 . 2)))
+ (if (equal (func-arity #'file-name-quote) '(1 . 2))
#'file-name-quote
(lambda (name &optional top)
"Add the quotation prefix \"/:\" to file NAME.
@@ -218,20 +96,17 @@ If NAME is a remote file name and TOP is nil, the local part of NAME is quoted."
(let ((file-name-handler-alist (unless top file-name-handler-alist)))
(if (tramp-compat-file-name-quoted-p name top)
name
- (concat
- (file-remote-p name) "/:" (tramp-compat-file-local-name name)))))))
+ (concat (file-remote-p name) "/:" (file-local-name name)))))))
(defalias 'tramp-compat-file-name-unquote
- (if (and
- (fboundp 'file-name-unquote)
- (equal (tramp-compat-funcall 'func-arity #'file-name-unquote) '(1 . 2)))
+ (if (equal (func-arity #'file-name-unquote) '(1 . 2))
#'file-name-unquote
(lambda (name &optional top)
"Remove quotation prefix \"/:\" from file NAME.
If NAME is a remote file name and TOP is nil, the local part of
NAME is unquoted."
(let* ((file-name-handler-alist (unless top file-name-handler-alist))
- (localname (tramp-compat-file-local-name name)))
+ (localname (file-local-name name)))
(when (tramp-compat-file-name-quoted-p localname top)
(setq
localname (if (= (length localname) 2) "/" (substring localname 2))))
@@ -289,28 +164,36 @@ A nil value for either argument stands for the current time."
;; `progress-reporter-update' got argument SUFFIX in Emacs 27.1.
(defalias 'tramp-compat-progress-reporter-update
- (if (equal (tramp-compat-funcall 'func-arity #'progress-reporter-update)
- '(1 . 3))
+ (if (equal (func-arity #'progress-reporter-update) '(1 . 3))
#'progress-reporter-update
(lambda (reporter &optional value _suffix)
(progress-reporter-update reporter value))))
+;; `ignore-error' is new in Emacs Emacs 27.1.
+(defmacro tramp-compat-ignore-error (condition &rest body)
+ "Execute BODY; if the error CONDITION occurs, return nil.
+Otherwise, return result of last form in BODY.
+
+CONDITION can also be a list of error conditions."
+ (declare (debug t) (indent 1))
+ `(condition-case nil (progn ,@body) (,condition nil)))
+
;; `file-modes', `set-file-modes' and `set-file-times' got argument
;; FLAG in Emacs 28.1.
(defalias 'tramp-compat-file-modes
- (if (equal (tramp-compat-funcall 'func-arity #'file-modes) '(1 . 2))
+ (if (equal (func-arity #'file-modes) '(1 . 2))
#'file-modes
(lambda (filename &optional _flag)
(file-modes filename))))
(defalias 'tramp-compat-set-file-modes
- (if (equal (tramp-compat-funcall 'func-arity #'set-file-modes) '(2 . 3))
+ (if (equal (func-arity #'set-file-modes) '(2 . 3))
#'set-file-modes
(lambda (filename mode &optional _flag)
(set-file-modes filename mode))))
(defalias 'tramp-compat-set-file-times
- (if (equal (tramp-compat-funcall 'func-arity #'set-file-times) '(1 . 3))
+ (if (equal (func-arity #'set-file-times) '(1 . 3))
#'set-file-times
(lambda (filename &optional timestamp _flag)
(set-file-times filename timestamp))))
@@ -318,14 +201,13 @@ A nil value for either argument stands for the current time."
;; `directory-files' and `directory-files-and-attributes' got argument
;; COUNT in Emacs 28.1.
(defalias 'tramp-compat-directory-files
- (if (equal (tramp-compat-funcall 'func-arity #'directory-files) '(1 . 5))
+ (if (equal (func-arity #'directory-files) '(1 . 5))
#'directory-files
(lambda (directory &optional full match nosort _count)
(directory-files directory full match nosort))))
(defalias 'tramp-compat-directory-files-and-attributes
- (if (equal (tramp-compat-funcall 'func-arity #'directory-files-and-attributes)
- '(1 . 6))
+ (if (equal (func-arity #'directory-files-and-attributes) '(1 . 6))
#'directory-files-and-attributes
(lambda (directory &optional full match nosort id-format _count)
(directory-files-and-attributes directory full match nosort id-format))))
@@ -350,10 +232,10 @@ A nil value for either argument stands for the current time."
(defalias 'tramp-compat-string-replace
(if (fboundp 'string-replace)
#'string-replace
- (lambda (fromstring tostring instring)
+ (lambda (from-string to-string in-string)
(let ((case-fold-search nil))
(replace-regexp-in-string
- (regexp-quote fromstring) tostring instring t t)))))
+ (regexp-quote from-string) to-string in-string t t)))))
;; Function `string-search' is new in Emacs 28.1.
(defalias 'tramp-compat-string-search
@@ -378,14 +260,17 @@ A nil value for either argument stands for the current time."
(if (fboundp 'file-name-concat)
#'file-name-concat
(lambda (directory &rest components)
- (unless (null directory)
- (let ((components (delq nil components))
- file-name-handler-alist)
- (if (null components)
- directory
- (tramp-compat-file-name-concat
- (concat (file-name-as-directory directory) (car components))
- (cdr components))))))))
+ (let ((components (cl-remove-if (lambda (el)
+ (or (null el) (equal "" el)))
+ components))
+ file-name-handler-alist)
+ (if (null components)
+ directory
+ (apply #'tramp-compat-file-name-concat
+ (concat (unless (or (equal "" directory) (null directory))
+ (file-name-as-directory directory))
+ (car components))
+ (cdr components)))))))
(dolist (elt (all-completions "tramp-compat-" obarray 'functionp))
(put (intern elt) 'tramp-suppress-trace t))
@@ -399,8 +284,6 @@ A nil value for either argument stands for the current time."
;;; TODO:
;;
-;; * `func-arity' exists since Emacs 26.1.
-;;
;; * Starting with Emacs 27.1, there's no need to escape open
;; parentheses with a backslash in docstrings anymore.
;;
diff --git a/lisp/net/tramp-crypt.el b/lisp/net/tramp-crypt.el
index fdb2907ec32..4ff8e6bbf12 100644
--- a/lisp/net/tramp-crypt.el
+++ b/lisp/net/tramp-crypt.el
@@ -157,7 +157,8 @@ If NAME doesn't belong to a crypted remote directory, retun nil."
;; New handlers should be added here.
;;;###tramp-autoload
(defconst tramp-crypt-file-name-handler-alist
- '((access-file . tramp-crypt-handle-access-file)
+ '(;; `abbreviate-file-name' performed by default handler.
+ (access-file . tramp-crypt-handle-access-file)
(add-name-to-file . tramp-handle-add-name-to-file)
;; `byte-compiler-base-file-name' performed by default handler.
(copy-directory . tramp-handle-copy-directory)
@@ -247,7 +248,7 @@ Operations not mentioned here will be handled by the default Emacs primitives.")
(unless (tramp-crypt-file-name-p tfnfo)
(setq tfnfo (apply
#'tramp-file-name-for-operation operation
- (cons (tramp-compat-temporary-file-directory) (cdr args)))))
+ (cons tramp-compat-temporary-file-directory (cdr args)))))
tfnfo))
(defun tramp-crypt-run-real-handler (operation args)
@@ -294,8 +295,8 @@ arguments to pass to the OPERATION."
(defun tramp-crypt-config-file-name (vec)
"Return the encfs config file name for VEC."
(expand-file-name
- (concat "tramp-" (tramp-file-name-host vec) tramp-crypt-encfs-config)
- user-emacs-directory))
+ (locate-user-emacs-file
+ (concat "tramp-" (tramp-file-name-host vec) tramp-crypt-encfs-config))))
(defun tramp-crypt-maybe-open-connection (vec)
"Maybe open a connection VEC.
@@ -329,7 +330,7 @@ connection if a previous connection has died for some reason."
(copy-file remote-config local-config 'ok 'keep)
;; Create local encfs6 config file otherwise.
- (let* ((default-directory (tramp-compat-temporary-file-directory))
+ (let* ((default-directory tramp-compat-temporary-file-directory)
(tmpdir1 (file-name-as-directory
(tramp-compat-make-temp-file " .crypt" 'dir-flag)))
(tmpdir2 (file-name-as-directory
@@ -383,7 +384,7 @@ ARGS are the arguments. It returns t if ran successful, and nil otherwise."
(with-temp-buffer
(let* (;; Don't check for a proper method.
(non-essential t)
- (default-directory (tramp-compat-temporary-file-directory))
+ (default-directory tramp-compat-temporary-file-directory)
;; We cannot add it to `process-environment', because
;; `tramp-call-process-region' doesn't use it.
(encfs-config
@@ -427,7 +428,7 @@ Otherwise, return NAME."
crypt-vec localname (concat (symbol-name op) "-file-name")
(unless (tramp-crypt-send-command
crypt-vec (if (eq op 'encrypt) "encode" "decode")
- (tramp-compat-temporary-file-directory) localname)
+ tramp-compat-temporary-file-directory localname)
(tramp-error
crypt-vec 'file-error "%s of file name %s failed."
(if (eq op 'encrypt) "Encoding" "Decoding") name))
@@ -485,6 +486,7 @@ See `tramp-crypt-do-encrypt-or-decrypt-file'."
Files in that directory and all subdirectories will be encrypted
before copying to, and decrypted after copying from that
directory. File names will be also encrypted."
+ ;; (declare (completion tramp-crypt-command-completion-p))
(interactive "DRemote directory name: ")
(unless tramp-crypt-enabled
(tramp-user-error nil "Feature is not enabled."))
@@ -517,7 +519,7 @@ kept in their encrypted form."
tramp-crypt-encfs-config
(directory-files name nil directory-files-no-dot-files-regexp))
(yes-or-no-p
- "There exist encrypted files, do you want to continue? "))
+ "There exist encrypted files, do you want to continue?"))
(setq tramp-crypt-directories (delete name tramp-crypt-directories))
(tramp-register-file-name-handlers)))
@@ -596,7 +598,7 @@ absolute file names."
(with-parsed-tramp-file-name (if t1 filename newname) nil
(unless (file-exists-p filename)
- (tramp-compat-file-missing v filename))
+ (tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@@ -698,7 +700,7 @@ absolute file names."
(directory &optional full match nosort count)
"Like `directory-files' for Tramp files."
(unless (file-exists-p directory)
- (tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
+ (tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
(when (file-directory-p directory)
(setq directory (file-name-as-directory (expand-file-name directory)))
(let* (tramp-crypt-enabled
diff --git a/lisp/net/tramp-ftp.el b/lisp/net/tramp-ftp.el
index fa2df89e495..f78c08ec415 100644
--- a/lisp/net/tramp-ftp.el
+++ b/lisp/net/tramp-ftp.el
@@ -120,15 +120,15 @@ pass to the OPERATION."
(nth 2 tramp-file-name-structure)
(nth 4 tramp-file-name-structure)))
;; ange-ftp uses `ange-ftp-ftp-name-arg' and `ange-ftp-ftp-name-res'
- ;; for optimization in `ange-ftp-ftp-name'. If Tramp wasn't active,
+ ;; for optimization in `ange-ftp-ftp-name'. If Tramp wasn't active,
;; there could be incorrect values from previous calls in case the
- ;; "ftp" method is used in the Tramp file name. So we unset
+ ;; "ftp" method is used in the Tramp file name. So we unset
;; those values.
(ange-ftp-ftp-name-arg "")
(ange-ftp-ftp-name-res nil))
(cond
;; If argument is a symlink, `file-directory-p' and
- ;; `file-exists-p' call the traversed file recursively. So we
+ ;; `file-exists-p' call the traversed file recursively. So we
;; cannot disable the file-name-handler this case. We set the
;; connection property "started" in order to put the remote
;; location into the cache, which is helpful for further
@@ -175,11 +175,10 @@ pass to the OPERATION."
;; It must be a `defsubst' in order to push the whole code into
;; tramp-loaddefs.el. Otherwise, there would be recursive autoloading.
;;;###tramp-autoload
-(defsubst tramp-ftp-file-name-p (filename)
- "Check if it's a FILENAME that should be forwarded to Ange-FTP."
- (and (tramp-tramp-file-p filename)
- (string= (tramp-file-name-method (tramp-dissect-file-name filename))
- tramp-ftp-method)))
+(defsubst tramp-ftp-file-name-p (vec-or-filename)
+ "Check if it's a VEC-OR-FILENAME that should be forwarded to Ange-FTP."
+ (when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
+ (string= (tramp-file-name-method vec) tramp-ftp-method)))
;;;###tramp-autoload
(tramp--with-startup
diff --git a/lisp/net/tramp-fuse.el b/lisp/net/tramp-fuse.el
index 93b184a36c2..cb270be68fb 100644
--- a/lisp/net/tramp-fuse.el
+++ b/lisp/net/tramp-fuse.el
@@ -48,7 +48,7 @@
(directory &optional full match nosort count)
"Like `directory-files' for Tramp files."
(unless (file-exists-p directory)
- (tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
+ (tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
(when (file-directory-p directory)
(setq directory (file-name-as-directory (expand-file-name directory)))
(with-parsed-tramp-file-name directory nil
@@ -107,12 +107,6 @@
(unless (string-match-p elt item) (throw 'match nil)))
(setq result (cons (concat item "/") result))))))))))
-(defun tramp-fuse-handle-file-readable-p (filename)
- "Like `file-readable-p' for Tramp files."
- (with-parsed-tramp-file-name (expand-file-name filename) nil
- (with-tramp-file-property v localname "file-readable-p"
- (file-readable-p (tramp-fuse-local-file-name filename)))))
-
;; This function isn't used.
(defun tramp-fuse-handle-insert-directory
(filename switches &optional wildcard full-directory-p)
@@ -154,36 +148,58 @@
(when (tramp-file-name-user vec)
(concat (tramp-file-name-user-domain vec) "@"))
(tramp-file-name-host-port vec))
- (tramp-compat-temporary-file-directory))))
+ tramp-compat-temporary-file-directory)))
+
+(defconst tramp-fuse-mount-timeout
+ (eval (car (get 'remote-file-name-inhibit-cache 'standard-value)) t)
+ "Time period to check whether the mount point still exists.
+It has the same meaning as `remote-file-name-inhibit-cache'.")
(defun tramp-fuse-mounted-p (vec)
"Check, whether fuse volume determined by VEC is mounted."
- (when (tramp-get-connection-process vec)
- ;; We cannot use `with-connection-property', because we don't want
- ;; to cache a nil result.
- (or (tramp-get-connection-property
- (tramp-get-connection-process vec) "mounted" nil)
- (let* ((default-directory (tramp-compat-temporary-file-directory))
+ ;; Remember the mount status by using a file property on "/",
+ ;; instead of using a connection property, because a file property
+ ;; has a timeout. Having a timeout lets us regularly recheck the
+ ;; mount status, as requested by `tramp-fuse-mount-timeout'. We
+ ;; cannot use `with-tramp-file-property', because we don't want to
+ ;; cache a nil result.
+ (let ((remote-file-name-inhibit-cache tramp-fuse-mount-timeout))
+ (or (tramp-get-file-property vec "/" "mounted" nil)
+ (let* ((default-directory tramp-compat-temporary-file-directory)
(command (format "mount -t fuse.%s" (tramp-file-name-method vec)))
(mount (shell-command-to-string command)))
(tramp-message vec 6 "%s\n%s" command mount)
- (tramp-set-connection-property
- (tramp-get-connection-process vec) "mounted"
+ (tramp-set-file-property
+ vec "/" "mounted"
(when (string-match
(format
"^\\(%s\\)\\s-" (regexp-quote (tramp-fuse-mount-spec vec)))
mount)
(match-string 1 mount)))))))
+(defun tramp-fuse-get-fusermount ()
+ "Determine the local `fusermount' command."
+ ;; We use key nil for local connection properties.
+ (with-tramp-connection-property nil "fusermount"
+ (or (executable-find "fusermount3")
+ (executable-find "fusermount"))))
+
+(defvar tramp-fuse-mount-points nil
+ "List of fuse volume determined by a VEC.")
+
(defun tramp-fuse-unmount (vec)
"Unmount fuse volume determined by VEC."
- (let ((default-directory (tramp-compat-temporary-file-directory))
- (command (format "fusermount3 -u %s" (tramp-fuse-mount-point vec))))
+ (let* ((default-directory tramp-compat-temporary-file-directory)
+ (mount-point (tramp-fuse-mount-point vec))
+ (command (format "%s -u %s" (tramp-fuse-get-fusermount) mount-point)))
(tramp-message vec 6 "%s\n%s" command (shell-command-to-string command))
- (tramp-flush-connection-property
- (tramp-get-connection-process vec) "mounted")
+ (tramp-flush-file-property vec "/" "mounted")
+ (setq tramp-fuse-mount-points
+ (delete (tramp-file-name-unify vec) tramp-fuse-mount-points))
;; Give the caches a chance to expire.
- (sleep-for 1)))
+ (sleep-for 1)
+ (when (tramp-compat-directory-empty-p mount-point)
+ (delete-directory mount-point))))
(defun tramp-fuse-local-file-name (filename)
"Return local mount name of FILENAME."
@@ -205,6 +221,36 @@
(substring localname 1) localname)
(tramp-fuse-mount-point v)))))))
+(defcustom tramp-fuse-unmount-on-cleanup nil
+ "Whether fuse volumes shall be unmounted on cleanup."
+ :group 'tramp
+ :version "28.1"
+ :type 'boolean)
+
+(defun tramp-fuse-cleanup (vec)
+ "Cleanup fuse volume determined by VEC."
+ (and tramp-fuse-unmount-on-cleanup
+ (member (tramp-file-name-unify vec) tramp-fuse-mount-points)
+ (tramp-fuse-unmount vec)))
+
+(defun tramp-fuse-cleanup-all ()
+ "Unmount all fuse volumes used by Tramp."
+ (and tramp-fuse-unmount-on-cleanup
+ (mapc #'tramp-fuse-unmount tramp-fuse-mount-points)))
+
+;; Add cleanup hooks.
+(add-hook 'tramp-cleanup-connection-hook #'tramp-fuse-cleanup)
+(add-hook 'tramp-cleanup-all-connections-hook #'tramp-fuse-cleanup-all)
+(add-hook 'kill-emacs-hook #'tramp-fuse-cleanup-all)
+(add-hook 'tramp-fuse-unload-hook
+ (lambda ()
+ (remove-hook 'tramp-cleanup-connection-hook
+ #'tramp-fuse-cleanup)
+ (remove-hook 'tramp-cleanup-all-connections-hook
+ #'tramp-fuse-cleanup-all)
+ (remove-hook 'kill-emacs-hook
+ #'tramp-fuse-cleanup-all)))
+
(add-hook 'tramp-unload-hook
(lambda ()
(unload-feature 'tramp-fuse 'force)))
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index e4f54cf4c46..6b0299aa097 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -122,10 +122,7 @@
(autoload 'zeroconf-init "zeroconf")
(tramp-compat-funcall 'dbus-get-unique-name :system)
(tramp-compat-funcall 'dbus-get-unique-name :session)
- (or ;; Until Emacs 25, `process-attributes' could crash Emacs
- ;; for some processes. Better we don't check.
- (<= emacs-major-version 25)
- (tramp-process-running-p "gvfs-fuse-daemon")
+ (or (tramp-process-running-p "gvfs-fuse-daemon")
(tramp-process-running-p "gvfsd-fuse"))))
"Non-nil when GVFS is available.")
@@ -471,8 +468,7 @@ It has been changed in GVFS 1.14.")
;; </method>
;; </interface>
-;; The basic structure for GNOME Online Accounts. We use a list :type,
-;; in order to be compatible with Emacs 25.
+;; The basic structure for GNOME Online Accounts.
(cl-defstruct (tramp-goa-account (:type list) :named) method user host port)
;;;###tramp-autoload
@@ -672,8 +668,7 @@ It has been changed in GVFS 1.14.")
;; STRING key (always-call-mount, is-removable, ...)
;; VARIANT value (boolean?)
-;; The basic structure for media devices. We use a list :type, in
-;; order to be compatible with Emacs 25.
+;; The basic structure for media devices.
(cl-defstruct (tramp-media-device (:type list) :named) method host port)
;; "gvfs-<command>" utilities have been deprecated in GVFS 1.31.1. We
@@ -749,7 +744,8 @@ It has been changed in GVFS 1.14.")
;; New handlers should be added here.
;;;###tramp-autoload
(defconst tramp-gvfs-file-name-handler-alist
- '((access-file . tramp-handle-access-file)
+ '((abbreviate-file-name . tramp-handle-abbreviate-file-name)
+ (access-file . tramp-handle-access-file)
(add-name-to-file . tramp-handle-add-name-to-file)
;; `byte-compiler-base-file-name' performed by default handler.
(copy-directory . tramp-handle-copy-directory)
@@ -788,7 +784,7 @@ It has been changed in GVFS 1.14.")
(file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
(file-notify-valid-p . tramp-handle-file-notify-valid-p)
(file-ownership-preserved-p . ignore)
- (file-readable-p . tramp-gvfs-handle-file-readable-p)
+ (file-readable-p . tramp-handle-file-readable-p)
(file-regular-p . tramp-handle-file-regular-p)
(file-remote-p . tramp-handle-file-remote-p)
(file-selinux-context . tramp-handle-file-selinux-context)
@@ -834,12 +830,11 @@ Operations not mentioned here will be handled by the default Emacs primitives.")
;; It must be a `defsubst' in order to push the whole code into
;; tramp-loaddefs.el. Otherwise, there would be recursive autoloading.
;;;###tramp-autoload
-(defsubst tramp-gvfs-file-name-p (filename)
- "Check if it's a FILENAME handled by the GVFS daemon."
- (and (tramp-tramp-file-p filename)
- (let ((method
- (tramp-file-name-method (tramp-dissect-file-name filename))))
- (and (stringp method) (member method tramp-gvfs-methods)))))
+(defsubst tramp-gvfs-file-name-p (vec-or-filename)
+ "Check if it's a VEC-OR-FILENAME handled by the GVFS daemon."
+ (when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
+ (let ((method (tramp-file-name-method vec)))
+ (and (stringp method) (member method tramp-gvfs-methods)))))
;;;###tramp-autoload
(defun tramp-gvfs-file-name-handler (operation &rest args)
@@ -1002,7 +997,7 @@ file names."
(with-parsed-tramp-file-name (if t1 filename newname) nil
(unless (file-exists-p filename)
- (tramp-compat-file-missing v filename))
+ (tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@@ -1102,8 +1097,7 @@ file names."
(tramp-skeleton-delete-directory directory recursive trash
(if (and recursive (not (file-symlink-p directory)))
(mapc (lambda (file)
- (if (eq t (tramp-compat-file-attribute-type
- (file-attributes file)))
+ (if (eq t (file-attribute-type (file-attributes file)))
(delete-directory file recursive)
(delete-file file)))
(directory-files
@@ -1155,15 +1149,12 @@ file names."
(make-tramp-file-name
:method method :user user :domain domain
:host host :port port :localname "/" :hop hop)))
- (setq localname
- (replace-match
- (tramp-get-connection-property v "default-location" "~")
- nil t localname 1)))
- ;; Tilde expansion is not possible.
- (when (string-match-p "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname)
- (tramp-error
- v 'file-error
- "Cannot expand tilde in file `%s'" name))
+ (unless (string-empty-p
+ (tramp-get-connection-property v "default-location" ""))
+ (setq localname
+ (replace-match
+ (tramp-get-connection-property v "default-location" "~")
+ nil t localname 1))))
(unless (tramp-run-real-handler #'file-name-absolute-p (list localname))
(setq localname (concat "/" localname)))
;; We do not pass "/..".
@@ -1178,10 +1169,12 @@ file names."
;; Do not keep "/..".
(when (string-match-p "^/\\.\\.?$" localname)
(setq localname "/"))
- ;; No tilde characters in file name, do normal
- ;; `expand-file-name' (this does "/./" and "/../").
+ ;; Do normal `expand-file-name' (this does "/./" and "/../"),
+ ;; unless there are tilde characters in file name.
(tramp-make-tramp-file-name
- v (tramp-run-real-handler #'expand-file-name (list localname))))))
+ v (if (string-match-p "\\`~" localname)
+ localname
+ (tramp-run-real-handler #'expand-file-name (list localname)))))))
(defun tramp-gvfs-get-directory-attributes (directory)
"Return GVFS attributes association list of all files in DIRECTORY."
@@ -1396,8 +1389,7 @@ If FILE-SYSTEM is non-nil, return file system attributes."
"Like `file-executable-p' for Tramp files."
(with-parsed-tramp-file-name filename nil
(with-tramp-file-property v localname "file-executable-p"
- (and (file-exists-p filename)
- (tramp-check-cached-permissions v ?x)))))
+ (tramp-check-cached-permissions v ?x))))
(defun tramp-gvfs-handle-file-name-all-completions (filename directory)
"Like `file-name-all-completions' for Tramp files."
@@ -1464,7 +1456,7 @@ If FILE-SYSTEM is non-nil, return file system attributes."
`file-notify' events."
(let* ((events (process-get proc 'events))
(rest-string (process-get proc 'rest-string))
- (dd (with-current-buffer (process-buffer proc) default-directory))
+ (dd (tramp-get-default-directory (process-buffer proc)))
(ddu (regexp-quote (tramp-gvfs-url-file-name dd))))
(when rest-string
(tramp-message proc 10 "Previous string:\n%s" rest-string))
@@ -1519,31 +1511,6 @@ If FILE-SYSTEM is non-nil, return file system attributes."
(when string (tramp-message proc 10 "Rest string:\n%s" string))
(process-put proc 'rest-string string)))
-(defun tramp-gvfs-handle-file-readable-p (filename)
- "Like `file-readable-p' for Tramp files."
- (with-parsed-tramp-file-name filename nil
- (with-tramp-file-property v localname "file-readable-p"
- (and (file-exists-p filename)
- (or (tramp-check-cached-permissions v ?r)
- ;; `tramp-check-cached-permissions' doesn't handle
- ;; symbolic links.
- (and (stringp (file-symlink-p filename))
- (file-readable-p
- (concat
- (file-remote-p filename) (file-symlink-p filename))))
- ;; If the user is different from what we guess to be
- ;; the user, we don't know. Let's check, whether
- ;; access is restricted explicitly.
- (and (/= (tramp-get-remote-uid v 'integer)
- (tramp-compat-file-attribute-user-id
- (file-attributes filename 'integer)))
- (not
- (string-equal
- "FALSE"
- (cdr (assoc
- "access::can-read"
- (tramp-gvfs-get-file-attributes filename)))))))))))
-
(defun tramp-gvfs-handle-file-system-info (filename)
"Like `file-system-info' for Tramp files."
(setq filename (directory-file-name (expand-file-name filename)))
@@ -1554,11 +1521,11 @@ If FILE-SYSTEM is non-nil, return file system attributes."
(size (cdr (assoc "filesystem::size" attr)))
(used (cdr (assoc "filesystem::used" attr)))
(free (cdr (assoc "filesystem::free" attr))))
- (when (or size used free)
- (list (string-to-number (or size "0"))
- (string-to-number (or free "0"))
- (- (string-to-number (or size "0"))
- (string-to-number (or used "0"))))))))
+ (when (or size free)
+ (list (and size (string-to-number size))
+ (and free (string-to-number free))
+ (and size used
+ (- (string-to-number size) (string-to-number used))))))))
(defun tramp-gvfs-handle-make-directory (dir &optional parents)
"Like `make-directory' for Tramp files."
@@ -1574,10 +1541,13 @@ If FILE-SYSTEM is non-nil, return file system attributes."
(when (and parents (not (file-directory-p ldir)))
(make-directory ldir parents))
;; Just do it.
- (unless (or (tramp-gvfs-send-command
- v "gvfs-mkdir" (tramp-gvfs-url-file-name dir))
- (and parents (file-directory-p dir)))
- (tramp-error v 'file-error "Couldn't make directory %s" dir))))))
+ (or (when-let ((mkdir-succeeded
+ (tramp-gvfs-send-command
+ v "gvfs-mkdir" (tramp-gvfs-url-file-name dir))))
+ (set-file-modes dir (default-file-modes))
+ mkdir-succeeded)
+ (and parents (file-directory-p dir))
+ (tramp-error v 'file-error "Couldn't make directory %s" dir))))))
(defun tramp-gvfs-handle-rename-file
(filename newname &optional ok-if-already-exists)
@@ -1625,7 +1595,7 @@ If FILE-SYSTEM is non-nil, return file system attributes."
"%s" (if (or (null time)
(tramp-compat-time-equal-p time tramp-time-doesnt-exist)
(tramp-compat-time-equal-p time tramp-time-dont-know))
- (current-time)
+ nil
time)))))
(defun tramp-gvfs-handle-get-remote-uid (vec id-format)
@@ -1637,9 +1607,8 @@ ID-FORMAT valid values are `string' and `integer'."
(tramp-get-connection-property
(tramp-get-process vec) "share"
(tramp-get-connection-property vec "default-location" nil))))
- (tramp-compat-file-attribute-user-id
- (file-attributes
- (tramp-make-tramp-file-name vec localname) id-format)))))
+ (file-attribute-user-id
+ (file-attributes (tramp-make-tramp-file-name vec localname) id-format)))))
(defun tramp-gvfs-handle-get-remote-gid (vec id-format)
"The gid of the remote connection VEC, in ID-FORMAT.
@@ -1648,9 +1617,8 @@ ID-FORMAT valid values are `string' and `integer'."
(tramp-get-connection-property
(tramp-get-process vec) "share"
(tramp-get-connection-property vec "default-location" nil))))
- (tramp-compat-file-attribute-group-id
- (file-attributes
- (tramp-make-tramp-file-name vec localname) id-format))))
+ (file-attribute-group-id
+ (file-attributes (tramp-make-tramp-file-name vec localname) id-format))))
(defun tramp-gvfs-handle-set-file-uid-gid (filename &optional uid gid)
"Like `tramp-set-file-uid-gid' for Tramp files."
@@ -1812,10 +1780,8 @@ a downcased host name only."
(message "%s" message)
(pop-to-buffer (current-buffer)))
(if (yes-or-no-p
- (concat
- (buffer-substring
- (line-beginning-position) (point))
- " "))
+ (buffer-substring
+ (line-beginning-position) (point)))
0 1)))))
;; When QUIT is raised, we shall return this
@@ -1832,12 +1798,13 @@ a downcased host name only."
result))))
(defun tramp-gvfs-handler-mounted-unmounted (mount-info)
- "Signal handler for the \"org.gtk.vfs.MountTracker.mounted\" and \
-\"org.gtk.vfs.MountTracker.unmounted\" signals."
+ "Signal handler for the gvfs \"mounted\" and \"unmounted\" signals.
+Their full names are \"org.gtk.vfs.MountTracker.mounted\" and
+\"org.gtk.vfs.MountTracker.unmounted\"."
(ignore-errors
(let ((signal-name (dbus-event-member-name last-input-event))
(elt mount-info))
- ;; Jump over the first elements of the mount info. Since there
+ ;; Jump over the first elements of the mount info. Since there
;; were changes in the entries, we cannot access dedicated
;; elements.
(while (stringp (car elt)) (setq elt (cdr elt)))
@@ -1889,8 +1856,9 @@ a downcased host name only."
host (tramp-file-name-host v)
port (tramp-file-name-port v)))))
(when (member method tramp-gvfs-methods)
- (with-parsed-tramp-file-name
- (tramp-make-tramp-file-name method user domain host port "") nil
+ (let ((v (make-tramp-file-name
+ :method method :user user :domain domain
+ :host host :port port)))
(tramp-message
v 6 "%s %s"
signal-name (tramp-gvfs-stringify-dbus-message mount-info))
@@ -1933,7 +1901,7 @@ a downcased host name only."
:session tramp-gvfs-service-daemon tramp-gvfs-path-mounttracker
tramp-gvfs-interface-mounttracker tramp-gvfs-listmounts))
nil)
- ;; Jump over the first elements of the mount info. Since there
+ ;; Jump over the first elements of the mount info. Since there
;; were changes in the entries, we cannot access dedicated
;; elements.
(while (stringp (car elt)) (setq elt (cdr elt)))
@@ -2089,8 +2057,10 @@ It was \"a(say)\", but has changed to \"a{sv})\"."
`(:struct ,(tramp-gvfs-dbus-string-to-byte-array mount-pref) ,mount-spec)))
(defun tramp-gvfs-handler-volumeadded-volumeremoved (_dbus-name _id volume)
- "Signal handler for the \"org.gtk.Private.RemoteVolumeMonitor.VolumeAdded\" \
-and \"org.gtk.Private.RemoteVolumeMonitor.VolumeRemoved\" signals."
+ "Signal handler for the gvfs \"VolumeAdded\" and \"VolumeRemoved\" signals.
+Their full names are
+\"org.gtk.Private.RemoteVolumeMonitor.VolumeAdded\" and
+\"org.gtk.Private.RemoteVolumeMonitor.VolumeRemoved\"."
(ignore-errors
(let* ((signal-name (dbus-event-member-name last-input-event))
(uri (url-generic-parse-url (nth 5 volume)))
@@ -2155,9 +2125,6 @@ connection if a previous connection has died for some reason."
(process-put p 'vector vec)
(set-process-query-on-exit-flag p nil)
- ;; Mark process for filelock.
- (tramp-set-connection-property p "lock-pid" (truncate (time-to-seconds)))
-
;; Set connection-local variables.
(tramp-set-connection-local-variables vec)))
diff --git a/lisp/net/tramp-integration.el b/lisp/net/tramp-integration.el
index 17264193fd6..238abd34230 100644
--- a/lisp/net/tramp-integration.el
+++ b/lisp/net/tramp-integration.el
@@ -85,13 +85,6 @@ special handling of `substitute-in-file-name'."
"An overlay covering the shadowed part of the filename."
(format "[^%s/~]*\\(/\\|~\\)" tramp-postfix-host-format))
-;; Package rfn-eshadow is preloaded in Emacs, but for some reason,
-;; it only did (defvar rfn-eshadow-overlay) without giving it a global
-;; value, so it was only declared as dynamically-scoped within the
-;; rfn-eshadow.el file. This is now fixed in Emacs>26.1 but we still need
-;; this defvar here for older releases.
-(defvar rfn-eshadow-overlay)
-
(defun tramp-rfn-eshadow-update-overlay ()
"Update `rfn-eshadow-overlay' to cover shadowed part of minibuffer input.
This is intended to be used as a minibuffer `post-command-hook' for
@@ -281,22 +274,18 @@ NAME must be equal to `tramp-current-connection'."
(remove-hook 'compilation-start-hook
#'tramp-compile-disable-ssh-controlmaster-options))))
-;;; Default connection-local variables for Tramp:
-;; `connection-local-set-profile-variables' and
-;; `connection-local-set-profiles' exists since Emacs 26.1.
+;;; Default connection-local variables for Tramp.
(defconst tramp-connection-local-default-system-variables
'((path-separator . ":")
(null-device . "/dev/null"))
"Default connection-local system variables for remote connections.")
-(tramp-compat-funcall
- 'connection-local-set-profile-variables
+(connection-local-set-profile-variables
'tramp-connection-local-default-system-profile
tramp-connection-local-default-system-variables)
-(tramp-compat-funcall
- 'connection-local-set-profiles
+(connection-local-set-profiles
'(:application tramp)
'tramp-connection-local-default-system-profile)
@@ -305,14 +294,12 @@ NAME must be equal to `tramp-current-connection'."
(shell-command-switch . "-c"))
"Default connection-local shell variables for remote connections.")
-(tramp-compat-funcall
- 'connection-local-set-profile-variables
+(connection-local-set-profile-variables
'tramp-connection-local-default-shell-profile
tramp-connection-local-default-shell-variables)
(with-eval-after-load 'shell
- (tramp-compat-funcall
- 'connection-local-set-profiles
+ (connection-local-set-profiles
'(:application tramp)
'tramp-connection-local-default-shell-profile))
diff --git a/lisp/net/tramp-rclone.el b/lisp/net/tramp-rclone.el
index 49e366c01c6..71ec2607a30 100644
--- a/lisp/net/tramp-rclone.el
+++ b/lisp/net/tramp-rclone.el
@@ -71,7 +71,8 @@
;; New handlers should be added here.
;;;###tramp-autoload
(defconst tramp-rclone-file-name-handler-alist
- '((access-file . tramp-handle-access-file)
+ '(;; `abbreviate-file-name' performed by default handler.
+ (access-file . tramp-handle-access-file)
(add-name-to-file . tramp-handle-add-name-to-file)
;; `byte-compiler-base-file-name' performed by default handler.
(copy-directory . tramp-handle-copy-directory)
@@ -110,7 +111,7 @@
(file-notify-rm-watch . ignore)
(file-notify-valid-p . ignore)
(file-ownership-preserved-p . ignore)
- (file-readable-p . tramp-fuse-handle-file-readable-p)
+ (file-readable-p . tramp-rclone-handle-file-readable-p)
(file-regular-p . tramp-handle-file-regular-p)
(file-remote-p . tramp-handle-file-remote-p)
(file-selinux-context . tramp-handle-file-selinux-context)
@@ -156,11 +157,10 @@ Operations not mentioned here will be handled by the default Emacs primitives.")
;; It must be a `defsubst' in order to push the whole code into
;; tramp-loaddefs.el. Otherwise, there would be recursive autoloading.
;;;###tramp-autoload
-(defsubst tramp-rclone-file-name-p (filename)
- "Check if it's a FILENAME for rclone."
- (and (tramp-tramp-file-p filename)
- (string= (tramp-file-name-method (tramp-dissect-file-name filename))
- tramp-rclone-method)))
+(defsubst tramp-rclone-file-name-p (vec-or-filename)
+ "Check if it's a VEC-OR-FILENAME for rclone."
+ (when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
+ (string= (tramp-file-name-method vec) tramp-rclone-method)))
;;;###tramp-autoload
(defun tramp-rclone-file-name-handler (operation &rest args)
@@ -223,7 +223,7 @@ file names."
(with-parsed-tramp-file-name (if t1 filename newname) nil
(unless (file-exists-p filename)
- (tramp-compat-file-missing v filename))
+ (tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@@ -280,6 +280,12 @@ file names."
(list filename newname ok-if-already-exists keep-date
preserve-uid-gid preserve-extended-attributes))))
+(defun tramp-rclone-handle-file-readable-p (filename)
+ "Like `file-readable-p' for Tramp files."
+ (with-parsed-tramp-file-name (expand-file-name filename) nil
+ (with-tramp-file-property v localname "file-readable-p"
+ (file-readable-p (tramp-fuse-local-file-name filename)))))
+
(defun tramp-rclone-handle-file-system-info (filename)
"Like `file-system-info' for Tramp files."
(ignore-errors
@@ -362,10 +368,6 @@ connection if a previous connection has died for some reason."
(process-put p 'vector vec)
(set-process-query-on-exit-flag p nil)
- ;; Mark process for filelock.
- (tramp-set-connection-property
- p "lock-pid" (truncate (time-to-seconds)))
-
;; Set connection-local variables.
(tramp-set-connection-local-variables vec)))
@@ -386,6 +388,7 @@ connection if a previous connection has died for some reason."
(tramp-cleanup-connection vec 'keep-debug 'keep-password))
;; Mark it as connected.
+ (add-to-list 'tramp-fuse-mount-points (tramp-file-name-unify vec))
(tramp-set-connection-property
(tramp-get-connection-process vec) "connected" t))))
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index f00434c1468..72eb63d3929 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -34,6 +34,8 @@
(eval-when-compile (require 'cl-lib))
(require 'tramp)
+;; `dired-*' declarations can be removed, starting with Emacs 29.1.
+(declare-function dired-compress-file "dired-aux")
(declare-function dired-remove-file "dired-aux")
(defvar dired-compress-file-suffixes)
(defvar process-file-return-signal-string)
@@ -202,7 +204,7 @@ The string is used in `tramp-methods'.")
(tramp-copy-program "rsync")
(tramp-copy-args (("-t" "%k") ("-p") ("-r") ("-s")
("-c")))
- (tramp-copy-env (("RSYNC_RSH") ("ssh" "%c")))
+ (tramp-copy-env (("RSYNC_RSH") ("ssh") ("%c")))
(tramp-copy-keep-date t)
(tramp-copy-keep-tmpfile t)
(tramp-copy-recursive t)))
@@ -280,13 +282,14 @@ The string is used in `tramp-methods'.")
(tramp-connection-timeout 10)))
(add-to-list 'tramp-methods
`("sudo"
- (tramp-login-program "sudo")
+ (tramp-login-program "env")
;; The password template must be masked. Otherwise,
;; it could be interpreted as password prompt if the
;; remote host echoes the command.
- (tramp-login-args (("-u" "%u") ("-s") ("-H")
- ("-p" "P\"\"a\"\"s\"\"s\"\"w\"\"o\"\"r\"\"d\"\":")
- ("%l")))
+ ;; The "-p" argument doesn't work reliably, see Bug#50594.
+ (tramp-login-args (("SUDO_PROMPT=P\"\"a\"\"s\"\"s\"\"w\"\"o\"\"r\"\"d\"\":")
+ ("sudo") ("-u" "%u") ("-s") ("-H")
+ ("%l")))
(tramp-remote-shell ,tramp-default-remote-shell)
(tramp-remote-shell-login ("-l"))
(tramp-remote-shell-args ("-c"))
@@ -939,7 +942,8 @@ Format specifiers \"%s\" are replaced before the script is used.")
;; New handlers should be added here.
;;;###tramp-autoload
(defconst tramp-sh-file-name-handler-alist
- '((access-file . tramp-handle-access-file)
+ '((abbreviate-file-name . tramp-handle-abbreviate-file-name)
+ (access-file . tramp-handle-access-file)
(add-name-to-file . tramp-sh-handle-add-name-to-file)
;; `byte-compiler-base-file-name' performed by default handler.
(copy-directory . tramp-sh-handle-copy-directory)
@@ -951,6 +955,8 @@ Format specifiers \"%s\" are replaced before the script is used.")
(directory-files . tramp-handle-directory-files)
(directory-files-and-attributes
. tramp-sh-handle-directory-files-and-attributes)
+ ;; Starting with Emacs 29.1, `dired-compress-file' performed by
+ ;; default handler.
(dired-compress-file . tramp-sh-handle-dired-compress-file)
(dired-uncache . tramp-handle-dired-uncache)
(exec-path . tramp-sh-handle-exec-path)
@@ -1063,7 +1069,7 @@ component is used as the target of the symlink."
(not
(yes-or-no-p
(format
- "File %s already exists; make it a link anyway? "
+ "File %s already exists; make it a link anyway?"
localname)))))
(tramp-error v 'file-already-exists localname)
(delete-file linkname)))
@@ -1072,7 +1078,7 @@ component is used as the target of the symlink."
;; Right, they are on the same host, regardless of user,
;; method, etc. We now make the link on the remote
- ;; machine. This will occur as the user that TARGET belongs to.
+ ;; machine. This will occur as the user that TARGET belongs to.
(and (tramp-send-command-and-check
v (format "cd %s" (tramp-shell-quote-argument cwd)))
(tramp-send-command-and-check
@@ -1333,7 +1339,7 @@ component is used as the target of the symlink."
(with-parsed-tramp-file-name f nil
(let* ((remote-file-name-inhibit-cache t)
(attr (file-attributes f))
- (modtime (or (tramp-compat-file-attribute-modification-time attr)
+ (modtime (or (file-attribute-modification-time attr)
tramp-time-doesnt-exist)))
(setq coding-system-used last-coding-system-used)
(if (not (tramp-compat-time-equal-p modtime tramp-time-dont-know))
@@ -1371,7 +1377,7 @@ of."
(with-parsed-tramp-file-name f nil
(let* ((remote-file-name-inhibit-cache t)
(attr (file-attributes f))
- (modtime (tramp-compat-file-attribute-modification-time attr))
+ (modtime (file-attribute-modification-time attr))
(mt (visited-file-modtime)))
(cond
@@ -1423,7 +1429,7 @@ of."
(if (or (null time)
(tramp-compat-time-equal-p time tramp-time-doesnt-exist)
(tramp-compat-time-equal-p time tramp-time-dont-know))
- (current-time)
+ nil
time)))
(tramp-send-command-and-check
v (format
@@ -1579,9 +1585,7 @@ ID-FORMAT valid values are `string' and `integer'."
"Like `file-readable-p' for Tramp files."
(with-parsed-tramp-file-name filename nil
(with-tramp-file-property v localname "file-readable-p"
- ;; Examine `file-attributes' cache to see if request can be
- ;; satisfied without remote operation.
- (or (tramp-check-cached-permissions v ?r)
+ (or (tramp-handle-file-readable-p filename)
(tramp-run-test "-r" filename)))))
;; Functions implemented using the basic functions above.
@@ -1621,16 +1625,14 @@ ID-FORMAT valid values are `string' and `integer'."
;; information would be lost by an (attempted) delete and create.
(or (null attributes)
(and
- (= (tramp-compat-file-attribute-user-id attributes)
+ (= (file-attribute-user-id attributes)
(tramp-get-remote-uid v 'integer))
(or (not group)
;; On BSD-derived systems files always inherit the
;; parent directory's group, so skip the group-gid
;; test.
- (string-match-p
- "BSD\\|DragonFly\\|Darwin"
- (tramp-get-connection-property v "uname" ""))
- (= (tramp-compat-file-attribute-group-id attributes)
+ (tramp-check-remote-uname v "BSD\\|DragonFly\\|Darwin")
+ (= (file-attribute-group-id attributes)
(tramp-get-remote-gid v 'integer)))))))))
;; Directory listings.
@@ -1640,8 +1642,7 @@ ID-FORMAT valid values are `string' and `integer'."
"Like `directory-files-and-attributes' for Tramp files."
(unless id-format (setq id-format 'integer))
(unless (file-exists-p directory)
- (tramp-compat-file-missing
- (tramp-dissect-file-name directory) directory))
+ (tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
(when (file-directory-p directory)
(setq directory (expand-file-name directory))
(let* ((temp
@@ -1700,7 +1701,7 @@ ID-FORMAT valid values are `string' and `integer'."
;; FIXME: Fix function to work with count parameter.
(defun tramp-do-directory-files-and-attributes-with-stat
(vec localname &optional id-format)
- "Implement `directory-files-and-attributes' for Tramp files using stat(1) command."
+ "Implement `directory-files-and-attributes' for Tramp files with stat(1) command."
(tramp-message vec 5 "directory-files-and-attributes with stat: %s" localname)
(tramp-send-command-and-read
vec
@@ -1824,7 +1825,7 @@ ID-FORMAT valid values are `string' and `integer'."
(and (numberp ok-if-already-exists)
(not (yes-or-no-p
(format
- "File %s already exists; make it a link anyway? "
+ "File %s already exists; make it a link anyway?"
v2-localname)))))
(tramp-error v2 'file-already-exists newname)
(delete-file newname)))
@@ -1857,41 +1858,53 @@ ID-FORMAT valid values are `string' and `integer'."
(dirname newname &optional keep-date parents copy-contents)
"Like `copy-directory' for Tramp files."
(let ((t1 (tramp-tramp-file-p dirname))
- (t2 (tramp-tramp-file-p newname)))
+ (t2 (tramp-tramp-file-p newname))
+ target)
(with-parsed-tramp-file-name (if t1 dirname newname) nil
(unless (file-exists-p dirname)
- (tramp-compat-file-missing v dirname))
- (if (and (not copy-contents)
- (tramp-get-method-parameter v 'tramp-copy-recursive)
- ;; When DIRNAME and NEWNAME are remote, they must have
- ;; the same method.
- (or (null t1) (null t2)
- (string-equal
- (tramp-file-name-method (tramp-dissect-file-name dirname))
- (tramp-file-name-method
- (tramp-dissect-file-name newname)))))
- ;; scp or rsync DTRT.
- (progn
- (when (and (file-directory-p newname)
- (not (directory-name-p newname)))
- (tramp-error v 'file-already-exists newname))
- (setq dirname (directory-file-name (expand-file-name dirname))
- newname (directory-file-name (expand-file-name newname)))
- (when (and (file-directory-p newname)
- (not (string-equal (file-name-nondirectory dirname)
- (file-name-nondirectory newname))))
- (setq newname
- (expand-file-name
- (file-name-nondirectory dirname) newname)))
- (unless (file-directory-p (file-name-directory newname))
+ (tramp-error v 'file-missing dirname))
+
+ ;; `copy-directory-create-symlink' exists since Emacs 28.1.
+ (if (and (bound-and-true-p copy-directory-create-symlink)
+ (setq target (file-symlink-p dirname))
+ (tramp-equal-remote dirname newname))
+ (make-symbolic-link
+ target
+ (if (directory-name-p newname)
+ (concat newname (file-name-nondirectory dirname)) newname)
+ t)
+
+ (if (and (not copy-contents)
+ (tramp-get-method-parameter v 'tramp-copy-recursive)
+ ;; When DIRNAME and NEWNAME are remote, they must
+ ;; have the same method.
+ (or (null t1) (null t2)
+ (string-equal
+ (tramp-file-name-method (tramp-dissect-file-name dirname))
+ (tramp-file-name-method
+ (tramp-dissect-file-name newname)))))
+ ;; scp or rsync DTRT.
+ (progn
+ (when (and (file-directory-p newname)
+ (not (directory-name-p newname)))
+ (tramp-error v 'file-already-exists newname))
+ (setq dirname (directory-file-name (expand-file-name dirname))
+ newname (directory-file-name (expand-file-name newname)))
+ (when (and (file-directory-p newname)
+ (not (string-equal (file-name-nondirectory dirname)
+ (file-name-nondirectory newname))))
+ (setq newname
+ (expand-file-name
+ (file-name-nondirectory dirname) newname)))
+ (unless (file-directory-p (file-name-directory newname))
(make-directory (file-name-directory newname) parents))
- (tramp-do-copy-or-rename-file-out-of-band
- 'copy dirname newname 'ok-if-already-exists keep-date))
+ (tramp-do-copy-or-rename-file-out-of-band
+ 'copy dirname newname 'ok-if-already-exists keep-date))
- ;; We must do it file-wise.
- (tramp-run-real-handler
- #'copy-directory
- (list dirname newname keep-date parents copy-contents)))
+ ;; We must do it file-wise.
+ (tramp-run-real-handler
+ #'copy-directory
+ (list dirname newname keep-date parents copy-contents))))
;; When newname did exist, we have wrong cached values.
(when t2
@@ -1943,7 +1956,7 @@ file names."
(let ((t1 (tramp-tramp-file-p filename))
(t2 (tramp-tramp-file-p newname))
- (length (tramp-compat-file-attribute-size
+ (length (file-attribute-size
(file-attributes (file-truename filename))))
(attributes (and preserve-extended-attributes
(file-extended-attributes filename)))
@@ -1951,7 +1964,7 @@ file names."
(with-parsed-tramp-file-name (if t1 filename newname) nil
(unless (file-exists-p filename)
- (tramp-compat-file-missing v filename))
+ (tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@@ -2043,7 +2056,7 @@ KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME."
;; Check, whether file is too large. Emacs checks in `insert-file-1'
;; and `find-file-noselect', but that's not called here.
(abort-if-file-too-large
- (tramp-compat-file-attribute-size (file-attributes (file-truename filename)))
+ (file-attribute-size (file-attributes (file-truename filename)))
(symbol-name op) filename)
;; We must disable multibyte, because binary data shall not be
;; converted. We don't want the target file to be compressed, so we
@@ -2065,8 +2078,7 @@ KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME."
(when keep-date
(tramp-compat-set-file-times
newname
- (tramp-compat-file-attribute-modification-time
- (file-attributes filename))
+ (file-attribute-modification-time (file-attributes filename))
(unless ok-if-already-exists 'nofollow)))
;; Set the mode.
(set-file-modes newname (tramp-default-file-modes filename))
@@ -2085,7 +2097,7 @@ as FILENAME. PRESERVE-UID-GID, when non-nil, instructs to keep
the uid and gid from FILENAME."
(let ((t1 (tramp-tramp-file-p filename))
(t2 (tramp-tramp-file-p newname))
- (file-times (tramp-compat-file-attribute-modification-time
+ (file-times (file-attribute-modification-time
(file-attributes filename)))
(file-modes (tramp-default-file-modes filename)))
(with-parsed-tramp-file-name (if t1 filename newname) nil
@@ -2218,7 +2230,7 @@ the uid and gid from FILENAME."
;; Save exit.
(ignore-errors (delete-file tmpfile)))))))))
- ;; Set the time and mode. Mask possible errors.
+ ;; Set the time and mode. Mask possible errors.
(ignore-errors
(when keep-date
(tramp-compat-set-file-times
@@ -2378,7 +2390,7 @@ The method used must be an out-of-band method."
;; can be handled. We don't set a timeout, because
;; the copying of large files can last longer than 60
;; secs.
- p (let ((default-directory (tramp-compat-temporary-file-directory)))
+ p (let ((default-directory tramp-compat-temporary-file-directory))
(apply
#'start-process
(tramp-get-connection-name v)
@@ -2410,8 +2422,7 @@ The method used must be an out-of-band method."
(when (and keep-date (not copy-keep-date))
(tramp-compat-set-file-times
newname
- (tramp-compat-file-attribute-modification-time
- (file-attributes filename))
+ (file-attribute-modification-time (file-attributes filename))
(unless ok-if-already-exists 'nofollow)))
;; Set the mode.
@@ -2437,8 +2448,9 @@ The method used must be an out-of-band method."
(tramp-flush-directory-properties
v (if parents "/" (file-name-directory localname)))
(tramp-barf-unless-okay
- v (format "%s %s"
+ v (format "%s -m %#o %s"
(if parents "mkdir -p" "mkdir")
+ (default-file-modes)
(tramp-shell-quote-argument localname))
"Couldn't make directory %s" dir)))
@@ -2466,42 +2478,58 @@ The method used must be an out-of-band method."
(defun tramp-sh-handle-dired-compress-file (file)
"Like `dired-compress-file' for Tramp files."
- ;; Code stolen mainly from dired-aux.el.
- (with-parsed-tramp-file-name file nil
- (tramp-flush-file-properties v localname)
- (let ((suffixes dired-compress-file-suffixes)
- suffix)
- ;; See if any suffix rule matches this file name.
- (while suffixes
- (let (case-fold-search)
- (if (string-match-p (car (car suffixes)) localname)
- (setq suffix (car suffixes) suffixes nil))
- (setq suffixes (cdr suffixes))))
-
- (cond ((file-symlink-p file) nil)
- ((and suffix (nth 2 suffix))
- ;; We found an uncompression rule.
- (with-tramp-progress-reporter
- v 0 (format "Uncompressing %s" file)
- (when (tramp-send-command-and-check
- v (concat (nth 2 suffix) " "
- (tramp-shell-quote-argument localname)))
- (dired-remove-file file)
- (string-match (car suffix) file)
- (concat (substring file 0 (match-beginning 0))))))
- (t
- ;; We don't recognize the file as compressed, so compress it.
- ;; Try gzip.
- (with-tramp-progress-reporter v 0 (format "Compressing %s" file)
- (when (tramp-send-command-and-check
- v (concat "gzip -f "
- (tramp-shell-quote-argument localname)))
- (dired-remove-file file)
- (cond ((file-exists-p (concat file ".gz"))
- (concat file ".gz"))
- ((file-exists-p (concat file ".z"))
- (concat file ".z"))
- (t nil)))))))))
+ ;; Starting with Emacs 29.1, `dired-compress-file' is performed by
+ ;; default handler.
+ (if (>= emacs-major-version 29)
+ (tramp-run-real-handler #'dired-compress-file (list file))
+ ;; Code stolen mainly from dired-aux.el.
+ (with-parsed-tramp-file-name file nil
+ (tramp-flush-file-properties v localname)
+ (let ((suffixes dired-compress-file-suffixes)
+ suffix)
+ ;; See if any suffix rule matches this file name.
+ (while suffixes
+ (let (case-fold-search)
+ (if (string-match-p (car (car suffixes)) localname)
+ (setq suffix (car suffixes) suffixes nil))
+ (setq suffixes (cdr suffixes))))
+
+ (cond ((file-symlink-p file) nil)
+ ((and suffix (nth 2 suffix))
+ ;; We found an uncompression rule.
+ (with-tramp-progress-reporter
+ v 0 (format "Uncompressing %s" file)
+ (when (tramp-send-command-and-check
+ v (if (string-match-p "%[io]" (nth 2 suffix))
+ (replace-regexp-in-string
+ "%i" (tramp-shell-quote-argument localname)
+ (nth 2 suffix))
+ (concat (nth 2 suffix) " "
+ (tramp-shell-quote-argument localname))))
+ (unless (string-match-p "\\.tar\\.gz" file)
+ (dired-remove-file file))
+ (string-match (car suffix) file)
+ (concat (substring file 0 (match-beginning 0))))))
+ (t
+ ;; We don't recognize the file as compressed, so
+ ;; compress it. Try gzip.
+ (with-tramp-progress-reporter v 0 (format "Compressing %s" file)
+ (when (tramp-send-command-and-check
+ v (if (file-directory-p file)
+ (format "tar -cf - %s | gzip -c9 > %s.tar.gz"
+ (tramp-shell-quote-argument
+ (file-name-nondirectory localname))
+ (tramp-shell-quote-argument localname))
+ (concat "gzip -f "
+ (tramp-shell-quote-argument localname))))
+ (unless (file-directory-p file)
+ (dired-remove-file file))
+ (catch 'found nil
+ (dolist (target (mapcar (lambda (suffix)
+ (concat file suffix))
+ '(".tar.gz" ".gz" ".z")))
+ (when (file-exists-p target)
+ (throw 'found target))))))))))))
(defun tramp-sh-handle-insert-directory
(filename switches &optional wildcard full-directory-p)
@@ -2573,7 +2601,7 @@ The method used must be an out-of-band method."
;; We cannot use `insert-buffer-substring' because the Tramp
;; buffer changes its contents before insertion due to calling
;; `expand-file-name' and alike.
- (insert (with-current-buffer (tramp-get-buffer v) (buffer-string)))
+ (insert (tramp-get-buffer-string (tramp-get-buffer v)))
;; We must enable unibyte strings, because the "--dired"
;; output counts in bytes.
@@ -2683,11 +2711,11 @@ 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)))
- ;; If connection is not established yet, run the real handler.
- (if (not (tramp-connectable-p name))
- (tramp-run-real-handler #'expand-file-name (list name nil))
- ;; Dissect NAME.
- (with-parsed-tramp-file-name name nil
+ ;; Dissect NAME.
+ (with-parsed-tramp-file-name name nil
+ ;; If connection is not established yet, run the real handler.
+ (if (not (tramp-connectable-p v))
+ (tramp-run-real-handler #'expand-file-name (list name nil))
(unless (tramp-run-real-handler #'file-name-absolute-p (list localname))
(setq localname (concat "~/" localname)))
;; Tilde expansion if necessary. This needs a shell which
@@ -2726,7 +2754,7 @@ the result will be a local, non-Tramp, file name."
;; `expand-file-name' (this does "/./" and "/../").
;; `default-directory' is bound, because on Windows there
;; would be problems with UNC shares or Cygwin mounts.
- (let ((default-directory (tramp-compat-temporary-file-directory)))
+ (let ((default-directory tramp-compat-temporary-file-directory))
(tramp-make-tramp-file-name
v (tramp-drop-volume-letter
(tramp-run-real-handler
@@ -2734,7 +2762,7 @@ the result will be a local, non-Tramp, file name."
;;; Remote commands:
-;; We use BUFFER also as connection buffer during setup. Because of
+;; We use BUFFER also as connection buffer during setup. Because of
;; this, its original contents must be saved, and restored once
;; connection has been setup.
(defun tramp-sh-handle-make-process (&rest args)
@@ -2753,16 +2781,14 @@ implementation will be used."
(coding (plist-get args :coding))
(noquery (plist-get args :noquery))
(connection-type
- (if (plist-member args :connection-type)
- (plist-get args :connection-type)
- tramp-process-connection-type))
+ (or (plist-get args :connection-type) process-connection-type))
(filter (plist-get args :filter))
(sentinel (plist-get args :sentinel))
(stderr (plist-get args :stderr)))
(unless (stringp name)
(signal 'wrong-type-argument (list #'stringp name)))
- (unless (or (null buffer) (bufferp buffer) (stringp buffer))
- (signal 'wrong-type-argument (list #'stringp buffer)))
+ (unless (or (bufferp buffer) (string-or-null-p buffer))
+ (signal 'wrong-type-argument (list #'bufferp buffer)))
(unless (or (null command) (consp command))
(signal 'wrong-type-argument (list #'consp command)))
(unless (or (null coding)
@@ -2771,13 +2797,15 @@ implementation will be used."
(memq (car coding) coding-system-list)
(memq (cdr coding) coding-system-list)))
(signal 'wrong-type-argument (list #'symbolp coding)))
- (unless (memq connection-type '(nil pipe t pty))
+ (when (eq connection-type t)
+ (setq connection-type 'pty))
+ (unless (memq connection-type '(nil pipe pty))
(signal 'wrong-type-argument (list #'symbolp connection-type)))
- (unless (or (null filter) (functionp filter))
+ (unless (or (null filter) (eq filter t) (functionp filter))
(signal 'wrong-type-argument (list #'functionp filter)))
(unless (or (null sentinel) (functionp sentinel))
(signal 'wrong-type-argument (list #'functionp sentinel)))
- (unless (or (null stderr) (bufferp stderr) (stringp stderr))
+ (unless (or (bufferp stderr) (string-or-null-p stderr))
(signal 'wrong-type-argument (list #'bufferp stderr)))
(when (and (stringp stderr)
(not (tramp-equal-remote default-directory stderr)))
@@ -2869,10 +2897,14 @@ implementation will be used."
;; Handle error buffer.
(when (bufferp stderr)
+ (unless (tramp-get-remote-mknod-or-mkfifo v)
+ (tramp-error
+ v 'file-error "Stderr buffer `%s' not supported" stderr))
(with-current-buffer stderr
(setq buffer-read-only nil))
;; Create named pipe.
- (tramp-send-command v (format "mknod %s p" tmpstderr))
+ (tramp-send-command
+ v (format (tramp-get-remote-mknod-or-mkfifo v) tmpstderr))
;; Create stderr process.
(make-process
:name (buffer-name stderr)
@@ -2919,8 +2951,11 @@ implementation will be used."
(setq p (tramp-get-connection-process v))
(process-put p 'remote-pid pid)
(tramp-set-connection-property p "remote-pid" pid))
- ;; Disable carriage return to newline translation.
- (when (memq connection-type '(nil pipe))
+ ;; Disable carriage return to newline
+ ;; translation. This does not work on
+ ;; macOS, see Bug#50748.
+ (when (and (memq connection-type '(nil pipe))
+ (not (tramp-check-remote-uname v "Darwin")))
(tramp-send-command v "stty -icrnl"))
;; `tramp-maybe-open-connection' and
;; `tramp-send-command-and-read' could have
@@ -2949,7 +2984,7 @@ implementation will be used."
(ignore-errors
(set-process-query-on-exit-flag p (null noquery))
(set-marker (process-mark p) (point)))
- ;; Kill stderr process delete and named pipe.
+ ;; Kill stderr process and delete named pipe.
(when (bufferp stderr)
(add-function
:after (process-sentinel p)
@@ -3125,8 +3160,7 @@ implementation will be used."
(when outbuf
(with-current-buffer outbuf
(insert
- (with-current-buffer (tramp-get-connection-buffer v)
- (buffer-string))))
+ (tramp-get-buffer-string (tramp-get-connection-buffer v))))
(when (and display (get-buffer-window outbuf t)) (redisplay))))
;; When the user did interrupt, we should do it also. We use
;; return code -1 as marker.
@@ -3170,9 +3204,9 @@ implementation will be used."
"Like `file-local-copy' for Tramp files."
(with-parsed-tramp-file-name filename nil
(unless (file-exists-p (file-truename filename))
- (tramp-compat-file-missing v filename))
+ (tramp-error v 'file-missing filename))
- (let* ((size (tramp-compat-file-attribute-size
+ (let* ((size (file-attribute-size
(file-attributes (file-truename filename))))
(rem-enc (tramp-get-inline-coding v "remote-encoding" size))
(loc-dec (tramp-get-inline-coding v "local-decoding" size))
@@ -3207,7 +3241,7 @@ implementation will be used."
(let (file-name-handler-alist
(coding-system-for-write 'binary)
(default-directory
- (tramp-compat-temporary-file-directory)))
+ tramp-compat-temporary-file-directory))
(with-temp-file tmpfile
(set-buffer-multibyte nil)
(insert-buffer-substring (tramp-get-buffer v))
@@ -3255,15 +3289,13 @@ implementation will be used."
(or (eq mustbenew 'excl)
(not
(y-or-n-p
- (format "File %s exists; overwrite anyway? " filename)))))
+ (format "File %s exists; overwrite anyway?" filename)))))
(tramp-error v 'file-already-exists filename))
(let ((file-locked (eq (file-locked-p lockname) t))
- (uid (or (tramp-compat-file-attribute-user-id
- (file-attributes filename 'integer))
+ (uid (or (file-attribute-user-id (file-attributes filename 'integer))
(tramp-get-remote-uid v 'integer)))
- (gid (or (tramp-compat-file-attribute-group-id
- (file-attributes filename 'integer))
+ (gid (or (file-attribute-group-id (file-attributes filename 'integer))
(tramp-get-remote-gid v 'integer))))
;; Lock file.
@@ -3300,8 +3332,7 @@ implementation will be used."
;; we use it always because this makes the logic
;; simpler. We must also set `temporary-file-directory',
;; because it could point to a remote directory.
- (temporary-file-directory
- (tramp-compat-temporary-file-directory))
+ (temporary-file-directory tramp-compat-temporary-file-directory)
(tmpfile (or tramp-temp-buffer-file-name
(tramp-compat-make-temp-file filename))))
@@ -3343,8 +3374,7 @@ implementation will be used."
;; specified. However, if the method _also_ specifies an
;; encoding function, then that is used for encoding the
;; contents of the tmp file.
- (let* ((size (tramp-compat-file-attribute-size
- (file-attributes tmpfile)))
+ (let* ((size (file-attribute-size (file-attributes tmpfile)))
(rem-dec (tramp-get-inline-coding v "remote-decoding" size))
(loc-enc (tramp-get-inline-coding v "local-encoding" size)))
(cond
@@ -3394,7 +3424,7 @@ implementation will be used."
;; question is a tmp file anyway.
(let ((coding-system-for-read 'binary)
(default-directory
- (tramp-compat-temporary-file-directory)))
+ tramp-compat-temporary-file-directory))
(insert-file-contents-literally tmpfile)
(funcall loc-enc (point-min) (point-max)))
@@ -3444,8 +3474,7 @@ implementation will be used."
(not
(string-equal
(buffer-string)
- (with-current-buffer (tramp-get-buffer v)
- (buffer-string))))
+ (tramp-get-buffer-string (tramp-get-buffer v))))
(tramp-error
v 'file-error
(concat "Couldn't write region to `%s',"
@@ -3479,10 +3508,10 @@ implementation will be used."
;; We must pass modtime explicitly, because FILENAME can
;; be different from (buffer-file-name), f.e. if
;; `file-precious-flag' is set.
- (or (tramp-compat-file-attribute-modification-time file-attr)
+ (or (file-attribute-modification-time file-attr)
(current-time)))
- (when (and (= (tramp-compat-file-attribute-user-id file-attr) uid)
- (= (tramp-compat-file-attribute-group-id file-attr) gid))
+ (when (and (= (file-attribute-user-id file-attr) uid)
+ (= (file-attribute-group-id file-attr) gid))
(setq need-chown nil))))
;; Set the ownership.
@@ -3495,7 +3524,7 @@ implementation will be used."
(tramp-compat-funcall 'unlock-file lockname))
(when (and (null noninteractive)
- (or (eq visit t) (null visit) (stringp visit)))
+ (or (eq visit t) (string-or-null-p visit)))
(tramp-message v 0 "Wrote %s" filename))
(run-hooks 'tramp-handle-write-region-hook)))))
@@ -3739,8 +3768,7 @@ Fall back to normal file name handler if no Tramp handler exists."
"Read output from \"gio monitor\" and add corresponding `file-notify' events."
(let ((events (process-get proc 'events))
(remote-prefix
- (with-current-buffer (process-buffer proc)
- (file-remote-p default-directory)))
+ (file-remote-p (tramp-get-default-directory (process-buffer proc))))
(rest-string (process-get proc 'rest-string))
pos)
(when rest-string
@@ -3986,15 +4014,12 @@ Returns the absolute file name of PROGNAME, if found, and nil otherwise.
This function expects to be in the right *tramp* buffer."
(with-current-buffer (tramp-get-connection-buffer vec)
(let (result)
- ;; Check whether the executable is in $PATH. "which(1)" does not
+ ;; Check whether the executable is in $PATH. "which(1)" does not
;; report always a correct error code; therefore we check the
;; number of words it returns. "SunOS 5.10" (and maybe "SunOS
;; 5.11") have problems with this command, we disable the call
;; therefore.
- (unless (or ignore-path
- (string-match-p
- tramp-sunos-unames
- (tramp-get-connection-property vec "uname" "")))
+ (unless (or ignore-path (tramp-check-remote-uname vec tramp-sunos-unames))
(tramp-send-command vec (format "which \\%s | wc -w" progname))
(goto-char (point-min))
(if (looking-at-p "^\\s-*1$")
@@ -4204,9 +4229,7 @@ file exists and nonzero exit status otherwise."
;; The default shell (ksh93) of OpenSolaris
;; and Solaris is buggy. We've got reports
;; for "SunOS 5.10" and "SunOS 5.11" so far.
- (string-match-p
- tramp-sunos-unames
- (tramp-get-connection-property vec "uname" "")))
+ (tramp-check-remote-uname vec tramp-sunos-unames))
(or (tramp-find-executable
vec "bash" (tramp-get-remote-path vec) t t)
@@ -4574,6 +4597,8 @@ Goes through the list `tramp-local-coding-commands' and
(value (symbol-value rem-enc)))
(while (string-match "-" name)
(setq name (replace-match "_" nil t name)))
+ (unless (tramp-expand-script vec value)
+ (throw 'wont-work-remote nil))
(tramp-maybe-send-script vec value name)
(setq rem-enc name)))
(tramp-message
@@ -4591,6 +4616,8 @@ Goes through the list `tramp-local-coding-commands' and
(value (symbol-value rem-dec)))
(while (string-match "-" name)
(setq name (replace-match "_" nil t name)))
+ (unless (tramp-expand-script vec value)
+ (throw 'wont-work-remote nil))
(tramp-maybe-send-script vec value name)
(setq rem-dec name)))
(tramp-message
@@ -4890,6 +4917,8 @@ connection if a previous connection has died for some reason."
(tramp-error vec 'file-error "`tramp-encoding-shell' not set"))
(let* ((current-host tramp-system-name)
(target-alist (tramp-compute-multi-hops vec))
+ ;; Needed for `tramp-get-remote-null-device'.
+ (previous-hop nil)
;; We will apply `tramp-ssh-controlmaster-options'
;; only for the first hop.
(options (tramp-ssh-controlmaster-options vec))
@@ -4903,7 +4932,7 @@ connection if a previous connection has died for some reason."
;; This must be done in order to avoid our file
;; name handler.
(p (let ((default-directory
- (tramp-compat-temporary-file-directory)))
+ tramp-compat-temporary-file-directory))
(apply
#'start-process
(tramp-get-connection-name vec)
@@ -5002,6 +5031,8 @@ connection if a previous connection has died for some reason."
hop 'tramp-login-args
?h (or l-host "") ?u (or l-user "") ?p (or l-port "")
?c (format-spec options (format-spec-make ?t tmpfile))
+ ?n (concat
+ "2>" (tramp-get-remote-null-device previous-hop))
?l (concat remote-shell " " extra-args " -i"))
;; A restricted shell does not allow "exec".
(when r-shell '("&&" "exit" "||" "exit")))
@@ -5017,10 +5048,12 @@ connection if a previous connection has died for some reason."
tramp-actions-before-shell
(or connection-timeout tramp-connection-timeout))
(tramp-message
- vec 3 "Found remote shell prompt on `%s'" l-host))
- ;; Next hop.
- (setq options ""
- target-alist (cdr target-alist)))
+ vec 3 "Found remote shell prompt on `%s'" l-host)
+
+ ;; Next hop.
+ (setq options ""
+ target-alist (cdr target-alist)
+ previous-hop hop)))
;; Activate session timeout.
(when (tramp-get-connection-property p "session-timeout" nil)
@@ -5317,6 +5350,10 @@ Return ATTR."
;; Variables local to connection.
+(defun tramp-check-remote-uname (vec regexp)
+ "Check whether REGEXP matches the connection property \"uname\"."
+ (string-match-p regexp (tramp-get-connection-property vec "uname" "")))
+
(defun tramp-get-remote-path (vec)
"Compile list of remote directories for PATH.
Nonexistent directories are removed from spec."
@@ -5541,8 +5578,7 @@ Nonexistent directories are removed from spec."
(with-tramp-connection-property vec "stat"
;; stat on Solaris is buggy. We've got reports for "SunOS 5.10"
;; and "SunOS 5.11" so far.
- (unless (string-match-p
- tramp-sunos-unames (tramp-get-connection-property vec "uname" ""))
+ (unless (tramp-check-remote-uname vec tramp-sunos-unames)
(tramp-message vec 5 "Finding a suitable `stat' command")
(let ((result (tramp-find-executable
vec "stat" (tramp-get-remote-path vec)))
@@ -5777,11 +5813,28 @@ This command is returned only if `delete-by-moving-to-trash' is non-nil."
(tramp-file-local-name tmpfile) (tramp-file-local-name tmpfile)))
(delete-file tmpfile)))))
+(defun tramp-get-remote-mknod-or-mkfifo (vec)
+ "Determine remote `mknod' or `mkfifo' command."
+ (with-tramp-connection-property vec "mknod-or-mkfifo"
+ (tramp-message vec 5 "Finding a suitable `mknod' or `mkfifo' command")
+ (let ((tmpfile (tramp-make-tramp-temp-name vec))
+ command)
+ (prog1
+ (or (and (setq command "mknod %s p")
+ (tramp-send-command-and-check
+ vec (format command (tramp-file-local-name tmpfile)))
+ command)
+ (and (setq command "mkfifo %s")
+ (tramp-send-command-and-check
+ vec (format command (tramp-file-local-name tmpfile)))
+ command))
+ (delete-file tmpfile)))))
+
;; Some predefined connection properties.
(defun tramp-get-inline-compress (vec prop size)
"Return the compress command related to PROP.
-PROP is either `inline-compress' or `inline-decompress'. SIZE is
-the length of the file to be compressed.
+PROP is either `inline-compress' or `inline-decompress'.
+SIZE is the length of the file to be compressed.
If no corresponding command is found, nil is returned."
(when (and (integerp tramp-inline-compress-start-size)
@@ -5970,5 +6023,8 @@ function cell is returned to be applied on a buffer."
;; be to stipulate, as a directory or connection-local variable, an
;; additional rc file on the remote machine that is sourced every
;; time Tramp connects. <https://emacs.stackexchange.com/questions/62306>
+;;
+;; * Support hostname canonicalization in ~/.ssh/config.
+;; <https://stackoverflow.com/questions/70205232/>
;;; tramp-sh.el ends here
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index 69372449172..34203076b24 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -48,7 +48,7 @@
;; Another guess. We might implement a better check later on.
(tramp-case-insensitive t)))))
-;; Add a default for `tramp-default-user-alist'. Rule: For the SMB method,
+;; Add a default for `tramp-default-user-alist'. Rule: For the SMB method,
;; the anonymous user is chosen.
;;;###tramp-autoload
(tramp--with-startup
@@ -83,7 +83,7 @@ call, letting the SMB client use the default one."
They are added to the `tramp-smb-program' call via \"--option '...'\".
For example, if the deprecated SMB1 protocol shall be used, add to
-this variable (\"client min protocol=NT1\") ."
+this variable \"client min protocol=NT1\"."
:group 'tramp
:type '(repeat string)
:version "28.1")
@@ -222,7 +222,8 @@ See `tramp-actions-before-shell' for more info.")
;; New handlers should be added here.
;;;###tramp-autoload
(defconst tramp-smb-file-name-handler-alist
- '((access-file . tramp-handle-access-file)
+ '((abbreviate-file-name . tramp-handle-abbreviate-file-name)
+ (access-file . tramp-handle-access-file)
(add-name-to-file . tramp-smb-handle-add-name-to-file)
;; `byte-compiler-base-file-name' performed by default handler.
(copy-directory . tramp-smb-handle-copy-directory)
@@ -330,11 +331,10 @@ This can be used to disable echo etc."
;; It must be a `defsubst' in order to push the whole code into
;; tramp-loaddefs.el. Otherwise, there would be recursive autoloading.
;;;###tramp-autoload
-(defsubst tramp-smb-file-name-p (filename)
- "Check if it's a FILENAME for SMB servers."
- (and (tramp-tramp-file-p filename)
- (string= (tramp-file-name-method (tramp-dissect-file-name filename))
- tramp-smb-method)))
+(defsubst tramp-smb-file-name-p (vec-or-filename)
+ "Check if it's a VEC-OR-FILENAME for SMB servers."
+ (when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
+ (string= (tramp-file-name-method vec) tramp-smb-method)))
;;;###tramp-autoload
(defun tramp-smb-file-name-handler (operation &rest args)
@@ -376,7 +376,7 @@ arguments to pass to the OPERATION."
(and (numberp ok-if-already-exists)
(not (yes-or-no-p
(format
- "File %s already exists; make it a link anyway? "
+ "File %s already exists; make it a link anyway?"
v2-localname)))))
(tramp-error v2 'file-already-exists newname)
(delete-file newname)))
@@ -414,157 +414,175 @@ arguments to pass to the OPERATION."
(defun tramp-smb-handle-copy-directory
(dirname newname &optional keep-date parents copy-contents)
"Like `copy-directory' for Tramp files."
- (if copy-contents
- ;; We must do it file-wise.
- (tramp-run-real-handler
- #'copy-directory (list dirname newname keep-date parents copy-contents))
-
- (setq dirname (expand-file-name dirname)
- newname (expand-file-name newname))
- (let ((t1 (tramp-tramp-file-p dirname))
- (t2 (tramp-tramp-file-p newname)))
- (with-parsed-tramp-file-name (if t1 dirname newname) nil
- (with-tramp-progress-reporter
- v 0 (format "Copying %s to %s" dirname newname)
- (unless (file-exists-p dirname)
- (tramp-compat-file-missing v dirname))
- (when (and (file-directory-p newname)
- (not (directory-name-p newname)))
- (tramp-error v 'file-already-exists newname))
- (cond
- ;; We must use a local temporary directory.
- ((and t1 t2)
- (let ((tmpdir (tramp-compat-make-temp-name)))
- (unwind-protect
- (progn
- (make-directory tmpdir)
- (copy-directory
- dirname (file-name-as-directory tmpdir) keep-date 'parents)
- (copy-directory
- (expand-file-name (file-name-nondirectory dirname) tmpdir)
- newname keep-date parents))
- (delete-directory tmpdir 'recursive))))
-
- ;; We can copy recursively.
- ;; TODO: Does not work reliably.
- (nil ;(and (or t1 t2) (tramp-smb-get-cifs-capabilities v))
+ (let ((t1 (tramp-tramp-file-p dirname))
+ (t2 (tramp-tramp-file-p newname))
+ target)
+ (with-parsed-tramp-file-name (if t1 dirname newname) nil
+ (unless (file-exists-p dirname)
+ (tramp-error v 'file-missing dirname))
+
+ ;; `copy-directory-create-symlink' exists since Emacs 28.1.
+ (if (and (bound-and-true-p copy-directory-create-symlink)
+ (setq target (file-symlink-p dirname))
+ (tramp-equal-remote dirname newname))
+ (make-symbolic-link
+ target
+ (if (directory-name-p newname)
+ (concat newname (file-name-nondirectory dirname)) newname)
+ t)
+
+ (if copy-contents
+ ;; We must do it file-wise.
+ (tramp-run-real-handler
+ #'copy-directory
+ (list dirname newname keep-date parents copy-contents))
+
+ (setq dirname (expand-file-name dirname)
+ newname (expand-file-name newname))
+ (with-tramp-progress-reporter
+ v 0 (format "Copying %s to %s" dirname newname)
+ (unless (file-exists-p dirname)
+ (tramp-error v 'file-missing dirname))
(when (and (file-directory-p newname)
- (not (string-equal (file-name-nondirectory dirname)
- (file-name-nondirectory newname))))
- (setq newname
- (expand-file-name
- (file-name-nondirectory dirname) newname))
- (if t2 (setq v (tramp-dissect-file-name newname))))
- (if (not (file-directory-p newname))
- (make-directory newname parents))
-
- (let* ((share (tramp-smb-get-share v))
- (localname (file-name-as-directory
- (tramp-compat-string-replace
- "\\" "/" (tramp-smb-get-localname v))))
- (tmpdir (tramp-compat-make-temp-name))
- (args (list (concat "//" host "/" share) "-E"))
- (options tramp-smb-options))
-
- (if (not (zerop (length user)))
- (setq args (append args (list "-U" user)))
- (setq args (append args (list "-N"))))
-
- (when domain (setq args (append args (list "-W" domain))))
- (when port (setq args (append args (list "-p" port))))
- (when tramp-smb-conf
- (setq args (append args (list "-s" tramp-smb-conf))))
- (while options
+ (not (directory-name-p newname)))
+ (tramp-error v 'file-already-exists newname))
+ (cond
+ ;; We must use a local temporary directory.
+ ((and t1 t2)
+ (let ((tmpdir (tramp-compat-make-temp-name)))
+ (unwind-protect
+ (progn
+ (make-directory tmpdir)
+ (copy-directory
+ dirname (file-name-as-directory tmpdir)
+ keep-date 'parents)
+ (copy-directory
+ (expand-file-name (file-name-nondirectory dirname) tmpdir)
+ newname keep-date parents))
+ (delete-directory tmpdir 'recursive))))
+
+ ;; We can copy recursively.
+ ;; TODO: Does not work reliably.
+ (nil ;(and (or t1 t2) (tramp-smb-get-cifs-capabilities v))
+ (when (and (file-directory-p newname)
+ (not (string-equal (file-name-nondirectory dirname)
+ (file-name-nondirectory newname))))
+ (setq newname
+ (expand-file-name
+ (file-name-nondirectory dirname) newname))
+ (if t2 (setq v (tramp-dissect-file-name newname))))
+ (if (not (file-directory-p newname))
+ (make-directory newname parents))
+
+ (let* ((share (tramp-smb-get-share v))
+ (localname (file-name-as-directory
+ (tramp-compat-string-replace
+ "\\" "/" (tramp-smb-get-localname v))))
+ (tmpdir (tramp-compat-make-temp-name))
+ (args (list (concat "//" host "/" share) "-E"))
+ (options tramp-smb-options))
+
+ (if (not (zerop (length user)))
+ (setq args (append args (list "-U" user)))
+ (setq args (append args (list "-N"))))
+
+ (when domain (setq args (append args (list "-W" domain))))
+ (when port (setq args (append args (list "-p" port))))
+ (when tramp-smb-conf
+ (setq args (append args (list "-s" tramp-smb-conf))))
+ (while options
+ (setq args
+ (append args `("--option" ,(format "%s" (car options))))
+ options (cdr options)))
(setq args
- (append args `("--option" ,(format "%s" (car options))))
- options (cdr options)))
- (setq args
- (if t1
- ;; Source is remote.
- (append args
+ (if t1
+ ;; Source is remote.
+ (append args
+ (list "-D" (tramp-unquote-shell-quote-argument
+ localname)
+ "-c" (tramp-unquote-shell-quote-argument
+ "tar qc - *")
+ "|" "tar" "xfC" "-"
+ (tramp-unquote-shell-quote-argument
+ tmpdir)))
+ ;; Target is remote.
+ (append (list
+ "tar" "cfC" "-"
+ (tramp-unquote-shell-quote-argument dirname)
+ "." "|")
+ args
(list "-D" (tramp-unquote-shell-quote-argument
localname)
"-c" (tramp-unquote-shell-quote-argument
- "tar qc - *")
- "|" "tar" "xfC" "-"
- (tramp-unquote-shell-quote-argument
- tmpdir)))
- ;; Target is remote.
- (append (list "tar" "cfC" "-"
- (tramp-unquote-shell-quote-argument dirname)
- "." "|")
- args
- (list "-D" (tramp-unquote-shell-quote-argument
- localname)
- "-c" (tramp-unquote-shell-quote-argument
- "tar qx -")))))
-
- (unwind-protect
- (with-temp-buffer
- ;; Set the transfer process properties.
- (tramp-set-connection-property
- v "process-name" (buffer-name (current-buffer)))
- (tramp-set-connection-property
- v "process-buffer" (current-buffer))
-
- (when t1
- ;; The smbclient tar command creates always
- ;; complete paths. We must emulate the
- ;; directory structure, and symlink to the real
- ;; target.
- (make-directory
- (expand-file-name
- ".." (concat tmpdir localname))
- 'parents)
- (make-symbolic-link
- newname (directory-file-name (concat tmpdir localname))))
-
- ;; Use an asynchronous processes. By this,
- ;; password can be handled.
- (let* ((default-directory tmpdir)
- (p (apply
- #'start-process
- (tramp-get-connection-name v)
- (tramp-get-connection-buffer v)
- tramp-smb-program args)))
-
- (tramp-message
- v 6 "%s" (string-join (process-command p) " "))
- (process-put p 'vector v)
- (process-put p 'adjust-window-size-function #'ignore)
- (set-process-query-on-exit-flag p nil)
- (tramp-process-actions p v nil tramp-smb-actions-with-tar)
-
- (while (process-live-p p)
- (sleep-for 0.1))
- (tramp-message v 6 "\n%s" (buffer-string))))
-
- ;; Reset the transfer process properties.
- (tramp-flush-connection-property v "process-name")
- (tramp-flush-connection-property v "process-buffer")
- (when t1 (delete-directory tmpdir 'recursive))))
-
- ;; Handle KEEP-DATE argument.
- (when keep-date
- (tramp-compat-set-file-times
- newname
- (tramp-compat-file-attribute-modification-time
- (file-attributes dirname))
- (unless ok-if-already-exists 'nofollow)))
-
- ;; Set the mode.
- (unless keep-date
- (set-file-modes newname (tramp-default-file-modes dirname)))
-
- ;; When newname did exist, we have wrong cached values.
- (when t2
- (with-parsed-tramp-file-name newname nil
- (tramp-flush-file-properties v localname))))
-
- ;; We must do it file-wise.
- (t
- (tramp-run-real-handler
- #'copy-directory (list dirname newname keep-date parents)))))))))
+ "tar qx -")))))
+
+ (unwind-protect
+ (with-temp-buffer
+ ;; Set the transfer process properties.
+ (tramp-set-connection-property
+ v "process-name" (buffer-name (current-buffer)))
+ (tramp-set-connection-property
+ v "process-buffer" (current-buffer))
+
+ (when t1
+ ;; The smbclient tar command creates always
+ ;; complete paths. We must emulate the
+ ;; directory structure, and symlink to the
+ ;; real target.
+ (make-directory
+ (expand-file-name
+ ".." (concat tmpdir localname))
+ 'parents)
+ (make-symbolic-link
+ newname
+ (directory-file-name (concat tmpdir localname))))
+
+ ;; Use an asynchronous processes. By this,
+ ;; password can be handled.
+ (let* ((default-directory tmpdir)
+ (p (apply
+ #'start-process
+ (tramp-get-connection-name v)
+ (tramp-get-connection-buffer v)
+ tramp-smb-program args)))
+
+ (tramp-message
+ v 6 "%s" (string-join (process-command p) " "))
+ (process-put p 'vector v)
+ (process-put p 'adjust-window-size-function #'ignore)
+ (set-process-query-on-exit-flag p nil)
+ (tramp-process-actions
+ p v nil tramp-smb-actions-with-tar)
+
+ (while (process-live-p p)
+ (sleep-for 0.1))
+ (tramp-message v 6 "\n%s" (buffer-string))))
+
+ ;; Reset the transfer process properties.
+ (tramp-flush-connection-property v "process-name")
+ (tramp-flush-connection-property v "process-buffer")
+ (when t1 (delete-directory tmpdir 'recursive))))
+
+ ;; Handle KEEP-DATE argument.
+ (when keep-date
+ (tramp-compat-set-file-times
+ newname
+ (file-attribute-modification-time (file-attributes dirname))
+ (unless ok-if-already-exists 'nofollow)))
+
+ ;; Set the mode.
+ (unless keep-date
+ (set-file-modes newname (tramp-default-file-modes dirname)))
+
+ ;; When newname did exist, we have wrong cached values.
+ (when t2
+ (with-parsed-tramp-file-name newname nil
+ (tramp-flush-file-properties v localname))))
+
+ ;; We must do it file-wise.
+ (t
+ (tramp-run-real-handler
+ #'copy-directory (list dirname newname keep-date parents))))))))))
(defun tramp-smb-handle-copy-file
(filename newname &optional ok-if-already-exists keep-date
@@ -583,10 +601,10 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(copy-directory filename newname keep-date 'parents 'copy-contents)
(unless (file-exists-p filename)
- (tramp-compat-file-missing
+ (tramp-error
(tramp-dissect-file-name
(if (tramp-tramp-file-p filename) filename newname))
- filename))
+ 'file-missing filename))
(if-let ((tmpfile (file-local-copy filename)))
;; Remote filename.
@@ -626,8 +644,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(when keep-date
(tramp-compat-set-file-times
newname
- (tramp-compat-file-attribute-modification-time
- (file-attributes filename))
+ (file-attribute-modification-time (file-attributes filename))
(unless ok-if-already-exists 'nofollow)))))
(defun tramp-smb-handle-delete-directory (directory &optional recursive trash)
@@ -687,7 +704,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(directory &optional full match nosort count)
"Like `directory-files' for Tramp files."
(unless (file-exists-p directory)
- (tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
+ (tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
(let ((result (mapcar #'directory-file-name
(file-name-all-completions "" directory))))
;; Discriminate with regexp.
@@ -957,7 +974,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
"Like `file-local-copy' for Tramp files."
(with-parsed-tramp-file-name (file-truename filename) nil
(unless (file-exists-p (file-truename filename))
- (tramp-compat-file-missing v filename))
+ (tramp-error v 'file-missing filename))
(let ((tmpfile (tramp-compat-make-temp-file filename)))
(with-tramp-progress-reporter
v 3 (format "Fetching %s to tmp file %s" filename tmpfile)
@@ -1022,8 +1039,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
"Like `file-writable-p' for Tramp files."
(if (file-exists-p filename)
(tramp-compat-string-search
- "w"
- (or (tramp-compat-file-attribute-modes (file-attributes filename)) ""))
+ "w" (or (file-attribute-modes (file-attributes filename)) ""))
(let ((dir (file-name-directory filename)))
(and (file-exists-p dir)
(file-writable-p dir)))))
@@ -1126,11 +1142,11 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(insert
(format
"%10s %3d %-8s %-8s %8s %s "
- (or (tramp-compat-file-attribute-modes attr) (nth 1 x))
- (or (tramp-compat-file-attribute-link-number attr) 1)
- (or (tramp-compat-file-attribute-user-id attr) "nobody")
- (or (tramp-compat-file-attribute-group-id attr) "nogroup")
- (or (tramp-compat-file-attribute-size attr) (nth 2 x))
+ (or (file-attribute-modes attr) (nth 1 x))
+ (or (file-attribute-link-number attr) 1)
+ (or (file-attribute-user-id attr) "nobody")
+ (or (file-attribute-group-id attr) "nogroup")
+ (or (file-attribute-size attr) (nth 2 x))
(format-time-string
(if (time-less-p
;; Half a year.
@@ -1152,8 +1168,8 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
;; Insert symlink.
(when (and (tramp-compat-string-search "l" switches)
- (stringp (tramp-compat-file-attribute-type attr)))
- (insert " -> " (tramp-compat-file-attribute-type attr))))
+ (stringp (file-attribute-type attr)))
+ (insert " -> " (file-attribute-type attr))))
(insert "\n")
(beginning-of-line)))
@@ -1228,7 +1244,7 @@ component is used as the target of the symlink."
(and (numberp ok-if-already-exists)
(not (yes-or-no-p
(format
- "File %s already exists; make it a link anyway? "
+ "File %s already exists; make it a link anyway?"
localname)))))
(tramp-error v 'file-already-exists localname)
(delete-file linkname)))
@@ -1375,7 +1391,7 @@ component is used as the target of the symlink."
(with-parsed-tramp-file-name
(if (tramp-tramp-file-p filename) filename newname) nil
(unless (file-exists-p filename)
- (tramp-compat-file-missing v filename))
+ (tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@@ -1420,9 +1436,9 @@ component is used as the target of the symlink."
(unless (process-live-p proc)
;; Accept pending output.
(while (tramp-accept-process-output proc))
- (with-current-buffer (tramp-get-connection-buffer vec)
- (tramp-message vec 10 "\n%s" (buffer-string))
- (throw 'tramp-action 'ok))))
+ (tramp-message
+ vec 10 "\n%s" (tramp-get-buffer-string (tramp-get-connection-buffer vec)))
+ (throw 'tramp-action 'ok)))
(defun tramp-smb-handle-set-file-acl (filename acl-string)
"Like `set-file-acl' for Tramp files."
@@ -1507,7 +1523,7 @@ component is used as the target of the symlink."
(tramp-error
v 'file-error "Error while changing file's mode %s" filename))))))
-;; We use BUFFER also as connection buffer during setup. Because of
+;; We use BUFFER also as connection buffer during setup. Because of
;; this, its original contents must be saved, and restored once
;; connection has been setup.
(defun tramp-smb-handle-start-file-process (name buffer program &rest args)
@@ -1584,7 +1600,7 @@ errors for shares like \"C$/\", which are common in Microsoft Windows."
(or (eq mustbenew 'excl)
(not
(y-or-n-p
- (format "File %s exists; overwrite anyway? " filename)))))
+ (format "File %s exists; overwrite anyway?" filename)))))
(tramp-error v 'file-already-exists filename))
(let ((file-locked (eq (file-locked-p lockname) t))
@@ -1628,8 +1644,7 @@ errors for shares like \"C$/\", which are common in Microsoft Windows."
;; Set file modification time.
(when (or (eq visit t) (stringp visit))
(set-visited-file-modtime
- (or (tramp-compat-file-attribute-modification-time
- (file-attributes filename))
+ (or (file-attribute-modification-time (file-attributes filename))
(current-time))))
;; Unlock file.
@@ -1639,7 +1654,7 @@ errors for shares like \"C$/\", which are common in Microsoft Windows."
;; The end.
(when (and (null noninteractive)
- (or (eq visit t) (null visit) (stringp visit)))
+ (or (eq visit t) (string-or-null-p visit)))
(tramp-message v 0 "Wrote %s" filename))
(run-hooks 'tramp-handle-write-region-hook))))
@@ -1684,7 +1699,7 @@ If VEC has no cifs capabilities, exchange \"/\" by \"\\\\\"."
localname)))
-;; Share names of a host are cached. It is very unlikely that the
+;; Share names of a host are cached. It is very unlikely that the
;; shares do change during connection.
(defun tramp-smb-get-file-entries (directory)
"Read entries which match DIRECTORY.
@@ -1943,7 +1958,7 @@ If ARGUMENT is non-nil, use it as argument for
;; Otherwise, we must delete the connection cache, because
;; capabilities might have changed.
(unless (or argument (processp p))
- (let ((default-directory (tramp-compat-temporary-file-directory))
+ (let ((default-directory tramp-compat-temporary-file-directory)
(command (concat tramp-smb-program " -V")))
(unless tramp-smb-version
@@ -2030,7 +2045,10 @@ If ARGUMENT is non-nil, use it as argument for
(let* ((coding-system-for-read nil)
(process-connection-type tramp-process-connection-type)
(p (let ((default-directory
- (tramp-compat-temporary-file-directory)))
+ tramp-compat-temporary-file-directory)
+ (process-environment
+ (cons (concat "TERM=" tramp-terminal-type)
+ process-environment)))
(apply #'start-process
(tramp-get-connection-name vec)
(tramp-get-connection-buffer vec)
@@ -2181,5 +2199,7 @@ Removes smb prompt. Returns nil if an error message has appeared."
;;
;; * Try to remove the inclusion of dummy "" directory. Seems to be at
;; several places, especially in `tramp-smb-handle-insert-directory'.
+;;
+;; * Keep a separate connection process per share.
;;; tramp-smb.el ends here
diff --git a/lisp/net/tramp-sshfs.el b/lisp/net/tramp-sshfs.el
index c5b84a6e4e4..ef1f302546a 100644
--- a/lisp/net/tramp-sshfs.el
+++ b/lisp/net/tramp-sshfs.el
@@ -71,7 +71,8 @@
;; New handlers should be added here.
;;;###tramp-autoload
(defconst tramp-sshfs-file-name-handler-alist
- '((access-file . tramp-handle-access-file)
+ '(;; `abbreviate-file-name' performed by default handler.
+ (access-file . tramp-handle-access-file)
(add-name-to-file . tramp-handle-add-name-to-file)
;; `byte-compiler-base-file-name' performed by default handler.
(copy-directory . tramp-handle-copy-directory)
@@ -110,7 +111,7 @@
(file-notify-rm-watch . ignore)
(file-notify-valid-p . ignore)
(file-ownership-preserved-p . ignore)
- (file-readable-p . tramp-fuse-handle-file-readable-p)
+ (file-readable-p . tramp-handle-file-readable-p)
(file-regular-p . tramp-handle-file-regular-p)
(file-remote-p . tramp-handle-file-remote-p)
(file-selinux-context . tramp-handle-file-selinux-context)
@@ -156,11 +157,10 @@ Operations not mentioned here will be handled by the default Emacs primitives.")
;; It must be a `defsubst' in order to push the whole code into
;; tramp-loaddefs.el. Otherwise, there would be recursive autoloading.
;;;###tramp-autoload
-(defsubst tramp-sshfs-file-name-p (filename)
- "Check if it's a FILENAME for sshfs."
- (and (tramp-tramp-file-p filename)
- (string= (tramp-file-name-method (tramp-dissect-file-name filename))
- tramp-sshfs-method)))
+(defsubst tramp-sshfs-file-name-p (vec-or-filename)
+ "Check if it's a VEC-OR-FILENAME for sshfs."
+ (when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
+ (string= (tramp-file-name-method vec) tramp-sshfs-method)))
;;;###tramp-autoload
(defun tramp-sshfs-file-name-handler (operation &rest args)
@@ -222,11 +222,14 @@ arguments to pass to the OPERATION."
(defun tramp-sshfs-handle-insert-file-contents
(filename &optional visit beg end replace)
"Like `insert-file-contents' for Tramp files."
- (let ((result
- (insert-file-contents
- (tramp-fuse-local-file-name filename) visit beg end replace)))
- (when visit (setq buffer-file-name filename))
- (cons (expand-file-name filename) (cdr result))))
+ (setq filename (expand-file-name filename))
+ (let (signal-hook-function result)
+ (unwind-protect
+ (setq result
+ (insert-file-contents
+ (tramp-fuse-local-file-name filename) visit beg end replace))
+ (when visit (setq buffer-file-name filename))
+ (cons filename (cdr result)))))
(defun tramp-sshfs-handle-process-file
(program &optional infile destination display &rest args)
@@ -292,7 +295,7 @@ arguments to pass to the OPERATION."
(or (eq mustbenew 'excl)
(not
(y-or-n-p
- (format "File %s exists; overwrite anyway? " filename)))))
+ (format "File %s exists; overwrite anyway?" filename)))))
(tramp-error v 'file-already-exists filename))
(let ((file-locked (eq (file-locked-p lockname) t)))
@@ -317,7 +320,7 @@ arguments to pass to the OPERATION."
;; The end.
(when (and (null noninteractive)
- (or (eq visit t) (null visit) (stringp visit)))
+ (or (eq visit t) (string-or-null-p visit)))
(tramp-message v 0 "Wrote %s" filename))
(run-hooks 'tramp-handle-write-region-hook))))
@@ -342,34 +345,32 @@ connection if a previous connection has died for some reason."
(process-put p 'vector vec)
(set-process-query-on-exit-flag p nil)
- ;; Mark process for filelock.
- (tramp-set-connection-property p "lock-pid" (truncate (time-to-seconds)))
-
;; Set connection-local variables.
- (tramp-set-connection-local-variables vec)
-
- ;; Create directory.
- (unless (file-directory-p (tramp-fuse-mount-point vec))
- (make-directory (tramp-fuse-mount-point vec) 'parents))
-
- (unless
- (or (tramp-fuse-mounted-p vec)
- (with-temp-buffer
- (zerop
- (apply
- #'tramp-call-process
- vec tramp-sshfs-program nil t nil
- (tramp-fuse-mount-spec vec)
- (tramp-fuse-mount-point vec)
- (tramp-expand-args
- vec 'tramp-mount-args
- ?p (or (tramp-file-name-port vec) "")))))
- (tramp-error
- vec 'file-error "Error mounting %s" (tramp-fuse-mount-spec vec))))
-
- ;; Mark it as connected.
- (tramp-set-connection-property
- (tramp-get-connection-process vec) "connected" t)))
+ (tramp-set-connection-local-variables vec)))
+
+ ;; Create directory.
+ (unless (file-directory-p (tramp-fuse-mount-point vec))
+ (make-directory (tramp-fuse-mount-point vec) 'parents))
+
+ (unless
+ (or (tramp-fuse-mounted-p vec)
+ (with-temp-buffer
+ (zerop
+ (apply
+ #'tramp-call-process
+ vec tramp-sshfs-program nil t nil
+ (tramp-fuse-mount-spec vec)
+ (tramp-fuse-mount-point vec)
+ (tramp-expand-args
+ vec 'tramp-mount-args
+ ?p (or (tramp-file-name-port vec) ""))))))
+ (tramp-error
+ vec 'file-error "Error mounting %s" (tramp-fuse-mount-spec vec)))
+
+ ;; Mark it as connected.
+ (add-to-list 'tramp-fuse-mount-points (tramp-file-name-unify vec))
+ (tramp-set-connection-property
+ (tramp-get-connection-process vec) "connected" t)
;; In `tramp-check-cached-permissions', the connection properties
;; "{uid,gid}-{integer,string}" are used. We set them to proper values.
diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el
index 5895f1d25b5..88e8c43534b 100644
--- a/lisp/net/tramp-sudoedit.el
+++ b/lisp/net/tramp-sudoedit.el
@@ -63,7 +63,8 @@ See `tramp-actions-before-shell' for more info.")
;;;###tramp-autoload
(defconst tramp-sudoedit-file-name-handler-alist
- '((access-file . tramp-handle-access-file)
+ '((abbreviate-file-name . tramp-handle-abbreviate-file-name)
+ (access-file . tramp-handle-access-file)
(add-name-to-file . tramp-sudoedit-handle-add-name-to-file)
(byte-compiler-base-file-name . ignore)
(copy-directory . tramp-handle-copy-directory)
@@ -148,11 +149,10 @@ See `tramp-actions-before-shell' for more info.")
;; It must be a `defsubst' in order to push the whole code into
;; tramp-loaddefs.el. Otherwise, there would be recursive autoloading.
;;;###tramp-autoload
-(defsubst tramp-sudoedit-file-name-p (filename)
- "Check if it's a FILENAME for SUDOEDIT."
- (and (tramp-tramp-file-p filename)
- (string= (tramp-file-name-method (tramp-dissect-file-name filename))
- tramp-sudoedit-method)))
+(defsubst tramp-sudoedit-file-name-p (vec-or-filename)
+ "Check if it's a VEC-OR-FILENAME for SUDOEDIT."
+ (when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
+ (string= (tramp-file-name-method vec) tramp-sudoedit-method)))
;;;###tramp-autoload
(defun tramp-sudoedit-file-name-handler (operation &rest args)
@@ -190,7 +190,7 @@ arguments to pass to the OPERATION."
(and (numberp ok-if-already-exists)
(not (yes-or-no-p
(format
- "File %s already exists; make it a link anyway? "
+ "File %s already exists; make it a link anyway?"
v2-localname)))))
(tramp-error v2 'file-already-exists newname)
(delete-file newname)))
@@ -233,7 +233,7 @@ absolute file names."
(let ((t1 (tramp-sudoedit-file-name-p filename))
(t2 (tramp-sudoedit-file-name-p newname))
- (file-times (tramp-compat-file-attribute-modification-time
+ (file-times (file-attribute-modification-time
(file-attributes filename)))
(file-modes (tramp-default-file-modes filename))
(attributes (and preserve-extended-attributes
@@ -247,7 +247,7 @@ absolute file names."
(with-parsed-tramp-file-name (if t1 filename newname) nil
(unless (file-exists-p filename)
- (tramp-compat-file-missing v filename))
+ (tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@@ -336,7 +336,7 @@ absolute file names."
(if (and delete-by-moving-to-trash trash)
(move-file-to-trash filename)
(unless (tramp-sudoedit-send-command
- v "rm" (tramp-compat-file-name-unquote localname))
+ v "rm" "-f" (tramp-compat-file-name-unquote localname))
;; Propagate the error.
(with-current-buffer (tramp-get-connection-buffer v)
(goto-char (point-min))
@@ -453,19 +453,21 @@ the result will be a local, non-Tramp, file name."
(if (file-directory-p (expand-file-name f directory))
(file-name-as-directory f)
f))
- (with-current-buffer (tramp-get-connection-buffer v)
- (delq
- nil
- (mapcar
- (lambda (l) (and (not (string-match-p "^[[:space:]]*$" l)) l))
- (split-string (buffer-string) "\n" 'omit)))))))))
+ (delq
+ nil
+ (mapcar
+ (lambda (l) (and (not (string-match-p "^[[:space:]]*$" l)) l))
+ (split-string
+ (tramp-get-buffer-string (tramp-get-connection-buffer v))
+ "\n" 'omit))))))))
(defun tramp-sudoedit-handle-file-readable-p (filename)
"Like `file-readable-p' for Tramp files."
(with-parsed-tramp-file-name filename nil
(with-tramp-file-property v localname "file-readable-p"
- (tramp-sudoedit-send-command
- v "test" "-r" (tramp-compat-file-name-unquote localname)))))
+ (or (tramp-handle-file-readable-p filename)
+ (tramp-sudoedit-send-command
+ v "test" "-r" (tramp-compat-file-name-unquote localname))))))
(defun tramp-sudoedit-handle-set-file-modes (filename mode &optional flag)
"Like `set-file-modes' for Tramp files."
@@ -533,7 +535,7 @@ the result will be a local, non-Tramp, file name."
(if (or (null time)
(tramp-compat-time-equal-p time tramp-time-doesnt-exist)
(tramp-compat-time-equal-p time tramp-time-dont-know))
- (current-time)
+ nil
time)))
(tramp-sudoedit-send-command
v "env" "TZ=UTC" "touch" "-t"
@@ -597,6 +599,7 @@ the result will be a local, non-Tramp, file name."
v (if parents "/" (file-name-directory localname)))
(unless (tramp-sudoedit-send-command
v (if parents '("mkdir" "-p") "mkdir")
+ "-m" (format "%#o" (default-file-modes))
(tramp-compat-file-name-unquote localname))
(tramp-error v 'file-error "Couldn't make directory %s" dir))))
@@ -631,7 +634,7 @@ component is used as the target of the symlink."
(not
(yes-or-no-p
(format
- "File %s already exists; make it a link anyway? "
+ "File %s already exists; make it a link anyway?"
localname)))))
(tramp-error v 'file-already-exists localname)
(delete-file linkname)))
@@ -719,11 +722,9 @@ ID-FORMAT valid values are `string' and `integer'."
"Like `write-region' for Tramp files."
(setq filename (expand-file-name filename))
(with-parsed-tramp-file-name filename nil
- (let* ((uid (or (tramp-compat-file-attribute-user-id
- (file-attributes filename 'integer))
+ (let* ((uid (or (file-attribute-user-id (file-attributes filename 'integer))
(tramp-get-remote-uid v 'integer)))
- (gid (or (tramp-compat-file-attribute-group-id
- (file-attributes filename 'integer))
+ (gid (or (file-attribute-group-id (file-attributes filename 'integer))
(tramp-get-remote-gid v 'integer)))
(flag (and (eq mustbenew 'excl) 'nofollow))
(modes (tramp-default-file-modes filename flag))
@@ -734,10 +735,10 @@ ID-FORMAT valid values are `string' and `integer'."
;; Set the ownership, modes and extended attributes. This is
;; not performed in `tramp-handle-write-region'.
- (unless (and (= (tramp-compat-file-attribute-user-id
+ (unless (and (= (file-attribute-user-id
(file-attributes filename 'integer))
uid)
- (= (tramp-compat-file-attribute-group-id
+ (= (file-attribute-group-id
(file-attributes filename 'integer))
gid))
(tramp-set-file-uid-gid filename uid gid))
@@ -787,9 +788,6 @@ connection if a previous connection has died for some reason."
(process-put p 'vector vec)
(set-process-query-on-exit-flag p nil)
- ;; Mark process for filelock.
- (tramp-set-connection-property p "lock-pid" (truncate (time-to-seconds)))
-
;; Set connection-local variables.
(tramp-set-connection-local-variables vec)
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 83df05c24b7..940e25e04f9 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -183,7 +183,7 @@ See the variable `tramp-encoding-shell' for more information."
:version "24.1"
:type '(choice (const nil) string))
-;; Since Emacs 26.1, `system-name' can return `nil' at build time if
+;; Since Emacs 26.1, `system-name' can return nil at build time if
;; Emacs is compiled with "--no-build-details". We do expect it to be
;; a string. (Bug#44481)
(defconst tramp-system-name (or (system-name) "")
@@ -714,6 +714,13 @@ The regexp should match at end of buffer."
:version "28.1"
:type 'regexp)
+(defcustom tramp-security-key-timeout-regexp
+ "^\r*sign_and_send_pubkey: signing failed for .*[\r\n]*"
+ "Regular expression matching security key timeout message.
+The regexp should match at end of buffer."
+ :version "28.1"
+ :type 'regexp)
+
(defcustom tramp-operation-not-permitted-regexp
(concat "\\(" "preserving times.*" "\\|" "set mode" "\\)" ":\\s-*"
(regexp-opt '("Operation not permitted") t))
@@ -744,11 +751,11 @@ The answer will be provided by `tramp-action-process-alive',
(defconst tramp-temp-name-prefix "tramp."
"Prefix to use for temporary files.
-If this is a relative file name (such as \"tramp.\"), it is considered
-relative to the directory name returned by the function
-`tramp-compat-temporary-file-directory' (which see). It may also be an
-absolute file name; don't forget to include a prefix for the filename
-part, though.")
+If this is a relative file name (such as \"tramp.\"), it is
+considered relative to the directory name returned by the
+function `temporary-file-directory' (which see). It may also be
+an absolute file name; don't forget to include a prefix for the
+filename part, though.")
(defconst tramp-temp-buffer-name " *tramp temp*"
"Buffer name for a temporary buffer.
@@ -815,11 +822,10 @@ to be set, depending on VALUE."
(tramp-register-file-name-handlers))
;; Initialize the Tramp syntax variables. We want to override initial
-;; value of `tramp-file-name-regexp'. Other Tramp syntax variables
-;; must be initialized as well to proper values. We do not call
+;; value of `tramp-file-name-regexp'. We do not call
;; `custom-set-variable', this would load Tramp via custom.el.
(tramp--with-startup
- (tramp-set-syntax 'tramp-syntax (tramp-compat-tramp-syntax)))
+ (tramp-set-syntax 'tramp-syntax tramp-syntax))
(defun tramp-syntax-values ()
"Return possible values of `tramp-syntax', a list."
@@ -829,9 +835,9 @@ to be set, depending on VALUE."
values))
(defun tramp-lookup-syntax (alist)
- "Look up a syntax string in ALIST according to `tramp-compat-tramp-syntax'.
-Raise an error if `tramp-syntax' is invalid."
- (or (cdr (assq (tramp-compat-tramp-syntax) alist))
+ "Look up a syntax string in ALIST according to `tramp-syntax'.
+Raise an error if it is invalid."
+ (or (cdr (assq tramp-syntax alist))
(error "Wrong `tramp-syntax' %s" tramp-syntax)))
(defconst tramp-prefix-format-alist
@@ -854,7 +860,7 @@ Used in `tramp-make-tramp-file-name'.")
(defvar tramp-prefix-regexp nil ;Initialized when defining `tramp-syntax'!
"Regexp matching the very beginning of Tramp file names.
-Should always start with \"^\". Derived from `tramp-prefix-format'.")
+Should always start with \"^\". Derived from `tramp-prefix-format'.")
(defconst tramp-method-regexp-alist
'((default . "[[:alnum:]-]+")
@@ -1297,7 +1303,7 @@ let-bind this variable."
;; "getconf PATH" yields:
;; HP-UX: /usr/bin:/usr/ccs/bin:/opt/ansic/bin:/opt/langtools/bin:/opt/fortran/bin
;; Solaris: /usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin
-;; GNU/Linux (Debian, Suse, RHEL): /bin:/usr/bin
+;; GNU/Linux (Debian, Suse, RHEL, Cygwin, MINGW64): /bin:/usr/bin
;; FreeBSD, DragonFly: /usr/bin:/bin:/usr/sbin:/sbin: - beware trailing ":"!
;; FreeBSD 12.1, Darwin: /usr/bin:/bin:/usr/sbin:/sbin
;; IRIX64: /usr/bin
@@ -1319,9 +1325,9 @@ tilde expansion, all directory names starting with \"~\" will be ignored.
the command \"getconf PATH\". It is recommended to use this
entry on head of this list, because these are the default
directories for POSIX compatible commands. On remote hosts which
-do not offer the getconf command (like cygwin), the value
-\"/bin:/usr/bin\" is used instead. This entry is represented in
-the list by the special value `tramp-default-remote-path'.
+do not offer the getconf command, the value \"/bin:/usr/bin\" is
+used instead. This entry is represented in the list by the
+special value `tramp-default-remote-path'.
`Private Directories' are the settings of the $PATH environment,
as given in your `~/.profile'. This entry is represented in
@@ -1402,8 +1408,7 @@ calling HANDLER.")
;; internal data structure. Convenience functions for internal
;; data structure.
-;; The basic structure for remote file names. We use a list :type,
-;; in order to be compatible with Emacs 25.
+;; The basic structure for remote file names.
(cl-defstruct (tramp-file-name (:type list) :named)
method user domain host port localname hop)
@@ -1443,16 +1448,24 @@ If nil, return `tramp-default-port'."
(put #'tramp-file-name-port-or-default 'tramp-suppress-trace t)
+(defun tramp-file-name-unify (vec)
+ "Unify VEC by removing localname and hop from `tramp-file-name' structure.
+Objects returned by this function compare `equal' if they refer to the
+same connection. Make a copy in order to avoid side effects."
+ (when (tramp-file-name-p vec)
+ (setq vec (copy-tramp-file-name vec))
+ (setf (tramp-file-name-localname vec) nil
+ (tramp-file-name-hop vec) nil))
+ vec)
+
+(put #'tramp-file-name-unify 'tramp-suppress-trace t)
+
;; Comparison of file names is performed by `tramp-equal-remote'.
(defun tramp-file-name-equal-p (vec1 vec2)
"Check, whether VEC1 and VEC2 denote the same `tramp-file-name'."
(and (tramp-file-name-p vec1) (tramp-file-name-p vec2)
- (string-equal (tramp-file-name-method vec1)
- (tramp-file-name-method vec2))
- (string-equal (tramp-file-name-user-domain vec1)
- (tramp-file-name-user-domain vec2))
- (string-equal (tramp-file-name-host-port vec1)
- (tramp-file-name-host-port vec2))))
+ (equal (tramp-file-name-unify vec1)
+ (tramp-file-name-unify vec2))))
(defun tramp-get-method-parameter (vec param)
"Return the method parameter PARAM.
@@ -1507,7 +1520,7 @@ of `process-file', `start-file-process', or `shell-command'."
(or (and (tramp-tramp-file-p name)
(string-match (nth 0 tramp-file-name-structure) name)
(match-string (nth 4 tramp-file-name-structure) name))
- (tramp-compat-file-local-name name)))
+ (file-local-name name)))
;; The localname can be quoted with "/:". Extract this.
(defun tramp-unquote-file-local-name (name)
@@ -1654,6 +1667,18 @@ default values are used."
(put #'tramp-dissect-file-name 'tramp-suppress-trace t)
+(defun tramp-ensure-dissected-file-name (vec-or-filename)
+ "Return a `tramp-file-name' structure for VEC-OR-FILENAME.
+
+VEC-OR-FILENAME may be either a string or a `tramp-file-name'.
+If it's not a Tramp filename, return nil."
+ (cond
+ ((tramp-file-name-p vec-or-filename) vec-or-filename)
+ ((tramp-tramp-file-p vec-or-filename)
+ (tramp-dissect-file-name vec-or-filename))))
+
+(put #'tramp-ensure-dissected-file-name 'tramp-suppress-trace t)
+
(defun tramp-dissect-hop-name (name &optional nodefault)
"Return a `tramp-file-name' structure of `hop' part of NAME.
See `tramp-dissect-file-name' for details."
@@ -1743,6 +1768,9 @@ the form (METHOD USER DOMAIN HOST PORT LOCALNAME &optional HOP)."
tramp-postfix-host-format
localname)))
+(set-advertised-calling-convention
+ #'tramp-make-tramp-file-name '(vec &optional localname hop) "27.1")
+
(defun tramp-make-tramp-hop-name (vec)
"Construct a Tramp hop name from VEC."
(replace-regexp-in-string
@@ -1821,9 +1849,7 @@ from the default one."
If connection-local variables are not supported by this Emacs
version, the function does nothing."
(with-current-buffer (tramp-get-connection-buffer vec)
- ;; `hack-connection-local-variables-apply' exists since Emacs 26.1.
- (tramp-compat-funcall
- 'hack-connection-local-variables-apply
+ (hack-connection-local-variables-apply
`(:application tramp
:protocol ,(tramp-file-name-method vec)
:user ,(tramp-file-name-user-domain vec)
@@ -1834,14 +1860,27 @@ version, the function does nothing."
If connection-local variables are not supported by this Emacs
version, the function does nothing."
(when (tramp-tramp-file-p default-directory)
- ;; `hack-connection-local-variables-apply' exists since Emacs 26.1.
- (tramp-compat-funcall
- 'hack-connection-local-variables-apply
+ (hack-connection-local-variables-apply
`(:application tramp
:protocol ,(file-remote-p default-directory 'method)
:user ,(file-remote-p default-directory 'user)
:machine ,(file-remote-p default-directory 'host)))))
+(defsubst tramp-get-default-directory (buffer)
+ "Return `default-directory' of BUFFER."
+ (buffer-local-value 'default-directory buffer))
+
+(put #'tramp-get-default-directory 'tramp-suppress-trace t)
+
+(defsubst tramp-get-buffer-string (&optional buffer)
+ "Return contents of BUFFER.
+If BUFFER is not a buffer or a buffer name, return the contents
+of `current-buffer'."
+ (with-current-buffer (or buffer (current-buffer))
+ (substring-no-properties (buffer-string))))
+
+(put #'tramp-get-buffer-string 'tramp-suppress-trace t)
+
(defun tramp-debug-buffer-name (vec)
"A name for the debug buffer for VEC."
(let ((method (tramp-file-name-method vec))
@@ -1880,29 +1919,55 @@ The outline level is equal to the verbosity of the Tramp message."
(put #'tramp-debug-outline-level 'tramp-suppress-trace t)
+;; This function takes action since Emacs 28.1, when
+;; `read-extended-command-predicate' is set to
+;; `command-completion-default-include-p'.
+(defun tramp-debug-buffer-command-completion-p (_symbol buffer)
+ "A predicate for Tramp interactive commands.
+They are completed by \"M-x TAB\" only in Tramp debug buffers."
+ (with-current-buffer buffer
+ (string-equal (buffer-substring 1 10) ";; Emacs:")))
+
+(put #'tramp-debug-buffer-command-completion-p 'tramp-suppress-trace t)
+
+(defun tramp-setup-debug-buffer ()
+ "Function to setup debug buffers."
+ ;; (declare (completion tramp-debug-buffer-command-completion-p))
+ (interactive)
+ (set-buffer-file-coding-system 'utf-8)
+ (setq buffer-undo-list t)
+ ;; Activate `outline-mode'. This runs `text-mode-hook' and
+ ;; `outline-mode-hook'. We must prevent that local processes die.
+ ;; Yes: I've seen `flyspell-mode', which starts "ispell".
+ ;; `(custom-declare-variable outline-minor-mode-prefix ...)' raises
+ ;; on error in `(outline-mode)', we don't want to see it in the
+ ;; traces.
+ (let ((default-directory tramp-compat-temporary-file-directory))
+ (outline-mode))
+ (setq-local outline-level 'tramp-debug-outline-level)
+ (setq-local font-lock-keywords
+ ;; FIXME: This `(t FOO . BAR)' representation in
+ ;; `font-lock-keywords' is supposed to be an internal
+ ;; implementation "detail". Don't abuse it here!
+ `(t (eval ,tramp-debug-font-lock-keywords t)
+ ,(eval tramp-debug-font-lock-keywords t)))
+ ;; Do not edit the debug buffer.
+ (use-local-map special-mode-map)
+ ;; For debugging purposes.
+ (local-set-key "\M-n" 'clone-buffer)
+ (add-hook 'clone-buffer-hook #'tramp-setup-debug-buffer nil 'local))
+
+(put #'tramp-setup-debug-buffer 'tramp-suppress-trace t)
+
+(function-put
+ #'tramp-setup-debug-buffer 'completion-predicate
+ #'tramp-debug-buffer-command-completion-p)
+
(defun tramp-get-debug-buffer (vec)
"Get the debug buffer for VEC."
(with-current-buffer (get-buffer-create (tramp-debug-buffer-name vec))
(when (bobp)
- (set-buffer-file-coding-system 'utf-8)
- (setq buffer-undo-list t)
- ;; Activate `outline-mode'. This runs `text-mode-hook' and
- ;; `outline-mode-hook'. We must prevent that local processes
- ;; die. Yes: I've seen `flyspell-mode', which starts "ispell".
- ;; `(custom-declare-variable outline-minor-mode-prefix ...)'
- ;; raises on error in `(outline-mode)', we don't want to see it
- ;; in the traces.
- (let ((default-directory (tramp-compat-temporary-file-directory)))
- (outline-mode))
- (setq-local outline-level 'tramp-debug-outline-level)
- (setq-local font-lock-keywords
- ;; FIXME: This `(t FOO . BAR)' representation in
- ;; `font-lock-keywords' is supposed to be an
- ;; internal implementation "detail". Don't abuse it here!
- `(t (eval ,tramp-debug-font-lock-keywords t)
- ,(eval tramp-debug-font-lock-keywords t)))
- ;; Do not edit the debug buffer.
- (use-local-map special-mode-map))
+ (tramp-setup-debug-buffer))
(current-buffer)))
(put #'tramp-get-debug-buffer 'tramp-suppress-trace t)
@@ -1911,7 +1976,7 @@ The outline level is equal to the verbosity of the Tramp message."
"Get the debug file name for VEC."
(expand-file-name
(tramp-compat-string-replace "/" " " (tramp-debug-buffer-name vec))
- (tramp-compat-temporary-file-directory)))
+ tramp-compat-temporary-file-directory))
(put #'tramp-get-debug-file-name 'tramp-suppress-trace t)
@@ -1922,7 +1987,7 @@ The outline level is equal to the verbosity of the Tramp message."
(put #'tramp-trace-buffer-name 'tramp-suppress-trace t)
(defvar tramp-trace-functions nil
- "A list of non-Tramp functions to be traced with tramp-verbose > 10.")
+ "A list of non-Tramp functions to be traced with `tramp-verbose' > 10.")
(defun tramp-debug-message (vec fmt-string &rest arguments)
"Append message to debug buffer of VEC.
@@ -1953,7 +2018,8 @@ ARGUMENTS to actually emit the message (if applicable)."
(dolist
(elt
(append
- (mapcar #'intern (all-completions "tramp-" obarray 'functionp))
+ (mapcar
+ #'intern (all-completions "tramp-" obarray #'functionp))
tramp-trace-functions))
(unless (get elt 'tramp-suppress-trace)
(trace-function-background elt))))
@@ -1963,9 +2029,7 @@ ARGUMENTS to actually emit the message (if applicable)."
(unless (bolp)
(insert "\n"))
;; Timestamp.
- (let ((now (current-time)))
- (insert (format-time-string "%T." now))
- (insert (format "%06d " (nth 2 now))))
+ (insert (format-time-string "%T.%6N "))
;; Calling Tramp function. We suppress compat and trace
;; functions from being displayed.
(let ((btn 1) btf fn)
@@ -2035,12 +2099,15 @@ applicable)."
;; Append connection buffer for error messages, if exists.
(when (= level 1)
(ignore-errors
- (with-current-buffer
- (if (processp vec-or-proc)
- (process-buffer vec-or-proc)
- (tramp-get-connection-buffer vec-or-proc 'dont-create))
- (setq fmt-string (concat fmt-string "\n%s")
- arguments (append arguments (list (buffer-string)))))))
+ (setq fmt-string (concat fmt-string "\n%s")
+ arguments
+ (append
+ arguments
+ `(,(tramp-get-buffer-string
+ (if (processp vec-or-proc)
+ (process-buffer vec-or-proc)
+ (tramp-get-connection-buffer
+ vec-or-proc 'dont-create))))))))
;; Translate proc to vec.
(when (processp vec-or-proc)
(setq vec-or-proc (process-get vec-or-proc 'vector))))
@@ -2071,8 +2138,7 @@ VEC-OR-PROC identifies the connection to use, SIGNAL is the
signal identifier to be raised, remaining arguments passed to
`tramp-message'. Finally, signal SIGNAL is raised with
FMT-STRING and ARGUMENTS."
- (let ((inhibit-message t)
- signal-hook-function)
+ (let (signal-hook-function)
(tramp-backtrace vec-or-proc)
(unless arguments
;; FMT-STRING could be just a file name, as in
@@ -2103,8 +2169,8 @@ an input event arrives. The other arguments are passed to `tramp-error'."
(and (tramp-file-name-p vec-or-proc)
(tramp-get-connection-buffer vec-or-proc))))
(vec (or (and (tramp-file-name-p vec-or-proc) vec-or-proc)
- (and buf (with-current-buffer buf
- (tramp-dissect-file-name default-directory))))))
+ (and buf (tramp-dissect-file-name
+ (tramp-get-default-directory buf))))))
(unwind-protect
(apply #'tramp-error vec-or-proc signal fmt-string arguments)
;; Save exit.
@@ -2168,10 +2234,14 @@ the resulting error message."
(defun tramp-test-message (fmt-string &rest arguments)
"Emit a Tramp message according `default-directory'."
- (if (tramp-tramp-file-p default-directory)
- (apply #'tramp-message
- (tramp-dissect-file-name default-directory) 0 fmt-string arguments)
- (apply #'message fmt-string arguments)))
+ (cond
+ ((tramp-tramp-file-p default-directory)
+ (apply #'tramp-message
+ (tramp-dissect-file-name default-directory) 0 fmt-string arguments))
+ ((tramp-file-name-p (car tramp-current-connection))
+ (apply #'tramp-message
+ (car tramp-current-connection) 0 fmt-string arguments))
+ (t (apply #'message fmt-string arguments))))
(put #'tramp-test-message 'tramp-suppress-trace t)
@@ -2182,9 +2252,10 @@ the resulting error message."
;; `custom-initialize-*' functions provoke `void-variable' errors.
;; We don't want to see them in the backtrace.
(unless (eq error-symbol 'void-variable)
- (tramp-error
- (car tramp-current-connection) error-symbol
- (mapconcat (lambda (x) (format "%s" x)) data " "))))
+ (let ((inhibit-message t))
+ (tramp-error
+ (car tramp-current-connection) error-symbol
+ (mapconcat (lambda (x) (format "%s" x)) data " ")))))
(put #'tramp-signal-hook-function 'tramp-suppress-trace t)
@@ -2372,7 +2443,7 @@ For definition of that list see `tramp-set-completion-function'."
;; Inodes don't exist for some file systems. Therefore we must
;; generate virtual ones. Used in `find-buffer-visiting'. The method
-;; applied might be not so efficient (Ange-FTP uses hashes). But
+;; applied might be not so efficient (Ange-FTP uses hashes). But
;; performance isn't the major issue given that file transfer will
;; take time.
(defvar tramp-inodes 0
@@ -2457,31 +2528,29 @@ Must be handled by the callers."
file-accessible-directory-p file-attributes
file-directory-p file-executable-p file-exists-p
file-local-copy file-modes file-name-as-directory
- file-name-directory file-name-nondirectory
- file-name-sans-versions file-notify-add-watch
- file-ownership-preserved-p file-readable-p
- file-regular-p file-remote-p file-selinux-context
- file-symlink-p file-truename file-writable-p
- find-backup-file-name get-file-buffer
+ file-name-case-insensitive-p file-name-directory
+ file-name-nondirectory file-name-sans-versions
+ file-notify-add-watch file-ownership-preserved-p
+ file-readable-p file-regular-p file-remote-p
+ file-selinux-context file-symlink-p file-truename
+ file-writable-p find-backup-file-name get-file-buffer
insert-directory insert-file-contents load
make-directory make-directory-internal set-file-acl
set-file-modes set-file-selinux-context set-file-times
substitute-in-file-name unhandled-file-name-directory
vc-registered
- ;; Emacs 26+ only.
- file-name-case-insensitive-p
;; Emacs 27+ only.
file-system-info
;; Emacs 28+ only.
file-locked-p lock-file make-lock-file-name unlock-file
+ ;; Emacs 29+ only.
+ abbreviate-file-name
;; Tramp internal magic file name function.
tramp-set-file-uid-gid))
(if (file-name-absolute-p (nth 0 args))
(nth 0 args)
default-directory))
;; STRING FILE.
- ;; Starting with Emacs 26.1, just the 2nd argument of
- ;; `make-symbolic-link' matters.
((eq operation 'make-symbolic-link) (nth 1 args))
;; FILE DIRECTORY resp FILE1 FILE2.
((member operation
@@ -2512,17 +2581,15 @@ Must be handled by the callers."
(if (bufferp (nth 0 args)) (nth 0 args) (current-buffer))))
;; COMMAND.
((member operation
- '(process-file shell-command start-file-process
- ;; Emacs 26+ only.
- make-nearby-temp-file temporary-file-directory
+ '(make-nearby-temp-file process-file shell-command
+ start-file-process temporary-file-directory
;; Emacs 27+ only.
exec-path make-process))
default-directory)
;; PROC.
((member operation '(file-notify-rm-watch file-notify-valid-p))
(when (processp (nth 0 args))
- (with-current-buffer (process-buffer (nth 0 args))
- default-directory)))
+ (tramp-get-default-directory (process-buffer (nth 0 args)))))
;; VEC.
((member operation '(tramp-get-remote-gid tramp-get-remote-uid))
(tramp-make-tramp-file-name (nth 0 args)))
@@ -2533,11 +2600,21 @@ Must be handled by the callers."
"Return foreign file name handler if exists."
(when (tramp-tramp-file-p filename)
(let ((handler tramp-foreign-file-name-handler-alist)
- elt res)
+ (vec (tramp-dissect-file-name filename))
+ elt func res)
(while handler
(setq elt (car handler)
handler (cdr handler))
- (when (funcall (car elt) filename)
+ ;; Previously, this function was called with FILENAME, but now
+ ;; it's called with the VEC.
+ (when (condition-case nil
+ (funcall (setq func (car elt)) vec)
+ (error
+ (setcar elt #'ignore)
+ (unless (member 'remote-file-error debug-ignored-errors)
+ (tramp-error
+ vec 'remote-file-error
+ "Not a valid Tramp file name function `%s'" func))))
(setq handler nil
res (cdr elt))))
res)))
@@ -2579,7 +2656,7 @@ Fall back to normal file name handler if no Tramp file name handler exists."
;; the bug#9114 for which it was added doesn't
;; clarify the core of the problem.
(let ((default-directory
- (tramp-compat-temporary-file-directory))
+ tramp-compat-temporary-file-directory)
file-name-handler-alist)
(autoload-do-load sf foreign)))
;; (tramp-message
@@ -2736,8 +2813,9 @@ remote file names."
(defun tramp-register-foreign-file-name-handler
(func handler &optional append)
"Register (FUNC . HANDLER) in `tramp-foreign-file-name-handler-alist'.
-FUNC is the function, which determines whether HANDLER is to be called.
-Add operations defined in `HANDLER-alist' to `tramp-file-name-handler'."
+FUNC is the function, which takes a dissected filename and determines
+whether HANDLER is to be called. Add operations defined in
+`HANDLER-alist' to `tramp-file-name-handler'."
(add-to-list
'tramp-foreign-file-name-handler-alist `(,func . ,handler) append)
;; Mark `operations' the handler is responsible for.
@@ -2788,18 +2866,14 @@ Add operations defined in `HANDLER-alist' to `tramp-file-name-handler'."
(defun tramp-command-completion-p (_symbol buffer)
"A predicate for Tramp interactive commands.
They are completed by \"M-x TAB\" only if the current buffer is remote."
- (with-current-buffer buffer (tramp-tramp-file-p default-directory)))
+ (tramp-tramp-file-p (tramp-get-default-directory buffer)))
(defun tramp-connectable-p (vec-or-filename)
"Check, whether it is possible to connect the remote host w/o side-effects.
This is true, if either the remote host is already connected, or if we are
not in completion mode."
(let ((tramp-verbose 0)
- (vec
- (cond
- ((tramp-file-name-p vec-or-filename) vec-or-filename)
- ((tramp-tramp-file-p vec-or-filename)
- (tramp-dissect-file-name vec-or-filename)))))
+ (vec (tramp-ensure-dissected-file-name vec-or-filename)))
(or ;; We check this for the process related to
;; `tramp-buffer-name'; otherwise `start-file-process'
;; wouldn't run ever when `non-essential' is non-nil.
@@ -2814,6 +2888,15 @@ not in completion mode."
"Like `file-name-all-completions' for partial Tramp files."
(let ((fullname
(tramp-drop-volume-letter (expand-file-name filename directory)))
+ ;; When `tramp-syntax' is `simplified', we need a default method.
+ (tramp-default-method
+ (and (zerop (length tramp-postfix-method-format))
+ tramp-default-method))
+ (tramp-default-method-alist
+ (and (zerop (length tramp-postfix-method-format))
+ tramp-default-method-alist))
+ tramp-default-user tramp-default-user-alist
+ tramp-default-host tramp-default-host-alist
hop result result1)
;; Suppress hop from completion.
@@ -2892,7 +2975,7 @@ not in completion mode."
;; I misuse a little bit the `tramp-file-name' structure in order to
;; handle completion possibilities for partial methods / user names /
;; host names. Return value is a list of `tramp-file-name' structures
-;; according to possible completions. If "localname" is non-nil it
+;; according to possible completions. If "localname" is non-nil it
;; means there shouldn't be a completion anymore.
;; Expected results:
@@ -2999,7 +3082,7 @@ remote host and localname (filename on remote host)."
"Return all method completions for PARTIAL-METHOD."
(mapcar
(lambda (method)
- (and method (string-prefix-p partial-method method)
+ (and method (string-prefix-p (or partial-method "") method)
(tramp-completion-make-tramp-file-name method nil nil nil)))
(mapcar #'car tramp-methods)))
@@ -3074,7 +3157,7 @@ User is always nil."
User is always nil."
;; On Windows, there are problems in completion when
;; `default-directory' is remote.
- (let ((default-directory (tramp-compat-temporary-file-directory)))
+ (let ((default-directory tramp-compat-temporary-file-directory))
(when (file-readable-p filename)
(with-temp-buffer
(insert-file-contents-literally filename)
@@ -3128,7 +3211,7 @@ User is always nil."
User is always nil."
;; On Windows, there are problems in completion when
;; `default-directory' is remote.
- (let* ((default-directory (tramp-compat-temporary-file-directory))
+ (let* ((default-directory tramp-compat-temporary-file-directory)
(files (and (file-directory-p dirname) (directory-files dirname))))
(cl-loop
for f in files
@@ -3248,12 +3331,43 @@ User is always nil."
(defvar tramp-handle-write-region-hook nil
"Normal hook to be run at the end of `tramp-*-handle-write-region'.")
+;; `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'.
+(defun tramp-handle-abbreviate-file-name (filename)
+ "Like `abbreviate-file-name' for Tramp files."
+ (let* ((case-fold-search (file-name-case-insensitive-p filename))
+ (vec (tramp-dissect-file-name filename))
+ (home-dir
+ (with-tramp-connection-property vec "home-directory"
+ (tramp-compat-funcall
+ 'directory-abbrev-apply
+ (expand-file-name (tramp-make-tramp-file-name vec "~"))))))
+ ;; If any elt of `directory-abbrev-alist' matches this name,
+ ;; abbreviate accordingly.
+ (setq filename (tramp-compat-funcall 'directory-abbrev-apply filename))
+ ;; Abbreviate home directory.
+ (if (string-match
+ (tramp-compat-funcall 'directory-abbrev-make-regexp home-dir) filename)
+ (tramp-make-tramp-file-name
+ vec (concat "~" (substring filename (match-beginning 1))))
+ filename)))
+
(defun tramp-handle-access-file (filename string)
"Like `access-file' for Tramp files."
- (unless (file-readable-p (file-truename filename))
- (tramp-compat-file-missing
- (tramp-dissect-file-name filename)
- (format "%s: %s" string filename))))
+ (setq filename (file-truename filename))
+ (with-parsed-tramp-file-name filename v
+ (if (file-exists-p filename)
+ (unless
+ (funcall
+ (if (file-directory-p filename)
+ #'file-accessible-directory-p #'file-readable-p)
+ filename)
+ (tramp-error
+ v 'file-error (format "%s: Permission denied, %s" string filename)))
+ (tramp-error
+ v 'file-missing
+ (format "%s: No such file or directory, %s" string filename)))))
(defun tramp-handle-add-name-to-file
(filename newname &optional ok-if-already-exists)
@@ -3272,7 +3386,7 @@ User is always nil."
(and (numberp ok-if-already-exists)
(not (yes-or-no-p
(format
- "File %s already exists; make it a link anyway? "
+ "File %s already exists; make it a link anyway?"
localname)))))
(tramp-error v 'file-already-exists newname)
(delete-file newname)))
@@ -3287,7 +3401,7 @@ User is always nil."
;; `copy-directory' creates NEWNAME before running this check. So
;; we do it ourselves.
(unless (file-exists-p directory)
- (tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
+ (tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
;; We must do it file-wise.
(tramp-run-real-handler
#'copy-directory
@@ -3308,7 +3422,7 @@ User is always nil."
(defun tramp-handle-directory-files (directory &optional full match nosort count)
"Like `directory-files' for Tramp files."
(unless (file-exists-p directory)
- (tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
+ (tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
(when (file-directory-p directory)
(setq directory (file-name-as-directory (expand-file-name directory)))
(let ((temp (nreverse (file-name-all-completions "" directory)))
@@ -3359,13 +3473,16 @@ User is always nil."
;; Do not keep "/..".
(when (string-match-p "^/\\.\\.?$" localname)
(setq localname "/"))
- ;; Do normal `expand-file-name' (this does "/./" and "/../").
+ ;; Do normal `expand-file-name' (this does "/./" and "/../"),
+ ;; unless there are tilde characters in file name.
;; `default-directory' is bound, because on Windows there would
;; be problems with UNC shares or Cygwin mounts.
- (let ((default-directory (tramp-compat-temporary-file-directory)))
+ (let ((default-directory tramp-compat-temporary-file-directory))
(tramp-make-tramp-file-name
- v (tramp-drop-volume-letter
- (tramp-run-real-handler #'expand-file-name (list localname))))))))
+ v (if (string-match-p "\\`~" localname)
+ localname
+ (tramp-drop-volume-letter
+ (tramp-run-real-handler #'expand-file-name (list localname)))))))))
(defun tramp-handle-file-accessible-directory-p (filename)
"Like `file-accessible-directory-p' for Tramp files."
@@ -3374,9 +3491,7 @@ User is always nil."
(defun tramp-handle-file-directory-p (filename)
"Like `file-directory-p' for Tramp files."
- (eq (tramp-compat-file-attribute-type
- (file-attributes (file-truename filename)))
- t))
+ (eq (file-attribute-type (file-attributes (file-truename filename))) t))
(defun tramp-handle-file-equal-p (filename1 filename2)
"Like `file-equalp-p' for Tramp files."
@@ -3408,7 +3523,7 @@ User is always nil."
"Like `file-local-copy' for Tramp files."
(with-parsed-tramp-file-name filename nil
(unless (file-exists-p filename)
- (tramp-compat-file-missing v filename))
+ (tramp-error v 'file-missing filename))
(let ((tmpfile (tramp-compat-make-temp-file filename)))
(copy-file filename tmpfile 'ok-if-already-exists 'keep-time)
tmpfile)))
@@ -3416,7 +3531,7 @@ User is always nil."
(defun tramp-handle-file-modes (filename &optional flag)
"Like `file-modes' for Tramp files."
(when-let ((attrs (file-attributes filename))
- (mode-string (tramp-compat-file-attribute-modes attrs)))
+ (mode-string (file-attribute-modes attrs)))
(if (and (not (eq flag 'nofollow)) (eq ?l (aref mode-string 0)))
(file-modes (file-truename filename))
(tramp-mode-string-to-int mode-string))))
@@ -3447,8 +3562,8 @@ User is always nil."
(or ;; Maybe there is a default value.
(tramp-get-method-parameter v 'tramp-case-insensitive)
- ;; There isn't. So we must check, in case there's a connection already.
- (and (file-remote-p filename nil 'connected)
+ ;; There isn't. So we must check, in case there's a connection already.
+ (and (let ((non-essential t)) (tramp-connectable-p v))
(with-tramp-connection-property v "case-insensitive"
(ignore-errors
(with-tramp-progress-reporter v 5 "Checking case-insensitive"
@@ -3469,16 +3584,13 @@ User is always nil."
(directory-file-name
(file-name-directory candidate))))
;; Nothing found, so we must use a temporary file
- ;; for comparison. `make-nearby-temp-file' is added
- ;; to Emacs 26+ like `file-name-case-insensitive-p',
- ;; so there is no compatibility problem calling it.
+ ;; for comparison.
(unless (string-match-p
"[[:lower:]]" (tramp-file-local-name candidate))
(setq tmpfile
(let ((default-directory
- (file-name-directory filename)))
- (tramp-compat-funcall
- 'make-nearby-temp-file "tramp."))
+ (file-name-directory filename)))
+ (make-nearby-temp-file "tramp."))
candidate tmpfile))
;; Check for the existence of the same file with
;; upper case letters.
@@ -3539,9 +3651,19 @@ User is always nil."
((not (file-exists-p file1)) nil)
((not (file-exists-p file2)) t)
(t (time-less-p
- (tramp-compat-file-attribute-modification-time (file-attributes file2))
- (tramp-compat-file-attribute-modification-time
- (file-attributes file1))))))
+ (file-attribute-modification-time (file-attributes file2))
+ (file-attribute-modification-time (file-attributes file1))))))
+
+(defun tramp-handle-file-readable-p (filename)
+ "Like `file-readable-p' for Tramp files."
+ (with-parsed-tramp-file-name filename nil
+ (with-tramp-file-property v localname "file-readable-p"
+ (or (tramp-check-cached-permissions v ?r)
+ ;; `tramp-check-cached-permissions' doesn't handle symbolic
+ ;; links.
+ (when-let ((symlink (file-symlink-p filename)))
+ (and (stringp symlink)
+ (file-readable-p (concat (file-remote-p filename) symlink))))))))
(defun tramp-handle-file-regular-p (filename)
"Like `file-regular-p' for Tramp files."
@@ -3549,7 +3671,7 @@ User is always nil."
;; Sometimes, `file-attributes' does not return a proper value
;; even if `file-exists-p' does.
(when-let ((attr (file-attributes filename)))
- (eq ?- (aref (tramp-compat-file-attribute-modes attr) 0)))))
+ (eq ?- (aref (file-attribute-modes attr) 0)))))
(defun tramp-handle-file-remote-p (filename &optional identification connected)
"Like `file-remote-p' for Tramp files."
@@ -3581,7 +3703,7 @@ User is always nil."
(defun tramp-handle-file-symlink-p (filename)
"Like `file-symlink-p' for Tramp files."
- (let ((x (tramp-compat-file-attribute-type (file-attributes filename))))
+ (let ((x (file-attribute-type (file-attributes filename))))
(and (stringp x) x)))
(defun tramp-handle-file-truename (filename)
@@ -3670,7 +3792,7 @@ User is always nil."
(when (and (not tramp-allow-unsafe-temporary-files)
(not backup-inhibited)
(file-in-directory-p (car result) temporary-file-directory)
- (zerop (or (tramp-compat-file-attribute-user-id
+ (zerop (or (file-attribute-user-id
(file-attributes filename 'integer))
tramp-unknown-id-integer))
(not (with-tramp-connection-property
@@ -3678,7 +3800,7 @@ User is always nil."
(yes-or-no-p
(concat
"Backup file on local temporary directory, "
- "do you want to continue? ")))))
+ "do you want to continue?")))))
(tramp-error v 'file-error "Unsafe backup file name"))))))
(defun tramp-handle-insert-directory
@@ -3726,7 +3848,8 @@ User is always nil."
(with-parsed-tramp-file-name filename nil
(unwind-protect
(if (not (file-exists-p filename))
- (tramp-compat-file-missing v filename)
+ (let ((tramp-verbose (if visit 0 tramp-verbose)))
+ (tramp-error v 'file-missing filename))
(with-tramp-progress-reporter
v 3 (format-message "Inserting `%s'" filename)
@@ -3828,7 +3951,7 @@ User is always nil."
(delete-file (tramp-make-tramp-file-name v remote-copy 'nohop))))
;; Result.
- (cons (expand-file-name filename) (cdr result)))))
+ (cons filename (cdr result)))))
(defun tramp-get-lock-file (file)
"Read lockfile info of FILE.
@@ -3840,16 +3963,19 @@ Return nil when there is no lockfile."
(insert-file-contents-literally lockname)
(buffer-string))))))
+(defvar tramp-lock-pid nil
+ "A random nunber local for every connection.
+Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.")
+
(defun tramp-get-lock-pid (file)
"Determine pid for lockfile of FILE."
- ;; Some Tramp methods do not offer a connection process, but just a
- ;; network process as a place holder. Those processes use the
- ;; "lock-pid" connection property as fake pid, in fact it is the
- ;; time stamp the process is created.
- (let ((p (tramp-get-process (tramp-dissect-file-name file))))
- (number-to-string
- (or (process-id p)
- (tramp-get-connection-property p "lock-pid" (emacs-pid))))))
+ ;; Not all Tramp methods use an own process. So we use a random
+ ;; number, which is as good as a process id.
+ (with-current-buffer
+ (tramp-get-connection-buffer (tramp-dissect-file-name file))
+ (or tramp-lock-pid
+ (setq-local
+ tramp-lock-pid (number-to-string (random most-positive-fixnum))))))
(defconst tramp-lock-file-info-regexp
;; USER@HOST.PID[:BOOT_TIME]
@@ -3860,9 +3986,11 @@ Return nil when there is no lockfile."
"Like `file-locked-p' for Tramp files."
(when-let ((info (tramp-get-lock-file file))
(match (string-match tramp-lock-file-info-regexp info)))
- (or (and (string-equal (match-string 1 info) (user-login-name))
+ (or ; Locked by me.
+ (and (string-equal (match-string 1 info) (user-login-name))
(string-equal (match-string 2 info) (system-name))
(string-equal (match-string 3 info) (tramp-get-lock-pid file)))
+ ; User name.
(match-string 1 info))))
(defun tramp-handle-lock-file (file)
@@ -3891,7 +4019,7 @@ Return nil when there is no lockfile."
(when (and (not tramp-allow-unsafe-temporary-files)
create-lockfiles
(file-in-directory-p lockname temporary-file-directory)
- (zerop (or (tramp-compat-file-attribute-user-id
+ (zerop (or (file-attribute-user-id
(file-attributes file 'integer))
tramp-unknown-id-integer))
(not (with-tramp-connection-property
@@ -3899,11 +4027,12 @@ Return nil when there is no lockfile."
(yes-or-no-p
(concat
"Lock file on local temporary directory, "
- "do you want to continue? ")))))
+ "do you want to continue?")))))
(tramp-error v 'file-error "Unsafe lock file name")))
;; Do the lock.
- (let (create-lockfiles signal-hook-function)
+ (let ((tramp-verbose 0)
+ create-lockfiles signal-hook-function)
(condition-case nil
(make-symbolic-link info lockname 'ok-if-already-exists)
(error
@@ -3942,7 +4071,7 @@ Return nil when there is no lockfile."
v 'file-error
"File `%s' does not include a `.el' or `.elc' suffix" file)))
(unless (or noerror (file-exists-p file))
- (tramp-compat-file-missing v file))
+ (tramp-error v 'file-missing file))
(if (not (file-exists-p file))
nil
(let ((signal-hook-function (unless noerror signal-hook-function))
@@ -4087,23 +4216,21 @@ substitution. SPEC-LIST is a list of char/value pairs used for
"An alternative `make-process' implementation for Tramp files."
(when args
(with-parsed-tramp-file-name (expand-file-name default-directory) nil
- (let ((default-directory (tramp-compat-temporary-file-directory))
+ (let ((default-directory tramp-compat-temporary-file-directory)
(name (plist-get args :name))
(buffer (plist-get args :buffer))
(command (plist-get args :command))
(coding (plist-get args :coding))
(noquery (plist-get args :noquery))
(connection-type
- (if (plist-member args :connection-type)
- (plist-get args :connection-type)
- tramp-process-connection-type))
+ (or (plist-get args :connection-type) process-connection-type))
(filter (plist-get args :filter))
(sentinel (plist-get args :sentinel))
(stderr (plist-get args :stderr)))
(unless (stringp name)
(signal 'wrong-type-argument (list #'stringp name)))
- (unless (or (null buffer) (bufferp buffer) (stringp buffer))
- (signal 'wrong-type-argument (list #'stringp buffer)))
+ (unless (or (bufferp buffer) (string-or-null-p buffer))
+ (signal 'wrong-type-argument (list #'bufferp buffer)))
(unless (consp command)
(signal 'wrong-type-argument (list #'consp command)))
(unless (or (null coding)
@@ -4112,9 +4239,11 @@ substitution. SPEC-LIST is a list of char/value pairs used for
(memq (car coding) coding-system-list)
(memq (cdr coding) coding-system-list)))
(signal 'wrong-type-argument (list #'symbolp coding)))
- (unless (memq connection-type '(nil pipe t pty))
+ (when (eq connection-type t)
+ (setq connection-type 'pty))
+ (unless (memq connection-type '(nil pipe pty))
(signal 'wrong-type-argument (list #'symbolp connection-type)))
- (unless (or (null filter) (functionp filter))
+ (unless (or (null filter) (eq filter t) (functionp filter))
(signal 'wrong-type-argument (list #'functionp filter)))
(unless (or (null sentinel) (functionp sentinel))
(signal 'wrong-type-argument (list #'functionp sentinel)))
@@ -4193,24 +4322,24 @@ substitution. SPEC-LIST is a list of char/value pairs used for
:name name :buffer buffer
:command (append `(,login-program) login-args command)
:coding coding :noquery noquery :connection-type connection-type
- :filter filter :sentinel sentinel :stderr stderr))
+ :sentinel sentinel :stderr stderr))
+ ;; Set filter. Prior Emacs 29.1, it doesn't work reliable
+ ;; to provide it as `make-process' argument when filter is
+ ;; t. See Bug#51177.
+ (when filter
+ (set-process-filter p filter))
(tramp-message v 6 "%s" (string-join (process-command p) " "))
p))))))
(defun tramp-handle-make-symbolic-link
- (target linkname &optional ok-if-already-exists)
+ (_target linkname &optional _ok-if-already-exists)
"Like `make-symbolic-link' for Tramp files.
This is the fallback implementation for backends which do not
support symbolic links."
- (if (tramp-tramp-file-p (expand-file-name linkname))
- (tramp-error
- (tramp-dissect-file-name (expand-file-name linkname)) 'file-error
- "make-symbolic-link not supported")
- ;; This is needed prior Emacs 26.1, where TARGET has also be
- ;; checked for a file name handler.
- (tramp-run-real-handler
- #'make-symbolic-link (list target linkname ok-if-already-exists))))
+ (tramp-error
+ (tramp-dissect-file-name (expand-file-name linkname)) 'file-error
+ "make-symbolic-link not supported"))
(defun tramp-handle-shell-command (command &optional output-buffer error-buffer)
"Like `shell-command' for Tramp files."
@@ -4258,13 +4387,13 @@ support symbolic links."
((eq async-shell-command-buffer 'confirm-kill-process)
;; If will kill a process, query first.
(if (yes-or-no-p
- "A command is running in the default buffer. Kill it? ")
+ "A command is running in the default buffer. Kill it?")
(kill-process p)
(tramp-user-error p "Shell command in progress")))
((eq async-shell-command-buffer 'confirm-new-buffer)
;; If will create a new buffer, query first.
(if (yes-or-no-p
- "A command is running in the default buffer. Use a new buffer? ")
+ "A command is running in the default buffer. Use a new buffer?")
(setq output-buffer (generate-new-buffer bname))
(tramp-user-error p "Shell command in progress")))
((eq async-shell-command-buffer 'new-buffer)
@@ -4273,7 +4402,7 @@ support symbolic links."
((eq async-shell-command-buffer 'confirm-rename-buffer)
;; If will rename the buffer, query first.
(if (yes-or-no-p
- "A command is running in the default buffer. Rename it? ")
+ "A command is running in the default buffer. Rename it?")
(progn
(with-current-buffer output-buffer
(rename-uniquely))
@@ -4428,7 +4557,7 @@ BUFFER might be a list, in this case STDERR is separated."
(unless time-list
(let ((remote-file-name-inhibit-cache t))
(setq time-list
- (or (tramp-compat-file-attribute-modification-time
+ (or (file-attribute-modification-time
(file-attributes (buffer-file-name)))
tramp-time-doesnt-exist))))
(unless (tramp-compat-time-equal-p time-list tramp-time-dont-know)
@@ -4452,7 +4581,7 @@ of."
t
(let* ((remote-file-name-inhibit-cache t)
(attr (file-attributes f))
- (modtime (tramp-compat-file-attribute-modification-time attr))
+ (modtime (file-attribute-modification-time attr))
(mt (visited-file-modtime)))
(cond
@@ -4476,18 +4605,16 @@ of."
(or (eq mustbenew 'excl)
(not
(y-or-n-p
- (format "File %s exists; overwrite anyway? " filename)))))
+ (format "File %s exists; overwrite anyway?" filename)))))
(tramp-error v 'file-already-exists filename))
(let ((file-locked (eq (file-locked-p lockname) t))
(tmpfile (tramp-compat-make-temp-file filename))
(modes (tramp-default-file-modes
filename (and (eq mustbenew 'excl) 'nofollow)))
- (uid (or (tramp-compat-file-attribute-user-id
- (file-attributes filename 'integer))
+ (uid (or (file-attribute-user-id (file-attributes filename 'integer))
(tramp-get-remote-uid v 'integer)))
- (gid (or (tramp-compat-file-attribute-group-id
- (file-attributes filename 'integer))
+ (gid (or (file-attribute-group-id (file-attributes filename 'integer))
(tramp-get-remote-gid v 'integer))))
;; Lock file.
@@ -4523,8 +4650,7 @@ of."
;; Set file modification time.
(when (or (eq visit t) (stringp visit))
(set-visited-file-modtime
- (or (tramp-compat-file-attribute-modification-time
- (file-attributes filename))
+ (or (file-attribute-modification-time (file-attributes filename))
(current-time))))
;; Set the ownership.
@@ -4537,7 +4663,7 @@ of."
;; The end.
(when (and (null noninteractive)
- (or (eq visit t) (null visit) (stringp visit)))
+ (or (eq visit t) (string-or-null-p visit)))
(tramp-message v 0 "Wrote %s" filename))
(run-hooks 'tramp-handle-write-region-hook))))
@@ -4603,11 +4729,10 @@ of."
(let ((user (or (tramp-file-name-user vec)
(with-tramp-connection-property vec "login-as"
(save-window-excursion
- (let ((enable-recursive-minibuffers t))
- (pop-to-buffer (tramp-get-connection-buffer vec))
- (read-string (match-string 0))))))))
- (with-current-buffer (tramp-get-connection-buffer vec)
- (tramp-message vec 6 "\n%s" (buffer-string)))
+ (pop-to-buffer (tramp-get-connection-buffer vec))
+ (read-string (match-string 0)))))))
+ (tramp-message
+ vec 6 "\n%s" (tramp-get-buffer-string (tramp-get-connection-buffer vec)))
(tramp-message vec 3 "Sending login name `%s'" user)
(tramp-send-string vec (concat user tramp-local-end-of-line)))
t)
@@ -4615,8 +4740,7 @@ of."
(defun tramp-action-password (proc vec)
"Query the user for a password."
(with-current-buffer (process-buffer proc)
- (let ((enable-recursive-minibuffers t)
- (case-fold-search t))
+ (let ((case-fold-search t))
;; Let's check whether a wrong password has been sent already.
;; Sometimes, the process returns a new password request
;; immediately after rejecting the previous (wrong) one.
@@ -4647,14 +4771,13 @@ of."
Send \"yes\" to remote process on confirmation, abort otherwise.
See also `tramp-action-yn'."
(save-window-excursion
- (let ((enable-recursive-minibuffers t))
- (pop-to-buffer (tramp-get-connection-buffer vec))
- (unless (yes-or-no-p (match-string 0))
- (kill-process proc)
- (throw 'tramp-action 'permission-denied))
- (with-current-buffer (tramp-get-connection-buffer vec)
- (tramp-message vec 6 "\n%s" (buffer-string)))
- (tramp-send-string vec (concat "yes" tramp-local-end-of-line))))
+ (pop-to-buffer (tramp-get-connection-buffer vec))
+ (unless (yes-or-no-p (match-string 0))
+ (kill-process proc)
+ (throw 'tramp-action 'permission-denied))
+ (tramp-message
+ vec 6 "\n%s" (tramp-get-buffer-string (tramp-get-connection-buffer vec)))
+ (tramp-send-string vec (concat "yes" tramp-local-end-of-line)))
t)
(defun tramp-action-yn (proc vec)
@@ -4662,29 +4785,28 @@ See also `tramp-action-yn'."
Send \"y\" to remote process on confirmation, abort otherwise.
See also `tramp-action-yesno'."
(save-window-excursion
- (let ((enable-recursive-minibuffers t))
- (pop-to-buffer (tramp-get-connection-buffer vec))
- (unless (y-or-n-p (match-string 0))
- (kill-process proc)
- (throw 'tramp-action 'permission-denied))
- (with-current-buffer (tramp-get-connection-buffer vec)
- (tramp-message vec 6 "\n%s" (buffer-string)))
- (tramp-send-string vec (concat "y" tramp-local-end-of-line))))
+ (pop-to-buffer (tramp-get-connection-buffer vec))
+ (unless (y-or-n-p (match-string 0))
+ (kill-process proc)
+ (throw 'tramp-action 'permission-denied))
+ (tramp-message
+ vec 6 "\n%s" (tramp-get-buffer-string (tramp-get-connection-buffer vec)))
+ (tramp-send-string vec (concat "y" tramp-local-end-of-line)))
t)
(defun tramp-action-terminal (_proc vec)
"Tell the remote host which terminal type to use.
The terminal type can be configured with `tramp-terminal-type'."
(tramp-message vec 5 "Setting `%s' as terminal type." tramp-terminal-type)
- (with-current-buffer (tramp-get-connection-buffer vec)
- (tramp-message vec 6 "\n%s" (buffer-string)))
+ (tramp-message
+ vec 6 "\n%s" (tramp-get-buffer-string (tramp-get-connection-buffer vec)))
(tramp-send-string vec (concat tramp-terminal-type tramp-local-end-of-line))
t)
(defun tramp-action-confirm-message (_proc vec)
"Return RET in order to confirm the message."
- (with-current-buffer (tramp-get-connection-buffer vec)
- (tramp-message vec 6 "\n%s" (buffer-string)))
+ (tramp-message
+ vec 6 "\n%s" (tramp-get-buffer-string (tramp-get-connection-buffer vec)))
(tramp-send-string vec tramp-local-end-of-line)
t)
@@ -4692,16 +4814,23 @@ The terminal type can be configured with `tramp-terminal-type'."
"Show the user a message for confirmation.
Wait, until the connection buffer changes."
(with-current-buffer (process-buffer proc)
- (let ((stimers (with-timeout-suspend)))
+ (let ((stimers (with-timeout-suspend))
+ (cursor-in-echo-area t)
+ set-message-function clear-message-function)
+ ;; Silence byte compiler.
+ (ignore set-message-function clear-message-function)
(tramp-message vec 6 "\n%s" (buffer-string))
- (goto-char (point-min))
(tramp-check-for-regexp proc tramp-process-action-regexp)
(with-temp-message (replace-regexp-in-string "[\r\n]" "" (match-string 0))
- (redisplay 'force)
;; Hide message in buffer.
(narrow-to-region (point-max) (point-max))
;; Wait for new output.
- (tramp-wait-for-regexp proc 30 tramp-security-key-confirmed-regexp))
+ (while (not (tramp-compat-ignore-error 'file-error
+ (tramp-wait-for-regexp
+ proc 0.1 tramp-security-key-confirmed-regexp)))
+ (when (tramp-check-for-regexp proc tramp-security-key-timeout-regexp)
+ (throw 'tramp-action 'timeout))
+ (redisplay 'force)))
;; Reenable the timers.
(with-timeout-unsuspend stimers)))
t)
@@ -4796,7 +4925,8 @@ performed successfully. Any other value means an error."
(save-restriction
(with-tramp-progress-reporter
proc 3 "Waiting for prompts from remote shell"
- (let (exit)
+ (let ((enable-recursive-minibuffers t)
+ exit)
(if timeout
(with-timeout (timeout (setq exit 'timeout))
(while (not exit)
@@ -4964,8 +5094,8 @@ nil."
;; The process could have timed out, for example due to session
;; timeout of sudo. The process buffer does not exist any longer then.
(ignore-errors
- (with-current-buffer (process-buffer proc)
- (tramp-message proc 6 "\n%s" (buffer-string))))
+ (tramp-message
+ proc 6 "\n%s" (tramp-get-buffer-string (process-buffer proc))))
(unless found
(if timeout
(tramp-error
@@ -5187,7 +5317,7 @@ If FILENAME is remote, a file name handler is called."
(let* ((dir (file-name-directory filename))
(modes (file-modes dir)))
(when (and modes (not (zerop (logand modes #o2000))))
- (setq gid (tramp-compat-file-attribute-group-id (file-attributes dir)))))
+ (setq gid (file-attribute-group-id (file-attributes dir)))))
(if-let ((handler (find-file-name-handler filename 'tramp-set-file-uid-gid)))
(funcall handler #'tramp-set-file-uid-gid filename uid gid)
@@ -5216,8 +5346,7 @@ ID-FORMAT valid values are `string' and `integer'."
;; `group-name' has been introduced with Emacs 27.1.
((and (fboundp 'group-name) (equal id-format 'string))
(tramp-compat-funcall 'group-name (group-gid)))
- ((tramp-compat-file-attribute-group-id
- (file-attributes "~/" id-format))))))
+ ((file-attribute-group-id (file-attributes "~/" id-format))))))
(defun tramp-get-local-locale (&optional vec)
"Determine locale, supporting UTF8 if possible.
@@ -5272,31 +5401,22 @@ be granted."
file-attr
(or
;; Not a symlink.
- (eq t (tramp-compat-file-attribute-type file-attr))
- (null (tramp-compat-file-attribute-type file-attr)))
+ (eq t (file-attribute-type file-attr))
+ (null (file-attribute-type file-attr)))
(or
;; World accessible.
- (eq access
- (aref (tramp-compat-file-attribute-modes file-attr)
- (+ offset 6)))
+ (eq access (aref (file-attribute-modes file-attr) (+ offset 6)))
;; User accessible and owned by user.
(and
- (eq access
- (aref (tramp-compat-file-attribute-modes file-attr) offset))
- (or (equal remote-uid
- (tramp-compat-file-attribute-user-id file-attr))
- (equal unknown-id
- (tramp-compat-file-attribute-user-id file-attr))))
+ (eq access (aref (file-attribute-modes file-attr) offset))
+ (or (equal remote-uid (file-attribute-user-id file-attr))
+ (equal unknown-id (file-attribute-user-id file-attr))))
;; Group accessible and owned by user's principal group.
(and
(eq access
- (aref (tramp-compat-file-attribute-modes file-attr)
- (+ offset 3)))
- (or (equal remote-gid
- (tramp-compat-file-attribute-group-id file-attr))
- (equal unknown-id
- (tramp-compat-file-attribute-group-id
- file-attr))))))))))))
+ (aref (file-attribute-modes file-attr) (+ offset 3)))
+ (or (equal remote-gid (file-attribute-group-id file-attr))
+ (equal unknown-id (file-attribute-group-id file-attr))))))))))))
(defun tramp-get-remote-uid (vec id-format)
"The uid of the remote connection VEC, in ID-FORMAT.
@@ -5343,7 +5463,7 @@ This handles also chrooted environments, which are not regarded as local."
;; The local temp directory must be writable for the other user.
(file-writable-p
(tramp-make-tramp-file-name
- vec (tramp-compat-temporary-file-directory) 'nohop))
+ vec tramp-compat-temporary-file-directory 'nohop))
;; On some systems, chown runs only for root.
(or (zerop (user-uid))
(zerop (tramp-get-remote-uid vec 'integer))))))
@@ -5405,7 +5525,8 @@ this file, if that variable is non-nil."
;; Create directory.
(unless (or (null tramp-auto-save-directory)
(file-exists-p tramp-auto-save-directory))
- (make-directory tramp-auto-save-directory t))
+ (with-file-modes #o0700
+ (make-directory tramp-auto-save-directory t)))
(let ((system-type
(if (and (stringp tramp-auto-save-directory)
@@ -5436,7 +5557,7 @@ this file, if that variable is non-nil."
(when (and (not tramp-allow-unsafe-temporary-files)
auto-save-default
(file-in-directory-p result temporary-file-directory)
- (zerop (or (tramp-compat-file-attribute-user-id
+ (zerop (or (file-attribute-user-id
(file-attributes filename 'integer))
tramp-unknown-id-integer))
(not (with-tramp-connection-property
@@ -5444,7 +5565,7 @@ this file, if that variable is non-nil."
(yes-or-no-p
(concat
"Autosave file on local temporary directory, "
- "do you want to continue? ")))))
+ "do you want to continue?")))))
(tramp-error v 'file-error "Unsafe autosave file name"))))))
(defun tramp-subst-strs-in-string (alist string)
@@ -5472,8 +5593,7 @@ ALIST is of the form ((FROM . TO) ...)."
(defun tramp-handle-make-nearby-temp-file (prefix &optional dir-flag suffix)
"Like `make-nearby-temp-file' for Tramp files."
- (let ((temporary-file-directory
- (tramp-compat-temporary-file-directory-function)))
+ (let ((temporary-file-directory (temporary-file-directory)))
(make-temp-file prefix dir-flag suffix)))
;;; Compatibility functions section:
@@ -5484,7 +5604,7 @@ ALIST is of the form ((FROM . TO) ...)."
It always returns a return code. The Lisp error raised when
PROGRAM is nil is trapped also, returning 1. Furthermore, traces
are written with verbosity of 6."
- (let ((default-directory (tramp-compat-temporary-file-directory))
+ (let ((default-directory tramp-compat-temporary-file-directory)
(process-environment (default-toplevel-value 'process-environment))
(destination (if (eq destination t) (current-buffer) destination))
(vec (or vec (car tramp-current-connection)))
@@ -5496,14 +5616,12 @@ are written with verbosity of 6."
(with-temp-buffer
(setq result
(apply
- #'call-process program infile (or destination t) display args))
+ #'call-process program infile (or destination t) display args)
+ output (tramp-get-buffer-string destination))
;; `result' could also be an error string.
(when (stringp result)
(setq error result
- result 1))
- (with-current-buffer
- (if (bufferp destination) destination (current-buffer))
- (setq output (buffer-string))))
+ result 1)))
(error
(setq error (error-message-string err)
result 1)))
@@ -5518,7 +5636,7 @@ are written with verbosity of 6."
It always returns a return code. The Lisp error raised when
PROGRAM is nil is trapped also, returning 1. Furthermore, traces
are written with verbosity of 6."
- (let ((default-directory (tramp-compat-temporary-file-directory))
+ (let ((default-directory tramp-compat-temporary-file-directory)
(process-environment (default-toplevel-value 'process-environment))
(buffer (if (eq buffer t) (current-buffer) buffer))
result)
@@ -5534,10 +5652,10 @@ are written with verbosity of 6."
;; `result' could also be an error string.
(when (stringp result)
(signal 'file-error (list result)))
- (with-current-buffer (if (bufferp buffer) buffer (current-buffer))
- (if (zerop result)
- (tramp-message vec 6 "%d" result)
- (tramp-message vec 6 "%d\n%s" result (buffer-string)))))
+ (if (zerop result)
+ (tramp-message vec 6 "%d" result)
+ (tramp-message
+ vec 6 "%d\n%s" result (tramp-get-buffer-string buffer))))
(error
(setq result 1)
(tramp-message vec 6 "%d\n%s" result (error-message-string err))))
@@ -5548,7 +5666,7 @@ are written with verbosity of 6."
"Call `process-lines' on the local host.
If an error occurs, it returns nil. Traces are written with
verbosity of 6."
- (let ((default-directory (tramp-compat-temporary-file-directory))
+ (let ((default-directory tramp-compat-temporary-file-directory)
(process-environment (default-toplevel-value 'process-environment))
(vec (or vec (car tramp-current-connection)))
result)
@@ -5576,6 +5694,9 @@ verbosity of 6."
(string-prefix-p comm process-name)
(throw 'result t)))))))
+;; When calling "emacs -Q", `auth-source-search' won't be called. If
+;; you want to debug exactly this case, call "emacs -Q --eval '(setq
+;; tramp-cache-read-persistent-data t)'" instead.
(defun tramp-read-passwd (proc &optional prompt)
"Read a password from user (compat function).
Consults the auth-source package.
@@ -5584,7 +5705,7 @@ Invokes `password-read' if available, `read-passwd' else."
;; `exec-path' contains a relative file name like ".", it
;; could happen that the "gpg" command is not found. So we
;; adapt `default-directory'. (Bug#39389, Bug#39489)
- (default-directory (tramp-compat-temporary-file-directory))
+ (default-directory tramp-compat-temporary-file-directory)
(case-fold-search t)
(key (tramp-make-tramp-file-name
;; In tramp-sh.el, we must use "password-vector" due to
@@ -5599,7 +5720,7 @@ Invokes `password-read' if available, `read-passwd' else."
(format "%s for %s " (capitalize (match-string 1)) key))))
(auth-source-creation-prompts `((secret . ,pw-prompt)))
;; Use connection-local value.
- (auth-sources (with-current-buffer (process-buffer proc) auth-sources))
+ (auth-sources (buffer-local-value 'auth-sources (process-buffer proc)))
;; We suspend the timers while reading the password.
(stimers (with-timeout-suspend))
auth-info auth-passwd)
@@ -5640,16 +5761,17 @@ Invokes `password-read' if available, `read-passwd' else."
(setq auth-passwd (funcall auth-passwd)))
auth-passwd)
- ;; Try the password cache. Exists since Emacs 26.1.
+ ;; Try the password cache.
(progn
(setq auth-passwd (password-read pw-prompt key)
tramp-password-save-function
(lambda () (password-cache-add key auth-passwd)))
- auth-passwd)
-
- ;; Else, get the password interactively w/o cache.
- (read-passwd pw-prompt))
+ auth-passwd))
+ ;; Workaround. Prior Emacs 28.1, auth-source has saved
+ ;; empty passwords. See discussion in Bug#50399.
+ (when (zerop (length auth-passwd))
+ (setq tramp-password-save-function nil))
(tramp-set-connection-property v "first-password-request" nil)))
;; Reenable the timers.
@@ -5756,13 +5878,11 @@ name of a process or buffer, or nil to default to the current buffer."
(while (tramp-accept-process-output proc 0))
(not (process-live-p proc))))))
-;; `interrupt-process-functions' exists since Emacs 26.1.
-(when (boundp 'interrupt-process-functions)
- (add-hook 'interrupt-process-functions #'tramp-interrupt-process)
- (add-hook
- 'tramp-unload-hook
- (lambda ()
- (remove-hook 'interrupt-process-functions #'tramp-interrupt-process))))
+(add-hook 'interrupt-process-functions #'tramp-interrupt-process)
+(add-hook
+ 'tramp-unload-hook
+ (lambda ()
+ (remove-hook 'interrupt-process-functions #'tramp-interrupt-process)))
(defun tramp-get-remote-null-device (vec)
"Return null device on the remote host identified by VEC.
@@ -5826,5 +5946,11 @@ BODY is the backend specific code."
;; and friends, for most of the handlers this is the major
;; difference between the different backends. Other handlers but
;; *-process-file would profit from this as well.
+;;
+;; * Implement file name abbreviation for a different user. That is,
+;; (abbreviate-file-name "/ssh:user1@host:/home/user2") =>
+;; "/ssh:user1@host:~user2".
+;;
+;; * Implement file name abbreviation for user and host names.
;;; tramp.el ends here
diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el
index 8ad641ee45b..6dc5da229c1 100644
--- a/lisp/net/trampver.el
+++ b/lisp/net/trampver.el
@@ -7,8 +7,8 @@
;; Maintainer: Michael Albinus <michael.albinus@gmx.de>
;; Keywords: comm, processes
;; Package: tramp
-;; Version: 2.5.2-pre
-;; Package-Requires: ((emacs "25.1"))
+;; Version: 2.6.0-pre
+;; Package-Requires: ((emacs "26.1"))
;; Package-Type: multi
;; URL: https://www.gnu.org/software/tramp/
@@ -29,7 +29,7 @@
;;; Commentary:
-;; Convenience functions around the Tramp version. Partly generated
+;; Convenience functions around the Tramp version. Partly generated
;; during Tramp configuration.
;;; Code:
@@ -40,7 +40,7 @@
;; ./configure" to change them.
;;;###tramp-autoload
-(defconst tramp-version "2.5.2-pre"
+(defconst tramp-version "2.6.0-pre"
"This version of Tramp.")
;;;###tramp-autoload
@@ -74,9 +74,9 @@
"The repository revision of the Tramp sources.")
;; Check for Emacs version.
-(let ((x (if (not (string-lessp emacs-version "25.1"))
+(let ((x (if (not (string-version-lessp emacs-version "26.1"))
"ok"
- (format "Tramp 2.5.2-pre is not fit for %s"
+ (format "Tramp 2.6.0-pre is not fit for %s"
(replace-regexp-in-string "\n" "" (emacs-version))))))
(unless (string-equal "ok" x) (error "%s" x)))
@@ -101,7 +101,8 @@
("2.2.13.25.2" . "25.3")
("2.3.3" . "26.1") ("2.3.3.26.1" . "26.1") ("2.3.5.26.2" . "26.2")
("2.3.5.26.3" . "26.3")
- ("2.4.3.27.1" . "27.1") ("2.4.5.27.2" . "27.2")))
+ ("2.4.3.27.1" . "27.1") ("2.4.5.27.2" . "27.2")
+ ("2.5.2.28.1" . "28.1")))
(add-hook 'tramp-unload-hook
(lambda ()
diff --git a/lisp/net/webjump.el b/lisp/net/webjump.el
index 4baa657c0a5..d14d382aac3 100644
--- a/lisp/net/webjump.el
+++ b/lisp/net/webjump.el
@@ -79,10 +79,10 @@
;; GNU FTP Mirror List from https://www.gnu.org/order/ftp.html
[mirrors "https://ftp.gnu.org/pub/gnu/"
"https://ftpmirror.gnu.org"])
- ("GNU Project Home Page" . "www.gnu.org")
+ ("GNU Project Website" . "www.gnu.org")
;; Emacs.
- ("Emacs Home Page" .
+ ("Emacs Website" .
"www.gnu.org/software/emacs/emacs.html")
("Savannah Emacs page" .
"savannah.gnu.org/projects/emacs")
diff --git a/lisp/net/zeroconf.el b/lisp/net/zeroconf.el
index d5da73bd857..98be0e0158e 100644
--- a/lisp/net/zeroconf.el
+++ b/lisp/net/zeroconf.el
@@ -104,7 +104,7 @@
(require 'dbus)
(defvar zeroconf-debug nil
- "Write messages during service discovery")
+ "Write messages during service discovery.")
(defconst zeroconf-service-avahi "org.freedesktop.Avahi"
"The D-Bus name used to talk to Avahi.")
@@ -375,7 +375,7 @@ type used when registering FUNCTION."
(defun zeroconf-get-service (name type)
"Return the service description of service NAME as list.
NAME must be a string. The service must be of service type
-TYPE. The resulting list has the format
+TYPE. The resulting list has the format
(INTERFACE PROTOCOL NAME TYPE DOMAIN FLAGS)."
;; Due to the service browser, all known services are kept in
@@ -387,7 +387,7 @@ TYPE. The resulting list has the format
(defun zeroconf-resolve-service (service)
"Return all service attributes SERVICE as list.
NAME must be a string. The service must be of service type
-TYPE. The resulting list has the format
+TYPE. The resulting list has the format
(INTERFACE PROTOCOL NAME TYPE DOMAIN HOST APROTOCOL ADDRESS PORT TXT FLAGS)."
(let* ((name (zeroconf-service-name service))
diff --git a/lisp/newcomment.el b/lisp/newcomment.el
index 57a52effd14..52e7f09b693 100644
--- a/lisp/newcomment.el
+++ b/lisp/newcomment.el
@@ -161,11 +161,11 @@ comments always start in column zero.")
(defvar-local comment-combine-change-calls t
"If non-nil (the default), use `combine-change-calls' around
- calls of `comment-region-function' and
- `uncomment-region-function'. This Substitutes a single call to
- each of the hooks `before-change-functions' and
- `after-change-functions' in place of those hooks being called
- for each individual buffer change.")
+calls of `comment-region-function' and
+`uncomment-region-function'. This Substitutes a single call to
+each of the hooks `before-change-functions' and
+`after-change-functions' in place of those hooks being called
+for each individual buffer change.")
(defvar comment-region-function 'comment-region-default
"Function to comment a region.
@@ -932,7 +932,8 @@ This function is the default value of `uncomment-region-function'."
(setq end (copy-marker end))
(let* ((numarg (prefix-numeric-value arg))
(ccs comment-continue)
- (srei (comment-padright ccs 're))
+ (srei (or (comment-padright ccs 're)
+ (and (stringp comment-continue) comment-continue)))
(csre (comment-padright comment-start 're))
(sre (and srei (concat "^\\s-*?\\(" srei "\\)")))
spt)
diff --git a/lisp/notifications.el b/lisp/notifications.el
index ebd74dd3ef2..c1b83dc1555 100644
--- a/lisp/notifications.el
+++ b/lisp/notifications.el
@@ -168,7 +168,7 @@ Various PARAMS can be set:
:sound-file The path to a sound file to play when the notification pops up.
:sound-name A themable named sound from the freedesktop.org sound naming
specification to play when the notification pops up.
- Similar to icon-name,only for sounds. An example would
+ Similar to icon-name, only for sounds. An example would
be \"message-new-instant\".
:suppress-sound Causes the server to suppress playing any sounds, if it has
that ability.
diff --git a/lisp/nxml/nxml-mode.el b/lisp/nxml/nxml-mode.el
index 405f803325c..98ce1d6993e 100644
--- a/lisp/nxml/nxml-mode.el
+++ b/lisp/nxml/nxml-mode.el
@@ -106,9 +106,10 @@ nor UTF-8."
(defcustom nxml-prefer-utf-16-little-to-big-endian-flag (eq system-type
'windows-nt)
"Non-nil means prefer little-endian to big-endian byte-order for UTF-16.
-This is used only for saving a buffer; when reading the byte-order is
-auto-detected. It may be relevant both when there is no encoding declaration
-and when the encoding declaration specifies `UTF-16'."
+This is used only for saving a buffer; when reading the
+byte-order is auto-detected. It may be relevant both when there
+is no encoding declaration and when the encoding declaration
+specifies `UTF-16'."
:group 'nxml
:type 'boolean
:safe #'booleanp)
@@ -392,11 +393,11 @@ reference.")
(define-key map "/" 'nxml-electric-slash)
(define-key map "\M-\t" 'completion-at-point)
map)
- "Keymap for nxml-mode.")
+ "Keymap for `nxml-mode'.")
(defvar nxml-font-lock-keywords
'(nxml-fontify-matcher)
- "Default font lock keywords for nxml-mode.")
+ "Default font lock keywords for `nxml-mode'.")
(defsubst nxml-set-face (start end face)
(when (and face (< start end))
@@ -454,8 +455,9 @@ reference.")
;; because Emacs turns C-c C-i into C-c TAB which is hard to type and
;; not mnemonic.
"Major mode for editing XML.
-
+\\<nxml-mode-map>
\\[nxml-finish-element] finishes the current element by inserting an end-tag.
+
C-c C-i closes a start-tag with `>' and then inserts a balancing end-tag
leaving point between the start-tag and end-tag.
\\[nxml-balanced-close-start-tag-block] is similar but for block rather than inline elements:
@@ -576,7 +578,7 @@ Many aspects this mode can be customized using
string)
(defun nxml-cleanup ()
- "Clean up after nxml-mode."
+ "Clean up after `nxml-mode'."
;; Disable associated minor modes.
(rng-validate-mode -1)
;; Clean up fontification.
@@ -2269,7 +2271,7 @@ ENDP is t in the former case, nil in the latter."
(defun nxml-dynamic-markup-word ()
"Dynamically markup the word before point.
This attempts to find a tag to put around the word before point based
-on the contents of the current buffer. The end-tag will be inserted at
+on the contents of the current buffer. The end-tag will be inserted at
point. The start-tag will be inserted at or before the beginning of
the word before point; the contents of the current buffer is used to
decide where.
diff --git a/lisp/nxml/nxml-ns.el b/lisp/nxml/nxml-ns.el
index e33140c0a48..93ffb215fb7 100644
--- a/lisp/nxml/nxml-ns.el
+++ b/lisp/nxml/nxml-ns.el
@@ -95,7 +95,7 @@ Return nil if there is no default namespace."
(caar nxml-ns-state))
(defun nxml-ns-set-default (ns)
- "Changes the current default namespace.
+ "Change the current default namespace.
The change will be in effect until the end of the current element.
NS is a symbol or nil."
(setq nxml-ns-state
diff --git a/lisp/nxml/nxml-outln.el b/lisp/nxml/nxml-outln.el
index c265b19cf05..681b297b489 100644
--- a/lisp/nxml/nxml-outln.el
+++ b/lisp/nxml/nxml-outln.el
@@ -40,7 +40,7 @@
;; For state 3 it is t.
;; The special display is achieved by using overlays. The overlays
;; are computed from the nxml-outline-state property by
-;; `nxml-refresh-outline'. There overlays all have a category property
+;; `nxml-refresh-outline'. There overlays all have a category property
;; with an nxml-outline-display property with value t.
;;
;; For a section to be recognized as such, the following conditions must
@@ -445,7 +445,7 @@ non-transparent child section."
(cond ((not (nxml-section-tag-forward))
(if (null tag-qnames)
nil
- (nxml-outline-error "missing end-tag %s"
+ (nxml-outline-error "Missing end-tag %s"
(car tag-qnames))))
;; section end-tag
((nxml-token-end-tag-p)
@@ -455,9 +455,9 @@ non-transparent child section."
xmltok-start))
(let ((qname (xmltok-end-tag-qname)))
(unless tag-qnames
- (nxml-outline-error "extra end-tag %s" qname))
+ (nxml-outline-error "Extra end-tag %s" qname))
(unless (string= (car tag-qnames) qname)
- (nxml-outline-error "mismatched end-tag; expected %s, got %s"
+ (nxml-outline-error "Mismatched end-tag; expected %s, got %s"
(car tag-qnames)
qname)))
(cond ((> transparent-depth 0)
@@ -938,7 +938,7 @@ If unbalanced section tags are found, signal an `nxml-outline-error'."
(setq found t))
(let ((qname (xmltok-start-tag-qname)))
(unless (string= (car open-tags) qname)
- (nxml-outline-error "mismatched end-tag"))
+ (nxml-outline-error "Mismatched end-tag"))
(setq open-tags (cdr open-tags)))))
(goto-char section-start-pos)
(and (not found)
diff --git a/lisp/nxml/nxml-rap.el b/lisp/nxml/nxml-rap.el
index 6f742746e9e..fa127da8749 100644
--- a/lisp/nxml/nxml-rap.el
+++ b/lisp/nxml/nxml-rap.el
@@ -22,14 +22,14 @@
;;; Commentary:
-;; This uses xmltok.el to do XML parsing. The fundamental problem is
-;; how to handle changes. We don't want to maintain a complete parse
+;; This uses xmltok.el to do XML parsing. The fundamental problem is
+;; how to handle changes. We don't want to maintain a complete parse
;; tree. We also don't want to reparse from the start of the document
;; on every keystroke. However, it is not possible in general to
;; parse an XML document correctly starting at a random point in the
;; middle. The main problems are comments, CDATA sections and
;; processing instructions: these can all contain things that are
-;; indistinguishable from elements. Literals in the prolog are also a
+;; indistinguishable from elements. Literals in the prolog are also a
;; problem. Attribute value literals are not a problem because
;; attribute value literals cannot contain less-than signs.
;;
@@ -47,14 +47,14 @@
;; we have found.
;;
;; The prolog has to be parsed specially, so we also keep track of the
-;; end of the prolog in `nxml-prolog-end'. The prolog is reparsed on
+;; end of the prolog in `nxml-prolog-end'. The prolog is reparsed on
;; every change to the prolog. This won't work well if people try to
-;; edit huge internal subsets. Hopefully that will be rare.
+;; edit huge internal subsets. Hopefully that will be rare.
;;
;; We rely on the `syntax-propertize-function' machinery to keep track
;; of the changes in the buffer. Fontification also relies on correct
;; `syntax-table' properties. This means that scanning for these
-;; constructs had better be quick. Fortunately it is. Firstly, the
+;; constructs had better be quick. Fortunately it is. Firstly, the
;; typical proportion of comments, CDATA sections and processing
;; instructions is small relative to other things. Secondly, to scan
;; we just search for the regexp <[!?].
@@ -191,7 +191,7 @@ Leave point unmoved if it is not inside anything special."
(defun nxml-scan-element-forward (from &optional up)
"Scan forward from FROM over a single balanced element.
Point must be between tokens. Return the position of the end of
-the tag that ends the element. `xmltok-start' will contain the
+the tag that ends the element. `xmltok-start' will contain the
position of the start of the tag. If UP is non-nil, then scan
past end-tag of element containing point. If no element is
found, return nil. If a well-formedness error prevents scanning,
@@ -242,7 +242,7 @@ expected `%s'"
(defun nxml-scan-element-backward (from &optional up bound)
"Scan backward from FROM over a single balanced element.
Point must be between tokens. Return the position of the end of
-the tag that starts the element. `xmltok-start' will contain the
+the tag that starts the element. `xmltok-start' will contain the
position of the start of the tag. If UP is non-nil, then scan
past start-tag of element containing point. If BOUND is non-nil,
then don't scan back past BOUND. If no element is found, return
diff --git a/lisp/nxml/rng-cmpct.el b/lisp/nxml/rng-cmpct.el
index dd3000773fd..1476aa0e5a3 100644
--- a/lisp/nxml/rng-cmpct.el
+++ b/lisp/nxml/rng-cmpct.el
@@ -369,7 +369,7 @@ OVERRIDE is either nil, require or t."
(while (re-search-forward "\\\\x+{\\([[:xdigit:]]+\\)}"
(point-max)
t)
- (let* ((ch (decode-char 'ucs (string-to-number (match-string 1) 16))))
+ (let* ((ch (string-to-number (match-string 1) 16)))
(if (and ch (> ch 0))
(let ((begin (match-beginning 0))
(end (match-end 0)))
diff --git a/lisp/nxml/rng-loc.el b/lisp/nxml/rng-loc.el
index a38da794226..c8b19e8c229 100644
--- a/lisp/nxml/rng-loc.el
+++ b/lisp/nxml/rng-loc.el
@@ -501,7 +501,7 @@ saved to the first writable file in `rng-schema-locating-files'."
nil
(error "Buffer does not have a filename")))
((and prompt
- (not (y-or-n-p (format "Save %s to %s "
+ (not (y-or-n-p (format "Save %s to %s?"
(if type-id
"type identifier"
"schema location")
@@ -539,7 +539,7 @@ saved to the first writable file in `rng-schema-locating-files'."
locating-file-uri))))))
(indent-according-to-mode)
(when (or (not modified)
- (y-or-n-p (format "Save file %s "
+ (y-or-n-p (format "Save file %s?"
(buffer-file-name))))
(save-buffer))))))))
diff --git a/lisp/nxml/rng-nxml.el b/lisp/nxml/rng-nxml.el
index d70a346159a..35faae3062c 100644
--- a/lisp/nxml/rng-nxml.el
+++ b/lisp/nxml/rng-nxml.el
@@ -35,7 +35,7 @@
(require 'sgml-mode)
(defcustom rng-nxml-auto-validate-flag t
- "Non-nil means automatically turn on validation with nxml-mode."
+ "Non-nil means automatically turn on validation with `nxml-mode'."
:type 'boolean
:group 'relax-ng)
diff --git a/lisp/nxml/rng-valid.el b/lisp/nxml/rng-valid.el
index a5eb893c554..9df20a16b1d 100644
--- a/lisp/nxml/rng-valid.el
+++ b/lisp/nxml/rng-valid.el
@@ -25,15 +25,15 @@
;; For usage information, see the documentation for rng-validate-mode.
;;
;; This file provides a minor mode that continually validates a buffer
-;; against a RELAX NG schema. The validation state is used to support
-;; schema-sensitive editing as well as validation. Validation is
+;; against a RELAX NG schema. The validation state is used to support
+;; schema-sensitive editing as well as validation. Validation is
;; performed while Emacs is idle. XML parsing is done using
-;; xmltok.el. This file is responsible for checking that end-tags
+;; xmltok.el. This file is responsible for checking that end-tags
;; match their start-tags. Namespace processing is handled by
-;; nxml-ns.el. The RELAX NG Compact Syntax schema is parsed into
+;; nxml-ns.el. The RELAX NG Compact Syntax schema is parsed into
;; internal form by rng-cmpct.el. This internal form is described by
;; rng-pttrn.el. Validation of the document by matching against this
-;; internal form is done by rng-match.el. Handling of W3C XML Schema
+;; internal form is done by rng-match.el. Handling of W3C XML Schema
;; datatypes is delegated by rng-match.el to rng-xsd.el. The minor
;; mode is intended to be used in conjunction with the nxml major
;; mode, but does not have to be.
@@ -44,11 +44,11 @@
;; parse and validate it from start to end. As we parse and validate
;; the buffer, we periodically cache the state. The state has three
;; components: the stack of open elements, the namespace processing
-;; state and the RELAX NG validation state. The state is cached as the
+;; state and the RELAX NG validation state. The state is cached as the
;; value of the rng-state text property on the closing greater-than of
;; tags (but at intervals, not on every tag). We keep track of the
;; position up to which cached state is known to be correct by adding
-;; a function to the buffer's after-change-functions. This is stored
+;; a function to the buffer's after-change-functions. This is stored
;; in the rng-validate-up-to-date-end variable. The first way in
;; which we make validation incremental is obvious: we start
;; validation from the first cached state before
@@ -59,7 +59,7 @@
;; minimizing destructive changes to the objects storing the state.
;; When state is changed, we use the old state to create new objects
;; representing the new state rather than destructively modifying the
-;; objects representing the old state. Copying the state is just a
+;; objects representing the old state. Copying the state is just a
;; matter of making a list of three objects, one for each component of
;; the state; the three objects themselves can be shared and do not
;; need to be copied.
@@ -261,7 +261,7 @@ to use for finding the schema."
(remove-hook 'after-change-functions #'rng-after-change-function t))))
(defun rng-set-schema-file-and-validate (filename)
- "Sets the schema and turns on `rng-validate-mode' if not already on.
+ "Set the schema and turn on `rng-validate-mode' if not already on.
The schema is set like `rng-set-schema'."
(interactive "fSchema file: ")
(rng-set-schema-file filename)
@@ -962,9 +962,8 @@ Return nil at end of buffer, t otherwise."
(and type t)))
(defun rng-process-start-tag (tag-type)
- "TAG-TYPE is `start-tag' for a start-tag, `empty-element' for
-an empty element. `partial-empty-element' should be passed
-as empty-element."
+ "TAG-TYPE is `start-tag' for a start-tag, `empty-element' for an empty element.
+`partial-empty-element' should be passed as empty-element."
(and rng-collecting-text (rng-flush-text))
(setq rng-collecting-text nil)
(setq rng-pending-contents nil)
diff --git a/lisp/nxml/rng-xsd.el b/lisp/nxml/rng-xsd.el
index 9941aba6eb1..e4c76b220ae 100644
--- a/lisp/nxml/rng-xsd.el
+++ b/lisp/nxml/rng-xsd.el
@@ -22,7 +22,7 @@
;;; Commentary:
-;; The main entry point is `rng-xsd-compile'. The validator
+;; The main entry point is `rng-xsd-compile'. The validator
;; knows to use this for the datatype library with URI
;; https://www.w3.org/2001/XMLSchema-datatypes because it
;; is the value of the rng-dt-compile property on that URI
diff --git a/lisp/nxml/xmltok.el b/lisp/nxml/xmltok.el
index 38bc2e141e6..ecad501a644 100644
--- a/lisp/nxml/xmltok.el
+++ b/lisp/nxml/xmltok.el
@@ -22,13 +22,13 @@
;;; Commentary:
-;; This implements an XML 1.0 parser. It also implements the XML
+;; This implements an XML 1.0 parser. It also implements the XML
;; Namespaces Recommendation. It is designed to be conforming, but it
-;; works a bit differently from a normal XML parser. An XML document
+;; works a bit differently from a normal XML parser. An XML document
;; consists of the prolog and an instance. The prolog is parsed as a
;; single unit using `xmltok-forward-prolog'. The instance is
;; considered as a sequence of tokens, where a token is something like
-;; a start-tag, a comment, a chunk of data or a CDATA section. The
+;; a start-tag, a comment, a chunk of data or a CDATA section. The
;; tokenization of the instance is stateless: the tokenization of one
;; part of the instance does not depend on tokenization of the
;; preceding part of the instance. This allows the instance to be
@@ -70,7 +70,7 @@
;; value literals specifying default attribute values, and default
;; attribute values are not reported to the client.
;;
-;; 2. It does not implement internal entities containing elements. If
+;; 2. It does not implement internal entities containing elements. If
;; an internal entity is referenced and parsing its replacement text
;; yields one or more tags, then it will skip the reference and
;; report this to the client.
@@ -943,7 +943,6 @@ and VALUE-END, otherwise a STRING giving the value."
(let ((n (string-to-number (buffer-substring-no-properties start end)
base)))
(cond ((and (integerp n) (xmltok-valid-char-p n))
- (setq n (xmltok-unicode-to-char n))
(and n (string n)))
(t
(xmltok-add-error "Invalid character code" start end)
@@ -971,11 +970,6 @@ and VALUE-END, otherwise a STRING giving the value."
(t (and (> n #xFFFF)
(< n #x110000)))))
-(defun xmltok-unicode-to-char (n)
- "Return the character corresponding to Unicode scalar value N.
-Return nil if unsupported in Emacs."
- (decode-char 'ucs n))
-
;;; Prolog parsing
(defvar xmltok-contains-doctype nil)
@@ -1766,6 +1760,10 @@ and `xmltok-namespace-attributes'."
xmltok-type))
(message "Scanned end of file")))
+;;; Obsolete
+
+(define-obsolete-function-alias 'xmltok-unicode-to-char #'identity "29.1")
+
(provide 'xmltok)
;;; xmltok.el ends here
diff --git a/lisp/nxml/xsd-regexp.el b/lisp/nxml/xsd-regexp.el
index f07ca6657ed..d6eaf7cc4bc 100644
--- a/lisp/nxml/xsd-regexp.el
+++ b/lisp/nxml/xsd-regexp.el
@@ -52,9 +52,6 @@
;; or a character translatable to such a character (i.e a character
;; for which `encode-char' will return non-nil).
;;
-;; Using unify-8859-on-decoding-mode is probably a good idea here
-;; (and generally with XML and other Unicode-oriented formats).
-;;
;; Unfortunately, this means that this package is currently useless
;; for CJK characters, since there's no mule-unicode charset for the
;; CJK ranges of Unicode. We should devise a workaround for this
@@ -290,7 +287,7 @@ and whose tail is ACCUM."
(defun xsdre-compile-single-char (ch)
(if (memq ch '(?. ?* ?+ ?? ?\[ ?\] ?^ ?$ ?\\))
(string ?\\ ch)
- (string (decode-char 'ucs ch))))
+ (string ch)))
(defun xsdre-char-class-to-range-list (cc)
"Return a range-list for a symbolic char-class CC."
@@ -407,10 +404,6 @@ consisting of a single char alternative delimited with []."
(cons last chars)
(cons last (cons ?- chars))))))
(setq range-list (cdr range-list)))
- (setq chars
- (mapcar (lambda (c)
- (decode-char 'ucs c))
- chars))
(when caret
(setq chars (cons ?^ chars)))
(when hyphen
diff --git a/lisp/obsolete/cc-compat.el b/lisp/obsolete/cc-compat.el
index 037a8e9e87c..2c383d31c84 100644
--- a/lisp/obsolete/cc-compat.el
+++ b/lisp/obsolete/cc-compat.el
@@ -80,7 +80,7 @@ This is in addition to c-continued-statement-offset.")
;; these offsets are taken by brute force testing c-mode.el, since
;; there's no logic to what it does.
-(let* ((offsets '(c-offsets-alist .
+(let* ((offsets '((c-offsets-alist .
((defun-block-intro . cc-block-intro-offset)
(statement-block-intro . cc-block-intro-offset)
(defun-open . 0)
@@ -95,7 +95,7 @@ This is in addition to c-continued-statement-offset.")
(case-label . c-label-offset)
(access-label . c-label-offset)
(label . c-label-offset)
- ))))
+ )))))
(c-add-style "BOCM" offsets))
diff --git a/lisp/obsolete/cl-compat.el b/lisp/obsolete/cl-compat.el
index 619bc06122b..0dba366192e 100644
--- a/lisp/obsolete/cl-compat.el
+++ b/lisp/obsolete/cl-compat.el
@@ -52,6 +52,7 @@
;;; Keyword routines not supported by new package.
(defmacro defkeyword (x &optional doc)
+ (declare (indent defun))
(cl-list* 'defconst x (list 'quote x) (and doc (list doc))))
(defun keyword-of (sym)
diff --git a/lisp/obsolete/cl.el b/lisp/obsolete/cl.el
index 9df62318572..a892ed7c76b 100644
--- a/lisp/obsolete/cl.el
+++ b/lisp/obsolete/cl.el
@@ -513,7 +513,8 @@ a temporary-variables list, a value-forms list, a store-variables list
See `gv-define-expander', and `gv-define-setter' for better and
simpler ways to define setf-methods."
(declare (debug
- (&define name cl-lambda-list cl-declarations-or-string def-body)))
+ (&define name cl-lambda-list cl-declarations-or-string def-body))
+ (indent defun))
`(progn
,@(if (stringp (car body))
(list `(put ',name 'setf-documentation ,(pop body))))
@@ -554,7 +555,8 @@ You can replace this form with `gv-define-setter'.
(&define name
[&or [symbolp &optional stringp]
[cl-lambda-list (symbolp)]]
- cl-declarations-or-string def-body)))
+ cl-declarations-or-string def-body))
+ (indent defun))
(if (and (listp arg1) (consp args))
;; Like `gv-define-setter' but with `cl-function'.
`(gv-define-expander ,name
@@ -615,7 +617,8 @@ arguments from ARGLIST using FUNC. For example:
You can replace this macro with `gv-letplace'."
(declare (debug
(&define name cl-lambda-list ;; should exclude &key
- symbolp &optional stringp)))
+ symbolp &optional stringp))
+ (indent defun))
(if (memq '&key arglist)
(error "&key not allowed in define-modify-macro"))
(require 'cl-macs) ;For cl--arglist-args.
diff --git a/lisp/obsolete/crisp.el b/lisp/obsolete/crisp.el
index 69bf3ed12bc..ccf9aaa2b6a 100644
--- a/lisp/obsolete/crisp.el
+++ b/lisp/obsolete/crisp.el
@@ -231,27 +231,13 @@ does not load the scroll-all package."
;; The cut and paste routines are different between XEmacs and Emacs
;; so we need to set up aliases for the functions.
-
-(defalias 'crisp-set-clipboard
- (if (fboundp 'clipboard-kill-ring-save)
- 'clipboard-kill-ring-save
- 'copy-primary-selection))
-
-(defalias 'crisp-kill-region
- (if (fboundp 'clipboard-kill-region)
- 'clipboard-kill-region
- 'kill-primary-selection))
-
-(defalias 'crisp-yank-clipboard
- (if (fboundp 'clipboard-yank)
- 'clipboard-yank
- 'yank-clipboard-selection))
+(defalias 'crisp-set-clipboard 'clipboard-kill-ring-save)
+(defalias 'crisp-kill-region 'clipboard-kill-region)
+(defalias 'crisp-yank-clipboard 'clipboard-yank)
(defun crisp-region-active ()
"Compatibility function to test for an active region."
- (if (featurep 'xemacs)
- zmacs-region-active-p
- mark-active))
+ mark-active)
(defun crisp-version (&optional arg)
"Version number of the CRiSP emulator package.
diff --git a/lisp/obsolete/cust-print.el b/lisp/obsolete/cust-print.el
index 01fcd38199c..897b4015889 100644
--- a/lisp/obsolete/cust-print.el
+++ b/lisp/obsolete/cust-print.el
@@ -643,11 +643,11 @@ See `custom-format' for the details."
(let ((print-circle t))
(or (equal (prin1-to-string circ-list) "#1=(a b [1 2 #1# 4] #1# e f)")
- (error "circular object with array printing")))
+ (error "Circular object with array printing")))
(let ((print-circle t))
(or (equal (prin1-to-string dotted-circ-list) "#1=(a b c . #1#)")
- (error "circular object with array printing")))
+ (error "Circular object with array printing")))
(let* ((print-circle t)
(x (list 'p 'q))
@@ -655,16 +655,16 @@ See `custom-format' for the details."
(setcdr (cdr (cdr (cdr y))) (cdr y))
(or (equal (prin1-to-string y) "((a b) . #1=(#2=(p q) foo #2# . #1#))"
)
- (error "circular list example from CL manual")))
+ (error "Circular list example from CL manual")))
(let ((print-circle nil))
;; cl-packages.el is required to print uninterned symbols like #:FOO.
;; (require 'cl-packages)
(or (equal (prin1-to-string circ-sym) "(#:FOO #:FOO)")
- (error "uninterned symbols in list")))
+ (error "Uninterned symbols in list")))
(let ((print-circle t))
(or (equal (prin1-to-string circ-sym) "(#1=FOO #1#)")
- (error "circular uninterned symbols in list")))
+ (error "Circular uninterned symbols in list")))
(uninstall-custom-print)
)
diff --git a/lisp/obsolete/eieio-compat.el b/lisp/obsolete/eieio-compat.el
new file mode 100644
index 00000000000..60b0638c63f
--- /dev/null
+++ b/lisp/obsolete/eieio-compat.el
@@ -0,0 +1,277 @@
+;;; eieio-compat.el --- Compatibility with Older EIEIO versions -*- lexical-binding:t -*-
+
+;; Copyright (C) 1995-1996, 1998-2021 Free Software Foundation, Inc.
+
+;; Author: Eric M. Ludlam <zappo@gnu.org>
+;; Keywords: OO, lisp
+;; Package: eieio
+
+;; 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:
+
+;; Backward compatibility definition of old EIEIO functions in
+;; terms of newer equivalent.
+
+;; The main elements are the old EIEIO `defmethod' and `defgeneric' which are
+;; now implemented on top of cl-generic. The differences we have to
+;; accommodate are:
+;; - EIEIO's :static methods (turned into a new `eieio--static' specializer).
+;; - EIEIO's support for `call-next-method' and `next-method-p' instead of
+;; `cl-next-method-p' and `cl-call-next-method' (simple matter of renaming).
+;; - Different errors are signaled.
+;; - EIEIO's defgeneric does not reset the function.
+;; - EIEIO's no-next-method and no-applicable-method can't be aliases of
+;; cl-generic's namesakes since they have different calling conventions,
+;; which means that packages that (defmethod no-next-method ..) don't work.
+;; - EIEIO's `call-next-method' and `next-method-p' had dynamic scope whereas
+;; cl-generic's `cl-next-method-p' and `cl-call-next-method' are lexically
+;; scoped.
+
+;;; Code:
+
+(require 'eieio-core)
+(require 'cl-generic)
+
+(put 'eieio--defalias 'byte-hunk-handler
+ #'byte-compile-file-form-defalias) ;;(get 'defalias 'byte-hunk-handler)
+;;;###autoload
+(defun eieio--defalias (name body)
+ "Like `defalias', but with less side-effects.
+More specifically, it has no side-effects at all when the new function
+definition is the same (`eq') as the old one."
+ (cl-assert (not (symbolp body)))
+ (while (and (fboundp name) (symbolp (symbol-function name)))
+ ;; Follow aliases, so methods applied to obsolete aliases still work.
+ (setq name (symbol-function name)))
+ (unless (and (fboundp name)
+ (eq (symbol-function name) body))
+ (defalias name body)))
+
+;;;###autoload
+(defmacro defgeneric (method args &optional doc-string)
+ "Create a generic function METHOD.
+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. Uses `defmethod' to create methods, and calls
+`defgeneric' for you. With this implementation the ARGS are
+currently ignored. You can use `defgeneric' to apply specialized
+top level documentation to a method."
+ (declare (doc-string 3) (obsolete cl-defgeneric "25.1")
+ (indent defun))
+ `(eieio--defalias ',method
+ (eieio--defgeneric-init-form
+ ',method
+ ,(if doc-string (help-add-fundoc-usage doc-string args)))))
+
+;;;###autoload
+(defmacro defmethod (method &rest args)
+ "Create a new METHOD through `defgeneric' with ARGS.
+
+The optional second argument KEY is a specifier that
+modifies how the method is called, including:
+ :before - Method will be called before the :primary
+ :primary - The default if not specified
+ :after - Method will be called after the :primary
+ :static - First arg could be an object or class
+The next argument is the ARGLIST. The ARGLIST specifies the arguments
+to the method as with `defun'. The first argument can have a type
+specifier, such as:
+ ((VARNAME CLASS) ARG2 ...)
+where VARNAME is the name of the local variable for the method being
+created. The CLASS is a class symbol for a class made with `defclass'.
+A DOCSTRING comes after the ARGLIST, and is optional.
+All the rest of the args are the BODY of the method. A method will
+return the value of the last form in the BODY.
+
+Summary:
+
+ (defmethod mymethod [:before | :primary | :after | :static]
+ ((typearg class-name) arg2 &optional opt &rest rest)
+ \"doc-string\"
+ body)"
+ (declare (doc-string 3) (obsolete cl-defmethod "25.1")
+ (indent defun)
+ (debug
+ (&define ; this means we are defining something
+ [&name sexp] ;Allow (setf ...) additionally to symbols.
+ ;; ^^ This is the methods symbol
+ [ &optional symbolp ] ; this is key :before etc
+ cl-generic-method-args ; arguments
+ [ &optional stringp ] ; documentation string
+ def-body ; part to be debugged
+ )))
+ (let* ((key (if (keywordp (car args)) (pop args)))
+ (params (car args))
+ (arg1 (car params))
+ (fargs (if (consp arg1)
+ (cons (car arg1) (cdr params))
+ params))
+ (class (if (consp arg1) (nth 1 arg1)))
+ (code `(lambda ,fargs ,@(cdr args))))
+ `(progn
+ ;; Make sure there is a generic and the byte-compiler sees it.
+ (defgeneric ,method ,args)
+ (eieio--defmethod ',method ',key ',class #',code))))
+
+(defun eieio--generic-static-symbol-specializers (tag &rest _)
+ (cl-assert (or (null tag) (eieio--class-p tag)))
+ (when (eieio--class-p tag)
+ (let ((superclasses (eieio--generic-subclass-specializers tag))
+ (specializers ()))
+ (dolist (superclass superclasses)
+ (push superclass specializers)
+ (push `(eieio--static ,(cadr superclass)) specializers))
+ (nreverse specializers))))
+
+(cl-generic-define-generalizer eieio--generic-static-symbol-generalizer
+ ;; Give it a slightly higher priority than `subclass' so that the
+ ;; interleaved list comes before subclass's non-interleaved list.
+ 61 (lambda (name &rest _) `(and (symbolp ,name) (cl--find-class ,name)))
+ #'eieio--generic-static-symbol-specializers)
+(cl-generic-define-generalizer eieio--generic-static-object-generalizer
+ ;; Give it a slightly higher priority than `class' so that the
+ ;; interleaved list comes before the class's non-interleaved list.
+ 51 #'cl--generic-struct-tag
+ (lambda (tag &rest _)
+ (and (symbolp tag) (setq tag (cl--find-class tag))
+ (eieio--class-p tag)
+ (let ((superclasses (eieio--class-precedence-list tag))
+ (specializers ()))
+ (dolist (superclass superclasses)
+ (setq superclass (eieio--class-name superclass))
+ (push superclass specializers)
+ (push `(eieio--static ,superclass) specializers))
+ (nreverse specializers)))))
+
+(cl-defmethod cl-generic-generalizers ((_specializer (head eieio--static)))
+ (list eieio--generic-static-symbol-generalizer
+ eieio--generic-static-object-generalizer))
+
+;;;###autoload
+(defun eieio--defgeneric-init-form (method doc-string)
+ (if doc-string (put method 'function-documentation doc-string))
+ (if (memq method '(no-next-method no-applicable-method))
+ (symbol-function method)
+ (let ((generic (cl-generic-ensure-function method)))
+ (or (symbol-function (cl--generic-name generic))
+ (cl--generic-make-function generic)))))
+
+;;;###autoload
+(defun eieio--defmethod (method kind argclass code)
+ (setq kind (intern (downcase (symbol-name kind))))
+ (let* ((specializer (if (not (eq kind :static))
+ (or argclass t)
+ (setq kind nil)
+ `(eieio--static ,argclass)))
+ (uses-cnm (not (memq kind '(:before :after))))
+ (specializers `((arg ,specializer)))
+ (code
+ ;; Backward compatibility for `no-next-method' and
+ ;; `no-applicable-method', which have slightly different calling
+ ;; convention than their cl-generic counterpart.
+ (pcase method
+ ('no-next-method
+ (setq method 'cl-no-next-method)
+ (setq specializers `(generic method ,@specializers))
+ (lambda (_generic _method &rest args) (apply code args)))
+ ('no-applicable-method
+ (setq method 'cl-no-applicable-method)
+ (setq specializers `(generic ,@specializers))
+ (lambda (generic arg &rest args)
+ (apply code arg (cl--generic-name generic) (cons arg args))))
+ (_ code))))
+ (cl-generic-define-method
+ method (unless (memq kind '(nil :primary)) (list kind))
+ specializers uses-cnm
+ (if uses-cnm
+ (let* ((docstring (documentation code 'raw))
+ (args (help-function-arglist code 'preserve-names))
+ (doc-only (if docstring
+ (let ((split (help-split-fundoc docstring nil)))
+ (if split (cdr split) docstring)))))
+ (lambda (cnm &rest args)
+ (:documentation
+ (help-add-fundoc-usage doc-only (cons 'cl-cnm args)))
+ (cl-letf (((symbol-function 'call-next-method) cnm)
+ ((symbol-function 'next-method-p)
+ (lambda () (cl--generic-isnot-nnm-p cnm))))
+ (apply code args))))
+ code))
+ ;; The old EIEIO code did not signal an error when there are methods
+ ;; applicable but only of the before/after kind. So if we add a :before
+ ;; or :after, make sure there's a matching dummy primary.
+ (when (and (memq kind '(:before :after))
+ ;; FIXME: Use `cl-find-method'?
+ (not (cl-find-method method ()
+ (mapcar (lambda (arg)
+ (if (consp arg) (nth 1 arg) t))
+ specializers))))
+ (cl-generic-define-method method () specializers t
+ (lambda (cnm &rest args)
+ (if (cl--generic-isnot-nnm-p cnm)
+ (apply cnm args)))))
+ method))
+
+;; Compatibility with code which tries to catch `no-method-definition' errors.
+(push 'no-method-definition (get 'cl-no-applicable-method 'error-conditions))
+
+(defun generic-p (fname) (not (null (cl--generic fname))))
+
+(defun no-next-method (&rest args)
+ (declare (obsolete cl-no-next-method "25.1"))
+ (apply #'cl-no-next-method 'unknown nil args))
+
+(defun no-applicable-method (object method &rest args)
+ (declare (obsolete cl-no-applicable-method "25.1"))
+ (apply #'cl-no-applicable-method method object args))
+
+(define-obsolete-function-alias 'call-next-method 'cl-call-next-method "25.1")
+(defun next-method-p ()
+ (declare (obsolete cl-next-method-p "25.1"))
+ ;; EIEIO's `next-method-p' just returned nil when called in an
+ ;; invalid context.
+ (message "next-method-p called outside of a primary or around method")
+ nil)
+
+;;;###autoload
+(defun eieio-defmethod (method args)
+ "Obsolete work part of an old version of the `defmethod' macro."
+ (declare (obsolete cl-defmethod "24.1"))
+ (eval `(defmethod ,method ,@args))
+ method)
+
+;;;###autoload
+(defun eieio-defgeneric (method doc-string)
+ "Obsolete work part of an old version of the `defgeneric' macro."
+ (declare (obsolete cl-defgeneric "24.1"))
+ (eval `(defgeneric ,method (x) ,@(if doc-string `(,doc-string))))
+ ;; Return the method
+ 'method)
+
+;;;###autoload
+(defun eieio-defclass (cname superclasses slots options)
+ (declare (obsolete eieio-defclass-internal "25.1"))
+ (eval `(defclass ,cname ,superclasses ,slots ,@options)))
+
+
+;; Local Variables:
+;; generated-autoload-file: "eieio-loaddefs.el"
+;; End:
+
+(provide 'eieio-compat)
+
+;;; eieio-compat.el ends here
diff --git a/lisp/obsolete/eudcb-ph.el b/lisp/obsolete/eudcb-ph.el
index 187879ce2f7..51a6780d903 100644
--- a/lisp/obsolete/eudcb-ph.el
+++ b/lisp/obsolete/eudcb-ph.el
@@ -176,9 +176,7 @@ SERVER is either a string naming the server or a list (NAME PORT)."
(setq eudc-ph-process-buffer (get-buffer-create (format " *PH-%s*" host)))
(with-current-buffer eudc-ph-process-buffer
(erase-buffer)
- (setq eudc-ph-read-point (point))
- (and (featurep 'xemacs) (featurep 'mule)
- (set-buffer-file-coding-system 'binary t)))
+ (setq eudc-ph-read-point (point)))
(setq process (open-network-stream "ph" eudc-ph-process-buffer host port))
(if (null process)
(throw 'done nil))
diff --git a/lisp/obsolete/fast-lock.el b/lisp/obsolete/fast-lock.el
index 960233d5627..1dee7120c0e 100644
--- a/lisp/obsolete/fast-lock.el
+++ b/lisp/obsolete/fast-lock.el
@@ -283,10 +283,7 @@ If a number, only buffers greater than this size have processing messages."
(other :tag "always" t)
(integer :tag "size")))
-(defvar fast-lock-save-faces
- (when (featurep 'xemacs)
- ;; XEmacs uses extents for everything, so we have to pick the right ones.
- font-lock-face-list)
+(defvar fast-lock-save-faces nil
"Faces that will be saved in a Font Lock cache file.
If nil, means information for all faces will be saved.")
@@ -707,35 +704,7 @@ See `fast-lock-get-face-properties'."
(while regions
(add-text-properties (nth 0 regions) (nth 1 regions) plist)
(setq regions (nthcdr 2 regions))))))))
-
-;; Functions for XEmacs:
-
-(unless (boundp 'font-lock-syntactic-keywords)
- (defvar font-lock-syntactic-keywords nil))
-
-(unless (boundp 'font-lock-inhibit-thing-lock)
- (defvar font-lock-inhibit-thing-lock nil))
-
-(unless (fboundp 'font-lock-compile-keywords)
- (defalias 'font-lock-compile-keywords #'identity))
-
-(unless (fboundp 'font-lock-eval-keywords)
- (defun font-lock-eval-keywords (keywords)
- (if (symbolp keywords)
- (font-lock-eval-keywords (if (fboundp keywords)
- (funcall keywords)
- (eval keywords t)))
- keywords)))
-
-(unless (fboundp 'font-lock-value-in-major-mode)
- (defun font-lock-value-in-major-mode (alist)
- (if (consp alist)
- (cdr (or (assq major-mode alist) (assq t alist)))
- alist)))
-
-(unless (fboundp 'current-message)
- (defun current-message ()
- ""))
+
;; Install ourselves:
diff --git a/lisp/obsolete/iswitchb.el b/lisp/obsolete/iswitchb.el
index a630baf3543..f1e4414e93f 100644
--- a/lisp/obsolete/iswitchb.el
+++ b/lisp/obsolete/iswitchb.el
@@ -467,9 +467,7 @@ interfere with other minibuffer usage.")
(switch-to-buffer-other-window . iswitchb-buffer-other-window)
(switch-to-buffer-other-frame . iswitchb-buffer-other-frame)
(display-buffer . iswitchb-display-buffer)))
- (if (fboundp 'command-remapping)
- (define-key map (vector 'remap (car b)) (cdr b))
- (substitute-key-definition (car b) (cdr b) map global-map)))
+ (define-key map (vector 'remap (car b)) (cdr b)))
map)
"Global keymap for `iswitchb-mode'.")
@@ -977,17 +975,7 @@ Return the modified list with the last element prepended to it."
(set-buffer buf))
(with-output-to-temp-buffer temp-buf
- (if (featurep 'xemacs)
-
- ;; XEmacs extents are put on by default, doesn't seem to be
- ;; any way of switching them off.
- (display-completion-list (or iswitchb-matches iswitchb-buflist)
- :help-string "iswitchb "
- :activate-callback
- (lambda (_x _y _z)
- (message "doesn't work yet, sorry!")))
- ;; else running Emacs
- (display-completion-list (or iswitchb-matches iswitchb-buflist))))
+ (display-completion-list (or iswitchb-matches iswitchb-buflist)))
(setq iswitchb-common-match-inserted nil))))
;;; KILL CURRENT BUFFER
@@ -1326,9 +1314,7 @@ This is an example function which can be hooked on to
"Return non-nil if we should ignore case when matching.
See the variable `iswitchb-case' for details."
(if iswitchb-case
- (if (featurep 'xemacs)
- (isearch-no-upper-case-p iswitchb-text)
- (isearch-no-upper-case-p iswitchb-text t))))
+ (isearch-no-upper-case-p iswitchb-text t)))
;;;###autoload
(define-minor-mode iswitchb-mode
diff --git a/lisp/obsolete/landmark.el b/lisp/obsolete/landmark.el
index cc4fd19c389..16c41c76ad2 100644
--- a/lisp/obsolete/landmark.el
+++ b/lisp/obsolete/landmark.el
@@ -757,9 +757,9 @@ If the game is finished, this command requests for another game."
(let ((square (landmark-point-square))
score)
(cond ((null square)
- (error "Your point is not on a square. Retry!"))
+ (error "Your point is not on a square. Retry!"))
((not (zerop (aref landmark-board square)))
- (error "Your point is not on a free square. Retry!"))
+ (error "Your point is not on a free square. Retry!"))
(t
(setq score (aref landmark-score-table square))
(landmark-play-move square 1)
@@ -823,14 +823,14 @@ If the game is finished, this command requests for another game."
(defun landmark-prompt-for-other-game ()
"Ask for another game, and start it."
(if (y-or-n-p "Another game? ")
- (if (y-or-n-p "Retain learned weights ")
+ (if (y-or-n-p "Retain learned weights?")
(landmark 2)
(landmark 1))
(message "Chicken!")))
(defun landmark-offer-a-draw ()
"Offer a draw and return t if Human accepted it."
- (or (y-or-n-p "I offer you a draw. Do you accept it? ")
+ (or (y-or-n-p "I offer you a draw. Do you accept it?")
(not (setq landmark-human-refused-draw t))))
@@ -1470,7 +1470,7 @@ push him out of it."
(mapc
(lambda (direction) (put direction 'y_t 0))
landmark-directions)
- (dolist (direction (nth (random 8) landmark-8-directions))
+ (dolist (direction (seq-random-elt landmark-8-directions))
(put direction 'y_t 1.0))
(landmark-move))
@@ -1512,9 +1512,9 @@ If the game is finished, this command requests for another game."
(t
(let ((square (landmark-point-square)))
(cond ((null square)
- (error "Your point is not on a square. Retry!"))
+ (error "Your point is not on a square. Retry!"))
((not (zerop (aref landmark-board square)))
- (error "Your point is not on a free square. Retry!"))
+ (error "Your point is not on a free square. Retry!"))
(t
(progn
(landmark-plot-square square 1)
diff --git a/lisp/obsolete/otodo-mode.el b/lisp/obsolete/otodo-mode.el
index 47f5089452f..a71d2b82e4c 100644
--- a/lisp/obsolete/otodo-mode.el
+++ b/lisp/obsolete/otodo-mode.el
@@ -908,8 +908,7 @@ If INCLUDE-SEP is non-nil, return point after the separator."
;;;###autoload
(define-derived-mode todo-mode nil "TODO"
"Major mode for editing TODO lists."
- (when (featurep 'xemacs)
- (easy-menu-add todo-menu)))
+ nil)
(with-suppressed-warnings ((lexical date entry))
(defvar date)
diff --git a/lisp/obsolete/pgg-parse.el b/lisp/obsolete/pgg-parse.el
index 2c76365a415..3e4c216abef 100644
--- a/lisp/obsolete/pgg-parse.el
+++ b/lisp/obsolete/pgg-parse.el
@@ -496,8 +496,7 @@
(defun pgg-parse-armor (string)
(with-temp-buffer
(buffer-disable-undo)
- (unless (featurep 'xemacs)
- (set-buffer-multibyte nil))
+ (set-buffer-multibyte nil)
(insert string)
(pgg-decode-armor-region (point-min)(point))))
diff --git a/lisp/obsolete/pgg.el b/lisp/obsolete/pgg.el
index 5ed59933f23..127e1dc15c0 100644
--- a/lisp/obsolete/pgg.el
+++ b/lisp/obsolete/pgg.el
@@ -376,8 +376,7 @@ signer's public key from `pgg-default-keyserver-address'."
(if (null signature) nil
(with-temp-buffer
(buffer-disable-undo)
- (unless (featurep 'xemacs)
- (set-buffer-multibyte nil))
+ (set-buffer-multibyte nil)
(insert-file-contents signature)
(cdr (assq 2 (pgg-decode-armor-region
(point-min)(point-max)))))))
diff --git a/lisp/obsolete/rcompile.el b/lisp/obsolete/rcompile.el
index d7020f0d074..c8fb9f20985 100644
--- a/lisp/obsolete/rcompile.el
+++ b/lisp/obsolete/rcompile.el
@@ -108,7 +108,10 @@ nil means run no commands."
;;;; entry point
-;; We use the Tramp internal function`tramp-make-tramp-file-name'.
+;; We use the Tramp internal function `tramp-make-tramp-file-name'.
+;; It has changed its signature in Emacs 27.1, supporting still the
+;; old calling convention. Let's assume rcompile.el has been removed
+;; once Tramp does not support it any longer.
;; Better would be, if there are functions to provide user, host and
;; localname of a remote filename, independent of Tramp's implementation.
;; The function calls are wrapped by `funcall' in order to pacify the byte
@@ -167,7 +170,8 @@ See \\[compile]."
(with-current-buffer compilation-last-buffer
(when (fboundp 'tramp-make-tramp-file-name)
(set (make-local-variable 'comint-file-name-prefix)
- (tramp-make-tramp-file-name
+ (funcall
+ #'tramp-make-tramp-file-name
nil ;; method.
remote-compile-user
remote-compile-host
diff --git a/lisp/mail/rfc2368.el b/lisp/obsolete/rfc2368.el
index b96f15d3e68..8a842b0cf30 100644
--- a/lisp/mail/rfc2368.el
+++ b/lisp/obsolete/rfc2368.el
@@ -4,6 +4,7 @@
;; Author: Sen Nagata <sen@eccosys.com>
;; Keywords: mail
+;; Obsolete-since: 28.1
;; This file is part of GNU Emacs.
diff --git a/lisp/obsolete/terminal.el b/lisp/obsolete/terminal.el
index 0167a00066b..fa89b586a0a 100644
--- a/lisp/obsolete/terminal.el
+++ b/lisp/obsolete/terminal.el
@@ -112,10 +112,9 @@ performance."
nil
(let ((map (make-sparse-keymap)))
(define-key map [t] #'undefined)
- (let ((s "0"))
- (while (<= (aref s 0) ?9)
- (define-key map s #'digit-argument)
- (aset s 0 (1+ (aref s 0)))))
+ (dotimes (i 10)
+ (let ((s (make-string 1 (+ ?0 i))))
+ (define-key map s #'digit-argument)))
(define-key map "b" #'switch-to-buffer)
(define-key map "o" #'other-window)
(define-key map "e" #'te-set-escape-char)
diff --git a/lisp/obsolete/tls.el b/lisp/obsolete/tls.el
index 5cba18d7897..ff01008613b 100644
--- a/lisp/obsolete/tls.el
+++ b/lisp/obsolete/tls.el
@@ -260,14 +260,14 @@ Fourth arg PORT is an integer specifying a port to connect to."
NOT trusted." host))
(not (yes-or-no-p
(format-message "\
-The certificate presented by `%s' is NOT trusted. Accept anyway? " host)))))
+The certificate presented by `%s' is NOT trusted. Accept anyway?" host)))))
(and tls-hostmismatch
(save-excursion
(goto-char (point-min))
(re-search-forward tls-hostmismatch nil t))
(not (yes-or-no-p
(format "Host name in certificate doesn't \
-match `%s'. Connect anyway? " host))))))
+match `%s'. Connect anyway?" host))))))
(setq done nil)
(delete-process process))
;; Delete all the informational messages that could confuse
diff --git a/lisp/obsolete/tpu-edt.el b/lisp/obsolete/tpu-edt.el
index e0e89c390ea..b59fb8c868c 100644
--- a/lisp/obsolete/tpu-edt.el
+++ b/lisp/obsolete/tpu-edt.el
@@ -650,12 +650,8 @@ GOLD is the ASCII 7-bit escape sequence <ESC>OP.")
(setq tpu-mark-flag (if transient-mark-mode "" (if (tpu-mark) " @" " ")))
(force-mode-line-update))
-(cond ((featurep 'xemacs)
- (add-hook 'zmacs-deactivate-region-hook 'tpu-update-mode-line)
- (add-hook 'zmacs-activate-region-hook 'tpu-update-mode-line))
- (t
- (add-hook 'activate-mark-hook 'tpu-update-mode-line)
- (add-hook 'deactivate-mark-hook 'tpu-update-mode-line)))
+(add-hook 'activate-mark-hook 'tpu-update-mode-line)
+(add-hook 'deactivate-mark-hook 'tpu-update-mode-line)
;;;
@@ -727,15 +723,13 @@ Otherwise sets the tpu-match markers to nil and returns nil."
"TPU-edt version of the mark function.
Return the appropriate value of the mark for the current
version of Emacs."
- (cond ((featurep 'xemacs) (mark (not zmacs-regions)))
- (t (and mark-active (mark (not transient-mark-mode))))))
+ (and mark-active (mark (not transient-mark-mode))))
(defun tpu-set-mark (pos)
"TPU-edt version of the `set-mark' function.
Sets the mark at POS and activates the region according to the
current version of Emacs."
- (set-mark pos)
- (when (featurep 'xemacs) (when pos (zmacs-activate-region))))
+ (set-mark pos))
(defun tpu-string-prompt (prompt history-symbol)
"Read a string with PROMPT."
@@ -2306,17 +2300,14 @@ Accepts a prefix argument for the number of tpu-pan-columns to scroll."
;;;
(defun tpu-load-xkeys (file)
"Load the TPU-edt X-windows key definitions FILE.
-If FILE is nil, try to load a default file. The default file names are
-`~/.tpu-lucid-keys' for XEmacs, and `~/.tpu-keys' for Emacs."
+If FILE is nil, try to load a default file. The default file name is
+`~/.tpu-keys'."
(interactive "fX key definition file: ")
(cond (file
(setq file (expand-file-name file)))
(tpu-xkeys-file
(setq file (expand-file-name tpu-xkeys-file)))
- ((featurep 'xemacs)
- (setq file (convert-standard-filename
- (expand-file-name "~/.tpu-lucid-keys"))))
- (t
+ (t
(setq file (convert-standard-filename
(expand-file-name "~/.tpu-keys")))
(and (not (file-exists-p file))
diff --git a/lisp/obsolete/tpu-mapper.el b/lisp/obsolete/tpu-mapper.el
index 5ae0a6558d5..02ba3632504 100644
--- a/lisp/obsolete/tpu-mapper.el
+++ b/lisp/obsolete/tpu-mapper.el
@@ -46,24 +46,14 @@
;;;
(defun tpu-map-key (ident descrip func gold-func)
(interactive)
- (if (featurep 'xemacs)
- (progn
- (setq tpu-key-seq (read-key-sequence
- (format "Press %s%s: " ident descrip))
- tpu-key (format "[%s]" (event-key (aref tpu-key-seq 0))))
- (unless (equal tpu-key tpu-return)
- (set-buffer "Keys")
- (insert (format"(global-set-key %s %s)\n" tpu-key func))
- (set-buffer "Gold-Keys")
- (insert (format "(define-key tpu-gold-map %s %s)\n" tpu-key gold-func))))
- (message "Press %s%s: " ident descrip)
- (setq tpu-key-seq (read-event)
- tpu-key (format "[%s]" tpu-key-seq))
- (unless (equal tpu-key tpu-return)
- (set-buffer "Keys")
- (insert (format"(define-key tpu-global-map %s %s)\n" tpu-key func))
- (set-buffer "Gold-Keys")
- (insert (format "(define-key tpu-gold-map %s %s)\n" tpu-key gold-func))))
+ (message "Press %s%s: " ident descrip)
+ (setq tpu-key-seq (read-event)
+ tpu-key (format "[%s]" tpu-key-seq))
+ (unless (equal tpu-key tpu-return)
+ (set-buffer "Keys")
+ (insert (format"(define-key tpu-global-map %s %s)\n" tpu-key func))
+ (set-buffer "Gold-Keys")
+ (insert (format "(define-key tpu-gold-map %s %s)\n" tpu-key gold-func)))
(set-buffer "Directions")
tpu-key)
@@ -103,8 +93,7 @@ your local X guru can try to figure out why the key is being ignored."
;; Make sure the window is big enough to display the instructions
- (if (featurep 'xemacs) (set-screen-size (selected-screen) 80 36)
- (set-frame-size (selected-frame) 80 36))
+ (set-frame-size (selected-frame) 80 36)
;; Create buffers - Directions, Keys, Gold-Keys
@@ -162,14 +151,9 @@ your local X guru can try to figure out why the key is being ignored."
;; Save <CR> for future reference
- (cond
- ((featurep 'xemacs)
- (setq tpu-return-seq (read-key-sequence "Hit carriage-return <CR> to continue "))
- (setq tpu-return (concat "[" (format "%s" (event-key (aref tpu-return-seq 0))) "]")))
- (t
- (message "Hit carriage-return <CR> to continue ")
- (setq tpu-return-seq (read-event))
- (setq tpu-return (concat "[" (format "%s" tpu-return-seq) "]"))))
+ (message "Hit carriage-return <CR> to continue ")
+ (setq tpu-return-seq (read-event))
+ (setq tpu-return (concat "[" (format "%s" tpu-return-seq) "]"))
;; Build the keymap file
@@ -308,24 +292,14 @@ your local X guru can try to figure out why the key is being ignored."
;;
")
- (cond ((featurep 'xemacs)
- (insert (format "(setq tpu-help-enter \"%s\")\n" tpu-enter-seq))
- (insert (format "(setq tpu-help-return \"%s\")\n" tpu-return-seq))
- (insert "(setq tpu-help-N \"[#<keypress-event N>]\")\n")
- (insert "(setq tpu-help-n \"[#<keypress-event n>]\")\n")
- (insert "(setq tpu-help-P \"[#<keypress-event P>]\")\n")
- (insert "(setq tpu-help-p \"[#<keypress-event p>]\")\n"))
- (t
- (insert (format "(setq tpu-help-enter \"%s\")\n" tpu-enter))))
+ (insert (format "(setq tpu-help-enter \"%s\")\n" tpu-enter))
(append-to-buffer "Keys" 1 (point))
(set-buffer "Keys")
;; Save the key mapping program
- (let ((file
- (convert-standard-filename
- (if (featurep 'xemacs) "~/.tpu-lucid-keys" "~/.tpu-keys"))))
+ (let ((file (convert-standard-filename "~/.tpu-keys")))
(set-visited-file-name
(read-file-name (format "Save key mapping to file (default %s): " file) "" file)))
(save-buffer)
diff --git a/lisp/obsolete/vc-arch.el b/lisp/obsolete/vc-arch.el
index cfbf981d3c8..1dffd36f0ea 100644
--- a/lisp/obsolete/vc-arch.el
+++ b/lisp/obsolete/vc-arch.el
@@ -24,7 +24,7 @@
;;; Commentary:
-;; The home page of the Arch version control system is at
+;; The Arch version control system website is at
;;
;; https://www.gnu.org/software/gnu-arch/
;;
@@ -83,8 +83,6 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches."
(repeat :tag "Argument List" :value ("") string))
:version "23.1")
-(define-obsolete-variable-alias 'vc-arch-command 'vc-arch-program "23.1")
-
(defcustom vc-arch-program
(let ((candidates '("tla" "baz")))
(while (and candidates (not (executable-find (car candidates))))
diff --git a/lisp/obsolete/vip.el b/lisp/obsolete/vip.el
index 16906b68a67..2fa8c951531 100644
--- a/lisp/obsolete/vip.el
+++ b/lisp/obsolete/vip.el
@@ -615,11 +615,11 @@ obtained so far, and COM is the command part obtained so far."
(cond ((null arg) nil)
((consp arg) (car arg))
((numberp arg) arg)
- (t (error "strange arg")))
+ (t (error "Strange arg")))
(cond ((null arg) nil)
((consp arg) (cdr arg))
((numberp arg) nil)
- (t (error "strange arg"))))
+ (t (error "Strange arg"))))
(quit
(setq vip-use-register nil)
(signal 'quit nil))))
@@ -2248,7 +2248,7 @@ a token has type \(command, address, end-mark) and value."
(setq ex-token-type "end-mark")
(setq ex-token "goto"))
(t
- (error "invalid token")))))
+ (error "Invalid token")))))
(defun vip-ex (&optional string)
"ex commands within VIP."
@@ -2333,7 +2333,7 @@ a token has type \(command, address, end-mark) and value."
(cond ((looking-at "[a-z]")
(vip-get-ex-com-subr)
(if (string= ex-token-type "non-command")
- (error "%s: not an editor command" ex-token)))
+ (error "%s: Not an editor command" ex-token)))
((looking-at "[!=><&~]")
(setq ex-token (char-to-string (following-char)))
(forward-char 1))
@@ -2378,7 +2378,7 @@ a token has type \(command, address, end-mark) and value."
(progn
(setq ex-flag t)
(setq cont nil))
- (error "address expected")))
+ (error "Address expected")))
((string= ex-token-type "end-mark")
(setq cont nil))
((string= ex-token-type "whole")
@@ -2568,7 +2568,7 @@ a token has type \(command, address, end-mark) and value."
(string= ex-token "insert")
(string= ex-token "open")
)
- (error "%s: no such command from VIP" ex-token))
+ (error "%s: No such command from VIP" ex-token))
((or (string= ex-token "abbreviate")
(string= ex-token "list")
(string= ex-token "next")
@@ -2581,7 +2581,7 @@ a token has type \(command, address, end-mark) and value."
(string= ex-token "xit")
(string= ex-token "z")
)
- (error "%s: not implemented in VIP" ex-token))
+ (error "%s: Not implemented in VIP" ex-token))
(t (error "%s: Not an editor command" ex-token))))
(defun ex-goto ()
diff --git a/lisp/org/ob-C.el b/lisp/org/ob-C.el
index 6e339017931..842e0d3e8ec 100644
--- a/lisp/org/ob-C.el
+++ b/lisp/org/ob-C.el
@@ -4,6 +4,7 @@
;; Author: Eric Schulte
;; Thierry Banel
+;; Maintainer: Thierry Banel
;; Keywords: literate programming, reproducible research
;; Homepage: https://orgmode.org
@@ -94,8 +95,7 @@ This function calls `org-babel-execute:C++'."
(org-babel-execute:C++ body params))
(defun org-babel-expand-body:cpp (body params)
- "Expand a block of C++ code with org-babel according to its
-header arguments."
+ "Expand a block of C++ code with org-babel according to its header arguments."
(org-babel-expand-body:C++ body params))
(defun org-babel-execute:C++ (body params)
@@ -104,8 +104,7 @@ This function is called by `org-babel-execute-src-block'."
(let ((org-babel-c-variant 'cpp)) (org-babel-C-execute body params)))
(defun org-babel-expand-body:C++ (body params)
- "Expand a block of C++ code with org-babel according to its
-header arguments."
+ "Expand a block of C++ code with org-babel according to its header arguments."
(let ((org-babel-c-variant 'cpp)) (org-babel-C-expand-C++ body params)))
(defun org-babel-execute:D (body params)
@@ -114,8 +113,7 @@ This function is called by `org-babel-execute-src-block'."
(let ((org-babel-c-variant 'd)) (org-babel-C-execute body params)))
(defun org-babel-expand-body:D (body params)
- "Expand a block of D code with org-babel according to its
-header arguments."
+ "Expand a block of D code with org-babel according to its header arguments."
(let ((org-babel-c-variant 'd)) (org-babel-C-expand-D body params)))
(defun org-babel-execute:C (body params)
@@ -124,8 +122,7 @@ This function is called by `org-babel-execute-src-block'."
(let ((org-babel-c-variant 'c)) (org-babel-C-execute body params)))
(defun org-babel-expand-body:C (body params)
- "Expand a block of C code with org-babel according to its
-header arguments."
+ "Expand a block of C code with org-babel according to its header arguments."
(let ((org-babel-c-variant 'c)) (org-babel-C-expand-C body params)))
(defun org-babel-C-execute (body params)
@@ -196,13 +193,11 @@ or `org-babel-execute:C++' or `org-babel-execute:D'."
)))
(defun org-babel-C-expand-C++ (body params)
- "Expand a block of C or C++ code with org-babel according to
-its header arguments."
+ "Expand a block of C/C++ code with org-babel according to its header arguments."
(org-babel-C-expand-C body params))
(defun org-babel-C-expand-C (body params)
- "Expand a block of C or C++ code with org-babel according to
-its header arguments."
+ "Expand a block of C/C++ code with org-babel according to its header arguments."
(let ((vars (org-babel--get-vars params))
(colnames (cdr (assq :colname-names params)))
(main-p (not (string= (cdr (assq :main params)) "no")))
@@ -257,15 +252,21 @@ its header arguments."
(when colnames
(org-babel-C-utility-header-to-C))
;; tables headers
- (mapconcat 'org-babel-C-header-to-C colnames "\n")
+ (mapconcat (lambda (head)
+ (let* ((tblnm (car head))
+ (tbl (cdr (car (let* ((el vars))
+ (while (not (or (equal tblnm (caar el)) (not el)))
+ (setq el (cdr el)))
+ el))))
+ (type (org-babel-C-val-to-base-type tbl)))
+ (org-babel-C-header-to-C head type))) colnames "\n")
;; body
(if main-p
(org-babel-C-ensure-main-wrap body)
body) "\n") "\n")))
(defun org-babel-C-expand-D (body params)
- "Expand a block of D code with org-babel according to
-its header arguments."
+ "Expand a block of D code with org-babel according to its header arguments."
(let ((vars (org-babel--get-vars params))
(colnames (cdr (assq :colname-names params)))
(main-p (not (string= (cdr (assq :main params)) "no")))
@@ -289,7 +290,14 @@ its header arguments."
(when colnames
(org-babel-C-utility-header-to-C))
;; tables headers
- (mapconcat 'org-babel-C-header-to-C colnames "\n")
+ (mapconcat (lambda (head)
+ (let* ((tblnm (car head))
+ (tbl (cdr (car (let* ((el vars))
+ (while (not (or (equal tblnm (caar el)) (not el)))
+ (setq el (cdr el)))
+ el))))
+ (type (org-babel-C-val-to-base-type tbl)))
+ (org-babel-C-header-to-C head type))) colnames "\n")
;; body
(if main-p
(org-babel-C-ensure-main-wrap body)
@@ -333,7 +341,7 @@ FORMAT can be either a format string or a function which is called with VAL."
(list
(if (eq org-babel-c-variant 'd) "string" "const char*")
"\"%s\""))
- (_ (error "unknown type %S" basetype)))))
+ (_ (error "Unknown type %S" basetype)))))
(cond
((integerp val) type) ;; an integer declared in the #+begin_src line
((floatp val) type) ;; a numeric declared in the #+begin_src line
@@ -341,7 +349,9 @@ FORMAT can be either a format string or a function which is called with VAL."
`(,(car type)
(lambda (val)
(cons
- (format "[%d][%d]" (length val) (length (car val)))
+ (pcase org-babel-c-variant
+ ((or `c `cpp) (format "[%d][%d]" (length val) (length (car val))))
+ (`d (format "[%d][%d]" (length (car val)) (length val))))
(concat
(if (eq org-babel-c-variant 'd) "[\n" "{\n")
(mapconcat
@@ -388,8 +398,7 @@ FORMAT can be either a format string or a function which is called with VAL."
(t 'stringp)))
(defun org-babel-C-var-to-C (pair)
- "Convert an elisp val into a string of C code specifying a var
-of the same value."
+ "Convert an elisp val into a string of C code specifying a var of the same value."
;; TODO list support
(let ((var (car pair))
(val (cdr pair)))
@@ -402,11 +411,19 @@ of the same value."
(formatted (org-babel-C-format-val type-data val))
(suffix (car formatted))
(data (cdr formatted)))
- (format "%s %s%s = %s;"
- type
- var
- suffix
- data))))
+ (pcase org-babel-c-variant
+ ((or `c `cpp)
+ (format "%s %s%s = %s;"
+ type
+ var
+ suffix
+ data))
+ (`d
+ (format "%s%s %s = %s;"
+ type
+ suffix
+ var
+ data))))))
(defun org-babel-C-table-sizes-to-C (pair)
"Create constants of table dimensions, if PAIR is a table."
@@ -421,11 +438,15 @@ of the same value."
(format "const int %s_cols = %d;" (car pair) (length (cdr pair)))))))
(defun org-babel-C-utility-header-to-C ()
- "Generate a utility function to convert a column name
-into a column number."
+ "Generate a utility function to convert a column name into a column number."
(pcase org-babel-c-variant
((or `c `cpp)
- "int get_column_num (int nbcols, const char** header, const char* column)
+ (concat
+ "
+#ifndef _STRING_H
+#include <string.h>
+#endif
+int get_column_num (int nbcols, const char** header, const char* column)
{
int c;
for (c=0; c<nbcols; c++)
@@ -433,7 +454,7 @@ into a column number."
return c;
return -1;
}
-")
+"))
(`d
"int get_column_num (string[] header, string column)
{
@@ -444,29 +465,40 @@ into a column number."
}
")))
-(defun org-babel-C-header-to-C (head)
+(defun org-babel-C-header-to-C (head type)
"Convert an elisp list of header table into a C or D vector
specifying a variable with the name of the table."
+ (message "%S" type)
(let ((table (car head))
- (headers (cdr head)))
+ (headers (cdr head))
+ (typename (pcase type
+ (`integerp "int")
+ (`floatp "double")
+ (`stringp (pcase org-babel-c-variant
+ ((or `c `cpp) "const char*")
+ (`d "string"))))))
(concat
- (format
- (pcase org-babel-c-variant
- ((or `c `cpp) "const char* %s_header[%d] = {%s};")
- (`d "string %s_header[%d] = [%s];"))
- table
- (length headers)
- (mapconcat (lambda (h) (format "%S" h)) headers ","))
+ (pcase org-babel-c-variant
+ ((or `c `cpp)
+ (format "const char* %s_header[%d] = {%s};"
+ table
+ (length headers)
+ (mapconcat (lambda (h) (format "\"%s\"" h)) headers ",")))
+ (`d
+ (format "string[%d] %s_header = [%s];"
+ (length headers)
+ table
+ (mapconcat (lambda (h) (format "\"%s\"" h)) headers ","))))
"\n"
(pcase org-babel-c-variant
((or `c `cpp)
(format
- "const char* %s_h (int row, const char* col) { return %s[row][get_column_num(%d,%s_header,col)]; }"
- table table (length headers) table))
+ "%s %s_h (int row, const char* col) { return %s[row][get_column_num(%d,%s_header,col)]; }"
+ typename table table (length headers) table))
(`d
(format
- "string %s_h (size_t row, string col) { return %s[row][get_column_num(%s_header,col)]; }"
- table table table))))))
+ "%s %s_h (size_t row, string col) { return %s[row][get_column_num(%s_header,col)]; }"
+ typename table table table))))))
(provide 'ob-C)
diff --git a/lisp/org/ob-J.el b/lisp/org/ob-J.el
deleted file mode 100644
index 0c5591d5b71..00000000000
--- a/lisp/org/ob-J.el
+++ /dev/null
@@ -1,189 +0,0 @@
-;;; ob-J.el --- Babel Functions for J -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2011-2021 Free Software Foundation, Inc.
-
-;; Author: Oleh Krehel
-;; Maintainer: Joseph Novakovich <josephnovakovich@gmail.com>
-;; Keywords: literate programming, reproducible research
-;; Homepage: https://orgmode.org
-
-;; 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:
-
-;; Org-Babel support for evaluating J code.
-;;
-;; Session interaction depends on `j-console' from package `j-mode'
-;; (available in MELPA).
-
-;;; Code:
-
-(require 'ob)
-(require 'org-macs)
-
-(declare-function j-console-ensure-session "ext:j-console" ())
-
-(defcustom org-babel-J-command "jconsole"
- "Command to call J."
- :group 'org-babel
- :version "26.1"
- :package-version '(Org . "9.0")
- :type 'string)
-
-(defun org-babel-expand-body:J (body _params &optional _processed-params)
- "Expand BODY according to PARAMS, return the expanded body.
-PROCESSED-PARAMS isn't used yet."
- (org-babel-J-interleave-echos-except-functions body))
-
-(defun org-babel-J-interleave-echos (body)
- "Interleave echo',' between each source line of BODY."
- (mapconcat #'identity (split-string body "\n") "\necho','\n"))
-
-(defun org-babel-J-interleave-echos-except-functions (body)
- "Interleave echo',' between source lines of BODY that aren't functions."
- (if (obj-string-match-m "\\(?:^\\|\n\\)[^\n]*\\(?:0\\|1\\|2\\|3\\|4\\|dyad\\) : 0\n.*\n)\\(?:\n\\|$\\)" body)
- (let ((s1 (substring body 0 (match-beginning 0)))
- (s2 (match-string 0 body))
- (s3 (substring body (match-end 0))))
- (concat
- (if (string= s1 "")
- ""
- (concat (org-babel-J-interleave-echos s1)
- "\necho','\n"))
- s2
- "\necho','\n"
- (org-babel-J-interleave-echos-except-functions s3)))
- (org-babel-J-interleave-echos body)))
-
-(defalias 'org-babel-execute:j 'org-babel-execute:J)
-
-(defun org-babel-execute:J (body params)
- "Execute a block of J code BODY.
-PARAMS are given by org-babel.
-This function is called by `org-babel-execute-src-block'."
- (message "executing J source code block")
- (let* ((processed-params (org-babel-process-params params))
- (sessionp (cdr (assq :session params)))
- (sit-time (let ((sit (assq :sit params)))
- (if sit (cdr sit) .1)))
- (full-body (org-babel-expand-body:J
- body params processed-params))
- (tmp-script-file (org-babel-temp-file "J-src")))
- (org-babel-j-initiate-session sessionp)
- (org-babel-J-strip-whitespace
- (if (string= sessionp "none")
- (progn
- (with-temp-file tmp-script-file
- (insert full-body))
- (org-babel-eval (format "%s < %s" org-babel-J-command tmp-script-file) ""))
- (org-babel-J-eval-string full-body sit-time)))))
-
-(defun org-babel-J-eval-string (str sit-time)
- "Sends STR to the `j-console-cmd' session and executes it."
- (let ((session (j-console-ensure-session)))
- (with-current-buffer (process-buffer session)
- (goto-char (point-max))
- (insert (format "\n%s\n" str))
- (let ((beg (point)))
- (comint-send-input)
- (sit-for sit-time)
- (buffer-substring-no-properties
- beg (point-max))))))
-
-(defun org-babel-J-strip-whitespace (str)
- "Remove whitespace from jconsole output STR."
- (mapconcat
- #'identity
- (delete "" (mapcar
- #'org-babel-J-print-block
- (split-string str "^ *,\n" t)))
- "\n\n"))
-
-(defun obj-get-string-alignment (str)
- "Return a number to describe STR alignment.
-STR represents a table.
-Positive/negative/zero result means right/left/undetermined.
-Don't trust first line."
- (let* ((str (org-trim str))
- (lines (split-string str "\n" t))
- n1 n2)
- (cond ((<= (length lines) 1)
- 0)
- ((= (length lines) 2)
- ;; numbers are right-aligned
- (if (and
- (numberp (read (car lines)))
- (numberp (read (cadr lines)))
- (setq n1 (obj-match-second-space-right (nth 0 lines)))
- (setq n2 (obj-match-second-space-right (nth 1 lines))))
- n2
- 0))
- ((not (obj-match-second-space-left (nth 0 lines)))
- 0)
- ((and
- (setq n1 (obj-match-second-space-left (nth 1 lines)))
- (setq n2 (obj-match-second-space-left (nth 2 lines)))
- (= n1 n2))
- n1)
- ((and
- (setq n1 (obj-match-second-space-right (nth 1 lines)))
- (setq n2 (obj-match-second-space-right (nth 2 lines)))
- (= n1 n2))
- (- n1))
- (t 0))))
-
-(defun org-babel-J-print-block (x)
- "Prettify jconsole output X."
- (let* ((x (org-trim x))
- (a (obj-get-string-alignment x))
- (lines (split-string x "\n" t))
- b)
- (cond ((< a 0)
- (setq b (obj-match-second-space-right (nth 0 lines)))
- (concat (make-string (+ a b) ? ) x))
- ((> a 0)
- (setq b (obj-match-second-space-left (nth 0 lines)))
- (concat (make-string (- a b) ? ) x))
- (t x))))
-
-(defun obj-match-second-space-left (s)
- "Return position of leftmost space in second space block of S or nil."
- (and (string-match "^ *[^ ]+\\( \\)" s)
- (match-beginning 1)))
-
-(defun obj-match-second-space-right (s)
- "Return position of rightmost space in second space block of S or nil."
- (and (string-match "^ *[^ ]+ *\\( \\)[^ ]" s)
- (match-beginning 1)))
-
-(defun obj-string-match-m (regexp string &optional start)
- "Call (string-match REGEXP STRING START).
-REGEXP is modified so that .* matches newlines as well."
- (string-match
- (replace-regexp-in-string "\\.\\*" "[\0-\377[:nonascii:]]*" regexp)
- string
- start))
-
-(defun org-babel-j-initiate-session (&optional session)
- "Initiate a J session.
-SESSION is a parameter given by org-babel."
- (unless (string= session "none")
- (require 'j-console)
- (j-console-ensure-session)))
-
-(provide 'ob-J)
-
-;;; ob-J.el ends here
diff --git a/lisp/org/ob-R.el b/lisp/org/ob-R.el
index 309a0acf7e7..169e1d6d6ce 100644
--- a/lisp/org/ob-R.el
+++ b/lisp/org/ob-R.el
@@ -4,6 +4,7 @@
;; Author: Eric Schulte
;; Dan Davison
+;; Maintainer: Jeremie Juste
;; Keywords: literate programming, reproducible research, R, statistics
;; Homepage: https://orgmode.org
@@ -39,6 +40,13 @@
(declare-function ess-wait-for-process "ext:ess-inf"
(&optional proc sec-prompt wait force-redisplay))
+;; FIXME: Temporary declaration to silence the byte-compiler
+(defvar user-inject-src-param)
+(defvar ess-eval-visibly-tmp)
+(defvar ess-eval-visibly)
+(defvar ess-inject-source)
+(defvar user-inject-src-param)
+
(defconst org-babel-header-args:R
'((width . :any)
(height . :any)
@@ -157,6 +165,7 @@ This function is called by `org-babel-execute-src-block'."
(save-excursion
(let* ((result-params (cdr (assq :result-params params)))
(result-type (cdr (assq :result-type params)))
+ (async (org-babel-comint-use-async params))
(session (org-babel-R-initiate-session
(cdr (assq :session params)) params))
(graphics-file (and (member "graphics" (assq :result-params params))
@@ -183,7 +192,8 @@ This function is called by `org-babel-execute-src-block'."
(cdr (assq :colname-names params)) colnames-p))
(or (equal "yes" rownames-p)
(org-babel-pick-name
- (cdr (assq :rowname-names params)) rownames-p)))))
+ (cdr (assq :rowname-names params)) rownames-p))
+ async)))
(if graphics-file nil result))))
(defun org-babel-prep-session:R (session params)
@@ -321,7 +331,7 @@ Each member of this list is a list with three members:
(device-info (or (assq (intern (concat ":" device))
org-babel-R-graphics-devices)
(assq :png org-babel-R-graphics-devices)))
- (extra-args (cdr (assq :R-dev-args params))) filearg args)
+ (extra-args (cdr (assq :R-dev-args params))) filearg args)
(setq device (nth 1 device-info))
(setq filearg (nth 2 device-info))
(setq args (mapconcat
@@ -348,7 +358,7 @@ Each member of this list is a list with three members:
{
tfile<-tempfile()
write.table(object, file=tfile, sep=\"\\t\",
- na=\"nil\",row.names=%s,col.names=%s,
+ na=\"\",row.names=%s,col.names=%s,
quote=FALSE)
file.rename(tfile,transfer.file)
},
@@ -370,11 +380,14 @@ Has four %s escapes to be filled in:
4. The name of the file to write to")
(defun org-babel-R-evaluate
- (session body result-type result-params column-names-p row-names-p)
+ (session body result-type result-params column-names-p row-names-p async)
"Evaluate R code in BODY."
(if session
- (org-babel-R-evaluate-session
- session body result-type result-params column-names-p row-names-p)
+ (if async
+ (ob-session-async-org-babel-R-evaluate-session
+ session body result-type result-params column-names-p row-names-p)
+ (org-babel-R-evaluate-session
+ session body result-type result-params column-names-p row-names-p))
(org-babel-R-evaluate-external-process
body result-type result-params column-names-p row-names-p)))
@@ -450,11 +463,13 @@ last statement in BODY, as elisp."
(car (split-string line "\n")))
(substring line (match-end 1))
line))
- (org-babel-comint-with-output (session org-babel-R-eoe-output)
- (insert (mapconcat 'org-babel-chomp
- (list body org-babel-R-eoe-indicator)
- "\n"))
- (inferior-ess-send-input)))))) "\n"))))
+ (with-current-buffer session
+ (let ((comint-prompt-regexp (concat "^" comint-prompt-regexp)))
+ (org-babel-comint-with-output (session org-babel-R-eoe-output)
+ (insert (mapconcat 'org-babel-chomp
+ (list body org-babel-R-eoe-indicator)
+ "\n"))
+ (inferior-ess-send-input)))))))) "\n"))))
(defun org-babel-R-process-value-result (result column-names-p)
"R-specific processing of return value.
@@ -465,6 +480,91 @@ Insert hline if column names in output have been requested."
(error "Could not parse R result"))
result))
+
+;;; async evaluation
+
+(defconst ob-session-async-R-indicator "'ob_comint_async_R_%s_%s'")
+
+(defun ob-session-async-org-babel-R-evaluate-session
+ (session body result-type _ column-names-p row-names-p)
+ "Asynchronously evaluate BODY in SESSION.
+Returns a placeholder string for insertion, to later be replaced
+by `org-babel-comint-async-filter'."
+ (org-babel-comint-async-register
+ session (current-buffer)
+ "^\\(?:[>.+] \\)*\\[1\\] \"ob_comint_async_R_\\(.+?\\)_\\(.+\\)\"$"
+ 'org-babel-chomp
+ 'ob-session-async-R-value-callback)
+ (cl-case result-type
+ (value
+ (let ((tmp-file (org-babel-temp-file "R-")))
+ (with-temp-buffer
+ (insert
+ (org-babel-chomp body))
+ (let ((ess-local-process-name
+ (process-name (get-buffer-process session))))
+ (ess-eval-buffer nil)))
+ (with-temp-buffer
+ (insert
+ (mapconcat
+ 'org-babel-chomp
+ (list (format org-babel-R-write-object-command
+ (if row-names-p "TRUE" "FALSE")
+ (if column-names-p
+ (if row-names-p "NA" "TRUE")
+ "FALSE")
+ ".Last.value"
+ (org-babel-process-file-name tmp-file 'noquote))
+ (format ob-session-async-R-indicator
+ "file" tmp-file))
+ "\n"))
+ (let ((ess-local-process-name
+ (process-name (get-buffer-process session))))
+ (ess-eval-buffer nil)))
+ tmp-file))
+ (output
+ (let ((uuid (md5 (number-to-string (random 100000000))))
+ (ess-local-process-name
+ (process-name (get-buffer-process session))))
+ (with-temp-buffer
+ (insert (format ob-session-async-R-indicator
+ "start" uuid))
+ (insert "\n")
+ (insert body)
+ (insert "\n")
+ (insert (format ob-session-async-R-indicator
+ "end" uuid))
+ (setq ess-eval-visibly-tmp ess-eval-visibly)
+ (setq user-inject-src-param ess-inject-source)
+ (setq ess-eval-visibly nil)
+ (setq ess-inject-source 'function-and-buffer)
+ (ess-eval-buffer nil))
+ (setq ess-eval-visibly ess-eval-visibly-tmp)
+ (setq ess-inject-source user-inject-src-param)
+ uuid))))
+
+(defun ob-session-async-R-value-callback (params tmp-file)
+ "Callback for async value results.
+Assigned locally to `ob-session-async-file-callback' in R
+comint buffers used for asynchronous Babel evaluation."
+ (let* ((graphics-file (and (member "graphics" (assq :result-params params))
+ (org-babel-graphical-output-file params)))
+ (colnames-p (unless graphics-file (cdr (assq :colnames params)))))
+ (org-babel-R-process-value-result
+ (org-babel-result-cond (assq :result-params params)
+ (with-temp-buffer
+ (insert-file-contents tmp-file)
+ (org-babel-chomp (buffer-string) "\n"))
+ (org-babel-import-elisp-from-file tmp-file '(16)))
+ (or (equal "yes" colnames-p)
+ (org-babel-pick-name
+ (cdr (assq :colname-names params)) colnames-p)))))
+
+
+
+;;; ob-session-async-R.el ends here
+
+
(provide 'ob-R)
;;; ob-R.el ends here
diff --git a/lisp/org/ob-abc.el b/lisp/org/ob-abc.el
deleted file mode 100644
index 404e39fc27c..00000000000
--- a/lisp/org/ob-abc.el
+++ /dev/null
@@ -1,90 +0,0 @@
-;;; ob-abc.el --- Org Babel Functions for ABC -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2013-2021 Free Software Foundation, Inc.
-
-;; Author: William Waites
-;; Keywords: literate programming, music
-;; Homepage: https://www.tardis.ed.ac.uk/~wwaites
-
-;; 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 file adds support to Org Babel for music in ABC notation.
-;;; It requires that the abcm2ps program is installed.
-;;; See http://moinejf.free.fr/
-
-(require 'ob)
-
-;; optionally define a file extension for this language
-(add-to-list 'org-babel-tangle-lang-exts '("abc" . "abc"))
-
-;; optionally declare default header arguments for this language
-(defvar org-babel-default-header-args:abc
- '((:results . "file") (:exports . "results"))
- "Default arguments to use when evaluating an ABC source block.")
-
-(defun org-babel-expand-body:abc (body params)
- "Expand BODY according to PARAMS, return the expanded body."
- (let ((vars (org-babel--get-vars params)))
- (mapc
- (lambda (pair)
- (let ((name (symbol-name (car pair)))
- (value (cdr pair)))
- (setq body
- (replace-regexp-in-string
- (concat "\\$" (regexp-quote name))
- (if (stringp value) value (format "%S" value))
- body))))
- vars)
- body))
-
-(defun org-babel-execute:abc (body params)
- "Execute a block of ABC code with org-babel. This function is
- called by `org-babel-execute-src-block'"
- (message "executing Abc source code block")
- (let* ((cmdline (cdr (assq :cmdline params)))
- (out-file (let ((file (cdr (assq :file params))))
- (if file (replace-regexp-in-string "\\.pdf$" ".ps" file)
- (error "abc code block requires :file header argument"))))
- (in-file (org-babel-temp-file "abc-"))
- (render (concat "abcm2ps" " " cmdline
- " -O " (org-babel-process-file-name out-file)
- " " (org-babel-process-file-name in-file))))
- (with-temp-file in-file (insert (org-babel-expand-body:abc body params)))
- (org-babel-eval render "")
- ;;; handle where abcm2ps changes the file name (to support multiple files
- (when (or (string= (file-name-extension out-file) "eps")
- (string= (file-name-extension out-file) "svg"))
- (rename-file (concat
- (file-name-sans-extension out-file) "001."
- (file-name-extension out-file))
- out-file t))
- ;;; if we were asked for a pdf...
- (when (string= (file-name-extension (cdr (assq :file params))) "pdf")
- (org-babel-eval (concat "ps2pdf" " " out-file " " (cdr (assq :file params))) ""))
- ;;; indicate that the file has been written
- nil))
-
-;; This function should be used to assign any variables in params in
-;; the context of the session environment.
-(defun org-babel-prep-session:abc (_session _params)
- "Return an error because abc does not support sessions."
- (error "ABC does not support sessions"))
-
-(provide 'ob-abc)
-
-;;; ob-abc.el ends here
diff --git a/lisp/org/ob-asymptote.el b/lisp/org/ob-asymptote.el
deleted file mode 100644
index bfb5b79145e..00000000000
--- a/lisp/org/ob-asymptote.el
+++ /dev/null
@@ -1,137 +0,0 @@
-;;; ob-asymptote.el --- Babel Functions for Asymptote -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2009-2021 Free Software Foundation, Inc.
-
-;; Author: Eric Schulte
-;; Keywords: literate programming, reproducible research
-;; Homepage: https://orgmode.org
-
-;; 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:
-
-;; Org-Babel support for evaluating asymptote source code.
-;;
-;; This differs from most standard languages in that
-;;
-;; 1) there is no such thing as a "session" in asymptote
-;;
-;; 2) we are generally only going to return results of type "file"
-;;
-;; 3) we are adding the "file" and "cmdline" header arguments, if file
-;; is omitted then the -V option is passed to the asy command for
-;; interactive viewing
-
-;;; Requirements:
-
-;; - The asymptote program :: http://asymptote.sourceforge.net/
-;;
-;; - asy-mode :: Major mode for editing asymptote files
-
-;;; Code:
-(require 'ob)
-
-(defvar org-babel-tangle-lang-exts)
-(add-to-list 'org-babel-tangle-lang-exts '("asymptote" . "asy"))
-
-(defvar org-babel-default-header-args:asymptote
- '((:results . "file") (:exports . "results"))
- "Default arguments when evaluating an Asymptote source block.")
-
-(defun org-babel-execute:asymptote (body params)
- "Execute a block of Asymptote code.
-This function is called by `org-babel-execute-src-block'."
- (let* ((out-file (cdr (assq :file params)))
- (format (or (file-name-extension out-file)
- "pdf"))
- (cmdline (cdr (assq :cmdline params)))
- (in-file (org-babel-temp-file "asymptote-"))
- (cmd
- (concat "asy "
- (if out-file
- (concat
- "-globalwrite -f " format
- " -o " (org-babel-process-file-name out-file))
- "-V")
- " " cmdline
- " " (org-babel-process-file-name in-file))))
- (with-temp-file in-file
- (insert (org-babel-expand-body:generic
- body params
- (org-babel-variable-assignments:asymptote params))))
- (message cmd) (shell-command cmd)
- nil)) ;; signal that output has already been written to file
-
-(defun org-babel-prep-session:asymptote (_session _params)
- "Return an error if the :session header argument is set.
-Asymptote does not support sessions."
- (error "Asymptote does not support sessions"))
-
-(defun org-babel-variable-assignments:asymptote (params)
- "Return list of asymptote statements assigning the block's variables."
- (mapcar #'org-babel-asymptote-var-to-asymptote
- (org-babel--get-vars params)))
-
-(defun org-babel-asymptote-var-to-asymptote (pair)
- "Convert an elisp value into an Asymptote variable.
-The elisp value PAIR is converted into Asymptote code specifying
-a variable of the same value."
- (let ((var (car pair))
- (val (let ((v (cdr pair)))
- (if (symbolp v) (symbol-name v) v))))
- (cond
- ((integerp val)
- (format "int %S=%S;" var val))
- ((floatp val)
- (format "real %S=%S;" var val))
- ((stringp val)
- (format "string %S=\"%s\";" var val))
- ((and (listp val) (not (listp (car val))))
- (let* ((type (org-babel-asymptote-define-type val))
- (fmt (if (eq 'string type) "\"%s\"" "%s"))
- (vect (mapconcat (lambda (e) (format fmt e)) val ", ")))
- (format "%s[] %S={%s};" type var vect)))
- ((listp val)
- (let* ((type (org-babel-asymptote-define-type val))
- (fmt (if (eq 'string type) "\"%s\"" "%s"))
- (array (mapconcat (lambda (row)
- (concat "{"
- (mapconcat (lambda (e) (format fmt e))
- row ", ")
- "}"))
- val ",")))
- (format "%S[][] %S={%s};" type var array))))))
-
-(defun org-babel-asymptote-define-type (data)
- "Determine type of DATA.
-
-DATA is a list. Return type as a symbol.
-
-The type is `string' if any element in DATA is a string.
-Otherwise, it is either `real', if some elements are floats, or
-`int'."
- (letrec ((type 'int)
- (find-type
- (lambda (row)
- (dolist (e row type)
- (cond ((listp e) (setq type (funcall find-type e)))
- ((stringp e) (throw 'exit 'string))
- ((floatp e) (setq type 'real)))))))
- (catch 'exit (funcall find-type data)) type))
-
-(provide 'ob-asymptote)
-
-;;; ob-asymptote.el ends here
diff --git a/lisp/org/ob-awk.el b/lisp/org/ob-awk.el
index b41d70f12ca..28e9d327576 100644
--- a/lisp/org/ob-awk.el
+++ b/lisp/org/ob-awk.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2011-2021 Free Software Foundation, Inc.
;; Author: Eric Schulte
+;; Maintainer: Tyler Smith <tyler@plantarum.ca>
;; Keywords: literate programming, reproducible research
;; Homepage: https://orgmode.org
@@ -58,12 +59,12 @@ This function is called by `org-babel-execute-src-block'."
(code-file (let ((file (org-babel-temp-file "awk-")))
(with-temp-file file (insert full-body)) file))
(stdin (let ((stdin (cdr (assq :stdin params))))
- (when stdin
- (let ((tmp (org-babel-temp-file "awk-stdin-"))
- (res (org-babel-ref-resolve stdin)))
- (with-temp-file tmp
- (insert (org-babel-awk-var-to-awk res)))
- tmp))))
+ (when stdin
+ (let ((tmp (org-babel-temp-file "awk-stdin-"))
+ (res (org-babel-ref-resolve stdin)))
+ (with-temp-file tmp
+ (insert (org-babel-awk-var-to-awk res)))
+ tmp))))
(cmd (mapconcat #'identity
(append
(list org-babel-awk-command
diff --git a/lisp/org/ob-calc.el b/lisp/org/ob-calc.el
index 39ebce10020..5962d387614 100644
--- a/lisp/org/ob-calc.el
+++ b/lisp/org/ob-calc.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2010-2021 Free Software Foundation, Inc.
;; Author: Eric Schulte
+;; Maintainer: Tom Gillespie <tgbugs@gmail.com>
;; Keywords: literate programming, reproducible research
;; Homepage: https://orgmode.org
@@ -90,7 +91,7 @@
(save-excursion
(with-current-buffer (get-buffer "*Calculator*")
(prog1
- (calc-eval (calc-top 1))
+ (calc-eval (calc-top 1))
(calc-pop 1)))))
(defun org-babel-calc-maybe-resolve-var (el)
diff --git a/lisp/org/ob-clojure.el b/lisp/org/ob-clojure.el
index 9834509fb03..3b995d94ce8 100644
--- a/lisp/org/ob-clojure.el
+++ b/lisp/org/ob-clojure.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2009-2021 Free Software Foundation, Inc.
;; Author: Joel Boehland, Eric Schulte, Oleh Krehel, Frederick Giasson
+;; Maintainer: Bastien Guerry <bzg@gnu.org>
;;
;; Keywords: literate programming, reproducible research
;; Homepage: https://orgmode.org
diff --git a/lisp/org/ob-comint.el b/lisp/org/ob-comint.el
index b14849df691..20ae76fadc6 100644
--- a/lisp/org/ob-comint.el
+++ b/lisp/org/ob-comint.el
@@ -93,12 +93,7 @@ or user `keyboard-quit' during execution of body."
(regexp-quote ,eoe-indicator) nil t)
(re-search-forward
comint-prompt-regexp nil t)))))
- (accept-process-output (get-buffer-process (current-buffer)))
- ;; thought the following this would allow async
- ;; background running, but I was wrong...
- ;; (run-with-timer .5 .5 'accept-process-output
- ;; (get-buffer-process (current-buffer)))
- )
+ (accept-process-output (get-buffer-process (current-buffer))))
;; replace cut dangling text
(goto-char (process-mark (get-buffer-process (current-buffer))))
(insert dangling-text)
@@ -135,7 +130,7 @@ statement (not large blocks of code)."
(accept-process-output (get-buffer-process buffer)))))
(defun org-babel-comint-eval-invisibly-and-wait-for-file
- (buffer file string &optional period)
+ (buffer file string &optional period)
"Evaluate STRING in BUFFER invisibly.
Don't return until FILE exists. Code in STRING must ensure that
FILE exists at end of evaluation."
@@ -147,6 +142,171 @@ FILE exists at end of evaluation."
(if (= (aref string (1- (length string))) ?\n) string (concat string "\n")))
(while (not (file-exists-p file)) (sit-for (or period 0.25))))
+
+;;; Async evaluation
+
+(defvar-local org-babel-comint-async-indicator nil
+ "Regular expression that `org-babel-comint-async-filter' scans for.
+It should have 2 parenthesized expressions,
+e.g. \"org_babel_async_\\(start\\|end\\|file\\)_\\(.*\\)\". The
+first parenthesized expression determines whether the token is
+delimiting a result block, or whether the result is in a file.
+If delimiting a block, the second expression gives a UUID for the
+location to insert the result. Otherwise, the result is in a tmp
+file, and the second expression gives the file name.")
+
+(defvar-local org-babel-comint-async-buffers nil
+ "List of Org mode buffers to check for Babel async output results.")
+
+(defvar-local org-babel-comint-async-file-callback nil
+ "Callback to clean and insert Babel async results from a temp file.
+The callback function takes two arguments: the alist of params of the Babel
+source block, and the name of the temp file.")
+
+(defvar-local org-babel-comint-async-chunk-callback nil
+ "Callback function to clean Babel async output results before insertion.
+Its single argument is a string consisting of output from the
+comint process. It should return a string that will be be passed
+to `org-babel-insert-result'.")
+
+(defvar-local org-babel-comint-async-dangling nil
+ "Dangling piece of the last process output, in case
+`org-babel-comint-async-indicator' is spread across multiple
+comint outputs due to buffering.")
+
+(defun org-babel-comint-use-async (params)
+ "Determine whether to use session async evaluation.
+PARAMS are the header arguments as passed to
+`org-babel-execute:lang'."
+ (let ((async (assq :async params))
+ (session (assq :session params)))
+ (and async
+ (not org-babel-exp-reference-buffer)
+ (not (equal (cdr async) "no"))
+ (not (equal (cdr session) "none")))))
+
+(defun org-babel-comint-async-filter (string)
+ "Captures Babel async output from comint buffer back to Org mode buffers.
+This function is added as a hook to `comint-output-filter-functions'.
+STRING contains the output originally inserted into the comint buffer."
+ ;; Remove outdated Org mode buffers
+ (setq org-babel-comint-async-buffers
+ (cl-loop for buf in org-babel-comint-async-buffers
+ if (buffer-live-p buf)
+ collect buf))
+ (let* ((indicator org-babel-comint-async-indicator)
+ (org-buffers org-babel-comint-async-buffers)
+ (file-callback org-babel-comint-async-file-callback)
+ (combined-string (concat org-babel-comint-async-dangling string))
+ (new-dangling combined-string)
+ ;; list of UUID's matched by `org-babel-comint-async-indicator'
+ uuid-list)
+ (with-temp-buffer
+ (insert combined-string)
+ (goto-char (point-min))
+ (while (re-search-forward indicator nil t)
+ ;; update dangling
+ (setq new-dangling (buffer-substring (point) (point-max)))
+ (cond ((equal (match-string 1) "end")
+ ;; save UUID for insertion later
+ (push (match-string 2) uuid-list))
+ ((equal (match-string 1) "file")
+ ;; insert results from tmp-file
+ (let ((tmp-file (match-string 2)))
+ (cl-loop for buf in org-buffers
+ until
+ (with-current-buffer buf
+ (save-excursion
+ (goto-char (point-min))
+ (when (search-forward tmp-file nil t)
+ (org-babel-previous-src-block)
+ (let* ((info (org-babel-get-src-block-info))
+ (params (nth 2 info))
+ (result-params
+ (cdr (assq :result-params params))))
+ (org-babel-insert-result
+ (funcall file-callback
+ (nth
+ 2 (org-babel-get-src-block-info))
+ tmp-file)
+ result-params info))
+ t))))))))
+ ;; Truncate dangling to only the most recent output
+ (when (> (length new-dangling) (length string))
+ (setq new-dangling string)))
+ (setq-local org-babel-comint-async-dangling new-dangling)
+ (when uuid-list
+ ;; Search for results in the comint buffer
+ (save-excursion
+ (goto-char (point-max))
+ (while uuid-list
+ (re-search-backward indicator)
+ (when (equal (match-string 1) "end")
+ (let* ((uuid (match-string-no-properties 2))
+ (res-str-raw
+ (buffer-substring
+ ;; move point to beginning of indicator
+ (- (match-beginning 0) 1)
+ ;; find the matching start indicator
+ (cl-loop
+ do (re-search-backward indicator)
+ until (and (equal (match-string 1) "start")
+ (equal (match-string 2) uuid))
+ finally return (+ 1 (match-end 0)))))
+ ;; Apply callback to clean up the result
+ (res-str (funcall org-babel-comint-async-chunk-callback
+ res-str-raw)))
+ ;; Search for uuid in associated org-buffers to insert results
+ (cl-loop for buf in org-buffers
+ until (with-current-buffer buf
+ (save-excursion
+ (goto-char (point-min))
+ (when (search-forward uuid nil t)
+ (org-babel-previous-src-block)
+ (let* ((info (org-babel-get-src-block-info))
+ (params (nth 2 info))
+ (result-params
+ (cdr (assq :result-params params))))
+ (org-babel-insert-result
+ res-str result-params info))
+ t))))
+ ;; Remove uuid from the list to search for
+ (setq uuid-list (delete uuid uuid-list)))))))))
+
+(defun org-babel-comint-async-register
+ (session-buffer org-buffer indicator-regexp
+ chunk-callback file-callback)
+ "Set local org-babel-comint-async variables in SESSION-BUFFER.
+ORG-BUFFER is added to `org-babel-comint-async-buffers' if not
+present. `org-babel-comint-async-indicator',
+`org-babel-comint-async-chunk-callback', and
+`org-babel-comint-async-file-callback' are set to
+INDICATOR-REGEXP, CHUNK-CALLBACK, and FILE-CALLBACK
+respectively."
+ (org-babel-comint-in-buffer session-buffer
+ (setq org-babel-comint-async-indicator indicator-regexp
+ org-babel-comint-async-chunk-callback chunk-callback
+ org-babel-comint-async-file-callback file-callback)
+ (unless (memq org-buffer org-babel-comint-async-buffers)
+ (setq org-babel-comint-async-buffers
+ (cons org-buffer org-babel-comint-async-buffers)))
+ (add-hook 'comint-output-filter-functions
+ 'org-babel-comint-async-filter nil t)))
+
+(defmacro org-babel-comint-async-delete-dangling-and-eval
+ (session-buffer &rest body)
+ "Remove dangling text in SESSION-BUFFER and evaluate BODY.
+This is analogous to `org-babel-comint-with-output', but meant
+for asynchronous output, and much shorter because inserting the
+result is delegated to `org-babel-comint-async-filter'."
+ (declare (indent 1) (debug t))
+ `(org-babel-comint-in-buffer ,session-buffer
+ (goto-char (process-mark (get-buffer-process (current-buffer))))
+ (delete-region (point) (point-max))
+ ,@body))
+
(provide 'ob-comint)
+
+
;;; ob-comint.el ends here
diff --git a/lisp/org/ob-coq.el b/lisp/org/ob-coq.el
deleted file mode 100644
index c77e8c9af69..00000000000
--- a/lisp/org/ob-coq.el
+++ /dev/null
@@ -1,80 +0,0 @@
-;;; ob-coq.el --- Babel Functions for Coq -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2010-2021 Free Software Foundation, Inc.
-
-;; Author: Eric Schulte
-;; Keywords: literate programming, reproducible research
-;; Homepage: https://orgmode.org
-
-;; 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:
-
-;; Rudimentary support for evaluating Coq code blocks. Currently only
-;; session evaluation is supported. Requires both coq.el and
-;; coq-inferior.el, both of which are distributed with Coq.
-;;
-;; https://coq.inria.fr/
-
-;;; Code:
-(require 'ob)
-
-(declare-function run-coq "ext:coq-inferior.el" (cmd))
-(declare-function coq-proc "ext:coq-inferior.el" ())
-
-(defvar coq-program-name "coqtop"
- "Name of the coq toplevel to run.")
-
-(defvar org-babel-coq-buffer "*coq*"
- "Buffer in which to evaluate coq code blocks.")
-
-(defun org-babel-coq-clean-prompt (string)
- (if (string-match "^[^[:space:]]+ < " string)
- (substring string 0 (match-beginning 0))
- string))
-
-(defun org-babel-execute:coq (body params)
- (let ((full-body (org-babel-expand-body:generic body params))
- (session (org-babel-coq-initiate-session))
- (pt (lambda ()
- (marker-position
- (process-mark (get-buffer-process (current-buffer)))))))
- (org-babel-coq-clean-prompt
- (org-babel-comint-in-buffer session
- (let ((start (funcall pt)))
- (with-temp-buffer
- (insert full-body)
- (comint-send-region (coq-proc) (point-min) (point-max))
- (comint-send-string (coq-proc)
- (if (string= (buffer-substring (- (point-max) 1) (point-max)) ".")
- "\n"
- ".\n")))
- (while (equal start (funcall pt)) (sleep-for 0.1))
- (buffer-substring start (funcall pt)))))))
-
-(defun org-babel-coq-initiate-session ()
- "Initiate a coq session.
-If there is not a current inferior-process-buffer in SESSION then
-create one. Return the initialized session."
- (unless (fboundp 'run-coq)
- (error "`run-coq' not defined, load coq-inferior.el"))
- (save-window-excursion (run-coq coq-program-name))
- (sit-for 0.1)
- (get-buffer org-babel-coq-buffer))
-
-(provide 'ob-coq)
-
-;;; ob-coq.el ends here
diff --git a/lisp/org/ob-core.el b/lisp/org/ob-core.el
index b1fd6943716..06a2a88cd49 100644
--- a/lisp/org/ob-core.el
+++ b/lisp/org/ob-core.el
@@ -290,9 +290,9 @@ environment, to override this check."
(format "Evaluate this %s code block%son your system? "
lang name-string)))
(progn
- (message "Evaluation of this %s code block%sis aborted."
- lang name-string)
- nil)))
+ (message "Evaluation of this %s code block%sis aborted."
+ lang name-string)
+ nil)))
(x (error "Unexpected value `%s' from `org-babel-check-confirm-evaluate'" x)))))
;;;###autoload
@@ -472,7 +472,35 @@ For the format of SAFE-LIST, see `org-babel-safe-header-args'."
(defvar org-babel-default-header-args
'((:session . "none") (:results . "replace") (:exports . "code")
(:cache . "no") (:noweb . "no") (:hlines . "no") (:tangle . "no"))
- "Default arguments to use when evaluating a source block.")
+ "Default arguments to use when evaluating a source block.
+
+This is a list in which each element is an alist. Each key
+corresponds to a header argument, and each value to that header's
+value. The value can either be a string or a closure that
+evaluates to a string. The closure is evaluated when the source
+block is being evaluated (e.g. during execution or export), with
+point at the source block. It is not possible to use an
+arbitrary function symbol (e.g. 'some-func), since org uses
+lexical binding. To achieve the same functionality, call the
+function within a closure (e.g. (lambda () (some-func))).
+
+To understand how closures can be used as default header
+arguments, imagine you'd like to set the file name output of a
+latex source block to a sha1 of its contents. We could achieve
+this with:
+
+(defun org-src-sha ()
+ (let ((elem (org-element-at-point)))
+ (concat (sha1 (org-element-property :value elem)) \".svg\")))
+
+(setq org-babel-default-header-args:latex
+ `((:results . \"file link replace\")
+ (:file . (lambda () (org-src-sha)))))
+
+Because the closure is evaluated with point at the source block,
+the call to `org-element-at-point' above will always retrieve
+information about the current source block.")
+
(put 'org-babel-default-header-args 'safe-local-variable
(org-babel-header-args-safe-fn org-babel-safe-header-args))
@@ -538,7 +566,7 @@ to raise errors for all languages.")
"Number of initial characters to show of a hidden results hash.")
(defvar org-babel-after-execute-hook nil
- "Hook for functions to be called after `org-babel-execute-src-block'")
+ "Hook for functions to be called after `org-babel-execute-src-block'.")
(defun org-babel-named-src-block-regexp-for-name (&optional name)
"Generate a regexp used to match a source block named NAME.
@@ -581,7 +609,17 @@ multiple blocks are being executed (e.g., in chained execution
through use of the :var header argument) this marker points to
the outer-most code block.")
-(defvar *this*)
+(defun org-babel-eval-headers (headers)
+ "Compute header list set with HEADERS.
+
+Evaluate all header arguments set to functions prior to returning
+the list of header arguments."
+ (let ((lst nil))
+ (dolist (elem headers)
+ (if (and (cdr elem) (functionp (cdr elem)))
+ (push `(,(car elem) . ,(funcall (cdr elem))) lst)
+ (push elem lst)))
+ (reverse lst)))
(defun org-babel-get-src-block-info (&optional light datum)
"Extract information from a source block or inline source block.
@@ -646,6 +684,16 @@ a list with the following pattern:
(replace-regexp-in-string
(org-src-coderef-regexp coderef) "" expand nil nil 1))))
+(defun org-babel--file-desc (params result)
+ "Retrieve file description."
+ (pcase (assq :file-desc params)
+ (`nil nil)
+ (`(:file-desc) result)
+ (`(:file-desc . ,(and (pred stringp) val)) val)))
+
+(defvar *this*) ; Dynamically bound in `org-babel-execute-src-block'
+ ; and `org-babel-read'
+
;;;###autoload
(defun org-babel-execute-src-block (&optional arg info params)
"Execute the current source code block.
@@ -749,8 +797,7 @@ block."
(let ((*this* (if (not file) result
(org-babel-result-to-file
file
- (let ((desc (assq :file-desc params)))
- (and desc (or (cdr desc) result)))))))
+ (org-babel--file-desc params result)))))
(setq result (org-babel-ref-resolve post))
(when file
(setq result-params (remove "file" result-params))))))
@@ -802,27 +849,6 @@ arguments and pop open the results in a preview buffer."
expanded (concat "*Org-Babel Preview " (buffer-name) "[ " lang " ]*"))
expanded)))
-(defun org-babel-edit-distance (s1 s2)
- "Return the edit (levenshtein) distance between strings S1 S2."
- (let* ((l1 (length s1))
- (l2 (length s2))
- (dist (vconcat (mapcar (lambda (_) (make-vector (1+ l2) nil))
- (number-sequence 1 (1+ l1)))))
- (in (lambda (i j) (aref (aref dist i) j))))
- (setf (aref (aref dist 0) 0) 0)
- (dolist (j (number-sequence 1 l2))
- (setf (aref (aref dist 0) j) j))
- (dolist (i (number-sequence 1 l1))
- (setf (aref (aref dist i) 0) i)
- (dolist (j (number-sequence 1 l2))
- (setf (aref (aref dist i) j)
- (min
- (1+ (funcall in (1- i) j))
- (1+ (funcall in i (1- j)))
- (+ (if (equal (aref s1 (1- i)) (aref s2 (1- j))) 0 1)
- (funcall in (1- i) (1- j)))))))
- (funcall in l1 l2)))
-
(defun org-babel-combine-header-arg-lists (original &rest others)
"Combine a number of lists of header argument names and arguments."
(let ((results (copy-sequence original)))
@@ -851,7 +877,7 @@ arguments and pop open the results in a preview buffer."
(match-string 4))))))
(dolist (name names)
(when (and (not (string= header name))
- (<= (org-babel-edit-distance header name) too-close)
+ (<= (org-string-distance header name) too-close)
(not (member header names)))
(error "Supplied header \"%S\" is suspiciously close to \"%S\""
header name))))
@@ -1446,7 +1472,7 @@ portions of results lines."
;; Remove overlays when changing major mode
(add-hook 'org-mode-hook
(lambda () (add-hook 'change-major-mode-hook
- #'org-babel-show-result-all 'append 'local)))
+ #'org-babel-show-result-all 'append 'local)))
(defun org-babel-params-from-properties (&optional lang no-eval)
"Retrieve source block parameters specified as properties.
@@ -1550,11 +1576,11 @@ balanced instances of \"[ \t]:\", set ALTS to ((32 9) . 58)."
(first= (lambda (str) (= ch (aref str 0)))))
(reverse
(cl-reduce (lambda (acc el)
- (let ((head (car acc)))
- (if (and head (or (funcall last= head) (funcall first= el)))
- (cons (concat head el) (cdr acc))
- (cons el acc))))
- list :initial-value nil))))
+ (let ((head (car acc)))
+ (if (and head (or (funcall last= head) (funcall first= el)))
+ (cons (concat head el) (cdr acc))
+ (cons el acc))))
+ list :initial-value nil))))
(defun org-babel-parse-header-arguments (string &optional no-eval)
"Parse header arguments in STRING.
@@ -1628,7 +1654,7 @@ shown below.
(t 'value))))
(cl-remove-if
(lambda (x) (memq (car x) '(:colname-names :rowname-names :result-params
- :result-type :var)))
+ :result-type :var)))
params))))
;; row and column names
@@ -1698,9 +1724,12 @@ of the vars, cnames and rnames."
(list
(mapcar
(lambda (var)
- (when (listp (cdr var))
+ (when (proper-list-p (cdr var))
(when (and (not (equal colnames "no"))
- (or colnames (and (eq (nth 1 (cdr var)) 'hline)
+ ;; Compatibility note: avoid `length>', which
+ ;; isn't available until Emacs 28.
+ (or colnames (and (> (length (cdr var)) 1)
+ (eq (nth 1 (cdr var)) 'hline)
(not (member 'hline (cddr (cdr var)))))))
(let ((both (org-babel-get-colnames (cdr var))))
(setq cnames (cons (cons (car var) (cdr both))
@@ -1720,7 +1749,7 @@ of the vars, cnames and rnames."
(defun org-babel-reassemble-table (table colnames rownames)
"Add column and row names to a table.
Given a TABLE and set of COLNAMES and ROWNAMES add the names
-to the table for reinsertion to org-mode."
+to the table for reinsertion to `org-mode'."
(if (listp table)
(let ((table (if (and rownames (= (length table) (length rownames)))
(org-babel-put-rownames table rownames) table)))
@@ -1755,7 +1784,7 @@ If the point is not on a source block then return nil."
"Go to the beginning of the current code block."
(interactive)
(let ((head (org-babel-where-is-src-block-head)))
- (if head (goto-char head) (error "Not currently in a code block"))))
+ (if head (goto-char head) (error "Not currently in a code block"))))
;;;###autoload
(defun org-babel-goto-named-src-block (name)
@@ -2199,6 +2228,10 @@ silent -- no results are inserted into the Org buffer but
ingested by Emacs (a potentially time consuming
process).
+none ---- no results are inserted into the Org buffer nor
+ echoed to the minibuffer. they are not processed into
+ Emacs-lisp objects at all.
+
file ---- the results are interpreted as a file path, and are
inserted into the buffer using the Org file syntax.
@@ -2256,9 +2289,8 @@ INFO may provide the values of these header arguments (in the
(setq result (org-no-properties result))
(when (member "file" result-params)
(setq result (org-babel-result-to-file
- result (when (assq :file-desc (nth 2 info))
- (or (cdr (assq :file-desc (nth 2 info)))
- result))))))
+ result
+ (org-babel--file-desc (nth 2 info) result)))))
((listp result))
(t (setq result (format "%S" result))))
(if (and result-params (member "silent" result-params))
@@ -2324,7 +2356,7 @@ INFO may provide the values of these header arguments (in the
(if results-switches (concat " " results-switches) ""))
(let ((wrap
(lambda (start finish &optional no-escape no-newlines
- inline-start inline-finish)
+ inline-start inline-finish)
(when inline
(setq start inline-start)
(setq finish inline-finish)
@@ -2553,8 +2585,9 @@ in the buffer."
(let ((element (org-element-at-point)))
(if (memq (org-element-type element)
;; Possible results types.
- '(drawer example-block export-block fixed-width item
- plain-list special-block src-block table))
+ '(drawer example-block export-block fixed-width
+ special-block src-block item plain-list table
+ latex-environment))
(save-excursion
(goto-char (min (point-max) ;for narrowed buffers
(org-element-property :end element)))
@@ -2570,9 +2603,9 @@ file's directory then expand relative links."
(let ((same-directory?
(and (buffer-file-name (buffer-base-buffer))
(not (string= (expand-file-name default-directory)
- (expand-file-name
- (file-name-directory
- (buffer-file-name (buffer-base-buffer)))))))))
+ (expand-file-name
+ (file-name-directory
+ (buffer-file-name (buffer-base-buffer)))))))))
(format "[[file:%s]%s]"
(if (and default-directory
(buffer-file-name (buffer-base-buffer)) same-directory?)
@@ -2706,12 +2739,17 @@ parameters when merging lists."
results-exclusive-groups
results
(split-string
- (if (stringp value) value (eval value t))))))
+ (cond ((stringp value) value)
+ ((functionp value) (funcall value))
+ (t (eval value t)))))))
(`(:exports . ,value)
(setq exports (funcall merge
exports-exclusive-groups
exports
- (split-string (or value "")))))
+ (split-string
+ (cond ((and value (functionp value)) (funcall value))
+ (value value)
+ (t ""))))))
;; Regular keywords: any value overwrites the previous one.
(_ (setq params (cons pair (assq-delete-all (car pair) params)))))))
;; Handle `:var' and clear out colnames and rownames for replaced
@@ -2726,14 +2764,14 @@ parameters when merging lists."
(cdr (assq param params))))
(setq params
(cl-remove-if (lambda (pair) (and (equal (car pair) param)
- (null (cdr pair))))
+ (null (cdr pair))))
params)))))
;; Handle other special keywords, which accept multiple values.
(setq params (nconc (list (cons :results (mapconcat #'identity results " "))
(cons :exports (mapconcat #'identity exports " ")))
params))
;; Return merged params.
- params))
+ (org-babel-eval-headers params)))
(defun org-babel-noweb-p (params context)
"Check if PARAMS require expansion in CONTEXT.
@@ -2842,8 +2880,6 @@ block but are passed literally to the \"example-block\"."
(setq cache nil)
(let ((raw (org-babel-ref-resolve id)))
(if (stringp raw) raw (format "%S" raw))))
- ;; Retrieve from the Library of Babel.
- ((nth 2 (assoc-string id org-babel-library-of-babel)))
;; Return the contents of headlines literally.
((org-babel-ref-goto-headline-id id)
(org-babel-ref-headline-body))
@@ -2856,6 +2892,8 @@ block but are passed literally to the \"example-block\"."
(not (org-in-commented-heading-p))
(funcall expand-body
(org-babel-get-src-block-info t))))))
+ ;; Retrieve from the Library of Babel.
+ ((nth 2 (assoc-string id org-babel-library-of-babel)))
;; All Noweb references were cached in a previous
;; run. Extract the information from the cache.
((hash-table-p cache)
@@ -2976,7 +3014,7 @@ block but are passed literally to the \"example-block\"."
(defun org-babel-read (cell &optional inhibit-lisp-eval)
"Convert the string value of CELL to a number if appropriate.
-Otherwise if CELL looks like lisp (meaning it starts with a
+Otherwise if CELL looks like Lisp (meaning it starts with a
\"(\", \"\\='\", \"\\=`\" or a \"[\") then read and evaluate it as
lisp, otherwise return it unmodified as a string. Optional
argument INHIBIT-LISP-EVAL inhibits lisp evaluation for
@@ -3148,7 +3186,7 @@ For the format of SAFE-LIST, see `org-babel-safe-header-args'."
(and entry
(consp entry)
(cond ((functionp (cdr entry))
- (funcall (cdr entry) (cdr pair)))
+ (funcall (cdr entry) (cdr pair)))
((listp (cdr entry))
(member (cdr pair) (cdr entry)))
(t nil)))))))
@@ -3168,10 +3206,10 @@ Otherwise, the :file parameter is treated as a full file name,
and the output file name is the directory (as calculated above)
plus the parameter value."
(let* ((file-cons (assq :file params))
- (file-ext-cons (assq :file-ext params))
- (file-ext (cdr-safe file-ext-cons))
- (dir (cdr-safe (assq :output-dir params)))
- fname)
+ (file-ext-cons (assq :file-ext params))
+ (file-ext (cdr-safe file-ext-cons))
+ (dir (cdr-safe (assq :output-dir params)))
+ fname)
;; create the output-dir if it does not exist
(when dir
(make-directory dir t))
diff --git a/lisp/org/ob-dot.el b/lisp/org/ob-dot.el
index d13261b340e..8e05a59f207 100644
--- a/lisp/org/ob-dot.el
+++ b/lisp/org/ob-dot.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2009-2021 Free Software Foundation, Inc.
;; Author: Eric Schulte
+;; Maintainer: Justin Abrahms
;; Keywords: literate programming, reproducible research
;; Homepage: https://orgmode.org
@@ -25,7 +26,7 @@
;; Org-Babel support for evaluating dot source code.
;;
-;; For information on dot see http://www.graphviz.org/
+;; For information on dot see https://www.graphviz.org/
;;
;; This differs from most standard languages in that
;;
diff --git a/lisp/org/ob-ebnf.el b/lisp/org/ob-ebnf.el
deleted file mode 100644
index 58666a4ded0..00000000000
--- a/lisp/org/ob-ebnf.el
+++ /dev/null
@@ -1,81 +0,0 @@
-;;; ob-ebnf.el --- Babel Functions for EBNF -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2013-2021 Free Software Foundation, Inc.
-
-;; Author: Michael Gauland
-;; Keywords: literate programming, reproducible research
-;; Homepage: https://orgmode.org
-
-;; 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:
-
-;; Org-Babel support for using ebnf2ps to generate encapsulated postscript
-;; railroad diagrams. It recognizes these arguments:
-;;
-;; :file is required; it must include the extension '.eps.' All the rules
-;; in the block will be drawn in the same file. This is done by
-;; inserting a '[<file>' comment at the start of the block (see the
-;; documentation for ebnf-eps-buffer for more information).
-;;
-;; :style specifies a value in ebnf-style-database. This provides the
-;; ability to customize the output. The style can also specify the
-;; grammar syntax (by setting ebnf-syntax); note that only ebnf,
-;; iso-ebnf, and yacc are supported by this file.
-
-;;; Requirements:
-
-;;; Code:
-(require 'ob)
-(require 'ebnf2ps)
-
-;; optionally declare default header arguments for this language
-(defvar org-babel-default-header-args:ebnf '((:style . nil)))
-
-;; Use ebnf-eps-buffer to produce an encapsulated postscript file.
-;;
-(defun org-babel-execute:ebnf (body params)
- "Execute a block of Ebnf code with org-babel.
-This function is called by `org-babel-execute-src-block'."
- (save-excursion
- (let* ((dest-file (cdr (assq :file params)))
- (dest-dir (file-name-directory dest-file))
- (dest-root (file-name-sans-extension
- (file-name-nondirectory dest-file)))
- (style (cdr (assq :style params)))
- (result nil))
- (with-temp-buffer
- (when style (ebnf-push-style style))
- (let ((comment-format
- (cond ((string= ebnf-syntax 'yacc) "/*%s*/")
- ((string= ebnf-syntax 'ebnf) ";%s")
- ((string= ebnf-syntax 'iso-ebnf) "(*%s*)")
- (t (setq result
- (format "EBNF error: format %s not supported."
- ebnf-syntax))))))
- (setq ebnf-eps-prefix dest-dir)
- (insert (format comment-format (format "[%s" dest-root)))
- (newline)
- (insert body)
- (newline)
- (insert (format comment-format (format "]%s" dest-root)))
- (ebnf-eps-buffer)
- (when style (ebnf-pop-style))))
- result)))
-
-(provide 'ob-ebnf)
-
-;;; ob-ebnf.el ends here
diff --git a/lisp/org/ob-eshell.el b/lisp/org/ob-eshell.el
index 6ae0fc613dd..d74c4fc43f9 100644
--- a/lisp/org/ob-eshell.el
+++ b/lisp/org/ob-eshell.el
@@ -3,8 +3,9 @@
;; Copyright (C) 2018-2021 Free Software Foundation, Inc.
;; Author: stardiviner <numbchild@gmail.com>
+;; Maintainer: stardiviner <numbchild@gmail.com>
+;; Homepage: https://github.com/stardiviner/ob-eshell
;; Keywords: literate programming, reproducible research
-;; Homepage: https://orgmode.org
;; This file is part of GNU Emacs.
diff --git a/lisp/org/ob-eval.el b/lisp/org/ob-eval.el
index b0fca7bd95b..cfd80222550 100644
--- a/lisp/org/ob-eval.el
+++ b/lisp/org/ob-eval.el
@@ -41,20 +41,22 @@
(display-buffer buf))
(message "Babel evaluation exited with code %S" exit-code))
-(defun org-babel-eval (cmd body)
- "Run CMD on BODY.
-If CMD succeeds then return its results, otherwise display
-STDERR with `org-babel-eval-error-notify'."
- (let ((err-buff (get-buffer-create " *Org-Babel Error*")) exit-code)
- (with-current-buffer err-buff (erase-buffer))
+(defun org-babel-eval (command query)
+ "Run COMMAND on QUERY.
+Writes QUERY into a temp-buffer that is processed with
+`org-babel--shell-command-on-region'. If COMMAND succeeds then return
+its results, otherwise display STDERR with
+`org-babel-eval-error-notify'."
+ (let ((error-buffer (get-buffer-create " *Org-Babel Error*")) exit-code)
+ (with-current-buffer error-buffer (erase-buffer))
(with-temp-buffer
- (insert body)
+ (insert query)
(setq exit-code
(org-babel--shell-command-on-region
- (point-min) (point-max) cmd err-buff))
+ command error-buffer))
(if (or (not (numberp exit-code)) (> exit-code 0))
(progn
- (with-current-buffer err-buff
+ (with-current-buffer error-buffer
(org-babel-eval-error-notify exit-code (buffer-string)))
(save-excursion
(when (get-buffer org-babel-error-buffer-name)
@@ -71,26 +73,19 @@ STDERR with `org-babel-eval-error-notify'."
(with-temp-buffer (insert-file-contents file)
(buffer-string)))
-(defun org-babel--shell-command-on-region (start end command error-buffer)
+(defun org-babel--shell-command-on-region (command error-buffer)
"Execute COMMAND in an inferior shell with region as input.
+Stripped down version of `shell-command-on-region' for internal use in
+Babel only. This lets us work around errors in the original function
+in various versions of Emacs. This expects the query to be run to be
+in the current temp buffer. This is written into
+input-file. ERROR-BUFFER is the name of the file which
+`org-babel-eval' has created to use for any error messages that are
+returned."
-Stripped down version of shell-command-on-region for internal use
-in Babel only. This lets us work around errors in the original
-function in various versions of Emacs.
-"
(let ((input-file (org-babel-temp-file "ob-input-"))
(error-file (if error-buffer (org-babel-temp-file "ob-error-") nil))
- ;; Unfortunately, `executable-find' does not support file name
- ;; handlers. Therefore, we could use it in the local case
- ;; only.
- (shell-file-name
- (cond ((and (not (file-remote-p default-directory))
- (executable-find shell-file-name))
- shell-file-name)
- ((file-executable-p
- (concat (file-remote-p default-directory) shell-file-name))
- shell-file-name)
- ("/bin/sh")))
+ (shell-file-name (org-babel--get-shell-file-name))
exit-status)
;; There is an error in `process-file' when `error-file' exists.
;; This is fixed in Emacs trunk as of 2012-12-21; let's use this
@@ -99,18 +94,13 @@ function in various versions of Emacs.
(delete-file error-file))
;; we always call this with 'replace, remove conditional
;; Replace specified region with output from command.
- (let ((swap (< start end)))
- (goto-char start)
- (push-mark (point) 'nomsg)
- (write-region start end input-file)
- (delete-region start end)
- (setq exit-status
- (process-file shell-file-name input-file
- (if error-file
- (list t error-file)
- t)
- nil shell-command-switch command))
- (when swap (exchange-point-and-mark)))
+ (org-babel--write-temp-buffer-input-file input-file)
+ (setq exit-status
+ (process-file shell-file-name input-file
+ (if error-file
+ (list t error-file)
+ t)
+ nil shell-command-switch command))
(when (and input-file (file-exists-p input-file)
;; bind org-babel--debug-input around the call to keep
@@ -135,6 +125,16 @@ function in various versions of Emacs.
(delete-file error-file))
exit-status))
+(defun org-babel--write-temp-buffer-input-file (input-file)
+ "Write the contents of the current temp buffer into INPUT-FILE."
+ (let ((start (point-min))
+ (end (point-max)))
+ (goto-char start)
+ (push-mark (point) 'nomsg)
+ (write-region start end input-file)
+ (delete-region start end)
+ (exchange-point-and-mark)))
+
(defun org-babel-eval-wipe-error-buffer ()
"Delete the contents of the Org code block error buffer.
This buffer is named by `org-babel-error-buffer-name'."
@@ -142,6 +142,19 @@ This buffer is named by `org-babel-error-buffer-name'."
(with-current-buffer org-babel-error-buffer-name
(delete-region (point-min) (point-max)))))
+(defun org-babel--get-shell-file-name ()
+ "Return system `shell-file-name', defaulting to /bin/sh.
+Unfortunately, `executable-find' does not support file name
+handlers. Therefore, we could use it in the local case only."
+ ;; FIXME: This is generic enough that it should probably be in emacs, not org-mode
+ (cond ((and (not (file-remote-p default-directory))
+ (executable-find shell-file-name))
+ shell-file-name)
+ ((file-executable-p
+ (concat (file-remote-p default-directory) shell-file-name))
+ shell-file-name)
+ ("/bin/sh")))
+
(provide 'ob-eval)
;;; ob-eval.el ends here
diff --git a/lisp/org/ob-exp.el b/lisp/org/ob-exp.el
index e851ff624a7..d10d228eba8 100644
--- a/lisp/org/ob-exp.el
+++ b/lisp/org/ob-exp.el
@@ -216,8 +216,11 @@ this template."
(delete-region begin end)
(insert replacement)))))
((or `babel-call `inline-babel-call)
- (org-babel-exp-do-export (org-babel-lob-get-info element)
- 'lob)
+ (org-babel-exp-do-export
+ (or (org-babel-lob-get-info element)
+ (user-error "Unknown Babel reference: %s"
+ (org-element-property :call element)))
+ 'lob)
(let ((rep
(org-fill-template
org-babel-exp-call-line-template
@@ -289,11 +292,11 @@ this template."
"Return a string with the exported content of a code block.
The function respects the value of the :exports header argument."
(let ((silently (lambda () (let ((session (cdr (assq :session (nth 2 info)))))
- (unless (equal "none" session)
- (org-babel-exp-results info type 'silent)))))
+ (unless (equal "none" session)
+ (org-babel-exp-results info type 'silent)))))
(clean (lambda () (if (eq type 'inline)
- (org-babel-remove-inline-result)
- (org-babel-remove-result info)))))
+ (org-babel-remove-inline-result)
+ (org-babel-remove-result info)))))
(pcase (or (cdr (assq :exports (nth 2 info))) "code")
("none" (funcall silently) (funcall clean) "")
("code" (funcall silently) (funcall clean) (org-babel-exp-code info type))
@@ -357,9 +360,12 @@ replaced with its value."
(org-fill-template
(if (eq type 'inline)
org-babel-exp-inline-code-template
- org-babel-exp-code-template)
+ org-babel-exp-code-template)
`(("lang" . ,(nth 0 info))
- ("body" . ,(org-escape-code-in-string (nth 1 info)))
+ ;; Inline source code should not be escaped.
+ ("body" . ,(let ((body (nth 1 info)))
+ (if (eq type 'inline) body
+ (org-escape-code-in-string body))))
("switches" . ,(let ((f (nth 3 info)))
(and (org-string-nw-p f) (concat " " f))))
("flags" . ,(let ((f (assq :flags (nth 2 info))))
@@ -390,10 +396,10 @@ inhibit insertion of results into the buffer."
(setf (nth 1 info) body)
(setf (nth 2 info)
(org-babel-exp--at-source
- (org-babel-process-params
- (org-babel-merge-params
- (nth 2 info)
- `((:results . ,(if silent "silent" "replace")))))))
+ (org-babel-process-params
+ (org-babel-merge-params
+ (nth 2 info)
+ `((:results . ,(if silent "silent" "replace")))))))
(pcase type
(`block (org-babel-execute-src-block nil info))
(`inline
diff --git a/lisp/org/ob-forth.el b/lisp/org/ob-forth.el
index 3b521bc4d95..74dbc021700 100644
--- a/lisp/org/ob-forth.el
+++ b/lisp/org/ob-forth.el
@@ -75,8 +75,8 @@ This function is called by `org-babel-execute-src-block'."
((string= "\n:" case)
;; Report errors.
(org-babel-eval-error-notify 1
- (buffer-substring
- (+ (match-beginning 0) 1) (point-max)))
+ (buffer-substring
+ (+ (match-beginning 0) 1) (point-max)))
nil))))
(split-string (org-trim
(org-babel-expand-body:generic body params))
diff --git a/lisp/org/ob-fortran.el b/lisp/org/ob-fortran.el
index 99afa0d963d..2e55498003b 100644
--- a/lisp/org/ob-fortran.el
+++ b/lisp/org/ob-fortran.el
@@ -40,9 +40,11 @@
(defvar org-babel-default-header-args:fortran '())
-(defvar org-babel-fortran-compiler "gfortran"
- "fortran command used to compile a fortran source code file into an
- executable.")
+(defcustom org-babel-fortran-compiler "gfortran"
+ "Fortran command used to compile Fortran source code file."
+ :group 'org-babel
+ :package-version '(Org . "9.5")
+ :type 'string)
(defun org-babel-execute:fortran (body params)
"This function should only be called by `org-babel-execute:fortran'."
@@ -155,7 +157,7 @@ of the same value."
(format "real, parameter :: %S(%d) = %s\n"
var (length val) (org-babel-fortran-transform-list val)))
(t
- (error "the type of parameter %s is not supported by ob-fortran" var)))))
+ (error "The type of parameter %s is not supported by ob-fortran" var)))))
(defun org-babel-fortran-transform-list (val)
"Return a fortran representation of enclose syntactic lists."
diff --git a/lisp/org/ob-gnuplot.el b/lisp/org/ob-gnuplot.el
index 6489c23f570..8c4a5957b99 100644
--- a/lisp/org/ob-gnuplot.el
+++ b/lisp/org/ob-gnuplot.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2009-2021 Free Software Foundation, Inc.
;; Author: Eric Schulte
+;; Maintainer: Ihor Radchenko <yantar92@gmail.com>
;; Keywords: literate programming, reproducible research
;; Homepage: https://orgmode.org
@@ -33,7 +34,7 @@
;;; Requirements:
-;; - gnuplot :: http://www.gnuplot.info/
+;; - gnuplot :: https://www.gnuplot.info/
;;
;; - gnuplot-mode :: you can search the web for the latest active one.
@@ -47,6 +48,8 @@
(declare-function gnuplot-send-string-to-gnuplot "ext:gnuplot-mode" (str txt))
(declare-function gnuplot-send-buffer-to-gnuplot "ext:gnuplot-mode" ())
+(defvar org-babel-temporary-directory)
+
(defvar org-babel-default-header-args:gnuplot
'((:results . "file") (:exports . "results") (:session . nil))
"Default arguments to use when evaluating a gnuplot source block.")
@@ -85,14 +88,29 @@ code."
(cons
(car pair) ;; variable name
(let* ((val (cdr pair)) ;; variable value
- (lp (listp val)))
+ (lp (proper-list-p val)))
(if lp
(org-babel-gnuplot-table-to-data
(let* ((first (car val))
(tablep (or (listp first) (symbolp first))))
(if tablep val (mapcar 'list val)))
(org-babel-temp-file "gnuplot-") params)
- val))))
+ (if (and (stringp val)
+ (file-remote-p val) ;; check if val is a remote file
+ (file-exists-p val)) ;; call to file-exists-p is slow, maybe remove it
+ (let* ((local-name (concat ;; create a unique filename to avoid multiple downloads
+ org-babel-temporary-directory
+ "/gnuplot/"
+ (file-remote-p val 'host)
+ (org-babel-local-file-name val))))
+ (if (and (file-exists-p local-name) ;; only download file if remote is newer
+ (file-newer-than-file-p local-name val))
+ local-name
+ (make-directory (file-name-directory local-name) t)
+ (copy-file val local-name t)
+ ))
+ val
+ )))))
(org-babel--get-vars params))))
(defun org-babel-expand-body:gnuplot (body params)
@@ -272,7 +290,7 @@ Pass PARAMS through to `orgtbl-to-generic' when exporting TABLE."
(orgtbl-to-generic
table
(org-combine-plists
- '(:sep "\t" :fmt org-babel-gnuplot-quote-tsv-field)
+ '(:sep "\t" :fmt org-babel-gnuplot-quote-tsv-field :raw t :backend ascii)
params)))))
data-file)
diff --git a/lisp/org/ob-groovy.el b/lisp/org/ob-groovy.el
index fa847dd0a2b..b3ff34aac3e 100644
--- a/lisp/org/ob-groovy.el
+++ b/lisp/org/ob-groovy.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2013-2021 Free Software Foundation, Inc.
;; Author: Miro Bezjak
+;; Maintainer: Palak Mathur
;; Keywords: literate programming, reproducible research
;; Homepage: https://orgmode.org
@@ -25,7 +26,7 @@
;; Currently only supports the external execution. No session support yet.
;;; Requirements:
-;; - Groovy language :: http://groovy.codehaus.org
+;; - Groovy language :: https://groovy-lang.org
;; - Groovy major mode :: Can be installed from MELPA or
;; https://github.com/russel/Emacs-Groovy-Mode
diff --git a/lisp/org/ob-haskell.el b/lisp/org/ob-haskell.el
index d7ac1b04b36..971e1ce6af8 100644
--- a/lisp/org/ob-haskell.el
+++ b/lisp/org/ob-haskell.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2009-2021 Free Software Foundation, Inc.
;; Author: Eric Schulte
+;; Maintainer: Lawrence Bottorff <borgauf@gmail.com>
;; Keywords: literate programming, reproducible research
;; Homepage: https://orgmode.org
@@ -33,9 +34,9 @@
;;; Requirements:
-;; - haskell-mode: http://www.iro.umontreal.ca/~monnier/elisp/#haskell-mode
-;; - inf-haskell: http://www.iro.umontreal.ca/~monnier/elisp/#haskell-mode
-;; - (optionally) lhs2tex: http://people.cs.uu.nl/andres/lhs2tex/
+;; - haskell-mode: https://www.iro.umontreal.ca/~monnier/elisp/#haskell-mode
+;; - inf-haskell: https://www.iro.umontreal.ca/~monnier/elisp/#haskell-mode
+;; - (optionally) lhs2tex: https://people.cs.uu.nl/andres/lhs2tex/
;;; Code:
(require 'ob)
@@ -69,11 +70,11 @@ a parameter, such as \"ghc -v\"."
:package-version '(Org "9.4")
:type 'string)
-(defconst org-babel-header-args:haskell '(compile . :any)
+(defconst org-babel-header-args:haskell '((compile . :any))
"Haskell-specific header arguments.")
(defun org-babel-haskell-execute (body params)
- "This function should only be called by `org-babel-execute:haskell'"
+ "This function should only be called by `org-babel-execute:haskell'."
(let* ((tmp-src-file (org-babel-temp-file "Haskell-src-" ".hs"))
(tmp-bin-file
(org-babel-process-file-name
diff --git a/lisp/org/ob-hledger.el b/lisp/org/ob-hledger.el
deleted file mode 100644
index 48dcb8cea1a..00000000000
--- a/lisp/org/ob-hledger.el
+++ /dev/null
@@ -1,69 +0,0 @@
-;;; ob-hledger.el --- Babel Functions for hledger -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2010-2021 Free Software Foundation, Inc.
-
-;; Author: Simon Michael
-;; Keywords: literate programming, reproducible research, plain text accounting
-;; Homepage: https://orgmode.org
-
-;; 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:
-
-;; Babel support for evaluating hledger entries.
-;;
-;; Based on ob-ledger.el.
-;; If the source block is empty, hledger will use a default journal file,
-;; probably ~/.hledger.journal (it may not notice your $LEDGER_FILE env var).
-;; So make ~/.hledger.journal a symbolic link to the real file if necessary.
-
-;; TODO Unit tests are more than welcome, too.
-
-;;; Code:
-(require 'ob)
-
-(defvar org-babel-default-header-args:hledger
- '((:results . "output") (:exports . "results") (:cmdline . "bal"))
- "Default arguments to use when evaluating a hledger source block.")
-
-(defun org-babel-execute:hledger (body params)
- "Execute a block of hledger entries with org-babel.
-This function is called by `org-babel-execute-src-block'."
- (message "executing hledger source code block")
- (letrec ( ;(result-params (split-string (or (cdr (assq :results params)) "")))
- (cmdline (cdr (assq :cmdline params)))
- (in-file (org-babel-temp-file "hledger-"))
- (out-file (org-babel-temp-file "hledger-output-"))
- (hledgercmd (concat "hledger"
- (if (> (length body) 0)
- (concat " -f " (org-babel-process-file-name in-file))
- "")
- " " cmdline)))
- (with-temp-file in-file (insert body))
-;; TODO This is calling for some refactoring:
-;; (concat "hledger" (if ...) " " cmdline)
-;; could be built only once and bound to a symbol.
- (message "%s" hledgercmd)
- (with-output-to-string
- (shell-command (concat hledgercmd " > " (org-babel-process-file-name out-file))))
- (with-temp-buffer (insert-file-contents out-file) (buffer-string))))
-
-(defun org-babel-prep-session:hledger (_session _params)
- (error "hledger does not support sessions"))
-
-(provide 'ob-hledger)
-
-;;; ob-hledger.el ends here
diff --git a/lisp/org/ob-io.el b/lisp/org/ob-io.el
deleted file mode 100644
index 63d2b6cf35e..00000000000
--- a/lisp/org/ob-io.el
+++ /dev/null
@@ -1,105 +0,0 @@
-;;; ob-io.el --- Babel Functions for Io -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2012-2021 Free Software Foundation, Inc.
-
-;; Author: Andrzej Lichnerowicz
-;; Keywords: literate programming, reproducible research
-;; Homepage: https://orgmode.org
-
-;; 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:
-;; Currently only supports the external execution. No session support yet.
-;; :results output -- runs in scripting mode
-;; :results output repl -- runs in repl mode
-
-;;; Requirements:
-;; - Io language :: http://iolanguage.org/
-;; - Io major mode :: Can be installed from Io sources
-;; https://github.com/stevedekorte/io/blob/master/extras/SyntaxHighlighters/Emacs/io-mode.el
-
-;;; Code:
-(require 'ob)
-
-(defvar org-babel-tangle-lang-exts) ;; Autoloaded
-(add-to-list 'org-babel-tangle-lang-exts '("io" . "io"))
-(defvar org-babel-default-header-args:io '())
-(defvar org-babel-io-command "io"
- "Name of the command to use for executing Io code.")
-
-(defun org-babel-execute:io (body params)
- "Execute a block of Io code with org-babel.
-This function is called by `org-babel-execute-src-block'."
- (message "executing Io source code block")
- (let* ((processed-params (org-babel-process-params params))
- (session (org-babel-io-initiate-session (nth 0 processed-params)))
- (result-params (nth 2 processed-params))
- (result-type (cdr (assq :result-type params)))
- (full-body (org-babel-expand-body:generic
- body params))
- (result (org-babel-io-evaluate
- session full-body result-type result-params)))
-
- (org-babel-reassemble-table
- result
- (org-babel-pick-name
- (cdr (assq :colname-names params)) (cdr (assq :colnames params)))
- (org-babel-pick-name
- (cdr (assq :rowname-names params)) (cdr (assq :rownames params))))))
-
-(defvar org-babel-io-wrapper-method
- "(
-%s
-) asString print
-")
-
-
-(defun org-babel-io-evaluate (session body &optional result-type result-params)
- "Evaluate BODY in external Io process.
-If RESULT-TYPE equals `output' then return standard output as a string.
-If RESULT-TYPE equals `value' then return the value of the last statement
-in BODY as elisp."
- (when session (error "Sessions are not (yet) supported for Io"))
- (pcase result-type
- (`output
- (if (member "repl" result-params)
- (org-babel-eval org-babel-io-command body)
- (let ((src-file (org-babel-temp-file "io-")))
- (progn (with-temp-file src-file (insert body))
- (org-babel-eval
- (concat org-babel-io-command " " src-file) "")))))
- (`value (let* ((src-file (org-babel-temp-file "io-"))
- (wrapper (format org-babel-io-wrapper-method body)))
- (with-temp-file src-file (insert wrapper))
- (let ((raw (org-babel-eval
- (concat org-babel-io-command " " src-file) "")))
- (org-babel-result-cond result-params
- raw
- (org-babel-script-escape raw)))))))
-
-(defun org-babel-prep-session:io (_session _params)
- "Prepare SESSION according to the header arguments specified in PARAMS."
- (error "Sessions are not (yet) supported for Io"))
-
-(defun org-babel-io-initiate-session (&optional _session)
- "If there is not a current inferior-process-buffer in SESSION
-then create. Return the initialized session. Sessions are not
-supported in Io."
- nil)
-
-(provide 'ob-io)
-
-;;; ob-io.el ends here
diff --git a/lisp/org/ob-java.el b/lisp/org/ob-java.el
index b1d517e94aa..dd3538743db 100644
--- a/lisp/org/ob-java.el
+++ b/lisp/org/ob-java.el
@@ -1,8 +1,10 @@
-;;; ob-java.el --- Babel Functions for Java -*- lexical-binding: t; -*-
+;;; ob-java.el --- org-babel functions for java evaluation -*- lexical-binding: t -*-
;; Copyright (C) 2011-2021 Free Software Foundation, Inc.
-;; Author: Eric Schulte
+;; Authors: Eric Schulte
+;; Dan Davison
+;; Maintainer: Ian Martins <ianxm@jhu.edu>
;; Keywords: literate programming, reproducible research
;; Homepage: https://orgmode.org
@@ -23,8 +25,7 @@
;;; Commentary:
-;; Currently this only supports the external compilation and execution
-;; of java code blocks (i.e., no session support).
+;; Org-Babel support for evaluating java source code.
;;; Code:
(require 'ob)
@@ -32,52 +33,457 @@
(defvar org-babel-tangle-lang-exts)
(add-to-list 'org-babel-tangle-lang-exts '("java" . "java"))
+(defvar org-babel-temporary-directory) ; from ob-core
+
+(defvar org-babel-default-header-args:java '((:results . "output")
+ (:dir . "."))
+ "Default header args for java source blocks.
+The docs say functional mode should be the default [1], but
+ob-java didn't originally support functional mode, so we keep
+scripting mode as the default for now to maintain previous
+behavior.
+
+Most languages write tempfiles to babel's temporary directory,
+but ob-java originally had to write them to the current
+directory, so we keep that as the default behavior.
+
+[1] https://orgmode.org/manual/Results-of-Evaluation.html")
+
+(defconst org-babel-header-args:java '((imports . :any))
+ "Java-specific header arguments.")
+
(defcustom org-babel-java-command "java"
"Name of the java command.
-May be either a command in the path, like java
-or an absolute path name, like /usr/local/bin/java
-parameters may be used, like java -verbose"
+May be either a command in the path, like java or an absolute
+path name, like /usr/local/bin/java. Parameters may be used,
+like java -verbose."
:group 'org-babel
- :version "24.3"
+ :package-version '(Org . "9.5")
:type 'string)
(defcustom org-babel-java-compiler "javac"
"Name of the java compiler.
-May be either a command in the path, like javac
-or an absolute path name, like /usr/local/bin/javac
-parameters may be used, like javac -verbose"
+May be either a command in the path, like javac or an absolute
+path name, like /usr/local/bin/javac. Parameters may be used,
+like javac -verbose."
+ :group 'org-babel
+ :package-version '(Org . "9.5")
+ :type 'string)
+
+(defcustom org-babel-java-hline-to "null"
+ "Replace hlines in incoming tables with this when translating to java."
:group 'org-babel
- :version "24.3"
+ :package-version '(Org . "9.5")
:type 'string)
+(defcustom org-babel-java-null-to 'hline
+ "Replace `null' in java tables with this before returning."
+ :group 'org-babel
+ :package-version '(Org . "9.5")
+ :type 'symbol)
+
+(defconst org-babel-java--package-re (rx line-start (0+ space) "package"
+ (1+ space) (group (1+ (in alnum ?_ ?.))) ; capture the package name
+ (0+ space) ?\; line-end)
+ "Regexp for the package statement.")
+(defconst org-babel-java--imports-re (rx line-start (0+ space) "import"
+ (opt (1+ space) "static")
+ (1+ space) (group (1+ (in alnum ?_ ?. ?*))) ; capture the fully qualified class name
+ (0+ space) ?\; line-end)
+ "Regexp for import statements.")
+(defconst org-babel-java--class-re (rx line-start (0+ space) (opt (seq "public" (1+ space)))
+ "class" (1+ space)
+ (group (1+ (in alnum ?_))) ; capture the class name
+ (0+ space) ?{)
+ "Regexp for the class declaration.")
+(defconst org-babel-java--main-re
+ (rx line-start (0+ space) "public"
+ (1+ space) "static"
+ (1+ space) "void"
+ (1+ space) "main"
+ (0+ space) ?\(
+ (0+ space) "String"
+ (1+ (in alnum ?_ ?\[ ?\] space)) ; "[] args" or "args[]"
+ ?\)
+ (0+ space) (opt "throws" (1+ (in alnum ?_ ?, ?. space)))
+ ?{)
+ "Regexp for the main method declaration.")
+(defconst org-babel-java--any-method-re
+ (rx line-start
+ (0+ space) (opt (seq (1+ alnum) (1+ space))) ; visibility
+ (opt (seq "static" (1+ space))) ; binding
+ (1+ (in alnum ?_ ?\[ ?\])) ; return type
+ (1+ space) (1+ (in alnum ?_)) ; method name
+ (0+ space) ?\(
+ (0+ (in alnum ?_ ?\[ ?\] ?, space)) ; params
+ ?\)
+ (0+ space) (opt "throws" (1+ (in alnum ?_ ?, ?. space)))
+ ?{)
+ "Regexp for any method.")
+(defconst org-babel-java--result-wrapper "\n public static String __toString(Object val) {
+ if (val instanceof String) {
+ return \"\\\"\" + val + \"\\\"\";
+ } else if (val == null) {
+ return \"null\";
+ } else if (val.getClass().isArray()) {
+ StringBuffer sb = new StringBuffer();
+ Object[] vals = (Object[])val;
+ sb.append(\"[\");
+ for (int ii=0; ii<vals.length; ii++) {
+ sb.append(__toString(vals[ii]));
+ if (ii<vals.length-1)
+ sb.append(\",\");
+ }
+ sb.append(\"]\");
+ return sb.toString();
+ } else if (val instanceof List) {
+ StringBuffer sb = new StringBuffer();
+ List vals = (List)val;
+ sb.append(\"[\");
+ for (int ii=0; ii<vals.size(); ii++) {
+ sb.append(__toString(vals.get(ii)));
+ if (ii<vals.size()-1)
+ sb.append(\",\");
+ }
+ sb.append(\"]\");
+ return sb.toString();
+ } else {
+ return String.valueOf(val);
+ }
+ }
+
+ public static void main(String[] args) throws IOException {
+ BufferedWriter output = new BufferedWriter(new FileWriter(\"%s\"));
+ output.write(__toString(_main(args)));
+ output.close();
+ }"
+ "Code to inject into a class so that we can capture the value it returns.
+This implementation was inspired by ob-python, although not as
+elegant. This modified the source block to write out the value
+it wants to return to a temporary file so that ob-java can read
+it back. The name of the temporary file to write must be
+replaced in this string.")
+
(defun org-babel-execute:java (body params)
- (let* ((classname (or (cdr (assq :classname params))
- (error
- "Can't compile a java block without a classname")))
- (packagename (file-name-directory classname))
- (src-file (concat classname ".java"))
- (cmpflag (or (cdr (assq :cmpflag params)) ""))
- (cmdline (or (cdr (assq :cmdline params)) ""))
- (cmdargs (or (cdr (assq :cmdargs params)) ""))
- (full-body (org-babel-expand-body:generic body params)))
- (with-temp-file src-file (insert full-body))
- (org-babel-eval
- (concat org-babel-java-compiler " " cmpflag " " src-file) "")
+ "Execute a java source block with BODY code and PARAMS params."
+ (let* (;; allow header overrides
+ (org-babel-java-compiler
+ (or (cdr (assq :javac params))
+ org-babel-java-compiler))
+ (org-babel-java-command
+ (or (cdr (assq :java params))
+ org-babel-java-command))
+ ;; if true, run from babel temp directory
+ (run-from-temp (not (cdr (assq :dir params))))
+ ;; class and package
+ (fullclassname (or (cdr (assq :classname params))
+ (org-babel-java-find-classname body)))
+ ;; just the class name
+ (classname (car (last (split-string fullclassname "\\."))))
+ ;; just the package name
+ (packagename (if (string-match-p "\\." fullclassname)
+ (file-name-base fullclassname)))
+ ;; the base dir that contains the top level package dir
+ (basedir (file-name-as-directory (if run-from-temp
+ (if (file-remote-p default-directory)
+ (concat
+ (file-remote-p default-directory)
+ org-babel-remote-temporary-directory)
+ org-babel-temporary-directory)
+ default-directory)))
+ ;; the dir to write the source file
+ (packagedir (if (and (not run-from-temp) packagename)
+ (file-name-as-directory
+ (concat basedir (replace-regexp-in-string "\\." "/" packagename)))
+ basedir))
+ ;; the filename of the source file
+ (src-file (concat packagedir classname ".java"))
+ ;; compiler flags
+ (cmpflag (or (cdr (assq :cmpflag params)) ""))
+ ;; runtime flags
+ (cmdline (or (cdr (assq :cmdline params)) ""))
+ ;; command line args
+ (cmdargs (or (cdr (assq :cmdargs params)) ""))
+ ;; the command to compile and run
+ (cmd (concat org-babel-java-compiler " " cmpflag " "
+ (org-babel-process-file-name src-file 'noquote)
+ " && " org-babel-java-command
+ " -cp " (org-babel-process-file-name basedir 'noquote)
+ " " cmdline " " (if run-from-temp classname fullclassname)
+ " " cmdargs))
+ ;; header args for result processing
+ (result-type (cdr (assq :result-type params)))
+ (result-params (cdr (assq :result-params params)))
+ (result-file (and (eq result-type 'value)
+ (org-babel-temp-file "java-")))
+ ;; the expanded body of the source block
+ (full-body (org-babel-expand-body:java body params)))
+
;; created package-name directories if missing
- (unless (or (not packagename) (file-exists-p packagename))
- (make-directory packagename 'parents))
- (let ((results (org-babel-eval (concat org-babel-java-command
- " " cmdline " " classname " " cmdargs) "")))
- (org-babel-reassemble-table
- (org-babel-result-cond (cdr (assq :result-params params))
- (org-babel-read results t)
- (let ((tmp-file (org-babel-temp-file "c-")))
- (with-temp-file tmp-file (insert results))
- (org-babel-import-elisp-from-file tmp-file)))
- (org-babel-pick-name
- (cdr (assq :colname-names params)) (cdr (assq :colnames params)))
- (org-babel-pick-name
- (cdr (assq :rowname-names params)) (cdr (assq :rownames params)))))))
+ (unless (or (not packagedir) (file-exists-p packagedir))
+ (make-directory packagedir 'parents))
+
+ ;; write the source file
+ (setq full-body (org-babel-java--expand-for-evaluation
+ full-body run-from-temp result-type result-file))
+ (with-temp-file src-file (insert full-body))
+
+ ;; compile, run, process result
+ (org-babel-reassemble-table
+ (org-babel-java-evaluate cmd result-type result-params result-file)
+ (org-babel-pick-name
+ (cdr (assoc :colname-names params)) (cdr (assoc :colnames params)))
+ (org-babel-pick-name
+ (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params))))))
+
+;; helper functions
+
+(defun org-babel-java-find-classname (body)
+ "Try to find fully qualified class name in BODY.
+Look through BODY for the package and class. If found, put them
+together into a fully qualified class name and return. Else just
+return class name. If that isn't found either, default to Main."
+ (let ((package (if (string-match org-babel-java--package-re body)
+ (match-string 1 body)))
+ (class (if (string-match org-babel-java--class-re body)
+ (match-string 1 body))))
+ (or (and package class (concat package "." class))
+ (and class class)
+ (and package (concat package ".Main"))
+ "Main")))
+
+(defun org-babel-java--expand-for-evaluation (body suppress-package-p result-type result-file)
+ "Expand source block for evaluation.
+In order to return a value we have to add a __toString method.
+In order to prevent classes without main methods from erroring we
+add a dummy main method if one is not provided. These
+manipulations are done outside of `org-babel--expand-body' so
+that they are hidden from tangles.
+
+BODY is the file content before instrumentation.
+
+SUPPRESS-PACKAGE-P if true, suppress the package statement.
+
+RESULT-TYPE is taken from params.
+
+RESULT-FILE is the temp file to write the result."
+ (with-temp-buffer
+ (insert body)
+
+ ;; suppress package statement
+ (goto-char (point-min))
+ (when (and suppress-package-p
+ (re-search-forward org-babel-java--package-re nil t))
+ (replace-match ""))
+
+ ;; add a dummy main method if needed
+ (goto-char (point-min))
+ (when (not (re-search-forward org-babel-java--main-re nil t))
+ (org-babel-java--move-past org-babel-java--class-re)
+ (insert "\n public static void main(String[] args) {
+ System.out.print(\"success\");
+ }\n\n"))
+
+ ;; special handling to return value
+ (when (eq result-type 'value)
+ (goto-char (point-min))
+ (org-babel-java--move-past org-babel-java--class-re)
+ (insert (format org-babel-java--result-wrapper
+ (org-babel-process-file-name result-file 'noquote)))
+ (search-forward "public static void main(") ; rename existing main
+ (replace-match "public static Object _main("))
+
+ ;; add imports
+ (org-babel-java--import-maybe "java.util" "List")
+ (org-babel-java--import-maybe "java.util" "Arrays")
+ (org-babel-java--import-maybe "java.io" "BufferedWriter")
+ (org-babel-java--import-maybe "java.io" "FileWriter")
+ (org-babel-java--import-maybe "java.io" "IOException")
+
+ (buffer-string)))
+
+(defun org-babel-java--move-past (re)
+ "Move point past the first occurrence of the given regexp RE."
+ (while (re-search-forward re nil t)
+ (goto-char (1+ (match-end 0)))))
+
+(defun org-babel-java--import-maybe (package class)
+ "Import from PACKAGE the given CLASS if it is used and not already imported."
+ (let (class-found import-found)
+ (goto-char (point-min))
+ (setq class-found (re-search-forward class nil t))
+ (goto-char (point-min))
+ (setq import-found
+ (re-search-forward (concat "^import .*" package ".*\\(?:\\*\\|" class "\\);") nil t))
+ (when (and class-found (not import-found))
+ (org-babel-java--move-past org-babel-java--package-re)
+ (insert (concat "import " package "." class ";\n")))))
+
+(defun org-babel-expand-body:java (body params)
+ "Expand BODY with PARAMS.
+BODY could be a few statements, or could include a full class
+definition specifying package, imports, and class. Because we
+allow this flexibility in what the source block can contain, it
+is simplest to expand the code block from the inside out."
+ (let* ((fullclassname (or (cdr (assq :classname params)) ; class and package
+ (org-babel-java-find-classname body)))
+ (classname (car (last (split-string fullclassname "\\.")))) ; just class name
+ (packagename (if (string-match-p "\\." fullclassname) ; just package name
+ (file-name-base fullclassname)))
+ (var-lines (org-babel-variable-assignments:java params))
+ (imports-val (assq :imports params))
+ (imports (if imports-val
+ (split-string (org-babel-read (cdr imports-val) nil) " ")
+ nil)))
+ (with-temp-buffer
+ (insert body)
+
+ ;; wrap main. If there are methods defined, but no main method
+ ;; and no class, wrap everything in a generic main method.
+ (goto-char (point-min))
+ (when (and (not (re-search-forward org-babel-java--main-re nil t))
+ (not (re-search-forward org-babel-java--any-method-re nil t)))
+ (org-babel-java--move-past org-babel-java--package-re) ; if package is defined, move past it
+ (org-babel-java--move-past org-babel-java--imports-re) ; if imports are defined, move past them
+ (insert "public static void main(String[] args) {\n")
+ (indent-code-rigidly (point) (point-max) 4)
+ (goto-char (point-max))
+ (insert "\n}"))
+
+ ;; wrap class. If there's no class, wrap everything in a
+ ;; generic class.
+ (goto-char (point-min))
+ (when (not (re-search-forward org-babel-java--class-re nil t))
+ (org-babel-java--move-past org-babel-java--package-re) ; if package is defined, move past it
+ (org-babel-java--move-past org-babel-java--imports-re) ; if imports are defined, move past them
+ (insert (concat "\npublic class " (file-name-base classname) " {\n"))
+ (indent-code-rigidly (point) (point-max) 4)
+ (goto-char (point-max))
+ (insert "\n}"))
+ (goto-char (point-min))
+
+ ;; insert variables from source block headers
+ (when var-lines
+ (goto-char (point-min))
+ (org-babel-java--move-past org-babel-java--class-re) ; move inside class
+ (insert (mapconcat 'identity var-lines "\n"))
+ (insert "\n"))
+
+ ;; add imports from source block headers
+ (when imports
+ (goto-char (point-min))
+ (org-babel-java--move-past org-babel-java--package-re) ; if package is defined, move past it
+ (insert (mapconcat (lambda (package) (concat "import " package ";")) imports "\n") "\n"))
+
+ ;; add package at the top
+ (goto-char (point-min))
+ (when (and packagename (not (re-search-forward org-babel-java--package-re nil t)))
+ (insert (concat "package " packagename ";\n")))
+
+ ;; return expanded body
+ (buffer-string))))
+
+(defun org-babel-variable-assignments:java (params)
+ "Return a list of java statements assigning the block's variables.
+variables are contained in PARAMS."
+ (mapcar
+ (lambda (pair)
+ (let* ((type-data (org-babel-java-val-to-type (cdr pair)))
+ (basetype (car type-data))
+ (var-to-java (lambda (var) (funcall #'org-babel-java-var-to-java var basetype))))
+ (format " static %s %s = %s;"
+ (cdr type-data) ; type
+ (car pair) ; name
+ (funcall var-to-java (cdr pair))))) ; value
+ (org-babel--get-vars params)))
+
+(defun org-babel-java-var-to-java (var basetype)
+ "Convert an elisp value to a java variable.
+Convert an elisp value, VAR, of type BASETYPE into a string of
+java source code specifying a variable of the same value."
+ (cond ((and (sequencep var) (not (stringp var)))
+ (let ((var-to-java (lambda (var) (funcall #'org-babel-java-var-to-java var basetype))))
+ (concat "Arrays.asList(" (mapconcat var-to-java var ", ") ")")))
+ ((eq var 'hline) org-babel-java-hline-to)
+ ((eq basetype 'integerp) (format "%d" var))
+ ((eq basetype 'floatp) (format "%f" var))
+ ((eq basetype 'stringp) (if (and (stringp var) (string-match-p ".\n+." var))
+ (error "Java does not support multiline string literals")
+ (format "\"%s\"" var)))))
+
+(defun org-babel-java-val-to-type (val)
+ "Determine the type of VAL.
+Return (BASETYPE . LISTTYPE), where BASETYPE is a symbol
+representing the type of the individual items in VAL, and
+LISTTYPE is a string name of the type parameter for a container
+for BASETYPE items."
+ (let* ((basetype (org-babel-java-val-to-base-type val))
+ (basetype-str (pcase basetype
+ (`integerp "Integer")
+ (`floatp "Double")
+ (`stringp "String")
+ (_ (error "Unknown type %S" basetype)))))
+ (cond
+ ((and (listp val) (listp (car val))) ; a table
+ (cons basetype (format "List<List<%s>>" basetype-str)))
+ ((or (listp val) (vectorp val)) ; a list declared in the source block header
+ (cons basetype (format "List<%s>" basetype-str)))
+ (t ; return base type
+ (cons basetype basetype-str)))))
+
+(defun org-babel-java-val-to-base-type (val)
+ "Determine the base type of VAL.
+VAL may be
+`integerp' if all base values are integers
+`floatp' if all base values are either floating points or integers
+`stringp' otherwise."
+ (cond
+ ((integerp val) 'integerp)
+ ((floatp val) 'floatp)
+ ((or (listp val) (vectorp val))
+ (let ((type nil))
+ (mapc (lambda (v)
+ (pcase (org-babel-java-val-to-base-type v)
+ (`stringp (setq type 'stringp))
+ (`floatp
+ (when (or (not type) (eq type 'integerp))
+ (setq type 'floatp)))
+ (`integerp
+ (unless type (setq type 'integerp)))))
+ val)
+ type))
+ (t 'stringp)))
+
+(defun org-babel-java-table-or-string (results)
+ "Convert RESULTS into an appropriate elisp value.
+If the results look like a list or vector, then convert them into an
+Emacs-lisp table, otherwise return the results as a string."
+ (let ((res (org-babel-script-escape results)))
+ (if (listp res)
+ (mapcar (lambda (el) (if (eq 'null el)
+ org-babel-java-null-to
+ el))
+ res)
+ res)))
+
+(defun org-babel-java-evaluate (cmd result-type result-params result-file)
+ "Evaluate using an external java process.
+CMD the command to execute.
+
+If RESULT-TYPE equals `output' then return standard output as a
+string. If RESULT-TYPE equals `value' then return the value
+returned by the source block, as elisp.
+
+RESULT-PARAMS input params used to format the response.
+
+RESULT-FILE filename of the tempfile to store the returned value in
+for `value' RESULT-TYPE. Not used for `output' RESULT-TYPE."
+ (let ((raw (pcase result-type
+ (`output (org-babel-eval cmd ""))
+ (`value (org-babel-eval cmd "")
+ (org-babel-eval-read-file result-file)))))
+ (org-babel-result-cond result-params raw
+ (org-babel-java-table-or-string raw))))
(provide 'ob-java)
diff --git a/lisp/org/ob-js.el b/lisp/org/ob-js.el
index b2a971e2a59..5d1be611768 100644
--- a/lisp/org/ob-js.el
+++ b/lisp/org/ob-js.el
@@ -158,8 +158,8 @@ specifying a variable of the same value."
(org-babel--get-vars params)))
(defun org-babel-js-initiate-session (&optional session _params)
- "If there is not a current inferior-process-buffer in `SESSION'
-then create. Return the initialized session."
+ "If there is not a current inferior-process-buffer in `SESSION' then create.
+Return the initialized session."
(cond
((string= session "none")
(warn "Session evaluation of ob-js is not supported"))
diff --git a/lisp/org/ob-julia.el b/lisp/org/ob-julia.el
new file mode 100644
index 00000000000..3176baf3702
--- /dev/null
+++ b/lisp/org/ob-julia.el
@@ -0,0 +1,333 @@
+;;; ob-julia.el --- org-babel functions for julia code evaluation -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2013-2021 Free Software Foundation, Inc.
+;; Authors: G. Jay Kerns
+;; Maintainer: Pedro Bruel <pedro.bruel@gmail.com>
+;; Keywords: literate programming, reproducible research, scientific computing
+;; Homepage: https://github.com/phrb/ob-julia
+
+;; 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:
+
+;; Org-Babel support for evaluating julia code
+;;
+;; Based on ob-R.el by Eric Schulte and Dan Davison.
+
+;;; Code:
+(require 'cl-lib)
+(require 'ob)
+
+(declare-function orgtbl-to-csv "org-table" (table params))
+(declare-function julia "ext:ess-julia" (&optional start-args))
+(declare-function inferior-ess-send-input "ext:ess-inf" ())
+(declare-function ess-make-buffer-current "ext:ess-inf" ())
+(declare-function ess-eval-buffer "ext:ess-inf" (vis))
+(declare-function ess-wait-for-process "ext:ess-inf"
+ (&optional proc sec-prompt wait force-redisplay))
+
+(defvar org-babel-header-args:julia
+ '((width . :any)
+ (horizontal . :any)
+ (results . ((file list vector table scalar verbatim)
+ (raw org html latex code pp wrap)
+ (replace silent append prepend)
+ (output value graphics))))
+ "Julia-specific header arguments.")
+
+(add-to-list 'org-babel-tangle-lang-exts '("julia" . "jl"))
+
+(defvar org-babel-default-header-args:julia '())
+
+(defcustom org-babel-julia-command "julia"
+ "Name of command to use for executing julia code."
+ :version "24.3"
+ :package-version '(Org . "8.0")
+ :group 'org-babel
+ :type 'string)
+
+(defvar ess-current-process-name) ; dynamically scoped
+(defvar ess-local-process-name) ; dynamically scoped
+(defvar ess-eval-visibly-p) ; dynamically scoped
+(defun org-babel-edit-prep:julia (info)
+ (let ((session (cdr (assq :session (nth 2 info)))))
+ (when (and session
+ (string-prefix-p "*" session)
+ (string-suffix-p "*" session))
+ (org-babel-julia-initiate-session session nil))))
+
+(defun org-babel-expand-body:julia (body params &optional _graphics-file)
+ "Expand BODY according to PARAMS, return the expanded body."
+ (mapconcat #'identity
+ (append
+ (when (cdr (assq :prologue params))
+ (list (cdr (assq :prologue params))))
+ (org-babel-variable-assignments:julia params)
+ (list body)
+ (when (cdr (assq :epilogue params))
+ (list (cdr (assq :epilogue params)))))
+ "\n"))
+
+(defun org-babel-execute:julia (body params)
+ "Execute a block of julia code.
+This function is called by `org-babel-execute-src-block'."
+ (save-excursion
+ (let* ((result-params (cdr (assq :result-params params)))
+ (result-type (cdr (assq :result-type params)))
+ (session (org-babel-julia-initiate-session
+ (cdr (assq :session params)) params))
+ (graphics-file (and (member "graphics" (assq :result-params params))
+ (org-babel-graphical-output-file params)))
+ (colnames-p (unless graphics-file (cdr (assq :colnames params))))
+ (full-body (org-babel-expand-body:julia body params graphics-file))
+ (result
+ (org-babel-julia-evaluate
+ session full-body result-type result-params
+ (or (equal "yes" colnames-p)
+ (org-babel-pick-name
+ (cdr (assq :colname-names params)) colnames-p)))))
+ (if graphics-file nil result))))
+
+(defun org-babel-normalize-newline (result)
+ (replace-regexp-in-string
+ "\\(\n\r?\\)\\{2,\\}"
+ "\n"
+ result))
+
+(defun org-babel-prep-session:julia (session params)
+ "Prepare SESSION according to the header arguments specified in PARAMS."
+ (let* ((session (org-babel-julia-initiate-session session params))
+ (var-lines (org-babel-variable-assignments:julia params)))
+ (org-babel-comint-in-buffer session
+ (mapc (lambda (var)
+ (end-of-line 1) (insert var) (comint-send-input nil t)
+ (org-babel-comint-wait-for-output session)) var-lines))
+ session))
+
+(defun org-babel-load-session:julia (session body params)
+ "Load BODY into SESSION."
+ (save-window-excursion
+ (let ((buffer (org-babel-prep-session:julia session params)))
+ (with-current-buffer buffer
+ (goto-char (process-mark (get-buffer-process (current-buffer))))
+ (insert (org-babel-chomp body)))
+ buffer)))
+
+;; helper functions
+
+(defun org-babel-variable-assignments:julia (params)
+ "Return list of julia statements assigning the block's variables."
+ (let ((vars (org-babel--get-vars params)))
+ (mapcar
+ (lambda (pair) (org-babel-julia-assign-elisp (car pair) (cdr pair)))
+ (mapcar
+ (lambda (i)
+ (cons (car (nth i vars))
+ (org-babel-reassemble-table
+ (cdr (nth i vars))
+ (cdr (nth i (cdr (assq :colname-names params))))
+ (cdr (nth i (cdr (assq :rowname-names params)))))))
+ (number-sequence 0 (1- (length vars)))))))
+
+(defun org-babel-julia-quote-csv-field (s)
+ "Quote field S for export to julia."
+ (if (stringp s)
+ (concat "\"" (mapconcat #'identity (split-string s "\"") "\"\"") "\"")
+ (format "%S" s)))
+
+(defun org-babel-julia-assign-elisp (name value)
+ "Construct julia code assigning the elisp VALUE to a variable named NAME."
+ (if (listp value)
+ (let* ((lengths (mapcar #'length (cl-remove-if-not #'sequencep value)))
+ (max (if lengths (apply #'max lengths) 0))
+ (min (if lengths (apply #'min lengths) 0)))
+ ;; Ensure VALUE has an orgtbl structure (depth of at least 2).
+ (unless (listp (car value)) (setq value (list value)))
+ (let ((file (orgtbl-to-csv value '(:fmt org-babel-julia-quote-csv-field))))
+ (if (= max min)
+ (format "%s = begin
+ using CSV
+ CSV.read(\"%s\")
+end" name file)
+ (format "%s = begin
+ using CSV
+ CSV.read(\"%s\")
+end"
+ name file))))
+ (format "%s = %s" name (org-babel-julia-quote-csv-field value))))
+
+(defvar ess-ask-for-ess-directory) ; dynamically scoped
+(defun org-babel-julia-initiate-session (session params)
+ "If there is not a current julia process then create one."
+ (unless (string= session "none")
+ (let ((session (or session "*Julia*"))
+ (ess-ask-for-ess-directory
+ (and (bound-and-true-p ess-ask-for-ess-directory)
+ (not (cdr (assq :dir params))))))
+ (if (org-babel-comint-buffer-livep session)
+ session
+ ;; FIXME: Depending on `display-buffer-alist', (julia) may end up
+ ;; popping up a new frame which `save-window-excursion' won't be able
+ ;; to "undo", so we really should call a kind of
+ ;; `julia-no-select' instead so we don't need to undo any
+ ;; window-changes afterwards.
+ (save-window-excursion
+ (when (get-buffer session)
+ ;; Session buffer exists, but with dead process
+ (set-buffer session))
+ (require 'ess) (set-buffer (julia))
+ (rename-buffer
+ (if (bufferp session)
+ (buffer-name session)
+ (if (stringp session)
+ session
+ (buffer-name))))
+ (current-buffer))))))
+
+(defun org-babel-julia-graphical-output-file (params)
+ "Name of file to which julia should send graphical output."
+ (and (member "graphics" (cdr (assq :result-params params)))
+ (cdr (assq :file params))))
+
+(defconst org-babel-julia-eoe-indicator "print(\"org_babel_julia_eoe\")")
+(defconst org-babel-julia-eoe-output "org_babel_julia_eoe")
+
+(defconst org-babel-julia-write-object-command "begin
+ local p_ans = %s
+ local p_tmp_file = \"%s\"
+
+ try
+ using CSV, DataFrames
+
+ if typeof(p_ans) <: DataFrame
+ p_ans_df = p_ans
+ else
+ p_ans_df = DataFrame(:ans => p_ans)
+ end
+
+ CSV.write(p_tmp_file,
+ p_ans_df,
+ writeheader = %s,
+ transform = (col, val) -> something(val, missing),
+ missingstring = \"nil\",
+ quotestrings = false)
+ p_ans
+ catch e
+ err_msg = \"Source block evaluation failed. $e\"
+ CSV.write(p_tmp_file,
+ DataFrame(:ans => err_msg),
+ writeheader = false,
+ transform = (col, val) -> something(val, missing),
+ missingstring = \"nil\",
+ quotestrings = false)
+
+ err_msg
+ end
+end")
+
+(defun org-babel-julia-evaluate
+ (session body result-type result-params column-names-p)
+ "Evaluate julia code in BODY."
+ (if session
+ (org-babel-julia-evaluate-session
+ session body result-type result-params column-names-p)
+ (org-babel-julia-evaluate-external-process
+ body result-type result-params column-names-p)))
+
+(defun org-babel-julia-evaluate-external-process
+ (body result-type result-params column-names-p)
+ "Evaluate BODY in external julia process.
+If RESULT-TYPE equals 'output then return standard output as a
+string. If RESULT-TYPE equals 'value then return the value of the
+last statement in BODY, as elisp."
+ (cl-case result-type
+ (value
+ (let ((tmp-file (org-babel-temp-file "julia-")))
+ (org-babel-eval org-babel-julia-command
+ (format org-babel-julia-write-object-command
+ (format "begin %s end" body)
+ (org-babel-process-file-name tmp-file 'noquote)
+ (if column-names-p "true" "false")
+ ))
+ (org-babel-julia-process-value-result
+ (org-babel-result-cond result-params
+ (with-temp-buffer
+ (insert-file-contents tmp-file)
+ (buffer-string))
+ (org-babel-import-elisp-from-file tmp-file '(4)))
+ column-names-p)))
+ (output (org-babel-eval org-babel-julia-command body))))
+
+(defun org-babel-julia-evaluate-session
+ (session body result-type result-params column-names-p)
+ "Evaluate BODY in SESSION.
+If RESULT-TYPE equals 'output then return standard output as a
+string. If RESULT-TYPE equals 'value then return the value of the
+last statement in BODY, as elisp."
+ (cl-case result-type
+ (value
+ (with-temp-buffer
+ (insert (org-babel-chomp body))
+ (let ((ess-local-process-name
+ (process-name (get-buffer-process session)))
+ (ess-eval-visibly-p nil))
+ (ess-eval-buffer nil)))
+ (let ((tmp-file (org-babel-temp-file "julia-")))
+ (org-babel-comint-eval-invisibly-and-wait-for-file
+ session tmp-file
+ (format org-babel-julia-write-object-command
+ "ans"
+ (org-babel-process-file-name tmp-file 'noquote)
+ (if column-names-p "true" "false")
+ ))
+ (org-babel-julia-process-value-result
+ (org-babel-result-cond result-params
+ (with-temp-buffer
+ (insert-file-contents tmp-file)
+ (buffer-string))
+ (org-babel-import-elisp-from-file tmp-file '(4)))
+ column-names-p)))
+ (output
+ (mapconcat
+ #'org-babel-chomp
+ (butlast
+ (delq nil
+ (mapcar
+ (lambda (line) (when (> (length line) 0) line))
+ (mapcar
+ (lambda (line) ;; cleanup extra prompts left in output
+ (if (string-match
+ "^\\([>+.]\\([ ][>.+]\\)*[ ]\\)"
+ (car (split-string line "\n")))
+ (substring line (match-end 1))
+ line))
+ (org-babel-comint-with-output (session org-babel-julia-eoe-output)
+ (insert (mapconcat #'org-babel-chomp
+ (list body org-babel-julia-eoe-indicator)
+ "\n"))
+ (inferior-ess-send-input))))))
+ "\n"))))
+
+(defun org-babel-julia-process-value-result (result column-names-p)
+ "Julia-specific processing of return value.
+Insert hline if column names in output have been requested."
+ (if column-names-p
+ (cons (car result) (cons 'hline (cdr result)))
+ result))
+
+(provide 'ob-julia)
+
+;;; ob-julia.el ends here
diff --git a/lisp/org/ob-latex.el b/lisp/org/ob-latex.el
index 138f4749525..7c652569765 100644
--- a/lisp/org/ob-latex.el
+++ b/lisp/org/ob-latex.el
@@ -66,7 +66,46 @@
"LaTeX-specific header arguments.")
(defcustom org-babel-latex-htlatex "htlatex"
- "The htlatex command to enable conversion of latex to SVG or HTML."
+ "The htlatex command to enable conversion of LaTeX to SVG or HTML."
+ :group 'org-babel
+ :type 'string)
+
+(defcustom org-babel-latex-preamble
+ (lambda (_)
+ "\\documentclass[preview]{standalone}
+\\def\\pgfsysdriver{pgfsys-tex4ht.def}
+")
+ "Closure which evaluates at runtime to the LaTeX preamble.
+
+It takes 1 argument which is the parameters of the source block."
+ :group 'org-babel
+ :type 'function)
+
+(defcustom org-babel-latex-begin-env
+ (lambda (_)
+ "\\begin{document}")
+ "Function that evaluates to the begin part of the document environment.
+
+It takes 1 argument which is the parameters of the source block.
+This allows adding additional code that will be ignored when
+exporting the literal LaTeX source."
+ :group 'org-babel
+ :type 'function)
+
+(defcustom org-babel-latex-end-env
+ (lambda (_)
+ "\\end{document}")
+ "Closure which evaluates at runtime to the end part of the document environment.
+
+It takes 1 argument which is the parameters of the source block.
+This allows adding additional code that will be ignored when
+exporting the literal LaTeX source."
+ :group 'org-babel
+ :type 'function)
+
+(defcustom org-babel-latex-pdf-svg-process
+ "inkscape --pdf-poppler %f -T -l -o %O"
+ "Command to convert a PDF file to an SVG file."
:group 'org-babel
:type 'string)
@@ -112,14 +151,28 @@ This function is called by `org-babel-execute-src-block'."
(let ((org-format-latex-header
(concat org-format-latex-header "\n"
(mapconcat #'identity headers "\n"))))
- (org-create-formula-image
- body out-file org-format-latex-options in-buffer)))
+ (org-create-formula-image
+ body out-file org-format-latex-options in-buffer)))
+ ((string= "svg" extension)
+ (with-temp-file tex-file
+ (insert (concat (funcall org-babel-latex-preamble params)
+ (mapconcat #'identity headers "\n")
+ (funcall org-babel-latex-begin-env params)
+ body
+ (funcall org-babel-latex-end-env params))))
+ (let ((tmp-pdf (org-babel-latex-tex-to-pdf tex-file)))
+ (let* ((log-buf (get-buffer-create "*Org Babel LaTeX Output*"))
+ (err-msg "org babel latex failed")
+ (img-out (org-compile-file
+ tmp-pdf
+ (list org-babel-latex-pdf-svg-process)
+ extension err-msg log-buf)))
+ (shell-command (format "mv %s %s" img-out out-file)))))
((string-suffix-p ".tikz" out-file)
(when (file-exists-p out-file) (delete-file out-file))
(with-temp-file out-file
(insert body)))
- ((and (or (string= "svg" extension)
- (string= "html" extension))
+ ((and (string= "html" extension)
(executable-find org-babel-latex-htlatex))
;; TODO: this is a very different way of generating the
;; frame latex document than in the pdf case. Ideally, both
diff --git a/lisp/org/ob-ledger.el b/lisp/org/ob-ledger.el
deleted file mode 100644
index a117f854e48..00000000000
--- a/lisp/org/ob-ledger.el
+++ /dev/null
@@ -1,68 +0,0 @@
-;;; ob-ledger.el --- Babel Functions for Ledger -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2010-2021 Free Software Foundation, Inc.
-
-;; Author: Eric S Fraga
-;; Keywords: literate programming, reproducible research, accounting
-;; Homepage: https://orgmode.org
-
-;; 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:
-
-;; Org-Babel support for evaluating ledger entries.
-;;
-;; This differs from most standard languages in that
-;;
-;; 1) there is no such thing as a "session" in ledger
-;;
-;; 2) we are generally only going to return output from the ledger program
-;;
-;; 3) we are adding the "cmdline" header argument
-;;
-;; 4) there are no variables
-
-;;; Code:
-(require 'ob)
-
-(defvar org-babel-default-header-args:ledger
- '((:results . "output") (:cmdline . "bal"))
- "Default arguments to use when evaluating a ledger source block.")
-
-(defun org-babel-execute:ledger (body params)
- "Execute a block of Ledger entries with org-babel. This function is
-called by `org-babel-execute-src-block'."
- (message "executing Ledger source code block")
- (let ((cmdline (cdr (assq :cmdline params)))
- (in-file (org-babel-temp-file "ledger-"))
- (out-file (org-babel-temp-file "ledger-output-")))
- (with-temp-file in-file (insert body))
- (message "%s" (concat "ledger"
- " -f " (org-babel-process-file-name in-file)
- " " cmdline))
- (with-output-to-string
- (shell-command (concat "ledger"
- " -f " (org-babel-process-file-name in-file)
- " " cmdline
- " > " (org-babel-process-file-name out-file))))
- (with-temp-buffer (insert-file-contents out-file) (buffer-string))))
-
-(defun org-babel-prep-session:ledger (_session _params)
- (error "Ledger does not support sessions"))
-
-(provide 'ob-ledger)
-
-;;; ob-ledger.el ends here
diff --git a/lisp/org/ob-lilypond.el b/lisp/org/ob-lilypond.el
index 47397e66259..410d53ba60a 100644
--- a/lisp/org/ob-lilypond.el
+++ b/lisp/org/ob-lilypond.el
@@ -27,9 +27,9 @@
;; https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-lilypond.html
;;
;; Lilypond documentation can be found at
-;; http://lilypond.org/manuals.html
+;; https://lilypond.org/manuals.html
;;
-;; This depends on epstopdf --- See http://www.ctan.org/pkg/epstopdf.
+;; This depends on epstopdf --- See https://www.ctan.org/pkg/epstopdf.
;;; Code:
(require 'ob)
@@ -43,6 +43,15 @@
(defvar org-babel-default-header-args:lilypond '()
"Default header arguments for lilypond code blocks.
NOTE: The arguments are determined at lilypond compile time.
+See `org-babel-lilypond-set-header-args'
+To configure, see `ob-lilypond-header-args'
+.")
+
+(defvar ob-lilypond-header-args
+ '((:results . "file") (:exports . "results"))
+ "User-configurable header arguments for lilypond code blocks.
+NOTE: The final value used by org-babel is computed at compile-time
+and stored in `org-babel-default-header-args:lilypond'
See `org-babel-lilypond-set-header-args'.")
(defvar org-babel-lilypond-compile-post-tangle t
@@ -196,9 +205,9 @@ specific arguments to =org-babel-tangle=."
If error in compilation, attempt to mark the error in lilypond org file."
(when org-babel-lilypond-compile-post-tangle
(let ((org-babel-lilypond-tangled-file (org-babel-lilypond-switch-extension
- (buffer-file-name) ".lilypond"))
+ (buffer-file-name) ".lilypond"))
(org-babel-lilypond-temp-file (org-babel-lilypond-switch-extension
- (buffer-file-name) ".ly")))
+ (buffer-file-name) ".ly")))
(if (not (file-exists-p org-babel-lilypond-tangled-file))
(error "Error: Tangle Failed!")
(when (file-exists-p org-babel-lilypond-temp-file)
@@ -328,7 +337,9 @@ If TEST is non-nil, the shell command is returned and is not run."
FILE-NAME is full path to lilypond file.
If TEST is non-nil, the shell command is returned and is not run."
(when org-babel-lilypond-play-midi-post-tangle
- (let ((midi-file (org-babel-lilypond-switch-extension file-name ".midi")))
+ (let* ((ext (if (eq system-type 'windows-nt)
+ ".mid" ".midi"))
+ (midi-file (org-babel-lilypond-switch-extension file-name ext)))
(if (file-exists-p midi-file)
(let ((cmd-string
(concat org-babel-lilypond-midi-command " " midi-file)))
@@ -392,7 +403,7 @@ If TEST is non-nil, the shell command is returned and is not run."
"Utility command to swap current FILE-NAME extension with EXT."
(concat (file-name-sans-extension
file-name)
- ext))
+ ext))
(defun org-babel-lilypond-get-header-args (mode)
"Default arguments to use when evaluating a lilypond source block.
@@ -404,8 +415,7 @@ These depend upon whether we are in Arrange mode i.e. MODE is t."
(:cache . "yes")
(:comments . "yes")))
(t
- '((:results . "file")
- (:exports . "results")))))
+ ob-lilypond-header-args)))
(defun org-babel-lilypond-set-header-args (mode)
"Set org-babel-default-header-args:lilypond
diff --git a/lisp/org/ob-lisp.el b/lisp/org/ob-lisp.el
index 87b9241e758..b32b122cdba 100644
--- a/lisp/org/ob-lisp.el
+++ b/lisp/org/ob-lisp.el
@@ -33,7 +33,7 @@
;; Requires SLY (Sylvester the Cat's Common Lisp IDE) or SLIME
;; (Superior Lisp Interaction Mode for Emacs). See:
;; - https://github.com/capitaomorte/sly
-;; - http://common-lisp.net/project/slime/
+;; - https://common-lisp.net/project/slime/
;;; Code:
(require 'ob)
diff --git a/lisp/org/ob-lua.el b/lisp/org/ob-lua.el
index 11503e47470..a4a964afc48 100644
--- a/lisp/org/ob-lua.el
+++ b/lisp/org/ob-lua.el
@@ -21,6 +21,10 @@
;; 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:
+
+;; Org-Babel support for evaluating lua source code.
+
;; Requirements:
;; for session support, lua-mode is needed.
;; lua-mode is not part of GNU Emacs/orgmode, but can be obtained
@@ -30,8 +34,6 @@
;; However, sessions are not yet working.
-;; Org-Babel support for evaluating lua source code.
-
;;; Code:
(require 'ob)
(require 'org-macs)
diff --git a/lisp/org/ob-makefile.el b/lisp/org/ob-makefile.el
index 69ab6fe9eaa..eae64cf4a94 100644
--- a/lisp/org/ob-makefile.el
+++ b/lisp/org/ob-makefile.el
@@ -37,8 +37,7 @@ This function is called by `org-babel-execute-src-block'."
body)
(defun org-babel-prep-session:makefile (_session _params)
- "Return an error if the :session header argument is set. Make
-does not support sessions."
+ "Signal error; Make does not support sessions."
(error "Makefile sessions are nonsensical"))
(provide 'ob-makefile)
diff --git a/lisp/org/ob-mscgen.el b/lisp/org/ob-mscgen.el
deleted file mode 100644
index 79c9f8702eb..00000000000
--- a/lisp/org/ob-mscgen.el
+++ /dev/null
@@ -1,81 +0,0 @@
-;;; ob-mscgen.el --- Babel Functions for Mscgen -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2010-2021 Free Software Foundation, Inc.
-
-;; Author: Juan Pechiar
-;; Keywords: literate programming, reproducible research
-;; Homepage: https://orgmode.org
-
-;; 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 software provides EMACS org-babel export support for message
-;; sequence charts. The mscgen utility is used for processing the
-;; sequence definition, and must therefore be installed in the system.
-;;
-;; Mscgen is available and documented at
-;; http://www.mcternan.me.uk/mscgen/index.html
-;;
-;; This code is directly inspired by Eric Schulte's ob-dot.el
-;;
-;; Example:
-;;
-;; #+begin_src mscgen :file example.png
-;; msc {
-;; A,B;
-;; A -> B [ label = "send message" ];
-;; A <- B [ label = "get answer" ];
-;; }
-;; #+end_src
-;;
-;; Header for alternative file type:
-;;
-;; #+begin_src mscgen :file ex2.svg :filetype svg
-
-;; This differs from most standard languages in that
-;;
-;; 1) there is no such thing as a "session" in mscgen
-;; 2) we are generally only going to return results of type "file"
-;; 3) we are adding the "file" and "filetype" header arguments
-;; 4) there are no variables
-
-;;; Code:
-(require 'ob)
-
-(defvar org-babel-default-header-args:mscgen
- '((:results . "file") (:exports . "results"))
- "Default arguments to use when evaluating a mscgen source block.")
-
-(defun org-babel-execute:mscgen (body params)
- "Execute a block of Mscgen code with Babel.
-This function is called by `org-babel-execute-src-block'.
-Default filetype is png. Modify by setting :filetype parameter to
-mscgen supported formats."
- (let* ((out-file (or (cdr (assq :file params)) "output.png" ))
- (filetype (or (cdr (assq :filetype params)) "png" )))
- (unless (cdr (assq :file params))
- (error "ERROR: no output file specified. Add \":file name.png\" to the src header"))
- (org-babel-eval (concat "mscgen -T " filetype " -o " out-file) body)
- nil)) ;; signal that output has already been written to file
-
-(defun org-babel-prep-session:mscgen (_session _params)
- "Raise an error because Mscgen doesn't support sessions."
- (error "Mscgen does not support sessions"))
-
-(provide 'ob-mscgen)
-
-;;; ob-mscgen.el ends here
diff --git a/lisp/org/ob-ocaml.el b/lisp/org/ob-ocaml.el
index 5fd6d1e09ff..faf117c4077 100644
--- a/lisp/org/ob-ocaml.el
+++ b/lisp/org/ob-ocaml.el
@@ -32,7 +32,7 @@
;;; Requirements:
-;; - tuareg-mode :: https://www-rocq.inria.fr/~acohen/tuareg/
+;; - tuareg-mode :: https://elpa.nongnu.org/nongnu/tuareg.html
;;; Code:
(require 'ob)
@@ -112,8 +112,8 @@
session
tuareg-interactive-buffer-name)))
(save-window-excursion (if (fboundp 'tuareg-run-process-if-needed)
- (tuareg-run-process-if-needed org-babel-ocaml-command)
- (tuareg-run-caml)))
+ (tuareg-run-process-if-needed org-babel-ocaml-command)
+ (tuareg-run-caml)))
(get-buffer tuareg-interactive-buffer-name)))
(defun org-babel-variable-assignments:ocaml (params)
diff --git a/lisp/org/ob-octave.el b/lisp/org/ob-octave.el
index 166cd596a53..bfe3e2aeec1 100644
--- a/lisp/org/ob-octave.el
+++ b/lisp/org/ob-octave.el
@@ -45,8 +45,8 @@
(defvar org-babel-matlab-with-emacs-link nil
"If non-nil use matlab-shell-run-region for session evaluation.
- This will use EmacsLink if (matlab-with-emacs-link) evaluates
- to a non-nil value.")
+This will use EmacsLink if (matlab-with-emacs-link) evaluates
+to a non-nil value.")
(defvar org-babel-matlab-emacs-link-wrapper-method
"%s
@@ -164,7 +164,7 @@ create. Return the initialized session."
(current-buffer))))))
(defun org-babel-octave-evaluate
- (session body result-type &optional matlabp)
+ (session body result-type &optional matlabp)
"Pass BODY to the octave process in SESSION.
If RESULT-TYPE equals `output' then return the outputs of the
statements in BODY, if RESULT-TYPE equals `value' then return the
@@ -181,12 +181,12 @@ value of the last statement in BODY, as elisp."
(pcase result-type
(`output (org-babel-eval cmd body))
(`value (let ((tmp-file (org-babel-temp-file "octave-")))
- (org-babel-eval
- cmd
- (format org-babel-octave-wrapper-method body
- (org-babel-process-file-name tmp-file 'noquote)
- (org-babel-process-file-name tmp-file 'noquote)))
- (org-babel-octave-import-elisp-from-file tmp-file))))))
+ (org-babel-eval
+ cmd
+ (format org-babel-octave-wrapper-method body
+ (org-babel-process-file-name tmp-file 'noquote)
+ (org-babel-process-file-name tmp-file 'noquote)))
+ (org-babel-octave-import-elisp-from-file tmp-file))))))
(defun org-babel-octave-evaluate-session
(session body result-type &optional matlabp)
diff --git a/lisp/org/ob-perl.el b/lisp/org/ob-perl.el
index 0cfac850078..4d405a8b6aa 100644
--- a/lisp/org/ob-perl.el
+++ b/lisp/org/ob-perl.el
@@ -4,6 +4,7 @@
;; Authors: Dan Davison
;; Eric Schulte
+;; Maintainer: Corwin Brust
;; Keywords: literate programming, reproducible research
;; Homepage: https://orgmode.org
diff --git a/lisp/org/ob-picolisp.el b/lisp/org/ob-picolisp.el
deleted file mode 100644
index b1587f2b86d..00000000000
--- a/lisp/org/ob-picolisp.el
+++ /dev/null
@@ -1,185 +0,0 @@
-;;; ob-picolisp.el --- Babel Functions for Picolisp -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2010-2021 Free Software Foundation, Inc.
-
-;; Authors: Thorsten Jolitz
-;; Eric Schulte
-;; Keywords: literate programming, reproducible research
-;; Homepage: https://orgmode.org
-
-;; 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 enables the use of PicoLisp in the multi-language
-;; programming framework Org-Babel. PicoLisp is a minimal yet
-;; fascinating lisp dialect and a highly productive application
-;; framework for web-based client-server applications on top of
-;; object-oriented databases. A good way to learn PicoLisp is to first
-;; read Paul Grahams essay "The hundred year language"
-;; (http://www.paulgraham.com/hundred.html) and then study the various
-;; documents and essays published in the PicoLisp wiki
-;; (http://picolisp.com/5000/-2.html). PicoLisp is included in some
-;; GNU/Linux Distributions, and can be downloaded here:
-;; http://software-lab.de/down.html. It ships with a picolisp-mode and
-;; an inferior-picolisp-mode for Emacs (to be found in the /lib/el/
-;; directory).
-
-;; Although it might seem more natural to use Emacs Lisp for most
-;; Lisp-based programming tasks inside Org, an Emacs library written
-;; in Emacs Lisp, PicoLisp has at least two outstanding features that
-;; make it a valuable addition to Org Babel:
-
-;; PicoLisp _is_ an object-oriented database with a Prolog-based query
-;; language implemented in PicoLisp (Pilog). Database objects are
-;; first-class members of the language.
-
-;; PicoLisp is an extremely productive framework for the development
-;; of interactive web-applications (on top of a database).
-
-;;; Requirements:
-
-;;; Code:
-(require 'ob)
-(require 'comint)
-
-(declare-function run-picolisp "ext:inferior-picolisp" (cmd))
-(defvar org-babel-tangle-lang-exts) ;; Autoloaded
-
-;; optionally define a file extension for this language
-(add-to-list 'org-babel-tangle-lang-exts '("picolisp" . "l"))
-
-;;; interferes with settings in org-babel buffer?
-;; optionally declare default header arguments for this language
-;; (defvar org-babel-default-header-args:picolisp
-;; '((:colnames . "no"))
-;; "Default arguments for evaluating a picolisp source block.")
-
-(defvar org-babel-picolisp-eoe "org-babel-picolisp-eoe"
- "String to indicate that evaluation has completed.")
-
-(defcustom org-babel-picolisp-cmd "pil"
- "Name of command used to evaluate picolisp blocks."
- :group 'org-babel
- :version "24.1"
- :type 'string)
-
-(defun org-babel-expand-body:picolisp (body params)
- "Expand BODY according to PARAMS, return the expanded body."
- (let ((vars (org-babel--get-vars params))
- (print-level nil)
- (print-length nil))
- (if (> (length vars) 0)
- (concat "(prog (let ("
- (mapconcat
- (lambda (var)
- (format "%S '%S)"
- (print (car var))
- (print (cdr var))))
- vars "\n ")
- " \n" body ") )")
- body)))
-
-(defun org-babel-execute:picolisp (body params)
- "Execute a block of Picolisp code with org-babel.
-This function is called by `org-babel-execute-src-block'."
- (message "executing Picolisp source code block")
- (let* (
- ;; Name of the session or "none".
- (session-name (cdr (assq :session params)))
- ;; Set the session if the session variable is non-nil.
- (session (org-babel-picolisp-initiate-session session-name))
- ;; Either OUTPUT or VALUE which should behave as described above.
- (result-params (cdr (assq :result-params params)))
- ;; Expand the body with `org-babel-expand-body:picolisp'.
- (full-body (org-babel-expand-body:picolisp body params))
- ;; Wrap body appropriately for the type of evaluation and results.
- (wrapped-body
- (cond
- ((or (member "code" result-params)
- (member "pp" result-params))
- (format "(pretty (out \"%s\" %s))" null-device full-body))
- ((and (member "value" result-params) (not session))
- (format "(print (out \"%s\" %s))" null-device full-body))
- ((member "value" result-params)
- (format "(out \"%s\" %s)" null-device full-body))
- (t full-body)))
- (result
- (if (not (string= session-name "none"))
- ;; Session based evaluation.
- (mapconcat ;; <- joins the list back into a single string
- #'identity
- (butlast ;; <- remove the org-babel-picolisp-eoe line
- (delq nil
- (mapcar
- (lambda (line)
- (org-babel-chomp ;; Remove trailing newlines.
- (when (> (length line) 0) ;; Remove empty lines.
- (cond
- ;; Remove leading "-> " from return values.
- ((and (>= (length line) 3)
- (string= "-> " (substring line 0 3)))
- (substring line 3))
- ;; Remove trailing "-> <<return-value>>" on the
- ;; last line of output.
- ((and (member "output" result-params)
- (string-match-p "->" line))
- (substring line 0 (string-match "->" line)))
- (t line)
- )
- ;;(if (and (>= (length line) 3);Remove leading "<-"
- ;; (string= "-> " (substring line 0 3)))
- ;; (substring line 3)
- ;; line)
- )))
- ;; Returns a list of the output of each evaluated exp.
- (org-babel-comint-with-output
- (session org-babel-picolisp-eoe)
- (insert wrapped-body) (comint-send-input)
- (insert "'" org-babel-picolisp-eoe)
- (comint-send-input)))))
- "\n")
- ;; external evaluation
- (let ((script-file (org-babel-temp-file "picolisp-script-")))
- (with-temp-file script-file
- (insert (concat wrapped-body "(bye)")))
- (org-babel-eval
- (format "%s %s"
- org-babel-picolisp-cmd
- (org-babel-process-file-name script-file))
- "")))))
- (org-babel-result-cond result-params
- result
- (read result))))
-
-(defun org-babel-picolisp-initiate-session (&optional session-name)
- "If there is not a current inferior-process-buffer in SESSION
-then create. Return the initialized session."
- (unless (string= session-name "none")
- (require 'inferior-picolisp)
- ;; provide a reasonable default session name
- (let ((session (or session-name "*inferior-picolisp*")))
- ;; check if we already have a live session by this name
- (if (org-babel-comint-buffer-livep session)
- (get-buffer session)
- (save-window-excursion
- (run-picolisp org-babel-picolisp-cmd)
- (rename-buffer session-name)
- (current-buffer))))))
-
-(provide 'ob-picolisp)
-
-;;; ob-picolisp.el ends here
diff --git a/lisp/org/ob-plantuml.el b/lisp/org/ob-plantuml.el
index 93c653870c2..fc621600c44 100644
--- a/lisp/org/ob-plantuml.el
+++ b/lisp/org/ob-plantuml.el
@@ -71,6 +71,12 @@ You can also configure extra arguments via `org-plantuml-executable-args'."
:package-version '(Org . "9.4")
:type '(repeat string))
+(defcustom org-babel-plantuml-svg-text-to-path nil
+ "When non-nil, export text in SVG images to paths using Inkscape."
+ :group 'org-babel
+ :package-version '(Org . "9.5")
+ :type 'boolean)
+
(defun org-babel-variable-assignments:plantuml (params)
"Return a list of PlantUML statements assigning the block's variables.
PARAMS is a property list of source block parameters, which may
@@ -78,9 +84,9 @@ contain multiple entries for the key `:var'. `:var' entries in PARAMS
are expected to be scalar variables."
(mapcar
(lambda (pair)
- (format "!define %s %s"
- (car pair)
- (replace-regexp-in-string "\"" "" (cdr pair))))
+ (format "!define %s %s"
+ (car pair)
+ (replace-regexp-in-string "\"" "" (cdr pair))))
(org-babel--get-vars params)))
(defun org-babel-plantuml-make-body (body params)
@@ -145,6 +151,9 @@ This function is called by `org-babel-execute-src-block'."
" ")))
(with-temp-file in-file (insert full-body))
(message "%s" cmd) (org-babel-eval cmd "")
+ (if (and (string= (file-name-extension out-file) "svg")
+ org-babel-plantuml-svg-text-to-path)
+ (org-babel-eval (format "inkscape %s -T -l %s" out-file out-file) ""))
nil)) ;; signal that output has already been written to file
(defun org-babel-prep-session:plantuml (_session _params)
diff --git a/lisp/org/ob-processing.el b/lisp/org/ob-processing.el
index 9e6572a5fdd..84fd6a2964f 100644
--- a/lisp/org/ob-processing.el
+++ b/lisp/org/ob-processing.el
@@ -47,7 +47,7 @@
;;; Requirements:
;; - processing2-emacs mode :: https://github.com/ptrv/processing2-emacs
-;; - Processing.js module :: http://processingjs.org/
+;; - Processing.js module :: https://processingjs.org/
;;; Code:
(require 'ob)
diff --git a/lisp/org/ob-python.el b/lisp/org/ob-python.el
index 7911205d08d..3c095ad463f 100644
--- a/lisp/org/ob-python.el
+++ b/lisp/org/ob-python.el
@@ -81,15 +81,20 @@ This function is called by `org-babel-execute-src-block'."
(cdr (assq :session params))))
(result-params (cdr (assq :result-params params)))
(result-type (cdr (assq :result-type params)))
- (return-val (when (and (eq result-type 'value) (not session))
+ (return-val (when (eq result-type 'value)
(cdr (assq :return params))))
(preamble (cdr (assq :preamble params)))
+ (async (org-babel-comint-use-async params))
(full-body
- (org-babel-expand-body:generic
- (concat body (if return-val (format "\nreturn %s" return-val) ""))
- params (org-babel-variable-assignments:python params)))
+ (concat
+ (org-babel-expand-body:generic
+ body params
+ (org-babel-variable-assignments:python params))
+ (when return-val
+ (format (if session "\n%s" "\nreturn %s") return-val))))
(result (org-babel-python-evaluate
- session full-body result-type result-params preamble)))
+ session full-body result-type
+ result-params preamble async)))
(org-babel-reassemble-table
result
(org-babel-pick-name (cdr (assq :colname-names params))
@@ -149,7 +154,7 @@ Emacs-lisp table, otherwise return the results as a string."
(let ((res (org-babel-script-escape results)))
(if (listp res)
(mapcar (lambda (el) (if (eq el 'None)
- org-babel-python-None-to el))
+ org-babel-python-None-to el))
res)
res)))
@@ -275,11 +280,14 @@ else:
(if (member "pp" result-params) "True" "False")))
(defun org-babel-python-evaluate
- (session body &optional result-type result-params preamble)
+ (session body &optional result-type result-params preamble async)
"Evaluate BODY as Python code."
(if session
- (org-babel-python-evaluate-session
- session body result-type result-params)
+ (if async
+ (org-babel-python-async-evaluate-session
+ session body result-type result-params)
+ (org-babel-python-evaluate-session
+ session body result-type result-params))
(org-babel-python-evaluate-external-process
body result-type result-params preamble)))
@@ -388,6 +396,49 @@ last statement in BODY, as elisp."
(substring string 1 -1)
string))
+;; Async session eval
+
+(defconst org-babel-python-async-indicator "print ('ob_comint_async_python_%s_%s')")
+
+(defun org-babel-python-async-value-callback (params tmp-file)
+ (let ((result-params (cdr (assq :result-params params)))
+ (results (org-babel-eval-read-file tmp-file)))
+ (org-babel-result-cond result-params
+ results
+ (org-babel-python-table-or-string results))))
+
+(defun org-babel-python-async-evaluate-session
+ (session body &optional result-type result-params)
+ "Asynchronously evaluate BODY in SESSION.
+Returns a placeholder string for insertion, to later be replaced
+by `org-babel-comint-async-filter'."
+ (org-babel-comint-async-register
+ session (current-buffer)
+ "ob_comint_async_python_\\(.+\\)_\\(.+\\)"
+ 'org-babel-chomp 'org-babel-python-async-value-callback)
+ (let ((python-shell-buffer-name (org-babel-python-without-earmuffs session)))
+ (pcase result-type
+ (`output
+ (let ((uuid (md5 (number-to-string (random 100000000)))))
+ (with-temp-buffer
+ (insert (format org-babel-python-async-indicator "start" uuid))
+ (insert "\n")
+ (insert body)
+ (insert "\n")
+ (insert (format org-babel-python-async-indicator "end" uuid))
+ (python-shell-send-buffer))
+ uuid))
+ (`value
+ (let ((tmp-results-file (org-babel-temp-file "python-"))
+ (tmp-src-file (org-babel-temp-file "python-")))
+ (with-temp-file tmp-src-file (insert body))
+ (with-temp-buffer
+ (insert (org-babel-python-format-session-value tmp-src-file tmp-results-file result-params))
+ (insert "\n")
+ (insert (format org-babel-python-async-indicator "file" tmp-results-file))
+ (python-shell-send-buffer))
+ tmp-results-file)))))
+
(provide 'ob-python)
;;; ob-python.el ends here
diff --git a/lisp/org/ob-ruby.el b/lisp/org/ob-ruby.el
index ccc746e8df2..b2483f1aa6c 100644
--- a/lisp/org/ob-ruby.el
+++ b/lisp/org/ob-ruby.el
@@ -27,7 +27,7 @@
;;; Requirements:
-;; - ruby and irb executables :: http://www.ruby-lang.org/
+;; - ruby and irb executables :: https://www.ruby-lang.org/
;;
;; - ruby-mode :: Can be installed through ELPA, or from
;; https://github.com/eschulte/rinari/raw/master/util/ruby-mode.el
diff --git a/lisp/org/ob-sass.el b/lisp/org/ob-sass.el
index 76cdfd8063a..c8762cabae3 100644
--- a/lisp/org/ob-sass.el
+++ b/lisp/org/ob-sass.el
@@ -23,7 +23,7 @@
;;; Commentary:
-;; For more information on sass see http://sass-lang.com/
+;; For more information on sass see https://sass-lang.com/
;;
;; This accepts a 'file' header argument which is the target of the
;; compiled sass. The default output type for sass evaluation is
diff --git a/lisp/org/ob-scheme.el b/lisp/org/ob-scheme.el
index a18bfb51817..f4836b23fe1 100644
--- a/lisp/org/ob-scheme.el
+++ b/lisp/org/ob-scheme.el
@@ -110,7 +110,7 @@
geiser-impl--implementation))
(defun org-babel-scheme-get-repl (impl name)
- "Switch to a scheme REPL, creating it if it doesn't exist:"
+ "Switch to a scheme REPL, creating it if it doesn't exist."
(let ((buffer (org-babel-scheme-get-session-buffer name)))
(or buffer
(progn
diff --git a/lisp/org/ob-screen.el b/lisp/org/ob-screen.el
index c3388c3d3de..7793825b60d 100644
--- a/lisp/org/ob-screen.el
+++ b/lisp/org/ob-screen.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2009-2021 Free Software Foundation, Inc.
;; Author: Benjamin Andresen
+;; Maintainer: Ken Mankoff
;; Keywords: literate programming, interactive shell
;; Homepage: https://orgmode.org
@@ -29,7 +30,7 @@
;; Adding :cmd and :terminal as header arguments
;; :terminal must support the -T (title) and -e (command) parameter
;;
-;; You can test the default setup. (xterm + sh) with
+;; You can test the default setup (xterm + sh) with
;; M-x org-babel-screen-test RET
;;; Code:
@@ -127,7 +128,7 @@ The terminal should shortly flicker."
;; XXX: need to find a better way to do the following
(while (not (file-readable-p tmpfile))
;; do something, otherwise this will be optimized away
- (sit-for 0.1))
+ (message "org-babel-screen: File not readable yet."))
(setq tmp-string (with-temp-buffer
(insert-file-contents-literally tmpfile)
(buffer-substring (point-min) (point-max))))
diff --git a/lisp/org/ob-sed.el b/lisp/org/ob-sed.el
index b95f411858d..4d3eeee6164 100644
--- a/lisp/org/ob-sed.el
+++ b/lisp/org/ob-sed.el
@@ -70,12 +70,12 @@ function is called by `org-babel-execute-src-block'."
(insert body))
file))
(stdin (let ((stdin (cdr (assq :stdin params))))
- (when stdin
- (let ((tmp (org-babel-temp-file "sed-stdin-"))
- (res (org-babel-ref-resolve stdin)))
- (with-temp-file tmp
- (insert res))
- tmp))))
+ (when stdin
+ (let ((tmp (org-babel-temp-file "sed-stdin-"))
+ (res (org-babel-ref-resolve stdin)))
+ (with-temp-file tmp
+ (insert res))
+ tmp))))
(cmd (mapconcat #'identity
(remq nil
(list org-babel-sed-command
diff --git a/lisp/org/ob-shen.el b/lisp/org/ob-shen.el
deleted file mode 100644
index 6803b0bf68b..00000000000
--- a/lisp/org/ob-shen.el
+++ /dev/null
@@ -1,79 +0,0 @@
-;;; ob-shen.el --- Babel Functions for Shen -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2010-2021 Free Software Foundation, Inc.
-
-;; Author: Eric Schulte
-;; Keywords: literate programming, reproducible research, shen
-;; Homepage: https://orgmode.org
-
-;; 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:
-
-;; Currently this only works using session evaluation as there is no
-;; defined method for executing shen code outside of a session.
-
-;;; Requirements:
-
-;; - shen-mode and inf-shen will soon be available through the GNU
-;; elpa, however in the interim they are available at
-;; https://github.com/eschulte/shen-mode
-
-;;; Code:
-(require 'ob)
-
-(declare-function shen-eval-defun "ext:inf-shen" (&optional and-go))
-(declare-function org-babel-ruby-var-to-ruby "ob-ruby" (var))
-
-(defvar org-babel-default-header-args:shen '()
- "Default header arguments for shen code blocks.")
-
-(defun org-babel-expand-body:shen (body params)
- "Expand BODY according to PARAMS, return the expanded body."
- (let ((vars (org-babel--get-vars params)))
- (if (> (length vars) 0)
- (concat "(let "
- (mapconcat (lambda (var)
- (format "%s %s" (car var)
- (org-babel-shen-var-to-shen (cdr var))))
- vars " ")
- body ")")
- body)))
-
-(defun org-babel-shen-var-to-shen (var)
- "Convert VAR into a shen variable."
- (if (listp var)
- (concat "[" (mapconcat #'org-babel-ruby-var-to-ruby var " ") "]")
- (format "%S" var)))
-
-(defun org-babel-execute:shen (body params)
- "Execute a block of Shen code with org-babel.
-This function is called by `org-babel-execute-src-block'."
- (require 'inf-shen)
- (let* ((result-params (cdr (assq :result-params params)))
- (full-body (org-babel-expand-body:shen body params)))
- (let ((results
- (with-temp-buffer
- (insert full-body)
- (call-interactively #'shen-eval-defun))))
- (org-babel-result-cond result-params
- results
- (condition-case nil (org-babel-script-escape results)
- (error results))))))
-
-(provide 'ob-shen)
-
-;;; ob-shen.el ends here
diff --git a/lisp/org/ob-sql.el b/lisp/org/ob-sql.el
index 947acef1b27..f512d2952cd 100644
--- a/lisp/org/ob-sql.el
+++ b/lisp/org/ob-sql.el
@@ -40,6 +40,7 @@
;; - dbuser
;; - dbpassword
;; - dbconnection (to reference connections in sql-connection-alist)
+;; - dbinstance (currently only used by SAP HANA)
;; - database
;; - colnames (default, nil, means "yes")
;; - result-params
@@ -58,6 +59,7 @@
;; - postgresql (postgres)
;; - oracle
;; - vertica
+;; - saphana
;;
;; TODO:
;;
@@ -85,20 +87,30 @@
(dbport . :any)
(dbuser . :any)
(dbpassword . :any)
+ (dbinstance . :any)
(database . :any))
"SQL-specific header arguments.")
(defun org-babel-expand-body:sql (body params)
"Expand BODY according to the values of PARAMS."
- (org-babel-sql-expand-vars
- body (org-babel--get-vars params)))
+ (let ((prologue (cdr (assq :prologue params)))
+ (epilogue (cdr (assq :epilogue params))))
+ (mapconcat 'identity
+ (list
+ prologue
+ (org-babel-sql-expand-vars
+ body (org-babel--get-vars params))
+ epilogue)
+ "\n")))
(defun org-babel-edit-prep:sql (info)
"Set `sql-product' in Org edit buffer.
Set `sql-product' in Org edit buffer according to the
corresponding :engine source block header argument."
(let ((product (cdr (assq :engine (nth 2 info)))))
- (sql-set-product product)))
+ (condition-case nil
+ (sql-set-product product)
+ (user-error "Cannot set `sql-product' in Org Src edit buffer"))))
(defun org-babel-sql-dbstring-mysql (host port user password database)
"Make MySQL cmd line args for database connection. Pass nil to omit that arg."
@@ -167,13 +179,27 @@ SQL Server on Windows and Linux platform."
"Make Vertica command line args for database connection.
Pass nil to omit that arg."
(mapconcat #'identity
- (delq nil
- (list (when host (format "-h %s" host))
- (when port (format "-p %d" port))
- (when user (format "-U %s" user))
- (when password (format "-w %s" (shell-quote-argument password) ))
- (when database (format "-d %s" database))))
- " "))
+ (delq nil
+ (list (when host (format "-h %s" host))
+ (when port (format "-p %d" port))
+ (when user (format "-U %s" user))
+ (when password (format "-w %s" (shell-quote-argument password) ))
+ (when database (format "-d %s" database))))
+ " "))
+
+(defun org-babel-sql-dbstring-saphana (host port instance user password database)
+ "Make SAP HANA command line args for database connection.
+Pass nil to omit that arg."
+ (mapconcat #'identity
+ (delq nil
+ (list (and host port (format "-n %s:%s" host port))
+ (and host (not port) (format "-n %s" host))
+ (and instance (format "-i %d" instance))
+ (and user (format "-u %s" user))
+ (and password (format "-p %s"
+ (shell-quote-argument password)))
+ (and database (format "-d %s" database))))
+ " "))
(defun org-babel-sql-convert-standard-filename (file)
"Convert FILE to OS standard file name.
@@ -189,8 +215,8 @@ Otherwise, use Emacs' standard conversion function."
"Return database connection parameter NAME.
Given a parameter NAME, if :dbconnection is defined in PARAMS
then look for the parameter into the corresponding connection
-defined in `sql-connection-alist`, otherwise look into PARAMS.
-Look `sql-connection-alist` (part of SQL mode) for how to define
+defined in `sql-connection-alist', otherwise look into PARAMS.
+See `sql-connection-alist' (part of SQL mode) for how to define
database connections."
(if (assq :dbconnection params)
(let* ((dbconnection (cdr (assq :dbconnection params)))
@@ -198,6 +224,7 @@ database connections."
(:dbport . sql-port)
(:dbuser . sql-user)
(:dbpassword . sql-password)
+ (:dbinstance . sql-dbinstance)
(:database . sql-database)))
(mapped-name (cdr (assq name name-mapping))))
(cadr (assq mapped-name
@@ -213,6 +240,7 @@ This function is called by `org-babel-execute-src-block'."
(dbport (org-babel-find-db-connection-param params :dbport))
(dbuser (org-babel-find-db-connection-param params :dbuser))
(dbpassword (org-babel-find-db-connection-param params :dbpassword))
+ (dbinstance (org-babel-find-db-connection-param params :dbinstance))
(database (org-babel-find-db-connection-param params :database))
(engine (cdr (assq :engine params)))
(colnames-p (not (equal "no" (cdr (assq :colnames params)))))
@@ -246,11 +274,14 @@ This function is called by `org-babel-execute-src-block'."
(org-babel-process-file-name in-file)
(org-babel-process-file-name out-file)))
((postgresql postgres) (format
- "%spsql --set=\"ON_ERROR_STOP=1\" %s -A -P \
+ "%s%s --set=\"ON_ERROR_STOP=1\" %s -A -P \
footer=off -F \"\t\" %s -f %s -o %s %s"
(if dbpassword
(format "PGPASSWORD=%s " dbpassword)
"")
+ (or (bound-and-true-p
+ sql-postgres-program)
+ "psql")
(if colnames-p "" "-t")
(org-babel-sql-dbstring-postgresql
dbhost dbport dbuser database)
@@ -277,6 +308,12 @@ footer=off -F \"\t\" %s -f %s -o %s %s"
dbhost dbport dbuser dbpassword database)
(org-babel-process-file-name in-file)
(org-babel-process-file-name out-file)))
+ (saphana (format "hdbsql %s -I %s -o %s %s"
+ (org-babel-sql-dbstring-saphana
+ dbhost dbport dbinstance dbuser dbpassword database)
+ (org-babel-process-file-name in-file)
+ (org-babel-process-file-name out-file)
+ (or cmdline "")))
(t (user-error "No support for the %s SQL engine" engine)))))
(with-temp-file in-file
(insert
@@ -310,7 +347,7 @@ SET COLSEP '|'
(progn (insert-file-contents-literally out-file) (buffer-string)))
(with-temp-buffer
(cond
- ((memq (intern engine) '(dbi mysql postgresql postgres sqsh vertica))
+ ((memq (intern engine) '(dbi mysql postgresql postgres saphana sqsh vertica))
;; Add header row delimiter after column-names header in first line
(cond
(colnames-p
@@ -347,8 +384,13 @@ SET COLSEP '|'
(org-babel-pick-name (cdr (assq :rowname-names params))
(cdr (assq :rownames params))))))))
-(defun org-babel-sql-expand-vars (body vars)
- "Expand the variables held in VARS in BODY."
+(defun org-babel-sql-expand-vars (body vars &optional sqlite)
+ "Expand the variables held in VARS in BODY.
+
+If SQLITE has been provided, prevent passing a format to
+`orgtbl-to-csv'. This prevents overriding the default format, which if
+there were commas in the context of the table broke the table as an
+argument mechanism."
(mapc
(lambda (pair)
(setq body
@@ -359,9 +401,11 @@ SET COLSEP '|'
(let ((data-file (org-babel-temp-file "sql-data-")))
(with-temp-file data-file
(insert (orgtbl-to-csv
- val '(:fmt (lambda (el) (if (stringp el)
- el
- (format "%S" el)))))))
+ val (if sqlite
+ nil
+ '(:fmt (lambda (el) (if (stringp el)
+ el
+ (format "%S" el))))))))
data-file)
(if (stringp val) val (format "%S" val))))
body)))
diff --git a/lisp/org/ob-sqlite.el b/lisp/org/ob-sqlite.el
index 6e21fa9fd9a..7bfb66cf688 100644
--- a/lisp/org/ob-sqlite.el
+++ b/lisp/org/ob-sqlite.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2010-2021 Free Software Foundation, Inc.
;; Author: Eric Schulte
+;; Maintainer: Nick Savage
;; Keywords: literate programming, reproducible research
;; Homepage: https://orgmode.org
@@ -27,6 +28,7 @@
;;; Code:
(require 'ob)
+(require 'ob-sql)
(declare-function org-table-convert-region "org-table"
(beg0 end0 &optional separator))
@@ -51,8 +53,8 @@
(defun org-babel-expand-body:sqlite (body params)
"Expand BODY according to the values of PARAMS."
- (org-babel-sqlite-expand-vars
- body (org-babel--get-vars params)))
+ (org-babel-sql-expand-vars
+ body (org-babel--get-vars params) t))
(defvar org-babel-sqlite3-command "sqlite3")
@@ -112,22 +114,8 @@ This function is called by `org-babel-execute-src-block'."
(defun org-babel-sqlite-expand-vars (body vars)
"Expand the variables held in VARS in BODY."
- ;; FIXME: Redundancy with org-babel-sql-expand-vars!
- (mapc
- (lambda (pair)
- (setq body
- (replace-regexp-in-string
- (format "$%s" (car pair))
- (let ((val (cdr pair)))
- (if (listp val)
- (let ((data-file (org-babel-temp-file "sqlite-data-")))
- (with-temp-file data-file
- (insert (orgtbl-to-csv val nil)))
- data-file)
- (if (stringp val) val (format "%S" val))))
- body)))
- vars)
- body)
+ (declare (obsolete "use `org-babel-sql-expand-vars' instead." "9.5"))
+ (org-babel-sql-expand-vars body vars t))
(defun org-babel-sqlite-table-or-scalar (result)
"If RESULT looks like a trivial table, then unwrap it."
@@ -137,7 +125,7 @@ This function is called by `org-babel-execute-src-block'."
(mapcar (lambda (row)
(if (eq 'hline row)
'hline
- (mapcar #'org-babel-string-read row)))
+ (mapcar #'org-babel-sqlite--read-cell row)))
result)))
(defun org-babel-sqlite-offset-colnames (table headers-p)
@@ -151,6 +139,10 @@ This function is called by `org-babel-execute-src-block'."
Prepare SESSION according to the header arguments specified in PARAMS."
(error "SQLite sessions not yet implemented"))
+(defun org-babel-sqlite--read-cell (cell)
+ "Process CELL to remove unnecessary characters."
+ (org-babel-read cell t))
+
(provide 'ob-sqlite)
;;; ob-sqlite.el ends here
diff --git a/lisp/org/ob-stan.el b/lisp/org/ob-stan.el
deleted file mode 100644
index 1f2afdeeda7..00000000000
--- a/lisp/org/ob-stan.el
+++ /dev/null
@@ -1,86 +0,0 @@
-;;; ob-stan.el --- Babel Functions for Stan -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2015-2021 Free Software Foundation, Inc.
-
-;; Author: Kyle Meyer
-;; Keywords: literate programming, reproducible research
-;; Homepage: https://orgmode.org
-
-;; 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:
-
-;; Org-Babel support for evaluating Stan [1] source code.
-;;
-;; Evaluating a Stan block can produce two different results.
-;;
-;; 1) Dump the source code contents to a file.
-;;
-;; This file can then be used as a variable in other blocks, which
-;; allows interfaces like RStan to use the model.
-;;
-;; 2) Compile the contents to a model file.
-;;
-;; This provides access to the CmdStan interface. To use this, set
-;; `org-babel-stan-cmdstan-directory' and provide a :file argument
-;; that does not end in ".stan".
-;;
-;; For more information and usage examples, visit
-;; https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-stan.html
-;;
-;; [1] https://mc-stan.org/
-
-;;; Code:
-(require 'ob)
-(require 'org-compat)
-
-(defcustom org-babel-stan-cmdstan-directory nil
- "CmdStan source directory.
-Call \"make\" from this directory to compile the Stan block.
-When nil, executing Stan blocks dumps the content to a file."
- :group 'org-babel
- :type '(choice
- (directory :tag "Compilation directory")
- (const :tag "Dump to a file" nil)))
-
-(defvar org-babel-default-header-args:stan
- '((:results . "file")))
-
-(defun org-babel-execute:stan (body params)
- "Generate Stan file from BODY according to PARAMS.
-A :file header argument must be given. If
-`org-babel-stan-cmdstan-directory' is non-nil and the file name
-does not have a \".stan\" extension, save an intermediate
-\".stan\" file and compile the block to the named file.
-Otherwise, write the Stan code directly to the named file."
- (let ((file (expand-file-name
- (or (cdr (assq :file params))
- (user-error "Set :file argument to execute Stan blocks")))))
- (if (or (not org-babel-stan-cmdstan-directory)
- (string-match-p "\\.stan\\'" file))
- (with-temp-file file (insert body))
- (with-temp-file (concat file ".stan") (insert body))
- (let ((default-directory org-babel-stan-cmdstan-directory))
- (call-process-shell-command (concat "make " file))))
- nil)) ; Signal that output has been written to file.
-
-(defun org-babel-prep-session:stan (_session _params)
- "Return an error because Stan does not support sessions."
- (user-error "Stan does not support sessions"))
-
-(provide 'ob-stan)
-
-;;; ob-stan.el ends here
diff --git a/lisp/org/ob-table.el b/lisp/org/ob-table.el
index 39a14a25d6c..e081708701d 100644
--- a/lisp/org/ob-table.el
+++ b/lisp/org/ob-table.el
@@ -78,7 +78,8 @@ So this `org-sbe' construct
is the equivalent of the following source code block:
- #+begin_src emacs-lisp :var results=source-block(n=val_at_col_2, m=3) :results silent
+ #+begin_src emacs-lisp :var results=source-block(n=val_at_col_2, m=3) \\
+ :results silent
results
#+end_src
diff --git a/lisp/org/ob-tangle.el b/lisp/org/ob-tangle.el
index aa0373ab88e..2dd1d031cb2 100644
--- a/lisp/org/ob-tangle.el
+++ b/lisp/org/ob-tangle.el
@@ -43,6 +43,7 @@
(declare-function org-in-commented-heading-p "org" (&optional no-inheritance))
(declare-function org-in-archived-heading-p "org" (&optional no-inheritance))
(declare-function outline-previous-heading "outline" ())
+(defvar org-id-link-to-org-use-id nil) ; Dynamically scoped
(defcustom org-babel-tangle-lang-exts
'(("emacs-lisp" . "el")
@@ -169,11 +170,14 @@ evaluating BODY."
(defun org-babel-tangle-file (file &optional target-file lang-re)
"Extract the bodies of source code blocks in FILE.
Source code blocks are extracted with `org-babel-tangle'.
+
Optional argument TARGET-FILE can be used to specify a default
-export file for all source blocks. Optional argument LANG-RE can
-be used to limit the exported source code blocks by languages
-matching a regular expression. Return a list whose CAR is the
-tangled file name."
+export file for all source blocks.
+
+Optional argument LANG-RE can be used to limit the exported
+source code blocks by languages matching a regular expression.
+
+Return a list whose CAR is the tangled file name."
(interactive "fFile to tangle: \nP")
(let ((visited-p (find-buffer-visiting (expand-file-name file)))
to-be-removed)
@@ -225,67 +229,55 @@ matching a regular expression."
(or (cdr (assq :tangle (nth 2 (org-babel-get-src-block-info 'light))))
(user-error "Point is not in a source code block"))))
path-collector)
- (mapc ;; map over all languages
- (lambda (by-lang)
- (let* ((lang (car by-lang))
- (specs (cdr by-lang))
- (ext (or (cdr (assoc lang org-babel-tangle-lang-exts)) lang))
- (lang-f (org-src-get-lang-mode lang))
- she-banged)
- (mapc
- (lambda (spec)
- (let ((get-spec (lambda (name) (cdr (assoc name (nth 4 spec))))))
- (let* ((tangle (funcall get-spec :tangle))
- (she-bang (let ((sheb (funcall get-spec :shebang)))
- (when (> (length sheb) 0) sheb)))
- (tangle-mode (funcall get-spec :tangle-mode))
- (base-name (cond
- ((string= "yes" tangle)
- (file-name-sans-extension
- (nth 1 spec)))
- ((string= "no" tangle) nil)
- ((> (length tangle) 0) tangle)))
- (file-name (when base-name
- ;; decide if we want to add ext to base-name
- (if (and ext (string= "yes" tangle))
- (concat base-name "." ext) base-name))))
- (when file-name
- ;; Possibly create the parent directories for file.
- (let ((m (funcall get-spec :mkdirp))
- (fnd (file-name-directory file-name)))
- (and m fnd (not (string= m "no"))
- (make-directory fnd 'parents)))
- ;; delete any old versions of file
- (and (file-exists-p file-name)
- (not (member file-name (mapcar #'car path-collector)))
- (delete-file file-name))
- ;; drop source-block to file
- (with-temp-buffer
- (when (fboundp lang-f) (ignore-errors (funcall lang-f)))
- (when (and she-bang (not (member file-name she-banged)))
+ (mapc ;; map over file-names
+ (lambda (by-fn)
+ (let ((file-name (car by-fn)))
+ (when file-name
+ (let ((lspecs (cdr by-fn))
+ (fnd (file-name-directory file-name))
+ modes make-dir she-banged lang)
+ ;; drop source-blocks to file
+ ;; We avoid append-to-file as it does not work with tramp.
+ (with-temp-buffer
+ (mapc
+ (lambda (lspec)
+ (let* ((block-lang (car lspec))
+ (spec (cdr lspec))
+ (get-spec (lambda (name) (cdr (assq name (nth 4 spec)))))
+ (she-bang (let ((sheb (funcall get-spec :shebang)))
+ (when (> (length sheb) 0) sheb)))
+ (tangle-mode (funcall get-spec :tangle-mode)))
+ (unless (string-equal block-lang lang)
+ (setq lang block-lang)
+ (let ((lang-f (org-src-get-lang-mode lang)))
+ (when (fboundp lang-f) (ignore-errors (funcall lang-f)))))
+ ;; if file contains she-bangs, then make it executable
+ (when she-bang
+ (unless tangle-mode (setq tangle-mode #o755)))
+ (when tangle-mode
+ (add-to-list 'modes tangle-mode))
+ ;; Possibly create the parent directories for file.
+ (let ((m (funcall get-spec :mkdirp)))
+ (and m fnd (not (string= m "no"))
+ (setq make-dir t)))
+ ;; Handle :padlines unless first line in file
+ (unless (or (string= "no" (funcall get-spec :padline))
+ (= (point) (point-min)))
+ (insert "\n"))
+ (when (and she-bang (not she-banged))
(insert (concat she-bang "\n"))
- (setq she-banged (cons file-name she-banged)))
- (org-babel-spec-to-string spec)
- ;; We avoid append-to-file as it does not work with tramp.
- (let ((content (buffer-string)))
- (with-temp-buffer
- (when (file-exists-p file-name)
- (insert-file-contents file-name))
- (goto-char (point-max))
- ;; Handle :padlines unless first line in file
- (unless (or (string= "no" (cdr (assq :padline (nth 4 spec))))
- (= (point) (point-min)))
- (insert "\n"))
- (insert content)
- (write-region nil nil file-name))))
- ;; if files contain she-bangs, then make the executable
- (when she-bang
- (unless tangle-mode (setq tangle-mode #o755)))
- ;; update counter
- (setq block-counter (+ 1 block-counter))
- (unless (assoc file-name path-collector)
- (push (cons file-name tangle-mode) path-collector))))))
- specs)))
+ (setq she-banged t))
+ (org-babel-spec-to-string spec)
+ (setq block-counter (+ 1 block-counter))))
+ lspecs)
+ (when make-dir
+ (make-directory fnd 'parents))
+ ;; erase previous file
+ (when (file-exists-p file-name)
+ (delete-file file-name))
+ (write-region nil nil file-name)
+ (mapc (lambda (mode) (set-file-modes file-name mode)) modes)
+ (push file-name path-collector))))))
(if (equal arg '(4))
(org-babel-tangle-single-block 1 t)
(org-babel-tangle-collect-blocks lang-re tangle-file)))
@@ -293,19 +285,18 @@ matching a regular expression."
(if (= block-counter 1) "" "s")
(file-name-nondirectory
(buffer-file-name
- (or (buffer-base-buffer) (current-buffer)))))
+ (or (buffer-base-buffer)
+ (current-buffer)
+ (and (org-src-edit-buffer-p)
+ (org-src-source-buffer))))))
;; run `org-babel-post-tangle-hook' in all tangled files
(when org-babel-post-tangle-hook
(mapc
(lambda (file)
(org-babel-with-temp-filebuffer file
(run-hooks 'org-babel-post-tangle-hook)))
- (mapcar #'car path-collector)))
- ;; set permissions on tangled files
- (mapc (lambda (pair)
- (when (cdr pair) (set-file-modes (car pair) (cdr pair))))
- path-collector)
- (mapcar #'car path-collector)))))
+ path-collector))
+ path-collector))))
(defun org-babel-tangle-clean ()
"Remove comments inserted by `org-babel-tangle'.
@@ -366,12 +357,32 @@ that the appropriate major-mode is set. SPEC has the form:
(org-fill-template
org-babel-tangle-comment-format-end link-data)))))
+(defun org-babel-effective-tangled-filename (buffer-fn src-lang src-tfile)
+ "Return effective tangled filename of a source-code block.
+BUFFER-FN is the name of the buffer, SRC-LANG the language of the
+block and SRC-TFILE is the value of the :tangle header argument,
+as computed by `org-babel-tangle-single-block'."
+ (let ((base-name (cond
+ ((string= "yes" src-tfile)
+ ;; Use the buffer name
+ (file-name-sans-extension buffer-fn))
+ ((string= "no" src-tfile) nil)
+ ((> (length src-tfile) 0) src-tfile)))
+ (ext (or (cdr (assoc src-lang org-babel-tangle-lang-exts)) src-lang)))
+ (when base-name
+ ;; decide if we want to add ext to base-name
+ (if (and ext (string= "yes" src-tfile))
+ (concat base-name "." ext) base-name))))
+
(defun org-babel-tangle-collect-blocks (&optional lang-re tangle-file)
"Collect source blocks in the current Org file.
-Return an association list of source-code block specifications of
-the form used by `org-babel-spec-to-string' grouped by language.
+Return an association list of language and source-code block
+specifications of the form used by `org-babel-spec-to-string'
+grouped by tangled file name.
+
Optional argument LANG-RE can be used to limit the collected
source code blocks by languages matching a regular expression.
+
Optional argument TANGLE-FILE can be used to limit the collected
code blocks by target file."
(let ((counter 0) last-heading-pos blocks)
@@ -390,12 +401,15 @@ code blocks by target file."
(unless (or (string= src-tfile "no")
(and tangle-file (not (equal tangle-file src-tfile)))
(and lang-re (not (string-match-p lang-re src-lang))))
- ;; Add the spec for this block to blocks under its
- ;; language.
- (let ((by-lang (assoc src-lang blocks))
- (block (org-babel-tangle-single-block counter)))
- (if by-lang (setcdr by-lang (cons block (cdr by-lang)))
- (push (cons src-lang (list block)) blocks)))))))
+ ;; Add the spec for this block to blocks under its tangled
+ ;; file name.
+ (let* ((block (org-babel-tangle-single-block counter))
+ (src-tfile (cdr (assq :tangle (nth 4 block))))
+ (file-name (org-babel-effective-tangled-filename
+ (nth 1 block) src-lang src-tfile))
+ (by-fn (assoc file-name blocks)))
+ (if by-fn (setcdr by-fn (cons (cons src-lang block) (cdr by-fn)))
+ (push (cons file-name (list (cons src-lang block))) blocks)))))))
;; Ensure blocks are in the correct order.
(mapcar (lambda (b) (cons (car b) (nreverse (cdr b))))
(nreverse blocks))))
@@ -414,10 +428,16 @@ non-nil, return the full association list to be used by
(src-lang (nth 0 info))
(params (nth 2 info))
(extra (nth 3 info))
- (cref-fmt (or (and (string-match "-l \"\\(.+\\)\"" extra)
- (match-string 1 extra))
- org-coderef-label-format))
- (link (let ((l (org-no-properties (org-store-link nil))))
+ (coderef (nth 6 info))
+ (cref-regexp (org-src-coderef-regexp coderef))
+ (link (let* (
+ ;; The created link is transient. Using ID is
+ ;; not necessary, but could have side-effects if
+ ;; used. An ID property may be added to
+ ;; existing entries thus creatin unexpected file
+ ;; modifications.
+ (org-id-link-to-org-use-id nil)
+ (l (org-no-properties (org-store-link nil))))
(and (string-match org-link-bracket-re l)
(match-string 1 l))))
(source-name
@@ -445,8 +465,7 @@ non-nil, return the full association list to be used by
(funcall assignments-cmd params))))))
(when (string-match "-r" extra)
(goto-char (point-min))
- (while (re-search-forward
- (replace-regexp-in-string "%s" ".+" cref-fmt) nil t)
+ (while (re-search-forward cref-regexp nil t)
(replace-match "")))
(run-hooks 'org-babel-tangle-body-hook)
(buffer-string))))
@@ -488,7 +507,10 @@ non-nil, return the full association list to be used by
(org-trim (org-remove-indentation body)))
comment)))
(if only-this-block
- (list (cons src-lang (list result)))
+ (let* ((src-tfile (cdr (assq :tangle (nth 4 result))))
+ (file-name (org-babel-effective-tangled-filename
+ (nth 1 result) src-lang src-tfile)))
+ (list (cons file-name (list (cons src-lang result)))))
result)))
(defun org-babel-tangle-comment-links (&optional info)
@@ -501,7 +523,13 @@ by `org-babel-get-src-block-info'."
(number-to-string
(line-number-at-pos))))
("file" . ,(buffer-file-name))
- ("link" . ,(org-no-properties (org-store-link nil)))
+ ("link" . ,(let (;; The created link is transient. Using ID is
+ ;; not necessary, but could have side-effects if
+ ;; used. An ID property may be added to
+ ;; existing entries thus creatin unexpected file
+ ;; modifications.
+ (org-id-link-to-org-use-id nil))
+ (org-no-properties (org-store-link nil))))
("source-name" . ,name))))))
(list (org-fill-template org-babel-tangle-comment-format-beg link-data)
(org-fill-template org-babel-tangle-comment-format-end link-data))))
diff --git a/lisp/org/ob-vala.el b/lisp/org/ob-vala.el
deleted file mode 100644
index 6c3068a8b47..00000000000
--- a/lisp/org/ob-vala.el
+++ /dev/null
@@ -1,116 +0,0 @@
-;;; ob-vala.el --- Babel functions for Vala evaluation -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2017-2021 Free Software Foundation, Inc.
-
-;; Author: Christian Garbs <mitch@cgarbs.de>
-;; Keywords: literate programming, reproducible research
-;; Homepage: https://orgmode.org
-
-;;; License:
-
-;; 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:
-
-;; ob-vala.el provides Babel support for the Vala language
-;; (see https://live.gnome.org/Vala for details)
-
-;;; Requirements:
-
-;; - Vala compiler binary (valac)
-;; - Vala development environment (Vala libraries etc.)
-;;
-;; vala-mode.el is nice to have for code formatting, but is not needed
-;; for ob-vala.el
-
-;;; Code:
-
-(require 'ob)
-(require 'org-macs)
-
-;; File extension.
-(add-to-list 'org-babel-tangle-lang-exts '("vala" . "vala"))
-
-;; Header arguments empty by default.
-(defvar org-babel-default-header-args:vala '())
-
-(defcustom org-babel-vala-compiler "valac"
- "Command used to compile a C source code file into an executable.
-May be either a command in the path, like \"valac\"
-or an absolute path name, like \"/usr/local/bin/valac\".
-Parameters may be used like this: \"valac -v\""
- :group 'org-babel
- :version "26.1"
- :package-version '(Org . "9.1")
- :type 'string)
-
-;; This is the main function which is called to evaluate a code
-;; block.
-;;
-;; - run Vala compiler and create a binary in a temporary file
-;; - compiler/linker flags can be set via :flags header argument
-;; - if compilation succeeded, run the binary
-;; - commandline parameters to the binary can be set via :cmdline
-;; header argument
-;; - stdout will be parsed as RESULT (control via :result-params
-;; header argument)
-;;
-;; There is no session support because Vala is a compiled language.
-;;
-;; This function is heavily based on ob-C.el
-(defun org-babel-execute:vala (body params)
- "Execute a block of Vala code with Babel.
-This function is called by `org-babel-execute-src-block'."
- (message "executing Vala source code block")
- (let* ((tmp-src-file (org-babel-temp-file
- "vala-src-"
- ".vala"))
- (tmp-bin-file (org-babel-temp-file "vala-bin-" org-babel-exeext))
- (cmdline (cdr (assq :cmdline params)))
- (flags (cdr (assq :flags params))))
- (with-temp-file tmp-src-file (insert body))
- (org-babel-eval
- (format "%s %s -o %s %s"
- org-babel-vala-compiler
- (mapconcat #'identity
- (if (listp flags) flags (list flags)) " ")
- (org-babel-process-file-name tmp-bin-file)
- (org-babel-process-file-name tmp-src-file)) "")
- (when (file-executable-p tmp-bin-file)
- (let ((results
- (org-trim
- (org-babel-eval
- (concat tmp-bin-file (if cmdline (concat " " cmdline) "")) ""))))
- (org-babel-reassemble-table
- (org-babel-result-cond (cdr (assq :result-params params))
- (org-babel-read results)
- (let ((tmp-file (org-babel-temp-file "vala-")))
- (with-temp-file tmp-file (insert results))
- (org-babel-import-elisp-from-file tmp-file)))
- (org-babel-pick-name
- (cdr (assq :colname-names params)) (cdr (assq :colnames params)))
- (org-babel-pick-name
- (cdr (assq :rowname-names params)) (cdr (assq :rownames params))))))))
-
-(defun org-babel-prep-session:vala (_session _params)
- "Prepare a session.
-This function does nothing as Vala is a compiled language with no
-support for sessions."
- (error "Vala is a compiled language -- no support for sessions"))
-
-(provide 'ob-vala)
-
-;;; ob-vala.el ends here
diff --git a/lisp/org/oc-basic.el b/lisp/org/oc-basic.el
new file mode 100644
index 00000000000..7c83bdc27c0
--- /dev/null
+++ b/lisp/org/oc-basic.el
@@ -0,0 +1,789 @@
+;;; oc-basic.el --- basic back-end for citations -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
+
+;; 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:
+
+;; The `basic' citation processor provides "activate", "follow", "export" and
+;; "insert" capabilities.
+
+;; "activate" capability re-uses default fontification, but provides additional
+;; features on both correct and wrong keys according to the bibliography
+;; defined in the document.
+
+;; When the mouse is over a known key, it displays the corresponding
+;; bibliography entry. Any wrong key, however, is highlighted with `error'
+;; face. Moreover, moving the mouse onto it displays a list of suggested correct
+;; keys, and pressing <mouse-1> on the faulty key will try to fix it according to
+;; those suggestions.
+
+;; On a citation key, "follow" capability moves point to the corresponding entry
+;; in the current bibliography. Elsewhere on the citation, it asks the user to
+;; follow any of the keys cited there, with completion.
+
+;; "export" capability supports the following citation styles:
+;;
+;; - author (a), including caps (c) variant,
+;; - noauthor (na) including bare (b) variant,
+;; - text (t), including bare (b), caps (c), and bare-caps (bc) variants,
+;; - note (ft, including bare (b), caps (c), and bare-caps (bc) variants,
+;; - nocite (n)
+;; - numeric (nb),
+;; - default, including bare (b), caps (c), and bare-caps (bc) variants.
+;;
+;; It also supports the following styles for bibliography:
+;; - plain
+;; - numeric
+;; - author-year (default)
+
+;; "insert" capability inserts or edits (with completion) citation style or
+;; citation reference keys. In an appropriate place, it offers to insert a new
+;; citation. With a prefix argument, it removes the one at point.
+
+;; It supports bibliography files in BibTeX (".bibtex"), biblatex (".bib") and
+;; JSON (".json") format.
+
+;; Disclaimer: this citation processor is meant to be a proof of concept, and
+;; possibly a fall-back mechanism when nothing else is available. It is too
+;; limited for any serious use case.
+
+;;; Code:
+
+(require 'bibtex)
+(require 'json)
+(require 'map)
+(require 'oc)
+(require 'seq)
+
+(declare-function org-open-at-point "org" (&optional arg))
+
+(declare-function org-element-interpret-data "org-element" (data))
+(declare-function org-element-property "org-element" (property element))
+(declare-function org-element-type "org-element" (element))
+
+(declare-function org-export-data "org-export" (data info))
+(declare-function org-export-derived-backend-p "org-export" (backend &rest backends))
+(declare-function org-export-raw-string "org-export" (contents))
+
+
+;;; Customization
+(defcustom org-cite-basic-sorting-field 'author
+ "Field used to sort bibliography items as a symbol, or nil."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type 'symbol
+ :safe #'symbolp)
+
+(defcustom org-cite-basic-author-year-separator ", "
+ "String used to separate cites in an author-year configuration."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type 'string
+ :safe #'stringp)
+
+(defcustom org-cite-basic-max-key-distance 2
+ "Maximum (Levenshtein) distance between a wrong key and its suggestions."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type 'integer
+ :safe #'integerp)
+
+(defcustom org-cite-basic-author-column-end 25
+ "Column where author field ends in completion table, as an integer."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type 'integer
+ :safe #'integerp)
+
+(defcustom org-cite-basic-column-separator " "
+ "Column separator in completion table, as a string."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type 'string
+ :safe #'stringp)
+
+(defcustom org-cite-basic-mouse-over-key-face 'highlight
+ "Face used when mouse is over a citation key."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type 'face
+ :safe #'facep)
+
+
+;;; Internal variables
+(defvar org-cite-basic--bibliography-cache nil
+ "Cache for parsed bibliography files.
+
+This is an association list following the pattern:
+
+ (FILE-ID . ENTRIES)
+
+FILE-ID is a cons cell (FILE . HASH), with FILE being the absolute file name of
+the bibliography file, and HASH a hash of its contents.
+
+ENTRIES is a hash table with citation references as keys and fields alist as
+values.")
+
+(defvar org-cite-basic--completion-cache (make-hash-table :test #'equal)
+ "Cache for key completion table.
+
+This is an a hash-table.")
+
+
+;;; Internal functions
+(defun org-cite-basic--parse-json ()
+ "Parse JSON entries in the current buffer.
+Return a hash table with citation references as keys and fields alist as values."
+ (let ((entries (make-hash-table :test #'equal)))
+ (let ((json-array-type 'list)
+ (json-key-type 'symbol))
+ (dolist (item (json-read))
+ (puthash (cdr (assq 'id item))
+ (mapcar (pcase-lambda (`(,field . ,value))
+ (pcase field
+ ('author
+ ;; Author is an array of objects, each
+ ;; of them designing a person. These
+ ;; objects may contain multiple
+ ;; properties, but for this basic
+ ;; processor, we'll focus on `given' and
+ ;; `family'.
+ ;;
+ ;; For compatibility with BibTeX, add
+ ;; "and" between authors.
+ (cons 'author
+ (mapconcat
+ (lambda (alist)
+ (concat (alist-get 'family alist)
+ " "
+ (alist-get 'given alist)))
+ value
+ " and ")))
+ ('issued
+ ;; Date are expressed as an array
+ ;; (`date-parts') or a "string (`raw').
+ ;; In both cases, extract the year and
+ ;; associate it to `year' field, for
+ ;; compatibility with BibTeX format.
+ (let ((date (or (alist-get 'date-parts value)
+ (alist-get 'raw value))))
+ (cons 'year
+ (cond
+ ((consp date)
+ (caar date))
+ ((stringp date)
+ (car (split-string date "-")))
+ (t
+ (error "Unknown CSL-JSON date format: %S"
+ date))))))
+ (_
+ (cons field value))))
+ item)
+ entries))
+ entries)))
+
+(defun org-cite-basic--parse-bibtex (dialect)
+ "Parse BibTeX entries in the current buffer.
+DIALECT is the BibTeX dialect used. See `bibtex-dialect'.
+Return a hash table with citation references as keys and fields alist as values."
+ (let ((entries (make-hash-table :test #'equal))
+ (bibtex-sort-ignore-string-entries t))
+ (bibtex-set-dialect dialect t)
+ (bibtex-map-entries
+ (lambda (key &rest _)
+ ;; Normalize entries: field names are turned into symbols
+ ;; including special "=key=" and "=type=", and consecutive
+ ;; white spaces are removed from values.
+ (puthash key
+ (mapcar
+ (pcase-lambda (`(,field . ,value))
+ (pcase field
+ ("=key=" (cons 'id key))
+ ("=type=" (cons 'type value))
+ (_
+ (cons
+ (intern (downcase field))
+ (replace-regexp-in-string "[ \t\n]+" " " value)))))
+ (bibtex-parse-entry t))
+ entries)))
+ entries))
+
+(defun org-cite-basic--parse-bibliography (&optional info)
+ "List all entries available in the buffer.
+
+Each association follows the pattern
+
+ (FILE . ENTRIES)
+
+where FILE is the absolute file name of the BibTeX file, and ENTRIES is a hash
+table where keys are references and values are association lists between fields,
+as symbols, and values as strings or nil.
+
+Optional argument INFO is the export state, as a property list."
+ (if (plist-member info :cite-basic/bibliography)
+ (plist-get info :cite-basic/bibliography)
+ (let ((results nil))
+ (dolist (file (org-cite-list-bibliography-files))
+ (when (file-readable-p file)
+ (with-temp-buffer
+ (insert-file-contents file)
+ (let* ((file-id (cons file (org-buffer-hash)))
+ (entries
+ (or (cdr (assoc file-id org-cite-basic--bibliography-cache))
+ (let ((table
+ (pcase (file-name-extension file)
+ ("json" (org-cite-basic--parse-json))
+ ("bib" (org-cite-basic--parse-bibtex 'biblatex))
+ ("bibtex" (org-cite-basic--parse-bibtex 'BibTeX))
+ (ext
+ (user-error "Unknown bibliography extension: %S"
+ ext)))))
+ (push (cons file-id table) org-cite-basic--bibliography-cache)
+ table))))
+ (push (cons file entries) results)))))
+ (when info (plist-put info :cite-basic/bibliography results))
+ results)))
+
+(defun org-cite-basic--key-number (key info)
+ "Return number associated to cited KEY.
+INFO is the export state, as a property list."
+ (let ((predicate
+ (org-cite-basic--field-less-p org-cite-basic-sorting-field info)))
+ (org-cite-key-number key info predicate)))
+
+(defun org-cite-basic--all-keys ()
+ "List all keys available in current bibliography."
+ (seq-mapcat (pcase-lambda (`(,_ . ,entries))
+ (map-keys entries))
+ (org-cite-basic--parse-bibliography)))
+
+(defun org-cite-basic--get-entry (key &optional info)
+ "Return BibTeX entry for KEY, as an association list.
+When non-nil, INFO is the export state, as a property list."
+ (catch :found
+ (pcase-dolist (`(,_ . ,entries) (org-cite-basic--parse-bibliography info))
+ (let ((entry (gethash key entries)))
+ (when entry (throw :found entry))))
+ nil))
+
+(defun org-cite-basic--get-field (field entry-or-key &optional info raw)
+ "Return FIELD value for ENTRY-OR-KEY, or nil.
+
+FIELD is a symbol. ENTRY-OR-KEY is either an association list, as returned by
+`org-cite-basic--get-entry', or a string representing a citation key.
+
+Optional argument INFO is the export state, as a property list.
+
+Return value may be nil or a string. If current export back-end is derived
+from `latex', return a raw string instead, unless optional argument RAW is
+non-nil."
+ (let ((value
+ (cdr
+ (assq field
+ (pcase entry-or-key
+ ((pred stringp)
+ (org-cite-basic--get-entry entry-or-key info))
+ ((pred consp)
+ entry-or-key)
+ (_
+ (error "Wrong value for ENTRY-OR-KEY: %S" entry-or-key)))))))
+ (if (and value
+ (not raw)
+ (org-export-derived-backend-p (plist-get info :back-end) 'latex))
+ (org-export-raw-string value)
+ value)))
+
+(defun org-cite-basic--number-to-suffix (n)
+ "Compute suffix associated to number N.
+This is used for disambiguation."
+ (let ((result nil))
+ (apply #'string
+ (mapcar (lambda (n) (+ 97 n))
+ (catch :complete
+ (while t
+ (push (% n 26) result)
+ (setq n (/ n 26))
+ (cond
+ ((= n 0) (throw :complete result))
+ ((< n 27) (throw :complete (cons (1- n) result)))
+ ((= n 27) (throw :complete (cons 0 (cons 0 result))))
+ (t nil))))))))
+
+(defun org-cite-basic--get-year (entry-or-key info &optional no-suffix)
+ "Return year associated to ENTRY-OR-KEY.
+
+ENTRY-OR-KEY is either an association list, as returned by
+`org-cite-basic--get-entry', or a string representing a citation
+key. INFO is the export state, as a property list.
+
+Year is obtained from the \"year\" field, if available, or from
+the \"date\" field if it starts with a year pattern.
+
+Unlike `org-cite-basic--get-field', this function disambiguates
+author-year patterns by adding a letter suffix to the year when
+necessary, unless optional argument NO-SUFFIX is non-nil."
+ ;; The cache is an association list with the following structure:
+ ;;
+ ;; (AUTHOR-YEAR . KEY-SUFFIX-ALIST).
+ ;;
+ ;; AUTHOR-YEAR is the author year pair associated to current entry
+ ;; or key.
+ ;;
+ ;; KEY-SUFFIX-ALIST is an association (KEY . SUFFIX), where KEY is
+ ;; the cite key, as a string, and SUFFIX is the generated suffix
+ ;; string, or the empty string.
+ (let* ((author (org-cite-basic--get-field 'author entry-or-key info 'raw))
+ (year
+ (or (org-cite-basic--get-field 'year entry-or-key info 'raw)
+ (let ((date
+ (org-cite-basic--get-field 'date entry-or-key info t)))
+ (and (stringp date)
+ (string-match (rx string-start
+ (group (= 4 digit))
+ (or string-end (not digit)))
+ date)
+ (match-string 1 date)))))
+ (cache-key (cons author year))
+ (key
+ (pcase entry-or-key
+ ((pred stringp) entry-or-key)
+ ((pred consp) (cdr (assq 'id entry-or-key)))
+ (_ (error "Wrong value for ENTRY-OR-KEY: %S" entry-or-key))))
+ (cache (plist-get info :cite-basic/author-date-cache)))
+ (pcase (assoc cache-key cache)
+ ('nil
+ (let ((value (cons cache-key (list (cons key "")))))
+ (plist-put info :cite-basic/author-date-cache (cons value cache))
+ year))
+ (`(,_ . ,alist)
+ (let ((suffix
+ (or (cdr (assoc key alist))
+ (let ((new (org-cite-basic--number-to-suffix
+ (1- (length alist)))))
+ (push (cons key new) alist)
+ new))))
+ (if no-suffix year (concat year suffix)))))))
+
+(defun org-cite-basic--print-entry (entry style &optional info)
+ "Format ENTRY according to STYLE string.
+ENTRY is an alist, as returned by `org-cite-basic--get-entry'.
+Optional argument INFO is the export state, as a property list."
+ (let ((author (org-cite-basic--get-field 'author entry info))
+ (title (org-cite-basic--get-field 'title entry info))
+ (from
+ (or (org-cite-basic--get-field 'publisher entry info)
+ (org-cite-basic--get-field 'journal entry info)
+ (org-cite-basic--get-field 'institution entry info)
+ (org-cite-basic--get-field 'school entry info))))
+ (pcase style
+ ("plain"
+ (let ((year (org-cite-basic--get-year entry info 'no-suffix)))
+ (org-cite-concat
+ author ". " title (and from (list ", " from)) ", " year ".")))
+ ("numeric"
+ (let ((n (org-cite-basic--key-number (cdr (assq 'id entry)) info))
+ (year (org-cite-basic--get-year entry info 'no-suffix)))
+ (org-cite-concat
+ (format "[%d] " n) author ", "
+ (org-cite-emphasize 'italic title)
+ (and from (list ", " from)) ", "
+ year ".")))
+ ;; Default to author-year. Use year disambiguation there.
+ (_
+ (let ((year (org-cite-basic--get-year entry info)))
+ (org-cite-concat
+ author " (" year "). "
+ (org-cite-emphasize 'italic title)
+ (and from (list ", " from)) "."))))))
+
+
+;;; "Activate" capability
+(defun org-cite-basic--close-keys (key keys)
+ "List cite keys close to KEY in terms of string distance."
+ (seq-filter (lambda (k)
+ (>= org-cite-basic-max-key-distance
+ (org-string-distance k key)))
+ keys))
+
+(defun org-cite-basic--set-keymap (beg end suggestions)
+ "Set keymap on citation key between BEG and END positions.
+
+When the key is know, SUGGESTIONS is nil. Otherwise, it may be
+a list of replacement keys, as strings, which will be offered as
+substitutes for the unknown key. Finally, it may be the symbol
+`all'."
+ (let ((km (make-sparse-keymap)))
+ (define-key km (kbd "<mouse-1>")
+ (pcase suggestions
+ ('nil #'org-open-at-point)
+ ('all #'org-cite-insert)
+ (_
+ (lambda ()
+ (interactive)
+ (setf (buffer-substring beg end)
+ (concat "@"
+ (if (= 1 (length suggestions))
+ (car suggestions)
+ (completing-read "Did you mean: "
+ suggestions nil t))))))))
+ (put-text-property beg end 'keymap km)))
+
+(defun org-cite-basic-activate (citation)
+ "Set various text properties on CITATION object.
+
+Fontify whole citation with `org-cite' face. Fontify key with `error' face
+when it does not belong to known keys. Otherwise, use `org-cite-key' face.
+
+Moreover, when mouse is on a known key, display the corresponding bibliography.
+On a wrong key, suggest a list of possible keys, and offer to substitute one of
+them with a mouse click."
+ (pcase-let ((`(,beg . ,end) (org-cite-boundaries citation))
+ (keys (org-cite-basic--all-keys)))
+ (put-text-property beg end 'font-lock-multiline t)
+ (add-face-text-property beg end 'org-cite)
+ (dolist (reference (org-cite-get-references citation))
+ (pcase-let* ((`(,beg . ,end) (org-cite-key-boundaries reference))
+ (key (org-element-property :key reference)))
+ ;; Highlight key on mouse over.
+ (put-text-property beg end
+ 'mouse-face
+ org-cite-basic-mouse-over-key-face)
+ (if (member key keys)
+ ;; Activate a correct key. Face is `org-cite-key' and
+ ;; `help-echo' displays bibliography entry, for reference.
+ ;; <mouse-1> calls `org-open-at-point'.
+ (let* ((entry (org-cite-basic--get-entry key))
+ (bibliography-entry
+ (org-element-interpret-data
+ (org-cite-basic--print-entry entry "plain"))))
+ (add-face-text-property beg end 'org-cite-key)
+ (put-text-property beg end 'help-echo bibliography-entry)
+ (org-cite-basic--set-keymap beg end nil))
+ ;; Activate a wrong key. Face is `error', `help-echo'
+ ;; displays possible suggestions.
+ (add-face-text-property beg end 'error)
+ (let ((close-keys (org-cite-basic--close-keys key keys)))
+ (when close-keys
+ (put-text-property beg end 'help-echo
+ (concat "Suggestions (mouse-1 to substitute): "
+ (mapconcat #'identity close-keys " "))))
+ ;; When the are close know keys, <mouse-1> provides
+ ;; completion to fix the current one. Otherwise, call
+ ;; `org-cite-insert'.
+ (org-cite-basic--set-keymap beg end (or close-keys 'all))))))))
+
+
+;;; "Export" capability
+(defun org-cite-basic--format-author-year (citation format-cite format-ref info)
+ "Format CITATION object according to author-year format.
+
+FORMAT-CITE is a function of three arguments: the global prefix, the contents,
+and the global suffix. All arguments can be strings or secondary strings.
+
+FORMAT-REF is a function of four arguments: the reference prefix, as a string or
+secondary string, the author, the year, and the reference suffix, as a string or
+secondary string.
+
+INFO is the export state, as a property list."
+ (org-export-data
+ (funcall format-cite
+ (org-element-property :prefix citation)
+ (org-cite-mapconcat
+ (lambda (ref)
+ (let ((k (org-element-property :key ref))
+ (prefix (org-element-property :prefix ref))
+ (suffix (org-element-property :suffix ref)))
+ (funcall format-ref
+ prefix
+ (org-cite-basic--get-field 'author k info)
+ (org-cite-basic--get-year k info)
+ suffix)))
+ (org-cite-get-references citation)
+ org-cite-basic-author-year-separator)
+ (org-element-property :suffix citation))
+ info))
+
+(defun org-cite-basic--citation-numbers (citation info)
+ "Return numbers associated to references in CITATION object.
+INFO is the export state as a property list."
+ (let* ((numbers
+ (sort (mapcar (lambda (k) (org-cite-basic--key-number k info))
+ (org-cite-get-references citation t))
+ #'<))
+ (last (car numbers))
+ (result (list (number-to-string (pop numbers)))))
+ ;; Use compact number references, i.e., "1, 2, 3" becomes "1-3".
+ (while numbers
+ (let ((current (pop numbers))
+ (next (car numbers)))
+ (cond
+ ((and next
+ (= current (1+ last))
+ (= current (1- next)))
+ (unless (equal "-" (car result))
+ (push "-" result)))
+ ((equal "-" (car result))
+ (push (number-to-string current) result))
+ (t
+ (push (format ", %d" current) result)))
+ (setq last current)))
+ (apply #'concat (nreverse result))))
+
+(defun org-cite-basic--field-less-p (field info)
+ "Return a sort predicate comparing FIELD values for two citation keys.
+INFO is the export state, as a property list."
+ (and field
+ (lambda (a b)
+ (org-string-collate-lessp
+ (org-cite-basic--get-field field a info 'raw)
+ (org-cite-basic--get-field field b info 'raw)
+ nil t))))
+
+(defun org-cite-basic--sort-keys (keys info)
+ "Sort KEYS by author name.
+INFO is the export communication channel, as a property list."
+ (let ((predicate (org-cite-basic--field-less-p org-cite-basic-sorting-field info)))
+ (if predicate
+ (sort keys predicate)
+ keys)))
+
+(defun org-cite-basic-export-citation (citation style _ info)
+ "Export CITATION object.
+STYLE is the expected citation style, as a pair of strings or nil. INFO is the
+export communication channel, as a property list."
+ (let ((has-variant-p
+ (lambda (variant type)
+ ;; Non-nil when style VARIANT has TYPE. TYPE is either
+ ;; `bare' or `caps'.
+ (member variant
+ (pcase type
+ ('bare '("bare" "bare-caps" "b" "bc"))
+ ('caps '("caps" "bare-caps" "c" "bc"))
+ (_ (error "Invalid variant type: %S" type)))))))
+ (pcase style
+ ;; "author" style.
+ (`(,(or "author" "a") . ,variant)
+ (let ((caps (member variant '("caps" "c"))))
+ (org-export-data
+ (mapconcat
+ (lambda (key)
+ (let ((author (org-cite-basic--get-field 'author key info)))
+ (if caps (capitalize author) author)))
+ (org-cite-get-references citation t)
+ org-cite-basic-author-year-separator)
+ info)))
+ ;; "noauthor" style.
+ (`(,(or "noauthor" "na") . ,variant)
+ (format (if (funcall has-variant-p variant 'bare) "%s" "(%s)")
+ (mapconcat (lambda (key) (org-cite-basic--get-year key info))
+ (org-cite-get-references citation t)
+ org-cite-basic-author-year-separator)))
+ ;; "nocite" style.
+ (`(,(or "nocite" "n") . ,_) nil)
+ ;; "text" and "note" styles.
+ (`(,(and (or "text" "note" "t" "ft") style) . ,variant)
+ (when (and (member style '("note" "ft"))
+ (not (org-cite-inside-footnote-p citation)))
+ (org-cite-adjust-note citation info)
+ (org-cite-wrap-citation citation info))
+ (let ((bare (funcall has-variant-p variant 'bare))
+ (caps (funcall has-variant-p variant 'caps)))
+ (org-cite-basic--format-author-year
+ citation
+ (lambda (p c s) (org-cite-concat p c s))
+ (lambda (p a y s)
+ (org-cite-concat p
+ (if caps (capitalize a) a)
+ (if bare " " " (")
+ y s
+ (and (not bare) ")")))
+ info)))
+ ;; "numeric" style.
+ ;;
+ ;; When using this style on citations with multiple references,
+ ;; use global affixes and ignore local ones.
+ (`(,(or "numeric" "nb") . ,_)
+ (pcase-let ((`(,prefix . ,suffix) (org-cite-main-affixes citation)))
+ (org-export-data
+ (org-cite-concat
+ "(" prefix (org-cite-basic--citation-numbers citation info) suffix ")")
+ info)))
+ ;; Default ("nil") style.
+ (`(,_ . ,variant)
+ (let ((bare (funcall has-variant-p variant 'bare))
+ (caps (funcall has-variant-p variant 'caps)))
+ (org-cite-basic--format-author-year
+ citation
+ (lambda (p c s)
+ (org-cite-concat (and (not bare) "(") p c s (and (not bare) ")")))
+ (lambda (p a y s)
+ (org-cite-concat p (if caps (capitalize a) a) ", " y s))
+ info)))
+ ;; This should not happen.
+ (_ (error "Invalid style: %S" style)))))
+
+(defun org-cite-basic-export-bibliography (keys _files style _props backend info)
+ "Generate bibliography.
+KEYS is the list of cited keys, as strings. STYLE is the expected bibliography
+style, as a string. BACKEND is the export back-end, as a symbol. INFO is the
+export state, as a property list."
+ (mapconcat
+ (lambda (k)
+ (let ((entry (org-cite-basic--get-entry k info)))
+ (org-export-data
+ (org-cite-make-paragraph
+ (and (org-export-derived-backend-p backend 'latex)
+ (org-export-raw-string "\\noindent\n"))
+ (org-cite-basic--print-entry entry style info))
+ info)))
+ (org-cite-basic--sort-keys keys info)
+ "\n"))
+
+
+;;; "Follow" capability
+(defun org-cite-basic-goto (datum _)
+ "Follow citation or citation reference DATUM.
+When DATUM is a citation reference, open bibliography entry referencing
+the citation key. Otherwise, select which key to follow among all keys
+present in the citation."
+ (let* ((key
+ (if (eq 'citation-reference (org-element-type datum))
+ (org-element-property :key datum)
+ (pcase (org-cite-get-references datum t)
+ (`(,key) key)
+ (keys
+ (or (completing-read "Select citation key: " keys nil t)
+ (user-error "Aborted"))))))
+ (file
+ (pcase (seq-find (pcase-lambda (`(,_ . ,entries))
+ (gethash key entries))
+ (org-cite-basic--parse-bibliography))
+ (`(,f . ,_) f)
+ (_ (user-error "Cannot find citation key: %S" key)))))
+ (org-open-file file '(4))
+ (pcase (file-name-extension file)
+ ("json"
+ ;; `rx' can not be used with Emacs <27.1 since `literal' form
+ ;; is not supported.
+ (let ((regexp (rx-to-string `(seq "\"id\":" (0+ (any "[ \t]")) "\"" ,key "\"") t)))
+ (goto-char (point-min))
+ (re-search-forward regexp)
+ (search-backward "{")))
+ (_
+ (bibtex-set-dialect)
+ (bibtex-search-entry key)))))
+
+
+;;; "Insert" capability
+(defun org-cite-basic--complete-style (_)
+ "Offer completion for style.
+Return chosen style as a string."
+ (let* ((styles
+ (mapcar (pcase-lambda (`((,style . ,_) . ,_))
+ style)
+ (org-cite-supported-styles))))
+ (pcase styles
+ (`(,style) style)
+ (_ (completing-read "Style (\"\" for default): " styles nil t)))))
+
+(defun org-cite-basic--key-completion-table ()
+ "Return completion table for cite keys, as a hash table.
+
+In this hash table, keys are a strings with author, date, and
+title of the reference. Values are the cite keys.
+
+Return nil if there are no bibliography files or no entries."
+ ;; Populate bibliography cache.
+ (let ((entries (org-cite-basic--parse-bibliography)))
+ (cond
+ ((null entries) nil) ;no bibliography files
+ ((gethash entries org-cite-basic--completion-cache)
+ org-cite-basic--completion-cache)
+ (t
+ (clrhash org-cite-basic--completion-cache)
+ (dolist (key (org-cite-basic--all-keys))
+ (let ((completion
+ (concat
+ (let ((author (org-cite-basic--get-field 'author key nil t)))
+ (if author
+ (truncate-string-to-width
+ (replace-regexp-in-string " and " "; " author)
+ org-cite-basic-author-column-end nil ?\s)
+ (make-string org-cite-basic-author-column-end ?\s)))
+ org-cite-basic-column-separator
+ (let ((date (org-cite-basic--get-year key nil 'no-suffix)))
+ (format "%4s" (or date "")))
+ org-cite-basic-column-separator
+ (org-cite-basic--get-field 'title key nil t))))
+ (puthash completion key org-cite-basic--completion-cache)))
+ (unless (map-empty-p org-cite-basic--completion-cache) ;no key
+ (puthash entries t org-cite-basic--completion-cache)
+ org-cite-basic--completion-cache)))))
+
+(defun org-cite-basic--complete-key (&optional multiple)
+ "Prompt for a reference key and return a citation reference string.
+
+When optional argument MULTIPLE is non-nil, prompt for multiple
+keys, until one of them is nil. Then return the list of
+reference strings selected.
+
+Raise an error when no bibliography is set in the buffer."
+ (let* ((table
+ (or (org-cite-basic--key-completion-table)
+ (user-error "No bibliography set")))
+ (prompt
+ (lambda (text)
+ (completing-read text table nil t))))
+ (if (null multiple)
+ (let ((key (gethash (funcall prompt "Key: ") table)))
+ (org-string-nw-p key))
+ (let* ((keys nil)
+ (build-prompt
+ (lambda ()
+ (if keys
+ (format "Key (empty input exits) %s: "
+ (mapconcat #'identity (reverse keys) ";"))
+ "Key (empty input exits): "))))
+ (let ((key (funcall prompt (funcall build-prompt))))
+ (while (org-string-nw-p key)
+ (push (gethash key table) keys)
+ (setq key (funcall prompt (funcall build-prompt)))))
+ keys))))
+
+
+;;; Register processor
+(org-cite-register-processor 'basic
+ :activate #'org-cite-basic-activate
+ :export-citation #'org-cite-basic-export-citation
+ :export-bibliography #'org-cite-basic-export-bibliography
+ :follow #'org-cite-basic-goto
+ :insert (org-cite-make-insert-processor #'org-cite-basic--complete-key
+ #'org-cite-basic--complete-style)
+ :cite-styles
+ '((("author" "a") ("caps" "c"))
+ (("noauthor" "na") ("bare" "b"))
+ (("nocite" "n"))
+ (("note" "ft") ("bare-caps" "bc") ("caps" "c"))
+ (("numeric" "nb"))
+ (("text" "t") ("bare-caps" "bc") ("caps" "c"))
+ (("nil") ("bare" "b") ("bare-caps" "bc") ("caps" "c"))))
+
+(provide 'oc-basic)
+;;; oc-basic.el ends here
diff --git a/lisp/org/oc-biblatex.el b/lisp/org/oc-biblatex.el
new file mode 100644
index 00000000000..e985963816a
--- /dev/null
+++ b/lisp/org/oc-biblatex.el
@@ -0,0 +1,318 @@
+;;; oc-biblatex.el --- biblatex citation processor for Org -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
+
+;; 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 registers the `biblatex' citation processor, which provides
+;; the "export" capability for citations.
+
+;; The processor relies on "biblatex" LaTeX package. As such it ensures that
+;; the package is properly required in the document's preamble. More
+;; accurately, it will re-use any "\usepackage{biblatex}" already present in
+;; the document (e.g., through `org-latex-packages-alist'), or insert one using
+;; options defined in `org-cite-biblatex-options'.
+
+;; In any case, the library will override style-related options with those
+;; specified with the citation processor, in `org-cite-export-processors' or
+;; "cite_export" keyword. If you need to use different styles for bibliography
+;; and citations, you can separate them with "bibstyle/citestyle" syntax. E.g.,
+;;
+;; #+cite_export: biblatex authortitle/authortitle-ibid
+
+;; The library supports the following citation styles:
+;;
+;; - author (a), including caps (c), full (f) and caps-full (cf) variants,
+;; - locators (l), including bare (b), caps (c) and bare-caps (bc) variants,
+;; - noauthor (na),
+;; - nocite (n),
+;; - text (t), including caps (c) variant,
+;; - default style, including bare (b), caps (c) and bare-caps (bc) variants.
+
+;; When citation and style permit, the library automatically generates
+;; "multicite" versions of the commands above.
+
+;; Bibliography is printed using "\printbibliography" command. Additional
+;; options may be passed to it through a property list attached to the
+;; "print_bibliography" keyword. E.g.,
+;;
+;; #+print_bibliography: :section 2 :heading subbibliography
+;;
+;; Values including spaces must be surrounded with double quotes. If you need
+;; to use a key multiple times, you can separate its values with commas, but
+;; without any space in-between:
+;;
+;; #+print_bibliography: :keyword abc,xyz :title "Primary Sources"
+
+;;; Code:
+(require 'org-macs)
+(require 'oc)
+
+(declare-function org-element-property "org-element" (property element))
+(declare-function org-export-data "org-export" (data info))
+(declare-function org-export-get-next-element "org-export" (blob info &optional n))
+
+
+;;; Customization
+(defcustom org-cite-biblatex-options nil
+ "Options added to \"biblatex\" package.
+If \"biblatex\" package is already required in the document, e.g., through
+`org-latex-packages-alist' variable, these options are ignored."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type '(choice
+ (string :tag "Options (key=value,key2=value2...)")
+ (const :tag "No option" nil))
+ :safe #'string-or-null-p)
+
+
+;;; Internal functions
+(defun org-cite-biblatex--package-options (initial style)
+ "Return options string for \"biblatex\" package.
+
+INITIAL is an initial style of comma-separated options, as a string or nil.
+STYLE is the style definition as a string or nil.
+
+Return a string."
+ (let ((options-no-style
+ (and initial
+ (let ((re (rx string-start (or "bibstyle" "citestyle" "style"))))
+ (seq-filter
+ (lambda (option) (not (string-match re option)))
+ (split-string (org-unbracket-string "[" "]" initial)
+ "," t " \t")))))
+ (style-options
+ (cond
+ ((null style) nil)
+ ((not (string-match "/" style)) (list (concat "style=" style)))
+ (t
+ (list (concat "bibstyle=" (substring style nil (match-beginning 0)))
+ (concat "citestyle=" (substring style (match-end 0))))))))
+ (if (or options-no-style style-options)
+ (format "[%s]"
+ (mapconcat #'identity
+ (append options-no-style style-options)
+ ","))
+ "")))
+
+(defun org-cite-biblatex--multicite-p (citation)
+ "Non-nil when citation could make use of a \"multicite\" command."
+ (let ((references (org-cite-get-references citation)))
+ (and (< 1 (length references))
+ (seq-some (lambda (r)
+ (or (org-element-property :prefix r)
+ (org-element-property :suffix r)))
+ references))))
+
+(defun org-cite-biblatex--atomic-arguments (references info &optional no-opt)
+ "Build argument for the list of citation REFERENCES.
+When NO-OPT argument is non-nil, only provide mandatory arguments."
+ (let ((mandatory
+ (format "{%s}"
+ (mapconcat (lambda (r) (org-element-property :key r))
+ references
+ ","))))
+ (if no-opt mandatory
+ (let* ((origin (pcase references
+ (`(,reference) reference)
+ (`(,reference . ,_)
+ (org-element-property :parent reference))))
+ (suffix (org-element-property :suffix origin))
+ (prefix (org-element-property :prefix origin)))
+ (concat (and prefix
+ (format "[%s]" (org-trim (org-export-data prefix info))))
+ (cond
+ (suffix (format "[%s]"
+ (org-trim (org-export-data suffix info))))
+ (prefix "[]")
+ (t nil))
+ mandatory)))))
+
+(defun org-cite-biblatex--multi-arguments (citation info)
+ "Build \"multicite\" command arguments for CITATION object.
+INFO is the export state, as a property list."
+ (let ((global-prefix (org-element-property :prefix citation))
+ (global-suffix (org-element-property :suffix citation)))
+ (concat (and global-prefix
+ (format "(%s)"
+ (org-trim (org-export-data global-prefix info))))
+ (cond
+ ;; Global pre/post-notes.
+ (global-suffix
+ (format "(%s)"
+ (org-trim (org-export-data global-suffix info))))
+ (global-prefix "()")
+ (t nil))
+ ;; All arguments.
+ (mapconcat (lambda (r)
+ (org-cite-biblatex--atomic-arguments (list r) info))
+ (org-cite-get-references citation)
+ "")
+ ;; According to BibLaTeX manual, left braces or brackets
+ ;; following a multicite command could be parsed as other
+ ;; arguments. So we stop any further parsing by inserting
+ ;; a \relax unconditionally.
+ "\\relax")))
+
+(defun org-cite-biblatex--command (citation info base &optional multi no-opt)
+ "Return biblatex command using BASE name for CITATION object.
+
+INFO is the export state, as a property list.
+
+When optional argument MULTI is non-nil, generate a \"multicite\" command when
+appropriate. When optional argument NO-OPT is non-nil, do not add optional
+arguments to the command."
+ (format "\\%s%s"
+ base
+ (if (and multi (org-cite-biblatex--multicite-p citation))
+ (concat "s" (org-cite-biblatex--multi-arguments citation info))
+ (org-cite-biblatex--atomic-arguments
+ (org-cite-get-references citation) info no-opt))))
+
+
+;;; Export capability
+(defun org-cite-biblatex-export-bibliography (_keys _files _style props &rest _)
+ "Print references from bibliography.
+PROPS is the local properties of the bibliography, as a property list."
+ (concat "\\printbibliography"
+ (and props
+ (let ((key nil)
+ (results nil))
+ (dolist (datum props)
+ (cond
+ ((keywordp datum)
+ (when key (push key results))
+ (setq key (substring (symbol-name datum) 1)))
+ (t
+ ;; Comma-separated values are associated to the
+ ;; same keyword.
+ (push (mapconcat (lambda (v) (concat key "=" v))
+ (split-string datum "," t)
+ ",")
+ results)
+ (setq key nil))))
+ (format "[%s]"
+ (mapconcat #'identity (nreverse results) ","))))))
+
+(defun org-cite-biblatex-export-citation (citation style _ info)
+ "Export CITATION object.
+STYLE is the citation style, as a pair of either strings or nil.
+INFO is the export state, as a property list."
+ (apply
+ #'org-cite-biblatex--command citation info
+ (pcase style
+ ;; "author" style.
+ (`(,(or "author" "a") . ,variant)
+ (pcase variant
+ ((or "caps" "c") '("Citeauthor*"))
+ ((or "full" "f") '("citeauthor"))
+ ((or "caps-full" "cf") '("Citeauthor"))
+ (_ '("citeauthor*"))))
+ ;; "locators" style.
+ (`(,(or "locators" "l") . ,variant)
+ (pcase variant
+ ((or "bare" "b") '("notecite"))
+ ((or "caps" "c") '("Pnotecite"))
+ ((or "bare-caps" "bc") '("Notecite"))
+ (_ '("pnotecite"))))
+ ;; "noauthor" style.
+ (`(,(or "noauthor" "na") . ,_) '("autocite*"))
+ ;; "nocite" style.
+ (`(,(or "nocite" "n") . ,_) '("nocite" nil t))
+ ;; "text" style.
+ (`(,(or "text" "t") . ,variant)
+ (pcase variant
+ ((or "caps" "c") '("Textcite" t))
+ (_ '("textcite" t))))
+ ;; Default "nil" style.
+ (`(,_ . ,variant)
+ (pcase variant
+ ((or "bare" "b") '("cite" t))
+ ((or "caps" "c") '("Autocite" t))
+ ((or "bare-caps" "bc") '("Cite" t))
+ (_ '("autocite" t))))
+ ;; This should not happen.
+ (_ (error "Invalid style: %S" style)))))
+
+(defun org-cite-biblatex-prepare-preamble (output _keys files style &rest _)
+ "Prepare document preamble for \"biblatex\" usage.
+
+OUTPUT is the final output of the export process. FILES is the list of file
+names used as the bibliography.
+
+This function ensures \"biblatex\" package is required. It also adds resources
+to the document, and set styles."
+ (with-temp-buffer
+ (save-excursion (insert output))
+ (when (search-forward "\\begin{document}" nil t)
+ ;; Ensure there is a \usepackage{biblatex} somewhere or add one.
+ ;; Then set options.
+ (goto-char (match-beginning 0))
+ (let ((re (rx "\\usepackage"
+ (opt (group "[" (*? anything) "]"))
+ "{biblatex}")))
+ (cond
+ ;; No "biblatex" package loaded. Insert "usepackage" command
+ ;; with appropriate options, including style.
+ ((not (re-search-backward re nil t))
+ (save-excursion
+ (insert
+ (format "\\usepackage%s{biblatex}\n"
+ (org-cite-biblatex--package-options
+ org-cite-biblatex-options style)))))
+ ;; "biblatex" package loaded, but without any option.
+ ;; Include style only.
+ ((not (match-beginning 1))
+ (search-forward "{" nil t)
+ (insert (org-cite-biblatex--package-options nil style)))
+ ;; "biblatex" package loaded with some options set. Override
+ ;; style-related options with ours.
+ (t
+ (replace-match
+ (save-match-data
+ (org-cite-biblatex--package-options (match-string 1) style))
+ nil nil nil 1))))
+ ;; Insert resources below.
+ (forward-line)
+ (insert (mapconcat (lambda (f)
+ (format "\\addbibresource%s{%s}"
+ (if (org-url-p f) "[location=remote]" "")
+ f))
+ files
+ "\n")
+ "\n"))
+ (buffer-string)))
+
+
+;;; Register `biblatex' processor
+(org-cite-register-processor 'biblatex
+ :export-bibliography #'org-cite-biblatex-export-bibliography
+ :export-citation #'org-cite-biblatex-export-citation
+ :export-finalizer #'org-cite-biblatex-prepare-preamble
+ :cite-styles
+ '((("author" "a") ("caps" "c") ("full" "f") ("caps-full" "cf"))
+ (("locators" "l") ("bare" "b") ("caps" "c") ("bare-caps" "bc"))
+ (("noauthor" "na"))
+ (("nocite" "n"))
+ (("text" "t") ("caps" "c"))
+ (("nil") ("bare" "b") ("caps" "c") ("bare-caps" "bc"))))
+
+(provide 'oc-biblatex)
+;;; oc-biblatex.el ends here
diff --git a/lisp/org/oc-csl.el b/lisp/org/oc-csl.el
new file mode 100644
index 00000000000..a92ea8a63e8
--- /dev/null
+++ b/lisp/org/oc-csl.el
@@ -0,0 +1,631 @@
+;;; oc-csl.el --- csl citation processor for Org -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
+
+;; 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 registers the `csl' citation processor, which provides
+;; the "export" capability for citations.
+
+;; The processor relies on the external Citeproc Emacs library, which must be
+;; available prior to loading this library.
+
+;; By default, citations are rendered in Chicago author-date CSL style. You can
+;; use another style file by specifying it in `org-cite-export-processors' or
+;; from within the document by adding the file name to "cite_export" keyword
+;;
+;; #+cite_export: csl /path/to/style-file.csl
+;; #+cite_export: csl "/path/to/style-file.csl"
+;;
+;; With the variable `org-cite-csl-styles-dir' set appropriately, the
+;; above can even be shortened to
+;;
+;; #+cite_export: csl style-file.csl
+;;
+;; Styles can be downloaded, for instance, from the Zotero Style Repository
+;; (<https://www.zotero.org/styles>). Dependent styles (which are not "unique"
+;; in the Zotero Style Repository terminology) are not supported.
+
+;; The processor uses the "en-US" CSL locale file shipped with Org for rendering
+;; localized dates and terms in the references, independently of the language
+;; settings of the Org document. Additional CSL locales can be made available
+;; by setting `org-cite-csl-locales-dir' to a directory containing the locale
+;; files in question (see <https://github.com/citation-style-language/locales>
+;; for such files).
+
+;; Bibliography is defined with the "bibliography" keyword. It supports files
+;; with ".bib", ".bibtex", and ".json" extensions. References are exported using
+;; the "print_bibliography" keyword.
+
+;; The library supports the following citation styles:
+;;
+;; - author (a), including caps (c), full (f), and caps-full (cf) variants,
+;; - noauthor (na), including bare (b), caps (c) and bare-caps (bc) variants,
+;; - year (y), including a bare (b) variant,
+;; - text (t). including caps (c), full (f), and caps-full (cf) variants,
+;; - default style, including bare (b), caps (c) and bare-caps (bc) variants.
+
+;; CSL styles recognize "locator" in citation references' suffix. For example,
+;; in the citation
+;;
+;; [cite:see @Tarski-1965 chapter 1, for an example]
+;;
+;; "chapter 1" is the locator. The whole citation is rendered as
+;;
+;; (see Tarski 1965, chap. 1 for an example)
+;;
+;; in the default CSL style.
+;;
+;; The locator starts with a locator term, among "bk.", "bks.", "book", "chap.",
+;; "chaps.", "chapter", "col.", "cols.", "column", "figure", "fig.", "figs.",
+;; "folio", "fol.", "fols.", "number", "no.", "nos.", "line", "l.", "ll.",
+;; "note", "n.", "nn.", "opus", "op.", "opp.", "page", "p.", "pp.", "paragraph",
+;; "para.", "paras.", "¶", "¶¶", "§", "§§", "part", "pt.", "pts.", "section",
+;; "sec.", "secs.", "sub verbo", "s.v.", "s.vv.", "verse", "v.", "vv.",
+;; "volume", "vol.", and "vols.". It ends with the last comma or digit in the
+;; suffix, whichever comes last, or runs till the end of the suffix.
+;;
+;; The part of the suffix before the locator is appended to reference's prefix.
+;; If no locator term is used, but a number is present, then "page" is assumed.
+
+;; This library was heavily inspired by and borrows from András Simonyi's
+;; Citeproc Org (<https://github.com/andras-simonyi/citeproc-org>) library.
+;; Many thanks to him!
+
+;;; Code:
+(require 'bibtex)
+(require 'json)
+(require 'oc)
+
+(require 'citeproc nil t)
+(declare-function citeproc-style-cite-note "ext:citeproc")
+(declare-function citeproc-proc-style "ext:citeproc")
+(declare-function citeproc-bt-entry-to-csl "ext:citeproc")
+(declare-function citeproc-locale-getter-from-dir "ext:citeproc")
+(declare-function citeproc-create "ext:citeproc")
+(declare-function citeproc-citation-create "ext:citeproc")
+(declare-function citeproc-append-citations "ext:citeproc")
+(declare-function citeproc-render-citations "ext:citeproc")
+(declare-function citeproc-render-bib "ext:citeproc")
+(declare-function citeproc-hash-itemgetter-from-any "ext:citeproc")
+
+(declare-function org-element-interpret-data "org-element" (data))
+(declare-function org-element-map "org-element" (data types fun &optional info first-match no-recursion with-affiliated))
+(declare-function org-element-property "org-element" (property element))
+(declare-function org-element-put-property "org-element" (element property value))
+
+(declare-function org-export-data "org-export" (data info))
+(declare-function org-export-derived-backend-p "org-export" (backend &rest backends))
+(declare-function org-export-get-footnote-number "org-export" (footnote info &optional data body-first))
+
+
+;;; Customization
+
+;;;; Location of CSL directories
+(defcustom org-cite-csl-locales-dir nil
+ "Directory of CSL locale files.
+If nil then only the fallback en-US locale will be available."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type '(choice
+ (directory :tag "Locales directory")
+ (const :tag "Use en-US locale only" nil))
+ ;; It's not obvious to me that arbitrary locations are safe.
+;;; :safe #'string-or-null-p
+ )
+
+(defcustom org-cite-csl-styles-dir nil
+ "Directory of CSL style files.
+When non-nil, relative style file names are expanded relatively to this
+directory. This variable is ignored when style file is absolute."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type '(choice
+ (directory :tag "Styles directory")
+ (const :tag "Use absolute file names" nil))
+ ;; It's not obvious to me that arbitrary locations are safe.
+;;; :safe #'string-or-null-p
+ )
+
+;;;; Citelinks
+(defcustom org-cite-csl-link-cites t
+ "When non-nil, link cites to references."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type 'boolean
+ :safe #'booleanp)
+
+(defcustom org-cite-csl-no-citelinks-backends '(ascii)
+ "List of export back-ends for which cite linking is disabled.
+Cite linking for export back-ends derived from any of the back-ends listed here,
+is also disabled."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type '(repeat symbol))
+
+;;;; Output-specific variables
+(defcustom org-cite-csl-html-hanging-indent "1.5em"
+ "Size of hanging-indent for HTML output in valid CSS units."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type 'string
+ :safe #'stringp)
+
+(defcustom org-cite-csl-html-label-width-per-char "0.6em"
+ "Character width in CSS units for calculating entry label widths.
+Used only when `second-field-align' is activated by the used CSL style."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type 'string
+ :safe #'stringp)
+
+(defcustom org-cite-csl-latex-hanging-indent "1.5em"
+ "Size of hanging-indent for LaTeX output in valid LaTeX units."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type 'string
+ :safe #'stringp)
+
+
+;;; Internal variables
+(defconst org-cite-csl--etc-dir
+ (let ((oc-root (file-name-directory (locate-library "oc"))))
+ (cond
+ ;; First check whether it looks like we're running from the main
+ ;; Org repository.
+ ((let ((csl-org (expand-file-name "../etc/csl/" oc-root)))
+ (and (file-directory-p csl-org) csl-org)))
+ ;; Next look for the directory alongside oc.el because package.el
+ ;; and straight will put all of org-mode/lisp/ in org-mode/.
+ ((let ((csl-pkg (expand-file-name "etc/csl/" oc-root)))
+ (and (file-directory-p csl-pkg) csl-pkg)))
+ ;; Finally fall back the location used by shared system installs
+ ;; and when running directly from Emacs repository.
+ (t
+ (expand-file-name "org/csl/" data-directory))))
+ "Directory containing CSL-related data files.")
+
+(defconst org-cite-csl--fallback-locales-dir org-cite-csl--etc-dir
+ "Fallback CSL locale files directory.")
+
+(defconst org-cite-csl--fallback-style-file
+ (expand-file-name "chicago-author-date.csl"
+ org-cite-csl--etc-dir)
+ "Default CSL style file, or nil.
+If nil then the Chicago author-date style is used as a fallback.")
+
+(defconst org-cite-csl--label-alist
+ '(("bk." . "book")
+ ("bks." . "book")
+ ("book" . "book")
+ ("chap." . "chapter")
+ ("chaps." . "chapter")
+ ("chapter" . "chapter")
+ ("col." . "column")
+ ("cols." . "column")
+ ("column" . "column")
+ ("figure" . "figure")
+ ("fig." . "figure")
+ ("figs." . "figure")
+ ("folio" . "folio")
+ ("fol." . "folio")
+ ("fols." . "folio")
+ ("number" . "number")
+ ("no." . "number")
+ ("nos." . "number")
+ ("line" . "line")
+ ("l." . "line")
+ ("ll." . "line")
+ ("note" . "note")
+ ("n." . "note")
+ ("nn." . "note")
+ ("opus" . "opus")
+ ("op." . "opus")
+ ("opp." . "opus")
+ ("page" . "page")
+ ("p" . "page")
+ ("p." . "page")
+ ("pp." . "page")
+ ("paragraph" . "paragraph")
+ ("para." . "paragraph")
+ ("paras." . "paragraph")
+ ("¶" . "paragraph")
+ ("¶¶" . "paragraph")
+ ("part" . "part")
+ ("pt." . "part")
+ ("pts." . "part")
+ ("§" . "section")
+ ("§§" . "section")
+ ("section" . "section")
+ ("sec." . "section")
+ ("secs." . "section")
+ ("sub verbo" . "sub verbo")
+ ("s.v." . "sub verbo")
+ ("s.vv." . "sub verbo")
+ ("verse" . "verse")
+ ("v." . "verse")
+ ("vv." . "verse")
+ ("volume" . "volume")
+ ("vol." . "volume")
+ ("vols." . "volume"))
+ "Alist mapping locator names to locators.")
+
+(defconst org-cite-csl--label-regexp
+ ;; Prior to Emacs-27.1 argument of `regexp' form must be a string literal.
+ ;; It is the reason why `rx' is avoided here.
+ (rx-to-string
+ `(seq (or line-start space)
+ (regexp ,(regexp-opt (mapcar #'car org-cite-csl--label-alist) t))
+ (0+ digit)
+ (or word-end line-end space " "))
+ t)
+ "Regexp matching a label in a citation reference suffix.
+Label is in match group 1.")
+
+
+;;; Internal functions
+(defun org-cite-csl--barf-without-citeproc ()
+ "Raise an error if Citeproc library is not loaded."
+ (unless (featurep 'citeproc)
+ (error "Citeproc library is not loaded")))
+
+(defun org-cite-csl--note-style-p (info)
+ "Non-nil when bibliography style implies wrapping citations in footnotes.
+INFO is the export state, as a property list."
+ (citeproc-style-cite-note
+ (citeproc-proc-style
+ (org-cite-csl--processor info))))
+
+(defun org-cite-csl--create-structure-params (citation info)
+ "Return citeproc structure creation params for CITATION object.
+STYLE is the citation style, as a string or nil. INFO is the export state, as
+a property list."
+ (let ((style (org-cite-citation-style citation info)))
+ (pcase style
+ ;; "author" style.
+ (`(,(or "author" "a") . ,variant)
+ (pcase variant
+ ((or "caps" "c") '(:mode author-only :capitalize-first t))
+ ((or "full" "f") '(:mode author-only :ignore-et-al t))
+ ((or "caps-full" "cf") '(:mode author-only :capitalize-first t :ignore-et-al t))
+ (_ '(:mode author-only))))
+ ;; "noauthor" style.
+ (`(,(or "noauthor" "na") . ,variant)
+ (pcase variant
+ ((or "bare" "b") '(:mode suppress-author :suppress-affixes t))
+ ((or "caps" "c") '(:mode suppress-author :capitalize-first t))
+ ((or "bare-caps" "bc")
+ '(:mode suppress-author :suppress-affixes t :capitalize-first t))
+ (_ '(:mode suppress-author))))
+ ;; "year" style.
+ (`(,(or "year" "y") . ,variant)
+ (pcase variant
+ ((or "bare" "b") '(:mode year-only :suppress-affixes t))
+ (_ '(:mode year-only))))
+ ;; "text" style.
+ (`(,(or "text" "t") . ,variant)
+ (pcase variant
+ ((or "caps" "c") '(:mode textual :capitalize-first t))
+ ((or "full" "f") '(:mode textual :ignore-et-al t))
+ ((or "caps-full" "cf") '(:mode textual :ignore-et-al t :capitalize-first t))
+ (_ '(:mode textual))))
+ ;; Default "nil" style.
+ (`(,_ . ,variant)
+ (pcase variant
+ ((or "caps" "c") '(:capitalize-first t))
+ ((or "bare" "b") '(:suppress-affixes t))
+ ((or "bare-caps" "bc") '(:suppress-affixes t :capitalize-first t))
+ (_ nil)))
+ ;; This should not happen.
+ (_ (error "Invalid style: %S" style)))))
+
+(defun org-cite-csl--no-citelinks-p (info)
+ "Non-nil when export BACKEND should not create cite-reference links."
+ (or (not org-cite-csl-link-cites)
+ (and org-cite-csl-no-citelinks-backends
+ (apply #'org-export-derived-backend-p
+ (plist-get info :back-end)
+ org-cite-csl-no-citelinks-backends))
+ ;; No references are being exported anyway.
+ (not (org-element-map (plist-get info :parse-tree) 'keyword
+ (lambda (k)
+ (equal "PRINT_BIBLIOGRAPHY" (org-element-property :key k)))
+ info t))))
+
+(defun org-cite-csl--output-format (info)
+ "Return expected Citeproc's output format.
+INFO is the export state, as a property list. The return value is a symbol
+corresponding to one of the output formats supported by Citeproc: `html',
+`latex', or `org'."
+ (let ((backend (plist-get info :back-end)))
+ (cond
+ ((org-export-derived-backend-p backend 'html) 'html)
+ ((org-export-derived-backend-p backend 'latex) 'latex)
+ (t 'org))))
+
+(defun org-cite-csl--style-file (info)
+ "Return style file associated to current export process.
+
+INFO is the export state, as a property list.
+
+When file name is relative, expand it according to `org-cite-csl-styles-dir',
+or raise an error if the variable is unset."
+ (pcase (org-cite-bibliography-style info)
+ ('nil org-cite-csl--fallback-style-file)
+ ((and (pred file-name-absolute-p) file) file)
+ ((and (guard org-cite-csl-styles-dir) file)
+ (expand-file-name file org-cite-csl-styles-dir))
+ (other
+ (user-error "Cannot handle relative style file name: %S" other))))
+
+(defun org-cite-csl--locale-getter ()
+ "Return a locale getter.
+The getter looks for locales in `org-cite-csl-locales-dir' directory. If it
+cannot find them, it retrieves the default \"en_US\" from
+`org-cite-csl--fallback-locales-dir'."
+ (lambda (loc)
+ (or (and org-cite-csl-locales-dir
+ (ignore-errors
+ (funcall (citeproc-locale-getter-from-dir org-cite-csl-locales-dir)
+ loc)))
+ (funcall (citeproc-locale-getter-from-dir
+ org-cite-csl--fallback-locales-dir)
+ loc))))
+
+(defun org-cite-csl--processor (info)
+ "Return Citeproc processor reading items from current bibliography.
+
+INFO is the export state, as a property list.
+
+Newly created processor is stored as the value of the `:cite-citeproc-processor'
+property in INFO."
+ (or (plist-get info :cite-citeproc-processor)
+ (let* ((bibliography (plist-get info :bibliography))
+ (locale (or (plist-get info :language) "en_US"))
+ (processor
+ (citeproc-create
+ (org-cite-csl--style-file info)
+ (citeproc-hash-itemgetter-from-any bibliography)
+ (org-cite-csl--locale-getter)
+ locale)))
+ (plist-put info :cite-citeproc-processor processor)
+ processor)))
+
+(defun org-cite-csl--parse-reference (reference info)
+ "Return Citeproc's structure associated to citation REFERENCE.
+
+INFO is the export state, as a property list.
+
+The result is a association list. Keys are: `id', `prefix',`suffix',
+`location', `locator' and `label'."
+ (let (label location-start locator-start location locator prefix suffix)
+ ;; Parse suffix. Insert it in a temporary buffer to find
+ ;; different parts: pre-label, label, locator, location (label +
+ ;; locator), and suffix.
+ (with-temp-buffer
+ (save-excursion
+ (insert (org-element-interpret-data
+ (org-element-property :suffix reference))))
+ (cond
+ ((re-search-forward org-cite-csl--label-regexp nil t)
+ (setq location-start (match-beginning 0))
+ (setq label (cdr (assoc (match-string 1) org-cite-csl--label-alist)))
+ (goto-char (match-end 1))
+ (skip-chars-forward "[:space:] ")
+ (setq locator-start (point)))
+ ((re-search-forward (rx digit) nil t)
+ (setq location-start (match-beginning 0))
+ (setq label "page")
+ (setq locator-start location-start))
+ (t
+ (setq suffix (org-element-property :suffix reference))))
+ ;; Find locator's end, and suffix, if any. To that effect, look
+ ;; for the last comma or digit after label, whichever comes
+ ;; last.
+ (unless suffix
+ (goto-char (point-max))
+ (let ((re (rx (or "," (group digit)))))
+ (when (re-search-backward re location-start t)
+ (goto-char (or (match-end 1) (match-beginning 0)))
+ (setq location (buffer-substring location-start (point)))
+ (setq locator (org-trim (buffer-substring locator-start (point))))
+ ;; Skip comma in suffix.
+ (setq suffix
+ (org-cite-parse-objects
+ (buffer-substring (match-end 0) (point-max))
+ t)))))
+ (setq prefix
+ (org-cite-concat
+ (org-element-property :prefix reference)
+ (and location-start
+ (org-cite-parse-objects
+ (buffer-substring 1 location-start)
+ t)))))
+ ;; Return value.
+ (let ((export
+ (lambda (data)
+ (org-string-nw-p
+ (org-trim
+ ;; When Citeproc exports to Org syntax, avoid mix and
+ ;; matching output formats by also generating Org
+ ;; syntax for prefix and suffix.
+ (if (eq 'org (org-cite-csl--output-format info))
+ (org-element-interpret-data data)
+ (org-export-data data info)))))))
+ `((id . ,(org-element-property :key reference))
+ (prefix . ,(funcall export prefix))
+ (suffix . ,(funcall export suffix))
+ (locator . ,locator)
+ (label . ,label)
+ (location . ,location)))))
+
+(defun org-cite-csl--create-structure (citation info)
+ "Create Citeproc structure for CITATION object.
+INFO is the export state, as a property list."
+ (let* ((cites (mapcar (lambda (r)
+ (org-cite-csl--parse-reference r info))
+ (org-cite-get-references citation)))
+ (footnote (org-cite-inside-footnote-p citation)))
+ ;; Global prefix is inserted in front of the prefix of the first
+ ;; reference.
+ (let ((global-prefix (org-element-property :prefix citation)))
+ (when global-prefix
+ (let* ((first (car cites))
+ (prefix-item (assq 'prefix first)))
+ (setcdr prefix-item
+ (concat (org-element-interpret-data global-prefix)
+ " "
+ (cdr prefix-item))))))
+ ;; Global suffix is appended to the suffix of the last reference.
+ (let ((global-suffix (org-element-property :suffix citation)))
+ (when global-suffix
+ (let* ((last (org-last cites))
+ (suffix-item (assq 'suffix last)))
+ (setcdr suffix-item
+ (concat (cdr suffix-item)
+ " "
+ (org-element-interpret-data global-suffix))))))
+ ;; Check if CITATION needs wrapping, i.e., it should be wrapped in
+ ;; a footnote, but isn't yet.
+ (when (and (not footnote) (org-cite-csl--note-style-p info))
+ (org-cite-adjust-note citation info)
+ (setq footnote (org-cite-wrap-citation citation info)))
+ ;; Return structure.
+ (apply #'citeproc-citation-create
+ `(:note-index
+ ,(and footnote (org-export-get-footnote-number footnote info))
+ :cites ,cites
+ ,@(org-cite-csl--create-structure-params citation info)))))
+
+(defun org-cite-csl--rendered-citations (info)
+ "Return the rendered citations as an association list.
+
+INFO is the export state, as a property list.
+
+Return an alist (CITATION . OUTPUT) where CITATION object has been rendered as
+OUTPUT using Citeproc."
+ (or (plist-get info :cite-citeproc-rendered-citations)
+ (let* ((citations (org-cite-list-citations info))
+ (processor (org-cite-csl--processor info))
+ (structures
+ (mapcar (lambda (c) (org-cite-csl--create-structure c info))
+ citations)))
+ (citeproc-append-citations structures processor)
+ (let* ((rendered
+ (citeproc-render-citations
+ processor
+ (org-cite-csl--output-format info)
+ (org-cite-csl--no-citelinks-p info)))
+ (result (seq-mapn #'cons citations rendered)))
+ (plist-put info :cite-citeproc-rendered-citations result)
+ result))))
+
+
+;;; Export capability
+(defun org-cite-csl-render-citation (citation _style _backend info)
+ "Export CITATION object.
+INFO is the export state, as a property list."
+ (org-cite-csl--barf-without-citeproc)
+ (let ((output (cdr (assq citation (org-cite-csl--rendered-citations info)))))
+ (if (not (eq 'org (org-cite-csl--output-format info)))
+ output
+ ;; Parse Org output to re-export it during the regular export
+ ;; process.
+ (org-cite-parse-objects output))))
+
+(defun org-cite-csl-render-bibliography (_keys _files _style _props _backend info)
+ "Export bibliography.
+INFO is the export state, as a property list."
+ (org-cite-csl--barf-without-citeproc)
+ (pcase-let* ((format (org-cite-csl--output-format info))
+ (`(,output . ,parameters)
+ (citeproc-render-bib
+ (org-cite-csl--processor info)
+ format
+ (org-cite-csl--no-citelinks-p info))))
+ (pcase format
+ ('html
+ (concat
+ (and (cdr (assq 'second-field-align parameters))
+ (let* ((max-offset (cdr (assq 'max-offset parameters)))
+ (char-width
+ (string-to-number org-cite-csl-html-label-width-per-char))
+ (char-width-unit
+ (progn
+ (string-match (number-to-string char-width)
+ org-cite-csl-html-label-width-per-char)
+ (substring org-cite-csl-html-label-width-per-char
+ (match-end 0)))))
+ (format
+ "<style>.csl-left-margin{float: left; padding-right: 0em;}
+ .csl-right-inline{margin: 0 0 0 %d%s;}</style>"
+ (* max-offset char-width)
+ char-width-unit)))
+ (and (cdr (assq 'hanging-indent parameters))
+ (format
+ "<style>.csl-entry{text-indent: -%s; margin-left: %s;}</style>"
+ org-cite-csl-html-hanging-indent
+ org-cite-csl-html-hanging-indent))
+ output))
+ ('latex
+ (if (cdr (assq 'hanging-indent parameters))
+ (format "\\begin{hangparas}{%s}{1}\n%s\n\\end{hangparas}"
+ org-cite-csl-latex-hanging-indent
+ output)
+ output))
+ (_
+ ;; Parse Org output to re-export it during the regular export
+ ;; process.
+ (org-cite-parse-elements output)))))
+
+(defun org-cite-csl-finalizer (output _keys _files _style _backend info)
+ "Add \"hanging\" package if missing from LaTeX output.
+OUTPUT is the export document, as a string. INFO is the export state, as a
+property list."
+ (org-cite-csl--barf-without-citeproc)
+ (if (not (eq 'latex (org-cite-csl--output-format info)))
+ output
+ (with-temp-buffer
+ (save-excursion (insert output))
+ (when (search-forward "\\begin{document}" nil t)
+ (goto-char (match-beginning 0))
+ ;; Ensure that \citeprocitem is defined for citeproc-el.
+ (insert "\\makeatletter\n\\newcommand{\\citeprocitem}[2]{\\hyper@linkstart{cite}{citeproc_bib_item_#1}#2\\hyper@linkend}\n\\makeatother\n\n")
+ ;; Ensure there is a \usepackage{hanging} somewhere or add one.
+ (let ((re (rx "\\usepackage" (opt "[" (*? nonl) "]") "{hanging}")))
+ (unless (re-search-backward re nil t)
+ (insert "\\usepackage[notquote]{hanging}\n"))))
+ (buffer-string))))
+
+
+;;; Register `csl' processor
+(org-cite-register-processor 'csl
+ :export-citation #'org-cite-csl-render-citation
+ :export-bibliography #'org-cite-csl-render-bibliography
+ :export-finalizer #'org-cite-csl-finalizer
+ :cite-styles
+ '((("author" "a") ("full" "f") ("caps" "c") ("caps-full" "cf"))
+ (("noauthor" "na") ("bare" "b") ("caps" "c") ("bare-caps" "bc"))
+ (("year" "y") ("bare" "b"))
+ (("text" "t") ("caps" "c") ("full" "f") ("caps-full" "cf"))
+ (("nil") ("bare" "b") ("caps" "c") ("bare-caps" "bc"))))
+
+(provide 'oc-csl)
+;;; oc-csl.el ends here
diff --git a/lisp/org/oc-natbib.el b/lisp/org/oc-natbib.el
new file mode 100644
index 00000000000..bf086f36dff
--- /dev/null
+++ b/lisp/org/oc-natbib.el
@@ -0,0 +1,193 @@
+;;; oc-natbib.el --- Citation processor using natbib LaTeX package -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
+
+;; 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 registers the `natbib' citation processor, which provides the
+;; "export" capability for citations.
+
+;; The processor relies on "natbib" LaTeX package. As such it ensures that the
+;; package is properly required in the document's preamble. More accurately, it
+;; will use any "\\usepackage{natbib}" command already present in the document
+;; (e.g., through `org-latex-packages-alist'), or insert one using options
+;; defined in `org-cite-natbib-options'.
+
+;; It supports the following citation styles:
+;;
+;; - author (a), including caps (c), and full (f) variants,
+;; - noauthor (na), including bare (b) variant,
+;; - text (t), including bare (b), caps (c), full (f), bare-caps (bc),
+;; bare-full (bf), caps-full (cf), and bare-caps-full (bcf) variants,
+;; - default, including bare (b), caps (c), full (f), bare-caps (bc),
+;; bare-full (bf), caps-full (cf), and bare-caps-full (bcf) variants.
+
+;; Bibliography accepts any style supported by "natbib" package.
+
+;;; Code:
+(require 'oc)
+
+(declare-function org-element-property "org-element" (property element))
+
+(declare-function org-export-data "org-export" (data info))
+
+
+;;; Customization
+(defcustom org-cite-natbib-options nil
+ "List of options added to \"natbib\" package.
+If \"natbib\" package is already required in the document, e.g., through
+`org-latex-packages-alist' variable, these options are ignored."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type
+ '(set
+ (const :tag "use round parentheses (default)" round)
+ (const :tag "use square brackets" square)
+ (const :tag "use curly braces" curly)
+ (const :tag "use angle brackets" angle)
+ (const :tag "separate multiple citations with colons (default)" colon)
+ (const :tag "separate multiple citations with comas" comma)
+ (const :tag "generate author-year citations" authoryear)
+ (const :tag "generate numerical citations" numbers)
+ (const :tag "generate superscripted numerical citations" super)
+ (const :tag "order multiple citations according to the list of references" sort)
+ (const :tag "order as above, but numerical citations are compressed if possible" sort&compress)
+ (const :tag "display full author list on first citation, abbreviate the others" longnamesfirst)
+ (const :tag "redefine \\thebibliography to issue \\section* instead of \\chapter*" sectionbib)
+ (const :tag "keep all the authors' names in a citation on one line" nonamebreak)))
+
+
+;;; Internal functions
+(defun org-cite-natbib--style-to-command (style)
+ "Return command name to use according to STYLE pair."
+ (pcase style
+ ;; "author" style.
+ (`(,(or "author" "a") . ,variant)
+ (pcase variant
+ ((or "caps" "c") "\\Citeauthor")
+ ((or "full" "f") "\\citeauthor*")
+ (_ "\\citeauthor")))
+ ;; "noauthor" style.
+ (`(,(or "noauthor" "na") . ,variant)
+ (pcase variant
+ ((or "bare" "b") "\\citeyear")
+ (_ "\\citeyearpar")))
+ ;; "nocite" style.
+ (`(,(or "nocite" "n") . ,_) "\\nocite")
+ ;; "text" style.
+ (`(,(or "text" "t") . ,variant)
+ (pcase variant
+ ((or "bare" "b") "\\citealt")
+ ((or "caps" "c") "\\Citet")
+ ((or "full" "f") "\\citet*")
+ ((or "bare-caps" "bc") "\\Citealt")
+ ((or "bare-full" "bf") "\\citealt*")
+ ((or "caps-full" "cf") "\\Citet*")
+ ((or "bare-caps-full" "bcf") "\\Citealt*")
+ (_ "\\citet")))
+ ;; Default ("nil") style.
+ (`(,_ . ,variant)
+ (pcase variant
+ ((or "bare" "b") "\\citealp")
+ ((or "caps" "c") "\\Citep")
+ ((or "full" "f") "\\citep*")
+ ((or "bare-caps" "bc") "\\Citealp")
+ ((or "bare-full" "bf") "\\citealp*")
+ ((or "caps-full" "cf") "\\Citep*")
+ ((or "bare-caps-full" "bcf") "\\Citealp*")
+ (_ "\\citep")))
+ ;; This should not happen.
+ (_ (error "Invalid style: %S" style))))
+
+(defun org-cite-natbib--build-optional-arguments (citation info)
+ "Build optional arguments for citation command.
+CITATION is the citation object. INFO is the export state, as a property list."
+ (pcase-let ((`(,prefix . ,suffix) (org-cite-main-affixes citation)))
+ (concat (and prefix (format "[%s]" (org-trim (org-export-data prefix info))))
+ (cond
+ (suffix (format "[%s]" (org-trim (org-export-data suffix info))))
+ (prefix "[]")
+ (t nil)))))
+
+(defun org-cite-natbib--build-arguments (citation)
+ "Build arguments for citation command for CITATION object."
+ (format "{%s}"
+ (mapconcat #'identity
+ (org-cite-get-references citation t)
+ ",")))
+
+
+;;; Export capability
+(defun org-cite-natbib-export-bibliography (_keys files style &rest _)
+ "Print references from bibliography FILES.
+FILES is a list of absolute file names. STYLE is the bibliography style, as
+a string or nil."
+ (concat (and style (format "\\bibliographystyle{%s}\n" style))
+ (format "\\bibliography{%s}"
+ (mapconcat #'file-name-sans-extension
+ files
+ ","))))
+
+(defun org-cite-natbib-export-citation (citation style _ info)
+ "Export CITATION object.
+STYLE is the citation style, as a pair of strings or nil. INFO is the export
+state, as a property list."
+ (concat (org-cite-natbib--style-to-command style)
+ (org-cite-natbib--build-optional-arguments citation info)
+ (org-cite-natbib--build-arguments citation)))
+
+(defun org-cite-natbib-use-package (output &rest _)
+ "Ensure output requires \"natbib\" package.
+OUTPUT is the final output of the export process."
+ (with-temp-buffer
+ (save-excursion (insert output))
+ (when (search-forward "\\begin{document}" nil t)
+ ;; Ensure there is a \usepackage{natbib} somewhere or add one.
+ (goto-char (match-beginning 0))
+ (let ((re (rx "\\usepackage" (opt "[" (*? nonl) "]") "{natbib}")))
+ (unless (re-search-backward re nil t)
+ (insert
+ (format "\\usepackage%s{natbib}\n"
+ (if (null org-cite-natbib-options)
+ ""
+ (format "[%s]"
+ (mapconcat #'symbol-name
+ org-cite-natbib-options
+ ","))))))))
+ (buffer-string)))
+
+
+;;; Register `natbib' processor
+(org-cite-register-processor 'natbib
+ :export-bibliography #'org-cite-natbib-export-bibliography
+ :export-citation #'org-cite-natbib-export-citation
+ :export-finalizer #'org-cite-natbib-use-package
+ :cite-styles
+ '((("author" "a") ("caps" "a") ("full" "f"))
+ (("noauthor" "na") ("bare" "b"))
+ (("text" "t")
+ ("bare" "b") ("caps" "c") ("full" "f") ("bare-caps" "bc")
+ ("bare-full" "bf") ("caps-full" "cf") ("bare-caps-full" "bcf"))
+ (("nil")
+ ("bare" "b") ("caps" "c") ("full" "f") ("bare-caps" "bc")
+ ("bare-full" "bf") ("caps-full" "cf") ("bare-caps-full" "bcf"))))
+
+(provide 'oc-natbib)
+;;; oc-natbib.el ends here
diff --git a/lisp/org/oc.el b/lisp/org/oc.el
new file mode 100644
index 00000000000..a77daa7e122
--- /dev/null
+++ b/lisp/org/oc.el
@@ -0,0 +1,1650 @@
+;;; oc.el --- Org Cite library -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
+
+;; 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 tooling to handle citations in Org, e.g,
+;; activate, follow, insert, and export them, respectively called
+;; "activate", "follow", "insert" and "export" capabilities.
+;; Libraries responsible for providing some, or all, of these
+;; capabilities are called "citation processors".
+
+;; Such processors are defined using `org-cite-register-processor'.
+;; Using this function, it is possible, in addition to giving it a
+;; name, to attach functions associated to capabilities. As such, a
+;; processor handling citation export must set the `:export-citation'
+;; property to an appropriate function. Likewise, "activate"
+;; capability requires an appropriate `:activate' property, "insert"
+;; requires `:insert' property and, unsurprisingly, "follow"
+;; capability implies `:follow' property.
+
+;; As a user, the first thing to do is setting a bibliography, either
+;; globally with `org-cite-global-bibliography', or locally using one
+;; or more "bibliography" keywords. Then one can select any
+;; registered processor for each capability by providing a processor
+;; name to the variables `org-cite-activate-processor' and
+;; `org-cite-follow-processor'.
+
+;; The "export" capability is slightly more involved as one need to
+;; select the processor providing it, but may also provide a default
+;; style for citations and bibliography. Also, the choice of an
+;; export processor may depend of the current export back-end. The
+;; association between export back-ends and triplets of parameters can
+;; be set in `org-cite-export-processors' variable, or in a document,
+;; through the "cite_export" keyword.
+
+;; Eventually, this library provides some tools, mainly targeted at
+;; processor implementors. Most are export-specific and are located
+;; in the "Tools only available during export" and "Tools generating
+;; or operating on parsed data" sections.
+
+;; The few others can be used directly from an Org buffer, or operate
+;; on processors. See "Generic tools" section.
+
+;;; Code:
+
+(require 'org-compat)
+(require 'org-macs)
+(require 'seq)
+
+(declare-function org-at-heading-p "org" (&optional _))
+(declare-function org-collect-keywords "org" (keywords &optional unique directory))
+
+(declare-function org-element-adopt-elements "org-element" (parent &rest children))
+(declare-function org-element-citation-parser "org-element" ())
+(declare-function org-element-citation-reference-parser "org-element" ())
+(declare-function org-element-class "org-element" (datum &optional parent))
+(declare-function org-element-contents "org-element" (element))
+(declare-function org-element-create "org-element" (type &optional props &rest children))
+(declare-function org-element-extract-element "org-element" (element))
+(declare-function org-element-insert-before "org-element" (element location))
+(declare-function org-element-lineage "org-element" (datum &optional types with-self))
+(declare-function org-element-map "org-element" (data types fun &optional info first-match no-recursion with-affiliated))
+(declare-function org-element-normalize-string "org-element" (s))
+(declare-function org-element-parse-buffer "org-element" (&optional granularity visible-only))
+(declare-function org-element-parse-secondary-string "org-element" (string restriction &optional parent))
+(declare-function org-element-context "org-element" (&optional element))
+(declare-function org-element-property "org-element" (property element))
+(declare-function org-element-put-property "org-element" (element property value))
+(declare-function org-element-restriction "org-element" (element))
+(declare-function org-element-set-element "org-element" (old new))
+(declare-function org-element-type "org-element" (element))
+
+(declare-function org-export-derived-backend-p "org-export" (backend &rest backends))
+(declare-function org-export-get-next-element "org-export" (blob info &optional n))
+(declare-function org-export-get-previous-element "org-export" (blob info &optional n))
+(declare-function org-export-raw-string "org-export" (s))
+
+(defvar org-complex-heading-regexp)
+(defvar org-element-all-objects)
+(defvar org-element-citation-key-re)
+(defvar org-element-citation-prefix-re)
+(defvar org-element-parsed-keywords)
+
+
+;;; Constants
+;; Borrowed from "citeproc.el" library.
+(defconst org-cite--default-region-alist
+ '(("af" . "za") ("ca" . "ad") ("cs" . "cz") ("cy" . "gb")
+ ("da" . "dk") ("el" . "gr") ("et" . "ee") ("fa" . "ir")
+ ("he" . "ir") ("ja" . "jp") ("km" . "kh") ("ko" . "kr")
+ ("nb" . "no") ("nn" . "no") ("sl" . "si") ("sr" . "rs")
+ ("sv" . "se") ("uk" . "ua") ("vi" . "vn") ("zh" . "cn"))
+ "Alist mapping those languages to their default region.
+Only those languages are given for which the default region is not simply the
+result of duplicating the language part.")
+
+
+;;; Configuration variables
+(defgroup org-cite nil
+ "Options concerning citations in Org mode."
+ :group 'org
+ :tag "Org Cite")
+
+(defcustom org-cite-global-bibliography nil
+ "List of bibliography files available in all documents.
+File names must be absolute."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type '(choice (const :tag "No global bibliography" nil)
+ (repeat :tag "List of bibliography files"
+ (file :tag "Bibliography"))))
+
+(defcustom org-cite-activate-processor 'basic
+ "Processor used for activating citations, as a symbol."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type '(choice (const :tag "Default fontification" nil)
+ (symbol :tag "Citation processor")))
+
+(defcustom org-cite-export-processors '((t basic))
+ "Processor used for exporting citations, as a triplet, or nil.
+
+When nil, citations and bibliography are not exported.
+
+When non-nil, the value is an association list between export back-ends and
+citation export processors:
+
+ (BACK-END . PROCESSOR)
+
+where BACK-END is the name of an export back-end or t, and PROCESSOR is a
+triplet following the pattern
+
+ (NAME BIBLIOGRAPHY-STYLE CITATION-STYLE)
+
+There, NAME is the name of a registered citation processor providing export
+functionality, as a symbol. BIBLIOGRAPHY-STYLE (respectively CITATION-STYLE)
+is the desired default style to use when printing a bibliography (respectively
+exporting a citation), as a string or nil. Both BIBLIOGRAPHY-STYLE and
+CITATION-STYLE are optional. NAME is mandatory.
+
+The export process selects the citation processor associated to the current
+export back-end, or the most specific back-end the current one is derived from,
+or, if all are inadequate, to the processor associated to t. For example, with
+the following value
+
+ ((beamer natbib)
+ (latex biblatex)
+ (t csl))
+
+exporting with `beamer' or any back-end derived from it will use `natbib',
+whereas exporting with `latex' or any back-end derived from it but different
+from `beamer' will use `biblatex' processor. Any other back-end, such as
+`html', will use `csl' processor.
+
+CITATION-STYLE is overridden by adding a style to any citation object. A nil
+style lets the export processor choose the default output. Any style not
+recognized by the export processor is equivalent to nil.
+
+The citation triplet can also be set with the CITE_EXPORT keyword.
+E.g.,
+
+ #+CITE_EXPORT: basic note numeric
+
+or
+
+ #+CITE_EXPORT: basic
+
+In that case, `basic' processor is used on every export, independently on the
+back-end."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type '(choice (const :tag "No export" nil)
+ (alist :key-type symbol
+ :value-type
+ (list :tag "Citation processor"
+ (symbol :tag "Processor name")
+ (choice
+ (const :tag "Default bibliography style" nil)
+ (string :tag "Use specific bibliography style"))
+ (choice
+ (const :tag "Default citation style" nil)
+ (string :tag "Use specific citation style"))))))
+
+(defcustom org-cite-follow-processor 'basic
+ "Processor used for following citations, as a symbol."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type '(choice (const :tag "No following" nil)
+ (symbol :tag "Citation processor")))
+
+(defcustom org-cite-insert-processor 'basic
+ "Processor used for inserting citations, as a symbol."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type '(choice (const :tag "No insertion" nil)
+ (symbol :tag "Citation processor")))
+
+(defcustom org-cite-adjust-note-numbers t
+ "When non-nil, allow process to modify location of note numbers.
+
+When this variable is non-nil, it is possible to swap between author-date and
+note style without modifying the document. To that effect, citations should
+always be located as in an author-date style. Prior to turning the citation
+into a footnote, the citation processor moves the citation (i.e., the future
+note number), and the surrounding punctuation, according to rules defined in
+`org-cite-note-rules'.
+
+When nil, the note number is not moved."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type '(choice (const :tag "Automatic note number location" t)
+ (const :tag "Place note numbers manually" nil))
+ :safe #'booleanp)
+
+(defcustom org-cite-note-rules
+ '(("en-us" inside outside after)
+ ("fr" adaptive same before))
+ "Alist between languages and typographic rules for citations in note style.
+
+When `org-cite-adjust-note-numbers' is non-nil, and note style is requested,
+citation processor is allowed to move the note marker according to some specific
+rules, detailed here. More accurately, a rule is a list following the pattern
+
+ (LANGUAGE-TAG . RULE)
+
+ LANGUAGE-TAG is a down-cased string representing a language tag as defined in
+ RFC 4646. It may constituted of a language and a region separated with an
+ hyphen (e.g., \"en-us\"), or the language alone (e.g., \"fr\"). A language
+ without a region applies to all regions.
+
+ RULE is a triplet
+
+ (PUNCTUATION NUMBER ORDER)
+
+ PUNCTUATION is the desired location of the punctuation with regards to the
+ quotation, if any. It may be `inside', `outside', or `adaptive'. The latter
+ permits subtler control over the punctuation: when there is no space between
+ the quotation mark and the punctuation, it is equivalent to `inside'.
+ Otherwise, it means `outside', as illustrated in the following examples:
+
+ \"A quotation ending without punctuation\" [cite:@org21].
+ \"A quotation ending with a period\"[cite:@org21].
+
+ Notwithstanding the above, a space always appear before the citation when it
+ is to become anything else than a note.
+
+ NUMBER is the desired location of the note number with regards to the
+ quotation mark, if any. It may be `inside', `outside', or `same'. When set
+ to `same', the number appears on the same side as the punctuation, unless
+ there is punctuation on both sides or on none.
+
+ ORDER is the relative position of the citation with regards to the closest
+ punctuation. It may be `after' or `before'.
+
+For example (adaptive same before) corresponds to French typography.
+
+When the locale is unknown to this variable, the default rule is:
+
+ (adaptive outside after)
+
+This roughly follows the Oxford Guide to Style recommendations."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type
+ '(repeat
+ (list :tag "Typographic rule"
+ (string :tag "Language code")
+ (choice :tag "Location of punctuation"
+ (const :tag "Punctuation inside quotation" inside)
+ (const :tag "Punctuation outside quotation" outside)
+ (const :tag "Location depends on spacing" adaptive))
+ (choice :tag "Location of citation"
+ (const :tag "Citation inside quotation" inside)
+ (const :tag "Citation outside quotation" outside)
+ (const :tag "Citation next to punctuation" same))
+ (choice :tag "Order of citation and punctuation"
+ (const :tag "Citation first" before)
+ (const :tag "Citation last" after)))))
+
+(defcustom org-cite-punctuation-marks '("." "," ";" ":" "!" "?")
+ "List of strings that can be moved around when placing note numbers.
+
+When `org-cite-adjust-note-numbers' is non-nil, the citation processor is
+allowed to shuffle punctuation marks specified in this list in order to
+place note numbers according to rules defined in `org-cite-note-rules'."
+ :group 'org-cite
+ :package-version '(Org . "9.5")
+ :type '(repeat string))
+
+
+;;; Citation processors
+(cl-defstruct (org-cite-processor (:constructor org-cite--make-processor)
+ (:copier nil))
+ (name nil :read-only t)
+ (activate nil :read-only t)
+ (cite-styles nil :read-only t)
+ (export-bibliography nil :read-only t)
+ (export-citation nil :read-only t)
+ (export-finalizer nil :read-only t)
+ (follow nil :read-only t)
+ (insert nil :read-only t))
+
+(defvar org-cite--processors nil
+ "List of registered citation processors.
+See `org-cite-register-processor' for more information about
+processors.")
+
+(defun org-cite--get-processor (name)
+ "Return citation processor named after symbol NAME.
+Return nil if no such processor is found."
+ (seq-find (lambda (p) (eq name (org-cite-processor-name p)))
+ org-cite--processors))
+
+(defun org-cite-register-processor (name &rest body)
+ "Mark citation processor NAME as available.
+
+NAME is a symbol. BODY is a property list, where the following
+optional keys can be set:
+
+ `:activate'
+
+ Function activating a citation. It is called with a single
+ argument: a citation object extracted from the current
+ buffer. It may add text properties to the buffer. If it is
+ not provided, `org-cite-fontify-default' is used.
+
+ `:export-bibliography'
+
+ Function rendering a bibliography. It is called with six
+ arguments: the list of citation keys used in the document, as
+ strings, a list of bibliography files, the style, as a string
+ or nil, the local properties, as a property list, the export
+ back-end, as a symbol, and the communication channel, as a
+ property list.
+
+ It is called at each \"print_bibliography\" keyword in the
+ parse tree. It may return a string, a parsed element, a list
+ of parsed elements, or nil. When it returns nil, the keyword
+ is ignored. Otherwise, the value it returns replaces the
+ keyword in the export output.
+
+ `:export-citation' (mandatory for \"export\" capability)
+
+ Function rendering citations. It is called with four
+ arguments: a citation object, the style, as a pair, the
+ export back-end, as a symbol, and the communication channel,
+ as a property list.
+
+ It is called on each citation object in the parse tree. It
+ may return a string, a parsed object, a secondary string, or
+ nil. When it returns nil, the citation is ignored.
+ Otherwise, the value it returns replaces the citation object
+ in the export output.
+
+ `:export-finalizer'
+
+ Function called at the end of export process. It must accept
+ six arguments: the output, as a string, a list of citation
+ keys used in the document, a list of bibliography files, the
+ expected bibliography style, as a string or nil, the export
+ back-end, as a symbol, and the communication channel, as a
+ property list.
+
+ It must return a string, which will become the final output
+ from the export process, barring subsequent modifications
+ from export filters.
+
+ `:follow'
+
+ Function called to follow a citation. It accepts two
+ arguments, the citation or citation reference object at
+ point, and any prefix argument received during interactive
+ call of `org-open-at-point'.
+
+ `:insert'
+
+ Function called to insert a citation. It accepts two
+ arguments, the citation or citation reference object at point
+ or nil, and any prefix argument received.
+
+ `:cite-styles'
+
+ When the processor has export capability, the value can
+ specify what cite styles, variants, and their associated
+ shortcuts are supported. It can be useful information for
+ completion or linting.
+
+ The expected format is
+
+ ((STYLE . SHORTCUTS) . VARIANTS))
+
+ where STYLE is a string, SHORTCUTS a list of strings or nil,
+ and VARIANTS is a list of pairs (VARIANT . SHORTCUTS),
+ VARIANT being a string and SHORTCUTS a list of strings or
+ nil.
+
+ The \"nil\" style denotes the processor fall-back style. It
+ should have a corresponding entry in the value.
+
+Return a non-nil value on a successful operation."
+ (declare (indent 1))
+ (unless (and name (symbolp name))
+ (error "Invalid processor name: %S" name))
+ (when (org-cite--get-processor name)
+ (org-cite-unregister-processor name))
+ (push (apply #'org-cite--make-processor :name name body)
+ org-cite--processors))
+
+(defun org-cite-unregister-processor (name)
+ "Unregister citation processor NAME.
+NAME is a symbol. Raise an error if processor is not registered.
+Return a non-nil value on a successful operation."
+ (unless (and name (symbolp name))
+ (error "Invalid processor name: %S" name))
+ (pcase (org-cite--get-processor name)
+ ('nil (error "Processor %S not registered" name))
+ (processor
+ (setq org-cite--processors (delete processor org-cite--processors))))
+ t)
+
+(defun org-cite-processor-has-capability-p (processor capability)
+ "Return non-nil if PROCESSOR is able to handle CAPABILITY.
+PROCESSOR is the name of a cite processor, as a symbol. CAPABILITY is
+`activate', `export', `follow', or `insert'."
+ (let ((p (org-cite--get-processor processor)))
+ (pcase capability
+ ((guard (not p)) nil) ;undefined processor
+ ('activate (functionp (org-cite-processor-activate p)))
+ ('export (functionp (org-cite-processor-export-citation p)))
+ ('follow (functionp (org-cite-processor-follow p)))
+ ('insert (functionp (org-cite-processor-insert p)))
+ (other (error "Invalid capability: %S" other)))))
+
+
+;;; Internal functions
+(defun org-cite--set-post-blank (datum blanks)
+ "Set `:post-blank' property from element or object before DATUM to BLANKS.
+DATUM is an element or object. BLANKS is an integer. DATUM is modified
+by side-effect."
+ (if (not (eq 'plain-text (org-element-type datum)))
+ (org-element-put-property datum :post-blank blanks)
+ ;; Remove any blank from string before DATUM so it is exported
+ ;; with exactly BLANKS white spaces.
+ (org-element-set-element
+ datum
+ (replace-regexp-in-string
+ "[ \t\n]*\\'" (make-string blanks ?\s) datum))))
+
+(defun org-cite--set-previous-post-blank (datum blanks info)
+ "Set `:post-blank' property from element or object before DATUM to BLANKS.
+DATUM is an element or object. BLANKS is an integer. INFO is the export
+state, as a property list. Previous element or object, if any, is modified by
+side-effect."
+ (let ((previous (org-export-get-previous-element datum info)))
+ (when previous
+ (org-cite--set-post-blank previous blanks))))
+
+(defun org-cite--insert-at-split (s citation n regexp)
+ "Split string S and insert CITATION object between the two parts.
+S is split at beginning of match group N upon matching REGEXP against it.
+This function assumes S precedes CITATION."
+ ;; When extracting the citation, remove white spaces before it, but
+ ;; preserve those after it.
+ (let ((post-blank (org-element-property :post-blank citation)))
+ (when (and post-blank (> post-blank 0))
+ (org-element-insert-before (make-string post-blank ?\s) citation)))
+ (org-element-insert-before
+ (org-element-put-property (org-element-extract-element citation)
+ :post-blank 0)
+ s)
+ (string-match regexp s)
+ (let* ((split (match-beginning n))
+ (first-part (substring s nil split))
+ ;; Remove trailing white spaces as they are before the
+ ;; citation.
+ (last-part
+ (replace-regexp-in-string (rx (1+ (any blank ?\n)) string-end)
+ ""
+ (substring s split))))
+ (when (org-string-nw-p first-part)
+ (org-element-insert-before first-part citation))
+ (org-element-set-element s last-part)))
+
+(defun org-cite--move-punct-before (punct citation s info)
+ "Move punctuation PUNCT before CITATION object.
+String S contains PUNCT. INFO is the export state, as a property list.
+The function assumes S follows CITATION. Parse tree is modified by side-effect."
+ (if (equal s punct)
+ (org-element-extract-element s) ;it would be empty anyway
+ (org-element-set-element s (substring s (length punct))))
+ ;; Remove blanks before citation.
+ (org-cite--set-previous-post-blank citation 0 info)
+ (org-element-insert-before
+ ;; Blanks between citation and punct are now before punct and
+ ;; citation.
+ (concat (make-string (or (org-element-property :post-blank citation) 0) ?\s)
+ punct)
+ citation))
+
+(defun org-cite--parse-as-plist (s)
+ "Parse string S as a property list.
+Values are always strings. Return nil if S is nil."
+ (cond
+ ((null s) nil)
+ ((stringp s)
+ (with-temp-buffer
+ (save-excursion (insert s))
+ (skip-chars-forward " \t")
+ (let ((results nil)
+ (value-flag nil))
+ (while (not (eobp))
+ (pcase (char-after)
+ (?:
+ (push (read (current-buffer)) results)
+ (setq value-flag t))
+ ((guard (not value-flag))
+ (skip-chars-forward "^ \t"))
+ (?\"
+ (let ((origin (point)))
+ (condition-case _
+ (progn
+ (read (current-buffer))
+ (push (buffer-substring (1+ origin) (1- (point))) results))
+ (end-of-file
+ (goto-char origin)
+ (skip-chars-forward "^ \t")
+ (push (buffer-substring origin (point)) results)))
+ (setq value-flag nil)))
+ (_
+ (let ((origin (point)))
+ (skip-chars-forward "^ \t")
+ (push (buffer-substring origin (point)) results)
+ (setq value-flag nil))))
+ (skip-chars-forward " \t"))
+ (nreverse results))))
+ (t (error "Invalid argument type: %S" s))))
+
+(defun org-cite--get-note-rule (info)
+ "Return punctuation rule according to language used for export.
+
+INFO is the export state, as a property list.
+
+Rule is found according to the language used for export and
+`org-cite-note-rules', which see.
+
+If there is no rule matching current language, the rule defaults
+to (adaptive outside after)."
+ (let* ((language-tags
+ ;; Normalize language as a language-region tag, as described
+ ;; in RFC 4646.
+ (pcase (split-string (plist-get info :language) "[-_]")
+ (`(,language)
+ (list language
+ (or (cdr (assoc language org-cite--default-region-alist))
+ language)))
+ (`(,language ,region)
+ (list language region))
+ (other
+ (error "Invalid language identifier: %S" other))))
+ (language-region (mapconcat #'downcase language-tags "-"))
+ (language (car language-tags)))
+ (or (cdr (assoc language-region org-cite-note-rules))
+ (cdr (assoc language org-cite-note-rules))
+ '(adaptive outside after))))
+
+
+;;; Generic tools
+(defun org-cite-list-bibliography-files ()
+ "List all bibliography files defined in the buffer."
+ (delete-dups
+ (append (mapcar (lambda (value)
+ (pcase value
+ (`(,f . ,d)
+ (expand-file-name (org-strip-quotes f) d))))
+ (pcase (org-collect-keywords
+ '("BIBLIOGRAPHY") nil '("BIBLIOGRAPHY"))
+ (`(("BIBLIOGRAPHY" . ,pairs)) pairs)))
+ org-cite-global-bibliography)))
+
+(defun org-cite-get-references (citation &optional keys-only)
+ "Return citations references contained in CITATION object.
+
+When optional argument KEYS-ONLY is non-nil, return the references' keys, as a
+list of strings.
+
+Assume CITATION object comes from either a full parse tree, e.g., during export,
+or from the current buffer."
+ (let ((contents (org-element-contents citation)))
+ (cond
+ ((null contents)
+ (org-with-point-at (org-element-property :contents-begin citation)
+ (narrow-to-region (point) (org-element-property :contents-end citation))
+ (let ((references nil))
+ (while (not (eobp))
+ (let ((reference (org-element-citation-reference-parser)))
+ (goto-char (org-element-property :end reference))
+ (push (if keys-only
+ (org-element-property :key reference)
+ reference)
+ references)))
+ (nreverse references))))
+ (keys-only (mapcar (lambda (r) (org-element-property :key r)) contents))
+ (t contents))))
+
+(defun org-cite-boundaries (citation)
+ "Return the beginning and end strict position of CITATION.
+Returns a (BEG . END) pair."
+ (let ((beg (org-element-property :begin citation))
+ (end (org-with-point-at (org-element-property :end citation)
+ (skip-chars-backward " \t")
+ (point))))
+ (cons beg end)))
+
+(defun org-cite-key-boundaries (reference)
+ "Return citation REFERENCE's key boundaries as buffer positions.
+The function returns a pair (START . END) where START and END denote positions
+in the current buffer. Positions include leading \"@\" character."
+ (org-with-point-at (org-element-property :begin reference)
+ (let ((end (org-element-property :end reference)))
+ (re-search-forward org-element-citation-key-re end t)
+ (cons (match-beginning 0) (match-end 0)))))
+
+(defun org-cite-main-affixes (citation)
+ "Return main affixes for CITATION object.
+
+Some export back-ends only support a single pair of affixes per
+citation, even if it contains multiple keys. This function
+decides what affixes are the most appropriate.
+
+Return a pair (PREFIX . SUFFIX) where PREFIX and SUFFIX are
+parsed data."
+ (let ((source
+ ;; When there are multiple references, use global affixes.
+ ;; Otherwise, local affixes have priority.
+ (pcase (org-cite-get-references citation)
+ (`(,reference) reference)
+ (_ citation))))
+ (cons (org-element-property :prefix source)
+ (org-element-property :suffix source))))
+
+(defun org-cite-supported-styles (&optional processors)
+ "List of supported citation styles and variants.
+
+Supported styles are those handled by export processors from
+`org-cite-export-processors', or in PROCESSORS, as a list of symbols,
+when non-nil.
+
+Return value is a list with the following items:
+
+ ((STYLE . SHORTCUTS) . VARIANTS))
+
+where STYLE is a string, SHORTCUTS a list of strings, and VARIANTS is a list of
+pairs (VARIANT . SHORTCUTS), VARIANT being a string and SHORTCUTS a list of
+strings."
+ (let ((collection
+ (seq-mapcat
+ (lambda (name)
+ (org-cite-processor-cite-styles (org-cite--get-processor name)))
+ (or processors
+ (mapcar (pcase-lambda (`(,_ . (,name . ,_))) name)
+ org-cite-export-processors))))
+ (result nil))
+ ;; Merge duplicate styles. Each style full name is guaranteed to
+ ;; be unique, and associated to all shortcuts and all variants in
+ ;; the initial collection.
+ (pcase-dolist (`((,style . ,shortcuts) . ,variants) collection)
+ (let ((entry (assoc style result)))
+ (if (not entry)
+ (push (list style shortcuts variants) result)
+ (setf (nth 1 entry)
+ (seq-uniq (append shortcuts (nth 1 entry))))
+ (setf (nth 2 entry)
+ (append variants (nth 2 entry))))))
+ ;; Return value with the desired format.
+ (nreverse
+ (mapcar (pcase-lambda (`(,style ,shortcuts ,variants))
+ (cons (cons style (nreverse shortcuts))
+ ;; Merge variant shortcuts.
+ (let ((result nil))
+ (pcase-dolist (`(,variant . ,shortcuts) variants)
+ (let ((entry (assoc variant result)))
+ (if (not entry)
+ (push (cons variant shortcuts) result)
+ (setf (cdr entry)
+ (seq-uniq (append shortcuts (cdr entry)))))))
+ result)))
+ result))))
+
+(defun org-cite-delete-citation (datum)
+ "Delete citation or citation reference DATUM.
+When removing the last reference, also remove the whole citation."
+ (pcase (org-element-type datum)
+ ('citation
+ (pcase-let* ((`(,begin . ,end) (org-cite-boundaries datum))
+ (pos-before-blank
+ (org-with-point-at begin
+ (skip-chars-backward " \t")
+ (point)))
+ (pos-after-blank (org-element-property :end datum))
+ (first-on-line?
+ (= pos-before-blank (line-beginning-position)))
+ (last-on-line?
+ (= pos-after-blank (line-end-position))))
+ (cond
+ ;; The citation is alone on its line. Remove the whole line.
+ ;; Do not leave it blank as it might break a surrounding
+ ;; paragraph.
+ ((and first-on-line? last-on-line?)
+ (delete-region (line-beginning-position) (line-beginning-position 2)))
+ ;; When the citation starts the line, preserve indentation.
+ (first-on-line? (delete-region begin pos-after-blank))
+ ;; When the citation ends the line, remove any trailing space.
+ (last-on-line? (delete-region pos-before-blank (line-end-position)))
+ ;; Otherwise, delete blanks before the citation.
+ ;; Nevertheless, make sure there is at least one blank left,
+ ;; so as to not splice unrelated surroundings.
+ (t
+ (delete-region pos-before-blank end)
+ (when (= pos-after-blank end)
+ (org-with-point-at pos-before-blank (insert " ")))))))
+ ('citation-reference
+ (let* ((citation (org-element-property :parent datum))
+ (references (org-cite-get-references citation))
+ (begin (org-element-property :begin datum))
+ (end (org-element-property :end datum)))
+ (cond
+ ;; Single reference.
+ ((= 1 (length references))
+ (org-cite-delete-citation citation))
+ ;; First reference, no prefix.
+ ((and (= begin (org-element-property :contents-begin citation))
+ (not (org-element-property :prefix citation)))
+ (org-with-point-at (org-element-property :begin datum)
+ (skip-chars-backward " \t")
+ (delete-region (point) end)))
+ ;; Last reference, no suffix.
+ ((and (= end (org-element-property :contents-end citation))
+ (not (org-element-property :suffix citation)))
+ (delete-region (1- begin) (1- (cdr (org-cite-boundaries citation)))))
+ ;; Somewhere in-between.
+ (t
+ (delete-region begin end)))))
+ (other
+ (error "Invalid object type: %S" other))))
+
+
+;;; Tools only available during export
+(defun org-cite-citation-style (citation info)
+ "Return citation style used for CITATION object.
+
+Style is a pair (NAME . VARIANT) where NAME and VARIANT are strings or nil.
+A nil NAME means the default style for the current processor should be used.
+
+INFO is a plist used as a communication channel."
+ (let* ((separate
+ (lambda (s)
+ (cond
+ ((null s) (cons nil nil))
+ ((not (string-match "/" s)) (cons s nil))
+ (t (cons (substring s nil (match-beginning 0))
+ (org-string-nw-p (substring s (match-end 0))))))))
+ (local (funcall separate (org-element-property :style citation)))
+ (global
+ (funcall separate (pcase (plist-get info :cite-export)
+ (`(,_ ,_ ,style) style)
+ (_ nil)))))
+ (cond
+ ((org-string-nw-p (car local))
+ (cons (org-not-nil (car local)) (cdr local)))
+ (t
+ (cons (org-not-nil (car global))
+ (or (cdr local) (cdr global)))))))
+
+(defun org-cite-bibliography-style (info)
+ "Return expected bibliography style.
+INFO is a plist used as a communication channel."
+ (pcase (plist-get info :cite-export)
+ (`(,_ ,style ,_) style)
+ (_ nil)))
+
+(defun org-cite-bibliography-properties (keyword)
+ "Return properties associated to \"print_bibliography\" KEYWORD object.
+Return value is a property list."
+ (org-cite--parse-as-plist (org-element-property :value keyword)))
+
+(defun org-cite-list-citations (info)
+ "List citations in the exported document.
+Citations are ordered by appearance in the document, when following footnotes.
+INFO is the export communication channel, as a property list."
+ (or (plist-get info :citations)
+ (letrec ((cites nil)
+ (tree (plist-get info :parse-tree))
+ (find-definition
+ ;; Find definition for standard reference LABEL. At
+ ;; this point, it is impossible to rely on
+ ;; `org-export-get-footnote-definition' because the
+ ;; function caches results that could contain
+ ;; un-processed citation objects. So we use
+ ;; a simplified version of the function above.
+ (lambda (label)
+ (org-element-map tree 'footnote-definition
+ (lambda (d)
+ (and (equal label (org-element-property :label d))
+ (or (org-element-contents d) "")))
+ info t)))
+ (search-cites
+ (lambda (data)
+ (org-element-map data '(citation footnote-reference)
+ (lambda (datum)
+ (pcase (org-element-type datum)
+ ('citation (push datum cites))
+ ;; Do not force entering inline definitions, since
+ ;; `org-element-map' is going to enter it anyway.
+ ((guard (eq 'inline (org-element-property :type datum))))
+ ;; Walk footnote definition.
+ (_
+ (let ((label (org-element-property :label datum)))
+ (funcall search-cites
+ (funcall find-definition label))))))
+ info nil 'footnote-definition t))))
+ (funcall search-cites tree)
+ (let ((result (nreverse cites)))
+ (plist-put info :citations result)
+ result))))
+
+(defun org-cite-list-keys (info)
+ "List citation keys in the exported document.
+Keys are ordered by first appearance in the document, when following footnotes.
+Duplicate keys are removed. INFO is the export communication channel, as a
+property list."
+ (delete-dups
+ (org-element-map (org-cite-list-citations info) 'citation-reference
+ (lambda (r) (org-element-property :key r))
+ info)))
+
+(defun org-cite-key-number (key info &optional predicate)
+ "Return number associated to string KEY.
+
+INFO is the export communication channel, as a property list.
+
+Optional argument PREDICATE is called with two keys, and returns non-nil
+if the first reference should sort before the second. When nil, references
+are sorted in order cited."
+ (let* ((keys (org-cite-list-keys info))
+ (sorted-keys (if (functionp predicate)
+ (sort keys predicate)
+ keys))
+ (position (seq-position sorted-keys key #'string-equal)))
+ (and (integerp position)
+ (1+ position))))
+
+(defun org-cite-inside-footnote-p (citation &optional strict)
+ "Non-nil when CITATION object is contained within a footnote.
+
+When optional argument STRICT is non-nil, return t only if CITATION represents
+the sole contents of the footnote, e.g., after calling `org-cite-wrap-citation'.
+
+When non-nil, the return value if the footnote container."
+ (let ((footnote
+ (org-element-lineage citation
+ '(footnote-definition footnote-reference))))
+ (and footnote
+ (or (not strict)
+ (equal (org-element-contents (org-element-property :parent citation))
+ (list citation)))
+ ;; Return value.
+ footnote)))
+
+(defun org-cite-wrap-citation (citation info)
+ "Wrap an anonymous inline footnote around CITATION object in the parse tree.
+
+INFO is the export state, as a property list.
+
+White space before the citation, if any, are removed. The parse tree is
+modified by side-effect.
+
+Return newly created footnote object."
+ (let ((footnote
+ (list 'footnote-reference
+ (list :label nil
+ :type 'inline
+ :contents-begin (org-element-property :begin citation)
+ :contents-end (org-element-property :end citation)
+ :post-blank (org-element-property :post-blank citation)))))
+ ;; Remove any white space before citation.
+ (org-cite--set-previous-post-blank citation 0 info)
+ ;; Footnote swallows citation.
+ (org-element-insert-before footnote citation)
+ (org-element-adopt-elements footnote
+ (org-element-extract-element citation))))
+
+(defun org-cite-adjust-note (citation info &optional rule punct)
+ "Adjust note number location for CITATION object, and punctuation around it.
+
+INFO is the export state, as a property list.
+
+Optional argument RULE is the punctuation rule used, as a triplet. When nil,
+rule is determined according to `org-cite-note-rules', which see.
+
+Optional argument PUNCT is a list of punctuation marks to be considered.
+When nil, it defaults to `org-cite-punctuation-marks'.
+
+Parse tree is modified by side-effect.
+
+Note: when calling both `org-cite-adjust-note' and `org-cite-wrap-citation' on
+the same object, call `org-cite-adjust-note' first."
+ (when org-cite-adjust-note-numbers
+ (pcase-let* ((rule (or rule (org-cite--get-note-rule info)))
+ (punct-re (regexp-opt (or punct org-cite-punctuation-marks)))
+ ;; with Emacs <27.1. Argument of `regexp' form (PUNCT-RE this case)
+ ;; must be a string literal.
+ (previous-punct-re
+ (rx-to-string `(seq (opt (group (regexp ,(rx (0+ (any blank ?\n))))
+ (regexp ,punct-re)))
+ (regexp ,(rx (opt (0+ (any blank ?\n)) (group ?\"))
+ (opt (group (1+ (any blank ?\n))))
+ string-end)))
+ t))
+ (next-punct-re
+ (rx-to-string `(seq string-start
+ (group (0+ (any blank ?\n)) (regexp ,punct-re)))
+ t))
+ (next (org-export-get-next-element citation info))
+ (final-punct
+ (and (stringp next)
+ (string-match next-punct-re next)
+ (match-string 1 next)))
+ (previous
+ ;; Find the closest terminal object. Consider
+ ;; citation, subscript and superscript objects as
+ ;; terminal.
+ (org-last
+ (org-element-map (org-export-get-previous-element citation info)
+ '(citation code entity export-snippet footnote-reference
+ line-break latex-fragment link plain-text
+ radio-target statistics-cookie timestamp
+ verbatim)
+ #'identity info nil '(citation subscript superscript))))
+ (`(,punct ,quote ,spacing)
+ (and (stringp previous)
+ (string-match previous-punct-re previous)
+ (list (match-string 1 previous)
+ (match-string 2 previous)
+ (match-string 3 previous)))))
+ ;; Bail you when there is no quote and either no punctuation, or
+ ;; punctuation on both sides.
+ (when (or quote (org-xor punct final-punct))
+ ;; Phase 1: handle punctuation rule.
+ (pcase rule
+ ((guard (not quote)) nil)
+ ;; Move punctuation inside.
+ (`(,(or `inside (and `adaptive (guard (not spacing)))) . ,_)
+ ;; This only makes sense if there is a quotation before the
+ ;; citation that does not end with some punctuation.
+ (when (and (not punct) final-punct)
+ ;; Quote guarantees there is a string object before
+ ;; citation. Likewise, any final punctuation guarantees
+ ;; there is a string object following citation.
+ (let ((new-prev
+ (replace-regexp-in-string
+ previous-punct-re
+ (concat final-punct "\"") previous nil nil 2))
+ (new-next
+ (replace-regexp-in-string
+ ;; Before Emacs-27.1 `literal' `rx' form with a variable
+ ;; as an argument is not available.
+ (rx-to-string `(seq string-start ,final-punct) t)
+ "" next)))
+ (org-element-set-element previous new-prev)
+ (org-element-set-element next new-next)
+ (setq previous new-prev)
+ (setq next new-next)
+ (setq punct final-punct)
+ (setq final-punct nil))))
+ ;; Move punctuation outside.
+ (`(,(or `outside (and `adaptive (guard spacing))) . ,_)
+ ;; This is only meaningful if there is some inner
+ ;; punctuation and no final punctuation already.
+ (when (and punct (not final-punct))
+ ;; Inner punctuation guarantees there is text object
+ ;; before the citation. However, there is no information
+ ;; about the object following citation, if any.
+ ;; Therefore, we handle all the possible cases (string,
+ ;; other type, or none).
+ (let ((new-prev
+ (replace-regexp-in-string
+ previous-punct-re "" previous nil nil 1))
+ (new-next (if (stringp next) (concat punct next) punct)))
+ (org-element-set-element previous new-prev)
+ (cond
+ ((stringp next)
+ (org-element-set-element next new-next))
+ (next
+ (org-element-insert-before new-next next))
+ (t
+ (org-element-adopt-elements
+ (org-element-property :parent citation)
+ new-next)))
+ (setq previous new-prev)
+ (setq next new-next)
+ (setq final-punct punct)
+ (setq punct nil))))
+ (_
+ (error "Invalid punctuation rule: %S" rule))))
+ ;; Phase 2: move citation to its appropriate location.
+ ;;
+ ;; First transform relative citation location into a definitive
+ ;; location, according to the surrounding punctuation.
+ (pcase rule
+ (`(,punctuation same ,order)
+ (setf rule
+ (list punctuation
+ (cond
+ ;; When there is punctuation on both sides, the
+ ;; citation is necessarily on the outside.
+ ((and punct final-punct) 'outside)
+ (punct 'inside)
+ (final-punct 'outside)
+ ;; No punctuation: bail out on next step.
+ (t nil))
+ order))))
+ (pcase rule
+ (`(,_ nil ,_) nil)
+ (`(,_ inside after)
+ ;; Citation has to be moved after punct, if there is
+ ;; a quotation mark, or after final punctuation.
+ (cond
+ (quote
+ (org-cite--insert-at-split previous citation 2 previous-punct-re))
+ (final-punct
+ (org-cite--move-punct-before final-punct citation next info))
+ ;; There is only punct, and we're already after it.
+ (t nil)))
+ (`(,_ inside before)
+ ;; Citation is already behind final-punct, so only consider
+ ;; other locations.
+ (when (or punct quote)
+ (org-cite--insert-at-split previous citation 0 previous-punct-re)))
+ (`(,_ outside after)
+ ;; Citation is already after any punct or quote. It can only
+ ;; move past final punctuation, if there is one.
+ (when final-punct
+ (org-cite--move-punct-before final-punct citation next info)))
+ (`(,_ outside before)
+ ;; The only non-trivial case is when citation follows punct
+ ;; without a quote.
+ (when (and punct (not quote))
+ (org-cite--insert-at-split previous citation 0 previous-punct-re)))
+ (_
+ (error "Invalid punctuation rule: %S" rule))))))
+
+
+;;; Tools generating or operating on parsed data
+(defun org-cite-parse-elements (s)
+ "Parse string S as a list of Org elements.
+
+The return value is suitable as a replacement for a
+\"print_bibliography\" keyword. As a consequence, the function
+raises an error if S contains a headline."
+ (with-temp-buffer
+ (insert s)
+ (pcase (org-element-contents (org-element-parse-buffer))
+ ('nil nil)
+ (`(,(and section (guard (eq 'section (org-element-type section)))))
+ (org-element-contents section))
+ (_
+ (error "Headlines cannot replace a keyword")))))
+
+(defun org-cite-parse-objects (s &optional affix)
+ "Parse string S as a secondary string.
+
+The return value is suitable as a replacement for a citation object.
+
+When optional argument AFFIX is non-nil, restrict the set of allowed object
+types to match the contents of a citation affix."
+ (org-element-parse-secondary-string
+ s (org-element-restriction (if affix 'citation-reference 'paragraph))))
+
+(defun org-cite-make-paragraph (&rest data)
+ "Return a paragraph element containing DATA.
+DATA are strings, objects or secondary strings."
+ (apply #'org-element-create 'paragraph nil (apply #'org-cite-concat data)))
+
+(defun org-cite-emphasize (type &rest data)
+ "Apply emphasis TYPE on DATA.
+TYPE is a symbol among `bold', `italic', `strike-through' and `underline'.
+DATA are strings, objects or secondary strings. Return an object of type TYPE."
+ (declare (indent 1))
+ (unless (memq type '(bold italic strike-through underline))
+ (error "Wrong emphasis type: %S" type))
+ (apply #'org-element-create type nil (apply #'org-cite-concat data)))
+
+(defun org-cite-concat (&rest data)
+ "Concatenate all the DATA arguments and make the result a secondary string.
+Each argument may be a string, an object, or a secondary string."
+ (let ((results nil))
+ (dolist (datum (reverse data))
+ (pcase datum
+ ('nil nil)
+ ;; Element or object.
+ ((pred org-element-type) (push datum results))
+ ;; Secondary string.
+ ((pred consp) (setq results (append datum results)))
+ (_
+ (signal
+ 'wrong-type-argument
+ (list (format "Argument is not a string or a secondary string: %S"
+ datum))))))
+ results))
+
+(defun org-cite-mapconcat (function data separator)
+ "Apply FUNCTION to each element of DATA, and return a secondary string.
+
+In between each pair of results, stick SEPARATOR, which may be a string,
+an object, or a secondary string. FUNCTION must be a function of one argument,
+and must return either a string, an object, or a secondary string."
+ (and data
+ (let ((result (list (funcall function (car data)))))
+ (dolist (datum (cdr data))
+ (setq result
+ (org-cite-concat result separator (funcall function datum))))
+ result)))
+
+
+;;; Internal interface with fontification (activate capability)
+(defun org-cite-fontify-default (cite)
+ "Fontify CITE with `org-cite' and `org-cite-key' faces.
+CITE is a citation object. The function applies `org-cite' face
+on the whole citation, and `org-cite-key' face on each key."
+ (let ((beg (org-element-property :begin cite))
+ (end (org-with-point-at (org-element-property :end cite)
+ (skip-chars-backward " \t")
+ (point))))
+ (add-text-properties beg end '(font-lock-multiline t))
+ (add-face-text-property beg end 'org-cite)
+ (dolist (reference (org-cite-get-references cite))
+ (let ((boundaries (org-cite-key-boundaries reference)))
+ (add-face-text-property (car boundaries) (cdr boundaries)
+ 'org-cite-key)))))
+
+(defun org-cite-activate (limit)
+ "Activate citations from up to LIMIT buffer position.
+Each citation encountered is activated using the appropriate function
+from the processor set in `org-cite-activate-processor'."
+ (let* ((name org-cite-activate-processor)
+ (activate
+ (or (and name
+ (org-cite-processor-has-capability-p name 'activate)
+ (org-cite-processor-activate (org-cite--get-processor name)))
+ #'org-cite-fontify-default)))
+ (when (re-search-forward org-element-citation-prefix-re limit t)
+ (let ((cite (org-with-point-at (match-beginning 0)
+ (org-element-citation-parser))))
+ (when cite
+ (funcall activate cite)
+ ;; Move after cite object and make sure to return
+ ;; a non-nil value.
+ (goto-char (org-element-property :end cite)))))))
+
+
+;;; Internal interface with Org Export library (export capability)
+(defun org-cite-store-bibliography (info)
+ "Store bibliography in the communication channel.
+
+Bibliography is stored as a list of absolute file names in the `:bibliography'
+property.
+
+INFO is the communication channel, as a plist. It is modified by side-effect."
+ (plist-put info :bibliography (org-cite-list-bibliography-files)))
+
+(defun org-cite-store-export-processor (info)
+ "Store export processor in the `:cite-export' property during export.
+
+Export processor is stored as a triplet, or nil.
+
+When non-nil, it is defined as (NAME BIBLIOGRAPHY-STYLE CITATION-STYLE) where
+NAME is a symbol, whereas BIBLIOGRAPHY-STYLE and CITATION-STYLE are strings,
+or nil.
+
+INFO is the communication channel, as a plist. It is modified by side-effect."
+ (let* ((err
+ (lambda (s)
+ (user-error "Invalid cite export processor definition: %S" s)))
+ (processor
+ (pcase (plist-get info :cite-export)
+ ((or "" `nil) nil)
+ ;; Value is a string. It comes from a "cite_export"
+ ;; keyword. It may contain between 1 and 3 tokens, the
+ ;; first one being a symbol and the other (optional) two,
+ ;; strings.
+ ((and (pred stringp) s)
+ (with-temp-buffer
+ (save-excursion (insert s))
+ (let ((result (list (read (current-buffer)))))
+ (dotimes (_ 2)
+ (skip-chars-forward " \t")
+ (cond
+ ((eobp) (push nil result))
+ ((char-equal ?\" (char-after))
+ (condition-case _
+ (push (org-not-nil (read (current-buffer))) result)
+ (error (funcall err s))))
+ (t
+ (let ((origin (point)))
+ (skip-chars-forward "^ \t")
+ (push (org-not-nil (buffer-substring origin (point)))
+ result)))))
+ (unless (eobp) (funcall err s))
+ (nreverse result))))
+ ;; Value is an alist. It must come from
+ ;; `org-cite-export-processors' variable. Find the most
+ ;; appropriate processor according to current export
+ ;; back-end.
+ ((and (pred consp) alist)
+ (let* ((backend (plist-get info :back-end))
+ (candidates
+ ;; Limit candidates to processors associated to
+ ;; back-ends derived from or equal to the current
+ ;; one.
+ (sort (seq-filter
+ (pcase-lambda (`(,key . ,_))
+ (org-export-derived-backend-p backend key))
+ alist)
+ (lambda (a b)
+ (org-export-derived-backend-p (car a) (car b))))))
+ ;; Select the closest candidate, or fallback to t.
+ (pcase (or (car candidates) (assq t alist))
+ ('nil nil)
+ (`(,_ . ,p)
+ ;; Normalize value by turning it into a triplet.
+ (pcase p
+ (`(,(pred symbolp))
+ (append p (list nil nil)))
+ (`(,(pred symbolp) ,(pred string-or-null-p))
+ (append p (list nil)))
+ (`(,(pred symbolp)
+ ,(pred string-or-null-p)
+ ,(pred string-or-null-p))
+ p)
+ (_ (funcall err p))))
+ (other (funcall err (cdr other))))))
+ (other (funcall err other)))))
+ (pcase processor
+ ('nil nil)
+ (`(,name . ,_)
+ (cond
+ ((not (org-cite--get-processor name))
+ (user-error "Unknown processor %S" name))
+ ((not (org-cite-processor-has-capability-p name 'export))
+ (user-error "Processor %S is unable to handle citation export" name)))))
+ (plist-put info :cite-export processor)))
+
+(defun org-cite-export-citation (citation _ info)
+ "Export CITATION object according to INFO property list.
+This function delegates the export of the current citation to the
+selected citation processor."
+ (pcase (plist-get info :cite-export)
+ ('nil nil)
+ (`(,p ,_ ,_)
+ (funcall (org-cite-processor-export-citation (org-cite--get-processor p))
+ citation
+ (org-cite-citation-style citation info)
+ (plist-get info :back-end)
+ info))
+ (other (error "Invalid `:cite-export' value: %S" other))))
+
+(defun org-cite-export-bibliography (keyword _ info)
+ "Return bibliography associated to \"print_bibliography\" KEYWORD.
+BACKEND is the export back-end, as a symbol. INFO is a plist
+used as a communication channel."
+ (pcase (plist-get info :cite-export)
+ ('nil nil)
+ (`(,p ,_ ,_)
+ (let ((export-bibilography
+ (org-cite-processor-export-bibliography
+ (org-cite--get-processor p))))
+ (when export-bibilography
+ (funcall export-bibilography
+ (org-cite-list-keys info)
+ (plist-get info :bibliography)
+ (org-cite-bibliography-style info)
+ (org-cite-bibliography-properties keyword)
+ (plist-get info :back-end)
+ info))))
+ (other (error "Invalid `:cite-export' value: %S" other))))
+
+(defun org-cite-process-citations (info)
+ "Replace all citations in the parse tree.
+INFO is the communication channel, as a plist. Parse tree is modified
+by side-effect."
+ (dolist (cite (org-cite-list-citations info))
+ (let ((replacement (org-cite-export-citation cite nil info))
+ (blanks (or (org-element-property :post-blank cite) 0)))
+ (if (null replacement)
+ ;; Before removing the citation, transfer its `:post-blank'
+ ;; property to the object before, if any.
+ (org-cite--set-previous-post-blank cite blanks info)
+ ;; Make sure there is a space between a quotation mark and
+ ;; a citation. This is particularly important when using
+ ;; `adaptive' note rule. See `org-cite-note-rules'.
+ (let ((previous (org-export-get-previous-element cite info)))
+ (when (and (org-string-nw-p previous)
+ (string-suffix-p "\"" previous))
+ (org-cite--set-previous-post-blank cite 1 info)))
+ (pcase replacement
+ ;; String.
+ ((pred stringp)
+ ;; Handle `:post-blank' before replacing value.
+ (let ((output (concat (org-trim replacement)
+ (make-string blanks ?\s))))
+ (org-element-insert-before (org-export-raw-string output) cite)))
+ ;; Single element.
+ (`(,(pred symbolp) . ,_)
+ (org-cite--set-post-blank replacement blanks)
+ (org-element-insert-before replacement cite))
+ ;; Secondary string: splice objects at cite's place.
+ ;; Transfer `:post-blank' to the last object.
+ ((pred consp)
+ (let ((last nil))
+ (dolist (datum replacement)
+ (setq last datum)
+ (org-element-insert-before datum cite))
+ (org-cite--set-post-blank last blanks)))
+ (_
+ (error "Invalid return value from citation export processor: %S"
+ replacement))))
+ (org-element-extract-element cite))))
+
+(defun org-cite-process-bibliography (info)
+ "Replace all \"print_bibliography\" keywords in the parse tree.
+
+INFO is the communication channel, as a plist. Parse tree is modified
+by side effect."
+ (org-element-map (plist-get info :parse-tree) 'keyword
+ (lambda (keyword)
+ (when (equal "PRINT_BIBLIOGRAPHY" (org-element-property :key keyword))
+ (let ((replacement (org-cite-export-bibliography keyword nil info))
+ (blanks (or (org-element-property :post-blank keyword) 0)))
+ (pcase replacement
+ ;; Before removing the citation, transfer its
+ ;; `:post-blank' property to the element before, if any.
+ ('nil
+ (org-cite--set-previous-post-blank keyword blanks info)
+ (org-element-extract-element keyword))
+ ;; Handle `:post-blank' before replacing keyword with string.
+ ((pred stringp)
+ (let ((output (concat (org-element-normalize-string replacement)
+ (make-string blanks ?\n))))
+ (org-element-set-element keyword (org-export-raw-string output))))
+ ;; List of elements: splice contents before keyword and
+ ;; remove the latter. Transfer `:post-blank' to last
+ ;; element.
+ ((and `(,(pred listp) . ,_) contents)
+ (let ((last nil))
+ (dolist (datum contents)
+ (setq last datum)
+ (org-element-insert-before datum keyword))
+ (org-cite--set-post-blank last blanks)
+ (org-element-extract-element keyword)))
+ ;; Single element: replace the keyword.
+ (`(,(pred symbolp) . ,_)
+ (org-cite--set-post-blank replacement blanks)
+ (org-element-set-element keyword replacement))
+ (_
+ (error "Invalid return value from citation export processor: %S"
+ replacement))))))
+ info))
+
+(defun org-cite-finalize-export (output info)
+ "Finalizer for export process.
+OUTPUT is the full output of the export process. INFO is the communication
+channel, as a property list."
+ (pcase (plist-get info :cite-export)
+ ('nil output)
+ (`(,p ,_ ,_)
+ (let ((finalizer
+ (org-cite-processor-export-finalizer (org-cite--get-processor p))))
+ (if (not finalizer)
+ output
+ (funcall finalizer
+ output
+ (org-cite-list-keys info)
+ (plist-get info :bibliography)
+ (org-cite-bibliography-style info)
+ (plist-get info :back-end)
+ info))))
+ (other (error "Invalid `:cite-export' value: %S" other))))
+
+
+;;; Internal interface with `org-open-at-point' (follow capability)
+(defun org-cite-follow (datum arg)
+ "Follow citation or citation-reference DATUM.
+Following is done according to the processor set in `org-cite-follow-processor'.
+ARG is the prefix argument received when calling `org-open-at-point', or nil."
+ (let ((name org-cite-follow-processor))
+ (cond
+ ((null name)
+ (user-error "No processor set to follow citations"))
+ ((not (org-cite--get-processor name))
+ (user-error "Unknown processor %S" name))
+ ((not (org-cite-processor-has-capability-p name 'follow))
+ (user-error "Processor %S cannot follow citations" name))
+ (t
+ (let ((follow (org-cite-processor-follow (org-cite--get-processor name))))
+ (funcall follow datum arg))))))
+
+
+;;; Meta-command for citation insertion (insert capability)
+(defun org-cite--allowed-p (context)
+ "Non-nil when a citation can be inserted at point.
+CONTEXT is the element or object at point, as returned by `org-element-context'."
+ (let ((type (org-element-type context)))
+ (cond
+ ;; No citation in attributes, except in parsed ones.
+ ;;
+ ;; XXX: Inserting citation in a secondary value is not allowed
+ ;; yet. Is it useful?
+ ((let ((post (org-element-property :post-affiliated context)))
+ (and post (< (point) post)))
+ (let ((case-fold-search t))
+ (looking-back
+ (rx-to-string
+ `(seq line-start (0+ (any " \t"))
+ "#+"
+ (or ,@org-element-parsed-keywords)
+ ":"
+ (0+ nonl))
+ t)
+ (line-beginning-position))))
+ ;; Paragraphs and blank lines at top of document are fine.
+ ((memq type '(nil paragraph)))
+ ;; So are contents of verse blocks.
+ ((eq type 'verse-block)
+ (and (>= (point) (org-element-property :contents-begin context))
+ (< (point) (org-element-property :contents-end context))))
+ ;; In an headline or inlinetask, point must be either on the
+ ;; heading itself or on the blank lines below.
+ ((memq type '(headline inlinetask))
+ (or (not (org-at-heading-p))
+ (and (save-excursion
+ (beginning-of-line)
+ (and (let ((case-fold-search t))
+ (not (looking-at-p "\\*+ END[ \t]*$")))
+ (let ((case-fold-search nil))
+ (looking-at org-complex-heading-regexp))))
+ (match-beginning 4)
+ (>= (point) (match-beginning 4))
+ (or (not (match-beginning 5))
+ (< (point) (match-beginning 5))))))
+ ;; White spaces after an object or blank lines after an element
+ ;; are OK.
+ ((>= (point)
+ (save-excursion (goto-char (org-element-property :end context))
+ (skip-chars-backward " \r\t\n")
+ (if (eq (org-element-class context) 'object) (point)
+ (line-beginning-position 2)))))
+ ;; At the beginning of a footnote definition, right after the
+ ;; label, is OK.
+ ((eq type 'footnote-definition) (looking-at (rx space)))
+ ;; At the start of a list item is fine, as long as the bullet is
+ ;; unaffected.
+ ((eq type 'item)
+ (> (point) (+ (org-element-property :begin context)
+ (current-indentation)
+ (if (org-element-property :checkbox context)
+ 5 1))))
+ ;; Other elements are invalid.
+ ((eq (org-element-class context) 'element) nil)
+ ;; Just before object is fine.
+ ((= (point) (org-element-property :begin context)))
+ ;; Within recursive object too, but not in a link.
+ ((eq type 'link) nil)
+ ((eq type 'table-cell)
+ ;; :contents-begin is not reliable on empty cells, so special
+ ;; case it.
+ (<= (save-excursion (skip-chars-backward " \t") (point))
+ (org-element-property :contents-end context)))
+ ((let ((cbeg (org-element-property :contents-begin context))
+ (cend (org-element-property :contents-end context)))
+ (and cbeg (>= (point) cbeg) (<= (point) cend)))))))
+
+(defun org-cite--insert-string-before (string reference)
+ "Insert STRING before citation REFERENCE object."
+ (org-with-point-at (org-element-property :begin reference)
+ (insert string ";")))
+
+(defun org-cite--insert-string-after (string reference)
+ "Insert STRING after citation REFERENCE object."
+ (org-with-point-at (org-element-property :end reference)
+ ;; Make sure to move forward when we're inserting at point, so the
+ ;; insertion can happen multiple times.
+ (if (char-equal ?\; (char-before))
+ (insert-before-markers string ";")
+ (insert-before-markers ";" string))))
+
+(defun org-cite--keys-to-citation (keys)
+ "Build a citation object from a list of citation KEYS.
+Citation keys are strings without the leading \"@\"."
+ (apply #'org-element-create
+ 'citation
+ nil
+ (mapcar (lambda (k)
+ (org-element-create 'citation-reference (list :key k)))
+ keys)))
+
+(defun org-cite-make-insert-processor (select-key select-style)
+ "Build a function appropriate as an insert processor.
+
+SELECT-KEY is a function called with one argument. When it is nil, the function
+should return a citation key as a string, or nil. Otherwise, the function
+should return a list of such keys, or nil. The keys should not have any leading
+\"@\" character.
+
+SELECT-STYLE is a function called with one argument, the citation object being
+edited or constructed so far. It should return a style string, or nil.
+
+The return value is a function of two arguments: CONTEXT and ARG. CONTEXT is
+either a citation reference, a citation object, or nil. ARG is a prefix
+argument.
+
+The generated function inserts or edit a citation at point. More specifically,
+
+ On a citation reference:
+
+ - on the prefix or right before the \"@\" character, insert a new reference
+ before the current one,
+ - on the suffix, insert it after the reference,
+ - otherwise, update the cite key, preserving both affixes.
+
+ When ARG is non-nil, remove the reference, possibly removing the whole
+ citation if it contains a single reference.
+
+ On a citation object:
+
+ - on the style part, offer to update it,
+ - on the global prefix, add a new reference before the first one,
+ - on the global suffix, add a new reference after the last one,
+
+ Elsewhere, insert a citation at point. When ARG is non-nil, offer to complete
+ style in addition to references."
+ (unless (and (functionp select-key) (functionp select-style))
+ (error "Wrong argument type(s)"))
+ (lambda (context arg)
+ (pcase (org-element-type context)
+ ;; When on a citation, check point is not on the blanks after it.
+ ;; Otherwise, consider we're after it.
+ ((and 'citation
+ (guard
+ (let ((boundaries (org-cite-boundaries context)))
+ (and (< (point) (cdr boundaries))
+ (> (point) (car boundaries))))))
+ ;; When ARG is non-nil, delete the whole citation. Otherwise,
+ ;; action depends on the point.
+ (if arg
+ (org-cite-delete-citation context)
+ (let* ((begin (org-element-property :begin context))
+ (style-end (1- (org-with-point-at begin (search-forward ":")))))
+ (if (>= style-end (point))
+ ;; On style part, edit the style.
+ (let ((style-start (+ 5 begin))
+ (style (funcall select-style)))
+ (unless style (user-error "Aborted"))
+ (org-with-point-at style-start
+ (delete-region style-start style-end)
+ (when (org-string-nw-p style) (insert "/" style))))
+ ;; On an affix, insert a new reference before or after
+ ;; point.
+ (let* ((references (org-cite-get-references context))
+ (key (concat "@" (funcall select-key nil))))
+ (if (< (point) (org-element-property :contents-begin context))
+ (org-cite--insert-string-before key (car references))
+ (org-cite--insert-string-after key (org-last references))))))))
+ ;; On a citation reference. If ARG is not nil, remove the
+ ;; reference. Otherwise, action depends on the point.
+ ((and 'citation-reference (guard arg)) (org-cite-delete-citation context))
+ ('citation-reference
+ (pcase-let* ((`(,start . ,end) (org-cite-key-boundaries context))
+ (key (concat "@"
+ (or (funcall select-key nil)
+ (user-error "Aborted")))))
+ ;; Right before the "@" character, do not replace the reference
+ ;; at point, but insert a new one before it. It makes adding
+ ;; a new reference at the beginning easier in the following
+ ;; case: [cite:@key].
+ (cond
+ ((>= start (point)) (org-cite--insert-string-before key context))
+ ((<= end (point)) (org-cite--insert-string-after key context))
+ (t
+ (org-with-point-at start
+ (delete-region start end)
+ (insert key))))))
+ (_
+ (let ((keys (funcall select-key t)))
+ (unless keys (user-error "Aborted"))
+ (insert
+ (format "[cite%s:%s]"
+ (if arg
+ (let ((style (funcall select-style
+ (org-cite--keys-to-citation keys))))
+ (if (org-string-nw-p style)
+ (concat "/" style)
+ ""))
+ "")
+ (mapconcat (lambda (k) (concat "@" k)) keys "; "))))))))
+
+;;;###autoload
+(defun org-cite-insert (arg)
+ "Insert a citation at point.
+Insertion is done according to the processor set in `org-cite-insert-processor'.
+ARG is the prefix argument received when calling interactively the function."
+ (interactive "P")
+ (let ((name org-cite-insert-processor))
+ (cond
+ ((null name)
+ (user-error "No processor set to insert citations"))
+ ((not (org-cite--get-processor name))
+ (user-error "Unknown processor %S" name))
+ ((not (org-cite-processor-has-capability-p name 'insert))
+ (user-error "Processor %S cannot insert citations" name))
+ (t
+ (let ((context (org-element-context))
+ (insert (org-cite-processor-insert (org-cite--get-processor name))))
+ (cond
+ ((memq (org-element-type context) '(citation citation-reference))
+ (funcall insert context arg))
+ ((org-cite--allowed-p context)
+ (funcall insert nil arg))
+ (t
+ (user-error "Cannot insert a citation here"))))))))
+
+(provide 'oc)
+;;; oc.el ends here
diff --git a/lisp/org/ol-bbdb.el b/lisp/org/ol-bbdb.el
index 01a1fe93255..f697f1f82b9 100644
--- a/lisp/org/ol-bbdb.el
+++ b/lisp/org/ol-bbdb.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
-;; Authors: Carsten Dominik <carsten at orgmode dot org>
+;; Authors: Carsten Dominik <carsten.dominik@gmail.com>
;; Thomas Baumann <thomas dot baumann at ch dot tum dot de>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
@@ -60,7 +60,7 @@
;;
;; CLASS-OR-FORMAT-STRING is one of two things:
;;
-;; - an identifier for a class of anniversaries (eg. birthday or
+;; - an identifier for a class of anniversaries (e.g. birthday or
;; wedding) from `org-bbdb-anniversary-format-alist' which then
;; defines the format string for this class
;; - the (format) string displayed in the diary.
diff --git a/lisp/org/ol-bibtex.el b/lisp/org/ol-bibtex.el
index 6b591218c82..476095d3e08 100644
--- a/lisp/org/ol-bibtex.el
+++ b/lisp/org/ol-bibtex.el
@@ -88,7 +88,7 @@
;;
;; - All Bibtex information is taken from the document compiled by
;; Andrew Roberts from the Bibtex manual, available at
-;; http://www.andy-roberts.net/res/writing/latex/bibentries.pdf
+;; https://www.andy-roberts.net/res/writing/latex/bibentries.pdf
;;
;;; History:
;;
@@ -145,59 +145,59 @@
'((:article
(:description . "An article from a journal or magazine")
(:required :author :title :journal :year)
- (:optional :volume :number :pages :month :note))
+ (:optional :volume :number :pages :month :note :doi))
(:book
(:description . "A book with an explicit publisher")
(:required (:editor :author) :title :publisher :year)
- (:optional (:volume :number) :series :address :edition :month :note))
+ (:optional (:volume :number) :series :address :edition :month :note :doi))
(:booklet
(:description . "A work that is printed and bound, but without a named publisher or sponsoring institution.")
(:required :title)
- (:optional :author :howpublished :address :month :year :note))
+ (:optional :author :howpublished :address :month :year :note :doi :url))
(:conference
(:description . "")
(:required :author :title :booktitle :year)
- (:optional :editor :pages :organization :publisher :address :month :note))
+ (:optional :editor :pages :organization :publisher :address :month :note :doi :url))
(:inbook
(:description . "A part of a book, which may be a chapter (or section or whatever) and/or a range of pages.")
(:required (:author :editor) :title (:chapter :pages) :publisher :year)
- (:optional :crossref (:volume :number) :series :type :address :edition :month :note))
+ (:optional :crossref (:volume :number) :series :type :address :edition :month :note :doi))
(:incollection
(:description . "A part of a book having its own title.")
(:required :author :title :booktitle :publisher :year)
- (:optional :crossref :editor (:volume :number) :series :type :chapter :pages :address :edition :month :note))
+ (:optional :crossref :editor (:volume :number) :series :type :chapter :pages :address :edition :month :note :doi))
(:inproceedings
(:description . "An article in a conference proceedings")
(:required :author :title :booktitle :year)
- (:optional :crossref :editor (:volume :number) :series :pages :address :month :organization :publisher :note))
+ (:optional :crossref :editor (:volume :number) :series :pages :address :month :organization :publisher :note :doi))
(:manual
(:description . "Technical documentation.")
(:required :title)
- (:optional :author :organization :address :edition :month :year :note))
+ (:optional :author :organization :address :edition :month :year :note :doi :url))
(:mastersthesis
(:description . "A Master’s thesis.")
(:required :author :title :school :year)
- (:optional :type :address :month :note))
+ (:optional :type :address :month :note :doi :url))
(:misc
(:description . "Use this type when nothing else fits.")
(:required)
- (:optional :author :title :howpublished :month :year :note))
+ (:optional :author :title :howpublished :month :year :note :doi :url))
(:phdthesis
(:description . "A PhD thesis.")
(:required :author :title :school :year)
- (:optional :type :address :month :note))
+ (:optional :type :address :month :note :doi :url))
(:proceedings
(:description . "The proceedings of a conference.")
(:required :title :year)
- (:optional :editor (:volume :number) :series :address :month :organization :publisher :note))
+ (:optional :editor (:volume :number) :series :address :month :organization :publisher :note :doi))
(:techreport
(:description . "A report published by a school or other institution.")
(:required :author :title :institution :year)
- (:optional :type :address :month :note))
+ (:optional :type :address :month :note :doi :url))
(:unpublished
(:description . "A document having an author and title, but not formally published.")
(:required :author :title :note)
- (:optional :month :year)))
+ (:optional :month :year :doi :url)))
"Bibtex entry types with required and optional parameters.")
(defvar org-bibtex-fields
@@ -207,6 +207,7 @@
(:booktitle . "Title of a book, part of which is being cited. See the LaTeX book for how to type titles. For book entries, use the title field instead.")
(:chapter . "A chapter (or section or whatever) number.")
(:crossref . "The database key of the entry being cross referenced.")
+ (:doi . "The digital object identifier.")
(:edition . "The edition of a book for example, 'Second'. This should be an ordinal, and should have the first letter capitalized, as shown here; the standard styles convert to lower case when necessary.")
(:editor . "Name(s) of editor(s), typed as indicated in the LaTeX book. If there is also an author field, then the editor field gives the editor of the book or collection in which the reference appears.")
(:howpublished . "How something strange has been published. The first word should be capitalized.")
@@ -223,6 +224,7 @@
(:series . "The name of a series or set of books. When citing an entire book, the title field gives its title and an optional series field gives the name of a series or multi-volume set in which the book is published.")
(:title . "The work’s title, typed as explained in the LaTeX book.")
(:type . "The type of a technical report for example, 'Research Note'.")
+ (:url . "Uniform resource locator.")
(:volume . "The volume of a journal or multi-volume book.")
(:year . "The year of publication or, for an unpublished work, the year it was written. Generally it should consist of four numerals, such as 1984, although the standard styles can handle any year whose last four nonpunctuation characters are numerals, such as '(about 1984)'"))
"Bibtex fields with descriptions.")
@@ -507,6 +509,7 @@ ARG, when non-nil, is a universal prefix argument. See
(org-link-store-props
:key (cdr (assoc "=key=" entry))
:author (or (cdr (assoc "author" entry)) "[no author]")
+ :doi (or (cdr (assoc "doi" entry)) "[no doi]")
:editor (or (cdr (assoc "editor" entry)) "[no editor]")
:title (or (cdr (assoc "title" entry)) "[no title]")
:booktitle (or (cdr (assoc "booktitle" entry)) "[no booktitle]")
@@ -656,7 +659,7 @@ This uses `bibtex-parse-entry'."
(interactive)
(let ((keyword (lambda (str) (intern (concat ":" (downcase str)))))
(clean-space (lambda (str) (replace-regexp-in-string
- "[[:space:]\n\r]+" " " str)))
+ "[[:space:]\n\r]+" " " str)))
(strip-delim
(lambda (str) ; strip enclosing "..." and {...}
(dolist (pair '((34 . 34) (123 . 125)))
@@ -674,7 +677,8 @@ This uses `bibtex-parse-entry'."
(_ field)))
(funcall clean-space (funcall strip-delim (cdr pair)))))
(save-excursion (bibtex-beginning-of-entry) (bibtex-parse-entry)))
- org-bibtex-entries)))
+ org-bibtex-entries)
+ (unless (car org-bibtex-entries) (pop org-bibtex-entries))))
(defun org-bibtex-read-buffer (buffer)
"Read all bibtex entries in BUFFER and save to `org-bibtex-entries'.
diff --git a/lisp/org/ol-doi.el b/lisp/org/ol-doi.el
new file mode 100644
index 00000000000..d2d16b27d51
--- /dev/null
+++ b/lisp/org/ol-doi.el
@@ -0,0 +1,72 @@
+;;; ol-doi.el --- DOI links support in Org -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
+
+;; 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 introduces the "doi" link type in Org, and provides
+;; code for opening and exporting such links.
+
+;;; Code:
+
+(require 'ol)
+
+(defcustom org-link-doi-server-url "https://doi.org/"
+ "The URL of the DOI server."
+ :group 'org-link-follow
+ :version "24.3"
+ :type 'string
+ :safe #'stringp)
+
+(defun org-link-doi-open (path arg)
+ "Open a \"doi\" type link.
+PATH is a the path to search for, as a string."
+ (browse-url (url-encode-url (concat org-link-doi-server-url path)) arg))
+
+(defun org-link-doi-export (path desc backend info)
+ "Export a \"doi\" type link.
+PATH is the DOI name. DESC is the description of the link, or
+nil. BACKEND is a symbol representing the backend used for
+export. INFO is a a plist containing the export parameters."
+ (let ((uri (concat org-link-doi-server-url path)))
+ (pcase backend
+ (`html
+ (format "<a href=\"%s\">%s</a>" uri (or desc uri)))
+ (`latex
+ (if desc (format "\\href{%s}{%s}" uri desc)
+ (format "\\url{%s}" uri)))
+ (`ascii
+ (if (not desc) (format "<%s>" uri)
+ (concat (format "[%s]" desc)
+ (and (not (plist-get info :ascii-links-to-notes))
+ (format " (<%s>)" uri)))))
+ (`texinfo
+ (if (not desc) (format "@uref{%s}" uri)
+ (format "@uref{%s, %s}" uri desc)))
+ (_ uri))))
+
+(org-link-set-parameters "doi"
+ :follow #'org-link-doi-open
+ :export #'org-link-doi-export)
+
+
+(provide 'org-link-doi)
+(provide 'ol-doi)
+;;; ol-doi.el ends here
diff --git a/lisp/org/ol-eshell.el b/lisp/org/ol-eshell.el
index 8920e0afb0d..a7550e3769b 100644
--- a/lisp/org/ol-eshell.el
+++ b/lisp/org/ol-eshell.el
@@ -35,9 +35,9 @@
(defun org-eshell-open (link _)
"Switch to an eshell buffer and execute a command line.
- The link can be just a command line (executed in the default
- eshell buffer) or a command line prefixed by a buffer name
- followed by a colon."
+The link can be just a command line (executed in the default
+eshell buffer) or a command line prefixed by a buffer name
+followed by a colon."
(let* ((buffer-and-command
(if (string-match "\\([A-Za-z0-9+*-]+\\):\\(.*\\)" link)
(list (match-string 1 link)
@@ -55,7 +55,7 @@
(defun org-eshell-store-link ()
"Store a link that, when opened, switches back to the current eshell buffer
- and the current working directory."
+and the current working directory."
(when (eq major-mode 'eshell-mode)
(let* ((command (concat "cd " (eshell/pwd)))
(link (concat (buffer-name) ":" command)))
diff --git a/lisp/org/ol-gnus.el b/lisp/org/ol-gnus.el
index 2d51447e0c4..72bdd7310a9 100644
--- a/lisp/org/ol-gnus.el
+++ b/lisp/org/ol-gnus.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Tassilo Horn <tassilo at member dot fsf dot org>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
@@ -194,7 +194,7 @@ If `org-store-link' was called with a prefix arg the meaning of
(message-tokenize-header
(mail-fetch-field "gcc" nil t) " ,"))))
(id (org-unbracket-string "<" ">"
- (mail-fetch-field "Message-ID")))
+ (mail-fetch-field "Message-ID")))
(to (mail-fetch-field "To"))
(from (mail-fetch-field "From"))
(subject (mail-fetch-field "Subject"))
diff --git a/lisp/org/ol-info.el b/lisp/org/ol-info.el
index 8b1e5da5168..a535ea581a3 100644
--- a/lisp/org/ol-info.el
+++ b/lisp/org/ol-info.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
@@ -56,7 +56,7 @@
"#" Info-current-node)))
(org-link-store-props :type "info" :file Info-current-file
:node Info-current-node
- :link link :desc desc)
+ :link link :description desc)
link)))
(defun org-info-open (path _)
@@ -91,7 +91,7 @@
"pgg" "rcirc" "reftex" "remember" "sasl" "sc" "semantic" "ses" "sieve"
"smtpmail" "speedbar" "srecode" "todo-mode" "tramp" "url" "vip" "viper"
"widget" "wisent" "woman")
- "List of emacs documents available.
+ "List of Emacs documents available.
Taken from <https://www.gnu.org/software/emacs/manual/html_mono/.>")
(defconst org-info-other-documents
diff --git a/lisp/org/ol-man.el b/lisp/org/ol-man.el
new file mode 100644
index 00000000000..0d9ac7c8c71
--- /dev/null
+++ b/lisp/org/ol-man.el
@@ -0,0 +1,86 @@
+;;; ol-man.el --- Links to man pages -*- lexical-binding: t; -*-
+;;
+;; Copyright (C) 2020-2021 Free Software Foundation, Inc.
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
+;; Maintainer: Bastien Guerry <bzg@gnu.org>
+;; Keywords: outlines, hypermedia, calendar, wp
+;; Homepage: https://orgmode.org
+;;
+;; This file is part of GNU Emacs.
+;;
+;; 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, 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+
+(require 'ol)
+
+(org-link-set-parameters "man"
+ :follow #'org-man-open
+ :export #'org-man-export
+ :store #'org-man-store-link)
+
+(defcustom org-man-command 'man
+ "The Emacs command to be used to display a man page."
+ :group 'org-link
+ :type '(choice (const man) (const woman)))
+
+(defun org-man-open (path _)
+ "Visit the manpage on PATH.
+PATH should be a topic that can be thrown at the man command.
+If PATH contains extra ::STRING which will use `occur' to search
+matched strings in man buffer."
+ (string-match "\\(.*?\\)\\(?:::\\(.*\\)\\)?$" path)
+ (let* ((command (match-string 1 path))
+ (search (match-string 2 path)))
+ (funcall org-man-command command)
+ (when search
+ (with-current-buffer (concat "*Man " command "*")
+ (goto-char (point-min))
+ (search-forward search)))))
+
+(defun org-man-store-link ()
+ "Store a link to a README file."
+ (when (memq major-mode '(Man-mode woman-mode))
+ ;; This is a man page, we do make this link
+ (let* ((page (org-man-get-page-name))
+ (link (concat "man:" page))
+ (description (format "Manpage for %s" page)))
+ (org-link-store-props
+ :type "man"
+ :link link
+ :description description))))
+
+(defun org-man-get-page-name ()
+ "Extract the page name from the buffer name."
+ ;; This works for both `Man-mode' and `woman-mode'.
+ (if (string-match " \\(\\S-+\\)\\*" (buffer-name))
+ (match-string 1 (buffer-name))
+ (error "Cannot create link to this man page")))
+
+(defun org-man-export (link description format)
+ "Export a man page link from Org files."
+ (let ((path (format "http://man.he.net/?topic=%s&section=all" link))
+ (desc (or description link)))
+ (cond
+ ((eq format 'html) (format "<a target=\"_blank\" href=\"%s\">%s</a>" path desc))
+ ((eq format 'latex) (format "\\href{%s}{%s}" path desc))
+ ((eq format 'texinfo) (format "@uref{%s,%s}" path desc))
+ ((eq format 'ascii) (format "%s (%s)" desc path))
+ ((eq format 'md) (format "[%s](%s)" desc path))
+ (t path))))
+
+(provide 'ol-man)
+
+;;; ol-man.el ends here
diff --git a/lisp/org/ol-rmail.el b/lisp/org/ol-rmail.el
index a73060b50fa..2593ebdf02e 100644
--- a/lisp/org/ol-rmail.el
+++ b/lisp/org/ol-rmail.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
diff --git a/lisp/org/ol-w3m.el b/lisp/org/ol-w3m.el
index ebb11ce3d54..9e03269e114 100644
--- a/lisp/org/ol-w3m.el
+++ b/lisp/org/ol-w3m.el
@@ -82,26 +82,41 @@ so that it can be yanked into an Org buffer with links working correctly."
(setq temp-position (point))
;; move to next anchor when current point is not at anchor
(or (get-text-property (point) 'w3m-href-anchor) (org-w3m-get-next-link-start))
- (if (<= (point) transform-end) ; if point is inside transform bound
- (progn
- ;; get content between two links.
- (when (> (point) temp-position)
- (setq return-content (concat return-content
- (buffer-substring
- temp-position (point)))))
- ;; get link location at current point.
- (setq link-location (get-text-property (point) 'w3m-href-anchor))
- ;; get link title at current point.
- (setq link-title (buffer-substring (point)
- (org-w3m-get-anchor-end)))
- ;; concat Org style url to `return-content'.
- (setq return-content
- (concat return-content
- (if (org-string-nw-p link-location)
- (org-link-make-string link-location link-title)
- link-title))))
+ (cond
+ ((<= (point) transform-end) ; point is inside transform bound
+ ;; get content between two links.
+ (when (> (point) temp-position)
+ (setq return-content (concat return-content
+ (buffer-substring
+ temp-position (point)))))
+ (cond
+ ((setq link-location (get-text-property (point) 'w3m-href-anchor))
+ ;; current point is a link
+ ;; (we thus also got link location at current point)
+ ;; get link title at current point.
+ (setq link-title (buffer-substring (point)
+ (org-w3m-get-anchor-end)))
+ ;; concat Org style url to `return-content'.
+ (setq return-content
+ (concat return-content
+ (if (org-string-nw-p link-location)
+ (org-link-make-string link-location link-title)
+ link-title))))
+ ((setq link-location (get-text-property (point) 'w3m-image))
+ ;; current point is an image
+ ;; (we thus also got image link location at current point)
+ ;; get link title at current point.
+ (setq link-title (buffer-substring (point) (org-w3m-get-image-end)))
+ ;; concat Org style url to `return-content'.
+ (setq return-content
+ (concat return-content
+ (if (org-string-nw-p link-location)
+ (org-link-make-string link-location link-title)
+ link-title))))
+ (t nil))); current point is neither a link nor an image
+ (t ; point is NOT inside transform bound
(goto-char temp-position) ; reset point before jump next anchor
- (setq out-bound t))) ; for break out `while' loop
+ (setq out-bound t)))) ; for break out `while' loop
;; add the rest until end of the region to be copied
(when (< (point) transform-end)
(setq return-content
@@ -114,6 +129,7 @@ so that it can be yanked into an Org buffer with links working correctly."
(defun org-w3m-get-anchor-start ()
"Move cursor to the start of current anchor. Return point."
;; get start position of anchor or current point
+ ;; NOTE: This function seems never to be used. Should it be removed?
(goto-char (or (previous-single-property-change (point) 'w3m-anchor-sequence)
(point))))
@@ -123,26 +139,46 @@ so that it can be yanked into an Org buffer with links working correctly."
(goto-char (or (next-single-property-change (point) 'w3m-anchor-sequence)
(point))))
+(defun org-w3m-get-image-end ()
+ "Move cursor to the end of current image. Return point."
+ ;; get end position of image or point
+ ;; NOTE: Function `org-w3m-get-image-start' was not created because
+ ;; function `org-w3m-get-anchor-start' is never used.
+ (goto-char (or (next-single-property-change (point) 'w3m-image)
+ (point))))
+
(defun org-w3m-get-next-link-start ()
- "Move cursor to the start of next link. Return point."
- (catch 'reach
- (while (next-single-property-change (point) 'w3m-anchor-sequence)
- ;; jump to next anchor
- (goto-char (next-single-property-change (point) 'w3m-anchor-sequence))
- (when (get-text-property (point) 'w3m-href-anchor)
- ;; return point when current is valid link
- (throw 'reach nil))))
- (point))
+ "Move cursor to the start of next link or image. Return point."
+ (let (pos start-pos anchor-pos image-pos)
+ (setq pos (setq start-pos (point)))
+ (setq anchor-pos
+ (catch 'reach
+ (while (setq pos (next-single-property-change pos 'w3m-anchor-sequence))
+ (when (get-text-property pos 'w3m-href-anchor)
+ (throw 'reach pos)))))
+ (setq pos start-pos)
+ (setq image-pos
+ (catch 'reach
+ (while (setq pos (next-single-property-change pos 'w3m-image))
+ (when (get-text-property pos 'w3m-image)
+ (throw 'reach pos)))))
+ (goto-char (min (or anchor-pos (point-max)) (or image-pos (point-max))))))
(defun org-w3m-get-prev-link-start ()
"Move cursor to the start of previous link. Return point."
+ ;; NOTE: This function is only called by `org-w3m-no-prev-link-p',
+ ;; which itself seems never to be used. Should it be removed?
+ ;;
+ ;; WARNING: This function has not been updated to account for
+ ;; `w3m-image'. See `org-w3m-get-next-link-start'.
(catch 'reach
- (while (previous-single-property-change (point) 'w3m-anchor-sequence)
- ;; jump to previous anchor
- (goto-char (previous-single-property-change (point) 'w3m-anchor-sequence))
- (when (get-text-property (point) 'w3m-href-anchor)
- ;; return point when current is valid link
- (throw 'reach nil))))
+ (let ((pos (point)))
+ (while (setq pos (previous-single-property-change pos 'w3m-anchor-sequence))
+ (when (get-text-property pos 'w3m-href-anchor)
+ ;; jump to previous anchor
+ (goto-char pos)
+ ;; return point when current is valid link
+ (throw 'reach nil)))))
(point))
(defun org-w3m-no-next-link-p ()
@@ -154,6 +190,7 @@ Return t if there is no next link; otherwise, return nil."
(defun org-w3m-no-prev-link-p ()
"Whether there is no previous link after the cursor.
Return t if there is no previous link; otherwise, return nil."
+ ;; NOTE: This function seems never to be used. Should it be removed?
(save-excursion
(equal (point) (org-w3m-get-prev-link-start))))
diff --git a/lisp/org/ol.el b/lisp/org/ol.el
index 38e2dd6a02c..b70f1996d54 100644
--- a/lisp/org/ol.el
+++ b/lisp/org/ol.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2018-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; This file is part of GNU Emacs.
@@ -178,8 +178,7 @@ link.
:group 'org-link
:package-version '(Org . "9.1")
:type '(alist :tag "Link display parameters"
- :value-type plist)
- :safe nil)
+ :value-type plist))
(defcustom org-link-descriptive t
"Non-nil means Org displays descriptive links.
@@ -214,13 +213,18 @@ relative Relative to the current directory, i.e. the directory of the file
absolute Absolute path, if possible with ~ for home directory.
noabbrev Absolute path, no abbreviation of home directory.
adaptive Use relative path for files in the current directory and sub-
- directories of it. For other files, use an absolute path."
+ directories of it. For other files, use an absolute path.
+
+Alternatively, users may supply a custom function that takes the
+full filename as an argument and returns the path."
:group 'org-link
:type '(choice
(const relative)
(const absolute)
(const noabbrev)
- (const adaptive))
+ (const adaptive)
+ (function))
+ :package-version '(Org . "9.5")
:safe #'symbolp)
(defcustom org-link-abbrev-alist nil
@@ -277,13 +281,6 @@ links created by planner."
:type '(choice (const nil) (function))
:safe #'null)
-(defcustom org-link-doi-server-url "https://doi.org/"
- "The URL of the DOI server."
- :group 'org-link-follow
- :version "24.3"
- :type 'string
- :safe #'stringp)
-
(defcustom org-link-frame-setup
'((vm . vm-visit-folder-other-frame)
(vm-imap . vm-visit-imap-folder-other-frame)
@@ -337,8 +334,7 @@ another window."
(cons (const wl)
(choice
(const wl)
- (const wl-other-frame))))
- :safe nil)
+ (const wl-other-frame)))))
(defcustom org-link-search-must-match-exact-headline 'query-to-create
"Non-nil means internal fuzzy links can only match headlines.
@@ -387,15 +383,13 @@ single keystroke rather than having to type \"yes\"."
:type '(choice
(const :tag "with yes-or-no (safer)" yes-or-no-p)
(const :tag "with y-or-n (faster)" y-or-n-p)
- (const :tag "no confirmation (dangerous)" nil))
- :safe nil)
+ (const :tag "no confirmation (dangerous)" nil)))
(defcustom org-link-shell-skip-confirm-regexp ""
"Regexp to skip confirmation for shell links."
:group 'org-link-follow
:version "24.1"
- :type 'regexp
- :safe nil)
+ :type 'regexp)
(defcustom org-link-elisp-confirm-function 'yes-or-no-p
"Non-nil means ask for confirmation before executing Emacs Lisp links.
@@ -412,15 +406,13 @@ single keystroke rather than having to type \"yes\"."
:type '(choice
(const :tag "with yes-or-no (safer)" yes-or-no-p)
(const :tag "with y-or-n (faster)" y-or-n-p)
- (const :tag "no confirmation (dangerous)" nil))
- :safe nil)
+ (const :tag "no confirmation (dangerous)" nil)))
(defcustom org-link-elisp-skip-confirm-regexp ""
"A regexp to skip confirmation for Elisp links."
:group 'org-link-follow
:version "24.1"
- :type 'regexp
- :safe nil)
+ :type 'regexp)
(defgroup org-link-store nil
"Options concerning storing links in Org mode."
@@ -444,7 +436,7 @@ negates this setting for the duration of the command."
:safe (lambda (val) (or (booleanp val) (integerp val))))
(defcustom org-link-email-description-format "Email %c: %s"
- "Format of the description part of a link to an email or usenet message.
+ "Format of the description part of a link to an email or Usenet message.
The following %-escapes will be replaced by corresponding information:
%F full \"From\" field
@@ -508,13 +500,16 @@ links more efficient."
"Regular expression matching radio targets in plain text.")
(defvar org-link-types-re nil
- "Matches a link that has a url-like prefix like \"http:\"")
+ "Matches a link that has a url-like prefix like \"http:\".")
(defvar org-link-angle-re nil
"Matches link with angular brackets, spaces are allowed.")
(defvar org-link-plain-re nil
- "Matches plain link, without spaces.")
+ "Matches plain link, without spaces.
+Group 1 must contain the link type (i.e. https).
+Group 2 must contain the link path (i.e. //example.com).
+Used by `org-element-link-parser'.")
(defvar org-link-bracket-re nil
"Matches a link in double brackets.")
@@ -802,15 +797,33 @@ This should be called after the variable `org-link-parameters' has changed."
(format "<%s:\\([^>\n]*\\(?:\n[ \t]*[^> \t\n][^>\n]*\\)*\\)>"
types-re)
org-link-plain-re
- (concat
- "\\<" types-re ":"
- "\\([^][ \t\n()<>]+\\(?:([[:word:]0-9_]+)\\|\\([^[:punct:] \t\n]\\|/\\)\\)\\)")
- ;; "\\([^]\t\n\r<>() ]+[^]\t\n\r<>,.;() ]\\)")
- org-link-bracket-re
- (rx (seq "[["
- ;; URI part: match group 1.
- (group
- (one-or-more
+ (let* ((non-space-bracket "[^][ \t\n()<>]")
+ (parenthesis
+ `(seq "("
+ (0+ (or (regex ,non-space-bracket)
+ (seq "("
+ (0+ (regex ,non-space-bracket))
+ ")")))
+ ")")))
+ ;; Heuristics for an URL link inspired by
+ ;; https://daringfireball.net/2010/07/improved_regex_for_matching_urls
+ (rx-to-string
+ `(seq word-start
+ ;; Link type: match group 1.
+ (regexp ,types-re)
+ ":"
+ ;; Link path: match group 2.
+ (group
+ (1+ (or (regex ,non-space-bracket)
+ ,parenthesis))
+ (or (regexp "[^[:punct:] \t\n]")
+ ?/
+ ,parenthesis)))))
+ org-link-bracket-re
+ (rx (seq "[["
+ ;; URI part: match group 1.
+ (group
+ (one-or-more
(or (not (any "[]\\"))
(and "\\" (zero-or-more "\\\\") (any "[]"))
(and (one-or-more "\\") (not (any "[]"))))))
@@ -910,7 +923,7 @@ and dates."
(defun org-link-encode (text table)
"Return percent escaped representation of string TEXT.
-TEXT is a string with the text to escape. TABLE is a list of
+TEXT is a string with the text to escape. TABLE is a list of
characters that should be escaped."
(mapconcat
(lambda (c)
@@ -1301,14 +1314,6 @@ If there is no description, use the link target."
;;; Built-in link types
-;;;; "doi" link type
-(defun org-link--open-doi (path arg)
- "Open a \"doi\" type link.
-PATH is a the path to search for, as a string."
- (browse-url (url-encode-url (concat org-link-doi-server-url path)) arg))
-
-(org-link-set-parameters "doi" :follow #'org-link--open-doi)
-
;;;; "elisp" link type
(defun org-link--open-elisp (path _)
"Open a \"elisp\" type link.
@@ -1335,11 +1340,27 @@ PATH is the sexp to evaluate, as a string."
"Open a \"help\" type link.
PATH is a symbol name, as a string."
(pcase (intern path)
- ((and (pred fboundp) variable) (describe-function variable))
- ((and (pred boundp) function) (describe-variable function))
+ ((and (pred fboundp) function) (describe-function function))
+ ((and (pred boundp) variable) (describe-variable variable))
(name (user-error "Unknown function or variable: %s" name))))
-(org-link-set-parameters "help" :follow #'org-link--open-help)
+(defun org-link--store-help ()
+ "Store \"help\" type link."
+ (when (eq major-mode 'help-mode)
+ (let ((symbol
+ (save-excursion
+ (goto-char (point-min))
+ ;; In case the help is about the key-binding, store the
+ ;; function instead.
+ (search-forward "runs the command " (line-end-position) t)
+ (read (current-buffer)))))
+ (org-link-store-props :type "help"
+ :link (format "help:%s" symbol)
+ :description nil))))
+
+(org-link-set-parameters "help"
+ :follow #'org-link--open-help
+ :store #'org-link--store-help)
;;;; "http", "https", "mailto", "ftp", and "news" link types
(dolist (scheme '("ftp" "http" "https" "mailto" "news"))
@@ -1491,14 +1512,17 @@ non-nil."
(apply #'org-link-store-props
(cdr (assoc-string
(completing-read
- "Which function for creating the link? "
- (mapcar #'car results-alist)
- nil t (symbol-name name))
+ (format "Store link with (default %s): " name)
+ (mapcar #'car results-alist)
+ nil t nil nil (symbol-name name))
results-alist)))
t))))
(setq link (plist-get org-store-link-plist :link))
- (setq desc (or (plist-get org-store-link-plist :description)
- link)))
+ ;; If store function actually set `:description' property, use
+ ;; it, even if it is nil. Otherwise, fallback to link value.
+ (setq desc (if (plist-member org-store-link-plist :description)
+ (plist-get org-store-link-plist :description)
+ link)))
;; Store a link from a remote editing buffer.
((org-src-edit-buffer-p)
@@ -1551,24 +1575,11 @@ non-nil."
(setq link
(format-time-string
(car org-time-stamp-formats)
- (apply 'encode-time
+ (encode-time
(list 0 0 0 (nth 1 cd) (nth 0 cd) (nth 2 cd)
nil nil nil))))
(org-link-store-props :type "calendar" :date cd)))
- ((eq major-mode 'help-mode)
- (let ((symbol (replace-regexp-in-string
- ;; Help mode escapes backquotes and backslashes
- ;; before displaying them. E.g., "`" appears
- ;; as "\'" for reasons. Work around this.
- (rx "\\" (group (or "`" "\\"))) "\\1"
- (save-excursion
- (goto-char (point-min))
- (looking-at "^[^ ]+")
- (match-string 0)))))
- (setq link (concat "help:" symbol)))
- (org-link-store-props :type "help"))
-
((eq major-mode 'w3-mode)
(setq cpltxt (if (and (buffer-name)
(not (string-match "Untitled" (buffer-name))))
@@ -1602,9 +1613,8 @@ non-nil."
((and (buffer-file-name (buffer-base-buffer)) (derived-mode-p 'org-mode))
(org-with-limited-levels
- (setq custom-id (org-entry-get nil "CUSTOM_ID"))
- (cond
- ;; Store a link using the target at point
+ (cond
+ ;; Store a link using the target at point.
((org-in-regexp "[^<]<<\\([^<>]+\\)>>[^>]" 1)
(setq cpltxt
(concat "file:"
@@ -1612,6 +1622,15 @@ non-nil."
(buffer-file-name (buffer-base-buffer)))
"::" (match-string 1))
link cpltxt))
+ ;; Store a link using the CUSTOM_ID property.
+ ((setq custom-id (org-entry-get nil "CUSTOM_ID"))
+ (setq cpltxt
+ (concat "file:"
+ (abbreviate-file-name
+ (buffer-file-name (buffer-base-buffer)))
+ "::#" custom-id)
+ link cpltxt))
+ ;; Store a link using (and perhaps creating) the ID property.
((and (featurep 'org-id)
(or (eq org-id-link-to-org-use-id t)
(and interactive?
@@ -1620,14 +1639,13 @@ non-nil."
'create-if-interactive-and-no-custom-id)
(not custom-id))))
(and org-id-link-to-org-use-id (org-entry-get nil "ID"))))
- ;; Store a link using the ID at point
(setq link (condition-case nil
(prog1 (org-id-store-link)
(setq desc (or (plist-get org-store-link-plist
:description)
"")))
(error
- ;; Probably before first headline, link only to file
+ ;; Probably before first headline, link only to file.
(concat "file:"
(abbreviate-file-name
(buffer-file-name (buffer-base-buffer))))))))
@@ -1696,7 +1714,7 @@ non-nil."
(if (not (and interactive? link))
(or agenda-link (and link (org-link-make-string link desc)))
(if (member (list link desc) org-stored-links)
- (message "This link already exists")
+ (message "This link has already been stored")
(push (list link desc) org-stored-links)
(message "Stored: %s" (or desc link))
(when custom-id
@@ -1791,12 +1809,13 @@ Use TAB to complete link prefixes, then RET for type-specific completion support
(reverse org-stored-links)
"\n")))
(goto-char (point-min)))
- (let ((cw (selected-window)))
- (select-window (get-buffer-window "*Org Links*" 'visible))
- (with-current-buffer "*Org Links*" (setq truncate-lines t))
- (unless (pos-visible-in-window-p (point-max))
- (org-fit-window-to-buffer))
- (and (window-live-p cw) (select-window cw)))
+ (when (get-buffer-window "*Org Links*" 'visible)
+ (let ((cw (selected-window)))
+ (select-window (get-buffer-window "*Org Links*" 'visible))
+ (with-current-buffer "*Org Links*" (setq truncate-lines t))
+ (unless (pos-visible-in-window-p (point-max))
+ (org-fit-window-to-buffer))
+ (and (window-live-p cw) (select-window cw))))
(setq all-prefixes (append (mapcar #'car abbrevs)
(mapcar #'car org-link-abbrev-alist)
(org-link-types)))
@@ -1877,6 +1896,9 @@ Use TAB to complete link prefixes, then RET for type-specific completion support
(setq path (expand-file-name path)))
((eq org-link-file-path-type 'relative)
(setq path (file-relative-name path)))
+ ((functionp org-link-file-path-type)
+ (setq path (funcall org-link-file-path-type
+ (expand-file-name path))))
(t
(save-match-data
(if (string-match (concat "^" (regexp-quote
diff --git a/lisp/org/org-agenda.el b/lisp/org/org-agenda.el
index 3acc18715dd..354f408679c 100644
--- a/lisp/org/org-agenda.el
+++ b/lisp/org/org-agenda.el
@@ -1,8 +1,8 @@
-;;; org-agenda.el --- Dynamic task and appointment lists for Org
+;;; org-agenda.el --- Dynamic task and appointment lists for Org -*- lexical-binding: t; -*-
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
@@ -99,8 +99,8 @@
(defvar org-agenda-buffer-name "*Org Agenda*")
(defvar org-agenda-overriding-header nil)
(defvar org-agenda-title-append nil)
-(with-no-warnings (defvar entry)) ;; unprefixed, from calendar.el
-(with-no-warnings (defvar date)) ;; unprefixed, from calendar.el
+;; (with-no-warnings (defvar entry)) ;; unprefixed, from calendar.el
+;; (with-no-warnings (defvar date)) ;; unprefixed, from calendar.el
(defvar original-date) ; dynamically scoped, calendar.el does scope this
(defvar org-agenda-undo-list nil
@@ -148,6 +148,8 @@ addresses the separator between the current and the previous block."
:type 'boolean)
(defcustom org-agenda-exporter-settings nil
+ ;; FIXME: Do we really want to evaluate those settings and thus force
+ ;; the user to use `quote' all the time?
"Alist of variable/value pairs that should be active during agenda export.
This is a good place to set options for ps-print and for htmlize.
Note that the way this is implemented, the values will be evaluated
@@ -1188,11 +1190,11 @@ This function makes sure that dates are aligned for easy reading."
(year (nth 2 date))
(iso-week (org-days-to-iso-week
(calendar-absolute-from-gregorian date)))
- (weekyear (cond ((and (= month 1) (>= iso-week 52))
- (1- year))
- ((and (= month 12) (<= iso-week 1))
- (1+ year))
- (t year)))
+ ;; (weekyear (cond ((and (= month 1) (>= iso-week 52))
+ ;; (1- year))
+ ;; ((and (= month 12) (<= iso-week 1))
+ ;; (1+ year))
+ ;; (t year)))
(weekstring (if (= day-of-week 1)
(format " W%02d" iso-week)
"")))
@@ -1230,7 +1232,8 @@ For example, 9:30am would become 09:30 rather than 9:30."
":" minute ampm)))
(defun org-agenda-time-of-day-to-ampm-maybe (time)
- "Conditionally convert TIME to AM/PM format based on `org-agenda-timegrid-use-ampm'."
+ "Conditionally convert TIME to AM/PM format.
+This is based on `org-agenda-timegrid-use-ampm'."
(if org-agenda-timegrid-use-ampm
(org-agenda-time-of-day-to-ampm time)
time))
@@ -2080,9 +2083,25 @@ For example, this value makes those two functions available:
With selected entries in an agenda buffer, `B R' will call
the custom function `set-category' on the selected entries.
-Note that functions in this alist don't need to be quoted."
- :type '(alist :key-type character :value-type (group function))
- :version "24.1"
+Note that functions in this alist don't need to be quoted.
+
+You can also specify a function which collects arguments to be
+used for each call to your bulk custom function. The argument
+collecting function will be run once and should return a list of
+arguments to pass to the bulk function. For example:
+
+ \\='((?R set-category get-category))
+
+Now, `B R' will call the custom `get-category' which would prompt
+the user once for a category. That category is then passed as an
+argument to `set-category' for each entry it's called against."
+ :type
+ '(alist :key-type character
+ :value-type
+ (group (function :tag "Bulk Custom Function")
+ (choice (function :tag "Bulk Custom Argument Function")
+ (const :tag "No Bulk Custom Argument Function" nil))))
+ :package-version '(Org . "9.5")
:group 'org-agenda)
(defmacro org-agenda-with-point-at-orig-entry (string &rest body)
@@ -2113,7 +2132,8 @@ works you probably want to add it to `org-agenda-custom-commands' for good."
The inserted header depends on `org-agenda-overriding-header'.
If the empty string, don't insert a header. If any other string,
insert it as a header. If nil, insert DEFAULT, which should
-evaluate to a string."
+evaluate to a string. If a function, call it and insert the
+string that it returns."
(declare (debug (form)) (indent defun))
`(cond
((not org-agenda-overriding-header) (insert ,default))
@@ -2122,6 +2142,8 @@ evaluate to a string."
(insert (propertize org-agenda-overriding-header
'face 'org-agenda-structure)
"\n"))
+ ((functionp org-agenda-overriding-header)
+ (insert (funcall org-agenda-overriding-header)))
(t (user-error "Invalid value for `org-agenda-overriding-header': %S"
org-agenda-overriding-header))))
@@ -2238,26 +2260,26 @@ The following commands are available:
(save (buffer-local-variables)))
(kill-all-local-variables)
(cl-flet ((reset-saved (var-set)
- "Reset variables in VAR-SET to possibly stored value in SAVE."
- (dolist (elem save)
- (pcase elem
- (`(,var . ,val) ;ignore unbound variables
- (when (and val (memq var var-set))
- (set var val)))))))
+ "Reset variables in VAR-SET to possibly stored value in SAVE."
+ (dolist (elem save)
+ (pcase elem
+ (`(,var . ,val) ;ignore unbound variables
+ (when (and val (memq var var-set))
+ (set var val)))))))
(cond (org-agenda-doing-sticky-redo
- ;; Refreshing sticky agenda-buffer
- ;;
- ;; Preserve the value of `org-agenda-local-vars' variables.
- (mapc #'make-local-variable org-agenda-local-vars)
- (reset-saved org-agenda-local-vars)
- (setq-local org-agenda-this-buffer-is-sticky t))
+ ;; Refreshing sticky agenda-buffer
+ ;;
+ ;; Preserve the value of `org-agenda-local-vars' variables.
+ (mapc #'make-local-variable org-agenda-local-vars)
+ (reset-saved org-agenda-local-vars)
+ (setq-local org-agenda-this-buffer-is-sticky t))
(org-agenda-sticky
- ;; Creating a sticky Agenda buffer for the first time
- (mapc 'make-local-variable org-agenda-local-vars)
- (setq-local org-agenda-this-buffer-is-sticky t))
+ ;; Creating a sticky Agenda buffer for the first time
+ (mapc #'make-local-variable org-agenda-local-vars)
+ (setq-local org-agenda-this-buffer-is-sticky t))
(t
- ;; Creating a non-sticky agenda buffer
- (setq-local org-agenda-this-buffer-is-sticky nil)))
+ ;; Creating a non-sticky agenda buffer
+ (setq-local org-agenda-this-buffer-is-sticky nil)))
(mapc #'make-local-variable agenda-local-vars-to-keep)
(reset-saved agenda-local-vars-to-keep)))
(setq org-agenda-undo-list nil
@@ -2271,8 +2293,8 @@ The following commands are available:
(use-local-map org-agenda-mode-map)
(when org-startup-truncated (setq truncate-lines t))
(setq-local line-move-visual nil)
- (add-hook 'post-command-hook 'org-agenda-update-agenda-type nil 'local)
- (add-hook 'pre-command-hook 'org-unhighlight nil 'local)
+ (add-hook 'post-command-hook #'org-agenda-update-agenda-type nil 'local)
+ (add-hook 'pre-command-hook #'org-unhighlight nil 'local)
;; Make sure properties are removed when copying text
(if (boundp 'filter-buffer-substring-functions)
(add-hook 'filter-buffer-substring-functions
@@ -2300,11 +2322,9 @@ The following commands are available:
'(org-edit-agenda-file-list)
(not (get 'org-agenda-files 'org-restrict)))
"--")
- (mapcar 'org-file-menu-entry (org-agenda-files))))
+ (mapcar #'org-file-menu-entry (org-agenda-files))))
(org-agenda-set-mode-name)
- (apply
- (if (fboundp 'run-mode-hooks) 'run-mode-hooks 'run-hooks)
- (list 'org-agenda-mode-hook)))
+ (run-mode-hooks 'org-agenda-mode-hook))
(substitute-key-definition #'undo #'org-agenda-undo
org-agenda-mode-map global-map)
@@ -2452,7 +2472,7 @@ The following commands are available:
(when org-agenda-mouse-1-follows-link
(org-defkey org-agenda-mode-map [follow-link] 'mouse-face))
-(easy-menu-define org-agenda-menu org-agenda-mode-map "Agenda menu"
+(easy-menu-define org-agenda-menu org-agenda-mode-map "Agenda menu."
'("Agenda"
("Agenda Files")
"--"
@@ -2644,7 +2664,7 @@ that have been changed along."
(while (bufferp (setq buf (pop entry)))
(when (pop entry)
(with-current-buffer buf
- (let ((last-undo-buffer buf)
+ (let (;; (last-undo-buffer buf)
(inhibit-read-only t))
(unless (memq buf org-agenda-undo-has-started-in)
(push buf org-agenda-undo-has-started-in)
@@ -2796,7 +2816,7 @@ to limit entries to in this type."
(defvar org-keys nil)
(defvar org-match nil)
;;;###autoload
-(defun org-agenda (&optional arg org-keys restriction)
+(defun org-agenda (&optional arg keys restriction)
"Dispatch agenda commands to collect entries to the agenda buffer.
Prompts for a command to execute. Any prefix arg will be passed
on to the selected command. The default selections are:
@@ -2831,7 +2851,8 @@ Pressing `<' twice means to restrict to the current subtree or region
\(if active)."
(interactive "P")
(catch 'exit
- (let* ((prefix-descriptions nil)
+ (let* ((org-keys keys)
+ (prefix-descriptions nil)
(org-agenda-buffer-name org-agenda-buffer-name)
(org-agenda-window-setup (if (equal (buffer-name)
org-agenda-buffer-name)
@@ -2853,9 +2874,9 @@ Pressing `<' twice means to restrict to the current subtree or region
(org-agenda-custom-commands
(org-contextualize-keys
org-agenda-custom-commands org-agenda-custom-commands-contexts))
- (buf (current-buffer))
+ ;; (buf (current-buffer))
(bfn (buffer-file-name (buffer-base-buffer)))
- entry key type org-match lprops ans)
+ entry type org-match lprops ans) ;; key
;; Turn off restriction unless there is an overriding one,
(unless org-agenda-overriding-restriction
(unless org-agenda-keep-restricted-file-list
@@ -2907,47 +2928,51 @@ Pressing `<' twice means to restrict to the current subtree or region
((setq entry (assoc org-keys org-agenda-custom-commands))
(if (or (symbolp (nth 2 entry)) (functionp (nth 2 entry)))
(progn
- (setq type (nth 2 entry) org-match (eval (nth 3 entry))
+ ;; FIXME: Is (nth 3 entry) supposed to have access (via dynvars)
+ ;; to some of the local variables? There's no doc about
+ ;; that for `org-agenda-custom-commands'.
+ (setq type (nth 2 entry) org-match (eval (nth 3 entry) t)
lprops (nth 4 entry))
(when org-agenda-sticky
(setq org-agenda-buffer-name
(or (and (stringp org-match) (format "*Org Agenda(%s:%s)*" org-keys org-match))
(format "*Org Agenda(%s)*" org-keys))))
(put 'org-agenda-redo-command 'org-lprops lprops)
- (cond
- ((eq type 'agenda)
- (org-let lprops '(org-agenda-list current-prefix-arg)))
- ((eq type 'agenda*)
- (org-let lprops '(org-agenda-list current-prefix-arg nil nil t)))
- ((eq type 'alltodo)
- (org-let lprops '(org-todo-list current-prefix-arg)))
- ((eq type 'search)
- (org-let lprops '(org-search-view current-prefix-arg org-match nil)))
- ((eq type 'stuck)
- (org-let lprops '(org-agenda-list-stuck-projects
- current-prefix-arg)))
- ((eq type 'tags)
- (org-let lprops '(org-tags-view current-prefix-arg org-match)))
- ((eq type 'tags-todo)
- (org-let lprops '(org-tags-view '(4) org-match)))
- ((eq type 'todo)
- (org-let lprops '(org-todo-list org-match)))
- ((eq type 'tags-tree)
- (org-check-for-org-mode)
- (org-let lprops '(org-match-sparse-tree current-prefix-arg org-match)))
- ((eq type 'todo-tree)
- (org-check-for-org-mode)
- (org-let lprops
- '(org-occur (concat "^" org-outline-regexp "[ \t]*"
- (regexp-quote org-match) "\\>"))))
- ((eq type 'occur-tree)
- (org-check-for-org-mode)
- (org-let lprops '(org-occur org-match)))
- ((functionp type)
- (org-let lprops '(funcall type org-match)))
- ((fboundp type)
- (org-let lprops '(funcall type org-match)))
- (t (user-error "Invalid custom agenda command type %s" type))))
+ (cl-progv
+ (mapcar #'car lprops)
+ (mapcar (lambda (binding) (eval (cadr binding) t)) lprops)
+ (pcase type
+ (`agenda
+ (org-agenda-list current-prefix-arg))
+ (`agenda*
+ (org-agenda-list current-prefix-arg nil nil t))
+ (`alltodo
+ (org-todo-list current-prefix-arg))
+ (`search
+ (org-search-view current-prefix-arg org-match nil))
+ (`stuck
+ (org-agenda-list-stuck-projects current-prefix-arg))
+ (`tags
+ (org-tags-view current-prefix-arg org-match))
+ (`tags-todo
+ (org-tags-view '(4) org-match))
+ (`todo
+ (org-todo-list org-match))
+ (`tags-tree
+ (org-check-for-org-mode)
+ (org-match-sparse-tree current-prefix-arg org-match))
+ (`todo-tree
+ (org-check-for-org-mode)
+ (org-occur (concat "^" org-outline-regexp "[ \t]*"
+ (regexp-quote org-match) "\\>")))
+ (`occur-tree
+ (org-check-for-org-mode)
+ (org-occur org-match))
+ ((pred functionp)
+ (funcall type org-match))
+ ;; FIXME: Will signal an error since it's not `functionp'!
+ ((pred fboundp) (funcall type org-match))
+ (_ (user-error "Invalid custom agenda command type %s" type)))))
(org-agenda-run-series (nth 1 entry) (cddr entry))))
((equal org-keys "C")
(setq org-agenda-custom-commands org-agenda-custom-commands-orig)
@@ -3226,70 +3251,79 @@ s Search for keywords M Like m, but only TODO entries
(defvar org-agenda-overriding-cmd-arguments nil)
(defun org-let (list &rest body) ;FIXME: So many kittens are suffering here.
- (declare (indent 1))
+ (declare (indent 1) (obsolete cl-progv "2021"))
(eval (cons 'let (cons list body))))
(defun org-let2 (list1 list2 &rest body) ;FIXME: Where did our karma go?
- (declare (indent 2))
+ (declare (indent 2) (obsolete cl-progv "2021"))
(eval (cons 'let (cons list1 (list (cons 'let (cons list2 body)))))))
(defun org-agenda-run-series (name series)
"Run agenda NAME as a SERIES of agenda commands."
- (org-let (nth 1 series) '(org-agenda-prepare name))
- ;; We need to reset agenda markers here, because when constructing a
- ;; block agenda, the individual blocks do not do that.
- (org-agenda-reset-markers)
- (let* ((org-agenda-multi t)
- (redo (list 'org-agenda-run-series name (list 'quote series)))
- (cmds (car series))
- (gprops (nth 1 series))
- match ;; The byte compiler incorrectly complains about this. Keep it!
- org-cmd type lprops)
- (while (setq org-cmd (pop cmds))
- (setq type (car org-cmd))
- (setq match (eval (nth 1 org-cmd)))
- (setq lprops (nth 2 org-cmd))
- (let ((org-agenda-overriding-arguments
- (if (eq org-agenda-overriding-cmd org-cmd)
- (or org-agenda-overriding-arguments
- org-agenda-overriding-cmd-arguments))))
- (cond
- ((eq type 'agenda)
- (org-let2 gprops lprops
- '(call-interactively 'org-agenda-list)))
- ((eq type 'agenda*)
- (org-let2 gprops lprops
- '(funcall 'org-agenda-list nil nil t)))
- ((eq type 'alltodo)
- (org-let2 gprops lprops
- '(call-interactively 'org-todo-list)))
- ((eq type 'search)
- (org-let2 gprops lprops
- '(org-search-view current-prefix-arg match nil)))
- ((eq type 'stuck)
- (org-let2 gprops lprops
- '(call-interactively 'org-agenda-list-stuck-projects)))
- ((eq type 'tags)
- (org-let2 gprops lprops
- '(org-tags-view current-prefix-arg match)))
- ((eq type 'tags-todo)
- (org-let2 gprops lprops
- '(org-tags-view '(4) match)))
- ((eq type 'todo)
- (org-let2 gprops lprops
- '(org-todo-list match)))
- ((fboundp type)
- (org-let2 gprops lprops
- '(funcall type match)))
- (t (error "Invalid type in command series")))))
- (widen)
- (let ((inhibit-read-only t))
- (add-text-properties (point-min) (point-max)
- `(org-series t org-series-redo-cmd ,redo)))
- (setq org-agenda-redo-command redo)
- (goto-char (point-min)))
- (org-agenda-fit-window-to-buffer)
- (org-let (nth 1 series) '(org-agenda-finalize)))
+ (let* ((gprops (nth 1 series))
+ (gvars (mapcar #'car gprops))
+ (gvals (mapcar (lambda (binding) (eval (cadr binding) t)) gprops)))
+ (cl-progv gvars gvals (org-agenda-prepare name))
+ ;; We need to reset agenda markers here, because when constructing a
+ ;; block agenda, the individual blocks do not do that.
+ (org-agenda-reset-markers)
+ (with-no-warnings
+ (defvar match)) ;Used via the `eval' below.
+ (let* ((org-agenda-multi t)
+ ;; FIXME: Redo should contain lists of (FUNS . ARGS) rather
+ ;; than expressions, so you don't need to `quote' the args
+ ;; and you just need to `apply' instead of `eval' when using it.
+ (redo (list 'org-agenda-run-series name (list 'quote series)))
+ (cmds (car series))
+ match
+ org-cmd type lprops)
+ (while (setq org-cmd (pop cmds))
+ (setq type (car org-cmd))
+ (setq match (eval (nth 1 org-cmd) t))
+ (setq lprops (nth 2 org-cmd))
+ (let ((org-agenda-overriding-arguments
+ (if (eq org-agenda-overriding-cmd org-cmd)
+ (or org-agenda-overriding-arguments
+ org-agenda-overriding-cmd-arguments)))
+ (lvars (mapcar #'car lprops))
+ (lvals (mapcar (lambda (binding) (eval (cadr binding) t)) lprops)))
+ (cl-progv (append gvars lvars) (append gvals lvals)
+ (pcase type
+ (`agenda
+ (call-interactively 'org-agenda-list))
+ (`agenda*
+ (funcall 'org-agenda-list nil nil t))
+ (`alltodo
+ (call-interactively 'org-todo-list))
+ (`search
+ (org-search-view current-prefix-arg match nil))
+ (`stuck
+ (call-interactively 'org-agenda-list-stuck-projects))
+ (`tags
+ (org-tags-view current-prefix-arg match))
+ (`tags-todo
+ (org-tags-view '(4) match))
+ (`todo
+ (org-todo-list match))
+ ((pred fboundp)
+ (funcall type match))
+ (_ (error "Invalid type in command series"))))))
+ (widen)
+ (let ((inhibit-read-only t))
+ (add-text-properties (point-min) (point-max)
+ `(org-series t org-series-redo-cmd ,redo)))
+ (setq org-agenda-redo-command redo)
+ (goto-char (point-min)))
+ (org-agenda-fit-window-to-buffer)
+ (cl-progv gvars gvals (org-agenda-finalize))))
+
+(defun org-agenda--split-plist (plist)
+ ;; We could/should arguably use `map-keys' and `map-values'.
+ (let (keys vals)
+ (while plist
+ (push (pop plist) keys)
+ (push (pop plist) vals))
+ (cons (nreverse keys) (nreverse vals))))
;;;###autoload
(defmacro org-batch-agenda (cmd-key &rest parameters)
@@ -3299,7 +3333,13 @@ If CMD-KEY is a string of length 1, it is used as a key in
longer string it is used as a tags/todo match string.
Parameters are alternating variable names and values that will be bound
before running the agenda command."
- (org-eval-in-environment (org-make-parameter-alist parameters)
+ (pcase-let ((`(,vars . ,exps) (org-agenda--split-plist parameters)))
+ `(org--batch-agenda ,cmd-key ',vars (list ,@exps))))
+
+(defun org--batch-agenda (cmd-key vars vals)
+ ;; `org-batch-agenda' is a macro because every other "parameter" is
+ ;; a variable name rather than an expression to evaluate. Yuck!
+ (cl-progv vars vals
(let (org-agenda-sticky)
(if (> (length cmd-key) 1)
(org-tags-view nil cmd-key)
@@ -3344,11 +3384,18 @@ extra String with extra planning info
priority-l The priority letter if any was given
priority-n The computed numerical priority
agenda-day The day in the agenda where this is listed"
- (org-eval-in-environment (append '((org-agenda-remove-tags t))
- (org-make-parameter-alist parameters))
- (if (> (length cmd-key) 2)
- (org-tags-view nil cmd-key)
- (org-agenda nil cmd-key)))
+ (pcase-let ((`(,vars . ,exps) (org-agenda--split-plist parameters)))
+ `(org--batch-agenda-csv ,cmd-key ',vars (list ,@exps))))
+
+(defun org--batch-agenda-csv (cmd-key vars vals)
+ ;; `org-batch-agenda-csv' is a macro because every other "parameter" is
+ ;; a variable name rather than an expression to evaluate. Yuck!
+ (let ((org-agenda-remove-tags t))
+ (cl-progv vars vals
+ ;; FIXME: Shouldn't this be 1 (see commit 10173ad6d610b)?
+ (if (> (length cmd-key) 2)
+ (org-tags-view nil cmd-key)
+ (org-agenda nil cmd-key))))
(set-buffer org-agenda-buffer-name)
(let ((lines (org-split-string (buffer-string) "\n")))
(dolist (line lines)
@@ -3356,9 +3403,9 @@ agenda-day The day in the agenda where this is listed"
(setq org-agenda-info
(org-fix-agenda-info (text-properties-at 0 line)))
(princ
- (mapconcat 'org-agenda-export-csv-mapper
+ (mapconcat #'org-agenda-export-csv-mapper
'(org-category txt type todo tags date time extra
- priority-letter priority agenda-day)
+ priority-letter priority agenda-day)
","))
(princ "\n")))))
@@ -3367,7 +3414,7 @@ agenda-day The day in the agenda where this is listed"
This ensures the export commands can easily use it."
(let (tmp re)
(when (setq tmp (plist-get props 'tags))
- (setq props (plist-put props 'tags (mapconcat 'identity tmp ":"))))
+ (setq props (plist-put props 'tags (mapconcat #'identity tmp ":"))))
(when (setq tmp (plist-get props 'date))
(when (integerp tmp) (setq tmp (calendar-gregorian-from-absolute tmp)))
(let ((calendar-date-display-form '(year "-" month "-" day)))
@@ -3403,19 +3450,22 @@ This ensures the export commands can easily use it."
(org-trim (replace-regexp-in-string "," ";" res nil t))))
;;;###autoload
-(defun org-store-agenda-views (&rest parameters)
+(defun org-store-agenda-views (&rest _parameters)
"Store agenda views."
(interactive)
- (eval (list 'org-batch-store-agenda-views)))
+ (org--batch-store-agenda-views nil nil))
;;;###autoload
(defmacro org-batch-store-agenda-views (&rest parameters)
"Run all custom agenda commands that have a file argument."
+ (pcase-let ((`(,vars . ,exps) (org-agenda--split-plist parameters)))
+ `(org--batch-store-agenda-views ',vars (list ,@exps))))
+
+(defun org--batch-store-agenda-views (vars vals)
(let ((cmds (org-agenda-normalize-custom-commands org-agenda-custom-commands))
- (pop-up-frames nil)
- (dir default-directory)
- (pars (org-make-parameter-alist parameters))
- cmd thiscmdkey thiscmdcmd match files opts cmd-or-set bufname)
+ (pop-up-frames nil)
+ (dir default-directory)
+ cmd thiscmdkey thiscmdcmd match files opts cmd-or-set bufname)
(save-window-excursion
(while cmds
(setq cmd (pop cmds)
@@ -3432,14 +3482,18 @@ This ensures the export commands can easily use it."
files (nth (if (listp cmd-or-set) 4 5) cmd))
(if (stringp files) (setq files (list files)))
(when files
- (org-eval-in-environment (append org-agenda-exporter-settings
- opts pars)
- (org-agenda nil thiscmdkey))
- (set-buffer bufname)
- (while files
- (org-eval-in-environment (append org-agenda-exporter-settings
- opts pars)
- (org-agenda-write (expand-file-name (pop files) dir) nil t bufname)))
+ (let* ((opts (append org-agenda-exporter-settings opts))
+ (vars (append (mapcar #'car opts) vars))
+ (vals (append (mapcar (lambda (binding) (eval (cadr binding) t))
+ opts)
+ vals)))
+ (cl-progv vars vals
+ (org-agenda nil thiscmdkey))
+ (set-buffer bufname)
+ (while files
+ (cl-progv vars vals
+ (org-agenda-write (expand-file-name (pop files) dir)
+ nil t bufname))))
(and (get-buffer bufname)
(kill-buffer bufname)))))))
@@ -3479,80 +3533,87 @@ the agenda to write."
(if (called-interactively-p 'any)
(not (y-or-n-p (format "Overwrite existing file %s? " file))))))
(user-error "Cannot write agenda to file %s" file))
- (org-let (if nosettings nil org-agenda-exporter-settings)
- '(save-excursion
- (save-window-excursion
- (let ((bs (copy-sequence (buffer-string)))
- (extension (file-name-extension file))
- (default-directory (file-name-directory file))
- beg content)
- (with-temp-buffer
- (rename-buffer org-agenda-write-buffer-name t)
- (set-buffer-modified-p nil)
- (insert bs)
- (org-agenda-remove-marked-text 'invisible 'org-filtered)
- (run-hooks 'org-agenda-before-write-hook)
- (cond
- ((bound-and-true-p org-mobile-creating-agendas)
- (org-mobile-write-agenda-for-mobile file))
- ((string= "org" extension)
- (let (content p m message-log-max)
- (goto-char (point-min))
- (while (setq p (next-single-property-change (point) 'org-hd-marker nil))
- (goto-char p)
- (setq m (get-text-property (point) 'org-hd-marker))
- (when m
- (push (save-excursion
- (set-buffer (marker-buffer m))
- (goto-char m)
- (org-copy-subtree 1 nil t t)
- org-subtree-clip)
- content)))
- (find-file file)
- (erase-buffer)
- (dolist (s content) (org-paste-subtree 1 s))
- (write-file file)
- (kill-buffer (current-buffer))
- (message "Org file written to %s" file)))
- ((member extension '("html" "htm"))
- (or (require 'htmlize nil t)
- (error "Please install htmlize from https://github.com/hniksic/emacs-htmlize"))
- (set-buffer (htmlize-buffer (current-buffer)))
- (when org-agenda-export-html-style
- ;; replace <style> section with org-agenda-export-html-style
- (goto-char (point-min))
- (kill-region (- (search-forward "<style") 6)
- (search-forward "</style>"))
- (insert org-agenda-export-html-style))
- (write-file file)
- (kill-buffer (current-buffer))
- (message "HTML written to %s" file))
- ((string= "ps" extension)
- (require 'ps-print)
- (ps-print-buffer-with-faces file)
- (message "Postscript written to %s" file))
- ((string= "pdf" extension)
- (require 'ps-print)
- (ps-print-buffer-with-faces
- (concat (file-name-sans-extension file) ".ps"))
- (call-process "ps2pdf" nil nil nil
- (expand-file-name
- (concat (file-name-sans-extension file) ".ps"))
- (expand-file-name file))
- (delete-file (concat (file-name-sans-extension file) ".ps"))
- (message "PDF written to %s" file))
- ((string= "ics" extension)
- (require 'ox-icalendar)
- (org-icalendar-export-current-agenda (expand-file-name file)))
- (t
- (let ((bs (buffer-string)))
- (find-file file)
- (erase-buffer)
- (insert bs)
- (save-buffer 0)
- (kill-buffer (current-buffer))
- (message "Plain text written to %s" file))))))))
+ (cl-progv
+ (if nosettings nil (mapcar #'car org-agenda-exporter-settings))
+ (if nosettings nil (mapcar (lambda (binding) (eval (cadr binding) t))
+ org-agenda-exporter-settings))
+ (save-excursion
+ (save-window-excursion
+ (let ((bs (copy-sequence (buffer-string)))
+ (extension (file-name-extension file))
+ (default-directory (file-name-directory file))
+ ) ;; beg content
+ (with-temp-buffer
+ (rename-buffer org-agenda-write-buffer-name t)
+ (set-buffer-modified-p nil)
+ (insert bs)
+ (org-agenda-remove-marked-text 'invisible 'org-filtered)
+ (run-hooks 'org-agenda-before-write-hook)
+ (cond
+ ((bound-and-true-p org-mobile-creating-agendas)
+ (org-mobile-write-agenda-for-mobile file))
+ ((string= "org" extension)
+ (let (content p m message-log-max)
+ (goto-char (point-min))
+ (while (setq p (next-single-property-change (point) 'org-hd-marker nil))
+ (goto-char p)
+ (setq m (get-text-property (point) 'org-hd-marker))
+ (when m
+ (push (with-current-buffer (marker-buffer m)
+ (goto-char m)
+ (org-copy-subtree 1 nil t t)
+ org-subtree-clip)
+ content)))
+ (find-file file)
+ (erase-buffer)
+ (dolist (s content) (org-paste-subtree 1 s))
+ (write-file file)
+ (kill-buffer (current-buffer))
+ (message "Org file written to %s" file)))
+ ((member extension '("html" "htm"))
+ (or (require 'htmlize nil t)
+ (error "Please install htmlize from https://github.com/hniksic/emacs-htmlize"))
+ (declare-function htmlize-buffer "htmlize" (&optional buffer))
+ (set-buffer (htmlize-buffer (current-buffer)))
+ (when org-agenda-export-html-style
+ ;; replace <style> section with org-agenda-export-html-style
+ (goto-char (point-min))
+ (kill-region (- (search-forward "<style") 6)
+ (search-forward "</style>"))
+ (insert org-agenda-export-html-style))
+ (write-file file)
+ (kill-buffer (current-buffer))
+ (message "HTML written to %s" file))
+ ((string= "ps" extension)
+ (require 'ps-print)
+ (ps-print-buffer-with-faces file)
+ (message "Postscript written to %s" file))
+ ((string= "pdf" extension)
+ (require 'ps-print)
+ (ps-print-buffer-with-faces
+ (concat (file-name-sans-extension file) ".ps"))
+ (call-process "ps2pdf" nil nil nil
+ (expand-file-name
+ (concat (file-name-sans-extension file) ".ps"))
+ (expand-file-name file))
+ (delete-file (concat (file-name-sans-extension file) ".ps"))
+ (message "PDF written to %s" file))
+ ((string= "ics" extension)
+ (require 'ox-icalendar)
+ (declare-function org-icalendar-export-current-agenda
+ "ox-icalendar" (file))
+ (org-icalendar-export-current-agenda (expand-file-name file)))
+ (t
+ (let ((bs (buffer-string)))
+ (find-file file)
+ (erase-buffer)
+ (insert bs)
+ (save-buffer 0)
+ (kill-buffer (current-buffer))
+ (message "Plain text written to %s" file))))))))
(set-buffer (or agenda-bufname
+ ;; FIXME: I'm pretty sure called-interactively-p
+ ;; doesn't do what we want here!
(and (called-interactively-p 'any) (buffer-name))
org-agenda-buffer-name)))
(when open (org-open-file file)))
@@ -3708,15 +3769,14 @@ the global options and expect it to be applied to the entire view.")
(tag . org-agenda-tag-filter)
(effort . org-agenda-effort-filter)
(regexp . org-agenda-regexp-filter))
- "Alist of filter types and associated variables")
+ "Alist of filter types and associated variables.")
(defun org-agenda-filter-any ()
"Is any filter active?"
- (let ((form (cons 'or (mapcar (lambda (x)
- (if (or (symbol-value (cdr x))
- (get :preset-filter x))
- t nil))
- org-agenda-filter-variables))))
- (eval form)))
+ (cl-some (lambda (x)
+ (or (symbol-value (cdr x))
+ (get :preset-filter x)))
+ org-agenda-filter-variables))
+
(defvar org-agenda-category-filter-preset nil
"A preset of the category filter used for secondary agenda filtering.
This must be a list of strings, each string must be a single category
@@ -3928,7 +3988,7 @@ agenda display, configure `org-agenda-finalize-hook'."
(put-text-property (point-at-bol) (point-at-eol)
'tags
(org-with-point-at mrk
- (mapcar #'downcase (org-get-tags)))))))))
+ (org-get-tags))))))))
(setq org-agenda-represented-tags nil
org-agenda-represented-categories nil)
(when org-agenda-top-headline-filter
@@ -3954,7 +4014,7 @@ agenda display, configure `org-agenda-finalize-hook'."
(when (get 'org-agenda-effort-filter :preset-filter)
(org-agenda-filter-apply
(get 'org-agenda-effort-filter :preset-filter) 'effort))
- (add-hook 'kill-buffer-hook 'org-agenda-reset-markers 'append 'local))
+ (add-hook 'kill-buffer-hook #'org-agenda-reset-markers 'append 'local))
(run-hooks 'org-agenda-finalize-hook))))
(defun org-agenda-mark-clocking-task ()
@@ -4023,10 +4083,10 @@ agenda display, configure `org-agenda-finalize-hook'."
(defvar org-depend-tag-blocked)
-(defun org-agenda-dim-blocked-tasks (&optional invisible)
+(defun org-agenda-dim-blocked-tasks (&optional _invisible)
"Dim currently blocked TODOs in the agenda display.
When INVISIBLE is non-nil, hide currently blocked TODO instead of
-dimming them."
+dimming them." ;FIXME: The arg isn't used, actually!
(interactive "P")
(when (called-interactively-p 'interactive)
(message "Dim or hide blocked tasks..."))
@@ -4051,7 +4111,9 @@ dimming them."
(overlay-put ov 'face 'org-agenda-dimmed-todo-face))
(when invisible
(org-agenda-filter-hide-line 'todo-blocked)))
- (move-beginning-of-line 2))))
+ (if (= (point-max) (line-end-position))
+ (goto-char (point-max))
+ (move-beginning-of-line 2)))))
(when (called-interactively-p 'interactive)
(message "Dim or hide blocked tasks...done")))
@@ -4134,7 +4196,7 @@ functions do."
(save-match-data
(if fp
(funcall form)
- (eval form)))))))
+ (eval form t)))))))
(defvar org-agenda-markers nil
"List of all currently active markers created by `org-agenda'.")
@@ -4208,6 +4270,9 @@ This check for agenda markers in all agenda buffers currently active."
"Return the face DATE should be displayed with."
(cond ((and (functionp org-agenda-day-face-function)
(funcall org-agenda-day-face-function date)))
+ ((and (org-agenda-today-p date)
+ (memq (calendar-day-of-week date) org-agenda-weekend-days))
+ 'org-agenda-date-weekend-today)
((org-agenda-today-p date) 'org-agenda-date-today)
((memq (calendar-day-of-week date) org-agenda-weekend-days)
'org-agenda-date-weekend)
@@ -4250,7 +4315,7 @@ items if they have an hour specification like [h]h:mm."
(setq span arg arg nil))
(when (numberp span)
(unless (< 0 span)
- (user-error "Agenda creation impossible for this span(=%d days)." span)))
+ (user-error "Agenda creation impossible for this span(=%d days)" span)))
(catch 'exit
(setq org-agenda-buffer-name
(org-agenda--get-buffer-name
@@ -4288,11 +4353,11 @@ items if they have an hour specification like [h]h:mm."
(day-cnt 0)
(inhibit-redisplay (not debug-on-error))
(org-agenda-show-log-scoped org-agenda-show-log)
- s e rtn rtnall file date d start-pos end-pos todayp
- clocktable-start clocktable-end filter)
+ s rtn rtnall file date d start-pos end-pos todayp ;; e
+ clocktable-start clocktable-end) ;; filter
(setq org-agenda-redo-command
(list 'org-agenda-list (list 'quote arg) start-day (list 'quote span) with-hour))
- (dotimes (n (1- ndays))
+ (dotimes (_ (1- ndays))
(push (1+ (car day-numbers)) day-numbers))
(setq day-numbers (nreverse day-numbers))
(setq clocktable-start (car day-numbers)
@@ -4358,11 +4423,11 @@ items if they have an hour specification like [h]h:mm."
(setq rtn (org-agenda-get-day-entries
file date :closed)))
(org-agenda-show-log-scoped
- (setq rtn (apply 'org-agenda-get-day-entries
+ (setq rtn (apply #'org-agenda-get-day-entries
file date
(append '(:closed) org-agenda-entry-types))))
(t
- (setq rtn (apply 'org-agenda-get-day-entries
+ (setq rtn (apply #'org-agenda-get-day-entries
file date
org-agenda-entry-types)))))
(setq rtnall (append rtnall rtn)))) ;; all entries
@@ -4402,7 +4467,7 @@ items if they have an hour specification like [h]h:mm."
(setq p (plist-put p :tstart clocktable-start))
(setq p (plist-put p :tend clocktable-end))
(setq p (plist-put p :scope 'agenda))
- (setq tbl (apply 'org-clock-get-clocktable p))
+ (setq tbl (apply #'org-clock-get-clocktable p))
(insert tbl)))
(goto-char (point-min))
(or org-agenda-multi (org-agenda-fit-window-to-buffer))
@@ -4531,7 +4596,7 @@ is active."
'org-todo-regexp org-todo-regexp
'org-complex-heading-regexp org-complex-heading-regexp
'mouse-face 'highlight
- 'help-echo (format "mouse-2 or RET jump to location")))
+ 'help-echo "mouse-2 or RET jump to location"))
(full-words org-agenda-search-view-force-full-words)
(org-agenda-text-search-extra-files org-agenda-text-search-extra-files)
regexp rtn rtnall files file pos inherited-tags
@@ -4623,7 +4688,7 @@ is active."
(setq re (regexp-quote (downcase w)))))
(if neg (push re regexps-) (push re regexps+)))
words)
- (push (mapconcat (lambda (w) (regexp-quote w)) words "\\s-+")
+ (push (mapconcat #'regexp-quote words "\\s-+")
regexps+))
(setq regexps+ (sort regexps+ (lambda (a b) (> (length a) (length b)))))
(if (not regexps+)
@@ -4746,7 +4811,7 @@ is active."
(list 'face 'org-agenda-structure))
(setq pos (point))
(insert string "\n")
- (add-text-properties pos (1- (point)) (list 'face 'org-warning))
+ (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure-filter))
(setq pos (point))
(unless org-agenda-multi
(insert (substitute-command-keys "\\<org-agenda-mode-map>\
@@ -4756,7 +4821,7 @@ Press `\\[org-agenda-manipulate-query-add]', \
`\\[org-agenda-manipulate-query-subtract-re]' to add/sub regexp, \
`\\[universal-argument] \\[org-agenda-redo]' for a fresh search\n"))
(add-text-properties pos (1- (point))
- (list 'face 'org-agenda-structure)))
+ (list 'face 'org-agenda-structure-secondary)))
(buffer-string)))
(org-agenda-mark-header-line (point-min))
(when rtnall
@@ -4777,10 +4842,10 @@ Press `\\[org-agenda-manipulate-query-add]', \
"Use `org-todo-keyword-faces' for the selected todo KEYWORDS."
(concat
(if (or (equal keywords "ALL") (not keywords))
- (propertize "ALL" 'face 'warning)
+ (propertize "ALL" 'face 'org-agenda-structure-filter)
(mapconcat
(lambda (kw)
- (propertize kw 'face (org-get-todo-face kw)))
+ (propertize kw 'face (list (org-get-todo-face kw) 'org-agenda-structure)))
(org-split-string keywords "|")
"|"))
"\n"))
@@ -4788,6 +4853,8 @@ Press `\\[org-agenda-manipulate-query-add]', \
(defvar org-select-this-todo-keyword nil)
(defvar org-last-arg nil)
+(defvar crm-separator)
+
;;;###autoload
(defun org-todo-list (&optional arg)
"Show all (not done) TODO entries from all agenda file in a single list.
@@ -4863,7 +4930,7 @@ to search again: (0)[ALL]"))
(insert "\n "))
(insert " " s))))
(insert "\n"))
- (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure))
+ (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure-secondary))
(buffer-string)))
(org-agenda-mark-header-line (point-min))
(when rtnall
@@ -4954,7 +5021,7 @@ The prefix arg TODO-ONLY limits the search to TODO entries."
(concat "Match: " match)))
(setq pos (point))
(insert match "\n")
- (add-text-properties pos (1- (point)) (list 'face 'org-warning))
+ (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure-filter))
(setq pos (point))
(unless org-agenda-multi
(insert (substitute-command-keys
@@ -4962,7 +5029,7 @@ The prefix arg TODO-ONLY limits the search to TODO entries."
\\<org-agenda-mode-map>`\\[universal-argument] \\[org-agenda-redo]' \
to search again\n")))
(add-text-properties pos (1- (point))
- (list 'face 'org-agenda-structure))
+ (list 'face 'org-agenda-structure-secondary))
(buffer-string)))
(org-agenda-mark-header-line (point-min))
(when rtnall
@@ -4988,10 +5055,11 @@ used by user-defined selections using `org-agenda-skip-function'.")
(defvar org-agenda-overriding-header nil
"When set during agenda, todo and tags searches it replaces the header.
If an empty string, no header will be inserted. If any other
-string, it will be inserted as a header. If nil, a header will
-be generated automatically according to the command. This
-variable should not be set directly, but custom commands can bind
-it in the options section.")
+string, it will be inserted as a header. If a function, insert
+the string returned by the function as a header. If nil, a
+header will be generated automatically according to the command.
+This variable should not be set directly, but custom commands can
+bind it in the options section.")
(defun org-agenda-skip-entry-if (&rest conditions)
"Skip entry if any of CONDITIONS is true.
@@ -5004,7 +5072,7 @@ See `org-agenda-skip-if' for details."
(org-agenda-skip-if t conditions))
(defun org-agenda-skip-if (subtree conditions)
- "Checks current entity for CONDITIONS.
+ "Check current entity for CONDITIONS.
If SUBTREE is non-nil, the entire subtree is checked. Otherwise, only
the entry (i.e. the text before the next heading) is checked.
@@ -5043,7 +5111,7 @@ If any of these conditions is met, this function returns the end point of
the entity, causing the search to continue from there. This is a function
that can be put into `org-agenda-skip-function' for the duration of a command."
(org-back-to-heading t)
- (let* ((beg (point))
+ (let* (;; (beg (point))
(end (if subtree (save-excursion (org-end-of-subtree t) (point))
(org-entry-end-position)))
(planning-end (if subtree end (line-end-position 2)))
@@ -5117,7 +5185,7 @@ a list of TODO keywords, or a state symbol `todo' or `done' or
(`(,type . ,_) (error "Unknown TODO skip type: %S" type)))))
;;;###autoload
-(defun org-agenda-list-stuck-projects (&rest ignore)
+(defun org-agenda-list-stuck-projects (&rest _ignore)
"Create agenda view for projects that are stuck.
Stuck projects are project that have no next actions. For the definitions
of what a project is and how to check if it stuck, customize the variable
@@ -5155,12 +5223,12 @@ of what a project is and how to check if it stuck, customize the variable
(org-agenda-skip-function
;; Skip entry if `org-agenda-skip-regexp' matches anywhere
;; in the subtree.
- `(lambda ()
- (and (save-excursion
- (let ((case-fold-search nil))
- (re-search-forward
- ,skip-re (save-excursion (org-end-of-subtree t)) t)))
- (progn (outline-next-heading) (point))))))
+ (lambda ()
+ (and (save-excursion
+ (let ((case-fold-search nil))
+ (re-search-forward
+ skip-re (save-excursion (org-end-of-subtree t)) t)))
+ (progn (outline-next-heading) (point))))))
(org-tags-view nil matcher)
(setq org-agenda-buffer-name (buffer-name))
(with-current-buffer org-agenda-buffer-name
@@ -5176,24 +5244,28 @@ of what a project is and how to check if it stuck, customize the variable
(defvar org-disable-agenda-to-diary nil) ;Dynamically-scoped param.
(defvar diary-list-entries-hook)
(defvar diary-time-regexp)
+(defvar diary-modify-entry-list-string-function)
+(defvar diary-file-name-prefix)
+(defvar diary-display-function)
+
(defun org-get-entries-from-diary (date)
"Get the (Emacs Calendar) diary entries for DATE."
(require 'diary-lib)
+ (declare-function diary-fancy-display "diary-lib" ())
(let* ((diary-fancy-buffer "*temporary-fancy-diary-buffer*")
- (diary-display-function 'diary-fancy-display)
+ (diary-display-function #'diary-fancy-display)
(pop-up-frames nil)
(diary-list-entries-hook
(cons 'org-diary-default-entry diary-list-entries-hook))
(diary-file-name-prefix nil) ; turn this feature off
- (diary-modify-entry-list-string-function 'org-modify-diary-entry-string)
+ (diary-modify-entry-list-string-function
+ #'org-modify-diary-entry-string)
(diary-time-regexp (concat "^" diary-time-regexp))
entries
(org-disable-agenda-to-diary t))
(save-excursion
(save-window-excursion
- (funcall (if (fboundp 'diary-list-entries)
- 'diary-list-entries 'list-diary-entries)
- date 1)))
+ (diary-list-entries date 1)))
(if (not (get-buffer diary-fancy-buffer))
(setq entries nil)
(with-current-buffer diary-fancy-buffer
@@ -5268,15 +5340,7 @@ each date. It also removes lines that contain only whitespace."
Needed to avoid empty dates which mess up holiday display."
;; Catch the error if dealing with the new add-to-diary-alist
(when org-disable-agenda-to-diary
- (condition-case nil
- (org-add-to-diary-list original-date "Org mode dummy" "")
- (error
- (org-add-to-diary-list original-date "Org mode dummy" "" nil)))))
-
-(defun org-add-to-diary-list (&rest args)
- (if (fboundp 'diary-add-to-list)
- (apply 'diary-add-to-list args)
- (apply 'add-to-diary-list args)))
+ (diary-add-to-list original-date "Org mode dummy" "")))
(defvar org-diary-last-run-time nil)
@@ -5307,6 +5371,7 @@ So the example above may also be written as
The function expects the lisp variables `entry' and `date' to be provided
by the caller, because this is how the calendar works. Don't use this
function from a program - use `org-agenda-get-day-entries' instead."
+ (with-no-warnings (defvar date) (defvar entry))
(when (> (- (float-time)
org-agenda-last-marker-time)
5)
@@ -5331,7 +5396,7 @@ function from a program - use `org-agenda-get-day-entries' instead."
;; the calendar. Org Agenda will list these entries itself.
(when org-disable-agenda-to-diary (setq files nil))
(while (setq file (pop files))
- (setq rtn (apply 'org-agenda-get-day-entries file date args))
+ (setq rtn (apply #'org-agenda-get-day-entries file date args))
(setq results (append results rtn)))
(when results
(setq results
@@ -5392,27 +5457,29 @@ the documentation of `org-diary'."
(setf args (cons :deadline* (delq :deadline* args)))))
;; Collect list of headlines. Return them flattened.
(let ((case-fold-search nil) results deadlines)
- (dolist (arg args (apply #'nconc (nreverse results)))
- (pcase arg
- ((and :todo (guard (org-agenda-today-p date)))
- (push (org-agenda-get-todos) results))
- (:timestamp
- (push (org-agenda-get-blocks) results)
- (push (org-agenda-get-timestamps deadlines) results))
- (:sexp
- (push (org-agenda-get-sexps) results))
- (:scheduled
- (push (org-agenda-get-scheduled deadlines) results))
- (:scheduled*
- (push (org-agenda-get-scheduled deadlines t) results))
- (:closed
- (push (org-agenda-get-progress) results))
- (:deadline
- (setf deadlines (org-agenda-get-deadlines))
- (push deadlines results))
- (:deadline*
- (setf deadlines (org-agenda-get-deadlines t))
- (push deadlines results)))))))))))
+ (org-dlet
+ ((date date))
+ (dolist (arg args (apply #'nconc (nreverse results)))
+ (pcase arg
+ ((and :todo (guard (org-agenda-today-p date)))
+ (push (org-agenda-get-todos) results))
+ (:timestamp
+ (push (org-agenda-get-blocks) results)
+ (push (org-agenda-get-timestamps deadlines) results))
+ (:sexp
+ (push (org-agenda-get-sexps) results))
+ (:scheduled
+ (push (org-agenda-get-scheduled deadlines) results))
+ (:scheduled*
+ (push (org-agenda-get-scheduled deadlines t) results))
+ (:closed
+ (push (org-agenda-get-progress) results))
+ (:deadline
+ (setf deadlines (org-agenda-get-deadlines))
+ (push deadlines results))
+ (:deadline*
+ (setf deadlines (org-agenda-get-deadlines t))
+ (push deadlines results))))))))))))
(defsubst org-em (x y list)
"Is X or Y a member of LIST?"
@@ -5474,11 +5541,12 @@ and the timestamp type relevant for the sorting strategy in
org-todo-regexp)
(org-select-this-todo-keyword
(concat "\\("
- (mapconcat 'identity
+ (mapconcat #'identity
(org-split-string
org-select-this-todo-keyword
"|")
- "\\|") "\\)"))
+ "\\|")
+ "\\)"))
(t org-not-done-regexp))))
marker priority category level tags todo-state
ts-date ts-date-type ts-date-pair
@@ -5618,6 +5686,7 @@ This function is invoked if `org-agenda-todo-ignore-deadlines',
"Return the date stamp information for agenda display.
Optional argument DEADLINES is a list of deadline items to be
displayed in agenda view."
+ (with-no-warnings (defvar date))
(let* ((props (list 'face 'org-agenda-calendar-event
'org-not-done-regexp org-not-done-regexp
'org-todo-regexp org-todo-regexp
@@ -5760,12 +5829,15 @@ displayed in agenda view."
(defun org-agenda-get-sexps ()
"Return the sexp information for agenda display."
(require 'diary-lib)
+ (with-no-warnings (defvar date) (defvar entry))
(let* ((props (list 'face 'org-agenda-calendar-sexp
'mouse-face 'highlight
'help-echo
(format "mouse-2 or RET jump to org file %s"
(abbreviate-file-name buffer-file-name))))
(regexp "^&?%%(")
+ ;; FIXME: Is this `entry' binding intended to be dynamic,
+ ;; so as to "hide" any current binding for it?
marker category extra level ee txt tags entry
result beg b sexp sexp-entry todo-state warntime inherited-tags)
(goto-char (point-min))
@@ -5846,6 +5918,7 @@ item should be skipped. If any of the SKIP-WEEKS arguments is the symbol
`holidays', then any date that is known by the Emacs calendar to be a
holiday will also be skipped. If SKIP-WEEKS arguments are holiday strings,
then those holidays will be skipped."
+ (with-no-warnings (defvar date) (defvar entry))
(let* ((date1 (calendar-absolute-from-gregorian (list m1 d1 y1)))
(date2 (calendar-absolute-from-gregorian (list m2 d2 y2)))
(d (calendar-absolute-from-gregorian date))
@@ -5862,9 +5935,10 @@ then those holidays will be skipped."
(delq nil (mapcar (lambda(g) (member g skip-weeks)) h))))
entry)))
-(defalias 'org-get-closed 'org-agenda-get-progress)
+(defalias 'org-get-closed #'org-agenda-get-progress)
(defun org-agenda-get-progress ()
"Return the logged TODO entries for agenda display."
+ (with-no-warnings (defvar date))
(let* ((props (list 'mouse-face 'highlight
'org-not-done-regexp org-not-done-regexp
'org-todo-regexp org-todo-regexp
@@ -5884,7 +5958,7 @@ then those holidays will be skipped."
(when (memq 'clock items) (concat "\\<" org-clock-string))
(when (memq 'state items)
(format "- +State \"%s\".*?" org-todo-regexp)))))
- (parts-re (if parts (mapconcat 'identity parts "\\|")
+ (parts-re (if parts (mapconcat #'identity parts "\\|")
(error "`org-agenda-log-mode-items' is empty")))
(regexp (concat
"\\(" parts-re "\\)"
@@ -5995,7 +6069,7 @@ See also the user option `org-agenda-clock-consistency-checks'."
'((:background "DarkRed") (:foreground "white"))))
issue face m te ts dt ov)
(goto-char (point-min))
- (while (re-search-forward " Clocked: +(-\\|\\([0-9]+:[0-9]+\\))" nil t)
+ (while (re-search-forward " Clocked: +(\\(?:-\\|\\([0-9]+:[0-9]+\\)\\))" nil t)
(setq issue nil face def-face)
(catch 'next
(setq m (org-get-at-bol 'org-marker)
@@ -6096,6 +6170,7 @@ See also the user option `org-agenda-clock-consistency-checks'."
"Return the deadline information for agenda display.
When WITH-HOUR is non-nil, only return deadlines with an hour
specification like [h]h:mm."
+ (with-no-warnings (defvar date))
(let* ((props (list 'mouse-face 'highlight
'org-not-done-regexp org-not-done-regexp
'org-todo-regexp org-todo-regexp
@@ -6254,6 +6329,7 @@ FRACTION is what fraction of the head-warning time has passed."
Optional argument DEADLINES is a list of deadline items to be
displayed in agenda view. When WITH-HOUR is non-nil, only return
scheduled items with an hour specification like [h]h:mm."
+ (with-no-warnings (defvar date))
(let* ((props (list 'org-not-done-regexp org-not-done-regexp
'org-todo-regexp org-todo-regexp
'org-complex-heading-regexp org-complex-heading-regexp
@@ -6454,6 +6530,7 @@ scheduled items with an hour specification like [h]h:mm."
(defun org-agenda-get-blocks ()
"Return the date-range information for agenda display."
+ (with-no-warnings (defvar date))
(let* ((props (list 'face nil
'org-not-done-regexp org-not-done-regexp
'org-todo-regexp org-todo-regexp
@@ -6585,14 +6662,14 @@ The flag is set if the currently compiled format contains a `%b'.")
(cl-return (cadr entry))
(cl-return (apply #'create-image (cdr entry)))))))
-(defun org-agenda-format-item (extra txt &optional level category tags dotime
+(defun org-agenda-format-item (extra txt &optional with-level with-category tags dotime
remove-re habitp)
"Format TXT to be inserted into the agenda buffer.
In particular, add the prefix and corresponding text properties.
EXTRA must be a string to replace the `%s' specifier in the prefix format.
-LEVEL may be a string to replace the `%l' specifier.
-CATEGORY (a string, a symbol or nil) may be used to overrule the default
+WITH-LEVEL may be a string to replace the `%l' specifier.
+WITH-CATEGORY (a string, a symbol or nil) may be used to overrule the default
category taken from local variable or file name. It will replace the `%c'
specifier in the format.
DOTIME, when non-nil, indicates that a time-of-day should be extracted from
@@ -6622,7 +6699,14 @@ Any match of REMOVE-RE will be removed from TXT."
org-agenda-show-inherited-tags
org-agenda-hide-tags-regexp))
- (let* ((category (or category
+ (with-no-warnings
+ ;; `time', `tag', `effort' are needed for the eval of the prefix format.
+ ;; Based on what I see in `org-compile-prefix-format', I added
+ ;; a few more.
+ (defvar breadcrumbs) (defvar category) (defvar category-icon)
+ (defvar effort) (defvar extra)
+ (defvar level) (defvar tag) (defvar time))
+ (let* ((category (or with-category
(if buffer-file-name
(file-name-sans-extension
(file-name-nondirectory buffer-file-name))
@@ -6633,9 +6717,9 @@ Any match of REMOVE-RE will be removed from TXT."
""))
(effort (and (not (string= txt ""))
(get-text-property 1 'effort txt)))
- ;; time, tag, effort are needed for the eval of the prefix format
(tag (if tags (nth (1- (length tags)) tags) ""))
(time-grid-trailing-characters (nth 2 org-agenda-time-grid))
+ (extra (or (and (not habitp) extra) ""))
time
(ts (when dotime (concat
(if (stringp dotime) dotime "")
@@ -6665,10 +6749,9 @@ Any match of REMOVE-RE will be removed from TXT."
(= (match-beginning 0) 0)
t))
(setq txt (replace-match "" nil nil txt))))
- ;; Normalize the time(s) to 24 hour
- (when s1 (setq s1 (org-get-time-of-day s1 'string t)))
- (when s2 (setq s2 (org-get-time-of-day s2 'string t)))
-
+ ;; Normalize the time(s) to 24 hour.
+ (when s1 (setq s1 (org-get-time-of-day s1 t)))
+ (when s2 (setq s2 (org-get-time-of-day s2 t)))
;; Try to set s2 if s1 and
;; `org-agenda-default-appointment-duration' are set
(when (and s1 (not s2) org-agenda-default-appointment-duration)
@@ -6677,12 +6760,13 @@ Any match of REMOVE-RE will be removed from TXT."
(+ (org-duration-to-minutes s1 t)
org-agenda-default-appointment-duration)
nil t)))
-
;; Compute the duration
(when s2
(setq duration (- (org-duration-to-minutes s2)
- (org-duration-to-minutes s1)))))
-
+ (org-duration-to-minutes s1))))
+ ;; Format S1 and S2 for display.
+ (when s1 (setq s1 (org-get-time-of-day s1 'overtime)))
+ (when s2 (setq s2 (org-get-time-of-day s2 'overtime))))
(when (string-match org-tag-group-re txt)
;; Tags are in the string
(if (or (eq org-agenda-remove-tags t)
@@ -6719,9 +6803,8 @@ Any match of REMOVE-RE will be removed from TXT."
(concat time-grid-trailing-characters " ")
time-grid-trailing-characters)))
(t ""))
- extra (or (and (not habitp) extra) "")
category (if (symbolp category) (symbol-name category) category)
- level (or level ""))
+ level (or with-level ""))
(if (string-match org-link-bracket-re category)
(progn
(setq l (string-width (or (match-string 2) (match-string 1))))
@@ -6734,14 +6817,14 @@ Any match of REMOVE-RE will be removed from TXT."
(>= (length category) org-prefix-category-max-length))
(setq category (substring category 0 (1- org-prefix-category-max-length)))))
;; Evaluate the compiled format
- (setq rtn (concat (eval formatter) txt))
+ (setq rtn (concat (eval formatter t) txt))
;; And finally add the text properties
(remove-text-properties 0 (length rtn) '(line-prefix t wrap-prefix t) rtn)
(org-add-props rtn nil
'org-category category
- 'tags (mapcar 'org-downcase-keep-props tags)
- 'org-priority-highest org-priority-highest
+ 'tags tags
+ 'org-priority-highest org-priority-highest
'org-priority-lowest org-priority-lowest
'time-of-day time-of-day
'duration duration
@@ -6785,12 +6868,6 @@ The modified list may contain inherited tags, and tags matched by
(if have-i "::" ":"))))))
txt)
-(defun org-downcase-keep-props (s)
- (let ((props (text-properties-at 0 s)))
- (setq s (downcase s))
- (add-text-properties 0 (length s) props s)
- s))
-
(defvar org-agenda-sorting-strategy) ;; because the def is in a let form
(defun org-agenda-add-time-grid-maybe (list ndays todayp)
@@ -6853,8 +6930,8 @@ and stored in the variable `org-prefix-format-compiled'."
(cdr (assq key org-agenda-prefix-format)))
(t " %-12:c%?-12t% s")))
(start 0)
- varform vars var e c f opt)
- (while (string-match "%\\(\\?\\)?\\([-+]?[0-9.]*\\)\\([ .;,:!?=|/<>]?\\)\\([cltseib]\\|(.+)\\)"
+ varform vars var c f opt) ;; e
+ (while (string-match "%\\(\\?\\)?\\([-+]?[0-9.]*\\)\\([ .;,:!?=|/<>]?\\)\\([cltseib]\\|(.+?)\\)"
s start)
(setq var (or (cdr (assoc (match-string 4 s)
'(("c" . category) ("t" . time) ("l" . level) ("s" . extra)
@@ -6878,17 +6955,21 @@ and stored in the variable `org-prefix-format-compiled'."
(and (string-match "\\.[0-9]+" x)
(string-to-number (substring (match-string 0 x) 1)))))))
(if (eq var 'eval)
- (setq varform `(format ,f (org-eval ,(read (match-string 4 s)))))
+ (setq varform `(format ,f (org-eval ,(read (substring s (match-beginning 4))))))
(if opt
(setq varform
- `(if (or (equal "" ,var) (equal nil ,var))
+ `(if (member ,var '("" nil))
""
(format ,f (concat ,var ,c))))
(setq varform
- `(format ,f (if (or (equal ,var "")
- (equal ,var nil)) ""
+ `(format ,f (if (member ,var '("" nil)) ""
(concat ,var ,c (get-text-property 0 'extra-space ,var)))))))
- (setq s (replace-match "%s" t nil s))
+ (if (eq var 'eval)
+ (setf (substring s (match-beginning 0)
+ (+ (match-beginning 4)
+ (length (format "%S" (read (substring s (match-beginning 4)))))))
+ "%s")
+ (setq s (replace-match "%s" t nil s)))
(push varform vars))
(setq vars (nreverse vars))
(with-current-buffer (or org-agenda-buffer (current-buffer))
@@ -6902,43 +6983,57 @@ and stored in the variable `org-prefix-format-compiled'."
`(format ,s ,@vars))))))
(defun org-set-sorting-strategy (key)
- (if (symbolp (car org-agenda-sorting-strategy))
- ;; the old format
- (setq org-agenda-sorting-strategy-selected org-agenda-sorting-strategy)
- (setq org-agenda-sorting-strategy-selected
+ (setq org-agenda-sorting-strategy-selected
+ (if (symbolp (car org-agenda-sorting-strategy))
+ ;; the old format
+ org-agenda-sorting-strategy
(or (cdr (assq key org-agenda-sorting-strategy))
(cdr (assq 'agenda org-agenda-sorting-strategy))
'(time-up category-keep priority-down)))))
-(defun org-get-time-of-day (s &optional string mod24)
+(defun org-get-time-of-day (s &optional string)
"Check string S for a time of day.
+
If found, return it as a military time number between 0 and 2400.
If not found, return nil.
+
The optional STRING argument forces conversion into a 5 character wide string
-HH:MM."
- (save-match-data
- (when
- (and
- (or (string-match "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)\\([AaPp][Mm]\\)?\\> *" s)
- (string-match "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)?\\([AaPp][Mm]\\)\\> *" s))
- (not (eq (get-text-property 1 'face s) 'org-link)))
- (let* ((h (string-to-number (match-string 1 s)))
- (m (if (match-end 3) (string-to-number (match-string 3 s)) 0))
- (ampm (when (match-end 4) (downcase (match-string 4 s))))
- (am-p (equal ampm "am"))
- (h1 (cond ((not ampm) h)
- ((= h 12) (if am-p 0 12))
- (t (+ h (if am-p 0 12)))))
- (h2 (if (and string mod24 (not (and (= m 0) (= h1 24))))
- (mod h1 24) h1))
- (t0 (+ (* 100 h2) m))
- (t1 (concat (if (>= h1 24) "+" " ")
- (if (and org-agenda-time-leading-zero
- (< t0 1000)) "0" "")
- (if (< t0 100) "0" "")
- (if (< t0 10) "0" "")
- (number-to-string t0))))
- (if string (concat (substring t1 -4 -2) ":" (substring t1 -2)) t0)))))
+HH:MM. When it is `overtime', any time above 24:00 is turned into \"+H:MM\"
+where H:MM is the duration above midnight."
+ (let ((case-fold-search t)
+ (time-regexp
+ (rx word-start
+ (group (opt (any "012")) digit) ;group 1: hours
+ (or (and ":" (group (any "012345") digit) ;group 2: minutes
+ (opt (group (or "am" "pm")))) ;group 3: am/pm
+ ;; Special "HHam/pm" case.
+ (group-n 3 (or "am" "pm")))
+ word-end)))
+ (save-match-data
+ (when (and (string-match time-regexp s)
+ (not (eq 'org-link (get-text-property 1 'face s))))
+ (let ((hours
+ (let* ((ampm (and (match-end 3) (downcase (match-string 3 s))))
+ (am-p (equal ampm "am")))
+ (pcase (string-to-number (match-string 1 s))
+ ((and (guard (not ampm)) h) h)
+ (12 (if am-p 0 12))
+ (h (+ h (if am-p 0 12))))))
+ (minutes
+ (if (match-end 2)
+ (string-to-number (match-string 2 s))
+ 0)))
+ (pcase string
+ (`nil (+ minutes (* hours 100)))
+ ((and `overtime
+ (guard (or (> hours 24)
+ (and (= hours 24)
+ (> minutes 0)))))
+ (format "+%d:%02d" (- hours 24) minutes))
+ ((guard org-agenda-time-leading-zero)
+ (format "%02d:%02d" hours minutes))
+ (_
+ (format "%d:%02d" hours minutes))))))))
(defvar org-agenda-before-sorting-filter-function nil
"Function to be applied to agenda items prior to sorting.
@@ -6980,8 +7075,8 @@ The optional argument TYPE tells the agenda type."
(delq nil
(mapcar
org-agenda-before-sorting-filter-function list))))
- (setq list (mapcar 'org-agenda-highlight-todo list)
- list (mapcar 'identity (sort list 'org-entries-lessp)))
+ (setq list (mapcar #'org-agenda-highlight-todo list)
+ list (mapcar #'identity (sort list #'org-entries-lessp)))
(when max-effort
(setq list (org-agenda-limit-entries
list 'effort-minutes max-effort
@@ -6995,7 +7090,7 @@ The optional argument TYPE tells the agenda type."
(setq list (org-agenda-limit-entries list 'org-hd-marker max-entries)))
(when (and org-agenda-dim-blocked-tasks org-blocker-hook)
(setq list (mapcar #'org-agenda--mark-blocked-entry list)))
- (mapconcat 'identity list "\n")))
+ (mapconcat #'identity list "\n")))
(defun org-agenda-limit-entries (list prop limit &optional fn)
"Limit the number of agenda entries."
@@ -7081,13 +7176,14 @@ The optional argument TYPE tells the agenda type."
(setq x
(concat
(substring x 0 (match-end 1))
- (format org-agenda-todo-keyword-format
- (match-string 2 x))
- ;; Remove `display' property as the icon could leak
+ (unless (string= org-agenda-todo-keyword-format "")
+ (format org-agenda-todo-keyword-format
+ (match-string 2 x)))
+ ;; Remove `display' property as the icon could leak
;; on the white space.
(org-add-props " " (org-plist-delete (text-properties-at 0 x)
- 'display))
- (substring x (match-end 3)))))))
+ 'display))
+ (substring x (match-end 3)))))))
x)))
(defsubst org-cmp-values (a b property)
@@ -7210,8 +7306,9 @@ their type."
"Predicate for sorting agenda entries."
;; The following variables will be used when the form is evaluated.
;; So even though the compiler complains, keep them.
- (let* ((ss org-agenda-sorting-strategy-selected)
- (timestamp-up (and (org-em 'timestamp-up 'timestamp-down ss)
+ (let ((ss org-agenda-sorting-strategy-selected))
+ (org-dlet
+ ((timestamp-up (and (org-em 'timestamp-up 'timestamp-down ss)
(org-cmp-ts a b "")))
(timestamp-down (if timestamp-up (- timestamp-up) nil))
(scheduled-up (and (org-em 'scheduled-up 'scheduled-down ss)
@@ -7257,14 +7354,14 @@ their type."
(alpha-down (if alpha-up (- alpha-up) nil))
(need-user-cmp (org-em 'user-defined-up 'user-defined-down ss))
user-defined-up user-defined-down)
- (when (and need-user-cmp org-agenda-cmp-user-defined
- (functionp org-agenda-cmp-user-defined))
- (setq user-defined-up
- (funcall org-agenda-cmp-user-defined a b)
- user-defined-down (if user-defined-up (- user-defined-up) nil)))
- (cdr (assoc
- (eval (cons 'or org-agenda-sorting-strategy-selected))
- '((-1 . t) (1 . nil) (nil . nil))))))
+ (when (and need-user-cmp org-agenda-cmp-user-defined
+ (functionp org-agenda-cmp-user-defined))
+ (setq user-defined-up
+ (funcall org-agenda-cmp-user-defined a b)
+ user-defined-down (if user-defined-up (- user-defined-up) nil)))
+ (cdr (assoc
+ (eval (cons 'or org-agenda-sorting-strategy-selected) t)
+ '((-1 . t) (1 . nil) (nil . nil)))))))
;;; Agenda restriction lock
@@ -7299,7 +7396,7 @@ When in a restricted subtree, remove it.
The restriction will span over the entire file if TYPE is `file',
or if type is '(4), or if the cursor is before the first headline
-in the file. Otherwise, only apply the restriction to the current
+in the file. Otherwise, only apply the restriction to the current
subtree."
(interactive "P")
(if (and org-agenda-overriding-restriction
@@ -7466,7 +7563,7 @@ This is used when toggling sticky agendas."
(dolist (buf (buffer-list))
(when (with-current-buffer buf (eq major-mode 'org-agenda-mode))
(push buf blist)))
- (mapc 'kill-buffer blist)))
+ (mapc #'kill-buffer blist)))
(defun org-agenda-execute (arg)
"Execute another agenda command, keeping same window.
@@ -7479,6 +7576,7 @@ in the agenda."
(defun org-agenda-redo (&optional all)
"Rebuild possibly ALL agenda view(s) in the current buffer."
(interactive "P")
+ (defvar org-agenda-tag-filter-while-redo) ;FIXME: Where is this var used?
(let* ((p (or (and (looking-at "\\'") (1- (point))) (point)))
(cpa (unless (eq all t) current-prefix-arg))
(org-agenda-doing-sticky-redo org-agenda-sticky)
@@ -7517,8 +7615,11 @@ in the agenda."
(and cols (org-columns-quit))
(message "Rebuilding agenda buffer...")
(if series-redo-cmd
- (eval series-redo-cmd)
- (org-let lprops redo-cmd))
+ (eval series-redo-cmd t)
+ (cl-progv
+ (mapcar #'car lprops)
+ (mapcar (lambda (binding) (eval (cadr binding) t)) lprops)
+ (eval redo-cmd t)))
(setq org-agenda-undo-list nil
org-agenda-pending-undo-list nil
org-agenda-tag-filter tag-filter
@@ -7720,7 +7821,7 @@ A single `\\[universal-argument]' prefix arg STRIP-OR-ACCUMULATE will negate the
entire filter, which can be useful in connection with the prompt history.
A double `\\[universal-argument] \\[universal-argument]' prefix arg will add the new filter elements to the
-existing ones. A shortcut for this is to add an additional `+' at the
+existing ones. A shortcut for this is to add an additional `+' at the
beginning of the string, like `+-John'.
With a triple prefix argument, execute the computed filtering defined in
@@ -7744,7 +7845,7 @@ the variable `org-agenda-auto-exclude-function'."
(negate (equal strip-or-accumulate '(4)))
(cf (mapconcat #'identity org-agenda-category-filter ""))
(tf (mapconcat #'identity org-agenda-tag-filter ""))
- (rpl-fn (lambda (c) (replace-regexp-in-string "^\\+" "" (or (car c) ""))))
+ ;; (rpl-fn (lambda (c) (replace-regexp-in-string "^\\+" "" (or (car c) ""))))
(ef (replace-regexp-in-string "^\\+" "" (or (car org-agenda-effort-filter) "")))
(rf (replace-regexp-in-string "^\\+" "" (or (car org-agenda-regexp-filter) "")))
(ff (concat cf tf ef (when (not (equal rf "")) (concat "/" rf "/"))))
@@ -7752,7 +7853,7 @@ the variable `org-agenda-auto-exclude-function'."
(concat
(if negate "Negative filter" "Filter")
" [+cat-tag<0:10-/regexp/]: ")
- 'org-agenda-filter-completion-function
+ #'org-agenda-filter-completion-function
nil nil ff))
(keep (or (if (string-match "^\\+[+-]" f-string)
(progn (setq f-string (substring f-string 1)) t))
@@ -7778,20 +7879,20 @@ the variable `org-agenda-auto-exclude-function'."
"~~~" "-" (match-string 3 f-string)))
(cond
((member s tag-list)
- (add-to-list 'ft (concat pm s) 'append 'equal))
+ (org-pushnew-to-end (concat pm s) ft))
((member s category-list)
- (add-to-list 'fc (concat pm ; Remove temporary double quotes.
- (replace-regexp-in-string "\"\\(.*\\)\"" "\\1" s))
- 'append 'equal))
+ (org-pushnew-to-end (concat pm ; Remove temporary double quotes.
+ (replace-regexp-in-string "\"\\(.*\\)\"" "\\1" s))
+ fc))
(t (message
"`%s%s' filter ignored because tag/category is not represented"
pm s))))
((match-beginning 4)
;; effort
- (add-to-list 'fe (concat pm (match-string 4 f-string)) t 'equal))
+ (org-pushnew-to-end (concat pm (match-string 4 f-string)) fe))
((match-beginning 5)
;; regexp
- (add-to-list 'fr (concat pm (match-string 6 f-string)) t 'equal)))
+ (org-pushnew-to-end (concat pm (match-string 6 f-string)) fr)))
(setq f-string (substring f-string (match-end 0))))
(org-agenda-filter-remove-all)
(and fc (org-agenda-filter-apply
@@ -7871,7 +7972,7 @@ With a `\\[universal-argument] \\[universal-argument] \\[universal-argument]' pr
i.e. don't
filter on all its group members.
-A lisp caller can specify CHAR. EXCLUDE means that the new tag
+A Lisp caller can specify CHAR. EXCLUDE means that the new tag
should be used to exclude the search - the interactive user can
also press `-' or `+' to switch between filtering and excluding."
(interactive "P")
@@ -7893,7 +7994,7 @@ also press `-' or `+' to switch between filtering and excluding."
(expand (not (equal strip-or-accumulate '(64))))
(inhibit-read-only t)
(current org-agenda-tag-filter)
- a n tag)
+ a tag) ;; n
(unless char
(while (not (memq char valid-char-list))
(org-unlogged-message
@@ -7974,19 +8075,20 @@ These will be lower-case, for filtering."
(if tt (push tt tags-lists)))
(setq tags-lists
(nreverse (org-uniquify
- (delq nil (apply 'append tags-lists)))))
+ (delq nil (apply #'append tags-lists)))))
(dolist (tag tags-lists)
(mapc
(lambda (group)
- (when (member tag (mapcar #'downcase group))
- (push (downcase (car group)) tags-lists)))
+ (when (member tag group)
+ (push (car group) tags-lists)))
org-tag-groups-alist-for-agenda))
(setq org-agenda-represented-tags tags-lists)))))
(defun org-agenda-filter-make-matcher (filter type &optional expand)
- "Create the form that tests a line for agenda filter. Optional
-argument EXPAND can be used for the TYPE tag and will expand the
-tags in the FILTER if any of the tags in FILTER are grouptags."
+ "Create the form that tests a line for agenda filter.
+Optional argument EXPAND can be used for the TYPE tag and will
+expand the tags in the FILTER if any of the tags in FILTER are
+grouptags."
(let ((multi-pos-cats
(and (eq type 'category)
(string-match-p "\\+.*\\+"
@@ -8053,7 +8155,7 @@ function to set the right switches in the returned form."
((and (string-match-p "\\`{" tag) (string-match-p "}\\'" tag))
;; TAG is a regexp.
(list 'org-match-any-p (substring tag 1 -1) 'tags))
- (t (list 'member (downcase tag) 'tags)))))
+ (t (list 'member tag 'tags)))))
(push (if (eq op ?-) (list 'not f) f) form)))))
(defun org-agenda-filter-effort-form (e)
@@ -8084,7 +8186,7 @@ If the line does not have an effort defined, return nil."
When NO-OPERATOR is non-nil, do not add the + operator to
returned tags."
(if org-group-tags
- (let ((case-fold-search t) rtn)
+ (let (case-fold-search rtn)
(mapc
(lambda (f)
(let (f0 dir)
@@ -8092,7 +8194,7 @@ returned tags."
(setq dir (match-string 1 f) f0 (match-string 2 f))
(setq dir (if no-operator "" "+") f0 f))
(setq rtn (append (mapcar (lambda(f1) (concat dir f1))
- (org-tags-expand f0 t t))
+ (org-tags-expand f0 t))
rtn))))
filter)
(reverse rtn))
@@ -8118,10 +8220,11 @@ grouptags."
(while (not (eobp))
(when (or (org-get-at-bol 'org-hd-marker)
(org-get-at-bol 'org-marker))
- (let ((tags (org-get-at-bol 'tags))
- (cat (org-agenda-get-category))
- (txt (or (org-get-at-bol 'txt) "")))
- (unless (eval org-agenda-filter-form)
+ (org-dlet
+ ((tags (org-get-at-bol 'tags))
+ (cat (org-agenda-get-category))
+ (txt (or (org-get-at-bol 'txt) "")))
+ (unless (eval org-agenda-filter-form t)
(org-agenda-filter-hide-line type))))
(beginning-of-line 2)))
(when (get-char-property (point) 'invisible)
@@ -8231,13 +8334,13 @@ Negative selection means regexp must not match for selection of an entry."
(defun org-add-to-string (var string)
(set var (concat (symbol-value var) string)))
-(defun org-agenda-goto-date (span)
+(defun org-agenda-goto-date (date)
"Jump to DATE in agenda."
- (interactive "P")
- (let* ((org-read-date-prefer-future
- (eval org-agenda-jump-prefer-future))
- (date (org-read-date))
- (day (time-to-days (org-time-string-to-time date)))
+ (interactive
+ (list
+ (let ((org-read-date-prefer-future org-agenda-jump-prefer-future))
+ (org-read-date))))
+ (let* ((day (time-to-days (org-time-string-to-time date)))
(org-agenda-sticky-orig org-agenda-sticky)
(org-agenda-buffer-tmp-name (buffer-name))
(args (get-text-property (min (1- (point-max)) (point)) 'org-last-args))
@@ -8304,12 +8407,12 @@ When optional argument BACKWARD is set, go backward."
"Cannot execute this command outside of org-agenda-mode buffers"))
((looking-at (if backward "\\`" "\\'"))
(message "Already at the %s block" (if backward "first" "last")))
- (t (let ((pos (prog1 (point)
- (ignore-errors (if backward (backward-char 1)
- (move-end-of-line 1)))))
+ (t (let ((_pos (prog1 (point)
+ (ignore-errors (if backward (backward-char 1)
+ (move-end-of-line 1)))))
(f (if backward
- 'previous-single-property-change
- 'next-single-property-change))
+ #'previous-single-property-change
+ #'next-single-property-change))
moved dest)
(while (and (setq dest (funcall
f (point) 'org-agenda-structural-header))
@@ -8327,7 +8430,8 @@ When optional argument BACKWARD is set, go backward."
With prefix ARG, go forward that many times the current span."
(interactive "p")
(org-agenda-check-type t 'agenda)
- (let* ((args (get-text-property (min (1- (point-max)) (point)) 'org-last-args))
+ (let* ((wstart (window-start))
+ (args (get-text-property (min (1- (point-max)) (point)) 'org-last-args))
(span (or (nth 2 args) org-agenda-current-span))
(sd (or (nth 1 args) (org-get-at-bol 'day) org-starting-day))
(greg (calendar-gregorian-from-absolute sd))
@@ -8360,7 +8464,8 @@ With prefix ARG, go forward that many times the current span."
(org-agenda-overriding-arguments
(list (car args) sd span)))
(org-agenda-redo)
- (org-agenda-find-same-or-today-or-agenda cnt))))
+ (org-agenda-find-same-or-today-or-agenda cnt))
+ (set-window-start nil wstart)))
(defun org-agenda-earlier (arg)
"Go backward in time by the current span.
@@ -8480,7 +8585,7 @@ SPAN may be `day', `week', `fortnight', `month', `year'. The return value
is a cons cell with the starting date and the number of days,
so that the date SD will be in that range."
(let* ((greg (calendar-gregorian-from-absolute sd))
- (dg (nth 1 greg))
+ ;; (dg (nth 1 greg))
(mg (car greg))
(yg (nth 2 greg)))
(cond
@@ -8552,7 +8657,7 @@ so that the date SD will be in that range."
(defun org-unhighlight-once ()
"Remove the highlight from its position, and this function from the hook."
- (remove-hook 'pre-command-hook 'org-unhighlight-once)
+ (remove-hook 'pre-command-hook #'org-unhighlight-once)
(org-unhighlight))
(defvar org-agenda-pre-follow-window-conf nil)
@@ -8689,7 +8794,8 @@ When called with a prefix argument, include all archive files as well."
(if org-agenda-include-deadlines " Ddl" "")
(if org-agenda-use-time-grid " Grid" "")
(if (and (boundp 'org-habit-show-habits)
- org-habit-show-habits) " Habit" "")
+ org-habit-show-habits)
+ " Habit" "")
(cond
((consp org-agenda-show-log) " LogAll")
((eq org-agenda-show-log 'clockcheck) " ClkCk")
@@ -8701,36 +8807,39 @@ When called with a prefix argument, include all archive files as well."
'(:eval (propertize
(concat "["
(mapconcat
- 'identity
+ #'identity
(append
(get 'org-agenda-category-filter :preset-filter)
org-agenda-category-filter)
"")
"]")
'face 'org-agenda-filter-category
- 'help-echo "Category used in filtering")) "")
+ 'help-echo "Category used in filtering"))
+ "")
(if (or org-agenda-tag-filter
(get 'org-agenda-tag-filter :preset-filter))
'(:eval (propertize
(concat (mapconcat
- 'identity
+ #'identity
(append
(get 'org-agenda-tag-filter :preset-filter)
org-agenda-tag-filter)
""))
'face 'org-agenda-filter-tags
- 'help-echo "Tags used in filtering")) "")
+ 'help-echo "Tags used in filtering"))
+ "")
(if (or org-agenda-effort-filter
(get 'org-agenda-effort-filter :preset-filter))
'(:eval (propertize
(concat (mapconcat
- 'identity
+ #'identity
(append
(get 'org-agenda-effort-filter :preset-filter)
org-agenda-effort-filter)
""))
'face 'org-agenda-filter-effort
- 'help-echo "Effort conditions used in filtering")) "")
+ 'help-echo "Effort conditions used in filtering"))
+ "")
(if (or org-agenda-regexp-filter
(get 'org-agenda-regexp-filter :preset-filter))
'(:eval (propertize
@@ -8741,7 +8850,8 @@ When called with a prefix argument, include all archive files as well."
org-agenda-regexp-filter)
""))
'face 'org-agenda-filter-regexp
- 'help-echo "Regexp used in filtering")) "")
+ 'help-echo "Regexp used in filtering"))
+ "")
(if org-agenda-archives-mode
(if (eq org-agenda-archives-mode t)
" Archives"
@@ -8772,7 +8882,7 @@ When called with a prefix argument, include all archive files as well."
"Move cursor to next agenda item."
(interactive "p")
(let ((col (current-column)))
- (dotimes (c n)
+ (dotimes (_ n)
(when (next-single-property-change (point-at-eol) 'org-marker)
(move-end-of-line 1)
(goto-char (next-single-property-change (point) 'org-marker))))
@@ -8782,7 +8892,7 @@ When called with a prefix argument, include all archive files as well."
(defun org-agenda-previous-item (n)
"Move cursor to next agenda item."
(interactive "p")
- (dotimes (c n)
+ (dotimes (_ n)
(let ((col (current-column))
(goto (save-excursion
(move-end-of-line 0)
@@ -8808,7 +8918,7 @@ When called with a prefix argument, include all archive files as well."
(let* ((tags (org-get-at-bol 'tags)))
(if tags
(message "Tags are :%s:"
- (org-no-properties (mapconcat 'identity tags ":")))
+ (org-no-properties (mapconcat #'identity tags ":")))
(message "No tags associated with this line"))))
(defun org-agenda-goto (&optional highlight)
@@ -8842,7 +8952,7 @@ Point is in the buffer where the item originated.")
(defun org-agenda-do-in-region (beg end cmd &optional arg force-arg delete)
"Between region BEG and END, call agenda command CMD.
-When optional argument ARG is non-nil or FORCE-ARG is `t', pass
+When optional argument ARG is non-nil or FORCE-ARG is t, pass
ARG to CMD. When optional argument DELETE is non-nil, assume CMD
deletes the agenda entry and don't move to the next entry."
(save-excursion
@@ -8949,6 +9059,8 @@ Pass ARG, FORCE-ARG, DELETE and BODY to `org-agenda-do-in-region'."
(funcall-interactively
#'org-agenda-archive-with 'org-archive-to-archive-sibling))
+(defvar org-archive-from-agenda)
+
(defun org-agenda-archive-with (cmd &optional confirm)
"Move the entry to the archive sibling."
(interactive)
@@ -9025,7 +9137,7 @@ When NO-UPDATE is non-nil, don't redo the agenda buffer."
(marker (or (org-get-at-bol 'org-hd-marker)
(org-agenda-error)))
(buffer (marker-buffer marker))
- (pos (marker-position marker))
+ ;; (pos (marker-position marker))
(rfloc (or rfloc
(org-refile-get-location
(if goto "Goto" "Refile to") buffer
@@ -9311,6 +9423,8 @@ by a remote command from the agenda.")
(interactive)
(org-agenda-todo 'previousset))
+(defvar org-agenda-headline-snapshot-before-repeat)
+
(defun org-agenda-todo (&optional arg)
"Cycle TODO state of line at point, also in Org file.
This changes the line at point, all other lines in the agenda referring to
@@ -9335,11 +9449,14 @@ the same tree node, and the headline of the tree node in the Org file."
(goto-char pos)
(org-show-context 'agenda)
(let ((current-prefix-arg arg))
- (call-interactively 'org-todo))
+ (call-interactively 'org-todo)
+ ;; Make sure that log is recorded in current undo.
+ (when (and org-log-setup
+ (not (eq org-log-note-how 'note)))
+ (org-add-log-note)))
(and (bolp) (forward-char 1))
(setq newhead (org-get-heading))
- (when (and (bound-and-true-p
- org-agenda-headline-snapshot-before-repeat)
+ (when (and org-agenda-headline-snapshot-before-repeat
(not (equal org-agenda-headline-snapshot-before-repeat
newhead))
todayp)
@@ -9358,15 +9475,15 @@ the same tree node, and the headline of the tree node in the Org file."
(org-move-to-column col)
(org-agenda-mark-clocking-task)))))
-(defun org-agenda-add-note (&optional arg)
+(defun org-agenda-add-note (&optional _arg)
"Add a time-stamped note to the entry at point."
- (interactive "P")
+ (interactive) ;; "P"
(org-agenda-check-no-diary)
(let* ((marker (or (org-get-at-bol 'org-marker)
(org-agenda-error)))
(buffer (marker-buffer marker))
(pos (marker-position marker))
- (hdmarker (org-get-at-bol 'org-hd-marker))
+ (_hdmarker (org-get-at-bol 'org-hd-marker))
(inhibit-read-only t))
(with-current-buffer buffer
(widen)
@@ -9389,7 +9506,7 @@ If FORCE-TAGS is non-nil, the car of it returns the new tags."
(org-agenda-buffer (current-buffer))
(thetags (with-current-buffer (marker-buffer hdmarker)
(org-get-tags hdmarker)))
- props m pl undone-face done-face finish new dotime level cat tags)
+ props m undone-face done-face finish new dotime level cat tags) ;; pl
(save-excursion
(goto-char (point-max))
(beginning-of-line 1)
@@ -9411,7 +9528,7 @@ If FORCE-TAGS is non-nil, the car of it returns the new tags."
(with-current-buffer (marker-buffer hdmarker)
(org-with-wide-buffer
(org-agenda-format-item extra newhead level cat tags dotime))))
- pl (text-property-any (point-at-bol) (point-at-eol) 'org-heading t)
+ ;; pl (text-property-any (point-at-bol) (point-at-eol) 'org-heading t)
undone-face (org-get-at-bol 'undone-face)
done-face (org-get-at-bol 'done-face))
(beginning-of-line 1)
@@ -9490,33 +9607,35 @@ current line."
(defun org-agenda-priority (&optional force-direction)
"Set the priority of line at point, also in Org file.
-This changes the line at point, all other lines in the agenda referring to
-the same tree node, and the headline of the tree node in the Org file.
-Called with a universal prefix arg, show the priority instead of setting it."
+This changes the line at point, all other lines in the agenda
+referring to the same tree node, and the headline of the tree
+node in the Org file.
+
+Called with one universal prefix arg, show the priority instead
+of setting it.
+
+When called programmatically, FORCE-DIRECTION can be `set', `up',
+`down', or a character."
(interactive "P")
- (if (equal force-direction '(4))
- (org-priority-show)
- (unless org-priority-enable-commands
- (user-error "Priority commands are disabled"))
- (org-agenda-check-no-diary)
- (let* ((col (current-column))
- (marker (or (org-get-at-bol 'org-marker)
- (org-agenda-error)))
- (hdmarker (org-get-at-bol 'org-hd-marker))
- (buffer (marker-buffer hdmarker))
- (pos (marker-position hdmarker))
- (inhibit-read-only t)
- newhead)
- (org-with-remote-undo buffer
- (with-current-buffer buffer
- (widen)
- (goto-char pos)
- (org-show-context 'agenda)
- (org-priority force-direction)
- (end-of-line 1)
- (setq newhead (org-get-heading)))
- (org-agenda-change-all-lines newhead hdmarker)
- (org-move-to-column col)))))
+ (unless org-priority-enable-commands
+ (user-error "Priority commands are disabled"))
+ (org-agenda-check-no-diary)
+ (let* ((col (current-column))
+ (hdmarker (org-get-at-bol 'org-hd-marker))
+ (buffer (marker-buffer hdmarker))
+ (pos (marker-position hdmarker))
+ (inhibit-read-only t)
+ newhead)
+ (org-with-remote-undo buffer
+ (with-current-buffer buffer
+ (widen)
+ (goto-char pos)
+ (org-show-context 'agenda)
+ (org-priority force-direction)
+ (end-of-line 1)
+ (setq newhead (org-get-heading)))
+ (org-agenda-change-all-lines newhead hdmarker)
+ (org-move-to-column col))))
;; FIXME: should fix the tags property of the agenda line.
(defun org-agenda-set-tags (&optional tag onoff)
@@ -9555,7 +9674,7 @@ Called with a universal prefix arg, show the priority instead of setting it."
(buffer (marker-buffer hdmarker))
(pos (marker-position hdmarker))
(inhibit-read-only t)
- newhead)
+ ) ;; newhead
(org-with-remote-undo buffer
(with-current-buffer buffer
(widen)
@@ -9716,7 +9835,12 @@ Called with a universal prefix arg, show the priority instead of setting it."
(line-end-position)
'(display nil))
(org-move-to-column
- (- (/ (window-width nil t) (window-font-width)) (length stamp)) t)
+ (- (if (fboundp 'window-font-width)
+ (/ (window-width nil t) (window-font-width))
+ ;; Fall back to pre-9.3.3 behavior on Emacs <25.
+ (window-width))
+ (length stamp))
+ t)
(add-text-properties
(1- (point)) (point-at-eol)
(list 'display (org-add-props stamp nil
@@ -9756,7 +9880,7 @@ ARG is passed through to `org-schedule'."
#'org-agenda-schedule arg t nil
(let* ((marker (or (org-get-at-bol 'org-marker)
(org-agenda-error)))
- (type (marker-insertion-type marker))
+ ;; (type (marker-insertion-type marker))
(buffer (marker-buffer marker))
(pos (marker-position marker))
ts)
@@ -9831,9 +9955,9 @@ ARG is passed through to `org-deadline'."
(org-move-to-column col)
(org-agenda-unmark-clocking-task)))
-(defun org-agenda-clock-cancel (&optional arg)
+(defun org-agenda-clock-cancel (&optional _arg)
"Cancel the currently running clock."
- (interactive "P")
+ (interactive) ;; "P"
(unless (marker-buffer org-clock-marker)
(user-error "No running clock"))
(org-with-remote-undo (marker-buffer org-clock-marker)
@@ -10077,7 +10201,7 @@ entries in that Org file."
(unwind-protect
(progn
(fset 'calendar-cursor-to-date
- (lambda (&optional error dummy)
+ (lambda (&optional _error _dummy)
(calendar-gregorian-from-absolute
(get-text-property point 'day))))
(call-interactively cmd))
@@ -10092,18 +10216,19 @@ entries in that Org file."
(let* ((oldf (symbol-function 'calendar-cursor-to-date))
(point (point))
(date (calendar-gregorian-from-absolute
- (get-text-property point 'day)))
- ;; the following 2 vars are needed in the calendar
- (displayed-month (car date))
+ (get-text-property point 'day))))
+ ;; the following 2 vars are needed in the calendar
+ (org-dlet
+ ((displayed-month (car date))
(displayed-year (nth 2 date)))
- (unwind-protect
- (progn
- (fset 'calendar-cursor-to-date
- (lambda (&optional error dummy)
- (calendar-gregorian-from-absolute
- (get-text-property point 'day))))
- (call-interactively cmd))
- (fset 'calendar-cursor-to-date oldf))))
+ (unwind-protect
+ (progn
+ (fset 'calendar-cursor-to-date
+ (lambda (&optional _error _dummy)
+ (calendar-gregorian-from-absolute
+ (get-text-property point 'day))))
+ (call-interactively cmd))
+ (fset 'calendar-cursor-to-date oldf)))))
(defun org-agenda-phases-of-moon ()
"Display the phases of the moon for the 3 months around the cursor date."
@@ -10208,7 +10333,7 @@ When ARG is greater than one mark ARG lines."
(setq arg (count-lines (region-beginning) (region-end)))
(goto-char (region-beginning))
(deactivate-mark))
- (dotimes (i (or arg 1))
+ (dotimes (_ (or arg 1))
(unless (org-get-at-bol 'org-agenda-diary-link)
(let* ((m (org-get-at-bol 'org-hd-marker))
ov)
@@ -10405,7 +10530,7 @@ The prefix arg is passed through to the command if possible."
(find-buffer-visiting (nth 1 refile-location))
(error "This should not happen")))))
- (setq cmd `(lambda () (org-agenda-refile nil ',refile-location t)))
+ (setq cmd (lambda () (org-agenda-refile nil refile-location t)))
(setq redo-at-end t)))
(?t
@@ -10413,10 +10538,10 @@ The prefix arg is passed through to the command if possible."
"Todo state: "
(with-current-buffer (marker-buffer (car entries))
(mapcar #'list org-todo-keywords-1)))))
- (setq cmd `(lambda ()
- (let ((org-inhibit-blocking t)
- (org-inhibit-logging 'note))
- (org-agenda-todo ,state))))))
+ (setq cmd (lambda ()
+ (let ((org-inhibit-blocking t)
+ (org-inhibit-logging 'note))
+ (org-agenda-todo state))))))
((and (or ?- ?+) action)
(let ((tag (completing-read
@@ -10426,9 +10551,9 @@ The prefix arg is passed through to the command if possible."
(mapcar (lambda (x) (and (stringp (car x)) x))
org-current-tag-alist))))))
(setq cmd
- `(lambda ()
- (org-agenda-set-tags ,tag
- ,(if (eq action ?+) ''on ''off))))))
+ (lambda ()
+ (org-agenda-set-tags tag
+ (if (eq action ?+) 'on 'off))))))
((and (or ?s ?d) c)
(let* ((schedule? (eq c ?s))
@@ -10450,13 +10575,13 @@ The prefix arg is passed through to the command if possible."
;; depending on the number of marked items.
(setq cmd
(if schedule?
- `(lambda ()
- (let ((org-log-reschedule
- (and org-log-reschedule 'time)))
- (org-agenda-schedule arg ,time)))
- `(lambda ()
- (let ((org-log-redeadline (and org-log-redeadline 'time)))
- (org-agenda-deadline arg ,time)))))))
+ (lambda ()
+ (let ((org-log-reschedule
+ (and org-log-reschedule 'time)))
+ (org-agenda-schedule arg time)))
+ (lambda ()
+ (let ((org-log-redeadline (and org-log-redeadline 'time)))
+ (org-agenda-deadline arg time)))))))
(?S
(unless (org-agenda-check-type nil 'agenda 'todo)
@@ -10466,29 +10591,29 @@ The prefix arg is passed through to the command if possible."
(if arg "week" ""))
7)))
(setq cmd
- `(lambda ()
- (let ((distance (1+ (random ,days))))
- (when arg
- (let ((dist distance)
- (day-of-week
- (calendar-day-of-week
- (calendar-gregorian-from-absolute (org-today)))))
- (dotimes (i (1+ dist))
- (while (member day-of-week org-agenda-weekend-days)
- (cl-incf distance)
- (cl-incf day-of-week)
- (when (= day-of-week 7)
- (setq day-of-week 0)))
- (cl-incf day-of-week)
- (when (= day-of-week 7)
- (setq day-of-week 0)))))
- ;; Silently fail when try to replan a sexp entry.
- (ignore-errors
- (let* ((date (calendar-gregorian-from-absolute
- (+ (org-today) distance)))
- (time (encode-time 0 0 0 (nth 1 date) (nth 0 date)
- (nth 2 date))))
- (org-agenda-schedule nil time))))))))
+ (lambda ()
+ (let ((distance (1+ (random days))))
+ (when arg
+ (let ((dist distance)
+ (day-of-week
+ (calendar-day-of-week
+ (calendar-gregorian-from-absolute (org-today)))))
+ (dotimes (_ (1+ dist))
+ (while (member day-of-week org-agenda-weekend-days)
+ (cl-incf distance)
+ (cl-incf day-of-week)
+ (when (= day-of-week 7)
+ (setq day-of-week 0)))
+ (cl-incf day-of-week)
+ (when (= day-of-week 7)
+ (setq day-of-week 0)))))
+ ;; Silently fail when try to replan a sexp entry.
+ (ignore-errors
+ (let* ((date (calendar-gregorian-from-absolute
+ (+ (org-today) distance)))
+ (time (encode-time 0 0 0 (nth 1 date) (nth 0 date)
+ (nth 2 date))))
+ (org-agenda-schedule nil time))))))))
(?f
(setq cmd
@@ -10496,10 +10621,15 @@ The prefix arg is passed through to the command if possible."
(completing-read "Function: " obarray #'fboundp t nil nil))))
(action
- (pcase (assoc action org-agenda-bulk-custom-functions)
- (`(,_ ,f) (setq cmd f) (setq redo-at-end t))
- (_ (user-error "Invalid bulk action: %c" action)))))
-
+ (setq cmd
+ (pcase (assoc action org-agenda-bulk-custom-functions)
+ (`(,_ ,fn)
+ fn)
+ (`(,_ ,fn ,arg-fn)
+ (apply #'apply-partially fn (funcall arg-fn)))
+ (_
+ (user-error "Invalid bulk action: %c" action))))
+ (setq redo-at-end t)))
;; Sort the markers, to make sure that parents are handled
;; before children.
(setq entries (sort entries
@@ -10523,9 +10653,7 @@ The prefix arg is passed through to the command if possible."
(let (org-loop-over-headlines-in-active-region) (funcall cmd))
;; `post-command-hook' is not run yet. We make sure any
;; pending log note is processed.
- (when (or (memq 'org-add-log-note (default-value 'post-command-hook))
- (memq 'org-add-log-note post-command-hook))
- (org-add-log-note))
+ (when org-log-setup (org-add-log-note))
(cl-incf processed))))
(when redo-at-end (org-agenda-redo))
(unless org-agenda-persistent-marks (org-agenda-bulk-unmark-all))
@@ -10570,7 +10698,7 @@ When the optional argument `backward' is non-nil, move backward."
(let ((inhibit-read-only t) lst line)
(if (or (not (get-text-property (point) 'txt))
(save-excursion
- (dotimes (n arg)
+ (dotimes (_ arg)
(move-beginning-of-line (if backward 0 2))
(push (not (get-text-property (point) 'txt)) lst))
(delq nil lst)))
@@ -10599,7 +10727,7 @@ tag and (if present) the flagging note."
(interactive)
(let ((hdmarker (org-get-at-bol 'org-hd-marker))
(win (selected-window))
- note heading newhead)
+ note) ;; heading newhead
(unless hdmarker
(user-error "No linked entry at point"))
(if (and (eq this-command last-command)
@@ -10627,11 +10755,11 @@ tag and note")))))
(defun org-agenda-remove-flag (marker)
"Remove the FLAGGED tag and any flagging note in the entry."
- (let (newhead)
- (org-with-point-at marker
- (org-toggle-tag "FLAGGED" 'off)
- (org-entry-delete nil "THEFLAGGINGNOTE")
- (setq newhead (org-get-heading)))
+ (let ((newhead
+ (org-with-point-at marker
+ (org-toggle-tag "FLAGGED" 'off)
+ (org-entry-delete nil "THEFLAGGINGNOTE")
+ (org-get-heading))))
(org-agenda-change-all-lines newhead marker)
(message "Entry unflagged")))
@@ -10699,7 +10827,7 @@ to override `appt-message-warning-time'."
(setq entries
(delq nil
(append entries
- (apply 'org-agenda-get-day-entries
+ (apply #'org-agenda-get-day-entries
file today scope)))))
;; Map through entries and find if we should filter them out
(mapc
diff --git a/lisp/org/org-archive.el b/lisp/org/org-archive.el
index 73cd83ebf33..0943869a882 100644
--- a/lisp/org/org-archive.el
+++ b/lisp/org/org-archive.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
diff --git a/lisp/org/org-attach-git.el b/lisp/org/org-attach-git.el
index 2091cbc610c..4c6bdc90239 100644
--- a/lisp/org/org-attach-git.el
+++ b/lisp/org/org-attach-git.el
@@ -24,7 +24,7 @@
;;; Commentary:
;; An extension to org-attach. If `org-attach-id-dir' is initialized
-;; as a Git repository, then org-attach-git will automatically commit
+;; as a Git repository, then `org-attach-git' will automatically commit
;; changes when it sees them. Requires git-annex.
;;; Code:
@@ -52,9 +52,25 @@ If \\='ask, prompt using `y-or-n-p'. If t, always get. If nil, never get."
(const :tag "always get from annex if necessary" t)
(const :tag "never get from annex" nil)))
+(defcustom org-attach-git-dir 'default
+ "Attachment directory with the Git repository to use.
+The default value is to use `org-attach-id-dir'. When set to
+`individual-repository', then the directory attached to the
+current node, if correctly initialized as a Git repository, will
+be used instead."
+ :group 'org-attach
+ :package-version '(Org . "9.5")
+ :type '(choice
+ (const :tag "Default" default)
+ (const :tag "Individual repository" individual-repository)))
+
(defun org-attach-git-use-annex ()
"Return non-nil if git annex can be used."
- (let ((git-dir (vc-git-root (expand-file-name org-attach-id-dir))))
+ (let ((git-dir (vc-git-root
+ (cond ((eq org-attach-git-dir 'default)
+ (expand-file-name org-attach-id-dir))
+ ((eq org-attach-git-dir 'individual-repository)
+ (org-attach-dir))))))
(and org-attach-git-annex-cutoff
(or (file-exists-p (expand-file-name "annex" git-dir))
(file-exists-p (expand-file-name ".git/annex" git-dir))))))
@@ -62,7 +78,11 @@ If \\='ask, prompt using `y-or-n-p'. If t, always get. If nil, never get."
(defun org-attach-git-annex-get-maybe (path)
"Call git annex get PATH (via shell) if using git annex.
Signals an error if the file content is not available and it was not retrieved."
- (let* ((default-directory (expand-file-name org-attach-id-dir))
+ (let* ((default-directory
+ (cond ((eq org-attach-git-dir 'default)
+ (expand-file-name org-attach-id-dir))
+ ((eq org-attach-git-dir 'individual-repository)
+ (org-attach-dir))))
(path-relative (file-relative-name path)))
(when (and (org-attach-git-use-annex)
(not
@@ -86,7 +106,10 @@ This checks for the existence of a \".git\" directory in that directory.
Takes an unused optional argument for the sake of being compatible
with hook `org-attach-after-change-hook'."
- (let* ((dir (expand-file-name org-attach-id-dir))
+ (let* ((dir (cond ((eq org-attach-git-dir 'default)
+ (expand-file-name org-attach-id-dir))
+ ((eq org-attach-git-dir 'individual-repository)
+ (org-attach-dir))))
(git-dir (vc-git-root dir))
(use-annex (org-attach-git-use-annex))
(changes 0))
@@ -102,7 +125,7 @@ with hook `org-attach-after-change-hook'."
org-attach-git-annex-cutoff))
(call-process "git" nil nil nil "annex" "add" new-or-modified)
(call-process "git" nil nil nil "add" new-or-modified))
- (cl-incf changes))
+ (cl-incf changes))
(dolist (deleted
(split-string
(shell-command-to-string "git ls-files -z --deleted") "\0" t))
diff --git a/lisp/org/org-attach.el b/lisp/org/org-attach.el
index 46decacca03..75db69c9cca 100644
--- a/lisp/org/org-attach.el
+++ b/lisp/org/org-attach.el
@@ -40,8 +40,11 @@
(require 'org-id)
(declare-function dired-dwim-target-directory "dired-aux")
+(declare-function dired-get-marked-files "dired" (&optional localp arg filter distinguish-one-marked error))
(declare-function org-element-property "org-element" (property element))
(declare-function org-element-type "org-element" (element))
+(declare-function org-inlinetask-goto-beginning "org-inlinetask" ())
+(declare-function org-inlinetask-in-task-p "org-inlinetask" ())
(defgroup org-attach nil
"Options concerning attachments in Org mode."
@@ -118,7 +121,7 @@ lns create a symbol link. Note that this is not supported
(defcustom org-attach-use-inheritance 'selective
"Attachment inheritance for the outline.
-Enabling inheritance for org-attach implies two things. First,
+Enabling inheritance for `org-attach' implies two things. First,
that attachment links will look through all parent headings until
it finds the linked attachment. Second, that running org-attach
inside a node without attachments will make org-attach operate on
@@ -243,6 +246,17 @@ Each entry in this list is a list of three elements:
(function :tag "Command")
(string :tag "Docstring"))))
+(defcustom org-attach-sync-delete-empty-dir 'query
+ "Determine what to do with an empty attachment directory on sync.
+When set to nil, don't touch the directory. When set to `query',
+ask the user instead, else remove without asking."
+ :group 'org-attach
+ :package-version '(Org . "9.5")
+ :type '(choice
+ (const :tag "Never delete" nil)
+ (const :tag "Always delete" t)
+ (const :tag "Query the user" query)))
+
;;;###autoload
(defun org-attach ()
"The dispatcher for attachment commands.
@@ -256,38 +270,45 @@ Shows a list of commands and prompts for another key to execute a command."
(unless marker
(error "No item in current line")))
(org-with-point-at marker
- (org-back-to-heading-or-point-min t)
+ (if (and (featurep 'org-inlinetask)
+ (not (org-inlinetask-in-task-p)))
+ (org-with-limited-levels
+ (org-back-to-heading-or-point-min t))
+ (if (and (featurep 'org-inlinetask)
+ (org-inlinetask-in-task-p))
+ (org-inlinetask-goto-beginning)
+ (org-back-to-heading-or-point-min t)))
(save-excursion
(save-window-excursion
(unless org-attach-expert
(org-switch-to-buffer-other-window "*Org Attach*")
(erase-buffer)
(setq cursor-type nil
- header-line-format "Use C-v, M-v, C-n or C-p to navigate.")
+ header-line-format "Use C-v, M-v, C-n or C-p to navigate.")
(insert
- (concat "Attachment folder:\n"
- (or dir
- "Can't find an existing attachment-folder")
- (unless (and dir (file-directory-p dir))
- "\n(Not yet created)")
- "\n\n"
- (format "Select an Attachment Command:\n\n%s"
- (mapconcat
- (lambda (entry)
- (pcase entry
- (`((,key . ,_) ,_ ,docstring)
- (format "%c %s"
- key
- (replace-regexp-in-string "\n\\([\t ]*\\)"
- " "
- docstring
- nil nil 1)))
- (_
- (user-error
- "Invalid `org-attach-commands' item: %S"
- entry))))
- org-attach-commands
- "\n")))))
+ (concat "Attachment folder:\n"
+ (or dir
+ "Can't find an existing attachment-folder")
+ (unless (and dir (file-directory-p dir))
+ "\n(Not yet created)")
+ "\n\n"
+ (format "Select an Attachment Command:\n\n%s"
+ (mapconcat
+ (lambda (entry)
+ (pcase entry
+ (`((,key . ,_) ,_ ,docstring)
+ (format "%c %s"
+ key
+ (replace-regexp-in-string "\n\\([\t ]*\\)"
+ " "
+ docstring
+ nil nil 1)))
+ (_
+ (user-error
+ "Invalid `org-attach-commands' item: %S"
+ entry))))
+ org-attach-commands
+ "\n")))))
(org-fit-window-to-buffer (get-buffer-window "*Org Attach*"))
(let ((msg (format "Select command: [%s]"
(concat (mapcar #'caar org-attach-commands)))))
@@ -365,7 +386,7 @@ If the attachment by some reason cannot be created an error will be raised."
attach-dir))
(defun org-attach-dir-from-id (id &optional try-all)
- "Returns a folder path based on `org-attach-id-dir' and ID.
+ "Return a folder path based on `org-attach-id-dir' and ID.
If TRY-ALL is non-nil, try all id-to-path functions in
`org-attach-id-to-path-function-list' and return the first path
that exist in the filesystem, or the first one if none exist.
@@ -426,7 +447,7 @@ Return the directory."
new))
(defun org-attach-unset-directory ()
- "Removes DIR node property.
+ "Remove DIR node property.
If attachment folder is changed due to removal of DIR-property
ask to move attachments to new location and ask to delete old
attachment-folder.
@@ -591,14 +612,22 @@ with no prompts."
(defun org-attach-sync ()
"Synchronize the current outline node with its attachments.
-This can be used after files have been added externally."
+Useful after files have been added/removed externally. Option
+`org-attach-sync-delete-empty-dir' controls the behavior for
+empty attachment directories."
(interactive)
(let ((attach-dir (org-attach-dir)))
- (when attach-dir
+ (if (not attach-dir)
+ (org-attach-tag 'off)
(run-hook-with-args 'org-attach-after-change-hook attach-dir)
(let ((files (org-attach-file-list attach-dir)))
- (org-attach-tag (not files))))
- (unless attach-dir (org-attach-tag t))))
+ (org-attach-tag (not files)))
+ (when org-attach-sync-delete-empty-dir
+ (when (and (org-directory-empty-p attach-dir)
+ (if (eq 'query org-attach-sync-delete-empty-dir)
+ (yes-or-no-p "Attachment directory is empty. Delete?")
+ t))
+ (delete-directory attach-dir))))))
(defun org-attach-file-list (dir)
"Return a list of files in the attachment directory.
diff --git a/lisp/org/org-capture.el b/lisp/org/org-capture.el
index 7ae8fae3aab..1756b34fc5b 100644
--- a/lisp/org/org-capture.el
+++ b/lisp/org/org-capture.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2010-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
@@ -69,6 +69,7 @@
(declare-function org-table-goto-line "org-table" (N))
(defvar dired-buffers)
+(defvar crm-separator)
(defvar org-end-time-was-given)
(defvar org-keyword-properties)
(defvar org-remember-default-headline)
@@ -107,7 +108,7 @@
(defun org-capture-upgrade-templates (templates)
"Update the template list to the new format.
-TEMPLATES is a template list, as in `org-capture-templates'. The
+TEMPLATES is a template list, as in `org-capture-templates'. The
new format unifies all the date/week tree targets into one that
also allows for an optional outline path to specify a target."
(let ((modified-templates
@@ -246,6 +247,10 @@ properties are:
:jump-to-captured When set, jump to the captured entry when finished.
+ :refile-targets When exiting capture mode via `org-capture-refile', the
+ variable `org-refile-targets' will be temporarily bound
+ to the value of this property.
+
:empty-lines Set this to the number of lines that should be inserted
before and after the new item. Default 0, only common
other value is 1.
@@ -301,13 +306,15 @@ be replaced with content and expanded:
current template.
%(sexp) Evaluate elisp `(sexp)' and replace it with the results.
Only placeholders pre-existing within the template, or
- introduced with %[pathname] are expanded this way. Since this
- happens after expanding non-interactive %-escapes, those can
- be used to fill the expression.
- %<...> The result of format-time-string on the ... format specification.
- %t Time stamp, date only. The time stamp is the current time,
- except when called from agendas with `\\[org-agenda-capture]' or
- with `org-capture-use-agenda-date' set.
+ introduced with %[pathname] are expanded this way.
+ Since this happens after expanding non-interactive
+ %-escapes, those can be used to fill the expression.
+ %<...> The result of `format-time-string' on the ... format
+ specification.
+ %t Time stamp, date only. The time stamp is the current
+ time, except when called from agendas with
+ `\\[org-agenda-capture]' or with
+ `org-capture-use-agenda-date' set.
%T Time stamp as above, with date and time.
%u, %U Like the above, but inactive time stamps.
%i Initial content, copied from the active region. If
@@ -317,12 +324,13 @@ be replaced with content and expanded:
%a Annotation, normally the link created with `org-store-link'.
%A Like %a, but prompt for the description part.
%l Like %a, but only insert the literal link.
+ %L Like %l, but without brackets (the link content itself).
%c Current kill ring head.
%x Content of the X clipboard.
%k Title of currently clocked task.
%K Link to currently clocked task.
%n User name (taken from the variable `user-full-name').
- %f File visited by current buffer when org-capture was called.
+ %f File visited by current buffer when `org-capture' was called.
%F Full path of the file or directory visited by current buffer.
%:keyword Specific information for certain link types, see below.
%^g Prompt for tags, with completion on tags in target file.
@@ -333,6 +341,8 @@ be replaced with content and expanded:
%^C Interactive selection of which kill or clip to use.
%^L Like %^C, but insert as link.
%^{prop}p Prompt the user for a value for property `prop'.
+ A default value can be specified like this:
+ %^{prop|default}p.
%^{prompt} Prompt the user for a string and replace this sequence with it.
A default value and a completion table can be specified like this:
%^{prompt|default|completion2|completion3|...}.
@@ -363,7 +373,7 @@ calendar | %:type %:date
When you need to insert a literal percent sign in the template,
you can escape ambiguous cases with a backward slash, e.g., \\%i."
:group 'org-capture
- :version "24.1"
+ :package-version '(Org . "9.5")
:set (lambda (s v) (set s (org-capture-upgrade-templates v)))
:type
(let ((file-variants '(choice :tag "Filename "
@@ -371,78 +381,78 @@ you can escape ambiguous cases with a backward slash, e.g., \\%i."
(function :tag "Function")
(variable :tag "Variable")
(sexp :tag "Form"))))
- `(repeat
- (choice :value ("" "" entry (file "~/org/notes.org") "")
- (list :tag "Multikey description"
- (string :tag "Keys ")
- (string :tag "Description"))
- (list :tag "Template entry"
- (string :tag "Keys ")
- (string :tag "Description ")
- (choice :tag "Capture Type " :value entry
- (const :tag "Org entry" entry)
- (const :tag "Plain list item" item)
- (const :tag "Checkbox item" checkitem)
- (const :tag "Plain text" plain)
- (const :tag "Table line" table-line))
- (choice :tag "Target location"
- (list :tag "File"
- (const :format "" file)
- ,file-variants)
- (list :tag "ID"
- (const :format "" id)
- (string :tag " ID"))
- (list :tag "File & Headline"
- (const :format "" file+headline)
- ,file-variants
- (string :tag " Headline"))
- (list :tag "File & Outline path"
- (const :format "" file+olp)
- ,file-variants
- (repeat :tag "Outline path" :inline t
- (string :tag "Headline")))
- (list :tag "File & Regexp"
- (const :format "" file+regexp)
- ,file-variants
- (regexp :tag " Regexp"))
- (list :tag "File [ & Outline path ] & Date tree"
- (const :format "" file+olp+datetree)
- ,file-variants
- (option (repeat :tag "Outline path" :inline t
- (string :tag "Headline"))))
- (list :tag "File & function"
- (const :format "" file+function)
- ,file-variants
- (sexp :tag " Function"))
- (list :tag "Current clocking task"
- (const :format "" clock))
- (list :tag "Function"
- (const :format "" function)
- (sexp :tag " Function")))
- (choice :tag "Template "
- (string)
- (list :tag "File"
- (const :format "" file)
- (file :tag "Template file"))
- (list :tag "Function"
- (const :format "" function)
- (function :tag "Template function")))
- (plist :inline t
- ;; Give the most common options as checkboxes
- :options (((const :format "%v " :prepend) (const t))
- ((const :format "%v " :immediate-finish) (const t))
- ((const :format "%v " :jump-to-captured) (const t))
- ((const :format "%v " :empty-lines) (const 1))
- ((const :format "%v " :empty-lines-before) (const 1))
- ((const :format "%v " :empty-lines-after) (const 1))
- ((const :format "%v " :clock-in) (const t))
- ((const :format "%v " :clock-keep) (const t))
- ((const :format "%v " :clock-resume) (const t))
- ((const :format "%v " :time-prompt) (const t))
- ((const :format "%v " :tree-type) (const week))
- ((const :format "%v " :unnarrowed) (const t))
- ((const :format "%v " :table-line-pos) (string))
- ((const :format "%v " :kill-buffer) (const t)))))))))
+ `(repeat
+ (choice :value ("" "" entry (file "~/org/notes.org") "")
+ (list :tag "Multikey description"
+ (string :tag "Keys ")
+ (string :tag "Description"))
+ (list :tag "Template entry"
+ (string :tag "Keys ")
+ (string :tag "Description ")
+ (choice :tag "Capture Type " :value entry
+ (const :tag "Org entry" entry)
+ (const :tag "Plain list item" item)
+ (const :tag "Checkbox item" checkitem)
+ (const :tag "Plain text" plain)
+ (const :tag "Table line" table-line))
+ (choice :tag "Target location"
+ (list :tag "File"
+ (const :format "" file)
+ ,file-variants)
+ (list :tag "ID"
+ (const :format "" id)
+ (string :tag " ID"))
+ (list :tag "File & Headline"
+ (const :format "" file+headline)
+ ,file-variants
+ (string :tag " Headline"))
+ (list :tag "File & Outline path"
+ (const :format "" file+olp)
+ ,file-variants
+ (repeat :tag "Outline path" :inline t
+ (string :tag "Headline")))
+ (list :tag "File & Regexp"
+ (const :format "" file+regexp)
+ ,file-variants
+ (regexp :tag " Regexp"))
+ (list :tag "File [ & Outline path ] & Date tree"
+ (const :format "" file+olp+datetree)
+ ,file-variants
+ (option (repeat :tag "Outline path" :inline t
+ (string :tag "Headline"))))
+ (list :tag "File & function"
+ (const :format "" file+function)
+ ,file-variants
+ (sexp :tag " Function"))
+ (list :tag "Current clocking task"
+ (const :format "" clock))
+ (list :tag "Function"
+ (const :format "" function)
+ (sexp :tag " Function")))
+ (choice :tag "Template "
+ (string)
+ (list :tag "File"
+ (const :format "" file)
+ (file :tag "Template file"))
+ (list :tag "Function"
+ (const :format "" function)
+ (function :tag "Template function")))
+ (plist :inline t
+ ;; Give the most common options as checkboxes
+ :options (((const :format "%v " :prepend) (const t))
+ ((const :format "%v " :immediate-finish) (const t))
+ ((const :format "%v " :jump-to-captured) (const t))
+ ((const :format "%v " :empty-lines) (const 1))
+ ((const :format "%v " :empty-lines-before) (const 1))
+ ((const :format "%v " :empty-lines-after) (const 1))
+ ((const :format "%v " :clock-in) (const t))
+ ((const :format "%v " :clock-keep) (const t))
+ ((const :format "%v " :clock-resume) (const t))
+ ((const :format "%v " :time-prompt) (const t))
+ ((const :format "%v " :tree-type) (const week))
+ ((const :format "%v " :unnarrowed) (const t))
+ ((const :format "%v " :table-line-pos) (string))
+ ((const :format "%v " :kill-buffer) (const t)))))))))
(defcustom org-capture-before-finalize-hook nil
"Hook that is run right before a capture process is finalized.
@@ -467,8 +477,7 @@ The capture buffer is current and still narrowed."
:type 'hook)
(defcustom org-capture-bookmark t
- "When non-nil, add a bookmark pointing at the last stored
-position when capturing."
+ "When non-nil, add bookmark pointing at the last stored position when capturing."
:group 'org-capture
:version "24.3"
:type 'boolean)
@@ -488,19 +497,19 @@ is copied to this variable, which is local in the indirect buffer.")
(defvar org-capture-clock-keep nil
"Local variable to store the value of the :clock-keep parameter.
-This is needed in case org-capture-finalize is called interactively.")
+This is needed in case `org-capture-finalize' is called interactively.")
-(defun org-capture-put (&rest stuff)
- "Add properties to the capture property list `org-capture-plist'."
- (while stuff
+(defun org-capture-put (&rest elements)
+ "Add ELEMENTS to the capture property list `org-capture-plist'."
+ (while elements
(setq org-capture-plist (plist-put org-capture-plist
- (pop stuff) (pop stuff)))))
-(defun org-capture-get (prop &optional local)
- "Get properties from the capture property list `org-capture-plist'.
+ (pop elements) (pop elements)))))
+(defun org-capture-get (property &optional local)
+ "Get PROPERTY from the capture property list `org-capture-plist'.
When LOCAL is set, use the local variable `org-capture-current-plist',
this is necessary after initialization of the capture process,
to avoid conflicts with other active capture processes."
- (plist-get (if local org-capture-current-plist org-capture-plist) prop))
+ (plist-get (if local org-capture-current-plist org-capture-plist) property))
;;; The minor mode
@@ -579,17 +588,17 @@ to avoid duplicates.)"
(string :tag " Capture key")
(string :tag "Replace by template")
(repeat :tag "Available when"
- (choice
- (cons :tag "Condition"
- (choice
- (const :tag "In file" in-file)
- (const :tag "Not in file" not-in-file)
- (const :tag "In buffer" in-buffer)
- (const :tag "Not in buffer" not-in-buffer)
- (const :tag "In mode" in-mode)
- (const :tag "Not in mode" not-in-mode))
- (regexp))
- (function :tag "Custom function"))))))
+ (choice
+ (cons :tag "Condition"
+ (choice
+ (const :tag "In file" in-file)
+ (const :tag "Not in file" not-in-file)
+ (const :tag "In buffer" in-buffer)
+ (const :tag "Not in buffer" not-in-buffer)
+ (const :tag "In mode" in-mode)
+ (const :tag "Not in mode" not-in-mode))
+ (regexp))
+ (function :tag "Custom function"))))))
(defcustom org-capture-use-agenda-date nil
"Non-nil means use the date at point when capturing from agendas.
@@ -882,7 +891,8 @@ for `entry'-type templates"))
(pos (make-marker))
(org-capture-is-refiling t)
(kill-buffer (org-capture-get :kill-buffer 'local))
- (jump-to-captured (org-capture-get :jump-to-captured 'local)))
+ (jump-to-captured (org-capture-get :jump-to-captured 'local))
+ (refile-targets (org-capture-get :refile-targets 'local)))
;; Since `org-capture-finalize' may alter buffer contents (e.g.,
;; empty lines) around entry, use a marker to refer to the
;; headline to be refiled. Place the marker in the base buffer,
@@ -892,11 +902,12 @@ for `entry'-type templates"))
;; early. We want to wait for the refiling to be over, so we
;; control when the latter function is called.
(org-capture-put :kill-buffer nil :jump-to-captured nil)
- (org-capture-finalize)
- (save-window-excursion
- (with-current-buffer base
- (org-with-point-at pos
- (call-interactively 'org-refile))))
+ (let ((org-refile-targets (or refile-targets org-refile-targets)))
+ (org-capture-finalize)
+ (save-window-excursion
+ (with-current-buffer base
+ (org-with-point-at pos
+ (call-interactively 'org-refile)))))
(when kill-buffer
(with-current-buffer base (save-buffer))
(kill-buffer base))
@@ -916,7 +927,7 @@ for `entry'-type templates"))
(interactive)
(org-goto-marker-or-bmk org-capture-last-stored-marker
(plist-get org-bookmark-names-plist
- :last-capture))
+ :last-capture))
(message "This is the last note stored by a capture process"))
;;; Supporting functions for handling the process
@@ -1025,28 +1036,23 @@ Store them in the capture property list."
(time-to-days org-overriding-default-time))
((or (org-capture-get :time-prompt)
(equal current-prefix-arg 1))
- ;; Prompt for date.
- (let ((prompt-time (org-read-date
- nil t nil "Date for tree entry:")))
+ ;; Prompt for date. Bind `org-end-time-was-given' so
+ ;; that `org-read-date-analyze' handles the time range
+ ;; case and returns `prompt-time' with the start value.
+ (let* ((org-time-was-given nil)
+ (org-end-time-was-given nil)
+ (prompt-time (org-read-date
+ nil t nil "Date for tree entry:")))
(org-capture-put
:default-time
- (cond ((and (or (not (boundp 'org-time-was-given))
- (not org-time-was-given))
- (not (= (time-to-days prompt-time) (org-today))))
- ;; Use 00:00 when no time is given for another
- ;; date than today?
- (apply #'encode-time 0 0
- org-extend-today-until
- (cl-cdddr (decode-time prompt-time))))
- ((string-match "\\([^ ]+\\)-[^ ]+[ ]+\\(.*\\)"
- org-read-date-final-answer)
- ;; Replace any time range by its start.
- (apply #'encode-time
- (org-read-date-analyze
- (replace-match "\\1 \\2" nil nil
- org-read-date-final-answer)
- prompt-time (decode-time prompt-time))))
- (t prompt-time)))
+ (if (or org-time-was-given
+ (= (time-to-days prompt-time) (org-today)))
+ prompt-time
+ ;; Use 00:00 when no time is given for another
+ ;; date than today?
+ (apply #'encode-time 0 0
+ org-extend-today-until
+ (cl-cdddr (decode-time prompt-time)))))
(time-to-days prompt-time)))
(t
;; Current date, possibly corrected for late night
@@ -1115,7 +1121,7 @@ FILE is a generalized file location, as handled by
(defun org-capture-place-template (&optional inhibit-wconf-store)
"Insert the template at the target location, and display the buffer.
-When `inhibit-wconf-store', don't store the window configuration, as it
+When INHIBIT-WCONF-STORE is non-nil, don't store the window configuration, as it
may have been stored before."
(unless inhibit-wconf-store
(org-capture-put :return-to-wconf (current-window-configuration)))
@@ -1410,21 +1416,21 @@ Of course, if exact position has been required, just put it there."
(org-capture--position-cursor beg end)))))
(defun org-capture-mark-kill-region (beg end)
- "Mark the region that will have to be killed when aborting capture."
+ "Mark region between BEG and END to be killed on aborted capture."
(let ((m1 (copy-marker beg))
(m2 (copy-marker end t)))
(org-capture-put :begin-marker m1)
(org-capture-put :end-marker m2)))
-(defun org-capture-position-for-last-stored (where)
- "Memorize the position that should later become the position of last capture."
+(defun org-capture-position-for-last-stored (position)
+ "Put POSITION on `org-capture-plist' for future use as `last capture`."
(cond
- ((integerp where)
+ ((integerp position)
(org-capture-put :position-for-last-stored
- (move-marker (make-marker) where
+ (move-marker (make-marker) position
(or (buffer-base-buffer (current-buffer))
(current-buffer)))))
- ((eq where 'table-line)
+ ((eq position 'table-line)
(org-capture-put :position-for-last-stored
(list 'table-line
(org-table-current-dline))))
@@ -1451,7 +1457,8 @@ Of course, if exact position has been required, just put it there."
(move-marker org-capture-last-stored-marker (point))))))
(defun org-capture-narrow (beg end)
- "Narrow, unless configuration says not to narrow."
+ "Possibly narrow to region between BEG and END.
+If configuration contains non-nil :unnarrowed property, do not narrow."
(unless (org-capture-get :unnarrowed)
(narrow-to-region beg end)))
@@ -1464,8 +1471,9 @@ of the template."
(replace-match "")))
(defun org-capture-empty-lines-before (&optional n)
- "Set the correct number of empty lines before the insertion point.
-Point will be after the empty lines, so insertion can directly be done."
+ "Insert N empty lines before the insertion point.
+Point will be after the empty lines, so insertion can directly be done.
+If N is nil, :empty-lines-before or :empty-lines are considered."
(setq n (or n (org-capture-get :empty-lines-before)
(org-capture-get :empty-lines) 0))
(let ((pos (point)))
@@ -1475,7 +1483,8 @@ Point will be after the empty lines, so insertion can directly be done."
(defun org-capture-empty-lines-after (&optional n)
"Set the correct number of empty lines after the inserted string.
-Point will remain at the first line after the inserted text."
+Point will remain at the first line after the inserted text.
+If N is nil, :empty-lines-after or :empty-lines are considered."
(setq n (or n (org-capture-get :empty-lines-after)
(org-capture-get :empty-lines) 0))
(org-back-over-empty-lines)
@@ -1487,7 +1496,7 @@ Point will remain at the first line after the inserted text."
(defvar org-clock-marker) ; Defined in org.el
(defun org-capture-set-plist (entry)
- "Initialize the property list from the template definition."
+ "Initialize the property list for ENTRY from the template definition."
(setq org-capture-plist (copy-sequence (nthcdr 5 entry)))
(org-capture-put :key (car entry) :description (nth 1 entry)
:target (nth 3 entry))
@@ -1504,7 +1513,7 @@ Point will remain at the first line after the inserted text."
(defun org-capture-goto-target (&optional template-key)
"Go to the target location of a capture template.
-The user is queried for the template."
+If TEMPLATE-KEY is nil, the user is queried for the template."
(interactive)
(let ((entry (org-capture-select-template template-key)))
(unless entry (error "No capture template selected"))
@@ -1514,7 +1523,7 @@ The user is queried for the template."
(goto-char (org-capture-get :pos))))
(defun org-capture-get-indirect-buffer (&optional buffer prefix)
- "Make an indirect buffer for a capture process.
+ "Make an indirect BUFFER for a capture process.
Use PREFIX as a prefix for the name of the indirect buffer."
(setq buffer (or buffer (current-buffer)))
(let ((n 1) (base (buffer-name buffer)) bname)
@@ -1556,8 +1565,10 @@ Lisp programs can force the template by setting KEYS to a string."
"List various clipboards values.")
(defun org-capture-fill-template (&optional template initial annotation)
- "Fill a template and return the filled template as a string.
-The template may still contain \"%?\" for cursor positioning."
+ "Fill a TEMPLATE and return the filled template as a string.
+The template may still contain \"%?\" for cursor positioning.
+INITIAL content and/or ANNOTATION may be specified, but will be overridden
+by their respective `org-store-link-plist' properties if present."
(let* ((template (or template (org-capture-get :template)))
(buffer (org-capture-get :buffer))
(file (buffer-file-name (or (buffer-base-buffer buffer) buffer)))
@@ -1595,6 +1606,9 @@ The template may still contain \"%?\" for cursor positioning."
(v-l (if (and v-a (string-match l-re v-a))
(replace-match "[[\\1]]" nil nil v-a)
v-a))
+ (v-L (if (and v-a (string-match l-re v-a))
+ (replace-match "\\1" nil nil v-a)
+ v-a))
(v-n user-full-name)
(v-k (if (marker-buffer org-clock-marker)
(org-no-properties org-clock-heading)
@@ -1647,7 +1661,7 @@ The template may still contain \"%?\" for cursor positioning."
;; Mark %() embedded elisp for later evaluation.
(org-capture-expand-embedded-elisp 'mark)
;; Expand non-interactive templates.
- (let ((regexp "%\\(:[-A-Za-z]+\\|<\\([^>\n]+\\)>\\|[aAcfFikKlntTuUx]\\)"))
+ (let ((regexp "%\\(:[-A-Za-z]+\\|<\\([^>\n]+\\)>\\|[aAcfFikKlLntTuUx]\\)"))
(save-excursion
(while (re-search-forward regexp nil t)
;; `org-capture-escaped-%' may modify buffer and cripple
@@ -1684,6 +1698,7 @@ The template may still contain \"%?\" for cursor positioning."
(?k v-k)
(?K v-K)
(?l v-l)
+ (?L v-L)
(?n v-n)
(?t v-t)
(?T v-T)
@@ -1731,12 +1746,11 @@ The template may still contain \"%?\" for cursor positioning."
(org-add-colon-after-tag-completion t)
(ins (mapconcat
#'identity
- (org-split-string
- (completing-read
- (if prompt (concat prompt ": ") "Tags: ")
- 'org-tags-completion-function nil nil nil
- 'org-tags-history)
- "[^[:alnum:]_@#%]+")
+ (let ((crm-separator "[ \t]*:[ \t]*"))
+ (completing-read-multiple
+ (if prompt (concat prompt ": ") "Tags: ")
+ org-last-tags-completion-table nil nil nil
+ 'org-tags-history))
":")))
(when (org-string-nw-p ins)
(unless (eq (char-before) ?:) (insert ":"))
@@ -1785,7 +1799,8 @@ The template may still contain \"%?\" for cursor positioning."
(setq l (org-up-heading-safe)))
(if l (point-marker)
(point-min-marker)))))))
- (value (org-read-property-value prompt pom)))
+ (value
+ (org-read-property-value prompt pom default)))
(org-set-property prompt value)))
((or "t" "T" "u" "U")
;; These are the date/time related ones.
@@ -1800,10 +1815,13 @@ The template may still contain \"%?\" for cursor positioning."
;; Load history list for current prompt.
(setq org-capture--prompt-history
(gethash prompt org-capture--prompt-history-table))
- (push (org-completing-read
- (concat (or prompt "Enter string")
- (and default (format " [%s]" default))
- ": ")
+ (push (org-completing-read
+ ;; `format-prompt' is new in Emacs 28.1.
+ (if (fboundp 'format-prompt)
+ (format-prompt (or prompt "Enter string") default)
+ (concat (or prompt "Enter string")
+ (and default (format " [%s]" default))
+ ": "))
completions
nil nil nil 'org-capture--prompt-history default)
strings)
@@ -1840,7 +1858,7 @@ The template may still contain \"%?\" for cursor positioning."
(defun org-capture-escaped-% ()
"Non-nil if % was escaped.
-If yes, unescape it now. Assume match-data contains the
+If yes, unescape it now. Assume `match-data' contains the
placeholder to check."
(save-excursion
(goto-char (match-beginning 0))
diff --git a/lisp/org/org-clock.el b/lisp/org/org-clock.el
index 1283970bc2b..2526ca793aa 100644
--- a/lisp/org/org-clock.el
+++ b/lisp/org/org-clock.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
@@ -85,7 +85,7 @@ function `org-clock-into-drawer' instead."
(string :tag "Into Drawer named...")))
(defun org-clock-into-drawer ()
- "Value of `org-clock-into-drawer'. but let properties overrule.
+ "Value of `org-clock-into-drawer', but let properties overrule.
If the current entry has or inherits a CLOCK_INTO_DRAWER
property, it will be used instead of the default value.
@@ -219,8 +219,7 @@ Emacs initialization file."
(const :tag "Clock and history" t)
(const :tag "No persistence" nil)))
-(defcustom org-clock-persist-file (convert-standard-filename
- (concat user-emacs-directory "org-clock-save.el"))
+(defcustom org-clock-persist-file (locate-user-emacs-file "org-clock-save.el")
"File to save clock data to."
:group 'org-clock
:type 'string)
@@ -438,12 +437,11 @@ specifications than `frame-title-format', which see."
(defcustom org-clock-x11idle-program-name "x11idle"
"Name of the program which prints X11 idle time in milliseconds.
-You can find x11idle.c in the contrib/scripts directory of the
-Org git distribution. Or, you can do:
+you can do \"~$ sudo apt-get install xprintidle\" if you are using
+a Debian-based distribution.
- sudo apt-get install xprintidle
-
-if you are using Debian."
+Alternatively, can find x11idle.c in the org-contrib repository at
+https://git.sr.ht/~bzg/org-contrib"
:group 'org-clock
:version "24.4"
:package-version '(Org . "8.0")
@@ -485,6 +483,17 @@ is added to the user configuration."
(integer :tag "Clock out after Emacs is idle for X seconds")
(const :tag "Never auto clock out" nil)))
+(defcustom org-clock-ask-before-exiting t
+ "If non-nil, ask if the user wants to clock out before exiting Emacs.
+This variable only has effect if set with \\[customize]."
+ :set (lambda (symbol value)
+ (if value
+ (add-hook 'kill-emacs-query-functions #'org-clock-kill-emacs-query)
+ (remove-hook 'kill-emacs-query-functions #'org-clock-kill-emacs-query))
+ (set symbol value))
+ :type 'boolean
+ :package-version '(Org . "9.5"))
+
(defvar org-clock-in-prepare-hook nil
"Hook run when preparing the clock.
This hook is run before anything happens to the task that
@@ -503,9 +512,9 @@ to add an effort property.")
"Has the clock been used during the current Emacs session?")
(defvar org-clock-stored-history nil
- "Clock history, populated by `org-clock-load'")
+ "Clock history, populated by `org-clock-load'.")
(defvar org-clock-stored-resume-clock nil
- "Clock to resume, saved by `org-clock-load'")
+ "Clock to resume, saved by `org-clock-load'.")
;;; The clock for measuring work time.
@@ -607,10 +616,6 @@ cannot be translated."
((stringp drawer) drawer)
(t nil))))
-(defun org-clocking-buffer ()
- "Return the clocking buffer if we are currently clocking a task or nil."
- (marker-buffer org-clock-marker))
-
(defun org-clocking-p ()
"Return t when clocking a task."
(not (equal (org-clocking-buffer) nil)))
@@ -677,19 +682,19 @@ pointing to it."
(let (cat task heading prefix)
(with-current-buffer (org-base-buffer (marker-buffer marker))
(org-with-wide-buffer
- (ignore-errors
- (goto-char marker)
- (setq cat (org-get-category)
- heading (org-get-heading 'notags)
- prefix (save-excursion
- (org-back-to-heading t)
- (looking-at org-outline-regexp)
- (match-string 0))
- task (substring
- (org-fontify-like-in-org-mode
- (concat prefix heading)
- org-odd-levels-only)
- (length prefix))))))
+ (ignore-errors
+ (goto-char marker)
+ (setq cat (org-get-category)
+ heading (org-get-heading 'notags)
+ prefix (save-excursion
+ (org-back-to-heading t)
+ (looking-at org-outline-regexp)
+ (match-string 0))
+ task (substring
+ (org-fontify-like-in-org-mode
+ (concat prefix heading)
+ org-odd-levels-only)
+ (length prefix))))))
(when (and cat task)
(insert (format "[%c] %-12s %s\n" i cat task))
(cons i marker)))))
@@ -853,6 +858,10 @@ use libnotify if available, or fall back on a message."
org-show-notification-timeout
nil
(lambda () (w32-notification-close id)))))
+ ((fboundp 'ns-do-applescript)
+ (ns-do-applescript
+ (format "display notification \"%s\" with title \"Org mode notification\""
+ (replace-regexp-in-string "\"" "#" notification))))
((fboundp 'notifications-notify)
(notifications-notify
:title "Org mode message"
@@ -1162,13 +1171,12 @@ If `only-dangling-p' is non-nil, only ask to resolve dangling
(org-clock-resolve
clock
(or prompt-fn
- (function
- (lambda (clock)
- (format
- "Dangling clock started %d mins ago"
- (floor (org-time-convert-to-integer
- (org-time-since (cdr clock)))
- 60)))))
+ (lambda (clock)
+ (format
+ "Dangling clock started %d mins ago"
+ (floor (org-time-convert-to-integer
+ (org-time-since (cdr clock)))
+ 60))))
(or last-valid
(cdr clock)))))))))))
@@ -1367,7 +1375,7 @@ the default behavior."
(end-of-line 0)
(org-in-item-p)))
(beginning-of-line 1)
- (indent-line-to (- (current-indentation) 2)))
+ (indent-line-to (max 0 (- (current-indentation) 2))))
(insert org-clock-string " ")
(setq org-clock-effort (org-entry-get (point) org-effort-property))
(setq org-clock-total-time (org-clock-sum-current-item
@@ -1671,17 +1679,13 @@ to, overriding the existing value of `org-clock-out-switch-to-state'."
(insert " => " (format "%2d:%02d" h m))
(move-marker org-clock-marker nil)
(move-marker org-clock-hd-marker nil)
- ;; Possibly remove zero time clocks. However, do not add
- ;; a note associated to the CLOCK line in this case.
- (cond ((and org-clock-out-remove-zero-time-clocks
- (= 0 h m))
- (setq remove t)
- (delete-region (line-beginning-position)
- (line-beginning-position 2)))
- (org-log-note-clock-out
- (org-add-log-setup
- 'clock-out nil nil nil
- (concat "# Task: " (org-get-heading t) "\n\n"))))
+ ;; Possibly remove zero time clocks.
+ (when (and org-clock-out-remove-zero-time-clocks
+ (= 0 h m))
+ (setq remove t)
+ (delete-region (line-beginning-position)
+ (line-beginning-position 2)))
+ (org-clock-remove-empty-clock-drawer)
(when org-clock-mode-line-timer
(cancel-timer org-clock-mode-line-timer)
(setq org-clock-mode-line-timer nil))
@@ -1712,11 +1716,14 @@ to, overriding the existing value of `org-clock-out-switch-to-state'."
"Clock stopped at %s after %s => LINE REMOVED"
"Clock stopped at %s after %s")
te (org-duration-from-minutes (+ (* 60 h) m)))
- (run-hooks 'org-clock-out-hook)
- (unless (org-clocking-p)
- (setq org-clock-current-task nil)))))))
-
-(add-hook 'org-clock-out-hook #'org-clock-remove-empty-clock-drawer)
+ (unless (org-clocking-p)
+ (setq org-clock-current-task nil))
+ (run-hooks 'org-clock-out-hook)
+ ;; Add a note, but only if we didn't remove the clock line.
+ (when (and org-log-note-clock-out (not remove))
+ (org-add-log-setup
+ 'clock-out nil nil nil
+ (concat "# Task: " (org-get-heading t) "\n\n"))))))))
(defun org-clock-remove-empty-clock-drawer ()
"Remove empty clock drawers in current subtree."
@@ -1897,11 +1904,11 @@ PROPNAME lets you set a custom text property instead of :org-clock-minutes."
((match-end 2)
;; Two time stamps.
(let* ((ts (float-time
- (apply #'encode-time
+ (encode-time
(save-match-data
(org-parse-time-string (match-string 2))))))
(te (float-time
- (apply #'encode-time
+ (encode-time
(org-parse-time-string (match-string 3)))))
(dt (- (if tend (min te tend) te)
(if tstart (max ts tstart) ts))))
@@ -2696,7 +2703,18 @@ from the dynamic block definition."
(format (concat "| %s %s | %s%s%s"
(format org-clock-file-time-cell-format
(org-clock--translate "File time" lang))
- " | *%s*|\n")
+
+ ;; The file-time rollup value goes in the first time
+ ;; column (of which there is always at least one)...
+ " | *%s*|"
+ ;; ...and the remaining file time cols (if any) are blank.
+ (make-string (max 0 (1- time-columns)) ?|)
+
+ ;; Optionally show the percentage contribution of "this"
+ ;; file time to the total time.
+ (if (eq formula '%) " %s |" "")
+ "\n")
+
(file-name-nondirectory file-name)
(if level? "| " "") ;level column, maybe
(if timestamp "| " "") ;timestamp column, maybe
@@ -2704,7 +2722,12 @@ from the dynamic block definition."
(if properties ;properties columns, maybe
(make-string (length properties) ?|)
"")
- (org-duration-from-minutes file-time)))) ;time
+ (org-duration-from-minutes file-time) ;time
+
+ (cond ((not (eq formula '%)) "") ;time percentage, maybe
+ ((or (not total-time) (= total-time 0)) "0.0")
+ (t
+ (format "%.1f" (* 100 (/ file-time (float total-time)))))))))
;; Get the list of node entries and iterate over it
(when (> maxlevel 0)
@@ -2732,13 +2755,13 @@ from the dynamic block definition."
(if timestamp (concat ts "|") "") ;timestamp, maybe
(if tags (concat (mapconcat #'identity tgs ", ") "|") "") ;tags, maybe
(if properties ;properties columns, maybe
- (concat (mapconcat (lambda (p) (or (cdr (assoc p props)) ""))
- properties
- "|")
- "|")
+ (concat (mapconcat (lambda (p) (or (cdr (assoc p props)) ""))
+ properties
+ "|")
+ "|")
"")
(if indent ;indentation
- (org-clocktable-indent-string level)
+ (org-clocktable-indent-string level)
"")
(format-field headline)
;; Empty fields for higher levels.
@@ -2746,7 +2769,7 @@ from the dynamic block definition."
(format-field (org-duration-from-minutes time))
(make-string (max 0 (- time-columns level)) ?|)
(if (eq formula '%)
- (format "%.1f |" (* 100 (/ time (float total-time))))
+ (format "%.1f |" (* 100 (/ time (float total-time))))
"")
"\n")))))))
(delete-char -1)
@@ -2814,7 +2837,7 @@ a number of clock tables."
(pcase (if range (car range) (plist-get params :tstart))
((and (pred numberp) n)
(pcase-let ((`(,m ,d ,y) (calendar-gregorian-from-absolute n)))
- (apply #'encode-time (list 0 0 org-extend-today-until d m y))))
+ (encode-time 0 0 org-extend-today-until d m y)))
(timestamp
(seconds-to-time
(org-matcher-time (or timestamp
@@ -2824,7 +2847,7 @@ a number of clock tables."
(pcase (if range (nth 1 range) (plist-get params :tend))
((and (pred numberp) n)
(pcase-let ((`(,m ,d ,y) (calendar-gregorian-from-absolute n)))
- (apply #'encode-time (list 0 0 org-extend-today-until d m y))))
+ (encode-time 0 0 org-extend-today-until d m y)))
(timestamp (seconds-to-time (org-matcher-time timestamp))))))
(while (time-less-p start end)
(unless (bolp) (insert "\n"))
@@ -3019,9 +3042,9 @@ Otherwise, return nil."
(setq ts (match-string 1)
te (match-string 3))
(setq s (- (float-time
- (apply #'encode-time (org-parse-time-string te)))
+ (encode-time (org-parse-time-string te)))
(float-time
- (apply #'encode-time (org-parse-time-string ts))))
+ (encode-time (org-parse-time-string ts))))
neg (< s 0)
s (abs s)
h (floor (/ s 3600))
@@ -3101,6 +3124,17 @@ The details of what will be saved are regulated by the variable
(when (org-invisible-p) (org-show-context))))))
(_ nil)))))
+(defun org-clock-kill-emacs-query ()
+ "Query user when killing Emacs.
+This function is added to `kill-emacs-query-functions'."
+ (let ((buf (org-clocking-buffer)))
+ (when (and buf (yes-or-no-p "Clock out and save? "))
+ (with-current-buffer buf
+ (org-clock-out)
+ (save-buffer))))
+ ;; Unconditionally return t for `kill-emacs-query-functions'.
+ t)
+
;; Suggested bindings
(org-defkey org-mode-map "\C-c\C-x\C-e" 'org-clock-modify-effort-estimate)
diff --git a/lisp/org/org-colview.el b/lisp/org/org-colview.el
index 2f039064404..f93e948bdcd 100644
--- a/lisp/org/org-colview.el
+++ b/lisp/org/org-colview.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
@@ -213,7 +213,7 @@ See `org-columns-summary-types' for details.")
(lambda () (interactive)
(org-columns-next-allowed-value nil i))))
-(easy-menu-define org-columns-menu org-columns-map "Org Column Menu"
+(easy-menu-define org-columns-menu org-columns-map "Org Column Menu."
'("Column"
["Edit property" org-columns-edit-value t]
["Next allowed value" org-columns-next-allowed-value t]
@@ -782,7 +782,7 @@ around it."
(setq time-after (copy-sequence time))
(setf (nth 3 time-before) (1- (nth 3 time)))
(setf (nth 3 time-after) (1+ (nth 3 time)))
- (mapcar (lambda (x) (format-time-string fmt (apply #'encode-time x)))
+ (mapcar (lambda (x) (format-time-string fmt (encode-time x)))
(list time-before time time-after)))))
(defun org-columns-open-link (&optional arg)
@@ -836,12 +836,11 @@ Also sets `org-columns-top-level-marker' to the new position."
(defun org-columns (&optional global columns-fmt-string)
"Turn on column view on an Org mode file.
-Column view applies to the whole buffer if point is before the
-first headline. Otherwise, it applies to the first ancestor
-setting \"COLUMNS\" property. If there is none, it defaults to
-the current headline. With a `\\[universal-argument]' prefix \
-argument, turn on column
-view for the whole buffer unconditionally.
+Column view applies to the whole buffer if point is before the first
+headline. Otherwise, it applies to the first ancestor setting
+\"COLUMNS\" property. If there is none, it defaults to the current
+headline. With a `\\[universal-argument]' prefix \ argument, GLOBAL,
+turn on column view for the whole buffer unconditionally.
When COLUMNS-FMT-STRING is non-nil, use it as the column format."
(interactive "P")
@@ -867,9 +866,8 @@ When COLUMNS-FMT-STRING is non-nil, use it as the column format."
(let ((cache
;; Collect contents of columns ahead of time so as to
;; compute their maximum width.
- (org-map-entries
- (lambda () (cons (point) (org-columns--collect-values)))
- nil nil (and org-columns-skip-archived-trees 'archive))))
+ (org-scan-tags
+ (lambda () (cons (point) (org-columns--collect-values))) t org--matcher-tags-todo-only)))
(when cache
(org-columns--set-widths cache)
(org-columns--display-here-title)
@@ -879,7 +877,8 @@ When COLUMNS-FMT-STRING is non-nil, use it as the column format."
(unless (local-variable-p 'org-colview-initial-truncate-line-value)
(setq-local org-colview-initial-truncate-line-value
truncate-lines))
- (setq truncate-lines t)
+ (if (not global-visual-line-mode)
+ (setq truncate-lines t))
(dolist (entry cache)
(goto-char (car entry))
(org-columns--display-here (cdr entry)))))))))
@@ -1165,7 +1164,11 @@ properties drawers."
(last-level lmax)
(property (car spec))
(printf (nth 4 spec))
- (operator (nth 3 spec))
+ ;; Special properties cannot be collected nor summarized, as
+ ;; they have their own way to be computed. Therefore, ignore
+ ;; any operator attached to them.
+ (operator (and (not (member property org-special-properties))
+ (nth 3 spec)))
(collect (and operator (org-columns--collect operator)))
(summarize (and operator (org-columns--summarize operator))))
(org-with-wide-buffer
@@ -1269,7 +1272,7 @@ When PRINTF is non-nil, use it to format the result."
"Summarize CHECK-BOXES with a check-box cookie."
(format "[%d/%d]"
(cl-count-if (lambda (b) (or (equal b "[X]")
- (string-match-p "\\[\\([1-9]\\)/\\1\\]" b)))
+ (string-match-p "\\[\\([1-9]\\)/\\1\\]" b)))
check-boxes)
(length check-boxes)))
@@ -1395,8 +1398,9 @@ other rows. Each row is a list of fields, as strings, or
(org-get-tags))))
(push (cons (org-reduced-level (org-current-level)) (nreverse row))
table)))))
- (or (and maxlevel (format "LEVEL<=%d" maxlevel))
- (and match match))
+ (if match
+ (concat match (and maxlevel (format "+LEVEL<=%d" maxlevel)))
+ (and maxlevel (format "LEVEL<=%d" maxlevel)))
(and local 'tree)
'archive 'comment)
(org-columns-quit)
@@ -1691,7 +1695,7 @@ This will add overlays to the date lines, to show the summary for each day."
(delq nil
(mapcar
(lambda (e) (org-string-nw-p
- (nth 1 (assoc spec e))))
+ (nth 1 (assoc spec e))))
entries)))
(final (if values
(funcall summarize values printf)
diff --git a/lisp/org/org-compat.el b/lisp/org/org-compat.el
index b68e5b58fca..b140df76223 100644
--- a/lisp/org/org-compat.el
+++ b/lisp/org/org-compat.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
@@ -72,6 +72,16 @@
(defvar org-table1-hline-regexp)
+;;; Emacs < 28.1 compatibility
+
+(if (fboundp 'directory-empty-p)
+ (defalias 'org-directory-empty-p #'directory-empty-p)
+ (defun org-directory-empty-p (dir)
+ "Return t if DIR names an existing directory containing no other files."
+ (and (file-directory-p dir)
+ (null (directory-files dir nil directory-files-no-dot-files-regexp t)))))
+
+
;;; Emacs < 27.1 compatibility
(unless (fboundp 'proper-list-p)
@@ -119,6 +129,32 @@ extension beyond end of line was not controllable."
(when (fboundp 'set-face-extend)
(mapc (lambda (f) (set-face-extend f extend-p)) faces)))
+(if (fboundp 'string-distance)
+ (defalias 'org-string-distance 'string-distance)
+ (defun org-string-distance (s1 s2)
+ "Return the edit (levenshtein) distance between strings S1 S2."
+ (let* ((l1 (length s1))
+ (l2 (length s2))
+ (dist (vconcat (mapcar (lambda (_) (make-vector (1+ l2) nil))
+ (number-sequence 1 (1+ l1)))))
+ (in (lambda (i j) (aref (aref dist i) j))))
+ (setf (aref (aref dist 0) 0) 0)
+ (dolist (j (number-sequence 1 l2))
+ (setf (aref (aref dist 0) j) j))
+ (dolist (i (number-sequence 1 l1))
+ (setf (aref (aref dist i) 0) i)
+ (dolist (j (number-sequence 1 l2))
+ (setf (aref (aref dist i) j)
+ (min
+ (1+ (funcall in (1- i) j))
+ (1+ (funcall in i (1- j)))
+ (+ (if (equal (aref s1 (1- i)) (aref s2 (1- j))) 0 1)
+ (funcall in (1- i) (1- j)))))))
+ (funcall in l1 l2))))
+
+(define-obsolete-function-alias 'org-babel-edit-distance 'org-string-distance
+ "9.5")
+
;;; Emacs < 26.1 compatibility
@@ -134,8 +170,7 @@ extension beyond end of line was not controllable."
(defsubst file-attribute-modification-time (attributes)
"The modification time in ATTRIBUTES returned by `file-attributes'.
This is the time of the last change to the file's contents, and
-is a list of integers (HIGH LOW USEC PSEC) in the same style
-as (current-time)."
+is a Lisp timestamp in the same style as `current-time'."
(nth 5 attributes)))
(unless (fboundp 'file-attribute-size)
@@ -179,9 +214,9 @@ This is a floating point number if the size is too large for an integer."
Case is significant."
(string< s1 s2)))
-;; The time- functions below translate nil to `current-time` and
-;; accept an integer as of Emacs 25. `decode-time` and
-;; `format-time-string` accept nil on Emacs 24 but don't accept an
+;; The time- functions below translate nil to 'current-time' and
+;; accept an integer as of Emacs 25. 'decode-time' and
+;; 'format-time-string' accept nil on Emacs 24 but don't accept an
;; integer until Emacs 25.
(if (< emacs-major-version 25)
(let ((convert
@@ -212,38 +247,38 @@ Case is significant."
;;; Obsolete aliases (remove them after the next major release).
;;;; XEmacs compatibility, now removed.
-(define-obsolete-function-alias 'org-activate-mark 'activate-mark "Org 9.0")
-(define-obsolete-function-alias 'org-add-hook 'add-hook "Org 9.0")
-(define-obsolete-function-alias 'org-bound-and-true-p 'bound-and-true-p "Org 9.0")
-(define-obsolete-function-alias 'org-decompose-region 'decompose-region "Org 9.0")
-(define-obsolete-function-alias 'org-defvaralias 'defvaralias "Org 9.0")
-(define-obsolete-function-alias 'org-detach-overlay 'delete-overlay "Org 9.0")
-(define-obsolete-function-alias 'org-file-equal-p 'file-equal-p "Org 9.0")
-(define-obsolete-function-alias 'org-float-time 'float-time "Org 9.0")
-(define-obsolete-function-alias 'org-indent-line-to 'indent-line-to "Org 9.0")
-(define-obsolete-function-alias 'org-indent-to-column 'indent-to-column "Org 9.0")
-(define-obsolete-function-alias 'org-looking-at-p 'looking-at-p "Org 9.0")
-(define-obsolete-function-alias 'org-looking-back 'looking-back "Org 9.0")
-(define-obsolete-function-alias 'org-match-string-no-properties 'match-string-no-properties "Org 9.0")
-(define-obsolete-function-alias 'org-propertize 'propertize "Org 9.0")
-(define-obsolete-function-alias 'org-select-frame-set-input-focus 'select-frame-set-input-focus "Org 9.0")
-(define-obsolete-function-alias 'org-file-remote-p 'file-remote-p "Org 9.2")
+(define-obsolete-function-alias 'org-activate-mark 'activate-mark "9.0")
+(define-obsolete-function-alias 'org-add-hook 'add-hook "9.0")
+(define-obsolete-function-alias 'org-bound-and-true-p 'bound-and-true-p "9.0")
+(define-obsolete-function-alias 'org-decompose-region 'decompose-region "9.0")
+(define-obsolete-function-alias 'org-defvaralias 'defvaralias "9.0")
+(define-obsolete-function-alias 'org-detach-overlay 'delete-overlay "9.0")
+(define-obsolete-function-alias 'org-file-equal-p 'file-equal-p "9.0")
+(define-obsolete-function-alias 'org-float-time 'float-time "9.0")
+(define-obsolete-function-alias 'org-indent-line-to 'indent-line-to "9.0")
+(define-obsolete-function-alias 'org-indent-to-column 'indent-to-column "9.0")
+(define-obsolete-function-alias 'org-looking-at-p 'looking-at-p "9.0")
+(define-obsolete-function-alias 'org-looking-back 'looking-back "9.0")
+(define-obsolete-function-alias 'org-match-string-no-properties 'match-string-no-properties "9.0")
+(define-obsolete-function-alias 'org-propertize 'propertize "9.0")
+(define-obsolete-function-alias 'org-select-frame-set-input-focus 'select-frame-set-input-focus "9.0")
+(define-obsolete-function-alias 'org-file-remote-p 'file-remote-p "9.2")
(defmacro org-re (s)
"Replace posix classes in regular expression S."
(declare (debug (form))
- (obsolete "you can safely remove it." "Org 9.0"))
+ (obsolete "you can safely remove it." "9.0"))
s)
;;;; Functions from cl-lib that Org used to have its own implementation of.
-(define-obsolete-function-alias 'org-count 'cl-count "Org 9.0")
-(define-obsolete-function-alias 'org-every 'cl-every "Org 9.0")
-(define-obsolete-function-alias 'org-find-if 'cl-find-if "Org 9.0")
-(define-obsolete-function-alias 'org-reduce 'cl-reduce "Org 9.0")
-(define-obsolete-function-alias 'org-remove-if 'cl-remove-if "Org 9.0")
-(define-obsolete-function-alias 'org-remove-if-not 'cl-remove-if-not "Org 9.0")
-(define-obsolete-function-alias 'org-some 'cl-some "Org 9.0")
-(define-obsolete-function-alias 'org-floor* 'cl-floor "Org 9.0")
+(define-obsolete-function-alias 'org-count 'cl-count "9.0")
+(define-obsolete-function-alias 'org-every 'cl-every "9.0")
+(define-obsolete-function-alias 'org-find-if 'cl-find-if "9.0")
+(define-obsolete-function-alias 'org-reduce 'cl-reduce "9.0")
+(define-obsolete-function-alias 'org-remove-if 'cl-remove-if "9.0")
+(define-obsolete-function-alias 'org-remove-if-not 'cl-remove-if-not "9.0")
+(define-obsolete-function-alias 'org-some 'cl-some "9.0")
+(define-obsolete-function-alias 'org-floor* 'cl-floor "9.0")
(defun org-sublist (list start end)
"Return a section of LIST, from START to END.
@@ -251,89 +286,91 @@ Counting starts at 1."
(cl-subseq list (1- start) end))
(make-obsolete 'org-sublist
"use cl-subseq (note the 0-based counting)."
- "Org 9.0")
+ "9.0")
;;;; Functions available since Emacs 24.3
-(define-obsolete-function-alias 'org-buffer-narrowed-p 'buffer-narrowed-p "Org 9.0")
-(define-obsolete-function-alias 'org-called-interactively-p 'called-interactively-p "Org 9.0")
-(define-obsolete-function-alias 'org-char-to-string 'char-to-string "Org 9.0")
-(define-obsolete-function-alias 'org-delete-directory 'delete-directory "Org 9.0")
-(define-obsolete-function-alias 'org-format-seconds 'format-seconds "Org 9.0")
-(define-obsolete-function-alias 'org-link-escape-browser 'url-encode-url "Org 9.0")
-(define-obsolete-function-alias 'org-no-warnings 'with-no-warnings "Org 9.0")
-(define-obsolete-function-alias 'org-number-sequence 'number-sequence "Org 9.0")
-(define-obsolete-function-alias 'org-pop-to-buffer-same-window 'pop-to-buffer-same-window "Org 9.0")
-(define-obsolete-function-alias 'org-string-match-p 'string-match-p "Org 9.0")
+(define-obsolete-function-alias 'org-buffer-narrowed-p 'buffer-narrowed-p "9.0")
+(define-obsolete-function-alias 'org-called-interactively-p 'called-interactively-p "9.0")
+(define-obsolete-function-alias 'org-char-to-string 'char-to-string "9.0")
+(define-obsolete-function-alias 'org-delete-directory 'delete-directory "9.0")
+(define-obsolete-function-alias 'org-format-seconds 'format-seconds "9.0")
+(define-obsolete-function-alias 'org-link-escape-browser 'url-encode-url "9.0")
+(define-obsolete-function-alias 'org-no-warnings 'with-no-warnings "9.0")
+(define-obsolete-function-alias 'org-number-sequence 'number-sequence "9.0")
+(define-obsolete-function-alias 'org-pop-to-buffer-same-window 'pop-to-buffer-same-window "9.0")
+(define-obsolete-function-alias 'org-string-match-p 'string-match-p "9.0")
;;;; Functions and variables from previous releases now obsolete.
(define-obsolete-function-alias 'org-element-remove-indentation
- 'org-remove-indentation "Org 9.0")
+ 'org-remove-indentation "9.0")
(define-obsolete-variable-alias 'org-latex-create-formula-image-program
- 'org-preview-latex-default-process "Org 9.0")
+ 'org-preview-latex-default-process "9.0")
(define-obsolete-variable-alias 'org-latex-preview-ltxpng-directory
- 'org-preview-latex-image-directory "Org 9.0")
-(define-obsolete-function-alias 'org-table-p 'org-at-table-p "Org 9.0")
-(define-obsolete-function-alias 'org-on-heading-p 'org-at-heading-p "Org 9.0")
-(define-obsolete-function-alias 'org-at-regexp-p 'org-in-regexp "Org 8.3")
+ 'org-preview-latex-image-directory "9.0")
+(define-obsolete-function-alias 'org-table-p 'org-at-table-p "9.0")
+(define-obsolete-function-alias 'org-on-heading-p 'org-at-heading-p "9.0")
+(define-obsolete-function-alias 'org-at-regexp-p 'org-in-regexp "8.3")
(define-obsolete-function-alias 'org-image-file-name-regexp
- 'image-file-name-regexp "Org 9.0")
+ 'image-file-name-regexp "9.0")
(define-obsolete-function-alias 'org-completing-read-no-i
- 'completing-read "Org 9.0")
+ 'completing-read "9.0")
(define-obsolete-function-alias 'org-icompleting-read
- 'completing-read "Org 9.0")
-(define-obsolete-function-alias 'org-iread-file-name 'read-file-name "Org 9.0")
+ 'completing-read "9.0")
+(define-obsolete-function-alias 'org-iread-file-name 'read-file-name "9.0")
(define-obsolete-function-alias 'org-days-to-time
- 'org-time-stamp-to-now "Org 8.2")
+ 'org-time-stamp-to-now "8.2")
(define-obsolete-variable-alias 'org-agenda-ignore-drawer-properties
- 'org-agenda-ignore-properties "Org 9.0")
+ 'org-agenda-ignore-properties "9.0")
(define-obsolete-function-alias 'org-preview-latex-fragment
- 'org-toggle-latex-fragment "Org 8.3")
+ 'org-toggle-latex-fragment "8.3")
(define-obsolete-function-alias 'org-export-get-genealogy
- 'org-element-lineage "Org 9.0")
+ 'org-element-lineage "9.0")
(define-obsolete-variable-alias 'org-latex-with-hyperref
- 'org-latex-hyperref-template "Org 9.0")
-(define-obsolete-variable-alias 'hfy-optimisations 'hfy-optimizations "Org 9.0")
+ 'org-latex-hyperref-template "9.0")
+(define-obsolete-variable-alias 'hfy-optimisations 'hfy-optimizations "9.0")
(define-obsolete-variable-alias 'org-export-htmlized-org-css-url
- 'org-org-htmlized-css-url "Org 8.2")
-(define-obsolete-function-alias 'org-list-parse-list 'org-list-to-lisp "Org 9.0")
+ 'org-org-htmlized-css-url "8.2")
+(define-obsolete-function-alias 'org-list-parse-list 'org-list-to-lisp "9.0")
(define-obsolete-function-alias 'org-agenda-todayp
- 'org-agenda-today-p "Org 9.0")
+ 'org-agenda-today-p "9.0")
(define-obsolete-function-alias 'org-babel-examplize-region
- 'org-babel-examplify-region "Org 9.0")
+ 'org-babel-examplify-region "9.0")
(define-obsolete-variable-alias 'org-babel-capitalize-example-region-markers
- 'org-babel-uppercase-example-markers "Org 9.1")
+ 'org-babel-uppercase-example-markers "9.1")
-(define-obsolete-function-alias 'org-babel-trim 'org-trim "Org 9.0")
+(define-obsolete-function-alias 'org-babel-trim 'org-trim "9.0")
(define-obsolete-variable-alias 'org-html-style 'org-html-head "24.4")
(define-obsolete-function-alias 'org-insert-columns-dblock
- 'org-columns-insert-dblock "Org 9.0")
+ 'org-columns-insert-dblock "9.0")
(define-obsolete-variable-alias 'org-export-babel-evaluate
- 'org-export-use-babel "Org 9.1")
+ 'org-export-use-babel "9.1")
(define-obsolete-function-alias 'org-activate-bracket-links
- 'org-activate-links "Org 9.0")
-(define-obsolete-function-alias 'org-activate-plain-links 'ignore "Org 9.0")
-(define-obsolete-function-alias 'org-activate-angle-links 'ignore "Org 9.0")
-(define-obsolete-function-alias 'org-remove-double-quotes 'org-strip-quotes "Org 9.0")
+ 'org-activate-links "9.0")
+(define-obsolete-function-alias 'org-activate-plain-links 'ignore "9.0")
+(define-obsolete-function-alias 'org-activate-angle-links 'ignore "9.0")
+(define-obsolete-function-alias 'org-remove-double-quotes 'org-strip-quotes "9.0")
(define-obsolete-function-alias 'org-get-indentation
- 'current-indentation "Org 9.2")
-(define-obsolete-function-alias 'org-capture-member 'org-capture-get "Org 9.2")
+ 'current-indentation "9.2")
+(define-obsolete-function-alias 'org-capture-member 'org-capture-get "9.2")
(define-obsolete-function-alias 'org-remove-from-invisibility-spec
- 'remove-from-invisibility-spec "Org 9.2")
+ 'remove-from-invisibility-spec "9.2")
(define-obsolete-variable-alias 'org-effort-durations 'org-duration-units
- "Org 9.2")
+ "9.2")
(define-obsolete-function-alias 'org-toggle-latex-fragment 'org-latex-preview
- "Org 9.3")
+ "9.3")
(define-obsolete-function-alias 'org-remove-latex-fragment-image-overlays
- 'org-clear-latex-preview "Org 9.3")
+ 'org-clear-latex-preview "9.3")
(define-obsolete-variable-alias 'org-attach-directory
- 'org-attach-id-dir "Org 9.3")
-(make-obsolete 'org-attach-store-link "No longer used" "Org 9.4")
-(make-obsolete 'org-attach-expand-link "No longer used" "Org 9.4")
+ 'org-attach-id-dir "9.3")
+(make-obsolete 'org-attach-store-link "No longer used" "9.4")
+(make-obsolete 'org-attach-expand-link "No longer used" "9.4")
+
+(define-obsolete-function-alias 'org-file-url-p 'org-url-p "9.5")
(defun org-in-fixed-width-region-p ()
"Non-nil if point in a fixed-width region."
@@ -341,7 +378,7 @@ Counting starts at 1."
(eq 'fixed-width (org-element-type (org-element-at-point)))))
(make-obsolete 'org-in-fixed-width-region-p
"use `org-element' library"
- "Org 9.0")
+ "9.0")
(defun org-compatible-face (inherits specs)
"Make a compatible face specification.
@@ -352,7 +389,7 @@ is, use SPECS to define the face."
(if (facep inherits)
(list (list t :inherit inherits))
specs))
-(make-obsolete 'org-compatible-face "you can remove it." "Org 9.0")
+(make-obsolete 'org-compatible-face "you can remove it." "9.0")
(defun org-add-link-type (type &optional follow export)
"Add a new TYPE link.
@@ -383,7 +420,7 @@ See `org-link-parameters' for documentation on the other parameters."
(org-link-set-parameters type :follow follow :export export)
(message "Created %s link." type))
-(make-obsolete 'org-add-link-type "use `org-link-set-parameters' instead." "Org 9.0")
+(make-obsolete 'org-add-link-type "use `org-link-set-parameters' instead." "9.0")
;;;; Functions unused in Org core.
(defun org-table-recognize-table.el ()
@@ -407,12 +444,12 @@ See `org-link-parameters' for documentation on the other parameters."
;; Not used since commit 6d1e3082, Feb 2010.
(make-obsolete 'org-table-recognize-table.el
"please notify Org mailing list if you use this function."
- "Org 9.0")
+ "9.0")
(defmacro org-preserve-lc (&rest body)
(declare (debug (body))
(obsolete "please notify Org mailing list if you use this function."
- "Org 9.2"))
+ "9.2"))
(org-with-gensyms (line col)
`(let ((,line (org-current-line))
(,col (current-column)))
@@ -424,12 +461,12 @@ See `org-link-parameters' for documentation on the other parameters."
(defun org-version-check (version &rest _)
"Non-nil if VERSION is lower (older) than `emacs-version'."
(declare (obsolete "use `version<' or `fboundp' instead."
- "Org 9.2"))
+ "9.2"))
(version< version emacs-version))
(defun org-remove-angle-brackets (s)
(org-unbracket-string "<" ">" s))
-(make-obsolete 'org-remove-angle-brackets 'org-unbracket-string "Org 9.0")
+(make-obsolete 'org-remove-angle-brackets 'org-unbracket-string "9.0")
(defcustom org-publish-sitemap-file-entry-format "%t"
"Format string for site-map file entry.
@@ -443,7 +480,7 @@ You could use brackets to delimit on what part the link will be.
(make-obsolete-variable
'org-publish-sitemap-file-entry-format
"set `:sitemap-format-entry' in `org-publish-project-alist' instead."
- "Org 9.1")
+ "9.1")
(defvar org-agenda-skip-regexp)
(defun org-agenda-skip-entry-when-regexp-matches ()
@@ -452,7 +489,7 @@ If yes, it returns the end position of this entry, causing agenda commands
to skip the entry but continuing the search in the subtree. This is a
function that can be put into `org-agenda-skip-function' for the duration
of a command."
- (declare (obsolete "use `org-agenda-skip-if' instead." "Org 9.1"))
+ (declare (obsolete "use `org-agenda-skip-if' instead." "9.1"))
(let ((end (save-excursion (org-end-of-subtree t)))
skip)
(save-excursion
@@ -464,7 +501,7 @@ of a command."
If yes, it returns the end position of this tree, causing agenda commands
to skip this subtree. This is a function that can be put into
`org-agenda-skip-function' for the duration of a command."
- (declare (obsolete "use `org-agenda-skip-if' instead." "Org 9.1"))
+ (declare (obsolete "use `org-agenda-skip-if' instead." "9.1"))
(let ((end (save-excursion (org-end-of-subtree t)))
skip)
(save-excursion
@@ -478,7 +515,7 @@ causing agenda commands to skip the entry but continuing the search in
the subtree. This is a function that can be put into
`org-agenda-skip-function' for the duration of a command. An important
use of this function is for the stuck project list."
- (declare (obsolete "use `org-agenda-skip-if' instead." "Org 9.1"))
+ (declare (obsolete "use `org-agenda-skip-if' instead." "9.1"))
(let ((end (save-excursion (org-end-of-subtree t)))
(entry-end (save-excursion (outline-next-heading) (1- (point))))
skip)
@@ -487,126 +524,126 @@ use of this function is for the stuck project list."
(and skip entry-end)))
(define-obsolete-function-alias 'org-minutes-to-clocksum-string
- 'org-duration-from-minutes "Org 9.1")
+ 'org-duration-from-minutes "9.1")
(define-obsolete-function-alias 'org-hh:mm-string-to-minutes
- 'org-duration-to-minutes "Org 9.1")
+ 'org-duration-to-minutes "9.1")
(define-obsolete-function-alias 'org-duration-string-to-minutes
- 'org-duration-to-minutes "Org 9.1")
+ 'org-duration-to-minutes "9.1")
(make-obsolete-variable 'org-time-clocksum-format
- "set `org-duration-format' instead." "Org 9.1")
+ "set `org-duration-format' instead." "9.1")
(make-obsolete-variable 'org-time-clocksum-use-fractional
- "set `org-duration-format' instead." "Org 9.1")
+ "set `org-duration-format' instead." "9.1")
(make-obsolete-variable 'org-time-clocksum-fractional-format
- "set `org-duration-format' instead." "Org 9.1")
+ "set `org-duration-format' instead." "9.1")
(make-obsolete-variable 'org-time-clocksum-use-effort-durations
- "set `org-duration-units' instead." "Org 9.1")
+ "set `org-duration-units' instead." "9.1")
(define-obsolete-function-alias 'org-babel-number-p
- 'org-babel--string-to-number "Org 9.0")
+ 'org-babel--string-to-number "9.0")
(define-obsolete-variable-alias 'org-usenet-links-prefer-google
- 'org-gnus-prefer-web-links "Org 9.1")
+ 'org-gnus-prefer-web-links "9.1")
(define-obsolete-variable-alias 'org-texinfo-def-table-markup
- 'org-texinfo-table-default-markup "Org 9.1")
+ 'org-texinfo-table-default-markup "9.1")
(define-obsolete-variable-alias 'org-agenda-overriding-columns-format
- 'org-overriding-columns-format "Org 9.2.2")
+ 'org-overriding-columns-format "9.2.2")
(define-obsolete-variable-alias 'org-doi-server-url
- 'org-link-doi-server-url "Org 9.3")
+ 'org-link-doi-server-url "9.3")
(define-obsolete-variable-alias 'org-email-link-description-format
- 'org-link-email-description-format "Org 9.3")
+ 'org-link-email-description-format "9.3")
(define-obsolete-variable-alias 'org-make-link-description-function
- 'org-link-make-description-function "Org 9.3")
+ 'org-link-make-description-function "9.3")
(define-obsolete-variable-alias 'org-from-is-user-regexp
- 'org-link-from-user-regexp "Org 9.3")
+ 'org-link-from-user-regexp "9.3")
(define-obsolete-variable-alias 'org-descriptive-links
- 'org-link-descriptive "Org 9.3")
+ 'org-link-descriptive "9.3")
(define-obsolete-variable-alias 'org-context-in-file-links
- 'org-link-context-for-files "Org 9.3")
+ 'org-link-context-for-files "9.3")
(define-obsolete-variable-alias 'org-keep-stored-link-after-insertion
- 'org-link-keep-stored-after-insertion "Org 9.3")
+ 'org-link-keep-stored-after-insertion "9.3")
(define-obsolete-variable-alias 'org-display-internal-link-with-indirect-buffer
- 'org-link-use-indirect-buffer-for-internals "Org 9.3")
+ 'org-link-use-indirect-buffer-for-internals "9.3")
(define-obsolete-variable-alias 'org-confirm-shell-link-function
- 'org-link-shell-confirm-function "Org 9.3")
+ 'org-link-shell-confirm-function "9.3")
(define-obsolete-variable-alias 'org-confirm-shell-link-not-regexp
- 'org-link-shell-skip-confirm-regexp "Org 9.3")
+ 'org-link-shell-skip-confirm-regexp "9.3")
(define-obsolete-variable-alias 'org-confirm-elisp-link-function
- 'org-link-elisp-confirm-function "Org 9.3")
+ 'org-link-elisp-confirm-function "9.3")
(define-obsolete-variable-alias 'org-confirm-elisp-link-not-regexp
- 'org-link-elisp-skip-confirm-regexp "Org 9.3")
+ 'org-link-elisp-skip-confirm-regexp "9.3")
(define-obsolete-function-alias 'org-file-complete-link
- 'org-link-complete-file "Org 9.3")
+ 'org-link-complete-file "9.3")
(define-obsolete-function-alias 'org-email-link-description
- 'org-link-email-description "Org 9.3")
+ 'org-link-email-description "9.3")
(define-obsolete-function-alias 'org-make-link-string
- 'org-link-make-string "Org 9.3")
+ 'org-link-make-string "9.3")
(define-obsolete-function-alias 'org-store-link-props
- 'org-link-store-props "Org 9.3")
+ 'org-link-store-props "9.3")
(define-obsolete-function-alias 'org-add-link-props
- 'org-link-add-props "Org 9.3")
+ 'org-link-add-props "9.3")
(define-obsolete-function-alias 'org-make-org-heading-search-string
- 'org-link-heading-search-string "Org 9.3")
+ 'org-link-heading-search-string "9.3")
(define-obsolete-function-alias 'org-make-link-regexps
- 'org-link-make-regexps "Org 9.3")
+ 'org-link-make-regexps "9.3")
(define-obsolete-function-alias 'org-property-global-value
- 'org-property-global-or-keyword-value "Org 9.3")
+ 'org-property-global-or-keyword-value "9.3")
-(make-obsolete-variable 'org-file-properties 'org-keyword-properties "Org 9.3")
+(make-obsolete-variable 'org-file-properties 'org-keyword-properties "9.3")
(define-obsolete-variable-alias 'org-angle-link-re
- 'org-link-angle-re "Org 9.3")
+ 'org-link-angle-re "9.3")
(define-obsolete-variable-alias 'org-plain-link-re
- 'org-link-plain-re "Org 9.3")
+ 'org-link-plain-re "9.3")
(define-obsolete-variable-alias 'org-bracket-link-regexp
- 'org-link-bracket-re "Org 9.3")
+ 'org-link-bracket-re "9.3")
(define-obsolete-variable-alias 'org-bracket-link-analytic-regexp
- 'org-link-bracket-re "Org 9.3")
+ 'org-link-bracket-re "9.3")
(define-obsolete-variable-alias 'org-any-link-re
- 'org-link-any-re "Org 9.3")
+ 'org-link-any-re "9.3")
(define-obsolete-function-alias 'org-open-link-from-string
- 'org-link-open-from-string "Org 9.3")
+ 'org-link-open-from-string "9.3")
(define-obsolete-function-alias 'org-add-angle-brackets
- 'org-link-add-angle-brackets "Org 9.3")
+ 'org-link-add-angle-brackets "9.3")
;; The function was made obsolete by commit 65399674d5 of 2013-02-22.
;; This make-obsolete call was added 2016-09-01.
(make-obsolete 'org-capture-import-remember-templates
"use the `org-capture-templates' variable instead."
- "Org 9.0")
+ "9.0")
(defun org-show-block-all ()
"Unfold all blocks in the current buffer."
@@ -615,34 +652,34 @@ use of this function is for the stuck project list."
(make-obsolete 'org-show-block-all
"use `org-show-all' instead."
- "Org 9.2")
+ "9.2")
-(define-obsolete-function-alias 'org-get-tags-at 'org-get-tags "Org 9.2")
+(define-obsolete-function-alias 'org-get-tags-at 'org-get-tags "9.2")
(defun org-get-local-tags ()
"Get a list of tags defined in the current headline."
- (declare (obsolete "use `org-get-tags' instead." "Org 9.2"))
+ (declare (obsolete "use `org-get-tags' instead." "9.2"))
(org-get-tags nil 'local))
(defun org-get-local-tags-at (&optional pos)
"Get a list of tags defined in the current headline."
- (declare (obsolete "use `org-get-tags' instead." "Org 9.2"))
+ (declare (obsolete "use `org-get-tags' instead." "9.2"))
(org-get-tags pos 'local))
(defun org-get-tags-string ()
"Get the TAGS string in the current headline."
- (declare (obsolete "use `org-make-tag-string' instead." "Org 9.2"))
+ (declare (obsolete "use `org-make-tag-string' instead." "9.2"))
(org-make-tag-string (org-get-tags nil t)))
-(define-obsolete-function-alias 'org-set-tags-to 'org-set-tags "Org 9.2")
+(define-obsolete-function-alias 'org-set-tags-to 'org-set-tags "9.2")
(defun org-align-all-tags ()
"Align the tags in all headings."
- (declare (obsolete "use `org-align-tags' instead." "Org 9.2"))
+ (declare (obsolete "use `org-align-tags' instead." "9.2"))
(org-align-tags t))
(define-obsolete-function-alias
- 'org-at-property-block-p 'org-at-property-drawer-p "Org 9.4")
+ 'org-at-property-block-p 'org-at-property-drawer-p "9.4")
(defun org-flag-drawer (flag &optional element beg end)
"When FLAG is non-nil, hide the drawer we are at.
@@ -653,7 +690,7 @@ When optional argument ELEMENT is a parsed drawer, as returned by
When buffer positions BEG and END are provided, hide or show that
region as a drawer without further ado."
- (declare (obsolete "use `org-hide-drawer-toggle' instead." "Org 9.4"))
+ (declare (obsolete "use `org-hide-drawer-toggle' instead." "9.4"))
(if (and beg end) (org-flag-region beg end flag 'outline)
(let ((drawer
(or element
@@ -678,14 +715,14 @@ region as a drawer without further ado."
"Toggle visibility of block at point.
Unlike to `org-hide-block-toggle', this function does not throw
an error. Return a non-nil value when toggling is successful."
- (declare (obsolete "use `org-hide-block-toggle' instead." "Org 9.4"))
+ (declare (obsolete "use `org-hide-block-toggle' instead." "9.4"))
(interactive)
(org-hide-block-toggle nil t))
(defun org-hide-block-toggle-all ()
"Toggle the visibility of all blocks in the current buffer."
(declare (obsolete "please notify Org mailing list if you use this function."
- "Org 9.4"))
+ "9.4"))
(let ((start (point-min))
(end (point-max)))
(save-excursion
@@ -703,17 +740,17 @@ an error. Return a non-nil value when toggling is successful."
Calls `org-table-next-row' or `newline-and-indent', depending on
context. See the individual commands for more information."
(declare (obsolete "use `org-return' with INDENT set to t instead."
- "Org 9.4"))
+ "9.4"))
(interactive)
(org-return t))
(defmacro org-with-silent-modifications (&rest body)
- (declare (obsolete "use `with-silent-modifications' instead." "Org 9.2")
+ (declare (obsolete "use `with-silent-modifications' instead." "9.2")
(debug (body)))
`(with-silent-modifications ,@body))
(define-obsolete-function-alias 'org-babel-strip-quotes
- 'org-strip-quotes "Org 9.2")
+ 'org-strip-quotes "9.2")
(define-obsolete-variable-alias 'org-sort-agenda-notime-is-late
'org-agenda-sort-notime-is-late "9.4")
@@ -730,7 +767,11 @@ context. See the individual commands for more information."
(make-obsolete-variable
'org-maybe-keyword-time-regexp
"use `org-planning-line-re', followed by `org-ts-regexp-both' instead."
- "Org 9.4")
+ "9.4")
+
+(define-obsolete-function-alias 'org-copy 'org-refile-copy "9.4")
+
+(define-obsolete-function-alias 'org-get-last-sibling 'org-get-previous-sibling "9.4")
;;;; Obsolete link types
@@ -1023,8 +1064,7 @@ ELEMENT is the element at point."
(defun org-mode-flyspell-verify ()
"Function used for `flyspell-generic-check-word-predicate'."
(if (org-at-heading-p)
- ;; At a headline or an inlinetask, check title only. This is
- ;; faster than relying on `org-element-at-point'.
+ ;; At a headline or an inlinetask, check title only.
(and (save-excursion (beginning-of-line)
(and (let ((case-fold-search t))
(not (looking-at-p "\\*+ END[ \t]*$")))
@@ -1033,7 +1073,9 @@ ELEMENT is the element at point."
(match-beginning 4)
(>= (point) (match-beginning 4))
(or (not (match-beginning 5))
- (< (point) (match-beginning 5))))
+ (< (point) (match-beginning 5)))
+ ;; Ignore checks in code, verbatim and others.
+ (org--flyspell-object-check-p (org-element-at-point)))
(let* ((element (org-element-at-point))
(post-affiliated (org-element-property :post-affiliated element)))
(cond
@@ -1102,14 +1144,7 @@ ELEMENT is the element at point."
(org-show-context 'bookmark-jump)))
;; Make `bookmark-jump' shows the jump location if it was hidden.
-(eval-after-load 'bookmark
- '(if (boundp 'bookmark-after-jump-hook)
- ;; We can use the hook
- (add-hook 'bookmark-after-jump-hook 'org-bookmark-jump-unhide)
- ;; Hook not available, use advice
- (defadvice bookmark-jump (after org-make-visible activate)
- "Make the position visible."
- (org-bookmark-jump-unhide))))
+(add-hook 'bookmark-after-jump-hook 'org-bookmark-jump-unhide)
;;;; Calendar
@@ -1206,6 +1241,11 @@ key."
(eval-after-load 'session
'(add-to-list 'session-globals-exclude 'org-mark-ring))
+;;;; Speed commands
+
+(make-obsolete-variable 'org-speed-commands-user
+ "configure `org-speed-commands' instead." "9.5")
+
(provide 'org-compat)
;; Local variables:
diff --git a/lisp/org/org-crypt.el b/lisp/org/org-crypt.el
index 103baeb49e0..48f76b79fd4 100644
--- a/lisp/org/org-crypt.el
+++ b/lisp/org/org-crypt.el
@@ -185,10 +185,10 @@ See `org-crypt-disable-auto-save'."
((eq org-crypt-disable-auto-save 'encrypt)
(message "org-decrypt: Enabling re-encryption on auto-save.")
(add-hook 'auto-save-hook
- (lambda ()
- (message "org-crypt: Re-encrypting all decrypted entries due to auto-save.")
- (org-encrypt-entries))
- nil t))
+ (lambda ()
+ (message "org-crypt: Re-encrypting all decrypted entries due to auto-save.")
+ (org-encrypt-entries))
+ nil t))
(t nil))))
(defun org-crypt-key-for-heading ()
diff --git a/lisp/org/org-ctags.el b/lisp/org/org-ctags.el
index dc2b3be6326..7876c6ef75f 100644
--- a/lisp/org/org-ctags.el
+++ b/lisp/org/org-ctags.el
@@ -3,10 +3,8 @@
;; Copyright (C) 2007-2021 Free Software Foundation, Inc.
;; Author: Paul Sexton <eeeickythump@gmail.com>
-
-
;; Keywords: org, wp
-;;
+
;; This file is part of GNU Emacs.
;;
;; GNU Emacs is free software: you can redistribute it and/or modify
@@ -22,6 +20,8 @@
;; 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:
+
;;
;; Synopsis
;; ========
diff --git a/lisp/org/org-datetree.el b/lisp/org/org-datetree.el
index 62bd46e2e97..74442b038a3 100644
--- a/lisp/org/org-datetree.el
+++ b/lisp/org/org-datetree.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2009-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
@@ -72,8 +72,8 @@ will be built under the headline at point."
(defun org-datetree--find-create-group
(d time-grouping &optional keep-restriction)
"Find or create an entry for date D.
-If time-period is day, group entries by day. If time-period is
-month, then group entries by month."
+If time-period is day, group entries by day.
+If time-period is month, then group entries by month."
(setq-local org-datetree-base-level 1)
(save-restriction
(if (eq keep-restriction 'subtree-at-point)
diff --git a/lisp/org/org-duration.el b/lisp/org/org-duration.el
index 29fae2dbf03..e627d0936ab 100644
--- a/lisp/org/org-duration.el
+++ b/lisp/org/org-duration.el
@@ -97,7 +97,11 @@ sure to call the following command:
:group 'org-agenda
:version "26.1"
:package-version '(Org . "9.1")
- :set (lambda (var val) (set-default var val) (org-duration-set-regexps))
+ :set (lambda (var val)
+ (set-default var val)
+ ;; Avoid recursive load at startup.
+ (when (featurep 'org-duration)
+ (org-duration-set-regexps)))
:initialize 'custom-initialize-changed
:type '(choice
(const :tag "H:MM" h:mm)
diff --git a/lisp/org/org-element.el b/lisp/org/org-element.el
index 31f5f78eae0..f8334ccbc60 100644
--- a/lisp/org/org-element.el
+++ b/lisp/org/org-element.el
@@ -117,6 +117,19 @@
;; `org-element-update-syntax' builds proper syntax regexps according
;; to current setup.
+(defconst org-element-citation-key-re
+ (rx "@" (group (one-or-more (any word "-.:?!`'/*@+|(){}<>&_^$#%~"))))
+ "Regexp matching a citation key.
+Key is located in match group 1.")
+
+(defconst org-element-citation-prefix-re
+ (rx "[cite"
+ (opt "/" (group (one-or-more (any "/_-" alnum)))) ;style
+ ":"
+ (zero-or-more (any "\t\n ")))
+ "Regexp matching a citation prefix.
+Style, if any, is located in match group 1.")
+
(defvar org-element-paragraph-separate nil
"Regexp to separate paragraphs in an Org buffer.
In the case of lines starting with \"#\" and \":\", this regexp
@@ -182,15 +195,17 @@ specially in `org-element--object-lex'.")
(nth 2 org-emphasis-regexp-components)))
;; Plain links.
(concat "\\<" link-types ":")
- ;; Objects starting with "[": regular link,
+ ;; Objects starting with "[": citations,
;; footnote reference, statistics cookie,
- ;; timestamp (inactive).
- (concat "\\[\\(?:"
- "fn:" "\\|"
- "\\[" "\\|"
- "[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}" "\\|"
- "[0-9]*\\(?:%\\|/[0-9]*\\)\\]"
- "\\)")
+ ;; timestamp (inactive) and regular link.
+ (format "\\[\\(?:%s\\)"
+ (mapconcat
+ #'identity
+ (list "cite[:/]"
+ "fn:"
+ "\\(?:[0-9]\\|\\(?:%\\|/[0-9]*\\)\\]\\)"
+ "\\[")
+ "\\|"))
;; Objects starting with "@": export snippets.
"@@"
;; Objects starting with "{": macro.
@@ -234,15 +249,15 @@ specially in `org-element--object-lex'.")
"List of recursive element types aka Greater Elements.")
(defconst org-element-all-objects
- '(bold code entity export-snippet footnote-reference inline-babel-call
- inline-src-block italic line-break latex-fragment link macro
- radio-target statistics-cookie strike-through subscript superscript
- table-cell target timestamp underline verbatim)
+ '(bold citation citation-reference code entity export-snippet
+ footnote-reference inline-babel-call inline-src-block italic line-break
+ latex-fragment link macro radio-target statistics-cookie strike-through
+ subscript superscript table-cell target timestamp underline verbatim)
"Complete list of object types.")
(defconst org-element-recursive-objects
- '(bold footnote-reference italic link subscript radio-target strike-through
- superscript table-cell underline)
+ '(bold citation footnote-reference italic link subscript radio-target
+ strike-through superscript table-cell underline)
"List of recursive object types.")
(defconst org-element-object-containers
@@ -331,9 +346,12 @@ Don't modify it, set `org-element-affiliated-keywords' instead.")
(defconst org-element-object-restrictions
(let* ((minimal-set '(bold code entity italic latex-fragment strike-through
subscript superscript underline verbatim))
- (standard-set (remq 'table-cell org-element-all-objects))
+ (standard-set
+ (remq 'citation-reference (remq 'table-cell org-element-all-objects)))
(standard-set-no-line-break (remq 'line-break standard-set)))
`((bold ,@standard-set)
+ (citation citation-reference)
+ (citation-reference ,@minimal-set)
(footnote-reference ,@standard-set)
(headline ,@standard-set-no-line-break)
(inlinetask ,@standard-set-no-line-break)
@@ -354,8 +372,8 @@ Don't modify it, set `org-element-affiliated-keywords' instead.")
;; Ignore inline babel call and inline source block as formulas
;; are possible. Also ignore line breaks and statistics
;; cookies.
- (table-cell export-snippet footnote-reference link macro radio-target
- target timestamp ,@minimal-set)
+ (table-cell citation export-snippet footnote-reference link macro
+ radio-target target timestamp ,@minimal-set)
(table-row table-cell)
(underline ,@standard-set)
(verse-block ,@standard-set)))
@@ -370,9 +388,11 @@ This alist also applies to secondary string. For example, an
still has an entry since one of its properties (`:title') does.")
(defconst org-element-secondary-value-alist
- '((headline :title)
+ '((citation :prefix :suffix)
+ (headline :title)
(inlinetask :title)
- (item :tag))
+ (item :tag)
+ (citation-reference :prefix :suffix))
"Alist between element types and locations of secondary values.")
(defconst org-element--pair-round-table
@@ -737,7 +757,9 @@ Return a list whose CAR is `drawer' and CDR is a plist containing
Assume point is at beginning of drawer."
(let ((case-fold-search t))
- (if (not (save-excursion (re-search-forward "^[ \t]*:END:[ \t]*$" limit t)))
+ (if (not (save-excursion
+ (goto-char (min limit (line-end-position)))
+ (re-search-forward "^[ \t]*:END:[ \t]*$" limit t)))
;; Incomplete drawer: parse it as a paragraph.
(org-element-paragraph-parser limit affiliated)
(save-excursion
@@ -999,7 +1021,10 @@ Assume point is at beginning of the headline."
(commentedp
(and (let (case-fold-search) (looking-at org-comment-string))
(goto-char (match-end 0))))
- (title-start (point))
+ (title-start (prog1 (point)
+ (unless (or todo priority commentedp)
+ ;; Headline like "* :tag:"
+ (skip-chars-backward " \t"))))
(tags (when (re-search-forward
"[ \t]+\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$"
(line-end-position)
@@ -2751,6 +2776,129 @@ CONTENTS is the contents of the object."
(format "*%s*" contents))
+;;;; Citation
+
+(defun org-element-citation-parser ()
+ "Parse citation object at point, if any.
+
+When at a citation object, return a list whose car is `citation'
+and cdr is a plist with `:style', `:prefix', `:suffix', `:begin',
+`:end', `:contents-begin', `:contents-end', and `:post-blank'
+keywords. Otherwise, return nil.
+
+Assume point is at the beginning of the citation."
+ (when (looking-at org-element-citation-prefix-re)
+ (let* ((begin (point))
+ (style (and (match-end 1)
+ (match-string-no-properties 1)))
+ ;; Ignore blanks between cite type and prefix or key.
+ (start (match-end 0))
+ (closing (with-syntax-table org-element--pair-square-table
+ (ignore-errors (scan-lists begin 1 0)))))
+ (save-excursion
+ (when (and closing
+ (re-search-forward org-element-citation-key-re closing t))
+ ;; Find prefix, if any.
+ (let ((first-key-end (match-end 0))
+ (types (org-element-restriction 'citation-reference))
+ (cite
+ (list 'citation
+ (list :style style
+ :begin begin
+ :post-blank (progn
+ (goto-char closing)
+ (skip-chars-forward " \t"))
+ :end (point)))))
+ ;; `:contents-begin' depends on the presence of
+ ;; a non-empty common prefix.
+ (goto-char first-key-end)
+ (if (not (search-backward ";" start t))
+ (org-element-put-property cite :contents-begin start)
+ (when (< start (point))
+ (org-element-put-property
+ cite :prefix
+ (org-element--parse-objects start (point) nil types cite)))
+ (forward-char)
+ (org-element-put-property cite :contents-begin (point)))
+ ;; `:contents-end' depends on the presence of a non-empty
+ ;; common suffix.
+ (goto-char (1- closing))
+ (skip-chars-backward " \r\t\n")
+ (let ((end (point)))
+ (if (or (not (search-backward ";" first-key-end t))
+ (re-search-forward org-element-citation-key-re end t))
+ (org-element-put-property cite :contents-end end)
+ (forward-char)
+ (when (< (point) end)
+ (org-element-put-property
+ cite :suffix
+ (org-element--parse-objects (point) end nil types cite)))
+ (org-element-put-property cite :contents-end (point))))
+ cite))))))
+
+(defun org-element-citation-interpreter (citation contents)
+ "Interpret CITATION object as Org syntax.
+CONTENTS is the contents of the object, as a string."
+ (let ((prefix (org-element-property :prefix citation))
+ (suffix (org-element-property :suffix citation))
+ (style (org-element-property :style citation)))
+ (concat "[cite"
+ (and style (concat "/" style))
+ ":"
+ (and prefix (concat (org-element-interpret-data prefix) ";"))
+ (if suffix
+ (concat contents (org-element-interpret-data suffix))
+ ;; Remove spurious semicolon.
+ (substring contents nil -1))
+ "]")))
+
+
+;;;; Citation Reference
+
+(defun org-element-citation-reference-parser ()
+ "Parse citation reference object at point, if any.
+
+When at a reference, return a list whose car is
+`citation-reference', and cdr is a plist with `:key',
+`:prefix', `:suffix', `:begin', `:end', and `:post-blank' keywords.
+
+Assume point is at the beginning of the reference."
+ (save-excursion
+ (let ((begin (point)))
+ (when (re-search-forward org-element-citation-key-re nil t)
+ (let* ((key (match-string-no-properties 1))
+ (key-start (match-beginning 0))
+ (key-end (match-end 0))
+ (separator (search-forward ";" nil t))
+ (end (or separator (point-max)))
+ (suffix-end (if separator (1- end) end))
+ (types (org-element-restriction 'citation-reference))
+ (reference
+ (list 'citation-reference
+ (list :key key
+ :begin begin
+ :end end
+ :post-blank 0))))
+ (when (< begin key-start)
+ (org-element-put-property
+ reference :prefix
+ (org-element--parse-objects begin key-start nil types reference)))
+ (when (< key-end suffix-end)
+ (org-element-put-property
+ reference :suffix
+ (org-element--parse-objects key-end suffix-end nil types reference)))
+ reference)))))
+
+(defun org-element-citation-reference-interpreter (citation-reference _)
+ "Interpret CITATION-REFERENCE object as Org syntax."
+ (concat (org-element-interpret-data
+ (org-element-property :prefix citation-reference))
+ "@" (org-element-property :key citation-reference)
+ (org-element-interpret-data
+ (org-element-property :suffix citation-reference))
+ ";"))
+
+
;;;; Code
(defun org-element-code-parser ()
@@ -3951,14 +4099,36 @@ element it has to parse."
;; There is no strict definition of a table.el
;; table. Try to prevent false positive while being
;; quick.
- (let ((rule-regexp "[ \t]*\\+\\(-+\\+\\)+[ \t]*$")
+ (let ((rule-regexp
+ (rx (zero-or-more (any " \t"))
+ "+"
+ (one-or-more (one-or-more "-") "+")
+ (zero-or-more (any " \t"))
+ eol))
+ (non-table.el-line
+ (rx bol
+ (zero-or-more (any " \t"))
+ (or eol (not (any "+| \t")))))
(next (line-beginning-position 2)))
- (and (looking-at rule-regexp)
- (save-excursion
- (forward-line)
- (re-search-forward "^[ \t]*\\($\\|[^|]\\)" limit t)
- (and (> (line-beginning-position) next)
- (org-match-line rule-regexp))))))
+ ;; Start with a full rule.
+ (and
+ (looking-at rule-regexp)
+ (< next limit) ;no room for a table.el table
+ (save-excursion
+ (end-of-line)
+ (cond
+ ;; Must end with a full rule.
+ ((not (re-search-forward non-table.el-line limit 'move))
+ (if (bolp) (forward-line -1) (beginning-of-line))
+ (looking-at rule-regexp))
+ ;; Ignore pseudo-tables with a single
+ ;; rule.
+ ((= next (line-beginning-position))
+ nil)
+ ;; Must end with a full rule.
+ (t
+ (forward-line -1)
+ (looking-at rule-regexp)))))))
(org-element-table-parser limit affiliated))
;; List.
((looking-at (org-item-re))
@@ -4322,7 +4492,7 @@ element or object. Meaningful values are `first-section',
TYPE is the type of the current element or object.
If PARENT? is non-nil, assume the next element or object will be
-located inside the current one. "
+located inside the current one."
(if parent?
(pcase type
(`headline 'section)
@@ -4413,7 +4583,11 @@ Elements are accumulated into ACC."
RESTRICTION is a list of object types, as symbols, that should be
looked after. This function assumes that the buffer is narrowed
to an appropriate container (e.g., a paragraph)."
- (if (memq 'table-cell restriction) (org-element-table-cell-parser)
+ (cond
+ ((memq 'table-cell restriction) (org-element-table-cell-parser))
+ ((memq 'citation-reference restriction)
+ (org-element-citation-reference-parser))
+ (t
(let* ((start (point))
(limit
;; Object regexp sometimes needs to have a peek at
@@ -4501,6 +4675,9 @@ to an appropriate container (e.g., a paragraph)."
((and ?f
(guard (memq 'footnote-reference restriction)))
(org-element-footnote-reference-parser))
+ ((and ?c
+ (guard (memq 'citation restriction)))
+ (org-element-citation-parser))
((and (or ?% ?/)
(guard (memq 'statistics-cookie restriction)))
(org-element-statistics-cookie-parser))
@@ -4515,8 +4692,8 @@ to an appropriate container (e.g., a paragraph)."
(or (eobp) (forward-char))))
(cond (found)
(limit (forward-char -1)
- (org-element-link-parser)) ;radio link
- (t nil))))))
+ (org-element-link-parser)) ;radio link
+ (t nil)))))))
(defun org-element--parse-objects (beg end acc restriction &optional parent)
"Parse objects between BEG and END and return recursive structure.
@@ -4640,7 +4817,7 @@ to interpret. Return Org syntax as a string."
(eq (org-element-property :pre-blank parent)
0)))))
""))))))
- (if (memq type '(org-data plain-text nil)) results
+ (if (memq type '(org-data nil)) results
;; Build white spaces. If no `:post-blank' property
;; is specified, assume its value is 0.
(let ((blank (or (org-element-property :post-blank data) 0)))
@@ -4655,19 +4832,18 @@ to interpret. Return Org syntax as a string."
"Return ELEMENT's affiliated keywords as Org syntax.
If there is no affiliated keyword, return the empty string."
(let ((keyword-to-org
- (function
- (lambda (key value)
- (let (dual)
- (when (member key org-element-dual-keywords)
- (setq dual (cdr value) value (car value)))
- (concat "#+" (downcase key)
- (and dual
- (format "[%s]" (org-element-interpret-data dual)))
- ": "
- (if (member key org-element-parsed-keywords)
- (org-element-interpret-data value)
- value)
- "\n"))))))
+ (lambda (key value)
+ (let (dual)
+ (when (member key org-element-dual-keywords)
+ (setq dual (cdr value) value (car value)))
+ (concat "#+" (downcase key)
+ (and dual
+ (format "[%s]" (org-element-interpret-data dual)))
+ ": "
+ (if (member key org-element-parsed-keywords)
+ (org-element-interpret-data value)
+ value)
+ "\n")))))
(mapconcat
(lambda (prop)
(let ((value (org-element-property prop element))
diff --git a/lisp/org/org-entities.el b/lisp/org/org-entities.el
index eb098993b77..9c5f626ab78 100644
--- a/lisp/org/org-entities.el
+++ b/lisp/org/org-entities.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2010-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>,
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>,
;; Ulf Stegemann <ulf at zeitform dot de>
;; Keywords: outlines, calendar, wp
;; Homepage: https://orgmode.org
@@ -114,6 +114,8 @@ packages to be loaded, add these packages to `org-latex-packages-alist'."
("igrave" "\\`{i}" nil "&igrave;" "i" "ì" "ì")
("Iacute" "\\'{I}" nil "&Iacute;" "I" "Í" "Í")
("iacute" "\\'{i}" nil "&iacute;" "i" "í" "í")
+ ("Idot" "\\.{I}" nil "&idot;" "I" "İ" "İ")
+ ("inodot" "\\i" nil "&inodot;" "i" "ı" "ı")
("Icirc" "\\^{I}" nil "&Icirc;" "I" "Î" "Î")
("icirc" "\\^{i}" nil "&icirc;" "i" "î" "î")
("Iuml" "\\\"{I}" nil "&Iuml;" "I" "Ï" "Ï")
diff --git a/lisp/org/org-faces.el b/lisp/org/org-faces.el
index c56873b54c5..b151045a958 100644
--- a/lisp/org/org-faces.el
+++ b/lisp/org/org-faces.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
@@ -38,13 +38,28 @@
:group 'org-faces)
(defface org-hide
- '((((background light)) (:foreground "white"))
+ '((default :inherit fixed-pitch)
+ (((background light)) (:foreground "white"))
(((background dark)) (:foreground "black")))
"Face used to hide leading stars in headlines.
The foreground color of this face should be equal to the background
color of the frame."
:group 'org-faces)
+(defface org-dispatcher-highlight
+ '((default :weight bold)
+ (((class color) (min-colors 88) (background dark))
+ :background "gray20" :foreground "gold1")
+ (((class color) (min-colors 88) (background light))
+ :background "SlateGray1" :foreground "DarkBlue")
+ (((class color) (min-colors 16) (background dark))
+ :foreground "yellow")
+ (((class color) (min-colors 16) (background light))
+ :foreground "blue")
+ (t :inverse-video t))
+ "Face for highlighted keys in the dispatcher."
+ :group 'org-faces)
+
(defface org-level-1 '((t :inherit outline-1))
"Face used for level 1 headlines."
:group 'org-faces)
@@ -153,6 +168,14 @@ set the properties in the `org-column' face. For example, set
"Face for headline with the ARCHIVE tag."
:group 'org-faces)
+(defface org-cite '((t :inherit link))
+ "Face for citations."
+ :group 'org-faces)
+
+(defface org-cite-key '((t :inherit link))
+ "Face for citation keys."
+ :group 'org-faces)
+
(defface org-link '((t :inherit link))
"Face for links."
:group 'org-faces)
@@ -179,7 +202,8 @@ set the properties in the `org-column' face. For example, set
:group 'org-faces)
(defface org-date
- '((((class color) (background light)) (:foreground "Purple" :underline t))
+ '((default :inherit fixed-pitch)
+ (((class color) (background light)) (:foreground "Purple" :underline t))
(((class color) (background dark)) (:foreground "Cyan" :underline t))
(t (:underline t)))
"Face for date/time stamps."
@@ -355,7 +379,8 @@ changes."
(sexp :tag "Face")))))
(defface org-table ;Copied from `font-lock-function-name-face'
- '((((class color) (min-colors 88) (background light)) (:foreground "Blue1"))
+ '((default :inherit fixed-pitch)
+ (((class color) (min-colors 88) (background light)) (:foreground "Blue1"))
(((class color) (min-colors 88) (background dark)) (:foreground "LightSkyBlue"))
(((class color) (min-colors 16) (background light)) (:foreground "Blue"))
(((class color) (min-colors 16) (background dark)) (:foreground "LightSkyBlue"))
@@ -371,7 +396,8 @@ changes."
:group 'org-faces)
(defface org-formula
- '((((class color) (min-colors 88) (background light)) (:foreground "Firebrick"))
+ '((default :inherit fixed-pitch)
+ (((class color) (min-colors 88) (background light)) (:foreground "Firebrick"))
(((class color) (min-colors 88) (background dark)) (:foreground "chocolate1"))
(((class color) (min-colors 8) (background light)) (:foreground "red"))
(((class color) (min-colors 8) (background dark)) (:foreground "red"))
@@ -379,12 +405,12 @@ changes."
"Face for formulas."
:group 'org-faces)
-(defface org-code '((t :inherit shadow))
+(defface org-code '((t :inherit (fixed-pitch shadow)))
"Face for fixed-width text like code snippets."
:group 'org-faces
:version "22.1")
-(defface org-meta-line '((t :inherit font-lock-comment-face))
+(defface org-meta-line '((t :inherit (fixed-pitch font-lock-comment-face)))
"Face for meta lines starting with \"#+\"."
:group 'org-faces
:version "22.1")
@@ -400,15 +426,18 @@ changes."
'((((class color) (background light)) (:foreground "midnight blue"))
(((class color) (background dark)) (:foreground "pale turquoise"))
(t nil))
- "Face for document date, author and email; i.e. that which
-follows a #+DATE:, #+AUTHOR: or #+EMAIL: keyword."
+ "Face for document information such as the author and date.
+This applies to the text that follows a #+SUBTITLE:, #+DATE:,
+#+AUTHOR: or #+EMAIL: keyword."
:group 'org-faces)
(defface org-document-info-keyword '((t :inherit shadow))
- "Face for #+TITLE:, #+AUTHOR:, #+EMAIL: and #+DATE: keywords."
+ "Face for document information keywords.
+This face applies to the #+TITLE:, #+SUBTITLE:, #+AUTHOR:,
+#+EMAIL: and #+DATE: keywords."
:group 'org-faces)
-(defface org-block `((t :inherit shadow
+(defface org-block `((t :inherit (fixed-pitch shadow)
,@(and (>= emacs-major-version 27) '(:extend t))))
"Face used for text inside various blocks.
@@ -430,7 +459,7 @@ verse and quote blocks are fontified using the `org-verse' and
"Face used for the line delimiting the end of source blocks."
:group 'org-faces)
-(defface org-verbatim '((t (:inherit shadow)))
+(defface org-verbatim '((t (:inherit (fixed-pitch shadow))))
"Face for fixed-with text like code snippets."
:group 'org-faces
:version "22.1")
@@ -478,6 +507,16 @@ content of these blocks will still be treated as Org syntax."
"Face used in agenda for captions and dates."
:group 'org-faces)
+(defface org-agenda-structure-secondary '((t (:inherit org-agenda-structure)))
+ "Face used for secondary information in agenda block headers."
+ :group 'org-faces)
+
+(defface org-agenda-structure-filter '((t (:inherit (org-warning org-agenda-structure))))
+ "Face used for the current type of task filter in the agenda.
+It inherits from `org-agenda-structure' so it can adapt to
+it (e.g. if that is assigned a diffent font height or family)."
+ :group 'org-faces)
+
(defface org-agenda-date '((t (:inherit org-agenda-structure)))
"Face used in agenda for normal days."
:group 'org-faces)
@@ -487,6 +526,10 @@ content of these blocks will still be treated as Org syntax."
"Face used in agenda for today."
:group 'org-faces)
+(defface org-agenda-date-weekend-today '((t (:inherit org-agenda-date-today)))
+ "Face used in agenda for today during weekends."
+ :group 'org-faces)
+
(defface org-agenda-clocking '((t (:inherit secondary-selection)))
"Face marking the current clock item in the agenda."
:group 'org-faces)
@@ -529,6 +572,11 @@ which days belong to the weekend."
"Face for items scheduled previously, and not yet done."
:group 'org-faces)
+(defface org-imminent-deadline '((t :inherit org-warning))
+ "Face for current deadlines in the agenda.
+See also `org-agenda-deadline-faces'."
+ :group 'org-faces)
+
(defface org-upcoming-deadline
'((((class color) (min-colors 88) (background light)) (:foreground "Firebrick"))
(((class color) (min-colors 88) (background dark)) (:foreground "chocolate1"))
@@ -544,7 +592,7 @@ See also `org-agenda-deadline-faces'."
See also `org-agenda-deadline-faces'.")
(defcustom org-agenda-deadline-faces
- '((1.0 . org-warning)
+ '((1.0 . org-imminent-deadline)
(0.5 . org-upcoming-deadline)
(0.0 . org-upcoming-distant-deadline))
"Faces for showing deadlines in the agenda.
diff --git a/lisp/org/org-feed.el b/lisp/org/org-feed.el
index 5dbd887ef50..5df3b697660 100644
--- a/lisp/org/org-feed.el
+++ b/lisp/org/org-feed.el
@@ -2,7 +2,7 @@
;;
;; Copyright (C) 2009-2021 Free Software Foundation, Inc.
;;
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
diff --git a/lisp/org/org-footnote.el b/lisp/org/org-footnote.el
index 3d42421e0db..fcc7579bad5 100644
--- a/lisp/org/org-footnote.el
+++ b/lisp/org/org-footnote.el
@@ -2,7 +2,7 @@
;;
;; Copyright (C) 2009-2021 Free Software Foundation, Inc.
;;
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
@@ -37,6 +37,7 @@
(declare-function org-at-comment-p "org" ())
(declare-function org-at-heading-p "org" (&optional ignored))
(declare-function org-back-over-empty-lines "org" ())
+(declare-function org-end-of-meta-data "org" (&optional full))
(declare-function org-edit-footnote-reference "org-src" ())
(declare-function org-element-at-point "org-element" ())
(declare-function org-element-class "org-element" (datum &optional parent))
@@ -280,13 +281,21 @@ otherwise."
(save-excursion (goto-char (org-element-property :end context))
(skip-chars-backward " \r\t\n")
(if (eq (org-element-class context) 'object) (point)
- (1+ (line-beginning-position 2))))))
+ (line-beginning-position 2)))))
+ ;; At the beginning of a footnote definition, right after the
+ ;; label, is OK.
+ ((eq type 'footnote-definition) (looking-at (rx space)))
;; Other elements are invalid.
((eq (org-element-class context) 'element) nil)
;; Just before object is fine.
((= (point) (org-element-property :begin context)))
;; Within recursive object too, but not in a link.
((eq type 'link) nil)
+ ((eq type 'table-cell)
+ ;; :contents-begin is not reliable on empty cells, so special
+ ;; case it.
+ (<= (save-excursion (skip-chars-backward " \t") (point))
+ (org-element-property :contents-end context)))
((let ((cbeg (org-element-property :contents-begin context))
(cend (org-element-property :contents-end context)))
(and cbeg (>= (point) cbeg) (<= (point) cend))))))))
@@ -704,7 +713,7 @@ function doesn't move point."
(concat "^\\*+[ \t]+" (regexp-quote org-footnote-section) "[ \t]*$")
nil t))
(goto-char (match-end 0))
- (forward-line)
+ (org-end-of-meta-data t)
(unless (bolp) (insert "\n")))
(t (org-footnote--clear-footnote-section)))
(when (zerop (org-back-over-empty-lines)) (insert "\n"))
diff --git a/lisp/org/org-goto.el b/lisp/org/org-goto.el
index 163aa580ef6..352bf9f2e52 100644
--- a/lisp/org/org-goto.el
+++ b/lisp/org/org-goto.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2012-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; This file is part of GNU Emacs.
@@ -203,40 +203,39 @@ When nil, you can use these keybindings to navigate the buffer:
"Let the user select a location in current buffer.
This function uses a recursive edit. It returns the selected
position or nil."
- (org-no-popups
- (let ((isearch-mode-map org-goto-local-auto-isearch-map)
- (isearch-hide-immediately nil)
- (isearch-search-fun-function
- (lambda () #'org-goto--local-search-headings))
- (help (or help org-goto-help)))
- (save-excursion
- (save-window-excursion
- (delete-other-windows)
- (and (get-buffer "*org-goto*") (kill-buffer "*org-goto*"))
- (pop-to-buffer-same-window
- (condition-case nil
- (make-indirect-buffer (current-buffer) "*org-goto*" t)
- (error (make-indirect-buffer (current-buffer) "*org-goto*" t))))
- (let (temp-buffer-show-function temp-buffer-show-hook)
- (with-output-to-temp-buffer "*Org Help*"
- (princ (format help (if org-goto-auto-isearch
- " Just type for auto-isearch."
- " n/p/f/b/u to navigate, q to quit.")))))
- (org-fit-window-to-buffer (get-buffer-window "*Org Help*"))
- (org-overview)
- (setq buffer-read-only t)
- (if (and (boundp 'org-goto-start-pos)
- (integer-or-marker-p org-goto-start-pos))
- (progn (goto-char org-goto-start-pos)
- (when (org-invisible-p)
- (org-show-set-visibility 'lineage)))
- (goto-char (point-min)))
- (let (org-special-ctrl-a/e) (org-beginning-of-line))
- (message "Select location and press RET")
- (use-local-map org-goto-map)
- (recursive-edit)))
- (kill-buffer "*org-goto*")
- (cons org-goto-selected-point org-goto-exit-command))))
+ (let ((isearch-mode-map org-goto-local-auto-isearch-map)
+ (isearch-hide-immediately nil)
+ (isearch-search-fun-function
+ (lambda () #'org-goto--local-search-headings))
+ (help (or help org-goto-help)))
+ (save-excursion
+ (save-window-excursion
+ (delete-other-windows)
+ (and (get-buffer "*org-goto*") (kill-buffer "*org-goto*"))
+ (pop-to-buffer-same-window
+ (condition-case nil
+ (make-indirect-buffer (current-buffer) "*org-goto*" t)
+ (error (make-indirect-buffer (current-buffer) "*org-goto*" t))))
+ (let (temp-buffer-show-function temp-buffer-show-hook)
+ (with-output-to-temp-buffer "*Org Help*"
+ (princ (format help (if org-goto-auto-isearch
+ " Just type for auto-isearch."
+ " n/p/f/b/u to navigate, q to quit.")))))
+ (org-fit-window-to-buffer (get-buffer-window "*Org Help*"))
+ (org-overview)
+ (setq buffer-read-only t)
+ (if (and (boundp 'org-goto-start-pos)
+ (integer-or-marker-p org-goto-start-pos))
+ (progn (goto-char org-goto-start-pos)
+ (when (org-invisible-p)
+ (org-show-set-visibility 'lineage)))
+ (goto-char (point-min)))
+ (let (org-special-ctrl-a/e) (org-beginning-of-line))
+ (message "Select location and press RET")
+ (use-local-map org-goto-map)
+ (recursive-edit)))
+ (kill-buffer "*org-goto*")
+ (cons org-goto-selected-point org-goto-exit-command)))
;;;###autoload
(defun org-goto (&optional alternative-interface)
@@ -250,7 +249,7 @@ want.
This command works around this by showing a copy of the current
buffer in an indirect buffer, in overview mode. You can dive
-into the tree in that copy, use org-occur and incremental search
+into the tree in that copy, use `org-occur' and incremental search
to find a location. When pressing RET or `Q', the command
returns to the original buffer in which the visibility is still
unchanged. After RET it will also jump to the location selected
diff --git a/lisp/org/org-habit.el b/lisp/org/org-habit.el
index 231c08be0ac..a355d8e5faf 100644
--- a/lisp/org/org-habit.el
+++ b/lisp/org/org-habit.el
@@ -90,7 +90,7 @@ It will be green even if it was done after the deadline."
:type 'boolean)
(defcustom org-habit-scheduled-past-days nil
-"Value to use instead of `org-scheduled-past-days', for habits only.
+ "Value to use instead of `org-scheduled-past-days', for habits only.
If nil, `org-scheduled-past-days' is used.
diff --git a/lisp/org/org-id.el b/lisp/org/org-id.el
index b3b98c614ab..bd7e73905f3 100644
--- a/lisp/org/org-id.el
+++ b/lisp/org/org-id.el
@@ -2,7 +2,7 @@
;;
;; Copyright (C) 2008-2021 Free Software Foundation, Inc.
;;
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
@@ -128,6 +128,15 @@ nil Never use an ID to make a link, instead link using a text search for
:group 'org-id
:type 'string)
+(defcustom org-id-ts-format "%Y%m%dT%H%M%S.%6N"
+ "Timestamp format for IDs generated using `ts' `org-id-method'.
+The format should be suitable to pass as an argument to `format-time-string'.
+
+Defaults to ISO8601 timestamps without separators and without
+timezone, local time and precision down to 1e-6 seconds."
+ :type 'string
+ :package-version '(Org . "9.5"))
+
(defcustom org-id-method 'uuid
"The method that should be used to create new IDs.
@@ -144,13 +153,12 @@ uuid Create random (version 4) UUIDs. If the program defined in
`org-id-uuid-program' is available it is used to create the ID.
Otherwise an internal functions is used.
-ts Create ID's based on ISO8601 timestamps (without separators
- and without timezone, local time). Precision down to seconds."
+ts Create ID's based on timestamps as specified in `org-id-ts-format'."
:group 'org-id
:type '(choice
(const :tag "Org's internal method" org)
(const :tag "external: uuidgen" uuid)
- (const :tag "ISO8601 timestamp" ts)))
+ (const :tag "Timestamp with format `org-id-ts-format'" ts)))
(defcustom org-id-prefix nil
"The prefix for IDs.
@@ -188,15 +196,14 @@ the link."
:group 'org-id
:type 'boolean)
-(defcustom org-id-locations-file (convert-standard-filename
- (concat user-emacs-directory ".org-id-locations"))
+(defcustom org-id-locations-file (locate-user-emacs-file ".org-id-locations")
"The file for remembering in which file an ID was defined.
This variable is only relevant when `org-id-track-globally' is set."
:group 'org-id
:type 'file)
(defcustom org-id-locations-file-relative nil
- "Determines if org-id-locations should be stored as relative links.
+ "Determine if `org-id-locations' should be stored as relative links.
Non-nil means that links to locations are stored as links
relative to the location of where `org-id-locations-file' is
stored.
@@ -297,7 +304,7 @@ If necessary, the ID is created."
(if (caar org-refile-targets) 'file t))
(org-refile-target-verify-function nil)
(spos (org-refile-get-location "Entry"))
- (pom (and spos (move-marker (make-marker) (nth 3 spos)
+ (pom (and spos (move-marker (make-marker) (or (nth 3 spos) 1)
(get-file-buffer (nth 1 spos))))))
(prog1 (org-id-get pom 'create)
(move-marker pom nil))))
@@ -374,17 +381,15 @@ So a typical ID could look like \"Org:4nd91V40HI\"."
(setq unique (org-id-uuid))))
((eq org-id-method 'org)
(let* ((etime (org-reverse-string (org-id-time-to-b36)))
- (postfix (if org-id-include-domain
- (progn
- (require 'message)
- (concat "@" (message-make-fqdn))))))
+ (postfix (when org-id-include-domain
+ (require 'message)
+ (concat "@" (message-make-fqdn)))))
(setq unique (concat etime postfix))))
((eq org-id-method 'ts)
- (let ((ts (format-time-string "%Y%m%dT%H%M%S.%6N"))
- (postfix (if org-id-include-domain
- (progn
- (require 'message)
- (concat "@" (message-make-fqdn))))))
+ (let ((ts (format-time-string org-id-ts-format))
+ (postfix (when org-id-include-domain
+ (require 'message)
+ (concat "@" (message-make-fqdn)))))
(setq unique (concat ts postfix))))
(t (error "Invalid `org-id-method'")))
(concat prefix unique)))
@@ -413,15 +418,15 @@ So a typical ID could look like \"Org:4nd91V40HI\"."
(substring rnd 18 20)
(substring rnd 20 32))))
-(defun org-id-int-to-b36-one-digit (i)
- "Turn an integer between 0 and 61 into a single character 0..9, A..Z, a..z."
+(defun org-id-int-to-b36-one-digit (integer)
+ "Convert INTEGER between 0 and 61 into a single character 0..9, A..Z, a..z."
(cond
- ((< i 10) (+ ?0 i))
- ((< i 36) (+ ?a i -10))
+ ((< integer 10) (+ ?0 integer))
+ ((< integer 36) (+ ?a integer -10))
(t (error "Larger that 35"))))
(defun org-id-b36-to-int-one-digit (i)
- "Turn a character 0..9, A..Z, a..z into a number 0..61.
+ "Convert character 0..9, A..Z, a..z into a number 0..61.
The input I may be a character, or a single-letter string."
(and (stringp i) (setq i (string-to-char i)))
(cond
@@ -429,9 +434,11 @@ The input I may be a character, or a single-letter string."
((and (>= i ?a) (<= i ?z)) (+ (- i ?a) 10))
(t (error "Invalid b36 letter"))))
-(defun org-id-int-to-b36 (i &optional length)
- "Convert an integer to a base-36 number represented as a string."
- (let ((s ""))
+(defun org-id-int-to-b36 (integer &optional length)
+ "Convert an INTEGER to a base-36 number represented as a string.
+The returned string is padded with leading zeros to LENGTH if necessary."
+ (let ((s "")
+ (i integer))
(while (> i 0)
(setq s (concat (char-to-string
(org-id-int-to-b36-one-digit (mod i 36))) s)
@@ -441,11 +448,11 @@ The input I may be a character, or a single-letter string."
(setq s (concat (make-string (- length (length s)) ?0) s)))
s))
-(defun org-id-b36-to-int (s)
- "Convert a base-36 string into the corresponding integer."
+(defun org-id-b36-to-int (string)
+ "Convert a base-36 STRING into the corresponding integer."
(let ((r 0))
(mapc (lambda (i) (setq r (+ (* r 36) (org-id-b36-to-int-one-digit i))))
- s)
+ string)
r))
(defun org-id-time-to-b36 (&optional time)
@@ -483,7 +490,8 @@ and TIME is a Lisp time value (HI LO USEC)."
Store the relation between files and corresponding IDs.
This will scan all agenda files, all associated archives, and all
files currently mentioned in `org-id-locations'.
-When FILES is given, scan also these files."
+When FILES is given, scan also these files.
+If SILENT is non-nil, messages are suppressed."
(interactive)
(unless org-id-track-globally
(error "Please turn on `org-id-track-globally' if you want to track IDs"))
@@ -512,28 +520,31 @@ When FILES is given, scan also these files."
(seen-ids nil)
(ndup 0)
(i 0))
- (dolist (file files)
- (when (file-exists-p file)
- (unless silent
- (cl-incf i)
- (message "Finding ID locations (%d/%d files): %s" i nfiles file))
- (with-current-buffer (find-file-noselect file t)
- (let ((ids nil)
- (case-fold-search t))
- (org-with-point-at 1
- (while (re-search-forward id-regexp nil t)
- (when (org-at-property-p)
- (push (org-entry-get (point) "ID") ids)))
- (when ids
- (push (cons (abbreviate-file-name file) ids)
- org-id-locations)
- (dolist (id ids)
- (cond
- ((not (member id seen-ids)) (push id seen-ids))
- (silent nil)
- (t
- (message "Duplicate ID %S" id)
- (cl-incf ndup))))))))))
+ (with-temp-buffer
+ (delay-mode-hooks
+ (org-mode)
+ (dolist (file files)
+ (when (file-exists-p file)
+ (unless silent
+ (cl-incf i)
+ (message "Finding ID locations (%d/%d files): %s" i nfiles file))
+ (insert-file-contents file nil nil nil 'replace)
+ (let ((ids nil)
+ (case-fold-search t))
+ (org-with-point-at 1
+ (while (re-search-forward id-regexp nil t)
+ (when (org-at-property-p)
+ (push (org-entry-get (point) "ID") ids)))
+ (when ids
+ (push (cons (abbreviate-file-name file) ids)
+ org-id-locations)
+ (dolist (id ids)
+ (cond
+ ((not (member id seen-ids)) (push id seen-ids))
+ (silent nil)
+ (t
+ (message "Duplicate ID %S" id)
+ (cl-incf ndup)))))))))))
(setq org-id-files (mapcar #'car org-id-locations))
(org-id-locations-save)
;; Now convert to a hash table.
@@ -580,7 +591,7 @@ When FILES is given, scan also these files."
(setf (car item) (expand-file-name (car item) loc))))
org-id-locations)))
(error
- (message "Could not read org-id-values from %s. Setting it to nil."
+ (message "Could not read `org-id-values' from %s, setting it to nil"
org-id-locations-file))))
(setq org-id-files (mapcar 'car org-id-locations))
(setq org-id-locations (org-id-alist-to-hash org-id-locations))))
@@ -589,7 +600,7 @@ When FILES is given, scan also these files."
"Add the ID with location FILE to the database of ID locations."
;; Only if global tracking is on, and when the buffer has a file
(unless file
- (error "bug: org-id-get expects a file-visiting buffer"))
+ (error "`org-id-get' expects a file-visiting buffer"))
(let ((afile (abbreviate-file-name file)))
(when (and org-id-track-globally id)
(unless org-id-locations (org-id-locations-load))
@@ -601,7 +612,8 @@ When FILES is given, scan also these files."
(add-hook 'kill-emacs-hook 'org-id-locations-save))
(defun org-id-hash-to-alist (hash)
- "Turn an org-id hash into an alist, so that it can be written to a file."
+ "Turn an org-id HASH into an alist.
+This is to be able to write it to a file."
(let (res x)
(maphash
(lambda (k v)
@@ -612,7 +624,7 @@ When FILES is given, scan also these files."
res))
(defun org-id-alist-to-hash (list)
- "Turn an org-id location list into a hash table."
+ "Turn an org-id location LIST into a hash table."
(let ((res (make-hash-table
:test 'equal
:size (apply '+ (mapcar 'length list))))
@@ -625,7 +637,7 @@ When FILES is given, scan also these files."
res))
(defun org-id-paste-tracker (txt &optional buffer-or-file)
- "Update any IDs in TXT and assign BUFFER-OR-FILE to them."
+ "Update any ids in TXT and assign BUFFER-OR-FILE to them."
(when org-id-track-globally
(save-match-data
(setq buffer-or-file (or buffer-or-file (current-buffer)))
@@ -644,7 +656,7 @@ When FILES is given, scan also these files."
;;;###autoload
(defun org-id-find-id-file (id)
- "Query the id database for the file in which this ID is located."
+ "Query the id database for the file in which ID is located."
(unless org-id-locations (org-id-locations-load))
(or (and org-id-locations
(hash-table-p org-id-locations)
@@ -655,20 +667,27 @@ When FILES is given, scan also these files."
(defun org-id-find-id-in-file (id file &optional markerp)
"Return the position of the entry ID in FILE.
+
If that files does not exist, or if it does not contain this ID,
return nil.
+
The position is returned as a cons cell (file-name . position). With
optional argument MARKERP, return the position as a new marker."
- (let (org-agenda-new-buffers buf pos)
- (cond
- ((not file) nil)
- ((not (file-exists-p file)) nil)
- (t (with-current-buffer (setq buf (org-get-agenda-file-buffer file))
- (setq pos (org-find-entry-with-id id))
- (when pos
- (if markerp
- (move-marker (make-marker) pos buf)
- (cons file pos))))))))
+ (cond
+ ((not file) nil)
+ ((not (file-exists-p file)) nil)
+ (t
+ (let* ((visiting (find-buffer-visiting file))
+ (buffer (or visiting (find-file-noselect file))))
+ (unwind-protect
+ (with-current-buffer buffer
+ (let ((pos (org-find-entry-with-id id)))
+ (cond
+ ((null pos) nil)
+ (markerp (move-marker (make-marker) pos buffer))
+ (t (cons file pos)))))
+ ;; Remove opened buffer in the process.
+ (unless (or visiting markerp) (kill-buffer buffer)))))))
;; id link type
@@ -677,21 +696,27 @@ optional argument MARKERP, return the position as a new marker."
;;;###autoload
(defun org-id-store-link ()
- "Store a link to the current entry, using its ID."
+ "Store a link to the current entry, using its ID.
+
+If before first heading store first title-keyword as description
+or filename if no title."
(interactive)
(when (and (buffer-file-name (buffer-base-buffer)) (derived-mode-p 'org-mode))
(let* ((link (concat "id:" (org-id-get-create)))
(case-fold-search nil)
(desc (save-excursion
(org-back-to-heading-or-point-min t)
- (or (and (org-before-first-heading-p)
- (file-name-nondirectory
- (buffer-file-name (buffer-base-buffer))))
- (and (looking-at org-complex-heading-regexp)
- (if (match-end 4)
- (match-string 4)
- (match-string 0)))
- link))))
+ (cond ((org-before-first-heading-p)
+ (let ((keywords (org-collect-keywords '("TITLE"))))
+ (if keywords
+ (cadr (assoc "TITLE" keywords))
+ (file-name-nondirectory
+ (buffer-file-name (buffer-base-buffer))))))
+ ((looking-at org-complex-heading-regexp)
+ (if (match-end 4)
+ (match-string 4)
+ (match-string 0)))
+ (t link)))))
(org-link-store-props :link link :description desc :type "id")
link)))
diff --git a/lisp/org/org-indent.el b/lisp/org/org-indent.el
index 3475cadc42d..e0cb69780e1 100644
--- a/lisp/org/org-indent.el
+++ b/lisp/org/org-indent.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2009-2021 Free Software Foundation, Inc.
;;
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
@@ -126,31 +126,32 @@ useful to make it ever so slightly different."
(make-vector org-indent--deepest-level nil))
(setq org-indent--text-line-prefixes
(make-vector org-indent--deepest-level nil))
- (dotimes (n org-indent--deepest-level)
- (let ((indentation (if (<= n 1) 0
- (* (1- org-indent-indentation-per-level)
- (1- n)))))
- ;; Headlines line prefixes.
- (let ((heading-prefix (make-string indentation ?*)))
- (aset org-indent--heading-line-prefixes
+ (when (> org-indent-indentation-per-level 0)
+ (dotimes (n org-indent--deepest-level)
+ (let ((indentation (if (<= n 1) 0
+ (* (1- org-indent-indentation-per-level)
+ (1- n)))))
+ ;; Headlines line prefixes.
+ (let ((heading-prefix (make-string indentation ?*)))
+ (aset org-indent--heading-line-prefixes
+ n
+ (org-add-props heading-prefix nil 'face 'org-indent))
+ ;; Inline tasks line prefixes
+ (aset org-indent--inlinetask-line-prefixes
+ n
+ (cond ((<= n 1) "")
+ ((bound-and-true-p org-inlinetask-show-first-star)
+ (concat org-indent-inlinetask-first-star
+ (substring heading-prefix 1)))
+ (t (org-add-props heading-prefix nil 'face 'org-indent)))))
+ ;; Text line prefixes.
+ (aset org-indent--text-line-prefixes
n
- (org-add-props heading-prefix nil 'face 'org-indent))
- ;; Inline tasks line prefixes
- (aset org-indent--inlinetask-line-prefixes
- n
- (cond ((<= n 1) "")
- ((bound-and-true-p org-inlinetask-show-first-star)
- (concat org-indent-inlinetask-first-star
- (substring heading-prefix 1)))
- (t (org-add-props heading-prefix nil 'face 'org-indent)))))
- ;; Text line prefixes.
- (aset org-indent--text-line-prefixes
- n
- (org-add-props
- (concat (make-string (+ n indentation) ?\s)
- (and (> n 0)
- (char-to-string org-indent-boundary-char)))
- nil 'face 'org-indent)))))
+ (org-add-props
+ (concat (make-string (+ n indentation) ?\s)
+ (and (> n 0)
+ (char-to-string org-indent-boundary-char)))
+ nil 'face 'org-indent))))))
(defsubst org-indent-remove-properties (beg end)
"Remove indentations between BEG and END."
diff --git a/lisp/org/org-inlinetask.el b/lisp/org/org-inlinetask.el
index 48402b092b2..3379a2e460c 100644
--- a/lisp/org/org-inlinetask.el
+++ b/lisp/org/org-inlinetask.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2009-2021 Free Software Foundation, Inc.
;;
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
@@ -131,7 +131,7 @@ If there is a region wrap it inside the inline task."
;; before this one.
(when (and (org-inlinetask-in-task-p)
(not (and (org-inlinetask-at-task-p) (bolp))))
- (error "Cannot nest inline tasks"))
+ (user-error "Cannot nest inline tasks"))
(or (bolp) (newline))
(let* ((indent (if org-odd-levels-only
(1- (* 2 org-inlinetask-min-level))
@@ -189,7 +189,7 @@ The number of levels is controlled by `org-inlinetask-min-level'."
(defun org-inlinetask-goto-end ()
"Go to the end of the inline task at point.
- Return point."
+Return point."
(save-match-data
(beginning-of-line)
(let ((case-fold-search t)
@@ -225,7 +225,7 @@ If the task has an end part, promote it. Also, prevents level from
going below `org-inlinetask-min-level'."
(interactive)
(if (not (org-inlinetask-in-task-p))
- (error "Not in an inline task")
+ (user-error "Not in an inline task")
(save-excursion
(let* ((lvl (org-inlinetask-get-task-level))
(next-lvl (org-get-valid-level lvl -1))
@@ -233,15 +233,18 @@ going below `org-inlinetask-min-level'."
(down-task (concat (make-string next-lvl ?*)))
beg)
(if (< next-lvl org-inlinetask-min-level)
- (error "Cannot promote an inline task at minimum level")
+ (user-error "Cannot promote an inline task at minimum level")
(org-inlinetask-goto-beginning)
(setq beg (point))
(replace-match down-task nil t nil 1)
(org-inlinetask-goto-end)
- (if (eobp) (beginning-of-line) (forward-line -1))
+ (if (and (eobp) (looking-back "END\\s-*" (point-at-bol)))
+ (beginning-of-line)
+ (forward-line -1))
(unless (= (point) beg)
+ (looking-at (org-inlinetask-outline-regexp))
(replace-match down-task nil t nil 1)
- (when org-adapt-indentation
+ (when (eq org-adapt-indentation t)
(goto-char beg)
(org-fixup-indentation diff))))))))
@@ -250,7 +253,7 @@ going below `org-inlinetask-min-level'."
If the task has an end part, also demote it."
(interactive)
(if (not (org-inlinetask-in-task-p))
- (error "Not in an inline task")
+ (user-error "Not in an inline task")
(save-excursion
(let* ((lvl (org-inlinetask-get-task-level))
(next-lvl (org-get-valid-level lvl 1))
@@ -261,10 +264,13 @@ If the task has an end part, also demote it."
(setq beg (point))
(replace-match down-task nil t nil 1)
(org-inlinetask-goto-end)
- (if (eobp) (beginning-of-line) (forward-line -1))
+ (if (and (eobp) (looking-back "END\\s-*" (point-at-bol)))
+ (beginning-of-line)
+ (forward-line -1))
(unless (= (point) beg)
+ (looking-at (org-inlinetask-outline-regexp))
(replace-match down-task nil t nil 1)
- (when org-adapt-indentation
+ (when (eq org-adapt-indentation t)
(goto-char beg)
(org-fixup-indentation diff)))))))
diff --git a/lisp/org/org-keys.el b/lisp/org/org-keys.el
index f0fdb79ea49..a3d95768278 100644
--- a/lisp/org/org-keys.el
+++ b/lisp/org/org-keys.el
@@ -31,6 +31,8 @@
(defvar org-outline-regexp)
+(require 'oc)
+
(declare-function org-add-note "org" ())
(declare-function org-agenda "org" (&optional arg org-keys restriction))
(declare-function org-agenda-file-to-front "org" (&optional to-end))
@@ -56,7 +58,6 @@
(declare-function org-clone-subtree-with-time-shift "org" (n &optional shift))
(declare-function org-columns "org" (&optional global columns-fmt-string))
(declare-function org-comment-dwim "org" (arg))
-(declare-function org-refile-copy "org" ())
(declare-function org-copy-special "org" ())
(declare-function org-copy-visible "org" (beg end))
(declare-function org-ctrl-c-ctrl-c "org" (&optional arg))
@@ -143,6 +144,8 @@
(declare-function org-promote-subtree "org" ())
(declare-function org-redisplay-inline-images "org" ())
(declare-function org-refile "org" (&optional arg1 default-buffer rfloc msg))
+(declare-function org-refile-copy "org" ())
+(declare-function org-refile-reverse "org-refile" (&optional arg default-buffer rfloc msg))
(declare-function org-reftex-citation "org" ())
(declare-function org-reload "org" (&optional arg1))
(declare-function org-remove-file "org" (&optional file))
@@ -174,7 +177,6 @@
(declare-function org-show-subtree "org" ())
(declare-function org-sort "org" (&optional with-case))
(declare-function org-sparse-tree "org" (&optional arg type))
-(declare-function org-table-blank-field "org" ())
(declare-function org-table-copy-down "org" (n))
(declare-function org-table-create-or-convert-from-region "org" (arg))
(declare-function org-table-create-with-table\.el "org-table" ())
@@ -277,8 +279,7 @@ before org.el is loaded."
:type '(choice
(const :tag "A double click follows the link" double)
(const :tag "Unconditionally follow the link with mouse-1" t)
- (integer :tag "mouse-1 click does not follow the link if longer than N ms" 450))
- :safe t)
+ (integer :tag "mouse-1 click does not follow the link if longer than N ms" 450)))
(defcustom org-tab-follows-link nil
"Non-nil means on links TAB will follow the link.
@@ -298,7 +299,7 @@ implementation is bad."
In tables, the special behavior of RET has precedence."
:group 'org-link-follow
:type 'boolean
- :safe t)
+ :safe #'booleanp)
;;; Functions
@@ -337,7 +338,6 @@ COMMANDS is a list of alternating OLDDEF NEWDEF command names."
(org-defkey org-mouse-map [follow-link] 'mouse-face))
(when org-tab-follows-link
- (org-defkey org-mouse-map (kbd "<tab>") #'org-open-at-point)
(org-defkey org-mouse-map (kbd "TAB") #'org-open-at-point))
@@ -443,18 +443,13 @@ COMMANDS is a list of alternating OLDDEF NEWDEF command names."
(org-defkey org-mode-map (kbd "C-c C-x") (make-sparse-keymap))
;;;; TAB key with modifiers
-(org-defkey org-mode-map (kbd "C-i") #'org-cycle)
-(org-defkey org-mode-map (kbd "<tab>") #'org-cycle)
+(org-defkey org-mode-map (kbd "TAB") #'org-cycle)
(org-defkey org-mode-map (kbd "C-c C-<tab>") #'org-force-cycle-archived)
;; Override text-mode binding to expose `complete-symbol' for
;; pcomplete functionality.
-(org-defkey org-mode-map (kbd "M-<tab>") nil)
(org-defkey org-mode-map (kbd "M-TAB") nil)
-(org-defkey org-mode-map (kbd "ESC <tab>") nil)
(org-defkey org-mode-map (kbd "ESC TAB") nil)
-(org-defkey org-mode-map (kbd "<S-iso-leftab>") #'org-shifttab)
-(org-defkey org-mode-map (kbd "S-<tab>") #'org-shifttab)
(org-defkey org-mode-map (kbd "S-TAB") #'org-shifttab)
(define-key org-mode-map (kbd "<backtab>") #'org-shifttab)
@@ -463,12 +458,7 @@ COMMANDS is a list of alternating OLDDEF NEWDEF command names."
(org-defkey org-mode-map (kbd "S-RET") #'org-table-copy-down)
(org-defkey org-mode-map (kbd "M-S-<return>") #'org-insert-todo-heading)
(org-defkey org-mode-map (kbd "M-S-RET") #'org-insert-todo-heading)
-(org-defkey org-mode-map (kbd "ESC S-<return>") #'org-insert-todo-heading)
-(org-defkey org-mode-map (kbd "ESC S-RET") #'org-insert-todo-heading)
-(org-defkey org-mode-map (kbd "M-<return>") #'org-meta-return)
(org-defkey org-mode-map (kbd "M-RET") #'org-meta-return)
-(org-defkey org-mode-map (kbd "ESC <return>") #'org-meta-return)
-(org-defkey org-mode-map (kbd "ESC RET") #'org-meta-return)
;;;; Cursor keys with modifiers
(org-defkey org-mode-map (kbd "M-<left>") #'org-metaleft)
@@ -582,6 +572,7 @@ COMMANDS is a list of alternating OLDDEF NEWDEF command names."
(org-defkey org-mode-map (kbd "C-c ;") #'org-toggle-comment)
(org-defkey org-mode-map (kbd "C-c C-w") #'org-refile)
(org-defkey org-mode-map (kbd "C-c M-w") #'org-refile-copy)
+(org-defkey org-mode-map (kbd "C-c C-M-w") #'org-refile-reverse)
(org-defkey org-mode-map (kbd "C-c /") #'org-sparse-tree) ;minor-mode reserved
(org-defkey org-mode-map (kbd "C-c \\") #'org-match-sparse-tree) ;minor-mode r.
(org-defkey org-mode-map (kbd "C-c RET") #'org-ctrl-c-ret)
@@ -620,7 +611,6 @@ COMMANDS is a list of alternating OLDDEF NEWDEF command names."
(org-defkey org-mode-map (kbd "RET") #'org-return)
(org-defkey org-mode-map (kbd "C-j") #'org-return-and-maybe-indent)
(org-defkey org-mode-map (kbd "C-c ?") #'org-table-field-info)
-(org-defkey org-mode-map (kbd "C-c SPC") #'org-table-blank-field)
(org-defkey org-mode-map (kbd "C-c +") #'org-table-sum)
(org-defkey org-mode-map (kbd "C-c =") #'org-table-eval-formula)
(org-defkey org-mode-map (kbd "C-c '") #'org-edit-special)
@@ -676,6 +666,7 @@ COMMANDS is a list of alternating OLDDEF NEWDEF command names."
(org-defkey org-mode-map (kbd "C-c C-x !") #'org-reload)
(org-defkey org-mode-map (kbd "C-c C-x g") #'org-feed-update-all)
(org-defkey org-mode-map (kbd "C-c C-x G") #'org-feed-goto-inbox)
+(org-defkey org-mode-map (kbd "C-c C-x @") #'org-cite-insert)
(org-defkey org-mode-map (kbd "C-c C-x [") #'org-reftex-citation)
(org-defkey org-mode-map (kbd "C-c C-x I") #'org-info-find-node)
@@ -698,28 +689,6 @@ star at the beginning of the headline, you can do this:
(const :tag "At beginning of headline stars" t)
(function)))
-(defcustom org-speed-commands-user nil
- "Alist of additional speed commands.
-This list will be checked before `org-speed-commands-default'
-when the variable `org-use-speed-commands' is non-nil
-and when the cursor is at the beginning of a headline.
-The car of each entry is a string with a single letter, which must
-be assigned to `self-insert-command' in the global map.
-The cdr is either a command to be called interactively, a function
-to be called, or a form to be evaluated.
-An entry that is just a list with a single string will be interpreted
-as a descriptive headline that will be added when listing the speed
-commands in the Help buffer using the `?' speed command."
- :group 'org-structure
- :type '(repeat :value ("k" . ignore)
- (choice :value ("k" . ignore)
- (list :tag "Descriptive Headline" (string :tag "Headline"))
- (cons :tag "Letter and Command"
- (string :tag "Command letter")
- (choice
- (function)
- (sexp))))))
-
(defcustom org-speed-command-hook
'(org-speed-command-activate org-babel-speed-command-activate)
"Hook for activating speed commands at strategic locations.
@@ -739,7 +708,7 @@ hook. The default setting is `org-speed-command-activate'."
:version "24.1"
:type 'hook)
-(defconst org-speed-commands-default
+(defcustom org-speed-commands
'(("Outline Navigation")
("n" . (org-speed-move-safe 'org-next-visible-heading))
("p" . (org-speed-move-safe 'org-previous-visible-heading))
@@ -749,7 +718,7 @@ hook. The default setting is `org-speed-command-activate'."
("B" . org-previous-block)
("u" . (org-speed-move-safe 'outline-up-heading))
("j" . org-goto)
- ("g" . (org-refile t))
+ ("g" . (org-refile '(4)))
("Outline Visibility")
("c" . org-cycle)
("C" . org-shifttab)
@@ -764,8 +733,7 @@ hook. The default setting is `org-speed-command-activate'."
("l" . org-metaleft)
("R" . org-shiftmetaright)
("L" . org-shiftmetaleft)
- ("i" . (progn (forward-char 1) (call-interactively
- 'org-insert-heading-respect-content)))
+ ("i" . (progn (forward-char 1) (call-interactively 'org-insert-heading-respect-content)))
("^" . org-sort)
("w" . org-refile)
("a" . org-archive-subtree-default-with-confirmation)
@@ -784,8 +752,7 @@ hook. The default setting is `org-speed-command-activate'."
(":" . org-set-tags-command)
("e" . org-set-effort)
("E" . org-inc-effort)
- ("W" . (lambda(m) (interactive "sMinutes before warning: ")
- (org-entry-put (point) "APPT_WARNTIME" m)))
+ ("W" . (lambda (m) (interactive "sMinutes before warning: ") (org-entry-put (point) "APPT_WARNTIME" m)))
("Agenda Views etc")
("v" . org-agenda)
("/" . org-sparse-tree)
@@ -794,7 +761,28 @@ hook. The default setting is `org-speed-command-activate'."
("?" . org-speed-command-help)
("<" . (org-agenda-set-restriction-lock 'subtree))
(">" . (org-agenda-remove-restriction-lock)))
- "The default speed commands.")
+ "Alist of speed commands.
+
+The car of each entry is a string with a single letter, which
+must be assigned to `self-insert-command' in the global map.
+
+The cdr is either a command to be called interactively, a
+function to be called, or a form to be evaluated.
+
+An entry that is just a list with a single string will be
+interpreted as a descriptive headline that will be added when
+listing the speed commands in the Help buffer using the `?' speed
+command."
+ :group 'org-structure
+ :package-version '(Org . "9.5")
+ :type '(repeat :value ("k" . ignore)
+ (choice :value ("k" . ignore)
+ (list :tag "Descriptive Headline" (string :tag "Headline"))
+ (cons :tag "Letter and Command"
+ (string :tag "Command letter")
+ (choice
+ (function)
+ (sexp))))))
(defun org-print-speed-command (e)
(if (> (length (car e)) 1)
@@ -816,12 +804,18 @@ hook. The default setting is `org-speed-command-activate'."
(interactive)
(unless org-use-speed-commands
(user-error "Speed commands are not activated, customize `org-use-speed-commands'"))
+ ;; FIXME: remove this warning for 9.6
+ (when (boundp 'org-speed-commands-user)
+ (message "`org-speed-command-user' is obsolete, please use `org-speed-commands'")
+ (sit-for 3))
(with-output-to-temp-buffer "*Help*"
- (princ "User-defined Speed commands\n===========================\n")
- (mapc #'org-print-speed-command org-speed-commands-user)
- (princ "\n")
- (princ "Built-in Speed commands\n=======================\n")
- (mapc #'org-print-speed-command org-speed-commands-default))
+ (princ "Speed commands\n==============\n")
+ (mapc #'org-print-speed-command
+ ;; FIXME: don't check `org-speed-commands-user' past 9.6
+ (if (boundp 'org-speed-commands-user)
+ (append org-speed-commands
+ org-speed-commands-user)
+ org-speed-commands)))
(with-current-buffer "*Help*"
(setq truncate-lines t)))
@@ -837,13 +831,16 @@ If not, return to the original position and throw an error."
(defun org-speed-command-activate (keys)
"Hook for activating single-letter speed commands.
-`org-speed-commands-default' specifies a minimal command set.
-Use `org-speed-commands-user' for further customization."
+See `org-speed-commands' for configuring them."
(when (or (and (bolp) (looking-at org-outline-regexp))
(and (functionp org-use-speed-commands)
(funcall org-use-speed-commands)))
- (cdr (assoc keys (append org-speed-commands-user
- org-speed-commands-default)))))
+ (cdr (assoc keys
+ ;; FIXME: don't check `org-speed-commands-user' past 9.6
+ (if (boundp 'org-speed-commands-user)
+ (append org-speed-commands
+ org-speed-commands-user)
+ org-speed-commands)))))
;;; Babel speed keys
diff --git a/lisp/org/org-lint.el b/lisp/org/org-lint.el
index 2e080cc138f..da5e6ae7995 100644
--- a/lisp/org/org-lint.el
+++ b/lisp/org/org-lint.el
@@ -350,7 +350,7 @@ called with one argument, the key used for comparison."
(lambda (datum name)
(goto-char (org-element-property :begin datum))
(re-search-forward
- (format "^[ \t]*#\\+[A-Za-z]+: +%s *$" (regexp-quote name)))
+ (format "^[ \t]*#\\+[A-Za-z]+:[ \t]*%s[ \t]*$" (regexp-quote name)))
(match-beginning 0))
(lambda (key) (format "Duplicate NAME \"%s\"" key))))
@@ -593,7 +593,7 @@ in description"
(let ((file (org-unbracket-string
"\"" "\""
(org-element-property :value k))))
- (and (not (org-file-url-p file))
+ (and (not (org-url-p file))
(not (file-remote-p file))
(not (file-exists-p file))
(list (org-element-property :begin k)
@@ -671,7 +671,7 @@ Use \"export %s\" instead"
(when (string= (org-element-property :key k) "OPTIONS")
(let ((value (org-element-property :value k))
(start 0))
- (while (string-match "\\(.+?\\):\\((.*?)\\|\\S-*\\)[ \t]*"
+ (while (string-match "\\(.+?\\):\\((.*?)\\|\\S-+\\)?[ \t]*"
value
start)
(setf start (match-end 0))
@@ -679,19 +679,50 @@ Use \"export %s\" instead"
(unless (member item allowed)
(push (list (org-element-property :post-affiliated k)
(format "Unknown OPTIONS item \"%s\"" item))
- reports))))))))
+ reports))
+ (unless (match-string 2 value)
+ (push (list (org-element-property :post-affiliated k)
+ (format "Missing value for option item %S" item))
+ reports))))))))
reports))
(defun org-lint-invalid-macro-argument-and-template (ast)
- (let ((extract-placeholders
- (lambda (template)
- (let ((start 0)
- args)
- (while (string-match "\\$\\([1-9][0-9]*\\)" template start)
- (setf start (match-end 0))
- (push (string-to-number (match-string 1 template)) args))
- (sort (org-uniquify args) #'<))))
- reports)
+ (let* ((reports nil)
+ (extract-placeholders
+ (lambda (template)
+ (let ((start 0)
+ args)
+ (while (string-match "\\$\\([1-9][0-9]*\\)" template start)
+ (setf start (match-end 0))
+ (push (string-to-number (match-string 1 template)) args))
+ (sort (org-uniquify args) #'<))))
+ (check-arity
+ (lambda (arity macro)
+ (let* ((name (org-element-property :key macro))
+ (pos (org-element-property :begin macro))
+ (args (org-element-property :args macro))
+ (l (length args)))
+ (cond
+ ((< l (1- (car arity)))
+ (push (list pos (format "Missing arguments in macro %S" name))
+ reports))
+ ((< l (car arity))
+ (push (list pos (format "Missing argument in macro %S" name))
+ reports))
+ ((> l (1+ (cdr arity)))
+ (push (let ((spurious-args (nthcdr (cdr arity) args)))
+ (list pos
+ (format "Spurious arguments in macro %S: %s"
+ name
+ (mapconcat #'org-trim spurious-args ", "))))
+ reports))
+ ((> l (cdr arity))
+ (push (list pos
+ (format "Spurious argument in macro %S: %s"
+ name
+ (org-last args)))
+ reports))
+ (t nil))))))
;; Check arguments for macro templates.
(org-element-map ast 'keyword
(lambda (k)
@@ -727,25 +758,29 @@ Use \"export %s\" instead"
(lambda (macro)
(let* ((name (org-element-property :key macro))
(template (cdr (assoc-string name templates t))))
- (if (not template)
- (push (list (org-element-property :begin macro)
- (format "Undefined macro \"%s\"" name))
- reports)
- (let ((arg-numbers (funcall extract-placeholders template)))
- (when arg-numbers
- (let ((spurious-args
- (nthcdr (apply #'max arg-numbers)
- (org-element-property :args macro))))
- (when spurious-args
- (push
- (list (org-element-property :begin macro)
- (format "Unused argument%s in macro \"%s\": %s"
- (if (> (length spurious-args) 1) "s" "")
- name
- (mapconcat (lambda (a) (format "\"%s\"" a))
- spurious-args
- ", ")))
- reports))))))))))
+ (pcase template
+ (`nil
+ (push (list (org-element-property :begin macro)
+ (format "Undefined macro %S" name))
+ reports))
+ ((guard (string= name "keyword"))
+ (funcall check-arity '(1 . 1) macro))
+ ((guard (string= name "modification-time"))
+ (funcall check-arity '(1 . 2) macro))
+ ((guard (string= name "n"))
+ (funcall check-arity '(0 . 2) macro))
+ ((guard (string= name "property"))
+ (funcall check-arity '(1 . 2) macro))
+ ((guard (string= name "time"))
+ (funcall check-arity '(1 . 1) macro))
+ ((pred functionp)) ;ignore (eval ...) templates
+ (_
+ (let* ((arg-numbers (funcall extract-placeholders template))
+ (arity (if (null arg-numbers)
+ '(0 . 0)
+ (let ((m (apply #'max arg-numbers)))
+ (cons m m)))))
+ (funcall check-arity arity macro))))))))
reports))
(defun org-lint-undefined-footnote-reference (ast)
@@ -1191,7 +1226,6 @@ CHECKERS is the list of checkers used."
(setf org-lint--source-buffer source)
(setf org-lint--local-checkers checkers)
(org-lint--refresh-reports)
- (tabulated-list-print)
(add-hook 'tabulated-list-revert-hook #'org-lint--refresh-reports nil t))
(pop-to-buffer buffer)))
@@ -1217,7 +1251,7 @@ CHECKERS is the list of checkers used."
(let ((c (org-lint--current-checker)))
(setf tabulated-list-entries
(cl-remove-if (lambda (e) (equal c (org-lint--current-checker e)))
- tabulated-list-entries))
+ tabulated-list-entries))
(tabulated-list-print)))
(defun org-lint--ignore-checker ()
@@ -1271,7 +1305,7 @@ ARG can also be a list of checker names, as symbols, to run."
(throw 'exit c)))))))
((pred consp)
(cl-remove-if-not (lambda (c) (memq (org-lint-checker-name c) arg))
- org-lint--checkers))
+ org-lint--checkers))
(_ (user-error "Invalid argument `%S' for `org-lint'" arg)))))
(if (not (called-interactively-p 'any))
(org-lint--generate-reports (current-buffer) checkers)
diff --git a/lisp/org/org-list.el b/lisp/org/org-list.el
index f97164ee33b..2bd9dc4d9e7 100644
--- a/lisp/org/org-list.el
+++ b/lisp/org/org-list.el
@@ -2,7 +2,7 @@
;;
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
;;
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Bastien Guerry <bzg@gnu.org>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
@@ -601,25 +601,23 @@ Assume point is at an item."
(beg-cell (cons (point) (current-indentation)))
itm-lst itm-lst-2 end-lst end-lst-2 struct
(assoc-at-point
- (function
- ;; Return association at point.
- (lambda (ind)
- (looking-at org-list-full-item-re)
- (let ((bullet (match-string-no-properties 1)))
- (list (point)
- ind
- bullet
- (match-string-no-properties 2) ; counter
- (match-string-no-properties 3) ; checkbox
- ;; Description tag.
- (and (string-match-p "[-+*]" bullet)
- (match-string-no-properties 4)))))))
+ ;; Return association at point.
+ (lambda (ind)
+ (looking-at org-list-full-item-re)
+ (let ((bullet (match-string-no-properties 1)))
+ (list (point)
+ ind
+ bullet
+ (match-string-no-properties 2) ; counter
+ (match-string-no-properties 3) ; checkbox
+ ;; Description tag.
+ (and (string-match-p "[-+*]" bullet)
+ (match-string-no-properties 4))))))
(end-before-blank
- (function
- ;; Ensure list ends at the first blank line.
- (lambda ()
- (skip-chars-backward " \r\t\n")
- (min (1+ (point-at-eol)) lim-down)))))
+ ;; Ensure list ends at the first blank line.
+ (lambda ()
+ (skip-chars-backward " \r\t\n")
+ (min (1+ (point-at-eol)) lim-down))))
;; 1. Read list from starting item to its beginning, and save
;; top item position and indentation in BEG-CELL. Also store
;; ending position of items in END-LST.
@@ -1004,23 +1002,22 @@ alist of ancestors, as returned by `org-list-parents-alist'.
Return value is a list of integers. Counters have an impact on
that value."
(let ((get-relative-number
- (function
- (lambda (item struct prevs)
- ;; Return relative sequence number of ITEM in the sub-list
- ;; it belongs. STRUCT is the list structure. PREVS is
- ;; the alist of previous items.
- (let ((seq 0) (pos item) counter)
- (while (and (not (setq counter (org-list-get-counter pos struct)))
- (setq pos (org-list-get-prev-item pos struct prevs)))
- (cl-incf seq))
- (if (not counter) (1+ seq)
- (cond
- ((string-match "[A-Za-z]" counter)
- (+ (- (string-to-char (upcase (match-string 0 counter))) 64)
- seq))
- ((string-match "[0-9]+" counter)
- (+ (string-to-number (match-string 0 counter)) seq))
- (t (1+ seq)))))))))
+ (lambda (item struct prevs)
+ ;; Return relative sequence number of ITEM in the sub-list
+ ;; it belongs. STRUCT is the list structure. PREVS is
+ ;; the alist of previous items.
+ (let ((seq 0) (pos item) counter)
+ (while (and (not (setq counter (org-list-get-counter pos struct)))
+ (setq pos (org-list-get-prev-item pos struct prevs)))
+ (cl-incf seq))
+ (if (not counter) (1+ seq)
+ (cond
+ ((string-match "[A-Za-z]" counter)
+ (+ (- (string-to-char (upcase (match-string 0 counter))) 64)
+ seq))
+ ((string-match "[0-9]+" counter)
+ (+ (string-to-number (match-string 0 counter)) seq))
+ (t (1+ seq))))))))
;; Cons each parent relative number into return value (OUT).
(let ((out (list (funcall get-relative-number item struct prevs)))
(parent item))
@@ -1182,14 +1179,13 @@ some heuristics to guess the result."
(cdr (assq 'plain-list-item org-blank-before-new-entry)))
usr-blank
(count-blanks
- (function
- (lambda ()
- ;; Count blank lines above beginning of line.
- (save-excursion
- (count-lines (goto-char (point-at-bol))
- (progn (skip-chars-backward " \r\t\n")
- (forward-line)
- (point))))))))
+ (lambda ()
+ ;; Count blank lines above beginning of line.
+ (save-excursion
+ (count-lines (goto-char (point-at-bol))
+ (progn (skip-chars-backward " \r\t\n")
+ (forward-line)
+ (point)))))))
(cond
;; Trivial cases where there should be none.
((not insert-blank-p) 0)
@@ -1652,65 +1648,64 @@ PREVS is the alist of previous items, as returned by
This function modifies STRUCT."
(let ((case-fold-search nil)
(fix-bul
- (function
- ;; Set bullet of ITEM in STRUCT, depending on the type of
- ;; first item of the list, the previous bullet and counter
- ;; if any.
- (lambda (item)
- (let* ((prev (org-list-get-prev-item item struct prevs))
- (prev-bul (and prev (org-list-get-bullet prev struct)))
- (counter (org-list-get-counter item struct))
- (bullet (org-list-get-bullet item struct))
- (alphap (and (not prev)
- (org-list-use-alpha-bul-p item struct prevs))))
- (org-list-set-bullet
- item struct
- (org-list-bullet-string
- (cond
- ;; Alpha counter in alpha list: use counter.
- ((and prev counter
- (string-match "[a-zA-Z]" counter)
- (string-match "[a-zA-Z]" prev-bul))
- ;; Use cond to be sure `string-match' is used in
- ;; both cases.
- (let ((real-count
- (cond
- ((string-match "[a-z]" prev-bul) (downcase counter))
- ((string-match "[A-Z]" prev-bul) (upcase counter)))))
- (replace-match real-count nil nil prev-bul)))
- ;; Num counter in a num list: use counter.
- ((and prev counter
- (string-match "[0-9]+" counter)
- (string-match "[0-9]+" prev-bul))
- (replace-match counter nil nil prev-bul))
- ;; No counter: increase, if needed, previous bullet.
- (prev
- (org-list-inc-bullet-maybe (org-list-get-bullet prev struct)))
- ;; Alpha counter at first item: use counter.
- ((and counter (org-list-use-alpha-bul-p item struct prevs)
- (string-match "[A-Za-z]" counter)
- (string-match "[A-Za-z]" bullet))
- (let ((real-count
- (cond
- ((string-match "[a-z]" bullet) (downcase counter))
- ((string-match "[A-Z]" bullet) (upcase counter)))))
- (replace-match real-count nil nil bullet)))
- ;; Num counter at first item: use counter.
- ((and counter
- (string-match "[0-9]+" counter)
- (string-match "[0-9]+" bullet))
- (replace-match counter nil nil bullet))
- ;; First bullet is alpha uppercase: use "A".
- ((and alphap (string-match "[A-Z]" bullet))
- (replace-match "A" nil nil bullet))
- ;; First bullet is alpha lowercase: use "a".
- ((and alphap (string-match "[a-z]" bullet))
- (replace-match "a" nil nil bullet))
- ;; First bullet is num: use "1".
- ((string-match "\\([0-9]+\\|[A-Za-z]\\)" bullet)
- (replace-match "1" nil nil bullet))
- ;; Not an ordered list: keep bullet.
- (t bullet)))))))))
+ ;; Set bullet of ITEM in STRUCT, depending on the type of
+ ;; first item of the list, the previous bullet and counter
+ ;; if any.
+ (lambda (item)
+ (let* ((prev (org-list-get-prev-item item struct prevs))
+ (prev-bul (and prev (org-list-get-bullet prev struct)))
+ (counter (org-list-get-counter item struct))
+ (bullet (org-list-get-bullet item struct))
+ (alphap (and (not prev)
+ (org-list-use-alpha-bul-p item struct prevs))))
+ (org-list-set-bullet
+ item struct
+ (org-list-bullet-string
+ (cond
+ ;; Alpha counter in alpha list: use counter.
+ ((and prev counter
+ (string-match "[a-zA-Z]" counter)
+ (string-match "[a-zA-Z]" prev-bul))
+ ;; Use cond to be sure `string-match' is used in
+ ;; both cases.
+ (let ((real-count
+ (cond
+ ((string-match "[a-z]" prev-bul) (downcase counter))
+ ((string-match "[A-Z]" prev-bul) (upcase counter)))))
+ (replace-match real-count nil nil prev-bul)))
+ ;; Num counter in a num list: use counter.
+ ((and prev counter
+ (string-match "[0-9]+" counter)
+ (string-match "[0-9]+" prev-bul))
+ (replace-match counter nil nil prev-bul))
+ ;; No counter: increase, if needed, previous bullet.
+ (prev
+ (org-list-inc-bullet-maybe (org-list-get-bullet prev struct)))
+ ;; Alpha counter at first item: use counter.
+ ((and counter (org-list-use-alpha-bul-p item struct prevs)
+ (string-match "[A-Za-z]" counter)
+ (string-match "[A-Za-z]" bullet))
+ (let ((real-count
+ (cond
+ ((string-match "[a-z]" bullet) (downcase counter))
+ ((string-match "[A-Z]" bullet) (upcase counter)))))
+ (replace-match real-count nil nil bullet)))
+ ;; Num counter at first item: use counter.
+ ((and counter
+ (string-match "[0-9]+" counter)
+ (string-match "[0-9]+" bullet))
+ (replace-match counter nil nil bullet))
+ ;; First bullet is alpha uppercase: use "A".
+ ((and alphap (string-match "[A-Z]" bullet))
+ (replace-match "A" nil nil bullet))
+ ;; First bullet is alpha lowercase: use "a".
+ ((and alphap (string-match "[a-z]" bullet))
+ (replace-match "a" nil nil bullet))
+ ;; First bullet is num: use "1".
+ ((string-match "\\([0-9]+\\|[A-Za-z]\\)" bullet)
+ (replace-match "1" nil nil bullet))
+ ;; Not an ordered list: keep bullet.
+ (t bullet))))))))
(mapc fix-bul (mapcar #'car struct))))
(defun org-list-struct-fix-ind (struct parents &optional bullet-size)
@@ -1756,21 +1751,20 @@ all others cases, the return value will be nil.
This function modifies STRUCT."
(let ((all-items (mapcar #'car struct))
(set-parent-box
- (function
- (lambda (item)
- (let* ((box-list
- (mapcar (lambda (child)
- (org-list-get-checkbox child struct))
- (org-list-get-children item struct parents))))
- (org-list-set-checkbox
- item struct
- (cond
- ((and (member "[ ]" box-list) (member "[X]" box-list)) "[-]")
- ((member "[-]" box-list) "[-]")
- ((member "[X]" box-list) "[X]")
- ((member "[ ]" box-list) "[ ]")
- ;; Parent has no boxed child: leave box as-is.
- (t (org-list-get-checkbox item struct))))))))
+ (lambda (item)
+ (let* ((box-list
+ (mapcar (lambda (child)
+ (org-list-get-checkbox child struct))
+ (org-list-get-children item struct parents))))
+ (org-list-set-checkbox
+ item struct
+ (cond
+ ((and (member "[ ]" box-list) (member "[X]" box-list)) "[-]")
+ ((member "[-]" box-list) "[-]")
+ ((member "[X]" box-list) "[X]")
+ ((member "[ ]" box-list) "[ ]")
+ ;; Parent has no boxed child: leave box as-is.
+ (t (org-list-get-checkbox item struct)))))))
parent-list)
;; 1. List all parents with a checkbox.
(mapc
@@ -1841,56 +1835,54 @@ Initial position of cursor is restored after the changes."
(org-inlinetask-outline-regexp)))
(item-re (org-item-re))
(shift-body-ind
- (function
- ;; Shift the indentation between END and BEG by DELTA.
- ;; Start from the line before END.
- (lambda (end beg delta)
- (goto-char end)
- (skip-chars-backward " \r\t\n")
- (beginning-of-line)
- (while (or (> (point) beg)
- (and (= (point) beg)
- (not (looking-at item-re))))
- (cond
- ;; Skip inline tasks.
- ((and inlinetask-re (looking-at inlinetask-re))
- (org-inlinetask-goto-beginning))
- ;; Shift only non-empty lines.
- ((looking-at-p "^[ \t]*\\S-")
- (indent-line-to (+ (current-indentation) delta))))
- (forward-line -1)))))
- (modify-item
- (function
- ;; Replace ITEM first line elements with new elements from
- ;; STRUCT, if appropriate.
- (lambda (item)
- (goto-char item)
- (let* ((new-ind (org-list-get-ind item struct))
- (old-ind (current-indentation))
- (new-bul (org-list-bullet-string
- (org-list-get-bullet item struct)))
- (old-bul (org-list-get-bullet item old-struct))
- (new-box (org-list-get-checkbox item struct)))
- (looking-at org-list-full-item-re)
- ;; a. Replace bullet
- (unless (equal old-bul new-bul)
- (replace-match new-bul nil nil nil 1))
- ;; b. Replace checkbox.
- (cond
- ((equal (match-string 3) new-box))
- ((and (match-string 3) new-box)
- (replace-match new-box nil nil nil 3))
- ((match-string 3)
- (looking-at ".*?\\([ \t]*\\[[ X-]\\]\\)")
- (replace-match "" nil nil nil 1))
- (t (let ((counterp (match-end 2)))
- (goto-char (if counterp (1+ counterp) (match-end 1)))
- (insert (concat new-box (unless counterp " "))))))
- ;; c. Indent item to appropriate column.
- (unless (= new-ind old-ind)
- (delete-region (goto-char (point-at-bol))
- (progn (skip-chars-forward " \t") (point)))
- (indent-to new-ind)))))))
+ ;; Shift the indentation between END and BEG by DELTA.
+ ;; Start from the line before END.
+ (lambda (end beg delta)
+ (goto-char end)
+ (skip-chars-backward " \r\t\n")
+ (beginning-of-line)
+ (while (or (> (point) beg)
+ (and (= (point) beg)
+ (not (looking-at item-re))))
+ (cond
+ ;; Skip inline tasks.
+ ((and inlinetask-re (looking-at inlinetask-re))
+ (org-inlinetask-goto-beginning))
+ ;; Shift only non-empty lines.
+ ((looking-at-p "^[ \t]*\\S-")
+ (indent-line-to (+ (current-indentation) delta))))
+ (forward-line -1))))
+ (modify-item
+ ;; Replace ITEM first line elements with new elements from
+ ;; STRUCT, if appropriate.
+ (lambda (item)
+ (goto-char item)
+ (let* ((new-ind (org-list-get-ind item struct))
+ (old-ind (current-indentation))
+ (new-bul (org-list-bullet-string
+ (org-list-get-bullet item struct)))
+ (old-bul (org-list-get-bullet item old-struct))
+ (new-box (org-list-get-checkbox item struct)))
+ (looking-at org-list-full-item-re)
+ ;; a. Replace bullet
+ (unless (equal old-bul new-bul)
+ (replace-match new-bul nil nil nil 1))
+ ;; b. Replace checkbox.
+ (cond
+ ((equal (match-string 3) new-box))
+ ((and (match-string 3) new-box)
+ (replace-match new-box nil nil nil 3))
+ ((match-string 3)
+ (looking-at ".*?\\([ \t]*\\[[ X-]\\]\\)")
+ (replace-match "" nil nil nil 1))
+ (t (let ((counterp (match-end 2)))
+ (goto-char (if counterp (1+ counterp) (match-end 1)))
+ (insert (concat new-box (unless counterp " "))))))
+ ;; c. Indent item to appropriate column.
+ (unless (= new-ind old-ind)
+ (delete-region (goto-char (point-at-bol))
+ (progn (skip-chars-forward " \t") (point)))
+ (indent-to new-ind))))))
;; 1. First get list of items and position endings. We maintain
;; two alists: ITM-SHIFT, determining indentation shift needed
;; at item, and END-LIST, a pseudo-alist where key is ending
@@ -2484,10 +2476,10 @@ With optional prefix argument ALL, do this for the whole buffer."
(let* ((cookie-re "\\(\\(\\[[0-9]*%\\]\\)\\|\\(\\[[0-9]*/[0-9]*\\]\\)\\)")
(box-re "^[ \t]*\\([-+*]\\|\\([0-9]+\\|[A-Za-z]\\)[.)]\\)[ \t]+\
\\(?:\\[@\\(?:start:\\)?\\([0-9]+\\|[A-Za-z]\\)\\][ \t]*\\)?\\(\\[[- X]\\]\\)")
+ (cookie-data (or (org-entry-get nil "COOKIE_DATA") ""))
(recursivep
(or (not org-checkbox-hierarchical-statistics)
- (string-match "\\<recursive\\>"
- (or (org-entry-get nil "COOKIE_DATA") ""))))
+ (string-match-p "\\<recursive\\>" cookie-data)))
(within-inlinetask (and (not all)
(featurep 'org-inlinetask)
(org-inlinetask-in-task-p)))
@@ -2533,7 +2525,8 @@ With optional prefix argument ALL, do this for the whole buffer."
(while (re-search-forward cookie-re end t)
(let ((context (save-excursion (backward-char)
(save-match-data (org-element-context)))))
- (when (eq (org-element-type context) 'statistics-cookie)
+ (when (and (eq (org-element-type context) 'statistics-cookie)
+ (not (string-match-p "\\<todo\\>" cookie-data)))
(push
(append
(list (match-beginning 1) (match-end 1) (match-end 2))
@@ -3355,7 +3348,7 @@ Valid parameters are:
(when (and backend (symbolp backend) (not (org-export-get-backend backend)))
(user-error "Unknown :backend value"))
(unless backend (require 'ox-org))
- ;; When`:raw' property has a non-nil value, turn all objects back
+ ;; When ':raw' property has a non-nil value, turn all objects back
;; into Org syntax.
(when (and backend (plist-get params :raw))
(org-element-map data org-element-all-objects
diff --git a/lisp/org/org-macro.el b/lisp/org/org-macro.el
index f914a33d61b..83c35faea41 100644
--- a/lisp/org/org-macro.el
+++ b/lisp/org/org-macro.el
@@ -30,7 +30,7 @@
;; `org-macro-initialize-templates', which recursively calls
;; `org-macro--collect-macros' in order to read setup files.
-;; Argument in macros are separated with commas. Proper escaping rules
+;; Argument in macros are separated with commas. Proper escaping rules
;; are implemented in `org-macro-escape-arguments' and arguments can
;; be extracted from a string with `org-macro-extract-arguments'.
@@ -61,7 +61,6 @@
(declare-function org-element-type "org-element" (element))
(declare-function org-entry-get "org" (pom property &optional inherit literal-nil))
(declare-function org-file-contents "org" (file &optional noerror nocache))
-(declare-function org-file-url-p "org" (file))
(declare-function org-in-commented-heading-p "org" (&optional no-inheritance))
(declare-function org-link-search "ol" (s &optional avoid-pos stealth))
(declare-function org-mode "org" ())
@@ -84,42 +83,67 @@ directly, use instead:
;;; Functions
-(defun org-macro--set-template (name value templates)
+(defun org-macro--makeargs (template)
+ "Compute the formal arglist to use for TEMPLATE."
+ (let ((max 0) (i 0))
+ (while (string-match "\\$\\([0-9]+\\)" template i)
+ (setq i (match-end 0))
+ (setq max (max max (string-to-number (match-string 1 template)))))
+ (let ((args '(&rest _)))
+ (if (< max 1) args ;Avoid `&optional &rest', refused by Emacs-26!
+ (while (> max 0)
+ (push (intern (format "$%d" max)) args)
+ (setq max (1- max)))
+ (cons '&optional args)))))
+
+(defun org-macro--set-templates (templates)
"Set template for the macro NAME.
VALUE is the template of the macro. The new value override the
-previous one, unless VALUE is nil. TEMPLATES is the list of
-templates. Return the updated list."
- (let ((old-definition (assoc name templates)))
- (cond ((and value old-definition) (setcdr old-definition value))
- (old-definition)
- (t (push (cons name (or value "")) templates))))
- templates)
+previous one, unless VALUE is nil. Return the updated list."
+ (let ((new-templates nil))
+ (pcase-dolist (`(,name . ,value) templates)
+ (let ((old-definition (assoc name new-templates)))
+ (when (and (stringp value) (string-match-p "\\`(eval\\>" value))
+ ;; Pre-process the evaluation form for faster macro expansion.
+ (let* ((args (org-macro--makeargs value))
+ (body
+ (condition-case nil
+ ;; `value' is of the form "(eval ...)" but we
+ ;; don't want this to mean to pass the result to
+ ;; `eval' (which would cause double evaluation),
+ ;; so we strip the `eval' away with `cadr'.
+ (cadr (read value))
+ (error
+ (user-error "Invalid definition for macro %S" name)))))
+ (setq value (eval (macroexpand-all `(lambda ,args ,body)) t))))
+ (cond ((and value old-definition) (setcdr old-definition value))
+ (old-definition)
+ (t (push (cons name (or value "")) new-templates)))))
+ new-templates))
(defun org-macro--collect-macros ()
"Collect macro definitions in current buffer and setup files.
Return an alist containing all macro templates found."
- (let ((templates nil))
+ (let ((templates
+ `(("author" . ,(org-macro--find-keyword-value "AUTHOR" t))
+ ("email" . ,(org-macro--find-keyword-value "EMAIL"))
+ ("title" . ,(org-macro--find-keyword-value "TITLE" t))
+ ("date" . ,(org-macro--find-date)))))
(pcase (org-collect-keywords '("MACRO"))
(`(("MACRO" . ,values))
(dolist (value values)
(when (string-match "^\\(\\S-+\\)[ \t]*" value)
(let ((name (match-string 1 value))
(definition (substring value (match-end 0))))
- (setq templates
- (org-macro--set-template name definition templates)))))))
- (let ((macros `(("author" . ,(org-macro--find-keyword-value "AUTHOR"))
- ("email" . ,(org-macro--find-keyword-value "EMAIL"))
- ("title" . ,(org-macro--find-keyword-value "TITLE" t))
- ("date" . ,(org-macro--find-date)))))
- (pcase-dolist (`(,name . ,value) macros)
- (setq templates (org-macro--set-template name value templates))))
+ (push (cons name definition) templates))))))
templates))
-(defun org-macro-initialize-templates ()
+(defun org-macro-initialize-templates (&optional default)
"Collect macro templates defined in current buffer.
-Templates are stored in buffer-local variable
-`org-macro-templates'.
+DEFAULT is a list of globally available templates.
+
+Templates are stored in buffer-local variable `org-macro-templates'.
In addition to buffer-defined macros, the function installs the
following ones: \"n\", \"author\", \"email\", \"keyword\",
@@ -129,8 +153,9 @@ a file, \"input-file\" and \"modification-time\"."
(org-macro--counter-initialize) ;for "n" macro
(setq org-macro-templates
(nconc
- ;; Install user-defined macros.
- (org-macro--collect-macros)
+ ;; Install user-defined macros. Local macros have higher
+ ;; precedence than global ones.
+ (org-macro--set-templates (append default (org-macro--collect-macros)))
;; Install file-specific macros.
(let ((visited-file (buffer-file-name (buffer-base-buffer))))
(and visited-file
@@ -138,21 +163,23 @@ a file, \"input-file\" and \"modification-time\"."
(list
`("input-file" . ,(file-name-nondirectory visited-file))
`("modification-time" .
- ,(format "(eval
-\(format-time-string $1
- (or (and (org-string-nw-p $2)
- (org-macro--vc-modified-time %s))
- '%s)))"
- (prin1-to-string visited-file)
- (prin1-to-string
- (file-attribute-modification-time
- (file-attributes visited-file))))))))
+ ,(let ((modtime (file-attribute-modification-time
+ (file-attributes visited-file))))
+ (lambda (arg1 &optional arg2 &rest _)
+ (format-time-string
+ arg1
+ (or (and (org-string-nw-p arg2)
+ (org-macro--vc-modified-time visited-file))
+ modtime))))))))
;; Install generic macros.
- (list
- '("n" . "(eval (org-macro--counter-increment $1 $2))")
- '("keyword" . "(eval (org-macro--find-keyword-value $1))")
- '("time" . "(eval (format-time-string $1))")
- '("property" . "(eval (org-macro--get-property $1 $2))")))))
+ '(("keyword" . (lambda (arg1 &rest _)
+ (org-macro--find-keyword-value arg1 t)))
+ ("n" . (lambda (&optional arg1 arg2 &rest _)
+ (org-macro--counter-increment arg1 arg2)))
+ ("property" . (lambda (arg1 &optional arg2 &rest _)
+ (org-macro--get-property arg1 arg2)))
+ ("time" . (lambda (arg1 &rest _)
+ (format-time-string arg1)))))))
(defun org-macro-expand (macro templates)
"Return expanded MACRO, as a string.
@@ -164,21 +191,17 @@ default value. Return nil if no template was found."
;; Macro names are case-insensitive.
(cdr (assoc-string (org-element-property :key macro) templates t))))
(when template
- (let* ((eval? (string-match-p "\\`(eval\\>" template))
- (value
- (replace-regexp-in-string
- "\\$[0-9]+"
- (lambda (m)
- (let ((arg (or (nth (1- (string-to-number (substring m 1)))
- (org-element-property :args macro))
- ;; No argument: remove place-holder.
- "")))
- ;; `eval' implies arguments are strings.
- (if eval? (format "%S" arg) arg)))
- template nil 'literal)))
- (when eval?
- (setq value (eval (condition-case nil (read value)
- (error (debug))))))
+ (let* ((value
+ (if (functionp template)
+ (apply template (org-element-property :args macro))
+ (replace-regexp-in-string
+ "\\$[0-9]+"
+ (lambda (m)
+ (or (nth (1- (string-to-number (substring m 1)))
+ (org-element-property :args macro))
+ ;; No argument: remove place-holder.
+ ""))
+ template nil 'literal))))
;; Force return value to be a string.
(format "%s" (or value ""))))))
@@ -345,7 +368,7 @@ Return value as a string."
date)
(unwind-protect
(progn
- (vc-call print-log file buf nil nil 1)
+ (vc-call print-log (list file) buf nil nil 1)
(with-current-buffer buf
(vc-exec-after
(lambda ()
@@ -355,7 +378,7 @@ Return value as a string."
(buffer-substring
(point) (line-end-position)))))
(when (cl-some #'identity time)
- (setq date (apply #'encode-time time))))))))
+ (setq date (encode-time time))))))))
(let ((proc (get-buffer-process buf)))
(while (and proc (accept-process-output proc .5 nil t)))))
(kill-buffer buf))
@@ -380,7 +403,7 @@ value, i.e. do not increment.
If the string represents an integer, set the counter to this number.
Any other non-empty string resets the counter to 1."
- (let ((name-trimmed (org-trim name))
+ (let ((name-trimmed (if (stringp name) (org-trim name) ""))
(action-trimmed (when (org-string-nw-p action)
(org-trim action))))
(puthash name-trimmed
diff --git a/lisp/org/org-macs.el b/lisp/org/org-macs.el
index 58d3fd39922..044056b7a04 100644
--- a/lisp/org/org-macs.el
+++ b/lisp/org/org-macs.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
@@ -39,6 +39,7 @@
(declare-function org-string-collate-lessp "org-compat" (s1 s2 &optional locale ignore-case))
(defvar org-ts-regexp0)
+(defvar ffap-url-regexp)
;;; Macros
@@ -172,7 +173,7 @@ because otherwise all these markers will point to nowhere."
,@body)))
(defmacro org-eval-in-environment (environment form)
- (declare (debug (form form)) (indent 1))
+ (declare (debug (form form)) (indent 1) (obsolete cl-progv "2021"))
`(eval (list 'let ,environment ',form)))
;;;###autoload
@@ -208,7 +209,7 @@ because otherwise all these markers will point to nowhere."
(defmacro org-no-popups (&rest body)
"Suppress popup windows and evaluate BODY."
- `(let (pop-up-frames display-buffer-alist)
+ `(let (pop-up-frames pop-up-windows)
,@body))
@@ -325,17 +326,19 @@ it for output."
;;; Indentation
-(defun org-do-remove-indentation (&optional n)
+(defun org-do-remove-indentation (&optional n skip-fl)
"Remove the maximum common indentation from the buffer.
When optional argument N is a positive integer, remove exactly
-that much characters from indentation, if possible. Return nil
-if it fails."
+that much characters from indentation, if possible. When
+optional argument SKIP-FL is non-nil, skip the first
+line. Return nil if it fails."
(catch :exit
(goto-char (point-min))
;; Find maximum common indentation, if not specified.
(let ((n (or n
(let ((min-ind (point-max)))
(save-excursion
+ (when skip-fl (forward-line))
(while (re-search-forward "^[ \t]*\\S-" nil t)
(let ((ind (current-indentation)))
(if (zerop ind) (throw :exit nil)
@@ -343,6 +346,7 @@ if it fails."
min-ind))))
(if (zerop n) (throw :exit nil)
;; Remove exactly N indentation, but give up if not possible.
+ (when skip-fl (forward-line))
(while (not (eobp))
(let ((ind (progn (skip-chars-forward " \t") (current-column))))
(cond ((eolp) (delete-region (line-beginning-position) (point)))
@@ -366,15 +370,17 @@ error when the user input is empty."
(allow-empty? nil)
(t (user-error "Empty input is not valid")))))
+(declare-function org-time-stamp-inactive "org" (&optional arg))
+
(defun org-completing-read (&rest args)
"Completing-read with SPACE being a normal character."
(let ((enable-recursive-minibuffers t)
(minibuffer-local-completion-map
(copy-keymap minibuffer-local-completion-map)))
- (define-key minibuffer-local-completion-map " " 'self-insert-command)
- (define-key minibuffer-local-completion-map "?" 'self-insert-command)
+ (define-key minibuffer-local-completion-map " " #'self-insert-command)
+ (define-key minibuffer-local-completion-map "?" #'self-insert-command)
(define-key minibuffer-local-completion-map (kbd "C-c !")
- 'org-time-stamp-inactive)
+ #'org-time-stamp-inactive)
(apply #'completing-read args)))
(defun org--mks-read-key (allowed-keys prompt navigation-keys)
@@ -470,8 +476,8 @@ is selected, only the bare key is returned."
(goto-char (point-min))
(org-fit-window-to-buffer)
(message "") ; With this line the prompt appears in
- ; the minibuffer. Else keystrokes may
- ; appear, which is spurious.
+ ; the minibuffer. Else keystrokes may
+ ; appear, which is spurious.
(let ((pressed (org--mks-read-key
allowed-keys prompt
(not (pos-visible-in-window-p (1- (point-max)))))))
@@ -535,6 +541,11 @@ that may remove elements by altering the list structure."
(setq list (delete (pop elts) list)))
list)
+(defun org-plist-delete-all (plist props)
+ "Delete all elements in PROPS from PLIST."
+ (dolist (e props plist)
+ (setq plist (org-plist-delete plist e))))
+
(defun org-plist-delete (plist property)
"Delete PROPERTY from PLIST.
This is in contrast to merely setting it to 0."
@@ -627,6 +638,30 @@ program is needed for, so that the error message can be more informative."
(let ((message-log-max nil))
(apply #'message args)))
+(defmacro org-dlet (binders &rest body)
+ "Like `let*' but using dynamic scoping."
+ (declare (indent 1) (debug let))
+ (let ((vars (mapcar (lambda (binder)
+ (if (consp binder) (car binder) binder))
+ binders)))
+ `(progn
+ (with-no-warnings
+ ,@(mapcar (lambda (var) `(defvar ,var)) vars))
+ (let* ,binders ,@body))))
+
+(defmacro org-pushnew-to-end (val var)
+ "Like `cl-pushnew' but pushes to the end of the list.
+Uses `equal' for comparisons.
+
+Beware: this performs O(N) memory allocations, so if you use it in a loop, you
+get an unnecessary O(N²) space complexity, so you're usually better off using
+`cl-pushnew' (with a final `reverse' if you care about the order of elements)."
+ (declare (debug (form gv-place)))
+ (let ((v (make-symbol "v")))
+ `(let ((,v ,val))
+ (unless (member ,v ,var)
+ (setf ,var (append ,var (list ,v)))))))
+
(defun org-eval (form)
"Eval FORM and return result."
(condition-case error
@@ -781,6 +816,10 @@ return nil."
(list context (match-beginning group) (match-end group))
t)))
+(defun org-url-p (s)
+ "Non-nil if string S is a URL."
+ (require 'ffap)
+ (and ffap-url-regexp (string-match-p ffap-url-regexp s)))
;;; String manipulation
@@ -975,7 +1014,7 @@ IF WIDTH is nil and LINES is non-nil, the string is forced into at most that
many lines, whatever width that takes.
The return value is a list of lines, without newlines at the end."
(let* ((words (split-string string))
- (maxword (apply 'max (mapcar 'org-string-width words)))
+ (maxword (apply #'max (mapcar #'org-string-width words)))
w ll)
(cond (width
(org--do-wrap words (max maxword width)))
@@ -1072,10 +1111,11 @@ that will be added to PLIST. Returns the string that was modified."
string)
(defun org-make-parameter-alist (flat)
+ ;; FIXME: "flat" is called a "plist"!
"Return alist based on FLAT.
FLAT is a list with alternating symbol names and values. The
returned alist is a list of lists with the symbol name in car and
-the value in cdr."
+the value in cadr."
(when flat
(cons (list (car flat) (cadr flat))
(org-make-parameter-alist (cddr flat)))))
@@ -1122,13 +1162,13 @@ move it back by one char before doing this check."
(org-invisible-p)))
(defun org-find-visible ()
- "Return closest visible buffer position, or `point-max'"
+ "Return closest visible buffer position, or `point-max'."
(if (org-invisible-p)
(next-single-char-property-change (point) 'invisible)
(point)))
(defun org-find-invisible ()
- "Return closest invisible buffer position, or `point-max'"
+ "Return closest invisible buffer position, or `point-max'."
(if (org-invisible-p)
(point)
(next-single-char-property-change (point) 'invisible)))
@@ -1145,7 +1185,7 @@ nil, just return 0."
((numberp s) s)
((stringp s)
(condition-case nil
- (float-time (apply #'encode-time (org-parse-time-string s)))
+ (float-time (encode-time (org-parse-time-string s)))
(error 0)))
(t 0)))
@@ -1212,7 +1252,7 @@ following special strings: \"<now>\", \"<today>\",
\"<tomorrow>\", and \"<yesterday>\".
Return 0. if S is not recognized as a valid value."
- (let ((today (float-time (apply #'encode-time
+ (let ((today (float-time (encode-time
(append '(0 0 0) (nthcdr 3 (decode-time)))))))
(save-match-data
(cond
@@ -1221,10 +1261,11 @@ Return 0. if S is not recognized as a valid value."
((string= s "<tomorrow>") (+ 86400.0 today))
((string= s "<yesterday>") (- today 86400.0))
((string-match "\\`<\\([-+][0-9]+\\)\\([hdwmy]\\)>\\'" s)
- (+ today
+ (+ (if (string= (match-string 2 s) "h") (float-time) today)
(* (string-to-number (match-string 1 s))
(cdr (assoc (match-string 2 s)
- '(("d" . 86400.0) ("w" . 604800.0)
+ '(("h" . 3600.0)
+ ("d" . 86400.0) ("w" . 604800.0)
("m" . 2678400.0) ("y" . 31557600.0)))))))
((string-match org-ts-regexp0 s) (org-2ft s))
(t 0.)))))
@@ -1238,13 +1279,13 @@ window."
(scrldn (if additional-keys `(?\d ?\M-v) ?\M-v)))
(pcase key
(?\C-n (if (not (pos-visible-in-window-p (point-max)))
- (ignore-errors (scroll-up 1))
- (message "End of buffer")
- (sit-for 1)))
+ (ignore-errors (scroll-up 1))
+ (message "End of buffer")
+ (sit-for 1)))
(?\C-p (if (not (pos-visible-in-window-p (point-min)))
- (ignore-errors (scroll-down 1))
- (message "Beginning of buffer")
- (sit-for 1)))
+ (ignore-errors (scroll-down 1))
+ (message "Beginning of buffer")
+ (sit-for 1)))
;; SPC or
((guard (memq key scrlup))
(if (not (pos-visible-in-window-p (point-max)))
diff --git a/lisp/org/org-mobile.el b/lisp/org/org-mobile.el
index a64e0a274a2..e51258af058 100644
--- a/lisp/org/org-mobile.el
+++ b/lisp/org/org-mobile.el
@@ -1,7 +1,7 @@
;;; org-mobile.el --- Code for Asymmetric Sync With a Mobile Device -*- lexical-binding: t; -*-
;; Copyright (C) 2009-2021 Free Software Foundation, Inc.
;;
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
diff --git a/lisp/org/org-mouse.el b/lisp/org/org-mouse.el
index 57281dd68c0..a35a19bca65 100644
--- a/lisp/org/org-mouse.el
+++ b/lisp/org/org-mouse.el
@@ -3,7 +3,7 @@
;; Copyright (C) 2006-2021 Free Software Foundation, Inc.
;; Author: Piotr Zielinski <piotr dot zielinski at gmail dot com>
-;; Maintainer: Carsten Dominik <carsten at orgmode dot org>
+;; Maintainer: Carsten Dominik <carsten.dominik@gmail.com>
;; This file is part of GNU Emacs.
@@ -161,7 +161,7 @@ it is intended to operate on. If nil, then the action has been invoked
indirectly, for example, through the agenda buffer.")
(defgroup org-mouse nil
- "Mouse support for org-mode."
+ "Mouse support for `org-mode'."
:tag "Org Mouse"
:group 'org)
@@ -220,7 +220,7 @@ this function is called. Otherwise, the current major mode menu is used."
(if (fboundp 'mouse-menu-major-mode-map)
(popup-menu (mouse-menu-major-mode-map) event prefix)
(with-no-warnings ; don't warn about fallback, obsolete since 23.1
- (mouse-major-mode-menu event prefix)))))
+ (mouse-major-mode-menu event prefix)))))
(setq this-command 'mouse-save-then-kill)
(mouse-save-then-kill event)))
@@ -291,18 +291,18 @@ string to (format ITEMFORMAT keyword). If it is neither a string
nor a function, elements of KEYWORDS are used directly."
(mapcar
(lambda (keyword)
- (vector (cond
- ((functionp itemformat) (funcall itemformat keyword))
- ((stringp itemformat) (format itemformat keyword))
- (t keyword))
- (list 'funcall function keyword)
- :style (cond
- ((null selected) t)
- ((functionp selected) 'toggle)
- (t 'radio))
- :selected (if (functionp selected)
- (and (funcall selected keyword) t)
- (equal selected keyword))))
+ (vector (cond
+ ((functionp itemformat) (funcall itemformat keyword))
+ ((stringp itemformat) (format itemformat keyword))
+ (t keyword))
+ (list 'funcall function keyword)
+ :style (cond
+ ((null selected) t)
+ ((functionp selected) 'toggle)
+ (t 'radio))
+ :selected (if (functionp selected)
+ (and (funcall selected keyword) t)
+ (equal selected keyword))))
keywords))
(defun org-mouse-remove-match-and-spaces ()
@@ -424,11 +424,11 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:"
(org-mouse-keyword-menu
(sort (mapcar #'car (org-get-buffer-tags)) #'string-lessp)
(lambda (tag)
- (org-mouse-set-tags
- (sort (if (member tag tags)
- (delete tag tags)
- (cons tag tags))
- #'string-lessp)))
+ (org-mouse-set-tags
+ (sort (if (member tag tags)
+ (delete tag tags)
+ (cons tag tags))
+ #'string-lessp)))
(lambda (tag) (member tag tags))
))
'("--"
@@ -499,7 +499,7 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:"
("Check Tags"
,@(org-mouse-keyword-menu
(sort (mapcar #'car (org-get-buffer-tags)) #'string-lessp)
- #'(lambda (tag) (org-tags-sparse-tree nil tag)))
+ (lambda (tag) (org-tags-sparse-tree nil tag)))
"--"
["Custom Tag ..." org-tags-sparse-tree t])
["Check Phrase ..." org-occur]
@@ -509,26 +509,26 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:"
("Display Tags"
,@(org-mouse-keyword-menu
(sort (mapcar #'car (org-get-buffer-tags)) #'string-lessp)
- #'(lambda (tag) (org-tags-view nil tag)))
+ (lambda (tag) (org-tags-view nil tag)))
"--"
["Custom Tag ..." org-tags-view t])
["Display Calendar" org-goto-calendar t]
"--"
,@(org-mouse-keyword-menu
(mapcar #'car org-agenda-custom-commands)
- #'(lambda (key)
- (org-agenda nil (string-to-char key)))
+ (lambda (key)
+ (org-agenda nil (string-to-char key)))
nil
- #'(lambda (key)
- (let ((entry (assoc key org-agenda-custom-commands)))
- (org-mouse-clip-text
- (cond
- ((stringp (nth 1 entry)) (nth 1 entry))
- ((stringp (nth 2 entry))
- (concat (org-mouse-agenda-type (nth 1 entry))
- (nth 2 entry)))
- (t "Agenda Command `%s'"))
- 30))))
+ (lambda (key)
+ (let ((entry (assoc key org-agenda-custom-commands)))
+ (org-mouse-clip-text
+ (cond
+ ((stringp (nth 1 entry)) (nth 1 entry))
+ ((stringp (nth 2 entry))
+ (concat (org-mouse-agenda-type (nth 1 entry))
+ (nth 2 entry)))
+ (t "Agenda Command `%s'"))
+ 30))))
"--"
["Delete Blank Lines" delete-blank-lines
:visible (org-mouse-empty-line)]
@@ -793,8 +793,8 @@ This means, between the beginning of line and the point."
("Tags and Priorities"
,@(org-mouse-keyword-menu
(org-mouse-priority-list)
- #'(lambda (keyword)
- (org-mouse-set-priority (string-to-char keyword)))
+ (lambda (keyword)
+ (org-mouse-set-priority (string-to-char keyword)))
priority "Priority %s")
"--"
,@(org-mouse-tag-menu))
@@ -854,55 +854,55 @@ This means, between the beginning of line and the point."
(mouse-drag-region event)))
(add-hook 'org-mode-hook
- #'(lambda ()
- (setq org-mouse-context-menu-function #'org-mouse-context-menu)
-
- (when (memq 'context-menu org-mouse-features)
- (org-defkey org-mouse-map [mouse-3] nil)
- (org-defkey org-mode-map [mouse-3] #'org-mouse-show-context-menu))
- (org-defkey org-mode-map [down-mouse-1] #'org-mouse-down-mouse)
- (when (memq 'context-menu org-mouse-features)
- (org-defkey org-mouse-map [C-drag-mouse-1] #'org-mouse-move-tree)
- (org-defkey org-mouse-map [C-down-mouse-1] #'org-mouse-move-tree-start))
- (when (memq 'yank-link org-mouse-features)
- (org-defkey org-mode-map [S-mouse-2] #'org-mouse-yank-link)
- (org-defkey org-mode-map [drag-mouse-3] #'org-mouse-yank-link))
- (when (memq 'move-tree org-mouse-features)
- (org-defkey org-mouse-map [drag-mouse-3] #'org-mouse-move-tree)
- (org-defkey org-mouse-map [down-mouse-3] #'org-mouse-move-tree-start))
-
- (when (memq 'activate-stars org-mouse-features)
- (font-lock-add-keywords
- nil
- `((,org-outline-regexp
- 0 `(face org-link mouse-face highlight keymap ,org-mouse-map)
- 'prepend))
- t))
-
- (when (memq 'activate-bullets org-mouse-features)
- (font-lock-add-keywords
- nil
- `(("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +"
- (1 `(face org-link keymap ,org-mouse-map mouse-face highlight)
- 'prepend)))
- t))
-
- (when (memq 'activate-checkboxes org-mouse-features)
- (font-lock-add-keywords
- nil
- `(("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +\\(\\[[ X]\\]\\)"
- (2 `(face bold keymap ,org-mouse-map mouse-face highlight) t)))
- t))
-
- (defadvice org-open-at-point (around org-mouse-open-at-point activate)
- (let ((context (org-context)))
- (cond
- ((assq :headline-stars context) (org-cycle))
- ((assq :checkbox context) (org-toggle-checkbox))
- ((assq :item-bullet context)
- (let ((org-cycle-include-plain-lists t)) (org-cycle)))
- ((org-footnote-at-reference-p) nil)
- (t ad-do-it))))))
+ (lambda ()
+ (setq org-mouse-context-menu-function #'org-mouse-context-menu)
+
+ (when (memq 'context-menu org-mouse-features)
+ (org-defkey org-mouse-map [mouse-3] nil)
+ (org-defkey org-mode-map [mouse-3] #'org-mouse-show-context-menu))
+ (org-defkey org-mode-map [down-mouse-1] #'org-mouse-down-mouse)
+ (when (memq 'context-menu org-mouse-features)
+ (org-defkey org-mouse-map [C-drag-mouse-1] #'org-mouse-move-tree)
+ (org-defkey org-mouse-map [C-down-mouse-1] #'org-mouse-move-tree-start))
+ (when (memq 'yank-link org-mouse-features)
+ (org-defkey org-mode-map [S-mouse-2] #'org-mouse-yank-link)
+ (org-defkey org-mode-map [drag-mouse-3] #'org-mouse-yank-link))
+ (when (memq 'move-tree org-mouse-features)
+ (org-defkey org-mouse-map [drag-mouse-3] #'org-mouse-move-tree)
+ (org-defkey org-mouse-map [down-mouse-3] #'org-mouse-move-tree-start))
+
+ (when (memq 'activate-stars org-mouse-features)
+ (font-lock-add-keywords
+ nil
+ `((,org-outline-regexp
+ 0 `(face org-link mouse-face highlight keymap ,org-mouse-map)
+ 'prepend))
+ t))
+
+ (when (memq 'activate-bullets org-mouse-features)
+ (font-lock-add-keywords
+ nil
+ `(("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +"
+ (1 `(face org-link keymap ,org-mouse-map mouse-face highlight)
+ 'prepend)))
+ t))
+
+ (when (memq 'activate-checkboxes org-mouse-features)
+ (font-lock-add-keywords
+ nil
+ `(("^[ \t]*\\(?:[-+*]\\|[0-9]+[.)]\\)[ \t]+\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\(\\[[- X]\\]\\)"
+ (1 `(face nil keymap ,org-mouse-map mouse-face highlight) prepend)))
+ t))
+
+ (defadvice org-open-at-point (around org-mouse-open-at-point activate)
+ (let ((context (org-context)))
+ (cond
+ ((assq :headline-stars context) (org-cycle))
+ ((assq :checkbox context) (org-toggle-checkbox))
+ ((assq :item-bullet context)
+ (let ((org-cycle-include-plain-lists t)) (org-cycle)))
+ ((org-footnote-at-reference-p) nil)
+ (t ad-do-it))))))
(defun org-mouse-move-tree-start (_event)
(interactive "e")
diff --git a/lisp/org/org-num.el b/lisp/org/org-num.el
index ebddaa32b4e..f00e6c463b8 100644
--- a/lisp/org/org-num.el
+++ b/lisp/org/org-num.el
@@ -29,8 +29,8 @@
;; to toggle it.
;;
;; You can select what is numbered according to level, tags, COMMENT
-;; keyword, or UNNUMBERED property. You can also skip footnotes
-;; sections. See `org-num-max-level', `org-num-skip-tags',
+;; keyword, or UNNUMBERED property. You can also skip footnotes
+;; sections. See `org-num-max-level', `org-num-skip-tags',
;; `org-num-skip-commented', `org-num-skip-unnumbered', and
;; `org-num-skip-footnotes' for details.
;;
@@ -63,6 +63,7 @@
(require 'cl-lib)
(require 'org-macs)
+(require 'org) ;Otherwise `org-num--comment-re' burps on `org-comment-string'
(defvar org-comment-string)
(defvar org-complex-heading-regexp)
@@ -90,7 +91,7 @@ output."
(face :tag "Use face"))
:safe (lambda (val) (or (null val) (facep val))))
-(defcustom org-num-format-function 'org-num-default-format
+(defcustom org-num-format-function #'org-num-default-format
"Function used to display numbering.
It is called with one argument, a list of numbers, and should
return a string, or nil. When nil, no numbering is displayed.
@@ -98,8 +99,7 @@ Any `face' text property on the returned string overrides
`org-num-face'."
:group 'org-appearance
:package-version '(Org . "9.3")
- :type 'function
- :safe nil)
+ :type 'function)
(defcustom org-num-max-level nil
"Level below which headlines are not numbered.
diff --git a/lisp/org/org-pcomplete.el b/lisp/org/org-pcomplete.el
index d8a4937b95a..b31dc333fd9 100644
--- a/lisp/org/org-pcomplete.el
+++ b/lisp/org/org-pcomplete.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
;;
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; John Wiegley <johnw at gnu dot org>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
@@ -21,8 +21,7 @@
;; 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 other packages
@@ -186,7 +185,7 @@ When completing for #+STARTUP, for example, this function returns
(cons (reverse args) (reverse begins))))))
(defun org-pcomplete-initial ()
- "Calls the right completion function for first argument completions."
+ "Call the right completion function for first argument completions."
(ignore
(funcall (or (pcomplete-find-completion-function
(car (org-thing-at-point)))
diff --git a/lisp/org/org-plot.el b/lisp/org/org-plot.el
index 4ac15b379d3..4f14c7d4c34 100644
--- a/lisp/org/org-plot.el
+++ b/lisp/org/org-plot.el
@@ -51,19 +51,28 @@
"Parse an OPTIONS line and set values in the property list P.
Returns the resulting property list."
(when options
- (let ((op '(("type" . :plot-type)
- ("script" . :script)
- ("line" . :line)
- ("set" . :set)
- ("title" . :title)
- ("ind" . :ind)
- ("deps" . :deps)
- ("with" . :with)
- ("file" . :file)
- ("labels" . :labels)
- ("map" . :map)
- ("timeind" . :timeind)
- ("timefmt" . :timefmt)))
+ (let ((op '(("type" . :plot-type)
+ ("script" . :script)
+ ("line" . :line)
+ ("set" . :set)
+ ("title" . :title)
+ ("ind" . :ind)
+ ("deps" . :deps)
+ ("with" . :with)
+ ("file" . :file)
+ ("labels" . :labels)
+ ("map" . :map)
+ ("timeind" . :timeind)
+ ("timefmt" . :timefmt)
+ ("min" . :ymin)
+ ("ymin" . :ymin)
+ ("max" . :ymax)
+ ("ymax" . :ymax)
+ ("xmin" . :xmin)
+ ("xmax" . :xmax)
+ ("ticks" . :ticks)
+ ("trans" . :transpose)
+ ("transpose" . :transpose)))
(multiples '("set" "line"))
(regexp ":\\([\"][^\"]+?[\"]\\|[(][^)]+?[)]\\|[^ \t\n\r;,.]*\\)")
(start 0))
@@ -180,94 +189,440 @@ and dependent variables."
(setf back-edge "") (setf front-edge ""))))
row-vals))
-(defun org-plot/gnuplot-script (data-file num-cols params &optional preface)
- "Write a gnuplot script to DATA-FILE respecting the options set in PARAMS.
+(defun org--plot/values-stats (nums &optional hard-min hard-max)
+ "Rudimentary statistics about NUMS, useful for guessing axis ticks.
+If HARD-MIN or HARD-MAX are set, they will be used instead of the min/max
+of the NUMS."
+ (let* ((minimum (or hard-min (apply #'min nums)))
+ (maximum (or hard-max (apply #'max nums)))
+ (range (- maximum minimum))
+ (rangeOrder (if (= range 0) 0
+ (ceiling (- 1 (log range 10)))))
+ (range-factor (expt 10 rangeOrder))
+ (nice-min (if (= range 0) (car nums)
+ (/ (float (floor (* minimum range-factor))) range-factor)))
+ (nice-max (if (= range 0) (car nums)
+ (/ (float (ceiling (* maximum range-factor))) range-factor))))
+ `(:min ,minimum :max ,maximum :range ,range
+ :range-factor ,range-factor
+ :nice-min ,nice-min :nice-max ,nice-max :nice-range ,(- nice-max nice-min))))
+
+(defun org--plot/sensible-tick-num (table &optional hard-min hard-max)
+ "From a the values in a TABLE of data, guess an appropriate number of ticks.
+If HARD-MIN and HARD-MAX can be used to fix the ends of the axis."
+ (let* ((row-data
+ (mapcar (lambda (row) (org--plot/values-stats
+ (mapcar #'string-to-number (cdr row))
+ hard-min
+ hard-max)) table))
+ (row-normalised-ranges (mapcar (lambda (r-data)
+ (let ((val (round (*
+ (plist-get r-data :range-factor)
+ (plist-get r-data :nice-range)))))
+ (if (= (% val 10) 0) (/ val 10) val)))
+ row-data))
+ (range-prime-decomposition (mapcar #'org--plot/prime-factors row-normalised-ranges))
+ (weighted-factors (sort (apply #'org--plot/merge-alists #'+ 0
+ (mapcar (lambda (factors) (org--plot/item-frequencies factors t))
+ range-prime-decomposition))
+ (lambda (a b) (> (cdr a) (cdr b))))))
+ (apply #'* (org--plot/nice-frequency-pick weighted-factors))))
+
+(defun org--plot/nice-frequency-pick (frequencies)
+ "From a list of FREQUENCIES, try to sensibly pick a sample of the most frequent."
+ ;; TODO this mosly works decently, but could do with some tweaking to work more consistently.
+ (cl-case (length frequencies)
+ (1 (list (car (nth 0 frequencies))))
+ (2 (if (<= 3 (/ (cdr (nth 0 frequencies))
+ (cdr (nth 1 frequencies))))
+ (make-list 2
+ (car (nth 0 frequencies)))
+ (list (car (nth 0 frequencies))
+ (car (nth 1 frequencies)))))
+ (t
+ (let* ((total-count (apply #'+ (mapcar #'cdr frequencies)))
+ (n-freq (mapcar (lambda (freq) `(,(car freq) . ,(/ (float (cdr freq)) total-count))) frequencies))
+ (f-pick (list (car (car n-freq))))
+ (1-2-ratio (/ (cdr (nth 0 n-freq))
+ (cdr (nth 1 n-freq))))
+ (2-3-ratio (/ (cdr (nth 1 n-freq))
+ (cdr (nth 2 n-freq))))
+ (1-3-ratio (* 1-2-ratio 2-3-ratio))
+ (1-val (car (nth 0 n-freq)))
+ (2-val (car (nth 1 n-freq)))
+ (3-val (car (nth 2 n-freq))))
+ (when (> 1-2-ratio 4) (push 1-val f-pick))
+ (when (and (< 1-2-ratio 2-val)
+ (< (* (apply #'* f-pick) 2-val) 30))
+ (push 2-val f-pick))
+ (when (and (< 1-3-ratio 3-val)
+ (< (* (apply #'* f-pick) 3-val) 30))
+ (push 3-val f-pick))
+ f-pick))))
+
+(defun org--plot/merge-alists (function default alist1 alist2 &rest alists)
+ "Using FUNCTION, combine the elements of ALIST1, ALIST2 and any other ALISTS.
+When an element is only present in one alist, DEFAULT is used as the second
+argument for the FUNCTION."
+ (when (> (length alists) 0)
+ (setq alist2 (apply #'org--plot/merge-alists function default alist2 alists)))
+ (cl-flet ((keys (alist) (mapcar #'car alist))
+ (lookup (key alist) (or (cdr (assoc key alist)) default)))
+ (cl-loop with keys = (cl-union (keys alist1) (keys alist2) :test 'equal)
+ for k in keys collect
+ (cons k (funcall function (lookup k alist1) (lookup k alist2))))))
+
+(defun org--plot/item-frequencies (values &optional normalise)
+ "Return an alist indicating the frequency of values in VALUES list.
+When NORMALISE is non-nil, the count is divided by the number of values."
+ (let ((normaliser (if normalise (float (length values)) 1)))
+ (cl-loop for (n . m) in (seq-group-by #'identity values)
+ collect (cons n (/ (length m) normaliser)))))
+
+(defun org--plot/prime-factors (value)
+ "Return the prime decomposition of VALUE, e.g. for 12, '(3 2 2)."
+ (let ((factors '(1)) (i 1))
+ (while (/= 1 value)
+ (setq i (1+ i))
+ (when (eq 0 (% value i))
+ (push i factors)
+ (setq value (/ value i))
+ (setq i (1- i))
+ ))
+ (cl-subseq factors 0 -1)))
+
+(defcustom org-plot/gnuplot-script-preamble ""
+ "String of function to be inserted before the gnuplot plot command is run.
+
+Note that this is in addition to, not instead of other content generated in
+`org-plot/gnuplot-script'. If a function, it is called with the plot type as
+the argument, and must return a string to be used."
+ :group 'org-plot
+ :type '(choice string function))
+
+(defcustom org-plot/preset-plot-types
+ '((2d :plot-cmd "plot"
+ :check-ind-type t
+ :plot-func
+ (lambda (_table data-file num-cols params plot-str)
+ (let* ((type (plist-get params :plot-type))
+ (with (if (eq type 'grid) 'pm3d (plist-get params :with)))
+ (ind (plist-get params :ind))
+ (deps (if (plist-member params :deps) (plist-get params :deps)))
+ (text-ind (or (plist-get params :textind)
+ (eq (plist-get params :with) 'histograms)))
+ (col-labels (plist-get params :labels))
+ res)
+ (dotimes (col num-cols res)
+ (unless (and (eq type '2d)
+ (or (and ind (equal (1+ col) ind))
+ (and deps (not (member (1+ col) deps)))))
+ (setf res
+ (cons
+ (format plot-str data-file
+ (or (and ind (> ind 0)
+ (not text-ind)
+ (format "%d:" ind)) "")
+ (1+ col)
+ (if text-ind (format ":xticlabel(%d)" ind) "")
+ with
+ (or (nth col col-labels)
+ (format "%d" (1+ col))))
+ res)))))))
+ (3d :plot-cmd "splot"
+ :plot-pre (lambda (_table _data-file _num-cols params _plot-str)
+ (if (plist-get params :map) "set map"))
+ :plot-func
+ (lambda (_table data-file _num-cols params _plot-str)
+ (let* ((type (plist-get params :plot-type))
+ (with (if (eq type 'grid) 'pm3d (plist-get params :with))))
+ (list (format "'%s' matrix with %s title ''"
+ data-file with)))))
+ (grid :plot-cmd "splot"
+ :plot-pre (lambda (_table _data-file _num-cols params _plot-str)
+ (if (plist-get params :map) "set pm3d map" "set map"))
+ :data-dump (lambda (table data-file params _num-cols)
+ (let ((y-labels (org-plot/gnuplot-to-grid-data
+ table data-file params)))
+ (when y-labels (plist-put params :ylabels y-labels))))
+ :plot-func
+ (lambda (table data-file _num-cols params _plot-str)
+ (let* ((type (plist-get params :plot-type))
+ (with (if (eq type 'grid) 'pm3d (plist-get params :with))))
+ (list (format "'%s' with %s title ''"
+ data-file with)))))
+ (radar :plot-func
+ (lambda (table _data-file _num-cols params plot-str)
+ (list (org--plot/radar table params)))))
+ "List of plists describing the available plot types.
+The car is the type name, and the property :plot-func must be
+set. The value of :plot-func is a lambda which yields plot-lines
+\(a list of strings) as the cdr.
+
+All lambda functions have the parameters of
+`org-plot/gnuplot-script' and PLOT-STR passed to them. i.e. they
+are called with the following signature: (TABLE DATA-FILE
+NUM-COLS PARAMS PLOT-STR)
+
+Potentially useful parameters in PARAMS include:
+ :set :line :map :title :file :ind :timeind :timefmt :textind
+ :deps :labels :xlabels :ylabels :xmin :xmax :ymin :ymax :ticks
+
+In addition to :plot-func, the following optional properties may
+be set.
+
+- :plot-cmd - A gnuplot command appended to each plot-line.
+ Accepts string or nil. Default value: nil.
+
+- :check-ind-type - Whether the types of ind values should be checked.
+ Accepts boolean.
+
+- :plot-str - the formula string passed to :plot-func as PLOT-STR
+ Accepts string. Default value: \"'%s' using %s%d%s with %s title '%s'\"
+
+- :data-dump - Function to dump the table to a datafile for ease of
+ use.
+
+ Accepts lambda function. Default lambda body:
+ (org-plot/gnuplot-to-data table data-file params)
+
+- :plot-pre - Gnuplot code to be inserted early into the script, just
+ after term and output have been set.
+
+ Accepts string, nil, or lambda function which returns string
+ or nil. Defaults to nil."
+ :group 'org-plot
+ :type 'alist)
+
+(defvar org--plot/radar-template
+ "### spider plot/chart with gnuplot
+# also known as: radar chart, web chart, star chart, cobweb chart,
+# radar plot, web plot, star plot, cobweb plot, etc. ...
+set datafile separator ' '
+set size square
+unset tics
+set angles degree
+set key bmargin center horizontal
+unset border
+
+# Load data and setup
+load \"%s\"
+
+# General settings
+DataColCount = words($Data[1])-1
+AxesCount = |$Data|-HeaderLines-1
+AngleOffset = 90
+Max = 1
+d=0.1*Max
+Direction = -1 # counterclockwise=1, clockwise = -1
+
+# Tic settings
+TicCount = %s
+TicOffset = 0.1
+TicValue(axis,i) = real(i)*(word($Settings[axis],3)-word($Settings[axis],2)) \\
+ / word($Settings[axis],4)+word($Settings[axis],2)
+TicLabelPosX(axis,i) = PosX(axis,i/TicCount) + PosY(axis, TicOffset)
+TicLabelPosY(axis,i) = PosY(axis,i/TicCount) - PosX(axis, TicOffset)
+TicLen = 0.03
+TicdX(axis,i) = 0.5*TicLen*cos(alpha(axis)-90)
+TicdY(axis,i) = 0.5*TicLen*sin(alpha(axis)-90)
+
+# Label
+LabOffset = 0.10
+LabX(axis) = PosX(axis+1,Max+2*d) + PosY(axis, LabOffset)
+LabY(axis) = PosY($0+1,Max+2*d)
+
+# Functions
+alpha(axis) = (axis-1)*Direction*360.0/AxesCount+AngleOffset
+PosX(axis,R) = R*cos(alpha(axis))
+PosY(axis,R) = R*sin(alpha(axis))
+Scale(axis,value) = real(value-word($Settings[axis],2))/(word($Settings[axis],3)-word($Settings[axis],2))
+
+# Spider settings
+set style arrow 1 dt 1 lw 1.0 @fgal head filled size 0.06,25 # style for axes
+set style arrow 2 dt 2 lw 0.5 @fgal nohead # style for weblines
+set style arrow 3 dt 1 lw 1 @fgal nohead # style for axis tics
+set samples AxesCount
+set isosamples TicCount
+set urange[1:AxesCount]
+set vrange[1:TicCount]
+set style fill transparent solid 0.2
+
+set xrange[-Max-4*d:Max+4*d]
+set yrange[-Max-4*d:Max+4*d]
+plot \\
+ '+' u (0):(0):(PosX($0,Max+d)):(PosY($0,Max+d)) w vec as 1 not, \\
+ $Data u (LabX($0)): \\
+ (LabY($0)):1 every ::HeaderLines w labels center enhanced @fgt not, \\
+ for [i=1:DataColCount] $Data u (PosX($0+1,Scale($0+1,column(i+1)))): \\
+ (PosY($0+1,Scale($0+1,column(i+1)))) every ::HeaderLines w filledcurves lt i title word($Data[1],i+1), \\
+%s
+# '++' u (PosX($1,$2/TicCount)-TicdX($1,$2/TicCount)): \\
+# (PosY($1,$2/TicCount)-TicdY($1,$2/TicCount)): \\
+# (2*TicdX($1,$2/TicCount)):(2*TicdY($1,$2/TicCount)) \\
+# w vec as 3 not, \\
+### end of code
+")
+
+(defvar org--plot/radar-ticks
+ " '++' u (PosX($1,$2/TicCount)):(PosY($1,$2/TicCount)): \\
+ (PosX($1+1,$2/TicCount)-PosX($1,$2/TicCount)): \\
+ (PosY($1+1,$2/TicCount)-PosY($1,$2/TicCount)) w vec as 2 not, \\
+ '++' u (TicLabelPosX(%s,$2)):(TicLabelPosY(%s,$2)): \\
+ (sprintf('%%g',TicValue(%s,$2))) w labels font ',8' @fgat not")
+
+(defvar org--plot/radar-setup-template
+ "# Data
+$Data <<HEREHAVESOMEDATA
+%s
+HEREHAVESOMEDATA
+HeaderLines = 1
+
+# Settings for scale and offset adjustments
+# axis min max tics axisLabelXoff axisLabelYoff
+$Settings <<EOD
+%s
+EOD
+")
+
+(defun org--plot/radar (table params)
+ "Create gnuplot code for a radar plot of TABLE with PARAMS."
+ (let* ((data
+ (concat "\"" (mapconcat #'identity (plist-get params :labels) "\" \"") "\""
+ "\n"
+ (mapconcat (lambda (row)
+ (format
+ "\"%s\" %s"
+ (car row)
+ (mapconcat #'identity (cdr row) " ")))
+ (append table (list (car table)))
+ "\n")))
+ (ticks (or (plist-get params :ticks)
+ (org--plot/sensible-tick-num table
+ (plist-get params :ymin)
+ (plist-get params :ymax))))
+ (settings
+ (mapconcat (lambda (row)
+ (let ((data (org--plot/values-stats
+ (mapcar #'string-to-number (cdr row)))))
+ (format
+ "\"%s\" %s %s %s"
+ (car row)
+ (or (plist-get params :ymin)
+ (plist-get data :nice-min))
+ (or (plist-get params :ymax)
+ (plist-get data :nice-max))
+ (if (eq ticks 0) 2 ticks)
+ )))
+ (append table (list (car table)))
+ "\n"))
+ (setup-file (make-temp-file "org-plot-setup")))
+ (let ((coding-system-for-write 'utf-8))
+ (write-region (format org--plot/radar-setup-template data settings) nil setup-file nil :silent))
+ (format org--plot/radar-template
+ setup-file
+ (if (eq ticks 0) 2 ticks)
+ (if (eq ticks 0) ""
+ (apply #'format org--plot/radar-ticks
+ (make-list 3 (if (and (plist-get params :ymin)
+ (plist-get params :ymax))
+ ;; FIXME multi-drawing of tick labels with "1"
+ "1" "$1")))))))
+
+(defcustom org-plot/gnuplot-term-extra ""
+ "String or function which provides the extra term options.
+E.g. a value of \"size 1050,650\" would cause
+\"set term ... size 1050,650\" to be used.
+If a function, it is called with the plot type as the argument."
+ :group 'org-plot
+ :type '(choice string function))
+
+(defun org-plot/gnuplot-script (table data-file num-cols params &optional preface)
+ "Write a gnuplot script for TABLE to DATA-FILE respecting options in PARAMS.
NUM-COLS controls the number of columns plotted in a 2-d plot.
Optional argument PREFACE returns only option parameters in a
manner suitable for prepending to a user-specified script."
- (let* ((type (plist-get params :plot-type))
- (with (if (eq type 'grid) 'pm3d (plist-get params :with)))
- (sets (plist-get params :set))
- (lines (plist-get params :line))
- (map (plist-get params :map))
- (title (plist-get params :title))
- (file (plist-get params :file))
- (ind (plist-get params :ind))
- (time-ind (plist-get params :timeind))
- (timefmt (plist-get params :timefmt))
- (text-ind (plist-get params :textind))
- (deps (if (plist-member params :deps) (plist-get params :deps)))
- (col-labels (plist-get params :labels))
- (x-labels (plist-get params :xlabels))
- (y-labels (plist-get params :ylabels))
- (plot-str "'%s' using %s%d%s with %s title '%s'")
- (plot-cmd (pcase type
- (`2d "plot")
- (`3d "splot")
- (`grid "splot")))
- (script "reset")
- ;; ats = add-to-script
- (ats (lambda (line) (setf script (concat script "\n" line))))
- plot-lines)
- (when file ; output file
- (funcall ats (format "set term %s" (file-name-extension file)))
- (funcall ats (format "set output '%s'" file)))
- (pcase type ; type
- (`2d ())
- (`3d (when map (funcall ats "set map")))
- (`grid (funcall ats (if map "set pm3d map" "set pm3d"))))
- (when title (funcall ats (format "set title '%s'" title))) ; title
- (mapc ats lines) ; line
- (dolist (el sets) (funcall ats (format "set %s" el))) ; set
- ;; Unless specified otherwise, values are TAB separated.
- (unless (string-match-p "^set datafile separator" script)
- (funcall ats "set datafile separator \"\\t\""))
- (when x-labels ; x labels (xtics)
- (funcall ats
- (format "set xtics (%s)"
- (mapconcat (lambda (pair)
- (format "\"%s\" %d" (cdr pair) (car pair)))
- x-labels ", "))))
- (when y-labels ; y labels (ytics)
- (funcall ats
- (format "set ytics (%s)"
- (mapconcat (lambda (pair)
- (format "\"%s\" %d" (cdr pair) (car pair)))
- y-labels ", "))))
- (when time-ind ; timestamp index
- (funcall ats "set xdata time")
- (funcall ats (concat "set timefmt \""
- (or timefmt ; timefmt passed to gnuplot
- "%Y-%m-%d-%H:%M:%S") "\"")))
- (unless preface
- (pcase type ; plot command
- (`2d (dotimes (col num-cols)
- (unless (and (eq type '2d)
- (or (and ind (equal (1+ col) ind))
- (and deps (not (member (1+ col) deps)))))
- (setf plot-lines
- (cons
- (format plot-str data-file
- (or (and ind (> ind 0)
- (not text-ind)
- (format "%d:" ind)) "")
- (1+ col)
- (if text-ind (format ":xticlabel(%d)" ind) "")
- with
- (or (nth col col-labels)
- (format "%d" (1+ col))))
- plot-lines)))))
- (`3d
- (setq plot-lines (list (format "'%s' matrix with %s title ''"
- data-file with))))
- (`grid
- (setq plot-lines (list (format "'%s' with %s title ''"
- data-file with)))))
+ (let* ((type-name (plist-get params :plot-type))
+ (type (cdr (assoc type-name org-plot/preset-plot-types))))
+ (unless type
+ (user-error "Org-plot type `%s' is undefined" type-name))
+ (let* ((sets (plist-get params :set))
+ (lines (plist-get params :line))
+ (title (plist-get params :title))
+ (file (plist-get params :file))
+ (time-ind (plist-get params :timeind))
+ (timefmt (plist-get params :timefmt))
+ (x-labels (plist-get params :xlabels))
+ (y-labels (plist-get params :ylabels))
+ (plot-str (or (plist-get type :plot-str)
+ "'%s' using %s%d%s with %s title '%s'"))
+ (plot-cmd (plist-get type :plot-cmd))
+ (plot-pre (plist-get type :plot-pre))
+ (script "reset")
+ ;; ats = add-to-script
+ (ats (lambda (line) (when line (setf script (concat script "\n" line)))))
+ plot-lines)
+
+
+ ;; handle output file, background, and size
+ (funcall ats (format "set term %s %s"
+ (if file (file-name-extension file) "GNUTERM")
+ (if (stringp org-plot/gnuplot-term-extra)
+ org-plot/gnuplot-term-extra
+ (funcall org-plot/gnuplot-term-extra type))))
+ (when file ; output file
+ (funcall ats (format "set output '%s'" (expand-file-name file))))
+
+ (when plot-pre
+ (funcall ats (funcall plot-pre table data-file num-cols params plot-str)))
+
(funcall ats
- (concat plot-cmd " " (mapconcat #'identity
- (reverse plot-lines)
- ",\\\n "))))
- script))
+ (if (stringp org-plot/gnuplot-script-preamble)
+ org-plot/gnuplot-script-preamble
+ (funcall org-plot/gnuplot-script-preamble type)))
+
+ (when title (funcall ats (format "set title '%s'" title))) ; title
+ (mapc ats lines) ; line
+ (dolist (el sets) (funcall ats (format "set %s" el))) ; set
+ ;; Unless specified otherwise, values are TAB separated.
+ (unless (string-match-p "^set datafile separator" script)
+ (funcall ats "set datafile separator \"\\t\""))
+ (when x-labels ; x labels (xtics)
+ (funcall ats
+ (format "set xtics (%s)"
+ (mapconcat (lambda (pair)
+ (format "\"%s\" %d" (cdr pair) (car pair)))
+ x-labels ", "))))
+ (when y-labels ; y labels (ytics)
+ (funcall ats
+ (format "set ytics (%s)"
+ (mapconcat (lambda (pair)
+ (format "\"%s\" %d" (cdr pair) (car pair)))
+ y-labels ", "))))
+ (when time-ind ; timestamp index
+ (funcall ats "set xdata time")
+ (funcall ats (concat "set timefmt \""
+ (or timefmt ; timefmt passed to gnuplot
+ "%Y-%m-%d-%H:%M:%S") "\"")))
+ (unless preface
+ (let ((type-func (plist-get type :plot-func)))
+ (when type-func
+ (setq plot-lines
+ (funcall type-func table data-file num-cols params plot-str))))
+ (funcall ats
+ (concat plot-cmd
+ (when plot-cmd " ")
+ (mapconcat #'identity
+ (reverse plot-lines)
+ ",\\\n "))))
+ script)))
+
+(defun org-plot/redisplay-img-in-buffer (img-file)
+ "Find any overlays for IMG-FILE in the current Org buffer, and refresh them."
+ (dolist (img-overlay org-inline-image-overlays)
+ (when (string= img-file (plist-get (cdr (overlay-get img-overlay 'display)) :file))
+ (when (file-exists-p img-file)
+ (image-refresh (overlay-get img-overlay 'display))))))
;;-----------------------------------------------------------------------------
;; facade functions
@@ -283,15 +638,40 @@ line directly before or after the table."
(when (get-buffer "*gnuplot*") ; reset *gnuplot* if it already running
(with-current-buffer "*gnuplot*"
(goto-char (point-max))))
- (org-plot/goto-nearest-table)
- ;; Set default options.
- (dolist (pair org-plot/gnuplot-default-options)
- (unless (plist-member params (car pair))
- (setf params (plist-put params (car pair) (cdr pair)))))
+ (save-excursion
+ (org-plot/goto-nearest-table)
+ ;; Set default options.
+ (dolist (pair org-plot/gnuplot-default-options)
+ (unless (plist-member params (car pair))
+ (setf params (plist-put params (car pair) (cdr pair)))))
+ ;; Collect options.
+ (while (and (equal 0 (forward-line -1))
+ (looking-at "[[:space:]]*#\\+"))
+ (setf params (org-plot/collect-options params))))
;; collect table and table information
(let* ((data-file (make-temp-file "org-plot"))
- (table (org-table-collapse-header (org-table-to-lisp)))
- (num-cols (length (car table))))
+ (table (let ((tbl (save-excursion
+ (org-plot/goto-nearest-table)
+ (org-table-to-lisp))))
+ (when (pcase (plist-get params :transpose)
+ (`y t)
+ (`yes t)
+ (`t t))
+ (if (not (memq 'hline tbl))
+ (setq tbl (apply #'cl-mapcar #'list tbl))
+ ;; When present, remove hlines as they can't (currentily) be easily transposed.
+ (setq tbl (apply #'cl-mapcar #'list
+ (remove 'hline tbl)))
+ (push 'hline (cdr tbl))))
+ tbl))
+ (num-cols (length (if (eq (nth 0 table) 'hline) (nth 1 table)
+ (nth 0 table))))
+ (type (assoc (plist-get params :plot-type)
+ org-plot/preset-plot-types)))
+
+ (unless type
+ (user-error "Org-plot type `%s' is undefined" (plist-get params :plot-type)))
+
(run-with-idle-timer 0.1 nil #'delete-file data-file)
(when (eq (cadr table) 'hline)
(setf params
@@ -301,15 +681,12 @@ line directly before or after the table."
(save-excursion (while (and (equal 0 (forward-line -1))
(looking-at "[[:space:]]*#\\+"))
(setf params (org-plot/collect-options params))))
- ;; Dump table to datafile (very different for grid).
- (pcase (plist-get params :plot-type)
- (`2d (org-plot/gnuplot-to-data table data-file params))
- (`3d (org-plot/gnuplot-to-data table data-file params))
- (`grid (let ((y-labels (org-plot/gnuplot-to-grid-data
- table data-file params)))
- (when y-labels (plist-put params :ylabels y-labels)))))
+ ;; Dump table to datafile
+ (if-let ((dump-func (plist-get type :data-dump)))
+ (funcall dump-func table data-file num-cols params)
+ (org-plot/gnuplot-to-data table data-file params))
;; Check type of ind column (timestamp? text?)
- (when (eq `2d (plist-get params :plot-type))
+ (when (plist-get params :check-ind-type)
(let* ((ind (1- (plist-get params :ind)))
(ind-column (mapcar (lambda (row) (nth ind row)) table)))
(cond ((< ind 0) nil) ; ind is implicit
@@ -326,18 +703,23 @@ line directly before or after the table."
(with-temp-buffer
(if (plist-get params :script) ; user script
(progn (insert
- (org-plot/gnuplot-script data-file num-cols params t))
- (insert "\n")
- (insert-file-contents (plist-get params :script))
- (goto-char (point-min))
- (while (re-search-forward "\\$datafile" nil t)
- (replace-match data-file nil nil)))
- (insert (org-plot/gnuplot-script data-file num-cols params)))
+ (org-plot/gnuplot-script table data-file num-cols params t))
+ (insert "\n")
+ (insert-file-contents (plist-get params :script))
+ (goto-char (point-min))
+ (while (re-search-forward "\\$datafile" nil t)
+ (replace-match data-file nil nil)))
+ (insert (org-plot/gnuplot-script table data-file num-cols params)))
;; Graph table.
(gnuplot-mode)
- (gnuplot-send-buffer-to-gnuplot))
+ (condition-case nil
+ (gnuplot-send-buffer-to-gnuplot)
+ (buffer-read-only nil)))
;; Cleanup.
- (bury-buffer (get-buffer "*gnuplot*")))))
+ (bury-buffer (get-buffer "*gnuplot*"))
+ ;; Refresh any displayed images
+ (when (plist-get params :file)
+ (org-plot/redisplay-img-in-buffer (expand-file-name (plist-get params :file)))))))
(provide 'org-plot)
diff --git a/lisp/org/org-protocol.el b/lisp/org/org-protocol.el
index 726c1ca2bae..ca3249dda5e 100644
--- a/lisp/org/org-protocol.el
+++ b/lisp/org/org-protocol.el
@@ -49,7 +49,7 @@
;; 4.) Try this from the command line (adjust the URL as needed):
;;
;; $ emacsclient \
-;; org-protocol://store-link?url=http:%2F%2Flocalhost%2Findex.html&title=The%20title
+;; "org-protocol://store-link?url=http:%2F%2Flocalhost%2Findex.html&title=The%20title"
;;
;; 5.) Optionally add custom sub-protocols and handlers:
;;
@@ -94,6 +94,15 @@
;; You may use the same bookmark URL for all those standard handlers and just
;; adjust the sub-protocol used:
;;
+;; javascript:location.href='org-protocol://sub-protocol?'+
+;; new URLSearchParams({
+;; url: location.href,
+;; title: document.title,
+;; body: window.getSelection()})
+;;
+;; Alternatively use the following expression that encodes space as \"%20\"
+;; instead of \"+\", so it is compatible with Org versions from 9.0 to 9.4:
+;;
;; location.href='org-protocol://sub-protocol?url='+
;; encodeURIComponent(location.href)+'&title='+
;; encodeURIComponent(document.title)+'&body='+
@@ -103,6 +112,11 @@
;; char that, if present, triggers the use of a special template.
;; Example:
;;
+;; location.href='org-protocol://capture?'+
+;; new URLSearchParams({template:'x', /* ... */})
+;;
+;; or
+;;
;; location.href='org-protocol://capture?template=x'+ ...
;;
;; uses template ?x.
@@ -176,13 +190,13 @@ Possible properties are:
:online-suffix - the suffix to strip from the published URLs
:working-suffix - the replacement for online-suffix
- :base-url - the base URL, e.g. http://www.example.com/project/
+ :base-url - the base URL, e.g. https://www.example.com/project/
Last slash required.
- :working-directory - the local working directory. This is, what base-url will
- be replaced with.
- :redirects - A list of cons cells, each of which maps a regular
- expression to match to a path relative to
- :working-directory.
+ :working-directory - the local working directory. This is what
+ base-url will be replaced with.
+ :redirects - A list of cons cells, each of which maps a
+ regular expression to match to a path relative
+ to `:working-directory'.
Example:
@@ -216,8 +230,9 @@ Example:
does not include any suffix properties, allowing local source
file to be opened as found by OpenGrok.
-Consider using the interactive functions `org-protocol-create' and
-`org-protocol-create-for-org' to help you filling this variable with valid contents."
+Consider using the interactive functions `org-protocol-create'
+and `org-protocol-create-for-org' to help you filling this
+variable with valid contents."
:group 'org-protocol
:type 'alist)
@@ -426,7 +441,12 @@ Parameters: url, title (optional), body (optional)
Old-style links such as org-protocol://store-link://URL/TITLE are
also recognized.
-The location for a browser's bookmark has to look like this:
+The location for a browser's bookmark may look like this:
+
+ javascript:location.href = \\='org-protocol://store-link?\\=' +
+ new URLSearchParams({url:location.href, title:document.title});
+
+or to keep compatibility with Org versions from 9.0 to 9.4 it may be:
javascript:location.href = \\
\\='org-protocol://store-link?url=\\=' + \\
@@ -435,7 +455,9 @@ The location for a browser's bookmark has to look like this:
Don't use `escape()'! Use `encodeURIComponent()' instead. The
title of the page could contain slashes and the location
-definitely will.
+definitely will. Org 9.4 and earlier could not decode \"+\"
+to space, that is why less readable latter expression may be necessary
+for backward compatibility.
The sub-protocol used to reach this function is set in
`org-protocol-protocol-alist'.
@@ -463,8 +485,16 @@ The sub-protocol used to reach this function is set in
This function detects an URL, title and optional text, separated
by `/'. The location for a browser's bookmark looks like this:
+ javascript:location.href = \\='org-protocol://capture?\\=' +
+ new URLSearchParams({
+ url: location.href,
+ title: document.title,
+ body: window.getSelection()})
+
+or to keep compatibility with Org versions from 9.0 to 9.4:
+
javascript:location.href = \\='org-protocol://capture?url=\\='+ \\
- encodeURIComponent(location.href) + \\='&title=\\=' \\
+ encodeURIComponent(location.href) + \\='&title=\\=' + \\
encodeURIComponent(document.title) + \\='&body=\\=' + \\
encodeURIComponent(window.getSelection())
@@ -518,10 +548,11 @@ Now template ?b will be used."
(defun org-protocol-convert-query-to-plist (query)
"Convert QUERY key=value pairs in the URL to a property list."
(when query
- (apply 'append (mapcar (lambda (x)
- (let ((c (split-string x "=")))
- (list (intern (concat ":" (car c))) (cadr c))))
- (split-string query "&")))))
+ (let ((plus-decoded (replace-regexp-in-string "\\+" " " query t t)))
+ (apply 'append (mapcar (lambda (x)
+ (let ((c (split-string x "=")))
+ (list (intern (concat ":" (car c))) (cadr c))))
+ (split-string plus-decoded "&"))))))
(defun org-protocol-open-source (fname)
"Process an org-protocol://open-source?url= style URL with FNAME.
@@ -531,6 +562,12 @@ in `org-protocol-project-alist'.
The location for a browser's bookmark should look like this:
+ javascript:location.href = \\='org-protocol://open-source?\\=' +
+ new URLSearchParams({url: location.href})
+
+or if you prefer to keep compatibility with older Org versions (9.0 to 9.4),
+consider the following expression:
+
javascript:location.href = \\='org-protocol://open-source?url=\\=' + \\
encodeURIComponent(location.href)"
;; As we enter this function for a match on our protocol, the return value
@@ -553,7 +590,7 @@ The location for a browser's bookmark should look like this:
(f1 (substring f 0 (string-match "\\([\\?#].*\\)?$" f)))
(start-pos (+ (string-match wsearch f1) (length base-url)))
(end-pos (if strip-suffix
- (string-match (regexp-quote strip-suffix) f1)
+ (string-match (regexp-quote strip-suffix) f1)
(length f1)))
;; We have to compare redirects without suffix below:
(f2 (concat wdir (substring f1 start-pos end-pos)))
@@ -631,7 +668,7 @@ CLIENT is ignored."
(greedy (plist-get (cdr prolist) :greedy))
(split (split-string fname proto))
(result (if greedy restoffiles (cadr split)))
- (new-style (string-match "/*?" (match-string 1 fname))))
+ (new-style (not (= ?: (aref (match-string 1 fname) 0)))))
(when (plist-get (cdr prolist) :kill-client)
(message "Greedy org-protocol handler. Killing client.")
(server-edit))
diff --git a/lisp/org/org-refile.el b/lisp/org/org-refile.el
index 8b42f817c1a..73eaad6bf52 100644
--- a/lisp/org/org-refile.el
+++ b/lisp/org/org-refile.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2010-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;;
;; This file is part of GNU Emacs.
@@ -214,7 +214,7 @@ converted to a headline before refiling."
org-org-menu
'("Edit Structure") i))
'(["Refile Subtree" org-refile (org-in-subtree-not-table-p)]
- ["Refile and copy Subtree" org-copy (org-in-subtree-not-table-p)]))
+ ["Refile and copy Subtree" org-refile-copy (org-in-subtree-not-table-p)]))
(defun org-refile-marker (pos)
"Get a new refile marker, but only if caching is in use."
@@ -310,11 +310,13 @@ converted to a headline before refiling."
(setq f (buffer-file-name (buffer-base-buffer f))))
(setq f (and f (expand-file-name f)))
(when (eq org-refile-use-outline-path 'file)
- (push (list (file-name-nondirectory f) f nil nil) tgs))
+ (push (list (and f (file-name-nondirectory f)) f nil nil) tgs))
(when (eq org-refile-use-outline-path 'buffer-name)
(push (list (buffer-name (buffer-base-buffer)) f nil nil) tgs))
(when (eq org-refile-use-outline-path 'full-file-path)
- (push (list (file-truename (buffer-file-name (buffer-base-buffer))) f nil nil) tgs))
+ (push (list (and (buffer-file-name (buffer-base-buffer))
+ (file-truename (buffer-file-name (buffer-base-buffer))))
+ f nil nil) tgs))
(org-with-wide-buffer
(goto-char (point-min))
(setq org-outline-path-cache nil)
@@ -337,9 +339,10 @@ converted to a headline before refiling."
#'identity
(append
(pcase org-refile-use-outline-path
- (`file (list (file-name-nondirectory
- (buffer-file-name
- (buffer-base-buffer)))))
+ (`file (list
+ (and (buffer-file-name (buffer-base-buffer))
+ (file-name-nondirectory
+ (buffer-file-name (buffer-base-buffer))))))
(`full-file-path
(list (buffer-file-name
(buffer-base-buffer))))
@@ -373,8 +376,6 @@ the *old* location.")
(defvar org-refile-keep nil
"Non-nil means `org-refile' will copy instead of refile.")
-(define-obsolete-function-alias 'org-copy 'org-refile-copy "Org 9.4")
-
;;;###autoload
(defun org-refile-copy ()
"Like `org-refile', but preserve the refiled subtree."
@@ -382,8 +383,19 @@ the *old* location.")
(let ((org-refile-keep t))
(org-refile nil nil nil "Copy")))
+;;;###autoload
+(defun org-refile-reverse (&optional arg default-buffer rfloc msg)
+ "Refile while temporarily toggling `org-reverse-note-order'.
+So if `org-refile' would append the entry as the last entry under
+the target heading, `org-refile-reverse' will prepend it as the
+first entry, and vice-versa."
+ (interactive "P")
+ (let ((org-reverse-note-order (not (org-notes-order-reversed-p))))
+ (org-refile arg default-buffer rfloc msg)))
+
(defvar org-capture-last-stored-marker)
+
;;;###autoload
(defun org-refile (&optional arg default-buffer rfloc msg)
"Move the entry or entries at point to another heading.
@@ -426,7 +438,7 @@ needed when passing RFLOC
headline to refile under
MSG is a string to replace \"Refile\" in the default prompt with
-another verb. E.g. `org-copy' sets this parameter to \"Copy\".
+another verb. E.g. `org-refile-copy' sets this parameter to \"Copy\".
See also `org-refile-use-outline-path'.
@@ -628,29 +640,29 @@ this function appends the default value from
org-refile-target-table))
(completion-ignore-case t)
cdef
- (prompt (concat prompt
- (or (and (car org-refile-history)
- (concat " (default " (car org-refile-history) ")"))
- (and (assoc cbnex tbl) (setq cdef cbnex)
- (concat " (default " cbnex ")"))) ": "))
+ (prompt (let ((default (or (car org-refile-history)
+ (and (assoc cbnex tbl) (setq cdef cbnex)
+ cbnex))))
+ ;; `format-prompt' is new in Emacs 28.1.
+ (if (fboundp 'format-prompt)
+ (format-prompt prompt default)
+ (concat prompt " (default " default ": "))))
pa answ parent-target child parent old-hist)
(setq old-hist org-refile-history)
(setq answ (funcall cfunc prompt tbl nil (not new-nodes)
nil 'org-refile-history
- (or cdef (concat (car org-refile-history) extra))))
+ (or cdef (car org-refile-history))))
(if (setq pa (org-refile--get-location answ tbl))
- (let* ((last-refile-loc (car org-refile-history))
- (last-refile-loc-path (concat last-refile-loc extra)))
+ (let ((last-refile-loc (car org-refile-history)))
(org-refile-check-position pa)
(when (or (not org-refile-history)
(not (eq old-hist org-refile-history))
- (not (equal (car pa) last-refile-loc-path)))
+ (not (equal (car pa) last-refile-loc)))
(setq org-refile-history
(cons (car pa) (if (assoc last-refile-loc tbl)
org-refile-history
(cdr org-refile-history))))
- (when (or (equal last-refile-loc-path (nth 1 org-refile-history))
- (equal last-refile-loc (nth 1 org-refile-history)))
+ (when (equal last-refile-loc (nth 1 org-refile-history))
(pop org-refile-history)))
pa)
(if (string-match "\\`\\(.*\\)/\\([^/]+\\)\\'" answ)
diff --git a/lisp/org/org-src.el b/lisp/org/org-src.el
index cabedecb689..8d02cf43450 100644
--- a/lisp/org/org-src.el
+++ b/lisp/org/org-src.el
@@ -2,7 +2,7 @@
;;
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
;;
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Bastien Guerry <bzg@gnu.org>
;; Dan Davison <davison at stats dot ox dot ac dot uk>
;; Keywords: outlines, hypermedia, calendar, wp
@@ -38,6 +38,7 @@
(require 'org-keys)
(declare-function org-mode "org" ())
+(declare-function org--get-expected-indentation "org" (element contentsp))
(declare-function org-element-at-point "org-element" ())
(declare-function org-element-class "org-element" (datum &optional parent))
(declare-function org-element-context "org-element" (&optional element))
@@ -299,6 +300,9 @@ is 0.")
"File name associated to Org source buffer, or nil.")
(put 'org-src-source-file-name 'permanent-local t)
+(defvar-local org-src--preserve-blank-line nil)
+(put 'org-src--preserve-blank-line 'permanent-local t)
+
(defun org-src--construct-edit-buffer-name (org-buffer-name lang)
"Construct the buffer name for a source editing buffer."
(concat "*Org Src " org-buffer-name "[ " lang " ]*"))
@@ -324,11 +328,11 @@ a cons cell (LINE . COLUMN) or symbol `end'. See also
(if (>= pos end) 'end
(org-with-wide-buffer
(goto-char (max beg pos))
- (cons (count-lines beg (line-beginning-position))
+ (cons (count-lines (save-excursion (goto-char beg) (line-beginning-position))
+ (line-beginning-position))
;; Column is relative to the end of line to avoid problems of
;; comma escaping or colons appended in front of the line.
- (- (current-column)
- (progn (end-of-line) (current-column)))))))
+ (- (point) (min end (line-end-position)))))))
(defun org-src--goto-coordinates (coord beg end)
"Move to coordinates COORD relatively to BEG and END.
@@ -341,9 +345,9 @@ which see. BEG and END are buffer positions."
(org-with-wide-buffer
(goto-char beg)
(forward-line (car coord))
- (end-of-line)
- (org-move-to-column (max (+ (current-column) (cdr coord)) 0))
- (point)))))
+ (max (point)
+ (+ (min end (line-end-position))
+ (cdr coord)))))))
(defun org-src--contents-area (datum)
"Return contents boundaries of DATUM.
@@ -433,8 +437,8 @@ spaces after it as being outside."
(line-end-position)
(point))))))
-(defun org-src--contents-for-write-back ()
- "Return buffer contents in a format appropriate for write back.
+(defun org-src--contents-for-write-back (write-back-buf)
+ "Populate WRITE-BACK-BUF with contents in the appropriate format.
Assume point is in the corresponding edit buffer."
(let ((indentation-offset
(if org-src--preserve-indentation 0
@@ -443,28 +447,39 @@ Assume point is in the corresponding edit buffer."
org-src--content-indentation
0))))
(use-tabs? (and (> org-src--tab-width 0) t))
+ (preserve-fl (eq org-src--source-type 'latex-fragment))
(source-tab-width org-src--tab-width)
- (contents (org-with-wide-buffer (buffer-string)))
- (write-back org-src--allow-write-back))
- (with-temp-buffer
+ (contents (org-with-wide-buffer
+ (let ((eol (line-end-position)))
+ (list (buffer-substring (point-min) eol)
+ (buffer-substring eol (point-max))))))
+ (write-back org-src--allow-write-back)
+ (preserve-blank-line org-src--preserve-blank-line)
+ marker)
+ (with-current-buffer write-back-buf
;; Reproduce indentation parameters from source buffer.
(setq indent-tabs-mode use-tabs?)
(when (> source-tab-width 0) (setq tab-width source-tab-width))
;; Apply WRITE-BACK function on edit buffer contents.
- (insert (org-no-properties contents))
+ (insert (org-no-properties (car contents)))
+ (setq marker (point-marker))
+ (insert (org-no-properties (car (cdr contents))))
(goto-char (point-min))
(when (functionp write-back) (save-excursion (funcall write-back)))
- ;; Add INDENTATION-OFFSET to every non-empty line in buffer,
+ ;; Add INDENTATION-OFFSET to every line in buffer,
;; unless indentation is meant to be preserved.
(when (> indentation-offset 0)
- (while (not (eobp))
+ (when preserve-fl (forward-line))
+ (while (not (eobp))
(skip-chars-forward " \t")
- (unless (eolp) ;ignore blank lines
+ (when (or (not (eolp)) ; not a blank line
+ (and (eq (point) (marker-position marker)) ; current line
+ preserve-blank-line))
(let ((i (current-column)))
(delete-region (line-beginning-position) (point))
(indent-to (+ i indentation-offset))))
(forward-line)))
- (buffer-string))))
+ (set-marker marker nil))))
(defun org-src--edit-element
(datum name &optional initialize write-back contents remote)
@@ -507,8 +522,19 @@ Leave point in edit buffer."
(source-tab-width (if indent-tabs-mode tab-width 0))
(type (org-element-type datum))
(block-ind (org-with-point-at (org-element-property :begin datum)
- (current-indentation)))
+ (cond
+ ((save-excursion (skip-chars-backward " \t") (bolp))
+ (current-indentation))
+ ((org-element-property :parent datum)
+ (org--get-expected-indentation
+ (org-element-property :parent datum) nil))
+ (t (current-indentation)))))
(content-ind org-edit-src-content-indentation)
+ (blank-line (save-excursion (beginning-of-line)
+ (looking-at-p "^[[:space:]]*$")))
+ (empty-line (and blank-line (looking-at-p "^$")))
+ (preserve-blank-line (or (and blank-line (not empty-line))
+ (and empty-line (= (+ block-ind content-ind) 0))))
(preserve-ind
(and (memq type '(example-block src-block))
(or (org-element-property :preserve-indent datum)
@@ -532,7 +558,8 @@ Leave point in edit buffer."
(insert contents)
(remove-text-properties (point-min) (point-max)
'(display nil invisible nil intangible nil))
- (unless preserve-ind (org-do-remove-indentation))
+ (let ((lf (eq type 'latex-fragment)))
+ (unless preserve-ind (org-do-remove-indentation (and lf block-ind) lf)))
(set-buffer-modified-p nil)
(setq buffer-file-name nil)
;; Initialize buffer.
@@ -557,6 +584,7 @@ Leave point in edit buffer."
(setq org-src--overlay overlay)
(setq org-src--allow-write-back write-back)
(setq org-src-source-file-name source-file-name)
+ (setq org-src--preserve-blank-line preserve-blank-line)
;; Start minor mode.
(org-src-mode)
;; Clear undo information so we cannot undo back to the
@@ -587,7 +615,7 @@ Leave point in edit buffer."
(defun org-src-font-lock-fontify-block (lang start end)
"Fontify code block.
-This function is called by emacs automatic fontification, as long
+This function is called by Emacs' automatic fontification, as long
as `org-src-fontify-natively' is non-nil."
(let ((lang-mode (org-src-get-lang-mode lang)))
(when (fboundp lang-mode)
@@ -1190,20 +1218,27 @@ Throw an error if there is no such buffer."
(interactive)
(unless (org-src-edit-buffer-p) (user-error "Not in a sub-editing buffer"))
(set-buffer-modified-p nil)
- (let ((edited-code (org-src--contents-for-write-back))
+ (let ((write-back-buf (generate-new-buffer "*org-src-write-back*"))
(beg org-src--beg-marker)
(end org-src--end-marker)
(overlay org-src--overlay))
+ (org-src--contents-for-write-back write-back-buf)
(with-current-buffer (org-src-source-buffer)
(undo-boundary)
(goto-char beg)
;; Temporarily disable read-only features of OVERLAY in order to
;; insert new contents.
(delete-overlay overlay)
- (delete-region beg end)
(let ((expecting-bol (bolp)))
- (insert edited-code)
+ (if (version< emacs-version "27.1")
+ (progn (delete-region beg end)
+ (insert (with-current-buffer write-back-buf (buffer-string))))
+ (save-restriction
+ (narrow-to-region beg end)
+ (replace-buffer-contents write-back-buf 0.1 nil)
+ (goto-char (point-max))))
(when (and expecting-bol (not (bolp))) (insert "\n")))
+ (kill-buffer write-back-buf)
(save-buffer)
(move-overlay overlay beg (point))))
;; `write-contents-functions' requires the function to return
@@ -1213,30 +1248,45 @@ Throw an error if there is no such buffer."
(defun org-edit-src-exit ()
"Kill current sub-editing buffer and return to source buffer."
(interactive)
- (unless (org-src-edit-buffer-p) (error "Not in a sub-editing buffer"))
+ (unless (org-src-edit-buffer-p)
+ (error "Not in a sub-editing buffer"))
(let* ((beg org-src--beg-marker)
(end org-src--end-marker)
(write-back org-src--allow-write-back)
(remote org-src--remote)
(coordinates (and (not remote)
(org-src--coordinates (point) 1 (point-max))))
- (code (and write-back (org-src--contents-for-write-back))))
+ (write-back-buf
+ (and write-back (generate-new-buffer "*org-src-write-back*"))))
+ (when write-back (org-src--contents-for-write-back write-back-buf))
(set-buffer-modified-p nil)
;; Switch to source buffer. Kill sub-editing buffer.
(let ((edit-buffer (current-buffer))
(source-buffer (marker-buffer beg)))
- (unless source-buffer (error "Source buffer disappeared. Aborting"))
+ (unless source-buffer
+ (when write-back-buf (kill-buffer write-back-buf))
+ (error "Source buffer disappeared. Aborting"))
(org-src-switch-to-buffer source-buffer 'exit)
(kill-buffer edit-buffer))
;; Insert modified code. Ensure it ends with a newline character.
(org-with-wide-buffer
- (when (and write-back (not (equal (buffer-substring beg end) code)))
+ (when (and write-back
+ (not (equal (buffer-substring beg end)
+ (with-current-buffer write-back-buf
+ (buffer-string)))))
(undo-boundary)
(goto-char beg)
- (delete-region beg end)
(let ((expecting-bol (bolp)))
- (insert code)
+ (if (version< emacs-version "27.1")
+ (progn (delete-region beg end)
+ (insert (with-current-buffer write-back-buf
+ (buffer-string))))
+ (save-restriction
+ (narrow-to-region beg end)
+ (replace-buffer-contents write-back-buf 0.1 nil)
+ (goto-char (point-max))))
(when (and expecting-bol (not (bolp))) (insert "\n")))))
+ (when write-back-buf (kill-buffer write-back-buf))
;; If we are to return to source buffer, put point at an
;; appropriate location. In particular, if block is hidden, move
;; to the beginning of the block opening line.
diff --git a/lisp/org/org-table.el b/lisp/org/org-table.el
index 0e93fb271f3..a6dd8bff20f 100644
--- a/lisp/org/org-table.el
+++ b/lisp/org/org-table.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
@@ -66,6 +66,7 @@
(declare-function org-export-install-filters "ox" (info))
(declare-function org-export-table-has-special-column-p "ox" (table))
(declare-function org-export-table-row-is-special-p "ox" (table-row info))
+(declare-function org-forward-paragraph "org" (&optional arg))
(declare-function org-id-find "org-id" (id &optional markerp))
(declare-function org-indent-line "org" ())
(declare-function org-load-modules-maybe "org" (&optional force))
@@ -331,7 +332,7 @@ relies on the variables to be present in the list."
The default value is `hours', and will output the results as a
number of hours. Other allowed values are `seconds', `minutes' and
`days', and the output will be a fraction of seconds, minutes or
-days. `hh:mm' selects to use hours and minutes, ignoring seconds.
+days. `hh:mm' selects to use hours and minutes, ignoring seconds.
The `U' flag in a table formula will select this specific format for
a single formula."
:group 'org-table-calculation
@@ -461,36 +462,41 @@ This may be useful when columns have been shrunk."
(when pos (goto-char pos))
(goto-char (line-beginning-position))
(let ((end (line-end-position)) str)
+ (backward-char)
(while (progn (forward-char 1) (< (point) end))
(let ((ov (car (overlays-at (point)))))
(if (not ov)
(push (char-to-string (char-after)) str)
(push (overlay-get ov 'display) str)
(goto-char (1- (overlay-end ov))))))
- (format "|%s" (mapconcat #'identity (reverse str) "")))))
+ (format "%s" (mapconcat #'identity (reverse str) "")))))
(defvar-local org-table-header-overlay nil)
(defun org-table-header-set-header ()
"Display the header of the table at point."
- (when (overlayp org-table-header-overlay)
- (delete-overlay org-table-header-overlay))
- (let* ((ws (window-start))
- (beg (save-excursion
- (goto-char (org-table-begin))
- (while (or (org-at-table-hline-p)
- (looking-at-p ".*|\\s-+<[rcl]?\\([0-9]+\\)?>"))
- (move-beginning-of-line 2))
- (point)))
- (end (save-excursion (goto-char beg) (point-at-eol))))
- (if (pos-visible-in-window-p beg)
- (when (overlayp org-table-header-overlay)
- (delete-overlay org-table-header-overlay))
- (setq org-table-header-overlay
- (make-overlay ws (+ ws (- end beg))))
- (org-overlay-display
- org-table-header-overlay
- (org-table-row-get-visible-string beg)
- 'org-table-header))))
+ (let ((gcol temporary-goal-column))
+ (unwind-protect
+ (progn
+ (when (overlayp org-table-header-overlay)
+ (delete-overlay org-table-header-overlay))
+ (let* ((ws (window-start))
+ (beg (save-excursion
+ (goto-char (org-table-begin))
+ (while (or (org-at-table-hline-p)
+ (looking-at-p ".*|\\s-+<[rcl]?\\([0-9]+\\)?>"))
+ (move-beginning-of-line 2))
+ (line-beginning-position)))
+ (end (save-excursion (goto-char beg) (point-at-eol))))
+ (if (pos-visible-in-window-p beg)
+ (when (overlayp org-table-header-overlay)
+ (delete-overlay org-table-header-overlay))
+ (setq org-table-header-overlay
+ (make-overlay ws (+ ws (- end beg))))
+ (org-overlay-display
+ org-table-header-overlay
+ (org-table-row-get-visible-string beg)
+ 'org-table-header))))
+ (setq temporary-goal-column gcol))))
;;;###autoload
(define-minor-mode org-table-header-line-mode
@@ -679,8 +685,6 @@ Will be filled automatically during use.")
("_" . "Names for values in row below this one.")
("^" . "Names for values in row above this one.")))
-(defvar org-tbl-calc-modes nil)
-
(defvar org-pos nil)
@@ -724,18 +728,6 @@ Field is restored even in case of abnormal exit."
(org-table-goto-column ,column)
(set-marker ,line nil)))))
-(defsubst org-table--set-calc-mode (var &optional value)
- (if (stringp var)
- (setq var (assoc var '(("D" calc-angle-mode deg)
- ("R" calc-angle-mode rad)
- ("F" calc-prefer-frac t)
- ("S" calc-symbolic-mode t)))
- value (nth 2 var) var (nth 1 var)))
- (if (memq var org-tbl-calc-modes)
- (setcar (cdr (memq var org-tbl-calc-modes)) value)
- (cons var (cons value org-tbl-calc-modes)))
- org-tbl-calc-modes)
-
;;; Predicates
@@ -870,52 +862,52 @@ nil When nil, the command tries to be smart and figure out the
(let* ((beg (min beg0 end0))
(end (max beg0 end0))
re)
- (if (> (count-lines beg end) org-table-convert-region-max-lines)
- (user-error "Region is longer than `org-table-convert-region-max-lines' (%s) lines; not converting"
- org-table-convert-region-max-lines)
- (when (equal separator '(64))
- (setq separator (read-regexp "Regexp for field separator")))
- (goto-char beg)
- (beginning-of-line 1)
- (setq beg (point-marker))
- (goto-char end)
- (if (bolp) (backward-char 1) (end-of-line 1))
- (setq end (point-marker))
- ;; Get the right field separator
- (unless separator
- (goto-char beg)
- (setq separator
- (cond
- ((not (re-search-forward "^[^\n\t]+$" end t)) '(16))
- ((not (re-search-forward "^[^\n,]+$" end t)) '(4))
- (t 1))))
+ (when (> (count-lines beg end) org-table-convert-region-max-lines)
+ (user-error "Region is longer than `org-table-convert-region-max-lines' (%s) lines; not converting"
+ org-table-convert-region-max-lines))
+ (when (equal separator '(64))
+ (setq separator (read-regexp "Regexp for field separator")))
+ (goto-char beg)
+ (beginning-of-line 1)
+ (setq beg (point-marker))
+ (goto-char end)
+ (if (bolp) (backward-char 1) (end-of-line 1))
+ (setq end (point-marker))
+ ;; Get the right field separator
+ (unless separator
(goto-char beg)
- (if (equal separator '(4))
- (while (< (point) end)
- ;; parse the csv stuff
+ (setq separator
(cond
- ((looking-at "^") (insert "| "))
- ((looking-at "[ \t]*$") (replace-match " |") (beginning-of-line 2))
- ((looking-at "[ \t]*\"\\([^\"\n]*\\)\"")
- (replace-match "\\1")
- (if (looking-at "\"") (insert "\"")))
- ((looking-at "[^,\n]+") (goto-char (match-end 0)))
- ((looking-at "[ \t]*,") (replace-match " | "))
- (t (beginning-of-line 2))))
- (setq re (cond
- ((equal separator '(4)) "^\\|\"?[ \t]*,[ \t]*\"?")
- ((equal separator '(16)) "^\\|\t")
- ((integerp separator)
- (if (< separator 1)
- (user-error "Number of spaces in separator must be >= 1")
- (format "^ *\\| *\t *\\| \\{%d,\\}" separator)))
- ((stringp separator)
- (format "^ *\\|%s" separator))
- (t (error "This should not happen"))))
- (while (re-search-forward re end t)
- (replace-match "| " t t)))
- (goto-char beg)
- (org-table-align))))
+ ((not (re-search-forward "^[^\n\t]+$" end t)) '(16))
+ ((not (re-search-forward "^[^\n,]+$" end t)) '(4))
+ (t 1))))
+ (goto-char beg)
+ (if (equal separator '(4))
+ (while (< (point) end)
+ ;; parse the csv stuff
+ (cond
+ ((looking-at "^") (insert "| "))
+ ((looking-at "[ \t]*$") (replace-match " |") (beginning-of-line 2))
+ ((looking-at "[ \t]*\"\\([^\"\n]*\\)\"")
+ (replace-match "\\1")
+ (if (looking-at "\"") (insert "\"")))
+ ((looking-at "[^,\n]+") (goto-char (match-end 0)))
+ ((looking-at "[ \t]*,") (replace-match " | "))
+ (t (beginning-of-line 2))))
+ (setq re (cond
+ ((equal separator '(4)) "^\\|\"?[ \t]*,[ \t]*\"?")
+ ((equal separator '(16)) "^\\|\t")
+ ((integerp separator)
+ (if (< separator 1)
+ (user-error "Number of spaces in separator must be >= 1")
+ (format "^ *\\| *\t *\\| \\{%d,\\}" separator)))
+ ((stringp separator)
+ (format "^ *\\|%s" separator))
+ (t (error "This should not happen"))))
+ (while (re-search-forward re end t)
+ (replace-match "| " t t)))
+ (goto-char beg)
+ (org-table-align)))
;;;###autoload
(defun org-table-import (file separator)
@@ -938,7 +930,8 @@ lines. It can have the following values:
- regexp When a regular expression, use it to match the separator."
(interactive "f\nP")
(when (and (called-interactively-p 'any)
- (not (string-match-p (rx "." (or "txt" "tsv" "csv") eos) file)))
+ (not (string-match-p (rx "." (or "txt" "tsv" "csv") eos) file))
+ (not (yes-or-no-p "The file's extension is not .txt, .tsv or .csv. Import? ")))
(user-error "Cannot import such file"))
(unless (bolp) (insert "\n"))
(let ((beg (point))
@@ -1936,8 +1929,9 @@ of lists of fields."
(forward-line))
(set-marker end nil))
(when cut (org-table-align))
- (message (substitute-command-keys "Cells in the region copied, use \
-\\[org-table-paste-rectangle] to paste them in a table."))
+ (when (called-interactively-p 'any)
+ (message (substitute-command-keys "Cells in the region copied, use \
+\\[org-table-paste-rectangle] to paste them in a table.")))
(setq org-table-clip (nreverse region))))
;;;###autoload
@@ -2168,7 +2162,7 @@ LOCATION instead."
(goto-char (match-beginning 3))
(delete-region (match-beginning 3) (match-end 0)))
(org-indent-line)
- (insert (or (match-string 2) "#+TBLFM:")))
+ (insert "#+TBLFM:"))
(insert " "
(mapconcat (lambda (x) (concat (car x) "=" (cdr x)))
(sort alist #'org-table-formula-less-p)
@@ -2436,51 +2430,45 @@ location of point."
equation
(org-table-get-formula equation (equal arg '(4)))))
(n0 (org-table-current-column))
- (org-tbl-calc-modes (copy-sequence org-calc-default-modes))
+ (calc-modes (copy-sequence org-calc-default-modes))
(numbers nil) ; was a variable, now fixed default
(keep-empty nil)
- n form form0 formrpl formrg bw fmt x ev orig c lispp literal
+ form form0 formrpl formrg bw fmt ev orig lispp literal
duration duration-output-format)
;; Parse the format string. Since we have a lot of modes, this is
;; a lot of work. However, I think calc still uses most of the time.
- (if (string-match ";" formula)
- (let ((tmp (org-split-string formula ";")))
- (setq formula (car tmp)
- fmt (concat (cdr (assoc "%" org-table-local-parameters))
- (nth 1 tmp)))
+ (if (string-match "\\(.*\\);\\(.*\\)" formula)
+ (progn
+ (setq fmt (concat (cdr (assoc "%" org-table-local-parameters))
+ (match-string-no-properties 2 formula)))
+ (setq formula (match-string-no-properties 1 formula))
(while (string-match "\\([pnfse]\\)\\(-?[0-9]+\\)" fmt)
- (setq c (string-to-char (match-string 1 fmt))
- n (string-to-number (match-string 2 fmt)))
- (if (= c ?p)
- (setq org-tbl-calc-modes
- (org-table--set-calc-mode 'calc-internal-prec n))
- (setq org-tbl-calc-modes
- (org-table--set-calc-mode
- 'calc-float-format
- (list (cdr (assoc c '((?n . float) (?f . fix)
- (?s . sci) (?e . eng))))
- n))))
+ (let ((c (string-to-char (match-string 1 fmt)))
+ (n (string-to-number (match-string 2 fmt))))
+ (cl-case c
+ (?p (setf (cl-getf calc-modes 'calc-internal-prec) n))
+ (?n (setf (cl-getf calc-modes 'calc-float-format) (list 'float n)))
+ (?f (setf (cl-getf calc-modes 'calc-float-format) (list 'fix n)))
+ (?s (setf (cl-getf calc-modes 'calc-float-format) (list 'sci n)))
+ (?e (setf (cl-getf calc-modes 'calc-float-format) (list 'eng n)))))
+ ;; Remove matched flags from the mode string.
(setq fmt (replace-match "" t t fmt)))
- (if (string-match "[tTU]" fmt)
- (let ((ff (match-string 0 fmt)))
- (setq duration t numbers t
- duration-output-format
- (cond ((equal ff "T") nil)
- ((equal ff "t") org-table-duration-custom-format)
- ((equal ff "U") 'hh:mm))
- fmt (replace-match "" t t fmt))))
- (if (string-match "N" fmt)
- (setq numbers t
- fmt (replace-match "" t t fmt)))
- (if (string-match "L" fmt)
- (setq literal t
- fmt (replace-match "" t t fmt)))
- (if (string-match "E" fmt)
- (setq keep-empty t
- fmt (replace-match "" t t fmt)))
- (while (string-match "[DRFS]" fmt)
- (setq org-tbl-calc-modes
- (org-table--set-calc-mode (match-string 0 fmt)))
+ (while (string-match "\\([tTUNLEDRFSu]\\)" fmt)
+ (let ((c (string-to-char (match-string 1 fmt))))
+ (cl-case c
+ (?t (setq duration t numbers t
+ duration-output-format org-table-duration-custom-format))
+ (?T (setq duration t numbers t duration-output-format nil))
+ (?U (setq duration t numbers t duration-output-format 'hh:mm))
+ (?N (setq numbers t))
+ (?L (setq literal t))
+ (?E (setq keep-empty t))
+ (?D (setf (cl-getf calc-modes 'calc-angle-mode) 'deg))
+ (?R (setf (cl-getf calc-modes 'calc-angle-mode) 'rad))
+ (?F (setf (cl-getf calc-modes 'calc-prefer-frac) t))
+ (?S (setf (cl-getf calc-modes 'calc-symbolic-mode) t))
+ (?u (setf (cl-getf calc-modes 'calc-simplify-mode) 'units))))
+ ;; Remove matched flags from the mode string.
(setq fmt (replace-match "" t t fmt)))
(unless (string-match "\\S-" fmt)
(setq fmt nil))))
@@ -2582,17 +2570,17 @@ location of point."
(setq form0 form)
;; Insert the references to fields in same row
(while (string-match "\\$\\(\\([-+]\\)?[0-9]+\\)" form)
- (setq n (+ (string-to-number (match-string 1 form))
- (if (match-end 2) n0 0))
- x (nth (1- (if (= n 0) n0 (max n 1))) fields)
- formrpl (save-match-data
- (org-table-make-reference
- x keep-empty numbers lispp)))
- (when (or (not x)
- (save-match-data
- (string-match (regexp-quote formula) formrpl)))
- (user-error "Invalid field specifier \"%s\""
- (match-string 0 form)))
+ (let* ((n (+ (string-to-number (match-string 1 form))
+ (if (match-end 2) n0 0)))
+ (x (nth (1- (if (= n 0) n0 (max n 1))) fields)))
+ (setq formrpl (save-match-data
+ (org-table-make-reference
+ x keep-empty numbers lispp)))
+ (when (or (not x)
+ (save-match-data
+ (string-match (regexp-quote formula) formrpl)))
+ (user-error "Invalid field specifier \"%s\""
+ (match-string 0 form))))
(setq form (replace-match formrpl t t form)))
(if lispp
@@ -2618,13 +2606,13 @@ location of point."
(format-time-string
(org-time-stamp-format
(string-match-p "[0-9]\\{1,2\\}:[0-9]\\{2\\}" ts))
- (apply #'encode-time
+ (encode-time
(save-match-data (org-parse-time-string ts))))))
form t t))
(setq ev (if (and duration (string-match "^[0-9]+:[0-9]+\\(?::[0-9]+\\)?$" form))
form
- (calc-eval (cons form org-tbl-calc-modes)
+ (calc-eval (cons form calc-modes)
(when (and (not keep-empty) numbers) 'num)))
ev (if duration (org-table-time-seconds-to-string
(if (string-match "^[0-9]+:[0-9]+\\(?::[0-9]+\\)?$" ev)
@@ -3280,7 +3268,7 @@ Parameters get priority."
(org-defkey map "\C-c}" 'org-table-fedit-toggle-coordinates)
map))
-(easy-menu-define org-table-fedit-menu org-table-fedit-map "Org Edit Formulas Menu"
+(easy-menu-define org-table-fedit-menu org-table-fedit-map "Org Edit Formulas Menu."
'("Edit-Formulas"
["Finish and Install" org-table-fedit-finish t]
["Finish, Install, and Apply" (org-table-fedit-finish t) :keys "C-u C-c C-c"]
@@ -4448,7 +4436,7 @@ Optional argument NEW may specify text to replace the current field content."
(col (org-table-current-column)))
(when (> col 0)
(skip-chars-backward "^|")
- (if (not (looking-at " *\\([^|\n]*?\\) *\\(|\\|$\\)"))
+ (if (not (looking-at " *\\(?:\\([^|\n]*?\\) *\\(|\\)\\|\\([^|\n]+?\\) *\\($\\)\\)"))
(setq org-table-may-need-update t)
(let* ((align (nth (1- col) org-table-last-alignment))
(width (nth (1- col) org-table-last-column-widths))
@@ -4674,19 +4662,24 @@ blank, and the content is appended to the field above."
(if (org-region-active-p)
;; There is a region: fill as a paragraph.
(let ((start (region-beginning)))
- (org-table-cut-region (region-beginning) (region-end))
- (when (> (length (car org-table-clip)) 1)
- (user-error "Region must be limited to single column"))
- (let ((nlines (cond ((not arg) (length org-table-clip))
- ((< arg 1) (+ (length org-table-clip) arg))
- (t arg))))
- (setq org-table-clip
- (mapcar #'list
- (org-wrap (mapconcat #'car org-table-clip " ")
- nil
- nlines))))
- (goto-char start)
- (org-table-paste-rectangle))
+ (save-restriction
+ (narrow-to-region
+ (save-excursion (goto-char start) (move-beginning-of-line 1))
+ (save-excursion (org-forward-paragraph) (point)))
+ (org-table-cut-region (region-beginning) (region-end))
+ (when (> (length (car org-table-clip)) 1)
+ (user-error "Region must be limited to single column"))
+ (let ((nlines (cond ((not arg) (length org-table-clip))
+ ((< arg 1) (+ (length org-table-clip) arg))
+ (t arg))))
+ (setq org-table-clip
+ (mapcar #'list
+ (org-wrap (mapconcat #'car org-table-clip " ")
+ nil
+ nlines))))
+ (goto-char start)
+ (org-table-paste-rectangle))
+ (org-table-align))
;; No region, split the current field at point.
(unless (org-get-alist-option org-M-RET-may-split-line 'table)
(skip-chars-forward "^\r\n|"))
@@ -5084,7 +5077,7 @@ When LOCAL is non-nil, show references for the table at point."
(put 'orgtbl-mode :included t)
(put 'orgtbl-mode :menu-tag "Org Table Mode")
-(easy-menu-define orgtbl-mode-menu orgtbl-mode-map "OrgTbl menu"
+(easy-menu-define orgtbl-mode-menu orgtbl-mode-map "OrgTbl menu."
'("OrgTbl"
["Create or convert" org-table-create-or-convert-from-region
:active (not (org-at-table-p)) :keys "C-c |" ]
@@ -5334,7 +5327,7 @@ With prefix arg, also recompute table."
(defun orgtbl-create-or-convert-from-region (_arg)
"Create table or convert region to table, if no conflicting binding.
This installs the table binding `C-c |', but only if there is no
-conflicting binding to this key outside orgtbl-mode."
+conflicting binding to this key outside `orgtbl-mode'."
(interactive "P")
(let* (orgtbl-mode (cmd (key-binding "\C-c|")))
(if cmd
@@ -5573,7 +5566,7 @@ First element has index 0, or I0 if given."
;;;###autoload
(defun orgtbl-to-generic (table params)
- "Convert the orgtbl-mode TABLE to some other format.
+ "Convert the `orgtbl-mode' TABLE to some other format.
This generic routine can be used for many standard cases.
@@ -5960,12 +5953,12 @@ information."
;;;###autoload
(defun orgtbl-to-tsv (table params)
- "Convert the orgtbl-mode table to TAB separated material."
+ "Convert the `orgtbl-mode' TABLE to TAB separated material."
(orgtbl-to-generic table (org-combine-plists '(:sep "\t") params)))
;;;###autoload
(defun orgtbl-to-csv (table params)
- "Convert the orgtbl-mode table to CSV material.
+ "Convert the `orgtbl-mode' TABLE to CSV material.
This does take care of the proper quoting of fields with comma or quotes."
(orgtbl-to-generic table
(org-combine-plists '(:sep "," :fmt org-quote-csv-field)
@@ -5973,7 +5966,7 @@ This does take care of the proper quoting of fields with comma or quotes."
;;;###autoload
(defun orgtbl-to-latex (table params)
- "Convert the orgtbl-mode TABLE to LaTeX.
+ "Convert the `orgtbl-mode' TABLE to LaTeX.
TABLE is a list, each entry either the symbol `hline' for
a horizontal separator line, or a list of fields for that line.
@@ -6006,7 +5999,7 @@ supported. It is also possible to use the following ones:
;;;###autoload
(defun orgtbl-to-html (table params)
- "Convert the orgtbl-mode TABLE to HTML.
+ "Convert the `orgtbl-mode' TABLE to HTML.
TABLE is a list, each entry either the symbol `hline' for
a horizontal separator line, or a list of fields for that line.
@@ -6037,7 +6030,7 @@ supported. It is also possible to use the following one:
;;;###autoload
(defun orgtbl-to-texinfo (table params)
- "Convert the orgtbl-mode TABLE to Texinfo.
+ "Convert the `orgtbl-mode' TABLE to Texinfo.
TABLE is a list, each entry either the symbol `hline' for
a horizontal separator line, or a list of fields for that line.
@@ -6068,7 +6061,7 @@ supported. It is also possible to use the following one:
;;;###autoload
(defun orgtbl-to-orgtbl (table params)
- "Convert the orgtbl-mode TABLE into another orgtbl-mode table.
+ "Convert the `orgtbl-mode' TABLE into another orgtbl-mode table.
TABLE is a list, each entry either the symbol `hline' for
a horizontal separator line, or a list of fields for that line.
@@ -6083,7 +6076,7 @@ be set to provide ORGTBL directives for the generated table."
(orgtbl-to-generic table (org-combine-plists params (list :backend 'org))))
(defun orgtbl-to-table.el (table params)
- "Convert the orgtbl-mode TABLE into a table.el table.
+ "Convert the `orgtbl-mode' TABLE into a table.el table.
TABLE is a list, each entry either the symbol `hline' for
a horizontal separator line, or a list of fields for that line.
PARAMS is a property list of parameters that can influence the
@@ -6097,7 +6090,7 @@ supported."
(replace-regexp-in-string "|-" "+-" (buffer-substring 1 (buffer-size))))))
(defun orgtbl-to-unicode (table params)
- "Convert the orgtbl-mode TABLE into a table with unicode characters.
+ "Convert the `orgtbl-mode' TABLE into a table with unicode characters.
TABLE is a list, each entry either the symbol `hline' for
a horizontal separator line, or a list of fields for that line.
@@ -6109,7 +6102,7 @@ supported. It is also possible to use the following ones:
When non-nil, use \"ascii-art-to-unicode\" package to translate
the table. You can download it here:
- http://gnuvola.org/software/j/aa2u/ascii-art-to-unicode.el.
+ https://gnuvola.org/software/j/aa2u/ascii-art-to-unicode.el.
:narrow
@@ -6214,7 +6207,7 @@ which will prompt for the width."
(defun orgtbl-uc-draw-grid (value min max &optional width)
"Draw a bar in a table using block unicode characters.
-It is a variant of orgtbl-ascii-draw with Unicode block
+It is a variant of `orgtbl-ascii-draw' with Unicode block
characters, for a smooth display. Bars appear as grids (to the
extent the font allows)."
;; https://en.wikipedia.org/wiki/Block_Elements
@@ -6224,7 +6217,7 @@ extent the font allows)."
(defun orgtbl-uc-draw-cont (value min max &optional width)
"Draw a bar in a table using block unicode characters.
-It is a variant of orgtbl-ascii-draw with Unicode block
+It is a variant of `orgtbl-ascii-draw' with Unicode block
characters, for a smooth display. Bars are solid (to the extent
the font allows)."
(orgtbl-ascii-draw value min max width
diff --git a/lisp/org/org-timer.el b/lisp/org/org-timer.el
index 852d18579a4..bfcea443c3b 100644
--- a/lisp/org/org-timer.el
+++ b/lisp/org/org-timer.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2008-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
;;
@@ -400,16 +400,16 @@ prompt the user if she wants to replace it.
Called with a numeric prefix argument, use this numeric value as
the duration of the timer in minutes.
-Called with a `C-u' prefix arguments, use `org-timer-default-timer'
+Called with a \\[universal-argument] prefix arguments, use `org-timer-default-timer'
without prompting the user for a duration.
-With two `C-u' prefix arguments, use `org-timer-default-timer'
+With two \\[universal-argument] prefix arguments, use `org-timer-default-timer'
without prompting the user for a duration and automatically
replace any running timer.
By default, the timer duration will be set to the number of
minutes in the Effort property, if any. You can ignore this by
-using three `C-u' prefix arguments."
+using three \\[universal-argument] prefix arguments."
(interactive "P")
(when (and org-timer-start-time
(not org-timer-countdown-timer))
diff --git a/lisp/org/org-version.el b/lisp/org/org-version.el
index 8871ef798d5..b009b9691fd 100644
--- a/lisp/org/org-version.el
+++ b/lisp/org/org-version.el
@@ -5,13 +5,13 @@
(defun org-release ()
"The release version of Org.
Inserted by installing Org mode or when a release is made."
- (let ((org-release "9.4.4"))
+ (let ((org-release "9.5.1"))
org-release))
;;;###autoload
(defun org-git-version ()
"The Git version of Org mode.
Inserted by installing Org or when a release is made."
- (let ((org-git-version "release_9.4.4"))
+ (let ((org-git-version "release_9.5.1-25-g9ca3bc"))
org-git-version))
(provide 'org-version)
diff --git a/lisp/org/org.el b/lisp/org/org.el
index f560c65dc4f..253a9efa27c 100644
--- a/lisp/org/org.el
+++ b/lisp/org/org.el
@@ -3,12 +3,13 @@
;; Carstens outline-mode for keeping track of everything.
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
;;
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Maintainer: Bastien Guerry <bzg@gnu.org>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
+;; Package-Requires: ((emacs "25.1"))
-;; Version: 9.4.4
+;; Version: 9.5.1
;; This file is part of GNU Emacs.
;;
@@ -93,6 +94,8 @@
(require 'org-compat)
(require 'org-keys)
(require 'ol)
+(require 'oc)
+(require 'oc-basic)
(require 'org-table)
;; `org-outline-regexp' ought to be a defconst but is let-bound in
@@ -144,7 +147,6 @@ Stars are put in group 1 and the trimmed body in group 2.")
(declare-function org-clock-timestamps-down "org-clock" (&optional n))
(declare-function org-clock-timestamps-up "org-clock" (&optional n))
(declare-function org-clock-update-time-maybe "org-clock" ())
-(declare-function org-clocking-buffer "org-clock" ())
(declare-function org-clocktable-shift "org-clock" (dir n))
(declare-function org-columns-quit "org-colview" ())
(declare-function org-columns-insert-dblock "org-colview" ())
@@ -157,13 +159,18 @@ Stars are put in group 1 and the trimmed body in group 2.")
(declare-function org-element-context "org-element" (&optional element))
(declare-function org-element-copy "org-element" (datum))
(declare-function org-element-create "org-element" (type &optional props &rest children))
+(declare-function org-element-extract-element "org-element" (element))
+(declare-function org-element-insert-before "org-element" (element location))
(declare-function org-element-interpret-data "org-element" (data))
(declare-function org-element-lineage "org-element" (blob &optional types with-self))
(declare-function org-element-link-parser "org-element" ())
+(declare-function org-element-map "org-element" (data types fun &optional info first-match no-recursion with-affiliated))
(declare-function org-element-nested-p "org-element" (elem-a elem-b))
(declare-function org-element-parse-buffer "org-element" (&optional granularity visible-only))
+(declare-function org-element-parse-secondary-string "org-element" (string restriction &optional parent))
(declare-function org-element-property "org-element" (property element))
(declare-function org-element-put-property "org-element" (element property value))
+(declare-function org-element-restriction "org-element" (element))
(declare-function org-element-swap-A-B "org-element" (elem-a elem-b))
(declare-function org-element-timestamp-parser "org-element" ())
(declare-function org-element-type "org-element" (element))
@@ -191,7 +198,6 @@ Stars are put in group 1 and the trimmed body in group 2.")
(declare-function org-toggle-archive-tag "org-archive" (&optional find-done))
(declare-function org-update-radio-target-regexp "ol" ())
-(defvar ffap-url-regexp)
(defvar org-element-paragraph-separate)
(defvar org-indent-indentation-per-level)
(defvar org-radio-target-regexp)
@@ -202,6 +208,8 @@ Stars are put in group 1 and the trimmed body in group 2.")
;; load languages based on value of `org-babel-load-languages'
(defvar org-babel-load-languages)
+(defvar crm-separator) ; dynamically scoped param
+
;;;###autoload
(defun org-babel-do-load-languages (sym value)
"Load the languages defined in `org-babel-load-languages'."
@@ -230,7 +238,11 @@ byte-compiled before it is loaded."
tangled-file
(file-attribute-modification-time
(file-attributes (file-truename file))))
- (org-babel-tangle-file file tangled-file "emacs-lisp\\|elisp"))
+ (org-babel-tangle-file file
+ tangled-file
+ (rx string-start
+ (or "emacs-lisp" "elisp")
+ string-end)))
(if compile
(progn
(byte-compile-file tangled-file)
@@ -263,32 +275,25 @@ requirement."
(const :tag "Awk" awk)
(const :tag "C" C)
(const :tag "R" R)
- (const :tag "Asymptote" asymptote)
- (const :tag "Calc" calc)
+ (const :tag "Calc" calc)
(const :tag "Clojure" clojure)
(const :tag "CSS" css)
(const :tag "Ditaa" ditaa)
(const :tag "Dot" dot)
- (const :tag "Ebnf2ps" ebnf2ps)
- (const :tag "Emacs Lisp" emacs-lisp)
+ (const :tag "Emacs Lisp" emacs-lisp)
(const :tag "Forth" forth)
(const :tag "Fortran" fortran)
(const :tag "Gnuplot" gnuplot)
(const :tag "Haskell" haskell)
- (const :tag "hledger" hledger)
- (const :tag "IO" io)
- (const :tag "J" J)
- (const :tag "Java" java)
+ (const :tag "Java" java)
(const :tag "Javascript" js)
(const :tag "LaTeX" latex)
- (const :tag "Ledger" ledger)
- (const :tag "Lilypond" lilypond)
+ (const :tag "Lilypond" lilypond)
(const :tag "Lisp" lisp)
(const :tag "Makefile" makefile)
(const :tag "Maxima" maxima)
(const :tag "Matlab" matlab)
- (const :tag "Mscgen" mscgen)
- (const :tag "Ocaml" ocaml)
+ (const :tag "Ocaml" ocaml)
(const :tag "Octave" octave)
(const :tag "Org" org)
(const :tag "Perl" perl)
@@ -301,11 +306,9 @@ requirement."
(const :tag "Scheme" scheme)
(const :tag "Screen" screen)
(const :tag "Shell Script" shell)
- (const :tag "Shen" shen)
- (const :tag "Sql" sql)
+ (const :tag "Sql" sql)
(const :tag "Sqlite" sqlite)
- (const :tag "Stan" stan)
- (const :tag "Vala" vala))
+ (const :tag "Stan" stan))
:value-type (boolean :tag "Activate" :value t)))
;;;; Customization variables
@@ -654,6 +657,10 @@ defined in org-duration.el.")
:group 'org
:type 'hook)
+(make-obsolete-variable
+ 'org-load-hook
+ "use `with-eval-after-load' instead." "9.5")
+
(defcustom org-log-buffer-setup-hook nil
"Hook that is run after an Org log buffer is created."
:group 'org
@@ -680,15 +687,16 @@ defined in org-duration.el.")
(org-load-modules-maybe 'force)
(org-element-cache-reset 'all)))
-(defcustom org-modules '(ol-w3m ol-bbdb ol-bibtex ol-docview ol-gnus ol-info ol-irc ol-mhe ol-rmail ol-eww)
+(defcustom org-modules '(ol-doi ol-w3m ol-bbdb ol-bibtex ol-docview ol-gnus ol-info ol-irc ol-mhe ol-rmail ol-eww)
"Modules that should always be loaded together with org.el.
-If a description starts with <C>, the file is not part of Emacs
-and loading it will require that you have downloaded and properly
-installed the Org mode distribution.
+If a description starts with <C>, the file is not part of Emacs and Org mode,
+so loading it will require that you have properly installed org-contrib
+package from NonGNU Emacs Lisp Package Archive
+https://elpa.nongnu.org/nongnu/org-contrib.html
You can also use this system to load external packages (i.e. neither Org
-core modules, nor modules from the CONTRIB directory). Just add symbols
+core modules, nor org-contrib modules). Just add symbols
to the end of the list. If the package is called org-xyz.el, then you need
to add the symbol `xyz', and the package must have a call to:
@@ -697,8 +705,7 @@ to add the symbol `xyz', and the package must have a call to:
For export specific modules, see also `org-export-backends'."
:group 'org
:set 'org-set-modules
- :version "26.1"
- :package-version '(Org . "9.2")
+ :package-version '(Org . "9.5")
:type
'(set :greedy t
(const :tag " bbdb: Links to BBDB entries" ol-bbdb)
@@ -706,6 +713,7 @@ For export specific modules, see also `org-export-backends'."
(const :tag " crypt: Encryption of subtrees" org-crypt)
(const :tag " ctags: Access to Emacs tags with links" org-ctags)
(const :tag " docview: Links to Docview buffers" ol-docview)
+ (const :tag " doi: Links to DOI references" ol-doi)
(const :tag " eww: Store link to URL of Eww" ol-eww)
(const :tag " gnus: Links to GNUS folders/messages" ol-gnus)
(const :tag " habit: Track your consistency with habits" org-habit)
@@ -762,9 +770,10 @@ For export specific modules, see also `org-export-backends'."
(defcustom org-export-backends '(ascii html icalendar latex odt)
"List of export back-ends that should be always available.
-If a description starts with <C>, the file is not part of Emacs
-and loading it will require that you have downloaded and properly
-installed the Org mode distribution.
+If a description starts with <C>, the file is not part of Emacs and Org mode,
+so loading it will require that you have properly installed org-contrib
+package from NonGNU Emacs Lisp Package Archive
+https://elpa.nongnu.org/nongnu/org-contrib.html
Unlike to `org-modules', libraries in this list will not be
loaded along with Org, but only once the export framework is
@@ -940,6 +949,7 @@ the following lines anywhere in the buffer:
#+STARTUP: fold (or `overview', this is equivalent)
#+STARTUP: nofold (or `showall', this is equivalent)
#+STARTUP: content
+ #+STARTUP: show<n>levels (<n> = 2..5)
#+STARTUP: showeverything
Set `org-agenda-inhibit-startup' to a non-nil value if you want
@@ -950,6 +960,10 @@ time."
:type '(choice
(const :tag "nofold: show all" nil)
(const :tag "fold: overview" t)
+ (const :tag "fold: show two levels" show2levels)
+ (const :tag "fold: show three levels" show3levels)
+ (const :tag "fold: show four levels" show4evels)
+ (const :tag "fold: show five levels" show5levels)
(const :tag "content: all headlines" content)
(const :tag "show everything, even drawers" showeverything)))
@@ -1194,6 +1208,8 @@ Allowed visibility spans are
ancestors show current headline and its direct ancestors; if
point is not on headline, also show entry
+ ancestors-full show current subtree and its direct ancestors
+
lineage show current headline, its direct ancestors and all
their children; if point is not on headline, also show
entry and first child
@@ -1235,6 +1251,7 @@ more context."
(const minimal)
(const local)
(const ancestors)
+ (const ancestors-full)
(const lineage)
(const tree)
(const canonical))))))
@@ -1575,14 +1592,13 @@ lines to the buffer:
:group 'org-appearance
:type 'boolean)
-(defcustom org-adapt-indentation t
+(defcustom org-adapt-indentation nil
"Non-nil means adapt indentation to outline node level.
-When this variable is set to t, Org assumes that you write
-outlines by indenting text in each node to align with the
-headline (after the stars).
+When set to t, Org assumes that you write outlines by indenting
+text in each node to align with the headline, after the stars.
-When this variable is set to 'headline-data, only adapt the
+When this variable is set to `headline-data', Org only adapts the
indentation of the data lines right below the headline, such as
planning/clock lines and property/logbook drawers.
@@ -1608,9 +1624,9 @@ time in Emacs."
:type '(choice
(const :tag "Adapt indentation for all lines" t)
(const :tag "Adapt indentation for headline data lines"
- 'headline-data)
+ headline-data)
(const :tag "Do not adapt indentation at all" nil))
- :safe #'booleanp)
+ :safe (lambda (x) (memq x '(t nil headline-data))))
(defvaralias 'org-special-ctrl-a 'org-special-ctrl-a/e)
@@ -2437,8 +2453,20 @@ set a priority."
(defcustom org-priority-highest ?A
"The highest priority of TODO items.
+
A character like ?A, ?B, etc., or a numeric value like 1, 2, etc.
-Must be smaller than `org-priority-lowest'."
+
+The default is the character ?A, which is 65 as a numeric value.
+
+If you set `org-priority-highest' to a numeric value inferior to
+65, Org assumes you want to use digits for the priority cookie.
+If you set it to >=65, Org assumes you want to use alphabetical
+characters.
+
+In both cases, the value of `org-priority-highest' must be
+smaller than `org-priority-lowest': for example, if \"A\" is the
+highest priority, it is smaller than the lowest \"C\" priority:
+65 < 67."
:group 'org-priorities
:type '(choice
(character :tag "Character")
@@ -2447,8 +2475,20 @@ Must be smaller than `org-priority-lowest'."
(defvaralias 'org-lowest-priority 'org-priority-lowest)
(defcustom org-priority-lowest ?C
"The lowest priority of TODO items.
-A character like ?A, ?B, etc., or a numeric value like 1, 2, etc.
-Must be higher than `org-priority-highest'."
+
+A character like ?C, ?B, etc., or a numeric value like 9, 8, etc.
+
+The default is the character ?C, which is 67 as a numeric value.
+
+If you set `org-priority-lowest' to a numeric value inferior to
+65, Org assumes you want to use digits for the priority cookie.
+If you set it to >=65, Org assumes you want to use alphabetical
+characters.
+
+In both cases, the value of `org-priority-lowest' must be greater
+than `org-priority-highest': for example, if \"C\" is the lowest
+priority, it is greater than the highest \"A\" priority: 67 >
+65."
:group 'org-priorities
:type '(choice
(character :tag "Character")
@@ -3113,7 +3153,7 @@ it in the document property drawer. For example:
:CATEGORY: ELisp
:END:
-Other ways to define it is as an emacs file variable, for example
+Other ways to define it is as an Emacs file variable, for example
# -*- mode: org; org-category: \"ELisp\"
@@ -3285,7 +3325,7 @@ All available processes and theirs documents can be found in
:image-output-type "png"
:image-size-adjust (1.0 . 1.0)
:latex-compiler ("latex -interaction nonstopmode -output-directory %o %f")
- :image-converter ("dvipng -D %D -T tight -o %O %f"))
+ :image-converter ("dvipng -D %D -T tight -bg Transparent -o %O %f"))
(dvisvgm
:programs ("latex" "dvisvgm")
:description "dvi > svg"
@@ -3428,13 +3468,11 @@ header, or they will be appended."
'(("AUTO" "inputenc" t ("pdflatex"))
("T1" "fontenc" t ("pdflatex"))
("" "graphicx" t)
- ("" "grffile" t)
("" "longtable" nil)
("" "wrapfig" nil)
("" "rotating" nil)
("normalem" "ulem" t)
("" "amsmath" t)
- ("" "textcomp" t)
("" "amssymb" t)
("" "capt-of" nil)
("" "hyperref" nil))
@@ -3448,15 +3486,14 @@ Org mode to function properly:
- inputenc, fontenc: for basic font and character selection
- graphicx: for including images
-- grffile: allow periods and spaces in graphics file names
- longtable: For multipage tables
- wrapfig: for figure placement
- rotating: for sideways figures and tables
- ulem: for underline and strike-through
- amsmath: for subscript and superscript and math environments
-- textcomp, amssymb: for various symbols used
- for interpreting the entities in `org-entities'. You can skip
- some of these packages if you don't use any of their symbols.
+- amssymb: for various symbols used for interpreting the entities
+ in `org-entities'. You can skip some of this package if you don't
+ use any of the symbols.
- capt-of: for captions outside of floats
- hyperref: for cross references
@@ -3570,10 +3607,11 @@ lines to the buffer:
For example, a value \\='(title) for this list makes the document's title
appear in the buffer without the initial \"#+TITLE:\" part."
:group 'org-appearance
- :version "24.1"
+ :package-version '(Org . "9.5")
:type '(set (const :tag "#+AUTHOR" author)
(const :tag "#+DATE" date)
(const :tag "#+EMAIL" email)
+ (const :tag "#+SUBTITLE" subtitle)
(const :tag "#+TITLE" title)))
(defcustom org-custom-properties nil
@@ -3593,7 +3631,7 @@ When this is non-nil, the headline after the keyword is set to the
:group 'org-appearance
:package-version '(Org . "9.4")
:type 'boolean
- :safe t)
+ :safe #'booleanp)
(defcustom org-fontify-done-headline t
"Non-nil means change the face of a headline if it is marked DONE.
@@ -3822,10 +3860,11 @@ This is needed for font-lock setup.")
"Marker recording the last clock-in, but the headline position.")
(defvar org-clock-heading ""
"The heading of the current clock entry.")
-(defun org-clock-is-active ()
+(defun org-clocking-buffer ()
"Return the buffer where the clock is currently running.
Return nil if no clock is running."
(marker-buffer org-clock-marker))
+(defalias 'org-clock-is-active #'org-clocking-buffer)
(defun org-check-running-clock ()
"Check if the current buffer contains the running clock.
@@ -4106,7 +4145,7 @@ groups carry important information:
(defconst org-stamp-time-of-day-regexp
(concat
"<\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} +\\sw+ +\\)"
- "\\([012][0-9]:[0-5][0-9]\\(-\\([012][0-9]:[0-5][0-9]\\)\\)?[^\n\r>]*?\\)>"
+ "\\([012][0-9]:[0-5][0-9]\\)\\(-\\([012][0-9]:[0-5][0-9]\\)\\)?[^\n\r>]*?>"
"\\(--?"
"<\\1\\([012][0-9]:[0-5][0-9]\\)>\\)?")
"Regular expression to match a timestamp time or time range.
@@ -4122,6 +4161,10 @@ After a match, the following groups carry important information:
("overview" org-startup-folded t)
("nofold" org-startup-folded nil)
("showall" org-startup-folded nil)
+ ("show2levels" org-startup-folded show2levels)
+ ("show3levels" org-startup-folded show3levels)
+ ("show4levels" org-startup-folded show4levels)
+ ("show5levels" org-startup-folded show5levels)
("showeverything" org-startup-folded showeverything)
("content" org-startup-folded content)
("indent" org-startup-indented t)
@@ -4498,7 +4541,7 @@ directory."
(when (and (org-string-nw-p value)
(not buffer-read-only)) ;FIXME: bug in Gnus?
(let* ((uri (org-strip-quotes value))
- (uri-is-url (org-file-url-p uri))
+ (uri-is-url (org-url-p uri))
(uri (if uri-is-url
uri
(expand-file-name uri))))
@@ -4628,11 +4671,6 @@ This is the cache of file URLs read using `org-file-contents'.")
"Reset the cache of files downloaded by `org-file-contents'."
(clrhash org--file-cache))
-(defun org-file-url-p (file)
- "Non-nil if FILE is a URL."
- (require 'ffap)
- (string-match-p ffap-url-regexp file))
-
(defun org-file-contents (file &optional noerror nocache)
"Return the contents of FILE, as a string.
@@ -4647,7 +4685,7 @@ from file or URL, and return nil.
If NOCACHE is non-nil, do a fresh fetch of FILE even if cached version
is available. This option applies only if FILE is a URL."
- (let* ((is-url (org-file-url-p file))
+ (let* ((is-url (org-url-p file))
(cache (and is-url
(not nocache)
(gethash file org--file-cache))))
@@ -4793,6 +4831,7 @@ The following commands are available:
(org-load-modules-maybe)
(org-install-agenda-files-menu)
(when org-link-descriptive (add-to-invisibility-spec '(org-link)))
+ (make-local-variable 'org-link-descriptive)
(add-to-invisibility-spec '(org-hide-block . t))
(setq-local outline-regexp org-outline-regexp)
(setq-local outline-level 'org-outline-level)
@@ -4903,6 +4942,18 @@ The following commands are available:
(when org-startup-numerated (require 'org-num) (org-num-mode 1))
(when org-startup-indented (require 'org-indent) (org-indent-mode 1))))
+ ;; Add a custom keymap for `visual-line-mode' so that activating
+ ;; this minor mode does not override Org's keybindings.
+ ;; FIXME: Probably `visual-line-mode' should take care of this.
+ (let ((oldmap (cdr (assoc 'visual-line-mode minor-mode-map-alist)))
+ (newmap (make-sparse-keymap)))
+ (set-keymap-parent newmap oldmap)
+ (define-key newmap [remap move-beginning-of-line] nil)
+ (define-key newmap [remap move-end-of-line] nil)
+ (define-key newmap [remap kill-line] nil)
+ (make-local-variable 'minor-mode-overriding-map-alist)
+ (push `(visual-line-mode . ,newmap) minor-mode-overriding-map-alist))
+
;; Activate `org-table-header-line-mode'
(when org-table-header-line-p
(org-table-header-line-mode 1))
@@ -4926,7 +4977,8 @@ The following commands are available:
("9.1" . "26.1")
("9.2" . "27.1")
("9.3" . "27.1")
- ("9.4" . "27.2")))
+ ("9.4" . "27.2")
+ ("9.5" . "28.1")))
(defvar org-mode-transpose-word-syntax-table
(let ((st (make-syntax-table text-mode-syntax-table)))
@@ -5059,9 +5111,10 @@ stacked delimiters is N. Escaping delimiters is not possible."
(when (and org-hide-emphasis-markers
(not (org-at-comment-p)))
(add-text-properties (match-end 4) (match-beginning 5)
- '(invisible org-link))
+ '(invisible t))
(add-text-properties (match-beginning 3) (match-end 3)
- '(invisible org-link)))
+ '(invisible t)))
+ (goto-char (match-end 0))
(throw :exit t))))))))
(defun org-emphasize (&optional char)
@@ -5143,30 +5196,31 @@ This includes angle, plain, and bracket links."
(link (org-element-property :raw-link link-object))
(type (org-element-property :type link-object))
(path (org-element-property :path link-object))
+ (face-property (pcase (org-link-get-parameter type :face)
+ ((and (pred functionp) face) (funcall face path))
+ ((and (pred facep) face) face)
+ ((and (pred consp) face) face) ;anonymous
+ (_ 'org-link)))
(properties ;for link's visible part
- (list
- 'face (pcase (org-link-get-parameter type :face)
- ((and (pred functionp) face) (funcall face path))
- ((and (pred facep) face) face)
- ((and (pred consp) face) face) ;anonymous
- (_ 'org-link))
- 'mouse-face (or (org-link-get-parameter type :mouse-face)
- 'highlight)
- 'keymap (or (org-link-get-parameter type :keymap)
- org-mouse-map)
- 'help-echo (pcase (org-link-get-parameter type :help-echo)
- ((and (pred stringp) echo) echo)
- ((and (pred functionp) echo) echo)
- (_ (concat "LINK: " link)))
- 'htmlize-link (pcase (org-link-get-parameter type
- :htmlize-link)
- ((and (pred functionp) f) (funcall f))
- (_ `(:uri ,link)))
- 'font-lock-multiline t)))
+ (list 'mouse-face (or (org-link-get-parameter type :mouse-face)
+ 'highlight)
+ 'keymap (or (org-link-get-parameter type :keymap)
+ org-mouse-map)
+ 'help-echo (pcase (org-link-get-parameter type :help-echo)
+ ((and (pred stringp) echo) echo)
+ ((and (pred functionp) echo) echo)
+ (_ (concat "LINK: " link)))
+ 'htmlize-link (pcase (org-link-get-parameter type
+ :htmlize-link)
+ ((and (pred functionp) f) (funcall f))
+ (_ `(:uri ,link)))
+ 'font-lock-multiline t)))
(org-remove-flyspell-overlays-in start end)
(org-rear-nonsticky-at end)
(if (not (eq 'bracket style))
- (add-text-properties start end properties)
+ (progn
+ (add-face-text-property start end face-property)
+ (add-text-properties start end properties))
;; Handle invisible parts in bracket links.
(remove-text-properties start end '(invisible nil))
(let ((hidden
@@ -5175,6 +5229,7 @@ This includes angle, plain, and bracket links."
'org-link))
properties)))
(add-text-properties start visible-start hidden)
+ (add-face-text-property start end face-property)
(add-text-properties visible-start visible-end properties)
(add-text-properties visible-end end hidden)
(org-rear-nonsticky-at visible-start)
@@ -5272,7 +5327,8 @@ by a #."
(org-remove-flyspell-overlays-in nl-before-endline end-of-endline)
(cond
((and lang (not (string= lang "")) org-src-fontify-natively)
- (org-src-font-lock-fontify-block lang block-start block-end)
+ (save-match-data
+ (org-src-font-lock-fontify-block lang block-start block-end))
(add-text-properties bol-after-beginline block-end '(src-block t)))
(quoting
(add-text-properties
@@ -5303,7 +5359,7 @@ by a #."
(min (point-max) end-of-endline))
'(face org-block-end-line)))
t))
- ((member dc1 '("+title:" "+author:" "+email:" "+date:"))
+ ((member dc1 '("+title:" "+subtitle:" "+author:" "+email:" "+date:"))
(org-remove-flyspell-overlays-in
(match-beginning 0)
(if (equal "+title:" dc1) (match-end 2) (match-end 0)))
@@ -5376,22 +5432,26 @@ by a #."
t)))))
(defun org-fontify-extend-region (beg end _old-len)
- (let ((begin-re "\\(\\\\\\[\\|\\(#\\+begin_\\|\\\\begin{\\)\\S-+\\)")
+ (let ((end (if (progn (goto-char end) (looking-at-p "^[*#]"))
+ (1+ end) end))
+ (begin-re "\\(\\\\\\[\\|\\(#\\+begin_\\|\\\\begin{\\)\\S-+\\)")
(end-re "\\(\\\\\\]\\|\\(#\\+end_\\|\\\\end{\\)\\S-+\\)")
- (extend (lambda (r1 r2 dir)
- (let ((re (replace-regexp-in-string "\\(begin\\|end\\)" r1
- (replace-regexp-in-string "[][]" r2
- (match-string-no-properties 0)))))
- (re-search-forward (regexp-quote re) nil t dir)))))
+ (extend
+ (lambda (r1 r2 dir)
+ (let ((re (replace-regexp-in-string
+ "\\(begin\\|end\\)" r1
+ (replace-regexp-in-string
+ "[][]" r2
+ (match-string-no-properties 0)))))
+ (re-search-forward (regexp-quote re) nil t dir)))))
+ (goto-char beg)
+ (back-to-indentation)
(save-match-data
- (save-excursion
- (goto-char beg)
- (back-to-indentation)
- (cond ((looking-at end-re)
- (cons (or (funcall extend "begin" "[" -1) beg) end))
- ((looking-at begin-re)
- (cons beg (or (funcall extend "end" "]" 1) end)))
- (t (cons beg end)))))))
+ (cond ((looking-at end-re)
+ (cons (or (funcall extend "begin" "[" -1) beg) end))
+ ((looking-at begin-re)
+ (cons beg (or (funcall extend "end" "]" 1) end)))
+ (t (cons beg end))))))
(defun org-activate-footnote-links (limit)
"Add text properties for footnotes."
@@ -5488,6 +5548,8 @@ highlighting was done, nil otherwise."
(while (and (< (point) limit)
(re-search-forward org-latex-and-related-regexp nil t))
(cond
+ ((>= (match-beginning 0) limit)
+ (throw 'found nil))
((cl-some (lambda (f)
(memq f '(org-code org-verbatim underline
org-special-keyword)))
@@ -5600,111 +5662,116 @@ needs to be inserted at a specific position in the font-lock sequence.")
(defun org-set-font-lock-defaults ()
"Set font lock defaults for the current buffer."
- (let* ((em org-fontify-emphasized-text)
- (lk org-highlight-links)
- (org-font-lock-extra-keywords
- (list
- ;; Call the hook
- '(org-font-lock-hook)
- ;; Headlines
- `(,(if org-fontify-whole-heading-line
- "^\\(\\**\\)\\(\\* \\)\\(.*\n?\\)"
- "^\\(\\**\\)\\(\\* \\)\\(.*\\)")
- (1 (org-get-level-face 1))
- (2 (org-get-level-face 2))
- (3 (org-get-level-face 3)))
- ;; Table lines
- '("^[ \t]*\\(\\(|\\|\\+-[-+]\\).*\\S-\\)"
- (1 'org-table t))
- ;; Table internals
- '("^[ \t]*|\\(?:.*?|\\)? *\\(:?=[^|\n]*\\)" (1 'org-formula t))
- '("^[ \t]*| *\\([#*]\\) *|" (1 'org-formula t))
- '("^[ \t]*|\\( *\\([$!_^/]\\) *|.*\\)|" (1 'org-formula t))
- '("| *\\(<[lrc]?[0-9]*>\\)" (1 'org-formula t))
- ;; Properties
- (list org-property-re
- '(1 'org-special-keyword t)
- '(3 'org-property-value t))
- ;; Drawers
- '(org-fontify-drawers)
- ;; Link related fontification.
- '(org-activate-links)
- (when (memq 'tag lk) '(org-activate-tags (1 'org-tag prepend)))
- (when (memq 'radio lk) '(org-activate-target-links (1 'org-link t)))
- (when (memq 'date lk) '(org-activate-dates (0 'org-date t)))
- (when (memq 'footnote lk) '(org-activate-footnote-links))
- ;; Targets.
- (list org-radio-target-regexp '(0 'org-target t))
- (list org-target-regexp '(0 'org-target t))
- ;; Diary sexps.
- '("^&?%%(.*\\|<%%([^>\n]*?>" (0 'org-sexp-date t))
- ;; Macro
- '(org-fontify-macros)
- ;; TODO keyword
- (list (format org-heading-keyword-regexp-format
- org-todo-regexp)
- '(2 (org-get-todo-face 2) t))
- ;; TODO
- (when org-fontify-todo-headline
- (list (format org-heading-keyword-regexp-format
- (concat
- "\\(?:"
- (mapconcat 'regexp-quote org-not-done-keywords "\\|")
- "\\)"))
- '(2 'org-headline-todo t)))
- ;; DONE
- (when org-fontify-done-headline
- (list (format org-heading-keyword-regexp-format
- (concat
- "\\(?:"
- (mapconcat 'regexp-quote org-done-keywords "\\|")
- "\\)"))
- '(2 'org-headline-done t)))
- ;; Priorities
- '(org-font-lock-add-priority-faces)
- ;; Tags
- '(org-font-lock-add-tag-faces)
- ;; Tags groups
- (when (and org-group-tags org-tag-groups-alist)
- (list (concat org-outline-regexp-bol ".+\\(:"
- (regexp-opt (mapcar 'car org-tag-groups-alist))
- ":\\).*$")
- '(1 'org-tag-group prepend)))
- ;; Special keywords
- (list (concat "\\<" org-deadline-string) '(0 'org-special-keyword t))
- (list (concat "\\<" org-scheduled-string) '(0 'org-special-keyword t))
- (list (concat "\\<" org-closed-string) '(0 'org-special-keyword t))
- (list (concat "\\<" org-clock-string) '(0 'org-special-keyword t))
- ;; Emphasis
- (when em '(org-do-emphasis-faces))
- ;; Checkboxes
- '("^[ \t]*\\(?:[-+*]\\|[0-9]+[.)]\\)[ \t]+\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\(\\[[- X]\\]\\)"
- 1 'org-checkbox prepend)
- (when (cdr (assq 'checkbox org-list-automatic-rules))
- '("\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]"
- (0 (org-get-checkbox-statistics-face) t)))
- ;; Description list items
- '("^[ \t]*[-+*][ \t]+\\(.*?[ \t]+::\\)\\([ \t]+\\|$\\)"
- 1 'org-list-dt prepend)
- ;; ARCHIVEd headings
- (list (concat
- org-outline-regexp-bol
- "\\(.*:" org-archive-tag ":.*\\)")
- '(1 'org-archived prepend))
- ;; Specials
- '(org-do-latex-and-related)
- '(org-fontify-entities)
- '(org-raise-scripts)
- ;; Code
- '(org-activate-code (1 'org-code t))
- ;; COMMENT
- (list (format
- "^\\*+\\(?: +%s\\)?\\(?: +\\[#[A-Z0-9]\\]\\)? +\\(?9:%s\\)\\(?: \\|$\\)"
- org-todo-regexp
- org-comment-string)
- '(9 'org-special-keyword t))
- ;; Blocks and meta lines
- '(org-fontify-meta-lines-and-blocks))))
+ (let ((org-font-lock-extra-keywords
+ (list
+ ;; Call the hook
+ '(org-font-lock-hook)
+ ;; Headlines
+ `(,(if org-fontify-whole-heading-line
+ "^\\(\\**\\)\\(\\* \\)\\(.*\n?\\)"
+ "^\\(\\**\\)\\(\\* \\)\\(.*\\)")
+ (1 (org-get-level-face 1))
+ (2 (org-get-level-face 2))
+ (3 (org-get-level-face 3)))
+ ;; Table lines
+ '("^[ \t]*\\(\\(|\\|\\+-[-+]\\).*\\S-\\)"
+ (1 'org-table t))
+ ;; Table internals
+ '("^[ \t]*|\\(?:.*?|\\)? *\\(:?=[^|\n]*\\)" (1 'org-formula t))
+ '("^[ \t]*| *\\([#*]\\) *|" (1 'org-formula t))
+ '("^[ \t]*|\\( *\\([$!_^/]\\) *|.*\\)|" (1 'org-formula t))
+ '("| *\\(<[lrc]?[0-9]*>\\)" (1 'org-formula t))
+ ;; Properties
+ (list org-property-re
+ '(1 'org-special-keyword t)
+ '(3 'org-property-value t))
+ ;; Drawers
+ '(org-fontify-drawers)
+ ;; Link related fontification.
+ '(org-activate-links)
+ (when (memq 'tag org-highlight-links) '(org-activate-tags (1 'org-tag prepend)))
+ (when (memq 'radio org-highlight-links) '(org-activate-target-links (1 'org-link t)))
+ (when (memq 'date org-highlight-links) '(org-activate-dates (0 'org-date t)))
+ (when (memq 'footnote org-highlight-links) '(org-activate-footnote-links))
+ ;; Targets.
+ (list org-radio-target-regexp '(0 'org-target t))
+ (list org-target-regexp '(0 'org-target t))
+ ;; Diary sexps.
+ '("^&?%%(.*\\|<%%([^>\n]*?>" (0 'org-sexp-date t))
+ ;; Macro
+ '(org-fontify-macros)
+ ;; TODO keyword
+ (list (format org-heading-keyword-regexp-format
+ org-todo-regexp)
+ '(2 (org-get-todo-face 2) prepend))
+ ;; TODO
+ (when org-fontify-todo-headline
+ (list (format org-heading-keyword-regexp-format
+ (concat
+ "\\(?:"
+ (mapconcat 'regexp-quote org-not-done-keywords "\\|")
+ "\\)"))
+ '(2 'org-headline-todo prepend)))
+ ;; DONE
+ (when org-fontify-done-headline
+ (list (format org-heading-keyword-regexp-format
+ (concat
+ "\\(?:"
+ (mapconcat 'regexp-quote org-done-keywords "\\|")
+ "\\)"))
+ '(2 'org-headline-done prepend)))
+ ;; Priorities
+ '(org-font-lock-add-priority-faces)
+ ;; Tags
+ '(org-font-lock-add-tag-faces)
+ ;; Tags groups
+ (when (and org-group-tags org-tag-groups-alist)
+ (list (concat org-outline-regexp-bol ".+\\(:"
+ (regexp-opt (mapcar 'car org-tag-groups-alist))
+ ":\\).*$")
+ '(1 'org-tag-group prepend)))
+ ;; Special keywords
+ (list (concat "\\<" org-deadline-string) '(0 'org-special-keyword t))
+ (list (concat "\\<" org-scheduled-string) '(0 'org-special-keyword t))
+ (list (concat "\\<" org-closed-string) '(0 'org-special-keyword t))
+ (list (concat "\\<" org-clock-string) '(0 'org-special-keyword t))
+ ;; Emphasis
+ (when org-fontify-emphasized-text '(org-do-emphasis-faces))
+ ;; Checkboxes
+ '("^[ \t]*\\(?:[-+*]\\|[0-9]+[.)]\\)[ \t]+\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\(\\[[- X]\\]\\)"
+ 1 'org-checkbox prepend)
+ (when (cdr (assq 'checkbox org-list-automatic-rules))
+ '("\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]"
+ (0 (org-get-checkbox-statistics-face) prepend)))
+ ;; Description list items
+ '("\\(?:^[ \t]*[-+]\\|^[ \t]+[*]\\)[ \t]+\\(.*?[ \t]+::\\)\\([ \t]+\\|$\\)"
+ 1 'org-list-dt prepend)
+ ;; Inline export snippets
+ '("\\(@@\\)\\([a-z-]+:\\).*?\\(@@\\)"
+ (1 'font-lock-comment-face t)
+ (2 'org-tag t)
+ (3 'font-lock-comment-face t))
+ ;; ARCHIVEd headings
+ (list (concat
+ org-outline-regexp-bol
+ "\\(.*:" org-archive-tag ":.*\\)")
+ '(1 'org-archived prepend))
+ ;; Specials
+ '(org-do-latex-and-related)
+ '(org-fontify-entities)
+ '(org-raise-scripts)
+ ;; Code
+ '(org-activate-code (1 'org-code t))
+ ;; COMMENT
+ (list (format
+ "^\\*+\\(?: +%s\\)?\\(?: +\\[#[A-Z0-9]\\]\\)? +\\(?9:%s\\)\\(?: \\|$\\)"
+ org-todo-regexp
+ org-comment-string)
+ '(9 'org-special-keyword t))
+ ;; Blocks and meta lines
+ '(org-fontify-meta-lines-and-blocks)
+ ;; Citations
+ '(org-cite-activate))))
(setq org-font-lock-extra-keywords (delq nil org-font-lock-extra-keywords))
(run-hooks 'org-font-lock-set-keywords-hook)
;; Now set the full font-lock-keywords
@@ -5842,19 +5909,26 @@ If TAG is a number, get the corresponding match group."
(defun org-font-lock-add-priority-faces (limit)
"Add the special priority faces."
- (while (re-search-forward org-priority-regexp limit t)
- (add-text-properties
- (match-beginning 1) (1+ (match-end 2))
- (list 'face (org-get-priority-face (string-to-char (match-string 2)))
- 'font-lock-fontified t))))
+ (while (re-search-forward (concat "^\\*+" org-priority-regexp) limit t)
+ (let ((beg (match-beginning 1))
+ (end (1+ (match-end 2))))
+ (add-face-text-property
+ beg end
+ (org-get-priority-face (string-to-char (match-string 2))))
+ (add-text-properties
+ beg end
+ (list 'font-lock-fontified t)))))
(defun org-font-lock-add-tag-faces (limit)
"Add the special tag faces."
(when (and org-tag-faces org-tags-special-faces-re)
(while (re-search-forward org-tags-special-faces-re limit t)
+ (add-face-text-property
+ (match-beginning 1)
+ (match-end 1)
+ (org-get-tag-face 1))
(add-text-properties (match-beginning 1) (match-end 1)
- (list 'face (org-get-tag-face 1)
- 'font-lock-fontified t))
+ (list 'font-lock-fontified t))
(backward-char 1))))
(defun org-unfontify-region (beg end &optional _maybe_loudly)
@@ -5928,8 +6002,9 @@ and subscripts."
"Remove outline overlays that do not contain non-white stuff."
(dolist (o (overlays-at pos))
(and (eq 'outline (overlay-get o 'invisible))
- (not (string-match-p "\\S-" (buffer-substring (overlay-start o)
- (overlay-end o))))
+ (not (string-match-p
+ "\\S-" (buffer-substring (overlay-start o)
+ (overlay-end o))))
(delete-overlay o))))
(defun org-show-empty-lines-in-parent ()
@@ -6138,9 +6213,38 @@ Return a non-nil value when toggling is successful."
(defun org-hide-drawer-all ()
"Fold all drawers in the current buffer."
+ (let ((begin (point-min))
+ (end (point-max)))
+ (org--hide-drawers begin end)))
+
+(defun org-cycle-hide-drawers (state)
+ "Re-hide all drawers after a visibility state change.
+STATE should be one of the symbols listed in the docstring of
+`org-cycle-hook'."
+ (when (derived-mode-p 'org-mode)
+ (cond ((not (memq state '(overview folded contents)))
+ (let* ((global? (eq state 'all))
+ (beg (if global? (point-min) (line-beginning-position)))
+ (end (cond (global? (point-max))
+ ((eq state 'children) (org-entry-end-position))
+ (t (save-excursion (org-end-of-subtree t t))))))
+ (org--hide-drawers beg end)))
+ ((memq state '(overview contents))
+ ;; Hide drawers before first heading.
+ (let ((beg (point-min))
+ (end (save-excursion
+ (goto-char (point-min))
+ (if (org-before-first-heading-p)
+ (org-entry-end-position)
+ (point-min)))))
+ (when (< beg end)
+ (org--hide-drawers beg end)))))))
+
+(defun org--hide-drawers (begin end)
+ "Hide all drawers between BEGIN and END."
(save-excursion
- (goto-char (point-min))
- (while (re-search-forward org-drawer-regexp nil t)
+ (goto-char begin)
+ (while (re-search-forward org-drawer-regexp end t)
(let* ((pair (get-char-property-and-overlay (line-beginning-position)
'invisible))
(o (cdr-safe pair)))
@@ -6157,32 +6261,6 @@ Return a non-nil value when toggling is successful."
;; `org-drawer-regexp'.
(goto-char (org-element-property :end drawer)))))))))))
-(defun org-cycle-hide-drawers (state)
- "Re-hide all drawers after a visibility state change.
-STATE should be one of the symbols listed in the docstring of
-`org-cycle-hook'."
- (when (and (derived-mode-p 'org-mode)
- (not (memq state '(overview folded contents))))
- (let* ((global? (eq state 'all))
- (beg (if global? (point-min) (line-beginning-position)))
- (end (cond (global? (point-max))
- ((eq state 'children) (org-entry-end-position))
- (t (save-excursion (org-end-of-subtree t t))))))
- (save-excursion
- (goto-char beg)
- (while (re-search-forward org-drawer-regexp end t)
- (pcase (get-char-property-and-overlay (point) 'invisible)
- ;; Do not fold already folded drawers.
- (`(outline . ,o) (goto-char (overlay-end o)))
- (_
- (let ((drawer (org-element-at-point)))
- (when (memq (org-element-type drawer) '(drawer property-drawer))
- (org-hide-drawer-toggle t nil drawer)
- ;; Make sure to skip drawer entirely or we might flag
- ;; it another time when matching its ending line with
- ;; `org-drawer-regexp'.
- (goto-char (org-element-property :end drawer)))))))))))
-
;;;; Visibility cycling
(defvar-local org-cycle-global-status nil)
@@ -6475,7 +6553,7 @@ Use `\\[org-edit-special]' to edit table.el tables"))
(org-list-set-item-visibility (point-at-bol) struct 'children)
(org-show-entry)
(org-with-limited-levels (org-show-children))
- (org-show-set-visibility 'canonical)
+ (org-show-set-visibility 'tree)
;; Fold every list in subtree to top-level items.
(when (eq org-cycle-include-plain-lists 'integrate)
(save-excursion
@@ -6541,6 +6619,14 @@ With a numeric prefix, show all headlines up to that level."
(org-overview))
((eq org-startup-folded 'content)
(org-content))
+ ((eq org-startup-folded 'show2levels)
+ (org-content 2))
+ ((eq org-startup-folded 'show3levels)
+ (org-content 3))
+ ((eq org-startup-folded 'show4levels)
+ (org-content 4))
+ ((eq org-startup-folded 'show5levels)
+ (org-content 5))
((or (eq org-startup-folded 'showeverything)
(eq org-startup-folded nil))
(org-show-all)))
@@ -6640,8 +6726,8 @@ This function is the default value of the hook `org-cycle-hook'."
;; First, find a reasonable region to look at:
;; Start two siblings above, end three below
(let* ((beg (save-excursion
- (and (org-get-last-sibling)
- (org-get-last-sibling))
+ (and (org-get-previous-sibling)
+ (org-get-previous-sibling))
(point)))
(end (save-excursion
(and (org-get-next-sibling)
@@ -6723,9 +6809,9 @@ be shown."
(defun org-show-set-visibility (detail)
"Set visibility around point according to DETAIL.
-DETAIL is either nil, `minimal', `local', `ancestors', `lineage',
-`tree', `canonical' or t. See `org-show-context-detail' for more
-information."
+DETAIL is either nil, `minimal', `local', `ancestors',
+`ancestors-full', `lineage', `tree', `canonical' or t. See
+`org-show-context-detail' for more information."
;; Show current heading and possibly its entry, following headline
;; or all children.
(if (and (org-at-heading-p) (not (eq detail 'local)))
@@ -6740,14 +6826,16 @@ information."
(org-with-limited-levels
(cl-case detail
((tree canonical t) (org-show-children))
- ((nil minimal ancestors))
+ ((nil minimal ancestors ancestors-full))
(t (save-excursion
(outline-next-heading)
(org-flag-heading nil)))))))
+ ;; Show whole subtree.
+ (when (eq detail 'ancestors-full) (org-show-subtree))
;; Show all siblings.
(when (eq detail 'lineage) (org-show-siblings))
;; Show ancestors, possibly with their children.
- (when (memq detail '(ancestors lineage tree canonical t))
+ (when (memq detail '(ancestors ancestors-full lineage tree canonical t))
(save-excursion
(while (org-up-heading-safe)
(org-flag-heading nil)
@@ -6945,6 +7033,14 @@ unconditionally."
(when (equal arg '(16)) (org-up-heading-safe))
(org-end-of-subtree)))
(unless (bolp) (insert "\n"))
+ (when (and blank? (save-excursion
+ (backward-char)
+ (org-before-first-heading-p)))
+ (insert "\n")
+ (backward-char))
+ (when (and (not level) (not (eobp)) (not (bobp)))
+ (when (org-at-heading-p) (insert "\n"))
+ (backward-char))
(unless (and blank? (org-previous-line-empty-p))
(org-N-empty-lines-before-current (if blank? 1 0)))
(insert stars " ")
@@ -7391,7 +7487,9 @@ Assume point is at a heading or an inlinetask beginning."
(col (+ (current-indentation) diff)))
(when (wholenump col)
(while (< (point) end-marker)
- (indent-line-to col)
+ (if (natnump diff)
+ (insert (make-string diff 32))
+ (delete-char (abs diff)))
(forward-line)))))
(catch 'no-shift
(when (or (zerop diff) (not (eq org-adapt-indentation t)))
@@ -7521,7 +7619,7 @@ case."
(setq arg (prefix-numeric-value arg))
(org-preserve-local-variables
(let ((movfunc (if (> arg 0) 'org-get-next-sibling
- 'org-get-last-sibling))
+ 'org-get-previous-sibling))
(ins-point (make-marker))
(cnt (abs arg))
(col (current-column))
@@ -7784,7 +7882,8 @@ called immediately, to move the markers with the entries."
"Check if MARKER is between BEG and END.
If yes, remember the marker and the distance to BEG."
(when (and (marker-buffer marker)
- (equal (marker-buffer marker) (current-buffer))
+ (or (equal (marker-buffer marker) (current-buffer))
+ (equal (marker-buffer marker) (buffer-base-buffer (current-buffer))))
(>= marker beg) (< marker end))
(push (cons marker (- marker beg)) org-markers-to-move)))
@@ -7875,7 +7974,7 @@ with the original repeater."
""))) ;No time shift
(doshift
(and (org-string-nw-p shift)
- (or (string-match "\\`[ \t]*\\([+-]?[0-9]+\\)\\([dwmy]\\)[ \t]*\\'"
+ (or (string-match "\\`[ \t]*\\([+-]?[0-9]+\\)\\([hdwmy]\\)[ \t]*\\'"
shift)
(user-error "Invalid shift specification %s" shift)))))
(goto-char end-of-tree)
@@ -7885,6 +7984,7 @@ with the original repeater."
(shift-n (and doshift (string-to-number (match-string 1 shift))))
(shift-what (pcase (and doshift (match-string 2 shift))
(`nil nil)
+ ("h" 'hour)
("d" 'day)
("w" (setq shift-n (* 7 shift-n)) 'day)
("m" 'month)
@@ -8074,14 +8174,37 @@ Optional argument WITH-CASE means sort case-sensitively."
with-case))
(defun org-sort-remove-invisible (s)
- "Remove invisible part of links and emphasis markers from string S."
- (remove-text-properties 0 (length s) org-rm-props s)
- (replace-regexp-in-string
- org-verbatim-re (lambda (m) (format "%s " (match-string 4 m)))
- (replace-regexp-in-string
- org-emph-re (lambda (m) (format " %s " (match-string 4 m)))
- (org-link-display-format s)
- t t) t t))
+ "Remove emphasis markers and any invisible property from string S.
+Assume S may contain only objects."
+ ;; org-element-interpret-data clears any text property, including
+ ;; invisible part.
+ (org-element-interpret-data
+ (let ((tree (org-element-parse-secondary-string
+ s (org-element-restriction 'paragraph))))
+ (org-element-map tree '(bold code italic link strike-through underline verbatim)
+ (lambda (o)
+ (pcase (org-element-type o)
+ ;; Terminal object. Replace it with its value.
+ ((or `code `verbatim)
+ (let ((new (org-element-property :value o)))
+ (org-element-insert-before new o)
+ (org-element-put-property
+ new :post-blank (org-element-property :post-blank o))))
+ ;; Non-terminal objects. Splice contents.
+ (type
+ (let ((contents
+ (or (org-element-contents o)
+ (and (eq type 'link)
+ (list (org-element-property :raw-link o)))))
+ (c nil))
+ (while contents
+ (setq c (pop contents))
+ (org-element-insert-before c o))
+ (org-element-put-property
+ c :post-blank (org-element-property :post-blank o)))))
+ (org-element-extract-element o)))
+ ;; Return modified tree.
+ tree)))
(defvar org-after-sorting-entries-or-items-hook nil
"Hook that is run after a bunch of entries or items have been sorted.
@@ -8222,7 +8345,7 @@ function is being called interactively."
;; The clock marker is lost when using `sort-subr'; mark
;; the clock with temporary `:org-clock-marker-backup'
;; text property.
- (when (and (eq (org-clock-is-active) (current-buffer))
+ (when (and (eq (org-clocking-buffer) (current-buffer))
(<= start (marker-position org-clock-marker))
(>= end (marker-position org-clock-marker)))
(with-silent-modifications
@@ -8735,7 +8858,16 @@ If the file does not exist, throw an error."
(save-window-excursion
(message "Running %s...done" cmd)
- (start-process-shell-command cmd nil cmd)
+ ;; Handlers such as "gio open" and kde-open5 start viewer in background
+ ;; and exit immediately. Use pipe connection type instead of pty to
+ ;; avoid killing children processes with SIGHUP when temporary terminal
+ ;; session is finished.
+ ;;
+ ;; TODO: Once minimum Emacs version is 25.1 or above, consider using
+ ;; the `make-process' invocation from 5db61eb0f929 to get more helpful
+ ;; error messages.
+ (let ((process-connection-type nil))
+ (start-process-shell-command cmd nil cmd))
(and (boundp 'org-wait) (numberp org-wait) (sit-for org-wait))))
((or (stringp cmd)
(eq cmd 'emacs))
@@ -8832,9 +8964,10 @@ a link."
;; closest one.
(org-element-lineage
(org-element-context)
- '(clock comment comment-block footnote-definition
- footnote-reference headline inline-src-block inlinetask
- keyword link node-property planning src-block timestamp)
+ '(citation citation-reference clock comment comment-block
+ footnote-definition footnote-reference headline
+ inline-src-block inlinetask keyword link node-property
+ planning src-block timestamp)
t))
(type (org-element-type context))
(value (org-element-property :value context)))
@@ -8845,7 +8978,7 @@ a link."
((memq type '(comment comment-block node-property keyword))
(call-interactively #'org-open-at-point-global))
;; On a headline or an inlinetask, but not on a timestamp,
- ;; a link, a footnote reference.
+ ;; a link, a footnote reference or a citation.
((memq type '(headline inlinetask))
(org-match-line org-complex-heading-regexp)
(let ((tags-beg (match-beginning 5))
@@ -8908,6 +9041,7 @@ a link."
((eq type 'inline-src-block) (org-babel-open-src-block-result))
((eq type 'timestamp) (org-follow-timestamp-link))
((eq type 'link) (org-link-open context arg))
+ ((memq type '(citation citation-reference)) (org-cite-follow context arg))
(t (user-error "No link found")))))
(run-hook-with-args 'org-follow-link-hook))
@@ -9042,26 +9176,29 @@ or to another Org file, automatically push the old position onto the ring."
(defvar org-agenda-buffer-tmp-name)
(defvar org-agenda-start-on-weekday)
+(defvar org-agenda-buffer-name)
(defun org-follow-timestamp-link ()
"Open an agenda view for the time-stamp date/range at point."
- (cond
- ((org-at-date-range-p t)
- (let ((org-agenda-start-on-weekday)
- (t1 (match-string 1))
- (t2 (match-string 2)) tt1 tt2)
- (setq tt1 (time-to-days (org-time-string-to-time t1))
- tt2 (time-to-days (org-time-string-to-time t2)))
+ ;; Avoid changing the global value.
+ (let ((org-agenda-buffer-name org-agenda-buffer-name))
+ (cond
+ ((org-at-date-range-p t)
+ (let ((org-agenda-start-on-weekday)
+ (t1 (match-string 1))
+ (t2 (match-string 2)) tt1 tt2)
+ (setq tt1 (time-to-days (org-time-string-to-time t1))
+ tt2 (time-to-days (org-time-string-to-time t2)))
+ (let ((org-agenda-buffer-tmp-name
+ (format "*Org Agenda(a:%s)"
+ (concat (substring t1 0 10) "--" (substring t2 0 10)))))
+ (org-agenda-list nil tt1 (1+ (- tt2 tt1))))))
+ ((org-at-timestamp-p 'lax)
(let ((org-agenda-buffer-tmp-name
- (format "*Org Agenda(a:%s)"
- (concat (substring t1 0 10) "--" (substring t2 0 10)))))
- (org-agenda-list nil tt1 (1+ (- tt2 tt1))))))
- ((org-at-timestamp-p 'lax)
- (let ((org-agenda-buffer-tmp-name
- (format "*Org Agenda(a:%s)" (substring (match-string 1) 0 10))))
- (org-agenda-list nil (time-to-days (org-time-string-to-time
- (substring (match-string 1) 0 10)))
- 1)))
- (t (error "This should not happen"))))
+ (format "*Org Agenda(a:%s)" (substring (match-string 1) 0 10))))
+ (org-agenda-list nil (time-to-days (org-time-string-to-time
+ (substring (match-string 1) 0 10)))
+ 1)))
+ (t (error "This should not happen")))))
;;; Following file links
@@ -9427,7 +9564,7 @@ If an element cannot be made unique, an error is raised."
(mapcar (apply-partially #'concat (substring key 0 1))
(split-string (substring key 1) "" t)))))))
(if (or (not potential-key) (assoc potential-key menu-keys))
- (user-error "Could not make unique key for %s." key)
+ (user-error "Could not make unique key for `%s'" key)
(push (cons potential-key key) menu-keys))))
(mapcar #'car
(cl-sort menu-keys #'<
@@ -9958,7 +10095,8 @@ all statistics cookies in the buffer."
(if all
(progn
(org-update-checkbox-count 'all)
- (org-map-entries 'org-update-parent-todo-statistics))
+ (org-map-region 'org-update-parent-todo-statistics
+ (point-min) (point-max)))
(if (not (org-at-heading-p))
(org-update-checkbox-count)
(let ((pos (point-marker))
@@ -9967,15 +10105,17 @@ all statistics cookies in the buffer."
(if (not (org-at-heading-p))
(org-update-checkbox-count)
(setq l1 (org-outline-level))
- (setq end (save-excursion
- (outline-next-heading)
- (when (org-at-heading-p) (setq l2 (org-outline-level)))
- (point)))
+ (setq end
+ (save-excursion
+ (outline-next-heading)
+ (when (org-at-heading-p) (setq l2 (org-outline-level)))
+ (point)))
(if (and (save-excursion
(re-search-forward
"^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) \\[[- X]\\]" end t))
- (not (save-excursion (re-search-forward
- ":COOKIE_DATA:.*\\<todo\\>" end t))))
+ (not (save-excursion
+ (re-search-forward
+ ":COOKIE_DATA:.*\\<todo\\>" end t))))
(org-update-checkbox-count)
(if (and l2 (> l2 l1))
(progn
@@ -9996,8 +10136,9 @@ all statistics cookies in the buffer."
When `org-hierarchical-todo-statistics' is nil, statistics will cover
the entire subtree and this will travel up the hierarchy and update
statistics everywhere."
- (let* ((prop (save-excursion (org-up-heading-safe)
- (org-entry-get nil "COOKIE_DATA" 'inherit)))
+ (let* ((prop (save-excursion
+ (org-up-heading-safe)
+ (org-entry-get nil "COOKIE_DATA" 'inherit)))
(recursive (or (not org-hierarchical-todo-statistics)
(and prop (string-match "\\<recursive\\>" prop))))
(lim (or (and prop (marker-position org-entry-property-inherited-from))
@@ -10242,7 +10383,8 @@ prefer a state in the current sequence over on in another sequence."
"Return the TODO keyword of the current subtree."
(save-excursion
(org-back-to-heading t)
- (and (let ((case-fold-search nil)) (looking-at org-todo-line-regexp))
+ (and (let ((case-fold-search nil))
+ (looking-at org-todo-line-regexp))
(match-end 2)
(match-string 2))))
@@ -10280,18 +10422,19 @@ this function is called before first heading.
When optional argument TIMESTAMP is a string, extract the
repeater from there instead."
(save-match-data
- (cond (timestamp
- (and (string-match org-repeat-re timestamp)
- (match-string-no-properties 1 timestamp)))
- ((org-before-first-heading-p) nil)
- (t
- (save-excursion
- (org-back-to-heading t)
- (let ((end (org-entry-end-position)))
- (catch :repeat
- (while (re-search-forward org-repeat-re end t)
- (when (save-match-data (org-at-timestamp-p 'agenda))
- (throw :repeat (match-string-no-properties 1)))))))))))
+ (cond
+ (timestamp
+ (and (string-match org-repeat-re timestamp)
+ (match-string-no-properties 1 timestamp)))
+ ((org-before-first-heading-p) nil)
+ (t
+ (save-excursion
+ (org-back-to-heading t)
+ (let ((end (org-entry-end-position)))
+ (catch :repeat
+ (while (re-search-forward org-repeat-re end t)
+ (when (save-match-data (org-at-timestamp-p 'agenda))
+ (throw :repeat (match-string-no-properties 1)))))))))))
(defvar org-last-changed-timestamp)
(defvar org-last-inserted-timestamp)
@@ -10299,6 +10442,7 @@ repeater from there instead."
(defvar org-log-note-purpose)
(defvar org-log-note-how nil)
(defvar org-log-note-extra)
+(defvar org-log-setup nil)
(defun org-auto-repeat-maybe (done-word)
"Check if the current headline contains a repeated time-stamp.
@@ -10317,10 +10461,11 @@ This function is run automatically after each state change to a DONE state."
(end (copy-marker (org-entry-end-position))))
(when (and repeat (not (= 0 (string-to-number (substring repeat 1)))))
(when (eq org-log-repeat t) (setq org-log-repeat 'state))
- (let ((to-state (or (org-entry-get nil "REPEAT_TO_STATE" 'selective)
- (and (stringp org-todo-repeat-to-state)
- org-todo-repeat-to-state)
- (and org-todo-repeat-to-state org-last-state))))
+ (let ((to-state
+ (or (org-entry-get nil "REPEAT_TO_STATE" 'selective)
+ (and (stringp org-todo-repeat-to-state)
+ org-todo-repeat-to-state)
+ (and org-todo-repeat-to-state org-last-state))))
(org-todo (cond ((and to-state (member to-state org-todo-keywords-1))
to-state)
((eq interpret 'type) org-last-state)
@@ -10338,8 +10483,7 @@ This function is run automatically after each state change to a DONE state."
(org-entry-put nil "LAST_REPEAT" (format-time-string
(org-time-stamp-format t t))))
(when org-log-repeat
- (if (or (memq 'org-add-log-note (default-value 'post-command-hook))
- (memq 'org-add-log-note post-command-hook))
+ (if org-log-setup
;; We are already setup for some record.
(when (eq org-log-repeat 'note)
;; Make sure we take a note, not only a time stamp.
@@ -10776,7 +10920,8 @@ narrowing."
(let ((beg (point)))
(insert ":" drawer ":\n:END:\n")
(org-indent-region beg (point))
- (org-flag-region (line-end-position -1) (1- (point)) t 'outline))
+ (org-flag-region (line-end-position -1)
+ (1- (point)) t 'outline))
(end-of-line -1)))))
(t
(org-end-of-meta-data org-log-state-notes-insert-after-drawers)
@@ -10799,7 +10944,8 @@ EXTRA is additional text that will be inserted into the notes buffer."
org-log-note-previous-state prev-state
org-log-note-how how
org-log-note-extra extra
- org-log-note-effective-time (org-current-effective-time))
+ org-log-note-effective-time (org-current-effective-time)
+ org-log-setup t)
(add-hook 'post-command-hook 'org-add-log-note 'append))
(defun org-skip-over-state-notes ()
@@ -10828,6 +10974,7 @@ EXTRA is additional text that will be inserted into the notes buffer."
(defun org-add-log-note (&optional _purpose)
"Pop up a window for taking a note, and add this note later."
(remove-hook 'post-command-hook 'org-add-log-note)
+ (setq org-log-setup nil)
(setq org-log-note-window-configuration (current-window-configuration))
(delete-other-windows)
(move-marker org-log-note-return-to (point))
@@ -10841,19 +10988,19 @@ EXTRA is additional text that will be inserted into the notes buffer."
(insert (format "# Insert note for %s.
# Finish with C-c C-c, or cancel with C-c C-k.\n\n"
(cl-case org-log-note-purpose
- (clock-out "stopped clock")
- (done "closed todo item")
- (reschedule "rescheduling")
- (delschedule "no longer scheduled")
- (redeadline "changing deadline")
- (deldeadline "removing deadline")
- (refile "refiling")
- (note "this entry")
- (state
- (format "state change from \"%s\" to \"%s\""
- (or org-log-note-previous-state "")
- (or org-log-note-state "")))
- (t (error "This should not happen")))))
+ (clock-out "stopped clock")
+ (done "closed todo item")
+ (reschedule "rescheduling")
+ (delschedule "no longer scheduled")
+ (redeadline "changing deadline")
+ (deldeadline "removing deadline")
+ (refile "refiling")
+ (note "this entry")
+ (state
+ (format "state change from \"%s\" to \"%s\""
+ (or org-log-note-previous-state "")
+ (or org-log-note-state "")))
+ (t (error "This should not happen")))))
(when org-log-note-extra (insert org-log-note-extra))
(setq-local org-finish-function 'org-store-log-note)
(run-hooks 'org-log-buffer-setup-hook)))
@@ -10936,19 +11083,13 @@ EXTRA is additional text that will be inserted into the notes buffer."
(indent-line-to ind)
(insert line)))
(message "Note stored")
- (org-back-to-heading t))
- ;; Fix `buffer-undo-list' when `org-store-log-note' is called
- ;; from within `org-add-log-note' because `buffer-undo-list'
- ;; is then modified outside of `org-with-remote-undo'.
- (when (eq this-command 'org-agenda-todo)
- (setcdr buffer-undo-list (cddr buffer-undo-list))))))
+ (org-back-to-heading t)))))
;; Don't add undo information when called from `org-agenda-todo'.
- (let ((buffer-undo-list (eq this-command 'org-agenda-todo)))
- (set-window-configuration org-log-note-window-configuration)
- (with-current-buffer (marker-buffer org-log-note-return-to)
- (goto-char org-log-note-return-to))
- (move-marker org-log-note-return-to nil)
- (when org-log-post-message (message "%s" org-log-post-message))))
+ (set-window-configuration org-log-note-window-configuration)
+ (with-current-buffer (marker-buffer org-log-note-return-to)
+ (goto-char org-log-note-return-to))
+ (move-marker org-log-note-return-to nil)
+ (when org-log-post-message (message "%s" org-log-post-message)))
(defun org-remove-empty-drawer-at (pos)
"Remove an empty drawer at position POS.
@@ -11182,14 +11323,18 @@ or a character."
(setq
new
(if nump
- (string-to-number
- (read-string (format "Priority %s-%s, SPC to remove: "
- (number-to-string org-priority-highest)
- (number-to-string org-priority-lowest))))
+ (let* ((msg (format "Priority %s-%s, SPC to remove: "
+ (number-to-string org-priority-highest)
+ (number-to-string org-priority-lowest)))
+ (s (if (< 9 org-priority-lowest)
+ (read-string msg)
+ (message msg)
+ (char-to-string (read-char-exclusive)))))
+ (if (equal s " ") ?\s (string-to-number s)))
(progn (message "Priority %c-%c, SPC to remove: "
- org-priority-highest org-priority-lowest)
- (save-match-data
- (setq new (read-char-exclusive)))))))
+ org-priority-highest org-priority-lowest)
+ (save-match-data
+ (setq new (read-char-exclusive)))))))
(when (and (= (upcase org-priority-highest) org-priority-highest)
(= (upcase org-priority-lowest) org-priority-lowest))
(setq new (upcase new)))
@@ -11713,7 +11858,7 @@ an accumulator used in recursive calls."
(org--tags-expand-group (cdr group) tag-groups expanded))))))
expanded)
-(defun org-tags-expand (match &optional single-as-list downcased)
+(defun org-tags-expand (match &optional single-as-list)
"Expand group tags in MATCH.
This replaces every group tag in MATCH with a regexp tag search.
@@ -11740,24 +11885,18 @@ will be replaced like this:
When the optional argument SINGLE-AS-LIST is non-nil, MATCH is
assumed to be a single group tag, and the function will return
-the list of tags in this group.
-
-When DOWNCASED is non-nil, expand downcased TAGS."
+the list of tags in this group."
(unless (org-string-nw-p match) (error "Invalid match tag: %S" match))
(let ((tag-groups
- (let ((g (or org-tag-groups-alist-for-agenda org-tag-groups-alist)))
- (if (not downcased) g
- (mapcar (lambda (s) (mapcar #'downcase s)) g)))))
+ (or org-tag-groups-alist-for-agenda org-tag-groups-alist)))
(cond
- (single-as-list (org--tags-expand-group
- (list (if downcased (downcase match) match))
- tag-groups nil))
+ (single-as-list (org--tags-expand-group (list match) tag-groups nil))
(org-group-tags
(let* ((case-fold-search t)
(tag-syntax org-mode-syntax-table)
(group-keys (mapcar #'car tag-groups))
(key-regexp (concat "\\([+-]?\\)" (regexp-opt group-keys 'words)))
- (return-match (if downcased (downcase match) match)))
+ (return-match match))
;; Mark regexp-expressions in the match-expression so that we
;; do not replace them later on.
(let ((s 0))
@@ -11777,7 +11916,7 @@ When DOWNCASED is non-nil, expand downcased TAGS."
m ;regexp tag: ignore
(let* ((operator (match-string 1 m))
(tag-token (let ((tag (match-string 2 m)))
- (list (if downcased (downcase tag) tag))))
+ (list tag)))
regexp-tags regular-tags)
;; Partition tags between regexp and regular tags.
;; Remove curly bracket syntax from regexp tags.
@@ -11928,12 +12067,15 @@ in Lisp code use `org-set-tags' instead."
inherited-tags
table
(and org-fast-tag-selection-include-todo org-todo-key-alist))
- (let ((org-add-colon-after-tag-completion (< 1 (length table))))
- (org-trim (completing-read
- "Tags: "
- #'org-tags-completion-function
- nil nil (org-make-tag-string current-tags)
- 'org-tags-history)))))))
+ (let ((org-add-colon-after-tag-completion (< 1 (length table)))
+ (crm-separator "[ \t]*:[ \t]*"))
+ (mapconcat #'identity
+ (completing-read-multiple
+ "Tags: "
+ org-last-tags-completion-table
+ nil nil (org-make-tag-string current-tags)
+ 'org-tags-history)
+ ":"))))))
(org-set-tags tags)))))
;; `save-excursion' may not replace the point at the right
;; position.
@@ -12013,7 +12155,7 @@ This works in the agenda, and also in an Org buffer."
(org-global-tags-completion-table))
(org-global-tags-completion-table))))
(completing-read
- "Tag: " 'org-tags-completion-function nil nil nil
+ "Tag: " org-last-tags-completion-table nil nil nil
'org-tags-history))
(progn
(message "[s]et or [r]emove? ")
@@ -12109,7 +12251,7 @@ Returns the new tags string, or nil to not change the current settings."
fulltable))))
(buf (current-buffer))
(expert (eq org-fast-tag-selection-single-key 'expert))
- (buffer-tags nil)
+ (tab-tags nil)
(fwidth (+ maxlen 3 1 3))
(ncol (/ (- (window-width) 4) fwidth))
(i-face 'org-done)
@@ -12244,16 +12386,21 @@ Returns the new tags string, or nil to not change the current settings."
(setq current nil)
(when exit-after-next (setq exit-after-next 'now)))
((= c ?\t)
- (condition-case nil
- (setq tg (completing-read
- "Tag: "
- (or buffer-tags
- (with-current-buffer buf
- (setq buffer-tags
- (org-get-buffer-tags))))))
- (quit (setq tg "")))
+ (condition-case nil
+ (unless tab-tags
+ (setq tab-tags
+ (delq nil
+ (mapcar (lambda (x)
+ (let ((item (car-safe x)))
+ (and (stringp item)
+ (list item))))
+ (org--tag-add-to-alist
+ (with-current-buffer buf
+ (org-get-buffer-tags))
+ table))))))
+ (setq tg (completing-read "Tag: " tab-tags))
(when (string-match "\\S-" tg)
- (cl-pushnew (list tg) buffer-tags :test #'equal)
+ (cl-pushnew (list tg) tab-tags :test #'equal)
(if (member tg current)
(setq current (delete tg current))
(push tg current)))
@@ -12361,12 +12508,12 @@ Inherited tags have the `inherited' text property."
(defun org-map-entries (func &optional match scope &rest skip)
"Call FUNC at each headline selected by MATCH in SCOPE.
-FUNC is a function or a lisp form. The function will be called without
+FUNC is a function or a Lisp form. The function will be called without
arguments, with the cursor positioned at the beginning of the headline.
The return values of all calls to the function will be collected and
returned as a list.
-The call to FUNC will be wrapped into a save-excursion form, so FUNC
+The call to FUNC will be wrapped into a `save-excursion' form, so FUNC
does not need to preserve point. After evaluation, the cursor will be
moved to the end of the line (presumably of the headline of the
processed entry) and search continues from there. Under some
@@ -12537,12 +12684,12 @@ it will be found. If the drawer does not exist, create it if
FORCE is non-nil, or return nil."
(org-with-wide-buffer
(let ((beg (cond (beg (goto-char beg))
- ((or (not (featurep 'org-inlinetask))
- (org-inlinetask-in-task-p))
- (org-back-to-heading-or-point-min t) (point))
- (t (org-with-limited-levels
- (org-back-to-heading-or-point-min t))
- (point)))))
+ ((or (not (featurep 'org-inlinetask))
+ (org-inlinetask-in-task-p))
+ (org-back-to-heading-or-point-min t) (point))
+ (t (org-with-limited-levels
+ (org-back-to-heading-or-point-min t))
+ (point)))))
;; Move point to its position according to its positional rules.
(cond ((org-before-first-heading-p)
(while (and (org-at-comment-p) (bolp)) (forward-line)))
@@ -13064,62 +13211,63 @@ decreases scheduled or deadline date by one day."
((not (stringp value)) (error "Properties values should be strings"))
((not (org--valid-property-p property))
(user-error "Invalid property name: \"%s\"" property)))
- (org-with-point-at pom
- (if (or (not (featurep 'org-inlinetask)) (org-inlinetask-in-task-p))
- (org-back-to-heading-or-point-min t)
- (org-with-limited-levels (org-back-to-heading-or-point-min t)))
- (let ((beg (point)))
- (cond
- ((equal property "TODO")
- (cond ((not (org-string-nw-p value)) (setq value 'none))
- ((not (member value org-todo-keywords-1))
- (user-error "\"%s\" is not a valid TODO state" value)))
- (org-todo value)
- (org-align-tags))
- ((equal property "PRIORITY")
- (org-priority (if (org-string-nw-p value) (string-to-char value) ?\s))
- (org-align-tags))
- ((equal property "SCHEDULED")
- (forward-line)
- (if (and (looking-at-p org-planning-line-re)
- (re-search-forward
- org-scheduled-time-regexp (line-end-position) t))
- (cond ((string= value "earlier") (org-timestamp-change -1 'day))
- ((string= value "later") (org-timestamp-change 1 'day))
- ((string= value "") (org-schedule '(4)))
- (t (org-schedule nil value)))
- (if (member value '("earlier" "later" ""))
- (call-interactively #'org-schedule)
- (org-schedule nil value))))
- ((equal property "DEADLINE")
- (forward-line)
- (if (and (looking-at-p org-planning-line-re)
- (re-search-forward
- org-deadline-time-regexp (line-end-position) t))
- (cond ((string= value "earlier") (org-timestamp-change -1 'day))
- ((string= value "later") (org-timestamp-change 1 'day))
- ((string= value "") (org-deadline '(4)))
- (t (org-deadline nil value)))
- (if (member value '("earlier" "later" ""))
- (call-interactively #'org-deadline)
- (org-deadline nil value))))
- ((member property org-special-properties)
- (error "The %s property cannot be set with `org-entry-put'" property))
- (t
- (let* ((range (org-get-property-block beg 'force))
- (end (cdr range))
- (case-fold-search t))
- (goto-char (car range))
- (if (re-search-forward (org-re-property property nil t) end t)
- (progn (delete-region (match-beginning 0) (match-end 0))
- (goto-char (match-beginning 0)))
- (goto-char end)
- (insert "\n")
- (backward-char))
- (insert ":" property ":")
- (when value (insert " " value))
- (org-indent-line)))))
- (run-hook-with-args 'org-property-changed-functions property value)))
+ (org-no-read-only
+ (org-with-point-at pom
+ (if (or (not (featurep 'org-inlinetask)) (org-inlinetask-in-task-p))
+ (org-back-to-heading-or-point-min t)
+ (org-with-limited-levels (org-back-to-heading-or-point-min t)))
+ (let ((beg (point)))
+ (cond
+ ((equal property "TODO")
+ (cond ((not (org-string-nw-p value)) (setq value 'none))
+ ((not (member value org-todo-keywords-1))
+ (user-error "\"%s\" is not a valid TODO state" value)))
+ (org-todo value)
+ (org-align-tags))
+ ((equal property "PRIORITY")
+ (org-priority (if (org-string-nw-p value) (string-to-char value) ?\s))
+ (org-align-tags))
+ ((equal property "SCHEDULED")
+ (forward-line)
+ (if (and (looking-at-p org-planning-line-re)
+ (re-search-forward
+ org-scheduled-time-regexp (line-end-position) t))
+ (cond ((string= value "earlier") (org-timestamp-change -1 'day))
+ ((string= value "later") (org-timestamp-change 1 'day))
+ ((string= value "") (org-schedule '(4)))
+ (t (org-schedule nil value)))
+ (if (member value '("earlier" "later" ""))
+ (call-interactively #'org-schedule)
+ (org-schedule nil value))))
+ ((equal property "DEADLINE")
+ (forward-line)
+ (if (and (looking-at-p org-planning-line-re)
+ (re-search-forward
+ org-deadline-time-regexp (line-end-position) t))
+ (cond ((string= value "earlier") (org-timestamp-change -1 'day))
+ ((string= value "later") (org-timestamp-change 1 'day))
+ ((string= value "") (org-deadline '(4)))
+ (t (org-deadline nil value)))
+ (if (member value '("earlier" "later" ""))
+ (call-interactively #'org-deadline)
+ (org-deadline nil value))))
+ ((member property org-special-properties)
+ (error "The %s property cannot be set with `org-entry-put'" property))
+ (t
+ (let* ((range (org-get-property-block beg 'force))
+ (end (cdr range))
+ (case-fold-search t))
+ (goto-char (car range))
+ (if (re-search-forward (org-re-property property nil t) end t)
+ (progn (delete-region (match-beginning 0) (match-end 0))
+ (goto-char (match-beginning 0)))
+ (goto-char end)
+ (insert "\n")
+ (backward-char))
+ (insert ":" property ":")
+ (when value (insert " " value))
+ (org-indent-line)))))
+ (run-hook-with-args 'org-property-changed-functions property value))))
(defun org-buffer-property-keys (&optional specials defaults columns)
"Get all property keys in the current buffer.
@@ -13309,11 +13457,12 @@ This is computed according to `org-property-set-functions-alist'."
(or (cdr (assoc property org-property-set-functions-alist))
'org-completing-read))
-(defun org-read-property-value (property &optional pom)
+(defun org-read-property-value (property &optional pom default)
"Read value for PROPERTY, as a string.
When optional argument POM is non-nil, completion uses additional
information, i.e., allowed or existing values at point or marker
-POM."
+POM.
+Optional argument DEFAULT provides a default value for PROPERTY."
(let* ((completion-ignore-case t)
(allowed
(or (org-property-get-allowed-values nil property 'table)
@@ -13329,7 +13478,8 @@ POM."
(if allowed
(funcall set-function
prompt allowed nil
- (not (get-text-property 0 'org-unrestricted (caar allowed))))
+ (not (get-text-property 0 'org-unrestricted (caar allowed)))
+ default nil default)
(let ((all (mapcar #'list
(append (org-property-values property)
(and pom
@@ -13655,7 +13805,7 @@ If there is already a timestamp at the cursor, it is replaced.
With two universal prefix arguments, insert an active timestamp
with the current time without prompting the user.
-When called from lisp, the timestamp is inactive if INACTIVE is
+When called from Lisp, the timestamp is inactive if INACTIVE is
non-nil."
(interactive "P")
(let* ((ts (cond
@@ -13837,7 +13987,7 @@ user."
(when (< (nth 2 org-defdecode) org-extend-today-until)
(setf (nth 2 org-defdecode) -1)
(setf (nth 1 org-defdecode) 59)
- (setq org-def (apply #'encode-time org-defdecode))
+ (setq org-def (encode-time org-defdecode))
(setq org-defdecode (decode-time org-def)))
(let* ((timestr (format-time-string
(if org-with-time "%Y-%m-%d %H:%M" "%Y-%m-%d")
@@ -14047,6 +14197,19 @@ user."
(setq ans (replace-match (format "%02d:%02d" hour minute)
t t ans))))
+ ;; Help matching HHhMM times, similarly as for am/pm times.
+ (cl-loop for i from 1 to 2 do ; twice, for end time as well
+ (when (and (not (string-match "\\(\\`\\|[^+]\\)[012]?[0-9]:[0-9][0-9]\\([ \t\n]\\|$\\)" ans))
+ (string-match "\\(?:\\(?1:[012]?[0-9]\\)?h\\(?2:[0-5][0-9]\\)\\)\\|\\(?:\\(?1:[012]?[0-9]\\)h\\(?2:[0-5][0-9]\\)?\\)\\>" ans))
+ (setq hour (if (match-end 1)
+ (string-to-number (match-string 1 ans))
+ 0)
+ minute (if (match-end 2)
+ (string-to-number (match-string 2 ans))
+ 0))
+ (setq ans (replace-match (format "%02d:%02d" hour minute)
+ t t ans))))
+
;; Check if a time range is given as a duration
(when (string-match "\\([012]?[0-9]\\):\\([0-6][0-9]\\)\\+\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)?" ans)
(setq hour (string-to-number (match-string 1 ans))
@@ -14308,7 +14471,7 @@ The command returns the inserted time stamp."
time (org-fix-decoded-time t1)
str (org-add-props
(format-time-string
- (substring tf 1 -1) (apply 'encode-time time))
+ (substring tf 1 -1) (encode-time time))
nil 'mouse-face 'highlight))
(put-text-property beg end 'display str)))
@@ -14563,7 +14726,7 @@ days in order to avoid rounding problems."
(defun org-time-string-to-time (s)
"Convert timestamp string S into internal time."
- (apply #'encode-time (org-parse-time-string s)))
+ (encode-time (org-parse-time-string s)))
(defun org-time-string-to-seconds (s)
"Convert a timestamp string S into a number of seconds."
@@ -14993,7 +15156,7 @@ When SUPPRESS-TMP-DELAY is non-nil, suppress delays like
(setcar time0 (or (car time0) 0))
(setcar (nthcdr 1 time0) (or (nth 1 time0) 0))
(setcar (nthcdr 2 time0) (or (nth 2 time0) 0))
- (setq time (apply 'encode-time time0))))
+ (setq time (encode-time time0))))
;; Insert the new time-stamp, and ensure point stays in the same
;; category as before (i.e. not after the last position in that
;; category).
@@ -15201,7 +15364,7 @@ The value is a list, with zero or more of the symbols `effort', `appt',
"Save all Org buffers without user confirmation."
(interactive)
(message "Saving all Org buffers...")
- (save-some-buffers t (lambda () (derived-mode-p 'org-mode)))
+ (save-some-buffers t (lambda () (and (derived-mode-p 'org-mode) t)))
(when (featurep 'org-id) (org-id-locations-save))
(message "Saving all Org buffers... done"))
@@ -15215,9 +15378,9 @@ This function is useful in a setup where one tracks Org files
with a version control system, to revert on one machine after pulling
changes from another. I believe the procedure must be like this:
-1. M-x org-save-all-org-buffers
+1. \\[org-save-all-org-buffers]
2. Pull changes from the other machine, resolve conflicts
-3. M-x org-revert-all-org-buffers"
+3. \\[org-revert-all-org-buffers]"
(interactive)
(unless (yes-or-no-p "Revert all Org buffers from their files? ")
(user-error "Abort"))
@@ -15306,13 +15469,12 @@ used by the agenda files. If ARCHIVE is `ifmode', do this only if
(if (file-directory-p f)
(directory-files
f t org-agenda-file-regexp)
- (list f)))
+ (list (expand-file-name f org-directory))))
files)))
(when org-agenda-skip-unavailable-files
(setq files (delq nil
- (mapcar (function
- (lambda (file)
- (and (file-readable-p file) file)))
+ (mapcar (lambda (file)
+ (and (file-readable-p file) file))
files))))
(when (or (eq archives t)
(and (eq archives 'ifmode) (eq org-agenda-archives-mode t)))
@@ -15928,15 +16090,25 @@ Some of the options can be changed using the variable
(fg
(let ((color (plist-get org-format-latex-options
:foreground)))
- (if (and forbuffer (eq color 'auto))
- (face-attribute face :foreground nil 'default)
- color)))
+ (if forbuffer
+ (cond
+ ((eq color 'auto)
+ (face-attribute face :foreground nil 'default))
+ ((eq color 'default)
+ (face-attribute 'default :foreground nil))
+ (t color))
+ color)))
(bg
(let ((color (plist-get org-format-latex-options
:background)))
- (if (and forbuffer (eq color 'auto))
- (face-attribute face :background nil 'default)
- color)))
+ (if forbuffer
+ (cond
+ ((eq color 'auto)
+ (face-attribute face :background nil 'default))
+ ((eq color 'default)
+ (face-attribute 'default :background nil))
+ (t color))
+ color)))
(hash (sha1 (prin1-to-string
(list org-format-latex-header
org-latex-default-packages-alist
@@ -16155,10 +16327,10 @@ a HTML file."
(if (eq fg 'default)
(setq fg (org-latex-color :foreground))
(setq fg (org-latex-color-format fg)))
- (if (eq bg 'default)
- (setq bg (org-latex-color :background))
- (setq bg (org-latex-color-format
- (if (string= bg "Transparent") "white" bg))))
+ (setq bg (cond
+ ((eq bg 'default) (org-latex-color :background))
+ ((string= bg "Transparent") nil)
+ (t (org-latex-color-format bg))))
;; Remove TeX \par at end of snippet to avoid trailing space.
(if (string-suffix-p string "\n")
(aset string (1- (length string)) ?%)
@@ -16167,8 +16339,10 @@ a HTML file."
(insert latex-header)
(insert "\n\\begin{document}\n"
"\\definecolor{fg}{rgb}{" fg "}%\n"
- "\\definecolor{bg}{rgb}{" bg "}%\n"
- "\n\\pagecolor{bg}%\n"
+ (if bg
+ (concat "\\definecolor{bg}{rgb}{" bg "}%\n"
+ "\n\\pagecolor{bg}%\n")
+ "")
"\n{\\color{fg}\n"
string
"\n}\n"
@@ -16438,30 +16612,7 @@ buffer boundaries with possible narrowing."
(ignore-errors (org-attach-expand path)))
(expand-file-name path))))
(when (and file (file-exists-p file))
- (let ((width
- ;; Apply `org-image-actual-width' specifications.
- (cond
- ((eq org-image-actual-width t) nil)
- ((listp org-image-actual-width)
- (or
- ;; First try to find a width among
- ;; attributes associated to the paragraph
- ;; containing link.
- (pcase (org-element-lineage link '(paragraph))
- (`nil nil)
- (p
- (let* ((case-fold-search t)
- (end (org-element-property :post-affiliated p))
- (re "^[ \t]*#\\+attr_.*?: +.*?:width +\\(\\S-+\\)"))
- (when (org-with-point-at
- (org-element-property :begin p)
- (re-search-forward re end t))
- (string-to-number (match-string 1))))))
- ;; Otherwise, fall-back to provided number.
- (car org-image-actual-width)))
- ((numberp org-image-actual-width)
- org-image-actual-width)
- (t nil)))
+ (let ((width (org-display-inline-image--width link))
(old (get-char-property-and-overlay
(org-element-property :begin link)
'org-image-overlay)))
@@ -16482,11 +16633,62 @@ buffer boundaries with possible narrowing."
(overlay-put
ov 'modification-hooks
(list 'org-display-inline-remove-overlay))
- (when (<= 26 emacs-major-version)
- (cl-assert (boundp 'image-map))
+ (when (boundp 'image-map)
(overlay-put ov 'keymap image-map))
(push ov org-inline-image-overlays))))))))))))))))
+(defvar visual-fill-column-width) ; Silence compiler warning
+(defun org-display-inline-image--width (link)
+ "Determine the display width of the image LINK, in pixels.
+- When `org-image-actual-width' is t, the image's pixel width is used.
+- When `org-image-actual-width' is a number, that value will is used.
+- When `org-image-actual-width' is nil or a list, the first :width attribute
+ set (if it exists) is used to set the image width. A width of X% is
+ divided by 100.
+ If no :width attribute is given and `org-image-actual-width' is a list with
+ a number as the car, then that number is used as the default value.
+ If the value is a float between 0 and 2, it interpreted as that proportion
+ of the text width in the buffer."
+ ;; Apply `org-image-actual-width' specifications.
+ (cond
+ ((eq org-image-actual-width t) nil)
+ ((listp org-image-actual-width)
+ (let* ((case-fold-search t)
+ (par (org-element-lineage link '(paragraph)))
+ (attr-re "^[ \t]*#\\+attr_.*?: +.*?:width +\\(\\S-+\\)")
+ (par-end (org-element-property :post-affiliated par))
+ ;; Try to find an attribute providing a :width.
+ (attr-width
+ (when (and par (org-with-point-at
+ (org-element-property :begin par)
+ (re-search-forward attr-re par-end t)))
+ (match-string 1)))
+ (attr-width-val
+ (cond
+ ((null attr-width) nil)
+ ((string-match-p "\\`[0-9.]+%" attr-width)
+ (/ (string-to-number attr-width) 100.0))
+ (t (string-to-number attr-width))))
+ ;; Fallback to `org-image-actual-width' if no explicit width is given.
+ (width (or attr-width-val (car org-image-actual-width))))
+ (if (and (floatp width) (<= 0.0 width 2.0))
+ ;; A float in [0,2] should be interpereted as this portion of
+ ;; the text width in the window. This works well with cases like
+ ;; #+attr_latex: :width 0.X\{line,page,column,etc.}width,
+ ;; as the "0.X" is pulled out as a float. We use 2 as the upper
+ ;; bound as cases such as 1.2\linewidth are feasible.
+ (round (* width
+ (window-pixel-width)
+ (/ (or (and (bound-and-true-p visual-fill-column-mode)
+ (or visual-fill-column-width auto-fill-function))
+ (when auto-fill-function fill-column)
+ (window-text-width))
+ (float (window-total-width)))))
+ width)))
+ ((numberp org-image-actual-width)
+ org-image-actual-width)
+ (t nil)))
+
(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))
@@ -16708,6 +16910,7 @@ because, in this case the deletion might narrow the column."
(put 'org-delete-char 'delete-selection 'supersede)
(put 'org-delete-backward-char 'delete-selection 'supersede)
(put 'org-yank 'delete-selection 'yank)
+(put 'org-return 'delete-selection t)
;; Make `flyspell-mode' delay after some commands
(put 'org-self-insert-command 'flyspell-delayed t)
@@ -16869,7 +17072,8 @@ When ARG is a numeric prefix, show contents of this level."
(message "Content view to level: %d" arg)
(org-content (prefix-numeric-value arg2))
(org-cycle-show-empty-lines t)
- (setq org-cycle-global-status 'overview)))
+ (setq org-cycle-global-status 'overview)
+ (run-hook-with-args 'org-cycle-hook 'overview)))
(t (call-interactively 'org-global-cycle))))
(defun org-shiftmetaleft ()
@@ -17061,6 +17265,9 @@ for more information."
(transpose-regions a b c d)
(goto-char c)))
((org-at-table-p) (org-call-with-arg 'org-table-move-row 'up))
+ ((and (featurep 'org-inlinetask)
+ (org-inlinetask-in-task-p))
+ (org-drag-element-backward))
((org-at-heading-p) (call-interactively 'org-move-subtree-up))
((org-at-item-p) (call-interactively 'org-move-item-up))
(t (org-drag-element-backward))))
@@ -17091,6 +17298,9 @@ commands for more information."
(transpose-regions a b c d)
(goto-char d)))
((org-at-table-p) (call-interactively 'org-table-move-row))
+ ((and (featurep 'org-inlinetask)
+ (org-inlinetask-in-task-p))
+ (org-drag-element-forward))
((org-at-heading-p) (call-interactively 'org-move-subtree-down))
((org-at-item-p) (call-interactively 'org-move-item-down))
(t (org-drag-element-forward))))
@@ -17354,7 +17564,7 @@ When in a source code block, call `org-edit-src-code'.
When in a fixed-width region, call `org-edit-fixed-width-region'.
When in an export block, call `org-edit-export-block'.
When in a LaTeX environment, call `org-edit-latex-environment'.
-When at an #+INCLUDE keyword, visit the included file.
+When at an INCLUDE, SETUPFILE or BIBLIOGRAPHY keyword, visit the included file.
When at a footnote reference, call `org-edit-footnote-reference'.
When at a planning line call, `org-deadline' and/or `org-schedule'.
When at an active timestamp, call `org-time-stamp'.
@@ -17380,14 +17590,14 @@ Otherwise, return a user error."
session params))))))
(`keyword
(unless (member (org-element-property :key element)
- '("INCLUDE" "SETUPFILE"))
+ '("BIBLIOGRAPHY" "INCLUDE" "SETUPFILE"))
(user-error "No special environment to edit here"))
(let ((value (org-element-property :value element)))
(unless (org-string-nw-p value) (user-error "No file to edit"))
(let ((file (and (string-match "\\`\"\\(.*?\\)\"\\|\\S-+" value)
(or (match-string 1 value)
(match-string 0 value)))))
- (when (org-file-url-p file)
+ (when (org-url-p file)
(user-error "Files located with a URL cannot be edited"))
(org-link-open-from-string
(format "[[%s]]" (expand-file-name file))))))
@@ -17632,28 +17842,35 @@ This command does many different things, depending on context:
(`statistics-cookie
(call-interactively #'org-update-statistics-cookies))
((or `table `table-cell `table-row)
- ;; At a table, recalculate every field and align it. Also
- ;; send the table if necessary. If the table has
- ;; a `table.el' type, just give up. At a table row or cell,
- ;; maybe recalculate line but always align table.
- (if (eq (org-element-property :type context) 'table.el)
- (message "%s" (substitute-command-keys "\\<org-mode-map>\
-Use `\\[org-edit-special]' to edit table.el tables"))
- (if (or (eq type 'table)
- ;; Check if point is at a TBLFM line.
- (and (eq type 'table-row)
- (= (point) (org-element-property :end context))))
- (save-excursion
- (if (org-at-TBLFM-p)
- (progn (require 'org-table)
- (org-table-calc-current-TBLFM))
- (goto-char (org-element-property :contents-begin context))
- (org-call-with-arg 'org-table-recalculate (or arg t))
- (orgtbl-send-table 'maybe)))
- (org-table-maybe-eval-formula)
- (cond (arg (call-interactively #'org-table-recalculate))
- ((org-table-maybe-recalculate-line))
- (t (org-table-align))))))
+ ;; At a table, generate a plot if on the #+plot line,
+ ;; recalculate every field and align it otherwise. Also
+ ;; send the table if necessary.
+ (cond
+ ((and (org-match-line "[ \t]*#\\+plot:")
+ (< (point) (org-element-property :post-affiliated context)))
+ (org-plot/gnuplot))
+ ;; If the table has a `table.el' type, just give up.
+ ((eq (org-element-property :type context) 'table.el)
+ (message "%s" (substitute-command-keys "\\<org-mode-map>\
+Use `\\[org-edit-special]' to edit table.el tables")))
+ ;; At a table row or cell, maybe recalculate line but always
+ ;; align table.
+ ((or (eq type 'table)
+ ;; Check if point is at a TBLFM line.
+ (and (eq type 'table-row)
+ (= (point) (org-element-property :end context))))
+ (save-excursion
+ (if (org-at-TBLFM-p)
+ (progn (require 'org-table)
+ (org-table-calc-current-TBLFM))
+ (goto-char (org-element-property :contents-begin context))
+ (org-call-with-arg 'org-table-recalculate (or arg t))
+ (orgtbl-send-table 'maybe))))
+ (t
+ (org-table-maybe-eval-formula)
+ (cond (arg (call-interactively #'org-table-recalculate))
+ ((org-table-maybe-recalculate-line))
+ (t (org-table-align))))))
((or `timestamp (and `planning (guard (org-at-timestamp-p 'lax))))
(org-timestamp-change 0 'day))
((and `nil (guard (org-at-heading-p)))
@@ -17668,7 +17885,7 @@ Use `\\[org-edit-special]' to edit table.el tables"))
"`\\[org-ctrl-c-ctrl-c]' can do nothing useful here"))))))))
(defun org-mode-restart ()
-"Restart `org-mode'."
+ "Restart `org-mode'."
(interactive)
(let ((indent-status (bound-and-true-p org-indent-mode)))
(funcall major-mode)
@@ -17783,12 +18000,13 @@ will not happen if point is in a table or on a \"dead\"
object (e.g., within a comment). In these case, you need to use
`org-open-at-point' directly."
(interactive "i\nP\np")
- (let ((context (if org-return-follows-link (org-element-context)
- (org-element-at-point))))
+ (let* ((context (if org-return-follows-link (org-element-context)
+ (org-element-at-point)))
+ (element-type (org-element-type context)))
(cond
;; In a table, call `org-table-next-row'. However, before first
;; column or after last one, split the table.
- ((or (and (eq 'table (org-element-type context))
+ ((or (and (eq 'table element-type)
(not (eq 'table.el (org-element-property :type context)))
(>= (point) (org-element-property :contents-begin context))
(< (point) (org-element-property :contents-end context)))
@@ -17802,7 +18020,7 @@ object (e.g., within a comment). In these case, you need to use
;; `org-return-follows-link' allows it. Tolerate fuzzy
;; locations, e.g., in a comment, as `org-open-at-point'.
((and org-return-follows-link
- (or (and (eq 'link (org-element-type context))
+ (or (and (eq 'link element-type)
;; Ensure point is not on the white spaces after
;; the link.
(let ((origin (point)))
@@ -17849,12 +18067,13 @@ object (e.g., within a comment). In these case, you need to use
(org--newline indent arg interactive))))))
(defun org-return-and-maybe-indent ()
- "Goto next table row, or insert a newline.
+ "Goto next table row, or insert a newline, maybe indented.
Call `org-table-next-row' or `org-return', depending on context.
See the individual commands for more information.
-When inserting a newline, indent the new line if
-`electric-indent-mode' is disabled."
+When inserting a newline, if `org-adapt-indentation' is t:
+indent the line if `electric-indent-mode' is disabled, don't
+indent it if it is enabled."
(interactive)
(org-return (not electric-indent-mode)))
@@ -17928,15 +18147,14 @@ when a numeric prefix argument is given, its value determines the
number of stars to add."
(interactive "P")
(let ((skip-blanks
- (function
- ;; Return beginning of first non-blank line, starting from
- ;; line at POS.
- (lambda (pos)
- (save-excursion
- (goto-char pos)
- (while (org-at-comment-p) (forward-line))
- (skip-chars-forward " \r\t\n")
- (point-at-bol)))))
+ ;; Return beginning of first non-blank line, starting from
+ ;; line at POS.
+ (lambda (pos)
+ (save-excursion
+ (goto-char pos)
+ (while (org-at-comment-p) (forward-line))
+ (skip-chars-forward " \r\t\n")
+ (point-at-bol))))
beg end toggled)
;; Determine boundaries of changes. If a universal prefix has
;; been given, put the list in a region. If region ends at a bol,
@@ -18023,7 +18241,7 @@ an argument, unconditionally call `org-insert-heading'."
(not (org-at-table-p))))
;; Define the Org mode menus
-(easy-menu-define org-org-menu org-mode-map "Org menu"
+(easy-menu-define org-org-menu org-mode-map "Org menu."
`("Org"
("Show/Hide"
["Cycle Visibility" org-cycle :active (or (bobp) (outline-on-heading-p))]
@@ -18208,7 +18426,7 @@ an argument, unconditionally call `org-insert-heading'."
["Reload Org (after update)" org-reload t]
["Reload Org uncompiled" (org-reload t) :active t :keys "C-u C-c C-x !"])))
-(easy-menu-define org-tbl-menu org-mode-map "Org Table menu"
+(easy-menu-define org-tbl-menu org-mode-map "Org Table menu."
'("Table"
["Align" org-ctrl-c-ctrl-c :active (org-at-table-p)]
["Next Field" org-cycle (org-at-table-p)]
@@ -18349,7 +18567,7 @@ Your bug report will be posted to the Org mailing list.
------------------------------------------------------------------------")
(save-excursion
(when (re-search-backward "^\\(Subject: \\)Org mode version \\(.*?\\);[ \t]*\\(.*\\)" nil t)
- (replace-match "\\1Bug: \\3 [\\2]")))))
+ (replace-match "\\1[BUG] \\3 [\\2]")))))
(defun org-install-agenda-files-menu ()
@@ -18823,11 +19041,6 @@ ELEMENT."
(t
(goto-char start)
(current-indentation))))
- ((and
- (eq org-adapt-indentation 'headline-data)
- (memq type '(planning clock node-property property-drawer drawer)))
- (org--get-expected-indentation
- (org-element-property :parent element) t))
((memq type '(headline inlinetask nil))
(if (org-match-line "[ \t]*$")
(org--get-expected-indentation element t)
@@ -18867,7 +19080,7 @@ ELEMENT."
(org--get-expected-indentation
(org-element-property :parent previous) t))))))))))
;; Otherwise, move to the first non-blank line above.
- ((not (eq org-adapt-indentation 'headline-data))
+ (t
(beginning-of-line)
(let ((pos (point)))
(skip-chars-backward " \r\t\n")
@@ -18944,7 +19157,7 @@ Indentation is done according to the following rules:
Else, indent like parent's first line.
3. Otherwise, indent relatively to current level, if
- `org-adapt-indentation' is non-nil, or to left margin.
+ `org-adapt-indentation' is t, or to left margin.
- On a blank line at the end of an element, indent according to
the type of the element. More precisely
@@ -18969,7 +19182,15 @@ list structure. Instead, use \\<org-mode-map>`\\[org-shiftmetaleft]' or \
Also align node properties according to `org-property-format'."
(interactive)
- (unless (org-at-heading-p)
+ (unless (or (org-at-heading-p)
+ (and (eq org-adapt-indentation 'headline-data)
+ (not (or (org-at-clock-log-p)
+ (org-at-planning-p)))
+ (save-excursion
+ (beginning-of-line 1)
+ (skip-chars-backward "\n")
+ (or (org-at-heading-p)
+ (looking-back ":END:.*" (point-at-bol))))))
(let* ((element (save-excursion (beginning-of-line) (org-element-at-point)))
(type (org-element-type element)))
(cond ((and (memq type '(plain-list item))
@@ -18991,6 +19212,21 @@ Also align node properties according to `org-property-format'."
(org-with-point-at (org-element-property :end element)
(skip-chars-backward " \t\n")
(line-beginning-position))))
+ ;; At the beginning of a blank line, do some preindentation. This
+ ;; signals org-src--edit-element to preserve the indentation on exit
+ (when (and (looking-at-p "^[[:space:]]*$")
+ (not org-src-preserve-indentation))
+ (let ((element (org-element-at-point))
+ block-content-ind some-ind)
+ (org-with-point-at (org-element-property :begin element)
+ (setq block-content-ind (+ (current-indentation)
+ org-edit-src-content-indentation))
+ (forward-line)
+ (save-match-data (re-search-forward "^[ \t]*\\S-" nil t))
+ (backward-char)
+ (setq some-ind (if (looking-at-p "#\\+end_src")
+ block-content-ind (current-indentation))))
+ (indent-line-to (min block-content-ind some-ind))))
(org-babel-do-key-sequence-in-edit-buffer (kbd "TAB")))
(t
(let ((column (org--get-expected-indentation element nil)))
@@ -19297,7 +19533,11 @@ a footnote definition, try to fill the first paragraph within."
;; the buffer. In that case, ignore filling.
(cl-case (org-element-type element)
;; Use major mode filling function is source blocks.
- (src-block (org-babel-do-key-sequence-in-edit-buffer (kbd "M-q")))
+ (src-block (org-babel-do-in-edit-buffer
+ (push-mark (point-min))
+ (goto-char (point-max))
+ (setq mark-active t)
+ (funcall-interactively #'fill-paragraph justify 'region)))
;; Align Org tables, leave table.el tables as-is.
(table-row (org-table-align) t)
(table
@@ -19432,7 +19672,9 @@ filling the current element."
;; previously unmodified), then flip the modification status back
;; to "unchanged".
(when (and hash (equal hash (org-buffer-hash)))
- (set-buffer-modified-p nil))))
+ (set-buffer-modified-p nil))
+ ;; Return non-nil.
+ t))
(defun org-auto-fill-function ()
"Auto-fill function."
@@ -19651,15 +19893,15 @@ When BLOCK-REGEXP is non-nil, use this regexp to find blocks."
;; example-block) don't accept comments. Usual Emacs comment commands
;; cannot cope with those requirements. Therefore, Org replaces them.
-;; Org still relies on `comment-dwim', but cannot trust
-;; `comment-only-p'. So, `comment-region-function' and
-;; `uncomment-region-function' both point
-;; to`org-comment-or-uncomment-region'. Eventually,
-;; `org-insert-comment' takes care of insertion of comments at the
+;; Org still relies on 'comment-dwim', but cannot trust
+;; 'comment-only-p'. So, 'comment-region-function' and
+;; 'uncomment-region-function' both point
+;; to 'org-comment-or-uncomment-region'. Eventually,
+;; 'org-insert-comment' takes care of insertion of comments at the
;; beginning of line.
-;; `org-setup-comments-handling' install comments related variables
-;; during `org-mode' initialization.
+;; 'org-setup-comments-handling' install comments related variables
+;; during 'org-mode' initialization.
(defun org-setup-comments-handling ()
(interactive)
@@ -19901,7 +20143,7 @@ it has a `diary' type."
(defvar org--rds)
(defun org-reftex-citation ()
- "Use reftex-citation to insert a citation into the buffer.
+ "Use `reftex-citation' to insert a citation into the buffer.
This looks for a line like
#+BIBLIOGRAPHY: foo plain option:-d
@@ -20221,7 +20463,7 @@ interactive command with similar behavior."
(call-interactively command))))))
(defun org-yank-folding-would-swallow-text (beg end)
- "Would hide-subtree at BEG swallow any text after END?"
+ "Would `hide-subtree' at BEG swallow any text after END?"
(let (level)
(org-with-limited-levels
(save-excursion
@@ -20337,6 +20579,10 @@ This function considers both visible and invisible heading lines.
With argument, move up ARG levels."
(outline-up-heading arg t))
+(defvar-local org--up-heading-cache nil
+ "Buffer-local `org-up-heading-safe' cache.")
+(defvar-local org--up-heading-cache-tick nil
+ "Buffer `buffer-chars-modified-tick' in `org--up-heading-cache'.")
(defun org-up-heading-safe ()
"Move to the heading line of which the present line is a subheading.
This version will not throw an error. It will return the level of the
@@ -20346,10 +20592,28 @@ Also, this function will be a lot faster than `outline-up-heading',
because it relies on stars being the outline starters. This can really
make a significant difference in outlines with very many siblings."
(when (ignore-errors (org-back-to-heading t))
- (let ((level-up (1- (funcall outline-level))))
- (and (> level-up 0)
- (re-search-backward (format "^\\*\\{1,%d\\} " level-up) nil t)
- (funcall outline-level)))))
+ (let (level-cache)
+ (unless org--up-heading-cache
+ (setq org--up-heading-cache (make-hash-table)))
+ (if (and (eq (buffer-chars-modified-tick) org--up-heading-cache-tick)
+ (setq level-cache (gethash (point) org--up-heading-cache)))
+ (when (<= (point-min) (car level-cache) (point-max))
+ ;; Parent is inside accessible part of the buffer.
+ (progn (goto-char (car level-cache))
+ (cdr level-cache)))
+ ;; Buffer modified. Invalidate cache.
+ (unless (eq (buffer-chars-modified-tick) org--up-heading-cache-tick)
+ (setq-local org--up-heading-cache-tick
+ (buffer-chars-modified-tick))
+ (clrhash org--up-heading-cache))
+ (let* ((level-up (1- (funcall outline-level)))
+ (pos (point))
+ (result (and (> level-up 0)
+ (re-search-backward
+ (format "^\\*\\{1,%d\\} " level-up) nil t)
+ (funcall outline-level))))
+ (when result (puthash pos (cons (point) result) org--up-heading-cache))
+ result)))))
(defun org-up-heading-or-point-min ()
"Move to the heading line of which the present is a subheading, or point-min.
@@ -20409,10 +20673,10 @@ move point."
Return t when a child was found. Otherwise don't move point and
return nil."
(let (level (pos (point)) (re org-outline-regexp-bol))
- (when (ignore-errors (org-back-to-heading t))
- (setq level (outline-level))
+ (when (org-back-to-heading-or-point-min t)
+ (setq level (org-outline-level))
(forward-char 1)
- (if (and (re-search-forward re nil t) (> (outline-level) level))
+ (if (and (re-search-forward re nil t) (> (org-outline-level) level))
(progn (goto-char (match-beginning 0)) t)
(goto-char pos) nil))))
@@ -20446,7 +20710,7 @@ This is like outline-next-sibling, but invisible headings are ok."
(unless (or (eobp) (< (funcall outline-level) level))
(point))))
-(defun org-get-last-sibling ()
+(defun org-get-previous-sibling ()
"Move to previous heading of the same level, and return point.
If there is no such heading, return nil."
(let ((opoint (point))
@@ -20503,8 +20767,7 @@ When optional argument FULL is t, also skip planning information,
clocking lines and any kind of drawer.
When FULL is non-nil but not t, skip planning information,
-clocking lines and only non-regular drawers, i.e. properties and
-logbook drawers."
+properties, clocking lines and logbook drawers."
(org-back-to-heading t)
(forward-line)
;; Skip planning information.
@@ -20858,7 +21121,11 @@ See `org-backward-paragraph'."
(cond
;; There is a blank line above. Move there.
((and (org-previous-line-empty-p)
- (not (org-invisible-p (1- (line-end-position 0)))))
+ (let ((lep (line-end-position 0)))
+ ;; When the first headline start at point 2, don't choke while
+ ;; checking with `org-invisible-p'.
+ (or (= lep 1)
+ (not (org-invisible-p (1- (line-end-position 0)))))))
(forward-line -1))
;; At the beginning of the first element within a greater
;; element. Move to the beginning of the greater element.
diff --git a/lisp/org/ox-ascii.el b/lisp/org/ox-ascii.el
index 70bd1c4df2f..78e6fb4988b 100644
--- a/lisp/org/ox-ascii.el
+++ b/lisp/org/ox-ascii.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2012-2021 Free Software Foundation, Inc.
;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
+;; Maintainer: Nicolas Goaziou <n.goaziou at gmail dot com>
;; Keywords: outlines, hypermedia, calendar, wp
;; This file is part of GNU Emacs.
@@ -479,6 +480,9 @@ HOW determines the type of justification: it can be `left',
(insert s)
(goto-char (point-min))
(let ((fill-column text-width)
+ ;; Ensure that `indent-tabs-mode' is nil so that indentation
+ ;; will always be achieved using spaces rather than tabs.
+ (indent-tabs-mode nil)
;; Disable `adaptive-fill-mode' so it doesn't prevent
;; filling lines matching `adaptive-fill-regexp'.
(adaptive-fill-mode nil))
@@ -1033,7 +1037,7 @@ INFO is a plist used as a communication channel."
;; Format TITLE. It may be filled if it is too wide,
;; that is wider than the two thirds of the total width.
(title-len (min (apply #'max
- (mapcar #'length
+ (mapcar #'string-width
(org-split-string
(concat title "\n" subtitle) "\n")))
(/ (* 2 text-width) 3)))
@@ -1376,7 +1380,7 @@ contextual information."
;;;; Inlinetask
(defun org-ascii-format-inlinetask-default
- (_todo _type _priority _name _tags contents width inlinetask info)
+ (_todo _type _priority _name _tags contents width inlinetask info)
"Format an inline task element for ASCII export.
See `org-ascii-format-inlinetask-function' for a description
of the parameters."
@@ -1940,33 +1944,32 @@ CONTENTS is the row contents. INFO is a plist used as
a communication channel."
(when (eq (org-element-property :type table-row) 'standard)
(let ((build-hline
- (function
- (lambda (lcorner horiz vert rcorner)
- (concat
- (apply
- 'concat
- (org-element-map table-row 'table-cell
- (lambda (cell)
- (let ((width (org-ascii--table-cell-width cell info))
- (borders (org-export-table-cell-borders cell info)))
- (concat
- ;; In order to know if CELL starts the row, do
- ;; not compare it with the first cell in the
- ;; row as there might be a special column.
- ;; Instead, compare it with first exportable
- ;; cell, obtained with `org-element-map'.
- (when (and (memq 'left borders)
- (eq (org-element-map table-row 'table-cell
- 'identity info t)
- cell))
- lcorner)
- (make-string (+ 2 width) (string-to-char horiz))
- (cond
- ((not (memq 'right borders)) nil)
- ((eq (car (last (org-element-contents table-row))) cell)
- rcorner)
- (t vert)))))
- info)) "\n"))))
+ (lambda (lcorner horiz vert rcorner)
+ (concat
+ (apply
+ 'concat
+ (org-element-map table-row 'table-cell
+ (lambda (cell)
+ (let ((width (org-ascii--table-cell-width cell info))
+ (borders (org-export-table-cell-borders cell info)))
+ (concat
+ ;; In order to know if CELL starts the row, do
+ ;; not compare it with the first cell in the
+ ;; row as there might be a special column.
+ ;; Instead, compare it with first exportable
+ ;; cell, obtained with `org-element-map'.
+ (when (and (memq 'left borders)
+ (eq (org-element-map table-row 'table-cell
+ 'identity info t)
+ cell))
+ lcorner)
+ (make-string (+ 2 width) (string-to-char horiz))
+ (cond
+ ((not (memq 'right borders)) nil)
+ ((eq (car (last (org-element-contents table-row))) cell)
+ rcorner)
+ (t vert)))))
+ info)) "\n")))
(utf8p (eq (plist-get info :ascii-charset) 'utf-8))
(borders (org-export-table-cell-borders
(org-element-map table-row 'table-cell 'identity info t)
@@ -2088,7 +2091,7 @@ a communication channel."
;;;###autoload
(defun org-ascii-export-as-ascii
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to a text buffer.
If narrowing is active in the current buffer, only export its
@@ -2123,7 +2126,7 @@ is non-nil."
;;;###autoload
(defun org-ascii-export-to-ascii
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to a text file.
If narrowing is active in the current buffer, only export its
diff --git a/lisp/org/ox-beamer.el b/lisp/org/ox-beamer.el
index 6ed95e84d6b..77de0aa5bfe 100644
--- a/lisp/org/ox-beamer.el
+++ b/lisp/org/ox-beamer.el
@@ -4,6 +4,7 @@
;; Author: Carsten Dominik <carsten.dominik AT gmail DOT com>
;; Nicolas Goaziou <n.goaziou AT gmail DOT com>
+;; Maintainer: Nicolas Goaziou <n.goaziou at gmail dot com>
;; Keywords: org, wp, tex
;; This file is part of GNU Emacs.
@@ -149,7 +150,7 @@ which is replaced with the subtitle."
(defconst org-beamer-column-widths
"0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 0.0 :ETC"
-"The column widths that should be installed as allowed property values.")
+ "The column widths that should be installed as allowed property values.")
(defconst org-beamer-environments-special
'(("againframe" "A")
@@ -379,13 +380,12 @@ used as a communication channel."
:parent 'latex
:transcoders
(let ((protected-output
- (function
- (lambda (object contents info)
- (let ((code (org-export-with-backend
- 'beamer object contents info)))
- (if (org-string-nw-p code) (concat "\\protect" code)
- code))))))
- (mapcar #'(lambda (type) (cons type protected-output))
+ (lambda (object contents info)
+ (let ((code (org-export-with-backend
+ 'beamer object contents info)))
+ (if (org-string-nw-p code) (concat "\\protect" code)
+ code)))))
+ (mapcar (lambda (type) (cons type protected-output))
'(bold footnote-reference italic strike-through timestamp
underline))))
headline
@@ -426,16 +426,16 @@ used as a communication channel."
;; Collect nonempty options from default value and
;; headline's properties.
(cl-remove-if-not #'org-string-nw-p
- (append
- (org-split-string
- (plist-get info :beamer-frame-default-options) ",")
- (and beamer-opt
- (org-split-string
- ;; Remove square brackets if user provided
- ;; them.
- (and (string-match "^\\[?\\(.*\\)\\]?$" beamer-opt)
- (match-string 1 beamer-opt))
- ",")))))
+ (append
+ (org-split-string
+ (plist-get info :beamer-frame-default-options) ",")
+ (and beamer-opt
+ (org-split-string
+ ;; Remove square brackets if user provided
+ ;; them.
+ (and (string-match "^\\[?\\(.*\\)\\]?$" beamer-opt)
+ (match-string 1 beamer-opt))
+ ",")))))
(fragile
;; Add "fragile" option if necessary.
(and fragilep
@@ -812,17 +812,16 @@ holding export options."
(org-latex-make-preamble info)
;; Insert themes.
(let ((format-theme
- (function
- (lambda (prop command)
- (let ((theme (plist-get info prop)))
- (when theme
- (concat command
- (if (not (string-match "\\[.*\\]" theme))
- (format "{%s}\n" theme)
- (format "%s{%s}\n"
- (match-string 0 theme)
- (org-trim
- (replace-match "" nil nil theme)))))))))))
+ (lambda (prop command)
+ (let ((theme (plist-get info prop)))
+ (when theme
+ (concat command
+ (if (not (string-match "\\[.*\\]" theme))
+ (format "{%s}\n" theme)
+ (format "%s{%s}\n"
+ (match-string 0 theme)
+ (org-trim
+ (replace-match "" nil nil theme))))))))))
(mapconcat (lambda (args) (apply format-theme args))
'((:beamer-theme "\\usetheme")
(:beamer-color-theme "\\usecolortheme")
@@ -960,7 +959,7 @@ value."
;;;###autoload
(defun org-beamer-export-as-latex
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer as a Beamer buffer.
If narrowing is active in the current buffer, only export its
@@ -995,7 +994,7 @@ is non-nil."
;;;###autoload
(defun org-beamer-export-to-latex
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer as a Beamer presentation (tex).
If narrowing is active in the current buffer, only export its
@@ -1029,7 +1028,7 @@ Return output file's name."
;;;###autoload
(defun org-beamer-export-to-pdf
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer as a Beamer presentation (PDF).
If narrowing is active in the current buffer, only export its
@@ -1060,7 +1059,7 @@ Return PDF file's name."
(let ((file (org-export-output-file-name ".tex" subtreep)))
(org-export-to-file 'beamer file
async subtreep visible-only body-only ext-plist
- (lambda (file) (org-latex-compile file)))))
+ #'org-latex-compile)))
;;;###autoload
(defun org-beamer-select-environment ()
@@ -1080,7 +1079,7 @@ aid, but the tag does not have any semantic meaning."
(org-current-tag-alist
(append '((:startgroup))
(mapcar (lambda (e) (cons (concat "B_" (car e))
- (string-to-char (nth 1 e))))
+ (string-to-char (nth 1 e))))
envs)
'((:endgroup))
'(("BMCOL" . ?|))))
diff --git a/lisp/org/ox-html.el b/lisp/org/ox-html.el
index 03145e35c53..a150b1fdb87 100644
--- a/lisp/org/ox-html.el
+++ b/lisp/org/ox-html.el
@@ -2,8 +2,9 @@
;; Copyright (C) 2011-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Jambunathan K <kjambunathan at gmail dot com>
+;; Maintainer: TEC <tecosaur@gmail.com>
;; Keywords: outlines, hypermedia, calendar, wp
;; This file is part of GNU Emacs.
@@ -113,6 +114,7 @@
:options-alist
'((:html-doctype "HTML_DOCTYPE" nil org-html-doctype)
(:html-container "HTML_CONTAINER" nil org-html-container-element)
+ (:html-content-class "HTML_CONTENT_CLASS" nil org-html-content-class)
(:description "DESCRIPTION" nil nil newline)
(:keywords "KEYWORDS" nil nil space)
(:html-html5-fancy nil "html5-fancy" org-html-html5-fancy)
@@ -192,7 +194,7 @@
(defvar htmlize-buffer-places) ; from htmlize.el
(defvar org-html--pre/postamble-class "status"
- "CSS class used for pre/postamble")
+ "CSS class used for pre/postamble.")
(defconst org-html-doctype-alist
'(("html4-strict" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"
@@ -231,10 +233,9 @@ property on the headline itself.")
("\\.\\.\\." . "&#x2026;")) ; hellip
"Regular expressions for special string conversion.")
-(defconst org-html-scripts
- "<script type=\"text/javascript\">
-// @license magnet:?xt=urn:btih:e95b018ef3580986a04669f1b5879592219e2a7a&dn=public-domain.txt Public Domain
-<!--/*--><![CDATA[/*><!--*/
+(defcustom org-html-scripts
+ "<script>
+// @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&amp;dn=gpl-3.0.txt GPL-v3-or-Later
function CodeHighlightOn(elem, id)
{
var target = document.getElementById(id);
@@ -251,14 +252,16 @@ property on the headline itself.")
target.classList.remove(\"code-highlighted\");
}
}
- /*]]>*///-->
// @license-end
</script>"
- "Basic JavaScript that is needed by HTML files produced by Org mode.")
+ "Basic JavaScript to allow highlighting references in code blocks."
+ :group 'org-export-html
+ :package-version '(Org . "9.5")
+ :type 'string)
-(defconst org-html-style-default
- "<style type=\"text/css\">
- <!--/*--><![CDATA[/*><!--*/
+(defcustom org-html-style-default
+ "<style>
+ #content { max-width: 60em; margin: auto; }
.title { text-align: center;
margin-bottom: .2em; }
.subtitle { text-align: center;
@@ -279,8 +282,9 @@ property on the headline itself.")
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
- border: 1px solid #ccc;
- box-shadow: 3px 3px 3px #eee;
+ border: 1px solid #e6e6e6;
+ border-radius: 3px;
+ background-color: #f2f2f2;
padding: 8pt;
font-family: monospace;
overflow: auto;
@@ -289,21 +293,21 @@ property on the headline itself.")
pre.src {
position: relative;
overflow: auto;
- padding-top: 1.2em;
}
pre.src:before {
display: none;
position: absolute;
- background-color: white;
- top: -10px;
- right: 10px;
+ top: -8px;
+ right: 12px;
padding: 3px;
- border: 1px solid black;
+ color: #555;
+ background-color: #f2f2f299;
}
pre.src:hover:before { display: inline; margin-top: 14px;}
/* Languages per Org manual */
pre.src-asymptote:before { content: 'Asymptote'; }
pre.src-awk:before { content: 'Awk'; }
+ pre.src-authinfo::before { content: 'Authinfo'; }
pre.src-C:before { content: 'C'; }
/* pre.src-C++ doesn't work in CSS */
pre.src-clojure:before { content: 'Clojure'; }
@@ -439,12 +443,14 @@ property on the headline itself.")
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
.org-svg { width: 90%; }
- /*]]>*/-->
</style>"
"The default style specification for exported HTML files.
You can use `org-html-head' and `org-html-head-extra' to add to
this style. If you don't want to include this default style,
-customize `org-html-head-include-default-style'.")
+customize `org-html-head-include-default-style'."
+ :group 'org-export-html
+ :package-version '(Org . "9.5")
+ :type 'string)
;;; User Configuration Variables
@@ -508,17 +514,15 @@ means to use the maximum value consistent with other options."
org-html-infojs-opts-table)))
(defcustom org-html-infojs-template
- "<script type=\"text/javascript\" src=\"%SCRIPT_PATH\">
+ "<script src=\"%SCRIPT_PATH\">
// @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&amp;dn=gpl-3.0.txt GPL-v3-or-Later
// @license-end
</script>
-<script type=\"text/javascript\">
+<script>
// @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&amp;dn=gpl-3.0.txt GPL-v3-or-Later
-<!--/*--><![CDATA[/*><!--*/
%MANAGER_OPTIONS
org_html_manager.setup(); // activate after the parameters are set
-/*]]>*///-->
// @license-end
</script>"
"The template for the export style additions when org-info.js is used.
@@ -653,9 +657,6 @@ The function must accept two parameters:
The function should return the string to be exported.
-For example, the variable could be set to the following function
-in order to mimic default behavior:
-
The default value simply returns the value of CONTENTS."
:group 'org-export-html
:version "24.4"
@@ -782,7 +783,7 @@ The function should return the string to be exported."
"The MathJax command to use when referencing equations.
This is a format control string that expects a single string argument
-specifying the label that is being referenced. The argument is
+specifying the label that is being referenced. The argument is
generated automatically on export.
The default is to wrap equations in parentheses (using \"\\eqref{%s}\)\".
@@ -794,7 +795,7 @@ Most common values are:
:group 'org-export-html
:package-version '(Org . "9.4")
:type 'string
- :safe t)
+ :safe #'stringp)
(defcustom org-html-with-latex org-export-with-latex
"Non-nil means process LaTeX math snippets.
@@ -825,13 +826,13 @@ e.g. \"tex:mathjax\". Allowed values are:
;;;; Links :: Generic
(defcustom org-html-link-org-files-as-html t
- "Non-nil means make file links to `file.org' point to `file.html'.
-When `org-mode' is exporting an `org-mode' file to HTML, links to
-non-html files are directly put into a href tag in HTML.
-However, links to other Org files (recognized by the extension
-\".org\") should become links to the corresponding HTML
-file, assuming that the linked `org-mode' file will also be
-converted to HTML.
+ "Non-nil means make file links to \"file.org\" point to \"file.html\".
+
+When Org mode is exporting an Org file to HTML, links to non-HTML files
+are directly put into a \"href\" tag in HTML. However, links to other Org files
+(recognized by the extension \".org\") should become links to the corresponding
+HTML file, assuming that the linked Org file will also be converted to HTML.
+
When nil, the links still point to the plain \".org\" file."
:group 'org-export-html
:type 'boolean)
@@ -848,16 +849,15 @@ link to the image."
:type 'boolean)
(defcustom org-html-inline-image-rules
- `(("file" . ,(regexp-opt '(".jpeg" ".jpg" ".png" ".gif" ".svg")))
- ("http" . ,(regexp-opt '(".jpeg" ".jpg" ".png" ".gif" ".svg")))
- ("https" . ,(regexp-opt '(".jpeg" ".jpg" ".png" ".gif" ".svg"))))
+ `(("file" . ,(regexp-opt '(".jpeg" ".jpg" ".png" ".gif" ".svg" ".webp")))
+ ("http" . ,(regexp-opt '(".jpeg" ".jpg" ".png" ".gif" ".svg" ".webp")))
+ ("https" . ,(regexp-opt '(".jpeg" ".jpg" ".png" ".gif" ".svg" ".webp"))))
"Rules characterizing image files that can be inlined into HTML.
A rule consists in an association whose key is the type of link
to consider, and value is a regexp that will be matched against
link's path."
:group 'org-export-html
- :version "24.4"
- :package-version '(Org . "8.0")
+ :package-version '(Org . "9.5")
:type '(alist :key-type (string :tag "Type")
:value-type (regexp :tag "Path")))
@@ -874,7 +874,7 @@ link's path."
(defcustom org-html-htmlize-output-type 'inline-css
"Output type to be used by htmlize when formatting code snippets.
Choices are `css' to export the CSS selectors only,`inline-css'
-to export the CSS attribute values inline in the HTML or `nil' to
+to export the CSS attribute values inline in the HTML or nil to
export plain text. We use as default `inline-css', in order to
make the resulting HTML self-containing.
@@ -903,7 +903,7 @@ numbers are enabled."
:group 'org-export-html
:package-version '(Org . "9.3")
:type 'boolean
- :safe t)
+ :safe #'booleanp)
;;;; Table
@@ -1060,13 +1060,7 @@ publishing, with :html-doctype."
(defcustom org-html-html5-fancy nil
"Non-nil means using new HTML5 elements.
-This variable is ignored for anything other than HTML5 export.
-
-For compatibility with Internet Explorer, it's probably a good
-idea to download some form of the html5shiv (for instance
-https://code.google.com/p/html5shiv/) and add it to your
-HTML_HEAD_EXTRA, so that your pages don't break for users of IE
-versions 8 and below."
+This variable is ignored for anything other than HTML5 export."
:group 'org-export-html
:version "24.4"
:package-version '(Org . "8.0")
@@ -1084,6 +1078,16 @@ org-info.js for your website."
:package-version '(Org . "8.0")
:type 'string)
+(defcustom org-html-content-class "content"
+ "CSS class name to use for the top level content wrapper.
+Can be set with the in-buffer HTML_CONTENT_CLASS property or for
+publishing, with :html-content-class."
+ :group 'org-export-html
+ :version "27.2"
+ :package-version '(Org . "9.5")
+ :type 'string)
+
+
(defcustom org-html-divs
'((preamble "div" "preamble")
(content "div" "content")
@@ -1110,15 +1114,15 @@ org-info.js for your website."
(defconst org-html-checkbox-types
'((unicode .
- ((on . "&#x2611;") (off . "&#x2610;") (trans . "&#x2610;")))
+ ((on . "&#x2611;") (off . "&#x2610;") (trans . "&#x2610;")))
(ascii .
- ((on . "<code>[X]</code>")
- (off . "<code>[&#xa0;]</code>")
- (trans . "<code>[-]</code>")))
+ ((on . "<code>[X]</code>")
+ (off . "<code>[&#xa0;]</code>")
+ (trans . "<code>[-]</code>")))
(html .
((on . "<input type='checkbox' checked='checked' />")
- (off . "<input type='checkbox' />")
- (trans . "<input type='checkbox' />"))))
+ (off . "<input type='checkbox' />")
+ (trans . "<input type='checkbox' />"))))
"Alist of checkbox types.
The cdr of each entry is an alist list three checkbox types for
HTML export: `on', `off' and `trans'.
@@ -1129,7 +1133,7 @@ The choices are:
`html' HTML checkboxes
Note that only the ascii characters implement tri-state
-checkboxes. The other two use the `off' checkbox for `trans'.")
+checkboxes. The other two use the `off' checkbox for `trans'.")
(defcustom org-html-checkbox-type 'ascii
"The type of checkboxes to use for HTML export.
@@ -1192,7 +1196,7 @@ You can also customize this for each buffer, using something like
For further information about MathJax options, see the MathJax documentation:
- http://docs.mathjax.org/"
+ https://docs.mathjax.org/"
:group 'org-export-html
:package-version '(Org . "8.3")
:type '(list :greedy t
@@ -1252,8 +1256,7 @@ For further information about MathJax options, see the MathJax documentation:
}
});
</script>
-<script type=\"text/javascript\"
- src=\"%PATH\"></script>"
+<script src=\"%PATH\"></script>"
"The MathJax template. See also `org-html-mathjax-options'."
:group 'org-export-html
:type 'string)
@@ -1414,10 +1417,9 @@ ignored."
;;;; Template :: Scripts
-(defcustom org-html-head-include-scripts t
+(defcustom org-html-head-include-scripts nil
"Non-nil means include the JavaScript snippets in exported HTML files.
-The actual script is defined in `org-html-scripts' and should
-not be modified."
+The actual script is defined in `org-html-scripts'."
:group 'org-export-html
:version "24.4"
:package-version '(Org . "8.0")
@@ -1425,6 +1427,23 @@ not be modified."
;;;; Template :: Styles
+(defcustom org-html-meta-tags #'org-html-meta-tags-default
+ "Form that is used to produce meta tags in the HTML head.
+
+Can be a list where each item is a list of arguments to be passed
+to `org-html--build-meta-entry'. Any nil items are ignored.
+
+Also accept a function which gives such a list when called with a
+single argument (INFO, a communication plist)."
+ :group 'org-export-html
+ :package-version '(Org . "9.5")
+ :type '(choice
+ (repeat
+ (list (string :tag "Meta label")
+ (string :tag "label value")
+ (string :tag "Content value")))
+ function))
+
(defcustom org-html-head-include-default-style t
"Non-nil means include the default style in exported HTML files.
The actual style is defined in `org-html-style-default' and
@@ -1447,14 +1466,12 @@ done, timestamp, timestamp-kwd, tag, target.
For example, a valid value would be:
- <style type=\"text/css\">
- /*<![CDATA[*/
+ <style>
p { font-weight: normal; color: gray; }
h1 { color: black; }
.title { text-align: center; }
.todo, .timestamp-kwd { color: red; }
.done { color: green; }
- /*]]>*/
</style>
If you want to refer to an external style, use something like
@@ -1588,7 +1605,7 @@ CSS classes, then this prefix can be very useful."
(defun org-html-html5-p (info)
(let ((dt (downcase (plist-get info :html-doctype))))
- (member dt '("html5" "xhtml5" "<!doctype html>"))))
+ (member dt '("html5" "xhtml5" "<!doctype html>"))))
(defun org-html--html5-fancy-p (info)
"Non-nil when exporting to HTML5 with fancy elements.
@@ -1680,43 +1697,20 @@ SOURCE is a string specifying the location of the image.
ATTRIBUTES is a plist, as returned by
`org-export-read-attribute'. INFO is a plist used as
a communication channel."
- (if (string= "svg" (file-name-extension source))
- (org-html--svg-image source attributes info)
- (org-html-close-tag
- "img"
- (org-html--make-attribute-string
- (org-combine-plists
- (list :src source
- :alt (if (string-match-p
- (concat "^" org-preview-latex-image-directory) source)
- (org-html-encode-plain-text
- (org-find-text-property-in-string 'org-latex-src source))
- (file-name-nondirectory source)))
- attributes))
- info)))
-
-(defun org-html--svg-image (source attributes info)
- "Return \"object\" embedding svg file SOURCE with given ATTRIBUTES.
-INFO is a plist used as a communication channel.
-
-The special attribute \"fallback\" can be used to specify a
-fallback image file to use if the object embedding is not
-supported. CSS class \"org-svg\" is assigned as the class of the
-object unless a different class is specified with an attribute."
- (let ((fallback (plist-get attributes :fallback))
- (attrs (org-html--make-attribute-string
- (org-combine-plists
- ;; Remove fallback attribute, which is not meant to
- ;; appear directly in the attributes string, and
- ;; provide a default class if none is set.
- '(:class "org-svg") attributes '(:fallback nil)))))
- (format "<object type=\"image/svg+xml\" data=\"%s\" %s>\n%s</object>"
- source
- attrs
- (if fallback
- (org-html-close-tag
- "img" (format "src=\"%s\" %s" fallback attrs) info)
- "Sorry, your browser does not support SVG."))))
+ (org-html-close-tag
+ "img"
+ (org-html--make-attribute-string
+ (org-combine-plists
+ (list :src source
+ :alt (if (string-match-p
+ (concat "^" org-preview-latex-image-directory) source)
+ (org-html-encode-plain-text
+ (org-find-text-property-in-string 'org-latex-src source))
+ (file-name-nondirectory source)))
+ (if (string= "svg" (file-name-extension source))
+ (org-combine-plists '(:class "org-svg") attributes '(:fallback nil))
+ attributes)))
+ info))
(defun org-html--textarea-block (element)
"Transcode ELEMENT into a textarea block.
@@ -1820,12 +1814,12 @@ INFO is a plist used as a communication channel."
(anchor (org-html--anchor
(format "fn.%d" n)
n
- (format " class=\"footnum\" href=\"#fnr.%d\"" n)
+ (format " class=\"footnum\" href=\"#fnr.%d\" role=\"doc-backlink\"" n)
info))
(contents (org-trim (org-export-data def info))))
(format "<div class=\"footdef\">%s %s</div>\n"
(format (plist-get info :html-footnote-format) anchor)
- (format "<div class=\"footpara\">%s</div>"
+ (format "<div class=\"footpara\" role=\"doc-footnote\">%s</div>"
(if (not inline?) contents
(format "<p class=\"footpara\">%s</p>"
contents))))))))
@@ -1835,78 +1829,93 @@ INFO is a plist used as a communication channel."
;;; Template
+(defun org-html-meta-tags-default (info)
+ "A default value for `org-html-meta-tags'.
+
+Generate a list items, each of which is a list of arguments that can
+be passed to `org-html--build-meta-entry', to generate meta tags to be
+included in the HTML head.
+
+Use document's plist INFO to derive relevant information for the tags."
+ (let ((author (and (plist-get info :with-author)
+ (let ((auth (plist-get info :author)))
+ ;; Return raw Org syntax.
+ (and auth (org-element-interpret-data auth))))))
+ (list
+ (when (org-string-nw-p author)
+ (list "name" "author" author))
+ (when (org-string-nw-p (plist-get info :description))
+ (list "name" "description"
+ (plist-get info :description)))
+ (when (org-string-nw-p (plist-get info :keywords))
+ (list "name" "keywords" (plist-get info :keywords)))
+ '("name" "generator" "Org Mode"))))
+
+(defun org-html--build-meta-entry
+ (label identity &optional content-format &rest content-formatters)
+ "Build a meta tag using the provided information.
+
+Construct <meta> tag of form <meta LABEL=\"IDENTITY\" />, or when CONTENT-FORMAT
+is present: <meta LABEL=\"IDENTITY\" content=\"{content}\" />
+
+Here {content} is determined by applying any CONTENT-FORMATTERS to the
+CONTENT-FORMAT and encoding the result as plain text."
+ (concat "<meta "
+ (format "%s=\"%s" label identity)
+ (when content-format
+ (concat "\" content=\""
+ (replace-regexp-in-string
+ "\"" "&quot;"
+ (org-html-encode-plain-text
+ (if content-formatters
+ (apply #'format content-format content-formatters)
+ content-format)))))
+ "\" />\n"))
+
(defun org-html--build-meta-info (info)
"Return meta tags for exported document.
INFO is a plist used as a communication channel."
- (let* ((protect-string
- (lambda (str)
- (replace-regexp-in-string
- "\"" "&quot;" (org-html-encode-plain-text str))))
- (title (org-export-data (plist-get info :title) info))
- ;; Set title to an invisible character instead of leaving it
- ;; empty, which is invalid.
- (title (if (org-string-nw-p title) title "&lrm;"))
- (author (and (plist-get info :with-author)
- (let ((auth (plist-get info :author)))
- ;; Return raw Org syntax.
- (and auth (org-element-interpret-data auth)))))
- (description (plist-get info :description))
- (keywords (plist-get info :keywords))
- (charset (or (and org-html-coding-system
- (fboundp 'coding-system-get)
- (coding-system-get org-html-coding-system
- 'mime-charset))
- "iso-8859-1")))
+ (let* ((title (org-html-plain-text
+ (org-element-interpret-data (plist-get info :title)) info))
+ ;; Set title to an invisible character instead of leaving it
+ ;; empty, which is invalid.
+ (title (if (org-string-nw-p title) title "&lrm;"))
+ (charset (or (and org-html-coding-system
+ (fboundp 'coding-system-get)
+ (symbol-name
+ (coding-system-get org-html-coding-system
+ 'mime-charset)))
+ "iso-8859-1")))
(concat
(when (plist-get info :time-stamp-file)
(format-time-string
(concat "<!-- "
(plist-get info :html-metadata-timestamp-format)
" -->\n")))
- (format
- (if (org-html-html5-p info)
- (org-html-close-tag "meta" "charset=\"%s\"" info)
- (org-html-close-tag
- "meta" "http-equiv=\"Content-Type\" content=\"text/html;charset=%s\""
- info))
- charset) "\n"
+
+ (if (org-html-html5-p info)
+ (org-html--build-meta-entry "charset" charset)
+ (org-html--build-meta-entry "http-equiv" "Content-Type"
+ (concat "text/html;charset=" charset)))
+
(let ((viewport-options
(cl-remove-if-not (lambda (cell) (org-string-nw-p (cadr cell)))
(plist-get info :html-viewport))))
- (and viewport-options
- (concat
- (org-html-close-tag
- "meta"
- (format "name=\"viewport\" content=\"%s\""
- (mapconcat
- (lambda (elm) (format "%s=%s" (car elm) (cadr elm)))
- viewport-options ", "))
- info)
- "\n")))
+ (if viewport-options
+ (org-html--build-meta-entry "name" "viewport"
+ (mapconcat
+ (lambda (elm)
+ (format "%s=%s" (car elm) (cadr elm)))
+ viewport-options ", "))))
+
(format "<title>%s</title>\n" title)
- (org-html-close-tag "meta" "name=\"generator\" content=\"Org mode\"" info)
- "\n"
- (and (org-string-nw-p author)
- (concat
- (org-html-close-tag "meta"
- (format "name=\"author\" content=\"%s\""
- (funcall protect-string author))
- info)
- "\n"))
- (and (org-string-nw-p description)
- (concat
- (org-html-close-tag "meta"
- (format "name=\"description\" content=\"%s\"\n"
- (funcall protect-string description))
- info)
- "\n"))
- (and (org-string-nw-p keywords)
- (concat
- (org-html-close-tag "meta"
- (format "name=\"keywords\" content=\"%s\""
- (funcall protect-string keywords))
- info)
- "\n")))))
+
+ (mapconcat
+ (lambda (args) (apply #'org-html--build-meta-entry args))
+ (delq nil (if (functionp org-html-meta-tags)
+ (funcall org-html-meta-tags info)
+ org-html-meta-tags))
+ ""))))
(defun org-html--build-head (info)
"Return information for the <head>..</head> of the HTML output.
@@ -2088,7 +2097,10 @@ holding export options."
(org-html--build-pre/postamble 'preamble info)
;; Document contents.
(let ((div (assq 'content (plist-get info :html-divs))))
- (format "<%s id=\"%s\">\n" (nth 1 div) (nth 2 div)))
+ (format "<%s id=\"%s\" class=\"%s\">\n"
+ (nth 1 div)
+ (nth 2 div)
+ (plist-get info :html-content-class)))
;; Document title.
(when (plist-get info :with-title)
(let ((title (and (plist-get info :with-title)
@@ -2104,7 +2116,7 @@ holding export options."
(if subtitle
(format
(if html5-fancy
- "<p class=\"subtitle\">%s</p>\n"
+ "<p class=\"subtitle\" role=\"doc-subtitle\">%s</p>\n"
(concat "\n" (org-html-close-tag "br" nil info) "\n"
"<span class=\"subtitle\">%s</span>\n"))
(org-export-data subtitle info))
@@ -2232,7 +2244,7 @@ is the language used for CODE, as a string, or nil."
(if (and beg end) (substring code beg end) code)))))))))
(defun org-html-do-format-code
- (code &optional lang refs retain-labels num-start wrap-lines)
+ (code &optional lang refs retain-labels num-start wrap-lines)
"Format CODE string as source code.
Optional arguments LANG, REFS, RETAIN-LABELS, NUM-START, WRAP-LINES
are, respectively, the language of the source code, as a string, an
@@ -2305,14 +2317,14 @@ of contents as a string, or nil if it is empty."
(org-export-get-relative-level headline info)))
(org-export-collect-headlines info depth scope))))
(when toc-entries
- (let ((toc (concat "<div id=\"text-table-of-contents\">"
+ (let ((toc (concat "<div id=\"text-table-of-contents\" role=\"doc-toc\">"
(org-html--toc-text toc-entries)
"</div>\n")))
(if scope toc
(let ((outer-tag (if (org-html--html5-fancy-p info)
"nav"
"div")))
- (concat (format "<%s id=\"table-of-contents\">\n" outer-tag)
+ (concat (format "<%s id=\"table-of-contents\" role=\"doc-toc\">\n" outer-tag)
(let ((top-level (plist-get info :html-toplevel-hlevel)))
(format "<h%d>%s</h%d>\n"
top-level
@@ -2585,7 +2597,7 @@ CONTENTS is nil. INFO is a plist holding contextual information."
(format
(plist-get info :html-footnote-format)
(org-html--anchor
- id n (format " class=\"footref\" href=\"#fn.%d\"" n) info)))))
+ id n (format " class=\"footref\" href=\"#fn.%d\" role=\"doc-backlink\"" n) info)))))
;;;; Headline
@@ -2650,7 +2662,7 @@ holding contextual information."
(format
"<span class=\"section-number-%d\">%s</span> "
level
- (mapconcat #'number-to-string numbers ".")))
+ (concat (mapconcat #'number-to-string numbers ".") ".")))
formatted-text)
level)
;; When there is no section, pretend there is an
@@ -2720,7 +2732,7 @@ holding contextual information."
todo todo-type priority text tags contents info)))
(defun org-html-format-inlinetask-default-function
- (todo todo-type priority text tags contents info)
+ (todo todo-type priority text tags contents info)
"Default format function for inlinetasks.
See `org-html-format-inlinetask-function' for details."
(format "<div class=\"inlinetask\">\n<b>%s</b>%s\n%s</div>"
@@ -3020,7 +3032,8 @@ images, set it to:
(`paragraph element)
(`link (org-export-get-parent element)))))
(and (eq (org-element-type paragraph) 'paragraph)
- (or (not (fboundp 'org-html-standalone-image-predicate))
+ (or (not (and (boundp 'org-html-standalone-image-predicate)
+ (fboundp org-html-standalone-image-predicate)))
(funcall org-html-standalone-image-predicate paragraph))
(catch 'exit
(let ((link-count 0))
@@ -3464,12 +3477,12 @@ contextual information."
(if (org-export-read-attribute :attr_html src-block :textarea)
(org-html--textarea-block src-block)
(let* ((lang (org-element-property :language src-block))
- (code (org-html-format-code src-block info))
- (label (let ((lbl (org-html--reference src-block info t)))
- (if lbl (format " id=\"%s\"" lbl) "")))
- (klipsify (and (plist-get info :html-klipsify-src)
- (member lang '("javascript" "js"
- "ruby" "scheme" "clojure" "php" "html")))))
+ (code (org-html-format-code src-block info))
+ (label (let ((lbl (org-html--reference src-block info t)))
+ (if lbl (format " id=\"%s\"" lbl) "")))
+ (klipsify (and (plist-get info :html-klipsify-src)
+ (member lang '("javascript" "js"
+ "ruby" "scheme" "clojure" "php" "html")))))
(if (not lang) (format "<pre class=\"example\"%s>\n%s</pre>" label code)
(format "<div class=\"org-src-container\">\n%s%s\n</div>"
;; Build caption.
@@ -3773,7 +3786,7 @@ contextual information."
;;;###autoload
(defun org-html-export-as-html
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to an HTML buffer.
If narrowing is active in the current buffer, only export its
@@ -3818,7 +3831,7 @@ to convert it."
;;;###autoload
(defun org-html-export-to-html
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to a HTML file.
If narrowing is active in the current buffer, only export its
diff --git a/lisp/org/ox-icalendar.el b/lisp/org/ox-icalendar.el
index b8834c4ce10..211d0f716b8 100644
--- a/lisp/org/ox-icalendar.el
+++ b/lisp/org/ox-icalendar.el
@@ -2,8 +2,9 @@
;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
-;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Nicolas Goaziou <n dot goaziou at gmail dot com>
+;; Maintainer: Nicolas Goaziou <n.goaziou at gmail dot com>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
@@ -32,6 +33,7 @@
;;; Code:
(require 'cl-lib)
+(require 'org-agenda)
(require 'ox-ascii)
(declare-function org-bbdb-anniv-export-ical "ol-bbdb" nil)
@@ -278,10 +280,10 @@ re-read the iCalendar file.")
(footnote-definition . ignore)
(footnote-reference . ignore)
(headline . org-icalendar-entry)
+ (inner-template . org-icalendar-inner-template)
(inlinetask . ignore)
(planning . ignore)
(section . ignore)
- (inner-template . (lambda (c i) c))
(template . org-icalendar-template))
:options-alist
'((:exclude-tags
@@ -370,7 +372,6 @@ A headline is blocked when either
(1- (length org-icalendar-date-time-format)))
?Z))
-(defvar org-agenda-default-appointment-duration) ; From org-agenda.el.
(defun org-icalendar-convert-timestamp (timestamp keyword &optional end tz)
"Convert TIMESTAMP to iCalendar format.
@@ -722,7 +723,7 @@ Return VEVENT component as a string."
"END:VEVENT"))))
(defun org-icalendar--vtodo
- (entry uid summary location description categories timezone class)
+ (entry uid summary location description categories timezone class)
"Create a VTODO component.
ENTRY is either a headline or an inlinetask element. UID is the
@@ -805,6 +806,11 @@ END:VALARM\n"
;;;; Template
+(defun org-icalendar-inner-template (contents _)
+ "Return document body string after iCalendar conversion.
+CONTENTS is the transcoded contents string."
+ contents)
+
(defun org-icalendar-template (contents info)
"Return complete document string after iCalendar conversion.
CONTENTS is the transcoded contents string. INFO is a plist used
@@ -818,8 +824,7 @@ as a communication channel."
(if (not (plist-get info :with-author)) ""
(org-export-data (plist-get info :author) info))
;; Timezone.
- (if (org-string-nw-p org-icalendar-timezone) org-icalendar-timezone
- (cadr (current-time-zone)))
+ (or (org-string-nw-p org-icalendar-timezone) (format-time-string "%Z"))
;; Description.
(org-export-data (plist-get info :title) info)
contents))
@@ -849,7 +854,7 @@ CALSCALE:GREGORIAN\n"
;;;###autoload
(defun org-icalendar-export-to-ics
- (&optional async subtreep visible-only body-only)
+ (&optional async subtreep visible-only body-only)
"Export current buffer to an iCalendar file.
If narrowing is active in the current buffer, only export its
@@ -882,8 +887,8 @@ Return ICS file name."
(org-export-to-file 'icalendar outfile
async subtreep visible-only body-only
'(:ascii-charset utf-8 :ascii-links-to-notes nil)
- (lambda (file)
- (run-hook-with-args 'org-icalendar-after-save-hook file) nil))))
+ '(lambda (file)
+ (run-hook-with-args 'org-icalendar-after-save-hook file) nil))))
;;;###autoload
(defun org-icalendar-export-agenda-files (&optional async)
@@ -966,7 +971,7 @@ This function assumes major mode for current buffer is
(org-icalendar--vcalendar
org-icalendar-combined-name
user-full-name
- (or (org-string-nw-p org-icalendar-timezone) (cadr (current-time-zone)))
+ (or (org-string-nw-p org-icalendar-timezone) (format-time-string "%Z"))
org-icalendar-combined-description
contents)))
(run-hook-with-args 'org-icalendar-after-save-hook file)))
@@ -989,7 +994,7 @@ FILES is a list of files to build the calendar from."
user-full-name
;; Timezone.
(or (org-string-nw-p org-icalendar-timezone)
- (cadr (current-time-zone)))
+ (format-time-string "Z"))
;; Description.
org-icalendar-combined-description
;; Contents.
diff --git a/lisp/org/ox-koma-letter.el b/lisp/org/ox-koma-letter.el
new file mode 100644
index 00000000000..978e4e41f56
--- /dev/null
+++ b/lisp/org/ox-koma-letter.el
@@ -0,0 +1,989 @@
+;;; ox-koma-letter.el --- KOMA Scrlttr2 Back-End for Org Export Engine -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2007-2021 Free Software Foundation, Inc.
+
+;; Author: Nicolas Goaziou <n.goaziou AT gmail DOT com>
+;; Alan Schmitt <alan.schmitt AT polytechnique DOT org>
+;; Viktor Rosenfeld <listuser36 AT gmail DOT com>
+;; Rasmus Pank Roulund <emacs AT pank DOT eu>
+;; Maintainer: Marco Wahl <marcowahlsoft@gmail.com>
+;; Keywords: org, wp, tex
+
+;; 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 implements a KOMA Scrlttr2 back-end, derived from the
+;; LaTeX one.
+;;
+;; Depending on the desired output format, three commands are provided
+;; for export: `org-koma-letter-export-as-latex' (temporary buffer),
+;; `org-koma-letter-export-to-latex' ("tex" file) and
+;; `org-koma-letter-export-to-pdf' ("pdf" file).
+;;
+;; On top of buffer keywords supported by `latex' back-end (see
+;; `org-latex-options-alist'), this back-end introduces the following
+;; keywords:
+;; - CLOSING: see `org-koma-letter-closing',
+;; - FROM_ADDRESS: see `org-koma-letter-from-address',
+;; - LCO: see `org-koma-letter-class-option-file',
+;; - OPENING: see `org-koma-letter-opening',
+;; - PHONE_NUMBER: see `org-koma-letter-phone-number',
+;; - URL: see `org-koma-letter-url',
+;; - FROM_LOGO: see `org-koma-letter-from-logo',
+;; - SIGNATURE: see `org-koma-letter-signature',
+;; - PLACE: see `org-koma-letter-place',
+;; - LOCATION: see `org-koma-letter-location',
+;; - TO_ADDRESS: If unspecified this is set to "\mbox{}".
+;;
+;; TO_ADDRESS, FROM_ADDRESS, LOCATION, CLOSING, and SIGNATURE can also
+;; be specified using "special headings" with the special tags
+;; specified in `org-koma-letter-special-tags-in-letter'. LaTeX line
+;; breaks are not necessary for TO_ADDRESS, FROM_ADDRESS and LOCATION.
+;; If both a headline and a keyword specify a to or from address the
+;; value is determined in accordance with
+;; `org-koma-letter-prefer-special-headings'.
+;;
+;; A number of OPTIONS settings can be set to change which contents is
+;; exported.
+;; - backaddress (see `org-koma-letter-use-backaddress')
+;; - foldmarks (see `org-koma-letter-use-foldmarks')
+;; - phone (see `org-koma-letter-use-phone')
+;; - url (see `org-koma-letter-use-url')
+;; - from-logo (see `org-koma-letter-use-from-logo')
+;; - email (see `org-koma-letter-use-email')
+;; - place (see `org-koma-letter-use-place')
+;; - location (see `org-koma-letter-use-location')
+;; - subject, a list of format options
+;; (see `org-koma-letter-subject-format')
+;; - after-closing-order, a list of the ordering of headings with
+;; special tags after closing (see
+;; `org-koma-letter-special-tags-after-closing')
+;; - after-letter-order, as above, but after the end of the letter
+;; (see `org-koma-letter-special-tags-after-letter').
+;;
+;; The following variables works differently from the main LaTeX class
+;; - AUTHOR: Default to user-full-name but may be disabled.
+;; (See also `org-koma-letter-author'.)
+;; - EMAIL: Same as AUTHOR. (See also `org-koma-letter-email'.)
+;;
+;; FROM_LOGO uses LaTeX markup. FROM_LOGO provides the
+;; "includegraphics" command to tell LaTeX where to find the logo.
+;; This command needs to know the logo's directory and file name. The
+;; directory can either be relative or absolute, just as you would
+;; expect. LaTeX can use three file types for the logo: PDF, JPEG, or
+;; PNG. The logo can either include or exclude its extension, which
+;; might surprise you. When you exclude its extension, LaTeX will
+;; search the directory for the "best" quality graphics format. For
+;; example if it finds both logo.pdf and logo.png then it will
+;; identify the PDF as "better", and include "logo.pdf". This can be
+;; useful, for example, when you are mocking up a logo in the PNG
+;; raster format and then switch over to the higher quality PDF vector
+;; format. When you include the file extension then LaTeX will
+;; include it without searching for higher quality file types.
+;; Whatever file type you choose, it will probably require a few
+;; design iterations to get the best looking logo size for your
+;; letter. Finally, the directory and file name are specified
+;; *without* quotes. Here are some examples with commentary, in the
+;; location of your letter, with a logo named "logo", to get you
+;; started:
+;;
+;; Logo in the same directory: \includegraphics{logo}
+;; or a sub-directory: \includegraphics{logos/production/logo}
+;;
+;; Logos specified using absolute paths on Linux or Windows:
+;;
+;; \includegraphics{~/correspondence/logo}
+;; \includegraphics{~/correspondence/logos/production/logo}
+;; \includegraphics{c:/you/correspondence/logo}
+;; \includegraphics{c:/you/correspondence/logos/production/logo}
+;;
+;; Logos in the same directory where the "better" quality PDF will
+;; be chosen over the JPG:
+;;
+;; \includegraphics{logo.pdf}
+;; \includegraphics{logo.png}
+;;
+;; Headlines are in general ignored. However, headlines with special
+;; tags can be used for specified contents like postscript (ps),
+;; carbon copy (cc), enclosures (encl) and code to be inserted after
+;; \end{letter} (after_letter). Specials tags are defined in
+;; `org-koma-letter-special-tags-after-closing' and
+;; `org-koma-letter-special-tags-after-letter'. Currently members of
+;; `org-koma-letter-special-tags-after-closing' used as macros and the
+;; content of the headline is the argument.
+;;
+;; Headlines with to and from may also be used rather than the keyword
+;; approach described above. If both a keyword and a headline with
+;; information is present precedence is determined by
+;; `org-koma-letter-prefer-special-headings'.
+;;
+;; You need an appropriate association in `org-latex-classes' in order
+;; to use the KOMA Scrlttr2 class. By default, a sparse scrlttr2
+;; class is provided: "default-koma-letter". You can also add you own
+;; letter class. For instance:
+;;
+;; (add-to-list 'org-latex-classes
+;; '("my-letter"
+;; "\\documentclass\[%
+;; DIV=14,
+;; fontsize=12pt,
+;; parskip=half,
+;; subject=titled,
+;; backaddress=false,
+;; fromalign=left,
+;; fromemail=true,
+;; fromphone=true\]\{scrlttr2\}
+;; \[DEFAULT-PACKAGES]
+;; \[PACKAGES]
+;; \[EXTRA]"))
+;;
+;; Then, in your Org document, be sure to require the proper class
+;; with:
+;;
+;; #+LATEX_CLASS: my-letter
+;;
+;; Or by setting `org-koma-letter-default-class'.
+;;
+;; You may have to load (LaTeX) Babel as well, e.g., by adding
+;; it to `org-latex-packages-alist',
+;;
+;; (add-to-list 'org-latex-packages-alist '("AUTO" "babel" nil))
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'ox-latex)
+
+;; Install a default letter class.
+(unless (assoc "default-koma-letter" org-latex-classes)
+ (add-to-list 'org-latex-classes
+ '("default-koma-letter" "\\documentclass[11pt]{scrlttr2}")))
+
+
+;;; User-Configurable Variables
+
+(defgroup org-export-koma-letter nil
+ "Options for exporting to KOMA scrlttr2 class in LaTeX export."
+ :tag "Org Koma-Letter"
+ :group 'org-export)
+
+(defcustom org-koma-letter-class-option-file "NF"
+ "Letter Class Option File.
+This option can also be set with the LCO keyword."
+ :type 'string)
+
+(defcustom org-koma-letter-author 'user-full-name
+ "Sender's name.
+
+This variable defaults to calling the function `user-full-name'
+which just returns the current function `user-full-name'.
+Alternatively a string, nil or a function may be given.
+Functions must return a string.
+
+This option can also be set with the AUTHOR keyword."
+ :type '(radio (function-item user-full-name)
+ (string)
+ (function)
+ (const :tag "Do not export author" nil)))
+
+(defcustom org-koma-letter-email 'org-koma-letter-email
+ "Sender's email address.
+
+This variable defaults to the value `org-koma-letter-email' which
+returns `user-mail-address'. Alternatively a string, nil or
+a function may be given. Functions must return a string.
+
+This option can also be set with the EMAIL keyword."
+ :type '(radio (function-item org-koma-letter-email)
+ (string)
+ (function)
+ (const :tag "Do not export email" nil)))
+
+(defcustom org-koma-letter-from-address ""
+ "Sender's address, as a string.
+This option can also be set with one or more FROM_ADDRESS
+keywords."
+ :type 'string)
+
+(defcustom org-koma-letter-phone-number ""
+ "Sender's phone number, as a string.
+This option can also be set with the PHONE_NUMBER keyword."
+ :type 'string)
+
+(defcustom org-koma-letter-url ""
+ "Sender's URL, e. g., the URL of her homepage.
+This option can also be set with the URL keyword."
+ :type 'string
+ :safe #'stringp)
+
+(defcustom org-koma-letter-from-logo ""
+ "Commands for inserting the sender's logo, e. g., \\includegraphics{logo}.
+This option can also be set with the FROM_LOGO keyword."
+ :type 'string
+ :safe #'stringp)
+
+(defcustom org-koma-letter-place ""
+ "Place from which the letter is sent, as a string.
+This option can also be set with the PLACE keyword."
+ :type 'string)
+
+(defcustom org-koma-letter-location ""
+ "Sender's extension field, as a string.
+
+This option can also be set with the LOCATION keyword.
+Moreover, when:
+ (1) Either `org-koma-letter-prefer-special-headings' is non-nil
+ or there is no LOCATION keyword or the LOCATION keyword is
+ empty;
+ (2) the letter contains a headline with the special
+ tag \"location\";
+then the location will be set as the content of the location
+special heading.
+
+The location field is typically printed right of the address
+field (See Figure 4.9. in the English manual of 2015-10-03)."
+ :type 'string)
+
+(defcustom org-koma-letter-opening ""
+ "Letter's opening, as a string.
+
+This option can also be set with the OPENING keyword. Moreover,
+when:
+ (1) Either `org-koma-letter-prefer-special-headings' is non-nil
+ or the CLOSING keyword is empty
+ (2) `org-koma-letter-headline-is-opening-maybe' is non-nil;
+ (3) the letter contains a headline without a special
+ tag (e.g. \"to\" or \"ps\");
+then the opening will be implicitly set as the untagged headline title."
+ :type 'string)
+
+(defcustom org-koma-letter-closing ""
+ "Letter's closing, as a string.
+This option can also be set with the CLOSING keyword. Moreover,
+when:
+ (1) Either `org-koma-letter-prefer-special-headings' is non-nil
+ or the CLOSING keyword is empty;
+ (2) `org-koma-letter-headline-is-opening-maybe' is non-nil;
+ (3) the letter contains a headline with the special
+ tag \"closing\";
+then the opening will be set as the title of the closing special
+heading title."
+ :type 'string)
+
+(defcustom org-koma-letter-signature ""
+ "Signature, as a string.
+This option can also be set with the SIGNATURE keyword.
+Moreover, when:
+ (1) Either `org-koma-letter-prefer-special-headings' is non-nil
+ or there is no CLOSING keyword or the CLOSING keyword is empty;
+ (2) `org-koma-letter-headline-is-opening-maybe' is non-nil;
+ (3) the letter contains a headline with the special
+ tag \"closing\";
+then the signature will be set as the content of the
+closing special heading.
+
+Note if the content is empty the signature will not be set."
+ :type 'string)
+
+(defcustom org-koma-letter-prefer-special-headings nil
+ "Non-nil means prefer headlines over keywords for TO and FROM.
+This option can also be set with the OPTIONS keyword, e.g.:
+\"special-headings:t\"."
+ :type 'boolean)
+
+(defcustom org-koma-letter-subject-format t
+ "Non-nil means include the subject.
+
+Support formatting options.
+
+When t, insert a subject using default options. When nil, do not
+insert a subject at all. It can also be a list of symbols among
+the following ones:
+
+ `afteropening' Subject after opening
+ `beforeopening' Subject before opening
+ `centered' Subject centered
+ `left' Subject left-justified
+ `right' Subject right-justified
+ `titled' Add title/description to subject
+ `underlined' Set subject underlined
+ `untitled' Do not add title/description to subject
+
+Please refer to the KOMA-script manual (Table 4.16. in the
+English manual of 2012-07-22).
+
+This option can also be set with the OPTIONS keyword, e.g.:
+\"subject:(underlined centered)\"."
+ :type
+ '(choice
+ (const :tag "No export" nil)
+ (const :tag "Default options" t)
+ (set :tag "Configure options"
+ (const :tag "Subject after opening" afteropening)
+ (const :tag "Subject before opening" beforeopening)
+ (const :tag "Subject centered" centered)
+ (const :tag "Subject left-justified" left)
+ (const :tag "Subject right-justified" right)
+ (const :tag "Add title or description to subject" underlined)
+ (const :tag "Set subject underlined" titled)
+ (const :tag "Do not add title or description to subject" untitled))))
+
+(defcustom org-koma-letter-use-backaddress nil
+ "Non-nil prints return address in line above to address.
+This option can also be set with the OPTIONS keyword, e.g.:
+\"backaddress:t\"."
+ :type 'boolean)
+
+(defcustom org-koma-letter-use-foldmarks t
+ "Configure appearance of folding marks.
+
+When t, activate default folding marks. When nil, do not insert
+folding marks at all. It can also be a list of symbols among the
+following ones:
+
+ `B' Activate upper horizontal mark on left paper edge
+ `b' Deactivate upper horizontal mark on left paper edge
+
+ `H' Activate all horizontal marks on left paper edge
+ `h' Deactivate all horizontal marks on left paper edge
+
+ `L' Activate left vertical mark on upper paper edge
+ `l' Deactivate left vertical mark on upper paper edge
+
+ `M' Activate middle horizontal mark on left paper edge
+ `m' Deactivate middle horizontal mark on left paper edge
+
+ `P' Activate punch or center mark on left paper edge
+ `p' Deactivate punch or center mark on left paper edge
+
+ `T' Activate lower horizontal mark on left paper edge
+ `t' Deactivate lower horizontal mark on left paper edge
+
+ `V' Activate all vertical marks on upper paper edge
+ `v' Deactivate all vertical marks on upper paper edge
+
+This option can also be set with the OPTIONS keyword, e.g.:
+\"foldmarks:(b l m t)\"."
+ :type '(choice
+ (const :tag "Activate default folding marks" t)
+ (const :tag "Deactivate folding marks" nil)
+ (set
+ :tag "Configure folding marks"
+ (const :tag "Activate upper horizontal mark on left paper edge" B)
+ (const :tag "Deactivate upper horizontal mark on left paper edge" b)
+ (const :tag "Activate all horizontal marks on left paper edge" H)
+ (const :tag "Deactivate all horizontal marks on left paper edge" h)
+ (const :tag "Activate left vertical mark on upper paper edge" L)
+ (const :tag "Deactivate left vertical mark on upper paper edge" l)
+ (const :tag "Activate middle horizontal mark on left paper edge" M)
+ (const :tag "Deactivate middle horizontal mark on left paper edge" m)
+ (const :tag "Activate punch or center mark on left paper edge" P)
+ (const :tag "Deactivate punch or center mark on left paper edge" p)
+ (const :tag "Activate lower horizontal mark on left paper edge" T)
+ (const :tag "Deactivate lower horizontal mark on left paper edge" t)
+ (const :tag "Activate all vertical marks on upper paper edge" V)
+ (const :tag "Deactivate all vertical marks on upper paper edge" v))))
+
+(defcustom org-koma-letter-use-phone nil
+ "Non-nil prints sender's phone number.
+This option can also be set with the OPTIONS keyword, e.g.:
+\"phone:t\"."
+ :type 'boolean)
+
+(defcustom org-koma-letter-use-url nil
+ "Non-nil prints sender's URL.
+This option can also be set with the OPTIONS keyword, e.g.:
+\"url:t\"."
+ :type 'boolean
+ :safe #'booleanp)
+
+(defcustom org-koma-letter-use-from-logo nil
+ "Non-nil prints sender's FROM_LOGO.
+This option can also be set with the OPTIONS keyword, e.g.:
+\"from-logo:t\"."
+ :type 'boolean
+ :safe #'booleanp)
+
+(defcustom org-koma-letter-use-email nil
+ "Non-nil prints sender's email address.
+This option can also be set with the OPTIONS keyword, e.g.:
+\"email:t\"."
+ :type 'boolean)
+
+(defcustom org-koma-letter-use-place t
+ "Non-nil prints the letter's place next to the date.
+This option can also be set with the OPTIONS keyword, e.g.:
+\"place:nil\"."
+ :type 'boolean)
+
+(defcustom org-koma-letter-default-class "default-koma-letter"
+ "Default class for `org-koma-letter'.
+The value must be a member of `org-latex-classes'."
+ :type 'string)
+
+(defcustom org-koma-letter-headline-is-opening-maybe t
+ "Non-nil means a headline may be used as an opening and closing.
+See also `org-koma-letter-opening' and
+`org-koma-letter-closing'."
+ :type 'boolean)
+
+(defcustom org-koma-letter-prefer-subject nil
+ "Non-nil means title should be interpreted as subject if subject is missing.
+This option can also be set with the OPTIONS keyword,
+e.g. \"title-subject:t\"."
+ :type 'boolean)
+
+(defconst org-koma-letter-special-tags-in-letter '(to from closing location)
+ "Header tags related to the letter itself.")
+
+(defconst org-koma-letter-special-tags-after-closing '(after_closing ps encl cc)
+ "Header tags to be inserted in the letter after closing.")
+
+(defconst org-koma-letter-special-tags-as-macro '(ps encl cc)
+ "Header tags to be inserted as macros.")
+
+(defconst org-koma-letter-special-tags-after-letter '(after_letter)
+ "Header tags to be inserted after the letter.")
+
+(defvar org-koma-letter-special-contents nil
+ "Holds special content temporarily.")
+
+
+;;; Define Back-End
+
+(org-export-define-derived-backend 'koma-letter 'latex
+ :options-alist
+ '((:latex-class "LATEX_CLASS" nil org-koma-letter-default-class t)
+ (:lco "LCO" nil org-koma-letter-class-option-file)
+ (:author "AUTHOR" nil (org-koma-letter--get-value org-koma-letter-author) parse)
+ (:author-changed-in-buffer-p "AUTHOR" nil nil t)
+ (:from-address "FROM_ADDRESS" nil org-koma-letter-from-address newline)
+ (:phone-number "PHONE_NUMBER" nil org-koma-letter-phone-number)
+ (:url "URL" nil org-koma-letter-url)
+ (:from-logo "FROM_LOGO" nil org-koma-letter-from-logo)
+ (:email "EMAIL" nil (org-koma-letter--get-value org-koma-letter-email) t)
+ (:to-address "TO_ADDRESS" nil nil newline)
+ (:place "PLACE" nil org-koma-letter-place)
+ (:location "LOCATION" nil org-koma-letter-location)
+ (:subject "SUBJECT" nil nil parse)
+ (:opening "OPENING" nil org-koma-letter-opening parse)
+ (:closing "CLOSING" nil org-koma-letter-closing parse)
+ (:signature "SIGNATURE" nil org-koma-letter-signature newline)
+ (:special-headings nil "special-headings" org-koma-letter-prefer-special-headings)
+ (:special-tags-as-macro nil nil org-koma-letter-special-tags-as-macro)
+ (:special-tags-in-letter nil nil org-koma-letter-special-tags-in-letter)
+ (:special-tags-after-closing nil "after-closing-order"
+ org-koma-letter-special-tags-after-closing)
+ (:special-tags-after-letter nil "after-letter-order"
+ org-koma-letter-special-tags-after-letter)
+ (:with-backaddress nil "backaddress" org-koma-letter-use-backaddress)
+ (:with-email nil "email" org-koma-letter-use-email)
+ (:with-foldmarks nil "foldmarks" org-koma-letter-use-foldmarks)
+ (:with-phone nil "phone" org-koma-letter-use-phone)
+ (:with-url nil "url" org-koma-letter-use-url)
+ (:with-from-logo nil "from-logo" org-koma-letter-use-from-logo)
+ (:with-place nil "place" org-koma-letter-use-place)
+ (:with-subject nil "subject" org-koma-letter-subject-format)
+ (:with-title-as-subject nil "title-subject" org-koma-letter-prefer-subject)
+ (:with-headline-opening nil nil org-koma-letter-headline-is-opening-maybe)
+ ;; Special properties non-nil when a setting happened in buffer.
+ ;; They are used to prioritize in-buffer settings over "lco"
+ ;; files. See `org-koma-letter-template'.
+ (:inbuffer-author "AUTHOR" nil 'koma-letter:empty)
+ (:inbuffer-from "FROM" nil 'koma-letter:empty)
+ (:inbuffer-email "EMAIL" nil 'koma-letter:empty)
+ (:inbuffer-phone-number "PHONE_NUMBER" nil 'koma-letter:empty)
+ (:inbuffer-url "URL" nil 'koma-letter:empty)
+ (:inbuffer-from-logo "FROM_LOGO" nil 'koma-letter:empty)
+ (:inbuffer-place "PLACE" nil 'koma-letter:empty)
+ (:inbuffer-location "LOCATION" nil 'koma-letter:empty)
+ (:inbuffer-signature "SIGNATURE" nil 'koma-letter:empty)
+ (:inbuffer-with-backaddress nil "backaddress" 'koma-letter:empty)
+ (:inbuffer-with-email nil "email" 'koma-letter:empty)
+ (:inbuffer-with-foldmarks nil "foldmarks" 'koma-letter:empty)
+ (:inbuffer-with-phone nil "phone" 'koma-letter:empty)
+ (:inbuffer-with-url nil "url" 'koma-letter:empty)
+ (:inbuffer-with-from-logo nil "from-logo" 'koma-letter:empty)
+ (:inbuffer-with-place nil "place" 'koma-letter:empty))
+ :translate-alist '((export-block . org-koma-letter-export-block)
+ (export-snippet . org-koma-letter-export-snippet)
+ (headline . org-koma-letter-headline)
+ (keyword . org-koma-letter-keyword)
+ (template . org-koma-letter-template))
+ :menu-entry
+ '(?k "Export with KOMA Scrlttr2"
+ ((?L "As LaTeX buffer" org-koma-letter-export-as-latex)
+ (?l "As LaTeX file" org-koma-letter-export-to-latex)
+ (?p "As PDF file" org-koma-letter-export-to-pdf)
+ (?o "As PDF file and open"
+ (lambda (a s v b)
+ (if a (org-koma-letter-export-to-pdf t s v b)
+ (org-open-file (org-koma-letter-export-to-pdf nil s v b))))))))
+
+
+
+;;; Helper functions
+
+(defun org-koma-letter-email ()
+ "Return the current `user-mail-address'."
+ user-mail-address)
+
+;; The following is taken from/inspired by ox-grof.el
+;; Thanks, Luis!
+
+(defun org-koma-letter--get-tagged-contents (key)
+ "Get contents from a headline tagged with KEY.
+The contents is stored in `org-koma-letter-special-contents'."
+ (let ((value (cdr (assoc-string (org-koma-letter--get-value key)
+ org-koma-letter-special-contents))))
+ (when value (org-string-nw-p (org-trim value)))))
+
+(defun org-koma-letter--get-value (value)
+ "Turn value into a string whenever possible.
+Determines if VALUE is nil, a string, a function or a symbol and
+return a string or nil."
+ (when value
+ (cond ((stringp value) value)
+ ((functionp value) (funcall value))
+ ((symbolp value) (symbol-name value))
+ (t value))))
+
+(defun org-koma-letter--special-contents-inline (keywords info)
+ "Process KEYWORDS members of `org-koma-letter-special-contents'.
+
+KEYWORDS is a list of symbols. Return them as a string to be
+formatted.
+
+The function is used for inserting content of special headings
+such as the one tagged with PS."
+ (mapconcat
+ (lambda (keyword)
+ (let* ((name (org-koma-letter--get-value keyword))
+ (value (org-koma-letter--get-tagged-contents name))
+ (macrop (memq keyword (plist-get info :special-tags-as-macro))))
+ (cond ((not value) nil)
+ (macrop (format "\\%s{%s}\n" name value))
+ (t value))))
+ keywords
+ "\n"))
+
+
+(defun org-koma-letter--add-latex-newlines (string)
+ "Replace regular newlines with LaTeX newlines (i.e. `\\\\')."
+ (let ((str (org-trim string)))
+ (when (org-string-nw-p str)
+ (replace-regexp-in-string "\n" "\\\\\\\\\n" str))))
+
+
+
+;;; Transcode Functions
+
+;;;; Export Block
+
+(defun org-koma-letter-export-block (export-block _contents _info)
+ "Transcode an EXPORT-BLOCK element into KOMA Scrlttr2 code.
+CONTENTS is nil. INFO is a plist used as a communication
+channel."
+ (when (member (org-element-property :type export-block)
+ '("KOMA-LETTER" "LATEX"))
+ (org-remove-indentation (org-element-property :value export-block))))
+
+;;;; Export Snippet
+
+(defun org-koma-letter-export-snippet (export-snippet _contents _info)
+ "Transcode an EXPORT-SNIPPET object into KOMA Scrlttr2 code.
+CONTENTS is nil. INFO is a plist used as a communication
+channel."
+ (when (memq (org-export-snippet-backend export-snippet) '(latex koma-letter))
+ (org-element-property :value export-snippet)))
+
+;;;; Keyword
+
+(defun org-koma-letter-keyword (keyword contents info)
+ "Transcode a KEYWORD element into KOMA Scrlttr2 code.
+CONTENTS is nil. INFO is a plist used as a communication
+channel."
+ (let ((key (org-element-property :key keyword))
+ (value (org-element-property :value keyword)))
+ ;; Handle specifically KOMA-LETTER keywords. Otherwise, fallback
+ ;; to `latex' back-end.
+ (if (equal key "KOMA-LETTER") value
+ (org-export-with-backend 'latex keyword contents info))))
+
+;; Headline
+
+(defun org-koma-letter-headline (headline contents info)
+ "Transcode a HEADLINE element from Org to LaTeX.
+CONTENTS holds the contents of the headline. INFO is a plist
+holding contextual information.
+
+Note that if a headline is tagged with a tag from
+`org-koma-letter-special-tags' it will not be exported, but
+stored in `org-koma-letter-special-contents' and included at the
+appropriate place."
+ (let ((special-tag (org-koma-letter--special-tag headline info)))
+ (if (not special-tag)
+ contents
+ (push (cons special-tag contents) org-koma-letter-special-contents)
+ "")))
+
+(defun org-koma-letter--special-tag (headline info)
+ "Non-nil if HEADLINE is a special headline.
+INFO is a plist holding contextual information. Return first
+special tag headline."
+ (let ((special-tags (append
+ (plist-get info :special-tags-in-letter)
+ (plist-get info :special-tags-after-closing)
+ (plist-get info :special-tags-after-letter))))
+ (cl-some (lambda (tag) (and (assoc-string tag special-tags) tag))
+ (org-export-get-tags headline info))))
+
+(defun org-koma-letter--keyword-or-headline (plist-key pred info)
+ "Return the correct version of opening or closing.
+PLIST-KEY should be a key in info, typically :opening
+or :closing. PRED is a predicate run on headline to determine
+which title to use which takes two arguments, a headline element
+and an info plist. INFO is a plist holding contextual
+information. Return the preferred candidate for the exported of
+PLIST-KEY."
+ (let* ((keyword-candidate (plist-get info plist-key))
+ (headline-candidate (when (and (plist-get info :with-headline-opening)
+ (or (plist-get info :special-headings)
+ (not keyword-candidate)))
+ (org-element-map (plist-get info :parse-tree)
+ 'headline
+ (lambda (h)
+ (and (funcall pred h info)
+ (org-element-property :title h)))
+ info t))))
+ (org-export-data (or headline-candidate keyword-candidate "") info)))
+
+;;;; Template
+
+(defun org-koma-letter-template (contents info)
+ "Return complete document string after KOMA Scrlttr2 conversion.
+CONTENTS is the transcoded contents string. INFO is a plist
+holding export options."
+ (concat
+ ;; Time-stamp.
+ (and (plist-get info :time-stamp-file)
+ (format-time-string "%% Created %Y-%m-%d %a %H:%M\n"))
+ ;; LaTeX compiler
+ (org-latex--insert-compiler info)
+ ;; Document class and packages.
+ (org-latex-make-preamble info)
+ ;; Settings. They can come from three locations, in increasing
+ ;; order of precedence: global variables, LCO files and in-buffer
+ ;; settings. Thus, we first insert settings coming from global
+ ;; variables, then we insert LCO files, and, eventually, we insert
+ ;; settings coming from buffer keywords.
+ (org-koma-letter--build-settings 'global info)
+ (mapconcat (lambda (file) (format "\\LoadLetterOption{%s}\n" file))
+ (split-string (or (plist-get info :lco) ""))
+ "")
+ (org-koma-letter--build-settings 'buffer info)
+ ;; Date.
+ (format "\\date{%s}\n" (org-export-data (org-export-get-date info) info))
+ ;; Hyperref, document start, and subject and title.
+ (let* ((with-subject (plist-get info :with-subject))
+ (with-title (plist-get info :with-title))
+ (title-as-subject (and with-subject
+ (plist-get info :with-title-as-subject)))
+ (subject* (org-string-nw-p
+ (org-export-data (plist-get info :subject) info)))
+ (title* (and with-title
+ (org-string-nw-p
+ (org-export-data (plist-get info :title) info))))
+ (subject (cond ((not with-subject) nil)
+ (title-as-subject (or subject* title*))
+ (t subject*)))
+ (title (cond ((not with-title) nil)
+ (title-as-subject (and subject* title*))
+ (t title*)))
+ (hyperref-template (plist-get info :latex-hyperref-template))
+ (spec (append (list (cons ?t (or title subject "")))
+ (org-latex--format-spec info))))
+ (concat
+ (when (and with-subject (not (eq with-subject t)))
+ (format "\\KOMAoption{subject}{%s}\n"
+ (if (symbolp with-subject) with-subject
+ (mapconcat #'symbol-name with-subject ","))))
+ ;; Hyperref.
+ (and (stringp hyperref-template)
+ (format-spec hyperref-template spec))
+ ;; Document start.
+ "\\begin{document}\n\n"
+ ;; Subject and title.
+ (when subject (format "\\setkomavar{subject}{%s}\n" subject))
+ (when title (format "\\setkomavar{title}{%s}\n" title))
+ (when (or (org-string-nw-p title) (org-string-nw-p subject)) "\n")))
+ ;; Letter start.
+ (let ((keyword-val (plist-get info :to-address))
+ (heading-val (org-koma-letter--get-tagged-contents 'to)))
+ (format "\\begin{letter}{%%\n%s}\n\n"
+ (org-koma-letter--add-latex-newlines
+ (or (if (plist-get info :special-headings)
+ (or heading-val keyword-val)
+ (or keyword-val heading-val))
+ "\\mbox{}"))))
+ ;; Opening.
+ (format "\\opening{%s}\n\n"
+ (org-koma-letter--keyword-or-headline
+ :opening
+ (lambda (h i)
+ (not (org-koma-letter--special-tag h i)))
+ info))
+ ;; Letter body.
+ contents
+ ;; Closing.
+ (format "\\closing{%s}\n"
+ (org-koma-letter--keyword-or-headline
+ :closing
+ (lambda (h i)
+ (let ((special-tag (org-koma-letter--special-tag h i)))
+ (and special-tag
+ (string= "closing" special-tag))))
+ info))
+ (org-koma-letter--special-contents-inline
+ (plist-get info :special-tags-after-closing) info)
+ ;; Letter end.
+ "\n\\end{letter}\n"
+ (org-koma-letter--special-contents-inline
+ (plist-get info :special-tags-after-letter) info)
+ ;; Document end.
+ "\n\\end{document}"))
+
+(defun org-koma-letter--build-settings (scope info)
+ "Build settings string according to type.
+SCOPE is either `global' or `buffer'. INFO is a plist used as
+a communication channel."
+ (let* ((check-scope
+ ;; Non-nil value when SETTING was defined in SCOPE.
+ (lambda (setting)
+ (let ((property (intern (format ":inbuffer-%s" setting))))
+ (if (eq scope 'global)
+ (eq (plist-get info property) 'koma-letter:empty)
+ (not (eq (plist-get info property) 'koma-letter:empty))))))
+ (heading-or-key-value
+ (lambda (heading key &optional scoped)
+ (let* ((heading-val
+ (org-koma-letter--get-tagged-contents heading))
+ (key-val (org-string-nw-p (plist-get info key)))
+ (scopedp (funcall check-scope (or scoped heading))))
+ (and (or (and key-val scopedp) heading-val)
+ (not (and (eq scope 'global) heading-val))
+ (if scopedp key-val heading-val))))))
+ (concat
+ ;; Name.
+ (let ((author (plist-get info :author)))
+ (and author
+ (funcall check-scope 'author)
+ (format "\\setkomavar{fromname}{%s}\n"
+ (org-export-data author info))))
+ ;; From.
+ (let ((from (funcall heading-or-key-value 'from :from-address)))
+ (and from
+ (format "\\setkomavar{fromaddress}{%s}\n"
+ (org-koma-letter--add-latex-newlines from))))
+ ;; Email.
+ (let ((email (plist-get info :email)))
+ (and email
+ (funcall check-scope 'email)
+ (format "\\setkomavar{fromemail}{%s}\n" email)))
+ (and (funcall check-scope 'with-email)
+ (format "\\KOMAoption{fromemail}{%s}\n"
+ (if (plist-get info :with-email) "true" "false")))
+ ;; Phone number.
+ (let ((phone-number (plist-get info :phone-number)))
+ (and (org-string-nw-p phone-number)
+ (funcall check-scope 'phone-number)
+ (format "\\setkomavar{fromphone}{%s}\n" phone-number)))
+ (and (funcall check-scope 'with-phone)
+ (format "\\KOMAoption{fromphone}{%s}\n"
+ (if (plist-get info :with-phone) "true" "false")))
+ ;; URL
+ (let ((url (plist-get info :url)))
+ (and (org-string-nw-p url)
+ (funcall check-scope 'url)
+ (format "\\setkomavar{fromurl}{%s}\n" url)))
+ (and (funcall check-scope 'with-url)
+ (format "\\KOMAoption{fromurl}{%s}\n"
+ (if (plist-get info :with-url) "true" "false")))
+ ;; From Logo
+ (let ((from-logo (plist-get info :from-logo)))
+ (and (org-string-nw-p from-logo)
+ (funcall check-scope 'from-logo)
+ (format "\\setkomavar{fromlogo}{%s}\n" from-logo)))
+ (and (funcall check-scope 'with-from-logo)
+ (format "\\KOMAoption{fromlogo}{%s}\n"
+ (if (plist-get info :with-from-logo) "true" "false")))
+ ;; Signature.
+ (let* ((heading-val
+ (and (plist-get info :with-headline-opening)
+ (pcase (org-koma-letter--get-tagged-contents 'closing)
+ ((and (pred org-string-nw-p) closing) (org-trim closing))
+ (_ nil))))
+ (signature (org-string-nw-p (plist-get info :signature)))
+ (signature-scope (funcall check-scope 'signature)))
+ (and (or (and signature signature-scope)
+ heading-val)
+ (not (and (eq scope 'global) heading-val))
+ (format "\\setkomavar{signature}{%s}\n"
+ (if signature-scope signature heading-val))))
+ ;; Back address.
+ (and (funcall check-scope 'with-backaddress)
+ (format "\\KOMAoption{backaddress}{%s}\n"
+ (if (plist-get info :with-backaddress) "true" "false")))
+ ;; Place.
+ (let ((with-place-set (funcall check-scope 'with-place))
+ (place-set (funcall check-scope 'place)))
+ (and (or (and with-place-set place-set)
+ (and (eq scope 'buffer) (or with-place-set place-set)))
+ (format "\\setkomavar{place}{%s}\n"
+ (if (plist-get info :with-place) (plist-get info :place)
+ ""))))
+ ;; Location.
+ (let ((location (funcall heading-or-key-value 'location :location)))
+ (and location
+ (format "\\setkomavar{location}{%s}\n" location)))
+ ;; Folding marks.
+ (and (funcall check-scope 'with-foldmarks)
+ (let ((foldmarks (plist-get info :with-foldmarks)))
+ (cond ((consp foldmarks)
+ (format "\\KOMAoptions{foldmarks=true,foldmarks=%s}\n"
+ (mapconcat #'symbol-name foldmarks "")))
+ (foldmarks "\\KOMAoptions{foldmarks=true}\n")
+ (t "\\KOMAoptions{foldmarks=false}\n")))))))
+
+
+
+;;; Commands
+
+;;;###autoload
+(defun org-koma-letter-export-as-latex
+ (&optional async subtreep visible-only body-only ext-plist)
+ "Export current buffer as a KOMA Scrlttr2 letter.
+
+If narrowing is active in the current buffer, only export its
+narrowed part.
+
+If a region is active, export that region.
+
+A non-nil optional argument ASYNC means the process should happen
+asynchronously. The resulting buffer should be accessible
+through the `org-export-stack' interface.
+
+When optional argument SUBTREEP is non-nil, export the sub-tree
+at point, extracting information from the headline properties
+first.
+
+When optional argument VISIBLE-ONLY is non-nil, don't export
+contents of hidden elements.
+
+When optional argument BODY-ONLY is non-nil, only write code
+between \"\\begin{letter}\" and \"\\end{letter}\".
+
+EXT-PLIST, when provided, is a property list with external
+parameters overriding Org default settings, but still inferior to
+file-local settings.
+
+Export is done in a buffer named \"*Org KOMA-LETTER Export*\". It
+will be displayed if `org-export-show-temporary-export-buffer' is
+non-nil."
+ (interactive)
+ (let (org-koma-letter-special-contents)
+ (org-export-to-buffer 'koma-letter "*Org KOMA-LETTER Export*"
+ async subtreep visible-only body-only ext-plist
+ (lambda () (LaTeX-mode)))))
+
+;;;###autoload
+(defun org-koma-letter-export-to-latex
+ (&optional async subtreep visible-only body-only ext-plist)
+ "Export current buffer as a KOMA Scrlttr2 letter (tex).
+
+If narrowing is active in the current buffer, only export its
+narrowed part.
+
+If a region is active, export that region.
+
+A non-nil optional argument ASYNC means the process should happen
+asynchronously. The resulting file should be accessible through
+the `org-export-stack' interface.
+
+When optional argument SUBTREEP is non-nil, export the sub-tree
+at point, extracting information from the headline properties
+first.
+
+When optional argument VISIBLE-ONLY is non-nil, don't export
+contents of hidden elements.
+
+When optional argument BODY-ONLY is non-nil, only write code
+between \"\\begin{letter}\" and \"\\end{letter}\".
+
+EXT-PLIST, when provided, is a property list with external
+parameters overriding Org default settings, but still inferior to
+file-local settings.
+
+When optional argument PUB-DIR is set, use it as the publishing
+directory.
+
+Return output file's name."
+ (interactive)
+ (let ((outfile (org-export-output-file-name ".tex" subtreep))
+ (org-koma-letter-special-contents))
+ (org-export-to-file 'koma-letter outfile
+ async subtreep visible-only body-only ext-plist)))
+
+;;;###autoload
+(defun org-koma-letter-export-to-pdf
+ (&optional async subtreep visible-only body-only ext-plist)
+ "Export current buffer as a KOMA Scrlttr2 letter (pdf).
+
+If narrowing is active in the current buffer, only export its
+narrowed part.
+
+If a region is active, export that region.
+
+A non-nil optional argument ASYNC means the process should happen
+asynchronously. The resulting file should be accessible through
+the `org-export-stack' interface.
+
+When optional argument SUBTREEP is non-nil, export the sub-tree
+at point, extracting information from the headline properties
+first.
+
+When optional argument VISIBLE-ONLY is non-nil, don't export
+contents of hidden elements.
+
+When optional argument BODY-ONLY is non-nil, only write code
+between \"\\begin{letter}\" and \"\\end{letter}\".
+
+EXT-PLIST, when provided, is a property list with external
+parameters overriding Org default settings, but still inferior to
+file-local settings.
+
+Return PDF file's name."
+ (interactive)
+ (let ((file (org-export-output-file-name ".tex" subtreep))
+ (org-koma-letter-special-contents))
+ (org-export-to-file 'koma-letter file
+ async subtreep visible-only body-only ext-plist
+ #'org-latex-compile)))
+
+
+(provide 'ox-koma-letter)
+;;; ox-koma-letter.el ends here
diff --git a/lisp/org/ox-latex.el b/lisp/org/ox-latex.el
index 149492fa849..c45dc98a09d 100644
--- a/lisp/org/ox-latex.el
+++ b/lisp/org/ox-latex.el
@@ -121,6 +121,7 @@
(:latex-classes nil nil org-latex-classes)
(:latex-default-figure-position nil nil org-latex-default-figure-position)
(:latex-default-table-environment nil nil org-latex-default-table-environment)
+ (:latex-default-quote-environment nil nil org-latex-default-quote-environment)
(:latex-default-table-mode nil nil org-latex-default-table-mode)
(:latex-diary-timestamp-format nil nil org-latex-diary-timestamp-format)
(:latex-footnote-defined-format nil nil org-latex-footnote-defined-format)
@@ -296,7 +297,7 @@
("uk" "ukrainian")
("ur" "urdu")
("vi" "vietnamese"))
- "Alist between language code and corresponding Polyglossia option")
+ "Alist between language code and corresponding Polyglossia option.")
(defconst org-latex-table-matrix-macros '(("bordermatrix" . "\\cr")
("qbordermatrix" . "\\cr")
@@ -307,14 +308,14 @@
(format
"\\`[ \t]*\\\\begin{%s\\*?}"
(regexp-opt
- '("equation" "eqnarray" "math" "displaymath"
- "align" "gather" "multline" "flalign" "alignat"
- "xalignat" "xxalignat"
- "subequations"
- ;; breqn
- "dmath" "dseries" "dgroup" "darray"
- ;; empheq
- "empheq")))
+ '("equation" "eqnarray" "math" "displaymath"
+ "align" "gather" "multline" "flalign" "alignat"
+ "xalignat" "xxalignat"
+ "subequations"
+ ;; breqn
+ "dmath" "dseries" "dgroup" "darray"
+ ;; empheq
+ "empheq")))
"Regexp of LaTeX math environments.")
@@ -345,7 +346,7 @@ symbols are: `image', `table', `src-block' and `special-block'."
(const :tag "Special blocks" special-block))))
(defcustom org-latex-prefer-user-labels nil
- "Use user-provided labels instead of internal ones when non-nil.
+ "Use user-provided labels instead of internal ones when non-nil.
When this variable is non-nil, Org will use the value of
CUSTOM_ID property, NAME keyword or Org target as the key for the
@@ -380,6 +381,9 @@ will be exported to LaTeX as:
This is section \\ref{sec:foo}.
And this is still section \\ref{sec:foo}.
+A non-default value of `org-latex-reference-command' will change the
+command (\\ref by default) used to create label references.
+
Note, however, that setting this variable introduces a limitation
on the possible values for CUSTOM_ID and NAME. When this
variable is non-nil, Org passes their value to \\label unchanged.
@@ -399,6 +403,18 @@ references."
:version "26.1"
:package-version '(Org . "8.3"))
+(defcustom org-latex-reference-command "\\ref{%s}"
+ "Format string that takes a reference to produce a LaTeX reference command.
+
+The reference is a label such as sec:intro. A format string of \"\\ref{%s}\"
+produces numbered references and will always work. It may be desirable to make
+use of a package such as hyperref or cleveref and then change the format string
+to \"\\autoref{%s}\" or \"\\cref{%s}\" for example."
+ :group 'org-export-latex
+ :type 'string
+ :package-version '(Org . "9.5")
+ :safe #'stringp)
+
;;;; Preamble
(defcustom org-latex-default-class "article"
@@ -772,6 +788,13 @@ default we use here encompasses both."
:package-version '(Org . "8.0")
:type 'string)
+(defcustom org-latex-default-quote-environment "quote"
+ "Default environment used to `quote' blocks."
+ :group 'org-export-latex
+ :package-version '(Org . "9.5")
+ :type 'string
+ :safe #'stringp)
+
(defcustom org-latex-default-table-mode 'table
"Default mode for tables.
@@ -932,7 +955,7 @@ using customize, or with
(add-to-list \\='org-latex-packages-alist \\='(\"newfloat\" \"minted\"))
In addition, it is necessary to install pygments
-\(URL `http://pygments.org>'), and to configure the variable
+\(URL `https://pygments.org>'), and to configure the variable
`org-latex-pdf-process' so that the -shell-escape option is
passed to pdflatex.
@@ -956,7 +979,7 @@ URL `https://orgmode.org/worg/org-tutorials/org-latex-preview.html'."
(tex "TeX") (latex "[LaTeX]TeX")
(shell-script "bash")
(gnuplot "Gnuplot")
- (ocaml "Caml") (caml "Caml")
+ (ocaml "[Objective]Caml") (caml "Caml")
(sql "SQL") (sqlite "sql")
(makefile "make")
(R "r"))
@@ -1157,9 +1180,11 @@ A better approach is to use a compiler suit such as `latexmk'."
:package-version '(Org . "9.0"))
(defcustom org-latex-pdf-process
- '("%latex -interaction nonstopmode -output-directory %o %f"
- "%latex -interaction nonstopmode -output-directory %o %f"
- "%latex -interaction nonstopmode -output-directory %o %f")
+ (if (executable-find "latexmk")
+ '("latexmk -f -pdf -%latex -interaction=nonstopmode -output-directory=%o %f")
+ '("%latex -interaction nonstopmode -output-directory %o %f"
+ "%latex -interaction nonstopmode -output-directory %o %f"
+ "%latex -interaction nonstopmode -output-directory %o %f"))
"Commands to process a LaTeX file to a PDF file.
This is a list of strings, each of them will be given to the
@@ -1203,7 +1228,7 @@ file name as its single argument."
(const :tag "texi2dvi"
("cd %o; LATEX=\"%latex\" texi2dvi -p -b -V %b.tex"))
(const :tag "latexmk"
- ("latexmk -g -pdf -pdflatex=\"%latex\" -outdir=%o %f"))
+ ("latexmk -f -pdf -%latex -interaction=nonstopmode -output-directory=%o %f"))
(function)))
(defcustom org-latex-logfiles-extensions
@@ -1486,7 +1511,10 @@ nil."
(pcase-let ((`(,keyword ,value) pair))
(concat keyword
(and (> (length value) 0)
- (concat "=" value)))))
+ (concat "="
+ (if (string-match-p (rx (any "[]")) value)
+ (format "{%s}" value)
+ value))))))
options
","))
@@ -1521,22 +1549,23 @@ INFO is a plist used as a communication channel. See
separator
(replace-regexp-in-string "\n" " " text)
separator)))
- ;; Handle the `protectedtexttt' special case: Protect some
- ;; special chars and use "\texttt{%s}" format string.
- (protectedtexttt
- (format "\\texttt{%s}"
- (replace-regexp-in-string
- "--\\|[\\{}$%&_#~^]"
- (lambda (m)
- (cond ((equal m "--") "-{}-")
- ((equal m "\\") "\\textbackslash{}")
- ((equal m "~") "\\textasciitilde{}")
- ((equal m "^") "\\textasciicircum{}")
- (t (org-latex--protect-text m))))
- text nil t)))
+ (protectedtexttt (org-latex--protect-texttt text))
;; Else use format string.
(t (format fmt text)))))
+(defun org-latex--protect-texttt (text)
+ "Protect special chars, then wrap TEXT in \"\\texttt{}\"."
+ (format "\\texttt{%s}"
+ (replace-regexp-in-string
+ "--\\|[\\{}$%&_#~^]"
+ (lambda (m)
+ (cond ((equal m "--") "-{}-")
+ ((equal m "\\") "\\textbackslash{}")
+ ((equal m "~") "\\textasciitilde{}")
+ ((equal m "^") "\\textasciicircum{}")
+ (t (org-latex--protect-text m))))
+ text nil t)))
+
(defun org-latex--delayed-footnotes-definitions (element info)
"Return footnotes definitions in ELEMENT as a string.
@@ -1604,9 +1633,9 @@ INFO is a plist used as a communication channel."
"Insert LaTeX_compiler info into the document.
INFO is a plist used as a communication channel."
(let ((compiler (plist-get info :latex-compiler)))
- (and (org-string-nw-p org-latex-compiler-file-string)
- (member (or compiler "") org-latex-compilers)
- (format org-latex-compiler-file-string compiler))))
+ (and (org-string-nw-p org-latex-compiler-file-string)
+ (member (or compiler "") org-latex-compilers)
+ (format org-latex-compiler-file-string compiler))))
;;; Filters
@@ -1888,10 +1917,11 @@ CONTENTS is nil. INFO is a plist holding contextual information."
(org-export-get-footnote-definition footnote-reference info)
info t)))
;; Use \footnotemark if reference is within another footnote
- ;; reference, footnote definition, table cell or item's tag.
+ ;; reference, footnote definition, table cell, verse block, or
+ ;; item's tag.
((or (org-element-lineage footnote-reference
'(footnote-reference footnote-definition
- table-cell))
+ table-cell verse-block))
(eq 'item (org-element-type
(org-export-get-parent-element footnote-reference))))
"\\footnotemark")
@@ -1903,7 +1933,8 @@ CONTENTS is nil. INFO is a plist holding contextual information."
;; Only insert a \label if there exist another
;; reference to def.
(cond ((not label) "")
- ((org-element-map (plist-get info :parse-tree) 'footnote-reference
+ ((org-element-map (plist-get info :parse-tree)
+ 'footnote-reference
(lambda (f)
(and (not (eq f footnote-reference))
(equal (org-element-property :label f) label)
@@ -1952,10 +1983,16 @@ holding contextual information."
;; Create a temporary export back-end that hard-codes
;; "\underline" within "\section" and alike.
(section-back-end
- (org-export-create-backend
- :parent 'latex
- :transcoders
- '((underline . (lambda (o c i) (format "\\underline{%s}" c))))))
+ (org-export-create-backend
+ :parent 'latex
+ :transcoders
+ '((underline . (lambda (o c i) (format "\\underline{%s}" c)))
+ ;; LaTeX isn't happy when you try to use \verb inside the argument of other
+ ;; commands (like \section, etc.), and this causes compilation to fail.
+ ;; So, within headings it's a good idea to replace any instances of \verb
+ ;; with \texttt.
+ (code . (lambda (o _ _) (org-latex--protect-texttt (org-element-property :value o))))
+ (verbatim . (lambda (o _ _) (org-latex--protect-texttt (org-element-property :value o)))))))
(text
(org-export-data-with-backend
(org-element-property :title headline) section-back-end info))
@@ -2089,8 +2126,8 @@ contextual information."
(let* ((code (org-element-property :value inline-src-block))
(separator (org-latex--find-verb-separator code)))
(cl-case (plist-get info :latex-listings)
- ;; Do not use a special package: transcode it verbatim.
- ((nil) (format "\\texttt{%s}" (org-latex--text-markup code 'code info)))
+ ;; Do not use a special package: transcode it verbatim, as code.
+ ((nil) (org-latex--text-markup code 'code info))
;; Use minted package.
(minted
(let* ((org-lang (org-element-property :language inline-src-block))
@@ -2375,8 +2412,8 @@ used as a communication channel."
((string= float "sideways") 'sideways)
((string= float "multicolumn") 'multicolumn)
((and (plist-member attr :float) (not float)) 'nonfloat)
- ((or float
- (org-element-property :caption parent)
+ (float float)
+ ((or (org-element-property :caption parent)
(org-string-nw-p (plist-get attr :caption)))
'figure)
(t 'nonfloat))))
@@ -2468,6 +2505,18 @@ used as a communication channel."
nil t))))
;; Return proper string, depending on FLOAT.
(pcase float
+ ((and (pred stringp) env-string)
+ (format "\\begin{%s}%s
+%s%s
+%s%s
+%s\\end{%s}"
+ env-string
+ placement
+ (if caption-above-p caption "")
+ (if center "\\centering" "")
+ comment-include image-code
+ (if caption-above-p "" caption)
+ env-string))
(`wrap (format "\\begin{wrapfigure}%s
%s%s
%s%s
@@ -2574,7 +2623,7 @@ INFO is a plist holding contextual information. See
(let ((label (org-latex--label destination info t)))
(if (and (not desc)
(org-export-numbered-headline-p destination info))
- (format "\\ref{%s}" label)
+ (format org-latex-reference-command label)
(format "\\hyperref[%s]{%s}" label
(or desc
(org-export-data
@@ -2582,7 +2631,7 @@ INFO is a plist holding contextual information. See
;; Fuzzy link points to a target. Do as above.
(otherwise
(let ((ref (org-latex--label destination info t)))
- (if (not desc) (format "\\ref{%s}" ref)
+ (if (not desc) (format org-latex-reference-command ref)
(format "\\hyperref[%s]{%s}" ref desc)))))))
;; Coderef: replace link with the reference name or the
;; equivalent line number.
@@ -2874,9 +2923,19 @@ channel."
"Transcode a QUOTE-BLOCK element from Org to LaTeX.
CONTENTS holds the contents of the block. INFO is a plist
holding contextual information."
- (org-latex--wrap-label
- quote-block (format "\\begin{quote}\n%s\\end{quote}" contents) info))
-
+ (let ((environment
+ (or (org-export-read-attribute :attr_latex quote-block :environment)
+ (plist-get info :latex-default-quote-environment)))
+ (options
+ (or (org-export-read-attribute :attr_latex quote-block :options)
+ "")))
+ (org-latex--wrap-label
+ quote-block (format "\\begin{%s}%s\n%s\\end{%s}"
+ environment
+ options
+ contents
+ environment)
+ info)))
;;;; Radio Target
@@ -2935,22 +2994,20 @@ contextual information."
(cond
;; Case 1. No source fontification.
((or (not lang) (not listings))
- (let* ((caption-str (org-latex--caption/label-string src-block info))
- (float-env
- (cond ((string= "multicolumn" float)
- (format "\\begin{figure*}[%s]\n%s%%s\n%s\\end{figure*}"
- (plist-get info :latex-default-figure-position)
- (if caption-above-p caption-str "")
- (if caption-above-p "" caption-str)))
- (caption (concat
- (if caption-above-p caption-str "")
- "%s"
- (if caption-above-p "" (concat "\n" caption-str))))
- (t "%s"))))
- (format
- float-env
- (concat (format "\\begin{verbatim}\n%s\\end{verbatim}"
- (org-export-format-code-default src-block info))))))
+ (let ((caption-str (org-latex--caption/label-string src-block info))
+ (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
+ (org-export-format-code-default src-block info))))
+ (cond ((string= "multicolumn" float)
+ (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
+ (plist-get info :latex-default-figure-position)
+ (if caption-above-p caption-str "")
+ verbatim
+ (if caption-above-p "" caption-str)))
+ (caption (concat
+ (if caption-above-p caption-str "")
+ verbatim
+ (if caption-above-p "" (concat "\n" caption-str))))
+ (t verbatim))))
;; Case 2. Custom environment.
(custom-env
(let ((caption-str (org-latex--caption/label-string src-block info))
@@ -3198,9 +3255,9 @@ centered."
(defun org-latex--decorate-table (table attributes caption above? info)
"Decorate TABLE string with caption and float environment.
-ATTRIBUTES is the plist containing is LaTeX attributes. CAPTION
-is its caption, as a string or nil. It is located above the
-table if ABOVE? is non-nil. INFO is the plist containing current
+ATTRIBUTES is the plist containing LaTeX attributes. CAPTION is
+its caption, as a string or nil. It is located above the table
+if ABOVE? is non-nil. INFO is the plist containing current
export parameters.
Return new environment, as a string."
@@ -3209,7 +3266,8 @@ Return new environment, as a string."
(cond ((and (not float) (plist-member attributes :float)) nil)
((member float '("sidewaystable" "sideways")) "sidewaystable")
((equal float "multicolumn") "table*")
- ((or float (org-string-nw-p caption)) "table")
+ (float float)
+ ((org-string-nw-p caption) "table")
(t nil))))
(placement
(or (plist-get attributes :placement)
@@ -3504,29 +3562,44 @@ channel."
"Transcode a VERSE-BLOCK element from Org to LaTeX.
CONTENTS is verse block contents. INFO is a plist holding
contextual information."
- (org-latex--wrap-label
- verse-block
- ;; In a verse environment, add a line break to each newline
- ;; character and change each white space at beginning of a line
- ;; into a space of 1 em. Also change each blank line with
- ;; a vertical space of 1 em.
- (format "\\begin{verse}\n%s\\end{verse}"
- (replace-regexp-in-string
- "^[ \t]+" (lambda (m) (format "\\hspace*{%dem}" (length m)))
- (replace-regexp-in-string
- "^[ \t]*\\\\\\\\$" "\\vspace*{1em}"
- (replace-regexp-in-string
- "\\([ \t]*\\\\\\\\\\)?[ \t]*\n" "\\\\\n"
- contents nil t) nil t) nil t))
- info))
-
+ (let* ((lin (org-export-read-attribute :attr_latex verse-block :lines))
+ (latcode (org-export-read-attribute :attr_latex verse-block :latexcode))
+ (cent (org-export-read-attribute :attr_latex verse-block :center))
+ (attr (concat
+ (if cent "[\\versewidth]" "")
+ (if lin (format "\n\\poemlines{%s}" lin) "")
+ (if latcode (format "\n%s" latcode) "")))
+ (versewidth (org-export-read-attribute :attr_latex verse-block :versewidth))
+ (vwidth (if versewidth (format "\\settowidth{\\versewidth}{%s}\n" versewidth) ""))
+ (linreset (if lin "\n\\poemlines{0}" "")))
+ (concat
+ (org-latex--wrap-label
+ verse-block
+ ;; In a verse environment, add a line break to each newline
+ ;; character and change each white space at beginning of a line
+ ;; into a space of 1 em. Also change each blank line with
+ ;; a vertical space of 1 em.
+ (format "%s\\begin{verse}%s\n%s\\end{verse}%s"
+ vwidth
+ attr
+ (replace-regexp-in-string
+ "^[ \t]+" (lambda (m) (format "\\hspace*{%dem}" (length m)))
+ (replace-regexp-in-string
+ "^[ \t]*\\\\\\\\$" "\\vspace*{1em}"
+ (replace-regexp-in-string
+ "\\([ \t]*\\\\\\\\\\)?[ \t]*\n" "\\\\\n"
+ contents nil t) nil t) nil t) linreset)
+ info)
+ ;; Insert footnote definitions, if any, after the environment, so
+ ;; the special formatting above is not applied to them.
+ (org-latex--delayed-footnotes-definitions verse-block info))))
;;; End-user functions
;;;###autoload
(defun org-latex-export-as-latex
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer as a LaTeX buffer.
If narrowing is active in the current buffer, only export its
@@ -3570,7 +3643,7 @@ command to convert it."
;;;###autoload
(defun org-latex-export-to-latex
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to a LaTeX file.
If narrowing is active in the current buffer, only export its
@@ -3602,7 +3675,7 @@ file-local settings."
;;;###autoload
(defun org-latex-export-to-pdf
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to LaTeX then process through to PDF.
If narrowing is active in the current buffer, only export its
@@ -3633,7 +3706,7 @@ Return PDF file's name."
(let ((outfile (org-export-output-file-name ".tex" subtreep)))
(org-export-to-file 'latex outfile
async subtreep visible-only body-only ext-plist
- (lambda (file) (org-latex-compile file)))))
+ #'org-latex-compile)))
(defun org-latex-compile (texfile &optional snippet)
"Compile a TeX file.
@@ -3660,12 +3733,12 @@ produced."
(match-string 0)))
"pdflatex"))
(process (if (functionp org-latex-pdf-process) org-latex-pdf-process
- ;; Replace "%latex" and "%bibtex" with,
- ;; respectively, "%L" and "%B" so as to adhere to
- ;; `format-spec' specifications.
+ ;; Replace "%latex" with "%L" and "%bib" and
+ ;; "%bibtex" with "%B" to adhere to `format-spec'
+ ;; specifications.
(mapcar (lambda (command)
(replace-regexp-in-string
- "%\\(?:bib\\|la\\)tex\\>"
+ "%\\(?:\\(?:bib\\|la\\)tex\\|bib\\)\\>"
(lambda (m) (upcase (substring m 0 2)))
command))
org-latex-pdf-process)))
diff --git a/lisp/org/ox-man.el b/lisp/org/ox-man.el
index 27d2dedb8ed..9a1f00f352b 100644
--- a/lisp/org/ox-man.el
+++ b/lisp/org/ox-man.el
@@ -186,7 +186,7 @@ When nil, no transformation is made."
(ldap "ldap") (opa "opa")
(php "php") (postscript "postscript") (prolog "prolog")
(properties "properties") (makefile "makefile")
- (tml "tml") (vala "vala") (vbscript "vbscript") (xorg "xorg"))
+ (tml "tml") (vbscript "vbscript") (xorg "xorg"))
"Alist mapping languages to their listing language counterpart.
The key is a symbol, the major mode symbol without the \"-mode\".
The value is the string that should be inserted as the language
@@ -301,12 +301,12 @@ CONTENTS is the transcoded contents string. INFO is a plist
holding export options."
(let* ((title (when (plist-get info :with-title)
(org-export-data (plist-get info :title) info)))
- (attr (read (format "(%s)"
- (mapconcat
- #'identity
- (list (plist-get info :man-class-options))
- " "))))
- (section-item (plist-get attr :section-id)))
+ (attr (read (format "(%s)"
+ (mapconcat
+ #'identity
+ (list (plist-get info :man-class-options))
+ " "))))
+ (section-item (plist-get attr :section-id)))
(concat
@@ -365,9 +365,9 @@ holding contextual information."
(defun org-man-drawer (_drawer contents _info)
"Transcode a DRAWER element from Org to Man.
- DRAWER holds the drawer information
- CONTENTS holds the contents of the block.
- INFO is a plist holding contextual information. "
+DRAWER holds the drawer information
+CONTENTS holds the contents of the block.
+INFO is a plist holding contextual information."
contents)
@@ -825,10 +825,10 @@ contextual information."
;; Case 1: verbatim table.
((or (plist-get info :man-tables-verbatim)
(let ((attr (read (format "(%s)"
- (mapconcat
- #'identity
- (org-element-property :attr_man table)
- " ")))))
+ (mapconcat
+ #'identity
+ (org-element-property :attr_man table)
+ " ")))))
(and attr (plist-get attr :verbatim))))
@@ -1053,7 +1053,7 @@ contextual information."
;;; Interactive functions
(defun org-man-export-to-man
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to a Man file.
If narrowing is active in the current buffer, only export its
@@ -1086,7 +1086,7 @@ Return output file's name."
async subtreep visible-only body-only ext-plist)))
(defun org-man-export-to-pdf
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to Groff then process through to PDF.
If narrowing is active in the current buffer, only export its
@@ -1117,7 +1117,7 @@ Return PDF file's name."
(let ((outfile (org-export-output-file-name ".man" subtreep)))
(org-export-to-file 'man outfile
async subtreep visible-only body-only ext-plist
- (lambda (file) (org-latex-compile file)))))
+ #'org-latex-compile)))
(defun org-man-compile (file)
"Compile a Groff file.
diff --git a/lisp/org/ox-md.el b/lisp/org/ox-md.el
index f4afe6b30ea..348b6d01dc9 100644
--- a/lisp/org/ox-md.el
+++ b/lisp/org/ox-md.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2012-2021 Free Software Foundation, Inc.
;; Author: Nicolas Goaziou <n.goaziou@gmail.com>
+;; Maintainer: Nicolas Goaziou <n.goaziou at gmail dot com>
;; Keywords: org, wp, markdown
;; This file is part of GNU Emacs.
@@ -57,10 +58,10 @@ This variable can be set to either `atx' or `setext'."
"Format string for the footnotes section.
The first %s placeholder will be replaced with the localized Footnotes section
heading, the second with the contents of the Footnotes section."
- :group 'org-export-md
- :type 'string
- :version "26.1"
- :package-version '(Org . "9.0"))
+ :group 'org-export-md
+ :type 'string
+ :version "26.1"
+ :package-version '(Org . "9.0"))
(defcustom org-md-footnote-format "<sup>%s</sup>"
"Format string for the footnote reference.
@@ -100,6 +101,8 @@ The %s will be replaced by the footnote reference itself."
(italic . org-md-italic)
(item . org-md-item)
(keyword . org-md-keyword)
+ (latex-environment . org-md-latex-environment)
+ (latex-fragment . org-md-latex-fragment)
(line-break . org-md-line-break)
(link . org-md-link)
(node-property . org-md-node-property)
@@ -210,9 +213,9 @@ the section."
(underline (concat (make-string (length title) underline-char)
"\n")))
(concat "\n" anchor-lines title tags "\n" underline "\n"))
- ;; Use "Atx" style
- (let ((level-mark (make-string level ?#)))
- (concat "\n" anchor-lines level-mark " " title tags "\n\n")))))
+ ;; Use "Atx" style
+ (let ((level-mark (make-string level ?#)))
+ (concat "\n" anchor-lines level-mark " " title tags "\n\n")))))
(defun org-md--build-toc (info &optional n _keyword scope)
"Return a table of contents.
@@ -460,6 +463,35 @@ channel."
(_ (org-export-with-backend 'html keyword contents info))))
+;;;; Latex Environment
+
+(defun org-md-latex-environment (latex-environment _contents info)
+ "Transcode a LATEX-ENVIRONMENT object from Org to Markdown.
+CONTENTS is nil. INFO is a plist holding contextual information."
+ (when (plist-get info :with-latex)
+ (let ((latex-frag (org-remove-indentation
+ (org-element-property :value latex-environment)))
+ (label (org-html--reference latex-environment info t)))
+ (if (org-string-nw-p label)
+ (replace-regexp-in-string "\\`.*"
+ (format "\\&\n\\\\label{%s}" label)
+ latex-frag)
+ latex-frag))))
+
+;;;; Latex Fragment
+
+(defun org-md-latex-fragment (latex-fragment _contents info)
+ "Transcode a LATEX-FRAGMENT object from Org to Markdown.
+CONTENTS is nil. INFO is a plist holding contextual information."
+ (when (plist-get info :with-latex)
+ (let ((frag (org-element-property :value latex-fragment)))
+ (cond
+ ((string-match-p "^\\\\(" frag)
+ (concat "$" (substring frag 2 -2) "$"))
+ ((string-match-p "^\\\\\\[" frag)
+ (concat "$$" (substring frag 2 -2) "$$"))
+ (t frag))))) ; either already $-deliminated or a macro
+
;;;; Line Break
(defun org-md-line-break (_line-break _contents _info)
@@ -543,7 +575,12 @@ INFO is a plist holding contextual information. See
((string= type "coderef")
(format (org-export-get-coderef-format path desc)
(org-export-resolve-coderef path info)))
- ((equal type "radio") desc)
+ ((string= type "radio")
+ (let ((destination (org-export-resolve-radio-link link info)))
+ (if (not destination) desc
+ (format "<a href=\"#%s\">%s</a>"
+ (org-export-get-reference destination info)
+ desc))))
(t (if (not desc) (format "<%s>" path)
(format "[%s](%s)" desc path))))))
diff --git a/lisp/org/ox-odt.el b/lisp/org/ox-odt.el
index a076d15978d..f186ebb16a7 100644
--- a/lisp/org/ox-odt.el
+++ b/lisp/org/ox-odt.el
@@ -251,7 +251,7 @@ Use `org-odt-add-automatic-style' to add update this variable.'")
(defvar org-odt-object-counters nil
"Running counters for various OBJECT-TYPEs.
-Use this to generate automatic names and style-names. See
+Use this to generate automatic names and style-names. See
`org-odt-add-automatic-style'.")
(defvar org-odt-src-block-paragraph-format
@@ -277,8 +277,7 @@ according to the default face identified by the `htmlfontify'.")
(defvar org-odt-default-image-sizes-alist
'(("as-char" . (5 . 0.4))
("paragraph" . (5 . 5)))
- "Hardcoded image dimensions one for each of the anchor
- methods.")
+ "Hardcoded image dimensions one for each of the anchor methods.")
;; A4 page size is 21.0 by 29.7 cms
;; The default page settings has 2cm margin on each of the sides. So
@@ -450,7 +449,7 @@ Valid values are one of:
4. list of the form (ODT-OR-OTT-FILE (FILE-MEMBER-1 FILE-MEMBER-2
...))
-In case of option 1, an in-built styles.xml is used. See
+In case of option 1, an in-built styles.xml is used. See
`org-odt-styles-dir' for more information.
In case of option 3, the specified file is unzipped and the
@@ -982,7 +981,7 @@ See `org-odt--build-date-styles' for implementation details."
;;;; Frame
(defun org-odt--frame (text width height style &optional extra
- anchor-type &rest title-and-desc)
+ anchor-type &rest title-and-desc)
(let ((frame-attrs
(concat
(if width (format " svg:width=\"%0.2fcm\"" width) "")
@@ -1044,7 +1043,7 @@ See `org-odt--build-date-styles' for implementation details."
;;;; Textbox
(defun org-odt--textbox (text width height style &optional
- extra anchor-type)
+ extra anchor-type)
(org-odt--frame
(format "\n<draw:text-box %s>%s\n</draw:text-box>"
(concat (format " fo:min-height=\"%0.2fcm\"" (or height .2))
@@ -1778,8 +1777,8 @@ INFO is a plist holding contextual information."
(if (functionp format-function) format-function
(cl-function
(lambda (todo todo-type priority text tags
- &key _level _section-number _headline-label
- &allow-other-keys)
+ &key _level _section-number _headline-label
+ &allow-other-keys)
(funcall (plist-get info :odt-format-headline-function)
todo todo-type priority text tags))))))
(apply format-function
@@ -1852,7 +1851,7 @@ holding contextual information."
contents))))))
(defun org-odt-format-headline-default-function
- (todo todo-type priority text tags)
+ (todo todo-type priority text tags)
"Default format function for a headline.
See `org-odt-format-headline-function' for details."
(concat
@@ -1930,7 +1929,7 @@ holding contextual information."
todo todo-type priority text tags contents)))
(defun org-odt-format-inlinetask-default-function
- (todo todo-type priority name tags contents)
+ (todo todo-type priority name tags contents)
"Default format function for inlinetasks.
See `org-odt-format-inlinetask-function' for details."
(format "\n<text:p text:style-name=\"%s\">%s</text:p>"
@@ -2176,7 +2175,7 @@ SHORT-CAPTION are strings."
;;;; Links :: Inline Images
(defun org-odt--copy-image-file (path)
- "Return the internal name of the file"
+ "Return the internal name of the file."
(let* ((image-type (file-name-extension path))
(media-type (format "image/%s" image-type))
(target-dir "Images/")
@@ -2199,7 +2198,7 @@ SHORT-CAPTION are strings."
(declare-function image-size "image.c" (spec &optional pixels frame))
(defun org-odt--image-size
- (file info &optional user-width user-height scale dpi embed-as)
+ (file info &optional user-width user-height scale dpi embed-as)
(let* ((--pixels-to-cms
(lambda (pixels dpi)
(let ((cms-per-inch 2.54)
@@ -2380,7 +2379,7 @@ used as a communication channel."
(concat equation "<text:tab/>" label))))))
(defun org-odt--copy-formula-file (src-file)
- "Return the internal name of the file"
+ "Return the internal name of the file."
(let* ((target-dir (format "Formula-%04d/"
(cl-incf org-odt-embedded-formulas-count)))
(target-file (concat target-dir "content.xml")))
@@ -2400,7 +2399,7 @@ used as a communication channel."
;; Case 2: OpenDocument formula.
((string= ext "odf")
(org-odt--zip-extract src-file "content.xml"
- (concat org-odt-zip-dir target-dir)))
+ (concat org-odt-zip-dir target-dir)))
(t (error "%s is not a formula file" src-file))))
;; Enter the formula file in to manifest.
(org-odt-create-manifest-file-entry "text/xml" target-file)
@@ -2468,15 +2467,14 @@ used as a communication channel."
(outer (nth 2 frame-cfg))
;; User-specified frame params (from #+ATTR_ODT spec)
(user user-frame-params)
- (--merge-frame-params (function
- (lambda (default user)
- "Merge default and user frame params."
- (if (not user) default
- (cl-assert (= (length default) 3))
- (cl-assert (= (length user) 3))
- (cl-loop for u in user
- for d in default
- collect (or u d)))))))
+ (--merge-frame-params (lambda (default user)
+ "Merge default and user frame params."
+ (if (not user) default
+ (cl-assert (= (length default) 3))
+ (cl-assert (= (length user) 3))
+ (cl-loop for u in user
+ for d in default
+ collect (or u d))))))
(cond
;; Case 1: Image/Formula has no caption.
;; There is only one frame, one that surrounds the image
@@ -2652,7 +2650,7 @@ Return nil, otherwise."
(format "<text:bookmark-ref text:reference-format=\"number-all-superior\" text:ref-name=\"%s\">%s</text:bookmark-ref>"
label
(mapconcat (lambda (n) (if (not n) " "
- (concat (number-to-string n) ".")))
+ (concat (number-to-string n) ".")))
item-numbers "")))))
;; Case 2: Locate a regular and numbered headline in the
;; hierarchy. Display its section number.
@@ -3032,7 +3030,7 @@ holding contextual information."
(anchor (plist-get attributes :anchor)))
(format "\n<text:p text:style-name=\"%s\">%s</text:p>"
"Text_20_body" (org-odt--textbox contents width height
- style extra anchor))))
+ style extra anchor))))
(t contents))))
@@ -3773,13 +3771,13 @@ contextual information."
;; paragraph.
(latex-environment
(org-element-adopt-elements
- (list 'paragraph
- (list :style "OrgFormula"
- :name
- (org-element-property :name latex-*)
- :caption
- (org-element-property :caption latex-*)))
- link))
+ (list 'paragraph
+ (list :style "OrgFormula"
+ :name
+ (org-element-property :name latex-*)
+ :caption
+ (org-element-property :caption latex-*)))
+ link))
;; LaTeX fragment. No special action.
(latex-fragment link))))
;; Note down the object that link replaces.
@@ -3842,15 +3840,15 @@ contextual information."
(mapcar
(lambda (item)
(org-element-adopt-elements
- (list 'item (list :checkbox (org-element-property
- :checkbox item)))
- (list 'paragraph (list :style "Text_20_body_20_bold")
- (or (org-element-property :tag item) "(no term)"))
- (org-element-adopt-elements
- (list 'plain-list (list :type 'descriptive-2))
- (apply 'org-element-adopt-elements
- (list 'item nil)
- (org-element-contents item)))))
+ (list 'item (list :checkbox (org-element-property
+ :checkbox item)))
+ (list 'paragraph (list :style "Text_20_body_20_bold")
+ (or (org-element-property :tag item) "(no term)"))
+ (org-element-adopt-elements
+ (list 'plain-list (list :type 'descriptive-2))
+ (apply 'org-element-adopt-elements
+ (list 'item nil)
+ (org-element-contents item)))))
(org-element-contents el)))))
nil)
info)
diff --git a/lisp/org/ox-org.el b/lisp/org/ox-org.el
index 26259d8752c..fcf876854fd 100644
--- a/lisp/org/ox-org.el
+++ b/lisp/org/ox-org.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2013-2021 Free Software Foundation, Inc.
;; Author: Nicolas Goaziou <n.goaziou@gmail.com>
+;; Maintainer: Nicolas Goaziou <n.goaziou at gmail dot com>
;; Keywords: org, wp
;; This file is part of GNU Emacs.
@@ -140,7 +141,7 @@ CONTENTS and INFO are ignored."
CONTENTS is its contents, as a string or nil. INFO is ignored."
(let ((case-fold-search t))
(replace-regexp-in-string
- "^[ \t]*#\\+ATTR_[-_A-Za-z0-9]+:\\(?: .*\\)?\n" ""
+ "^[ \t]*#\\+attr_[-_a-z0-9]+:\\(?: .*\\)?\n" ""
(org-export-expand blob contents t))))
(defun org-org-headline (headline contents info)
@@ -184,26 +185,26 @@ as a communication channel."
(org-element-map (plist-get info :parse-tree) 'keyword
(lambda (k)
(and (string-equal (org-element-property :key k) "OPTIONS")
- (concat "#+OPTIONS: "
+ (concat "#+options: "
(org-element-property :value k)))))
"\n"))
(and (plist-get info :with-title)
- (format "#+TITLE: %s\n" (org-export-data (plist-get info :title) info)))
+ (format "#+title: %s\n" (org-export-data (plist-get info :title) info)))
(and (plist-get info :with-date)
(let ((date (org-export-data (org-export-get-date info) info)))
(and (org-string-nw-p date)
- (format "#+DATE: %s\n" date))))
+ (format "#+date: %s\n" date))))
(and (plist-get info :with-author)
(let ((author (org-export-data (plist-get info :author) info)))
(and (org-string-nw-p author)
- (format "#+AUTHOR: %s\n" author))))
+ (format "#+author: %s\n" author))))
(and (plist-get info :with-email)
(let ((email (org-export-data (plist-get info :email) info)))
(and (org-string-nw-p email)
- (format "#+EMAIL: %s\n" email))))
+ (format "#+email: %s\n" email))))
(and (plist-get info :with-creator)
(org-string-nw-p (plist-get info :creator))
- (format "#+CREATOR: %s\n" (plist-get info :creator)))
+ (format "#+creator: %s\n" (plist-get info :creator)))
contents))
(defun org-org-timestamp (timestamp _contents _info)
@@ -238,7 +239,7 @@ a communication channel."
;;;###autoload
(defun org-org-export-as-org
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to an Org buffer.
If narrowing is active in the current buffer, only export its
@@ -273,7 +274,7 @@ non-nil."
;;;###autoload
(defun org-org-export-to-org
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to an Org file.
If narrowing is active in the current buffer, only export its
diff --git a/lisp/org/ox-publish.el b/lisp/org/ox-publish.el
index 6f82b485724..bc9b17ab3ef 100644
--- a/lisp/org/ox-publish.el
+++ b/lisp/org/ox-publish.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2006-2021 Free Software Foundation, Inc.
;; Author: David O'Toole <dto@gnu.org>
-;; Maintainer: Carsten Dominik <carsten at orgmode dot org>
+;; Maintainer: Nicolas Goaziou <n.goaziou at gmail dot com>
;; Keywords: hypermedia, outlines, wp
;; This file is part of GNU Emacs.
@@ -358,7 +358,7 @@ You can overwrite this default per project in your
(concat "X" (if (fboundp 'sha1) (sha1 filename) (md5 filename))))
(defun org-publish-needed-p
- (filename &optional pub-dir pub-func _true-pub-dir base-dir)
+ (filename &optional pub-dir pub-func _true-pub-dir base-dir)
"Non-nil if FILENAME should be published in PUB-DIR using PUB-FUNC.
TRUE-PUB-DIR is where the file will truly end up. Currently we
are not using this - maybe it can eventually be used to check if
@@ -375,7 +375,7 @@ still decide about that independently."
rtn))
(defun org-publish-update-timestamp
- (filename &optional pub-dir pub-func _base-dir)
+ (filename &optional pub-dir pub-func _base-dir)
"Update publishing timestamp for file FILENAME.
If there is no timestamp, create one."
(let ((key (org-publish-timestamp-filename filename pub-dir pub-func))
@@ -617,7 +617,8 @@ files, when entire projects are published (see
(abbreviate-file-name filename))))
(project-plist (cdr project))
(publishing-function
- (pcase (org-publish-property :publishing-function project)
+ (pcase (org-publish-property :publishing-function project
+ 'org-html-publish-to-html)
(`nil (user-error "No publishing function chosen"))
((and f (pred listp)) f)
(f (list f))))
@@ -1064,7 +1065,7 @@ publishing directory."
(setq full-index
(sort (nreverse full-index)
(lambda (a b) (string< (downcase (car a))
- (downcase (car b)))))))
+ (downcase (car b)))))))
(let ((index (org-publish-cache-get-file-property file :index)))
(dolist (term index)
(unless (member term full-index) (push term full-index)))))
@@ -1270,7 +1271,7 @@ If FREE-CACHE, empty the cache."
org-publish-cache)
(defun org-publish-reset-cache ()
- "Empty org-publish-cache and reset it nil."
+ "Empty `org-publish-cache' and reset it nil."
(message "%s" "Resetting org-publish-cache")
(when (hash-table-p org-publish-cache)
(clrhash org-publish-cache))
@@ -1290,29 +1291,28 @@ the file including them will be republished as well."
(org-inhibit-startup t)
included-files-ctime)
(when (equal (file-name-extension filename) "org")
- (let ((visiting (find-buffer-visiting filename))
- (buf (find-file-noselect filename))
- (case-fold-search t))
- (unwind-protect
- (with-current-buffer buf
- (goto-char (point-min))
- (while (re-search-forward "^[ \t]*#\\+INCLUDE:" nil t)
- (let ((element (org-element-at-point)))
- (when (eq 'keyword (org-element-type element))
- (let* ((value (org-element-property :value element))
- (filename
- (and (string-match "\\`\\(\".+?\"\\|\\S-+\\)" value)
- (let ((m (org-strip-quotes
- (match-string 1 value))))
- ;; Ignore search suffix.
- (if (string-match "::.*?\\'" m)
- (substring m 0 (match-beginning 0))
- m)))))
- (when filename
- (push (org-publish-cache-ctime-of-src
- (expand-file-name filename))
- included-files-ctime)))))))
- (unless visiting (kill-buffer buf)))))
+ (let ((case-fold-search t))
+ (with-temp-buffer
+ (delay-mode-hooks
+ (org-mode)
+ (insert-file-contents filename)
+ (goto-char (point-min))
+ (while (re-search-forward "^[ \t]*#\\+INCLUDE:" nil t)
+ (let ((element (org-element-at-point)))
+ (when (eq 'keyword (org-element-type element))
+ (let* ((value (org-element-property :value element))
+ (include-filename
+ (and (string-match "\\`\\(\".+?\"\\|\\S-+\\)" value)
+ (let ((m (org-strip-quotes
+ (match-string 1 value))))
+ ;; Ignore search suffix.
+ (if (string-match "::.*?\\'" m)
+ (substring m 0 (match-beginning 0))
+ m)))))
+ (when include-filename
+ (push (org-publish-cache-ctime-of-src
+ (expand-file-name include-filename (file-name-directory filename)))
+ included-files-ctime))))))))))
(or (null pstamp)
(let ((ctime (org-publish-cache-ctime-of-src filename)))
(or (time-less-p pstamp ctime)
@@ -1320,7 +1320,7 @@ the file including them will be republished as well."
included-files-ctime))))))
(defun org-publish-cache-set-file-property
- (filename property value &optional project-name)
+ (filename property value &optional project-name)
"Set the VALUE for a PROPERTY of file FILENAME in publishing cache to VALUE.
Use cache file of PROJECT-NAME. If the entry does not exist, it
will be created. Return VALUE."
diff --git a/lisp/org/ox-texinfo.el b/lisp/org/ox-texinfo.el
index 6e8d0d62141..46077ece4b8 100644
--- a/lisp/org/ox-texinfo.el
+++ b/lisp/org/ox-texinfo.el
@@ -2,6 +2,7 @@
;; Copyright (C) 2012-2021 Free Software Foundation, Inc.
;; Author: Jonathan Leech-Pepin <jonathan.leechpepin at gmail dot com>
+;; Maintainer: Nicolas Goaziou <n.goaziou at gmail dot com>
;; Keywords: outlines, hypermedia, calendar, wp
;; This file is part of GNU Emacs.
@@ -420,8 +421,8 @@ If two strings share the same prefix (e.g. \"ISO-8859-1\" and
(defun org-texinfo--normalize-headlines (tree _backend info)
"Normalize headlines in TREE.
-BACK-END is the symbol specifying back-end used for export. INFO
-is a plist used as a communication channel.
+BACK-END is the symbol specifying back-end used for export.
+INFO is a plist used as a communication channel.
Make sure every headline in TREE contains a section, since those
are required to install a menu. Also put exactly one blank line
@@ -489,16 +490,18 @@ node or anchor name is unique."
;; Org exports deeper elements before their parents. If two
;; node names collide -- e.g., they have the same title --
;; within the same hierarchy, the second one would get the
- ;; shorter node name. This is counter-intuitive.
- ;; Consequently, we ensure that every parent headline get
- ;; its node beforehand. As a recursive operation, this
+ ;; smaller node name. This is counter-intuitive.
+ ;; Consequently, we ensure that every parent headline gets
+ ;; its node beforehand. As a recursive operation, this
;; achieves the desired effect.
(let ((parent (org-element-lineage datum '(headline))))
(when (and parent (not (assq parent cache)))
(org-texinfo--get-node parent info)
(setq cache (plist-get info :texinfo-node-cache))))
- ;; Ensure NAME is unique and not reserved node name "Top".
- (while (or (equal name "Top") (rassoc name cache))
+ ;; Ensure NAME is unique and not reserved node name "Top",
+ ;; no matter what case is used.
+ (while (or (string-equal "Top" (capitalize name))
+ (rassoc name cache))
(setq name (concat basename (format " (%d)" (cl-incf salt)))))
(plist-put info :texinfo-node-cache (cons (cons datum name) cache))
name))))
@@ -559,6 +562,14 @@ strings (e.g., returned by `org-export-get-caption')."
(format "@float %s%s\n%s\n%s%s@end float"
type (if label (concat "," label) "") value caption-str short-str)))
+(defun org-texinfo--sectioning-structure (info)
+ "Return sectioning structure used in the document.
+INFO is a plist holding export options."
+ (let ((class (plist-get info :texinfo-class)))
+ (pcase (assoc class (plist-get info :texinfo-classes))
+ (`(,_ ,_ . ,sections) sections)
+ (_ (user-error "Unknown Texinfo class: %S" class)))))
+
;;; Template
(defun org-texinfo-template (contents info)
@@ -838,9 +849,17 @@ CONTENTS is nil. INFO is a plist holding contextual information."
FOOTNOTE is the footnote to define. CONTENTS is nil. INFO is a
plist holding contextual information."
- (let ((def (org-export-get-footnote-definition footnote info)))
+ (let* ((contents (org-export-get-footnote-definition footnote info))
+ (data (org-export-data contents info)))
(format "@footnote{%s}"
- (org-trim (org-export-data def info)))))
+ ;; It is invalid to close a footnote on a line starting
+ ;; with "@end". As a safety net, we leave a newline
+ ;; character before the closing brace. However, when the
+ ;; footnote ends with a paragraph, it is visually pleasing
+ ;; to move the brace right after its end.
+ (if (eq 'paragraph (org-element-type (org-last contents)))
+ (org-trim data)
+ data))))
;;;; Headline
@@ -858,25 +877,22 @@ holding contextual information."
(notoc? (org-export-excluded-from-toc-p headline info))
(command
(and
- (not (org-export-low-level-p headline info))
- (let ((class (plist-get info :texinfo-class)))
- (pcase (assoc class (plist-get info :texinfo-classes))
- (`(,_ ,_ . ,sections)
- (pcase (nth (1- (org-export-get-relative-level headline info))
- sections)
- (`(,numbered ,unnumbered ,unnumbered-no-toc ,appendix)
- (cond
- ((org-not-nil
- (org-export-get-node-property :APPENDIX headline t))
- appendix)
- (numbered? numbered)
- (index unnumbered)
- (notoc? unnumbered-no-toc)
- (t unnumbered)))
- (`nil nil)
- (_ (user-error "Invalid Texinfo class specification: %S"
- class))))
- (_ (user-error "Unknown Texinfo class: %S" class))))))
+ (not (org-export-low-level-p headline info))
+ (let ((sections (org-texinfo--sectioning-structure info)))
+ (pcase (nth (1- (org-export-get-relative-level headline info))
+ sections)
+ (`(,numbered ,unnumbered ,unnumbered-no-toc ,appendix)
+ (cond
+ ((org-not-nil
+ (org-export-get-node-property :APPENDIX headline t))
+ appendix)
+ (numbered? numbered)
+ (index unnumbered)
+ (notoc? unnumbered-no-toc)
+ (t unnumbered)))
+ (`nil nil)
+ (_ (user-error "Invalid Texinfo class specification: %S"
+ (plist-get info :texinfo-class)))))))
(todo
(and (plist-get info :with-todo-keywords)
(let ((todo (org-element-property :todo-keyword headline)))
@@ -894,11 +910,12 @@ holding contextual information."
(contents
(concat "\n"
(if (org-string-nw-p contents) (concat "\n" contents) "")
- (and index (format "\n@printindex %s\n" index)))))
+ (and index (format "\n@printindex %s\n" index))))
+ (node (org-texinfo--get-node headline info)))
(if (not command)
(concat (and (org-export-first-sibling-p headline info)
(format "@%s\n" (if numbered? 'enumerate 'itemize)))
- "@item\n" full-text "\n"
+ (format "@item\n@anchor{%s}%s\n" node full-text)
contents
(if (org-export-last-sibling-p headline info)
(format "@end %s" (if numbered? 'enumerate 'itemize))
@@ -906,13 +923,12 @@ holding contextual information."
(concat
;; Even if HEADLINE is using @subheading and al., leave an
;; anchor so cross-references in the Org document still work.
- (format (if notoc? "@anchor{%s}\n" "@node %s\n")
- (org-texinfo--get-node headline info))
+ (format (if notoc? "@anchor{%s}\n" "@node %s\n") node)
(format command full-text)
contents))))))
(defun org-texinfo-format-headline-default-function
- (todo _todo-type priority text tags)
+ (todo _todo-type priority text tags)
"Default format function for a headline.
See `org-texinfo-format-headline-function' for details."
(concat (and todo (format "@strong{%s} " todo))
@@ -949,7 +965,7 @@ holding contextual information."
todo todo-type priority title tags contents)))
(defun org-texinfo-format-inlinetask-default-function
- (todo _todo-type priority title tags contents)
+ (todo _todo-type priority title tags contents)
"Default format function for inlinetasks.
See `org-texinfo-format-inlinetask-function' for details."
(let ((full-title
@@ -1111,7 +1127,9 @@ current state of the export, as a plist."
(path (org-element-property :path link))
(filename
(file-name-sans-extension
- (if (file-name-absolute-p path) (expand-file-name path) path)))
+ (if (file-name-absolute-p path)
+ (expand-file-name path)
+ (file-relative-name path))))
(extension (file-name-extension path))
(attributes (org-export-read-attribute :attr_texinfo parent))
(height (or (plist-get attributes :height) ""))
@@ -1192,7 +1210,7 @@ a plist containing contextual information."
;; Colons are used as a separator between title and node
;; name. Remove them.
(replace-regexp-in-string
- "[ \t]+:+" ""
+ "[ \t]*:+" ""
(org-texinfo--sanitize-title
(org-export-get-alt-title h info) info)))
(node (org-texinfo--get-node h info))
@@ -1215,12 +1233,15 @@ holding contextual information."
:texinfo-entries-cache)))
(cached-entries (gethash scope cache 'no-cache)))
(if (not (eq cached-entries 'no-cache)) cached-entries
- (puthash scope
- (cl-remove-if
- (lambda (h)
- (org-not-nil (org-export-get-node-property :COPYING h t)))
- (org-export-collect-headlines info 1 scope))
- cache))))
+ (let* ((sections (org-texinfo--sectioning-structure info))
+ (max-depth (length sections)))
+ (puthash scope
+ (cl-remove-if
+ (lambda (h)
+ (or (org-not-nil (org-export-get-node-property :COPYING h t))
+ (< max-depth (org-export-get-relative-level h info))))
+ (org-export-collect-headlines info 1 scope))
+ cache)))))
;;;; Node Property
@@ -1585,7 +1606,7 @@ channel."
(defun org-texinfo-verse-block (_verse-block contents _info)
"Transcode a VERSE-BLOCK element from Org to Texinfo.
-CONTENTS is verse block contents. INFO is a plist holding
+CONTENTS is verse block contents. INFO is a plist holding
contextual information."
(format "@display\n%s@end display" contents))
@@ -1594,7 +1615,7 @@ contextual information."
;;;###autoload
(defun org-texinfo-export-to-texinfo
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to a Texinfo file.
If narrowing is active in the current buffer, only export its
@@ -1645,7 +1666,7 @@ Usage: emacs -batch -f org-texinfo-export-to-texinfo-batch INFILE OUTFILE"
;;;###autoload
(defun org-texinfo-export-to-info
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to Texinfo then process through to INFO.
If narrowing is active in the current buffer, only export its
@@ -1680,7 +1701,7 @@ Return INFO file's name."
(org-export-coding-system org-texinfo-coding-system))
(org-export-to-file 'texinfo outfile
async subtreep visible-only body-only ext-plist
- (lambda (file) (org-texinfo-compile file)))))
+ #'org-texinfo-compile)))
;;;###autoload
(defun org-texinfo-publish-to-texinfo (plist filename pub-dir)
diff --git a/lisp/org/ox.el b/lisp/org/ox.el
index 36ecf014830..80202b08500 100644
--- a/lisp/org/ox.el
+++ b/lisp/org/ox.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2012-2021 Free Software Foundation, Inc.
;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
+;; Maintainer: Nicolas Goaziou <n.goaziou at gmail dot com>
;; Keywords: outlines, hypermedia, calendar, wp
;; This file is part of GNU Emacs.
@@ -73,6 +74,8 @@
(require 'cl-lib)
(require 'ob-exp)
+(require 'oc)
+(require 'oc-basic) ;default value for `org-cite-export-processors'
(require 'ol)
(require 'org-element)
(require 'org-macro)
@@ -139,7 +142,9 @@
(:with-tasks nil "tasks" org-export-with-tasks)
(:with-timestamps nil "<" org-export-with-timestamps)
(:with-title nil "title" org-export-with-title)
- (:with-todo-keywords nil "todo" org-export-with-todo-keywords))
+ (:with-todo-keywords nil "todo" org-export-with-todo-keywords)
+ ;; Citations processing.
+ (:cite-export "CITE_EXPORT" nil org-cite-export-processors))
"Alist between export properties and ways to set them.
The key of the alist is the property name, and the value is a list
@@ -294,7 +299,7 @@ and its CDR is a list of export options.")
(defvar org-export-dispatch-last-position (make-marker)
"The position where the last export command was created using the dispatcher.
-This marker will be used with `C-u C-c C-e' to make sure export repetition
+This marker will be used with `\\[universal-argument] C-c C-e' to make sure export repetition
uses the same subtree if the previous command was restricted to a subtree.")
;; For compatibility with Org < 8
@@ -1043,6 +1048,7 @@ BACKEND is a structure with `org-export-backend' type."
(unless (org-export-backend-p backend)
(error "Unknown \"%s\" back-end: Aborting export" backend)))
+;;;###autoload
(defun org-export-derived-backend-p (backend &rest backends)
"Non-nil if BACKEND is derived from one of BACKENDS.
BACKEND is an export back-end, as returned by, e.g.,
@@ -1207,12 +1213,12 @@ keywords are understood:
or
\\='(?l \"Export to LaTeX\"
- (?p \"As PDF file\" org-latex-export-to-pdf)
- (?o \"As PDF file and open\"
- (lambda (a s v b)
- (if a (org-latex-export-to-pdf t s v b)
- (org-open-file
- (org-latex-export-to-pdf nil s v b)))))))
+ ((?p \"As PDF file\" org-latex-export-to-pdf)
+ (?o \"As PDF file and open\"
+ (lambda (a s v b)
+ (if a (org-latex-export-to-pdf t s v b)
+ (org-open-file
+ (org-latex-export-to-pdf nil s v b)))))))
or the following, which will be added to the previous
sub-menu,
@@ -1386,11 +1392,13 @@ e.g., `org-export-create-backend'. It specifies which back-end
specific items to read, if any."
(let ((line
(let ((s 0) alist)
- (while (string-match "\\(.+?\\):\\((.*?)\\|\\S-*\\)[ \t]*" options s)
+ (while (string-match "\\(.+?\\):\\((.*?)\\|\\S-+\\)?[ \t]*" options s)
(setq s (match-end 0))
- (push (cons (match-string 1 options)
- (read (match-string 2 options)))
- alist))
+ (let ((value (match-string 2 options)))
+ (when value
+ (push (cons (match-string 1 options)
+ (read value))
+ alist))))
alist))
;; Priority is given to back-end specific options.
(all (append (org-export-get-all-options backend)
@@ -1569,7 +1577,7 @@ process."
plist
prop
;; Evaluate default value provided.
- (let ((value (eval (nth 3 cell))))
+ (let ((value (eval (nth 3 cell) t)))
(if (eq (nth 4 cell) 'parse)
(org-element-parse-secondary-string
value (org-element-restriction 'keyword))
@@ -1851,6 +1859,7 @@ INFO is a plist containing export directives."
(let ((transcoder (cdr (assq type (plist-get info :translate-alist)))))
(and (functionp transcoder) transcoder)))))
+;;;###autoload
(defun org-export-data (data info)
"Convert DATA into current back-end format.
@@ -1878,6 +1887,8 @@ Return a string."
(cond
;; Ignored element/object.
((memq data (plist-get info :ignore-list)) nil)
+ ;; Raw code.
+ ((eq type 'raw) (car (org-element-contents data)))
;; Plain text.
((eq type 'plain-text)
(org-export-filter-apply-functions
@@ -1944,7 +1955,7 @@ Return a string."
data
(cond
((not results) "")
- ((memq type '(org-data plain-text nil)) results)
+ ((memq type '(nil org-data plain-text raw)) results)
;; Append the same white space between elements or objects
;; as in the original buffer, and call appropriate filters.
(t
@@ -2559,16 +2570,16 @@ another buffer, effectively cloning the original buffer there.
The function assumes BUFFER's major mode is `org-mode'."
(with-current-buffer buffer
- `(lambda ()
- (let ((inhibit-modification-hooks t))
- ;; Set major mode. Ignore `org-mode-hook' as it has been run
- ;; already in BUFFER.
- (let ((org-mode-hook nil) (org-inhibit-startup t)) (org-mode))
- ;; Copy specific buffer local variables and variables set
- ;; through BIND keywords.
- ,@(let ((bound-variables (org-export--list-bound-variables))
- vars)
- (dolist (entry (buffer-local-variables (buffer-base-buffer)) vars)
+ (let ((str (org-with-wide-buffer (buffer-string)))
+ (narrowing
+ (if (org-region-active-p)
+ (list (region-beginning) (region-end))
+ (list (point-min) (point-max))))
+ (pos (point))
+ (varvals
+ (let ((bound-variables (org-export--list-bound-variables))
+ (varvals nil))
+ (dolist (entry (buffer-local-variables (buffer-base-buffer)))
(when (consp entry)
(let ((var (car entry))
(val (cdr entry)))
@@ -2583,27 +2594,35 @@ The function assumes BUFFER's major mode is `org-mode'."
;; Skip unreadable values, as they cannot be
;; sent to external process.
(or (not val) (ignore-errors (read (format "%S" val))))
- (push `(set (make-local-variable (quote ,var))
- (quote ,val))
- vars))))))
- ;; Whole buffer contents.
- (insert ,(org-with-wide-buffer (buffer-string)))
- ;; Narrowing.
- ,(if (org-region-active-p)
- `(narrow-to-region ,(region-beginning) ,(region-end))
- `(narrow-to-region ,(point-min) ,(point-max)))
- ;; Current position of point.
- (goto-char ,(point))
- ;; Overlays with invisible property.
- ,@(let (ov-set)
- (dolist (ov (overlays-in (point-min) (point-max)) ov-set)
+ (push (cons var val) varvals)))))
+ varvals))
+ (ols
+ (let (ov-set)
+ (dolist (ov (overlays-in (point-min) (point-max)))
(let ((invis-prop (overlay-get ov 'invisible)))
(when invis-prop
- (push `(overlay-put
- (make-overlay ,(overlay-start ov)
- ,(overlay-end ov))
- 'invisible (quote ,invis-prop))
- ov-set)))))))))
+ (push (list (overlay-start ov) (overlay-end ov)
+ invis-prop)
+ ov-set))))
+ ov-set)))
+ (lambda ()
+ (let ((inhibit-modification-hooks t))
+ ;; Set major mode. Ignore `org-mode-hook' as it has been run
+ ;; already in BUFFER.
+ (let ((org-mode-hook nil) (org-inhibit-startup t)) (org-mode))
+ ;; Copy specific buffer local variables and variables set
+ ;; through BIND keywords.
+ (pcase-dolist (`(,var . ,val) varvals)
+ (set (make-local-variable var) val))
+ ;; Whole buffer contents.
+ (insert str)
+ ;; Narrowing.
+ (apply #'narrow-to-region narrowing)
+ ;; Current position of point.
+ (goto-char pos)
+ ;; Overlays with invisible property.
+ (pcase-dolist (`(,start ,end ,invis) ols)
+ (overlay-put (make-overlay start end) 'invisible invis)))))))
(defun org-export--delete-comment-trees ()
"Delete commented trees and commented inlinetasks in the buffer.
@@ -2709,8 +2728,8 @@ a list of footnote definitions or in the widened buffer."
) ;; seen
(dolist (l (funcall list-labels tree))
(cond ;; ((member l seen))
- ((member l known-definitions) (push l defined))
- (t (push l undefined)))))
+ ((member l known-definitions) (push l defined))
+ (t (push l undefined)))))
;; Complete MISSING-DEFINITIONS by finding the definition of every
;; undefined label, first by looking into DEFINITIONS, then by
;; searching the widened buffer. This is a recursive process
@@ -2722,7 +2741,7 @@ a list of footnote definitions or in the widened buffer."
(cond
((cl-some
(lambda (d) (and (equal (org-element-property :label d) label)
- d))
+ d))
definitions))
((pcase (org-footnote-get-definition label)
(`(,_ ,beg . ,_)
@@ -2785,16 +2804,16 @@ containing their first reference."
;; the definitions at the end of the tree.
(org-footnote-section
(org-element-adopt-elements
- tree
- (org-element-create 'headline
- (list :footnote-section-p t
- :level 1
- :title org-footnote-section
- :raw-value org-footnote-section)
- (apply #'org-element-create
- 'section
- nil
- (nreverse definitions)))))
+ tree
+ (org-element-create 'headline
+ (list :footnote-section-p t
+ :level 1
+ :title org-footnote-section
+ :raw-value org-footnote-section)
+ (apply #'org-element-create
+ 'section
+ nil
+ (nreverse definitions)))))
;; Otherwise add each definition at the end of the section where it
;; is first referenced.
(t
@@ -2817,8 +2836,8 @@ containing their first reference."
d))
definitions)))
(org-element-adopt-elements
- (org-element-lineage reference '(section))
- definition)
+ (org-element-lineage reference '(section))
+ definition)
;; Also insert definitions for nested
;; references, if any.
(funcall insert-definitions definition))))))))))
@@ -2947,10 +2966,8 @@ Return code as a string."
(org-export-backend-name backend))
(org-export-expand-include-keyword)
(org-export--delete-comment-trees)
- (org-macro-initialize-templates)
- (org-macro-replace-all (append org-macro-templates
- org-export-global-macros)
- parsed-keywords)
+ (org-macro-initialize-templates org-export-global-macros)
+ (org-macro-replace-all org-macro-templates parsed-keywords)
;; Refresh buffer properties and radio targets after previous
;; potentially invasive changes.
(org-set-regexps-and-options)
@@ -2977,6 +2994,10 @@ Return code as a string."
(setq info
(org-combine-plists
info (org-export-get-environment backend subtreep ext-plist)))
+ ;; Pre-process citations environment, i.e. install
+ ;; bibliography list, and citation processor in INFO.
+ (org-cite-store-bibliography info)
+ (org-cite-store-export-processor info)
;; De-activate uninterpreted data from parsed keywords.
(dolist (entry (append (org-export-get-all-options backend)
org-export-options-alist))
@@ -3010,6 +3031,11 @@ Return code as a string."
;; Now tree is complete, compute its properties and add them
;; to communication channel.
(setq info (org-export--collect-tree-properties tree info))
+ ;; Process citations and bibliography. Replace each citation
+ ;; and "print_bibliography" keyword in the parse tree with
+ ;; the output of the selected citation export processor.
+ (org-cite-process-citations info)
+ (org-cite-process-bibliography info)
;; Eventually transcode TREE. Wrap the resulting string into
;; a template.
(let* ((body (org-element-normalize-string
@@ -3022,16 +3048,19 @@ Return code as a string."
(funcall inner-template body info))
info))
(template (cdr (assq 'template
- (plist-get info :translate-alist)))))
+ (plist-get info :translate-alist))))
+ (output
+ (if (or (not (functionp template)) body-only) full-body
+ (funcall template full-body info))))
+ ;; Call citation export finalizer.
+ (setq output (org-cite-finalize-export output info))
;; Remove all text properties since they cannot be
;; retrieved from an external process. Finally call
;; final-output filter and return result.
(org-no-properties
(org-export-filter-apply-functions
(plist-get info :filter-final-output)
- (if (or (not (functionp template)) body-only) full-body
- (funcall template full-body info))
- info))))))))
+ output info))))))))
;;;###autoload
(defun org-export-string-as (string backend &optional body-only ext-plist)
@@ -3104,22 +3133,22 @@ locally for the subtree through node properties."
(keyword (unless (assoc keyword keywords)
(let ((value
(if (eq (nth 4 entry) 'split)
- (mapconcat #'identity (eval (nth 3 entry)) " ")
- (eval (nth 3 entry)))))
+ (mapconcat #'identity (eval (nth 3 entry) t) " ")
+ (eval (nth 3 entry) t))))
(push (cons keyword value) keywords))))
(option (unless (assoc option options)
- (push (cons option (eval (nth 3 entry))) options))))))
+ (push (cons option (eval (nth 3 entry) t)) options))))))
;; Move to an appropriate location in order to insert options.
(unless subtreep (beginning-of-line))
;; First (multiple) OPTIONS lines. Never go past fill-column.
(when options
(let ((items
(mapcar
- #'(lambda (opt) (format "%s:%S" (car opt) (cdr opt)))
+ (lambda (opt) (format "%s:%S" (car opt) (cdr opt)))
(sort options (lambda (k1 k2) (string< (car k1) (car k2)))))))
(if subtreep
(org-entry-put
- node "EXPORT_OPTIONS" (mapconcat 'identity items " "))
+ node "EXPORT_OPTIONS" (mapconcat #'identity items " "))
(while items
(insert "#+options:")
(let ((width 10))
@@ -3609,7 +3638,7 @@ will become the empty string."
(attributes
(let ((value (org-element-property attribute element)))
(when value
- (let ((s (mapconcat 'identity value " ")) result)
+ (let ((s (mapconcat #'identity value " ")) result)
(while (string-match
"\\(?:^\\|[ \t]+\\)\\(:[-a-zA-Z0-9_]+\\)\\([ \t]+\\|$\\)"
s)
@@ -3659,7 +3688,8 @@ the communication channel used for export, as a plist."
(when (symbolp backend) (setq backend (org-export-get-backend backend)))
(org-export-barf-if-invalid-backend backend)
(let ((type (org-element-type data)))
- (when (memq type '(nil org-data)) (error "No foreign transcoder available"))
+ (when (memq type '(nil org-data raw))
+ (error "No foreign transcoder available"))
(let* ((all-transcoders (org-export-get-all-transcoders backend))
(transcoder (cdr (assq type all-transcoders))))
(unless (functionp transcoder) (error "No foreign transcoder available"))
@@ -4194,10 +4224,10 @@ Return modified DATA."
(or rules org-export-default-inline-image-rule))
;; Replace contents with image link.
(org-element-adopt-elements
- (org-element-set-contents l nil)
- (with-temp-buffer
- (save-excursion (insert contents))
- (org-element-link-parser))))))))
+ (org-element-set-contents l nil)
+ (with-temp-buffer
+ (save-excursion (insert contents))
+ (org-element-link-parser))))))))
info nil nil t))
data)
@@ -4553,6 +4583,18 @@ objects of the same type."
((funcall predicate el info) (cl-incf counter) nil)))
info 'first-match)))))
+;;;; For Raw objects
+;;
+;; `org-export-raw-string' builds a pseudo-object out of a string
+;; that any export back-end returns as-is.
+
+;;;###autoload
+(defun org-export-raw-string (s)
+ "Return a raw object containing string S.
+A raw string is exported as-is, with no additional processing
+from the export back-end."
+ (unless (stringp s) (error "Wrong raw contents type: %S" s))
+ (org-element-create 'raw nil s))
;;;; For Src-Blocks
;;
@@ -4702,7 +4744,7 @@ code."
;; should start six columns after the widest line of code,
;; wrapped with parenthesis.
(max-width
- (+ (apply 'max (mapcar 'length code-lines))
+ (+ (apply #'max (mapcar #'length code-lines))
(if (not num-start) 0 (length (format num-fmt num-start))))))
(org-export-format-code
code
@@ -5082,8 +5124,8 @@ INFO is a plist used as a communication channel."
;; A cell ends a column group either when it is at the end of a row
;; or when it has a right border.
(or (eq (car (last (org-element-contents
- (org-export-get-parent table-cell))))
- table-cell)
+ (org-export-get-parent table-cell))))
+ table-cell)
(memq 'right (org-export-table-cell-borders table-cell info))))
(defun org-export-table-row-starts-rowgroup-p (table-row info)
@@ -5398,6 +5440,16 @@ transcoding it."
(secondary-closing
:utf-8 "‘" :html "&lsquo;" :latex "\\grq{}" :texinfo "@quoteleft{}")
(apostrophe :utf-8 "’" :html "&rsquo;"))
+ ("el"
+ (primary-opening
+ :utf-8 "«" :html "&laquo;" :latex "\\guillemotleft{}"
+ :texinfo "@guillemetleft{}")
+ (primary-closing
+ :utf-8 "»" :html "&raquo;" :latex "\\guillemotright{}"
+ :texinfo "@guillemetright{}")
+ (secondary-opening :utf-8 "“" :html "&ldquo;" :latex "``" :texinfo "``")
+ (secondary-closing :utf-8 "”" :html "&rdquo;" :latex "''" :texinfo "''")
+ (apostrophe :utf-8 "’" :html "&rsquo;"))
("en"
(primary-opening :utf-8 "“" :html "&ldquo;" :latex "``" :texinfo "``")
(primary-closing :utf-8 "”" :html "&rdquo;" :latex "''" :texinfo "''")
@@ -5437,6 +5489,12 @@ transcoding it."
(secondary-closing
:utf-8 "‘" :html "&lsquo;" :latex "\\grq{}" :texinfo "@quoteleft{}")
(apostrophe :utf-8 "’" :html "&rsquo;"))
+ ("it"
+ (primary-opening :utf-8 "“" :html "&ldquo;" :latex "``" :texinfo "``")
+ (primary-closing :utf-8 "”" :html "&rdquo;" :latex "''" :texinfo "''")
+ (secondary-opening :utf-8 "‘" :html "&lsquo;" :latex "`" :texinfo "`")
+ (secondary-closing :utf-8 "’" :html "&rsquo;" :latex "'" :texinfo "'")
+ (apostrophe :utf-8 "’" :html "&rsquo;"))
("no"
;; https://nn.wikipedia.org/wiki/Sitatteikn
(primary-opening
@@ -5483,7 +5541,7 @@ transcoding it."
(apostrophe :utf-8 "’" :html "&rsquo;"))
("ru"
;; https://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D0%B2%D1%8B%D1%87%D0%BA%D0%B8#.D0.9A.D0.B0.D0.B2.D1.8B.D1.87.D0.BA.D0.B8.2C_.D0.B8.D1.81.D0.BF.D0.BE.D0.BB.D1.8C.D0.B7.D1.83.D0.B5.D0.BC.D1.8B.D0.B5_.D0.B2_.D1.80.D1.83.D1.81.D1.81.D0.BA.D0.BE.D0.BC_.D1.8F.D0.B7.D1.8B.D0.BA.D0.B5
- ;; http://www.artlebedev.ru/kovodstvo/sections/104/
+ ;; https://www.artlebedev.ru/kovodstvo/sections/104/
(primary-opening :utf-8 "«" :html "&laquo;" :latex "{}<<"
:texinfo "@guillemetleft{}")
(primary-closing :utf-8 "»" :html "&raquo;" :latex ">>{}"
@@ -5745,6 +5803,7 @@ them."
("ru" :html "&#1040;&#1074;&#1090;&#1086;&#1088;" :utf-8 "Автор")
("sl" :default "Avtor")
("sv" :html "F&ouml;rfattare")
+ ("tr" :default "Yazar")
("uk" :html "&#1040;&#1074;&#1090;&#1086;&#1088;" :utf-8 "Автор")
("zh-CN" :html "&#20316;&#32773;" :utf-8 "作者")
("zh-TW" :html "&#20316;&#32773;" :utf-8 "作者"))
@@ -5757,12 +5816,14 @@ them."
("it" :default "Continua da pagina precedente")
("ja" :default "前ページからの続き")
("nl" :default "Vervolg van vorige pagina")
+ ("pl" :default "Ciąg dalszy poprzedniej strony")
("pt" :default "Continuação da página anterior")
("pt_BR" :html "Continua&ccedil;&atilde;o da p&aacute;gina anterior" :ascii "Continuacao da pagina anterior" :default "Continuação da página anterior")
("ro" :default "Continuare de pe pagina precedentă")
("ru" :html "(&#1055;&#1088;&#1086;&#1076;&#1086;&#1083;&#1078;&#1077;&#1085;&#1080;&#1077;)"
:utf-8 "(Продолжение)")
- ("sl" :default "Nadaljevanje s prejšnje strani"))
+ ("sl" :default "Nadaljevanje s prejšnje strani")
+ ("tr" :default "Önceki sayfadan devam ediyor"))
("Continued on next page"
("ar" :default "التتمة في الصفحة التالية")
("cs" :default "Pokračuje na další stránce")
@@ -5772,18 +5833,21 @@ them."
("it" :default "Continua alla pagina successiva")
("ja" :default "次ページに続く")
("nl" :default "Vervolg op volgende pagina")
+ ("pl" :default "Kontynuacja na następnej stronie")
("pt" :default "Continua na página seguinte")
("pt_BR" :html "Continua na pr&oacute;xima p&aacute;gina" :ascii "Continua na proxima pagina" :default "Continua na próxima página")
("ro" :default "Continuare pe pagina următoare")
("ru" :html "(&#1055;&#1088;&#1086;&#1076;&#1086;&#1083;&#1078;&#1077;&#1085;&#1080;&#1077; &#1089;&#1083;&#1077;&#1076;&#1091;&#1077;&#1090;)"
:utf-8 "(Продолжение следует)")
- ("sl" :default "Nadaljevanje na naslednji strani"))
+ ("sl" :default "Nadaljevanje na naslednji strani")
+ ("tr" :default "Devamı sonraki sayfada"))
("Created"
("cs" :default "Vytvořeno")
("nl" :default "Gemaakt op") ;; must be followed by a date or date+time
("pt_BR" :default "Criado em")
("ro" :default "Creat")
- ("sl" :default "Ustvarjeno"))
+ ("sl" :default "Ustvarjeno")
+ ("tr" :default "Oluşturuldu"))
("Date"
("ar" :default "بتاريخ")
("ca" :default "Data")
@@ -5808,6 +5872,7 @@ them."
("ru" :html "&#1044;&#1072;&#1090;&#1072;" :utf-8 "Дата")
("sl" :default "Datum")
("sv" :default "Datum")
+ ("tr" :default "Tarih")
("uk" :html "&#1044;&#1072;&#1090;&#1072;" :utf-8 "Дата")
("zh-CN" :html "&#26085;&#26399;" :utf-8 "日期")
("zh-TW" :html "&#26085;&#26399;" :utf-8 "日期"))
@@ -5831,6 +5896,7 @@ them."
:utf-8 "Уравнение")
("sl" :default "Enačba")
("sv" :default "Ekvation")
+ ("tr" :default "Eşitlik")
("zh-CN" :html "&#26041;&#31243;" :utf-8 "方程"))
("Figure"
("ar" :default "شكل")
@@ -5850,6 +5916,7 @@ them."
("ro" :default "Imaginea")
("ru" :html "&#1056;&#1080;&#1089;&#1091;&#1085;&#1086;&#1082;" :utf-8 "Рисунок")
("sv" :default "Illustration")
+ ("tr" :default "Şekil")
("zh-CN" :html "&#22270;" :utf-8 "图"))
("Figure %d:"
("ar" :default "شكل %d:")
@@ -5871,6 +5938,7 @@ them."
("ru" :html "&#1056;&#1080;&#1089;. %d.:" :utf-8 "Рис. %d.:")
("sl" :default "Slika %d")
("sv" :default "Illustration %d")
+ ("tr" :default "Şekil %d:")
("zh-CN" :html "&#22270;%d&nbsp;" :utf-8 "图%d "))
("Footnotes"
("ar" :default "الهوامش")
@@ -5879,7 +5947,7 @@ them."
("da" :default "Fodnoter")
("de" :html "Fu&szlig;noten" :default "Fußnoten")
("eo" :default "Piednotoj")
- ("es" :ascii "Nota al pie de pagina" :html "Nota al pie de p&aacute;gina" :default "Nota al pie de página")
+ ("es" :ascii "Notas al pie de pagina" :html "Notas al pie de p&aacute;gina" :default "Notas al pie de página")
("et" :html "Allm&#228;rkused" :utf-8 "Allmärkused")
("fi" :default "Alaviitteet")
("fr" :default "Notes de bas de page")
@@ -5897,6 +5965,7 @@ them."
("ru" :html "&#1057;&#1085;&#1086;&#1089;&#1082;&#1080;" :utf-8 "Сноски")
("sl" :default "Opombe")
("sv" :default "Fotnoter")
+ ("tr" :default "Dipnotlar")
("uk" :html "&#1055;&#1088;&#1080;&#1084;&#1110;&#1090;&#1082;&#1080;"
:utf-8 "Примітки")
("zh-CN" :html "&#33050;&#27880;" :utf-8 "脚注")
@@ -5917,6 +5986,7 @@ them."
("ru" :html "&#1057;&#1087;&#1080;&#1089;&#1086;&#1082; &#1088;&#1072;&#1089;&#1087;&#1077;&#1095;&#1072;&#1090;&#1086;&#1082;"
:utf-8 "Список распечаток")
("sl" :default "Seznam programskih izpisov")
+ ("tr" :default "Program Listesi")
("zh-CN" :html "&#20195;&#30721;&#30446;&#24405;" :utf-8 "代码目录"))
("List of Tables"
("ar" :default "قائمة بالجداول")
@@ -5939,6 +6009,7 @@ them."
:utf-8 "Список таблиц")
("sl" :default "Seznam tabel")
("sv" :default "Tabeller")
+ ("tr" :default "Tablo Listesi")
("zh-CN" :html "&#34920;&#26684;&#30446;&#24405;" :utf-8 "表格目录"))
("Listing"
("ar" :default "برنامج")
@@ -5958,6 +6029,7 @@ them."
("ru" :html "&#1056;&#1072;&#1089;&#1087;&#1077;&#1095;&#1072;&#1090;&#1082;&#1072;"
:utf-8 "Распечатка")
("sl" :default "Izpis programa")
+ ("tr" :default "Program")
("zh-CN" :html "&#20195;&#30721;" :utf-8 "代码"))
("Listing %d:"
("ar" :default "برنامج %d:")
@@ -5977,6 +6049,7 @@ them."
("ru" :html "&#1056;&#1072;&#1089;&#1087;&#1077;&#1095;&#1072;&#1090;&#1082;&#1072; %d.:"
:utf-8 "Распечатка %d.:")
("sl" :default "Izpis programa %d")
+ ("tr" :default "Program %d:")
("zh-CN" :html "&#20195;&#30721;%d&nbsp;" :utf-8 "代码%d "))
("References"
("ar" :default "المراجع")
@@ -5988,7 +6061,8 @@ them."
("nl" :default "Bronverwijzingen")
("pt_BR" :html "Refer&ecirc;ncias" :default "Referências" :ascii "Referencias")
("ro" :default "Bibliografie")
- ("sl" :default "Reference"))
+ ("sl" :default "Reference")
+ ("tr" :default "Referanslar"))
("See figure %s"
("cs" :default "Viz obrázek %s")
("fr" :default "cf. figure %s"
@@ -5998,7 +6072,8 @@ them."
:html "Zie figuur&nbsp;%s" :latex "Zie figuur~%s")
("pt_BR" :default "Veja a figura %s")
("ro" :default "Vezi figura %s")
- ("sl" :default "Glej sliko %s"))
+ ("sl" :default "Glej sliko %s")
+ ("tr" :default "bkz. şekil %s"))
("See listing %s"
("cs" :default "Viz program %s")
("fr" :default "cf. programme %s"
@@ -6007,7 +6082,8 @@ them."
:html "Zie programma&nbsp;%s" :latex "Zie programma~%s")
("pt_BR" :default "Veja a listagem %s")
("ro" :default "Vezi tabelul %s")
- ("sl" :default "Glej izpis programa %s"))
+ ("sl" :default "Glej izpis programa %s")
+ ("tr" :default "bkz. program %s"))
("See section %s"
("ar" :default "انظر قسم %s")
("cs" :default "Viz sekce %s")
@@ -6026,6 +6102,7 @@ them."
("ru" :html "&#1057;&#1084;. &#1088;&#1072;&#1079;&#1076;&#1077;&#1083; %s"
:utf-8 "См. раздел %s")
("sl" :default "Glej poglavje %d")
+ ("tr" :default "bkz. bölüm %s")
("zh-CN" :html "&#21442;&#35265;&#31532;%s&#33410;" :utf-8 "参见第%s节"))
("See table %s"
("cs" :default "Viz tabulka %s")
@@ -6036,7 +6113,8 @@ them."
:html "Zie tabel&nbsp;%s" :latex "Zie tabel~%s")
("pt_BR" :default "Veja a tabela %s")
("ro" :default "Vezi tabelul %s")
- ("sl" :default "Glej tabelo %s"))
+ ("sl" :default "Glej tabelo %s")
+ ("tr" :default "bkz. tablo %s"))
("Table"
("ar" :default "جدول")
("cs" :default "Tabulka")
@@ -6052,6 +6130,7 @@ them."
("ro" :default "Tabel")
("ru" :html "&#1058;&#1072;&#1073;&#1083;&#1080;&#1094;&#1072;"
:utf-8 "Таблица")
+ ("tr" :default "Tablo")
("zh-CN" :html "&#34920;" :utf-8 "表"))
("Table %d:"
("ar" :default "جدول %d:")
@@ -6074,6 +6153,7 @@ them."
:utf-8 "Таблица %d.:")
("sl" :default "Tabela %d")
("sv" :default "Tabell %d")
+ ("tr" :default "Tablo %d")
("zh-CN" :html "&#34920;%d&nbsp;" :utf-8 "表%d "))
("Table of Contents"
("ar" :default "قائمة المحتويات")
@@ -6101,6 +6181,7 @@ them."
:utf-8 "Содержание")
("sl" :default "Kazalo")
("sv" :html "Inneh&aring;ll")
+ ("tr" :default "İçindekiler")
("uk" :html "&#1047;&#1084;&#1110;&#1089;&#1090;" :utf-8 "Зміст")
("zh-CN" :html "&#30446;&#24405;" :utf-8 "目录")
("zh-TW" :html "&#30446;&#37636;" :utf-8 "目錄"))
@@ -6119,6 +6200,7 @@ them."
("ru" :html "&#1053;&#1077;&#1080;&#1079;&#1074;&#1077;&#1089;&#1090;&#1085;&#1072;&#1103; &#1089;&#1089;&#1099;&#1083;&#1082;&#1072;"
:utf-8 "Неизвестная ссылка")
("sl" :default "Neznana referenca")
+ ("tr" :default "Bilinmeyen referans")
("zh-CN" :html "&#26410;&#30693;&#24341;&#29992;" :utf-8 "未知引用")))
"Dictionary for export engine.
@@ -6176,97 +6258,93 @@ to `:default' encoding. If it fails, return S."
;; For back-ends, `org-export-add-to-stack' add a new source to stack.
;; It should be used whenever `org-export-async-start' is called.
-(defmacro org-export-async-start (fun &rest body)
+(defun org-export-async-start (fun body)
"Call function FUN on the results returned by BODY evaluation.
-FUN is an anonymous function of one argument. BODY evaluation
-happens in an asynchronous process, from a buffer which is an
-exact copy of the current one.
+FUN is an anonymous function of one argument. BODY should be a valid
+ELisp source expression. BODY evaluation happens in an asynchronous process,
+from a buffer which is an exact copy of the current one.
Use `org-export-add-to-stack' in FUN in order to register results
in the stack.
This is a low level function. See also `org-export-to-buffer'
and `org-export-to-file' for more specialized functions."
- (declare (indent 1) (debug t))
- (org-with-gensyms (process temp-file copy-fun proc-buffer coding)
- ;; Write the full sexp evaluating BODY in a copy of the current
- ;; buffer to a temporary file, as it may be too long for program
- ;; args in `start-process'.
- `(with-temp-message "Initializing asynchronous export process"
- (let ((,copy-fun (org-export--generate-copy-script (current-buffer)))
- (,temp-file (make-temp-file "org-export-process"))
- (,coding buffer-file-coding-system))
- (with-temp-file ,temp-file
- (insert
- ;; Null characters (from variable values) are inserted
- ;; within the file. As a consequence, coding system for
- ;; buffer contents will not be recognized properly. So,
- ;; we make sure it is the same as the one used to display
- ;; the original buffer.
- (format ";; -*- coding: %s; -*-\n%S"
- ,coding
- `(with-temp-buffer
- (when org-export-async-debug '(setq debug-on-error t))
- ;; Ignore `kill-emacs-hook' and code evaluation
- ;; queries from Babel as we need a truly
- ;; non-interactive process.
- (setq kill-emacs-hook nil
- org-babel-confirm-evaluate-answer-no t)
- ;; Initialize export framework.
- (require 'ox)
- ;; Re-create current buffer there.
- (funcall ,,copy-fun)
- (restore-buffer-modified-p nil)
- ;; Sexp to evaluate in the buffer.
- (print (progn ,,@body))))))
- ;; Start external process.
- (let* ((process-connection-type nil)
- (,proc-buffer (generate-new-buffer-name "*Org Export Process*"))
- (,process
- (apply
- #'start-process
- (append
- (list "org-export-process"
- ,proc-buffer
- (expand-file-name invocation-name invocation-directory)
- "--batch")
- (if org-export-async-init-file
- (list "-Q" "-l" org-export-async-init-file)
- (list "-l" user-init-file))
- (list "-l" ,temp-file)))))
- ;; Register running process in stack.
- (org-export-add-to-stack (get-buffer ,proc-buffer) nil ,process)
- ;; Set-up sentinel in order to catch results.
- (let ((handler ,fun))
- (set-process-sentinel
- ,process
- `(lambda (p status)
- (let ((proc-buffer (process-buffer p)))
- (when (eq (process-status p) 'exit)
- (unwind-protect
- (if (zerop (process-exit-status p))
- (unwind-protect
- (let ((results
- (with-current-buffer proc-buffer
- (goto-char (point-max))
- (backward-sexp)
- (read (current-buffer)))))
- (funcall ,handler results))
- (unless org-export-async-debug
- (and (get-buffer proc-buffer)
- (kill-buffer proc-buffer))))
- (org-export-add-to-stack proc-buffer nil p)
- (ding)
- (message "Process `%s' exited abnormally" p))
- (unless org-export-async-debug
- (delete-file ,,temp-file)))))))))))))
+ (declare (indent 1))
+ ;; Write the full sexp evaluating BODY in a copy of the current
+ ;; buffer to a temporary file, as it may be too long for program
+ ;; args in `start-process'.
+ (with-temp-message "Initializing asynchronous export process"
+ (let ((copy-fun (org-export--generate-copy-script (current-buffer)))
+ (temp-file (make-temp-file "org-export-process")))
+ (let ((coding-system-for-write 'utf-8-emacs-unix))
+ (write-region
+ ;; Null characters (from variable values) are inserted
+ ;; within the file. As a consequence, coding system for
+ ;; buffer contents could fail to be recognized properly.
+ (format ";; -*- coding: utf-8-emacs-unix; lexical-binding:t -*-\n%S"
+ `(with-temp-buffer
+ ,(when org-export-async-debug '(setq debug-on-error t))
+ ;; Ignore `kill-emacs-hook' and code evaluation
+ ;; queries from Babel as we need a truly
+ ;; non-interactive process.
+ (setq kill-emacs-hook nil
+ org-babel-confirm-evaluate-answer-no t)
+ ;; Initialize export framework.
+ (require 'ox)
+ ;; Re-create current buffer there.
+ (funcall ',copy-fun)
+ (restore-buffer-modified-p nil)
+ ;; Sexp to evaluate in the buffer.
+ (print ,body)))
+ nil temp-file nil 'silent))
+ ;; Start external process.
+ (let* ((process-connection-type nil)
+ (proc-buffer (generate-new-buffer-name "*Org Export Process*"))
+ (process
+ (apply
+ #'start-process
+ (append
+ (list "org-export-process"
+ proc-buffer
+ (expand-file-name invocation-name invocation-directory)
+ "--batch")
+ (if org-export-async-init-file
+ (list "-Q" "-l" org-export-async-init-file)
+ (list "-l" user-init-file))
+ (list "-l" temp-file)))))
+ ;; Register running process in stack.
+ (org-export-add-to-stack (get-buffer proc-buffer) nil process)
+ ;; Set-up sentinel in order to catch results.
+ (let ((handler fun))
+ (set-process-sentinel
+ process
+ (lambda (p _status)
+ (let ((proc-buffer (process-buffer p)))
+ (when (eq (process-status p) 'exit)
+ (unwind-protect
+ (if (zerop (process-exit-status p))
+ (unwind-protect
+ (let ((results
+ (with-current-buffer proc-buffer
+ (goto-char (point-max))
+ (backward-sexp)
+ (read (current-buffer)))))
+ (funcall handler results))
+ (unless org-export-async-debug
+ (and (get-buffer proc-buffer)
+ (kill-buffer proc-buffer))))
+ (org-export-add-to-stack proc-buffer nil p)
+ (ding)
+ (message "Process `%s' exited abnormally" p))
+ (unless org-export-async-debug
+ (delete-file temp-file))))))))))))
;;;###autoload
(defun org-export-to-buffer
- (backend buffer
- &optional async subtreep visible-only body-only ext-plist
- post-process)
+ (backend buffer
+ &optional async subtreep visible-only body-only ext-plist
+ post-process)
"Call `org-export-as' with output to a specified buffer.
BACKEND is either an export back-end, as returned by, e.g.,
@@ -6295,20 +6373,25 @@ use it to set a major mode there, e.g,
(&optional async subtreep visible-only body-only ext-plist)
(interactive)
(org-export-to-buffer \\='latex \"*Org LATEX Export*\"
- async subtreep visible-only body-only ext-plist (lambda () (LaTeX-mode))))
+ async subtreep visible-only body-only ext-plist
+ #'LaTeX-mode))
+
+When expressed as an anonymous function, using `lambda',
+POST-PROCESS needs to be quoted.
This function returns BUFFER."
(declare (indent 2))
(if async
(org-export-async-start
- `(lambda (output)
- (with-current-buffer (get-buffer-create ,buffer)
- (erase-buffer)
- (setq buffer-file-coding-system ',buffer-file-coding-system)
- (insert output)
- (goto-char (point-min))
- (org-export-add-to-stack (current-buffer) ',backend)
- (ignore-errors (funcall ,post-process))))
+ (let ((cs buffer-file-coding-system))
+ (lambda (output)
+ (with-current-buffer (get-buffer-create buffer)
+ (erase-buffer)
+ (setq buffer-file-coding-system cs)
+ (insert output)
+ (goto-char (point-min))
+ (org-export-add-to-stack (current-buffer) backend)
+ (ignore-errors (funcall post-process)))))
`(org-export-as
',backend ,subtreep ,visible-only ,body-only ',ext-plist))
(let ((output
@@ -6329,8 +6412,8 @@ This function returns BUFFER."
;;;###autoload
(defun org-export-to-file
- (backend file &optional async subtreep visible-only body-only ext-plist
- post-process)
+ (backend file &optional async subtreep visible-only body-only ext-plist
+ post-process)
"Call `org-export-as' with output to a specified file.
BACKEND is either an export back-end, as returned by, e.g.,
@@ -6357,18 +6440,22 @@ to send the output file through additional processing, e.g,
(let ((outfile (org-export-output-file-name \".tex\" subtreep)))
(org-export-to-file \\='latex outfile
async subtreep visible-only body-only ext-plist
- (lambda (file) (org-latex-compile file)))
+ #'org-latex-compile)))
+
+When expressed as an anonymous function, using `lambda',
+POST-PROCESS needs to be quoted.
The function returns either a file name returned by POST-PROCESS,
or FILE."
(declare (indent 2))
(if (not (file-writable-p file)) (error "Output file not writable")
(let ((ext-plist (org-combine-plists `(:output-file ,file) ext-plist))
- (encoding (or org-export-coding-system buffer-file-coding-system)))
+ (encoding (or org-export-coding-system buffer-file-coding-system))
+ auto-mode-alist)
(if async
(org-export-async-start
- `(lambda (file)
- (org-export-add-to-stack (expand-file-name file) ',backend))
+ (lambda (file)
+ (org-export-add-to-stack (expand-file-name file) backend))
`(let ((output
(org-export-as
',backend ,subtreep ,visible-only ,body-only
@@ -6422,7 +6509,10 @@ Return file name as a string."
(throw :found
(org-element-property :value element))))))))
;; Extract from buffer's associated file, if any.
- (and visited-file (file-name-nondirectory visited-file))
+ (and visited-file
+ (file-name-nondirectory
+ ;; For a .gpg visited file, remove the .gpg extension:
+ (replace-regexp-in-string "\\.gpg\\'" "" visited-file)))
;; Can't determine file name on our own: ask user.
(read-file-name
"Output file: " pub-dir nil nil nil
@@ -6483,7 +6573,7 @@ If optional argument SOURCE is non-nil, remove it instead."
(let ((source (or source (org-export--stack-source-at-point))))
(setq org-export-stack-contents
(cl-remove-if (lambda (el) (equal (car el) source))
- org-export-stack-contents))))
+ org-export-stack-contents))))
(defun org-export-stack-view (&optional in-emacs)
"View export results at point in stack.
@@ -6499,16 +6589,16 @@ within Emacs."
(defvar org-export-stack-mode-map
(let ((km (make-sparse-keymap)))
(set-keymap-parent km tabulated-list-mode-map)
- (define-key km " " 'next-line)
- (define-key km "\C-n" 'next-line)
- (define-key km [down] 'next-line)
- (define-key km "\C-p" 'previous-line)
- (define-key km "\C-?" 'previous-line)
- (define-key km [up] 'previous-line)
- (define-key km "C" 'org-export-stack-clear)
- (define-key km "v" 'org-export-stack-view)
- (define-key km (kbd "RET") 'org-export-stack-view)
- (define-key km "d" 'org-export-stack-remove)
+ (define-key km " " #'next-line)
+ (define-key km "\C-n" #'next-line)
+ (define-key km [down] #'next-line)
+ (define-key km "\C-p" #'previous-line)
+ (define-key km "\C-?" #'previous-line)
+ (define-key km [up] #'previous-line)
+ (define-key km "C" #'org-export-stack-clear)
+ (define-key km "v" #'org-export-stack-view)
+ (define-key km (kbd "RET") #'org-export-stack-view)
+ (define-key km "d" #'org-export-stack-remove)
km)
"Keymap for Org Export Stack.")
@@ -6706,7 +6796,7 @@ back to standard interface."
;; on the first key, if any. A nil value means KEY will
;; only be activated at first level.
(if (or (eq access-key t) (eq access-key first-key))
- (propertize key 'face 'org-warning)
+ (propertize key 'face 'org-dispatcher-highlight)
key)))
(fontify-value
(lambda (value)
@@ -6725,16 +6815,16 @@ back to standard interface."
(cond ((and (numberp key-a) (numberp key-b))
(< key-a key-b))
((numberp key-b) t)))))
- 'car-less-than-car))
+ #'car-less-than-car))
;; Compute a list of allowed keys based on the first key
;; pressed, if any. Some keys
;; (?^B, ?^V, ?^S, ?^F, ?^A, ?&, ?# and ?q) are always
;; available.
(allowed-keys
(nconc (list 2 22 19 6 1)
- (if (not first-key) (org-uniquify (mapcar 'car entries))
+ (if (not first-key) (org-uniquify (mapcar #'car entries))
(let (sub-menu)
- (dolist (entry entries (sort (mapcar 'car sub-menu) '<))
+ (dolist (entry entries (sort (mapcar #'car sub-menu) #'<))
(when (eq (car entry) first-key)
(setq sub-menu (append (nth 2 entry) sub-menu))))))
(cond ((eq first-key ?P) (list ?f ?p ?x ?a))
diff --git a/lisp/outline.el b/lisp/outline.el
index 0bb74ffd64a..5e3d4e0e002 100644
--- a/lisp/outline.el
+++ b/lisp/outline.el
@@ -35,6 +35,8 @@
;;; Code:
+(eval-when-compile (require 'cl-lib))
+
(defgroup outlines nil
"Support for hierarchical outlining."
:prefix "outline-"
@@ -175,36 +177,58 @@ in the file it applies to.")
outline-mode-menu-bar-map))))))
map))
-(defvar outline-mode-cycle-map
+(defcustom outline-minor-mode-cycle-filter nil
+ "Filter out positions on the heading available for cycling."
+ :type '(choice (const :tag "Everywhere" nil)
+ (const :tag "At line beginning" bolp)
+ (const :tag "Not at line beginning"
+ (lambda () (not (bolp))))
+ (const :tag "At line end" eolp)
+ (function :tag "Custom filter"))
+ :version "28.1")
+
+(defun outline-minor-mode-cycle--bind (map key binding &optional filter)
+ (define-key map key
+ `(menu-item
+ "" ,binding
+ ;; Filter out specific positions on the heading.
+ :filter
+ ,(or filter
+ (lambda (cmd)
+ (when (or (not (functionp outline-minor-mode-cycle-filter))
+ (funcall outline-minor-mode-cycle-filter))
+ cmd))))))
+
+(defvar outline-minor-mode-cycle-map
(let ((map (make-sparse-keymap)))
- (let ((tab-binding `(menu-item
- "" outline-cycle
- ;; Only takes effect if point is on a heading.
- :filter ,(lambda (cmd)
- (when (outline-on-heading-p) cmd)))))
- (define-key map (kbd "TAB") tab-binding)
- (define-key map (kbd "<backtab>") #'outline-cycle-buffer))
+ (outline-minor-mode-cycle--bind map (kbd "TAB") #'outline-cycle)
+ (outline-minor-mode-cycle--bind map (kbd "<backtab>") #'outline-cycle-buffer)
map)
- "Keymap used by `outline-mode-map' and `outline-minor-mode-cycle'.")
+ "Keymap used by `outline-minor-mode-cycle'.")
(defvar outline-mode-map
(let ((map (make-sparse-keymap)))
- (set-keymap-parent map outline-mode-cycle-map)
(define-key map "\C-c" outline-mode-prefix-map)
(define-key map [menu-bar] outline-mode-menu-bar-map)
+ ;; Only takes effect if point is on a heading.
+ (define-key map (kbd "TAB")
+ `(menu-item "" outline-cycle
+ :filter ,(lambda (cmd)
+ (when (outline-on-heading-p) cmd))))
+ (define-key map (kbd "<backtab>") #'outline-cycle-buffer)
map))
(defvar outline-font-lock-keywords
'(
;; Highlight headings according to the level.
- (eval . (list (concat "^\\(?:" outline-regexp "\\).+")
+ (eval . (list (concat "^\\(?:" outline-regexp "\\).*")
0 '(if outline-minor-mode
(if outline-minor-mode-cycle
(if outline-minor-mode-highlight
(list 'face (outline-font-lock-face)
- 'keymap outline-mode-cycle-map)
+ 'keymap outline-minor-mode-cycle-map)
(list 'face nil
- 'keymap outline-mode-cycle-map))
+ 'keymap outline-minor-mode-cycle-map))
(if outline-minor-mode-highlight
(list 'face (outline-font-lock-face))))
(outline-font-lock-face))
@@ -250,6 +274,25 @@ in the file it applies to.")
(defvar outline-font-lock-faces
[outline-1 outline-2 outline-3 outline-4
outline-5 outline-6 outline-7 outline-8])
+
+(defcustom outline-minor-mode-use-buttons nil
+ "If non-nil, use clickable buttons on the headings.
+Note that this feature is not meant to be used in editing
+buffers (yet) -- that will be amended in a future version.
+
+The `outline-minor-mode-buttons' variable specifies how the
+buttons should look."
+ :type 'boolean
+ :safe #'booleanp
+ :version "29.1")
+
+(defcustom outline-minor-mode-buttons
+ '(("▶️" "🔽" outline--valid-emoji-p)
+ ("▶" "▼" outline--valid-char-p))
+ "List of close/open pairs to use if using buttons."
+ :type 'sexp
+ :version "29.1")
+
(defvar outline-level #'outline-level
"Function of no args to compute a header's nesting level in an outline.
@@ -334,8 +377,8 @@ When point is on a heading line, then typing `TAB' cycles between `hide all',
a heading line cycles the whole buffer (`outline-cycle-buffer').
Typing these keys anywhere outside heading lines uses their default bindings."
:type 'boolean
+ :safe #'booleanp
:version "28.1")
-;;;###autoload(put 'outline-minor-mode-cycle 'safe-local-variable 'booleanp)
(defcustom outline-minor-mode-highlight nil
"Highlight headings in `outline-minor-mode' using font-lock keywords.
@@ -349,8 +392,8 @@ faces to major mode's faces."
(const :tag "Overwrite major mode faces" override)
(const :tag "Append outline faces to major mode faces" append)
(const :tag "Highlight separately from major mode faces" t))
+ :safe #'symbolp
:version "28.1")
-;;;###autoload(put 'outline-minor-mode-highlight 'safe-local-variable 'symbolp)
(defun outline-minor-mode-highlight-buffer ()
;; Fallback to overlays when font-lock is unsupported.
@@ -366,8 +409,10 @@ faces to major mode's faces."
(goto-char (match-beginning 0))
(not (get-text-property (point) 'face))))
(overlay-put overlay 'face (outline-font-lock-face)))
+ (when outline-minor-mode-use-buttons
+ (outline--insert-open-button))
(when outline-minor-mode-cycle
- (overlay-put overlay 'keymap outline-mode-cycle-map)))
+ (overlay-put overlay 'keymap outline-minor-mode-cycle-map)))
(goto-char (match-end 0))))))
;;;###autoload
@@ -785,6 +830,7 @@ If FLAG is nil then text is shown, while if FLAG is t the text is hidden."
(overlay-put o 'isearch-open-invisible
(or outline-isearch-open-invisible-function
#'outline-isearch-open-invisible))))
+ (outline--fix-up-all-buttons from to)
;; Seems only used by lazy-lock. I.e. obsolete.
(run-hooks 'outline-view-change-hook))
@@ -901,11 +947,82 @@ Note that this does not hide the lines preceding the first heading line."
(define-obsolete-function-alias 'show-all #'outline-show-all "25.1")
-(defun outline-hide-subtree ()
- "Hide everything after this heading at deeper levels."
- (interactive)
+(defun outline-hide-subtree (&optional event)
+ "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 (and outline-minor-mode-use-buttons outline-minor-mode)
+ (outline--insert-close-button))
(outline-flag-subtree t))
+(defun outline--make-button (type)
+ (cl-loop for (close open test) in outline-minor-mode-buttons
+ when (and (funcall test close) (funcall test open))
+ return (concat (if (eq type 'close)
+ close
+ open)
+ " " (buffer-substring (point) (1+ (point))))))
+
+(defun outline--valid-emoji-p (string)
+ (when-let ((font (and (display-multi-font-p)
+ (car (internal-char-font nil ?😀)))))
+ (font-has-char-p font (aref string 0))))
+
+(defun outline--valid-char-p (string)
+ (char-displayable-p (aref string 0)))
+
+(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))
+ (overlay-put o 'display (outline--make-button type))
+ o))
+
+(defun outline--insert-open-button ()
+ (save-excursion
+ (beginning-of-line)
+ (let ((o (outline--make-button-overlay 'open)))
+ (overlay-put o 'help-echo "Click to hide")
+ (overlay-put o 'keymap
+ (define-keymap
+ :parent outline-minor-mode-cycle-map
+ "RET" #'outline-hide-subtree
+ "<mouse-2>" #'outline-hide-subtree)))))
+
+(defun outline--insert-close-button ()
+ (save-excursion
+ (beginning-of-line)
+ (let ((o (outline--make-button-overlay 'close)))
+ (overlay-put o 'help-echo "Click to show")
+ (overlay-put o 'keymap
+ (define-keymap
+ :parent outline-minor-mode-cycle-map
+ "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-minor-mode-use-buttons
+ (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)))))
+
(define-obsolete-function-alias 'hide-subtree #'outline-hide-subtree "25.1")
(defun outline-hide-leaves ()
@@ -921,9 +1038,13 @@ Note that this does not hide the lines preceding the first heading line."
(define-obsolete-function-alias 'hide-leaves #'outline-hide-leaves "25.1")
-(defun outline-show-subtree ()
+(defun outline-show-subtree (&optional event)
"Show everything after this heading at deeper levels."
- (interactive)
+ (interactive (list last-nonmenu-event))
+ (when (mouse-event-p event)
+ (mouse-set-point event))
+ (when (and outline-minor-mode-use-buttons outline-minor-mode)
+ (outline--insert-open-button))
(outline-flag-subtree nil))
(define-obsolete-function-alias 'show-subtree #'outline-show-subtree "25.1")
@@ -1273,7 +1394,8 @@ Return either 'hide-all, 'headings-only, or 'show-all."
(t
(outline-show-all)
(setq outline--cycle-buffer-state 'show-all)
- (message "Show all")))))
+ (message "Show all")))
+ (outline--fix-up-all-buttons)))
(defvar outline-navigation-repeat-map
(let ((map (make-sparse-keymap)))
diff --git a/lisp/paren.el b/lisp/paren.el
index a45a08abd36..7e7cf6c262a 100644
--- a/lisp/paren.el
+++ b/lisp/paren.el
@@ -88,6 +88,14 @@ is not highlighted, the cursor being regarded as adequate to mark
its position."
:type 'boolean)
+(defcustom show-paren-context-when-offscreen nil
+ "If non-nil, show context in the echo area when the openparen is offscreen.
+The context is usually the line that contains the openparen,
+except if the openparen is on its own line, in which case the
+context includes the previous nonblank line."
+ :type 'boolean
+ :version "29.1")
+
(defvar show-paren--idle-timer nil)
(defvar show-paren--overlay
(let ((ol (make-overlay (point) (point) nil t))) (delete-overlay ol) ol)
@@ -101,10 +109,14 @@ its position."
(define-minor-mode show-paren-mode
"Toggle visualization of matching parens (Show Paren mode).
-Show Paren mode is a global minor mode. When enabled, any
-matching parenthesis is highlighted in `show-paren-style' after
-`show-paren-delay' seconds of Emacs idle time."
+When enabled, any matching parenthesis is highlighted in `show-paren-style'
+after `show-paren-delay' seconds of Emacs idle time.
+
+This is a global minor mode. To toggle the mode in a single buffer,
+use `show-paren-local-mode'."
:global t :group 'paren-showing
+ :initialize 'custom-initialize-delay
+ :init-value t
;; Enable or disable the mechanism.
;; First get rid of the old idle timer.
(when show-paren--idle-timer
@@ -114,8 +126,28 @@ matching parenthesis is highlighted in `show-paren-style' after
show-paren-delay t
#'show-paren-function))
(unless show-paren-mode
- (delete-overlay show-paren--overlay)
- (delete-overlay show-paren--overlay-1)))
+ (show-paren--delete-overlays)))
+
+(defun show-paren--delete-overlays ()
+ (delete-overlay show-paren--overlay)
+ (delete-overlay show-paren--overlay-1))
+
+;;;###autoload
+(define-minor-mode show-paren-local-mode
+ "Toggle `show-paren-mode' only in this buffer."
+ :variable (buffer-local-value 'show-paren-mode (current-buffer))
+ (cond
+ ((eq show-paren-mode (default-value 'show-paren-mode))
+ (unless show-paren-mode
+ (show-paren--delete-overlays))
+ (kill-local-variable 'show-paren-mode))
+ ((not (default-value 'show-paren-mode))
+ ;; Locally enabled, but globally disabled.
+ (show-paren-mode 1) ; Setup the timer.
+ (setq-default show-paren-mode nil) ; But keep it globally disabled.
+ )
+ (t ;; Locally disabled only.
+ (show-paren--delete-overlays))))
(defun show-paren--unescaped-p (pos)
"Determine whether the paren after POS is unescaped."
@@ -288,6 +320,19 @@ It is the default value of `show-paren-data-function'."
(current-buffer))
(move-overlay show-paren--overlay
there-beg there-end (current-buffer)))
+ ;; If `show-paren-open-line-when-offscreen' is t and point
+ ;; is at a close paren, show the line that contains the
+ ;; openparen in the echo area.
+ (let ((openparen (min here-beg there-beg)))
+ (if (and show-paren-context-when-offscreen
+ (< there-beg here-beg)
+ (not (pos-visible-in-window-p openparen)))
+ (let ((open-paren-line-string
+ (blink-paren-open-paren-line-string openparen))
+ (message-log-max nil))
+ (minibuffer-message
+ "Matches %s"
+ (substring-no-properties open-paren-line-string)))))
;; Always set the overlay face, since it varies.
(overlay-put show-paren--overlay 'priority show-paren-priority)
(overlay-put show-paren--overlay 'face face))))))
diff --git a/lisp/pcmpl-x.el b/lisp/pcmpl-x.el
index fd147101b69..d9479edf6a6 100644
--- a/lisp/pcmpl-x.el
+++ b/lisp/pcmpl-x.el
@@ -21,6 +21,8 @@
;; 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:
(eval-when-compile (require 'cl-lib))
diff --git a/lisp/pcomplete.el b/lisp/pcomplete.el
index 64acc416c23..1636e218821 100644
--- a/lisp/pcomplete.el
+++ b/lisp/pcomplete.el
@@ -680,8 +680,8 @@ user actually typed in."
(match-string which arg)
(throw 'pcompleted nil))))
-(defalias 'pcomplete-match-beginning 'match-beginning)
-(defalias 'pcomplete-match-end 'match-end)
+(define-obsolete-function-alias 'pcomplete-match-beginning #'match-beginning "29.1")
+(define-obsolete-function-alias 'pcomplete-match-end #'match-end "29.1")
(defsubst pcomplete--test (pred arg)
"Perform a programmable completion predicate match."
@@ -1006,7 +1006,7 @@ Arguments NO-GANGING and ARGS-FOLLOW are currently ignored."
((eq arg-char ?*) (pcomplete-executables))
((eq arg-char ??) nil)
((eq arg-char ?.) (pcomplete-entries))
- ((eq arg-char ?\() (eval result))))))
+ ((eq arg-char ?\() (eval result t))))))
(setq index (1+ index))))))))
(defun pcomplete--here (&optional form stub paring form-only)
@@ -1040,7 +1040,7 @@ See the documentation for `pcomplete-here'."
(funcall form)
;; Old calling convention, might still be used by files
;; byte-compiled with the older code.
- (eval form)))))
+ (eval form t)))))
(defmacro pcomplete-here* (&optional form stub form-only)
@@ -1062,9 +1062,9 @@ See the documentation for `pcomplete-here'."
pcomplete-window-restore-timer nil))
(define-obsolete-function-alias 'pcomplete-event-matches-key-specifier-p
- 'eq "27.1")
+ #'eq "27.1")
-(define-obsolete-function-alias 'pcomplete-read-event 'read-event "27.1")
+(define-obsolete-function-alias 'pcomplete-read-event #'read-event "27.1")
(defun pcomplete-show-completions (completions)
"List in help buffer sorted COMPLETIONS.
@@ -1244,7 +1244,7 @@ If specific documentation can't be given, be generic."
(fboundp 'Info-goto-node))
(listp pcomplete-help)))
(if (listp pcomplete-help)
- (message "%s" (eval pcomplete-help))
+ (message "%s" (eval pcomplete-help t))
(save-window-excursion (info))
(declare-function Info-goto-node
"info" (nodename &optional fork strict-case))
diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el
index 78b8259b395..fa0185b16e9 100644
--- a/lisp/pixel-scroll.el
+++ b/lisp/pixel-scroll.el
@@ -67,6 +67,8 @@
;;; Code:
(require 'mwheel)
+(require 'subr-x)
+(require 'ring)
(defvar pixel-wait 0
"Idle time on each step of pixel scroll specified in second.
@@ -90,6 +92,73 @@ is always with pixel resolution.")
(defvar pixel-last-scroll-time 0
"Time when the last scrolling was made, in second since the epoch.")
+(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)
+ map)
+ "The key map used by `pixel-scroll-precision-mode'.")
+
+(defcustom pixel-scroll-precision-use-momentum nil
+ "If non-nil, continue to scroll the display after wheel movement stops.
+This is only effective if supported by your mouse or touchpad."
+ :group 'mouse
+ :type 'boolean
+ :version "29.1")
+
+(defcustom pixel-scroll-precision-momentum-tick 0.01
+ "Number of seconds between each momentum scroll."
+ :group 'mouse
+ :type 'float
+ :version "29.1")
+
+(defcustom pixel-scroll-precision-momentum-seconds 1.75
+ "The maximum duration in seconds of momentum scrolling."
+ :group 'mouse
+ :type 'float
+ :version "29.1")
+
+(defcustom pixel-scroll-precision-momentum-min-velocity 10.0
+ "The minimum scrolled pixels per second before momentum scrolling starts."
+ :group 'mouse
+ :type 'float
+ :version "29.1")
+
+(defcustom pixel-scroll-precision-initial-velocity-factor 0.25
+ "Factor applied to the initial velocity before momentum scrolling begins."
+ :group 'mouse
+ :type 'float
+ :version "29.1")
+
+(defcustom pixel-scroll-precision-large-scroll-height nil
+ "Pixels that must be scrolled before an animation is performed.
+Nil means to not interpolate such scrolls."
+ :group 'mouse
+ :type '(choice (const :tag "Do not interpolate large scrolls" nil)
+ number)
+ :version "29.1")
+
+(defcustom pixel-scroll-precision-interpolation-total-time 0.1
+ "The total time in seconds to spend interpolating a large scroll."
+ :group 'mouse
+ :type 'float
+ :version "29.1")
+
+(defcustom pixel-scroll-precision-interpolation-factor 4.0
+ "A factor to apply to the distance of an interpolated scroll."
+ :group 'mouse
+ :type 'float
+ :version "29.1")
+
+(defcustom pixel-scroll-precision-interpolation-between-scroll 0.001
+ "The number of seconds between each step of an interpolated scroll."
+ :group 'mouse
+ :type 'float
+ :version "29.1")
+
(defun pixel-scroll-in-rush-p ()
"Return non-nil if next scroll should be non-smooth.
When scrolling request is delivered soon after the previous one,
@@ -296,9 +365,9 @@ unseen line above the first line, respectively, is provided."
(defun pixel-visible-pos-in-window ()
"Return position shown on text line where cursor is in the selected window.
-This will look for positions of point and end-of-visual-line,
-then positions from beginning-of-visual-line to
-end-of-visual-line. When no char in a line is shown, this
+This will look for positions of point and `end-of-visual-line',
+then positions from `beginning-of-visual-line' to
+`end-of-visual-line'. When no char in a line is shown, this
returns nil."
(let* ((beginning-of-visual-line-pos (save-excursion (beginning-of-visual-line) (point)))
(end-of-visual-line-pos (save-excursion (end-of-visual-line) (point)))
@@ -323,28 +392,44 @@ returns nil."
(setq pos-list (cdr pos-list))))
visible-pos))
-(defun pixel-point-at-unseen-line ()
- "Return the character position of line above the selected window.
-The returned value is the position of the first character on the
-unseen line just above the scope of current window."
- (let* ((pos0 (window-start))
+(defun pixel-point-and-height-at-unseen-line ()
+ "Return the position and pixel height of line above the selected window.
+The returned value is a cons of the position of the first
+character on the unseen line just above the scope of current
+window, and the pixel height of that line."
+ (let* ((pos0 (save-excursion
+ (goto-char (window-start))
+ (unless (bobp)
+ (beginning-of-visual-line))
+ (point)))
(vscroll0 (window-vscroll nil t))
+ (line-height nil)
(pos
(save-excursion
(goto-char pos0)
(if (bobp)
(point-min)
- ;; When there's an overlay string at window-start,
- ;; (beginning-of-visual-line 0) stays put.
- (let ((ppos (point))
- (tem (beginning-of-visual-line 0)))
- (if (eq tem ppos)
- (vertical-motion -1))
- (point))))))
+ (vertical-motion -1)
+ (setq line-height
+ (cdr (window-text-pixel-size nil (point) pos0)))
+ (point)))))
;; restore initial position
(set-window-start nil pos0 t)
(set-window-vscroll nil vscroll0 t)
- pos))
+ (when (and line-height
+ (> (car (posn-x-y (posn-at-point pos0)))
+ (line-number-display-width t)))
+ (setq line-height (- line-height
+ (save-excursion
+ (goto-char pos0)
+ (line-pixel-height)))))
+ (cons pos line-height)))
+
+(defun pixel-point-at-unseen-line ()
+ "Return the character position of line above the selected window.
+The returned value is the position of the first character on the
+unseen line just above the scope of current window."
+ (car (pixel-point-and-height-at-unseen-line)))
(defun pixel-scroll-down-and-set-window-vscroll (vscroll)
"Scroll down a line and set VSCROLL in pixels.
@@ -354,5 +439,299 @@ Otherwise, redisplay will reset the window's vscroll."
(set-window-start nil (pixel-point-at-unseen-line) t)
(set-window-vscroll nil vscroll t))
+(defun pixel-scroll-precision-scroll-down-page (delta)
+ "Scroll the current window down by DELTA pixels.
+Note that this function doesn't work if DELTA is larger than
+the height of the current window."
+ (let* ((desired-pos (posn-at-x-y 0 (+ delta
+ (window-tab-line-height)
+ (window-header-line-height))))
+ (desired-start (posn-point desired-pos))
+ (current-vs (window-vscroll nil t))
+ (start-posn (unless (eq desired-start (window-start))
+ (posn-at-point desired-start)))
+ (desired-vscroll (if start-posn
+ (- delta (cdr (posn-x-y start-posn)))
+ (+ current-vs delta)))
+ (edges (window-edges nil t))
+ (usable-height (- (nth 3 edges)
+ (nth 1 edges)))
+ (next-pos (save-excursion
+ (goto-char desired-start)
+ (when (zerop (vertical-motion (1+ scroll-margin)))
+ (signal 'end-of-buffer nil))
+ (point)))
+ (scroll-preserve-screen-position nil)
+ (auto-window-vscroll nil))
+ (when (and (or (< (point) next-pos))
+ (let ((pos-visibility (pos-visible-in-window-p next-pos nil t)))
+ (and pos-visibility
+ (or (eq (length pos-visibility) 2)
+ (when-let* ((posn (posn-at-point next-pos)))
+ (> (cdr (posn-object-width-height posn))
+ usable-height))))))
+ (goto-char next-pos))
+ (set-window-start nil (if (zerop (window-hscroll))
+ desired-start
+ (save-excursion
+ (goto-char desired-start)
+ (beginning-of-visual-line)
+ (point)))
+ t)
+ (set-window-vscroll nil desired-vscroll t)))
+
+(defun pixel-scroll-precision-scroll-down (delta)
+ "Scroll the current window down by DELTA pixels."
+ (let ((max-height (- (window-text-height nil t)
+ (frame-char-height))))
+ (while (> delta max-height)
+ (pixel-scroll-precision-scroll-down-page max-height)
+ (setq delta (- delta max-height)))
+ (pixel-scroll-precision-scroll-down-page delta)))
+
+(defun pixel-scroll-precision-scroll-up-page (delta)
+ "Scroll the current window up by DELTA pixels.
+Note that this function doesn't work if DELTA is larger than
+the height of the current window."
+ (let* ((edges (window-edges nil t nil t))
+ (max-y (- (nth 3 edges)
+ (nth 1 edges)))
+ (usable-height max-y)
+ (posn (posn-at-x-y 0 (+ (window-tab-line-height)
+ (window-header-line-height)
+ (- max-y delta))))
+ (point (posn-point posn))
+ (up-point (save-excursion
+ (goto-char point)
+ (vertical-motion (- (1+ scroll-margin)))
+ (point))))
+ (when (> (point) up-point)
+ (when (let ((pos-visible (pos-visible-in-window-p up-point nil t)))
+ (or (eq (length pos-visible) 2)
+ (when-let* ((posn (posn-at-point up-point))
+ (edges (window-edges nil t))
+ (usable-height (- (nth 3 edges)
+ (nth 1 edges))))
+ (> (cdr (posn-object-width-height posn))
+ usable-height))))
+ (goto-char up-point)))
+ (let ((current-vscroll (window-vscroll nil t)))
+ (if (<= delta current-vscroll)
+ (set-window-vscroll nil (- current-vscroll delta) t)
+ (setq delta (- delta current-vscroll))
+ (set-window-vscroll nil 0 t)
+ (while (> delta 0)
+ (let ((position (pixel-point-and-height-at-unseen-line)))
+ (unless (cdr position)
+ (signal 'beginning-of-buffer nil))
+ (set-window-start nil (car position) t)
+ ;; If the line above is taller than the window height (i.e. there's
+ ;; a very tall image), keep point on it.
+ (when (> (cdr position) usable-height)
+ (goto-char (car position)))
+ (setq delta (- delta (cdr position)))))
+ (when (< delta 0)
+ (set-window-vscroll nil (- delta) t))))))
+
+(defun pixel-scroll-precision-interpolate (delta)
+ "Interpolate a scroll of DELTA pixels.
+This results in the window being scrolled by DELTA pixels with an
+animation."
+ (let ((percentage 0)
+ (total-time pixel-scroll-precision-interpolation-total-time)
+ (factor pixel-scroll-precision-interpolation-factor)
+ (last-time (float-time))
+ (time-elapsed 0.0)
+ (between-scroll pixel-scroll-precision-interpolation-between-scroll)
+ (rem (window-parameter nil 'interpolated-scroll-remainder))
+ (time (window-parameter nil 'interpolated-scroll-remainder-time)))
+ (when (and rem time
+ (< (- (float-time) time) 1.0)
+ (eq (< delta 0) (< rem 0)))
+ (setq delta (+ delta rem)))
+ (if (or (null rem)
+ (eq (< delta 0) (< rem 0)))
+ (while-no-input
+ (unwind-protect
+ (while (< percentage 1)
+ (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)))
+ (if (< percentage 1)
+ (progn
+ (set-window-parameter nil 'interpolated-scroll-remainder
+ (* delta (- 1 percentage)))
+ (set-window-parameter nil 'interpolated-scroll-remainder-time
+ (float-time)))
+ (set-window-parameter nil
+ 'interpolated-scroll-remainder
+ nil)
+ (set-window-parameter nil
+ 'interpolated-scroll-remainder-time
+ nil))))
+ (set-window-parameter nil
+ 'interpolated-scroll-remainder
+ nil)
+ (set-window-parameter nil
+ 'interpolated-scroll-remainder-time
+ nil))))
+
+(defun pixel-scroll-precision-scroll-up (delta)
+ "Scroll the current window up by DELTA pixels."
+ (let ((max-height (- (window-text-height nil t)
+ (frame-char-height))))
+ (while (> delta max-height)
+ (pixel-scroll-precision-scroll-up-page max-height)
+ (setq delta (- delta max-height)))
+ (pixel-scroll-precision-scroll-up-page delta)))
+
+;; FIXME: This doesn't _always_ work when there's an image above the
+;; current line that is taller than the window, and scrolling can
+;; sometimes be jumpy in that case.
+(defun pixel-scroll-precision (event)
+ "Scroll the display vertically by pixels according to EVENT.
+Move the display up or down by the pixel deltas in EVENT to
+scroll the display according to the user's turning the mouse
+wheel."
+ (interactive "e")
+ (let ((window (mwheel-event-window event)))
+ (if (and (nth 4 event))
+ (let ((delta (round (cdr (nth 4 event)))))
+ (unless (zerop delta)
+ (if (> (abs delta) (window-text-height window t))
+ (mwheel-scroll event nil)
+ (with-selected-window window
+ (if (and pixel-scroll-precision-large-scroll-height
+ (> (abs delta)
+ pixel-scroll-precision-large-scroll-height)
+ (let* ((kin-state (pixel-scroll-kinetic-state))
+ (ring (aref kin-state 0))
+ (time (aref kin-state 1)))
+ (or (null time)
+ (> (- (float-time) time) 1.0)
+ (and (consp ring)
+ (ring-empty-p ring)))))
+ (progn
+ (let ((kin-state (pixel-scroll-kinetic-state)))
+ (aset kin-state 0 (make-ring 10))
+ (aset kin-state 1 nil))
+ (pixel-scroll-precision-interpolate delta))
+ (condition-case nil
+ (progn
+ (if (< delta 0)
+ (pixel-scroll-precision-scroll-down (- delta))
+ (pixel-scroll-precision-scroll-up delta))
+ (pixel-scroll-accumulate-velocity delta))
+ ;; Do not ding at buffer limits. Show a message instead.
+ (beginning-of-buffer
+ (message (error-message-string '(beginning-of-buffer))))
+ (end-of-buffer
+ (message (error-message-string '(end-of-buffer))))))))))
+ (mwheel-scroll event nil))))
+
+(defun pixel-scroll-kinetic-state ()
+ "Return the kinetic scroll state of the current window.
+It is a vector of the form [ VELOCITY TIME ]."
+ (or (window-parameter nil 'kinetic-state)
+ (set-window-parameter nil 'kinetic-state
+ (vector (make-ring 10) nil))))
+
+(defun pixel-scroll-accumulate-velocity (delta)
+ "Accumulate DELTA into the current window's kinetic scroll state."
+ (let* ((state (pixel-scroll-kinetic-state))
+ (ring (aref state 0))
+ (time (aref state 1)))
+ (when (or (and time (> (- (float-time) time) 0.5))
+ (and (not (ring-empty-p ring))
+ (not (eq (< delta 0)
+ (< (cdr (ring-ref ring 0))
+ 0)))))
+ (aset state 0 (make-ring 10)))
+ (ring-insert (aref state 0)
+ (cons (aset state 1 (float-time))
+ delta))))
+
+(defun pixel-scroll-calculate-velocity (state)
+ "Calculate velocity from the kinetic state vector STATE."
+ (let* ((ring (aref state 0))
+ (elts (ring-elements ring))
+ (total 0))
+ (dolist (tem elts)
+ (setq total (+ total (cdr tem))))
+ (/ total (* (- (float-time) (caar elts))
+ 100))))
+
+(defun pixel-scroll-start-momentum (event)
+ "Start kinetic scrolling for the touch event EVENT."
+ (interactive "e")
+ (when pixel-scroll-precision-use-momentum
+ (let ((window (mwheel-event-window event))
+ (state nil))
+ (with-selected-window window
+ (setq state (pixel-scroll-kinetic-state))
+ (when (and (aref state 1)
+ (listp (aref state 0)))
+ (while-no-input
+ (unwind-protect (progn
+ (aset state 0 (pixel-scroll-calculate-velocity state))
+ (when (> (abs (aref state 0))
+ pixel-scroll-precision-momentum-min-velocity)
+ (let* ((velocity (* (aref state 0)
+ pixel-scroll-precision-initial-velocity-factor))
+ (original-velocity velocity)
+ (time-spent 0))
+ (if (> velocity 0)
+ (while (and (> velocity 0)
+ (<= time-spent
+ pixel-scroll-precision-momentum-seconds))
+ (when (> (round velocity) 0)
+ (pixel-scroll-precision-scroll-up (round velocity)))
+ (setq velocity (- velocity
+ (/ original-velocity
+ (/ pixel-scroll-precision-momentum-seconds
+ pixel-scroll-precision-momentum-tick))))
+ (redisplay t)
+ (sit-for pixel-scroll-precision-momentum-tick)
+ (setq time-spent (+ time-spent
+ pixel-scroll-precision-momentum-tick))))
+ (while (and (< velocity 0)
+ (<= time-spent
+ pixel-scroll-precision-momentum-seconds))
+ (when (> (round (abs velocity)) 0)
+ (pixel-scroll-precision-scroll-down (round
+ (abs velocity))))
+ (setq velocity (+ velocity
+ (/ (abs original-velocity)
+ (/ pixel-scroll-precision-momentum-seconds
+ pixel-scroll-precision-momentum-tick))))
+ (redisplay t)
+ (sit-for pixel-scroll-precision-momentum-tick)
+ (setq time-spent (+ time-spent
+ pixel-scroll-precision-momentum-tick))))))
+ (aset state 0 (make-ring 10))
+ (aset state 1 nil))))))))
+
+;;;###autoload
+(define-minor-mode pixel-scroll-precision-mode
+ "Toggle pixel scrolling.
+When enabled, this minor mode allows to scroll the display
+precisely, according to the turning of the mouse wheel."
+ :global t
+ :group 'mouse
+ :keymap pixel-scroll-precision-mode-map
+ (setq mwheel-coalesce-scroll-events
+ (not pixel-scroll-precision-mode)))
+
(provide 'pixel-scroll)
;;; pixel-scroll.el ends here
diff --git a/lisp/play/5x5.el b/lisp/play/5x5.el
index 3630c199bc4..085c97f5d8e 100644
--- a/lisp/play/5x5.el
+++ b/lisp/play/5x5.el
@@ -315,7 +315,7 @@ Quit current game \\[5x5-quit-game]"
(save-excursion
(goto-char grid-org)
(beginning-of-line (+ 1 (/ 5x5-y-scale 2)))
- (let ((solution-grid (cl-cdadr 5x5-solver-output)))
+ (let ((solution-grid (cdadr 5x5-solver-output)))
(dotimes (y 5x5-grid-size)
(save-excursion
(forward-char (+ 1 (/ (1+ 5x5-x-scale) 2)))
@@ -387,7 +387,7 @@ Mutate the result."
(defun 5x5-crack (breeder)
"Attempt to find a solution for 5x5.
-5x5-crack takes the argument BREEDER which should be a function that takes
+`5x5-crack' takes the argument BREEDER which should be a function that takes
two parameters, the first will be a grid vector array that is the current
solution and the second will be the best solution so far. The function
should return a grid vector array that is the new solution."
@@ -443,8 +443,9 @@ should return a grid vector array that is the new solution."
solution)
(defun 5x5-play-solution (solution best)
- "Play a solution on an empty grid. This destroys the current game
-in progress because it is an animated attempt."
+ "Play a solution on an empty grid.
+This destroys the current game in progress because it is an
+animated attempt."
(5x5-new-game)
(let ((inhibit-quit t))
(dotimes (y 5x5-grid-size)
@@ -473,8 +474,8 @@ position."
grid)))
(defun 5x5-vec-to-grid (grid-matrix)
- "Convert a grid matrix GRID-MATRIX in Calc format to a grid in
-5x5 format. See function `5x5-grid-to-vec'."
+ "Convert a grid matrix GRID-MATRIX in Calc format to a grid in 5x5 format.
+See function `5x5-grid-to-vec'."
(apply
#'vector
(mapcar
@@ -746,9 +747,9 @@ Solutions are sorted from least to greatest Hamming weight."
;; The Hamming Weight is computed by matrix reduction
;; with an ad-hoc operator.
(math-reduce-vec
- ;; (cl-cadadr '(vec (mod x 2))) => x
- (lambda (r x) (+ (if (integerp r) r (cl-cadadr r))
- (cl-cadadr x)))
+ ;; (cadadr '(vec (mod x 2))) => x
+ (lambda (r x) (+ (if (integerp r) r (cadadr r))
+ (cadadr x)))
solution); car
(5x5-vec-to-grid
(calcFunc-arrange solution 5x5-grid-size));cdr
@@ -802,7 +803,7 @@ there are 4 possible solutions. When function
`5x5-solve-suggest' (press `\\[5x5-solve-suggest]') is called the
solution that is presented is the one that needs least number of
strokes --- other solutions can be viewed by rotating through the
-list. The list of solution is ordered by number of strokes, so
+list. The list of solution is ordered by number of strokes, so
rotating left just after calling `5x5-solve-suggest' will show
the solution with second least number of strokes, while rotating
right will show the solution with greatest number of strokes."
diff --git a/lisp/play/animate.el b/lisp/play/animate.el
index 7eb1b277179..54ee9dc84eb 100644
--- a/lisp/play/animate.el
+++ b/lisp/play/animate.el
@@ -93,9 +93,17 @@
(unless (eolp) (delete-char 1))
(insert-char char 1))
-(defcustom animate-n-steps 10
+(defcustom animate-n-steps 20
"Number of steps `animate-string' will place a char before its last position."
- :type 'integer)
+ :type 'natnum
+ :version "29.1")
+
+(defcustom animate-total-added-delay 0.5
+ "Total number of seconds to wait in between steps.
+This is added to the total time it takes to run `animate-string'
+to ensure that the animation is not too fast to be seen."
+ :type 'float
+ :version "29.1")
(defvar animation-buffer-name nil
"String naming the default buffer for animations.
@@ -130,7 +138,7 @@ in the current window."
;; Make sure buffer is displayed starting at the beginning.
(set-window-start nil 1)
;; Display it, and wait just a little while.
- (sit-for .05)
+ (sit-for (/ (float animate-total-added-delay) (max animate-n-steps 1)))
;; Now undo the changes we made in the buffer.
(setq list-to-undo buffer-undo-list)
(while list-to-undo
diff --git a/lisp/play/cookie1.el b/lisp/play/cookie1.el
index be35daf4da8..d1bf45ed510 100644
--- a/lisp/play/cookie1.el
+++ b/lisp/play/cookie1.el
@@ -110,7 +110,7 @@ of load, ENDMSG at the end."
(fill-region-as-paragraph start (point) nil))))
(defun cookie1 (arg cookie-vec)
- "Inserts a cookie phrase ARG times."
+ "Insert a cookie phrase ARG times."
(cond ((zerop arg) t)
(t (insert (aref cookie-vec arg))
(insert " ")
@@ -118,8 +118,8 @@ of load, ENDMSG at the end."
;;;###autoload
(defun cookie-snarf (phrase-file &optional startmsg endmsg)
- "Reads in the PHRASE-FILE, returns it as a vector of strings.
-Emit STARTMSG and ENDMSG before and after. Caches the result; second
+ "Read the PHRASE-FILE, return it as a vector of strings.
+Emit STARTMSG and ENDMSG before and after. Cache the result; second
and subsequent calls on the same file won't go to disk."
(setq phrase-file (cookie-check-file phrase-file))
(let ((sym (intern-soft phrase-file cookie-cache)))
diff --git a/lisp/play/decipher.el b/lisp/play/decipher.el
index 47ed6e28b58..5431d7f068a 100644
--- a/lisp/play/decipher.el
+++ b/lisp/play/decipher.el
@@ -177,7 +177,7 @@ the tail of the list."
(modify-syntax-entry c "_" table) ;Digits are not part of words
(cl-incf c))
table)
- "Decipher mode syntax table")
+ "Decipher mode syntax table.")
(defvar-local decipher-alphabet nil)
;; This is an alist containing entries (PLAIN-CHAR . CIPHER-CHAR),
@@ -769,8 +769,8 @@ TOTAL is the total number of letters in the ciphertext."
(while temp-list
(insert (caar temp-list)
(format "%4d%3d%% "
- (cl-cadar temp-list)
- (floor (* 100.0 (cl-cadar temp-list)) total)))
+ (cadar temp-list)
+ (floor (* 100.0 (cadar temp-list)) total)))
(setq temp-list (nthcdr 4 temp-list)))
(insert ?\n)
(setq freq-list (cdr freq-list)
diff --git a/lisp/play/doctor.el b/lisp/play/doctor.el
index bf923f4f2e5..33fecaa188a 100644
--- a/lisp/play/doctor.el
+++ b/lisp/play/doctor.el
@@ -115,7 +115,7 @@
(defun doc// (x) x)
(defmacro doc$ (what)
- "Quoted arg form of doctor-$."
+ "Quoted arg form of `doctor-$'."
`(doctor-$ ',what))
(defun doctor-$ (what)
@@ -137,6 +137,7 @@
Like Text mode with Auto Fill mode
except that RET when point is after a newline, or LFD at any time,
reads the sentence before point, and prints the Doctor's answer."
+ :interactive nil
(make-doctor-variables)
(turn-on-auto-fill)
(doctor-type '(i am the psychotherapist \.
@@ -827,14 +828,14 @@ reads the sentence before point, and prints the Doctor's answer."
(defun doctor-ret-or-read (arg)
"Insert a newline if preceding character is not a newline.
Otherwise call the Doctor to parse preceding sentence."
- (interactive "*p")
+ (interactive "*p" doctor-mode)
(if (= (preceding-char) ?\n)
(doctor-read-print)
(newline arg)))
(defun doctor-read-print ()
"Top level loop."
- (interactive)
+ (interactive nil doctor-mode)
(setq doctor-sent (doctor-readin))
(insert "\n")
(setq doctor--lincount (1+ doctor--lincount))
@@ -1010,8 +1011,8 @@ Put dialogue in buffer."
(defun doctor-subjsearch (sent key type)
"Search for the subject of a sentence SENT, looking for the noun closest
-to and preceding KEY by at least TYPE words. Set global variable doctor-subj to
-the subject noun, and return the portion of the sentence following it."
+to and preceding KEY by at least TYPE words. Set global variable `doctor-subj'
+to the subject noun, and return the portion of the sentence following it."
(let ((i (- (length sent) (length (memq key sent)) type)))
(while (and (> i -1) (not (doctor-nounp (nth i sent))))
(setq i (1- i)))
diff --git a/lisp/play/dunnet.el b/lisp/play/dunnet.el
index 9d5ee261976..706c1be81e0 100644
--- a/lisp/play/dunnet.el
+++ b/lisp/play/dunnet.el
@@ -944,8 +944,8 @@ handled specially by 'dun-describe-room.")
(list obj-pc) ;; pc-area
nil nil nil nil nil nil
)
- "These are objects in a room that are only described in the
-room description. They are permanent.")
+ "These are objects in a room that are only described in the room description.
+They are permanent.")
(defvar dun-inventory '(1))
(defconst dun-objects
@@ -1010,8 +1010,7 @@ the inventory.")
nil nil
("There is a bus here.")
nil nil nil)
- "These are the descriptions for the negative numbered objects from
-`dun-room-objects'.")
+ "Descriptions for the negative numbered objects from `dun-room-objects'.")
(defconst dun-physobj-desc '(
@@ -1135,11 +1134,12 @@ treasures for points?" "4" "four")
(define-derived-mode dun-mode text-mode "Dungeon"
"Major mode for running dunnet."
+ :interactive nil
(setq-local scroll-step 2))
(defun dun-parse (_arg)
"Function called when return is pressed in interactive mode to parse line."
- (interactive "*p")
+ (interactive "*p" dun-mode)
(beginning-of-line)
(let ((beg (1+ (point)))
line)
@@ -1215,8 +1215,9 @@ Otherwise short. Also give long if we were called with negative room number."
(dun-mprincl "You are on the bus."))))
(defun dun-special-object ()
- "There is a special object in the room. This object's description,
-or lack thereof, depends on certain conditions."
+ "There is a special object in the room.
+This object's description, or lack thereof, depends on certain
+conditions."
(cond
((= dun-current-room computer-room)
(if dun-computer
@@ -2229,7 +2230,7 @@ Call the proper verb with the rest of the line passed in as a list."
(defun dun-fix-screen ()
"In window mode, keep screen from jumping by keeping last line at
the bottom of the screen."
- (interactive)
+ (interactive nil dun-mode)
(forward-line (- 0 (- (window-height) 2 )))
(set-window-start (selected-window) (point))
(goto-char (point-max)))
@@ -2263,7 +2264,7 @@ except for the verb."
result)))
(defun dun-get-path (dirstring startlist)
- "Given a unix style pathname, build a list of path components (recursive)"
+ "Given a unix style pathname, build a list of path components (recursive)."
(let (slash)
(if (= (length dirstring) 0)
startlist
@@ -2336,7 +2337,7 @@ Also prints current score to let user know he has scored."
;;;;
(defun dun-unix-parse (_args)
- (interactive "*p")
+ (interactive "*p" dun-mode)
(beginning-of-line)
(let (beg esign)
(setq beg (+ (point) 2))
@@ -2825,7 +2826,7 @@ drwxr-xr-x 3 root staff 2048 Jan 1 1970 ..")
;;;;
(defun dun-dos-parse (_args)
- (interactive "*p")
+ (interactive "*p" dun-mode)
(beginning-of-line)
(let (beg)
(setq beg (+ (point) 3))
@@ -3119,7 +3120,7 @@ File not found")))
(defun dungeon-nil (_arg)
"noop"
- (interactive "*p")
+ (interactive "*p" dun-mode)
nil)
(defun dun-batch-dungeon ()
diff --git a/lisp/play/fortune.el b/lisp/play/fortune.el
index fb02edffe73..f13302525b3 100644
--- a/lisp/play/fortune.el
+++ b/lisp/play/fortune.el
@@ -142,7 +142,7 @@ No need to add an `in'."
;;; **************
;;; Inserting a new fortune
(defun fortune-append (string &optional interactive file)
- "Appends STRING to the fortune FILE.
+ "Append STRING to the fortune FILE.
If INTERACTIVE is non-nil, don't compile the fortune file afterwards."
(setq file (expand-file-name
diff --git a/lisp/play/gamegrid.el b/lisp/play/gamegrid.el
index 8b64dfdf9b5..49a0c9ee02b 100644
--- a/lisp/play/gamegrid.el
+++ b/lisp/play/gamegrid.el
@@ -490,7 +490,7 @@ format."
"Add the current score to the high score file.
If REVERSE is non-nil, treat lower scores as better than higher
-scores. This is useful for games where lower scores are better.
+scores. This is useful for games where lower scores are better.
On POSIX systems there may be a shared game directory for all users in
which the scorefiles are kept. On such systems Emacs doesn't create
diff --git a/lisp/play/gametree.el b/lisp/play/gametree.el
index c6aef027e5f..cc9a6b7a4f0 100644
--- a/lisp/play/gametree.el
+++ b/lisp/play/gametree.el
@@ -508,7 +508,7 @@ being entered automatically (and thus should lack the manual mark)."
(insert (int-to-string (prefix-numeric-value score))))))
(defun gametree-compute-and-insert-score ()
- "Compute current node score, maybe recursively from subnodes. Insert it.
+ "Compute current node score, maybe recursively from subnodes. Insert it.
Subnodes which have been manually scored are honored."
(interactive "*")
(let ((auto (not (and (looking-at gametree-score-regexp)
diff --git a/lisp/play/handwrite.el b/lisp/play/handwrite.el
index 2aec408e11b..d59352c3529 100644
--- a/lisp/play/handwrite.el
+++ b/lisp/play/handwrite.el
@@ -139,7 +139,7 @@
;;;###autoload
(defun handwrite ()
- "Turns the buffer into a \"handwritten\" document.
+ "Turn the buffer into a \"handwritten\" document.
The functions `handwrite-10pt', `handwrite-11pt', `handwrite-12pt'
and `handwrite-13pt' set up for various sizes of output.
diff --git a/lisp/play/hanoi.el b/lisp/play/hanoi.el
index ac28fba10a4..227dd790af5 100644
--- a/lisp/play/hanoi.el
+++ b/lisp/play/hanoi.el
@@ -70,7 +70,7 @@
:group 'games)
(defcustom hanoi-horizontal-flag nil
- "If non-nil, hanoi poles are oriented horizontally."
+ "Non-nil means that hanoi poles are oriented horizontally."
:type 'boolean)
(defcustom hanoi-move-period 1.0
@@ -131,9 +131,9 @@ Repent before ring 31 moves."
;;;###autoload
(defun hanoi-unix-64 ()
- "Like hanoi-unix, but pretend to have a 64-bit clock.
+ "Like `hanoi-unix', but pretend to have a 64-bit clock.
This is, necessarily (as of Emacs 20.3), a crock. When the
-current-time interface is made s2G-compliant, hanoi.el will need
+`current-time' interface is made s2G-compliant, hanoi.el will need
to be updated."
(interactive)
(let* ((start (ftruncate (float-time)))
@@ -284,7 +284,7 @@ BITS must be of length nrings. Start at START-TIME."
(force-mode-line-update)))
(defun hanoi-put-face (start end value &optional object)
- "If hanoi-use-faces is non-nil, call put-text-property for face property."
+ "If `hanoi-use-faces' is non-nil, call `put-text-property' for face property."
(if hanoi-use-faces
(put-text-property start end 'face value object)))
diff --git a/lisp/play/life.el b/lisp/play/life.el
index 2abf8ccb74b..2bf72927723 100644
--- a/lisp/play/life.el
+++ b/lisp/play/life.el
@@ -136,10 +136,10 @@
(defvar life-window-start nil)
(defvar life--max-width nil
- "If non-nil, restrict width to this positive integer. ")
+ "If non-nil, restrict width to this positive integer.")
(defvar life--max-height nil
- "If non-nil, restrict height to this positive integer. ")
+ "If non-nil, restrict height to this positive integer.")
;; For mode line
(defvar life-current-generation nil)
diff --git a/lisp/play/mpuz.el b/lisp/play/mpuz.el
index 838bddfb665..df2b6fc867a 100644
--- a/lisp/play/mpuz.el
+++ b/lisp/play/mpuz.el
@@ -89,6 +89,7 @@ The value t means never ding, and `error' means only ding on wrong input."
(define-derived-mode mpuz-mode fundamental-mode "Mult Puzzle"
+ :interactive nil
"Multiplication puzzle mode.
You have to guess which letters stand for which digits in the
@@ -98,7 +99,7 @@ You may enter a guess for a letter's value by typing first the letter,
then the digit. Thus, to guess that A=3, type `A 3'.
To leave the game to do other editing work, just switch buffers.
-Then you may resume the game with M-x mpuz.
+Then you may resume the game with \\[mpuz].
You may abort a game by typing \\<mpuz-mode-map>\\[mpuz-offer-abort]."
(setq tab-width 30))
@@ -118,7 +119,7 @@ You may abort a game by typing \\<mpuz-mode-map>\\[mpuz-offer-abort]."
;; Some variables for game tracking
;;---------------------------------
(defvar mpuz-in-progress nil
- "True if a game is currently in progress.")
+ "Non-nil if a game is currently in progress.")
(defvar mpuz-found-digits (make-bool-vector 10 nil)
"A vector recording which digits have been decrypted.")
@@ -152,7 +153,7 @@ You may abort a game by typing \\<mpuz-mode-map>\\[mpuz-offer-abort]."
(index 10)
elem)
(while letters
- (setq elem (nth (random index) letters)
+ (setq elem (seq-random-elt letters)
letters (delq elem letters)
index (1- index))
(aset mpuz-digit-to-letter index elem)
@@ -367,7 +368,7 @@ You may abort a game by typing \\<mpuz-mode-map>\\[mpuz-offer-abort]."
(defun mpuz-offer-abort ()
"Ask if user wants to abort current puzzle."
- (interactive)
+ (interactive nil mpuz-mode)
(if (y-or-n-p "Abort game? ")
(let ((buf (mpuz-get-buffer)))
(message "Mult Puzzle aborted.")
@@ -389,7 +390,7 @@ You may abort a game by typing \\<mpuz-mode-map>\\[mpuz-offer-abort]."
(defun mpuz-try-letter ()
"Propose a digit for a letter in puzzle."
- (interactive)
+ (interactive nil mpuz-mode)
(if mpuz-in-progress
(let (letter-char digit digit-char)
(setq letter-char (upcase last-command-event)
@@ -474,7 +475,7 @@ You may abort a game by typing \\<mpuz-mode-map>\\[mpuz-offer-abort]."
(defun mpuz-show-solution (row)
"Display solution for debugging purposes."
- (interactive "P")
+ (interactive "P" mpuz-mode)
(mpuz-switch-to-window)
(mpuz-solve (if row (* 2 (prefix-numeric-value row))))
(mpuz-paint-board)
diff --git a/lisp/play/pong.el b/lisp/play/pong.el
index b73dbc1010e..b8545dfa82f 100644
--- a/lisp/play/pong.el
+++ b/lisp/play/pong.el
@@ -216,7 +216,6 @@
(defun pong-init-buffer ()
"Initialize pong buffer and draw stuff thanks to gamegrid library."
- (interactive)
(get-buffer-create pong-buffer-name)
(switch-to-buffer pong-buffer-name)
(use-local-map pong-mode-map)
@@ -249,7 +248,7 @@
"Move bat 1 up.
This is called left for historical reasons, since in some pong
implementations you move with left/right paddle."
- (interactive)
+ (interactive nil pong-mode)
(if (> pong-bat-player1 1)
(and
(setq pong-bat-player1 (1- pong-bat-player1))
@@ -259,7 +258,7 @@ implementations you move with left/right paddle."
(defun pong-move-right ()
"Move bat 1 down."
- (interactive)
+ (interactive nil pong-mode)
(if (< (+ pong-bat-player1 pong-bat-width) (1- pong-height))
(and
(setq pong-bat-player1 (1+ pong-bat-player1))
@@ -269,7 +268,7 @@ implementations you move with left/right paddle."
(defun pong-move-up ()
"Move bat 2 up."
- (interactive)
+ (interactive nil pong-mode)
(if (> pong-bat-player2 1)
(and
(setq pong-bat-player2 (1- pong-bat-player2))
@@ -279,7 +278,7 @@ implementations you move with left/right paddle."
(defun pong-move-down ()
"Move bat 2 down."
- (interactive)
+ (interactive nil pong-mode)
(if (< (+ pong-bat-player2 pong-bat-width) (1- pong-height))
(and
(setq pong-bat-player2 (1+ pong-bat-player2))
@@ -412,7 +411,7 @@ detection and checks if a player scores."
(defun pong-pause ()
"Pause the game."
- (interactive)
+ (interactive nil pong-mode)
(gamegrid-kill-timer)
;; Oooohhh ugly. I don't know why, gamegrid-kill-timer don't do the
;; jobs it is made for. So I have to do it "by hand". Anyway, next
@@ -424,7 +423,7 @@ detection and checks if a player scores."
(defun pong-resume ()
"Resume a paused game."
- (interactive)
+ (interactive nil pong-mode)
(define-key pong-mode-map pong-pause-key 'pong-pause)
(gamegrid-start-timer pong-timer-delay 'pong-update-game))
@@ -432,7 +431,7 @@ detection and checks if a player scores."
(defun pong-quit ()
"Quit the game and kill the pong buffer."
- (interactive)
+ (interactive nil pong-mode)
(gamegrid-kill-timer)
;; Be sure not to draw things in another buffer and wait for some
;; time.
diff --git a/lisp/play/snake.el b/lisp/play/snake.el
index 29effa23460..dbdecde973d 100644
--- a/lisp/play/snake.el
+++ b/lisp/play/snake.el
@@ -160,31 +160,28 @@ and then start moving it leftwards.")
;; ;;;;;;;;;;;;; keymaps ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defvar snake-mode-map
- (let ((map (make-sparse-keymap 'snake-mode-map)))
-
- (define-key map "n" 'snake-start-game)
- (define-key map "q" 'snake-end-game)
- (define-key map "p" 'snake-pause-game)
-
- (define-key map [left] 'snake-move-left)
- (define-key map [right] 'snake-move-right)
- (define-key map [up] 'snake-move-up)
- (define-key map [down] 'snake-move-down)
-
- (define-key map "\C-b" 'snake-move-left)
- (define-key map "\C-f" 'snake-move-right)
- (define-key map "\C-p" 'snake-move-up)
- (define-key map "\C-n" 'snake-move-down)
- map)
- "Keymap for Snake games.")
-
-(defvar snake-null-map
- (let ((map (make-sparse-keymap 'snake-null-map)))
- (define-key map "n" 'snake-start-game)
- (define-key map "q" 'quit-window)
- map)
- "Keymap for finished Snake games.")
+(defvar-keymap snake-mode-map
+ :doc "Keymap for Snake games."
+ :name 'snake-mode-map
+ "n" #'snake-start-game
+ "q" #'snake-end-game
+ "p" #'snake-pause-game
+
+ "<left>" #'snake-move-left
+ "<right>" #'snake-move-right
+ "<up>" #'snake-move-up
+ "<down>" #'snake-move-down
+
+ "C-b" #'snake-move-left
+ "C-f" #'snake-move-right
+ "C-p" #'snake-move-up
+ "C-n" #'snake-move-down)
+
+(defvar-keymap snake-null-map
+ :doc "Keymap for finished Snake games."
+ :name 'snake-null-map
+ "n" #'snake-start-game
+ "q" #'quit-window)
(defconst snake--menu-def
'("Snake"
diff --git a/lisp/play/solitaire.el b/lisp/play/solitaire.el
index e74ba98ca1b..bc1a0e44cbf 100644
--- a/lisp/play/solitaire.el
+++ b/lisp/play/solitaire.el
@@ -93,6 +93,7 @@ To learn how to play Solitaire, see the documentation for function
\\<solitaire-mode-map>
The usual mnemonic keys move the cursor around the board; in addition,
\\[solitaire-move] is a prefix character for actually moving a stone on the board."
+ :interactive nil
(setq truncate-lines t)
(setq show-trailing-whitespace nil))
@@ -248,7 +249,7 @@ Pick your favorite shortcuts:
(setq solitaire-end-y (solitaire-current-line))))
(defun solitaire-right ()
- (interactive)
+ (interactive nil solitaire-mode)
(let ((start (point)))
(forward-char)
(while (= ?\s (following-char))
@@ -259,7 +260,7 @@ Pick your favorite shortcuts:
(goto-char start))))
(defun solitaire-left ()
- (interactive)
+ (interactive nil solitaire-mode)
(let ((start (point)))
(backward-char)
(while (= ?\s (following-char))
@@ -270,7 +271,7 @@ Pick your favorite shortcuts:
(goto-char start))))
(defun solitaire-up ()
- (interactive)
+ (interactive nil solitaire-mode)
(let ((start (point))
(c (current-column)))
(forward-line -1)
@@ -286,7 +287,7 @@ Pick your favorite shortcuts:
(goto-char start))))
(defun solitaire-down ()
- (interactive)
+ (interactive nil solitaire-mode)
(let ((start (point))
(c (current-column)))
(forward-line 1)
@@ -301,13 +302,13 @@ Pick your favorite shortcuts:
(goto-char start))))
(defun solitaire-center-point ()
- (interactive)
+ (interactive nil solitaire-mode)
(goto-char solitaire-center))
-(defun solitaire-move-right () (interactive) (solitaire-move '[right]))
-(defun solitaire-move-left () (interactive) (solitaire-move '[left]))
-(defun solitaire-move-up () (interactive) (solitaire-move '[up]))
-(defun solitaire-move-down () (interactive) (solitaire-move '[down]))
+(defun solitaire-move-right () (interactive nil solitaire-mode) (solitaire-move '[right]))
+(defun solitaire-move-left () (interactive nil solitaire-mode) (solitaire-move '[left]))
+(defun solitaire-move-up () (interactive nil solitaire-mode) (solitaire-move '[up]))
+(defun solitaire-move-down () (interactive nil solitaire-mode) (solitaire-move '[down]))
(defun solitaire-possible-move (movesymbol)
"Check if a move is possible from current point in the specified direction.
@@ -332,7 +333,7 @@ which a stone will be taken away) and target."
(defun solitaire-move (dir)
"Pseudo-prefix command to move a stone in Solitaire."
- (interactive "kMove where? ")
+ (interactive "kMove where? " solitaire-mode)
(let* ((class (solitaire-possible-move (lookup-key solitaire-mode-map dir)))
(buffer-read-only nil))
(if (stringp class)
@@ -356,7 +357,7 @@ which a stone will be taken away) and target."
(defun solitaire-undo (arg)
"Undo a move in Solitaire."
- (interactive "P")
+ (interactive "P" solitaire-mode)
(let ((buffer-read-only nil))
(undo arg))
(save-excursion
@@ -393,7 +394,7 @@ which a stone will be taken away) and target."
(defun solitaire-do-check (&optional _arg)
"Check for any possible moves in Solitaire."
- (interactive "P")
+ (interactive "P" solitaire-mode)
(let ((moves (solitaire-check)))
(cond ((= 1 solitaire-stones)
(message "Yeah! You made it! Only the King is left!"))
@@ -414,7 +415,7 @@ Seen in info on text lines."
(defun solitaire-solve ()
"Spoil Solitaire by solving the game for you - nearly ...
... stops with five stones left ;)"
- (interactive)
+ (interactive nil solitaire-mode)
(when (< solitaire-stones 32)
(error "Cannot solve game in progress"))
(let ((allmoves [up up S-down up left left S-right up up left S-down
diff --git a/lisp/play/spook.el b/lisp/play/spook.el
index d0669eb1f46..69f444994f5 100644
--- a/lisp/play/spook.el
+++ b/lisp/play/spook.el
@@ -53,7 +53,7 @@
;;;###autoload
(defun spook ()
- "Adds that special touch of class to your outgoing mail."
+ "Add that special touch of class to your outgoing mail."
(interactive)
(cookie-insert spook-phrases-file
spook-phrase-default-count
diff --git a/lisp/play/tetris.el b/lisp/play/tetris.el
index f43aa47326f..693bfe49354 100644
--- a/lisp/play/tetris.el
+++ b/lisp/play/tetris.el
@@ -236,26 +236,24 @@ each one of its four blocks.")
;; ;;;;;;;;;;;;; keymaps ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defvar tetris-mode-map
- (let ((map (make-sparse-keymap 'tetris-mode-map)))
- (define-key map "n" 'tetris-start-game)
- (define-key map "q" 'tetris-end-game)
- (define-key map "p" 'tetris-pause-game)
-
- (define-key map " " 'tetris-move-bottom)
- (define-key map [left] 'tetris-move-left)
- (define-key map [right] 'tetris-move-right)
- (define-key map [up] 'tetris-rotate-prev)
- (define-key map [down] 'tetris-move-down)
- map)
- "Keymap for Tetris games.")
-
-(defvar tetris-null-map
- (let ((map (make-sparse-keymap 'tetris-null-map)))
- (define-key map "n" 'tetris-start-game)
- (define-key map "q" 'quit-window)
- map)
- "Keymap for finished Tetris games.")
+(defvar-keymap tetris-mode-map
+ :doc "Keymap for Tetris games."
+ :name 'tetris-mode-map
+ "n" #'tetris-start-game
+ "q" #'tetris-end-game
+ "p" #'tetris-pause-game
+
+ "SPC" #'tetris-move-bottom
+ "<left>" #'tetris-move-left
+ "<right>" #'tetris-move-right
+ "<up>" #'tetris-rotate-prev
+ "<down>" #'tetris-move-down)
+
+(defvar-keymap tetris-null-map
+ :doc "Keymap for finished Tetris games."
+ :name 'tetris-null-map
+ "n" #'tetris-start-game
+ "q" #'quit-window)
(defconst tetris--menu-def
'("Tetris"
@@ -620,7 +618,7 @@ Shapes drop from the top of the screen, and the user has to move and
rotate the shape to fit in with those at the bottom of the screen so
as to form complete rows.
-tetris-mode keybindings:
+`tetris-mode' keybindings:
\\<tetris-mode-map>
\\[tetris-start-game] Start a new game of Tetris
\\[tetris-end-game] Terminate the current game
diff --git a/lisp/play/zone.el b/lisp/play/zone.el
index 19e4e399ff3..a5d4ac9dc66 100644
--- a/lisp/play/zone.el
+++ b/lisp/play/zone.el
@@ -99,7 +99,7 @@ If the element is a function or a list of a function and a number,
(functionp (car elem))
(numberp (cadr elem)))
(apply 'zone-call elem))
- (t (error "bad `zone-call' elem: %S" elem))))
+ (t (error "Bad `zone-call' elem: %S" elem))))
program))))
;;;###autoload
@@ -596,7 +596,7 @@ If the element is a function or a list of a function and a number,
(forward-line -1)
(delete-region (point) (line-beginning-position 2))
(goto-char (point-min))
- (insert (nth (random (length lines)) lines)))
+ (insert (seq-random-elt lines)))
(message (concat (make-string (random (- (frame-width) 5)) ? ) "grrr"))
(sit-for 0.1)))))
diff --git a/lisp/plstore.el b/lisp/plstore.el
index 4ca5886bf15..bcca637e00a 100644
--- a/lisp/plstore.el
+++ b/lisp/plstore.el
@@ -83,7 +83,7 @@
(require 'epg)
(defgroup plstore nil
- "Searchable, partially encrypted, persistent plist store"
+ "Searchable, partially encrypted, persistent plist store."
:version "24.1"
:group 'files)
diff --git a/lisp/printing.el b/lisp/printing.el
index e7aab901d53..dfa5a6ef761 100644
--- a/lisp/printing.el
+++ b/lisp/printing.el
@@ -5,7 +5,7 @@
;; Author: Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>
;; Keywords: wp, print, PostScript
;; Version: 6.9.3
-;; X-URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
+;; URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
(defconst pr-version "6.9.3"
"printing.el, v 6.9.3 <2007/12/09 vinicius>
@@ -1403,7 +1403,7 @@ The printer name symbol should be defined on `pr-txt-printer-alist' (see it for
documentation).
This variable should be modified by customization engine. If this variable is
-modified by other means (for example, a lisp function), use `pr-update-menus'
+modified by other means (for example, a Lisp function), use `pr-update-menus'
function (see it for documentation) to update text printer menu."
:type 'symbol
:set 'pr-txt-name-custom-set)
@@ -1489,7 +1489,7 @@ NAME A string that specifies a text printer name.
\"share-name\"
This variable should be modified by customization engine. If this variable is
-modified by other means (for example, a lisp function), use `pr-update-menus'
+modified by other means (for example, a Lisp function), use `pr-update-menus'
function (see it for documentation) to update text printer menu.
Examples:
@@ -1544,7 +1544,7 @@ This printer name symbol should be defined on `pr-ps-printer-alist' (see it for
documentation).
This variable should be modified by customization engine. If this variable is
-modified by other means (for example, a lisp function), use `pr-update-menus'
+modified by other means (for example, a Lisp function), use `pr-update-menus'
function (see it for documentation) to update PostScript printer menu."
:type 'symbol
:set 'pr-ps-name-custom-set)
@@ -1672,7 +1672,7 @@ DEFAULT It's a way to set default values when this entry is selected.
(set VARIABLE (eval VALUE))
- Note that VALUE can be any valid lisp expression. So, don't
+ Note that VALUE can be any valid Lisp expression. So, don't
forget to quote symbols and constant lists.
If VARIABLE is the special keyword `inherits-from:', VALUE must
be a symbol name setting defined in `pr-setting-database' from
@@ -1772,8 +1772,7 @@ Useful links:
`https://linux.die.net/man/1/lp'
* GNU utilities for w32 (cp.exe)
- `http://unxutils.sourceforge.net/'
-"
+ `http://unxutils.sourceforge.net/'"
:type '(repeat
(list
:tag "PostScript Printer"
@@ -2181,7 +2180,7 @@ DEFAULT It's a way to set default values when this entry is selected.
(set (make-local-variable VARIABLE-SYM) (eval VALUE))
- Note that VALUE can be any valid lisp expression. So, don't
+ Note that VALUE can be any valid Lisp expression. So, don't
forget to quote symbols and constant lists.
If VARIABLE is the special keyword `inherits-from:', VALUE must
be a symbol name setting defined in `pr-setting-database' from
@@ -2246,7 +2245,7 @@ This utility symbol should be defined on `pr-ps-utility-alist' (see it for
documentation).
This variable should be modified by customization engine. If this variable is
-modified by other means (for example, a lisp function), use `pr-update-menus'
+modified by other means (for example, a Lisp function), use `pr-update-menus'
function (see it for documentation) to update PostScript utility menu.
NOTE: Don't forget to download and install the utilities declared on
@@ -2413,8 +2412,7 @@ Useful links:
* GNU Enscript documentation (Windows, GNU or Unix)
`https://people.ssh.com/mtr/genscript/enscript.man.html'
- (on GNU or Unix, type `man enscript')
-"
+ (on GNU or Unix, type `man enscript')"
:type '(repeat
(list :tag "PS File Utility"
(symbol :tag "Utility Symbol")
@@ -2560,7 +2558,7 @@ SETTING It's a cons like:
* If LOCAL is nil:
(set VARIABLE (eval VALUE))
- Note that VALUE can be any valid lisp expression. So, don't
+ Note that VALUE can be any valid Lisp expression. So, don't
forget to quote symbols and constant lists.
This setting is ignored if VARIABLE is equal to keyword
`inherits-from:'.
@@ -2672,7 +2670,7 @@ happens when printing:
"Non-nil means list directory when processing a directory.
That is, any subdirectories (and the superdirectory) of the directory (given as
-argument of functions below) are also printed (as dired-mode listings).
+argument of functions below) are also printed (as `dired-mode' listings).
It's used by `pr-ps-directory-preview', `pr-ps-directory-using-ghostscript',
`pr-ps-directory-print', `pr-ps-directory-ps-print', `pr-printify-directory'
@@ -3476,7 +3474,7 @@ For more information, type \\[pr-interface-help]."
"Preview directory using ghostview.
Interactively, the command prompts for N-UP printing number, a directory, a
-file name regexp for matching and, when you use a prefix argument (C-u), the
+file name regexp for matching and, when you use a prefix argument (\\[universal-argument]), the
command prompts the user for a file name, and saves the PostScript image in
that file instead of saving it in a temporary file.
@@ -3505,7 +3503,7 @@ See also documentation for `pr-list-directory'."
"Print directory using PostScript through ghostscript.
Interactively, the command prompts for N-UP printing number, a directory, a
-file name regexp for matching and, when you use a prefix argument (C-u), the
+file name regexp for matching and, when you use a prefix argument (\\[universal-argument]), the
command prompts the user for a file name, and saves the PostScript image in
that file instead of saving it in a temporary file.
@@ -3535,7 +3533,7 @@ See also documentation for `pr-list-directory'."
"Print directory using PostScript printer.
Interactively, the command prompts for N-UP printing number, a directory, a
-file name regexp for matching and, when you use a prefix argument (C-u), the
+file name regexp for matching and, when you use a prefix argument (\\[universal-argument]), the
command prompts the user for a file name, and saves the PostScript image in
that file instead of saving it in a temporary file.
@@ -3567,7 +3565,7 @@ See also documentation for `pr-list-directory'."
It depends on `pr-print-using-ghostscript'.
Interactively, the command prompts for N-UP printing number, a directory, a
-file name regexp for matching and, when you use a prefix argument (C-u), the
+file name regexp for matching and, when you use a prefix argument (\\[universal-argument]), the
command prompts the user for a file name, and saves the PostScript image in
that file instead of saving it in a temporary file.
@@ -3598,7 +3596,7 @@ See also documentation for `pr-list-directory'."
"Preview buffer using ghostview.
Interactively, the command prompts for N-UP printing number and, when you use a
-prefix argument (C-u), the command prompts the user for a file name, and saves
+prefix argument (\\[universal-argument]), the command prompts the user for a file name, and saves
the PostScript image in that file instead of saving it in a temporary file.
Noninteractively, if N-UP is nil, prompts for N-UP printing number. The
@@ -3617,7 +3615,7 @@ with that name. If FILENAME is t, prompts for a file name."
"Print buffer using PostScript through ghostscript.
Interactively, the command prompts for N-UP printing number and, when you use a
-prefix argument (C-u), the command prompts the user for a file name, and saves
+prefix argument (\\[universal-argument]), the command prompts the user for a file name, and saves
the PostScript image in that file instead of sending it to the printer.
Noninteractively, if N-UP is nil, prompts for N-UP printing number. The
@@ -3636,7 +3634,7 @@ that name. If FILENAME is t, prompts for a file name."
"Print buffer using PostScript printer.
Interactively, the command prompts for N-UP printing number and, when you use a
-prefix argument (C-u), the command prompts the user for a file name, and saves
+prefix argument (\\[universal-argument]), the command prompts the user for a file name, and saves
the PostScript image in that file instead of sending it to the printer.
Noninteractively, if N-UP is nil, prompts for N-UP printing number. The
@@ -3657,7 +3655,7 @@ that name. If FILENAME is t, prompts for a file name."
It depends on `pr-print-using-ghostscript'.
Interactively, the command prompts for N-UP printing number and, when you use a
-prefix argument (C-u), the command prompts the user for a file name, and saves
+prefix argument (\\[universal-argument]), the command prompts the user for a file name, and saves
the PostScript image in that file instead of sending it to the printer.
Noninteractively, if N-UP is nil, prompts for N-UP printing number. The
@@ -3877,7 +3875,7 @@ See also documentation for `pr-list-directory'."
(defun pr-despool-preview (&optional filename)
"Preview spooled PostScript.
-Interactively, when you use a prefix argument (C-u), the command prompts the
+Interactively, when you use a prefix argument (\\[universal-argument]), the command prompts the
user for a file name, and saves the spooled PostScript image in that file
instead of saving it in a temporary file.
@@ -3895,7 +3893,7 @@ PostScript image in a file with that name."
(defun pr-despool-using-ghostscript (&optional filename)
"Print spooled PostScript using ghostscript.
-Interactively, when you use a prefix argument (C-u), the command prompts the
+Interactively, when you use a prefix argument (\\[universal-argument]), the command prompts the
user for a file name, and saves the spooled PostScript image in that file
instead of sending it to the printer.
@@ -3914,7 +3912,7 @@ image in a file with that name."
(defun pr-despool-print (&optional filename)
"Send the spooled PostScript to the printer.
-Interactively, when you use a prefix argument (C-u), the command prompts the
+Interactively, when you use a prefix argument (\\[universal-argument]), the command prompts the
user for a file name, and saves the spooled PostScript image in that file
instead of sending it to the printer.
@@ -3934,7 +3932,7 @@ image in a file with that name."
(defun pr-despool-ps-print (&optional filename)
"Send the spooled PostScript to the printer or use ghostscript to print it.
-Interactively, when you use a prefix argument (C-u), the command prompts the
+Interactively, when you use a prefix argument (\\[universal-argument]), the command prompts the
user for a file name, and saves the spooled PostScript image in that file
instead of sending it to the printer.
@@ -4035,7 +4033,7 @@ image in a file with that name."
"Process a PostScript file IFILENAME and send it to printer.
Interactively, the command prompts for N-UP printing number, for an input
-PostScript file IFILENAME and, when you use a prefix argument (C-u), the
+PostScript file IFILENAME and, when you use a prefix argument (\\[universal-argument]), the
command prompts the user for an output PostScript file name OFILENAME, and
saves the PostScript image in that file instead of sending it to the printer.
@@ -4276,22 +4274,22 @@ printed using `pr-ps-mode-ps-print'.
Interactively, you have the following situations:
- M-x pr-ps-fast-fire RET
+ \\[pr-ps-fast-fire]
The command prompts the user for a N-UP value and printing will
immediately be done using the current active printer.
- C-u M-x pr-ps-fast-fire RET
- C-u 0 M-x pr-ps-fast-fire RET
+ \\[universal-argument] \\[pr-ps-fast-fire]
+ \\[universal-argument] 0 \\[pr-ps-fast-fire]
The command prompts the user for a N-UP value and also for a current
PostScript printer, then printing will immediately be done using the new
current active printer.
- C-u 1 M-x pr-ps-fast-fire RET
+ \\[universal-argument] 1 \\[pr-ps-fast-fire]
The command prompts the user for a N-UP value and also for a file name,
and saves the PostScript image in that file instead of sending it to the
printer.
- C-u 2 M-x pr-ps-fast-fire RET
+ \\[universal-argument] 2 \\[pr-ps-fast-fire]
The command prompts the user for a N-UP value, then for a current
PostScript printer and, finally, for a file name. Then change the active
printer to that chosen by user and saves the PostScript image in
@@ -4360,7 +4358,7 @@ Also if the current major-mode is defined in `pr-mode-alist', the settings in
`pr-mode-alist' will be used, that is, the current buffer or region will be
printed using `pr-txt-mode'.
-Interactively, when you use a prefix argument (C-u), the command prompts the
+Interactively, when you use a prefix argument (\\[universal-argument]), the command prompts the
user for a new active text printer.
Noninteractively, the argument SELECT-PRINTER is treated as follows:
@@ -5135,7 +5133,7 @@ If menu binding was not done, calls `pr-menu-bind'."
(and (eq (symbol-value infile-sym) t)
(set infile-sym (pr-ps-infile-preprint prompt)))
(or (symbol-value infile-sym)
- (error "%s: input PostScript file name is missing" prompt))
+ (error "%s: Input PostScript file name is missing" prompt))
;; output file
(and (eq (symbol-value outfile-sym) t)
(set outfile-sym (and current-prefix-arg
@@ -5577,7 +5575,7 @@ COMMAND.exe, COMMAND.bat and COMMAND.com in this order."
(define-key map "q" 'pr-interface-quit)
(define-key map "?" 'pr-interface-help)
map)
- "Keymap for pr-interface.")
+ "Keymap for `pr-interface'.")
(defmacro pr-interface-save (&rest body)
`(with-current-buffer pr-i-buffer
@@ -5933,7 +5931,7 @@ COMMAND.exe, COMMAND.bat and COMMAND.com in this order."
(defun pr-interface-help (&rest _ignore)
- "printing buffer interface help."
+ "Printing buffer interface help."
(interactive)
(pr-show-setup pr-interface-help-message "*Printing Interface Help*"))
diff --git a/lisp/proced.el b/lisp/proced.el
index 2fafdcc58e5..9e9793abece 100644
--- a/lisp/proced.el
+++ b/lisp/proced.el
@@ -32,7 +32,7 @@
;; - Allow "sudo kill PID", "sudo renice PID"
;; `proced-send-signal' operates on multiple processes one by one.
;; With "sudo" we want to execute one "kill" or "renice" command
-;; for all marked processes. Is there a `sudo-call-process'?
+;; for all marked processes. Is there a `sudo-call-process'?
;;
;; Thoughts and Ideas
;; - Currently, `process-attributes' returns the list of
@@ -497,8 +497,8 @@ Important: the match ends just after the marker.")
km)
"Keymap for Proced commands.")
-(easy-menu-define
- proced-menu proced-mode-map "Proced Menu"
+(easy-menu-define proced-menu proced-mode-map
+ "Proced Menu."
`("Proced"
["Mark" proced-mark
:help "Mark Current Process"]
@@ -658,6 +658,7 @@ After displaying or updating a Proced buffer, Proced runs the normal hook
`proced-post-display-hook'.
\\{proced-mode-map}"
+ :interactive nil
(abbrev-mode 0)
(auto-fill-mode 0)
(setq buffer-read-only t
@@ -721,7 +722,7 @@ Proced buffers."
With prefix ARG, update this buffer automatically if ARG is positive,
otherwise do not update. Sets the variable `proced-auto-update-flag'.
The time interval for updates is specified via `proced-auto-update-interval'."
- (interactive (list (or current-prefix-arg 'toggle)))
+ (interactive (list (or current-prefix-arg 'toggle)) proced-mode)
(setq proced-auto-update-flag
(cond ((eq arg 'toggle) (not proced-auto-update-flag))
(arg (> (prefix-numeric-value arg) 0))
@@ -733,19 +734,19 @@ The time interval for updates is specified via `proced-auto-update-interval'."
(defun proced-mark (&optional count)
"Mark the current (or next COUNT) processes."
- (interactive "p")
+ (interactive "p" proced-mode)
(proced-do-mark t count))
(defun proced-unmark (&optional count)
"Unmark the current (or next COUNT) processes."
- (interactive "p")
+ (interactive "p" proced-mode)
(proced-do-mark nil count))
(defun proced-unmark-backward (&optional count)
"Unmark the previous (or COUNT previous) processes."
;; Analogous to `dired-unmark-backward',
;; but `ibuffer-unmark-backward' behaves different.
- (interactive "p")
+ (interactive "p" proced-mode)
(proced-do-mark nil (- (or count 1))))
(defun proced-do-mark (mark &optional count)
@@ -762,7 +763,7 @@ The time interval for updates is specified via `proced-auto-update-interval'."
(defun proced-toggle-marks ()
"Toggle marks: marked processes become unmarked, and vice versa."
- (interactive)
+ (interactive nil proced-mode)
(let ((mark-re (proced-marker-regexp))
buffer-read-only)
(save-excursion
@@ -788,14 +789,14 @@ Otherwise move one line forward after inserting the mark."
"Mark all processes.
If `transient-mark-mode' is turned on and the region is active,
mark the region."
- (interactive)
+ (interactive nil proced-mode)
(proced-do-mark-all t))
(defun proced-unmark-all ()
"Unmark all processes.
If `transient-mark-mode' is turned on and the region is active,
unmark the region."
- (interactive)
+ (interactive nil proced-mode)
(proced-do-mark-all nil))
(defun proced-do-mark-all (mark)
@@ -830,14 +831,14 @@ mark the region."
(defun proced-mark-children (ppid &optional omit-ppid)
"Mark child processes of process PPID.
Also mark process PPID unless prefix OMIT-PPID is non-nil."
- (interactive (list (proced-pid-at-point) current-prefix-arg))
+ (interactive (list (proced-pid-at-point) current-prefix-arg) proced-mode)
(proced-mark-process-alist
(proced-filter-children proced-process-alist ppid omit-ppid)))
(defun proced-mark-parents (cpid &optional omit-cpid)
"Mark parent processes of process CPID.
Also mark CPID unless prefix OMIT-CPID is non-nil."
- (interactive (list (proced-pid-at-point) current-prefix-arg))
+ (interactive (list (proced-pid-at-point) current-prefix-arg) proced-mode)
(proced-mark-process-alist
(proced-filter-parents proced-process-alist cpid omit-cpid)))
@@ -870,7 +871,7 @@ If `transient-mark-mode' is turned on and the region is active,
omit the processes in region.
If QUIET is non-nil suppress status message.
Returns count of omitted lines."
- (interactive "P")
+ (interactive "P" proced-mode)
(let ((mark-re (proced-marker-regexp))
(count 0)
buffer-read-only)
@@ -947,7 +948,8 @@ Set variable `proced-filter' to SCHEME. Revert listing."
(interactive
(let ((scheme (completing-read "Filter: "
proced-filter-alist nil t)))
- (list (if (string= "" scheme) nil (intern scheme)))))
+ (list (if (string= "" scheme) nil (intern scheme))))
+ proced-mode)
;; only update if necessary
(unless (eq proced-filter scheme)
(setq proced-filter scheme)
@@ -1057,7 +1059,7 @@ Each parent process is followed by its child processes.
The process tree inherits the chosen sorting order of the process listing,
that is, child processes of the same parent process are sorted using
the selected sorting order."
- (interactive (list (or current-prefix-arg 'toggle)))
+ (interactive (list (or current-prefix-arg 'toggle)) proced-mode)
(setq proced-tree-flag
(cond ((eq arg 'toggle) (not proced-tree-flag))
(arg (> (prefix-numeric-value arg) 0))
@@ -1140,7 +1142,7 @@ This command refines an already existing process listing generated initially
based on the value of the variable `proced-filter'. It does not change
this variable. It does not revert the listing. If you frequently need
a certain refinement, consider defining a new filter in `proced-filter-alist'."
- (interactive (list last-input-event))
+ (interactive (list last-input-event) proced-mode)
(if event (posn-set-point (event-end event)))
(let ((key (get-text-property (point) 'proced-key))
(pid (get-text-property (point) 'proced-pid)))
@@ -1269,7 +1271,8 @@ in the mode line, using \"+\" or \"-\" for ascending or descending order."
nil t)))
(list (if (string= "" scheme) nil (intern scheme))
;; like 'toggle in `define-derived-mode'
- (or current-prefix-arg 'no-arg))))
+ (or current-prefix-arg 'no-arg)))
+ proced-mode)
(setq proced-descend
;; If `proced-sort-interactive' is called repeatedly for the same
@@ -1290,37 +1293,37 @@ in the mode line, using \"+\" or \"-\" for ascending or descending order."
(defun proced-sort-pcpu (&optional arg)
"Sort Proced buffer by percentage CPU time (%CPU).
Prefix ARG controls sort order, see `proced-sort-interactive'."
- (interactive (list (or current-prefix-arg 'no-arg)))
+ (interactive (list (or current-prefix-arg 'no-arg)) proced-mode)
(proced-sort-interactive 'pcpu arg))
(defun proced-sort-pmem (&optional arg)
"Sort Proced buffer by percentage memory usage (%MEM).
Prefix ARG controls sort order, see `proced-sort-interactive'."
- (interactive (list (or current-prefix-arg 'no-arg)))
+ (interactive (list (or current-prefix-arg 'no-arg)) proced-mode)
(proced-sort-interactive 'pmem arg))
(defun proced-sort-pid (&optional arg)
"Sort Proced buffer by PID.
Prefix ARG controls sort order, see `proced-sort-interactive'."
- (interactive (list (or current-prefix-arg 'no-arg)))
+ (interactive (list (or current-prefix-arg 'no-arg)) proced-mode)
(proced-sort-interactive 'pid arg))
(defun proced-sort-start (&optional arg)
"Sort Proced buffer by time the command started (START).
Prefix ARG controls sort order, see `proced-sort-interactive'."
- (interactive (list (or current-prefix-arg 'no-arg)))
+ (interactive (list (or current-prefix-arg 'no-arg)) proced-mode)
(proced-sort-interactive 'start arg))
(defun proced-sort-time (&optional arg)
"Sort Proced buffer by CPU time (TIME).
Prefix ARG controls sort order, see `proced-sort-interactive'."
- (interactive (list (or current-prefix-arg 'no-arg)))
+ (interactive (list (or current-prefix-arg 'no-arg)) proced-mode)
(proced-sort-interactive 'time arg))
(defun proced-sort-user (&optional arg)
"Sort Proced buffer by USER.
Prefix ARG controls sort order, see `proced-sort-interactive'."
- (interactive (list (or current-prefix-arg 'no-arg)))
+ (interactive (list (or current-prefix-arg 'no-arg)) proced-mode)
(proced-sort-interactive 'user arg))
(defun proced-sort-header (event &optional arg)
@@ -1329,12 +1332,13 @@ EVENT is a mouse event with starting position in the header line.
It is converted to the corresponding attribute key.
This command updates the variable `proced-sort'.
Prefix ARG controls sort order, see `proced-sort-interactive'."
- (interactive (list last-input-event (or last-prefix-arg 'no-arg)))
- (let ((start (event-start event))
- col key)
+ (interactive (list last-input-event (or last-prefix-arg 'no-arg)) proced-mode)
+ (let* ((start (event-start event))
+ (obj (posn-object start))
+ col key)
(save-selected-window
(select-window (posn-window start))
- (setq col (+ (1- (car (posn-actual-col-row start)))
+ (setq col (+ (if obj (cdr obj) (posn-point start))
(window-hscroll)))
(when (and (<= 0 col) (< col (length proced-header-line)))
(setq key (get-text-property col 'proced-key proced-header-line))
@@ -1534,7 +1538,8 @@ With prefix REVERT non-nil revert listing."
(let ((scheme (completing-read "Format: "
proced-format-alist nil t)))
(list (if (string= "" scheme) nil (intern scheme))
- current-prefix-arg)))
+ current-prefix-arg))
+ proced-mode)
;; only update if necessary
(when (or (not (eq proced-format scheme)) revert)
(setq proced-format scheme)
@@ -1566,7 +1571,7 @@ Suppress status information if QUIET is nil.
After updating a displayed Proced buffer run the normal hook
`proced-post-display-hook'."
;; This is the main function that generates and updates the process listing.
- (interactive "P")
+ (interactive "P" proced-mode)
(setq revert (or revert (not proced-process-alist)))
(or quiet (message (if revert "Updating process information..."
"Updating process display...")))
@@ -1772,11 +1777,12 @@ supported but discouraged. It will be removed in a future version of Emacs."
`(:annotation-function
,(lambda (s) (cdr (assoc s proced-signal-list))))))
(proced-with-processes-buffer process-alist
- (list (completing-read (concat "Send signal [" pnum
- "] (default TERM): ")
+ (list (completing-read (format-prompt "Send signal [%s]"
+ "TERM" pnum)
proced-signal-list
nil nil nil nil "TERM")
- process-alist))))
+ process-alist)))
+ proced-mode)
(unless (and signal process-alist)
;; Discouraged usage (supported for backward compatibility):
@@ -1797,8 +1803,8 @@ supported but discouraged. It will be removed in a future version of Emacs."
`(:annotation-function
,(lambda (s) (cdr (assoc s proced-signal-list))))))
(proced-with-processes-buffer process-alist
- (setq signal (completing-read (concat "Send signal [" pnum
- "] (default TERM): ")
+ (setq signal (completing-read (format-prompt "Send signal [%s]"
+ "TERM" pnum)
proced-signal-list
nil nil nil nil "TERM"))))))
@@ -1861,7 +1867,8 @@ the normal hook `proced-after-send-signal-hook'."
(let ((process-alist (proced-marked-processes)))
(proced-with-processes-buffer process-alist
(list (read-number "New priority: ")
- process-alist))))
+ process-alist)))
+ proced-mode)
(if (numberp priority)
(setq priority (number-to-string priority)))
(let (failures)
@@ -1893,7 +1900,7 @@ the normal hook `proced-after-send-signal-hook'."
"Pop up a buffer with error log output from Proced.
A group of errors from a single command ends with a formfeed.
Thus, use \\[backward-page] to find the beginning of a group of errors."
- (interactive)
+ (interactive nil proced-mode)
(if (get-buffer proced-log-buffer)
(save-selected-window
;; move `proced-log-buffer' to the front of the buffer list
@@ -1945,7 +1952,7 @@ STRING is an overall summary of the failures."
(defun proced-help ()
"Provide help for the Proced user."
- (interactive)
+ (interactive nil proced-mode)
(proced-why)
(if (eq last-command 'proced-help)
(describe-mode)
@@ -1955,7 +1962,7 @@ STRING is an overall summary of the failures."
"Undo in a Proced buffer.
This doesn't recover killed processes, it just undoes changes in the Proced
buffer. You can use it to recover marks."
- (interactive)
+ (interactive nil proced-mode)
(let (buffer-read-only)
(undo))
(message "Change in Proced buffer undone.
diff --git a/lisp/profiler.el b/lisp/profiler.el
index 4c427692cb8..fa74fe8de25 100644
--- a/lisp/profiler.el
+++ b/lisp/profiler.el
@@ -105,8 +105,8 @@
;;; Entries
(defun profiler-format-entry (entry)
- "Format ENTRY in human readable string. ENTRY would be a
-function name of a function itself."
+ "Format ENTRY in human readable string.
+ENTRY would be a function name of a function itself."
(cond ((memq (car-safe entry) '(closure lambda))
(format "#<lambda %#x>" (sxhash entry)))
((byte-code-function-p entry)
@@ -463,12 +463,12 @@ Optional argument MODE means only check for the specified mode (cpu or mem)."
"The current profile.")
(defvar-local profiler-report-reversed nil
- "True if calltree is rendered in bottom-up. Do not touch this
-variable directly.")
+ "Non-nil if calltree is rendered in bottom-up.
+Do not touch this variable directly.")
(defvar-local profiler-report-order nil
- "The value can be `ascending' or `descending'. Do not touch
-this variable directly.")
+ "The value can be `ascending' or `descending'.
+Do not touch this variable directly.")
(defun profiler-report-make-entry-part (entry)
(let ((string (cond
@@ -618,8 +618,7 @@ RET: expand or collapse"))
buffer))
(defun profiler-report-setup-buffer (profile)
- "Make a buffer for PROFILE with rendering the profile and
-return it."
+ "Make a buffer for PROFILE with rendering the profile and return it."
(let ((buffer (profiler-report-setup-buffer-1 profile)))
(with-current-buffer buffer
(profiler-report-render-calltree))
@@ -706,9 +705,9 @@ With a prefix argument, expand the whole subtree."
t)))
(defun profiler-report-toggle-entry (&optional arg)
- "Expand entry at point if the tree is collapsed,
-otherwise collapse. With prefix argument, expand all subentries
-below entry at point."
+ "Expand entry at point if the tree is collapsed, otherwise collapse.
+With prefix argument, expand all subentries below entry at
+point."
(interactive "P")
(or (profiler-report-expand-entry arg)
(profiler-report-collapse-entry)))
diff --git a/lisp/progmodes/antlr-mode.el b/lisp/progmodes/antlr-mode.el
index 2a4b3482831..0b7945430d3 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
-;; X-URL: http://antlr-mode.sourceforge.net/
+;; URL: http://antlr-mode.sourceforge.net/
;; This file is part of GNU Emacs.
@@ -570,7 +570,7 @@ See \\[antlr-show-makefile-rules] and `antlr-unknown-file-formats'.")
"The following Makefile rules define the dependencies for all (non-
expanded) grammars in directory \"%s\".\n
They are stored in the kill-ring, i.e., you can insert them with C-y
-into your Makefile. You can also invoke M-x antlr-show-makefile-rules
+into your Makefile. You can also invoke \\[antlr-show-makefile-rules]
from within a Makefile to insert them directly.\n\n\n"
"Introduction to use with \\[antlr-show-makefile-rules].
It is a format string and used with substitution DIRECTORY/%s where
@@ -2167,7 +2167,8 @@ command `antlr-show-makefile-rules' for detail."
(unless in-makefile
(copy-region-as-kill (point-min) (point-max))
(goto-char (point-min))
- (insert (format antlr-help-rules-intro dirname)))))
+ (insert (format (substitute-command-keys antlr-help-rules-intro)
+ dirname)))))
;;;###autoload
(defun antlr-show-makefile-rules ()
diff --git a/lisp/progmodes/autoconf.el b/lisp/progmodes/autoconf.el
index 73cf290f43c..78148ccf858 100644
--- a/lisp/progmodes/autoconf.el
+++ b/lisp/progmodes/autoconf.el
@@ -44,7 +44,7 @@
"A\\(?:H_TEMPLATE\\|C_\\(?:SUBST\\|DEFINE\\(?:_UNQUOTED\\)?\\)\\)(\\[*\\(\\(?:\\sw\\|\\s_\\)+\\)\\]*")
(defvar autoconf-font-lock-keywords
- `(("\\_<A[CHMS]_\\(?:\\sw\\|\\s_\\)+" . font-lock-keyword-face)
+ `(("\\_<\\(?:A[CHMS]\\|LT\\)_\\(?:\\sw\\|\\s_\\)+" . font-lock-keyword-face)
(,autoconf-definition-regexp
1 font-lock-function-name-face)
;; Are any other M4 keywords really appropriate for configure.ac,
diff --git a/lisp/progmodes/bat-mode.el b/lisp/progmodes/bat-mode.el
index 7ba8a69775e..2cc8dfce668 100644
--- a/lisp/progmodes/bat-mode.el
+++ b/lisp/progmodes/bat-mode.el
@@ -175,7 +175,7 @@
;;;###autoload
(define-derived-mode bat-mode prog-mode "Bat"
- "Major mode for editing DOS/Windows batch files.\n
+ "Major mode for editing DOS/Windows batch files.
Start a new script from `bat-template'. Read help pages for DOS commands
with `bat-cmd-help'. Navigate between sections using `imenu'.
Run script using `bat-run' and `bat-run-args'.\n
diff --git a/lisp/progmodes/bug-reference.el b/lisp/progmodes/bug-reference.el
index 9b9c58eb1f2..d7092a37d44 100644
--- a/lisp/progmodes/bug-reference.el
+++ b/lisp/progmodes/bug-reference.el
@@ -26,17 +26,17 @@
;; This file provides minor modes for putting clickable overlays on
;; references to bugs. A bug reference is text like "PR foo/29292";
;; this is mapped to a URL using a user-supplied format; see
-;; `bug-reference-url-format' and `bug-reference-bug-regexp'. More
+;; `bug-reference-url-format' and `bug-reference-bug-regexp'. More
;; extensive documentation is in (info "(emacs) Bug Reference").
;; Two minor modes are provided. One works on any text in the buffer;
-;; the other operates only on comments and strings. By default, the
+;; the other operates only on comments and strings. By default, the
;; URL link is followed by invoking C-c RET or mouse-2.
;;; Code:
(defgroup bug-reference nil
- "Hyperlinking references to bug reports"
+ "Hyperlinking references to bug reports."
;; Somewhat arbitrary, by analogy with eg goto-address.
:group 'comm)
@@ -72,11 +72,30 @@ so that it is considered safe, see `enable-local-variables'.")
(get s 'bug-reference-url-format)))))
(defcustom bug-reference-bug-regexp
- "\\([Bb]ug ?#?\\|[Pp]atch ?#\\|RFE ?#\\|PR [a-z+-]+/\\)\\([0-9]+\\(?:#[0-9]+\\)?\\)"
+ "\\(\\b\\(?:[Bb]ug ?#?\\|[Pp]atch ?#\\|RFE ?#\\|PR [a-z+-]+/\\)\\([0-9]+\\(?:#[0-9]+\\)?\\)\\)"
"Regular expression matching bug references.
-The second subexpression should match the bug reference (usually a number)."
+The first subexpression defines the region of the bug-reference
+overlay, i.e., the region being fontified and made clickable in
+order to browse the referenced bug in the corresponding project's
+issue tracker.
+
+If `bug-reference-url-format' is set to a format string with
+single %s placeholder, the second subexpression must match
+the (part of the) bug reference which needs to be injected in
+place of the %s in order to form the bug's ticket URL.
+
+If `bug-reference-url-format' is a function, the interpretation
+of the subexpressions larger than 1 is up to the function.
+However, it is checked that the bounds of all matching
+subexpressions from 2 to 10 are within the bounds of the
+subexpression 1 defining the overlay region. Larger
+subexpressions may also be used by the function but may lay
+outside the bounds of subexpressions 1 and then don't contribute
+to the highlighted and clickable region."
:type 'regexp
- :version "24.3") ; previously defconst
+ ; 24.3: defconst -> defcustom
+ ; 28.1: contract about subexpression 1 defines the overlay region.
+ :version "28.1")
;;;###autoload
(put 'bug-reference-bug-regexp 'safe-local-variable 'stringp)
@@ -92,37 +111,92 @@ The second subexpression should match the bug reference (usually a number)."
(bug-reference-set-overlay-properties)
+(defun bug-reference--overlays-in (start end)
+ "Return bug reference overlays in the region between START and END."
+ (let (overlays)
+ (dolist (o (overlays-in start end))
+ (when (eq (overlay-get o 'category) 'bug-reference)
+ (push o overlays)))
+ (nreverse overlays)))
+
(defun bug-reference-unfontify (start end)
"Remove bug reference overlays from the region between START and END."
- (dolist (o (overlays-in start end))
- (when (eq (overlay-get o 'category) 'bug-reference)
- (delete-overlay o))))
+ (mapc #'delete-overlay (bug-reference--overlays-in start end)))
(defvar bug-reference-prog-mode)
+(defvar bug-reference--nonconforming-regexps nil)
+
+(defun bug-reference--overlay-bounds ()
+ (let ((m-b1 (match-beginning 1))
+ (m-e1 (match-end 1)))
+ (if (and m-b1 m-e1
+ (catch 'within-bounds
+ (let ((i 2))
+ (while (<= i 10)
+ (when (and (match-beginning i)
+ (or (< (match-beginning i) m-b1)
+ (> (match-end i) m-e1)))
+ (throw 'within-bounds nil))
+ (cl-incf i))
+ t)))
+ ;; All groups 2..10 are within bounds.
+ (cons m-b1 m-e1)
+ ;; The regexp doesn't fulfil the contract of
+ ;; bug-reference-bug-regexp, so fall back to the old behavior.
+ (unless (member bug-reference-bug-regexp
+ bug-reference--nonconforming-regexps)
+ (setq bug-reference--nonconforming-regexps
+ (cons bug-reference-bug-regexp
+ bug-reference--nonconforming-regexps))
+ (display-warning
+ 'bug-reference
+ (format-message
+ "The value of `bug-reference-bug-regexp'
+
+ %S
+
+in buffer %S doesn't conform to the contract specified by its
+docstring. The subexpression 1 should define the region of the
+bug-reference overlay and cover all other subexpressions up to
+subexpression 10."
+ bug-reference-bug-regexp
+ (buffer-name))))
+ (cons (match-beginning 0) (match-end 0)))))
+
(defun bug-reference-fontify (start end)
"Apply bug reference overlays to the region between START and END."
(save-excursion
- (let ((beg-line (progn (goto-char start) (line-beginning-position)))
- (end-line (progn (goto-char end) (line-end-position))))
- ;; Remove old overlays.
- (bug-reference-unfontify beg-line end-line)
+ (let* ((beg-line (progn (goto-char start) (line-beginning-position)))
+ (end-line (progn (goto-char end) (line-end-position)))
+ ;; Reuse existing overlays overlays.
+ (overlays (bug-reference--overlays-in beg-line end-line)))
(goto-char beg-line)
(while (and (< (point) end-line)
- (re-search-forward bug-reference-bug-regexp end-line 'move))
- (when (or (not bug-reference-prog-mode)
- ;; This tests for both comment and string syntax.
- (nth 8 (syntax-ppss)))
- (let ((overlay (make-overlay (match-beginning 0) (match-end 0)
- nil t nil)))
- (overlay-put overlay 'category 'bug-reference)
- ;; Don't put a link if format is undefined
- (when bug-reference-url-format
+ (re-search-forward bug-reference-bug-regexp end-line 'move))
+ (when (or (not bug-reference-prog-mode)
+ ;; This tests for both comment and string syntax.
+ (nth 8 (syntax-ppss)))
+ (let* ((bounds (bug-reference--overlay-bounds))
+ (overlay (or
+ (let ((ov (pop overlays)))
+ (when ov
+ (move-overlay ov (car bounds) (cdr bounds))
+ ov))
+ (let ((ov (make-overlay (car bounds) (cdr bounds)
+ nil t nil)))
+ (overlay-put ov 'category 'bug-reference)
+ ov))))
+ ;; Don't put a link if format is undefined.
+ (when bug-reference-url-format
(overlay-put overlay 'bug-reference-url
(if (stringp bug-reference-url-format)
(format bug-reference-url-format
(match-string-no-properties 2))
- (funcall bug-reference-url-format))))))))))
+ (funcall bug-reference-url-format)))))))
+ ;; Delete remaining but unused overlays.
+ (dolist (ov overlays)
+ (delete-overlay ov)))))
;; Taken from button.el.
(defun bug-reference-push-button (&optional pos _use-mouse-action)
@@ -135,14 +209,14 @@ The second subexpression should match the bug reference (usually a number)."
(if (and (not (integerp pos)) (eventp pos))
;; POS is a mouse event; switch to the proper window/buffer
(let ((posn (event-start pos)))
- (with-current-buffer (window-buffer (posn-window posn))
- (bug-reference-push-button (posn-point posn) t)))
+ (with-current-buffer (window-buffer (posn-window posn))
+ (bug-reference-push-button (posn-point posn) t)))
;; POS is just normal position.
(dolist (o (overlays-at pos))
;; It should only be possible to have one URL overlay.
(let ((url (overlay-get o 'bug-reference-url)))
- (when url
- (browse-url url))))))
+ (when url
+ (browse-url url))))))
(defun bug-reference-maybe-setup-from-vc (url url-rx bug-rx bug-url-fmt)
(when (string-match url-rx url)
@@ -153,95 +227,140 @@ The second subexpression should match the bug reference (usually a number)."
(push (match-string i url) groups))
(funcall bug-url-fmt (nreverse groups))))))
-(defvar bug-reference-setup-from-vc-alist
- `(;;
- ;; GNU projects on savannah.
- ;;
- ;; Not all of them use debbugs but that doesn't really matter
- ;; because the auto-setup is only performed if
- ;; `bug-reference-url-format' and `bug-reference-bug-regexp'
- ;; aren't set already.
- ("git\\.\\(?:sv\\|savannah\\)\\.gnu\\.org:"
- "\\<\\([Bb]ug ?#?\\)\\([0-9]+\\(?:#[0-9]+\\)?\\)\\>"
- ,(lambda (_) "https://debbugs.gnu.org/%s"))
- ;;
- ;; GitHub projects.
- ;;
- ;; Here #17 may refer to either an issue or a pull request but
- ;; visiting the issue/17 web page will automatically redirect to
- ;; the pull/17 page if 17 is a PR. Explicit user/project#17 links
- ;; to possibly different projects are also supported.
- ("[/@]github.com[/:]\\([.A-Za-z0-9_/-]+\\)\\.git"
- "\\([.A-Za-z0-9_/-]+\\)?\\(?:#\\)\\([0-9]+\\)\\>"
- ,(lambda (groups)
- (let ((ns-project (nth 1 groups)))
- (lambda ()
- (concat "https://github.com/"
- (or
- ;; Explicit user/proj#18 link.
- (match-string 1)
- ns-project)
- "/issues/"
- (match-string 2))))))
- ;;
- ;; Codeberg projects.
- ;;
- ;; The systematics is exactly as for Github projects.
- ("[/@]codeberg.org[/:]\\([.A-Za-z0-9_/-]+\\)\\.git"
- "\\([.A-Za-z0-9_/-]+\\)?\\(?:#\\)\\([0-9]+\\)\\>"
- ,(lambda (groups)
- (let ((ns-project (nth 1 groups)))
- (lambda ()
- (concat "https://codeberg.org/"
- (or
- ;; Explicit user/proj#18 link.
- (match-string 1)
- ns-project)
- "/issues/"
- (match-string 2))))))
- ;;
- ;; GitLab projects.
- ;;
- ;; Here #18 is an issue and !17 is a merge request. Explicit
- ;; namespace/project#18 or namespace/project!17 references to
- ;; possibly different projects are also supported.
- ("[/@]gitlab.com[/:]\\([.A-Za-z0-9_/-]+\\)\\.git"
- "\\(?1:[.A-Za-z0-9_/-]+\\)?\\(?3:[#!]\\)\\(?2:[0-9]+\\)\\>"
- ,(lambda (groups)
- (let ((ns-project (nth 1 groups)))
- (lambda ()
- (concat "https://gitlab.com/"
- (or (match-string 1)
- ns-project)
- "/-/"
- (if (string= (match-string 3) "#")
- "issues/"
- "merge_requests/")
- (match-string 2))))))
- ;;
- ;; Sourcehut projects.
- ;;
- ;; #19 is an issue. Other project's issues can be referenced as
- ;; #~user/project#19.
- ;;
- ;; Caveat: The code assumes that a project on git.sr.ht or
- ;; hg.sr.ht has a tracker of the same name on todo.sh.ht. That's
- ;; a very common setup but all sr.ht services are loosely coupled,
- ;; so you can have a repo without tracker, or a repo with a
- ;; tracker using a different name, etc. So we can only try to
- ;; make a good guess.
- ("[/@]\\(?:git\\|hg\\).sr.ht[/:]\\(~[.A-Za-z0-9_/-]+\\)"
- "\\(~[.A-Za-z0-9_/-]+\\)?\\(?:#\\)\\([0-9]+\\)\\>"
- ,(lambda (groups)
- (let ((ns-project (nth 1 groups)))
- (lambda ()
- (concat "https://todo.sr.ht/"
- (or
- ;; Explicit user/proj#18 link.
- (match-string 1)
- ns-project)
- "/"
- (match-string 2)))))))
+(defvar bug-reference--setup-from-vc-alist nil
+ "An alist for setting up `bug-reference-mode' based on VC URL.
+This is like `bug-reference-setup-from-vc-alist' but generated
+from a few default entries, and the value of
+`bug-reference-forge-alist'.")
+
+(defvar bug-reference-forge-alist
+ '(("github.com" github "https")
+ ("gitea.com" gitea "https")
+ ("codeberg.org" gitea "https")
+ ("gitlab.com" gitlab "https")
+ ("framagit.org" gitlab "https")
+ ("salsa.debian.org" gitlab "https")
+ ("sr.ht" sourcehut "https"))
+ "An alist of forge instances.
+Each entry has the form (HOST-DOMAIN FORGE-TYPE PROTOCOL).
+HOST-DOMAIN is the host- and domain name, e.g., gitlab.com,
+salsa.debian.org, or sr.ht.
+FORGE-TYPE is the type of the forge, e.g., gitlab, gitea,
+sourcehut, or github.
+PROTOCOL is the protocol for accessing the forge's issue tracker,
+usually \"https\" but for self-hosted forge instances not
+accessible via the internet it might also be \"http\".")
+
+(cl-defgeneric bug-reference--build-forge-setup-entry
+ (host-domain forge-type protocol)
+ "Build an entry for `bug-reference--setup-from-vc-alist'.
+HOST-DOMAIN is the host- and domain name, e.g., gitlab.com, or
+sr.ht.
+
+FORGE-TYPE is the type of the forge, e.g., gitlab, gitea,
+sourcehut, or github.
+
+PROTOCOL is the protocol for accessing the forge's issue tracker,
+usually https but for self-hosted forge instances not accessible
+via the internet it might also be http.")
+
+;; GitHub: Here #17 may refer to either an issue or a pull request but
+;; visiting the issue/17 web page will automatically redirect to the
+;; pull/17 page if 17 is a PR. Explicit user/project#17 links to
+;; possibly different projects are also supported.
+(cl-defmethod bug-reference--build-forge-setup-entry
+ (host-domain (_forge-type (eql 'github)) protocol)
+ `(,(concat "[/@]" (regexp-quote host-domain)
+ "[/:]\\([.A-Za-z0-9_/-]+?\\)\\(?:\\.git\\)?/?\\'")
+ "\\(\\([.A-Za-z0-9_/-]+\\)?\\(?:#\\)\\([0-9]+\\)\\)\\>"
+ ,(lambda (groups)
+ (let ((ns-project (nth 1 groups)))
+ (lambda ()
+ (format "%s://%s/%s/issues/%s"
+ protocol host-domain
+ (or (match-string-no-properties 2) ns-project)
+ (match-string-no-properties 3)))))))
+
+;; GitLab: Here #18 is an issue and !17 is a merge request. Explicit
+;; namespace/project#18 or namespace/project!17 references to possibly
+;; different projects are also supported.
+(cl-defmethod bug-reference--build-forge-setup-entry
+ (host-domain (_forge-type (eql 'gitlab)) protocol)
+ `(,(concat "[/@]" (regexp-quote host-domain)
+ "[/:]\\([.A-Za-z0-9_/-]+?\\)\\(?:\\.git\\)?/?\\'")
+ "\\(\\([.A-Za-z0-9_/-]+\\)?\\([#!]\\)\\([0-9]+\\)\\)\\>"
+ ,(lambda (groups)
+ (let ((ns-project (nth 1 groups)))
+ (lambda ()
+ (format "%s://%s/%s/-/%s/%s"
+ protocol host-domain
+ (or (match-string-no-properties 2) ns-project)
+ (if (string= (match-string-no-properties 3) "#")
+ "issues/"
+ "merge_requests/")
+ (match-string-no-properties 4)))))))
+
+;; Gitea: The systematics is exactly as for Github projects.
+(cl-defmethod bug-reference--build-forge-setup-entry
+ (host-domain (_forge-type (eql 'gitea)) protocol)
+ `(,(concat "[/@]" (regexp-quote host-domain)
+ "[/:]\\([.A-Za-z0-9_/-]+?\\)\\(?:\\.git\\)?/?\\'")
+ "\\(\\([.A-Za-z0-9_/-]+\\)?\\(?:#\\)\\([0-9]+\\)\\)\\>"
+ ,(lambda (groups)
+ (let ((ns-project (nth 1 groups)))
+ (lambda ()
+ (format "%s://%s/%s/issues/%s"
+ protocol host-domain
+ (or (match-string-no-properties 2) ns-project)
+ (match-string-no-properties 3)))))))
+
+;; Sourcehut: #19 is an issue. Other project's issues can be
+;; referenced as ~user/project#19.
+;;
+;; Caveat: The code assumes that a project on git.sr.ht or hg.sr.ht
+;; has a tracker of the same name on todo.sh.ht. That's a very common
+;; setup but all sr.ht services are loosely coupled, so you can have a
+;; repo without tracker, or a repo with a tracker using a different
+;; name, etc. So we can only try to make a good guess.
+(cl-defmethod bug-reference--build-forge-setup-entry
+ (host-domain (_forge-type (eql 'sourcehut)) protocol)
+ `(,(concat "[/@]\\(?:git\\|hg\\)." (regexp-quote host-domain)
+ "[/:]\\(~[.A-Za-z0-9_/-]+\\)")
+ "\\(\\(~[.A-Za-z0-9_/-]+\\)?\\(?:#\\)\\([0-9]+\\)\\)\\>"
+ ,(lambda (groups)
+ (let ((ns-project (nth 1 groups)))
+ (lambda ()
+ (format "%s://todo.%s/%s/%s"
+ protocol host-domain
+ (or (match-string-no-properties 2) ns-project)
+ (match-string-no-properties 3)))))))
+
+(defun bug-reference--setup-from-vc-alist (&optional rebuild)
+ "Compute the `bug-reference--setup-from-vc-alist' value.
+If REBUILD is non-nil, compute it again even if has been computed
+already. The value contains a few default entries, and entries
+generated from `bug-reference-forge-alist'."
+ (if (and bug-reference--setup-from-vc-alist
+ (null rebuild))
+ bug-reference--setup-from-vc-alist
+ (setq bug-reference--setup-from-vc-alist
+ `(;; GNU projects on savannah.
+ ;;
+ ;; Not all of them use debbugs but that doesn't really
+ ;; matter because the auto-setup is only performed if
+ ;; `bug-reference-url-format' and
+ ;; `bug-reference-bug-regexp' aren't set already.
+ ("git\\.\\(?:sv\\|savannah\\)\\.gnu\\.org:"
+ "\\(\\b\\(?:[Bb]ug ?#?\\)\\([0-9]+\\(?:#[0-9]+\\)?\\)\\)\\>"
+ ,(lambda (_) "https://debbugs.gnu.org/%s"))
+
+ ;; Entries for the software forges of
+ ;; `bug-reference-forge-alist'.
+ ,@(mapcar (lambda (entry)
+ (apply #'bug-reference--build-forge-setup-entry entry))
+ bug-reference-forge-alist)))))
+
+(defvar bug-reference-setup-from-vc-alist nil
"An alist for setting up `bug-reference-mode' based on VC URL.
Each element has the form (URL-REGEXP BUG-REGEXP URL-FORMAT-FN).
@@ -256,30 +375,28 @@ URL-REGEXP against the VCS URL and returns the value to be set as
(defun bug-reference-try-setup-from-vc ()
"Try setting up `bug-reference-mode' based on VC information.
Test each configuration in `bug-reference-setup-from-vc-alist'
-and apply it if applicable."
- (let ((file-or-dir (or buffer-file-name
- ;; Catches modes such as vc-dir and Magit.
- default-directory)))
- (when file-or-dir
- (let* ((backend (vc-responsible-backend file-or-dir t))
- (url
- (or (ignore-errors
- (vc-call-backend backend 'repository-url "upstream"))
- (ignore-errors
- (vc-call-backend backend 'repository-url)))))
- (when url
- (catch 'found
- (dolist (config bug-reference-setup-from-vc-alist)
- (when (apply #'bug-reference-maybe-setup-from-vc
- url config)
- (throw 'found t)))))))))
+and `bug-reference--setup-from-vc-alist' and apply it if
+applicable."
+ (when-let ((file-or-dir (or buffer-file-name
+ ;; Catches modes such as vc-dir and Magit.
+ default-directory))
+ (backend (vc-responsible-backend file-or-dir t))
+ (url (seq-some (lambda (remote)
+ (ignore-errors
+ (vc-call-backend backend 'repository-url
+ file-or-dir remote)))
+ '("upstream" nil))))
+ (seq-some (lambda (config)
+ (apply #'bug-reference-maybe-setup-from-vc url config))
+ (append bug-reference-setup-from-vc-alist
+ (bug-reference--setup-from-vc-alist)))))
(defvar bug-reference-setup-from-mail-alist
`((,(regexp-opt '("emacs" "auctex" "gnus" "tramp" "orgmode") 'words)
,(regexp-opt '("@debbugs.gnu.org" "-devel@gnu.org"
;; List-Id of Gnus devel mailing list.
"ding.gnus.org"))
- "\\([Bb]ug ?#?\\)\\([0-9]+\\(?:#[0-9]+\\)?\\)"
+ "\\(\\b[Bb]ug ?#?\\([0-9]+\\(?:#[0-9]+\\)?\\)\\)"
"https://debbugs.gnu.org/%s"))
"An alist for setting up `bug-reference-mode' in mail modes.
@@ -410,7 +527,7 @@ From, and Cc against HEADER-REGEXP in
`((,(concat "#" (regexp-opt '("emacs" "gnus" "org-mode" "rcirc"
"erc") 'words))
"Libera.Chat"
- "\\([Bb]ug ?#?\\)\\([0-9]+\\(?:#[0-9]+\\)?\\)"
+ "\\(\\b[Bb]ug ?#?\\([0-9]+\\(?:#[0-9]+\\)?\\)\\)"
"https://debbugs.gnu.org/%s"))
"An alist for setting up `bug-reference-mode' in IRC modes.
@@ -512,10 +629,8 @@ guesswork is based on these variables:
bug-reference-url-format)
(with-demoted-errors
"Error during bug-reference auto-setup: %S"
- (catch 'setup
- (dolist (f bug-reference-auto-setup-functions)
- (when (funcall f)
- (throw 'setup t))))))))
+ (run-hook-with-args-until-success
+ 'bug-reference-auto-setup-functions)))))
;;;###autoload
(define-minor-mode bug-reference-mode
@@ -532,7 +647,7 @@ guesswork is based on these variables:
"Enable `bug-reference-mode' and force auto-setup.
Enabling `bug-reference-mode' runs its auto-setup only if
`bug-reference-bug-regexp' and `bug-reference-url-format' are not
-set already. This function sets the latter to `nil'
+set already. This function sets the latter to nil
buffer-locally, so that the auto-setup will always run.
This is mostly intended for MUA modes like `rmail-mode' where the
diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el
index 9234d0b19b9..a26c1d5bff9 100644
--- a/lisp/progmodes/cc-align.el
+++ b/lisp/progmodes/cc-align.el
@@ -914,7 +914,7 @@ Works with: template-args-cont."
(defun c-lineup-ObjC-method-call (langelem)
"Line up selector args as Emacs Lisp mode does with function args:
Go to the position right after the message receiver, and if you are at
-the end of the line, indent the current line c-basic-offset columns
+the end of the line, indent the current line `c-basic-offset' columns
from the opening bracket; otherwise you are looking at the first
character of the first method call argument, so line up the current
line with it.
@@ -943,9 +943,9 @@ Works with: objc-method-call-cont."
(defun c-lineup-ObjC-method-call-colons (langelem)
"Line up selector args as Project Builder / XCode: colons of first
- selector portions on successive lines are aligned. If no decision can
- be made return NIL, so that other lineup methods can be tried. This is
- typically chained with `c-lineup-ObjC-method-call'.
+selector portions on successive lines are aligned. If no decision can
+be made return NIL, so that other lineup methods can be tried. This is
+typically chained with `c-lineup-ObjC-method-call'.
Works with: objc-method-call-cont."
(save-excursion
diff --git a/lisp/progmodes/cc-awk.el b/lisp/progmodes/cc-awk.el
index 334e82114fc..ea991017508 100644
--- a/lisp/progmodes/cc-awk.el
+++ b/lisp/progmodes/cc-awk.el
@@ -658,7 +658,7 @@
;; prevent a repeat invocation. See elisp/lispref page "Search-based
;; Fontification".
;;
- ;; This function gives invalid GAWK namepace separators (::)
+ ;; This function gives invalid GAWK namespace separators (::)
;; font-lock-warning-face. "Invalid" here means there are spaces, etc.,
;; around a separator, or there are more than one of them in an identifier.
;; Invalid separators inside function declaration parentheses are handled
@@ -1095,9 +1095,10 @@ std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\
"[#\n\r]"))))))))
(defun c-awk-beginning-of-defun (&optional arg)
- "Move backward to the beginning of an AWK \"defun\". With ARG, do it that
-many times. Negative arg -N means move forward to Nth following beginning of
-defun. Returns t unless search stops due to beginning or end of buffer.
+ "Move backward to the beginning of an AWK \"defun\".
+With ARG, do it that many times. Negative arg -N means move
+forward to Nth following beginning of defun. Returns t unless
+search stops due to beginning or end of buffer.
By a \"defun\" is meant either a pattern-action pair or a function. The start
of a defun is recognized as code starting at column zero which is neither a
diff --git a/lisp/progmodes/cc-bytecomp.el b/lisp/progmodes/cc-bytecomp.el
index edbac64eadb..b6805898b0e 100644
--- a/lisp/progmodes/cc-bytecomp.el
+++ b/lisp/progmodes/cc-bytecomp.el
@@ -339,8 +339,8 @@ should be a string. CONDITION should not be quoted."
'(progn)))
(defmacro cc-provide (feature)
- "A replacement for the `provide' form that restores the environment
-after the compilation. Don't use within `eval-when-compile'."
+ "A replacement for `provide' that restores the environment after the compilation.
+Don't use within `eval-when-compile'."
(declare (debug t))
`(progn
(eval-when-compile (cc-bytecomp-restore-environment))
@@ -381,8 +381,9 @@ afterwards. Don't use within `eval-when-compile'."
(eval-when-compile (cc-bytecomp-setup-environment))))
(defmacro cc-bytecomp-defvar (var)
- "Binds the symbol as a variable during compilation of the file,
-to silence the byte compiler. Don't use within `eval-when-compile'."
+ "Bind the symbol VAR as a variable during compilation of the file.
+This can be used to silence the byte compiler. Don't use within
+`eval-when-compile'."
(declare (debug nil))
`(eval-when-compile
(if (boundp ',var)
@@ -403,8 +404,9 @@ to silence the byte compiler. Don't use within `eval-when-compile'."
"cc-bytecomp-defvar: Covered variable %s" ',var))))))
(defmacro cc-bytecomp-defun (fun)
- "Bind the symbol as a function during compilation of the file,
-to silence the byte compiler. Don't use within `eval-when-compile'.
+ "Bind the symbol FUN as a function during compilation of the file.
+This can be used to silence the byte compiler. Don't use within
+`eval-when-compile'.
If the symbol already is bound as a function, it will keep that
definition. That means that this macro will not shut up warnings
@@ -431,8 +433,8 @@ at compile time, e.g. for macros and inline functions."
"cc-bytecomp-defun: Covered function %s" ',fun))))))
(defmacro cc-bytecomp-put (symbol propname value)
- "Set a property on a symbol during compilation (and evaluation) of
-the file. Don't use outside `eval-when-compile'."
+ "Set a property on SYMBOL during compilation (and evaluation) of the file.
+Don't use outside `eval-when-compile'."
(declare (debug t))
`(eval-when-compile
(if (not (assoc (cons ,symbol ,propname) cc-bytecomp-original-properties))
@@ -450,9 +452,9 @@ the file. Don't use outside `eval-when-compile'."
,propname ,symbol ,value)))
(defmacro cc-bytecomp-boundp (symbol)
- "Return non-nil if the given symbol is bound as a variable outside
-the compilation. This is the same as using `boundp' but additionally
-exclude any variables that have been bound during compilation with
+ "Return non-nil if SYMBOL is bound as a variable outside the compilation.
+This is the same as using `boundp' but additionally exclude any
+variables that have been bound during compilation with
`cc-bytecomp-defvar'."
(declare (debug t))
(if (and (cc-bytecomp-is-compiling)
@@ -461,9 +463,9 @@ exclude any variables that have been bound during compilation with
`(boundp ,symbol)))
(defmacro cc-bytecomp-fboundp (symbol)
- "Return non-nil if the given symbol is bound as a function outside
-the compilation. This is the same as using `fboundp' but additionally
-exclude any functions that have been bound during compilation with
+ "Return non-nil if SYMBOL is bound as a function outside the compilation.
+This is the same as using `fboundp' but additionally exclude any
+functions that have been bound during compilation with
`cc-bytecomp-defun'."
(declare (debug t))
(let (fun-elem)
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index bdfdf178d43..50249728048 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -64,7 +64,6 @@ point is used to decide where the old indentation is on a lines that
is otherwise empty (ignoring any line continuation backslash), but
that's not done if IGNORE-POINT-POS is non-nil. Returns the amount of
indentation change \(in columns)."
-
(let ((line-cont-backslash (save-excursion
(end-of-line)
(eq (char-before) ?\\)))
@@ -480,7 +479,7 @@ function to control that."
;; This function is only used in XEmacs.
(defun c-hungry-delete ()
- "Delete a non-whitespace char, or all whitespace up to the next non-whitespace char.
+ "Delete non-whitespace char, or all whitespace up to next non-whitespace char.
The direction of deletion depends on the configuration: If the
function `delete-forward-p' is defined and returns non-nil, it deletes
forward using `c-hungry-delete-forward'. Otherwise it deletes
@@ -497,7 +496,7 @@ function to control that."
(defvar c--unsafe-post-self-insert-hook-functions
'(electric-pair-post-self-insert-function)
- "Known unsafe functions when members of `post-self-insert-hook' in CC Mode")
+ "Known unsafe functions when members of `post-self-insert-hook' in CC Mode.")
(defun c--call-post-self-insert-hook-more-safely-1 ()
;; Call post-self-insert-hook, having removed from `post-self-insert-hook'
@@ -1897,16 +1896,18 @@ defun."
(if (< arg 0)
(c-while-widening-to-decl-block
(< (setq arg (- (c-forward-to-nth-EOF-\;-or-} (- arg) where))) 0)))
- ;; Move forward to the next opening brace....
- (when (and (= arg 0)
- (progn
- (c-while-widening-to-decl-block
- (not (c-syntactic-re-search-forward "{" nil 'eob)))
- (eq (char-before) ?{)))
- (backward-char)
- ;; ... and backward to the function header.
- (c-beginning-of-decl-1)
- t))
+ (prog1
+ ;; Move forward to the next opening brace....
+ (when (and (= arg 0)
+ (progn
+ (c-while-widening-to-decl-block
+ (not (c-syntactic-re-search-forward "{" nil 'eob)))
+ (eq (char-before) ?{)))
+ (backward-char)
+ ;; ... and backward to the function header.
+ (c-beginning-of-decl-1)
+ t)
+ (c-keep-region-active)))
;; Move backward to the opening brace of a function, making successively
;; larger portions of the buffer visible as necessary.
@@ -2058,9 +2059,9 @@ the open-parenthesis that starts a defun; see `beginning-of-defun'."
(= arg 0))))
(defun c-defun-name-1 ()
- "Return the name of the current defun, at the current narrowing,
-or NIL if there isn't one. \"Defun\" here means a function, or
-other top level construct with a brace block."
+ "Return name of current defun, at current narrowing, or nil if there isn't one.
+\"Defun\" here means a function, or other top level construct
+with a brace block."
(c-save-buffer-state
(beginning-of-defun-function end-of-defun-function
where pos decl0 decl type-pos tag-pos case-fold-search)
@@ -3383,12 +3384,12 @@ directives."
(defun c-backward-conditional (count &optional target-depth with-else)
"Move back across a preprocessor conditional, leaving mark behind.
-A prefix argument acts as a repeat count. With a negative argument,
+A prefix argument acts as a repeat COUNT. With a negative argument,
move forward across a preprocessor conditional.
The optional arguments TARGET-DEPTH and WITH-ELSE are historical,
and have the same meanings as in `c-scan-conditionals'. If you
-are calling c-forward-conditional from a program, you might want
+are calling `c-forward-conditional' from a program, you might want
to call `c-scan-conditionals' directly instead."
(interactive "p")
(let ((new-point (c-scan-conditionals (- count) target-depth with-else)))
@@ -3414,7 +3415,8 @@ to call `c-scan-conditionals' directly instead."
(interactive "p")
(let ((new-point (c-scan-conditionals count target-depth with-else)))
(push-mark)
- (goto-char new-point)))
+ (goto-char new-point))
+ (c-keep-region-active))
(defun c-scan-conditionals (count &optional target-depth with-else)
"Scan forward across COUNT preprocessor conditionals.
@@ -3655,9 +3657,9 @@ continuation backslashes, unless `c-auto-align-backslashes' is nil."
(set-marker here nil))))
(defun c-indent-region (start end &optional quiet)
- "Indent syntactically every line whose first char is between START
-and END inclusive. If the optional argument QUIET is non-nil then no
-syntactic errors are reported, even if `c-report-syntactic-errors' is
+ "Indent syntactically lines whose first char is between START and END inclusive.
+If the optional argument QUIET is non-nil then no syntactic
+errors are reported, even if `c-report-syntactic-errors' is
non-nil."
(save-excursion
(goto-char end)
@@ -5113,8 +5115,9 @@ inside a preprocessor directive."
(defun c-context-open-line ()
"Insert a line break suitable to the context and leave point before it.
-This is the `c-context-line-break' equivalent to `open-line', which is
-normally bound to C-o. See `c-context-line-break' for the details."
+This is the `c-context-line-break' equivalent to `open-line'
+\(bound to \\[open-line]). See `c-context-line-break' for the
+details."
(interactive "*")
(let ((here (point)))
(unwind-protect
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index 01bd64cb5c3..12e10c26eec 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -234,6 +234,14 @@ On XEmacs and older Emacsen, this refontifies that region immediately."
`(font-lock-flush ,beg ,end)
`(font-lock-fontify-region ,beg ,end)))
+(defmacro c-benign-error (format &rest args)
+ ;; Formats an error message for the echo area and dings, i.e. like
+ ;; `error' but doesn't abort.
+ (declare (debug t))
+ `(progn
+ (message ,format ,@args)
+ (ding)))
+
(defmacro c-point (position &optional point)
"Return the value of certain commonly referenced POSITIONs relative to POINT.
The current point is used if POINT isn't specified. POSITION can be
@@ -660,19 +668,27 @@ even when the buffer is read-only, and without interference from
various buffer change hooks."
(declare (indent 0) (debug t))
`(let (-tnt-chng-keep
- -tnt-chng-state)
+ -tnt-chng-state
+ (old-undo-list buffer-undo-list))
(unwind-protect
;; Insert an undo boundary for use with `undo-more'. We
;; don't use `undo-boundary' since it doesn't insert one
;; unconditionally.
- (setq buffer-undo-list (cons nil buffer-undo-list)
- -tnt-chng-state (c-tnt-chng-record-state)
+ (setq buffer-undo-list
+ (if (eq old-undo-list t)
+ nil
+ (cons nil buffer-undo-list))
+ old-undo-list (if (eq old-undo-list t)
+ t
+ buffer-undo-list)
+ -tnt-chng-state (c-tnt-chng-record-state
+ old-undo-list)
-tnt-chng-keep (progn ,@body))
(c-tnt-chng-cleanup -tnt-chng-keep -tnt-chng-state))))
-(defun c-tnt-chng-record-state ()
+(defun c-tnt-chng-record-state (old-undo-list)
;; Used internally in `c-tentative-buffer-changes'.
- (vector buffer-undo-list ; 0
+ (vector old-undo-list ; 0
(current-buffer) ; 1
;; No need to use markers for the point and mark; if the
;; undo got out of synch we're hosed anyway.
@@ -690,18 +706,26 @@ various buffer change hooks."
(setq buffer-undo-list (cdr saved-undo-list))
(if keep
- ;; Find and remove the undo boundary.
- (let ((p buffer-undo-list))
- (while (not (eq (cdr p) saved-undo-list))
- (setq p (cdr p)))
- (setcdr p (cdr saved-undo-list)))
-
- ;; `primitive-undo' will remove the boundary.
- (setq saved-undo-list (cdr saved-undo-list))
- (let ((undo-in-progress t))
- (while (not (eq (setq buffer-undo-list
- (primitive-undo 1 buffer-undo-list))
- saved-undo-list))))
+ (if (eq saved-undo-list t)
+ (progn
+ (c-benign-error
+ "Can't save additional undo list in c-tnt-chng-cleanup")
+ (setq buffer-undo-list t))
+ ;; Find and remove the undo boundary.
+ (let ((p buffer-undo-list))
+ (while (not (eq (cdr p) saved-undo-list))
+ (setq p (cdr p)))
+ (setcdr p (cdr saved-undo-list))))
+
+ (let ((undo-in-progress t)
+ (end-undo-list (if (eq saved-undo-list t)
+ nil
+ ;; `primitive-undo' will remove the boundary.
+ (cdr saved-undo-list))))
+ (while (not (eq buffer-undo-list end-undo-list))
+ (setq buffer-undo-list (primitive-undo 1 buffer-undo-list))))
+ (if (eq saved-undo-list t)
+ (setq buffer-undo-list t))
(when (buffer-live-p (elt saved-state 1))
(set-buffer (elt saved-state 1))
@@ -803,9 +827,9 @@ right side of it."
;; impossible to get a feel for how that function works.
(defmacro c-go-list-forward (&optional pos limit)
- "Move forward across one balanced group of parentheses starting at POS or
-point. Return POINT when we succeed, NIL when we fail. In the latter case,
-leave point unmoved.
+ "Move forward across one balanced group of parentheses starting at POS or point.
+Return POINT when we succeed, NIL when we fail. In the latter
+case, leave point unmoved.
A LIMIT for the search may be given. The start position is assumed to be
before it."
@@ -814,9 +838,9 @@ before it."
(when dest (goto-char dest) dest)))
(defmacro c-go-list-backward (&optional pos limit)
- "Move backward across one balanced group of parentheses starting at POS or
-point. Return POINT when we succeed, NIL when we fail. In the latter case,
-leave point unmoved.
+ "Move backward across one balanced group of parentheses starting at POS or point.
+Return POINT when we succeed, NIL when we fail. In the latter
+case, leave point unmoved.
A LIMIT for the search may be given. The start position is assumed to be
after it."
@@ -1027,14 +1051,6 @@ be after it."
'(if c-vsemi-status-unknown-p-fn (funcall c-vsemi-status-unknown-p-fn)))
-(defmacro c-benign-error (format &rest args)
- ;; Formats an error message for the echo area and dings, i.e. like
- ;; `error' but doesn't abort.
- (declare (debug t))
- `(progn
- (message ,format ,@args)
- (ding)))
-
(defmacro c-with-syntax-table (table &rest code)
;; Temporarily switches to the specified syntax table in a failsafe
;; way to execute code.
@@ -1369,7 +1385,7 @@ point is then left undefined."
"Remove all text-properties PROPERTY from the region (FROM, TO)
which have the value VALUE, as tested by `equal'. These
properties are assumed to be over individual characters, having
-been put there by c-put-char-property. POINT remains unchanged."
+been put there by `c-put-char-property'. POINT remains unchanged."
(let ((place from) end-place)
(while ; loop round occurrences of (PROPERTY VALUE)
(progn
@@ -1390,7 +1406,7 @@ been put there by c-put-char-property. POINT remains unchanged."
"Remove all text-properties PROPERTY from the region [FROM, TO)
which have the value VALUE, as tested by `equal'. These
properties are assumed to be over individual characters, having
-been put there by c-put-char-property. POINT remains unchanged."
+been put there by `c-put-char-property'. POINT remains unchanged."
(declare (debug t))
(if c-use-extents
;; XEmacs
@@ -2577,7 +2593,7 @@ quoted."
(defvar c-lang-constants-under-evaluation nil
"Alist of constants in the process of being evaluated.
The `cdr' of each entry indicates how far we've looked in the list
-of definitions, so that the def for var FOO in c-mode can be defined in
+of definitions, so that the def for var FOO in `c-mode' can be defined in
terms of the def for that same var FOO (which will then rely on the
fallback definition for all modes, to break the cycle).")
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 5d2e41ae575..d37a50997ad 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -165,12 +165,16 @@
(defvar c-doc-line-join-end-ch)
(defvar c-syntactic-context)
(defvar c-syntactic-element)
+(defvar c-new-id-start)
+(defvar c-new-id-end)
+(defvar c-new-id-is-type)
(cc-bytecomp-defvar c-min-syn-tab-mkr)
(cc-bytecomp-defvar c-max-syn-tab-mkr)
(cc-bytecomp-defun c-clear-syn-tab)
(cc-bytecomp-defun c-clear-string-fences)
(cc-bytecomp-defun c-restore-string-fences)
(cc-bytecomp-defun c-remove-string-fences)
+(cc-bytecomp-defun c-fontify-new-found-type)
;; Make declarations for all the `c-lang-defvar' variables in cc-langs.
@@ -1545,7 +1549,7 @@ comment at the start of cc-engine.el for more info."
nil))))))
(defun c-at-statement-start-p ()
- "Return non-nil if the point is at the first token in a statement
+ "Return non-nil if point is at the first token in a statement
or somewhere in the syntactic whitespace before it.
A \"statement\" here is not restricted to those inside code blocks.
@@ -1574,7 +1578,7 @@ comment at the start of cc-engine.el for more info."
(c-crosses-statement-barrier-p (point) end)))))
(defun c-at-expression-start-p ()
- "Return non-nil if the point is at the first token in an expression or
+ "Return non-nil if point is at the first token in an expression or
statement, or somewhere in the syntactic whitespace before it.
An \"expression\" here is a bit different from the normal language
@@ -1731,7 +1735,7 @@ Line continuations, i.e. a backslashes followed by line breaks, are
treated as whitespace. The line breaks that end line comments are
considered to be the comment enders, so the point cannot be at the end
of the same line to move over a line comment. Unlike
-c-backward-syntactic-ws, this function doesn't move back over
+`c-backward-syntactic-ws', this function doesn't move back over
preprocessor directives.
Note that this function might do hidden buffer changes. See the
@@ -3210,7 +3214,7 @@ comment at the start of cc-engine.el for more info."
This function should be added to the `before-change-functions'
hook by major modes that use CC Mode's filling functionality
without initializing CC Mode. Currently (2020-06) these are
-js-mode and mhtml-mode."
+`js-mode' and `mhtml-mode'."
(c-truncate-lit-pos-cache beg))
(defun c-foreign-init-lit-pos-cache ()
@@ -3218,8 +3222,8 @@ js-mode and mhtml-mode."
This function should be called from the mode functions of major
modes which use CC Mode's filling functionality without
-initializing CC Mode. Currently (2020-06) these are js-mode and
-mhtml-mode."
+initializing CC Mode. Currently (2020-06) these are `js-mode' and
+`mhtml-mode'."
(c-truncate-lit-pos-cache 1))
@@ -4969,7 +4973,7 @@ out of an enclosing paren."
nil))))
(defun c-forward-over-token-and-ws (&optional balanced)
- "Move forward over a token and any following whitespace
+ "Move forward over a token and any following whitespace.
Return t if we moved, nil otherwise (i.e. we were at EOB, or a
non-token or BALANCED is non-nil and we can't move). If we
are at syntactic whitespace, move over this in place of a token.
@@ -5384,8 +5388,8 @@ comment at the start of cc-engine.el for more info."
(defvar safe-pos-list) ; bound in c-syntactic-skip-backward
(defun c-syntactic-skip-backward (skip-chars &optional limit paren-level)
- "Like `skip-chars-backward' but only look at syntactically relevant chars,
-i.e. don't stop at positions inside syntactic whitespace or string
+ "Like `skip-chars-backward' but only look at syntactically relevant chars.
+This means don't stop at positions inside syntactic whitespace or string
literals. Preprocessor directives are also ignored, with the exception
of the one that the point starts within, if any. If LIMIT is given,
it's assumed to be at a syntactically relevant position.
@@ -6808,26 +6812,47 @@ comment at the start of cc-engine.el for more info."
(defvar c-found-types nil)
(make-variable-buffer-local 'c-found-types)
+;; Dynamically bound variable that instructs `c-forward-type' to
+;; record the ranges of types that only are found. Behaves otherwise
+;; like `c-record-type-identifiers'. Also when this variable is non-nil,
+;; `c-fontify-new-found-type' doesn't get called (yet) for the purported
+;; type.
+(defvar c-record-found-types nil)
+
(defsubst c-clear-found-types ()
;; Clears `c-found-types'.
(setq c-found-types
(make-hash-table :test #'equal :weakness nil)))
-(defun c-add-type (from to)
- ;; Add the given region as a type in `c-found-types'. If the region
- ;; doesn't match an existing type but there is a type which is equal
- ;; to the given one except that the last character is missing, then
- ;; the shorter type is removed. That's done to avoid adding all
- ;; prefixes of a type as it's being entered and font locked. This
- ;; doesn't cover cases like when characters are removed from a type
- ;; or added in the middle. We'd need the position of point when the
- ;; font locking is invoked to solve this well.
+(defun c-add-type-1 (from to)
+ ;; Add the given region as a type in `c-found-types'. Prepare occurrences
+ ;; of this new type for fontification throughout the buffer.
;;
;; This function might do hidden buffer changes.
(let ((type (c-syntactic-content from to c-recognize-<>-arglists)))
(unless (gethash type c-found-types)
- (remhash (substring type 0 -1) c-found-types)
- (puthash type t c-found-types))))
+ (puthash type t c-found-types)
+ (when (and (not c-record-found-types) ; Only call `c-fontify-new-fount-type'
+ ; when we haven't "bound" c-found-types
+ ; to itself in c-forward-<>-arglist.
+ (eq (string-match c-symbol-key type) 0)
+ (eq (match-end 0) (length type)))
+ (c-fontify-new-found-type type)))))
+
+(defun c-add-type (from to)
+ ;; Add the given region as a type in `c-found-types'. Also perform the
+ ;; actions of `c-add-type-1'. If the region is or overlaps an identifier
+ ;; which might be being typed in, don't record it. This is tested by
+ ;; checking `c-new-id-start' and `c-new-id-end'. That's done to avoid
+ ;; adding all prefixes of a type as it's being entered and font locked.
+ ;; This is a bit rough and ready, but now covers adding characters into the
+ ;; middle of an identifer.
+ ;;
+ ;; This function might do hidden buffer changes.
+ (if (and c-new-id-start c-new-id-end
+ (<= from c-new-id-end) (>= to c-new-id-start))
+ (setq c-new-id-is-type t)
+ (c-add-type-1 from to)))
(defun c-unfind-type (name)
;; Remove the "NAME" from c-found-types, if present.
@@ -7223,7 +7248,7 @@ comment at the start of cc-engine.el for more info."
;; the rest of the file is fontified normally.
(defun c-ml-string-make-closer-re (_opener)
- "Return c-ml-string-any-closer-re.
+ "Return `c-ml-string-any-closer-re'.
This is a suitable language specific value of
`c-make-ml-string-closer-re-function' for most languages with
@@ -7231,7 +7256,7 @@ multi-line strings (but not C++, for example)."
c-ml-string-any-closer-re)
(defun c-ml-string-make-opener-re (_closer)
- "Return c-ml-string-opener-re.
+ "Return `c-ml-string-opener-re'.
This is a suitable language specific value of
`c-make-ml-string-opener-re-function' for most languages with
@@ -7422,7 +7447,7 @@ multi-line strings (but not C++, for example)."
t)
(save-excursion
(goto-char (match-end 1))
- (if (c-in-literal) ; a psuedo closer.
+ (if (c-in-literal) ; a pseudo closer.
t
(setq saved-match-data (match-data))
(setq found t)
@@ -8210,11 +8235,6 @@ multi-line strings (but not C++, for example)."
(setq c-record-ref-identifiers
(cons range c-record-ref-identifiers))))))
-;; Dynamically bound variable that instructs `c-forward-type' to
-;; record the ranges of types that only are found. Behaves otherwise
-;; like `c-record-type-identifiers'.
-(defvar c-record-found-types nil)
-
(defmacro c-forward-keyword-prefixed-id (type)
;; Used internally in `c-forward-keyword-clause' to move forward
;; over a type (if TYPE is 'type) or a name (otherwise) which
@@ -8444,6 +8464,11 @@ multi-line strings (but not C++, for example)."
(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.
@@ -9169,6 +9194,12 @@ multi-line strings (but not C++, for example)."
(when (and (eq res t)
(consp c-record-found-types))
+ ;; Cause the confirmed types to get fontified.
+ (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))))
;; Merge in the ranges of any types found by the second
;; `c-forward-type'.
(setq c-record-type-identifiers
@@ -9978,7 +10009,12 @@ This function might do hidden buffer changes."
(save-excursion
(goto-char type-start)
(let ((c-promote-possible-types t))
- (c-forward-type)))))
+ (c-forward-type))))
+
+ ;; Signal a type declaration for "struct foo {".
+ (when (and backup-at-type-decl
+ (eq (char-after) ?{))
+ (setq at-type-decl t)))
(setq backup-at-type at-type
backup-type-start type-start
@@ -10409,6 +10445,7 @@ This function might do hidden buffer changes."
;; are directly inside a class (etc.) called "bar".
(save-excursion
(and
+ type-start
(progn
(goto-char name-start)
(not (memq (c-forward-type) '(nil maybe))))
@@ -12086,7 +12123,10 @@ comment at the start of cc-engine.el for more info."
(and (c-major-mode-is 'pike-mode)
c-decl-block-key)))
(while (eq braceassignp 'dontknow)
- (cond ((eq (char-after) ?\;)
+ (cond ((or (eq (char-after) ?\;)
+ (save-excursion
+ (progn (c-backward-syntactic-ws)
+ (c-at-vsemi-p))))
(setq braceassignp nil))
((and class-key
(looking-at class-key))
@@ -12288,12 +12328,15 @@ comment at the start of cc-engine.el for more info."
pos2 in-paren parens-before-brace
paren-state paren-pos)
- (setq res (c-backward-token-2 1 t lim))
+ (setq res
+ (or (progn (c-backward-syntactic-ws)
+ (c-back-over-compound-identifier))
+ (c-backward-token-2 1 t lim)))
;; Checks to do only on the first sexp before the brace.
;; Have we a C++ initialization, without an "="?
(if (and (c-major-mode-is 'c++-mode)
(cond
- ((and (or (not (eq res 0))
+ ((and (or (not (memq res '(t 0)))
(eq (char-after) ?,))
(setq paren-state (c-parse-state))
(setq paren-pos (c-pull-open-brace paren-state))
@@ -12317,7 +12360,7 @@ comment at the start of cc-engine.el for more info."
(t nil))
(save-excursion
(cond
- ((or (not (eq res 0))
+ ((or (not (memq res '(t 0)))
(eq (char-after) ?,))
(and (setq paren-state (c-parse-state))
(setq paren-pos (c-pull-open-brace paren-state))
@@ -14007,7 +14050,8 @@ comment at the start of cc-engine.el for more info."
;; clause - we assume only C++ needs it.
(c-syntactic-skip-backward "^;,=" lim t))
(setq placeholder (point))
- (memq (char-before) '(?, ?= ?<)))
+ (and (memq (char-before) '(?, ?= ?<))
+ (not (c-crosses-statement-barrier-p (point) indent-point))))
(cond
;; CASE 5D.6: Something like C++11's "using foo = <type-exp>"
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 7e7053b98e1..967464ac14d 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -93,10 +93,15 @@
(cc-bytecomp-defvar c-preprocessor-face-name)
(cc-bytecomp-defvar c-reference-face-name)
(cc-bytecomp-defvar c-block-comment-flag)
+(cc-bytecomp-defvar c-type-finder-pos)
+(cc-bytecomp-defvar c-inhibit-type-finder)
+(cc-bytecomp-defvar c-type-finder-timer)
(cc-bytecomp-defun c-fontify-recorded-types-and-refs)
(cc-bytecomp-defun c-font-lock-declarators)
(cc-bytecomp-defun c-font-lock-objc-method)
(cc-bytecomp-defun c-font-lock-invalid-string)
+(cc-bytecomp-defun c-before-context-fl-expand-region)
+(cc-bytecomp-defun c-font-lock-fontify-region)
;; Note that font-lock in XEmacs doesn't expand face names as
@@ -919,13 +924,6 @@ casts and declarations are fontified. Used on level 2 and higher."
;; This function does hidden buffer changes.
;;(message "c-font-lock-complex-decl-prepare %s %s" (point) limit)
-
- ;; Clear the list of found types if we start from the start of the
- ;; buffer, to make it easier to get rid of misspelled types and
- ;; variables that have gotten recognized as types in malformed code.
- (when (bobp)
- (c-clear-found-types))
-
(c-skip-comments-and-strings limit)
(when (< (point) limit)
@@ -1605,6 +1603,175 @@ casts and declarations are fontified. Used on level 2 and higher."
nil))))
+(defun c-find-types-background (start limit)
+ ;; Find any "found types" between START and LIMIT. Allow any such types to
+ ;; be entered into `c-found-types' by the action of `c-forward-name' or
+ ;; `c-forward-type' called from this function. This process also causes
+ ;; occurrences of the type to be prepared for fontification throughout the
+ ;; buffer.
+ ;;
+ ;; Return POINT at the end of the function. This should be at or after
+ ;; LIMIT, and not later than the next decl-spot after LIMIT.
+ ;;
+ ;; This function is called from the timer `c-type-finder-timer'. It may do
+ ;; hidden buffer changes.
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char start)
+ ;; If we're in a (possibly large) literal, skip over it.
+ (let ((lit-bounds (nth 2 (c-full-pp-to-literal (point)))))
+ (if lit-bounds
+ (goto-char (cdr lit-bounds))))
+ (when (< (point) limit)
+ (let (;; o - 'decl if we're in an arglist containing declarations
+ ;; (but if `c-recognize-paren-inits' is set it might also be
+ ;; an initializer arglist);
+ ;; o - '<> if the arglist is of angle bracket type;
+ ;; o - 'arglist if it's some other arglist;
+ ;; o - nil, if not in an arglist at all. This includes the
+ ;; parenthesized condition which follows "if", "while", etc.
+ context
+ ;; A list of starting positions of possible type declarations, or of
+ ;; the typedef preceding one, if any.
+ last-cast-end
+ ;; The result from `c-forward-decl-or-cast-1'.
+ decl-or-cast
+ ;; The maximum of the end positions of all the checked type
+ ;; decl expressions in the successfully identified
+ ;; declarations. The position might be either before or
+ ;; after the syntactic whitespace following the last token
+ ;; in the type decl expression.
+ (max-type-decl-end 0)
+ ;; Same as `max-type-decl-*', but used when we're before
+ ;; `token-pos'.
+ (max-type-decl-end-before-token 0)
+ )
+ (goto-char start)
+ (c-find-decl-spots
+ limit
+ c-decl-start-re
+ nil ; (eval c-maybe-decl-faces)
+
+ (lambda (match-pos inside-macro &optional toplev)
+ ;; Note to maintainers: don't use `limit' inside this lambda form;
+ ;; c-find-decl-spots sometimes narrows to less than `limit'.
+ (if (and c-macro-with-semi-re
+ (looking-at c-macro-with-semi-re))
+ ;; Don't do anything more if we're looking at something that
+ ;; can't start a declaration.
+ t
+
+ ;; Set `context' and `c-restricted-<>-arglists'. Look for
+ ;; "<" for the sake of C++-style template arglists.
+ ;; "Ignore "(" when it's part of a control flow construct
+ ;; (e.g. "for (").
+ (let ((got-context
+ (c-get-fontification-context
+ match-pos
+ (< match-pos (if inside-macro
+ max-type-decl-end-before-token
+ max-type-decl-end))
+ toplev)))
+ (setq context (car got-context)
+ c-restricted-<>-arglists (cdr got-context)))
+
+ ;; In QT, "more" is an irritating keyword that expands to nothing.
+ ;; We skip over it to prevent recognition of "more slots: <symbol>"
+ ;; as a bitfield declaration.
+ (when (and (c-major-mode-is 'c++-mode)
+ (looking-at
+ (concat "\\(more\\)\\([^" c-symbol-chars "]\\|$\\)")))
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws))
+
+ ;; Now analyze the construct. This analysis will cause
+ ;; `c-forward-name' and `c-forward-type' to call `c-add-type',
+ ;; triggering the desired recognition and fontification of
+ ;; these found types.
+ (when (not (eq context 'not-decl))
+ (setq decl-or-cast
+ (c-forward-decl-or-cast-1
+ match-pos context last-cast-end))
+
+ (cond
+ ((eq decl-or-cast 'cast)
+ ;; Save the position after the previous cast so we can feed
+ ;; it to `c-forward-decl-or-cast-1' in the next round. That
+ ;; helps it discover cast chains like "(a) (b) c".
+ (setq last-cast-end (point))
+ nil)
+ (decl-or-cast
+ ;; We've found a declaration.
+
+ ;; Set `max-type-decl-end' or `max-type-decl-end-before-token'
+ ;; under the assumption that we're after the first type decl
+ ;; expression in the declaration now. That's not really true;
+ ;; we could also be after a parenthesized initializer
+ ;; expression in C++, but this is only used as a last resort
+ ;; to slant ambiguous expression/declarations, and overall
+ ;; it's worth the risk to occasionally fontify an expression
+ ;; as a declaration in an initializer expression compared to
+ ;; getting ambiguous things in normal function prototypes
+ ;; fontified as expressions.
+ (if inside-macro
+ (when (> (point) max-type-decl-end-before-token)
+ (setq max-type-decl-end-before-token (point)))
+ (when (> (point) max-type-decl-end)
+ (setq max-type-decl-end (point)))))
+ (t t))))))))
+ (point))))
+
+(defun c-type-finder-timer-func ()
+ ;; A CC Mode idle timer function for finding "found types". It triggers
+ ;; every `c-type-finder-repeat-time' seconds and processes buffer chunks of
+ ;; size around `c-type-finder-chunk-size' characters, and runs for (a little
+ ;; over) `c-type-finder-time-slot' seconds. The types it finds are inserted
+ ;; into `c-found-types', and their occurrences throughout the buffer are
+ ;; prepared for fontification.
+ (when (and c-type-finder-time-slot
+ (boundp 'font-lock-support-mode)
+ (eq font-lock-support-mode 'jit-lock-mode))
+ (if c-inhibit-type-finder ; No processing immediately after a GC operation.
+ (setq c-inhibit-type-finder nil)
+ (let* ((stop-time (+ (float-time) c-type-finder-time-slot))
+ (buf-list (buffer-list)))
+ ;; One CC Mode buffer needing processing each time around this loop.
+ (while (and buf-list
+ (< (float-time) stop-time))
+ ;; Cdr through BUF-LIST to find the next buffer needing processing.
+ (while (and buf-list
+ (not (with-current-buffer (car buf-list) c-type-finder-pos)))
+ (setq buf-list (cdr buf-list)))
+ (when buf-list
+ (with-current-buffer (car buf-list)
+ ;; (message "%s" (current-buffer)) ; Useful diagnostic.
+ (save-restriction
+ (widen)
+ ;; Process one `c-type-finder-chunk-size' chunk each time
+ ;; around this loop.
+ (while (and c-type-finder-pos
+ (< (float-time) stop-time))
+ ;; Process one chunk per iteration.
+ (save-match-data
+ (c-save-buffer-state
+ (case-fold-search
+ (beg (marker-position c-type-finder-pos))
+ (end (min (+ beg c-type-finder-chunk-size) (point-max)))
+ (region (c-before-context-fl-expand-region beg end)))
+ (setq beg (car region)
+ end (cdr region))
+ (setq beg (max (c-find-types-background beg end) end))
+ (move-marker c-type-finder-pos
+ (if (save-excursion (goto-char beg) (eobp))
+ nil
+ beg))
+ (when (not (marker-position c-type-finder-pos))
+ (setq c-type-finder-pos nil))))))))))))
+ ;; Set the timer to run again.
+ (setq c-type-finder-timer
+ (run-at-time c-type-finder-repeat-time nil #'c-type-finder-timer-func)))
+
(defun c-font-lock-enum-body (limit)
;; Fontify the identifiers of each enum we find by searching forward.
;;
@@ -1765,7 +1932,7 @@ casts and declarations are fontified. Used on level 2 and higher."
(> (match-beginning 0) (point-min))
(memq (c-get-char-property (1- (match-beginning 0)) 'face)
'(font-lock-comment-face font-lock-string-face
- font-lock-comment-delimiter-face))))
+ font-lock-comment-delimiter-face))))
(when found
(setq open-delim (cons (match-beginning 1)
(cons (match-end 1) (match-beginning 2)))
@@ -2255,6 +2422,47 @@ higher."
;; defvar will install its default value later on.
(makunbound def-var)))
+;; `c-re-redisplay-timer' is a timer which, when triggered, causes a
+;; redisplay.
+(defvar c-re-redisplay-timer nil)
+
+(defun c-force-redisplay (start end)
+ ;; Force redisplay immediately. This assumes `font-lock-support-mode' is
+ ;; 'jit-lock-mode. Set the variable `c-re-redisplay-timer' to nil.
+ (save-excursion (c-font-lock-fontify-region start end))
+ (jit-lock-force-redisplay (copy-marker start) (copy-marker end))
+ (setq c-re-redisplay-timer nil))
+
+(defun c-fontify-new-found-type (type)
+ ;; Cause the fontification of TYPE, a string, wherever it occurs in the
+ ;; buffer. If TYPE is currently displayed in a window, cause redisplay to
+ ;; happen "instantaneously". These actions are done only when jit-lock-mode
+ ;; is active.
+ (when (and font-lock-mode
+ (boundp 'font-lock-support-mode)
+ (eq font-lock-support-mode 'jit-lock-mode))
+ (c-save-buffer-state
+ ((window-boundaries
+ (mapcar (lambda (win)
+ (cons (window-start win)
+ (window-end win)))
+ (get-buffer-window-list (current-buffer) 'no-mini t)))
+ (target-re (concat "\\_<" type "\\_>")))
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (while (re-search-forward target-re nil t)
+ (put-text-property (match-beginning 0) (match-end 0)
+ 'fontified nil)
+ (dolist (win-boundary window-boundaries)
+ (when (and (< (match-beginning 0) (cdr win-boundary))
+ (> (match-end 0) (car win-boundary))
+ (not c-re-redisplay-timer))
+ (setq c-re-redisplay-timer
+ (run-with-timer 0 nil #'c-force-redisplay
+ (match-beginning 0) (match-end 0)))))))))))
+
;;; C.
diff --git a/lisp/progmodes/cc-guess.el b/lisp/progmodes/cc-guess.el
index 9c88c14a6c1..8f46b17c54d 100644
--- a/lisp/progmodes/cc-guess.el
+++ b/lisp/progmodes/cc-guess.el
@@ -34,18 +34,18 @@
;; are some variants.
;;
;; Suppose the major mode for the current buffer is one of the modes
-;; provided by cc-mode. `c-guess' guesses the indentation style by
+;; provided by cc-mode. `c-guess' guesses the indentation style by
;; examining the indentation in the region between beginning of buffer
;; and `c-guess-region-max'.
-;; and installs the guessed style. The name for installed style is given
+;; and installs the guessed style. The name for installed style is given
;; by `c-guess-style-name'.
;;
;; `c-guess-buffer' does the same but in the whole buffer.
;; `c-guess-region' does the same but in the region between the point
;; and the mark. `c-guess-no-install', `c-guess-buffer-no-install'
;; and `c-guess-region-no-install' guess the indentation style but
-;; don't install it. You can review a guessed style with `c-guess-view'.
+;; don't install it. You can review a guessed style with `c-guess-view'.
;; After reviewing, use `c-guess-install' to install the style
;; if you prefer it.
;;
@@ -56,11 +56,11 @@
;; or implicitly with `c-guess', `c-guess-buffer', or `c-guess-region',
;; a style name is given by `c-guess-style-name' with the above form.
;;
-;; If you want to reuse the guessed style in future emacs sessions,
-;; you may want to put it to your .emacs. `c-guess-view' is for
-;; you. It emits Emacs Lisp code which defines the last guessed
-;; style, in a temporary buffer. You can put the emitted code into
-;; your .emacs. This command was suggested by Alan Mackenzie.
+;; If you want to reuse the guessed style in future Emacs sessions,
+;; you may want to put it to your .emacs. `c-guess-view' is for
+;; you. It emits Emacs Lisp code which defines the last guessed
+;; style, in a temporary buffer. You can put the emitted code into
+;; your .emacs. This command was suggested by Alan Mackenzie.
;;; Code:
@@ -91,7 +91,7 @@ The offset of a line included in the indent information returned by
(defcustom c-guess-region-max 50000
"The maximum region size for examining indent information with `c-guess'.
It takes a long time to examine indent information from a large region;
-this option helps you limit that time. nil means no limit."
+this option helps you limit that time. nil means no limit."
:version "24.1"
:type 'integer
:group 'c)
@@ -465,7 +465,7 @@ the absolute file name of the file if STYLE-NAME is nil."
(defun c-guess-dump-guessed-style (&optional printer)
"Show the guessed style.
`pp' is used to print the style but if PRINTER is given,
-PRINTER is used instead. If PRINTER is not nil, it
+PRINTER is used instead. If PRINTER is not nil, it
is called with one argument, the guessed style."
(interactive)
(let ((style (c-guess-make-style c-guess-guessed-basic-offset
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 0b125bc43fa..53f6206a821 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -151,10 +151,10 @@
c-emacs-variable-inits-tail c-emacs-variable-inits))
(defmacro c-lang-defvar (var val &optional doc)
- "Declares the buffer local variable VAR to get the value VAL. VAL is
-evaluated and assigned at mode initialization. More precisely, VAL is
-evaluated and bound to VAR when the result from the macro
-`c-init-language-vars' is evaluated.
+ "Declares the buffer local variable VAR to get the value VAL.
+VAL is evaluated and assigned at mode initialization. More
+precisely, VAL is evaluated and bound to VAR when the result from
+the macro `c-init-language-vars' is evaluated.
`c-lang-const' is typically used in VAL to get the right value for the
language being initialized, and such calls will be macro expanded to
@@ -184,8 +184,8 @@ the evaluated constant value at compile time."
`',var)
(defmacro c-lang-setvar (var val)
- "Causes the variable VAR to be made buffer local and to get set to the
-value VAL. VAL is evaluated and assigned at mode initialization. More
+ "Make variable VAR buffer local and set it to value VAL.
+VAL is evaluated and assigned at mode initialization. More
precisely, VAL is evaluated and bound to VAR when the result from the
macro `c-init-language-vars' is evaluated. VAR is typically a standard
Emacs variable like `comment-start'.
@@ -680,7 +680,7 @@ A search for this regexp starting at the end of the corresponding
opener must find the first closer as the first match.
Such a closer must include a \" character. (match-string 1)
-matches the actual delimiter and and (match-string 2) matches the
+matches the actual delimiter and (match-string 2) matches the
actual \". If a delimiter contains several \"s, it is
recommended to regard the last of them as \"the\" \"."
t nil
@@ -4178,8 +4178,7 @@ aliases in Emacs are resolved."
(cdr c-emacs-variable-inits))))
(defun c-make-init-lang-vars-fun (mode)
- "Create a function that initializes all the language dependent variables
-for the given mode.
+ "Create a function that initializes all language dependent variables for MODE.
This function should be evaluated at compile time, so that the
function it returns is byte compiled with all the evaluated results
diff --git a/lisp/progmodes/cc-menus.el b/lisp/progmodes/cc-menus.el
index a099ec1de95..52b47a58732 100644
--- a/lisp/progmodes/cc-menus.el
+++ b/lisp/progmodes/cc-menus.el
@@ -172,7 +172,7 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.")
"[ \t\n\r]*"))
(defun cc-imenu-java-build-type-args-regex (depth)
- "Builds regexp for type arguments list with DEPTH allowed
+ "Build regexp for type arguments list with DEPTH allowed
nested angle brackets constructs."
(if (> depth 0)
(concat "<"
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 057d292246f..f9435c9ceee 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -129,6 +129,16 @@
; '
(require 'cc-fonts) ;)
+(defvar c-type-finder-timer nil)
+;; The variable which holds the repeating idle timer which triggers off the
+;; background type finding search.
+
+(defvar c-inhibit-type-finder nil)
+;; When non-nil (set by `c-post-gc-hook') don't perform the type finding
+;; activities the next time `c-type-finder-timer' triggers. This ensures
+;; keyboard/mouse input will be dealt with when garbage collection is taking a
+;; large portion of CPU time.
+
;; The following three really belong to cc-fonts.el, but they are required
;; even when cc-fonts.el hasn't been loaded (this happens in XEmacs when
;; font-lock-mode is nil).
@@ -179,6 +189,18 @@
(when c-buffer-is-cc-mode
(save-restriction
(widen)
+ (let ((lst (buffer-list)))
+ (catch 'found
+ (dolist (b lst)
+ (if (and (not (eq b (current-buffer)))
+ (with-current-buffer b
+ c-buffer-is-cc-mode))
+ (throw 'found nil)))
+ (remove-hook 'post-command-hook 'c-post-command)
+ (remove-hook 'post-gc-hook 'c-post-gc-hook)
+ (and c-type-finder-timer
+ (progn (cancel-timer c-type-finder-timer)
+ (setq c-type-finder-timer nil)))))
(c-save-buffer-state ()
(c-clear-char-properties (point-min) (point-max) 'category)
(c-clear-char-properties (point-min) (point-max) 'syntax-table)
@@ -574,10 +596,15 @@ preferably use the `c-mode-menu' language constant directly."
;; currently no such text property.
(make-variable-buffer-local 'c-max-syn-tab-mkr)
+;; `c-type-finder-pos' is a marker marking the current place in a CC Mode
+;; buffer which is due to be searched next for "found types", or nil if the
+;; searching is complete.
+(defvar c-type-finder-pos nil)
+(make-variable-buffer-local 'c-type-finder-pos)
+
(defun c-basic-common-init (mode default-style)
- "Do the necessary initialization for the syntax handling routines
-and the line breaking/filling code. Intended to be used by other
-packages that embed CC Mode.
+ "Initialize the syntax handling routines and the line breaking/filling code.
+Intended to be used by other packages that embed CC Mode.
MODE is the CC Mode flavor to set up, e.g. `c-mode' or `java-mode'.
DEFAULT-STYLE tells which indentation style to install. It has the
@@ -746,6 +773,19 @@ that requires a literal mode spec at compile time."
;; would do since font-lock uses a(n implicit) depth of 0) so we don't need
;; c-after-font-lock-init.
(add-hook 'after-change-functions 'c-after-change nil t)
+ (add-hook 'post-command-hook 'c-post-command)
+ (setq c-type-finder-pos
+ (save-restriction
+ (widen)
+ (move-marker (make-marker) (point-min))))
+
+ ;; Install the functionality for seeking "found types" at mode startup:
+ (or c-type-finder-timer
+ (setq c-type-finder-timer
+ (run-at-time
+ c-type-finder-repeat-time nil #'c-type-finder-timer-func)))
+ (add-hook 'post-gc-hook #'c-post-gc-hook)
+
(when (boundp 'font-lock-extend-after-change-region-function)
(set (make-local-variable 'font-lock-extend-after-change-region-function)
'c-extend-after-change-region))) ; Currently (2009-05) used by all
@@ -1403,7 +1443,7 @@ Note that the style variables are always made local to the buffer."
(memq (char-after) c-string-delims))
(c-clear-syn-tab (point)))))
(c-clear-syn-tab (point)))
- (t (c-benign-error "c-remove-string-fences: wrong position")))))
+ (t (c-benign-error "c-remove-string-fences: Wrong position")))))
(defun c-before-change-check-unbalanced-strings (beg end)
;; If BEG or END is inside an unbalanced string, remove the syntax-table
@@ -1649,7 +1689,7 @@ Note that the style variables are always made local to the buffer."
(and (memq (char-before) c-string-delims)
(not (nth 4 s))))) ; Check we're actually out of the
; comment. not stuck at EOB
- (unless
+ (unless
(and c-ml-string-opener-re
(c-maybe-re-mark-ml-string))
(if (c-unescaped-nls-in-string-p (1- (point)))
@@ -1951,6 +1991,46 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
;; confused by already processed single quotes.
(narrow-to-region (point) (point-max))))))
+;; The next two variables record the bounds of an identifier currently being
+;; typed in. These are used to prevent such a partial identifier being
+;; recorded as a found type by c-add-type.
+(defvar c-new-id-start nil)
+(make-variable-buffer-local 'c-new-id-start)
+(defvar c-new-id-end nil)
+(make-variable-buffer-local 'c-new-id-end)
+;; The next variable, when non-nil, records that the previous two variables
+;; define a type.
+(defvar c-new-id-is-type nil)
+(make-variable-buffer-local 'c-new-id-is-type)
+
+(defun c-update-new-id (end)
+ ;; Note the bounds of any identifier that END is in or just after, in
+ ;; `c-new-id-start' and `c-new-id-end'. Otherwise set these variables to
+ ;; nil.
+ (save-excursion
+ (goto-char end)
+ (let ((id-beg (c-on-identifier)))
+ (setq c-new-id-start id-beg
+ c-new-id-end (and id-beg
+ (progn (c-end-of-current-token) (point)))))))
+
+
+(defun c-post-command ()
+ ;; If point was inside of a new identifier and no longer is, record that
+ ;; fact.
+ (when (and c-buffer-is-cc-mode
+ c-new-id-start c-new-id-end
+ (or (> (point) c-new-id-end)
+ (< (point) c-new-id-start)))
+ (when c-new-id-is-type
+ (c-add-type-1 c-new-id-start c-new-id-end))
+ (setq c-new-id-start nil
+ c-new-id-end nil
+ c-new-id-is-type nil)))
+
+(defun c-post-gc-hook (&optional _stats) ; For XEmacs.
+ (setq c-inhibit-type-finder t))
+
(defun c-before-change (beg end)
;; Function to be put on `before-change-functions'. Primarily, this calls
;; the language dependent `c-get-state-before-change-functions'. It is
@@ -1970,11 +2050,16 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
(unless (c-called-from-text-property-change-p)
(save-restriction
(widen)
+ ;; Clear the list of found types if we make a change at the start of the
+ ;; buffer, to make it easier to get rid of misspelled types and
+ ;; variables that have gotten recognized as types in malformed code.
+ (when (eq beg (point-min))
+ (c-clear-found-types))
(if c-just-done-before-change
- ;; We have two consecutive calls to `before-change-functions' without
- ;; an intervening `after-change-functions'. An example of this is bug
- ;; #38691. To protect CC Mode, assume that the entire buffer has
- ;; changed.
+ ;; We have two consecutive calls to `before-change-functions'
+ ;; without an intervening `after-change-functions'. An example of
+ ;; this is bug #38691. To protect CC Mode, assume that the entire
+ ;; buffer has changed.
(setq beg (point-min)
end (point-max)
c-just-done-before-change 'whole-buffer)
@@ -2152,6 +2237,7 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
c->-as-paren-syntax)
(c-clear-char-property-with-value beg end 'syntax-table nil)))
+ (c-update-new-id end)
(c-trim-found-types beg end old-len) ; maybe we don't
; need all of these.
(c-invalidate-sws-region-after beg end old-len)
@@ -2550,17 +2636,24 @@ 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 \", t will be returned unless the \" is marked with
-a string fence syntax-table text property. For other characters,
-the default value of `electric-pair-inhibit-predicate' is called
-and its value returned.
+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.
This function is the appropriate value of
`electric-pair-inhibit-predicate' for CC Mode modes, which mark
invalid strings with such a syntax table text property on the
opening \" and the next unescaped end of line."
- (if (eq char ?\")
- (not (equal (get-text-property (1- (point)) 'c-fl-syn-tab) '(15)))
+ (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))))
(funcall (default-value 'electric-pair-inhibit-predicate) char)))
@@ -2568,17 +2661,17 @@ opening \" and the next unescaped end of line."
(defvar c-mode-syntax-table
(funcall (c-lang-const c-make-mode-syntax-table c))
- "Syntax table used in c-mode buffers.")
+ "Syntax table used in `c-mode' buffers.")
(defvar c-mode-map
(let ((map (c-make-inherited-keymap)))
map)
- "Keymap used in c-mode buffers.")
+ "Keymap used in `c-mode' buffers.")
;; Add bindings which are only useful for C.
(define-key c-mode-map "\C-c\C-e" 'c-macro-expand)
-(easy-menu-define c-c-menu c-mode-map "C Mode Commands"
+(easy-menu-define c-c-menu c-mode-map "C Mode Commands."
(cons "C" (c-lang-const c-mode-menu c)))
;; In XEmacs >= 21.5 modes should add their own entries to
@@ -2617,7 +2710,7 @@ opening \" and the next unescaped end of line."
"Major mode for editing C code.
To submit a problem report, enter `\\[c-submit-bug-report]' from a
-c-mode buffer. This automatically sets up a mail buffer with version
+`c-mode' buffer. This automatically sets up a mail buffer with version
information already added. You just need to add a description of the
problem, including a reproducible test case, and send the message.
@@ -2701,7 +2794,7 @@ the code is C or C++ and based on that chooses whether to enable
(define-key c++-mode-map "<" 'c-electric-lt-gt)
(define-key c++-mode-map ">" 'c-electric-lt-gt)
-(easy-menu-define c-c++-menu c++-mode-map "C++ Mode Commands"
+(easy-menu-define c-c++-menu c++-mode-map "C++ Mode Commands."
(cons "C++" (c-lang-const c-mode-menu c++)))
;;;###autoload
@@ -2738,16 +2831,16 @@ Key bindings:
(defvar objc-mode-syntax-table
(funcall (c-lang-const c-make-mode-syntax-table objc))
- "Syntax table used in objc-mode buffers.")
+ "Syntax table used in `objc-mode' buffers.")
(defvar objc-mode-map
(let ((map (c-make-inherited-keymap)))
map)
- "Keymap used in objc-mode buffers.")
+ "Keymap used in `objc-mode' buffers.")
;; Add bindings which are only useful for Objective-C.
(define-key objc-mode-map "\C-c\C-e" 'c-macro-expand)
-(easy-menu-define c-objc-menu objc-mode-map "ObjC Mode Commands"
+(easy-menu-define c-objc-menu objc-mode-map "ObjC Mode Commands."
(cons "ObjC" (c-lang-const c-mode-menu objc)))
;;;###autoload (add-to-list 'auto-mode-alist '("\\.m\\'" . objc-mode))
@@ -2756,7 +2849,7 @@ Key bindings:
(define-derived-mode objc-mode prog-mode "ObjC"
"Major mode for editing Objective C code.
To submit a problem report, enter `\\[c-submit-bug-report]' from an
-objc-mode buffer. This automatically sets up a mail buffer with
+`objc-mode' buffer. This automatically sets up a mail buffer with
version information already added. You just need to add a description
of the problem, including a reproducible test case, and send the
message.
@@ -2785,12 +2878,12 @@ Key bindings:
(defvar java-mode-syntax-table
(funcall (c-lang-const c-make-mode-syntax-table java))
- "Syntax table used in java-mode buffers.")
+ "Syntax table used in `java-mode' buffers.")
(defvar java-mode-map
(let ((map (c-make-inherited-keymap)))
map)
- "Keymap used in java-mode buffers.")
+ "Keymap used in `java-mode' buffers.")
;; Add bindings which are only useful for Java.
;; Regexp trying to describe the beginning of a Java top-level
@@ -2800,7 +2893,7 @@ Key bindings:
(defconst c-Java-defun-prompt-regexp
"^[ \t]*\\(\\(\\(public\\|protected\\|private\\|const\\|abstract\\|synchronized\\|final\\|static\\|threadsafe\\|transient\\|native\\|volatile\\)\\s-+\\)*\\(\\(\\([[a-zA-Z][][_$.a-zA-Z0-9]+\\|[[a-zA-Z]\\)\\s-*\\)\\s-+\\)\\)?\\(\\([[a-zA-Z][][_$.a-zA-Z0-9]*\\s-+\\)\\s-*\\)?\\([_a-zA-Z][^][ \t:;.,{}()\^?=]*\\|\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)\\)\\s-*\\(([^);{}]*)\\)?\\([] \t]*\\)\\(\\s-*\\<throws\\>\\s-*\\(\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)[, \t\n\r\f\v]*\\)+\\)?\\s-*")
-(easy-menu-define c-java-menu java-mode-map "Java Mode Commands"
+(easy-menu-define c-java-menu java-mode-map "Java Mode Commands."
(cons "Java" (c-lang-const c-mode-menu java)))
;;;###autoload (add-to-list 'auto-mode-alist '("\\.java\\'" . java-mode))
@@ -2809,7 +2902,7 @@ Key bindings:
(define-derived-mode java-mode prog-mode "Java"
"Major mode for editing Java code.
To submit a problem report, enter `\\[c-submit-bug-report]' from a
-java-mode buffer. This automatically sets up a mail buffer with
+`java-mode' buffer. This automatically sets up a mail buffer with
version information already added. You just need to add a description
of the problem, including a reproducible test case, and send the
message.
@@ -2836,15 +2929,15 @@ Key bindings:
(defvar idl-mode-syntax-table
(funcall (c-lang-const c-make-mode-syntax-table idl))
- "Syntax table used in idl-mode buffers.")
+ "Syntax table used in `idl-mode' buffers.")
(defvar idl-mode-map
(let ((map (c-make-inherited-keymap)))
map)
- "Keymap used in idl-mode buffers.")
+ "Keymap used in `idl-mode' buffers.")
;; Add bindings which are only useful for IDL.
-(easy-menu-define c-idl-menu idl-mode-map "IDL Mode Commands"
+(easy-menu-define c-idl-menu idl-mode-map "IDL Mode Commands."
(cons "IDL" (c-lang-const c-mode-menu idl)))
;;;###autoload (add-to-list 'auto-mode-alist '("\\.idl\\'" . idl-mode))
@@ -2853,7 +2946,7 @@ Key bindings:
(define-derived-mode idl-mode prog-mode "IDL"
"Major mode for editing CORBA's IDL, PSDL and CIDL code.
To submit a problem report, enter `\\[c-submit-bug-report]' from an
-idl-mode buffer. This automatically sets up a mail buffer with
+`idl-mode' buffer. This automatically sets up a mail buffer with
version information already added. You just need to add a description
of the problem, including a reproducible test case, and send the
message.
@@ -2879,16 +2972,16 @@ Key bindings:
(defvar pike-mode-syntax-table
(funcall (c-lang-const c-make-mode-syntax-table pike))
- "Syntax table used in pike-mode buffers.")
+ "Syntax table used in `pike-mode' buffers.")
(defvar pike-mode-map
(let ((map (c-make-inherited-keymap)))
map)
- "Keymap used in pike-mode buffers.")
+ "Keymap used in `pike-mode' buffers.")
;; Additional bindings.
(define-key pike-mode-map "\C-c\C-e" 'c-macro-expand)
-(easy-menu-define c-pike-menu pike-mode-map "Pike Mode Commands"
+(easy-menu-define c-pike-menu pike-mode-map "Pike Mode Commands."
(cons "Pike" (c-lang-const c-mode-menu pike)))
;;;###autoload (add-to-list 'auto-mode-alist '("\\.\\(u?lpc\\|pike\\|pmod\\(\\.in\\)?\\)\\'" . pike-mode))
@@ -2898,7 +2991,7 @@ Key bindings:
(define-derived-mode pike-mode prog-mode "Pike"
"Major mode for editing Pike code.
To submit a problem report, enter `\\[c-submit-bug-report]' from a
-pike-mode buffer. This automatically sets up a mail buffer with
+`pike-mode' buffer. This automatically sets up a mail buffer with
version information already added. You just need to add a description
of the problem, including a reproducible test case, and send the
message.
@@ -2932,7 +3025,7 @@ Key bindings:
(defvar awk-mode-map
(let ((map (c-make-inherited-keymap)))
map)
- "Keymap used in awk-mode buffers.")
+ "Keymap used in `awk-mode' buffers.")
;; Add bindings which are only useful for awk.
(define-key awk-mode-map "#" 'self-insert-command);Overrides electric parent binding.
(define-key awk-mode-map "/" 'self-insert-command);Overrides electric parent binding.
@@ -2945,7 +3038,7 @@ Key bindings:
(define-key awk-mode-map "\C-\M-a" 'c-awk-beginning-of-defun)
(define-key awk-mode-map "\C-\M-e" 'c-awk-end-of-defun)
-(easy-menu-define c-awk-menu awk-mode-map "AWK Mode Commands"
+(easy-menu-define c-awk-menu awk-mode-map "AWK Mode Commands."
(cons "AWK" (c-lang-const c-mode-menu awk)))
;; (require 'cc-awk) brings these in.
@@ -2956,7 +3049,7 @@ Key bindings:
(define-derived-mode awk-mode prog-mode "AWK"
"Major mode for editing AWK code.
To submit a problem report, enter `\\[c-submit-bug-report]' from an
-awk-mode buffer. This automatically sets up a mail buffer with version
+`awk-mode' buffer. This automatically sets up a mail buffer with version
information already added. You just need to add a description of the
problem, including a reproducible test case, and send the message.
diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el
index 8514434e9ac..4d518838d11 100644
--- a/lisp/progmodes/cc-styles.el
+++ b/lisp/progmodes/cc-styles.el
@@ -406,7 +406,7 @@ a null operation."
;;;###autoload
(defun c-add-style (style description &optional set-p)
- "Adds a style to `c-style-alist', or updates an existing one.
+ "Add a style to `c-style-alist', or update an existing one.
STYLE is a string identifying the style to add or update. DESCRIPTION
is an association list describing the style and must be of the form:
@@ -444,17 +444,19 @@ STYLE using `c-set-style' if the optional SET-P flag is non-nil."
defstr))
(prompt (concat symname " offset " defstr))
(keymap (make-sparse-keymap))
- (minibuffer-completion-table obarray)
- (minibuffer-completion-predicate 'fboundp)
offset input)
;; In principle completing-read is used here, but SPC is unbound
;; to make it less annoying to enter lists.
(set-keymap-parent keymap minibuffer-local-completion-map)
(define-key keymap " " 'self-insert-command)
(while (not offset)
- (setq input (read-from-minibuffer prompt nil keymap t
- 'c-read-offset-history
- (format "%s" oldoff)))
+ (minibuffer-with-setup-hook
+ (lambda ()
+ (setq-local minibuffer-completion-table obarray)
+ (setq-local minibuffer-completion-predicate 'fboundp))
+ (setq input (read-from-minibuffer prompt nil keymap t
+ 'c-read-offset-history
+ (format "%s" oldoff))))
(if (c-valid-offset input)
(setq offset input)
;; error, but don't signal one, keep trying
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index b33fea0b48c..40a43c32ed9 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -179,7 +179,7 @@ STYLE stands for the choice where the value is taken from some
style setting. PREAMBLE is optionally prepended to FOO; that is,
if FOO contains :tag or :value, the respective two-element list
component is ignored."
- (declare (debug (symbolp form stringp &rest)))
+ (declare (debug (symbolp form stringp &rest)) (indent defun))
(let* ((expanded-doc (concat doc "
This is a style variable. Apart from the valid values described
@@ -1227,7 +1227,7 @@ can always override the use of `c-default-style' by making calls to
;; Anchor pos: None.
))
(defcustom c-offsets-alist nil
- "Association list of syntactic element symbols and indentation offsets.
+ "Alist of syntactic element symbols and indentation offsets.
As described below, each cons cell in this list has the form:
(SYNTACTIC-SYMBOL . OFFSET)
@@ -1427,23 +1427,23 @@ localized, they cannot be made global again.
This variable must be set appropriately before CC Mode is loaded.
The list of variables to buffer localize are:
- c-basic-offset
- c-comment-only-line-offset
- c-indent-comment-alist
- c-indent-comments-syntactically-p
- c-block-comment-prefix
- c-comment-prefix-regexp
- c-doc-comment-style
- c-cleanup-list
- c-hanging-braces-alist
- c-hanging-colons-alist
- c-hanging-semi&comma-criteria
- c-backslash-column
- c-backslash-max-column
- c-label-minimum-indentation
- c-offsets-alist
- c-special-indent-hook
- c-indentation-style"
+ `c-basic-offset'
+ `c-comment-only-line-offset'
+ `c-indent-comment-alist'
+ `c-indent-comments-syntactically-p'
+ `c-block-comment-prefix'
+ `c-comment-prefix-regexp'
+ `c-doc-comment-style'
+ `c-cleanup-list'
+ `c-hanging-braces-alist'
+ `c-hanging-colons-alist'
+ `c-hanging-semi&comma-criteria'
+ `c-backslash-column'
+ `c-backslash-max-column'
+ `c-label-minimum-indentation'
+ `c-offsets-alist'
+ `c-special-indent-hook'
+ `c-indentation-style'"
:type 'boolean
:safe 'booleanp
:group 'c)
@@ -1524,6 +1524,39 @@ working due to this change."
:type 'boolean
:group 'c)
+(defcustom c-type-finder-time-slot 0.05
+ "The length in seconds of a background type search time slot.
+
+In CC Mode modes, \"found types\" wouldn't always get cleanly
+fontified without the background searching for them which happens
+in the seconds after starting Emacs or initializing the major
+mode.
+
+This background searching can be disabled by setting this option
+to nil."
+ :type '(choice (const :tag "disabled" nil)
+ number)
+ :group 'c)
+
+(defcustom c-type-finder-repeat-time 0.1
+ "The interval, in seconds, at which background type searches occur.
+
+This interval must be greater than `c-type-finder-time-slot'."
+ :type 'number
+ :group 'c)
+
+(defcustom c-type-finder-chunk-size 1000
+ "The size, in characters, of a chunk for background type search.
+
+Chunks of this size are searched atomically for \"found types\"
+just after starting Emacs or initializing the major mode.
+
+This chunk size is a balance between efficiency (with larger
+values) and responsiveness of the keyboard (with smaller values).
+See also `c-type-finder-time-slot'."
+ :type 'integer
+ :group 'c)
+
(define-widget 'c-extra-types-widget 'radio
"Internal CC Mode widget for the `*-font-lock-extra-types' variables."
:args '((const :tag "none" nil)
@@ -1770,7 +1803,7 @@ variables.")
; all XEmacsen.
((null c-macro-names-with-semicolon)
nil)
- (t (error "c-make-macro-with-semi-re: invalid \
+ (t (error "c-make-macro-with-semi-re: Invalid \
c-macro-names-with-semicolon: %s"
c-macro-names-with-semicolon))))))
@@ -1864,13 +1897,13 @@ Set from `c-comment-prefix-regexp' at mode initialization.")
(defvar c-string-par-start
;; (concat "\\(" (default-value 'paragraph-start) "\\)\\|[ \t]*\\\\$")
"\f\\|[ \t]*\\\\?$"
- "Value of paragraph-start used when scanning strings.
+ "Value of `paragraph-start' used when scanning strings.
It treats escaped EOLs as whitespace.")
(defvar c-string-par-separate
;; (concat "\\(" (default-value 'paragraph-separate) "\\)\\|[ \t]*\\\\$")
"[ \t\f]*\\\\?$"
- "Value of paragraph-separate used when scanning strings.
+ "Value of `paragraph-separate' used when scanning strings.
It treats escaped EOLs as whitespace.")
(defvar c-sentence-end-with-esc-eol
@@ -1878,7 +1911,7 @@ It treats escaped EOLs as whitespace.")
;; N.B.: "$" would be illegal when not enclosed like "\\($\\)".
"\\|" "[.?!][]\"')}]* ?\\\\\\($\\)[ \t\n]*"
"\\)")
- "Value used like sentence-end used when scanning strings.
+ "Value used like `sentence-end' used when scanning strings.
It treats escaped EOLs as whitespace.")
diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el
index 4649e506541..53914616cdc 100644
--- a/lisp/progmodes/cfengine.el
+++ b/lisp/progmodes/cfengine.el
@@ -47,8 +47,8 @@
;; (add-hook 'cfengine3-mode-hook 'eldoc-mode)
;; You may also find the command `cfengine3-reformat-json-string'
-;; useful, just bind it to a key you prefer. It will take the current
-;; string and reformat it as JSON. So if you're editing JSON inside
+;; useful, just bind it to a key you prefer. It will take the current
+;; string and reformat it as JSON. So if you're editing JSON inside
;; the policy, it's a quick way to make it more legible without
;; manually reindenting it. For instance:
@@ -140,8 +140,7 @@ bundle agent rcfiles
\"/tmp/netrc\"
comment => \"my netrc\",
perms => mog(\"600\", \"tzz\", \"tzz\");
-}
-"
+}"
:version "24.4"
:type '(list
(choice (const :tag "Anchor at beginning of promise" promise)
@@ -1193,7 +1192,7 @@ Intended as the value of `indent-line-function'."
;; CATEGORY: [a-zA-Z_]+:
(defun cfengine3--current-function ()
- "Look up current CFEngine 3 function"
+ "Look up current CFEngine 3 function."
(let* ((syntax (cfengine3-make-syntax-cache))
(flist (assq 'functions syntax)))
(when flist
diff --git a/lisp/progmodes/cl-font-lock.el b/lisp/progmodes/cl-font-lock.el
index 178fe944f30..f602c3e13f4 100644
--- a/lisp/progmodes/cl-font-lock.el
+++ b/lisp/progmodes/cl-font-lock.el
@@ -8,7 +8,6 @@
;; Package-Requires: ((emacs "24.5"))
;; Keywords: lisp wp files convenience
;; URL: https://github.com/cl-font-lock/cl-font-lock
-;; Homepage: https://github.com/cl-font-lock/cl-font-lock
;; This file is part of GNU Emacs
diff --git a/lisp/progmodes/cmacexp.el b/lisp/progmodes/cmacexp.el
index 0f7c8c6f31a..07648ac623c 100644
--- a/lisp/progmodes/cmacexp.el
+++ b/lisp/progmodes/cmacexp.el
@@ -101,7 +101,7 @@
:type 'boolean)
(defcustom c-macro-prompt-flag nil
- "Non-nil makes `c-macro-expand' prompt for preprocessor arguments."
+ "Non-nil means `c-macro-expand' will prompt for preprocessor arguments."
:type 'boolean)
(defcustom c-macro-preprocessor
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index 1fb6124ab56..6e3589df7ad 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -86,7 +86,7 @@ This is bound before running `compilation-filter-hook'.")
"This is how compilers number the first column, usually 1 or 0.
If this is buffer-local in the destination buffer, Emacs obeys
that value, otherwise it uses the value in the *compilation*
-buffer. This enables a major-mode to specify its own value.")
+buffer. This enables a major mode to specify its own value.")
(defvar compilation-parse-errors-filename-function #'identity
"Function to call to post-process filenames while parsing error messages.
@@ -346,12 +346,9 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
;; PROGRAM:SOURCE-FILE-NAME:LINENO: MESSAGE
;; which is used for non-interactive programs other than
;; compilers (e.g. the "jade:" entry in compilation.txt).
- (? (| (regexp "[[:alpha:]][-[:alnum:].]+: ?")
- ;; FIXME: This pattern was added for handling messages
- ;; from Ruby, but it is unclear whether it is actually
- ;; used since the gcc-include rule above seems to cover
- ;; it.
- (regexp "[ \t]+\\(?:in \\|from\\)")))
+ (? (| (: alpha (+ (in ?. ?- alnum)) ":" (? " "))
+ ;; Skip indentation generated by GCC's -fanalyzer.
+ (: (+ " ") "|")))
;; File name group.
(group-n 1
@@ -662,7 +659,8 @@ has just been matched, and should correspondingly preserve this match data.
TYPE is 2 or nil for a real error or 1 for warning or 0 for info.
TYPE can also be of the form (WARNING . INFO). In that case this
will be equivalent to 1 if the WARNING'th subexpression matched
-or else equivalent to 0 if the INFO'th subexpression matched.
+or else equivalent to 0 if the INFO'th subexpression matched,
+or else equivalent to 2 if neither of them matched.
See `compilation-error-face', `compilation-warning-face',
`compilation-info-face' and `compilation-skip-threshold'.
@@ -687,11 +685,13 @@ matched file names, and weeding out false positives."
,(expand-file-name "compilation.txt" data-directory)))
(defvar compilation-error-case-fold-search nil
- "If non-nil, use case-insensitive matching of compilation errors
-by the regexps of `compilation-error-regexp-alist' and
-`compilation-error-regexp-alist-alist'.
+ "If non-nil, use case-insensitive matching of compilation errors.
If nil, matching is case-sensitive.
+Compilation errors are given by the regexps in
+`compilation-error-regexp-alist' and
+`compilation-error-regexp-alist-alist'.
+
This variable should only be set for backward compatibility as a temporary
measure. The proper solution is to use a regexp that matches the
messages without case-folding.")
@@ -752,7 +752,7 @@ program and Emacs agree about the display width of the characters,
especially the TAB character.
If this is buffer-local in the destination buffer, Emacs obeys
that value, otherwise it uses the value in the *compilation*
-buffer. This enables a major-mode to specify its own value."
+buffer. This enables a major mode to specify its own value."
:type 'boolean
:version "20.4")
@@ -1783,6 +1783,9 @@ Returns the compilation buffer created."
(replace-regexp-in-string "-mode\\'" "" (symbol-name mode))))
(thisdir default-directory)
(thisenv compilation-environment)
+ (buffer-path (and (local-variable-p 'exec-path) exec-path))
+ (buffer-env (and (local-variable-p 'process-environment)
+ process-environment))
outwin outbuf)
(with-current-buffer
(setq outbuf
@@ -1850,6 +1853,12 @@ Returns the compilation buffer created."
;; NB: must be done after (funcall mode) as that resets local variables
(setq-local compilation-directory thisdir)
(setq-local compilation-environment thisenv)
+ (if buffer-path
+ (setq-local exec-path buffer-path)
+ (kill-local-variable 'exec-path))
+ (if buffer-env
+ (setq-local process-environment buffer-env)
+ (kill-local-variable 'process-environment))
(if highlight-regexp
(setq-local compilation-highlight-regexp highlight-regexp))
(if (or compilation-auto-jump-to-first-error
@@ -2216,6 +2225,7 @@ The parent is always `compilation-mode' and the customizable `compilation-...'
variables are also set from the name of the mode you have chosen,
by replacing the first word, e.g., `compilation-scroll-output' from
`grep-scroll-output' if that variable exists."
+ (declare (indent defun))
(let ((mode-name (replace-regexp-in-string "-mode\\'" "" (symbol-name mode))))
`(define-derived-mode ,mode compilation-mode ,name
,doc
@@ -2251,7 +2261,7 @@ by replacing the first word, e.g., `compilation-scroll-output' from
(if buffer-file-name
(let (revert-buffer-function)
(revert-buffer ignore-auto noconfirm))
- (if (or noconfirm (yes-or-no-p (format "Restart compilation? ")))
+ (if (or noconfirm (yes-or-no-p "Restart compilation? "))
(apply #'compilation-start compilation-arguments))))
(defvar compilation-current-error nil
@@ -2767,7 +2777,7 @@ Actual value is never used, only the text property.")
(set-window-margins w (- (car (window-margins w)) 2))))
(defun compilation--set-up-arrow-spec-in-margins ()
- "Set up compilation-arrow-overlay to display as an arrow in margins."
+ "Set up `compilation-arrow-overlay' to display as an arrow in margins."
(setq overlay-arrow-string "")
(setq compilation-arrow-overlay
(make-overlay overlay-arrow-position overlay-arrow-position))
@@ -2780,7 +2790,7 @@ Actual value is never used, only the text property.")
#'compilation--tear-down-arrow-spec-in-margins nil t))
(defun compilation--tear-down-arrow-spec-in-margins ()
- "Restore compilation-arrow-overlay to not using the margins, which are removed."
+ "Restore `compilation-arrow-overlay' to not using the margins, which are removed."
(when (overlayp compilation-arrow-overlay)
(overlay-put compilation-arrow-overlay 'before-string nil)
(delete-overlay compilation-arrow-overlay)
@@ -2951,7 +2961,8 @@ attempts to find a file whose name is produced by (format FMT FILENAME)."
fmts formats)
;; For each directory, try each format string.
(while (and fmts (null buffer))
- (setq name (expand-file-name (format (car fmts) filename) thisdir)
+ (setq name (file-truename
+ (file-name-concat thisdir (format (car fmts) filename)))
buffer (and (file-exists-p name)
(find-file-noselect name))
fmts (cdr fmts)))
@@ -2973,7 +2984,8 @@ attempts to find a file whose name is produced by (format FMT FILENAME)."
(setq thisdir (car dirs)
fmts formats)
(while (and fmts (null buffer))
- (setq name (expand-file-name (format (car fmts) filename) thisdir)
+ (setq name (file-truename
+ (file-name-concat thisdir (format (car fmts) filename)))
buffer (and (file-exists-p name)
(find-file-noselect name))
fmts (cdr fmts)))
@@ -3016,7 +3028,8 @@ attempts to find a file whose name is produced by (format FMT FILENAME)."
(ding) (sit-for 2))
((and (file-directory-p name)
(not (file-exists-p
- (setq name (expand-file-name filename name)))))
+ (setq name (file-truename
+ (file-name-concat name filename))))))
(message "No `%s' in directory %s" filename origname)
(ding) (sit-for 2))
(t
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index 3370df64919..fe9612a09a9 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -308,12 +308,11 @@ Can be overwritten by `cperl-hairy' if nil."
Can be overwritten by `cperl-hairy' if nil.
Uses `abbrev-mode' to do the expansion. If you want to use your
-own abbrevs in cperl-mode, but do not want keywords to be
+own abbrevs in `cperl-mode', but do not want keywords to be
electric, you must redefine `cperl-mode-abbrev-table': do
\\[edit-abbrevs], search for `cperl-mode-abbrev-table', and, in
that paragraph, delete the words that appear at the ends of lines and
-that begin with \"cperl-electric\".
-"
+that begin with \"cperl-electric\"."
:type '(choice (const null) boolean)
:group 'cperl-affected-by-hairy)
@@ -362,14 +361,14 @@ Affects: `cperl-font-lock', `cperl-electric-lbrace-space',
;; :group 'cperl)
(defcustom cperl-info-on-command-no-prompt nil
- "Not-nil (and non-null) means not to prompt on C-h f.
+ "Not-nil (and non-null) means not to prompt on \\[cperl-info-on-command].
The opposite behavior is always available if prefixed with C-c.
Can be overwritten by `cperl-hairy' if nil."
:type '(choice (const null) boolean)
:group 'cperl-affected-by-hairy)
(defcustom cperl-clobber-lisp-bindings nil
- "Not-nil (and non-null) means not overwrite C-h f.
+ "Not-nil (and non-null) means not overwrite \\[describe-function].
The function is available on \\[cperl-info-on-command], \\[cperl-get-help].
Can be overwritten by `cperl-hairy' if nil."
:type '(choice (const null) boolean)
@@ -508,9 +507,9 @@ Currently used with `cperl-check-syntax' only."
:group 'cperl-help-system)
(defcustom cperl-indent-region-fix-constructs 1
- "Amount of space to insert between `}' and `else' or `elsif'
-in `cperl-indent-region'. Set to nil to leave as is. Values other
-than 1 and nil will probably not work."
+ "Amount of space to insert between `}' and `else' or `elsif'.
+Used by `cperl-indent-region'. Set to nil to leave as is.
+Values other than 1 and nil will probably not work."
:type '(choice (const nil) (const 1))
:group 'cperl-indentation-details)
@@ -767,8 +766,7 @@ line-breaks/spacing between elements of the construct.
10) Uses a linear-time algorithm for indentation of regions.
-11) Syntax-highlight, indentation, sexp-recognition inside regular expressions.
-")
+11) Syntax-highlight, indentation, sexp-recognition inside regular expressions.")
(defvar cperl-speed 'please-ignore-this-line
"This is an incomplete compendium of what is available in other parts
@@ -865,9 +863,7 @@ In regular expressions (including character classes):
backslashes of escape sequences
`font-lock-variable-name-face' Interpolated constructs, embedded code,
POSIX classes (inside charclasses)
- `font-lock-comment-face' Embedded comments
-
-")
+ `font-lock-comment-face' Embedded comments")
@@ -1023,15 +1019,9 @@ Unless KEEP, removes the old indentation."
(define-key map [(control ?c) (control ?h) ?v]
;;(concat (char-to-string help-char) "v") ; does not work
'cperl-get-help))
- (substitute-key-definition
- 'indent-sexp 'cperl-indent-exp
- map global-map)
- (substitute-key-definition
- 'indent-region 'cperl-indent-region
- map global-map)
- (substitute-key-definition
- 'indent-for-comment 'cperl-indent-for-comment
- map global-map)
+ (define-key map [remap indent-sexp] #'cperl-indent-exp)
+ (define-key map [remap indent-region] #'cperl-indent-region)
+ (define-key map [remap indent-for-comment] #'cperl-indent-for-comment)
map)
"Keymap used in CPerl mode.")
@@ -1203,153 +1193,198 @@ The expansion is entirely correct because it uses the C preprocessor."
;; minimalistic Perl grammar, to be used instead of individual (and
;; not always consistent) literal regular expressions.
-(defconst cperl--basic-identifier-regexp
- (rx (sequence (or alpha "_") (* (or word "_"))))
- "A regular expression for the name of a \"basic\" Perl variable.
+;; This is necessary to compile this file under Emacs 26.1
+;; (there's no rx-define which would help)
+(eval-and-compile
+
+ (defconst cperl--basic-identifier-rx
+ '(sequence (or alpha "_") (* (or word "_")))
+ "A regular expression for the name of a \"basic\" Perl variable.
Neither namespace separators nor sigils are included. As is,
this regular expression applies to labels,subroutine calls where
the ampersand sigil is not required, and names of subroutine
attributes.")
-(defconst cperl--label-regexp
- (rx-to-string
- `(sequence
- symbol-start
- (regexp ,cperl--basic-identifier-regexp)
- (0+ space)
- ":"))
- "A regular expression for a Perl label.
+ (defconst cperl--label-rx
+ `(sequence symbol-start
+ ,cperl--basic-identifier-rx
+ (0+ space)
+ ":")
+ "A regular expression for a Perl label.
By convention, labels are uppercase alphabetics, but this isn't
enforced.")
-(defconst cperl--normal-identifier-regexp
- (rx-to-string
- `(or
- (sequence
- (1+ (sequence
- (opt (regexp ,cperl--basic-identifier-regexp))
- "::"))
- (opt (regexp ,cperl--basic-identifier-regexp)))
- (regexp ,cperl--basic-identifier-regexp)))
- "A regular expression for a Perl variable name with optional namespace.
+ (defconst cperl--false-label-rx
+ '(sequence (or (in "sym") "tr") (0+ space) ":")
+ "A regular expression which is similar to a label, but might as
+well be a quote-like operator with a colon as delimiter.")
+
+ (defconst cperl--normal-identifier-rx
+ `(or (sequence (1+ (sequence
+ (opt ,cperl--basic-identifier-rx)
+ "::"))
+ (opt ,cperl--basic-identifier-rx))
+ ,cperl--basic-identifier-rx)
+ "A regular expression for a Perl variable name with optional namespace.
Examples are `foo`, `Some::Module::VERSION`, and `::` (yes, that
is a legal variable name).")
-(defconst cperl--special-identifier-regexp
- (rx-to-string
- `(or
- (1+ digit) ; $0, $1, $2, ...
- (sequence "^" (any "A-Z" "]^_?\\")) ; $^V
- (sequence "{" (0+ space) ; ${^MATCH}
- "^" (any "A-Z" "]^_?\\")
- (0+ (any "A-Z" "_" digit))
- (0+ space) "}")
- (in "!\"$%&'()+,-./:;<=>?@\\]^_`|~"))) ; $., $|, $", ... but not $^ or ${
- "The list of Perl \"punctuation\" variables, as listed in perlvar.")
-
-(defconst cperl--ws-regexp
- (rx-to-string
- '(or space "\n"))
- "Regular expression for a single whitespace in Perl.")
-
-(defconst cperl--eol-comment-regexp
- (rx-to-string
- '(sequence "#" (0+ (not (in "\n"))) "\n"))
- "Regular expression for a single end-of-line comment in Perl")
-
-(defconst cperl--ws-or-comment-regexp
- (rx-to-string
- `(1+
- (or
- (regexp ,cperl--ws-regexp)
- (regexp ,cperl--eol-comment-regexp))))
- "Regular expression for a sequence of whitespace and comments in Perl.")
-
-(defconst cperl--ows-regexp
- (rx-to-string
- `(opt (regexp ,cperl--ws-or-comment-regexp)))
- "Regular expression for optional whitespaces or comments in Perl")
-
-(defconst cperl--version-regexp
- (rx-to-string
- `(or
- (sequence (opt "v")
- (>= 2 (sequence (1+ digit) "."))
- (1+ digit)
- (opt (sequence "_" (1+ word))))
- (sequence (1+ digit)
- (opt (sequence "." (1+ digit)))
- (opt (sequence "_" (1+ word))))))
- "A sequence for recommended version number schemes in Perl.")
-
-(defconst cperl--package-regexp
- (rx-to-string
- `(sequence
- "package" ; FIXME: the "class" and "role" keywords need to be
- ; recognized soon...ish.
- (regexp ,cperl--ws-or-comment-regexp)
- (group (regexp ,cperl--normal-identifier-regexp))
- (opt
- (sequence
- (regexp ,cperl--ws-or-comment-regexp)
- (group (regexp ,cperl--version-regexp))))))
- "A regular expression for package NAME VERSION in Perl.
-Contains two groups for the package name and version.")
-
-(defconst cperl--package-for-imenu-regexp
- (rx-to-string
- `(sequence
- (regexp ,cperl--package-regexp)
- (regexp ,cperl--ows-regexp)
- (group (or ";" "{"))))
- "A regular expression to collect package names for `imenu`.
+ (defconst cperl--special-identifier-rx
+ '(or
+ (1+ digit) ; $0, $1, $2, ...
+ (sequence "^" (any "A-Z" "]^_?\\")) ; $^V
+ (sequence "{" (0+ space) ; ${^MATCH}
+ "^" (any "A-Z" "]^_?\\")
+ (0+ (any "A-Z" "_" digit))
+ (0+ space) "}")
+ (in "!\"$%&'()+,-./:;<=>?@\\]^_`|~")) ; $., $|, $", ... but not $^ or ${
+ "The list of Perl \"punctuation\" variables, as listed in perlvar.")
+
+ (defconst cperl--ws-rx
+ '(sequence (or space "\n"))
+ "Regular expression for a single whitespace in Perl.")
+
+ (defconst cperl--eol-comment-rx
+ '(sequence "#" (0+ (not (in "\n"))) "\n")
+ "Regular expression for a single end-of-line comment in Perl")
+
+ (defconst cperl--ws-or-comment-rx
+ `(or ,cperl--ws-rx
+ ,cperl--eol-comment-rx)
+ "A regular expression for either whitespace or comment")
+
+ (defconst cperl--ws*-rx
+ `(0+ ,cperl--ws-or-comment-rx)
+ "Regular expression for optional whitespaces or comments in Perl")
+
+ (defconst cperl--ws+-rx
+ `(1+ ,cperl--ws-or-comment-rx)
+ "Regular expression for a sequence of whitespace and comments in Perl.")
+
+ ;; This is left as a string regexp. There are many version schemes in
+ ;; the wild, so people might want to fiddle with this variable.
+ (defconst cperl--version-regexp
+ (rx-to-string
+ `(or
+ (sequence (optional "v")
+ (>= 2 (sequence (1+ digit) "."))
+ (1+ digit)
+ (optional (sequence "_" (1+ word))))
+ (sequence (1+ digit)
+ (optional (sequence "." (1+ digit)))
+ (optional (sequence "_" (1+ word))))))
+ "A sequence for recommended version number schemes in Perl.")
+
+ (defconst cperl--package-rx
+ `(sequence (group "package")
+ ,cperl--ws+-rx
+ (group ,cperl--normal-identifier-rx)
+ (optional (sequence ,cperl--ws+-rx
+ (group (regexp ,cperl--version-regexp)))))
+ "A regular expression for package NAME VERSION in Perl.
+Contains three groups for the keyword \"package\", for the
+package name and for the version.")
+
+ (defconst cperl--package-for-imenu-rx
+ `(sequence symbol-start
+ (group-n 1 "package")
+ ,cperl--ws*-rx
+ (group-n 2 ,cperl--normal-identifier-rx)
+ (optional (sequence ,cperl--ws+-rx
+ (regexp ,cperl--version-regexp)))
+ ,cperl--ws*-rx
+ (group-n 3 (or ";" "{")))
+ "A regular expression to collect package names for `imenu'.
Catches \"package NAME;\", \"package NAME VERSION;\", \"package
NAME BLOCK\" and \"package NAME VERSION BLOCK.\" Contains three
-groups: Two from `cperl--package-regexp` for the package name and
-version, and a third to detect \"package BLOCK\" syntax.")
-
-(defconst cperl--sub-name-regexp
- (rx-to-string
- `(sequence
- (optional (sequence (group (or "my" "state" "our"))
- (regexp ,cperl--ws-or-comment-regexp)))
- "sub" ; FIXME: the "method" and maybe "fun" keywords need to be
- ; recognized soon...ish.
- (regexp ,cperl--ws-or-comment-regexp)
- (group (regexp ,cperl--normal-identifier-regexp))))
- "A regular expression to detect a subroutine start.
-Contains two groups: One for to distinguish lexical from
-\"normal\" subroutines and one for the subroutine name.")
-
-(defconst cperl--pod-heading-regexp
- (rx-to-string
- `(sequence
- line-start "=head"
- (group (in "1-4"))
- (1+ (in " \t"))
- (group (1+ (not (in "\n"))))
- line-end)) ; that line-end seems to be redundant?
+groups: One for the keyword \"package\", one for the package
+name, and one for the discovery of a following BLOCK.")
+
+ (defconst cperl--sub-name-for-imenu-rx
+ `(sequence symbol-start
+ (optional (sequence (group-n 3 (or "my" "state" "our"))
+ ,cperl--ws+-rx))
+ (group-n 1 "sub")
+ ,cperl--ws+-rx
+ (group-n 2 ,cperl--normal-identifier-rx))
+ "A regular expression to detect a subroutine start.
+Contains three groups: One one to distinguish lexical from
+\"normal\" subroutines, for the keyword \"sub\", and one for the
+subroutine name.")
+
+(defconst cperl--block-declaration-rx
+ `(sequence
+ (or "package" "sub") ; "class" and "method" coming soon
+ (1+ ,cperl--ws-or-comment-rx)
+ ,cperl--normal-identifier-rx)
+ "A regular expression to find a declaration for a named block.
+Used for indentation. These declarations introduce a block which
+does not need a semicolon to terminate the statement.")
+
+(defconst cperl--pod-heading-rx
+ `(sequence line-start
+ (group-n 1 "=head")
+ (group-n 3 (in "1-4"))
+ (1+ (in " \t"))
+ (group-n 2 (1+ (not (in "\n")))))
"A regular expression to detect a POD heading.
Contains two groups: One for the heading level, and one for the
heading text.")
-(defconst cperl--imenu-entries-regexp
- (rx-to-string
- `(or
- (regexp ,cperl--package-for-imenu-regexp) ; 1..3
- (regexp ,cperl--sub-name-regexp) ; 4..5
- (regexp ,cperl--pod-heading-regexp))) ; 6..7
- "A regular expression to collect stuff that goes into the `imenu` index.
+(defconst cperl--imenu-entries-rx
+ `(or ,cperl--package-for-imenu-rx
+ ,cperl--sub-name-for-imenu-rx
+ ,cperl--pod-heading-rx)
+ "A regular expression to collect stuff that goes into the `imenu' index.
Covers packages, subroutines, and POD headings.")
+;; end of eval-and-compiled stuff
+)
+
+
+(defun cperl-block-declaration-p ()
+ "Test whether the following ?\\{ opens a declaration block.
+Returns the column where the declarating keyword is found, or nil
+if this isn't a declaration block. Declaration blocks are named
+subroutines, packages and the like. They start with a keyword
+and a name, to be followed by various descriptive items which are
+just skipped over for our purpose. Declaration blocks end a
+statement, so there's no semicolon."
+ ;; A scan error means that none of the declarators has been found
+ (condition-case nil
+ (let ((is-block-declaration nil)
+ (continue-searching t))
+ (while (and continue-searching (not (bobp)))
+ (forward-sexp -1)
+ (cond
+ ((looking-at (rx (eval cperl--block-declaration-rx)))
+ (setq is-block-declaration (current-column)
+ continue-searching nil))
+ ;; Another brace means this is no block declaration
+ ((looking-at "{")
+ (setq continue-searching nil))
+ (t
+ (cperl-backward-to-noncomment (point-min))
+ ;; A semicolon or an opening brace prevent this block from
+ ;; being a block declaration
+ (when (or (eq (preceding-char) ?\;)
+ (eq (preceding-char) ?{))
+ (setq continue-searching nil)))))
+ is-block-declaration)
+ (error nil)))
+
;; These two must be unwound, otherwise take exponential time
-(defconst cperl-maybe-white-and-comment-rex "[ \t\n]*\\(#[^\n]*\n[ \t\n]*\\)*"
+(defconst cperl-maybe-white-and-comment-rex
+ (rx (group (eval cperl--ws*-rx)))
+ ;; was: "[ \t\n]*\\(#[^\n]*\n[ \t\n]*\\)*"
"Regular expression to match optional whitespace with interspersed comments.
Should contain exactly one group.")
;; This one is tricky to unwind; still very inefficient...
-(defconst cperl-white-and-comment-rex "\\([ \t\n]\\|#[^\n]*\n\\)+"
+(defconst cperl-white-and-comment-rex
+ (rx (group (eval cperl--ws+-rx)))
+ ;; was: "\\([ \t\n]\\|#[^\n]*\n\\)+"
"Regular expression to match whitespace with interspersed comments.
Should contain exactly one group.")
@@ -1366,7 +1401,7 @@ the last)."
(concat ; Assume n groups before this...
"\\(" ; n+1=name-group
cperl-white-and-comment-rex ; n+2=pre-name
- "\\(::[a-zA-Z_0-9:']+\\|[a-zA-Z_'][a-zA-Z_0-9:']*\\)" ; n+3=name
+ (rx-to-string `(group ,cperl--normal-identifier-rx))
"\\)" ; END n+1=name-group
(if named "" "?")
"\\(" ; n+4=proto-group
@@ -1405,28 +1440,9 @@ the last)."
when (eq char (aref keyword (1- (length keyword))))
return t))
-;; Details of groups in this are used in `cperl-imenu--create-perl-index'
-;; and `cperl-outline-level'.
-;; Was: 2=sub|package; now 2=package-group, 5=package-name 8=sub-name (+3)
-(defvar cperl-imenu--function-name-regexp-perl
- (concat
- "^\\(" ; 1 = all
- "\\([ \t]*package" ; 2 = package-group
- "\\(" ; 3 = package-name-group
- cperl-white-and-comment-rex ; 4 = pre-package-name
- "\\([a-zA-Z_0-9:']+\\)\\)?\\)" ; 5 = package-name
- "\\|"
- "[ \t]*"
- cperl-sub-regexp
- (cperl-after-sub-regexp 'named nil) ; 8=name 11=proto 14=attr-start
- cperl-maybe-white-and-comment-rex ; 15=pre-block
- "\\|"
- "=head\\([1-4]\\)[ \t]+" ; 16=level
- "\\([^\n]+\\)$" ; 17=text
- "\\)"))
-
(defvar cperl-outline-regexp
- (concat cperl-imenu--function-name-regexp-perl "\\|" "\\`"))
+ (rx (sequence line-start (0+ blank) (eval cperl--imenu-entries-rx)))
+ "The regular expression used for `outline-minor-mode'.")
(defvar cperl-mode-syntax-table nil
"Syntax table in use in CPerl mode buffers.")
@@ -1562,7 +1578,7 @@ into
\\{cperl-mode-map}
-Setting the variable `cperl-font-lock' to t switches on font-lock-mode
+Setting the variable `cperl-font-lock' to t switches on `font-lock-mode'
\(even with older Emacsen), `cperl-electric-lbrace-space' to t switches
on electric space between $ and {, `cperl-electric-parens-string' is
the string that contains parentheses that should be electric in CPerl
@@ -1741,7 +1757,9 @@ or as help on variables `cperl-tips', `cperl-problems',
'((cperl-load-font-lock-keywords
cperl-load-font-lock-keywords-1
cperl-load-font-lock-keywords-2)
- nil nil ((?_ . "w"))))
+ nil nil ((?_ . "w")) nil
+ (font-lock-syntactic-face-function
+ . cperl-font-lock-syntactic-face-function)))
;; Reset syntaxification cache.
(setq-local cperl-syntax-state nil)
(when cperl-use-syntax-table-text-property
@@ -2451,7 +2469,8 @@ Will untabify if `cperl-electric-backspace-untabify' is non-nil."
(put 'cperl-electric-backspace 'delete-selection 'supersede)
-(defun cperl-inside-parens-p () ;; NOT USED????
+(defun cperl-inside-parens-p ()
+ (declare (obsolete nil "28.1")) ; not used
(condition-case ()
(save-excursion
(save-restriction
@@ -2514,8 +2533,9 @@ Return the amount the indentation changed by."
(t
(skip-chars-forward " \t")
(if (listp indent) (setq indent (car indent)))
- (cond ((and (looking-at "[A-Za-z_][A-Za-z_0-9]*:[^:]")
- (not (looking-at "[smy]:\\|tr:")))
+ (cond ((and (looking-at (rx (sequence (eval cperl--label-rx)
+ (not (in ":")))))
+ (not (looking-at (rx (eval cperl--false-label-rx)))))
(and (> indent 0)
(setq indent (max cperl-min-label-indent
(+ indent cperl-label-offset)))))
@@ -2547,12 +2567,13 @@ Return the amount the indentation changed by."
'(?w ?_))
(progn
(backward-sexp)
- (looking-at "[a-zA-Z_][a-zA-Z0-9_]*:[^:]"))))
+ (looking-at (rx (sequence (eval cperl--label-rx)
+ (not (in ":"))))))))
(defun cperl-get-state (&optional parse-start start-state)
- "Return list (START STATE DEPTH PRESTART),
+ "Return list (START STATE DEPTH PRESTART).
START is a good place to start parsing, or equal to
-PARSE-START if preset,
+PARSE-START if preset.
STATE is what is returned by `parse-partial-sexp'.
DEPTH is true is we are immediately after end of block
which contains START.
@@ -2707,12 +2728,16 @@ Will not look before LIM."
(and (eq (preceding-char) ?\})
(cperl-after-block-and-statement-beg
(point-min))) ; Was start - too close
+ (and char-after (char-equal char-after ?{)
+ (save-excursion (cperl-block-declaration-p)))
(memq char-after (append ")]}" nil))
(and (eq (preceding-char) ?\:) ; label
(progn
(forward-sexp -1)
(skip-chars-backward " \t")
- (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*[ \t]*:")))
+ (looking-at
+ (rx (sequence (0+ blank)
+ (eval cperl--label-rx))))))
(get-text-property (point) 'first-format-line)))
;; Look at previous line that's at column 0
@@ -2750,12 +2775,10 @@ Will not look before LIM."
;; Back up over label lines, since they don't
;; affect whether our line is a continuation.
;; (Had \, too)
- (while;;(or (eq (preceding-char) ?\,)
- (and (eq (preceding-char) ?:)
- (or;;(eq (char-after (- (point) 2)) ?\') ; ????
- (memq (char-syntax (char-after (- (point) 2)))
- '(?w ?_))))
- ;;)
+ (while (and (eq (preceding-char) ?:)
+ (re-search-backward
+ (rx (sequence (eval cperl--label-rx) point))
+ nil t))
;; This is always FALSE?
(if (eq (preceding-char) ?\,)
;; Will go to beginning of line, essentially.
@@ -2767,6 +2790,7 @@ Will not look before LIM."
(if (not (or (eq (1- (point)) containing-sexp)
(and cperl-indent-parens-as-block
(not is-block))
+ (save-excursion (cperl-block-declaration-p))
(memq (preceding-char)
(append (if is-block " ;{" " ,;{") '(nil)))
(and (eq (preceding-char) ?\})
@@ -2795,10 +2819,17 @@ Will not look before LIM."
(forward-char 1)
(let ((colon-line-end 0))
(while
- (progn (skip-chars-forward " \t\n")
- ;; s: foo : bar :x is NOT label
- (and (looking-at "#\\|\\([a-zA-Z0-9_$]+\\):[^:]\\|=[a-zA-Z]")
- (not (looking-at "[sym]:\\|tr:"))))
+ (progn
+ (skip-chars-forward " \t\n")
+ ;; s: foo : bar :x is NOT label
+ (and (looking-at
+ (rx
+ (or "#"
+ (sequence (eval cperl--label-rx)
+ (not (in ":")))
+ (sequence "=" (in "a-zA-Z")))))
+ (not (looking-at
+ (rx (eval cperl--false-label-rx))))))
;; Skip over comments and labels following openbrace.
(cond ((= (following-char) ?\#)
(forward-line 1))
@@ -3057,7 +3088,10 @@ and closing parentheses and brackets."
;; If line starts with label, calculate label indentation
(if (save-excursion
(beginning-of-line)
- (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]"))
+ (looking-at (rx
+ (sequence (0+ space)
+ (eval cperl--label-rx)
+ (not (in ":"))))))
(if (> (current-indentation) cperl-min-label-indent)
(- (current-indentation) cperl-label-offset)
;; Do not move `parse-data', this should
@@ -3070,8 +3104,9 @@ and closing parentheses and brackets."
(error "Got strange value of indent: %s" i))))))
(defun cperl-calculate-indent-within-comment ()
- "Return the indentation amount for line, assuming that
-the current line is to be regarded as part of a block comment."
+ "Return the indentation amount for line.
+Assume that the current line is to be regarded as part of a block
+comment."
(let (end)
(save-excursion
(beginning-of-line)
@@ -3147,26 +3182,29 @@ Returns true if comment is found. In POD will not move the point."
(while (re-search-forward "^\\s(" e 'to-end)
(put-text-property (1- (point)) (point) 'syntax-table cperl-st-punct))))
-(defun cperl-commentify (bb e string &optional noface)
- (if cperl-use-syntax-table-text-property
- (if (eq noface 'n) ; Only immediate
- nil
- ;; We suppose that e is _after_ the end of construction, as after eol.
- (setq string (if string cperl-st-sfence cperl-st-cfence))
- (if (> bb (- e 2))
+(defun cperl-commentify (begin end string)
+ "Mark text from BEGIN to END as generic string or comment.
+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."
+ (if (and cperl-use-syntax-table-text-property
+ (> end begin))
+ (progn
+ (setq string (if string cperl-st-sfence cperl-st-cfence))
+ (if (> begin (- end 2))
;; one-char string/comment?!
- (cperl-modify-syntax-type bb cperl-st-punct)
- (cperl-modify-syntax-type bb string)
- (cperl-modify-syntax-type (1- e) string))
- (if (and (eq string cperl-st-sfence) (> (- e 2) bb))
- (put-text-property (1+ bb) (1- e)
+ (cperl-modify-syntax-type begin cperl-st-punct)
+ (cperl-modify-syntax-type begin string)
+ (cperl-modify-syntax-type (1- end) string))
+ (if (and (eq string cperl-st-sfence) (> (- end 2) begin))
+ (put-text-property (1+ begin) (1- end)
'syntax-table cperl-string-syntax-table))
- (cperl-protect-defun-start bb e))
+ (cperl-protect-defun-start begin end))
;; Fontify
- (or noface
- (not cperl-pod-here-fontify)
- (put-text-property bb e 'face (if string 'font-lock-string-face
- 'font-lock-comment-face)))))
+ (when cperl-pod-here-fontify
+ (put-text-property begin end 'face (if string 'font-lock-string-face
+ 'font-lock-comment-face)))))
(defvar cperl-starters '(( ?\( . ?\) )
( ?\[ . ?\] )
@@ -3333,8 +3371,10 @@ Works before syntax recognition is done."
;; Each non-literal part is marked `syntax-type' ==> `pod'
;; Each literal part is marked `syntax-type' ==> `in-pod'
;; b) HEREs:
+;; The point before start is marked `here-doc-start'
;; Start-to-end is marked `here-doc-group' ==> t
;; The body is marked `syntax-type' ==> `here-doc'
+;; and is also marked as style 2 comment
;; The delimiter is marked `syntax-type' ==> `here-doc-delim'
;; c) FORMATs:
;; First line (to =) marked `first-format-line' ==> t
@@ -3351,8 +3391,36 @@ Works before syntax recognition is done."
;; (value: 0 in //o, 1 if "interpolated variable" is whole-REx, t otherwise).
(defun cperl-unwind-to-safe (before &optional end)
- ;; if BEFORE, go to the previous start-of-line on each step of unwinding
- (let ((pos (point)))
+ "Move point back to a safe place, back up one extra line if BEFORE.
+A place is \"safe\" if it is not within POD, a here-document, a
+format, a quote-like expression, a subroutine attribute list or a
+multiline declaration. These places all have special syntactical
+rules and need to be parsed as a whole. If END, return the
+position of the end of the unsafe construct."
+ (let ((pos (point))
+ (state (syntax-ppss)))
+ ;; Check edge cases for here-documents first
+ (when before ; we need a safe start for parsing
+ (cond
+ ((or (equal (get-text-property (cperl-1- (point)) 'syntax-type)
+ 'here-doc-start)
+ (equal (syntax-after (cperl-1- (point)))
+ (string-to-syntax "> c")))
+ ;; point is either immediately after the start of a here-doc
+ ;; (which may consist of nothing but one newline) or
+ ;; immediately after the now-outdated end marker of the
+ ;; here-doc. In both cases we need to back up to the line
+ ;; where the here-doc delimiters are defined.
+ (forward-char -1)
+ (cperl-backward-to-noncomment (point-min))
+ (beginning-of-line))
+ ((eq 2 (nth 7 state))
+ ;; point is somewhere in a here-document. Back up to the line
+ ;; where the here-doc delimiters are defined.
+ (goto-char (nth 8 state)) ; beginning of this here-doc
+ (cperl-backward-to-noncomment ; skip back over more
+ (point-min)) ; here-documents (if any)
+ (beginning-of-line)))) ; skip back over here-doc starters
(while (and pos (progn
(beginning-of-line)
(get-text-property (setq pos (point)) 'syntax-type)))
@@ -3510,19 +3578,194 @@ Should be called with the point before leading colon of an attribute."
(goto-char endbracket) ; just in case something misbehaves???
t))
+(defvar cperl-here-doc-functions
+ (regexp-opt '("print" "printf" "say" ; print $handle <<EOF
+ "system" "exec" ; system $progname <<EOF
+ "sort") ; sort $subname <<EOF
+ 'symbols) ; avoid false positives
+ "List of keywords after which `$var <<bareword' is a here-document.
+After any other token `$var <<bareword' is treated as the variable `$var'
+left-shifted by the return value of the function `bareword'.")
+
+(defun cperl-is-here-doc-p (start)
+ "Find out whether a \"<<\" construct starting at START is a here-document.
+The point is expected to be after the end of the delimiter.
+Quoted delimiters after \"<<\" are unambiguously starting
+here-documents and are not handled here. This function does not
+move point but does change match data."
+ ;; not a here-doc | here-doc
+ ;; $foo << b; | $f .= <<B;
+ ;; ($f+1) << b; | a($f) . <<B;
+ ;; foo 1, <<B; | $x{a} <<b;
+ ;; Limitations:
+ ;; foo <<bar is statically undecidable. It could be either
+ ;; foo() << bar # left shifting the return value or
+ ;; foo(<<bar) # passing a here-doc to foo().
+ ;; We treat it as here-document and kindly ask programmers to
+ ;; disambiguate by adding parens.
+ (null
+ (or (looking-at "[ \t]*(") ; << function_call()
+ (looking-at ">>") ; <<>> operator
+ (save-excursion ; 1 << func_name, or $foo << 10
+ (condition-case nil
+ (progn
+ (goto-char start)
+ (forward-sexp -1) ;; examine the part before "<<"
+ (save-match-data
+ (cond
+ ((looking-at "[0-9$({]")
+ (forward-sexp 1)
+ (and
+ (looking-at "[ \t]*<<")
+ (condition-case nil
+ ;; print $foo <<EOF
+ (progn
+ (forward-sexp -2)
+ (not
+ (looking-at cperl-here-doc-functions)))
+ (error t)))))))
+ (error nil)))))) ; func(<<EOF)
+
+(defun cperl-process-here-doc (min max end overshoot stop-point
+ end-of-here-doc err-l
+ indented-here-doc-p
+ matched-pos todo-pos
+ delim-begin delim-end)
+ "Process a here-document's delimiters and body.
+The parameters MIN, MAX, END, OVERSHOOT, STOP-POINT, ERR-L are
+used for recursive calls to `cperl-find-pods-here' to handle the
+rest of the line which contains the delimiter. MATCHED-POS and
+TODO-POS are initial values for this function's result.
+END-OF-HERE-DOC is the end of a previous here-doc in the same
+line, or nil if this is the first. DELIM-BEGIN and DELIM-END are
+the positions where the here-document's delimiter has been found.
+This is part of `cperl-find-pods-heres' (below)."
+ (let* ((my-cperl-delimiters-face font-lock-constant-face)
+ (delimiter (buffer-substring-no-properties delim-begin delim-end))
+ (qtag (regexp-quote delimiter))
+ (use-syntax-state (and cperl-syntax-state
+ (>= min (car cperl-syntax-state))))
+ (state-point (if use-syntax-state
+ (car cperl-syntax-state)
+ (point-min)))
+ (state (if use-syntax-state
+ (cdr cperl-syntax-state)))
+ here-doc-start here-doc-end defs-eol
+ warning-message)
+ (when cperl-pod-here-fontify
+ ;; Highlight the starting delimiter
+ (cperl-postpone-fontification delim-begin delim-end
+ 'face my-cperl-delimiters-face)
+ (cperl-put-do-not-fontify delim-begin delim-end t))
+ (forward-line)
+ (setq here-doc-start (point) ; first char of (first) here-doc
+ defs-eol (1- here-doc-start)) ; end of definitions line
+ (if end-of-here-doc
+ ;; skip to the end of the previous here-doc
+ (goto-char end-of-here-doc)
+ ;; otherwise treat the first (or only) here-doc: Check for
+ ;; special cases if the line containing the delimiter(s)
+ ;; ends in a regular comment or a solitary ?#
+ (let* ((eol-state (save-excursion (syntax-ppss defs-eol))))
+ (when (nth 4 eol-state) ; EOL is in a comment
+ (if (= (1- defs-eol) (nth 8 eol-state))
+ ;; line ends with a naked comment starter.
+ ;; We let it start the here-doc.
+ (progn
+ (put-text-property (1- defs-eol) defs-eol
+ 'font-lock-face
+ 'font-lock-comment-face)
+ (put-text-property (1- defs-eol) defs-eol
+ 'syntax-type 'here-doc)
+ (put-text-property (1- defs-eol) defs-eol
+ 'syntax-type 'here-doc)
+ (put-text-property (1- defs-eol) defs-eol
+ 'syntax-table
+ (string-to-syntax "< c"))
+ )
+ ;; line ends with a "regular" comment: make
+ ;; the last character of the comment closing
+ ;; it so that we can use the line feed to
+ ;; start the here-doc
+ (put-text-property (1- defs-eol) defs-eol
+ 'syntax-table
+ (string-to-syntax ">"))))))
+ (setq here-doc-start (point)) ; now points to current here-doc
+ ;; Find the terminating delimiter.
+ ;; We do not search to max, since we may be called from
+ ;; some hook of fontification, and max is random
+ (or (re-search-forward
+ (concat "^" (when indented-here-doc-p "[ \t]*")
+ qtag "$")
+ stop-point 'toend)
+ (progn ; Pretend we matched at the end
+ (goto-char (point-max))
+ (re-search-forward "\\'")
+ (setq warning-message
+ (format "End of here-document `%s' not found." delimiter))
+ (or (car err-l) (setcar err-l here-doc-start))))
+ (when cperl-pod-here-fontify
+ ;; Highlight the ending delimiter
+ (cperl-postpone-fontification
+ (match-beginning 0) (match-end 0)
+ 'face my-cperl-delimiters-face)
+ (cperl-put-do-not-fontify here-doc-start (match-end 0) t))
+ (setq here-doc-end (cperl-1+ (match-end 0))) ; eol after delim
+ (put-text-property here-doc-start (match-beginning 0)
+ 'syntax-type 'here-doc)
+ (put-text-property (match-beginning 0) here-doc-end
+ 'syntax-type 'here-doc-delim)
+ (put-text-property here-doc-start here-doc-end 'here-doc-group t)
+ ;; This makes insertion at the start of HERE-DOC update
+ ;; the whole construct:
+ (put-text-property here-doc-start (cperl-1+ here-doc-start) 'front-sticky '(syntax-type))
+ (cperl-commentify (match-beginning 0) (1- here-doc-end) nil)
+ (put-text-property (1- here-doc-start) here-doc-start
+ 'syntax-type 'here-doc-start)
+ (when (> (match-beginning 0) here-doc-start)
+ ;; here-document has non-zero length
+ (cperl-modify-syntax-type (1- here-doc-start) (string-to-syntax "< c"))
+ (cperl-modify-syntax-type (1- (match-beginning 0))
+ (string-to-syntax "> c")))
+ (cperl-put-do-not-fontify here-doc-start (match-end 0) t)
+ ;; Cache the syntax info...
+ (setq cperl-syntax-state (cons state-point state))
+ ;; ... and process the rest of the line...
+ (setq overshoot
+ (elt ; non-inter ignore-max
+ (cperl-find-pods-heres todo-pos defs-eol
+ t end t here-doc-end)
+ 1))
+ (if (and overshoot (> overshoot (point)))
+ (goto-char overshoot)
+ (setq overshoot here-doc-end))
+ (list (if (> here-doc-end max) matched-pos nil)
+ 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)
- "Scans the buffer for hard-to-parse Perl constructions.
-If `cperl-pod-here-fontify' is not-nil after evaluation, will fontify
-the sections using `cperl-pod-head-face', `cperl-pod-face',
-`cperl-here-face'."
+ "Scan the buffer for hard-to-parse Perl constructions.
+If `cperl-pod-here-fontify' is non-nil after evaluation,
+fontify the sections using `cperl-pod-head-face',
+`cperl-pod-face', `cperl-here-face'. The optional parameters are
+for internal use: scan from MIN to MAX, or the whole buffer if
+these are nil. If NON-INTER, don't write progress messages. If
+IGNORE-MAX, scan to end of buffer. If END, we are after a
+\"__END__\" or \"__DATA__\" token, so ignore unbalanced
+constructs. END-OF-HERE-DOC points to the end of a here-document
+which has already been processed.
+Value is a two-element list of the position where an error
+occurred (if any) and the \"overshoot\", which is used for
+recursive calls in starting lines of here-documents."
(interactive)
(or min (setq min (point-min)
cperl-syntax-state nil
cperl-syntax-done-to min))
(or max (setq max (point-max)))
- (let* ((cperl-pod-here-fontify (eval cperl-pod-here-fontify)) go tmpend
- face head-face here-face b e bb tag qtag b1 e1 argument i c tail tb
+ (font-lock-flush min max)
+ (let* (go tmpend
+ face head-face b e bb tag qtag b1 e1 argument i c tail tb
is-REx is-x-REx REx-subgr-start REx-subgr-end was-subgr i2 hairy-RE
(case-fold-search nil) (inhibit-read-only t) (buffer-undo-list t)
(modified (buffer-modified-p)) overshoot is-o-REx name
@@ -3591,7 +3834,8 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
"\\<" cperl-sub-regexp "\\>" ; sub with proto/attr
"\\("
cperl-white-and-comment-rex
- "\\(::[a-zA-Z_:'0-9]*\\|[a-zA-Z_'][a-zA-Z_:'0-9]*\\)\\)?" ; name
+ (rx (group (eval cperl--normal-identifier-rx)))
+ "\\)"
"\\("
cperl-maybe-white-and-comment-rex
"\\(([^()]*)\\|:[^:]\\)\\)" ; prototype or attribute start
@@ -3619,20 +3863,20 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
(and cperl-pod-here-fontify
;; We had evals here, do not know why...
(setq face cperl-pod-face
- head-face cperl-pod-head-face
- here-face cperl-here-face))
- (remove-text-properties min max
- '(syntax-type t in-pod t syntax-table t
- attrib-group t
- REx-interpolated t
- cperl-postpone t
- syntax-subtype t
- rear-nonsticky t
- front-sticky t
- here-doc-group t
- first-format-line t
- REx-part2 t
- indentable t))
+ head-face cperl-pod-head-face))
+ (unless end-of-here-doc
+ (remove-text-properties min max
+ '(syntax-type t in-pod t syntax-table t
+ attrib-group t
+ REx-interpolated t
+ cperl-postpone t
+ syntax-subtype t
+ rear-nonsticky t
+ front-sticky t
+ here-doc-group t
+ first-format-line t
+ REx-part2 t
+ indentable t)))
;; Need to remove face as well...
(goto-char min)
(while (and
@@ -3751,120 +3995,36 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
;; but multiline quote on the same line as <<HERE confuses us...
;; ;; One extra () before this:
;;"<<"
- ;; "\\(" ; 1 + 1
+ ;; "<<\\(~?\\)" ; HERE-DOC, indented-p = capture 2
;; ;; First variant "BLAH" or just ``.
;; "[ \t]*" ; Yes, whitespace is allowed!
- ;; "\\([\"'`]\\)" ; 2 + 1
- ;; "\\([^\"'`\n]*\\)" ; 3 + 1
- ;; "\\3"
+ ;; "\\([\"'`]\\)" ; 3 + 1
+ ;; "\\([^\"'`\n]*\\)" ; 4 + 1
+ ;; "\\4"
;; "\\|"
;; ;; Second variant: Identifier or \ID or empty
- ;; "\\\\?\\(\\([a-zA-Z_][a-zA-Z_0-9]*\\)?\\)" ; 4 + 1, 5 + 1
+ ;; "\\\\?\\(\\([a-zA-Z_][a-zA-Z_0-9]*\\)?\\)" ; 5 + 1, 6 + 1
;; ;; Do not have <<= or << 30 or <<30 or << $blah.
;; ;; "\\([^= \t0-9$@%&]\\|[ \t]+[^ \t\n0-9$@%&]\\)" ; 6 + 1
- ;; "\\(\\)" ; To preserve count of pars :-( 6 + 1
;; "\\)"
- ((match-beginning 3) ; 2 + 1: found "<<", detect its type
- (setq b (point)
- tb (match-beginning 0)
- c (and ; not HERE-DOC
- (match-beginning 6)
- (save-match-data
- (or (looking-at "[ \t]*(") ; << function_call()
- (looking-at ">>") ; <<>> operator
- (save-excursion ; 1 << func_name, or $foo << 10
- (condition-case nil
- (progn
- (goto-char tb)
- ;;; XXX What to do: foo <<bar ???
- ;;; XXX Need to support print {a} <<B ???
- (forward-sexp -1)
- (save-match-data
- ; $foo << b; $f .= <<B;
- ; ($f+1) << b; a($f) . <<B;
- ; foo 1, <<B; $x{a} <<b;
- (cond
- ((looking-at "[0-9$({]")
- (forward-sexp 1)
- (and
- (looking-at "[ \t]*<<")
- (condition-case nil
- ;; print $foo <<EOF
- (progn
- (forward-sexp -2)
- (not
- (looking-at "\\(printf?\\|say\\|system\\|exec\\|sort\\)\\>")))
- (error t)))))))
- (error nil))) ; func(<<EOF)
- (and (not (match-beginning 7)) ; Empty
- (looking-at
- "[ \t]*[=0-9$@%&(]"))))))
- (if c ; Not here-doc
- nil ; Skip it.
- (setq c (match-end 3)) ; 2 + 1
- (if (match-beginning 6) ;6 + 1
- (setq b1 (match-beginning 6) ; 5 + 1
- e1 (match-end 6)) ; 5 + 1
- (setq b1 (match-beginning 5) ; 4 + 1
- e1 (match-end 5))) ; 4 + 1
- (setq tag (buffer-substring b1 e1)
- qtag (regexp-quote tag))
- (cond (cperl-pod-here-fontify
- ;; Highlight the starting delimiter
- (cperl-postpone-fontification
- b1 e1 'face my-cperl-delimiters-face)
- (cperl-put-do-not-fontify b1 e1 t)))
- (forward-line)
- (setq i (point))
- (if end-of-here-doc
- (goto-char end-of-here-doc))
- (setq b (point))
- ;; We do not search to max, since we may be called from
- ;; some hook of fontification, and max is random
- (or (and (re-search-forward
- (concat "^" (when (equal (match-string 2) "~") "[ \t]*")
- qtag "$")
- stop-point 'toend)
- ;;;(eq (following-char) ?\n) ; XXXX WHY???
- )
- (progn ; Pretend we matched at the end
- (goto-char (point-max))
- (re-search-forward "\\'")
- (setq warning-message
- (format "End of here-document `%s' not found." tag))
- (or (car err-l) (setcar err-l b))))
- (if cperl-pod-here-fontify
- (progn
- ;; Highlight the ending delimiter
- (cperl-postpone-fontification
- (match-beginning 0) (match-end 0)
- 'face my-cperl-delimiters-face)
- (cperl-put-do-not-fontify b (match-end 0) t)
- ;; Highlight the HERE-DOC
- (cperl-postpone-fontification b (match-beginning 0)
- 'face here-face)))
- (setq e1 (cperl-1+ (match-end 0)))
- (put-text-property b (match-beginning 0)
- 'syntax-type 'here-doc)
- (put-text-property (match-beginning 0) e1
- 'syntax-type 'here-doc-delim)
- (put-text-property b e1 'here-doc-group t)
- ;; This makes insertion at the start of HERE-DOC update
- ;; the whole construct:
- (put-text-property b (cperl-1+ b) 'front-sticky '(syntax-type))
- (cperl-commentify b e1 nil)
- (cperl-put-do-not-fontify b (match-end 0) t)
- ;; Cache the syntax info...
- (setq cperl-syntax-state (cons state-point state))
- ;; ... and process the rest of the line...
- (setq overshoot
- (elt ; non-inter ignore-max
- (cperl-find-pods-heres c i t end t e1) 1))
- (if (and overshoot (> overshoot (point)))
- (goto-char overshoot)
- (setq overshoot e1))
- (if (> e1 max)
- (setq tmpend tb))))
+ ((match-beginning 3) ; 2 + 1: found "<<", detect its type
+ (let* ((matched-pos (match-beginning 0))
+ (quoted-delim-p (if (match-beginning 6) nil t))
+ (delim-capture (if quoted-delim-p 5 6)))
+ (when (cperl-is-here-doc-p matched-pos)
+ (let ((here-doc-results
+ (cperl-process-here-doc
+ min max end overshoot stop-point ; for recursion
+ end-of-here-doc err-l ; for recursion
+ (equal (match-string 2) "~") ; indented here-doc?
+ matched-pos ; for recovery (?)
+ (match-end 3) ; todo from here
+ (match-beginning delim-capture) ; starting delimiter
+ (match-end delim-capture)))) ; boundaries
+ (setq tmpend (nth 0 here-doc-results)
+ overshoot (nth 1 here-doc-results))
+ (and (nth 2 here-doc-results)
+ (setq warning-message (nth 2 here-doc-results)))))))
;; format
((match-beginning 8)
;; 1+6=7 extra () before this:
@@ -3950,10 +4110,12 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
(t t))))
;; <file> or <$file>
(and (eq c ?\<)
- ;; Do not stringify <FH>, <$fh> :
+ ;; Stringify what looks like a glob, but
+ ;; do not stringify file handles <FH>, <$fh> :
(save-match-data
(looking-at
- "\\$?\\([_a-zA-Z:][_a-zA-Z0-9:]*\\)?>"))))
+ (rx (sequence (opt "$")
+ (eval cperl--normal-identifier-rx)))))))
tb (match-beginning 0))
(goto-char (match-beginning b1))
(cperl-backward-to-noncomment (point-min))
@@ -4023,7 +4185,16 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
(error nil)))
(if (or bb
(looking-at ; $foo -> {s}
- "[$@]\\$*\\([a-zA-Z0-9_:]+\\|[^{]\\)\\([ \t\n]*->\\)?[ \t\n]*{")
+ (rx
+ (sequence
+ (in "$@") (0+ "$")
+ (or
+ (eval cperl--normal-identifier-rx)
+ (not (in "{")))
+ (opt (sequence (eval cperl--ws*-rx))
+ "->")
+ (eval cperl--ws*-rx)
+ "{")))
(and ; $foo[12] -> {s}
(memq (following-char) '(?\{ ?\[))
(progn
@@ -4038,7 +4209,12 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
(setq bb t))
((and (eq (following-char) ?:)
(eq b1 ?\{) ; Check for $ { s::bar }
- (looking-at "::[a-zA-Z0-9_:]*[ \t\n\f]*}")
+ ;; (looking-at "::[a-zA-Z0-9_:]*[ \t\n\f]*}")
+ (looking-at
+ (rx (sequence "::"
+ (eval cperl--normal-identifier-rx)
+ (eval cperl--ws*-rx)
+ "}")))
(progn
(goto-char (1- go))
(skip-chars-backward " \t\n\f")
@@ -4203,7 +4379,7 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
"\\(" ;; XXXX 1-char variables, exc. |()\s
"[$@]"
"\\("
- "[_a-zA-Z:][_a-zA-Z0-9:]*"
+ (rx (eval cperl--normal-identifier-rx))
"\\|"
"{[^{}]*}" ; only one-level allowed
"\\|"
@@ -4642,19 +4818,24 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
(if (< p (point)) (goto-char p))
(setq stop t))))))
-;; Used only in `cperl-calculate-indent'...
+;; Used only in `cperl-sniff-for-indent'...
(defun cperl-block-p ()
- "Point is before ?\\{. Checks whether it starts a block."
+ "Point is before ?\\{. Return true if it starts a block."
;; No save-excursion! This is more a distinguisher of a block/hash ref...
(cperl-backward-to-noncomment (point-min))
(or (memq (preceding-char) (append ";){}$@&%\C-@" nil)) ; Or label! \C-@ at bobp
; Label may be mixed up with `$blah :'
(save-excursion (cperl-after-label))
+ ;; text with the 'attrib-group property is also covered by the
+ ;; next clause. We keep it because it is faster (for
+ ;; subroutines with attributes).
(get-text-property (cperl-1- (point)) 'attrib-group)
+ (save-excursion (cperl-block-declaration-p))
(and (memq (char-syntax (preceding-char)) '(?w ?_))
(progn
(backward-sexp)
;; sub {BLK}, print {BLK} $data, but NOT `bless', `return', `tr', `constant'
+ ;; a-zA-Z is fine here, these are Perl keywords
(or (and (looking-at "[a-zA-Z0-9_:]+[ \t\n\f]*[{#]") ; Method call syntax
(not (looking-at "\\(bless\\|return\\|q[wqrx]?\\|tr\\|[smy]\\|constant\\)\\>")))
;; sub bless::foo {}
@@ -4672,7 +4853,7 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
;; Moreover, one takes positive approach (looks for else,grep etc)
;; another negative (looks for bless,tr etc)
(defun cperl-after-block-p (lim &optional pre-block)
- "Return true if the preceding } (if PRE-BLOCK, following {) delimits a block.
+ "Return non-nil if the preceding } (if PRE-BLOCK, following {) delimits a block.
Would not look before LIM. Assumes that LIM is a good place to begin a
statement. The kind of block we treat here is one after which a new
statement would start; thus the block in ${func()} does not count."
@@ -4688,6 +4869,7 @@ statement would start; thus the block in ${func()} does not count."
(save-excursion (cperl-after-label))
;; sub :attr {}
(get-text-property (cperl-1- (point)) 'attrib-group)
+ (save-excursion (cperl-block-declaration-p))
(if (memq (char-syntax (preceding-char)) '(?w ?_)) ; else {}
(save-excursion
(forward-sexp -1)
@@ -4707,7 +4889,7 @@ statement would start; thus the block in ${func()} does not count."
(error nil))))
(defun cperl-after-expr-p (&optional lim chars test)
- "Return true if the position is good for start of expression.
+ "Return non-nil if the position is good for start of expression.
TEST is the expression to evaluate at the found position. If absent,
CHARS is a string that contains good characters to have before us (however,
`}' is treated \"smartly\" if it is not in the list)."
@@ -4803,7 +4985,8 @@ CHARS is a string that contains good characters to have before us (however,
(skip-chars-forward " \t"))
(defun cperl-after-block-and-statement-beg (lim)
- ;; We assume that we are after ?\}
+ "Return non-nil if the preceding ?} ends the statement."
+ ;; We assume that we are after ?\}
(and
(cperl-after-block-p lim)
(save-excursion
@@ -4861,7 +5044,11 @@ conditional/loop constructs."
cperl-maybe-white-and-comment-rex
"\\(state\\|my\\|local\\|our\\)\\)?"
cperl-maybe-white-and-comment-rex
- "\\$[_a-zA-Z0-9]+\\)?\\)\\>"))
+ (rx
+ (sequence
+ "$"
+ (eval cperl--basic-identifier-rx)))
+ "\\)?\\)\\>"))
(progn
(goto-char top)
(forward-sexp 1)
@@ -4955,7 +5142,14 @@ Returns some position at the last line."
;; Looking at:
;; foreach my $var (
(if (looking-at
- "[ \t]*\\<for\\(each\\)?[ \t]+\\(state\\|my\\|local\\|our\\)[ \t]*\\$[_a-zA-Z0-9]+\\(\t*\\|[ \t][ \t]+\\)[^ \t\n#]")
+ (rx (sequence (0+ blank) symbol-start
+ "for" (opt "each")
+ (1+ blank)
+ (or "state" "my" "local" "our")
+ (0+ blank)
+ "$" (eval cperl--basic-identifier-rx)
+ (1+ blank)
+ (not (in " \t\n#")))))
(progn
(forward-sexp 3)
(delete-horizontal-space)
@@ -4965,9 +5159,25 @@ Returns some position at the last line."
;; Looking at (with or without "}" at start, ending after "({"):
;; } foreach my $var () OR {
(if (looking-at
- "[ \t]*\\(}[ \t]*\\)?\\<\\(els\\(e\\|if\\)\\|continue\\|if\\|unless\\|while\\|for\\(each\\)?\\(\\([ \t]+\\(state\\|my\\|local\\|our\\)\\)?[ \t]*\\$[_a-zA-Z0-9]+\\)?\\|until\\)\\>\\([ \t]*(\\|[ \t\n]*{\\)\\|[ \t]*{")
+ (rx (sequence
+ (0+ blank)
+ (opt (sequence "}" (0+ blank) ))
+ symbol-start
+ (or "else" "elsif" "continue" "if" "unless" "while" "until"
+ (sequence (or "for" "foreach")
+ (opt
+ (opt (sequence (1+ blank)
+ (or "state" "my" "local" "our")))
+ (0+ blank)
+ "$" (eval cperl--basic-identifier-rx))))
+ symbol-end
+ (group-n 1
+ (or
+ (or (sequence (0+ blank) "(")
+ (sequence (eval cperl--ws*-rx) "{"))
+ (sequence (0+ blank) "{"))))))
(progn
- (setq ml (match-beginning 8)) ; "(" or "{" after control word
+ (setq ml (match-beginning 1)) ; "(" or "{" after control word
(re-search-forward "[({]")
(forward-char -1)
(setq p (point))
@@ -5279,8 +5489,12 @@ indentation and initial hashes. Behaves usually outside of comment."
;; Previous space could have gone:
(or (memq (preceding-char) '(?\s ?\t)) (insert " "))))))
+(defvar cperl-imenu-package-keywords '("package" "class" "role"))
+(defvar cperl-imenu-sub-keywords '("sub" "method" "function" "fun"))
+(defvar cperl-imenu-pod-keywords '("=head"))
+
(defun cperl-imenu--create-perl-index ()
- "Implement `imenu-create-index-function` for CPerl mode.
+ "Implement `imenu-create-index-function' for CPerl mode.
This function relies on syntaxification to exclude lines which
look like declarations but actually are part of a string, a
comment, or POD."
@@ -5297,20 +5511,21 @@ comment, or POD."
(current-package "(main)")
(current-package-end (point-max))) ; end of package scope
;; collect index entries
- (while (re-search-forward cperl--imenu-entries-regexp nil t)
+ (while (re-search-forward (rx (eval cperl--imenu-entries-rx)) nil t)
;; First, check whether we have left the scope of previously
;; recorded packages, and if so, eliminate them from the stack.
(while (< current-package-end (point))
(setq current-package (pop package-stack))
(setq current-package-end (pop package-stack)))
(let ((state (syntax-ppss))
+ (entry-type (match-string 1))
name marker) ; for the "current" entry
(cond
((nth 3 state) nil) ; matched in a string, so skip
- ((match-string 1) ; found a package name!
+ ((member entry-type cperl-imenu-package-keywords) ; package or class
(unless (nth 4 state) ; skip if in a comment
- (setq name (match-string-no-properties 1)
- marker (copy-marker (match-end 1)))
+ (setq name (match-string-no-properties 2)
+ marker (copy-marker (match-end 2)))
(if (string= (match-string 3) ";")
(setq current-package name) ; package NAME;
;; No semicolon, therefore we have: package NAME BLOCK.
@@ -5323,32 +5538,33 @@ comment, or POD."
(setq current-package-end (save-excursion
(goto-char (match-beginning 3))
(forward-sexp)
- (point)))
+ (point))))
(push (cons name marker) index-package-alist)
- (push (cons (concat "package " name) marker) index-unsorted-alist))))
- ((match-string 5) ; found a sub name!
+ (push (cons (concat entry-type " " name) marker) index-unsorted-alist)))
+ ((or (member entry-type cperl-imenu-sub-keywords) ; sub or method
+ (string-equal entry-type "")) ; named blocks
(unless (nth 4 state) ; skip if in a comment
- (setq name (match-string-no-properties 5)
- marker (copy-marker (match-end 5)))
+ (setq name (match-string-no-properties 2)
+ marker (copy-marker (match-end 2)))
;; Qualify the sub name with the package if it doesn't
;; already have one, and if it isn't lexically scoped.
;; "my" and "state" subs are lexically scoped, but "our"
;; are just lexical aliases to package subs.
(if (and (null (string-match "::" name))
- (or (null (match-string 4))
- (string-equal (match-string 4) "our")))
+ (or (null (match-string 3))
+ (string-equal (match-string 3) "our")))
(setq name (concat current-package "::" name)))
(let ((index (cons name marker)))
(push index index-alist)
(push index index-sub-alist)
(push index index-unsorted-alist))))
- ((match-string 6) ; found a POD heading!
- (when (get-text-property (match-beginning 6) 'in-pod)
+ ((member entry-type cperl-imenu-pod-keywords) ; POD heading
+ (when (get-text-property (match-beginning 2) 'in-pod)
(setq name (concat (make-string
- (* 3 (- (char-after (match-beginning 6)) ?1))
+ (* 3 (- (char-after (match-beginning 3)) ?1))
?\ )
- (match-string-no-properties 7))
- marker (copy-marker (match-beginning 7)))
+ (match-string-no-properties 2))
+ marker (copy-marker (match-beginning 2)))
(push (cons name marker) index-pod-alist)
(push (cons (concat "=" name) marker) index-unsorted-alist)))
(t (error "Unidentified match: %s" (match-string 0))))))
@@ -5371,7 +5587,11 @@ comment, or POD."
(setq lst index-sub-alist)
(while lst
(setq elt (car lst) lst (cdr lst))
- (cond ((string-match "\\(::\\|'\\)[_a-zA-Z0-9]+$" (car elt))
+ (cond ((string-match
+ (rx (sequence (or "::" "'")
+ (eval cperl--basic-identifier-rx)
+ string-end))
+ (car elt))
(setq pack (substring (car elt) 0 (match-beginning 0)))
(if (setq group (assoc pack hier-list))
(if (listp (cdr group))
@@ -5444,7 +5664,7 @@ comment, or POD."
(defvar cperl-font-lock-keywords nil
"Additional expressions to highlight in Perl mode. Default set.")
(defvar cperl-font-lock-keywords-2 nil
- "Additional expressions to highlight in Perl mode. Maximal set")
+ "Additional expressions to highlight in Perl mode. Maximal set.")
(defun cperl-load-font-lock-keywords ()
(or cperl-faces-init (cperl-init-faces))
@@ -5458,11 +5678,22 @@ comment, or POD."
(or cperl-faces-init (cperl-init-faces))
cperl-font-lock-keywords-2)
+(defun cperl-font-lock-syntactic-face-function (state)
+ "Apply faces according to their syntax type.
+In CPerl mode, this is used for here-documents which have been
+marked as c-style comments. For everything else, delegate to the
+default function."
+ (cond
+ ;; A c-style comment is a HERE-document. Fontify if requested.
+ ((and (eq 2 (nth 7 state))
+ cperl-pod-here-fontify)
+ cperl-here-face)
+ (t (funcall (default-value 'font-lock-syntactic-face-function) state))))
+
(defun cperl-init-faces ()
(condition-case errs
(progn
- (let (t-font-lock-keywords t-font-lock-keywords-1 font-lock-anchored)
- (setq font-lock-anchored t)
+ (let (t-font-lock-keywords t-font-lock-keywords-1)
(setq
t-font-lock-keywords
(list
@@ -5575,105 +5806,188 @@ comment, or POD."
(if (eq (char-after (cperl-1- (match-end 0))) ?\{ )
'font-lock-function-name-face
'font-lock-variable-name-face))))
- '("\\<\\(package\\|require\\|use\\|import\\|no\\|bootstrap\\)[ \t]+\\([a-zA-Z_][a-zA-Z_0-9:]*\\)[ \t;]" ; require A if B;
- 2 font-lock-function-name-face)
+ `(,(rx (sequence symbol-start
+ (or "package" "require" "use" "import"
+ "no" "bootstrap")
+ (eval cperl--ws+-rx)
+ (group-n 1 (eval cperl--normal-identifier-rx))
+ (any " \t;"))) ; require A if B;
+ 1 font-lock-function-name-face)
'("^[ \t]*format[ \t]+\\([a-zA-Z_][a-zA-Z_0-9:]*\\)[ \t]*=[ \t]*$"
1 font-lock-function-name-face)
- (cond (font-lock-anchored
- '("\\([]}\\%@>*&]\\|\\$[a-zA-Z0-9_:]*\\)[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
- (2 font-lock-string-face t)
- ("\\=[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
- nil nil
- (1 font-lock-string-face t))))
- (t '("\\([]}\\%@>*&]\\|\\$[a-zA-Z0-9_:]*\\)[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
- 2 font-lock-string-face t)))
- '("[[ \t{,(]\\(-?[a-zA-Z0-9_:]+\\)[ \t]*=>" 1
- font-lock-string-face t)
- '("^[ \t]*\\([a-zA-Z0-9_]+[ \t]*:\\)[ \t]*\\($\\|{\\|\\<\\(until\\|while\\|for\\(each\\)?\\|do\\)\\>\\)" 1
- font-lock-constant-face) ; labels
- '("\\<\\(continue\\|next\\|last\\|redo\\|break\\|goto\\)\\>[ \t]+\\([a-zA-Z0-9_:]+\\)" ; labels as targets
- 2 font-lock-constant-face)
+ ;; bareword hash key: $foo{bar}
+ `(,(rx (or (in "]}\\%@>*&") ; What Perl is this?
+ (sequence "$" (eval cperl--normal-identifier-rx)))
+ (0+ blank) "{" (0+ blank)
+ (group-n 1 (sequence (opt "-")
+ (eval cperl--basic-identifier-rx)))
+ (0+ blank) "}")
+;; '("\\([]}\\%@>*&]\\|\\$[a-zA-Z0-9_:]*\\)[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
+ (1 font-lock-string-face t)
+ ;; anchored bareword hash key: $foo{bar}{baz}
+ (,(rx point
+ (0+ blank) "{" (0+ blank)
+ (group-n 1 (sequence (opt "-")
+ (eval cperl--basic-identifier-rx)))
+ (0+ blank) "}")
+ ;; ("\\=[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
+ nil nil
+ (1 font-lock-string-face t)))
+ ;; hash element assignments with bareword key => value
+ `(,(rx (in "[ \t{,()")
+ (group-n 1 (sequence (opt "-")
+ (eval cperl--basic-identifier-rx)))
+ (0+ blank) "=>")
+ 1 font-lock-string-face t)
+;; '("[[ \t{,(]\\(-?[a-zA-Z0-9_:]+\\)[ \t]*=>" 1
+;; font-lock-string-face t)
+ ;; labels
+ `(,(rx
+ (sequence
+ (0+ space)
+ (group (eval cperl--label-rx))
+ (0+ space)
+ (or line-end "#" "{"
+ (sequence word-start
+ (or "until" "while" "for" "foreach" "do")
+ word-end))))
+ 1 font-lock-constant-face)
+ ;; labels as targets (no trailing colon!)
+ `(,(rx
+ (sequence
+ symbol-start
+ (or "continue" "next" "last" "redo" "break" "goto")
+ (1+ space)
+ (group (eval cperl--basic-identifier-rx))))
+ 1 font-lock-constant-face)
;; Uncomment to get perl-mode-like vars
;;; '("[$*]{?\\(\\sw+\\)" 1 font-lock-variable-name-face)
;;; '("\\([@%]\\|\\$#\\)\\(\\sw+\\)"
;;; (2 (cons font-lock-variable-name-face '(underline))))
- (cond (font-lock-anchored
;; 1=my_etc, 2=white? 3=(+white? 4=white? 5=var
- `(,(concat "\\<\\(state\\|my\\|local\\|our\\)"
- cperl-maybe-white-and-comment-rex
- "\\(("
- cperl-maybe-white-and-comment-rex
- "\\)?\\([$@%*]\\([a-zA-Z0-9_:]+\\|[^a-zA-Z0-9_]\\)\\)")
- (5 ,(if cperl-font-lock-multiline
- 'font-lock-variable-name-face
- '(progn (setq cperl-font-lock-multiline-start
- (match-beginning 0))
- 'font-lock-variable-name-face)))
- (,(concat "\\="
- cperl-maybe-white-and-comment-rex
- ","
- cperl-maybe-white-and-comment-rex
- "\\([$@%*]\\([a-zA-Z0-9_:]+\\|[^a-zA-Z0-9_]\\)\\)")
- ;; Bug in font-lock: limit is used not only to limit
- ;; searches, but to set the "extend window for
- ;; facification" property. Thus we need to minimize.
- ,(if cperl-font-lock-multiline
- '(if (match-beginning 3)
- (save-excursion
- (goto-char (match-beginning 3))
- (condition-case nil
- (forward-sexp 1)
- (error
- (condition-case nil
- (forward-char 200)
- (error nil)))) ; typeahead
- (1- (point))) ; report limit
- (forward-char -2)) ; disable continued expr
- '(if (match-beginning 3)
- (point-max) ; No limit for continuation
- (forward-char -2))) ; disable continued expr
- ,(if cperl-font-lock-multiline
- nil
- '(progn ; Do at end
- ;; "my" may be already fontified (POD),
- ;; so cperl-font-lock-multiline-start is nil
- (if (or (not cperl-font-lock-multiline-start)
- (> 2 (count-lines
- cperl-font-lock-multiline-start
- (point))))
- nil
- (put-text-property
- (1+ cperl-font-lock-multiline-start) (point)
- 'syntax-type 'multiline))
- (setq cperl-font-lock-multiline-start nil)))
- (3 font-lock-variable-name-face))))
- (t '("^[ \t{}]*\\(state\\|my\\|local\\|our\\)[ \t]*\\(([ \t]*\\)?\\([$@%*][a-zA-Z0-9_:]+\\)"
- 3 font-lock-variable-name-face)))
- '("\\<for\\(each\\)?\\([ \t]+\\(state\\|my\\|local\\|our\\)\\)?[ \t]*\\(\\$[a-zA-Z_][a-zA-Z_0-9]*\\)[ \t]*("
- 4 font-lock-variable-name-face)
+ `(,(rx (sequence (or "state" "my" "local" "our"))
+ (eval cperl--ws*-rx)
+ (opt (sequence "(" (eval cperl--ws*-rx)))
+ (group
+ (in "$@%*")
+ (or
+ (eval cperl--normal-identifier-rx)
+ (eval cperl--special-identifier-rx))
+ )
+ )
+ ;; (concat "\\<\\(state\\|my\\|local\\|our\\)"
+ ;; cperl-maybe-white-and-comment-rex
+ ;; "\\(("
+ ;; cperl-maybe-white-and-comment-rex
+ ;; "\\)?\\([$@%*]\\([a-zA-Z0-9_:]+\\|[^a-zA-Z0-9_]\\)\\)")
+ ;; (5 ,(if cperl-font-lock-multiline
+ (1 ,(if cperl-font-lock-multiline
+ 'font-lock-variable-name-face
+ '(progn (setq cperl-font-lock-multiline-start
+ (match-beginning 0))
+ 'font-lock-variable-name-face)))
+ (,(rx (sequence point
+ (eval cperl--ws*-rx)
+ ","
+ (eval cperl--ws*-rx)
+ (group
+ (in "$@%*")
+ (or
+ (eval cperl--normal-identifier-rx)
+ (eval cperl--special-identifier-rx))
+ )
+ )
+ )
+ ;; ,(concat "\\="
+ ;; cperl-maybe-white-and-comment-rex
+ ;; ","
+ ;; cperl-maybe-white-and-comment-rex
+ ;; "\\([$@%*]\\([a-zA-Z0-9_:]+\\|[^a-zA-Z0-9_]\\)\\)")
+ ;; Bug in font-lock: limit is used not only to limit
+ ;; searches, but to set the "extend window for
+ ;; facification" property. Thus we need to minimize.
+ ,(if cperl-font-lock-multiline
+ '(if (match-beginning 1)
+ (save-excursion
+ (goto-char (match-beginning 1))
+ (condition-case nil
+ (forward-sexp 1)
+ (error
+ (condition-case nil
+ (forward-char 200)
+ (error nil)))) ; typeahead
+ (1- (point))) ; report limit
+ (forward-char -2)) ; disable continued expr
+ '(if (match-beginning 1)
+ (point-max) ; No limit for continuation
+ (forward-char -2))) ; disable continued expr
+ ,(if cperl-font-lock-multiline
+ nil
+ '(progn ; Do at end
+ ;; "my" may be already fontified (POD),
+ ;; so cperl-font-lock-multiline-start is nil
+ (if (or (not cperl-font-lock-multiline-start)
+ (> 2 (count-lines
+ cperl-font-lock-multiline-start
+ (point))))
+ nil
+ (put-text-property
+ (1+ cperl-font-lock-multiline-start) (point)
+ 'syntax-type 'multiline))
+ (setq cperl-font-lock-multiline-start nil)))
+ (1 font-lock-variable-name-face)))
+ ;; foreach my $foo (
+ `(,(rx symbol-start "for" (opt "each")
+ (opt (sequence (1+ blank)
+ (or "state" "my" "local" "our")))
+ (0+ blank)
+ (group-n 1 (sequence "$"
+ (eval cperl--basic-identifier-rx)))
+ (0+ blank) "(")
+;; '("\\<for\\(each\\)?\\([ \t]+\\(state\\|my\\|local\\|our\\)\\)?[ \t]*\\(\\$[a-zA-Z_][a-zA-Z_0-9]*\\)[ \t]*("
+ 1 font-lock-variable-name-face)
;; Avoid $!, and s!!, qq!! etc. when not fontifying syntactically
'("\\(?:^\\|[^smywqrx$]\\)\\(!\\)" 1 font-lock-negation-char-face)
'("\\[\\(\\^\\)" 1 font-lock-negation-char-face prepend)))
(setq
t-font-lock-keywords-1
- '(
- ("\\(\\([@%]\\|\\$#\\)[a-zA-Z_:][a-zA-Z0-9_:]*\\)" 1
+ `(
+ ;; arrays and hashes. Access to elements is fixed below
+ (,(rx (group-n 1 (group-n 2 (or (in "@%") "$#"))
+ (eval cperl--normal-identifier-rx)))
+ 1
+;; ("\\(\\([@%]\\|\\$#\\)[a-zA-Z_:][a-zA-Z0-9_:]*\\)" 1
(if (eq (char-after (match-beginning 2)) ?%)
'cperl-hash-face
'cperl-array-face)
nil) ; arrays and hashes
- ("\\(\\([$@%]+\\)[a-zA-Z_:][a-zA-Z0-9_:]*\\)[ \t]*\\([[{]\\)"
+ ;; access to array/hash elements
+ (,(rx (group-n 1 (group-n 2 (in "$@%"))
+ (eval cperl--normal-identifier-rx))
+ (0+ blank)
+ (group-n 3 (in "[{")))
+;; ("\\(\\([$@%]+\\)[a-zA-Z_:][a-zA-Z0-9_:]*\\)[ \t]*\\([[{]\\)"
1
(if (= (- (match-end 2) (match-beginning 2)) 1)
(if (eq (char-after (match-beginning 3)) ?{)
'cperl-hash-face
'cperl-array-face) ; arrays and hashes
font-lock-variable-name-face) ; Just to put something
- t)
- ("\\(@\\|\\$#\\)\\(\\$+\\([a-zA-Z_:][a-zA-Z0-9_:]*\\|[^ \t\n]\\)\\)"
+ t) ; override previous
+ ;; @$ array dereferences, $#$ last array index
+ (,(rx (group-n 1 (or "@" "$#"))
+ (group-n 2 (sequence "$"
+ (or (eval cperl--normal-identifier-rx)
+ (not (in " \t\n"))))))
+ ;; ("\\(@\\|\\$#\\)\\(\\$+\\([a-zA-Z_:][a-zA-Z0-9_:]*\\|[^ \t\n]\\)\\)"
(1 'cperl-array-face)
(2 font-lock-variable-name-face))
- ("\\(%\\)\\(\\$+\\([a-zA-Z_:][a-zA-Z0-9_:]*\\|[^ \t\n]\\)\\)"
+ ;; %$ hash dereferences
+ (,(rx (group-n 1 "%")
+ (group-n 2 (sequence "$"
+ (or (eval cperl--normal-identifier-rx)
+ (not (in " \t\n"))))))
+ ;; ("\\(%\\)\\(\\$+\\([a-zA-Z_:][a-zA-Z0-9_:]*\\|[^ \t\n]\\)\\)"
(1 'cperl-hash-face)
(2 font-lock-variable-name-face))
;;("\\([smy]\\|tr\\)\\([^a-z_A-Z0-9]\\)\\(\\([^\n\\]*||\\)\\)\\2")
@@ -6048,7 +6362,7 @@ side-effect of memorizing only. Examples in `cperl-style-examples'."
(filename nodename &optional no-going-back strict-case))
(defun cperl-info-buffer (type)
- ;; Returns buffer with documentation. Creates if missing.
+ ;; Return buffer with documentation. Creates if missing.
;; If TYPE, this vars buffer.
;; Special care is taken to not stomp over an existing info buffer
(let* ((bname (if type "*info-perl-var*" "*info-perl*"))
@@ -6182,7 +6496,7 @@ Customized by setting variables `cperl-shrink-wrap-info-frame',
(declare-function imenu-choose-buffer-index "imenu" (&optional prompt alist))
(defun cperl-imenu-on-info ()
- "Shows imenu for Perl Info Buffer.
+ "Show imenu for Perl Info Buffer.
Opens Perl Info buffer if needed."
(interactive)
(require 'imenu)
@@ -6235,6 +6549,8 @@ Will not move the position at the start to the left."
(indent-region beg end nil)
(goto-char beg)
(setq col (current-column))
+ ;; Assuming that lineup is done on Perl syntax, this regexp
+ ;; doesn't need to be unicode aware -- haj, 2021-09-10
(if (looking-at "[a-zA-Z0-9_]")
(if (looking-at "\\<[a-zA-Z0-9_]+\\>")
(setq search
@@ -6272,6 +6588,9 @@ Will not move the position at the start to the left."
"Run etags with appropriate options for Perl files.
If optional argument ALL is `recursive', will process Perl files
in subdirectories too."
+ ;; Apparently etags doesn't support UTF-8 encoded sources, and usage
+ ;; of etags has been commented out in the menu since ... well,
+ ;; forever. So, let's just stick to ASCII here. -- haj, 2021-09-14
(interactive)
(let ((cmd "etags")
(args `("-l" "none" "-r"
@@ -6411,6 +6730,9 @@ Does not move point."
;; Search for the function
(progn ;;save-match-data
(while (re-search-forward
+ ;; FIXME: Should XS code be unicode aware? Recent C
+ ;; compilers (Gcc 10+) are, but I guess this isn't used
+ ;; much. -- haj, 2021-09-14
"^\\([ \t]*MODULE\\>[^\n]*\\<PACKAGE[ \t]*=[ \t]*\\([a-zA-Z_][a-zA-Z_0-9:]*\\)\\>\\|\\([a-zA-Z_][a-zA-Z_0-9]*\\)(\\|[ \t]*BOOT:\\)"
nil t)
(cond
@@ -6473,7 +6795,7 @@ Does not move point."
(setq lst
(mapcar
(lambda (elt)
- (cond ((string-match "^[_a-zA-Z]" (car elt))
+ (cond ((string-match (rx line-start (or alpha "_")) (car elt))
(goto-char (cdr elt))
(beginning-of-line) ; pos should be of the start of the line
(list (car elt)
@@ -6503,9 +6825,14 @@ Does not move point."
","
(number-to-string (1- (elt elt 1))) ; Char pos 0-based
"\n")
- (if (and (string-match "^[_a-zA-Z]+::" (car elt))
- (string-match (concat "^" cperl-sub-regexp "[ \t]+\\([_a-zA-Z]+\\)[^:_a-zA-Z]")
- (elt elt 3)))
+ (if (and (string-match (rx line-start
+ (eval cperl--basic-identifier-rx) "++")
+ (car elt))
+ (string-match (rx-to-string `(sequence line-start
+ (regexp ,cperl-sub-regexp)
+ (1+ (in " \t"))
+ ,cperl--normal-identifier-rx))
+ (elt elt 3)))
;; Need to insert the name without package as well
(setq lst (cons (cons (substring (elt elt 3)
(match-beginning 1)
@@ -6530,8 +6857,7 @@ Does not move point."
"Add to TAGS data for \"pure\" Perl files in the current directory and kids.
Use as
emacs -batch -q -no-site-file -l emacs/cperl-mode.el \\
- -f cperl-add-tags-recurse-noxs
-"
+ -f cperl-add-tags-recurse-noxs"
(cperl-write-tags nil nil t t nil t))
(defun cperl-add-tags-recurse-noxs-fullpath ()
@@ -6539,16 +6865,14 @@ Use as
Writes down fullpath, so TAGS is relocatable (but if the build directory
is relocated, the file TAGS inside it breaks). Use as
emacs -batch -q -no-site-file -l emacs/cperl-mode.el \\
- -f cperl-add-tags-recurse-noxs-fullpath
-"
+ -f cperl-add-tags-recurse-noxs-fullpath"
(cperl-write-tags nil nil t t nil t ""))
(defun cperl-add-tags-recurse ()
"Add to TAGS file data for Perl files in the current directory and kids.
Use as
emacs -batch -q -no-site-file -l emacs/cperl-mode.el \\
- -f cperl-add-tags-recurse
-"
+ -f cperl-add-tags-recurse"
(cperl-write-tags nil nil t t))
(defvar cperl-tags-file-name "TAGS"
@@ -6958,14 +7282,14 @@ Currently it is tuned to C and Perl syntax."
;;(concat "\\("
(mapconcat
#'identity
- '("[$@%*&][0-9a-zA-Z_:]+\\([ \t]*[[{]\\)?" ; Usual variable
+ '("[$@%*&][[:alnum:]_:]+\\([ \t]*[[{]\\)?" ; Usual variable
"[$@]\\^[a-zA-Z]" ; Special variable
"[$@][^ \n\t]" ; Special variable
"-[a-zA-Z]" ; File test
"\\\\[a-zA-Z0]" ; Special chars
"^=[a-z][a-zA-Z0-9_]*" ; POD sections
"[-!&*+,./<=>?\\^|~]+" ; Operator
- "[a-zA-Z_0-9:]+" ; symbol or number
+ "[[:alnum:]_:]+" ; symbol or number
"x="
"#!")
;;"\\)\\|\\("
@@ -6981,7 +7305,7 @@ Currently it is tuned to C and Perl syntax."
;; Does not save-excursion
;; Get to the something meaningful
(or (eobp) (eolp) (forward-char 1))
- (re-search-backward "[-a-zA-Z0-9_:!&*+,./<=>?\\^|~$%@]"
+ (re-search-backward "[-[:alnum:]_:!&*+,./<=>?\\^|~$%@]"
(point-at-bol)
'to-beg)
;; (cond
@@ -6990,8 +7314,8 @@ Currently it is tuned to C and Perl syntax."
;; (or (bobp) (backward-char 1))))
;; Try to backtrace
(cond
- ((looking-at "[a-zA-Z0-9_:]") ; symbol
- (skip-chars-backward "a-zA-Z0-9_:")
+ ((looking-at "[[:alnum:]_:]") ; symbol
+ (skip-chars-backward "[:alnum:]_:")
(cond
((and (eq (preceding-char) ?^) ; $^I
(eq (char-after (- (point) 2)) ?\$))
@@ -7002,7 +7326,7 @@ Currently it is tuned to C and Perl syntax."
(eq (current-column) 1))
(forward-char -1))) ; =head1
(if (and (eq (preceding-char) ?\<)
- (looking-at "\\$?[a-zA-Z0-9_:]+>")) ; <FH>
+ (looking-at "\\$?[[:alnum:]_:]+>")) ; <FH>
(forward-char -1)))
((and (looking-at "=") (eq (preceding-char) ?x)) ; x=
(forward-char -1))
@@ -7015,15 +7339,15 @@ Currently it is tuned to C and Perl syntax."
(not (eq (char-after (- (point) 2)) ?\$))) ; $-
(forward-char -1))
((and (eq (following-char) ?\>)
- (string-match "[a-zA-Z0-9_]" (char-to-string (preceding-char)))
+ (string-match "[[:alnum:]_]" (char-to-string (preceding-char)))
(save-excursion
(forward-sexp -1)
(and (eq (preceding-char) ?\<)
- (looking-at "\\$?[a-zA-Z0-9_:]+>")))) ; <FH>
+ (looking-at "\\$?[[:alnum:]_:]+>")))) ; <FH>
(search-backward "<"))))
((and (eq (following-char) ?\$)
(eq (preceding-char) ?\<)
- (looking-at "\\$?[a-zA-Z0-9_:]+>")) ; <$fh>
+ (looking-at "\\$?[[:alnum:]_:]+>")) ; <$fh>
(forward-char -1)))
(if (looking-at cperl-have-help-regexp)
(buffer-substring (match-beginning 0) (match-end 0))))
@@ -7532,11 +7856,10 @@ prototype \\&SUB Returns prototype of the function given a reference.
=begin formatname Start directly formatted region.
=end formatname End directly formatted region.
=for formatname text Paragraph in special format.
-=encoding encodingname Encoding of the document.
-")
+=encoding encodingname Encoding of the document.")
(defun cperl-switch-to-doc-buffer (&optional interactive)
- "Go to the perl documentation buffer and insert the documentation."
+ "Go to the Perl documentation buffer and insert the documentation."
(interactive "p")
(let ((buf (get-buffer-create cperl-doc-buffer)))
(if interactive
@@ -8195,7 +8518,7 @@ If a region is highlighted, restricts to the region."
beg end))))
(defun cperl-map-pods-heres (func &optional prop s end)
- "Executes a function over regions of pods or here-documents.
+ "Execute a function over regions of pods or here-documents.
PROP is the text-property to search for; default to `in-pod'. Stop when
function returns nil."
(let (pos posend has-prop (cont t))
@@ -8370,7 +8693,7 @@ Delay of auto-help controlled by `cperl-lazy-help-time'."
(remove-text-properties beg end '(face nil))))
(defun cperl-font-lock-fontify-region-function (beg end loudly)
- "Extends the region to safe positions, then calls the default function.
+ "Extend the region to safe positions, then call the default function.
Newer `font-lock's can do it themselves.
We unwind only as far as needed for fontification. Syntaxification may
do extra unwind via `cperl-unwind-to-safe'."
diff --git a/lisp/progmodes/cpp.el b/lisp/progmodes/cpp.el
index 6602a79b2a4..baee72b332d 100644
--- a/lisp/progmodes/cpp.el
+++ b/lisp/progmodes/cpp.el
@@ -702,17 +702,14 @@ BRANCH should be either nil (false branch), t (true branch) or `both'."
(x-popup-menu cpp-button-event
(list prompt (cons prompt cpp-face-default-list)))
(let ((name (car (rassq default cpp-face-default-list))))
- (cdr (assoc (completing-read (if name
- (concat prompt
- " (default " name "): ")
- (concat prompt ": "))
- cpp-face-default-list nil t)
+ (cdr (assoc (completing-read (format-prompt "%s" name prompt)
+ cpp-face-default-list nil t)
cpp-face-all-list))))
default))
(defun cpp-choose-default-face (type)
- ;; Choose default face list for screen of TYPE.
- ;; Type must be one of the types defined in `cpp-face-type-list'.
+ "Choose default face list for screen of TYPE.
+Type must be one of the types defined in `cpp-face-type-list'."
(interactive (list (if cpp-button-event
(x-popup-menu cpp-button-event
(list "Screen type"
@@ -789,7 +786,7 @@ BRANCH should be either nil (false branch), t (true branch) or `both'."
(if data (list 'cpp-data data))))))
(defun cpp-push-button (event)
- ;; Pushed a CPP button.
+ "Pushed a CPP button."
(interactive "@e")
(set-buffer (window-buffer (posn-window (event-start event))))
(let ((pos (posn-point (event-start event))))
diff --git a/lisp/progmodes/dcl-mode.el b/lisp/progmodes/dcl-mode.el
index ed024f24344..b74b558f8df 100644
--- a/lisp/progmodes/dcl-mode.el
+++ b/lisp/progmodes/dcl-mode.el
@@ -494,7 +494,7 @@ Variables controlling indentation style and extra features:
These variables control the look of expanded templates.
dcl-imenu-generic-expression
- Default value for imenu-generic-expression. The default includes
+ Default value for `imenu-generic-expression'. The default includes
SUBROUTINE labels in the main listing and sub-listings for
other labels, CALL, GOTO and GOSUB statements.
@@ -1463,7 +1463,7 @@ Inserts continuation marks and splits character strings."
;;;-------------------------------------------------------------------------
(defun dcl-delete-indentation (&optional arg)
- "Join this line to previous like delete-indentation.
+ "Join this line to previous like `delete-indentation'.
Also remove the continuation mark if easily detected."
(interactive "*P")
(delete-indentation arg)
diff --git a/lisp/progmodes/ebnf-abn.el b/lisp/progmodes/ebnf-abn.el
index 2a37110f6ae..c3b240ad8be 100644
--- a/lisp/progmodes/ebnf-abn.el
+++ b/lisp/progmodes/ebnf-abn.el
@@ -530,13 +530,14 @@ See documentation for variable `ebnf-abn-lex'."
(let ((prose-p (= (following-char) ?<)))
(when prose-p
(forward-char)
- (or (looking-at ebnf-abn-non-terminal-letter-chars)
+ (or (looking-at (concat "[" ebnf-abn-non-terminal-letter-chars "]"))
(error "Invalid prose value")))
(setq ebnf-abn-lex
(ebnf-buffer-substring ebnf-abn-non-terminal-chars))
(when prose-p
(or (= (following-char) ?>)
(error "Invalid prose value"))
+ (forward-char)
(setq ebnf-abn-lex (concat "<" ebnf-abn-lex ">"))))
'non-terminal)
;; equal: =, =/
diff --git a/lisp/progmodes/ebnf-dtd.el b/lisp/progmodes/ebnf-dtd.el
index 93bae5a33c5..d4bfdaa9957 100644
--- a/lisp/progmodes/ebnf-dtd.el
+++ b/lisp/progmodes/ebnf-dtd.el
@@ -56,14 +56,14 @@
;;
;; Char ::= #x9 | #xA | #xD
;; | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
-;; /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */
+;; /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */
;;
;; /* NOTE:
;;
;; Document authors are encouraged to avoid "compatibility characters", as
;; defined in section 6.8 of [Unicode] (see also D21 in section 3.6 of
-;; [Unicode3]). The characters defined in the following ranges are also
-;; discouraged. They are either control characters or permanently undefined
+;; [Unicode3]). The characters defined in the following ranges are also
+;; discouraged. They are either control characters or permanently undefined
;; Unicode characters:
;;
;; [#x7F-#x84], [#x86-#x9F], [#xFDD0-#xFDDF],
@@ -72,7 +72,7 @@
;; [#7FFFE-#x7FFFF], [#8FFFE-#x8FFFF], [#9FFFE-#x9FFFF],
;; [#AFFFE-#xAFFFF], [#BFFFE-#xBFFFF], [#CFFFE-#xCFFFF],
;; [#DFFFE-#xDFFFF], [#EFFFE-#xEFFFF], [#FFFFE-#xFFFFF],
-;; [#10FFFE-#x10FFFF]. */
+;; [#10FFFE-#x10FFFF]. */
;;
;;
;; /* White Space */
@@ -115,7 +115,7 @@
;; Although the EntityValue production allows the definition of a general
;; entity consisting of a single explicit < in the literal (e.g., <!ENTITY
;; mylt "<">), it is strongly advised to avoid this practice since any
-;; reference to that entity will cause a well-formedness error. */
+;; reference to that entity will cause a well-formedness error. */
;;
;;
;; /* Character Data */
diff --git a/lisp/progmodes/ebnf-ebx.el b/lisp/progmodes/ebnf-ebx.el
index 5d8541931e1..ae48881ee9e 100644
--- a/lisp/progmodes/ebnf-ebx.el
+++ b/lisp/progmodes/ebnf-ebx.el
@@ -43,7 +43,7 @@
;;
;;
;; rule ::= symbol '::=' expression
-;; /* rules are separated by at least one blank line. */
+;; /* rules are separated by at least one blank line. */
;;
;; expression ::= concatenation ('|' concatenation)*
;;
diff --git a/lisp/progmodes/ebnf-yac.el b/lisp/progmodes/ebnf-yac.el
index 816cc432d1b..84950e45f51 100644
--- a/lisp/progmodes/ebnf-yac.el
+++ b/lisp/progmodes/ebnf-yac.el
@@ -113,7 +113,7 @@
;;; YACC-Code = "any C definition".
(defun ebnf-yac-parser (start)
- "yacc/Bison parser."
+ "Yacc/Bison parser."
(let ((total (+ (- ebnf-limit start) 1))
(bias (1- start))
(origin (point))
diff --git a/lisp/progmodes/ebnf2ps.el b/lisp/progmodes/ebnf2ps.el
index 884104a16f7..21ab48b1104 100644
--- a/lisp/progmodes/ebnf2ps.el
+++ b/lisp/progmodes/ebnf2ps.el
@@ -5,7 +5,7 @@
;; Author: Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>
;; Keywords: wp, ebnf, PostScript
;; Version: 4.4
-;; X-URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
+;; URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
;; This file is part of GNU Emacs.
@@ -1165,7 +1165,7 @@ Please send all bug fixes and enhancements to
;;; Interface to the command system
(defgroup postscript nil
- "Printing with PostScript"
+ "Printing with PostScript."
:tag "PostScript"
:version "20"
:group 'environment)
@@ -2244,8 +2244,12 @@ the PostScript image in a file with that name. If FILENAME is a
number, prompt the user for the name of the file to save in."
(interactive (list (ps-print-preprint current-prefix-arg)))
(ebnf-log-header "(ebnf-print-buffer %S)" filename)
- (ebnf-print-region (point-min) (point-max) filename))
-
+ (cl-letf (((symbol-function 'ps-output-string)
+ ;; Make non-ASCII work (sort of).
+ (lambda (string)
+ (ps-output t (and string
+ (encode-coding-string string 'iso-8859-1))))))
+ (ebnf-print-region (point-min) (point-max) filename)))
;;;###autoload
(defun ebnf-print-region (from to &optional filename)
diff --git a/lisp/progmodes/ebrowse.el b/lisp/progmodes/ebrowse.el
index 7524c280f25..0713370da3c 100644
--- a/lisp/progmodes/ebrowse.el
+++ b/lisp/progmodes/ebrowse.el
@@ -1330,9 +1330,9 @@ Pop to member buffer if no prefix ARG, to tree buffer otherwise."
"Set the indentation width of the tree display."
(interactive)
(let ((width (string-to-number (read-string
- (concat "Indentation (default "
- (int-to-string ebrowse--indentation)
- "): ")
+ (format-prompt
+ "Indentation"
+ (int-to-string ebrowse--indentation))
nil nil ebrowse--indentation))))
(when (cl-plusp width)
(setq-local ebrowse--indentation width)
@@ -3062,7 +3062,7 @@ the first derived class."
(easy-menu-define
ebrowse-member-name-object-menu ebrowse-member-mode-map
- "Object menu for member names"
+ "Object menu for member names."
'("Ebrowse"
["Find Definition" ebrowse-find-member-definition
:help "Find this member's definition in the source files"
@@ -4045,23 +4045,27 @@ NUMBER-OF-STATIC-VARIABLES:"
(defvar ebrowse-global-map nil
"Keymap for Ebrowse commands.")
-
(defvar ebrowse-global-prefix-key "\C-c\C-m"
"Prefix key for Ebrowse commands.")
-
-(defvar ebrowse-global-submap-4 nil
- "Keymap used for `ebrowse-global-prefix' followed by `4'.")
-
-
-(defvar ebrowse-global-submap-5 nil
- "Keymap used for `ebrowse-global-prefix' followed by `5'.")
-
+(defvar-keymap ebrowse-global-submap-4
+ :doc "Keymap used for `ebrowse-global-prefix' followed by `4'."
+ "." #'ebrowse-tags-find-definition-other-window
+ "f" #'ebrowse-tags-find-definition-other-window
+ "v" #'ebrowse-tags-find-declaration-other-window
+ "F" #'ebrowse-tags-view-definition-other-window
+ "V" #'ebrowse-tags-view-declaration-other-window)
+
+(defvar-keymap ebrowse-global-submap-5
+ :doc "Keymap used for `ebrowse-global-prefix' followed by `5'."
+ "." #'ebrowse-tags-find-definition-other-frame
+ "f" #'ebrowse-tags-find-definition-other-frame
+ "v" #'ebrowse-tags-find-declaration-other-frame
+ "F" #'ebrowse-tags-view-definition-other-frame
+ "V" #'ebrowse-tags-view-declaration-other-frame)
(unless ebrowse-global-map
(setq ebrowse-global-map (make-sparse-keymap))
- (setq ebrowse-global-submap-4 (make-sparse-keymap))
- (setq ebrowse-global-submap-5 (make-sparse-keymap))
(define-key ebrowse-global-map "a" 'ebrowse-tags-apropos)
(define-key ebrowse-global-map "b" 'ebrowse-pop-to-browser-buffer)
(define-key ebrowse-global-map "-" 'ebrowse-back-in-position-stack)
@@ -4082,17 +4086,7 @@ NUMBER-OF-STATIC-VARIABLES:"
(define-key ebrowse-global-map " " 'ebrowse-electric-buffer-list)
(define-key ebrowse-global-map "\t" 'ebrowse-tags-complete-symbol)
(define-key ebrowse-global-map "4" ebrowse-global-submap-4)
- (define-key ebrowse-global-submap-4 "." 'ebrowse-tags-find-definition-other-window)
- (define-key ebrowse-global-submap-4 "f" 'ebrowse-tags-find-definition-other-window)
- (define-key ebrowse-global-submap-4 "v" 'ebrowse-tags-find-declaration-other-window)
- (define-key ebrowse-global-submap-4 "F" 'ebrowse-tags-view-definition-other-window)
- (define-key ebrowse-global-submap-4 "V" 'ebrowse-tags-view-declaration-other-window)
(define-key ebrowse-global-map "5" ebrowse-global-submap-5)
- (define-key ebrowse-global-submap-5 "." 'ebrowse-tags-find-definition-other-frame)
- (define-key ebrowse-global-submap-5 "f" 'ebrowse-tags-find-definition-other-frame)
- (define-key ebrowse-global-submap-5 "v" 'ebrowse-tags-find-declaration-other-frame)
- (define-key ebrowse-global-submap-5 "F" 'ebrowse-tags-view-definition-other-frame)
- (define-key ebrowse-global-submap-5 "V" 'ebrowse-tags-view-declaration-other-frame)
(define-key global-map ebrowse-global-prefix-key ebrowse-global-map))
@@ -4200,7 +4194,7 @@ EVENT is the mouse event."
(easy-menu-define
ebrowse-tree-buffer-class-object-menu ebrowse-tree-mode-map
- "Object menu for classes in the tree buffer"
+ "Object menu for classes in the tree buffer."
'("Class"
["Functions" ebrowse-tree-command:show-member-functions
:help "Display a list of member functions"
@@ -4242,7 +4236,7 @@ EVENT is the mouse event."
(easy-menu-define
ebrowse-tree-buffer-object-menu ebrowse-tree-mode-map
- "Object menu for tree buffers"
+ "Object menu for tree buffers."
'("Ebrowse"
["Filename Display" ebrowse-toggle-file-name-display
:help "Toggle display of source files names"
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index 542f8ad0b1b..efb5df8ebfb 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -45,15 +45,13 @@ It has `lisp-mode-abbrev-table' as its parent."
table)
"Syntax table used in `emacs-lisp-mode'.")
-(defvar emacs-lisp-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map lisp-mode-shared-map)
- (define-key map "\e\t" 'completion-at-point)
- (define-key map "\e\C-x" 'eval-defun)
- (define-key map "\e\C-q" 'indent-pp-sexp)
- map)
- "Keymap for Emacs Lisp mode.
-All commands in `lisp-mode-shared-map' are inherited by this map.")
+(defvar-keymap emacs-lisp-mode-map
+ :doc "Keymap for Emacs Lisp mode.
+All commands in `lisp-mode-shared-map' are inherited by this map."
+ :parent lisp-mode-shared-map
+ "M-TAB" #'completion-at-point
+ "C-M-x" #'eval-defun
+ "C-M-q" #'indent-pp-sexp)
(easy-menu-define emacs-lisp-mode-menu emacs-lisp-mode-map
"Menu for Emacs Lisp mode."
@@ -153,6 +151,41 @@ All commands in `lisp-mode-shared-map' are inherited by this map.")
:style toggle
:selected (bound-and-true-p eldoc-mode)]))
+(defun elisp-context-menu (menu click)
+ "Populate MENU with symbol help commands at CLICK."
+ (when (thing-at-mouse click 'symbol)
+ (define-key-after menu [elisp-separator] menu-bar-separator
+ 'middle-separator)
+
+ (let* ((string (thing-at-mouse click 'symbol t))
+ (symbol (when (stringp string) (intern string)))
+ (title (cond
+ ((not (symbolp symbol)) nil)
+ ((and (facep symbol) (not (fboundp symbol)))
+ "Face")
+ ((and (fboundp symbol)
+ (not (or (boundp symbol) (facep symbol))))
+ "Function")
+ ((and (boundp symbol)
+ (not (or (fboundp symbol) (facep symbol))))
+ "Variable")
+ ((or (fboundp symbol) (boundp symbol) (facep symbol))
+ "Symbol"))))
+ (when title
+ (define-key-after menu [info-lookup-symbol]
+ `(menu-item "Look up in Manual"
+ (lambda (_click) (interactive "e")
+ (info-lookup-symbol ',symbol))
+ :help ,(format "Find `%s' in relevant manual" symbol))
+ 'elisp-separator)
+ (define-key-after menu [describe-symbol]
+ `(menu-item (format "Describe %s" ,title)
+ (lambda (_click) (interactive "e")
+ (describe-symbol ',symbol))
+ :help ,(format "Display the documentation of `%s'" symbol))
+ 'elisp-separator))))
+ menu)
+
(defun emacs-lisp-byte-compile ()
"Byte compile the file containing the current buffer."
(interactive nil emacs-lisp-mode)
@@ -175,7 +208,7 @@ All commands in `lisp-mode-shared-map' are inherited by this map.")
(emacs-lisp--before-compile-buffer)
(require 'bytecomp)
(byte-recompile-file buffer-file-name nil 0)
- (load buffer-file-name))
+ (load (byte-compile-dest-file buffer-file-name)))
(declare-function native-compile "comp")
(defun emacs-lisp-native-compile-and-load ()
@@ -183,7 +216,7 @@ 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-comp-deferred-compilation' set to t to achieve asynchronous
native compilation."
(interactive nil emacs-lisp-mode)
(emacs-lisp--before-compile-buffer)
@@ -235,10 +268,8 @@ Comments in the form will be lost."
(setq-local lexical-binding t)
(add-file-local-variable-prop-line 'lexical-binding t interactive))))
-(defvar elisp--dynlex-modeline-map
- (let ((map (make-sparse-keymap)))
- (define-key map [mode-line mouse-1] 'elisp-enable-lexical-binding)
- map))
+(defvar-keymap elisp--dynlex-modeline-map
+ "<mode-line> <mouse-1>" #'elisp-enable-lexical-binding)
;;;###autoload
(define-derived-mode emacs-lisp-mode lisp-data-mode
@@ -256,6 +287,9 @@ Commands:
Delete converts tabs to spaces as it moves back.
Blank lines separate paragraphs. Semicolons start comments.
+When editing Lisp data (as opposed to code), `lisp-data-mode' can
+be used instead.
+
\\{emacs-lisp-mode-map}"
:group 'lisp
(defvar project-vc-external-roots-function)
@@ -280,7 +314,8 @@ Blank lines separate paragraphs. Semicolons start comments.
#'elisp-completion-at-point nil 'local)
(add-hook 'flymake-diagnostic-functions #'elisp-flymake-checkdoc nil t)
(add-hook 'flymake-diagnostic-functions
- #'elisp-flymake-byte-compile nil t))
+ #'elisp-flymake-byte-compile nil t)
+ (add-hook 'context-menu-functions #'elisp-context-menu 10 t))
;; Font-locking support.
@@ -493,6 +528,53 @@ It can be quoted, or be inside a quoted form."
0))
((facep sym) (find-definition-noselect sym 'defface)))))
+(defvar obarray-cache nil
+ "If non-nil, a hash table of cached obarray-related information.
+The cache holds information specific to the current state of the
+Elisp obarray. If the obarray is modified by any means (such as
+interning or uninterning a symbol), this variable is set to nil.")
+
+(defun elisp--completion-local-symbols ()
+ "Compute collections of all Elisp symbols for completion purposes.
+The return value is compatible with the COLLECTION form described
+in `completion-at-point-functions' (which see)."
+ (cl-flet ((obarray-plus-shorthands ()
+ (let (retval)
+ (mapatoms
+ (lambda (s)
+ (push s retval)
+ (cl-loop
+ for (shorthand . longhand) in read-symbol-shorthands
+ for full-name = (symbol-name s)
+ when (string-prefix-p longhand full-name)
+ do (let ((sym (make-symbol
+ (concat shorthand
+ (substring full-name
+ (length longhand))))))
+ (put sym 'shorthand t)
+ (push sym retval)
+ retval))))
+ retval)))
+ (cond ((null read-symbol-shorthands) obarray)
+ ((and obarray-cache
+ (gethash (cons (current-buffer) read-symbol-shorthands)
+ obarray-cache)))
+ (obarray-cache
+ (puthash (cons (current-buffer) read-symbol-shorthands)
+ (obarray-plus-shorthands)
+ obarray-cache))
+ (t
+ (setq obarray-cache (make-hash-table :test #'equal))
+ (puthash (cons (current-buffer) read-symbol-shorthands)
+ (obarray-plus-shorthands)
+ obarray-cache)))))
+
+(defun elisp--shorthand-aware-fboundp (sym)
+ (fboundp (intern-soft (symbol-name sym))))
+
+(defun elisp--shorthand-aware-boundp (sym)
+ (boundp (intern-soft (symbol-name sym))))
+
(defun elisp-completion-at-point ()
"Function used for `completion-at-point-functions' in `emacs-lisp-mode'.
If the context at point allows only a certain category of
@@ -540,36 +622,41 @@ functions are annotated with \"<f>\" via the
;; the current form and use it to provide a more
;; specific completion table in more cases.
((eq fun-sym 'ignore-error)
- (list t obarray
+ (list t (elisp--completion-local-symbols)
:predicate (lambda (sym)
(get sym 'error-conditions))))
((elisp--expect-function-p beg)
- (list nil obarray
- :predicate #'fboundp
+ (list nil (elisp--completion-local-symbols)
+ :predicate
+ #'elisp--shorthand-aware-fboundp
:company-kind #'elisp--company-kind
:company-doc-buffer #'elisp--company-doc-buffer
:company-docsig #'elisp--company-doc-string
- :company-location #'elisp--company-location))
+ :company-location #'elisp--company-location
+ :company-deprecated #'elisp--company-deprecated))
(quoted
- (list nil obarray
+ (list nil (elisp--completion-local-symbols)
;; Don't include all symbols (bug#16646).
:predicate (lambda (sym)
- (or (boundp sym)
- (fboundp sym)
- (featurep sym)
- (symbol-plist sym)))
+ ;; shorthand-aware
+ (let ((sym (intern-soft (symbol-name sym))))
+ (or (boundp sym)
+ (fboundp sym)
+ (featurep sym)
+ (symbol-plist sym))))
:annotation-function
(lambda (str) (if (fboundp (intern-soft str)) " <f>"))
:company-kind #'elisp--company-kind
:company-doc-buffer #'elisp--company-doc-buffer
:company-docsig #'elisp--company-doc-string
- :company-location #'elisp--company-location))
+ :company-location #'elisp--company-location
+ :company-deprecated #'elisp--company-deprecated))
(t
(list nil (completion-table-merge
elisp--local-variables-completion-table
(apply-partially #'completion-table-with-predicate
- obarray
- #'boundp
+ (elisp--completion-local-symbols)
+ #'elisp--shorthand-aware-boundp
'strict))
:company-kind
(lambda (s)
@@ -578,7 +665,8 @@ functions are annotated with \"<f>\" via the
'variable))
:company-doc-buffer #'elisp--company-doc-buffer
:company-docsig #'elisp--company-doc-string
- :company-location #'elisp--company-location)))
+ :company-location #'elisp--company-location
+ :company-deprecated #'elisp--company-deprecated)))
;; Looks like a funcall position. Let's double check.
(save-excursion
(goto-char (1- beg))
@@ -606,11 +694,11 @@ functions are annotated with \"<f>\" via the
(ignore-errors
(forward-sexp 2)
(< (point) beg)))))
- (list t obarray
+ (list t (elisp--completion-local-symbols)
:predicate (lambda (sym) (get sym 'error-conditions))))
;; `ignore-error' with a list CONDITION parameter.
('ignore-error
- (list t obarray
+ (list t (elisp--completion-local-symbols)
:predicate (lambda (sym)
(get sym 'error-conditions))))
((and (or ?\( 'let 'let*)
@@ -620,18 +708,20 @@ functions are annotated with \"<f>\" via the
(up-list -1))
(forward-symbol -1)
(looking-at "\\_<let\\*?\\_>"))))
- (list t obarray
- :predicate #'boundp
+ (list t (elisp--completion-local-symbols)
+ :predicate #'elisp--shorthand-aware-boundp
:company-kind (lambda (_) 'variable)
:company-doc-buffer #'elisp--company-doc-buffer
:company-docsig #'elisp--company-doc-string
- :company-location #'elisp--company-location))
- (_ (list nil obarray
- :predicate #'fboundp
+ :company-location #'elisp--company-location
+ :company-deprecated #'elisp--company-deprecated))
+ (_ (list nil (elisp--completion-local-symbols)
+ :predicate #'elisp--shorthand-aware-fboundp
:company-kind #'elisp--company-kind
:company-doc-buffer #'elisp--company-doc-buffer
:company-docsig #'elisp--company-doc-string
:company-location #'elisp--company-location
+ :company-deprecated #'elisp--company-deprecated
))))))))
(nconc (list beg end)
(if (null (car table-etc))
@@ -654,6 +744,11 @@ functions are annotated with \"<f>\" via the
((facep sym) 'color)
(t 'text))))
+(defun elisp--company-deprecated (str)
+ (let ((sym (intern-soft str)))
+ (or (get sym 'byte-obsolete-variable)
+ (get sym 'byte-obsolete-info))))
+
(defun lisp-completion-at-point (&optional _predicate)
(declare (obsolete elisp-completion-at-point "25.1"))
(elisp-completion-at-point))
@@ -661,6 +756,7 @@ functions are annotated with \"<f>\" via the
;;; Xref backend
(declare-function xref-make "xref" (summary location))
+(declare-function xref-item-location "xref" (this))
(defun elisp--xref-backend () 'elisp)
@@ -696,21 +792,214 @@ Each function should return a list of xrefs, or nil; the first
non-nil result supersedes the xrefs produced by
`elisp--xref-find-definitions'.")
+(defun elisp--xref-list-index ()
+ "Return the list index of the form at point, moving to the start.
+If the buffer start was reached, return nil."
+ (let ((i 0))
+ (while (condition-case nil
+ (let ((pt (point)))
+ (backward-sexp)
+ (< (point) pt))
+ (scan-error nil))
+ (setq i (1+ i)))
+ (and (not (bobp)) i)))
+
+(defun elisp--xref-infer-namespace (pos)
+ "Find the likely namespace of the identifier at POS.
+Return one of `function', `variable' `maybe-variable', `feature', `face', or
+`any' (indicating any namespace). `maybe-variable' indicates a variable
+namespace but with lower confidence."
+ (save-excursion
+ (goto-char pos)
+ (cl-flet ((looking-at-sym ()
+ (let ((val (save-excursion
+ (ignore-errors (read (current-buffer))))))
+ (and (symbolp val) val))))
+ (cond
+ ((and (eq (char-before pos) ?\')
+ (eq (char-before (1- pos)) ?#))
+ ;; #'IDENT
+ 'function)
+ ((memq (char-before pos) '(?\' ?`))
+ ;; 'IDENT or `IDENT -- try to disambiguate.
+ (backward-char) ; Step over '
+ (let ((i (elisp--xref-list-index))
+ (sym (looking-at-sym)))
+ (cond
+ ((eql i 1)
+ (cond
+ ((memq sym '( featurep require provide))
+ 'feature)
+ ((memq sym
+ '(
+ ;; We are mostly interested in functions that take a
+ ;; function symbol as argument:
+ fboundp symbol-function fset
+ ;; ... but we include some common higher-order functions
+ ;; as well, even though the argument really should
+ ;; be #'-quoted:
+ function-get function-put
+ func-arity functionp
+ funcall funcall-interactively
+ apply mapcar mapc mapcan mapconcat
+ apply-partially
+ substitute-key-definition))
+ 'function)
+ ((memq sym
+ '(
+ ;; Functions taking a variable symbol as first argument.
+ ;; More of these could be added for greater precision.
+ boundp set symbol-value
+ special-variable-p local-variable-p
+ local-variable-if-set-p
+ make-variable-buffer-local
+ default-value set-default make-local-variable
+ buffer-local-value))
+ 'variable)
+ ((memq sym
+ '(
+ ;; FIXME: Add more functions taking a face
+ ;; symbol for greater precision.
+ facep face-name face-id))
+ 'face)
+ (t 'any)))
+ ((and (eql i 2)
+ (memq sym '( global-set-key local-set-key
+ substitute-key-definition
+ add-hook)))
+ 'function)
+ ((and (eql i 3)
+ (memq sym '( define-key add-function)))
+ 'function)
+ (t 'any))))
+ ((or (and (eq (char-before (1- pos)) ?,)
+ (eq (char-before pos) ?@))
+ (eq (char-before pos) ?,))
+ ;; ,IDENT or ,@IDENT
+ 'variable)
+ (t
+ ;; Unquoted name -- look at the context. General scheme:
+ ;; (K-HEAD ... (J-HEAD ... (I-HEAD ... IDENT
+ ;; ^ index K ^ index J ^ index I
+ (let* ((i (elisp--xref-list-index))
+ (i-head (looking-at-sym))
+ (i-paren (and i (eq (char-before) ?\()
+ (progn (backward-char) t)))
+ (i-quoted (and i-paren (memq (char-before) '(?\' ?`))))
+ (j (and i-paren (elisp--xref-list-index)))
+ (j-head (and j (looking-at-sym)))
+ (j-paren (and j (eq (char-before) ?\()
+ (progn (backward-char) t)))
+ (j-quoted (and j-paren (memq (char-before) '(?\' ?`))))
+ (k (and j-paren (elisp--xref-list-index)))
+ (k-head (and k (looking-at-sym)))
+ (k-paren (and k (eq (char-before) ?\()
+ (progn (backward-char) t)))
+ (k-quoted (and k-paren (memq (char-before) '(?\' ?`)))))
+ (cond
+ ((or i-quoted j-quoted k-quoted)
+ ;; '(... IDENT or '(... (... IDENT or '(... (... (... IDENT
+ 'any)
+ ((and (eql j 1)
+ (memq j-head '( let let* letrec dlet lambda)))
+ ;; (let (... IDENT
+ 'variable)
+ ((and (eql j 2)
+ (memq j-head '( defun defmacro defsubst
+ define-inline declare-function
+ defadvice
+ cl-defmethod cl-defgeneric)))
+ ;; (defun FUNC (... IDENT
+ 'variable)
+ ((eq j-head 'cond)
+ ;; (cond ... (... IDENT
+ 'variable)
+ ((and (eql k 1)
+ (memq k-head '( let let* letrec dlet )))
+ ;; (let (... (... IDENT
+ 'variable)
+ ((eql i 0)
+ ;; (IDENT ...
+ 'function)
+ ((functionp i-head)
+ ;; (FUNC ... IDENT
+ 'variable)
+ ((and (eql i 1)
+ (cond
+ ((memq i-head '( function
+ defun defmacro defsubst
+ define-inline declare-function
+ defadvice
+ cl-defmethod cl-defgeneric))
+ 'function)
+ ((memq i-head '( defvar defvar-local defconst defcustom))
+ 'variable)
+ ((eq i-head 'defface)
+ 'face))))
+ ((memq i-head '( if while and or when unless progn prog1
+ let let* lambda defun defsubst defvar defconst))
+ ;; arg to some common non-function forms
+ 'variable)
+ ;; Anything else: probably a variable, but since i-head may be
+ ;; a macro we cannot be sure.
+ (t 'maybe-variable))))))))
+
+(cl-defmethod xref-backend-identifier-at-point ((_backend (eql 'elisp)))
+ (let ((bounds (bounds-of-thing-at-point 'symbol)))
+ (and bounds
+ (let ((ident (buffer-substring-no-properties
+ (car bounds) (cdr bounds))))
+ ;; Use a property to transport the location of the identifier.
+ (propertize ident 'pos (car bounds))))))
+
(cl-defmethod xref-backend-definitions ((_backend (eql 'elisp)) identifier)
(require 'find-func)
- ;; FIXME: use information in source near point to filter results:
- ;; (dvc-log-edit ...) - exclude 'feature
- ;; (require 'dvc-log-edit) - only 'feature
- ;; Semantic may provide additional information
- ;;
(let ((sym (intern-soft identifier)))
(when sym
- (elisp--xref-find-definitions sym))))
+ (let* ((pos (get-text-property 0 'pos identifier))
+ (namespace (if pos
+ (elisp--xref-infer-namespace pos)
+ 'any))
+ (defs (elisp--xref-find-definitions sym)))
+ (if (eq namespace 'maybe-variable)
+ (or (elisp--xref-filter-definitions defs 'variable sym)
+ (elisp--xref-filter-definitions defs 'any sym))
+ (elisp--xref-filter-definitions defs namespace sym))))))
+
+(defun elisp--xref-filter-definitions (definitions namespace symbol)
+ (if (eq namespace 'any)
+ (if (memq symbol minor-mode-list)
+ ;; The symbol is a minor mode. These should be defined by
+ ;; "define-minor-mode", which means the variable and the
+ ;; function are declared in the same place. So we return only
+ ;; the function, arbitrarily.
+ ;;
+ ;; There is an exception, when the variable is defined in C
+ ;; code, as for abbrev-mode.
+ (cl-loop for d in definitions
+ for loc = (xref-item-location d)
+ for file = (xref-elisp-location-file loc)
+ when (or (not (eq (xref-elisp-location-type loc) 'defvar))
+ (null file)
+ (string-prefix-p "src/" file))
+ collect d)
+ definitions)
+ (let ((expected-types
+ (pcase-exhaustive namespace
+ ('function '( nil defalias define-type
+ cl-defgeneric cl-defmethod))
+ ('variable '(defvar))
+ ('face '(defface))
+ ('feature '(feature)))))
+ (cl-loop for d in definitions
+ when (memq
+ (xref-elisp-location-type (xref-item-location d))
+ expected-types)
+ collect d))))
(defun elisp--xref-find-definitions (symbol)
;; The file name is not known when `symbol' is defined via interactive eval.
(let (xrefs)
-
(let ((temp elisp-xref-find-def-functions))
(while (and (null xrefs)
temp)
@@ -754,7 +1043,7 @@ non-nil result supersedes the xrefs produced by
;; First call to find-lisp-object-file-name for an object
;; defined in C; the doc strings from the C source have
;; not been loaded yet. Second call will return "src/*.c"
- ;; in file; handled by 't' case below.
+ ;; in file; handled by t case below.
(push (elisp--xref-make-xref nil symbol (help-C-file-name (symbol-function symbol) 'subr)) xrefs))
((and (setq doc (documentation symbol t))
@@ -774,6 +1063,8 @@ non-nil result supersedes the xrefs produced by
((setq generic (cl--generic symbol))
;; FIXME: move this to elisp-xref-find-def-functions, in cl-generic.el
+ ;; XXX: How are we going to support using newer xref
+ ;; with older versions of Emacs, though?
;; A generic function. If there is a default method, it
;; will appear in the method table, with no
@@ -796,7 +1087,7 @@ non-nil result supersedes the xrefs produced by
specializers))
(file (find-lisp-object-file-name met-name 'cl-defmethod)))
(dolist (item specializers)
- ;; default method has all 't' in specializers
+ ;; Default method has all t in specializers.
(setq non-default (or non-default (not (equal t item)))))
(when (and file
@@ -836,29 +1127,6 @@ non-nil result supersedes the xrefs produced by
;; return "src/*.c" in file; handled below.
(push (elisp--xref-make-xref 'defvar symbol (help-C-file-name symbol 'var)) xrefs))
- ((string= "src/" (substring file 0 4))
- ;; The variable is defined in a C source file; don't check
- ;; for define-minor-mode.
- (push (elisp--xref-make-xref 'defvar symbol file) xrefs))
-
- ((memq symbol minor-mode-list)
- ;; The symbol is a minor mode. These should be defined by
- ;; "define-minor-mode", which means the variable and the
- ;; function are declared in the same place. So we return only
- ;; the function, arbitrarily.
- ;;
- ;; There is an exception, when the variable is defined in C
- ;; code, as for abbrev-mode.
- ;;
- ;; IMPROVEME: If the user is searching for the identifier at
- ;; point, we can determine whether it is a variable or
- ;; function by looking at the source code near point.
- ;;
- ;; IMPROVEME: The user may actually be asking "do any
- ;; variables by this name exist"; we need a way to specify
- ;; that.
- nil)
-
(t
(push (elisp--xref-make-xref 'defvar symbol file) xrefs))
@@ -928,16 +1196,14 @@ non-nil result supersedes the xrefs produced by
;;; Elisp Interaction mode
-(defvar lisp-interaction-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map lisp-mode-shared-map)
- (define-key map "\e\C-x" 'eval-defun)
- (define-key map "\e\C-q" 'indent-pp-sexp)
- (define-key map "\e\t" 'completion-at-point)
- (define-key map "\n" 'eval-print-last-sexp)
- map)
- "Keymap for Lisp Interaction mode.
-All commands in `lisp-mode-shared-map' are inherited by this map.")
+(defvar-keymap lisp-interaction-mode-map
+ :doc "Keymap for Lisp Interaction mode.
+All commands in `lisp-mode-shared-map' are inherited by this map."
+ :parent lisp-mode-shared-map
+ "C-M-x" #'eval-defun
+ "C-M-q" #'indent-pp-sexp
+ "M-TAB" #'completion-at-point
+ "C-j" #'eval-print-last-sexp)
(easy-menu-define lisp-interaction-mode-menu lisp-interaction-mode-map
"Menu for Lisp Interaction mode."
@@ -1051,7 +1317,7 @@ this command arranges for all errors to enter the debugger."
(defun last-sexp-setup-props (beg end value alt1 alt2)
"Set up text properties for the output of `elisp--eval-last-sexp'.
-BEG and END are the start and end of the output in current-buffer.
+BEG and END are the start and end of the output in current buffer.
VALUE is the Lisp value printed, ALT1 and ALT2 are strings for the
alternative printed representations that can be displayed."
(let ((map (make-sparse-keymap)))
@@ -1452,7 +1718,7 @@ Elisp eldoc behaviour. Consider variable docstrings and function
signatures only, in this order. If none applies, returns nil.
Changes to `eldoc-documentation-functions' and
`eldoc-documentation-strategy' are _not_ reflected here. As such
-it is preferrable to use ElDoc's interfaces directly.")
+it is preferable to use ElDoc's interfaces directly.")
(make-obsolete 'elisp-eldoc-documentation-function
"use ElDoc's interfaces instead." "28.1")
@@ -1863,5 +2129,8 @@ Runs in a batch-mode Emacs. Interactively use variable
(terpri)
(pp collected)))
+
+(put 'read-symbol-shorthands 'safe-local-variable #'consp)
+
(provide 'elisp-mode)
;;; elisp-mode.el ends here
diff --git a/lisp/progmodes/erts-mode.el b/lisp/progmodes/erts-mode.el
new file mode 100644
index 00000000000..a12c964c250
--- /dev/null
+++ b/lisp/progmodes/erts-mode.el
@@ -0,0 +1,225 @@
+;;; erts-mode.el --- major mode to edit erts files -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Keywords: tools
+
+;; 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:
+
+(eval-when-compile (require 'cl-lib))
+(require 'ert)
+
+(defgroup erts-mode nil
+ "Major mode for editing Emacs test files."
+ :group 'lisp)
+
+(defface erts-mode-specification-name
+ '((((class color)
+ (background dark))
+ :foreground "green")
+ (((class color)
+ (background light))
+ :foreground "cornflower blue")
+ (t
+ :bold t))
+ "Face used for displaying specification names."
+ :group 'erts-mode)
+
+(defface erts-mode-specification-value
+ '((((class color)
+ (background dark))
+ :foreground "DeepSkyBlue1")
+ (((class color)
+ (background light))
+ :foreground "blue")
+ (t
+ :bold t))
+ "Face used for displaying specificaton values."
+ :group 'erts-mode)
+
+(defface erts-mode-start-test
+ '((t :inherit font-lock-keyword-face))
+ "Face used for displaying specificaton test start markers."
+ :group 'erts-mode)
+
+(defface erts-mode-end-test
+ '((t :inherit font-lock-comment-face))
+ "Face used for displaying specificaton test start markers."
+ :group 'erts-mode)
+
+(defvar erts-mode-map
+ (let ((map (make-keymap)))
+ (set-keymap-parent map prog-mode-map)
+ (define-key map "\C-c\C-r" 'erts-tag-region)
+ (define-key map "\C-c\C-c" 'erts-run-test)
+ map))
+
+(defvar erts-mode-font-lock-keywords
+ ;; Specifications.
+ `((erts-mode--match-not-in-test
+ ("^\\([^ \t\n:]+:\\)[ \t]*\\(.*\\(\n[ \t].*\\)*\\)\n?"
+ (progn (goto-char (match-beginning 0)) (match-end 0)) nil
+ (1 'erts-mode-specification-name)
+ (2 'erts-mode-specification-value)))
+ ("^=-=$" 0 'erts-mode-start-test)
+ ("^=-=-=$" 0 'erts-mode-end-test)))
+
+(defun erts-mode--match-not-in-test (_limit)
+ (when (erts-mode--in-test-p (point))
+ (erts-mode--end-of-test))
+ (let ((start (point)))
+ (goto-char
+ (if (re-search-forward "^=-=$" nil t)
+ (match-beginning 0)
+ (point-max)))
+ (if (< (point) start)
+ nil
+ ;; Here we disregard LIMIT so that we may extend the area again.
+ (set-match-data (list start (point)))
+ (point))))
+
+(defun erts-mode--end-of-test ()
+ (search-forward "^=-=-=\n" nil t))
+
+(defun erts-mode--in-test-p (point)
+ "Say whether POINT is in a test."
+ (save-excursion
+ (goto-char point)
+ (beginning-of-line)
+ (if (looking-at "=-=\\(-=\\)?$")
+ t
+ (let ((test-start (save-excursion
+ (re-search-backward "^=-=\n" nil t))))
+ ;; Before the first test.
+ (and test-start
+ (let ((test-end (re-search-backward "^=-=-=\n" nil t)))
+ (or (null test-end)
+ ;; Between tests.
+ (> test-start test-end))))))))
+
+;;;###autoload
+(define-derived-mode erts-mode prog-mode "erts"
+ "Major mode for editing erts (Emacs testing) files.
+This mode mainly provides some font locking.
+
+\\{erts-mode-map}"
+ (setq-local font-lock-defaults '(erts-mode-font-lock-keywords t)))
+
+(defun erts-tag-region (start end name)
+ "Tag the region between START and END as a test.
+Interactively, this is the region.
+
+NAME should be a string appropriate for output by ert if the test fails.
+If NAME is nil or the empty string, a name will be auto-generated."
+ (interactive "r\nsTest name: " erts-mode)
+ ;; Automatically make a name.
+ (when (zerop (length name))
+ (save-excursion
+ (goto-char (point-min))
+ (let ((names nil))
+ (while (re-search-forward "^Name:[ \t]*\\(.*\\)" nil t)
+ (let ((name (match-string 1)))
+ (unless (erts-mode--in-test-p (point))
+ (push name names))))
+ (setq name
+ (cl-loop with base = (file-name-sans-extension (buffer-name))
+ for i from 1
+ for name = (format "%s%d" base i)
+ unless (member name names)
+ return name)))))
+ (save-excursion
+ (goto-char end)
+ (unless (bolp)
+ (insert "\n"))
+ (insert "=-=-=\n")
+ (goto-char start)
+ (insert "Name: " name "\n\n")
+ (insert "=-=\n")))
+
+(defun erts-mode--preceding-spec (name)
+ (save-excursion
+ ;; Find the name, but skip if it's in a test.
+ (while (and (re-search-backward (format "^%s:" name) nil t)
+ (erts-mode--in-test-p (point))))
+ (and (not (erts-mode--in-test-p (point)))
+ (re-search-forward "^=-=$" nil t)
+ (progn
+ (goto-char (match-beginning 0))
+ (cdr (assq (intern (downcase name))
+ (ert--erts-specifications (point))))))))
+
+(defun erts-run-test (test-function &optional verbose)
+ "Run the current test.
+If the current erts file doesn't define a test function, the user
+will be prompted for one.
+
+If VERBOSE (interactively, the prefix), display a diff of the
+expected results and the actual results in a separate buffer."
+ (interactive
+ (list (or (erts-mode--preceding-spec "Code")
+ (read-string "Transformation function: "))
+ current-prefix-arg)
+ erts-mode)
+ (save-excursion
+ (erts-mode--goto-start-of-test)
+ (condition-case arg
+ (ert-test--erts-test
+ (list (cons 'dummy t)
+ (cons 'code (car (read-from-string test-function)))
+ (cons 'point-char (erts-mode--preceding-spec "Point-Char")))
+ (buffer-file-name))
+ (:success (message "Test successful"))
+ (ert-test-failed
+ (if (not verbose)
+ (message "Test failure; result: \n%s"
+ (substring-no-properties (cadr (cadr arg))))
+ (message "Test failure")
+ (let (expected got)
+ (unwind-protect
+ (progn
+ (with-current-buffer
+ (setq expected (generate-new-buffer "erts expected"))
+ (insert (nth 1 (cadr arg))))
+ (with-current-buffer
+ (setq got (generate-new-buffer "erts results"))
+ (insert (nth 2 (cadr arg))))
+ (diff-buffers expected got))
+ (kill-buffer expected)
+ (kill-buffer got))))))))
+
+(defun erts-mode--goto-start-of-test ()
+ (if (not (erts-mode--in-test-p (point)))
+ (re-search-forward "^=-=\n" nil t)
+ (re-search-backward "^=-=\n" nil t)
+ (let ((potential-start (match-end 0)))
+ ;; See if we're in a two-clause ("before" and "after") test or not.
+ (if-let ((start (and (save-excursion (re-search-backward "^=-=\n" nil t))
+ (match-end 0))))
+ (let ((end (save-excursion (re-search-backward "^=-=-=\n" nil t))))
+ (if (or (not end)
+ (> start end))
+ ;; We are, so go to the real start.
+ (goto-char start)
+ (goto-char potential-start)))
+ (goto-char potential-start)))))
+
+(provide 'erts-mode)
+
+;;; erts-mode.el ends here
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
index a1f806ae8c9..d7dbaa06505 100644
--- a/lisp/progmodes/etags.el
+++ b/lisp/progmodes/etags.el
@@ -145,7 +145,9 @@ Otherwise, `find-tag-default' is used."
:type '(choice (const nil) function))
(define-obsolete-variable-alias 'find-tag-marker-ring-length
- 'xref-marker-ring-length "25.1")
+ 'tags-location-ring-length "25.1")
+
+(defvar tags-location-ring-length 16)
(defcustom tags-tag-face 'default
"Face for tags in the output of `tags-apropos'."
@@ -158,11 +160,12 @@ Otherwise, `find-tag-default' is used."
:version "21.1")
(defcustom tags-apropos-additional-actions nil
- "Specify additional actions for `tags-apropos'.
+ "Specify additional actions for `tags-apropos' and `xref-find-apropos'.
If non-nil, value should be a list of triples (TITLE FUNCTION
-TO-SEARCH). For each triple, `tags-apropos' processes TO-SEARCH and
-lists tags from it. TO-SEARCH should be an alist, obarray, or symbol.
+TO-SEARCH). For each triple, `tags-apropos' and `xref-find-apropos'
+process TO-SEARCH and list tags from it. TO-SEARCH should be an alist,
+obarray, or symbol.
If it is a symbol, the symbol's value is used.
TITLE, a string, is a title used to label the additional list of tags.
FUNCTION is a function to call when a symbol is selected in the
@@ -179,10 +182,11 @@ Example value:
(sexp :tag "Tags to search")))
:version "21.1")
-(defvaralias 'find-tag-marker-ring 'xref--marker-ring)
+;; Obsolete variable kept for compatibility. We don't use it in any way.
+(defvar find-tag-marker-ring (make-ring 16))
(make-obsolete-variable
'find-tag-marker-ring
- "use `xref-push-marker-stack' or `xref-pop-marker-stack' instead."
+ "use `xref-push-marker-stack' or `xref-go-back' instead."
"25.1")
(defvar default-tags-table-function nil
@@ -190,7 +194,7 @@ Example value:
This function receives no arguments and should return the default
tags table file to use for the current buffer.")
-(defvar tags-location-ring (make-ring xref-marker-ring-length)
+(defvar tags-location-ring (make-ring tags-location-ring-length)
"Ring of markers which are locations visited by \\[find-tag].
Pop back to the last location with \\[negative-argument] \\[find-tag].")
@@ -291,7 +295,7 @@ file the tag was in."
(or (locate-dominating-file default-directory "TAGS")
default-directory)))
(list (read-file-name
- "Visit tags table (default TAGS): "
+ (format-prompt "Visit tags table" "TAGS")
;; default to TAGS from default-directory up to root.
default-tag-dir
(expand-file-name "TAGS" default-tag-dir)
@@ -624,7 +628,7 @@ Returns t if it visits a tags table, or nil if there are no more in the list."
(car list))
;; Finally, prompt the user for a file name.
(expand-file-name
- (read-file-name "Visit tags table (default TAGS): "
+ (read-file-name (format-prompt "Visit tags table" "TAGS")
default-directory
"TAGS"
t))))))
@@ -730,13 +734,13 @@ Returns t if it visits a tags table, or nil if there are no more in the list."
(interactive)
;; Clear out the markers we are throwing away.
(let ((i 0))
- (while (< i xref-marker-ring-length)
+ (while (< i tags-location-ring-length)
(if (aref (cddr tags-location-ring) i)
(set-marker (aref (cddr tags-location-ring) i) nil))
(setq i (1+ i))))
(xref-clear-marker-stack)
(setq tags-file-name nil
- tags-location-ring (make-ring xref-marker-ring-length)
+ tags-location-ring (make-ring tags-location-ring-length)
tags-table-list nil
tags-table-computed-list nil
tags-table-computed-list-for nil
@@ -748,7 +752,7 @@ Returns t if it visits a tags table, or nil if there are no more in the list."
"Return the file name of the file whose tags point is within.
Assumes the tags table is the current buffer.
If RELATIVE is non-nil, file name returned is relative to tags
-table file's directory. If RELATIVE is nil, file name returned
+table file's directory. If RELATIVE is nil, file name returned
is complete."
(funcall file-of-tag-function relative))
@@ -1067,7 +1071,7 @@ See documentation of variable `tags-file-name'."
regexp next-p t))
;;;###autoload
-(defalias 'pop-tag-mark 'xref-pop-marker-stack)
+(defalias 'pop-tag-mark 'xref-go-back)
(defvar tag-lines-already-matched nil
@@ -1988,7 +1992,8 @@ see the doc of that variable if you want to add names to the list."
(setq set-list (delete (car set-list) set-list)))
(goto-char (point-min))
(insert-before-markers
- "Type `t' to select a tags table or set of tags tables:\n\n")
+ (substitute-command-keys
+ "Type \\`t' to select a tags table or set of tags tables:\n\n"))
(if desired-point
(goto-char desired-point))
(set-window-start (selected-window) 1 t))
@@ -2096,7 +2101,10 @@ file name, add `tag-partial-file-name-match-p' to the list value.")
definitions))
(cl-defmethod xref-backend-apropos ((_backend (eql 'etags)) pattern)
- (etags--xref-find-definitions (xref-apropos-regexp pattern) t))
+ (let ((regexp (xref-apropos-regexp pattern)))
+ (nconc
+ (etags--xref-find-definitions regexp t)
+ (etags--xref-apropos-additional regexp))))
(defun etags--xref-find-definitions (pattern &optional regexp?)
;; This emulates the behavior of `find-tag-in-order' but instead of
@@ -2131,18 +2139,42 @@ file name, add `tag-partial-file-name-match-p' to the list value.")
(puthash mark-key t marks))))))))))
(nreverse xrefs)))
-(defclass xref-etags-location (xref-location)
- ((tag-info :type list :initarg :tag-info)
- (file :type string :initarg :file
- :reader xref-location-group))
- :documentation "Location of an etags tag.")
-
-(defun xref-make-etags-location (tag-info file)
- (make-instance 'xref-etags-location :tag-info tag-info
- :file (expand-file-name file)))
+(defun etags--xref-apropos-additional (regexp)
+ (cl-mapcan
+ (lambda (oba)
+ (pcase-let* ((`(,group ,goto-fun ,symbs) oba)
+ (res nil)
+ (add-xref (lambda (sym)
+ (let ((sn (symbol-name sym)))
+ (when (string-match-p regexp sn)
+ (push
+ (xref-make
+ sn
+ (xref-make-etags-apropos-location
+ sym goto-fun group))
+ res))))))
+ (when (symbolp symbs)
+ (if (boundp symbs)
+ (setq symbs (symbol-value symbs))
+ (warn "symbol `%s' has no value" symbs)
+ (setq symbs nil))
+ (if (vectorp symbs)
+ (mapatoms add-xref symbs)
+ (dolist (sy symbs)
+ (funcall add-xref (car sy))))
+ (nreverse res))))
+ tags-apropos-additional-actions))
+
+(cl-defstruct (xref-etags-location
+ (:constructor xref-make-etags-location (tag-info file)))
+ "Location of an etags tag."
+ tag-info file)
+
+(cl-defmethod xref-location-group ((l xref-etags-location))
+ (xref-etags-location-file l))
(cl-defmethod xref-location-marker ((l xref-etags-location))
- (with-slots (tag-info file) l
+ (pcase-let (((cl-struct xref-etags-location tag-info file) l))
(let ((buffer (find-file-noselect file)))
(with-current-buffer buffer
(save-excursion
@@ -2152,9 +2184,23 @@ file name, add `tag-partial-file-name-match-p' to the list value.")
(point-marker)))))))
(cl-defmethod xref-location-line ((l xref-etags-location))
- (with-slots (tag-info) l
+ (pcase-let (((cl-struct xref-etags-location tag-info) l))
(nth 1 tag-info)))
+(cl-defstruct (xref-etags-apropos-location
+ (:constructor xref-make-etags-apropos-location (symbol goto-fun group)))
+ "Location of an additional apropos etags symbol."
+ symbol goto-fun group)
+
+(cl-defmethod xref-location-group ((l xref-etags-apropos-location))
+ (xref-etags-apropos-location-group l))
+
+(cl-defmethod xref-location-marker ((l xref-etags-apropos-location))
+ (save-window-excursion
+ (pcase-let (((cl-struct xref-etags-apropos-location goto-fun symbol) l))
+ (funcall goto-fun symbol)
+ (point-marker))))
+
(provide 'etags)
diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el
index 5c0b7880e8b..eb6da20ff7f 100644
--- a/lisp/progmodes/f90.el
+++ b/lisp/progmodes/f90.el
@@ -64,10 +64,11 @@
;; The function f90-comment-region toggles insertion of
;; the variable f90-comment-region in every line of the region.
-;; One common convention for free vs. fixed format is that free format files
-;; have the ending .f90 or .f95 while fixed format files have the ending .f.
-;; Emacs automatically loads Fortran files in the appropriate mode based
-;; on extension. You can modify this by adjusting the variable auto-mode-alist.
+;; One common convention for free vs. fixed format is that free format
+;; files have the ending ".f90" or ".f95" while fixed format files have
+;; the ending ".f". Emacs automatically loads Fortran files in the
+;; appropriate mode based on extension. You can modify this by
+;; adjusting the variable `auto-mode-alist'.
;; For example:
;; (add-to-list 'auto-mode-alist '("\\.f\\'" . f90-mode))
@@ -104,21 +105,21 @@
;; (if f90-auto-keyword-case ; change case of all keywords on startup
;; (f90-change-keywords f90-auto-keyword-case))))
;;
-;; in your init file. You can also customize the lists
-;; f90-font-lock-keywords, etc.
+;; in your init file. You can also customize the lists
+;; `f90-font-lock-keywords', etc.
;;
;; The auto-fill and abbreviation minor modes are accessible from the F90 menu,
;; or by using M-x auto-fill-mode and M-x abbrev-mode, respectively.
;; Remarks
-;; 1) Line numbers are by default left-justified. If f90-leave-line-no is
+;; 1) Line numbers are by default left-justified. If f90-leave-line-no is
;; non-nil, the line numbers are never touched.
;; 2) Multi-; statements like "do i=1,20 ; j=j+i ; end do" are not handled
;; correctly, but I imagine them to be rare.
;; 3) Regexps for hilit19 are no longer supported.
;; 4) For FIXED FORMAT code, use fortran mode.
;; 5) Preprocessor directives, i.e., lines starting with # are left-justified
-;; and are untouched by all case-changing commands. There is, at present, no
+;; and are untouched by all case-changing commands. There is, at present, no
;; mechanism for treating multi-line directives (continued by \ ).
;; 6) f77 do-loops do 10 i=.. ; ; 10 continue are not correctly indented.
;; You are urged to use f90-do loops (with labels if you wish).
@@ -140,7 +141,7 @@
;; f90-font-lock-1, f90-font-lock-2, f90-font-lock-3, f90-font-lock-4
;; Original author's thanks
-;; Thanks to all the people who have tested the mode. Special thanks to Jens
+;; Thanks to all the people who have tested the mode. Special thanks to Jens
;; Bloch Helmers for encouraging me to write this code, for creative
;; suggestions as well as for the lists of hpf-commands.
;; Also thanks to the authors of the fortran and pascal modes, on which some
@@ -344,6 +345,7 @@ The options are `downcase-word', `upcase-word', `capitalize-word' and nil."
;; there are spaces.
"contiguous" "submodule" "concurrent" "codimension"
"sync all" "sync memory" "critical" "image_index" "error stop"
+ "impure"
))
"\\_>")
"Regexp used by the function `f90-change-keywords'.")
@@ -645,7 +647,7 @@ do\\([ \t]*while\\)?\\|select[ \t]*\\(?:case\\|type\\)\\|where\\|\
forall\\|block\\|critical\\)\\)\\_>"
(2 font-lock-constant-face nil t) (3 font-lock-keyword-face))
;; Implicit declaration.
- '("\\_<\\(implicit\\)[ \t]*\\(real\\|integer\\|c\\(haracter\\|omplex\\)\
+ '("\\_<\\(implicit\\)[ \t]+\\(real\\|integer\\|c\\(haracter\\|omplex\\)\
\\|enumerator\\|procedure\\|\
logical\\|double[ \t]*precision\\|type[ \t]*(\\(?:\\sw\\|\\s_\\)+)\\|none\\)[ \t]*"
(1 font-lock-keyword-face) (2 font-lock-type-face))
@@ -655,8 +657,10 @@ logical\\|double[ \t]*precision\\|type[ \t]*(\\(?:\\sw\\|\\s_\\)+)\\|none\\)[ \t
'("\\(&\\)[ \t]*\\(!\\|$\\)" (1 font-lock-keyword-face))
"\\_<\\(then\\|continue\\|format\\|include\\|\\(?:error[ \t]+\\)?stop\\|\
return\\)\\_>"
- '("\\_<\\(exit\\|cycle\\)[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)?\\_>"
+ '("\\_<\\(exit\\|cycle\\)[ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)?\\_>"
(1 font-lock-keyword-face) (2 font-lock-constant-face nil t))
+ '("\\_<\\(exit\\|cycle\\)\\_>"
+ (1 font-lock-keyword-face))
'("\\_<\\(case\\)[ \t]*\\(default\\|(\\)" . 1)
;; F2003 "class default".
'("\\_<\\(class\\)[ \t]*default" . 1)
@@ -983,7 +987,7 @@ Used in the F90 entry in `hs-special-modes-alist'.")
;; FIXME trivial to extend this to enum. Worth it?
(defun f90-imenu-type-matcher ()
"Search backward for the start of a derived type.
-Set subexpression 1 in the match-data to the name of the type."
+Set subexpression 1 in the `match-data' to the name of the type."
(let (found)
(while (and (re-search-backward "^[ \t0-9]*type[ \t]*" nil t)
(not (setq found
diff --git a/lisp/progmodes/flymake-cc.el b/lisp/progmodes/flymake-cc.el
index bd403faf7c4..3ae3fcb9fec 100644
--- a/lisp/progmodes/flymake-cc.el
+++ b/lisp/progmodes/flymake-cc.el
@@ -61,23 +61,34 @@ SOURCE."
(cl-loop
while
(search-forward-regexp
- "^\\(In file included from \\)?<stdin>:\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?:\n?\\(.*\\): \\(.*\\)$"
+ "^\\(In file included from \\)?\\([^ :]+\\):\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?:\n?\\(.*\\): \\(.*\\)$"
nil t)
- for msg = (match-string 5)
- for (beg . end) = (flymake-diag-region
- source
- (string-to-number (match-string 2))
- (and (match-string 3) (string-to-number (match-string 3))))
+ for msg = (match-string 6)
+ for locus = (match-string 2)
+ for line = (string-to-number (match-string 3))
+ for col = (ignore-errors (string-to-number (match-string 4)))
+ for source-buffer = (and (string= locus "<stdin>") source)
for type = (if (match-string 1)
:error
- (assoc-default
- (match-string 4)
- '(("error" . :error)
- ("note" . :note)
- ("warning" . :warning))
- #'string-match
- :error))
- collect (flymake-make-diagnostic source beg end type msg)))
+ (save-match-data
+ (assoc-default
+ (match-string 5)
+ '(("error" . :error)
+ ("note" . :note)
+ ("warning" . :warning))
+ #'string-match
+ :error)))
+ for diag =
+ (cond (source-buffer
+ (pcase-let ((`(,beg . ,end)
+ (flymake-diag-region source-buffer line col)))
+ (flymake-make-diagnostic source-buffer beg end type msg)))
+ (t (flymake-make-diagnostic locus (cons line col) nil type msg)))
+ collect diag
+ ;; If "In file included from..." matched, then move to end of that
+ ;; line. This helps us collect the diagnostic at its .h locus,
+ ;; too.
+ when (match-end 1) do (goto-char (match-end 2))))
(defun flymake-cc-use-special-make-target ()
"Command for checking a file via a CHK_SOURCES Make target."
@@ -88,7 +99,7 @@ SOURCE."
(cond ((derived-mode-p 'c++-mode) "c++")
(t "c")))))
-(defvar-local flymake-cc--proc nil "Internal variable for `flymake-cc'")
+(defvar-local flymake-cc--proc nil "Internal variable for `flymake-cc'.")
;; forward declare this to shoosh compiler (instead of requiring
;; flymake-proc)
diff --git a/lisp/progmodes/flymake-proc.el b/lisp/progmodes/flymake-proc.el
index 9cbad121d1f..7f2aa0f469f 100644
--- a/lisp/progmodes/flymake-proc.el
+++ b/lisp/progmodes/flymake-proc.el
@@ -188,10 +188,14 @@ Convert it to Flymake internal format."
2 4 5 6))
;; compilation-error-regexp-alist)
(flymake-proc-reformat-err-line-patterns-from-compile-el compilation-error-regexp-alist-alist))
- "Patterns for matching error/warning lines. Each pattern has the form
-\(REGEXP FILE-IDX LINE-IDX COL-IDX ERR-TEXT-IDX).
-Use `flymake-proc-reformat-err-line-patterns-from-compile-el' to add patterns
-from compile.el")
+ "Patterns for matching error/warning lines.
+
+Each pattern has the form:
+
+ (REGEXP FILE-IDX LINE-IDX COL-IDX ERR-TEXT-IDX)
+
+Use `flymake-proc-reformat-err-line-patterns-from-compile-el' to
+add patterns from compile.el.")
(define-obsolete-variable-alias 'flymake-warning-re 'flymake-proc-diagnostic-type-pred "26.1")
(defvar flymake-proc-diagnostic-type-pred
@@ -760,7 +764,7 @@ May only be called in a dynamic environment where
(defun flymake-proc-legacy-flymake (report-fn &rest args)
"Flymake backend based on the original Flymake implementation.
This function is suitable for inclusion in
-`flymake-diagnostic-functions'. For backward compatibility, it
+`flymake-diagnostic-functions'. For backward compatibility, it
can also be executed interactively independently of
`flymake-mode'."
;; Interactively, behave as if flymake had invoked us through its
@@ -898,7 +902,7 @@ can also be executed interactively independently of
temp-dir))))
(defun flymake-proc--delete-temp-directory (dir-name)
- "Attempt to delete temp dir created by `flymake-proc-create-temp-with-folder-structure', do not fail on error."
+ "Attempt to delete temp dir DIR-NAME, do not fail on error."
(let* ((temp-dir temporary-file-directory)
(suffix (substring dir-name (1+ (length (directory-file-name temp-dir))))))
@@ -915,7 +919,8 @@ can also be executed interactively independently of
(defvar-local flymake-proc--base-dir nil)
(defun flymake-proc-init-create-temp-buffer-copy (create-temp-f)
- "Make a temporary copy of the current buffer, save its name in buffer data and return the name."
+ "Make a temporary copy of the current buffer, save its name in buffer data.
+Return the name."
(let* ((source-file-name buffer-file-name)
(temp-source-file-name (funcall create-temp-f source-file-name "flymake")))
@@ -1003,7 +1008,7 @@ Return full-name. Names are real, not patched."
buildfile-name source-file-name)))))
(defun flymake-proc--init-create-temp-source-and-master-buffer-copy (get-incl-dirs-f create-temp-f master-file-masks include-regexp)
- "Find master file (or buffer), create its copy along with a copy of the source file."
+ "Find master file (or buffer), create its copy and a copy of the source file."
(let* ((source-file-name buffer-file-name)
(temp-source-file-name (flymake-proc-init-create-temp-buffer-copy create-temp-f))
(master-and-temp-master (flymake-proc--create-master-file
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index 77a807f21ae..72199b33a43 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -4,9 +4,9 @@
;; Author: Pavel Kobyakov <pk_at_work@yahoo.com>
;; Maintainer: João Távora <joaotavora@gmail.com>
-;; Version: 1.1.1
+;; Version: 1.2.1
;; Keywords: c languages tools
-;; Package-Requires: ((emacs "26.1") (eldoc "1.1.0"))
+;; Package-Requires: ((emacs "28.1") (eldoc "1.1.0") (project "0.7.1"))
;; This is a GNU ELPA :core package. Avoid functionality that is not
;; compatible with the version of Emacs recorded above.
@@ -121,6 +121,7 @@
(require 'mwheel)
;; when-let*, if-let*, hash-table-keys, hash-table-values:
(eval-when-compile (require 'subr-x))
+(require 'project)
(defgroup flymake nil
"Universal on-the-fly syntax checker."
@@ -265,7 +266,9 @@ If set to nil, don't suppress any zero counters."
(warning-type-format
(format " [%s %s]"
(or sublog 'flymake)
- (current-buffer))))
+ ;; Handle file names with "%" correctly. (Bug#51549)
+ (string-replace "%" "%%"
+ (buffer-name (current-buffer))))))
(display-warning (list 'flymake sublog)
(apply #'format-message msg args)
(if (numberp level)
@@ -291,7 +294,7 @@ generated it."
(macroexp-file-name)
(and (not load-file-name)
(bound-and-true-p byte-compile-current-file))))
- (sublog (if file
+ (sublog (if (stringp file)
(intern
(file-name-nondirectory
(file-name-sans-extension file))))))
@@ -305,35 +308,51 @@ generated it."
(cl-defstruct (flymake--diag
(:constructor flymake--diag-make))
- buffer beg end type text backend data overlay-properties overlay)
+ locus beg end type text backend data overlay-properties overlay
+ ;; FIXME: See usage of these two in `flymake--highlight-line'.
+ ;; Ideally they wouldn't be needed.
+ orig-beg orig-end)
;;;###autoload
-(defun flymake-make-diagnostic (buffer
+(defun flymake-make-diagnostic (locus
beg
end
type
text
&optional data
overlay-properties)
- "Make a Flymake diagnostic for BUFFER's region from BEG to END.
+ "Make a Flymake diagnostic for LOCUS's region from BEG to END.
+LOCUS is a buffer object or a string designating a file name.
+
TYPE is a diagnostic symbol and TEXT is string describing the
problem detected in this region. DATA is any object that the
caller wishes to attach to the created diagnostic for later
-retrieval.
+retrieval with `flymake-diagnostic-data'.
+
+If LOCUS is a buffer BEG and END should be buffer positions
+inside it. If LOCUS designates a file, BEG and END should be a
+cons (LINE . COL) indicating a file position. In this second
+case, END may be omitted in which case the region is computed
+using `flymake-diag-region' if the diagnostic is appended to an
+actual buffer.
OVERLAY-PROPERTIES is an alist of properties attached to the
created diagnostic, overriding the default properties and any
-properties of `flymake-overlay-control' of the diagnostic's
-type."
- (flymake--diag-make :buffer buffer :beg beg :end end
+properties listed in the `flymake-overlay-control' property of
+the diagnostic's type symbol."
+ (when (stringp locus)
+ (setq locus (expand-file-name locus)))
+ (flymake--diag-make :locus locus :beg beg :end end
:type type :text text :data data
- :overlay-properties overlay-properties))
+ :overlay-properties overlay-properties
+ :orig-beg beg
+ :orig-end end))
;;;###autoload
(defun flymake-diagnostics (&optional beg end)
"Get Flymake diagnostics in region determined by BEG and END.
-If neither BEG or END is supplied, use the whole buffer,
+If neither BEG or END is supplied, use whole accessible buffer,
otherwise if BEG is non-nil and END is nil, consider only
diagnostics at BEG."
(mapcar (lambda (ov) (overlay-get ov 'flymake-diagnostic))
@@ -345,27 +364,13 @@ diagnostics at BEG."
,(format "Get Flymake diagnostic DIAG's %s." (symbol-name thing))
(,internal diag)))
-(flymake--diag-accessor flymake-diagnostic-buffer flymake--diag-buffer buffer)
(flymake--diag-accessor flymake-diagnostic-text flymake--diag-text text)
(flymake--diag-accessor flymake-diagnostic-type flymake--diag-type type)
(flymake--diag-accessor flymake-diagnostic-backend flymake--diag-backend backend)
-(flymake--diag-accessor flymake-diagnostic-data flymake--diag-data backend)
-
-(defun flymake-diagnostic-beg (diag)
- "Get Flymake diagnostic DIAG's start position.
-This position only be queried after DIAG has been reported to Flymake."
- (let ((overlay (flymake--diag-overlay diag)))
- (unless overlay
- (error "DIAG %s not reported to Flymake yet" diag))
- (overlay-start overlay)))
-
-(defun flymake-diagnostic-end (diag)
- "Get Flymake diagnostic DIAG's end position.
-This position only be queried after DIAG has been reported to Flymake."
- (let ((overlay (flymake--diag-overlay diag)))
- (unless overlay
- (error "DIAG %s not reported to Flymake yet" diag))
- (overlay-end overlay)))
+(flymake--diag-accessor flymake-diagnostic-data flymake--diag-data data)
+(flymake--diag-accessor flymake-diagnostic-beg flymake--diag-beg beg)
+(flymake--diag-accessor flymake-diagnostic-end flymake--diag-end end)
+(flymake--diag-accessor flymake-diagnostic-buffer flymake--diag-locus locus)
(cl-defun flymake--overlays (&key beg end filter compare key)
"Get flymake-related overlays.
@@ -556,7 +561,7 @@ Currently accepted REPORT-KEY arguments are:
(put :warning 'flymake-category 'flymake-warning)
(put :note 'flymake-category 'flymake-note)
-(defvar flymake-diagnostic-types-alist '() "")
+(defvar flymake-diagnostic-types-alist '())
(make-obsolete-variable
'flymake-diagnostic-types-alist
"Set properties on the diagnostic symbols instead. See Info
@@ -625,13 +630,74 @@ associated `flymake-category' return DEFAULT."
bitmap
(list bitmap)))))))
-(defun flymake--highlight-line (diagnostic)
- "Highlight buffer with info in DIGNOSTIC."
- (let ((type (or (flymake--diag-type diagnostic)
- :error))
- (ov (make-overlay
- (flymake--diag-beg diagnostic)
- (flymake--diag-end diagnostic))))
+(defun flymake--equal-diagnostic-p (a b)
+ "Tell if A and B are equivalent `flymake--diag' objects."
+ (or (eq a b)
+ (cl-loop for comp in '(flymake--diag-end
+ flymake--diag-beg
+ flymake-diagnostic-type
+ flymake-diagnostic-backend
+ flymake-diagnostic-text)
+ always (equal (funcall comp a) (funcall comp b)))))
+
+(cl-defun flymake--highlight-line (diagnostic &optional foreign)
+ "Attempt to overlay DIAGNOSTIC in current buffer.
+
+FOREIGN says if DIAGNOSTIC is \"foreign\" to the current buffer,
+i.e. managed by another buffer where `flymake-mode' is also
+active.
+
+This function mayskip overlay creation if a diagnostic which is
+the same as DIAGNOSTIC is already highlighted
+(in the sense of `flymake--equal-diagnostic-p'). In that case
+the action to take depends on FOREIGN. If nil the existing
+overlay is deleted, else no overlay is created.
+
+Return nil or the overlay created."
+ (let* ((type (or (flymake-diagnostic-type diagnostic)
+ :error))
+ (beg (flymake--diag-beg diagnostic))
+ (end (flymake--diag-end diagnostic))
+ (convert (lambda (cell)
+ (flymake-diag-region (current-buffer)
+ (car cell)
+ (cdr cell))))
+ ov)
+ ;; Convert (LINE . COL) forms of `flymake--diag-beg' and
+ ;; `flymake--diag-end'. Record the converted positions.
+ ;;
+ (cond ((and (consp beg) (not (null end)))
+ (setq beg (car (funcall convert beg)))
+ (when (consp end)
+ (setq end (car (funcall convert end)))))
+ ((consp beg)
+ (cl-destructuring-bind (a . b) (funcall convert beg)
+ (setq beg a end b))))
+ (setf (flymake--diag-beg diagnostic) beg
+ (flymake--diag-end diagnostic) end)
+ ;; Try to fix the remedy the situation if there is the same
+ ;; diagnostic is already registered in the same place, which only
+ ;; happens for clashes between domestic and foreign diagnostics
+ (cl-loop for e in (flymake-diagnostics beg end)
+ when (flymake--equal-diagnostic-p e diagnostic)
+ ;; FIXME. This is an imperfect heuristic. Ideally, we'd
+ ;; want to delete no overlays and keep annotating the
+ ;; superseded foreign in an overlay but hide it from most
+ ;; `flymake-diagnostics' calls. If the target buffer is
+ ;; killed we can keep the "latent" state of the foreign
+ ;; diagnostic (with filename and updated line/col info).
+ ;; If it is revisited the foreign diagnostic can be
+ ;; revived again.
+ do (if foreign
+ (cl-return-from flymake--highlight-line nil)
+ (setf (flymake--diag-beg e)
+ (flymake--diag-orig-beg e)
+ (flymake--diag-end e)
+ (flymake--diag-orig-end e))
+ (delete-overlay (flymake--diag-overlay e))))
+ (setq ov (make-overlay end beg))
+ (setf (flymake--diag-beg diagnostic) (overlay-start ov)
+ (flymake--diag-end diagnostic) (overlay-end ov))
;; First set `category' in the overlay
;;
(overlay-put ov 'category
@@ -665,7 +731,7 @@ associated `flymake-category' return DEFAULT."
(lambda (window _ov pos)
(with-selected-window window
(mapconcat
- #'flymake--diag-text
+ #'flymake-diagnostic-text
(flymake-diagnostics pos)
"\n"))))
(default-maybe 'severity (warning-numeric-level :error))
@@ -676,17 +742,18 @@ associated `flymake-category' return DEFAULT."
;;
(overlay-put ov 'evaporate t)
(overlay-put ov 'flymake-diagnostic diagnostic)
+ (setf (flymake--diag-overlay diagnostic) ov)
ov))
;; Nothing in Flymake uses this at all any more, so this is just for
;; third-party compatibility.
(define-obsolete-function-alias 'flymake-display-warning 'message-box "26.1")
-(defvar-local flymake--backend-state nil
- "Buffer-local hash table of a Flymake backend's state.
+(defvar-local flymake--state nil
+ "State of a buffer's multiple Flymake backends.
The keys to this hash table are functions as found in
`flymake-diagnostic-functions'. The values are structures
-of the type `flymake--backend-state', with these slots:
+of the type `flymake--state', with these slots:
`running', a symbol to keep track of a backend's replies via its
REPORT-FN argument. A backend is running if this key is
@@ -701,11 +768,16 @@ since it last was contacted.
`disabled', a string with the explanation for a previous
exceptional situation reported by the backend, nil if the
-backend is operating normally.")
+backend is operating normally.
+
+`foreign-diags', a hash table of buffers/files to
+collections of diagnostics outside the buffer where this
+`flymake--state' pertains.")
-(cl-defstruct (flymake--backend-state
+(cl-defstruct (flymake--state
(:constructor flymake--make-backend-state))
- running reported-p disabled diags)
+ running reported-p disabled diags (foreign-diags
+ (make-hash-table)))
(defmacro flymake--with-backend-state (backend state-var &rest body)
"Bind BACKEND's STATE-VAR to its state, run BODY."
@@ -713,9 +785,9 @@ backend is operating normally.")
(let ((b (make-symbol "b")))
`(let* ((,b ,backend)
(,state-var
- (or (gethash ,b flymake--backend-state)
+ (or (gethash ,b flymake--state)
(puthash ,b (flymake--make-backend-state)
- flymake--backend-state))))
+ flymake--state))))
,@body)))
(defun flymake-is-running ()
@@ -730,9 +802,10 @@ backend is operating normally.")
(and (>= start1 start0) (< start1 end0))
(and (> end1 start0) (<= end1 end0))))
-(cl-defun flymake--handle-report (backend token report-action
- &key explanation force region
- &allow-other-keys)
+(cl-defun flymake--handle-report
+ (backend token report-action
+ &key explanation force region
+ &allow-other-keys)
"Handle reports from BACKEND identified by TOKEN.
BACKEND, REPORT-ACTION and EXPLANATION, and FORCE conform to the
calling convention described in
@@ -740,81 +813,117 @@ calling convention described in
to handle a report even if TOKEN was not expected. REGION is
a (BEG . END) pair of buffer positions indicating that this
report applies to that region."
- (let* ((state (gethash backend flymake--backend-state))
- first-report)
- (unless state
- (error "Can't find state for %s in `flymake--backend-state'" backend))
- (setf first-report (not (flymake--backend-state-reported-p state)))
- (setf (flymake--backend-state-reported-p state) t)
- (let (expected-token
- new-diags)
- (cond
- ((null state)
- (flymake-error
- "Unexpected report from unknown backend %s" backend))
- ((flymake--backend-state-disabled state)
- (flymake-error
- "Unexpected report from disabled backend %s" backend))
- ((progn
- (setq expected-token (flymake--backend-state-running state))
- (null expected-token))
- ;; should never happen
- (flymake-error "Unexpected report from stopped backend %s" backend))
- ((not (or (eq expected-token token)
- force))
- (flymake-error "Obsolete report from backend %s with explanation %s"
- backend explanation))
- ((eq :panic report-action)
- (flymake--disable-backend backend explanation))
- ((not (listp report-action))
- (flymake--disable-backend backend
- (format "Unknown action %S" report-action))
- (flymake-error "Expected report, but got unknown key %s" report-action))
- (t
- (setq new-diags
- (cl-remove-if-not
- (lambda (diag) (eq (flymake--diag-buffer diag) (current-buffer)))
- report-action))
- (save-restriction
- (widen)
- ;; Before adding to backend's diagnostic list, decide if
- ;; some or all must be deleted. When deleting, also delete
- ;; the associated overlay.
- (cond
- (region
- (cl-loop for diag in (flymake--backend-state-diags state)
- for ov = (flymake--diag-overlay diag)
- if (or (not (overlay-buffer ov))
- (flymake--intersects-p
- (overlay-start ov) (overlay-end ov)
- (car region) (cdr region)))
- do (delete-overlay ov)
- else collect diag into surviving
- finally (setf (flymake--backend-state-diags state)
- surviving)))
- (first-report
- (dolist (diag (flymake--backend-state-diags state))
- (delete-overlay (flymake--diag-overlay diag)))
- (setf (flymake--backend-state-diags state) nil)))
- ;; Now make new ones
- (mapc (lambda (diag)
- (let ((overlay (flymake--highlight-line diag)))
- (setf (flymake--diag-backend diag) backend
- (flymake--diag-overlay diag) overlay)))
- new-diags)
- (setf (flymake--backend-state-diags state)
- (append new-diags (flymake--backend-state-diags state)))
- (when flymake-check-start-time
- (flymake-log :debug "backend %s reported %d diagnostics in %.2f second(s)"
- backend
- (length new-diags)
- (float-time
- (time-since flymake-check-start-time))))
- (when (and (get-buffer (flymake--diagnostics-buffer-name))
- (get-buffer-window (flymake--diagnostics-buffer-name))
- (null (cl-set-difference (flymake-running-backends)
- (flymake-reporting-backends))))
- (flymake-show-diagnostics-buffer))))))))
+ (let ((state (or (gethash backend flymake--state)
+ (error "Can't find state for %s in `flymake--state'"
+ backend)))
+ expected-token)
+ (cond
+ ((null state)
+ (flymake-error
+ "Unexpected report from unknown backend %s" backend))
+ ((flymake--state-disabled state)
+ (flymake-error
+ "Unexpected report from disabled backend %s" backend))
+ ((progn
+ (setq expected-token (flymake--state-running state))
+ (null expected-token))
+ ;; should never happen
+ (flymake-error "Unexpected report from stopped backend %s" backend))
+ ((not (or (eq expected-token token)
+ force))
+ (flymake-error "Obsolete report from backend %s with explanation %s"
+ backend explanation))
+ ((eq :panic report-action)
+ (flymake--disable-backend backend explanation))
+ ((not (listp report-action))
+ (flymake--disable-backend backend
+ (format "Unknown action %S" report-action))
+ (flymake-error "Expected report, but got unknown key %s" report-action))
+ (t
+ (flymake--publish-diagnostics report-action
+ :backend backend
+ :state state
+ :region region)
+ (when flymake-check-start-time
+ (flymake-log :debug "backend %s reported %d diagnostics in %.2f second(s)"
+ backend
+ (length report-action)
+ (float-time
+ (time-since flymake-check-start-time))))))
+ (setf (flymake--state-reported-p state) t)
+ (flymake--update-diagnostics-listings (current-buffer))))
+
+(defun flymake--clear-foreign-diags (state)
+ (maphash (lambda (_buffer diags)
+ (cl-loop for d in diags
+ when (flymake--diag-overlay d)
+ do (delete-overlay it)))
+ (flymake--state-foreign-diags state))
+ (clrhash (flymake--state-foreign-diags state)))
+
+(defvar-local flymake-mode nil)
+
+(cl-defun flymake--publish-diagnostics (diags &key backend state region)
+ "Helper for `flymake--handle-report'.
+Publish DIAGS, which contain diagnostics for the current buffer
+and other buffers."
+ (dolist (d diags) (setf (flymake--diag-backend d) backend))
+ (save-restriction
+ (widen)
+ ;; First, clean up. Remove diagnostics from bookkeeping lists and
+ ;; their overlays from buffers.
+ ;;
+ (cond
+ (;; If there is a `region' arg, only affect the diagnostics whose
+ ;; overlays are in a certain region. Discard "foreign"
+ ;; diagnostics.
+ region
+ (cl-loop for diag in (flymake--state-diags state)
+ for ov = (flymake--diag-overlay diag)
+ if (or (not (overlay-buffer ov))
+ (flymake--intersects-p
+ (overlay-start ov) (overlay-end ov)
+ (car region) (cdr region)))
+ do (delete-overlay ov)
+ else collect diag into surviving
+ finally (setf (flymake--state-diags state)
+ surviving)))
+ (;; Else, if this is the first report, zero all lists and delete
+ ;; all associated overlays.
+ (not (flymake--state-reported-p state))
+ (cl-loop for diag in (flymake--state-diags state)
+ for ov = (flymake--diag-overlay diag)
+ when ov do (delete-overlay ov))
+ (setf (flymake--state-diags state) nil)
+ ;; Also clear all overlays for `foreign-diags' in all other
+ ;; buffers.
+ (flymake--clear-foreign-diags state))
+ (;; If this is not the first report, do no cleanup.
+ t))
+
+ ;; Now place new overlays for all diagnostics: "domestic"
+ ;; diagnostics are for the current buffer; "foreign" may be for a
+ ;; some other live buffer or for a file name that hasn't a buffer
+ ;; yet. If a foreign diagnostic is for a buffer, convert to a
+ ;; file name, protecting it against that buffer's killing.
+ ;;
+ (cl-loop
+ for d in diags
+ for locus = (flymake--diag-locus d)
+ do (cond ((eq locus (current-buffer))
+ (push d (flymake--state-diags state))
+ (flymake--highlight-line d))
+ (t
+ (when (or (buffer-live-p locus)
+ (setq locus (find-buffer-visiting locus)))
+ (with-current-buffer locus
+ (when flymake-mode (flymake--highlight-line d 'foreign))
+ ;; Ensure locus of a foreign diag is always a file-name
+ ;; string, even if created from a buffer.
+ (setf (flymake--diag-locus d) (buffer-file-name))))
+ (cl-assert (stringp (flymake--diag-locus d)))
+ (push d (gethash (flymake--diag-locus d)
+ (flymake--state-foreign-diags state))))))))
(defun flymake-make-report-fn (backend &optional token)
"Make a suitable anonymous report function for BACKEND.
@@ -830,12 +939,12 @@ different runs of the same backend."
(defun flymake--collect (fn &optional message-prefix)
"Collect Flymake backends matching FN.
If MESSAGE-PREFIX, echo a message using that prefix."
- (unless flymake--backend-state
+ (unless flymake--state
(user-error "Flymake is not initialized"))
(let (retval)
(maphash (lambda (backend state)
(when (funcall fn state) (push backend retval)))
- flymake--backend-state)
+ flymake--state)
(when message-prefix
(message "%s%s"
message-prefix
@@ -846,21 +955,21 @@ If MESSAGE-PREFIX, echo a message using that prefix."
(defun flymake-running-backends ()
"Compute running Flymake backends in current buffer."
(interactive)
- (flymake--collect #'flymake--backend-state-running
+ (flymake--collect #'flymake--state-running
(and (called-interactively-p 'interactive)
"Running backends: ")))
(defun flymake-disabled-backends ()
"Compute disabled Flymake backends in current buffer."
(interactive)
- (flymake--collect #'flymake--backend-state-disabled
+ (flymake--collect #'flymake--state-disabled
(and (called-interactively-p 'interactive)
"Disabled backends: ")))
(defun flymake-reporting-backends ()
"Compute reporting Flymake backends in current buffer."
(interactive)
- (flymake--collect #'flymake--backend-state-reported-p
+ (flymake--collect #'flymake--state-reported-p
(and (called-interactively-p 'interactive)
"Reporting backends: ")))
@@ -869,9 +978,9 @@ If MESSAGE-PREFIX, echo a message using that prefix."
If it is running also stop it."
(flymake-log :warning "Disabling backend %s because %s" backend explanation)
(flymake--with-backend-state backend state
- (setf (flymake--backend-state-running state) nil
- (flymake--backend-state-disabled state) explanation
- (flymake--backend-state-reported-p state) t)))
+ (setf (flymake--state-running state) nil
+ (flymake--state-disabled state) explanation
+ (flymake--state-reported-p state) t)))
(defun flymake--run-backend (backend &optional args)
"Run the backend BACKEND, re-enabling if necessary.
@@ -880,9 +989,9 @@ with a report function."
(flymake-log :debug "Running backend %s" backend)
(let ((run-token (cl-gensym "backend-token")))
(flymake--with-backend-state backend state
- (setf (flymake--backend-state-running state) run-token
- (flymake--backend-state-disabled state) nil
- (flymake--backend-state-reported-p state) nil))
+ (setf (flymake--state-running state) run-token
+ (flymake--state-disabled state) nil
+ (flymake--state-reported-p state) nil))
;; FIXME: Should use `condition-case-unless-debug' here, but don't
;; for two reasons: (1) that won't let me catch errors from inside
;; `ert-deftest' where `debug-on-error' appears to be always
@@ -964,7 +1073,7 @@ Interactively, with a prefix arg, FORCE is t."
(cond
((and (not force)
(flymake--with-backend-state backend state
- (flymake--backend-state-disabled state)))
+ (flymake--state-disabled state)))
(flymake-log :debug "Backend %s is disabled, not starting"
backend))
(t
@@ -973,7 +1082,7 @@ Interactively, with a prefix arg, FORCE is t."
(defvar flymake-mode-map
(let ((map (make-sparse-keymap))) map)
- "Keymap for `flymake-mode'")
+ "Keymap for `flymake-mode'.")
;;;###autoload
(define-minor-mode flymake-mode
@@ -1019,13 +1128,43 @@ special *Flymake log* buffer." :group 'flymake :lighter
;; If Flymake happened to be already already ON, we must cleanup
;; existing diagnostic overlays, lest we forget them by blindly
- ;; reinitializing `flymake--backend-state' in the next line.
+ ;; reinitializing `flymake--state' in the next line.
;; See https://github.com/joaotavora/eglot/issues/223.
(mapc #'delete-overlay (flymake--overlays))
- (setq flymake--backend-state (make-hash-table))
+ (setq flymake--state (make-hash-table))
(setq flymake--recent-changes nil)
- (when flymake-start-on-flymake-mode (flymake-start t)))
+ (when flymake-start-on-flymake-mode (flymake-start t))
+
+ ;; Other diagnostic sources may already target this buffer's file
+ ;; before we turned on: these sources may be of two types...
+ (let ((source (current-buffer))
+ (bfn buffer-file-name))
+ ;; 1. For `flymake-list-only-diagnostics': here, we do nothing.
+ ;; FIXME: We could remove the corresponding entry from that
+ ;; variable, as we assume that new diagnostics will come in soon
+ ;; via the brand new `flymake-mode' setup. For simplicity's
+ ;; sake, we have opted to leave the backend for now.
+ nil
+ ;; 2. other buffers where a backend has created "foreign"
+ ;; diagnostics and pointed them here. We must highlight them in
+ ;; this buffer, i.e. create overlays for them. Those other
+ ;; buffers and backends are still responsible for them, i.e. the
+ ;; current buffer does not "own" these foreign diags.
+ (dolist (buffer (buffer-list))
+ (with-current-buffer buffer
+ (when (and flymake-mode flymake--state)
+ (maphash (lambda (_backend state)
+ (maphash (lambda (file diags)
+ (when (or (eq file source)
+ (string= bfn (expand-file-name file)))
+ (with-current-buffer source
+ (mapc (lambda (diag)
+ (flymake--highlight-line diag
+ 'foreign))
+ diags))))
+ (flymake--state-foreign-diags state)))
+ flymake--state))))))
;; Turning the mode OFF.
(t
@@ -1035,11 +1174,16 @@ special *Flymake log* buffer." :group 'flymake :lighter
;;+(remove-hook 'find-file-hook (function flymake-find-file-hook) t)
(remove-hook 'eldoc-documentation-functions 'flymake-eldoc-function t)
- (mapc #'delete-overlay (flymake--overlays))
-
(when flymake-timer
(cancel-timer flymake-timer)
- (setq flymake-timer nil)))))
+ (setq flymake-timer nil))
+ (mapc #'delete-overlay (flymake--overlays))
+ (when flymake--state
+ (maphash (lambda (_backend state)
+ (flymake--clear-foreign-diags state))
+ flymake--state)))
+ ;; turning Flymake on or off has consequences for listings
+ (flymake--update-diagnostics-listings (current-buffer))))
(defun flymake--schedule-timer-maybe ()
"(Re)schedule an idle timer for checking the buffer.
@@ -1091,9 +1235,9 @@ START and STOP and LEN are as in `after-change-functions'."
(flymake-start t)))
(defun flymake-kill-buffer-hook ()
- (when flymake-timer
- (cancel-timer flymake-timer)
- (setq flymake-timer nil)))
+ ;; Explicitly set flymake off, because that does a lot of useful
+ ;; cleanup.
+ (flymake-mode -1))
(defun flymake-find-file-hook ()
(unless (or flymake-mode
@@ -1137,7 +1281,7 @@ default) no filter is applied."
(not filter)
(cl-find
(flymake--severity
- (flymake--diag-type diag))
+ (flymake-diagnostic-type diag))
filter :key #'flymake--severity)))))
:compare (if (cl-plusp n) #'< #'>)
:key #'overlay-start))
@@ -1187,12 +1331,12 @@ default) no filter is applied."
;;; Mode-line and menu
;;;
-(easy-menu-define flymake-menu flymake-mode-map "Flymake"
+(easy-menu-define flymake-menu flymake-mode-map "Flymake menu."
'("Flymake"
[ "Go to next problem" flymake-goto-next-error t ]
[ "Go to previous problem" flymake-goto-prev-error t ]
[ "Check now" flymake-start t ]
- [ "List all problems" flymake-show-diagnostics-buffer t ]
+ [ "List all problems" flymake-show-buffer-diagnostics t ]
"--"
[ "Go to log buffer" flymake-switch-to-log-buffer t ]
[ "Turn off Flymake" flymake-mode t ]))
@@ -1247,7 +1391,7 @@ correctly.")
help-echo
,(lambda (&rest _)
(concat
- (format "%s known backends\n" (hash-table-count flymake--backend-state))
+ (format "%s known backends\n" (hash-table-count flymake--state))
(format "%s running\n" (length (flymake-running-backends)))
(format "%s disabled\n" (length (flymake-disabled-backends)))
"mouse-1: Display minor mode menu\n"
@@ -1256,6 +1400,8 @@ correctly.")
,(let ((map (make-sparse-keymap)))
(define-key map [mode-line down-mouse-1]
flymake-menu)
+ (define-key map [mode-line down-mouse-3]
+ flymake-menu)
(define-key map [mode-line mouse-2]
(lambda ()
(interactive)
@@ -1266,7 +1412,7 @@ correctly.")
"Helper for `flymake-mode-line-exception'."
(pcase-let* ((running) (reported)
(`(,ind ,face ,explain)
- (cond ((zerop (hash-table-count flymake--backend-state))
+ (cond ((zerop (hash-table-count flymake--state))
'("?" nil "No known backends"))
((cl-set-difference
(setq running (flymake-running-backends))
@@ -1298,13 +1444,10 @@ TYPE is usually keyword `:error', `:warning' or `:note'."
(face (flymake--lookup-type-property type
'mode-line-face
'compilation-error)))
- (maphash (lambda
- (_b state)
- (dolist (d (flymake--backend-state-diags state))
- (when (= (flymake--severity type)
- (flymake--severity (flymake--diag-type d)))
- (cl-incf count))))
- flymake--backend-state)
+ (dolist (d (flymake-diagnostics))
+ (when (= (flymake--severity type)
+ (flymake--severity (flymake-diagnostic-type d)))
+ (cl-incf count)))
(when (or (cl-plusp count)
(cond ((eq flymake-suppress-zero-counters t)
nil)
@@ -1334,7 +1477,7 @@ TYPE is usually keyword `:error', `:warning' or `:note'."
(flymake-goto-next-error 1 (list type) t))))
map))))))
-;;; Diagnostics buffer
+;;; Per-buffer diagnostic listing
(defvar-local flymake--diagnostics-buffer-source nil)
@@ -1349,14 +1492,30 @@ TYPE is usually keyword `:error', `:warning' or `:note'."
(interactive (list (point) t))
(let* ((id (or (tabulated-list-get-id pos)
(user-error "Nothing at point")))
- (diag (plist-get id :diagnostic)))
- (with-current-buffer (flymake--diag-buffer diag)
+ (diag (plist-get id :diagnostic))
+ (locus (flymake--diag-locus diag))
+ (beg (flymake--diag-beg diag))
+ (end (flymake--diag-end diag))
+ (visit (lambda (b e)
+ (goto-char b)
+ (pulse-momentary-highlight-region (point)
+ (or e (line-end-position))
+ 'highlight))))
+ (with-current-buffer (cond ((bufferp locus) locus)
+ (t (find-file-noselect locus)))
(with-selected-window
(display-buffer (current-buffer) other-window)
- (goto-char (flymake--diag-beg diag))
- (pulse-momentary-highlight-region (flymake-diagnostic-beg diag)
- (flymake-diagnostic-end diag)
- 'highlight))
+ (cond (;; an annotated diagnostic (most common case), or a
+ ;; non-annotated buffer diag
+ (number-or-marker-p beg)
+ (funcall visit beg end))
+ (;; a non-annotated file diag (TODO: could use `end'
+ ;; here, too)
+ (pcase-let ((`(,bbeg . ,bend)
+ (flymake-diag-region (current-buffer)
+ (car beg)
+ (cdr beg))))
+ (funcall visit bbeg bend)))))
(current-buffer))))
(defun flymake-goto-diagnostic (pos)
@@ -1366,65 +1525,116 @@ POS can be a buffer position or a button"
(pop-to-buffer
(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'.
+PROJECT-ROOT indicates that each entry should be preceded by the
+filename of the diagnostic relative to that directory."
+ (cl-loop
+ for diag in diags
+ for locus = (flymake-diagnostic-buffer diag)
+ for file = (if (bufferp locus)
+ (buffer-file-name locus)
+ locus)
+ for overlay = (flymake--diag-overlay diag)
+ for (line . col) =
+ (cond (;; has live overlay, use overlay for position
+ (and overlay (overlay-buffer overlay))
+ (with-current-buffer (overlay-buffer overlay)
+ (save-excursion
+ (goto-char (overlay-start overlay))
+ (cons (line-number-at-pos)
+ (- (point)
+ (line-beginning-position))))))
+ (;; diagnostic not annotated, maybe foreign, check for cons
+ (consp (flymake--diag-beg diag))
+ (flymake--diag-beg diag))
+ (;; may still be a valid foreign diagnostic
+ (consp (flymake--diag-orig-beg diag))
+ (flymake--diag-orig-beg diag))
+ (;; somehow dead annotated diagnostic, ignore/give up
+ t nil))
+ for type = (flymake-diagnostic-type diag)
+ for backend = (flymake-diagnostic-backend diag)
+ for bname = (or (ignore-errors (symbol-name backend))
+ "(anonymous function)")
+ for data-vec = `[,(format "%s" line)
+ ,(format "%s" col)
+ ,(propertize (format "%s"
+ (flymake--lookup-type-property
+ type 'flymake-type-name type))
+ 'face (flymake--lookup-type-property
+ type 'mode-line-face 'flymake-error))
+ ,(propertize
+ (if bname
+ (replace-regexp-in-string "\\(.\\)[^-]+\\(-\\|$\\)"
+ "\\1\\2" bname)
+ "(anon)")
+ 'help-echo (format "From `%s' backend" backend))
+ (,(replace-regexp-in-string "\n.*" ""
+ (flymake-diagnostic-text diag))
+ mouse-face highlight
+ help-echo "mouse-2: visit this diagnostic"
+ face nil
+ action flymake-goto-diagnostic
+ mouse-action flymake-goto-diagnostic)]
+ when (and line col) collect
+ (list (list :diagnostic diag
+ :line line
+ :severity (flymake--lookup-type-property
+ type
+ 'severity (warning-numeric-level :error)))
+ (if project-root
+ (vconcat `[(,(file-name-nondirectory file)
+ help-echo ,(file-relative-name file project-root)
+ face nil
+ mouse-face highlight
+ action flymake-goto-diagnostic
+ mouse-action flymake-goto-diagnostic )]
+ data-vec)
+ data-vec))))
+
(defun flymake--diagnostics-buffer-entries ()
+ "Get tabulated list entries for current tabulated list buffer.
+Expects `flymake--diagnostics-buffer-entries' to be bound to a
+buffer."
;; Do nothing if 'flymake--diagnostics-buffer-source' has not yet
;; been set to a valid buffer. This could happen when this function
;; is called too early. For example 'global-display-line-numbers-mode'
;; calls us from its mode hook, when the diagnostic buffer has just
- ;; been created by 'flymake-show-diagnostics-buffer', but is not yet
- ;; set up properly.
+ ;; been created by 'flymake-show-buffer-diagnostics', but is not yet
+ ;; set up properly (Bug#40529).
(when (bufferp flymake--diagnostics-buffer-source)
(with-current-buffer flymake--diagnostics-buffer-source
- (cl-loop for diag in
- (cl-sort (flymake-diagnostics) #'< :key #'flymake-diagnostic-beg)
- for (line . col) =
- (save-excursion
- (goto-char (flymake--diag-beg diag))
- (cons (line-number-at-pos)
- (- (point)
- (line-beginning-position))))
- for type = (flymake--diag-type diag)
- collect
- (list (list :diagnostic diag
- :line line
- :severity (flymake--lookup-type-property
- type
- 'severity (warning-numeric-level :error)))
- `[,(format "%s" line)
- ,(format "%s" col)
- ,(propertize (format "%s"
- (flymake--lookup-type-property
- type 'flymake-type-name type))
- 'face (flymake--lookup-type-property
- type 'mode-line-face 'flymake-error))
- (,(format "%s" (flymake--diag-text diag))
- mouse-face highlight
- help-echo "mouse-2: visit this diagnostic"
- face nil
- action flymake-goto-diagnostic
- mouse-action flymake-goto-diagnostic)])))))
+ (when flymake-mode
+ (flymake--tabulated-entries-1 (flymake-diagnostics) nil)))))
+
+(defvar flymake--diagnostics-base-tabulated-list-format
+ `[("Line" 5 ,(lambda (l1 l2)
+ (< (plist-get (car l1) :line)
+ (plist-get (car l2) :line)))
+ :right-align t)
+ ("Col" 3 nil :right-align t)
+ ("Type" 8 ,(lambda (l1 l2)
+ (< (plist-get (car l1) :severity)
+ (plist-get (car l2) :severity))))
+ ("Backend" 8 t)
+ ("Message" 0 t)])
(define-derived-mode flymake-diagnostics-buffer-mode tabulated-list-mode
"Flymake diagnostics"
"A mode for listing Flymake diagnostics."
- (setq tabulated-list-format
- `[("Line" 5 ,(lambda (l1 l2)
- (< (plist-get (car l1) :line)
- (plist-get (car l2) :line)))
- :right-align t)
- ("Col" 3 nil :right-align t)
- ("Type" 8 ,(lambda (l1 l2)
- (< (plist-get (car l1) :severity)
- (plist-get (car l2) :severity))))
- ("Message" 0 t)])
+ (setq tabulated-list-format flymake--diagnostics-base-tabulated-list-format)
(setq tabulated-list-entries
'flymake--diagnostics-buffer-entries)
(tabulated-list-init-header))
(defun flymake--diagnostics-buffer-name ()
- (format "*Flymake diagnostics for %s*" (current-buffer)))
+ (format "*Flymake diagnostics for `%s'*" (current-buffer)))
-(defun flymake-show-diagnostics-buffer ()
+(define-obsolete-function-alias 'flymake-show-diagnostics-buffer
+ 'flymake-show-buffer-diagnostics "1.2.1")
+
+(defun flymake-show-buffer-diagnostics ()
"Show a list of Flymake diagnostics for current buffer."
(interactive)
(let* ((name (flymake--diagnostics-buffer-name))
@@ -1435,8 +1645,121 @@ POS can be a buffer position or a button"
(current-buffer)))))
(with-current-buffer target
(setq flymake--diagnostics-buffer-source source)
- (revert-buffer)
- (display-buffer (current-buffer)))))
+ (display-buffer (current-buffer))
+ (revert-buffer))))
+
+
+;;; Per-project diagnostic listing
+;;;
+
+(defvar flymake-list-only-diagnostics nil
+ "Diagnostics list meant for listing, not highlighting.
+This variable holds an alist ((FILE-NAME . DIAGS) ...) where
+FILE-NAME is a string holding an absolute file name and DIAGS is
+a list of diagnostic objects created with
+`flymake-make-diagnostic'. These diagnostics are never annotated
+as overlays in actual buffers: they merely serve as temporary
+stand-ins for more accurate diagnostics that are produced once
+the file they refer to is visited and `flymake-mode' is turned on
+in the resulting buffer.
+
+Flymake backends that somehow gain sporadic information about
+diagnostics in neighbouring files may freely modify this variable
+by adding or removing entries to for those files. If the
+information about those neighbouring files is acquired repeatedly
+and reliably, it may be more sensible to report them as
+\"foreign\" diagnostics instead.
+
+Commands such as `flymake-show-project-diagnostics' will include
+some of this variable's contents the diagnostic listings.")
+
+(defvar-local flymake--project-diagnostic-list-project nil)
+
+(define-derived-mode flymake-project-diagnostics-mode tabulated-list-mode
+ "Flymake diagnostics"
+ "A mode for listing Flymake diagnostics."
+ (setq tabulated-list-format
+ (vconcat [("File" 25 t)]
+ flymake--diagnostics-base-tabulated-list-format))
+ (setq tabulated-list-entries
+ 'flymake--project-diagnostics-entries)
+ (tabulated-list-init-header))
+
+(cl-defun flymake--project-diagnostics (&optional (project (project-current)))
+ "Get all known relevant diagnostics for PROJECT."
+ (let* ((root (project-root project))
+ (visited-buffers (cl-remove-if-not #'buffer-file-name (project-buffers project)))
+ buffer-annotated-diags
+ relevant-foreign-diags
+ list-only-diags
+ annotated-diag-files)
+ (setq buffer-annotated-diags
+ (cl-loop for buf in visited-buffers
+ for diags = (with-current-buffer buf
+ (flymake-diagnostics))
+ when diags do
+ (push (buffer-file-name buf) annotated-diag-files)
+ append (cl-sort diags #'< :key #'flymake-diagnostic-beg)))
+ (cl-loop
+ for buf in visited-buffers
+ do (with-current-buffer buf
+ (when (and flymake-mode flymake--state)
+ (maphash
+ (lambda (_backend state)
+ (maphash
+ (lambda (foreign-file diags)
+ (setq foreign-file (expand-file-name foreign-file))
+ ;; FIXME: This is not right if more than one visited
+ ;; source targets the same foreign file. Don't
+ ;; think we can get away without some kind of
+ ;; `cl-remove-duplicates' here that utilizes
+ ;; `flymake--equal-diagnostic-p'.
+ (unless (member foreign-file annotated-diag-files)
+ (push foreign-file annotated-diag-files)
+ (setq relevant-foreign-diags
+ (append relevant-foreign-diags
+ diags))))
+ (flymake--state-foreign-diags state)))
+ flymake--state))))
+ (setq list-only-diags
+ (cl-loop for (file-name . diags) in flymake-list-only-diagnostics
+ if (and (string-prefix-p (expand-file-name root) file-name)
+ (not (member file-name annotated-diag-files)))
+ append diags))
+ (append buffer-annotated-diags relevant-foreign-diags list-only-diags)))
+
+(defun flymake--project-diagnostics-entries ()
+ (let ((p (project-current)))
+ (flymake--tabulated-entries-1 (flymake--project-diagnostics p)
+ (project-root p))))
+
+(defun flymake--project-diagnostics-buffer (root)
+ (get-buffer-create (format "*Flymake diagnostics for `%s'*" root)))
+
+(defun flymake-show-project-diagnostics ()
+ "Show a list of Flymake diagnostics for the current project."
+ (interactive)
+ (let* ((prj (project-current))
+ (root (project-root prj))
+ (buffer (flymake--project-diagnostics-buffer root)))
+ (with-current-buffer buffer
+ (flymake-project-diagnostics-mode)
+ (setq-local flymake--project-diagnostic-list-project prj)
+ (display-buffer (current-buffer))
+ (revert-buffer))))
+
+(defun flymake--update-diagnostics-listings (buffer)
+ "Update diagnostics listings somehow relevant to BUFFER."
+ (dolist (probe (buffer-list))
+ (with-current-buffer probe
+ (when (or (and (eq major-mode 'flymake-project-diagnostics-mode)
+ flymake--project-diagnostic-list-project
+ (buffer-file-name buffer)
+ (memq buffer
+ (project-buffers flymake--project-diagnostic-list-project)))
+ (and (eq major-mode 'flymake-diagnostics-buffer-mode)
+ (eq flymake--diagnostics-buffer-source buffer)))
+ (revert-buffer)))))
(provide 'flymake)
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el
index 707226fb2a5..7cf4ce27305 100644
--- a/lisp/progmodes/fortran.el
+++ b/lisp/progmodes/fortran.el
@@ -749,7 +749,7 @@ Variables controlling indentation style and extra features:
`fortran-comment-line-extra-indent'
Amount of extra indentation for text in full-line comments (default 0).
`fortran-comment-indent-style'
- How to indent the text in full-line comments. Allowed values are:
+ How to indent the text in full-line comments. Allowed values are:
nil don't change the indentation
`fixed' indent to `fortran-comment-line-extra-indent' beyond the
value of either
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 67ad39b7f46..409ff940d96 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -5,11 +5,10 @@
;; Author: Nick Roberts <nickrob@gnu.org>
;; Maintainer: emacs-devel@gnu.org
;; Keywords: unix, tools
+;; URL: https://www.emacswiki.org/emacs/GDB-MI
;; This file is part of GNU Emacs.
-;; Homepage: https://www.emacswiki.org/emacs/GDB-MI
-
;; 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
@@ -468,8 +467,8 @@ GDB session needs to be restarted for this setting to take effect."
;; TODO Some commands can't be called with --all (give a notice about
;; it in setting doc)
(defcustom gdb-gud-control-all-threads t
- "When non-nil, GUD execution commands affect all threads when
-in non-stop mode. Otherwise, only current thread is affected."
+ "When non-nil, GUD execution commands affect all threads when in non-stop mode.
+Otherwise, only current thread is affected."
:type 'boolean
:group 'gdb-non-stop
:version "23.2")
@@ -767,7 +766,9 @@ NOARG must be t when this macro is used outside `gud-def'."
;; Apparently we're not running with -i=mi (or we're, for
;; instance, debugging something inside a Docker instance with
;; Emacs on the outside).
- (let ((msg "Error: Either -i=mi wasn't specified on the GDB command line, or the extra socket couldn't be established. Consider using `M-x gud-gdb' instead."))
+ (let ((msg (substitute-command-keys
+ "Error: Either -i=mi wasn't specified on the GDB command line,\
+ or the extra socket couldn't be established. Consider using \\[gud-gdb] instead.")))
(message msg)
(setq string (concat (propertize msg 'font-lock-face 'error)
"\n" string)))
@@ -789,7 +790,7 @@ becomes the initial working directory and source-file directory
for your debugger.
If COMMAND-LINE requests that gdb attaches to a process PID, gdb
will run in *gud-PID*, otherwise it will run in *gud*; in these
-cases the initial working directory is the default-directory of
+cases the initial working directory is the `default-directory' of
the buffer in which this command was invoked.
COMMAND-LINE should include \"-i=mi\" to use gdb's MI text interface.
@@ -1265,7 +1266,7 @@ Used by Speedbar."
:version "22.1")
(define-key gud-minor-mode-map "\C-c\C-w" 'gud-watch)
-(define-key global-map (vconcat gud-key-prefix "\C-w") 'gud-watch)
+(keymap-set gud-global-map "C-w" 'gud-watch)
(declare-function tooltip-identifier-from-point "tooltip" (point))
@@ -1484,7 +1485,7 @@ INDENT is the current indentation depth."
(expr (nth 1 var)) (children (nth 2 var)))
(if (or (<= (string-to-number children) gdb-max-children)
(y-or-n-p
- (format "%s has %s children. Continue? " expr children)))
+ (format "%s has %s children. Continue?" expr children)))
(gdb-var-list-children token))))
((string-search "-" text) ;contract this node
(dolist (var gdb-var-list)
@@ -1611,6 +1612,7 @@ this trigger is subscribed to `gdb-buf-publisher' and called with
;; Used to display windows with thread-bound buffers
(defmacro def-gdb-preempt-display-buffer (name buffer &optional doc
split-horizontal)
+ (declare (indent defun))
`(defun ,name (&optional thread)
,(when doc doc)
(message "%s" thread)
@@ -3011,6 +3013,7 @@ calling `gdb-current-context-command').
Triggers defined by this command are meant to be used as a
trigger argument when describing buffer types with
`gdb-set-buffer-rules'."
+ (declare (indent defun))
`(defun ,trigger-name (&optional signal)
(when
(or (not ,signal-list)
@@ -3031,6 +3034,7 @@ Erase current buffer and evaluate CUSTOM-DEFUN.
Then call `gdb-update-buffer-name'.
If NOPRESERVE is non-nil, window point is not restored after CUSTOM-DEFUN."
+ (declare (indent defun))
`(defun ,handler-name ()
(let* ((inhibit-read-only t)
,@(unless nopreserve
@@ -3054,6 +3058,7 @@ See `def-gdb-auto-update-trigger'.
HANDLER-NAME handler uses customization of CUSTOM-DEFUN.
See `def-gdb-auto-update-handler'."
+ (declare (indent defun))
`(progn
(def-gdb-auto-update-trigger ,trigger-name
,gdb-command
@@ -3472,6 +3477,7 @@ corresponding to the mode line clicked."
CUSTOM-DEFUN may use locally bound `thread' variable, which will
be the value of `gdb-thread' property of the current line.
If `gdb-thread' is nil, error is signaled."
+ (declare (indent defun))
`(defun ,name (&optional event)
,(when doc doc)
(interactive (list last-input-event))
@@ -3487,6 +3493,7 @@ If `gdb-thread' is nil, error is signaled."
&optional doc)
"Define a NAME which will call BUFFER-COMMAND with id of thread
on the current line."
+ (declare (indent defun))
`(def-gdb-thread-buffer-command ,name
(,buffer-command (gdb-mi--field thread 'id))
,doc))
@@ -3542,6 +3549,7 @@ on the current line."
"Define a NAME which will execute GUD-COMMAND with
`gdb-thread-number' locally bound to id of thread on the current
line."
+ (declare (indent defun))
`(def-gdb-thread-buffer-command ,name
(if gdb-non-stop
(let ((gdb-thread-number (gdb-mi--field thread 'id))
@@ -3710,6 +3718,7 @@ in `gdb-memory-format'."
(defmacro def-gdb-set-positive-number (name variable echo-string &optional doc)
"Define a function NAME which reads new VAR value from minibuffer."
+ (declare (indent defun))
`(defun ,name (event)
,(when doc doc)
(interactive "e")
@@ -3738,6 +3747,7 @@ in `gdb-memory-format'."
"Define a function NAME to switch memory buffer to use FORMAT.
DOC is an optional documentation string."
+ (declare (indent defun))
`(defun ,name () ,(when doc doc)
(interactive)
(customize-set-variable 'gdb-memory-format ,format)
@@ -3807,6 +3817,7 @@ DOC is an optional documentation string."
"Define a function NAME to switch memory unit size to UNIT-SIZE.
DOC is an optional documentation string."
+ (declare (indent defun))
`(defun ,name () ,(when doc doc)
(interactive)
(customize-set-variable 'gdb-memory-unit ,unit-size)
@@ -3831,6 +3842,7 @@ The defined function switches Memory buffer to show address
stored in ADDRESS-VAR variable.
DOC is an optional documentation string."
+ (declare (indent defun))
`(defun ,name
,(when doc doc)
(interactive)
@@ -4599,7 +4611,9 @@ overlay arrow in source buffer."
(let ((frame (gdb-mi--field (gdb-mi--partial-output) 'frame)))
(when frame
(setq gdb-selected-frame (gdb-mi--field frame 'func))
- (setq gdb-selected-file (file-local-name (gdb-mi--field frame 'fullname)))
+ (setq gdb-selected-file
+ (when-let ((full (gdb-mi--field frame 'fullname)))
+ (file-local-name full)))
(setq gdb-frame-number (gdb-mi--field frame 'level))
(setq gdb-frame-address (gdb-mi--field frame 'addr))
(let ((line (gdb-mi--field frame 'line)))
diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el
index b2a9b3e3206..70c55c01dd7 100644
--- a/lisp/progmodes/grep.el
+++ b/lisp/progmodes/grep.el
@@ -72,7 +72,7 @@ SYMBOL should be one of `grep-command', `grep-template',
Some grep programs are able to surround matches with special
markers in grep output. Such markers can be used to highlight
matches in grep mode. This requires `font-lock-mode' to be active
-in grep buffers, so if you have globally disabled font-lock-mode,
+in grep buffers, so if you have globally disabled `font-lock-mode',
you will not get highlighting.
This option sets the environment variable GREP_COLORS to specify
@@ -137,7 +137,7 @@ The following place holders should be present in the string:
<F> - file names and wildcards to search.
<X> - file names and wildcards to exclude.
<R> - the regular expression searched for.
- <N> - place to insert null-device.
+ <N> - place to insert `null-device'.
In interactive usage, the actual value of this variable is set up
by `grep-compute-defaults'; to change the default value, use
@@ -203,7 +203,7 @@ by `grep-compute-defaults'; to change the default value, use
:version "22.1")
(defcustom grep-files-aliases
- '(("all" . "* .[!.]* ..?*") ;; Don't match `..'. See bug#22577
+ '(("all" . "* .*")
("el" . "*.el")
("ch" . "*.[ch]")
("c" . "*.c")
@@ -523,7 +523,7 @@ This variable's value takes effect when `grep-compute-defaults' is called."
;;;###autoload
(defvar grep-history nil "History list for grep.")
;;;###autoload
-(defvar grep-find-history nil "History list for grep-find.")
+(defvar grep-find-history nil "History list for `grep-find'.")
;; History of lgrep and rgrep regexp and files args.
(defvar grep-regexp-history nil)
@@ -1057,11 +1057,9 @@ REGEXP is used as a string in the prompt."
default-extension
(car grep-files-history)
(car (car grep-files-aliases))))
- (files (completing-read
- (concat "Search for \"" regexp
- "\" in files matching wildcard"
- (if default (concat " (default " default ")"))
- ": ")
+ (files (completing-read
+ (format-prompt "Search for \"%s\" in files matching wildcard"
+ default regexp)
#'read-file-name-internal
nil nil nil 'grep-files-history
(delete-dups
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index 08814ebcaaa..d5bd2655174 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -31,7 +31,7 @@
;; <shane@spr.com> added support for xdb (HPUX debugger). Rick Sladkey
;; <jrs@world.std.com> wrote the GDB command completion code. Dave Love
;; <d.love@dl.ac.uk> added the IRIX kluge, re-implemented the Mips-ish variant
-;; and added a menu. Brian D. Carlstrom <bdc@ai.mit.edu> combined the IRIX
+;; and added a menu. Brian D. Carlstrom <bdc@ai.mit.edu> combined the IRIX
;; kluge with the gud-xdb-directories hack producing gud-dbx-directories.
;; Derek L. Davies <ddavies@world.std.com> added support for jdb (Java
;; debugger.) Jan Nieuwenhuizen added support for the Guile REPL (Guile
@@ -90,8 +90,10 @@ pdb (Python), and jdb."
"Prefix of all GUD commands valid in C buffers."
:type 'key-sequence)
-(global-set-key (vconcat gud-key-prefix "\C-l") #'gud-refresh)
-;; (define-key ctl-x-map " " 'gud-break); backward compatibility hack
+(defvar-keymap gud-global-map
+ "C-l" #'gud-refresh)
+
+(global-set-key gud-key-prefix gud-global-map)
(defvar gud-marker-filter nil)
(put 'gud-marker-filter 'permanent-local t)
@@ -433,7 +435,7 @@ we're in the GUD buffer)."
;; Unused lexical warning if cmd does not use "arg".
cmd))))
,(if key `(local-set-key ,(concat "\C-c" key) #',func))
- ,(if key `(global-set-key (vconcat gud-key-prefix ,key) #',func))))
+ ,(if key `(define-key gud-global-map ,key #',func))))
;; Where gud-display-frame should put the debugging arrow; a cons of
;; (filename . line-number). This is set by the marker-filter, which scans
@@ -795,7 +797,7 @@ becomes the initial working directory and source-file directory
for your debugger.
If COMMAND-LINE requests that gdb attaches to a process PID, gdb
will run in *gud-PID*, otherwise it will run in *gud*; in these
-cases the initial working directory is the default-directory of
+cases the initial working directory is the `default-directory' of
the buffer in which this command was invoked."
(interactive (list (gud-query-cmdline 'gud-gdb)))
@@ -1679,9 +1681,14 @@ into one that invokes an Emacs-enabled debugging session.
;;;###autoload
(defun perldb (command-line)
- "Run perldb on program FILE in buffer *gud-FILE*.
-The directory containing FILE becomes the initial working directory
-and source-file directory for your debugger."
+ "Debug a perl program with gud.
+Interactively, this will prompt you for a command line.
+
+Noninteractively, COMMAND-LINE should be on the form
+\"perl -d perl-file.pl\".
+
+The directory containing the perl program becomes the initial
+working directory and source-file directory for your debugger."
(interactive
(list (gud-query-cmdline 'perldb
(concat (or (buffer-file-name) "-e 0") " "))))
@@ -2672,8 +2679,8 @@ gud, see `gud-mode'."
(define-derived-mode gud-mode comint-mode "Debugger"
"Major mode for interacting with an inferior debugger process.
- You start it up with one of the commands M-x gdb, M-x sdb, M-x dbx,
-M-x perldb, M-x xdb, or M-x jdb. Each entry point finishes by executing a
+ You start it up with one of the commands \\[gdb], \\[sdb], \\[dbx],
+\\[perldb], \\[xdb], or \\[jdb]. Each entry point finishes by executing a
hook; `gdb-mode-hook', `sdb-mode-hook', `dbx-mode-hook',
`perldb-mode-hook', `xdb-mode-hook', or `jdb-mode-hook' respectively.
@@ -2775,14 +2782,24 @@ Commands:
(expand-file-name file-subst)
file-subst)))
(filepart (and file-word (concat "-" (file-name-nondirectory file))))
- (existing-buffer (get-buffer (concat "*gud" filepart "*"))))
+ (buffer-name (concat "*gud" filepart "*"))
+ (existing-buffer (get-buffer buffer-name))
+ error)
+ (when (and existing-buffer
+ (get-buffer-process existing-buffer))
+ (if (equal (buffer-local-value 'default-directory existing-buffer)
+ default-directory)
+ ;; We're already debugging this executable.
+ (setq error t)
+ ;; Open a new window to debug an executable with the same name.
+ (setq buffer-name (generate-new-buffer-name buffer-name))))
(select-window
(display-buffer
- (get-buffer-create (concat "*gud" filepart "*"))
+ (get-buffer-create buffer-name)
'((display-buffer-reuse-window
display-buffer-in-previous-window
display-buffer-same-window display-buffer-pop-up-window))))
- (when (and existing-buffer (get-buffer-process existing-buffer))
+ (when error
(error "This program is already being debugged"))
;; Set the dir, in case the buffer already existed with a different dir.
(setq default-directory dir)
@@ -2804,8 +2821,12 @@ Commands:
(setq w (cdr w)))
;; Tramp has already been loaded if we are here.
(if w (setcar w (setq file (file-local-name file)))))
- (apply #'make-comint (concat "gud" filepart) program nil
- (if massage-args (funcall massage-args file args) args))
+ (apply #'make-comint-in-buffer
+ (concat "gud" filepart) (current-buffer)
+ program nil
+ (if massage-args
+ (funcall massage-args file args)
+ args))
;; Since comint clobbered the mode, we don't set it until now.
(gud-mode)
(setq-local gud-target-name
@@ -3314,7 +3335,7 @@ This function uses the `gud-jdb-classpath' (and optional
`gud-jdb-sourcepath') list(s) to derive a file
pathname relative to its classpath directory. The values in
`gud-jdb-classpath' are assumed to have been converted to absolute
-pathname standards using file-truename.
+pathname standards using `file-truename'.
If F is visited by a buffer and its mode is CC-mode(Java),
syntactic information of LINE is used to find the enclosing (nested)
class string which is appended to the top level
@@ -3520,8 +3541,8 @@ Treats actions as defuns."
#'gdb-script-end-of-defun)
(setq-local font-lock-defaults
'(gdb-script-font-lock-keywords nil nil ((?_ . "w")) nil
- (font-lock-syntactic-face-function
- . gdb-script-font-lock-syntactic-face)))
+ (font-lock-syntactic-face-function
+ . gdb-script-font-lock-syntactic-face)))
;; Recognize docstrings.
(setq-local syntax-propertize-function
gdb-script-syntax-propertize-function)
diff --git a/lisp/progmodes/hideif.el b/lisp/progmodes/hideif.el
index 4a1da62c7e9..538ec4df804 100644
--- a/lisp/progmodes/hideif.el
+++ b/lisp/progmodes/hideif.el
@@ -181,30 +181,24 @@ Effective only if `hide-ifdef-expand-reinclusion-guard' is t."
:type 'regexp
:version "25.1")
-(defvar hide-ifdef-mode-submap
+(defvar-keymap hide-ifdef-mode-submap
+ :doc "Keymap used by `hide-ifdef-mode' under `hide-ifdef-mode-prefix-key'."
;; Set up the submap that goes after the prefix key.
- (let ((map (make-sparse-keymap)))
- (define-key map "d" 'hide-ifdef-define)
- (define-key map "u" 'hide-ifdef-undef)
- (define-key map "D" 'hide-ifdef-set-define-alist)
- (define-key map "U" 'hide-ifdef-use-define-alist)
-
- (define-key map "h" 'hide-ifdefs)
- (define-key map "s" 'show-ifdefs)
- (define-key map "\C-d" 'hide-ifdef-block)
- (define-key map "\C-s" 'show-ifdef-block)
- (define-key map "e" 'hif-evaluate-macro)
- (define-key map "C" 'hif-clear-all-ifdef-defined)
-
- (define-key map "\C-q" 'hide-ifdef-toggle-read-only)
- (define-key map "\C-w" 'hide-ifdef-toggle-shadowing)
- (substitute-key-definition
- 'read-only-mode 'hide-ifdef-toggle-outside-read-only map)
- ;; `toggle-read-only' is obsoleted by `read-only-mode'.
- (substitute-key-definition
- 'toggle-read-only 'hide-ifdef-toggle-outside-read-only map)
- map)
- "Keymap used by `hide-ifdef-mode' under `hide-ifdef-mode-prefix-key'.")
+ "d" #'hide-ifdef-define
+ "u" #'hide-ifdef-undef
+ "D" #'hide-ifdef-set-define-alist
+ "U" #'hide-ifdef-use-define-alist
+ "h" #'hide-ifdefs
+ "s" #'show-ifdefs
+ "C-d" #'hide-ifdef-block
+ "C-s" #'show-ifdef-block
+ "e" #'hif-evaluate-macro
+ "C" #'hif-clear-all-ifdef-defined
+ "C-q" #'hide-ifdef-toggle-read-only
+ "C-w" #'hide-ifdef-toggle-shadowing
+ "<remap> <read-only-mode>" #'hide-ifdef-toggle-outside-read-only
+ ;; `toggle-read-only' is obsoleted by `read-only-mode'.
+ "<remap> <toggle-read-only>" #'hide-ifdef-toggle-outside-read-only)
(defcustom hide-ifdef-mode-prefix-key "\C-c@"
"Prefix key for all Hide-Ifdef mode commands."
@@ -531,7 +525,7 @@ that form should be displayed.")
((bound-and-true-p semantic-c-takeover-hideif)
(semantic-c-hideif-defined var))
;; Here we can't use hif-lookup as an empty definition like `#define EMPTY'
- ;; is considered defined but is evaluated as `nil'.
+ ;; is considered defined but is evaluated as nil.
((assq var hide-ifdef-env) 1)
((and (setq def (assq var hif-predefine-alist))
(funcall (cdr def))) 1)
@@ -682,7 +676,7 @@ that form should be displayed.")
(defconst hif-valid-token-list (mapcar 'cdr hif-token-alist))
(defconst hif-token-regexp
- ;; The ordering of regexp grouping is crutial to `hif-strtok'
+ ;; The ordering of regexp grouping is crucial to `hif-strtok'
(concat
;; hex/binary:
"\\([+-]?0[xXbB]\\([[:xdigit:]']+\\)?\\.?\\([[:xdigit:]']+\\)?\\([pP]\\([+-]?[0-9]+\\)\\)?"
@@ -1071,7 +1065,7 @@ Assuming we've just performed a `hif-token-regexp' lookup."
(error "`defined' followed by non-identifier: %S" target))
(if (and paren
(not (eq (hif-nexttoken) 'hif-rparen)))
- (error "missing right parenthesis for `defined'"))
+ (error "Missing right parenthesis for `defined'"))
(setq hif-token
(list 'hif-defined 'hif-lparen target 'hif-rparen)))
(push hif-token tokens))
@@ -2456,7 +2450,7 @@ This allows #ifdef VAR to be hidden."
(t
nil))))
(var (read-minibuffer "Define what? " default))
- (val (read-from-minibuffer (format "Set %s to? (default 1): " var)
+ (val (read-from-minibuffer (format-prompt "Set %s to?" "1" var)
nil nil t nil "1")))
(list var val)))
(hif-set-var var (or val 1))
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
index b2557587c6c..e2ad480281f 100644
--- a/lisp/progmodes/hideshow.el
+++ b/lisp/progmodes/hideshow.el
@@ -62,7 +62,7 @@
;; activated or deactivated, `hs-minor-mode-hook' is run w/ `run-hooks'.
;;
;; Additionally, Joseph Eydelnant writes:
-;; I enjoy your package hideshow.el Ver. 5.24 2001/02/13
+;; I enjoy your package hideshow.el Version 5.24 2001/02/13
;; a lot and I've been looking for the following functionality:
;; toggle hide/show all with a single key.
;; Here are a few lines of code that lets me do just that.
diff --git a/lisp/progmodes/idlw-complete-structtag.el b/lisp/progmodes/idlw-complete-structtag.el
index 6d2d402e358..bf49c92552a 100644
--- a/lisp/progmodes/idlw-complete-structtag.el
+++ b/lisp/progmodes/idlw-complete-structtag.el
@@ -44,7 +44,7 @@
;; completion for its tags.
;;
;; This file is a completion plugin which implements this kind of
-;; completion. It is also an example which shows how completion plugins
+;; completion. It is also an example which shows how completion plugins
;; should be programmed.
;;
;; New versions of IDLWAVE, documentation, and more information available
@@ -86,6 +86,8 @@
;; - You can force an update of the tag list with the usual command
;; to update routine info in IDLWAVE: C-c C-i
+;;; Code:
+
(require 'idlwave)
(declare-function idlwave-shell-buffer "idlw-shell")
diff --git a/lisp/progmodes/idlw-help.el b/lisp/progmodes/idlw-help.el
index c53b9a4775c..df04a43d3f4 100644
--- a/lisp/progmodes/idlw-help.el
+++ b/lisp/progmodes/idlw-help.el
@@ -37,10 +37,7 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
;;; Code:
-(defvar idlwave-help-browse-url-available t
- "Whether browse-url is available.")
(require 'browse-url)
@@ -69,9 +66,6 @@ is used in preference to the old `idlwave-html-help-location'."
6.2 or later (see `idlwave-html-system-help-location')."
:type 'directory)
-(defvar idlwave-help-use-hh nil
- "Obsolete variable.")
-
(defcustom idlwave-help-use-assistant t
"Whether to use the IDL Assistant as the help browser."
:type 'boolean)
@@ -101,9 +95,6 @@ must be explicitly set non-nil in order for the variable
`idlwave-help-use-dedicated-frame' to function."
:type 'boolean)
-(defvar idlwave-help-directory ""
- "Obsolete variable. See `idlwave-html-help-location'.")
-
(defcustom idlwave-help-use-dedicated-frame t
"Non-nil means, use a separate frame for Online Help if possible."
:type 'boolean)
@@ -221,9 +212,8 @@ support."
;; Define the menu for the Help application
-(easy-menu-define
- idlwave-help-menu idlwave-help-mode-map
- "Menu for Help IDLWAVE system"
+(easy-menu-define idlwave-help-menu idlwave-help-mode-map
+ "Menu for Help IDLWAVE system."
'("IDLHelp"
["Definition <-> Help Text" idlwave-help-toggle-header-match-and-def t]
["Find DocLib Header" idlwave-help-find-header t]
@@ -332,9 +322,7 @@ Here are all keybindings.
(when (and idlwave-help-use-assistant
(not (eq (idlwave-help-assistant-available) t)))
(message "Cannot locate IDL Assistant, enabling default browser.")
- (setq idlwave-help-use-assistant nil)
- (unless idlwave-help-browse-url-available
- (error "browse-url is not available; install it or IDL Assistant to use HTML help")))))
+ (setq idlwave-help-use-assistant nil))))
(defvar idlwave-current-obj_new-class)
@@ -1354,6 +1342,15 @@ IDL assistant.")
(setq idlwave-help-assistant-socket nil
idlwave-help-assistant-process nil)))
+;;; Obsolete
+
+(defvar idlwave-help-browse-url-available t)
+(make-obsolete-variable 'idlwave-help-browse-url-available nil "28.1")
+(defvar idlwave-help-use-hh nil "Obsolete variable.")
+(make-obsolete-variable 'idlwave-help-use-hh nil "28.1")
+(defvar idlwave-help-directory ""
+ "Obsolete variable. See `idlwave-html-help-location'.")
+(make-obsolete-variable 'idlwave-help-directory nil "28.1")
(provide 'idlw-help)
(provide 'idlwave-help)
diff --git a/lisp/progmodes/idlw-shell.el b/lisp/progmodes/idlw-shell.el
index eb88f25dfd6..ded3a9c463c 100644
--- a/lisp/progmodes/idlw-shell.el
+++ b/lisp/progmodes/idlw-shell.el
@@ -105,8 +105,9 @@ process buffer."
:type 'regexp)
(defcustom idlwave-shell-process-name "idl"
- "Name to be associated with the IDL process. The buffer for the
-process output is made by surrounding this name with `*'s."
+ "Name to be associated with the IDL process.
+The buffer for the process output is made by surrounding this
+name with `*'s."
:group 'idlwave-shell-general-setup
:type 'string)
@@ -124,7 +125,7 @@ process output is made by surrounding this name with `*'s."
(defcustom idlwave-shell-frame-parameters
'((height . 30) (unsplittable . nil))
- "The frame parameters for a dedicated idlwave-shell frame.
+ "The frame parameters for a dedicated `idlwave-shell' frame.
See also `idlwave-shell-use-dedicated-frame'.
The default makes the frame splittable, so that completion works correctly."
:group 'idlwave-shell-general-setup
@@ -154,10 +155,10 @@ t Arrows force the cursor back to the current command line and
(defcustom idlwave-shell-use-toolbar t
"Non-nil means, use the debugging toolbar in all IDL related buffers.
-Starting the shell will then add the toolbar to all idlwave-mode buffers.
+Starting the shell will then add the toolbar to all `idlwave-mode' buffers.
Exiting the shell will removed everywhere.
At any time you can toggle the display of the toolbar with
-`C-c C-d C-t' (`idlwave-shell-toggle-toolbar')."
+\\[idlwave-shell-toggle-toolbar]."
:group 'idlwave-shell-general-setup
:type 'boolean)
@@ -550,7 +551,7 @@ the expression output by IDL."
;; Other variables
(defvar idlwave-shell-temp-pro-file nil
- "Absolute pathname for temporary IDL file for compiling regions")
+ "Absolute pathname for temporary IDL file for compiling regions.")
(defvar idlwave-shell-temp-rinfo-save-file nil
"Absolute pathname for temporary IDL file save file for routine_info.
@@ -590,7 +591,7 @@ the directory stack.")
"Additional info displayed in the mode line.")
(defvar idlwave-shell-default-directory nil
- "The default directory in the idlwave-shell buffer, of outside use.")
+ "The default directory in the `idlwave-shell' buffer, of outside use.")
(defvar idlwave-shell-last-save-and-action-file nil
"The last file which was compiled with `idlwave-shell-save-and-...'.")
@@ -734,9 +735,9 @@ IDL is currently stopped.")
(defconst idlwave-shell-trace-message-re
"^% At " ;; First line of a trace message
- "A regular expression matching IDL trace messages. These are the
-messages containing file and line information of a current
-traceback.")
+ "A regular expression matching IDL trace messages.
+These are the messages containing file and line information of a
+current traceback.")
(defconst idlwave-shell-step-messages
'("^% Stepped to:"
@@ -816,7 +817,7 @@ IDL has currently stepped.")
Command history, searching of previous commands, command line
editing are available via the comint-mode key bindings, by default
- mostly on the key `C-c'. Command history is also available with
+ mostly on the key \\`C-c'. Command history is also available with
the arrow keys UP and DOWN.
2. Completion
@@ -878,8 +879,8 @@ IDL has currently stepped.")
-------------------------------
Info documentation for this package is available. Use \\[idlwave-info]
to display (complain to your sysadmin if that does not work).
- For PostScript and HTML versions of the documentation, check IDLWAVE's
- homepage at URL `https://github.com/jdtsmith/idlwave'.
+ For PostScript and HTML versions of the documentation, see IDLWAVE's
+ website at URL `https://github.com/jdtsmith/idlwave'.
IDLWAVE has customize support - see the group `idlwave'.
8. Keybindings
@@ -1326,7 +1327,7 @@ See also the variable `idlwave-shell-input-mode-spells'."
Characters are sent one by one, without newlines. The loop is blocking
and intercepts all input events to Emacs. You can use this command
to interact with the IDL command GET_KBRD.
-The loop can be aborted by typing `C-g'. The loop also exits automatically
+The loop can be aborted by typing \\[keyboard-quit]. The loop also exits automatically
when the IDL prompt gets displayed again after the current IDL command."
(interactive)
@@ -1341,7 +1342,8 @@ when the IDL prompt gets displayed again after the current IDL command."
(funcall errf "No IDL program seems to be waiting for input"))
;; OK, start the loop
- (message "Character mode on: Sending single chars (`C-g' to exit)")
+ (message (substitute-command-keys
+ "Character mode on: Sending single chars (\\[keyboard-quit] to exit)"))
(message
(catch 'exit
(while t
@@ -1384,14 +1386,14 @@ Otherwise just move the line. Move down unless UP is non-nil."
(forward-line (- arg)))))
(defun idlwave-shell-up-or-history (&optional arg)
-"When in last line of process buffer, move to previous input.
- Otherwise just go up one line."
+ "When in last line of process buffer, move to previous input.
+Otherwise just go up one line."
(interactive "p")
(idlwave-shell-move-or-history t arg))
(defun idlwave-shell-down-or-history (&optional arg)
-"When in last line of process buffer, move to next input.
- Otherwise just go down one line."
+ "When in last line of process buffer, move to next input.
+Otherwise just go down one line."
(interactive "p")
(idlwave-shell-move-or-history nil arg))
@@ -1897,7 +1899,7 @@ HEAP_GC, /VERBOSE"
(cons sysdir (nreverse dirs))))
(defun idlwave-shell-routine-info-filter ()
- "Function which parses the special output from idlwave_routine_info.pro."
+ "Parse the special output from idlwave_routine_info.pro."
(let ((text idlwave-shell-command-output)
(start 0)
sep sep-re file type spec specs name cs key keys class entry)
@@ -2056,7 +2058,7 @@ Change the default directory for the process buffer to concur."
(idlwave-new-sintern-type execcomm)
(defun idlwave-shell-complete (&optional arg)
- "Do completion in the idlwave-shell buffer.
+ "Do completion in the `idlwave-shell' buffer.
Calls `idlwave-shell-complete-filename' after some executive commands or
in strings. Otherwise, calls `idlwave-complete' to complete modules and
keywords."
@@ -2136,7 +2138,7 @@ args of an executive .run, .rnew or .compile."
(and (memq (preceding-char) '(?\' ?\")) t))))
(defun idlwave-shell-batch-command ()
- "Return t if we're in a batch command statement like @foo"
+ "Return t if we're in a batch command statement like \"@foo\"."
(let ((limit (point-at-bol)))
(save-excursion
;; Skip backwards over filename
@@ -2145,7 +2147,7 @@ args of an executive .run, .rnew or .compile."
(and (eq (preceding-char) ?@) (not (idlwave-in-quote))))))
(defun idlwave-shell-shell-command ()
- "Return t if we're in a shell command statement like $ls"
+ "Return t if we're in a shell command statement like \"$ls\"."
(save-excursion
(idlwave-beginning-of-statement)
(looking-at "\\$")))
@@ -2276,7 +2278,7 @@ matter what the settings of that variable."
(if (not (idlwave-shell-valid-frame frame))
;; fixme: errors are dangerous in shell filters. but i think i
;; have never encountered this one.
- (error "invalid frame - unable to access file: %s" (car frame))
+ (error "Invalid frame - unable to access file: %s" (car frame))
;;
;; buffer : the buffer to display a line in.
;; select-shell: current buffer is the shell.
@@ -3147,14 +3149,14 @@ index - the index number of the breakpoint internal to IDL.
module - the module for breakpoint internal to IDL.
Remaining elements of the cdr:
-data - Data associated with the breakpoint by idlwave-shell currently
+data - Data associated with the breakpoint by `idlwave-shell' currently
contains four items:
count - number of times to execute breakpoint. When count reaches 0
the breakpoint is cleared and removed from the alist.
command - command to execute when breakpoint is reached, either a
- lisp function to be called with `funcall' with no arguments or a
+ Lisp function to be called with `funcall' with no arguments or a
list to be evaluated with `eval'.
condition - any condition to apply to the breakpoint.
@@ -4316,11 +4318,11 @@ Shell debugging commands are available as single key sequences."
["Toggle Toolbar" idlwave-shell-toggle-toolbar t]
["Exit IDL" idlwave-shell-quit t]))
-(easy-menu-define
- idlwave-mode-debug-menu idlwave-mode-map "IDL debugging menus"
+(easy-menu-define idlwave-mode-debug-menu idlwave-mode-map
+ "IDL debugging menus."
idlwave-shell-menu-def)
-(easy-menu-define
- idlwave-shell-mode-menu idlwave-shell-mode-map "IDL shell menus"
+(easy-menu-define idlwave-shell-mode-menu idlwave-shell-mode-map
+ "IDL shell menus."
idlwave-shell-menu-def)
;; The Breakpoint Glyph -------------------------------------------------------
diff --git a/lisp/progmodes/idlw-toolbar.el b/lisp/progmodes/idlw-toolbar.el
index d3f47fcf45e..c3ffcd18ced 100644
--- a/lisp/progmodes/idlw-toolbar.el
+++ b/lisp/progmodes/idlw-toolbar.el
@@ -355,7 +355,7 @@ static char * file[] = {
\" \",
\" \",
\" \"};")
- "The edit-cmd icon")
+ "The edit-cmd icon.")
(defvar idlwave-toolbar-run-icon
(idlwave-toolbar-make-button
diff --git a/lisp/progmodes/idlwave.el b/lisp/progmodes/idlwave.el
index 55e712dd77d..9aaabd8a0e1 100644
--- a/lisp/progmodes/idlwave.el
+++ b/lisp/progmodes/idlwave.el
@@ -119,7 +119,7 @@
;;
;; Moving the point backwards in conjunction with abbrev expansion
;; does not work as I would like it, but this is a problem with
-;; emacs abbrev expansion done by the self-insert-command. It ends
+;; Emacs abbrev expansion done by the self-insert-command. It ends
;; up inserting the character that expanded the abbrev after moving
;; point backward, e.g., "\cl" expanded with a space becomes
;; "LONG( )" with point before the close paren. This is solved by
@@ -163,7 +163,7 @@
(defgroup idlwave nil
"Major mode for editing IDL .pro files."
:tag "IDLWAVE"
- :link '(url-link :tag "Home Page"
+ :link '(url-link :tag "Website"
"https://github.com/jdtsmith/idlwave")
:link '(emacs-commentary-link :tag "Commentary in idlw-shell.el"
"idlw-shell.el")
@@ -245,7 +245,7 @@ would yield:
:type 'boolean)
(defcustom idlwave-indent-parens-nested nil
- "Non-nil means, indent continuation lines with parens by nesting
+ "Non-nil means indent continuation lines with parens by nesting
lines at consecutively deeper levels."
:group 'idlwave-code-formatting
:type 'boolean)
@@ -1359,13 +1359,13 @@ Normally a space.")
(defconst idlwave-continuation-char ?$
"Character which is inserted as a last character on previous line by
- \\[idlwave-split-line] to begin a continuation line. Normally $.")
+\\[idlwave-split-line] to begin a continuation line. Normally $.")
(defconst idlwave-mode-version "6.1_em22")
(defun idlwave-keyword-abbrev (&rest args)
"Create a function for abbrev hooks to call `idlwave-modify-abbrev' with args."
- (lambda () (append #'idlwave-modify-abbrev args)))
+ (lambda () (apply #'idlwave-modify-abbrev args)))
(autoload 'idlwave-shell "idlw-shell"
"Run an inferior IDL, with I/O through buffer `(idlwave-shell-buffer)'." t)
@@ -1522,7 +1522,8 @@ No spaces before and 1 after a comma
A minimum of 1 space before and after `=' (see `idlwave-expand-equal').
(idlwave-action-and-binding \"=\" (lambda (_) (idlwave-expand-equal -1 -1)))
Capitalize system variables - action only
- (idlwave-action-and-binding idlwave-sysvar (lambda (_) (capitalize-word 1) t))"
+ (idlwave-action-and-binding idlwave-sysvar
+ (lambda (_) (capitalize-word 1) t))"
(if (not (equal select 'noaction))
;; Add action
(let* ((table (if select 'idlwave-indent-action-table
@@ -1821,7 +1822,7 @@ The main features of this mode are
Info documentation for this package is available. Use
\\[idlwave-info] to display (complain to your sysadmin if that does
not work). For Postscript, PDF, and HTML versions of the
- documentation, check IDLWAVE's homepage at URL
+ documentation, check IDLWAVE's website at URL
`https://github.com/jdtsmith/idlwave'.
IDLWAVE has customize support - see the group `idlwave'.
@@ -1953,7 +1954,7 @@ The main features of this mode are
(defvar idlwave--command-function nil
"If non-nil, a function called from `post-command-hook'.
-It is evaluated in the lisp function `idlwave-command-hook' which is
+It is evaluated in the Lisp function `idlwave-command-hook' which is
placed in `post-command-hook'.")
(defun idlwave-command-hook ()
@@ -4067,7 +4068,7 @@ blank lines."
iname))
(defun idlwave-sintern-keyword-list (kwd-list &optional set)
- "Sintern a set of keywords (file (key . link) (key2 . link2) ...)"
+ "Sintern a set of keywords (file (key . link) (key2 . link2) ...)."
(mapc (lambda(x)
(setcar x (idlwave-sintern-keyword (car x) set)))
(cdr kwd-list))
@@ -5049,7 +5050,7 @@ Can run from `after-save-hook'."
;;----- Scanning buffers -------------------
(defun idlwave-get-routine-info-from-buffers (buffers)
- "Call `idlwave-get-buffer-routine-info' on idlwave-mode buffers in BUFFERS."
+ "Call `idlwave-get-buffer-routine-info' on `idlwave-mode' buffers in BUFFERS."
(let (buf routine-lists res)
(save-excursion
(while (setq buf (pop buffers))
@@ -5316,7 +5317,7 @@ directories and save the routine info.
(defun idlwave-delete-user-catalog-file (&rest _ignore)
(if (yes-or-no-p
- (format "Delete file %s " idlwave-user-catalog-file))
+ (format "Delete file %s?" idlwave-user-catalog-file))
(progn
(delete-file idlwave-user-catalog-file)
(message "%s has been deleted" idlwave-user-catalog-file))))
@@ -5727,10 +5728,10 @@ Possible values are:
8 <=> `function-method-keyword'
9 <=> `class'
-As a special case, the universal argument C-u forces completion of
+As a special case, the universal argument \\[universal-argument] forces completion of
function names in places where the default would be a keyword.
-Two prefix argument, C-u C-u, prompts for a regexp by which to limit
+Two prefix argument, \\[universal-argument] \\[universal-argument], prompts for a regexp by which to limit
completion.
For Lisp programmers only:
@@ -7285,8 +7286,7 @@ The list is cached in `idlwave-class-info' for faster access."
inherits))
(if (> (cdr cl) 999)
(error
- "Class scan: inheritance depth exceeded. Circular inheritance?")
- ))
+ "Class scan: inheritance depth exceeded. Circular inheritance?")))
(setq all-inherits (nreverse rtn))
(nconc info (list (cons 'all-inherits all-inherits)))
all-inherits))))))
@@ -7786,7 +7786,7 @@ force class query for object methods."
(if (or (not this-buffer)
(assoc default list))
(format-prompt "Module" default)
- (format "Module in this file: "))
+ "Module in this file: ")
list))
type class)
(if (string-match "\\`\\s-*\\'" name)
@@ -8971,10 +8971,10 @@ Assumes that point is at the beginning of the unit as found by
idlwave-shell-automatic-start)]))
(easy-menu-define idlwave-mode-menu idlwave-mode-map
- "IDL and WAVE CL editing menu"
+ "IDL and WAVE CL editing menu."
idlwave-mode-menu-def)
(easy-menu-define idlwave-mode-debug-menu idlwave-mode-map
- "IDL and WAVE CL editing menu"
+ "IDL and WAVE CL editing menu."
idlwave-mode-debug-menu-def)
(defun idlwave-customize ()
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index c2481f6095a..9303f1ecb91 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -24,16 +24,16 @@
;; 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
+;;; Commentary:
-;; This is based on Karl Landstrom's barebones javascript-mode. This
+;; This is based on Karl Landstrom's barebones javascript-mode. This
;; is much more robust and works with cc-mode's comment filling
;; (mostly).
;;
;; The main features of this JavaScript mode are syntactic
;; highlighting (enabled with `font-lock-mode' or
;; `global-font-lock-mode'), automatic indentation and filling of
-;; comments, C preprocessor fontification, and MozRepl integration.
+;; comments, and C preprocessor fontification.
;;
;; General Remarks:
;;
@@ -51,7 +51,6 @@
(require 'cc-fonts))
(require 'newcomment)
(require 'imenu)
-(require 'moz nil t)
(require 'json)
(require 'prog-mode)
@@ -59,12 +58,9 @@
(require 'cl-lib)
(require 'ido))
-(defvar inferior-moz-buffer)
-(defvar moz-repl-name)
(defvar ido-cur-list)
(defvar electric-layout-rules)
(declare-function ido-mode "ido" (&optional arg))
-(declare-function inferior-moz-process "ext:mozrepl" ())
;;; Constants
@@ -95,7 +91,7 @@ name.")
(defconst js--plain-method-re
(concat "^\\s-*?\\(" js--dotted-name-re "\\)\\.prototype"
- "\\.\\(" js--name-re "\\)\\s-*?=\\s-*?\\(function\\)\\_>")
+ "\\.\\(" js--name-re "\\)\\s-*?=\\s-*?\\(\\(:?async[ \t\n]+\\)function\\)\\_>")
"Regexp matching an explicit JavaScript prototype \"method\" declaration.
Group 1 is a (possibly-dotted) class name, group 2 is a method name,
and group 3 is the `function' keyword.")
@@ -237,8 +233,7 @@ will create multiple top-level entries. Don't use :prototype
unnecessarily: it has an associated cost in performance.
If :strip-prototype is present and non-nil, then if the class
-name as matched contains
-")
+name as matched contains.")
(defconst js--available-frameworks
(cl-loop for style in js--class-styles
@@ -486,25 +481,22 @@ seldom use, either globally or on a per-buffer basis."
(list 'const x))
js--available-frameworks)))
-(defcustom js-js-switch-tabs
- (and (memq system-type '(darwin)) t)
+(defvar js-js-switch-tabs (and (memq system-type '(darwin)) t)
"Whether `js-mode' should display tabs while selecting them.
This is useful only if the windowing system has a good mechanism
-for preventing Firefox from stealing the keyboard focus."
- :type 'boolean)
+for preventing Firefox from stealing the keyboard focus.")
+(make-obsolete-variable 'js-js-switch-tabs "MozRepl no longer exists" "28.1")
-(defcustom js-js-tmpdir
- (locate-user-emacs-file "js/js")
+(defvar js-js-tmpdir (locate-user-emacs-file "js/js")
"Temporary directory used by `js-mode' to communicate with Mozilla.
-This directory must be readable and writable by both Mozilla and Emacs."
- :type 'directory
- :version "28.1")
+This directory must be readable and writable by both Mozilla and Emacs.")
+(make-obsolete-variable 'js-js-tmpdir "MozRepl no longer exists" "28.1")
-(defcustom js-js-timeout 5
+(defvar js-js-timeout 5
"Reply timeout for executing commands in Mozilla via `js-mode'.
The value is given in seconds. Increase this value if you are
-getting timeout messages."
- :type 'integer)
+getting timeout messages.")
+(make-obsolete-variable 'js-js-timeout "MozRepl no longer exists" "28.1")
(defcustom js-indent-first-init nil
"Non-nil means specially indent the first variable declaration's initializer.
@@ -554,8 +546,7 @@ If the previous expression also contains a \".\" at the same level,
then the \".\"s will be lined up:
let x = svg.mumble()
- .chained;
-"
+ .chained;"
:version "26.1"
:type 'boolean
:safe 'booleanp)
@@ -574,8 +565,8 @@ to `js-jsx-regexps', which see."
This enables proper font-locking and indentation of code using
Facebook’s “JSX” syntax extension for JavaScript, for use with
-Facebook’s “React” library. Font-locking is like sgml-mode.
-Indentation is also like sgml-mode, although some indentation
+Facebook’s “React” library. Font-locking is like `sgml-mode'.
+Indentation is also like `sgml-mode', although some indentation
behavior may differ slightly to align more closely with the
conventions of the React developer community.
@@ -673,18 +664,7 @@ This variable is like `sgml-attribute-offset'."
(defvar js-mode-map
(let ((keymap (make-sparse-keymap)))
- (define-key keymap [(control ?c) (meta ?:)] #'js-eval)
- (define-key keymap [(control ?c) (control ?j)] #'js-set-js-context)
- (define-key keymap [(control meta ?x)] #'js-eval-defun)
(define-key keymap [(meta ?.)] #'js-find-symbol)
- (easy-menu-define nil keymap "JavaScript Menu"
- '("JavaScript"
- ["Select New Mozilla Context..." js-set-js-context
- (fboundp #'inferior-moz-process)]
- ["Evaluate Expression in Mozilla Context..." js-eval
- (fboundp #'inferior-moz-process)]
- ["Send Current Function to Mozilla..." js-eval-defun
- (fboundp #'inferior-moz-process)]))
keymap)
"Keymap for `js-mode'.")
@@ -934,9 +914,10 @@ This puts point at the `function' keyword.
If this is a syntactically-correct non-expression function,
return the name of the function, or t if the name could not be
determined. Otherwise, return nil."
- (cl-assert (looking-at "\\_<function\\_>"))
+ (unless (looking-at "\\(\\_<async\\_>[ \t\n]+\\)?\\_<function\\_>")
+ (error "Invalid position"))
(let ((name t))
- (forward-word-strictly)
+ (goto-char (match-end 0))
(forward-comment most-positive-fixnum)
(when (eq (char-after) ?*)
(forward-char)
@@ -972,14 +953,17 @@ If POS is not in a function prologue, return nil."
(goto-char (match-end 0))))
(skip-syntax-backward "w_")
- (and (or (looking-at "\\_<function\\_>")
- (js--re-search-backward "\\_<function\\_>" nil t))
-
- (save-match-data (goto-char (match-beginning 0))
- (js--forward-function-decl))
-
- (<= pos (point))
- (or prologue-begin (match-beginning 0))))))
+ (let ((start nil))
+ (and (or (looking-at "\\_<function\\_>")
+ (js--re-search-backward "\\_<function\\_>" nil t))
+ (progn
+ (setq start (match-beginning 0))
+ (goto-char start)
+ (when (looking-back "\\_<async\\_>[ \t\n]+" (- (point) 30))
+ (setq start (match-beginning 0)))
+ (js--forward-function-decl))
+ (<= pos (point))
+ (or prologue-begin start))))))
(defun js--beginning-of-defun-raw ()
"Helper function for `js-beginning-of-defun'.
@@ -1249,7 +1233,6 @@ LIMIT defaults to point."
;; Regular function declaration
((and (looking-at "\\_<function\\_>")
(setq name (js--forward-function-decl)))
-
(when (eq name t)
(setq name (js--guess-function-name orig-match-end))
(if name
@@ -1261,6 +1244,11 @@ LIMIT defaults to point."
(cl-assert (eq (char-after) ?{))
(forward-char)
+ (save-excursion
+ (goto-char orig-match-start)
+ (when (looking-back "\\_<async\\_>[ \t\n]+"
+ (- (point) 30))
+ (setq orig-match-start (match-beginning 0))))
(make-js--pitem
:paren-depth orig-depth
:h-begin orig-match-start
@@ -3267,7 +3255,7 @@ the broken-down class name of the item to insert."
(defun js--get-all-known-symbols ()
"Return a hash table of all JavaScript symbols.
-This searches all existing `js-mode' buffers. Each key is the
+This searches all existing `js-mode' buffers. Each key is the
name of a symbol (possibly disambiguated with <N>, where N > 1),
and each value is a marker giving the location of that symbol."
(cl-loop with symbols = (make-hash-table :test 'equal)
@@ -3310,10 +3298,7 @@ marker."
(setf (car bounds) (point))))
(buffer-substring (car bounds) (cdr bounds)))))
-(defvar find-tag-marker-ring) ; etags
-
-;; etags loads ring.
-(declare-function ring-insert "ring" (ring item))
+(declare-function xref-push-marker-stack "xref" (&optional m))
(defun js-find-symbol (&optional arg)
"Read a JavaScript symbol and jump to it.
@@ -3321,7 +3306,7 @@ With a prefix argument, restrict symbols to those from the
current buffer. Pushes a mark onto the tag ring just like
`find-tag'."
(interactive "P")
- (require 'etags)
+ (require 'xref)
(let (symbols marker)
(if (not arg)
(setq symbols (js--get-all-known-symbols))
@@ -3333,1111 +3318,11 @@ current buffer. Pushes a mark onto the tag ring just like
symbols "Jump to: "
(js--guess-symbol-at-point))))
- (ring-insert find-tag-marker-ring (point-marker))
+ (xref-push-marker-stack)
(switch-to-buffer (marker-buffer marker))
(push-mark)
(goto-char marker)))
-;;; MozRepl integration
-
-(define-error 'js-moz-bad-rpc "Mozilla RPC Error") ;; '(timeout error))
-(define-error 'js-js-error "JavaScript Error") ;; '(js-error error))
-
-(defun js--wait-for-matching-output
- (process regexp timeout &optional start)
- "Wait TIMEOUT seconds for PROCESS to output a match for REGEXP.
-On timeout, return nil. On success, return t with match data
-set. If START is non-nil, look for output starting from START.
-Otherwise, use the current value of `process-mark'."
- (with-current-buffer (process-buffer process)
- (cl-loop with start-pos = (or start
- (marker-position (process-mark process)))
- with end-time = (time-add nil timeout)
- for time-left = (float-time (time-subtract end-time nil))
- do (goto-char (point-max))
- if (looking-back regexp start-pos) return t
- while (> time-left 0)
- do (accept-process-output process time-left nil t)
- do (goto-char (process-mark process))
- finally do (signal
- 'js-moz-bad-rpc
- (list (format "Timed out waiting for output matching %S" regexp))))))
-
-(cl-defstruct js--js-handle
- ;; Integer, mirrors the value we see in JS
- (id nil :read-only t)
-
- ;; Process to which this thing belongs
- (process nil :read-only t))
-
-(defun js--js-handle-expired-p (x)
- (not (eq (js--js-handle-process x)
- (inferior-moz-process))))
-
-(defvar js--js-references nil
- "Maps Elisp JavaScript proxy objects to their JavaScript IDs.")
-
-(defvar js--js-process nil
- "The most recent MozRepl process object.")
-
-(defvar js--js-gc-idle-timer nil
- "Idle timer for cleaning up JS object references.")
-
-(defvar js--js-last-gcs-done nil)
-
-(defconst js--moz-interactor
- (replace-regexp-in-string
- "[ \n]+" " "
- ; */" Make Emacs happy
-"(function(repl) {
- repl.defineInteractor('js', {
- onStart: function onStart(repl) {
- if(!repl._jsObjects) {
- repl._jsObjects = {};
- repl._jsLastID = 0;
- repl._jsGC = this._jsGC;
- }
- this._input = '';
- },
-
- _jsGC: function _jsGC(ids_in_use) {
- var objects = this._jsObjects;
- var keys = [];
- var num_freed = 0;
-
- for(var pn in objects) {
- keys.push(Number(pn));
- }
-
- keys.sort(function(x, y) x - y);
- ids_in_use.sort(function(x, y) x - y);
- var i = 0;
- var j = 0;
-
- while(i < ids_in_use.length && j < keys.length) {
- var id = ids_in_use[i++];
- while(j < keys.length && keys[j] !== id) {
- var k_id = keys[j++];
- delete objects[k_id];
- ++num_freed;
- }
- ++j;
- }
-
- while(j < keys.length) {
- var k_id = keys[j++];
- delete objects[k_id];
- ++num_freed;
- }
-
- return num_freed;
- },
-
- _mkArray: function _mkArray() {
- var result = [];
- for(var i = 0; i < arguments.length; ++i) {
- result.push(arguments[i]);
- }
- return result;
- },
-
- _parsePropDescriptor: function _parsePropDescriptor(parts) {
- if(typeof parts === 'string') {
- parts = [ parts ];
- }
-
- var obj = parts[0];
- var start = 1;
-
- if(typeof obj === 'string') {
- obj = window;
- start = 0;
- } else if(parts.length < 2) {
- throw new Error('expected at least 2 arguments');
- }
-
- for(var i = start; i < parts.length - 1; ++i) {
- obj = obj[parts[i]];
- }
-
- return [obj, parts[parts.length - 1]];
- },
-
- _getProp: function _getProp(/*...*/) {
- if(arguments.length === 0) {
- throw new Error('no arguments supplied to getprop');
- }
-
- if(arguments.length === 1 &&
- (typeof arguments[0]) !== 'string')
- {
- return arguments[0];
- }
-
- var [obj, propname] = this._parsePropDescriptor(arguments);
- return obj[propname];
- },
-
- _putProp: function _putProp(properties, value) {
- var [obj, propname] = this._parsePropDescriptor(properties);
- obj[propname] = value;
- },
-
- _delProp: function _delProp(propname) {
- var [obj, propname] = this._parsePropDescriptor(arguments);
- delete obj[propname];
- },
-
- _typeOf: function _typeOf(thing) {
- return typeof thing;
- },
-
- _callNew: function(constructor) {
- if(typeof constructor === 'string')
- {
- constructor = window[constructor];
- } else if(constructor.length === 1 &&
- typeof constructor[0] !== 'string')
- {
- constructor = constructor[0];
- } else {
- var [obj,propname] = this._parsePropDescriptor(constructor);
- constructor = obj[propname];
- }
-
- /* Hacky, but should be robust */
- var s = 'new constructor(';
- for(var i = 1; i < arguments.length; ++i) {
- if(i != 1) {
- s += ',';
- }
-
- s += 'arguments[' + i + ']';
- }
-
- s += ')';
- return eval(s);
- },
-
- _callEval: function(thisobj, js) {
- return eval.call(thisobj, js);
- },
-
- getPrompt: function getPrompt(repl) {
- return 'EVAL>'
- },
-
- _lookupObject: function _lookupObject(repl, id) {
- if(typeof id === 'string') {
- switch(id) {
- case 'global':
- return window;
- case 'nil':
- return null;
- case 't':
- return true;
- case 'false':
- return false;
- case 'undefined':
- return undefined;
- case 'repl':
- return repl;
- case 'interactor':
- return this;
- case 'NaN':
- return NaN;
- case 'Infinity':
- return Infinity;
- case '-Infinity':
- return -Infinity;
- default:
- throw new Error('No object with special id:' + id);
- }
- }
-
- var ret = repl._jsObjects[id];
- if(ret === undefined) {
- throw new Error('No object with id:' + id + '(' + typeof id + ')');
- }
- return ret;
- },
-
- _findOrAllocateObject: function _findOrAllocateObject(repl, value) {
- if(typeof value !== 'object' && typeof value !== 'function') {
- throw new Error('_findOrAllocateObject called on non-object('
- + typeof(value) + '): '
- + value)
- }
-
- for(var id in repl._jsObjects) {
- id = Number(id);
- var obj = repl._jsObjects[id];
- if(obj === value) {
- return id;
- }
- }
-
- var id = ++repl._jsLastID;
- repl._jsObjects[id] = value;
- return id;
- },
-
- _fixupList: function _fixupList(repl, list) {
- for(var i = 0; i < list.length; ++i) {
- if(list[i] instanceof Array) {
- this._fixupList(repl, list[i]);
- } else if(typeof list[i] === 'object') {
- var obj = list[i];
- if(obj.funcall) {
- var parts = obj.funcall;
- this._fixupList(repl, parts);
- var [thisobj, func] = this._parseFunc(parts[0]);
- list[i] = func.apply(thisobj, parts.slice(1));
- } else if(obj.objid) {
- list[i] = this._lookupObject(repl, obj.objid);
- } else {
- throw new Error('Unknown object type: ' + obj.toSource());
- }
- }
- }
- },
-
- _parseFunc: function(func) {
- var thisobj = null;
-
- if(typeof func === 'string') {
- func = window[func];
- } else if(func instanceof Array) {
- if(func.length === 1 && typeof func[0] !== 'string') {
- func = func[0];
- } else {
- [thisobj, func] = this._parsePropDescriptor(func);
- func = thisobj[func];
- }
- }
-
- return [thisobj,func];
- },
-
- _encodeReturn: function(value, array_as_mv) {
- var ret;
-
- if(value === null) {
- ret = ['special', 'null'];
- } else if(value === true) {
- ret = ['special', 'true'];
- } else if(value === false) {
- ret = ['special', 'false'];
- } else if(value === undefined) {
- ret = ['special', 'undefined'];
- } else if(typeof value === 'number') {
- if(isNaN(value)) {
- ret = ['special', 'NaN'];
- } else if(value === Infinity) {
- ret = ['special', 'Infinity'];
- } else if(value === -Infinity) {
- ret = ['special', '-Infinity'];
- } else {
- ret = ['atom', value];
- }
- } else if(typeof value === 'string') {
- ret = ['atom', value];
- } else if(array_as_mv && value instanceof Array) {
- ret = ['array', value.map(this._encodeReturn, this)];
- } else {
- ret = ['objid', this._findOrAllocateObject(repl, value)];
- }
-
- return ret;
- },
-
- _handleInputLine: function _handleInputLine(repl, line) {
- var ret;
- var array_as_mv = false;
-
- try {
- if(line[0] === '*') {
- array_as_mv = true;
- line = line.substring(1);
- }
- var parts = eval(line);
- this._fixupList(repl, parts);
- var [thisobj, func] = this._parseFunc(parts[0]);
- ret = this._encodeReturn(
- func.apply(thisobj, parts.slice(1)),
- array_as_mv);
- } catch(x) {
- ret = ['error', x.toString() ];
- }
-
- var JSON = Components.classes['@mozilla.org/dom/json;1'].createInstance(Components.interfaces.nsIJSON);
- repl.print(JSON.encode(ret));
- repl._prompt();
- },
-
- handleInput: function handleInput(repl, chunk) {
- this._input += chunk;
- var match, line;
- while(match = this._input.match(/.*\\n/)) {
- line = match[0];
-
- if(line === 'EXIT\\n') {
- repl.popInteractor();
- repl._prompt();
- return;
- }
-
- this._input = this._input.substring(line.length);
- this._handleInputLine(repl, line);
- }
- }
- });
-})
-")
-
- "String to set MozRepl up into a simple-minded evaluation mode.")
-
-(defun js--js-encode-value (x)
- "Marshall the given value for JS.
-Strings and numbers are JSON-encoded. Lists (including nil) are
-made into JavaScript array literals and their contents encoded
-with `js--js-encode-value'."
- (cond ((or (stringp x) (numberp x)) (json-encode x))
- ((symbolp x) (format "{objid:%S}" (symbol-name x)))
- ((js--js-handle-p x)
-
- (when (js--js-handle-expired-p x)
- (error "Stale JS handle"))
-
- (format "{objid:%s}" (js--js-handle-id x)))
-
- ((sequencep x)
- (if (eq (car-safe x) 'js--funcall)
- (format "{funcall:[%s]}"
- (mapconcat #'js--js-encode-value (cdr x) ","))
- (concat
- "[" (mapconcat #'js--js-encode-value x ",") "]")))
- (t
- (error "Unrecognized item: %S" x))))
-
-(defconst js--js-prompt-regexp "\\(repl[0-9]*\\)> $")
-(defconst js--js-repl-prompt-regexp "^EVAL>$")
-(defvar js--js-repl-depth 0)
-
-(defun js--js-wait-for-eval-prompt ()
- (js--wait-for-matching-output
- (inferior-moz-process)
- js--js-repl-prompt-regexp js-js-timeout
-
- ;; start matching against the beginning of the line in
- ;; order to catch a prompt that's only partially arrived
- (save-excursion (forward-line 0) (point))))
-
-;; Presumably "inferior-moz-process" loads comint.
-(declare-function comint-send-string "comint" (process string))
-(declare-function comint-send-input "comint"
- (&optional no-newline artificial))
-
-(defun js--js-enter-repl ()
- (inferior-moz-process) ; called for side-effect
- (with-current-buffer inferior-moz-buffer
- (goto-char (point-max))
-
- ;; Do some initialization the first time we see a process
- (unless (eq (inferior-moz-process) js--js-process)
- (setq js--js-process (inferior-moz-process))
- (setq js--js-references (make-hash-table :test 'eq :weakness t))
- (setq js--js-repl-depth 0)
-
- ;; Send interactor definition
- (comint-send-string js--js-process js--moz-interactor)
- (comint-send-string js--js-process
- (concat "(" moz-repl-name ")\n"))
- (js--wait-for-matching-output
- (inferior-moz-process) js--js-prompt-regexp
- js-js-timeout))
-
- ;; Sanity check
- (when (looking-back js--js-prompt-regexp
- (save-excursion (forward-line 0) (point)))
- (setq js--js-repl-depth 0))
-
- (if (> js--js-repl-depth 0)
- ;; If js--js-repl-depth > 0, we *should* be seeing an
- ;; EVAL> prompt. If we don't, give Mozilla a chance to catch
- ;; up with us.
- (js--js-wait-for-eval-prompt)
-
- ;; Otherwise, tell Mozilla to enter the interactor mode
- (insert (match-string-no-properties 1)
- ".pushInteractor('js')")
- (comint-send-input nil t)
- (js--wait-for-matching-output
- (inferior-moz-process) js--js-repl-prompt-regexp
- js-js-timeout))
-
- (cl-incf js--js-repl-depth)))
-
-(defun js--js-leave-repl ()
- (cl-assert (> js--js-repl-depth 0))
- (when (= 0 (cl-decf js--js-repl-depth))
- (with-current-buffer inferior-moz-buffer
- (goto-char (point-max))
- (js--js-wait-for-eval-prompt)
- (insert "EXIT")
- (comint-send-input nil t)
- (js--wait-for-matching-output
- (inferior-moz-process) js--js-prompt-regexp
- js-js-timeout))))
-
-(defsubst js--js-not (value)
- (memq value '(nil null false undefined)))
-
-(defsubst js--js-true (value)
- (not (js--js-not value)))
-
-(eval-and-compile
- (defun js--optimize-arglist (arglist)
- "Convert immediate js< and js! references to deferred ones."
- (cl-loop for item in arglist
- if (eq (car-safe item) 'js<)
- collect (append (list 'list ''js--funcall
- '(list 'interactor "_getProp"))
- (js--optimize-arglist (cdr item)))
- else if (eq (car-safe item) 'js>)
- collect (append (list 'list ''js--funcall
- '(list 'interactor "_putProp"))
-
- (if (atom (cadr item))
- (list (cadr item))
- (list
- (append
- (list 'list ''js--funcall
- '(list 'interactor "_mkArray"))
- (js--optimize-arglist (cadr item)))))
- (js--optimize-arglist (cddr item)))
- else if (eq (car-safe item) 'js!)
- collect (pcase-let ((`(,_ ,function . ,body) item))
- (append (list 'list ''js--funcall
- (if (consp function)
- (cons 'list
- (js--optimize-arglist function))
- function))
- (js--optimize-arglist body)))
- else
- collect item)))
-
-(defmacro js--js-get-service (class-name interface-name)
- `(js! ("Components" "classes" ,class-name "getService")
- (js< "Components" "interfaces" ,interface-name)))
-
-(defmacro js--js-create-instance (class-name interface-name)
- `(js! ("Components" "classes" ,class-name "createInstance")
- (js< "Components" "interfaces" ,interface-name)))
-
-(defmacro js--js-qi (object interface-name)
- `(js! (,object "QueryInterface")
- (js< "Components" "interfaces" ,interface-name)))
-
-(defmacro with-js (&rest forms)
- "Run FORMS with the Mozilla repl set up for js commands.
-Inside the lexical scope of `with-js', `js?', `js!',
-`js-new', `js-eval', `js-list', `js<', `js>', `js-get-service',
-`js-create-instance', and `js-qi' are defined."
- (declare (indent 0) (debug t))
- `(progn
- (js--js-enter-repl)
- (unwind-protect
- (cl-macrolet ((js? (&rest body) `(js--js-true ,@body))
- (js! (function &rest body)
- `(js--js-funcall
- ,(if (consp function)
- (cons 'list
- (js--optimize-arglist function))
- function)
- ,@(js--optimize-arglist body)))
-
- (js-new (function &rest body)
- `(js--js-new
- ,(if (consp function)
- (cons 'list
- (js--optimize-arglist function))
- function)
- ,@body))
-
- (js-eval (thisobj js)
- `(js--js-eval
- ,@(js--optimize-arglist
- (list thisobj js))))
-
- (js-list (&rest args)
- `(js--js-list
- ,@(js--optimize-arglist args)))
-
- (js-get-service (&rest args)
- `(js--js-get-service
- ,@(js--optimize-arglist args)))
-
- (js-create-instance (&rest args)
- `(js--js-create-instance
- ,@(js--optimize-arglist args)))
-
- (js-qi (&rest args)
- `(js--js-qi
- ,@(js--optimize-arglist args)))
-
- (js< (&rest body) `(js--js-get
- ,@(js--optimize-arglist body)))
- (js> (props value)
- `(js--js-funcall
- '(interactor "_putProp")
- ,(if (consp props)
- (cons 'list
- (js--optimize-arglist props))
- props)
- ,@(js--optimize-arglist (list value))
- ))
- (js-handle? (arg) `(js--js-handle-p ,arg)))
- ,@forms)
- (js--js-leave-repl))))
-
-(defvar js--js-array-as-list nil
- "Whether to listify any Array returned by a Mozilla function.
-If nil, the whole Array is treated as a JS symbol.")
-
-(defun js--js-decode-retval (result)
- (pcase (intern (cl-first result))
- ('atom (cl-second result))
- ('special (intern (cl-second result)))
- ('array
- (mapcar #'js--js-decode-retval (cl-second result)))
- ('objid
- (or (gethash (cl-second result)
- js--js-references)
- (puthash (cl-second result)
- (make-js--js-handle
- :id (cl-second result)
- :process (inferior-moz-process))
- js--js-references)))
-
- ('error (signal 'js-js-error (list (cl-second result))))
- (x (error "Unmatched case in js--js-decode-retval: %S" x))))
-
-(defvar comint-last-input-end)
-
-(defun js--js-funcall (function &rest arguments)
- "Call the Mozilla function FUNCTION with arguments ARGUMENTS.
-If function is a string, look it up as a property on the global
-object and use the global object for `this'.
-If FUNCTION is a list with one element, use that element as the
-function with the global object for `this', except that if that
-single element is a string, look it up on the global object.
-If FUNCTION is a list with more than one argument, use the list
-up to the last value as a property descriptor and the last
-argument as a function."
-
- (with-js
- (let ((argstr (js--js-encode-value
- (cons function arguments))))
-
- (with-current-buffer inferior-moz-buffer
- ;; Actual funcall
- (when js--js-array-as-list
- (insert "*"))
- (insert argstr)
- (comint-send-input nil t)
- (js--wait-for-matching-output
- (inferior-moz-process) "EVAL>"
- js-js-timeout)
- (goto-char comint-last-input-end)
-
- ;; Read the result
- (let* ((json-array-type 'list)
- (result (prog1 (json-read)
- (goto-char (point-max)))))
- (js--js-decode-retval result))))))
-
-(defun js--js-new (constructor &rest arguments)
- "Call CONSTRUCTOR as a constructor, with arguments ARGUMENTS.
-CONSTRUCTOR is a JS handle, a string, or a list of these things."
- (apply #'js--js-funcall
- '(interactor "_callNew")
- constructor arguments))
-
-(defun js--js-eval (thisobj js)
- (js--js-funcall '(interactor "_callEval") thisobj js))
-
-(defun js--js-list (&rest arguments)
- "Return a Lisp array resulting from evaluating each of ARGUMENTS."
- (let ((js--js-array-as-list t))
- (apply #'js--js-funcall '(interactor "_mkArray")
- arguments)))
-
-(defun js--js-get (&rest props)
- (apply #'js--js-funcall '(interactor "_getProp") props))
-
-(defun js--js-put (props value)
- (js--js-funcall '(interactor "_putProp") props value))
-
-(defun js-gc (&optional force)
- "Tell the repl about any objects we don't reference anymore.
-With argument, run even if no intervening GC has happened."
- (interactive)
-
- (when force
- (setq js--js-last-gcs-done nil))
-
- (let ((this-gcs-done gcs-done) keys num)
- (when (and js--js-references
- (boundp 'inferior-moz-buffer)
- (buffer-live-p inferior-moz-buffer)
-
- ;; Don't bother running unless we've had an intervening
- ;; garbage collection; without a gc, nothing is deleted
- ;; from the weak hash table, so it's pointless telling
- ;; MozRepl about that references we still hold
- (not (eq js--js-last-gcs-done this-gcs-done))
-
- ;; Are we looking at a normal prompt? Make sure not to
- ;; interrupt the user if he's doing something
- (with-current-buffer inferior-moz-buffer
- (save-excursion
- (goto-char (point-max))
- (looking-back js--js-prompt-regexp
- (save-excursion (forward-line 0) (point))))))
-
- (setq keys (cl-loop for x being the hash-keys
- of js--js-references
- collect x))
- (setq num (js--js-funcall '(repl "_jsGC") (or keys [])))
-
- (setq js--js-last-gcs-done this-gcs-done)
- (when (called-interactively-p 'interactive)
- (message "Cleaned %s entries" num))
-
- num)))
-
-(run-with-idle-timer 30 t #'js-gc)
-
-(defun js-eval (js)
- "Evaluate the JavaScript in JS and return JSON-decoded result."
- (interactive "MJavaScript to evaluate: ")
- (with-js
- (let* ((content-window (js--js-content-window
- (js--get-js-context)))
- (result (js-eval content-window js)))
- (when (called-interactively-p 'interactive)
- (message "%s" (js! "String" result)))
- result)))
-
-(defun js--get-tabs ()
- "Enumerate all JavaScript contexts available.
-Each context is a list:
- (TITLE URL BROWSER TAB TABBROWSER) for content documents
- (TITLE URL WINDOW) for windows
-
-All tabs of a given window are grouped together. The most recent
-window is first. Within each window, the tabs are returned
-left-to-right."
- (with-js
- (let (windows)
-
- (cl-loop with window-mediator = (js! ("Components" "classes"
- "@mozilla.org/appshell/window-mediator;1"
- "getService")
- (js< "Components" "interfaces"
- "nsIWindowMediator"))
- with enumerator = (js! (window-mediator "getEnumerator") nil)
-
- while (js? (js! (enumerator "hasMoreElements")))
- for window = (js! (enumerator "getNext"))
- for window-info = (js-list window
- (js< window "document" "title")
- (js! (window "location" "toString"))
- (js< window "closed")
- (js< window "windowState"))
-
- unless (or (js? (cl-fourth window-info))
- (eq (cl-fifth window-info) 2))
- do (push window-info windows))
-
- (cl-loop for (window title location) in windows
- collect (list title location window)
-
- for gbrowser = (js< window "gBrowser")
- if (js-handle? gbrowser)
- nconc (cl-loop
- for x below (js< gbrowser "browsers" "length")
- collect (js-list (js< gbrowser
- "browsers"
- x
- "contentDocument"
- "title")
-
- (js! (gbrowser
- "browsers"
- x
- "contentWindow"
- "location"
- "toString"))
- (js< gbrowser
- "browsers"
- x)
-
- (js! (gbrowser
- "tabContainer"
- "childNodes"
- "item")
- x)
-
- gbrowser))))))
-
-(defvar js-read-tab-history nil)
-
-(declare-function ido-chop "ido" (items elem))
-
-(defun js--read-tab (prompt)
- "Read a Mozilla tab with prompt PROMPT.
-Return a cons of (TYPE . OBJECT). TYPE is either `window' or
-`tab', and OBJECT is a JavaScript handle to a ChromeWindow or a
-browser, respectively."
-
- ;; Prime IDO
- (unless ido-mode
- (ido-mode 1)
- (ido-mode -1))
-
- (with-js
- (let ((tabs (js--get-tabs)) selected-tab-cname
- selected-tab prev-hitab)
-
- ;; Disambiguate names
- (setq tabs
- (cl-loop with tab-names = (make-hash-table :test 'equal)
- for tab in tabs
- for cname = (format "%s (%s)"
- (cl-second tab) (cl-first tab))
- for num = (cl-incf (gethash cname tab-names -1))
- if (> num 0)
- do (setq cname (format "%s <%d>" cname num))
- collect (cons cname tab)))
-
- (cl-labels
- ((find-tab-by-cname
- (cname)
- (cl-loop for tab in tabs
- if (equal (car tab) cname)
- return (cdr tab)))
-
- (mogrify-highlighting
- (hitab unhitab)
-
- ;; Hack to reduce the number of
- ;; round-trips to mozilla
- (let (cmds)
- (cond
- ;; Highlighting tab
- ((cl-fourth hitab)
- (push '(js! ((cl-fourth hitab) "setAttribute")
- "style"
- "color: red; font-weight: bold")
- cmds)
-
- ;; Highlight window proper
- (push '(js! ((cl-third hitab)
- "setAttribute")
- "style"
- "border: 8px solid red")
- cmds)
-
- ;; Select tab, when appropriate
- (when js-js-switch-tabs
- (push
- '(js> ((cl-fifth hitab) "selectedTab") (cl-fourth hitab))
- cmds)))
-
- ;; Highlighting whole window
- ((cl-third hitab)
- (push '(js! ((cl-third hitab) "document"
- "documentElement" "setAttribute")
- "style"
- (concat "-moz-appearance: none;"
- "border: 8px solid red;"))
- cmds)))
-
- (cond
- ;; Unhighlighting tab
- ((cl-fourth unhitab)
- (push '(js! ((cl-fourth unhitab) "setAttribute") "style" "")
- cmds)
- (push '(js! ((cl-third unhitab) "setAttribute") "style" "")
- cmds))
-
- ;; Unhighlighting window
- ((cl-third unhitab)
- (push '(js! ((cl-third unhitab) "document"
- "documentElement" "setAttribute")
- "style" "")
- cmds)))
-
- (eval `(with-js
- (js-list ,@(nreverse cmds)))
- t)))
-
- (command-hook
- ()
- (let* ((tab (find-tab-by-cname (car ido-matches))))
- (mogrify-highlighting tab prev-hitab)
- (setq prev-hitab tab)))
-
- (setup-hook
- ()
- ;; Fiddle with the match list a bit: if our first match
- ;; is a tabbrowser window, rotate the match list until
- ;; the active tab comes up
- (let ((matched-tab (find-tab-by-cname (car ido-matches))))
- (when (and matched-tab
- (null (cl-fourth matched-tab))
- (equal "navigator:browser"
- (js! ((cl-third matched-tab)
- "document"
- "documentElement"
- "getAttribute")
- "windowtype")))
-
- (cl-loop with tab-to-match = (js< (cl-third matched-tab)
- "gBrowser"
- "selectedTab")
-
- for match in ido-matches
- for candidate-tab = (find-tab-by-cname match)
- if (eq (cl-fourth candidate-tab) tab-to-match)
- do (setq ido-cur-list
- (ido-chop ido-cur-list match))
- and return t)))
-
- (add-hook 'post-command-hook #'command-hook t t)))
-
-
- (unwind-protect
- ;; FIXME: Don't impose IDO on the user.
- (setq selected-tab-cname
- (let ((ido-minibuffer-setup-hook
- (cons #'setup-hook ido-minibuffer-setup-hook)))
- (ido-completing-read
- prompt
- (mapcar #'car tabs)
- nil t nil
- 'js-read-tab-history)))
-
- (when prev-hitab
- (mogrify-highlighting nil prev-hitab)
- (setq prev-hitab nil)))
-
- (add-to-history 'js-read-tab-history selected-tab-cname)
-
- (setq selected-tab (cl-loop for tab in tabs
- if (equal (car tab) selected-tab-cname)
- return (cdr tab)))
-
- (cons (if (cl-fourth selected-tab) 'browser 'window)
- (cl-third selected-tab))))))
-
-(defun js--guess-eval-defun-info (pstate)
- "Helper function for `js-eval-defun'.
-Return a list (NAME . CLASSPARTS), where CLASSPARTS is a list of
-strings making up the class name and NAME is the name of the
-function part."
- (cond ((and (= (length pstate) 3)
- (eq (js--pitem-type (cl-first pstate)) 'function)
- (= (length (js--pitem-name (cl-first pstate))) 1)
- (consp (js--pitem-type (cl-second pstate))))
-
- (append (js--pitem-name (cl-second pstate))
- (list (cl-first (js--pitem-name (cl-first pstate))))))
-
- ((and (= (length pstate) 2)
- (eq (js--pitem-type (cl-first pstate)) 'function))
-
- (append
- (butlast (js--pitem-name (cl-first pstate)))
- (list (car (last (js--pitem-name (cl-first pstate)))))))
-
- (t (error "Function not a toplevel defun or class member"))))
-
-(defvar js--js-context nil
- "The current JavaScript context.
-This is a cons like the one returned from `js--read-tab'.
-Change with `js-set-js-context'.")
-
-(defconst js--js-inserter
- "(function(func_info,func) {
- func_info.unshift('window');
- var obj = window;
- for(var i = 1; i < func_info.length - 1; ++i) {
- var next = obj[func_info[i]];
- if(typeof next !== 'object' && typeof next !== 'function') {
- next = obj.prototype && obj.prototype[func_info[i]];
- if(typeof next !== 'object' && typeof next !== 'function') {
- alert('Could not find ' + func_info.slice(0, i+1).join('.') +
- ' or ' + func_info.slice(0, i+1).join('.') + '.prototype');
- return;
- }
-
- func_info.splice(i+1, 0, 'prototype');
- ++i;
- }
- }
-
- obj[func_info[i]] = func;
- alert('Successfully updated '+func_info.join('.'));
- })")
-
-(defun js-set-js-context (context)
- "Set the JavaScript context to CONTEXT.
-When called interactively, prompt for CONTEXT."
- (interactive (list (js--read-tab "JavaScript Context: ")))
- (setq js--js-context context))
-
-(defun js--get-js-context ()
- "Return a valid JavaScript context.
-If one hasn't been set, or if it's stale, prompt for a new one."
- (with-js
- (when (or (null js--js-context)
- (js--js-handle-expired-p (cdr js--js-context))
- (pcase (car js--js-context)
- ('window (js? (js< (cdr js--js-context) "closed")))
- ('browser (not (js? (js< (cdr js--js-context)
- "contentDocument"))))
- (x (error "Unmatched case in js--get-js-context: %S" x))))
- (setq js--js-context (js--read-tab "JavaScript Context: ")))
- js--js-context))
-
-(defun js--js-content-window (context)
- (with-js
- (pcase (car context)
- ('window (cdr context))
- ('browser (js< (cdr context)
- "contentWindow" "wrappedJSObject"))
- (x (error "Unmatched case in js--js-content-window: %S" x)))))
-
-(defun js--make-nsilocalfile (path)
- (with-js
- (let ((file (js-create-instance "@mozilla.org/file/local;1"
- "nsILocalFile")))
- (js! (file "initWithPath") path)
- file)))
-
-(defun js--js-add-resource-alias (alias path)
- (with-js
- (let* ((io-service (js-get-service "@mozilla.org/network/io-service;1"
- "nsIIOService"))
- (res-prot (js! (io-service "getProtocolHandler") "resource"))
- (res-prot (js-qi res-prot "nsIResProtocolHandler"))
- (path-file (js--make-nsilocalfile path))
- (path-uri (js! (io-service "newFileURI") path-file)))
- (js! (res-prot "setSubstitution") alias path-uri))))
-
-(cl-defun js-eval-defun ()
- "Update a Mozilla tab using the JavaScript defun at point."
- (interactive)
-
- ;; This function works by generating a temporary file that contains
- ;; the function we'd like to insert. We then use the elisp-js bridge
- ;; to command mozilla to load this file by inserting a script tag
- ;; into the document we set. This way, debuggers and such will have
- ;; a way to find the source of the just-inserted function.
- ;;
- ;; We delete the temporary file if there's an error, but otherwise
- ;; we add an unload event listener on the Mozilla side to delete the
- ;; file.
-
- (save-excursion
- (let (begin end pstate defun-info temp-name defun-body)
- (js-end-of-defun)
- (setq end (point))
- (js--ensure-cache)
- (js-beginning-of-defun)
- (re-search-forward "\\_<function\\_>")
- (setq begin (match-beginning 0))
- (setq pstate (js--forward-pstate))
-
- (when (or (null pstate)
- (> (point) end))
- (error "Could not locate function definition"))
-
- (setq defun-info (js--guess-eval-defun-info pstate))
-
- (let ((overlay (make-overlay begin end)))
- (overlay-put overlay 'face 'highlight)
- (unwind-protect
- (unless (y-or-n-p (format "Send %s to Mozilla? "
- (mapconcat #'identity defun-info ".")))
- (message "") ; question message lingers until next command
- (cl-return-from js-eval-defun))
- (delete-overlay overlay)))
-
- (setq defun-body (buffer-substring-no-properties begin end))
-
- (make-directory js-js-tmpdir t)
-
- ;; (Re)register a Mozilla resource URL to point to the
- ;; temporary directory
- (js--js-add-resource-alias "js" js-js-tmpdir)
-
- (setq temp-name (make-temp-file (concat js-js-tmpdir
- "/js-")
- nil ".js"))
- (unwind-protect
- (with-js
- (with-temp-buffer
- (insert js--js-inserter)
- (insert "(")
- (let ((standard-output (current-buffer)))
- (json--print-list defun-info))
- (insert ",\n")
- (insert defun-body)
- (insert "\n)")
- (write-region (point-min) (point-max) temp-name
- nil 1))
-
- ;; Give Mozilla responsibility for deleting this file
- (let* ((content-window (js--js-content-window
- (js--get-js-context)))
- (content-document (js< content-window "document"))
- (head (if (js? (js< content-document "body"))
- ;; Regular content
- (js< (js! (content-document "getElementsByTagName")
- "head")
- 0)
- ;; Chrome
- (js< content-document "documentElement")))
- (elem (js! (content-document "createElementNS")
- "http://www.w3.org/1999/xhtml" "script")))
-
- (js! (elem "setAttribute") "type" "text/javascript")
- (js! (elem "setAttribute") "src"
- (format "resource://js/%s"
- (file-name-nondirectory temp-name)))
-
- (js! (head "appendChild") elem)
-
- (js! (content-window "addEventListener") "unload"
- (js! ((js-new
- "Function" "file"
- "return function() { file.remove(false) }"))
- (js--make-nsilocalfile temp-name))
- 'false)
- (setq temp-name nil)
-
-
-
- ))
-
- ;; temp-name is set to nil on success
- (when temp-name
- (delete-file temp-name))))))
-
;;; Syntax extensions
(defvar js-syntactic-mode-name t
diff --git a/lisp/progmodes/ld-script.el b/lisp/progmodes/ld-script.el
index 485e64e2492..879eb720651 100644
--- a/lisp/progmodes/ld-script.el
+++ b/lisp/progmodes/ld-script.el
@@ -167,11 +167,11 @@
("\\W\\(\\.\\)\\W" 1 ld-script-location-counter-face)
)
cpp-font-lock-keywords)
- "Default font-lock-keywords for `ld-script-mode'.")
+ "Default `font-lock-keywords' for `ld-script-mode'.")
;;;###autoload
(define-derived-mode ld-script-mode prog-mode "LD-Script"
- "A major mode to edit GNU ld script files"
+ "A major mode to edit GNU ld script files."
(setq-local comment-start "/* ")
(setq-local comment-end " */")
(setq-local font-lock-defaults '(ld-script-font-lock-keywords nil)))
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el
index b1a5f301587..79530f81673 100644
--- a/lisp/progmodes/octave.el
+++ b/lisp/progmodes/octave.el
@@ -351,7 +351,7 @@ Non-nil means always go to the next Octave code line after sending."
;; corresponding continuation lines).
(defun octave-smie--funcall-p ()
- "Return non-nil if we're in an expression context. Moves point."
+ "Return non-nil if we're in an expression context. Move point."
(looking-at "[ \t]*("))
(defun octave-smie--end-index-p ()
@@ -1034,7 +1034,7 @@ directory and makes this the current buffer's default directory."
(nth 8 (syntax-ppss)))
(defun octave-looking-at-kw (regexp)
- "Like `looking-at', but sets `case-fold-search' nil."
+ "Like `looking-at', but set `case-fold-search' nil first."
(let ((case-fold-search nil))
(looking-at regexp)))
@@ -1814,18 +1814,18 @@ If the environment variable OCTAVE_SRCDIR is set, it is searched first."
(user-error "Aborted")))
(_ name)))
-(defvar find-tag-marker-ring)
+(declare-function xref-push-marker-stack "xref" (&optional m))
(defun octave-find-definition (fn)
"Find the definition of FN.
Functions implemented in C++ can be found if
variable `octave-source-directories' is set correctly."
(interactive (list (octave-completing-read)))
- (require 'etags)
+ (require 'xref)
(let ((orig (point)))
(if (and (derived-mode-p 'octave-mode)
(octave-goto-function-definition fn))
- (ring-insert find-tag-marker-ring (copy-marker orig))
+ (xref-push-marker-stack (copy-marker orig))
(inferior-octave-send-list-and-digest
;; help NAME is more verbose
(list (format "\
@@ -1840,7 +1840,7 @@ if iskeyword('%s') disp('`%s'' is a keyword') else which('%s') endif\n"
(setq file (match-string 1 line))))
(if (not file)
(user-error "%s" (or line (format-message "`%s' not found" fn)))
- (ring-insert find-tag-marker-ring (point-marker))
+ (xref-push-marker-stack)
(setq file (funcall octave-find-definition-filename-function file))
(when file
(find-file file)
diff --git a/lisp/progmodes/opascal.el b/lisp/progmodes/opascal.el
index 662d2b4b74f..495c77bbd90 100644
--- a/lisp/progmodes/opascal.el
+++ b/lisp/progmodes/opascal.el
@@ -24,9 +24,10 @@
;;; Commentary:
-;; To enter OPascal mode when you find an Object Pascal source file, one must
-;; override the auto-mode-alist to associate OPascal with .pas (and .dpr and
-;; .dpk) files. Emacs, by default, will otherwise enter Pascal mode. E.g.
+;; To enter OPascal mode when you find an Object Pascal source file,
+;; one must override the auto-mode-alist to associate OPascal with
+;; .pas (and .dpr and .dpk) files. Emacs, by default, will otherwise
+;; enter Pascal mode. For example:
;;
;; (autoload 'opascal-mode "opascal")
;; (add-to-list 'auto-mode-alist
@@ -50,7 +51,7 @@
:group 'languages)
(defconst opascal-debug nil
- "True if in debug mode.")
+ "Non-nil if in debug mode.")
(define-obsolete-variable-alias
'delphi-search-path 'opascal-search-path "24.4")
@@ -244,8 +245,8 @@ are followed by an expression.")
(defconst opascal-begin-previous-tokens
`(,@opascal-decl-sections ,@opascal-routine-statements)
- "Tokens that a begin token aligns with, but only if not part of a nested
-routine.")
+ "Tokens that a begin token aligns with, but only if not part of a \
+nested routine.")
(defconst opascal-space-chars "\000-\011\013- ") ; all except \n
(defconst opascal-non-space-chars (concat "^" opascal-space-chars))
@@ -1530,7 +1531,7 @@ If no extension is specified, .pas is assumed. Creates a buffer for the unit."
(concat unit ".pas")))
(file (opascal-find-unit-file unit-file)))
(if (null file)
- (error "unit not found: %s" unit-file)
+ (error "Unit not found: %s" unit-file)
(find-file file)
(if (not (derived-mode-p 'opascal-mode))
(opascal-mode)))
@@ -1539,7 +1540,7 @@ If no extension is specified, .pas is assumed. Creates a buffer for the unit."
(defun opascal-find-current-def ()
"Find the definition of the identifier under the current point."
(interactive)
- (error "opascal-find-current-def: not implemented yet"))
+ (error "opascal-find-current-def: Not implemented yet"))
(defun opascal-find-current-xdef ()
"Find the definition of the identifier under the current point, searching
@@ -1547,13 +1548,13 @@ in external units if necessary (as listed in the current unit's use clause).
The set of directories to search for a unit is specified by the global variable
`opascal-search-path'."
(interactive)
- (error "opascal-find-current-xdef: not implemented yet"))
+ (error "opascal-find-current-xdef: Not implemented yet"))
(defun opascal-find-current-body ()
"Find the body of the identifier under the current point, assuming
it is a routine."
(interactive)
- (error "opascal-find-current-body: not implemented yet"))
+ (error "opascal-find-current-body: Not implemented yet"))
(defun opascal-fill-comment ()
"Fill the text of the current comment, according to `fill-column'.
@@ -1731,7 +1732,8 @@ comment block. If not in a // comment, just does a normal newline."
(define-obsolete-function-alias 'delphi-mode #'opascal-mode "24.4")
;;;###autoload
(define-derived-mode opascal-mode prog-mode "OPascal"
- "Major mode for editing OPascal code.\\<opascal-mode-map>
+ "Major mode for editing OPascal code.
+\\<opascal-mode-map>
\\[opascal-find-unit]\t- Search for a OPascal source file.
\\[opascal-fill-comment]\t- Fill the current comment.
\\[opascal-new-comment-line]\t- If in a // comment, do a new comment line.
diff --git a/lisp/progmodes/pascal.el b/lisp/progmodes/pascal.el
index e6e6e40aa19..5938da542ac 100644
--- a/lisp/progmodes/pascal.el
+++ b/lisp/progmodes/pascal.el
@@ -1357,9 +1357,7 @@ The default is a name found in the buffer around point."
default ""))
(label
;; Do completion with default.
- (completing-read (if (not (string= default ""))
- (concat "Label (default " default "): ")
- "Label: ")
+ (completing-read (format-prompt "Label" default)
;; Complete with the defuns found in the
;; current-buffer.
(let ((buf (current-buffer)))
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el
index 4e14c30bc5d..20834dd2e1e 100644
--- a/lisp/progmodes/perl-mode.el
+++ b/lisp/progmodes/perl-mode.el
@@ -101,7 +101,7 @@
:version "28.1")
(defvar perl-mode-abbrev-table nil
- "Abbrev table in use in perl-mode buffers.")
+ "Abbrev table in use in `perl-mode' buffers.")
(define-abbrev-table 'perl-mode-abbrev-table ())
(defvar perl-mode-map
@@ -509,7 +509,7 @@
(defface perl-heredoc
'((t (:inherit font-lock-string-face)))
- "The face for here-documents. Inherits from font-lock-string-face.")
+ "The face for here-documents. Inherits from `font-lock-string-face'.")
(defun perl-font-lock-syntactic-face-function (state)
(cond
@@ -644,10 +644,10 @@ the Perl source to be checked as its standard input."
;;;###autoload
(defun perl-flymake (report-fn &rest _args)
- "Perl backend for Flymake. Launches
-`perl-flymake-command' (which see) and passes to its standard
-input the contents of the current buffer. The output of this
-command is analyzed for error and warning messages."
+ "Perl backend for Flymake.
+Launch `perl-flymake-command' (which see) and pass to its
+standard input the contents of the current buffer. The output of
+this command is analyzed for error and warning messages."
(unless (executable-find (car perl-flymake-command))
(error "Cannot find a suitable checker"))
diff --git a/lisp/progmodes/prog-mode.el b/lisp/progmodes/prog-mode.el
index a8b608b018a..496b0810183 100644
--- a/lisp/progmodes/prog-mode.el
+++ b/lisp/progmodes/prog-mode.el
@@ -43,22 +43,61 @@
display-line-numbers-mode
prettify-symbols-mode))
-(defun prog-context-menu (menu)
- (when (featurep 'xref)
- (define-key-after menu [prog-separator] menu-bar-separator
- 'mark-whole-buffer)
- (define-key-after menu [xref-find-def]
- '(menu-item "Find Definition" xref-find-definitions-at-mouse
- :visible (save-excursion
- (mouse-set-point last-input-event)
- (xref-backend-identifier-at-point (xref-find-backend)))
- :help "Find definition of function or variable")
- 'prog-separator)
+(defun prog-context-menu (menu click)
+ "Populate MENU with xref commands at CLICK."
+ (require 'xref)
+ (define-key-after menu [prog-separator] menu-bar-separator
+ 'middle-separator)
+
+ (unless (xref-forward-history-empty-p)
+ (define-key-after menu [xref-forward]
+ '(menu-item "Go Forward" xref-go-forward
+ :help "Forward to the position gone Back from")
+ 'prog-separator))
+
+ (unless (xref-marker-stack-empty-p)
(define-key-after menu [xref-pop]
- '(menu-item "Back Definition" xref-pop-marker-stack
- :visible (not (xref-marker-stack-empty-p))
+ '(menu-item "Go Back" xref-go-back
:help "Back to the position of the last search")
- 'xref-find-def))
+ 'prog-separator))
+
+ (let ((identifier (save-excursion
+ (mouse-set-point click)
+ (xref-backend-identifier-at-point
+ (xref-find-backend)))))
+ (when identifier
+ (define-key-after menu [xref-find-ref]
+ `(menu-item "Find References" xref-find-references-at-mouse
+ :help ,(format "Find references to `%s'" identifier))
+ 'prog-separator)
+ (define-key-after menu [xref-find-def]
+ `(menu-item "Find Definition" xref-find-definitions-at-mouse
+ :help ,(format "Find definition of `%s'" identifier))
+ 'prog-separator)))
+
+ (when (thing-at-mouse click 'symbol)
+ (define-key-after menu [select-region mark-symbol]
+ `(menu-item "Symbol"
+ ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'symbol))
+ :help "Mark the symbol at click for a subsequent cut/copy")
+ 'mark-whole-buffer))
+ (define-key-after menu [select-region mark-list]
+ `(menu-item "List"
+ ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'list))
+ :help "Mark the list at click for a subsequent cut/copy")
+ 'mark-whole-buffer)
+ (define-key-after menu [select-region mark-defun]
+ `(menu-item "Defun"
+ ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'defun))
+ :help "Mark the defun at click for a subsequent cut/copy")
+ 'mark-whole-buffer)
+
+ ;; Include text-mode select menu only in strings and comments.
+ (when (nth 8 (save-excursion
+ (with-current-buffer (window-buffer (posn-window (event-end click)))
+ (syntax-ppss (posn-point (event-end click))))))
+ (text-mode-context-menu menu click))
+
menu)
(defvar prog-mode-map
@@ -118,7 +157,7 @@ which case it will be used to compose the new symbol as per the
third argument of `compose-region'.")
(defun prettify-symbols-default-compose-p (start end _match)
- "Return true iff the symbol MATCH should be composed.
+ "Return non-nil iff the symbol MATCH should be composed.
The symbol starts at position START and ends at position END.
This is the default for `prettify-symbols-compose-predicate'
which is suitable for most programming languages such as C or Lisp."
@@ -136,7 +175,7 @@ which is suitable for most programming languages such as C or Lisp."
"A predicate for deciding if the currently matched symbol is to be composed.
The matched symbol is the car of one entry in `prettify-symbols-alist'.
The predicate receives the match's start and end positions as well
-as the match-string as arguments.")
+as the `match-string' as arguments.")
(defun prettify-symbols--compose-symbol (alist)
"Compose a sequence of characters into a symbol.
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index 4620ea8f47e..3b634471ace 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-2021 Free Software Foundation, Inc.
-;; Version: 0.6.1
+;; Version: 0.8.1
;; Package-Requires: ((emacs "26.1") (xref "1.0.2"))
;; This is a GNU ELPA :core package. Avoid using functionality that
@@ -51,6 +51,11 @@
;; files and its relations to external directories. `project-files'
;; should be consistent with `project-ignores'.
;;
+;; `project-buffers' can be overridden if the project has some unusual
+;; shape (e.g. it contains files residing outside of its root, or some
+;; files inside the root must not be considered a part of it). It
+;; should be consistent with `project-files'.
+;;
;; This list can change in future versions.
;;
;; VC project:
@@ -297,11 +302,10 @@ to find the list of ignores for each directory."
;; expanded and not left for the shell command
;; to interpret.
(localdir (file-name-unquote (file-local-name (expand-file-name dir))))
- (command (format "%s -H %s %s -type f %s -print0"
+ (dfn (directory-file-name localdir))
+ (command (format "%s -H . %s -type f %s -print0"
find-program
- (shell-quote-argument
- (directory-file-name localdir)) ; Bug#48471
- (xref--find-ignores-arguments ignores localdir)
+ (xref--find-ignores-arguments ignores "./")
(if files
(concat (shell-quote-argument "(")
" " find-name-arg " "
@@ -312,15 +316,29 @@ to find the list of ignores for each directory."
" "
(shell-quote-argument ")"))
"")))
- (output (with-output-to-string
- (with-current-buffer standard-output
- (let ((status
- (process-file-shell-command command nil t)))
- (unless (zerop status)
- (error "File listing failed: %s" (buffer-string))))))))
+ res)
+ (with-temp-buffer
+ (let ((status
+ (process-file-shell-command command nil t))
+ (pt (point-min)))
+ (unless (zerop status)
+ (goto-char (point-min))
+ (if (and
+ (not (eql status 127))
+ (search-forward "Permission denied\n" nil t))
+ (let ((end (1- (point))))
+ (re-search-backward "\\`\\|\0")
+ (error "File listing failed: %s"
+ (buffer-substring (1+ (point)) end)))
+ (error "File listing failed: %s" (buffer-string))))
+ (goto-char pt)
+ (while (search-forward "\0" nil t)
+ (push (buffer-substring-no-properties (1+ pt) (1- (point)))
+ res)
+ (setq pt (point)))))
(project--remote-file-names
- (sort (split-string output "\0" t)
- #'string<))))
+ (mapcar (lambda (s) (concat dfn s))
+ (sort res #'string<)))))
(defun project--remote-file-names (local-files)
"Return LOCAL-FILES as if they were on the system of `default-directory'.
@@ -334,6 +352,16 @@ Also quote LOCAL-FILES if `default-directory' is quoted."
(concat remote-id file))
local-files))))
+(cl-defgeneric project-buffers (project)
+ "Return the list of all live buffers that belong to PROJECT."
+ (let ((root (expand-file-name (file-name-as-directory (project-root project))))
+ bufs)
+ (dolist (buf (buffer-list))
+ (when (string-prefix-p root (expand-file-name
+ (buffer-local-value 'default-directory buf)))
+ (push buf bufs)))
+ (nreverse bufs)))
+
(defgroup project-vc nil
"Project implementation based on the VC package."
:version "25.1"
@@ -589,7 +617,9 @@ backend implementation of `project-external-roots'.")
(replace-match "./" t t entry 1)
(concat "./" entry)))
(t entry)))
- (vc-call-backend backend 'ignore-completion-table root))))
+ (condition-case nil
+ (vc-call-backend backend 'ignore-completion-table root)
+ (vc-not-supported () nil)))))
(project--value-in-dir 'project-vc-ignores root)
(mapcar
(lambda (dir)
@@ -628,6 +658,23 @@ DIRS must contain directory names."
(hack-dir-local-variables-non-file-buffer))
(symbol-value var)))
+(cl-defmethod project-buffers ((project (head vc)))
+ (let* ((root (expand-file-name (file-name-as-directory (project-root project))))
+ (modules (unless (or (project--vc-merge-submodules-p root)
+ (project--submodule-p root))
+ (mapcar
+ (lambda (m) (format "%s%s/" root m))
+ (project--git-submodules))))
+ dd
+ bufs)
+ (dolist (buf (buffer-list))
+ (setq dd (expand-file-name (buffer-local-value 'default-directory buf)))
+ (when (and (string-prefix-p root dd)
+ (not (cl-find-if (lambda (module) (string-prefix-p module dd))
+ modules)))
+ (push buf bufs)))
+ (nreverse bufs)))
+
;;; Project commands
@@ -640,7 +687,8 @@ DIRS must contain directory names."
(define-key map "F" 'project-or-external-find-file)
(define-key map "b" 'project-switch-to-buffer)
(define-key map "s" 'project-shell)
- (define-key map "d" 'project-dired)
+ (define-key map "d" 'project-find-dir)
+ (define-key map "D" 'project-dired)
(define-key map "v" 'project-vc-dir)
(define-key map "c" 'project-compile)
(define-key map "e" 'project-eshell)
@@ -800,28 +848,36 @@ pattern to search for."
project-regexp-history-variable)))
;;;###autoload
-(defun project-find-file ()
+(defun project-find-file (&optional include-all)
"Visit a file (with completion) in the current project.
-The completion default is the filename at point, determined by
-`thing-at-point' (whether such file exists or not)."
- (interactive)
+The filename at point (determined by `thing-at-point'), if any,
+is available as part of \"future history\".
+
+If INCLUDE-ALL is non-nil, or with prefix argument when called
+interactively, include all files under the project root, except
+for VCS directories listed in `vc-directory-exclusion-list'."
+ (interactive "P")
(let* ((pr (project-current t))
(dirs (list (project-root pr))))
- (project-find-file-in (thing-at-point 'filename) dirs pr)))
+ (project-find-file-in (thing-at-point 'filename) dirs pr include-all)))
;;;###autoload
-(defun project-or-external-find-file ()
+(defun project-or-external-find-file (&optional include-all)
"Visit a file (with completion) in the current project or external roots.
-The completion default is the filename at point, determined by
-`thing-at-point' (whether such file exists or not)."
- (interactive)
+The filename at point (determined by `thing-at-point'), if any,
+is available as part of \"future history\".
+
+If INCLUDE-ALL is non-nil, or with prefix argument when called
+interactively, include all files under the project root, except
+for VCS directories listed in `vc-directory-exclusion-list'."
+ (interactive "P")
(let* ((pr (project-current t))
(dirs (cons
(project-root pr)
(project-external-roots pr))))
- (project-find-file-in (thing-at-point 'filename) dirs pr)))
+ (project-find-file-in (thing-at-point 'filename) dirs pr include-all)))
(defcustom project-read-file-name-function #'project--read-file-cpd-relative
"Function to call to read a file name from a list.
@@ -836,11 +892,14 @@ For the arguments list, see `project--read-file-cpd-relative'."
(defun project--read-file-cpd-relative (prompt
all-files &optional predicate
- hist default)
+ hist mb-default)
"Read a file name, prompting with PROMPT.
ALL-FILES is a list of possible file name completions.
-PREDICATE, HIST, and DEFAULT have the same meaning as in
-`completing-read'."
+
+PREDICATE and HIST have the same meaning as in `completing-read'.
+
+MB-DEFAULT is used as part of \"future history\", to be inserted
+by the user at will."
(let* ((common-parent-directory
(let ((common-prefix (try-completion "" all-files)))
(if (> (length common-prefix) 0)
@@ -849,41 +908,63 @@ PREDICATE, HIST, and DEFAULT have the same meaning as in
(prompt (if (zerop cpd-length)
prompt
(concat prompt (format " in %s" common-parent-directory))))
+ (included-cpd (when (member common-parent-directory all-files)
+ (setq all-files
+ (delete common-parent-directory all-files))
+ t))
(substrings (mapcar (lambda (s) (substring s cpd-length)) all-files))
+ (_ (when included-cpd
+ (setq substrings (cons "./" substrings))))
(new-collection (project--file-completion-table substrings))
(res (project--completing-read-strict prompt
new-collection
predicate
- hist default)))
+ hist mb-default)))
(concat common-parent-directory res)))
(defun project--read-file-absolute (prompt
all-files &optional predicate
- hist default)
+ hist mb-default)
(project--completing-read-strict prompt
(project--file-completion-table all-files)
predicate
- hist default))
-
-(defun project-find-file-in (filename dirs project)
- "Complete FILENAME in DIRS in PROJECT and visit the result."
- (let* ((all-files (project-files project dirs))
+ hist mb-default))
+
+(defun project-find-file-in (suggested-filename dirs project &optional include-all)
+ "Complete a file name in DIRS in PROJECT and visit the result.
+
+SUGGESTED-FILENAME is a relative file name, or part of it, which
+is used as part of \"future history\".
+
+If INCLUDE-ALL is non-nil, or with prefix argument when called
+interactively, include all files from DIRS, except for VCS
+directories listed in `vc-directory-exclusion-list'."
+ (let* ((vc-dirs-ignores (mapcar
+ (lambda (dir)
+ (concat dir "/"))
+ vc-directory-exclusion-list))
+ (all-files
+ (if include-all
+ (mapcan
+ (lambda (dir) (project--files-in-directory dir vc-dirs-ignores))
+ dirs)
+ (project-files project dirs)))
(completion-ignore-case read-file-name-completion-ignore-case)
(file (funcall project-read-file-name-function
"Find file" all-files nil nil
- filename)))
+ suggested-filename)))
(if (string= file "")
(user-error "You didn't specify the file")
(find-file file))))
(defun project--completing-read-strict (prompt
collection &optional predicate
- hist default)
+ hist mb-default)
(minibuffer-with-setup-hook
(lambda ()
(setq-local minibuffer-default-add-function
(lambda ()
- (let ((minibuffer-default default))
+ (let ((minibuffer-default mb-default))
(minibuffer-default-add-completions)))))
(completing-read (format "%s: " prompt)
collection predicate 'confirm
@@ -891,6 +972,26 @@ PREDICATE, HIST, and DEFAULT have the same meaning as in
hist)))
;;;###autoload
+(defun project-find-dir ()
+ "Start Dired in a directory inside the current project."
+ (interactive)
+ (let* ((project (project-current t))
+ (all-files (project-files project))
+ (completion-ignore-case read-file-name-completion-ignore-case)
+ ;; FIXME: This misses directories without any files directly
+ ;; inside. Consider DIRS-ONLY as an argument for
+ ;; `project-files-filtered', and see
+ ;; https://stackoverflow.com/a/50685235/615245 for possible
+ ;; implementation.
+ (all-dirs (mapcar #'file-name-directory all-files))
+ (dir (funcall project-read-file-name-function
+ "Dired"
+ ;; Some completion UIs show duplicates.
+ (delete-dups all-dirs)
+ nil nil)))
+ (dired dir)))
+
+;;;###autoload
(defun project-dired ()
"Start Dired in the current project's root."
(interactive)
@@ -966,8 +1067,8 @@ command \\[fileloop-continue]."
(defun project-query-replace-regexp (from to)
"Query-replace REGEXP in all the files of the project.
Stops when a match is found and prompts for whether to replace it.
-If you exit the query-replace, you can later continue the query-replace
-loop using the command \\[fileloop-continue]."
+If you exit the `query-replace', you can later continue the
+`query-replace' loop using the command \\[fileloop-continue]."
(interactive
(pcase-let ((`(,from ,to)
(query-replace-read-args "Query replace (regexp)" t t)))
@@ -1014,13 +1115,11 @@ If non-nil, it overrides `compilation-buffer-name-function' for
(current-buffer (current-buffer))
(other-buffer (other-buffer current-buffer))
(other-name (buffer-name other-buffer))
+ (buffers (project-buffers pr))
(predicate
(lambda (buffer)
;; BUFFER is an entry (BUF-NAME . BUF-OBJ) of Vbuffer_alist.
- (and (cdr buffer)
- (equal pr
- (with-current-buffer (cdr buffer)
- (project-current)))))))
+ (memq (cdr buffer) buffers))))
(read-buffer
"Switch to buffer: "
(when (funcall predicate (cons other-name other-buffer))
@@ -1074,7 +1173,10 @@ displayed."
(not (major-mode . help-mode)))
(derived-mode . compilation-mode)
(derived-mode . dired-mode)
- (derived-mode . diff-mode))
+ (derived-mode . diff-mode)
+ (derived-mode . comint-mode)
+ (derived-mode . eshell-mode)
+ (derived-mode . change-log-mode))
"List of conditions to kill buffers related to a project.
This list is used by `project-kill-buffers'.
Each condition is either:
@@ -1107,9 +1209,18 @@ current project, it will be killed."
(const and) sexp)
(cons :tag "Disjunction"
(const or) sexp)))
- :version "28.1"
+ :version "29.1"
+ :group 'project
+ :package-version '(project . "0.8.2"))
+
+(defcustom project-kill-buffers-display-buffer-list nil
+ "Non-nil to display list of buffers to kill before killing project buffers.
+Used by `project-kill-buffers'."
+ :type 'boolean
+ :version "29.1"
:group 'project
- :package-version '(project . "0.6.0"))
+ :package-version '(project . "0.8.2")
+ :safe #'booleanp)
(defun project--buffer-list (pr)
"Return the list of all buffers in project PR."
@@ -1160,7 +1271,7 @@ of CONDITIONS."
What buffers should or should not be killed is described
in `project-kill-buffer-conditions'."
(let (bufs)
- (dolist (buf (project--buffer-list pr))
+ (dolist (buf (project-buffers pr))
(when (project--kill-buffer-check buf project-kill-buffer-conditions)
(push buf bufs)))
bufs))
@@ -1177,14 +1288,35 @@ NO-CONFIRM is always nil when the command is invoked
interactively."
(interactive)
(let* ((pr (project-current t))
- (bufs (project--buffers-to-kill pr)))
+ (bufs (project--buffers-to-kill pr))
+ (query-user (lambda ()
+ (yes-or-no-p
+ (format "Kill %d buffers in %s? "
+ (length bufs)
+ (project-root pr))))))
(cond (no-confirm
(mapc #'kill-buffer bufs))
((null bufs)
(message "No buffers to kill"))
- ((yes-or-no-p (format "Kill %d buffers in %s? "
- (length bufs)
- (project-root pr)))
+ (project-kill-buffers-display-buffer-list
+ (when
+ (with-current-buffer-window
+ (get-buffer-create "*Buffer List*")
+ `(display-buffer--maybe-at-bottom
+ (dedicated . t)
+ (window-height . (fit-window-to-buffer))
+ (preserve-size . (nil . t))
+ (body-function
+ . ,#'(lambda (_window)
+ (list-buffers-noselect nil bufs))))
+ #'(lambda (window _value)
+ (with-selected-window window
+ (unwind-protect
+ (funcall query-user)
+ (when (window-live-p window)
+ (quit-restore-window window 'kill))))))
+ (mapc #'kill-buffer bufs)))
+ ((funcall query-user)
(mapc #'kill-buffer bufs)))))
@@ -1231,9 +1363,10 @@ With some possible metadata (to be decided).")
(write-region nil nil filename nil 'silent))))
;;;###autoload
-(defun project-remember-project (pr)
+(defun project-remember-project (pr &optional no-write)
"Add project PR to the front of the project list.
-Save the result in `project-list-file' if the list of projects has changed."
+Save the result in `project-list-file' if the list of projects
+has changed, and NO-WRITE is nil."
(project--ensure-read-project-list)
(let ((dir (project-root pr)))
(unless (equal (caar project--list) dir)
@@ -1241,7 +1374,8 @@ Save the result in `project-list-file' if the list of projects has changed."
(when (equal dir (car ent))
(setq project--list (delq ent project--list))))
(push (list dir) project--list)
- (project--write-project-list))))
+ (unless no-write
+ (project--write-project-list)))))
(defun project--remove-from-project-list (project-root report-message)
"Remove directory PROJECT-ROOT of a missing project from the project list.
@@ -1256,7 +1390,7 @@ passed to `message' as its first argument."
(project--write-project-list)))
;;;###autoload
-(defun project-remove-known-project (project-root)
+(defun project-forget-project (project-root)
"Remove directory PROJECT-ROOT from the project list.
PROJECT-ROOT is the root directory of a known project listed in
the project list."
@@ -1276,7 +1410,10 @@ It's also possible to enter an arbitrary directory not in the list."
;; completion style).
(project--file-completion-table
(append project--list `(,dir-choice))))
- (pr-dir (completing-read "Select project: " choices nil t)))
+ (pr-dir ""))
+ (while (equal pr-dir "")
+ ;; If the user simply pressed RET, do this again until they don't.
+ (setq pr-dir (completing-read "Select project: " choices nil t)))
(if (equal pr-dir dir-choice)
(read-directory-name "Select directory: " default-directory nil t)
pr-dir)))
@@ -1295,13 +1432,77 @@ It's also possible to enter an arbitrary directory not in the list."
(let ((default-directory (project-root (project-current t))))
(call-interactively #'execute-extended-command)))
+(defun project-remember-projects-under (dir &optional recursive)
+ "Index all projects below a directory DIR.
+If RECURSIVE is non-nil, recurse into all subdirectories to find
+more projects. After finishing, a message is printed summarizing
+the progress. The function returns the number of detected
+projects."
+ (interactive "DDirectory: \nP")
+ (project--ensure-read-project-list)
+ (let ((queue (directory-files dir t nil t)) (count 0)
+ (known (make-hash-table
+ :size (* 2 (length project--list))
+ :test #'equal )))
+ (dolist (project (mapcar #'car project--list))
+ (puthash project t known))
+ (while queue
+ (when-let ((subdir (pop queue))
+ ((file-directory-p subdir))
+ ((not (gethash subdir known))))
+ (when-let (pr (project--find-in-directory subdir))
+ (project-remember-project pr t)
+ (message "Found %s..." (project-root pr))
+ (setq count (1+ count)))
+ (when (and recursive (file-symlink-p subdir))
+ (setq queue (nconc (directory-files subdir t nil t) queue))
+ (puthash subdir t known))))
+ (unless (eq recursive 'in-progress)
+ (if (zerop count)
+ (message "No projects were found")
+ (project--write-project-list)
+ (message "%d project%s were found"
+ count (if (= count 1) "" "s"))))
+ count))
+
+(defun project-forget-zombie-projects ()
+ "Forget all known projects that don't exist any more."
+ (interactive)
+ (dolist (proj (project-known-project-roots))
+ (unless (file-exists-p proj)
+ (project-forget-project proj))))
+
+(defun project-forget-projects-under (dir &optional recursive)
+ "Forget all known projects below a directory DIR.
+If RECURSIVE is non-nil, recurse into all subdirectories to
+remove all known projects. After finishing, a message is printed
+summarizing the progress. The function returns the number of
+forgotten projects."
+ (interactive "DDirectory: \nP")
+ (let ((count 0))
+ (if recursive
+ (dolist (proj (project-known-project-roots))
+ (when (file-in-directory-p proj dir)
+ (project-forget-project proj)
+ (setq count (1+ count))))
+ (dolist (proj (project-known-project-roots))
+ (when (file-equal-p (file-name-directory proj) dir)
+ (project-forget-project proj)
+ (setq count (1+ count)))))
+ (if (zerop count)
+ (message "No projects were forgotten")
+ (project--write-project-list)
+ (message "%d project%s were forgotten"
+ count (if (= count 1) "" "s")))
+ count))
+
;;; Project switching
(defcustom project-switch-commands
'((project-find-file "Find file")
(project-find-regexp "Find regexp")
- (project-dired "Dired")
+ (project-find-dir "Find directory")
(project-vc-dir "VC-Dir")
(project-eshell "Eshell"))
"Alist mapping commands to descriptions.
@@ -1312,17 +1513,22 @@ Each element is of the form (COMMAND LABEL &optional KEY) where
COMMAND is the command to run when KEY is pressed. LABEL is used
to distinguish the menu entries in the dispatch menu. If KEY is
absent, COMMAND must be bound in `project-prefix-map', and the
-key is looked up in that map."
+key is looked up in that map.
+
+The value can also be a symbol, the name of the command to be
+invoked immediately without any dispatch menu."
:version "28.1"
:group 'project
:package-version '(project . "0.6.0")
- :type '(repeat
- (list
- (symbol :tag "Command")
- (string :tag "Label")
- (choice :tag "Key to press"
- (const :tag "Infer from the keymap" nil)
- (character :tag "Explicit key")))))
+ :type '(choice
+ (repeat :tag "Commands menu"
+ (list
+ (symbol :tag "Command")
+ (string :tag "Label")
+ (choice :tag "Key to press"
+ (const :tag "Infer from the keymap" nil)
+ (character :tag "Explicit key"))))
+ (symbol :tag "Single command")))
(defcustom project-switch-use-entire-map nil
"Make `project-switch-project' use entire `project-prefix-map'.
@@ -1352,15 +1558,7 @@ are legal even if they aren't listed in the dispatch menu."
project-switch-commands
" "))
-;;;###autoload
-(defun project-switch-project (dir)
- "\"Switch\" to another project by running an Emacs command.
-The available commands are presented as a dispatch menu
-made from `project-switch-commands'.
-
-When called in a program, it will use the project corresponding
-to directory DIR."
- (interactive (list (project-prompt-project-dir)))
+(defun project--switch-project-command ()
(let* ((commands-menu
(mapcar
(lambda (row)
@@ -1391,6 +1589,20 @@ to directory DIR."
(when (memq global-command
'(keyboard-quit keyboard-escape-quit))
(call-interactively global-command)))))
+ command))
+
+;;;###autoload
+(defun project-switch-project (dir)
+ "\"Switch\" to another project by running an Emacs command.
+The available commands are presented as a dispatch menu
+made from `project-switch-commands'.
+
+When called in a program, it will use the project corresponding
+to directory DIR."
+ (interactive (list (project-prompt-project-dir)))
+ (let ((command (if (symbolp project-switch-commands)
+ project-switch-commands
+ (project--switch-project-command))))
(let ((default-directory dir)
(project-current-inhibit-prompt t))
(call-interactively command))))
diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el
index 2e23c2e2cab..c36082bb6d0 100644
--- a/lisp/progmodes/prolog.el
+++ b/lisp/progmodes/prolog.el
@@ -512,7 +512,7 @@ to automatically indent if-then-else constructs."
:type 'boolean)
(defcustom prolog-electric-colon-flag nil
- "Makes `:' electric (inserts `:-' on a new line).
+ "Non-nil means make `:' electric (inserts `:-' on a new line).
If non-nil, pressing `:' at the end of a line that starts in
the first column (i.e., clause heads) inserts ` :-' and newline."
:version "24.1"
@@ -520,7 +520,7 @@ the first column (i.e., clause heads) inserts ` :-' and newline."
:type 'boolean)
(defcustom prolog-electric-dash-flag nil
- "Makes `-' electric (inserts a `-->' on a new line).
+ "Non-nil means make `-' electric (inserts a `-->' on a new line).
If non-nil, pressing `-' at the end of a line that starts in
the first column (i.e., DCG heads) inserts ` -->' and newline."
:version "24.1"
@@ -1272,7 +1272,7 @@ using the commands `send-region', `send-string' and \\[prolog-consult-region].
Commands:
Tab indents for Prolog; with argument, shifts rest
of expression rigidly with the current line.
-Paragraphs are separated only by blank lines and `%%'. `%'s start comments.
+Paragraphs are separated only by blank lines and `%%'. `%'s start comments.
Return at end of buffer sends line as input.
Return not at end copies rest of line to end and sends it.
@@ -1352,7 +1352,7 @@ the variable `prolog-prompt-regexp'."
(let ((pname (prolog-program-name))
(pswitches (prolog-program-switches)))
(if (null pname)
- (error "This Prolog system has defined no interpreter."))
+ (error "This Prolog system has defined no interpreter"))
(unless (comint-check-proc "*prolog*")
(with-current-buffer (get-buffer-create "*prolog*")
(prolog-inferior-mode)
@@ -1641,7 +1641,7 @@ region.
This function must be called from the source code buffer."
(if prolog-process-flag
- (error "Another Prolog task is running."))
+ (error "Another Prolog task is running"))
(prolog-ensure-process t)
(let* ((buffer (get-buffer-create prolog-compilation-buffer))
(real-file buffer-file-name)
@@ -2136,7 +2136,8 @@ A return value of N means N more left parentheses than right ones."
(line-end-position)))))
(defun prolog-electric--if-then-else ()
- "Insert spaces after the opening parenthesis, \"then\" (->) and \"else\" (;) branches.
+ "Insert spaces after the opening parenthesis.
+\"then\" (->) and \"else\" (;) branches.
Spaces are inserted if all preceding objects on the line are
whitespace characters, parentheses, or then/else branches."
(when prolog-electric-if-then-else-flag
@@ -2355,7 +2356,7 @@ In effect it sets the `fill-prefix' when inside comments and then calls
)
(if prolog-help-function-i
(funcall prolog-help-function-i predicate)
- (error "Sorry, no help method defined for this Prolog system."))))
+ (error "Sorry, no help method defined for this Prolog system"))))
))
@@ -2369,7 +2370,7 @@ In effect it sets the `fill-prefix' when inside comments and then calls
(pop-to-buffer nil)
(Info-goto-node prolog-info-predicate-index)
(if (not (re-search-forward str nil t))
- (error "Help on predicate `%s' not found." predicate))
+ (error "Help on predicate `%s' not found" predicate))
(setq oldp (point))
(if (re-search-forward str nil t)
@@ -2413,7 +2414,7 @@ This function is only available when `prolog-system' is set to `swi'."
(process-send-string "prolog" (concat "apropos(" string ").\n"))
(display-buffer "*prolog*"))
(t
- (error "Sorry, no Prolog apropos available for this Prolog system."))))
+ (error "Sorry, no Prolog apropos available for this Prolog system"))))
(defun prolog-atom-under-point ()
"Return the atom under or left to the point."
@@ -2483,11 +2484,8 @@ Interaction supports completion."
(if (eq (try-completion default prolog-info-alist) nil)
(setq default nil))
;; Read the PredSpec from the user
- (completing-read
- (if (zerop (length default))
- "Help on predicate: "
- (concat "Help on predicate (default " default "): "))
- prolog-info-alist nil t nil nil default)))
+ (completing-read (format-prompt "Help on predicate" default)
+ prolog-info-alist nil t nil nil default)))
(defun prolog-build-info-alist (&optional verbose)
"Build an alist of all builtins and library predicates.
@@ -3289,7 +3287,7 @@ PREFIX is the prefix of the search regexp."
(easy-menu-define
prolog-edit-menu-runtime prolog-mode-map
- "Runtime Prolog commands available from the editing buffer"
+ "Runtime Prolog commands available from the editing buffer."
;; FIXME: Don't use a whole menu for just "Run Mercury". --Stef
`("System"
;; Runtime menu name.
diff --git a/lisp/progmodes/ps-mode.el b/lisp/progmodes/ps-mode.el
index 67c034d0905..68c3cd91fa4 100644
--- a/lisp/progmodes/ps-mode.el
+++ b/lisp/progmodes/ps-mode.el
@@ -446,7 +446,7 @@ If nil, use `temporary-file-directory'."
ps-mode-submit-bug-report
t]))
-(easy-menu-define ps-mode-main ps-mode-map "PostScript" ps-mode-menu-main)
+(easy-menu-define ps-mode-main ps-mode-map "PostScript Menu." ps-mode-menu-main)
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 20299c20d28..b403de8b7a6 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -4,8 +4,8 @@
;; Author: Fabián E. Gallina <fgallina@gnu.org>
;; URL: https://github.com/fgallina/python.el
-;; Version: 0.27.1
-;; Package-Requires: ((emacs "24.2") (cl-lib "1.0"))
+;; Version: 0.28
+;; Package-Requires: ((emacs "24.4") (cl-lib "1.0"))
;; Maintainer: emacs-devel@gnu.org
;; Created: Jul 2010
;; Keywords: languages
@@ -542,7 +542,7 @@ the {...} holes that appear within f-strings."
(1 font-lock-function-name-face))
(,(rx symbol-start "class" (1+ space) (group (1+ (or word ?_))))
(1 font-lock-type-face)))
- "Font lock keywords to use in python-mode for level 1 decoration.
+ "Font lock keywords to use in `python-mode' for level 1 decoration.
This is the minimum decoration level, including function and
class declarations.")
@@ -555,9 +555,6 @@ class declarations.")
"assert" "else" "if" "pass" "yield" "break" "except" "import" "class"
"in" "raise" "continue" "finally" "is" "return" "def" "for" "lambda"
"try"
- ;; Python 2:
- "print" "exec"
- ;; Python 3:
;; False, None, and True are listed as keywords on the Python 3
;; documentation, but since they also qualify as constants they are
;; fontified like that in order to keep font-lock consistent between
@@ -596,7 +593,7 @@ class declarations.")
;; Extras:
"__all__")
symbol-end) . font-lock-builtin-face))
- "Font lock keywords to use in python-mode for level 2 decoration.
+ "Font lock keywords to use in `python-mode' for level 2 decoration.
This is the medium decoration level, including everything in
`python-font-lock-keywords-level-1', as well as keywords and
@@ -712,7 +709,7 @@ avoid '==' being treated as an assignment."
(or ")" "]") (* space)
assignment-operator))
(1 font-lock-variable-name-face)))
- "Font lock keywords to use in python-mode for maximum decoration.
+ "Font lock keywords to use in `python-mode' for maximum decoration.
This decoration level includes everything in
`python-font-lock-keywords-level-2', as well as constants,
@@ -726,7 +723,7 @@ decorators, exceptions, and assignments.")
; is more than 1, or t (which it is,
; by default).
)
- "List of font lock keyword specifications to use in python-mode.
+ "List of font lock keyword specifications to use in `python-mode'.
Which one will be chosen depends on the value of
`font-lock-maximum-decoration'.")
@@ -775,12 +772,21 @@ is used to limit the scan."
;; The first quote is escaped, so it's not part of a triple quote!
(goto-char (1+ quote-starting-pos)))
((null string-start)
- ;; This set of quotes delimit the start of a string.
- (put-text-property quote-starting-pos (1+ quote-starting-pos)
+ ;; This set of quotes delimit the start of a string. Put
+ ;; string fence syntax on last quote. (bug#49518)
+ ;; FIXME: This makes sexp-movement a bit suboptimal since """a"""
+ ;; is now treated as 3 strings.
+ ;; We could probably have our cake and eat it too by
+ ;; putting the string fence on the first quote and then
+ ;; convincing `syntax-ppss-flush-cache' to flush to before
+ ;; that fence when any char of the 3-char delimiter
+ ;; is modified.
+ (put-text-property (1- quote-ending-pos) quote-ending-pos
'syntax-table (string-to-syntax "|")))
(t
- ;; This set of quotes delimit the end of a string.
- (put-text-property (1- quote-ending-pos) quote-ending-pos
+ ;; This set of quotes delimit the end of a string. Put
+ ;; string fence syntax on first quote. (bug#49518)
+ (put-text-property quote-starting-pos (1+ quote-starting-pos)
'syntax-table (string-to-syntax "|"))))))
(defvar python-mode-syntax-table
@@ -1421,6 +1427,13 @@ marks the next defun after the ones already marked."
;;; Navigation
+(defcustom python-forward-sexp-function #'python-nav-forward-sexp
+ "Function to use when navigating between expressions."
+ :version "28.1"
+ :type '(choice (const :tag "Python blocks" python-nav-forward-sexp)
+ (const :tag "CC-mode like" nil)
+ function))
+
(defvar python-nav-beginning-of-defun-regexp
(python-rx line-start (* space) defun (+ space) (group symbol-name))
"Regexp matching class or function definition.
@@ -1512,7 +1525,10 @@ Returns nil if point is not in a def or class."
(python-util-forward-comment -1)
(forward-line 1)
;; Ensure point moves forward.
- (and (> beg-pos (point)) (goto-char beg-pos)))))
+ (and (> beg-pos (point)) (goto-char beg-pos))
+ ;; Return non-nil if we did something (because then we were in a
+ ;; def/class).
+ (/= beg-pos (point)))))
(defun python-nav--syntactically (fn poscompfn &optional contextfn)
"Move point using FN avoiding places with specific context.
@@ -2022,7 +2038,12 @@ position, else returns nil."
(cond ((executable-find "python3") "python3")
((executable-find "python") "python")
(t "python3"))
- "Default Python interpreter for shell."
+ "Default Python interpreter for shell.
+
+Some Python interpreters also require changes to
+`python-shell-interpreter-args'. In particular, setting
+`python-shell-interpreter' to \"ipython3\" requires setting
+`python-shell-interpreter-args' to \"--simple-prompt\"."
:version "28.1"
:type 'string
:group 'python)
@@ -2184,6 +2205,9 @@ virtualenv."
:type '(alist regexp)
:group 'python)
+(defvar python-shell-output-filter-in-progress nil)
+(defvar python-shell-output-filter-buffer nil)
+
(defmacro python-shell--add-to-path-with-priority (pathvar paths)
"Modify PATHVAR and ensure PATHS are added only once at beginning."
`(dolist (path (reverse ,paths))
@@ -2566,10 +2590,12 @@ the `buffer-name'."
(format
(concat
"import os.path;import sys;"
- "sys.path.append(os.path.dirname(os.path.dirname('''%s''')));"
- "__package__ = '''%s''';"
+ "sys.path.append(os.path.dirname(os.path.dirname(%s)));"
+ "__package__ = %s;"
"import %s")
- directory package package)
+ (python-shell--encode-string directory)
+ (python-shell--encode-string package)
+ package)
(python-shell-get-process)))
(defun python-shell-accept-process-output (process &optional timeout regexp)
@@ -2708,20 +2734,12 @@ goes wrong and syntax highlighting in the shell gets messed up."
(deactivate-mark nil)
(start-pos prompt-end)
(buffer-undo-list t)
- (font-lock-buffer-pos nil)
(replacement
(python-shell-font-lock-with-font-lock-buffer
- (delete-region (line-beginning-position)
- (point-max))
- (setq font-lock-buffer-pos (point))
+ (delete-region (point-min) (point-max))
(insert input)
- ;; Ensure buffer is fontified, keeping it
- ;; compatible with Emacs < 24.4.
- (if (fboundp 'font-lock-ensure)
- (funcall 'font-lock-ensure)
- (font-lock-default-fontify-buffer))
- (buffer-substring font-lock-buffer-pos
- (point-max))))
+ (font-lock-ensure)
+ (buffer-string)))
(replacement-length (length replacement))
(i 0))
;; Inject text properties to get input fontified.
@@ -2806,6 +2824,49 @@ eventually provide a shell."
:type 'hook
:group 'python)
+(defconst python-shell-eval-setup-code
+ "\
+def __PYTHON_EL_eval(source, filename):
+ import ast, sys
+ if sys.version_info[0] == 2:
+ from __builtin__ import compile, eval, globals
+ else:
+ from builtins import compile, eval, globals
+ try:
+ p, e = ast.parse(source, filename), None
+ except SyntaxError:
+ t, v, tb = sys.exc_info()
+ sys.excepthook(t, v, tb.tb_next)
+ return
+ if p.body and isinstance(p.body[-1], ast.Expr):
+ e = p.body.pop()
+ try:
+ g = globals()
+ exec(compile(p, filename, 'exec'), g, g)
+ if e:
+ return eval(compile(ast.Expression(e.value), filename, 'eval'), g, g)
+ except Exception:
+ t, v, tb = sys.exc_info()
+ sys.excepthook(t, v, tb.tb_next)"
+ "Code used to evaluate statements in inferior Python processes.")
+
+(defconst python-shell-eval-file-setup-code
+ "\
+def __PYTHON_EL_eval_file(filename, tempname, delete):
+ import codecs, os, re
+ pattern = r'^[ \t\f]*#.*?coding[:=][ \t]*([-_.a-zA-Z0-9]+)'
+ with codecs.open(tempname or filename, encoding='latin-1') as file:
+ match = re.match(pattern, file.readline())
+ match = match or re.match(pattern, file.readline())
+ encoding = match.group(1) if match else 'utf-8'
+ with codecs.open(tempname or filename, encoding=encoding) as file:
+ source = file.read().encode(encoding)
+ if delete and tempname:
+ os.remove(tempname)
+ return __PYTHON_EL_eval(source, filename)"
+ "Code used to evaluate files in inferior Python processes.
+The coding cookie regexp is specified in PEP 263.")
+
(defun python-shell-comint-watch-for-first-prompt-output-filter (output)
"Run `python-shell-first-prompt-hook' when first prompt is found in OUTPUT."
(when (not python-shell--first-prompt-received)
@@ -2821,6 +2882,15 @@ eventually provide a shell."
(setq python-shell--first-prompt-received-output-buffer nil)
(setq-local python-shell--first-prompt-received t)
(setq python-shell--first-prompt-received-output-buffer nil)
+ (cl-letf (((symbol-function 'python-shell-send-string)
+ (lambda (string process)
+ (comint-send-string
+ process
+ (format "exec(%s)\n" (python-shell--encode-string string))))))
+ ;; Bootstrap: the normal definition of `python-shell-send-string'
+ ;; depends on the Python code sent here.
+ (python-shell-send-string-no-output python-shell-eval-setup-code)
+ (python-shell-send-string-no-output python-shell-eval-file-setup-code))
(with-current-buffer (current-buffer)
(let ((inhibit-quit nil))
(run-hooks 'python-shell-first-prompt-hook))))))
@@ -2926,8 +2996,9 @@ killed."
(mapconcat #'identity args " ")))
(with-current-buffer buffer
(inferior-python-mode))
- (when show (display-buffer buffer))
(and internal (set-process-query-on-exit-flag process nil))))
+ (when show
+ (pop-to-buffer proc-buffer-name))
proc-buffer-name))))
;;;###autoload
@@ -2959,7 +3030,6 @@ process buffer for a list of commands.)"
(python-shell-make-comint
(or cmd (python-shell-calculate-command))
(python-shell-get-process-name dedicated) show)))
- (set-buffer buffer)
(get-buffer-process buffer)))
(defun run-python-internal ()
@@ -3010,13 +3080,12 @@ of `error' with a user-friendly message."
(or (python-shell-get-process)
(if interactivep
(user-error
- "Start a Python process first with `M-x run-python' or `%s'."
+ "Start a Python process first with `M-x run-python' or `%s'"
;; Get the binding.
(key-description
(where-is-internal
#'run-python overriding-local-map t)))
- (error
- "No inferior Python process running."))))
+ (error "No inferior Python process running"))))
(defun python-shell-get-or-create-process (&optional cmd dedicated show)
"Get or create an inferior Python process for current buffer and return it.
@@ -3072,10 +3141,24 @@ there for compatibility with CEDET.")
(temp-file-name (make-temp-file "py"))
(coding-system-for-write (python-info-encoding)))
(with-temp-file temp-file-name
- (insert string)
+ (if (bufferp string)
+ (insert-buffer-substring string)
+ (insert string))
(delete-trailing-whitespace))
temp-file-name))
+(defalias 'python-shell--encode-string
+ (let ((fun (if (and (fboundp 'json-serialize)
+ (>= emacs-major-version 28))
+ 'json-serialize
+ (require 'json)
+ 'json-encode-string)))
+ (lambda (text)
+ (if (stringp text)
+ (funcall fun text)
+ (signal 'wrong-type-argument (list 'stringp text)))))
+ "Encode TEXT as a valid Python string.")
+
(defun python-shell-send-string (string &optional process msg)
"Send STRING to inferior Python PROCESS.
When optional argument MSG is non-nil, forces display of a
@@ -3083,19 +3166,25 @@ user-friendly message if there's no process running; defaults to
t when called interactively."
(interactive
(list (read-string "Python command: ") nil t))
- (let ((process (or process (python-shell-get-process-or-error msg))))
- (if (string-match ".\n+." string) ;Multiline.
- (let* ((temp-file-name (with-current-buffer (process-buffer process)
- (python-shell--save-temp-file string)))
- (file-name (or (buffer-file-name) temp-file-name)))
- (python-shell-send-file file-name process temp-file-name t))
- (comint-send-string process string)
- (when (or (not (string-match "\n\\'" string))
- (string-match "\n[ \t].*\n?\\'" string))
- (comint-send-string process "\n")))))
-
-(defvar python-shell-output-filter-in-progress nil)
-(defvar python-shell-output-filter-buffer nil)
+ (let ((process (or process (python-shell-get-process-or-error msg)))
+ (code (format "__PYTHON_EL_eval(%s, %s)\n"
+ (python-shell--encode-string string)
+ (python-shell--encode-string (or (buffer-file-name)
+ "<string>")))))
+ (unless python-shell-output-filter-in-progress
+ (with-current-buffer (process-buffer process)
+ (save-excursion
+ (goto-char (process-mark process))
+ (insert-before-markers "\n"))))
+ (if (or (null (process-tty-name process))
+ (<= (string-bytes code)
+ (or (bound-and-true-p comint-max-line-length)
+ 1024))) ;; For Emacs < 28
+ (comint-send-string process code)
+ (let* ((temp-file-name (with-current-buffer (process-buffer process)
+ (python-shell--save-temp-file string)))
+ (file-name (or (buffer-file-name) temp-file-name)))
+ (python-shell-send-file file-name process temp-file-name t)))))
(defun python-shell-output-filter (string)
"Filter used in `python-shell-send-string-no-output' to grab output.
@@ -3334,11 +3423,15 @@ t when called interactively."
(defun python-shell-send-file (file-name &optional process temp-file-name
delete msg)
"Send FILE-NAME to inferior Python PROCESS.
+
If TEMP-FILE-NAME is passed then that file is used for processing
instead, while internally the shell will continue to use
-FILE-NAME. If TEMP-FILE-NAME and DELETE are non-nil, then
-TEMP-FILE-NAME is deleted after evaluation is performed. When
-optional argument MSG is non-nil, forces display of a
+FILE-NAME. FILE-NAME can be remote, but TEMP-FILE-NAME must be
+in the same host as PROCESS. If TEMP-FILE-NAME and DELETE are
+non-nil, then TEMP-FILE-NAME is deleted after evaluation is
+performed.
+
+When optional argument MSG is non-nil, forces display of a
user-friendly message if there's no process running; defaults to
t when called interactively."
(interactive
@@ -3348,27 +3441,26 @@ t when called interactively."
nil ; temp-file-name
nil ; delete
t)) ; msg
- (let* ((process (or process (python-shell-get-process-or-error msg)))
- (encoding (with-temp-buffer
- (insert-file-contents
- (or temp-file-name file-name))
- (python-info-encoding)))
- (file-name (file-local-name (expand-file-name file-name)))
+ (setq process (or process (python-shell-get-process-or-error msg)))
+ (with-current-buffer (process-buffer process)
+ (unless (or temp-file-name
+ (string= (file-remote-p file-name)
+ (file-remote-p default-directory)))
+ (setq delete t
+ temp-file-name (with-temp-buffer
+ (insert-file-contents file-name)
+ (python-shell--save-temp-file (current-buffer))))))
+ (let* ((file-name (file-local-name (expand-file-name file-name)))
(temp-file-name (when temp-file-name
(file-local-name (expand-file-name
temp-file-name)))))
- (python-shell-send-string
+ (comint-send-string
+ process
(format
- (concat
- "import codecs, os;"
- "__pyfile = codecs.open('''%s''', encoding='''%s''');"
- "__code = __pyfile.read().encode('''%s''');"
- "__pyfile.close();"
- (when (and delete temp-file-name)
- (format "os.remove('''%s''');" temp-file-name))
- "exec(compile(__code, '''%s''', 'exec'));")
- (or temp-file-name file-name) encoding encoding file-name)
- process)))
+ "__PYTHON_EL_eval_file(%s, %s, %s)\n"
+ (python-shell--encode-string file-name)
+ (python-shell--encode-string (or temp-file-name ""))
+ (if delete "True" "False")))))
(defun python-shell-switch-to-shell (&optional msg)
"Switch to inferior Python process buffer.
@@ -3470,23 +3562,14 @@ def __PYTHON_EL_get_completions(text):
"25.1"
"Completion string code must work for (i)pdb.")
-(defcustom python-shell-completion-string-code
- "';'.join(__PYTHON_EL_get_completions('''%s'''))"
- "Python code used to get a string of completions separated by semicolons.
-The string passed to the function is the current python name or
-the full statement in the case of imports."
- :type 'string
- :group 'python)
-
(defcustom python-shell-completion-native-disabled-interpreters
;; PyPy's readline cannot handle some escape sequences yet. Native
- ;; completion was found to be non-functional for IPython (see
- ;; Bug#25067). Native completion doesn't work on w32 (Bug#28580).
+ ;; completion doesn't work on w32 (Bug#28580).
(if (eq system-type 'windows-nt) '("")
- '("pypy" "ipython"))
+ '("pypy"))
"List of disabled interpreters.
When a match is found, native completion is disabled."
- :version "25.1"
+ :version "28.1"
:type '(repeat string))
(defcustom python-shell-completion-native-enable t
@@ -3522,13 +3605,12 @@ When a match is found, native completion is disabled."
python-shell-completion-native-try-output-timeout))
(python-shell-completion-native-get-completions
(get-buffer-process (current-buffer))
- nil "_")))
+ "_")))
(defun python-shell-completion-native-setup ()
"Try to setup native completion, return non-nil on success."
- (let ((process (python-shell-get-process)))
- (with-current-buffer (process-buffer process)
- (python-shell-send-string "
+ (let* ((process (python-shell-get-process))
+ (output (python-shell-send-string-no-output "
def __PYTHON_EL_native_completion_setup():
try:
import readline
@@ -3631,6 +3713,8 @@ def __PYTHON_EL_native_completion_setup():
readline.parse_and_bind('tab: complete')
# Require just one tab to send output.
readline.parse_and_bind('set show-all-if-ambiguous on')
+ # Avoid replacing common prefix with ellipsis.
+ readline.parse_and_bind('set completion-prefix-display-length 0')
print ('python.el: native completion setup loaded')
except:
@@ -3638,14 +3722,10 @@ def __PYTHON_EL_native_completion_setup():
print ('python.el: native completion setup failed, %s: %s'
% sys.exc_info()[:2])
-__PYTHON_EL_native_completion_setup()" process)
- (when (and
- (python-shell-accept-process-output
- process python-shell-completion-native-try-output-timeout)
- (save-excursion
- (re-search-backward
- (regexp-quote "python.el: native completion setup loaded") nil t 1)))
- (python-shell-completion-native-try)))))
+__PYTHON_EL_native_completion_setup()" process)))
+ (when (string-match-p "python\\.el: native completion setup loaded"
+ output)
+ (python-shell-completion-native-try))))
(defun python-shell-completion-native-turn-off (&optional msg)
"Turn off shell native completions.
@@ -3685,7 +3765,8 @@ With argument MSG show activation/deactivation message."
(format "was t and %S is not part of the "
(file-name-nondirectory python-shell-interpreter))
"`python-shell-completion-native-disabled-interpreters' "
- "list. Native completions have been disabled locally. "))
+ "list. Native completions have been disabled locally. "
+ "Consider installing the python package \"readline\". "))
(python-shell-completion-native-turn-off msg))))))
(defun python-shell-completion-native-turn-on-maybe-with-msg ()
@@ -3705,13 +3786,10 @@ With argument MSG show activation/deactivation message."
(python-shell-completion-native-turn-on msg))
python-shell-completion-native-enable))
-(defun python-shell-completion-native-get-completions (process import input)
- "Get completions using native readline for PROCESS.
-When IMPORT is non-nil takes precedence over INPUT for
-completion."
+(defun python-shell-completion-native-get-completions (process input)
+ "Get completions of INPUT using native readline for PROCESS."
(with-current-buffer (process-buffer process)
- (let* ((input (or import input))
- (original-filter-fn (process-filter process))
+ (let* ((original-filter-fn (process-filter process))
(redirect-buffer (get-buffer-create
python-shell-completion-native-redirect-buffer))
(trigger "\t")
@@ -3735,7 +3813,7 @@ completion."
(comint-redirect-perform-sanity-check nil)
(comint-redirect-insert-matching-regexp t)
(comint-redirect-finished-regexp
- "1__dummy_completion__[[:space:]]*\n")
+ "1__dummy_completion__.*\n")
(comint-redirect-output-buffer redirect-buffer))
;; Compatibility with Emacs 24.x. Comint changed and
;; now `comint-redirect-filter' gets 3 args. This
@@ -3763,23 +3841,24 @@ completion."
:test #'string=))))
(set-process-filter process original-filter-fn)))))
-(defun python-shell-completion-get-completions (process import input)
- "Do completion at point using PROCESS for IMPORT or INPUT.
-When IMPORT is non-nil takes precedence over INPUT for
-completion."
- (setq input (or import input))
+(defun python-shell-completion-get-completions (process input)
+ "Get completions of INPUT using PROCESS."
(with-current-buffer (process-buffer process)
(let ((completions
(python-util-strip-string
(python-shell-send-string-no-output
(format
- (concat python-shell-completion-setup-code
- "\nprint (" python-shell-completion-string-code ")")
- input) process))))
+ "%s\nprint(';'.join(__PYTHON_EL_get_completions(%s)))"
+ python-shell-completion-setup-code
+ (python-shell--encode-string input))
+ process))))
(when (> (length completions) 2)
(split-string completions
"^'\\|^\"\\|;\\|'$\\|\"$" t)))))
+(defvar-local python-shell--capf-cache nil
+ "Variable to store cached completions and invalidation keys.")
+
(defun python-shell-completion-at-point (&optional process)
"Function for `completion-at-point-functions' in `inferior-python-mode'.
Optional argument PROCESS forces completions to be retrieved
@@ -3833,12 +3912,21 @@ using that one instead of current buffer's process."
;; it during a multiline statement (Bug#28051).
#'ignore
#'python-shell-completion-get-completions))
- (t #'python-shell-completion-native-get-completions)))))
- (list start end
- (completion-table-dynamic
- (apply-partially
- completion-fn
- process import-statement)))))
+ (t #'python-shell-completion-native-get-completions))))
+ (prev-prompt (car python-shell--capf-cache))
+ (re (or (cadr python-shell--capf-cache) regexp-unmatchable))
+ (prefix (buffer-substring-no-properties start end)))
+ ;; To invalidate the cache, we check if the prompt position or the
+ ;; completion prefix changed.
+ (unless (and (equal prev-prompt (car prompt-boundaries))
+ (string-match re prefix))
+ (setq python-shell--capf-cache
+ `(,(car prompt-boundaries)
+ ,(if (string-empty-p prefix)
+ regexp-unmatchable
+ (concat "\\`" (regexp-quote prefix) "\\(?:\\sw\\|\\s_\\)*\\'"))
+ ,@(funcall completion-fn process (or import-statement prefix)))))
+ (list start end (cddr python-shell--capf-cache))))
(define-obsolete-function-alias
'python-shell-completion-complete-at-point
@@ -4231,6 +4319,7 @@ JUSTIFY should be used (if applicable) as in `fill-paragraph'."
(and (equal (string-to-syntax "|")
(syntax-after (point)))
(point)))))
+ ;; JT@2021-09-21: Since bug#49518's fix this will always be 1
(num-quotes (python-syntax-count-quotes
(char-after str-start-pos) str-start-pos))
(str-line-start-pos
@@ -4498,28 +4587,16 @@ def __FFAP_get_module_path(objstr):
:type 'string
:group 'python)
-(defcustom python-ffap-string-code
- "__FFAP_get_module_path('''%s''')"
- "Python code used to get a string with the path of a module."
- :type 'string
- :group 'python)
-
(defun python-ffap-module-path (module)
"Function for `ffap-alist' to return path for MODULE."
- (let ((process (or
- (and (derived-mode-p 'inferior-python-mode)
- (get-buffer-process (current-buffer)))
- (python-shell-get-process))))
- (if (not process)
- nil
- (let ((module-file
- (python-shell-send-string-no-output
- (concat
- python-ffap-setup-code
- "\nprint (" (format python-ffap-string-code module) ")")
- process)))
- (unless (zerop (length module-file))
- (python-util-strip-string module-file))))))
+ (when-let ((process (python-shell-get-process))
+ (module-file
+ (python-shell-send-string-no-output
+ (format "%s\nprint(__FFAP_get_module_path(%s))"
+ python-ffap-setup-code
+ (python-shell--encode-string module)))))
+ (unless (string-empty-p module-file)
+ (python-util-strip-string module-file))))
(defvar ffap-alist)
@@ -4596,7 +4673,10 @@ See `python-check-command' for the default."
target = obj
objtype = 'def'
if target:
- args = inspect.formatargspec(*argspec_function(target))
+ if hasattr(inspect, 'signature'):
+ args = str(inspect.signature(target))
+ else:
+ args = inspect.formatargspec(*argspec_function(target))
name = obj.__name__
doc = '{objtype} {name}{args}'.format(
objtype=objtype, name=name, args=args
@@ -4610,12 +4690,6 @@ See `python-check-command' for the default."
:type 'string
:group 'python)
-(defcustom python-eldoc-string-code
- "__PYDOC_get_help('''%s''')"
- "Python code used to get a string with the documentation of an object."
- :type 'string
- :group 'python)
-
(defun python-eldoc--get-symbol-at-point ()
"Get the current symbol for eldoc.
Returns the current symbol handling point within arguments."
@@ -4645,18 +4719,19 @@ returns will be used. If not FORCE-PROCESS is passed what
;; enabled. Bug#18794.
(python-util-strip-string
(python-shell-send-string-no-output
- (concat
+ (format
+ "%s\nprint(__PYDOC_get_help(%s))"
python-eldoc-setup-code
- "\nprint(" (format python-eldoc-string-code input) ")")
+ (python-shell--encode-string input))
process)))))
- (unless (zerop (length docstring))
+ (unless (string-empty-p docstring)
docstring)))))
(defvar-local python-eldoc-get-doc t
- "Non-nil means eldoc should fetch the documentation
- automatically. Set to nil by `python-eldoc-function' if
- `python-eldoc-function-timeout-permanent' is non-nil and
- `python-eldoc-function' times out.")
+ "Non-nil means eldoc should fetch the documentation automatically.
+Set to nil by `python-eldoc-function' if
+`python-eldoc-function-timeout-permanent' is non-nil and
+`python-eldoc-function' times out.")
(defcustom python-eldoc-function-timeout 1
"Timeout for `python-eldoc-function' in seconds."
@@ -4700,8 +4775,14 @@ Interactively, prompt for symbol."
(interactive
(let ((symbol (python-eldoc--get-symbol-at-point))
(enable-recursive-minibuffers t))
- (list (read-string (format-prompt "Describe symbol" symbol)
- nil nil symbol))))
+ (list (read-string
+ ;; `format-prompt' is new in Emacs 28.1.
+ (if (fboundp 'format-prompt)
+ (format-prompt "Describe symbol" symbol)
+ (if symbol
+ (format "Describe symbol (default %s): " symbol)
+ "Describe symbol: "))
+ nil nil symbol))))
(message (python-eldoc--get-doc-at-point symbol)))
(defun python-describe-at-point (symbol process)
@@ -4712,10 +4793,9 @@ Interactively, prompt for symbol."
;;; Hideshow
-(defun python-hideshow-forward-sexp-function (arg)
+(defun python-hideshow-forward-sexp-function (_arg)
"Python specific `forward-sexp' function for `hs-minor-mode'.
Argument ARG is ignored."
- arg ; Shut up, byte compiler.
(python-nav-end-of-defun)
(unless (python-info-current-line-empty-p)
(backward-char)))
@@ -5499,13 +5579,6 @@ By default messages are considered errors."
:type '(alist :key-type (regexp)
:value-type (symbol)))
-(defcustom python-forward-sexp-function #'python-nav-forward-sexp
- "Function to use when navigating between expressions."
- :version "28.1"
- :type '(choice (const :tag "Python blocks" python-nav-forward-sexp)
- (const :tag "CC-mode like" nil)
- function))
-
(defvar-local python--flymake-proc nil)
(defun python--flymake-parse-output (source proc report-fn)
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index c09f007a5ee..b0b055bd361 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -151,10 +151,8 @@ This should only be called after matching against `ruby-here-doc-beg-re'."
map)
"Keymap used in Ruby mode.")
-(easy-menu-define
- ruby-mode-menu
- ruby-mode-map
- "Ruby Mode Menu"
+(easy-menu-define ruby-mode-menu ruby-mode-map
+ "Ruby Mode Menu."
'("Ruby"
["Beginning of Block" ruby-beginning-of-block t]
["End of Block" ruby-end-of-block t]
@@ -640,7 +638,15 @@ It is used when `ruby-encoding-magic-comment-style' is set to `custom'."
('(:before . "do") (ruby-smie--indent-to-stmt))
('(:before . ".")
(if (smie-rule-sibling-p)
- (and ruby-align-chained-calls 0)
+ (when ruby-align-chained-calls
+ (while
+ (let ((pos (point))
+ (parent (smie-backward-sexp ".")))
+ (if (not (equal (nth 2 parent) "."))
+ (progn (goto-char pos) nil)
+ (goto-char (nth 1 parent))
+ (not (smie-rule-bolp)))))
+ (cons 'column (current-column)))
(smie-backward-sexp ".")
(cons 'column (+ (current-column)
ruby-indent-level))))
@@ -828,6 +834,7 @@ The style of the comment is controlled by `ruby-encoding-magic-comment-style'."
;; `ruby-calculate-indent' in user init files still call it.
(defun ruby-current-indentation ()
"Return the indentation level of current line."
+ (declare (obsolete current-indentation "28.1"))
(save-excursion
(beginning-of-line)
(back-to-indentation)
@@ -927,7 +934,7 @@ Can be one of `heredoc', `modifier', `expr-qstr', `expr-re'."
(defun ruby-forward-string (term &optional end no-error expand)
"Move forward across one balanced pair of string delimiters.
-Skips escaped delimiters. If EXPAND is non-nil, also ignores
+Skips escaped delimiters. If EXPAND is non-nil, also ignores
delimiters in interpolated strings.
TERM should be a string containing either a single, self-matching
diff --git a/lisp/progmodes/scheme.el b/lisp/progmodes/scheme.el
index 57351a7308d..abcdcb3349e 100644
--- a/lisp/progmodes/scheme.el
+++ b/lisp/progmodes/scheme.el
@@ -143,7 +143,6 @@
(setq-local comment-start-skip ";+[ \t]*")
(setq-local comment-use-syntax t)
(setq-local comment-column 40)
- (setq-local parse-sexp-ignore-comments t)
(setq-local lisp-indent-function 'scheme-indent-function)
(setq mode-line-process '("" scheme-mode-line-process))
(setq-local imenu-case-fold-search t)
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index b6674731ddf..c6b6f83471d 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -628,7 +628,8 @@ removed when closing the here document."
(wksh sh-append ksh88)
(zsh sh-append ksh88
- "autoload" "bindkey" "builtin" "chdir" "compctl" "declare" "dirs"
+ "autoload" "always"
+ "bindkey" "builtin" "chdir" "compctl" "declare" "dirs"
"disable" "disown" "echotc" "enable" "functions" "getln" "hash"
"history" "integer" "limit" "local" "log" "popd" "pushd" "r"
"readonly" "rehash" "sched" "setopt" "source" "suspend" "true"
@@ -1396,8 +1397,15 @@ If FORCE is non-nil and no process found, create one."
(or found
(and force
(get-buffer-process
- (let ((explicit-shell-file-name sh-shell-file))
- (shell)))))))))
+ (let ((explicit-shell-file-name sh-shell-file)
+ (display-buffer-overriding-action
+ '(nil . ((inhibit-same-window . t)))))
+ ;; We must prevent this `(shell)' call from
+ ;; switching buffers, so that the variable
+ ;; `sh-shell-process' is set locally in the
+ ;; correct buffer.
+ (save-current-buffer
+ (shell))))))))))
(defun sh-show-shell ()
"Pop the shell interaction buffer."
@@ -1775,7 +1783,7 @@ Does not preserve point."
(goto-char p)
nil))))
(while
- (progn (skip-syntax-backward "w_'")
+ (progn (skip-syntax-backward ".w_'")
(or (not (zerop (skip-syntax-backward "\\")))
(when (eq ?\\ (char-before (1- (point))))
(let ((p (point)))
@@ -2193,7 +2201,7 @@ Point should be before the newline."
When used interactively, insert the proper starting #!-line,
and make the visited file executable via `executable-set-magic',
perhaps querying depending on the value of `executable-query'.
-(If given a prefix (i.e., `C-u') don't insert any starting #!
+(If given a prefix (i.e., `\\[universal-argument]') don't insert any starting #!
line.)
When this function is called noninteractively, INSERT-FLAG (the third
@@ -2515,7 +2523,7 @@ overwritten if
sh-styles-alist nil t)))
(let ((sl (assoc name sh-styles-alist)))
(if (null sl)
- (error "sh-load-style - style %s not known" name)
+ (error "sh-load-style: Style %s not known" name)
(dolist (var (cdr sl))
(set (car var) (cdr var))))))
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el
index d144d68b571..f5888a0ce7a 100644
--- a/lisp/progmodes/sql.el
+++ b/lisp/progmodes/sql.el
@@ -481,9 +481,9 @@ file. Since that is a plaintext file, this could be dangerous."
:list-all ("\\d+" . "\\dS+")
:list-table ("\\d+ %s" . "\\dS+ %s")
:completion-object sql-postgres-completion-object
- :prompt-regexp "^[[:alnum:]_]*=[#>] "
+ :prompt-regexp "^[-[:alnum:]_]*[-=][#>] "
:prompt-length 5
- :prompt-cont-regexp "^[[:alnum:]_]*[-(][#>] "
+ :prompt-cont-regexp "^[-[:alnum:]_]*[-'(][#>] "
:statement sql-postgres-statement-starters
:input-filter sql-remove-tabs-filter
:terminator ("\\(^\\s-*\\\\g\\|;\\)" . "\\g"))
@@ -700,8 +700,17 @@ making new SQLi sessions."
(sexp :tag "Value Expression")))))
:version "24.1")
-(defvaralias 'sql-dialect 'sql-product)
+(defun sql-add-connection (connection params)
+ "Add a new connection to `sql-connection-alist'.
+If CONNECTION already exists, it is replaced with PARAMS."
+ (setq sql-connection-alist
+ (assoc-delete-all connection sql-connection-alist))
+ (push
+ (cons connection params)
+ sql-connection-alist))
+
+(defvaralias 'sql-dialect 'sql-product)
(defcustom sql-product 'ansi
"Select the SQL database product used.
This allows highlighting buffers properly when you open them."
@@ -963,12 +972,7 @@ If set to \"\\n\", each line in the history file will be interpreted as
one command. Multi-line commands are split into several commands when
the input ring is initialized from a history file.
-This variable used to initialize `comint-input-ring-separator'.
-`comint-input-ring-separator' is part of Emacs 21; if your Emacs
-does not have it, setting `sql-input-ring-separator' will have no
-effect. In that case multiline commands will be split into several
-commands when the input history is read, as if you had set
-`sql-input-ring-separator' to \"\\n\"."
+This variable used to initialize `comint-input-ring-separator'."
:type 'string)
;; The usual hooks
@@ -1357,8 +1361,6 @@ specified, it's `sql-product' or `sql-connection' must match."
(defvar sql-interactive-mode-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map comint-mode-map)
- (if (fboundp 'set-keymap-name)
- (set-keymap-name map 'sql-interactive-mode-map)); XEmacs
(define-key map (kbd "C-j") 'sql-accumulate-and-indent)
(define-key map (kbd "C-c C-w") 'sql-copy-column)
(define-key map (kbd "O") 'sql-magic-go)
@@ -2794,7 +2796,7 @@ See `sql-product-alist' for a list of products and supported features."
(symbolp v))
(symbol-value v)
v))
- (error "`%s' is not a known product; use `sql-add-product' to add it first." product)
+ (error "`%s' is not a known product; use `sql-add-product' to add it first" product)
nil)))
(defun sql-product-font-lock (keywords-only imenu)
@@ -2832,16 +2834,6 @@ configured."
(font-lock-mode-internal nil)
(font-lock-mode-internal t))
- (add-hook 'font-lock-mode-hook
- (lambda ()
- ;; Provide defaults for new font-lock faces.
- (defvar font-lock-builtin-face
- (if (boundp 'font-lock-preprocessor-face)
- font-lock-preprocessor-face
- font-lock-keyword-face))
- (defvar font-lock-doc-face font-lock-string-face))
- nil t)
-
;; Setup imenu; it needs the same syntax-alist.
(when imenu
(setq imenu-syntax-alist syntax-alist))))
@@ -2952,7 +2944,7 @@ adds a fontification pattern to fontify identifiers ending in
"Display a SQLi buffer based on `sql-display-sqli-buffer-function'.
If BUF is hidden or `sql-display-sqli-buffer-function' is nil,
-then the buffer will not be displayed. Otherwise the BUF is
+then the buffer will not be displayed. Otherwise the BUF is
displayed."
(unless (sql-buffer-hidden-p buf)
(cond
@@ -3219,14 +3211,7 @@ For both `:file' and `:completion', there can also be a
symbol
(let* ((default (plist-get plist :default))
(last-value (sql-default-value symbol))
- (prompt-def
- (if default
- (if (string-match "\\(\\):[ \t]*\\'" prompt)
- (replace-match (format " (default \"%s\")" default) t t prompt 1)
- (replace-regexp-in-string "[ \t]*\\'"
- (format " (default \"%s\") " default)
- prompt t t))
- prompt))
+ (prompt-def (format-prompt prompt default))
(use-dialog-box nil))
(cond
((plist-member plist :file)
@@ -3311,7 +3296,7 @@ function like this: (sql-get-login \\='user \\='password \\='database)."
(let ((plist (cdr-safe w)))
(pcase (or (car-safe w) w)
('user
- (sql-get-login-ext 'sql-user "User: " 'sql-user-history plist))
+ (sql-get-login-ext 'sql-user "User" 'sql-user-history plist))
('password
(setq-default sql-password
@@ -3330,14 +3315,14 @@ function like this: (sql-get-login \\='user \\='password \\='database)."
(read-passwd "Password: " nil (sql-default-value 'sql-password)))))
('server
- (sql-get-login-ext 'sql-server "Server: " 'sql-server-history plist))
+ (sql-get-login-ext 'sql-server "Server" 'sql-server-history plist))
('database
- (sql-get-login-ext 'sql-database "Database: "
+ (sql-get-login-ext 'sql-database "Database"
'sql-database-history plist))
('port
- (sql-get-login-ext 'sql-port "Port: "
+ (sql-get-login-ext 'sql-port "Port"
nil (append '(:number t) plist)))))))
(defun sql-find-sqli-buffer (&optional product connection)
@@ -3976,13 +3961,13 @@ for each match."
(cond
((numberp c) (match-string c))
((stringp c) (match-substitute-replacement c))
- (t (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s" c))))
+ (t (error "sql-redirect-value: Unknown REGEXP-GROUPS value - %s" c))))
regexp-groups))
;; String is specified; return replacement string
((stringp regexp-groups)
(match-substitute-replacement regexp-groups))
(t
- (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s"
+ (error "sql-redirect-value: Unknown REGEXP-GROUPS value - %s"
regexp-groups)))
results)))
@@ -4182,10 +4167,6 @@ must tell Emacs. Here's how to do that in your init file:
(modify-syntax-entry ?\\\\ \"\\\\\" sql-mode-syntax-table)))"
:abbrev-table sql-mode-abbrev-table
- (when (and (featurep 'xemacs)
- sql-mode-menu)
- (easy-menu-add sql-mode-menu))
-
;; (smie-setup sql-smie-grammar #'sql-smie-rules)
(setq-local comment-start "--")
;; Make each buffer in sql-mode remember the "current" SQLi buffer.
@@ -4308,9 +4289,6 @@ you entered, right above the output it created.
(setq mode-name
(concat "SQLi[" (or (sql-get-product-feature sql-product :name)
(symbol-name sql-product)) "]"))
- (when (and (featurep 'xemacs)
- sql-interactive-mode-menu)
- (easy-menu-add sql-interactive-mode-menu))
;; Note that making KEYWORDS-ONLY nil will cause havoc if you try
;; SELECT 'x' FROM DUAL with SQL*Plus, because the title of the column
@@ -4681,6 +4659,14 @@ the call to \\[sql-product-interactive] with
(get-buffer new-sqli-buffer)))))
(user-error "No default SQL product defined: set `sql-product'")))
+(defun sql-comint-automatic-password (_)
+ "Intercept password prompts when we know the password.
+This must also do the job of detecting password prompts."
+ (when (and
+ sql-password
+ (not (string= "" sql-password)))
+ sql-password))
+
(defun sql-comint (product params &optional buf-name)
"Set up a comint buffer to run the SQL processor.
@@ -4705,6 +4691,13 @@ buffer. If nil, a name is chosen for it."
(setq buf-name (sql-generate-unique-sqli-buffer-name product nil)))
(set-text-properties 0 (length buf-name) nil buf-name)
+ ;; Create the buffer first, because we want to set it up before
+ ;; comint starts to run.
+ (set-buffer (get-buffer-create buf-name))
+ ;; Set up the automatic population of passwords, if supported.
+ (when (sql-get-product-feature product :password-in-comint)
+ (setq comint-password-function #'sql-comint-automatic-password))
+
;; Start the command interpreter in the buffer
;; PROC-NAME is BUF-NAME without enclosing asterisks
(let ((proc-name (replace-regexp-in-string "\\`[*]\\(.*\\)[*]\\'" "\\1" buf-name)))
diff --git a/lisp/progmodes/tcl.el b/lisp/progmodes/tcl.el
index f6a50bf1a88..b6a7a20d87f 100644
--- a/lisp/progmodes/tcl.el
+++ b/lisp/progmodes/tcl.el
@@ -288,7 +288,7 @@ quoted for Tcl."
["Tcl help" tcl-help-on-word tcl-help-directory-list]))
(defvar inferior-tcl-buffer nil
- "The current inferior-tcl process buffer.
+ "The current `inferior-tcl' process buffer.
MULTIPLE PROCESS SUPPORT
===========================================================================
diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el
index 7c8ccea065e..14f252b42d4 100644
--- a/lisp/progmodes/verilog-mode.el
+++ b/lisp/progmodes/verilog-mode.el
@@ -1,15 +1,15 @@
-;;; verilog-mode.el --- major mode for editing verilog source in Emacs
+;;; verilog-mode.el --- major mode for editing verilog source in Emacs -*- lexical-binding: t; -*-
;; Copyright (C) 1996-2021 Free Software Foundation, Inc.
;; Author: Michael McNamara <mac@verilog.com>
;; Wilson Snyder <wsnyder@wsnyder.org>
-;; X-URL: https://www.veripool.org
+;; URL: https://www.veripool.org
;; Created: 3 Jan 1996
;; Keywords: languages
;; The "Version" is the date followed by the decimal rendition of the Git
;; commit hex.
-;; Version: 2021.04.12.188864585
+;; Version: 2021.10.14.127365406
;; Yoni Rabkin <yoni@rabkins.net> contacted the maintainer of this
;; file on 19/3/2008, and the maintainer agreed that when a bug is
@@ -87,7 +87,7 @@
;;
;; If you want to customize Verilog mode to fit your needs better,
;; you may add the below lines (the values of the variables presented
-;; here are the defaults). Note also that if you use an Emacs that
+;; here are the defaults). Note also that if you use an Emacs that
;; supports custom, it's probably better to use the custom menu to
;; edit these. If working as a member of a large team these settings
;; should be common across all users (in a site-start file), or set
@@ -124,7 +124,7 @@
;;
;; This variable will always hold the version number of the mode
-(defconst verilog-mode-version "2021-04-12-b41d849-vpo-GNU"
+(defconst verilog-mode-version "2021-10-14-797711e-vpo-GNU"
"Version of this Verilog mode.")
(defconst verilog-mode-release-emacs t
"If non-nil, this version of Verilog mode was released with Emacs itself.")
@@ -414,7 +414,7 @@ wherever possible, since it is slow."
;; "----" ["MB" nil :help "Help MB"]))
(defun verilog-define-abbrev-table (tablename definitions &optional docstring &rest props)
- "Filter `define-abbrev-table' TABLENAME DEFINITIONS
+ "Filter `define-abbrev-table' TABLENAME DEFINITIONS.
Provides DOCSTRING PROPS in newer Emacs (23.1)."
(condition-case nil
(apply #'define-abbrev-table tablename definitions docstring props)
@@ -591,19 +591,19 @@ If `all' is selected, then all line ups described below are done.
If `declarations', then just declarations are lined up with any
preceding declarations, taking into account widths and the like,
so or example the code:
- reg [31:0] a;
- reg b;
+ reg [31:0] a;
+ reg b;
would become
- reg [31:0] a;
- reg b;
+ reg [31:0] a;
+ reg b;
If `assignment', then assignments are lined up with any preceding
assignments, so for example the code
- a_long_variable <= b + c;
- d = e + f;
+ a_long_variable <= b + c;
+ d = e + f;
would become
- a_long_variable <= b + c;
- d = e + f;
+ a_long_variable <= b + c;
+ d = e + f;
In order to speed up editing, large blocks of statements are lined up
only when a \\[verilog-pretty-expr] is typed; and large blocks of declarations
@@ -641,13 +641,13 @@ Set to 0 to get them list right under containing block."
(defcustom verilog-indent-declaration-macros nil
"How to treat macro expansions in a declaration.
If nil, indent as:
- input [31:0] a;
- input \\=`CP;
- output c;
+ input [31:0] a;
+ input \\=`CP;
+ output c;
If non-nil, treat as:
- input [31:0] a;
- input \\=`CP ;
- output c;"
+ input [31:0] a;
+ input \\=`CP ;
+ output c;"
:group 'verilog-mode-indent
:type 'boolean)
(put 'verilog-indent-declaration-macros 'safe-local-variable #'verilog-booleanp)
@@ -655,12 +655,12 @@ If non-nil, treat as:
(defcustom verilog-indent-lists t
"How to treat indenting items in a list.
If t (the default), indent as:
- always @( posedge a or
- reset ) begin
+ always @( posedge a or
+ reset ) begin
If nil, treat as:
- always @( posedge a or
- reset ) begin"
+ always @( posedge a or
+ reset ) begin"
:group 'verilog-mode-indent
:type 'boolean)
(put 'verilog-indent-lists 'safe-local-variable #'verilog-booleanp)
@@ -829,7 +829,7 @@ The name of the function or case will be set between the braces."
(defcustom verilog-auto-ignore-concat nil
"Non-nil means ignore signals in {...} concatenations for AUTOWIRE etc.
This will exclude signals referenced as pin connections in {...}
-or (...) from AUTOWIRE, AUTOOUTPUT and friends."
+or (...) from AUTOWIRE, AUTOOUTPUT and friends. See also AUTONOHOOKUP."
:group 'verilog-mode-actions
:type 'boolean)
(put 'verilog-auto-ignore-concat 'safe-local-variable #'verilog-booleanp)
@@ -1264,7 +1264,9 @@ See `verilog-auto-inst-param-value'."
Also affects AUTOINSTPARAM. Declaration order is the default for
backward compatibility, and as some teams prefer signals that are
declared together to remain together. Sorted order reduces
-changes when declarations are moved around in a file.
+changes when declarations are moved around in a file. Sorting is
+within input/output/inout groupings, there is intentionally no
+option to intermix between input/output/inouts.
See also `verilog-auto-arg-sort'."
:version "24.1" ; rev688
@@ -1529,8 +1531,8 @@ If set will become buffer local.")
"Keymap used in Verilog mode.")
;; menus
-(easy-menu-define
- verilog-menu verilog-mode-map "Menu for Verilog mode"
+(easy-menu-define verilog-menu verilog-mode-map
+ "Menu for Verilog mode."
(verilog-easy-menu-filter
`("Verilog"
("Choose Compilation Action"
@@ -2077,8 +2079,7 @@ find the errors."
(if (boundp 'compilation-error-regexp-systems-alist)
(if (and
(not (equal compilation-error-regexp-systems-list 'all))
- ;; eval required due to bug1700, XEmacs otherwise errors on compile
- (not (eval "(member compilation-error-regexp-systems-list 'verilog)")))
+ (not (member 'verilog compilation-error-regexp-systems-list)))
(push 'verilog compilation-error-regexp-systems-list)))
(if (boundp 'compilation-error-regexp-alist-alist)
(if (not (assoc 'verilog compilation-error-regexp-alist-alist))
@@ -2505,7 +2506,7 @@ find the errors."
(defconst verilog-no-indent-begin-re
(eval-when-compile
(verilog-regexp-words
- '("always" "always_comb" "always_ff" "always_latch" "initial" "final" ; procedural blocks
+ '("always" "always_comb" "always_ff" "always_latch" "analog" "initial" "final" ; procedural blocks
"if" "else" ; conditional statements
"while" "for" "foreach" "repeat" "do" "forever" )))) ; loop statements
@@ -2651,6 +2652,7 @@ find the errors."
"\\(\\<end\\>\\s-+\\<else\\>\\)\\|" ; 3
"\\(\\<always\\(?:_ff\\)?\\>\\(?:[ \t]*@\\)\\)\\|" ; 4 (matches always or always_ff w/ @...)
"\\(\\<always\\(?:_comb\\|_latch\\)?\\>\\)\\|" ; 5 (matches always, always_comb, always_latch w/o @...)
+ "\\(\\<analog\\>\\)\\|" ; 6
"\\(\\<fork\\>\\)\\|" ; 7
"\\(\\<if\\>\\)\\|"
verilog-property-re "\\|"
@@ -2853,7 +2855,7 @@ find the errors."
(eval-when-compile (verilog-regexp-words '("Outputs" "Inouts" "Inputs" "Interfaces" "Interfaced"))))
(defconst verilog-behavioral-block-beg-re
- (eval-when-compile (verilog-regexp-words '("initial" "final" "always" "always_comb" "always_latch" "always_ff"
+ (eval-when-compile (verilog-regexp-words '("initial" "final" "always" "always_comb" "always_latch" "always_ff" "analog"
"function" "task"))))
(defconst verilog-coverpoint-re "\\w+\\s-*:\\s-*\\(coverpoint\\|cross\\|constraint\\)")
(defconst verilog-in-constraint-re ; keywords legal in constraint blocks starting a statement/block
@@ -2864,7 +2866,7 @@ find the errors."
(verilog-regexp-words
'(
"{"
- "always" "always_latch" "always_ff" "always_comb"
+ "always" "always_latch" "always_ff" "always_comb" "analog"
"begin" "end"
;; "unique" "priority"
"case" "casex" "casez" "randcase" "endcase"
@@ -2956,13 +2958,13 @@ find the errors."
'( "connectmodule" "module" "macromodule" "primitive" "class" "program"
"interface" "package" "config")
'( "initial" "final" "always" "always_comb" "always_ff"
- "always_latch" "endtask" "endfunction" )))))
+ "always_latch" "analog" "endtask" "endfunction" )))))
(defconst verilog-defun-level-generate-only-re
(eval-when-compile
(verilog-regexp-words
'( "initial" "final" "always" "always_comb" "always_ff"
- "always_latch" "endtask" "endfunction" ))))
+ "always_latch" "analog" "endtask" "endfunction" ))))
(defconst verilog-cpp-level-re
(eval-when-compile
@@ -2989,7 +2991,7 @@ find the errors."
(eval-when-compile
(verilog-regexp-words
'(
- "always" "assign" "always_latch" "always_ff" "always_comb" "connectmodule" "constraint"
+ "always" "assign" "always_latch" "always_ff" "always_comb" "analog" "connectmodule" "constraint"
"import" "initial" "final" "module" "macromodule" "repeat" "randcase" "while"
"if" "for" "forever" "foreach" "else" "parameter" "do" "localparam" "assert"
))))
@@ -3066,7 +3068,7 @@ find the errors."
(defconst verilog-keywords
(append verilog-compiler-directives
'(
- "after" "alias" "always" "always_comb" "always_ff" "always_latch" "and"
+ "after" "alias" "always" "always_comb" "always_ff" "always_latch" "analog" "and"
"assert" "assign" "assume" "automatic" "before" "begin" "bind"
"bins" "binsof" "bit" "break" "buf" "bufif0" "bufif1" "byte"
"case" "casex" "casez" "cell" "chandle" "class" "clocking" "cmos"
@@ -3283,7 +3285,7 @@ See also `verilog-font-lock-extra-types'.")
"use" "wait" "while"
;; 1800-2005
"alias" "always_comb" "always_ff" "always_latch" "assert"
- "assume" "before" "bind" "bins" "binsof" "break" "class"
+ "assume" "analog" "before" "bind" "bins" "binsof" "break" "class"
"clocking" "constraint" "context" "continue" "cover"
"covergroup" "coverpoint" "cross" "dist" "do" "endclass"
"endclocking" "endgroup" "endinterface" "endpackage"
@@ -3563,7 +3565,7 @@ either is ok to parse as a non-comment, or `verilog-insert' was used."
(defun verilog-scan-debug ()
"For debugging, show with display face results of `verilog-scan'."
(font-lock-mode 0)
- ;;(if dbg (setq dbg (concat dbg (format "verilog-scan-debug\n"))))
+ ;;(if dbg (setq dbg (concat dbg "verilog-scan-debug\n")))
(save-excursion
(goto-char (point-min))
(remove-text-properties (point-min) (point-max) '(face nil))
@@ -3610,19 +3612,19 @@ inserted using a single call to `verilog-insert'."
(search-forward ";" nil t))
(defun verilog-single-declaration-end (limit)
- "Returns pos where current (single) declaration statement ends.
+ "Return pos where current (single) declaration statement ends.
Also, this function moves POINT forward to the start of a variable name
(skipping the range-part and whitespace).
Function expected to be called with POINT just after a declaration keyword.
-LIMIT sets the max POINT for searching and moving to. No such limit if LIMIT
+LIMIT sets the max POINT for searching and moving to. No such limit if LIMIT
is 0.
Meaning of *single* declaration:
- Eg. In a module's port-list -
+ E.g. In a module's port-list -
module test(input clk, rst, x, output [1:0] y);
Here 'input clk, rst, x' is 1 *single* declaration statement,
and 'output [1:0] y' is the other single declaration. In the 1st single
-declaration, POINT is moved to start of 'clk'. And in the 2nd declaration,
+declaration, POINT is moved to start of 'clk'. And in the 2nd declaration,
POINT is moved to 'y'."
@@ -4038,9 +4040,12 @@ Some other functions are:
\\[verilog-sk-repeat] Insert a repeat (..) begin .. end block.
\\[verilog-sk-specify] Insert a specify .. endspecify block.
\\[verilog-sk-task] Insert a task .. begin .. end endtask block.
- \\[verilog-sk-while] Insert a while (...) begin .. end block, prompting for details.
- \\[verilog-sk-casex] Insert a casex (...) item: begin.. end endcase block, prompting for details.
- \\[verilog-sk-casez] Insert a casez (...) item: begin.. end endcase block, prompting for details.
+ \\[verilog-sk-while] Insert a while (...) begin .. end block,
+ prompting for details.
+ \\[verilog-sk-casex] Insert a casex (...) item: begin.. end endcase block,
+ prompting for details.
+ \\[verilog-sk-casez] Insert a casez (...) item: begin.. end endcase block,
+ prompting for details.
\\[verilog-sk-if] Insert an if (..) begin .. end block.
\\[verilog-sk-else-if] Insert an else if (..) begin .. end block.
\\[verilog-sk-comment] Insert a comment block.
@@ -4759,7 +4764,7 @@ More specifically, after a generate and before an endgenerate."
(while (and
(/= nest 0)
(verilog-re-search-backward
- "\\<\\(module\\)\\|\\(connectmodule\\)\\|\\(generate\\)\\|\\(endgenerate\\)\\>" nil 'move)
+ "\\<\\(module\\)\\|\\(connectmodule\\)\\|\\(generate\\)\\|\\(endgenerate\\)\\|\\(if\\)\\|\\(case\\)\\|\\(for\\)\\>" nil 'move)
(cond
((match-end 1) ; module - we have crawled out
(throw 'done 1))
@@ -4768,7 +4773,13 @@ More specifically, after a generate and before an endgenerate."
((match-end 3) ; generate
(setq nest (1- nest)))
((match-end 4) ; endgenerate
- (setq nest (1+ nest))))))))
+ (setq nest (1+ nest)))
+ ((match-end 5) ; if
+ (setq nest (1- nest)))
+ ((match-end 6) ; case
+ (setq nest (1- nest)))
+ ((match-end 7) ; for
+ (setq nest (1- nest))))))))
(= nest 0) )) ; return nest
(defun verilog-in-fork-region-p ()
@@ -4818,7 +4829,7 @@ Limit search to point LIM."
((match-end 1) ; [
(setq colon (1+ colon))
(if (>= colon 0)
- (error "%s: unbalanced [" (verilog-point-text))))
+ (error "%s: Unbalanced [" (verilog-point-text))))
((match-end 2) ; ]
(setq colon (1- colon)))
@@ -5104,7 +5115,7 @@ primitive or interface named NAME."
(throw 'skip 1)))))))))
(; always, always_comb, always_latch w/o @...
- (match-end 5)
+ (or (match-end 5) (match-end 6))
(goto-char (match-end 0))
(setq there (point))
(setq err nil)
@@ -5419,7 +5430,7 @@ Useful for creating tri's and other expanded fields."
(defun verilog-lint-off ()
"Convert a Verilog linter warning line into a disable statement.
For example:
- pci_bfm_null.v, line 46: Unused input: pci_rst_
+ pci_bfm_null.v, line 46: Unused input: pci_rst_
becomes a comment for the appropriate tool.
The first word of the `compile-command' or `verilog-linter'
@@ -5443,9 +5454,9 @@ Run from Verilog source window; assumes there is a *compile* buffer
with point set appropriately.
For example:
- WARNING [STD-UDDONX]: xx.v, line 8: output out is never assigned.
+ WARNING [STD-UDDONX]: xx.v, line 8: output out is never assigned.
becomes:
- // surefire lint_line_off UDDONX"
+ // surefire lint_line_off UDDONX"
(interactive)
(let ((buff (if (boundp 'next-error-last-buffer)
next-error-last-buffer
@@ -5469,8 +5480,11 @@ becomes:
(let* ((pop-up-windows t))
(let ((name (expand-file-name
(read-file-name
- (format "Find this error in: (default %s) "
- file)
+ ;; `format-prompt' is new in Emacs 28.1.
+ (if (fboundp 'format-prompt)
+ (format-prompt "Find this error in" file)
+ (format "Find this error in (default %s): "
+ file))
nil ;; dir
file t))))
(setq buffer
@@ -5504,9 +5518,9 @@ becomes:
"Convert a Verilint warning line into a disable statement.
For example:
- (W240) pci_bfm_null.v, line 46: Unused input: pci_rst_
+ (W240) pci_bfm_null.v, line 46: Unused input: pci_rst_
becomes:
- //Verilint 240 off // WARNING: Unused input"
+ //Verilint 240 off // WARNING: Unused input"
(interactive)
(save-excursion
(beginning-of-line)
@@ -6574,7 +6588,8 @@ Return >0 for nested struct."
nil))))
(defun verilog-at-constraint-p ()
- "If at the { of a constraint or coverpoint definition, return true, moving point to constraint."
+ "If at the { of a constraint or coverpoint definition, return true.
+Also move point to constraint."
(if (save-excursion
(let ((p (point)))
(and
@@ -6588,7 +6603,8 @@ Return >0 for nested struct."
(equal (char-before) ?\;)
(equal (char-before) ?\}))
;; skip what looks like bus repetition operator {#{
- (not (string-match "^{\\s-*[0-9a-zA-Z_]+\\s-*{" (buffer-substring p (point)))))))))
+ (not (string-match "^{\\s-*[()0-9a-zA-Z_\\]*\\s-*{"
+ (buffer-substring p (point)))))))))
(progn
(let ( (pt (point)) (pass 0))
(verilog-backward-ws&directives)
@@ -6805,6 +6821,8 @@ Only look at a few lines to determine indent level."
(verilog-do-indent (verilog-calculate-indent)))
(defun verilog-do-indent (indent-str)
+ ;; `ind' is used in expressions stored in `verilog-indent-alist'.
+ (verilog--suppressed-warnings ((lexical ind)) (defvar ind))
(let ((type (car indent-str))
(ind (car (cdr indent-str))))
(cond
@@ -7157,11 +7175,11 @@ Be verbose about progress unless optional QUIET set."
(forward-char -1)
(just-one-space)
(goto-char (marker-position m1))
- (just-one-space)
- (indent-to ind))
+ (delete-horizontal-space)
+ (indent-to ind 1))
(progn
- (just-one-space)
- (indent-to ind)))))
+ (delete-horizontal-space)
+ (indent-to ind 1)))))
((verilog-continued-line-1 (marker-position startpos))
(goto-char e)
(indent-line-to ind))
@@ -7286,6 +7304,8 @@ If QUIET is non-nil, do not print messages showing the progress of line-up."
Line up the variable names based on previous declaration's indentation.
BASEIND is the base indent to offset everything."
(interactive)
+ ;; `ind' is used in expressions stored in `verilog-indent-alist'.
+ (verilog--suppressed-warnings ((lexical ind)) (defvar ind))
(let ((pos (point-marker))
(lim (save-excursion
;; (verilog-re-search-backward verilog-declaration-opener nil 'move)
@@ -7324,12 +7344,10 @@ BASEIND is the base indent to offset everything."
(forward-char -1)
(just-one-space)
(goto-char (marker-position m1))
- (just-one-space)
- (indent-to ind))
- (if (/= (current-column) ind)
- (progn
- (just-one-space)
- (indent-to ind)))))
+ (delete-horizontal-space)
+ (indent-to ind 1))
+ (delete-horizontal-space)
+ (indent-to ind 1)))
(if (looking-at verilog-declaration-re-2-no-macro)
(let ((p (match-end 0)))
(set-marker m1 p)
@@ -7338,12 +7356,10 @@ BASEIND is the base indent to offset everything."
(forward-char -1)
(just-one-space)
(goto-char (marker-position m1))
- (just-one-space)
- (indent-to ind))
- (if (/= (current-column) ind)
- (progn
- (just-one-space)
- (indent-to ind))))))))))
+ (delete-horizontal-space)
+ (indent-to ind 1))
+ (delete-horizontal-space)
+ (indent-to ind 1))))))))
(goto-char pos)))
(defun verilog-get-lineup-indent (b edpos)
@@ -7457,7 +7473,7 @@ will be completed at runtime and should not be added to this list.")
(defvar verilog-defun-keywords
(append
'(
- "always" "always_comb" "always_ff" "always_latch" "assign"
+ "always" "always_comb" "always_ff" "always_latch" "analog" "assign"
"begin" "end" "connectmodule" "endconnectmodule" "generate" "endgenerate" "module" "endmodule"
"specify" "endspecify" "function" "endfunction" "initial" "final"
"task" "endtask" "primitive" "endprimitive"
@@ -7853,14 +7869,14 @@ If search fails, other files are checked based on
(let* ((default (verilog-get-default-symbol))
;; The following variable is used in verilog-comp-function
(verilog-buffer-to-use (current-buffer))
- (label (if (not (string= default ""))
- ;; Do completion with default
- (completing-read (concat "Goto-Label: (default "
- default ") ")
- #'verilog-comp-defun nil nil "")
- ;; There is no default value. Complete without it
- (completing-read "Goto-Label: "
- #'verilog-comp-defun nil nil "")))
+ (label
+ (completing-read (cond ((fboundp 'format-prompt)
+ ;; `format-prompt' is new in Emacs 28.1.
+ (format-prompt "Goto-Label" default))
+ ((not (string= default ""))
+ (concat "Goto-Label (default " default "): "))
+ (t "Goto-Label: "))
+ #'verilog-comp-defun nil nil ""))
pt)
;; Make sure library paths are correct, in case need to resolve module
(verilog-auto-reeval-locals)
@@ -8643,6 +8659,13 @@ Optional NUM-PARAM and MAX-PARAM check for a specific number of parameters."
(defun verilog-read-decls ()
"Compute signal declaration information for the current module at point.
Return an array of [outputs inouts inputs wire reg assign const gparam intf]."
+ (verilog--suppressed-warnings
+ ((lexical sigs-intf sigs-var sigs-const sigs-assign sigs-var
+ sigs-gparam sigs-inout sigs-out sigs-in))
+ ;; The local variable below are accessed via (symbol-value expect-signal).
+ (defvar sigs-intf) (defvar sigs-var) (defvar sigs-const)
+ (defvar sigs-assign) (defvar sigs-var) (defvar sigs-gparam)
+ (defvar sigs-inout) (defvar sigs-out) (defvar sigs-in))
(let ((end-mod-point (or (verilog-get-end-of-defun) (point-max)))
(functask 0) (paren 0) (sig-paren 0) (v2kargs-ok t)
in-modport in-clocking in-ign-to-semi ptype ign-prop
@@ -9106,9 +9129,7 @@ Inserts the list of signals found, using submodi to look up each port."
;; We intentionally ignore (non-escaped) signals with .s in them
;; this prevents AUTOWIRE etc from noticing hierarchical sigs.
(when port
- (cond ((and verilog-auto-ignore-concat
- (looking-at "[({]"))
- nil) ; {...} or (...) historically ignored with auto-ignore-concat
+ (cond ((looking-at "[^\n]*AUTONOHOOKUP"))
((looking-at "\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\s-*)")
(verilog-read-sub-decls-sig
submoddecls par-values comment port
@@ -9325,6 +9346,9 @@ Must call `verilog-read-auto-lisp-present' before this function."
EXIT-KEYWD is expression to stop at, nil if top level.
RVALUE is true if at right hand side of equal.
TEMP-NEXT is true to ignore next token, fake from inside case statement."
+ (verilog--suppressed-warnings ((lexical sigs-temp sigs-in sigs-out-unk))
+ ;; The local variable below are accessed via (symbol-value got-list).
+ (defvar sigs-temp) (defvar sigs-in) (defvar sigs-out-unk))
(let* ((semi-rvalue (equal "endcase" exit-keywd)) ; true if after a ; we are looking for rvalue
keywd last-keywd sig-tolk sig-last-tolk gotend got-sig got-list end-else-check
ignore-next)
@@ -9555,7 +9579,10 @@ Returns REGEXP and list of ( (signal_name connection_name)... )."
(cons (list
(match-string-no-properties 1)
(match-string-no-properties 2)
- templateno lineno)
+ templateno lineno
+ (save-excursion
+ (goto-char (match-end 0))
+ (looking-at "[^\n]*AUTONOHOOKUP")))
tpl-sig-list))
(goto-char (match-end 0)))
;; Regexp form??
@@ -9571,7 +9598,10 @@ Returns REGEXP and list of ( (signal_name connection_name)... )."
(match-string 1))
"$")
rep
- templateno lineno)
+ templateno lineno
+ (save-excursion
+ (goto-char (match-end 0))
+ (looking-at "[^\n]*AUTONOHOOKUP")))
tpl-wild-list)))
((looking-at "[ \t\f]+")
(goto-char (match-end 0)))
@@ -9745,6 +9775,9 @@ warning message, you need to add to your init file:
(while (re-search-forward
"^\\s-*\\(parameter\\|localparam\\)\\(\\s-*\\[[^]]*\\]\\)?\\s-*" nil t)
(let (enumname)
+ ;; Advance over parameter's type if present
+ (if (looking-at "\\([a-zA-Z0-9_]+\\s-+\\)[a-zA-Z0-9_]+")
+ (goto-char (match-end 1)))
;; The primary way of getting defines is verilog-read-decls
;; However, that isn't called yet for included files, so we'll add another scheme
(if (looking-at "[^\n]*\\(auto\\|synopsys\\)\\s +enum\\s +\\([a-zA-Z0-9_]+\\)")
@@ -9789,11 +9822,11 @@ variable over and over when many modules are compiled together, put a test
around the inside each include file:
foo.v (an include file):
- \\=`ifdef _FOO_V // include if not already included
- \\=`else
- \\=`define _FOO_V
- ... contents of file
- \\=`endif // _FOO_V"
+ \\=`ifdef _FOO_V // include if not already included
+ \\=`else
+ \\=`define _FOO_V
+ ... contents of file
+ \\=`endif // _FOO_V"
;;slow: (verilog-read-defines nil t)
(save-excursion
(verilog-getopt-flags)
@@ -11040,7 +11073,7 @@ Intended for internal use inside a
'verilog-delete-auto-star-all)
;; Remove template comments ... anywhere in case was pasted after AUTOINST removed
(goto-char (point-min))
- (while (re-search-forward "\\s-*// \\(Templated\\|Implicit \\.\\*\\)\\([ \tLT0-9]*\\| LHS: .*\\)$" nil t)
+ (while (re-search-forward "\\s-*// \\(Templated\\(\\s-*AUTONOHOOKUP\\)?\\|Implicit \\.\\*\\)\\([ \tLT0-9]*\\| LHS: .*\\)$" nil t)
(replace-match ""))
;; Final customize
@@ -11558,6 +11591,7 @@ See the example in `verilog-auto-inout-modport'."
(defun verilog-auto-inst-port-map (_port-st)
nil)
+;; These are used by user's AUTO_TEMPLATE Lisp expressions
(defvar vl-cell-type nil "See `verilog-auto-inst'.") ; Prevent compile warning
(defvar vl-cell-name nil "See `verilog-auto-inst'.") ; Prevent compile warning
(defvar vl-memory nil "See `verilog-auto-inst'.") ; Prevent compile warning
@@ -11689,15 +11723,14 @@ If PAR-VALUES replace final strings with these parameter values."
;; verilog-insert requires the complete comment in one call - including the newline
(cond ((equal verilog-auto-inst-template-numbers 'lhs)
(verilog-insert " // Templated"
- " LHS: " (nth 0 tpl-ass)
- "\n"))
+ " LHS: " (nth 0 tpl-ass)))
(verilog-auto-inst-template-numbers
(verilog-insert " // Templated"
" T" (int-to-string (nth 2 tpl-ass))
- " L" (int-to-string (nth 3 tpl-ass))
- "\n"))
+ " L" (int-to-string (nth 3 tpl-ass))))
(t
- (verilog-insert " // Templated\n"))))
+ (verilog-insert " // Templated")))
+ (verilog-insert (if (nth 4 tpl-ass) " AUTONOHOOKUP\n" "\n")))
(for-star
(indent-to (+ (if (< verilog-auto-inst-column 48) 24 16)
verilog-auto-inst-column))
@@ -12087,6 +12120,16 @@ Lisp Templates:
After the evaluation is completed, @ substitution and [] substitution
occur.
+
+Ignoring Hookup:
+
+ AUTOWIRE and related AUTOs will read the signals created by a template.
+ To specify that a signal should not be parsed to participate in this
+ hookup, add a AUTONOHOOKUP comment to the template. For example:
+
+ .pci_req_l (pci_req_not_to_wire), //AUTONOHOOKUP
+
+
For more information see the \\[verilog-faq] and forums at URL
`https://www.veripool.org'."
(save-excursion
@@ -12563,7 +12606,7 @@ You may also provide an optional regular expression, in which case only
signals matching the regular expression will be included. For example the
same expansion will result from only extracting outputs starting with ov:
- /*AUTOOUTPUT(\"^ov\")*/"
+ /*AUTOOUTPUT(\"^ov\")*/"
(save-excursion
;; Point must be at insertion point.
(let* ((indent-pt (current-indentation))
@@ -12714,7 +12757,7 @@ included. or excluded if the regexp begins with
expansion will result from only extracting inputs starting with
i:
- /*AUTOINPUT(\"^i\")*/"
+ /*AUTOINPUT(\"^i\")*/"
(save-excursion
(let* ((indent-pt (current-indentation))
(params (verilog-read-auto-params 0 1))
@@ -13428,7 +13471,7 @@ Constant signals:
is put into the AUTOSENSE list and is not desired, use the AUTO_CONSTANT
declaration anywhere in the module (parenthesis are required):
- /* AUTO_CONSTANT ( \\=`this_is_really_constant_dont_autosense_it ) */
+ /* AUTO_CONSTANT( \\=`this_is_really_constant_dont_autosense_it ) */
Better yet, use a parameter, which will be understood to be constant
automatically.
@@ -13444,7 +13487,7 @@ OOps!
An example:
always @ (/*AS*/) begin
- /*AUTO_CONSTANT (\\=`constant) */
+ /*AUTO_CONSTANT(\\=`constant) */
outin = ina | inb | \\=`constant;
out = outin;
end
@@ -13452,7 +13495,7 @@ An example:
Typing \\[verilog-auto] will make this into:
always @ (/*AS*/ina or inb) begin
- /*AUTO_CONSTANT (\\=`constant) */
+ /*AUTO_CONSTANT(\\=`constant) */
outin = ina | inb | \\=`constant;
out = outin;
end
@@ -13625,7 +13668,7 @@ signals to deasserted.
the same input/output list as another module, but no internals.
Specifically, it finds all outputs in the module, and if that
input is not otherwise declared as a register or wire, nor comes
-from a AUTOINST submodule's output, creates a tieoff. AUTOTIEOFF
+from a AUTOINST submodule's output, creates a tieoff. AUTOTIEOFF
does not examine assignments to determine what is already driven.
AUTORESET ties signals to deasserted, which is presumed to be zero.
@@ -14108,14 +14151,14 @@ For example:
endmodule
You can also update the AUTOs from the shell using:
- emacs --batch <filenames.v> -f verilog-batch-auto
+ emacs --batch <filenames.v> -f verilog-batch-auto
Or fix indentation with:
- emacs --batch <filenames.v> -f verilog-batch-indent
+ emacs --batch <filenames.v> -f verilog-batch-indent
Likewise, you can delete or inject AUTOs with:
- emacs --batch <filenames.v> -f verilog-batch-delete-auto
- emacs --batch <filenames.v> -f verilog-batch-inject-auto
+ emacs --batch <filenames.v> -f verilog-batch-delete-auto
+ emacs --batch <filenames.v> -f verilog-batch-inject-auto
Or check if AUTOs have the same expansion
- emacs --batch <filenames.v> -f verilog-batch-diff-auto
+ emacs --batch <filenames.v> -f verilog-batch-diff-auto
Using \\[describe-function], see also:
`verilog-auto-arg' for AUTOARG module instantiations
@@ -14402,7 +14445,7 @@ See also `verilog-header' for an alternative format."
;; ------------------------------------------------------------------------
(define-skeleton verilog-sk-ovm-class
- "Insert a class definition"
+ "Insert a class definition."
()
> "class " (setq name (skeleton-read "Name: ")) " extends " (skeleton-read "Extends: ") ";" \n
> _ \n
@@ -14416,7 +14459,7 @@ See also `verilog-header' for an alternative format."
> "endclass" (progn (electric-verilog-terminate-line) nil))
(define-skeleton verilog-sk-uvm-object
- "Insert a class definition"
+ "Insert a class definition."
()
> "class " (setq name (skeleton-read "Name: ")) " extends " (skeleton-read "Extends: ") ";" \n
> _ \n
@@ -14430,7 +14473,7 @@ See also `verilog-header' for an alternative format."
> "endclass" (progn (electric-verilog-terminate-line) nil))
(define-skeleton verilog-sk-uvm-component
- "Insert a class definition"
+ "Insert a class definition."
()
> "class " (setq name (skeleton-read "Name: ")) " extends " (skeleton-read "Extends: ") ";" \n
> _ \n
@@ -14471,8 +14514,7 @@ See also `verilog-header' for an alternative format."
> (- verilog-indent-level-behavioral) "endfunction" (progn (electric-verilog-terminate-line) nil))
(define-skeleton verilog-sk-always
- "Insert always block. Uses the minibuffer to prompt
-for sensitivity list."
+ "Insert always block. Prompt for sensitivity list."
()
> "always @ ( /*AUTOSENSE*/ ) begin\n"
> _ \n
@@ -14487,14 +14529,14 @@ for sensitivity list."
> (- verilog-indent-level-behavioral) "end" \n > )
(define-skeleton verilog-sk-specify
- "Insert specify block. "
+ "Insert specify block."
()
> "specify\n"
> _ \n
> (- verilog-indent-level-behavioral) "endspecify" \n > )
(define-skeleton verilog-sk-generate
- "Insert generate block. "
+ "Insert generate block."
()
> "generate\n"
> _ \n
@@ -14953,7 +14995,9 @@ but instead, [[Fill in here]] happens!.
(provide 'verilog-mode)
+;;TODO: Could `byte-compile-docstring-max-column' be decreased?
;; Local Variables:
+;; byte-compile-docstring-max-column: 90
;; checkdoc-permit-comma-termination-flag:t
;; checkdoc-force-docstrings-flag:nil
;; indent-tabs-mode:nil
diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el
index 5eeac8af3b8..f3a7d96c63b 100644
--- a/lisp/progmodes/vhdl-mode.el
+++ b/lisp/progmodes/vhdl-mode.el
@@ -2197,8 +2197,8 @@ is pair matching KEY."
(setq alist alist-cdr)))))
(defun vhdl-aget (alist key)
- "Return the value in ALIST that is associated with KEY. If KEY is
-not found, then nil is returned."
+ "Return the value in ALIST that is associated with KEY.
+If KEY is not found, then nil is returned."
(cdr (assoc key alist)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -4275,8 +4275,7 @@ STRING are replaced by `-' and substrings are converted to lower case."
(defvar vhdl-sources-menu nil)
(defun vhdl-directory-files (directory &optional full match)
- "Call `directory-files' if DIRECTORY exists, otherwise generate error
-message."
+ "Call `directory-files' if DIRECTORY exists, otherwise generate error message."
(if (not (file-directory-p directory))
(vhdl-warning-when-idle "No such directory: \"%s\"" directory)
(let ((dir (directory-files directory full match)))
@@ -4700,7 +4699,7 @@ Usage:
`vhdl-project-alist'.
- SPECIAL MENUES:
+ SPECIAL MENUS:
As an alternative to the speedbar, an index menu can be added (set
option `vhdl-index-menu' to non-nil) or made accessible as a mouse menu
(e.g. add \"(global-set-key [S-down-mouse-3] \\='imenu)\" to your start-up
@@ -5734,8 +5733,8 @@ the offset is simply returned."
(save-excursion (re-search-forward "\\\\" (vhdl-point 'eol) t)))))
(defun vhdl-forward-comment (&optional direction)
- "Skip all comments (including whitespace). Skip backwards if DIRECTION is
-negative, skip forward otherwise."
+ "Skip all comments (including whitespace).
+Skip backwards if DIRECTION is negative, skip forward otherwise."
(interactive "p")
(if (and direction (< direction 0))
;; skip backwards
@@ -5918,16 +5917,16 @@ negative, skip forward otherwise."
;; Functions to help finding the correct indentation column:
(defun vhdl-first-word (point)
- "If the keyword at POINT is at boi, then return (current-column) at
-that point, else nil."
+ "If the keyword at POINT is at boi, return (current-column) at that point.
+Otherwise return nil."
(save-excursion
(and (goto-char point)
(eq (point) (vhdl-point 'boi))
(current-column))))
(defun vhdl-last-word (point)
- "If the keyword at POINT is at eoi, then return (current-column) at
-that point, else nil."
+ "If keyword at POINT is at eoi, then return (current-column) at that point.
+Otherwise, return nil."
(save-excursion
(and (goto-char point)
(save-excursion (or (eq (progn (forward-sexp) (point))
@@ -5985,13 +5984,11 @@ corresponding \"begin\" keyword, else return nil."
(defconst vhdl-begin-fwd-re
"\\b\\(is\\|begin\\|block\\|component\\|generate\\|then\\|else\\|loop\\|process\\|procedural\\(\\s-+body\\)?\\|units\\|use\\|record\\|protected\\(\\s-+body\\)?\\|for\\)\\b\\([^_]\\|\\'\\)"
- "A regular expression for searching forward that matches all known
-\"begin\" keywords.")
+ "Regexp for searching forward that matches all known \"begin\" keywords.")
(defconst vhdl-begin-bwd-re
"\\b\\(is\\|begin\\|block\\|component\\|generate\\|then\\|else\\|loop\\|process\\|procedural\\(\\s-+body\\)?\\|units\\|use\\|record\\|protected\\(\\s-+body\\)?\\|for\\)\\b[^_]"
- "A regular expression for searching backward that matches all known
-\"begin\" keywords.")
+ "Regexp for searching backward that matches all known \"begin\" keywords.")
(defun vhdl-begin-p (&optional lim)
"Return t if we are looking at a real \"begin\" keyword.
@@ -6269,13 +6266,11 @@ of an identifier that just happens to contain an \"end\" keyword."
(defconst vhdl-statement-fwd-re
"\\b\\(if\\|for\\|while\\|loop\\)\\b\\([^_]\\|\\'\\)"
- "A regular expression for searching forward that matches all known
-\"statement\" keywords.")
+ "Regexp for searching forward that matches all known \"statement\" keywords.")
(defconst vhdl-statement-bwd-re
"\\b\\(if\\|for\\|while\\|loop\\)\\b[^_]"
- "A regular expression for searching backward that matches all known
-\"statement\" keywords.")
+ "Regexp for searching backward that matches all known \"statement\" keywords.")
(defun vhdl-statement-p (&optional _lim)
"Return t if we are looking at a real \"statement\" keyword.
@@ -6726,8 +6721,9 @@ search, and an argument indicating an interactive call."
vhdl-begin-bwd-re "\\|" vhdl-statement-bwd-re))
(defun vhdl-beginning-of-statement-1 (&optional lim)
- "Move to the start of the current statement, or the previous
-statement if already at the beginning of one."
+ "Move to the start of the current statement.
+If already at the beginning of a statement, move to the start of
+the previous statement instead."
(let ((lim (or lim (point-min)))
(here (point))
(pos (point))
@@ -6848,7 +6844,7 @@ keyword at PLACEHOLDER, then return the library unit type."
))
(defun vhdl-get-block-state (&optional lim)
- "Finds and records all the closest opens.
+ "Find and records all the closest opens.
LIM is the furthest back we need to search (it should be the
previous libunit keyword)."
(let ((here (point))
@@ -6914,9 +6910,9 @@ previous libunit keyword)."
(concat vhdl-case-alternative-re "\\|" vhdl-case-header-key))
(defun vhdl-skip-case-alternative (&optional lim)
- "Skip forward over case/when bodies, with optional maximal
-limit. If no next case alternative is found, nil is returned and
-point is not moved."
+ "Skip forward over case/when bodies, with optional maximal limit.
+If no next case alternative is found, nil is returned and point
+is not moved."
(let ((lim (or lim (point-max)))
(here (point))
donep foundp)
@@ -6941,9 +6937,8 @@ point is not moved."
foundp))
(defun vhdl-backward-skip-label (&optional lim)
- "Skip backward over a label, with optional maximal
-limit. If label is not found, nil is returned and point
-is not moved."
+ "Skip backward over a label, with optional maximal limit.
+If label is not found, nil is returned and point is not moved."
(let ((lim (or lim (point-min)))
placeholder)
(if (save-excursion
@@ -6957,9 +6952,8 @@ is not moved."
))
(defun vhdl-forward-skip-label (&optional lim)
- "Skip forward over a label, with optional maximal
-limit. If label is not found, nil is returned and point
-is not moved."
+ "Skip forward over a label, with optional maximal limit.
+If label is not found, nil is returned and point is not moved."
(let ((lim (or lim (point-max))))
(if (looking-at vhdl-label-key)
(progn
@@ -7329,9 +7323,9 @@ after the containing paren which starts the arglist."
(- ce-curcol cs-curcol -1))))
(defun vhdl-lineup-comment (_langelem)
- "Support old behavior for comment indentation. We look at
-vhdl-comment-only-line-offset to decide how to indent comment
-only-lines."
+ "Support old behavior for comment indentation.
+We look at `vhdl-comment-only-line-offset' to decide how to
+indent comment only-lines."
(save-excursion
(back-to-indentation)
;; at or to the right of comment-column
@@ -7447,7 +7441,7 @@ else indent `correctly'."
(setq this-command 'vhdl-electric-tab)))
(defun vhdl-electric-return ()
- "newline-and-indent or indent-new-comment-line if in comment and preceding
+ "`newline-and-indent' or `indent-new-comment-line' if in comment and preceding
character is a space."
(interactive)
(if (and (= (preceding-char) ? ) (vhdl-in-comment-p))
@@ -7458,8 +7452,8 @@ character is a space."
(newline-and-indent)))
(defun vhdl-indent-line ()
- "Indent the current line as VHDL code. Returns the amount of
-indentation change."
+ "Indent the current line as VHDL code.
+Return the amount of indentation change."
(interactive)
(let* ((syntax (and vhdl-indent-syntax-based (vhdl-get-syntactic-context)))
(pos (- (point-max) (point)))
@@ -7619,8 +7613,8 @@ ALIGN-PATTERN matches the white space to be expanded/contracted.")
;; Align code
(defvar vhdl-align-try-all-clauses t
- "If REGEXP is not found on the first line of the region that clause
-is ignored. If this variable is non-nil, then the clause is tried anyway.")
+ "If REGEXP is not found on the first line of the region that clause is ignored.
+If this variable is non-nil, then the clause is tried anyway.")
(defun vhdl-do-group (function &optional spacing)
"Apply FUNCTION on group of lines between empty lines."
@@ -7639,8 +7633,7 @@ is ignored. If this variable is non-nil, then the clause is tried anyway.")
(funcall function beg end spacing)))
(defun vhdl-do-list (function &optional spacing)
- "Apply FUNCTION to the lines of a list surrounded by a balanced group of
-parentheses."
+ "Apply FUNCTION to lines of a list surrounded by a balanced group of parentheses."
(let (beg end)
(save-excursion
;; search for beginning of balanced group of parentheses
@@ -7685,11 +7678,11 @@ parentheses."
(funcall function beg end spacing)))
(defun vhdl-align-region-1 (begin end &optional spacing alignment-list _indent)
- "Attempt to align a range of lines based on the content of the
-lines. The definition of `alignment-list' determines the matching
-order and the manner in which the lines are aligned. If ALIGNMENT-LIST
-is not specified `vhdl-align-alist' is used. If INDENT is non-nil,
-indentation is done before aligning."
+ "Attempt to align a range of lines based on the content of the lines.
+The definition of `alignment-list' determines the matching order
+and the manner in which the lines are aligned. If ALIGNMENT-LIST
+is not specified `vhdl-align-alist' is used. If INDENT is
+non-nil, indentation is done before aligning."
(interactive "r\np")
(setq alignment-list (or alignment-list vhdl-align-alist))
(setq spacing (or spacing 1))
@@ -7722,13 +7715,13 @@ indentation is done before aligning."
(setq copy (cdr copy))))))))
(defun vhdl-align-region-2 (begin end match &optional substr spacing)
- "Align a range of lines from BEGIN to END. The regular expression
-MATCH must match exactly one field: the whitespace to be
-contracted/expanded. The alignment column will equal the
-rightmost column of the widest whitespace block. SPACING is
-the amount of extra spaces to add to the calculated maximum required.
-SPACING defaults to 1 so that at least one space is inserted after
-the token in MATCH."
+ "Align a range of lines from BEGIN to END.
+The regular expression MATCH must match exactly one field: the
+whitespace to be contracted/expanded. The alignment column will
+equal the rightmost column of the widest whitespace block.
+SPACING is the amount of extra spaces to add to the calculated
+maximum required. SPACING defaults to 1 so that at least one
+space is inserted after the token in MATCH."
(setq spacing (or spacing 1))
(setq substr (or substr 1))
(save-excursion
@@ -7994,8 +7987,9 @@ the token in MATCH."
(beginning-of-line 2))))))
(defun vhdl-align-inline-comment-region (beg end &optional spacing no-message)
- "Align inline comments within a region. Groups of code lines separated by
-empty lines are aligned individually, if `vhdl-align-groups' is non-nil."
+ "Align inline comments within a region.
+Groups of code lines separated by empty lines are aligned
+individually, if `vhdl-align-groups' is non-nil."
(interactive "r\nP")
(save-excursion
(let (orig pos)
@@ -8044,8 +8038,9 @@ empty lines are aligned individually, if `vhdl-align-groups' is non-nil."
(message "Aligning inline comments...done"))))
(defun vhdl-align-inline-comment-buffer ()
- "Align inline comments within buffer. Groups of code lines separated by
-empty lines are aligned individually, if `vhdl-align-groups' is non-nil."
+ "Align inline comments within buffer.
+Groups of code lines separated by empty lines are aligned
+individually, if `vhdl-align-groups' is non-nil."
(interactive)
(vhdl-align-inline-comment-region (point-min) (point-max)))
@@ -8053,9 +8048,10 @@ empty lines are aligned individually, if `vhdl-align-groups' is non-nil."
;; Fixup whitespace
(defun vhdl-fixup-whitespace-region (beg end &optional no-message)
- "Fixup whitespace in region. Surround operator symbols by one space,
-eliminate multiple spaces (except at beginning of line), eliminate spaces at
-end of line, do nothing in comments and strings."
+ "Fixup whitespace in region.
+Surround operator symbols by one space, eliminate multiple
+spaces (except at beginning of line), eliminate spaces at end of
+line, do nothing in comments and strings."
(interactive "r")
(unless no-message (message "Fixing up whitespace..."))
(save-excursion
@@ -8107,9 +8103,10 @@ end of line, do nothing in comments and strings."
(unless no-message (message "Fixing up whitespace...done")))
(defun vhdl-fixup-whitespace-buffer ()
- "Fixup whitespace in buffer. Surround operator symbols by one space,
-eliminate multiple spaces (except at beginning of line), eliminate spaces at
-end of line, do nothing in comments."
+ "Fixup whitespace in buffer.
+Surround operator symbols by one space, eliminate multiple
+spaces (except at beginning of line), eliminate spaces at end of
+line, do nothing in comments."
(interactive)
(vhdl-fixup-whitespace-region (point-min) (point-max)))
@@ -10456,8 +10453,8 @@ otherwise."
reset))
(defun vhdl-template-standard-package (library package)
- "Insert specification of a standard package. Include a library
-specification, if not already there."
+ "Insert specification of a standard package.
+Include a library specification, if not already there."
(let ((margin (current-indentation)))
(unless (equal library "std")
(unless (or (save-excursion
@@ -10686,8 +10683,9 @@ specification, if not already there."
(replace-match "" t t)
(vhdl-template-insert-date))
(goto-char beg)
- (while (search-forward "<year>" end t)
- (replace-match (format-time-string "%Y" nil) t t))
+ (let ((year (format-time-string "%Y")))
+ (while (search-forward "<year>" end t)
+ (replace-match year t t)))
(goto-char beg)
(when file-title
(while (search-forward "<title string>" end t)
@@ -11068,7 +11066,7 @@ Point is left between them."
;; Help functions
(defun vhdl-electric-space (count)
- "Expand abbreviations and self-insert space(s), do indent-new-comment-line
+ "Expand abbreviations and self-insert space(s), do `indent-new-comment-line'
if in comment and past end-comment-column."
(interactive "p")
(cond ((vhdl-in-comment-p)
@@ -11617,8 +11615,7 @@ but not if inside a comment or quote."
string)))
(defun vhdl-paste-group-comment (string indent)
- "Paste comment and empty lines from STRING between groups of lines
-with INDENT."
+ "Paste comment and empty lines from STRING between groups of lines with INDENT."
(let ((pos (point-marker)))
(when (> indent 0)
(while (string-match "^\\(--\\)" string)
@@ -13175,7 +13172,7 @@ File statistics: \"%s\"\n\
"Regexp to match start of construct to hide.")
(defun vhdl-hs-forward-sexp-func (count)
- "Find end of construct to hide (for hideshow). Only searches forward."
+ "Find end of construct to hide (for hideshow). Only search forward."
(let ((pos (point)))
(vhdl-prepare-search-2
(beginning-of-line)
@@ -13299,7 +13296,8 @@ File statistics: \"%s\"\n\
(goto-char end))))))
(defun vhdl-font-lock-match-item (limit)
- "Match, and move over, any declaration item after point. Adapted from
+ "Match, and move over, any declaration item after point.
+Adapted from
`font-lock-match-c-style-declaration-item-and-skip-to-next'."
(condition-case nil
(save-restriction
@@ -13750,8 +13748,7 @@ This does background highlighting of translate-off regions.")
;; Variables
(defvar vhdl-entity-alist nil
- "Cache with entities and corresponding architectures for each
-project/directory.")
+ "Cache with entities and corresponding architectures for each project/directory.")
;; structure: (parenthesized expression means list of such entries)
;; (cache-key
;; (ent-key ent-name ent-file ent-line
@@ -14917,7 +14914,8 @@ if required."
(setq project-alist (cdr project-alist)))))
(defun vhdl-speedbar-insert-project-hierarchy (project indent &optional rescan)
- "Insert hierarchy of PROJECT. Rescan directories if RESCAN is non-nil,
+ "Insert hierarchy of PROJECT.
+Rescan directories if optional argument RESCAN is non-nil,
otherwise use cached data."
(when (or rescan (and (not (assoc project vhdl-file-alist))
(not (vhdl-load-cache project))))
@@ -14935,7 +14933,8 @@ otherwise use cached data."
(vhdl-speedbar-expand-units project))
(defun vhdl-speedbar-insert-dir-hierarchy (directory depth &optional rescan)
- "Insert hierarchy of DIRECTORY. Rescan directory if RESCAN is non-nil,
+ "Insert hierarchy of DIRECTORY.
+Rescan directory if optional argument RESCAN is non-nil,
otherwise use cached data."
(when (or rescan (and (not (assoc directory vhdl-file-alist))
(not (vhdl-load-cache directory))))
@@ -15019,8 +15018,7 @@ otherwise use cached data."
(declare-function speedbar-goto-this-file "speedbar" (file))
(defun vhdl-speedbar-expand-dirs (_directory)
- "Expand subdirectories in DIRECTORY according to
- `speedbar-shown-directories'."
+ "Expand subdirectories in DIRECTORY according to `speedbar-shown-directories'."
;; (nicked from `speedbar-default-directory-list')
(let ((sf (cdr (reverse speedbar-shown-directories)))
(vhdl-speedbar-update-current-unit nil))
@@ -15836,7 +15834,7 @@ NO-POSITION non-nil means do not re-position cursor."
(declare-function speedbar-line-text "speedbar" (&optional p))
(defun vhdl-speedbar-line-text ()
- "Calls `speedbar-line-text' and removes text properties."
+ "Call `speedbar-line-text' and remove text properties."
(let ((string (speedbar-line-text)))
(set-text-properties 0 (length string) nil string)
string))
@@ -17074,8 +17072,7 @@ do not print any file names."
(or project-options compiler-options)))
(defun vhdl-compile ()
- "Compile current buffer using the VHDL compiler specified in
-`vhdl-compiler'."
+ "Compile current buffer using the VHDL compiler specified in `vhdl-compiler'."
(interactive)
(vhdl-compile-init)
(let* ((project (vhdl-aget vhdl-project-alist vhdl-project))
@@ -17852,8 +17849,7 @@ User Options
`vhdl-indent-comment-like-next-code-line': (new)
Specify whether comment lines are indented like following code line.
`vhdl-array-index-record-field-in-sensitivity-list': (new)
- Specify whether to include array indices / record fields in sensitivity list.
-")
+ Specify whether to include array indices / record fields in sensitivity list.")
(defconst vhdl-doc-keywords nil
diff --git a/lisp/progmodes/which-func.el b/lisp/progmodes/which-func.el
index eb170baa5d8..176f599649f 100644
--- a/lisp/progmodes/which-func.el
+++ b/lisp/progmodes/which-func.el
@@ -141,12 +141,14 @@ Zero means compute the Imenu menu regardless of size."
local-map ,which-func-keymap
face which-func
mouse-face mode-line-highlight
- help-echo "mouse-1: go to beginning\n\
-mouse-2: toggle rest visibility\n\
-mouse-3: go to end")
+ help-echo ,(concat
+ "Current function\n"
+ "mouse-1: go to beginning\n"
+ "mouse-2: toggle rest visibility\n"
+ "mouse-3: go to end"))
"]")
"Format for displaying the function in the mode line."
- :version "24.2" ; added mouse-face; 24point2 is correct
+ :version "28.1"
:type 'sexp)
;;;###autoload (put 'which-func-format 'risky-local-variable t)
@@ -183,7 +185,8 @@ and you want to simplify them for the mode line
(defvar-local which-func-mode nil
"Non-nil means display current function name in mode line.
-This makes a difference only if `which-function-mode' is non-nil.")
+This makes a difference only if variable `which-function-mode' is
+non-nil.")
(add-hook 'after-change-major-mode-hook #'which-func-ff-hook t)
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index d3780d571fc..ca3594d253b 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -1,7 +1,7 @@
;;; xref.el --- Cross-referencing commands -*-lexical-binding:t-*-
;; Copyright (C) 2014-2021 Free Software Foundation, Inc.
-;; Version: 1.1.0
+;; Version: 1.3.2
;; Package-Requires: ((emacs "26.1"))
;; This is a GNU ELPA :core package. Avoid functionality that is not
@@ -46,9 +46,9 @@
;;
;; One would usually call `make-xref' and `xref-make-file-location',
;; `xref-make-buffer-location' or `xref-make-bogus-location' to create
-;; them. More generally, a location must be an instance of an EIEIO
-;; class inheriting from `xref-location' and implementing
-;; `xref-location-group' and `xref-location-marker'.
+;; them. More generally, a location must be an instance of a type for
+;; which methods `xref-location-group' and `xref-location-marker' are
+;; implemented.
;;
;; There's a special kind of xrefs we call "match xrefs", which
;; correspond to search results. For these values,
@@ -62,31 +62,48 @@
;; distinct, because the user can't see the properties when making the
;; choice.
;;
+;; Older versions of Xref used EIEIO for implementation of the
+;; built-in types, and included a class called `xref-location' which
+;; was supposed to be inherited from. Neither is true anymore.
+;;
;; See the etags and elisp-mode implementations for full examples.
;;; Code:
(require 'cl-lib)
-(require 'eieio)
(require 'ring)
(require 'project)
-(defgroup xref nil "Cross-referencing commands"
+(eval-and-compile
+ (when (version< emacs-version "28.0.60")
+ ;; etags.el in Emacs 26 and 27 uses EIEIO, and its location type
+ ;; inherits from `xref-location'.
+ (require 'eieio)
+
+ ;; Suppressing byte-compilation warnings (in Emacs 28+) about
+ ;; `defclass' not being defined, which happens because the
+ ;; `require' statement above is not evaluated either.
+ ;; FIXME: Use `with-suppressed-warnings' when we stop supporting Emacs 26.
+ (with-no-warnings
+ (defclass xref-location () ()
+ :documentation "(Obsolete) location represents a position in a file or buffer."))))
+
+(defgroup xref nil "Cross-referencing commands."
:version "25.1"
:group 'tools)
;;; Locations
-(defclass xref-location () ()
- :documentation "A location represents a position in a file or buffer.")
-
(cl-defgeneric xref-location-marker (location)
"Return the marker for LOCATION.")
(cl-defgeneric xref-location-group (location)
"Return a string used to group a set of locations.
-This is typically the filename.")
+This is typically a file name, but can also be a package name, or
+some other label.
+
+When it is a file name, it should be the \"expanded\" version.")
(cl-defgeneric xref-location-line (_location)
"Return the line number corresponding to the location."
@@ -96,7 +113,7 @@ This is typically the filename.")
"Return the length of the match."
nil)
-;;;; Commonly needed location classes are defined here:
+;;;; Commonly needed location types are defined here:
(defcustom xref-file-name-display 'project-relative
"Style of file name display in *xref* buffers.
@@ -118,19 +135,20 @@ in its full absolute form."
;; FIXME: might be useful to have an optional "hint" i.e. a string to
;; search for in case the line number is slightly out of date.
-(defclass xref-file-location (xref-location)
- ((file :type string :initarg :file)
- (line :type fixnum :initarg :line :reader xref-location-line)
- (column :type fixnum :initarg :column :reader xref-file-location-column))
- :documentation "A file location is a file/line/column triple.
-Line numbers start from 1 and columns from 0.")
+(cl-defstruct (xref-file-location
+ (:constructor xref-make-file-location (file line column)))
+ "A file location is a file/line/column triple.
+Line numbers start from 1 and columns from 0."
+ file line column)
+
+(cl-defmethod xref-location-group ((l xref-file-location))
+ (xref-file-location-file l))
-(defun xref-make-file-location (file line column)
- "Create and return a new `xref-file-location'."
- (make-instance 'xref-file-location :file file :line line :column column))
+(cl-defmethod xref-location-line ((l xref-file-location))
+ (xref-file-location-line l))
(cl-defmethod xref-location-marker ((l xref-file-location))
- (with-slots (file line column) l
+ (pcase-let (((cl-struct xref-file-location file line column) l))
(with-current-buffer
(or (get-file-buffer file)
(let ((find-file-suppress-same-file-warnings t))
@@ -148,103 +166,58 @@ Line numbers start from 1 and columns from 0.")
(forward-char column))
(point-marker))))))
-(defvar xref--project-root-memo nil
- "Cons mapping `default-directory' value to the search root.")
-
-(cl-defmethod xref-location-group ((l xref-file-location))
- (cl-ecase xref-file-name-display
- (abs
- (oref l file))
- (nondirectory
- (file-name-nondirectory (oref l file)))
- (project-relative
- (unless (and xref--project-root-memo
- (equal (car xref--project-root-memo)
- default-directory))
- (setq xref--project-root-memo
- (cons default-directory
- (let ((root
- (let ((pr (project-current)))
- (and pr (xref--project-root pr)))))
- (and root (expand-file-name root))))))
- (let ((file (oref l file))
- (search-root (cdr xref--project-root-memo)))
- (if (and search-root
- (string-prefix-p search-root file))
- (substring file (length search-root))
- file)))))
-
-(defclass xref-buffer-location (xref-location)
- ((buffer :type buffer :initarg :buffer)
- (position :type fixnum :initarg :position)))
-
-(defun xref-make-buffer-location (buffer position)
- "Create and return a new `xref-buffer-location'."
- (make-instance 'xref-buffer-location :buffer buffer :position position))
+(cl-defstruct (xref-buffer-location
+ (:constructor xref-make-buffer-location (buffer position)))
+ buffer position)
(cl-defmethod xref-location-marker ((l xref-buffer-location))
- (with-slots (buffer position) l
+ (pcase-let (((cl-struct xref-buffer-location buffer position) l))
(let ((m (make-marker)))
(move-marker m position buffer))))
(cl-defmethod xref-location-group ((l xref-buffer-location))
- (with-slots (buffer) l
+ (pcase-let (((cl-struct xref-buffer-location buffer) l))
(or (buffer-file-name buffer)
(format "(buffer %s)" (buffer-name buffer)))))
-(defclass xref-bogus-location (xref-location)
- ((message :type string :initarg :message
- :reader xref-bogus-location-message))
- :documentation "Bogus locations are sometimes useful to
-indicate errors, e.g. when we know that a function exists but the
-actual location is not known.")
-
-(defun xref-make-bogus-location (message)
- "Create and return a new `xref-bogus-location'."
- (make-instance 'xref-bogus-location :message message))
+(cl-defstruct (xref-bogus-location
+ (:constructor xref-make-bogus-location (message)))
+ "Bogus locations are sometimes useful to indicate errors,
+e.g. when we know that a function exists but the actual location
+is not known."
+ message)
(cl-defmethod xref-location-marker ((l xref-bogus-location))
- (user-error "%s" (oref l message)))
+ (user-error "%s" (xref-bogus-location-message l)))
(cl-defmethod xref-location-group ((_ xref-bogus-location)) "(No location)")
;;; Cross-reference
-(defclass xref-item ()
- ((summary :type string :initarg :summary
- :reader xref-item-summary
- :documentation "One line which will be displayed for
-this item in the output buffer.")
- (location :initarg :location
- :reader xref-item-location
- :documentation "An object describing how to navigate
-to the reference's target."))
- :comment "An xref item describes a reference to a location
-somewhere.")
-
-(defun xref-make (summary location)
- "Create and return a new `xref-item'.
-SUMMARY is a short string to describe the xref.
-LOCATION is an `xref-location'."
- (make-instance 'xref-item :summary summary :location location))
-
-(defclass xref-match-item ()
- ((summary :type string :initarg :summary
- :reader xref-item-summary)
- (location :initarg :location
- :type xref-file-location
- :reader xref-item-location)
- (length :initarg :length :reader xref-match-length))
- :comment "A match xref item describes a search result.")
-
-(defun xref-make-match (summary location length)
- "Create and return a new `xref-match-item'.
-SUMMARY is a short string to describe the xref.
-LOCATION is an `xref-location'.
-LENGTH is the match length, in characters."
- (make-instance 'xref-match-item :summary summary
- :location location :length length))
+(defmacro xref--defstruct (name &rest fields)
+ (declare (indent 1))
+ `(cl-defstruct ,(if (>= emacs-major-version 27)
+ name
+ (remq (assq :noinline name) name))
+ ,@fields))
+
+(xref--defstruct (xref-item
+ (:constructor xref-make (summary location))
+ (:noinline t))
+ "An xref item describes a reference to a location somewhere."
+ summary location)
+
+(xref--defstruct (xref-match-item
+ (:include xref-item)
+ (:constructor xref-make-match (summary location length))
+ (:noinline t))
+ "A match xref item describes a search result."
+ length)
+
+(cl-defgeneric xref-match-length ((item xref-match-item))
+ "Return the length of the match."
+ (xref-match-item-length item))
;;; API
@@ -270,7 +243,7 @@ generic functions.")
The result must be a list of xref objects. If IDENTIFIER
contains sufficient information to determine a unique definition,
-return only that definition. If there are multiple possible
+return only that definition. If there are multiple possible
definitions, return all of them. If no definitions can be found,
return nil.
@@ -290,7 +263,11 @@ find a search tool; by default, this uses \"find | grep\" in the
current project's main and external roots."
(mapcan
(lambda (dir)
- (xref-references-in-directory identifier dir))
+ (message "Searching %s..." dir)
+ (redisplay)
+ (prog1
+ (xref-references-in-directory identifier dir)
+ (message "Searching %s... done" dir)))
(let ((pr (project-current t)))
(cons
(xref--project-root pr)
@@ -326,20 +303,19 @@ recognize and then delegate the work to an external process."
;;; misc utilities
-(defun xref--alistify (list key test)
+(defun xref--alistify (list key)
"Partition the elements of LIST into an alist.
-KEY extracts the key from an element and TEST is used to compare
-keys."
- (let ((alist '()))
+KEY extracts the key from an element."
+ (let ((table (make-hash-table :test #'equal)))
(dolist (e list)
(let* ((k (funcall key e))
- (probe (cl-assoc k alist :test test)))
+ (probe (gethash k table)))
(if probe
- (setcdr probe (cons e (cdr probe)))
- (push (cons k (list e)) alist))))
+ (puthash k (cons e probe) table)
+ (puthash k (list e) table))))
;; Put them back in order.
- (cl-loop for (key . value) in (reverse alist)
- collect (cons key (reverse value)))))
+ (cl-loop for key being hash-keys of table using (hash-values value)
+ collect (cons key (nreverse value)))))
(defun xref--insert-propertized (props &rest strings)
"Insert STRINGS with text properties PROPS."
@@ -365,15 +341,9 @@ backward."
(t (goto-char start) nil))))
-;;; Marker stack (M-. pushes, M-, pops)
-
-(defcustom xref-marker-ring-length 16
- "Length of the xref marker ring.
-If this variable is not set through Customize, you must call
-`xref-set-marker-ring-length' for changes to take effect."
- :type 'integer
- :initialize #'custom-initialize-default
- :set #'xref-set-marker-ring-length)
+;; Dummy variable retained for compatibility.
+(defvar xref-marker-ring-length 16)
+(make-obsolete-variable 'xref-marker-ring-length nil "29.1")
(defcustom xref-prompt-for-identifier '(not xref-find-definitions
xref-find-definitions-other-window
@@ -412,29 +382,91 @@ elements is negated: these commands will NOT prompt."
:version "28.1"
:package-version '(xref . "1.0.4"))
-(defvar xref--marker-ring (make-ring xref-marker-ring-length)
- "Ring of markers to implement the marker stack.")
+(defcustom xref-auto-jump-to-first-definition nil
+ "If t, `xref-find-definitions' always jumps to the first result.
+`show' means to show the first result's location, but keep the
+focus on the Xref buffer's window.
+`move' means to only move point to the first result.
+This variable also affects the variants of `xref-find-definitions',
+such as `xref-find-definitions-other-window'."
+ :type '(choice (const :tag "Jump" t)
+ (const :tag "Show" show)
+ (const :tag "Move point only" move)
+ (const :tag "No auto-jump" nil))
+ :version "28.1"
+ :package-version '(xref . "1.2.0"))
+
+(defcustom xref-auto-jump-to-first-xref nil
+ "If t, `xref-find-references' always jumps to the first result.
+`show' means to show the first result's location, but keep the
+focus on the Xref buffer's window.
+`move' means to only move point to the first result.
+This variable also affects commands similar to `xref-find-references',
+such as `xref-find-references-at-mouse', `xref-find-apropos',
+and `project-find-regexp'.
+
+Please be careful when changing the value if you are using Emacs 27
+or earlier: it can break `dired-do-find-regexp-and-replace'."
+ :type '(choice (const :tag "Jump" t)
+ (const :tag "Show" show)
+ (const :tag "Move point only" move)
+ (const :tag "No auto-jump" nil))
+ :version "28.1"
+ :package-version '(xref . "1.2.0"))
+
+(make-obsolete-variable 'xref-marker-ring nil "29.1")
+
+(defun xref-set-marker-ring-length (_var _val)
+ (declare (obsolete nil "29.1"))
+ nil)
+
+(defvar xref--history (cons nil nil)
+ "(BACKWARD-STACK . FORWARD-STACK) of markers to visited Xref locations.")
-(defun xref-set-marker-ring-length (var val)
- "Set `xref-marker-ring-length'.
-VAR is the symbol `xref-marker-ring-length' and VAL is the new
-value."
- (set-default var val)
- (if (ring-p xref--marker-ring)
- (ring-resize xref--marker-ring val)))
+(defun xref--push-backward (m)
+ "Push marker M onto the backward history stack."
+ (unless (equal m (caar xref--history))
+ (push m (car xref--history))))
+
+(defun xref--push-forward (m)
+ "Push marker M onto the forward history stack."
+ (unless (equal m (cadr xref--history))
+ (push m (cdr xref--history))))
(defun xref-push-marker-stack (&optional m)
- "Add point M (defaults to `point-marker') to the marker stack."
- (ring-insert xref--marker-ring (or m (point-marker))))
+ "Add point M (defaults to `point-marker') to the marker stack.
+The future stack is erased."
+ (xref--push-backward (or m (point-marker)))
+ (dolist (mk (cdr xref--history))
+ (set-marker mk nil nil))
+ (setcdr xref--history nil))
+
+;;;###autoload
+(define-obsolete-function-alias 'xref-pop-marker-stack #'xref-go-back "29.1")
+
+;;;###autoload
+(defun xref-go-back ()
+ "Go back to the previous position in xref history.
+To undo, use \\[xref-go-forward]."
+ (interactive)
+ (if (null (car xref--history))
+ (user-error "At start of xref history")
+ (let ((marker (pop (car xref--history))))
+ (xref--push-forward (point-marker))
+ (switch-to-buffer (or (marker-buffer marker)
+ (user-error "The marked buffer has been deleted")))
+ (goto-char (marker-position marker))
+ (set-marker marker nil nil)
+ (run-hooks 'xref-after-return-hook))))
;;;###autoload
-(defun xref-pop-marker-stack ()
- "Pop back to where \\[xref-find-definitions] was last invoked."
+(defun xref-go-forward ()
+ "Got to the point where a previous \\[xref-go-back] was invoked."
(interactive)
- (let ((ring xref--marker-ring))
- (when (ring-empty-p ring)
- (user-error "Marker stack is empty"))
- (let ((marker (ring-remove ring 0)))
+ (if (null (cdr xref--history))
+ (user-error "At end of xref history")
+ (let ((marker (pop (cdr xref--history))))
+ (xref--push-backward (point-marker))
(switch-to-buffer (or (marker-buffer marker)
(user-error "The marked buffer has been deleted")))
(goto-char (marker-position marker))
@@ -457,17 +489,23 @@ value."
;; etags.el needs this
(defun xref-clear-marker-stack ()
- "Discard all markers from the marker stack."
- (let ((ring xref--marker-ring))
- (while (not (ring-empty-p ring))
- (let ((marker (ring-remove ring)))
- (set-marker marker nil nil)))))
+ "Discard all markers from the xref history."
+ (dolist (l (list (car xref--history) (cdr xref--history)))
+ (dolist (m l)
+ (set-marker m nil nil)))
+ (setq xref--history (cons nil nil))
+ nil)
;;;###autoload
(defun xref-marker-stack-empty-p ()
- "Return t if the marker stack is empty; nil otherwise."
- (ring-empty-p xref--marker-ring))
+ "Whether the xref back-history is empty."
+ (null (car xref--history)))
+;; FIXME: rename this to `xref-back-history-empty-p'.
+;;;###autoload
+(defun xref-forward-history-empty-p ()
+ "Whether the xref forward-history is empty."
+ (null (cdr xref--history)))
(defun xref--goto-char (pos)
@@ -478,7 +516,7 @@ value."
(goto-char pos))
(defun xref--goto-location (location)
- "Set buffer and point according to xref-location LOCATION."
+ "Set buffer and point according to `xref-location' LOCATION."
(let ((marker (xref-location-marker location)))
(set-buffer (marker-buffer marker))
(xref--goto-char marker)))
@@ -486,9 +524,9 @@ value."
(defun xref-pop-to-location (item &optional action)
"Go to the location of ITEM and display the buffer.
ACTION controls how the buffer is displayed:
- nil -- switch-to-buffer
- `window' -- pop-to-buffer (other window)
- `frame' -- pop-to-buffer (other frame)
+ nil -- `switch-to-buffer'
+ `window' -- `pop-to-buffer' (other window)
+ `frame' -- `pop-to-buffer' (other frame)
If SELECT is non-nil, select the target window."
(let* ((marker (save-excursion
(xref-location-marker (xref-item-location item))))
@@ -596,12 +634,19 @@ SELECT is `quit', also quit the *xref* window."
(xref--show-pos-in-buf marker buf))))))
(user-error (message (error-message-string err)))))
+(defun xref--set-arrow ()
+ "Set the overlay arrow at the line at point."
+ (setq overlay-arrow-position
+ (set-marker (or overlay-arrow-position (make-marker))
+ (line-beginning-position))))
+
(defun xref-show-location-at-point ()
"Display the source of xref at point in the appropriate window, if any."
(interactive)
(let* ((xref (xref--item-at-point))
(xref--current-item xref))
(when xref
+ (xref--set-arrow)
(xref--show-location (xref-item-location xref)))))
(defun xref-next-line-no-show ()
@@ -659,6 +704,7 @@ quit the *xref* buffer."
(xref (or (xref--item-at-point)
(user-error "Choose a reference to visit")))
(xref--current-item xref))
+ (xref--set-arrow)
(xref--show-location (xref-item-location xref) (if quit 'quit t))
(if (fboundp 'next-error-found)
(next-error-found buffer (current-buffer))
@@ -674,7 +720,7 @@ quit the *xref* buffer."
"Quit *xref* buffer, then pop the xref marker stack."
(interactive)
(quit-window)
- (xref-pop-marker-stack))
+ (xref-go-back))
(defun xref-query-replace-in-results (from to)
"Perform interactive replacement of FROM with TO in all displayed xrefs.
@@ -739,7 +785,7 @@ references displayed in the current *xref* buffer."
(defun xref--outdated-p (item)
"Check that the match location at current position is up-to-date.
-ITEMS is an xref item which "
+ITEMS is an xref item which " ; FIXME: Expand documentation.
;; FIXME: The check should most likely be a generic function instead
;; of the assumption that all matches' summaries relate to the
;; buffer text in a particular way.
@@ -877,18 +923,21 @@ beginning of the line."
;; it gets reset to that window's point from time to time).
(let ((win (get-buffer-window (current-buffer))))
(and win (set-window-point win (point))))
- (xref--show-location (xref-item-location xref) t))
+ (xref--set-arrow)
+ (let ((xref--current-item xref))
+ (xref--show-location (xref-item-location xref) t)))
(t
(error "No %s xref" (if backward "previous" "next"))))))
(defvar xref--button-map
(let ((map (make-sparse-keymap)))
(define-key map [mouse-1] #'xref-goto-xref)
- (define-key map [mouse-2] #'xref--mouse-2)
+ (define-key map [mouse-2] #'xref-select-and-show-xref)
map))
-(defun xref--mouse-2 (event)
- "Move point to the button and show the xref definition."
+(defun xref-select-and-show-xref (event)
+ "Move point to the button and show the xref definition.
+The window showing the xref buffer will be selected."
(interactive "e")
(mouse-set-point event)
(forward-line 0)
@@ -896,6 +945,9 @@ beginning of the line."
(xref--search-property 'xref-item))
(xref-show-location-at-point))
+(define-obsolete-function-alias
+ 'xref--mouse-2 #'xref-select-and-show-xref "28.1")
+
(defcustom xref-truncation-width 400
"The column to visually \"truncate\" each Xref buffer line to."
:type '(choice
@@ -935,50 +987,48 @@ beginning of the line."
(put-text-property (+ pos xref-truncation-width) eol 'invisible 'ellipsis))))))
(defun xref--insert-xrefs (xref-alist)
- "Insert XREF-ALIST in the current-buffer.
+ "Insert XREF-ALIST in the current buffer.
XREF-ALIST is of the form ((GROUP . (XREF ...)) ...), where
GROUP is a string for decoration purposes and XREF is an
`xref-item' object."
(require 'compile) ; For the compilation faces.
- (cl-loop for ((group . xrefs) . more1) on xref-alist
- for max-line-width =
- (cl-loop for xref in xrefs
- maximize (let ((line (xref-location-line
- (oref xref location))))
- (length (and line (format "%d" line)))))
- for line-format = (and max-line-width
- (format "%%%dd: " max-line-width))
+ (cl-loop for (group . xrefs) in xref-alist
+ for max-line = (cl-loop for xref in xrefs
+ maximize (xref-location-line
+ (xref-item-location xref)))
+ for line-format = (and max-line
+ (format "%%%dd: " (1+ (floor (log max-line 10)))))
+ with item-text-props = (list 'mouse-face 'highlight
+ 'keymap xref--button-map
+ 'help-echo
+ (concat "mouse-2: display in another window, "
+ "RET or mouse-1: follow reference"))
with prev-group = nil
with prev-line = nil
do
(xref--insert-propertized '(face xref-file-header xref-group t)
group "\n")
- (cl-loop for (xref . more2) on xrefs do
- (with-slots (summary location) xref
- (let* ((line (xref-location-line location))
- (prefix
- (cond
- ((not line) " ")
- ((and (equal line prev-line)
- (equal prev-group group))
- "")
- (t (propertize (format line-format line)
- 'face 'xref-line-number)))))
- ;; Render multiple matches on the same line, together.
- (when (and (equal prev-group group)
- (or (null line)
- (not (equal prev-line line))))
- (insert "\n"))
- (xref--insert-propertized
- (list 'xref-item xref
- 'mouse-face 'highlight
- 'keymap xref--button-map
- 'help-echo
- (concat "mouse-2: display in another window, "
- "RET or mouse-1: follow reference"))
- prefix summary)
- (setq prev-line line
- prev-group group))))
+ (dolist (xref xrefs)
+ (pcase-let (((cl-struct xref-item summary location) xref))
+ (let* ((line (xref-location-line location))
+ (prefix
+ (cond
+ ((not line) " ")
+ ((and (equal line prev-line)
+ (equal prev-group group))
+ "")
+ (t (propertize (format line-format line)
+ 'face 'xref-line-number)))))
+ ;; Render multiple matches on the same line, together.
+ (when (and (equal prev-group group)
+ (or (null line)
+ (not (equal prev-line line))))
+ (insert "\n"))
+ (xref--insert-propertized (nconc (list 'xref-item xref)
+ item-text-props)
+ prefix summary)
+ (setq prev-line line
+ prev-group group))))
(insert "\n"))
(add-to-invisibility-spec '(ellipsis . t))
(save-excursion
@@ -987,13 +1037,49 @@ GROUP is a string for decoration purposes and XREF is an
(xref--apply-truncation)))
(run-hooks 'xref-after-update-hook))
+(defun xref--group-name-for-display (group project-root)
+ "Return GROUP formatted in the preferred style.
+
+The style is determined by the value of `xref-file-name-display'.
+If GROUP looks like a file name, its value is formatted according
+to that style. Otherwise it is returned unchanged."
+ ;; XXX: The way we verify that it's indeed a file name and not some
+ ;; other kind of string, e.g. Java package name or TITLE from
+ ;; `tags-apropos-additional-actions', is pretty lax. But we don't
+ ;; want to use `file-exists-p' for performance reasons. If this
+ ;; ever turns out to be a problem, some other alternatives are to
+ ;; either have every location type which uses file names format the
+ ;; values themselves (e.g. by piping through some public function),
+ ;; or adding a new accessor to locations, like GROUP-TYPE.
+ (cl-ecase xref-file-name-display
+ (abs group)
+ (nondirectory
+ (if (string-match-p "\\`~?/" group)
+ (file-name-nondirectory group)
+ group))
+ (project-relative
+ (if (and project-root
+ (string-prefix-p project-root group))
+ (substring group (length project-root))
+ group))))
+
(defun xref--analyze (xrefs)
- "Find common filenames in XREFS.
-Return an alist of the form ((FILENAME . (XREF ...)) ...)."
- (xref--alistify xrefs
- (lambda (x)
- (xref-location-group (xref-item-location x)))
- #'equal))
+ "Find common groups in XREFS and format group names.
+Return an alist of the form ((GROUP . (XREF ...)) ...)."
+ (let* ((alist
+ (xref--alistify xrefs
+ (lambda (x)
+ (xref-location-group (xref-item-location x)))))
+ (project (and
+ (eq xref-file-name-display 'project-relative)
+ (project-current)))
+ (project-root (and project
+ (expand-file-name (xref--project-root project)))))
+ (mapcar
+ (lambda (pair)
+ (cons (xref--group-name-for-display (car pair) project-root)
+ (cdr pair)))
+ alist)))
(defun xref--show-xref-buffer (fetcher alist)
(cl-assert (functionp fetcher))
@@ -1002,13 +1088,16 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
(assoc-default 'fetched-xrefs alist)
(funcall fetcher)))
(xref-alist (xref--analyze xrefs))
- (dd default-directory))
+ (dd default-directory)
+ buf)
(with-current-buffer (get-buffer-create xref-buffer-name)
(setq default-directory dd)
(xref--xref-buffer-mode)
(xref--show-common-initialize xref-alist fetcher alist)
(pop-to-buffer (current-buffer))
- (current-buffer))))
+ (setq buf (current-buffer)))
+ (xref--auto-jump-first buf (assoc-default 'auto-jump alist))
+ buf))
(defun xref--project-root (project)
(if (fboundp 'project-root)
@@ -1019,8 +1108,10 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
(defun xref--show-common-initialize (xref-alist fetcher alist)
(setq buffer-undo-list nil)
(let ((inhibit-read-only t)
- (buffer-undo-list t))
+ (buffer-undo-list t)
+ (inhibit-modification-hooks t))
(erase-buffer)
+ (setq overlay-arrow-position nil)
(xref--insert-xrefs xref-alist)
(add-hook 'post-command-hook 'xref--apply-truncation nil t)
(goto-char (point-min))
@@ -1032,7 +1123,8 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
"Refresh the search results in the current buffer."
(interactive)
(let ((inhibit-read-only t)
- (buffer-undo-list t))
+ (buffer-undo-list t)
+ (inhibit-modification-hooks t))
(save-excursion
(condition-case err
(let ((alist (xref--analyze (funcall xref--fetcher))))
@@ -1045,19 +1137,36 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
(error-message-string err)
'face 'error)))))))
+(defun xref--auto-jump-first (buf value)
+ (when value
+ (select-window (get-buffer-window buf))
+ (goto-char (point-min)))
+ (cond
+ ((eq value t)
+ (xref-next-line-no-show)
+ (xref-goto-xref))
+ ((eq value 'show)
+ (xref-next-line))
+ ((eq value 'move)
+ (forward-line 1))))
+
(defun xref-show-definitions-buffer (fetcher alist)
"Show the definitions list in a regular window.
When only one definition found, jump to it right away instead."
- (let ((xrefs (funcall fetcher)))
+ (let ((xrefs (funcall fetcher))
+ buf)
(cond
((not (cdr xrefs))
(xref-pop-to-location (car xrefs)
(assoc-default 'display-action alist)))
(t
- (xref--show-xref-buffer fetcher
- (cons (cons 'fetched-xrefs xrefs)
- alist))))))
+ (setq buf
+ (xref--show-xref-buffer fetcher
+ (cons (cons 'fetched-xrefs xrefs)
+ alist)))
+ (xref--auto-jump-first buf (assoc-default 'auto-jump alist))
+ buf))))
(define-obsolete-function-alias
'xref--show-defs-buffer #'xref-show-definitions-buffer "28.1")
@@ -1073,7 +1182,8 @@ local keymap that binds `RET' to `xref-quit-and-goto-xref'."
;; XXX: Make percentage customizable maybe?
(max-height (/ (window-height) 2))
(size-fun (lambda (window)
- (fit-window-to-buffer window max-height))))
+ (fit-window-to-buffer window max-height)))
+ buf)
(cond
((not (cdr xrefs))
(xref-pop-to-location (car xrefs)
@@ -1086,7 +1196,9 @@ local keymap that binds `RET' to `xref-quit-and-goto-xref'."
(pop-to-buffer (current-buffer)
`(display-buffer-in-direction . ((direction . below)
(window-height . ,size-fun))))
- (current-buffer))))))
+ (setq buf (current-buffer)))
+ (xref--auto-jump-first buf (assoc-default 'auto-jump alist))
+ buf))))
(define-obsolete-function-alias 'xref--show-defs-buffer-at-bottom
#'xref-show-definitions-buffer-at-bottom "28.1")
@@ -1118,22 +1230,23 @@ between them by typing in the minibuffer with completion."
(cl-loop for ((group . xrefs) . more1) on xref-alist
do
(cl-loop for (xref . more2) on xrefs do
- (with-slots (summary location) xref
- (let* ((line (xref-location-line location))
- (line-fmt
- (if line
- (format #("%d:" 0 2 (face xref-line-number))
- line)
- ""))
- (group-prefix
- (substring group group-prefix-length))
- (group-fmt
- (propertize group-prefix
- 'face 'xref-file-header
- 'xref--group group-prefix))
- (candidate
- (format "%s:%s%s" group-fmt line-fmt summary)))
- (push (cons candidate xref) xref-alist-with-line-info)))))
+ (let* ((summary (xref-item-summary xref))
+ (location (xref-item-location xref))
+ (line (xref-location-line location))
+ (line-fmt
+ (if line
+ (format #("%d:" 0 2 (face xref-line-number))
+ line)
+ ""))
+ (group-prefix
+ (substring group group-prefix-length))
+ (group-fmt
+ (propertize group-prefix
+ 'face 'xref-file-header
+ 'xref--group group-prefix))
+ (candidate
+ (format "%s:%s%s" group-fmt line-fmt summary)))
+ (push (cons candidate xref) xref-alist-with-line-info))))
(setq xref (if (not (cdr xrefs))
(car xrefs)
@@ -1215,13 +1328,15 @@ definitions."
(setq xrefs 'called-already)))))))
(funcall xref-show-xrefs-function fetcher
`((window . ,(selected-window))
- (display-action . ,display-action))))
+ (display-action . ,display-action)
+ (auto-jump . ,xref-auto-jump-to-first-xref))))
(defun xref--show-defs (xrefs display-action)
(xref--push-markers)
(funcall xref-show-definitions-function xrefs
`((window . ,(selected-window))
- (display-action . ,display-action))))
+ (display-action . ,display-action)
+ (auto-jump . ,xref-auto-jump-to-first-definition))))
(defun xref--push-markers ()
(unless (region-active-p) (push-mark nil t))
@@ -1244,12 +1359,17 @@ definitions."
(xref--prompt-p this-command))
(let ((id
(completing-read
- (if def
- (format "%s (default %s): "
- (substring prompt 0 (string-match
- "[ :]+\\'" prompt))
- def)
- prompt)
+ ;; `format-prompt' is new in Emacs 28.1
+ (if (fboundp 'format-prompt)
+ (format-prompt (substring prompt 0 (string-match
+ "[ :]+\\'" prompt))
+ def)
+ (if def
+ (format "%s (default %s): "
+ (substring prompt 0 (string-match
+ "[ :]+\\'" prompt))
+ def)
+ prompt))
(xref-backend-identifier-completion-table backend)
nil nil nil
'xref--read-identifier-history def)))
@@ -1308,7 +1428,9 @@ prompt for it.
If sufficient information is available to determine a unique
definition for IDENTIFIER, display it in the selected window.
Otherwise, display the list of the possible definitions in a
-buffer where the user can select from the list."
+buffer where the user can select from the list.
+
+Use \\[xref-go-back] to return back to where you invoked this command."
(interactive (list (xref--read-identifier "Find definitions of: ")))
(xref--find-definitions identifier nil))
@@ -1348,12 +1470,28 @@ This command is intended to be bound to a mouse event."
(xref-find-definitions identifier)
(user-error "No identifier here"))))
+;;;###autoload
+(defun xref-find-references-at-mouse (event)
+ "Find references to the identifier at or around mouse click.
+This command is intended to be bound to a mouse event."
+ (interactive "e")
+ (let ((identifier
+ (save-excursion
+ (mouse-set-point event)
+ (xref-backend-identifier-at-point (xref-find-backend)))))
+ (if identifier
+ (let ((xref-prompt-for-identifier nil))
+ (xref-find-references identifier))
+ (user-error "No identifier here"))))
+
(declare-function apropos-parse-pattern "apropos" (pattern))
;;;###autoload
(defun xref-find-apropos (pattern)
"Find all meaningful symbols that match PATTERN.
-The argument has the same meaning as in `apropos'."
+The argument has the same meaning as in `apropos'.
+See `tags-apropos-additional-actions' for how to augment the
+output of this command when the backend is etags."
(interactive (list (read-string
"Search for pattern (word list or regexp): "
nil 'xref--read-pattern-history
@@ -1383,7 +1521,8 @@ The argument has the same meaning as in `apropos'."
;;; Key bindings
;;;###autoload (define-key esc-map "." #'xref-find-definitions)
-;;;###autoload (define-key esc-map "," #'xref-pop-marker-stack)
+;;;###autoload (define-key esc-map "," #'xref-go-back)
+;;;###autoload (define-key esc-map [?\C-,] #'xref-go-forward)
;;;###autoload (define-key esc-map "?" #'xref-find-references)
;;;###autoload (define-key esc-map [?\C-.] #'xref-find-apropos)
;;;###autoload (define-key ctl-x-4-map "." #'xref-find-definitions-other-window)
@@ -1469,18 +1608,18 @@ IGNORES is a list of glob patterns for files to ignore."
;; do that reliably enough, without creating false negatives?
(command (xref--rgrep-command (xref--regexp-to-extended regexp)
files
- (directory-file-name
- (file-name-unquote
- (file-local-name (expand-file-name dir))))
+ "."
ignores))
- (def default-directory)
+ (local-dir (directory-file-name
+ (file-name-unquote
+ (file-local-name (expand-file-name dir)))))
(buf (get-buffer-create " *xref-grep*"))
(`(,grep-re ,file-group ,line-group . ,_) (car grep-regexp-alist))
(status nil)
(hits nil))
(with-current-buffer buf
(erase-buffer)
- (setq default-directory def)
+ (setq default-directory dir)
(setq status
(process-file-shell-command command nil t))
(goto-char (point-min))
@@ -1493,7 +1632,7 @@ IGNORES is a list of glob patterns for files to ignore."
(user-error "Search failed with status %d: %s" status (buffer-string)))
(while (re-search-forward grep-re nil t)
(push (list (string-to-number (match-string line-group))
- (match-string file-group)
+ (concat local-dir (substring (match-string file-group) 1))
(buffer-substring-no-properties (point) (line-end-position)))
hits)))
(xref--convert-hits (nreverse hits) regexp)))
@@ -1514,16 +1653,11 @@ IGNORES is a list of glob patterns for files to ignore."
'((grep
.
;; '-s' because 'git ls-files' can output broken symlinks.
- "xargs -0 grep <C> -snHE -e <R>")
+ "xargs -0 grep <C> --null -snHE -e <R>")
(ripgrep
.
- ;; Note: by default, ripgrep's output order is non-deterministic
- ;; (https://github.com/BurntSushi/ripgrep/issues/152)
- ;; because it does the search in parallel. You can use the template
- ;; without the '| sort ...' part if GNU sort is not available on
- ;; your system and/or stable ordering is not important to you.
- ;; Note#2: '!*/' is there to filter out dirs (e.g. submodules).
- "xargs -0 rg <C> -nH --no-messages -g '!*/' -e <R> | sort -t: -k1,1 -k2n,2"
+ ;; '!*/' is there to filter out dirs (e.g. submodules).
+ "xargs -0 rg <C> --null -nH --no-messages -g '!*/' -e <R>"
))
"Associative list mapping program identifiers to command templates.
@@ -1545,8 +1679,12 @@ The template should have the following fields:
(defcustom xref-search-program 'grep
"The program to use for regexp search inside files.
-This must reference a corresponding entry in `xref-search-program-alist'."
- :type `(choice
+This must reference a corresponding entry in `xref-search-program-alist'.
+
+This variable is used in `xref-matches-in-files', which is the
+utility function used by commands like `dired-do-find-regexp' and
+`project-find-regexp'."
+ :type '(choice
(const :tag "Use Grep" grep)
(const :tag "Use ripgrep" ripgrep)
(symbol :tag "User defined"))
@@ -1557,7 +1695,10 @@ This must reference a corresponding entry in `xref-search-program-alist'."
(defun xref-matches-in-files (regexp files)
"Find all matches for REGEXP in FILES.
Return a list of xref values.
-FILES must be a list of absolute file names."
+FILES must be a list of absolute file names.
+
+See `xref-search-program' and `xref-search-program-alist' for how
+to control which program to use when looking for matches."
(cl-assert (consp files))
(require 'grep)
(defvar grep-highlight-matches)
@@ -1615,7 +1756,16 @@ FILES must be a list of absolute file names."
(match-string file-group)
(buffer-substring-no-properties (point) (line-end-position)))
hits)))
- (xref--convert-hits (nreverse hits) regexp)))
+ ;; By default, ripgrep's output order is non-deterministic
+ ;; (https://github.com/BurntSushi/ripgrep/issues/152)
+ ;; because it does the search in parallel.
+ ;; Grep's output also comes out in seemingly arbitrary order,
+ ;; though stable one. Let's sort both for better UI.
+ (setq hits
+ (sort (nreverse hits)
+ (lambda (h1 h2)
+ (string< (cadr h1) (cadr h2)))))
+ (xref--convert-hits hits regexp)))
(defun xref--process-file-region ( start end program
&optional buffer display
@@ -1662,6 +1812,11 @@ directory, used as the root of the ignore globs."
(cl-assert (not (string-match-p "\\`~" dir)))
(if (not ignores)
""
+ ;; TODO: All in-tree callers are passing in just "." or "./".
+ ;; We can simplify.
+ ;; And, if we ever end up deleting xref-matches-in-directory, move
+ ;; this function to the project package.
+ (setq dir (file-name-as-directory dir))
(concat
(shell-quote-argument "(")
" -path "
@@ -1714,18 +1869,20 @@ Such as the current syntax table and the applied syntax properties."
(defun xref--convert-hits (hits regexp)
(let (xref--last-file-buffer
- (tmp-buffer (generate-new-buffer " *xref-temp*")))
+ (tmp-buffer (generate-new-buffer " *xref-temp*"))
+ (remote-id (file-remote-p default-directory))
+ (syntax-needed (xref--regexp-syntax-dependent-p regexp)))
(unwind-protect
- (mapcan (lambda (hit) (xref--collect-matches hit regexp tmp-buffer))
+ (mapcan (lambda (hit)
+ (xref--collect-matches hit regexp tmp-buffer remote-id syntax-needed))
hits)
(kill-buffer tmp-buffer))))
-(defun xref--collect-matches (hit regexp tmp-buffer)
+(defun xref--collect-matches (hit regexp tmp-buffer remote-id syntax-needed)
(pcase-let* ((`(,line ,file ,text) hit)
- (remote-id (file-remote-p default-directory))
(file (and file (concat remote-id file)))
(buf (xref--find-file-buffer file))
- (syntax-needed (xref--regexp-syntax-dependent-p regexp)))
+ (inhibit-modification-hooks t))
(if buf
(with-current-buffer buf
(save-excursion
@@ -1762,34 +1919,36 @@ Such as the current syntax table and the applied syntax properties."
syntax-needed)))))
(defun xref--collect-matches-1 (regexp file line line-beg line-end syntax-needed)
- (let (match-pairs matches)
+ (let (matches
+ stop beg end
+ last-beg last-end
+ summary-end)
(when syntax-needed
(syntax-propertize line-end))
- (while (and
- ;; REGEXP might match an empty string. Or line.
- (or (null match-pairs)
- (> (point) line-beg))
- (re-search-forward regexp line-end t))
- (push (cons (match-beginning 0)
- (match-end 0))
- match-pairs))
- (setq match-pairs (nreverse match-pairs))
- (while match-pairs
- (let* ((beg-end (pop match-pairs))
- (beg-column (- (car beg-end) line-beg))
- (end-column (- (cdr beg-end) line-beg))
- (loc (xref-make-file-location file line beg-column))
- (summary (buffer-substring (if matches (car beg-end) line-beg)
- (if match-pairs
- (caar match-pairs)
- line-end))))
- (when matches
- (cl-decf beg-column (- (car beg-end) line-beg))
- (cl-decf end-column (- (car beg-end) line-beg)))
- (add-face-text-property beg-column end-column 'xref-match
- t summary)
- (push (xref-make-match summary loc (- end-column beg-column))
- matches)))
+ (while (not stop)
+ (if (and
+ ;; REGEXP might match an empty string. Or line.
+ (not (and last-beg (eql end line-beg)))
+ (re-search-forward regexp line-end t))
+ (setq beg (match-beginning 0)
+ end (match-end 0)
+ summary-end beg)
+ (setq stop t
+ summary-end line-end))
+ (when last-beg
+ (let* ((beg-column (- last-beg line-beg))
+ (end-column (- last-end line-beg))
+ (summary-start (if matches last-beg line-beg))
+ (summary (buffer-substring summary-start
+ summary-end))
+ (loc (xref-make-file-location file line beg-column)))
+ (add-face-text-property (- last-beg summary-start)
+ (- last-end summary-start)
+ 'xref-match t summary)
+ (push (xref-make-match summary loc (- end-column beg-column))
+ matches)))
+ (setq last-beg beg
+ last-end end))
(nreverse matches)))
(defun xref--find-file-buffer (file)
diff --git a/lisp/progmodes/xscheme.el b/lisp/progmodes/xscheme.el
index 70763319840..e7667ebf51f 100644
--- a/lisp/progmodes/xscheme.el
+++ b/lisp/progmodes/xscheme.el
@@ -562,7 +562,7 @@ The strings are concatenated and terminated by a newline."
(defun xscheme-yank (&optional arg)
"Insert the most recent expression at point.
-With just C-U as argument, same but put point in front (and mark at end).
+With just \\[universal-argument] as argument, same but put point in front (and mark at end).
With argument n, reinsert the nth most recently sent expression.
See also the commands \\[xscheme-yank-pop] and \\[xscheme-yank-push]."
(interactive "*P")
@@ -574,9 +574,8 @@ See also the commands \\[xscheme-yank-pop] and \\[xscheme-yank-push]."
(if (consp arg)
(exchange-point-and-mark)))
-;; Old name, to avoid errors in users' init files.
-(fset 'xscheme-yank-previous-send
- 'xscheme-yank)
+(define-obsolete-function-alias 'xscheme-yank-previous-send
+ #'xscheme-yank "29.1")
(defun xscheme-yank-pop (arg)
"Insert or replace a just-yanked expression with an older expression.
@@ -908,8 +907,8 @@ the remaining input.")
xscheme-signal-death-message)
(progn
(beep)
- (message
-"The Scheme process has died! Do M-x reset-scheme to restart it"))))))
+ (message (substitute-command-keys
+"The Scheme process has died! Type \\[reset-scheme] to restart it")))))))
(defun xscheme-process-filter-initialize (running-p)
(setq xscheme-process-filter-state 'idle)
diff --git a/lisp/ps-def.el b/lisp/ps-def.el
index b9c3ab57a26..4f8498d9ef2 100644
--- a/lisp/ps-def.el
+++ b/lisp/ps-def.el
@@ -5,7 +5,7 @@
;; Author: Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>
;; Kenichi Handa <handa@gnu.org> (multi-byte characters)
;; Keywords: wp, print, PostScript
-;; X-URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
+;; URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
;; Package: ps-print
;; This file is part of GNU Emacs.
diff --git a/lisp/ps-mule.el b/lisp/ps-mule.el
index ab8af40628a..2d1dcd2b686 100644
--- a/lisp/ps-mule.el
+++ b/lisp/ps-mule.el
@@ -1209,8 +1209,8 @@ V%s 0 /%s-latin1 /%s Latin1Encoding put\n"
(ps-output-prologue (format "ETOP%d %d %d put\n" i (car font) index))
(setq index (1+ index))))
(ps-output-prologue (format "/VTOP%d [%s] def\n" i
- (mapconcat #'(lambda (x)
- (format "F%02X" (cdr x)))
+ (mapconcat (lambda (x)
+ (format "F%02X" (cdr x)))
font-list " ")))))
;; Redefine fonts f0, f1, f2, f3, h0, h1, H0.
diff --git a/lisp/ps-print.el b/lisp/ps-print.el
index 1b8654ead2b..0fc95546794 100644
--- a/lisp/ps-print.el
+++ b/lisp/ps-print.el
@@ -9,7 +9,7 @@
;; Maintainer: Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>
;; Keywords: wp, print, PostScript
;; Version: 7.3.5
-;; X-URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
+;; URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
(eval-when-compile (require 'cl-lib))
@@ -450,7 +450,7 @@ Please send all bug fixes and enhancements to
;; (setq ps-left-header (list 'moe-func 'larry-var "(Curly)"))
;;
;; Note that Curly has the PostScript string delimiters inside his quotes --
-;; those aren't misplaced lisp delimiters!
+;; those aren't misplaced Lisp delimiters!
;;
;; Without them, PostScript would attempt to call the undefined function Curly,
;; which would result in a PostScript error.
@@ -676,7 +676,7 @@ Please send all bug fixes and enhancements to
;; Valid values for `ps-print-control-characters' are:
;;
;; 8-bit This is the value to use when you want an ASCII encoding of
-;; any control or non-ASCII character. Control characters are
+;; any control or non-ASCII character. Control characters are
;; encoded as "^D", and non-ASCII characters have an
;; octal encoding.
;;
@@ -689,7 +689,7 @@ Please send all bug fixes and enhancements to
;; European 8-bits accented characters are printed according
;; the current font.
;;
-;; nil No ASCII encoding. Any character is printed according the
+;; nil No ASCII encoding. Any character is printed according the
;; current font.
;;
;; Any other value is treated as nil.
@@ -968,7 +968,7 @@ Please send all bug fixes and enhancements to
;; ps-font-info-database))
;; - Now you can use this font family with any size:
;; (setq ps-font-family 'Helvetica)
-;; - if you want to use this family in another emacs session, you must put into
+;; - if you want to use this family in another Emacs session, you must put into
;; your `~/.emacs':
;; (require 'ps-print)
;; (setq ps-font-info-database (append ...)))
@@ -1101,7 +1101,7 @@ Please send all bug fixes and enhancements to
;; -----------------------
;;
;; As ps-print uses PostScript to print buffers, it is possible to have other
-;; attributes associated with faces. So the new attributes used by ps-print
+;; attributes associated with faces. So the new attributes used by ps-print
;; are:
;;
;; strikeout - like underline, but the line is in middle of text.
@@ -1423,7 +1423,7 @@ Please send all bug fixes and enhancements to
;; * Check `ps-paper-type': Sudhakar Frederick <sfrederi@asc.corp.mot.com>
;;
;; Thanks to Jacques Duthen <duthen@cegelec-red.fr> (Jack) for version 3.4 I
-;; started from. [vinicius]
+;; started from. [vinicius]
;;
;; Thanks to Jim Thompson <?@?> for the 2.8 version I started from. [jack]
;;
@@ -2788,7 +2788,7 @@ Each element comprises: font family (the key), name, bold, italic, bold-italic,
reference size, line height, space width, average character width.
To get the info for another specific font (say Helvetica), do the following:
- create a new buffer
-- generate the PostScript image to a file (C-u M-x ps-print-buffer)
+- generate the PostScript image to a file (\\[universal-argument] \\[ps-print-buffer])
- open this file and delete the leading `%' (which is the PostScript comment
character) from the line
`% 3 cm 20 cm moveto 10/Courier ReportFontInfo showpage'
@@ -3855,7 +3855,7 @@ It can be retrieved with `(ps-get ALIST-SYM KEY)'."
(defun ps-color-scale (color)
;; Scale 16-bit X-COLOR-VALUE to PostScript color value in [0, 1] interval.
- (mapcar #'(lambda (value) (/ value ps-print-color-scale))
+ (mapcar (lambda (value) (/ value ps-print-color-scale))
(color-values color)))
@@ -3878,7 +3878,7 @@ Note: No major/minor-mode is activated and no local variables are evaluated for
(with-temp-buffer
(insert-file-contents filename)
(buffer-string))
- (error "ps-print PostScript prologue `%s' file was not found"
+ (error "ps-print: PostScript prologue `%s' file was not found"
filename))))
@@ -4747,11 +4747,11 @@ page-height == ((floor print-height ((th + ls) * zh)) * ((th + ls) * zh)) - th
(defun ps-background-pages (page-list func)
(if page-list
(mapcar
- #'(lambda (pages)
- (let ((start (if (consp pages) (car pages) pages))
- (end (if (consp pages) (cdr pages) pages)))
- (and (integerp start) (integerp end) (<= start end)
- (add-to-list 'ps-background-pages (vector start end func)))))
+ (lambda (pages)
+ (let ((start (if (consp pages) (car pages) pages))
+ (end (if (consp pages) (cdr pages) pages)))
+ (and (integerp start) (integerp end) (<= start end)
+ (add-to-list 'ps-background-pages (vector start end func)))))
page-list)
(setq ps-background-all-pages (cons func ps-background-all-pages))))
@@ -4789,76 +4789,76 @@ page-height == ((floor print-height ((th + ls) * zh)) * ((th + ls) * zh)) - th
(defun ps-background-text ()
(mapcar
- #'(lambda (text)
- (setq ps-background-text-count (1+ ps-background-text-count))
- (ps-output (format "/ShowBackText-%d{\n" ps-background-text-count))
- (ps-output-string (nth 0 text)) ; text
- (ps-output
- "\n"
- (ps-float-format (nth 4 text) 200.0) ; font size
- (format "/%s " (or (nth 3 text) "Times-Roman")) ; font name
- (ps-float-format (nth 6 text)
- "PrintHeight PrintPageWidth atan") ; rotation
- (ps-float-format (nth 5 text) 0.85) ; gray
- (ps-float-format (nth 1 text) "0") ; x position
- (ps-float-format (nth 2 text) "0") ; y position
- "\nShowBackText}def\n")
- (ps-background-pages (nthcdr 7 text) ; page list
- (format "ShowBackText-%d\n"
- ps-background-text-count)))
+ (lambda (text)
+ (setq ps-background-text-count (1+ ps-background-text-count))
+ (ps-output (format "/ShowBackText-%d{\n" ps-background-text-count))
+ (ps-output-string (nth 0 text)) ; text
+ (ps-output
+ "\n"
+ (ps-float-format (nth 4 text) 200.0) ; font size
+ (format "/%s " (or (nth 3 text) "Times-Roman")) ; font name
+ (ps-float-format (nth 6 text)
+ "PrintHeight PrintPageWidth atan") ; rotation
+ (ps-float-format (nth 5 text) 0.85) ; gray
+ (ps-float-format (nth 1 text) "0") ; x position
+ (ps-float-format (nth 2 text) "0") ; y position
+ "\nShowBackText}def\n")
+ (ps-background-pages (nthcdr 7 text) ; page list
+ (format "ShowBackText-%d\n"
+ ps-background-text-count)))
ps-print-background-text))
(defun ps-background-image ()
(mapcar
- #'(lambda (image)
- (let ((image-file (expand-file-name (nth 0 image))))
- (when (file-readable-p image-file)
- (setq ps-background-image-count (1+ ps-background-image-count))
- (ps-output
- (format "/ShowBackImage-%d{\n--back-- "
- ps-background-image-count)
- (ps-float-format (nth 5 image) 0.0) ; rotation
- (ps-float-format (nth 3 image) 1.0) ; x scale
- (ps-float-format (nth 4 image) 1.0) ; y scale
- (ps-float-format (nth 1 image) ; x position
- "PrintPageWidth 2 div")
- (ps-float-format (nth 2 image) ; y position
- "PrintHeight 2 div BottomMargin add")
- "\nBeginBackImage\n")
- (ps-insert-file image-file)
- ;; coordinate adjustment to center image
- ;; around x and y position
- (let ((box (ps-get-boundingbox)))
- (with-current-buffer ps-spool-buffer
- (save-excursion
- (if (re-search-backward "^--back--" nil t)
- (replace-match
- (format "%s %s"
- (ps-float-format
- (- (+ (/ (- (aref box 2) (aref box 0)) 2.0)
- (aref box 0))))
- (ps-float-format
- (- (+ (/ (- (aref box 3) (aref box 1)) 2.0)
- (aref box 1)))))
- t)))))
- (ps-output "\nEndBackImage}def\n")
- (ps-background-pages (nthcdr 6 image) ; page list
- (format "ShowBackImage-%d\n"
- ps-background-image-count)))))
+ (lambda (image)
+ (let ((image-file (expand-file-name (nth 0 image))))
+ (when (file-readable-p image-file)
+ (setq ps-background-image-count (1+ ps-background-image-count))
+ (ps-output
+ (format "/ShowBackImage-%d{\n--back-- "
+ ps-background-image-count)
+ (ps-float-format (nth 5 image) 0.0) ; rotation
+ (ps-float-format (nth 3 image) 1.0) ; x scale
+ (ps-float-format (nth 4 image) 1.0) ; y scale
+ (ps-float-format (nth 1 image) ; x position
+ "PrintPageWidth 2 div")
+ (ps-float-format (nth 2 image) ; y position
+ "PrintHeight 2 div BottomMargin add")
+ "\nBeginBackImage\n")
+ (ps-insert-file image-file)
+ ;; coordinate adjustment to center image
+ ;; around x and y position
+ (let ((box (ps-get-boundingbox)))
+ (with-current-buffer ps-spool-buffer
+ (save-excursion
+ (if (re-search-backward "^--back--" nil t)
+ (replace-match
+ (format "%s %s"
+ (ps-float-format
+ (- (+ (/ (- (aref box 2) (aref box 0)) 2.0)
+ (aref box 0))))
+ (ps-float-format
+ (- (+ (/ (- (aref box 3) (aref box 1)) 2.0)
+ (aref box 1)))))
+ t)))))
+ (ps-output "\nEndBackImage}def\n")
+ (ps-background-pages (nthcdr 6 image) ; page list
+ (format "ShowBackImage-%d\n"
+ ps-background-image-count)))))
ps-print-background-image))
(defun ps-background (page-number)
(let (has-local-background)
- (mapc #'(lambda (range)
- (and (<= (aref range 0) page-number)
- (<= page-number (aref range 1))
- (if has-local-background
- (ps-output (aref range 2))
- (setq has-local-background t)
- (ps-output "/printLocalBackground{\n"
- (aref range 2)))))
+ (mapc (lambda (range)
+ (and (<= (aref range 0) page-number)
+ (<= page-number (aref range 1))
+ (if has-local-background
+ (ps-output (aref range 2))
+ (setq has-local-background t)
+ (ps-output "/printLocalBackground{\n"
+ (aref range 2)))))
ps-background-pages)
(and has-local-background (ps-output "}def\n"))))
@@ -5697,8 +5697,8 @@ XSTART YSTART are the relative position for the first page in a sheet.")
(> (car page) 0)
(<= (car page) (cdr page))
(setq new (cons page new))))))
- (setq ps-selected-pages (sort new #'(lambda (one other)
- (< (car one) (car other))))
+ (setq ps-selected-pages (sort new (lambda (one other)
+ (< (car one) (car other))))
ps-last-selected-pages ps-selected-pages
ps-first-page nil
ps-last-page nil))
@@ -5782,8 +5782,8 @@ XSTART YSTART are the relative position for the first page in a sheet.")
"unspecified-fg"
0.0)
ps-foreground-list (mapcar
- #'(lambda (arg)
- (ps-rgb-color arg "unspecified-fg" 0.0))
+ (lambda (arg)
+ (ps-rgb-color arg "unspecified-fg" 0.0))
(append (and (not (member ps-print-color-p
'(nil black-white)))
ps-fg-list)
@@ -6012,9 +6012,9 @@ XSTART YSTART are the relative position for the first page in a sheet.")
(if (and (boundp 'ucs-mule-8859-to-mule-unicode)
(char-table-p ucs-mule-8859-to-mule-unicode))
(map-char-table
- #'(lambda (k v)
- (if (and v (eq (char-charset v) 'latin-iso8859-1) (/= k v))
- (aset tbl k v)))
+ (lambda (k v)
+ (if (and v (eq (char-charset v) 'latin-iso8859-1) (/= k v))
+ (aset tbl k v)))
ucs-mule-8859-to-mule-unicode))
tbl)
"Translation table for PostScript printing.
diff --git a/lisp/ps-samp.el b/lisp/ps-samp.el
index 22a29b8b4b1..2f7de40da63 100644
--- a/lisp/ps-samp.el
+++ b/lisp/ps-samp.el
@@ -8,7 +8,7 @@
;; Kenichi Handa <handa@gnu.org> (multi-byte characters)
;; Maintainer: Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>
;; Keywords: wp, print, PostScript
-;; X-URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
+;; URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
;; Package: ps-print
;; This file is part of GNU Emacs.
diff --git a/lisp/recentf.el b/lisp/recentf.el
index 9ae059a70dd..6b5a47c66fd 100644
--- a/lisp/recentf.el
+++ b/lisp/recentf.el
@@ -674,55 +674,55 @@ Return nil if file NAME is not one of the ten more recent."
"Sort the list of menu elements L in ascending order.
The MENU-ITEM part of each menu element is compared."
(sort (copy-sequence l)
- #'(lambda (e1 e2)
- (recentf-string-lessp
- (recentf-menu-element-item e1)
- (recentf-menu-element-item e2)))))
+ (lambda (e1 e2)
+ (recentf-string-lessp
+ (recentf-menu-element-item e1)
+ (recentf-menu-element-item e2)))))
(defsubst recentf-sort-descending (l)
"Sort the list of menu elements L in descending order.
The MENU-ITEM part of each menu element is compared."
(sort (copy-sequence l)
- #'(lambda (e1 e2)
- (recentf-string-lessp
- (recentf-menu-element-item e2)
- (recentf-menu-element-item e1)))))
+ (lambda (e1 e2)
+ (recentf-string-lessp
+ (recentf-menu-element-item e2)
+ (recentf-menu-element-item e1)))))
(defsubst recentf-sort-basenames-ascending (l)
"Sort the list of menu elements L in ascending order.
Only filenames sans directory are compared."
(sort (copy-sequence l)
- #'(lambda (e1 e2)
- (recentf-string-lessp
- (file-name-nondirectory (recentf-menu-element-value e1))
- (file-name-nondirectory (recentf-menu-element-value e2))))))
+ (lambda (e1 e2)
+ (recentf-string-lessp
+ (file-name-nondirectory (recentf-menu-element-value e1))
+ (file-name-nondirectory (recentf-menu-element-value e2))))))
(defsubst recentf-sort-basenames-descending (l)
"Sort the list of menu elements L in descending order.
Only filenames sans directory are compared."
(sort (copy-sequence l)
- #'(lambda (e1 e2)
- (recentf-string-lessp
- (file-name-nondirectory (recentf-menu-element-value e2))
- (file-name-nondirectory (recentf-menu-element-value e1))))))
+ (lambda (e1 e2)
+ (recentf-string-lessp
+ (file-name-nondirectory (recentf-menu-element-value e2))
+ (file-name-nondirectory (recentf-menu-element-value e1))))))
(defsubst recentf-sort-directories-ascending (l)
"Sort the list of menu elements L in ascending order.
Compares directories then filenames to order the list."
(sort (copy-sequence l)
- #'(lambda (e1 e2)
- (recentf-directory-compare
- (recentf-menu-element-value e1)
- (recentf-menu-element-value e2)))))
+ (lambda (e1 e2)
+ (recentf-directory-compare
+ (recentf-menu-element-value e1)
+ (recentf-menu-element-value e2)))))
(defsubst recentf-sort-directories-descending (l)
"Sort the list of menu elements L in descending order.
Compares directories then filenames to order the list."
(sort (copy-sequence l)
- #'(lambda (e1 e2)
- (recentf-directory-compare
- (recentf-menu-element-value e2)
- (recentf-menu-element-value e1)))))
+ (lambda (e1 e2)
+ (recentf-directory-compare
+ (recentf-menu-element-value e2)
+ (recentf-menu-element-value e1)))))
(defun recentf-show-basenames (l &optional no-dir)
"Filter the list of menu elements L to show filenames sans directory.
@@ -1122,8 +1122,9 @@ IGNORE arguments."
(setq-local recentf-edit-list nil)
(widget-insert
(format-message
- "Click on OK to delete selected files from the recent list.
-Click on Cancel or type `q' to cancel.\n"))
+ (substitute-command-keys
+ "Click on OK to delete selected files from the recent list.
+Click on Cancel or type \\[recentf-cancel-dialog] to cancel.\n")))
;; Insert the list of files as checkboxes
(dolist (item recentf-list)
(widget-create 'checkbox
@@ -1221,7 +1222,8 @@ use for the dialog. It defaults to \"*`recentf-menu-title'*\"."
", or type the corresponding digit key,"
"")
" to open it.\n"
- (format-message "Click on Cancel or type `q' to cancel.\n"))
+ (substitute-command-keys
+ "Click on Cancel or type \\[recentf-cancel-dialog] to cancel.\n"))
;; Use a L&F that looks like the recentf menu.
(tree-widget-set-theme "folder")
(apply #'widget-create
@@ -1380,5 +1382,5 @@ buffers you switch to a lot, you can say something like the following:
(provide 'recentf)
(run-hooks 'recentf-load-hook)
-
+
;;; recentf.el ends here
diff --git a/lisp/rect.el b/lisp/rect.el
index 504be41b673..d288adfbaf6 100644
--- a/lisp/rect.el
+++ b/lisp/rect.el
@@ -202,8 +202,8 @@ rectangles, as conses of the form (WIDTH . HEIGHT)."
(<= (+ y2 h2) y1)))))
(defun rectangle-dimensions (start end)
- "Return the dimensions of the rectangle with corners at START
-and END. The returned value has the form of (WIDTH . HEIGHT)."
+ "Return the dimensions of the rectangle with corners at START and END.
+The returned value has the form of (WIDTH . HEIGHT)."
(save-excursion
(let* ((height (1+ (abs (- (line-number-at-pos end)
(line-number-at-pos start)))))
diff --git a/lisp/register.el b/lisp/register.el
index 11d98482cb4..38ee87cd775 100644
--- a/lisp/register.el
+++ b/lisp/register.el
@@ -102,7 +102,7 @@ If nil, do not show register previews, unless `help-char' (or a member of
(alist-get register register-alist))
(defun set-register (register value)
- "Set contents of Emacs register named REGISTER to VALUE. Returns VALUE.
+ "Set contents of Emacs register named REGISTER to VALUE. Return VALUE.
See the documentation of the variable `register-alist' for possible VALUEs."
(setf (alist-get register register-alist) value))
@@ -279,6 +279,8 @@ ARG is the value of the prefix argument or nil."
(goto-char (cadr val)))
((eq (car val) 'file)
(find-file (cdr val)))
+ ((eq (car val) 'buffer)
+ (switch-to-buffer (cdr val)))
((eq (car val) 'file-query)
(or (find-buffer-visiting (nth 1 val))
(y-or-n-p (format "Visit file %s again? " (nth 1 val)))
@@ -417,6 +419,11 @@ Interactively, reads the register using `register-read-with-preview'."
(prin1 (cdr val))
(princ "."))
+ ((eq (car val) 'buffer)
+ (princ "the buffer ")
+ (prin1 (cdr val))
+ (princ "."))
+
((eq (car val) 'file-query)
(princ "a file-query reference:\n file ")
(prin1 (car (cdr val)))
diff --git a/lisp/registry.el b/lisp/registry.el
index 258f7fc9046..c10ae91d169 100644
--- a/lisp/registry.el
+++ b/lisp/registry.el
@@ -60,7 +60,7 @@
;; The user decides which fields are "precious", F2 for example. When
;; the registry is pruned, any entries without the F2 field will be
;; removed until the size is :max-size * :prune-factor _less_ than the
-;; maximum database size. No entries with the F2 field will be removed
+;; maximum database size. No entries with the F2 field will be removed
;; at PRUNE TIME, which means it may not be possible to prune back all
;; the way to the target size.
@@ -326,7 +326,7 @@ Errors out if the key exists already."
Attempts to prune the number of entries down to \(*
:max-size :prune-factor) less than the max-size limit, so
-pruning doesn't need to happen on every save. Removes only
+pruning doesn't need to happen on every save. Removes only
entries without the :precious keys, so it may not be possible to
reach the target limit.
diff --git a/lisp/repeat.el b/lisp/repeat.el
index cec3cb643a1..ea6da5d7f9b 100644
--- a/lisp/repeat.el
+++ b/lisp/repeat.el
@@ -218,7 +218,7 @@ recently executed command not bound to an input event\"."
((null last-repeatable-command)
(error "There is nothing to repeat"))
((eq last-repeatable-command 'mode-exit)
- (error "last-repeatable-command is mode-exit & can't be repeated"))
+ (error "`last-repeatable-command' is `mode-exit' and can't be repeated"))
((memq last-repeatable-command repeat-too-dangerous)
(error "Command %S too dangerous to repeat automatically"
last-repeatable-command)))
@@ -344,8 +344,10 @@ For example, you can set it to <return> like `isearch-exit'."
(defcustom repeat-exit-timeout nil
"Break the repetition chain of keys after specified timeout.
-When a number, exit the repeat mode after idle time of the specified
-number of seconds."
+When a number, exit the transient repeating mode after idle time
+of the specified number of seconds.
+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
@@ -354,8 +356,26 @@ number of seconds."
(defvar repeat-exit-timer nil
"Timer activated after the last key typed in the repeating key sequence.")
-(defcustom repeat-keep-prefix t
- "Keep the prefix arg of the previous command."
+(defcustom repeat-keep-prefix nil
+ "Whether to keep the prefix arg of the previous command when repeating."
+ :type 'boolean
+ :group 'convenience
+ :version "28.1")
+
+(defcustom repeat-check-key t
+ "Whether to check that the last key exists in the repeat map.
+When non-nil and the last typed key (with or without modifiers)
+doesn't exist in the keymap attached by the `repeat-map' property,
+then don't activate that keymap for the next command. So only the
+same keys among repeatable keys are allowed in the repeating sequence.
+For example, with a non-nil value, only `C-x u u' repeats undo,
+whereas `C-/ u' doesn't.
+
+You can also set the property `repeat-check-key' on the command symbol.
+This property can override the value of this variable.
+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
:version "28.1")
@@ -363,7 +383,7 @@ number of seconds."
(defcustom repeat-echo-function #'repeat-echo-message
"Function to display a hint about available keys.
Function is called after every repeatable command with one argument:
-a repeating map, or nil after deactivating the repeat mode."
+a repeating map, or nil after deactivating the transient repeating mode."
:type '(choice (const :tag "Show hints in the echo area"
repeat-echo-message)
(const :tag "Show indicator in the mode line"
@@ -374,11 +394,11 @@ a repeating map, or nil after deactivating the repeat mode."
:version "28.1")
(defvar repeat-in-progress nil
- "Non-nil when the repeating map is active.")
+ "Non-nil when the repeating transient map is active.")
;;;###autoload
(defvar repeat-map nil
- "The value of the repeating map for the next command.
+ "The value of the repeating transient map for the next command.
A command called from the map can set it again to the same map when
the map can't be set on the command symbol property `repeat-map'.")
@@ -386,7 +406,8 @@ the map can't be set on the command symbol property `repeat-map'.")
(define-minor-mode repeat-mode
"Toggle Repeat mode.
When Repeat mode is enabled, and the command symbol has the property named
-`repeat-map', this map is activated temporarily for the next command."
+`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
(if (not repeat-mode)
(remove-hook 'post-command-hook 'repeat-post-hook)
@@ -401,24 +422,43 @@ When Repeat mode is enabled, and the command symbol has the property named
(length commands)
(length (delete-dups keymaps))))))
+(defvar repeat--prev-mb '(0)
+ "Previous minibuffer state.")
+
+(defun repeat--command-property (property)
+ (or (and (symbolp this-command)
+ (get this-command property))
+ (and (symbolp real-this-command)
+ (get real-this-command property))))
+
+(defun repeat-check-key (key map)
+ "Check if the last key is suitable to activate the repeating MAP."
+ (let* ((prop (repeat--command-property 'repeat-check-key))
+ (check-key (unless (eq prop 'no) (or prop repeat-check-key))))
+ (or (not check-key)
+ (lookup-key map (vector key))
+ ;; Try without modifiers:
+ (lookup-key map (vector (event-basic-type key))))))
+
(defun repeat-post-hook ()
"Function run after commands to set transient keymap for repeatable keys."
(let ((was-in-progress repeat-in-progress))
(setq repeat-in-progress nil)
(when repeat-mode
- (let ((rep-map (or repeat-map
- (and (symbolp real-this-command)
- (get real-this-command 'repeat-map)))))
+ (let ((rep-map (or repeat-map (repeat--command-property 'repeat-map))))
(when rep-map
- (when (boundp rep-map)
+ (when (and (symbolp rep-map) (boundp rep-map))
(setq rep-map (symbol-value rep-map)))
(let ((map (copy-keymap rep-map)))
- ;; Exit when the last char is not among repeatable keys,
- ;; so e.g. `C-x u u' repeats undo, whereas `C-/ u' doesn't.
- (when (and (zerop (minibuffer-depth)) ; avoid remapping in prompts
- (or (lookup-key map (this-command-keys-vector))
- prefix-arg))
+ (when (and
+ ;; Detect changes in the minibuffer state to allow repetitions
+ ;; in the same minibuffer, but not when the minibuffer is activated
+ ;; in the middle of repeating sequence (bug#47566).
+ (or (< (minibuffer-depth) (car repeat--prev-mb))
+ (eq current-minibuffer-command (cdr repeat--prev-mb)))
+ (or (not repeat-keep-prefix) prefix-arg)
+ (repeat-check-key last-command-event map))
;; Messaging
(unless prefix-arg
@@ -438,16 +478,19 @@ When Repeat mode is enabled, and the command symbol has the property named
(cancel-timer repeat-exit-timer)
(setq repeat-exit-timer nil))
- (when repeat-exit-timeout
- (setq repeat-exit-timer
- (run-with-idle-timer
- repeat-exit-timeout nil
- (lambda ()
- (setq repeat-in-progress nil)
- (funcall exitfun)
- (funcall repeat-echo-function nil)))))))))))
+ (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))))))))))))
(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)
@@ -469,13 +512,20 @@ When Repeat mode is enabled, and the command symbol has the property named
(defun repeat-echo-message (keymap)
"Display available repeating keys in the echo area."
- (if keymap
- (let ((mess (repeat-echo-message-string keymap)))
- (if (current-message)
- (message "%s [%s]" (current-message) mess)
- (message mess)))
- (when (string-prefix-p "Repeat with " (current-message))
- (message nil))))
+ (let ((message-log-max nil))
+ (if keymap
+ (let ((message (repeat-echo-message-string keymap)))
+ (if (current-message)
+ (message "%s [%s]" (current-message) message)
+ (message "%s" message)))
+ (let ((message (current-message)))
+ (when message
+ (cond
+ ((string-prefix-p "Repeat with " message)
+ (message nil))
+ ((string-search " [Repeat with " message)
+ (message "%s" (replace-regexp-in-string
+ " \\[Repeat with .*\\'" "" message)))))))))
(defvar repeat-echo-mode-line-string
(propertize "[Repeating...] " 'face 'mode-line-emphasis)
@@ -489,27 +539,39 @@ When Repeat mode is enabled, and the command symbol has the property named
repeat-echo-mode-line-string)))
(force-mode-line-update t)))
+(declare-function help-fns--analyze-function "help-fns" (function))
+
(defun describe-repeat-maps ()
- "Describe mappings of commands repeatable by symbol property `repeat-map'."
+ "Describe mappings of commands repeatable by symbol property `repeat-map'.
+Used in `repeat-mode'."
(interactive)
- (help-setup-xref (list #'describe-repeat-maps)
- (called-interactively-p 'interactive))
- (let ((keymaps nil))
- (all-completions
- "" obarray (lambda (s)
- (and (commandp s)
- (get s 'repeat-map)
- (push s (alist-get (get s 'repeat-map) keymaps)))))
- (with-help-window (help-buffer)
- (with-current-buffer standard-output
- (princ "A list of keymaps used by commands with the symbol property `repeat-map'.\n\n")
-
- (dolist (keymap (sort keymaps (lambda (a b) (string-lessp (car a) (car b)))))
- (princ (format-message "`%s' keymap is repeatable by these commands:\n"
- (car keymap)))
- (dolist (command (sort (cdr keymap) 'string-lessp))
- (princ (format-message " `%s'\n" command)))
- (princ "\n"))))))
+ (require 'help-fns)
+ (let ((help-buffer-under-preparation t))
+ (help-setup-xref (list #'describe-repeat-maps)
+ (called-interactively-p 'interactive))
+ (let ((keymaps nil))
+ (all-completions
+ "" obarray (lambda (s)
+ (and (commandp s)
+ (get s 'repeat-map)
+ (push s (alist-get (get s 'repeat-map) keymaps)))))
+ (with-help-window (help-buffer)
+ (with-current-buffer standard-output
+ (princ "A list of keymaps used by commands with the symbol property `repeat-map'.\n\n")
+
+ (dolist (keymap (sort keymaps (lambda (a b) (string-lessp (car a) (car b)))))
+ (princ (format-message "`%s' keymap is repeatable by these commands:\n"
+ (car keymap)))
+ (dolist (command (sort (cdr keymap) 'string-lessp))
+ (let* ((info (help-fns--analyze-function command))
+ (map (list (symbol-value (car keymap))))
+ (desc (mapconcat (lambda (key)
+ (format-message "`%s'" (key-description key)))
+ (or (where-is-internal command map)
+ (where-is-internal (nth 3 info) map))
+ ", ")))
+ (princ (format-message " `%s' (bound to %s)\n" command desc))))
+ (princ "\n")))))))
(provide 'repeat)
diff --git a/lisp/replace.el b/lisp/replace.el
index 69bdfe1331d..0e81b15a097 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -63,7 +63,7 @@ it will match any sequence matched by the regexp `search-whitespace-regexp'."
:version "24.3")
(defvar query-replace-history nil
- "Default history list for query-replace commands.
+ "Default history list for `query-replace' commands.
See `query-replace-from-history-variable' and
`query-replace-to-history-variable'.")
@@ -83,7 +83,7 @@ from Isearch by using a key sequence like `C-s C-s M-%'." "24.3")
(defcustom query-replace-from-to-separator " → "
"String that separates FROM and TO in the history of replacement pairs.
When nil, the pair will not be added to the history (same behavior
-as in emacs 24.5)."
+as in Emacs 24.5)."
:group 'matching
:type '(choice
(const :tag "Disabled" nil)
@@ -202,7 +202,7 @@ by this function to the end of values available via
(car (symbol-value query-replace-from-history-variable)))))
(defun query-replace-read-from (prompt regexp-flag)
- "Query and return the `from' argument of a query-replace operation.
+ "Query and return the `from' argument of a `query-replace' operation.
Prompt with PROMPT. REGEXP-FLAG non-nil means the response should be a regexp.
The return value can also be a pair (FROM . TO) indicating that the user
wants to replace FROM with TO."
@@ -326,8 +326,9 @@ the original string if not."
(defun query-replace-read-to (from prompt regexp-flag)
- "Query and return the `to' argument of a query-replace operation.
-Prompt with PROMPT. REGEXP-FLAG non-nil means the response should a regexp."
+ "Query and return the `to' argument of a `query-replace' operation.
+Prompt with PROMPT. REGEXP-FLAG non-nil means the response
+should a regexp."
(query-replace-compile-replacement
(save-excursion
(let* ((history-add-new-input nil)
@@ -796,7 +797,7 @@ of `history-length', which see.")
"Overlays used to temporarily highlight occur matches.")
(defvar occur-collect-regexp-history '("\\1")
- "History of regexp for occur's collect operation")
+ "History of regexp for occur's collect operation.")
(defcustom read-regexp-defaults-function nil
"Function that provides default regexp(s) for `read-regexp'.
@@ -1300,7 +1301,7 @@ See `occur-revert-function'.")
(defcustom occur-mode-find-occurrence-hook nil
"Hook run by Occur after locating an occurrence.
This will be called with the cursor position at the occurrence. An application
-for this is to reveal context in an outline-mode when the occurrence is hidden."
+for this is to reveal context in an outline mode when the occurrence is hidden."
:type 'hook
:group 'matching)
@@ -1760,7 +1761,7 @@ If REGEXP contains upper case characters (excluding those preceded by `\\')
and `search-upper-case' is non-nil, the matching is case-sensitive.
When NLINES is a string or when the function is called
-interactively with prefix argument without a number (`C-u' alone
+interactively with prefix argument without a number (\\[universal-argument] alone
as prefix) the matching strings are collected into the `*Occur*'
buffer by using NLINES as a replacement regexp. NLINES may
contain \\& and \\N which convention follows `replace-match'.
@@ -2262,11 +2263,11 @@ See also `multi-occur'."
(defun occur-engine-add-prefix (lines &optional prefix-face)
(mapcar
- #'(lambda (line)
- (concat (if prefix-face
- (propertize " :" 'font-lock-face prefix-face)
- " :")
- line "\n"))
+ (lambda (line)
+ (concat (if prefix-face
+ (propertize " :" 'font-lock-face prefix-face)
+ " :")
+ line "\n"))
lines))
(defun occur-accumulate-lines (count &optional keep-props pt)
@@ -2367,24 +2368,54 @@ See also `multi-occur'."
;; And the second element is the list of context after-lines.
(if (> nlines 0) after-lines))))
+(defun occur-word-at-mouse (event)
+ "Display an occur buffer for the word at EVENT."
+ (interactive "e")
+ (let ((word (thing-at-mouse event 'word t)))
+ (occur (concat "\\<" (regexp-quote word) "\\>"))))
+
+(defun occur-symbol-at-mouse (event)
+ "Display an occur buffer for the symbol at EVENT."
+ (interactive "e")
+ (let ((symbol (thing-at-mouse event 'symbol t)))
+ (occur (concat "\\_<" (regexp-quote symbol) "\\_>"))))
+
+(defun occur-context-menu (menu click)
+ "Populate MENU with occur commands at CLICK.
+To be added to `context-menu-functions'."
+ (let ((word (thing-at-mouse click 'word))
+ (sym (thing-at-mouse click 'symbol)))
+ (when (or word sym)
+ (define-key-after menu [occur-separator] menu-bar-separator
+ 'middle-separator)
+ (when sym
+ (define-key-after menu [occur-symbol-at-mouse]
+ '(menu-item "Occur Symbol" occur-symbol-at-mouse)
+ 'occur-separator))
+ (when word
+ (define-key-after menu [occur-word-at-mouse]
+ '(menu-item "Occur Word" occur-word-at-mouse)
+ 'occur-separator))))
+ menu)
+
;; It would be nice to use \\[...], but there is no reasonable way
;; to make that display both SPC and Y.
(defconst query-replace-help
- "Type Space or `y' to replace one match, Delete or `n' to skip to next,
-RET or `q' to exit, Period to replace one match and exit,
-Comma to replace but not move point immediately,
-C-r to enter recursive edit (\\[exit-recursive-edit] to get out again),
-C-w to delete match and recursive edit,
-C-l to clear the screen, redisplay, and offer same replacement again,
-! to replace all remaining matches in this buffer with no more questions,
-^ to move point back to previous match,
-u to undo previous replacement,
-U to undo all replacements,
-E to edit the replacement string.
-In multi-buffer replacements type `Y' to replace all remaining
+ "Type \\`SPC' or \\`y' to replace one match, Delete or \\`n' to skip to next,
+\\`RET' or \\`q' to exit, Period to replace one match and exit,
+\\`,' to replace but not move point immediately,
+\\`C-r' to enter recursive edit (\\[exit-recursive-edit] to get out again),
+\\`C-w' to delete match and recursive edit,
+\\`C-l' to clear the screen, redisplay, and offer same replacement again,
+\\`!' to replace all remaining matches in this buffer with no more questions,
+\\`^' to move point back to previous match,
+\\`u' to undo previous replacement,
+\\`U' to undo all replacements,
+\\`E' to edit the replacement string.
+In multi-buffer replacements type \\`Y' to replace all remaining
matches in all remaining buffers with no more questions,
-`N' to skip to the next buffer without replacing remaining matches
+\\`N' to skip to the next buffer without replacing remaining matches
in the current buffer."
"Help message while in `query-replace'.")
@@ -2576,7 +2607,7 @@ passed in. If LITERAL is set, no checking is done, anyway."
noedit)
(defvar replace-update-post-hook nil
- "Function(s) to call after query-replace has found a match in the buffer.")
+ "Function(s) to call after `query-replace' has found a match in the buffer.")
(defvar replace-search-function nil
"Function to use when searching for strings to replace.
diff --git a/lisp/rfn-eshadow.el b/lisp/rfn-eshadow.el
index 378358feac2..3c1958686f3 100644
--- a/lisp/rfn-eshadow.el
+++ b/lisp/rfn-eshadow.el
@@ -122,7 +122,7 @@ system, `file-name-shadow-properties' is used instead."
"Minibuffer setup functions from other packages.")
(defvar rfn-eshadow-update-overlay-hook nil
- "Customer overlay functions from other packages")
+ "Customer overlay functions from other packages.")
;;; Internal variables
diff --git a/lisp/rot13.el b/lisp/rot13.el
index 4e4e60fea3f..e509b22529f 100644
--- a/lisp/rot13.el
+++ b/lisp/rot13.el
@@ -46,29 +46,23 @@
;;; Code:
-(defvar rot13-display-table
- (let ((table (make-display-table))
- (i 0))
- (while (< i 26)
+(defconst rot13-display-table
+ (let ((table (make-display-table)))
+ (dotimes (i 26)
(aset table (+ i ?a) (vector (+ (% (+ i 13) 26) ?a)))
- (aset table (+ i ?A) (vector (+ (% (+ i 13) 26) ?A)))
- (setq i (1+ i)))
+ (aset table (+ i ?A) (vector (+ (% (+ i 13) 26) ?A))))
table)
"Char table for ROT13 display.")
-(defvar rot13-translate-table
- (let ((str (make-string 127 0))
- (i 0))
- (while (< i 127)
- (aset str i i)
- (setq i (1+ i)))
- (setq i 0)
- (while (< i 26)
- (aset str (+ i ?a) (+ (% (+ i 13) 26) ?a))
- (aset str (+ i ?A) (+ (% (+ i 13) 26) ?A))
- (setq i (1+ i)))
- str)
- "String table for ROT13 translation.")
+(put 'plain-char-table 'char-table-extra-slots 0)
+
+(defconst rot13-translate-table
+ (let ((table (make-char-table 'translation-table)))
+ (dotimes (i 26)
+ (aset table (+ i ?a) (+ (% (+ i 13) 26) ?a))
+ (aset table (+ i ?A) (+ (% (+ i 13) 26) ?A)))
+ table)
+ "Char table for ROT13 translation.")
;;;###autoload
(defun rot13 (object &optional start end)
diff --git a/lisp/rtree.el b/lisp/rtree.el
index 166c7808184..0eaaa58e6e2 100644
--- a/lisp/rtree.el
+++ b/lisp/rtree.el
@@ -171,7 +171,7 @@
(setq tree nil))))))))
(defun rtree-delq (tree number)
- "Remove NUMBER from TREE destructively. Returns the new tree."
+ "Remove NUMBER from TREE destructively. Return the new tree."
(let ((result tree)
prev)
(while tree
diff --git a/lisp/ruler-mode.el b/lisp/ruler-mode.el
index a0d4f6e96c2..84c9d06ecec 100644
--- a/lisp/ruler-mode.el
+++ b/lisp/ruler-mode.el
@@ -348,7 +348,7 @@ nothing is dragged.")
(defun ruler-mode-text-scaled-width (width)
"Compute scaled text width according to current font scaling.
Convert a width of char units into a text-scaled char width units,
-Ex. `window-hscroll'."
+for example `window-hscroll'."
(/ (* width (frame-char-width)) (default-font-width)))
(defun ruler-mode-text-scaled-window-hscroll ()
diff --git a/lisp/saveplace.el b/lisp/saveplace.el
index 2a95b39da87..3eff816fa07 100644
--- a/lisp/saveplace.el
+++ b/lisp/saveplace.el
@@ -55,7 +55,7 @@ This alist is saved between Emacs sessions.")
:type 'file)
(defcustom save-place-version-control nil
- "Controls whether to make numbered backups of master save-place file.
+ "Controls whether to make numbered backups of master `save-place' file.
It can have four values: t, nil, `never', and `nospecial'. The first
three have the same meaning that they do for the variable
`version-control', and the final value `nospecial' means just use the
@@ -88,7 +88,9 @@ this happens automatically before saving `save-place-alist' to
:type 'boolean)
(defcustom save-place-abbreviate-file-names nil
- "If non-nil, abbreviate file names before saving them."
+ "If non-nil, abbreviate file names before saving them.
+This can simplify sharing the `save-place-file' file across
+different hosts."
:type 'boolean
:version "28.1")
@@ -326,11 +328,18 @@ may have changed) back to `save-place-alist'."
(with-current-buffer (car buf-list)
;; save-place checks buffer-file-name too, but we can avoid
;; overhead of function call by checking here too.
- (and (or buffer-file-name (and (derived-mode-p 'dired-mode)
- (boundp 'dired-subdir-alist)
- dired-subdir-alist
- (dired-current-directory)))
- (save-place-to-alist))
+ (when (and (or buffer-file-name
+ (and (derived-mode-p 'dired-mode)
+ (boundp 'dired-subdir-alist)
+ dired-subdir-alist
+ (dired-current-directory)))
+ ;; Don't save place in literally-visited file
+ ;; because this will commonly differ from the place
+ ;; when visiting literally (and
+ ;; `find-file-literally' always places point at the
+ ;; start of the buffer).
+ (not find-file-literally))
+ (save-place-to-alist))
(setq buf-list (cdr buf-list))))))
(defun save-place-find-file-hook ()
diff --git a/lisp/select.el b/lisp/select.el
index 15e171c13f9..5e7f4a696a3 100644
--- a/lisp/select.el
+++ b/lisp/select.el
@@ -140,24 +140,27 @@ MS-Windows does not have a \"primary\" selection."
(defcustom x-select-request-type nil
"Data type request for X selection.
The value is one of the following data types, a list of them, or nil:
- `COMPOUND_TEXT', `UTF8_STRING', `STRING', `TEXT'
+ `COMPOUND_TEXT', `UTF8_STRING', `STRING', `TEXT', `text/plain\\;charset=utf-8'
If the value is one of the above symbols, try only the specified type.
If the value is a list of them, try each of them in the specified
order until succeed.
-The value nil is the same as the list (UTF8_STRING COMPOUND_TEXT STRING)."
+The value nil is the same as the list (UTF8_STRING COMPOUND_TEXT STRING
+text/plain\\;charset=utf-8)."
:type '(choice (const :tag "Default" nil)
(const COMPOUND_TEXT)
(const UTF8_STRING)
(const STRING)
(const TEXT)
+ (const text/plain\;charset=utf-8)
(set :tag "List of values"
(const COMPOUND_TEXT)
(const UTF8_STRING)
(const STRING)
- (const TEXT)))
+ (const TEXT)
+ (const text/plain\;charset=utf-8)))
:group 'killing)
(defun gui--selection-value-internal (type)
@@ -165,9 +168,9 @@ The value nil is the same as the list (UTF8_STRING COMPOUND_TEXT STRING)."
Call `gui-get-selection' with an appropriate DATA-TYPE argument
decided by `x-select-request-type'. The return value is already
decoded. If `gui-get-selection' signals an error, return nil."
- (let ((request-type (if (eq window-system 'x)
+ (let ((request-type (if (memq window-system '(x pgtk))
(or x-select-request-type
- '(UTF8_STRING COMPOUND_TEXT STRING))
+ '(UTF8_STRING COMPOUND_TEXT STRING text/plain\;charset=utf-8))
'STRING))
text)
(with-demoted-errors "gui-get-selection: %S"
@@ -304,22 +307,33 @@ the formats available in the clipboard if TYPE is `CLIPBOARD'."
(let ((data (gui-backend-get-selection (or type 'PRIMARY)
(or data-type 'STRING))))
(when (and (stringp data)
- (setq data-type (get-text-property 0 'foreign-selection data)))
+ ;; If this text property is set, then the data needs to
+ ;; be decoded -- otherwise it has already been decoded
+ ;; by the lower level functions.
+ (get-text-property 0 'foreign-selection data))
(let ((coding (or next-selection-coding-system
selection-coding-system
(pcase data-type
('UTF8_STRING 'utf-8)
+ ('text/plain\;charset=utf-8 'utf-8)
('COMPOUND_TEXT 'compound-text-with-extensions)
('C_STRING nil)
- ('STRING 'iso-8859-1)
- (_ (error "Unknown selection data type: %S"
- type))))))
- (setq data (if coding (decode-coding-string data coding)
- ;; This is for C_STRING case.
+ ('STRING 'iso-8859-1)))))
+ (setq data
+ (cond (coding (decode-coding-string data coding))
;; We want to convert each non-ASCII byte to the
;; corresponding eight-bit character, which has
;; a codepoint >= #x3FFF00.
- (string-to-multibyte data))))
+ ((eq data-type 'C_STRING)
+ (string-to-multibyte data))
+ ;; Guess at the charset for types like text/html
+ ;; -- it can be anything, and different
+ ;; applications use different encodings.
+ ((string-match-p "\\`text/" (symbol-name data-type))
+ (decode-coding-string
+ data (car (detect-coding-string data))))
+ ;; Do nothing.
+ (t data))))
(setq next-selection-coding-system nil)
(put-text-property 0 (length data) 'foreign-selection data-type data))
data))
@@ -440,13 +454,13 @@ two markers or an overlay. Otherwise, it is nil."
(setq type 'C_STRING))
(t
(let (non-latin-1 non-unicode eight-bit)
- (mapc #'(lambda (x)
- (if (>= x #x100)
- (if (< x #x110000)
- (setq non-latin-1 t)
- (if (< x #x3FFF80)
- (setq non-unicode t)
- (setq eight-bit t)))))
+ (mapc (lambda (x)
+ (if (>= x #x100)
+ (if (< x #x110000)
+ (setq non-latin-1 t)
+ (if (< x #x3FFF80)
+ (setq non-unicode t)
+ (setq eight-bit t)))))
str)
(setq type (if (or non-unicode
(and
diff --git a/lisp/server.el b/lisp/server.el
index ac5db197f3e..d510df1208a 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -90,12 +90,12 @@
(defcustom server-use-tcp nil
"If non-nil, use TCP sockets instead of local sockets."
- :set #'(lambda (sym val)
- (unless (featurep 'make-network-process '(:family local))
- (setq val t)
- (unless load-in-progress
- (message "Local sockets unsupported, using TCP sockets")))
- (set-default sym val))
+ :set (lambda (sym val)
+ (unless (featurep 'make-network-process '(:family local))
+ (setq val t)
+ (unless load-in-progress
+ (message "Local sockets unsupported, using TCP sockets")))
+ (set-default sym val))
:type 'boolean
:version "22.1")
@@ -485,11 +485,11 @@ If CLIENT is non-nil, add a description of it to the logged message."
(when (and (frame-live-p frame)
proc
;; See if this is the last frame for this client.
- (>= 1 (let ((frame-num 0))
- (dolist (f (frame-list))
- (when (eq proc (frame-parameter f 'client))
- (setq frame-num (1+ frame-num))))
- frame-num)))
+ (not (seq-some
+ (lambda (f)
+ (and (not (eq frame f))
+ (eq proc (frame-parameter f 'client))))
+ (frame-list))))
(server-log (format "server-handle-delete-frame, frame %s" frame) proc)
(server-delete-client proc 'noframe)))) ; Let delete-frame delete the frame later.
@@ -881,7 +881,7 @@ This handles splitting the command if it would be bigger than
&optional parameters)
(let* ((display (or display
(frame-parameter nil 'display)
- (error "Please specify display.")))
+ (error "Please specify display")))
(w (or (cdr (assq 'window-system parameters))
(window-system-for-display display))))
@@ -900,12 +900,17 @@ This handles splitting the command if it would be bigger than
)
(cond (w
- (server--create-frame
- nowait proc
- `((display . ,display)
- ,@(if parent-id
- `((parent-id . ,(string-to-number parent-id))))
- ,@parameters)))
+ (condition-case nil
+ (server--create-frame
+ nowait proc
+ `((display . ,display)
+ ,@(if parent-id
+ `((parent-id . ,(string-to-number parent-id))))
+ ,@parameters))
+ (error
+ (server-log "Window system unsupported" proc)
+ (server-send-string proc "-window-system-unsupported \n")
+ nil)))
(t
(server-log "Window system unsupported" proc)
@@ -1078,7 +1083,7 @@ The following commands are accepted by the client:
`-suspend'
Suspend this terminal, i.e., stop the client process.
- Sent when the user presses C-z."
+ Sent when the user presses \\[suspend-frame]."
(server-log (concat "Received " string) proc)
;; First things first: let's check the authentication
(unless (process-get proc :authenticated)
@@ -1580,13 +1585,13 @@ 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."
- (or (not (let (live-client)
- (dolist (proc server-clients)
- (when (memq t (mapcar #'buffer-live-p
- (process-get proc 'buffers)))
- (setq live-client t)))
- live-client))
+ "Ask before exiting Emacs if it has 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? ")))
(defun server-kill-buffer ()
@@ -1716,6 +1721,9 @@ be a cons cell (LINENUMBER . COLUMNNUMBER)."
(when server-raise-frame
(select-frame-set-input-focus (window-frame)))))
+(defvar server-stop-automatically nil
+ "Internal status variable for `server-stop-automatically'.")
+
;;;###autoload
(defun server-save-buffers-kill-terminal (arg)
;; Called from save-buffers-kill-terminal in files.el.
@@ -1724,27 +1732,103 @@ With ARG non-nil, silently save all file-visiting buffers, then kill.
If emacsclient was started with a list of filenames to edit, then
only these files will be asked to be saved."
- (let ((proc (frame-parameter nil 'client)))
- (cond ((eq proc 'nowait)
- ;; Nowait frames have no client buffer list.
- (if (cdr (frame-list))
- (progn (save-some-buffers arg)
- (delete-frame))
- ;; If we're the last frame standing, kill Emacs.
- (save-buffers-kill-emacs arg)))
- ((processp proc)
- (let ((buffers (process-get proc 'buffers)))
- (save-some-buffers
- arg (if buffers
- ;; Only files from emacsclient file list.
- (lambda () (memq (current-buffer) buffers))
- ;; No emacsclient file list: don't override
- ;; `save-some-buffers-default-predicate' (unless
- ;; ARG is non-nil), since we're not killing
- ;; Emacs (unlike `save-buffers-kill-emacs').
- (and arg t)))
- (server-delete-client proc)))
- (t (error "Invalid client frame")))))
+ (if server-stop-automatically
+ (server-stop-automatically--handle-delete-frame (selected-frame))
+ (let ((proc (frame-parameter nil 'client)))
+ (cond ((eq proc 'nowait)
+ ;; Nowait frames have no client buffer list.
+ (if (cdr (frame-list))
+ (progn (save-some-buffers arg)
+ (delete-frame))
+ ;; If we're the last frame standing, kill Emacs.
+ (save-buffers-kill-emacs arg)))
+ ((processp proc)
+ (let ((buffers (process-get proc 'buffers)))
+ (save-some-buffers
+ arg (if buffers
+ ;; Only files from emacsclient file list.
+ (lambda () (memq (current-buffer) buffers))
+ ;; No emacsclient file list: don't override
+ ;; `save-some-buffers-default-predicate' (unless
+ ;; ARG is non-nil), since we're not killing
+ ;; Emacs (unlike `save-buffers-kill-emacs').
+ (and arg t)))
+ (server-delete-client proc)))
+ (t (error "Invalid client frame"))))))
+
+(defun server-stop-automatically--handle-delete-frame (frame)
+ "Handle deletion of FRAME when `server-stop-automatically' is used."
+ (when server-stop-automatically
+ (if (if (and (processp (frame-parameter frame 'client))
+ (eq this-command 'save-buffers-kill-terminal))
+ (progn
+ (dolist (f (frame-list))
+ (when (and (eq (frame-parameter frame 'client)
+ (frame-parameter f 'client))
+ (not (eq frame f)))
+ (set-frame-parameter f 'client nil)
+ (let ((server-stop-automatically nil))
+ (delete-frame f))))
+ (if (cddr (frame-list))
+ (let ((server-stop-automatically nil))
+ (delete-frame frame)
+ nil)
+ t))
+ (null (cddr (frame-list))))
+ (let ((server-stop-automatically nil))
+ (save-buffers-kill-emacs)
+ (delete-frame frame)))))
+
+(defun server-stop-automatically--maybe-kill-emacs ()
+ "Handle closing of Emacs daemon when `server-stop-automatically' is used."
+ (unless (cdr (frame-list))
+ (when (and
+ (not (memq t (mapcar (lambda (b)
+ (and (buffer-file-name b)
+ (buffer-modified-p b)))
+ (buffer-list))))
+ (not (memq t (mapcar (lambda (p)
+ (and (memq (process-status p)
+ '(run stop open listen))
+ (process-query-on-exit-flag p)))
+ (process-list)))))
+ (kill-emacs))))
+
+;;;###autoload
+(defun server-stop-automatically (arg)
+ "Automatically stop server as specified by ARG.
+
+If ARG is the symbol `empty', stop the server when it has no
+remaining clients, no remaining unsaved file-visiting buffers,
+and no running processes with a `query-on-exit' flag.
+
+If ARG is the symbol `delete-frame', ask the user when the last
+frame is deleted whether each unsaved file-visiting buffer must
+be saved and each running process with a `query-on-exit' flag
+can be stopped, and if so, stop the server itself.
+
+If ARG is the symbol `kill-terminal', ask the user when the
+terminal is killed with \\[save-buffers-kill-terminal] \
+whether each unsaved file-visiting
+buffer must be saved and each running process with a `query-on-exit'
+flag can be stopped, and if so, stop the server itself.
+
+Any other value of ARG will cause this function to signal an error.
+
+This function is meant to be called from the user init file."
+ (when (daemonp)
+ (setq server-stop-automatically arg)
+ (cond
+ ((eq arg 'empty)
+ (setq server-stop-automatically nil)
+ (run-with-timer 10 2
+ #'server-stop-automatically--maybe-kill-emacs))
+ ((eq arg 'delete-frame)
+ (add-hook 'delete-frame-functions
+ #'server-stop-automatically--handle-delete-frame))
+ ((eq arg 'kill-terminal))
+ (t
+ (error "Unexpected argument")))))
(define-key ctl-x-map "#" 'server-edit)
diff --git a/lisp/ses.el b/lisp/ses.el
index 81c27144a54..8496aeec8e8 100644
--- a/lisp/ses.el
+++ b/lisp/ses.el
@@ -227,12 +227,6 @@ Used for listing local printers or renamed cells.")
"w" ses-set-column-width
"x" ses-export-keymap
"\M-p" ses-read-column-printer))
- (repl '(;;We'll replace these wherever they appear in the keymap
- clipboard-kill-region ses-kill-override
- end-of-line ses-end-of-line
- kill-line ses-delete-row
- kill-region ses-kill-override
- open-line ses-insert-row))
(numeric "0123456789.-")
(newmap (make-keymap)))
;;Get rid of printables
@@ -240,13 +234,11 @@ Used for listing local printers or renamed cells.")
;;These keys insert themselves as the beginning of a numeric value
(dotimes (x (length numeric))
(define-key newmap (substring numeric x (1+ x)) 'ses-read-cell))
- ;;Override these global functions wherever they're bound
- (while repl
- (substitute-key-definition (car repl) (cadr repl) newmap
- (current-global-map))
- (setq repl (cddr repl)))
- ;;Apparently substitute-key-definition doesn't catch this?
- (define-key newmap [(menu-bar) edit cut] 'ses-kill-override)
+ (define-key newmap [remap clipboard-kill-region] #'ses-kill-override)
+ (define-key newmap [remap end-of-line] #'ses-end-of-line)
+ (define-key newmap [remap kill-line] #'ses-delete-row)
+ (define-key newmap [remap kill-region] #'ses-kill-override)
+ (define-key newmap [remap open-line] #'ses-insert-row)
;;Define our other local keys
(while keys
(define-key newmap (car keys) (cadr keys))
@@ -299,11 +291,11 @@ Used for listing local printers or renamed cells.")
ses-center-span ses-dashfill ses-dashfill-span
ses-tildefill-span
ses-prin1)
- "List of print functions to be included in initial history of
-printer functions. None of these standard-printer functions,
-except function `ses-prin1', is suitable for use as a column
-printer or a global-default printer because they invoke the
-column or default printer and then modify its output.")
+ "List of print functions to be included in initial history of printer functions.
+None of these standard-printer functions, except function
+`ses-prin1', is suitable for use as a column printer or a
+global-default printer because they invoke the column or default
+printer and then modify its output.")
;;----------------------------------------------------------------------------
@@ -454,8 +446,8 @@ functions refer to its value."
`(ses-cell--references ,(if col `(ses-get-cell ,row ,col) row)))
(defmacro ses-sym-rowcol (sym)
- "From a cell-symbol SYM, gets the cons (row . col). A1 => (0 . 0). Result
-is nil if SYM is not a symbol that names a cell."
+ "From a cell-symbol SYM, gets the cons (row . col). A1 => (0 . 0).
+Result is nil if SYM is not a symbol that names a cell."
(declare (debug t))
`(let ((rc (and (symbolp ,sym) (get ,sym 'ses-cell))))
(if (eq rc :ses-named)
@@ -623,7 +615,7 @@ This is a macro to prevent propagate-on-load viruses."
t)
(defmacro ses-column-printers (printers)
- "Load the vector of column printers from the spreadsheet file and checks
+ "Load the vector of column printers from the spreadsheet file and check
them for safety. This is a macro to prevent propagate-on-load viruses."
(or (and (vectorp printers) (= (length printers) ses--numcols))
(error "Bad column-printers vector"))
@@ -634,14 +626,14 @@ them for safety. This is a macro to prevent propagate-on-load viruses."
t)
(defmacro ses-default-printer (def)
- "Load the global default printer from the spreadsheet file and checks it
+ "Load the global default printer from the spreadsheet file and check it
for safety. This is a macro to prevent propagate-on-load viruses."
(setq ses--default-printer (ses-safe-printer def))
(ses-printer-record def)
t)
(defmacro ses-header-row (row)
- "Load the header row from the spreadsheet file and checks it
+ "Load the header row from the spreadsheet file and check it
for safety. This is a macro to prevent propagate-on-load viruses."
(or (and (wholenump row) (or (zerop ses--numrows) (< row ses--numrows)))
(error "Bad header-row"))
@@ -819,8 +811,8 @@ Return nil in case of failure."
buffer-undo-list))
(defun ses-reset-header-string ()
- "Flag the header string for update. Upon undo, the header string will be
-updated again."
+ "Flag the header string for update.
+Upon undo, the header string will be updated again."
(push '(apply ses-reset-header-string) buffer-undo-list)
(setq ses--header-hscroll -1))
@@ -1677,7 +1669,7 @@ if the range was altered."
(funcall field (ses-sym-rowcol min))))
;; This range has changed size.
(setq ses-relocate-return 'range))
- `(ses-range ,min ,max ,@(cl-cdddr range)))))
+ `(ses-range ,min ,max ,@(cdddr range)))))
(defun ses-relocate-all (minrow mincol rowincr colincr)
"Alter all cell values, symbols, formulas, and reference-lists to relocate
@@ -1898,7 +1890,7 @@ Does not execute cell formulas or print functions."
(or (and (= (following-char) ?\n)
(eq (car-safe x) 'ses-local-printer)
(apply #'ses--local-printer (cdr x)))
- (error "local printer-def error"))
+ (error "Local printer-def error"))
(setq ses--numlocprn (1+ ses--numlocprn))))))
;; Load cell definitions.
(dotimes (row ses--numrows)
@@ -2594,8 +2586,7 @@ With prefix, deletes several cells."
(forward-char 1))))
(defun ses-clear-cell-backward (count)
- "Move to previous cell and then delete it. With prefix, delete several
-cells."
+ "Move to previous cell and then delete it. With prefix, delete several cells."
(interactive "*p")
(if (< count 0)
(1value (ses-clear-cell-forward (- count)))
@@ -3054,8 +3045,9 @@ hard to override how mouse-1 works."
(advice-add 'copy-region-as-kill :around #'ses--advice-copy-region-as-kill)
(defun ses-copy-region (beg end)
- "Treat the region as rectangular. Convert the intangible attributes to
-SES attributes recording the contents of the cell as of the time of copying."
+ "Treat the region as rectangular.
+Convert the intangible attributes to SES attributes recording the
+contents of the cell as of the time of copying."
(when (= end ses--data-marker)
;;Avoid overflow situation
(setq end (1- ses--data-marker)))
@@ -3070,7 +3062,7 @@ SES attributes recording the contents of the cell as of the time of copying."
x))
(defun ses-copy-region-helper (line)
- "Converts one line (of a rectangle being extracted from a spreadsheet) to
+ "Convert one line (of a rectangle being extracted from a spreadsheet) to
external form by attaching to each print cell a `ses' attribute that records
the corresponding data cell."
(or (> (length line) 1)
@@ -3124,13 +3116,13 @@ Otherwise the text is inserted as the formula for the current cell.
When inserting cells, the formulas are usually relocated to keep the same
relative references to neighboring cells. This is best if the formulas
-generally refer to other cells within the yanked text. You can use the C-u
+generally refer to other cells within the yanked text. You can use the \\[universal-argument]
prefix to specify insertion without relocation, which is best when the
formulas refer to cells outside the yanked text.
When inserting formulas, the text is treated as a string constant if it doesn't
make sense as a sexp or would otherwise be considered a symbol. Use `sym' to
-explicitly insert a symbol, or use the C-u prefix to treat all unmarked words
+explicitly insert a symbol, or use the \\[universal-argument] prefix to treat all unmarked words
as symbols."
(if (not (and (derived-mode-p 'ses-mode)
(eq (get-text-property (point) 'keymap) 'ses-mode-print-map)))
@@ -3172,8 +3164,8 @@ previous insertion."
(setq this-command 'yank))
(defun ses-yank-cells (text arg)
- "If the TEXT has a proper set of `ses' attributes, insert the text as
-cells, else return nil. The cells are reprinted--the supplied text is
+ "If TEXT has a proper set of `ses' attributes, insert it as cells.
+Otherwise, return nil. The cells are reprinted--the supplied text is
ignored because the column widths, default printer, etc. at yank time might
be different from those at kill-time. ARG is a list to indicate that
formulas are to be inserted without relocation."
@@ -3554,7 +3546,7 @@ With prefix, sorts in REVERSE order."
(push (cons (buffer-substring-no-properties (point) end)
(+ minrow x))
keys))
- (setq keys (sort keys #'(lambda (x y) (string< (car x) (car y)))))
+ (setq keys (sort keys (lambda (x y) (string< (car x) (car y)))))
;;Extract the lines in reverse sorted order
(or reverse
(setq keys (nreverse keys)))
@@ -3743,7 +3735,7 @@ Uses the value COMPILED-VALUE for this printer."
(defun ses-define-local-printer (name definition)
"Define a local printer with name NAME and definition DEFINITION.
-NAME shall be a symbol. Use TAB to complete over existing local
+NAME shall be a symbol. Use TAB to complete over existing local
printer names.
DEFINITION shall be either a string formatter, e.g.:
@@ -3774,7 +3766,9 @@ function is redefined."
(setq name (intern name))
(let* ((cur-printer (gethash name ses--local-printer-hashmap))
(default (and cur-printer (ses--locprn-def cur-printer))))
- (setq def (ses-read-printer (format "Enter definition of printer %S" name)
+ (setq def (ses-read-printer (format-prompt
+ "Enter definition of printer %S"
+ default name)
default)))
(list name def)))
@@ -4012,8 +4006,9 @@ Use `math-format-value' as a printer for Calc objects."
(apply #'+ (apply #'ses-delete-blanks args)))
(defun ses-average (list)
- "Computes the sum of the numbers in LIST, divided by their length. Blanks
-are ignored. Result is always floating-point, even if all args are integers."
+ "Calculate the sum of the numbers in LIST, divided by their length.
+Blanks are ignored. Result is always floating-point, even if all
+args are integers."
(setq list (apply #'ses-delete-blanks list))
(/ (float (apply #'+ list)) (length list)))
diff --git a/lisp/shadowfile.el b/lisp/shadowfile.el
index f67b0b9b39c..63e9bd655cf 100644
--- a/lisp/shadowfile.el
+++ b/lisp/shadowfile.el
@@ -213,6 +213,14 @@ information defining the cluster. For interactive use, call
;;; SITES
+;; This simplifies it a little bit. "system-name" is also accepted.
+;; But we don't want to make the help echo too long.
+(defconst shadow-site-help "\
+A cluster identification \"/name:\", a remote identification
+\"/method:user@host:\", or \"/system-name:\" (the value of
+`shadow-system-name')"
+ "The help string describing a valid site.")
+
(defun shadow-site-name (site)
"Return name if SITE has the form \"/name:\", otherwise SITE."
(if (string-match "\\`/\\([-.[:word:]]+\\):\\'" site)
@@ -239,9 +247,10 @@ information defining the cluster. For interactive use, call
shadow-clusters)))
(defun shadow-read-site ()
- "Read a cluster name or host identification from the minibuffer."
- (let ((ans (completing-read "Host identification or cluster name: "
- shadow-clusters)))
+ "Read a site name from the minibuffer."
+ (let ((ans (completing-read
+ (propertize "Site name: " 'help-echo shadow-site-help)
+ shadow-clusters)))
(when (or (shadow-get-cluster (shadow-site-name ans))
(string-equal ans shadow-system-name)
(string-equal ans (shadow-site-name shadow-system-name))
@@ -285,7 +294,7 @@ Argument can be a simple name, remote file name, or already a
(defsubst shadow-make-fullname (hup &optional host name)
"Make a Tramp style fullname out of HUP, a `tramp-file-name' structure.
Replace HOST, and NAME when non-nil. HOST can also be a remote file name."
- (let ((hup (copy-tramp-file-name hup)))
+ (when-let ((hup (copy-tramp-file-name hup)))
(when host
(if (file-remote-p host)
(setq name (or name (and hup (tramp-file-name-localname hup)))
@@ -355,23 +364,23 @@ Will return the name bare if it is a local file."
Do so by replacing (when possible) home directory with ~/, and
hostname with cluster name that includes it. Filename should be
absolute and true."
- (let* ((hup (shadow-parse-name file))
- (homedir (if (shadow-local-file hup)
- shadow-homedir
- (file-name-as-directory
- (file-local-name
- (expand-file-name
- (shadow-make-fullname hup nil shadow-homedir))))))
- (suffix (shadow-suffix homedir (tramp-file-name-localname hup)))
- (cluster (shadow-site-cluster (shadow-make-fullname hup nil ""))))
- (when cluster
- (setf (tramp-file-name-method hup) nil
- (tramp-file-name-host hup) (shadow-cluster-name cluster)))
- (shadow-make-fullname
- hup nil
- (if suffix
- (concat shadow-homedir suffix)
- (tramp-file-name-localname hup)))))
+ (when-let ((hup (shadow-parse-name file)))
+ (let* ((homedir (if (shadow-local-file hup)
+ shadow-homedir
+ (file-name-as-directory
+ (file-local-name
+ (expand-file-name
+ (shadow-make-fullname hup nil shadow-homedir))))))
+ (suffix (shadow-suffix homedir (tramp-file-name-localname hup)))
+ (cluster (shadow-site-cluster (shadow-make-fullname hup nil ""))))
+ (when cluster
+ (setf (tramp-file-name-method hup) nil
+ (tramp-file-name-host hup) (shadow-cluster-name cluster)))
+ (shadow-make-fullname
+ hup nil
+ (if suffix
+ (concat shadow-homedir suffix)
+ (tramp-file-name-localname hup))))))
(defun shadow-same-site (pattern file)
"True if the site of PATTERN and of FILE are on the same site.
@@ -455,16 +464,17 @@ It may have different filenames on each site. When this file is edited, the
new version will be copied to each of the other locations. Sites can be
specific hostnames, or names of clusters (see `shadow-define-cluster')."
(interactive)
- (let* ((hup (shadow-parse-name
- (shadow-contract-file-name (buffer-file-name))))
- (name (tramp-file-name-localname hup))
- site group)
- (while (setq site (shadow-read-site))
- (setq name (read-string "Filename: " name)
- hup (shadow-parse-name (shadow-contract-file-name name))
- group (cons (shadow-make-fullname hup site) group)))
- (setq shadow-literal-groups (cons group shadow-literal-groups)))
- (shadow-write-info-file))
+ (when-let ((hup (shadow-parse-name
+ (shadow-contract-file-name (buffer-file-name)))))
+ (let* ((name (tramp-file-name-localname hup))
+ site group)
+ (while (setq site (shadow-read-site))
+ (setq name (read-string "Filename: " name)
+ hup (shadow-parse-name (shadow-contract-file-name name))
+ group (cons (shadow-make-fullname hup site) group)))
+ (when group
+ (setq shadow-literal-groups (cons group shadow-literal-groups))))
+ (shadow-write-info-file)))
;;;###autoload
(defun shadow-define-regexp-group ()
diff --git a/lisp/shell.el b/lisp/shell.el
index 5cdc0385a6f..370532ea46f 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -517,7 +517,8 @@ Shell buffers. It implements `shell-completion-execonly' for
(put 'shell-mode 'mode-class 'special)
(define-derived-mode shell-mode comint-mode "Shell"
- "Major mode for interacting with an inferior shell.\\<shell-mode-map>
+ "Major mode for interacting with an inferior shell.
+\\<shell-mode-map>
\\[comint-send-input] after the end of the process' output sends the text from
the end of process to the end of the current line.
\\[comint-send-input] before end of process output copies the current line minus the prompt to
@@ -765,12 +766,16 @@ Make the shell buffer the current buffer, and return it.
(called-interactively-p 'any)
(null explicit-shell-file-name)
(null (getenv "ESHELL")))
+ ;; `expand-file-name' shall not add the MS Windows volume letter
+ ;; (Bug#49229).
(setq-local explicit-shell-file-name
- (file-local-name
- (expand-file-name
- (read-file-name "Remote shell path: " default-directory
- shell-file-name t shell-file-name
- #'file-remote-p)))))
+ (replace-regexp-in-string
+ "^[[:alpha:]]:" ""
+ (file-local-name
+ (expand-file-name
+ (read-file-name "Remote shell path: " default-directory
+ shell-file-name t shell-file-name
+ #'file-remote-p))))))
;; Rain or shine, BUFFER must be current by now.
(unless (comint-check-proc buffer)
@@ -780,7 +785,8 @@ Make the shell buffer the current buffer, and return it.
(startfile (concat "~/.emacs_" name))
(xargs-name (intern-soft (concat "explicit-" name "-args"))))
(unless (file-exists-p startfile)
- (setq startfile (concat user-emacs-directory "init_" name ".sh")))
+ (setq startfile (locate-user-emacs-file
+ (concat "init_" name ".sh"))))
(setq-local shell--start-prog (file-name-nondirectory prog))
(apply #'make-comint-in-buffer "shell" buffer prog
(if (file-exists-p startfile) startfile)
diff --git a/lisp/simple.el b/lisp/simple.el
index 7da315e8692..26c3ff575e2 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -241,7 +241,7 @@ all other buffers."
(defun next-error-buffer-on-selected-frame (&optional _avoid-current
extra-test-inclusive
extra-test-exclusive)
- "Return a single visible next-error buffer on the selected frame."
+ "Return a single visible `next-error' buffer on the selected frame."
(let ((window-buffers
(delete-dups
(delq nil (mapcar (lambda (w)
@@ -259,7 +259,7 @@ all other buffers."
extra-test-exclusive)
"Try the current buffer when outside navigation.
But return nil if we navigated to the current buffer by the means
-of `next-error' command. Otherwise, return it if it's next-error
+of `next-error' command. Otherwise, return it if it's `next-error'
capable."
;; Check that next-error-buffer has no buffer-local value
;; (i.e. we never navigated to the current buffer from another),
@@ -527,21 +527,28 @@ Other major modes are defined by comparison with this one."
(kill-all-local-variables)
(run-mode-hooks))
+(define-derived-mode clean-mode fundamental-mode "Clean"
+ "A mode that removes all overlays and text properties."
+ (kill-all-local-variables t)
+ (let ((inhibit-read-only t))
+ (dolist (overlay (overlays-in (point-min) (point-max)))
+ (delete-overlay overlay))
+ (set-text-properties (point-min) (point-max) nil)
+ (setq-local yank-excluded-properties t)))
+
;; Special major modes to view specially formatted data rather than files.
-(defvar special-mode-map
- (let ((map (make-sparse-keymap)))
- (suppress-keymap map)
- (define-key map "q" 'quit-window)
- (define-key map " " 'scroll-up-command)
- (define-key map [?\S-\ ] 'scroll-down-command)
- (define-key map "\C-?" 'scroll-down-command)
- (define-key map "?" 'describe-mode)
- (define-key map "h" 'describe-mode)
- (define-key map ">" 'end-of-buffer)
- (define-key map "<" 'beginning-of-buffer)
- (define-key map "g" 'revert-buffer)
- map))
+(defvar-keymap special-mode-map
+ :suppress t
+ "q" #'quit-window
+ "SPC" #'scroll-up-command
+ "S-SPC" #'scroll-down-command
+ "DEL" #'scroll-down-command
+ "?" #'describe-mode
+ "h" #'describe-mode
+ ">" #'end-of-buffer
+ "<" #'beginning-of-buffer
+ "g" #'revert-buffer)
(put 'special-mode 'mode-class 'special)
(define-derived-mode special-mode nil "Special"
@@ -589,6 +596,9 @@ text-property `hard'.
A non-nil INTERACTIVE argument means to run the `post-self-insert-hook'."
(interactive "*P\np")
(barf-if-buffer-read-only)
+ (when (and arg
+ (< (prefix-numeric-value arg) 0))
+ (error "Repetition argument has to be non-negative"))
;; Call self-insert so that auto-fill, abbrev expansion etc. happen.
;; Set last-command-event to tell self-insert what to insert.
(let* ((was-page-start (and (bolp) (looking-at page-delimiter)))
@@ -700,9 +710,10 @@ When called from Lisp code, ARG may be a prefix string to copy."
:height 0.1 :background "#505050")
(((type graphic) (background light))
:height 0.1 :background "#a0a0a0")
- (t :foreground "ForestGreen"))
+ (t
+ :foreground "ForestGreen" :underline t))
"Face for separator lines."
- :version "28.1"
+ :version "29.1"
:group 'text)
(defun make-separator-line (&optional length)
@@ -710,11 +721,13 @@ When called from Lisp code, ARG may be a prefix string to copy."
This uses the `separator-line' face.
If LENGTH is nil, use the window width."
- (if (display-graphic-p)
+ (if (or (display-graphic-p)
+ (display-supports-face-attributes-p '(:underline t)))
(if length
(concat (propertize (make-string length ?\s) 'face 'separator-line)
"\n")
(propertize "\n" 'face '(:inherit separator-line :extend t)))
+ ;; In terminals (that don't support underline), use a line of dashes.
(concat (propertize (make-string (or length (1- (window-width))) ?-)
'face 'separator-line)
"\n")))
@@ -2070,7 +2083,7 @@ This function uses the `read-extended-command-predicate' user option."
"Say whether SYMBOL has been marked as a mode-specific command in BUFFER."
;; Check the modes.
(let ((modes (command-modes symbol)))
- ;; Common case: Just a single mode.
+ ;; Common fast case: Just a single mode.
(if (null (cdr modes))
(or (provided-mode-derived-p
(buffer-local-value 'major-mode buffer) (car modes))
@@ -2078,13 +2091,7 @@ This function uses the `read-extended-command-predicate' user option."
(buffer-local-value 'local-minor-modes buffer))
(memq (car modes) global-minor-modes))
;; Uncommon case: Multiple modes.
- (apply #'provided-mode-derived-p
- (buffer-local-value 'major-mode buffer)
- modes)
- (seq-intersection modes
- (buffer-local-value 'local-minor-modes buffer)
- #'eq)
- (seq-intersection modes global-minor-modes #'eq))))
+ (command-completion-with-modes-p modes buffer))))
(defun command-completion-default-include-p (symbol buffer)
"Say whether SYMBOL should be offered as a completion.
@@ -2139,21 +2146,23 @@ or (if one of MODES is a minor mode), if it is switched on in BUFFER."
command-names)))
(defcustom suggest-key-bindings t
- "Non-nil means show the equivalent key-binding when M-x command has one.
+ "Non-nil means show the equivalent keybinding when \
+\\[execute-extended-command] has one.
The value can be a length of time to show the message for.
If the value is non-nil and not a number, we wait 2 seconds.
Also see `extended-command-suggest-shorter'.
Equivalent key-bindings are also shown in the completion list of
-M-x for all commands that have them."
+\\[execute-extended-command] for all commands that have them."
:group 'keyboard
:type '(choice (const :tag "off" nil)
- (integer :tag "time" 2)
+ (natnum :tag "time" 2)
(other :tag "on")))
(defcustom extended-command-suggest-shorter t
- "If non-nil, show a shorter M-x invocation when there is one.
+ "If non-nil, show a shorter \\[execute-extended-command] invocation \
+when there is one.
Also see `suggest-key-bindings'."
:group 'keyboard
@@ -2219,7 +2228,9 @@ invoking, give a prefix argument to `execute-extended-command'."
(let* ((function (and (stringp command-name) (intern-soft command-name)))
(binding (and suggest-key-bindings
(not executing-kbd-macro)
- (where-is-internal function overriding-local-map t))))
+ (where-is-internal function overriding-local-map t)))
+ (delay-before-suggest 0)
+ (find-shorter nil))
(unless (commandp function)
(error "`%s' is not a valid command name" command-name))
;; Some features, such as novice.el, rely on this-command-keys
@@ -2234,50 +2245,52 @@ invoking, give a prefix argument to `execute-extended-command'."
(setq real-this-command function)
(let ((prefix-arg prefixarg))
(command-execute function 'record))
- ;; If enabled, show which key runs this command.
- ;; But first wait, and skip the message if there is input.
- (let* ((waited
- ;; If this command displayed something in the echo area;
- ;; wait a few seconds, then display our suggestion message.
- ;; FIXME: Wait *after* running post-command-hook!
- ;; FIXME: If execute-extended-command--shorter were
- ;; faster, we could compute the result here first too.
- (when (and suggest-key-bindings
- (or binding
- (and extended-command-suggest-shorter typed)))
- (sit-for (cond
- ((zerop (length (current-message))) 0)
- ((numberp suggest-key-bindings) suggest-key-bindings)
- (t 2))))))
- (when (and waited (not (consp unread-command-events)))
- (unless (or (not extended-command-suggest-shorter)
- binding executing-kbd-macro (not (symbolp function))
- (<= (length (symbol-name function)) 2))
- ;; There's no binding for CMD. Let's try and find the shortest
- ;; string to use in M-x.
- ;; FIXME: Can be slow. Cache it maybe?
- (while-no-input
- (setq binding (execute-extended-command--shorter
- (symbol-name function) typed))))
- (when binding
- ;; This is normally not necessary -- the timer should run
- ;; immediately, but be defensive and ensure that we never
- ;; have two of these timers in flight.
- (when execute-extended-command--binding-timer
- (cancel-timer execute-extended-command--binding-timer))
- (setq execute-extended-command--binding-timer
- (run-at-time
- 0 nil
- (lambda ()
- (with-temp-message
- (format-message "You can run the command `%s' with %s"
- function
- (if (stringp binding)
- (concat "M-x " binding " RET")
- (key-description binding)))
- (sit-for (if (numberp suggest-key-bindings)
- suggest-key-bindings
- 2)))))))))))
+ ;; Ensure that we never have two of the suggest-binding timers in
+ ;; flight.
+ (when execute-extended-command--binding-timer
+ (cancel-timer execute-extended-command--binding-timer))
+ ;; If this command displayed something in the echo area, then
+ ;; postpone the display of our suggestion message a bit.
+ (when (and suggest-key-bindings
+ (or binding
+ (and extended-command-suggest-shorter typed)))
+ (setq delay-before-suggest
+ (cond
+ ((zerop (length (current-message))) 0)
+ ((numberp suggest-key-bindings) suggest-key-bindings)
+ (t 2)))
+ (when (and extended-command-suggest-shorter
+ (not binding)
+ (not executing-kbd-macro)
+ (symbolp function)
+ (> (length (symbol-name function)) 2))
+ ;; There's no binding for CMD. Let's try and find the shortest
+ ;; string to use in M-x.
+ (setq find-shorter t))
+ (when (or binding find-shorter)
+ (setq execute-extended-command--binding-timer
+ (run-at-time
+ delay-before-suggest nil
+ (lambda ()
+ ;; If the user has typed any other commands in the
+ ;; meantime, then don't display anything.
+ (when (eq function real-last-command)
+ ;; Find shorter string.
+ (when find-shorter
+ (while-no-input
+ ;; FIXME: Can be slow. Cache it maybe?
+ (setq binding (execute-extended-command--shorter
+ (symbol-name function) typed))))
+ (when binding
+ (with-temp-message
+ (format-message "You can run the command `%s' with %s"
+ function
+ (if (stringp binding)
+ (concat "M-x " binding " RET")
+ (key-description binding)))
+ (sit-for (if (numberp suggest-key-bindings)
+ suggest-key-bindings
+ 2))))))))))))
(defun execute-extended-command-for-buffer (prefixarg &optional
command-name typed)
@@ -2942,8 +2955,9 @@ undo record: if we undo from 4, `pending-undo-list' will be at 3,
(defvar undo-in-region nil
"Non-nil if `pending-undo-list' is not just a tail of `buffer-undo-list'.")
-(defvar undo-no-redo nil
- "If t, `undo' doesn't go through redo entries.")
+(defcustom undo-no-redo nil
+ "If t, `undo' doesn't go through redo entries."
+ :type 'boolean)
(defvar pending-undo-list nil
"Within a run of consecutive undo commands, list remaining to be undone.
@@ -3100,7 +3114,7 @@ Interactively, ARG is the prefix numeric argument and defaults to 1."
(let ((undo-in-progress t))
(while (and (consp ul) (eq (car ul) nil))
(setq ul (cdr ul)))
- (primitive-undo arg ul)))
+ (primitive-undo (or arg 1) ul)))
(new-pul (undo--last-change-was-undo-p new-ul)))
(message "Redo%s" (if undo-in-region " in region" ""))
(setq this-command 'undo)
@@ -3524,7 +3538,7 @@ with < or <= based on USE-<."
;; called or in some cases on a timer called after a change is made in
;; any buffer.
(defvar-local undo-auto--last-boundary-cause nil
- "Describe the cause of the last undo-boundary.
+ "Describe the cause of the last `undo-boundary'.
If `explicit', the last boundary was caused by an explicit call to
`undo-boundary', that is one not called by the code in this
@@ -5065,10 +5079,11 @@ interact nicely with `interprogram-cut-function' and
interaction; you may want to use them instead of manipulating the kill
ring directly.")
-(defcustom kill-ring-max 60
+(defcustom kill-ring-max 120
"Maximum length of kill ring before oldest elements are thrown away."
:type 'integer
- :group 'killing)
+ :group 'killing
+ :version "29.1")
(defvar kill-ring-yank-pointer nil
"The tail of the kill ring whose car is the last thing yanked.")
@@ -5281,12 +5296,16 @@ Lisp programs should use this function for killing text.
Supply two arguments, character positions BEG and END indicating the
stretch of text to be killed. If the optional argument REGION is
non-nil, the function ignores BEG and END, and kills the current
- region instead."
+ region instead. Interactively, REGION is always non-nil, and so
+ this command always kills the current region."
;; Pass mark first, then point, because the order matters when
;; calling `kill-append'.
- (interactive (list (mark) (point) 'region))
- (unless (and beg end)
- (user-error "The mark is not set now, so there is no region"))
+ (interactive (progn
+ (let ((beg (mark))
+ (end (point)))
+ (unless (and beg end)
+ (user-error "The mark is not set now, so there is no region"))
+ (list beg end 'region))))
(condition-case nil
(let ((string (if region
(funcall region-extract-function 'delete)
@@ -6513,13 +6532,13 @@ Display `Mark set' unless the optional second arg NOMSG is non-nil."
(defcustom set-mark-command-repeat-pop nil
"Non-nil means repeating \\[set-mark-command] after popping mark pops it again.
-That means that C-u \\[set-mark-command] \\[set-mark-command]
+That means that \\[universal-argument] \\[set-mark-command] \\[set-mark-command]
will pop the mark twice, and
-C-u \\[set-mark-command] \\[set-mark-command] \\[set-mark-command]
+\\[universal-argument] \\[set-mark-command] \\[set-mark-command] \\[set-mark-command]
will pop the mark three times.
A value of nil means \\[set-mark-command]'s behavior does not change
-after C-u \\[set-mark-command]."
+after \\[universal-argument] \\[set-mark-command]."
:type 'boolean
:group 'editing-basics)
@@ -6624,7 +6643,6 @@ Does not set point. Does nothing if mark ring is empty."
(setq mark-ring (nconc mark-ring (list (copy-marker (mark-marker)))))
(set-marker (mark-marker) (car mark-ring))
(set-marker (car mark-ring) nil)
- (unless (mark t) (ding))
(pop mark-ring))
(deactivate-mark))
@@ -7779,7 +7797,9 @@ other purposes."
When Visual Line mode is enabled, `word-wrap' is turned on in
this buffer, and simple editing commands are redefined to act on
visual lines, not logical lines. See Info node `Visual Line
-Mode' for details."
+Mode' for details.
+Turning on this mode disables line truncation set up by
+variables `truncate-lines' and `truncate-partial-width-windows'."
:keymap visual-line-mode-map
:group 'visual-line
:lighter " Wrap"
@@ -7912,8 +7932,8 @@ With argument 0, interchanges line point is in with line mark is in."
(defun transpose-subr (mover arg &optional special)
"Subroutine to do the work of transposing objects.
Works for lines, sentences, paragraphs, etc. MOVER is a function that
-moves forward by units of the given object (e.g. forward-sentence,
-forward-paragraph). If ARG is zero, exchanges the current object
+moves forward by units of the given object (e.g. `forward-sentence',
+`forward-paragraph'). If ARG is zero, exchanges the current object
with the one containing mark. If ARG is an integer, moves the
current object past ARG following (if ARG is positive) or
preceding (if ARG is negative) objects, leaving point after the
@@ -8308,8 +8328,13 @@ non-nil."
(if (eq buffer (window-buffer window))
(set-window-hscroll window 0)))
nil t)))
- (message "Truncate long lines %s"
- (if truncate-lines "enabled" "disabled")))
+ (message "Truncate long lines %s%s"
+ (if truncate-lines "enabled" "disabled")
+ (if (and truncate-lines visual-line-mode)
+ (progn
+ (visual-line-mode -1)
+ (format-message " and `visual-line-mode' disabled"))
+ "")))
(defun toggle-word-wrap (&optional arg)
"Toggle whether to use word-wrapping for continuation lines.
@@ -8409,16 +8434,29 @@ presented."
(defcustom blink-matching-paren t
"Non-nil means show matching open-paren when close-paren is inserted.
-If t, highlight the paren. If `jump', briefly move cursor to its
-position. If `jump-offscreen', move cursor there even if the
-position is off screen. With any other non-nil value, the
-off-screen position of the opening paren will be shown in the
-echo area."
+If this is non-nil, then when you type a closing delimiter, such as a
+closing parenthesis or brace, Emacs briefly indicates the location
+of the matching opening delimiter.
+
+The valid values are:
+
+ t Highlight the matching open-paren if it is visible
+ in the window, otherwise show the text with matching
+ open-paren in the echo area. This is the default.
+ `jump' If the matching open-paren is visible in the window,
+ briefly move cursor to its position; otherwise show
+ the text with matching open-paren in the echo area.
+ `jump-offscreen' Briefly move cursor to the matching open-paren
+ even if it is not visible in the window.
+ nil Don't show the matching open-paren.
+
+Any other non-nil value is handled the same as t."
+
:type '(choice
(const :tag "Disable" nil)
- (const :tag "Highlight" t)
- (const :tag "Move cursor" jump)
- (const :tag "Move cursor, even if off screen" jump-offscreen))
+ (const :tag "Highlight open-paren if visible" t)
+ (const :tag "Move cursor to open-paren if visible" jump)
+ (const :tag "Move cursor even if it's off screen" jump-offscreen))
:group 'paren-blinking)
(defcustom blink-matching-paren-on-screen t
@@ -8546,40 +8584,43 @@ The function should return non-nil if the two tokens do not match.")
(current-buffer))
(sit-for blink-matching-delay))
(delete-overlay blink-matching--overlay)))))
- (t
- (let ((open-paren-line-string
- (save-excursion
- (goto-char blinkpos)
- ;; Show what precedes the open in its line, if anything.
- (cond
- ((save-excursion (skip-chars-backward " \t") (not (bolp)))
- (buffer-substring (line-beginning-position)
- (1+ blinkpos)))
- ;; Show what follows the open in its line, if anything.
- ((save-excursion
- (forward-char 1)
- (skip-chars-forward " \t")
- (not (eolp)))
- (buffer-substring blinkpos
- (line-end-position)))
- ;; Otherwise show the previous nonblank line,
- ;; if there is one.
- ((save-excursion (skip-chars-backward "\n \t") (not (bobp)))
- (concat
- (buffer-substring (progn
- (skip-chars-backward "\n \t")
- (line-beginning-position))
- (progn (end-of-line)
- (skip-chars-backward " \t")
- (point)))
- ;; Replace the newline and other whitespace with `...'.
- "..."
- (buffer-substring blinkpos (1+ blinkpos))))
- ;; There is nothing to show except the char itself.
- (t (buffer-substring blinkpos (1+ blinkpos)))))))
- (minibuffer-message
- "Matches %s"
- (substring-no-properties open-paren-line-string))))))))
+ ((not show-paren-context-when-offscreen)
+ (minibuffer-message
+ "Matches %s"
+ (substring-no-properties
+ (blink-paren-open-paren-line-string blinkpos))))))))
+
+(defun blink-paren-open-paren-line-string (pos)
+ "Return the line string that contains the openparen at POS."
+ (save-excursion
+ (goto-char pos)
+ ;; Show what precedes the open in its line, if anything.
+ (cond
+ ((save-excursion (skip-chars-backward " \t") (not (bolp)))
+ (buffer-substring (line-beginning-position)
+ (1+ pos)))
+ ;; Show what follows the open in its line, if anything.
+ ((save-excursion
+ (forward-char 1)
+ (skip-chars-forward " \t")
+ (not (eolp)))
+ (buffer-substring pos
+ (line-end-position)))
+ ;; Otherwise show the previous nonblank line,
+ ;; if there is one.
+ ((save-excursion (skip-chars-backward "\n \t") (not (bobp)))
+ (concat
+ (buffer-substring (progn
+ (skip-chars-backward "\n \t")
+ (line-beginning-position))
+ (progn (end-of-line)
+ (skip-chars-backward " \t")
+ (point)))
+ ;; Replace the newline and other whitespace with `...'.
+ "..."
+ (buffer-substring pos (1+ pos))))
+ ;; There is nothing to show except the char itself.
+ (t (buffer-substring pos (1+ pos))))))
(defvar blink-paren-function 'blink-matching-open
"Function called, if non-nil, whenever a close parenthesis is inserted.
@@ -8725,7 +8766,7 @@ See also `read-mail-command' concerning reading mail."
(function-item :tag "Message with full Gnus features"
:format "%t\n"
gnus-user-agent)
- (function :tag "Other"))
+ (symbol :tag "Other"))
:version "23.2" ; sendmail->message
:group 'mail)
@@ -8871,7 +8912,7 @@ With a prefix argument, set VARIABLE to VALUE buffer-locally.
When called interactively, the user is prompted for VARIABLE and
then VALUE. The current value of VARIABLE will be put in the
-minibuffer history so that it can be accessed with `M-n', which
+minibuffer history so that it can be accessed with \\`M-n', which
makes it easier to edit it."
(interactive
(let* ((default-var (variable-at-point))
@@ -9575,7 +9616,7 @@ call `normal-erase-is-backspace-mode' (which see) instead."
(if (if (eq normal-erase-is-backspace 'maybe)
(and (not noninteractive)
(or (memq system-type '(ms-dos windows-nt))
- (memq window-system '(w32 ns))
+ (memq window-system '(w32 ns pgtk))
(and (eq window-system 'x)
(fboundp 'x-backspace-delete-keys-p)
(x-backspace-delete-keys-p))
@@ -9813,11 +9854,13 @@ warning using STRING as the message.")
The argument `COMMAND' should be a symbol.
-Running `M-x COMMAND RET' for the first time prompts for which
+Running `\\[execute-extended-command] COMMAND RET' for \
+the first time prompts for which
alternative to use and records the selected command as a custom
variable.
-Running `C-u M-x COMMAND RET' prompts again for an alternative
+Running `\\[universal-argument] \\[execute-extended-command] COMMAND RET' \
+prompts again for an alternative
and overwrites the previous choice.
The variable `COMMAND-alternatives' contains an alist with
@@ -9827,6 +9870,7 @@ does not have any effect until this variable is set.
CUSTOMIZATIONS, if non-nil, should be composed of alternating
`defcustom' keywords and values to add to the declaration of
`COMMAND-alternatives' (typically :group and :version)."
+ (declare (indent defun))
(let* ((command-name (symbol-name command))
(varalt-name (concat command-name "-alternatives"))
(varalt-sym (intern varalt-name))
diff --git a/lisp/skeleton.el b/lisp/skeleton.el
index c363fb2c489..2b183996d83 100644
--- a/lisp/skeleton.el
+++ b/lisp/skeleton.el
@@ -113,7 +113,8 @@ are integer buffer positions in the reverse order of the insertion order.")
"Define a user-configurable COMMAND that enters a statement skeleton.
DOCUMENTATION is that of the command.
SKELETON is as defined under `skeleton-insert'."
- (declare (doc-string 2) (debug (&define name stringp skeleton-edebug-spec)))
+ (declare (doc-string 2) (debug (&define name stringp skeleton-edebug-spec))
+ (indent defun))
(if skeleton-debug
(set command skeleton))
`(progn
diff --git a/lisp/so-long.el b/lisp/so-long.el
index 7bf15e85dad..c975384ddb3 100644
--- a/lisp/so-long.el
+++ b/lisp/so-long.el
@@ -8,7 +8,7 @@
;; Keywords: convenience
;; Created: 23 Dec 2015
;; Package-Requires: ((emacs "24.4"))
-;; Version: 1.1.1
+;; Version: 1.1.2
;; This file is part of GNU Emacs.
@@ -410,6 +410,7 @@
;; * Change Log:
;;
+;; 1.1.2 - Use `so-long-mode-line-active' face on `mode-name' in `so-long-mode'.
;; 1.1.1 - Identical to 1.1, but fixing an incorrect GNU ELPA release.
;; 1.1 - Utilise `buffer-line-statistics' in Emacs 28+, with the new
;; `so-long-predicate' function `so-long-statistics-excessive-p'.
@@ -447,7 +448,7 @@
;; 0.7.5 - Documentation.
;; - Added sgml-mode and nxml-mode to `so-long-target-modes'.
;; 0.7.4 - Refactored the handling of `whitespace-mode'.
-;; 0.7.3 - Added customize group `so-long' with user options.
+;; 0.7.3 - Added customization group `so-long' with user options.
;; - Added `so-long-original-values' to generalise the storage and
;; restoration of values from the original mode upon `so-long-revert'.
;; - Added `so-long-revert-hook'.
@@ -477,7 +478,7 @@
'(so-long ("1.0" . "27.1")
("1.1" . "28.1")))
-(defconst so-long--latest-version "1.1")
+(defconst so-long--latest-version "1.1.2")
(declare-function buffer-line-statistics "fns.c" t t) ;; Emacs 28+
(declare-function longlines-mode "longlines")
@@ -491,7 +492,7 @@
;; considered internal-use only (with `global-so-long-mode' the interface
;; for enabling or disabling the automated behaviour). FIXME: Establish a
;; way to support the original use-case, or rename to `so-long--enabled'.
- "Internal use. Non-nil when any so-long functionality has been used.")
+ "Internal use. Non-nil when any `so-long' functionality has been used.")
(defvar-local so-long--active nil ; internal use
"Non-nil when `so-long' mitigations are in effect.")
@@ -568,7 +569,7 @@ See `so-long-detected-long-line-p' for details."
(defcustom so-long-target-modes
'(prog-mode css-mode sgml-mode nxml-mode fundamental-mode)
- "`so-long' affects only these modes and their derivatives.
+ "`global-so-long-mode' affects only these modes and their derivatives.
Our primary use-case is minified programming code, so `prog-mode' covers
most cases, but there are some exceptions to this.
@@ -615,7 +616,9 @@ the mentioned options might interfere with some intended processing."
(defcustom so-long-predicate (if (fboundp 'buffer-line-statistics)
'so-long-statistics-excessive-p
'so-long-detected-long-line-p)
- "Function, called after `set-auto-mode' to decide whether action is needed.
+ "Function called after `set-auto-mode' to decide whether action is needed.
+
+This affects the behaviour of `global-so-long-mode'.
Only called if the major mode is a member of `so-long-target-modes'.
@@ -750,6 +753,8 @@ If ACTION-ARG is provided, it is used in place of `so-long-action'."
(defcustom so-long-file-local-mode-function 'so-long-mode-downgrade
"Function to call during `set-auto-mode' when a file-local mode is set.
+This affects the behaviour of `global-so-long-mode'.
+
The specified function will be called with a single argument, being the
file-local mode which was established.
@@ -761,8 +766,8 @@ place of `so-long-mode' -- therefore respecting the file-local mode value, yet
still overriding minor modes and variables (as if `so-long-action' had been set
to `so-long-minor-mode').
-The value `so-long-inhibit' means that so-long will not take any action at all
-for this file.
+The value `so-long-inhibit' means that `global-so-long-mode' will not take any
+action at all for this file.
If nil, then do not treat files with file-local modes any differently to other
files.
@@ -965,7 +970,12 @@ If nil, no mode line indicator will be displayed."
(defface so-long-mode-line-active
'((t :inherit mode-line-emphasis))
- "Face for `so-long-mode-line-info' when mitigations are active."
+ "Face for the mode line construct when mitigations are active.
+
+Applied to `mode-name' in the `so-long-mode' major mode, and to
+`so-long-mode-line-label' otherwise (for non-major-mode actions).
+
+See also `so-long-mode-line-info'."
:package-version '(so-long . "1.0"))
(defface so-long-mode-line-inactive
@@ -1090,7 +1100,7 @@ This command calls `so-long' with the selected action as an argument.")
;;;###autoload
(defun so-long-commentary ()
- "View the so-long documentation in `outline-mode'."
+ "View the `so-long' library's documentation in `outline-mode'."
(interactive)
(let ((buf "*So Long: Commentary*"))
(when (buffer-live-p (get-buffer buf))
@@ -1130,7 +1140,7 @@ This command calls `so-long' with the selected action as an argument.")
;;;###autoload
(defun so-long-customize ()
- "Open the so-long `customize' group."
+ "Open the customization group `so-long'."
(interactive)
(customize-group 'so-long))
@@ -1351,7 +1361,8 @@ This minor mode is a standard `so-long-action' option."
"Major mode keymap and menu for `so-long-mode'.")
;;;###autoload
-(define-derived-mode so-long-mode nil "So Long"
+(define-derived-mode so-long-mode nil
+ (propertize "So Long" 'face 'so-long-mode-line-active)
"This major mode is the default `so-long-action' option.
The normal reason for this mode being active is that `global-so-long-mode' is
@@ -1375,7 +1386,8 @@ values), despite potential performance issues, type \\[so-long-revert].
Use \\[so-long-commentary] for more information.
-Use \\[so-long-customize] to configure the behaviour."
+Use \\[so-long-customize] to open the customization group `so-long' to
+configure the behaviour."
;; Housekeeping. `so-long-mode' might be invoked directly rather than via
;; `so-long', so replicate the necessary behaviours. We could use this same
;; test in `so-long-after-change-major-mode' to run `so-long-hook', but that's
@@ -1532,7 +1544,7 @@ This is the `so-long-revert-function' for `so-long-mode'."
(interactive)
(let ((so-long-original-mode (so-long-original 'major-mode)))
(unless so-long-original-mode
- (error "Original mode unknown."))
+ (error "Original mode unknown"))
(funcall so-long-original-mode)
;; Emacs 26+ has already called `hack-local-variables' (during
;; `run-mode-hooks'; provided there was a `buffer-file-name'), but for older
@@ -1583,7 +1595,7 @@ because we do not want to downgrade the major mode in that scenario."
so-long-revert-function 'turn-off-so-long-minor-mode))))
(defun so-long-inhibit (&optional _mode)
- "Prevent so-long from having any effect at all.
+ "Prevent `global-so-long-mode' from having any effect.
This is a `so-long-file-local-mode-function' option."
(setq so-long--inhibited t))
@@ -1642,12 +1654,13 @@ function defined by `so-long-file-local-mode-function'."
"-mode"))
modes))))
- ;; `so-long' now processes the resulting mode list. If any modes were
- ;; listed, we assume that one of them is a major mode. It's possible that
- ;; this isn't true, but the buffer would remain in fundamental-mode if that
- ;; were the case, so it is very unlikely. For the purposes of passing a
- ;; value to `so-long-handle-file-local-mode' we assume the major mode was
- ;; the first mode specified (in which case it is the last in the list).
+ ;; Now process the resulting mode list for `so-long--set-auto-mode'.
+ ;; If any modes were listed, we assume that one of them is a major mode.
+ ;; It's possible that this isn't true, but the buffer would remain in
+ ;; fundamental-mode if that were the case, so it is very unlikely.
+ ;; For the purposes of passing a value to `so-long-handle-file-local-mode'
+ ;; we assume the major mode was the first mode specified (in which case it
+ ;; is the last in the list).
(when modes
(so-long-handle-file-local-mode (car (last modes))))))
@@ -1661,7 +1674,7 @@ function defined by `so-long-file-local-mode-function'."
;; (advice-add 'hack-local-variables :around #'so-long--hack-local-variables)
;;
;; See also "Files with a file-local 'mode'" in the Commentary.
- "Ensure that `so-long' defers to file-local mode declarations if necessary.
+ "Enable `global-so-long-mode' to defer to file-local mode declarations.
If a file-local mode is detected, then we call the function defined by
`so-long-file-local-mode-function'.
@@ -1673,7 +1686,7 @@ File-local header comments are currently an exception, and are processed by
`so-long--check-header-modes' (see which for details)."
;; The first arg to `hack-local-variables' is HANDLE-MODE since Emacs 26.1,
;; and MODE-ONLY in earlier versions. In either case we are interested in
- ;; whether it has the value `t'.
+ ;; whether it has the value t.
(let ((retval (apply orig-fun handle-mode args)))
(and (eq handle-mode t)
retval ; A file-local mode was set.
@@ -1685,7 +1698,8 @@ File-local header comments are currently an exception, and are processed by
;; (advice-add 'set-auto-mode :around #'so-long--set-auto-mode)
"Maybe call `so-long' for files with very long lines.
-This advice acts after `set-auto-mode' has set the buffer's major mode.
+This advice acts after `set-auto-mode' has set the buffer's major mode, if
+`global-so-long-mode' is enabled.
We can't act before this point, because some major modes must be exempt
\(binary file modes, for example). Instead, we act only when the selected
@@ -1848,14 +1862,14 @@ invoked."
;;;###autoload
(defun so-long-enable ()
- "Enable the so-long library's functionality.
+ "Enable the `so-long' library's functionality.
Equivalent to calling (global-so-long-mode 1)"
(interactive)
(global-so-long-mode 1))
(defun so-long-disable ()
- "Disable the so-long library's functionality.
+ "Disable the `so-long' library's functionality.
Equivalent to calling (global-so-long-mode 0)"
(interactive)
@@ -1880,7 +1894,8 @@ When such files are detected by `so-long-predicate', we invoke the selected
Use \\[so-long-commentary] for more information.
-Use \\[so-long-customize] to configure the behaviour."
+Use \\[so-long-customize] to open the customization group `so-long' to
+configure the behaviour."
:global t
:group 'so-long
(if global-so-long-mode
@@ -2065,13 +2080,13 @@ If it appears in `%s', you should remove it."
;; M-x ispell-buffer (using aspell).
; LocalWords: LocalWords british ispell aspell hunspell emacs elisp el init dir
-; LocalWords: customize customized customizing Customization globalized amongst
+; LocalWords: customize customized customizing customization Customization prog
; LocalWords: initialized profiler boolean minified pre redisplay config keymap
; LocalWords: noerror selectable mapc sgml nxml hl flydiff defs arg Phil Sainty
; LocalWords: defadvice nadvice whitespace ie bos eos eobp origmode un Un setq
; LocalWords: docstring auf Wiedersehen longlines alist autoload Refactored Inc
; LocalWords: MERCHANTABILITY RET REGEXP VAR ELPA WS mitigations EmacsWiki eval
-; LocalWords: rx filename filenames js defun bidi bpa prog FIXME
+; LocalWords: rx filename filenames js defun bidi bpa FIXME globalized amongst
;; So long, farewell, auf Wiedersehen, goodbye
;; You have to go, this code is minified
diff --git a/lisp/sort.el b/lisp/sort.el
index 0d2fd416649..09259805415 100644
--- a/lisp/sort.el
+++ b/lisp/sort.el
@@ -56,12 +56,12 @@ The variable `sort-fold-case' determines whether alphabetic case affects
the sort order.
The next four arguments are functions to be called to move point
-across a sort record. They will be called many times from within sort-subr.
+across a sort record. They will be called many times from within `sort-subr'.
NEXTRECFUN is called with point at the end of the previous record.
It moves point to the start of the next record.
It should move point to the end of the buffer if there are no more records.
-The first record is assumed to start at the position of point when sort-subr
+The first record is assumed to start at the position of point when `sort-subr'
is called.
ENDRECFUN is called with point within the record.
@@ -507,7 +507,8 @@ Use \\[untabify] to convert tabs to spaces before sorting."
(setq col-start (min col-beg1 col-end1))
(setq col-end (max col-beg1 col-end1))
(if (search-backward "\t" beg1 t)
- (error "sort-columns does not work with tabs -- use M-x untabify"))
+ (error (substitute-command-keys
+ "sort-columns does not work with tabs -- use \\[untabify]")))
(if (not (or (memq system-type '(windows-nt))
(let ((pos beg1) plist fontified)
(catch 'found
@@ -539,8 +540,8 @@ Use \\[untabify] to convert tabs to spaces before sorting."
(narrow-to-region beg1 end1)
(goto-char beg1)
(sort-subr reverse 'forward-line 'end-of-line
- #'(lambda () (move-to-column col-start) nil)
- #'(lambda () (move-to-column col-end) nil))))))))
+ (lambda () (move-to-column col-start) nil)
+ (lambda () (move-to-column col-end) nil))))))))
;;;###autoload
(defun reverse-region (beg end)
@@ -587,16 +588,16 @@ is the one that ends before END."
Non-interactively, arguments BEG and END delimit the region.
Normally it searches forwards, keeping the first instance of
each identical line. If REVERSE is non-nil (interactively, with
-a C-u prefix), it searches backwards and keeps the last instance of
+a \\[universal-argument] prefix), it searches backwards and keeps the last instance of
each repeated line.
Identical lines need not be adjacent, unless the argument
-ADJACENT is non-nil (interactively, with a C-u C-u prefix).
+ADJACENT is non-nil (interactively, with a \\[universal-argument] \\[universal-argument] prefix).
This is a more efficient mode of operation, and may be useful
on large regions that have already been sorted.
If the argument KEEP-BLANKS is non-nil (interactively, with a
-C-u C-u C-u prefix), it retains repeated blank lines.
+\\[universal-argument] \\[universal-argument] \\[universal-argument] prefix), it retains repeated blank lines.
Returns the number of deleted lines. Interactively, or if INTERACTIVE
is non-nil, it also prints a message describing the number of deletions."
diff --git a/lisp/speedbar.el b/lisp/speedbar.el
index 3cc3e276067..cfa96608bff 100644
--- a/lisp/speedbar.el
+++ b/lisp/speedbar.el
@@ -3694,27 +3694,21 @@ regular expression EXPR."
;;; BUFFER DISPLAY mode.
;;
-(defvar speedbar-buffers-key-map nil
+(defvar speedbar-buffers-key-map
+ (let ((map (speedbar-make-specialized-keymap)))
+ ;; Basic tree features
+ (define-key map "e" #'speedbar-edit-line)
+ (define-key map "\C-m" #'speedbar-edit-line)
+ (define-key map "+" #'speedbar-expand-line)
+ (define-key map "=" #'speedbar-expand-line)
+ (define-key map "-" #'speedbar-contract-line)
+ (define-key map " " #'speedbar-toggle-line-expansion)
+ ;; Buffer specific keybindings
+ (define-key map "k" #'speedbar-buffer-kill-buffer)
+ (define-key map "r" #'speedbar-buffer-revert-buffer)
+ map)
"Keymap used when in the buffers display mode.")
-(if speedbar-buffers-key-map
- nil
- (setq speedbar-buffers-key-map (speedbar-make-specialized-keymap))
-
- ;; Basic tree features
- (define-key speedbar-buffers-key-map "e" 'speedbar-edit-line)
- (define-key speedbar-buffers-key-map "\C-m" 'speedbar-edit-line)
- (define-key speedbar-buffers-key-map "+" 'speedbar-expand-line)
- (define-key speedbar-buffers-key-map "=" 'speedbar-expand-line)
- (define-key speedbar-buffers-key-map "-" 'speedbar-contract-line)
- (define-key speedbar-buffers-key-map " " 'speedbar-toggle-line-expansion)
-
- ;; Buffer specific keybindings
- (define-key speedbar-buffers-key-map "k" 'speedbar-buffer-kill-buffer)
- (define-key speedbar-buffers-key-map "r" 'speedbar-buffer-revert-buffer)
-
- )
-
(defvar speedbar-buffer-easymenu-definition
'(["Jump to buffer" speedbar-edit-line t]
["Expand File Tags" speedbar-expand-line
diff --git a/lisp/sqlite-mode.el b/lisp/sqlite-mode.el
new file mode 100644
index 00000000000..082eb8276e8
--- /dev/null
+++ b/lisp/sqlite-mode.el
@@ -0,0 +1,216 @@
+;;; sqlite-mode.el --- Mode for examining sqlite3 database files -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 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 'cl-lib)
+
+(declare-function sqlite-execute "sqlite.c")
+(declare-function sqlite-more-p "sqlite.c")
+(declare-function sqlite-next "sqlite.c")
+(declare-function sqlite-columns "sqlite.c")
+(declare-function sqlite-finalize "sqlite.c")
+(declare-function sqlite-select "sqlite.c")
+(declare-function sqlite-open "sqlite.c")
+
+(defvar-keymap sqlite-mode-map
+ "g" #'sqlite-mode-list-tables
+ "c" #'sqlite-mode-list-columns
+ "RET" #'sqlite-mode-list-data
+ "DEL" #'sqlite-mode-delete)
+
+(define-derived-mode sqlite-mode special-mode "Sqlite"
+ "This mode lists the contents of an .sqlite3 file"
+ :interactive nil
+ (buffer-disable-undo)
+ (setq-local buffer-read-only t
+ truncate-lines t))
+
+(defvar sqlite--db nil)
+
+;;;###autoload
+(defun sqlite-mode-open-file (file)
+ "Browse the contents of an sqlite file."
+ (interactive "fSQLite file name: ")
+ (unless (sqlite-available-p)
+ (error "This Emacs doesn't have SQLite support, so it can't view SQLite files"))
+ (pop-to-buffer (get-buffer-create
+ (format "*SQLite %s*" (file-name-nondirectory file))))
+ (sqlite-mode)
+ (setq-local sqlite--db (sqlite-open file))
+ (sqlite-mode-list-tables))
+
+(defun sqlite-mode-list-tables ()
+ "Re-list the tables from the currently selected database."
+ (interactive nil sqlite-mode)
+ (let ((inhibit-read-only t)
+ (db sqlite--db)
+ (entries nil))
+ (erase-buffer)
+ (dolist (table (sqlite-select db "select name from sqlite_master where type = 'table' and name not like 'sqlite_%' order by name"))
+ (push (list (car table)
+ (caar (sqlite-select db (format "select count(*) from %s"
+ (car table)))))
+ entries))
+ (sqlite-mode--tablify '("Table Name" "Number of Rows")
+ (nreverse entries)
+ 'table)
+ (goto-char (point-min))))
+
+(defun sqlite-mode--tablify (columns rows type &optional prefix)
+ (let ((widths
+ (mapcar
+ (lambda (i)
+ (1+ (seq-max (mapcar (lambda (row)
+ (length (format "%s" (nth i row))))
+ (cons columns rows)))))
+ (number-sequence 0 (1- (length columns))))))
+ (when prefix
+ (insert prefix))
+ (dotimes (i (length widths))
+ (insert (propertize (format (format "%%-%ds " (nth i widths))
+ (nth i columns))
+ 'face 'header-line)))
+ (insert "\n")
+ (dolist (row rows)
+ (let ((start (point)))
+ (when prefix
+ (insert prefix))
+ (dotimes (i (length widths))
+ (let ((elem (nth i row)))
+ (insert (format (format "%%%s%ds "
+ (if (numberp elem)
+ "" "-")
+ (nth i widths))
+ (if (numberp elem)
+ (nth i row)
+ (string-replace "\n" " " (or elem "")))))))
+ (put-text-property start (point) 'sqlite--row row)
+ (put-text-property start (point) 'sqlite--type type)
+ (insert "\n")))))
+
+(defun sqlite-mode-list-columns ()
+ "List the columns of the table under point."
+ (interactive nil sqlite-mode)
+ (let ((row (get-text-property (point) 'sqlite--row)))
+ (unless row
+ (user-error "No table under point"))
+ (let ((columns (sqlite-mode--column-names (car row)))
+ (inhibit-read-only t))
+ (save-excursion
+ (forward-line 1)
+ (if (looking-at " ")
+ ;; Delete the info.
+ (delete-region (point) (if (re-search-forward "^[^ ]" nil t)
+ (match-beginning 0)
+ (point-max)))
+ ;; Insert the info.
+ (dolist (column columns)
+ (insert (format " %s\n" column))))))))
+
+(defun sqlite-mode--column-names (table)
+ (let ((sql
+ (caar
+ (sqlite-select
+ sqlite--db
+ "select sql from sqlite_master where tbl_name = ? AND type = 'table'"
+ (list table)))))
+ (mapcar
+ #'string-trim
+ (split-string (replace-regexp-in-string "^.*(\\|)$" "" sql) ","))))
+
+(defun sqlite-mode-list-data ()
+ "List the data from the table under point."
+ (interactive nil sqlite-mode)
+ (let ((row (and (eq (get-text-property (point) 'sqlite--type) 'table)
+ (get-text-property (point) 'sqlite--row))))
+ (unless row
+ (user-error "No table under point"))
+ (let ((inhibit-read-only t))
+ (save-excursion
+ (forward-line 1)
+ (if (looking-at " ")
+ ;; Delete the info.
+ (delete-region (point) (if (re-search-forward "^[^ ]" nil t)
+ (match-beginning 0)
+ (point-max)))
+ (sqlite--mode--list-data (list (car row) 0)))))))
+
+(defun sqlite-mode--more-data (stmt)
+ (let ((inhibit-read-only t))
+ (beginning-of-line)
+ (delete-region (point) (progn (forward-line 1) (point)))
+ (sqlite--mode--list-data stmt)))
+
+(defun sqlite--mode--list-data (data)
+ (let* ((table (car data))
+ (rowid (cadr data))
+ stmt)
+ (unwind-protect
+ (progn
+ (setq stmt
+ (sqlite-select
+ sqlite--db
+ (format "select rowid, * from %s where rowid >= ?" table)
+ (list rowid)
+ 'set))
+ (sqlite-mode--tablify (sqlite-columns stmt)
+ (cl-loop for i from 0 upto 1000
+ for row = (sqlite-next stmt)
+ while row
+ do (setq rowid (car row))
+ collect row)
+ (cons 'row table)
+ " ")
+ (when (sqlite-more-p stmt)
+ (insert (buttonize " More data...\n" #'sqlite-mode--more-data
+ (list table rowid)))))
+ (when stmt
+ (sqlite-finalize stmt)))))
+
+(defun sqlite-mode-delete ()
+ "Delete the row under point."
+ (interactive nil sqlite-mode)
+ (let ((table (get-text-property (point) 'sqlite--type))
+ (row (get-text-property (point) 'sqlite--row))
+ (inhibit-read-only t))
+ (when (or (not (consp table))
+ (not (eq (car table) 'row)))
+ (user-error "No row under point"))
+ (unless (yes-or-no-p "Really delete the row under point? ")
+ (user-error "Not deleting"))
+ (sqlite-execute
+ sqlite--db
+ (format "delete from %s where %s"
+ (cdr table)
+ (string-join
+ (mapcar (lambda (column)
+ (format "%s = ?" (car (split-string column " "))))
+ (cons "rowid" (sqlite-mode--column-names (cdr table))))
+ " and "))
+ row)
+ (delete-region (line-beginning-position) (progn (forward-line 1) (point)))))
+
+(provide 'sqlite-mode)
+
+;;; sqlite-mode.el ends here
diff --git a/lisp/sqlite.el b/lisp/sqlite.el
new file mode 100644
index 00000000000..6d32a0468f3
--- /dev/null
+++ b/lisp/sqlite.el
@@ -0,0 +1,43 @@
+;;; sqlite.el --- Functions for interacting with sqlite3 databases -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 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:
+
+(defmacro with-sqlite-transaction (db &rest body)
+ "Execute BODY while holding a transaction for DB."
+ (declare (indent 1) (debug (form body)))
+ (let ((db-var (gensym))
+ (func-var (gensym)))
+ `(let ((,db-var ,db)
+ (,func-var (lambda () ,@body)))
+ (if (sqlite-available-p)
+ (unwind-protect
+ (progn
+ (sqlite-transaction ,db-var)
+ (funcall ,func-var))
+ (sqlite-commit ,db-var))
+ (funcall ,func-var)))))
+
+(provide 'sqlite)
+
+;;; sqlite.el ends here
diff --git a/lisp/startup.el b/lisp/startup.el
index f20c61bdfed..2928e815124 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -519,6 +519,19 @@ DIRS are relative."
xdg-dir)
(t emacs-d-dir))))
+(defvar comp--delayed-sources)
+(defvar comp--loadable)
+(declare-function native--compile-async "comp.el"
+ (files &optional recursively load selector))
+(defun startup--honor-delayed-native-compilations ()
+ "Honor pending delayed deferred native compilations."
+ (when (and (native-comp-available-p)
+ comp--delayed-sources)
+ (require 'comp)
+ (setq comp--loadable t)
+ (native--compile-async comp--delayed-sources nil 'late)
+ (setq comp--delayed-sources nil)))
+
(defvar native-comp-eln-load-path)
(defun normal-top-level ()
"Emacs calls this function when it first starts up.
@@ -785,7 +798,8 @@ It is the default value of the variable `top-level'."
(if (string-match "\\`DISPLAY=" varval)
(setq display varval))))
(when display
- (delete display process-environment)))))
+ (delete display process-environment))))
+ (startup--honor-delayed-native-compilations))
;; Precompute the keyboard equivalents in the menu bar items.
;; Command-line options supported by tty's:
@@ -1557,17 +1571,22 @@ If this is nil, no message will be displayed."
`((:face (variable-pitch font-lock-comment-face)
"Welcome to "
:link ("GNU Emacs"
- ,(lambda (_button) (browse-url "https://www.gnu.org/software/emacs/"))
+ ,(lambda (_button)
+ (let ((browse-url-browser-function 'eww-browse-url))
+ (browse-url "https://www.gnu.org/software/emacs/")))
"Browse https://www.gnu.org/software/emacs/")
", one component of the "
:link
,(lambda ()
(if (eq system-type 'gnu/linux)
`("GNU/Linux"
- ,(lambda (_button) (browse-url "https://www.gnu.org/gnu/linux-and-gnu.html"))
+ ,(lambda (_button)
+ (let ((browse-url-browser-function 'eww-browse-url))
+ (browse-url "https://www.gnu.org/gnu/linux-and-gnu.html")))
"Browse https://www.gnu.org/gnu/linux-and-gnu.html")
`("GNU" ,(lambda (_button)
- (browse-url "https://www.gnu.org/gnu/thegnuproject.html"))
+ (let ((browse-url-browser-function 'eww-browse-url))
+ (browse-url "https://www.gnu.org/gnu/thegnuproject.html")))
"Browse https://www.gnu.org/gnu/thegnuproject.html")))
" operating system.\n\n"
:face variable-pitch
@@ -1600,7 +1619,8 @@ If this is nil, no message will be displayed."
"\n"
:link ("Emacs Guided Tour"
,(lambda (_button)
- (browse-url "https://www.gnu.org/software/emacs/tour/"))
+ (let ((browse-url-browser-function 'eww-browse-url))
+ (browse-url "https://www.gnu.org/software/emacs/tour/")))
"Browse https://www.gnu.org/software/emacs/tour/")
"\tOverview of Emacs features at gnu.org\n"
:link ("View Emacs Manual" ,(lambda (_button) (info-emacs-manual)))
@@ -1623,22 +1643,31 @@ Each element in the list should be a list of strings or pairs
`((:face (variable-pitch font-lock-comment-face)
"This is "
:link ("GNU Emacs"
- ,(lambda (_button) (browse-url "https://www.gnu.org/software/emacs/"))
+ ,(lambda (_button)
+ (let ((browse-url-browser-function 'eww-browse-url))
+ (browse-url "https://www.gnu.org/software/emacs/")))
"Browse https://www.gnu.org/software/emacs/")
- ", one component of the "
+ ", a text editor and more.\nIt's a component of the "
:link
,(lambda ()
(if (eq system-type 'gnu/linux)
`("GNU/Linux"
,(lambda (_button)
- (browse-url "https://www.gnu.org/gnu/linux-and-gnu.html"))
+ (let ((browse-url-browser-function 'eww-browse-url))
+ (browse-url "https://www.gnu.org/gnu/linux-and-gnu.html")))
"Browse https://www.gnu.org/gnu/linux-and-gnu.html")
- `("GNU" ,(lambda (_button) (describe-gnu-project))
+ `("GNU" ,(lambda (_button)
+ (let ((browse-url-browser-function 'eww-browse-url))
+ (describe-gnu-project)))
"Display info on the GNU project.")))
" operating system.\n"
:face (variable-pitch font-lock-builtin-face)
"\n"
- ,(lambda () (emacs-version))
+ ,(lambda ()
+ (with-temp-buffer
+ (insert (emacs-version))
+ (fill-region (point-min) (point-max))
+ (buffer-string)))
"\n"
:face (variable-pitch (:height 0.8))
,(lambda () emacs-copyright)
@@ -1653,7 +1682,9 @@ Each element in the list should be a list of strings or pairs
,(lambda (_button) (info "(emacs)Contributing")))
"\tHow to report bugs and contribute improvements to Emacs\n"
"\n"
- :link ("GNU and Freedom" ,(lambda (_button) (describe-gnu-project)))
+ :link ("GNU and Freedom" ,(lambda (_button)
+ (let ((browse-url-browser-function 'eww-browse-url))
+ (describe-gnu-project))))
"\tWhy we developed GNU Emacs, and the GNU operating system\n"
:link ("Absence of Warranty" ,(lambda (_button) (describe-no-warranty)))
"\tGNU Emacs comes with "
@@ -1691,7 +1722,8 @@ Each element in the list should be a list of strings or pairs
"\n"
:link ("Emacs Guided Tour"
,(lambda (_button)
- (browse-url "https://www.gnu.org/software/emacs/tour/"))
+ (let ((browse-url-browser-function 'eww-browse-url))
+ (browse-url "https://www.gnu.org/software/emacs/tour/")))
"Browse https://www.gnu.org/software/emacs/tour/")
"\tSee an overview of Emacs features at gnu.org\n"
:link ("Emacs Manual" ,(lambda (_button) (info-emacs-manual)))
@@ -1789,9 +1821,19 @@ a face or button specification."
(window-width (window-width)))
(when img
(when (> window-width image-width)
- ;; Center the image in the window.
- (insert (propertize " " 'display
- `(space :align-to (+ center (-0.5 . ,img)))))
+ ;; Center the image above text.
+ ;; NB. The logo used to be centered in the window, which made
+ ;; it align poorly with the non-centered text on large
+ ;; displays. Arguably it would be better to center both
+ ;; text and image, but this will do for now. -- SK
+ (let ((text-width 80)
+ ;; The below value chosen to avoid splash screen being
+ ;; visually unbalanced. This needs to be eye-balled.
+ (adjust-left 3))
+ (insert (propertize " " 'display
+ `(space :align-to (+ ,(- (/ text-width 2)
+ adjust-left)
+ (-0.5 . ,img))))))
;; Change the color of the XPM version of the splash image
;; so that it is visible with a dark frame background.
@@ -1803,7 +1845,9 @@ a face or button specification."
(make-button (prog1 (point) (insert-image img)) (point)
'face 'default
'help-echo "mouse-2, RET: Browse https://www.gnu.org/"
- 'action (lambda (_button) (browse-url "https://www.gnu.org/"))
+ 'action (lambda (_button)
+ (let ((browse-url-browser-function 'eww-browse-url))
+ (browse-url "https://www.gnu.org/")))
'follow-link t)
(insert "\n\n")))))
@@ -1812,28 +1856,35 @@ a face or button specification."
(unless concise
(fancy-splash-insert
:face 'variable-pitch
- "\nTo start... "
+ "\nTo start...\t"
:link `("Open a File"
,(lambda (_button) (call-interactively 'find-file))
"Specify a new file's name, to edit the file")
- " "
+ "\t\t"
:link `("Open Home Directory"
,(lambda (_button) (dired "~"))
"Open your home directory, to operate on its files")
- " "
+ "\n\t"
:link `("Customize Startup"
,(lambda (_button) (customize-group 'initialization))
"Change initialization settings including this screen")
+ "\t"
+ :link `("Explore Packages"
+ ,(lambda (_button) (call-interactively 'package-list-packages))
+ "Explore, install and remove Emacs packages (requires Internet connection)")
"\n"))
(fancy-splash-insert
:face 'variable-pitch "To quit a partially entered command, type "
:face 'default "Control-g"
:face 'variable-pitch ".\n")
- (fancy-splash-insert :face '(variable-pitch font-lock-builtin-face)
- "\nThis is "
- (emacs-version)
- "\n"
- :face '(variable-pitch (:height 0.8))
+ (save-restriction
+ (narrow-to-region (point) (point))
+ (fancy-splash-insert :face '(variable-pitch font-lock-builtin-face)
+ "\nThis is "
+ (emacs-version)
+ "\n")
+ (fill-region (point-min) (point-max)))
+ (fancy-splash-insert :face '(variable-pitch (:height 0.8))
emacs-copyright
"\n")
(when auto-save-list-file-prefix
@@ -1917,7 +1968,6 @@ splash screen in another window."
(insert "\n")
(fancy-startup-tail concise))
(use-local-map splash-screen-keymap)
- (setq-local browse-url-browser-function 'eww-browse-url)
(setq tab-width 22
buffer-read-only t)
(set-buffer-modified-p nil)
@@ -1955,11 +2005,11 @@ splash screen in another window."
(goto-char (point-min))
(force-mode-line-update))
(use-local-map splash-screen-keymap)
- (setq-local browse-url-browser-function 'eww-browse-url)
(setq tab-width 22)
(setq buffer-read-only t)
+ ;; Place point somewhere it doesn't cover a character.
(goto-char (point-min))
- (forward-line 3))))
+ (re-search-forward "\n$" nil nil 2))))
(defun fancy-splash-frame ()
"Return the frame to use for the fancy splash screen.
@@ -1971,6 +2021,8 @@ we put it on this frame."
;; frame visible.
(if (eq (window-system) 'w32)
(sit-for 0 t))
+ (if (eq (window-system) 'pgtk)
+ (sit-for 0.1 t))
(dolist (frame (append (frame-list) (list (selected-frame))))
(if (and (frame-visible-p frame)
(not (window-minibuffer-p (frame-selected-window frame))))
@@ -2112,8 +2164,11 @@ To quit a partially entered command, type Control-g.\n")
'follow-link t)
(insert "\tChange initialization settings including this screen\n")
- (insert "\n" (emacs-version)
- "\n" emacs-copyright))
+ (save-restriction
+ (narrow-to-region (point) (point))
+ (insert "\n" (emacs-version) "\n")
+ (fill-region (point-min) (point-max)))
+ (insert emacs-copyright))
(defun normal-no-mouse-startup-screen ()
"Show a splash screen suitable for displays without mouse support."
@@ -2193,7 +2248,11 @@ If you have no Meta key, you may instead type ESC followed by the character.)"))
(startup--get-buffer-create-scratch)))
'follow-link t)
(insert "\n")
- (insert "\n" (emacs-version) "\n" emacs-copyright "\n")
+ (save-restriction
+ (narrow-to-region (point) (point))
+ (insert "\n" (emacs-version) "\n")
+ (fill-region (point-min) (point-max)))
+ (insert emacs-copyright "\n")
(insert (substitute-command-keys
"
GNU Emacs comes with ABSOLUTELY NO WARRANTY; type \\[describe-no-warranty] for "))
@@ -2233,7 +2292,9 @@ Type \\[describe-distribution] for information on "))
(insert "\tHow to report bugs and contribute improvements to Emacs\n\n")
(insert-button "GNU and Freedom"
- 'action (lambda (_button) (describe-gnu-project))
+ 'action (lambda (_button)
+ (let ((browse-url-browser-function 'eww-browse-url))
+ (describe-gnu-project)))
'follow-link t)
(insert "\t\tWhy we developed GNU Emacs and the GNU system\n")
@@ -2374,6 +2435,7 @@ A fancy display is used on graphic displays, normal otherwise."
;; and long versions of what's on command-switch-alist.
(longopts
(append '("--funcall" "--load" "--insert" "--kill"
+ "--dump-file" "--seccomp"
"--directory" "--eval" "--execute" "--no-splash"
"--find-file" "--visit" "--file" "--no-desktop")
(mapcar (lambda (elt) (concat "-" (car elt)))
@@ -2517,7 +2579,15 @@ nil default-directory" name)
(let* ((file (command-line-normalize-file-name
(or argval (pop command-line-args-left))))
;; Take file from default dir.
- (file-ex (file-truename (expand-file-name file))))
+ (file-ex (expand-file-name file))
+ (truename (file-truename file-ex)))
+ ;; We want to use the truename here if we can,
+ ;; because that makes `eval-after-load' work
+ ;; more reliably. But if the file is, for
+ ;; instance, /dev/stdin, the truename doesn't
+ ;; actually exist on some systems.
+ (when (file-exists-p truename)
+ (setq file-ex truename))
(load file-ex nil t t)))
((equal argi "-insert")
@@ -2527,6 +2597,11 @@ nil default-directory" name)
(error "File name omitted from `-insert' option"))
(insert-file-contents (command-line-normalize-file-name tem)))
+ ((or (equal argi "-dump-file")
+ (equal argi "-seccomp"))
+ ;; This was processed in C.
+ (or argval (pop command-line-args-left)))
+
((equal argi "-kill")
(kill-emacs t))
diff --git a/lisp/strokes.el b/lisp/strokes.el
index 18595cb0947..db0eb83a3e6 100644
--- a/lisp/strokes.el
+++ b/lisp/strokes.el
@@ -928,13 +928,13 @@ cycle can continue.
To toggle strokes-mode, invoke the command
-> M-x strokes-mode
+> \\[strokes-mode]
** Strokes for controlling the behavior of Emacs...
When you're ready to start defining strokes, just use the command
-> M-x strokes-global-set-stroke
+> \\[strokes-global-set-stroke]
You will see a ` *strokes*' buffer which is waiting for you to enter in
your stroke. When you enter in the stroke, you draw with button 1 or
@@ -943,7 +943,7 @@ which will be executed when that stroke is invoked. Simple as that.
For now, try to define a stroke to copy a region. This is a popular
edit command, so type
-> M-x strokes-global-set-stroke
+> \\[strokes-global-set-stroke]
Then, in the ` *strokes*' buffer, draw the letter `C' (for `copy')
and then, when it asks you to enter the command to map that to, type
@@ -955,7 +955,7 @@ Remember: paint with button 1 or button 2 and then end with button 3.
If ever you want to know what a certain strokes maps to, then do
-> M-x strokes-describe-stroke
+> \\[strokes-describe-stroke]
and you can enter in any arbitrary stroke. Remember: The strokes
package lets you program in simple and complex (multi-lift) strokes.
@@ -967,12 +967,12 @@ will invoke the command `strokes-do-stroke'.
If ever you define a stroke which you don't like, then you can unset
it with the command
-> M-x strokes-unset-last-stroke
+> \\[strokes-unset-last-stroke]
You can always get an idea of what your current strokes look like with
the command
-> M-x strokes-list-strokes
+> \\[strokes-list-strokes]
Your strokes will be displayed in alphabetical order (based on command
names) and the beginning of each simple stroke will be marked by a
@@ -981,19 +981,19 @@ stroke, the dot colors are arranged in the rainbow color sequence,
`ROYGBIV'. If you want a listing of your strokes from most recent
down, then use a prefix argument:
-> C-u M-x strokes-list-strokes
+> \\[universal-argument] \\[strokes-list-strokes]
Your strokes are stored as you enter them. They get saved into the
file specified by the `strokes-file' variable, along with other strokes
configuration variables. You will be prompted to save them when you
exit Emacs, or you can save them with
-> M-x strokes-prompt-user-save-strokes
+> \\[strokes-prompt-user-save-strokes]
Your strokes get loaded automatically when you enable `strokes-mode'.
You can also load in your user-defined strokes with
-> M-x strokes-load-user-strokes
+> \\[strokes-load-user-strokes]
** Strokes for pictographic editing...
@@ -1006,11 +1006,11 @@ into the buffer. You treat it somewhat like any other character,
which you can copy, paste, delete, move, etc. When all is done, you
may want to send the file, or save it. This is done with
-> M-x strokes-encode-buffer
+> \\[strokes-encode-buffer]
Likewise, to decode the strokes from a strokes-encoded buffer you do
-> M-x strokes-decode-buffer
+> \\[strokes-decode-buffer]
** A few more important things...
@@ -1395,14 +1395,19 @@ Encode/decode your strokes with \\[strokes-encode-buffer],
(strokes-load-user-strokes))
(add-hook 'kill-emacs-query-functions
#'strokes-prompt-user-save-strokes)
- (add-hook 'select-frame-hook
- #'strokes-update-window-configuration)
+ ;; FIXME: Should this be something like `focus-in-hook'?
+ ;; That variable is obsolete, but `select-frame-hook' has
+ ;; never existed in Emacs.
+ ;;(add-hook 'select-frame-hook
+ ;; #'strokes-update-window-configuration)
(strokes-update-window-configuration))
(t ; turn off strokes
(if (get-buffer strokes-buffer-name)
- (kill-buffer (get-buffer strokes-buffer-name)))
- (remove-hook 'select-frame-hook
- #'strokes-update-window-configuration))))
+ (kill-buffer (get-buffer strokes-buffer-name)))
+ ;; FIXME: Same as above.
+ ;;(remove-hook 'select-frame-hook
+ ;; #'strokes-update-window-configuration)
+ )))
;;;; strokes-xpm stuff (later may be separate)...
diff --git a/lisp/subr.el b/lisp/subr.el
index 0a31ef2b29f..9c07606100b 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -22,6 +22,8 @@
;; 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:
;; declare-function's args use &rest, not &optional, for compatibility
@@ -59,7 +61,8 @@ must be the first non-whitespace on a line.
For more information, see Info node `(elisp)Declaring Functions'."
(declare (advertised-calling-convention
(fn file &optional arglist fileonly) nil))
- ;; Does nothing - byte-compile-declare-function does the work.
+ ;; Does nothing - `byte-compile-macroexpand-declare-function' does
+ ;; the work.
nil)
@@ -166,8 +169,8 @@ variables are literal symbols and should not be quoted.
The second VALUE is not computed until after the first VARIABLE
is set, and so on; each VALUE can use the new value of variables
-set earlier in the ‘setq-local’. The return value of the
-‘setq-local’ form is the value of the last VALUE.
+set earlier in the `setq-local'. The return value of the
+`setq-local' form is the value of the last VALUE.
\(fn [VARIABLE VALUE]...)"
(declare (debug setq))
@@ -191,7 +194,7 @@ set earlier in the ‘setq-local’. The return value of the
"Define VAR as a buffer-local variable with default value VAL.
Like `defvar' but additionally marks the variable as being automatically
buffer-local wherever it is set."
- (declare (debug defvar) (doc-string 3))
+ (declare (debug defvar) (doc-string 3) (indent 2))
;; Can't use backquote here, it's too early in the bootstrap.
(list 'progn (list 'defvar var val docstring)
(list 'make-variable-buffer-local (list 'quote var))))
@@ -486,7 +489,7 @@ was called."
"Return VALUE with its bits shifted left by COUNT.
If COUNT is negative, shifting is actually to the right.
In this case, if VALUE is a negative fixnum treat it as unsigned,
-i.e., subtract 2 * most-negative-fixnum from VALUE before shifting it."
+i.e., subtract 2 * `most-negative-fixnum' from VALUE before shifting it."
(when (and (< value 0) (< count 0))
(when (< value most-negative-fixnum)
(signal 'args-out-of-range (list value count)))
@@ -694,7 +697,7 @@ If N is omitted or nil, remove the last element."
"Destructively remove `equal' duplicates from LIST.
Store the result in LIST and return it. LIST must be a proper list.
Of several `equal' occurrences of an element in LIST, the first
-one is kept."
+one is kept. See `seq-uniq' for non-destructive operation."
(let ((l (length list)))
(if (> l 100)
(let ((hash (make-hash-table :test #'equal :size l))
@@ -927,15 +930,29 @@ side-effects, and the argument LIST is not modified."
"Convert KEYS to the internal Emacs key representation.
KEYS should be a string in the format returned by commands such
as `C-h k' (`describe-key').
+
This is the same format used for saving keyboard macros (see
`edmacro-mode').
+Here's some example key sequences:
+
+ \"f\"
+ \"C-c C-c\"
+ \"H-<left>\"
+ \"M-RET\"
+ \"C-M-<return>\"
+
For an approximate inverse of this, see `key-description'."
- ;; Don't use a defalias, since the `pure' property is true only for
- ;; the calling convention of `kbd'.
(declare (pure t) (side-effect-free t))
- ;; A pure function is expected to preserve the match data.
- (save-match-data (read-kbd-macro keys)))
+ (let ((res (key-parse keys)))
+ (if (not (memq nil (mapcar (lambda (ch)
+ (and (numberp ch)
+ (<= 0 ch 127)))
+ res)))
+ ;; Return a string.
+ (concat (mapcar #'identity res))
+ ;; Return a vector.
+ res)))
(defun undefined ()
"Beep to tell the user this binding is undefined."
@@ -986,6 +1003,9 @@ PARENT if non-nil should be a keymap."
(defun define-key-after (keymap key definition &optional after)
"Add binding in KEYMAP for KEY => DEFINITION, right after AFTER's binding.
+This is a legacy function; see `keymap-set-after' for the
+recommended function to use instead.
+
This is like `define-key' except that the binding for KEY is placed
just after the binding for the event AFTER, instead of at the beginning
of the map. Note that AFTER must be an event type (like KEY), NOT a command
@@ -998,6 +1018,7 @@ Bindings are always added before any inherited map.
The order of bindings in a keymap matters only when it is used as
a menu, so this function is not useful for non-menu keymaps."
+ (declare (indent defun))
(unless after (setq after t))
(or (keymapp keymap)
(signal 'wrong-type-argument (list 'keymapp keymap)))
@@ -1155,6 +1176,9 @@ Subkeymaps may be modified but are not canonicalized."
(defun keyboard-translate (from to)
"Translate character FROM to TO on the current terminal.
+This is a legacy function; see `keymap-translate' for the
+recommended function to use instead.
+
This function creates a `keyboard-translate-table' if necessary
and then modifies one entry in it."
(or (char-table-p keyboard-translate-table)
@@ -1166,6 +1190,9 @@ and then modifies one entry in it."
(defun global-set-key (key command)
"Give KEY a global binding as COMMAND.
+This is a legacy function; see `keymap-global-set' for the
+recommended function to use instead.
+
COMMAND is the command definition to use; usually it is
a symbol naming an interactively-callable function.
KEY is a key sequence; noninteractively, it is a string or vector
@@ -1187,6 +1214,9 @@ that you make with this function."
(defun local-set-key (key command)
"Give KEY a local binding as COMMAND.
+This is a legacy function; see `keymap-local-set' for the
+recommended function to use instead.
+
COMMAND is the command definition to use; usually it is
a symbol naming an interactively-callable function.
KEY is a key sequence; noninteractively, it is a string or vector
@@ -1205,12 +1235,18 @@ cases is shared with all other buffers in the same major mode."
(defun global-unset-key (key)
"Remove global binding of KEY.
+This is a legacy function; see `keymap-global-unset' for the
+recommended function to use instead.
+
KEY is a string or vector representing a sequence of keystrokes."
(interactive "kUnset key globally: ")
(global-set-key key nil))
(defun local-unset-key (key)
"Remove local binding of KEY.
+This is a legacy function; see `keymap-local-unset' for the
+recommended function to use instead.
+
KEY is a string or vector representing a sequence of keystrokes."
(interactive "kUnset key locally: ")
(if (current-local-map)
@@ -1219,6 +1255,9 @@ KEY is a string or vector representing a sequence of keystrokes."
(defun local-key-binding (keys &optional accept-default)
"Return the binding for command KEYS in current local keymap only.
+This is a legacy function; see `keymap-local-binding' for the
+recommended function to use instead.
+
KEYS is a string or vector, a sequence of keystrokes.
The binding is probably a symbol with a function definition.
@@ -1230,6 +1269,9 @@ about this."
(defun global-key-binding (keys &optional accept-default)
"Return the binding for command KEYS in current global keymap only.
+This is a legacy function; see `keymap-global-binding' for the
+recommended function to use instead.
+
KEYS is a string or vector, a sequence of keystrokes.
The binding is probably a symbol with a function definition.
This function's return values are the same as those of `lookup-key'
@@ -1248,6 +1290,9 @@ about this."
(defun substitute-key-definition (olddef newdef keymap &optional oldmap prefix)
"Replace OLDDEF with NEWDEF for any keys in KEYMAP now defined as OLDDEF.
+This is a legacy function; see `keymap-substitute' for the
+recommended function to use instead.
+
In other words, OLDDEF is replaced with NEWDEF wherever it appears.
Alternatively, if optional fourth argument OLDMAP is specified, we redefine
in KEYMAP as NEWDEF those keys that are defined as OLDDEF in OLDMAP.
@@ -1509,18 +1554,22 @@ nil or (STRING . POSITION)'.
`posn-timestamp': The time the event occurred, in milliseconds.
For more information, see Info node `(elisp)Click Events'."
- (if (consp event) (nth 1 event)
- (or (posn-at-point)
- (list (selected-window) (point) '(0 . 0) 0))))
+ (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)))
(defun event-end (event)
"Return the ending position of EVENT.
EVENT should be a click, drag, or key press event.
See `event-start' for a description of the value returned."
- (if (consp event) (nth (if (consp (nth 2 event)) 2 1) event)
- (or (posn-at-point)
- (list (selected-window) (point) '(0 . 0) 0))))
+ (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)))
(defsubst event-click-count (event)
"Return the multi-click count of EVENT, a click or drag event.
@@ -1746,6 +1795,7 @@ be a list of the form returned by `event-start' and `event-end'."
(make-obsolete 'window-redisplay-end-trigger nil "23.1")
(make-obsolete 'set-window-redisplay-end-trigger nil "23.1")
(make-obsolete-variable 'operating-system-release nil "28.1")
+(make-obsolete-variable 'inhibit-changing-match-data 'save-match-data "29.1")
(make-obsolete 'run-window-configuration-change-hook nil "27.1")
@@ -1862,7 +1912,7 @@ performance impact when running `add-hook' and `remove-hook'."
(when (or (get hook 'hook--depth-alist) (not (zerop depth)))
;; Note: The main purpose of the above `when' test is to avoid running
;; this `setf' before `gv' is loaded during bootstrap.
- (push (cons function depth) (get hook 'hook--depth-alist)))
+ (setf (alist-get function (get hook 'hook--depth-alist) 0) depth))
(setq hook-value
(if (< 0 depth)
(append hook-value (list function))
@@ -2872,9 +2922,23 @@ This function is used by the `interactive' code letter `n'."
(defvar read-char-choice-use-read-key nil
"Prefer `read-key' when reading a character by `read-char-choice'.
-Otherwise, use the minibuffer.")
+Otherwise, use the minibuffer.
+
+When using the minibuffer, the user is less constrained, and can
+use the normal commands available in the minibuffer, and can, for
+instance, switch to another buffer, do things there, and then
+switch back again to the minibuffer before entering the
+character. This is not possible when using `read-key', but using
+`read-key' may be less confusing to some users.")
(defun read-char-choice (prompt chars &optional inhibit-keyboard-quit)
+ "Read and return one of CHARS, prompting for PROMPT.
+Any input that is not one of CHARS is ignored.
+
+By default, the minibuffer is used to read the key
+non-modally (see `read-char-from-minibuffer'). If
+`read-char-choice-use-read-key' is non-nil, the modal `read-key'
+function is used instead (see `read-char-choice-with-read-key')."
(if (not read-char-choice-use-read-key)
(read-char-from-minibuffer prompt chars)
(read-char-choice-with-read-key prompt chars inhibit-keyboard-quit)))
@@ -2884,7 +2948,7 @@ Otherwise, use the minibuffer.")
Any input that is not one of CHARS is ignored.
If optional argument INHIBIT-KEYBOARD-QUIT is non-nil, ignore
-keyboard-quit events while waiting for a valid input.
+`keyboard-quit' events while waiting for a valid input.
If you bind the variable `help-form' to a non-nil value
while calling this function, then pressing `help-char'
@@ -3015,6 +3079,7 @@ If there is a natural number at point, use it as default."
(set-keymap-parent map minibuffer-local-map)
(define-key map [remap self-insert-command] #'read-char-from-minibuffer-insert-char)
+ (define-key map [remap exit-minibuffer] #'read-char-from-minibuffer-insert-other)
(define-key map [remap recenter-top-bottom] #'minibuffer-recenter-top-bottom)
(define-key map [remap scroll-up-command] #'minibuffer-scroll-up-command)
@@ -3056,7 +3121,7 @@ Optional argument CHARS, if non-nil, should be a list of characters;
the function will ignore any input that is not one of CHARS.
Optional argument HISTORY, if non-nil, should be a symbol that
specifies the history list variable to use for navigating in input
-history using `M-p' and `M-n', with `RET' to select a character from
+history using \\`M-p' and \\`M-n', with \\`RET' to select a character from
history.
If you bind the variable `help-form' to a non-nil value
while calling this function, then pressing `help-char'
@@ -3132,9 +3197,10 @@ There is no need to explicitly add `help-char' to CHARS;
(define-key map [remap scroll-other-window] #'minibuffer-scroll-other-window)
(define-key map [remap scroll-other-window-down] #'minibuffer-scroll-other-window-down)
- (define-key map [escape] #'abort-recursive-edit)
- (dolist (symbol '(quit exit exit-prefix))
+ (define-key map [remap exit] #'y-or-n-p-insert-other)
+ (dolist (symbol '(exit-prefix quit))
(define-key map (vector 'remap symbol) #'abort-recursive-edit))
+ (define-key map [escape] #'abort-recursive-edit)
;; FIXME: try catch-all instead of explicit bindings:
;; (define-key map [remap t] #'y-or-n-p-insert-other)
@@ -3174,13 +3240,22 @@ Also discard all previous input in the minibuffer."
(defvar y-or-n-p-use-read-key nil
"Prefer `read-key' when answering a \"y or n\" question by `y-or-n-p'.
-Otherwise, use the minibuffer.")
+Otherwise, use the minibuffer.
+
+When using the minibuffer, the user is less constrained, and can
+use the normal commands available in the minibuffer, and can, for
+instance, switch to another buffer, do things there, and then
+switch back again to the minibuffer before entering the
+character. This is not possible when using `read-key', but using
+`read-key' may be less confusing to some users.")
(defun y-or-n-p (prompt)
"Ask user a \"y or n\" question.
Return t if answer is \"y\" and nil if it is \"n\".
-PROMPT is the string to display to ask the question. It should
-end in a space; `y-or-n-p' adds \"(y or n) \" to it.
+
+PROMPT is the string to display to ask the question; `y-or-n-p'
+adds \" (y or n) \" to it. It does not need to end in space, but
+if it does up to one space will be removed.
If you bind the variable `help-form' to a non-nil value
while calling this function, then pressing `help-char'
@@ -3203,7 +3278,12 @@ responses, perform the requested window recentering or scrolling
and ask again.
Under a windowing system a dialog box will be used if `last-nonmenu-event'
-is nil and `use-dialog-box' is non-nil."
+is nil and `use-dialog-box' is non-nil.
+
+By default, this function uses the minibuffer to read the key.
+If `y-or-n-p-use-read-key' is non-nil, `read-key' is used
+instead (which means that the user can't change buffers (and the
+like) while `y-or-n-p' is running)."
(let ((answer 'recenter)
(padded (lambda (prompt &optional dialog)
(let ((l (length prompt)))
@@ -3332,6 +3412,29 @@ user can undo the change normally."
(accept-change-group ,handle)
(cancel-change-group ,handle))))))
+(defmacro with-undo-amalgamate (&rest body)
+ "Like `progn' but perform BODY with amalgamated undo barriers.
+
+This allows multiple operations to be undone in a single step.
+When undo is disabled this behaves like `progn'."
+ (declare (indent 0) (debug t))
+ (let ((handle (make-symbol "--change-group-handle--")))
+ `(let ((,handle (prepare-change-group))
+ ;; Don't truncate any undo data in the middle of this,
+ ;; otherwise Emacs might truncate part of the resulting
+ ;; undo step: we want to mimic the behavior we'd get if the
+ ;; undo-boundaries were never added in the first place.
+ (undo-outer-limit nil)
+ (undo-limit most-positive-fixnum)
+ (undo-strong-limit most-positive-fixnum))
+ (unwind-protect
+ (progn
+ (activate-change-group ,handle)
+ ,@body)
+ (progn
+ (accept-change-group ,handle)
+ (undo-amalgamate-change-group ,handle))))))
+
(defun prepare-change-group (&optional buffer)
"Return a handle for the current buffer's state, for a change group.
If you specify BUFFER, make a handle for BUFFER's state instead.
@@ -3531,6 +3634,9 @@ If either NAME or VAL are specified, both should be specified."
(defvar suspend-resume-hook nil
"Normal hook run by `suspend-emacs', after Emacs is continued.")
+(defvar after-pdump-load-hook nil
+ "Normal hook run after loading the .pdmp file.")
+
(defvar temp-buffer-show-hook nil
"Normal hook run by `with-output-to-temp-buffer' after displaying the buffer.
When the hook runs, the temporary buffer is current, and the window it
@@ -3951,7 +4057,7 @@ BUFFER is the buffer (or buffer name) to associate with the process.
Process output goes at end of that buffer, unless you specify
an output stream or filter function to handle the output.
BUFFER may be also nil, meaning that this process is not associated
- with any buffer
+ with any buffer.
COMMAND is the shell command to run."
;; We used to use `exec' to replace the shell with the command,
;; but that failed to handle (...) and semicolon, etc.
@@ -4350,11 +4456,6 @@ is allowed once again. (Immediately, if `inhibit-quit' is nil.)"
;; that intends to handle the quit signal next time.
(eval '(ignore nil)))))
-;; Don't throw `throw-on-input' on those events by default.
-(setq while-no-input-ignore-events
- '(focus-in focus-out help-echo iconify-frame
- make-frame-visible selection-request))
-
(defmacro while-no-input (&rest body)
"Execute BODY only as long as there's no pending input.
If input arrives, that ends the execution of BODY,
@@ -4593,6 +4694,20 @@ MODES is as for `set-default-file-modes'."
,@body)
(set-default-file-modes ,umask)))))
+(defmacro with-existing-directory (&rest body)
+ "Execute BODY with `default-directory' bound to an existing directory.
+If `default-directory' is already an existing directory, it's not changed."
+ (declare (indent 0) (debug t))
+ `(let ((default-directory (seq-find (lambda (dir)
+ (and dir
+ (file-exists-p dir)))
+ (list default-directory
+ (expand-file-name "~/")
+ temporary-file-directory
+ (getenv "TMPDIR")
+ "/tmp/")
+ "/")))
+ ,@body))
;;; Matching and match data.
@@ -4620,13 +4735,24 @@ rather than your caller's match data."
'(set-match-data save-match-data-internal 'evaporate))))
(defun match-string (num &optional string)
- "Return string of text matched by last search.
-NUM specifies which parenthesized expression in the last regexp.
- Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
-Zero means the entire text matched by the whole regexp or whole string.
-STRING should be given if the last search was by `string-match' on STRING.
-If STRING is nil, the current buffer should be the same buffer
-the search/match was performed in."
+ "Return the string of text matched by the previous search or regexp operation.
+NUM specifies the number of the parenthesized sub-expression in the last
+regexp whose match to return. Zero means return the text matched by the
+entire regexp or the whole string.
+
+The return value is nil if NUMth pair didn't match anything, or if there
+were fewer than NUM sub-expressions in the regexp used in the search.
+
+STRING should be given if the last search was by `string-match'
+on STRING. If STRING is nil, the current buffer should be the
+same buffer as the one in which the search/match was performed.
+
+Note that many functions in Emacs modify the match data, so this
+function should be called \"close\" to the function that did the
+regexp search. In particular, saying (for instance)
+`M-: (looking-at \"[0-9]\") RET' followed by `M-: (match-string 0) RET'
+interactively is seldom meaningful, since the Emacs command loop
+may modify the match data."
(declare (side-effect-free t))
(if (match-beginning num)
(if string
@@ -4702,14 +4828,12 @@ wherever possible, since it is slow."
(defsubst looking-at-p (regexp)
"\
Same as `looking-at' except this function does not change the match data."
- (let ((inhibit-changing-match-data t))
- (looking-at regexp)))
+ (looking-at regexp t))
(defsubst string-match-p (regexp string &optional start)
"\
Same as `string-match' except this function does not change the match data."
- (let ((inhibit-changing-match-data t))
- (string-match regexp string start)))
+ (string-match regexp string start t))
(defun subregexp-context-p (regexp pos &optional start)
"Return non-nil if POS is in a normal subregexp context in REGEXP.
@@ -4892,25 +5016,25 @@ Unless optional argument INPLACE is non-nil, return a new string."
(aset newstr i tochar)))
newstr))
-(defun string-replace (fromstring tostring instring)
- "Replace FROMSTRING with TOSTRING in INSTRING each time it occurs."
+(defun string-replace (from-string to-string in-string)
+ "Replace FROM-STRING with TO-STRING in IN-STRING each time it occurs."
(declare (pure t) (side-effect-free t))
- (when (equal fromstring "")
+ (when (equal from-string "")
(signal 'wrong-length-argument '(0)))
(let ((start 0)
(result nil)
pos)
- (while (setq pos (string-search fromstring instring start))
+ (while (setq pos (string-search from-string in-string start))
(unless (= start pos)
- (push (substring instring start pos) result))
- (push tostring result)
- (setq start (+ pos (length fromstring))))
+ (push (substring in-string start pos) result))
+ (push to-string result)
+ (setq start (+ pos (length from-string))))
(if (null result)
;; No replacements were done, so just return the original string.
- instring
+ in-string
;; Get any remaining bit.
- (unless (= start (length instring))
- (push (substring instring start) result))
+ (unless (= start (length in-string))
+ (push (substring in-string start) result))
(apply #'concat (nreverse result)))))
(defun replace-regexp-in-string (regexp rep string &optional
@@ -5229,7 +5353,7 @@ that can be added.
If `buffer-invisibility-spec' isn't a list before calling this
function, `buffer-invisibility-spec' will afterwards be a list
with the value `(t ELEMENT)'. This means that if text exists
-that invisibility values that aren't either `t' or ELEMENT, that
+that invisibility values that aren't either t or ELEMENT, that
text will become visible."
(if (eq buffer-invisibility-spec t)
(setq buffer-invisibility-spec (list t)))
@@ -5239,8 +5363,8 @@ text will become visible."
(defun remove-from-invisibility-spec (element)
"Remove ELEMENT from `buffer-invisibility-spec'.
If `buffer-invisibility-spec' isn't a list before calling this
-function, it will be made into a list containing just `t' as the
-only list member. This means that if text exists with non-`t'
+function, it will be made into a list containing just t as the
+only list member. This means that if text exists with non-t
invisibility values, that text will become visible."
(setq buffer-invisibility-spec
(if (consp buffer-invisibility-spec)
@@ -5514,6 +5638,7 @@ If HOOKVAR is nil, `mail-send-hook' is used.
The properties used on SYMBOL are `composefunc', `sendfunc',
`abortfunc', and `hookvar'."
+ (declare (indent defun))
(put symbol 'composefunc composefunc)
(put symbol 'sendfunc sendfunc)
(put symbol 'abortfunc (or abortfunc #'kill-buffer))
@@ -5950,7 +6075,7 @@ print the reporter message followed by the word \"done\".
(,count 0)
(,list ,(cadr spec)))
(when (stringp ,prep)
- (setq ,prep (make-progress-reporter ,prep 0 (1- (length ,list)))))
+ (setq ,prep (make-progress-reporter ,prep 0 (length ,list))))
(dolist (,(car spec) ,list)
,@body
(progress-reporter-update ,prep (setq ,count (1+ ,count))))
@@ -6360,17 +6485,29 @@ seconds."
This is intended for very simple filling while bootstrapping
Emacs itself, and does not support all the customization options
of fill.el (for example `fill-region')."
- (if (< (string-width str) fill-column)
+ (if (< (length str) fill-column)
str
- (let ((fst (substring str 0 fill-column))
- (lst (substring str fill-column)))
- (if (string-match ".*\\( \\(.+\\)\\)$" fst)
- (setq fst (replace-match "\n\\2" nil nil fst 1)))
+ (let* ((limit (min fill-column (length str)))
+ (fst (substring str 0 limit))
+ (lst (substring str limit)))
+ (cond ((string-match "\\( \\)$" fst)
+ (setq fst (replace-match "\n" nil nil fst 1)))
+ ((string-match "^ \\(.*\\)" lst)
+ (setq fst (concat fst "\n"))
+ (setq lst (match-string 1 lst)))
+ ((string-match ".*\\( \\(.+\\)\\)$" fst)
+ (setq lst (concat (match-string 2 fst) lst))
+ (setq fst (replace-match "\n" nil nil fst 1))))
(concat fst (internal--fill-string-single-line lst)))))
(defun internal--format-docstring-line (string &rest objects)
- "Format a documentation string out of STRING and OBJECTS.
-This is intended for internal use only."
+ "Format a single line from a documentation string out of STRING and OBJECTS.
+Signal an error if STRING contains a newline.
+This is intended for internal use only. Avoid using this for the
+first line of a docstring; the first line should be a complete
+sentence (see Info node `(elisp) Documentation Tips')."
+ (when (string-match "\n" string)
+ (error "Unable to fill string containing newline: %S" string))
(internal--fill-string-single-line (apply #'format string objects)))
(defun json-available-p ()
@@ -6381,4 +6518,153 @@ This is intended for internal use only."
(:success t)
(json-unavailable nil))))
+(defun ensure-list (object)
+ "Return OBJECT as a list.
+If OBJECT is already a list, return OBJECT itself. If it's
+not a list, return a one-element list containing OBJECT."
+ (if (listp object)
+ object
+ (list object)))
+
+(defun define-keymap--compile (form &rest args)
+ ;; This compiler macro is only there for compile-time
+ ;; error-checking; it does not change the call in any way.
+ (while (and args
+ (keywordp (car args))
+ (not (eq (car args) :menu)))
+ (unless (memq (car args) '(:full :keymap :parent :suppress :name :prefix))
+ (byte-compile-warn "Invalid keyword: %s" (car args)))
+ (setq args (cdr args))
+ (when (null args)
+ (byte-compile-warn "Uneven number of keywords in %S" form))
+ (setq args (cdr args)))
+ ;; Bindings.
+ (while args
+ (let ((key (pop args)))
+ (when (and (stringp key) (not (key-valid-p key)))
+ (byte-compile-warn "Invalid `kbd' syntax: %S" key)))
+ (when (null args)
+ (byte-compile-warn "Uneven number of key bindings in %S" form))
+ (setq args (cdr args)))
+ form)
+
+(defun define-keymap (&rest definitions)
+ "Create a new keymap and define KEY/DEFEFINITION pairs as key sequences.
+The new keymap is returned.
+
+Options can be given as keywords before the KEY/DEFEFINITION
+pairs. Available keywords are:
+
+:full If non-nil, create a chartable alist (see `make-keymap').
+ If nil (i.e., the default), create a sparse keymap (see
+ `make-sparse-keymap').
+
+:suppress If non-nil, the keymap will be suppressed (see `suppress-keymap').
+ If `nodigits', treat digits like other chars.
+
+:parent If non-nil, this should be a keymap to use as the parent
+ (see `set-keymap-parent').
+
+:keymap If non-nil, instead of creating a new keymap, the given keymap
+ will be destructively modified instead.
+
+:name If non-nil, this should be a string to use as the menu for
+ the keymap in case you use it as a menu with `x-popup-menu'.
+
+:prefix If non-nil, this should be a symbol to be used as a prefix
+ command (see `define-prefix-command'). If this is the case,
+ this symbol is returned instead of the map itself.
+
+KEY/DEFINITION pairs are as KEY and DEF in `keymap-set'. KEY can
+also be the special symbol `:menu', in which case DEFINITION
+should be a MENU form as accepted by `easy-menu-define'.
+
+\(fn &key FULL PARENT SUPPRESS NAME PREFIX KEYMAP &rest [KEY DEFINITION]...)"
+ (declare (indent defun)
+ (compiler-macro define-keymap--compile))
+ (let (full suppress parent name prefix keymap)
+ ;; Handle keywords.
+ (while (and definitions
+ (keywordp (car definitions))
+ (not (eq (car definitions) :menu)))
+ (let ((keyword (pop definitions)))
+ (unless definitions
+ (error "Missing keyword value for %s" keyword))
+ (let ((value (pop definitions)))
+ (pcase keyword
+ (:full (setq full value))
+ (:keymap (setq keymap value))
+ (:parent (setq parent value))
+ (:suppress (setq suppress value))
+ (:name (setq name value))
+ (:prefix (setq prefix value))
+ (_ (error "Invalid keyword: %s" keyword))))))
+
+ (when (and prefix
+ (or full parent suppress keymap))
+ (error "A prefix keymap can't be defined with :full/:parent/:suppress/:keymap keywords"))
+
+ (when (and keymap full)
+ (error "Invalid combination: :keymap with :full"))
+
+ (let ((keymap (cond
+ (keymap keymap)
+ (prefix (define-prefix-command prefix nil name))
+ (full (make-keymap name))
+ (t (make-sparse-keymap name)))))
+ (when suppress
+ (suppress-keymap keymap (eq suppress 'nodigits)))
+ (when parent
+ (set-keymap-parent keymap parent))
+
+ ;; Do the bindings.
+ (while definitions
+ (let ((key (pop definitions)))
+ (unless definitions
+ (error "Uneven number of key/definition pairs"))
+ (let ((def (pop definitions)))
+ (if (eq key :menu)
+ (easy-menu-define nil keymap "" def)
+ (keymap-set keymap key def)))))
+ keymap)))
+
+(defmacro defvar-keymap (variable-name &rest defs)
+ "Define VARIABLE-NAME as a variable with a keymap definition.
+See `define-keymap' for an explanation of the keywords and KEY/DEFINITION.
+
+In addition to the keywords accepted by `define-keymap', this
+macro also accepts a `:doc' keyword, which (if present) is used
+as the variable documentation string.
+
+\(fn VARIABLE-NAME &key DOC FULL PARENT SUPPRESS NAME PREFIX KEYMAP &rest [KEY DEFINITION]...)"
+ (declare (indent 1))
+ (let ((opts nil)
+ doc)
+ (while (and defs
+ (keywordp (car defs))
+ (not (eq (car defs) :menu)))
+ (let ((keyword (pop defs)))
+ (unless defs
+ (error "Uneven number of keywords"))
+ (if (eq keyword :doc)
+ (setq doc (pop defs))
+ (push keyword opts)
+ (push (pop defs) opts))))
+ (unless (zerop (% (length defs) 2))
+ (error "Uneven number of key/definition pairs: %s" defs))
+ `(defvar ,variable-name
+ (define-keymap ,@(nreverse opts) ,@defs)
+ ,@(and doc (list doc)))))
+
+(defmacro with-delayed-message (args &rest body)
+ "Like `progn', but display MESSAGE if BODY takes longer than TIMEOUT seconds.
+The MESSAGE form will be evaluated immediately, but the resulting
+string will be displayed only if BODY takes longer than TIMEOUT seconds.
+
+\(fn (timeout message) &rest body)"
+ (declare (indent 1))
+ `(funcall-with-delayed-message ,(car args) ,(cadr args)
+ (lambda ()
+ ,@body)))
+
;;; subr.el ends here
diff --git a/lisp/svg.el b/lisp/svg.el
index 05accf4f13f..3c7f0550314 100644
--- a/lisp/svg.el
+++ b/lisp/svg.el
@@ -188,7 +188,7 @@ otherwise. IMAGE-TYPE should be a MIME image type, like
"Insert image placed at RELATIVE-FILENAME into the SVG structure.
RELATIVE-FILENAME will be searched in `file-name-directory' of the
image's `:base-uri' property. If `:base-uri' is not specified for the
-image, then embedding won't work. Embedding large images using this
+image, then embedding won't work. Embedding large images using this
function is much faster than `svg-embed'."
(svg--append
svg
diff --git a/lisp/t-mouse.el b/lisp/t-mouse.el
index ec36f543789..e9de31f50d7 100644
--- a/lisp/t-mouse.el
+++ b/lisp/t-mouse.el
@@ -25,7 +25,7 @@
;;; Commentary:
;; This package provides access to mouse event as reported by the gpm-Linux
-;; package. It tries to reproduce the functionality offered by Emacs under X.
+;; package. It tries to reproduce the functionality offered by Emacs under X.
;; The "gpm" server runs under Linux, so this package is rather
;; Linux-dependent.
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index 4ec1143128b..07aa0f2d569 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -27,10 +27,7 @@
;; bindings for the global tab bar.
;; The normal global binding for [tab-bar] (below) uses the value of
-;; `tab-bar-map' as the actual keymap to define the tab bar. Modes
-;; may either bind items under the [tab-bar] prefix key of the local
-;; map to add to the global bar or may set `tab-bar-map'
-;; buffer-locally to override it.
+;; `tab-bar-map' as the actual keymap to define the tab bar.
;;; Code:
@@ -92,10 +89,14 @@
(defcustom tab-bar-select-tab-modifiers '()
- "List of modifier keys for selecting a tab by its index digit.
+ "List of modifier keys for selecting tab-bar tabs by their numbers.
Possible modifier keys are `control', `meta', `shift', `hyper', `super' and
-`alt'. To help you to select a tab by its number, you can customize
-`tab-bar-tab-hints' that will show tab numbers alongside the tab name."
+`alt'. Pressing one of the modifiers in the list and a digit selects the
+tab whose number equals the digit (see `tab-bar-select-tab').
+The digit 9 selects the last (rightmost) tab (see `tab-last').
+The digit 0 selects the most recently visited tab (see `tab-recent').
+For easier selection of tabs by their numbers, consider customizing
+`tab-bar-tab-hints', which will show tab numbers alongside the tab name."
:type '(set :tag "Tab selection modifier keys"
(const control)
(const meta)
@@ -113,7 +114,6 @@ Possible modifier keys are `control', `meta', `shift', `hyper', `super' and
:group 'tab-bar
:version "27.1")
-
(defun tab-bar--define-keys ()
"Install key bindings for switching between tabs if the user has configured them."
(when tab-bar-select-tab-modifiers
@@ -161,7 +161,7 @@ Possible modifier keys are `control', `meta', `shift', `hyper', `super' and
(add-text-properties 0 (length tab-bar-new-button)
`(display (image :type xpm
:file "tabs/new.xpm"
- :margin (2 . 0)
+ :margin ,tab-bar-button-margin
:ascent center))
tab-bar-new-button))
@@ -171,7 +171,7 @@ Possible modifier keys are `control', `meta', `shift', `hyper', `super' and
(add-text-properties 0 (length tab-bar-close-button)
`(display (image :type xpm
:file "tabs/close.xpm"
- :margin (2 . 0)
+ :margin ,tab-bar-button-margin
:ascent center))
tab-bar-close-button)))
@@ -190,7 +190,7 @@ either 1 or 0 depending on the value of the customizable variable
(defun tab-bar--update-tab-bar-lines (&optional frames)
"Update the `tab-bar-lines' frame parameter in FRAMES.
If the optional parameter FRAMES is omitted, update only
-the currently selected frame. If it is `t', update all frames
+the currently selected frame. If it is t, update all frames
as well as the default for new frames. Otherwise FRAMES should be
a list of frames to update."
(let ((frame-lst (cond ((null frames)
@@ -224,32 +224,190 @@ a list of frames to update."
(tab-bar--define-keys)
(tab-bar--undefine-keys)))
-(defun tab-bar-handle-mouse (event)
- "Text-mode emulation of switching tabs on the tab bar.
-This command is used when you click the mouse in the tab bar
-on a console which has no window system but does have a mouse."
+
+;;; Key bindings
+
+(defun tab-bar--key-to-number (key)
+ "Return the tab number represented by KEY.
+If KEY is a symbol 'tab-N', where N is a tab number, the value is N.
+If KEY is \\='current-tab, the value is nil.
+For any other value of KEY, the value is t."
+ (cond
+ ((null key) t)
+ ((eq key 'current-tab) nil)
+ ((let ((key-name (format "%S" key)))
+ (when (string-prefix-p "tab-" key-name)
+ (string-to-number (string-replace "tab-" "" key-name)))))
+ (t t)))
+
+(defvar tab-bar--dragging-in-progress)
+
+(defun tab-bar--event-to-item (posn)
+ "This function extracts extra info from the mouse event at position POSN.
+It returns a list of the form (KEY KEY-BINDING CLOSE-P), where:
+ KEY is a symbol representing a tab, such as \\='tab-1 or \\='current-tab;
+ KEY-BINDING is the binding of KEY;
+ CLOSE-P is non-nil if the mouse event was a click on the close button \"x\",
+ nil otherwise."
+ (setq tab-bar--dragging-in-progress nil)
+ (if (posn-window posn)
+ (let ((caption (car (posn-string posn))))
+ (when caption
+ (get-text-property 0 'menu-item caption)))
+ ;; Text-mode emulation of switching tabs on the tab bar.
+ ;; This code is used when you click the mouse in the tab bar
+ ;; on a console which has no window system but does have a mouse.
+ (let* ((x-position (car (posn-x-y posn)))
+ (keymap (lookup-key (cons 'keymap (nreverse (current-active-maps))) [tab-bar]))
+ (column 0))
+ (when x-position
+ (catch 'done
+ (map-keymap
+ (lambda (key binding)
+ (when (eq (car-safe binding) 'menu-item)
+ (when (> (+ column (length (nth 1 binding))) x-position)
+ (throw 'done (list key (nth 2 binding)
+ (get-text-property
+ (- x-position column)
+ 'close-tab (nth 1 binding)))))
+ (setq column (+ column (length (nth 1 binding))))))
+ keymap))))))
+
+(defun tab-bar-mouse-down-1 (event)
+ "Select the tab at mouse click, or add a new tab on the tab bar.
+Whether this command adds a new tab or selects an existing tab
+depends on whether the click is on the \"+\" button or on an
+existing tab."
+ (interactive "e")
+ (let* ((item (tab-bar--event-to-item (event-start event)))
+ (tab-number (tab-bar--key-to-number (nth 0 item))))
+ (setq tab-bar--dragging-in-progress t)
+ ;; Don't close the tab when clicked on the close button. Also
+ ;; don't add new tab on down-mouse. Let `tab-bar-mouse-1' do this.
+ (unless (or (memq (car item) '(add-tab history-back history-forward))
+ (nth 2 item))
+ (if (functionp (nth 1 item))
+ (call-interactively (nth 1 item))
+ (unless (eq tab-number t)
+ (tab-bar-select-tab tab-number))))))
+
+(defun tab-bar-mouse-1 (event)
+ "Close the tab whose \"x\" close button you click.
+See also `tab-bar-mouse-close-tab', which closes the tab
+regardless of where you click on it. Also add a new tab."
+ (interactive "e")
+ (let* ((item (tab-bar--event-to-item (event-start event)))
+ (tab-number (tab-bar--key-to-number (nth 0 item))))
+ (cond
+ ((and (memq (car item) '(add-tab history-back history-forward))
+ (functionp (nth 1 item)))
+ (call-interactively (nth 1 item)))
+ ((and (nth 2 item) (not (eq tab-number t)))
+ (tab-bar-close-tab tab-number)))))
+
+(defun tab-bar-mouse-close-tab (event)
+ "Close the tab you click on.
+This is in contrast with `tab-bar-mouse-1' that closes a tab
+only when you click on its \"x\" close button."
+ (interactive "e")
+ (let* ((item (tab-bar--event-to-item (event-start event)))
+ (tab-number (tab-bar--key-to-number (nth 0 item))))
+ (unless (eq tab-number t)
+ (tab-bar-close-tab tab-number))))
+
+(defun tab-bar-mouse-context-menu (event)
+ "Pop up the context menu for the tab on which you click."
+ (interactive "e")
+ (let* ((item (tab-bar--event-to-item (event-start event)))
+ (tab-number (tab-bar--key-to-number (nth 0 item)))
+ (menu (make-sparse-keymap (propertize "Context Menu" 'hide t))))
+
+ (cond
+ ((eq tab-number t)
+ (define-key-after menu [new-tab]
+ '(menu-item "New tab" tab-bar-new-tab
+ :help "Create a new tab"))
+ (when tab-bar-closed-tabs
+ (define-key-after menu [undo-close]
+ '(menu-item "Reopen closed tab" tab-bar-undo-close-tab
+ :help "Undo closing the tab"))))
+
+ (t
+ (define-key-after menu [duplicate-tab]
+ `(menu-item "Duplicate" (lambda () (interactive)
+ (tab-bar-duplicate-tab
+ nil ,tab-number))
+ :help "Clone the tab"))
+ (define-key-after menu [detach-tab]
+ `(menu-item "Detach" (lambda () (interactive)
+ (tab-bar-detach-tab
+ ,tab-number))
+ :help "Move the tab to new frame"))
+ (define-key-after menu [close]
+ `(menu-item "Close" (lambda () (interactive)
+ (tab-bar-close-tab ,tab-number))
+ :help "Close the tab"))
+ (define-key-after menu [close-other]
+ `(menu-item "Close other tabs"
+ (lambda () (interactive)
+ (tab-bar-close-other-tabs ,tab-number))
+ :help "Close all other tabs"))))
+
+ (popup-menu menu event)))
+
+(defun tab-bar-mouse-move-tab (event)
+ "Move a tab to a different position on the tab bar.
+This command should be bound to a drag event. It moves the tab
+at the mouse-down event to the position at mouse-up event."
(interactive "e")
- (let* ((x-position (car (posn-x-y (event-start event))))
- (keymap (lookup-key (cons 'keymap (nreverse (current-active-maps))) [tab-bar]))
- (column 0))
- (when x-position
- (unless (catch 'done
- (map-keymap
- (lambda (key binding)
- (when (eq (car-safe binding) 'menu-item)
- (when (> (+ column (length (nth 1 binding))) x-position)
- (if (get-text-property (- x-position column) 'close-tab (nth 1 binding))
- (let* ((close-key (vector (intern (format "C-%s" key))))
- (close-def (lookup-key keymap close-key)))
- (when close-def
- (call-interactively close-def)))
- (call-interactively (nth 2 binding)))
- (throw 'done t))
- (setq column (+ column (length (nth 1 binding))))))
- keymap))
- ;; Clicking anywhere outside existing tabs will add a new tab
- (tab-bar-new-tab)))))
+ (setq tab-bar--dragging-in-progress nil)
+ (let ((from (tab-bar--key-to-number
+ (nth 0 (tab-bar--event-to-item
+ (event-start event)))))
+ (to (tab-bar--key-to-number
+ (nth 0 (tab-bar--event-to-item
+ (event-end event))))))
+ (unless (or (eq from to) (eq from t) (eq to t))
+ (tab-bar-move-tab-to
+ (if (null to) (1+ (tab-bar--current-tab-index)) to) from))))
+
+(defvar tab-bar-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [down-mouse-1] 'tab-bar-mouse-down-1)
+ (define-key map [drag-mouse-1] 'tab-bar-mouse-move-tab)
+ (define-key map [mouse-1] 'tab-bar-mouse-1)
+ (define-key map [down-mouse-2] 'tab-bar-mouse-close-tab)
+ (define-key map [mouse-2] 'ignore)
+ (define-key map [down-mouse-3] 'tab-bar-mouse-context-menu)
+
+ (define-key map [mouse-4] 'tab-previous)
+ (define-key map [mouse-5] 'tab-next)
+ (define-key map [wheel-up] 'tab-previous)
+ (define-key map [wheel-down] 'tab-next)
+ (define-key map [wheel-left] 'tab-previous)
+ (define-key map [wheel-right] 'tab-next)
+
+ (define-key map [S-mouse-4] 'tab-bar-move-tab-backward)
+ (define-key map [S-mouse-5] 'tab-bar-move-tab)
+ (define-key map [S-wheel-up] 'tab-bar-move-tab-backward)
+ (define-key map [S-wheel-down] 'tab-bar-move-tab)
+ (define-key map [S-wheel-left] 'tab-bar-move-tab-backward)
+ (define-key map [S-wheel-right] 'tab-bar-move-tab)
+
+ map)
+ "Keymap for the commands used on the tab bar.")
+
+(global-set-key [tab-bar]
+ `(menu-item ,(purecopy "tab bar") ignore
+ :filter tab-bar-make-keymap))
+(defun tab-bar-make-keymap (&optional _ignore)
+ "Generate an actual keymap from `tab-bar-map'.
+Its main job is to show tabs in the tab bar
+and to bind mouse events to the commands."
+ (tab-bar-make-keymap-1))
+
+
(defun toggle-tab-bar-mode-from-frame (&optional arg)
"Toggle tab bar on or off, based on the status of the current frame.
Used in the Show/Hide menu, to have the toggle reflect the current frame.
@@ -260,10 +418,12 @@ See `tab-bar-mode' for more information."
(tab-bar-mode arg)))
(defun toggle-frame-tab-bar (&optional frame)
- "Toggle tab bar of FRAME.
-This is useful when you want to enable the tab bar individually
+ "Toggle tab bar of the selected frame.
+When calling from Lisp, use the optional argument FRAME to toggle
+the tab bar on that frame.
+This is useful if you want to enable the tab bar individually
on each new frame when the global `tab-bar-mode' is disabled,
-or when you want to disable the tab bar individually on each
+or if you want to disable the tab bar individually on each
new frame when the global `tab-bar-mode' is enabled, by using
(add-hook 'after-make-frame-functions 'toggle-frame-tab-bar)"
@@ -273,32 +433,20 @@ new frame when the global `tab-bar-mode' is enabled, by using
(set-frame-parameter frame 'tab-bar-lines-keep-state
(not (frame-parameter frame 'tab-bar-lines-keep-state))))
-(defvar tab-bar-map (make-sparse-keymap)
- "Keymap for the tab bar.
-Define this locally to override the global tab bar.")
-
-(global-set-key [tab-bar]
- `(menu-item ,(purecopy "tab bar") ignore
- :filter tab-bar-make-keymap))
-
-(defconst tab-bar-keymap-cache (make-hash-table :weakness t :test 'equal))
-
-(defun tab-bar-make-keymap (&optional _ignore)
- "Generate an actual keymap from `tab-bar-map'.
-Its main job is to show tabs in the tab bar."
- (if (= 1 (length tab-bar-map))
- (tab-bar-make-keymap-1)
- (let ((key (cons (frame-terminal) tab-bar-map)))
- (or (gethash key tab-bar-keymap-cache)
- (puthash key tab-bar-map tab-bar-keymap-cache)))))
-
(defcustom tab-bar-show t
"Defines when to show the tab bar.
-If t, enable `tab-bar-mode' automatically on using the commands that
-create new window configurations (e.g. `tab-new').
-If the value is `1', then hide the tab bar when it has only one tab,
-and show it again once more tabs are created.
+If t, the default, enable `tab-bar-mode' automatically upon using
+the commands that create new window configurations (e.g., `tab-new').
+If a non-negative integer, show the tab bar only if the number of
+the tabs exceeds the value of this variable. In particular,
+if the value is 1, hide the tab bar when it has only one tab, and
+show it again once more tabs are created. A value that is a
+non-negative integer also makes the tab bar appearance be different
+on different frames: the tab bar can be shown on some frames and
+hidden on others, depending on how many tab-bar tabs are on that
+frame, and whether that number is greater than the numerical value
+of this variable.
If nil, always keep the tab bar hidden. In this case it's still
possible to use persistent named window configurations by relying on
keyboard commands `tab-new', `tab-close', `tab-next', `tab-switcher', etc.
@@ -415,6 +563,7 @@ and `tab-bar-select-tab-modifiers'."
"String that delimits tabs.")
(defun tab-bar-separator ()
+ "Separator between tabs."
(or tab-bar-separator (if window-system " " "|")))
@@ -559,14 +708,23 @@ the formatted tab name to display in the tab bar."
"Template for displaying tab bar items.
Every item in the list is a function that returns
a string, or a list of menu-item elements, or nil.
-When you add more items `tab-bar-format-align-right' and
-`tab-bar-format-global' to the end, then after enabling
-`display-time-mode' (or any other mode that uses `global-mode-string')
-it will display time aligned to the right on the tab bar instead of
-the mode line. Replacing `tab-bar-format-tabs' with
+Adding a function to the list causes the tab bar to show
+that string, or display a tab button which, when clicked,
+will invoke the command that is the binding of the menu item.
+The menu-item binding of nil will produce a tab clicking
+on which will select that tab. The menu-item's title is
+displayed as the label of the tab.
+If a function returns nil, it doesn't directly affect the
+tab bar appearance, but can do that by some side-effect.
+If the list ends with `tab-bar-format-align-right' and
+`tab-bar-format-global', then after enabling `display-time-mode'
+(or any other mode that uses `global-mode-string'),
+it will display time aligned to the right on the tab bar instead
+of the mode line. Replacing `tab-bar-format-tabs' with
`tab-bar-format-tabs-groups' will group tabs on the tab bar."
:type 'hook
- :options '(tab-bar-format-history
+ :options '(tab-bar-format-menu-bar
+ tab-bar-format-history
tab-bar-format-tabs
tab-bar-format-tabs-groups
tab-bar-separator
@@ -580,8 +738,27 @@ the mode line. Replacing `tab-bar-format-tabs' with
:group 'tab-bar
:version "28.1")
+(defun tab-bar-menu-bar (event)
+ "Pop up the same menu as displayed by the menu bar.
+Used by `tab-bar-format-menu-bar'."
+ (interactive "e")
+ (let ((menu (make-sparse-keymap (propertize "Menu Bar" 'hide t))))
+ (run-hooks 'activate-menubar-hook 'menu-bar-update-hook)
+ (map-keymap (lambda (key binding)
+ (when (consp binding)
+ (define-key-after menu (vector key)
+ (copy-sequence binding))))
+ (menu-bar-keymap))
+ (popup-menu menu event)))
+
+(defun tab-bar-format-menu-bar ()
+ "Produce the Menu button for the tab bar that shows the menu bar."
+ `((menu-bar menu-item (propertize "Menu" 'face 'tab-bar-tab-inactive)
+ tab-bar-menu-bar :help "Menu Bar")))
+
(defun tab-bar-format-history ()
- "Show back and forward buttons when `tab-bar-history-mode' is enabled.
+ "Produce back and forward buttons for the tab bar.
+These buttons will be shown when `tab-bar-history-mode' is enabled.
You can hide these buttons by customizing `tab-bar-format' and removing
`tab-bar-format-history' from it."
(when tab-bar-history-mode
@@ -595,6 +772,7 @@ You can hide these buttons by customizing `tab-bar-format' and removing
:help "Click to go forward in tab history"))))
(defun tab-bar--format-tab (tab i)
+ "Format TAB using its index I and return the result as a keymap."
(append
`((,(intern (format "sep-%i" i)) menu-item ,(tab-bar-separator) ignore))
(cond
@@ -608,21 +786,15 @@ You can hide these buttons by customizing `tab-bar-format' and removing
`((,(intern (format "tab-%i" i))
menu-item
,(funcall tab-bar-tab-name-format-function tab i)
- ,(or
- (alist-get 'binding tab)
- `(lambda ()
- (interactive)
- (tab-bar-select-tab ,i)))
+ ,(alist-get 'binding tab)
:help "Click to visit tab"))))
- `((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i)))
- menu-item ""
- ,(or
- (alist-get 'close-binding tab)
- `(lambda ()
- (interactive)
- (tab-bar-close-tab ,i)))))))
+ (when (alist-get 'close-binding tab)
+ `((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i)))
+ menu-item ""
+ ,(alist-get 'close-binding tab))))))
(defun tab-bar-format-tabs ()
+ "Produce all the tabs for the tab bar."
(let ((i 0))
(mapcan
(lambda (tab)
@@ -676,6 +848,9 @@ Function gets one argument: a tab."
(tab-bar-tab-face-default tab)))
(defun tab-bar--format-tab-group (tab i &optional current-p)
+ "Format TAB as a tab that represents a group of tabs.
+The argument I is the tab index, and CURRENT-P is non-nil
+when the tab is current. Return the result as a keymap."
(append
`((,(intern (format "sep-%i" i)) menu-item ,(tab-bar-separator) ignore))
`((,(intern (format "group-%i" i))
@@ -693,6 +868,7 @@ Function gets one argument: a tab."
:help "Click to visit group"))))
(defun tab-bar-format-tabs-groups ()
+ "Produce tabs for the tab bar grouped according to their groups."
(let* ((tabs (funcall tab-bar-tabs-function))
(current-group (funcall tab-bar-tab-group-function
(tab-bar--current-tab-find tabs)))
@@ -721,6 +897,7 @@ Function gets one argument: a tab."
tabs)))
(defun tab-bar-format-add-tab ()
+ "Button to add a new tab."
(when (and tab-bar-new-button-show tab-bar-new-button)
`((add-tab menu-item ,tab-bar-new-button tab-bar-new-tab
:help "New tab"))))
@@ -735,7 +912,7 @@ Function gets one argument: a tab."
`((align-right menu-item ,str ignore))))
(defun tab-bar-format-global ()
- "Format `global-mode-string' to display it in the tab bar.
+ "Produce display of `global-mode-string' in the tab bar.
When `tab-bar-format-global' is added to `tab-bar-format'
(possibly appended after `tab-bar-format-align-right'),
then modes that display information on the mode line
@@ -760,9 +937,7 @@ on the tab bar instead."
(defun tab-bar-make-keymap-1 ()
"Generate an actual keymap from `tab-bar-map', without caching."
- (append
- '(keymap (mouse-1 . tab-bar-handle-mouse))
- (tab-bar-format-list tab-bar-format)))
+ (append tab-bar-map (tab-bar-format-list tab-bar-format)))
;; Some window-configuration parameters don't need to be persistent.
@@ -776,7 +951,8 @@ on the tab bar instead."
(if (consp current)
(seq-reduce (lambda (current param)
(assq-delete-all param current))
- '(wc wc-point wc-bl wc-bbl wc-history-back wc-history-forward)
+ '(wc wc-point wc-bl wc-bbl
+ wc-history-back wc-history-forward)
(copy-sequence current))
current))
current)
@@ -785,11 +961,14 @@ on the tab bar instead."
(push '(tabs . frameset-filter-tabs) frameset-filter-alist)
(defun tab-bar--tab (&optional frame)
+ "Make a new tab data structure that can be added to tabs on the FRAME."
(let* ((tab (tab-bar--current-tab-find nil frame))
(tab-explicit-name (alist-get 'explicit-name tab))
(tab-group (alist-get 'group tab))
- (bl (seq-filter #'buffer-live-p (frame-parameter frame 'buffer-list)))
- (bbl (seq-filter #'buffer-live-p (frame-parameter frame 'buried-buffer-list))))
+ (bl (seq-filter #'buffer-live-p (frame-parameter
+ frame 'buffer-list)))
+ (bbl (seq-filter #'buffer-live-p (frame-parameter
+ frame 'buried-buffer-list))))
`(tab
(name . ,(if tab-explicit-name
(alist-get 'name tab)
@@ -803,16 +982,30 @@ on the tab bar instead."
(wc-point . ,(point-marker))
(wc-bl . ,bl)
(wc-bbl . ,bbl)
- (wc-history-back . ,(gethash (or frame (selected-frame)) tab-bar-history-back))
- (wc-history-forward . ,(gethash (or frame (selected-frame)) tab-bar-history-forward)))))
+ ,@(when tab-bar-history-mode
+ `((wc-history-back . ,(gethash (or frame (selected-frame))
+ tab-bar-history-back))
+ (wc-history-forward . ,(gethash (or frame (selected-frame))
+ tab-bar-history-forward))))
+ ;; Copy other possible parameters
+ ,@(mapcan (lambda (param)
+ (unless (memq (car param)
+ '(name explicit-name group time
+ ws wc wc-point wc-bl wc-bbl
+ wc-history-back wc-history-forward))
+ (list param)))
+ (cdr tab)))))
(defun tab-bar--current-tab (&optional tab frame)
+ "Make the current tab data structure from TAB on FRAME."
(tab-bar--current-tab-make (or tab (tab-bar--current-tab-find nil frame))))
(defun tab-bar--current-tab-make (&optional tab)
- ;; `tab' here is an argument meaning "use tab as template". This is
- ;; necessary when switching tabs, otherwise the destination tab
- ;; inherits the current tab's `explicit-name' parameter.
+ "Make the current tab data structure from TAB.
+TAB here is an argument meaning \"use tab as template\",
+i.e. the tab is created using data from TAB. This is
+necessary when switching tabs, otherwise the destination tab
+inherits the current tab's `explicit-name' parameter."
(let* ((tab-explicit-name (alist-get 'explicit-name tab))
(tab-group (if tab
(alist-get 'group tab)
@@ -824,30 +1017,44 @@ on the tab bar instead."
(alist-get 'name tab)
(funcall tab-bar-tab-name-function)))
(explicit-name . ,tab-explicit-name)
- ,@(if tab-group `((group . ,tab-group))))))
+ ,@(if tab-group `((group . ,tab-group)))
+ ;; Copy other possible parameters
+ ,@(mapcan (lambda (param)
+ (unless (memq (car param)
+ '(name explicit-name group time
+ ws wc wc-point wc-bl wc-bbl
+ wc-history-back wc-history-forward))
+ (list param)))
+ (cdr tab)))))
(defun tab-bar--current-tab-find (&optional tabs frame)
+ ;; Find the current tab as a pointer to its data structure.
(assq 'current-tab (or tabs (funcall tab-bar-tabs-function frame))))
(defun tab-bar--current-tab-index (&optional tabs frame)
+ ;; Return the index of the current tab.
(seq-position (or tabs (funcall tab-bar-tabs-function frame))
'current-tab (lambda (a b) (eq (car a) b))))
(defun tab-bar--tab-index (tab &optional tabs frame)
+ ;; Return the index of TAB.
(seq-position (or tabs (funcall tab-bar-tabs-function frame))
tab #'eq))
(defun tab-bar--tab-index-by-name (name &optional tabs frame)
+ ;; Return the index of TAB by the its NAME.
(seq-position (or tabs (funcall tab-bar-tabs-function frame))
name (lambda (a b) (equal (alist-get 'name a) b))))
(defun tab-bar--tab-index-recent (nth &optional tabs frame)
+ ;; Return the index of NTH recent tab.
(let* ((tabs (or tabs (funcall tab-bar-tabs-function frame)))
(sorted-tabs (tab-bar--tabs-recent tabs frame))
(tab (nth (1- nth) sorted-tabs)))
(tab-bar--tab-index tab tabs)))
(defun tab-bar--tabs-recent (&optional tabs frame)
+ ;; Return the list of tabs sorted by recency.
(let* ((tabs (or tabs (funcall tab-bar-tabs-function frame))))
(seq-sort-by (lambda (tab) (alist-get 'time tab)) #'>
(seq-remove (lambda (tab)
@@ -855,23 +1062,29 @@ on the tab bar instead."
tabs))))
-(defun tab-bar-select-tab (&optional arg)
- "Switch to the tab by its absolute position ARG in the tab bar.
-When this command is bound to a numeric key (with a prefix or modifier key
+(defun tab-bar-select-tab (&optional tab-number)
+ "Switch to the tab by its absolute position TAB-NUMBER in the tab bar.
+When this command is bound to a numeric key (with a key prefix or modifier key
using `tab-bar-select-tab-modifiers'), calling it without an argument
will translate its bound numeric key to the numeric argument.
-ARG counts from 1. Negative ARG counts tabs from the end of the tab bar."
+Also the prefix argument TAB-NUMBER can be used to override
+the numeric key, so it takes precedence over the bound digit key.
+For example, `<MODIFIER>-2' will select the second tab, but `C-u 15
+<MODIFIER>-2' will select the 15th tab. TAB-NUMBER counts from 1.
+Negative TAB-NUMBER counts tabs from the end of the tab bar."
(interactive "P")
- (unless (integerp arg)
+ (unless (integerp tab-number)
(let ((key (event-basic-type last-command-event)))
- (setq arg (if (and (characterp key) (>= key ?1) (<= key ?9))
- (- key ?0)
- 1))))
+ (setq tab-number (if (and (characterp key) (>= key ?1) (<= key ?9))
+ (- key ?0)
+ 0))))
(let* ((tabs (funcall tab-bar-tabs-function))
(from-index (tab-bar--current-tab-index tabs))
- (to-index (if (< arg 0) (+ (length tabs) (1+ arg)) arg))
- (to-index (1- (max 1 (min to-index (length tabs))))))
+ (to-number (cond ((< tab-number 0) (+ (length tabs) (1+ tab-number)))
+ ((zerop tab-number) (1+ from-index))
+ (t tab-number)))
+ (to-index (1- (max 1 (min to-number (length tabs))))))
(unless (eq from-index to-index)
(let* ((from-tab (tab-bar--tab))
@@ -886,7 +1099,11 @@ ARG counts from 1. Negative ARG counts tabs from the end of the tab bar."
;; its value of window-configuration is unreadable,
;; so restore its saved window-state.
(cond
- ((window-configuration-p wc)
+ ((and (window-configuration-p wc)
+ ;; Check for such cases as cloning a frame with tabs.
+ ;; When tabs were cloned to another frame, then fall back
+ ;; to using `window-state-put' below.
+ (eq (window-configuration-frame wc) (selected-frame)))
(let ((wc-point (alist-get 'wc-point to-tab))
(wc-bl (seq-filter #'buffer-live-p (alist-get 'wc-bl to-tab)))
(wc-bbl (seq-filter #'buffer-live-p (alist-get 'wc-bbl to-tab)))
@@ -910,19 +1127,21 @@ ARG counts from 1. Negative ARG counts tabs from the end of the tab bar."
(when wc-bl (set-frame-parameter nil 'buffer-list wc-bl))
(when wc-bbl (set-frame-parameter nil 'buried-buffer-list wc-bbl))
- (puthash (selected-frame)
- (and (window-configuration-p (alist-get 'wc (car wc-history-back)))
- wc-history-back)
- tab-bar-history-back)
- (puthash (selected-frame)
- (and (window-configuration-p (alist-get 'wc (car wc-history-forward)))
- wc-history-forward)
- tab-bar-history-forward)))
+ (when tab-bar-history-mode
+ (puthash (selected-frame)
+ (and (window-configuration-p (alist-get 'wc (car wc-history-back)))
+ wc-history-back)
+ tab-bar-history-back)
+ (puthash (selected-frame)
+ (and (window-configuration-p (alist-get 'wc (car wc-history-forward)))
+ wc-history-forward)
+ tab-bar-history-forward))))
(ws
(window-state-put ws nil 'safe)))
- (setq tab-bar-history-omit t)
+ (when tab-bar-history-mode
+ (setq tab-bar-history-omit t))
(when from-index
(setf (nth from-index tabs) from-tab))
@@ -934,7 +1153,8 @@ ARG counts from 1. Negative ARG counts tabs from the end of the tab bar."
(force-mode-line-update))))
(defun tab-bar-switch-to-next-tab (&optional arg)
- "Switch to ARGth next tab."
+ "Switch to ARGth next tab.
+Interactively, ARG is the prefix numeric argument and defaults to 1."
(interactive "p")
(unless (integerp arg)
(setq arg 1))
@@ -944,20 +1164,25 @@ ARG counts from 1. Negative ARG counts tabs from the end of the tab bar."
(tab-bar-select-tab (1+ to-index))))
(defun tab-bar-switch-to-prev-tab (&optional arg)
- "Switch to ARGth previous tab."
+ "Switch to ARGth previous tab.
+Interactively, ARG is the prefix numeric argument and defaults to 1."
(interactive "p")
(unless (integerp arg)
(setq arg 1))
(tab-bar-switch-to-next-tab (- arg)))
(defun tab-bar-switch-to-last-tab (&optional arg)
- "Switch to the last tab or ARGth tab from the end of the tab bar."
+ "Switch to the last tab or ARGth tab from the end of the tab bar.
+Interactively, ARG is the prefix numeric argument; it defaults to 1,
+which means the last tab on the tab bar. For example, `C-u 2
+<MODIFIER>-9' selects the tab before the last tab."
(interactive "p")
(tab-bar-select-tab (- (length (funcall tab-bar-tabs-function))
- (1- (or arg 1)))))
+ (1- (abs (or arg 1))))))
(defun tab-bar-switch-to-recent-tab (&optional arg)
- "Switch to ARGth most recently visited tab."
+ "Switch to ARGth most recently visited tab.
+Interactively, ARG is the prefix numeric argument and defaults to 1."
(interactive "p")
(unless (integerp arg)
(setq arg 1))
@@ -971,7 +1196,9 @@ ARG counts from 1. Negative ARG counts tabs from the end of the tab bar."
Default values are tab names sorted by recency, so you can use \
\\<minibuffer-local-map>\\[next-history-element]
to get the name of the most recently visited tab, the second
-most recent, and so on."
+most recent, and so on.
+When the tab with that NAME doesn't exist, create a new tab
+and rename it to NAME."
(interactive
(let* ((recent-tabs (mapcar (lambda (tab)
(alist-get 'name tab))
@@ -979,25 +1206,29 @@ most recent, and so on."
(list (completing-read (format-prompt "Switch to tab by name"
(car recent-tabs))
recent-tabs nil nil nil nil recent-tabs))))
- (tab-bar-select-tab (1+ (or (tab-bar--tab-index-by-name name) 0))))
+ (let ((tab-index (tab-bar--tab-index-by-name name)))
+ (if tab-index
+ (tab-bar-select-tab (1+ tab-index))
+ (tab-bar-new-tab)
+ (tab-bar-rename-tab name))))
(defalias 'tab-bar-select-tab-by-name 'tab-bar-switch-to-tab)
-(defun tab-bar-move-tab-to (to-index &optional from-index)
- "Move tab from FROM-INDEX position to new position at TO-INDEX.
-FROM-INDEX defaults to the current tab index.
-FROM-INDEX and TO-INDEX count from 1.
-Negative TO-INDEX counts tabs from the end of the tab bar.
+(defun tab-bar-move-tab-to (to-number &optional from-number)
+ "Move tab from FROM-NUMBER position to new position at TO-NUMBER.
+FROM-NUMBER defaults to the current tab number.
+FROM-NUMBER and TO-NUMBER count from 1.
+Negative TO-NUMBER counts tabs from the end of the tab bar.
Argument addressing is absolute in contrast to `tab-bar-move-tab'
where argument addressing is relative."
(interactive "P")
(let* ((tabs (funcall tab-bar-tabs-function))
- (from-index (or from-index (1+ (tab-bar--current-tab-index tabs))))
- (from-tab (nth (1- from-index) tabs))
- (to-index (if to-index (prefix-numeric-value to-index) 1))
- (to-index (if (< to-index 0) (+ (length tabs) (1+ to-index)) to-index))
- (to-index (max 0 (min (1- to-index) (1- (length tabs))))))
+ (from-number (or from-number (1+ (tab-bar--current-tab-index tabs))))
+ (from-tab (nth (1- from-number) tabs))
+ (to-number (if to-number (prefix-numeric-value to-number) 1))
+ (to-number (if (< to-number 0) (+ (length tabs) (1+ to-number)) to-number))
+ (to-index (max 0 (min (1- to-number) (1- (length tabs))))))
(setq tabs (delq from-tab tabs))
(cl-pushnew from-tab (nthcdr to-index tabs))
(tab-bar-tabs-set tabs)
@@ -1005,8 +1236,9 @@ where argument addressing is relative."
(defun tab-bar-move-tab (&optional arg)
"Move the current tab ARG positions to the right.
-If a negative ARG, move the current tab ARG positions to the left.
-Argument addressing is relative in contrast to `tab-bar-move-tab-to'
+Interactively, ARG is the prefix numeric argument and defaults to 1.
+If ARG is negative, move the current tab ARG positions to the left.
+Argument addressing is relative in contrast to `tab-bar-move-tab-to',
where argument addressing is absolute."
(interactive "p")
(let* ((tabs (funcall tab-bar-tabs-function))
@@ -1014,13 +1246,21 @@ where argument addressing is absolute."
(to-index (mod (+ from-index arg) (length tabs))))
(tab-bar-move-tab-to (1+ to-index) (1+ from-index))))
-(defun tab-bar-move-tab-to-frame (arg &optional from-frame from-index to-frame to-index)
- "Move tab from FROM-INDEX position to new position at TO-INDEX.
-FROM-INDEX defaults to the current tab index.
-FROM-INDEX and TO-INDEX count from 1.
+(defun tab-bar-move-tab-backward (&optional arg)
+ "Move the current tab ARG positions to the left.
+Interactively, ARG is the prefix numeric argument and defaults to 1.
+Like `tab-bar-move-tab', but moves in the opposite direction."
+ (interactive "p")
+ (tab-bar-move-tab (- (or arg 1))))
+
+(defun tab-bar-move-tab-to-frame (arg &optional from-frame from-number to-frame to-number)
+ "Move tab from FROM-NUMBER position to new position at TO-NUMBER.
+FROM-NUMBER defaults to the current tab number.
+FROM-NUMBER and TO-NUMBER count from 1.
FROM-FRAME specifies the source frame and defaults to the selected frame.
TO-FRAME specifies the target frame and defaults the next frame.
-Interactively, ARG selects the ARGth different frame to move to."
+Interactively, ARG selects the ARGth next frame on the same terminal,
+to which to move the tab; ARG defaults to 1."
(interactive "P")
(unless from-frame
(setq from-frame (selected-frame)))
@@ -1029,10 +1269,10 @@ Interactively, ARG selects the ARGth different frame to move to."
(setq to-frame (next-frame to-frame))))
(unless (eq from-frame to-frame)
(let* ((from-tabs (funcall tab-bar-tabs-function from-frame))
- (from-index (or from-index (1+ (tab-bar--current-tab-index from-tabs))))
- (from-tab (nth (1- from-index) from-tabs))
+ (from-number (or from-number (1+ (tab-bar--current-tab-index from-tabs))))
+ (from-tab (nth (1- from-number) from-tabs))
(to-tabs (funcall tab-bar-tabs-function to-frame))
- (to-index (max 0 (min (1- (or to-index 1)) (1- (length to-tabs))))))
+ (to-index (max 0 (min (1- (or to-number 1)) (1- (length to-tabs))))))
(cl-pushnew (assq-delete-all
'wc (if (eq (car from-tab) 'current-tab)
(tab-bar--tab from-frame)
@@ -1040,24 +1280,52 @@ Interactively, ARG selects the ARGth different frame to move to."
(nthcdr to-index to-tabs))
(with-selected-frame from-frame
(let ((inhibit-message t) ; avoid message about deleted tab
+ (tab-bar-close-last-tab-choice 'delete-frame)
tab-bar-closed-tabs)
- (tab-bar-close-tab from-index)))
+ (tab-bar-close-tab from-number)))
(tab-bar-tabs-set to-tabs to-frame)
(force-mode-line-update t))))
+(defun tab-bar-detach-tab (&optional from-number)
+ "Move tab number FROM-NUMBER to a new frame.
+FROM-NUMBER defaults to the current tab (which happens interactively)."
+ (interactive (list (1+ (tab-bar--current-tab-index))))
+ (let* ((tabs (funcall tab-bar-tabs-function))
+ (tab-index (1- (or from-number (1+ (tab-bar--current-tab-index tabs)))))
+ (tab-name (alist-get 'name (nth tab-index tabs)))
+ ;; On some window managers, `make-frame' selects the new frame,
+ ;; so previously selected frame is saved to `from-frame'.
+ (from-frame (selected-frame))
+ (new-frame (make-frame `((name . ,tab-name)))))
+ (tab-bar-move-tab-to-frame nil from-frame from-number new-frame nil)
+ (with-selected-frame new-frame
+ (tab-bar-close-tab))))
+
+(defun tab-bar-move-window-to-tab ()
+ "Move the selected window to a new tab.
+This command removes the selected window from the configuration stored
+on the current tab, and makes a new tab with that window in its
+configuration."
+ (interactive)
+ (let ((tab-bar-new-tab-choice 'window))
+ (tab-bar-new-tab))
+ (tab-bar-switch-to-recent-tab)
+ (delete-window)
+ (tab-bar-switch-to-recent-tab))
+
(defcustom tab-bar-new-tab-to 'right
- "Defines where to create a new tab.
+ "Where to create a new tab.
If `leftmost', create as the first tab.
-If `left', create to the left from the current tab.
-If `right', create to the right from the current tab.
+If `left', create to the left of the current tab.
+If `right', create to the right of the current tab.
If `rightmost', create as the last tab.
If the value is a function, it should return a number as a position
-on the tab bar specifying where to insert a new tab."
- :type '(choice (const :tag "First tab" leftmost)
- (const :tag "To the left" left)
- (const :tag "To the right" right)
- (const :tag "Last tab" rightmost)
+on the tab bar specifying where to add a new tab."
+ :type '(choice (const :tag "Add as First" leftmost)
+ (const :tag "Add to Left" left)
+ (const :tag "Add to Right" right)
+ (const :tag "Add as Last" rightmost)
(function :tag "Function"))
:group 'tab-bar
:version "27.1")
@@ -1070,12 +1338,13 @@ to the tab argument will be applied after all functions are called."
:group 'tab-bar
:version "27.1")
-(defun tab-bar-new-tab-to (&optional to-index)
- "Add a new tab at the absolute position TO-INDEX.
-TO-INDEX counts from 1. If no TO-INDEX is specified, then add
+(defun tab-bar-new-tab-to (&optional tab-number)
+ "Add a new tab at the absolute position TAB-NUMBER.
+TAB-NUMBER counts from 1. If no TAB-NUMBER is specified, then add
a new tab at the position specified by `tab-bar-new-tab-to'.
-Negative TO-INDEX counts tabs from the end of the tab bar.
-Argument addressing is absolute in contrast to `tab-bar-new-tab'
+Negative TAB-NUMBER counts tabs from the end of the tab bar,
+and -1 means the new tab will become the last one.
+Argument addressing is absolute in contrast to `tab-bar-new-tab',
where argument addressing is relative.
After the tab is created, the hooks in
`tab-bar-tab-post-open-functions' are run."
@@ -1088,10 +1357,12 @@ After the tab is created, the hooks in
;; Handle the case when it's called in the active minibuffer.
(when (minibuffer-selected-window)
(select-window (minibuffer-selected-window)))
- (delete-other-windows)
- ;; Create a new window to get rid of old window parameters
- ;; (e.g. prev/next buffers) of old window.
- (split-window) (delete-window)
+ (let ((ignore-window-parameters t))
+ (delete-other-windows))
+ (unless (eq tab-bar-new-tab-choice 'window)
+ ;; Create a new window to get rid of old window parameters
+ ;; (e.g. prev/next buffers) of old window.
+ (split-window) (delete-window))
(let ((buffer
(if (functionp tab-bar-new-tab-choice)
(funcall tab-bar-new-tab-choice)
@@ -1107,11 +1378,11 @@ After the tab is created, the hooks in
(let* ((to-tab (tab-bar--current-tab-make
(when (eq tab-bar-new-tab-group t)
`((group . ,(alist-get 'group from-tab))))))
- (to-index (and to-index (prefix-numeric-value to-index)))
- (to-index (or (if to-index
- (if (< to-index 0)
- (+ (length tabs) (1+ to-index))
- (1- to-index)))
+ (to-number (and tab-number (prefix-numeric-value tab-number)))
+ (to-index (or (if to-number
+ (if (< to-number 0)
+ (+ (length tabs) (1+ to-number))
+ (1- to-number)))
(pcase tab-bar-new-tab-to
('leftmost 0)
('rightmost (length tabs))
@@ -1126,6 +1397,11 @@ After the tab is created, the hooks in
;; `pushnew' handles the head of tabs but not frame-parameter
(tab-bar-tabs-set tabs))
+ (when tab-bar-history-mode
+ (puthash (selected-frame) nil tab-bar-history-back)
+ (puthash (selected-frame) nil tab-bar-history-forward)
+ (setq tab-bar-history-omit t))
+
(run-hook-with-args 'tab-bar-tab-post-open-functions
(nth to-index tabs)))
@@ -1140,15 +1416,19 @@ After the tab is created, the hooks in
(unless tab-bar-mode
(message "Added new tab at %s" tab-bar-new-tab-to))))
-(defun tab-bar-new-tab (&optional arg)
+(defun tab-bar-new-tab (&optional arg from-number)
"Create a new tab ARG positions to the right.
If a negative ARG, create a new tab ARG positions to the left.
If ARG is zero, create a new tab in place of the current tab.
If no ARG is specified, then add a new tab at the position
specified by `tab-bar-new-tab-to'.
-Argument addressing is relative in contrast to `tab-bar-new-tab-to'
-where argument addressing is absolute."
+Argument addressing is relative in contrast to `tab-bar-new-tab-to',
+where argument addressing is absolute.
+If FROM-NUMBER is a tab number, a new tab is created from that tab."
(interactive "P")
+ (when from-number
+ (let ((inhibit-message t))
+ (tab-bar-select-tab from-number)))
(if arg
(let* ((tabs (funcall tab-bar-tabs-function))
(from-index (or (tab-bar--current-tab-index tabs) 0))
@@ -1156,21 +1436,20 @@ where argument addressing is absolute."
(tab-bar-new-tab-to (1+ to-index)))
(tab-bar-new-tab-to)))
-(defun tab-bar-duplicate-tab (&optional arg)
- "Duplicate the current tab to ARG positions to the right.
-If a negative ARG, duplicate the tab to ARG positions to the left.
-If ARG is zero, duplicate the tab in place of the current tab."
+(defun tab-bar-duplicate-tab (&optional arg from-number)
+ "Clone the current tab to ARG positions to the right.
+ARG and FROM-NUMBER have the same meaning as in `tab-bar-new-tab'."
(interactive "P")
(let ((tab-bar-new-tab-choice nil)
(tab-bar-new-tab-group t))
- (tab-bar-new-tab arg)))
+ (tab-bar-new-tab arg from-number)))
(defvar tab-bar-closed-tabs nil
"A list of closed tabs to be able to undo their closing.")
(defcustom tab-bar-close-tab-select 'recent
- "Defines what tab to select after closing the specified tab.
+ "Which tab to make current after closing the specified tab.
If `left', select the adjacent left tab.
If `right', select the adjacent right tab.
If `recent', select the most recently visited tab."
@@ -1181,10 +1460,10 @@ If `recent', select the most recently visited tab."
:version "27.1")
(defcustom tab-bar-close-last-tab-choice nil
- "Defines what to do when the last tab is closed.
+ "What to do when the last tab is closed.
If nil, do nothing and show a message, like closing the last window or frame.
If `delete-frame', delete the containing frame, as a web browser would do.
-If `tab-bar-mode-disable', disable tab-bar-mode so that tabs no longer show
+If `tab-bar-mode-disable', disable `tab-bar-mode' so that tabs no longer show
in the frame.
If the value is a function, call that function with the tab to be closed
as an argument."
@@ -1206,22 +1485,22 @@ function returns a non-nil value, the tab will not be closed."
(defcustom tab-bar-tab-pre-close-functions nil
"List of functions to call before closing a tab.
-The tab to be closed and a boolean indicating whether or not it
-is the only tab in the frame are supplied as arguments,
-respectively."
+Each function is called with two arguments: the tab to be closed
+and a boolean indicating whether or not it is the only tab on its frame."
:type '(repeat function)
:group 'tab-bar
:version "27.1")
-(defun tab-bar-close-tab (&optional arg to-index)
- "Close the tab specified by its absolute position ARG.
-If no ARG is specified, then close the current tab and switch
+(defun tab-bar-close-tab (&optional tab-number to-number)
+ "Close the tab specified by its absolute position TAB-NUMBER.
+If no TAB-NUMBER is specified, then close the current tab and switch
to the tab specified by `tab-bar-close-tab-select'.
-ARG counts from 1.
-Optional TO-INDEX could be specified to override the value of
+Interactively, TAB-NUMBER is the prefix numeric argument, and defaults to 1.
+TAB-NUMBER counts from 1.
+Optional TO-NUMBER could be specified to override the value of
`tab-bar-close-tab-select' programmatically with a position
of an existing tab to select after closing the current tab.
-TO-INDEX counts from 1.
+TO-NUMBER counts from 1.
The functions in `tab-bar-tab-prevent-close-functions' will be
run to determine whether or not to close the tab.
@@ -1232,7 +1511,7 @@ for the last tab on a frame is determined by
(interactive "P")
(let* ((tabs (funcall tab-bar-tabs-function))
(current-index (tab-bar--current-tab-index tabs))
- (close-index (if (integerp arg) (1- arg) current-index))
+ (close-index (if (integerp tab-number) (1- tab-number) current-index))
(last-tab-p (= 1 (length tabs)))
(prevent-close (run-hook-with-args-until-success
'tab-bar-tab-prevent-close-functions
@@ -1260,7 +1539,7 @@ for the last tab on a frame is determined by
;; More than one tab still open
(when (eq current-index close-index)
;; Select another tab before deleting the current tab
- (let ((to-index (or (if to-index (1- to-index))
+ (let ((to-index (or (if to-number (1- to-number))
(pcase tab-bar-close-tab-select
('left (1- (if (< current-index 1) 2 current-index)))
('right (if (> (length tabs) (1+ current-index))
@@ -1290,7 +1569,8 @@ for the last tab on a frame is determined by
(message "Deleted tab and switched to %s" tab-bar-close-tab-select))))))
(defun tab-bar-close-tab-by-name (name)
- "Close the tab by NAME."
+ "Close the tab given its NAME.
+Interactively, prompt for NAME."
(interactive
(list (completing-read "Close tab by name: "
(mapcar (lambda (tab)
@@ -1298,15 +1578,25 @@ for the last tab on a frame is determined by
(funcall tab-bar-tabs-function)))))
(tab-bar-close-tab (1+ (tab-bar--tab-index-by-name name))))
-(defun tab-bar-close-other-tabs ()
- "Close all tabs on the selected frame, except the selected one."
+(defun tab-bar-close-other-tabs (&optional tab-number)
+ "Close all tabs on the selected frame, except the tab TAB-NUMBER.
+TAB-NUMBER counts from 1 and defaults to the current tab (which
+happens interactively)."
(interactive)
(let* ((tabs (funcall tab-bar-tabs-function))
- (current-tab (tab-bar--current-tab-find tabs))
+ (current-index (tab-bar--current-tab-index tabs))
+ (keep-index (if (integerp tab-number)
+ (1- (max 1 (min tab-number (length tabs))))
+ current-index))
(index 0))
- (when current-tab
+
+ (when (nth keep-index tabs)
+ (unless (eq keep-index current-index)
+ (tab-bar-select-tab (1+ keep-index))
+ (setq tabs (funcall tab-bar-tabs-function)))
+
(dolist (tab tabs)
- (unless (or (eq tab current-tab)
+ (unless (or (eq index keep-index)
(run-hook-with-args-until-success
'tab-bar-tab-prevent-close-functions tab
;; `last-tab-p' logically can't ever be true
@@ -1355,23 +1645,26 @@ for the last tab on a frame is determined by
(message "No more closed tabs to undo")))
-(defun tab-bar-rename-tab (name &optional arg)
- "Rename the tab specified by its absolute position ARG.
-If no ARG is specified, then rename the current tab.
-ARG counts from 1.
+(defun tab-bar-rename-tab (name &optional tab-number)
+ "Give the tab specified by its absolute position TAB-NUMBER a new NAME.
+If no TAB-NUMBER is specified, then rename the current tab.
+Interactively, TAB-NUMBER is the prefix numeric argument, and defaults
+to the current tab.
+TAB-NUMBER counts from 1.
+Interactively, prompt for the new NAME.
If NAME is the empty string, then use the automatic name
function `tab-bar-tab-name-function'."
(interactive
(let* ((tabs (funcall tab-bar-tabs-function))
- (tab-index (or current-prefix-arg (1+ (tab-bar--current-tab-index tabs))))
- (tab-name (alist-get 'name (nth (1- tab-index) tabs))))
+ (tab-number (or current-prefix-arg (1+ (tab-bar--current-tab-index tabs))))
+ (tab-name (alist-get 'name (nth (1- tab-number) tabs))))
(list (read-from-minibuffer
"New name for tab (leave blank for automatic naming): "
nil nil nil nil tab-name)
current-prefix-arg)))
(let* ((tabs (funcall tab-bar-tabs-function))
- (tab-index (if arg
- (1- (max 0 (min arg (length tabs))))
+ (tab-index (if (integerp tab-number)
+ (1- (max 0 (min tab-number (length tabs))))
(tab-bar--current-tab-index tabs)))
(tab-to-rename (nth tab-index tabs))
(tab-explicit-name (> (length name) 0))
@@ -1386,7 +1679,8 @@ function `tab-bar-tab-name-function'."
(message "Renamed tab to '%s'" tab-new-name))))
(defun tab-bar-rename-tab-by-name (tab-name new-name)
- "Rename the tab named TAB-NAME.
+ "Rename the tab named TAB-NAME to NEW-NAME.
+Interactively, prompt for TAB-NAME and NEW-NAME.
If NEW-NAME is the empty string, then use the automatic name
function `tab-bar-tab-name-function'."
(interactive
@@ -1403,7 +1697,7 @@ function `tab-bar-tab-name-function'."
;;; Tab groups
(defun tab-bar-move-tab-to-group (&optional tab)
- "Relocate TAB (or the current tab) closer to its group."
+ "Relocate TAB (by default, the current tab) closer to its group."
(interactive)
(let* ((tabs (funcall tab-bar-tabs-function))
(tab (or tab (tab-bar--current-tab-find tabs)))
@@ -1438,20 +1732,22 @@ The current tab is supplied as an argument."
:group 'tab-bar
:version "28.1")
-(defun tab-bar-change-tab-group (group-name &optional arg)
- "Add the tab specified by its absolute position ARG to GROUP-NAME.
-If no ARG is specified, then set the GROUP-NAME for the current tab.
-ARG counts from 1.
+(defun tab-bar-change-tab-group (group-name &optional tab-number)
+ "Add the tab specified by its absolute position TAB-NUMBER to GROUP-NAME.
+If no TAB-NUMBER is specified, then set the GROUP-NAME for the current tab.
+Interactively, TAB-NUMBER is the prefix numeric argument, and the command
+prompts for GROUP-NAME.
+TAB-NUMBER counts from 1.
If GROUP-NAME is the empty string, then remove the tab from any group.
While using this command, you might also want to replace
`tab-bar-format-tabs' with `tab-bar-format-tabs-groups' in
`tab-bar-format' to group tabs on the tab bar."
(interactive
(let* ((tabs (funcall tab-bar-tabs-function))
- (tab-index (or current-prefix-arg
+ (tab-number (or current-prefix-arg
(1+ (tab-bar--current-tab-index tabs))))
(group-name (funcall tab-bar-tab-group-function
- (nth (1- tab-index) tabs))))
+ (nth (1- tab-number) tabs))))
(list (completing-read
"Group name for tab (leave blank to remove group): "
(delete-dups
@@ -1461,8 +1757,8 @@ While using this command, you might also want to replace
(funcall tab-bar-tabs-function))))))
current-prefix-arg)))
(let* ((tabs (funcall tab-bar-tabs-function))
- (tab-index (if arg
- (1- (max 0 (min arg (length tabs))))
+ (tab-index (if tab-number
+ (1- (max 0 (min tab-number (length tabs))))
(tab-bar--current-tab-index tabs)))
(tab (nth tab-index tabs))
(group (assq 'group tab))
@@ -1478,7 +1774,8 @@ While using this command, you might also want to replace
(message "Set tab group to '%s'" group-new-name))))
(defun tab-bar-close-group-tabs (group-name)
- "Close all tabs that belong to GROUP-NAME on the selected frame."
+ "Close all tabs that belong to GROUP-NAME on the selected frame.
+Interactively, prompt for GROUP-NAME."
(interactive
(let ((group-name (funcall tab-bar-tab-group-function
(tab-bar--current-tab-find))))
@@ -1520,29 +1817,34 @@ While using this command, you might also want to replace
(defvar tab-bar-history-old nil
"Window configuration before the current command.")
-(defvar tab-bar-history-old-minibuffer-depth 0
- "Minibuffer depth before the current command.")
+(defvar tab-bar-history-pre-command nil
+ "Command set to `this-command' by `pre-command-hook'.")
+
+(defvar tab-bar-history-done-command nil
+ "Command handled by `window-configuration-change-hook'.")
(defun tab-bar--history-pre-change ()
- (setq tab-bar-history-old-minibuffer-depth (minibuffer-depth))
- ;; Store wc before possibly entering the minibuffer
- (when (zerop tab-bar-history-old-minibuffer-depth)
+ ;; Reset before the command could set it
+ (setq tab-bar-history-omit nil)
+ (setq tab-bar-history-pre-command this-command)
+ (when (zerop (minibuffer-depth))
(setq tab-bar-history-old
`((wc . ,(current-window-configuration))
(wc-point . ,(point-marker))))))
(defun tab-bar--history-change ()
- (when (and (not tab-bar-history-omit)
- tab-bar-history-old
- ;; Store wc before possibly entering the minibuffer
- (zerop tab-bar-history-old-minibuffer-depth))
+ (when (and (not tab-bar-history-omit) tab-bar-history-old
+ ;; Don't register changes performed by the same command
+ ;; repeated in sequence, such as incremental window resizing.
+ (not (eq tab-bar-history-done-command tab-bar-history-pre-command))
+ (zerop (minibuffer-depth)))
(puthash (selected-frame)
(seq-take (cons tab-bar-history-old
(gethash (selected-frame) tab-bar-history-back))
tab-bar-history-limit)
- tab-bar-history-back))
- (when tab-bar-history-omit
- (setq tab-bar-history-omit nil)))
+ tab-bar-history-back)
+ (setq tab-bar-history-old nil))
+ (setq tab-bar-history-done-command tab-bar-history-pre-command))
(defun tab-bar-history-back ()
"Restore a previous window configuration used in the current tab.
@@ -1594,7 +1896,7 @@ and can restore them."
(add-text-properties 0 (length tab-bar-back-button)
`(display (image :type xpm
:file "tabs/left-arrow.xpm"
- :margin (2 . 0)
+ :margin ,tab-bar-button-margin
:ascent center))
tab-bar-back-button))
(when (and tab-bar-mode (not (get-text-property 0 'display tab-bar-forward-button)))
@@ -1602,7 +1904,7 @@ and can restore them."
(add-text-properties 0 (length tab-bar-forward-button)
`(display (image :type xpm
:file "tabs/right-arrow.xpm"
- :margin (2 . 0)
+ :margin ,tab-bar-button-margin
:ascent center))
tab-bar-forward-button))
@@ -1726,20 +2028,24 @@ Letters do not insert themselves; instead, they are commands.
nil))))
(defun tab-switcher-next-line (&optional arg)
+ "Move to ARGth next line in the list of tabs.
+Interactively, ARG is the prefix numeric argument and defaults to 1."
(interactive "p")
(forward-line arg)
(beginning-of-line)
(move-to-column tab-switcher-column))
(defun tab-switcher-prev-line (&optional arg)
+ "Move to ARGth previous line in the list of tabs.
+Interactively, ARG is the prefix numeric argument and defaults to 1."
(interactive "p")
(forward-line (- arg))
(beginning-of-line)
(move-to-column tab-switcher-column))
(defun tab-switcher-unmark (&optional backup)
- "Cancel all requested operations on window configuration on this line and move down.
-Optional prefix arg means move up."
+ "Cancel requested operations on window configuration on this line and move down.
+With prefix arg, move up instead."
(interactive "P")
(beginning-of-line)
(move-to-column tab-switcher-column)
@@ -1750,7 +2056,7 @@ Optional prefix arg means move up."
(move-to-column tab-switcher-column))
(defun tab-switcher-backup-unmark ()
- "Move up and cancel all requested operations on window configuration on line above."
+ "Move up one line and cancel requested operations on window configuration there."
(interactive)
(forward-line -1)
(tab-switcher-unmark)
@@ -1759,7 +2065,7 @@ Optional prefix arg means move up."
(defun tab-switcher-delete (&optional arg)
"Mark window configuration on this line to be deleted by \\<tab-switcher-mode-map>\\[tab-switcher-execute] command.
-Prefix arg is how many window configurations to delete.
+Prefix arg says how many window configurations to delete.
Negative arg means delete backwards."
(interactive "p")
(let ((buffer-read-only nil))
@@ -1784,7 +2090,7 @@ Then move up one line. Prefix arg means move that many lines."
(tab-switcher-delete (- (or arg 1))))
(defun tab-switcher-delete-from-list (tab)
- "Delete the window configuration from both lists."
+ "Delete the window configuration from the list of tabs."
(push `((frame . ,(selected-frame))
(index . ,(tab-bar--tab-index tab))
(tab . ,tab))
@@ -1812,8 +2118,8 @@ Then move up one line. Prefix arg means move that many lines."
(defun tab-switcher-select ()
"Select this line's window configuration.
-This command deletes and replaces all the previously existing windows
-in the selected frame."
+This command replaces all the existing windows in the selected frame
+with those specified by the selected window configuration."
(interactive)
(let* ((to-tab (tab-switcher-current-tab t)))
(kill-buffer (current-buffer))
@@ -1839,8 +2145,8 @@ in the selected frame."
(t (list (selected-frame)))))
(defun tab-bar-get-buffer-tab (buffer-or-name &optional all-frames ignore-current-tab)
- "Return a tab owning a window whose buffer is BUFFER-OR-NAME.
-BUFFER-OR-NAME may be a buffer or a buffer name and defaults to
+ "Return the tab that owns the window whose buffer is BUFFER-OR-NAME.
+BUFFER-OR-NAME may be a buffer or a buffer name, and defaults to
the current buffer.
The optional argument ALL-FRAMES specifies the frames to consider:
@@ -1851,11 +2157,12 @@ The optional argument ALL-FRAMES specifies the frames to consider:
- A frame means consider all tabs on that frame only.
-Any other value of ALL-FRAMES means consider all tabs on the
+- Any other value of ALL-FRAMES means consider all tabs on the
selected frame and no others.
When the optional argument IGNORE-CURRENT-TAB is non-nil,
-don't take into account the buffers in the currently selected tab."
+don't take into account the buffers in the currently selected tab.
+Otherwise, prefer buffers of the current tab."
(let ((buffer (if buffer-or-name
(get-buffer buffer-or-name)
(current-buffer))))
@@ -1865,8 +2172,7 @@ don't take into account the buffers in the currently selected tab."
(seq-some
(lambda (tab)
(when (if (eq (car tab) 'current-tab)
- (unless ignore-current-tab
- (get-buffer-window buffer frame))
+ (get-buffer-window buffer frame)
(let* ((state (alist-get 'ws tab))
(buffers (when state
(window-state-buffers state))))
@@ -1877,11 +2183,18 @@ don't take into account the buffers in the currently selected tab."
(member (buffer-name buffer) buffers))))
(append tab `((index . ,(tab-bar--tab-index tab nil frame))
(frame . ,frame)))))
- (funcall tab-bar-tabs-function frame)))
+ (let* ((tabs (funcall tab-bar-tabs-function frame))
+ (current-tab (tab-bar--current-tab-find tabs)))
+ (setq tabs (remq current-tab tabs))
+ (if ignore-current-tab
+ ;; Use tabs without current-tab.
+ tabs
+ ;; Make sure current-tab is at the beginning of tabs.
+ (cons current-tab tabs)))))
(tab-bar--reusable-frames all-frames)))))
(defun display-buffer-in-tab (buffer alist)
- "Display BUFFER in a tab.
+ "Display BUFFER in a tab using display actions in ALIST.
ALIST is an association list of action symbols and values. See
Info node `(elisp) Buffer Display Action Alists' for details of
such alists.
@@ -1889,27 +2202,34 @@ such alists.
If ALIST contains a `tab-name' entry, it creates a new tab with that name and
displays BUFFER in a new tab. If a tab with this name already exists, it
switches to that tab before displaying BUFFER. The `tab-name' entry can be
-a function, then it is called with two arguments: BUFFER and ALIST, and
-should return the tab name. When a `tab-name' entry is omitted, create
+a function, in which case it is called with two arguments: BUFFER and ALIST,
+and should return the tab name. When a `tab-name' entry is omitted, create
a new tab without an explicit name.
The ALIST entry `tab-group' (string or function) defines the tab group.
If ALIST contains a `reusable-frames' entry, its value determines
which frames to search for a reusable tab:
- nil -- the selected frame (actually the last non-minibuffer frame)
- A frame -- just that frame
- `visible' -- all visible frames
- 0 -- all frames on the current terminal
- t -- all frames.
+ nil -- do not reuse any frames;
+ a frame -- just that frame;
+ `visible' -- all visible frames;
+ 0 -- all frames on the current terminal;
+ t -- all frames;
+ other non-nil values -- use the selected frame.
+
+If ALIST contains a non-nil `ignore-current-tab' entry, then the buffers
+of the current tab are skipped when searching for a reusable tab.
+Otherwise, prefer buffers of the current tab.
This is an action function for buffer display, see Info
node `(elisp) Buffer Display Action Functions'. It should be
called only by `display-buffer' or a function directly or
indirectly called by the latter."
(let* ((reusable-frames (alist-get 'reusable-frames alist))
+ (ignore-current-tab (alist-get 'ignore-current-tab alist))
(reusable-tab (when reusable-frames
- (tab-bar-get-buffer-tab buffer reusable-frames))))
+ (tab-bar-get-buffer-tab buffer reusable-frames
+ ignore-current-tab))))
(if reusable-tab
(let* ((frame (alist-get 'frame reusable-tab))
(index (alist-get 'index reusable-tab)))
@@ -1933,7 +2253,7 @@ indirectly called by the latter."
(display-buffer-in-new-tab buffer alist))))))
(defun display-buffer-in-new-tab (buffer alist)
- "Display BUFFER in a new tab.
+ "Display BUFFER in a new tab using display actions in ALIST.
ALIST is an association list of action symbols and values. See
Info node `(elisp) Buffer Display Action Alists' for details of
such alists.
@@ -1943,9 +2263,9 @@ without checking if a suitable tab already exists.
If ALIST contains a `tab-name' entry, it creates a new tab with that name
and displays BUFFER in a new tab. The `tab-name' entry can be a function,
-then it is called with two arguments: BUFFER and ALIST, and should return
-the tab name. When a `tab-name' entry is omitted, create a new tab without
-an explicit name.
+in which case it is called with two arguments: BUFFER and ALIST, and should
+return the tab name. When a `tab-name' entry is omitted, create a new tab
+without an explicit name.
The ALIST entry `tab-group' (string or function) defines the tab group.
@@ -1967,19 +2287,23 @@ indirectly called by the latter."
(tab-bar-change-tab-group tab-group)))
(window--display-buffer buffer (selected-window) 'tab alist)))
-(defun switch-to-buffer-other-tab (buffer-or-name &optional norecord)
+(defun switch-to-buffer-other-tab (buffer-or-name &optional _norecord)
"Switch to buffer BUFFER-OR-NAME in another tab.
-Like \\[switch-to-buffer-other-frame] (which see), but creates a new tab."
+Like \\[switch-to-buffer-other-frame] (which see), but creates a new tab.
+Interactively, prompt for the buffer to switch to."
+ (declare (advertised-calling-convention (buffer-or-name) "28.1"))
(interactive
(list (read-buffer-to-switch "Switch to buffer in other tab: ")))
(display-buffer (window-normalize-buffer-to-switch-to buffer-or-name)
'((display-buffer-in-tab)
- (inhibit-same-window . nil))
- norecord))
+ (inhibit-same-window . nil))))
(defun find-file-other-tab (filename &optional wildcards)
"Edit file FILENAME, in another tab.
-Like \\[find-file-other-frame] (which see), but creates a new tab."
+Like \\[find-file-other-frame] (which see), but creates a new tab.
+Interactively, prompt for FILENAME.
+If WILDCARDS is non-nil, FILENAME can include widcards, and all matching
+files will be visited."
(interactive
(find-file-read-args "Find file in other tab: "
(confirm-nonexistent-file-or-buffer)))
@@ -1996,7 +2320,10 @@ Like \\[find-file-other-frame] (which see), but creates a new tab."
"Edit file FILENAME, in another tab, but don't allow changes.
Like \\[find-file-other-frame] (which see), but creates a new tab.
Like \\[find-file-other-tab], but marks buffer as read-only.
-Use \\[read-only-mode] to permit editing."
+Use \\[read-only-mode] to permit editing.
+Interactively, prompt for FILENAME.
+If WILDCARDS is non-nil, FILENAME can include widcards, and all matching
+files will be visited."
(interactive
(find-file-read-args "Find file read-only in other tab: "
(confirm-nonexistent-file-or-buffer)))
@@ -2027,24 +2354,26 @@ When `switch-to-buffer-obey-display-actions' is non-nil,
;;; Short aliases and keybindings
-(defalias 'tab-new 'tab-bar-new-tab)
-(defalias 'tab-new-to 'tab-bar-new-tab-to)
-(defalias 'tab-duplicate 'tab-bar-duplicate-tab)
-(defalias 'tab-close 'tab-bar-close-tab)
-(defalias 'tab-close-other 'tab-bar-close-other-tabs)
-(defalias 'tab-close-group 'tab-bar-close-group-tabs)
-(defalias 'tab-undo 'tab-bar-undo-close-tab)
-(defalias 'tab-select 'tab-bar-select-tab)
-(defalias 'tab-switch 'tab-bar-switch-to-tab)
-(defalias 'tab-next 'tab-bar-switch-to-next-tab)
-(defalias 'tab-previous 'tab-bar-switch-to-prev-tab)
-(defalias 'tab-last 'tab-bar-switch-to-last-tab)
-(defalias 'tab-recent 'tab-bar-switch-to-recent-tab)
-(defalias 'tab-move 'tab-bar-move-tab)
-(defalias 'tab-move-to 'tab-bar-move-tab-to)
-(defalias 'tab-rename 'tab-bar-rename-tab)
-(defalias 'tab-group 'tab-bar-change-tab-group)
-(defalias 'tab-list 'tab-switcher)
+(defalias 'tab-new 'tab-bar-new-tab)
+(defalias 'tab-new-to 'tab-bar-new-tab-to)
+(defalias 'tab-duplicate 'tab-bar-duplicate-tab)
+(defalias 'tab-detach 'tab-bar-detach-tab)
+(defalias 'tab-window-detach 'tab-bar-move-window-to-tab)
+(defalias 'tab-close 'tab-bar-close-tab)
+(defalias 'tab-close-other 'tab-bar-close-other-tabs)
+(defalias 'tab-close-group 'tab-bar-close-group-tabs)
+(defalias 'tab-undo 'tab-bar-undo-close-tab)
+(defalias 'tab-select 'tab-bar-select-tab)
+(defalias 'tab-switch 'tab-bar-switch-to-tab)
+(defalias 'tab-next 'tab-bar-switch-to-next-tab)
+(defalias 'tab-previous 'tab-bar-switch-to-prev-tab)
+(defalias 'tab-last 'tab-bar-switch-to-last-tab)
+(defalias 'tab-recent 'tab-bar-switch-to-recent-tab)
+(defalias 'tab-move 'tab-bar-move-tab)
+(defalias 'tab-move-to 'tab-bar-move-tab-to)
+(defalias 'tab-rename 'tab-bar-rename-tab)
+(defalias 'tab-group 'tab-bar-change-tab-group)
+(defalias 'tab-list 'tab-switcher)
(define-key tab-prefix-map "n" 'tab-duplicate)
(define-key tab-prefix-map "N" 'tab-new-to)
@@ -2078,14 +2407,12 @@ Used in `repeat-mode'.")
(defvar tab-bar-move-repeat-map
(let ((map (make-sparse-keymap)))
(define-key map "m" 'tab-move)
- (define-key map "M" (lambda ()
- (interactive)
- (setq repeat-map 'tab-bar-move-repeat-map)
- (tab-move -1)))
+ (define-key map "M" 'tab-bar-move-tab-backward)
map)
"Keymap to repeat tab move key sequences `C-x t m m M'.
Used in `repeat-mode'.")
(put 'tab-move 'repeat-map 'tab-bar-move-repeat-map)
+(put 'tab-bar-move-tab-backward 'repeat-map 'tab-bar-move-repeat-map)
(provide 'tab-bar)
diff --git a/lisp/tab-line.el b/lisp/tab-line.el
index d5fad353638..af0647acf7c 100644
--- a/lisp/tab-line.el
+++ b/lisp/tab-line.el
@@ -36,13 +36,15 @@
:group 'convenience
:version "27.1")
-(defcustom tab-line-tab-face-functions '(tab-line-tab-face-special)
+(defcustom tab-line-tab-face-functions
+ '(tab-line-tab-face-modified tab-line-tab-face-special)
"Functions called to modify tab faces.
Each function is called with five arguments: the tab, a list of
all tabs, the face returned by the previously called modifier,
whether the tab is a buffer, and whether the tab is selected."
:type '(repeat
(choice (function-item tab-line-tab-face-special)
+ (function-item tab-line-tab-face-modified)
(function-item tab-line-tab-face-inactive-alternating)
(function-item tab-line-tab-face-group)
(function :tag "Custom function")))
@@ -92,6 +94,14 @@ function `tab-line-tab-face-special'."
:version "28.1"
:group 'tab-line-faces)
+(defface tab-line-tab-modified
+ '((t :inherit font-lock-doc-face))
+ "Face for modified tabs.
+Applied when option `tab-line-tab-face-functions' includes
+function `tab-line-tab-face-modified'."
+ :version "28.1"
+ :group 'tab-line-faces)
+
(defface tab-line-tab-group
'((t :inherit tab-line :box nil))
"Face for group tabs.
@@ -109,7 +119,11 @@ function `tab-line-tab-face-group'."
:group 'tab-line-faces)
(defface tab-line-highlight
- '((t :inherit tab-line-tab))
+ '((((class color) (min-colors 88))
+ :box (:line-width 1 :style released-button)
+ :background "grey85"
+ :foreground "black")
+ (t :inverse-video nil))
"Tab line face for highlighting."
:version "27.1"
:group 'tab-line-faces)
@@ -123,16 +137,17 @@ function `tab-line-tab-face-group'."
(defvar tab-line-tab-map
(let ((map (make-sparse-keymap)))
- (define-key map [tab-line mouse-1] 'tab-line-select-tab)
+ (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 mouse-1] 'tab-line-new-tab)
- (define-key map [tab-line mouse-2] 'tab-line-new-tab)
+ (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.")
@@ -146,16 +161,16 @@ function `tab-line-tab-face-group'."
(defvar tab-line-left-map
(let ((map (make-sparse-keymap)))
- (define-key map [tab-line mouse-1] 'tab-line-hscroll-left)
- (define-key map [tab-line mouse-2] 'tab-line-hscroll-left)
+ (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 mouse-1] 'tab-line-hscroll-right)
- (define-key map [tab-line mouse-2] 'tab-line-hscroll-right)
+ (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.")
@@ -247,13 +262,14 @@ If nil, don't show it at all."
(defcustom tab-line-tab-name-function #'tab-line-tab-name-buffer
"Function to get a tab name.
-Function gets two arguments: tab to get name for and a list of tabs
-to display. By default, use function `tab-line-tab-name'."
+The function is called with one or two arguments: the buffer or
+another object whose tab's name is requested, and, optionally,
+the list of all tabs."
:type '(choice (const :tag "Buffer name"
tab-line-tab-name-buffer)
(const :tag "Truncated buffer name"
tab-line-tab-name-truncated-buffer)
- (function :tag "Function"))
+ (function :tag "Function"))
:initialize 'custom-initialize-default
:set (lambda (sym val)
(set-default sym val)
@@ -279,9 +295,9 @@ to `tab-line-tab-name-truncated-buffer'."
(defvar tab-line-tab-name-ellipsis t)
(defun tab-line-tab-name-truncated-buffer (buffer &optional _buffers)
- "Generate tab name from BUFFER.
+ "Generate tab name from BUFFER, truncating it as needed.
Truncate it to the length specified by `tab-line-tab-name-truncated-max'.
-Append ellipsis `tab-line-tab-name-ellipsis' in this case."
+If truncated, append ellipsis per `tab-line-tab-name-ellipsis'."
(let ((tab-name (buffer-name buffer)))
(if (< (length tab-name) tab-line-tab-name-truncated-max)
tab-name
@@ -328,7 +344,7 @@ Used only for `tab-line-tabs-mode-buffers' and `tab-line-tabs-buffer-groups'.")
(buffer-list)))))
(defun tab-line-tabs-mode-buffers ()
- "Return a list of buffers with the same major mode with current buffer."
+ "Return a list of buffers with the same major mode as the current buffer."
(let ((mode major-mode))
(seq-sort-by #'buffer-name #'string<
(seq-filter (lambda (b) (with-current-buffer b
@@ -336,12 +352,12 @@ Used only for `tab-line-tabs-mode-buffers' and `tab-line-tabs-buffer-groups'.")
(funcall tab-line-tabs-buffer-list-function)))))
(defvar tab-line-tabs-buffer-group-function nil
- "Function to put a buffer to the group.
-Takes a buffer as arg and should return a group name as string.
-When the return value is nil, filter out the buffer.")
+ "Function to add a buffer to the appropriate group of tabs.
+Takes a buffer as arg and should return a group name as a string.
+If the return value is nil, the buffer should be filtered out.")
(defvar tab-line-tabs-buffer-group-sort-function nil
- "Function to sort buffers in group.")
+ "Function to sort buffers in a group.")
(defvar tab-line-tabs-buffer-groups-sort-function #'string<
"Function to sort group names.")
@@ -349,7 +365,9 @@ When the return value is nil, filter out the buffer.")
(defvar tab-line-tabs-buffer-groups mouse-buffer-menu-mode-groups
"How to group various major modes together in the tab line.
Each element has the form (REGEXP . GROUPNAME).
-If the major mode's name string matches REGEXP, use GROUPNAME instead.")
+If the major mode's name matches REGEXP, it belongs to GROUPNAME.
+The default is for each major mode to have a separate group
+named the same as the mode.")
(defun tab-line-tabs-buffer-group-name (&optional buffer)
(if (functionp tab-line-tabs-buffer-group-function)
@@ -445,8 +463,11 @@ variable `tab-line-tabs-function'."
(defcustom tab-line-tab-name-format-function #'tab-line-tab-name-format-default
"Function to format a tab name.
-Function gets two arguments: the tab and a list of all tabs, and
-should return the formatted tab name to display in the tab line."
+The function will be called two arguments: the tab whose name to format,
+and the list of all the tabs; it should return the formatted tab name
+to display in the tab line.
+The first argument could also be a different object, for example the buffer
+which the tab will represent."
:type 'function
:initialize 'custom-initialize-default
:set (lambda (sym val)
@@ -456,6 +477,7 @@ should return the formatted tab name to display in the tab line."
:version "28.1")
(defun tab-line-tab-name-format-default (tab tabs)
+ "Default function to use as `tab-line-tab-name-format-function', which see."
(let* ((buffer-p (bufferp tab))
(selected-p (if buffer-p
(eq tab (window-buffer))
@@ -488,7 +510,8 @@ should return the formatted tab name to display in the tab line."
mouse-face tab-line-highlight))))
(defun tab-line-format-template (tabs)
- "Template for displaying tab line for selected window."
+ "Template of the format for displaying tab line for selected window.
+This is used by `tab-line-format'."
(let* ((separator (or tab-line-separator (if window-system " " "|")))
(hscroll (window-parameter nil 'tab-line-hscroll))
(strings
@@ -520,7 +543,8 @@ should return the formatted tab name to display in the tab line."
(defun tab-line-tab-face-inactive-alternating (tab tabs face _buffer-p selected-p)
"Return FACE for TAB in TABS with alternation.
-When TAB is an inactive buffer and is even-numbered, make FACE
+SELECTED-P nil means TAB is not the selected tab.
+When TAB is not selected and is even-numbered, make FACE
inherit from `tab-line-tab-inactive-alternate'. For use in
`tab-line-tab-face-functions'."
(when (and (not selected-p) (cl-evenp (cl-position tab tabs)))
@@ -528,14 +552,23 @@ inherit from `tab-line-tab-inactive-alternate'. For use in
face)
(defun tab-line-tab-face-special (tab _tabs face buffer-p _selected-p)
- "Return FACE for TAB according to whether it's special.
-When TAB is a non-file-backed buffer, make FACE inherit from
+ "Return FACE for TAB according to whether its buffer is special.
+When TAB is a non-file-visiting buffer, make FACE inherit from
`tab-line-tab-special'. For use in
`tab-line-tab-face-functions'."
(when (and buffer-p (not (buffer-file-name tab)))
(setf face `(:inherit (tab-line-tab-special ,face))))
face)
+(defun tab-line-tab-face-modified (tab _tabs face buffer-p _selected-p)
+ "Return FACE for TAB according to whether its buffer is modified.
+When TAB is a modified, file-backed buffer, make FACE inherit
+from `tab-line-tab-modified'. For use in
+`tab-line-tab-face-functions'."
+ (when (and buffer-p (buffer-file-name tab) (buffer-modified-p tab))
+ (setf face `(:inherit (tab-line-tab-modified ,face))))
+ face)
+
(defun tab-line-tab-face-group (tab _tabs face _buffer-p _selected-p)
"Return FACE for TAB according to whether it's a group tab.
For use in `tab-line-tab-face-functions'."
@@ -546,7 +579,7 @@ For use in `tab-line-tab-face-functions'."
(defvar tab-line-auto-hscroll)
(defun tab-line-format ()
- "Template for displaying tab line for selected window."
+ "Format for displaying the tab line of the selected window."
(let* ((tabs (funcall tab-line-tabs-function))
(cache-key (list tabs
;; handle buffer renames
@@ -554,7 +587,10 @@ For use in `tab-line-tab-face-functions'."
;; handle tab-line scrolling
(window-parameter nil 'tab-line-hscroll)
;; for setting face 'tab-line-tab-current'
- (eq (selected-window) (old-selected-window))))
+ (eq (selected-window) (old-selected-window))
+ (and (memq 'tab-line-tab-face-modified
+ tab-line-tab-face-functions)
+ (buffer-file-name) (buffer-modified-p))))
(cache (window-parameter nil 'tab-line-cache)))
;; Enable auto-hscroll again after it was disabled on manual scrolling.
;; The moment to enable it is when the window-buffer was updated.
@@ -571,7 +607,7 @@ For use in `tab-line-tab-face-functions'."
(defcustom tab-line-auto-hscroll t
"Allow or disallow automatic horizontal scrolling of the tab line.
-Non-nil means the tab line are automatically scrolled horizontally to make
+Non-nil means the tab lines are automatically scrolled horizontally to make
the selected tab visible."
:type 'boolean
:group 'tab-line
@@ -666,42 +702,46 @@ the selected tab visible."
(when window
(force-mode-line-update t))))
-(defun tab-line-hscroll-right (&optional arg mouse-event)
+(defun tab-line-hscroll-right (&optional arg event)
+ "Scroll the tab line ARG positions to the right.
+Interactively, ARG is the prefix numeric argument and defaults to 1."
(interactive (list current-prefix-arg last-nonmenu-event))
- (let ((window (and (listp mouse-event) (posn-window (event-start mouse-event)))))
+ (let ((window (and (listp event) (posn-window (event-start event)))))
(tab-line-hscroll arg window)
(force-mode-line-update window)))
-(defun tab-line-hscroll-left (&optional arg mouse-event)
+(defun tab-line-hscroll-left (&optional arg event)
+ "Scroll the tab line ARG positions to the left.
+Interactively, ARG is the prefix numeric argument and defaults to 1."
(interactive (list current-prefix-arg last-nonmenu-event))
- (let ((window (and (listp mouse-event) (posn-window (event-start mouse-event)))))
+ (let ((window (and (listp event) (posn-window (event-start event)))))
(tab-line-hscroll (- (or arg 1)) window)
(force-mode-line-update window)))
-(defun tab-line-new-tab (&optional mouse-event)
- "Add a new tab to the tab line.
-Usually is invoked by clicking on the plus-shaped button.
-But any switching to other buffer also adds a new tab
-corresponding to the switched buffer."
+(defun tab-line-new-tab (&optional event)
+ "Add a new tab to the selected-window's tab line.
+This command is usually invoked by clicking on the plus-shaped button
+on the tab line. Switching to another buffer also adds a new tab
+corresponding to the new buffer shown in the window."
(interactive (list last-nonmenu-event))
(if (functionp tab-line-new-tab-choice)
(funcall tab-line-new-tab-choice)
(let ((tab-line-tabs-buffer-groups mouse-buffer-menu-mode-groups))
- (if (and (listp mouse-event)
+ (if (and (listp event)
(display-popup-menus-p)
(not tty-menu-open-use-tmm))
- (mouse-buffer-menu mouse-event) ; like (buffer-menu-open)
+ (mouse-buffer-menu event) ; like (buffer-menu-open)
;; tty menu doesn't support mouse clicks, so use tmm
(tmm-prompt (mouse-buffer-menu-keymap))))))
-(defun tab-line-select-tab (&optional e)
- "Switch to the selected tab.
+(defun tab-line-select-tab (&optional event)
+ "Switch to the buffer specified by the tab on which you click.
This command maintains the original order of prev/next buffers.
-So for example, switching to a previous tab is equivalent to
+So, for example, switching to a previous tab is equivalent to
using the `previous-buffer' command."
(interactive "e")
- (let* ((posnp (event-start e))
+ (let* ((posnp (event-start event))
(tab (get-pos-property 1 'tab (car (posn-string posnp))))
(buffer (if (bufferp tab) tab (cdr (assq 'buffer tab)))))
(if buffer
@@ -743,16 +783,18 @@ when `tab-line-tabs-function' is `tab-line-tabs-window-buffers'."
:group 'tab-line
:version "28.1")
-(defun tab-line-switch-to-prev-tab (&optional mouse-event)
- "Switch to the previous tab.
+(defun tab-line-switch-to-prev-tab (&optional event)
+ "Switch to the previous tab's buffer.
Its effect is the same as using the `previous-buffer' command
(\\[previous-buffer])."
(interactive (list last-nonmenu-event))
- (let ((window (and (listp mouse-event) (posn-window (event-start mouse-event)))))
+ (let ((window (and (listp event) (posn-window (event-start event)))))
(if (eq tab-line-tabs-function #'tab-line-tabs-window-buffers)
(switch-to-prev-buffer window)
(with-selected-window (or window (selected-window))
- (let* ((tabs (funcall tab-line-tabs-function))
+ (let* ((tabs (seq-filter
+ (lambda (tab) (or (bufferp tab) (assq 'buffer tab)))
+ (funcall tab-line-tabs-function)))
(pos (seq-position
tabs (current-buffer)
(lambda (tab buffer)
@@ -767,16 +809,18 @@ Its effect is the same as using the `previous-buffer' command
(when (bufferp buffer)
(switch-to-buffer buffer)))))))
-(defun tab-line-switch-to-next-tab (&optional mouse-event)
- "Switch to the next tab.
+(defun tab-line-switch-to-next-tab (&optional event)
+ "Switch to the next tab's buffer.
Its effect is the same as using the `next-buffer' command
(\\[next-buffer])."
(interactive (list last-nonmenu-event))
- (let ((window (and (listp mouse-event) (posn-window (event-start mouse-event)))))
+ (let ((window (and (listp event) (posn-window (event-start event)))))
(if (eq tab-line-tabs-function #'tab-line-tabs-window-buffers)
(switch-to-next-buffer window)
(with-selected-window (or window (selected-window))
- (let* ((tabs (funcall tab-line-tabs-function))
+ (let* ((tabs (seq-filter
+ (lambda (tab) (or (bufferp tab) (assq 'buffer tab)))
+ (funcall tab-line-tabs-function)))
(pos (seq-position
tabs (current-buffer)
(lambda (tab buffer)
@@ -793,9 +837,9 @@ Its effect is the same as using the `next-buffer' command
(defcustom tab-line-close-tab-function 'bury-buffer
- "Defines what to do on closing the tab.
+ "What to do upon closing a tab on the tab line.
If `bury-buffer', put the tab's buffer at the end of the list of all
-buffers that effectively hides the buffer's tab from the tab line.
+buffers, which effectively hides the buffer's tab from the tab line.
If `kill-buffer', kills the tab's buffer.
When a function, it is called with the tab as its argument.
This option is useful when `tab-line-tabs-function' has the value
@@ -806,13 +850,13 @@ This option is useful when `tab-line-tabs-function' has the value
:group 'tab-line
:version "27.1")
-(defun tab-line-close-tab (&optional mouse-event)
+(defun tab-line-close-tab (&optional event)
"Close the selected tab.
-Usually is invoked by clicking on the close button on the right side
-of the tab. This command buries the buffer, so it goes out of sight
-from the tab line."
+This command is usually invoked by clicking on the close button on the
+right side of the tab. This command buries the buffer, so it goes out of
+sight of the tab line."
(interactive (list last-nonmenu-event))
- (let* ((posnp (and (listp mouse-event) (event-start mouse-event)))
+ (let* ((posnp (and (listp event) (event-start event)))
(window (and posnp (posn-window posnp)))
(tab (get-pos-property 1 'tab (car (posn-string posnp))))
(buffer (if (bufferp tab) tab (cdr (assq 'buffer tab))))
@@ -832,16 +876,41 @@ from the tab line."
(funcall tab-line-close-tab-function tab)))
(force-mode-line-update))))
+(defun tab-line-tab-context-menu (&optional event)
+ "Pop up the context menu for a tab-line tab."
+ (interactive "e")
+ (let ((menu (make-sparse-keymap (propertize "Context Menu" 'hide t))))
+ (define-key-after menu [close]
+ '(menu-item "Close" tab-line-close-tab :help "Close the tab"))
+ (popup-menu menu event)))
+
+(defun tab-line-context-menu (&optional event)
+ "Pop up the context menu for the tab line."
+ (interactive "e")
+ (let ((menu (make-sparse-keymap (propertize "Context Menu" 'hide t))))
+ (define-key-after menu [close]
+ '(menu-item "New tab" tab-line-new-tab :help "Create a new tab"))
+ (popup-menu menu event)))
+
;;;###autoload
(define-minor-mode tab-line-mode
- "Toggle display of window tab line in the buffer."
+ "Toggle display of tab line in the windows displaying the current buffer."
:lighter nil
- (setq tab-line-format (when tab-line-mode '(:eval (tab-line-format)))))
+ (let ((default-value '(:eval (tab-line-format))))
+ (if tab-line-mode
+ ;; Preserve the existing tab-line set outside of this mode
+ (unless tab-line-format
+ (setq tab-line-format default-value))
+ ;; Reset only values set by this mode
+ (when (equal tab-line-format default-value)
+ (setq tab-line-format nil)))))
(defcustom tab-line-exclude-modes
'(completion-list-mode)
- "List of major modes in which the tab line is not enabled."
+ "List of major modes for which the tab-line display is not enabled.
+Buffers under any of these major modes will not show the tab line in
+their windows, even if `global-tab-line-mode' is enabled."
:type '(repeat symbol)
:group 'tab-line
:version "27.1")
@@ -850,7 +919,12 @@ from the tab line."
(defvar-local tab-line-exclude nil)
(defun tab-line-mode--turn-on ()
- "Turn on `tab-line-mode'."
+ "Turn on `tab-line-mode' in all pertinent buffers.
+Temporary buffers, buffers whose names begin with a space, buffers
+under major modes that are either mentioned in `tab-line-exclude-mode'
+or have a non-nil `tab-line-exclude' property on their symbol,
+and buffers that have a non-nil buffer-local value
+of `tab-line-exclude', are exempt from `tab-line-mode'."
(unless (or (minibufferp)
(string-match-p "\\` " (buffer-name))
(memq major-mode tab-line-exclude-modes)
@@ -865,6 +939,8 @@ from the tab line."
:version "27.1")
+(global-set-key [tab-line down-mouse-3] 'tab-line-context-menu)
+
(global-set-key [tab-line mouse-4] 'tab-line-hscroll-left)
(global-set-key [tab-line mouse-5] 'tab-line-hscroll-right)
(global-set-key [tab-line wheel-up] 'tab-line-hscroll-left)
diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el
index 411c71cd8c4..0ca26f770c4 100644
--- a/lisp/tar-mode.el
+++ b/lisp/tar-mode.el
@@ -360,7 +360,7 @@ of the file header. This is used for \"old GNU\" Tar format."
#'tar-parse-octal-integer "27.1")
(defun tar-parse-octal-integer-safe (string)
- (if (zerop (length string)) (error "empty string"))
+ (if (zerop (length string)) (error "Empty string"))
(mapc (lambda (c)
(if (or (< c ?0) (> c ?7))
(error "`%c' is not an octal digit" c)))
@@ -372,7 +372,7 @@ of the file header. This is used for \"old GNU\" Tar format."
The header will lack a proper checksum; use `tar-header-block-checksum'
to compute one, or request `tar-header-serialize' to do that.
-Other tar-mode facilities may also require the data-start header
+Other `tar-mode' facilities may also require the data-start header
field to be set to a valid value.
If SIZE is not given or nil, it defaults to 0.
@@ -467,8 +467,8 @@ checksum before doing the check."
(defun tar-clip-time-string (time)
(declare (obsolete format-time-string "27.1"))
- (let ((str (current-time-string time)))
- (concat " " (substring str 4 16) (format-time-string " %Y" time))))
+ (let ((system-time-locale "C"))
+ (format-time-string " %b %e %H:%M %Y" time)))
(defun tar-grind-file-mode (mode)
"Construct a `rw-r--r--' string indicating MODE.
@@ -1241,7 +1241,7 @@ for this to be permanent."
(interactive
(list (read-string "New name: "
(tar-header-name (tar-current-descriptor)))))
- (if (string= "" new-name) (error "zero length name"))
+ (if (string= "" new-name) (error "Zero length name"))
(let ((encoded-new-name (encode-coding-string new-name
tar-file-name-coding-system))
(descriptor (tar-current-descriptor))
@@ -1259,7 +1259,7 @@ for this to be permanent."
(setq prefix (substring encoded-new-name 0 (match-beginning 0)))
(setq encoded-new-name (substring encoded-new-name (match-end 0))))
- (if (> (length encoded-new-name) 98) (error "name too long"))
+ (if (> (length encoded-new-name) 98) (error "Name too long"))
(setf (tar-header-name descriptor) new-name)
(tar-alter-one-field 0
(substring (concat encoded-new-name (make-string 99 0)) 0 99))
diff --git a/lisp/tempo.el b/lisp/tempo.el
index 87e274a527c..b722cc04ca2 100644
--- a/lisp/tempo.el
+++ b/lisp/tempo.el
@@ -25,22 +25,22 @@
;;; Commentary:
;; This file provides a simple way to define powerful templates, or
-;; macros, if you wish. It is mainly intended for, but not limited to,
+;; macros, if you wish. It is mainly intended for, but not limited to,
;; other programmers to be used for creating shortcuts for editing
-;; certain kind of documents. It was originally written to be used by
+;; certain kind of documents. It was originally written to be used by
;; a HTML editing mode written by Nelson Minar <nelson@santafe.edu>,
;; and his html-helper-mode.el is probably the best example of how to
;; use this program.
;; A template is defined as a list of items to be inserted in the
-;; current buffer at point. Some of the items can be simple strings,
+;; current buffer at point. Some of the items can be simple strings,
;; while other can control formatting or define special points of
;; interest in the inserted text.
;; If a template defines a "point of interest" that point is inserted
;; in a buffer-local list of "points of interest" that the user can
;; jump between with the commands `tempo-backward-mark' and
-;; `tempo-forward-mark'. If the template definer provides a prompt for
+;; `tempo-forward-mark'. If the template definer provides a prompt for
;; the point, and the variable `tempo-interactive' is non-nil, the
;; user will be prompted for a string to be inserted in the buffer,
;; using the minibuffer.
@@ -49,21 +49,21 @@
;; current region if the template command is called with a prefix (or
;; a non-nil argument).
-;; More flexible templates can be created by including lisp symbols,
+;; More flexible templates can be created by including Lisp symbols,
;; which will be evaluated as variables, or lists, which will be
-;; evaluated as lisp expressions.
+;; evaluated as Lisp expressions.
;; See the documentation for tempo-define-template for the different
;; items that can be used to define a tempo template.
;; One of the more powerful features of tempo templates are automatic
-;; completion. With every template can be assigned a special tag that
+;; completion. With every template can be assigned a special tag that
;; should be recognized by `tempo-complete-tag' and expanded to the
-;; complete template. By default the tags are added to a global list
+;; complete template. By default the tags are added to a global list
;; of template tags, and are matched against the last word before
-;; point. But if you assign your tags to a specific list, you can also
+;; point. But if you assign your tags to a specific list, you can also
;; specify another method for matching text in the buffer against the
-;; tags. In the HTML mode, for instance, the tags are matched against
+;; tags. In the HTML mode, for instance, the tags are matched against
;; the text between the last `<' and point.
;; When defining a template named `foo', a symbol named
@@ -177,7 +177,7 @@ If `tempo-match-finder' is a string, it should contain a regular
expression with at least one \\( \\) pair. When searching for tags,
`tempo-complete-tag' calls `re-search-backward' with this string, and
the string between the first \\( and \\) is used for matching against
-each string in the tag list. If one is found, the whole text between
+each string in the tag list. If one is found, the whole text between
the first \\( and the point is replaced with the inserted template.
You will probably want to include \\=\\= at the end of the regexp to
@@ -247,7 +247,7 @@ The elements in ELEMENTS can be of several types:
happens when you call the template function with a prefix argument.
- (s NAME): Inserts text previously read with the (p ..) construct.
Finds the insertion saved under NAME and inserts it. Acts like `p'
- if tempo-interactive is nil.
+ if `tempo-interactive' is nil.
- `&': If there is only whitespace between the line start and point,
nothing happens. Otherwise a newline is inserted.
- `%': If there is only whitespace between point and end of line,
@@ -319,8 +319,8 @@ mode, ON-REGION is ignored and assumed true if the region is active."
;;; tempo-insert
(defun tempo-insert (element on-region)
- "Insert a template element.
-Insert one element from a template. If ON-REGION is non-nil the `r'
+ "Insert a template ELEMENT.
+Insert one element from a template. If ON-REGION is non-nil the `r'
elements are replaced with the current region.
See documentation for `tempo-define-template' for the kind of elements
@@ -445,7 +445,7 @@ never prompted."
;;; tempo-is-user-element
(defun tempo-is-user-element (element)
- "Tries all the user-defined element handlers in `tempo-user-elements'."
+ "Try all the user-defined element handlers in `tempo-user-elements'."
;; Sigh... I need (some list)
(catch 'found
(mapc (lambda (handler)
@@ -465,7 +465,7 @@ never prompted."
;;; tempo-save-named
(defun tempo-save-named (name data) ; Had an optional prompt for 'v
- "Save some data for later insertion
+ "Save some data for later insertion.
The contents of DATA is saved under the name NAME.
The data can later be retrieved with `tempo-lookup-named'.
@@ -615,7 +615,7 @@ COMPLETION-FUNCTION just sets `tempo-match-finder' locally."
;;; tempo-invalidate-collection
(defun tempo-invalidate-collection (&optional global)
- "Marks the tag collection as obsolete.
+ "Mark the tag collection as obsolete.
Whenever it is needed again it will be rebuilt. If GLOBAL is non-nil,
mark the tag collection of all buffers as obsolete, not just the
current one."
diff --git a/lisp/term.el b/lisp/term.el
index b3870a814d2..698bef08b2d 100644
--- a/lisp/term.el
+++ b/lisp/term.el
@@ -35,7 +35,7 @@
;; This file defines a general command-interpreter-in-a-buffer package
;; (term mode). The idea is that you can build specific process-in-a-buffer
-;; modes on top of term mode -- e.g., lisp, shell, scheme, T, soar, ....
+;; modes on top of term mode -- e.g., Lisp, shell, Scheme, T, soar, ....
;; This way, all these specific packages share a common base functionality,
;; and a common set of bindings, which makes them easier to use (and
;; saves code, implementation time, etc., etc.).
@@ -303,6 +303,7 @@
(require 'ange-ftp)
(require 'cl-lib))
(require 'comint) ; Password regexp.
+(require 'ansi-color)
(require 'ehelp)
(require 'ring)
(require 'shell)
@@ -340,7 +341,7 @@
(defvar term-home-marker) ; Marks the "home" position for cursor addressing.
(defvar term-saved-home-marker nil
"When using alternate sub-buffer,
-contains saved term-home-marker from original sub-buffer.")
+contains saved `term-home-marker' from original sub-buffer.")
(defvar term-start-line-column 0
"(current-column) at start of screen line, or nil if unknown.")
(defvar term-current-column 0 "If non-nil, is cache for (current-column).")
@@ -377,7 +378,7 @@ are not allowed.")
(defvar term-scroll-with-delete nil
"If t, forward scrolling should be implemented by delete to
top-most line(s); and if nil, scrolling should be implemented
-by moving term-home-marker. It is set to t if there is a
+by moving `term-home-marker'. It is set to t if there is a
\(non-default) scroll-region OR the alternate buffer is used.")
(defvar term-pending-delete-marker) ; New user input in line mode
; needs to be deleted, because it gets echoed by the inferior.
@@ -669,7 +670,7 @@ Do not change it directly; use `term-set-escape-char' instead.")
"Keymap used in Term pager mode.")
(defvar term-ptyp t
- "True if communications via pty; false if by pipe. Buffer local.
+ "Non-nil if communications via pty; false if by pipe. Buffer local.
This is to work around a bug in Emacs process signaling.")
(defvar term-last-input-match ""
@@ -710,13 +711,20 @@ Buffer local variable.")
(defvar term-ansi-at-save-pwd nil)
(defvar term-ansi-at-save-anon nil)
(defvar term-ansi-current-bold nil)
+(defvar term-ansi-current-faint nil)
+(defvar term-ansi-current-italic nil)
+(defvar term-ansi-current-underline nil)
+(defvar term-ansi-current-slow-blink nil)
+(defvar term-ansi-current-fast-blink nil)
(defvar term-ansi-current-color 0)
(defvar term-ansi-face-already-done nil)
(defvar term-ansi-current-bg-color 0)
-(defvar term-ansi-current-underline nil)
(defvar term-ansi-current-reverse nil)
(defvar term-ansi-current-invisible nil)
+(make-obsolete-variable 'term-ansi-face-already-done
+ "it doesn't have any effect." "29.1")
+
;;; Faces
(defvar ansi-term-color-vector
[term
@@ -727,7 +735,15 @@ Buffer local variable.")
term-color-blue
term-color-magenta
term-color-cyan
- term-color-white])
+ term-color-white
+ term-color-bright-black
+ term-color-bright-red
+ term-color-bright-green
+ term-color-bright-yellow
+ term-color-bright-blue
+ term-color-bright-magenta
+ term-color-bright-cyan
+ term-color-bright-white])
(defcustom term-default-fg-color nil
"If non-nil, default color for foreground in Term mode."
@@ -752,54 +768,136 @@ Buffer local variable.")
:group 'term)
(defface term-bold
- '((t :bold t))
+ '((t :inherit ansi-color-bold))
"Default face to use for bold text."
- :group 'term)
+ :group 'term
+ :version "28.1")
+
+(defface term-faint
+ '((t :inherit ansi-color-faint))
+ "Default face to use for faint text."
+ :group 'term
+ :version "29.1")
+
+(defface term-italic
+ '((t :inherit ansi-color-italic))
+ "Default face to use for italic text."
+ :group 'term
+ :version "29.1")
(defface term-underline
- '((t :underline t))
+ '((t :inherit ansi-color-underline))
"Default face to use for underlined text."
- :group 'term)
+ :group 'term
+ :version "28.1")
+
+(defface term-slow-blink
+ '((t :inherit ansi-color-slow-blink))
+ "Default face to use for slowly blinking text."
+ :group 'term
+ :version "29.1")
+
+(defface term-fast-blink
+ '((t :inherit ansi-color-fast-blink))
+ "Default face to use for rapidly blinking text."
+ :group 'term
+ :version "29.1")
(defface term-color-black
- '((t :foreground "black" :background "black"))
+ '((t :inherit ansi-color-black))
"Face used to render black color code."
- :group 'term)
+ :group 'term
+ :version "28.1")
(defface term-color-red
- '((t :foreground "red3" :background "red3"))
+ '((t :inherit ansi-color-red))
"Face used to render red color code."
- :group 'term)
+ :group 'term
+ :version "28.1")
(defface term-color-green
- '((t :foreground "green3" :background "green3"))
+ '((t :inherit ansi-color-green))
"Face used to render green color code."
- :group 'term)
+ :group 'term
+ :version "28.1")
(defface term-color-yellow
- '((t :foreground "yellow3" :background "yellow3"))
+ '((t :inherit ansi-color-yellow))
"Face used to render yellow color code."
- :group 'term)
+ :group 'term
+ :version "28.1")
(defface term-color-blue
- '((t :foreground "blue2" :background "blue2"))
+ '((t :inherit ansi-color-blue))
"Face used to render blue color code."
- :group 'term)
+ :group 'term
+ :version "28.1")
(defface term-color-magenta
- '((t :foreground "magenta3" :background "magenta3"))
+ '((t :inherit ansi-color-magenta))
"Face used to render magenta color code."
- :group 'term)
+ :group 'term
+ :version "28.1")
(defface term-color-cyan
- '((t :foreground "cyan3" :background "cyan3"))
+ '((t :inherit ansi-color-cyan))
"Face used to render cyan color code."
- :group 'term)
+ :group 'term
+ :version "28.1")
(defface term-color-white
- '((t :foreground "white" :background "white"))
+ '((t :inherit ansi-color-white))
"Face used to render white color code."
- :group 'term)
+ :group 'term
+ :version "28.1")
+
+(defface term-color-bright-black
+ '((t :inherit ansi-color-bright-black))
+ "Face used to render bright black color code."
+ :group 'term
+ :version "28.1")
+
+(defface term-color-bright-red
+ '((t :inherit ansi-color-bright-red))
+ "Face used to render bright red color code."
+ :group 'term
+ :version "28.1")
+
+(defface term-color-bright-green
+ '((t :inherit ansi-color-bright-green))
+ "Face used to render bright green color code."
+ :group 'term
+ :version "28.1")
+
+(defface term-color-bright-yellow
+ '((t :inherit ansi-color-bright-yellow))
+ "Face used to render bright yellow color code."
+ :group 'term
+ :version "28.1")
+
+(defface term-color-bright-blue
+ '((t :inherit ansi-color-bright-blue))
+ "Face used to render bright blue color code."
+ :group 'term
+ :version "28.1")
+
+(defface term-color-bright-magenta
+ '((t :inherit ansi-color-bright-magenta))
+ "Face used to render bright magenta color code."
+ :group 'term
+ :version "28.1")
+
+(defface term-color-bright-cyan
+ '((t :inherit ansi-color-bright-cyan))
+ "Face used to render bright cyan color code."
+ :group 'term
+ :version "28.1")
+
+(defface term-color-bright-white
+ '((t :inherit ansi-color-bright-white))
+ "Face used to render bright white color code."
+ :group 'term
+ :version "28.1")
(defcustom term-buffer-maximum-size 8192
"The maximum size in lines for term buffers.
@@ -968,15 +1066,15 @@ is buffer-local."
(defun term-ansi-reset ()
(setq term-current-face 'term)
- (setq term-ansi-current-underline nil)
(setq term-ansi-current-bold nil)
+ (setq term-ansi-current-faint nil)
+ (setq term-ansi-current-italic nil)
+ (setq term-ansi-current-underline nil)
+ (setq term-ansi-current-slow-blink nil)
+ (setq term-ansi-current-fast-blink nil)
(setq term-ansi-current-reverse nil)
(setq term-ansi-current-color 0)
(setq term-ansi-current-invisible nil)
- ;; Stefan thought this should be t, but could not remember why.
- ;; Setting it to t seems to cause bug#11785. Setting it to nil
- ;; again to see if there are other consequences...
- (setq term-ansi-face-already-done nil)
(setq term-ansi-current-bg-color 0))
(define-derived-mode term-mode fundamental-mode "Term"
@@ -1228,8 +1326,7 @@ Entry to this mode runs the hooks on `term-mode-hook'."
(process-send-string proc chars))))
(defun term-send-raw ()
- "Send the last character typed through the terminal-emulator
-without any interpretation."
+ "Send last typed character to the terminal-emulator without any interpretation."
(interactive)
(let ((keys (this-command-keys)))
(term-send-raw-string (string (aref keys (1- (length keys)))))))
@@ -1401,8 +1498,8 @@ Called as a buffer-local `read-only-mode-hook' function."
(force-mode-line-update))
(defun term-check-proc (buffer)
- "True if there is a process associated w/buffer BUFFER, and it
-is alive. BUFFER can be either a buffer or the name of one."
+ "Non-nil if there is a process associated w/buffer BUFFER, and it is alive.
+BUFFER can be either a buffer or the name of one."
(let ((proc (get-buffer-process buffer)))
(and proc (memq (process-status proc) '(run stop open listen connect)))))
@@ -1429,12 +1526,11 @@ The buffer is in Term mode; see `term-mode' for the
commands to use in that buffer.
\\<term-raw-map>Type \\[switch-to-buffer] to switch to another buffer."
- (interactive (list (read-from-minibuffer "Run program: "
- (or explicit-shell-file-name
- (getenv "ESHELL")
- shell-file-name))))
+ (interactive (list (read-shell-command "Run program: "
+ (or explicit-shell-file-name
+ (getenv "ESHELL")
+ shell-file-name))))
(set-buffer (make-term "terminal" program))
- (term-mode)
(term-char-mode)
(switch-to-buffer "*terminal*"))
@@ -1516,10 +1612,12 @@ Using \"emacs\" loses, because bash disables editing if $TERM == emacs.")
:nd=\\E[C:up=\\E[A:ce=\\E[K:ho=\\E[H:pt\
:al=\\E[L:dl=\\E[M:DL=\\E[%%dM:AL=\\E[%%dL:cs=\\E[%%i%%d;%%dr:sf=^J\
:dc=\\E[P:DC=\\E[%%dP:IC=\\E[%%d@:im=\\E[4h:ei=\\E[4l:mi:\
+:mb=\\E[5m:mh=\\E[2m:ZR=\\E[23m:ZH=\\E[3m\
:so=\\E[7m:se=\\E[m:us=\\E[4m:ue=\\E[m:md=\\E[1m:mr=\\E[7m:me=\\E[m\
:UP=\\E[%%dA:DO=\\E[%%dB:LE=\\E[%%dD:RI=\\E[%%dC\
:kl=\\EOD:kd=\\EOB:kr=\\EOC:ku=\\EOA:kN=\\E[6~:kP=\\E[5~:@7=\\E[4~:kh=\\E[1~\
-:mk=\\E[8m:cb=\\E[1K:op=\\E[39;49m:Co#8:pa#64:AB=\\E[4%%dm:AF=\\E[3%%dm:cr=^M\
+:mk=\\E[8m:cb=\\E[1K:op=\\E[39;49m:Co#256:pa#32767\
+:AB=\\E[48;5;%%dm:AF=\\E[38;5;%%dm:cr=^M\
:bl=^G:do=^J:le=^H:ta=^I:se=\\E[27m:ue=\\E[24m\
:kb=^?:kD=^[[3~:sc=\\E7:rc=\\E8:r1=\\Ec:"
;; : -undefine ic
@@ -1538,7 +1636,7 @@ Using \"emacs\" loses, because bash disables editing if $TERM == emacs.")
Some other integer if Bash is new or not in use.
Nil if unknown.")
(defun term--bash-needs-EMACSp ()
- "t if Bash is old, nil if it is new or not in use."
+ "Return t if Bash is old, nil if it is new or not in use."
(eq 43
(or term--bash-needs-EMACS-status
(setf
@@ -2107,17 +2205,17 @@ The values of `term-get-old-input', `term-input-filter-functions', and
in the buffer. E.g.,
If the interpreter is the csh,
- term-get-old-input is the default: take the current line, discard any
- initial string matching regexp term-prompt-regexp.
- term-input-filter-functions monitors input for \"cd\", \"pushd\", and
+ `term-get-old-input' is the default: take the current line, discard any
+ initial string matching regexp `term-prompt-regexp'.
+ `term-input-filter-functions' monitors input for \"cd\", \"pushd\", and
\"popd\" commands. When it sees one, it cd's the buffer.
- term-input-filter is the default: returns t if the input isn't all white
+ `term-input-filter' is the default: returns t if the input isn't all white
space.
If the term is Lucid Common Lisp,
- term-get-old-input snarfs the sexp ending at point.
- term-input-filter-functions does nothing.
- term-input-filter returns nil if the input matches input-filter-regexp,
+ `term-get-old-input' snarfs the sexp ending at point.
+ `term-input-filter-functions' does nothing.
+ `term-input-filter' returns nil if the input matches input-filter-regexp,
which matches (1) all whitespace (2) :a, :c, etc.
Similarly for Soar, Scheme, etc."
@@ -2310,7 +2408,14 @@ Checks if STRING contains a password prompt as defined by
(when (term-in-line-mode)
(when (let ((case-fold-search t))
(string-match comint-password-prompt-regexp string))
- (term-send-invisible (read-passwd string)))))
+ ;; Use `run-at-time' in order not to pause execution of the
+ ;; process filter with a minibuffer
+ (run-at-time
+ 0 nil
+ (lambda (current-buf)
+ (with-current-buffer current-buf
+ (term-send-invisible (read-passwd string))))
+ (current-buffer)))))
;;; Low-level process communication
@@ -2403,8 +2508,7 @@ Useful if you accidentally suspend the top-level process."
(kill-region pmark (point)))))
(defun term-delchar-or-maybe-eof (arg)
- "Delete ARG characters forward, or send an EOF to process if at end of
-buffer."
+ "Delete ARG characters forward, or send an EOF to process if at end of buffer."
(interactive "p")
(if (eobp)
(process-send-eof)
@@ -3040,30 +3144,34 @@ See `term-prompt-regexp'."
(term-horizontal-column)
term-ansi-current-bg-color
term-ansi-current-bold
+ term-ansi-current-faint
+ term-ansi-current-italic
+ term-ansi-current-underline
+ term-ansi-current-slow-blink
+ term-ansi-current-fast-blink
term-ansi-current-color
term-ansi-current-invisible
term-ansi-current-reverse
- term-ansi-current-underline
term-current-face)))
(?8 ;; Restore cursor (terminfo: rc, [ctlseqs]
;; "DECRC").
(when term-saved-cursor
(term-goto (nth 0 term-saved-cursor)
(nth 1 term-saved-cursor))
- (setq term-ansi-current-bg-color
- (nth 2 term-saved-cursor)
- term-ansi-current-bold
- (nth 3 term-saved-cursor)
- term-ansi-current-color
- (nth 4 term-saved-cursor)
- term-ansi-current-invisible
- (nth 5 term-saved-cursor)
- term-ansi-current-reverse
- (nth 6 term-saved-cursor)
- term-ansi-current-underline
- (nth 7 term-saved-cursor)
- term-current-face
- (nth 8 term-saved-cursor))))
+ (pcase-setq
+ `( ,_ ,_
+ ,term-ansi-current-bg-color
+ ,term-ansi-current-bold
+ ,term-ansi-current-faint
+ ,term-ansi-current-italic
+ ,term-ansi-current-underline
+ ,term-ansi-current-slow-blink
+ ,term-ansi-current-fast-blink
+ ,term-ansi-current-color
+ ,term-ansi-current-invisible
+ ,term-ansi-current-reverse
+ ,term-current-face)
+ term-saved-cursor)))
(?c ;; \Ec - Reset (terminfo: rs1, [ctlseqs] "RIS").
;; This is used by the "clear" program.
(term-reset-terminal))
@@ -3126,7 +3234,7 @@ See `term-prompt-regexp'."
(setq win (next-window win nil t))
(when (eq (window-buffer win) (process-buffer proc))
(let ((scroll term-scroll-to-bottom-on-output))
- (select-window win)
+ (select-window win t)
(when (or (= (point) save-marker)
(eq scroll t) (eq scroll 'all)
;; Maybe user wants point to jump to the end.
@@ -3171,7 +3279,7 @@ See `term-prompt-regexp'."
Set in `pre-command-hook' in char mode by `term-set-goto-process-mark'.")
(defun term-set-goto-process-mark ()
- "Sets `term-goto-process-mark'.
+ "Set `term-goto-process-mark'.
Always set to nil if `term-char-mode-point-at-process-mark' is nil.
@@ -3221,110 +3329,141 @@ option is enabled. See `term-set-goto-process-mark'."
(setq term-current-row 0)
(setq term-current-column 1)
(term--reset-scroll-region)
- (setq term-insert-mode nil)
- ;; FIXME: No idea why this is here, it looks wrong. --Stef
- (setq term-ansi-face-already-done nil))
+ (setq term-insert-mode nil))
+
+(defun term--color-as-hex (for-foreground)
+ "Return the current ANSI color as a hexadecimal color string.
+Use the current background color if FOR-FOREGROUND is nil,
+otherwise use the current foreground color."
+ (let ((color (if for-foreground term-ansi-current-color
+ term-ansi-current-bg-color)))
+ (or (ansi-color--code-as-hex (1- color))
+ (progn
+ (and ansi-color-bold-is-bright term-ansi-current-bold
+ (<= 1 color 8)
+ (setq color (+ color 8)))
+ (if for-foreground
+ (face-foreground (elt ansi-term-color-vector color)
+ nil 'default)
+ (face-background (elt ansi-term-color-vector color)
+ nil 'default))))))
;; New function to deal with ansi colorized output, as you can see you can
;; have any bold/underline/fg/bg/reverse combination. -mm
(defun term-handle-colors-array (parameter)
- (cond
-
- ;; Bold (terminfo: bold)
- ((eq parameter 1)
- (setq term-ansi-current-bold t))
-
- ;; Underline
- ((eq parameter 4)
- (setq term-ansi-current-underline t))
-
- ;; Blink (unsupported by Emacs), will be translated to bold.
- ;; This may change in the future though.
- ((eq parameter 5)
- (setq term-ansi-current-bold t))
-
- ;; Reverse (terminfo: smso)
- ((eq parameter 7)
- (setq term-ansi-current-reverse t))
-
- ;; Invisible
- ((eq parameter 8)
- (setq term-ansi-current-invisible t))
-
- ;; Reset underline (terminfo: rmul)
- ((eq parameter 24)
- (setq term-ansi-current-underline nil))
-
- ;; Reset reverse (terminfo: rmso)
- ((eq parameter 27)
- (setq term-ansi-current-reverse nil))
-
- ;; Foreground
- ((and (>= parameter 30) (<= parameter 37))
- (setq term-ansi-current-color (- parameter 29)))
-
- ;; Reset foreground
- ((eq parameter 39)
- (setq term-ansi-current-color 0))
-
- ;; Background
- ((and (>= parameter 40) (<= parameter 47))
- (setq term-ansi-current-bg-color (- parameter 39)))
-
- ;; Reset background
- ((eq parameter 49)
- (setq term-ansi-current-bg-color 0))
-
- ;; 0 (Reset) or unknown (reset anyway)
- (t
- (term-ansi-reset)))
-
- ;; (message "Debug: U-%d R-%d B-%d I-%d D-%d F-%d B-%d"
- ;; term-ansi-current-underline
- ;; term-ansi-current-reverse
- ;; term-ansi-current-bold
- ;; term-ansi-current-invisible
- ;; term-ansi-face-already-done
- ;; term-ansi-current-color
- ;; term-ansi-current-bg-color)
-
- (unless term-ansi-face-already-done
+ (declare (obsolete term--handle-colors-list "29.1"))
+ (term--handle-colors-list (list parameter)))
+
+(defun term--handle-colors-list (parameters)
+ (while parameters
+ (pcase (pop parameters)
+ (1 (setq term-ansi-current-bold t)) ; (terminfo: bold)
+ (2 (setq term-ansi-current-faint t)) ; (terminfo: dim)
+ (3 (setq term-ansi-current-italic t)) ; (terminfo: sitm)
+ (4 (setq term-ansi-current-underline t)) ; (terminfo: smul)
+ (5 (setq term-ansi-current-slow-blink t)) ; (terminfo: blink)
+ (6 (setq term-ansi-current-fast-blink t))
+ (7 (setq term-ansi-current-reverse t)) ; (terminfo: smso, rev)
+ (8 (setq term-ansi-current-invisible t)) ; (terminfo: invis)
+ (21 (setq term-ansi-current-bold nil))
+ (22 (setq term-ansi-current-bold nil)
+ (setq term-ansi-current-faint nil))
+ (23 (setq term-ansi-current-italic nil)) ; (terminfo: ritm)
+ (24 (setq term-ansi-current-underline nil)) ; (terminfo: rmul)
+ (25 (setq term-ansi-current-slow-blink nil)
+ (setq term-ansi-current-fast-blink nil))
+ (27 (setq term-ansi-current-reverse nil)) ; (terminfo: rmso)
+
+ ;; Foreground (terminfo: setaf)
+ ((and param (guard (<= 30 param 37)))
+ (setq term-ansi-current-color (- param 29)))
+
+ ;; Bright foreground (terminfo: setaf)
+ ((and param (guard (<= 90 param 97)))
+ (setq term-ansi-current-color (- param 81)))
+
+ ;; Extended foreground (terminfo: setaf)
+ (38
+ (pcase (pop parameters)
+ ;; 256 color
+ (5 (if (setq term-ansi-current-color (pop parameters))
+ (cl-incf term-ansi-current-color)
+ (term-ansi-reset)))
+ ;; Full 24-bit color
+ (2 (cl-loop with color = (1+ 256) ; Base
+ for i from 16 downto 0 by 8
+ if (pop parameters)
+ do (setq color (+ color (ash it i)))
+ else return (term-ansi-reset)
+ finally
+ (if (> color (+ 1 256 #xFFFFFF))
+ (term-ansi-reset)
+ (setq term-ansi-current-color color))))
+ (_ (term-ansi-reset))))
+
+ ;; Reset foreground (terminfo: op)
+ (39 (setq term-ansi-current-color 0))
+
+ ;; Background (terminfo: setab)
+ ((and param (guard (<= 40 param 47)))
+ (setq term-ansi-current-bg-color (- param 39)))
+
+ ;; Bright background (terminfo: setab)
+ ((and param (guard (<= 100 param 107)))
+ (setq term-ansi-current-bg-color (- param 91)))
+
+ ;; Extended background (terminfo: setab)
+ (48
+ (pcase (pop parameters)
+ ;; 256 color
+ (5 (if (setq term-ansi-current-bg-color (pop parameters))
+ (cl-incf term-ansi-current-bg-color)
+ (term-ansi-reset)))
+ ;; Full 24-bit color
+ (2 (cl-loop with color = (1+ 256) ; Base
+ for i from 16 downto 0 by 8
+ if (pop parameters)
+ do (setq color (+ color (ash it i)))
+ else return (term-ansi-reset)
+ finally
+ (if (> color (+ 1 256 #xFFFFFF))
+ (term-ansi-reset)
+ (setq term-ansi-current-bg-color color))))
+ (_ (term-ansi-reset))))
+
+ ;; Reset background (terminfo: op)
+ (49 (setq term-ansi-current-bg-color 0))
+
+ ;; 0 (Reset) (terminfo: sgr0) or unknown (reset anyway)
+ (_ (term-ansi-reset))))
+
+ (let (fg bg)
(if term-ansi-current-invisible
- (let ((color
- (if term-ansi-current-reverse
- (face-foreground
- (elt ansi-term-color-vector term-ansi-current-color)
- nil 'default)
- (face-background
- (elt ansi-term-color-vector term-ansi-current-bg-color)
- nil 'default))))
- (setq term-current-face
- (list :background color
- :foreground color))
- ) ;; No need to bother with anything else if it's invisible.
- (setq term-current-face
- (list :foreground
- (face-foreground
- (elt ansi-term-color-vector term-ansi-current-color)
- nil 'default)
- :background
- (face-background
- (elt ansi-term-color-vector term-ansi-current-bg-color)
- nil 'default)
- :inverse-video term-ansi-current-reverse))
-
- (when term-ansi-current-bold
- (setq term-current-face
- `(,term-current-face :inherit term-bold)))
-
- (when term-ansi-current-underline
- (setq term-current-face
- `(,term-current-face :inherit term-underline)))))
-
- ;; (message "Debug %S" term-current-face)
- ;; FIXME: shouldn't we set term-ansi-face-already-done to t here? --Stef
- (setq term-ansi-face-already-done nil))
+ (setq bg (term--color-as-hex term-ansi-current-reverse)
+ fg bg)
+ (setq fg (term--color-as-hex t)
+ bg (term--color-as-hex nil)))
+ (setq term-current-face
+ `( :foreground ,fg
+ :background ,bg
+ ,@(unless term-ansi-current-invisible
+ (list :inverse-video term-ansi-current-reverse)))))
+
+ (setq term-current-face
+ `(,term-current-face
+ ,@(when term-ansi-current-bold
+ '(term-bold))
+ ,@(when term-ansi-current-faint
+ '(term-faint))
+ ,@(when term-ansi-current-italic
+ '(term-italic))
+ ,@(when term-ansi-current-underline
+ '(term-underline))
+ ,@(when term-ansi-current-slow-blink
+ '(term-slow-blink))
+ ,@(when term-ansi-current-fast-blink
+ '(term-fast-blink)))))
;; Handle a character assuming (eq terminal-state 2) -
@@ -3410,9 +3549,9 @@ option is enabled. See `term-set-goto-process-mark'."
;; Modified to allow ansi coloring -mm
;; \E[m - Set/reset modes, set bg/fg
- ;;(terminfo: smso,rmso,smul,rmul,rev,bold,sgr0,invis,op,setab,setaf)
+ ;;(terminfo: smso,rmso,smul,rmul,rev,bold,dim,sitm,ritm,blink,sgr0,invis,op,setab,setaf)
((eq char ?m)
- (mapc #'term-handle-colors-array params))
+ (term--handle-colors-list params))
;; \E[6n - Report cursor position (terminfo: u7)
((eq char ?n)
@@ -3430,7 +3569,7 @@ option is enabled. See `term-set-goto-process-mark'."
(t)))
(defun term--reset-scroll-region ()
- "Sets the scroll region to the full height of the terminal."
+ "Set the scroll region to the full height of the terminal."
(term-set-scroll-region 0 (term--last-line)))
(defun term-set-scroll-region (top bottom)
@@ -3793,7 +3932,7 @@ all pending output has been dealt with."))
(defun term-erase-in-display (kind)
"Erase (that is blank out) part of the window.
-If KIND is 0, erase from (point) to (point-max);
+If KIND is 0, erase from point to point-max;
if KIND is 1, erase from home to point; else erase from home to point-max."
(term-handle-deferred-scroll)
(cond ((eq kind 0)
@@ -4322,8 +4461,7 @@ Try to be nice by providing useful defaults and history."
"Speed (default nil = set by port): ")
(h
(format-prompt "Speed" (format "%s b/s" h)))
- (t
- (format "Speed (b/s): ")))
+ (t "Speed (b/s): "))
nil nil nil '(history . 1) nil nil)))
(when (or (null x) (and (stringp x) (zerop (length x))))
(setq x h))
diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el
new file mode 100644
index 00000000000..3c4d00f7f99
--- /dev/null
+++ b/lisp/term/haiku-win.el
@@ -0,0 +1,139 @@
+;;; haiku-win.el --- set up windowing on Haiku -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021 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:
+
+;; Support for using Haiku's BeOS derived windowing system.
+
+;;; Code:
+
+(eval-when-compile (require 'cl-lib))
+(unless (featurep 'haiku)
+ (error "%s: Loading haiku-win without having Haiku"
+ invocation-name))
+
+;; Documentation-purposes only: actually loaded in loadup.el.
+(require 'frame)
+(require 'mouse)
+(require 'scroll-bar)
+(require 'menu-bar)
+(require 'fontset)
+(require 'dnd)
+
+(add-to-list 'display-format-alist '(".*" . haiku-win))
+
+;;;; Command line argument handling.
+
+(defvar x-invocation-args)
+(defvar x-command-line-resources)
+
+(defvar haiku-initialized)
+
+(declare-function x-open-connection "haikufns.c")
+(declare-function x-handle-args "common-win")
+(declare-function haiku-selection-data "haikuselect.c")
+(declare-function haiku-selection-put "haikuselect.c")
+(declare-function haiku-selection-targets "haikuselect.c")
+(declare-function haiku-put-resource "haikufns.c")
+
+(defun haiku--handle-x-command-line-resources (command-line-resources)
+ "Handle command line X resources specified with the option `-xrm'.
+The resources should be a list of strings in COMMAND-LINE-RESOURCES."
+ (dolist (s command-line-resources)
+ (let ((components (split-string s ":")))
+ (when (car components)
+ (haiku-put-resource (car components)
+ (string-trim-left
+ (mapconcat #'identity (cdr components) ":")))))))
+
+(cl-defmethod window-system-initialization (&context (window-system haiku)
+ &optional display)
+ "Set up the window system. WINDOW-SYSTEM must be HAIKU.
+DISPLAY may be set to the name of a display that will be initialized."
+ (cl-assert (not haiku-initialized))
+
+ (create-default-fontset)
+ (when x-command-line-resources
+ (haiku--handle-x-command-line-resources
+ (split-string x-command-line-resources "\n")))
+ (x-open-connection (or display "be") x-command-line-resources t)
+ (setq haiku-initialized t))
+
+(cl-defmethod frame-creation-function (params &context (window-system haiku))
+ (x-create-frame-with-faces params))
+
+(cl-defmethod handle-args-function (args &context (window-system haiku))
+ (x-handle-args args))
+
+(defun haiku--selection-type-to-mime (type)
+ "Convert symbolic selection type TYPE to its MIME equivalent.
+If TYPE is nil, return \"text/plain\"."
+ (cond
+ ((memq type '(TEXT COMPOUND_TEXT STRING UTF8_STRING)) "text/plain")
+ ((stringp type) type)
+ ((symbolp type) (symbol-name type))
+ (t "text/plain")))
+
+(cl-defmethod gui-backend-get-selection (type data-type
+ &context (window-system haiku))
+ (if (eq data-type 'TARGETS)
+ (apply #'vector (mapcar #'intern
+ (haiku-selection-targets type)))
+ (haiku-selection-data type (haiku--selection-type-to-mime data-type))))
+
+(cl-defmethod gui-backend-set-selection (type value
+ &context (window-system haiku))
+ (haiku-selection-put type "text/plain" value t))
+
+(cl-defmethod gui-backend-selection-exists-p (selection
+ &context (window-system haiku))
+ (haiku-selection-data selection "text/plain"))
+
+(cl-defmethod gui-backend-selection-owner-p (_
+ &context (window-system haiku))
+ t)
+
+(declare-function haiku-read-file-name "haikufns.c")
+
+(defun x-file-dialog (prompt dir default_filename mustmatch only_dir_p)
+ "SKIP: real doc in xfns.c."
+ (if (eq (framep-on-display (selected-frame)) 'haiku)
+ (haiku-read-file-name prompt (selected-frame)
+ (or dir (and default_filename
+ (file-name-directory default_filename)))
+ mustmatch only_dir_p
+ (file-name-nondirectory default_filename))
+ (error "x-file-dialog on a tty frame")))
+
+(defun haiku-dnd-handle-drag-n-drop-event (event)
+ "Handle specified drag-n-drop EVENT."
+ (interactive "e")
+ (let* ((string (caddr event))
+ (window (posn-window (event-start event))))
+ (with-selected-window window
+ (raise-frame)
+ (dnd-handle-one-url window 'private (concat "file:" string)))))
+
+(define-key special-event-map [drag-n-drop]
+ 'haiku-dnd-handle-drag-n-drop-event)
+
+(provide 'haiku-win)
+(provide 'term/haiku-win)
+
+;;; haiku-win.el ends here
diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el
index af1e388c2a3..67a417c1161 100644
--- a/lisp/term/ns-win.el
+++ b/lisp/term/ns-win.el
@@ -586,8 +586,8 @@ string dropped into the current buffer."
;; Based on a function by David Reitter <dreitter@inf.ed.ac.uk> ;
;; see https://lists.gnu.org/r/emacs-devel/2005-09/msg00681.html .
(defun ns-toggle-toolbar (&optional frame)
- "Switches the tool bar on and off in frame FRAME.
- If FRAME is nil, the change applies to the selected frame."
+ "Switch the tool bar on and off in frame FRAME.
+If FRAME is nil, the change applies to the selected frame."
(interactive)
(modify-frame-parameters
frame (list (cons 'tool-bar-lines
@@ -867,10 +867,10 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.")
;; For Darwin nothing except UTF-8 makes sense.
(when (eq system-type 'darwin)
(add-hook 'before-init-hook
- #'(lambda ()
- (setq locale-coding-system 'utf-8-unix)
- (setq default-process-coding-system
- '(utf-8-unix . utf-8-unix)))))
+ (lambda ()
+ (setq locale-coding-system 'utf-8-unix)
+ (setq default-process-coding-system
+ '(utf-8-unix . utf-8-unix)))))
;; Mac OS X Lion introduces PressAndHold, which is unsupported by this port.
;; See this thread for more details:
diff --git a/lisp/term/pgtk-win.el b/lisp/term/pgtk-win.el
new file mode 100644
index 00000000000..689a5e595a5
--- /dev/null
+++ b/lisp/term/pgtk-win.el
@@ -0,0 +1,504 @@
+;;; xterm.el --- define function key sequences and standard colors for xterm -*- lexical-binding: t -*-
+
+;; Copyright (C) 1995, 2001-2020 Free Software Foundation, Inc.
+
+;; Author: FSF
+;; Keywords: terminals
+
+;; 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:
+(eval-when-compile (require 'cl-lib))
+(or (featurep 'pgtk)
+ (error "%s: Loading pgtk-win.el but not compiled for pure Gtk+-3."
+ invocation-name))
+
+;; Documentation-purposes only: actually loaded in loadup.el.
+(require 'term/common-win)
+(require 'frame)
+(require 'mouse)
+(require 'scroll-bar)
+(require 'faces)
+(require 'menu-bar)
+(require 'fontset)
+(require 'dnd)
+
+(defgroup pgtk nil
+ "Pure-GTK specific features."
+ :group 'environment)
+
+;;;; Command line argument handling.
+
+(defvar x-invocation-args)
+;; Set in term/common-win.el; currently unused by Gtk's x-open-connection.
+(defvar x-command-line-resources)
+
+;; pgtkterm.c.
+(defvar pgtk-input-file)
+
+(declare-function pgtk-use-im-context "pgtkim.c")
+(defvar pgtk-use-im-context-on-new-connection)
+
+(defun pgtk-handle-nxopen (_switch &optional temp)
+ (setq unread-command-events (append unread-command-events
+ (if temp '(pgtk-open-temp-file)
+ '(pgtk-open-file)))
+ pgtk-input-file (append pgtk-input-file (list (pop x-invocation-args)))))
+
+(defun pgtk-handle-nxopentemp (switch)
+ (pgtk-handle-nxopen switch t))
+
+(defun pgtk-ignore-1-arg (_switch)
+ (setq x-invocation-args (cdr x-invocation-args)))
+
+;;;; File handling.
+
+(declare-function pgtk-hide-emacs "pgtkfns.c" (on))
+
+
+(defun pgtk-drag-n-drop (event &optional new-frame force-text)
+ "Edit the files listed in the drag-n-drop EVENT.
+Switch to a buffer editing the last file dropped."
+ (interactive "e")
+ (let* ((window (posn-window (event-start event)))
+ (arg (car (cdr (cdr event))))
+ (type (car arg))
+ (data (car (cdr arg)))
+ (url-or-string (cond ((eq type 'file)
+ (concat "file:" data))
+ (t data))))
+ (set-frame-selected-window nil window)
+ (when new-frame
+ (select-frame (make-frame)))
+ (raise-frame)
+ (setq window (selected-window))
+ (if force-text
+ (dnd-insert-text window 'private data)
+ (dnd-handle-one-url window 'private url-or-string))))
+
+
+(defun pgtk-drag-n-drop-other-frame (event)
+ "Edit the files listed in the drag-n-drop EVENT, in other frames.
+May create new frames, or reuse existing ones. The frame editing
+the last file dropped is selected."
+ (interactive "e")
+ (pgtk-drag-n-drop event t))
+
+(defun pgtk-drag-n-drop-as-text (event)
+ "Drop the data in EVENT as text."
+ (interactive "e")
+ (pgtk-drag-n-drop event nil t))
+
+(defun pgtk-drag-n-drop-as-text-other-frame (event)
+ "Drop the data in EVENT as text in a new frame."
+ (interactive "e")
+ (pgtk-drag-n-drop event t t))
+
+(global-set-key [drag-n-drop] 'pgtk-drag-n-drop)
+(global-set-key [C-drag-n-drop] 'pgtk-drag-n-drop-other-frame)
+(global-set-key [M-drag-n-drop] 'pgtk-drag-n-drop-as-text)
+(global-set-key [C-M-drag-n-drop] 'pgtk-drag-n-drop-as-text-other-frame)
+
+;;;; Frame-related functions.
+
+;; pgtkterm.c
+(defvar pgtk-alternate-modifier)
+(defvar pgtk-right-alternate-modifier)
+(defvar pgtk-right-command-modifier)
+(defvar pgtk-right-control-modifier)
+
+;; You say tomAYto, I say tomAHto..
+(with-no-warnings
+ (defvaralias 'pgtk-option-modifier 'pgtk-alternate-modifier)
+ (defvaralias 'pgtk-right-option-modifier 'pgtk-right-alternate-modifier))
+
+(defun pgtk-do-hide-emacs ()
+ (interactive)
+ (pgtk-hide-emacs t))
+
+(declare-function pgtk-hide-others "pgtkfns.c" ())
+
+(defun pgtk-do-hide-others ()
+ (interactive)
+ (pgtk-hide-others))
+
+(declare-function pgtk-emacs-info-panel "pgtkfns.c" ())
+
+(defun pgtk-do-emacs-info-panel ()
+ (interactive)
+ (pgtk-emacs-info-panel))
+
+(defun pgtk-next-frame ()
+ "Switch to next visible frame."
+ (interactive)
+ (other-frame 1))
+
+(defun pgtk-prev-frame ()
+ "Switch to previous visible frame."
+ (interactive)
+ (other-frame -1))
+
+;; Frame will be focused anyway, so select it
+;; (if this is not done, mode line is dimmed until first interaction)
+;; FIXME: Sounds like we're working around a bug in the underlying code.
+(add-hook 'after-make-frame-functions 'select-frame)
+
+(defvar tool-bar-mode)
+(declare-function tool-bar-mode "tool-bar" (&optional arg))
+
+;; Based on a function by David Reitter <dreitter@inf.ed.ac.uk> ;
+;; see https://lists.gnu.org/archive/html/emacs-devel/2005-09/msg00681.html .
+(defun pgtk-toggle-toolbar (&optional frame)
+ "Switches the tool bar on and off in frame FRAME.
+ If FRAME is nil, the change applies to the selected frame."
+ (interactive)
+ (modify-frame-parameters
+ frame (list (cons 'tool-bar-lines
+ (if (> (or (frame-parameter frame 'tool-bar-lines) 0) 0)
+ 0 1)) ))
+ (if (not tool-bar-mode) (tool-bar-mode t)))
+
+
+;;;; Dialog-related functions.
+
+;; Ask user for confirm before printing. Due to Kevin Rodgers.
+(defun pgtk-print-buffer ()
+ "Interactive front-end to `print-buffer': asks for user confirmation first."
+ (interactive)
+ (if (and (called-interactively-p 'interactive)
+ (or (listp last-nonmenu-event)
+ (and (char-or-string-p (event-basic-type last-command-event))
+ (memq 'super (event-modifiers last-command-event)))))
+ (let ((last-nonmenu-event (if (listp last-nonmenu-event)
+ last-nonmenu-event
+ ;; Fake it:
+ `(mouse-1 POSITION 1))))
+ (if (y-or-n-p (format "Print buffer %s? " (buffer-name)))
+ (print-buffer)
+ (error "Canceled")))
+ (print-buffer)))
+
+;;;; Font support.
+
+;; Needed for font listing functions under both backend and normal
+(setq scalable-fonts-allowed t)
+
+;; Default fontset. This is mainly here to show how a fontset
+;; can be set up manually. Ordinarily, fontsets are auto-created whenever
+;; a font is chosen by
+(defvar pgtk-standard-fontset-spec
+ ;; Only some code supports this so far, so use uglier XLFD version
+ ;; "-pgtk-*-*-*-*-*-10-*-*-*-*-*-fontset-standard,latin:Courier,han:Kai"
+ (mapconcat 'identity
+ '("-*-Monospace-*-*-*-*-10-*-*-*-*-*-fontset-standard"
+ "latin:-*-Courier-*-*-*-*-10-*-*-*-*-*-iso10646-1")
+ ",")
+ "String of fontset spec of the standard fontset.
+This defines a fontset consisting of the Courier and other fonts.
+See the documentation of `create-fontset-from-fontset-spec' for the format.")
+
+
+;;;; Pasteboard support.
+
+(define-obsolete-function-alias 'pgtk-store-cut-buffer-internal
+ 'gui-set-selection "24.1")
+
+
+(defun pgtk-copy-including-secondary ()
+ (interactive)
+ (call-interactively 'kill-ring-save)
+ (gui-set-selection 'SECONDARY (buffer-substring (point) (mark t))))
+
+(defun pgtk-paste-secondary ()
+ (interactive)
+ (insert (gui-get-selection 'SECONDARY)))
+
+
+(defun pgtk-suspend-error ()
+ ;; Don't allow suspending if any of the frames are PGTK frames.
+ (if (memq 'pgtk (mapcar 'window-system (frame-list)))
+ (error "Cannot suspend Emacs while a PGTK GUI frame exists")))
+
+
+
+(defvar pgtk-initialized nil
+ "Non-nil if pure-GTK windowing has been initialized.")
+
+(declare-function x-handle-args "common-win" (args))
+(declare-function x-open-connection "pgtkfns.c"
+ (display &optional xrm-string must-succeed))
+(declare-function pgtk-set-resource "pgtkfns.c" (owner name value))
+
+;; Do the actual pure-GTK Windows setup here; the above code just
+;; defines functions and variables that we use now.
+(cl-defmethod window-system-initialization (&context (window-system pgtk)
+ &optional display)
+ "Initialize Emacs for pure-GTK windowing."
+ (cl-assert (not pgtk-initialized))
+
+ ;; PENDING: not needed?
+ (setq command-line-args (x-handle-args command-line-args))
+
+ ;; Make sure we have a valid resource name.
+ (or (stringp x-resource-name)
+ (let (i)
+ (setq x-resource-name (copy-sequence invocation-name))
+
+ ;; Change any . or * characters in x-resource-name to hyphens,
+ ;; so as not to choke when we use it in X resource queries.
+ (while (setq i (string-match "[.*]" x-resource-name))
+ (aset x-resource-name i ?-))))
+
+ ;; Setup the default fontset.
+ (create-default-fontset)
+ ;; Create the standard fontset.
+ (condition-case err
+ (create-fontset-from-fontset-spec pgtk-standard-fontset-spec t)
+ (error (display-warning
+ 'initialization
+ (format "Creation of the standard fontset failed: %s" err)
+ :error)))
+
+ (x-open-connection (or display
+ x-display-name)
+ x-command-line-resources
+ ;; Exit Emacs with fatal error if this fails and we
+ ;; are the initial display.
+ (= (length (frame-list)) 0))
+
+ (x-apply-session-resources)
+
+ ;; Don't let Emacs suspend under PGTK.
+ (add-hook 'suspend-hook 'pgtk-suspend-error)
+
+ (setq pgtk-initialized t))
+
+;; Any display name is OK.
+(add-to-list 'display-format-alist '(".*" . pgtk))
+(cl-defmethod handle-args-function (args &context (window-system pgtk))
+ (x-handle-args args))
+
+(cl-defmethod frame-creation-function (params &context (window-system pgtk))
+ (x-create-frame-with-faces params))
+
+(declare-function pgtk-own-selection-internal "pgtkselect.c" (selection value &optional frame))
+(declare-function pgtk-disown-selection-internal "pgtkselect.c" (selection &optional time_object terminal))
+(declare-function pgtk-selection-owner-p "pgtkselect.c" (&optional selection terminal))
+(declare-function pgtk-selection-exists-p "pgtkselect.c" (&optional selection terminal))
+(declare-function pgtk-get-selection-internal "pgtkselect.c" (selection-symbol target-type &optional time_stamp terminal))
+
+(cl-defmethod gui-backend-set-selection (selection value
+ &context (window-system pgtk))
+ (if value (pgtk-own-selection-internal selection value)
+ (pgtk-disown-selection-internal selection)))
+
+(cl-defmethod gui-backend-selection-owner-p (selection
+ &context (window-system pgtk))
+ (pgtk-selection-owner-p selection))
+
+(cl-defmethod gui-backend-selection-exists-p (selection
+ &context (window-system pgtk))
+ (pgtk-selection-exists-p selection))
+
+(cl-defmethod gui-backend-get-selection (selection-symbol target-type
+ &context (window-system pgtk))
+ (pgtk-get-selection-internal selection-symbol target-type))
+
+
+(defvar pgtk-preedit-overlay nil)
+
+(defun pgtk-preedit-text (event)
+ "An internal function to display preedit text from input method.
+
+EVENT is an event of PGTK_PREEDIT_TEXT_EVENT.
+It contains colors and texts."
+ (interactive "e")
+ (when pgtk-preedit-overlay
+ (delete-overlay pgtk-preedit-overlay))
+ (setq pgtk-preedit-overlay nil)
+
+ (let ((ovstr "")
+ (idx 0)
+ atts ov str color face-name)
+ (dolist (part (nth 1 event))
+ (setq str (car part))
+ (setq face-name (intern (format "pgtk-im-%d" idx)))
+ (eval
+ `(defface ,face-name nil "face of input method preedit"))
+ (setq atts nil)
+ (when (setq color (cdr-safe (assq 'fg (cdr part))))
+ (setq atts (append atts `(:foreground ,color))))
+ (when (setq color (cdr-safe (assq 'bg (cdr part))))
+ (setq atts (append atts `(:background ,color))))
+ (when (setq color (cdr-safe (assq 'ul (cdr part))))
+ (setq atts (append atts `(:underline ,color))))
+ (face-spec-set face-name `((t . ,atts)))
+ (add-text-properties 0 (length str) `(face ,face-name) str)
+ (setq ovstr (concat ovstr str))
+ (setq idx (1+ idx)))
+
+ (setq ov (make-overlay (point) (point)))
+ (overlay-put ov 'before-string ovstr)
+ (setq pgtk-preedit-overlay ov)))
+
+
+(add-hook 'after-init-hook
+ (function
+ (lambda ()
+ (when (eq window-system 'pgtk)
+ (pgtk-use-im-context pgtk-use-im-context-on-new-connection)))))
+
+
+;;;
+
+(defcustom x-gtk-stock-map
+ (mapcar (lambda (arg)
+ (cons (purecopy (car arg)) (purecopy (cdr arg))))
+ '(
+ ("etc/images/new" . ("document-new" "gtk-new"))
+ ("etc/images/open" . ("document-open" "gtk-open"))
+ ("etc/images/diropen" . "n:system-file-manager")
+ ("etc/images/close" . ("window-close" "gtk-close"))
+ ("etc/images/save" . ("document-save" "gtk-save"))
+ ("etc/images/saveas" . ("document-save-as" "gtk-save-as"))
+ ("etc/images/undo" . ("edit-undo" "gtk-undo"))
+ ("etc/images/cut" . ("edit-cut" "gtk-cut"))
+ ("etc/images/copy" . ("edit-copy" "gtk-copy"))
+ ("etc/images/paste" . ("edit-paste" "gtk-paste"))
+ ("etc/images/search" . ("edit-find" "gtk-find"))
+ ("etc/images/print" . ("document-print" "gtk-print"))
+ ("etc/images/preferences" . ("preferences-system" "gtk-preferences"))
+ ("etc/images/help" . ("help-browser" "gtk-help"))
+ ("etc/images/left-arrow" . ("go-previous" "gtk-go-back"))
+ ("etc/images/right-arrow" . ("go-next" "gtk-go-forward"))
+ ("etc/images/home" . ("go-home" "gtk-home"))
+ ("etc/images/jump-to" . ("go-jump" "gtk-jump-to"))
+ ("etc/images/index" . ("gtk-search" "gtk-index"))
+ ("etc/images/exit" . ("application-exit" "gtk-quit"))
+ ("etc/images/cancel" . "gtk-cancel")
+ ("etc/images/info" . ("dialog-information" "gtk-info"))
+ ("etc/images/bookmark_add" . "n:bookmark_add")
+ ;; Used in Gnus and/or MH-E:
+ ("etc/images/attach" . ("mail-attachment" "gtk-attach"))
+ ("etc/images/connect" . "gtk-connect")
+ ("etc/images/contact" . "gtk-contact")
+ ("etc/images/delete" . ("edit-delete" "gtk-delete"))
+ ("etc/images/describe" . ("document-properties" "gtk-properties"))
+ ("etc/images/disconnect" . "gtk-disconnect")
+ ;; ("etc/images/exit" . "gtk-exit")
+ ("etc/images/lock-broken" . "gtk-lock_broken")
+ ("etc/images/lock-ok" . "gtk-lock_ok")
+ ("etc/images/lock" . "gtk-lock")
+ ("etc/images/next-page" . "gtk-next-page")
+ ("etc/images/refresh" . ("view-refresh" "gtk-refresh"))
+ ("etc/images/search-replace" . "edit-find-replace")
+ ("etc/images/sort-ascending" . ("view-sort-ascending" "gtk-sort-ascending"))
+ ("etc/images/sort-column-ascending" . "gtk-sort-column-ascending")
+ ("etc/images/sort-criteria" . "gtk-sort-criteria")
+ ("etc/images/sort-descending" . ("view-sort-descending"
+ "gtk-sort-descending"))
+ ("etc/images/sort-row-ascending" . "gtk-sort-row-ascending")
+ ("etc/images/spell" . ("tools-check-spelling" "gtk-spell-check"))
+ ("images/gnus/toggle-subscription" . "gtk-task-recurring")
+ ("images/mail/compose" . ("mail-message-new" "gtk-mail-compose"))
+ ("images/mail/copy" . "gtk-mail-copy")
+ ("images/mail/forward" . "gtk-mail-forward")
+ ("images/mail/inbox" . "gtk-inbox")
+ ("images/mail/move" . "gtk-mail-move")
+ ("images/mail/not-spam" . "gtk-not-spam")
+ ("images/mail/outbox" . "gtk-outbox")
+ ("images/mail/reply-all" . "gtk-mail-reply-to-all")
+ ("images/mail/reply" . "gtk-mail-reply")
+ ("images/mail/save-draft" . "gtk-mail-handling")
+ ("images/mail/send" . ("mail-send" "gtk-mail-send"))
+ ("images/mail/spam" . "gtk-spam")
+ ;; Used for GDB Graphical Interface
+ ("images/gud/break" . "gtk-no")
+ ("images/gud/recstart" . ("media-record" "gtk-media-record"))
+ ("images/gud/recstop" . ("media-playback-stop" "gtk-media-stop"))
+ ;; No themed versions available:
+ ;; mail/preview (combining stock_mail and stock_zoom)
+ ;; mail/save (combining stock_mail, stock_save and stock_convert)
+ ))
+ "How icons for tool bars are mapped to Gtk+ stock items.
+Emacs must be compiled with the Gtk+ toolkit for this to have any effect.
+A value that begins with n: denotes a named icon instead of a stock icon."
+ :version "22.2"
+ :type '(choice (repeat
+ (choice symbol
+ (cons (string :tag "Emacs icon")
+ (choice (group (string :tag "Named")
+ (string :tag "Stock"))
+ (string :tag "Stock/named"))))))
+ :group 'pgtk)
+
+(defcustom icon-map-list '(x-gtk-stock-map)
+ "A list of alists that map icon file names to stock/named icons.
+The alists are searched in the order they appear. The first match is used.
+The keys in the alists are file names without extension and with two directory
+components. For example, to map /usr/share/emacs/22.1.1/etc/images/open.xpm
+to stock item gtk-open, use:
+
+ (\"etc/images/open\" . \"gtk-open\")
+
+Themes also have named icons. To map to one of those, use n: before the name:
+
+ (\"etc/images/diropen\" . \"n:system-file-manager\")
+
+The list elements are either the symbol name for the alist or the
+alist itself.
+
+If you don't want stock icons, set the variable to nil."
+ :version "22.2"
+ :type '(choice (const :tag "Don't use stock icons" nil)
+ (repeat (choice symbol
+ (cons (string :tag "Emacs icon")
+ (string :tag "Stock/named")))))
+ :group 'pgtk)
+
+(defconst x-gtk-stock-cache (make-hash-table :weakness t :test 'equal))
+
+(defun x-gtk-map-stock (file)
+ "Map icon with file name FILE to a Gtk+ stock name.
+This uses `icon-map-list' to map icon file names to stock icon names."
+ (when (stringp file)
+ (or (gethash file x-gtk-stock-cache)
+ (puthash
+ file
+ (save-match-data
+ (let* ((file-sans (file-name-sans-extension file))
+ (key (and (string-match "/\\([^/]+/[^/]+/[^/]+$\\)"
+ file-sans)
+ (match-string 1 file-sans)))
+ (icon-map icon-map-list)
+ elem value)
+ (while (and (null value) icon-map)
+ (setq elem (car icon-map)
+ value (assoc-string (or key file-sans)
+ (if (symbolp elem)
+ (symbol-value elem)
+ elem))
+ icon-map (cdr icon-map)))
+ (and value (cdr value))))
+ x-gtk-stock-cache))))
+
+
+(provide 'pgtk-win)
+(provide 'term/pgtk-win)
+
+;;; pgtk-win.el ends here
diff --git a/lisp/term/st.el b/lisp/term/st.el
index f1cbad6d59f..26478ca2490 100644
--- a/lisp/term/st.el
+++ b/lisp/term/st.el
@@ -11,8 +11,7 @@
(require 'term/xterm)
-(defcustom xterm-st-extra-capabilities '( modifyOtherKeys getSelection
- setSelection)
+(defcustom xterm-st-extra-capabilities '(modifyOtherKeys)
"Extra capabilities supported under \"stterm\"."
:version "28.1"
:type xterm--extra-capabilities-type
diff --git a/lisp/term/sun.el b/lisp/term/sun.el
index 3dfd4c697a2..4c88c80bf7b 100644
--- a/lisp/term/sun.el
+++ b/lisp/term/sun.el
@@ -38,7 +38,7 @@
(scroll-up n))
(defun kill-region-and-unmark (beg end)
- "Like `kill-region', but pops the mark [which equals point, anyway.]"
+ "Like `kill-region', but pops the mark [which equals point, anyway]."
(interactive "r")
(kill-region beg end)
(setq this-command 'kill-region-and-unmark)
@@ -49,7 +49,7 @@
(interactive)
(eval (nth 0 command-history)))
-(defvar grep-arg nil "Default arg for RE-search")
+(defvar grep-arg nil "Default arg for RE-search.")
(defun grep-arg ()
(if (memq last-command '(research-forward research-backward)) grep-arg
(let* ((command (car command-history))
diff --git a/lisp/term/w32-win.el b/lisp/term/w32-win.el
index 80afcb36040..0ee010b6c87 100644
--- a/lisp/term/w32-win.el
+++ b/lisp/term/w32-win.el
@@ -274,6 +274,8 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.")
'(gif "libgif-6.dll" "giflib5.dll" "gif.dll")
'(gif "libgif-5.dll" "giflib4.dll" "libungif4.dll" "libungif.dll")))
'(svg "librsvg-2-2.dll")
+ '(webp "libwebp-7.dll" "libwebp.dll")
+ '(sqlite3 "libsqlite3-0.dll")
'(gdk-pixbuf "libgdk_pixbuf-2.0-0.dll")
'(glib "libglib-2.0-0.dll")
'(gio "libgio-2.0-0.dll")
@@ -532,7 +534,7 @@ characters from these blocks.")
(let (val)
(dolist (elt script-representative-chars)
(let ((subranges w32-no-usb-subranges)
- (chars (cdr elt))
+ (chars (append (cdr elt) nil)) ; handle vectors as well
ch found subrange)
(while (and (consp chars) (not found))
(setq ch (car chars)
@@ -595,7 +597,11 @@ default font on FRAME, or its best approximation."
0 nchars script-chars)
'[nil]))
;; Does this font support ALL of the script's
- ;; representative characters?
+ ;; representative characters? Note that, when the
+ ;; representative characters are specified as a
+ ;; vector, this is a more stringent test than font
+ ;; selection does, because supporting _any_
+ ;; character from the vector is enough.
(setq idx 0)
(while (and (< idx nchars) (not (null (aref glyphs idx))))
(setq idx (1+ idx)))
diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el
index 8c6c75e7e22..d6e63187487 100644
--- a/lisp/term/x-win.el
+++ b/lisp/term/x-win.el
@@ -131,7 +131,7 @@ When a session manager tells Emacs that the window system is shutting
down, this function is called. It calls the functions in the hook
`emacs-save-session-functions'. Functions are called with the current
buffer set to a temporary buffer. Functions should use `insert' to insert
-lisp code to save the session state. The buffer is saved in a file in the
+Lisp code to save the session state. The buffer is saved in a file in the
home directory of the user running Emacs. The file is evaluated when
Emacs is restarted by the session manager.
diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el
index e63bf36cc3d..52a64d6c414 100644
--- a/lisp/term/xterm.el
+++ b/lisp/term/xterm.el
@@ -73,6 +73,13 @@ string bytes that can be copied is 3/4 of this value."
:version "27.1"
:type 'boolean)
+(defcustom xterm-store-paste-on-kill-ring t
+ "If non-nil, pasting text into Emacs will put the text onto the kill ring.
+This user option is only heeded when using a terminal using xterm
+capabilities, and only when that terminal understands bracketed paste."
+ :version "28.1"
+ :type 'boolean)
+
(defconst xterm-paste-ending-sequence "\e[201~"
"Characters sent by the terminal to end a bracketed paste.")
@@ -100,9 +107,15 @@ Return the pasted text as a string."
(interactive "e")
(unless (eq (car-safe event) 'xterm-paste)
(error "xterm-paste must be found to xterm-paste event"))
- (let* ((pasted-text (nth 1 event))
- (interprogram-paste-function (lambda () pasted-text)))
- (yank)))
+ (let ((pasted-text (nth 1 event)))
+ (if xterm-store-paste-on-kill-ring
+ ;; Put the text onto the kill ring and then insert it into the
+ ;; buffer.
+ (let ((interprogram-paste-function (lambda () pasted-text)))
+ (yank))
+ ;; Insert the text without putting it onto the kill ring.
+ (push-mark)
+ (insert-for-yank pasted-text))))
;; Put xterm-paste itself in global-map because, after translation,
;; it's just a normal input event.
@@ -350,7 +363,20 @@ Return the pasted text as a string."
(define-key map "\e[5;3~" [M-prior])
(define-key map "\e[6;3~" [M-next])
- (define-key map "\e[29~" [print])
+ ;; This escape sequence has a controversial story.
+ ;; It was initially mapped to [print] (initial commit by Karl Heuer),
+ ;; but we can't find any justification for it.
+ ;; Xterm uses this escape sequence for both `F16' and `Menu' keys,
+ ;; and the reason for it is that in the VT220 keyboard the key
+ ;; placed logically at position where `F16' would be (and sending
+ ;; the escape sequence that naturally belongs to `F16') was
+ ;; labeled `Menu'. [ The story gets even more interesting if you
+ ;; want to dig deeper, e.g. some terminals would send that same
+ ;; escape sequence in response to `S-F4' (because they (ab)used
+ ;; the escape sequence of `F<n+12>' for `S-F<n>'). ]
+ ;; The current binding was chosen because current keyboards almost never
+ ;; have an `F16' key, whereas many do have a `Menu' key.
+ (define-key map "\e[29~" [menu])
(define-key map "\eOj" [kp-multiply])
(define-key map "\eOk" [kp-add])
@@ -368,6 +394,9 @@ Return the pasted text as a string."
(define-key map "\eOx" [kp-8])
(define-key map "\eOy" [kp-9])
+ ;; Some keypads have an equal key (for instance, most Apple keypads).
+ (define-key map "\eOX" [kp-equal])
+
(define-key map "\eO2j" [S-kp-multiply])
(define-key map "\eO2k" [S-kp-add])
(define-key map "\eO2l" [S-kp-separator])
@@ -761,14 +790,13 @@ Return the pasted text as a string."
Can be nil to mean \"no timeout\".")
(defvar xterm-query-redisplay-timeout 0.2
- "Seconds to wait before allowing redisplay during terminal
- query." )
+ "Seconds to wait before allowing redisplay during terminal query." )
(defun xterm--read-event-for-query ()
- "Like read-event, but inhibit redisplay.
+ "Like `read-event', but inhibit redisplay.
By not redisplaying right away for xterm queries, we can avoid
-unsightly flashing during initialization. Give up and redisplay
+unsightly flashing during initialization. Give up and redisplay
anyway if we've been waiting a little while."
(let ((start-time (current-time)))
(or (let ((inhibit-redisplay t))
diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el
index d9a83c566b4..25f0c35aa5d 100644
--- a/lisp/textmodes/artist.el
+++ b/lisp/textmodes/artist.el
@@ -1277,7 +1277,7 @@ Drawing with keys
\\[artist-key-set-point] Does one of the following:
For lines/rectangles/squares: sets the first/second endpoint
- For poly-lines: sets a point (use C-u \\[artist-key-set-point] to set last point)
+ For poly-lines: sets a point (use \\[universal-argument] \\[artist-key-set-point] to set last point)
When erase characters: toggles erasing
When cutting/copying: Sets first/last endpoint of rect/square
When pasting: Pastes
@@ -2840,9 +2840,8 @@ Returns a list of strings."
(if (memq system-type '(windows-nt ms-dos))
(artist-figlet-get-font-list-windows)
(artist-figlet-get-font-list)))
- (font (completing-read (concat "Select font (default "
- artist-figlet-default-font
- "): ")
+ (font (completing-read (format-prompt "Select font"
+ artist-figlet-default-font)
(mapcar
(lambda (font) (cons font font))
avail-fonts))))
@@ -4891,7 +4890,7 @@ If optional argument STATE is positive, turn borders on."
(+ window-y window-start-y))))
(defun artist--adjust-x (x)
- "Adjust the X position wrt. `display-line-numbers-mode'."
+ "Adjust the X position with regards to `display-line-numbers-mode'."
(let ((adjust (line-number-display-width)))
(if (= adjust 0)
x
diff --git a/lisp/textmodes/bib-mode.el b/lisp/textmodes/bib-mode.el
index e2fd3ecaa42..a429aae7f70 100644
--- a/lisp/textmodes/bib-mode.el
+++ b/lisp/textmodes/bib-mode.el
@@ -137,7 +137,7 @@ with the cdr.")
(defcustom bib-auto-capitalize t
- "True to automatically capitalize appropriate fields in Bib mode."
+ "Non-nil to automatically capitalize appropriate fields in Bib mode."
:type 'boolean)
(defconst bib-capitalized-fields "%[AETCBIJR]")
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index 5cece1aa3c6..2dd4e8e7af0 100644
--- a/lisp/textmodes/bibtex.el
+++ b/lisp/textmodes/bibtex.el
@@ -113,7 +113,7 @@ page-dashes Change double dashes in page field to single dash
whitespace Delete whitespace at the beginning and end of fields.
inherit-booktitle If entry contains a crossref field and the booktitle
field is empty, set the booktitle field to the content
- of the title field of the crossreferenced entry.
+ of the title field of the cross-referenced entry.
realign Realign entries, so that field texts and perhaps equal
signs (depending on the value of
`bibtex-align-at-equal-sign') begin in the same column.
@@ -839,6 +839,24 @@ for a new entry."
("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4)
("eprinttype" nil nil 5) ("archiveprefix" nil nil -5)
("url") ("urldate")))
+ ("PhdThesis" "PhD Thesis"
+ (("author")
+ ("title" "Title of the PhD thesis")
+ ("school" "School where the PhD thesis was written")
+ ("year"))
+ nil
+ (("type" "Type of the PhD thesis")
+ ("address" "Address of the school (if not part of field \"school\") or country")
+ ("month") ("note")))
+ ("TechReport" "Technical Report"
+ (("author")
+ ("title" "Title of the technical report (BibTeX converts it to lowercase)")
+ ("institution" "Sponsoring institution of the report")
+ ("year"))
+ nil
+ (("type" "Type of the report (if other than \"technical report\")")
+ ("number" "Number of the technical report")
+ ("address") ("month") ("note")))
("Unpublished" "Unpublished"
(("author") ("title") ("date" nil nil 1) ("year" nil nil -1))
nil
@@ -1228,9 +1246,9 @@ See `bibtex-generate-autokey' for details."
:type 'integer)
(defcustom bibtex-autokey-use-crossref t
- "If non-nil use fields from crossreferenced entry if necessary.
+ "If non-nil use fields from cross-referenced entry if necessary.
If this variable is non-nil and some field has no entry, but a
-valid crossref entry, the field from the crossreferenced entry is used.
+valid crossref entry, the field from the cross-referenced entry is used.
See `bibtex-generate-autokey' for details."
:group 'bibtex-autokey
:type 'boolean)
@@ -1569,8 +1587,8 @@ Set this variable before loading BibTeX mode."
km)
"Keymap used in BibTeX mode.")
-(easy-menu-define
- bibtex-edit-menu bibtex-mode-map "BibTeX-Edit Menu in BibTeX mode"
+(easy-menu-define bibtex-edit-menu bibtex-mode-map
+ "BibTeX-Edit Menu in BibTeX mode."
'("BibTeX-Edit"
("Moving inside an Entry"
["End of Field" bibtex-find-text t]
@@ -2975,7 +2993,7 @@ The year part:
`bibtex-autokey-year-length' digits (useful values are 2 and 4).
2. If both the year and date fields are absent, but the entry has a
valid crossref field and `bibtex-autokey-use-crossref' is
- non-nil, use the date or year field of the crossreferenced entry
+ non-nil, use the date or year field of the cross-referenced entry
instead.
The title part
@@ -4317,8 +4335,6 @@ for a crossref key, t otherwise."
(eqb (goto-char pos))
(t (set-buffer buffer) (goto-char pos)))
pos))
-;; backward compatibility
-(defalias 'bibtex-find-crossref 'bibtex-search-crossref)
(defun bibtex-dist (pos beg end)
"Return distance between POS and region delimited by BEG and END."
@@ -4381,8 +4397,6 @@ A prefix arg negates the value of `bibtex-search-entry-globally'."
(if display (bibtex-reposition-window)))
(display (message "Key `%s' not found" key)))
pnt)))
-;; backward compatibility
-(defalias 'bibtex-find-entry 'bibtex-search-entry)
(defun bibtex-prepare-new-entry (index)
"Prepare a new BibTeX entry with index INDEX.
@@ -5608,5 +5622,8 @@ If APPEND is non-nil, append ENTRIES to those already displayed."
(setq buffer-read-only t)
(goto-char (point-min)))
+(define-obsolete-function-alias 'bibtex-find-crossref #'bibtex-search-crossref "29.1")
+(define-obsolete-function-alias 'bibtex-find-entry #'bibtex-search-entry "29.1")
+
(provide 'bibtex)
;;; bibtex.el ends here
diff --git a/lisp/textmodes/conf-mode.el b/lisp/textmodes/conf-mode.el
index 5f34ae152d1..30f8fd0ca91 100644
--- a/lisp/textmodes/conf-mode.el
+++ b/lisp/textmodes/conf-mode.el
@@ -417,12 +417,18 @@ See also `conf-space-mode', `conf-colon-mode', `conf-javaprop-mode',
;; To tell the difference between those two cases where the function
;; might be called, we check `delay-mode-hooks'.
;; (inspired from tex-mode.el)
+(defvar conf-mode--recursing nil)
(advice-add 'conf-mode :around
(lambda (orig-fun)
"Redirect to one of the submodes when called directly."
- (funcall (if delay-mode-hooks orig-fun (conf--guess-mode)))))
-
-
+ ;; The file may have "mode: conf" in the local variable
+ ;; block, in which case we'll be called recursively
+ ;; infinitely. Inhibit that.
+ (let ((conf-mode--recursing conf-mode--recursing))
+ (funcall (if (or delay-mode-hooks conf-mode--recursing)
+ orig-fun
+ (setq conf-mode--recursing t)
+ (conf--guess-mode))))))
(defun conf-mode-initialize (comment &optional font-lock)
"Initializations for sub-modes of `conf-mode'.
@@ -609,7 +615,7 @@ For details see `conf-mode'. Example:
(conf-mode-initialize "!"))
(defun conf-toml-recognize-section (limit)
- "Font-lock helper function for conf-toml-mode.
+ "Font-lock helper function for `conf-toml-mode'.
Handles recognizing TOML section names, like [section],
\[[section]], or [something.\"else\".section]."
(save-excursion
diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el
index 61a2f6b3bc0..e5017a68f78 100644
--- a/lisp/textmodes/css-mode.el
+++ b/lisp/textmodes/css-mode.el
@@ -57,7 +57,7 @@
"Identifiers for pseudo-classes.")
(defconst css-pseudo-element-ids
- '("after" "before" "first-letter" "first-line")
+ '("after" "before" "first-letter" "first-line" "selection")
"Identifiers for pseudo-elements.")
(defconst css-at-ids
@@ -274,12 +274,13 @@
("color" color)
("opacity" alphavalue)
- ;; CSS Containment Module Level 1
- ;; (https://www.w3.org/TR/css-contain-1/#property-index)
- ("contain" "none" "strict" "content" "size" "layout" "paint")
+ ;; CSS Containment Module Level 2
+ ;; (https://www.w3.org/TR/css-contain-2/#property-index)
+ ("contain" "none" "strict" "content" "size" "layout" "style" "paint")
+ ("content-visibility" "visible" "auto" "hidden")
- ;; CSS Grid Layout Module Level 1
- ;; (https://www.w3.org/TR/css-grid-1/#property-index)
+ ;; CSS Grid Layout Module Level 2
+ ;; (https://www.w3.org/TR/css-grid-2/#property-index)
("grid" grid-template grid-template-rows "auto-flow" "dense"
grid-auto-columns grid-auto-rows grid-template-columns)
("grid-area" grid-line)
@@ -298,17 +299,32 @@
("grid-template" "none" grid-template-rows grid-template-columns
line-names string track-size line-names explicit-track-list)
("grid-template-areas" "none" string)
- ("grid-template-columns" "none" track-list auto-track-list)
- ("grid-template-rows" "none" track-list auto-track-list)
-
- ;; CSS Flexible Box Layout Module Level 1
- ;; (https://www.w3.org/TR/css-flexbox-1/#property-index)
- ("align-content" "flex-start" "flex-end" "center" "space-between"
- "space-around" "stretch")
- ("align-items" "flex-start" "flex-end" "center" "baseline"
- "stretch")
- ("align-self" "auto" "flex-start" "flex-end" "center" "baseline"
- "stretch")
+ ("grid-template-columns" "none" track-list auto-track-list "subgrid")
+ ("grid-template-rows" "none" track-list auto-track-list "subgrid")
+
+ ;; CSS Box Alignment Module Level 3
+ ;; (https://www.w3.org/TR/css-align-3/#property-index)
+ ("align-content"
+ baseline-position content-distribution overflow-position content-position)
+ ("align-items"
+ "normal" "stretch" baseline-position overflow-position self-position)
+ ("align-self"
+ "auto" "normal" "stretch"
+ baseline-position overflow-position self-position)
+ ("justify-content" "normal"
+ content-distribution overflow-position content-position "left" "right")
+ ("justify-items"
+ "normal" "stretch" baseline-position overflow-position self-position
+ "left" "right" "legacy")
+ ("justify-self"
+ "auto" "normal" "stretch" baseline-position overflow-position self-position
+ "left" "right")
+ ("place-content" align-content justify-content)
+ ("place-items" align-items justify-items)
+ ("place-self" justify-self align-self)
+
+ ;; CSS Flexible Box Layout Module Level 2
+ ;; (https://www.w3.org/TR/css-flexbox-2/#property-index)
("flex" "none" flex-grow flex-shrink flex-basis)
("flex-basis" "auto" "content" width)
("flex-direction" "row" "row-reverse" "column" "column-reverse")
@@ -316,8 +332,6 @@
("flex-grow" number)
("flex-shrink" number)
("flex-wrap" "nowrap" "wrap" "wrap-reverse")
- ("justify-content" "flex-start" "flex-end" "center"
- "space-between" "space-around")
("order" integer)
;; CSS Fonts Module Level 3
@@ -757,6 +771,13 @@ further value candidates, since that list would be infinite.")
(padding-width length percentage)
(position
"left" "center" "right" "top" "bottom" percentage length)
+ (baseline-position "left" "right" "baseline")
+ (content-distribution
+ "space-between" "space-around" "space-evenly" "stretch")
+ (overflow-position "unsafe" "safe")
+ (content-position "center" "start" "end" "flex-start" "flex-end")
+ (self-position
+ "center" "start" "end" "self-start" "self-end" "flex-start" "flex-end")
(radial-gradient "radial-gradient()")
(relative-size "larger" "smaller")
(repeat-style
@@ -1135,7 +1156,7 @@ by `css--colors-regexp'. START-POINT is the start of the color,
and MATCH is the string matched by the regexp.
This function will either return the color, as a hex RGB string;
-or `nil' if no color could be recognized. When this function
+or nil if no color could be recognized. When this function
returns, point will be at the end of the recognized color."
(cond
((eq (aref match 0) ?#)
@@ -1149,7 +1170,7 @@ returns, point will be at the end of the recognized color."
(defcustom css-fontify-colors t
"Whether CSS colors should be fontified using the color as the background.
-When non-`nil', a text representing CSS color will be fontified
+When non-nil, a text representing CSS color will be fontified
such that its background is the color itself. E.g., #ff0000 will
be fontified with a red background."
:version "26.1"
diff --git a/lisp/textmodes/enriched.el b/lisp/textmodes/enriched.el
index 877658a5a55..4a5a5ab3677 100644
--- a/lisp/textmodes/enriched.el
+++ b/lisp/textmodes/enriched.el
@@ -34,7 +34,7 @@
;; A separate file, enriched.txt, contains further documentation and other
;; important information about this code. It also serves as an example
;; file in text/enriched format. It should be in the etc directory of your
-;; emacs distribution.
+;; Emacs distribution.
;;; Code:
@@ -191,6 +191,7 @@ The value is a list of \(VAR VALUE VAR VALUE...).")
(define-key map "\C-x\t" #'increase-left-margin)
(define-key map "\C-c[" #'set-left-margin)
(define-key map "\C-c]" #'set-right-margin)
+ (define-key map "\M-o" #'facemenu-keymap)
map)
"Keymap for Enriched mode.")
diff --git a/lisp/textmodes/etc-authors-mode.el b/lisp/textmodes/etc-authors-mode.el
new file mode 100644
index 00000000000..a79a1ecf4bb
--- /dev/null
+++ b/lisp/textmodes/etc-authors-mode.el
@@ -0,0 +1,133 @@
+;;; etc-authors-mode.el --- font-locking for etc/AUTHORS -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Stefan Kangas <stefan@marxist.se>
+;; Keywords: internal
+
+;; 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:
+
+;; Major mode to display the etc/AUTHORS file from the Emacs
+;; distribution. Provides some basic font locking and not much else.
+
+;;; Code:
+
+(defgroup etc-authors-mode nil
+ "Display the \"etc/AUTHORS\" file from the Emacs distribution."
+ :version "28.1"
+ :group 'internal)
+
+(defface etc-authors-default '((t :inherit variable-pitch))
+ "Default face used to display the \"etc/AUTHORS\" file.
+See also `etc-authors-mode'."
+ :version "28.1")
+
+(defface etc-authors-author '((((class color) (min-colors 88) (background light))
+ :foreground "midnight blue"
+ :weight bold :height 1.05
+ :inherit variable-pitch)
+ (((class color) (min-colors 88) (background dark))
+ :foreground "cyan"
+ :weight bold :height 1.05
+ :inherit variable-pitch)
+ (((supports :weight bold) (supports :height 1.05))
+ :weight bold :height 1.05
+ :inherit variable-pitch)
+ (((supports :weight bold))
+ :weight bold :inherit variable-pitch)
+ (t :inherit variable-pitch))
+ "Face used for the author in the \"etc/AUTHORS\" file.
+See also `etc-authors-mode'."
+ :version "28.1")
+
+(defface etc-authors-descriptor '((((class color) (min-colors 88) (background light))
+ :foreground "sienna" :inherit variable-pitch)
+ (((class color) (min-colors 88) (background dark))
+ :foreground "peru" :inherit variable-pitch)
+ (t :inherit variable-pitch))
+ "Face used for the description text in the \"etc/AUTHORS\" file.
+See also `etc-authors-mode'."
+ :version "28.1")
+
+(defface etc-authors-other-files '((t :inherit etc-authors-descriptor))
+ "Face used for the \"other files\" text in the \"etc/AUTHORS\" file.
+See also `etc-authors-mode'."
+ :version "28.1")
+
+(defconst etc-authors--author-re
+ (rx bol (group (not (any blank "\n")) (+? (not (any ":" "\n")))) ":")
+ "Regexp matching an author in \"etc/AUTHORS\".")
+
+(defvar etc-authors-mode-font-lock-keywords
+ `((,etc-authors--author-re
+ 1 'etc-authors-author)
+ (,(rx (or "wrote"
+ (seq (? "and ") (or "co-wrote" "changed"))))
+ 0 'etc-authors-descriptor)
+ (,(rx "and " (+ digit) " other files")
+ 0 'etc-authors-other-files)
+ (,(rx bol (not space) (+ not-newline) eol)
+ 0 'etc-authors-default)))
+
+(defun etc-authors-mode--hide-local-variables ()
+ "Hide local variables in \"etc/AUTHORS\". Used by `etc-authors-mode'."
+ (narrow-to-region (point-min)
+ (save-excursion
+ (goto-char (point-min))
+ ;; Obfuscate to avoid this being interpreted
+ ;; as a local variable section itself.
+ (if (re-search-forward "^Local\sVariables:$" nil t)
+ (progn (forward-line -1) (point))
+ (point-max)))))
+
+(defun etc-authors-next-author (&optional arg)
+ "Move point to the next author in \"etc/AUTHORS\".
+With a prefix arg ARG, move point that many authors forward."
+ (interactive "p" etc-authors-mode)
+ (if (< 0 arg)
+ (progn
+ (when (looking-at etc-authors--author-re)
+ (forward-line 1))
+ (re-search-forward etc-authors--author-re nil t arg))
+ (when (looking-at etc-authors--author-re)
+ (forward-line -1))
+ (re-search-backward etc-authors--author-re nil t (abs arg)))
+ (goto-char (line-beginning-position)))
+
+(defun etc-authors-prev-author (&optional arg)
+ "Move point to the previous author in \"etc/AUTHORS\".
+With a prefix arg ARG, move point that many authors backward."
+ (interactive "p" etc-authors-mode)
+ (etc-authors-next-author (- arg)))
+
+(defvar-keymap etc-authors-mode-map
+ :doc "Keymap for `etc-authors-mode'."
+ "n" #'etc-authors-next-author
+ "p" #'etc-authors-prev-author)
+
+;;;###autoload
+(define-derived-mode etc-authors-mode special-mode "Authors View"
+ "Major mode for viewing \"etc/AUTHORS\" from the Emacs distribution.
+Provides some basic font locking and not much else."
+ (setq-local font-lock-defaults
+ '(etc-authors-mode-font-lock-keywords nil nil ((?_ . "w"))))
+ (setq font-lock-multiline nil)
+ (etc-authors-mode--hide-local-variables))
+
+(provide 'etc-authors-mode)
+;;; etc-authors-mode.el ends here
diff --git a/lisp/textmodes/fill.el b/lisp/textmodes/fill.el
index f394171fb6c..4e161099cd6 100644
--- a/lisp/textmodes/fill.el
+++ b/lisp/textmodes/fill.el
@@ -396,12 +396,8 @@ and `fill-nobreak-invisible'."
(save-excursion
(skip-chars-backward " ")
(and (eq (preceding-char) ?.)
- (looking-at " \\([^ ]\\|$\\)"))))
- ;; Another approach to the same problem.
- (save-excursion
- (skip-chars-backward " ")
- (and (eq (preceding-char) ?.)
- (not (progn (forward-char -1) (looking-at (sentence-end))))))
+ ;; There's something more after the space.
+ (looking-at " [^ \n]"))))
;; Don't split a line if the rest would look like a new paragraph.
(unless use-hard-newlines
(save-excursion
@@ -709,7 +705,10 @@ space does not end a sentence, so don't break a line there."
(goto-char from-plus-indent))
(if (not (> to (point)))
- nil ;; There is no paragraph, only whitespace: exit now.
+ ;; There is no paragraph, only whitespace: exit now.
+ (progn
+ (set-marker to nil)
+ nil)
(or justify (setq justify (current-justification)))
@@ -768,7 +767,7 @@ space does not end a sentence, so don't break a line there."
(setq first nil
linebeg (+ (point) (length actual-fill-prefix))))
(move-to-column (current-fill-column))
- (if (when (< (point) to)
+ (if (when (and (< (point) to) (< linebeg to))
;; Find the position where we'll break the line.
;; Use an immediately following space, if any.
;; However, note that `move-to-column' may overshoot
@@ -795,6 +794,7 @@ space does not end a sentence, so don't break a line there."
;; Leave point after final newline.
(goto-char to)
(unless (eobp) (forward-char 1))
+ (set-marker to nil)
;; Return the fill-prefix we used
fill-prefix)))
@@ -1064,7 +1064,7 @@ than line breaks untouched, and fifth arg TO-EOP non-nil means
to keep filling to the end of the paragraph (or next hard newline,
if variable `use-hard-newlines' is on).
-Return the fill-prefix used for filling the last paragraph.
+Return the `fill-prefix' used for filling the last paragraph.
If `sentence-end-double-space' is non-nil, then period followed by one
space does not end a sentence, so don't break a line there."
diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el
index 836d889a1cf..2a9cae29f79 100644
--- a/lisp/textmodes/flyspell.el
+++ b/lisp/textmodes/flyspell.el
@@ -442,22 +442,6 @@ like <img alt=\"Some thing.\">."
map)
"Minor mode keymap for Flyspell mode--for the whole buffer.")
-;; correct on mouse 3
-(defun flyspell--set-use-mouse-3-for-menu (var value)
- (set-default var value)
- (if value
- (progn (define-key flyspell-mouse-map [mouse-2] nil)
- (define-key flyspell-mouse-map [down-mouse-3] 'flyspell-correct-word))
- (define-key flyspell-mouse-map [mouse-2] 'flyspell-correct-word)
- (define-key flyspell-mouse-map [down-mouse-3] nil)))
-
-(defcustom flyspell-use-mouse-3-for-menu nil
- "Non-nil means to bind `mouse-3' to `flyspell-correct-word'.
-If this is set, also unbind `mouse-2'."
- :type 'boolean
- :set 'flyspell--set-use-mouse-3-for-menu
- :version "28.1")
-
;; dash character machinery
(defvar-local flyspell-consider-dash-as-word-delimiter-flag nil
"Non-nil means that the `-' char is considered as a word delimiter.")
@@ -486,6 +470,13 @@ See also `flyspell-duplicate-distance'."
(defvar flyspell-overlay nil)
+(defun flyspell-context-menu (_menu _click)
+ "Context menu for `context-menu-mode'."
+ ;; TODO: refactor `flyspell-correct-word' and related functions to return
+ ;; a keymap menu where every menu item is bound to a lambda that calls
+ ;; `flyspell-do-correct' with an argument that is a correct word.
+ 'flyspell-correct-word)
+
;;*---------------------------------------------------------------------*/
;;* flyspell-mode ... */
;;*---------------------------------------------------------------------*/
@@ -537,10 +528,7 @@ in your init file.
:group 'flyspell
(if flyspell-mode
(condition-case err
- (progn
- (when flyspell-use-mouse-3-for-menu
- (flyspell--set-use-mouse-3-for-menu 'flyspell-use-mouse-3-for-menu t))
- (flyspell-mode-on (called-interactively-p 'interactive)))
+ (flyspell-mode-on (called-interactively-p 'interactive))
(error (message "Error enabling Flyspell mode:\n%s" (cdr err))
(flyspell-mode -1)))
(flyspell-mode-off)))
@@ -558,7 +546,7 @@ in your init file.
(custom-add-option 'text-mode-hook 'turn-on-flyspell)
(defvar flyspell-buffers nil
- "For remembering buffers running flyspell")
+ "For remembering buffers running flyspell.")
(make-obsolete-variable 'flyspell-buffers "not used." "28.1")
;;*---------------------------------------------------------------------*/
@@ -656,8 +644,7 @@ are both non-nil."
show-msg)
(let* ((binding (where-is-internal 'flyspell-auto-correct-word
nil 'non-ascii))
- (mouse-button (if flyspell-use-mouse-3-for-menu
- "Mouse-3" "Mouse-2")))
+ (mouse-button (if context-menu-mode "Mouse-3" "Mouse-2")))
(message (format-message
"Welcome to Flyspell. Use %s to correct words."
(if binding
@@ -715,8 +702,8 @@ has been used, the current word is not checked."
;;* has to be spell checked. */
;;*---------------------------------------------------------------------*/
(defvar flyspell-pre-buffer nil "Buffer current before `this-command'.")
-(defvar flyspell-pre-point nil "Point before running `this-command'")
-(defvar flyspell-pre-column nil "Column before running `this-command'")
+(defvar flyspell-pre-point nil "Point before running `this-command'.")
+(defvar flyspell-pre-column nil "Column before running `this-command'.")
(defvar flyspell-pre-pre-buffer nil)
(defvar flyspell-pre-pre-point nil)
(make-variable-buffer-local 'flyspell-pre-point) ;Why?? --Stef
@@ -1759,7 +1746,7 @@ FLYSPELL-BUFFER."
;;* flyspell-overlay-p ... */
;;*---------------------------------------------------------------------*/
(defun flyspell-overlay-p (o)
- "Return true if O is an overlay used by flyspell."
+ "Return non-nil if O is an overlay used by flyspell."
(and (overlayp o) (overlay-get o 'flyspell-overlay)))
;;*---------------------------------------------------------------------*/
@@ -1820,13 +1807,15 @@ for the overlay."
(overlay-put overlay 'mouse-face mouse-face)
(overlay-put overlay 'flyspell-overlay t)
(overlay-put overlay 'evaporate t)
- (overlay-put overlay 'help-echo (concat (if flyspell-use-mouse-3-for-menu
- "mouse-3"
- "mouse-2") ": correct word at point"))
- ;; If misspelled text has a 'keymap' property, let that remain in
- ;; effect for the bindings that flyspell-mouse-map doesn't override.
- (set-keymap-parent flyspell-mouse-map (get-char-property beg 'keymap))
- (overlay-put overlay 'keymap flyspell-mouse-map)
+ (overlay-put overlay 'help-echo
+ (concat (if context-menu-mode "mouse-3" "mouse-2")
+ ": correct word at point"))
+ (if context-menu-mode
+ (overlay-put overlay 'context-menu-function 'flyspell-context-menu)
+ ;; If misspelled text has a 'keymap' property, let that remain in
+ ;; effect for the bindings that flyspell-mouse-map doesn't override.
+ (set-keymap-parent flyspell-mouse-map (get-char-property beg 'keymap))
+ (overlay-put overlay 'keymap flyspell-mouse-map))
(when (eq face 'flyspell-incorrect)
(and (stringp flyspell-before-incorrect-word-string)
(overlay-put overlay 'before-string
@@ -1872,7 +1861,7 @@ is itself incorrect, but suspiciously repeated."
;;* flyspell-highlight-duplicate-region ... */
;;*---------------------------------------------------------------------*/
(defun flyspell-highlight-duplicate-region (beg end poss)
- "Set up an overlay on a duplicate misspelled word, in the buffer from BEG to END.
+ "Set up overlay on duplicate misspelled word, in the buffer from BEG to END.
POSS is a list of possible spelling/correction lists,
as returned by `ispell-parse-output'."
(let ((inhibit-read-only t))
@@ -2171,7 +2160,7 @@ The word checked is the word at the mouse position."
(interactive "e")
(let ((save (point)))
(mouse-set-point event)
- (flyspell-correct-word-before-point event save)))
+ (flyspell-correct-word-before-point (and (consp event) event) save)))
(defun flyspell-correct-word-before-point (&optional event opoint)
"Pop up a menu of possible corrections for misspelled word before point.
@@ -2281,17 +2270,8 @@ If OPOINT is non-nil, restore point there after adjusting it for replacement."
;;*---------------------------------------------------------------------*/
(defun flyspell-emacs-popup (event poss word)
"The Emacs popup menu."
- (if (and (not event)
- (display-mouse-p))
- (let* ((mouse-pos (mouse-position))
- (mouse-pos (if (nth 1 mouse-pos)
- mouse-pos
- (set-mouse-position (car mouse-pos)
- (/ (frame-width) 2) 2)
- (mouse-position))))
- (setq event (list (list (car (cdr mouse-pos))
- (1+ (cdr (cdr mouse-pos))))
- (car mouse-pos)))))
+ (unless event
+ (setq event (popup-menu-normalize-position (point))))
(let* ((corrects (flyspell-sort (car (cdr (cdr poss))) word))
(cor-menu (if (consp corrects)
(mapcar (lambda (correct)
diff --git a/lisp/textmodes/glyphless-mode.el b/lisp/textmodes/glyphless-mode.el
new file mode 100644
index 00000000000..177ba42c9c8
--- /dev/null
+++ b/lisp/textmodes/glyphless-mode.el
@@ -0,0 +1,68 @@
+;;; glyphless-mode.el --- minor mode for displaying glyphless characters -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Maintainer: emacs-devel@gnu.org
+
+;; 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:
+
+(defcustom glyphless-mode-types '(all)
+ "Which glyphless characters to display.
+The value can be any of the groups supported by
+`glyphless-char-display-control' (which see), and in addition
+`all', for all glyphless characters."
+ :version "29.1"
+ :type '(repeat (choice (const :tag "All" all)
+ (const :tag "No font" no-font)
+ (const :tag "C0 Control" c0-control)
+ (const :tag "C1 Control" c1-control)
+ (const :tag "Format Control" format-control)
+ (const :tag "Bidirectional Control" bidi-control)
+ (const :tag "Variation Selectors" variation-selectors)
+ (const :tag "No Font" no-font)))
+ :group 'display)
+
+;;;###autoload
+(define-minor-mode glyphless-display-mode
+ "Minor mode for displaying glyphless characters in the current buffer.
+If enabled, all glyphless characters will be displayed as boxes
+that display their acronyms."
+ :lighter " Glyphless"
+ (if glyphless-display-mode
+ (progn
+ (setq-local glyphless-char-display
+ (let ((table (make-display-table)))
+ (set-char-table-parent table glyphless-char-display)
+ table))
+ (glyphless-mode--setup))
+ (kill-local-variable 'glyphless-char-display)))
+
+(defun glyphless-mode--setup ()
+ (let ((types (if (memq 'all glyphless-mode-types)
+ '(c0-control c1-control format-control
+ variation-selectors no-font)
+ glyphless-mode-types)))
+ (when types
+ (update-glyphless-char-display
+ nil (mapcar (lambda (e) (cons e 'acronym)) types)))))
+
+(provide 'glyphless-mode)
+
+;;; glyphless-mode.el ends here
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el
index 67852998f42..754ecb3a1d7 100644
--- a/lisp/textmodes/ispell.el
+++ b/lisp/textmodes/ispell.el
@@ -60,7 +60,7 @@
;; `a': Accept word for this session.
;; `A': Accept word and place in buffer-local dictionary.
;; `r': Replace word with typed-in value. Rechecked.
-;; `R': Replace word with typed-in value. Query-replaced in buffer. Rechecked.
+;; `R': Replace word with typed-in value. Query-replaced in buffer. Rechecked.
;; `?': Show these commands
;; `x': Exit spelling buffer. Move cursor to original point.
;; `X': Exit spelling buffer. Leaves cursor at the current point, and permits
@@ -250,16 +250,15 @@ Always stores Fcc copy of message when nil."
Should probably be \"-Ei\"."
:type 'string)
-(defcustom ispell-look-command
- (cond ((file-exists-p "/bin/look") "/bin/look")
- ((file-exists-p "/usr/local/bin/look") "/usr/local/bin/look")
- ((file-exists-p "/usr/bin/look") "/usr/bin/look")
- (t "look"))
+(defcustom ispell-look-command (executable-find "look")
"Name of the look command for search processes.
This must be an absolute file name."
- :type 'file)
+ :type '(choice (const :tag "None" nil)
+ file)
+ :version "28.1")
-(defcustom ispell-look-p (file-exists-p ispell-look-command)
+(defcustom ispell-look-p (and ispell-look-command
+ (file-exists-p ispell-look-command))
"Non-nil means use `look' rather than `grep'.
Default is based on whether `look' seems to be available."
:type 'boolean)
@@ -398,6 +397,10 @@ re-start Emacs."
(const :tag "default" nil))
(coding-system :tag "Coding System"))))
+(defcustom ispell-help-timeout 5
+ "The number of seconds to display the help text."
+ :type 'number
+ :version "28.1")
(defvar ispell-dictionary-base-alist
'((nil ; default
@@ -621,7 +624,7 @@ this would require some extra guessing in `ispell-aspell-find-dictionary'.")
("svenska" "sv_SE")
("hebrew" "he_IL"))
"Alist with known matching locales for standard dict names in
- `ispell-dictionary-base-alist'.")
+`ispell-dictionary-base-alist'.")
;;; **********************************************************************
@@ -731,8 +734,7 @@ Otherwise returns the library directory name, if that is defined."
result))
(defmacro ispell-with-safe-default-directory (&rest body)
- "Execute the forms in BODY with a reasonable
-`default-directory'."
+ "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)
@@ -759,8 +761,7 @@ See `ispell-buffer-with-debug' for an example of use."
(let ((ispell-debug-buffer (get-buffer-create "*ispell-debug*")))
(with-current-buffer ispell-debug-buffer
(if append
- (insert
- (format "-----------------------------------------------\n"))
+ (insert "-----------------------------------------------\n")
(erase-buffer)))
ispell-debug-buffer))
@@ -1039,7 +1040,11 @@ did."
Invoke this command before you want to start Hunspell for the first time
with a particular combination of dictionaries. The first dictionary
-in the list must have an affix file where Hunspell affix files are kept."
+in the list must have an affix file where Hunspell affix files are kept.
+
+If you invoke this from Lisp, make sure to precede it with
+a call to `ispell-set-spellchecker-params', as `ispell-change-dictionary'
+calls it only when invoked interactively."
(interactive "sMulti-dictionary combination: ")
;; Make sure the first dictionary in the list is known to us.
(let ((first-dict (car (split-string dict "," t))))
@@ -2393,24 +2398,24 @@ Global `ispell-quit' set to start location to continue spell session."
Selections are:
-DIGIT: Replace the word with a digit offered in the *Choices* buffer.
-SPC: Accept word this time.
-`i': Accept word and insert into private dictionary.
-`a': Accept word for this session.
-`A': Accept word and place in `buffer-local dictionary'.
-`r': Replace word with typed-in value. Rechecked.
-`R': Replace word with typed-in value. Query-replaced in buffer. Rechecked.
-`?': Show these commands.
-`x': Exit spelling buffer. Move cursor to original point.
-`X': Exit spelling buffer. Leaves cursor at the current point, and permits
+\\`0'..\\`9' Replace the word with a digit offered in the *Choices* buffer.
+\\`SPC' Accept word this time.
+\\`i' Accept word and insert into private dictionary.
+\\`a' Accept word for this session.
+\\`A' Accept word and place in `buffer-local dictionary'.
+\\`r' Replace word with typed-in value. Rechecked.
+\\`R' Replace word with typed-in value. Query-replaced in buffer. Rechecked.
+\\`?' Show these commands.
+\\`x' Exit spelling buffer. Move cursor to original point.
+\\`X' Exit spelling buffer. Leaves cursor at the current point, and permits
the aborted check to be completed later.
-`q': Quit spelling session (Kills ispell process).
-`l': Look up typed-in replacement in alternate dictionary. Wildcards okay.
-`u': Like `i', but the word is lower-cased first.
-`m': Place typed-in value in personal dictionary, then recheck current word.
-`C-l': Redraw screen.
-`C-r': Recursive edit.
-`C-z': Suspend Emacs or iconify frame."
+\\`q' Quit spelling session (Kills ispell process).
+\\`l' Look up typed-in replacement in alternate dictionary. Wildcards okay.
+\\`u' Like \\`i', but the word is lower-cased first.
+\\`m' Place typed-in value in personal dictionary, then recheck current word.
+\\`C-l' Redraw screen.
+\\`C-r' Recursive edit.
+\\`C-z' Suspend Emacs or iconify frame."
(if (equal ispell-help-in-bufferp 'electric)
(progn
@@ -2423,26 +2428,28 @@ SPC: Accept word this time.
;;(if (< (window-height) 15)
;; (enlarge-window
;; (- 15 (ispell-adjusted-window-height))))
- (princ "Selections are:
-
-DIGIT: Replace the word with a digit offered in the *Choices* buffer.
-SPC: Accept word this time.
-`i': Accept word and insert into private dictionary.
-`a': Accept word for this session.
-`A': Accept word and place in `buffer-local dictionary'.
-`r': Replace word with typed-in value. Rechecked.
-`R': Replace word with typed-in value. Query-replaced in buffer. Rechecked.
-`?': Show these commands.
-`x': Exit spelling buffer. Move cursor to original point.
-`X': Exit spelling buffer. Leaves cursor at the current point, and permits
- the aborted check to be completed later.
-`q': Quit spelling session (Kills ispell process).
-`l': Look up typed-in replacement in alternate dictionary. Wildcards okay.
-`u': Like `i', but the word is lower-cased first.
-`m': Place typed-in value in personal dictionary, then recheck current word.
-`C-l': Redraw screen.
-`C-r': Recursive edit.
-`C-z': Suspend Emacs or iconify frame.")
+ (princ
+ (substitute-command-keys
+ "Selections are:
+
+\\`0'..\\`9' Replace the word with a digit offered in the *Choices* buffer.
+\\`SPC' Accept word this time.
+\\`i' Accept word and insert into private dictionary.
+\\`a' Accept word for this session.
+\\`A' Accept word and place in `buffer-local dictionary'.
+\\`r' Replace word with typed-in value. Rechecked.
+\\`R' Replace word with typed-in value. Query-replaced in buffer. Rechecked.
+\\`?' Show these commands.
+\\`x' Exit spelling buffer. Move cursor to original point.
+\\`X' Exit spelling buffer. Leaves cursor at the current point, and permits
+ the aborted check to be completed later.
+\\`q' Quit spelling session (Kills ispell process).
+\\`l' Look up typed-in replacement in alternate dictionary. Wildcards okay.
+\\`u' Like \\`i', but the word is lower-cased first.
+\\`m' Place typed-in value in personal dictionary, then recheck current word.
+\\`C-l' Redraw screen.
+\\`C-r' Recursive edit.
+\\`C-z' Suspend Emacs or iconify frame."))
nil)))
@@ -2458,7 +2465,7 @@ SPC: Accept word this time.
(with-current-buffer buffer
(insert (concat help-1 "\n" help-2 "\n" help-3)))
(ispell-display-buffer buffer)
- (sit-for 5)
+ (sit-for ispell-help-timeout)
(kill-buffer "*Ispell Help*"))
(unwind-protect
(let ((resize-mini-windows 'grow-only))
@@ -2468,7 +2475,7 @@ SPC: Accept word this time.
;;(set-minibuffer-window (selected-window))
(enlarge-window 2)
(insert (concat help-1 "\n" help-2 "\n" help-3))
- (sit-for 5))
+ (sit-for ispell-help-timeout))
(erase-buffer)))))))
(define-obsolete-function-alias 'lookup-words 'ispell-lookup-words "24.4")
@@ -2526,7 +2533,7 @@ if defined."
;; `grep' returns status 1 and no output when word not found, which
;; is a perfectly normal thing.
(if (stringp status)
- (error "error: %s exited with signal %s"
+ (error "Error: %s exited with signal %s"
(file-name-nondirectory prog) status)
;; Else collect words into `results' in FIFO order.
(goto-char (point-max))
@@ -2919,7 +2926,14 @@ Keeps argument list for future Ispell invocations for no async support."
;; But first wait to see if some more output is going to arrive.
;; Otherwise we get cool errors like "Can't open ".
(sleep-for 1)
- (ispell-accept-output 3)
+ ;; Only call `ispell-accept-output' if the Ispell process
+ ;; is alive, to avoid showing an unhelpful error message
+ ;; about a missing process, instead of the error which
+ ;; reports why the Ispell process died.
+ (when (if ispell-async-processp
+ (process-live-p ispell-process)
+ ispell-process)
+ (ispell-accept-output 3))
(error "%s" (mapconcat #'identity ispell-filter "\n"))))
(setq ispell-filter nil) ; Discard version ID line
(let ((extended-char-mode (ispell-get-extended-character-mode)))
@@ -3632,8 +3646,7 @@ sequence inside of a word.
Standard ispell choices are then available."
;; FIXME: completion-at-point-function.
(interactive "P")
- (let ((cursor-location (point))
- (case-fold-search-val case-fold-search)
+ (let ((case-fold-search-val case-fold-search)
(word (ispell-get-word nil "\\*")) ; force "previous-word" processing.
start end possibilities replacement)
(setq start (car (cdr word))
@@ -3670,18 +3683,12 @@ Standard ispell choices are then available."
(ispell-add-per-file-word-list word))
(replacement ; REPLACEMENT WORD
(delete-region start end)
- (setq word (if (atom replacement) replacement (car replacement))
- cursor-location (+ (- (length word) (- end start))
- cursor-location))
- (insert word)
- (if (not (atom replacement)) ; recheck spelling of replacement.
- (progn
- (goto-char cursor-location)
- (ispell-word nil t)))))
+ (insert (if (atom replacement) replacement (car replacement)))
+ (unless (atom replacement) ; recheck spelling of replacement.
+ (ispell-word nil t))))
(if (get-buffer ispell-choices-buffer)
(kill-buffer ispell-choices-buffer))))
- (ispell-pdict-save ispell-silently-savep)
- (goto-char cursor-location)))
+ (ispell-pdict-save ispell-silently-savep)))
;;;###autoload
@@ -3878,8 +3885,8 @@ Don't check spelling of message headers except the Subject field.
Don't check included messages.
To abort spell checking of a message region and send the message anyway,
-use the `x' command. (Any subsequent regions will be checked.)
-The `X' command aborts sending the message so that you can edit the buffer.
+use the \\`x' command. (Any subsequent regions will be checked.)
+The \\`X' command aborts sending the message so that you can edit the buffer.
To spell-check whenever a message is sent, include the appropriate lines
in your init file:
@@ -3970,7 +3977,7 @@ You can bind this to the key C-c i in GNUS or mail by adding to
(if (re-search-forward "^Subject: *" end-of-headers t)
(progn
(goto-char (match-end 0))
- (if (and (not (looking-at ".*Re\\>"))
+ (if (and (not (looking-at ".*\\<Re\\>"))
(not (looking-at "\\[")))
(progn
(setq case-fold-search old-case-fold-search)
@@ -4086,7 +4093,7 @@ Includes LaTeX/Nroff modes and extended character mode."
;; Can kill the current ispell process
(defun ispell-buffer-local-dict (&optional no-reload)
- "Initializes local dictionary and local personal dictionary.
+ "Initialize local dictionary and local personal dictionary.
If optional NO-RELOAD is non-nil, do not reload any dictionary.
When a dictionary is defined in the buffer (see variable
`ispell-dictionary-keyword'), it will override the local setting
diff --git a/lisp/textmodes/makeinfo.el b/lisp/textmodes/makeinfo.el
index 13367a09bcf..6b9b3f3e9de 100644
--- a/lisp/textmodes/makeinfo.el
+++ b/lisp/textmodes/makeinfo.el
@@ -175,10 +175,9 @@ command to gain use of `next-error'."
'makeinfo-compilation-sentinel-region)))))))
(defun makeinfo-next-error (_arg _reset)
- "This function is used to disable `next-error' if the user has
-used `makeinfo-region'. Since the compilation process is used on
-a temporary file in that case, calling `next-error' would give
-nonsensical results."
+ "This is used to disable `next-error' if the user has used `makeinfo-region'.
+Since the compilation process is used on a temporary file in that
+case, calling `next-error' would give nonsensical results."
(error "Use `makeinfo-buffer' to gain use of the `next-error' command"))
;; Actually run makeinfo. COMMAND is the command to run. If
diff --git a/lisp/textmodes/mhtml-mode.el b/lisp/textmodes/mhtml-mode.el
index 25905385685..936732153ae 100644
--- a/lisp/textmodes/mhtml-mode.el
+++ b/lisp/textmodes/mhtml-mode.el
@@ -19,6 +19,8 @@
;; 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:
(eval-when-compile (require 'cl-lib))
diff --git a/lisp/textmodes/page-ext.el b/lisp/textmodes/page-ext.el
index 87c91e8f1b7..558d6b81d77 100644
--- a/lisp/textmodes/page-ext.el
+++ b/lisp/textmodes/page-ext.el
@@ -257,7 +257,7 @@
;;; Addresses related variables
(defcustom pages-addresses-file-name "~/addresses"
- "Standard name for file of addresses. Entries separated by page-delimiter.
+ "Standard name for file of addresses. Entries separated by `page-delimiter'.
Used by `pages-directory-for-addresses' function."
:type 'file)
diff --git a/lisp/textmodes/picture.el b/lisp/textmodes/picture.el
index 1d5d1caeabc..cb7f275ea6f 100644
--- a/lisp/textmodes/picture.el
+++ b/lisp/textmodes/picture.el
@@ -514,7 +514,7 @@ Interactively, reads the register using `register-read-with-preview'."
(move-to-column column t))))
(defun picture-yank-rectangle (&optional insertp)
- "Overlay rectangle saved by \\[picture-clear-rectangle]
+ "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
@@ -699,10 +699,10 @@ afterwards settable by these commands:
Move southwest (sw) after insertion: \\[picture-movement-sw]
Move southeast (se) after insertion: \\[picture-movement-se]
- Move westnorthwest (wnw) after insertion: C-u \\[picture-movement-nw]
- Move eastnortheast (ene) after insertion: C-u \\[picture-movement-ne]
- Move westsouthwest (wsw) after insertion: C-u \\[picture-movement-sw]
- Move eastsoutheast (ese) after insertion: C-u \\[picture-movement-se]
+ Move westnorthwest (wnw) after insertion: \\[universal-argument] \\[picture-movement-nw]
+ Move eastnortheast (ene) after insertion: \\[universal-argument] \\[picture-movement-ne]
+ Move westsouthwest (wsw) after insertion: \\[universal-argument] \\[picture-movement-sw]
+ Move eastsoutheast (ese) after insertion: \\[universal-argument] \\[picture-movement-se]
The current direction is displayed in the mode line. The initial
direction is right. Whitespace is inserted and tabs are changed to
diff --git a/lisp/textmodes/pixel-fill.el b/lisp/textmodes/pixel-fill.el
new file mode 100644
index 00000000000..0a0f0eb8b66
--- /dev/null
+++ b/lisp/textmodes/pixel-fill.el
@@ -0,0 +1,240 @@
+;;; pixel-fill.el --- variable pitch filling functions -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Maintainer: emacs-devel@gnu.org
+;; Keywords: filling
+
+;; 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:
+
+;; The main entry point is `pixel-fill-region', but
+;; `pixel-fill-find-fill-point' can also be useful by itself.
+
+;;; Code:
+
+(require 'kinsoku)
+
+(defgroup pixel-fill nil
+ "Filling based on pixel widths."
+ :group 'fill
+ :version "29.1")
+
+(defcustom pixel-fill-respect-kinsoku t
+ "If nil, fill even if we can't find a good kinsoku point.
+Kinsoku is a Japanese word meaning a rule that should not be violated.
+In Emacs, it is a term used for characters, e.g. punctuation marks,
+parentheses, and so on, that should not be placed in the beginning
+of a line or the end of a line."
+ :type 'boolean
+ :version "29.1")
+
+(defun pixel-fill-width (&optional columns window)
+ "Return the pixel width corresponding to COLUMNS in WINDOW.
+If COLUMNS in nil, use the enture window width.
+
+If WINDOW is nil, this defaults to the current window."
+ (unless window
+ (setq window (selected-window)))
+ (let ((frame (window-frame window)))
+ (if columns
+ (* (frame-char-width frame) columns)
+ (- (window-body-width nil t)
+ (* 2 (frame-char-width frame))
+ ;; We need to adjust the available width for when the user
+ ;; disables the fringes, which will cause the display
+ ;; engine usurp one column for the continuation glyph.
+ (if (and (fboundp 'fringe-columns)
+ (or (not (zerop (fringe-columns 'right)))
+ (not (zerop (fringe-columns 'left)))))
+ 0
+ (* (frame-char-width frame) 2))
+ 1))))
+
+(defun pixel-fill-region (start end pixel-width)
+ "Fill the region between START and END.
+This will attempt to reformat the text in the region to have no
+lines that are visually wider than PIXEL-WIDTH.
+
+If START isn't at the start of a line, the horizontal position of
+START, converted to pixel units, will be used as the indentation
+prefix on subsequent lines."
+ (save-excursion
+ (goto-char start)
+ (let ((indentation
+ (car (window-text-pixel-size nil (line-beginning-position)
+ (point))))
+ (newline-end nil))
+ (when (> indentation pixel-width)
+ (error "The indentation (%s) is wider than the fill width (%s)"
+ indentation pixel-width))
+ (save-restriction
+ (narrow-to-region start end)
+ (goto-char (point-max))
+ (when (looking-back "\n[ \t]*" (point-min))
+ (setq newline-end t))
+ (goto-char (point-min))
+ ;; First replace all whitespace with space.
+ (while (re-search-forward "[ \t\n]+" nil t)
+ (cond
+ ((or (= (match-beginning 0) start)
+ (= (match-end 0) end))
+ (delete-region (match-beginning 0) (match-end 0)))
+ ;; If there's just a single space here, don't replace.
+ ((not (and (= (- (match-end 0) (match-beginning 0)) 1)
+ (= (char-after (match-beginning 0)) ?\s)))
+ (replace-match
+ ;; We need to use a space that has an appropriate width.
+ (propertize " " 'face
+ (get-text-property (match-beginning 0) 'face))))))
+ (goto-char start)
+ (pixel-fill--fill-line pixel-width indentation)
+ (goto-char (point-max))
+ (when newline-end
+ (insert "\n"))))))
+
+(defun pixel-fill--goto-pixel (width)
+ (vertical-motion (cons (/ width (frame-char-width)) 0)))
+
+(defun pixel-fill--fill-line (width &optional indentation)
+ (let ((start (point)))
+ (pixel-fill--goto-pixel width)
+ (while (not (eolp))
+ ;; We have to do some folding. First find the first previous
+ ;; point suitable for folding.
+ (when (or (not (pixel-fill-find-fill-point (line-beginning-position)))
+ (= (point) start))
+ ;; We had unbreakable text (for this width), so just go to
+ ;; the first space and carry on.
+ (beginning-of-line)
+ (skip-chars-forward " ")
+ (search-forward " " (line-end-position) 'move))
+ (when (= (preceding-char) ?\s)
+ (delete-char -1))
+ (unless (eobp)
+ (insert ?\n)
+ (when (> indentation 0)
+ (insert (propertize " " 'display
+ (list 'space :align-to (list indentation))))))
+ (setq start (point))
+ (unless (eobp)
+ (pixel-fill--goto-pixel width)))))
+
+(define-inline pixel-fill--char-breakable-p (char)
+ "Return non-nil if a line can be broken before and after CHAR."
+ (inline-quote (aref fill-find-break-point-function-table ,char)))
+
+(define-inline pixel-fill--char-nospace-p (char)
+ "Return non-nil if no space is required before and after CHAR."
+ (inline-quote (aref fill-nospace-between-words-table ,char)))
+
+(define-inline pixel-fill--char-kinsoku-bol-p (char)
+ "Return non-nil if a line ought not to begin with CHAR."
+ (inline-letevals (char)
+ (inline-quote (and (not (eq ,char ?'))
+ (aref (char-category-set ,char) ?>)))))
+
+(define-inline pixel-fill--char-kinsoku-eol-p (char)
+ "Return non-nil if a line ought not to end with CHAR."
+ (inline-quote (aref (char-category-set ,char) ?<)))
+
+(defun pixel-fill-find-fill-point (start)
+ "Find a place suitable for breaking the current line.
+START should be the earliest buffer position that should be considered
+(typically the start of the line), and this function will search
+backward in the current buffer from the current position."
+ (let ((bp (point))
+ (end (point))
+ failed)
+ (while (not
+ (or (setq failed (<= (point) start))
+ (eq (preceding-char) ?\s)
+ (eq (following-char) ?\s)
+ (pixel-fill--char-breakable-p (preceding-char))
+ (pixel-fill--char-breakable-p (following-char))
+ (and (pixel-fill--char-kinsoku-bol-p (preceding-char))
+ (pixel-fill--char-breakable-p (following-char))
+ (not (pixel-fill--char-kinsoku-bol-p (following-char))))
+ (pixel-fill--char-kinsoku-eol-p (following-char))
+ (bolp)))
+ (backward-char 1))
+ (if failed
+ ;; There's no breakable point, so we give it up.
+ (let (found)
+ (goto-char bp)
+ ;; Don't overflow the window edge, even if
+ ;; `pixel-fill-respect-kinsoku' is t.
+ (when pixel-fill-respect-kinsoku
+ (while (setq found (re-search-forward
+ "\\(\\c>\\)\\| \\|\\c<\\|\\c|"
+ (line-end-position) 'move)))
+ (if (and found
+ (not (match-beginning 1)))
+ (goto-char (match-beginning 0)))))
+ (or
+ (eolp)
+ ;; Don't put kinsoku-bol characters at the beginning of a line,
+ ;; or kinsoku-eol characters at the end of a line.
+ (cond
+ ;; Don't overflow the window edge, even if `pixel-fill-respect-kinsoku'
+ ;; is t.
+ ((not pixel-fill-respect-kinsoku)
+ (while (and (not (eq (preceding-char) ?\s))
+ (or (pixel-fill--char-kinsoku-eol-p (preceding-char))
+ (pixel-fill--char-kinsoku-bol-p (following-char))))
+ (backward-char 1))
+ (when (setq failed (<= (point) start))
+ ;; There's no breakable point that doesn't violate kinsoku,
+ ;; so we look for the second best position.
+ (while (and (progn
+ (forward-char 1)
+ (<= (point) end))
+ (progn
+ (setq bp (point))
+ (pixel-fill--char-kinsoku-eol-p (following-char)))))
+ (goto-char bp)))
+ ((pixel-fill--char-kinsoku-eol-p (preceding-char))
+ ;; Find backward the point where kinsoku-eol characters begin.
+ (let ((count 4))
+ (while
+ (progn
+ (backward-char 1)
+ (and (> (setq count (1- count)) 0)
+ (not (eq (preceding-char) ?\s))
+ (or (pixel-fill--char-kinsoku-eol-p (preceding-char))
+ (pixel-fill--char-kinsoku-bol-p (following-char)))))))
+ (when (setq failed (<= (point) start))
+ ;; There's no breakable point that doesn't violate kinsoku,
+ ;; so we go to the second best position.
+ (if (looking-at "\\(\\c<+\\)\\c<")
+ (goto-char (match-end 1))
+ (forward-char 1))))
+ ((pixel-fill--char-kinsoku-bol-p (following-char))
+ ;; Find forward the point where kinsoku-bol characters end.
+ (let ((count 4))
+ (while (progn
+ (forward-char 1)
+ (and (>= (setq count (1- count)) 0)
+ (pixel-fill--char-kinsoku-bol-p (following-char))
+ (pixel-fill--char-breakable-p (following-char))))))))
+ (when (eq (following-char) ?\s)
+ (forward-char 1))))
+ (not failed)))
+
+(provide 'pixel-fill)
+
+;;; pixel-fill.el ends here
diff --git a/lisp/textmodes/refbib.el b/lisp/textmodes/refbib.el
index 084b17c676b..ce556be00db 100644
--- a/lisp/textmodes/refbib.el
+++ b/lisp/textmodes/refbib.el
@@ -195,7 +195,7 @@ This is in addition to the `r2b-capitalize-title-stop-words'.")
(sit-for 0))))
(defun r2b-match (exp)
- "Returns string matched in current buffer."
+ "Return string matched in current buffer."
(buffer-substring (match-beginning exp) (match-end exp)))
(defcustom r2b-out-buf-name "*Out*"
diff --git a/lisp/textmodes/refill.el b/lisp/textmodes/refill.el
index 0a0e4cc444c..b2ebbd5f375 100644
--- a/lisp/textmodes/refill.el
+++ b/lisp/textmodes/refill.el
@@ -153,7 +153,7 @@ regardless of the number of after-change calls from commands doing
complex processing.")
(defun refill-after-change-function (_beg end _len)
- "Function for `after-change-functions' which just sets `refill-doit'."
+ "Set `refill-doit'. Used by `after-change-functions'."
(unless undo-in-progress
(setq refill-doit end)))
diff --git a/lisp/textmodes/reftex-cite.el b/lisp/textmodes/reftex-cite.el
index 895064b82f3..e1475934ddb 100644
--- a/lisp/textmodes/reftex-cite.el
+++ b/lisp/textmodes/reftex-cite.el
@@ -30,11 +30,11 @@
;;; Variables and constants
(defvar reftex-cite-regexp-hist nil
- "The history list of regular expressions used for citations")
+ "The history list of regular expressions used for citations.")
(defconst reftex-citation-prompt
"Select: [n]ext [p]revious [r]estrict [ ]full_entry [q]uit RET [?]Help+more"
- "Prompt and help string for citation selection")
+ "Prompt and help string for citation selection.")
(defconst reftex-citation-help
" n / p Go to next/previous entry (Cursor motion works as well).
@@ -221,7 +221,7 @@ Return list with entries."
(if (string-match "\\`[ \t]*\\'" (or first-re ""))
(user-error "Empty regular expression"))
(if (string-match first-re "")
- (user-error "Regular expression matches the empty string."))
+ (user-error "Regular expression matches the empty string"))
(save-excursion
(save-window-excursion
@@ -628,7 +628,7 @@ If NO-INSERT is non-nil, nothing is inserted, only the selected key returned.
FORMAT-KEY can be used to pre-select a citation format.
-When called with a `C-u' prefix, prompt for optional arguments in
+When called with a \\[universal-argument] prefix, prompt for optional arguments in
cite macros. When called with a numeric prefix, make that many
citations. When called with point inside the braces of a `\\cite'
command, it will add another key, ignoring the value of
@@ -814,7 +814,7 @@ in order to only add another reference in the same cite command."
(interactive)
(reftex-citation nil ?t))
-(defvar reftex-select-bib-map)
+(defvar reftex-select-bib-mode-map)
(defvar reftex--found-list)
(defun reftex-offer-bib-menu ()
"Offer bib menu and return list of selected items."
@@ -870,7 +870,7 @@ in order to only add another reference in the same cite command."
(reftex-select-item
reftex-citation-prompt
reftex-citation-help
- reftex-select-bib-map
+ reftex-select-bib-mode-map
nil
'reftex-bibtex-selection-callback nil))
(setq key (car rtn)
diff --git a/lisp/textmodes/reftex-dcr.el b/lisp/textmodes/reftex-dcr.el
index a21dd3362b0..ee26d911a5d 100644
--- a/lisp/textmodes/reftex-dcr.el
+++ b/lisp/textmodes/reftex-dcr.el
@@ -32,17 +32,20 @@
;;;###autoload
(defun reftex-view-crossref (&optional arg auto-how fail-quietly)
- "View cross reference of macro at point. Point must be on the KEY
-argument. When at a `\\ref' macro, show corresponding `\\label'
-definition, also in external documents (`xr'). When on a label, show
-a locations where KEY is referenced. Subsequent calls find additional
-locations. When on a `\\cite', show the associated `\\bibitem' macro or
-the BibTeX database entry. When on a `\\bibitem', show a `\\cite' macro
-which uses this KEY. When on an `\\index', show other locations marked
-by the same index entry.
+ "View cross reference of macro at point.
+
+Point must be on the KEY argument. When at a `\\ref' macro, show
+corresponding `\\label' definition, also in external
+documents (`xr'). When on a label, show a locations where KEY is
+referenced. Subsequent calls find additional locations. When on
+a `\\cite', show the associated `\\bibitem' macro or the BibTeX
+database entry. When on a `\\bibitem', show a `\\cite' macro
+which uses this KEY. When on an `\\index', show other locations
+marked by the same index entry.
+
To define additional cross referencing items, use the option
`reftex-view-crossref-extra'. See also `reftex-view-crossref-from-bibtex'.
-With one or two C-u prefixes, enforce rescanning of the document.
+With one or two \\[universal-argument] prefixes, enforce rescanning of the document.
With argument 2, select the window showing the cross reference.
AUTO-HOW is only for the automatic crossref display and is handed through
to the functions `reftex-view-cr-cite' and `reftex-view-cr-ref'."
diff --git a/lisp/textmodes/reftex-global.el b/lisp/textmodes/reftex-global.el
index 3b7518e5c3f..f787f5f3e56 100644
--- a/lisp/textmodes/reftex-global.el
+++ b/lisp/textmodes/reftex-global.el
@@ -148,8 +148,10 @@ No active TAGS table is required."
(erase-buffer)
(insert " MULTIPLE LABELS IN CURRENT DOCUMENT:\n")
(insert
- " Move point to label and type `r' to run a query-replace on the label\n"
- " and its references. Type `q' to exit this buffer.\n\n")
+ (substitute-command-keys
+ " Move point to label and type \\`r' to run a query-replace on the label\n")
+ (substitute-command-keys
+ " and its references. Type \\`q' to exit this buffer.\n\n"))
(insert " LABEL FILE\n")
(insert " -------------------------------------------------------------\n")
(use-local-map (make-sparse-keymap))
@@ -338,17 +340,17 @@ Also checks if buffers visiting the files are in read-only mode."
(while (setq file (pop files))
(unless (file-exists-p file)
(ding)
- (or (y-or-n-p (format "No such file %s. Continue? " file))
+ (or (y-or-n-p (format "No such file %s. Continue?" file))
(error "Abort")))
(unless (file-writable-p file)
(ding)
- (or (y-or-n-p (format "No write access to %s. Continue? " file))
+ (or (y-or-n-p (format "No write access to %s. Continue?" file))
(error "Abort")))
(when (and (setq buf (find-buffer-visiting file))
(with-current-buffer buf
buffer-read-only))
(ding)
- (or (y-or-n-p (format "Buffer %s is read-only. Continue? "
+ (or (y-or-n-p (format "Buffer %s is read-only. Continue?"
(buffer-name buf)))
(error "Abort"))))))
diff --git a/lisp/textmodes/reftex-index.el b/lisp/textmodes/reftex-index.el
index 28cc7db2dcd..357f7da2f9d 100644
--- a/lisp/textmodes/reftex-index.el
+++ b/lisp/textmodes/reftex-index.el
@@ -29,17 +29,15 @@
(require 'reftex)
-;; START remove for XEmacs release
(defvar TeX-master)
-;; END remove for XEmacs release
;;;###autoload
(defun reftex-index-selection-or-word (&optional arg phrase)
"Put selection or the word near point into the default index macro.
This uses the information in `reftex-index-default-macro' to make an index
entry. The phrase indexed is the current selection or the word near point.
-When called with one `C-u' prefix, let the user have a chance to edit the
-index entry. When called with 2 `C-u' as prefix, also ask for the index
+When called with one \\[universal-argument] prefix, let the user have a chance to edit the
+index entry. When called with 2 \\[universal-argument] as prefix, also ask for the index
macro and other stuff.
When called inside TeX math mode as determined by the `texmathp.el' library
which is part of AUCTeX, the string is first processed with the
@@ -462,7 +460,7 @@ _ ^ Add/Remove parent key (to make this item a subitem).
"Display a buffer with an index compiled from the current document.
When the document has multiple indices, first prompts for the correct one.
When index support is turned off, offer to turn it on.
-With one or two `C-u' prefixes, rescan document first.
+With one or two \\[universal-argument] prefixes, rescan document first.
With prefix 2, restrict index to current document section.
With prefix 3, restrict index to region."
@@ -842,7 +840,7 @@ The function will go to the section where the entry at point was defined."
(reftex-display-index nil nil 'redo))
(defun reftex-index-restrict-to-section (&optional force)
- "Restrict index to entries defined in same document sect. as entry at point."
+ "Restrict index to entries defined in same document section as entry at point."
;; Optional FORCE means, even if point is not on an index entry.
(interactive)
(let* ((data (get-text-property (point) :data))
@@ -934,8 +932,8 @@ When index is restricted, select the previous section as restriction criterion."
(t nil))))
(defun reftex-index-analyze-entry (data)
- ;; This splits the index context so that key, attribute and visual
- ;; values are accessible individually.
+ "Split index context so that key, attribute and visual
+values are accessible individually."
(interactive)
(let* ((arg (nth 5 data))
(context (nth 2 data))
@@ -1150,7 +1148,7 @@ When index is restricted, select the previous section as restriction criterion."
;; Some constants and variables
(defconst reftex-index-phrases-comment-regexp "^[ \t]*%.*"
- "Regular expression to match comment lines in phrases buffer")
+ "Regular expression to match comment lines in phrases buffer.")
(defconst reftex-index-phrases-macrodef-regexp
"^\\(>>>INDEX_MACRO_DEFINITION:\\)[ \t]+\\(\\S-\\)\\( *\t[ \t]*\\)\\([^\t]*[^ \t]\\)\\( *\t[ \t]*\\)\\(\\S-+\\)"
"Regular expression to match macro definition lines the phrases buffer.")
@@ -1666,7 +1664,7 @@ this function repeatedly."
(repeat
(princ (format " Index entry: %s\n" phrase)))
(t
- (princ (format " Index key: <<Given by the match>>\n"))))
+ (princ " Index key: <<Given by the match>>\n")))
(princ (format " Example: %s\n" example))
(terpri)
(princ (format "Total matches: %s in %s\n"
@@ -2068,7 +2066,7 @@ both ends."
(defun reftex-index-phrases-replace-space (pos)
"If there is a space at POS, replace it with a newline char.
-Does not do a save-excursion."
+Does not do a `save-excursion'."
(when (equal (char-after pos) ?\ )
(goto-char pos)
(delete-char 1)
diff --git a/lisp/textmodes/reftex-parse.el b/lisp/textmodes/reftex-parse.el
index 9def10cee05..b8c75cb21b6 100644
--- a/lisp/textmodes/reftex-parse.el
+++ b/lisp/textmodes/reftex-parse.el
@@ -345,7 +345,17 @@ of master file."
;; Find external document specifications
(goto-char 1)
- (while (re-search-forward "[\n\r][ \t]*\\\\externaldocument\\(\\[\\([^]]*\\)\\]\\)?{\\([^}]+\\)}" nil t)
+ (while (re-search-forward
+ (concat "[\n\r][ \t]*"
+ ;; Support \externalcitedocument macro
+ "\\\\external\\(?:cite\\)?document"
+ ;; The optional prefix
+ "\\(\\[\\([^]]*\\)\\]\\)?"
+ ;; The 2nd opt. arg can only be nocite
+ "\\(?:\\[nocite\\]\\)?"
+ ;; Mandatory file argument
+ "{\\([^}]+\\)}")
+ nil t)
(push (list 'xr-doc (reftex-match-string 2)
(reftex-match-string 3))
docstruct))
@@ -435,7 +445,8 @@ This function also makes sure the old toc markers do not point anywhere."
;;;###autoload
(defun reftex-section-info (file)
"Return a section entry for the current match.
-Careful: This function expects the match-data to be still in place!"
+Careful: This function expects the `match-data' to still be in
+place!"
(let* ((marker (set-marker (make-marker) (1- (match-beginning 3))))
(macro (reftex-match-string 3))
(prefix (save-match-data
@@ -494,7 +505,8 @@ will rescan the entire document."
;;;###autoload
(defun reftex-index-info (file)
"Return an index entry for the current match.
-Careful: This function expects the match-data to be still in place!"
+Careful: This function expects the `match-data' to still be in
+place!"
(catch 'exit
(let* ((macro (reftex-match-string 10))
(bom (match-beginning 10))
diff --git a/lisp/textmodes/reftex-ref.el b/lisp/textmodes/reftex-ref.el
index 19081825931..15d86b359cc 100644
--- a/lisp/textmodes/reftex-ref.el
+++ b/lisp/textmodes/reftex-ref.el
@@ -230,7 +230,7 @@ This function is controlled by the settings of reftex-insert-label-flags."
(symbol-value reftex-docstruct-symbol)))
(ding)
(if (y-or-n-p
- (format-message "Label `%s' exists. Use anyway? " label))
+ (format-message "Label `%s' exists. Use anyway?" label))
(setq valid t)))
;; Label is ok
@@ -415,7 +415,7 @@ reftex-label. Rescanning of the buffer can also be requested from the
label selection menu.
The function returns the selected label or nil.
If NO-INSERT is non-nil, do not insert \\ref command, just return label.
-When called with 2 C-u prefix args, disable magic word recognition."
+When called with 2 \\[universal-argument] prefix args, disable magic word recognition."
(interactive)
@@ -533,7 +533,7 @@ When called with 2 C-u prefix args, disable magic word recognition."
(cons (cdr cell) (- (match-end 0) (match-end 1)))
nil)))
-(defvar reftex-select-label-map)
+(defvar reftex-select-label-mode-map)
(defun reftex-offer-label-menu (typekey)
;; Offer a menu with the appropriate labels.
(let* ((buf (current-buffer))
@@ -605,7 +605,7 @@ When called with 2 C-u prefix args, disable magic word recognition."
(reftex-select-item
reftex-select-label-prompt
reftex-select-label-help
- reftex-select-label-map
+ reftex-select-label-mode-map
offset
'reftex-show-label-location follow))
(setq key (car rtn)
diff --git a/lisp/textmodes/reftex-toc.el b/lisp/textmodes/reftex-toc.el
index b5643491338..b5f53ba86e7 100644
--- a/lisp/textmodes/reftex-toc.el
+++ b/lisp/textmodes/reftex-toc.el
@@ -180,7 +180,7 @@ z Jump to a specific section (e.g. '3 z' goes to section 3).")
(defun reftex-toc (&optional _rebuild reuse)
;; FIXME: Get rid of the `rebuild' argument.
"Show the table of contents for the current document.
-When called with a raw C-u prefix, rescan the document first."
+When called with a raw \\[universal-argument] prefix, rescan the document first."
;; The REUSE argument means, search all visible frames for a window
;; displaying the toc window. If yes, reuse this window.
@@ -856,10 +856,10 @@ label prefix determines the wording of a reference."
(label (car toc)) newlabel)
(if (not (stringp label))
(error "This is not a label entry"))
- (setq newlabel (read-string (format "Rename label \"%s\" to:" label)))
+ (setq newlabel (read-string (format "Rename label \"%s\" to: " label)))
(if (assoc newlabel (symbol-value reftex-docstruct-symbol))
(if (not (y-or-n-p
- (format-message "Label `%s' exists. Use anyway? " label)))
+ (format-message "Label `%s' exists. Use anyway? " newlabel)))
(error "Abort")))
(save-excursion
(save-window-excursion
diff --git a/lisp/textmodes/reftex-vars.el b/lisp/textmodes/reftex-vars.el
index 96065ee69e1..dedd74607ae 100644
--- a/lisp/textmodes/reftex-vars.el
+++ b/lisp/textmodes/reftex-vars.el
@@ -70,12 +70,16 @@
("tabwindow" ?f nil nil 1)))
(rotating "Sidewaysfigure and table"
- (("sidewaysfigure" ?f nil nil caption)
- ("sidewaystable" ?t nil nil caption)))
+ (("sidewaysfigure" ?f nil nil caption)
+ ("sidewaysfigure*" ?f nil nil caption)
+ ("sidewaystable" ?t nil nil caption)
+ ("sidewaystable*" ?t nil nil caption)))
- (sidecap "CSfigure and SCtable"
- (("SCfigure" ?f nil nil caption)
- ("SCtable" ?t nil nil caption)))
+ (sidecap "SCfigure and SCtable"
+ (("SCfigure" ?f nil nil caption)
+ ("SCfigure*" ?f nil nil caption)
+ ("SCtable" ?t nil nil caption)
+ ("SCtable*" ?t nil nil caption)))
(subfigure "Subfigure environments/macro"
(("subfigure" ?f nil nil caption)
@@ -263,7 +267,7 @@ distribution. Mixed-case symbols are convenience aliases.")
(defgroup reftex nil
"LaTeX label and citation support."
:tag "RefTeX"
- :link '(url-link :tag "Home Page"
+ :link '(url-link :tag "Website"
"https://www.gnu.org/software/auctex/reftex.html")
:link '(emacs-commentary-link :tag "Commentary in reftex.el" "reftex.el")
:link '(custom-manual "(reftex)Top")
@@ -330,7 +334,8 @@ select the nearest entry with the correct new level."
"The maximum level of toc entries which will be included in the TOC.
Section headings with a bigger level will be ignored. In RefTeX, chapters
are level 1, sections are level 2 etc.
-This variable can be changed from within the *toc* buffer with the `t' key."
+This variable can be changed from within the *toc* buffer with \
+\\<reftex-toc-mode-map>\\[reftex-toc-max-level]."
:group 'reftex-table-of-contents-browser
:type 'integer)
@@ -391,19 +396,19 @@ that the *toc* window fills half the frame."
(defcustom reftex-toc-include-file-boundaries nil
"Non-nil means, include file boundaries in *toc* buffer.
-This flag can be toggled from within the *toc* buffer with the `F' key."
+This flag can be toggled from within the *toc* buffer with the \\`F' key."
:group 'reftex-table-of-contents-browser
:type 'boolean)
(defcustom reftex-toc-include-labels nil
"Non-nil means, include labels in *toc* buffer.
-This flag can be toggled from within the *toc* buffer with the `l' key."
+This flag can be toggled from within the *toc* buffer with the \\`l' key."
:group 'reftex-table-of-contents-browser
:type 'boolean)
(defcustom reftex-toc-include-index-entries nil
"Non-nil means, include index entries in *toc* buffer.
-This flag can be toggled from within the *toc* buffer with the `i' key."
+This flag can be toggled from within the *toc* buffer with the \\`i' key."
:group 'reftex-table-of-contents-browser
:type 'boolean)
@@ -421,20 +426,20 @@ changed."
(defcustom reftex-toc-include-context nil
"Non-nil means, include context with labels in the *toc* buffer.
Context will only be shown when labels are visible as well.
-This flag can be toggled from within the *toc* buffer with the `c' key."
+This flag can be toggled from within the *toc* buffer with the \\`c' key."
:group 'reftex-table-of-contents-browser
:type 'boolean)
(defcustom reftex-toc-follow-mode nil
"Non-nil means, point in *toc* buffer will cause other window to follow.
The other window will show the corresponding part of the document.
-This flag can be toggled from within the *toc* buffer with the `f' key."
+This flag can be toggled from within the *toc* buffer with the \\`f' key."
:group 'reftex-table-of-contents-browser
:type 'boolean)
(defcustom reftex-revisit-to-follow nil
- "Non-nil means, follow-mode will revisit files if necessary.
-If nil, follow-mode will be suspended for stuff in unvisited files."
+ "Non-nil means, `follow-mode' will revisit files if necessary.
+If nil, `follow-mode' will be suspended for stuff in unvisited files."
:group 'reftex-table-of-contents-browser
:group 'reftex-referencing-labels
:type 'boolean)
@@ -1208,7 +1213,7 @@ path."
:type '(repeat (file)))
(defcustom reftex-sort-bibtex-matches 'reverse-year
- "Sorting of the entries found in BibTeX databases by reftex-citation.
+ "Sorting of the entries found in BibTeX databases by `reftex-citation'.
Possible values:
nil Do not sort entries.
`author' Sort entries by author name.
@@ -1292,7 +1297,7 @@ prompt for values. Possible values are:
nil Never prompt for optional arguments
t Always prompt
-maybe Prompt only if `reftex-citation' was called with C-u prefix arg
+maybe Prompt only if `reftex-citation' was called with \\[universal-argument] prefix arg
Unnecessary empty optional arguments are removed before insertion into
the buffer. See `reftex-cite-cleanup-optional-args'."
@@ -1364,7 +1369,7 @@ should return the string to insert into the buffer."
:type '(choice (const nil) function))
(defcustom reftex-select-bib-mode-hook nil
- "Mode hook for reftex-select-bib-mode."
+ "Mode hook for `reftex-select-bib-mode'."
:group 'reftex-citation-support
:type 'hook)
@@ -1626,14 +1631,14 @@ to that section."
(defcustom reftex-index-include-context nil
"Non-nil means, display the index definition context in the index buffer.
-This flag may also be toggled from the index buffer with the `c' key."
+This flag may also be toggled from the index buffer with the \\`c' key."
:group 'reftex-index-support
:type 'boolean)
(defcustom reftex-index-follow-mode nil
"Non-nil means, point in *Index* buffer will cause other window to follow.
The other window will show the corresponding part of the document.
-This flag can be toggled from within the *Index* buffer with the `f' key."
+This flag can be toggled from within the *Index* buffer with the \\`f' key."
:group 'reftex-table-of-contents-browser
:type 'boolean)
@@ -1694,8 +1699,8 @@ entries and for BibTeX database files with live associated buffers."
"Non-nil means, echoed information for cite macros is cached.
The information displayed in the echo area for cite macros is
cached and even saved along with the parsing information. The
-cache survives document scans. In order to clear it, use M-x
-reftex-reset-mode <RET>."
+cache survives document scans. In order to clear it, use
+\\[reftex-reset-mode]."
:group 'reftex-viewing-cross-references
:type 'boolean)
@@ -1840,7 +1845,7 @@ upon the variable `reftex-initialize-temporary-buffers'."
(defcustom reftex-initialize-temporary-buffers nil
"Non-nil means do initializations even when visiting file temporarily.
-When nil, RefTeX may turn off find-file hooks and other stuff to briefly
+When nil, RefTeX may turn off `find-file' hooks and other stuff to briefly
visit a file.
When t, the full default initializations are done (find-file-hook etc.).
Instead of t or nil, this variable may also be a list of hook functions to
@@ -1861,11 +1866,12 @@ of the regular expressions in this list, that file is not parsed by RefTeX."
(defcustom reftex-enable-partial-scans nil
"Non-nil means, re-parse only 1 file when asked to re-parse.
-Re-parsing is normally requested with a `C-u' prefix to many RefTeX commands,
-or with the `r' key in menus. When this option is t in a multifile document,
+Re-parsing is normally requested with a \\[universal-argument] prefix to many RefTeX commands,
+or with the \\`r' key in menus. When this option is t in a multifile document,
we will only parse the current buffer, or the file associated with the label
or section heading near point in a menu. Requesting re-parsing of an entire
-multifile document then requires a `C-u C-u' prefix or the capital `R' key
+multifile document then requires a \\[universal-argument] \
+\\[universal-argument] prefix or the capital \\`R' key
in menus."
:group 'reftex-optimizations-for-large-documents
:type 'boolean)
@@ -1911,7 +1917,7 @@ when new labels in its category are added. See the variable
When a new label is defined with `reftex-label', all selection buffers
associated with that label category are emptied, in order to force an
update upon next use. When nil, the buffers are left alone and have to be
-updated by hand, with the `g' key from the label selection process.
+updated by hand, with the \\`g' key from the label selection process.
The value of this variable will only have any effect when
`reftex-use-multiple-selection-buffers' is non-nil."
:group 'reftex-optimizations-for-large-documents
@@ -1963,7 +1969,7 @@ instead or as well. The variable may have one of these values:
both Both cursor and mouse trigger highlighting.
Changing this variable requires rebuilding the selection and *toc* buffers
-to become effective (keys `g' or `r')."
+to become effective (keys \\`g' or \\`r')."
:group 'reftex-fontification-configurations
:type '(choice
(const :tag "Never" nil)
diff --git a/lisp/textmodes/reftex.el b/lisp/textmodes/reftex.el
index 1cb2cf40c3b..f7424b60b36 100644
--- a/lisp/textmodes/reftex.el
+++ b/lisp/textmodes/reftex.el
@@ -1,4 +1,5 @@
;;; reftex.el --- minor mode for doing \label, \ref, \cite, \index in LaTeX -*- lexical-binding: t; -*-
+
;; Copyright (C) 1997-2000, 2003-2021 Free Software Foundation, Inc.
;; Author: Carsten Dominik <dominik@science.uva.nl>
@@ -1207,7 +1208,7 @@ Valid actions are: readable, restore, read, kill, write."
(if (file-writable-p file)
(with-temp-file file
(message "Writing parse file %s" (abbreviate-file-name file))
- (insert (format ";; RefTeX parse info file\n"))
+ (insert ";; RefTeX parse info file\n")
(insert (format ";; File: %s\n" master))
(insert (format ";; User: %s (%s)\n\n"
(user-login-name) (user-full-name)))
@@ -1930,7 +1931,7 @@ When DIE is non-nil, throw an error if file not found."
(defun reftex-convert-string (string split-re invalid-re dot keep-fp
nwords maxchar invalid abbrev sep
ignore-words &optional downcase)
- "Convert a string (a sentence) to something shorter.
+ "Convert STRING (a sentence) to something shorter.
SPLIT-RE is the regular expression used to split the string into words.
INVALID-RE matches characters which are invalid in the final string.
DOT t means add dots to abbreviated words.
@@ -2139,7 +2140,7 @@ IGNORE-WORDS List of words which should be removed from the string."
(make-variable-buffer-local 'reftex-isearch-minor-mode)
(easy-menu-define reftex-mode-menu reftex-mode-map
- "Menu used in RefTeX mode"
+ "Menu used in RefTeX mode."
`("Ref"
["Table of Contents" reftex-toc t]
["Recenter TOC" reftex-toc-recenter t]
diff --git a/lisp/textmodes/rst.el b/lisp/textmodes/rst.el
index 1471be0ecd6..ed1d721f82c 100644
--- a/lisp/textmodes/rst.el
+++ b/lisp/textmodes/rst.el
@@ -2444,7 +2444,7 @@ PREFER-ROMAN roman numbering is preferred over using letters."
tab))
;; FIXME: At least the continuation may be folded into
-;; `newline-and-indent`. However, this may not be wanted by everyone so
+;; 'newline-and-indent'. However, this may not be wanted by everyone so
;; it should be possible to switch this off.
(defun rst-insert-list (&optional prefer-roman)
;; testcover: ok.
@@ -2915,7 +2915,7 @@ error if there is no working link at the given position."
(pop-to-buffer (marker-buffer mrkr))
(goto-char mrkr)
;; FIXME: Should be a customizable number of lines from beginning or end of
- ;; window just like the argument to `recenter`. It would be ideal if
+ ;; window just like the argument to 'recenter'. It would be ideal if
;; the adornment is always completely visible.
(recenter 5)))
@@ -2995,7 +2995,7 @@ burying it."
(define-derived-mode rst-toc-mode special-mode "ReST-TOC"
"Major mode for output from \\[rst-toc], the table-of-contents for the document.
\\{rst-toc-mode-map}"
- ;; FIXME: `revert-buffer-function` must be defined so `revert-buffer` works
+ ;; FIXME: 'revert-buffer-function' must be defined so 'revert-buffer' works
;; as expected for a special mode. In particular the referred buffer
;; needs to be rescanned and the TOC must be updated accordingly.
;; FIXME: Should contain the name of the buffer this is the toc of.
@@ -3217,7 +3217,7 @@ Return a list of tabs sorted by likeliness to continue writing
like `rst-line-tabs'. Nearer lines have generally a higher
likeliness than farther lines. Return nil if no tab is found in
the text above."
- ;; FIXME: See test `indent-for-tab-command-BUGS`.
+ ;; FIXME: See test 'indent-for-tab-command-BUGS'.
(save-excursion
(goto-char pt)
(let (leftmost ; Leftmost column found so far.
diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el
index fda00ec367e..dedc3882199 100644
--- a/lisp/textmodes/sgml-mode.el
+++ b/lisp/textmodes/sgml-mode.el
@@ -440,7 +440,8 @@ These have to be run via `sgml-syntax-propertize'"))
;; internal
(defvar sgml-face-tag-alist ()
- "Alist of face and tag name for facemenu.")
+ "Alist of face and tag name for facemenu.
+The tag name can be a string or a list of strings.")
(defvar sgml-tag-face-alist ()
"Tag names and face or list of faces to fontify with when invisible.
@@ -528,11 +529,13 @@ an optional alist of possible values."
(comment-indent-new-line soft)))
(defun sgml-mode-facemenu-add-face-function (face _end)
- (let ((tag-face (cdr (assq face sgml-face-tag-alist))))
+ "Add \"face\" tags with `facemenu-keymap' commands."
+ (let ((tag-face (ensure-list (cdr (assq face sgml-face-tag-alist)))))
(cond (tag-face
(setq tag-face (funcall skeleton-transformation-function tag-face))
- (setq facemenu-end-add-face (concat "</" tag-face ">"))
- (concat "<" tag-face ">"))
+ (setq facemenu-end-add-face
+ (mapconcat (lambda (f) (concat "</" f ">")) (reverse tag-face) ""))
+ (mapconcat (lambda (f) (concat "<" f ">")) tag-face ""))
((and (consp face)
(consp (car face))
(null (cdr face))
@@ -1208,7 +1211,7 @@ and move to the line in the SGML document that caused it."
(compilation-start command))
(defsubst sgml-at-indentation-p ()
- "Return true if point is at the first non-whitespace character on the line."
+ "Return t if point is at the first non-whitespace character on the line."
(save-excursion
(skip-chars-backward " \t")
(bolp)))
@@ -1835,6 +1838,7 @@ This takes effect when first loading the library.")
(define-key map "\C-cs" 'html-span))
(define-key map "\C-c\C-s" 'html-autoview-mode)
(define-key map "\C-c\C-v" 'browse-url-of-buffer)
+ (define-key map "\M-o" 'facemenu-keymap)
map)
"Keymap for commands for use in HTML mode.")
@@ -1867,6 +1871,7 @@ This takes effect when first loading the library.")
(defvar html-face-tag-alist
'((bold . "strong")
(italic . "em")
+ (bold-italic . ("strong" "em"))
(underline . "u")
(mode-line . "rev"))
"Value of `sgml-face-tag-alist' for HTML mode.")
@@ -2372,10 +2377,11 @@ can also view with a browser to see what happens:
have <h1>Very Major Headlines</h1> through <h6>Very Minor Headlines</h6>
<hr> Parts can be separated with horizontal rules.
-<p>Paragraphs only need an opening tag. Line breaks and multiple spaces are
-ignored unless the text is <pre>preformatted.</pre> Text can be marked as
-<strong>bold</strong>, <em>italic</em> or <u>underlined</u> using the normal M-o
-or Edit/Text Properties/Face commands.
+<p>Paragraphs only need an opening tag. Line breaks and multiple
+spaces are ignored unless the text is <pre>preformatted.</pre>
+Text can be marked as <strong>bold</strong>, <em>italic</em> or
+<u>underlined</u> using the facemenu M-o or Edit/Text
+Properties/Face commands.
Pages can have <a name=\"SOMENAME\">named points</a> and can link other points
to them with <a href=\"#SOMENAME\">see also somename</a>. In the same way <a
@@ -2409,6 +2415,8 @@ To work around that, do:
(setq-local css-id-list-function #'html-current-buffer-ids))
(setq imenu-create-index-function 'html-imenu-index)
+ (yank-media-handler 'text/html #'html-mode--html-yank-handler)
+ (yank-media-handler "image/.*" #'html-mode--image-yank-handler)
(setq-local sgml-empty-tags
;; From HTML-4.01's loose.dtd, parsed with
@@ -2424,6 +2432,30 @@ To work around that, do:
;; (setq imenu-sort-function nil) ; sorting the menu defeats the purpose
)
+(defun html-mode--html-yank-handler (_type html)
+ (save-restriction
+ (insert html)
+ (ignore-errors
+ (sgml-pretty-print (point-min) (point-max)))))
+
+(defun html-mode--image-yank-handler (type image)
+ (let ((file (read-file-name (format "Save %s image to: " type))))
+ (when (file-directory-p file)
+ (user-error "%s is a directory"))
+ (when (and (file-exists-p file)
+ (not (yes-or-no-p (format "%s exists; overwrite?" file))))
+ (user-error "%s exists"))
+ (with-temp-buffer
+ (set-buffer-multibyte nil)
+ (insert image)
+ (write-region (point-min) (point-max) file))
+ (insert (format "<img src=%S>\n" (file-relative-name file)))
+ (insert-image
+ (create-image file (mailcap-mime-type-to-extension type) nil
+ :max-width 200
+ :max-height 200)
+ " ")))
+
(defvar html-imenu-regexp
"\\s-*<h\\([1-9]\\)[^\n<>]*>\\(<[^\n<>]*>\\)*\\s-*\\([^\n<>]*\\)"
"A regular expression matching a head line to be added to the menu.
@@ -2614,7 +2646,7 @@ HTML Autoview mode is a buffer-local minor mode for use with
"</nav>")
(define-skeleton html-html5-template
- "Initial HTML5 template"
+ "Initial HTML5 template."
nil
"<!DOCTYPE html>" \n
"<html lang=\"en\">" \n
diff --git a/lisp/textmodes/table.el b/lisp/textmodes/table.el
index 2dd52b87b79..ca99d562e40 100644
--- a/lisp/textmodes/table.el
+++ b/lisp/textmodes/table.el
@@ -61,7 +61,7 @@
;; holders. Amazingly there have been no direct support for WYSIWYG
;; table editing tasks in Emacs. Many people must have experienced
;; manipulating existing overwrite-mode and picture-mode for this task
-;; and only dreamed of having such a lisp package which supports this
+;; and only dreamed of having such a Lisp package which supports this
;; specific task directly. Certainly, I have been one of them. The
;; most difficult part of dealing with table editing in Emacs probably
;; is how to realize localized rectangular editing effect. Emacs has
@@ -860,7 +860,7 @@ cell to cache and cache to cell.")
This is always set to nil at the entry to `table-with-cache-buffer' before
executing body forms.")
(defvar-local table-mode-indicator nil
- "For mode line indicator")
+ "For mode line indicator.")
;; This is not a real minor-mode but placed in the minor-mode-alist
;; so that we can show the indicator on the mode line handy.
(unless (assq table-mode-indicator minor-mode-alist)
@@ -1190,11 +1190,26 @@ executing body forms.")
;; register table menu under global tools menu
(easy-menu-define table-global-menu-map nil
- "Table global menu" table-global-menu)
+ "Table global menu." table-global-menu)
(easy-menu-add-item (current-global-map) '("menu-bar" "tools") "--")
(easy-menu-add-item (current-global-map)
'("menu-bar" "tools") table-global-menu-map)
+;;;###autoload
+(define-minor-mode table-fixed-width-mode
+ "Cell width is fixed when this is non-nil.
+Normally it should be nil for allowing automatic cell width expansion
+that widens a cell when it is necessary. When non-nil, typing in a
+cell does not automatically expand the cell width. A word that is too
+long to fit in a cell is chopped into multiple lines. The chopped
+location is indicated by `table-word-continuation-char'. This
+variable's value can be toggled by \\[table-fixed-width-mode] at
+run-time."
+ :tag "Fix Cell Width"
+ :group 'table
+ (table--finish-delayed-tasks)
+ (table--update-cell-face))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Macros
@@ -1219,43 +1234,49 @@ original buffer's point is moved to the location that corresponds to
the last cache point coordinate."
(declare (debug (body)) (indent 0))
(let ((height-expansion (make-symbol "height-expansion-var-symbol"))
- (width-expansion (make-symbol "width-expansion-var-symbol")))
- `(let (,height-expansion ,width-expansion)
+ (width-expansion (make-symbol "width-expansion-var-symbol"))
+ (fixed-width (make-symbol "fixed-width")))
+ `(let ((,fixed-width table-fixed-width-mode)
+ ,height-expansion ,width-expansion)
;; make sure cache has valid data unless it is explicitly inhibited.
(unless table-inhibit-update
(table-recognize-cell))
(with-current-buffer (get-buffer-create table-cache-buffer-name)
- ;; goto the cell coordinate based on `table-cell-cache-point-coordinate'.
- (set-mark (table--goto-coordinate table-cell-cache-mark-coordinate))
- (table--goto-coordinate table-cell-cache-point-coordinate)
- (table--untabify-line)
- ;; always reset before executing body forms because auto-fill behavior is the default.
- (setq table-inhibit-auto-fill-paragraph nil)
- ;; do the body
- ,@body
- ;; fill paragraph unless the body does not want to by setting `table-inhibit-auto-fill-paragraph'.
- (unless table-inhibit-auto-fill-paragraph
- (if (and table-cell-info-justify
- (not (eq table-cell-info-justify 'left)))
- (table--fill-region (point-min) (point-max))
- (table--fill-region
- (save-excursion (forward-paragraph -1) (point))
- (save-excursion (forward-paragraph 1) (point)))))
- ;; keep the updated cell coordinate.
- (setq table-cell-cache-point-coordinate (table--get-coordinate))
- ;; determine the cell width expansion.
- (setq ,width-expansion (table--measure-max-width))
- (if (<= ,width-expansion table-cell-info-width) nil
- (table--fill-region (point-min) (point-max) ,width-expansion)
- ;; keep the updated cell coordinate.
- (setq table-cell-cache-point-coordinate (table--get-coordinate)))
- (setq ,width-expansion (- ,width-expansion table-cell-info-width))
- ;; determine the cell height expansion.
- (if (looking-at "\\s *\\'") nil
- (goto-char (point-min))
- (if (re-search-forward "\\(\\s *\\)\\'" nil t)
- (goto-char (match-beginning 1))))
- (setq ,height-expansion (- (cdr (table--get-coordinate)) (1- table-cell-info-height))))
+ (let ((table-fixed-width-mode ,fixed-width))
+ ;; Go to the cell coordinate based on
+ ;; `table-cell-cache-point-coordinate'.
+ (set-mark (table--goto-coordinate table-cell-cache-mark-coordinate))
+ (table--goto-coordinate table-cell-cache-point-coordinate)
+ (table--untabify-line)
+ ;; Always reset before executing body forms because
+ ;; auto-fill behavior is the default.
+ (setq table-inhibit-auto-fill-paragraph nil)
+ ;; Do the body
+ ,@body
+ ;; Fill paragraph unless the body does not want to by
+ ;; setting `table-inhibit-auto-fill-paragraph'.
+ (unless table-inhibit-auto-fill-paragraph
+ (if (and table-cell-info-justify
+ (not (eq table-cell-info-justify 'left)))
+ (table--fill-region (point-min) (point-max))
+ (table--fill-region
+ (save-excursion (forward-paragraph -1) (point))
+ (save-excursion (forward-paragraph 1) (point)))))
+ ;; Keep the updated cell coordinate.
+ (setq table-cell-cache-point-coordinate (table--get-coordinate))
+ ;; Determine the cell width expansion.
+ (setq ,width-expansion (table--measure-max-width))
+ (if (<= ,width-expansion table-cell-info-width) nil
+ (table--fill-region (point-min) (point-max) ,width-expansion)
+ ;; Keep the updated cell coordinate.
+ (setq table-cell-cache-point-coordinate (table--get-coordinate)))
+ (setq ,width-expansion (- ,width-expansion table-cell-info-width))
+ ;; Determine the cell height expansion.
+ (if (looking-at "\\s *\\'") nil
+ (goto-char (point-min))
+ (if (re-search-forward "\\(\\s *\\)\\'" nil t)
+ (goto-char (match-beginning 1))))
+ (setq ,height-expansion (- (cdr (table--get-coordinate)) (1- table-cell-info-height)))))
;; now back to the table buffer.
;; expand the cell width in the table buffer if necessary.
(if (> ,width-expansion 0)
@@ -2368,7 +2389,9 @@ table's rectangle structure."
"Move point forward to the beginning of the next cell.
With argument ARG, do it ARG times;
a negative argument ARG = -N means move backward N cells.
-Do not specify NO-RECOGNIZE and UNRECOGNIZE. They are for internal use only.
+
+Do not specify NO-RECOGNIZE and UNRECOGNIZE. They are for
+internal use only.
Sample Cell Traveling Order (In Irregular Table Cases)
@@ -2399,8 +2422,7 @@ You can actually try how it works in this buffer. Press
+--+ |4 | |4 | +--+ |5 +--+--+6 | |3 +--+--+4 | |5 | |6 |
|5 +--+ | | +--+5 | | |7 |8 | | | |5 |6 | | | | | |
| |6 | | | |6 | | +--+--+--+--+ +--+--+--+--+ +--+-----+--+
-+--+--+--+ +--+--+--+
-"
++--+--+--+ +--+--+--+"
;; After modifying this function, test against the above tables in
;; the doc string. It is quite tricky. The tables above do not
;; mean to cover every possible cases of cell layout, of course.
@@ -2822,21 +2844,6 @@ or `top', `middle', `bottom' or `none' for vertical."
(table--justify-cell-contents justify))))))
;;;###autoload
-(define-minor-mode table-fixed-width-mode
- "Cell width is fixed when this is non-nil.
-Normally it should be nil for allowing automatic cell width expansion
-that widens a cell when it is necessary. When non-nil, typing in a
-cell does not automatically expand the cell width. A word that is too
-long to fit in a cell is chopped into multiple lines. The chopped
-location is indicated by `table-word-continuation-char'. This
-variable's value can be toggled by \\[table-fixed-width-mode] at
-run-time."
- :tag "Fix Cell Width"
- :group 'table
- (table--finish-delayed-tasks)
- (table--update-cell-face))
-
-;;;###autoload
(defun table-query-dimension (&optional where)
"Return the dimension of the current cell and the current table.
The result is a list (cw ch tw th c r cells) where cw is the cell
@@ -2915,8 +2922,7 @@ LaTeX:
CALS (DocBook DTD):
URL `https://www.oasis-open.org/html/a502.htm'
- URL `https://www.oreilly.com/catalog/docbook/chapter/book/table.html#AEN114751'
-"
+ URL `https://www.oreilly.com/catalog/docbook/chapter/book/table.html#AEN114751'"
(interactive
(let* ((_ (unless (table--probe-cell) (error "Table not found here")))
(completion-ignore-case t)
@@ -3206,7 +3212,7 @@ CALS (DocBook DTD):
(insert ?\n))))))
(defun table--cell-horizontal-char-p (c)
- "Test if character C is one of the horizontal characters"
+ "Test if character C is one of the horizontal characters."
(memq c (string-to-list table-cell-horizontal-chars)))
(defun table--generate-source-scan-lines (dest-buffer _language origin-cell tail-cell col-list row-list)
@@ -3625,8 +3631,7 @@ independently.
By applying `table-release', which does the opposite process, the
contents become once again plain text. `table-release' works as
-companion command to `table-capture' this way.
-"
+companion command to `table-capture' this way."
(interactive
(let ((col-delim-regexp)
(row-delim-regexp))
@@ -4535,7 +4540,7 @@ grow into."
(defun table--untabify-line (&optional from)
"Untabify current line.
-Unlike save-excursion this guarantees preserving the cursor location
+Unlike `save-excursion' this guarantees preserving the cursor location
even when the point is on a tab character which is to be removed.
Optional FROM narrows the subject operation from this point to the end
of line."
@@ -5074,7 +5079,7 @@ signals error if the optional ABORT-ON-ERROR is non-nil."
(defun table--insert-rectangle (rectangle)
"Insert text of RECTANGLE with upper left corner at point.
-Same as insert-rectangle except that mark operation is eliminated."
+Same as `insert-rectangle' except that mark operation is eliminated."
(let ((lines rectangle)
(insertcolumn (current-column))
(first t))
@@ -5290,7 +5295,7 @@ Current buffer must already be set to the cache buffer."
(set-marker marker-point nil)))
(defun table--fill-region-strictly (beg end)
- "Fill region strictly so that no line exceeds fill-column.
+ "Fill region strictly so that no line exceeds `fill-column'.
When a word exceeds fill-column the word is chopped into pieces. The
chopped location is indicated with table-word-continuation-char."
(or (and (markerp beg) (markerp end))
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el
index c53acf53e7e..5fba93c76eb 100644
--- a/lisp/textmodes/tex-mode.el
+++ b/lisp/textmodes/tex-mode.el
@@ -1014,12 +1014,18 @@ says which mode to use."
(tex-common-initialization))
(advice-add 'tex-mode :around #'tex--redirect-to-submode)
+(defvar tex-mode--recursing nil)
(defun tex--redirect-to-submode (orig-fun)
"Redirect to one of the submodes when called directly."
- (funcall (if delay-mode-hooks
- ;; We're called from one of the children already.
- orig-fun
- (tex--guess-mode))))
+ ;; The file may have "mode: tex" in the local variable
+ ;; block, in which case we'll be called recursively
+ ;; infinitely. Inhibit that.
+ (let ((tex-mode--recursing tex-mode--recursing))
+ (funcall (if (or delay-mode-hooks tex-mode--recursing)
+ ;; We're called from one of the children already.
+ orig-fun
+ (setq tex-mode--recursing t)
+ (tex--guess-mode)))))
;; The following three autoloaded aliases appear to conflict with
;; AUCTeX. However, even though AUCTeX uses the mixed case variants
@@ -2347,7 +2353,7 @@ FILE is typically the output DVI or PDF file."
collect (cons char (shell-quote-argument file))))
(defun tex-format-cmd (format fspec)
- "Like `format-spec' but adds user-specified args to the command.
+ "Like `format-spec' but add user-specified args to the command.
Only applies the FSPEC to the args part of FORMAT."
(setq fspec (tex--quote-spec fspec))
(if (not (string-match "\\([^ /\\]+\\) " format))
@@ -2451,7 +2457,7 @@ Only applies the FSPEC to the args part of FORMAT."
(default (tex-compile-default fspec)))
(list default-directory
(completing-read
- (format "Command [%s]: " (tex-summarize-command default))
+ (format-prompt "Command" (tex-summarize-command default))
(mapcar (lambda (x)
(list (tex-format-cmd (eval (car x) t) fspec)))
tex-compile-commands)
@@ -3448,7 +3454,7 @@ There might be text before point."
("\\varprime" . ?′)
("\\varpropto" . ?∝)
("\\varrho" . ?ϱ)
- ("\\varsigma" ?ς)
+ ("\\varsigma" . ?ς)
("\\vartriangleleft" . ?⊲)
("\\vartriangleright" . ?⊳)
("\\vdash" . ?⊢)
@@ -3463,7 +3469,97 @@ There might be text before point."
("\\Bbb{P}" . ?ℙ) ; Also sometimes \mathbb.
("\\Bbb{Q}" . ?ℚ)
("\\Bbb{R}" . ?ℝ)
+ ("\\Bbb{T}" . ?𝕋)
("\\Bbb{Z}" . ?ℤ)
+ ("\\mathbb{N}" . ?ℕ) ; AMS commands for blackboard bold
+ ("\\mathbb{P}" . ?ℙ) ; Also sometimes \mathbb.
+ ("\\mathbb{Q}" . ?ℚ)
+ ("\\mathbb{R}" . ?ℝ)
+ ("\\mathbb{T}" . ?𝕋)
+ ("\\mathbb{Z}" . ?ℤ)
+ ("\\pm" . ?±)
+ ("\\|" . ?‖)
+ ("\\varkappa" . ?ϰ)
+ ;; caligraphic
+ ("\\mathcal{A}" . ?𝒜)
+ ("\\mathcal{B}" . ?ℬ)
+ ("\\mathcal{C}" . ?𝒞)
+ ("\\mathcal{D}" . ?𝒟)
+ ("\\mathcal{E}" . ?ℰ)
+ ("\\mathcal{F}" . ?ℱ)
+ ("\\mathcal{G}" . ?𝒢)
+ ("\\mathcal{H}" . ?ℋ)
+ ("\\mathcal{I}" . ?ℐ)
+ ("\\mathcal{J}" . ?𝒥)
+ ("\\mathcal{K}" . ?𝒦)
+ ("\\mathcal{L}" . ?ℒ)
+ ("\\mathcal{M}" . ?ℳ)
+ ("\\mathcal{N}" . ?𝒩)
+ ("\\mathcal{O}" . ?𝒪)
+ ("\\mathcal{P}" . ?𝒫)
+ ("\\mathcal{Q}" . ?𝒬)
+ ("\\mathcal{R}" . ?ℛ)
+ ("\\mathcal{S}" . ?𝒮)
+ ("\\mathcal{T}" . ?𝒯)
+ ("\\mathcal{U}" . ?𝒰)
+ ("\\mathcal{V}" . ?𝒱)
+ ("\\mathcal{W}" . ?𝒲)
+ ("\\mathcal{X}" . ?𝒳)
+ ("\\mathcal{Y}" . ?𝒴)
+ ("\\mathcal{Z}" . ?𝒵)
+ ;; fractur
+ ("\\mathfrak{A}" . ?𝔄)
+ ("\\mathfrak{B}" . ?𝔅)
+ ("\\mathfrak{C}" . ?ℭ)
+ ("\\mathfrak{D}" . ?𝔇)
+ ("\\mathfrak{E}" . ?𝔈)
+ ("\\mathfrak{F}" . ?𝔉)
+ ("\\mathfrak{G}" . ?𝔊)
+ ("\\mathfrak{H}" . ?ℌ)
+ ("\\mathfrak{I}" . ?ℑ)
+ ("\\mathfrak{J}" . ?𝔍)
+ ("\\mathfrak{K}" . ?𝔎)
+ ("\\mathfrak{L}" . ?𝔏)
+ ("\\mathfrak{M}" . ?𝔐)
+ ("\\mathfrak{N}" . ?𝔑)
+ ("\\mathfrak{O}" . ?𝔒)
+ ("\\mathfrak{P}" . ?𝔓)
+ ("\\mathfrak{Q}" . ?𝔔)
+ ("\\mathfrak{R}" . ?ℜ)
+ ("\\mathfrak{S}" . ?𝔖)
+ ("\\mathfrak{T}" . ?𝔗)
+ ("\\mathfrak{U}" . ?𝔘)
+ ("\\mathfrak{V}" . ?𝔙)
+ ("\\mathfrak{W}" . ?𝔚)
+ ("\\mathfrak{X}" . ?𝔛)
+ ("\\mathfrak{Y}" . ?𝔜)
+ ("\\mathfrak{Z}" . ?ℨ)
+ ("\\mathfrak{a}" . ?𝔞)
+ ("\\mathfrak{b}" . ?𝔟)
+ ("\\mathfrak{c}" . ?𝔠)
+ ("\\mathfrak{d}" . ?𝔡)
+ ("\\mathfrak{e}" . ?𝔢)
+ ("\\mathfrak{f}" . ?𝔣)
+ ("\\mathfrak{g}" . ?𝔤)
+ ("\\mathfrak{h}" . ?𝔥)
+ ("\\mathfrak{i}" . ?𝔦)
+ ("\\mathfrak{j}" . ?𝔧)
+ ("\\mathfrak{k}" . ?𝔨)
+ ("\\mathfrak{l}" . ?𝔩)
+ ("\\mathfrak{m}" . ?𝔪)
+ ("\\mathfrak{n}" . ?𝔫)
+ ("\\mathfrak{o}" . ?𝔬)
+ ("\\mathfrak{p}" . ?𝔭)
+ ("\\mathfrak{q}" . ?𝔮)
+ ("\\mathfrak{r}" . ?𝔯)
+ ("\\mathfrak{s}" . ?𝔰)
+ ("\\mathfrak{t}" . ?𝔱)
+ ("\\mathfrak{u}" . ?𝔲)
+ ("\\mathfrak{v}" . ?𝔳)
+ ("\\mathfrak{w}" . ?𝔴)
+ ("\\mathfrak{x}" . ?𝔵)
+ ("\\mathfrak{y}" . ?𝔶)
+ ("\\mathfrak{z}" . ?𝔷)
("--" . ?–)
("---" . ?—)
("\\ordfeminine" . ?ª)
diff --git a/lisp/textmodes/texinfmt.el b/lisp/textmodes/texinfmt.el
index 977f3bab6ce..550994cd7b6 100644
--- a/lisp/textmodes/texinfmt.el
+++ b/lisp/textmodes/texinfmt.el
@@ -932,9 +932,9 @@ commands."
"Text of the copyright notice and copying permissions.")
(defun texinfo-copying ()
- "Copy the copyright notice and copying permissions from the Texinfo file,
-as indicated by the @copying ... @end copying command;
-insert the text with the @insertcopying command."
+ "Copy the copyright notice and copying permissions from Texinfo file.
+This is indicated by the \"@copying ... @end copying\" command;
+insert the text with the \"@insertcopying\" command."
(let ((beg (progn (beginning-of-line) (point)))
(end (progn (re-search-forward "^@end copying[ \t]*\n") (point))))
(setq texinfo-copying-text
@@ -944,8 +944,8 @@ insert the text with the @insertcopying command."
(delete-region beg end)))
(defun texinfo-insertcopying ()
- "Insert the copyright notice and copying permissions from the Texinfo file,
-which are indicated by the @copying ... @end copying command."
+ "Insert the copyright notice and copying permissions from Texinfo file.
+This is indicated by the \"@copying ... @end copying\" command."
(insert (concat "\n" texinfo-copying-text)))
(put 'begin 'texinfo-format 'texinfo-format-begin)
@@ -1618,7 +1618,7 @@ Used by @refill indenting command to avoid indenting within lists, etc.")
(if (and (symbolp (car (cdr (car texinfo-stack))))
(> 1 (length (symbol-name (car (cdr (car texinfo-stack)))))))
(error
- "@enumerate: Use a number or letter, eg: 1, A, a, 3, B, or d." ))
+ "@enumerate: Use a number or letter, eg: 1, A, a, 3, B, or d"))
(texinfo-discard-line-with-args)
(setq fill-column (- fill-column 5)))
@@ -1705,7 +1705,7 @@ Used by @refill indenting command to avoid indenting within lists, etc.")
(if (or (equal ?\[ (string-to-char enumerating-symbol))
(equal ?\{ (string-to-char enumerating-symbol)))
(error
- "Too many items in enumerated list; alphabet ends at Z."))
+ "Too many items in enumerated list; alphabet ends at Z"))
(insert ?\b (format "%3s. " enumerating-symbol) ?\n)
(setcar (cdr (car texinfo-stack))
(make-symbol
@@ -1714,7 +1714,7 @@ Used by @refill indenting command to avoid indenting within lists, etc.")
(string-to-char enumerating-symbol))))))
(t
(error
- "@enumerate: Use a number or letter, eg: 1, A, a, 3, B or d." )))
+ "@enumerate: Use a number or letter, eg: 1, A, a, 3, B or d")))
(forward-line -1)))
(put 'alphaenumerate 'texinfo-item 'texinfo-alphaenumerate-item)
@@ -2032,7 +2032,7 @@ commands that are defined in texinfo.tex for printed output.
;; Case 3: Trouble
(t
(error
- "You probably need to specify column widths for @multitable correctly.")))
+ "You probably need to specify column widths for @multitable correctly")))
;; Check whether columns fit on page.
(let ((desired-columns
(+
@@ -2044,7 +2044,7 @@ commands that are defined in texinfo.tex for printed output.
(apply #'+ texinfo-multitable-width-list))))
(if (> desired-columns fill-column)
(error
- "Multi-column table width, %d chars, is greater than page width, %d chars."
+ "Multi-column table width, %d chars, is greater than page width, %d chars"
desired-columns fill-column)))
texinfo-multitable-width-list))
@@ -2546,7 +2546,9 @@ If used within a line, follow `@bullet' with braces."
"smalllisp"
"\\)")
"Regexp specifying end of environments in which @kbd does not put `...'
-around argument. (See `texinfo-format-kbd-regexp')")
+around argument.
+
+See `texinfo-format-kbd-regexp'.")
(put 'kbd 'texinfo-format 'texinfo-format-kbd)
(defun texinfo-format-kbd ()
diff --git a/lisp/textmodes/texinfo.el b/lisp/textmodes/texinfo.el
index 11d60e1eb03..dbf30dabe59 100644
--- a/lisp/textmodes/texinfo.el
+++ b/lisp/textmodes/texinfo.el
@@ -4,7 +4,6 @@
;; Foundation, Inc.
;; Author: Robert J. Chassell
-;; Date: [See date below for texinfo-version]
;; Maintainer: emacs-devel@gnu.org
;; Keywords: maint, tex, docs
@@ -350,7 +349,7 @@ and also to be turned into Info files with \\[makeinfo-buffer] or
the `makeinfo' program. These files must be written in a very restricted and
modified version of TeX input format.
- Editing commands are like text-mode except that the syntax table is
+ Editing commands are like `text-mode' except that the syntax table is
set up so expression commands skip Texinfo bracket groups. To see
what the Info version of a region of the Texinfo file will look like,
use \\[makeinfo-region], which runs `makeinfo' on the current region.
@@ -378,15 +377,15 @@ updating menus and node pointers. These functions
Here are the functions:
- texinfo-update-node \\[texinfo-update-node]
- texinfo-every-node-update \\[texinfo-every-node-update]
- texinfo-sequential-node-update
+ `texinfo-update-node' \\[texinfo-update-node]
+ `texinfo-every-node-update' \\[texinfo-every-node-update]
+ `texinfo-sequential-node-update'
- texinfo-make-menu \\[texinfo-make-menu]
- texinfo-all-menus-update \\[texinfo-all-menus-update]
- texinfo-master-menu
+ `texinfo-make-menu' \\[texinfo-make-menu]
+ `texinfo-all-menus-update' \\[texinfo-all-menus-update]
+ `texinfo-master-menu'
- texinfo-indent-menu-description (column &optional region-p)
+ `texinfo-indent-menu-description' (column &optional region-p)
The `texinfo-column-for-description' variable specifies the column to
which menu descriptions are indented.
@@ -411,13 +410,13 @@ value of `texinfo-mode-hook'."
"\\)\\>"))
(setq-local require-final-newline mode-require-final-newline)
(setq-local indent-tabs-mode nil)
- (setq-local paragraph-separate
- (concat "@[a-zA-Z]*[ \n]\\|"
- paragraph-separate))
(setq-local paragraph-start (concat "@[a-zA-Z]*[ \n]\\|"
paragraph-start))
+ (setq-local fill-paragraph-function 'texinfo--fill-paragraph)
(setq-local sentence-end-base "\\(@\\(end\\)?dots{}\\|[.?!]\\)[]\"'”)}]*")
(setq-local fill-column 70)
+ (setq-local beginning-of-defun-function #'texinfo--beginning-of-defun)
+ (setq-local end-of-defun-function #'texinfo--end-of-defun)
(setq-local comment-start "@c ")
(setq-local comment-start-skip "@c +\\|@comment +")
(setq-local words-include-escapes t)
@@ -457,6 +456,58 @@ value of `texinfo-mode-hook'."
prevent-filling
(concat auto-fill-inhibit-regexp "\\|" prevent-filling)))))
+(defvar texinfo-fillable-commands '("@noindent")
+ "A list of commands that can be filled.")
+
+(defun texinfo--fill-paragraph (justify)
+ "Function to fill a paragraph in `texinfo-mode'."
+ (let ((command-re "\\(@[a-zA-Z]+\\)[ \t\n]"))
+ (catch 'no-fill
+ (save-restriction
+ ;; First check whether we're on a command line that can be
+ ;; filled by itself.
+ (or
+ (save-excursion
+ (beginning-of-line)
+ (when (looking-at command-re)
+ (let ((command (match-string 1)))
+ (if (member command texinfo-fillable-commands)
+ (progn
+ (narrow-to-region (point) (progn (forward-line 1) (point)))
+ t)
+ (throw 'no-fill nil)))))
+ ;; We're not on such a line, so fill the region.
+ (save-excursion
+ (let ((regexp (concat command-re "\\|^[ \t]*$\\|\f")))
+ (narrow-to-region
+ (if (re-search-backward regexp nil t)
+ (progn
+ (forward-line 1)
+ (point))
+ (point-min))
+ (if (re-search-forward regexp nil t)
+ (match-beginning 0)
+ (point-max)))
+ (goto-char (point-min)))))
+ ;; We've now narrowed to the region we want to fill.
+ (let ((fill-paragraph-function nil)
+ (adaptive-fill-mode nil))
+ (fill-paragraph justify))))
+ t))
+
+(defun texinfo--beginning-of-defun (&optional arg)
+ "Go to the previous @node line."
+ (while (and (> arg 0)
+ (re-search-backward "^@node " nil t))
+ (setq arg (1- arg))))
+
+(defun texinfo--end-of-defun ()
+ "Go to the start of the next @node line."
+ (when (looking-at-p "@node")
+ (forward-line))
+ (if (re-search-forward "^@node " nil t)
+ (goto-char (match-beginning 0))
+ (goto-char (point-max))))
;;; Insert string commands
@@ -806,7 +857,8 @@ temporary file before the region itself. The buffer's header is all lines
between the strings defined by `tex-start-of-header' and `tex-end-of-header'
inclusive. The header must start in the first 100 lines.
-The value of `texinfo-tex-trailer' is appended to the temporary file after the region."
+The value of `texinfo-tex-trailer' is appended to the temporary
+file after the region."
(interactive "r")
(require 'tex-mode)
(let ((tex-command texinfo-tex-command)
diff --git a/lisp/textmodes/texnfo-upd.el b/lisp/textmodes/texnfo-upd.el
index f56f197c502..6862da60464 100644
--- a/lisp/textmodes/texnfo-upd.el
+++ b/lisp/textmodes/texnfo-upd.el
@@ -894,10 +894,10 @@ be updated first using `texinfo-make-menu' or
`texinfo-all-menus-update', which see. Alternatively, invoke
this function with a prefix argument, see below.
-Non-nil, non-numeric argument (C-u prefix, if interactive) means
+Non-nil, non-numeric argument (\\[universal-argument] prefix, if interactive) means
first update all existing menus in the buffer (incorporating
descriptions from pre-existing menus) before it constructs the
-master menu. If the argument is numeric (e.g., \"C-u 2\"),
+master menu. If the argument is numeric (e.g., \"\\[universal-argument] 2\"),
update all existing nodes as well, by calling
`texinfo-update-node' on the entire file. Warning: do NOT
invoke with a numeric argument if your Texinfo file uses @node
@@ -1508,7 +1508,7 @@ will be at some level higher in the Texinfo file. The fourth argument
'normal
'no-pointer))
(t
- (error "texinfo-find-pointer: lack proper arguments")))))
+ (error "texinfo-find-pointer: Lack proper arguments")))))
(defun texinfo-pointer-name (kind)
"Return the node name preceding the section command.
@@ -1676,7 +1676,7 @@ or `Up' pointer."
'normal
'no-pointer))
(t
- (error "texinfo-sequential-find-pointer: lack proper arguments")))))
+ (error "texinfo-sequential-find-pointer: Lack proper arguments")))))
;;; Inserting `@node' lines
diff --git a/lisp/textmodes/text-mode.el b/lisp/textmodes/text-mode.el
index 74c6d412a65..478cf62268f 100644
--- a/lisp/textmodes/text-mode.el
+++ b/lisp/textmodes/text-mode.el
@@ -95,6 +95,28 @@ inherit all the commands defined in this map.")
:style toggle
:selected (memq 'turn-on-auto-fill text-mode-hook)]))
+(defun text-mode-context-menu (menu click)
+ "Populate MENU with text selection commands at CLICK."
+
+ (when (thing-at-mouse click 'word)
+ (define-key-after menu [select-region mark-word]
+ `(menu-item "Word"
+ ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'word))
+ :help "Mark the word at click for a subsequent cut/copy")
+ 'mark-whole-buffer))
+ (define-key-after menu [select-region mark-sentence]
+ `(menu-item "Sentence"
+ ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'sentence))
+ :help "Mark the sentence at click for a subsequent cut/copy")
+ 'mark-whole-buffer)
+ (define-key-after menu [select-region mark-paragraph]
+ `(menu-item "Paragraph"
+ ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'paragraph))
+ :help "Mark the paragraph at click for a subsequent cut/copy")
+ 'mark-whole-buffer)
+
+ menu)
+
(define-derived-mode text-mode nil "Text"
"Major mode for editing text written for humans to read.
@@ -104,7 +126,8 @@ You can thus get the full benefit of adaptive filling
\\{text-mode-map}
Turning on Text mode runs the normal hook `text-mode-hook'."
(setq-local text-mode-variant t)
- (setq-local require-final-newline mode-require-final-newline))
+ (setq-local require-final-newline mode-require-final-newline)
+ (add-hook 'context-menu-functions 'text-mode-context-menu 10 t))
(define-derived-mode paragraph-indent-text-mode text-mode "Parindent"
"Major mode for editing text, with leading spaces starting a paragraph.
diff --git a/lisp/textmodes/tildify.el b/lisp/textmodes/tildify.el
index 01e2ad72d88..2a4c8cff8f0 100644
--- a/lisp/textmodes/tildify.el
+++ b/lisp/textmodes/tildify.el
@@ -67,7 +67,7 @@ matching the white space). The pattern is matched case-sensitive regardless of
the value of `case-fold-search' setting."
:version "25.1"
:type 'regexp
- :safe t)
+ :safe #'stringp)
(defcustom tildify-pattern-alist ()
"Alist specifying where to insert hard spaces.
@@ -112,7 +112,7 @@ If nil, current major mode has no way to represent a hard space."
" ")
(const :tag "No-break space (U+00A0)" "\u00A0")
(string :tag "Custom string"))
- :safe t)
+ :safe #'string-or-null-p)
(defcustom tildify-string-alist ()
"Alist specifying what is a hard space in the current major mode.
diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el
index 66bbfb0f9f6..2d1bf2013e1 100644
--- a/lisp/thingatpt.el
+++ b/lisp/thingatpt.el
@@ -31,7 +31,7 @@
;; The function bounds-of-thing-at-point finds the beginning and end
;; positions by moving first forward to the end of the "thing", and then
;; backwards to the beginning. By default, it uses the corresponding
-;; forward-"thing" operator (eg. forward-word, forward-line).
+;; forward-"thing" operator (e.g. forward-word, forward-line).
;;
;; Special cases are allowed for using properties associated with the named
;; "thing":
@@ -106,8 +106,17 @@ valid THING.
Return a cons cell (START . END) giving the start and end
positions of the thing found."
- (if (get thing 'bounds-of-thing-at-point)
- (funcall (get thing 'bounds-of-thing-at-point))
+ (cond
+ ((get thing 'bounds-of-thing-at-point)
+ (funcall (get thing 'bounds-of-thing-at-point)))
+ ;; If the buffer is totally empty, give up.
+ ((and (not (eq thing 'whitespace))
+ (save-excursion
+ (goto-char (point-min))
+ (not (re-search-forward "[^\t\n ]" nil t))))
+ nil)
+ ;; Find the thing.
+ (t
(let ((orig (point)))
(ignore-errors
(save-excursion
@@ -149,7 +158,7 @@ positions of the thing found."
(lambda () (forward-thing thing -1))))
(point))))
(if (and (<= real-beg orig) (<= orig end) (< real-beg end))
- (cons real-beg end))))))))))
+ (cons real-beg end)))))))))))
;;;###autoload
(defun thing-at-point (thing &optional no-properties)
@@ -162,24 +171,48 @@ Possibilities include `symbol', `list', `sexp', `defun',
When the optional argument NO-PROPERTIES is non-nil,
strip text properties from the return value.
+If the current buffer uses fields (see Info node `(elisp)Fields'),
+this function will narrow to the field before identifying the
+thing at point.
+
See the file `thingatpt.el' for documentation on how to define
a symbol as a valid THING."
- (let ((text
- (cond
- ((cl-loop for (pthing . function) in thing-at-point-provider-alist
- when (eq pthing thing)
- for result = (funcall function)
- when result
- return result))
- ((get thing 'thing-at-point)
- (funcall (get thing 'thing-at-point)))
- (t
- (let ((bounds (bounds-of-thing-at-point thing)))
- (when bounds
- (buffer-substring (car bounds) (cdr bounds))))))))
- (when (and text no-properties (sequencep text))
- (set-text-properties 0 (length text) nil text))
- text))
+ (save-restriction
+ (narrow-to-region (field-beginning) (field-end))
+ (let ((text
+ (cond
+ ((cl-loop for (pthing . function) in thing-at-point-provider-alist
+ when (eq pthing thing)
+ for result = (funcall function)
+ when result
+ return result))
+ ((get thing 'thing-at-point)
+ (funcall (get thing 'thing-at-point)))
+ (t
+ (let ((bounds (bounds-of-thing-at-point thing)))
+ (when bounds
+ (buffer-substring (car bounds) (cdr bounds))))))))
+ (when (and text no-properties (sequencep text))
+ (set-text-properties 0 (length text) nil text))
+ text)))
+
+;;;###autoload
+(defun bounds-of-thing-at-mouse (event thing)
+ "Determine start and end locations for THING at mouse click given by EVENT.
+Like `bounds-of-thing-at-point', but tries to use the position in EVENT
+where the mouse button is clicked to find the thing nearby."
+ (save-excursion
+ (mouse-set-point event)
+ (bounds-of-thing-at-point thing)))
+
+;;;###autoload
+(defun thing-at-mouse (event thing &optional no-properties)
+ "Return the THING at mouse click specified by EVENT.
+Like `thing-at-point', but tries to use the position in EVENT
+where the mouse button is clicked to find the thing nearby."
+ (save-excursion
+ (mouse-set-point event)
+ (thing-at-point thing no-properties)))
;; Go to beginning/end
@@ -207,7 +240,27 @@ The bounds of THING are determined by `bounds-of-thing-at-point'."
(put 'line 'beginning-op
(lambda () (if (bolp) (forward-line -1) (beginning-of-line))))
-;; Sexps
+;; Strings
+
+(put 'string 'bounds-of-thing-at-point 'thing-at-point-bounds-of-string-at-point)
+
+(defun thing-at-point-bounds-of-string-at-point ()
+ "Return the bounds of the string at point.
+Prefer the enclosing string with fallback on sexp at point.
+\[Internal function used by `bounds-of-thing-at-point'.]"
+ (save-excursion
+ (let ((ppss (syntax-ppss)))
+ (if (nth 3 ppss)
+ ;; Inside the string
+ (ignore-errors
+ (goto-char (nth 8 ppss))
+ (cons (point) (progn (forward-sexp) (point))))
+ ;; At the beginning of the string
+ (if (eq (char-syntax (char-after)) ?\")
+ (let ((bound (bounds-of-thing-at-point 'sexp)))
+ (and bound
+ (<= (car bound) (point)) (< (point) (cdr bound))
+ bound)))))))
(defun in-string-p ()
"Return non-nil if point is in a string."
@@ -217,6 +270,8 @@ The bounds of THING are determined by `bounds-of-thing-at-point'."
(beginning-of-defun)
(nth 3 (parse-partial-sexp (point) orig)))))
+;; Sexps
+
(defun thing-at-point--end-of-sexp ()
"Move point to the end of the current sexp."
(let ((char-syntax (syntax-after (point))))
diff --git a/lisp/thumbs.el b/lisp/thumbs.el
index 4c863883ba4..001b2c8e770 100644
--- a/lisp/thumbs.el
+++ b/lisp/thumbs.el
@@ -91,7 +91,7 @@ When it reaches that size (in bytes), a warning is sent."
(defcustom thumbs-conversion-program
(if (eq system-type 'windows-nt)
;; FIXME is this necessary, or can a sane PATHEXE be assumed?
- ;; Eg find-program does not do this.
+ ;; E.g. find-program does not do this.
"convert.exe"
"convert")
"Name of conversion program for thumbnails generation.
@@ -292,22 +292,11 @@ smaller according to whether INCREMENT is 1 or -1."
(thumbs-call-convert fn tn "sample" thumbs-geometry))
tn))
-(defun thumbs-image-type (img)
- "Return image type from filename IMG."
- (cond ((string-match ".*\\.jpe?g\\'" img) 'jpeg)
- ((string-match ".*\\.xpm\\'" img) 'xpm)
- ((string-match ".*\\.xbm\\'" img) 'xbm)
- ((string-match ".*\\.pbm\\'" img) 'pbm)
- ((string-match ".*\\.gif\\'" img) 'gif)
- ((string-match ".*\\.bmp\\'" img) 'bmp)
- ((string-match ".*\\.png\\'" img) 'png)
- ((string-match ".*\\.tiff?\\'" img) 'tiff)))
-
(declare-function image-size "image.c" (spec &optional pixels frame))
(defun thumbs-file-size (img)
(let ((i (image-size
- (find-image `((:type ,(thumbs-image-type img) :file ,img))) t)))
+ (find-image `((:type ,(image-type-from-file-name img) :file ,img))) t)))
(concat (number-to-string (round (car i))) "x"
(number-to-string (round (cdr i))))))
@@ -410,7 +399,7 @@ and SAME-WINDOW to show thumbs in the same window."
thumbs-image-num (or num 0))
(delete-region (point-min)(point-max))
(save-excursion
- (thumbs-insert-image img (thumbs-image-type img) 0)))))
+ (thumbs-insert-image img (image-type-from-file-name img) 0)))))
(defun thumbs-find-image-at-point (&optional img otherwin)
"Display image IMG for thumbnail at point.
@@ -544,7 +533,7 @@ Open another window."
" - " (number-to-string num)))
(let ((inhibit-read-only t))
(erase-buffer)
- (thumbs-insert-image img (thumbs-image-type img) 0)
+ (thumbs-insert-image img (image-type-from-file-name img) 0)
(goto-char (point-min))))
(setq thumbs-image-num num
thumbs-current-image-filename img))))
@@ -775,6 +764,9 @@ ACTION and ARG should be a valid convert command."
(define-key dired-mode-map "\C-tm" 'thumbs-dired-show-marked)
(define-key dired-mode-map "\C-tw" 'thumbs-dired-setroot)
+(define-obsolete-function-alias 'thumbs-image-type
+ #'image-type-from-file-name "29.1")
+
(provide 'thumbs)
;;; thumbs.el ends here
diff --git a/lisp/time-stamp.el b/lisp/time-stamp.el
index ae911717151..04e736d027c 100644
--- a/lisp/time-stamp.el
+++ b/lisp/time-stamp.el
@@ -41,13 +41,11 @@
:group 'data
:group 'extensions)
+
(defcustom time-stamp-format "%Y-%02m-%02d %02H:%02M:%02S %l"
"Format of the string inserted by \\[time-stamp].
This is a string, used verbatim except for character sequences beginning
-with %, as follows. The values of non-numeric formatted items depend
-on the locale setting recorded in `system-time-locale' and
-`locale-coding-system'. The examples here are for the default
-\(`C') locale.
+with %, as follows.
%:A weekday name: `Monday' %#A gives uppercase: `MONDAY'
%3a abbreviated weekday: `Mon' %#a gives uppercase: `MON'
@@ -61,13 +59,13 @@ on the locale setting recorded in `system-time-locale' and
%#p `am' or `pm' %P gives uppercase: `AM' or `PM'
%02S seconds
%w day number of week, Sunday is 0
-%02y 2-digit year: `03' %Y 4-digit year: `2003'
+%02y 2-digit year %Y 4-digit year
%Z time zone name: `EST' %#Z gives lowercase: `est'
%5z time zone offset: `-0500' (since Emacs 27; see note below)
Non-date items:
%% a literal percent character: `%'
-%f file name without directory %F gives absolute pathname
+%f file name without directory %F absolute file name
%l login name %L full name of logged-in user
%q unqualified host name %Q fully-qualified host name
%h mail host name
@@ -79,6 +77,11 @@ A leading zero in the field width zero-fills a number.
For example, to get the format used by the `date' command,
use \"%3a %3b %2d %02H:%02M:%02S %Z %Y\".
+The values of non-numeric formatted items depend on the locale
+setting recorded in `system-time-locale' and `locale-coding-system'.
+The examples here are for the default (`C') locale.
+`time-stamp-time-zone' controls the time zone used.
+
The default padding of some formats has changed to be more compatible
with format-time-string. To be compatible with older versions of Emacs,
specify a padding width (as shown) or use the : modifier to request the
@@ -90,6 +93,7 @@ edited by older versions of Emacs also, do not use this format yet."
:version "27.1")
;;;###autoload(put 'time-stamp-format 'safe-local-variable 'stringp)
+
(defcustom time-stamp-active t
"Non-nil to enable time-stamping of buffers by \\[time-stamp].
Can be toggled by \\[time-stamp-toggle-active].
@@ -100,9 +104,14 @@ when they are saved, either add this line to your init file:
(add-hook \\='before-save-hook \\='time-stamp)
or customize option `before-save-hook'.
+To enable automatic time-stamping for only a specific file, add this
+line to a local variables list near the end of the file:
+ eval: (add-hook \\='before-save-hook \\='time-stamp nil t)
+
See also the variable `time-stamp-warn-inactive'."
:type 'boolean)
+
(defcustom time-stamp-warn-inactive t
"Have \\[time-stamp] warn if a buffer did not get time-stamped.
If non-nil, a warning is displayed if `time-stamp-active' has
@@ -111,6 +120,7 @@ otherwise would have been updated."
:type 'boolean
:version "19.29")
+
(defcustom time-stamp-time-zone nil
"The time zone to be used by \\[time-stamp].
Its format is that of the ZONE argument of the `format-time-string' function."
@@ -125,9 +135,10 @@ Its format is that of the ZONE argument of the `format-time-string' function."
:version "20.1")
;;;###autoload(put 'time-stamp-time-zone 'safe-local-variable 'time-stamp-zone-type-p)
+
;;;###autoload
(defun time-stamp-zone-type-p (zone)
- "Return whether or not ZONE is of the correct type for a timezone rule.
+ "Return non-nil if ZONE is of the correct type for a timezone rule.
Valid ZONE values are described in the documentation of `format-time-string'."
(or (memq zone '(nil t wall))
(stringp zone)
@@ -137,6 +148,7 @@ Valid ZONE values are described in the documentation of `format-time-string'."
(stringp (cadr zone)))
(integerp zone)))
+
;;; Do not change time-stamp-line-limit, time-stamp-start,
;;; time-stamp-end, time-stamp-pattern, time-stamp-inserts-lines,
;;; or time-stamp-count in your .emacs or you will be incompatible
@@ -151,46 +163,51 @@ the first (last) `time-stamp-line-limit' lines of the file for the
file to be time-stamped by \\[time-stamp]. A value of 0 searches the
entire buffer (use with care).
-This value can also be set with the variable `time-stamp-pattern'.
+It may be more convenient to use `time-stamp-pattern' if you set more
+than one of `time-stamp-line-limit', `time-stamp-start', `time-stamp-end',
+or `time-stamp-format'.
-Do not change `time-stamp-line-limit', `time-stamp-start',
-`time-stamp-end', or `time-stamp-pattern' for yourself or you will be
-incompatible with other people's files! If you must change them for some
-application, do so in the local variables section of the time-stamped file
-itself.")
+These variables are best changed with file-local variables.
+If you were to change `time-stamp-line-limit', `time-stamp-start',
+`time-stamp-end', or `time-stamp-pattern' in your init file, you
+would be incompatible with other people's files.")
;;;###autoload(put 'time-stamp-line-limit 'safe-local-variable 'integerp)
+
(defvar time-stamp-start "Time-stamp:[ \t]+\\\\?[\"<]+" ;Do not change!
"Regexp after which the time stamp is written by \\[time-stamp].
-See also the variables `time-stamp-end' and `time-stamp-line-limit'.
-This value can also be set with the variable `time-stamp-pattern'.
+It may be more convenient to use `time-stamp-pattern' if you set more
+than one of `time-stamp-line-limit', `time-stamp-start', `time-stamp-end',
+or `time-stamp-format'.
-Do not change `time-stamp-line-limit', `time-stamp-start',
-`time-stamp-end', or `time-stamp-pattern' for yourself or you will be
-incompatible with other people's files! If you must change them for some
-application, do so in the local variables section of the time-stamped file
-itself.")
+These variables are best changed with file-local variables.
+If you were to change `time-stamp-line-limit', `time-stamp-start',
+`time-stamp-end', or `time-stamp-pattern' in your init file, you
+would be incompatible with other people's files.")
;;;###autoload(put 'time-stamp-start 'safe-local-variable 'stringp)
+
(defvar time-stamp-end "\\\\?[\">]" ;Do not change!
"Regexp marking the text after the time stamp.
\\[time-stamp] deletes the text between the first match of `time-stamp-start'
and the following match of `time-stamp-end', then writes the
time stamp specified by `time-stamp-format' between them.
-This value can also be set with the variable `time-stamp-pattern'.
+It may be more convenient to use `time-stamp-pattern' if you set more
+than one of `time-stamp-line-limit', `time-stamp-start', `time-stamp-end',
+or `time-stamp-format'.
The end text normally starts on the same line as the start text ends,
but if there are any newlines in `time-stamp-format', the same number
-of newlines must separate the start and end. \\[time-stamp] tries
-to not change the number of lines in the buffer. `time-stamp-inserts-lines'
+of newlines must separate the start and end. Thus \\[time-stamp] tries
+to not change the number of lines in the buffer; `time-stamp-inserts-lines'
controls this behavior.
-Do not change `time-stamp-start', `time-stamp-end', `time-stamp-pattern',
-or `time-stamp-inserts-lines' for yourself or you will be incompatible
-with other people's files! If you must change them for some application,
-do so in the local variables section of the time-stamped file itself.")
+These variables are best changed with file-local variables.
+If you were to change `time-stamp-line-limit', `time-stamp-start',
+`time-stamp-end', `time-stamp-pattern', or `time-stamp-inserts-lines' in
+your init file, you would be incompatible with other people's files.")
;;;###autoload(put 'time-stamp-end 'safe-local-variable 'stringp)
@@ -204,10 +221,9 @@ immediately after the start pattern. This behavior can cause
unexpected changes in the buffer if used carelessly, but it is useful
for generating repeated time stamps.
-Do not change `time-stamp-end' or `time-stamp-inserts-lines' for
-yourself or you will be incompatible with other people's files!
-If you must change them for some application, do so in the local
-variables section of the time-stamped file itself.")
+These variables are best changed with file-local variables.
+If you were to change `time-stamp-end' or `time-stamp-inserts-lines' in
+your init file, you would be incompatible with other people's files.")
;;;###autoload(put 'time-stamp-inserts-lines 'safe-local-variable 'symbolp)
@@ -215,10 +231,9 @@ variables section of the time-stamped file itself.")
"How many templates \\[time-stamp] will look for in a buffer.
The same time stamp will be written in each case.
-Do not change `time-stamp-count' for yourself or you will be
-incompatible with other people's files! If you must change it for
-some application, do so in the local variables section of the
-time-stamped file itself.")
+`time-stamp-count' is best changed with a file-local variable.
+If you were to change it in your init file, you would be incompatible
+with other people's files.")
;;;###autoload(put 'time-stamp-count 'safe-local-variable 'integerp)
@@ -244,6 +259,15 @@ part as \"%%\" to use the normal format.
The fourth part is a regexp identifying the pattern following the time stamp.
This part may be omitted to use the normal pattern.
+The pattern does not need to match the entire line of the time stamp.
+
+These variables are best changed with file-local variables.
+If you were to change `time-stamp-pattern', `time-stamp-line-limit',
+`time-stamp-start', or `time-stamp-end' in your init file, you
+would be incompatible with other people's files.
+
+See also `time-stamp-count' and `time-stamp-inserts-lines'.
+
Examples:
\"-10/\" (sets only `time-stamp-line-limit')
@@ -255,38 +279,44 @@ Examples:
`time-stamp-format' and `time-stamp-end')
\"newcommand{\\\\\\\\timestamp}{%%}\" (sets `time-stamp-start'
-and `time-stamp-end')
-
-Do not change `time-stamp-pattern' `time-stamp-line-limit',
-`time-stamp-start', or `time-stamp-end' for yourself or you will be
-incompatible with other people's files! If you must change them for
-some application, do so only in the local variables section of the
-time-stamped file itself.")
+and `time-stamp-end')")
;;;###autoload(put 'time-stamp-pattern 'safe-local-variable 'stringp)
;;;###autoload
(defun time-stamp ()
- "Update the time stamp string(s) in the buffer.
-A template in a file can be automatically updated with a new time stamp
-every time you save the file. Add this line to your init file:
- (add-hook \\='before-save-hook \\='time-stamp)
-or customize option `before-save-hook'.
-Normally the template must appear in the first 8 lines of a file and
-look like one of the following:
+ "Update any time stamp string(s) in the buffer.
+This function looks for a time stamp template and updates it with
+the current date, time, and/or other info.
+
+The template, which you manually create on one of the first 8 lines
+of the file before running this function, by default can look like
+one of the following (your choice):
Time-stamp: <>
Time-stamp: \" \"
-The time stamp is written between the brackets or quotes:
+This function writes the current time between the brackets or quotes,
+by default formatted like this:
Time-stamp: <2020-08-07 17:10:21 gildea>
-The time stamp is updated only if the variable
-`time-stamp-active' is non-nil.
-The format of the time stamp is set by the variable
-`time-stamp-pattern' or `time-stamp-format'.
-The variables `time-stamp-pattern', `time-stamp-line-limit',
-`time-stamp-start', `time-stamp-end', `time-stamp-count', and
-`time-stamp-inserts-lines' control finding the template."
+Although you can run this function manually to update a time stamp
+once, usually you want automatic time stamp updating.
+
+A time stamp can be automatically updated with current information
+every time you save a file. To enable time-stamping for all files,
+customize option `before-save-hook' or add this line to your init file:
+ (add-hook \\='before-save-hook \\='time-stamp)
+
+To enable automatic time-stamping for only a specific file, add
+this line to a local variables list near the end of the file:
+ eval: (add-hook \\='before-save-hook \\='time-stamp nil t)
+
+If the file has no time-stamp template, this function does nothing.
+
+You can set `time-stamp-pattern' in a file's local variables list
+to customize the information in the time stamp and where it is written.
+
+The time stamp is updated only if `time-stamp-active' is non-nil."
(interactive)
(let ((line-limit time-stamp-line-limit)
(ts-start time-stamp-start)
@@ -431,6 +461,8 @@ With ARG, turn time stamping on if and only if ARG is positive."
(message "time-stamp is now %s." (if time-stamp-active "active" "off")))
(defun time-stamp--format (format time)
+ "FORMAT a TIME in zone `time-stamp-time-zone'.
+Internal helper used by `time-stamp-string-preprocess'."
(format-time-string format time time-stamp-time-zone))
(defun time-stamp-string (&optional ts-format time)
@@ -445,9 +477,8 @@ normally the current time is used."
(defconst time-stamp-no-file "(no file)"
"String to use when the buffer is not associated with a file.")
-;;; time-stamp is transitioning to be compatible with format-time-string.
-;;; During the process, this function implements
-;;; intermediate, compatible formats.
+;;; time-stamp is transitioning to be more compatible with format-time-string.
+;;; This function implements the differences.
;;; At all times, all the formats recommended in the doc string
;;; of time-stamp-format will work not only in the current version of
;;; Emacs, but in all versions that have been released within the past
@@ -457,7 +488,7 @@ normally the current time is used."
(defun time-stamp-string-preprocess (format &optional time)
"Use a FORMAT to format date, time, file, and user information.
Optional second argument TIME is only for testing.
-Implements extensions to `format-time-string'
+This is an internal routine implementing extensions to `format-time-string'
and all `time-stamp-format' compatibility."
(let ((fmt-len (length format))
(ind 0)
@@ -630,7 +661,7 @@ and all `time-stamp-format' compatibility."
(if buffer-file-name
(file-name-nondirectory buffer-file-name)
time-stamp-no-file))
- ((eq cur-char ?F) ;buffer-file-name, full path
+ ((eq cur-char ?F) ;buffer-file-name, absolute name
(or buffer-file-name
time-stamp-no-file))
((eq cur-char ?s) ;system name, legacy
@@ -681,15 +712,17 @@ and all `time-stamp-format' compatibility."
(defun time-stamp-do-number (format-char alt-form field-width time)
"Handle compatible FORMAT-CHAR where only default width/padding will change.
-ALT-FORM is whether `#' specified. FIELD-WIDTH is the string
-width specification or \"\". TIME is the time to convert."
+ALT-FORM is whether `#' was specified. FIELD-WIDTH is the string
+width specification or \"\". TIME is the time to convert.
+This is an internal helper for `time-stamp-string-preprocess'."
(let ((format-string (concat "%" (char-to-string format-char))))
(if (and (> alt-form 0) (not (string-equal field-width "")))
"" ;discourage "%:2d" and the like
(string-to-number (time-stamp--format format-string time)))))
+
(defvar time-stamp-conversion-warn t
- "Warn about soon-to-be-unsupported forms in `time-stamp-format'.
+ "Enable warnings about soon-to-be-unsupported forms in `time-stamp-format'.
If nil, these warnings are disabled, which would be a bad idea!
You really need to update your files instead.
@@ -715,6 +748,7 @@ Suggests replacing OLD-FORM with NEW-FORM."
(insert "\"" old-form "\" -- use " new-form "\n"))
(display-buffer "*Time-stamp-compatibility*"))))
+
;;; A principled, expressive implementation of time zone offset
;;; formatting ("%z" and variants).
@@ -755,7 +789,7 @@ Suggests replacing OLD-FORM with NEW-FORM."
;; Principles guiding our choices:
;;
;; - The syntax should be easy to remember and the effect predictable.
-;; - It should be possible to produces as many useful effects as possible.
+;; - The syntax should enable as many useful effects as possible.
;;
;; Padding choices:
;;
@@ -789,21 +823,19 @@ Suggests replacing OLD-FORM with NEW-FORM."
;; %07:z "+99:00:00" "+100:00"
;; %7::z "+99:00:00" "+100:00:00"
-;;; * BNF syntax of the offset string produced by %z
-
-;; <offset> ::= <sign><hours>[<minutes>[<seconds>]]<padding> |
-;; <sign><hours>[<colonminutes>[<colonseconds>]]<padding> |
-;; <sign><bighours><colonminutes>[<colonseconds>]<padding>
-;; <sign> ::= "+"|"-"
-;; <hours> ::= <2digits>
-;; <minutes> ::= <2digits>
-;; <seconds> ::= <2digits>
-;; <colonminutes> ::= ":"<minutes>
-;; <colonseconds> ::= ":"<seconds>
-;; <2digits> ::= <digit><digit>
-;; <digit> ::= "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
-;; <bighours> ::= <digit>*<digit><2digits>
-;; <padding> ::= " "*
+;;; * ABNF syntax of the offset string produced by %z
+
+;; offset = sign ( hours [minutes [seconds]] /
+;; hours [":" minutes [":" seconds]] /
+;; bighours ":" minutes [":" seconds] ) padding
+;; sign = "+" / "-"
+;; hours = digitpair
+;; minutes = digitpair
+;; seconds = digitpair
+;; digitpair = digit digit
+;; digit = "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9"
+;; bighours = 1*digit digitpair
+;; padding = *" "
(defun time-stamp-formatz-from-parsed-options (flag-minimize
flag-pad-spaces-only
@@ -812,8 +844,6 @@ Suggests replacing OLD-FORM with NEW-FORM."
field-width
offset-secs)
"Formats a time offset according to a %z variation.
-The caller of this function must have already parsed the %z format
-string; this function accepts just the parts of the format.
With no flags, the output includes hours and minutes: +-HHMM
unless there is a non-zero seconds part, in which case the seconds
@@ -840,7 +870,14 @@ added on the right if necessary. The added characters will be spaces
unless FLAG-PAD-ZEROS-FIRST is non-nil.
OFFSET-SECS is the time zone offset (in seconds east of UTC) to be
-formatted according to the preceding parameters."
+formatted according to the preceding parameters.
+
+This is an internal function used by `time-stamp'."
+ ;; The caller of this function must have already parsed the %z
+ ;; format string; this function accepts just the parts of the format.
+ ;; `time-stamp-string-preprocess' is the full-fledged parser normally
+ ;; used. The unit test (in time-stamp-tests.el) defines the simpler
+ ;; parser `format-time-offset'.
(let ((hrs (/ (abs offset-secs) 3600))
(mins (/ (% (abs offset-secs) 3600) 60))
(secs (% (abs offset-secs) 60))
diff --git a/lisp/time.el b/lisp/time.el
index 9f25f99a149..b67315cf630 100644
--- a/lisp/time.el
+++ b/lisp/time.el
@@ -340,10 +340,10 @@ Switches from the 1 to 5 to 15 minute load average, and then back to 1."
(float-time end-time))))))))))
(defun display-time-update ()
- "Update the display-time info for the mode line.
+ "Update the `display-time' info for the mode line.
However, don't redisplay right now.
-This is used for things like Rmail `g' that want to force an
+This is used for things like Rmail \\`g' that want to force an
update which can wait for the next redisplay."
(let* ((now (current-time))
(time (current-time-string now))
@@ -355,7 +355,7 @@ update which can wait for the next redisplay."
(am-pm (if (>= hour 12) "pm" "am"))
(minutes (substring time 14 16))
(seconds (substring time 17 19))
- (time-zone (car (cdr (current-time-zone now))))
+ (time-zone (format-time-string "%Z" now))
(day (substring time 8 10))
(year (format-time-string "%Y" now))
(monthname (substring time 4 7))
@@ -526,11 +526,9 @@ If the value is t instead of an alist, use the value of
'((t :inherit font-lock-variable-name-face))
"Face for time zone label in `world-clock' buffer.")
-(defvar world-clock-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "n" #'next-line)
- (define-key map "p" #'previous-line)
- map))
+(defvar-keymap world-clock-mode-map
+ "n" #'next-line
+ "p" #'previous-line)
(define-derived-mode world-clock-mode special-mode "World clock"
"Major mode for buffer that displays times in various time zones.
@@ -626,7 +624,7 @@ point."
;;;###autoload
(defun emacs-init-time (&optional format)
"Return a string giving the duration of the Emacs initialization.
-FORMAT is a string to format the result, using `format'. If nil,
+FORMAT is a string to format the result, using `format'. If nil,
the default format \"%f seconds\" is used."
(interactive)
(let ((str (format (or format "%f seconds")
diff --git a/lisp/timezone.el b/lisp/timezone.el
index 2c96343a74b..7a461c4e22d 100644
--- a/lisp/timezone.el
+++ b/lisp/timezone.el
@@ -95,10 +95,7 @@ if nil, the local time zone is assumed."
Optional argument TIMEZONE specifies a time zone."
(let ((zone
(if (listp timezone)
- (let* ((m (timezone-zone-to-minute timezone))
- (absm (if (< m 0) (- m) m)))
- (format "%c%02d%02d"
- (if (< m 0) ?- ?+) (/ absm 60) (% absm 60)))
+ (format-time-string "%z" 0 (or timezone 0))
timezone)))
(format "%02d %s %04d %s %s"
day
@@ -302,11 +299,10 @@ Return a list in the same format as `current-time-zone's result,
or nil if the local time zone could not be computed.
DATE is the number of days elapsed since the (imaginary)
Gregorian date Sunday, December 31, 1 BC."
- (and (fboundp 'current-time-zone)
- (let ((utc-time (timezone-time-from-absolute date seconds)))
- (and utc-time
- (let ((zone (current-time-zone utc-time)))
- (and (car zone) zone))))))
+ (let ((utc-time (timezone-time-from-absolute date seconds)))
+ (and utc-time
+ (let ((zone (current-time-zone utc-time)))
+ (and (car zone) zone)))))
(defun timezone-fix-time (date local timezone)
"Convert DATE (default timezone LOCAL) to YYYY-MM-DD-HH-MM-SS-ZONE vector.
diff --git a/lisp/tool-bar.el b/lisp/tool-bar.el
index 6da401187b1..f5d64aeb36c 100644
--- a/lisp/tool-bar.el
+++ b/lisp/tool-bar.el
@@ -290,6 +290,8 @@ holds a keymap."
"Specify on which side the tool bar shall be.
Possible values are `top' (tool bar on top), `bottom' (tool bar at bottom),
`left' (tool bar on left) and `right' (tool bar on right).
+This option has effect only on graphical frames and only
+if Emacs was built with GTK.
Customize `tool-bar-mode' if you want to show or hide the tool bar."
:version "24.1"
:type '(choice (const top)
diff --git a/lisp/tooltip.el b/lisp/tooltip.el
index 23b67ee2cab..6cc482d012a 100644
--- a/lisp/tooltip.el
+++ b/lisp/tooltip.el
@@ -368,10 +368,15 @@ It is also called if Tooltip mode is on, for text-only displays."
((equal-including-properties tooltip-help-message (current-message))
(message nil)))))
+(declare-function menu-or-popup-active-p "xmenu.c" ())
+
(defun tooltip-show-help (msg)
"Function installed as `show-help-function'.
MSG is either a help string to display, or nil to cancel the display."
- (if (display-graphic-p)
+ (if (and (display-graphic-p)
+ (or (not (eq window-system 'haiku)) ;; On Haiku, there isn't a reliable way to show tooltips
+ ;; above menus.
+ (not (menu-or-popup-active-p))))
(let ((previous-help tooltip-help-message))
(setq tooltip-help-message msg)
(cond ((null msg)
diff --git a/lisp/transient.el b/lisp/transient.el
index 5f441e80ddd..f80e6afb10b 100644
--- a/lisp/transient.el
+++ b/lisp/transient.el
@@ -7,7 +7,7 @@
;; Keywords: bindings
;; Package-Requires: ((emacs "25.1"))
-;; Package-Version: 0.3.6
+;; Package-Version: 0.3.7
;; SPDX-License-Identifier: GPL-3.0-or-later
@@ -54,6 +54,7 @@
(require 'cl-lib)
(require 'eieio)
+(require 'edmacro)
(require 'format-spec)
(require 'seq)
@@ -74,7 +75,7 @@
(define-obsolete-function-alias 'define-infix-command
'transient-define-infix "Transient 0.3.0")
(define-obsolete-function-alias 'define-infix-argument
- 'transient-define-argument "Transient 0.3.0")
+ #'transient-define-argument "Transient 0.3.0")
(define-obsolete-variable-alias 'current-transient-prefix
'transient-current-prefix "Transient 0.3.0")
@@ -148,34 +149,46 @@ features are available:
(defcustom transient-display-buffer-action
'(display-buffer-in-side-window
(side . bottom)
- (inhibit-same-window . t))
+ (dedicated . t)
+ (inhibit-same-window . t)
+ (window-parameters (no-other-window . t)))
"The action used to display the transient popup buffer.
The transient popup buffer is displayed in a window using
- \(display-buffer buf transient-display-buffer-action)
+ (display-buffer BUFFER transient-display-buffer-action)
The value of this option has the form (FUNCTION . ALIST),
where FUNCTION is a function or a list of functions. Each such
-function should accept two arguments: a buffer to display and
-an alist of the same form as ALIST. See `display-buffer' for
-details.
+function should accept two arguments: a buffer to display and an
+alist of the same form as ALIST. See info node `(elisp)Choosing
+Window' for details.
The default is:
(display-buffer-in-side-window
(side . bottom)
- (inhibit-same-window . t))
+ (dedicated . t)
+ (inhibit-same-window . t)
+ (window-parameters (no-other-window . t)))
This displays the window at the bottom of the selected frame.
-Another useful value is (display-buffer-below-selected). This
-is what `magit-popup' used by default. For more alternatives
-see info node `(elisp)Display Action Functions'.
+Another useful FUNCTION is `display-buffer-below-selected', which
+is what `magit-popup' used by default. For more alternatives see
+info node `(elisp)Display Action Functions' and info node
+`(elisp)Buffer Display Action Alists'.
+
+Note that the buffer that was current before the transient buffer
+is shown should remain the current buffer. Many suffix commands
+act on the thing at point, if appropriate, and if the transient
+buffer became the current buffer, then that would change what is
+at point. To that effect `inhibit-same-window' ensures that the
+selected window is not used to show the transient buffer.
It may be possible to display the window in another frame, but
whether that works in practice depends on the window-manager.
If the window manager selects the new window (Emacs frame),
-then it doesn't work.
+then that unfortunately changes which buffer is current.
If you change the value of this option, then you might also
want to change the value of `transient-mode-line-format'."
@@ -266,7 +279,7 @@ discouraged.
For example, \"=\" is hard to reach using my custom keyboard
layout, so I substitute \"(\" for that, which is easy to reach
-using a layout optimized for lisp.
+using a layout optimized for Lisp.
(setq transient-substitute-key-function
(lambda (obj)
@@ -569,7 +582,7 @@ If `transient-save-history' is nil, then do nothing."
(transient-save-history)))
(unless noninteractive
- (add-hook 'kill-emacs-hook 'transient-maybe-save-history))
+ (add-hook 'kill-emacs-hook #'transient-maybe-save-history))
;;; Classes
;;;; Prefix
@@ -585,12 +598,14 @@ If `transient-save-history' is nil, then do nothing."
(history :initarg :history :initform nil)
(history-pos :initarg :history-pos :initform 0)
(history-key :initarg :history-key :initform nil)
- (man-page :initarg :man-page :initform nil)
+ (show-help :initarg :show-help :initform nil)
(info-manual :initarg :info-manual :initform nil)
+ (man-page :initarg :man-page :initform nil)
(transient-suffix :initarg :transient-suffix :initform nil)
(transient-non-suffix :initarg :transient-non-suffix :initform nil)
(incompatible :initarg :incompatible :initform nil)
- (suffix-description :initarg :suffix-description))
+ (suffix-description :initarg :suffix-description)
+ (variable-pitch :initarg :variable-pitch :initform nil))
"Transient prefix command.
Each transient prefix command consists of a command, which is
@@ -640,7 +655,7 @@ the prototype is stored in the clone's `prototype' slot.")
:initarg :if-not-derived
:initform nil
:documentation "Enable if major-mode does not derive from value."))
- "Abstract superclass for group and and suffix classes.
+ "Abstract superclass for group and suffix classes.
It is undefined what happens if more than one `if*' predicate
slot is non-nil."
@@ -652,6 +667,7 @@ slot is non-nil."
(transient :initarg :transient)
(format :initarg :format :initform " %k %d")
(description :initarg :description :initform nil)
+ (show-help :initarg :show-help :initform nil)
(inapt :initform nil)
(inapt-if
:initarg :inapt-if
@@ -726,10 +742,14 @@ slot is non-nil."
(argument-regexp :initarg :argument-regexp))
"Class used for sets of mutually exclusive command-line switches.")
-(defclass transient-files (transient-infix) ()
- "Class used for the \"--\" argument.
+(defclass transient-files (transient-option) ()
+ ((key :initform "--")
+ (argument :initform "--")
+ (multi-value :initform rest)
+ (reader :initform transient-read-files))
+ "Class used for the \"--\" argument or similar.
All remaining arguments are treated as files.
-They become the value of this this argument.")
+They become the value of this argument.")
;;;; Group
@@ -910,7 +930,7 @@ keyword.
(put ',name 'transient--suffix
(,(or class 'transient-switch) :command ',name ,@slots)))))
-(defalias 'transient-define-argument 'define-infix-command
+(defalias 'transient-define-argument #'transient-define-infix
"Define NAME as a transient infix command.
Only use this alias to define an infix command that actually
@@ -1061,7 +1081,8 @@ example, sets a variable use `transient-define-infix' instead.
(put cmd 'transient--infix-command
(transient--default-infix-command))
;; This is not an anonymous infix argument.
- (error "Suffix %s is not defined or autoloaded as a command" cmd)))))
+ (when (transient--use-suffix-p obj)
+ (error "Suffix %s is not defined or autoloaded as a command" cmd))))))
(defun transient--derive-shortarg (arg)
(save-match-data
@@ -1415,14 +1436,14 @@ then just return it. Otherwise return the symbol whose
(defvar transient-base-map
(let ((map (make-sparse-keymap)))
- (define-key map (kbd "ESC ESC ESC") 'transient-quit-all)
- (define-key map (kbd "C-g") 'transient-quit-one)
- (define-key map (kbd "C-q") 'transient-quit-all)
- (define-key map (kbd "C-z") 'transient-suspend)
- (define-key map (kbd "C-v") 'transient-scroll-up)
- (define-key map (kbd "C-M-v") 'transient-scroll-down)
- (define-key map [next] 'transient-scroll-up)
- (define-key map [prior] 'transient-scroll-down)
+ (define-key map (kbd "ESC ESC ESC") #'transient-quit-all)
+ (define-key map (kbd "C-g") #'transient-quit-one)
+ (define-key map (kbd "C-q") #'transient-quit-all)
+ (define-key map (kbd "C-z") #'transient-suspend)
+ (define-key map (kbd "C-v") #'transient-scroll-up)
+ (define-key map (kbd "C-M-v") #'transient-scroll-down)
+ (define-key map [next] #'transient-scroll-up)
+ (define-key map [prior] #'transient-scroll-down)
map)
"Parent of other keymaps used by Transient.
@@ -1442,14 +1463,14 @@ to `transient-predicate-map'.")
(defvar transient-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map transient-base-map)
- (define-key map (kbd "C-p") 'universal-argument)
- (define-key map (kbd "C--") 'negative-argument)
- (define-key map (kbd "C-t") 'transient-show)
- (define-key map (kbd "?") 'transient-help)
- (define-key map (kbd "C-h") 'transient-help)
+ (define-key map (kbd "C-u") #'universal-argument)
+ (define-key map (kbd "C--") #'negative-argument)
+ (define-key map (kbd "C-t") #'transient-show)
+ (define-key map (kbd "?") #'transient-help)
+ (define-key map (kbd "C-h") #'transient-help)
;; Also bound to "C-x p" and "C-x n" in transient-common-commands.
- (define-key map (kbd "C-M-p") 'transient-history-prev)
- (define-key map (kbd "C-M-n") 'transient-history-next)
+ (define-key map (kbd "C-M-p") #'transient-history-prev)
+ (define-key map (kbd "C-M-n") #'transient-history-next)
map)
"Top-level keymap used by all transients.
@@ -1459,16 +1480,16 @@ to `transient-predicate-map'. Also see `transient-base-map'.")
(defvar transient-edit-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map transient-base-map)
- (define-key map (kbd "?") 'transient-help)
- (define-key map (kbd "C-h") 'transient-help)
- (define-key map (kbd "C-x l") 'transient-set-level)
+ (define-key map (kbd "?") #'transient-help)
+ (define-key map (kbd "C-h") #'transient-help)
+ (define-key map (kbd "C-x l") #'transient-set-level)
map)
"Keymap that is active while a transient in is in \"edit mode\".")
(defvar transient-sticky-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map transient-base-map)
- (define-key map (kbd "C-g") 'transient-quit-seq)
+ (define-key map (kbd "C-g") #'transient-quit-seq)
map)
"Keymap that is active while an incomplete key sequence is active.")
@@ -1503,36 +1524,36 @@ to `transient-predicate-map'. Also see `transient-base-map'.")
(defvar transient-predicate-map
(let ((map (make-sparse-keymap)))
- (define-key map [handle-switch-frame] 'transient--do-suspend)
- (define-key map [transient-suspend] 'transient--do-suspend)
- (define-key map [transient-help] 'transient--do-stay)
- (define-key map [transient-set-level] 'transient--do-stay)
- (define-key map [transient-history-prev] 'transient--do-stay)
- (define-key map [transient-history-next] 'transient--do-stay)
- (define-key map [universal-argument] 'transient--do-stay)
- (define-key map [negative-argument] 'transient--do-stay)
- (define-key map [digit-argument] 'transient--do-stay)
- (define-key map [transient-quit-all] 'transient--do-quit-all)
- (define-key map [transient-quit-one] 'transient--do-quit-one)
- (define-key map [transient-quit-seq] 'transient--do-stay)
- (define-key map [transient-show] 'transient--do-stay)
- (define-key map [transient-update] 'transient--do-stay)
- (define-key map [transient-toggle-common] 'transient--do-stay)
- (define-key map [transient-set] 'transient--do-call)
- (define-key map [transient-save] 'transient--do-call)
- (define-key map [describe-key-briefly] 'transient--do-stay)
- (define-key map [describe-key] 'transient--do-stay)
- (define-key map [transient-scroll-up] 'transient--do-stay)
- (define-key map [transient-scroll-down] 'transient--do-stay)
- (define-key map [mwheel-scroll] 'transient--do-stay)
- (define-key map [scroll-bar-toolkit-scroll] 'transient--do-stay)
- (define-key map [transient-noop] 'transient--do-noop)
- (define-key map [transient-mouse-push-button] 'transient--do-move)
- (define-key map [transient-push-button] 'transient--do-move)
- (define-key map [transient-backward-button] 'transient--do-move)
- (define-key map [transient-forward-button] 'transient--do-move)
- (define-key map [transient-isearch-backward] 'transient--do-move)
- (define-key map [transient-isearch-forward] 'transient--do-move)
+ (define-key map [handle-switch-frame] #'transient--do-suspend)
+ (define-key map [transient-suspend] #'transient--do-suspend)
+ (define-key map [transient-help] #'transient--do-stay)
+ (define-key map [transient-set-level] #'transient--do-stay)
+ (define-key map [transient-history-prev] #'transient--do-stay)
+ (define-key map [transient-history-next] #'transient--do-stay)
+ (define-key map [universal-argument] #'transient--do-stay)
+ (define-key map [negative-argument] #'transient--do-stay)
+ (define-key map [digit-argument] #'transient--do-stay)
+ (define-key map [transient-quit-all] #'transient--do-quit-all)
+ (define-key map [transient-quit-one] #'transient--do-quit-one)
+ (define-key map [transient-quit-seq] #'transient--do-stay)
+ (define-key map [transient-show] #'transient--do-stay)
+ (define-key map [transient-update] #'transient--do-stay)
+ (define-key map [transient-toggle-common] #'transient--do-stay)
+ (define-key map [transient-set] #'transient--do-call)
+ (define-key map [transient-save] #'transient--do-call)
+ (define-key map [describe-key-briefly] #'transient--do-stay)
+ (define-key map [describe-key] #'transient--do-stay)
+ (define-key map [transient-scroll-up] #'transient--do-stay)
+ (define-key map [transient-scroll-down] #'transient--do-stay)
+ (define-key map [mwheel-scroll] #'transient--do-stay)
+ (define-key map [scroll-bar-toolkit-scroll] #'transient--do-stay)
+ (define-key map [transient-noop] #'transient--do-noop)
+ (define-key map [transient-mouse-push-button] #'transient--do-move)
+ (define-key map [transient-push-button] #'transient--do-move)
+ (define-key map [transient-backward-button] #'transient--do-move)
+ (define-key map [transient-forward-button] #'transient--do-move)
+ (define-key map [transient-isearch-backward] #'transient--do-move)
+ (define-key map [transient-isearch-forward] #'transient--do-move)
map)
"Base keymap used to map common commands to their transient behavior.
@@ -1606,22 +1627,23 @@ of the corresponding object.")
(sym (transient--suffix-symbol cmd)))
(cond
((oref obj inapt)
- (define-key map (vector sym) 'transient--do-warn-inapt))
+ (define-key map (vector sym) #'transient--do-warn-inapt))
((slot-boundp obj 'transient)
(define-key map (vector sym)
(let ((do (oref obj transient)))
(pcase do
- (`t (if sub-prefix
- 'transient--do-replace
- 'transient--do-stay))
+ (`t (cond (sub-prefix #'transient--do-replace)
+ ((cl-typep obj 'transient-infix)
+ #'transient--do-stay)
+ (t #'transient--do-call)))
(`nil 'transient--do-exit)
(_ do)))))
((not (lookup-key transient-predicate-map (vector sym)))
(define-key map (vector sym)
(if sub-prefix
- 'transient--do-replace
+ #'transient--do-replace
(or (oref transient--prefix transient-suffix)
- 'transient--do-exit)))))))
+ #'transient--do-exit)))))))
map))
(defun transient--make-redisplay-map ()
@@ -1649,7 +1671,7 @@ of the corresponding object.")
(listp def)
(keymapp def))
(define-key topmap (vconcat transient--redisplay-key (list key))
- 'transient-update)))
+ #'transient-update)))
(if transient--redisplay-key
(lookup-key transient--transient-map (vconcat transient--redisplay-key))
transient--transient-map))
@@ -1678,7 +1700,7 @@ EDIT may be non-nil."
(transient--pop-keymap 'transient--redisplay-map)
(setq name (oref transient--prefix command))
(setq params (list :scope (oref transient--prefix scope))))
- (transient--transient-map
+ (transient--prefix
;; Invoked as a ":transient-non-suffix 'transient--do-{stay,call}"
;; of an outer prefix. Unlike the usual `transient--do-replace',
;; these predicates fail to clean up after the outer prefix.
@@ -1953,8 +1975,10 @@ value. Otherwise return CHILDREN as is."
(defun transient--delete-window ()
(when (window-live-p transient--window)
(let ((buf (window-buffer transient--window)))
- (with-demoted-errors "Error while exiting transient: %S"
- (delete-window transient--window))
+ ;; Only delete the window if it never showed another buffer.
+ (unless (eq (car (window-parameter transient--window 'quit-restore)) 'other)
+ (with-demoted-errors "Error while exiting transient: %S"
+ (delete-window transient--window)))
(kill-buffer buf))))
(defun transient--export ()
@@ -2093,8 +2117,8 @@ value. Otherwise return CHILDREN as is."
(defun transient--emergency-exit ()
"Exit the current transient command after an error occurred.
-When no transient is active (i.e. when `transient--prefix') is
-nil, then do nothing."
+When no transient is active (i.e. when `transient--prefix' is
+nil) then do nothing."
(transient--debug 'emergency-exit)
(when transient--prefix
(setq transient--stack nil)
@@ -2171,17 +2195,17 @@ to `transient--do-warn'."
(setq this-command 'transient-popup-navigation-help))
transient--stay)
-(put 'transient--do-stay 'transient-color 'transient-blue)
-(put 'transient--do-noop 'transient-color 'transient-blue)
-(put 'transient--do-warn 'transient-color 'transient-blue)
-(put 'transient--do-warn-inapt 'transient-color 'transient-blue)
-(put 'transient--do-call 'transient-color 'transient-blue)
-(put 'transient--do-exit 'transient-color 'transient-red)
-(put 'transient--do-replace 'transient-color 'transient-red)
-(put 'transient--do-suspend 'transient-color 'transient-red)
-(put 'transient--do-quit-one 'transient-color 'transient-red)
-(put 'transient--do-quit-all 'transient-color 'transient-red)
-(put 'transient--do-move 'transient-color 'transient-blue)
+(put 'transient--do-stay 'transient-color 'transient-red)
+(put 'transient--do-noop 'transient-color 'transient-red)
+(put 'transient--do-warn 'transient-color 'transient-red)
+(put 'transient--do-warn-inapt 'transient-color 'transient-red)
+(put 'transient--do-call 'transient-color 'transient-red)
+(put 'transient--do-exit 'transient-color 'transient-blue)
+(put 'transient--do-replace 'transient-color 'transient-blue)
+(put 'transient--do-suspend 'transient-color 'transient-blue)
+(put 'transient--do-quit-one 'transient-color 'transient-blue)
+(put 'transient--do-quit-all 'transient-color 'transient-blue)
+(put 'transient--do-move 'transient-color 'transient-red)
;;; Commands
@@ -2209,7 +2233,18 @@ to `transient--do-warn'."
(propertize "?" 'face 'transient-key)
(propertize (symbol-name (transient--suffix-symbol
this-original-command))
- 'face 'font-lock-warning-face)))
+ 'face 'font-lock-warning-face))
+ (unless (and transient--transient-map
+ (memq transient--transient-map overriding-terminal-local-map))
+ (let ((transient--prefix (or transient--prefix 'sic)))
+ (transient--emergency-exit))
+ (view-lossage)
+ (other-window 1)
+ (display-warning 'transient "Inconsistent transient state detected.
+This should never happen.
+Please open an issue and post the shown command log.
+This is a heisenbug, so any additional details might help.
+Thanks!" :error)))
(defun transient-toggle-common ()
"Toggle whether common commands are always shown."
@@ -2407,14 +2442,14 @@ Non-infix suffix commands usually don't have a value."
(cl-defmethod transient-init-value :around ((obj transient-prefix))
"If bound, then call OBJ's `init-value' function.
-Otherwise call the primary method according to objects class."
+Otherwise call the primary method according to object's class."
(if (slot-boundp obj 'init-value)
(funcall (oref obj init-value) obj)
(cl-call-next-method obj)))
(cl-defmethod transient-init-value :around ((obj transient-infix))
"If bound, then call OBJ's `init-value' function.
-Otherwise call the primary method according to objects class."
+Otherwise call the primary method according to object's class."
(if (slot-boundp obj 'init-value)
(funcall (oref obj init-value) obj)
(cl-call-next-method obj)))
@@ -2432,30 +2467,30 @@ Otherwise call the primary method according to objects class."
default)
nil)))))
+(cl-defmethod transient-init-value ((obj transient-argument))
+ (oset obj value
+ (let ((value (oref transient--prefix value))
+ (argument (and (slot-boundp obj 'argument)
+ (oref obj argument)))
+ (multi-value (oref obj multi-value))
+ (regexp (if (slot-exists-p obj 'argument-regexp)
+ (oref obj argument-regexp)
+ (format "\\`%s\\(.*\\)" (oref obj argument)))))
+ (if (memq multi-value '(t rest))
+ (cdr (assoc argument value))
+ (let ((match (lambda (v)
+ (and (stringp v)
+ (string-match regexp v)
+ (match-string 1 v)))))
+ (if multi-value
+ (delq nil (mapcar match value))
+ (cl-some match value)))))))
+
(cl-defmethod transient-init-value ((obj transient-switch))
(oset obj value
(car (member (oref obj argument)
(oref transient--prefix value)))))
-(cl-defmethod transient-init-value ((obj transient-option))
- (oset obj value
- (transient--value-match (format "\\`%s\\(.*\\)" (oref obj argument)))))
-
-(cl-defmethod transient-init-value ((obj transient-switches))
- (oset obj value
- (transient--value-match (oref obj argument-regexp))))
-
-(defun transient--value-match (re)
- (when-let ((match (cl-find-if (lambda (v)
- (and (stringp v)
- (string-match re v)))
- (oref transient--prefix value))))
- (match-string 1 match)))
-
-(cl-defmethod transient-init-value ((obj transient-files))
- (oset obj value
- (cdr (assoc "--" (oref transient--prefix value)))))
-
;;;; Read
(cl-defgeneric transient-infix-read (obj)
@@ -2595,13 +2630,12 @@ stand-alone command."
(cl-block nil
(while t
(let ((str (read-from-minibuffer prompt initial-input nil nil history)))
- (cond ((string-equal str "")
- (cl-return nil))
- ((string-match-p (if include-zero
- "\\`\\(0\\|[1-9][0-9]*\\)\\'"
- "\\`[1-9][0-9]*\\'")
- str)
- (cl-return str))))
+ (when (or (string-equal str "")
+ (string-match-p (if include-zero
+ "\\`\\(0\\|[1-9][0-9]*\\)\\'"
+ "\\`[1-9][0-9]*\\'")
+ str))
+ (cl-return str)))
(message "Please enter a natural number (%s zero)."
(if include-zero "including" "excluding"))
(sit-for 1)))))
@@ -2670,7 +2704,10 @@ prompt."
(oref obj argument-regexp))))
(if-let ((sic (and value arg transient--unset-incompatible))
(spec (oref transient--prefix incompatible))
- (incomp (remove arg (cl-find-if (lambda (elt) (member arg elt)) spec))))
+ (incomp (cl-mapcan (lambda (rule)
+ (and (member arg rule)
+ (remove arg rule)))
+ spec)))
(progn
(cl-call-next-method obj value)
(dolist (arg incomp)
@@ -2703,7 +2740,7 @@ If the current command was invoked from the transient prefix
command PREFIX, then return the active infix arguments. If
the current command was not invoked from PREFIX, then return
the set, saved or default value for PREFIX."
- (delq nil (mapcar 'transient-infix-value (transient-suffixes prefix))))
+ (cl-mapcan #'transient--get-wrapped-value (transient-suffixes prefix)))
(defun transient-suffixes (prefix)
"Return the suffix objects of the transient prefix command PREFIX."
@@ -2714,11 +2751,20 @@ the set, saved or default value for PREFIX."
(transient--init-suffixes prefix)))))
(defun transient-get-value ()
- (delq nil (mapcar (lambda (obj)
- (and (or (not (slot-exists-p obj 'unsavable))
- (not (oref obj unsavable)))
- (transient-infix-value obj)))
- transient-current-suffixes)))
+ (transient--with-emergency-exit
+ (cl-mapcan (lambda (obj)
+ (and (or (not (slot-exists-p obj 'unsavable))
+ (not (oref obj unsavable)))
+ (transient--get-wrapped-value obj)))
+ transient-current-suffixes)))
+
+(defun transient--get-wrapped-value (obj)
+ (when-let ((value (transient-infix-value obj)))
+ (cl-ecase (and (slot-exists-p obj 'multi-value)
+ (oref obj multi-value))
+ ((nil) (list value))
+ ((t rest) (list value))
+ (repeat value))))
(cl-defgeneric transient-infix-value (obj)
"Return the value of the suffix object OBJ.
@@ -2736,7 +2782,7 @@ Usually only infixes have a value, but see the method for
(cl-defmethod transient-infix-value ((_ transient-suffix))
"Return nil, which means \"no value\".
-Infix arguments contribute the the transient's value while suffix
+Infix arguments contribute the transient's value while suffix
commands consume it. This function is called for suffixes anyway
because a command that both contributes to the transient's value
and also consumes it is not completely unconceivable.
@@ -2750,13 +2796,13 @@ does nothing." nil)
(oref obj value))
(cl-defmethod transient-infix-value ((obj transient-option))
- "Return (concat ARGUMENT VALUE) or nil.
-
-ARGUMENT and VALUE are the values of the respective slots of OBJ.
-If VALUE is nil, then return nil. VALUE may be the empty string,
-which is not the same as nil."
+ "Return ARGUMENT and VALUE as a unit or nil if the latter is nil."
(when-let ((value (oref obj value)))
- (concat (oref obj argument) value)))
+ (let ((arg (oref obj argument)))
+ (cl-ecase (oref obj multi-value)
+ ((nil) (concat arg value))
+ ((t rest) (cons arg value))
+ (repeat (mapcar (lambda (v) (concat arg v)) value))))))
(cl-defmethod transient-infix-value ((_ transient-variable))
"Return nil, which means \"no value\".
@@ -2766,15 +2812,6 @@ value of the variable. I.e. this is a side-effect and does not
contribute to the value of the transient."
nil)
-(cl-defmethod transient-infix-value ((obj transient-files))
- "Return (cons ARGUMENT VALUE) or nil.
-
-ARGUMENT and VALUE are the values of the respective slots of OBJ.
-If VALUE is nil, then return nil. VALUE may be the empty string,
-which is not the same as nil."
- (when-let ((value (oref obj value)))
- (cons (oref obj argument) value)))
-
;;;; Utilities
(defun transient-arg-value (arg args)
@@ -2860,16 +2897,11 @@ have a history of their own.")
(setq transient--showp t)
(let ((buf (get-buffer-create transient--buffer-name))
(focus nil))
- (unless (window-live-p transient--window)
- (setq transient--window
- (display-buffer buf transient-display-buffer-action)))
- (with-selected-window transient--window
+ (with-current-buffer buf
(when transient-enable-popup-navigation
- (setq focus (button-get (point) 'command)))
+ (setq focus (or (button-get (point) 'command)
+ (transient--heading-at-point))))
(erase-buffer)
- (set-window-hscroll transient--window 0)
- (set-window-dedicated-p transient--window t)
- (set-window-parameter transient--window 'no-other-window t)
(setq window-size-fixed t)
(when (bound-and-true-p tab-line-format)
(setq tab-line-format nil))
@@ -2896,14 +2928,26 @@ have a history of their own.")
'transient-separator)))
(insert (propertize "__" 'face face 'display '(space :height (1))))
(insert (propertize "\n" 'face face 'line-height t))))
- (let ((window-resize-pixelwise t)
- (window-size-fixed nil))
- (fit-window-to-buffer nil nil 1))
- (goto-char (point-min))
(when transient-force-fixed-pitch
- (transient--force-fixed-pitch))
- (when transient-enable-popup-navigation
- (transient--goto-button focus)))))
+ (transient--force-fixed-pitch)))
+ (unless (window-live-p transient--window)
+ (setq transient--window
+ (display-buffer buf transient-display-buffer-action)))
+ (when (window-live-p transient--window)
+ (with-selected-window transient--window
+ (goto-char (point-min))
+ (when transient-enable-popup-navigation
+ (transient--goto-button focus))
+ (magit--fit-window-to-buffer transient--window)))))
+
+(defun magit--fit-window-to-buffer (window)
+ (let ((window-resize-pixelwise t)
+ (window-size-fixed nil))
+ (if (eq (car (window-parameter window 'quit-restore)) 'other)
+ ;; Grow but never shrink window that previously displayed
+ ;; another buffer and is going to display that again.
+ (fit-window-to-buffer window nil (window-height window))
+ (fit-window-to-buffer window nil 1))))
(defun transient--insert-groups ()
(let ((groups (cl-mapcan (lambda (group)
@@ -2946,16 +2990,22 @@ have a history of their own.")
(mapcar
(lambda (column)
(transient--maybe-pad-keys column group)
- (let ((rows (mapcar 'transient-format (oref column suffixes))))
+ (let ((rows (mapcar #'transient-format (oref column suffixes))))
(when-let ((desc (transient-format-description column)))
(push desc rows))
rows))
(oref group suffixes)))
+ (vp (oref transient--prefix variable-pitch))
(rs (apply #'max (mapcar #'length columns)))
(cs (length columns))
- (cw (mapcar (lambda (col) (apply #'max (mapcar #'length col)))
+ (cw (mapcar (lambda (col)
+ (apply #'max
+ (mapcar (if vp #'transient--pixel-width #'length)
+ col)))
columns))
- (cc (transient--seq-reductions-from (apply-partially #'+ 3) cw 0)))
+ (cc (transient--seq-reductions-from
+ (apply-partially #'+ (* 3 (if vp (transient--pixel-width " ") 1)))
+ cw 0)))
(if transient-force-single-column
(dotimes (c cs)
(dotimes (r rs)
@@ -2966,11 +3016,28 @@ have a history of their own.")
(insert ?\n)))
(dotimes (r rs)
(dotimes (c cs)
- (insert (make-string (- (nth c cc) (current-column)) ?\s))
- (when-let ((cell (nth r (nth c columns))))
- (insert cell))
- (when (= c (1- cs))
- (insert ?\n)))))))
+ (if vp
+ (progn
+ (when-let ((cell (nth r (nth c columns))))
+ (insert cell))
+ (if (= c (1- cs))
+ (insert ?\n)
+ (insert (propertize " " 'display
+ `(space :align-to (,(nth (1+ c) cc)))))))
+ (insert (make-string (- (nth c cc) (current-column)) ?\s))
+ (when-let ((cell (nth r (nth c columns))))
+ (insert cell))
+ (when (= c (1- cs))
+ (insert ?\n))))))))
+
+(defun transient--pixel-width (string)
+ (save-window-excursion
+ (with-temp-buffer
+ (insert string)
+ (set-window-dedicated-p nil nil)
+ (set-window-buffer nil (current-buffer))
+ (car (window-text-pixel-size
+ nil (line-beginning-position) (point))))))
(cl-defmethod transient--insert-group ((group transient-subgroups))
(let* ((subgroups (oref group suffixes))
@@ -3064,18 +3131,18 @@ Optional support for popup buttons is also implemented here."
((equal (seq-take seq len) transient--redisplay-key)
(let ((pre (key-description (vconcat (seq-take seq len))))
(suf (key-description (vconcat (seq-drop seq len)))))
- (setq pre (string-replace "RET" "C-m" pre))
- (setq pre (string-replace "TAB" "C-i" pre))
- (setq suf (string-replace "RET" "C-m" suf))
- (setq suf (string-replace "TAB" "C-i" suf))
+ (setq pre (replace-regexp-in-string "RET" "C-m" pre t))
+ (setq pre (replace-regexp-in-string "TAB" "C-i" pre t))
+ (setq suf (replace-regexp-in-string "RET" "C-m" suf t))
+ (setq suf (replace-regexp-in-string "TAB" "C-i" suf t))
;; We use e.g. "-k" instead of the more correct "- k",
;; because the former is prettier. If we did that in
;; the definition, then we want to drop the space that
;; is reinserted above. False-positives are possible
;; for silly bindings like "-C-c C-c".
- (unless (string-search " " key)
- (setq pre (string-replace " " "" pre))
- (setq suf (string-replace " " "" suf)))
+ (unless (string-match-p " " key)
+ (setq pre (replace-regexp-in-string " " "" pre))
+ (setq suf (replace-regexp-in-string " " "" suf)))
(concat (propertize pre 'face 'default)
(and (string-prefix-p (concat pre " ") key) " ")
(transient--colorize-key suf cmd)
@@ -3157,14 +3224,17 @@ If the OBJ's `key' is currently unreachable, then apply the face
'transient-inactive-argument)))
(cl-defmethod transient-format-value ((obj transient-option))
- (let ((value (oref obj value)))
- (propertize (concat (oref obj argument)
- (if (listp value)
- (mapconcat #'identity value ",")
- value))
- 'face (if value
- 'transient-value
- 'transient-inactive-value))))
+ (let ((argument (oref obj argument)))
+ (if-let ((value (oref obj value)))
+ (propertize
+ (cl-ecase (oref obj multi-value)
+ ((nil) (concat argument value))
+ ((t rest) (concat argument
+ (and (not (string-suffix-p " " argument)) " ")
+ (mapconcat #'prin1-to-string value " ")))
+ (repeat (mapconcat (lambda (v) (concat argument v)) value " ")))
+ 'face 'transient-value)
+ (propertize argument 'face 'transient-inactive-value))))
(cl-defmethod transient-format-value ((obj transient-switches))
(with-slots (value argument-format choices) obj
@@ -3184,15 +3254,6 @@ If the OBJ's `key' is currently unreachable, then apply the face
(propertize "|" 'face 'transient-inactive-value))
(propertize "]" 'face 'transient-inactive-value)))))
-(cl-defmethod transient-format-value ((obj transient-files))
- (let ((argument (oref obj argument)))
- (if-let ((value (oref obj value)))
- (propertize (concat argument " "
- (mapconcat (lambda (f) (format "%S" f))
- (oref obj value) " "))
- 'face 'transient-argument)
- (propertize argument 'face 'transient-inactive-argument))))
-
(defun transient--key-unreachable-p (obj)
(and transient--redisplay-key
(let ((key (oref obj key)))
@@ -3236,41 +3297,58 @@ a prefix command, while porting a regular keymap to a transient."
;;; Help
(cl-defgeneric transient-show-help (obj)
- "Show help for OBJ's command.")
+ "Show documentation for the command represented by OBJ.")
(cl-defmethod transient-show-help ((obj transient-prefix))
- "Show the info manual, manpage or command doc-string.
-Show the first one that is specified."
- (if-let ((manual (oref obj info-manual)))
- (info manual)
- (if-let ((manpage (oref obj man-page)))
- (transient--show-manpage manpage)
- (transient--describe-function (oref obj command)))))
+ "Call `show-help' if non-nil, else show `info-manual',
+if non-nil, else show the `man-page' if non-nil, else use
+`describe-function'."
+ (with-slots (show-help info-manual man-page command) obj
+ (cond (show-help (funcall show-help obj))
+ (info-manual (transient--show-manual info-manual))
+ (man-page (transient--show-manpage man-page))
+ (t (transient--describe-function command)))))
(cl-defmethod transient-show-help ((obj transient-suffix))
- "Show the command doc-string."
- (if (eq this-original-command 'transient-help)
- (if-let ((manpage (oref transient--prefix man-page)))
- (transient--show-manpage manpage)
- (transient--describe-function (oref transient--prefix command)))
- (if-let ((prefix (get (transient--suffix-command obj) 'transient--prefix))
- (manpage (oref prefix man-page)))
- (transient--show-manpage manpage)
- (transient--describe-function this-original-command))))
+ "Call `show-help' if non-nil, else use `describe-function'.
+Also used to dispatch showing documentation for the current
+prefix. If the suffix is a sub-prefix, then also call the
+prefix method."
+ (cond
+ ((eq this-command 'transient-help)
+ (transient-show-help transient--prefix))
+ ((let ((prefix (get (transient--suffix-command obj)
+ 'transient--prefix)))
+ (and prefix (not (eq (oref transient--prefix command) this-command))
+ (prog1 t (transient-show-help prefix)))))
+ (t (if-let ((show-help (oref obj show-help)))
+ (funcall show-help obj)
+ (transient--describe-function this-command)))))
(cl-defmethod transient-show-help ((obj transient-infix))
- "Show the manpage if defined or the command doc-string.
-If the manpage is specified, then try to jump to the correct
-location."
- (if-let ((manpage (oref transient--prefix man-page)))
- (transient--show-manpage manpage (ignore-errors (oref obj argument)))
- (transient--describe-function this-original-command)))
+ "Call `show-help' if non-nil, else show the `man-page'
+if non-nil, else use `describe-function'. When showing the
+manpage, then try to jump to the correct location."
+ (if-let ((show-help (oref obj show-help)))
+ (funcall show-help obj)
+ (if-let ((man-page (oref transient--prefix man-page))
+ (argument (and (slot-boundp obj 'argument)
+ (oref obj argument))))
+ (transient--show-manpage man-page argument)
+ (transient--describe-function this-command))))
;; `cl-generic-generalizers' doesn't support `command' et al.
(cl-defmethod transient-show-help (cmd)
"Show the command doc-string."
(transient--describe-function cmd))
+(defun transient--describe-function (fn)
+ (describe-function fn)
+ (select-window (get-buffer-window (help-buffer))))
+
+(defun transient--show-manual (manual)
+ (info manual))
+
(defun transient--show-manpage (manpage &optional argument)
(require 'man)
(let* ((Man-notify-method 'meek)
@@ -3282,10 +3360,6 @@ location."
(when argument
(transient--goto-argument-description argument))))
-(defun transient--describe-function (fn)
- (describe-function fn)
- (select-window (get-buffer-window (help-buffer))))
-
(defun transient--goto-argument-description (arg)
(goto-char (point-min))
(let ((case-fold-search nil)
@@ -3366,9 +3440,9 @@ Suffixes on levels %s and %s are unavailable.\n"
(defvar transient-resume-mode-map
(let ((map (make-sparse-keymap)))
- (define-key map [remap Man-quit] 'transient-resume)
- (define-key map [remap Info-exit] 'transient-resume)
- (define-key map [remap quit-window] 'transient-resume)
+ (define-key map [remap Man-quit] #'transient-resume)
+ (define-key map [remap Info-exit] #'transient-resume)
+ (define-key map [remap quit-window] #'transient-resume)
map)
"Keymap for `transient-resume-mode'.
@@ -3395,19 +3469,20 @@ resumes the suspended transient.")
;; Yes, I know that this is wrong(tm).
;; Unfortunately it is also necessary.
(setq this-original-command command)
+ (transient--pre-command)
(call-interactively command))))
(defvar transient-popup-navigation-map
(let ((map (make-sparse-keymap)))
- (define-key map (kbd "<down-mouse-1>") 'transient-noop)
- (define-key map (kbd "<mouse-1>") 'transient-mouse-push-button)
- (define-key map (kbd "RET") 'transient-push-button)
- (define-key map (kbd "<up>") 'transient-backward-button)
- (define-key map (kbd "C-p") 'transient-backward-button)
- (define-key map (kbd "<down>") 'transient-forward-button)
- (define-key map (kbd "C-n") 'transient-forward-button)
- (define-key map (kbd "C-r") 'transient-isearch-backward)
- (define-key map (kbd "C-s") 'transient-isearch-forward)
+ (define-key map (kbd "<down-mouse-1>") #'transient-noop)
+ (define-key map (kbd "<mouse-1>") #'transient-mouse-push-button)
+ (define-key map (kbd "RET") #'transient-push-button)
+ (define-key map (kbd "<up>") #'transient-backward-button)
+ (define-key map (kbd "C-p") #'transient-backward-button)
+ (define-key map (kbd "<down>") #'transient-forward-button)
+ (define-key map (kbd "C-n") #'transient-forward-button)
+ (define-key map (kbd "C-r") #'transient-isearch-backward)
+ (define-key map (kbd "C-s") #'transient-isearch-forward)
map))
(defun transient-mouse-push-button (&optional pos)
@@ -3436,22 +3511,32 @@ See `forward-button' for information about N."
(forward-button n t)))
(defun transient--goto-button (command)
- (if (not command)
- (forward-button 1)
+ (cond
+ ((stringp command)
+ (when (re-search-forward (concat "^" (regexp-quote command)) nil t)
+ (goto-char (match-beginning 0))))
+ (command
(while (and (ignore-errors (forward-button 1))
(not (eq (button-get (button-at (point)) 'command) command))))
(unless (eq (button-get (button-at (point)) 'command) command)
(goto-char (point-min))
- (forward-button 1))))
+ (forward-button 1)))))
+
+(defun transient--heading-at-point ()
+ (and (eq (get-text-property (point) 'face) 'transient-heading)
+ (let ((beg (line-beginning-position)))
+ (buffer-substring-no-properties
+ beg (next-single-property-change
+ beg 'face nil (line-end-position))))))
;;;; Popup Isearch
(defvar transient--isearch-mode-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map isearch-mode-map)
- (define-key map [remap isearch-exit] 'transient-isearch-exit)
- (define-key map [remap isearch-cancel] 'transient-isearch-cancel)
- (define-key map [remap isearch-abort] 'transient-isearch-abort)
+ (define-key map [remap isearch-exit] #'transient-isearch-exit)
+ (define-key map [remap isearch-cancel] #'transient-isearch-cancel)
+ (define-key map [remap isearch-abort] #'transient-isearch-abort)
map))
(defun transient-isearch-backward (&optional regexp-p)
@@ -3537,14 +3622,14 @@ search instead."
(funcall fn arg-mode)
(transient--resume-override t)))
-(advice-add 'edebug--recursive-edit :around 'transient--edebug--recursive-edit)
+(advice-add 'edebug--recursive-edit :around #'transient--edebug--recursive-edit)
(defun transient--abort-edebug ()
(when (bound-and-true-p edebug-active)
(transient--emergency-exit)))
-(advice-add 'abort-recursive-edit :before 'transient--abort-edebug)
-(advice-add 'top-level :before 'transient--abort-edebug)
+(advice-add 'abort-recursive-edit :before #'transient--abort-edebug)
+(advice-add 'top-level :before #'transient--abort-edebug)
(defun transient--edebug-command-p ()
(and (bound-and-true-p edebug-active)
@@ -3558,12 +3643,12 @@ search instead."
(defun transient--suspend-which-key-mode ()
(when (bound-and-true-p which-key-mode)
(which-key-mode -1)
- (add-hook 'transient-exit-hook 'transient--resume-which-key-mode)))
+ (add-hook 'transient-exit-hook #'transient--resume-which-key-mode)))
(defun transient--resume-which-key-mode ()
(unless transient--prefix
(which-key-mode 1)
- (remove-hook 'transient-exit-hook 'transient--resume-which-key-mode)))
+ (remove-hook 'transient-exit-hook #'transient--resume-which-key-mode)))
(defun transient-bind-q-to-quit ()
"Modify some keymaps to bind \"q\" to the appropriate quit command.
@@ -3583,10 +3668,10 @@ that does that. Of course \"Q\" may already be bound to something
else, so that function binds \"M-q\" to that command instead.
Of course \"M-q\" may already be bound to something else, but
we stop there."
- (define-key transient-base-map "q" 'transient-quit-one)
- (define-key transient-sticky-map "q" 'transient-quit-seq)
+ (define-key transient-base-map "q" #'transient-quit-one)
+ (define-key transient-sticky-map "q" #'transient-quit-seq)
(setq transient-substitute-key-function
- 'transient-rebind-quit-commands))
+ #'transient-rebind-quit-commands))
(defun transient-rebind-quit-commands (obj)
"See `transient-bind-q-to-quit'."
@@ -3672,5 +3757,6 @@ we stop there."
(provide 'transient)
;; Local Variables:
;; indent-tabs-mode: nil
+;; checkdoc-symbol-words: ("command-line" "edit-mode" "help-mode")
;; End:
;;; transient.el ends here
diff --git a/lisp/tree-widget.el b/lisp/tree-widget.el
index d40a628b994..8691f03f86d 100644
--- a/lisp/tree-widget.el
+++ b/lisp/tree-widget.el
@@ -214,8 +214,8 @@ Give the image the specified properties PROPS."
See also the option `widget-image-conversion'."
(delq nil
(mapcar
- #'(lambda (fmt)
- (and (image-type-available-p (car fmt)) fmt))
+ (lambda (fmt)
+ (and (image-type-available-p (car fmt)) fmt))
widget-image-conversion)))
;; Buffer local cache of theme data.
diff --git a/lisp/tutorial.el b/lisp/tutorial.el
index 186bf35fe7e..bf985280d80 100644
--- a/lisp/tutorial.el
+++ b/lisp/tutorial.el
@@ -423,11 +423,9 @@ where
;; Handle prefix definitions specially
;; so that a mode that rebinds some subcommands
;; won't make it appear that the whole prefix is gone.
- (key-fun (if (eq def-fun 'ESC-prefix)
- (lookup-key global-map [27])
- (if (eq def-fun 'Control-X-prefix)
- (lookup-key global-map [24])
- (key-binding key))))
+ (key-fun (if (keymapp def-fun)
+ (lookup-key global-map key)
+ (key-binding key)))
(where (where-is-internal (if rem-fun rem-fun def-fun)))
cwhere)
diff --git a/lisp/url/url-auth.el b/lisp/url/url-auth.el
index 06cfacc99d6..2d9a7758f13 100644
--- a/lisp/url/url-auth.el
+++ b/lisp/url/url-auth.el
@@ -19,6 +19,8 @@
;; 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 'url-vars)
@@ -458,8 +460,7 @@ information associated with them.")
;;;###autoload
(defun url-get-authentication (url realm type prompt &optional args)
- "Return an authorization string suitable for use in the WWW-Authenticate
-header in an HTTP/1.0 request.
+ "Return authorization string for the WWW-Authenticate header in HTTP/1.0 request.
URL is the url you are requesting authorization to. This can be either a
string representing the URL, or the parsed representation returned by
diff --git a/lisp/url/url-cache.el b/lisp/url/url-cache.el
index 830e6ba9dcc..f869d2e2cf1 100644
--- a/lisp/url/url-cache.el
+++ b/lisp/url/url-cache.el
@@ -19,6 +19,8 @@
;; 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 'url-parse)
@@ -47,7 +49,7 @@ Used by the function `url-cache-expired'."
(file-directory-p (file-name-directory file)))))
(defun url-cache-prepare (file)
- "Makes it possible to cache data in FILE.
+ "Make it possible to cache data in FILE.
Creates any necessary parent directories, deleting any non-directory files
that would stop this. Returns nil if parent directories can not be
created. If FILE already exists as a non-directory, it changes
diff --git a/lisp/url/url-cid.el b/lisp/url/url-cid.el
index 0ca2d8a0737..3095f7bd2c1 100644
--- a/lisp/url/url-cid.el
+++ b/lisp/url/url-cid.el
@@ -19,6 +19,8 @@
;; 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 'url-vars)
diff --git a/lisp/url/url-dired.el b/lisp/url/url-dired.el
index 398113db139..feb7c50ce53 100644
--- a/lisp/url/url-dired.el
+++ b/lisp/url/url-dired.el
@@ -19,6 +19,8 @@
;; 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:
(autoload 'dired-get-filename "dired")
diff --git a/lisp/url/url-expand.el b/lisp/url/url-expand.el
index 05088e3cac8..4e737e965dd 100644
--- a/lisp/url/url-expand.el
+++ b/lisp/url/url-expand.el
@@ -19,6 +19,8 @@
;; 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 'url-methods)
diff --git a/lisp/url/url-gw.el b/lisp/url/url-gw.el
index d2bf843fc36..caffa6fb7bd 100644
--- a/lisp/url/url-gw.el
+++ b/lisp/url/url-gw.el
@@ -21,6 +21,8 @@
;; 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 'url-vars)
diff --git a/lisp/url/url-handlers.el b/lisp/url/url-handlers.el
index ed0402a5137..650c610e04c 100644
--- a/lisp/url/url-handlers.el
+++ b/lisp/url/url-handlers.el
@@ -102,6 +102,7 @@
;;;###autoload
(define-minor-mode url-handler-mode
+ ;; Can't use "\\[find-file]" below as it produces "[open]":
"Handle URLs as if they were file names throughout Emacs.
After switching on this minor mode, Emacs file primitives handle
URLs. For instance:
diff --git a/lisp/url/url-http.el b/lisp/url/url-http.el
index ba13a17a8fc..44ebedeeaef 100644
--- a/lisp/url/url-http.el
+++ b/lisp/url/url-http.el
@@ -225,7 +225,7 @@ request.")
(os-info (unless (and (listp url-privacy-level)
(memq 'os url-privacy-level))
(format "(%s; %s)" url-system-type url-os-type)))
- (url-info (format "URL/Emacs")))
+ (url-info "URL/Emacs"))
(string-join (delq nil (list package-info url-info
emacs-info os-info))
" ")))
@@ -462,53 +462,53 @@ Return the number of characters removed."
;; credentials to the server, and they were wrong, so just give
;; up.
(let ((authorization (assoc "Authorization" url-http-extra-headers)))
- (when (and authorization
- (not (string-match "^NTLM " (cdr authorization))))
- (error "Wrong authorization used for %s" url)))
-
- ;; find strongest supported auth
- (dolist (this-auth auths)
- (setq this-auth (url-eat-trailing-space
- (url-strip-leading-spaces
- this-auth)))
- (let* ((this-type
- (downcase (if (string-match "[ \t]" this-auth)
- (substring this-auth 0 (match-beginning 0))
- this-auth)))
- (registered (url-auth-registered this-type))
- (this-strength (cddr registered)))
- (when (and registered (> this-strength strength))
- (setq auth this-auth
- type this-type
- strength this-strength))))
-
- (if (not (url-auth-registered type))
- (progn
- (widen)
- (goto-char (point-max))
- (insert "<hr>Sorry, but I do not know how to handle " (or type auth url "")
- " authentication. If you'd like to write it,"
- " please use M-x report-emacs-bug RET.<hr>")
- ;; We used to set a `status' var (declared "special") but I can't
- ;; find the corresponding let-binding, so it's probably an error.
- ;; FIXME: Maybe it was supposed to set `success', i.e. to return t?
- ;; (setq status t)
- nil) ;; Not success yet.
-
- (let* ((args (url-parse-args (subst-char-in-string ?, ?\; auth)))
- (auth (url-get-authentication auth-url
- (cdr-safe (assoc "realm" args))
- type t args)))
- (if (not auth)
- t ;Success.
- (push (cons (if proxy "Proxy-Authorization" "Authorization") auth)
- url-http-extra-headers)
- (let ((url-request-method url-http-method)
- (url-request-data url-http-data)
- (url-request-extra-headers url-http-extra-headers))
- (url-retrieve-internal url url-callback-function
- url-callback-arguments))
- nil))))) ;; Not success yet.
+ (if (and authorization
+ (not (string-match "^NTLM " (cdr authorization)))) ;Bug#43566
+ t ;; Instruct caller to signal an error. Bug#50511
+ ;; Find strongest supported auth.
+ (dolist (this-auth auths)
+ (setq this-auth (url-eat-trailing-space
+ (url-strip-leading-spaces
+ this-auth)))
+ (let* ((this-type
+ (downcase (if (string-match "[ \t]" this-auth)
+ (substring this-auth 0 (match-beginning 0))
+ this-auth)))
+ (registered (url-auth-registered this-type))
+ (this-strength (cddr registered)))
+ (when (and registered (> this-strength strength))
+ (setq auth this-auth
+ type this-type
+ strength this-strength))))
+
+ (if (not (url-auth-registered type))
+ (progn
+ (widen)
+ (goto-char (point-max))
+ (insert "<hr>Sorry, but I do not know how to handle "
+ (or type auth url "")
+ " authentication. If you'd like to write it,"
+ " please use M-x report-emacs-bug RET.<hr>")
+ ;; We used to set a `status' var (declared "special") but I can't
+ ;; find the corresponding let-binding, so it's probably an error.
+ ;; FIXME: Maybe it was supposed to set `success', i.e. to return t?
+ ;; (setq status t)
+ nil) ;; Not success yet.
+
+ (let* ((args (url-parse-args (subst-char-in-string ?, ?\; auth)))
+ (auth (url-get-authentication auth-url
+ (cdr-safe (assoc "realm" args))
+ type t args)))
+ (if (not auth)
+ t ;Success.
+ (push (cons (if proxy "Proxy-Authorization" "Authorization") auth)
+ url-http-extra-headers)
+ (let ((url-request-method url-http-method)
+ (url-request-data url-http-data)
+ (url-request-extra-headers url-http-extra-headers))
+ (url-retrieve-internal url url-callback-function
+ url-callback-arguments))
+ nil))))))) ;; Not success yet.
(defun url-http-parse-response ()
"Parse just the response code."
@@ -1451,8 +1451,8 @@ The return value of this function is the retrieval buffer."
(error "gnutls-error: %s" e))
(error
(url-http-activate-callback)
- (error "error: %s" e)))
- (error "error: gnutls support needed!")))
+ (error "Error: %s" e)))
+ (error "Error: gnutls support needed!")))
(t
(url-http-debug "error response: %d" url-http-response-status)
(url-http-activate-callback))))))
diff --git a/lisp/url/url-imap.el b/lisp/url/url-imap.el
index 492907f33ff..f2e9b4c4a1f 100644
--- a/lisp/url/url-imap.el
+++ b/lisp/url/url-imap.el
@@ -22,8 +22,8 @@
;;; Commentary:
-;; Anyway, here's a teaser. It's quite broken in lots of regards, but at
-;; least it seem to work. At least a little. At least when called
+;; Anyway, here's a teaser. It's quite broken in lots of regards, but at
+;; least it seem to work. At least a little. At least when called
;; manually like this (I've no idea how it's supposed to be called):
;; (url-imap (url-generic-parse-url "imap://cyrus.andrew.cmu.edu/archive.c-client;UID=1021"))
diff --git a/lisp/url/url-ldap.el b/lisp/url/url-ldap.el
index d26562b7f10..5d18f85fadf 100644
--- a/lisp/url/url-ldap.el
+++ b/lisp/url/url-ldap.el
@@ -218,7 +218,7 @@ URL can be a URL string, or a URL record of the type returned by
"</td></tr>\n")
;; Multiple matches, slightly uglier
(insert " <tr>\n"
- (format " <td valign=top>")
+ " <td valign=top>"
(url-ldap-attribute-pretty-name (car attr)) "</td><td>"
(mapconcat (lambda (x)
(url-ldap-attribute-pretty-desc (car attr) x))
diff --git a/lisp/url/url-misc.el b/lisp/url/url-misc.el
index fe2393beb64..c741b6c85a3 100644
--- a/lisp/url/url-misc.el
+++ b/lisp/url/url-misc.el
@@ -20,6 +20,8 @@
;; 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 'url-vars)
diff --git a/lisp/url/url-news.el b/lisp/url/url-news.el
index 4fe909cadbc..c9216862b0f 100644
--- a/lisp/url/url-news.el
+++ b/lisp/url/url-news.el
@@ -19,6 +19,8 @@
;; 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 'url-vars)
diff --git a/lisp/url/url-privacy.el b/lisp/url/url-privacy.el
index d926775c48d..ebba87ebbb5 100644
--- a/lisp/url/url-privacy.el
+++ b/lisp/url/url-privacy.el
@@ -19,6 +19,8 @@
;; 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 'url-vars)
@@ -46,6 +48,7 @@
(pcase (or window-system 'tty)
('x "X11")
('ns "OpenStep")
+ ('pgtk "PureGTK")
('tty "TTY")
(_ nil)))))
diff --git a/lisp/url/url-proxy.el b/lisp/url/url-proxy.el
index c89c1b6bc3e..0ffe51616db 100644
--- a/lisp/url/url-proxy.el
+++ b/lisp/url/url-proxy.el
@@ -19,6 +19,8 @@
;; 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 'url-parse)
diff --git a/lisp/url/url-tramp.el b/lisp/url/url-tramp.el
index 5b9dd8a2682..5cf0d804d62 100644
--- a/lisp/url/url-tramp.el
+++ b/lisp/url/url-tramp.el
@@ -48,12 +48,14 @@ In case URL is not convertible, nil is returned."
(when (url-password obj)
(password-cache-add
(tramp-make-tramp-file-name
- (url-type obj) (url-user obj) nil
- (url-host obj) port "")
+ (make-tramp-file-name
+ :method (url-type obj) :user (url-user obj)
+ :host (url-host obj)))
(url-password obj)))
(tramp-make-tramp-file-name
- (url-type obj) (url-user obj) nil
- (url-host obj) port (url-filename obj)))))
+ (make-tramp-file-name
+ :method (url-type obj) :user (url-user obj)
+ :host (url-host obj) :port port :localname (url-filename obj))))))
(defun url-tramp-convert-tramp-to-url (file)
"Convert FILE, a Tramp file name, to a URL.
diff --git a/lisp/url/url-util.el b/lisp/url/url-util.el
index 113ac2833bc..7ffccfd3a0b 100644
--- a/lisp/url/url-util.el
+++ b/lisp/url/url-util.el
@@ -282,7 +282,7 @@ Given a QUERY in the form:
\(This is the same format as produced by `url-parse-query-string')
This will return a string
-\"key1=val1&key2=val2&key3=val1&key3=val2&key4&key5\". Keys may
+\"key1=val1&key2=val2&key3=val1&key3=val2&key4&key5\". Keys may
be strings or symbols; if they are symbols, the symbol name will
be used.
diff --git a/lisp/url/url-vars.el b/lisp/url/url-vars.el
index 2aa2e7912f5..d916a71e41b 100644
--- a/lisp/url/url-vars.el
+++ b/lisp/url/url-vars.el
@@ -20,6 +20,8 @@
;; 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:
(defgroup url nil
@@ -158,8 +160,7 @@ none -- Always send last location.
domain-match -- Send last location if the new location is within the
same domain
host-match -- Send last location if the new location is on the
- same host
-"
+ same host"
:version "27.1"
:type '(radio (const :tag "Always send" none)
(const :tag "Domains match" domain-match)
diff --git a/lisp/userlock.el b/lisp/userlock.el
index 38aaf6aec23..9a2d45a8468 100644
--- a/lisp/userlock.el
+++ b/lisp/userlock.el
@@ -39,10 +39,6 @@
(define-error 'file-locked "File is locked" 'file-error)
-(defun userlock--fontify-key (key)
- "Add the `help-key-binding' face to string KEY."
- (propertize key 'face 'help-key-binding))
-
;;;###autoload
(defun ask-user-about-lock (file opponent)
"Ask user what to do when he wants to edit FILE but it is locked by OPPONENT.
@@ -68,12 +64,9 @@ in any way you like."
(match-string 0 opponent)))
opponent))
(while (null answer)
- (message "%s locked by %s: (%s, %s, %s, %s)? "
- short-file short-opponent
- (userlock--fontify-key "s")
- (userlock--fontify-key "q")
- (userlock--fontify-key "p")
- (userlock--fontify-key "?"))
+ (message (substitute-command-keys
+ "%s locked by %s: (\\`s', \\`q', \\`p', \\`?'? ")
+ short-file short-opponent)
(if noninteractive (error "Cannot resolve lock conflict in batch mode"))
(let ((tem (let ((inhibit-quit t)
(cursor-in-echo-area t))
@@ -88,12 +81,9 @@ in any way you like."
(?? . help))))
(cond ((null answer)
(beep)
- (message "Please type %s, %s, or %s; or %s for help"
- (userlock--fontify-key "q")
- (userlock--fontify-key "s")
- (userlock--fontify-key "p")
- ;; FIXME: Why do we use "?" here and "C-h" below?
- (userlock--fontify-key "?"))
+ ;; FIXME: Why do we use "?" here and "C-h" below?
+ (message (substitute-command-keys
+ "Please type \\`q', \\`s', or \\`p'; or \\`?' for help"))
(sit-for 3))
((eq (cdr answer) 'help)
(ask-user-about-lock-help)
@@ -106,17 +96,14 @@ in any way you like."
(with-output-to-temp-buffer "*Help*"
(with-current-buffer standard-output
(insert
- (format
+ (substitute-command-keys
"It has been detected that you want to modify a file that someone else has
already started modifying in Emacs.
-You can <%s>teal the file; the other user becomes the
+You can <\\`s'>teal the file; the other user becomes the
intruder if (s)he ever unmodifies the file and then changes it again.
-You can <%s>roceed; you edit at your own (and the other user's) risk.
-You can <%s>uit; don't modify this file."
- (userlock--fontify-key "s")
- (userlock--fontify-key "p")
- (userlock--fontify-key "q")))
+You can <\\`p'>roceed; you edit at your own (and the other user's) risk.
+You can <\\`q'>uit; don't modify this file."))
(help-mode))))
(define-error 'file-supersession nil 'file-error)
@@ -125,7 +112,8 @@ You can <%s>uit; don't modify this file."
(with-demoted-errors "Unchanged content check: %S"
;; Even tho we receive `filename', we know that `filename' refers to the current
;; buffer's file.
- (cl-assert (equal filename (expand-file-name buffer-file-truename)))
+ (cl-assert (equal (expand-file-name filename)
+ (expand-file-name buffer-file-truename)))
;; Note: rather than read the file and compare to the buffer, we could save
;; the buffer and compare to the file, but for encrypted data this
;; wouldn't work well (and would risk exposing the data).
@@ -168,14 +156,11 @@ The buffer in question is current when this function is called."
(discard-input)
(save-window-excursion
(let ((prompt
- (format "%s changed on disk; \
-really edit the buffer? (%s, %s, %s or %s) "
- (file-name-nondirectory filename)
- (userlock--fontify-key "y")
- (userlock--fontify-key "n")
- (userlock--fontify-key "r")
- ;; FIXME: Why do we use "C-h" here and "?" above?
- (userlock--fontify-key "C-h")))
+ ;; FIXME: Why do we use "C-h" here and "?" above?
+ (format (substitute-command-keys
+ "%s changed on disk; \
+really edit the buffer? (\\`y', \\`n', \\`r' or \\`C-h') ")
+ (file-name-nondirectory filename)))
(choices '(?y ?n ?r ?? ?\C-h))
answer)
(when noninteractive
@@ -193,36 +178,30 @@ really edit the buffer? (%s, %s, %s or %s) "
(list "File reverted" filename)))
((eq answer ?n)
(signal 'file-supersession
- (list "File changed on disk" filename)))))
+ (list "File changed on disk" filename)))
+ ((eq answer ?y))
+ (t (setq answer nil))))
(message
"File on disk now will become a backup file if you save these changes.")
(setq buffer-backed-up nil))))
(defun ask-user-about-supersession-help ()
(with-output-to-temp-buffer "*Help*"
- (let ((revert-buffer-binding
- ;; This takes place in the original buffer.
- (substitute-command-keys "\\[revert-buffer]")))
- (with-current-buffer standard-output
- (insert
- (format
- "You want to modify a buffer whose disk file has changed
+ (with-current-buffer standard-output
+ (insert
+ (substitute-command-keys
+ "You want to modify a buffer whose disk file has changed
since you last read it in or saved it with this buffer.
-If you say %s to go ahead and modify this buffer,
+If you say \\`y' to go ahead and modify this buffer,
you risk ruining the work of whoever rewrote the file.
-If you say %s to revert, the contents of the buffer are refreshed
+If you say \\`r' to revert, the contents of the buffer are refreshed
from the file on disk.
-If you say %s, the change you started to make will be aborted.
-
-Usually, you should type %s and then %s,
-to get the latest version of the file, then make the change again."
- (userlock--fontify-key "y")
- (userlock--fontify-key "r")
- (userlock--fontify-key "n")
- (userlock--fontify-key "n")
- revert-buffer-binding))
- (help-mode)))))
+If you say \\`n', the change you started to make will be aborted.
+
+Usually, you should type \\`r' to get the latest version of the
+file, then make the change again."))
+ (help-mode))))
;;;###autoload
(defun userlock--handle-unlock-error (error)
diff --git a/lisp/vc/add-log.el b/lisp/vc/add-log.el
index 2e20284951f..1290d7e03a5 100644
--- a/lisp/vc/add-log.el
+++ b/lisp/vc/add-log.el
@@ -930,8 +930,7 @@ non-nil, otherwise in local time."
(not (looking-at "[ \t]+.*<.*>$")))
(setq hit t)))))
(forward-line 1)
- (insert (nth (random (length new-entries))
- new-entries)
+ (insert (and new-entries (seq-random-elt new-entries))
(if use-hard-newlines hard-newline "\n")
(if use-hard-newlines hard-newline "\n"))
(forward-line -1))))
diff --git a/lisp/vc/compare-w.el b/lisp/vc/compare-w.el
index 4c1d9eaad55..29dfaa7668d 100644
--- a/lisp/vc/compare-w.el
+++ b/lisp/vc/compare-w.el
@@ -113,7 +113,7 @@ and the value `((4) (4))' for horizontally split windows."
:version "22.1")
(defcustom compare-windows-highlight t
- "Non-nil means compare-windows highlights the differences.
+ "Non-nil means `compare-windows' highlights the differences.
The value t removes highlighting immediately after invoking a command
other than `compare-windows'.
The value `persistent' leaves all highlighted differences. You can clear
@@ -188,7 +188,7 @@ If both windows display the same buffer,
the mark is pushed twice in that buffer:
first in the other window, then in the selected window.
-A prefix arg means reverse the value of variable
+A prefix arg IGNORE-WHITESPACE, means reverse the value of variable
`compare-ignore-whitespace'. If `compare-ignore-whitespace' is
nil, then a prefix arg means ignore changes in whitespace. If
`compare-ignore-whitespace' is non-nil, then a prefix arg means
diff --git a/lisp/vc/cvs-status.el b/lisp/vc/cvs-status.el
index 63b886362ba..7886cc1eae2 100644
--- a/lisp/vc/cvs-status.el
+++ b/lisp/vc/cvs-status.el
@@ -29,23 +29,22 @@
;;; Code:
(require 'cl-lib)
-(require 'pcvs-util)
+(require 'pcvs)
+(require 'easy-mmode)
;;;
-(easy-mmode-defmap cvs-status-mode-map
- '(("n" . next-line)
- ("p" . previous-line)
- ("N" . cvs-status-next)
- ("P" . cvs-status-prev)
- ("\M-n" . cvs-status-next)
- ("\M-p" . cvs-status-prev)
- ("t" . cvs-status-cvstrees)
- ("T" . cvs-status-trees)
- (">" . cvs-mode-checkout))
- "CVS-Status' keymap."
- :group 'cvs-status
- :inherit 'cvs-mode-map)
+(defvar-keymap cvs-status-mode-map
+ :parent 'cvs-mode-map
+ "n" #'next-line
+ "p" #'previous-line
+ "N" #'cvs-status-next
+ "P" #'cvs-status-prev
+ "M-n" #'cvs-status-next
+ "M-p" #'cvs-status-prev
+ "t" #'cvs-status-cvstrees
+ "T" #'cvs-status-trees
+ ">" #'cvs-mode-checkout)
;;(easy-menu-define cvs-status-menu cvs-status-mode-map
;; "Menu for `cvs-status-mode'."
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index eeb32f8fe50..8f83aa580e4 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -55,6 +55,7 @@
;;; Code:
(eval-when-compile (require 'cl-lib))
(eval-when-compile (require 'subr-x))
+(require 'easy-mmode)
(autoload 'vc-find-revision "vc")
(autoload 'vc-find-revision-no-save "vc")
@@ -162,57 +163,55 @@ and hunk-based syntax highlighting otherwise as a fallback."
;;;; keymap, menu, ...
;;;;
-(easy-mmode-defmap diff-mode-shared-map
- '(("n" . diff-hunk-next)
- ("N" . diff-file-next)
- ("p" . diff-hunk-prev)
- ("P" . diff-file-prev)
- ("\t" . diff-hunk-next)
- ([backtab] . diff-hunk-prev)
- ("k" . diff-hunk-kill)
- ("K" . diff-file-kill)
- ("}" . diff-file-next) ; From compilation-minor-mode.
- ("{" . diff-file-prev)
- ("\C-m" . diff-goto-source)
- ([mouse-2] . diff-goto-source)
- ("W" . widen)
- ("o" . diff-goto-source) ; other-window
- ("A" . diff-ediff-patch)
- ("r" . diff-restrict-view)
- ("R" . diff-reverse-direction)
- ([remap undo] . diff-undo))
- "Basic keymap for `diff-mode', bound to various prefix keys."
- :inherit special-mode-map)
-
-(easy-mmode-defmap diff-mode-map
- `(("\e" . ,(let ((map (make-sparse-keymap)))
- ;; We want to inherit most bindings from diff-mode-shared-map,
- ;; but not all since they may hide useful M-<foo> global
- ;; bindings when editing.
- (set-keymap-parent map diff-mode-shared-map)
- (dolist (key '("A" "r" "R" "g" "q" "W" "z"))
- (define-key map key nil))
- map))
- ;; From compilation-minor-mode.
- ("\C-c\C-c" . diff-goto-source)
- ;; By analogy with the global C-x 4 a binding.
- ("\C-x4A" . diff-add-change-log-entries-other-window)
- ;; Misc operations.
- ("\C-c\C-a" . diff-apply-hunk)
- ("\C-c\C-e" . diff-ediff-patch)
- ("\C-c\C-n" . diff-restrict-view)
- ("\C-c\C-s" . diff-split-hunk)
- ("\C-c\C-t" . diff-test-hunk)
- ("\C-c\C-r" . diff-reverse-direction)
- ("\C-c\C-u" . diff-context->unified)
- ;; `d' because it duplicates the context :-( --Stef
- ("\C-c\C-d" . diff-unified->context)
- ("\C-c\C-w" . diff-ignore-whitespace-hunk)
- ;; `l' because it "refreshes" the hunk like C-l refreshes the screen
- ("\C-c\C-l" . diff-refresh-hunk)
- ("\C-c\C-b" . diff-refine-hunk) ;No reason for `b' :-(
- ("\C-c\C-f" . next-error-follow-minor-mode))
- "Keymap for `diff-mode'. See also `diff-mode-shared-map'.")
+(defvar-keymap diff-mode-shared-map
+ :parent special-mode-map
+ "n" #'diff-hunk-next
+ "N" #'diff-file-next
+ "p" #'diff-hunk-prev
+ "P" #'diff-file-prev
+ "TAB" #'diff-hunk-next
+ "<backtab>" #'diff-hunk-prev
+ "k" #'diff-hunk-kill
+ "K" #'diff-file-kill
+ "}" #'diff-file-next ; From compilation-minor-mode.
+ "{" #'diff-file-prev
+ "RET" #'diff-goto-source
+ "<mouse-2>" #'diff-goto-source
+ "W" #'widen
+ "o" #'diff-goto-source ; other-window
+ "A" #'diff-ediff-patch
+ "r" #'diff-restrict-view
+ "R" #'diff-reverse-direction
+ "<remap> <undo>" #'diff-undo)
+
+(defvar-keymap diff-mode-map
+ :doc "Keymap for `diff-mode'. See also `diff-mode-shared-map'."
+ "ESC" (let ((map (define-keymap :parent diff-mode-shared-map)))
+ ;; We want to inherit most bindings from
+ ;; `diff-mode-shared-map', but not all since they may hide
+ ;; useful `M-<foo>' global bindings when editing.
+ (dolist (key '("A" "r" "R" "g" "q" "W" "z"))
+ (keymap-set map key nil))
+ map)
+ ;; From compilation-minor-mode.
+ "C-c C-c" #'diff-goto-source
+ ;; By analogy with the global C-x 4 a binding.
+ "C-x 4 A" #'diff-add-change-log-entries-other-window
+ ;; Misc operations.
+ "C-c C-a" #'diff-apply-hunk
+ "C-c C-e" #'diff-ediff-patch
+ "C-c C-n" #'diff-restrict-view
+ "C-c C-s" #'diff-split-hunk
+ "C-c C-t" #'diff-test-hunk
+ "C-c C-r" #'diff-reverse-direction
+ "C-c C-u" #'diff-context->unified
+ ;; `d' because it duplicates the context :-( --Stef
+ "C-c C-d" #'diff-unified->context
+ "C-c C-w" #'diff-ignore-whitespace-hunk
+ ;; `l' because it "refreshes" the hunk like C-l refreshes the screen
+ "C-c C-l" #'diff-refresh-hunk
+ "C-c C-b" #'diff-refine-hunk ;No reason for `b' :-(
+ "C-c C-f" #'next-error-follow-minor-mode)
(easy-menu-define diff-mode-menu diff-mode-map
"Menu for `diff-mode'."
@@ -267,11 +266,12 @@ and hunk-based syntax highlighting otherwise as a fallback."
(defcustom diff-minor-mode-prefix "\C-c="
"Prefix key for `diff-minor-mode' commands."
- :type '(choice (string "\e") (string "C-c=") string))
+ :type '(choice (string "ESC")
+ (string "\C-c=") string))
-(easy-mmode-defmap diff-minor-mode-map
- `((,diff-minor-mode-prefix . ,diff-mode-shared-map))
- "Keymap for `diff-minor-mode'. See also `diff-mode-shared-map'.")
+(defvar-keymap diff-minor-mode-map
+ :doc "Keymap for `diff-minor-mode'. See also `diff-mode-shared-map'."
+ (key-description diff-minor-mode-prefix) diff-mode-shared-map)
(define-minor-mode diff-auto-refine-mode
"Toggle automatic diff hunk finer highlighting (Diff Auto Refine mode).
@@ -894,6 +894,9 @@ data such as \"Index: ...\" and such."
;; Fix the original hunk-header.
(diff-fixup-modifs start pos))))
+(defun diff--outline-level ()
+ (if (string-match-p diff-hunk-header-re (match-string 0))
+ 2 1))
;;;;
;;;; jump to other buffers
@@ -1355,7 +1358,11 @@ else cover the whole buffer."
(pcase (char-after)
(?\s (cl-incf space))
(?+ (cl-incf plus))
- (?- (cl-incf minus))
+ (?- (unless ;; In git format-patch "^-- $" signifies
+ ;; the end of the patch.
+ (and (eq diff-buffer-type 'git)
+ (looking-at "^-- $"))
+ (cl-incf minus)))
(?! (cl-incf bang))
((or ?\\ ?#) nil)
(?\n (if diff-valid-unified-empty-line
@@ -1479,7 +1486,7 @@ Supports unified and context diffs as well as (to a lesser extent)
normal diffs.
When the buffer is read-only, the ESC prefix is not necessary.
-If you edit the buffer manually, diff-mode will try to update the hunk
+If you edit the buffer manually, `diff-mode' will try to update the hunk
headers for you on-the-fly.
You can also switch between context diff and unified diff with \\[diff-context->unified],
@@ -1490,7 +1497,6 @@ a diff with \\[diff-reverse-direction].
(setq-local font-lock-defaults diff-font-lock-defaults)
(add-hook 'font-lock-mode-hook #'diff--font-lock-cleanup nil 'local)
- (setq-local outline-regexp diff-outline-regexp)
(setq-local imenu-generic-expression
diff-imenu-generic-expression)
;; These are not perfect. They would be better done separately for
@@ -1535,11 +1541,7 @@ a diff with \\[diff-reverse-direction].
#'diff--filter-substring)
(unless buffer-file-name
(hack-dir-local-variables-non-file-buffer))
- (save-excursion
- (setq-local diff-buffer-type
- (if (re-search-forward "^diff --git" nil t)
- 'git
- nil))))
+ (diff-setup-buffer-type))
;;;###autoload
(define-minor-mode diff-minor-mode
@@ -1575,6 +1577,21 @@ modified lines of the diff."
"^[-+!] .*?\\([\t ]+\\)$"
"^[-+!<>].*?\\([\t ]+\\)$"))))
+(defun diff-setup-buffer-type ()
+ "Try to guess the `diff-buffer-type' from content of current Diff mode buffer.
+`outline-regexp' is updated accordingly."
+ (save-excursion
+ (goto-char (point-min))
+ (setq-local diff-buffer-type
+ (if (re-search-forward "^diff --git" nil t)
+ 'git
+ nil)))
+ (when (eq diff-buffer-type 'git)
+ (setq diff-outline-regexp
+ (concat "\\(^diff --git.*\n\\|" diff-hunk-header-re "\\)"))
+ (setq-local outline-level #'diff--outline-level))
+ (setq-local outline-regexp diff-outline-regexp))
+
(defun diff-delete-if-empty ()
;; An empty diff file means there's no more diffs to integrate, so we
;; can just remove the file altogether. Very handy for .rej files if we
@@ -2599,13 +2616,15 @@ fixed, visit it in a buffer."
(or (match-beginning 2) (match-beginning 1))
'display (propertize
(cond
- ((null (match-beginning 1)) "new file ")
- ((null (match-beginning 2)) "deleted ")
- (t "modified "))
+ ((null (match-beginning 1))
+ (concat "new file " (match-string 2)))
+ ((null (match-beginning 2))
+ (concat "deleted " (match-string 1)))
+ (t
+ (concat "modified " (match-string 1))))
'face '(diff-file-header diff-header)))
- (unless (match-beginning 2)
- (put-text-property (match-end 1) (1- (match-end 0))
- 'display "")))))
+ (put-text-property (match-end 1) (1- (match-end 0))
+ 'display ""))))
nil)
;;; Syntax highlighting from font-lock
diff --git a/lisp/vc/diff.el b/lisp/vc/diff.el
index 7bb1151602c..4061fedd578 100644
--- a/lisp/vc/diff.el
+++ b/lisp/vc/diff.el
@@ -87,24 +87,24 @@ minibuffer. The default for NEW is the current buffer's file
name, and the default for OLD is a backup file for NEW, if one
exists. If NO-ASYNC is non-nil, call diff synchronously.
-When called interactively with a prefix argument, prompt
+When called interactively with a prefix argument SWITCHES, prompt
interactively for diff switches. Otherwise, the switches
-specified in the variable `diff-switches' are passed to the
-diff command.
+specified in the variable `diff-switches' are passed to the diff
+command.
Non-interactively, OLD and NEW may each be a file or a buffer."
(interactive
(let* ((newf (if (and buffer-file-name (file-exists-p buffer-file-name))
(read-file-name
- (concat "Diff new file (default "
- (file-name-nondirectory buffer-file-name) "): ")
+ (format-prompt "Diff new file"
+ (file-name-nondirectory buffer-file-name))
nil buffer-file-name t)
(read-file-name "Diff new file: " nil nil t)))
(oldf (file-newest-backup newf)))
(setq oldf (if (and oldf (file-exists-p oldf))
(read-file-name
- (concat "Diff original file (default "
- (file-name-nondirectory oldf) "): ")
+ (format-prompt "Diff original file"
+ (file-name-nondirectory oldf))
(file-name-directory oldf) oldf t)
(read-file-name "Diff original file: "
(file-name-directory newf) nil t)))
@@ -229,7 +229,7 @@ returns the buffer used."
Uses the latest backup, if there are several numerical backups.
If this file is a backup, diff it with its original.
The backup file is the first file given to `diff'.
-With prefix arg, prompt for diff switches."
+With prefix arg SWITCHES, prompt for diff switches."
(interactive (list (read-file-name "Diff (file with backup): ")
(diff-switches)))
(let (bak ori)
@@ -243,7 +243,7 @@ With prefix arg, prompt for diff switches."
;;;###autoload
(defun diff-latest-backup-file (fn)
- "Return the latest existing backup of FILE, or nil."
+ "Return the latest existing backup of file FN, or nil."
(let ((handler (find-file-name-handler fn 'diff-latest-backup-file)))
(if handler
(funcall handler 'diff-latest-backup-file fn)
diff --git a/lisp/vc/ediff-diff.el b/lisp/vc/ediff-diff.el
index 0965e888f06..68abea794f0 100644
--- a/lisp/vc/ediff-diff.el
+++ b/lisp/vc/ediff-diff.el
@@ -24,7 +24,6 @@
;;; Code:
-
(require 'ediff-init)
(require 'ediff-util)
@@ -78,14 +77,14 @@ are `-I REGEXP', to ignore changes whose lines match the REGEXP."
"Options to pass to `ediff-diff-program'.
If Unix diff is used as `ediff-diff-program',
then a useful option is `-w', to ignore space.
-Options `-c', `-u', and `-i' are not allowed. Case sensitivity can be
+Options `-c', `-u', and `-i' are not allowed. Case sensitivity can be
toggled interactively using \\[ediff-toggle-ignore-case].
-Do not remove the default options. If you need to change this variable, add new
+Do not remove the default options. If you need to change this variable, add new
options after the default ones.
This variable is not for customizing the look of the differences produced by
-the command \\[ediff-show-diff-output]. Use the variable
+the command \\[ediff-show-diff-output]. Use the variable
`ediff-custom-diff-options' for that."
:set #'ediff-set-diff-options
:type 'string)
@@ -104,8 +103,8 @@ Use `setq-default' if setting it in .emacs")
GNU diff3 doesn't have such an option."
:type 'string)
-;; the actual options used in comparison
-(ediff-defvar-local ediff-actual-diff-options ediff-diff-options "")
+(ediff-defvar-local ediff-actual-diff-options ediff-diff-options
+ "The actual options used in comparison.")
(defcustom ediff-custom-diff-program ediff-diff-program
"Program to use for generating custom diff output for saving it in a file.
@@ -124,8 +123,8 @@ This output is not used by Ediff internally."
:set 'ediff-set-diff-options
:type 'string)
-;; the actual options used in comparison
-(ediff-defvar-local ediff-actual-diff3-options ediff-diff3-options "")
+(ediff-defvar-local ediff-actual-diff3-options ediff-diff3-options
+ "The actual options used in comparison.")
(defcustom ediff-diff3-ok-lines-regexp
"^\\([1-3]:\\|====\\| \\|.*Warning *:\\|.*No newline\\|.*missing newline\\|^\C-m$\\)"
@@ -133,16 +132,16 @@ This output is not used by Ediff internally."
Lines that do not match are assumed to be error messages."
:type 'regexp)
-;; keeps the status of the current diff in 3-way jobs.
-;; the status can be =diff(A), =diff(B), or =diff(A+B)
-(ediff-defvar-local ediff-diff-status "" "")
+(ediff-defvar-local ediff-diff-status ""
+ "Keeps the status of the current diff in 3-way jobs.
+The status can be =diff(A), =diff(B), or =diff(A+B).")
;;; Fine differences
(ediff-defvar-local ediff-auto-refine (if (ediff-has-face-support-p) 'on 'nix)
"If `on', Ediff auto-highlights fine diffs for the current diff region.
-If `off', auto-highlighting is not used. If `nix', no fine diffs are shown
+If `off', auto-highlighting is not used. If `nix', no fine diffs are shown
at all, unless the user force-refines the region by hitting `*'.
This variable can be set either in .emacs or toggled interactively.
@@ -180,12 +179,12 @@ Lines that do not match are assumed to be error messages.")
"Pattern to match lines produced by diff that describe differences.")
(ediff-defvar-local ediff-setup-diff-regions-function nil
- "value is a function symbol depending on the kind of job is to be done.
-For 2-way jobs and for ediff-merge, it should be `ediff-setup-diff-regions'.
+ "Value is a function symbol depending on the kind of job is to be done.
+For 2-way jobs and for `ediff-merge', it should be `ediff-setup-diff-regions'.
For jobs requiring diff3, it should be `ediff-setup-diff-regions3'.
The function should take three mandatory arguments, file-A, file-B, and
-file-C. It may ignore file C for diff2 jobs. It should also take
+file-C. It may ignore file C for diff2 jobs. It should also take
one optional arguments, diff-number to refine.")
@@ -824,13 +823,10 @@ one optional arguments, diff-number to refine.")
(setq overlay-list (cons overlay overlay-list))
(if (> (length diff-list) 1)
(setq diff-list (cdr (cdr diff-list)))
- (error "ediff-set-fine-overlays-for-combined-merge: corrupt list of
-delimiter regions"))
- )
+ (error "Corrupt list of delimiter regions")))
(setq overlay-list (reverse overlay-list))
(ediff-set-fine-diff-vector
- reg-num 'C (apply #'vector overlay-list))
- ))
+ reg-num 'C (apply #'vector overlay-list))))
;; Convert diff list to overlays for a given DIFF-REGION
@@ -1462,8 +1458,7 @@ affects only files whose names match the expression."
(message "Ignoring letter case is not supported by this diff program"))
(t
(sit-for 1)
- (ediff-update-diffs)))
- )
+ (ediff-update-diffs))))
(provide 'ediff-diff)
;;; ediff-diff.el ends here
diff --git a/lisp/vc/ediff-help.el b/lisp/vc/ediff-help.el
index a5bb953b6d4..48e1f15f05c 100644
--- a/lisp/vc/ediff-help.el
+++ b/lisp/vc/ediff-help.el
@@ -24,7 +24,6 @@
;;; Code:
-
;; Compiler pacifier start
(defvar ediff-multiframe)
;; end pacifier
@@ -127,9 +126,9 @@ Normally, not a user option. See `ediff-help-message' for details.")
(defconst ediff-brief-message-string
" Type ? for help"
"Contents of the brief help message.")
-;; The actual brief help message
(ediff-defvar-local ediff-brief-help-message ""
- "Normally, not a user option. See `ediff-help-message' for details.")
+ "The actual brief help message.
+Normally, not a user option. See `ediff-help-message' for details.")
(ediff-defvar-local ediff-brief-help-message-function nil
"The brief help message that the user can customize.
@@ -144,7 +143,6 @@ See `ediff-brief-help-message-function' for more.")
:type 'boolean
:group 'ediff-window)
-;; The actual help message.
(ediff-defvar-local ediff-help-message ""
"The actual help message.
Normally, the user shouldn't touch this. However, if you want Ediff to
@@ -229,7 +227,9 @@ the value of this variable and the variables `ediff-help-message-*' in
((string= cmd "s") (re-search-forward "^['`‘]s['’]"))
((string= cmd "+") (re-search-forward "^['`‘]\\+['’]"))
((string= cmd "=") (re-search-forward "^['`‘]=['’]"))
- (t (user-error "Undocumented command! Type `G' in Ediff Control Panel to drop a note to the Ediff maintainer")))
+ (t (user-error (substitute-command-keys
+ "Undocumented command! Type \\`G' in Ediff Control \
+Panel to drop a note to the Ediff maintainer"))))
) ; let case-fold-search
))
diff --git a/lisp/vc/ediff-init.el b/lisp/vc/ediff-init.el
index 17c4202d647..4b352bd34fc 100644
--- a/lisp/vc/ediff-init.el
+++ b/lisp/vc/ediff-init.el
@@ -49,7 +49,6 @@ that Ediff doesn't know about.")
(declare (obsolete nil "27.1"))
window-system)
-;; in XEmacs: device-type is tty on tty and stream in batch.
(defun ediff-window-display-p ()
(and window-system
(not (memq window-system '(tty pc stream)))))
@@ -75,46 +74,45 @@ that Ediff doesn't know about.")
(boundp 'ediff-use-toolbar-p)
ediff-use-toolbar-p)) ;Does the user want it ?
-;; Defines VAR as an advertised local variable.
-;; Performs a defvar, then executes `make-variable-buffer-local' on
-;; the variable. Also sets the `permanent-local' property,
-;; so that `kill-all-local-variables' (called by major-mode setting
-;; commands) won't destroy Ediff control variables.
-;;
;; Plagiarized from `emerge-defvar-local'.
-(defmacro ediff-defvar-local (var value doc)
- "Defines VAR as a local variable."
+(defmacro ediff-defvar-local (symbol value &optional doc)
+ "Define SYMBOL as an advertised buffer-local variable.
+Run `defvar-local', setting the value of the variable to VALUE
+and its docstring to DOC.
+
+Then set the `permanent-local' property, so that
+`kill-all-local-variables' (called by major-mode setting
+commands) won't destroy Ediff control variables."
(declare (indent defun) (doc-string 3))
`(progn
- (defvar-local ,var ,value ,doc)
- (put ',var 'permanent-local t)))
+ (defvar-local ,symbol ,value ,doc)
+ (put ',symbol 'permanent-local t)))
;; Variables that control each Ediff session---local to the control buffer.
;; Mode variables
-;; The buffer in which the A variant is stored.
-(ediff-defvar-local ediff-buffer-A nil "")
-;; The buffer in which the B variant is stored.
-(ediff-defvar-local ediff-buffer-B nil "")
-;; The buffer in which the C variant is stored or where the merge buffer lives.
-(ediff-defvar-local ediff-buffer-C nil "")
-;; Ancestor buffer
-(ediff-defvar-local ediff-ancestor-buffer nil "")
-;; The Ediff control buffer
-(ediff-defvar-local ediff-control-buffer nil "")
+(ediff-defvar-local ediff-buffer-A nil
+ "The buffer in which the A variant is stored.")
+(ediff-defvar-local ediff-buffer-B nil
+ "The buffer in which the B variant is stored.")
+(ediff-defvar-local ediff-buffer-C nil
+ "The buffer in which the C variant is stored or where the merge buffer lives.")
+(ediff-defvar-local ediff-ancestor-buffer nil
+ "Ancestor buffer.")
+(ediff-defvar-local ediff-control-buffer nil
+ "The Ediff control buffer.")
(ediff-defvar-local ediff-temp-indirect-buffer nil
"If t, the buffer is a temporary indirect buffer.
It needs to be killed when we quit the session.")
-
-;; Association between buff-type and ediff-buffer-*
(defconst ediff-buffer-alist
'((?A . ediff-buffer-A)
(?B . ediff-buffer-B)
- (?C . ediff-buffer-C)))
+ (?C . ediff-buffer-C))
+ "Association between `buff-type' and `ediff-buffer-*'.")
;;; Macros
(defsubst ediff-buffer-live-p (buf)
@@ -162,10 +160,10 @@ It needs to be killed when we quit the session.")
;; no-fine-diffs-flag says if there are fine differences.
;; state-of-difference is A, B, C, or nil, indicating which buffer is
;; different from the other two (used only in 3-way jobs.
-(ediff-defvar-local ediff-difference-vector-A nil "")
-(ediff-defvar-local ediff-difference-vector-B nil "")
-(ediff-defvar-local ediff-difference-vector-C nil "")
-(ediff-defvar-local ediff-difference-vector-Ancestor nil "")
+(ediff-defvar-local ediff-difference-vector-A nil)
+(ediff-defvar-local ediff-difference-vector-B nil)
+(ediff-defvar-local ediff-difference-vector-C nil)
+(ediff-defvar-local ediff-difference-vector-Ancestor nil)
;; A-list of diff vector types associated with buffer types
(defconst ediff-difference-vector-alist
'((A . ediff-difference-vector-A)
@@ -249,7 +247,7 @@ It needs to be killed when we quit the session.")
;; Doesn't save the point and mark.
;; This is `with-current-buffer' with the added test for live buffers."
(defmacro ediff-with-current-buffer (buffer &rest body)
- "Evaluates BODY in BUFFER."
+ "Evaluate BODY in BUFFER."
(declare (indent 1) (debug (form body)))
`(if (ediff-buffer-live-p ,buffer)
(save-current-buffer
@@ -271,7 +269,7 @@ It needs to be killed when we quit the session.")
'(memq
ediff-job-name
'(ediff-files3 ediff-buffers3)))
-(ediff-defvar-local ediff-3way-comparison-job nil "")
+(ediff-defvar-local ediff-3way-comparison-job nil)
(defmacro ediff-merge-job ()
'(memq
@@ -282,7 +280,7 @@ It needs to be killed when we quit the session.")
ediff-merge-buffers-with-ancestor
ediff-merge-revisions
ediff-merge-revisions-with-ancestor)))
-(ediff-defvar-local ediff-merge-job nil "")
+(ediff-defvar-local ediff-merge-job nil)
(defmacro ediff-patch-job ()
'(eq ediff-job-name 'epatch))
@@ -293,18 +291,18 @@ It needs to be killed when we quit the session.")
'(ediff-merge-files-with-ancestor
ediff-merge-buffers-with-ancestor
ediff-merge-revisions-with-ancestor)))
-(ediff-defvar-local ediff-merge-with-ancestor-job nil "")
+(ediff-defvar-local ediff-merge-with-ancestor-job nil)
(defmacro ediff-3way-job ()
'(or ediff-3way-comparison-job ediff-merge-job))
-(ediff-defvar-local ediff-3way-job nil "")
+(ediff-defvar-local ediff-3way-job nil)
;; A diff3 job is like a 3way job, but ediff-merge doesn't require the use
;; of diff3.
(defmacro ediff-diff3-job ()
'(or ediff-3way-comparison-job
ediff-merge-with-ancestor-job))
-(ediff-defvar-local ediff-diff3-job nil "")
+(ediff-defvar-local ediff-diff3-job nil)
(defmacro ediff-windows-job ()
'(memq ediff-job-name '(ediff-windows-wordwise ediff-windows-linewise)))
@@ -312,14 +310,14 @@ It needs to be killed when we quit the session.")
(defmacro ediff-word-mode-job ()
'(memq ediff-job-name '(ediff-windows-wordwise ediff-regions-wordwise)))
-(ediff-defvar-local ediff-word-mode-job nil "")
+(ediff-defvar-local ediff-word-mode-job nil)
(defmacro ediff-narrow-job ()
'(memq ediff-job-name '(ediff-windows-wordwise
ediff-regions-wordwise
ediff-windows-linewise
ediff-regions-linewise)))
-(ediff-defvar-local ediff-narrow-job nil "")
+(ediff-defvar-local ediff-narrow-job nil)
;; Note: ediff-merge-directory-revisions-with-ancestor is not treated as an
;; ancestor metajob, since it behaves differently.
@@ -405,7 +403,7 @@ It needs to be killed when we quit the session.")
(defcustom ediff-before-setup-hook nil
"Hooks to run before Ediff begins to set up windows and buffers.
This hook can be used to save the previous window config, which can be restored
-on ediff-quit or ediff-suspend."
+on `ediff-quit' or `ediff-suspend'."
:type 'hook
:group 'ediff-hook)
(defcustom ediff-before-setup-windows-hook nil
@@ -456,7 +454,7 @@ For each buffer, the hooks are run with that buffer made current."
"use `with-eval-after-load' instead." "28.1")
(defcustom ediff-mode-hook nil
- "Hook run just after ediff-mode is set up in the control buffer.
+ "Hook run just after `ediff-mode' is set up in the control buffer.
This is done before any windows or frames are created. One can use it to
set local variables that determine how the display looks like."
:type 'hook
@@ -492,11 +490,11 @@ set local variables that determine how the display looks like."
(defconst ediff-BAD-DIFF-NUMBER
;; %S stands for this-command, %d - diff number, %d - max diff
"%S: Bad diff region number, %d. Valid numbers are 1 to %d")
-(defconst ediff-BAD-INFO (format "
+(defconst ediff-BAD-INFO "
*** The Info file for Ediff, a part of the standard distribution
*** of Emacs, does not seem to be properly installed.
***
-*** Please contact your system administrator. "))
+*** Please contact your system administrator. ")
;; Selective browsing
@@ -516,25 +514,25 @@ See the documentation string of `ediff-hide-regexp-matches' for details.")
"Function to use in determining which regions to focus on.
See the documentation string of `ediff-focus-on-regexp-matches' for details.")
-;; Regexp that determines buf A regions to focus on when skipping to diff
-(ediff-defvar-local ediff-regexp-focus-A "" "")
-;; Regexp that determines buf B regions to focus on when skipping to diff
-(ediff-defvar-local ediff-regexp-focus-B "" "")
-;; Regexp that determines buf C regions to focus on when skipping to diff
-(ediff-defvar-local ediff-regexp-focus-C "" "")
+(ediff-defvar-local ediff-regexp-focus-A ""
+ "Regexp that determines buf A regions to focus on when skipping to diff.")
+(ediff-defvar-local ediff-regexp-focus-B ""
+ "Regexp that determines buf B regions to focus on when skipping to diff.")
+(ediff-defvar-local ediff-regexp-focus-C ""
+ "Regexp that determines buf C regions to focus on when skipping to diff.")
;; connective that determines whether to focus regions that match both or
;; one of the regexps
-(ediff-defvar-local ediff-focus-regexp-connective 'and "")
-
-;; Regexp that determines buf A regions to ignore when skipping to diff
-(ediff-defvar-local ediff-regexp-hide-A "" "")
-;; Regexp that determines buf B regions to ignore when skipping to diff
-(ediff-defvar-local ediff-regexp-hide-B "" "")
-;; Regexp that determines buf C regions to ignore when skipping to diff
-(ediff-defvar-local ediff-regexp-hide-C "" "")
+(ediff-defvar-local ediff-focus-regexp-connective 'and)
+
+(ediff-defvar-local ediff-regexp-hide-A ""
+ "Regexp that determines buf A regions to ignore when skipping to diff.")
+(ediff-defvar-local ediff-regexp-hide-B ""
+ "Regexp that determines buf B regions to ignore when skipping to diff.")
+(ediff-defvar-local ediff-regexp-hide-C ""
+ "Regexp that determines buf C regions to ignore when skipping to diff.")
;; connective that determines whether to hide regions that match both or
;; one of the regexps
-(ediff-defvar-local ediff-hide-regexp-connective 'and "")
+(ediff-defvar-local ediff-hide-regexp-connective 'and)
;;; Copying difference regions between buffers.
@@ -544,12 +542,12 @@ See the documentation string of `ediff-focus-on-regexp-matches' for details.")
;; from another buffer. This alist has the form:
;; \((num (buff-object . diff) (buff-object . diff) (buff-object . diff)) ...),
;; where some buffer-objects may be missing.
-(ediff-defvar-local ediff-killed-diffs-alist nil "")
+(ediff-defvar-local ediff-killed-diffs-alist nil)
;; Syntax table to use in ediff-forward-word-function
;; This is chosen by a heuristic. The important thing is for all buffers to
;; have the same syntax table. Which is not too important.
-(ediff-defvar-local ediff-syntax-table nil "")
+(ediff-defvar-local ediff-syntax-table nil)
;; Highlighting
@@ -589,25 +587,25 @@ highlighted using ASCII flags."
;; this indicates that diff regions are word-size, so fine diffs are
;; permanently nixed; used in ediff-windows-wordwise and ediff-regions-wordwise
-(ediff-defvar-local ediff-word-mode nil "")
+(ediff-defvar-local ediff-word-mode nil)
;; Name of the job (ediff-files, ediff-windows, etc.)
-(ediff-defvar-local ediff-job-name nil "")
+(ediff-defvar-local ediff-job-name nil)
;; Narrowing and ediff-region/windows support
;; This is a list (overlay-A overlay-B overlay-C)
;; If set, Ediff compares only those parts of buffers A/B/C that lie within
;; the bounds of these overlays.
-(ediff-defvar-local ediff-narrow-bounds nil "")
+(ediff-defvar-local ediff-narrow-bounds nil)
;; List (overlay-A overlay-B overlay-C), where each overlay spans the
;; entire corresponding buffer.
-(ediff-defvar-local ediff-wide-bounds nil "")
+(ediff-defvar-local ediff-wide-bounds nil)
;; Current visibility boundaries in buffers A, B, and C.
;; This is also a list of overlays. When the user toggles narrow/widen,
;; this list changes from ediff-wide-bounds to ediff-narrow-bounds.
;; and back.
-(ediff-defvar-local ediff-visible-bounds nil "")
+(ediff-defvar-local ediff-visible-bounds nil)
(ediff-defvar-local ediff-start-narrowed t
"Non-nil means start narrowed, if doing ediff-windows-* or ediff-regions-*")
@@ -616,9 +614,9 @@ highlighted using ASCII flags."
Actually, Ediff restores the scope of visibility that existed at startup.")
(defcustom ediff-keep-variants t
- "nil means prompt to remove unmodified buffers A/B/C at session end.
-Supplying a prefix argument to the quit command `q' temporarily reverses the
-meaning of this variable."
+ "Nil means prompt to remove unmodified buffers A/B/C at session end.
+Supplying a prefix argument to the quit command \\`q' temporarily
+reverses the meaning of this variable."
:type 'boolean
:group 'ediff)
@@ -632,28 +630,28 @@ shown in brighter colors."
(put 'ediff-highlight-all-diffs 'permanent-local t)
-;; The suffix of the control buffer name.
-(ediff-defvar-local ediff-control-buffer-suffix nil "")
-;; Same as ediff-control-buffer-suffix, but without <,>.
-;; It's a number rather than string.
-(ediff-defvar-local ediff-control-buffer-number nil "")
+(ediff-defvar-local ediff-control-buffer-suffix nil
+ "The suffix of the control buffer name.")
+(ediff-defvar-local ediff-control-buffer-number nil
+ "Same as `ediff-control-buffer-suffix', but without \"<,>\".
+It's a number rather than string.")
-;; The original values of ediff-protected-variables for buffer A
-(ediff-defvar-local ediff-buffer-values-orig-A nil "")
-;; The original values of ediff-protected-variables for buffer B
-(ediff-defvar-local ediff-buffer-values-orig-B nil "")
-;; The original values of ediff-protected-variables for buffer C
-(ediff-defvar-local ediff-buffer-values-orig-C nil "")
-;; The original values of ediff-protected-variables for buffer Ancestor
-(ediff-defvar-local ediff-buffer-values-orig-Ancestor nil "")
+(ediff-defvar-local ediff-buffer-values-orig-A nil
+ "The original values of ediff-protected-variables for buffer A.")
+(ediff-defvar-local ediff-buffer-values-orig-B nil
+ "The original values of ediff-protected-variables for buffer B.")
+(ediff-defvar-local ediff-buffer-values-orig-C nil
+ "The original values of ediff-protected-variables for buffer C.")
+(ediff-defvar-local ediff-buffer-values-orig-Ancestor nil
+ "The original values of ediff-protected-variables for buffer Ancestor.")
-;; association between buff-type and ediff-buffer-values-orig-*
(defconst ediff-buffer-values-orig-alist
'((A . ediff-buffer-values-orig-A)
(B . ediff-buffer-values-orig-B)
(C . ediff-buffer-values-orig-C)
- (Ancestor . ediff-buffer-values-orig-Ancestor)))
+ (Ancestor . ediff-buffer-values-orig-Ancestor))
+ "Association between buff-type and `ediff-buffer-values-orig-*'.")
;; Buffer-local variables to be saved then restored during Ediff sessions
(defconst ediff-protected-variables '(
@@ -666,37 +664,37 @@ shown in brighter colors."
;; indicates the way a diff region was created in buffer C.
;; state-of-ancestor says if the corresponding region in ancestor buffer is
;; empty.
-(ediff-defvar-local ediff-state-of-merge nil "")
-
-;; The difference that is currently selected.
-(ediff-defvar-local ediff-current-difference -1 "")
-;; Number of differences found.
-(ediff-defvar-local ediff-number-of-differences nil "")
-
-;; Buffer containing the output of diff, which is used by Ediff to step
-;; through files.
-(ediff-defvar-local ediff-diff-buffer nil "")
-;; Like ediff-diff-buffer, but contains context diff. It is not used by
-;; Ediff, but it is saved in a file, if user requests so.
-(ediff-defvar-local ediff-custom-diff-buffer nil "")
-;; Buffer used for diff-style fine differences between regions.
-(ediff-defvar-local ediff-fine-diff-buffer nil "")
-;; Temporary buffer used for computing fine differences.
-(defconst ediff-tmp-buffer " *ediff-tmp*" "")
-;; Buffer used for messages
-(defconst ediff-msg-buffer " *ediff-message*" "")
-;; Buffer containing the output of diff when diff returns errors.
-(ediff-defvar-local ediff-error-buffer nil "")
-;; Buffer to display debug info
-(ediff-defvar-local ediff-debug-buffer "*ediff-debug*" "")
-
-;; List of ediff control panels associated with each buffer A/B/C/Ancestor.
-;; Not used any more, but may be needed in the future.
-(ediff-defvar-local ediff-this-buffer-ediff-sessions nil "")
+(ediff-defvar-local ediff-state-of-merge nil)
+
+(ediff-defvar-local ediff-current-difference -1
+ "The difference that is currently selected.")
+(ediff-defvar-local ediff-number-of-differences nil
+ "Number of differences found.")
+
+(ediff-defvar-local ediff-diff-buffer nil
+ "Buffer containing the output of diff, which is used to step through files.")
+(ediff-defvar-local ediff-custom-diff-buffer nil
+ "Like `ediff-diff-buffer', but contains context diff.
+It is not used by Ediff, but it is saved in a file, if user
+requests so.")
+(ediff-defvar-local ediff-fine-diff-buffer nil
+ "Buffer used for diff-style fine differences between regions.")
+(defconst ediff-tmp-buffer " *ediff-tmp*"
+ "Temporary buffer used for computing fine differences.")
+(defconst ediff-msg-buffer " *ediff-message*"
+ "Buffer used for messages.")
+(ediff-defvar-local ediff-error-buffer nil
+ "Buffer containing the output of diff when diff returns errors.")
+(ediff-defvar-local ediff-debug-buffer "*ediff-debug*"
+ "Buffer to display debug info.")
+
+(ediff-defvar-local ediff-this-buffer-ediff-sessions nil
+ "List of ediff control panels associated with each buffer A/B/C/Ancestor.
+Not used any more, but may be needed in the future.")
;; to be deleted in due time
;; List of difference overlays disturbed by working with the current diff.
-(defvar ediff-disturbed-overlays nil "")
+(defvar ediff-disturbed-overlays nil)
(defcustom ediff-version-control-package 'vc
"Version control package used.
@@ -708,7 +706,7 @@ appropriate symbol: `rcs', `pcl-cvs', or `generic-sc' if you so desire."
:group 'ediff)
(defcustom ediff-coding-system-for-read 'raw-text
- "The coding system for read to use when running the diff program as a subprocess.
+ "Coding system for read to use when running the diff program as a subprocess.
In most cases, the default will do. However, under certain circumstances in
MS-Windows you might need to use something like `raw-text-dos' here.
So, if the output that your diff program sends to Emacs contains extra ^M's,
@@ -718,8 +716,9 @@ work."
:group 'ediff)
(defcustom ediff-coding-system-for-write 'emacs-internal
- "The coding system for write to use when writing out difference regions
-to temp files in buffer jobs and when Ediff needs to find fine differences."
+ "Coding system for write to use when writing out difference regions.
+This is used when writing to temp files in buffer jobs and when
+Ediff needs to find fine differences."
:type 'symbol
:group 'ediff)
@@ -739,8 +738,7 @@ to temp files in buffer jobs and when Ediff needs to find fine differences."
;; in effect for this buffer: `face', `ascii',
;; `off' -- turned off (on a dumb terminal only).
(ediff-defvar-local ediff-highlighting-style
- (if (and (ediff-has-face-support-p) ediff-use-faces) 'face 'ascii)
- "")
+ (if (and (ediff-has-face-support-p) ediff-use-faces) 'face 'ascii))
(define-obsolete-function-alias 'ediff-display-pixel-width
@@ -790,7 +788,7 @@ to temp files in buffer jobs and when Ediff needs to find fine differences."
(defun ediff-set-face-pixmap (face pixmap)
- "Set face pixmap on a monochrome display."
+ "Set stipple pixmap of FACE to PIXMAP on a monochrome display."
(if (and (ediff-window-display-p) (not (display-color-p)))
(condition-case nil
(set-face-background-pixmap face pixmap)
@@ -836,7 +834,7 @@ this variable represents.")
;; this variable is set to nil, then again to the appropriate face.
(defvar ediff-current-diff-face-B 'ediff-current-diff-B
"Face for highlighting the selected difference in buffer B.
- this variable. Instead, use the customization
+DO NOT CHANGE this variable. Instead, use the customization
widget to customize the actual face `ediff-current-diff-B'
this variable represents.")
@@ -1221,7 +1219,7 @@ This property can be toggled interactively."
;; Store orig value of `ediff-show-ancestor' when changed in
;; `ediff-toggle-show-ancestor' and restore it on exit.
-(ediff-defvar-local ediff--show-ancestor-orig nil "")
+(ediff-defvar-local ediff--show-ancestor-orig nil)
(defcustom ediff-autostore-merges 'group-jobs-only
"Save the results of merge jobs automatically.
@@ -1233,8 +1231,8 @@ or `ediff-merge-directory-revisions'."
:group 'ediff-merge)
(make-variable-buffer-local 'ediff-autostore-merges)
-;; file where the result of the merge is to be saved. used internally
-(ediff-defvar-local ediff-merge-store-file nil "")
+(ediff-defvar-local ediff-merge-store-file nil
+ "File where the result of the merge is to be saved. Internal.")
(defcustom ediff-merge-filename-prefix "merge_"
"Prefix to be attached to saved merge buffers."
@@ -1267,12 +1265,12 @@ This default should work without changes."
(make-obsolete-variable 'ediff-H-glyph nil "28.1")
-;; Temporary file used for refining difference regions in buffer A.
-(ediff-defvar-local ediff-temp-file-A nil "")
-;; Temporary file used for refining difference regions in buffer B.
-(ediff-defvar-local ediff-temp-file-B nil "")
-;; Temporary file used for refining difference regions in buffer C.
-(ediff-defvar-local ediff-temp-file-C nil "")
+(ediff-defvar-local ediff-temp-file-A nil
+ "Temporary file used for refining difference regions in buffer A.")
+(ediff-defvar-local ediff-temp-file-B nil
+ "Temporary file used for refining difference regions in buffer B.")
+(ediff-defvar-local ediff-temp-file-C nil
+ "Temporary file used for refining difference regions in buffer C.")
(defun ediff-file-remote-p (file-name)
@@ -1474,7 +1472,7 @@ This default should work without changes."
(delete-overlay overlay)))))
(defun ediff-overlay-put (overlay prop value)
- "Calls `overlay-put', but checks if overlay's buffer exists."
+ "Call `overlay-put', but check if OVERLAY's buffer exists."
(if (ediff-buffer-live-p (overlay-buffer overlay))
(overlay-put overlay prop value)
(delete-overlay overlay)))
diff --git a/lisp/vc/ediff-merg.el b/lisp/vc/ediff-merg.el
index ad4ef473f84..d0ce9d326d8 100644
--- a/lisp/vc/ediff-merg.el
+++ b/lisp/vc/ediff-merg.el
@@ -53,7 +53,7 @@ Valid values are the symbols `default-A', `default-B', and `combined'."
"Pattern to be used for combining difference regions in buffers A and B.
The value must be a list of the form
\(STRING1 bufspec1 STRING2 bufspec2 STRING3 bufspec3 STRING4)
-where bufspec is the symbol A, B, or Ancestor. For instance, if the value is
+where bufspec is the symbol A, B, or Ancestor. For instance, if the value is
'(STRING1 A STRING2 Ancestor STRING3 B STRING4) then the
combined text will look like this:
@@ -63,8 +63,7 @@ STRING2
diff region from the ancestor
STRING3
diff region from variant B
-STRING4
-"
+STRING4"
:type '(choice (list string symbol string symbol string)
(list string symbol string symbol string symbol string))
:group 'ediff-merge)
@@ -258,7 +257,8 @@ Buffer B."
(defun ediff-re-merge ()
- "Remerge unmodified diff regions using a new default. Start with the current region."
+ "Remerge unmodified diff regions using a new default.
+Start with the current region."
(interactive)
(let* ((default-variant-alist
(list '("default-A") '("default-B") '("combined")))
diff --git a/lisp/vc/ediff-mult.el b/lisp/vc/ediff-mult.el
index 8e88b60a0bd..bec0ec01208 100644
--- a/lisp/vc/ediff-mult.el
+++ b/lisp/vc/ediff-mult.el
@@ -47,7 +47,7 @@
;; explanation of the two nil placeholders in such elements.
;;
;; There is API for extracting the components of the members of the
-;; above list. Search for `API for ediff-meta-list' for details.
+;; above list. Search for `API for ediff-meta-list' for details.
;;
;; HEADER must be a list of SIX elements (nil or string):
;; (regexp metaobj1 metaobj2 metaobj3 merge-save-buffer
@@ -114,8 +114,8 @@
(require 'ediff-util)
;; meta-buffer
-(ediff-defvar-local ediff-meta-buffer nil "")
-(ediff-defvar-local ediff-parent-meta-buffer nil "")
+(ediff-defvar-local ediff-meta-buffer nil)
+(ediff-defvar-local ediff-parent-meta-buffer nil)
;; the registry buffer
(defvar ediff-registry-buffer nil)
@@ -157,28 +157,27 @@ Useful commands (type ? to hide them and free up screen):
(define-key map [delete] #'previous-line)
(define-key map [backspace] #'previous-line)
map)
- "The keymap to be installed in the buffer showing differences between
-directories.")
+ "Keymap for buffer showing differences between directories.")
;; Variable specifying the action to take when the use invokes ediff in the
;; meta buffer. This is usually ediff-registry-action or ediff-filegroup-action
-(ediff-defvar-local ediff-meta-action-function nil "")
+(ediff-defvar-local ediff-meta-action-function nil)
;; Tells ediff-update-meta-buffer how to redraw it
-(ediff-defvar-local ediff-meta-redraw-function nil "")
+(ediff-defvar-local ediff-meta-redraw-function nil)
;; Tells ediff-filegroup-action and similar procedures how to invoke Ediff for
;; the sessions in a given session group
-(ediff-defvar-local ediff-session-action-function nil "")
+(ediff-defvar-local ediff-session-action-function nil)
-(ediff-defvar-local ediff-metajob-name nil "")
+(ediff-defvar-local ediff-metajob-name nil)
;; buffer used to collect custom diffs from individual sessions in the group
-(ediff-defvar-local ediff-meta-diff-buffer nil "")
+(ediff-defvar-local ediff-meta-diff-buffer nil)
;; t means recurse into subdirs when deciding which files have same contents
-(ediff-defvar-local ediff-recurse-to-subdirectories nil "")
+(ediff-defvar-local ediff-recurse-to-subdirectories nil)
;; history var to use for filtering groups of files
-(defvar ediff-filtering-regexp-history nil "")
+(defvar ediff-filtering-regexp-history nil)
(defcustom ediff-default-filtering-regexp nil
"Default regular expression used as a filename filter in multifile comparisons.
@@ -195,14 +194,14 @@ Should be a sexp. For instance (car ediff-filtering-regexp-history) or nil."
;; buffer, this means ediff is still working on the pair.
;; Eq-status of a file is t if the file equals some other file in the same
;; group.
-(ediff-defvar-local ediff-meta-list nil "")
+(ediff-defvar-local ediff-meta-list nil)
-(ediff-defvar-local ediff-meta-session-number nil "")
+(ediff-defvar-local ediff-meta-session-number nil)
;; the difference list between directories in a directory session group
-(ediff-defvar-local ediff-dir-difference-list nil "")
-(ediff-defvar-local ediff-dir-diffs-buffer nil "")
+(ediff-defvar-local ediff-dir-difference-list nil)
+(ediff-defvar-local ediff-dir-diffs-buffer nil)
;; The registry of Ediff sessions. A list of control buffers.
(defvar ediff-session-registry nil)
@@ -233,8 +232,8 @@ on `ediff-quit', `ediff-suspend', or `ediff-quit-session-group-hook'."
(make-obsolete-variable 'ediff-before-session-group-setup-hooks nil "27.1")
(defcustom ediff-after-session-group-setup-hook nil
- "Hooks run just after a meta-buffer controlling a session group, such as
-ediff-directories, is run."
+ "Hooks run just after a meta-buffer controlling a session group is run.
+One example of this is `ediff-directories'."
:type 'hook)
(defcustom ediff-quit-session-group-hook nil
"Hooks run just before exiting a session group."
@@ -252,8 +251,8 @@ This means that you can set different bindings for different kinds of meta
buffers."
:type 'hook)
-;; Buffer holding the multi-file patch. Local to the meta buffer
-(ediff-defvar-local ediff-meta-patchbufer nil "")
+(ediff-defvar-local ediff-meta-patchbufer nil
+ "Buffer holding the multi-file patch. Local to the meta buffer.")
;;; API for ediff-meta-list
@@ -367,8 +366,8 @@ buffers."
(ediff-defvar-local ediff-verbose-help-enabled nil
- "If t, display redundant help in ediff-directories and other meta buffers.
-Toggled by ediff-toggle-verbose-help-meta-buffer" )
+ "If t, display redundant help in `ediff-directories' and other meta buffers.
+Toggled by `ediff-toggle-verbose-help-meta-buffer'.")
;; Toggle verbose help in meta-buffers
;; TODO: Someone who understands all this can make it better.
@@ -460,7 +459,9 @@ Commands:
(defun ediff-next-meta-item (count)
"Move to the next item in Ediff registry or session group buffer.
-Moves in circular fashion. With numeric prefix arg, skip this many items."
+Moves in circular fashion.
+
+With numeric prefix arg COUNT, skip this many items."
(interactive "p")
(or count (setq count 1))
(let (overl)
@@ -488,7 +489,9 @@ Moves in circular fashion. With numeric prefix arg, skip this many items."
(defun ediff-previous-meta-item (count)
"Move to the previous item in Ediff registry or session group buffer.
-Moves in circular fashion. With numeric prefix arg, skip this many items."
+Moves in circular fashion.
+
+With numeric prefix arg COUNT, skip this many items."
(interactive "p")
(or count (setq count 1))
(let (overl)
@@ -611,22 +614,22 @@ behavior."
(if (ediff-nonempty-string-p merge-autostore-dir)
(setq merge-autostore-dir
(file-name-as-directory merge-autostore-dir)))
- (setq common (ediff-intersection lis1 lis2 #'string=))
+ (setq common (seq-intersection lis1 lis2 #'string=))
;; In merge with ancestor jobs, we don't intersect with lis3.
;; If there is no ancestor, we'll offer to merge without the ancestor.
;; So, we intersect with lis3 only when we are doing 3-way file comparison
(if (and lis3 (ediff-comparison-metajob3 jobname))
- (setq common (ediff-intersection common lis3 #'string=)))
+ (setq common (seq-intersection common lis3 #'string=)))
;; copying is needed because sort sorts via side effects
(setq common (sort (copy-sequence common) #'string-lessp))
;; compute difference list
- (setq difflist (ediff-set-difference
- (ediff-union (ediff-union lis1 lis2 #'string=)
- lis3
- #'string=)
+ (setq difflist (seq-difference
+ (seq-union (seq-union lis1 lis2 #'string=)
+ lis3
+ #'string=)
common
#'string=)
difflist (delete "." difflist)
@@ -1531,7 +1534,9 @@ Useful commands:
(ediff-overlay-put overl 'ediff-meta-session-number session-number))))
(defun ediff-mark-for-hiding-at-pos (unmark)
- "Mark session for hiding. With prefix arg, unmark."
+ "Mark session for hiding.
+
+With prefix arg UNMARK, unmark instead."
(interactive "P")
(let* ((pos (ediff-event-point last-command-event))
(meta-buf (ediff-event-buffer last-command-event))
@@ -1541,10 +1546,9 @@ Useful commands:
(ediff-mark-session-for-hiding info unmark)
(ediff-next-meta-item 1)
(save-excursion
- (ediff-update-meta-buffer meta-buf nil session-number))
- ))
+ (ediff-update-meta-buffer meta-buf nil session-number))))
-;; Returns whether session was marked or unmarked
+;; Return whether session was marked or unmarked.
(defun ediff-mark-session-for-hiding (info unmark)
(let (ignore)
(cond ((eq unmark 'mark) (setq unmark nil))
@@ -1560,7 +1564,9 @@ Useful commands:
(defun ediff-mark-for-operation-at-pos (unmark)
- "Mark session for a group operation. With prefix arg, unmark."
+ "Mark session for a group operation.
+
+With prefix arg UNMARK, unmark instead."
(interactive "P")
(let* ((pos (ediff-event-point last-command-event))
(meta-buf (ediff-event-buffer last-command-event))
@@ -1589,7 +1595,9 @@ Useful commands:
(defun ediff-hide-marked-sessions (unhide)
- "Hide marked sessions. With prefix arg, unhide."
+ "Hide marked sessions.
+
+With prefix arg UNHIDE, unhide instead."
(interactive "P")
(let ((grp-buf (ediff-get-group-buffer ediff-meta-list))
(meta-list (cdr ediff-meta-list))
@@ -1669,7 +1677,7 @@ Useful commands:
(setq custom-diff-buf ediff-custom-diff-buffer)))))
(or (ediff-buffer-live-p meta-diff-buff)
- (user-error "Ediff: something wrong--killed multiple diff's buffer"))
+ (user-error "Ediff: Something wrong--killed multiple diff's buffer"))
(cond ((ediff-buffer-live-p custom-diff-buf)
;; for live session buffers we do them first because the user may
diff --git a/lisp/vc/ediff-ptch.el b/lisp/vc/ediff-ptch.el
index d52910efceb..a03c6a5ed7e 100644
--- a/lisp/vc/ediff-ptch.el
+++ b/lisp/vc/ediff-ptch.el
@@ -128,18 +128,19 @@ You probably don't want to change that, unless you are using an obscure patch
program."
:type 'regexp)
-;; The buffer of the patch file. Local to control buffer.
-(ediff-defvar-local ediff-patchbufer nil "")
+(ediff-defvar-local ediff-patchbufer nil
+ "The buffer of the patch file. Local to control buffer.")
-;; The buffer where patch displays its diagnostics.
-(ediff-defvar-local ediff-patch-diagnostics nil "")
+(ediff-defvar-local ediff-patch-diagnostics nil
+ "The buffer where patch displays its diagnostics.")
-;; Map of patch buffer. Has the form:
-;; ((filename1 marker1 marker2) (filename2 marker1 marker2) ...)
-;; where filenames are files to which patch would have applied the patch;
-;; marker1 delimits the beginning of the corresponding patch and marker2 does
-;; it for the end.
-(ediff-defvar-local ediff-patch-map nil "")
+(ediff-defvar-local ediff-patch-map nil
+ "Map of patch buffer.
+Has the form:
+ ((filename1 marker1 marker2) (filename2 marker1 marker2) ...)
+where filenames are files to which patch would have applied the patch;
+marker1 delimits the beginning of the corresponding patch and marker2 does
+it for the end.")
;; strip prefix from filename
;; returns /dev/null, if can't strip prefix
@@ -414,7 +415,9 @@ other files, enter `/dev/null'.
(with-output-to-temp-buffer ediff-msg-buffer
(ediff-with-current-buffer standard-output
(fundamental-mode))
- (princ (format-message "
+ (with-current-buffer standard-output
+ (insert (format-message
+ (substitute-command-keys "
Ediff has inferred that
%s
%s
@@ -422,10 +425,10 @@ are two possible targets for applying the patch.
Both files seem to be plausible alternatives.
Please advise:
- Type `y' to use %s as the target;
- Type `n' to use %s as the target.
-"
- file1 file2 file1 file2)))
+ Type \\`y' to use %s as the target;
+ Type \\`n' to use %s as the target.
+")
+ file1 file2 file1 file2))))
(setcar session-file-object
(if (y-or-n-p (format "Use %s ? " file1))
(progn
@@ -502,15 +505,11 @@ are two possible targets for this %spatch. However, these files do not exist."
patch-file-name)
(setq patch-file-name
(read-file-name
- (format "Patch is in file%s: "
- (cond ((and buffer-file-name
- (equal (expand-file-name dir)
- (file-name-directory buffer-file-name)))
- (concat
- " (default "
- (file-name-nondirectory buffer-file-name)
- ")"))
- (t "")))
+ (format-prompt "Patch is in file"
+ (and buffer-file-name
+ (equal (expand-file-name dir)
+ (file-name-directory buffer-file-name))
+ (file-name-nondirectory buffer-file-name)))
dir buffer-file-name 'must-match))
(if (file-directory-p patch-file-name)
(error "Patch file cannot be a directory: %s" patch-file-name)
@@ -826,7 +825,8 @@ you can still examine the changes via M-x ediff-files"
ediff-patch-diagnostics patch-diagnostics))
(bury-buffer patch-diagnostics)
- (message "Type `P', if you need to see patch diagnostics")
+ (message (substitute-command-keys
+ "Type \\`P', if you need to see patch diagnostics"))
ctl-buf))
(defun ediff-multi-patch-internal (patch-buf &optional startup-hooks)
diff --git a/lisp/vc/ediff-util.el b/lisp/vc/ediff-util.el
index 0cbea2c28d7..c2b08bd31af 100644
--- a/lisp/vc/ediff-util.el
+++ b/lisp/vc/ediff-util.el
@@ -87,12 +87,10 @@ Commands:
(kill-all-local-variables)
(setq major-mode 'ediff-mode)
(setq mode-name "Ediff")
- ;; We use run-hooks instead of run-mode-hooks for two reasons.
+ ;; We use run-hooks instead of run-mode-hooks for one reason.
;; The ediff control buffer is read-only and it is not supposed to be
;; modified by minor modes and such. So, run-mode-hooks doesn't do anything
;; useful here on top of what run-hooks does.
- ;; Second, changing run-hooks to run-mode-hooks would require an
- ;; if-statement, since XEmacs doesn't have this.
(run-hooks 'ediff-mode-hook))
@@ -515,7 +513,7 @@ to invocation.")
;; This function assumes that we are in the window where control buffer is
;; to reside.
(defun ediff-setup-control-buffer (ctl-buf)
- "Set up window for control buffer."
+ "Set up window for control buffer CTL-BUF."
(if (window-dedicated-p)
(set-buffer ctl-buf) ; we are in control frame but just in case
(switch-to-buffer ctl-buf))
@@ -523,7 +521,25 @@ to invocation.")
(erase-buffer)
(ediff-set-help-message)
(insert ediff-help-message)
- (shrink-window-if-larger-than-buffer)
+ ;; With the fix for Bug#49277 and an 'ediff-setup-windows-plain'
+ ;; layout, the window of the control buffer we want to adjust here
+ ;; is no longer the lower of two windows on their frame both showing
+ ;; that control buffer but rather the bottom-most window in the
+ ;; established ediff layout for that frame. As a consequence,
+ ;; 'shrink-window-if-larger-than-buffer' will fail to show the whole
+ ;; buffer with 'ediff-toggle-help' because that window's maximum
+ ;; height is not half the height of its frame but the height of the
+ ;; control buffer's window in the established layout (Bug#52504).
+ ;;
+ ;; The form below is an attempt to emulate the behavior of Emacs 27
+ ;; as faithfully as possible in this regard (the use of 'ceiling'
+ ;; mimics the behavior of 'split-window' giving the lower window the
+ ;; residue line when the window to split has an uneven number of
+ ;; lines).
+ (when (and (window-combined-p)
+ (pos-visible-in-window-p (point-min)))
+ (fit-window-to-buffer
+ nil (ceiling (/ (window-total-height (frame-root-window)) 2.0))))
(or (ediff-multiframe-setup-p)
(ediff-indent-help-message))
(ediff-set-help-overlays)
@@ -663,7 +679,7 @@ if necessary."
(message "")
))
-;; Not bound to any key---to dangerous. A user can do it if necessary.
+;; Not bound to any key---too dangerous. A user can do it if necessary.
(defun ediff-revert-buffers-then-recompute-diffs (noconfirm)
"Revert buffers A, B and C. Then rerun Ediff on file A and file B."
(interactive "P")
@@ -698,11 +714,12 @@ if necessary."
(ediff-merge-buffers bufA bufB)))
(ediff-update-diffs))))
-
-;; optional NO-REHIGHLIGHT says to not rehighlight buffers
(defun ediff-recenter (&optional no-rehighlight)
"Bring the highlighted region of all buffers being compared into view.
-Reestablish the default window display."
+Reestablish the default window display.
+
+If optional NO-REHIGHLIGHT is non-nil, do not rehighlight
+buffers."
(interactive)
(ediff-barf-if-not-control-buffer)
(let (buffer-read-only)
@@ -967,7 +984,7 @@ Please report this bug to bug-gnu-emacs@gnu.org")
(message "Showing ancestor buffer")))
(defun ediff-make-or-kill-fine-diffs (arg)
- "Compute fine diffs. With negative prefix arg, kill fine diffs.
+ "Compute fine diffs. With negative prefix ARG, kill fine diffs.
In both cases, operates on the current difference region."
(interactive "P")
(ediff-barf-if-not-control-buffer)
@@ -1331,7 +1348,7 @@ To change the default, set the variable `ediff-use-toolbar-p', which see."
;; Merging
(defun ediff-toggle-show-clashes-only ()
- "Toggle the mode that shows only the merge regions where both variants differ from the ancestor."
+ "Toggle mode showing only merge regions where both variants differ from ancestor."
(interactive)
(ediff-barf-if-not-control-buffer)
(if (not ediff-merge-with-ancestor-job)
@@ -1512,7 +1529,7 @@ the one half of the height of window-A."
(defun ediff-scroll-horizontally (&optional arg)
"Horizontally scroll buffers A, B (and C if appropriate).
-If an argument is given, that is how many columns are scrolled, else nearly
+With prefix argument ARG, scroll that many columns, else nearly
the width of the A/B/C windows."
(interactive "P")
(ediff-barf-if-not-control-buffer)
@@ -1680,7 +1697,7 @@ the width of the A/B/C windows."
(defun ediff-next-difference (&optional arg)
"Advance to the next difference.
-With a prefix argument, go forward that many differences."
+With a prefix argument ARG, go forward that many differences."
(interactive "p")
(ediff-barf-if-not-control-buffer)
(if (< ediff-current-difference ediff-number-of-differences)
@@ -1731,7 +1748,7 @@ With a prefix argument, go forward that many differences."
(defun ediff-previous-difference (&optional arg)
"Go to the previous difference.
-With a prefix argument, go back that many differences."
+With a prefix argument ARG, go back that many differences."
(interactive "p")
(ediff-barf-if-not-control-buffer)
(if (> ediff-current-difference -1)
@@ -1781,8 +1798,9 @@ With a prefix argument, go back that many differences."
;; The diff number is as perceived by the user (i.e., 1+ the internal
;; representation)
(defun ediff-jump-to-difference (difference-number)
- "Go to the difference specified as a prefix argument.
-If the prefix is negative, count differences from the end."
+ "Go to the difference specified as a prefix argument DIFFERENCE-NUMBER.
+If the prefix argument is negative, count differences from the
+end."
(interactive "p")
(ediff-barf-if-not-control-buffer)
(setq difference-number
@@ -1803,8 +1821,9 @@ If the prefix is negative, count differences from the end."
The buffer depends on last command character \(a, b, or c) that invoked this
command. For instance, if the command was `ga' then the point value in buffer
A is used.
-With a prefix argument, synchronize all files around the current point position
-in the specified buffer."
+
+With a prefix argument ARG, synchronize all files around the
+current point position in the specified buffer."
(interactive "P")
(ediff-barf-if-not-control-buffer)
(let* ((buf-type (ediff-char-to-buftype last-command-event))
@@ -1900,15 +1919,17 @@ in the specified buffer."
(defun ediff-diff-to-diff (arg &optional keys)
"Copy buffer-X'th difference region to buffer Y (X,Y are A, B, or C).
-If numerical prefix argument, copy the difference specified in the arg.
+With numerical prefix argument ARG, copy the difference specified
+in the arg.
Otherwise, copy the difference given by `ediff-current-difference'.
This command assumes it is bound to a 2-character key sequence, `ab', `ba',
`ac', etc., which is used to determine the types of buffers to be used for
copying difference regions. The first character in the sequence specifies
the source buffer and the second specifies the target.
-If the second optional argument, a 2-character string, is given, use it to
-determine the source and the target buffers instead of the command keys."
+If optional argument KEYS, a 2-character string, is given, use it
+to determine the source and the target buffers instead of the
+command keys."
(interactive "P")
(ediff-barf-if-not-control-buffer)
(or keys (setq keys (this-command-keys)))
@@ -2139,8 +2160,9 @@ ARG is a prefix argument. If nil, copy the current difference region."
(defun ediff-restore-diff (arg &optional key)
"Restore ARGth diff from `ediff-killed-diffs-alist'.
ARG is a prefix argument. If ARG is nil, restore the current-difference.
-If the second optional argument, a character, is given, use it to
-determine the target buffer instead of `ediff-last-command-char'."
+If the second optional argument KEY, a character, is given, use
+it to determine the target buffer instead of
+`ediff-last-command-char'."
(interactive "P")
(ediff-barf-if-not-control-buffer)
(if (numberp arg)
@@ -2159,8 +2181,8 @@ ARG is a prefix argument. If nil, restore the current diff."
(defun ediff-toggle-regexp-match ()
- "Toggle between focusing and hiding of difference regions that match
-a regular expression typed in by the user."
+ "Toggle between focusing and hiding difference regions matching a regexp.
+Prompt the user for regular expression."
(interactive)
(ediff-barf-if-not-control-buffer)
(let ((regexp-A "")
@@ -2360,9 +2382,11 @@ flags of the compared file buffers, kills Ediff buffers for this session
\(but not buffers A, B, C).
If `ediff-keep-variants' is nil, the user will be asked whether the buffers
-containing the variants should be removed \(if they haven't been modified).
-If it is t, they will be preserved unconditionally. A prefix argument,
-temporarily reverses the meaning of this variable."
+containing the variants should be removed (if they haven't been modified).
+If it is t, they will be preserved unconditionally.
+
+With prefix argument REVERSE-DEFAULT-KEEP-VARIANTS, temporarily
+reverse the meaning of this variable."
(interactive "P")
(ediff-barf-if-not-control-buffer)
(let ((ctl-buf (current-buffer))
@@ -2771,8 +2795,8 @@ up an appropriate window config."
(interactive)
(ediff-barf-if-not-control-buffer)
(run-hooks 'ediff-suspend-hook)
- (message
- "To resume, type M-x eregistry and select the desired Ediff session"))
+ (message (substitute-command-keys
+ "To resume, type \\[eregistry] and select the desired Ediff session")))
;; ediff-barf-if-not-control-buffer ensures only called from ediff.
(declare-function ediff-version "ediff" ())
@@ -3097,11 +3121,7 @@ Hit \\[ediff-recenter] to reset the windows afterward."
(lambda () (when defaults
(setq minibuffer-default defaults)))
(read-file-name
- (format "%s%s "
- prompt
- (cond (default-file
- (concat " (default " default-file "):"))
- (t (concat " (default " default-dir "):"))))
+ (format-prompt prompt (or default-file default-dir))
default-dir
(or default-file default-dir)
t ; must match, no-confirm
@@ -3214,7 +3234,7 @@ Hit \\[ediff-recenter] to reset the windows afterward."
(if (buffer-modified-p)
;; If buffer is not obsolete and is modified, offer to save
(if (yes-or-no-p
- (format "Buffer %s has been modified. Save it in file %s? "
+ (format "Buffer %s has been modified. Save it in file %s?"
(buffer-name)
buffer-file-name))
(condition-case nil
@@ -3271,7 +3291,7 @@ Hit \\[ediff-recenter] to reset the windows afterward."
`wa' saves buffer A, `wb' saves buffer B, `wc' saves buffer C,
and `wd' saves the diff output.
-With prefix argument, `wd' saves plain diff output.
+With prefix argument ARG, `wd' saves plain diff output.
Without an argument, it saves customized diff argument, if available
\(and plain output, if customized output was not generated)."
(interactive "P")
@@ -3938,8 +3958,8 @@ If Emacs happens to dump core, this is NOT an Ediff problem---it is
an Emacs bug. Report this to Emacs maintainers.
Another popular topic for reports is compilation messages. Because Ediff
-interfaces to several other packages and runs under Emacs and XEmacs,
-byte-compilation may produce output like this:
+interfaces to several other packages, byte-compilation may produce output
+like this:
While compiling toplevel forms in file ediff.el:
** reference to free variable zzz
@@ -4068,7 +4088,7 @@ Mail anyway? (y or n) ")
;;; Debug
-(ediff-defvar-local ediff-command-begin-time '(0 0 0) "")
+(ediff-defvar-local ediff-command-begin-time '(0 0 0))
;; calculate time used by command
(defun ediff-calc-command-time ()
@@ -4139,6 +4159,7 @@ Mail anyway? (y or n) ")
;; this uses comparison-func to decide who is a member
(defun ediff-member (elt lis comparison-func)
+ (declare (obsolete seq-contains-p "28.1"))
(while (and lis (not (funcall comparison-func (car lis) elt)))
(setq lis (cdr lis)))
lis)
@@ -4153,42 +4174,11 @@ Mail anyway? (y or n) ")
(key-description desc)
(format "M-x %s" func-def))))
-;; this uses comparison-func to decide who is a member, and this determines how
-;; intersection looks like
-(defun ediff-intersection (lis1 lis2 comparison-func)
- (let ((result (list 'a)))
- (while lis1
- (if (ediff-member (car lis1) lis2 comparison-func)
- (nconc result (list (car lis1))))
- (setq lis1 (cdr lis1)))
- (cdr result)))
-
-
-;; eliminates duplicates using comparison-func
-(defun ediff-union (lis1 lis2 comparison-func)
- (let ((result (list 'a)))
- (while lis1
- (or (ediff-member (car lis1) (cdr result) comparison-func)
- (nconc result (list (car lis1))))
- (setq lis1 (cdr lis1)))
- (while lis2
- (or (ediff-member (car lis2) (cdr result) comparison-func)
- (nconc result (list (car lis2))))
- (setq lis2 (cdr lis2)))
- (cdr result)))
-
-;; eliminates duplicates using comparison-func
-(defun ediff-set-difference (lis1 lis2 comparison-func)
- (let ((result (list 'a)))
- (while lis1
- (or (ediff-member (car lis1) (cdr result) comparison-func)
- (ediff-member (car lis1) lis2 comparison-func)
- (nconc result (list (car lis1))))
- (setq lis1 (cdr lis1)))
- (cdr result)))
-
(define-obsolete-function-alias 'ediff-add-to-history #'add-to-history "27.1")
(define-obsolete-function-alias 'ediff-copy-list #'copy-sequence "28.1")
+(define-obsolete-function-alias 'ediff-union #'seq-union "28.1")
+(define-obsolete-function-alias 'ediff-intersection #'seq-intersection "28.1")
+(define-obsolete-function-alias 'ediff-set-difference #'seq-difference "28.1")
(run-hooks 'ediff-load-hook)
diff --git a/lisp/vc/ediff-vers.el b/lisp/vc/ediff-vers.el
index 9e82392725d..0646ba3cc20 100644
--- a/lisp/vc/ediff-vers.el
+++ b/lisp/vc/ediff-vers.el
@@ -88,8 +88,8 @@ comparison or merge operations are being performed."
;; RCS.el support
(defun rcs-ediff-view-revision (&optional rev)
-;; View previous RCS revision of current file.
-;; With prefix argument, prompts for a revision name.
+ "View previous RCS revision of current file.
+With prefix argument, prompts for a revision name."
(interactive (list (if current-prefix-arg
(read-string "Revision: "))))
(let* ((filename (buffer-file-name (current-buffer)))
diff --git a/lisp/vc/ediff-wind.el b/lisp/vc/ediff-wind.el
index 7c90348b5d4..bc6aa288508 100644
--- a/lisp/vc/ediff-wind.el
+++ b/lisp/vc/ediff-wind.el
@@ -89,25 +89,25 @@ provided functions are written."
(function :tag "Other function"))
:version "24.3")
-;; indicates if we are in a multiframe setup
-(ediff-defvar-local ediff-multiframe nil "")
-
-;; Share of the frame occupied by the merge window (buffer C)
-(ediff-defvar-local ediff-merge-window-share 0.45 "")
-
-;; The control window.
-(ediff-defvar-local ediff-control-window nil "")
-;; Official window for buffer A
-(ediff-defvar-local ediff-window-A nil "")
-;; Official window for buffer B
-(ediff-defvar-local ediff-window-B nil "")
-;; Official window for buffer C
-(ediff-defvar-local ediff-window-C nil "")
-;; Official window for buffer Ancestor
-(ediff-defvar-local ediff-window-Ancestor nil "")
-;; Ediff's window configuration.
-;; Used to minimize the need to rearrange windows.
-(ediff-defvar-local ediff-window-config-saved "" "")
+(ediff-defvar-local ediff-multiframe nil
+ "Indicates if we are in a multiframe setup.")
+
+(ediff-defvar-local ediff-merge-window-share 0.45
+ "Share of the frame occupied by the merge window (buffer C).")
+
+(ediff-defvar-local ediff-control-window nil
+ "The control window.")
+(ediff-defvar-local ediff-window-A nil
+ "Official window for buffer A.")
+(ediff-defvar-local ediff-window-B nil
+ "Official window for buffer B.")
+(ediff-defvar-local ediff-window-C nil
+ "Official window for buffer C.")
+(ediff-defvar-local ediff-window-Ancestor nil
+ "Official window for buffer Ancestor.")
+(ediff-defvar-local ediff-window-config-saved ""
+ "Ediff's window configuration.
+Used to minimize the need to rearrange windows.")
;; Association between buff-type and ediff-window-*
(defconst ediff-window-alist
@@ -176,9 +176,9 @@ In this case, Ediff will use those frames to display these buffers."
"Frame parameters for displaying Ediff Control Panel.
Used internally---not a user option.")
-;; position of the mouse; used to decide whether to warp the mouse into ctl
-;; frame
-(ediff-defvar-local ediff-mouse-pixel-position nil "")
+(ediff-defvar-local ediff-mouse-pixel-position nil
+ "Position of the mouse.
+Used to decide whether to warp the mouse into control frame.")
;; not used for now
(defvar ediff-mouse-pixel-threshold 30
@@ -227,12 +227,10 @@ customization of the default."
;; Wide frame display
-;; t means Ediff is using wide display
-(ediff-defvar-local ediff-wide-display-p nil "")
-;; keeps frame config for toggling wide display
+(ediff-defvar-local ediff-wide-display-p nil
+ "If t, Ediff is using wide display.")
(ediff-defvar-local ediff-wide-display-orig-parameters nil
- "Frame parameters to be restored when the user wants to toggle the wide
-display off.")
+ "Frame parameters to restore when toggling the wide display off.")
(ediff-defvar-local ediff-wide-display-frame nil
"Frame to be used for wide display.")
(ediff-defvar-local ediff-make-wide-display-function #'ediff-make-wide-display
@@ -243,8 +241,8 @@ frame parameters in `ediff-wide-display-orig-parameters'.
The variable `ediff-wide-display-frame' should be set to contain
the frame used for the wide display.")
-;; Frame used for the control panel in a windowing system.
-(ediff-defvar-local ediff-control-frame nil "")
+(ediff-defvar-local ediff-control-frame nil
+ "Frame used for the control panel in a windowing system.")
(defcustom ediff-prefer-iconified-control-frame nil
"If t, keep control panel iconified when help message is off.
@@ -844,7 +842,7 @@ keyboard input to go into icons."
(defun ediff-skip-unsuitable-frames (&optional ok-unsplittable)
"Skip unsplittable frames and frames that have dedicated windows.
-create a new splittable frame if none is found."
+Create a new splittable frame if none is found."
(if (ediff-window-display-p)
(let ((wind-frame (window-frame))
seen-windows)
diff --git a/lisp/vc/ediff.el b/lisp/vc/ediff.el
index 3536cbf7381..cb4c8d93052 100644
--- a/lisp/vc/ediff.el
+++ b/lisp/vc/ediff.el
@@ -6,7 +6,7 @@
;; Created: February 2, 1994
;; Keywords: comparing, merging, patching, vc, tools, unix
;; Version: 2.81.6
-(defconst ediff-version "2.81.6" "The current version of Ediff")
+(defconst ediff-version "2.81.6" "The current version of Ediff.")
;; Yoni Rabkin <yoni@rabkins.net> contacted the maintainer of this
;; file on 20/3/2008, and the maintainer agreed that when a bug is
@@ -551,9 +551,11 @@ symbol describing the Ediff job type; it defaults to
;;;###autoload
(defun ediff-directories (dir1 dir2 regexp)
- "Run Ediff on a pair of directories, DIR1 and DIR2, comparing files that have
-the same name in both. The third argument, REGEXP, is nil or a regular
-expression; only file names that match the regexp are considered."
+ "Run Ediff on directories DIR1 and DIR2, comparing files.
+Consider only files that have the same name in both directories.
+
+REGEXP is nil or a regular expression; only file names that match
+the regexp are considered."
(interactive
(let ((dir-A (ediff-get-default-directory-name))
(default-regexp (eval ediff-default-filtering-regexp t))
@@ -608,10 +610,11 @@ names. Only the files that are under revision control are taken into account."
;;;###autoload
(defun ediff-directories3 (dir1 dir2 dir3 regexp)
- "Run Ediff on three directories, DIR1, DIR2, and DIR3, comparing files that
-have the same name in all three. The last argument, REGEXP, is nil or a
-regular expression; only file names that match the regexp are considered."
+ "Run Ediff on directories DIR1, DIR2, and DIR3, comparing files.
+Consider only files that have the same name in all three directories.
+REGEXP is nil or a regular expression; only file names that match
+the regexp are considered."
(interactive
(let ((dir-A (ediff-get-default-directory-name))
(default-regexp (eval ediff-default-filtering-regexp t))
@@ -677,7 +680,7 @@ MERGE-AUTOSTORE-DIR is the directory in which to store merged files."
(defun ediff-merge-directories-with-ancestor (dir1 dir2 ancestor-dir regexp
&optional
merge-autostore-dir)
- "Merge files in directories DIR1 and DIR2 using files in ANCESTOR-DIR as ancestors.
+ "Merge files in DIR1 and DIR2 using files in ANCESTOR-DIR as ancestors.
Ediff merges files that have identical names in DIR1, DIR2. If a pair of files
in DIR1 and DIR2 doesn't have an ancestor in ANCESTOR-DIR, Ediff will merge
without ancestor. The fourth argument, REGEXP, is nil or a regular expression;
@@ -743,7 +746,7 @@ MERGE-AUTOSTORE-DIR is the directory in which to store merged files."
(defun ediff-merge-directory-revisions-with-ancestor (dir1 regexp
&optional
merge-autostore-dir)
- "Run Ediff on a directory, DIR1, merging its files with their revisions and ancestors.
+ "Run Ediff on DIR1 and merge its files with their revisions and ancestors.
The second argument, REGEXP, is a regular expression that filters the file
names. Only the files that are under revision control are taken into account.
MERGE-AUTOSTORE-DIR is the directory in which to store merged files."
@@ -980,9 +983,9 @@ STARTUP-HOOKS is a list of functions that Emacs calls without
arguments after setting up the Ediff buffers."
(interactive
(let (bf)
- (list (setq bf (read-buffer "Region's A buffer: "
+ (list (setq bf (read-buffer "Region A's buffer: "
(ediff-other-buffer "") t))
- (read-buffer "Region's B buffer: "
+ (read-buffer "Region B's buffer: "
(progn
;; realign buffers so that two visible bufs will be
;; at the top
@@ -1555,7 +1558,9 @@ With optional NODE, goes to that node."
(info "ediff")
(if node
(Info-goto-node node)
- (message "Type `i' to search for a specific topic"))
+ (message (substitute-command-keys
+ (concat "Type \\<Info-mode-map>\\[Info-index] to"
+ " search for a specific topic"))))
(raise-frame))
(error (beep 1)
(with-output-to-temp-buffer ediff-msg-buffer
@@ -1597,7 +1602,7 @@ With optional NODE, goes to that node."
;;;###autoload
(defun ediff-merge-with-ancestor-command ()
- "Call `ediff-merge-files-with-ancestor' with the next three command line arguments."
+ "Call `ediff-merge-files-with-ancestor' with next three command line arguments."
(let ((file-a (nth 0 command-line-args-left))
(file-b (nth 1 command-line-args-left))
(ancestor (nth 2 command-line-args-left)))
@@ -1634,7 +1639,8 @@ With optional NODE, goes to that node."
;;;###autoload
(defun ediff-merge-directories-with-ancestor-command ()
- "Call `ediff-merge-directories-with-ancestor' with the next four command line arguments."
+ "Call `ediff-merge-directories-with-ancestor' with the next four command line
+arguments."
(let ((file-a (nth 0 command-line-args-left))
(file-b (nth 1 command-line-args-left))
(ancestor (nth 2 command-line-args-left))
diff --git a/lisp/vc/emerge.el b/lisp/vc/emerge.el
index 8f7affeea4e..b2fdb07d5fb 100644
--- a/lisp/vc/emerge.el
+++ b/lisp/vc/emerge.el
@@ -26,15 +26,18 @@
;;; Macros
-(defmacro emerge-defvar-local (var value doc)
+(defmacro emerge-defvar-local (symbol value &optional doc)
"Define SYMBOL as an advertised buffer-local variable.
-Performs a defvar, then executes `make-variable-buffer-local' on
-the variable. Also sets the `permanent-local' property, so that
-`kill-all-local-variables' (called by major-mode setting commands)
-won't destroy Emerge control variables."
+Run `defvar-local', setting the value of the variable to VALUE
+and its docstring to DOC.
+
+Then set the `permanent-local' property, so that
+`kill-all-local-variables' (called by major-mode setting
+commands) won't destroy Emerge control variables."
+ (declare (indent defun) (doc-string 3))
`(progn
- (defvar-local ,var ,value ,doc)
- (put ',var 'permanent-local t)))
+ (defvar-local ,symbol ,value ,doc)
+ (put ',symbol 'permanent-local t)))
;; We need to define this function so describe-mode can describe Emerge mode.
(define-minor-mode emerge-mode
@@ -217,8 +220,7 @@ depend on the flags."
(emerge-new-flags)
(defcustom emerge-min-visible-lines 3
- "Number of lines that we want to show above and below the flags when we are
-displaying a difference."
+ "Number of lines to show above and below the flags when displaying a difference."
:type 'integer)
(defcustom emerge-temp-file-prefix
@@ -434,8 +436,7 @@ or nil if there is none.")
'((buffer-modified-p set-buffer-modified-p)
buffer-read-only
buffer-auto-save-file-name)
- "Variables and properties of a buffer which are saved, modified and restored
-during a merge.")
+ "Variables and properties of a buffer to save, modify and restore during a merge.")
(defconst emerge-merging-values '(nil t nil)
"Values to be assigned to emerge-saved-variables during a merge.")
@@ -481,10 +482,10 @@ replaced by emerge-fast-keymap.")
(emerge-defvar-local emerge-old-keymap nil
"The original local keymap for the merge buffer.")
(emerge-defvar-local emerge-auto-advance nil
- "If non-nil, emerge-select-A and emerge-select-B automatically advance to
+ "If non-nil, emerge-select-A and emerge-select-B automatically advance to
the next difference.")
(emerge-defvar-local emerge-skip-prefers nil
- "If non-nil, differences for which there is a preference are automatically
+ "If non-nil, differences for which there is a preference are automatically
skipped.")
(emerge-defvar-local emerge-quit-hook nil
"Hooks to run in the merge buffer after the merge has been finished.
@@ -825,7 +826,7 @@ This is *not* a user option, since Emerge uses it for its own processing.")
;;;###autoload
(defun emerge-files (_arg file-A file-B file-out &optional startup-hooks
quit-hooks)
- "Run Emerge on two files."
+ "Run Emerge on two files FILE-A and FILE-B."
(interactive
(let (f)
(list current-prefix-arg
@@ -874,7 +875,7 @@ This is *not* a user option, since Emerge uses it for its own processing.")
;;;###autoload
(defun emerge-buffers (buffer-A buffer-B &optional startup-hooks quit-hooks)
- "Run Emerge on two buffers."
+ "Run Emerge on two buffers BUFFER-A and BUFFER-B."
(interactive "bBuffer A to merge: \nbBuffer B to merge: ")
(let ((emerge-file-A (emerge-make-temp-file "A"))
(emerge-file-B (emerge-make-temp-file "B")))
@@ -1773,15 +1774,15 @@ BEG must be at the beginning of a line."
(emerge-unselect-and-select-difference n)))
(error "At beginning")))
-(defun emerge-jump-to-difference (difference-number)
- "Go to the N-th difference."
+(defun emerge-jump-to-difference (n)
+ "Go to difference number N."
(interactive "p")
(let ((inhibit-read-only t))
- (setq difference-number (1- difference-number))
- (if (and (>= difference-number -1)
- (< difference-number (1+ emerge-number-of-differences)))
- (emerge-unselect-and-select-difference difference-number)
- (error "Bad difference number"))))
+ (setq n (1- n))
+ (if (and (>= n -1)
+ (< n (1+ emerge-number-of-differences)))
+ (emerge-unselect-and-select-difference n)
+ (error "Bad difference number: %s" n))))
(defun emerge-abort ()
"Abort the Emerge session."
@@ -1790,7 +1791,7 @@ BEG must be at the beginning of a line."
(defun emerge-quit (arg)
"Finish the Emerge session and exit Emerge.
-Prefix argument means to abort rather than successfully finish.
+Prefix argument ARG means to abort rather than successfully finish.
The difference depends on how the merge was started,
but usually means to not write over one of the original files, or to signal
to some process which invoked Emerge a failure code.
@@ -1849,7 +1850,7 @@ buffer after this will cause serious problems."
"Select the A variant of this difference.
Refuses to function if this difference has been edited, i.e., if it
is neither the A nor the B variant.
-A prefix argument forces the variant to be selected
+With prefix argument FORCE, force the variant to be selected
even if the difference has been edited."
(interactive "P")
(let ((operate #'emerge-select-A-edit)
@@ -1876,7 +1877,7 @@ even if the difference has been edited."
"Select the B variant of this difference.
Refuses to function if this difference has been edited, i.e., if it
is neither the A nor the B variant.
-A prefix argument forces the variant to be selected
+With prefix argument FORCE, force the variant to be selected
even if the difference has been edited."
(interactive "P")
(let ((operate #'emerge-select-B-edit)
@@ -1973,8 +1974,8 @@ must be prefixed with \\<emerge-fast-keymap>\\[emerge-basic-keymap]."
"Toggle Auto-Advance mode, for Emerge.
This mode causes `emerge-select-A' and `emerge-select-B' to automatically
advance to the next difference.
-With a positive argument, turn on Auto-Advance mode.
-With a negative argument, turn off Auto-Advance mode."
+With a positive argument ARG, turn on Auto-Advance mode.
+With a negative argument ARG, turn off Auto-Advance mode."
(interactive "P")
(setq emerge-auto-advance (if (null arg)
(not emerge-auto-advance)
@@ -1988,8 +1989,8 @@ With a negative argument, turn off Auto-Advance mode."
"Toggle Skip-Prefers mode, for Emerge.
This mode causes `emerge-next-difference' and `emerge-previous-difference'
to automatically skip over differences for which there is a preference.
-With a positive argument, turn on Skip-Prefers mode.
-With a negative argument, turn off Skip-Prefers mode."
+With a positive argument ARG, turn on Skip-Prefers mode.
+With a negative argument ARG, turn off Skip-Prefers mode."
(interactive "P")
(setq emerge-skip-prefers (if (null arg)
(not emerge-skip-prefers)
@@ -2028,7 +2029,7 @@ With a negative argument, turn off Skip-Prefers mode."
(defun emerge-insert-A (arg)
"Insert the A variant of this difference at the point.
Leaves point after text, mark before.
-With prefix argument, puts point before, mark after."
+With prefix argument ARG, puts point before, mark after."
(interactive "P")
(emerge-validate-difference)
(let* ((diff-vector
@@ -2046,7 +2047,7 @@ With prefix argument, puts point before, mark after."
(defun emerge-insert-B (arg)
"Insert the B variant of this difference at the point.
Leaves point after text, mark before.
-With prefix argument, puts point before, mark after."
+With prefix argument ARG, puts point before, mark after."
(interactive "P")
(emerge-validate-difference)
(let* ((diff-vector
@@ -2062,8 +2063,8 @@ With prefix argument, puts point before, mark after."
(goto-char opoint))))
(defun emerge-mark-difference (arg)
- "Leaves the point before this difference and the mark after it.
-With prefix argument, puts mark before, point after."
+ "Leave the point before this difference and the mark after it.
+With prefix argument ARG, put mark before, point after."
(interactive "P")
(emerge-validate-difference)
(let* ((diff-vector
@@ -2079,7 +2080,7 @@ With prefix argument, puts mark before, point after."
(defun emerge-file-names ()
"Show the names of the buffers or files being operated on by Emerge.
-Use C-u l to reset the windows afterward."
+Use \\[universal-argument] l to reset the windows afterward."
(interactive)
(delete-other-windows)
(let ((temp-buffer-show-function
@@ -2122,7 +2123,7 @@ Use C-u l to reset the windows afterward."
(defun emerge-join-differences (arg)
"Join the selected difference with the following one.
-With a prefix argument, join with the preceding one."
+With a prefix argument ARG, join with the preceding one."
(interactive "P")
(let ((n emerge-current-difference))
;; adjust n to be first difference to join
@@ -2332,9 +2333,9 @@ ancestor version does not share.)"
;; to have it ask for a buffer.
(defun emerge-find-difference (arg)
"Find the difference containing the current position of the point.
-If there is no containing difference and the prefix argument is positive,
-it finds the nearest following difference. A negative prefix argument finds
-the nearest previous difference."
+If there is no containing difference and the prefix argument ARG
+is positive, find the nearest following difference. With
+negative prefix argument, find the nearest previous difference."
(interactive "P")
(cond ((eq (current-buffer) emerge-A-buffer)
(emerge-find-difference-A arg))
@@ -2344,9 +2345,9 @@ the nearest previous difference."
(defun emerge-find-difference-merge (arg)
"Find the difference containing point, in the merge buffer.
-If there is no containing difference and the prefix argument is positive,
-it finds the nearest following difference. A negative prefix argument finds
-the nearest previous difference."
+If there is no containing difference and the prefix argument ARG
+is positive, find the nearest following difference. With
+negative prefix argument, find the nearest previous difference."
(interactive "P")
;; search for the point in the merge buffer, using the markers
;; for the beginning and end of the differences in the merge buffer
@@ -2355,9 +2356,9 @@ the nearest previous difference."
(defun emerge-find-difference-A (arg)
"Find the difference containing point, in the A buffer.
This command must be executed in the merge buffer.
-If there is no containing difference and the prefix argument is positive,
-it finds the nearest following difference. A negative prefix argument finds
-the nearest previous difference."
+If there is no containing difference and the prefix argument ARG
+is positive, find the nearest following difference. With
+negative prefix argument, find the nearest previous difference."
(interactive "P")
;; search for the point in the A buffer, using the markers
;; for the beginning and end of the differences in the A buffer
@@ -2368,9 +2369,9 @@ the nearest previous difference."
(defun emerge-find-difference-B (arg)
"Find the difference containing point, in the B buffer.
This command must be executed in the merge buffer.
-If there is no containing difference and the prefix argument is positive,
-it finds the nearest following difference. A negative prefix argument finds
-the nearest previous difference."
+If there is no containing difference and the prefix argument ARG
+is positive, find the nearest following difference. With
+negative prefix argument, find the nearest previous difference."
(interactive "P")
;; search for the point in the B buffer, using the markers
;; for the beginning and end of the differences in the B buffer
@@ -2450,8 +2451,10 @@ merge buffers."
(defun emerge-set-combine-template (string &optional localize)
"Set `emerge-combine-versions-template' to STRING.
This value controls how `emerge-combine-versions' combines the two versions.
-With prefix argument, `emerge-combine-versions-template' is made local to this
-merge buffer. Localization is permanent for any particular merge buffer."
+
+With prefix argument LOCALIZE, `emerge-combine-versions-template'
+is made local to this merge buffer. Localization is permanent
+for any particular merge buffer."
(interactive "s\nP")
(if localize
(make-local-variable 'emerge-combine-versions-template))
@@ -2464,8 +2467,10 @@ merge buffer. Localization is permanent for any particular merge buffer."
(defun emerge-set-combine-versions-template (start end &optional localize)
"Copy region into `emerge-combine-versions-template'.
This controls how `emerge-combine-versions' will combine the two versions.
-With prefix argument, `emerge-combine-versions-template' is made local to this
-merge buffer. Localization is permanent for any particular merge buffer."
+
+With prefix argument LOCALIZE, `emerge-combine-versions-template'
+is made local to this merge buffer. Localization is permanent
+for any particular merge buffer."
(interactive "r\nP")
(if localize
(make-local-variable 'emerge-combine-versions-template))
@@ -2479,8 +2484,9 @@ merge buffer. Localization is permanent for any particular merge buffer."
"Combine versions using the template in `emerge-combine-versions-template'.
Refuses to function if this difference has been edited, i.e., if it is
neither the A nor the B variant.
-An argument forces the variant to be selected even if the difference has
-been edited."
+
+With prefix argument FORCE, force the variant to be selected even
+if the difference has been edited."
(interactive "P")
(emerge-combine-versions-internal emerge-combine-versions-template force))
@@ -2490,8 +2496,9 @@ See documentation of the variable `emerge-combine-versions-template'
for how the template is interpreted.
Refuses to function if this difference has been edited, i.e., if it is
neither the A nor the B variant.
-An argument forces the variant to be selected even if the difference has
-been edited.
+
+With prefix argument CHAR, force the variant to be selected even
+if the difference has been edited.
Interactively, reads the register using `register-read-with-preview'."
(interactive (list
@@ -2539,9 +2546,9 @@ Interactively, reads the register using `register-read-with-preview'."
(if emerge-auto-advance (emerge-next-difference))))
(defun emerge-set-merge-mode (mode)
- "Set the major mode in a merge buffer.
-Overrides any change that the mode might make to the mode line or local
-keymap. Leaves merge in fast mode."
+ "Set the major mode to MODE in a merge buffer.
+Override any change that the mode might make to the mode line or
+local keymap. Leave merge in fast mode."
(interactive
(list (intern (completing-read "New major mode for merge buffer: "
obarray 'commandp t nil))))
@@ -2678,8 +2685,8 @@ keymap. Leaves merge in fast mode."
(emerge-refresh-mode-line))))
(defun emerge-select-version (force a-version b-version neither-version)
- "Perform tests to see whether user should be allowed to select a version
-of this difference:
+ "Test if user should be allowed to select a version of this difference.
+This is the case if:
a valid difference has been selected; and
the difference text in the merge buffer is:
the A version (execute a-version), or
@@ -2847,7 +2854,9 @@ Otherwise, signal an error."
;; When the pointless option emerge-temp-file-prefix goes,
;; make this function obsolete too, and just use make-temp-file.
(defun emerge-make-temp-file (prefix)
- "Make a private temporary file based on `emerge-temp-file-prefix'."
+ "Make a private temporary file based on PREFIX.
+This is named by concatenating `emerge-temp-file-prefix' with
+PREFIX."
(make-temp-file (concat emerge-temp-file-prefix prefix)))
;;; Functions that query the user before he can write out the current buffer.
@@ -2921,7 +2930,7 @@ around the current difference are removed."
;; Define a key, even if a prefix of it is defined
(defun emerge-force-define-key (keymap key definition)
- "Like `define-key', but forcibly creates prefix characters as needed.
+ "Like `define-key', but forcibly create prefix characters as needed.
If some prefix of KEY has a non-prefix definition, it is redefined."
;; Find out if a prefix of key is defined
(let ((v (lookup-key keymap key)))
diff --git a/lisp/vc/log-edit.el b/lisp/vc/log-edit.el
index 46e9c97eb0a..6e3f302263b 100644
--- a/lisp/vc/log-edit.el
+++ b/lisp/vc/log-edit.el
@@ -54,21 +54,19 @@
(define-obsolete-variable-alias 'vc-log-mode-map 'log-edit-mode-map "28.1")
(define-obsolete-variable-alias 'vc-log-entry-mode 'log-edit-mode-map "28.1")
-(easy-mmode-defmap log-edit-mode-map
- '(("\C-c\C-c" . log-edit-done)
- ("\C-c\C-a" . log-edit-insert-changelog)
- ("\C-c\C-w" . log-edit-generate-changelog-from-diff)
- ("\C-c\C-d" . log-edit-show-diff)
- ("\C-c\C-f" . log-edit-show-files)
- ("\C-c\C-k" . log-edit-kill-buffer)
- ("\C-a" . log-edit-beginning-of-line)
- ("\M-n" . log-edit-next-comment)
- ("\M-p" . log-edit-previous-comment)
- ("\M-r" . log-edit-comment-search-backward)
- ("\M-s" . log-edit-comment-search-forward)
- ("\C-c?" . log-edit-mode-help))
- "Keymap for the `log-edit-mode' (to edit version control log messages)."
- :group 'log-edit)
+(defvar-keymap log-edit-mode-map
+ "C-c C-c" #'log-edit-done
+ "C-c C-a" #'log-edit-insert-changelog
+ "C-c C-w" #'log-edit-generate-changelog-from-diff
+ "C-c C-d" #'log-edit-show-diff
+ "C-c C-f" #'log-edit-show-files
+ "C-c C-k" #'log-edit-kill-buffer
+ "C-a" #'log-edit-beginning-of-line
+ "M-n" #'log-edit-next-comment
+ "M-p" #'log-edit-previous-comment
+ "M-r" #'log-edit-comment-search-backward
+ "M-s" #'log-edit-comment-search-forward
+ "C-c ?" #'log-edit-mode-help)
(easy-menu-define log-edit-menu log-edit-mode-map
"Menu used for `log-edit-mode'."
@@ -98,7 +96,7 @@
(defcustom log-edit-confirm 'changed
"If non-nil, `log-edit-done' will request confirmation.
If `changed', only request confirmation if the list of files has
- changed since the beginning of the log-edit session."
+ changed since the beginning of the `log-edit' session."
:group 'log-edit
:type '(choice (const changed) (const t) (const nil)))
@@ -497,7 +495,7 @@ When done editing the log entry, type \\[log-edit-done], which will
trigger the actual commit of the file(s).
Several other handy support commands are provided, and the package
from which this is used might also provide additional commands (under
-the \"C-x v\" prefix for VC commands, for example).
+the \\[vc-prefix-map] prefix for VC commands, for example).
\\{log-edit-mode-map}"
(setq-local font-lock-defaults '(log-edit-font-lock-keywords t))
@@ -891,7 +889,7 @@ name or time."
Actually, the narrowed region doesn't include the date line.
A \"page\" in a ChangeLog file is the area between two dates."
(or (eq major-mode 'change-log-mode)
- (error "log-edit-narrow-changelog: current buffer isn't a ChangeLog"))
+ (error "log-edit-narrow-changelog: Current buffer isn't a ChangeLog"))
(goto-char (point-min))
diff --git a/lisp/vc/log-view.el b/lisp/vc/log-view.el
index e8930979b5d..d45c1696a2f 100644
--- a/lisp/vc/log-view.el
+++ b/lisp/vc/log-view.el
@@ -50,7 +50,7 @@
;; ------------------------------------------------------------------------
;; r4622 | ckuethe | 2007-12-23 18:18:01 -0500 (Sun, 23 Dec 2007) | 2 lines
;;
-;; uBlox AEK-4T in binary mode. Added to unstable because it breaks gpsfake
+;; uBlox AEK-4T in binary mode. Added to unstable because it breaks gpsfake
;;
;; ------------------------------------------------------------------------
;; r4621 | ckuethe | 2007-12-23 16:48:11 -0500 (Sun, 23 Dec 2007) | 3 lines
@@ -110,6 +110,7 @@
;;; Code:
(require 'pcvs-util)
+(require 'easy-mmode)
(autoload 'vc-find-revision "vc")
(autoload 'vc-diff-internal "vc")
@@ -121,42 +122,26 @@
:group 'pcl-cvs
:prefix "log-view-")
-(easy-mmode-defmap log-view-mode-map
- '(
- ("-" . negative-argument)
- ("0" . digit-argument)
- ("1" . digit-argument)
- ("2" . digit-argument)
- ("3" . digit-argument)
- ("4" . digit-argument)
- ("5" . digit-argument)
- ("6" . digit-argument)
- ("7" . digit-argument)
- ("8" . digit-argument)
- ("9" . digit-argument)
-
- ("\C-m" . log-view-toggle-entry-display)
- ("m" . log-view-toggle-mark-entry)
- ("e" . log-view-modify-change-comment)
- ("d" . log-view-diff)
- ("=" . log-view-diff)
- ("D" . log-view-diff-changeset)
- ("a" . log-view-annotate-version)
- ("f" . log-view-find-revision)
- ("n" . log-view-msg-next)
- ("p" . log-view-msg-prev)
- ("\t" . log-view-msg-next)
- ([backtab] . log-view-msg-prev)
- ("N" . log-view-file-next)
- ("P" . log-view-file-prev)
- ("\M-n" . log-view-file-next)
- ("\M-p" . log-view-file-prev))
- "Log-View's keymap."
- :inherit special-mode-map
- :group 'log-view)
+(defvar-keymap log-view-mode-map
+ "RET" #'log-view-toggle-entry-display
+ "m" #'log-view-toggle-mark-entry
+ "e" #'log-view-modify-change-comment
+ "d" #'log-view-diff
+ "=" #'log-view-diff
+ "D" #'log-view-diff-changeset
+ "a" #'log-view-annotate-version
+ "f" #'log-view-find-revision
+ "n" #'log-view-msg-next
+ "p" #'log-view-msg-prev
+ "TAB" #'log-view-msg-next
+ "<backtab>" #'log-view-msg-prev
+ "N" #'log-view-file-next
+ "P" #'log-view-file-prev
+ "M-n" #'log-view-file-next
+ "M-p" #'log-view-file-prev)
(easy-menu-define log-view-mode-menu log-view-mode-map
- "Log-View Display Menu"
+ "Log-View Display Menu."
'("Log-View"
;; XXX Do we need menu entries for these?
;; ["Quit" quit-window]
diff --git a/lisp/vc/pcvs-defs.el b/lisp/vc/pcvs-defs.el
index 54ef06960f9..c3109f7e85b 100644
--- a/lisp/vc/pcvs-defs.el
+++ b/lisp/vc/pcvs-defs.el
@@ -264,160 +264,6 @@ This variable is buffer local and only used in the *cvs* buffer.")
(defconst cvs-vendor-branch "1.1.1"
"The default branch used by CVS for vendor code.")
-(easy-mmode-defmap cvs-mode-diff-map
- '(("E" "imerge" . cvs-mode-imerge)
- ("=" . cvs-mode-diff)
- ("e" "idiff" . cvs-mode-idiff)
- ("2" "other" . cvs-mode-idiff-other)
- ("d" "diff" . cvs-mode-diff)
- ("b" "backup" . cvs-mode-diff-backup)
- ("h" "head" . cvs-mode-diff-head)
- ("r" "repository" . cvs-mode-diff-repository)
- ("y" "yesterday" . cvs-mode-diff-yesterday)
- ("v" "vendor" . cvs-mode-diff-vendor))
- "Keymap for diff-related operations in `cvs-mode'."
- :name "Diff")
-;; This is necessary to allow correct handling of \\[cvs-mode-diff-map]
-;; in substitute-command-keys.
-(fset 'cvs-mode-diff-map cvs-mode-diff-map)
-
-(easy-mmode-defmap cvs-mode-map
- ;;(define-prefix-command 'cvs-mode-map-diff-prefix)
- ;;(define-prefix-command 'cvs-mode-map-control-c-prefix)
- '(;; various
- ;; (undo . cvs-mode-undo)
- ("?" . cvs-help)
- ("h" . cvs-help)
- ("q" . cvs-bury-buffer)
- ("z" . kill-this-buffer)
- ("F" . cvs-mode-set-flags)
- ;; ("\M-f" . cvs-mode-force-command)
- ("!" . cvs-mode-force-command)
- ("\C-c\C-c" . cvs-mode-kill-process)
- ;; marking
- ("m" . cvs-mode-mark)
- ("M" . cvs-mode-mark-all-files)
- ("S" . cvs-mode-mark-on-state)
- ("u" . cvs-mode-unmark)
- ("\C-?". cvs-mode-unmark-up)
- ("%" . cvs-mode-mark-matching-files)
- ("T" . cvs-mode-toggle-marks)
- ("\M-\C-?" . cvs-mode-unmark-all-files)
- ;; navigation keys
- (" " . cvs-mode-next-line)
- ("n" . cvs-mode-next-line)
- ("p" . cvs-mode-previous-line)
- ("\t" . cvs-mode-next-line)
- ([backtab] . cvs-mode-previous-line)
- ;; M- keys are usually those that operate on modules
- ;;("\M-C". cvs-mode-rcs2log) ; i.e. "Create a ChangeLog"
- ;;("\M-t". cvs-rtag)
- ;;("\M-l". cvs-rlog)
- ("\M-c". cvs-checkout)
- ("\M-e". cvs-examine)
- ("g" . cvs-mode-revert-buffer)
- ("\M-u". cvs-update)
- ("\M-s". cvs-status)
- ;; diff commands
- ("=" . cvs-mode-diff)
- ("d" . cvs-mode-diff-map)
- ;; keys that operate on individual files
- ("\C-k" . cvs-mode-acknowledge)
- ("A" . cvs-mode-add-change-log-entry-other-window)
- ;;("B" . cvs-mode-byte-compile-files)
- ("C" . cvs-mode-commit-setup)
- ("O" . cvs-mode-update)
- ("U" . cvs-mode-undo)
- ("I" . cvs-mode-insert)
- ("a" . cvs-mode-add)
- ("b" . cvs-set-branch-prefix)
- ("B" . cvs-set-secondary-branch-prefix)
- ("c" . cvs-mode-commit)
- ("e" . cvs-mode-examine)
- ("f" . cvs-mode-find-file)
- ("\C-m" . cvs-mode-find-file)
- ("i" . cvs-mode-ignore)
- ("l" . cvs-mode-log)
- ("o" . cvs-mode-find-file-other-window)
- ("r" . cvs-mode-remove)
- ("s" . cvs-mode-status)
- ("t" . cvs-mode-tag)
- ("v" . cvs-mode-view-file)
- ("x" . cvs-mode-remove-handled)
- ;; cvstree bindings
- ("+" . cvs-mode-tree)
- ;; mouse bindings
- ([mouse-2] . cvs-mode-find-file)
- ([follow-link] . (lambda (pos)
- (if (eq (get-char-property pos 'face) 'cvs-filename) t)))
- ([(down-mouse-3)] . cvs-menu)
- ;; dired-like bindings
- ("\C-o" . cvs-mode-display-file)
- ;; Emacs-21 toolbar
- ;;([tool-bar item1] . (menu-item "Examine" cvs-examine :image (image :file "/usr/share/icons/xpaint.xpm" :type xpm)))
- ;;([tool-bar item2] . (menu-item "Update" cvs-update :image (image :file "/usr/share/icons/mail1.xpm" :type xpm)))
- )
- "Keymap for `cvs-mode'."
- :dense t
- :suppress t)
-
-(fset 'cvs-mode-map cvs-mode-map)
-
-(easy-menu-define cvs-menu cvs-mode-map "Menu used in `cvs-mode'."
- '("CVS"
- ["Open file" cvs-mode-find-file t]
- ["Open in other window" cvs-mode-find-file-other-window t]
- ["Display in other window" cvs-mode-display-file t]
- ["Interactive merge" cvs-mode-imerge t]
- ("View diff"
- ["Interactive diff" cvs-mode-idiff t]
- ["Current diff" cvs-mode-diff t]
- ["Diff with head" cvs-mode-diff-head t]
- ["Diff with vendor" cvs-mode-diff-vendor t]
- ["Diff against yesterday" cvs-mode-diff-yesterday t]
- ["Diff with backup" cvs-mode-diff-backup t])
- ["View log" cvs-mode-log t]
- ["View status" cvs-mode-status t]
- ["View tag tree" cvs-mode-tree t]
- "----"
- ["Insert" cvs-mode-insert]
- ["Update" cvs-mode-update (cvs-enabledp 'update)]
- ["Re-examine" cvs-mode-examine t]
- ["Commit" cvs-mode-commit-setup (cvs-enabledp 'commit)]
- ["Tag" cvs-mode-tag (cvs-enabledp (when cvs-force-dir-tag 'tag))]
- ["Undo changes" cvs-mode-undo (cvs-enabledp 'undo)]
- ["Add" cvs-mode-add (cvs-enabledp 'add)]
- ["Remove" cvs-mode-remove (cvs-enabledp 'remove)]
- ["Ignore" cvs-mode-ignore (cvs-enabledp 'ignore)]
- ["Add ChangeLog" cvs-mode-add-change-log-entry-other-window t]
- "----"
- ["Mark" cvs-mode-mark t]
- ["Mark all" cvs-mode-mark-all-files t]
- ["Mark by regexp..." cvs-mode-mark-matching-files t]
- ["Mark by state..." cvs-mode-mark-on-state t]
- ["Unmark" cvs-mode-unmark t]
- ["Unmark all" cvs-mode-unmark-all-files t]
- ["Hide handled" cvs-mode-remove-handled t]
- "----"
- ["PCL-CVS Manual" (lambda () (interactive)
- (info "(pcl-cvs)Top")) t]
- "----"
- ["Quit" cvs-mode-quit t]))
-
-;;;;
-;;;; CVS-Minor mode
-;;;;
-
-(defcustom cvs-minor-mode-prefix "\C-xc"
- "Prefix key for the `cvs-mode' bindings in `cvs-minor-mode'."
- :type 'string)
-
-(easy-mmode-defmap cvs-minor-mode-map
- `((,cvs-minor-mode-prefix . cvs-mode-map)
- ("e" . (menu-item nil cvs-mode-edit-log
- :filter (lambda (x) (if (derived-mode-p 'log-view-mode) x)))))
- "Keymap for `cvs-minor-mode', used in buffers related to PCL-CVS.")
-
(defvar cvs-buffer nil
"(Buffer local) The *cvs* buffer associated with this buffer.")
(put 'cvs-buffer 'permanent-local t)
diff --git a/lisp/vc/pcvs.el b/lisp/vc/pcvs.el
index 42f531e4f75..2d7b8cb2ef7 100644
--- a/lisp/vc/pcvs.el
+++ b/lisp/vc/pcvs.el
@@ -117,11 +117,11 @@
(require 'cl-lib)
(require 'ewoc) ;Ewoc was once cookie
-(require 'pcvs-defs)
(require 'pcvs-util)
(require 'pcvs-parse)
(require 'pcvs-info)
(require 'vc-cvs)
+(require 'easy-mmode)
;;;;
@@ -138,6 +138,147 @@
(defvar cvs-from-vc nil "Bound to t inside VC advice.")
+(defvar-keymap cvs-mode-diff-map
+ :name "Diff"
+ "E" (cons "imerge" #'cvs-mode-imerge)
+ "=" #'cvs-mode-diff
+ "e" (cons "idiff" #'cvs-mode-idiff)
+ "2" (cons "other" #'cvs-mode-idiff-other)
+ "d" (cons "diff" #'cvs-mode-diff)
+ "b" (cons "backup" #'cvs-mode-diff-backup)
+ "h" (cons "head" #'cvs-mode-diff-head)
+ "r" (cons "repository" #'cvs-mode-diff-repository)
+ "y" (cons "yesterday" #'cvs-mode-diff-yesterday)
+ "v" (cons "vendor" #'cvs-mode-diff-vendor))
+;; This is necessary to allow correct handling of \\[cvs-mode-diff-map]
+;; in substitute-command-keys.
+(fset 'cvs-mode-diff-map cvs-mode-diff-map)
+
+(defvar-keymap cvs-mode-map
+ :full t
+ :suppress t
+ ;; various
+ "?" #'cvs-help
+ "h" #'cvs-help
+ "q" #'cvs-bury-buffer
+ "z" #'kill-this-buffer
+ "F" #'cvs-mode-set-flags
+ "!" #'cvs-mode-force-command
+ "C-c C-c" #'cvs-mode-kill-process
+ ;; marking
+ "m" #'cvs-mode-mark
+ "M" #'cvs-mode-mark-all-files
+ "S" #'cvs-mode-mark-on-state
+ "u" #'cvs-mode-unmark
+ "DEL" #'cvs-mode-unmark-up
+ "%" #'cvs-mode-mark-matching-files
+ "T" #'cvs-mode-toggle-marks
+ "M-DEL" #'cvs-mode-unmark-all-files
+ ;; navigation keys
+ "SPC" #'cvs-mode-next-line
+ "n" #'cvs-mode-next-line
+ "p" #'cvs-mode-previous-line
+ "TAB" #'cvs-mode-next-line
+ "<backtab>" #'cvs-mode-previous-line
+ ;; M- keys are usually those that operate on modules
+ "M-c" #'cvs-checkout
+ "M-e" #'cvs-examine
+ "g" #'cvs-mode-revert-buffer
+ "M-u" #'cvs-update
+ "M-s" #'cvs-status
+ ;; diff commands
+ "=" #'cvs-mode-diff
+ "d" cvs-mode-diff-map
+ ;; keys that operate on individual files
+ "C-k" #'cvs-mode-acknowledge
+ "A" #'cvs-mode-add-change-log-entry-other-window
+ "C" #'cvs-mode-commit-setup
+ "O" #'cvs-mode-update
+ "U" #'cvs-mode-undo
+ "I" #'cvs-mode-insert
+ "a" #'cvs-mode-add
+ "b" #'cvs-set-branch-prefix
+ "B" #'cvs-set-secondary-branch-prefix
+ "c" #'cvs-mode-commit
+ "e" #'cvs-mode-examine
+ "f" #'cvs-mode-find-file
+ "RET" #'cvs-mode-find-file
+ "i" #'cvs-mode-ignore
+ "l" #'cvs-mode-log
+ "o" #'cvs-mode-find-file-other-window
+ "r" #'cvs-mode-remove
+ "s" #'cvs-mode-status
+ "t" #'cvs-mode-tag
+ "v" #'cvs-mode-view-file
+ "x" #'cvs-mode-remove-handled
+ ;; cvstree bindings
+ "+" #'cvs-mode-tree
+ ;; mouse bindings
+ "<mouse-2>" #'cvs-mode-find-file
+ "<follow-link>" (lambda (pos)
+ (eq (get-char-property pos 'face) 'cvs-filename))
+ "<down-mouse-3>" #'cvs-menu
+ ;; dired-like bindings
+ "C-o" #'cvs-mode-display-file)
+
+(easy-menu-define cvs-menu cvs-mode-map "Menu used in `cvs-mode'."
+ '("CVS"
+ ["Open file" cvs-mode-find-file t]
+ ["Open in other window" cvs-mode-find-file-other-window t]
+ ["Display in other window" cvs-mode-display-file t]
+ ["Interactive merge" cvs-mode-imerge t]
+ ("View diff"
+ ["Interactive diff" cvs-mode-idiff t]
+ ["Current diff" cvs-mode-diff t]
+ ["Diff with head" cvs-mode-diff-head t]
+ ["Diff with vendor" cvs-mode-diff-vendor t]
+ ["Diff against yesterday" cvs-mode-diff-yesterday t]
+ ["Diff with backup" cvs-mode-diff-backup t])
+ ["View log" cvs-mode-log t]
+ ["View status" cvs-mode-status t]
+ ["View tag tree" cvs-mode-tree t]
+ "----"
+ ["Insert" cvs-mode-insert]
+ ["Update" cvs-mode-update (cvs-enabledp 'update)]
+ ["Re-examine" cvs-mode-examine t]
+ ["Commit" cvs-mode-commit-setup (cvs-enabledp 'commit)]
+ ["Tag" cvs-mode-tag (cvs-enabledp (when cvs-force-dir-tag 'tag))]
+ ["Undo changes" cvs-mode-undo (cvs-enabledp 'undo)]
+ ["Add" cvs-mode-add (cvs-enabledp 'add)]
+ ["Remove" cvs-mode-remove (cvs-enabledp 'remove)]
+ ["Ignore" cvs-mode-ignore (cvs-enabledp 'ignore)]
+ ["Add ChangeLog" cvs-mode-add-change-log-entry-other-window t]
+ "----"
+ ["Mark" cvs-mode-mark t]
+ ["Mark all" cvs-mode-mark-all-files t]
+ ["Mark by regexp..." cvs-mode-mark-matching-files t]
+ ["Mark by state..." cvs-mode-mark-on-state t]
+ ["Unmark" cvs-mode-unmark t]
+ ["Unmark all" cvs-mode-unmark-all-files t]
+ ["Hide handled" cvs-mode-remove-handled t]
+ "----"
+ ["PCL-CVS Manual" (lambda () (interactive)
+ (info "(pcl-cvs)Top")) t]
+ "----"
+ ["Quit" cvs-mode-quit t]))
+
+;;;;
+;;;; CVS-Minor mode
+;;;;
+
+(defcustom cvs-minor-mode-prefix "\C-xc"
+ "Prefix key for the `cvs-mode' bindings in `cvs-minor-mode'."
+ :type 'string
+ :group 'pcl-cvs)
+
+(defvar-keymap cvs-minor-mode-map
+ (key-description cvs-minor-mode-prefix) 'cvs-mode-map
+ "e" '(menu-item nil cvs-mode-edit-log
+ :filter (lambda (x)
+ (and (derived-mode-p 'log-view-mode) x))))
+
+(require 'pcvs-defs)
+
;;;;
;;;; flags variables
;;;;
@@ -247,7 +388,7 @@ If -CVS-MODE!-FUN is provided, it is executed *cvs* being the current buffer
(let* ((-cvs-mode!-buf (current-buffer))
(cvsbuf (cond ((cvs-buffer-p) (current-buffer))
((and cvs-buffer (cvs-buffer-p cvs-buffer)) cvs-buffer)
- (t (error "can't find the *cvs* buffer"))))
+ (t (error "Can't find the *cvs* buffer"))))
(-cvs-mode!-wrapper cvs-minor-wrap-function)
(-cvs-mode!-cont (lambda ()
(save-current-buffer
@@ -672,7 +813,7 @@ it is finished."
(when cvs-postproc
(if (null procbuf)
;;(set-process-buffer proc nil)
- (error "cvs' process buffer was killed")
+ (error "CVS process buffer was killed")
(with-current-buffer procbuf
;; Do the postprocessing like parsing and such.
(save-excursion
@@ -758,6 +899,7 @@ clear what alternative to use.
- `DOUBLE' is the generic case."
(declare (debug (&define sexp lambda-list stringp
("interactive" interactive) def-body))
+ (indent defun)
(doc-string 3))
(let ((style (cvs-cdr fun))
(fun (cvs-car fun)))
@@ -1144,7 +1286,8 @@ Full documentation is in the Texinfo file."
("->" cvs-secondary-branch-prefix))))
" " cvs-mode-line-process))
(if buffer-file-name
- (error "Use M-x cvs-quickdir to get a *cvs* buffer"))
+ (error (substitute-command-keys
+ "Use \\[cvs-quickdir] to get a *cvs* buffer")))
(buffer-disable-undo)
;;(setq-local goal-column cvs-cursor-column)
(setq-local revert-buffer-function 'cvs-mode-revert-buffer)
@@ -1283,8 +1426,7 @@ marked instead. A directory can never be marked."
(intern
(upcase
(completing-read
- (concat
- "Mark files in state" (if default (concat " [" default "]")) ": ")
+ (format-prompt "Mark files in state" default)
(mapcar (lambda (x)
(list (downcase (symbol-name (car x)))))
cvs-states)
@@ -1503,7 +1645,7 @@ The POSTPROC specified there (typically `log-edit') is then called,
(defvar cvs-edit-log-revision)
(defvar cvs-edit-log-files) (put 'cvs-edit-log-files 'permanent-local t)
(defun cvs-mode-edit-log (file rev &optional text)
- "Edit the log message at point.
+ "Edit log message at point.
This is best called from a `log-view-mode' buffer."
(interactive
(list
@@ -1661,7 +1803,7 @@ See `cvs-mode-diff' for more info."
This command can be used on files that are marked with \"Merged\"
or \"Conflict\" in the *cvs* buffer."
(interactive (list (cvs-flags-query 'cvs-diff-flags "diff flags")))
- (unless (listp flags) (error "flags should be a list of strings"))
+ (unless (listp flags) (error "Flags should be a list of strings"))
(save-some-buffers)
(let* ((marked (cvs-get-marked (cvs-ignore-marks-p "diff")))
(fis (car (cvs-partition 'cvs-fileinfo->backup-file marked))))
@@ -1862,7 +2004,7 @@ POSTPROC is a function of no argument to be evaluated at the very end (after
(let ((def-dir default-directory))
;; Save the relevant buffers
(save-some-buffers nil (lambda () (cvs-is-within-p fis def-dir))))
- (unless (listp flags) (error "flags should be a list of strings"))
+ (unless (listp flags) (error "Flags should be a list of strings"))
;; Some w32 versions of CVS don't like an explicit . too much.
(when (and (car fis) (null (cdr fis))
(eq (cvs-fileinfo->type (car fis)) 'DIRCHANGE)
@@ -2259,7 +2401,7 @@ With prefix argument, prompt for cvs flags."
;;;;
(defun cvs-dir-member-p (fileinfo dir)
- "Return true if FILEINFO represents a file in directory DIR."
+ "Return non-nil if FILEINFO represents a file in directory DIR."
(and (not (eq (cvs-fileinfo->type fileinfo) 'DIRCHANGE))
(string-prefix-p dir (cvs-fileinfo->dir fileinfo))))
@@ -2316,7 +2458,7 @@ this file, or a list of arguments to send to the program."
(defun cvs-change-cvsroot (newroot)
- "Change the CVSROOT."
+ "Change the CVSROOT to NEWROOT."
(interactive "DNew repository: ")
(if (or (file-directory-p (expand-file-name "CVSROOT" newroot))
(y-or-n-p (concat "Warning: no CVSROOT found inside repository."
diff --git a/lisp/vc/smerge-mode.el b/lisp/vc/smerge-mode.el
index 956d9b38017..6c1b8cc95b3 100644
--- a/lisp/vc/smerge-mode.el
+++ b/lisp/vc/smerge-mode.el
@@ -47,6 +47,7 @@
(require 'diff) ;For diff-check-labels.
(require 'diff-mode) ;For diff-refine.
(require 'newcomment)
+(require 'easy-mmode)
;;; The real definition comes later.
(defvar smerge-mode)
@@ -142,36 +143,34 @@ Used in `smerge-diff-base-upper' and related functions."
"Face used for added characters shown by `smerge-refine'."
:version "24.3")
-(easy-mmode-defmap smerge-basic-map
- `(("n" . smerge-next)
- ("p" . smerge-prev)
- ("r" . smerge-resolve)
- ("a" . smerge-keep-all)
- ("b" . smerge-keep-base)
- ("o" . smerge-keep-lower) ; for the obsolete keep-other
- ("l" . smerge-keep-lower)
- ("m" . smerge-keep-upper) ; for the obsolete keep-mine
- ("u" . smerge-keep-upper)
- ("E" . smerge-ediff)
- ("C" . smerge-combine-with-next)
- ("R" . smerge-refine)
- ("\C-m" . smerge-keep-current)
- ("=" . ,(make-sparse-keymap "Diff"))
- ("=<" "base-upper" . smerge-diff-base-upper)
- ("=>" "base-lower" . smerge-diff-base-lower)
- ("==" "upper-lower" . smerge-diff-upper-lower))
- "The base keymap for `smerge-mode'.")
+(defvar-keymap smerge-basic-map
+ "n" #'smerge-next
+ "p" #'smerge-prev
+ "r" #'smerge-resolve
+ "a" #'smerge-keep-all
+ "b" #'smerge-keep-base
+ "o" #'smerge-keep-lower ; for the obsolete keep-other
+ "l" #'smerge-keep-lower
+ "m" #'smerge-keep-upper ; for the obsolete keep-mine
+ "u" #'smerge-keep-upper
+ "E" #'smerge-ediff
+ "C" #'smerge-combine-with-next
+ "R" #'smerge-refine
+ "C-m" #'smerge-keep-current
+ "=" (define-keymap :name "Diff"
+ "<" (cons "base-upper" #'smerge-diff-base-upper)
+ ">" (cons "base-lower" #'smerge-diff-base-lower)
+ "=" (cons "upper-lower" #'smerge-diff-upper-lower)))
(defcustom smerge-command-prefix "\C-c^"
"Prefix for `smerge-mode' commands."
:type '(choice (const :tag "ESC" "\e")
- (const :tag "C-c ^" "\C-c^" )
+ (const :tag "C-c ^" "\C-c^")
(const :tag "none" "")
string))
-(easy-mmode-defmap smerge-mode-map
- `((,smerge-command-prefix . ,smerge-basic-map))
- "Keymap for `smerge-mode'.")
+(defvar-keymap smerge-mode-map
+ (key-description smerge-command-prefix) smerge-basic-map)
(defvar-local smerge-check-cache nil)
(defun smerge-check (n)
@@ -961,7 +960,7 @@ It has the following disadvantages:
(defvar smerge--refine-long-words)
(defun smerge--refine-chopup-region (beg end file &optional preproc)
- "Chopup the region into small elements, one per line.
+ "Chopup the region from BEG to END into small elements, one per line.
Save the result into FILE.
If non-nil, PREPROC is called with no argument in a buffer that contains
a copy of the text, just before chopping it up. It can be used to replace
diff --git a/lisp/vc/vc-annotate.el b/lisp/vc/vc-annotate.el
index 07b2800c2dc..def87db8712 100644
--- a/lisp/vc/vc-annotate.el
+++ b/lisp/vc/vc-annotate.el
@@ -277,7 +277,7 @@ cover the range from the oldest annotation to the newest."
;; Menu -- Using easymenu.el
(easy-menu-define vc-annotate-mode-menu vc-annotate-mode-map
- "VC Annotate Display Menu"
+ "VC Annotate Display Menu."
`("VC-Annotate"
["By Color Map Range" (unless (null vc-annotate-display-mode)
(setq vc-annotate-display-mode nil)
@@ -545,6 +545,7 @@ Return a cons (REV . FILENAME)."
(defvar log-view-vc-backend)
(defvar log-view-vc-fileset)
+(defvar vc-git-print-log-follow)
(defun vc-annotate-show-log-revision-at-line ()
"Visit the log of the revision at line.
@@ -559,6 +560,8 @@ the file in question, search for the log entry required and move point."
(message "Cannot extract revision number from the current line")
(let ((backend vc-annotate-backend)
(log-buf (get-buffer "*vc-change-log*"))
+ ;; No need to follow renames: we specify the historical file name.
+ vc-git-print-log-follow
pos)
(if (and
log-buf
@@ -607,7 +610,8 @@ the file in question, search for the log entry required and move point."
(vc-annotate-show-diff-revision-at-line-internal t))
(defun vc-annotate-show-changeset-diff-revision-at-line ()
- "Visit the diff of the revision at line from its previous revision for all files in the changeset."
+ "Show the diffs of revision at current line relative to previous revision.
+This is done for all files in changeset."
(interactive)
(when (eq 'file (vc-call-backend vc-annotate-backend 'revision-granularity))
(error "The %s backend does not support changeset diffs" vc-annotate-backend))
diff --git a/lisp/vc/vc-bzr.el b/lisp/vc/vc-bzr.el
index 5144b5d0bbb..48fedeca5a8 100644
--- a/lisp/vc/vc-bzr.el
+++ b/lisp/vc/vc-bzr.el
@@ -634,7 +634,7 @@ Returns nil if unable to find this information."
(error "Don't know how to compute the next revision of %s" rev)))
(defun vc-bzr-register (files &optional _comment)
- "Register FILES under bzr. COMMENT is ignored."
+ "Register FILES under bzr. COMMENT is ignored."
(vc-bzr-command "add" nil 0 files))
;; Could run `bzr status' in the directory and see if it succeeds, but
@@ -1054,7 +1054,8 @@ stream. Standard error output is discarded."
(vc-bzr-command "info" t 0 dir)
(buffer-string)))
(shelve (vc-bzr-shelve-list))
- (shelve-help-echo "Use M-x vc-bzr-shelve to create shelves")
+ (shelve-help-echo (substitute-command-keys
+ "Use \\[vc-bzr-shelve] to create shelves"))
(root-dir (vc-bzr-root dir))
(pending-merge
;; FIXME: looking for .bzr/checkout/merge-hashes is not a
diff --git a/lisp/vc/vc-cvs.el b/lisp/vc/vc-cvs.el
index c8f36fb76ec..c8954472245 100644
--- a/lisp/vc/vc-cvs.el
+++ b/lisp/vc/vc-cvs.el
@@ -24,9 +24,9 @@
;;; Code:
+(require 'vc-rcs)
(eval-when-compile (require 'vc))
-(declare-function vc-branch-p "vc" (rev))
(declare-function vc-checkout "vc" (file &optional rev))
(declare-function vc-expand-dirs "vc" (file-or-dir-list backend))
(declare-function vc-read-revision "vc"
@@ -309,10 +309,11 @@ to the CVS command."
(defun vc-cvs-responsible-p (file)
"Return non-nil if CVS thinks it is responsible for FILE."
- (file-directory-p (expand-file-name "CVS"
- (if (file-directory-p file)
- file
- (file-name-directory file)))))
+ (let ((dir (if (file-directory-p file)
+ file
+ (file-name-directory file))))
+ (and (file-directory-p (expand-file-name "CVS" dir))
+ (file-name-directory (expand-file-name "CVS" dir)))))
(defun vc-cvs-could-register (file)
"Return non-nil if FILE could be registered in CVS.
@@ -451,17 +452,17 @@ REV is the revision to check out."
((string= first-revision "")
(setq status (vc-cvs-merge-news file)))
(t
- (if (not (vc-branch-p first-revision))
+ (if (not (vc-rcs-branch-p first-revision))
(setq second-revision
(vc-read-revision
"Second revision: "
(list file) 'CVS nil
- (concat (vc-branch-part first-revision) ".")))
+ (concat (vc-rcs-branch-part first-revision) ".")))
;; We want to merge an entire branch. Set revisions
;; accordingly, so that vc-cvs-merge understands us.
(setq second-revision first-revision)
;; first-revision must be the starting point of the branch
- (setq first-revision (vc-branch-part first-revision)))
+ (setq first-revision (vc-rcs-branch-part first-revision)))
(setq status (vc-cvs-merge file first-revision second-revision))))
status))
@@ -542,14 +543,12 @@ Will fail unless you have administrative privileges on the repo."
;;; History functions
;;;
-(declare-function vc-rcs-print-log-cleanup "vc-rcs" ())
;; Follows vc-cvs-command, which uses vc-do-command from vc-dispatcher.
(declare-function vc-exec-after "vc-dispatcher" (code))
(defun vc-cvs-print-log (files buffer &optional _shortlog _start-revision limit)
"Print commit log associated with FILES into specified BUFFER.
Remaining arguments are ignored."
- (require 'vc-rcs)
;; It's just the catenation of the individual logs.
(vc-cvs-command
buffer
@@ -827,7 +826,7 @@ individually should stay local."
(line-end-position))))))))
(defun vc-cvs-parse-uhp (path)
- "parse user@host/path into (user@host /path)"
+ "Parse user@host/path into (user@host /path)."
(if (string-match "\\([^/]+\\)\\(/.*\\)" path)
(list (match-string 1 path) (match-string 2 path))
(list nil path)))
diff --git a/lisp/vc/vc-dav.el b/lisp/vc/vc-dav.el
index 5fd8d8e5036..49a8af10e78 100644
--- a/lisp/vc/vc-dav.el
+++ b/lisp/vc/vc-dav.el
@@ -96,8 +96,7 @@ If REV is non-nil, that is the revision to check out. If REV is the
empty string, that means to check ou tht ehead of the trunk.
If optional arg DESTFILE is given, it is an alternate filename to
-write the contents to.
-"
+write the contents to."
;; This should LOCK the resource.
)
@@ -106,8 +105,7 @@ write the contents to.
If optional arg CONTENTS-DONE is non-nil, then the contents of FILE
have already been reverted from a version backup, and this function
-only needs to update the status of URL within the backend.
-"
+only needs to update the status of URL within the backend."
;; Should do a GET if !contents_done
;; Should UNLOCK the file.
)
@@ -123,8 +121,7 @@ If REV1 is nil, use the current workfile version as the older version.
If REV2 is nil, use the current workfile contents as the nwer version.
It should return a status of either 0 (no differences found), or
-1 (either non-empty diff or the diff is run asynchronously).
-"
+1 (either non-empty diff or the diff is run asynchronously)."
;; We should do this asynchronously...
;; How would we do it at all, that is the question!
)
@@ -136,13 +133,13 @@ It should return a status of either 0 (no differences found), or
;; This should use url-dav-get-properties with a depth of `1' to get
;; all the properties.
(defun vc-dav-dir-state (_url)
- "find the version control state of all files in DIR in a fast way."
+ "Find the version control state of all files in DIR in a fast way."
)
-(defun vc-dav-responsible-p (_url)
+(defun vc-dav-responsible-p (url)
"Return non-nil if DAV considers itself `responsible' for URL."
;; Check for DAV support on the web server.
- t)
+ (and t url))
;;; Unimplemented functions
;;
diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el
index eb8cf8192c1..32e492171d3 100644
--- a/lisp/vc/vc-dir.el
+++ b/lisp/vc/vc-dir.el
@@ -374,7 +374,7 @@ See `run-hooks'."
"Keymap for directory buffer.")
(defmacro vc-dir-at-event (event &rest body)
- "Evaluate BODY with point located at event-start of EVENT.
+ "Evaluate BODY with point located at `event-start' of EVENT.
If BODY uses EVENT, it should be a variable,
otherwise it will be evaluated twice."
(let ((posn (make-symbol "vc-dir-at-event-posn")))
@@ -567,7 +567,7 @@ If NOINSERT, ignore elements on ENTRIES which are not in the ewoc."
(defun vc-dir-next-line (arg)
"Go to the next line.
-If a prefix argument is given, move by that many lines."
+With prefix argument ARG, move that many lines."
(interactive "p")
(with-no-warnings
(ewoc-goto-next vc-ewoc arg)
@@ -575,7 +575,7 @@ If a prefix argument is given, move by that many lines."
(defun vc-dir-previous-line (arg)
"Go to the previous line.
-If a prefix argument is given, move by that many lines."
+With prefix argument ARG, move that many lines."
(interactive "p")
(ewoc-goto-prev vc-ewoc arg)
(vc-dir-move-to-goal-column))
@@ -703,7 +703,7 @@ line."
(defun vc-dir-mark-all-files (arg)
"Mark all files with the same state as the current one.
-With a prefix argument mark all files (not directories).
+With prefix argument ARG, mark all files (not directories).
If the current entry is a directory, mark all child files.
The commands operate on files that are on the same state.
@@ -813,7 +813,7 @@ line."
(defun vc-dir-unmark-all-files (arg)
"Unmark all files with the same state as the current one.
-With a prefix argument unmark all files.
+With prefix argument ARG, unmark all files.
If the current entry is a directory, unmark all the child files.
The commands operate on files that are on the same state.
@@ -1015,8 +1015,11 @@ child files."
(nreverse result)))
(defun vc-dir-child-files-and-states ()
- "Return the list of conses (FILE . STATE) for child files of the current entry if it's a directory.
-If it is a file, return the corresponding cons for the file itself."
+ "Return the state of one or more files for the current entry.
+If the entry is a directory, return the list of states of its child
+files, where each file is described by a cons of the form (FILE . STATE).
+If the entry is a file, return a single cons cell (FILE . STATE) for
+that file."
(let* ((crt (ewoc-locate vc-ewoc))
(crt-data (ewoc-data crt))
result)
@@ -1113,33 +1116,33 @@ If it is a file, return the corresponding cons for the file itself."
(define-derived-mode vc-dir-mode special-mode "VC dir"
"Major mode for VC directory buffers.
-Marking/Unmarking key bindings and actions:
-m - mark a file/directory
+Marking/Unmarking key bindings and actions: \\<vc-dir-mode-map>
+\\[vc-dir-mark] - mark a file/directory
- if the region is active, mark all the files in region.
Restrictions: - a file cannot be marked if any parent directory is marked
- a directory cannot be marked if any child file or
directory is marked
-u - unmark a file/directory
+\\[vc-dir-unmark] - unmark a file/directory
- if the region is active, unmark all the files in region.
-M - if the cursor is on a file: mark all the files with the same state as
+\\[vc-dir-mark-all-files] - if the cursor is on a file: mark all the files with the same state as
the current file
- if the cursor is on a directory: mark all child files
- with a prefix argument: mark all files
-U - if the cursor is on a file: unmark all the files with the same state
+\\[vc-dir-unmark-all-files] - if the cursor is on a file: unmark all the files with the same state
as the current file
- if the cursor is on a directory: unmark all child files
- with a prefix argument: unmark all files
VC commands
-VC commands in the `C-x v' prefix can be used.
+VC commands in the \\[vc-prefix-map] prefix can be used.
VC commands act on the marked entries. If nothing is marked, VC
commands act on the current entry.
Search & Replace
-S - searches the marked files
-Q - does a query replace on the marked files
-M-s a C-s - does an isearch on the marked files
-M-s a C-M-s - does a regexp isearch on the marked files
+\\[vc-dir-search] - searches the marked files
+\\[vc-dir-query-replace-regexp] - does a query replace on the marked files
+\\[vc-dir-isearch] - does an isearch on the marked files
+\\[vc-dir-isearch-regexp] - does a regexp isearch on the marked files
If nothing is marked, these commands act on the current entry.
When a directory is current or marked, the Search & Replace
commands act on the child files of that directory that are displayed in
@@ -1181,7 +1184,7 @@ specific headers."
"\n"))
(defun vc-dir-refresh-files (files)
- "Refresh some files in the *VC-dir* buffer."
+ "Refresh some FILES in the *VC-dir* buffer."
(let ((def-dir default-directory)
(backend vc-dir-backend))
(vc-set-mode-line-busy-indicator)
@@ -1424,7 +1427,12 @@ These are the commands available for use in the file status buffer:
(vc-dir-refresh)
;; FIXME: find a better way to pass the backend to `vc-dir-mode'.
(let ((use-vc-backend backend))
- (vc-dir-mode))))
+ (vc-dir-mode)
+ ;; Activate the backend-specific minor mode, if any.
+ (when-let ((minor-mode
+ (intern-soft (format "vc-dir-%s-mode"
+ (downcase (symbol-name backend))))))
+ (funcall minor-mode 1)))))
(defun vc-default-dir-extra-headers (_backend _dir)
;; Be loud by default to remind people to add code to display
@@ -1542,7 +1550,7 @@ This implements the `bookmark-make-record-function' type for
;;;###autoload
(defun vc-dir-bookmark-jump (bmk)
- "Provides the bookmark-jump behavior for a `vc-dir' buffer.
+ "Provide the `bookmark-jump' behavior for a `vc-dir' buffer.
This implements the `handler' function interface for the record
type returned by `vc-dir-bookmark-make-record'."
(let* ((file (bookmark-prop-get bmk 'filename))
diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el
index c29458620e9..53cdb5eba84 100644
--- a/lisp/vc/vc-dispatcher.el
+++ b/lisp/vc/vc-dispatcher.el
@@ -104,12 +104,13 @@
;; will be called with the buffer file name as argument whenever the
;; dispatcher resyncs the buffer.
-;; To do:
-;;
+;;; Code:
+
+;; TODO:
;; - log buffers need font-locking.
-;;
;; General customization
+
(defcustom vc-logentry-check-hook nil
"Normal hook run by `vc-finish-logentry'.
Use this to impose your own rules on the entry in addition to any the
@@ -126,8 +127,12 @@ preserve the setting."
:group 'vc)
(defcustom vc-command-messages nil
- "If non-nil, display run messages from back-end commands."
- :type 'boolean
+ "If non-nil, display and log messages about running back-end commands.
+If the value is `log', messages about running VC back-end commands are
+logged in the *Messages* buffer, but not displayed."
+ :type '(choice (const :tag "No messages" nil)
+ (const :tag "Display and log messages" t)
+ (const :tag "Log messages, but don't display" log))
:group 'vc)
(defcustom vc-suppress-confirm nil
@@ -310,7 +315,10 @@ case, and the process object in the asynchronous case."
(substring command 0 -1)
command)
" " (vc-delistify flags)
- " " (vc-delistify files))))
+ " " (vc-delistify files)))
+ (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)
@@ -334,7 +342,7 @@ case, and the process object in the asynchronous case."
(apply #'start-file-process command (current-buffer)
command squeezed))))
(when vc-command-messages
- (let ((inhibit-message (eq (selected-window) (active-minibuffer-window))))
+ (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.
@@ -344,11 +352,11 @@ case, and the process object in the asynchronous case."
(when vc-command-messages
(vc-run-delayed
(let ((message-truncate-lines t)
- (inhibit-message (eq (selected-window) (active-minibuffer-window))))
+ (inhibit-message vc-inhibit-message))
(message "Done in background: %s" full-command)))))
;; Run synchronously
(when vc-command-messages
- (let ((inhibit-message (eq (selected-window) (active-minibuffer-window))))
+ (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)))
@@ -363,7 +371,7 @@ case, and the process object in the asynchronous case."
(if (integerp status) (format "status %d" status) status)
full-command))
(when vc-command-messages
- (let ((inhibit-message (eq (selected-window) (active-minibuffer-window))))
+ (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
@@ -403,7 +411,7 @@ Display the buffer in some window, but don't select it."
(defvar compilation-error-regexp-alist)
(defun vc-compilation-mode (backend)
- "Setup `compilation-mode' after with the appropriate `compilation-error-regexp-alist'."
+ "Setup `compilation-mode' with the appropriate `compilation-error-regexp-alist'."
(require 'compile)
(let* ((error-regexp-alist
(vc-make-backend-sym backend 'error-regexp-alist))
@@ -662,7 +670,7 @@ contents of the log entry buffer. If COMMENT is a string and
INITIAL-CONTENTS is nil, do action immediately as if the user had
entered COMMENT. If COMMENT is t, also do action immediately with an
empty comment. Remember the file's buffer in `vc-parent-buffer'
-\(current one if no file). Puts the log-entry buffer in major-mode
+\(current one if no file). Puts the log-entry buffer in major mode
MODE, defaulting to `log-edit-mode' if MODE is nil.
AFTER-HOOK specifies the local value for `vc-log-after-operation-hook'.
BACKEND, if non-nil, specifies a VC backend for the Log Edit buffer."
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index 935dc8b9aee..5c6a39aec96 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -242,14 +242,19 @@ included in the completions."
;;;###autoload (load "vc-git" nil t)
;;;###autoload (vc-git-registered file))))
-(defun vc-git--literal-pathspec (pathspec)
- "Prepend :(literal) path magic to PATHSPEC."
- ;; Good example of PATHSPEC that needs this: "test[56].xx".
- (and pathspec (concat ":(literal)" pathspec)))
-
-(defun vc-git--literal-pathspecs (pathspecs)
- "Prepend :(literal) path magic to PATHSPECS."
- (mapcar #'vc-git--literal-pathspec pathspecs))
+;; Good example of file name that needs this: "test[56].xx".
+(defun vc-git--literal-pathspec (file)
+ "Prepend :(literal) path magic to FILE."
+ (when file
+ ;; Expand abbreviated file names.
+ (when (file-name-absolute-p file)
+ (setq file (expand-file-name file)))
+ (concat ":(literal)" (file-local-name file))))
+
+(defun vc-git--literal-pathspecs (files)
+ "Prepend :(literal) path magic to FILES."
+ (unless (vc-git--file-list-is-rootdir files)
+ (mapcar #'vc-git--literal-pathspec files)))
(defun vc-git-registered (file)
"Check whether FILE is registered with git."
@@ -293,12 +298,14 @@ included in the completions."
(vc-git--run-command-string nil "version")))
(setq vc-git--program-version
(if (and version-string
- ;; Git for Windows appends ".windows.N" to the
- ;; numerical version reported by Git.
- (string-match
- "git version \\([0-9.]+\\)\\(\\.windows\\.[0-9]+\\)?$"
- version-string))
- (match-string 1 version-string)
+ ;; Some Git versions append additional strings
+ ;; to the numerical version string. E.g., Git
+ ;; for Windows appends ".windows.N", while Git
+ ;; for Mac appends " (Apple Git-N)". Capture
+ ;; numerical version and ignore the rest.
+ (string-match "git version \\([0-9][0-9.]+\\)"
+ version-string))
+ (string-trim-right (match-string 1 version-string) "\\.")
"0")))))
(defun vc-git--git-status-to-vc-state (code-list)
@@ -402,7 +409,7 @@ in the order given by `git status'."
orig-name) ;; Original name for renames or copies.
(defun vc-git-escape-file-name (name)
- "Escape a file name if necessary."
+ "Escape filename NAME if necessary."
(if (string-match "[\n\t\"\\]" name)
(concat "\""
(mapconcat (lambda (c)
@@ -891,8 +898,7 @@ The car of the list is the current branch."
(declare-function log-edit--toggle-amend "log-edit" (last-msg-fn))
(defun vc-git-log-edit-toggle-signoff ()
- "Toggle whether to add the \"Signed-off-by\" line at the end of
-the commit message."
+ "Toggle whether to add the \"Signed-off-by\" line at the end of commit message."
(interactive)
(log-edit-toggle-header "Sign-Off" "yes"))
@@ -1142,6 +1148,14 @@ This prompts for a branch to merge from."
(autoload 'vc-setup-buffer "vc-dispatcher")
+;; It's a weird option due to how Git handles '--follow', and it can
+;; hide certain (usually merge) commits in the `vc-print-log' buffers.
+;;
+;; (setq vc-git-log-switches '("-m")) can fix that, but at the cost of
+;; duplicating many merge commits in the log.
+;;
+;; Long explanation here:
+;; https://stackoverflow.com/questions/46487476/git-log-follow-graph-skips-commits
(defcustom vc-git-print-log-follow nil
"If true, follow renames in Git logs for a single file."
:type 'boolean
@@ -1244,7 +1258,10 @@ log entries."
(defun vc-git-mergebase (rev1 &optional rev2)
(unless rev2 (setq rev2 "HEAD"))
- (string-trim-right (vc-git--run-command-string nil "merge-base" rev1 rev2)))
+ (let ((base (vc-git--run-command-string nil "merge-base" rev1 rev2)))
+ (if base
+ (string-trim-right base)
+ (error "No common ancestor for merge base"))))
(defvar log-view-message-re)
(defvar log-view-file-re)
@@ -1311,7 +1328,7 @@ or BRANCH^ (where \"^\" can be repeated)."
(defun vc-git-expanded-log-entry (revision)
(with-temp-buffer
- (apply #'vc-git-command t nil nil (list "log" revision "-1" "--"))
+ (apply #'vc-git-command t nil nil (list "log" revision "-1" "--no-color" "--"))
(goto-char (point-min))
(unless (eobp)
;; Indent the expanded log entry.
@@ -1552,10 +1569,10 @@ This requires git 1.8.4 or later, for the \"-L\" option of \"git log\"."
(or (vc-git-symbolic-commit next-rev) next-rev)))
(defun vc-git-delete-file (file)
- (vc-git-command nil 0 (vc-git--literal-pathspecs file) "rm" "-f" "--"))
+ (vc-git-command nil 0 (vc-git--literal-pathspec file) "rm" "-f" "--"))
(defun vc-git-rename-file (old new)
- (vc-git-command nil 0 (vc-git--literal-pathspecs (list old new)) "mv" "-f" "--"))
+ (vc-git-command nil 0 (list old new) "mv" "-f" "--"))
(defun vc-git-mark-resolved (files)
(vc-git-command nil 0 (vc-git--literal-pathspecs files) "add"))
@@ -1607,8 +1624,8 @@ before it is executed.
With two \\[universal-argument] prefixes, directly edit and run `grep-command'.
Collect output in a buffer. While git grep runs asynchronously, you
-can use \\[next-error] (M-x next-error), or \\<grep-mode-map>\\[compile-goto-error] \
-in the grep output buffer,
+can use \\[next-error] (`next-error'), or \\<grep-mode-map>\
+\\[compile-goto-error] in the grep output buffer,
to go to the lines where grep found matches.
This command shares argument histories with \\[rgrep] and \\[grep]."
@@ -1673,7 +1690,7 @@ This command shares argument histories with \\[rgrep] and \\[grep]."
(let ((stash (completing-read
prompt
(split-string
- (or (vc-git--run-command-string nil "stash" "list") "") "\n")
+ (or (vc-git--run-command-string nil "stash" "list") "") "\n" t)
nil :require-match nil 'vc-git-stash-read-history)))
(if (string-equal stash "")
(user-error "Not a stash")
@@ -1718,12 +1735,11 @@ This command shares argument histories with \\[rgrep] and \\[grep]."
(defun vc-git-stash-list ()
(when-let ((out (vc-git--run-command-string nil "stash" "list")))
- (delete
- ""
- (split-string
- (replace-regexp-in-string
- "^stash@" " " out)
- "\n"))))
+ (split-string
+ (replace-regexp-in-string
+ "^stash@" " " out)
+ "\n"
+ t)))
(defun vc-git-stash-get-at-point (point)
(save-excursion
@@ -1787,15 +1803,18 @@ The difference to vc-do-command is that this function always invokes
'("GIT_OPTIONAL_LOCKS=0")))
process-environment)))
(apply #'vc-do-command (or buffer "*vc*") okstatus vc-git-program
- ;; https://debbugs.gnu.org/16897
- (unless (and (not (cdr-safe file-or-list))
- (let ((file (or (car-safe file-or-list)
- file-or-list)))
- (and file
- (eq ?/ (aref file (1- (length file))))
- (equal file (vc-git-root file)))))
- file-or-list)
- (cons "--no-pager" flags))))
+ ;; https://debbugs.gnu.org/16897
+ (unless (vc-git--file-list-is-rootdir file-or-list)
+ file-or-list)
+ (cons "--no-pager" flags))))
+
+(defun vc-git--file-list-is-rootdir (file-or-list)
+ (and (not (cdr-safe file-or-list))
+ (let ((file (or (car-safe file-or-list)
+ file-or-list)))
+ (and file
+ (eq ?/ (aref file (1- (length file))))
+ (equal file (vc-git-root file))))))
(defun vc-git--empty-db-p ()
"Check if the git db is empty (no commit done yet)."
@@ -1853,6 +1872,17 @@ Returns nil if not possible."
(1- (point-max)))))))
(and name (not (string= name "undefined")) name))))
+(defvar-keymap vc-dir-git-mode-map
+ "z c" #'vc-git-stash
+ "z s" #'vc-git-stash-snapshot
+ "z p" #'vc-git-stash-pop)
+
+(define-minor-mode vc-dir-git-mode
+ "A minor mode for git-specific commands in `vc-dir-mode' buffers.
+Also note that there are git stash commands available in the
+\"Stash\" section at the head of the buffer."
+ :lighter " Git")
+
(provide 'vc-git)
;;; vc-git.el ends here
diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el
index 4a64caa36b8..6bec9edbf35 100644
--- a/lisp/vc/vc-hg.el
+++ b/lisp/vc/vc-hg.el
@@ -137,8 +137,7 @@ switches."
:version "25.1")
(defcustom vc-hg-revert-switches nil
- "String or list of strings specifying switches for hg revert
-under VC."
+ "String or list of strings specifying switches for hg revert under VC."
:type '(choice (const :tag "None" nil)
(string :tag "Argument String")
(repeat :tag "Argument List" :value ("") string))
@@ -271,9 +270,9 @@ If `ask', you will be prompted for a branch type."
(defcustom vc-hg-symbolic-revision-styles
'(builtin-active-bookmark
"{if(bookmarks,sub(' ',',',bookmarks),if(phabdiff,phabdiff,shortest(node,6)))}")
- "List of ways to present versions symbolically. The version
-that we use is the first one that successfully produces a
-non-empty string.
+ "List of ways to present versions symbolically.
+The version that we use is the first one that successfully
+produces a non-empty string.
Each entry in the list can be either:
@@ -291,7 +290,7 @@ and an optional path to which to limit history) and produce a
string. The function is called with `default-directory' set to
within the repository.
-If no list entry produces a useful revision, return `nil'."
+If no list entry produces a useful revision, return nil."
:type '(repeat (choice
(const :tag "Active bookmark" builtin-active-bookmark)
(string :tag "Hg template")
@@ -301,7 +300,7 @@ If no list entry produces a useful revision, return `nil'."
(defcustom vc-hg-use-file-version-for-mode-line-version nil
"When enabled, the modeline contains revision information for the visited file.
When not, the revision in the modeline is for the repository
-working copy. `nil' is the much faster setting for
+working copy. nil is the much faster setting for
large repositories."
:type 'boolean
:version "26.1")
@@ -643,8 +642,8 @@ Variable `vc-hg-create-bookmark' controls what kind of branch will be created."
;;; Native data structure reading
(defcustom vc-hg-parse-hg-data-structures t
- "If true, try directly parsing Mercurial data structures
-directly instead of always running Mercurial. We try to be safe
+ "If true, try parsing Mercurial data structures directly.
+This is done instead of always running Mercurial. We try to be safe
against Mercurial data structure format changes and always fall
back to running Mercurial directly."
:type 'boolean
@@ -673,7 +672,6 @@ Return the byte's value as an integer."
(let* ((result nil)
(flen (length fname))
(case-fold-search nil)
- (inhibit-changing-match-data t)
;; Find a conservative bound for the loop below by using
;; Boyer-Moore on the raw dirstate without parsing it; we
;; know we can't possibly find fname _after_ the last place
@@ -811,7 +809,7 @@ if we don't understand a construct, we signal
(push c parts)
(cond ((eq c ?\\) (setf state 'charclass-backslash))
((eq c ?\]) (setf state 'normal))))
- (t (error "invalid state")))
+ (t (error "Invalid state")))
(setf i (1+ i))))
(unless (eq state 'normal)
(signal 'vc-hg-unsupported-syntax (list pcre)))
@@ -977,10 +975,9 @@ REPO must be the directory name of an hg repository."
"Test whether the ignore pattern set HGIP says to ignore FILENAME.
FILENAME must be the file's true absolute name."
(let ((patterns (vc-hg--ignore-patterns-ignore-patterns hgip))
- (inhibit-changing-match-data t)
(ignored nil))
(while (and patterns (not ignored))
- (setf ignored (string-match (pop patterns) filename)))
+ (setf ignored (string-match-p (pop patterns) filename)))
ignored))
(defvar vc-hg--cached-ignore-patterns nil
@@ -1017,9 +1014,9 @@ FILENAME must be the file's true absolute name."
"remotefilelog"
"revlogv1"
"store")
- "List of Mercurial repository requirements we understand; if a
-repository requires features not present in this list, we avoid
-attempting to parse Mercurial data structures.")
+ "List of Mercurial repository requirements we understand.
+If a repository requires features not present in this list, we
+avoid attempting to parse Mercurial data structures.")
(defun vc-hg--requirements-understood-p (repo)
"Check that we understand the format of the given repository.
@@ -1044,7 +1041,8 @@ Avoids the need to repeatedly scan dirstate on repeated calls to
(equal size (pop cache))
(equal ascii-fname (pop cache)))
(pop cache)
- (let ((result (vc-hg--raw-dirstate-search dirstate ascii-fname)))
+ (let ((result (save-match-data
+ (vc-hg--raw-dirstate-search dirstate ascii-fname))))
(setf vc-hg--dirstate-scan-cache
(list dirstate mtime size ascii-fname result))
result))))
@@ -1151,7 +1149,7 @@ hg binary."
(expand-file-name old)))
(defun vc-hg-register (files &optional _comment)
- "Register FILES under hg. COMMENT is ignored."
+ "Register FILES under hg. COMMENT is ignored."
(vc-hg-command nil 0 files "add"))
(defun vc-hg-create-repo ()
diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el
index 4b3c829a2c6..cd5b11d840b 100644
--- a/lisp/vc/vc-hooks.el
+++ b/lisp/vc/vc-hooks.el
@@ -256,9 +256,9 @@ It is usually called via the `vc-call' macro."
(defmacro vc-call (fun file &rest args)
"A convenience macro for calling VC backend functions.
Functions called by this macro must accept FILE as the first argument.
-ARGS specifies any additional arguments. FUN should be unquoted.
-BEWARE!! FILE is evaluated twice!!"
- `(vc-call-backend (vc-backend ,file) ',fun ,file ,@args))
+ARGS specifies any additional arguments. FUN should be unquoted."
+ (macroexp-let2 nil file file
+ `(vc-call-backend (vc-backend ,file) ',fun ,file ,@args)))
(defsubst vc-parse-buffer (pattern i)
"Find PATTERN in the current buffer and return its Ith submatch."
@@ -483,7 +483,7 @@ status of this file. Otherwise, the value returned is one of:
(vc-call-backend backend 'state file)))
(defsubst vc-up-to-date-p (file)
- "Convenience function that checks whether `vc-state' of FILE is `up-to-date'."
+ "Convenience function to check whether `vc-state' of FILE is `up-to-date'."
(eq (vc-state file) 'up-to-date))
(defun vc-working-revision (file &optional backend)
@@ -627,7 +627,7 @@ Before doing that, check if there are any old backups and get rid of them."
(declare-function vc-dir-resynch-file "vc-dir" (&optional fname))
-(defvar vc-dir-buffers nil "List of vc-dir buffers.")
+(defvar vc-dir-buffers nil "List of `vc-dir' buffers.")
(defun vc-after-save ()
"Function to be called by `basic-save-buffer' (in files.el)."
@@ -864,7 +864,8 @@ In the latter case, VC mode is deactivated for this buffer."
(defvar vc-prefix-map
(let ((map (make-sparse-keymap)))
(define-key map "a" #'vc-update-change-log)
- (define-key map "b" #'vc-switch-backend)
+ (with-suppressed-warnings ((obsolete vc-switch-backend))
+ (define-key map "b" #'vc-switch-backend))
(define-key map "d" #'vc-dir)
(define-key map "g" #'vc-annotate)
(define-key map "G" #'vc-ignore)
diff --git a/lisp/vc/vc-rcs.el b/lisp/vc/vc-rcs.el
index 6ffc1a8a2ff..2422e99d3da 100644
--- a/lisp/vc/vc-rcs.el
+++ b/lisp/vc/vc-rcs.el
@@ -41,7 +41,6 @@
(require 'cl-lib)
(require 'vc))
-(declare-function vc-branch-p "vc" (rev))
(declare-function vc-read-revision "vc"
(prompt &optional files backend default initial-input))
(declare-function vc-buffer-context "vc-dispatcher" ())
@@ -173,6 +172,19 @@ For a description of possible values, see `vc-check-master-templates'."
(defun vc-rcs-dir-extra-headers (&rest _ignore))
+;; functions that operate on RCS revision numbers.
+(defun vc-rcs-branch-p (rev)
+ "Return t if REV is a branch revision."
+ (not (eq nil (string-match "\\`[0-9]+\\(\\.[0-9]+\\.[0-9]+\\)*\\'" rev))))
+(define-obsolete-function-alias 'vc-branch-p #'vc-rcs-branch-p "28.1")
+
+(defun vc-rcs-branch-part (rev)
+ "Return the branch part of a revision number REV."
+ (let ((index (string-match "\\.[0-9]+\\'" rev)))
+ (when index
+ (substring rev 0 index))))
+(define-obsolete-function-alias 'vc-branch-part #'vc-rcs-branch-part "28.1")
+
(defun vc-rcs-working-revision (file)
"RCS-specific version of `vc-working-revision'."
(or (and vc-consult-headers
@@ -198,7 +210,7 @@ When VERSION is given, perform check for that version."
;; If we are not on the trunk, we need to examine the
;; whole current branch.
(vc-insert-file (vc-master-name file) "^desc")
- (vc-rcs-find-most-recent-rev (vc-branch-part version))))))
+ (vc-rcs-find-most-recent-rev (vc-rcs-branch-part version))))))
(defun vc-rcs-workfile-unchanged-p (file)
"Has FILE remained unchanged since last checkout?"
@@ -230,7 +242,7 @@ When VERSION is given, perform check for that version."
(autoload 'vc-switches "vc")
(defun vc-rcs-register (files &optional comment)
- "Register FILES into the RCS version-control system.
+ "Register FILES into the RCS version control system.
Automatically retrieve a read-only version of the file with keywords expanded.
COMMENT can be used to provide an initial description for each FILES.
Passes either `vc-rcs-register-switches' or `vc-register-switches'
@@ -278,10 +290,11 @@ to the RCS command."
(defun vc-rcs-responsible-p (file)
"Return non-nil if RCS thinks it would be responsible for registering FILE."
;; TODO: check for all the patterns in vc-rcs-master-templates
- (file-directory-p (expand-file-name "RCS"
- (if (file-directory-p file)
- file
- (file-name-directory file)))))
+ (let ((dir (if (file-directory-p file)
+ file
+ (file-name-directory file))))
+ (and (file-directory-p (expand-file-name "RCS" dir))
+ (file-name-directory (expand-file-name "RCS" dir)))))
(defun vc-rcs-receive-file (file rev)
"Implementation of receive-file for RCS."
@@ -326,7 +339,7 @@ whether to remove it."
(setq rev default-branch)
(setq switches (cons "-f" switches)))
(if (and (not rev) old-version)
- (setq rev (vc-branch-part old-version)))
+ (setq rev (vc-rcs-branch-part old-version)))
(apply #'vc-do-command "*vc*" 0 "ci" (vc-master-name file)
;; if available, use the secure check-in option
(and (vc-rcs-release-p "5.6.4") "-j")
@@ -349,11 +362,11 @@ whether to remove it."
;; branch accordingly
(cond
((and old-version new-version
- (not (string= (vc-branch-part old-version)
- (vc-branch-part new-version))))
+ (not (string= (vc-rcs-branch-part old-version)
+ (vc-rcs-branch-part new-version))))
(vc-rcs-set-default-branch file
(if (vc-rcs-trunk-p new-version) nil
- (vc-branch-part new-version)))
+ (vc-rcs-branch-part new-version)))
;; If this is an old (pre-1992!) RCS release, we might have
;; to remove a remaining lock.
(if (not (vc-rcs-release-p "5.6.2"))
@@ -370,8 +383,9 @@ whether to remove it."
(vc-switches 'RCS 'checkout)))
(defun vc-rcs-checkout (file &optional rev)
- "Retrieve a copy of a saved version of FILE. If FILE is a directory,
-attempt the checkout for all registered files beneath it."
+ "Retrieve a copy of a saved version of FILE.
+If FILE is a directory, attempt the checkout for all registered
+files beneath it."
(if (file-directory-p file)
(mapc #'vc-rcs-checkout (vc-expand-dirs (list file) 'RCS))
(let ((file-buffer (get-file-buffer file))
@@ -414,7 +428,7 @@ attempt the checkout for all registered files beneath it."
;; REV is t ...
(if (not (vc-rcs-trunk-p workrev))
;; ... go to head of current branch
- (vc-branch-part workrev)
+ (vc-rcs-branch-part workrev)
;; ... go to head of trunk
(vc-rcs-set-default-branch file
nil)
@@ -431,13 +445,13 @@ attempt the checkout for all registered files beneath it."
file
(if (vc-rcs-latest-on-branch-p file new-version)
(if (vc-rcs-trunk-p new-version) nil
- (vc-branch-part new-version))
+ (vc-rcs-branch-part new-version))
new-version)))))
(message "Checking out %s...done" file))))))
(defun vc-rcs-revert (file &optional _contents-done)
- "Revert FILE to the version it was based on. If FILE is a directory,
-revert all registered files beneath it."
+ "Revert FILE to the version it was based on.
+If FILE is a directory, revert all registered files beneath it."
(if (file-directory-p file)
(mapc #'vc-rcs-revert (vc-expand-dirs (list file) 'RCS))
(vc-do-command "*vc*" 0 "co" (vc-master-name file) "-f"
@@ -456,17 +470,17 @@ revert all registered files beneath it."
((string= first-revision "")
(error "A starting RCS revision is required"))
(t
- (if (not (vc-branch-p first-revision))
+ (if (not (vc-rcs-branch-p first-revision))
(setq second-revision
(vc-read-revision
"Second RCS revision: "
(list file) 'RCS nil
- (concat (vc-branch-part first-revision) ".")))
+ (concat (vc-rcs-branch-part first-revision) ".")))
;; We want to merge an entire branch. Set revisions
;; accordingly, so that vc-rcs-merge understands us.
(setq second-revision first-revision)
;; first-revision must be the starting point of the branch
- (setq first-revision (vc-branch-part first-revision)))))
+ (setq first-revision (vc-rcs-branch-part first-revision)))))
(vc-rcs-merge file first-revision second-revision)))
(defun vc-rcs-merge (file first-version &optional second-version)
@@ -504,8 +518,9 @@ Needs RCS 5.6.2 or later for -M."
(kill-buffer filename)))))
(defun vc-rcs-modify-change-comment (files rev comment)
- "Modify the change comments change on FILES on a specified REV. If FILE is a
-directory the operation is applied to all registered files beneath it."
+ "Modify the change comments change on FILES on a specified REV.
+If FILE is a directory the operation is applied to all registered
+files beneath it."
(dolist (file (vc-expand-dirs files 'RCS))
(vc-do-command "*vc*" 0 "rcs" (vc-master-name file)
(concat "-m" rev ":" comment))))
@@ -637,11 +652,11 @@ Optional arg REVISION is a revision to annotate from."
;; Find which branches (if any) must be included in the edits.
(let ((par revision)
bpt kids)
- (while (setq bpt (vc-branch-part par)
- par (vc-branch-part bpt))
+ (while (setq bpt (vc-rcs-branch-part par)
+ par (vc-rcs-branch-part bpt))
(setq kids (cdr (assq 'branches (cdr (assoc par revisions)))))
;; A branchpoint may have multiple children. Find the right one.
- (while (not (string= bpt (vc-branch-part (car kids))))
+ (while (not (string= bpt (vc-rcs-branch-part (car kids))))
(setq kids (cdr kids)))
(push (cons par (car kids)) nbls)))
;; Start with the full text.
@@ -818,7 +833,7 @@ systime, or nil if there is none. Also, reposition point."
or nil if there is no previous revision. This default
implementation works for MAJOR.MINOR-style revision numbers as
used by RCS and CVS."
- (let ((branch (vc-branch-part rev))
+ (let ((branch (vc-rcs-branch-part rev))
(minor-num (string-to-number (vc-rcs-minor-part rev))))
(when branch
(if (> minor-num 1)
@@ -830,7 +845,7 @@ used by RCS and CVS."
nil
;; we are at the beginning of a branch --
;; return revision of starting point
- (vc-branch-part branch))))))
+ (vc-rcs-branch-part branch))))))
(defun vc-rcs-next-revision (file rev)
"Return the revision number immediately following REV for FILE,
@@ -838,7 +853,7 @@ or nil if there is no next revision. This default implementation
works for MAJOR.MINOR-style revision numbers as used by RCS
and CVS."
(when (not (string= rev (vc-working-revision file)))
- (let ((branch (vc-branch-part rev))
+ (let ((branch (vc-rcs-branch-part rev))
(minor-num (string-to-number (vc-rcs-minor-part rev))))
(concat branch "." (number-to-string (1+ minor-num))))))
@@ -965,7 +980,7 @@ to its master version."
(setq latest-rev rev)
(setq value (match-string 1)))))
(or value
- (vc-branch-part branch))))
+ (vc-rcs-branch-part branch))))
(defun vc-rcs-fetch-master-state (file &optional working-revision)
"Compute the master file's idea of the state of FILE.
diff --git a/lisp/vc/vc-sccs.el b/lisp/vc/vc-sccs.el
index 92cce5f13a8..4b56fbf28ef 100644
--- a/lisp/vc/vc-sccs.el
+++ b/lisp/vc/vc-sccs.el
@@ -191,7 +191,7 @@ Optional string REV is a revision."
(autoload 'vc-switches "vc")
(defun vc-sccs-register (files &optional comment)
- "Register FILES into the SCCS version-control system.
+ "Register FILES into the SCCS version control system.
Automatically retrieve a read-only version of the files with keywords expanded.
COMMENT can be used to provide an initial description of FILES.
Passes either `vc-sccs-register-switches' or `vc-register-switches'
@@ -214,9 +214,13 @@ to the SCCS command."
(defun vc-sccs-responsible-p (file)
"Return non-nil if SCCS thinks it would be responsible for registering FILE."
;; TODO: check for all the patterns in vc-sccs-master-templates
- (or (file-directory-p (expand-file-name "SCCS" (file-name-directory file)))
- (stringp (vc-sccs-search-project-dir (or (file-name-directory file) "")
- (file-name-nondirectory file)))))
+ (or (and (file-directory-p
+ (expand-file-name "SCCS" (file-name-directory file)))
+ (file-name-directory file))
+ (let ((dir (vc-sccs-search-project-dir (or (file-name-directory file) "")
+ (file-name-nondirectory file))))
+ (and (stringp dir)
+ dir))))
(defun vc-sccs-checkin (files comment &optional rev)
"SCCS-specific version of `vc-backend-checkin'."
@@ -270,8 +274,8 @@ locked. REV is the revision to check out."
(message "Checking out %s...done" file))))
(defun vc-sccs-revert (file &optional _contents-done)
- "Revert FILE to the version it was based on. If FILE is a directory,
-revert all subfiles."
+ "Revert FILE to the version it was based on.
+If FILE is a directory, revert all subfiles."
(if (file-directory-p file)
(mapc #'vc-sccs-revert (vc-expand-dirs (list file) 'SCCS))
(vc-sccs-do-command nil 0 "unget" (vc-master-name file))
diff --git a/lisp/vc/vc-src.el b/lisp/vc/vc-src.el
index faba5bce2b7..b408b7de760 100644
--- a/lisp/vc/vc-src.el
+++ b/lisp/vc/vc-src.el
@@ -238,7 +238,7 @@ This function differs from vc-do-command in that it invokes `vc-src-program'."
(autoload 'vc-switches "vc")
(defun vc-src-register (files &optional _comment)
- "Register FILES under src. COMMENT is ignored."
+ "Register FILES under src. COMMENT is ignored."
(vc-src-command nil files "add"))
(defun vc-src-responsible-p (file)
@@ -268,15 +268,16 @@ REV is the revision to check out into WORKFILE."
(vc-src-command nil file "co")))
(defun vc-src-revert (file &optional _contents-done)
- "Revert FILE to the version it was based on. If FILE is a directory,
-revert all registered files beneath it."
+ "Revert FILE to the version it was based on.
+If FILE is a directory, revert all registered files beneath it."
(if (file-directory-p file)
(mapc #'vc-src-revert (vc-expand-dirs (list file) 'SRC))
(vc-src-command nil file "co")))
(defun vc-src-modify-change-comment (files rev comment)
- "Modify the change comments change on FILES on a specified REV. If FILE is a
-directory the operation is applied to all registered files beneath it."
+ "Modify the change comments change on FILES on a specified REV.
+If FILE is a directory the operation is applied to all registered
+files beneath it."
(dolist (file (vc-expand-dirs files 'SRC))
(vc-src-command nil file "amend" "-m" comment rev)))
diff --git a/lisp/vc/vc-svn.el b/lisp/vc/vc-svn.el
index 544a6c769fc..e14519cc20e 100644
--- a/lisp/vc/vc-svn.el
+++ b/lisp/vc/vc-svn.el
@@ -295,7 +295,7 @@ RESULT is a list of conses (FILE . STATE) for directory DIR."
(autoload 'vc-switches "vc")
(defun vc-svn-register (files &optional _comment)
- "Register FILES into the SVN version-control system.
+ "Register FILES into the SVN version control system.
The COMMENT argument is ignored This does an add but not a commit.
Passes either `vc-svn-register-switches' or `vc-register-switches'
to the SVN command."
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index b75862e8a52..64f752f248d 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -431,7 +431,7 @@
;; and displays a file name and a revision, then return a cons
;; (REVISION . FILENAME).
;;
-;; - region-history (FILE BUFFER LFROM LTO)
+;; - region-history (file buffer lfrom lto)
;;
;; Insert into BUFFER the history (log comments and diffs) of the content of
;; FILE between lines LFROM and LTO. This is typically done asynchronously.
@@ -496,7 +496,7 @@
;; `.bzrignore'. The default behavior is to read the contents of
;; the file returned by the `find-ignore-file' function.
;;
-;; - find-ignore-file
+;; - find-ignore-file (file)
;;
;; Return the ignore file that controls FILE, e.g. `.gitignore' or
;; `.bzrignore'.
@@ -515,7 +515,7 @@
;;
;; Turn on the mode used for editing the check in log. This
;; defaults to `log-edit-mode'. If changed, it should use a mode
-;; derived from`log-edit-mode'.
+;; derived from `log-edit-mode'.
;;
;; - check-headers ()
;;
@@ -739,6 +739,7 @@
(require 'cl-lib)
(declare-function diff-setup-whitespace "diff-mode" ())
+(declare-function diff-setup-buffer-type "diff-mode" ())
(eval-when-compile
(require 'dired))
@@ -860,7 +861,9 @@ See `run-hooks'."
(defcustom vc-revert-show-diff t
"If non-nil, `vc-revert' shows a `vc-diff' buffer before querying."
- :type 'boolean
+ :type '(choice (const :tag "Show and bury afterwards" t)
+ (const :tag "Show and kill afterwards" kill)
+ (const :tag "Don't show" nil))
:version "24.1")
;; Header-insertion hair
@@ -935,11 +938,20 @@ repository, prompting for the directory and the VC backend to
use."
(catch 'found
;; First try: find a responsible backend, it must be a backend
- ;; under which FILE is not yet registered.
- (dolist (backend vc-handled-backends)
- (and (not (vc-call-backend backend 'registered file))
- (vc-call-backend backend 'responsible-p file)
- (throw 'found backend)))
+ ;; under which FILE is not yet registered and with the most
+ ;; specific path to FILE.
+ (let ((max 0)
+ bk)
+ (dolist (backend vc-handled-backends)
+ (when (not (vc-call-backend backend 'registered file))
+ (let* ((dir-name (vc-call-backend backend 'responsible-p file))
+ (len (and dir-name
+ (length (file-name-split
+ (expand-file-name dir-name))))))
+ (when (and len (> len max))
+ (setq max len bk backend)))))
+ (when bk
+ (throw 'found bk)))
;; no responsible backend
(let* ((possible-backends
(let (pos)
@@ -967,7 +979,7 @@ use."
(message "arg %s" arg)
(and (file-directory-p arg)
(string-prefix-p (expand-file-name arg) def-dir)))))))
- (let ((default-directory repo-dir))
+ (let ((default-directory repo-dir))
(vc-call-backend bk 'create-repo))
(throw 'found bk))))
@@ -1010,7 +1022,7 @@ responsible for the given file."
(error "No VC backend is responsible for %s" file))))
(defun vc-expand-dirs (file-or-dir-list backend)
- "Expands directories in a file list specification.
+ "Expand directories in a file list specification.
Within directories, only files already under version control are noticed."
(let ((flattened '()))
(dolist (node file-or-dir-list)
@@ -1150,15 +1162,17 @@ BEWARE: this function may change the current buffer."
(memq (vc-state file) '(edited needs-merge conflict))))))
(defun vc-compatible-state (p q)
- "Controls which states can be in the same commit."
+ "Control which states can be in the same commit."
(or
(eq p q)
(and (member p '(edited added removed)) (member q '(edited added removed)))))
-(defun vc-read-backend (prompt)
- (intern
- (completing-read prompt (mapcar #'symbol-name vc-handled-backends)
- nil 'require-match)))
+(defun vc-read-backend (prompt &optional backends default)
+ (let ((backends (or backends vc-handled-backends))
+ (completion-ignore-case t))
+ (intern
+ (completing-read prompt (mapcar #'symbol-name backends)
+ nil 'require-match nil nil default))))
;; Here's the major entry point.
@@ -1184,7 +1198,11 @@ For old-style locking-based version control systems, like RCS:
*vc-log* buffer to check in the changes. Leave a
read-only copy of each changed file after checking in.
If every file is locked by you and unchanged, unlock them.
- If every file is locked by someone else, offer to steal the lock."
+ If every file is locked by someone else, offer to steal the lock.
+
+When using this command to register a new file (or files), it
+will automatically deduce which VC repository to register it
+with, using the most specific one."
(interactive "P")
(let* ((vc-fileset (vc-deduce-fileset nil t 'state-model-only-files))
(backend (car vc-fileset))
@@ -1212,7 +1230,11 @@ For old-style locking-based version control systems, like RCS:
((eq state 'ignored)
(error "Fileset files are ignored by the version-control system"))
((or (null state) (eq state 'unregistered))
- (vc-register vc-fileset))
+ (cond (verbose
+ (let ((backend (vc-read-backend "Backend to register to: ")))
+ (vc-register (cons backend (cdr vc-fileset)))))
+ (t
+ (vc-register vc-fileset))))
;; Files are up-to-date, or need a merge and user specified a revision
((or (eq state 'up-to-date) (and verbose (eq state 'needs-update)))
(cond
@@ -1367,14 +1389,7 @@ For old-style locking-based version control systems, like RCS:
(defun vc-create-repo (backend)
"Create an empty repository in the current directory."
- (interactive
- (list
- (intern
- (upcase
- (completing-read
- "Create repository for: "
- (mapcar (lambda (b) (list (downcase (symbol-name b)))) vc-handled-backends)
- nil t)))))
+ (interactive (list (vc-read-backend "Create repository for: ")))
(vc-call-backend backend 'create-repo))
;;;###autoload
@@ -1727,6 +1742,7 @@ to override the value of `vc-diff-switches' and `diff-switches'."
(insert (cdr messages) ".\n")
(message "%s" (cdr messages))))
(diff-setup-whitespace)
+ (diff-setup-buffer-type)
(goto-char (point-min))
(when window
(shrink-window-if-larger-than-buffer window)))
@@ -1862,13 +1878,10 @@ Return t if the buffer had changes, nil otherwise."
(vc-working-revision first))))
(when (string= rev1-default "") (setq rev1-default nil))))
;; construct argument list
- (let* ((rev1-prompt (if rev1-default
- (concat "Older revision (default "
- rev1-default "): ")
- "Older revision: "))
- (rev2-prompt (concat "Newer revision (default "
- ;; (or rev2-default
- "current source): "))
+ (let* ((rev1-prompt (format-prompt "Older revision" rev1-default))
+ (rev2-prompt (format-prompt "Newer revision"
+ ;; (or rev2-default
+ "current source"))
(rev1 (vc-read-revision rev1-prompt files backend rev1-default))
(rev2 (vc-read-revision rev2-prompt files backend nil))) ;; rev2-default
(when (string= rev1 "") (setq rev1 nil))
@@ -2055,9 +2068,9 @@ saving the buffer."
;; here, this way the *vc-diff* buffer is setup correctly, so
;; relative file names work.
(let ((default-directory rootdir))
- (vc-diff-internal
- t (list backend (list (expand-file-name rootdir)) working-revision) nil nil
- (called-interactively-p 'interactive))))))
+ (vc-diff-internal
+ t (list backend (list rootdir) working-revision) nil nil
+ (called-interactively-p 'interactive))))))
;;;###autoload
(defun vc-root-dir ()
@@ -2081,7 +2094,7 @@ If `F.~REV~' already exists, use it instead of checking it out again."
(with-current-buffer (or (buffer-base-buffer) (current-buffer))
(vc-ensure-vc-buffer)
(list
- (vc-read-revision "Revision to visit (default is working revision): "
+ (vc-read-revision (format-prompt "Revision to visit" "working revision")
(list buffer-file-name)))))
(set-buffer (or (buffer-base-buffer) (current-buffer)))
(vc-ensure-vc-buffer)
@@ -2377,7 +2390,7 @@ This function runs the hook `vc-retrieve-tag-hook' when finished."
(read-directory-name "Directory: " default-directory nil t))))
(list
dir
- (vc-read-revision "Tag name to retrieve (default latest revisions): "
+ (vc-read-revision (format-prompt "Tag name to retrieve" "latest revisions")
(list dir)
(vc-responsible-backend dir)))))
(let* ((backend (vc-responsible-backend dir))
@@ -2603,8 +2616,8 @@ with its diffs (if the underlying VCS supports that)."
(setq backend (vc-responsible-backend rootdir))
(unless backend
(error "Directory is not version controlled")))
- (setq default-directory (expand-file-name rootdir))
- (vc-print-log-internal backend (list default-directory) revision revision limit
+ (setq default-directory rootdir)
+ (vc-print-log-internal backend (list rootdir) revision revision limit
(when with-diff 'with-diff))))
;;;###autoload
@@ -2623,7 +2636,7 @@ with its diffs (if the underlying VCS supports that)."
;;;###autoload
(defun vc-log-incoming (&optional remote-location)
- "Show a log of changes that will be received with a pull operation from 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."
(interactive
(when current-prefix-arg
@@ -2636,7 +2649,7 @@ When called interactively with a prefix argument, prompt for REMOTE-LOCATION."
;;;###autoload
(defun vc-log-outgoing (&optional remote-location)
- "Show a log of changes that will be sent with a push operation to 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."
(interactive
(when current-prefix-arg
@@ -2757,7 +2770,7 @@ to the working revision (except for keyword expansion)."
(if (= nfiles 1) "" "s"))))))
(error "Revert canceled")))
(when diff-buffer
- (quit-windows-on diff-buffer)))
+ (quit-windows-on diff-buffer (eq vc-revert-show-diff 'kill))))
(dolist (file files)
(message "Reverting %s..." (vc-delistify files))
(vc-revert-file file)
@@ -2863,6 +2876,7 @@ permanent, only for the current session. This function only changes
VC's perspective on FILE, it does not register or unregister it.
By default, this command cycles through the registered backends.
To get a prompt, use a prefix argument."
+ (declare (obsolete nil "28.1"))
(interactive
(list
(or buffer-file-name
@@ -2882,12 +2896,7 @@ To get a prompt, use a prefix argument."
(cond
((null others) (error "No other backend to switch to"))
(current-prefix-arg
- (intern
- (upcase
- (completing-read
- (format "Switch to backend [%s]: " def)
- (mapcar (lambda (b) (list (downcase (symbol-name b)))) backends)
- nil t nil nil (downcase (symbol-name def))))))
+ (vc-read-backend "Switch to backend: " backends (symbol-name def)))
(t def))))))
(unless (eq backend (vc-backend file))
(vc-file-clearprops file)
@@ -2922,7 +2931,8 @@ backend to NEW-BACKEND, and unregister FILE from the current backend.
(if registered
(set-file-modes file (logior (file-modes file) 128))
;; `registered' might have switched under us.
- (vc-switch-backend file old-backend)
+ (with-suppressed-warnings ((obsolete vc-switch-backend))
+ (vc-switch-backend file old-backend))
(let* ((rev (vc-working-revision file))
(modified-file (and edited (make-temp-file file)))
(unmodified-file (and modified-file (vc-version-backup-file file))))
@@ -2941,16 +2951,19 @@ backend to NEW-BACKEND, and unregister FILE from the current backend.
(vc-revert-file file))))
(vc-call-backend new-backend 'receive-file file rev))
(when modified-file
- (vc-switch-backend file new-backend)
+ (with-suppressed-warnings ((obsolete vc-switch-backend))
+ (vc-switch-backend file new-backend))
(unless (eq (vc-checkout-model new-backend (list file)) 'implicit)
(vc-checkout file))
(rename-file modified-file file 'ok-if-already-exists)
(vc-file-setprop file 'vc-checkout-time nil)))))
(when move
- (vc-switch-backend file old-backend)
+ (with-suppressed-warnings ((obsolete vc-switch-backend))
+ (vc-switch-backend file old-backend))
(setq comment (vc-call-backend old-backend 'comment-history file))
(vc-call-backend old-backend 'unregister file))
- (vc-switch-backend file new-backend)
+ (with-suppressed-warnings ((obsolete vc-switch-backend))
+ (vc-switch-backend file new-backend))
(when (or move edited)
(vc-file-setprop file 'vc-state 'edited)
(vc-mode-line file new-backend)
@@ -3072,20 +3085,6 @@ log entries should be gathered."
(vc-call-backend (vc-responsible-backend default-directory)
'update-changelog args))
-;; functions that operate on RCS revision numbers. This code should
-;; also be moved into the backends. It stays for now, however, since
-;; it is used in code below.
-(defun vc-branch-p (rev)
- "Return t if REV is a branch revision."
- (not (eq nil (string-match "\\`[0-9]+\\(\\.[0-9]+\\.[0-9]+\\)*\\'" rev))))
-
-;;;###autoload
-(defun vc-branch-part (rev)
- "Return the branch part of a revision number REV."
- (let ((index (string-match "\\.[0-9]+\\'" rev)))
- (when index
- (substring rev 0 index))))
-
(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/vcursor.el b/lisp/vcursor.el
index e219dc2d1a5..df65db39e38 100644
--- a/lisp/vcursor.el
+++ b/lisp/vcursor.el
@@ -788,9 +788,9 @@ out how much to copy."
(vcursor-check)
(with-current-buffer (overlay-buffer vcursor-overlay)
- (let ((start (goto-char (overlay-start vcursor-overlay))))
- (- (progn (apply func args) (point)) start)))
- )
+ (save-excursion
+ (let ((start (goto-char (overlay-start vcursor-overlay))))
+ (- (progn (apply func args) (point)) start)))))
;; Make sure the virtual cursor is active. Unless arg is non-nil,
;; report an error if it is not.
diff --git a/lisp/version.el b/lisp/version.el
index 3a3093fdd4a..5d0a1ae37dc 100644
--- a/lisp/version.el
+++ b/lisp/version.el
@@ -53,6 +53,8 @@ developing Emacs.")
(defvar ns-version-string)
(defvar cairo-version-string)
+(declare-function haiku-get-version-string "haikufns.c")
+
(defun emacs-version (&optional here)
"Return string describing the version of Emacs that is running.
If optional argument HERE is non-nil, insert string at point.
@@ -71,6 +73,8 @@ to the system configuration; look at `system-configuration' instead."
((featurep 'x-toolkit) ", X toolkit")
((featurep 'ns)
(format ", NS %s" ns-version-string))
+ ((featurep 'haiku)
+ (format ", Haiku %s" (haiku-get-version-string)))
(t ""))
(if (featurep 'cairo)
(format ", cairo version %s" cairo-version-string)
diff --git a/lisp/view.el b/lisp/view.el
index 3476ced3f79..321bc5f5660 100644
--- a/lisp/view.el
+++ b/lisp/view.el
@@ -36,8 +36,8 @@
;;; Suggested key bindings:
;;
-;; (define-key ctl-x-4-map "v" #'view-file-other-window) ; ^x4v
-;; (define-key ctl-x-5-map "v" #'view-file-other-frame) ; ^x5v
+;; (keymap-set ctl-x-4-map "v" #'view-file-other-window) ; C-x 4 v
+;; (keymap-set ctl-x-5-map "v" #'view-file-other-frame) ; C-x 5 v
;;
;; You could also bind `view-file', `view-buffer', `view-buffer-other-window' and
;; `view-buffer-other-frame' to keys.
@@ -142,68 +142,68 @@ that use View mode automatically.")
(defvar-local view-overlay nil
"Overlay used to display where a search operation found its match.
This is local in each buffer, once it is used.")
+
-;; Define keymap inside defvar to make it easier to load changes.
;; Some redundant "less"-like key bindings below have been commented out.
-(defvar view-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "C" #'View-kill-and-leave)
- (define-key map "c" #'View-leave)
- (define-key map "Q" #'View-quit-all)
- (define-key map "E" #'View-exit-and-edit)
- ;; (define-key map "v" #'View-exit)
- (define-key map "e" #'View-exit)
- (define-key map "q" #'View-quit)
- ;; (define-key map "N" #'View-search-last-regexp-backward)
- (define-key map "p" #'View-search-last-regexp-backward)
- (define-key map "n" #'View-search-last-regexp-forward)
- ;; (define-key map "?" #'View-search-regexp-backward) ; Less does this.
- (define-key map "\\" #'View-search-regexp-backward)
- (define-key map "/" #'View-search-regexp-forward)
- (define-key map "r" #'isearch-backward)
- (define-key map "s" #'isearch-forward)
- (define-key map "m" #'point-to-register)
- (define-key map "'" #'register-to-point)
- (define-key map "x" #'exchange-point-and-mark)
- (define-key map "@" #'View-back-to-mark)
- (define-key map "." #'set-mark-command)
- (define-key map "%" #'View-goto-percent)
- ;; (define-key map "G" #'View-goto-line-last)
- (define-key map "g" #'View-goto-line)
- (define-key map "=" #'what-line)
- (define-key map "F" #'View-revert-buffer-scroll-page-forward)
- ;; (define-key map "k" #'View-scroll-line-backward)
- (define-key map "y" #'View-scroll-line-backward)
- ;; (define-key map "j" #'View-scroll-line-forward)
- (define-key map "\n" #'View-scroll-line-forward)
- (define-key map "\r" #'View-scroll-line-forward)
- (define-key map "u" #'View-scroll-half-page-backward)
- (define-key map "d" #'View-scroll-half-page-forward)
- (define-key map "z" #'View-scroll-page-forward-set-page-size)
- (define-key map "w" #'View-scroll-page-backward-set-page-size)
- ;; (define-key map "b" #'View-scroll-page-backward)
- (define-key map "\C-?" #'View-scroll-page-backward)
- ;; (define-key map "f" #'View-scroll-page-forward)
- (define-key map " " #'View-scroll-page-forward)
- (define-key map [?\S-\ ] #'View-scroll-page-backward)
- (define-key map "o" #'View-scroll-to-buffer-end)
- (define-key map ">" #'end-of-buffer)
- (define-key map "<" #'beginning-of-buffer)
- (define-key map "-" #'negative-argument)
- (define-key map "9" #'digit-argument)
- (define-key map "8" #'digit-argument)
- (define-key map "7" #'digit-argument)
- (define-key map "6" #'digit-argument)
- (define-key map "5" #'digit-argument)
- (define-key map "4" #'digit-argument)
- (define-key map "3" #'digit-argument)
- (define-key map "2" #'digit-argument)
- (define-key map "1" #'digit-argument)
- (define-key map "0" #'digit-argument)
- (define-key map "H" #'describe-mode)
- (define-key map "?" #'describe-mode) ; Maybe do as less instead? See above.
- (define-key map "h" #'describe-mode)
- map))
+(defvar-keymap view-mode-map
+ :doc "Keymap for ‘view-mode’."
+ "C" #'View-kill-and-leave
+ "c" #'View-leave
+ "Q" #'View-quit-all
+ "E" #'View-exit-and-edit
+ ;; "v" #'View-exit
+ "e" #'View-exit
+ "q" #'View-quit
+ ;; "N" #'View-search-last-regexp-backward
+ "p" #'View-search-last-regexp-backward
+ "n" #'View-search-last-regexp-forward
+ ;; "?" #'View-search-regexp-backward ; Less does this.
+ "\\" #'View-search-regexp-backward
+ "/" #'View-search-regexp-forward
+ "r" #'isearch-backward
+ "s" #'isearch-forward
+ "m" #'point-to-register
+ "'" #'register-to-point
+ "x" #'exchange-point-and-mark
+ "@" #'View-back-to-mark
+ "." #'set-mark-command
+ "%" #'View-goto-percent
+ ;; "G" #'View-goto-line-last
+ "g" #'View-goto-line
+ "=" #'what-line
+ "F" #'View-revert-buffer-scroll-page-forward
+ ;; "k" #'View-scroll-line-backward
+ "y" #'View-scroll-line-backward
+ ;; "j" #'View-scroll-line-forward
+ "C-j" #'View-scroll-line-forward
+ "RET" #'View-scroll-line-forward
+ "u" #'View-scroll-half-page-backward
+ "d" #'View-scroll-half-page-forward
+ "z" #'View-scroll-page-forward-set-page-size
+ "w" #'View-scroll-page-backward-set-page-size
+ ;; "b" #'View-scroll-page-backward
+ "DEL" #'View-scroll-page-backward
+ ;; "f" #'View-scroll-page-forward
+ "SPC" #'View-scroll-page-forward
+ "S-SPC" #'View-scroll-page-backward
+ "o" #'View-scroll-to-buffer-end
+ ">" #'end-of-buffer
+ "<" #'beginning-of-buffer
+ "-" #'negative-argument
+ "9" #'digit-argument
+ "8" #'digit-argument
+ "7" #'digit-argument
+ "6" #'digit-argument
+ "5" #'digit-argument
+ "4" #'digit-argument
+ "3" #'digit-argument
+ "2" #'digit-argument
+ "1" #'digit-argument
+ "0" #'digit-argument
+ "H" #'describe-mode
+ "?" #'describe-mode ; Maybe do as less instead? See above.
+ "h" #'describe-mode)
+
;;; Commands that enter or exit view mode.
diff --git a/lisp/vt-control.el b/lisp/vt-control.el
index bac0069b852..8f62b5757a3 100644
--- a/lisp/vt-control.el
+++ b/lisp/vt-control.el
@@ -23,7 +23,7 @@
;;; Commentary:
;; The functions contained in this file send various VT control codes
-;; to the terminal where emacs is running. The following functions are
+;; to the terminal where Emacs is running. The following functions are
;; available.
;; Function Action
diff --git a/lisp/wdired.el b/lisp/wdired.el
index fd549bac322..eb5a6385563 100644
--- a/lisp/wdired.el
+++ b/lisp/wdired.el
@@ -453,7 +453,7 @@ non-nil means return old filename."
(remove-function (local 'revert-buffer-function) #'wdired-revert))
(defun wdired-abort-changes ()
- "Abort changes and return to dired mode."
+ "Abort changes and return to `dired-mode'."
(interactive)
(remove-hook 'before-change-functions #'wdired--before-change-fn t)
(let ((inhibit-read-only t))
@@ -689,7 +689,7 @@ Optional arguments are ignored."
;; FIXME: Can't we use the normal mechanism for that? --Stef
(if (and
(buffer-modified-p)
- (not (y-or-n-p "Buffer changed. Discard changes and kill buffer? ")))
+ (not (y-or-n-p "Buffer changed. Discard changes and kill buffer?")))
(error "Error")))
;; Added to after-change-functions in wdired-change-to-wdired-mode to
diff --git a/lisp/whitespace.el b/lisp/whitespace.el
index a2dc6ab9814..5a482c5253a 100644
--- a/lisp/whitespace.el
+++ b/lisp/whitespace.el
@@ -5,7 +5,7 @@
;; Author: Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>
;; Keywords: data, wp
;; Version: 13.2.2
-;; X-URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
+;; URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
;; This file is part of GNU Emacs.
@@ -565,8 +565,8 @@ Used when `whitespace-style' includes the value `space-before-tab'.")
(defvar whitespace-indentation 'whitespace-indentation
- "Symbol face used to visualize `tab-width' or more SPACEs at beginning of
-line. Used when `whitespace-style' includes the value `indentation'.")
+ "Symbol face used to visualize `tab-width' or more SPACEs at beginning of line.
+Used when `whitespace-style' includes the value `indentation'.")
(make-obsolete-variable 'whitespace-indentation "use the face instead." "24.4")
(defface whitespace-indentation
@@ -924,7 +924,10 @@ Any other value is treated as nil."
"Toggle whitespace visualization (Whitespace mode).
See also `whitespace-style', `whitespace-newline' and
-`whitespace-display-mappings'."
+`whitespace-display-mappings'.
+
+This mode uses a number of faces to visualize the whitespace; see
+the customization group `whitespace' for details."
:lighter " ws"
:init-value nil
:global nil
@@ -1684,32 +1687,32 @@ cleaning up these problems."
(or whitespace-active-style whitespace-style)))
(bogus-list
(mapcar
- #'(lambda (option)
- (when force
- (push (car option) style))
- (goto-char rstart)
- (let ((regexp
- (cond
- ((eq (car option) 'indentation)
- (whitespace-indentation-regexp))
- ((eq (car option) 'indentation::tab)
- (whitespace-indentation-regexp 'tab))
- ((eq (car option) 'indentation::space)
- (whitespace-indentation-regexp 'space))
- ((eq (car option) 'space-after-tab)
- (whitespace-space-after-tab-regexp))
- ((eq (car option) 'space-after-tab::tab)
- (whitespace-space-after-tab-regexp 'tab))
- ((eq (car option) 'space-after-tab::space)
- (whitespace-space-after-tab-regexp 'space))
- ((eq (car option) 'missing-newline-at-eof)
- "[^\n]\\'")
- (t
- (cdr option)))))
- (when (re-search-forward regexp rend t)
- (unless has-bogus
- (setq has-bogus (memq (car option) style)))
- t)))
+ (lambda (option)
+ (when force
+ (push (car option) style))
+ (goto-char rstart)
+ (let ((regexp
+ (cond
+ ((eq (car option) 'indentation)
+ (whitespace-indentation-regexp))
+ ((eq (car option) 'indentation::tab)
+ (whitespace-indentation-regexp 'tab))
+ ((eq (car option) 'indentation::space)
+ (whitespace-indentation-regexp 'space))
+ ((eq (car option) 'space-after-tab)
+ (whitespace-space-after-tab-regexp))
+ ((eq (car option) 'space-after-tab::tab)
+ (whitespace-space-after-tab-regexp 'tab))
+ ((eq (car option) 'space-after-tab::space)
+ (whitespace-space-after-tab-regexp 'space))
+ ((eq (car option) 'missing-newline-at-eof)
+ "[^\n]\\'")
+ (t
+ (cdr option)))))
+ (when (re-search-forward regexp rend t)
+ (unless has-bogus
+ (setq has-bogus (memq (car option) style)))
+ t)))
whitespace-report-list)))
(when (pcase report-if-bogus ('nil t) ('never nil) (_ has-bogus))
(whitespace-kill-buffer whitespace-report-buffer-name)
@@ -1719,30 +1722,32 @@ cleaning up these problems."
(ws-tab-width tab-width))
(with-current-buffer (get-buffer-create
whitespace-report-buffer-name)
- (erase-buffer)
- (insert (if ws-indent-tabs-mode
- (car whitespace-report-text)
- (cdr whitespace-report-text)))
- (goto-char (point-min))
- (forward-line 3)
- (dolist (option whitespace-report-list)
+ (let ((inhibit-read-only t))
+ (special-mode)
+ (erase-buffer)
+ (insert (if ws-indent-tabs-mode
+ (car whitespace-report-text)
+ (cdr whitespace-report-text)))
+ (goto-char (point-min))
+ (forward-line 3)
+ (dolist (option whitespace-report-list)
+ (forward-line 1)
+ (whitespace-mark-x
+ 27 (memq (car option) style))
+ (whitespace-mark-x 7 (car bogus-list))
+ (setq bogus-list (cdr bogus-list)))
(forward-line 1)
- (whitespace-mark-x
- 27 (memq (car option) style))
- (whitespace-mark-x 7 (car bogus-list))
- (setq bogus-list (cdr bogus-list)))
- (forward-line 1)
- (whitespace-insert-value ws-indent-tabs-mode)
- (whitespace-insert-value ws-tab-width)
- (when has-bogus
- (goto-char (point-max))
- (insert (substitute-command-keys
- " Type `\\[whitespace-cleanup]'")
- " to cleanup the buffer.\n\n"
- (substitute-command-keys
- " Type `\\[whitespace-cleanup-region]'")
- " to cleanup a region.\n\n"))
- (whitespace-display-window (current-buffer)))))
+ (whitespace-insert-value ws-indent-tabs-mode)
+ (whitespace-insert-value ws-tab-width)
+ (when has-bogus
+ (goto-char (point-max))
+ (insert (substitute-command-keys
+ " Type `\\[whitespace-cleanup]'")
+ " to cleanup the buffer.\n\n"
+ (substitute-command-keys
+ " Type `\\[whitespace-cleanup-region]'")
+ " to cleanup a region.\n\n"))
+ (whitespace-display-window (current-buffer))))))
has-bogus)))
@@ -1831,17 +1836,14 @@ cleaning up these problems."
(defun whitespace-display-window (buffer)
- "Display BUFFER in a new window."
+ "Display BUFFER, preferably below the selected window."
(goto-char (point-min))
(set-buffer-modified-p nil)
- (when (< (window-height) (* 2 window-min-height))
- (kill-buffer buffer)
- (error "Window height is too small; \
-can't split window to display whitespace toggle options"))
- (let ((win (split-window)))
- (set-window-buffer win buffer)
- (shrink-window-if-larger-than-buffer win)))
-
+ (let ((window (display-buffer
+ buffer
+ `((display-buffer-reuse-window
+ display-buffer-below-selected)))))
+ (shrink-window-if-larger-than-buffer window)))
(defun whitespace-kill-buffer (buffer-name)
"Kill buffer BUFFER-NAME and windows related with it."
@@ -2191,8 +2193,7 @@ resultant list will be returned."
limit t))
(defun whitespace-empty-at-bob-regexp (limit)
- "Match spaces at beginning of buffer which do not contain the point at \
-beginning of buffer."
+ "Match spaces at beginning of buffer (BOB) which do not contain point at BOB."
(let ((b (point))
r)
(cond
@@ -2352,7 +2353,7 @@ Also refontify when necessary."
(defun whitespace-display-vector-p (vec)
- "Return true if every character in vector VEC can be displayed."
+ "Return non-nil if every character in vector VEC can be displayed."
(let ((i (length vec)))
(when (> i 0)
(while (and (>= (setq i (1- i)) 0)
@@ -2462,5 +2463,4 @@ It should be added buffer-locally to `write-file-functions'."
"use `with-eval-after-load' instead." "28.1")
(run-hooks 'whitespace-load-hook)
-
;;; whitespace.el ends here
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index 9a34dc8d438..a53add7d084 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -190,7 +190,7 @@ the contents of strings."
(buffer-enable-undo))
(defcustom widget-menu-max-size 40
- "Largest number of items allowed in a popup-menu.
+ "Largest number of items allowed in a popup menu.
Larger menus are read through the minibuffer."
:group 'widgets
:type 'integer)
@@ -202,9 +202,8 @@ For a larger number of items, the minibuffer is used."
:type 'integer)
(defcustom widget-menu-minibuffer-flag nil
- "Control how to ask for a choice from the keyboard.
-Non-nil means use the minibuffer;
-nil means read a single character."
+ "Non-nil means use the minibuffer; to ask for a choice from the keyboard.
+If nil, read a single character."
:group 'widgets
:type 'boolean)
@@ -2969,7 +2968,8 @@ Save CHILD into the :last-deleted list, so it can be inserted later."
"A widget which groups other widgets inside."
:convert-widget 'widget-types-convert-widget
:copy 'widget-types-copy
- :format ":\n%v"
+ :format (concat (propertize ":" 'display "")
+ "\n%v")
:value-create 'widget-group-value-create
:value-get 'widget-editable-list-value-get
:default-get 'widget-group-default-get
@@ -3326,7 +3326,7 @@ It reads a file name from an editable text field."
;;; (file (file-name-nondirectory value))
;;; (menu-tag (widget-apply widget :menu-tag-get))
;;; (must-match (widget-get widget :must-match))
-;;; (answer (read-file-name (concat menu-tag " (default " value "): ")
+;;; (answer (read-file-name (format-prompt menu-tag value)
;;; dir nil must-match file)))
;;; (widget-value-set widget (abbreviate-file-name answer))
;;; (widget-setup)
@@ -3645,6 +3645,13 @@ match-alternatives: %S"
:type-error "This field should contain an integer"
:match-alternatives '(integerp))
+(define-widget 'natnum 'restricted-sexp
+ "A nonnegative integer."
+ :tag "Integer (positive or zero)"
+ :value 0
+ :type-error "This field should contain a nonnegative integer"
+ :match-alternatives '(natnump))
+
(define-widget 'number 'restricted-sexp
"A number (floating point or integer)."
:tag "Number"
diff --git a/lisp/widget.el b/lisp/widget.el
index d258e6fae2b..0232f6cf93f 100644
--- a/lisp/widget.el
+++ b/lisp/widget.el
@@ -4,7 +4,7 @@
;;
;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
;; Keywords: help, extensions, faces, hypermedia
-;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
+;; URL: http://www.dina.kvl.dk/~abraham/custom/
;; Package: emacs
;; This file is part of GNU Emacs.
@@ -44,7 +44,7 @@
;; (list 'or (list 'boundp (list 'car 'keywords))
;; (list 'set (list 'car 'keywords) (list 'car 'keywords)))
;; (list 'setq 'keywords (list 'cdr 'keywords)))))
- (declare (obsolete nil "27.1"))
+ (declare (obsolete nil "27.1") (indent defun))
nil)
;;(define-widget-keywords :documentation-indent
@@ -83,10 +83,10 @@ create identical widgets:
* (apply #\\='widget-create CLASS ARGS)
The third argument DOC is a documentation string for the widget."
- (declare (doc-string 3))
+ (declare (doc-string 3) (indent defun))
;;
(unless (or (null doc) (stringp doc))
- (error "widget documentation must be nil or a string."))
+ (error "Widget documentation must be nil or a string"))
(put name 'widget-type (cons class args))
(put name 'widget-documentation (purecopy doc))
name)
diff --git a/lisp/windmove.el b/lisp/windmove.el
index f747c409431..8904f5cbf70 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -170,7 +170,7 @@ placement bugs in old versions of Emacs."
(defcustom windmove-allow-all-windows nil
"Whether the windmove commands are allowed to target all type of windows.
-If this variable is set to non-nil, all windmove commmands will
+If this variable is set to non-nil, all windmove commands will
ignore the `no-other-window' parameter applied by `display-buffer-alist'
or `set-window-parameter'."
:type 'boolean
@@ -498,7 +498,7 @@ Default value of MODIFIERS is `shift'."
(defcustom windmove-display-no-select nil
"Whether the window should be selected after displaying the buffer in it.
-If `nil', then the new window where the buffer is displayed will be selected.
+If nil, then the new window where the buffer is displayed will be selected.
If `ignore', then don't select a window: neither the new nor the old window,
thus allowing the next command to decide what window it selects.
Other non-nil values will reselect the old window that was selected before.
@@ -525,7 +525,7 @@ to decide what window it selects. With other non-nil values of
`windmove-display-no-select', this function reselects
a previously selected old window.
-If prefix ARG is `C-u', reselect a previously selected old window.
+If prefix ARG is \\[universal-argument], reselect a previously selected old window.
If `windmove-display-no-select' is non-nil, the meaning of
the prefix argument is reversed and it selects the new window.
@@ -662,7 +662,7 @@ from the opposite side of the frame."
;;;###autoload
(defun windmove-delete-left (&optional arg)
"Delete the window to the left of the current one.
-If prefix ARG is `C-u', delete the selected window and
+If prefix ARG is \\[universal-argument], delete the selected window and
select the window that was to the left of the current one."
(interactive "P")
(windmove-delete-in-direction 'left arg))
@@ -670,7 +670,7 @@ select the window that was to the left of the current one."
;;;###autoload
(defun windmove-delete-up (&optional arg)
"Delete the window above the current one.
-If prefix ARG is `C-u', delete the selected window and
+If prefix ARG is \\[universal-argument], delete the selected window and
select the window that was above the current one."
(interactive "P")
(windmove-delete-in-direction 'up arg))
@@ -678,7 +678,7 @@ select the window that was above the current one."
;;;###autoload
(defun windmove-delete-right (&optional arg)
"Delete the window to the right of the current one.
-If prefix ARG is `C-u', delete the selected window and
+If prefix ARG is \\[universal-argument], delete the selected window and
select the window that was to the right of the current one."
(interactive "P")
(windmove-delete-in-direction 'right arg))
@@ -686,7 +686,7 @@ select the window that was to the right of the current one."
;;;###autoload
(defun windmove-delete-down (&optional arg)
"Delete the window below the current one.
-If prefix ARG is `C-u', delete the selected window and
+If prefix ARG is \\[universal-argument], delete the selected window and
select the window that was below the current one."
(interactive "P")
(windmove-delete-in-direction 'down arg))
@@ -698,9 +698,9 @@ Keys are bound to commands that delete windows in the specified
direction. Keybindings are of the form PREFIX MODIFIERS-{left,right,up,down},
where PREFIX is a prefix key and MODIFIERS is either a list of modifiers or
a single modifier.
-If PREFIX is `none', no prefix is used. If MODIFIERS is `none', the keybindings
-are directly bound to the arrow keys.
-Default value of PREFIX is `C-x' and MODIFIERS is `shift'."
+If PREFIX is `none', no prefix is used. If MODIFIERS is `none',
+the keybindings are directly bound to the arrow keys.
+Default value of PREFIX is \\`C-x' and MODIFIERS is `shift'."
(interactive)
(unless prefix (setq prefix '(?\C-x)))
(when (eq prefix 'none) (setq prefix nil))
diff --git a/lisp/window.el b/lisp/window.el
index e14d472cf3f..0f17bb28b4c 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -108,11 +108,14 @@ Return the buffer."
;; Return the buffer.
buffer)))
+;; Defined in help.el.
+(defvar resize-temp-buffer-window-inhibit)
+
(defun temp-buffer-window-show (buffer &optional action)
"Show temporary buffer BUFFER in a window.
Return the window showing BUFFER. Pass ACTION as action argument
to `display-buffer'."
- (let (window frame)
+ (let (resize-temp-buffer-window-inhibit window)
(with-current-buffer buffer
(set-buffer-modified-p nil)
(setq buffer-read-only t)
@@ -130,9 +133,9 @@ to `display-buffer'."
t
window-combination-limit)))
(setq window (display-buffer buffer action)))
- (setq frame (window-frame window))
- (unless (eq frame (selected-frame))
- (raise-frame frame))
+ ;; We used to raise the window's frame here. Do not do that
+ ;; since it would override an `inhibit-switch-frame' entry
+ ;; specified for the action alist used by `display-buffer'.
(setq minibuffer-scroll-window window)
(set-window-hscroll window 0)
(with-selected-window window
@@ -634,7 +637,7 @@ is unpredictable."
(defun window-with-parameter (parameter &optional value frame any minibuf)
"Return first window on FRAME with PARAMETER non-nil.
FRAME defaults to the selected frame. Optional argument VALUE
-non-nil means only return a window whose window-parameter value
+non-nil means only return a window whose `window-parameter' value
for PARAMETER equals VALUE (comparison is done with `equal').
Optional argument ANY non-nil means consider internal windows
too.
@@ -867,7 +870,7 @@ window annihilates any effect provided by this variable.")
(defun window--sides-reverse-on-frame-p (frame)
"Return non-nil when side windows should appear reversed on FRAME.
This uses some heuristics to guess the user's intentions when the
-selected window of FRAME is a side window ."
+selected window of FRAME is a side window."
(cond
;; Reverse when `window-sides-reversed' is t. Do not reverse when
;; `window-sides-reversed' is nil.
@@ -1212,7 +1215,8 @@ it is found."
((setq state (frame-parameter frame 'window-state))
;; A window state was saved for FRAME. Restore it and put the
;; current root window into its main window.
- (let ((main-state (window-state-get (frame-root-window frame))))
+ (let ((window-combination-resize t)
+ (main-state (window-state-get (frame-root-window frame))))
(window-state-put state (frame-root-window frame) t)
(window-state-put main-state (window-main-window frame)))
(window--sides-reverse-frame frame))
@@ -1406,9 +1410,12 @@ before writing to it."
(cadr fringes)
(window-scroll-bar-width window)
(window-right-divider-width window))
- (format "height header-line: %s mode-line: %s divider: %s\n"
+ (format "height tab-line: %s header-line: %s mode-line: %s\n"
+ (window-tab-line-height window)
(window-header-line-height window)
- (window-mode-line-height window)
+ (window-mode-line-height window))
+ (format "height scroll-bar: %s divider: %s"
+ (window-scroll-bar-height window)
(window-bottom-divider-width window)))))
(insert "\n")))
@@ -1510,21 +1517,11 @@ Emacs won't change the size of any window displaying that buffer,
unless it has no other choice (like when deleting a neighboring
window).")
-(defun window--preservable-size (window &optional horizontal)
- "Return height of WINDOW as `window-preserve-size' would preserve it.
-Optional argument HORIZONTAL non-nil means to return the width of
-WINDOW as `window-preserve-size' would preserve it."
- (if horizontal
- (window-body-width window t)
- (+ (window-body-height window t)
- (window-header-line-height window)
- (window-mode-line-height window))))
-
(defun window-preserve-size (&optional window horizontal preserve)
- "Preserve height of window WINDOW.
+ "Preserve height of specified WINDOW's body.
WINDOW must be a live window and defaults to the selected one.
-Optional argument HORIZONTAL non-nil means preserve the width of
-WINDOW.
+Optional argument HORIZONTAL non-nil means to preserve the width
+of WINDOW's body.
PRESERVE t means to preserve the current height/width of WINDOW's
body in frame and window resizing operations whenever possible.
@@ -1541,21 +1538,15 @@ WINDOW as argument also removes the respective restraint.
Other values of PRESERVE are reserved for future use."
(setq window (window-normalize-window window t))
(let* ((parameter (window-parameter window 'window-preserved-size))
- (width (nth 1 parameter))
- (height (nth 2 parameter)))
- (if horizontal
- (set-window-parameter
- window 'window-preserved-size
- (list
- (window-buffer window)
- (and preserve (window--preservable-size window t))
- height))
- (set-window-parameter
- window 'window-preserved-size
- (list
- (window-buffer window)
- width
- (and preserve (window--preservable-size window)))))))
+ (width (if horizontal
+ (and preserve (window-body-width window t))
+ (nth 1 parameter)))
+ (height (if horizontal
+ (nth 2 parameter)
+ (and preserve (window-body-height window t)))))
+ (set-window-parameter
+ window 'window-preserved-size
+ (list (window-buffer window) width height))))
(defun window-preserved-size (&optional window horizontal)
"Return preserved height of window WINDOW.
@@ -1563,12 +1554,9 @@ WINDOW must be a live window and defaults to the selected one.
Optional argument HORIZONTAL non-nil means to return preserved
width of WINDOW."
(setq window (window-normalize-window window t))
- (let* ((parameter (window-parameter window 'window-preserved-size))
- (buffer (nth 0 parameter))
- (width (nth 1 parameter))
- (height (nth 2 parameter)))
- (when (eq buffer (window-buffer window))
- (if horizontal width height))))
+ (let ((parameter (window-parameter window 'window-preserved-size)))
+ (when (eq (nth 0 parameter) (window-buffer window))
+ (nth (if horizontal 1 2) parameter))))
(defun window--preserve-size (window horizontal)
"Return non-nil when the height of WINDOW shall be preserved.
@@ -1576,7 +1564,7 @@ Optional argument HORIZONTAL non-nil means to return non-nil when
the width of WINDOW shall be preserved."
(let ((size (window-preserved-size window horizontal)))
(and (numberp size)
- (= size (window--preservable-size window horizontal)))))
+ (= size (window-body-size window horizontal t)))))
(defun window-safe-min-size (&optional window horizontal pixelwise)
"Return safe minimum size of WINDOW.
@@ -1690,6 +1678,7 @@ return the minimum pixel-size of WINDOW."
((let ((char-size (frame-char-size window))
(pixel-height
(+ (window-safe-min-size window nil t)
+ (window-tab-line-height window)
(window-header-line-height window)
(window-scroll-bar-height window)
(window-mode-line-height window)
@@ -4632,7 +4621,7 @@ another window. Also, if WINDOW's frame has a `buffer-predicate'
parameter, that predicate may inhibit switching to certain
buffers.
-This function is called by `prev-buffer'."
+This function is called by `previous-buffer'."
(interactive)
(let* ((window (window-normalize-window window t))
(frame (window-frame window))
@@ -6567,9 +6556,6 @@ of the window used."
(make-obsolete-variable 'display-buffer-function
'display-buffer-alist "24.3")
-;; Eventually, we want to turn this into a defvar; instead of
-;; customizing this, the user should use a `pop-up-frame-parameters'
-;; alist entry in `display-buffer-base-action'.
(defcustom pop-up-frame-alist nil
"Alist of parameters for automatically generated new frames.
If non-nil, the value you specify here is used by the default
@@ -6579,7 +6565,12 @@ Since `pop-up-frame-function' is used by `display-buffer' for
making new frames, any value specified here by default affects
the automatic generation of new frames via `display-buffer' and
all functions based on it. The behavior of `make-frame' is not
-affected by this variable."
+affected by this variable.
+
+This option is provided for backward compatibility only. New
+code should use a `pop-up-frame-parameters' action alist entry in
+`display-buffer-alist' instead. See Info node `(elisp) Choosing
+Window Options' in the Emacs Lisp manual."
:type '(repeat (cons :format "%v"
(symbol :tag "Parameter")
(sexp :tag "Value")))
@@ -6851,6 +6842,11 @@ the buffer name. This is for compatibility with
`special-display-buffer-names'; the cdr of the cons cell is
ignored.
+This variable is provided for backward compatibility only and
+should not be used in new code. Customize `display-buffer-alist'
+instead. See Info node `(elisp) Choosing Window Options' in the
+Emacs Lisp manual for an example.
+
See also `same-window-regexps'."
:type '(repeat (string :format "%v"))
:group 'windows)
@@ -6866,6 +6862,11 @@ string. In that case, the cell's car must be a regexp matching
the buffer name. This is for compatibility with
`special-display-regexps'; the cdr of the cons cell is ignored.
+This variable is provided for backward compatibility only and
+should not be used in new code. Customize `display-buffer-alist'
+instead. See Info node `(elisp) Choosing Window Options' in the
+Emacs Lisp manual for an example.
+
See also `same-window-buffer-names'."
:type '(repeat (regexp :format "%v"))
:group 'windows)
@@ -6897,7 +6898,13 @@ selected rather than (as usual) some other window. See
If nil, never make a separate frame.
If the value is `graphic-only', make a separate frame
on graphic displays only.
-Any other non-nil value means always make a separate frame."
+Any other non-nil value means always make a separate frame.
+
+This variable is provided mainly for backward compatibility and
+should not be used in new code. To make `display-buffer' behave
+as if this were t, customize `display-buffer-base-action'
+instead. See Info node `(elisp) Choosing Window Options' in the
+Emacs Lisp manual for an example."
:type '(choice
(const :tag "Never" nil)
(const :tag "On graphic displays only" graphic-only)
@@ -6918,7 +6925,12 @@ that frame."
"24.3")
(defcustom pop-up-windows t
- "Non-nil means `display-buffer' should make a new window."
+ "Non-nil means `display-buffer' should make a new window.
+This variable is provided mainly for backward compatibility and
+should not be used in new code. To make `display-buffer' behave
+as if this were t, customize `display-buffer-base-action'
+instead. See Info node `(elisp) Choosing Window Options' in the
+Emacs Lisp manual for an example."
:type 'boolean
:group 'windows)
@@ -7222,11 +7234,15 @@ Return WINDOW if BUFFER and WINDOW are live."
(inhibit-modification-hooks t))
(funcall (cdr (assq 'body-function alist)) window)))
- (let ((quit-restore (window-parameter window 'quit-restore))
- (height (cdr (assq 'window-height alist)))
- (width (cdr (assq 'window-width alist)))
- (size (cdr (assq 'window-size alist)))
- (preserve-size (cdr (assq 'preserve-size alist))))
+ (let* ((frame (window-frame window))
+ (quit-restore (window-parameter window 'quit-restore))
+ (window-height (assq 'window-height alist))
+ (height (cdr window-height))
+ (window-width (assq 'window-width alist))
+ (width (cdr window-width))
+ (window-size (assq 'window-size alist))
+ (size (cdr window-size))
+ (preserve-size (cdr (assq 'preserve-size alist))))
(cond
((or (eq type 'frame)
(and (eq (car quit-restore) 'same)
@@ -7237,29 +7253,43 @@ Return WINDOW if BUFFER and WINDOW are live."
;; Adjust size of frame if asked for. We probably should do
;; that only for a single window frame.
(cond
- ((not size))
+ ((not size)
+ (when window-size
+ (setq resize-temp-buffer-window-inhibit t)))
((consp size)
- (let ((width (car size))
- (height (cdr size))
- (frame (window-frame window)))
- (when (and (numberp width) (numberp height))
- (set-frame-height
- frame (+ (frame-height frame)
- (- height (window-total-height window))))
- (set-frame-width
- frame (+ (frame-width frame)
- (- width (window-total-width window)))))))
- ((functionp size)
- (ignore-errors (funcall size window)))))
+ ;; Modifying the parameters of a newly created frame might
+ ;; not work everywhere, but then `temp-buffer-resize-mode'
+ ;; will certainly fail in a similar fashion.
+ (if (eq (car size) 'body-chars)
+ (let ((width (+ (frame-text-width frame)
+ (* (frame-char-width frame) (cadr size))
+ (- (window-body-width window t))))
+ (height (+ (frame-text-height frame)
+ (* (frame-char-height frame) (cddr size))
+ (- (window-body-height window t)))))
+ (modify-frame-parameters
+ frame `((height . (text-pixels . ,height))
+ (width . (text-pixels . ,width)))))
+ (let ((width (- (+ (frame-width frame) (car size))
+ (window-total-width window)))
+ (height (- (+ (frame-height frame) (cdr size))
+ (window-total-height window))))
+ (modify-frame-parameters
+ frame `((height . ,height) (width . ,width)))))
+ (setq resize-temp-buffer-window-inhibit t))
+ ((functionp size)
+ (ignore-errors (funcall size window))
+ (setq resize-temp-buffer-window-inhibit t))))
((or (eq type 'window)
(and (eq (car quit-restore) 'same)
(eq (nth 1 quit-restore) 'window)))
;; A window that never showed another buffer but BUFFER ever
- ;; since it was created on an existing frame.
- ;;
- ;; Adjust width and/or height of window if asked for.
+ ;; since it was created on an existing frame. Adjust its width
+ ;; and/or height if asked for.
(cond
- ((not height))
+ ((not height)
+ (when window-height
+ (setq resize-temp-buffer-window-inhibit 'vertical)))
((numberp height)
(let* ((new-height
(if (integerp height)
@@ -7270,12 +7300,23 @@ Return WINDOW if BUFFER and WINDOW are live."
(delta (- new-height (window-total-height window))))
(when (and (window--resizable-p window delta nil 'safe)
(window-combined-p window))
- (window-resize window delta nil 'safe))))
- ((functionp height)
- (ignore-errors (funcall height window))))
+ (window-resize window delta nil 'safe)))
+ (setq resize-temp-buffer-window-inhibit 'vertical))
+ ((and (consp height) (eq (car height) 'body-lines))
+ (let* ((delta (- (* (frame-char-height frame) (cdr height))
+ (window-body-height window t))))
+ (and (window--resizable-p window delta nil 'safe nil nil nil t)
+ (window-combined-p window)
+ (window-resize window delta nil 'safe t)))
+ (setq resize-temp-buffer-window-inhibit 'vertical))
+ ((functionp height)
+ (ignore-errors (funcall height window))
+ (setq resize-temp-buffer-window-inhibit 'vertical)))
;; Adjust width of window if asked for.
(cond
- ((not width))
+ ((not width)
+ (when window-width
+ (setq resize-temp-buffer-window-inhibit 'horizontal)))
((numberp width)
(let* ((new-width
(if (integerp width)
@@ -7286,13 +7327,24 @@ Return WINDOW if BUFFER and WINDOW are live."
(delta (- new-width (window-total-width window))))
(when (and (window--resizable-p window delta t 'safe)
(window-combined-p window t))
- (window-resize window delta t 'safe))))
+ (window-resize window delta t 'safe)))
+ (setq resize-temp-buffer-window-inhibit 'horizontal))
+ ((and (consp width) (eq (car width) 'body-columns))
+ (let* ((delta (- (* (frame-char-width frame) (cdr width))
+ (window-body-width window t))))
+ (and (window--resizable-p window delta t 'safe nil nil nil t)
+ (window-combined-p window t)
+ (window-resize window delta t 'safe t)))
+ (setq resize-temp-buffer-window-inhibit 'horizontal))
((functionp width)
- (ignore-errors (funcall width window))))
+ (ignore-errors (funcall width window))
+ (setq resize-temp-buffer-window-inhibit 'horizontal)))
+
;; Preserve window size if asked for.
(when (consp preserve-size)
(window-preserve-size window t (car preserve-size))
(window-preserve-size window nil (cdr preserve-size)))))
+
;; Assign any window parameters specified.
(let ((parameters (cdr (assq 'window-parameters alist))))
(dolist (parameter parameters)
@@ -7535,6 +7587,9 @@ Action alist entries are:
window from being used for display.
`inhibit-switch-frame' -- A non-nil value prevents any frame
used for showing the buffer from being raised or selected.
+ Note that a window manager may still raise a new frame and
+ give it focus, effectively overriding the value specified
+ here.
`reusable-frames' -- The value specifies the set of frames to
search for a window that already displays the buffer.
Possible values are nil (the selected frame), t (any live
@@ -7544,20 +7599,33 @@ Action alist entries are:
frame parameters to give a new frame, if one is created.
`window-height' -- The value specifies the desired height of the
window chosen and is either an integer (the total height of
- the window), a floating point number (the fraction of its
- total height with respect to the total height of the frame's
- root window) or a function to be called with one argument -
- the chosen window. The function is supposed to adjust the
- height of the window; its return value is ignored. Suitable
- functions are `shrink-window-if-larger-than-buffer' and
- `fit-window-to-buffer'.
+ the window specified in frame lines), a floating point
+ number (the fraction of its total height with respect to the
+ total height of the frame's root window), a cons cell whose
+ car is 'body-lines' and whose cdr is an integer that
+ specifies the height of the window's body in frame lines, or
+ a function to be called with one argument - the chosen
+ window. That function is supposed to adjust the height of
+ the window. Suitable functions are `fit-window-to-buffer'
+ and `shrink-window-if-larger-than-buffer'.
`window-width' -- The value specifies the desired width of the
window chosen and is either an integer (the total width of
- the window), a floating point number (the fraction of its
- total width with respect to the width of the frame's root
- window) or a function to be called with one argument - the
- chosen window. The function is supposed to adjust the width
- of the window; its return value is ignored.
+ the window specified in frame lines), a floating point
+ number (the fraction of its total width with respect to the
+ width of the frame's root window), a cons cell whose car is
+ 'body-columns' and whose cdr is an integer that specifies the
+ width of the window's body in frame columns, or a function to
+ be called with one argument - the chosen window. That
+ function is supposed to adjust the width of the window.
+ `window-size' -- This entry is only useful for windows appearing
+ alone on their frame and specifies the desired size of that
+ window either as a cons of integers (the total width and
+ height of the window on that frame), a cons cell whose car is
+ 'body-chars' and whose cdr is a cons of integers (the desired
+ width and height of the window's body in columns and lines of
+ its frame), or a function to be called with one argument -
+ the chosen window. That function is supposed to adjust the
+ size of the frame.
`preserve-size' -- The value should be either (t . nil) to
preserve the width of the chosen window, (nil . t) to
preserve its height or (t . t) to preserve its height and
@@ -7573,9 +7641,9 @@ Action alist entries are:
to fill the window body with some contents that might depend
on dimensions of the displayed window.
-The entries `window-height', `window-width' and `preserve-size'
-are applied only when the window used for displaying the buffer
-never showed another buffer before.
+The entries `window-height', `window-width', `window-size' and
+`preserve-size' are applied only when the window used for
+displaying the buffer never showed another buffer before.
The ACTION argument can also have a non-nil and non-list value.
This means to display the buffer in a window other than the
@@ -8340,7 +8408,8 @@ indirectly called by the latter."
(throw 'best t)))))
;; When ALIST has a `previous-window' entry, that entry may override
;; anything we found so far.
- (when (and previous-window (boundp previous-window))
+ (when (and previous-window (symbolp previous-window)
+ (boundp previous-window))
(setq previous-window (symbol-value previous-window)))
(when (and (setq window previous-window)
(window-live-p window)
@@ -8505,7 +8574,7 @@ from the list of completions and default values."
(let ((rbts-completion-table (internal-complete-buffer-except)))
(minibuffer-with-setup-hook
(lambda ()
- (setq minibuffer-completion-table rbts-completion-table)
+ (setq-local minibuffer-completion-table rbts-completion-table)
;; Since rbts-completion-table is built dynamically, we
;; can't just add it to the default value of
;; icomplete-with-completion-tables, so we add it
@@ -8595,7 +8664,7 @@ the buffer in the window specified by the rules from these variables."
WARNING: This is NOT the way to work on another buffer temporarily
within a Lisp program! Use `set-buffer' instead. That avoids
-messing with the window-buffer correspondences.
+messing with the `window-buffer' correspondences.
If the selected window cannot display the specified buffer
because it is a minibuffer window or strongly dedicated to
@@ -8650,7 +8719,7 @@ Return the buffer switched to."
"Cannot switch buffers in a dedicated window"))
('prompt
(if (y-or-n-p
- (format "Window is dedicated to %s; undedicate it"
+ (format "Window is dedicated to %s; undedicate it?"
(window-buffer)))
(progn
(set-window-dedicated-p nil nil)
@@ -9746,7 +9815,7 @@ tool-bar's height to the minimum height needed); if
`recenter-redisplay' has the special value `tty', then only tty frames
are redrawn.
-Just C-u as prefix means put point in the center of the window
+Just \\[universal-argument] as prefix means put point in the center of the window
and redisplay normally--don't erase and redraw the frame."
(if (functionp recenter-window-group-function)
(funcall recenter-window-group-function arg)
@@ -9875,7 +9944,7 @@ With plain \\[universal-argument], move current line to window center."
A prefix argument is handled like `recenter':
With numeric prefix ARG, move current line to window-line ARG.
- With plain `C-u', move current line to window center."
+ With plain \\[universal-argument], move current line to window center."
(interactive "P")
(with-selected-window (other-window-for-scrolling)
(recenter-top-bottom arg)
@@ -10365,7 +10434,7 @@ displaying that processes's buffer."
(setq repeat-map 'other-window-repeat-map)
(other-window -1)))
map)
- "Keymap to repeat other-window key sequences. Used in `repeat-mode'.")
+ "Keymap to repeat `other-window' key sequences. Used in `repeat-mode'.")
(put 'other-window 'repeat-map 'other-window-repeat-map)
(defvar resize-window-repeat-map
diff --git a/lisp/winner.el b/lisp/winner.el
index 8062fbae904..1b2807f2482 100644
--- a/lisp/winner.el
+++ b/lisp/winner.el
@@ -131,8 +131,7 @@ You may want to include buffer names such as *Help*, *Apropos*,
(defsubst winner-equal (a b)
- "Check whether two Winner configurations (as produced by
-`winner-conf') are equal."
+ "Return t if two Winner configurations (as produced by `winner-conf') are equal."
(equal (cdr a) (cdr b)))
diff --git a/lisp/woman.el b/lisp/woman.el
index fe9f8969c3e..1ca4d5e8716 100644
--- a/lisp/woman.el
+++ b/lisp/woman.el
@@ -1790,7 +1790,7 @@ Argument EVENT is the invoking mouse event."
;; That comment was moved after the symbol `woman-menu' to make
;; find-function-search-for-symbol work. -- rost
woman-mode-map
- "WoMan Menu"
+ "WoMan Menu."
`("WoMan"
["WoMan..." woman t] ; [NAME CALLBACK ENABLE]
"--"
@@ -2182,7 +2182,7 @@ To be called on original buffer and any .so insertions."
;; variable. zsoelim is always run as the very first preprocessor.
(defvar woman-emulate-tbl nil
- "True if WoMan should emulate the tbl preprocessor.
+ "Non-nil if WoMan should emulate the tbl preprocessor.
This applies to text between .TE and .TS directives.
Currently set only from \\='\\\" t in the first line of the source file.")
diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el
index 23e8001c013..2819c6163d0 100644
--- a/lisp/x-dnd.el
+++ b/lisp/x-dnd.el
@@ -377,7 +377,7 @@ Currently XDND, Motif and old KDE 1.x protocols are recognized."
("XdndActionMove" . move)
("XdndActionLink" . link)
("XdndActionAsk" . ask))
- "Mapping from XDND action types to lisp symbols.")
+ "Mapping from XDND action types to Lisp symbols.")
(declare-function x-change-window-property "xfns.c"
(prop value &optional frame type format outer-P))
diff --git a/lisp/xdg.el b/lisp/xdg.el
index e5165bbd86a..60558982146 100644
--- a/lisp/xdg.el
+++ b/lisp/xdg.el
@@ -41,39 +41,108 @@
;; XDG Base Directory Specification
;; https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
-(defmacro xdg--dir-home (environ default-path)
- (declare (debug (stringp stringp)))
- (let ((env (make-symbol "env")))
- `(let ((,env (getenv ,environ)))
- (if (or (null ,env) (not (file-name-absolute-p ,env)))
- (expand-file-name ,default-path)
- ,env))))
+(defun xdg--dir-home (environ default-path)
+ (let ((env (getenv environ)))
+ (if (or (null env) (not (file-name-absolute-p env)))
+ (expand-file-name default-path)
+ env)))
(defun xdg-config-home ()
- "Return the base directory for user specific configuration files."
+ "Return the base directory for user specific configuration files.
+
+According to the XDG Base Directory Specification version
+0.8 (8th May 2021):
+
+ \"$XDG_CONFIG_HOME defines the base directory relative to
+ which user-specific configuration files should be stored.
+ If $XDG_CONFIG_HOME is either not set or empty, a default
+ equal to $HOME/.config should be used.\""
(xdg--dir-home "XDG_CONFIG_HOME" "~/.config"))
(defun xdg-cache-home ()
- "Return the base directory for user specific cache files."
+ "Return the base directory for user specific cache files.
+
+According to the XDG Base Directory Specification version
+0.8 (8th May 2021):
+
+ \"$XDG_CACHE_HOME defines the base directory relative to
+ which user-specific non-essential data files should be
+ stored. If $XDG_CACHE_HOME is either not set or empty, a
+ default equal to $HOME/.cache should be used.\""
(xdg--dir-home "XDG_CACHE_HOME" "~/.cache"))
(defun xdg-data-home ()
- "Return the base directory for user specific data files."
+ "Return the base directory for user specific data files.
+
+According to the XDG Base Directory Specification version
+0.8 (8th May 2021):
+
+ \"$XDG_DATA_HOME defines the base directory relative to which
+ user-specific data files should be stored. If $XDG_DATA_HOME is
+ either not set or empty, a default equal to $HOME/.local/share
+ should be used.\""
(xdg--dir-home "XDG_DATA_HOME" "~/.local/share"))
+(defun xdg-state-home ()
+ "Return the base directory for user-specific state data.
+
+According to the XDG Base Directory Specification version
+0.8 (8th May 2021):
+
+ \"The $XDG_STATE_HOME 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. It may contain:
+
+ * actions history (logs, history, recently used files, …)
+
+ * current state of the application that can be reused on a
+ restart (view, layout, open files, undo history, …)\""
+ (xdg--dir-home "XDG_STATE_HOME" "~/.local/state"))
+
(defun xdg-runtime-dir ()
- "Return the value of $XDG_RUNTIME_DIR."
+ "Return the value of $XDG_RUNTIME_DIR.
+
+According to the XDG Base Directory Specification version
+0.8 (8th May 2021):
+
+ \"$XDG_RUNTIME_DIR defines the base directory relative to
+ which user-specific non-essential runtime files and other
+ file objects (such as sockets, named pipes, ...) should be
+ stored.\""
(getenv "XDG_RUNTIME_DIR"))
(defun xdg-config-dirs ()
- "Return the config directory search path as a list."
+ "Return the config directory search path as a list.
+
+According to the XDG Base Directory Specification version
+0.8 (8th May 2021):
+
+ \"$XDG_CONFIG_DIRS defines the preference-ordered set of base
+ directories to search for configuration files in addition to
+ the $XDG_CONFIG_HOME base directory. The directories in
+ $XDG_CONFIG_DIRS should be separated with a colon ':'.
+
+ \"If $XDG_CONFIG_DIRS is either not set or empty, a value equal to
+ /etc/xdg should be used.\""
(let ((env (getenv "XDG_CONFIG_DIRS")))
(if (or (null env) (string= env ""))
'("/etc/xdg")
(parse-colon-path env))))
(defun xdg-data-dirs ()
- "Return the data directory search path as a list."
+ "Return the data directory search path as a list.
+
+According to the XDG Base Directory Specification version
+0.8 (8th May 2021):
+
+ \"$XDG_DATA_DIRS defines the preference-ordered set of base
+ directories to search for data files in addition to the
+ $XDG_DATA_HOME base directory. The directories in
+ $XDG_DATA_DIRS should be separated with a colon ':'.
+
+ \"If $XDG_DATA_DIRS is either not set or empty, a value equal
+ to /usr/local/share/:/usr/share/ should be used.\""
(let ((env (getenv "XDG_DATA_DIRS")))
(if (or (null env) (string= env ""))
'("/usr/local/share/" "/usr/share/")
@@ -109,7 +178,7 @@ file:///foo/bar.jpg"
"_DIR=\""
(group-n 2 (or "/" "$HOME/") (*? (or (not (any "\"")) "\\\"")))
"\""))
- "Regexp matching non-comment lines in xdg-user-dirs config files.")
+ "Regexp matching non-comment lines in `xdg-user-dirs' config files.")
(defvar xdg-user-dirs nil
"Alist of directory keys and values.")
@@ -131,7 +200,7 @@ This should be called at the beginning of a line."
(when (and k v) (cons k (xdg--substitute-home-env v))))))
(defun xdg--user-dirs-parse-file (filename)
- "Return alist of xdg-user-dirs from FILENAME."
+ "Return alist of `xdg-user-dirs' from FILENAME."
(let (elt res)
(when (file-readable-p filename)
(with-temp-buffer
diff --git a/lisp/xml.el b/lisp/xml.el
index 1b2d6557388..e2ba02e1952 100644
--- a/lisp/xml.el
+++ b/lisp/xml.el
@@ -83,7 +83,7 @@
;;; Macros to parse the list
(defconst xml-undefined-entity "?"
- "What to substitute for undefined entities")
+ "What to substitute for undefined entities.")
(defconst xml-default-ns '(("" . "")
("xml" . "http://www.w3.org/XML/1998/namespace")
@@ -612,8 +612,8 @@ references."
(if (setq ref (match-string 2))
(progn ; Numeric char reference
(setq val (save-match-data
- (decode-char 'ucs (string-to-number
- ref (if (match-string 1) 16)))))
+ (string-to-number
+ ref (if (match-string 1) 16))))
(and (null val)
xml-validating-parser
(error "XML: (Validity) Invalid character reference `%s'"
@@ -898,11 +898,11 @@ references and parameter-entity references."
ref val)
(cond ((setq ref (match-string 1 string))
;; Decimal character reference
- (setq val (decode-char 'ucs (string-to-number ref)))
+ (setq val (string-to-number ref))
(if val (push (string val) children)))
;; Hexadecimal character reference
((setq ref (match-string 2 string))
- (setq val (decode-char 'ucs (string-to-number ref 16)))
+ (setq val (string-to-number ref 16))
(if val (push (string val) children)))
;; Parameter entity reference
((setq ref (match-string 3 string))
@@ -962,7 +962,7 @@ STRING is assumed to occur in an XML attribute value."
(if ref
;; [4.6] Character references are included as
;; character data.
- (let ((val (decode-char 'ucs (string-to-number ref (if is-hex 16)))))
+ (let ((val (string-to-number ref (if is-hex 16))))
(push (cond (val (string val))
(xml-validating-parser
(error "XML: (Validity) Undefined character `x%s'" ref))
diff --git a/lisp/xt-mouse.el b/lisp/xt-mouse.el
index 72faff81015..e4e91aa8928 100644
--- a/lisp/xt-mouse.el
+++ b/lisp/xt-mouse.el
@@ -27,7 +27,7 @@
;; This is actually useful when you are running X11 locally, but is
;; working on remote machine over a modem line or through a gateway.
-;; It works by translating xterm escape codes into generic emacs mouse
+;; It works by translating xterm escape codes into generic Emacs mouse
;; events so it should work with any package that uses the mouse.
;; You don't have to turn off xterm mode to use the normal xterm mouse
@@ -376,11 +376,11 @@ given escape sequence takes precedence over the former."
"\e[?1000h\e[?1003h\e[?1005h\e[?1006h"
"Control sequence to enable xterm mouse tracking.
Enables basic mouse tracking, mouse motion events and finally
-extended tracking on terminals that support it. The following
+extended tracking on terminals that support it. The following
escape sequences are understood by modern xterms:
\"\\e[?1000h\" \"Basic mouse mode\": Enables reports for mouse
- clicks. There is a limit to the maximum row/column
+ clicks. There is a limit to the maximum row/column
position (<= 223), which can be reported in this
basic mode.
@@ -389,7 +389,7 @@ escape sequences are understood by modern xterms:
\"\\e[?1005h\" \"UTF-8 coordinate extension\": Enables an extension
to the basic mouse mode, which uses UTF-8
- characters to overcome the 223 row/column limit. This
+ characters to overcome the 223 row/column limit. This
extension may conflict with non UTF-8 applications or
non UTF-8 locales.
diff --git a/lisp/xwidget.el b/lisp/xwidget.el
index b8df55090a2..ce9839ebd34 100644
--- a/lisp/xwidget.el
+++ b/lisp/xwidget.el
@@ -33,10 +33,12 @@
(require 'cl-lib)
(require 'bookmark)
+(require 'format-spec)
(declare-function make-xwidget "xwidget.c"
- (type title width height arguments &optional buffer))
+ (type title width height arguments &optional buffer related))
(declare-function xwidget-buffer "xwidget.c" (xwidget))
+(declare-function set-xwidget-buffer "xwidget.c" (xwidget buffer))
(declare-function xwidget-size-request "xwidget.c" (xwidget))
(declare-function xwidget-resize "xwidget.c" (xwidget new-width new-height))
(declare-function xwidget-webkit-execute-script "xwidget.c"
@@ -53,31 +55,33 @@
(declare-function delete-xwidget-view "xwidget.c" (xwidget-view))
(declare-function get-buffer-xwidgets "xwidget.c" (buffer))
(declare-function xwidget-query-on-exit-flag "xwidget.c" (xwidget))
+(declare-function xwidget-webkit-back-forward-list "xwidget.c" (xwidget &optional limit))
+(declare-function xwidget-webkit-estimated-load-progress "xwidget.c" (xwidget))
+(declare-function xwidget-webkit-set-cookie-storage-file "xwidget.c" (xwidget file))
+(declare-function xwidget-live-p "xwidget.c" (xwidget))
+(declare-function xwidget-webkit-stop-loading "xwidget.c" (xwidget))
(defgroup xwidget nil
"Displaying native widgets in Emacs buffers."
:group 'widgets)
-(defun xwidget-insert (pos type title width height &optional args)
+(defun xwidget-insert (pos type title width height &optional args related)
"Insert an xwidget at position POS.
-Supply the xwidget's TYPE, TITLE, WIDTH, and HEIGHT.
+Supply the xwidget's TYPE, TITLE, WIDTH, HEIGHT, and RELATED.
See `make-xwidget' for the possible TYPE values.
The usage of optional argument ARGS depends on the xwidget.
This returns the result of `make-xwidget'."
(goto-char pos)
- (let ((id (make-xwidget type title width height args)))
+ (let ((id (make-xwidget type title width height args nil related)))
(put-text-property (point) (+ 1 (point))
'display (list 'xwidget ':xwidget id))
id))
(defun xwidget-at (pos)
"Return xwidget at POS."
- ;; TODO this function is a bit tedious because the C layer isn't well
- ;; protected yet and xwidgetp apparently doesn't work yet.
(let* ((disp (get-text-property pos 'display))
- (xw (car (cdr (cdr disp)))))
- ;;(if (xwidgetp xw) xw nil)
- (if (equal 'xwidget (car disp)) xw)))
+ (xw (car (cdr (cdr disp)))))
+ (when (xwidget-live-p xw) xw)))
@@ -88,6 +92,29 @@ This returns the result of `make-xwidget'."
(require 'seq)
(require 'url-handlers)
+(defgroup xwidget-webkit nil
+ "Displaying webkit xwidgets in Emacs buffers."
+ :version "29.1"
+ :group 'web
+ :prefix "xwidget-webkit-")
+
+(defcustom xwidget-webkit-buffer-name-format "*xwidget-webkit: %T*"
+ "Template for naming `xwidget-webkit' buffers.
+It can use the following special constructs:
+
+ %T -- the title of the Web page loaded by the xwidget.
+ %U -- the URI of the Web page loaded by the xwidget."
+ :type 'string
+ :version "29.1")
+
+(defcustom xwidget-webkit-cookie-file nil
+ "The name of the file where `xwidget-webkit-browse-url' will store cookies.
+They will be stored as plain text in Mozilla \"cookies.txt\"
+format. If nil, do not store cookies. You must kill all xwidget-webkit
+buffers for this setting to take effect after setting it to nil."
+ :type '(choice (const :tag "Do not store cookies" nil) file)
+ :version "29.1")
+
;;;###autoload
(defun xwidget-webkit-browse-url (url &optional new-session)
"Ask xwidget-webkit to browse URL.
@@ -95,9 +122,7 @@ NEW-SESSION specifies whether to create a new xwidget-webkit session.
Interactively, URL defaults to the string looking like a url around point."
(interactive (progn
(require 'browse-url)
- (browse-url-interactive-arg "xwidget-webkit URL: "
- ;;(xwidget-webkit-current-url)
- )))
+ (browse-url-interactive-arg "xwidget-webkit URL: ")))
(or (featurep 'xwidget-internal)
(user-error "Your Emacs was not compiled with xwidgets support"))
(when (stringp url)
@@ -112,7 +137,7 @@ Interactively, URL defaults to the string looking like a url around point."
"Clone current URL into a new widget place in new window below.
Get the URL of current session, then browse to the URL
in `split-window-below' with a new xwidget webkit session."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(let ((url (xwidget-webkit-current-url)))
(with-selected-window (split-window-below)
(xwidget-webkit-new-session url))))
@@ -121,11 +146,50 @@ in `split-window-below' with a new xwidget webkit session."
"Clone current URL into a new widget place in new window right.
Get the URL of current session, then browse to the URL
in `split-window-right' with a new xwidget webkit session."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(let ((url (xwidget-webkit-current-url)))
(with-selected-window (split-window-right)
(xwidget-webkit-new-session url))))
+(declare-function xwidget-perform-lispy-event "xwidget.c")
+
+(defvar xwidget-webkit--input-method-events nil
+ "Internal variable used to store input method events.")
+
+(defvar-local xwidget-webkit--loading-p nil
+ "Whether or not a page is being loaded.")
+
+(defvar-local xwidget-webkit--progress-update-timer nil
+ "Timer that updates the display of page load progress in the header line.")
+
+(defun xwidget-webkit-pass-command-event-with-input-method ()
+ "Handle a `with-input-method' event."
+ (interactive)
+ (let ((key (pop unread-command-events)))
+ (setq xwidget-webkit--input-method-events
+ (funcall input-method-function key))
+ (exit-minibuffer)))
+
+(defun xwidget-webkit-pass-command-event ()
+ "Pass `last-command-event' to the current buffer's WebKit widget.
+If `current-input-method' is non-nil, consult `input-method-function'
+for the actual events that will be sent."
+ (interactive)
+ (if (and current-input-method
+ (characterp last-command-event))
+ (let ((xwidget-webkit--input-method-events nil)
+ (minibuffer-local-map (make-keymap)))
+ (define-key minibuffer-local-map [with-input-method]
+ 'xwidget-webkit-pass-command-event-with-input-method)
+ (push last-command-event unread-command-events)
+ (push 'with-input-method unread-command-events)
+ (read-from-minibuffer "" nil nil nil nil nil t)
+ (dolist (event xwidget-webkit--input-method-events)
+ (xwidget-perform-lispy-event (xwidget-webkit-current-session)
+ event)))
+ (xwidget-perform-lispy-event (xwidget-webkit-current-session)
+ last-command-event)))
+
;;todo.
;; - check that the webkit support is compiled in
(defvar xwidget-webkit-mode-map
@@ -135,11 +199,14 @@ in `split-window-right' with a new xwidget webkit session."
(define-key map "b" 'xwidget-webkit-back)
(define-key map "f" 'xwidget-webkit-forward)
(define-key map "r" 'xwidget-webkit-reload)
- (define-key map "t" (lambda () (interactive) (message "o"))) ;FIXME: ?!?
(define-key map "\C-m" 'xwidget-webkit-insert-string)
(define-key map "w" 'xwidget-webkit-current-url)
(define-key map "+" 'xwidget-webkit-zoom-in)
(define-key map "-" 'xwidget-webkit-zoom-out)
+ (define-key map "e" 'xwidget-webkit-edit-mode)
+ (define-key map "\C-r" 'xwidget-webkit-isearch-mode)
+ (define-key map "\C-s" 'xwidget-webkit-isearch-mode)
+ (define-key map "H" 'xwidget-webkit-browse-history)
;;similar to image mode bindings
(define-key map (kbd "SPC") 'xwidget-webkit-scroll-up)
@@ -166,14 +233,78 @@ in `split-window-right' with a new xwidget webkit session."
map)
"Keymap for `xwidget-webkit-mode'.")
+(easy-menu-define nil xwidget-webkit-mode-map "Xwidget WebKit menu."
+ (list "Xwidget WebKit"
+ ["Browse URL" xwidget-webkit-browse-url
+ :active t
+ :help "Prompt for a URL, then instruct WebKit to browse it"]
+ ["Back" xwidget-webkit-back t]
+ ["Forward" xwidget-webkit-forward t]
+ ["Reload" xwidget-webkit-reload t]
+ ["History" xwidget-webkit-browse-history t]
+ ["Insert String" xwidget-webkit-insert-string
+ :active t
+ :help "Insert a string into the currently active field"]
+ ["Zoom In" xwidget-webkit-zoom-in t]
+ ["Zoom Out" xwidget-webkit-zoom-out t]
+ ["Edit Mode" xwidget-webkit-edit-mode
+ :active t
+ :style toggle
+ :selected xwidget-webkit-edit-mode
+ :help "Send self inserting characters to the WebKit widget"]
+ ["Save Selection" xwidget-webkit-copy-selection-as-kill
+ :active t
+ :help "Save the browser's selection in the kill ring"]
+ ["Incremental Search" xwidget-webkit-isearch-mode
+ :active (not xwidget-webkit-isearch-mode)
+ :help "Perform incremental search inside the WebKit widget"]
+ ["Stop Loading" xwidget-webkit-stop
+ :active xwidget-webkit--loading-p]))
+
+(defvar xwidget-webkit-tool-bar-map
+ (let ((map (make-sparse-keymap)))
+ (prog1 map
+ (tool-bar-local-item-from-menu 'xwidget-webkit-stop
+ "cancel"
+ map
+ xwidget-webkit-mode-map)
+ (tool-bar-local-item-from-menu 'xwidget-webkit-back
+ "left-arrow"
+ map
+ xwidget-webkit-mode-map)
+ (tool-bar-local-item-from-menu 'xwidget-webkit-forward
+ "right-arrow"
+ map
+ xwidget-webkit-mode-map)
+ (tool-bar-local-item-from-menu 'xwidget-webkit-reload
+ "refresh"
+ map
+ xwidget-webkit-mode-map)
+ (tool-bar-local-item-from-menu 'xwidget-webkit-zoom-in
+ "zoom-in"
+ map
+ xwidget-webkit-mode-map)
+ (tool-bar-local-item-from-menu 'xwidget-webkit-zoom-out
+ "zoom-out"
+ map
+ xwidget-webkit-mode-map)
+ (tool-bar-local-item-from-menu 'xwidget-webkit-browse-url
+ "connect-to-url"
+ map
+ xwidget-webkit-mode-map)
+ (tool-bar-local-item-from-menu 'xwidget-webkit-isearch-mode
+ "search"
+ map
+ xwidget-webkit-mode-map))))
+
(defun xwidget-webkit-zoom-in ()
"Increase webkit view zoom factor."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(xwidget-webkit-zoom (xwidget-webkit-current-session) 0.1))
(defun xwidget-webkit-zoom-out ()
"Decrease webkit view zoom factor."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(xwidget-webkit-zoom (xwidget-webkit-current-session) -0.1))
(defun xwidget-webkit-scroll-up (&optional arg)
@@ -181,7 +312,7 @@ in `split-window-right' with a new xwidget webkit session."
Stop if bottom of page is reached.
Interactively, ARG is the prefix numeric argument.
Negative ARG scrolls down."
- (interactive "P")
+ (interactive "P" xwidget-webkit-mode)
(xwidget-webkit-execute-script
(xwidget-webkit-current-session)
(format "window.scrollBy(0, %d);"
@@ -192,7 +323,7 @@ Negative ARG scrolls down."
Stop if top of page is reached.
Interactively, ARG is the prefix numeric argument.
Negative ARG scrolls up."
- (interactive "P")
+ (interactive "P" xwidget-webkit-mode)
(xwidget-webkit-execute-script
(xwidget-webkit-current-session)
(format "window.scrollBy(0, -%d);"
@@ -203,7 +334,7 @@ Negative ARG scrolls up."
The height of line is calculated with `window-font-height'.
Stop if the bottom edge of the page is reached.
If N is omitted or nil, scroll up by one line."
- (interactive "p")
+ (interactive "p" xwidget-webkit-mode)
(xwidget-webkit-scroll-up (* n (window-font-height))))
(defun xwidget-webkit-scroll-down-line (&optional n)
@@ -211,14 +342,14 @@ If N is omitted or nil, scroll up by one line."
The height of line is calculated with `window-font-height'.
Stop if the top edge of the page is reached.
If N is omitted or nil, scroll down by one line."
- (interactive "p")
+ (interactive "p" xwidget-webkit-mode)
(xwidget-webkit-scroll-down (* n (window-font-height))))
(defun xwidget-webkit-scroll-forward (&optional n)
"Scroll webkit horizontally by N chars.
The width of char is calculated with `window-font-width'.
If N is omitted or nil, scroll forwards by one char."
- (interactive "p")
+ (interactive "p" xwidget-webkit-mode)
(xwidget-webkit-execute-script
(xwidget-webkit-current-session)
(format "window.scrollBy(%d, 0);"
@@ -228,7 +359,7 @@ If N is omitted or nil, scroll forwards by one char."
"Scroll webkit back by N chars.
The width of char is calculated with `window-font-width'.
If N is omitted or nil, scroll backwards by one char."
- (interactive "p")
+ (interactive "p" xwidget-webkit-mode)
(xwidget-webkit-execute-script
(xwidget-webkit-current-session)
(format "window.scrollBy(-%d, 0);"
@@ -236,22 +367,25 @@ If N is omitted or nil, scroll backwards by one char."
(defun xwidget-webkit-scroll-top ()
"Scroll webkit to the very top."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(xwidget-webkit-execute-script
(xwidget-webkit-current-session)
"window.scrollTo(pageXOffset, 0);"))
(defun xwidget-webkit-scroll-bottom ()
"Scroll webkit to the very bottom."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(xwidget-webkit-execute-script
(xwidget-webkit-current-session)
"window.scrollTo(pageXOffset, window.document.body.scrollHeight);"))
-;; The xwidget event needs to go into a higher level handler
-;; since the xwidget can generate an event even if it's offscreen.
-;; TODO this needs to use callbacks and consider different xwidget event types.
-(define-key (current-global-map) [xwidget-event] #'xwidget-event-handler)
+;; The xwidget event needs to go in the special map. To receive
+;; xwidget events, you should place a callback in the property list of
+;; the xwidget, instead of handling these events manually.
+;;
+;; See `xwidget-webkit-new-session' for an example of how to do this.
+(define-key special-event-map [xwidget-event] #'xwidget-event-handler)
+
(defun xwidget-log (&rest msg)
"Log MSG to a buffer."
(let ((buf (get-buffer-create " *xwidget-log*")))
@@ -261,13 +395,24 @@ If N is omitted or nil, scroll backwards by one char."
(defun xwidget-event-handler ()
"Receive xwidget event."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(xwidget-log "stuff happened to xwidget %S" last-input-event)
(let*
((xwidget-event-type (nth 1 last-input-event))
(xwidget (nth 2 last-input-event))
(xwidget-callback (xwidget-get xwidget 'callback)))
- (funcall xwidget-callback xwidget xwidget-event-type)))
+ (when xwidget-callback
+ (funcall xwidget-callback xwidget xwidget-event-type))))
+
+(defun xwidget-webkit--update-progress-timer-function (xwidget)
+ "Force an update of the header line of XWIDGET's buffer."
+ (with-current-buffer (xwidget-buffer xwidget)
+ (force-mode-line-update)))
+
+(defun xwidget-webkit-buffer-kill ()
+ "Clean up an xwidget-webkit buffer before it is killed."
+ (when (timerp xwidget-webkit--progress-update-timer)
+ (cancel-timer xwidget-webkit--progress-update-timer)))
(defun xwidget-webkit-callback (xwidget xwidget-event-type)
"Callback for xwidgets.
@@ -275,42 +420,85 @@ XWIDGET instance, XWIDGET-EVENT-TYPE depends on the originating xwidget."
(if (not (buffer-live-p (xwidget-buffer xwidget)))
(xwidget-log
"error: callback called for xwidget with dead buffer")
- (with-current-buffer (xwidget-buffer xwidget)
- (cond ((eq xwidget-event-type 'load-changed)
- (let ((title (xwidget-webkit-title xwidget)))
- (xwidget-log "webkit finished loading: %s" title)
- ;; Do not adjust webkit size to window here, the selected window
- ;; can be the mini-buffer window unwantedly.
- (rename-buffer (format "*xwidget webkit: %s *" title) t)))
- ((eq xwidget-event-type 'decide-policy)
- (let ((strarg (nth 3 last-input-event)))
- (if (string-match ".*#\\(.*\\)" strarg)
- (xwidget-webkit-show-id-or-named-element
- xwidget
- (match-string 1 strarg)))))
- ;; TODO: Response handling other than download.
- ((eq xwidget-event-type 'download-callback)
- (let ((url (nth 3 last-input-event))
- (mime-type (nth 4 last-input-event))
- (file-name (nth 5 last-input-event)))
- (xwidget-webkit-save-as-file url mime-type file-name)))
- ((eq xwidget-event-type 'javascript-callback)
- (let ((proc (nth 3 last-input-event))
- (arg (nth 4 last-input-event)))
- (funcall proc arg)))
- (t (xwidget-log "unhandled event:%s" xwidget-event-type))))))
+ (cond ((eq xwidget-event-type 'load-changed)
+ (let ((title (xwidget-webkit-title xwidget))
+ (uri (xwidget-webkit-uri xwidget)))
+ (when-let ((buffer (get-buffer "*Xwidget WebKit History*")))
+ (with-current-buffer buffer
+ (revert-buffer)))
+ (with-current-buffer (xwidget-buffer xwidget)
+ (if (string-equal (nth 3 last-input-event)
+ "load-finished")
+ (progn
+ (setq xwidget-webkit--loading-p nil)
+ (cancel-timer xwidget-webkit--progress-update-timer))
+ (unless xwidget-webkit--loading-p
+ (setq xwidget-webkit--loading-p t
+ xwidget-webkit--progress-update-timer
+ (run-at-time 0.5 0.5 #'xwidget-webkit--update-progress-timer-function
+ xwidget)))))
+ ;; This funciton will be called multi times, so only
+ ;; change buffer name when the load actually completes
+ ;; this can limit buffer-name flicker in mode-line.
+ (when (or (string-equal (nth 3 last-input-event)
+ "load-finished")
+ (> (length title) 0))
+ (with-current-buffer (xwidget-buffer xwidget)
+ (force-mode-line-update)
+ (xwidget-log "webkit finished loading: %s" title)
+ ;; Do not adjust webkit size to window here, the
+ ;; selected window can be the mini-buffer window
+ ;; unwantedly.
+ (rename-buffer
+ (format-spec
+ xwidget-webkit-buffer-name-format
+ `((?T . ,title)
+ (?U . ,uri)))
+ t)))))
+ ((eq xwidget-event-type 'decide-policy)
+ (let ((strarg (nth 3 last-input-event)))
+ (if (string-match ".*#\\(.*\\)" strarg)
+ (xwidget-webkit-show-id-or-named-element
+ xwidget
+ (match-string 1 strarg)))))
+ ;; TODO: Response handling other than download.
+ ((eq xwidget-event-type 'download-callback)
+ (let ((url (nth 3 last-input-event))
+ (mime-type (nth 4 last-input-event))
+ (file-name (nth 5 last-input-event)))
+ (xwidget-webkit-save-as-file url mime-type file-name)))
+ ((eq xwidget-event-type 'javascript-callback)
+ (let ((proc (nth 3 last-input-event))
+ (arg (nth 4 last-input-event)))
+ (funcall proc arg)))
+ (t (xwidget-log "unhandled event:%s" xwidget-event-type)))))
(defvar bookmark-make-record-function)
(when (memq window-system '(mac ns))
- (defvar xwidget-webkit-enable-plugins nil
+ (defcustom xwidget-webkit-enable-plugins nil
"Enable plugins for xwidget webkit.
-If non-nil, plugins are enabled. Otherwise, disabled."))
+If non-nil, plugins are enabled. Otherwise, disabled."
+ :type 'boolean
+ :version "28.1"))
-(define-derived-mode xwidget-webkit-mode
- special-mode "xwidget-webkit" "Xwidget webkit view mode."
+(define-derived-mode xwidget-webkit-mode special-mode "xwidget-webkit"
+ "Xwidget webkit view mode."
(setq buffer-read-only t)
+ (add-hook 'kill-buffer-hook #'xwidget-webkit-buffer-kill)
+ (setq-local tool-bar-map xwidget-webkit-tool-bar-map)
(setq-local bookmark-make-record-function
#'xwidget-webkit-bookmark-make-record)
+ (setq-local header-line-format
+ (list "WebKit: "
+ '(:eval
+ (xwidget-webkit-title (xwidget-webkit-current-session)))
+ '(:eval
+ (when xwidget-webkit--loading-p
+ (let ((session (xwidget-webkit-current-session)))
+ (format " [%d%%%%]"
+ (* 100
+ (xwidget-webkit-estimated-load-progress
+ session))))))))
;; Keep track of [vh]scroll when switching buffers
(image-mode-setup-winprops))
@@ -352,7 +540,9 @@ When you set this variable to nil, consider further customization with
:type 'boolean)
(defun xwidget-webkit-bookmark-make-record ()
- "Create bookmark record in webkit xwidget."
+ "Create bookmark record in webkit xwidget.
+See `xwidget-webkit-bookmark-jump-new-session' for whether this
+should create a new session or not."
(nconc (bookmark-make-record-default t t)
`((page . ,(xwidget-webkit-uri (xwidget-webkit-current-session)))
(handler . (lambda (bmk)
@@ -384,6 +574,10 @@ The latter might be nil."
(let ((size (xwidget-size-request xw)))
(xwidget-resize xw (car size) (cadr size))))
+(defun xwidget-webkit-stop ()
+ "Stop trying to load the current page."
+ (interactive)
+ (xwidget-webkit-stop-loading (xwidget-webkit-current-session)))
(defvar xwidget-webkit-activeelement-js"
function findactiveelement(doc){
@@ -420,7 +614,7 @@ function findactiveelement(doc){
(defun xwidget-webkit-insert-string ()
"Insert string into the active field in the current webkit widget."
;; Read out the string in the field first and provide for edit.
- (interactive)
+ (interactive nil xwidget-webkit-mode)
;; As the prompt differs on JavaScript execution results,
;; the function must handle the prompt itself.
(let ((xww (xwidget-webkit-current-session)))
@@ -456,7 +650,7 @@ XW is the xwidget identifier, TEXT is retrieved from the webkit."
(defun xwidget-webkit-end-edit-textarea ()
"End editing of a webkit text area."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(goto-char (point-min))
(while (search-forward "\n" nil t)
(replace-match "\\n" nil t))
@@ -472,7 +666,8 @@ XW is the xwidget identifier, TEXT is retrieved from the webkit."
The ELEMENT-SELECTOR must be a valid CSS selector. For example,
use this to display an anchor."
(interactive (list (xwidget-webkit-current-session)
- (read-string "Element selector: ")))
+ (read-string "Element selector: "))
+ xwidget-webkit-mode)
(xwidget-webkit-execute-script
xw
(format "
@@ -488,7 +683,8 @@ use this to display an anchor."
"Make webkit xwidget XW show a named element ELEMENT-NAME.
For example, use this to display an anchor."
(interactive (list (xwidget-webkit-current-session)
- (read-string "Element name: ")))
+ (read-string "Element name: "))
+ xwidget-webkit-mode)
;; TODO: This needs to be interfaced into browse-url somehow. The
;; tricky part is that we need to do this in two steps: A: load the
;; base url, wait for load signal to arrive B: navigate to the
@@ -508,7 +704,8 @@ For example, use this to display an anchor."
"Make webkit xwidget XW show an id-element ELEMENT-ID.
For example, use this to display an anchor."
(interactive (list (xwidget-webkit-current-session)
- (read-string "Element id: ")))
+ (read-string "Element id: "))
+ xwidget-webkit-mode)
(xwidget-webkit-execute-script
xw
(format "
@@ -524,7 +721,8 @@ For example, use this to display an anchor."
"Make webkit xwidget XW show a name or element id ELEMENT-ID.
For example, use this to display an anchor."
(interactive (list (xwidget-webkit-current-session)
- (read-string "Name or element id: ")))
+ (read-string "Name or element id: "))
+ xwidget-webkit-mode)
(xwidget-webkit-execute-script
xw
(format "
@@ -539,12 +737,12 @@ For example, use this to display an anchor."
(defun xwidget-webkit-adjust-size-to-content ()
"Adjust webkit to content size."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(xwidget-adjust-size-to-content (xwidget-webkit-current-session)))
(defun xwidget-webkit-adjust-size-dispatch ()
"Adjust size according to mode."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(xwidget-webkit-adjust-size-to-window (xwidget-webkit-current-session))
;; The recenter is intended to correct a visual glitch.
;; It errors out if the buffer isn't visible, but then we don't get
@@ -573,12 +771,12 @@ For example, use this to display an anchor."
(defun xwidget-webkit-adjust-size (w h)
"Manually set webkit size to width W, height H."
;; TODO shouldn't be tied to the webkit xwidget
- (interactive "nWidth:\nnHeight:\n")
+ (interactive "nWidth:\nnHeight:\n" xwidget-webkit-mode)
(xwidget-resize (xwidget-webkit-current-session) w h))
(defun xwidget-webkit-fit-width ()
"Adjust width of webkit to window width."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(xwidget-webkit-adjust-size (- (nth 2 (window-inside-pixel-edges))
(car (window-inside-pixel-edges)))
1000))
@@ -600,10 +798,15 @@ For example, use this to display an anchor."
(defun xwidget-webkit-new-session (url &optional callback)
"Create a new webkit session buffer with URL."
- (let*
- ((bufname (generate-new-buffer-name "*xwidget-webkit*"))
- (callback (or callback #'xwidget-webkit-callback))
- xw)
+ (let* ((bufname
+ ;; Generate a temp-name based on current buffer name. it
+ ;; will be renamed by `xwidget-webkit-callback' in the
+ ;; future. This approach can limit flicker of buffer-name in
+ ;; mode-line.
+ (generate-new-buffer-name (buffer-name)))
+ (callback (or callback #'xwidget-webkit-callback))
+ (current-session (xwidget-webkit-current-session))
+ xw)
(setq xwidget-webkit-last-session-buffer (switch-to-buffer
(get-buffer-create bufname)))
;; The xwidget id is stored in a text property, so we need to have
@@ -615,40 +818,94 @@ For example, use this to display an anchor."
(setq xw (xwidget-insert
start 'webkit bufname
(xwidget-window-inside-pixel-width (selected-window))
- (xwidget-window-inside-pixel-height (selected-window)))))
+ (xwidget-window-inside-pixel-height (selected-window))
+ nil current-session)))
+ (when xwidget-webkit-cookie-file
+ (xwidget-webkit-set-cookie-storage-file
+ xw (expand-file-name xwidget-webkit-cookie-file)))
(xwidget-put xw 'callback callback)
+ (xwidget-put xw 'display-callback #'xwidget-webkit-display-callback)
(xwidget-webkit-mode)
(xwidget-webkit-goto-uri (xwidget-webkit-last-session) url)))
+(defun xwidget-webkit-import-widget (xwidget)
+ "Create a new webkit session buffer from XWIDGET, an existing xwidget.
+Return the buffer."
+ (let* ((bufname
+ ;; Generate a temp-name based on current buffer name. it
+ ;; will be renamed by `xwidget-webkit-callback' in the
+ ;; future. This approach can limit flicker of buffer-name in
+ ;; mode-line.
+ (generate-new-buffer-name (buffer-name)))
+ (callback #'xwidget-webkit-callback)
+ (buffer (get-buffer-create bufname)))
+ (with-current-buffer buffer
+ (setq xwidget-webkit-last-session-buffer buffer)
+ (save-excursion
+ (erase-buffer)
+ (insert ".")
+ (put-text-property (point-min) (point-max)
+ 'display (list 'xwidget :xwidget xwidget)))
+ (xwidget-put xwidget 'callback callback)
+ (xwidget-put xwidget 'display-callback
+ #'xwidget-webkit-display-callback)
+ (set-xwidget-buffer xwidget buffer)
+ (xwidget-webkit-mode))
+ buffer))
+
+(defun xwidget-webkit-display-event (event)
+ "Trigger display callback for EVENT."
+ (interactive "e")
+ (let ((xwidget (cadr event))
+ (source (caddr event)))
+ (when (xwidget-get source 'display-callback)
+ (funcall (xwidget-get source 'display-callback)
+ xwidget source))))
+
+(defun xwidget-webkit-display-callback (xwidget _source)
+ "Import XWIDGET and display it."
+ (display-buffer (xwidget-webkit-import-widget xwidget)))
+
+(define-key special-event-map [xwidget-display-event] 'xwidget-webkit-display-event)
(defun xwidget-webkit-goto-url (url)
"Goto URL with xwidget webkit."
(if (xwidget-webkit-current-session)
(progn
- (xwidget-webkit-goto-uri (xwidget-webkit-current-session) url))
+ (xwidget-webkit-goto-uri (xwidget-webkit-current-session) url)
+ (switch-to-buffer (xwidget-buffer (xwidget-webkit-current-session))))
(xwidget-webkit-new-session url)))
(defun xwidget-webkit-back ()
"Go back to previous URL in xwidget webkit buffer."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(xwidget-webkit-goto-history (xwidget-webkit-current-session) -1))
(defun xwidget-webkit-forward ()
"Go forward in history."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(xwidget-webkit-goto-history (xwidget-webkit-current-session) 1))
(defun xwidget-webkit-reload ()
"Reload current URL."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(xwidget-webkit-goto-history (xwidget-webkit-current-session) 0))
(defun xwidget-webkit-current-url ()
"Display the current xwidget webkit URL and place it on the `kill-ring'."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(let ((url (xwidget-webkit-uri (xwidget-webkit-current-session))))
(message "URL: %s" (kill-new (or url "")))))
+(defun xwidget-webkit-browse-history ()
+ "Display a buffer containing the history of page loads."
+ (interactive)
+ (setq xwidget-webkit-last-session-buffer (current-buffer))
+ (let ((buffer (get-buffer-create "*Xwidget WebKit History*")))
+ (with-current-buffer buffer
+ (xwidget-webkit-history-mode))
+ (display-buffer buffer)))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun xwidget-webkit-get-selection (proc)
"Get the webkit selection and pass it to PROC."
@@ -659,7 +916,7 @@ For example, use this to display an anchor."
(defun xwidget-webkit-copy-selection-as-kill ()
"Get the webkit selection and put it on the `kill-ring'."
- (interactive)
+ (interactive nil xwidget-webkit-mode)
(xwidget-webkit-get-selection #'kill-new))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -678,7 +935,275 @@ You can retrieve the value with `xwidget-get'."
(set-xwidget-plist xwidget
(plist-put (xwidget-plist xwidget) propname value)))
+(defvar xwidget-webkit-edit-mode-map (make-keymap))
+
+(define-key xwidget-webkit-edit-mode-map [backspace] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [tab] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [left] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [right] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [up] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [down] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [return] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [C-left] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [C-right] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [C-up] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [C-down] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [C-return] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [S-left] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [S-right] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [S-up] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [S-down] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [S-return] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [M-left] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [M-right] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [M-up] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [M-down] 'xwidget-webkit-pass-command-event)
+(define-key xwidget-webkit-edit-mode-map [M-return] 'xwidget-webkit-pass-command-event)
+
+(define-minor-mode xwidget-webkit-edit-mode
+ "Minor mode for editing the content of WebKit buffers.
+
+This defines most self-inserting characters and some common
+keyboard shortcuts to `xwidget-webkit-pass-command-event', which
+will pass the key events corresponding to these characters to the
+WebKit widget."
+ :keymap xwidget-webkit-edit-mode-map)
+
+(substitute-key-definition 'self-insert-command
+ 'xwidget-webkit-pass-command-event
+ xwidget-webkit-edit-mode-map
+ global-map)
+
+(declare-function xwidget-webkit-search "xwidget.c")
+(declare-function xwidget-webkit-next-result "xwidget.c")
+(declare-function xwidget-webkit-previous-result "xwidget.c")
+(declare-function xwidget-webkit-finish-search "xwidget.c")
+
+(defvar-local xwidget-webkit-isearch--string ""
+ "The current search query.")
+(defvar-local xwidget-webkit-isearch--is-reverse nil
+ "Whether or not the current isearch should be reverse.")
+(defvar xwidget-webkit-isearch--read-string-buffer nil
+ "The buffer we are reading input method text for, if any.")
+
+(defun xwidget-webkit-isearch--update (&optional only-message)
+ "Update the current buffer's WebKit widget's search query.
+If ONLY-MESSAGE is non-nil, the query will not be sent to the
+WebKit widget. The query will be set to the contents of
+`xwidget-webkit-isearch--string'."
+ (unless only-message
+ (xwidget-webkit-search xwidget-webkit-isearch--string
+ (xwidget-webkit-current-session)
+ t xwidget-webkit-isearch--is-reverse t))
+ (let ((message-log-max nil))
+ (message "%s" (concat (propertize "Search contents: " 'face 'minibuffer-prompt)
+ xwidget-webkit-isearch--string))))
+
+(defun xwidget-webkit-isearch-erasing-char (count)
+ "Erase the last COUNT characters of the current query."
+ (interactive (list (prefix-numeric-value current-prefix-arg)))
+ (when (> (length xwidget-webkit-isearch--string) 0)
+ (setq xwidget-webkit-isearch--string
+ (substring xwidget-webkit-isearch--string 0
+ (- (length xwidget-webkit-isearch--string) count))))
+ (xwidget-webkit-isearch--update))
+
+(defun xwidget-webkit-isearch-with-input-method ()
+ "Handle a request to use the input method to modify the search query."
+ (interactive)
+ (let ((key (car unread-command-events))
+ events)
+ (setq unread-command-events (cdr unread-command-events)
+ events (funcall input-method-function key))
+ (dolist (k events)
+ (with-current-buffer xwidget-webkit-isearch--read-string-buffer
+ (setq xwidget-webkit-isearch--string
+ (concat xwidget-webkit-isearch--string
+ (char-to-string k)))))
+ (exit-minibuffer)))
+
+(defun xwidget-webkit-isearch-printing-char-with-input-method (char)
+ "Handle printing char CHAR with the current input method."
+ (let ((minibuffer-local-map (make-keymap))
+ (xwidget-webkit-isearch--read-string-buffer (current-buffer)))
+ (define-key minibuffer-local-map [with-input-method]
+ 'xwidget-webkit-isearch-with-input-method)
+ (setq unread-command-events
+ (cons 'with-input-method
+ (cons char unread-command-events)))
+ (read-string "Search contents: "
+ xwidget-webkit-isearch--string
+ 'junk-hist nil t)
+ (xwidget-webkit-isearch--update)))
+
+(defun xwidget-webkit-isearch-printing-char (char &optional count)
+ "Add ordinary character CHAR to the search string and search.
+With argument, add COUNT copies of CHAR."
+ (interactive (list last-command-event
+ (prefix-numeric-value current-prefix-arg)))
+ (if current-input-method
+ (xwidget-webkit-isearch-printing-char-with-input-method char)
+ (setq xwidget-webkit-isearch--string (concat xwidget-webkit-isearch--string
+ (make-string (or count 1) char))))
+ (xwidget-webkit-isearch--update))
+
+(defun xwidget-webkit-isearch-forward (count)
+ "Move to the next search result COUNT times."
+ (interactive (list (prefix-numeric-value current-prefix-arg)))
+ (let ((was-reverse xwidget-webkit-isearch--is-reverse))
+ (setq xwidget-webkit-isearch--is-reverse nil)
+ (when was-reverse
+ (xwidget-webkit-isearch--update)
+ (setq count (1- count))))
+ (let ((i 0))
+ (while (< i count)
+ (xwidget-webkit-next-result (xwidget-webkit-current-session))
+ (cl-incf i)))
+ (xwidget-webkit-isearch--update t))
+
+(defun xwidget-webkit-isearch-backward (count)
+ "Move to the previous search result COUNT times."
+ (interactive (list (prefix-numeric-value current-prefix-arg)))
+ (let ((was-reverse xwidget-webkit-isearch--is-reverse))
+ (setq xwidget-webkit-isearch--is-reverse t)
+ (unless was-reverse
+ (xwidget-webkit-isearch--update)
+ (setq count (1- count))))
+ (let ((i 0))
+ (while (< i count)
+ (xwidget-webkit-previous-result (xwidget-webkit-current-session))
+ (cl-incf i)))
+ (xwidget-webkit-isearch--update t))
+
+(defun xwidget-webkit-isearch-exit ()
+ "Exit incremental search of a WebKit buffer."
+ (interactive)
+ (xwidget-webkit-isearch-mode 0))
+
+(defvar xwidget-webkit-isearch-mode-map (make-keymap)
+ "The keymap used inside xwidget-webkit-isearch-mode.")
+
+(set-char-table-range (nth 1 xwidget-webkit-isearch-mode-map)
+ (cons 0 (max-char))
+ 'xwidget-webkit-isearch-exit)
+
+(substitute-key-definition 'self-insert-command
+ 'xwidget-webkit-isearch-printing-char
+ xwidget-webkit-isearch-mode-map
+ global-map)
+
+(define-key xwidget-webkit-isearch-mode-map (kbd "DEL")
+ 'xwidget-webkit-isearch-erasing-char)
+(define-key xwidget-webkit-isearch-mode-map [backspace] 'xwidget-webkit-isearch-erasing-char)
+(define-key xwidget-webkit-isearch-mode-map [return] 'xwidget-webkit-isearch-exit)
+(define-key xwidget-webkit-isearch-mode-map "\r" 'xwidget-webkit-isearch-exit)
+(define-key xwidget-webkit-isearch-mode-map "\C-g" 'xwidget-webkit-isearch-exit)
+(define-key xwidget-webkit-isearch-mode-map "\C-r" 'xwidget-webkit-isearch-backward)
+(define-key xwidget-webkit-isearch-mode-map "\C-s" 'xwidget-webkit-isearch-forward)
+(define-key xwidget-webkit-isearch-mode-map "\C-y" 'xwidget-webkit-isearch-yank-kill)
+(define-key xwidget-webkit-isearch-mode-map "\C-\\" 'toggle-input-method)
+(define-key xwidget-webkit-isearch-mode-map "\t" 'xwidget-webkit-isearch-printing-char)
+
+(let ((meta-map (make-keymap)))
+ (set-char-table-range (nth 1 meta-map)
+ (cons 0 (max-char))
+ 'xwidget-webkit-isearch-exit)
+ (define-key xwidget-webkit-isearch-mode-map (char-to-string meta-prefix-char) meta-map))
+
+(define-minor-mode xwidget-webkit-isearch-mode
+ "Minor mode for performing incremental search inside WebKit buffers.
+
+This resembles the regular incremental search, but it does not
+support recursive edits.
+
+If this mode is activated with `\\<xwidget-webkit-isearch-mode-map>\\[xwidget-webkit-isearch-backward]', then the search will by default
+start in the reverse direction.
+
+To navigate around the search results, type
+\\<xwidget-webkit-isearch-mode-map>\\[xwidget-webkit-isearch-forward] to move forward, and
+\\<xwidget-webkit-isearch-mode-map>\\[xwidget-webkit-isearch-backward] to move backward.
+
+To insert the string at the front of the kill ring into the
+search query, type \\<xwidget-webkit-isearch-mode-map>\\[xwidget-webkit-isearch-yank-kill].
+
+Press \\<xwidget-webkit-isearch-mode-map>\\[xwidget-webkit-isearch-exit] to exit incremental search."
+ :keymap xwidget-webkit-isearch-mode-map
+ (if xwidget-webkit-isearch-mode
+ (progn
+ (setq xwidget-webkit-isearch--string "")
+ (setq xwidget-webkit-isearch--is-reverse (eq last-command-event ?\C-r))
+ (xwidget-webkit-isearch--update))
+ (xwidget-webkit-finish-search (xwidget-webkit-current-session))))
+(defun xwidget-webkit-isearch-yank-kill ()
+ "Append the most recent kill from `kill-ring' to the current query."
+ (interactive)
+ (unless xwidget-webkit-isearch-mode
+ (xwidget-webkit-isearch-mode t))
+ (setq xwidget-webkit-isearch--string
+ (concat xwidget-webkit-isearch--string
+ (current-kill 0)))
+ (xwidget-webkit-isearch--update))
+
+(defvar-local xwidget-webkit-history--session nil
+ "The xwidget this history buffer controls.")
+
+(define-button-type 'xwidget-webkit-history 'action #'xwidget-webkit-history-select-item)
+
+(defun xwidget-webkit-history--insert-item (item)
+ "Insert specified ITEM into the current buffer."
+ (let ((idx (car item))
+ (title (cadr item))
+ (uri (caddr item)))
+ (push (list idx (vector (list (number-to-string idx)
+ :type 'xwidget-webkit-history)
+ (list title :type 'xwidget-webkit-history)
+ (list uri :type 'xwidget-webkit-history)))
+ tabulated-list-entries)))
+
+(defun xwidget-webkit-history-select-item (pos)
+ "Navigate to the history item underneath POS."
+ (interactive "P")
+ (let ((id (tabulated-list-get-id pos)))
+ (xwidget-webkit-goto-history xwidget-webkit-history--session id))
+ (xwidget-webkit-history-reload))
+
+(defun xwidget-webkit-history-reload (&rest ignored)
+ "Reload the current history buffer."
+ (interactive)
+ (setq tabulated-list-entries nil)
+ (let* ((back-forward-list
+ (xwidget-webkit-back-forward-list xwidget-webkit-history--session))
+ (back-list (car back-forward-list))
+ (here (cadr back-forward-list))
+ (forward-list (caddr back-forward-list)))
+ (mapc #'xwidget-webkit-history--insert-item (nreverse forward-list))
+ (xwidget-webkit-history--insert-item here)
+ (mapc #'xwidget-webkit-history--insert-item back-list)
+ (tabulated-list-print t nil)
+ (goto-char (point-min))
+ (let ((position (line-beginning-position (1+ (length back-list)))))
+ (goto-char position)
+ (setq-local overlay-arrow-position (make-marker))
+ (set-marker overlay-arrow-position position))))
+
+(define-derived-mode xwidget-webkit-history-mode tabulated-list-mode
+ "Xwidget Webkit History"
+ "Major mode for browsing the history of an Xwidget Webkit buffer.
+Each line describes an entry in history."
+ (setq truncate-lines t)
+ (setq buffer-read-only t)
+ (setq tabulated-list-format [("Index" 10 nil)
+ ("Title" 50 nil)
+ ("URL" 100 nil)])
+ (setq tabulated-list-entries nil)
+ (setq xwidget-webkit-history--session (xwidget-webkit-current-session))
+ (xwidget-webkit-history-reload)
+ (setq-local revert-buffer-function #'xwidget-webkit-history-reload)
+ (tabulated-list-init-header))
+
+(define-key xwidget-webkit-history-mode-map (kbd "RET")
+ #'xwidget-webkit-history-select-item)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar xwidget-view-list) ; xwidget.c
diff --git a/lisp/yank-media.el b/lisp/yank-media.el
new file mode 100644
index 00000000000..decab3b3625
--- /dev/null
+++ b/lisp/yank-media.el
@@ -0,0 +1,194 @@
+;;; yank-media.el --- Yanking images and HTML -*- lexical-binding:t -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Lars Ingebrigtsen <larsi@gnus.org>
+;; Keywords: utility
+
+;; 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 'cl-lib)
+(require 'seq)
+
+(defvar yank-media--registered-handlers nil)
+
+;;;###autoload
+(defun yank-media ()
+ "Yank media (images, HTML and the like) from the clipboard.
+This command depends on the current major mode having support for
+accepting the media type. The mode has to register itself using
+the `yank-media-handler' mechanism.
+
+Also see `yank-media-types' for a command that lets you explore
+all the different selection types."
+ (interactive)
+ (unless yank-media--registered-handlers
+ (user-error "The `%s' mode hasn't registered any handlers" major-mode))
+ (let ((all-types nil))
+ (pcase-dolist (`(,handled-type . ,handler)
+ yank-media--registered-handlers)
+ (dolist (type (yank-media--find-matching-media handled-type))
+ (push (cons type handler) all-types)))
+ (unless all-types
+ (user-error
+ "No handler in the current buffer for anything on the clipboard"))
+ ;; We have a handler in the current buffer; if there's just
+ ;; matching type, just call the handler.
+ (if (length= all-types 1)
+ (funcall (cdar all-types) (caar all-types)
+ (yank-media--get-selection (caar all-types)))
+ ;; More than one type the user for what type to insert.
+ (let ((type
+ (intern
+ (completing-read "Several types available, choose one: "
+ (mapcar #'car all-types) nil t))))
+ (funcall (alist-get type all-types)
+ type (yank-media--get-selection type))))))
+
+(defun yank-media--find-matching-media (handled-type)
+ (seq-filter
+ (lambda (type)
+ (pcase-let ((`(,major ,minor) (split-string (symbol-name type) "/")))
+ (if (and (equal major "image")
+ (not (image-type-available-p (intern minor))))
+ ;; Just filter out all the image types that Emacs doesn't
+ ;; support, because the clipboard is full of things like
+ ;; `image/x-win-bitmap'.
+ nil
+ ;; Check that the handler wants this type.
+ (and (if (symbolp handled-type)
+ (eq handled-type type)
+ (string-match-p handled-type (symbol-name type)))
+ ;; An element may be in TARGETS but be empty.
+ (yank-media--get-selection type)))))
+ (gui-get-selection 'CLIPBOARD 'TARGETS)))
+
+(defun yank-media--get-selection (data-type)
+ (when-let ((data (gui-backend-get-selection 'CLIPBOARD data-type)))
+ (if (string-match-p "\\`text/" (symbol-name data-type))
+ (yank-media-types--format data-type data)
+ data)))
+
+;;;###autoload
+(defun yank-media-handler (types handler)
+ "Register HANDLER for dealing with `yank-media' actions for TYPES.
+TYPES should be a MIME media type symbol, a regexp, or a list
+that can contain both symbols and regexps.
+
+HANDLER is a function that will be called with two arguments: The
+MIME type (a symbol on the form `image/png') and the selection
+data (a string)."
+ (make-local-variable 'yank-media--registered-handlers)
+ (dolist (type (ensure-list types))
+ (setf (alist-get type yank-media--registered-handlers nil nil #'equal)
+ handler)))
+
+(defun yank-media-types (&optional all)
+ "Yank any element present in the primary selection or the clipboard.
+This is primarily meant as a debugging tool -- many of the
+elements (like images) will be inserted as raw data into the
+current buffer. See `yank-media' instead for a command that
+inserts images as images.
+
+By default, data types that aren't supported by
+`gui-get-selection' (i.e., that returns nothing if you actually
+try to look at the selection) are not included by this command.
+If ALL (interactively, the prefix), also include these
+non-supported selection data types."
+ (interactive "P")
+ (let ((elements nil))
+ ;; First gather all the data.
+ (dolist (type '(PRIMARY CLIPBOARD))
+ (when-let ((data-types (gui-get-selection type 'TARGETS)))
+ (when (vectorp data-types)
+ (seq-do (lambda (data-type)
+ (unless (memq data-type '( TARGETS MULTIPLE
+ DELETE SAVE_TARGETS))
+ (let ((data (gui-get-selection type data-type)))
+ (when (or data all)
+ ;; Remove duplicates -- the data in PRIMARY and
+ ;; CLIPBOARD are sometimes (mostly) identical,
+ ;; and sometimes not.
+ (let ((old (assq data-type elements)))
+ (when (or (not old)
+ (not (equal (nth 2 old) data)))
+ (push (list data-type type data)
+ elements)))))))
+ data-types))))
+ ;; Then query the user.
+ (unless elements
+ (user-error "No elements in the primary selection or the clipboard"))
+ (let ((spec
+ (completing-read
+ "Yank type: "
+ (mapcar (lambda (e)
+ (format "%s:%s" (downcase (symbol-name (cadr e)))
+ (car e)))
+ elements)
+ nil t)))
+ (dolist (elem elements)
+ (when (equal (format "%s:%s" (downcase (symbol-name (cadr elem)))
+ (car elem))
+ spec)
+ (insert (yank-media-types--format (car elem) (nth 2 elem))))))))
+
+(defun yank-media-types--format (data-type data)
+ (cond
+ ((not (stringp data))
+ (format "%s" data))
+ ((string-match-p "\\`text/" (symbol-name data-type))
+ ;; We may have utf-16, which Emacs won't detect automatically.
+ (let ((coding-system
+ (and (zerop (mod (length data) 2))
+ (let ((stats (vector 0 0)))
+ (dotimes (i (length data))
+ (when (zerop (elt data i))
+ (setf (aref stats (mod i 2))
+ (1+ (aref stats (mod i 2))))))
+ ;; If we have more than 90% every-other nul, then it's
+ ;; pretty likely to be utf-16.
+ (cond
+ ((> (if (zerop (elt stats 1))
+ 1
+ (/ (float (elt stats 0))
+ (float (elt stats 1))))
+ 0.9)
+ ;; Big endian.
+ 'utf-16-be)
+ ((> (if (zerop (elt stats 0))
+ 1
+ (/ (float (elt stats 1))
+ (float (elt stats 0))))
+ 0.9)
+ ;; Little endian.
+ 'utf-16-le))))))
+ (if coding-system
+ (decode-coding-string data coding-system)
+ ;; Some programs add a nul character at the end of text/*
+ ;; selections. Remove that.
+ (if (zerop (elt data (1- (length data))))
+ (substring data 0 (1- (length data)))
+ data))))
+ (t
+ data)))
+
+(provide 'yank-media)
+
+;;; yank-media.el ends here
diff --git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c
index cc73d9aa498..a0a10d13db5 100644
--- a/lwlib/xlwmenu.c
+++ b/lwlib/xlwmenu.c
@@ -157,6 +157,9 @@ xlwMenuResources[] =
offset(menu.cursor_shape), XtRString, (XtPointer)"right_ptr"},
{XtNhorizontal, XtCHorizontal, XtRInt, sizeof(int),
offset(menu.horizontal), XtRImmediate, (XtPointer)True},
+ {XtNborderThickness, XtCBorderThickness, XtRDimension,
+ sizeof (Dimension), offset (menu.border_thickness),
+ XtRImmediate, (XtPointer)1}
};
#undef offset
@@ -635,9 +638,24 @@ draw_shadow_rectangle (XlwMenuWidget mw,
Display *dpy = XtDisplay (mw);
GC top_gc = !erase_p ? mw->menu.shadow_top_gc : mw->menu.background_gc;
GC bottom_gc = !erase_p ? mw->menu.shadow_bottom_gc : mw->menu.background_gc;
- int thickness = mw->menu.shadow_thickness;
+ int thickness = !x && !y ? mw->menu.border_thickness : mw->menu.shadow_thickness;
XPoint points [4];
+ if (!erase_p && width == height && width == toggle_button_width (mw))
+ {
+ points [0].x = x;
+ points [0].y = y;
+ points [1].x = x + width;
+ points [1].y = y;
+ points [2].x = x + width;
+ points [2].y = y + height;
+ points [3].x = x;
+ points [3].y = y + height;
+ XFillPolygon (dpy, window,
+ down_p ? mw->menu.button_gc : mw->menu.inactive_button_gc,
+ points, 4, Convex, CoordModeOrigin);
+ }
+
if (!erase_p && down_p)
{
GC temp;
@@ -701,6 +719,21 @@ draw_shadow_rhombus (XlwMenuWidget mw,
int thickness = mw->menu.shadow_thickness;
XPoint points [4];
+ if (!erase_p && width == height && width == radio_button_width (mw))
+ {
+ points [0].x = x;
+ points [0].y = y + width / 2;
+ points [1].x = x + height / 2;
+ points [1].y = y + width;
+ points [2].x = x + height;
+ points [2].y = y + width / 2;
+ points [3].x = x + height / 2;
+ points [3].y = y;
+ XFillPolygon (dpy, window,
+ down_p ? mw->menu.button_gc : mw->menu.inactive_button_gc,
+ points, 4, Convex, CoordModeOrigin);
+ }
+
if (!erase_p && down_p)
{
GC temp;
@@ -1624,7 +1657,6 @@ make_drawing_gcs (XlwMenuWidget mw)
#define BRIGHTNESS(color) (((color) & 0xff) + (((color) >> 8) & 0xff) + (((color) >> 16) & 0xff))
/* Allocate color for disabled menu-items. */
- mw->menu.disabled_foreground = mw->menu.foreground;
if (BRIGHTNESS(mw->menu.foreground) < BRIGHTNESS(mw->core.background_pixel))
scale = 2.3;
else
diff --git a/lwlib/xlwmenu.h b/lwlib/xlwmenu.h
index 9143edba9a2..89e548bc8da 100644
--- a/lwlib/xlwmenu.h
+++ b/lwlib/xlwmenu.h
@@ -56,6 +56,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#define XtCResizeToPreferred "ResizeToPreferred"
#define XtNallowResize "allowResize"
#define XtCAllowResize "AllowResize"
+#define XtNborderThickness "borderThickness"
+#define XtCBorderThickness "BorderThickness"
/* Motif-compatible resource names */
#define XmNshadowThickness "shadowThickness"
diff --git a/lwlib/xlwmenuP.h b/lwlib/xlwmenuP.h
index fc77ec4bfd1..bb37b0dee2f 100644
--- a/lwlib/xlwmenuP.h
+++ b/lwlib/xlwmenuP.h
@@ -75,6 +75,7 @@ typedef struct _XlwMenu_part
Dimension vertical_spacing;
Dimension arrow_spacing;
Dimension shadow_thickness;
+ Dimension border_thickness;
Pixel top_shadow_color;
Pixel bottom_shadow_color;
Pixmap top_shadow_pixmap;
diff --git a/m4/close-stream.m4 b/m4/close-stream.m4
deleted file mode 100644
index feeb4eae5d3..00000000000
--- a/m4/close-stream.m4
+++ /dev/null
@@ -1,11 +0,0 @@
-#serial 4
-dnl Copyright (C) 2006-2007, 2009-2021 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 Prerequisites of lib/close-stream.c.
-AC_DEFUN([gl_CLOSE_STREAM],
-[
- :
-])
diff --git a/m4/dirent_h.m4 b/m4/dirent_h.m4
index 6d861425855..17e2a20c5d4 100644
--- a/m4/dirent_h.m4
+++ b/m4/dirent_h.m4
@@ -1,4 +1,4 @@
-# dirent_h.m4 serial 16
+# dirent_h.m4 serial 19
dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -6,10 +6,10 @@ dnl with or without modifications, as long as this notice is preserved.
dnl Written by Bruno Haible.
-AC_DEFUN([gl_DIRENT_H],
+AC_DEFUN_ONCE([gl_DIRENT_H],
[
- dnl Use AC_REQUIRE here, so that the default behavior below is expanded
- dnl once only, before all statements that occur in other macros.
+ dnl Ensure to expand the default settings once only, before all statements
+ dnl that occur in other macros.
AC_REQUIRE([gl_DIRENT_H_DEFAULTS])
dnl <dirent.h> is always overridden, because of GNULIB_POSIXCHECK.
@@ -27,26 +27,41 @@ AC_DEFUN([gl_DIRENT_H],
]], [alphasort closedir dirfd fdopendir opendir readdir rewinddir scandir])
])
+# gl_DIRENT_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_DIRENT_MODULE_INDICATOR],
[
- dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
- AC_REQUIRE([gl_DIRENT_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only.
+ gl_DIRENT_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_DIRENT_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_DIRENT_H_MODULE_INDICATOR_DEFAULTS], [
+ gl_UNISTD_H_REQUIRE_DEFAULTS dnl for REPLACE_FCHDIR
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OPENDIR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_READDIR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REWINDDIR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CLOSEDIR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DIRFD])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FDOPENDIR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SCANDIR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ALPHASORT])
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_DIRENT_H_MODULE_INDICATOR_DEFAULTS])
+ AC_REQUIRE([gl_DIRENT_H_DEFAULTS])
+])
+
AC_DEFUN([gl_DIRENT_H_DEFAULTS],
[
- AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) dnl for REPLACE_FCHDIR
- GNULIB_OPENDIR=0; AC_SUBST([GNULIB_OPENDIR])
- GNULIB_READDIR=0; AC_SUBST([GNULIB_READDIR])
- GNULIB_REWINDDIR=0; AC_SUBST([GNULIB_REWINDDIR])
- GNULIB_CLOSEDIR=0; AC_SUBST([GNULIB_CLOSEDIR])
- GNULIB_DIRFD=0; AC_SUBST([GNULIB_DIRFD])
- GNULIB_FDOPENDIR=0; AC_SUBST([GNULIB_FDOPENDIR])
- GNULIB_SCANDIR=0; AC_SUBST([GNULIB_SCANDIR])
- GNULIB_ALPHASORT=0; AC_SUBST([GNULIB_ALPHASORT])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_OPENDIR=1; AC_SUBST([HAVE_OPENDIR])
HAVE_READDIR=1; AC_SUBST([HAVE_READDIR])
diff --git a/m4/environ.m4 b/m4/environ.m4
index d971770860c..ae5329108e9 100644
--- a/m4/environ.m4
+++ b/m4/environ.m4
@@ -1,4 +1,4 @@
-# environ.m4 serial 7
+# environ.m4 serial 8
dnl Copyright (C) 2001-2004, 2006-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -33,7 +33,8 @@ AC_DEFUN([gt_CHECK_VAR_DECL],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[$1
- extern struct { int foo; } $2;]],
+ typedef struct { int foo; } foo_t;
+ extern foo_t $2;]],
[[$2.foo = 1;]])],
[gt_cv_var=no],
[gt_cv_var=yes])])
diff --git a/m4/explicit_bzero.m4 b/m4/explicit_bzero.m4
index d77ec5a3a5e..8c86d69e054 100644
--- a/m4/explicit_bzero.m4
+++ b/m4/explicit_bzero.m4
@@ -5,7 +5,7 @@ dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_EXPLICIT_BZERO],
[
- AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+ AC_REQUIRE([gl_STRING_H_DEFAULTS])
dnl Persuade glibc <string.h> to declare explicit_bzero.
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
diff --git a/m4/extern-inline.m4 b/m4/extern-inline.m4
index a2acf126c87..a4ac5ea532a 100644
--- a/m4/extern-inline.m4
+++ b/m4/extern-inline.m4
@@ -17,7 +17,8 @@ AC_DEFUN([gl_EXTERN_INLINE],
mishandles inline functions that call each other. E.g., for 'inline void f
(void) { } inline void g (void) { f (); }', c99 incorrectly complains
'reference to static identifier "f" in extern inline function'.
- This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16.
+ This bug was observed with Oracle Developer Studio 12.6
+ (Sun C 5.15 SunOS_sparc 2017/05/30).
Suppress extern inline (with or without __attribute__ ((__gnu_inline__)))
on configurations that mistakenly use 'static inline' to implement
@@ -83,8 +84,8 @@ AC_DEFUN([gl_EXTERN_INLINE],
# define _GL_EXTERN_INLINE extern
# define _GL_EXTERN_INLINE_IN_USE
#else
-# define _GL_INLINE static _GL_UNUSED
-# define _GL_EXTERN_INLINE static _GL_UNUSED
+# define _GL_INLINE _GL_UNUSED static
+# define _GL_EXTERN_INLINE _GL_UNUSED static
#endif
/* In GCC 4.6 (inclusive) to 5.1 (exclusive),
diff --git a/m4/fcntl_h.m4 b/m4/fcntl_h.m4
index e63a82f10a2..aba44735d14 100644
--- a/m4/fcntl_h.m4
+++ b/m4/fcntl_h.m4
@@ -1,4 +1,4 @@
-# serial 17
+# serial 20
# Configure fcntl.h.
dnl Copyright (C) 2006-2007, 2009-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
@@ -7,7 +7,7 @@ dnl with or without modifications, as long as this notice is preserved.
dnl Written by Paul Eggert.
-AC_DEFUN([gl_FCNTL_H],
+AC_DEFUN_ONCE([gl_FCNTL_H],
[
AC_REQUIRE([gl_FCNTL_H_DEFAULTS])
AC_REQUIRE([gl_FCNTL_O_FLAGS])
@@ -26,25 +26,40 @@ AC_DEFUN([gl_FCNTL_H],
]], [fcntl openat])
])
+# gl_FCNTL_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_FCNTL_MODULE_INDICATOR],
[
- dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
- AC_REQUIRE([gl_FCNTL_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only.
+ gl_FCNTL_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_FCNTL_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_FCNTL_H_MODULE_INDICATOR_DEFAULTS], [
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CREAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCNTL])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_NONBLOCKING])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OPEN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OPENAT])
+ dnl Support Microsoft deprecated alias function names by default.
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_CREAT], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_OPEN], [1])
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_FCNTL_H_MODULE_INDICATOR_DEFAULTS])
+ AC_REQUIRE([gl_FCNTL_H_DEFAULTS])
+])
+
AC_DEFUN([gl_FCNTL_H_DEFAULTS],
[
- GNULIB_CREAT=0; AC_SUBST([GNULIB_CREAT])
- GNULIB_FCNTL=0; AC_SUBST([GNULIB_FCNTL])
- GNULIB_NONBLOCKING=0; AC_SUBST([GNULIB_NONBLOCKING])
- GNULIB_OPEN=0; AC_SUBST([GNULIB_OPEN])
- GNULIB_OPENAT=0; AC_SUBST([GNULIB_OPENAT])
- dnl Support Microsoft deprecated alias function names by default.
- GNULIB_MDA_CREAT=1; AC_SUBST([GNULIB_MDA_CREAT])
- GNULIB_MDA_OPEN=1; AC_SUBST([GNULIB_MDA_OPEN])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_FCNTL=1; AC_SUBST([HAVE_FCNTL])
HAVE_OPENAT=1; AC_SUBST([HAVE_OPENAT])
diff --git a/m4/free.m4 b/m4/free.m4
index d671376b0bb..a7923b90590 100644
--- a/m4/free.m4
+++ b/m4/free.m4
@@ -1,4 +1,4 @@
-# free.m4 serial 5
+# free.m4 serial 6
# Copyright (C) 2003-2005, 2009-2021 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -40,7 +40,10 @@ AC_DEFUN([gl_FUNC_FREE],
])
case $gl_cv_func_free_preserves_errno in
- *yes) ;;
+ *yes)
+ AC_DEFINE([HAVE_FREE_POSIX], [1],
+ [Define if the 'free' function is guaranteed to preserve errno.])
+ ;;
*) REPLACE_FREE=1 ;;
esac
])
diff --git a/m4/gettimeofday.m4 b/m4/gettimeofday.m4
index 3c200815740..37c54404bb5 100644
--- a/m4/gettimeofday.m4
+++ b/m4/gettimeofday.m4
@@ -1,4 +1,4 @@
-# serial 28
+# serial 29
# Copyright (C) 2001-2003, 2005, 2007, 2009-2021 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
@@ -9,10 +9,10 @@ dnl From Jim Meyering.
AC_DEFUN([gl_FUNC_GETTIMEOFDAY],
[
- AC_REQUIRE([gl_HEADER_SYS_TIME_H_DEFAULTS])
+ AC_REQUIRE([gl_SYS_TIME_H_DEFAULTS])
AC_REQUIRE([AC_C_RESTRICT])
AC_REQUIRE([AC_CANONICAL_HOST])
- AC_REQUIRE([gl_HEADER_SYS_TIME_H])
+ AC_REQUIRE([gl_SYS_TIME_H])
AC_CHECK_FUNCS_ONCE([gettimeofday])
gl_gettimeofday_timezone=void
diff --git a/m4/glibc21.m4 b/m4/glibc21.m4
deleted file mode 100644
index 74a781aa1c9..00000000000
--- a/m4/glibc21.m4
+++ /dev/null
@@ -1,34 +0,0 @@
-# glibc21.m4 serial 5
-dnl Copyright (C) 2000-2002, 2004, 2008, 2010-2021 Free Software
-dnl 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.
-
-# Test for the GNU C Library, version 2.1 or newer, or uClibc.
-# From Bruno Haible.
-
-AC_DEFUN([gl_GLIBC21],
- [
- AC_CACHE_CHECK([whether we are using the GNU C Library >= 2.1 or uClibc],
- [ac_cv_gnu_library_2_1],
- [AC_EGREP_CPP([Lucky],
- [
-#include <features.h>
-#ifdef __GNU_LIBRARY__
- #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2)
- Lucky GNU user
- #endif
-#endif
-#ifdef __UCLIBC__
- Lucky user
-#endif
- ],
- [ac_cv_gnu_library_2_1=yes],
- [ac_cv_gnu_library_2_1=no])
- ]
- )
- AC_SUBST([GLIBC21])
- GLIBC21="$ac_cv_gnu_library_2_1"
- ]
-)
diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4
index f2eff10de6d..12b19dbcb44 100644
--- a/m4/gnulib-common.m4
+++ b/m4/gnulib-common.m4
@@ -1,4 +1,4 @@
-# gnulib-common.m4 serial 63
+# gnulib-common.m4 serial 67
dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -85,12 +85,12 @@ AC_DEFUN([gl_COMMON_BODY], [
# define _GL_ATTR_fallthrough _GL_GNUC_PREREQ (7, 0)
# define _GL_ATTR_format _GL_GNUC_PREREQ (2, 7)
# define _GL_ATTR_leaf _GL_GNUC_PREREQ (4, 6)
+# define _GL_ATTR_malloc _GL_GNUC_PREREQ (3, 0)
# ifdef _ICC
# define _GL_ATTR_may_alias 0
# else
# define _GL_ATTR_may_alias _GL_GNUC_PREREQ (3, 3)
# endif
-# define _GL_ATTR_malloc _GL_GNUC_PREREQ (3, 0)
# define _GL_ATTR_noinline _GL_GNUC_PREREQ (3, 1)
# define _GL_ATTR_nonnull _GL_GNUC_PREREQ (3, 3)
# define _GL_ATTR_nonstring _GL_GNUC_PREREQ (8, 0)
@@ -103,26 +103,47 @@ AC_DEFUN([gl_COMMON_BODY], [
# define _GL_ATTR_warn_unused_result _GL_GNUC_PREREQ (3, 4)
#endif
+#ifdef __has_c_attribute
+# define _GL_HAS_C_ATTRIBUTE(attr) __has_c_attribute (__##attr##__)
+#else
+# define _GL_HAS_C_ATTRIBUTE(attr) 0
+#endif
+
]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.
+ _GL_ATTRIBUTE_ALLOC_SIZE ((M, N)) declares that the Mth argument multiplied
+ by the Nth argument of the function is the size of the returned memory block.
+ */
+/* Applies to: function, pointer to function, function types. */
#if _GL_HAS_ATTRIBUTE (alloc_size)
# define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))
#else
# define _GL_ATTRIBUTE_ALLOC_SIZE(args)
#endif
+/* _GL_ATTRIBUTE_ALWAYS_INLINE tells that the compiler should always inline the
+ function and report an error if it cannot do so. */
+/* Applies to: function. */
#if _GL_HAS_ATTRIBUTE (always_inline)
# define _GL_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__))
#else
# define _GL_ATTRIBUTE_ALWAYS_INLINE
#endif
+/* _GL_ATTRIBUTE_ARTIFICIAL declares that the function is not important to show
+ in stack traces when debugging. The compiler should omit the function from
+ stack traces. */
+/* Applies to: function. */
#if _GL_HAS_ATTRIBUTE (artificial)
# define _GL_ATTRIBUTE_ARTIFICIAL __attribute__ ((__artificial__))
#else
# define _GL_ATTRIBUTE_ARTIFICIAL
#endif
+/* _GL_ATTRIBUTE_COLD declares that the function is rarely executed. */
+/* Applies to: functions. */
/* Avoid __attribute__ ((cold)) on MinGW; see thread starting at
<https://lists.gnu.org/r/emacs-devel/2019-04/msg01152.html>.
Also, Oracle Studio 12.6 requires 'cold' not '__cold__'. */
@@ -136,13 +157,41 @@ AC_DEFUN([gl_COMMON_BODY], [
# define _GL_ATTRIBUTE_COLD
#endif
+/* _GL_ATTRIBUTE_CONST declares that it is OK for a compiler to omit duplicate
+ calls to the function with the same arguments.
+ This attribute is safe for a function that neither depends on nor affects
+ observable state, and always returns exactly once - e.g., does not loop
+ forever, and does not call longjmp.
+ (This attribute is stricter than _GL_ATTRIBUTE_PURE.) */
+/* Applies to: functions. */
#if _GL_HAS_ATTRIBUTE (const)
# define _GL_ATTRIBUTE_CONST __attribute__ ((__const__))
#else
# define _GL_ATTRIBUTE_CONST
#endif
-#if 201710L < __STDC_VERSION__
+/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
+ that can be freed by passing them as the Ith argument to the
+ function F.
+ _GL_ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that
+ can be freed via 'free'; it can be used only after declaring 'free'. */
+/* Applies to: functions. Cannot be used on inline functions. */
+#if _GL_GNUC_PREREQ (11, 0)
+# define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i)))
+#else
+# define _GL_ATTRIBUTE_DEALLOC(f, i)
+#endif
+#define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (free, 1)
+
+/* _GL_ATTRIBUTE_DEPRECATED: Declares that an entity is deprecated.
+ The compiler may warn if the entity is used. */
+/* Applies to:
+ - function, variable,
+ - struct, union, struct/union member,
+ - enumeration, enumeration item,
+ - typedef,
+ in C++ also: namespace, class, template specialization. */
+#if _GL_HAS_C_ATTRIBUTE (deprecated)
# define _GL_ATTRIBUTE_DEPRECATED [[__deprecated__]]
#elif _GL_HAS_ATTRIBUTE (deprecated)
# define _GL_ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__))
@@ -150,6 +199,11 @@ AC_DEFUN([gl_COMMON_BODY], [
# define _GL_ATTRIBUTE_DEPRECATED
#endif
+/* _GL_ATTRIBUTE_ERROR(msg) requests an error if a function is called and
+ the function call is not optimized away.
+ _GL_ATTRIBUTE_WARNING(msg) requests a warning if a function is called and
+ the function call is not optimized away. */
+/* Applies to: functions. */
#if _GL_HAS_ATTRIBUTE (error)
# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__error__ (msg)))
# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__warning__ (msg)))
@@ -161,14 +215,21 @@ AC_DEFUN([gl_COMMON_BODY], [
# define _GL_ATTRIBUTE_WARNING(msg)
#endif
+/* _GL_ATTRIBUTE_EXTERNALLY_VISIBLE declares that the entity should remain
+ visible to debuggers etc., even with '-fwhole-program'. */
+/* Applies to: functions, variables. */
#if _GL_HAS_ATTRIBUTE (externally_visible)
# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE __attribute__ ((externally_visible))
#else
# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE
#endif
-/* FALLTHROUGH is special, because it always expands to something. */
-#if 201710L < __STDC_VERSION__
+/* _GL_ATTRIBUTE_FALLTHROUGH declares that it is not a programming mistake if
+ the control flow falls through to the immediately following 'case' or
+ 'default' label. The compiler should not warn in this case. */
+/* Applies to: Empty statement (;), inside a 'switch' statement. */
+/* Always expands to something. */
+#if _GL_HAS_C_ATTRIBUTE (fallthrough)
# define _GL_ATTRIBUTE_FALLTHROUGH [[__fallthrough__]]
#elif _GL_HAS_ATTRIBUTE (fallthrough)
# define _GL_ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__))
@@ -176,18 +237,47 @@ AC_DEFUN([gl_COMMON_BODY], [
# define _GL_ATTRIBUTE_FALLTHROUGH ((void) 0)
#endif
+/* _GL_ATTRIBUTE_FORMAT ((ARCHETYPE, STRING-INDEX, FIRST-TO-CHECK))
+ declares that the STRING-INDEXth function argument is a format string of
+ style ARCHETYPE, which is one of:
+ printf, gnu_printf
+ scanf, gnu_scanf,
+ strftime, gnu_strftime,
+ strfmon,
+ or the same thing prefixed and suffixed with '__'.
+ If FIRST-TO-CHECK is not 0, arguments starting at FIRST-TO_CHECK
+ are suitable for the format string. */
+/* Applies to: functions. */
#if _GL_HAS_ATTRIBUTE (format)
# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
#else
# define _GL_ATTRIBUTE_FORMAT(spec)
#endif
+/* _GL_ATTRIBUTE_LEAF declares that if the function is called from some other
+ compilation unit, it executes code from that unit only by return or by
+ exception handling. This declaration lets the compiler optimize that unit
+ more aggressively. */
+/* Applies to: functions. */
#if _GL_HAS_ATTRIBUTE (leaf)
# define _GL_ATTRIBUTE_LEAF __attribute__ ((__leaf__))
#else
# define _GL_ATTRIBUTE_LEAF
#endif
+/* _GL_ATTRIBUTE_MALLOC declares that the function returns a pointer to freshly
+ allocated memory. */
+/* Applies to: functions. */
+#if _GL_HAS_ATTRIBUTE (malloc)
+# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
+#else
+# define _GL_ATTRIBUTE_MALLOC
+#endif
+
+/* _GL_ATTRIBUTE_MAY_ALIAS declares that pointers to the type may point to the
+ same storage as pointers to other types. Thus this declaration disables
+ strict aliasing optimization. */
+/* Applies to: types. */
/* Oracle Studio 12.6 mishandles may_alias despite __has_attribute OK. */
#if _GL_HAS_ATTRIBUTE (may_alias) && !defined __SUNPRO_C
# define _GL_ATTRIBUTE_MAY_ALIAS __attribute__ ((__may_alias__))
@@ -195,24 +285,33 @@ AC_DEFUN([gl_COMMON_BODY], [
# define _GL_ATTRIBUTE_MAY_ALIAS
#endif
-#if 201710L < __STDC_VERSION__
+/* _GL_ATTRIBUTE_MAYBE_UNUSED declares that it is not a programming mistake if
+ the entity is not used. The compiler should not warn if the entity is not
+ used. */
+/* Applies to:
+ - function, variable,
+ - struct, union, struct/union member,
+ - enumeration, enumeration item,
+ - typedef,
+ in C++ also: class. */
+/* In C++ and C2x, this is spelled [[__maybe_unused__]].
+ GCC's syntax is __attribute__ ((__unused__)).
+ clang supports both syntaxes. */
+#if _GL_HAS_C_ATTRIBUTE (maybe_unused)
# define _GL_ATTRIBUTE_MAYBE_UNUSED [[__maybe_unused__]]
-#elif _GL_HAS_ATTRIBUTE (unused)
-# define _GL_ATTRIBUTE_MAYBE_UNUSED __attribute__ ((__unused__))
#else
-# define _GL_ATTRIBUTE_MAYBE_UNUSED
+# define _GL_ATTRIBUTE_MAYBE_UNUSED _GL_ATTRIBUTE_UNUSED
#endif
-/* Earlier spellings of this macro. */
+/* Alternative spelling of this macro, for convenience. */
#define _GL_UNUSED _GL_ATTRIBUTE_MAYBE_UNUSED
+/* Earlier spellings of this macro. */
#define _UNUSED_PARAMETER_ _GL_ATTRIBUTE_MAYBE_UNUSED
-#if _GL_HAS_ATTRIBUTE (malloc)
-# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
-#else
-# define _GL_ATTRIBUTE_MALLOC
-#endif
-
-#if 201710L < __STDC_VERSION__
+/* _GL_ATTRIBUTE_NODISCARD declares that the caller of the function should not
+ discard the return value. The compiler may warn if the caller does not use
+ the return value, unless the caller uses something like ignore_value. */
+/* Applies to: function, enumeration, class. */
+#if _GL_HAS_C_ATTRIBUTE (nodiscard)
# define _GL_ATTRIBUTE_NODISCARD [[__nodiscard__]]
#elif _GL_HAS_ATTRIBUTE (warn_unused_result)
# define _GL_ATTRIBUTE_NODISCARD __attribute__ ((__warn_unused_result__))
@@ -220,18 +319,30 @@ AC_DEFUN([gl_COMMON_BODY], [
# define _GL_ATTRIBUTE_NODISCARD
#endif
+/* _GL_ATTRIBUTE_NOINLINE tells that the compiler should not inline the
+ function. */
+/* Applies to: functions. */
#if _GL_HAS_ATTRIBUTE (noinline)
# define _GL_ATTRIBUTE_NOINLINE __attribute__ ((__noinline__))
#else
# define _GL_ATTRIBUTE_NOINLINE
#endif
+/* _GL_ATTRIBUTE_NONNULL ((N1, N2,...)) declares that the arguments N1, N2,...
+ must not be NULL.
+ _GL_ATTRIBUTE_NONNULL () declares that all pointer arguments must not be
+ null. */
+/* Applies to: functions. */
#if _GL_HAS_ATTRIBUTE (nonnull)
# define _GL_ATTRIBUTE_NONNULL(args) __attribute__ ((__nonnull__ args))
#else
# define _GL_ATTRIBUTE_NONNULL(args)
#endif
+/* _GL_ATTRIBUTE_NONSTRING declares that the contents of a character array is
+ not meant to be NUL-terminated. */
+/* Applies to: struct/union members and variables that are arrays of element
+ type '[[un]signed] char'. */
#if _GL_HAS_ATTRIBUTE (nonstring)
# define _GL_ATTRIBUTE_NONSTRING __attribute__ ((__nonstring__))
#else
@@ -240,41 +351,77 @@ AC_DEFUN([gl_COMMON_BODY], [
/* There is no _GL_ATTRIBUTE_NORETURN; use _Noreturn instead. */
+/* _GL_ATTRIBUTE_NOTHROW declares that the function does not throw exceptions.
+ */
+/* Applies to: functions. */
#if _GL_HAS_ATTRIBUTE (nothrow) && !defined __cplusplus
# define _GL_ATTRIBUTE_NOTHROW __attribute__ ((__nothrow__))
#else
# define _GL_ATTRIBUTE_NOTHROW
#endif
+/* _GL_ATTRIBUTE_PACKED declares:
+ For struct members: The member has the smallest possible alignment.
+ For struct, union, class: All members have the smallest possible alignment,
+ minimizing the memory required. */
+/* Applies to: struct members, struct, union,
+ in C++ also: class. */
#if _GL_HAS_ATTRIBUTE (packed)
# define _GL_ATTRIBUTE_PACKED __attribute__ ((__packed__))
#else
# define _GL_ATTRIBUTE_PACKED
#endif
+/* _GL_ATTRIBUTE_PURE declares that It is OK for a compiler to omit duplicate
+ calls to the function with the same arguments if observable state is not
+ changed between calls.
+ This attribute is safe for a function that does not affect
+ observable state, and always returns exactly once.
+ (This attribute is looser than _GL_ATTRIBUTE_CONST.) */
+/* Applies to: functions. */
#if _GL_HAS_ATTRIBUTE (pure)
# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
#else
# define _GL_ATTRIBUTE_PURE
#endif
+/* _GL_ATTRIBUTE_RETURNS_NONNULL declares that the function's return value is
+ a non-NULL pointer. */
+/* Applies to: functions. */
#if _GL_HAS_ATTRIBUTE (returns_nonnull)
# define _GL_ATTRIBUTE_RETURNS_NONNULL __attribute__ ((__returns_nonnull__))
#else
# define _GL_ATTRIBUTE_RETURNS_NONNULL
#endif
+/* _GL_ATTRIBUTE_SENTINEL(pos) declares that the variadic function expects a
+ trailing NULL argument.
+ _GL_ATTRIBUTE_SENTINEL () - The last argument is NULL (requires C99).
+ _GL_ATTRIBUTE_SENTINEL ((N)) - The (N+1)st argument from the end is NULL. */
+/* Applies to: functions. */
#if _GL_HAS_ATTRIBUTE (sentinel)
# define _GL_ATTRIBUTE_SENTINEL(pos) __attribute__ ((__sentinel__ pos))
#else
# define _GL_ATTRIBUTE_SENTINEL(pos)
#endif
+/* A helper macro. Don't use it directly. */
+#if _GL_HAS_ATTRIBUTE (unused)
+# define _GL_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+#else
+# define _GL_ATTRIBUTE_UNUSED
+#endif
+
]dnl There is no _GL_ATTRIBUTE_VISIBILITY; see m4/visibility.m4 instead.
[
-/* To support C++ as well as C, use _GL_UNUSED_LABEL with trailing ';'. */
-#if !defined __cplusplus || _GL_GNUC_PREREQ (4, 5)
-# define _GL_UNUSED_LABEL _GL_ATTRIBUTE_MAYBE_UNUSED
+/* _GL_UNUSED_LABEL; declares that it is not a programming mistake if the
+ immediately preceding label is not used. The compiler should not warn
+ if the label is not used. */
+/* Applies to: label (both in C and C++). */
+/* Note that g++ < 4.5 does not support the '__attribute__ ((__unused__)) ;'
+ syntax. But clang does. */
+#if !(defined __cplusplus && !_GL_GNUC_PREREQ (4, 5)) || defined __clang__
+# define _GL_UNUSED_LABEL _GL_ATTRIBUTE_UNUSED
#else
# define _GL_UNUSED_LABEL
#endif
@@ -357,6 +504,16 @@ AC_DEFUN([gl_COMMON_BODY], [
export LIBC_FATAL_STDERR_
])
+# gl_MODULE_INDICATOR_INIT_VARIABLE([variablename])
+# gl_MODULE_INDICATOR_INIT_VARIABLE([variablename], [initialvalue])
+# initializes the shell variable that indicates the presence of the given module
+# as a C preprocessor expression.
+AC_DEFUN([gl_MODULE_INDICATOR_INIT_VARIABLE],
+[
+ GL_MODULE_INDICATOR_PREFIX[]_[$1]=m4_if([$2], , [0], [$2])
+ AC_SUBST(GL_MODULE_INDICATOR_PREFIX[]_[$1])
+])
+
# gl_MODULE_INDICATOR_CONDITION
# expands to a C preprocessor expression that evaluates to 1 or 0, depending
# whether a gnulib module that has been requested shall be considered present
@@ -369,9 +526,9 @@ m4_define([gl_MODULE_INDICATOR_CONDITION], [1])
AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE],
[
gl_MODULE_INDICATOR_SET_VARIABLE_AUX(
- [GNULIB_[]m4_translit([[$1]],
- [abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])],
+ [GL_MODULE_INDICATOR_PREFIX[]_GNULIB_[]m4_translit([[$1]],
+ [abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])],
[gl_MODULE_INDICATOR_CONDITION])
])
@@ -656,6 +813,72 @@ AC_DEFUN([gl_CACHE_VAL_SILENT],
])
])
+# gl_CC_ALLOW_WARNINGS
+# sets and substitutes a variable GL_CFLAG_ALLOW_WARNINGS, to a $(CC) option
+# that reverts a preceding '-Werror' option, if available.
+# This is expected to be '-Wno-error' on gcc, clang (except clang/MSVC), xlclang
+# and empty otherwise.
+AC_DEFUN([gl_CC_ALLOW_WARNINGS],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_CACHE_CHECK([for C compiler option to allow warnings],
+ [gl_cv_cc_wallow],
+ [rm -f conftest*
+ echo 'int dummy;' > conftest.c
+ AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c 2>conftest1.err]) >/dev/null
+ AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -Wno-error -c conftest.c 2>conftest2.err]) >/dev/null
+ dnl Test the number of error output lines, because AIX xlc accepts the
+ dnl option '-Wno-error', just to produce a warning
+ dnl "Option -Wno-error was incorrectly specified. The option will be ignored."
+ dnl afterwards.
+ if test $? = 0 && test `wc -l < conftest1.err` = `wc -l < conftest2.err`; then
+ gl_cv_cc_wallow='-Wno-error'
+ else
+ gl_cv_cc_wallow=none
+ fi
+ rm -f conftest*
+ ])
+ case "$gl_cv_cc_wallow" in
+ none) GL_CFLAG_ALLOW_WARNINGS='' ;;
+ *) GL_CFLAG_ALLOW_WARNINGS="$gl_cv_cc_wallow" ;;
+ esac
+ AC_SUBST([GL_CFLAG_ALLOW_WARNINGS])
+])
+
+# gl_CXX_ALLOW_WARNINGS
+# sets and substitutes a variable GL_CXXFLAG_ALLOW_WARNINGS, to a $(CC) option
+# that reverts a preceding '-Werror' option, if available.
+AC_DEFUN([gl_CXX_ALLOW_WARNINGS],
+[
+ dnl Requires AC_PROG_CXX or gl_PROG_ANSI_CXX.
+ if test -n "$CXX" && test "$CXX" != no; then
+ AC_CACHE_CHECK([for C++ compiler option to allow warnings],
+ [gl_cv_cxx_wallow],
+ [rm -f conftest*
+ echo 'int dummy;' > conftest.cc
+ AC_TRY_COMMAND([${CXX-c++} $CXXFLAGS $CPPFLAGS -c conftest.cc 2>conftest1.err]) >/dev/null
+ AC_TRY_COMMAND([${CXX-c++} $CXXFLAGS $CPPFLAGS -Wno-error -c conftest.cc 2>conftest2.err]) >/dev/null
+ dnl Test the number of error output lines, because AIX xlC accepts the
+ dnl option '-Wno-error', just to produce a warning
+ dnl "Option -Wno-error was incorrectly specified. The option will be ignored."
+ dnl afterwards.
+ if test $? = 0 && test `wc -l < conftest1.err` = `wc -l < conftest2.err`; then
+ gl_cv_cxx_wallow='-Wno-error'
+ else
+ gl_cv_cxx_wallow=none
+ fi
+ rm -f conftest*
+ ])
+ case "$gl_cv_cxx_wallow" in
+ none) GL_CXXFLAG_ALLOW_WARNINGS='' ;;
+ *) GL_CXXFLAG_ALLOW_WARNINGS="$gl_cv_cxx_wallow" ;;
+ esac
+ else
+ GL_CXXFLAG_ALLOW_WARNINGS=''
+ fi
+ AC_SUBST([GL_CXXFLAG_ALLOW_WARNINGS])
+])
+
dnl Expands to some code for use in .c programs that, on native Windows, defines
dnl the Microsoft deprecated alias function names to the underscore-prefixed
dnl actual function names. With this macro, these function names are available
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 05e7faa9937..e314edcfb53 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -63,6 +63,7 @@ AC_DEFUN([gl_EARLY],
# Code from module count-leading-zeros:
# Code from module count-one-bits:
# Code from module count-trailing-zeros:
+ # Code from module crypto/md5:
# Code from module crypto/md5-buffer:
# Code from module crypto/sha1-buffer:
# Code from module crypto/sha256-buffer:
@@ -121,11 +122,13 @@ AC_DEFUN([gl_EARLY],
# Code from module inttypes-incomplete:
# Code from module largefile:
AC_REQUIRE([AC_SYS_LARGEFILE])
+ AC_REQUIRE([gl_YEAR2038_EARLY])
# Code from module lchmod:
# Code from module libc-config:
# Code from module libgmp:
# Code from module limits-h:
# Code from module lstat:
+ # Code from module malloc-posix:
# Code from module manywarnings:
# Code from module memmem-simple:
# Code from module mempcpy:
@@ -136,6 +139,7 @@ AC_DEFUN([gl_EARLY],
# Code from module mktime-internal:
# Code from module multiarch:
# Code from module nocrash:
+ # Code from module nproc:
# Code from module nstrftime:
# Code from module open:
# Code from module openat-h:
@@ -147,6 +151,8 @@ AC_DEFUN([gl_EARLY],
# Code from module rawmemchr:
# Code from module readlink:
# Code from module readlinkat:
+ # Code from module realloc-gnu:
+ # Code from module realloc-posix:
# Code from module regex:
# Code from module root-uid:
# Code from module scratch_buffer:
@@ -189,6 +195,7 @@ AC_DEFUN([gl_EARLY],
# Code from module u64:
# Code from module unistd:
# Code from module unlocked-io:
+ # Code from module unlocked-io-internal:
# Code from module update-copyright:
# Code from module utimens:
# Code from module utimensat:
@@ -213,6 +220,8 @@ AC_DEFUN([gl_INIT],
m4_pushdef([AC_LIBSOURCES], m4_defn([gl_LIBSOURCES]))
m4_pushdef([gl_LIBSOURCES_LIST], [])
m4_pushdef([gl_LIBSOURCES_DIR], [])
+ m4_pushdef([GL_MACRO_PREFIX], [gl])
+ m4_pushdef([GL_MODULE_INDICATOR_PREFIX], [GL])
gl_COMMON
gl_source_base='lib'
gl_FUNC_ACL
@@ -245,6 +254,7 @@ AC_DEFUN([gl_INIT],
gl_SHA512
gl_CHECK_TYPE_STRUCT_DIRENT_D_TYPE
gl_DIRENT_H
+ gl_DIRENT_H_REQUIRE_DEFAULTS
gl_DOUBLE_SLASH_ROOT
gl_FUNC_DUP2
if test $REPLACE_DUP2 = 1; then
@@ -282,6 +292,7 @@ AC_DEFUN([gl_INIT],
fi
gl_FCNTL_MODULE_INDICATOR([fcntl])
gl_FCNTL_H
+ gl_FCNTL_H_REQUIRE_DEFAULTS
gl_FUNC_FDOPENDIR
if test $HAVE_FDOPENDIR = 0 || test $REPLACE_FDOPENDIR = 1; then
AC_LIBOBJ([fdopendir])
@@ -337,10 +348,10 @@ AC_DEFUN([gl_INIT],
if test $REPLACE_GETOPT = 1; then
AC_LIBOBJ([getopt])
AC_LIBOBJ([getopt1])
- dnl Arrange for unistd.h to include getopt.h.
- GNULIB_GL_UNISTD_H_GETOPT=1
+ dnl Define the substituted variable GNULIB_UNISTD_H_GETOPT to 1.
+ gl_UNISTD_H_REQUIRE_DEFAULTS
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNISTD_H_GETOPT], [1])
fi
- AC_SUBST([GNULIB_GL_UNISTD_H_GETOPT])
gl_UNISTD_MODULE_INDICATOR([getopt-posix])
AC_REQUIRE([AC_CANONICAL_HOST])
gl_FUNC_GETRANDOM
@@ -357,6 +368,7 @@ AC_DEFUN([gl_INIT],
gl_SYS_TIME_MODULE_INDICATOR([gettimeofday])
gl_IEEE754_H
gl_INTTYPES_INCOMPLETE
+ gl_INTTYPES_H_REQUIRE_DEFAULTS
AC_REQUIRE([gl_LARGEFILE])
gl___INLINE
gl_LIBGMP
@@ -402,6 +414,7 @@ AC_DEFUN([gl_INIT],
fi
gl_TIME_MODULE_INDICATOR([mktime])
gl_MULTIARCH
+ gl_NPROC
gl_FUNC_GNU_STRFTIME
gl_PATHMAX
gl_FUNC_PIPE2
@@ -444,22 +457,50 @@ AC_DEFUN([gl_INIT],
fi
gl_STRING_MODULE_INDICATOR([sigdescr_np])
gl_SIGNAL_H
+ gl_SIGNAL_H_REQUIRE_DEFAULTS
gl_TYPE_SOCKLEN_T
gt_TYPE_SSIZE_T
gl_STAT_TIME
gl_STAT_BIRTHTIME
gl_STDALIGN_H
gl_STDDEF_H
+ gl_STDDEF_H_REQUIRE_DEFAULTS
gl_STDINT_H
gl_STDIO_H
+ gl_STDIO_H_REQUIRE_DEFAULTS
+ dnl No need to create extra modules for these functions. Everyone who uses
+ dnl <stdio.h> likely needs them.
+ gl_STDIO_MODULE_INDICATOR([fscanf])
+ gl_MODULE_INDICATOR([fscanf])
+ gl_STDIO_MODULE_INDICATOR([scanf])
+ gl_MODULE_INDICATOR([scanf])
+ gl_STDIO_MODULE_INDICATOR([fgetc])
+ gl_STDIO_MODULE_INDICATOR([getc])
+ gl_STDIO_MODULE_INDICATOR([getchar])
+ gl_STDIO_MODULE_INDICATOR([fgets])
+ gl_STDIO_MODULE_INDICATOR([fread])
+ dnl No need to create extra modules for these functions. Everyone who uses
+ dnl <stdio.h> likely needs them.
+ gl_STDIO_MODULE_INDICATOR([fprintf])
+ gl_STDIO_MODULE_INDICATOR([printf])
+ gl_STDIO_MODULE_INDICATOR([vfprintf])
+ gl_STDIO_MODULE_INDICATOR([vprintf])
+ gl_STDIO_MODULE_INDICATOR([fputc])
+ gl_STDIO_MODULE_INDICATOR([putc])
+ gl_STDIO_MODULE_INDICATOR([putchar])
+ gl_STDIO_MODULE_INDICATOR([fputs])
+ gl_STDIO_MODULE_INDICATOR([puts])
+ gl_STDIO_MODULE_INDICATOR([fwrite])
gl_STDLIB_H
+ gl_STDLIB_H_REQUIRE_DEFAULTS
gl_FUNC_STPCPY
if test $HAVE_STPCPY = 0; then
AC_LIBOBJ([stpcpy])
gl_PREREQ_STPCPY
fi
gl_STRING_MODULE_INDICATOR([stpcpy])
- gl_HEADER_STRING_H
+ gl_STRING_H
+ gl_STRING_H_REQUIRE_DEFAULTS
gl_FUNC_STRNLEN
if test $HAVE_DECL_STRNLEN = 0 || test $REPLACE_STRNLEN = 1; then
AC_LIBOBJ([strnlen])
@@ -477,19 +518,25 @@ AC_DEFUN([gl_INIT],
AC_LIBOBJ([symlink])
fi
gl_UNISTD_MODULE_INDICATOR([symlink])
- gl_HEADER_SYS_RANDOM
+ gl_SYS_RANDOM_H
+ gl_SYS_RANDOM_H_REQUIRE_DEFAULTS
AC_PROG_MKDIR_P
- AC_REQUIRE([gl_HEADER_SYS_SELECT])
+ gl_SYS_SELECT_H
+ gl_SYS_SELECT_H_REQUIRE_DEFAULTS
AC_PROG_MKDIR_P
- gl_HEADER_SYS_STAT_H
+ gl_SYS_STAT_H
+ gl_SYS_STAT_H_REQUIRE_DEFAULTS
AC_PROG_MKDIR_P
- gl_HEADER_SYS_TIME_H
+ gl_SYS_TIME_H
+ gl_SYS_TIME_H_REQUIRE_DEFAULTS
AC_PROG_MKDIR_P
gl_SYS_TYPES_H
+ gl_SYS_TYPES_H_REQUIRE_DEFAULTS
AC_PROG_MKDIR_P
gl_FUNC_GEN_TEMPNAME
gl_MODULE_INDICATOR([tempname])
- gl_HEADER_TIME_H
+ gl_TIME_H
+ gl_TIME_H_REQUIRE_DEFAULTS
gl_TIME_R
if test $HAVE_LOCALTIME_R = 0 || test $REPLACE_LOCALTIME_R = 1; then
AC_LIBOBJ([time_r])
@@ -510,6 +557,17 @@ AC_DEFUN([gl_INIT],
gl_TIMER_TIME
gl_TIMESPEC
gl_UNISTD_H
+ gl_UNISTD_H_REQUIRE_DEFAULTS
+ AC_DEFINE([GNULIB_STDIO_SINGLE_THREAD], [1],
+ [Define to 1 if you want the FILE stream functions getc, putc, etc.
+ to use unlocked I/O if available, throughout the package.
+ Unlocked I/O can improve performance, sometimes dramatically.
+ But unlocked I/O is safe only in single-threaded programs,
+ as well as in multithreaded programs for which you can guarantee that
+ every FILE stream, including stdin, stdout, stderr, is used only
+ in a single thread.])
+ AC_DEFINE([USE_UNLOCKED_IO], [GNULIB_STDIO_SINGLE_THREAD],
+ [An alias of GNULIB_STDIO_SINGLE_THREAD.])
gl_FUNC_GLIBC_UNLOCKED_IO
gl_FUNC_UTIMENSAT
if test $HAVE_UTIMENSAT = 0 || test $REPLACE_UTIMENSAT = 1; then
@@ -527,12 +585,14 @@ AC_DEFUN([gl_INIT],
gl_gnulib_enabled_getgroups=false
gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false
gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1=false
- gl_gnulib_enabled_idx=false
gl_gnulib_enabled_lchmod=false
+ gl_gnulib_enabled_ef455225c00f5049c808c2eda3e76866=false
gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31=false
gl_gnulib_enabled_open=false
gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7=false
gl_gnulib_enabled_rawmemchr=false
+ gl_gnulib_enabled_d3b2383720ee0e541357aa2aac598e2b=false
+ gl_gnulib_enabled_61bcaca76b3e6f9ae55d57a1c3193bc4=false
gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=false
gl_gnulib_enabled_scratch_buffer=false
gl_gnulib_enabled_strtoll=false
@@ -571,6 +631,7 @@ AC_DEFUN([gl_INIT],
func_gl_gnulib_m4code_dynarray ()
{
if ! $gl_gnulib_enabled_dynarray; then
+ AC_PROG_MKDIR_P
gl_gnulib_enabled_dynarray=true
fi
}
@@ -617,6 +678,9 @@ AC_DEFUN([gl_INIT],
fi
gl_UNISTD_MODULE_INDICATOR([getgroups])
gl_gnulib_enabled_getgroups=true
+ if test $HAVE_GETGROUPS = 0 || test $REPLACE_GETGROUPS = 1; then
+ func_gl_gnulib_m4code_ef455225c00f5049c808c2eda3e76866
+ fi
fi
}
func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36 ()
@@ -641,16 +705,10 @@ AC_DEFUN([gl_INIT],
func_gl_gnulib_m4code_getgroups
fi
if test $HAVE_GROUP_MEMBER = 0; then
- func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec
+ func_gl_gnulib_m4code_d3b2383720ee0e541357aa2aac598e2b
fi
fi
}
- func_gl_gnulib_m4code_idx ()
- {
- if ! $gl_gnulib_enabled_idx; then
- gl_gnulib_enabled_idx=true
- fi
- }
func_gl_gnulib_m4code_lchmod ()
{
if ! $gl_gnulib_enabled_lchmod; then
@@ -663,6 +721,20 @@ AC_DEFUN([gl_INIT],
gl_gnulib_enabled_lchmod=true
fi
}
+ func_gl_gnulib_m4code_ef455225c00f5049c808c2eda3e76866 ()
+ {
+ if ! $gl_gnulib_enabled_ef455225c00f5049c808c2eda3e76866; then
+ AC_REQUIRE([gl_FUNC_MALLOC_POSIX])
+ if test $REPLACE_MALLOC = 1; then
+ AC_LIBOBJ([malloc])
+ fi
+ gl_STDLIB_MODULE_INDICATOR([malloc-posix])
+ gl_gnulib_enabled_ef455225c00f5049c808c2eda3e76866=true
+ if test $REPLACE_MALLOC = 1; then
+ func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec
+ fi
+ fi
+ }
func_gl_gnulib_m4code_5264294aa0a5557541b53c8c741f7f31 ()
{
if ! $gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31; then
@@ -707,6 +779,34 @@ AC_DEFUN([gl_INIT],
gl_gnulib_enabled_rawmemchr=true
fi
}
+ func_gl_gnulib_m4code_d3b2383720ee0e541357aa2aac598e2b ()
+ {
+ if ! $gl_gnulib_enabled_d3b2383720ee0e541357aa2aac598e2b; then
+ gl_FUNC_REALLOC_GNU
+ if test $REPLACE_REALLOC = 1; then
+ AC_LIBOBJ([realloc])
+ fi
+ gl_gnulib_enabled_d3b2383720ee0e541357aa2aac598e2b=true
+ func_gl_gnulib_m4code_61bcaca76b3e6f9ae55d57a1c3193bc4
+ fi
+ }
+ func_gl_gnulib_m4code_61bcaca76b3e6f9ae55d57a1c3193bc4 ()
+ {
+ if ! $gl_gnulib_enabled_61bcaca76b3e6f9ae55d57a1c3193bc4; then
+ gl_FUNC_REALLOC_POSIX
+ if test $REPLACE_REALLOC = 1; then
+ AC_LIBOBJ([realloc])
+ fi
+ gl_STDLIB_MODULE_INDICATOR([realloc-posix])
+ gl_gnulib_enabled_61bcaca76b3e6f9ae55d57a1c3193bc4=true
+ if test $REPLACE_REALLOC = 1; then
+ func_gl_gnulib_m4code_ef455225c00f5049c808c2eda3e76866
+ fi
+ if test $REPLACE_REALLOC = 1; then
+ func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec
+ fi
+ fi
+ }
func_gl_gnulib_m4code_6099e9737f757db36c47fa9d9f02e88c ()
{
if ! $gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c; then
@@ -716,14 +816,17 @@ AC_DEFUN([gl_INIT],
func_gl_gnulib_m4code_scratch_buffer ()
{
if ! $gl_gnulib_enabled_scratch_buffer; then
+ AC_PROG_MKDIR_P
gl_gnulib_enabled_scratch_buffer=true
+ func_gl_gnulib_m4code_ef455225c00f5049c808c2eda3e76866
+ func_gl_gnulib_m4code_61bcaca76b3e6f9ae55d57a1c3193bc4
fi
}
func_gl_gnulib_m4code_strtoll ()
{
if ! $gl_gnulib_enabled_strtoll; then
gl_FUNC_STRTOLL
- if test $HAVE_STRTOLL = 0; then
+ if test $HAVE_STRTOLL = 0 || test $REPLACE_STRTOLL = 1; then
AC_LIBOBJ([strtoll])
gl_PREREQ_STRTOLL
fi
@@ -748,9 +851,6 @@ AC_DEFUN([gl_INIT],
func_gl_gnulib_m4code_925677f0343de64b89a9f0c790b4104c
fi
if test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONICALIZE_FILE_NAME = 1; then
- func_gl_gnulib_m4code_idx
- fi
- if test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONICALIZE_FILE_NAME = 1; then
func_gl_gnulib_m4code_rawmemchr
fi
if test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONICALIZE_FILE_NAME = 1; then
@@ -813,9 +913,6 @@ AC_DEFUN([gl_INIT],
if { test $HAVE_DECL_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; } && test $ac_cv_type_long_long_int = yes; then
func_gl_gnulib_m4code_strtoll
fi
- if test $HAVE_TIMEZONE_T = 0; then
- func_gl_gnulib_m4code_idx
- fi
if test $HAVE_TIMEGM = 0 || test $REPLACE_TIMEGM = 1; then
func_gl_gnulib_m4code_5264294aa0a5557541b53c8c741f7f31
fi
@@ -839,12 +936,14 @@ AC_DEFUN([gl_INIT],
AM_CONDITIONAL([gl_GNULIB_ENABLED_getgroups], [$gl_gnulib_enabled_getgroups])
AM_CONDITIONAL([gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36], [$gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36])
AM_CONDITIONAL([gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1], [$gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1])
- AM_CONDITIONAL([gl_GNULIB_ENABLED_idx], [$gl_gnulib_enabled_idx])
AM_CONDITIONAL([gl_GNULIB_ENABLED_lchmod], [$gl_gnulib_enabled_lchmod])
+ AM_CONDITIONAL([gl_GNULIB_ENABLED_ef455225c00f5049c808c2eda3e76866], [$gl_gnulib_enabled_ef455225c00f5049c808c2eda3e76866])
AM_CONDITIONAL([gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31], [$gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31])
AM_CONDITIONAL([gl_GNULIB_ENABLED_open], [$gl_gnulib_enabled_open])
AM_CONDITIONAL([gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7], [$gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7])
AM_CONDITIONAL([gl_GNULIB_ENABLED_rawmemchr], [$gl_gnulib_enabled_rawmemchr])
+ AM_CONDITIONAL([gl_GNULIB_ENABLED_d3b2383720ee0e541357aa2aac598e2b], [$gl_gnulib_enabled_d3b2383720ee0e541357aa2aac598e2b])
+ AM_CONDITIONAL([gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4], [$gl_gnulib_enabled_61bcaca76b3e6f9ae55d57a1c3193bc4])
AM_CONDITIONAL([gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c], [$gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c])
AM_CONDITIONAL([gl_GNULIB_ENABLED_scratch_buffer], [$gl_gnulib_enabled_scratch_buffer])
AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll])
@@ -862,6 +961,8 @@ AC_DEFUN([gl_INIT],
m4_if(m4_sysval, [0], [],
[AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])])
])
+ m4_popdef([GL_MODULE_INDICATOR_PREFIX])
+ m4_popdef([GL_MACRO_PREFIX])
m4_popdef([gl_LIBSOURCES_DIR])
m4_popdef([gl_LIBSOURCES_LIST])
m4_popdef([AC_LIBSOURCES])
@@ -888,6 +989,8 @@ AC_DEFUN([gl_INIT],
m4_pushdef([AC_LIBSOURCES], m4_defn([gltests_LIBSOURCES]))
m4_pushdef([gltests_LIBSOURCES_LIST], [])
m4_pushdef([gltests_LIBSOURCES_DIR], [])
+ m4_pushdef([GL_MACRO_PREFIX], [gltests])
+ m4_pushdef([GL_MODULE_INDICATOR_PREFIX], [GL])
gl_COMMON
gl_source_base='tests'
changequote(,)dnl
@@ -909,6 +1012,8 @@ changequote([, ])dnl
m4_if(m4_sysval, [0], [],
[AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])])
])
+ m4_popdef([GL_MODULE_INDICATOR_PREFIX])
+ m4_popdef([GL_MACRO_PREFIX])
m4_popdef([gltests_LIBSOURCES_DIR])
m4_popdef([gltests_LIBSOURCES_LIST])
m4_popdef([AC_LIBSOURCES])
@@ -1092,6 +1197,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/libc-config.h
lib/limits.in.h
lib/lstat.c
+ lib/malloc.c
lib/malloc/dynarray-skeleton.c
lib/malloc/dynarray.h
lib/malloc/dynarray_at_failure.c
@@ -1104,6 +1210,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/malloc/scratch_buffer_grow.c
lib/malloc/scratch_buffer_grow_preserve.c
lib/malloc/scratch_buffer_set_array_size.c
+ lib/md5-stream.c
lib/md5.c
lib/md5.h
lib/memmem.c
@@ -1116,6 +1223,8 @@ AC_DEFUN([gl_FILE_LIST], [
lib/mkostemp.c
lib/mktime-internal.h
lib/mktime.c
+ lib/nproc.c
+ lib/nproc.h
lib/nstrftime.c
lib/open.c
lib/openat-priv.h
@@ -1130,6 +1239,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/rawmemchr.valgrind
lib/readlink.c
lib/readlinkat.c
+ lib/realloc.c
lib/regcomp.c
lib/regex.c
lib/regex.h
@@ -1250,6 +1360,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/libgmp.m4
m4/limits-h.m4
m4/lstat.m4
+ m4/malloc.m4
m4/manywarnings-c++.m4
m4/manywarnings.m4
m4/mbstate_t.m4
@@ -1263,6 +1374,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/mode_t.m4
m4/multiarch.m4
m4/nocrash.m4
+ m4/nproc.m4
m4/nstrftime.m4
m4/off_t.m4
m4/open-cloexec.m4
@@ -1276,6 +1388,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/rawmemchr.m4
m4/readlink.m4
m4/readlinkat.m4
+ m4/realloc.m4
m4/regex.m4
m4/sha1.m4
m4/sha256.m4
@@ -1322,5 +1435,6 @@ AC_DEFUN([gl_FILE_LIST], [
m4/warnings.m4
m4/wchar_t.m4
m4/wint_t.m4
+ m4/year2038.m4
m4/zzgnulib.m4
])
diff --git a/m4/gsettings.m4 b/m4/gsettings.m4
new file mode 100644
index 00000000000..882e6a83e76
--- /dev/null
+++ b/m4/gsettings.m4
@@ -0,0 +1,88 @@
+# Increment this whenever this file is changed.
+#serial 2
+
+dnl GLIB_GSETTINGS
+dnl Defines GSETTINGS_SCHEMAS_INSTALL which controls whether
+dnl the schema should be compiled
+dnl
+
+AC_DEFUN([GLIB_GSETTINGS],
+[
+ dnl We can't use PKG_PREREQ because that needs 0.29.
+ m4_ifndef([PKG_PROG_PKG_CONFIG],
+ [pkg.m4 version 0.28 or later is required])
+
+ m4_pattern_allow([AM_V_GEN])
+ AC_ARG_ENABLE(schemas-compile,
+ AS_HELP_STRING([--disable-schemas-compile],
+ [Disable regeneration of gschemas.compiled on install]),
+ [case ${enableval} in
+ yes) GSETTINGS_DISABLE_SCHEMAS_COMPILE="" ;;
+ no) GSETTINGS_DISABLE_SCHEMAS_COMPILE="1" ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for --enable-schemas-compile]) ;;
+ esac])
+ AC_SUBST([GSETTINGS_DISABLE_SCHEMAS_COMPILE])
+ PKG_PROG_PKG_CONFIG([0.16])
+ AC_SUBST(gsettingsschemadir, [${datadir}/glib-2.0/schemas])
+ AS_IF([test x$cross_compiling != xyes],
+ [PKG_CHECK_VAR([GLIB_COMPILE_SCHEMAS], [gio-2.0], [glib_compile_schemas])],
+ [AC_PATH_PROG([GLIB_COMPILE_SCHEMAS], [glib-compile-schemas])])
+ AC_SUBST(GLIB_COMPILE_SCHEMAS)
+ if test "x$GLIB_COMPILE_SCHEMAS" = "x"; then
+ ifelse([$2],,[AC_MSG_ERROR([glib-compile-schemas not found.])],[$2])
+ else
+ ifelse([$1],,[:],[$1])
+ fi
+
+ GSETTINGS_RULES='
+.PHONY : uninstall-gsettings-schemas install-gsettings-schemas clean-gsettings-schemas
+
+mostlyclean-am: clean-gsettings-schemas
+
+gsettings__enum_file = $(addsuffix .enums.xml,$(gsettings_ENUM_NAMESPACE))
+
+%.gschema.valid: %.gschema.xml $(gsettings__enum_file)
+ $(AM_V_GEN) $(GLIB_COMPILE_SCHEMAS) --strict --dry-run $(addprefix --schema-file=,$(gsettings__enum_file)) --schema-file=$< && mkdir -p [$](@D) && touch [$]@
+
+all-am: $(gsettings_SCHEMAS:.xml=.valid)
+uninstall-am: uninstall-gsettings-schemas
+install-data-am: install-gsettings-schemas
+
+.SECONDARY: $(gsettings_SCHEMAS)
+
+install-gsettings-schemas: $(gsettings_SCHEMAS) $(gsettings__enum_file)
+ @$(NORMAL_INSTALL)
+ if test -n "$^"; then \
+ test -z "$(gsettingsschemadir)" || $(MKDIR_P) "$(DESTDIR)$(gsettingsschemadir)"; \
+ $(INSTALL_DATA) $^ "$(DESTDIR)$(gsettingsschemadir)"; \
+ test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir); \
+ fi
+
+uninstall-gsettings-schemas:
+ @$(NORMAL_UNINSTALL)
+ @list='\''$(gsettings_SCHEMAS) $(gsettings__enum_file)'\''; test -n "$(gsettingsschemadir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e '\''s|^.*/||'\''`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '\''$(DESTDIR)$(gsettingsschemadir)'\'' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(gsettingsschemadir)" && rm -f $$files
+ test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir)
+
+clean-gsettings-schemas:
+ rm -f $(gsettings_SCHEMAS:.xml=.valid) $(gsettings__enum_file)
+
+ifdef gsettings_ENUM_NAMESPACE
+$(gsettings__enum_file): $(gsettings_ENUM_FILES)
+ $(AM_V_GEN) glib-mkenums --comments '\''<!-- @comment@ -->'\'' --fhead "<schemalist>" --vhead " <@type@ id='\''$(gsettings_ENUM_NAMESPACE).@EnumName@'\''>" --vprod " <value nick='\''@valuenick@'\'' value='\''@valuenum@'\''/>" --vtail " </@type@>" --ftail "</schemalist>" [$]^ > [$]@.tmp && mv [$]@.tmp [$]@
+endif
+'
+ _GSETTINGS_SUBST(GSETTINGS_RULES)
+])
+
+dnl _GSETTINGS_SUBST(VARIABLE)
+dnl Abstract macro to do either _AM_SUBST_NOTMAKE or AC_SUBST
+AC_DEFUN([_GSETTINGS_SUBST],
+[
+AC_SUBST([$1])
+m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([$1])])
+]
+)
diff --git a/m4/inttypes.m4 b/m4/inttypes.m4
index f56e94a8881..64b1de5c42a 100644
--- a/m4/inttypes.m4
+++ b/m4/inttypes.m4
@@ -1,4 +1,4 @@
-# inttypes.m4 serial 32
+# inttypes.m4 serial 35
dnl Copyright (C) 2006-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -7,7 +7,7 @@ dnl with or without modifications, as long as this notice is preserved.
dnl From Derek Price, Bruno Haible.
dnl Test whether <inttypes.h> is supported or must be substituted.
-AC_DEFUN([gl_INTTYPES_H],
+AC_DEFUN_ONCE([gl_INTTYPES_H],
[
AC_REQUIRE([gl_INTTYPES_INCOMPLETE])
gl_INTTYPES_PRI_SCN
@@ -136,19 +136,34 @@ AC_DEFUN([gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION],
AC_SUBST([$1])
])
+# gl_INTTYPES_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_INTTYPES_MODULE_INDICATOR],
[
- dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
- AC_REQUIRE([gl_INTTYPES_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only.
+ gl_INTTYPES_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
])
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_INTTYPES_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_INTTYPES_H_MODULE_INDICATOR_DEFAULTS], [
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_IMAXABS])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_IMAXDIV])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOIMAX])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOUMAX])
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_INTTYPES_H_MODULE_INDICATOR_DEFAULTS])
+ AC_REQUIRE([gl_INTTYPES_H_DEFAULTS])
+])
+
AC_DEFUN([gl_INTTYPES_H_DEFAULTS],
[
- GNULIB_IMAXABS=0; AC_SUBST([GNULIB_IMAXABS])
- GNULIB_IMAXDIV=0; AC_SUBST([GNULIB_IMAXDIV])
- GNULIB_STRTOIMAX=0; AC_SUBST([GNULIB_STRTOIMAX])
- GNULIB_STRTOUMAX=0; AC_SUBST([GNULIB_STRTOUMAX])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_DECL_IMAXABS=1; AC_SUBST([HAVE_DECL_IMAXABS])
HAVE_DECL_IMAXDIV=1; AC_SUBST([HAVE_DECL_IMAXDIV])
diff --git a/m4/largefile.m4 b/m4/largefile.m4
index cadb16dc972..fbde5e66471 100644
--- a/m4/largefile.m4
+++ b/m4/largefile.m4
@@ -22,7 +22,8 @@ AC_DEFUN([gl_SET_LARGEFILE_SOURCE],
esac
])
-# The following implementation works around a problem in autoconf <= 2.69;
+# Work around a problem in Autoconf through at least 2.71 on glibc 2.34+
+# with _TIME_BITS. Also, work around a problem in autoconf <= 2.69:
# AC_SYS_LARGEFILE does not configure for large inodes on Mac OS X 10.5,
# or configures them incorrectly in some cases.
m4_version_prereq([2.70], [], [
@@ -40,6 +41,7 @@ m4_define([_AC_SYS_LARGEFILE_TEST_INCLUDES],
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1]];[]dnl
])
+])# m4_version_prereq 2.70
# _AC_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, VALUE,
@@ -54,7 +56,8 @@ m4_define([_AC_SYS_LARGEFILE_MACRO_VALUE],
[AC_LANG_PROGRAM([$5], [$6])],
[$3=no; break])
m4_ifval([$6], [AC_LINK_IFELSE], [AC_COMPILE_IFELSE])(
- [AC_LANG_PROGRAM([#define $1 $2
+ [AC_LANG_PROGRAM([#undef $1
+#define $1 $2
$5], [$6])],
[$3=$2; break])
$3=unknown
@@ -80,9 +83,8 @@ rm -rf conftest*[]dnl
AC_DEFUN([AC_SYS_LARGEFILE],
[AC_ARG_ENABLE(largefile,
[ --disable-largefile omit support for large files])
-if test "$enable_largefile" != no; then
-
- AC_CACHE_CHECK([for special C compiler options needed for large files],
+AS_IF([test "$enable_largefile" != no],
+ [AC_CACHE_CHECK([for special C compiler options needed for large files],
ac_cv_sys_largefile_CC,
[ac_cv_sys_largefile_CC=no
if test "$GCC" != yes; then
@@ -107,15 +109,15 @@ if test "$enable_largefile" != no; then
ac_cv_sys_file_offset_bits,
[Number of bits in a file offset, on hosts where this is settable.],
[_AC_SYS_LARGEFILE_TEST_INCLUDES])
- if test $ac_cv_sys_file_offset_bits = unknown; then
- _AC_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, 1,
- ac_cv_sys_large_files,
- [Define for large files, on AIX-style hosts.],
- [_AC_SYS_LARGEFILE_TEST_INCLUDES])
- fi
-fi
+ AS_CASE([$ac_cv_sys_file_offset_bits],
+ [unknown],
+ [_AC_SYS_LARGEFILE_MACRO_VALUE([_LARGE_FILES], [1],
+ [ac_cv_sys_large_files],
+ [Define for large files, on AIX-style hosts.],
+ [_AC_SYS_LARGEFILE_TEST_INCLUDES])],
+ [64],
+ [gl_YEAR2038_BODY([])])])
])# AC_SYS_LARGEFILE
-])# m4_version_prereq 2.70
# Enable large files on systems where this is implemented by Gnulib, not by the
# system headers.
diff --git a/m4/limits-h.m4 b/m4/limits-h.m4
index 70dbb7dcfa0..00c9fe9e50a 100644
--- a/m4/limits-h.m4
+++ b/m4/limits-h.m4
@@ -11,7 +11,7 @@ AC_DEFUN_ONCE([gl_LIMITS_H],
[
gl_CHECK_NEXT_HEADERS([limits.h])
- AC_CACHE_CHECK([whether limits.h has LLONG_MAX, WORD_BIT, ULLONG_WIDTH etc.],
+ AC_CACHE_CHECK([whether limits.h has WORD_BIT, BOOL_WIDTH etc.],
[gl_cv_header_limits_width],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
@@ -22,6 +22,7 @@ AC_DEFUN_ONCE([gl_LIMITS_H],
long long llm = LLONG_MAX;
int wb = WORD_BIT;
int ullw = ULLONG_WIDTH;
+ int bw = BOOL_WIDTH;
]])],
[gl_cv_header_limits_width=yes],
[gl_cv_header_limits_width=no])])
diff --git a/m4/malloc.m4 b/m4/malloc.m4
new file mode 100644
index 00000000000..972e808ab7e
--- /dev/null
+++ b/m4/malloc.m4
@@ -0,0 +1,174 @@
+# malloc.m4 serial 27
+dnl Copyright (C) 2007, 2009-2021 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.
+
+# This is adapted with modifications from upstream Autoconf here:
+# https://git.savannah.gnu.org/cgit/autoconf.git/tree/lib/autoconf/functions.m4?id=v2.70#n949
+AC_DEFUN([_AC_FUNC_MALLOC_IF],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
+ AC_CACHE_CHECK([whether malloc (0) returns nonnull],
+ [ac_cv_func_malloc_0_nonnull],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <stdlib.h>
+ ]],
+ [[void *p = malloc (0);
+ int result = !p;
+ free (p);
+ return result;]])
+ ],
+ [ac_cv_func_malloc_0_nonnull=yes],
+ [ac_cv_func_malloc_0_nonnull=no],
+ [case "$host_os" in
+ # Guess yes on platforms where we know the result.
+ *-gnu* | freebsd* | netbsd* | openbsd* | bitrig* \
+ | gnu* | *-musl* | midnightbsd* \
+ | hpux* | solaris* | cygwin* | mingw* | msys* )
+ ac_cv_func_malloc_0_nonnull="guessing yes" ;;
+ # If we don't know, obey --enable-cross-guesses.
+ *) ac_cv_func_malloc_0_nonnull="$gl_cross_guess_normal" ;;
+ esac
+ ])
+ ])
+ AS_CASE([$ac_cv_func_malloc_0_nonnull], [*yes], [$1], [$2])
+])# _AC_FUNC_MALLOC_IF
+
+# gl_FUNC_MALLOC_GNU
+# ------------------
+# Replace malloc if it is not compatible with GNU libc.
+AC_DEFUN([gl_FUNC_MALLOC_GNU],
+[
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_REQUIRE([gl_FUNC_MALLOC_POSIX])
+ if test $REPLACE_MALLOC = 0; then
+ _AC_FUNC_MALLOC_IF([], [REPLACE_MALLOC=1])
+ fi
+])
+
+# gl_FUNC_MALLOC_PTRDIFF
+# ----------------------
+# Test whether malloc (N) reliably fails when N exceeds PTRDIFF_MAX,
+# and replace malloc otherwise.
+AC_DEFUN([gl_FUNC_MALLOC_PTRDIFF],
+[
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_REQUIRE([gl_CHECK_MALLOC_PTRDIFF])
+ test "$gl_cv_malloc_ptrdiff" = yes || REPLACE_MALLOC=1
+])
+
+# Test whether malloc, realloc, calloc refuse to create objects
+# larger than what can be expressed in ptrdiff_t.
+# Set gl_cv_func_malloc_gnu to yes or no accordingly.
+AC_DEFUN([gl_CHECK_MALLOC_PTRDIFF],
+[
+ AC_CACHE_CHECK([whether malloc is ptrdiff_t safe],
+ [gl_cv_malloc_ptrdiff],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <stdint.h>
+ ]],
+ [[/* 64-bit ptrdiff_t is so wide that no practical platform
+ can exceed it. */
+ #define WIDE_PTRDIFF (PTRDIFF_MAX >> 31 >> 31 != 0)
+
+ /* On rare machines where size_t fits in ptrdiff_t there
+ is no problem. */
+ #define NARROW_SIZE (SIZE_MAX <= PTRDIFF_MAX)
+
+ /* glibc 2.30 and later malloc refuses to exceed ptrdiff_t
+ bounds even on 32-bit platforms. We don't know which
+ non-glibc systems are safe. */
+ #define KNOWN_SAFE (2 < __GLIBC__ + (30 <= __GLIBC_MINOR__))
+
+ #if WIDE_PTRDIFF || NARROW_SIZE || KNOWN_SAFE
+ return 0;
+ #else
+ #error "malloc might not be ptrdiff_t safe"
+ syntax error
+ #endif
+ ]])],
+ [gl_cv_malloc_ptrdiff=yes],
+ [gl_cv_malloc_ptrdiff=no])
+ ])
+])
+
+# gl_FUNC_MALLOC_POSIX
+# --------------------
+# Test whether 'malloc' is POSIX compliant (sets errno to ENOMEM when it
+# fails, and doesn't mess up with ptrdiff_t overflow), and replace
+# malloc if it is not.
+AC_DEFUN([gl_FUNC_MALLOC_POSIX],
+[
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_REQUIRE([gl_FUNC_MALLOC_PTRDIFF])
+ AC_REQUIRE([gl_CHECK_MALLOC_POSIX])
+ if test "$gl_cv_func_malloc_posix" = yes; then
+ AC_DEFINE([HAVE_MALLOC_POSIX], [1],
+ [Define if malloc, realloc, and calloc set errno on allocation failure.])
+ else
+ REPLACE_MALLOC=1
+ fi
+])
+
+# Test whether malloc, realloc, calloc set errno to ENOMEM on failure.
+# Set gl_cv_func_malloc_posix to yes or no accordingly.
+AC_DEFUN([gl_CHECK_MALLOC_POSIX],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_CACHE_CHECK([whether malloc, realloc, calloc set errno on failure],
+ [gl_cv_func_malloc_posix],
+ [
+ dnl It is too dangerous to try to allocate a large amount of memory:
+ dnl some systems go to their knees when you do that. So assume that
+ dnl all Unix implementations of the function set errno on failure,
+ dnl except on those platforms where we have seen 'test-malloc-gnu',
+ dnl 'test-realloc-gnu', 'test-calloc-gnu' fail.
+ case "$host_os" in
+ mingw*)
+ gl_cv_func_malloc_posix=no ;;
+ irix* | solaris*)
+ dnl On IRIX 6.5, the three functions return NULL with errno unset
+ dnl when the argument is larger than PTRDIFF_MAX.
+ dnl On Solaris 11.3, the three functions return NULL with errno set
+ dnl to EAGAIN, not ENOMEM, when the argument is larger than
+ dnl PTRDIFF_MAX.
+ dnl Here is a test program:
+m4_divert_push([KILL])
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#define ptrdiff_t long
+#ifndef PTRDIFF_MAX
+# define PTRDIFF_MAX ((ptrdiff_t) ((1UL << (8 * sizeof (ptrdiff_t) - 1)) - 1))
+#endif
+
+int main ()
+{
+ void *p;
+
+ fprintf (stderr, "PTRDIFF_MAX = %lu\n", (unsigned long) PTRDIFF_MAX);
+
+ errno = 0;
+ p = malloc ((unsigned long) PTRDIFF_MAX + 1);
+ fprintf (stderr, "p=%p errno=%d\n", p, errno);
+
+ errno = 0;
+ p = calloc (PTRDIFF_MAX / 2 + 1, 2);
+ fprintf (stderr, "p=%p errno=%d\n", p, errno);
+
+ errno = 0;
+ p = realloc (NULL, (unsigned long) PTRDIFF_MAX + 1);
+ fprintf (stderr, "p=%p errno=%d\n", p, errno);
+
+ return 0;
+}
+m4_divert_pop([KILL])
+ gl_cv_func_malloc_posix=no ;;
+ *)
+ gl_cv_func_malloc_posix=yes ;;
+ esac
+ ])
+])
diff --git a/m4/malloca.m4 b/m4/malloca.m4
deleted file mode 100644
index 7ee33773d25..00000000000
--- a/m4/malloca.m4
+++ /dev/null
@@ -1,14 +0,0 @@
-# malloca.m4 serial 2
-dnl Copyright (C) 2003-2004, 2006-2007, 2009-2021 Free Software
-dnl 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_MALLOCA],
-[
- dnl Use the autoconf tests for alloca(), but not the AC_SUBSTed variables
- dnl @ALLOCA@ and @LTALLOCA@.
- dnl gl_FUNC_ALLOCA dnl Already brought in by the module dependencies.
- AC_REQUIRE([gl_EEMALLOC])
-])
diff --git a/m4/manywarnings.m4 b/m4/manywarnings.m4
index 53ab1534036..872ea58e62a 100644
--- a/m4/manywarnings.m4
+++ b/m4/manywarnings.m4
@@ -1,4 +1,4 @@
-# manywarnings.m4 serial 21
+# manywarnings.m4 serial 23
dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -195,15 +195,9 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC(C)],
gl_AS_VAR_APPEND([$1], [' -Wno-uninitialized'])
fi
- # Some warnings have too many false alarms in GCC 10.1.
- # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93695
- gl_AS_VAR_APPEND([$1], [' -Wno-analyzer-double-free'])
- # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94458
+ # This warning have too many false alarms in GCC 11.2.1.
+ # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101713
gl_AS_VAR_APPEND([$1], [' -Wno-analyzer-malloc-leak'])
- # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94851
- gl_AS_VAR_APPEND([$1], [' -Wno-analyzer-null-dereference'])
- # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95758
- gl_AS_VAR_APPEND([$1], [' -Wno-analyzer-use-after-free'])
AC_LANG_POP([C])
])
diff --git a/m4/memmem.m4 b/m4/memmem.m4
index e2a785f48d4..6dac7661283 100644
--- a/m4/memmem.m4
+++ b/m4/memmem.m4
@@ -1,4 +1,4 @@
-# memmem.m4 serial 27
+# memmem.m4 serial 29
dnl Copyright (C) 2002-2004, 2007-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -10,7 +10,7 @@ AC_DEFUN([gl_FUNC_MEMMEM_SIMPLE],
dnl Persuade glibc <string.h> to declare memmem().
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
- AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+ AC_REQUIRE([gl_STRING_H_DEFAULTS])
AC_CHECK_FUNCS([memmem])
if test $ac_cv_func_memmem = yes; then
HAVE_MEMMEM=1
@@ -50,6 +50,7 @@ AC_DEFUN([gl_FUNC_MEMMEM_SIMPLE],
dnl Assume that it works on all other platforms (even if not linear).
AC_EGREP_CPP([Lucky user],
[
+#include <string.h> /* for __GNU_LIBRARY__ */
#ifdef __GNU_LIBRARY__
#include <features.h>
#if ((__GLIBC__ == 2 && ((__GLIBC_MINOR > 0 && __GLIBC_MINOR__ < 9) \
diff --git a/m4/mempcpy.m4 b/m4/mempcpy.m4
index c5ee2af8ccd..f9d9ec8f308 100644
--- a/m4/mempcpy.m4
+++ b/m4/mempcpy.m4
@@ -1,4 +1,4 @@
-# mempcpy.m4 serial 11
+# mempcpy.m4 serial 12
dnl Copyright (C) 2003-2004, 2006-2007, 2009-2021 Free Software Foundation,
dnl Inc.
dnl This file is free software; the Free Software Foundation
@@ -13,7 +13,7 @@ AC_DEFUN([gl_FUNC_MEMPCPY],
dnl The mempcpy() declaration in lib/string.in.h uses 'restrict'.
AC_REQUIRE([AC_C_RESTRICT])
- AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+ AC_REQUIRE([gl_STRING_H_DEFAULTS])
AC_CHECK_FUNCS([mempcpy])
if test $ac_cv_func_mempcpy = no; then
HAVE_MEMPCPY=0
diff --git a/m4/memrchr.m4 b/m4/memrchr.m4
index d0c05896e54..40f61c5ac0a 100644
--- a/m4/memrchr.m4
+++ b/m4/memrchr.m4
@@ -1,4 +1,4 @@
-# memrchr.m4 serial 10
+# memrchr.m4 serial 11
dnl Copyright (C) 2002-2003, 2005-2007, 2009-2021 Free Software Foundation,
dnl Inc.
dnl This file is free software; the Free Software Foundation
@@ -10,7 +10,7 @@ AC_DEFUN([gl_FUNC_MEMRCHR],
dnl Persuade glibc <string.h> to declare memrchr().
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
- AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+ AC_REQUIRE([gl_STRING_H_DEFAULTS])
AC_CHECK_DECLS_ONCE([memrchr])
if test $ac_cv_have_decl_memrchr = no; then
HAVE_DECL_MEMRCHR=0
diff --git a/m4/mktime.m4 b/m4/mktime.m4
index 245649e774a..721189af56e 100644
--- a/m4/mktime.m4
+++ b/m4/mktime.m4
@@ -1,4 +1,4 @@
-# serial 35
+# serial 36
dnl Copyright (C) 2002-2003, 2005-2007, 2009-2021 Free Software Foundation,
dnl Inc.
dnl This file is free software; the Free Software Foundation
@@ -255,7 +255,7 @@ main ()
dnl Main macro of module 'mktime'.
AC_DEFUN([gl_FUNC_MKTIME],
[
- AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS])
+ AC_REQUIRE([gl_TIME_H_DEFAULTS])
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([gl_FUNC_MKTIME_WORKS])
diff --git a/m4/nproc.m4 b/m4/nproc.m4
new file mode 100644
index 00000000000..887c66bee81
--- /dev/null
+++ b/m4/nproc.m4
@@ -0,0 +1,54 @@
+# nproc.m4 serial 5
+dnl Copyright (C) 2009-2021 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_NPROC],
+[
+ gl_PREREQ_NPROC
+])
+
+# Prerequisites of lib/nproc.c.
+AC_DEFUN([gl_PREREQ_NPROC],
+[
+ dnl Persuade glibc <sched.h> to declare CPU_SETSIZE, CPU_ISSET etc.
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+ AC_CHECK_HEADERS([sys/pstat.h sys/sysmp.h sys/param.h],,,
+ [AC_INCLUDES_DEFAULT])
+ dnl <sys/sysctl.h> requires <sys/param.h> on OpenBSD 4.0.
+ AC_CHECK_HEADERS([sys/sysctl.h],,,
+ [AC_INCLUDES_DEFAULT
+ #if HAVE_SYS_PARAM_H
+ # include <sys/param.h>
+ #endif
+ ])
+
+ AC_CHECK_FUNCS([sched_getaffinity sched_getaffinity_np \
+ pstat_getdynamic sysmp sysctl])
+
+ dnl Test whether sched_getaffinity has the expected declaration.
+ dnl glibc 2.3.[0-2]:
+ dnl int sched_getaffinity (pid_t, unsigned int, unsigned long int *);
+ dnl glibc 2.3.3:
+ dnl int sched_getaffinity (pid_t, cpu_set_t *);
+ dnl glibc >= 2.3.4:
+ dnl int sched_getaffinity (pid_t, size_t, cpu_set_t *);
+ if test $ac_cv_func_sched_getaffinity = yes; then
+ AC_CACHE_CHECK([for glibc compatible sched_getaffinity],
+ [gl_cv_func_sched_getaffinity3],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <errno.h>
+ #include <sched.h>]],
+ [[sched_getaffinity (0, 0, (cpu_set_t *) 0);]])],
+ [gl_cv_func_sched_getaffinity3=yes],
+ [gl_cv_func_sched_getaffinity3=no])
+ ])
+ if test $gl_cv_func_sched_getaffinity3 = yes; then
+ AC_DEFINE([HAVE_SCHED_GETAFFINITY_LIKE_GLIBC], [1],
+ [Define to 1 if sched_getaffinity has a glibc compatible declaration.])
+ fi
+ fi
+])
diff --git a/m4/pselect.m4 b/m4/pselect.m4
index 538fe7dc122..9de63baf990 100644
--- a/m4/pselect.m4
+++ b/m4/pselect.m4
@@ -1,4 +1,4 @@
-# pselect.m4 serial 9
+# pselect.m4 serial 10
dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -6,7 +6,7 @@ dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_PSELECT],
[
- AC_REQUIRE([gl_HEADER_SYS_SELECT])
+ AC_REQUIRE([gl_SYS_SELECT_H])
AC_REQUIRE([AC_C_RESTRICT])
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
AC_CHECK_FUNCS_ONCE([pselect])
diff --git a/m4/pthread_sigmask.m4 b/m4/pthread_sigmask.m4
index eb4c7849655..ff7fa9610e2 100644
--- a/m4/pthread_sigmask.m4
+++ b/m4/pthread_sigmask.m4
@@ -1,4 +1,4 @@
-# pthread_sigmask.m4 serial 19
+# pthread_sigmask.m4 serial 21
dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -111,9 +111,9 @@ AC_DEFUN([gl_FUNC_PTHREAD_SIGMASK],
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
- dnl On FreeBSD 6.4, HP-UX 11.31, Solaris 9, in programs that are not linked
- dnl with -lpthread, the pthread_sigmask() function always returns 0 and has
- dnl no effect.
+ dnl On FreeBSD 13.0, MidnightBSD 1.1, HP-UX 11.31, Solaris 9, in programs
+ dnl that are not linked with -lpthread, the pthread_sigmask() function
+ dnl always returns 0 and has no effect.
if test -z "$LIB_PTHREAD_SIGMASK"; then
case " $LIBS " in
*' -pthread '*) ;;
@@ -138,7 +138,7 @@ AC_DEFUN([gl_FUNC_PTHREAD_SIGMASK],
[
changequote(,)dnl
case "$host_os" in
- freebsd* | hpux* | solaris | solaris2.[2-9]*)
+ freebsd* | midnightbsd* | hpux* | solaris | solaris2.[2-9]*)
gl_cv_func_pthread_sigmask_in_libc_works="guessing no";;
*)
gl_cv_func_pthread_sigmask_in_libc_works="guessing yes";;
diff --git a/m4/rawmemchr.m4 b/m4/rawmemchr.m4
index f92846543cc..452fab18f13 100644
--- a/m4/rawmemchr.m4
+++ b/m4/rawmemchr.m4
@@ -1,4 +1,4 @@
-# rawmemchr.m4 serial 2
+# rawmemchr.m4 serial 3
dnl Copyright (C) 2003, 2007-2021 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,7 @@ AC_DEFUN([gl_FUNC_RAWMEMCHR],
dnl Persuade glibc <string.h> to declare rawmemchr().
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
- AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+ AC_REQUIRE([gl_STRING_H_DEFAULTS])
AC_CHECK_FUNCS([rawmemchr])
if test $ac_cv_func_rawmemchr = no; then
HAVE_RAWMEMCHR=0
diff --git a/m4/realloc.m4 b/m4/realloc.m4
new file mode 100644
index 00000000000..0abc4185ed0
--- /dev/null
+++ b/m4/realloc.m4
@@ -0,0 +1,63 @@
+# realloc.m4 serial 24
+dnl Copyright (C) 2007, 2009-2021 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.
+
+# This is adapted with modifications from upstream Autoconf here:
+# https://git.savannah.gnu.org/cgit/autoconf.git/tree/lib/autoconf/functions.m4?id=v2.70#n1455
+AC_DEFUN([_AC_FUNC_REALLOC_IF],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
+ AC_CACHE_CHECK([whether realloc (0, 0) returns nonnull],
+ [ac_cv_func_realloc_0_nonnull],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <stdlib.h>
+ ]],
+ [[void *p = realloc (0, 0);
+ int result = !p;
+ free (p);
+ return result;]])
+ ],
+ [ac_cv_func_realloc_0_nonnull=yes],
+ [ac_cv_func_realloc_0_nonnull=no],
+ [case "$host_os" in
+ # Guess yes on platforms where we know the result.
+ *-gnu* | freebsd* | netbsd* | openbsd* | bitrig* \
+ | gnu* | *-musl* | midnightbsd* \
+ | hpux* | solaris* | cygwin* | mingw* | msys* )
+ ac_cv_func_realloc_0_nonnull="guessing yes" ;;
+ # If we don't know, obey --enable-cross-guesses.
+ *) ac_cv_func_realloc_0_nonnull="$gl_cross_guess_normal" ;;
+ esac
+ ])
+ ])
+ AS_CASE([$ac_cv_func_realloc_0_nonnull], [*yes], [$1], [$2])
+])# AC_FUNC_REALLOC
+
+# gl_FUNC_REALLOC_GNU
+# -------------------
+# Replace realloc if it is not compatible with GNU libc.
+AC_DEFUN([gl_FUNC_REALLOC_GNU],
+[
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_REQUIRE([gl_FUNC_REALLOC_POSIX])
+ if test $REPLACE_REALLOC = 0; then
+ _AC_FUNC_REALLOC_IF([], [REPLACE_REALLOC=1])
+ fi
+])# gl_FUNC_REALLOC_GNU
+
+# gl_FUNC_REALLOC_POSIX
+# ---------------------
+# Test whether 'realloc' is POSIX compliant (sets errno to ENOMEM when it
+# fails, and doesn't mess up with ptrdiff_t overflow),
+# and replace realloc if it is not.
+AC_DEFUN([gl_FUNC_REALLOC_POSIX],
+[
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_REQUIRE([gl_FUNC_MALLOC_POSIX])
+ if test $REPLACE_MALLOC = 1; then
+ REPLACE_REALLOC=1
+ fi
+])
diff --git a/m4/regex.m4 b/m4/regex.m4
index 850c572228a..1c7e562f6c6 100644
--- a/m4/regex.m4
+++ b/m4/regex.m4
@@ -1,4 +1,4 @@
-# serial 71
+# serial 73
# Copyright (C) 1996-2001, 2003-2021 Free Software Foundation, Inc.
#
@@ -246,7 +246,7 @@ AC_DEFUN([gl_REGEX],
& ~RE_CONTEXT_INVALID_DUP
& ~RE_NO_EMPTY_RANGES);
memset (&regex, 0, sizeof regex);
- s = re_compile_pattern ("[[:alnum:]_-]\\\\+$", 16, &regex);
+ s = re_compile_pattern ("[[:alnum:]_-]\\\\+\$", 16, &regex);
if (s)
result |= 32;
else
@@ -264,14 +264,50 @@ AC_DEFUN([gl_REGEX],
back reference. */
re_set_syntax (RE_SYNTAX_POSIX_EGREP);
memset (&regex, 0, sizeof regex);
- s = re_compile_pattern ("0|()0|\\1|0", 10, &regex);
+ s = re_compile_pattern ("0|()0|\\\\1|0", 10, &regex);
if (!s)
- result |= 64;
+ {
+ memset (&regs, 0, sizeof regs);
+ i = re_search (&regex, "x", 1, 0, 1, &regs);
+ if (i != -1)
+ result |= 64;
+ if (0 <= i)
+ {
+ free (regs.start);
+ free (regs.end);
+ }
+ regfree (&regex);
+ }
else
{
if (strcmp (s, "Invalid back reference"))
result |= 64;
+ }
+
+ /* glibc bug 11053. */
+ re_set_syntax (RE_SYNTAX_POSIX_BASIC);
+ memset (&regex, 0, sizeof regex);
+ static char const pat_sub2[] = "\\\\(a*\\\\)*a*\\\\1";
+ s = re_compile_pattern (pat_sub2, sizeof pat_sub2 - 1, &regex);
+ if (s)
+ result |= 64;
+ else
+ {
+ memset (&regs, 0, sizeof regs);
+ static char const data[] = "a";
+ int datalen = sizeof data - 1;
+ i = re_search (&regex, data, datalen, 0, datalen, &regs);
+ if (i != 0)
+ result |= 64;
+ else if (regs.num_regs < 2)
+ result |= 64;
+ else if (! (regs.start[0] == 0 && regs.end[0] == 1))
+ result |= 64;
+ else if (! (regs.start[1] == 0 && regs.end[1] == 0))
+ result |= 64;
regfree (&regex);
+ free (regs.start);
+ free (regs.end);
}
#if 0
diff --git a/m4/sigdescr_np.m4 b/m4/sigdescr_np.m4
index f6fa63140c4..17c22506cca 100644
--- a/m4/sigdescr_np.m4
+++ b/m4/sigdescr_np.m4
@@ -1,4 +1,4 @@
-# sigdescr_np.m4 serial 1
+# sigdescr_np.m4 serial 2
dnl Copyright (C) 2020-2021 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,7 @@ AC_DEFUN([gl_FUNC_SIGDESCR_NP],
dnl Persuade glibc <string.h> to declare sigdescr_np().
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
- AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+ AC_REQUIRE([gl_STRING_H_DEFAULTS])
AC_CHECK_FUNCS([sigdescr_np])
if test $ac_cv_func_sigdescr_np = no; then
HAVE_SIGDESCR_NP=0
diff --git a/m4/signal_h.m4 b/m4/signal_h.m4
index ff9f0251fd9..8b938809b7c 100644
--- a/m4/signal_h.m4
+++ b/m4/signal_h.m4
@@ -1,10 +1,10 @@
-# signal_h.m4 serial 19
+# signal_h.m4 serial 22
dnl Copyright (C) 2007-2021 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_SIGNAL_H],
+AC_DEFUN_ONCE([gl_SIGNAL_H],
[
AC_REQUIRE([gl_SIGNAL_H_DEFAULTS])
AC_REQUIRE([gl_CHECK_TYPE_SIGSET_T])
@@ -52,22 +52,37 @@ AC_DEFUN([gl_CHECK_TYPE_SIGSET_T],
fi
])
+# gl_SIGNAL_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_SIGNAL_MODULE_INDICATOR],
[
- dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
- AC_REQUIRE([gl_SIGNAL_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only.
+ gl_SIGNAL_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_SIGNAL_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_SIGNAL_H_MODULE_INDICATOR_DEFAULTS], [
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PTHREAD_SIGMASK])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RAISE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGNAL_H_SIGPIPE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGPROCMASK])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGACTION])
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_SIGNAL_H_MODULE_INDICATOR_DEFAULTS])
+ AC_REQUIRE([gl_SIGNAL_H_DEFAULTS])
+])
+
AC_DEFUN([gl_SIGNAL_H_DEFAULTS],
[
- GNULIB_PTHREAD_SIGMASK=0; AC_SUBST([GNULIB_PTHREAD_SIGMASK])
- GNULIB_RAISE=0; AC_SUBST([GNULIB_RAISE])
- GNULIB_SIGNAL_H_SIGPIPE=0; AC_SUBST([GNULIB_SIGNAL_H_SIGPIPE])
- GNULIB_SIGPROCMASK=0; AC_SUBST([GNULIB_SIGPROCMASK])
- GNULIB_SIGACTION=0; AC_SUBST([GNULIB_SIGACTION])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_POSIX_SIGNALBLOCKING=1; AC_SUBST([HAVE_POSIX_SIGNALBLOCKING])
HAVE_PTHREAD_SIGMASK=1; AC_SUBST([HAVE_PTHREAD_SIGMASK])
diff --git a/m4/stdalign.m4 b/m4/stdalign.m4
index 8dcb634d55b..e22d7f78c06 100644
--- a/m4/stdalign.m4
+++ b/m4/stdalign.m4
@@ -13,7 +13,8 @@ AC_DEFUN([gl_STDALIGN_H],
[gl_cv_header_working_stdalign_h],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
- [[#include <stdalign.h>
+ [[#include <stdint.h>
+ #include <stdalign.h>
#include <stddef.h>
/* Test that alignof yields a result consistent with offsetof.
@@ -32,6 +33,7 @@ AC_DEFUN([gl_STDALIGN_H],
/* Test _Alignas only on platforms where gnulib can help. */
#if \
((defined __cplusplus && 201103 <= __cplusplus) \
+ || (__TINYC__ && defined __attribute__) \
|| (defined __APPLE__ && defined __MACH__ \
? 4 < __GNUC__ + (1 <= __GNUC_MINOR__) \
: __GNUC__) \
diff --git a/m4/stddef_h.m4 b/m4/stddef_h.m4
index cd666c4a58c..1303d2e06c7 100644
--- a/m4/stddef_h.m4
+++ b/m4/stddef_h.m4
@@ -1,4 +1,4 @@
-# stddef_h.m4 serial 9
+# stddef_h.m4 serial 11
dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -6,7 +6,7 @@ dnl with or without modifications, as long as this notice is preserved.
dnl A placeholder for <stddef.h>, for platforms that have issues.
-AC_DEFUN([gl_STDDEF_H],
+AC_DEFUN_ONCE([gl_STDDEF_H],
[
AC_REQUIRE([gl_STDDEF_H_DEFAULTS])
AC_REQUIRE([gt_TYPE_WCHAR_T])
@@ -68,13 +68,28 @@ AC_DEFUN([gl_STDDEF_H],
fi
])
+# gl_STDDEF_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_STDDEF_MODULE_INDICATOR],
[
- dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
- AC_REQUIRE([gl_STDDEF_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only.
+ gl_STDDEF_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
])
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_STDDEF_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_STDDEF_H_MODULE_INDICATOR_DEFAULTS], [
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_STDDEF_H_MODULE_INDICATOR_DEFAULTS])
+ AC_REQUIRE([gl_STDDEF_H_DEFAULTS])
+])
+
AC_DEFUN([gl_STDDEF_H_DEFAULTS],
[
dnl Assume proper GNU behavior unless another module says otherwise.
diff --git a/m4/stdint.m4 b/m4/stdint.m4
index a785b44ed17..2eb1652d8e2 100644
--- a/m4/stdint.m4
+++ b/m4/stdint.m4
@@ -1,4 +1,4 @@
-# stdint.m4 serial 58
+# stdint.m4 serial 60
dnl Copyright (C) 2001-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -170,7 +170,7 @@ struct s {
PTRDIFF_MIN == TYPE_MINIMUM (ptrdiff_t)
&& PTRDIFF_MAX == TYPE_MAXIMUM (ptrdiff_t)
? 1 : -1;
- /* Detect bug in FreeBSD 6.0 / ia64. */
+ /* Detect bug in FreeBSD 6.0/ia64 and FreeBSD 13.0/arm64. */
int check_SIG_ATOMIC:
SIG_ATOMIC_MIN == TYPE_MINIMUM (sig_atomic_t)
&& SIG_ATOMIC_MAX == TYPE_MAXIMUM (sig_atomic_t)
@@ -527,7 +527,7 @@ AC_DEFUN([gl_STDINT_TYPE_PROPERTIES],
dnl requirement that wint_t is "unchanged by default argument promotions".
dnl In this case gnulib's <wchar.h> and <wctype.h> override wint_t.
dnl Set the variable BITSIZEOF_WINT_T accordingly.
- if test $GNULIB_OVERRIDES_WINT_T = 1; then
+ if test $GNULIBHEADERS_OVERRIDE_WINT_T = 1; then
BITSIZEOF_WINT_T=32
fi
])
diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4
index 4c3f24accaa..e704383862d 100644
--- a/m4/stdio_h.m4
+++ b/m4/stdio_h.m4
@@ -1,11 +1,12 @@
-# stdio_h.m4 serial 52
+# stdio_h.m4 serial 56
dnl Copyright (C) 2007-2021 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_STDIO_H],
+AC_DEFUN_ONCE([gl_STDIO_H],
[
+ AC_REQUIRE([gl_STDIO_H_DEFAULTS])
AH_VERBATIM([MINGW_ANSI_STDIO],
[/* Use GNU style printf and scanf. */
#ifndef __USE_MINGW_ANSI_STDIO
@@ -13,7 +14,6 @@ AC_DEFUN([gl_STDIO_H],
#endif
])
AC_DEFINE([__USE_MINGW_ANSI_STDIO])
- AC_REQUIRE([gl_STDIO_H_DEFAULTS])
gl_NEXT_HEADERS([stdio.h])
dnl Determine whether __USE_MINGW_ANSI_STDIO makes printf and
@@ -40,17 +40,6 @@ AC_DEFUN([gl_STDIO_H],
attribute "__gnu_printf__" instead of "__printf__"])
fi
- dnl No need to create extra modules for these functions. Everyone who uses
- dnl <stdio.h> likely needs them.
- GNULIB_FSCANF=1
- gl_MODULE_INDICATOR([fscanf])
- GNULIB_SCANF=1
- gl_MODULE_INDICATOR([scanf])
- GNULIB_FGETC=1
- GNULIB_GETC=1
- GNULIB_GETCHAR=1
- GNULIB_FGETS=1
- GNULIB_FREAD=1
dnl This ifdef is necessary to avoid an error "missing file lib/stdio-read.c"
dnl "expected source file, required through AC_LIBSOURCES, not found". It is
dnl also an optimization, to avoid performing a configure check whose result
@@ -64,18 +53,6 @@ AC_DEFUN([gl_STDIO_H],
fi
])
- dnl No need to create extra modules for these functions. Everyone who uses
- dnl <stdio.h> likely needs them.
- GNULIB_FPRINTF=1
- GNULIB_PRINTF=1
- GNULIB_VFPRINTF=1
- GNULIB_VPRINTF=1
- GNULIB_FPUTC=1
- GNULIB_PUTC=1
- GNULIB_PUTCHAR=1
- GNULIB_FPUTS=1
- GNULIB_PUTS=1
- GNULIB_FWRITE=1
dnl This ifdef is necessary to avoid an error "missing file lib/stdio-write.c"
dnl "expected source file, required through AC_LIBSOURCES, not found". It is
dnl also an optimization, to avoid performing a configure check whose result
@@ -116,77 +93,92 @@ AC_DEFUN([gl_STDIO_H],
fi
])
+# gl_STDIO_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_STDIO_MODULE_INDICATOR],
[
- dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
- AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only.
+ gl_STDIO_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_STDIO_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_STDIO_H_MODULE_INDICATOR_DEFAULTS], [
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DPRINTF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCLOSE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FDOPEN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FFLUSH])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FGETC])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FGETS])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FOPEN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FPRINTF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FPRINTF_POSIX])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FPURGE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FPUTC])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FPUTS])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREAD])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREOPEN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSCANF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSEEK])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSEEKO])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FTELL])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FTELLO])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FWRITE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETC])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETCHAR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETDELIM])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLINE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OBSTACK_PRINTF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OBSTACK_PRINTF_POSIX])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PCLOSE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PERROR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POPEN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PRINTF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PRINTF_POSIX])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PUTC])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PUTCHAR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PUTS])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REMOVE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RENAME])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RENAMEAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SCANF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SNPRINTF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SPRINTF_POSIX])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDIO_H_NONBLOCKING])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDIO_H_SIGPIPE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TMPFILE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VASPRINTF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFSCANF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSCANF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VDPRINTF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFPRINTF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFPRINTF_POSIX])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VPRINTF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VPRINTF_POSIX])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSNPRINTF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSPRINTF_POSIX])
+ dnl Support Microsoft deprecated alias function names by default.
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FCLOSEALL], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FDOPEN], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FILENO], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_GETW], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_PUTW], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_TEMPNAM], [1])
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_STDIO_H_MODULE_INDICATOR_DEFAULTS])
+ AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+])
+
AC_DEFUN([gl_STDIO_H_DEFAULTS],
[
- GNULIB_DPRINTF=0; AC_SUBST([GNULIB_DPRINTF])
- GNULIB_FCLOSE=0; AC_SUBST([GNULIB_FCLOSE])
- GNULIB_FDOPEN=0; AC_SUBST([GNULIB_FDOPEN])
- GNULIB_FFLUSH=0; AC_SUBST([GNULIB_FFLUSH])
- GNULIB_FGETC=0; AC_SUBST([GNULIB_FGETC])
- GNULIB_FGETS=0; AC_SUBST([GNULIB_FGETS])
- GNULIB_FOPEN=0; AC_SUBST([GNULIB_FOPEN])
- GNULIB_FPRINTF=0; AC_SUBST([GNULIB_FPRINTF])
- GNULIB_FPRINTF_POSIX=0; AC_SUBST([GNULIB_FPRINTF_POSIX])
- GNULIB_FPURGE=0; AC_SUBST([GNULIB_FPURGE])
- GNULIB_FPUTC=0; AC_SUBST([GNULIB_FPUTC])
- GNULIB_FPUTS=0; AC_SUBST([GNULIB_FPUTS])
- GNULIB_FREAD=0; AC_SUBST([GNULIB_FREAD])
- GNULIB_FREOPEN=0; AC_SUBST([GNULIB_FREOPEN])
- GNULIB_FSCANF=0; AC_SUBST([GNULIB_FSCANF])
- GNULIB_FSEEK=0; AC_SUBST([GNULIB_FSEEK])
- GNULIB_FSEEKO=0; AC_SUBST([GNULIB_FSEEKO])
- GNULIB_FTELL=0; AC_SUBST([GNULIB_FTELL])
- GNULIB_FTELLO=0; AC_SUBST([GNULIB_FTELLO])
- GNULIB_FWRITE=0; AC_SUBST([GNULIB_FWRITE])
- GNULIB_GETC=0; AC_SUBST([GNULIB_GETC])
- GNULIB_GETCHAR=0; AC_SUBST([GNULIB_GETCHAR])
- GNULIB_GETDELIM=0; AC_SUBST([GNULIB_GETDELIM])
- GNULIB_GETLINE=0; AC_SUBST([GNULIB_GETLINE])
- GNULIB_OBSTACK_PRINTF=0; AC_SUBST([GNULIB_OBSTACK_PRINTF])
- GNULIB_OBSTACK_PRINTF_POSIX=0; AC_SUBST([GNULIB_OBSTACK_PRINTF_POSIX])
- GNULIB_PCLOSE=0; AC_SUBST([GNULIB_PCLOSE])
- GNULIB_PERROR=0; AC_SUBST([GNULIB_PERROR])
- GNULIB_POPEN=0; AC_SUBST([GNULIB_POPEN])
- GNULIB_PRINTF=0; AC_SUBST([GNULIB_PRINTF])
- GNULIB_PRINTF_POSIX=0; AC_SUBST([GNULIB_PRINTF_POSIX])
- GNULIB_PUTC=0; AC_SUBST([GNULIB_PUTC])
- GNULIB_PUTCHAR=0; AC_SUBST([GNULIB_PUTCHAR])
- GNULIB_PUTS=0; AC_SUBST([GNULIB_PUTS])
- GNULIB_REMOVE=0; AC_SUBST([GNULIB_REMOVE])
- GNULIB_RENAME=0; AC_SUBST([GNULIB_RENAME])
- GNULIB_RENAMEAT=0; AC_SUBST([GNULIB_RENAMEAT])
- GNULIB_SCANF=0; AC_SUBST([GNULIB_SCANF])
- GNULIB_SNPRINTF=0; AC_SUBST([GNULIB_SNPRINTF])
- GNULIB_SPRINTF_POSIX=0; AC_SUBST([GNULIB_SPRINTF_POSIX])
- GNULIB_STDIO_H_NONBLOCKING=0; AC_SUBST([GNULIB_STDIO_H_NONBLOCKING])
- GNULIB_STDIO_H_SIGPIPE=0; AC_SUBST([GNULIB_STDIO_H_SIGPIPE])
- GNULIB_TMPFILE=0; AC_SUBST([GNULIB_TMPFILE])
- GNULIB_VASPRINTF=0; AC_SUBST([GNULIB_VASPRINTF])
- GNULIB_VFSCANF=0; AC_SUBST([GNULIB_VFSCANF])
- GNULIB_VSCANF=0; AC_SUBST([GNULIB_VSCANF])
- GNULIB_VDPRINTF=0; AC_SUBST([GNULIB_VDPRINTF])
- GNULIB_VFPRINTF=0; AC_SUBST([GNULIB_VFPRINTF])
- GNULIB_VFPRINTF_POSIX=0; AC_SUBST([GNULIB_VFPRINTF_POSIX])
- GNULIB_VPRINTF=0; AC_SUBST([GNULIB_VPRINTF])
- GNULIB_VPRINTF_POSIX=0; AC_SUBST([GNULIB_VPRINTF_POSIX])
- GNULIB_VSNPRINTF=0; AC_SUBST([GNULIB_VSNPRINTF])
- GNULIB_VSPRINTF_POSIX=0; AC_SUBST([GNULIB_VSPRINTF_POSIX])
- dnl Support Microsoft deprecated alias function names by default.
- GNULIB_MDA_FCLOSEALL=1; AC_SUBST([GNULIB_MDA_FCLOSEALL])
- GNULIB_MDA_FDOPEN=1; AC_SUBST([GNULIB_MDA_FDOPEN])
- GNULIB_MDA_FILENO=1; AC_SUBST([GNULIB_MDA_FILENO])
- GNULIB_MDA_GETW=1; AC_SUBST([GNULIB_MDA_GETW])
- GNULIB_MDA_PUTW=1; AC_SUBST([GNULIB_MDA_PUTW])
- GNULIB_MDA_TEMPNAM=1; AC_SUBST([GNULIB_MDA_TEMPNAM])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_DECL_FCLOSEALL=1; AC_SUBST([HAVE_DECL_FCLOSEALL])
HAVE_DECL_FPURGE=1; AC_SUBST([HAVE_DECL_FPURGE])
diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4
index 5a02972e05d..9c1d1c76c13 100644
--- a/m4/stdlib_h.m4
+++ b/m4/stdlib_h.m4
@@ -1,10 +1,10 @@
-# stdlib_h.m4 serial 55
+# stdlib_h.m4 serial 63
dnl Copyright (C) 2007-2021 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_STDLIB_H],
+AC_DEFUN_ONCE([gl_STDLIB_H],
[
AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
gl_NEXT_HEADERS([stdlib.h])
@@ -28,7 +28,7 @@ AC_DEFUN([gl_STDLIB_H],
posix_memalign posix_openpt ptsname ptsname_r qsort_r
random random_r reallocarray realpath rpmatch secure_getenv setenv
setstate setstate_r srandom srandom_r
- strtod strtold strtoll strtoull unlockpt unsetenv])
+ strtod strtol strtold strtoll strtoul strtoull unlockpt unsetenv])
AC_REQUIRE([AC_C_RESTRICT])
@@ -46,61 +46,78 @@ AC_DEFUN([gl_STDLIB_H],
fi
])
+# gl_STDLIB_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_STDLIB_MODULE_INDICATOR],
[
- dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
- AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only.
+ gl_STDLIB_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_STDLIB_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_STDLIB_H_MODULE_INDICATOR_DEFAULTS], [
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB__EXIT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ALIGNED_ALLOC])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ATOLL])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CALLOC_POSIX])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CANONICALIZE_FILE_NAME])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREE_POSIX])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLOADAVG])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETSUBOPT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GRANTPT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MALLOC_POSIX])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBTOWC])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKDTEMP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKOSTEMP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKOSTEMPS])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKSTEMP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKSTEMPS])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_MEMALIGN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_OPENPT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PTSNAME])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PTSNAME_R])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PUTENV])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_QSORT_R])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RANDOM])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RANDOM_R])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALLOCARRAY])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALLOC_POSIX])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALPATH])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RPMATCH])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SECURE_GETENV])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETENV])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOD])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOL])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOLD])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOLL])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOUL])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOULL])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SYSTEM_POSIX])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNLOCKPT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNSETENV])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCTOMB])
+ dnl Support Microsoft deprecated alias function names by default.
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_ECVT], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FCVT], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_GCVT], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_MKTEMP], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_PUTENV], [1])
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_STDLIB_H_MODULE_INDICATOR_DEFAULTS])
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+])
+
AC_DEFUN([gl_STDLIB_H_DEFAULTS],
[
- GNULIB__EXIT=0; AC_SUBST([GNULIB__EXIT])
- GNULIB_ALIGNED_ALLOC=0; AC_SUBST([GNULIB_ALIGNED_ALLOC])
- GNULIB_ATOLL=0; AC_SUBST([GNULIB_ATOLL])
- GNULIB_CALLOC_POSIX=0; AC_SUBST([GNULIB_CALLOC_POSIX])
- GNULIB_CANONICALIZE_FILE_NAME=0; AC_SUBST([GNULIB_CANONICALIZE_FILE_NAME])
- GNULIB_FREE_POSIX=0; AC_SUBST([GNULIB_FREE_POSIX])
- GNULIB_GETLOADAVG=0; AC_SUBST([GNULIB_GETLOADAVG])
- GNULIB_GETSUBOPT=0; AC_SUBST([GNULIB_GETSUBOPT])
- GNULIB_GRANTPT=0; AC_SUBST([GNULIB_GRANTPT])
- GNULIB_MALLOC_POSIX=0; AC_SUBST([GNULIB_MALLOC_POSIX])
- GNULIB_MBTOWC=0; AC_SUBST([GNULIB_MBTOWC])
- GNULIB_MKDTEMP=0; AC_SUBST([GNULIB_MKDTEMP])
- GNULIB_MKOSTEMP=0; AC_SUBST([GNULIB_MKOSTEMP])
- GNULIB_MKOSTEMPS=0; AC_SUBST([GNULIB_MKOSTEMPS])
- GNULIB_MKSTEMP=0; AC_SUBST([GNULIB_MKSTEMP])
- GNULIB_MKSTEMPS=0; AC_SUBST([GNULIB_MKSTEMPS])
- GNULIB_POSIX_MEMALIGN=0;AC_SUBST([GNULIB_POSIX_MEMALIGN])
- GNULIB_POSIX_OPENPT=0; AC_SUBST([GNULIB_POSIX_OPENPT])
- GNULIB_PTSNAME=0; AC_SUBST([GNULIB_PTSNAME])
- GNULIB_PTSNAME_R=0; AC_SUBST([GNULIB_PTSNAME_R])
- GNULIB_PUTENV=0; AC_SUBST([GNULIB_PUTENV])
- GNULIB_QSORT_R=0; AC_SUBST([GNULIB_QSORT_R])
- GNULIB_RANDOM=0; AC_SUBST([GNULIB_RANDOM])
- GNULIB_RANDOM_R=0; AC_SUBST([GNULIB_RANDOM_R])
- GNULIB_REALLOCARRAY=0; AC_SUBST([GNULIB_REALLOCARRAY])
- GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX])
- GNULIB_REALPATH=0; AC_SUBST([GNULIB_REALPATH])
- GNULIB_RPMATCH=0; AC_SUBST([GNULIB_RPMATCH])
- GNULIB_SECURE_GETENV=0; AC_SUBST([GNULIB_SECURE_GETENV])
- GNULIB_SETENV=0; AC_SUBST([GNULIB_SETENV])
- GNULIB_STRTOD=0; AC_SUBST([GNULIB_STRTOD])
- GNULIB_STRTOLD=0; AC_SUBST([GNULIB_STRTOLD])
- GNULIB_STRTOLL=0; AC_SUBST([GNULIB_STRTOLL])
- GNULIB_STRTOULL=0; AC_SUBST([GNULIB_STRTOULL])
- GNULIB_SYSTEM_POSIX=0; AC_SUBST([GNULIB_SYSTEM_POSIX])
- GNULIB_UNLOCKPT=0; AC_SUBST([GNULIB_UNLOCKPT])
- GNULIB_UNSETENV=0; AC_SUBST([GNULIB_UNSETENV])
- GNULIB_WCTOMB=0; AC_SUBST([GNULIB_WCTOMB])
- dnl Support Microsoft deprecated alias function names by default.
- GNULIB_MDA_ECVT=1; AC_SUBST([GNULIB_MDA_ECVT])
- GNULIB_MDA_FCVT=1; AC_SUBST([GNULIB_MDA_FCVT])
- GNULIB_MDA_GCVT=1; AC_SUBST([GNULIB_MDA_GCVT])
- GNULIB_MDA_MKTEMP=1; AC_SUBST([GNULIB_MDA_MKTEMP])
- GNULIB_MDA_PUTENV=1; AC_SUBST([GNULIB_MDA_PUTENV])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE__EXIT=1; AC_SUBST([HAVE__EXIT])
HAVE_ALIGNED_ALLOC=1; AC_SUBST([HAVE_ALIGNED_ALLOC])
@@ -137,8 +154,10 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
HAVE_SETSTATE=1; AC_SUBST([HAVE_SETSTATE])
HAVE_DECL_SETSTATE=1; AC_SUBST([HAVE_DECL_SETSTATE])
HAVE_STRTOD=1; AC_SUBST([HAVE_STRTOD])
+ HAVE_STRTOL=1; AC_SUBST([HAVE_STRTOL])
HAVE_STRTOLD=1; AC_SUBST([HAVE_STRTOLD])
HAVE_STRTOLL=1; AC_SUBST([HAVE_STRTOLL])
+ HAVE_STRTOUL=1; AC_SUBST([HAVE_STRTOUL])
HAVE_STRTOULL=1; AC_SUBST([HAVE_STRTOULL])
HAVE_STRUCT_RANDOM_DATA=1; AC_SUBST([HAVE_STRUCT_RANDOM_DATA])
HAVE_SYS_LOADAVG_H=0; AC_SUBST([HAVE_SYS_LOADAVG_H])
@@ -160,11 +179,16 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
REPLACE_RANDOM=0; AC_SUBST([REPLACE_RANDOM])
REPLACE_RANDOM_R=0; AC_SUBST([REPLACE_RANDOM_R])
REPLACE_REALLOC=0; AC_SUBST([REPLACE_REALLOC])
+ REPLACE_REALLOCARRAY=0; AC_SUBST([REPLACE_REALLOCARRAY])
REPLACE_REALPATH=0; AC_SUBST([REPLACE_REALPATH])
REPLACE_SETENV=0; AC_SUBST([REPLACE_SETENV])
REPLACE_SETSTATE=0; AC_SUBST([REPLACE_SETSTATE])
REPLACE_STRTOD=0; AC_SUBST([REPLACE_STRTOD])
+ REPLACE_STRTOL=0; AC_SUBST([REPLACE_STRTOL])
REPLACE_STRTOLD=0; AC_SUBST([REPLACE_STRTOLD])
+ REPLACE_STRTOLL=0; AC_SUBST([REPLACE_STRTOLL])
+ REPLACE_STRTOUL=0; AC_SUBST([REPLACE_STRTOUL])
+ REPLACE_STRTOULL=0; AC_SUBST([REPLACE_STRTOULL])
REPLACE_UNSETENV=0; AC_SUBST([REPLACE_UNSETENV])
REPLACE_WCTOMB=0; AC_SUBST([REPLACE_WCTOMB])
])
diff --git a/m4/stpcpy.m4 b/m4/stpcpy.m4
index 28db4f45dfe..eb44f03adba 100644
--- a/m4/stpcpy.m4
+++ b/m4/stpcpy.m4
@@ -1,4 +1,4 @@
-# stpcpy.m4 serial 8
+# stpcpy.m4 serial 9
dnl Copyright (C) 2002, 2007, 2009-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -12,7 +12,7 @@ AC_DEFUN([gl_FUNC_STPCPY],
dnl The stpcpy() declaration in lib/string.in.h uses 'restrict'.
AC_REQUIRE([AC_C_RESTRICT])
- AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+ AC_REQUIRE([gl_STRING_H_DEFAULTS])
AC_CHECK_FUNCS([stpcpy])
if test $ac_cv_func_stpcpy = no; then
HAVE_STPCPY=0
diff --git a/m4/string_h.m4 b/m4/string_h.m4
index a4cc5b43783..e88ac9ca853 100644
--- a/m4/string_h.m4
+++ b/m4/string_h.m4
@@ -5,20 +5,15 @@
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 29
+# serial 34
# Written by Paul Eggert.
-AC_DEFUN([gl_HEADER_STRING_H],
+AC_DEFUN_ONCE([gl_STRING_H],
[
- dnl Use AC_REQUIRE here, so that the default behavior below is expanded
- dnl once only, before all statements that occur in other macros.
- AC_REQUIRE([gl_HEADER_STRING_H_BODY])
-])
-
-AC_DEFUN([gl_HEADER_STRING_H_BODY],
-[
- AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only, before all statements
+ dnl that occur in other macros.
+ AC_REQUIRE([gl_STRING_H_DEFAULTS])
gl_NEXT_HEADERS([string.h])
dnl Check for declarations of anything we want to poison if the
@@ -33,62 +28,79 @@ AC_DEFUN([gl_HEADER_STRING_H_BODY],
AC_REQUIRE([AC_C_RESTRICT])
])
+# gl_STRING_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_STRING_MODULE_INDICATOR],
[
- dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
- AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only.
+ gl_STRING_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
-AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_STRING_H_MODULE_INDICATOR_DEFAULTS], [
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXPLICIT_BZERO])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FFSL])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FFSLL])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MEMCHR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MEMMEM])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MEMPCPY])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MEMRCHR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RAWMEMCHR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STPCPY])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STPNCPY])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCHRNUL])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRDUP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNCAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNDUP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNLEN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRPBRK])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSEP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSTR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASESTR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOK_R])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSLEN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNLEN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCHR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSRCHR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSSTR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCASECMP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNCASECMP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSPCASECMP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCASESTR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCSPN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSPBRK])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSSPN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSSEP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSTOK_R])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERROR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERROR_R])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERRORNAME_NP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGABBREV_NP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGDESCR_NP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSIGNAL])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRVERSCMP])
+ dnl Support Microsoft deprecated alias function names by default.
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_MEMCCPY], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_STRDUP], [1])
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_STRING_H_MODULE_INDICATOR_DEFAULTS])
+ dnl Make sure the shell variable for GNULIB_FREE_POSIX is initialized.
+ gl_STDLIB_H_REQUIRE_DEFAULTS
+ AC_REQUIRE([gl_STRING_H_DEFAULTS])
+])
+
+AC_DEFUN([gl_STRING_H_DEFAULTS],
[
- GNULIB_EXPLICIT_BZERO=0; AC_SUBST([GNULIB_EXPLICIT_BZERO])
- GNULIB_FFSL=0; AC_SUBST([GNULIB_FFSL])
- GNULIB_FFSLL=0; AC_SUBST([GNULIB_FFSLL])
- GNULIB_MEMCHR=0; AC_SUBST([GNULIB_MEMCHR])
- GNULIB_MEMMEM=0; AC_SUBST([GNULIB_MEMMEM])
- GNULIB_MEMPCPY=0; AC_SUBST([GNULIB_MEMPCPY])
- GNULIB_MEMRCHR=0; AC_SUBST([GNULIB_MEMRCHR])
- GNULIB_RAWMEMCHR=0; AC_SUBST([GNULIB_RAWMEMCHR])
- GNULIB_STPCPY=0; AC_SUBST([GNULIB_STPCPY])
- GNULIB_STPNCPY=0; AC_SUBST([GNULIB_STPNCPY])
- GNULIB_STRCHRNUL=0; AC_SUBST([GNULIB_STRCHRNUL])
- GNULIB_STRDUP=0; AC_SUBST([GNULIB_STRDUP])
- GNULIB_STRNCAT=0; AC_SUBST([GNULIB_STRNCAT])
- GNULIB_STRNDUP=0; AC_SUBST([GNULIB_STRNDUP])
- GNULIB_STRNLEN=0; AC_SUBST([GNULIB_STRNLEN])
- GNULIB_STRPBRK=0; AC_SUBST([GNULIB_STRPBRK])
- GNULIB_STRSEP=0; AC_SUBST([GNULIB_STRSEP])
- GNULIB_STRSTR=0; AC_SUBST([GNULIB_STRSTR])
- GNULIB_STRCASESTR=0; AC_SUBST([GNULIB_STRCASESTR])
- GNULIB_STRTOK_R=0; AC_SUBST([GNULIB_STRTOK_R])
- GNULIB_MBSLEN=0; AC_SUBST([GNULIB_MBSLEN])
- GNULIB_MBSNLEN=0; AC_SUBST([GNULIB_MBSNLEN])
- GNULIB_MBSCHR=0; AC_SUBST([GNULIB_MBSCHR])
- GNULIB_MBSRCHR=0; AC_SUBST([GNULIB_MBSRCHR])
- GNULIB_MBSSTR=0; AC_SUBST([GNULIB_MBSSTR])
- GNULIB_MBSCASECMP=0; AC_SUBST([GNULIB_MBSCASECMP])
- GNULIB_MBSNCASECMP=0; AC_SUBST([GNULIB_MBSNCASECMP])
- GNULIB_MBSPCASECMP=0; AC_SUBST([GNULIB_MBSPCASECMP])
- GNULIB_MBSCASESTR=0; AC_SUBST([GNULIB_MBSCASESTR])
- GNULIB_MBSCSPN=0; AC_SUBST([GNULIB_MBSCSPN])
- GNULIB_MBSPBRK=0; AC_SUBST([GNULIB_MBSPBRK])
- GNULIB_MBSSPN=0; AC_SUBST([GNULIB_MBSSPN])
- GNULIB_MBSSEP=0; AC_SUBST([GNULIB_MBSSEP])
- GNULIB_MBSTOK_R=0; AC_SUBST([GNULIB_MBSTOK_R])
- GNULIB_STRERROR=0; AC_SUBST([GNULIB_STRERROR])
- GNULIB_STRERROR_R=0; AC_SUBST([GNULIB_STRERROR_R])
- GNULIB_STRERRORNAME_NP=0; AC_SUBST([GNULIB_STRERRORNAME_NP])
- GNULIB_SIGABBREV_NP=0; AC_SUBST([GNULIB_SIGABBREV_NP])
- GNULIB_SIGDESCR_NP=0; AC_SUBST([GNULIB_SIGDESCR_NP])
- GNULIB_STRSIGNAL=0; AC_SUBST([GNULIB_STRSIGNAL])
- GNULIB_STRVERSCMP=0; AC_SUBST([GNULIB_STRVERSCMP])
HAVE_MBSLEN=0; AC_SUBST([HAVE_MBSLEN])
- dnl Support Microsoft deprecated alias function names by default.
- GNULIB_MDA_MEMCCPY=1; AC_SUBST([GNULIB_MDA_MEMCCPY])
- GNULIB_MDA_STRDUP=1; AC_SUBST([GNULIB_MDA_STRDUP])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_EXPLICIT_BZERO=1; AC_SUBST([HAVE_EXPLICIT_BZERO])
HAVE_FFSL=1; AC_SUBST([HAVE_FFSL])
diff --git a/m4/strnlen.m4 b/m4/strnlen.m4
index bb9a680fdc4..1d4f10616e2 100644
--- a/m4/strnlen.m4
+++ b/m4/strnlen.m4
@@ -1,4 +1,4 @@
-# strnlen.m4 serial 13
+# strnlen.m4 serial 14
dnl Copyright (C) 2002-2003, 2005-2007, 2009-2021 Free Software Foundation,
dnl Inc.
dnl This file is free software; the Free Software Foundation
@@ -7,7 +7,7 @@ dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_STRNLEN],
[
- AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+ AC_REQUIRE([gl_STRING_H_DEFAULTS])
dnl Persuade glibc <string.h> to declare strnlen().
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
diff --git a/m4/strtoll.m4 b/m4/strtoll.m4
index d2c9e5310d1..14455dc3db9 100644
--- a/m4/strtoll.m4
+++ b/m4/strtoll.m4
@@ -1,4 +1,4 @@
-# strtoll.m4 serial 8
+# strtoll.m4 serial 9
dnl Copyright (C) 2002, 2004, 2006, 2008-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -7,8 +7,40 @@ dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_STRTOLL],
[
AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_REQUIRE([AC_CANONICAL_HOST])
AC_CHECK_FUNCS([strtoll])
- if test $ac_cv_func_strtoll = no; then
+ if test $ac_cv_func_strtoll = yes; then
+ AC_CACHE_CHECK([whether strtoll works],
+ [gl_cv_func_strtoll_works],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <stdlib.h>]],
+ [[int result = 0;
+ char *term;
+ /* This test fails on Minix and native Windows. */
+ {
+ const char input[] = "0x";
+ (void) strtoll (input, &term, 16);
+ if (term != input + 1)
+ result |= 1;
+ }
+ return result;
+ ]])
+ ],
+ [gl_cv_func_strtoll_works=yes],
+ [gl_cv_func_strtoll_works=no],
+ [case "$host_os" in
+ # Guess no on native Windows.
+ mingw*) gl_cv_func_strtoll_works="guessing no" ;;
+ *) gl_cv_func_strtoll_works="$gl_cross_guess_normal" ;;
+ esac
+ ])
+ ])
+ case "$gl_cv_func_strtoll_works" in
+ *yes) ;;
+ *) REPLACE_STRTOLL=1 ;;
+ esac
+ else
HAVE_STRTOLL=0
fi
])
diff --git a/m4/sys_random_h.m4 b/m4/sys_random_h.m4
index 45e0469ba05..37bc31606bd 100644
--- a/m4/sys_random_h.m4
+++ b/m4/sys_random_h.m4
@@ -1,10 +1,10 @@
-# sys_random_h.m4 serial 5
+# sys_random_h.m4 serial 8
dnl Copyright (C) 2020-2021 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_HEADER_SYS_RANDOM],
+AC_DEFUN_ONCE([gl_SYS_RANDOM_H],
[
AC_REQUIRE([gl_SYS_RANDOM_H_DEFAULTS])
dnl <sys/random.h> is always overridden, because of GNULIB_POSIXCHECK.
@@ -35,18 +35,33 @@ AC_DEFUN([gl_HEADER_SYS_RANDOM],
[getrandom])
])
+# gl_SYS_RANDOM_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_SYS_RANDOM_MODULE_INDICATOR],
[
- dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
- AC_REQUIRE([gl_SYS_RANDOM_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only.
+ gl_SYS_RANDOM_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_SYS_RANDOM_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_SYS_RANDOM_H_MODULE_INDICATOR_DEFAULTS], [
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETRANDOM])
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_SYS_RANDOM_H_MODULE_INDICATOR_DEFAULTS])
+ AC_REQUIRE([gl_SYS_RANDOM_H_DEFAULTS])
+])
+
AC_DEFUN([gl_SYS_RANDOM_H_DEFAULTS],
[
- GNULIB_GETRANDOM=0; AC_SUBST([GNULIB_GETRANDOM])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_GETRANDOM=1; AC_SUBST([HAVE_GETRANDOM])
REPLACE_GETRANDOM=0; AC_SUBST([REPLACE_GETRANDOM])
diff --git a/m4/sys_select_h.m4 b/m4/sys_select_h.m4
index 4b33d312e55..2e7d140dee2 100644
--- a/m4/sys_select_h.m4
+++ b/m4/sys_select_h.m4
@@ -1,13 +1,13 @@
-# sys_select_h.m4 serial 20
+# sys_select_h.m4 serial 23
dnl Copyright (C) 2006-2021 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_HEADER_SYS_SELECT],
+AC_DEFUN_ONCE([gl_SYS_SELECT_H],
[
- AC_REQUIRE([AC_C_RESTRICT])
AC_REQUIRE([gl_SYS_SELECT_H_DEFAULTS])
+ AC_REQUIRE([AC_C_RESTRICT])
AC_CACHE_CHECK([whether <sys/select.h> is self-contained],
[gl_cv_header_sys_select_h_selfcontained],
[
@@ -75,19 +75,34 @@ AC_DEFUN([gl_HEADER_SYS_SELECT],
]], [pselect select])
])
+# gl_SYS_SELECT_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_SYS_SELECT_MODULE_INDICATOR],
[
- dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
- AC_REQUIRE([gl_SYS_SELECT_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only.
+ gl_SYS_SELECT_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_SYS_SELECT_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_SYS_SELECT_H_MODULE_INDICATOR_DEFAULTS], [
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PSELECT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SELECT])
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_SYS_SELECT_H_MODULE_INDICATOR_DEFAULTS])
+ AC_REQUIRE([gl_SYS_SELECT_H_DEFAULTS])
+])
+
AC_DEFUN([gl_SYS_SELECT_H_DEFAULTS],
[
- GNULIB_PSELECT=0; AC_SUBST([GNULIB_PSELECT])
- GNULIB_SELECT=0; AC_SUBST([GNULIB_SELECT])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_PSELECT=1; AC_SUBST([HAVE_PSELECT])
REPLACE_PSELECT=0; AC_SUBST([REPLACE_PSELECT])
diff --git a/m4/sys_socket_h.m4 b/m4/sys_socket_h.m4
index 503cb9668b7..5676a0d2170 100644
--- a/m4/sys_socket_h.m4
+++ b/m4/sys_socket_h.m4
@@ -1,4 +1,4 @@
-# sys_socket_h.m4 serial 25
+# sys_socket_h.m4 serial 28
dnl Copyright (C) 2005-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -6,7 +6,7 @@ dnl with or without modifications, as long as this notice is preserved.
dnl From Simon Josefsson.
-AC_DEFUN([gl_HEADER_SYS_SOCKET],
+AC_DEFUN_ONCE([gl_SYS_SOCKET_H],
[
AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS])
AC_REQUIRE([AC_CANONICAL_HOST])
@@ -156,32 +156,47 @@ AC_DEFUN([gl_PREREQ_SYS_H_WS2TCPIP],
AC_SUBST([HAVE_WS2TCPIP_H])
])
+# gl_SYS_SOCKET_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_SYS_SOCKET_MODULE_INDICATOR],
[
- dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
- AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only.
+ gl_SYS_SOCKET_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_SYS_SOCKET_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_SYS_SOCKET_H_MODULE_INDICATOR_DEFAULTS], [
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SOCKET])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CONNECT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ACCEPT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_BIND])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPEERNAME])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETSOCKNAME])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETSOCKOPT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LISTEN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RECV])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SEND])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RECVFROM])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SENDTO])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETSOCKOPT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SHUTDOWN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ACCEPT4])
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_SYS_SOCKET_H_MODULE_INDICATOR_DEFAULTS])
+ AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS])
+])
+
AC_DEFUN([gl_SYS_SOCKET_H_DEFAULTS],
[
- GNULIB_SOCKET=0; AC_SUBST([GNULIB_SOCKET])
- GNULIB_CONNECT=0; AC_SUBST([GNULIB_CONNECT])
- GNULIB_ACCEPT=0; AC_SUBST([GNULIB_ACCEPT])
- GNULIB_BIND=0; AC_SUBST([GNULIB_BIND])
- GNULIB_GETPEERNAME=0; AC_SUBST([GNULIB_GETPEERNAME])
- GNULIB_GETSOCKNAME=0; AC_SUBST([GNULIB_GETSOCKNAME])
- GNULIB_GETSOCKOPT=0; AC_SUBST([GNULIB_GETSOCKOPT])
- GNULIB_LISTEN=0; AC_SUBST([GNULIB_LISTEN])
- GNULIB_RECV=0; AC_SUBST([GNULIB_RECV])
- GNULIB_SEND=0; AC_SUBST([GNULIB_SEND])
- GNULIB_RECVFROM=0; AC_SUBST([GNULIB_RECVFROM])
- GNULIB_SENDTO=0; AC_SUBST([GNULIB_SENDTO])
- GNULIB_SETSOCKOPT=0; AC_SUBST([GNULIB_SETSOCKOPT])
- GNULIB_SHUTDOWN=0; AC_SUBST([GNULIB_SHUTDOWN])
- GNULIB_ACCEPT4=0; AC_SUBST([GNULIB_ACCEPT4])
HAVE_STRUCT_SOCKADDR_STORAGE=1; AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE])
HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=1;
AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY])
diff --git a/m4/sys_stat_h.m4 b/m4/sys_stat_h.m4
index 23cbdd28eb2..ac91d425bbb 100644
--- a/m4/sys_stat_h.m4
+++ b/m4/sys_stat_h.m4
@@ -1,4 +1,4 @@
-# sys_stat_h.m4 serial 38 -*- Autoconf -*-
+# sys_stat_h.m4 serial 41 -*- Autoconf -*-
dnl Copyright (C) 2006-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -7,7 +7,7 @@ dnl with or without modifications, as long as this notice is preserved.
dnl From Eric Blake.
dnl Provide a GNU-like <sys/stat.h>.
-AC_DEFUN([gl_HEADER_SYS_STAT_H],
+AC_DEFUN_ONCE([gl_SYS_STAT_H],
[
AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
@@ -52,38 +52,53 @@ AC_DEFUN([gl_HEADER_SYS_STAT_H],
AC_REQUIRE([AC_C_RESTRICT])
])
+# gl_SYS_STAT_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_SYS_STAT_MODULE_INDICATOR],
[
- dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
- AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only.
+ gl_SYS_STAT_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_SYS_STAT_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_SYS_STAT_H_MODULE_INDICATOR_DEFAULTS], [
+ gl_UNISTD_H_REQUIRE_DEFAULTS dnl for REPLACE_FCHDIR
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCHMODAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSTAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSTATAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FUTIMENS])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETUMASK])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LCHMOD])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LSTAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKDIR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKDIRAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKFIFO])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKFIFOAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKNOD])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKNODAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UTIMENSAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OVERRIDES_STRUCT_STAT])
+ dnl Support Microsoft deprecated alias function names by default.
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_CHMOD], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_MKDIR], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_UMASK], [1])
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_SYS_STAT_H_MODULE_INDICATOR_DEFAULTS])
+ AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
+])
+
AC_DEFUN([gl_SYS_STAT_H_DEFAULTS],
[
- AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) dnl for REPLACE_FCHDIR
- GNULIB_FCHMODAT=0; AC_SUBST([GNULIB_FCHMODAT])
- GNULIB_FSTAT=0; AC_SUBST([GNULIB_FSTAT])
- GNULIB_FSTATAT=0; AC_SUBST([GNULIB_FSTATAT])
- GNULIB_FUTIMENS=0; AC_SUBST([GNULIB_FUTIMENS])
- GNULIB_GETUMASK=0; AC_SUBST([GNULIB_GETUMASK])
- GNULIB_LCHMOD=0; AC_SUBST([GNULIB_LCHMOD])
- GNULIB_LSTAT=0; AC_SUBST([GNULIB_LSTAT])
- GNULIB_MKDIR=0; AC_SUBST([GNULIB_MKDIR])
- GNULIB_MKDIRAT=0; AC_SUBST([GNULIB_MKDIRAT])
- GNULIB_MKFIFO=0; AC_SUBST([GNULIB_MKFIFO])
- GNULIB_MKFIFOAT=0; AC_SUBST([GNULIB_MKFIFOAT])
- GNULIB_MKNOD=0; AC_SUBST([GNULIB_MKNOD])
- GNULIB_MKNODAT=0; AC_SUBST([GNULIB_MKNODAT])
- GNULIB_STAT=0; AC_SUBST([GNULIB_STAT])
- GNULIB_UTIMENSAT=0; AC_SUBST([GNULIB_UTIMENSAT])
- GNULIB_OVERRIDES_STRUCT_STAT=0; AC_SUBST([GNULIB_OVERRIDES_STRUCT_STAT])
- dnl Support Microsoft deprecated alias function names by default.
- GNULIB_MDA_CHMOD=1; AC_SUBST([GNULIB_MDA_CHMOD])
- GNULIB_MDA_MKDIR=1; AC_SUBST([GNULIB_MDA_MKDIR])
- GNULIB_MDA_UMASK=1; AC_SUBST([GNULIB_MDA_UMASK])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_FCHMODAT=1; AC_SUBST([HAVE_FCHMODAT])
HAVE_FSTATAT=1; AC_SUBST([HAVE_FSTATAT])
diff --git a/m4/sys_time_h.m4 b/m4/sys_time_h.m4
index 64f133d5133..c425a9639a1 100644
--- a/m4/sys_time_h.m4
+++ b/m4/sys_time_h.m4
@@ -1,5 +1,5 @@
# Configure a replacement for <sys/time.h>.
-# serial 9
+# serial 12
# Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
@@ -8,18 +8,13 @@
# Written by Paul Eggert and Martin Lambers.
-AC_DEFUN([gl_HEADER_SYS_TIME_H],
+AC_DEFUN_ONCE([gl_SYS_TIME_H],
[
dnl Use AC_REQUIRE here, so that the REPLACE_GETTIMEOFDAY=0 statement
dnl below is expanded once only, before all REPLACE_GETTIMEOFDAY=1
dnl statements that occur in other macros.
- AC_REQUIRE([gl_HEADER_SYS_TIME_H_BODY])
-])
-
-AC_DEFUN([gl_HEADER_SYS_TIME_H_BODY],
-[
+ AC_REQUIRE([gl_SYS_TIME_H_DEFAULTS])
AC_REQUIRE([AC_C_RESTRICT])
- AC_REQUIRE([gl_HEADER_SYS_TIME_H_DEFAULTS])
AC_CHECK_HEADERS_ONCE([sys/time.h])
gl_CHECK_NEXT_HEADERS([sys/time.h])
@@ -89,18 +84,33 @@ AC_DEFUN([gl_HEADER_SYS_TIME_H_BODY],
]], [gettimeofday])
])
+# gl_SYS_TIME_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_SYS_TIME_MODULE_INDICATOR],
[
- dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
- AC_REQUIRE([gl_HEADER_SYS_TIME_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only.
+ gl_SYS_TIME_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
-AC_DEFUN([gl_HEADER_SYS_TIME_H_DEFAULTS],
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_SYS_TIME_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_SYS_TIME_H_MODULE_INDICATOR_DEFAULTS], [
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETTIMEOFDAY])
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_SYS_TIME_H_MODULE_INDICATOR_DEFAULTS])
+ AC_REQUIRE([gl_SYS_TIME_H_DEFAULTS])
+])
+
+AC_DEFUN([gl_SYS_TIME_H_DEFAULTS],
[
- GNULIB_GETTIMEOFDAY=0; AC_SUBST([GNULIB_GETTIMEOFDAY])
dnl Assume POSIX behavior unless another module says otherwise.
HAVE_GETTIMEOFDAY=1; AC_SUBST([HAVE_GETTIMEOFDAY])
HAVE_STRUCT_TIMEVAL=1; AC_SUBST([HAVE_STRUCT_TIMEVAL])
diff --git a/m4/sys_types_h.m4 b/m4/sys_types_h.m4
index 2172c836d95..6dd6fee10c8 100644
--- a/m4/sys_types_h.m4
+++ b/m4/sys_types_h.m4
@@ -1,4 +1,4 @@
-# sys_types_h.m4 serial 11
+# sys_types_h.m4 serial 13
dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -6,10 +6,11 @@ dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN_ONCE([gl_SYS_TYPES_H],
[
+ AC_REQUIRE([gl_SYS_TYPES_H_DEFAULTS])
+
dnl Use sane struct stat types in OpenVMS 8.2 and later.
AC_DEFINE([_USE_STD_STAT], 1, [For standard stat data types on VMS.])
- AC_REQUIRE([gl_SYS_TYPES_H_DEFAULTS])
gl_NEXT_HEADERS([sys/types.h])
dnl Ensure the type pid_t gets defined.
@@ -30,6 +31,17 @@ AC_DEFUN_ONCE([gl_SYS_TYPES_H],
AC_SUBST([WINDOWS_STAT_INODES])
])
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_SYS_TYPES_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_SYS_TYPE_H_MODULE_INDICATOR_DEFAULTS], [
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_SYS_TYPE_H_MODULE_INDICATOR_DEFAULTS])
+ AC_REQUIRE([gl_SYS_TYPES_H_DEFAULTS])
+])
+
AC_DEFUN([gl_SYS_TYPES_H_DEFAULTS],
[
])
diff --git a/m4/time_h.m4 b/m4/time_h.m4
index b6a1aa3bc0f..b57474b48b3 100644
--- a/m4/time_h.m4
+++ b/m4/time_h.m4
@@ -2,7 +2,7 @@
# Copyright (C) 2000-2001, 2003-2007, 2009-2021 Free Software Foundation, Inc.
-# serial 15
+# serial 18
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -10,16 +10,11 @@
# Written by Paul Eggert and Jim Meyering.
-AC_DEFUN([gl_HEADER_TIME_H],
+AC_DEFUN_ONCE([gl_TIME_H],
[
- dnl Use AC_REQUIRE here, so that the default behavior below is expanded
- dnl once only, before all statements that occur in other macros.
- AC_REQUIRE([gl_HEADER_TIME_H_BODY])
-])
-
-AC_DEFUN([gl_HEADER_TIME_H_BODY],
-[
- AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only, before all statements
+ dnl that occur in other macros.
+ AC_REQUIRE([gl_TIME_H_DEFAULTS])
gl_NEXT_HEADERS([time.h])
AC_REQUIRE([gl_CHECK_TYPE_STRUCT_TIMESPEC])
@@ -111,30 +106,45 @@ AC_DEFUN([gl_CHECK_TYPE_STRUCT_TIMESPEC],
AC_SUBST([UNISTD_H_DEFINES_STRUCT_TIMESPEC])
])
+# gl_TIME_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_TIME_MODULE_INDICATOR],
[
- dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
- AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only.
+ gl_TIME_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
-AC_DEFUN([gl_HEADER_TIME_H_DEFAULTS],
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_TIME_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_TIME_H_MODULE_INDICATOR_DEFAULTS], [
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CTIME])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKTIME])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOCALTIME])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_NANOSLEEP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRFTIME])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRPTIME])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIMEGM])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIMESPEC_GET])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIME_R])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIME_RZ])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TZSET])
+ dnl Support Microsoft deprecated alias function names by default.
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_TZSET], [1])
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_TIME_H_MODULE_INDICATOR_DEFAULTS])
+ AC_REQUIRE([gl_TIME_H_DEFAULTS])
+])
+
+AC_DEFUN([gl_TIME_H_DEFAULTS],
[
- GNULIB_CTIME=0; AC_SUBST([GNULIB_CTIME])
- GNULIB_MKTIME=0; AC_SUBST([GNULIB_MKTIME])
- GNULIB_LOCALTIME=0; AC_SUBST([GNULIB_LOCALTIME])
- GNULIB_NANOSLEEP=0; AC_SUBST([GNULIB_NANOSLEEP])
- GNULIB_STRFTIME=0; AC_SUBST([GNULIB_STRFTIME])
- GNULIB_STRPTIME=0; AC_SUBST([GNULIB_STRPTIME])
- GNULIB_TIMEGM=0; AC_SUBST([GNULIB_TIMEGM])
- GNULIB_TIMESPEC_GET=0; AC_SUBST([GNULIB_TIMESPEC_GET])
- GNULIB_TIME_R=0; AC_SUBST([GNULIB_TIME_R])
- GNULIB_TIME_RZ=0; AC_SUBST([GNULIB_TIME_RZ])
- GNULIB_TZSET=0; AC_SUBST([GNULIB_TZSET])
- dnl Support Microsoft deprecated alias function names by default.
- GNULIB_MDA_TZSET=1; AC_SUBST([GNULIB_MDA_TZSET])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_DECL_LOCALTIME_R=1; AC_SUBST([HAVE_DECL_LOCALTIME_R])
HAVE_NANOSLEEP=1; AC_SUBST([HAVE_NANOSLEEP])
diff --git a/m4/time_r.m4 b/m4/time_r.m4
index 713e93ac263..2d49b64f12c 100644
--- a/m4/time_r.m4
+++ b/m4/time_r.m4
@@ -12,7 +12,7 @@ AC_DEFUN([gl_TIME_R],
dnl Persuade glibc and Solaris <time.h> to declare localtime_r.
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
- AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS])
+ AC_REQUIRE([gl_TIME_H_DEFAULTS])
AC_REQUIRE([AC_C_RESTRICT])
dnl Some systems don't declare localtime_r() and gmtime_r() if _REENTRANT is
diff --git a/m4/time_rz.m4 b/m4/time_rz.m4
index 34ef0bab4b9..c5e85dc625e 100644
--- a/m4/time_rz.m4
+++ b/m4/time_rz.m4
@@ -10,7 +10,7 @@ dnl Written by Paul Eggert.
AC_DEFUN([gl_TIME_RZ],
[
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
- AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS])
+ AC_REQUIRE([gl_TIME_H_DEFAULTS])
AC_REQUIRE([AC_STRUCT_TIMEZONE])
# On Mac OS X 10.6, localtime loops forever with some time_t values.
diff --git a/m4/timegm.m4 b/m4/timegm.m4
index 098c857e7f2..58123beb0cc 100644
--- a/m4/timegm.m4
+++ b/m4/timegm.m4
@@ -1,4 +1,4 @@
-# timegm.m4 serial 12
+# timegm.m4 serial 13
dnl Copyright (C) 2003, 2007, 2009-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -6,7 +6,7 @@ dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_TIMEGM],
[
- AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS])
+ AC_REQUIRE([gl_TIME_H_DEFAULTS])
AC_REQUIRE([gl_FUNC_MKTIME_WORKS])
REPLACE_TIMEGM=0
AC_CHECK_FUNCS_ONCE([timegm])
diff --git a/m4/timer_time.m4 b/m4/timer_time.m4
index f0e5785e9aa..003e36e9d14 100644
--- a/m4/timer_time.m4
+++ b/m4/timer_time.m4
@@ -1,4 +1,4 @@
-# timer_time.m4 serial 4
+# timer_time.m4 serial 5
dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -18,9 +18,13 @@ AC_DEFUN([gl_TIMER_TIME],
dnl the threadlib.m4 file that is installed in $PREFIX/share/aclocal/.
m4_ifdef([gl_][PTHREADLIB], [AC_REQUIRE([gl_][PTHREADLIB])])
+ AC_CHECK_DECL([timer_settime], [], [],
+ [[#include <time.h>
+ ]])
LIB_TIMER_TIME=
AC_SUBST([LIB_TIMER_TIME])
- gl_saved_libs=$LIBS
+ AS_IF([test "$ac_cv_have_decl_timer_settime" = yes], [
+ gl_saved_libs=$LIBS
AC_SEARCH_LIBS([timer_settime], [rt posix4],
[test "$ac_cv_search_timer_settime" = "none required" ||
LIB_TIMER_TIME=$ac_cv_search_timer_settime])
@@ -40,5 +44,6 @@ AC_DEFUN([gl_TIMER_TIME],
],
[LIB_TIMER_TIME="$LIB_TIMER_TIME $LIBPMULTITHREAD"])])
AC_CHECK_FUNCS([timer_settime])
- LIBS=$gl_saved_libs
+ LIBS=$gl_saved_libs
+ ])
])
diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4
index 0f26fb908d3..0ce4ea4511f 100644
--- a/m4/unistd_h.m4
+++ b/m4/unistd_h.m4
@@ -1,4 +1,4 @@
-# unistd_h.m4 serial 85
+# unistd_h.m4 serial 89
dnl Copyright (C) 2006-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -6,10 +6,10 @@ dnl with or without modifications, as long as this notice is preserved.
dnl Written by Simon Josefsson, Bruno Haible.
-AC_DEFUN([gl_UNISTD_H],
+AC_DEFUN_ONCE([gl_UNISTD_H],
[
- dnl Use AC_REQUIRE here, so that the default behavior below is expanded
- dnl once only, before all statements that occur in other macros.
+ dnl Ensure to expand the default settings once only, before all statements
+ dnl that occur in other macros.
AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
gl_CHECK_NEXT_HEADERS([unistd.h])
@@ -59,100 +59,116 @@ AC_DEFUN([gl_UNISTD_H],
fi
])
+# gl_UNISTD_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
AC_DEFUN([gl_UNISTD_MODULE_INDICATOR],
[
- dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
- AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+ dnl Ensure to expand the default settings once only.
+ gl_UNISTD_H_REQUIRE_DEFAULTS
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
dnl Define it also as a C macro, for the benefit of the unit tests.
gl_MODULE_INDICATOR_FOR_TESTS([$1])
])
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd. It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_UNISTD_H_REQUIRE_DEFAULTS],
+[
+ m4_defun(GL_MODULE_INDICATOR_PREFIX[_UNISTD_H_MODULE_INDICATOR_DEFAULTS], [
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ACCESS])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CHDIR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CHOWN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CLOSE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_COPY_FILE_RANGE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DUP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DUP2])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DUP3])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ENVIRON])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EUIDACCESS])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECL])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECLE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECLP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECV])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECVE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECVP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECVPE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FACCESSAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCHDIR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCHOWNAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FDATASYNC])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSYNC])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FTRUNCATE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETCWD])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETDOMAINNAME])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETDTABLESIZE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETENTROPY])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETGROUPS])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETHOSTNAME])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLOGIN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLOGIN_R])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETOPT_POSIX])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPAGESIZE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPASS])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETUSERSHELL])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GROUP_MEMBER])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISATTY])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LCHOWN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LINK])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LINKAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LSEEK])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PIPE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PIPE2])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PREAD])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PWRITE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_READ])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_READLINK])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_READLINKAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RMDIR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETHOSTNAME])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SLEEP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SYMLINK])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SYMLINKAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TRUNCATE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TTYNAME_R])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNISTD_H_GETOPT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNISTD_H_NONBLOCKING])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNISTD_H_SIGPIPE])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNLINK])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNLINKAT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_USLEEP])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WRITE])
+ dnl Support Microsoft deprecated alias function names by default.
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_ACCESS], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_CHDIR], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_CLOSE], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_DUP], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_DUP2], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECL], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECLE], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECLP], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECV], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECVE], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECVP], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECVPE], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_GETCWD], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_GETPID], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_ISATTY], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_LSEEK], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_READ], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_RMDIR], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_SWAB], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_UNLINK], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_WRITE], [1])
+ ])
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_UNISTD_H_MODULE_INDICATOR_DEFAULTS])
+ AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+])
+
AC_DEFUN([gl_UNISTD_H_DEFAULTS],
[
- GNULIB_ACCESS=0; AC_SUBST([GNULIB_ACCESS])
- GNULIB_CHDIR=0; AC_SUBST([GNULIB_CHDIR])
- GNULIB_CHOWN=0; AC_SUBST([GNULIB_CHOWN])
- GNULIB_CLOSE=0; AC_SUBST([GNULIB_CLOSE])
- GNULIB_COPY_FILE_RANGE=0; AC_SUBST([GNULIB_COPY_FILE_RANGE])
- GNULIB_DUP=0; AC_SUBST([GNULIB_DUP])
- GNULIB_DUP2=0; AC_SUBST([GNULIB_DUP2])
- GNULIB_DUP3=0; AC_SUBST([GNULIB_DUP3])
- GNULIB_ENVIRON=0; AC_SUBST([GNULIB_ENVIRON])
- GNULIB_EUIDACCESS=0; AC_SUBST([GNULIB_EUIDACCESS])
- GNULIB_EXECL=0; AC_SUBST([GNULIB_EXECL])
- GNULIB_EXECLE=0; AC_SUBST([GNULIB_EXECLE])
- GNULIB_EXECLP=0; AC_SUBST([GNULIB_EXECLP])
- GNULIB_EXECV=0; AC_SUBST([GNULIB_EXECV])
- GNULIB_EXECVE=0; AC_SUBST([GNULIB_EXECVE])
- GNULIB_EXECVP=0; AC_SUBST([GNULIB_EXECVP])
- GNULIB_EXECVPE=0; AC_SUBST([GNULIB_EXECVPE])
- GNULIB_FACCESSAT=0; AC_SUBST([GNULIB_FACCESSAT])
- GNULIB_FCHDIR=0; AC_SUBST([GNULIB_FCHDIR])
- GNULIB_FCHOWNAT=0; AC_SUBST([GNULIB_FCHOWNAT])
- GNULIB_FDATASYNC=0; AC_SUBST([GNULIB_FDATASYNC])
- GNULIB_FSYNC=0; AC_SUBST([GNULIB_FSYNC])
- GNULIB_FTRUNCATE=0; AC_SUBST([GNULIB_FTRUNCATE])
- GNULIB_GETCWD=0; AC_SUBST([GNULIB_GETCWD])
- GNULIB_GETDOMAINNAME=0; AC_SUBST([GNULIB_GETDOMAINNAME])
- GNULIB_GETDTABLESIZE=0; AC_SUBST([GNULIB_GETDTABLESIZE])
- GNULIB_GETENTROPY=0; AC_SUBST([GNULIB_GETENTROPY])
- GNULIB_GETGROUPS=0; AC_SUBST([GNULIB_GETGROUPS])
- GNULIB_GETHOSTNAME=0; AC_SUBST([GNULIB_GETHOSTNAME])
- GNULIB_GETLOGIN=0; AC_SUBST([GNULIB_GETLOGIN])
- GNULIB_GETLOGIN_R=0; AC_SUBST([GNULIB_GETLOGIN_R])
- GNULIB_GETOPT_POSIX=0; AC_SUBST([GNULIB_GETOPT_POSIX])
- GNULIB_GETPAGESIZE=0; AC_SUBST([GNULIB_GETPAGESIZE])
- GNULIB_GETPASS=0; AC_SUBST([GNULIB_GETPASS])
- GNULIB_GETUSERSHELL=0; AC_SUBST([GNULIB_GETUSERSHELL])
- GNULIB_GROUP_MEMBER=0; AC_SUBST([GNULIB_GROUP_MEMBER])
- GNULIB_ISATTY=0; AC_SUBST([GNULIB_ISATTY])
- GNULIB_LCHOWN=0; AC_SUBST([GNULIB_LCHOWN])
- GNULIB_LINK=0; AC_SUBST([GNULIB_LINK])
- GNULIB_LINKAT=0; AC_SUBST([GNULIB_LINKAT])
- GNULIB_LSEEK=0; AC_SUBST([GNULIB_LSEEK])
- GNULIB_PIPE=0; AC_SUBST([GNULIB_PIPE])
- GNULIB_PIPE2=0; AC_SUBST([GNULIB_PIPE2])
- GNULIB_PREAD=0; AC_SUBST([GNULIB_PREAD])
- GNULIB_PWRITE=0; AC_SUBST([GNULIB_PWRITE])
- GNULIB_READ=0; AC_SUBST([GNULIB_READ])
- GNULIB_READLINK=0; AC_SUBST([GNULIB_READLINK])
- GNULIB_READLINKAT=0; AC_SUBST([GNULIB_READLINKAT])
- GNULIB_RMDIR=0; AC_SUBST([GNULIB_RMDIR])
- GNULIB_SETHOSTNAME=0; AC_SUBST([GNULIB_SETHOSTNAME])
- GNULIB_SLEEP=0; AC_SUBST([GNULIB_SLEEP])
- GNULIB_SYMLINK=0; AC_SUBST([GNULIB_SYMLINK])
- GNULIB_SYMLINKAT=0; AC_SUBST([GNULIB_SYMLINKAT])
- GNULIB_TRUNCATE=0; AC_SUBST([GNULIB_TRUNCATE])
- GNULIB_TTYNAME_R=0; AC_SUBST([GNULIB_TTYNAME_R])
- GNULIB_UNISTD_H_NONBLOCKING=0; AC_SUBST([GNULIB_UNISTD_H_NONBLOCKING])
- GNULIB_UNISTD_H_SIGPIPE=0; AC_SUBST([GNULIB_UNISTD_H_SIGPIPE])
- GNULIB_UNLINK=0; AC_SUBST([GNULIB_UNLINK])
- GNULIB_UNLINKAT=0; AC_SUBST([GNULIB_UNLINKAT])
- GNULIB_USLEEP=0; AC_SUBST([GNULIB_USLEEP])
- GNULIB_WRITE=0; AC_SUBST([GNULIB_WRITE])
- dnl Support Microsoft deprecated alias function names by default.
- GNULIB_MDA_ACCESS=1; AC_SUBST([GNULIB_MDA_ACCESS])
- GNULIB_MDA_CHDIR=1; AC_SUBST([GNULIB_MDA_CHDIR])
- GNULIB_MDA_CLOSE=1; AC_SUBST([GNULIB_MDA_CLOSE])
- GNULIB_MDA_DUP=1; AC_SUBST([GNULIB_MDA_DUP])
- GNULIB_MDA_DUP2=1; AC_SUBST([GNULIB_MDA_DUP2])
- GNULIB_MDA_EXECL=1; AC_SUBST([GNULIB_MDA_EXECL])
- GNULIB_MDA_EXECLE=1; AC_SUBST([GNULIB_MDA_EXECLE])
- GNULIB_MDA_EXECLP=1; AC_SUBST([GNULIB_MDA_EXECLP])
- GNULIB_MDA_EXECV=1; AC_SUBST([GNULIB_MDA_EXECV])
- GNULIB_MDA_EXECVE=1; AC_SUBST([GNULIB_MDA_EXECVE])
- GNULIB_MDA_EXECVP=1; AC_SUBST([GNULIB_MDA_EXECVP])
- GNULIB_MDA_EXECVPE=1; AC_SUBST([GNULIB_MDA_EXECVPE])
- GNULIB_MDA_GETCWD=1; AC_SUBST([GNULIB_MDA_GETCWD])
- GNULIB_MDA_GETPID=1; AC_SUBST([GNULIB_MDA_GETPID])
- GNULIB_MDA_ISATTY=1; AC_SUBST([GNULIB_MDA_ISATTY])
- GNULIB_MDA_LSEEK=1; AC_SUBST([GNULIB_MDA_LSEEK])
- GNULIB_MDA_READ=1; AC_SUBST([GNULIB_MDA_READ])
- GNULIB_MDA_RMDIR=1; AC_SUBST([GNULIB_MDA_RMDIR])
- GNULIB_MDA_SWAB=1; AC_SUBST([GNULIB_MDA_SWAB])
- GNULIB_MDA_UNLINK=1; AC_SUBST([GNULIB_MDA_UNLINK])
- GNULIB_MDA_WRITE=1; AC_SUBST([GNULIB_MDA_WRITE])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_CHOWN=1; AC_SUBST([HAVE_CHOWN])
HAVE_COPY_FILE_RANGE=1; AC_SUBST([HAVE_COPY_FILE_RANGE])
diff --git a/m4/unlocked-io.m4 b/m4/unlocked-io.m4
index a2dc8a144af..b689020ff49 100644
--- a/m4/unlocked-io.m4
+++ b/m4/unlocked-io.m4
@@ -1,4 +1,4 @@
-# unlocked-io.m4 serial 15
+# unlocked-io.m4 serial 16
# Copyright (C) 1998-2006, 2009-2021 Free Software Foundation, Inc.
#
@@ -16,11 +16,6 @@ dnl on Solaris 2.6).
AC_DEFUN([gl_FUNC_GLIBC_UNLOCKED_IO],
[
- AC_DEFINE([USE_UNLOCKED_IO], [1],
- [Define to 1 if you want getc etc. to use unlocked I/O if available.
- Unlocked I/O can improve performance in unithreaded apps,
- but it is not safe for multithreaded apps.])
-
dnl Persuade glibc and Solaris <stdio.h> to declare
dnl fgets_unlocked(), fputs_unlocked() etc.
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
diff --git a/m4/year2038.m4 b/m4/year2038.m4
new file mode 100644
index 00000000000..da0f8d73030
--- /dev/null
+++ b/m4/year2038.m4
@@ -0,0 +1,124 @@
+# year2038.m4 serial 7
+dnl Copyright (C) 2017-2021 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 Attempt to ensure that 'time_t' can go past the year 2038 and that
+dnl the functions 'time', 'stat', etc. work with post-2038 timestamps.
+
+AC_DEFUN([gl_YEAR2038_EARLY],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ case "$host_os" in
+ mingw*)
+ AC_DEFINE([__MINGW_USE_VC2005_COMPAT], [1],
+ [For 64-bit time_t on 32-bit mingw.])
+ ;;
+ esac
+])
+
+# gl_YEAR2038_TEST_INCLUDES
+# -------------------------
+AC_DEFUN([gl_YEAR2038_TEST_INCLUDES],
+[[
+ #include <time.h>
+ /* Check that time_t can represent 2**32 - 1 correctly. */
+ #define LARGE_TIME_T \\
+ ((time_t) (((time_t) 1 << 30) - 1 + 3 * ((time_t) 1 << 30)))
+ int verify_time_t_range[(LARGE_TIME_T / 65537 == 65535
+ && LARGE_TIME_T % 65537 == 0)
+ ? 1 : -1];
+]])
+
+# gl_YEAR2038_BODY(REQUIRE-YEAR2038-SAFE)
+-----------------------------------------
+AC_DEFUN([gl_YEAR2038_BODY],
+[
+ AC_ARG_ENABLE([year2038],
+ [ --disable-year2038 omit support for timestamps past the year 2038])
+ AS_IF([test "$enable_year2038" != no],
+ [
+ dnl On many systems, time_t is already a 64-bit type.
+ dnl On those systems where time_t is still 32-bit, it requires kernel
+ dnl and libc support to make it 64-bit. For glibc 2.34 and later on Linux,
+ dnl defining _TIME_BITS=64 and _FILE_OFFSET_BITS=64 is needed on x86 and ARM.
+ dnl
+ dnl On native Windows, the system include files define types __time32_t
+ dnl and __time64_t. By default, time_t is an alias of
+ dnl - __time32_t on 32-bit mingw,
+ dnl - __time64_t on 64-bit mingw and on MSVC (since MSVC 8).
+ dnl But when compiling with -D__MINGW_USE_VC2005_COMPAT, time_t is an
+ dnl alias of __time64_t.
+ dnl And when compiling with -D_USE_32BIT_TIME_T, time_t is an alias of
+ dnl __time32_t.
+ AC_CACHE_CHECK([for time_t past the year 2038], [gl_cv_type_time_t_y2038],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([gl_YEAR2038_TEST_INCLUDES])],
+ [gl_cv_type_time_t_y2038=yes], [gl_cv_type_time_t_y2038=no])
+ ])
+ if test "$gl_cv_type_time_t_y2038" = no; then
+ AC_CACHE_CHECK([for 64-bit time_t with _TIME_BITS=64],
+ [gl_cv_type_time_t_bits_macro],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([[#define _TIME_BITS 64
+ #define _FILE_OFFSET_BITS 64
+ ]gl_YEAR2038_TEST_INCLUDES])],
+ [gl_cv_type_time_t_bits_macro=yes],
+ [gl_cv_type_time_t_bits_macro=no])
+ ])
+ if test "$gl_cv_type_time_t_bits_macro" = yes; then
+ AC_DEFINE([_TIME_BITS], [64],
+ [Number of bits in a timestamp, on hosts where this is settable.])
+ dnl AC_SYS_LARGFILE also defines this; it's OK if we do too.
+ AC_DEFINE([_FILE_OFFSET_BITS], [64],
+ [Number of bits in a file offset, on hosts where this is settable.])
+ gl_cv_type_time_t_y2038=yes
+ fi
+ fi
+ if test $gl_cv_type_time_t_y2038 = no; then
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#ifdef _USE_32BIT_TIME_T
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [AC_MSG_FAILURE(
+ [The 'time_t' type stops working after January 2038.
+ Remove _USE_32BIT_TIME_T from the compiler flags.])],
+ [# If not cross-compiling and $1 says we should check,
+ # and 'touch' works with a large timestamp, then evidently wider time_t
+ # is desired and supported, so fail and ask the builder to fix the
+ # problem. Otherwise, just warn the builder.
+ m4_ifval([$1],
+ [if test $cross_compiling = no \
+ && TZ=UTC0 touch -t 210602070628.15 conftest.time 2>/dev/null; then
+ case `TZ=UTC0 LC_ALL=C ls -l conftest.time 2>/dev/null` in
+ *'Feb 7 2106'* | *'Feb 7 17:10'*)
+ AC_MSG_FAILURE(
+ [The 'time_t' type stops working after January 2038,
+ and your system appears to support a wider 'time_t'.
+ Try configuring with 'CC="${CC} -m64"'.
+ To build with a 32-bit time_t anyway (not recommended),
+ configure with '--disable-year2038'.]);;
+ esac
+ rm -f conftest.time
+ fi])
+ if test "$gl_warned_about_y2038" != yes; then
+ AC_MSG_WARN(
+ [The 'time_t' type stops working after January 2038,
+ and this package needs a wider 'time_t' type
+ if there is any way to access timestamps after that.
+ Configure with 'CC="${CC} -m64"' perhaps?])
+ gl_warned_about_y2038=yes
+ fi
+ ])
+ fi])
+])
+
+AC_DEFUN([gl_YEAR2038],
+[
+ gl_YEAR2038_BODY([require-year2038-safe])
+])
diff --git a/make-dist b/make-dist
index 7074bb801be..db7a74b82b3 100755
--- a/make-dist
+++ b/make-dist
@@ -299,13 +299,6 @@ if [ $check = yes ]; then
echo "${bogosities}"
fi
- ## This exits with non-zero status if any .info files need
- ## rebuilding.
- if [ -r Makefile ] && [ "$with_info" = "yes" ]; then
- echo "Checking to see if info files are up-to-date..."
- make --question info || error=yes
- fi
-
## Is this a release?
case $version in
[1-9][0-9].[0-9])
@@ -366,9 +359,9 @@ possibly_non_vc_files="
src/config.in
"$(
find admin doc etc lisp \
- \( -name '*.el' -o -name '*.elc' -o -name '*.map' -o -name '*.stamp' \
- -o -name '*.texi' -o -name '*.tex' -o -name '*.txt' \) \
- ! -name 'site-init*' ! -name 'site-load*' ! -name 'default*'
+ \( -name '*.el' -o -name '*.elc' -o -name '*.map' -o -name '*.stamp' \
+ -o -name '*.texi' -o -name '*.tex' -o -name '*.txt' -o -name '*.pdf' \) \
+ ! -name 'site-init*' ! -name 'site-load*' ! -name 'default*'
) || exit
if [ $with_info = yes ]; then
@@ -392,9 +385,11 @@ manifest=MANIFEST
# other way when adding or deleting a distributed file while not using Git.
# TODO: maybe this should ignore $update, and always update MANIFEST
# if .git is present.
+# Filter out the files in msdos/autogen/, as they aren't useful in the
+# tarball, and get in the way during the build of the MSDOS port.
if ( [ $update = yes ] || [ ! -f $manifest ] ) && [ -r .git ]; then
echo "Updating $manifest"
- git ls-files > $manifest || exit
+ git ls-files | sed -e '/^msdos\/autogen\//d' > $manifest || exit
printf '%s\n' $possibly_non_vc_files $info_files >>$manifest || exit
sort -u -o $manifest $manifest || exit
fi
diff --git a/msdos/autogen/config.in b/msdos/autogen/config.in
index 263cba15a28..560f5f346ff 100644
--- a/msdos/autogen/config.in
+++ b/msdos/autogen/config.in
@@ -1712,7 +1712,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
/* Suppress GCC's bogus "no previous prototype for 'FOO'"
and "no previous declaration for 'FOO'" diagnostics,
when FOO is an inline function in the header; see
- <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54113>. */
+ <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54113>. */
# define _GL_INLINE_HEADER_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \
diff --git a/msdos/langinfo.h b/msdos/langinfo.h
new file mode 100644
index 00000000000..a74c3f7f8e8
--- /dev/null
+++ b/msdos/langinfo.h
@@ -0,0 +1,20 @@
+/* Replacement langinfo.h file for building GNU Emacs on MS-DOS with DJGPP.
+
+Copyright (C) 2021 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/>. */
+
+#define nl_langinfo(ignore) "cp437"
diff --git a/msdos/sed1v2.inp b/msdos/sed1v2.inp
index 5d82af66d95..60f67e43039 100644
--- a/msdos/sed1v2.inp
+++ b/msdos/sed1v2.inp
@@ -55,6 +55,10 @@ s/ *@LIBJPEG@//
s/ *@LIBPNG@//
s/ *@LIBGIF@//
s/ *@LIBXPM@//
+/^HAVE_NATIVE_COMP *=/s/@HAVE_NATIVE_COMP@/no/
+/^HAVE_PDUMPER *=/s/@HAVE_PDUMPER@/no/
+/^CHECK_STRUCTS *=/s/@CHECK_STRUCTS@//
+/^RUN_TEMACS \=/s/temacs/temacs.exe/
/^XFT_LIBS *=/s/@XFT_LIBS@//
/^XCB_LIBS *=/s/@XCB_LIBS@//
/^FONTCONFIG_CFLAGS *=/s/@FONTCONFIG_CFLAGS@//
@@ -150,6 +154,18 @@ s/ *@LIBXPM@//
/^CANNOT_DUMP *=/s/@CANNOT_DUMP@/no/
/^W32_OBJ *=/s/@W32_OBJ@//
/^W32_LIBS *=/s/@W32_LIBS@//
+/^JSON_OBJ *=/s/@JSON_OBJ@//
+/^JSON_CFLAGS *=/s/@JSON_CFLAGS@//
+/^JSON_LIBS *=/s/@JSON_LIBS@//
+/^LIBGCCJIT_OBJ *=/s/@LIBGCCJIT_OBJ@//
+/^LIBGCCJIT_CFLAGS *=/s/@LIBGCCJIT_CFLAGS@//
+/^LIBGCCJIT_LIBS *=/s/@LIBGCCJIT_LIBS@//
+/^HARFBUZZ_CFLAGS *=/s/@HARFBUZZ_CFLAGS@//
+/^HARFBUZZ_LIBS *=/s/@HARFBUZZ_LIBS@//
+/^LCMS2_CFLAGS *=/s/@LCMS2_CFLAGS@//
+/^LCMS2_LIBS *=/s/@LCMS2_LIBS@//
+/^LIBGMP *=/s/@LIBGMP@//
+/^DYNLIB_OBJ *=/s/@DYNLIB_OBJ@//
/^version *=/s/@[^@\n]*@//
/^EMACSRES *=/s/@EMACSRES@//
/^W32_RES_LINK *=/s/@W32_RES_LINK@//
@@ -162,6 +178,7 @@ s/ *@LIBXPM@//
/^AUTO_DEPEND *=/s/@AUTO_DEPEND@/yes/
/^PAXCTL_dumped *=/s/=.*$/=/
/^PAXCTL_notdumped *=/s/=.*$/=/
+/^DUMPING *=/s/@DUMPING@/unexec/
/^lisp\.mk:/,/^$/c\
lisp.mk: $(lispsource)/loadup.el\
@rm -f $@\
@@ -183,6 +200,7 @@ lisp.mk: $(lispsource)/loadup.el\
/^ *ifneq (\$(PAXCTL_dumped),)/,/^ *endif/d
/^ *ln /s/ln /cp /
/^ fi/d
+/ifeq (\$(HAVE_NATIVE_COMP):\$(NATIVE_DISABLED),yes:)/,/endif/d
/^ *\$(RUN_TEMACS) /i\
stubedit temacs.exe minstack=1024k
/^ *LC_ALL=C \$(RUN_TEMACS)/i\
@@ -214,8 +232,8 @@ s/echo.*buildobj.lst/dj&/
/^ -\{0,1\}rm -f/s/\\#/#/
/^ echo.* buildobj.h/s|echo |djecho |
/^buildobj\.h:/,/^ *\$(AM_V_at)mv /{
- /^ *\$(AM_V_GEN)for /,/^ *done /c\
- djecho "$(ALLOBJS)" | sed -e 's/^ */"/' -e 's/ *$$/"/' -e 's/ */", "/g' >>$@.tmp
+ /^ *\$(AM_V_GEN)for /,/mv \$@.tmp \$@/c\
+ djecho "$(ALLOBJS)" | sed -e 's/^ */"/' -e 's/ *$$/"/' -e 's/ */", "/g' >>$@
}
# Remove or replace dependencies we cannot have
/^\.PRECIOUS: /s!\.\./config.status !!
@@ -236,3 +254,5 @@ s| -I\$(srcdir)/\.\./lib||
s| -I\$(top_srcdir)/lib||
s| -I\. -I\$(srcdir)| -I.|
/^ *test "X/d
+/\$(CC) -o \$@.tmp/s/\$@.tmp/\$@/
+/mv \$@.tmp \$@/d \ No newline at end of file
diff --git a/msdos/sed2v2.inp b/msdos/sed2v2.inp
index ce45a7c80e9..52fbd4e9cbc 100644
--- a/msdos/sed2v2.inp
+++ b/msdos/sed2v2.inp
@@ -37,6 +37,7 @@
/^#undef HAVE_STRUCT_UTIMBUF *$/s/^.*$/#define HAVE_STRUCT_UTIMBUF 1/
/^#undef LOCALTIME_CACHE *$/s/^.*$/#define LOCALTIME_CACHE 1/
/^#undef HAVE_TZSET *$/s/^.*$/#define HAVE_TZSET 1/
+/^#undef HAVE_UNEXEC *$/s/^.*$/#define HAVE_UNEXEC 1/
/^#undef HAVE_RINT *$/s/^.*$/#define HAVE_RINT 1/
/^#undef HAVE_C99_STRTOLD *$/s/^.*$/#define HAVE_C99_STRTOLD 1/
/^#undef HAVE_DIFFTIME *$/s/^.*$/#define HAVE_DIFFTIME 1/
@@ -66,7 +67,7 @@
/^#undef PACKAGE_NAME/s/^.*$/#define PACKAGE_NAME ""/
/^#undef PACKAGE_STRING/s/^.*$/#define PACKAGE_STRING ""/
/^#undef PACKAGE_TARNAME/s/^.*$/#define PACKAGE_TARNAME ""/
-/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "28.0.50"/
+/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "29.0.50"/
/^#undef SYSTEM_TYPE/s/^.*$/#define SYSTEM_TYPE "ms-dos"/
/^#undef HAVE_DECL_GETENV/s/^.*$/#define HAVE_DECL_GETENV 1/
/^#undef SYS_SIGLIST_DECLARED/s/^.*$/#define SYS_SIGLIST_DECLARED 1/
diff --git a/msdos/sed3v2.inp b/msdos/sed3v2.inp
index 8b9bb0679bd..f7c9eb05ba9 100644
--- a/msdos/sed3v2.inp
+++ b/msdos/sed3v2.inp
@@ -34,6 +34,7 @@
/^LIBS_SYSTEM *=/s/@[^@\n]*@//g
/^LIB_CLOCK_GETTIME *=/s/@[^@\n]*@//g
/^LIB_TIMER_TIME *=/s/@[^@\n]*@//g
+/^LIB_GETRANDOM *=/s/@[^@\n]*@//g
/^CFLAGS *=/s!=.*$!=-O2 -g!
/^CPPFLAGS *=/s/@CPPFLAGS@//
/^LDFLAGS *=/s/@LDFLAGS@//
diff --git a/msdos/sedlibmk.inp b/msdos/sedlibmk.inp
index 825be849680..b3b94297d60 100644
--- a/msdos/sedlibmk.inp
+++ b/msdos/sedlibmk.inp
@@ -144,7 +144,7 @@ s/@PACKAGE@/emacs/
/^CPP *=/s/@[^@\n]*@/gcc -e/
/^CPPFLAGS *=/s/@[^@\n]*@//
/^CCDEPMODE *=/s/@[^@\n]*@/depmode=gcc3/
-/^CFLAGS *=/s/@[^@\n]*@/-g -O2/
+/^CFLAGS *=/s/@[^@\n]*@/-g -O2 -I$\(srcdir\)\/..\/msdos/
/^CYGPATH_W *=/s/@[^@\n]*@//
/^CYGWIN_OBJ *=/s/@[^@\n]*@//
/^C_SWITCH_MACHINE *=/s/@C_SWITCH_MACHINE@//
@@ -170,28 +170,28 @@ s/@PACKAGE@/emacs/
/^BITSIZEOF_WCHAR_T *=/s/@BITSIZEOF_WCHAR_T@/16/
/^BITSIZEOF_WINT_T *=/s/@BITSIZEOF_WINT_T@/32/
/^APPLE_UNIVERSAL_BUILD *=/s/@APPLE_UNIVERSAL_BUILD@/0/
-#
-# Most GNULIB_* are replaced with zero even though DJGPP does not have
-# these features. That's because the gnulib replacements cannot
+# Most GL_GNULIB_* are replaced with zero even though DJGPP does not
+# have these features. That's because the gnulib replacements cannot
# possibly work for DJGPP, so we prefer to fail the link than have a
# subtly botched executable. Those replacements that _are_ needed
# should be before the last catch-all rule.
-/^GNULIB_ATOLL *=/s/@GNULIB_ATOLL@/1/
-/^GNULIB_DUP3 *=/s/@GNULIB_DUP3@/1/
-/^GNULIB_ENVIRON *=/s/@GNULIB_ENVIRON@/1/
-/^GNULIB_FDATASYNC *=/s/@GNULIB_FDATASYNC@/1/
-/^GNULIB_GETLOADAVG *=/s/@GNULIB_GETLOADAVG@/1/
-/^GNULIB_GL_UNISTD_H_GETOPT *=/s/@GNULIB_GL_UNISTD_H_GETOPT@/1/
-/^GNULIB_MEMRCHR *=/s/@GNULIB_MEMRCHR@/1/
-/^GNULIB_MKOSTEMP *=/s/@GNULIB_MKOSTEMP@/1/
-/^GNULIB_MKTIME *=/s/@GNULIB_MKTIME@/1/
-/^GNULIB_TIME_R *=/s/@GNULIB_TIME_R@/1/
-/^GNULIB_TIMEGM *=/s/@GNULIB_TIMEGM@/1/
-/^GNULIB_TIME_RZ *=/s/@GNULIB_TIME_RZ@/1/
-/^GNULIB_UNSETENV *=/s/@GNULIB_UNSETENV@/1/
-/^GNULIB_[^ =]* *= *@/s/@[^@\n]*@/0/
-/^GSETTINGS_CFLAGS *=/s/@[^@\n]*@//
-/^GSETTINGS_LIBS *=/s/@[^@\n]*@//
+/^GL_GNULIB_ATOLL *=/s/@GL_GNULIB_ATOLL@/1/
+/^GL_GNULIB_DUP3 *=/s/@GL_GNULIB_DUP3@/1/
+/^GL_GNULIB_ENVIRON *=/s/@GL_GNULIB_ENVIRON@/1/
+/^GL_GNULIB_FDATASYNC *=/s/@GL_GNULIB_FDATASYNC@/1/
+/^GL_GNULIB_GETLOADAVG *=/s/@GL_GNULIB_GETLOADAVG@/1/
+/^GL_GNULIB_UNISTD_H_GETOPT *=/s/@GL_GNULIB_UNISTD_H_GETOPT@/1/
+/^GL_GNULIB_MEMRCHR *=/s/@GL_GNULIB_MEMRCHR@/1/
+/^GL_GNULIB_MEMPCPY *=/s/@GL_GNULIB_MEMPCPY@/1/
+/^GL_GNULIB_MKOSTEMP *=/s/@GL_GNULIB_MKOSTEMP@/1/
+/^GL_GNULIB_MKTIME *=/s/@GL_GNULIB_MKTIME@/1/
+/^GL_GNULIB_TIME_R *=/s/@GL_GNULIB_TIME_R@/1/
+/^GL_GNULIB_TIMEGM *=/s/@GL_GNULIB_TIMEGM@/1/
+/^GL_GNULIB_TIME_RZ *=/s/@GL_GNULIB_TIME_RZ@/1/
+/^GL_GNULIB_UNSETENV *=/s/@GL_GNULIB_UNSETENV@/1/
+/^GL_GNULIB_[^ =]* *= *@/s/@[^@\n]*@/0/
+/^GL_GSETTINGS_CFLAGS *=/s/@[^@\n]*@//
+/^GL_GSETTINGS_LIBS *=/s/@[^@\n]*@//
#
# Edit the HAVE_foo variables
/^HAVE_ATOLL *=/s/@HAVE_ATOLL@/0/
@@ -253,6 +253,7 @@ s/@PACKAGE@/emacs/
/^HAVE_USLEEP *=/s/@HAVE_USLEEP@/1/
/^HAVE_WCHAR_H *=/s/@HAVE_WCHAR_H@/1/
/^HAVE_WCHAR_T *=/s/@HAVE_WCHAR_T@/1/
+/^HAVE_LIBGMP *=/s/@HAVE_LIBGMP@/0/
/^HAVE__BOOL *=/s/@HAVE__BOOL@/1/
/^HAVE__EXIT *=/s/@HAVE__EXIT@/1/
/^HAVE_[^ =]* *= *@/s/@[^@\n]*@/0/
@@ -265,7 +266,9 @@ s/@PACKAGE@/emacs/
/^LIBS *=/s/@[^@\n]*@//
/^MAKEINFO *=/s/@MAKEINFO@/makeinfo/
# MKDIR_P lines are edited further below
-/^MKDIR_P *=/s/@MKDIR_P@//
+# MKDIR_P is only used to create lib/malloc, and the folder is
+# already present in the distribution, so this should work fine.
+/^MKDIR_P *=/s/@MKDIR_P@/echo/
/^NEXT_AS_FIRST_DIRECTIVE_DIRENT_H *=/s/@[^@\n]*@/<dirent.h>/
/^NEXT_AS_FIRST_DIRECTIVE_ERRNO_H *=/s/@[^@\n]*@//
/^NEXT_AS_FIRST_DIRECTIVE_FCNTL_H *=/s/@[^@\n]*@/<fcntl.h>/
@@ -309,6 +312,7 @@ s/@PACKAGE@/emacs/
/^REPLACE_MKTIME *=/s/@[^@\n]*@/1/
# We don't want any other gnulib replacement functions
/^REPLACE_[^ =]* *= *@/s/@[^@\n]*@/0/
+/^LIB_GETRANDOM[^ =]* *= *@/s/@[^@\n]*@//
/^SIG_ATOMIC_T_SUFFIX *=/s/@SIG_ATOMIC_T_SUFFIX@//
/^SIZE_T_SUFFIX *=/s/@SIZE_T_SUFFIX@/u/
/^ALLOCA_H *=/s/@[^@\n]*@/alloca.h/
@@ -317,18 +321,23 @@ s/@PACKAGE@/emacs/
/^ERRNO_H *=/s/@[^@\n]*@//
/^EXECINFO_H *=/s/@[^@\n]*@/execinfo.h/
/^GETOPT_CDEFS_H *=/s/@[^@\n]*@/getopt-cdefs.h/
+/^GMP_H *=/s/@[^@\n]*@/gmp.h/
/^LIMITS_H *=/s/@[^@\n]*@/limits.h/
+/^IEEE754_H *=/s/@[^@\n]*@/ieee754.h/
/^STDALIGN_H *=/s/@[^@\n]*@/stdalign.h/
/^STDDEF_H *=/s/@[^@\n]*@/stddef.h/
/^STDINT_H *=/s/@[^@\n]*@/stdint.h/
/^SYS_TIME_H_DEFINES_STRUCT_TIMESPEC *=/s/@[^@\n]*@/0/
/^TIME_H_DEFINES_STRUCT_TIMESPEC *=/s/@[^@\n]*@/0/
+/^TIME_H_DEFINES_TIME_UTC *=/s/@[^@\n]*@/0/
+/^UNISTD_H_HAVE_SYS_RANDOM_H *=/s/@[^@\n]*@/0/
/^UNISTD_H_HAVE_WINSOCK2_H *=/s/@[^@\n]*@/0/
/^UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS *=/s/@[^@\n]*@/0/
/^UNISTD_H_DEFINES_STRUCT_TIMESPEC *=/s/@[^@\n]*@/0/
/^UNDEFINE_STRTOK_R *=/s/@UNDEFINE_STRTOK_R@/0/
/^WCHAR_T_SUFFIX *=/s/@WCHAR_T_SUFFIX@/h/
/^WINT_T_SUFFIX *=/s/@WINT_T_SUFFIX@//
+/^GNULIBHEADERS_OVERRIDE_WINT_T *=/s/@[^@\n]*@/0/
/^WINDOWS_64_BIT_OFF_T *=/s/@WINDOWS_64_BIT_OFF_T@/0/
/^WINDOWS_64_BIT_ST_SIZE *=/s/@WINDOWS_64_BIT_ST_SIZE@/0/
/^WINDOWS_STAT_INODES *=/s/@WINDOWS_STAT_INODES@/0/
@@ -337,7 +346,7 @@ s/@PACKAGE@/emacs/
/am__append_[1-9][0-9]* *=.*gettext\.h/s/@[^@\n]*@/\#/
/am__append_2 *=.*verify\.h/s/@[^@\n]*@//
/^@gl_GNULIB_ENABLED_tempname_TRUE@/s/@[^@\n]*@//
-/^gl_LIBOBJS *=/s/@[^@\n]*@/getopt.o getopt1.o memrchr.o sig2str.o time_r.o time_rz.o timegm.o mktime.o getloadavg.o pthread_sigmask.o mkostemp.o fpending.o fdatasync.o execinfo.o/
+/^gl_LIBOBJS *=/s/@[^@\n]*@/getopt.o getopt1.o getrandom.o memrchr.o mempcpy.o regex.o memmem.o sig2str.o sigdescr_np.o time_r.o time_rz.o timegm.o mktime.o mini-gmp-gnulib.o getloadavg.o pthread_sigmask.o mkostemp.o fpending.o execinfo.o tempname.o/
/^am__append_[1-9][0-9]* *=/,/^[^ ]/{
s/ *inttypes\.h//
s| *sys/select\.h||
@@ -394,15 +403,19 @@ s/^ -*test -z.*|| rm/ -rm/
s/@echo /@djecho /
#
# Determine which headers to generate
-s/= @GL_GENERATE_ALLOCA_H@/= 1/
+s/= @GL_GENERATE_ALLOCA_H_TRUE@/= 1/
s/= @GL_GENERATE_BYTESWAP_H@/= 1/
s/= @GL_GENERATE_EXECINFO_H@/= 1/
+s/= @GL_GENERATE_IEEE754_H@/= 1/
s/= @GL_GENERATE_STDALIGN_H@/= 1/
s/= @GL_GENERATE_STDDEF_H@/= 1/
s/= @GL_GENERATE_STDINT_H@/= 1/
s/= @GL_GENERATE_LIMITS_H@/= 1/
s/= @GL_GENERATE_ERRNO_H@/= /
s/= @GL_GENERATE_LIMITS_H@/= /
+s/= @GL_GENERATE_GMP_GMP_H@/= 1/
+s/= @GL_GENERATE_MINI_GMP_H@/= 1/
+s/\$\(MKDIR_P\) malloc//
#
# Determine which modules to build and which to omit
/^noinst_LIBRARIES /a\
@@ -413,6 +426,7 @@ OMIT_GNULIB_MODULE_careadlinkat = true\
OMIT_GNULIB_MODULE_cloexec = true\
OMIT_GNULIB_MODULE_dirent = true\
OMIT_GNULIB_MODULE_dirfd = true\
+OMIT_GNULIB_MODULE_scratch_buffer = true\
OMIT_GNULIB_MODULE_dup2 = true\
OMIT_GNULIB_MODULE_errno = true\
OMIT_GNULIB_MODULE_euidaccess = true\
@@ -439,7 +453,8 @@ OMIT_GNULIB_MODULE_strtoimax = true\
OMIT_GNULIB_MODULE_strtoll = true\
OMIT_GNULIB_MODULE_symlink = true\
OMIT_GNULIB_MODULE_sys_select = true\
-OMIT_GNULIB_MODULE_sys_time = true
+OMIT_GNULIB_MODULE_sys_time = true\
+OMIT_GNULIB_MODULE_crypto\/md5 = true
/^arg-nonnull\.h:/,/^[ ][ ]*mv /c\
arg-nonnull.h: $(top_srcdir)/build-aux/snippet/arg-nonnull.h\
sed -n -e '/GL_ARG_NONNULL/,$$p' < $(top_srcdir)/build-aux/snippet/arg-nonnull.h > $@
diff --git a/nextstep/templates/Info.plist.in b/nextstep/templates/Info.plist.in
index 66cde9f4eeb..f9f0ec08571 100644
--- a/nextstep/templates/Info.plist.in
+++ b/nextstep/templates/Info.plist.in
@@ -555,7 +555,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
<key>UTTypeIdentifier</key>
<string>org.orgmode.org</string>
<key>UTTypeReferenceURL</key>
- <string>http://orgmode.org</string>
+ <string>https://orgmode.org</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
diff --git a/nt/ChangeLog.1 b/nt/ChangeLog.1
index 247f10a7335..d0aed936d19 100644
--- a/nt/ChangeLog.1
+++ b/nt/ChangeLog.1
@@ -222,7 +222,7 @@
as earlier versions. This is so GetVersion and GetVersionEx APIs
used for bug reporting and other purposes return accurate version
number on Windows 8.1. See the discussion on MSDN
- http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
+ https://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
for more details.
2013-12-12 Eli Zaretskii <eliz@gnu.org>
diff --git a/nt/INSTALL b/nt/INSTALL
index 9f543151a94..c324fb4ae7d 100644
--- a/nt/INSTALL
+++ b/nt/INSTALL
@@ -488,6 +488,7 @@ build will run on Windows 9X and newer systems).
Does Emacs use a gif library? yes
Does Emacs use a png library? yes
Does Emacs use -lrsvg-2? yes
+ Does Emacs use -lwebp? yes
Does Emacs use cairo? no
Does Emacs use -llcms2? yes
Does Emacs use imagemagick? no
@@ -597,8 +598,8 @@ build will run on Windows 9X and newer systems).
* Optional image library support
In addition to its "native" image formats (pbm and xbm), Emacs can
- handle other image types: xpm, tiff, gif, png, jpeg and experimental
- support for svg.
+ handle other image types: xpm, tiff, gif, png, jpeg, webp and
+ experimental support for svg.
To build Emacs with support for them, the corresponding headers must
be in the include path and libraries should be where the linker
@@ -736,6 +737,18 @@ build will run on Windows 9X and newer systems).
without it by specifying the --without-rsvg switch to the configure
script.
+ For WebP images you will need libwebp. You can find it here:
+
+ http://sourceforge.net/projects/ezwinports/files/
+
+ Note: the MS-Windows binary distribution on the Google site:
+
+ https://developers.google.com/speed/webp/
+
+ was compiled by MSVC, and includes only static libraries, no DLLs.
+ So you cannot use that to build Emacs with WebP support on
+ MS-Windows, as that needs libwebp as a DLL.
+
Binaries for the other image libraries can be found on the
ezwinports site or at the GnuWin32 project (the latter are generally
very old, so not recommended). Note specifically that, due to some
diff --git a/nt/INSTALL.W64 b/nt/INSTALL.W64
index 8f0d0c9528f..c3845d5b177 100644
--- a/nt/INSTALL.W64
+++ b/nt/INSTALL.W64
@@ -51,6 +51,7 @@ packages (you can copy and paste it into the shell with Shift + Insert):
mingw-w64-x86_64-libpng \
mingw-w64-x86_64-libjpeg-turbo \
mingw-w64-x86_64-librsvg \
+ mingw-w64-x86_64-libwebp \
mingw-w64-x86_64-lcms2 \
mingw-w64-x86_64-jansson \
mingw-w64-x86_64-libxml2 \
diff --git a/nt/Makefile.in b/nt/Makefile.in
index 3274ff924f9..811680da851 100644
--- a/nt/Makefile.in
+++ b/nt/Makefile.in
@@ -144,6 +144,7 @@ LIBS_ADDPM = -lole32 -luuid
## Compilation and linking flags
BASE_CFLAGS = $(C_SWITCH_SYSTEM) $(C_SWITCH_MACHINE) \
$(WARN_CFLAGS) $(WERROR_CFLAGS) \
+ -I../src -I${srcdir}/../src -I../lib -I${srcdir}/../lib \
-I. -I${srcdir}
ALL_CFLAGS = ${BASE_CFLAGS} ${PROFILING_CFLAGS} ${LDFLAGS} ${CPPFLAGS} ${CFLAGS}
diff --git a/nt/README.W32 b/nt/README.W32
index ed5673334ad..495af0baede 100644
--- a/nt/README.W32
+++ b/nt/README.W32
@@ -1,7 +1,7 @@
Copyright (C) 2001-2021 Free Software Foundation, Inc.
See the end of the file for license conditions.
- Emacs version 28.0.50 for MS-Windows
+ Emacs version 29.0.50 for MS-Windows
This README file describes how to set up and run a precompiled
distribution of the latest version of GNU Emacs for MS-Windows. You
diff --git a/nt/addpm.c b/nt/addpm.c
index f54a6ea9f7c..4fbcf6c05ea 100644
--- a/nt/addpm.c
+++ b/nt/addpm.c
@@ -34,6 +34,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
installed, then the DDE fallback for creating icons the Windows 3.1
progman way will be used instead, but that is prone to lockups
caused by other applications not servicing their message queues. */
+
+#define DEFER_MS_W32_H
+#include <config.h>
+
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
diff --git a/nt/cmdproxy.c b/nt/cmdproxy.c
index 224f68b1e85..f5a0550aa9d 100644
--- a/nt/cmdproxy.c
+++ b/nt/cmdproxy.c
@@ -27,6 +27,9 @@ 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/>. */
+#define DEFER_MS_W32_H
+#include <config.h>
+
#include <windows.h>
#include <stdarg.h> /* va_args */
diff --git a/nt/ddeclient.c b/nt/ddeclient.c
index c577bfcfa93..0a44cbfd770 100644
--- a/nt/ddeclient.c
+++ b/nt/ddeclient.c
@@ -16,6 +16,9 @@ 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/>. */
+#define DEFER_MS_W32_H
+#include <config.h>
+
#include <windows.h>
#include <ddeml.h>
#include <stdlib.h>
diff --git a/nt/gnulib-cfg.mk b/nt/gnulib-cfg.mk
index c85b9150f0c..e9f00e748ea 100644
--- a/nt/gnulib-cfg.mk
+++ b/nt/gnulib-cfg.mk
@@ -49,10 +49,14 @@ OMIT_GNULIB_MODULE_dirent = true
OMIT_GNULIB_MODULE_dirfd = true
OMIT_GNULIB_MODULE_fcntl = true
OMIT_GNULIB_MODULE_fcntl-h = true
+OMIT_GNULIB_MODULE_free-posix = true
OMIT_GNULIB_MODULE_fsusage = true
OMIT_GNULIB_MODULE_inttypes-incomplete = true
+OMIT_GNULIB_MODULE_malloc-posix = true
OMIT_GNULIB_MODULE_open = true
OMIT_GNULIB_MODULE_pipe2 = true
+OMIT_GNULIB_MODULE_realloc-gnu = true
+OMIT_GNULIB_MODULE_realloc-posix = true
OMIT_GNULIB_MODULE_secure_getenv = true
OMIT_GNULIB_MODULE_signal-h = true
OMIT_GNULIB_MODULE_stdio = true
@@ -69,3 +73,4 @@ OMIT_GNULIB_MODULE_lchmod = true
OMIT_GNULIB_MODULE_futimens = true
OMIT_GNULIB_MODULE_utimensat = true
OMIT_GNULIB_MODULE_file-has-acl = true
+OMIT_GNULIB_MODULE_nproc = true
diff --git a/nt/preprep.c b/nt/preprep.c
index 78ed1c32381..8b054b19a71 100644
--- a/nt/preprep.c
+++ b/nt/preprep.c
@@ -21,6 +21,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
based on code from addsection.c
*/
+#define DEFER_MS_W32_H
+#include <config.h>
+
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
diff --git a/nt/runemacs.c b/nt/runemacs.c
index 308e856be2a..b4ed9fb1564 100644
--- a/nt/runemacs.c
+++ b/nt/runemacs.c
@@ -40,6 +40,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
/* #define CHOOSE_NEWEST_EXE */
+#define DEFER_MS_W32_H
+#include <config.h>
+
#include <windows.h>
#include <string.h>
#include <malloc.h>
diff --git a/oldXMenu/Activate.c b/oldXMenu/Activate.c
index 91439eacc2f..8ffa817f6c1 100644
--- a/oldXMenu/Activate.c
+++ b/oldXMenu/Activate.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
Copyright (C) 2001-2021 Free Software Foundation, Inc.
diff --git a/oldXMenu/AddPane.c b/oldXMenu/AddPane.c
index e7246f2faa0..8616de804f4 100644
--- a/oldXMenu/AddPane.c
+++ b/oldXMenu/AddPane.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
* XMenu: MIT Project Athena, X Window system menu package
@@ -12,8 +30,8 @@
*
*/
-#include <string.h>
#include "XMenuInt.h"
+#include <string.h>
int
XMenuAddPane(Display *display, register XMenu *menu, register char const *label, int active)
diff --git a/oldXMenu/AddSel.c b/oldXMenu/AddSel.c
index 2a52a6a6c8c..d81c54b8707 100644
--- a/oldXMenu/AddSel.c
+++ b/oldXMenu/AddSel.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
@@ -13,8 +31,8 @@
*
*/
-#include <string.h>
#include "XMenuInt.h"
+#include <string.h>
int
XMenuAddSelection(Display *display, register XMenu *menu, register int p_num, char *data, char *label, int active, char const *help)
diff --git a/oldXMenu/ChgPane.c b/oldXMenu/ChgPane.c
index 733f65950f5..c9c4a5e8a42 100644
--- a/oldXMenu/ChgPane.c
+++ b/oldXMenu/ChgPane.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/ChgSel.c b/oldXMenu/ChgSel.c
index 5a46b5cf587..c26781b014d 100644
--- a/oldXMenu/ChgSel.c
+++ b/oldXMenu/ChgSel.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/Create.c b/oldXMenu/Create.c
index e209bbeceeb..2077a718482 100644
--- a/oldXMenu/Create.c
+++ b/oldXMenu/Create.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
Copyright (C) 1993-1994, 2001-2021 Free Software Foundation, Inc.
diff --git a/oldXMenu/DelPane.c b/oldXMenu/DelPane.c
index 10234e02902..37a2095c55d 100644
--- a/oldXMenu/DelPane.c
+++ b/oldXMenu/DelPane.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/DelSel.c b/oldXMenu/DelSel.c
index ca2ea28c4bd..47cc1685f06 100644
--- a/oldXMenu/DelSel.c
+++ b/oldXMenu/DelSel.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/Destroy.c b/oldXMenu/Destroy.c
index 7f0f6146316..fdaa69b8d1c 100644
--- a/oldXMenu/Destroy.c
+++ b/oldXMenu/Destroy.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/Error.c b/oldXMenu/Error.c
index 01738458b6a..b49e172f0e9 100644
--- a/oldXMenu/Error.c
+++ b/oldXMenu/Error.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/EvHand.c b/oldXMenu/EvHand.c
index bd15359d919..94789c296f0 100644
--- a/oldXMenu/EvHand.c
+++ b/oldXMenu/EvHand.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/FindPane.c b/oldXMenu/FindPane.c
index 8101d009a2f..3e763215ddd 100644
--- a/oldXMenu/FindPane.c
+++ b/oldXMenu/FindPane.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/FindSel.c b/oldXMenu/FindSel.c
index e2a5dbbdcd4..53d14053b3c 100644
--- a/oldXMenu/FindSel.c
+++ b/oldXMenu/FindSel.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
Copyright (C) 2001-2021 Free Software Foundation, Inc.
diff --git a/oldXMenu/InsPane.c b/oldXMenu/InsPane.c
index da92f49aa77..89253e1db0f 100644
--- a/oldXMenu/InsPane.c
+++ b/oldXMenu/InsPane.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/InsSel.c b/oldXMenu/InsSel.c
index f5380437958..527a7a0da85 100644
--- a/oldXMenu/InsSel.c
+++ b/oldXMenu/InsSel.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/Internal.c b/oldXMenu/Internal.c
index 3e97f9ab3f1..476336ce496 100644
--- a/oldXMenu/Internal.c
+++ b/oldXMenu/Internal.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
Copyright (C) 1993, 1996, 2001-2021 Free Software Foundation, Inc.
diff --git a/oldXMenu/Locate.c b/oldXMenu/Locate.c
index 1605b4bbb29..bd126660116 100644
--- a/oldXMenu/Locate.c
+++ b/oldXMenu/Locate.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/Post.c b/oldXMenu/Post.c
index e78fedcf77a..524773673bc 100644
--- a/oldXMenu/Post.c
+++ b/oldXMenu/Post.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/Recomp.c b/oldXMenu/Recomp.c
index 2aec87a51dd..5c129fc5432 100644
--- a/oldXMenu/Recomp.c
+++ b/oldXMenu/Recomp.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/SetAEQ.c b/oldXMenu/SetAEQ.c
index ee2d64b8806..57debf0dd71 100644
--- a/oldXMenu/SetAEQ.c
+++ b/oldXMenu/SetAEQ.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/SetFrz.c b/oldXMenu/SetFrz.c
index c8998eeb66b..eb54dd671ed 100644
--- a/oldXMenu/SetFrz.c
+++ b/oldXMenu/SetFrz.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/SetPane.c b/oldXMenu/SetPane.c
index f29a81c5ca0..b43c777f278 100644
--- a/oldXMenu/SetPane.c
+++ b/oldXMenu/SetPane.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/SetSel.c b/oldXMenu/SetSel.c
index 2f950d49fd6..251b5f95159 100644
--- a/oldXMenu/SetSel.c
+++ b/oldXMenu/SetSel.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/XCrAssoc.c b/oldXMenu/XCrAssoc.c
index 7150cbc53d6..e017cbbbccf 100644
--- a/oldXMenu/XCrAssoc.c
+++ b/oldXMenu/XCrAssoc.c
@@ -1,5 +1,23 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
#include <config.h>
diff --git a/oldXMenu/XDelAssoc.c b/oldXMenu/XDelAssoc.c
index ec1d09d46ec..26a635eef58 100644
--- a/oldXMenu/XDelAssoc.c
+++ b/oldXMenu/XDelAssoc.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
#include "XMenuInt.h"
diff --git a/oldXMenu/XDestAssoc.c b/oldXMenu/XDestAssoc.c
index 94c0454756a..73069444344 100644
--- a/oldXMenu/XDestAssoc.c
+++ b/oldXMenu/XDestAssoc.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
#include "XMenuInt.h"
diff --git a/oldXMenu/XLookAssoc.c b/oldXMenu/XLookAssoc.c
index fad960d7a4c..577e63f42f2 100644
--- a/oldXMenu/XLookAssoc.c
+++ b/oldXMenu/XLookAssoc.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
#include <config.h>
#include <X11/Xlib.h>
diff --git a/oldXMenu/XMakeAssoc.c b/oldXMenu/XMakeAssoc.c
index 2530e8e507b..256d4ebb0e2 100644
--- a/oldXMenu/XMakeAssoc.c
+++ b/oldXMenu/XMakeAssoc.c
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
#include "XMenuInt.h"
diff --git a/oldXMenu/XMenu.h b/oldXMenu/XMenu.h
index 8e4292f5088..50ea6834090 100644
--- a/oldXMenu/XMenu.h
+++ b/oldXMenu/XMenu.h
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/oldXMenu/XMenuInt.h b/oldXMenu/XMenuInt.h
index 369b8c1a4a9..86b8e057cd5 100644
--- a/oldXMenu/XMenuInt.h
+++ b/oldXMenu/XMenuInt.h
@@ -1,6 +1,24 @@
/* Copyright Massachusetts Institute of Technology 1985 */
-#include "copyright.h"
+/*
+
+Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+
/*
diff --git a/src/.gdbinit b/src/.gdbinit
index f74e295f7ea..68db1ff3ea4 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -41,6 +41,11 @@ handle SIGUSR2 noprint pass
# debugging.
handle SIGALRM ignore
+# On selection send failed.
+if defined_HAVE_PGTK
+ handle SIGPIPE nostop noprint
+end
+
# Use $bugfix so that the value isn't a constant.
# Using a constant runs into GDB bugs sometimes.
define xgetptr
@@ -1224,6 +1229,9 @@ set print pretty on
set print sevenbit-strings
show environment DISPLAY
+if defined_HAVE_PGTK
+ show environment WAYLAND_DISPLAY
+end
show environment TERM
# When debugging, it is handy to be able to "return" from
diff --git a/src/ChangeLog.11 b/src/ChangeLog.11
index 41c35babda0..cf5e7b7a2a2 100644
--- a/src/ChangeLog.11
+++ b/src/ChangeLog.11
@@ -22399,7 +22399,7 @@
* Makefile.in (${lispsource}international/charprop.el):
Delete this target.
- * search.c (boyer_moore): Fix incorrect synching of the trunk and
+ * search.c (boyer_moore): Fix incorrect syncing of the trunk and
emacs-unicode-2.
2008-02-11 Stefan Monnier <monnier@iro.umontreal.ca>
@@ -23177,7 +23177,7 @@
2008-02-01 Kenichi Handa <handa@ni.aist.go.jp>
* xfaces.c (face_for_overlay_string): Call lookup_face with
- correct arguments (fix of synching with the trunk).
+ correct arguments (fix of syncing with the trunk).
2008-02-01 Kenichi Handa <handa@m17n.org>
diff --git a/src/Makefile.in b/src/Makefile.in
index 732cd8f0998..ee9a22469ea 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -34,6 +34,7 @@ top_builddir = @top_builddir@
abs_top_srcdir=@abs_top_srcdir@
VPATH = $(srcdir)
CC = @CC@
+CXX = @CXX@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
@@ -55,6 +56,8 @@ lwlibdir = ../lwlib
# Configuration files for .o files to depend on.
config_h = config.h $(srcdir)/conf_post.h
+HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@
+
## ns-app if NS self contained app, else empty.
OTHER_FILES = @OTHER_FILES@
@@ -122,7 +125,7 @@ LIB_MATH=@LIB_MATH@
## -lpthread, or empty.
LIB_PTHREAD=@LIB_PTHREAD@
-LIBIMAGE=@LIBTIFF@ @LIBJPEG@ @LIBPNG@ @LIBGIF@ @LIBXPM@
+LIBIMAGE=@LIBTIFF@ @LIBJPEG@ @LIBPNG@ @LIBGIF@ @LIBXPM@ @WEBP_LIBS@
XCB_LIBS=@XCB_LIBS@
XFT_LIBS=@XFT_LIBS@
@@ -221,6 +224,8 @@ CFLAGS_SOUND= @CFLAGS_SOUND@
RSVG_LIBS= @RSVG_LIBS@
RSVG_CFLAGS= @RSVG_CFLAGS@
+WEBP_CFLAGS= @WEBP_CFLAGS@
+
WEBKIT_LIBS= @WEBKIT_LIBS@
WEBKIT_CFLAGS= @WEBKIT_CFLAGS@
@@ -233,6 +238,8 @@ IMAGEMAGICK_CFLAGS= @IMAGEMAGICK_CFLAGS@
LIBXML2_LIBS = @LIBXML2_LIBS@
LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
+SQLITE3_LIBS = @SQLITE3_LIBS@
+
GETADDRINFO_A_LIBS = @GETADDRINFO_A_LIBS@
LCMS2_LIBS = @LCMS2_LIBS@
@@ -254,6 +261,9 @@ XINERAMA_CFLAGS = @XINERAMA_CFLAGS@
XFIXES_LIBS = @XFIXES_LIBS@
XFIXES_CFLAGS = @XFIXES_CFLAGS@
+XINPUT_LIBS = @XINPUT_LIBS@
+XINPUT_CFLAGS = @XINPUT_CFLAGS@
+
XDBE_LIBS = @XDBE_LIBS@
XDBE_CFLAGS = @XDBE_CFLAGS@
@@ -287,6 +297,9 @@ W32_OBJ=@W32_OBJ@
## -lkernel32 if CYGWIN but not HAVE_W32, else empty.
W32_LIBS=@W32_LIBS@
+PGTK_OBJ=@PGTK_OBJ@
+PGTK_LIBS=@PGTK_LIBS@
+
## emacs.res if HAVE_W32
EMACSRES = @EMACSRES@
## If HAVE_W32, compiler arguments for including
@@ -339,10 +352,17 @@ BUILD_DETAILS = @BUILD_DETAILS@
UNEXEC_OBJ = @UNEXEC_OBJ@
+HAIKU_OBJ = @HAIKU_OBJ@
+HAIKU_CXX_OBJ = @HAIKU_CXX_OBJ@
+HAIKU_LIBS = @HAIKU_LIBS@
+HAIKU_CFLAGS = @HAIKU_CFLAGS@
+
DUMPING=@DUMPING@
CHECK_STRUCTS = @CHECK_STRUCTS@
HAVE_PDUMPER = @HAVE_PDUMPER@
+HAVE_BE_APP = @HAVE_BE_APP@
+
## ARM Macs require that all code have a valid signature. Since pdump
## invalidates the signature, we must re-sign to fix it.
DO_CODESIGN=$(patsubst aarch64-apple-darwin%,yes,@configuration@)
@@ -360,6 +380,9 @@ endif
# Flags that might be in WARN_CFLAGS but are not valid for Objective C.
NON_OBJC_CFLAGS = -Wignored-attributes -Wignored-qualifiers -Wopenmp-simd
+# Ditto, but for C++.
+NON_CXX_CFLAGS = -Wmissing-prototypes -Wnested-externs -Wold-style-definition \
+ -Wstrict-prototypes -Wno-override-init
# -Demacs makes some files produce the correct version for use in Emacs.
# MYCPPFLAGS is for by-hand Emacs-specific overrides, e.g.,
@@ -370,22 +393,26 @@ EMACS_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \
$(GNUSTEP_CFLAGS) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \
$(PNG_CFLAGS) $(LIBXML2_CFLAGS) $(LIBGCCJIT_CFLAGS) $(DBUS_CFLAGS) \
$(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) $(XFIXES_CFLAGS) $(XDBE_CFLAGS) \
- $(WEBKIT_CFLAGS) $(LCMS2_CFLAGS) \
+ $(XINPUT_CFLAGS) $(WEBP_CFLAGS) $(WEBKIT_CFLAGS) $(LCMS2_CFLAGS) \
$(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \
$(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
$(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) \
$(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \
- $(WERROR_CFLAGS)
+ $(WERROR_CFLAGS) $(HAIKU_CFLAGS)
ALL_CFLAGS = $(EMACS_CFLAGS) $(WARN_CFLAGS) $(CFLAGS)
ALL_OBJC_CFLAGS = $(EMACS_CFLAGS) \
$(filter-out $(NON_OBJC_CFLAGS),$(WARN_CFLAGS)) $(CFLAGS) \
$(GNU_OBJC_CFLAGS)
+ALL_CXX_CFLAGS = $(EMACS_CFLAGS) \
+ $(filter-out $(NON_CXX_CFLAGS),$(WARN_CFLAGS)) $(CXXFLAGS)
-.SUFFIXES: .m
+.SUFFIXES: .m .cc
.c.o:
$(AM_V_CC)$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $(PROFILING_CFLAGS) $<
.m.o:
$(AM_V_CC)$(CC) -c $(CPPFLAGS) $(ALL_OBJC_CFLAGS) $(PROFILING_CFLAGS) $<
+.cc.o:
+ $(AM_V_CXX)$(CXX) -c $(CPPFLAGS) $(ALL_CXX_CFLAGS) $(PROFILING_CFLAGS) $<
## lastfile must follow all files whose initialized data areas should
## be dumped as pure by dump-emacs.
@@ -404,11 +431,13 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
doprnt.o intervals.o textprop.o composite.o xml.o lcms.o $(NOTIFY_OBJ) \
$(XWIDGETS_OBJ) \
profiler.o decompress.o \
- thread.o systhread.o \
+ thread.o systhread.o sqlite.o \
$(if $(HYBRID_MALLOC),sheap.o) \
$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
- $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ)
-obj = $(base_obj) $(NS_OBJC_OBJ)
+ $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ) \
+ $(HAIKU_OBJ) $(PGTK_OBJ)
+doc_obj = $(base_obj) $(NS_OBJC_OBJ)
+obj = $(doc_obj) $(HAIKU_CXX_OBJ)
## Object files used on some machine or other.
## These go in the DOC file on all machines in case they are needed.
@@ -422,7 +451,8 @@ SOME_MACHINE_OBJECTS = dosfns.o msdos.o \
w32.o w32console.o w32cygwinx.o w32fns.o w32heap.o w32inevt.o w32notify.o \
w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o \
w16select.o widget.o xfont.o ftfont.o xftfont.o gtkutil.o \
- xsettings.o xgselect.o termcap.o hbfont.o
+ xsettings.o xgselect.o termcap.o hbfont.o \
+ haikuterm.o haikufns.o haikumenu.o haikufont.o
## gmalloc.o if !SYSTEM_MALLOC && !DOUG_LEA_MALLOC, else empty.
GMALLOC_OBJ=@GMALLOC_OBJ@
@@ -448,7 +478,14 @@ FIRSTFILE_OBJ=@FIRSTFILE_OBJ@
ALLOBJS = $(FIRSTFILE_OBJ) $(VMLIMIT_OBJ) $(obj) $(otherobj)
# Must be first, before dep inclusion!
+ifneq ($(HAVE_BE_APP),yes)
all: emacs$(EXEEXT) $(pdmp) $(OTHER_FILES)
+else
+all: Emacs Emacs.pdmp $(OTHER_FILES)
+endif
+ifeq ($(HAVE_NATIVE_COMP):$(NATIVE_DISABLED),yes:)
+all: ../native-lisp
+endif
.PHONY: all
dmpstruct_headers=$(srcdir)/lisp.h $(srcdir)/buffer.h \
@@ -505,7 +542,7 @@ export LISP_PRELOADED = ${shortlisp}
lisp = $(addprefix ${lispsource}/,${shortlisp})
## Construct full set of libraries to be linked.
-LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
+LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(PGTK_LIBS) $(LIBX_BASE) $(LIBIMAGE) \
$(LIBX_OTHER) $(LIBSOUND) \
$(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_ACL) $(LIB_CLOCK_GETTIME) \
$(WEBKIT_LIBS) \
@@ -517,7 +554,8 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
$(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
$(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \
$(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \
- $(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS)
+ $(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) $(XINPUT_LIBS) $(HAIKU_LIBS) \
+ $(SQLITE3_LIBS)
## FORCE it so that admin/unidata can decide whether this file is
## up-to-date. Although since charprop depends on bootstrap-emacs,
@@ -545,7 +583,13 @@ charscript = ${lispintdir}/charscript.el
${charscript}: FORCE
$(MAKE) -C ../admin/unidata $(notdir $@)
-${lispintdir}/characters.elc: ${charscript:.el=.elc}
+emoji-zwj = ${lispintdir}/emoji-zwj.el
+${emoji-zwj}: FORCE
+ $(MAKE) -C ../admin/unidata $(notdir $@)
+
+${lispintdir}/characters.elc: ${charscript:.el=.elc} ${emoji-zwj:.el=.elc}
+
+SYSTEM_TYPE = @SYSTEM_TYPE@
## The dumped Emacs is as functional and more efficient than
## bootstrap-emacs, so we replace the latter with the former.
@@ -555,6 +599,9 @@ ${lispintdir}/characters.elc: ${charscript:.el=.elc}
emacs$(EXEEXT): temacs$(EXEEXT) \
lisp.mk $(etc)/DOC $(lisp) \
$(lispsource)/international/charprop.el ${charsets}
+ifeq ($(SYSTEM_TYPE),cygwin)
+ find ${top_builddir} -name '*.eln' | rebase -v -O -T -
+endif
ifeq ($(DUMPING),unexec)
LC_ALL=C $(RUN_TEMACS) -batch $(BUILD_DETAILS) -l loadup --temacs=dump
ifneq ($(PAXCTL_dumped),)
@@ -565,6 +612,18 @@ else
rm -f $@ && cp -f temacs$(EXEEXT) $@
endif
+## On Haiku, also produce a binary named Emacs with the appropriate
+## icon set.
+
+ifeq ($(HAVE_BE_APP),yes)
+Emacs: emacs$(EXEEXT)
+ cp -f emacs$(EXEEXT) $@
+ $(AM_V_GEN) $(libsrc)/be-resources \
+ $(etc)/images/icons/hicolor/32x32/apps/emacs.png $@
+Emacs.pdmp: $(pdmp)
+ $(AM_V_GEN) cp -f $(pdmp) $@
+endif
+
ifeq ($(DUMPING),pdumper)
$(pdmp): emacs$(EXEEXT)
LC_ALL=C $(RUN_TEMACS) -batch $(BUILD_DETAILS) -l loadup --temacs=pdump \
@@ -583,11 +642,11 @@ endif
## for the first time, this prevents any variation between configurations
## in the contents of the DOC file.
##
-$(etc)/DOC: lisp.mk $(libsrc)/make-docfile$(EXEEXT) $(obj) $(lisp)
+$(etc)/DOC: lisp.mk $(libsrc)/make-docfile$(EXEEXT) $(doc_obj) $(lisp)
$(AM_V_GEN)$(MKDIR_P) $(etc)
$(AM_V_at)rm -f $(etc)/DOC
$(AM_V_at)$(libsrc)/make-docfile -d $(srcdir) \
- $(SOME_MACHINE_OBJECTS) $(obj) > $(etc)/DOC
+ $(SOME_MACHINE_OBJECTS) $(doc_obj) > $(etc)/DOC
$(AM_V_at)$(libsrc)/make-docfile -a $(etc)/DOC -d $(lispsource) \
$(shortlisp)
@@ -605,7 +664,7 @@ buildobj.h: Makefile
GLOBAL_SOURCES = $(base_obj:.o=.c) $(NS_OBJC_OBJ:.o=.m)
gl-stamp: $(libsrc)/make-docfile$(EXEEXT) $(GLOBAL_SOURCES)
- $(AM_V_GLOBALS)$(libsrc)/make-docfile -d $(srcdir) -g $(obj) > globals.tmp
+ $(AM_V_GLOBALS)$(libsrc)/make-docfile -d $(srcdir) -g $(doc_obj) > globals.tmp
$(AM_V_at)$(top_srcdir)/build-aux/move-if-change globals.tmp globals.h
$(AM_V_at)echo timestamp > $@
@@ -629,10 +688,16 @@ endif
## This goes on to affect various things, and the emacs binary fails
## to start if Vinstallation_directory has the wrong value.
temacs$(EXEEXT): $(LIBXMENU) $(ALLOBJS) $(LIBEGNU_ARCHIVE) $(EMACSRES) \
- $(charsets) $(charscript) $(MAKE_PDUMPER_FINGERPRINT)
- $(AM_V_CCLD)$(CC) -o $@.tmp \
+ $(charsets) $(charscript) ${emoji-zwj} $(MAKE_PDUMPER_FINGERPRINT)
+ifeq ($(HAVE_BE_APP),yes)
+ $(AM_V_CXXLD)$(CXX) -o $@.tmp \
$(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
+ $(ALLOBJS) $(LIBEGNU_ARCHIVE) $(W32_RES_LINK) $(LIBES) -lstdc++
+else
+ $(AM_V_CCLD)$(CC) -o $@.tmp \
+ $(ALL_CFLAGS) $(CXXFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
$(ALLOBJS) $(LIBEGNU_ARCHIVE) $(W32_RES_LINK) $(LIBES)
+endif
ifeq ($(HAVE_PDUMPER),yes)
$(AM_V_at)$(MAKE_PDUMPER_FINGERPRINT) $@.tmp
ifeq ($(DO_CODESIGN),yes)
@@ -717,6 +782,7 @@ ${ETAGS}: FORCE
# to be built before we can get TAGS.
ctagsfiles1 = $(filter-out ${srcdir}/macuvs.h, $(wildcard ${srcdir}/*.[hc]))
ctagsfiles2 = $(wildcard ${srcdir}/*.m)
+ctagsfiles3 = $(wildcard ${srcdir}/*.cc)
## In out-of-tree builds, TAGS are generated in the build dir, like
## other non-bootstrap build products (see Bug#31744).
@@ -731,7 +797,8 @@ TAGS: ${ETAGS} $(ctagsfiles1) $(ctagsfiles2)
$(ctagsfiles1) \
--regex='{objc}/[ ]*DEFVAR_[A-Z_ (]+"\([^"]+\)"/\1/' \
--regex='{objc}/[ ]*DEFVAR_[A-Z_ (]+"[^"]+",[ ]\([A-Za-z0-9_]+\)/\1/' \
- $(ctagsfiles2)
+ $(ctagsfiles2) \
+ $(ctagsfiles3)
## Arrange to make tags tables for ../lisp and ../lwlib,
## which the above TAGS file for the C files includes by reference.
@@ -766,6 +833,51 @@ tags: TAGS ../lisp/TAGS $(lwlibdir)/TAGS
@$(MAKE) $(AM_V_NO_PD) -C ../lisp EMACS="$(bootstrap_exe)"\
THEFILE=$< $<c
+ifeq ($(HAVE_NATIVE_COMP):$(NATIVE_DISABLED),yes:)
+## The following rules are used only when building a source tarball
+## for the first time, when the native-lisp/ directory doesn't yet
+## exist and needs to be created and populated with the preloaded
+## *.eln files.
+
+## List of *.eln files we need to produce in addition to the preloaded
+## ones in $(lisp).
+elnlisp := \
+ emacs-lisp/autoload.eln \
+ emacs-lisp/byte-opt.eln \
+ emacs-lisp/bytecomp.eln \
+ emacs-lisp/cconv.eln \
+ international/charscript.eln \
+ emacs-lisp/comp.eln \
+ emacs-lisp/comp-cstr.eln \
+ international/emoji-zwj.eln
+elnlisp := $(addprefix ${lispsource}/,${elnlisp}) $(lisp:.elc=.eln)
+
+%.eln: %.el | emacs$(EXEEXT) $(pdmp)
+ @$(MAKE) $(AM_V_NO_PD) -C ../lisp EMACS="../src/emacs$(EXEEXT)"\
+ THEFILE=$< $<n
+
+## FIXME: this is fragile! We lie to Make about the files produced by
+## this rule, and we rely on the absence of the native-lisp directory
+## to trigger it. This means that if anything goes wrong during
+## native compilation, the only way to trigger it again is to remove
+## the directory and re-native-compile everything. The main
+## underlying problem is that the name of the subdirectory of
+## native-lisp where the *.eln files will be produced, and the exact
+## names of those *.eln files, cannot be known in advance; we must ask
+## Emacs to produce them.
+../native-lisp: | $(pdmp)
+ @if test ! -d $@; then \
+ mkdir $@ && $(MAKE) $(AM_V_NO_PD) $(elnlisp); \
+ if test $(SYSTEM_TYPE) = cygwin; then \
+ find $@ -name '*.eln' | rebase -v -O -T -; \
+ fi; \
+ LC_ALL=C $(RUN_TEMACS) -batch $(BUILD_DETAILS) -l loadup --temacs=pdump \
+ --bin-dest $(BIN_DESTDIR) --eln-dest $(ELN_DESTDIR) \
+ && cp -f emacs$(EXEEXT) bootstrap-emacs$(EXEEXT) \
+ && cp -f $(pdmp) $(bootstrap_pdmp); \
+ fi
+endif
+
## VCSWITNESS points to the file that holds info about the current checkout.
## We use it as a heuristic to decide when to rebuild loaddefs.el.
## If empty it is ignored; the parent makefile can set it to some other value.
@@ -791,6 +903,9 @@ ifeq ($(DUMPING),unexec)
else
@: In the pdumper case, make compile-first after the dump
cp -f temacs$(EXEEXT) bootstrap-emacs$(EXEEXT)
+ifeq ($(DO_CODESIGN),yes)
+ codesign -s - -f bootstrap-emacs$(EXEEXT)
+endif
endif
ifeq ($(DUMPING),pdumper)
diff --git a/src/alloc.c b/src/alloc.c
index 4ea337ddbaa..16f9076b03c 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -125,6 +125,7 @@ union emacs_align_type
struct Lisp_Overlay Lisp_Overlay;
struct Lisp_Sub_Char_Table Lisp_Sub_Char_Table;
struct Lisp_Subr Lisp_Subr;
+ struct Lisp_Sqlite Lisp_Sqlite;
struct Lisp_User_Ptr Lisp_User_Ptr;
struct Lisp_Vector Lisp_Vector;
struct terminal terminal;
@@ -765,7 +766,7 @@ xmalloc (size_t size)
val = lmalloc (size, false);
MALLOC_UNBLOCK_INPUT;
- if (!val && size)
+ if (!val)
memory_full (size);
MALLOC_PROBE (size);
return val;
@@ -782,7 +783,7 @@ xzalloc (size_t size)
val = lmalloc (size, true);
MALLOC_UNBLOCK_INPUT;
- if (!val && size)
+ if (!val)
memory_full (size);
MALLOC_PROBE (size);
return val;
@@ -796,15 +797,15 @@ xrealloc (void *block, size_t size)
void *val;
MALLOC_BLOCK_INPUT;
- /* We must call malloc explicitly when BLOCK is 0, since some
- reallocs don't do this. */
+ /* Call lmalloc when BLOCK is null, for the benefit of long-obsolete
+ platforms lacking support for realloc (NULL, size). */
if (! block)
val = lmalloc (size, false);
else
val = lrealloc (block, size);
MALLOC_UNBLOCK_INPUT;
- if (!val && size)
+ if (!val)
memory_full (size);
MALLOC_PROBE (size);
return val;
@@ -1030,7 +1031,7 @@ lisp_malloc (size_t nbytes, bool clearit, enum mem_type type)
#endif
MALLOC_UNBLOCK_INPUT;
- if (!val && nbytes)
+ if (!val)
memory_full (nbytes);
MALLOC_PROBE (nbytes);
return val;
@@ -1329,16 +1330,20 @@ laligned (void *p, size_t size)
|| size % LISP_ALIGNMENT != 0);
}
-/* Like malloc and realloc except that if SIZE is Lisp-aligned, make
- sure the result is too, if necessary by reallocating (typically
- with larger and larger sizes) until the allocator returns a
- Lisp-aligned pointer. Code that needs to allocate C heap memory
+/* Like malloc and realloc except return null only on failure,
+ the result is Lisp-aligned if SIZE is, and lrealloc's pointer
+ argument must be nonnull. Code allocating C heap memory
for a Lisp object should use one of these functions to obtain a
pointer P; that way, if T is an enum Lisp_Type value and L ==
make_lisp_ptr (P, T), then XPNTR (L) == P and XTYPE (L) == T.
+ If CLEARIT, arrange for the allocated memory to be cleared.
+ This might use calloc, as calloc can be faster than malloc+memset.
+
On typical modern platforms these functions' loops do not iterate.
- On now-rare (and perhaps nonexistent) platforms, the loops in
+ On now-rare (and perhaps nonexistent) platforms, the code can loop,
+ reallocating (typically with larger and larger sizes) until the
+ allocator returns a Lisp-aligned pointer. This loop in
theory could repeat forever. If an infinite loop is possible on a
platform, a build would surely loop and the builder can then send
us a bug report. Adding a counter to try to detect any such loop
@@ -1352,8 +1357,13 @@ lmalloc (size_t size, bool clearit)
if (! MALLOC_IS_LISP_ALIGNED && size % LISP_ALIGNMENT == 0)
{
void *p = aligned_alloc (LISP_ALIGNMENT, size);
- if (clearit && p)
- memclear (p, size);
+ if (p)
+ {
+ if (clearit)
+ memclear (p, size);
+ }
+ else if (! (MALLOC_0_IS_NONNULL || size))
+ return aligned_alloc (LISP_ALIGNMENT, LISP_ALIGNMENT);
return p;
}
#endif
@@ -1361,7 +1371,7 @@ lmalloc (size_t size, bool clearit)
while (true)
{
void *p = clearit ? calloc (1, size) : malloc (size);
- if (laligned (p, size))
+ if (laligned (p, size) && (MALLOC_0_IS_NONNULL || size || p))
return p;
free (p);
size_t bigger = size + LISP_ALIGNMENT;
@@ -1376,7 +1386,7 @@ lrealloc (void *p, size_t size)
while (true)
{
p = realloc (p, size);
- if (laligned (p, size))
+ if (laligned (p, size) && (size || p))
return p;
size_t bigger = size + LISP_ALIGNMENT;
if (size < bigger)
@@ -1929,8 +1939,7 @@ allocate_string_data (struct Lisp_String *s,
The character is at byte offset CIDX_BYTE in the string.
The character being replaced is CLEN bytes long,
and the character that will replace it is NEW_CLEN bytes long.
- Return the address of where the caller should store the
- the new character. */
+ Return the address where the caller should store the new character. */
unsigned char *
resize_string_data (Lisp_Object string, ptrdiff_t cidx_byte,
@@ -3152,26 +3161,26 @@ cleanup_vector (struct Lisp_Vector *vector)
module_finalize_function (function);
}
#endif
- else if (NATIVE_COMP_FLAG
- && PSEUDOVECTOR_TYPEP (&vector->header, PVEC_NATIVE_COMP_UNIT))
+#ifdef HAVE_NATIVE_COMP
+ else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_NATIVE_COMP_UNIT))
{
struct Lisp_Native_Comp_Unit *cu =
PSEUDOVEC_STRUCT (vector, Lisp_Native_Comp_Unit);
unload_comp_unit (cu);
}
- else if (NATIVE_COMP_FLAG
- && PSEUDOVECTOR_TYPEP (&vector->header, PVEC_SUBR))
+ else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_SUBR))
{
struct Lisp_Subr *subr =
PSEUDOVEC_STRUCT (vector, Lisp_Subr);
- if (!NILP (subr->native_comp_u[0]))
+ if (!NILP (subr->native_comp_u))
{
/* FIXME Alternative and non invasive solution to this
cast? */
xfree ((char *)subr->symbol_name);
- xfree (subr->native_c_name[0]);
+ xfree (subr->native_c_name);
}
}
+#endif
}
/* Reclaim space used by unmarked vectors. */
@@ -6136,11 +6145,18 @@ garbage_collect (void)
mark_terminals ();
mark_kboards ();
mark_threads ();
+#ifdef HAVE_PGTK
+ mark_pgtkterm ();
+#endif
#ifdef USE_GTK
xg_mark_data ();
#endif
+#ifdef HAVE_HAIKU
+ mark_haiku_display ();
+#endif
+
#ifdef HAVE_WINDOW_SYSTEM
mark_fringe_data ();
#endif
@@ -6773,15 +6789,17 @@ mark_object (Lisp_Object arg)
break;
case PVEC_SUBR:
+#ifdef HAVE_NATIVE_COMP
if (SUBR_NATIVE_COMPILEDP (obj))
{
set_vector_marked (ptr);
struct Lisp_Subr *subr = XSUBR (obj);
mark_object (subr->native_intspec);
- mark_object (subr->native_comp_u[0]);
- mark_object (subr->lambda_list[0]);
- mark_object (subr->type[0]);
+ mark_object (subr->native_comp_u);
+ mark_object (subr->lambda_list);
+ mark_object (subr->type);
}
+#endif
break;
case PVEC_FREE:
@@ -7706,6 +7724,12 @@ enum defined_HAVE_X_WINDOWS { defined_HAVE_X_WINDOWS = true };
enum defined_HAVE_X_WINDOWS { defined_HAVE_X_WINDOWS = false };
#endif
+#ifdef HAVE_PGTK
+enum defined_HAVE_PGTK { defined_HAVE_PGTK = true };
+#else
+enum defined_HAVE_PGTK { defined_HAVE_PGTK = false };
+#endif
+
/* When compiled with GCC, GDB might say "No enum type named
pvec_type" if we don't have at least one symbol with that type, and
then xbacktrace could fail. Similarly for the other enums and
@@ -7725,5 +7749,6 @@ union
enum More_Lisp_Bits More_Lisp_Bits;
enum pvec_type pvec_type;
enum defined_HAVE_X_WINDOWS defined_HAVE_X_WINDOWS;
+ enum defined_HAVE_PGTK defined_HAVE_PGTK;
} const EXTERNALLY_VISIBLE gdb_make_enums_visible = {0};
#endif /* __GNUC__ */
diff --git a/src/atimer.c b/src/atimer.c
index 9b198675ab4..df35603f324 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -305,18 +305,34 @@ set_alarm (void)
#ifdef HAVE_ITIMERSPEC
if (0 <= timerfd || alarm_timer_ok)
{
+ bool exit = false;
struct itimerspec ispec;
ispec.it_value = atimers->expiration;
ispec.it_interval.tv_sec = ispec.it_interval.tv_nsec = 0;
+ if (alarm_timer_ok
+ && timer_settime (alarm_timer, TIMER_ABSTIME, &ispec, 0) == 0)
+ exit = true;
+
+ /* Don't start both timerfd and POSIX timers on Cygwin; this
+ causes a slowdown (bug#51734). Prefer POSIX timers
+ because the timerfd notifications aren't delivered while
+ Emacs is busy, which prevents things like the hourglass
+ pointer from being displayed reliably (bug#19776). */
+# ifdef CYGWIN
+ if (exit)
+ return;
+# endif
+
# ifdef HAVE_TIMERFD
- if (timerfd_settime (timerfd, TFD_TIMER_ABSTIME, &ispec, 0) == 0)
+ if (0 <= timerfd
+ && timerfd_settime (timerfd, TFD_TIMER_ABSTIME, &ispec, 0) == 0)
{
add_timer_wait_descriptor (timerfd);
- return;
+ exit = true;
}
# endif
- if (alarm_timer_ok
- && timer_settime (alarm_timer, TIMER_ABSTIME, &ispec, 0) == 0)
+
+ if (exit)
return;
}
#endif
@@ -333,9 +349,8 @@ set_alarm (void)
memset (&it, 0, sizeof it);
it.it_value = make_timeval (interval);
setitimer (ITIMER_REAL, &it, 0);
-#else /* not HAVE_SETITIMER */
- alarm (max (interval.tv_sec, 1));
#endif /* not HAVE_SETITIMER */
+ alarm (max (interval.tv_sec, 1));
}
}
@@ -583,15 +598,17 @@ init_atimer (void)
timerfd = (egetenv ("EMACS_IGNORE_TIMERFD") || have_buggy_timerfd () ? -1 :
timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC));
# endif
- if (timerfd < 0)
- {
- struct sigevent sigev;
- sigev.sigev_notify = SIGEV_SIGNAL;
- sigev.sigev_signo = SIGALRM;
- sigev.sigev_value.sival_ptr = &alarm_timer;
- alarm_timer_ok
- = timer_create (CLOCK_REALTIME, &sigev, &alarm_timer) == 0;
- }
+ /* We're starting the alarms even if we have timerfd, because
+ timerfd events do not fire while Emacs Lisp is busy and doesn't
+ call thread_select. This might or might not mean that the
+ timerfd code doesn't really give us anything and should be
+ removed, see discussion in bug#19776. */
+ struct sigevent sigev;
+ sigev.sigev_notify = SIGEV_SIGNAL;
+ sigev.sigev_signo = SIGALRM;
+ sigev.sigev_value.sival_ptr = &alarm_timer;
+ alarm_timer_ok
+ = timer_create (CLOCK_REALTIME, &sigev, &alarm_timer) == 0;
#endif
free_atimers = stopped_atimers = atimers = NULL;
diff --git a/src/bidi.c b/src/bidi.c
index 1413ba6b888..890a60acc43 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -3564,11 +3564,19 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it)
}
/* Utility function for looking for strong directional characters
- whose bidi type was overridden by a directional override. */
+ whose bidi type was overridden by directional override or embedding
+ or isolate control characters. */
ptrdiff_t
bidi_find_first_overridden (struct bidi_it *bidi_it)
{
ptrdiff_t found_pos = ZV;
+ /* Maximum bidi levels we allow for L2R and R2L characters. Note
+ that these are levels after resolving explicit embeddings,
+ overrides, and isolates, i.e. before resolving implicit levels. */
+ int max_l2r = bidi_it->paragraph_dir == L2R ? 0 : 2;
+ int max_r2l = 1;
+ /* Same for WEAK and NEUTRAL_ON types. */
+ int max_weak = bidi_it->paragraph_dir == L2R ? 1 : 2;
do
{
@@ -3576,11 +3584,28 @@ bidi_find_first_overridden (struct bidi_it *bidi_it)
because the directional overrides are applied by the
former. */
bidi_type_t type = bidi_resolve_weak (bidi_it);
+ unsigned level = bidi_it->level_stack[bidi_it->stack_idx].level;
+ bidi_category_t category = bidi_get_category (bidi_it->orig_type);
+ /* Detect strong L or R types that have been overridden by
+ explicit overrides. */
if ((type == STRONG_R && bidi_it->orig_type == STRONG_L)
|| (type == STRONG_L
&& (bidi_it->orig_type == STRONG_R
- || bidi_it->orig_type == STRONG_AL)))
+ || bidi_it->orig_type == STRONG_AL))
+ /* Detect strong L or R types or WEAK_EN types that were
+ pushed into higher embedding levels (and will thus
+ reorder) by explicit embeddings and isolates. */
+ || ((bidi_it->orig_type == STRONG_L
+ || bidi_it->orig_type == WEAK_EN)
+ && level > max_l2r)
+ || ((bidi_it->orig_type == STRONG_R
+ || bidi_it->orig_type == STRONG_AL)
+ && level > max_r2l)
+ /* Detect other weak or neutral types whose level was
+ tweaked by explicit embeddings and isolates. */
+ || ((category == WEAK || bidi_it->orig_type == NEUTRAL_ON)
+ && level > max_weak))
found_pos = bidi_it->charpos;
} while (found_pos == ZV
&& bidi_it->charpos < ZV
diff --git a/src/bignum.c b/src/bignum.c
index 1ac75c19e24..5c587fc6dba 100644
--- a/src/bignum.c
+++ b/src/bignum.c
@@ -53,6 +53,15 @@ init_bignum (void)
{
eassert (mp_bits_per_limb == GMP_NUMB_BITS);
integer_width = 1 << 16;
+
+ /* FIXME: The Info node `(gmp) Custom Allocation' states: "No error
+ return is allowed from any of these functions, if they return
+ then they must have performed the specified operation. [...]
+ There's currently no defined way for the allocation functions to
+ recover from an error such as out of memory, they must terminate
+ program execution. A 'longjmp' or throwing a C++ exception will
+ have undefined results." But xmalloc and xrealloc do call
+ 'longjmp'. */
mp_set_memory_functions (xmalloc, xrealloc_for_gmp, xfree_for_gmp);
for (int i = 0; i < ARRAYELTS (mpz); i++)
diff --git a/src/buffer.c b/src/buffer.c
index 7e4c84911bb..9d8892a797a 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1434,7 +1434,7 @@ and `buffer-file-truename' are non-nil. */)
DEFUN ("restore-buffer-modified-p", Frestore_buffer_modified_p,
Srestore_buffer_modified_p, 1, 1, 0,
doc: /* Like `set-buffer-modified-p', but doesn't redisplay buffer's mode line.
-This function also locks and unlocks the file visited by the buffer,
+This function also locks or unlocks the file visited by the buffer,
if both `buffer-file-truename' and `buffer-file-name' are non-nil.
It is not ensured that mode lines will be updated to show the modified
@@ -1768,6 +1768,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
/* Run hooks with the buffer to be killed as the current buffer. */
{
ptrdiff_t count = SPECPDL_INDEX ();
+ bool modified;
record_unwind_protect_excursion ();
set_buffer_internal (b);
@@ -1782,9 +1783,12 @@ cleaning up all windows currently displaying the buffer to be killed. */)
return unbind_to (count, Qnil);
}
+ /* Is this a modified buffer that's visiting a file? */
+ modified = !NILP (BVAR (b, filename))
+ && BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
+
/* Query if the buffer is still modified. */
- if (INTERACTIVE && !NILP (BVAR (b, filename))
- && BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
+ if (INTERACTIVE && modified)
{
AUTO_STRING (format, "Buffer %s modified; kill anyway? ");
tem = do_yes_or_no_p (CALLN (Fformat, format, BVAR (b, name)));
@@ -1792,6 +1796,23 @@ cleaning up all windows currently displaying the buffer to be killed. */)
return unbind_to (count, Qnil);
}
+ /* Delete the autosave file, if requested. */
+ if (modified
+ && kill_buffer_delete_auto_save_files
+ && delete_auto_save_files
+ && !NILP (Frecent_auto_save_p ())
+ && STRINGP (BVAR (b, auto_save_file_name))
+ && !NILP (Ffile_exists_p (BVAR (b, auto_save_file_name)))
+ /* If `auto-save-visited-mode' is on, then we're auto-saving
+ to the visited file -- don't delete it.. */
+ && NILP (Fstring_equal (BVAR (b, auto_save_file_name),
+ BVAR (b, filename))))
+ {
+ tem = do_yes_or_no_p (build_string ("Delete auto-save file? "));
+ if (!NILP (tem))
+ call0 (intern ("delete-auto-save-file-if-necessary"));
+ }
+
/* If the hooks have killed the buffer, exit now. */
if (!BUFFER_LIVE_P (b))
return unbind_to (count, Qt);
@@ -1888,24 +1909,6 @@ cleaning up all windows currently displaying the buffer to be killed. */)
replace_buffer_in_windows_safely (buffer);
Vinhibit_quit = tem;
- /* Delete any auto-save file, if we saved it in this session.
- But not if the buffer is modified. */
- if (STRINGP (BVAR (b, auto_save_file_name))
- && BUF_AUTOSAVE_MODIFF (b) != 0
- && BUF_SAVE_MODIFF (b) < BUF_AUTOSAVE_MODIFF (b)
- && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
- && NILP (Fsymbol_value (intern ("auto-save-visited-file-name"))))
- {
- Lisp_Object delete;
- delete = Fsymbol_value (intern ("delete-auto-save-files"));
- if (! NILP (delete))
- internal_delete_file (BVAR (b, auto_save_file_name));
- }
-
- /* Deleting an auto-save file could have killed our buffer. */
- if (!BUFFER_LIVE_P (b))
- return Qt;
-
if (b->base_buffer)
{
INTERVAL i;
@@ -2802,7 +2805,7 @@ current buffer is cleared. */)
}
DEFUN ("kill-all-local-variables", Fkill_all_local_variables,
- Skill_all_local_variables, 0, 0, 0,
+ Skill_all_local_variables, 0, 1, 0,
doc: /* Switch to Fundamental mode by killing current buffer's local variables.
Most local variable bindings are eliminated so that the default values
become effective once more. Also, the syntax table is set from
@@ -2813,18 +2816,20 @@ This function also forces redisplay of the mode line.
Every function to select a new major mode starts by
calling this function.
-As a special exception, local variables whose names have
-a non-nil `permanent-local' property are not eliminated by this function.
+As a special exception, local variables whose names have a non-nil
+`permanent-local' property are not eliminated by this function. If
+the optional KILL-PERMANENT argument is non-nil, clear out these local
+variables, too.
The first thing this function does is run
the normal hook `change-major-mode-hook'. */)
- (void)
+ (Lisp_Object kill_permanent)
{
run_hook (Qchange_major_mode_hook);
/* Actually eliminate all local bindings of this buffer. */
- reset_buffer_local_variables (current_buffer, 0);
+ reset_buffer_local_variables (current_buffer, !NILP (kill_permanent));
/* Force mode-line redisplay. Useful here because all major mode
commands call this function. */
@@ -3840,7 +3845,9 @@ fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos)
or the found one ends before PREV,
or the found one is the last one in the list,
we don't have to fix anything. */
- if (!tail || end < prev || !tail->next)
+ if (!tail)
+ return;
+ if (end < prev || !tail->next)
return;
right_pair = parent;
@@ -5802,7 +5809,10 @@ Note that this is overridden by the variable
`truncate-partial-width-windows' if that variable is non-nil
and this buffer is not full-frame width.
-Minibuffers set this variable to nil. */);
+Minibuffers set this variable to nil.
+
+Don't set this to a non-nil value when `visual-line-mode' is
+turned on, as it could produce confusing results. */);
DEFVAR_PER_BUFFER ("word-wrap", &BVAR (current_buffer, word_wrap), Qnil,
doc: /* Non-nil means to use word-wrapping for continuation lines.
@@ -6366,6 +6376,18 @@ nil NORECORD argument since it may lead to infinite recursion. */);
Vbuffer_list_update_hook = Qnil;
DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook");
+ DEFVAR_BOOL ("kill-buffer-delete-auto-save-files",
+ kill_buffer_delete_auto_save_files,
+ doc: /* If non-nil, offer to delete any autosave file when killing a buffer.
+
+If `delete-auto-save-files' is nil, any autosave deletion is inhibited. */);
+ kill_buffer_delete_auto_save_files = 0;
+
+ DEFVAR_BOOL ("delete-auto-save-files", delete_auto_save_files,
+ doc: /* Non-nil means delete auto-save file when a buffer is saved.
+This is the default. If nil, auto-save file deletion is inhibited. */);
+ delete_auto_save_files = 1;
+
defsubr (&Sbuffer_live_p);
defsubr (&Sbuffer_list);
defsubr (&Sget_buffer);
diff --git a/src/buffer.h b/src/buffer.h
index 24e9c3fcbc8..8623bed08e6 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -60,6 +60,14 @@ enum { BEG = 1, BEG_BYTE = BEG };
/* Macros for the addresses of places in the buffer. */
+/* WARNING: Use the 'char *' pointers to buffer text with care in code
+ that could GC: GC can relocate buffer text, invalidating such
+ pointers. It is best to use character or byte position instead,
+ delaying the access through BYTE_POS_ADDR etc. pointers to the
+ latest possible moment. If you must use the 'char *' pointers
+ (e.g., for speed), be sure to adjust them after any call that could
+ potentially GC. */
+
/* Address of beginning of buffer. */
#define BEG_ADDR (current_buffer->text->beg)
@@ -1002,6 +1010,9 @@ SET_BUF_PT_BOTH (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t byte)
or convert between a byte position and an address.
These functions do not check that the position is in range. */
+/* See the important WARNING above about using the 'char *' pointers
+ returned by these functions. */
+
/* Return the address of byte position N in current buffer. */
INLINE unsigned char *
diff --git a/src/callint.c b/src/callint.c
index 6f8a7f13f61..68f103759ae 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -364,11 +364,14 @@ invoke it (via an `interactive' spec that contains, for instance, an
/* The index of the next element of this_command_keys to examine for
the 'e' interactive code. Initialize it to point to the first
- event with parameters. */
- ptrdiff_t next_event;
- for (next_event = 0; next_event < key_count; next_event++)
- if (EVENT_HAS_PARAMETERS (AREF (keys, next_event)))
- break;
+ event with parameters. When `inhibit_mouse_event_check' is non-nil,
+ the command can accept an event without parameters,
+ so don't search for the event with parameters in this case. */
+ ptrdiff_t next_event = 0;
+ if (!inhibit_mouse_event_check)
+ for (; next_event < key_count; next_event++)
+ if (EVENT_HAS_PARAMETERS (AREF (keys, next_event)))
+ break;
/* Handle special starting chars `*' and `@'. Also `-'. */
/* Note that `+' is reserved for user extensions. */
@@ -614,11 +617,15 @@ invoke it (via an `interactive' spec that contains, for instance, an
args[i] = AREF (keys, next_event);
varies[i] = -1;
- /* Find the next parameterized event. */
- do
+ /* `inhibit_mouse_event_check' allows non-parameterized events. */
+ if (inhibit_mouse_event_check)
next_event++;
- while (next_event < key_count
- && ! EVENT_HAS_PARAMETERS (AREF (keys, next_event)));
+ else
+ /* Find the next parameterized event. */
+ do
+ next_event++;
+ while (next_event < key_count
+ && ! EVENT_HAS_PARAMETERS (AREF (keys, next_event)));
break;
@@ -900,6 +907,14 @@ Its purpose is to give temporary modes such as Isearch mode
a way to turn themselves off when a mouse command switches windows. */);
Vmouse_leave_buffer_hook = Qnil;
+ DEFVAR_BOOL ("inhibit-mouse-event-check", inhibit_mouse_event_check,
+ doc: /* Whether the interactive spec "e" requires a mouse gesture event.
+If non-nil, `(interactive "e")' doesn't signal an error when the command
+was invoked by an input event that is not a mouse gesture: a click, a drag,
+etc. To create the event data when the input was some other event,
+use `event-start', `event-end', and `event-click-count'. */);
+ inhibit_mouse_event_check = false;
+
defsubr (&Sinteractive);
defsubr (&Scall_interactively);
defsubr (&Sfuncall_interactively);
diff --git a/src/callproc.c b/src/callproc.c
index 675b78daf3e..c89628bb0ec 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -25,9 +25,27 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <sys/types.h>
#include <unistd.h>
+#ifdef MSDOS
+extern char **environ;
+#endif
+
#include <sys/file.h>
#include <fcntl.h>
+/* In order to be able to use `posix_spawn', it needs to support some
+ variant of `chdir' as well as `setsid'. */
+#if defined HAVE_SPAWN_H && defined HAVE_POSIX_SPAWN \
+ && defined HAVE_POSIX_SPAWNATTR_SETFLAGS \
+ && (defined HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR \
+ || defined HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP) \
+ && defined HAVE_DECL_POSIX_SPAWN_SETSID \
+ && HAVE_DECL_POSIX_SPAWN_SETSID == 1
+# include <spawn.h>
+# define USABLE_POSIX_SPAWN 1
+#else
+# define USABLE_POSIX_SPAWN 0
+#endif
+
#include "lisp.h"
#ifdef SETUP_SLAVE_PTY
@@ -232,6 +250,8 @@ directory where the process is run (see below). If you want to make the
input come from an Emacs buffer, use `call-process-region' instead.
Third argument DESTINATION specifies how to handle program's output.
+(\"Output\" here means both standard output and standard error
+output.)
If DESTINATION is a buffer, or t that stands for the current buffer,
it means insert output in that buffer before point.
If DESTINATION is nil, it means discard output; 0 means discard
@@ -1183,6 +1203,11 @@ static CHILD_SETUP_TYPE
child_setup (int in, int out, int err, char **new_argv, char **env,
const char *current_dir)
{
+#ifdef MSDOS
+ char *pwd_var;
+ char *temp;
+ ptrdiff_t i;
+#endif
#ifdef WINDOWSNT
int cpid;
HANDLE handles[3];
@@ -1235,6 +1260,22 @@ child_setup (int in, int out, int err, char **new_argv, char **env,
exec_failed (new_argv[0], errnum);
#else /* MSDOS */
+ i = strlen (current_dir);
+ pwd_var = xmalloc (i + 5);
+ temp = pwd_var + 4;
+ memcpy (pwd_var, "PWD=", 4);
+ stpcpy (temp, current_dir);
+
+ if (i > 2 && IS_DEVICE_SEP (temp[1]) && IS_DIRECTORY_SEP (temp[2]))
+ {
+ temp += 2;
+ i -= 2;
+ }
+
+ /* Strip trailing slashes for PWD, but leave "/" and "//" alone. */
+ while (i > 2 && IS_DIRECTORY_SEP (temp[i - 1]))
+ temp[--i] = 0;
+
pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env);
xfree (pwd_var);
if (pid == -1)
@@ -1245,6 +1286,130 @@ child_setup (int in, int out, int err, char **new_argv, char **env,
#endif /* not WINDOWSNT */
}
+#if USABLE_POSIX_SPAWN
+
+/* Set up ACTIONS and ATTRIBUTES for `posix_spawn'. Return an error
+ number. */
+
+static int
+emacs_posix_spawn_init_actions (posix_spawn_file_actions_t *actions,
+ int std_in, int std_out, int std_err,
+ const char *cwd)
+{
+ int error = posix_spawn_file_actions_init (actions);
+ if (error != 0)
+ return error;
+
+ error = posix_spawn_file_actions_adddup2 (actions, std_in,
+ STDIN_FILENO);
+ if (error != 0)
+ goto out;
+
+ error = posix_spawn_file_actions_adddup2 (actions, std_out,
+ STDOUT_FILENO);
+ if (error != 0)
+ goto out;
+
+ error = posix_spawn_file_actions_adddup2 (actions,
+ std_err < 0 ? std_out
+ : std_err,
+ STDERR_FILENO);
+ if (error != 0)
+ goto out;
+
+ error =
+#ifdef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR
+ posix_spawn_file_actions_addchdir
+#else
+ posix_spawn_file_actions_addchdir_np
+#endif
+ (actions, cwd);
+ if (error != 0)
+ goto out;
+
+ out:
+ if (error != 0)
+ posix_spawn_file_actions_destroy (actions);
+ return error;
+}
+
+static int
+emacs_posix_spawn_init_attributes (posix_spawnattr_t *attributes)
+{
+ int error = posix_spawnattr_init (attributes);
+ if (error != 0)
+ return error;
+
+ error = posix_spawnattr_setflags (attributes,
+ POSIX_SPAWN_SETSID
+ | POSIX_SPAWN_SETSIGDEF
+ | POSIX_SPAWN_SETSIGMASK);
+ if (error != 0)
+ goto out;
+
+ sigset_t sigdefault;
+ sigemptyset (&sigdefault);
+
+#ifdef DARWIN_OS
+ /* Work around a macOS bug, where SIGCHLD is apparently
+ delivered to a vforked child instead of to its parent. See:
+ https://lists.gnu.org/r/emacs-devel/2017-05/msg00342.html
+ */
+ sigaddset (&sigdefault, SIGCHLD);
+#endif
+
+ sigaddset (&sigdefault, SIGINT);
+ sigaddset (&sigdefault, SIGQUIT);
+#ifdef SIGPROF
+ sigaddset (&sigdefault, SIGPROF);
+#endif
+
+ /* Emacs ignores SIGPIPE, but the child should not. */
+ sigaddset (&sigdefault, SIGPIPE);
+ /* Likewise for SIGPROF. */
+#ifdef SIGPROF
+ sigaddset (&sigdefault, SIGPROF);
+#endif
+
+ error = posix_spawnattr_setsigdefault (attributes, &sigdefault);
+ if (error != 0)
+ goto out;
+
+ /* Stop blocking SIGCHLD in the child. */
+ sigset_t oldset;
+ error = pthread_sigmask (SIG_SETMASK, NULL, &oldset);
+ if (error != 0)
+ goto out;
+ error = posix_spawnattr_setsigmask (attributes, &oldset);
+ if (error != 0)
+ goto out;
+
+ out:
+ if (error != 0)
+ posix_spawnattr_destroy (attributes);
+
+ return error;
+}
+
+static int
+emacs_posix_spawn_init (posix_spawn_file_actions_t *actions,
+ posix_spawnattr_t *attributes, int std_in,
+ int std_out, int std_err, const char *cwd)
+{
+ int error = emacs_posix_spawn_init_actions (actions, std_in,
+ std_out, std_err, cwd);
+ if (error != 0)
+ return error;
+
+ error = emacs_posix_spawn_init_attributes (attributes);
+ if (error != 0)
+ return error;
+
+ return 0;
+}
+
+#endif
+
/* Start a new asynchronous subprocess. If successful, return zero
and store the process identifier of the new process in *NEWPID.
Use STDIN, STDOUT, and STDERR as standard streams for the new
@@ -1264,10 +1429,58 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err,
char **argv, char **envp, const char *cwd,
const char *pty, const sigset_t *oldset)
{
+#if USABLE_POSIX_SPAWN
+ /* Prefer the simpler `posix_spawn' if available. `posix_spawn'
+ doesn't yet support setting up pseudoterminals, so we fall back
+ to `vfork' if we're supposed to use a pseudoterminal. */
+
+ bool use_posix_spawn = pty == NULL;
+
+ posix_spawn_file_actions_t actions;
+ posix_spawnattr_t attributes;
+
+ if (use_posix_spawn)
+ {
+ /* Initialize optional attributes before blocking. */
+ int error
+ = emacs_posix_spawn_init (&actions, &attributes, std_in,
+ std_out, std_err, cwd);
+ if (error != 0)
+ return error;
+ }
+#endif
+
int pid;
+ int vfork_error;
eassert (input_blocked_p ());
+#if USABLE_POSIX_SPAWN
+ if (use_posix_spawn)
+ {
+ vfork_error = posix_spawn (&pid, argv[0], &actions, &attributes,
+ argv, envp);
+ if (vfork_error != 0)
+ pid = -1;
+
+ int error = posix_spawn_file_actions_destroy (&actions);
+ if (error != 0)
+ {
+ errno = error;
+ emacs_perror ("posix_spawn_file_actions_destroy");
+ }
+
+ error = posix_spawnattr_destroy (&attributes);
+ if (error != 0)
+ {
+ errno = error;
+ emacs_perror ("posix_spawnattr_destroy");
+ }
+
+ goto fork_done;
+ }
+#endif
+
#ifndef WINDOWSNT
/* vfork, and prevent local vars from being clobbered by the vfork. */
pid_t *volatile newpid_volatile = newpid;
@@ -1394,11 +1607,13 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err,
signal (SIGPROF, SIG_DFL);
#endif
+#ifdef subprocesses
/* Stop blocking SIGCHLD in the child. */
unblock_child_signal (oldset);
if (pty_flag)
child_setup_tty (std_out);
+#endif
if (std_err < 0)
std_err = std_out;
@@ -1411,8 +1626,11 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err,
/* Back in the parent process. */
- int vfork_error = pid < 0 ? errno : 0;
+ vfork_error = pid < 0 ? errno : 0;
+#if USABLE_POSIX_SPAWN
+ fork_done:
+#endif
if (pid < 0)
{
eassert (0 < vfork_error);
diff --git a/src/casefiddle.c b/src/casefiddle.c
index a7a25414909..81e9ed153fb 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -54,6 +54,9 @@ struct casing_context
/* Whether the context is within a word. */
bool inword;
+
+ /* What the last operation was. */
+ bool downcase_last;
};
/* Initialize CTX structure for casing characters. */
@@ -143,10 +146,14 @@ case_character_impl (struct casing_str_buf *buf,
/* Handle simple, one-to-one case. */
if (flag == CASE_DOWN)
- cased = downcase (ch);
+ {
+ cased = downcase (ch);
+ ctx->downcase_last = true;
+ }
else
{
bool cased_is_set = false;
+ ctx->downcase_last = false;
if (!NILP (ctx->titlecase_char_table))
{
prop = CHAR_TABLE_REF (ctx->titlecase_char_table, ch);
@@ -297,6 +304,16 @@ do_casify_multibyte_string (struct casing_context *ctx, Lisp_Object obj)
return obj;
}
+static int
+ascii_casify_character (bool downcase, int c)
+{
+ Lisp_Object cased = CHAR_TABLE_REF (downcase?
+ uniprop_table (Qlowercase) :
+ uniprop_table (Quppercase),
+ c);
+ return FIXNATP (cased) ? XFIXNAT (cased) : c;
+}
+
static Lisp_Object
do_casify_unibyte_string (struct casing_context *ctx, Lisp_Object obj)
{
@@ -310,11 +327,12 @@ do_casify_unibyte_string (struct casing_context *ctx, Lisp_Object obj)
cased = case_single_character (ctx, ch);
if (ch == cased)
continue;
- cased = make_char_unibyte (cased);
- /* If the char can't be converted to a valid byte, just don't
- change it. */
- if (SINGLE_BYTE_CHAR_P (cased))
- SSET (obj, i, cased);
+ /* If down/upcasing changed an ASCII character into a non-ASCII
+ character (this can happen in some locales, like the Turkish
+ "I"), downcase using the ASCII char table. */
+ if (ASCII_CHAR_P (ch) && !SINGLE_BYTE_CHAR_P (cased))
+ cased = ascii_casify_character (ctx->downcase_last, ch);
+ SSET (obj, i, make_char_unibyte (cased));
}
return obj;
}
@@ -339,10 +357,13 @@ casify_object (enum case_action flag, Lisp_Object obj)
DEFUN ("upcase", Fupcase, Supcase, 1, 1, 0,
doc: /* Convert argument to upper case and return that.
-The argument may be a character or string. The result has the same type.
+The argument may be a character or string. The result has the same
+type. (See `downcase' for further details about the type.)
+
The argument object is not altered--the value is a copy. If argument
is a character, characters which map to multiple code points when
cased, e.g. fi, are returned unchanged.
+
See also `capitalize', `downcase' and `upcase-initials'. */)
(Lisp_Object obj)
{
@@ -351,7 +372,15 @@ See also `capitalize', `downcase' and `upcase-initials'. */)
DEFUN ("downcase", Fdowncase, Sdowncase, 1, 1, 0,
doc: /* Convert argument to lower case and return that.
-The argument may be a character or string. The result has the same type.
+The argument may be a character or string. The result has the same type,
+including the multibyteness of the string.
+
+This means that if this function is called with a unibyte string
+argument, and downcasing it would turn it into a multibyte string
+(according to the current locale), the downcasing is done using ASCII
+\"C\" rules instead. To accurately downcase according to the current
+locale, the string must be converted into multibyte first.
+
The argument object is not altered--the value is a copy. */)
(Lisp_Object obj)
{
@@ -362,7 +391,10 @@ DEFUN ("capitalize", Fcapitalize, Scapitalize, 1, 1, 0,
doc: /* Convert argument to capitalized form and return that.
This means that each word's first character is converted to either
title case or upper case, and the rest to lower case.
-The argument may be a character or string. The result has the same type.
+
+The argument may be a character or string. The result has the same
+type. (See `downcase' for further details about the type.)
+
The argument object is not altered--the value is a copy. If argument
is a character, characters which map to multiple code points when
cased, e.g. fi, are returned unchanged. */)
@@ -377,7 +409,10 @@ DEFUN ("upcase-initials", Fupcase_initials, Supcase_initials, 1, 1, 0,
doc: /* Convert the initial of each word in the argument to upper case.
This means that each word's first character is converted to either
title case or upper case, and the rest are left unchanged.
-The argument may be a character or string. The result has the same type.
+
+The argument may be a character or string. The result has the same
+type. (See `downcase' for further details about the type.)
+
The argument object is not altered--the value is a copy. If argument
is a character, characters which map to multiple code points when
cased, e.g. fi, are returned unchanged. */)
@@ -651,6 +686,8 @@ syms_of_casefiddle (void)
DEFSYM (Qbounds, "bounds");
DEFSYM (Qidentity, "identity");
DEFSYM (Qtitlecase, "titlecase");
+ DEFSYM (Qlowercase, "lowercase");
+ DEFSYM (Quppercase, "uppercase");
DEFSYM (Qspecial_uppercase, "special-uppercase");
DEFSYM (Qspecial_lowercase, "special-lowercase");
DEFSYM (Qspecial_titlecase, "special-titlecase");
diff --git a/src/character.h b/src/character.h
index 1a745484daa..6ee6bcab205 100644
--- a/src/character.h
+++ b/src/character.h
@@ -82,6 +82,8 @@ enum
LEFT_ANGLE_BRACKET = 0x3008,
RIGHT_ANGLE_BRACKET = 0x3009,
OBJECT_REPLACEMENT_CHARACTER = 0xFFFC,
+ TAG_SPACE = 0xE0020,
+ CANCEL_TAG = 0xE007F,
};
extern int char_string (unsigned, unsigned char *);
diff --git a/src/charset.c b/src/charset.c
index 7cd0fa78f04..670fd48a2d9 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -63,7 +63,7 @@ Lisp_Object Vcharset_hash_table;
/* Table of struct charset. */
struct charset *charset_table;
int charset_table_size;
-static int charset_table_used;
+int charset_table_used;
/* Special charsets corresponding to symbols. */
int charset_ascii;
diff --git a/src/charset.h b/src/charset.h
index 97122d82a65..8c538234d8d 100644
--- a/src/charset.h
+++ b/src/charset.h
@@ -249,6 +249,7 @@ extern Lisp_Object Vcharset_hash_table;
/* Table of struct charset. */
extern struct charset *charset_table;
extern int charset_table_size;
+extern int charset_table_used;
#define CHARSET_FROM_ID(id) (charset_table + (id))
diff --git a/src/coding.c b/src/coding.c
index d027c7d5399..f8004d202e5 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -9454,12 +9454,14 @@ code_convert_region (Lisp_Object start, Lisp_Object end,
DEFUN ("decode-coding-region", Fdecode_coding_region, Sdecode_coding_region,
3, 4, "r\nzCoding system: ",
- doc: /* Decode the current region from the specified coding system.
-
-What's meant by \"decoding\" is transforming bytes into text
-(characters). If, for instance, you have a region that contains data
-that represents the two bytes #xc2 #xa9, after calling this function
-with the utf-8 coding system, the region will contain the single
+ doc: /* Decode the current region using the specified coding system.
+Interactively, prompt for the coding system to decode the region, and
+replace the region with the decoded text.
+
+\"Decoding\" means transforming bytes into readable text (characters).
+If, for instance, you have a region that contains data that represents
+the two bytes #xc2 #xa9, after calling this function with the utf-8
+coding system, the region will contain the single
character ?\\N{COPYRIGHT SIGN}.
When called from a program, takes four arguments:
@@ -9484,7 +9486,9 @@ not fully specified.) */)
DEFUN ("encode-coding-region", Fencode_coding_region, Sencode_coding_region,
3, 4, "r\nzCoding system: ",
- doc: /* Encode the current region by specified coding system.
+ doc: /* Encode the current region using th specified coding system.
+Interactively, prompt for the coding system to encode the region, and
+replace the region with the bytes that are the result of the encoding.
What's meant by \"encoding\" is transforming textual data (characters)
into bytes. If, for instance, you have a region that contains the
@@ -10430,8 +10434,7 @@ encode_file_name (Lisp_Object fname)
cause subtle bugs because the system would silently use a
different filename than expected. Perform this check after
encoding to not miss NUL bytes introduced through encoding. */
- CHECK_TYPE (memchr (SSDATA (encoded), '\0', SBYTES (encoded)) == NULL,
- Qfilenamep, fname);
+ CHECK_STRING_NULL_BYTES (encoded);
return encoded;
}
diff --git a/src/comp.c b/src/comp.c
index c3803464827..1fb384840cf 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -71,6 +71,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#undef gcc_jit_context_new_binary_op
#undef gcc_jit_context_new_call
#undef gcc_jit_context_new_call_through_ptr
+#undef gcc_jit_context_new_cast
#undef gcc_jit_context_new_comparison
#undef gcc_jit_context_new_field
#undef gcc_jit_context_new_function
@@ -151,8 +152,10 @@ DEF_DLL_FN (gcc_jit_lvalue *, gcc_jit_context_new_global,
DEF_DLL_FN (gcc_jit_lvalue *, gcc_jit_function_new_local,
(gcc_jit_function *func, gcc_jit_location *loc, gcc_jit_type *type,
const char *name));
+#if defined (LIBGCCJIT_HAVE_gcc_jit_global_set_initializer)
DEF_DLL_FN (gcc_jit_lvalue *, gcc_jit_global_set_initializer,
(gcc_jit_lvalue *global, const void *blob, size_t num_bytes));
+#endif
DEF_DLL_FN (gcc_jit_lvalue *, gcc_jit_lvalue_access_field,
(gcc_jit_lvalue *struct_or_union, gcc_jit_location *loc,
gcc_jit_field *field));
@@ -176,6 +179,9 @@ DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_call,
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));
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));
@@ -255,9 +261,11 @@ DEF_DLL_FN (void, gcc_jit_context_set_str_option,
DEF_DLL_FN (void, gcc_jit_struct_set_fields,
(gcc_jit_struct *struct_type, gcc_jit_location *loc, int num_fields,
gcc_jit_field **fields));
+#if defined (LIBGCCJIT_HAVE_gcc_jit_version)
DEF_DLL_FN (int, gcc_jit_version_major, (void));
DEF_DLL_FN (int, gcc_jit_version_minor, (void));
DEF_DLL_FN (int, gcc_jit_version_patchlevel, (void));
+#endif
static bool
init_gccjit_functions (void)
@@ -288,6 +296,7 @@ init_gccjit_functions (void)
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);
+ LOAD_DLL_FN (library, gcc_jit_context_new_cast);
LOAD_DLL_FN (library, gcc_jit_context_new_comparison);
LOAD_DLL_FN (library, gcc_jit_context_new_field);
LOAD_DLL_FN (library, gcc_jit_context_new_function);
@@ -327,10 +336,14 @@ init_gccjit_functions (void)
LOAD_DLL_FN (library, gcc_jit_type_get_pointer);
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)
LOAD_DLL_FN_OPT (library, gcc_jit_global_set_initializer);
+#endif
+#if defined (LIBGCCJIT_HAVE_gcc_jit_version)
LOAD_DLL_FN_OPT (library, gcc_jit_version_major);
LOAD_DLL_FN_OPT (library, gcc_jit_version_minor);
LOAD_DLL_FN_OPT (library, gcc_jit_version_patchlevel);
+#endif
return true;
}
@@ -358,6 +371,7 @@ init_gccjit_functions (void)
#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
+#define gcc_jit_context_new_cast fn_gcc_jit_context_new_cast
#define gcc_jit_context_new_comparison fn_gcc_jit_context_new_comparison
#define gcc_jit_context_new_field fn_gcc_jit_context_new_field
#define gcc_jit_context_new_function fn_gcc_jit_context_new_function
@@ -382,7 +396,9 @@ init_gccjit_functions (void)
#define gcc_jit_function_get_param fn_gcc_jit_function_get_param
#define gcc_jit_function_new_block fn_gcc_jit_function_new_block
#define gcc_jit_function_new_local fn_gcc_jit_function_new_local
-#define gcc_jit_global_set_initializer fn_gcc_jit_global_set_initializer
+#if defined (LIBGCCJIT_HAVE_gcc_jit_global_set_initializer)
+ #define gcc_jit_global_set_initializer fn_gcc_jit_global_set_initializer
+#endif
#define gcc_jit_lvalue_access_field fn_gcc_jit_lvalue_access_field
#define gcc_jit_lvalue_as_rvalue fn_gcc_jit_lvalue_as_rvalue
#define gcc_jit_lvalue_get_address fn_gcc_jit_lvalue_get_address
@@ -396,9 +412,11 @@ init_gccjit_functions (void)
#define gcc_jit_struct_set_fields fn_gcc_jit_struct_set_fields
#define gcc_jit_type_get_const fn_gcc_jit_type_get_const
#define gcc_jit_type_get_pointer fn_gcc_jit_type_get_pointer
-#define gcc_jit_version_major fn_gcc_jit_version_major
-#define gcc_jit_version_minor fn_gcc_jit_version_minor
-#define gcc_jit_version_patchlevel fn_gcc_jit_version_patchlevel
+#if defined (LIBGCCJIT_HAVE_gcc_jit_version)
+ #define gcc_jit_version_major fn_gcc_jit_version_major
+ #define gcc_jit_version_minor fn_gcc_jit_version_minor
+ #define gcc_jit_version_patchlevel fn_gcc_jit_version_patchlevel
+#endif
#endif
@@ -499,13 +517,6 @@ static f_reloc_t freloc;
#define NUM_CAST_TYPES 15
-enum cast_kind_of_type
- {
- kind_unsigned,
- kind_signed,
- kind_pointer
- };
-
typedef struct {
EMACS_INT len;
gcc_jit_rvalue *r_val;
@@ -516,6 +527,7 @@ typedef struct {
typedef struct {
EMACS_INT speed;
EMACS_INT debug;
+ Lisp_Object compiler_options;
Lisp_Object driver_options;
gcc_jit_context *ctxt;
gcc_jit_type *void_type;
@@ -571,14 +583,9 @@ typedef struct {
be used for the scope. */
gcc_jit_type *cast_union_type;
gcc_jit_function *cast_functions_from_to[NUM_CAST_TYPES][NUM_CAST_TYPES];
- /* We add one to make space for the last member which is the "biggest_type"
- member. */
- gcc_jit_type *cast_types[NUM_CAST_TYPES + 1];
- size_t cast_type_sizes[NUM_CAST_TYPES + 1];
- enum cast_kind_of_type cast_type_kind[NUM_CAST_TYPES + 1];
- const char *cast_type_names[NUM_CAST_TYPES + 1];
- gcc_jit_field *cast_union_fields[NUM_CAST_TYPES + 1];
- size_t cast_union_field_biggest_type;
+ gcc_jit_function *cast_ptr_to_int;
+ gcc_jit_function *cast_int_to_ptr;
+ gcc_jit_type *cast_types[NUM_CAST_TYPES];
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. */
@@ -698,6 +705,12 @@ comp_hash_source_file (Lisp_Object filename)
/* Can't use Finsert_file_contents + Fbuffer_hash as this is called
by Fcomp_el_to_eln_filename too early during bootstrap. */
bool is_gz = suffix_p (filename, ".gz");
+#ifndef HAVE_ZLIB
+ if (is_gz)
+ xsignal2 (Qfile_notify_error,
+ build_string ("Cannot natively compile compressed *.el files without zlib support"),
+ filename);
+#endif
Lisp_Object encoded_filename = ENCODE_FILE (filename);
FILE *f = emacs_fopen (SSDATA (encoded_filename), is_gz ? "rb" : "r");
@@ -706,9 +719,13 @@ comp_hash_source_file (Lisp_Object filename)
Lisp_Object digest = make_uninit_string (MD5_DIGEST_SIZE * 2);
+#ifdef HAVE_ZLIB
int res = is_gz
? md5_gz_stream (f, SSDATA (digest))
: md5_stream (f, SSDATA (digest));
+#else
+ int res = md5_stream (f, SSDATA (digest));
+#endif
fclose (f);
if (res)
@@ -1113,13 +1130,6 @@ emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj)
int old_index = type_to_cast_index (old_type);
int new_index = type_to_cast_index (new_type);
- if (comp.cast_type_sizes[old_index] < comp.cast_type_sizes[new_index]
- && comp.cast_type_kind[new_index] == kind_signed)
- xsignal3 (Qnative_ice,
- build_string ("FIXME: sign extension not implemented"),
- build_string (comp.cast_type_names[old_index]),
- build_string (comp.cast_type_names[new_index]));
-
/* Lookup the appropriate cast function in the cast matrix. */
return gcc_jit_context_new_call (comp.ctxt,
NULL,
@@ -2493,8 +2503,7 @@ emit_static_object (const char *name, Lisp_Object obj)
ptrdiff_t len = SBYTES (str);
const char *p = SSDATA (str);
-#if defined (LIBGCCJIT_HAVE_gcc_jit_global_set_initializer) \
- || defined (WINDOWSNT)
+#if defined (LIBGCCJIT_HAVE_gcc_jit_global_set_initializer)
if (gcc_jit_global_set_initializer)
{
ptrdiff_t str_size = len + 1;
@@ -3111,30 +3120,17 @@ define_thread_state_struct (void)
gcc_jit_type_get_pointer (gcc_jit_struct_as_type (comp.thread_state_s));
}
-struct cast_type
-{
- gcc_jit_type *type;
- const char *name;
- size_t bytes_size;
- enum cast_kind_of_type kind;
-};
-
static gcc_jit_function *
-define_cast_from_to (struct cast_type from, int from_index, struct cast_type to,
- int to_index)
+define_type_punning (const char *name,
+ gcc_jit_type *from, gcc_jit_field *from_field,
+ gcc_jit_type *to, gcc_jit_field *to_field)
{
- /* FIXME: sign extension not implemented. */
- if (comp.cast_type_sizes[from_index] < comp.cast_type_sizes[to_index]
- && comp.cast_type_kind[to_index] == kind_signed)
- return NULL;
-
- char *name = format_string ("cast_from_%s_to_%s", from.name, to.name);
gcc_jit_param *param = gcc_jit_context_new_param (comp.ctxt, NULL,
- from.type, "arg");
+ from, "arg");
gcc_jit_function *result = gcc_jit_context_new_function (comp.ctxt,
NULL,
GCC_JIT_FUNCTION_INTERNAL,
- to.type,
+ to,
name,
1,
&param,
@@ -3148,26 +3144,63 @@ define_cast_from_to (struct cast_type from, int from_index, struct cast_type to,
comp.cast_union_type,
"union_cast");
- /* Zero the union first. */
- gcc_jit_block_add_assignment (entry_block, NULL,
- gcc_jit_lvalue_access_field (tmp_union, NULL,
- comp.cast_union_fields[NUM_CAST_TYPES]),
- gcc_jit_context_new_rvalue_from_int (
- comp.ctxt,
- comp.cast_types[NUM_CAST_TYPES],
- 0));
-
gcc_jit_block_add_assignment (entry_block, NULL,
gcc_jit_lvalue_access_field (tmp_union, NULL,
- comp.cast_union_fields[from_index]),
+ from_field),
gcc_jit_param_as_rvalue (param));
gcc_jit_block_end_with_return (entry_block,
NULL,
gcc_jit_rvalue_access_field (
gcc_jit_lvalue_as_rvalue (tmp_union),
- NULL,
- comp.cast_union_fields[to_index]));
+ NULL, to_field));
+
+ return result;
+}
+
+struct cast_type
+{
+ gcc_jit_type *type;
+ const char *name;
+ bool is_ptr;
+};
+
+static gcc_jit_function *
+define_cast_from_to (struct cast_type from, struct cast_type to)
+{
+ char *name = format_string ("cast_from_%s_to_%s", from.name, to.name);
+ gcc_jit_param *param = gcc_jit_context_new_param (comp.ctxt, NULL,
+ from.type, "arg");
+ gcc_jit_function *result
+ = gcc_jit_context_new_function (comp.ctxt,
+ NULL,
+ GCC_JIT_FUNCTION_INTERNAL,
+ to.type, name,
+ 1, &param, 0);
+ DECL_BLOCK (entry_block, result);
+
+ gcc_jit_rvalue *tmp = gcc_jit_param_as_rvalue (param);
+ if (from.is_ptr != to.is_ptr)
+ {
+ if (from.is_ptr)
+ {
+ tmp = gcc_jit_context_new_cast (comp.ctxt, NULL,
+ tmp, comp.void_ptr_type);
+ tmp = gcc_jit_context_new_call (comp.ctxt, NULL,
+ comp.cast_ptr_to_int, 1, &tmp);
+ }
+ else
+ {
+ tmp = gcc_jit_context_new_cast (comp.ctxt, NULL,
+ tmp, comp.uintptr_type);
+ tmp = gcc_jit_context_new_call (comp.ctxt, NULL,
+ comp.cast_int_to_ptr, 1, &tmp);
+ }
+ }
+
+ tmp = gcc_jit_context_new_cast (comp.ctxt, NULL, tmp, to.type);
+
+ gcc_jit_block_end_with_return (entry_block, NULL, tmp);
return result;
}
@@ -3176,69 +3209,58 @@ static void
define_cast_functions (void)
{
struct cast_type cast_types[NUM_CAST_TYPES]
- = { { comp.bool_type, "bool", sizeof (bool), kind_unsigned },
- { comp.char_ptr_type, "char_ptr", sizeof (char *), kind_pointer },
- { comp.int_type, "int", sizeof (int), kind_signed },
- { comp.lisp_cons_ptr_type, "cons_ptr", sizeof (struct Lisp_Cons *),
- kind_pointer },
- { comp.lisp_obj_ptr_type, "lisp_obj_ptr", sizeof (Lisp_Object *),
- kind_pointer },
- { comp.lisp_word_tag_type, "lisp_word_tag", sizeof (Lisp_Word_tag),
- kind_unsigned },
- { comp.lisp_word_type, "lisp_word", sizeof (Lisp_Word),
- LISP_WORDS_ARE_POINTERS ? kind_pointer : kind_signed },
- { comp.long_long_type, "long_long", sizeof (long long), kind_signed },
- { comp.long_type, "long", sizeof (long), kind_signed },
- { comp.ptrdiff_type, "ptrdiff", sizeof (ptrdiff_t), kind_signed },
- { comp.uintptr_type, "uintptr", sizeof (uintptr_t), kind_unsigned },
- { comp.unsigned_long_long_type, "unsigned_long_long",
- sizeof (unsigned long long), kind_unsigned },
- { comp.unsigned_long_type, "unsigned_long", sizeof (unsigned long),
- kind_unsigned },
- { comp.unsigned_type, "unsigned", sizeof (unsigned), kind_unsigned },
- { comp.void_ptr_type, "void_ptr", sizeof (void*), kind_pointer } };
-
- /* Find the biggest size. It should be unsigned long long, but to be
- sure we find it programmatically. */
- size_t biggest_size = 0;
- for (int i = 0; i < NUM_CAST_TYPES; ++i)
- biggest_size = max (biggest_size, cast_types[i].bytes_size);
+ = { { comp.bool_type, "bool", false },
+ { comp.char_ptr_type, "char_ptr", true },
+ { comp.int_type, "int", false },
+ { comp.lisp_cons_ptr_type, "lisp_cons_ptr", true },
+ { comp.lisp_obj_ptr_type, "lisp_obj_ptr", true },
+ { comp.lisp_word_tag_type, "lisp_word_tag", false },
+ { comp.lisp_word_type, "lisp_word", LISP_WORDS_ARE_POINTERS },
+ { comp.long_long_type, "long_long", false },
+ { comp.long_type, "long", false },
+ { comp.ptrdiff_type, "ptrdiff", false },
+ { comp.uintptr_type, "uintptr", false },
+ { comp.unsigned_long_long_type, "unsigned_long_long", false },
+ { comp.unsigned_long_type, "unsigned_long", false },
+ { comp.unsigned_type, "unsigned", false },
+ { comp.void_ptr_type, "void_ptr", true } };
+ gcc_jit_field *cast_union_fields[2];
+
+ /* Define the union used for type punning. */
+ cast_union_fields[0] = gcc_jit_context_new_field (comp.ctxt,
+ NULL,
+ comp.void_ptr_type,
+ "void_ptr");
+ cast_union_fields[1] = gcc_jit_context_new_field (comp.ctxt,
+ NULL,
+ comp.uintptr_type,
+ "uintptr");
- /* Define the union used for casting. */
- for (int i = 0; i < NUM_CAST_TYPES; ++i)
- {
- comp.cast_types[i] = cast_types[i].type;
- comp.cast_union_fields[i] = gcc_jit_context_new_field (comp.ctxt,
- NULL,
- cast_types[i].type,
- cast_types[i].name);
- comp.cast_type_names[i] = cast_types[i].name;
- comp.cast_type_sizes[i] = cast_types[i].bytes_size;
- comp.cast_type_kind[i] = cast_types[i].kind;
- }
+ comp.cast_union_type
+ = gcc_jit_context_new_union_type (comp.ctxt,
+ NULL,
+ "cast_union",
+ 2, cast_union_fields);
+
+ comp.cast_ptr_to_int = define_type_punning ("cast_pointer_to_uintptr_t",
+ comp.void_ptr_type,
+ cast_union_fields[0],
+ comp.uintptr_type,
+ cast_union_fields[1]);
+ comp.cast_int_to_ptr = define_type_punning ("cast_uintptr_t_to_pointer",
+ comp.uintptr_type,
+ cast_union_fields[1],
+ comp.void_ptr_type,
+ cast_union_fields[0]);
- gcc_jit_type *biggest_type = gcc_jit_context_get_int_type (comp.ctxt,
- biggest_size,
- false);
- comp.cast_types[NUM_CAST_TYPES] = biggest_type;
- comp.cast_union_fields[NUM_CAST_TYPES] =
- gcc_jit_context_new_field (comp.ctxt, NULL, biggest_type, "biggest_type");
- comp.cast_type_names[NUM_CAST_TYPES] = "biggest_type";
- comp.cast_type_sizes[NUM_CAST_TYPES] = biggest_size;
- comp.cast_type_kind[NUM_CAST_TYPES] = kind_unsigned;
-
- comp.cast_union_type =
- gcc_jit_context_new_union_type (comp.ctxt,
- NULL,
- "cast_union",
- NUM_CAST_TYPES + 1,
- comp.cast_union_fields);
+ for (int i = 0; i < NUM_CAST_TYPES; ++i)
+ comp.cast_types[i] = cast_types[i].type;
/* Define the cast functions using a matrix. */
for (int i = 0; i < NUM_CAST_TYPES; ++i)
for (int j = 0; j < NUM_CAST_TYPES; ++j)
comp.cast_functions_from_to[i][j] =
- define_cast_from_to (cast_types[i], i, cast_types[j], j);
+ define_cast_from_to (cast_types[i], cast_types[j]);
}
static void
@@ -4029,7 +4051,13 @@ make_directory_wrapper_1 (Lisp_Object ignore)
DEFUN ("comp-el-to-eln-rel-filename", Fcomp_el_to_eln_rel_filename,
Scomp_el_to_eln_rel_filename, 1, 1, 0,
- doc: /* Return the corresponding .eln relative filename. */)
+ doc: /* Return the relative name of the .eln file for FILENAME.
+FILENAME must exist, and if it's a symlink, the target must exist.
+If FILENAME is compressed, it must have the \".gz\" extension,
+and Emacs must have been compiled with zlib; the file will be
+uncompressed on the fly to hash its contents.
+Value includes the original base name, followed by 2 hash values,
+one for the file name and another for its contents, followed by .eln. */)
(Lisp_Object filename)
{
CHECK_STRING (filename);
@@ -4095,7 +4123,7 @@ DEFUN ("comp-el-to-eln-rel-filename", Fcomp_el_to_eln_rel_filename,
FOR_EACH_TAIL (lds_re_tail)
{
Lisp_Object match_idx =
- Fstring_match (XCAR (lds_re_tail), filename, Qnil);
+ Fstring_match (XCAR (lds_re_tail), filename, Qnil, Qnil);
if (EQ (match_idx, make_fixnum (0)))
{
filename =
@@ -4114,10 +4142,22 @@ DEFUN ("comp-el-to-eln-rel-filename", Fcomp_el_to_eln_rel_filename,
DEFUN ("comp-el-to-eln-filename", Fcomp_el_to_eln_filename,
Scomp_el_to_eln_filename, 1, 2, 0,
- doc: /* Return the .eln filename for source FILENAME to used
-for new compilations.
-If BASE-DIR is non-nil use it as a base directory, look for a suitable
-directory in `comp-eln-load-path' otherwise. */)
+ doc: /* Return the absolute .eln file name for source FILENAME.
+The resulting .eln file name is intended to be used for natively
+compiling FILENAME. FILENAME must exist and be readable, but other
+than that, its leading directories are ignored when constructing
+the name of the .eln file.
+If BASE-DIR is non-nil, use it as the directory for the .eln file;
+non-absolute BASE-DIR is interpreted as relative to `invocation-directory'.
+If BASE-DIR is omitted or nil, look for the first writable directory
+in `native-comp-eln-load-path', and use as BASE-DIR its subdirectory
+whose name is given by `comp-native-version-dir'.
+If FILENAME specifies a preloaded file, the directory for the .eln
+file is the \"preloaded/\" subdirectory of the directory determined
+as described above. FILENAME is considered to be a preloaded file if
+the value of `comp-file-preloaded-p' is non-nil, or if FILENAME
+appears in the value of the environment variable LISP_PRELOADED;
+the latter is supposed to be used by the Emacs build procedure. */)
(Lisp_Object filename, Lisp_Object base_dir)
{
Lisp_Object source_filename = filename;
@@ -4374,8 +4414,7 @@ DEFUN ("comp-native-driver-options-effective-p",
doc: /* Return t if `comp-native-driver-options' is effective. */)
(void)
{
-#if defined (LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option) \
- || defined (WINDOWSNT)
+#if defined (LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option)
if (gcc_jit_context_add_driver_option)
return Qt;
#endif
@@ -4383,13 +4422,28 @@ DEFUN ("comp-native-driver-options-effective-p",
}
#pragma GCC diagnostic pop
+#pragma GCC diagnostic ignored "-Waddress"
+DEFUN ("comp-native-compiler-options-effective-p",
+ Fcomp_native_compiler_options_effective_p,
+ Scomp_native_compiler_options_effective_p,
+ 0, 0, 0,
+ doc: /* Return t if `comp-native-compiler-options' is effective. */)
+ (void)
+{
+#if defined (LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option)
+ if (gcc_jit_context_add_command_line_option)
+ return Qt;
+#endif
+ return Qnil;
+}
+#pragma GCC diagnostic pop
+
static void
add_driver_options (void)
{
Lisp_Object options = Fsymbol_value (Qnative_comp_driver_options);
-#if defined (LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option) \
- || defined (WINDOWSNT)
+#if defined (LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option)
load_gccjit_if_necessary (true);
if (!NILP (Fcomp_native_driver_options_effective_p ()))
FOR_EACH_TAIL (options)
@@ -4408,8 +4462,7 @@ add_driver_options (void)
" and above."));
/* Captured `comp-native-driver-options' because file-local. */
-#if defined (LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option) \
- || defined (WINDOWSNT)
+#if defined (LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option)
options = comp.driver_options;
if (!NILP (Fcomp_native_driver_options_effective_p ()))
FOR_EACH_TAIL (options)
@@ -4422,6 +4475,43 @@ add_driver_options (void)
#endif
}
+static void
+add_compiler_options (void)
+{
+ Lisp_Object options = Fsymbol_value (Qnative_comp_compiler_options);
+
+#if defined (LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option)
+ load_gccjit_if_necessary (true);
+ if (!NILP (Fcomp_native_compiler_options_effective_p ()))
+ FOR_EACH_TAIL (options)
+ gcc_jit_context_add_command_line_option (comp.ctxt,
+ /* FIXME: Need to encode
+ this, but how? either
+ ENCODE_FILE or
+ ENCODE_SYSTEM. */
+ SSDATA (XCAR (options)));
+#endif
+ if (CONSP (options))
+ xsignal1 (Qnative_compiler_error,
+ build_string ("Customizing native compiler options"
+ " via `comp-native-compiler-options' is"
+ " only available on libgccjit version 9"
+ " and above."));
+
+ /* Captured `comp-native-compiler-options' because file-local. */
+#if defined (LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option)
+ options = comp.compiler_options;
+ if (!NILP (Fcomp_native_compiler_options_effective_p ()))
+ FOR_EACH_TAIL (options)
+ gcc_jit_context_add_command_line_option (comp.ctxt,
+ /* FIXME: Need to encode
+ this, but how? either
+ ENCODE_FILE or
+ ENCODE_SYSTEM. */
+ SSDATA (XCAR (options)));
+#endif
+}
+
DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file,
Scomp__compile_ctxt_to_file,
1, 1, 0,
@@ -4467,6 +4557,7 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file,
comp.debug = XFIXNUM (CALL1I (comp-ctxt-debug, Vcomp_ctxt));
eassert (comp.debug < INT_MAX);
comp.driver_options = CALL1I (comp-ctxt-driver-options, Vcomp_ctxt);
+ comp.compiler_options = CALL1I (comp-ctxt-compiler-options, Vcomp_ctxt);
if (comp.debug)
gcc_jit_context_set_bool_option (comp.ctxt,
@@ -4490,6 +4581,15 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file,
GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
comp.speed < 0 ? 0
: (comp.speed > 3 ? 3 : comp.speed));
+
+ /* On MacOS set a unique dylib ID. */
+#if defined (LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option) \
+ && defined (DARWIN_OS)
+ gcc_jit_context_add_driver_option (comp.ctxt, "-install_name");
+ gcc_jit_context_add_driver_option (
+ comp.ctxt, SSDATA (Ffile_name_nondirectory (filename)));
+#endif
+
comp.d_default_idx =
CALL1I (comp-data-container-idx, CALL1I (comp-ctxt-d-default, Vcomp_ctxt));
comp.d_impure_idx =
@@ -4523,8 +4623,7 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file,
/* Work around bug#46495 (GCC PR99126). */
#if defined (WIDE_EMACS_INT) \
- && (defined (LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option) \
- || defined (WINDOWSNT))
+ && defined (LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option)
Lisp_Object version = Fcomp_libgccjit_version ();
if (NILP (version)
|| XFIXNUM (XCAR (version)) < 11)
@@ -4532,6 +4631,7 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file,
"-fdisable-tree-isolate-paths");
#endif
+ add_compiler_options ();
add_driver_options ();
if (comp.debug > 1)
@@ -4575,7 +4675,7 @@ The return value has the form (MAJOR MINOR PATCHLEVEL) or nil if
unknown (before GCC version 10). */)
(void)
{
-#if defined (LIBGCCJIT_HAVE_gcc_jit_version) || defined (WINDOWSNT)
+#if defined (LIBGCCJIT_HAVE_gcc_jit_version)
load_gccjit_if_necessary (true);
return gcc_jit_version_major
@@ -4635,7 +4735,7 @@ helper_PSEUDOVECTOR_TYPEP_XUNTAG (Lisp_Object a, enum pvec_type code)
}
-/* `comp-eln-load-path' clean-up support code. */
+/* `native-comp-eln-load-path' clean-up support code. */
static Lisp_Object all_loaded_comp_units_h;
@@ -4650,7 +4750,7 @@ return_nil (Lisp_Object arg)
/* Windows does not let us delete a .eln file that is currently loaded
by a process. The strategy is to rename .eln files into .old.eln
instead of removing them when this is not possible and clean-up
- `comp-eln-load-path' when exiting.
+ `native-comp-eln-load-path' when exiting.
Any error is ignored because it may be due to the file being loaded
in another Emacs instance. */
@@ -4686,10 +4786,6 @@ register_native_comp_unit (Lisp_Object comp_u)
/* Deferred compilation mechanism. */
/***********************************/
-/* List of sources we'll compile and load after having conventionally
- loaded the compiler and its dependencies. */
-static Lisp_Object delayed_sources;
-
/* Queue an asynchronous compilation for the source file defining
FUNCTION_NAME and perform a late load.
@@ -4746,30 +4842,16 @@ maybe_defer_native_compilation (Lisp_Object function_name,
/* This is so deferred compilation is able to compile comp
dependencies breaking circularity. */
- if (!NILP (Ffeaturep (Qcomp, Qnil)))
+ if (comp__loadable)
{
- /* Comp already loaded. */
- if (!NILP (delayed_sources))
- {
- CALLN (Ffuncall, intern_c_string ("native--compile-async"),
- delayed_sources, Qnil, Qlate);
- delayed_sources = Qnil;
- }
+ /* Startup is done, comp is usable. */
+ Frequire (Qcomp, Qnil, Qnil);
Fputhash (function_name, definition, Vcomp_deferred_pending_h);
CALLN (Ffuncall, intern_c_string ("native--compile-async"),
src, Qnil, Qlate);
}
else
- {
- delayed_sources = Fcons (src, delayed_sources);
- /* Require comp only once. */
- static bool comp_required = false;
- if (!comp_required)
- {
- comp_required = true;
- Frequire (Qcomp, Qnil, Qnil);
- }
- }
+ Vcomp__delayed_sources = Fcons (src, Vcomp__delayed_sources);
}
@@ -4778,7 +4860,7 @@ maybe_defer_native_compilation (Lisp_Object function_name,
/**************************************/
/* Fixup the system eln-cache directory, which is the last entry in
- `comp-eln-load-path'. Argument is a .eln file in that directory. */
+ `native-comp-eln-load-path'. Argument is a .eln file in that directory. */
void
fixup_eln_load_path (Lisp_Object eln_filename)
{
@@ -5054,21 +5136,29 @@ make_subr (Lisp_Object symbol_name, Lisp_Object minarg, Lisp_Object maxarg,
if (CONSP (minarg))
{
/* Dynamic code. */
- x->s.lambda_list[0] = maxarg;
+#ifdef HAVE_NATIVE_COMP
+ x->s.lambda_list = maxarg;
+#endif
maxarg = XCDR (minarg);
minarg = XCAR (minarg);
}
else
- x->s.lambda_list[0] = Qnil;
+ {
+#ifdef HAVE_NATIVE_COMP
+ x->s.lambda_list = Qnil;
+#endif
+ }
x->s.function.a0 = func;
x->s.min_args = XFIXNUM (minarg);
x->s.max_args = FIXNUMP (maxarg) ? XFIXNUM (maxarg) : MANY;
x->s.symbol_name = xstrdup (SSDATA (symbol_name));
x->s.native_intspec = intspec;
x->s.doc = XFIXNUM (doc_idx);
- x->s.native_comp_u[0] = comp_u;
- x->s.native_c_name[0] = xstrdup (SSDATA (c_name));
- x->s.type[0] = type;
+#ifdef HAVE_NATIVE_COMP
+ x->s.native_comp_u = comp_u;
+ x->s.native_c_name = xstrdup (SSDATA (c_name));
+ x->s.type = type;
+#endif
Lisp_Object tem;
XSETSUBR (tem, &x->s);
@@ -5160,7 +5250,8 @@ file_in_eln_sys_dir (Lisp_Object filename)
eln_sys_dir = XCAR (tmp);
return !NILP (Fstring_match (Fregexp_quote (Fexpand_file_name (eln_sys_dir,
Qnil)),
- Fexpand_file_name (filename, Qnil), Qnil));
+ Fexpand_file_name (filename, Qnil),
+ Qnil, Qnil));
}
/* Load related routines. */
@@ -5187,16 +5278,16 @@ LATE_LOAD has to be non-nil when loading for deferred compilation. */)
Fmake_temp_file_internal (filename, Qnil, build_string (".eln.tmp"),
Qnil);
if (NILP (Ffile_writable_p (tmp_filename)))
- comp_u->handle = dynlib_open (SSDATA (encoded_filename));
+ comp_u->handle = dynlib_open_for_eln (SSDATA (encoded_filename));
else
{
Frename_file (filename, tmp_filename, Qt);
- comp_u->handle = dynlib_open (SSDATA (ENCODE_FILE (tmp_filename)));
+ comp_u->handle = dynlib_open_for_eln (SSDATA (ENCODE_FILE (tmp_filename)));
Frename_file (tmp_filename, filename, Qnil);
}
}
else
- comp_u->handle = dynlib_open (SSDATA (encoded_filename));
+ comp_u->handle = dynlib_open_for_eln (SSDATA (encoded_filename));
if (!comp_u->handle)
xsignal2 (Qnative_lisp_load_failed, filename,
@@ -5227,6 +5318,13 @@ void
syms_of_comp (void)
{
#ifdef HAVE_NATIVE_COMP
+ DEFVAR_LISP ("comp--delayed-sources", Vcomp__delayed_sources,
+ doc: /* List of sources to be native-compiled when startup is finished.
+For internal use. */);
+ DEFVAR_BOOL ("comp--loadable",
+ comp__loadable,
+ doc: /* Non-nil when comp.el can be loaded.
+For internal use. */);
/* Compiler control customizes. */
DEFVAR_BOOL ("native-comp-deferred-compilation",
native_comp_deferred_compilation,
@@ -5239,6 +5337,7 @@ compiled one. */);
DEFSYM (Qnative_comp_speed, "native-comp-speed");
DEFSYM (Qnative_comp_debug, "native-comp-debug");
DEFSYM (Qnative_comp_driver_options, "native-comp-driver-options");
+ DEFSYM (Qnative_comp_compiler_options, "native-comp-compiler-options");
DEFSYM (Qcomp_libgccjit_reproducer, "comp-libgccjit-reproducer");
/* Limple instruction set. */
@@ -5348,6 +5447,7 @@ compiled one. */);
defsubr (&Scomp_el_to_eln_rel_filename);
defsubr (&Scomp_el_to_eln_filename);
defsubr (&Scomp_native_driver_options_effective_p);
+ defsubr (&Scomp_native_compiler_options_effective_p);
defsubr (&Scomp__install_trampoline);
defsubr (&Scomp__init_ctxt);
defsubr (&Scomp__release_ctxt);
@@ -5365,8 +5465,6 @@ compiled one. */);
staticpro (&comp.func_blocks_h);
staticpro (&comp.emitter_dispatcher);
comp.emitter_dispatcher = Qnil;
- staticpro (&delayed_sources);
- delayed_sources = Qnil;
staticpro (&loadsearch_re_list);
loadsearch_re_list = Qnil;
@@ -5423,9 +5521,9 @@ protect the trampolines against GC. */);
Vcomp_installed_trampolines_h = CALLN (Fmake_hash_table);
DEFVAR_LISP ("comp-no-native-file-h", V_comp_no_native_file_h,
- doc: /* Files for which no deferred compilation has to
-be performed because the bytecode version was explicitly requested by
-the user during load.
+ doc: /* Files for which no deferred compilation has to be performed.
+These files' compilation should not be deferred because the bytecode
+version was explicitly requested by the user during load.
For internal use. */);
V_comp_no_native_file_h = CALLN (Fmake_hash_table, QCtest, Qequal);
diff --git a/src/comp.h b/src/comp.h
index c4af4193d0b..96bb52a14bc 100644
--- a/src/comp.h
+++ b/src/comp.h
@@ -20,16 +20,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#ifndef COMP_H
#define COMP_H
-/* To keep ifdefs under control. */
-enum {
- NATIVE_COMP_FLAG =
-#ifdef HAVE_NATIVE_COMP
- 1
-#else
- 0
-#endif
-};
-
#include <dynlib.h>
struct Lisp_Native_Comp_Unit
diff --git a/src/composite.c b/src/composite.c
index e97f8e2b4cd..c170805d9dd 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -882,14 +882,15 @@ fill_gstring_body (Lisp_Object gstring)
/* Try to compose the characters at CHARPOS according to composition
rule RULE ([PATTERN PREV-CHARS FUNC]). LIMIT limits the characters
to compose. STRING, if not nil, is a target string. WIN is a
- window where the characters are being displayed. If characters are
+ window where the characters are being displayed. CH is the
+ character that triggered the composition check. If characters are
successfully composed, return the composition as a glyph-string
object. Otherwise return nil. */
static Lisp_Object
autocmp_chars (Lisp_Object rule, ptrdiff_t charpos, ptrdiff_t bytepos,
ptrdiff_t limit, struct window *win, struct face *face,
- Lisp_Object string, Lisp_Object direction)
+ Lisp_Object string, Lisp_Object direction, int ch)
{
ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object pos = make_fixnum (charpos);
@@ -920,7 +921,7 @@ autocmp_chars (Lisp_Object rule, ptrdiff_t charpos, ptrdiff_t bytepos,
struct frame *f = XFRAME (font_object);
if (FRAME_WINDOW_P (f))
{
- font_object = font_range (charpos, bytepos, &to, win, face, string);
+ font_object = font_range (charpos, bytepos, &to, win, face, string, ch);
if (! FONT_OBJECT_P (font_object)
|| (! NILP (re)
&& to < limit
@@ -953,6 +954,9 @@ char_composable_p (int c)
Lisp_Object val;
return (c >= ' '
&& (c == ZERO_WIDTH_NON_JOINER || c == ZERO_WIDTH_JOINER
+ /* Per Unicode TR51, these tag characters can be part of
+ Emoji sequences. */
+ || (TAG_SPACE <= c && c <= CANCEL_TAG)
/* unicode-category-table may not be available during
dumping. */
|| (CHAR_TABLE_P (Vunicode_category_table)
@@ -1269,7 +1273,7 @@ composition_reseat_it (struct composition_it *cmp_it, ptrdiff_t charpos,
if (XFIXNAT (AREF (elt, 1)) != cmp_it->lookback)
goto no_composition;
lgstring = autocmp_chars (elt, charpos, bytepos, endpos,
- w, face, string, direction);
+ w, face, string, direction, cmp_it->ch);
if (composition_gstring_p (lgstring))
break;
lgstring = Qnil;
@@ -1307,7 +1311,7 @@ composition_reseat_it (struct composition_it *cmp_it, ptrdiff_t charpos,
else
direction = QR2L;
lgstring = autocmp_chars (elt, cpos, bpos, charpos + 1, w, face,
- string, direction);
+ string, direction, cmp_it->ch);
if (! composition_gstring_p (lgstring)
|| cpos + LGSTRING_CHAR_LEN (lgstring) - 1 != charpos)
/* Composition failed or didn't cover the current
@@ -1676,7 +1680,7 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, ptrdiff_t backlim,
for (check = cur; check_pos < check.pos; )
BACKWARD_CHAR (check, stop);
*gstring = autocmp_chars (elt, check.pos, check.pos_byte,
- tail, w, NULL, string, Qnil);
+ tail, w, NULL, string, Qnil, c);
need_adjustment = 1;
if (NILP (*gstring))
{
@@ -2120,6 +2124,17 @@ GSTRING, or modify GSTRING itself and return it.
See also the documentation of `auto-composition-mode'. */);
Vcomposition_function_table = Fmake_char_table (Qnil, Qnil);
+ DEFVAR_LISP ("auto-composition-emoji-eligible-codepoints", Vauto_composition_emoji_eligible_codepoints,
+ doc: /* List of codepoints for which auto-composition will check for an emoji font.
+
+These are codepoints which have Emoji_Presentation = No, and thus by
+default are not displayed as emoji. In certain circumstances, such as
+when followed by U+FE0F (VS-16) the emoji font should be used for
+them anyway.
+
+This list is auto-generated, you should not need to modify it. */);
+ Vauto_composition_emoji_eligible_codepoints = Qnil;
+
defsubr (&Scompose_region_internal);
defsubr (&Scompose_string_internal);
defsubr (&Sfind_composition_internal);
diff --git a/src/composite.h b/src/composite.h
index 67e87201bf2..945f2612915 100644
--- a/src/composite.h
+++ b/src/composite.h
@@ -254,6 +254,10 @@ composition_valid_p (ptrdiff_t start, ptrdiff_t end, Lisp_Object prop)
#define LGSTRING_HEADER(lgs) AREF (lgs, 0)
#define LGSTRING_SET_HEADER(lgs, header) ASET (lgs, 0, header)
+/* LGSTRING_FONT retrieves the font used for LGSTRING, if we are going
+ to display it on a GUI frame. On text-mode frames, that slot
+ stores the coding-system that should be used to write output to the
+ frame's terminal. */
#define LGSTRING_FONT(lgs) AREF (LGSTRING_HEADER (lgs), 0)
#define LGSTRING_CHAR(lgs, i) AREF (LGSTRING_HEADER (lgs), (i) + 1)
#define LGSTRING_CHAR_LEN(lgs) (ASIZE (LGSTRING_HEADER (lgs)) - 1)
diff --git a/src/conf_post.h b/src/conf_post.h
index 8558dc466cc..2c6fbb0dba5 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -293,7 +293,6 @@ extern int emacs_setenv_TZ (char const *);
ATTRIBUTE_FORMAT ((PRINTF_ARCHETYPE, string_index, first_to_check))
#define ARG_NONNULL ATTRIBUTE_NONNULL
-#define ATTRIBUTE_UNUSED MAYBE_UNUSED
/* Declare NAME to be a pointer to an object of type TYPE, initialized
to the address ADDR, which may be of a different type. Accesses
diff --git a/src/data.c b/src/data.c
index ffca7e75355..f07667b0003 100644
--- a/src/data.c
+++ b/src/data.c
@@ -259,6 +259,8 @@ for example, (type-of 1) returns `integer'. */)
return Qxwidget;
case PVEC_XWIDGET_VIEW:
return Qxwidget_view;
+ case PVEC_SQLITE:
+ return Qsqlite;
/* "Impossible" cases. */
case PVEC_MISC_PTR:
case PVEC_OTHER:
@@ -681,7 +683,7 @@ global value outside of any lexical scope. */)
/* It has been previously suggested to make this function an alias for
symbol-function, but upon discussion at Bug#23957, there is a risk
breaking backward compatibility, as some users of fboundp may
- expect `t' in particular, rather than any true value. */
+ expect t in particular, rather than any true value. */
DEFUN ("fboundp", Ffboundp, Sfboundp, 1, 1, 0,
doc: /* Return t if SYMBOL's function definition is not void. */)
(Lisp_Object symbol)
@@ -891,9 +893,11 @@ function or t otherwise. */)
{
CHECK_SUBR (subr);
- return SUBR_NATIVE_COMPILED_DYNP (subr)
- ? XSUBR (subr)->lambda_list[0]
- : Qt;
+#ifdef HAVE_NATIVE_COMP
+ if (SUBR_NATIVE_COMPILED_DYNP (subr))
+ return XSUBR (subr)->lambda_list;
+#endif
+ return Qt;
}
DEFUN ("subr-type", Fsubr_type,
@@ -917,7 +921,7 @@ DEFUN ("subr-native-comp-unit", Fsubr_native_comp_unit,
(Lisp_Object subr)
{
CHECK_SUBR (subr);
- return XSUBR (subr)->native_comp_u[0];
+ return XSUBR (subr)->native_comp_u;
}
DEFUN ("native-comp-unit-file", Fnative_comp_unit_file,
@@ -1045,6 +1049,8 @@ The value, if non-nil, is a list of mode name symbols. */)
if (COMPILEDP (fun))
{
+ if (PVSIZE (fun) <= COMPILED_INTERACTIVE)
+ return Qnil;
Lisp_Object form = AREF (fun, COMPILED_INTERACTIVE);
if (VECTORP (form))
/* New form -- the second element is the command modes. */
diff --git a/src/dispextern.h b/src/dispextern.h
index 33fcaa4c078..0f316a2eaf9 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -134,6 +134,21 @@ typedef Emacs_Pixmap Emacs_Pix_Context;
#define FACE_COLOR_TO_PIXEL(face_color, frame) face_color
#endif
+#ifdef HAVE_PGTK
+#include "pgtkgui.h"
+/* Following typedef needed to accommodate the MSDOS port, believe it or not. */
+typedef struct pgtk_display_info Display_Info;
+typedef Emacs_Pixmap XImagePtr;
+typedef XImagePtr XImagePtr_or_DC;
+#endif /* HAVE_PGTK */
+
+#ifdef HAVE_HAIKU
+#include "haikugui.h"
+typedef struct haiku_display_info Display_Info;
+typedef Emacs_Pixmap Emacs_Pix_Container;
+typedef Emacs_Pixmap Emacs_Pix_Context;
+#endif
+
#ifdef HAVE_WINDOW_SYSTEM
# include <time.h>
# include "fontset.h"
@@ -536,8 +551,8 @@ struct glyph
int img_id;
#ifdef HAVE_XWIDGETS
- /* Xwidget reference (type == XWIDGET_GLYPH). */
- struct xwidget *xwidget;
+ /* Xwidget ID. */
+ uint32_t xwidget;
#endif
/* Sub-structure for type == STRETCH_GLYPH. */
@@ -1326,7 +1341,9 @@ struct glyph_string
/* The area within row. */
enum glyph_row_area area;
- /* Characters to be drawn, and number of characters. */
+ /* Characters to be drawn, and number of characters. Note that
+ NCHARS can be zero if this is a composition glyph string, as
+ evidenced by FIRST_GLYPH->type. */
unsigned *char2b;
int nchars;
@@ -1391,6 +1408,9 @@ struct glyph_string
Emacs_GC *gc;
HDC hdc;
#endif
+#if defined (HAVE_PGTK)
+ Emacs_GC xgcv;
+#endif
/* A pointer to the first glyph in the string. This glyph
corresponds to char2b[0]. Needed to draw rectangles if
@@ -1468,21 +1488,23 @@ struct glyph_string
compared against minibuf_window (if SELW doesn't match), and SCRW
which is compared against minibuf_selected_window (if MBW matches). */
-#define CURRENT_MODE_LINE_FACE_ID_3(SELW, MBW, SCRW) \
+#define CURRENT_MODE_LINE_ACTIVE_FACE_ID_3(SELW, MBW, SCRW) \
((!mode_line_in_non_selected_windows \
|| (SELW) == XWINDOW (selected_window) \
|| (minibuf_level > 0 \
&& !NILP (minibuf_selected_window) \
&& (MBW) == XWINDOW (minibuf_window) \
&& (SCRW) == XWINDOW (minibuf_selected_window))) \
- ? MODE_LINE_FACE_ID \
+ ? MODE_LINE_ACTIVE_FACE_ID \
: MODE_LINE_INACTIVE_FACE_ID)
/* Return the desired face id for the mode line of window W. */
-#define CURRENT_MODE_LINE_FACE_ID(W) \
- (CURRENT_MODE_LINE_FACE_ID_3((W), XWINDOW (selected_window), (W)))
+#define CURRENT_MODE_LINE_ACTIVE_FACE_ID(W) \
+ (CURRENT_MODE_LINE_ACTIVE_FACE_ID_3((W), \
+ XWINDOW (selected_window), \
+ (W)))
/* Return the current height of the mode line of window W. If not known
from W->mode_line_height, look at W's current glyph matrix, or return
@@ -1495,7 +1517,7 @@ struct glyph_string
= (MATRIX_MODE_LINE_HEIGHT ((W)->current_matrix) \
? MATRIX_MODE_LINE_HEIGHT ((W)->current_matrix) \
: estimate_mode_line_height \
- (XFRAME ((W)->frame), CURRENT_MODE_LINE_FACE_ID (W)))))
+ (XFRAME ((W)->frame), CURRENT_MODE_LINE_ACTIVE_FACE_ID (W)))))
/* Return the current height of the header line of window W. If not known
from W->header_line_height, look at W's current glyph matrix, or return
@@ -1809,7 +1831,7 @@ face_tty_specified_color (unsigned long color)
enum face_id
{
DEFAULT_FACE_ID,
- MODE_LINE_FACE_ID,
+ MODE_LINE_ACTIVE_FACE_ID,
MODE_LINE_INACTIVE_FACE_ID,
TOOL_BAR_FACE_ID,
FRINGE_FACE_ID,
@@ -1827,6 +1849,7 @@ enum face_id
CHILD_FRAME_BORDER_FACE_ID,
TAB_BAR_FACE_ID,
TAB_LINE_FACE_ID,
+ MODE_LINE_FACE_ID,
BASIC_FACE_ID_SENTINEL
};
@@ -2536,7 +2559,8 @@ struct it
enum line_wrap_method line_wrap;
/* The ID of the default face to use. One of DEFAULT_FACE_ID,
- MODE_LINE_FACE_ID, etc, depending on what we are displaying. */
+ MODE_LINE_ACTIVE_FACE_ID, etc, depending on what we are
+ displaying. */
int base_face_id;
/* If `what' == IT_CHARACTER, the character and the length in bytes
@@ -2737,6 +2761,12 @@ struct it
/* For iterating over bidirectional text. */
struct bidi_it bidi_it;
bidi_dir_t paragraph_embedding;
+
+ /* For handling the :min-width property. The object is the text
+ property we're testing the `eq' of (nil if none), and the integer
+ is the x position of the start of the run of glyphs. */
+ Lisp_Object min_width_property;
+ int min_width_start;
};
@@ -3009,7 +3039,7 @@ struct redisplay_interface
#ifdef HAVE_WINDOW_SYSTEM
# if (defined USE_CAIRO || defined HAVE_XRENDER \
- || defined HAVE_NS || defined HAVE_NTGUI)
+ || defined HAVE_NS || defined HAVE_NTGUI || defined HAVE_HAIKU)
# define HAVE_NATIVE_TRANSFORMS
# endif
@@ -3048,6 +3078,14 @@ struct image
#ifdef HAVE_NTGUI
XFORM xform;
#endif
+#ifdef HAVE_HAIKU
+ /* Non-zero if the image has not yet been transformed for display. */
+ int have_be_transforms_p;
+
+ double be_rotate;
+ double be_scale_x;
+ double be_scale_y;
+#endif
/* Colors allocated for this image, if any. Allocated via xmalloc. */
unsigned long *colors;
@@ -3160,7 +3198,7 @@ struct image_cache
/* Size of bucket vector of image caches. Should be prime. */
-#define IMAGE_CACHE_BUCKETS_SIZE 1001
+#define IMAGE_CACHE_BUCKETS_SIZE 1009
#endif /* HAVE_WINDOW_SYSTEM */
@@ -3202,7 +3240,7 @@ enum tab_bar_item_idx
/* Default values of the above variables. */
-#define DEFAULT_TAB_BAR_BUTTON_MARGIN 4
+#define DEFAULT_TAB_BAR_BUTTON_MARGIN 1
#define DEFAULT_TAB_BAR_BUTTON_RELIEF 1
/* The height in pixels of the default tab-bar images. */
@@ -3415,8 +3453,8 @@ extern void get_glyph_string_clip_rect (struct glyph_string *,
NativeRectangle *nr);
extern Lisp_Object find_hot_spot (Lisp_Object, int, int);
-extern void handle_tab_bar_click (struct frame *,
- int, int, bool, int);
+extern Lisp_Object handle_tab_bar_click (struct frame *,
+ int, int, bool, int);
extern void handle_tool_bar_click (struct frame *,
int, int, bool, int);
@@ -3487,7 +3525,8 @@ bool valid_image_p (Lisp_Object);
void prepare_image_for_display (struct frame *, struct image *);
ptrdiff_t lookup_image (struct frame *, Lisp_Object, int);
-#if defined HAVE_X_WINDOWS || defined USE_CAIRO || defined HAVE_NS
+#if defined HAVE_X_WINDOWS || defined USE_CAIRO || defined HAVE_NS \
+ || defined HAVE_HAIKU
#define RGB_PIXEL_COLOR unsigned long
#endif
@@ -3720,10 +3759,8 @@ extern Lisp_Object gui_default_parameter (struct frame *, Lisp_Object,
const char *, const char *,
enum resource_types);
-#ifndef HAVE_NS /* These both used on W32 and X only. */
extern bool gui_mouse_grabbed (Display_Info *);
extern void gui_redo_mouse_highlight (Display_Info *);
-#endif /* HAVE_NS */
#endif /* HAVE_WINDOW_SYSTEM */
diff --git a/src/dispnew.c b/src/dispnew.c
index 0c313199173..4faa7a7777b 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -475,7 +475,8 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
= row->glyphs[TEXT_AREA] + dim.width - left - right;
/* Leave room for a border glyph. */
if (!FRAME_WINDOW_P (XFRAME (w->frame))
- && !WINDOW_RIGHTMOST_P (w))
+ && !WINDOW_RIGHTMOST_P (w)
+ && right > 0)
row->glyphs[RIGHT_MARGIN_AREA] -= 1;
row->glyphs[LAST_AREA]
= row->glyphs[LEFT_MARGIN_AREA] + dim.width;
@@ -1033,7 +1034,7 @@ copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from)
{
enum { off = offsetof (struct glyph_row, x) };
- memcpy (&to->x, &from->x, sizeof *to - off);
+ memcpy ((char *) to + off, (char *) from + off, sizeof *to - off);
}
@@ -1148,7 +1149,8 @@ prepare_desired_row (struct window *w, struct glyph_row *row, bool mode_line_p)
row->glyphs[RIGHT_MARGIN_AREA] = row->glyphs[LAST_AREA] - right;
/* Leave room for a border glyph. */
if (!FRAME_WINDOW_P (XFRAME (w->frame))
- && !WINDOW_RIGHTMOST_P (w))
+ && !WINDOW_RIGHTMOST_P (w)
+ && right > 0)
row->glyphs[RIGHT_MARGIN_AREA] -= 1;
}
}
@@ -3848,6 +3850,9 @@ gui_update_window_end (struct window *w, bool cursor_on_p,
w->output_cursor.hpos, w->output_cursor.vpos,
w->output_cursor.x, w->output_cursor.y);
+ if (cursor_in_mouse_face_p (w) && cursor_on_p)
+ mouse_face_overwritten_p = 1;
+
if (draw_window_fringes (w, true))
{
if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
@@ -4444,16 +4449,6 @@ scrolling_window (struct window *w, int tab_line_p)
break;
}
-#ifdef HAVE_XWIDGETS
- /* Currently this seems needed to detect xwidget movement reliably.
- This is most probably because an xwidget glyph is represented in
- struct glyph's 'union u' by a pointer to a struct, which takes 8
- bytes in 64-bit builds, and thus the comparison of u.val values
- done by GLYPH_EQUAL_P doesn't work reliably, since it assumes the
- size of the union is 4 bytes. FIXME. */
- return 0;
-#endif
-
/* Can't scroll the display of w32 GUI frames when position of point
is indicated by the system caret, because scrolling the display
will then "copy" the pixels used by the caret. */
@@ -6151,7 +6146,7 @@ sit_for (Lisp_Object timeout, bool reading, int display_option)
wrong_type_argument (Qnumberp, timeout);
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
gobble_input ();
#endif
@@ -6458,6 +6453,24 @@ init_display_interactive (void)
}
#endif
+#ifdef HAVE_PGTK
+ if (!inhibit_window_system && !will_dump_p ())
+ {
+ Vinitial_window_system = Qpgtk;
+ Vwindow_system_version = make_fixnum (3);
+ return;
+ }
+#endif
+
+#ifdef HAVE_HAIKU
+ if (!inhibit_window_system && !will_dump_p ())
+ {
+ Vinitial_window_system = Qhaiku;
+ Vwindow_system_version = make_fixnum (1);
+ return;
+ }
+#endif
+
/* If no window system has been specified, try to use the terminal. */
if (! isatty (STDIN_FILENO))
fatal ("standard input is not a tty");
@@ -6704,7 +6717,7 @@ See `buffer-display-table' for more information. */);
DEFVAR_LISP ("tab-bar-position", Vtab_bar_position,
doc: /* Specify on which side from the tool bar the tab bar shall be.
-Possible values are `t' (below the tool bar), `nil' (above the tool bar).
+Possible values are t (below the tool bar), nil (above the tool bar).
This option affects only builds where the tool bar is not external. */);
pdumper_do_now_and_after_load (syms_of_display_for_pdumper);
diff --git a/src/dosfns.c b/src/dosfns.c
index 10023c8c7f1..17e896cf2e1 100644
--- a/src/dosfns.c
+++ b/src/dosfns.c
@@ -58,8 +58,8 @@ DEFUN ("int86", Fint86, Sint86, 2, 2, 0,
Return the updated REGISTER vector.
INTERRUPT should be an integer in the range 0 to 255.
-REGISTERS should be a vector produced by `make-register' and
-`set-register-value'. */)
+REGISTERS should be a vector produced by `dos-make-register' and
+`dos-set-register-value'. */)
(Lisp_Object interrupt, Lisp_Object registers)
{
register int i;
diff --git a/src/dynlib.c b/src/dynlib.c
index a8c88439615..e9a775f2d3c 100644
--- a/src/dynlib.c
+++ b/src/dynlib.c
@@ -104,6 +104,12 @@ dynlib_open (const char *dll_fname)
return (dynlib_handle_ptr) hdll;
}
+dynlib_handle_ptr
+dynlib_open_for_eln (const char *dll_fname)
+{
+ return dynlib_open (dll_fname);
+}
+
void *
dynlib_sym (dynlib_handle_ptr h, const char *sym)
{
@@ -270,6 +276,12 @@ dynlib_close (dynlib_handle_ptr h)
dynlib_handle_ptr
dynlib_open (const char *path)
{
+ return dlopen (path, RTLD_LAZY | RTLD_GLOBAL);
+}
+
+dynlib_handle_ptr
+dynlib_open_for_eln (const char *path)
+{
return dlopen (path, RTLD_LAZY);
}
diff --git a/src/dynlib.h b/src/dynlib.h
index e20d8891a23..05ba7981226 100644
--- a/src/dynlib.h
+++ b/src/dynlib.h
@@ -24,6 +24,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
typedef void *dynlib_handle_ptr;
dynlib_handle_ptr dynlib_open (const char *path);
+dynlib_handle_ptr dynlib_open_for_eln (const char *path);
int dynlib_close (dynlib_handle_ptr h);
const char *dynlib_error (void);
diff --git a/src/editfns.c b/src/editfns.c
index c8219decb06..5c9c34dc352 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -4265,9 +4265,6 @@ ring. */)
enough to use as the temporary storage? That would avoid an
allocation... interesting. Later, don't fool with it now. */
- /* Working without memmove, for portability (sigh), so must be
- careful of overlapping subsections of the array... */
-
if (end1 == start2) /* adjacent regions */
{
modify_text (start1, end2);
diff --git a/src/emacs-module.h.in b/src/emacs-module.h.in
index fe52587c1a5..a56e4dd12ae 100644
--- a/src/emacs-module.h.in
+++ b/src/emacs-module.h.in
@@ -169,6 +169,19 @@ struct emacs_env_28
@module_env_snippet_28@
};
+struct emacs_env_29
+{
+@module_env_snippet_25@
+
+@module_env_snippet_26@
+
+@module_env_snippet_27@
+
+@module_env_snippet_28@
+
+@module_env_snippet_29@
+};
+
/* Every module should define a function as follows. */
extern int emacs_module_init (struct emacs_runtime *runtime)
EMACS_NOEXCEPT
diff --git a/src/emacs.c b/src/emacs.c
index 866e43fda94..6048d126781 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -109,6 +109,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "getpagesize.h"
#include "gnutls.h"
+#ifdef HAVE_HAIKU
+#include <kernel/OS.h>
+#endif
+
#ifdef PROFILING
# include <sys/gmon.h>
extern void moncontrol (int mode);
@@ -133,6 +137,7 @@ extern char etext;
#endif
#include "pdumper.h"
+#include "fingerprint.h"
#include "epaths.h"
static const char emacs_version[] = PACKAGE_VERSION;
@@ -255,11 +260,12 @@ Initialization options:\n\
#ifdef HAVE_PDUMPER
"\
--dump-file FILE read dumped state from FILE\n\
+--fingerprint output fingerprint and exit\n\
",
#endif
#if SECCOMP_USABLE
"\
---sandbox=FILE read Seccomp BPF filter from FILE\n\
+--seccomp=FILE read Seccomp BPF filter from FILE\n\
"
#endif
"\
@@ -830,6 +836,8 @@ load_pdump (int argc, char **argv)
const char *const suffix = ".pdmp";
int result;
char *emacs_executable = argv[0];
+ ptrdiff_t hexbuf_size;
+ char *hexbuf;
const char *strip_suffix =
#if defined DOS_NT || defined CYGWIN
".exe"
@@ -924,12 +932,18 @@ load_pdump (int argc, char **argv)
path_exec = ns_relocate (path_exec);
#endif
- /* Look for "emacs.pdmp" in PATH_EXEC. We hardcode "emacs" in
- "emacs.pdmp" so that the Emacs binary still works if the user
- copies and renames it. */
+ /* Look for "emacs-FINGERPRINT.pdmp" in PATH_EXEC. We hardcode
+ "emacs" in "emacs-FINGERPRINT.pdmp" so that the Emacs binary
+ still works if the user copies and renames it. */
+ hexbuf_size = 2 * sizeof fingerprint;
+ hexbuf = xmalloc (hexbuf_size + 1);
+ hexbuf_digest (hexbuf, (char *) fingerprint, sizeof fingerprint);
+ hexbuf[hexbuf_size] = '\0';
needed = (strlen (path_exec)
+ 1
+ strlen (argv0_base)
+ + 1
+ + strlen (hexbuf)
+ strlen (suffix)
+ 1);
if (bufsize < needed)
@@ -937,8 +951,8 @@ load_pdump (int argc, char **argv)
xfree (dump_file);
dump_file = xpalloc (NULL, &bufsize, needed - bufsize, -1, 1);
}
- sprintf (dump_file, "%s%c%s%s",
- path_exec, DIRECTORY_SEP, argv0_base, suffix);
+ sprintf (dump_file, "%s%c%s-%s%s",
+ path_exec, DIRECTORY_SEP, argv0_base, hexbuf, suffix);
#if !defined (NS_SELF_CONTAINED)
/* Assume the Emacs binary lives in a sibling directory as set up by
the default installation configuration. */
@@ -1342,6 +1356,39 @@ main (int argc, char **argv)
init_standard_fds ();
atexit (close_output_streams);
+ /* Command-line argument processing.
+
+ The arguments in the argv[] array are sorted in the descending
+ order of their priority as defined in the standard_args[] array
+ below. Then the sorted arguments are processed from the highest
+ to the lowest priority. Each command-line argument that is
+ recognized by 'main', if found in argv[], causes skip_args to be
+ incremented, effectively removing the processed argument from the
+ command line.
+
+ Then init_cmdargs is called, and conses a list of the unprocessed
+ command-line arguments, as strings, in 'command-line-args'. It
+ ignores all the arguments up to the one indexed by skip_args, as
+ those were already processed.
+
+ The arguments in 'command-line-args' are further processed by
+ startup.el, functions 'command-line' and 'command-line-1'. The
+ first of them handles the arguments which need to be processed
+ before loading the user init file and initializing the
+ window-system. The second one processes the arguments that are
+ related to the GUI system, like -font, -geometry, and -title, and
+ then processes the rest of arguments whose priority is below
+ those that are related to the GUI system. The arguments
+ porcessed by 'command-line' are removed from 'command-line-args';
+ the arguments processed by 'command-line-1' aren't, they are only
+ removed from 'command-line-args-left'.
+
+ 'command-line-1' emits an error message for any argument it
+ doesn't recognize, so any command-line arguments processed in C
+ below whose priority is below the GUI system related switches
+ should be explicitly recognized, ignored, and removed from
+ 'command-line-args-left' in 'command-line-1'. */
+
sort_args (argc, argv);
argc = 0;
while (argv[argc]) argc++;
@@ -1387,6 +1434,24 @@ main (int argc, char **argv)
exit (0);
}
+#ifdef HAVE_PDUMPER
+ if (argmatch (argv, argc, "-fingerprint", "--fingerprint", 4,
+ NULL, &skip_args))
+ {
+ if (initialized)
+ {
+ dump_fingerprint (stdout, "",
+ (unsigned char *) fingerprint);
+ exit (0);
+ }
+ else
+ {
+ fputs ("Not initialized\n", stderr);
+ exit (1);
+ }
+ }
+#endif
+
emacs_wd = emacs_get_current_dir_name ();
#ifdef HAVE_PDUMPER
if (dumped_with_pdumper_p ())
@@ -1844,7 +1909,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
init_bignum ();
init_threads ();
init_eval ();
- init_atimer ();
+#ifdef HAVE_PGTK
+ init_pgtkterm (); /* before init_atimer(). */
+#endif
running_asynch_code = 0;
init_random ();
@@ -2006,6 +2073,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
if (!will_dump_p ())
set_initial_environment ();
+ /* Has to run after the environment is set up. */
+ init_atimer ();
+
#ifdef WINDOWSNT
globals_of_w32 ();
#ifdef HAVE_W32NOTIFY
@@ -2116,6 +2186,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#endif
syms_of_window ();
syms_of_xdisp ();
+ syms_of_sqlite ();
syms_of_font ();
#ifdef HAVE_WINDOW_SYSTEM
syms_of_fringe ();
@@ -2177,6 +2248,27 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
syms_of_fontset ();
#endif /* HAVE_NS */
+#ifdef HAVE_PGTK
+ syms_of_pgtkterm ();
+ syms_of_pgtkfns ();
+ syms_of_pgtkselect ();
+ syms_of_pgtkmenu ();
+ syms_of_pgtkim ();
+ syms_of_fontset ();
+ syms_of_xsettings ();
+#endif /* HAVE_PGTK */
+#ifdef HAVE_HAIKU
+ syms_of_haikuterm ();
+ syms_of_haikufns ();
+ syms_of_haikumenu ();
+ syms_of_haikufont ();
+ syms_of_haikuselect ();
+#ifdef HAVE_NATIVE_IMAGE_API
+ syms_of_haikuimage ();
+#endif
+ syms_of_fontset ();
+#endif /* HAVE_HAIKU */
+
syms_of_gnutls ();
#ifdef HAVE_INOTIFY
@@ -2231,6 +2323,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#if defined WINDOWSNT || defined HAVE_NTGUI
globals_of_w32select ();
#endif
+
+#ifdef HAVE_HAIKU
+ init_haiku_select ();
+#endif
}
init_charset ();
@@ -2244,7 +2340,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#ifdef HAVE_DBUS
init_dbusbind ();
#endif
-#ifdef USE_GTK
+#if defined(USE_GTK) && !defined(HAVE_PGTK)
init_xterm ();
#endif
@@ -2284,6 +2380,17 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
/* Unless next switch is -nl, load "loadup.el" first thing. */
if (! no_loadup)
Vtop_level = list2 (Qload, build_string ("loadup.el"));
+
+#ifdef HAVE_NATIVE_COMP
+ /* If we are going to load stuff in a non-initialized Emacs,
+ update the value of native-comp-eln-load-path, so that the
+ *.eln files will be found if they are there. */
+ if (!NILP (Vtop_level) && !temacs)
+ Vnative_comp_eln_load_path =
+ Fcons (Fexpand_file_name (XCAR (Vnative_comp_eln_load_path),
+ Vinvocation_directory),
+ Qnil);
+#endif
}
/* Set up for profiling. This is known to work on FreeBSD,
@@ -2305,6 +2412,11 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
if (dump_mode)
Vdump_mode = build_string (dump_mode);
+#ifdef HAVE_PDUMPER
+ /* Allow code to be run (mostly useful after redumping). */
+ safe_run_hooks (Qafter_pdump_load_hook);
+#endif
+
/* Enter editor command loop. This never returns. */
set_initial_minibuffer_mode ();
Frecursive_edit ();
@@ -2327,6 +2439,9 @@ struct standard_args
static const struct standard_args standard_args[] =
{
{ "-version", "--version", 150, 0 },
+#ifdef HAVE_PDUMPER
+ { "-fingerprint", "--fingerprint", 140, 0 },
+#endif
{ "-chdir", "--chdir", 130, 1 },
{ "-t", "--terminal", 120, 1 },
{ "-nw", "--no-window-system", 110, 0 },
@@ -2690,6 +2805,9 @@ shut_down_emacs (int sig, Lisp_Object stuff)
/* Don't update display from now on. */
Vinhibit_redisplay = Qt;
+#ifdef HAVE_HAIKU
+ be_app_quit ();
+#endif
/* If we are controlling the terminal, reset terminal modes. */
#ifndef DOS_NT
pid_t tpgrp = tcgetpgrp (STDIN_FILENO);
@@ -2699,6 +2817,10 @@ shut_down_emacs (int sig, Lisp_Object stuff)
if (sig && sig != SIGTERM)
{
static char const fmt[] = "Fatal error %d: %n%s\n";
+#ifdef HAVE_HAIKU
+ if (haiku_debug_on_fatal_error)
+ debugger ("Fatal error in Emacs");
+#endif
char buf[max ((sizeof fmt - sizeof "%d%n%s\n"
+ INT_STRLEN_BOUND (int) + 1),
min (PIPE_BUF, MAX_ALLOCA))];
@@ -3191,6 +3313,7 @@ Special values:
`ms-dos' compiled as an MS-DOS application.
`windows-nt' compiled as a native W32 application.
`cygwin' compiled using the Cygwin library.
+ `haiku' compiled for a Haiku system.
Anything else (in Emacs 26, the possibilities are: aix, berkeley-unix,
hpux, usg-unix-v) indicates some sort of Unix system. */);
Vsystem_type = intern_c_string (SYSTEM_TYPE);
diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c
index 996ded2acaa..78c952f8054 100644
--- a/src/emacsgtkfixed.c
+++ b/src/emacsgtkfixed.c
@@ -22,7 +22,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "lisp.h"
#include "frame.h"
+#ifdef HAVE_PGTK
+#include "pgtkterm.h"
+#else
#include "xterm.h"
+#endif
#include "xwidget.h"
#include "emacsgtkfixed.h"
@@ -47,7 +51,9 @@ static void emacs_fixed_get_preferred_width (GtkWidget *widget,
static void emacs_fixed_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural);
+#ifndef HAVE_PGTK
static GType emacs_fixed_get_type (void);
+#endif
G_DEFINE_TYPE (EmacsFixed, emacs_fixed, GTK_TYPE_FIXED)
static EmacsFixed *
@@ -57,92 +63,6 @@ EMACS_FIXED (GtkWidget *widget)
EmacsFixed);
}
-#ifdef HAVE_XWIDGETS
-
-static EmacsFixedClass *
-EMACS_FIXED_GET_CLASS (GtkWidget *widget)
-{
- return G_TYPE_INSTANCE_GET_CLASS (widget, emacs_fixed_get_type (),
- EmacsFixedClass);
-}
-
-struct GtkFixedPrivateL
-{
- GList *children;
-};
-
-static void
-emacs_fixed_gtk_widget_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- /* For xwidgets.
-
- This basically re-implements the base class method and adds an
- additional case for an xwidget view.
-
- It would be nicer if the bse class method could be called first,
- and the xview modification only would remain here. It wasn't
- possible to solve it that way yet. */
- EmacsFixedClass *klass;
- GtkWidgetClass *parent_class;
- struct GtkFixedPrivateL *priv;
-
- klass = EMACS_FIXED_GET_CLASS (widget);
- parent_class = g_type_class_peek_parent (klass);
- parent_class->size_allocate (widget, allocation);
-
- priv = G_TYPE_INSTANCE_GET_PRIVATE (widget, GTK_TYPE_FIXED,
- struct GtkFixedPrivateL);
-
- gtk_widget_set_allocation (widget, allocation);
-
- if (gtk_widget_get_has_window (widget))
- {
- if (gtk_widget_get_realized (widget))
- gdk_window_move_resize (gtk_widget_get_window (widget),
- allocation->x,
- allocation->y,
- allocation->width,
- allocation->height);
- }
-
- for (GList *children = priv->children; children; children = children->next)
- {
- GtkFixedChild *child = children->data;
-
- if (!gtk_widget_get_visible (child->widget))
- continue;
-
- GtkRequisition child_requisition;
- gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
-
- GtkAllocation child_allocation;
- child_allocation.x = child->x;
- child_allocation.y = child->y;
-
- if (!gtk_widget_get_has_window (widget))
- {
- child_allocation.x += allocation->x;
- child_allocation.y += allocation->y;
- }
-
- child_allocation.width = child_requisition.width;
- child_allocation.height = child_requisition.height;
-
- struct xwidget_view *xv
- = g_object_get_data (G_OBJECT (child->widget), XG_XWIDGET_VIEW);
- if (xv)
- {
- child_allocation.width = xv->clip_right;
- child_allocation.height = xv->clip_bottom - xv->clip_top;
- }
-
- gtk_widget_size_allocate (child->widget, &child_allocation);
- }
-}
-
-#endif /* HAVE_XWIDGETS */
-
static void
emacs_fixed_class_init (EmacsFixedClass *klass)
{
@@ -152,9 +72,6 @@ emacs_fixed_class_init (EmacsFixedClass *klass)
widget_class->get_preferred_width = emacs_fixed_get_preferred_width;
widget_class->get_preferred_height = emacs_fixed_get_preferred_height;
-#ifdef HAVE_XWIDGETS
- widget_class->size_allocate = emacs_fixed_gtk_widget_size_allocate;
-#endif
g_type_class_add_private (klass, sizeof (EmacsFixedPrivate));
}
@@ -182,9 +99,15 @@ emacs_fixed_get_preferred_width (GtkWidget *widget,
{
EmacsFixed *fixed = EMACS_FIXED (widget);
EmacsFixedPrivate *priv = fixed->priv;
+#ifdef HAVE_PGTK
+ int w = priv->f->output_data.pgtk->size_hints.min_width;
+ if (minimum) *minimum = w;
+ if (natural) *natural = priv->f->output_data.pgtk->preferred_width;
+#else
int w = priv->f->output_data.x->size_hints.min_width;
if (minimum) *minimum = w;
if (natural) *natural = w;
+#endif
}
static void
@@ -194,12 +117,20 @@ emacs_fixed_get_preferred_height (GtkWidget *widget,
{
EmacsFixed *fixed = EMACS_FIXED (widget);
EmacsFixedPrivate *priv = fixed->priv;
+#ifdef HAVE_PGTK
+ int h = priv->f->output_data.pgtk->size_hints.min_height;
+ if (minimum) *minimum = h;
+ if (natural) *natural = priv->f->output_data.pgtk->preferred_height;
+#else
int h = priv->f->output_data.x->size_hints.min_height;
if (minimum) *minimum = h;
if (natural) *natural = h;
+#endif
}
+#ifndef HAVE_PGTK
+
/* Override the X function so we can intercept Gtk+ 3 calls.
Use our values for min_width/height so that KDE don't freak out
(Bug#8919), and so users can resize our frames as they wish. */
@@ -234,8 +165,13 @@ XSetWMSizeHints (Display *d,
if ((hints->flags & PMinSize) && f)
{
+#ifdef HAVE_PGTK
+ int w = f->output_data.pgtk->size_hints.min_width;
+ int h = f->output_data.pgtk->size_hints.min_height;
+#else
int w = f->output_data.x->size_hints.min_width;
int h = f->output_data.x->size_hints.min_height;
+#endif
data[5] = w;
data[6] = h;
}
@@ -253,3 +189,5 @@ XSetWMNormalHints (Display *d, Window w, XSizeHints *hints)
{
XSetWMSizeHints (d, w, hints, XA_WM_NORMAL_HINTS);
}
+
+#endif
diff --git a/src/emacsgtkfixed.h b/src/emacsgtkfixed.h
index 78879764d86..4f7a4eb3f71 100644
--- a/src/emacsgtkfixed.h
+++ b/src/emacsgtkfixed.h
@@ -27,6 +27,11 @@ struct frame;
G_BEGIN_DECLS
+#ifdef HAVE_PGTK
+#define EMACS_TYPE_FIXED (emacs_fixed_get_type ())
+#define EMACS_IS_FIXED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EMACS_TYPE_FIXED))
+#endif
+
struct frame;
typedef struct _EmacsFixedPrivate EmacsFixedPrivate;
@@ -44,6 +49,10 @@ struct _EmacsFixedClass
GtkFixedClass parent_class;
};
+#ifdef HAVE_PGTK
+extern GType emacs_fixed_get_type (void);
+#endif
+
extern GtkWidget *emacs_fixed_new (struct frame *f);
G_END_DECLS
diff --git a/src/eval.c b/src/eval.c
index 48104bd0f45..fe29564aa2d 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -29,6 +29,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "dispextern.h"
#include "buffer.h"
#include "pdumper.h"
+#include "atimer.h"
/* CACHEABLE is ordinarily nothing, except it is 'volatile' if
necessary to cajole GCC into not warning incorrectly that a
@@ -219,17 +220,14 @@ void
init_eval_once (void)
{
/* Don't forget to update docs (lispref node "Local Variables"). */
- if (!NATIVE_COMP_FLAG)
- {
- max_specpdl_size = 1800; /* See bug#46818. */
- max_lisp_eval_depth = 800;
- }
- else
- {
- /* Original values increased for comp.el. */
- max_specpdl_size = 2500;
- max_lisp_eval_depth = 1600;
- }
+#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;
+ max_lisp_eval_depth = 1600;
+#endif
Vrun_hooks = Qnil;
pdumper_do_now_and_after_load (init_eval_once_for_pdumper);
}
@@ -364,9 +362,6 @@ do_debug_on_call (Lisp_Object code, ptrdiff_t count)
call_debugger (list1 (code));
}
-/* NOTE!!! Every function that can call EVAL must protect its args
- and temporaries from garbage collection while it needs them.
- The definition of `For' shows what you have to do. */
DEFUN ("or", For, Sor, 0, UNEVALLED, 0,
doc: /* Eval args until one of them yields non-nil, then return that value.
@@ -1081,6 +1076,47 @@ usage: (while TEST BODY...) */)
return Qnil;
}
+static void
+with_delayed_message_display (struct atimer *timer)
+{
+ message3 (build_string (timer->client_data));
+}
+
+static void
+with_delayed_message_cancel (void *timer)
+{
+ xfree (((struct atimer *) timer)->client_data);
+ cancel_atimer (timer);
+}
+
+DEFUN ("funcall-with-delayed-message",
+ Ffuncall_with_delayed_message, Sfuncall_with_delayed_message,
+ 3, 3, 0,
+ doc: /* Like `funcall', but display MESSAGE if FUNCTION takes longer than TIMEOUT.
+TIMEOUT is a number of seconds, and can be an integer or a floating
+point number.
+
+If FUNCTION takes less time to execute than TIMEOUT seconds, MESSAGE
+is not displayed. */)
+ (Lisp_Object timeout, Lisp_Object message, Lisp_Object function)
+{
+ ptrdiff_t count = SPECPDL_INDEX ();
+
+ CHECK_NUMBER (timeout);
+ CHECK_STRING (message);
+
+ /* Set up the atimer. */
+ struct timespec interval = dtotimespec (XFLOATINT (timeout));
+ struct atimer *timer = start_atimer (ATIMER_RELATIVE, interval,
+ with_delayed_message_display,
+ xstrdup (SSDATA (message)));
+ record_unwind_protect_ptr (with_delayed_message_cancel, timer);
+
+ Lisp_Object result = CALLN (Ffuncall, function);
+
+ return unbind_to (count, result);
+}
+
DEFUN ("macroexpand", Fmacroexpand, Smacroexpand, 1, 2, 0,
doc: /* Return result of expanding macros at top level of FORM.
If FORM is not a macro call, it is returned unchanged.
@@ -1174,14 +1210,6 @@ usage: (catch TAG BODY...) */)
FUNC should return a Lisp_Object.
This is how catches are done from within C code. */
-/* MINIBUFFER_QUIT_LEVEL is to handle quitting from nested minibuffers by
- throwing t to tag `exit'.
- 0 means there is no (throw 'exit t) in progress, or it wasn't from
- a minibuffer which isn't the most nested;
- N > 0 means the `throw' was done from the minibuffer at level N which
- wasn't the most nested. */
-EMACS_INT minibuffer_quit_level = 0;
-
Lisp_Object
internal_catch (Lisp_Object tag,
Lisp_Object (*func) (Lisp_Object), Lisp_Object arg)
@@ -1189,9 +1217,6 @@ internal_catch (Lisp_Object tag,
/* This structure is made part of the chain `catchlist'. */
struct handler *c = push_handler (tag, CATCHER);
- if (EQ (tag, Qexit))
- minibuffer_quit_level = 0;
-
/* Call FUNC. */
if (! sys_setjmp (c->jmp))
{
@@ -1205,17 +1230,6 @@ internal_catch (Lisp_Object tag,
Lisp_Object val = handlerlist->val;
clobbered_eassert (handlerlist == c);
handlerlist = handlerlist->next;
- if (EQ (tag, Qexit) && EQ (val, Qt) && minibuffer_quit_level > 0)
- /* If we've thrown t to tag `exit' from within a minibuffer, we
- exit all minibuffers more deeply nested than the current
- one. */
- {
- if (minibuf_level > minibuffer_quit_level
- && !NILP (Fminibuffer_innermost_command_loop_p (Qnil)))
- Fthrow (Qexit, Qt);
- else
- minibuffer_quit_level = 0;
- }
return val;
}
}
@@ -3261,15 +3275,18 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
else if (MODULE_FUNCTIONP (fun))
return funcall_module (fun, nargs, arg_vector);
#endif
+#ifdef HAVE_NATIVE_COMP
else if (SUBR_NATIVE_COMPILED_DYNP (fun))
{
- syms_left = XSUBR (fun)->lambda_list[0];
+ syms_left = XSUBR (fun)->lambda_list;
lexenv = Qnil;
}
+#endif
else
emacs_abort ();
i = optional = rest = 0;
+ bool previous_rest = false;
for (; CONSP (syms_left); syms_left = XCDR (syms_left))
{
maybe_quit ();
@@ -3280,13 +3297,14 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
if (EQ (next, Qand_rest))
{
- if (rest)
+ if (rest || previous_rest)
xsignal1 (Qinvalid_function, fun);
rest = 1;
+ previous_rest = true;
}
else if (EQ (next, Qand_optional))
{
- if (optional || rest)
+ if (optional || rest || previous_rest)
xsignal1 (Qinvalid_function, fun);
optional = 1;
}
@@ -3312,10 +3330,11 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
else
/* Dynamically bind NEXT. */
specbind (next, arg);
+ previous_rest = false;
}
}
- if (!NILP (syms_left))
+ if (!NILP (syms_left) || previous_rest)
xsignal1 (Qinvalid_function, fun);
else if (i < nargs)
xsignal2 (Qwrong_number_of_arguments, fun, make_fixnum (nargs));
@@ -4333,13 +4352,19 @@ 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 increase the total number past this amount,
-an error is signaled.
-You can safely use a value considerably larger than the default value,
-if that proves inconveniently small. However, if you increase it too far,
-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. */);
+
+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.
@@ -4527,6 +4552,7 @@ alist of active lexical bindings. */);
defsubr (&Slet);
defsubr (&SletX);
defsubr (&Swhile);
+ defsubr (&Sfuncall_with_delayed_message);
defsubr (&Smacroexpand);
defsubr (&Scatch);
defsubr (&Sthrow);
diff --git a/src/fileio.c b/src/fileio.c
index 13c99bee109..a0563ccba4b 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -945,6 +945,7 @@ the root directory. */)
USE_SAFE_ALLOCA;
CHECK_STRING (name);
+ CHECK_STRING_NULL_BYTES (name);
/* If the file name has special constructs in it,
call the corresponding file name handler. */
@@ -993,7 +994,10 @@ the root directory. */)
if (STRINGP (dir))
{
if (file_name_absolute_no_tilde_p (dir))
- default_directory = dir;
+ {
+ CHECK_STRING_NULL_BYTES (dir);
+ default_directory = dir;
+ }
else
{
Lisp_Object absdir
@@ -1307,6 +1311,8 @@ the root directory. */)
newdir = SSDATA (hdir);
newdirlim = newdir + SBYTES (hdir);
}
+ else if (!multibyte && STRING_MULTIBYTE (tem))
+ multibyte = 1;
#ifdef DOS_NT
collapse_newdir = false;
#endif
@@ -2280,6 +2286,7 @@ permissions. */)
off_t insize = st.st_size;
ssize_t copied;
+#ifndef MSDOS
for (newsize = 0; newsize < insize; newsize += copied)
{
/* Copy at most COPY_MAX bytes at a time; this is min
@@ -2294,6 +2301,7 @@ permissions. */)
break;
maybe_quit ();
}
+#endif /* MSDOS */
/* Fall back on read+write if copy_file_range failed, or if the
input is empty and so could be a /proc file. read+write will
@@ -2380,7 +2388,9 @@ permissions. */)
if (!NILP (keep_time))
{
- struct timespec ts[] = { get_stat_atime (&st), get_stat_mtime (&st) };
+ struct timespec ts[2];
+ ts[0] = get_stat_atime (&st);
+ ts[1] = get_stat_mtime (&st);
if (futimens (ofd, ts) != 0)
xsignal2 (Qfile_date_error,
build_string ("Cannot set file date"), newname);
@@ -3823,7 +3833,7 @@ restore_window_points (Lisp_Object window_markers, ptrdiff_t inserted,
Lisp_Object oldpos = XCDR (car);
if (MARKERP (marker) && FIXNUMP (oldpos)
&& XFIXNUM (oldpos) > same_at_start
- && XFIXNUM (oldpos) < same_at_end)
+ && XFIXNUM (oldpos) <= same_at_end)
{
ptrdiff_t oldsize = same_at_end - same_at_start;
ptrdiff_t newsize = inserted;
@@ -6184,7 +6194,7 @@ before any other event (mouse or keypress) is handled. */)
(void)
{
#if (defined USE_GTK || defined USE_MOTIF \
- || defined HAVE_NS || defined HAVE_NTGUI)
+ || defined HAVE_NS || defined HAVE_NTGUI || defined HAVE_HAIKU)
if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
&& use_dialog_box
&& use_file_dialog
diff --git a/src/filelock.c b/src/filelock.c
index cc185d96cdf..c12776246bd 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -65,7 +65,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#define BOOT_TIME_FILE "/var/run/random-seed"
#endif
-#if !defined WTMP_FILE && !defined WINDOWSNT
+#if !defined WTMP_FILE && !defined WINDOWSNT && defined BOOT_TIME
#define WTMP_FILE "/var/log/wtmp"
#endif
diff --git a/src/floatfns.c b/src/floatfns.c
index aadae4fd9d6..f52dae47193 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -347,6 +347,21 @@ int
double_integer_scale (double d)
{
int exponent = ilogb (d);
+#ifdef HAIKU
+ /* On Haiku, the values returned by ilogb are nonsensical when
+ confronted with tiny numbers, inf, or NaN, which breaks the trick
+ used by code on other platforms, so we have to test for each case
+ manually, and return the appropriate value. */
+ if (exponent == FP_ILOGB0)
+ {
+ if (isnan (d))
+ return (DBL_MANT_DIG - DBL_MIN_EXP) + 2;
+ if (isinf (d))
+ return (DBL_MANT_DIG - DBL_MIN_EXP) + 1;
+
+ return (DBL_MANT_DIG - DBL_MIN_EXP);
+ }
+#endif
return (DBL_MIN_EXP - 1 <= exponent && exponent < INT_MAX
? DBL_MANT_DIG - 1 - exponent
: (DBL_MANT_DIG - DBL_MIN_EXP
diff --git a/src/fns.c b/src/fns.c
index 5126439fd66..76c76c92ba9 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -322,7 +322,7 @@ Letter-case is significant, but text properties are ignored. */)
USE_SAFE_ALLOCA;
ptrdiff_t *column = SAFE_ALLOCA ((len1 + 1) * sizeof (ptrdiff_t));
- for (y = 1; y <= len1; y++)
+ for (y = 0; y <= len1; y++)
column[y] = y;
if (use_byte_compare)
@@ -672,6 +672,9 @@ DEFUN ("concat", Fconcat, Sconcat, 0, MANY, 0,
doc: /* Concatenate all the arguments and make the result a string.
The result is a string whose elements are the elements of all the arguments.
Each argument may be a string or a list or vector of characters (integers).
+
+Values of the `composition' property of the result are not guaranteed
+to be `eq'.
usage: (concat &rest SEQUENCES) */)
(ptrdiff_t nargs, Lisp_Object *args)
{
@@ -1174,7 +1177,7 @@ string_make_multibyte (Lisp_Object string)
/* Convert STRING (if unibyte) to a multibyte string without changing
- the number of characters. Characters 0200 trough 0237 are
+ the number of characters. Characters 0200 through 0237 are
converted to eight-bit characters. */
Lisp_Object
@@ -2852,12 +2855,16 @@ mapcar1 (EMACS_INT leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq)
return leni;
}
-DEFUN ("mapconcat", Fmapconcat, Smapconcat, 3, 3, 0,
+DEFUN ("mapconcat", Fmapconcat, Smapconcat, 2, 3, 0,
doc: /* Apply FUNCTION to each element of SEQUENCE, and concat the results as strings.
In between each pair of results, stick in SEPARATOR. Thus, " " as
SEPARATOR results in spaces between the values returned by FUNCTION.
+
SEQUENCE may be a list, a vector, a bool-vector, or a string.
-SEPARATOR must be a string, a vector, or a list of characters.
+
+Optional argument SEPARATOR must be a string, a vector, or a list of
+characters; nil stands for the empty string.
+
FUNCTION must be a function of one argument, and must return a value
that is a sequence of characters: either a string, or a vector or
list of numbers that are valid character codepoints. */)
@@ -2950,8 +2957,10 @@ do_yes_or_no_p (Lisp_Object prompt)
DEFUN ("yes-or-no-p", Fyes_or_no_p, Syes_or_no_p, 1, 1, 0,
doc: /* Ask user a yes-or-no question.
Return t if answer is yes, and nil if the answer is no.
-PROMPT is the string to display to ask the question. It should end in
-a space; `yes-or-no-p' adds \"(yes or no) \" to it.
+
+PROMPT is the string to display to ask the question; `yes-or-no-p'
+adds \"(yes or no) \" to it. It does not need to end in space, but if
+it does up to one space will be removed.
The user must confirm the answer with RET, and can edit it until it
has been confirmed.
diff --git a/src/font.c b/src/font.c
index e043ef8d01b..f2fd64e76ee 100644
--- a/src/font.c
+++ b/src/font.c
@@ -57,24 +57,28 @@ struct table_entry
int numeric;
/* The first one is a valid name as a face attribute.
The second one (if any) is a typical name in XLFD field. */
- const char *names[5];
+ const char *names[6];
};
+/* The following tables should be in sync with 'custom-face-attributes'. */
+
/* Table of weight numeric values and their names. This table must be
- sorted by numeric values in ascending order. */
+ sorted by numeric values in ascending order and the numeric values
+ must approximately match the weights in the font files. */
static const struct table_entry weight_table[] =
{
{ 0, { "thin" }},
- { 20, { "ultra-light", "ultralight" }},
- { 40, { "extra-light", "extralight" }},
+ { 40, { "ultra-light", "ultralight", "extra-light", "extralight" }},
{ 50, { "light" }},
- { 75, { "semi-light", "semilight", "demilight", "book" }},
- { 100, { "normal", "medium", "regular", "unspecified" }},
- { 180, { "semi-bold", "semibold", "demibold", "demi" }},
+ { 55, { "semi-light", "semilight", "demilight" }},
+ { 80, { "regular", "normal", "unspecified", "book" }},
+ { 100, { "medium" }},
+ { 180, { "semi-bold", "semibold", "demibold", "demi-bold", "demi" }},
{ 200, { "bold" }},
- { 205, { "extra-bold", "extrabold" }},
- { 210, { "ultra-bold", "ultrabold", "black" }}
+ { 205, { "extra-bold", "extrabold", "ultra-bold", "ultrabold" }},
+ { 210, { "black", "heavy" }},
+ { 250, { "ultra-heavy", "ultraheavy" }}
};
/* Table of slant numeric values and their names. This table must be
@@ -1484,11 +1488,20 @@ font_parse_fcname (char *name, ptrdiff_t len, Lisp_Object font)
#define PROP_MATCH(STR) (word_len == strlen (STR) \
&& memcmp (p, STR, strlen (STR)) == 0)
- if (PROP_MATCH ("light")
+ if (PROP_MATCH ("thin")
+ || PROP_MATCH ("ultra-light")
+ || PROP_MATCH ("light")
+ || PROP_MATCH ("semi-light")
+ || PROP_MATCH ("book")
|| PROP_MATCH ("medium")
+ || PROP_MATCH ("normal")
+ || PROP_MATCH ("semibold")
|| PROP_MATCH ("demibold")
|| PROP_MATCH ("bold")
- || PROP_MATCH ("black"))
+ || PROP_MATCH ("ultra-bold")
+ || PROP_MATCH ("black")
+ || PROP_MATCH ("heavy")
+ || PROP_MATCH ("ultra-heavy"))
FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, val);
else if (PROP_MATCH ("roman")
|| PROP_MATCH ("italic")
@@ -2748,10 +2761,34 @@ font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size)
continue;
}
for (prop = FONT_WEIGHT_INDEX; prop < FONT_SIZE_INDEX; prop++)
- if (FIXNUMP (AREF (spec, prop))
- && ((XFIXNUM (AREF (spec, prop)) >> 8)
- != (XFIXNUM (AREF (entity, prop)) >> 8)))
- prop = FONT_SPEC_MAX;
+ {
+ if (FIXNUMP (AREF (spec, prop)))
+ {
+ int required = XFIXNUM (AREF (spec, prop)) >> 8;
+ int candidate = XFIXNUM (AREF (entity, prop)) >> 8;
+
+ if (candidate != required
+ /* A kludge for w32 font search, where listing a
+ family returns only 4 standard weights: regular,
+ italic, bold, bold-italic. For other values one
+ must specify the font, not just the family in the
+ :family attribute of the face. But specifying
+ :family in the face attributes looks for regular
+ weight, so if we require exact match, the
+ non-regular font will be rejected. So we relax
+ the accuracy of the match here, and let
+ font_sort_entities find the best match.
+
+ Similar things happen on Posix platforms, when
+ people use font families that don't have the
+ regular weight, only the medium weight: these
+ families get rejected if we require an exact match. */
+ && (prop != FONT_WEIGHT_INDEX
+ || eabs (candidate - required) > 100)
+ )
+ prop = FONT_SPEC_MAX;
+ }
+ }
if (prop < FONT_SPEC_MAX
&& size
&& XFIXNUM (AREF (entity, FONT_SIZE_INDEX)) > 0)
@@ -3151,8 +3188,9 @@ font_clear_prop (Lisp_Object *attrs, enum font_property_index prop)
attrs[LFACE_FONT_INDEX] = font;
}
-/* Select a font from ENTITIES (list of font-entity vectors) that
- supports C and is the best match for ATTRS and PIXEL_SIZE. */
+/* Select a font from ENTITIES (list of one or more font-entity
+ vectors) that supports the character C (if non-negative) and is the
+ best match for ATTRS and PIXEL_SIZE. */
static Lisp_Object
font_select_entity (struct frame *f, Lisp_Object entities,
@@ -3162,6 +3200,7 @@ font_select_entity (struct frame *f, Lisp_Object entities,
Lisp_Object prefer;
int i;
+ /* If we have a single candidate, return it if it supports C. */
if (NILP (XCDR (entities))
&& ASIZE (XCAR (entities)) == 1)
{
@@ -3171,7 +3210,10 @@ font_select_entity (struct frame *f, Lisp_Object entities,
return Qnil;
}
- /* Sort fonts by properties specified in ATTRS. */
+ /* If we have several candidates, find the best match by sorting
+ them by properties specified in ATTRS. Style attributes (weight,
+ slant, width, and size) are taken from the font spec in ATTRS (if
+ that is non-nil), or from ATTRS, or left as nil. */
prefer = scratch_font_prefer;
for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++)
@@ -3208,6 +3250,8 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int
int i, j, k, l;
USE_SAFE_ALLOCA;
+ /* Registry specification alternatives: from the most specific to
+ the least specific and finally an unspecified one. */
registry[0] = AREF (spec, FONT_REGISTRY_INDEX);
if (NILP (registry[0]))
{
@@ -3244,6 +3288,9 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int
pixel_size = 1;
}
ASET (work, FONT_SIZE_INDEX, Qnil);
+
+ /* Foundry specification alternatives: from the most specific to the
+ least specific and finally an unspecified one. */
foundry[0] = AREF (work, FONT_FOUNDRY_INDEX);
if (! NILP (foundry[0]))
foundry[1] = zero_vector;
@@ -3257,6 +3304,8 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int
else
foundry[0] = Qnil, foundry[1] = zero_vector;
+ /* Additional style specification alternatives: from the most
+ specific to the least specific and finally an unspecified one. */
adstyle[0] = AREF (work, FONT_ADSTYLE_INDEX);
if (! NILP (adstyle[0]))
adstyle[1] = zero_vector;
@@ -3277,6 +3326,8 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int
adstyle[0] = Qnil, adstyle[1] = zero_vector;
+ /* Family specification alternatives: from the most specific to
+ the least specific and finally an unspecified one. */
val = AREF (work, FONT_FAMILY_INDEX);
if (NILP (val) && STRINGP (attrs[LFACE_FAMILY_INDEX]))
{
@@ -3316,6 +3367,8 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int
}
}
+ /* Now look up suitable fonts, from the most specific spec to the
+ least specific spec. Accept the first one that matches. */
for (i = 0; SYMBOLP (family[i]); i++)
{
ASET (work, FONT_FAMILY_INDEX, family[i]);
@@ -3328,9 +3381,12 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int
for (l = 0; SYMBOLP (adstyle[l]); l++)
{
ASET (work, FONT_ADSTYLE_INDEX, adstyle[l]);
+ /* Produce the list of candidates for the spec in WORK. */
entities = font_list_entities (f, work);
if (! NILP (entities))
{
+ /* If there are several candidates, select the
+ best match for PIXEL_SIZE and attributes in ATTRS. */
val = font_select_entity (f, entities,
attrs, pixel_size, c);
if (! NILP (val))
@@ -3860,12 +3916,32 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w,
#ifdef HAVE_WINDOW_SYSTEM
+/* Check if CH is a codepoint for which we should attempt to use the
+ emoji font, even if the codepoint itself has Emoji_Presentation =
+ No. Vauto_composition_emoji_eligible_codepoints is filled in for
+ us by admin/unidata/emoji-zwj.awk. */
+static bool
+codepoint_is_emoji_eligible (int ch)
+{
+ if (EQ (CHAR_TABLE_REF (Vchar_script_table, ch), Qemoji))
+ return true;
+
+ if (! NILP (Fmemq (make_fixnum (ch),
+ Vauto_composition_emoji_eligible_codepoints)))
+ return true;
+
+ return false;
+}
+
/* Check how many characters after character/byte position POS/POS_BYTE
(at most to *LIMIT) can be displayed by the same font in the window W.
FACE, if non-NULL, is the face selected for the character at POS.
If STRING is not nil, it is the string to check instead of the current
buffer. In that case, FACE must be not NULL.
+ CH is the character that actually caused the composition
+ process to start, it may be different from the character at POS.
+
The return value is the font-object for the character at POS.
*LIMIT is set to the position where that font can't be used.
@@ -3873,15 +3949,16 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w,
Lisp_Object
font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit,
- struct window *w, struct face *face, Lisp_Object string)
+ struct window *w, struct face *face, Lisp_Object string,
+ int ch)
{
ptrdiff_t ignore;
int c;
Lisp_Object font_object = Qnil;
+ struct frame *f = XFRAME (w->frame);
if (!face)
{
- struct frame *f = XFRAME (w->frame);
int face_id;
if (NILP (string))
@@ -3900,6 +3977,23 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit,
face = FACE_FROM_ID (f, face_id);
}
+ /* If the composition was triggered by an emoji, use a character
+ from 'script-representative-chars', rather than the first
+ character in the string, to determine the font to use. */
+ if (codepoint_is_emoji_eligible (ch))
+ {
+ Lisp_Object val = assq_no_quit (Qemoji, Vscript_representative_chars);
+ if (CONSP (val))
+ {
+ val = XCDR (val);
+ if (CONSP (val))
+ val = XCAR (val);
+ else if (VECTORP (val))
+ val = AREF (val, 0);
+ font_object = font_for_char (face, XFIXNAT (val), pos, string);
+ }
+ }
+
while (pos < *limit)
{
c = (NILP (string)
@@ -4928,6 +5022,33 @@ If the font is not OpenType font, CAPABILITY is nil. */)
: Qnil));
}
+DEFUN ("font-has-char-p", Ffont_has_char_p, Sfont_has_char_p, 2, 3, 0,
+ doc:
+ /* Return non-nil if FONT on FRAME has a glyph for character CH.
+FONT can be either a font-entity or a font-object. If it is
+a font-entity and the result is nil, it means the font needs to be
+opened (with `open-font') to check.
+FRAME defaults to the selected frame if it is nil or omitted. */)
+ (Lisp_Object font, Lisp_Object ch, Lisp_Object frame)
+{
+ struct frame *f;
+ CHECK_FONT (font);
+ CHECK_CHARACTER (ch);
+
+ if (NILP (frame))
+ f = XFRAME (selected_frame);
+ else
+ {
+ CHECK_FRAME (frame);
+ f = XFRAME (frame);
+ }
+
+ if (font_has_char (f, font, XFIXNAT (ch)) <= 0)
+ return Qnil;
+ else
+ return Qt;
+}
+
DEFUN ("font-get-glyphs", Ffont_get_glyphs, Sfont_get_glyphs, 3, 4, 0,
doc:
/* Return a vector of FONT-OBJECT's glyphs for the specified characters.
@@ -4946,8 +5067,13 @@ where
CODE is the glyph-code of C in FONT-OBJECT.
WIDTH thru DESCENT are the metrics (in pixels) of the glyph.
ADJUSTMENT is always nil.
-If FONT-OBJECT doesn't have a glyph for a character,
-the corresponding element is nil. */)
+
+If FONT-OBJECT doesn't have a glyph for a character, the corresponding
+element is nil.
+
+Also see `font-has-char-p', which is more efficient than this function
+if you just want to check whether FONT-OBJECT has a glyph for a
+character. */)
(Lisp_Object font_object, Lisp_Object from, Lisp_Object to,
Lisp_Object object)
{
@@ -5423,6 +5549,7 @@ syms_of_font (void)
DEFSYM (Qiso8859_1, "iso8859-1");
DEFSYM (Qiso10646_1, "iso10646-1");
DEFSYM (Qunicode_bmp, "unicode-bmp");
+ DEFSYM (Qemoji, "emoji");
/* Symbols representing keys of font extra info. */
DEFSYM (QCotf, ":otf");
@@ -5498,6 +5625,7 @@ syms_of_font (void)
defsubr (&Sclose_font);
defsubr (&Squery_font);
defsubr (&Sfont_get_glyphs);
+ defsubr (&Sfont_has_char_p);
defsubr (&Sfont_match_p);
defsubr (&Sfont_at);
#if 0
@@ -5616,7 +5744,11 @@ match. */);
syms_of_xftfont ();
#endif /* HAVE_XFT */
#endif /* not USE_CAIRO */
-#endif /* HAVE_X_WINDOWS */
+#else /* not HAVE_X_WINDOWS */
+#ifdef USE_CAIRO
+ syms_of_ftcrfont ();
+#endif
+#endif /* not HAVE_X_WINDOWS */
#else /* not HAVE_FREETYPE */
#ifdef HAVE_X_WINDOWS
syms_of_xfont ();
@@ -5628,6 +5760,9 @@ match. */);
#ifdef HAVE_NTGUI
syms_of_w32font ();
#endif /* HAVE_NTGUI */
+#ifdef USE_BE_CAIRO
+ syms_of_ftcrfont ();
+#endif
#endif /* HAVE_WINDOW_SYSTEM */
}
diff --git a/src/font.h b/src/font.h
index d3e15306427..2da5ec45047 100644
--- a/src/font.h
+++ b/src/font.h
@@ -69,9 +69,10 @@ INLINE_HEADER_BEGIN
enum font_property_index
{
- /* FONT-TYPE is a symbol indicating a font backend; currently `x'
- and `xft' are available on X, `uniscribe' and `gdi' on
- Windows, and `ns' under Cocoa / GNUstep. */
+ /* FONT-TYPE is a symbol indicating a font backend; currently `x',
+ `xft', `xfthb', `ftrc', and `ftcrhb' are available on X;
+ `harfbuzz', `uniscribe', and `gdi' on Windows, and `ns' under
+ Cocoa / GNUstep. */
FONT_TYPE_INDEX,
/* FONT-FOUNDRY is a foundry name (symbol). */
@@ -885,7 +886,7 @@ valid_font_driver (struct font_driver const *d)
extern Lisp_Object font_update_drivers (struct frame *f, Lisp_Object list);
extern Lisp_Object font_range (ptrdiff_t, ptrdiff_t, ptrdiff_t *,
struct window *, struct face *,
- Lisp_Object);
+ Lisp_Object, int);
extern void font_fill_lglyph_metrics (Lisp_Object, struct font *, unsigned int);
extern Lisp_Object font_put_extra (Lisp_Object font, Lisp_Object prop,
@@ -964,7 +965,7 @@ extern struct font_driver const nsfont_driver;
extern void syms_of_nsfont (void);
extern void syms_of_macfont (void);
#endif /* HAVE_NS */
-#ifdef USE_CAIRO
+#if defined (USE_CAIRO) || defined (USE_BE_CAIRO)
extern struct font_driver const ftcrfont_driver;
#ifdef HAVE_HARFBUZZ
extern struct font_driver ftcrhbfont_driver;
@@ -998,7 +999,7 @@ extern void font_deferred_log (const char *, Lisp_Object, Lisp_Object);
INLINE bool
font_data_structures_may_be_ill_formed (void)
{
-#ifdef USE_CAIRO
+#if defined USE_CAIRO || defined USE_BE_CAIRO
/* Although this works around Bug#20890, it is probably not the
right thing to do. */
return gc_in_progress;
diff --git a/src/frame.c b/src/frame.c
index b105268d423..2b06bc821d0 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -225,7 +225,9 @@ Value is:
`x' for an Emacs frame that is really an X window,
`w32' for an Emacs frame that is a window on MS-Windows display,
`ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
- `pc' for a direct-write MS-DOS frame.
+ `pc' for a direct-write MS-DOS frame,
+ `pgtk' for an Emacs frame running on pure GTK.
+ `haiku' for an Emacs frame running in Haiku.
See also `frame-live-p'. */)
(Lisp_Object object)
{
@@ -244,6 +246,10 @@ See also `frame-live-p'. */)
return Qpc;
case output_ns:
return Qns;
+ case output_pgtk:
+ return Qpgtk;
+ case output_haiku:
+ return Qhaiku;
default:
emacs_abort ();
}
@@ -729,7 +735,7 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
&& (f->new_width >= 0 || f->new_height >= 0))
/* For implied resizes with inhibit 2 (external menu and tool
bar) pick up any new sizes the display engine has not
- processed yet. Otherwsie, we would request the old sizes
+ processed yet. Otherwise, we would request the old sizes
which will make this request appear as a request to set new
sizes and have the WM react accordingly which is not TRT.
@@ -1406,11 +1412,6 @@ affects all frames on the same terminal device. */)
(t->display_info.tty->name
? build_string (t->display_info.tty->name)
: Qnil));
- /* On terminal frames the `minibuffer' frame parameter is always
- virtually t. Avoid that a different value in parms causes
- complaints, see Bug#24758. */
- store_in_alist (&parms, Qminibuffer, Qt);
- Fmodify_frame_parameters (frame, parms);
/* Make the frame face hash be frame-specific, so that each
frame could change its face definitions independently. */
@@ -1423,6 +1424,12 @@ affects all frames on the same terminal device. */)
for (idx = 0; idx < table->count; ++idx)
set_hash_value_slot (table, idx, Fcopy_sequence (HASH_VALUE (table, idx)));
+ /* On terminal frames the `minibuffer' frame parameter is always
+ virtually t. Avoid that a different value in parms causes
+ complaints, see Bug#24758. */
+ store_in_alist (&parms, Qminibuffer, Qt);
+ Fmodify_frame_parameters (frame, parms);
+
f->can_set_window_size = true;
f->after_make_frame = true;
@@ -1837,15 +1844,20 @@ prev_frame (Lisp_Object frame, Lisp_Object minibuf)
DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
doc: /* Return the next frame in the frame list after FRAME.
-It considers only frames on the same terminal as FRAME.
-By default, skip minibuffer-only frames.
-If omitted, FRAME defaults to the selected frame.
-If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
-If MINIFRAME is a window, include only its own frame
-and any frame now using that window as the minibuffer.
-If MINIFRAME is `visible', include all visible frames.
-If MINIFRAME is 0, include all visible and iconified frames.
-Otherwise, include all frames. */)
+Only frames on the same terminal as FRAME are included in the list
+of candidate frames. If omitted, FRAME defaults to the selected frame.
+
+If MINIFRAME is nil (the default), include all frames except
+minibuffer-only frames.
+
+If MINIFRAME is a window, include only its own frame and any frame now
+using that window as the minibuffer.
+
+If MINIFRAME is `visible', include only visible frames.
+
+If MINIFRAME is 0, include only visible and iconified frames.
+
+If MINIFRAME is any other value, include all frames. */)
(Lisp_Object frame, Lisp_Object miniframe)
{
if (NILP (frame))
@@ -2206,7 +2218,8 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
/* Since a similar behavior was observed on the Lucid and Motif
builds (see Bug#5802, Bug#21509, Bug#23499, Bug#27816), we now
don't delete the terminal for these builds either. */
- if (terminal->reference_count == 0 && terminal->type == output_x_window)
+ if (terminal->reference_count == 0 &&
+ (terminal->type == output_x_window || terminal->type == output_pgtk))
terminal->reference_count = 1;
#endif /* USE_X_TOOLKIT || USE_GTK */
if (terminal->reference_count == 0)
@@ -5022,8 +5035,6 @@ gui_set_no_special_glyphs (struct frame *f, Lisp_Object new_value, Lisp_Object o
}
-#ifndef HAVE_NS
-
/* Non-zero if mouse is grabbed on DPYINFO
and we know the frame where it is. */
@@ -5048,8 +5059,6 @@ gui_redo_mouse_highlight (Display_Info *dpyinfo)
dpyinfo->last_mouse_motion_y);
}
-#endif /* HAVE_NS */
-
/* Subroutines of creating an X frame. */
/* Make sure that Vx_resource_name is set to a reasonable value.
@@ -5891,7 +5900,7 @@ This function is for internal use only. */)
#ifdef HAVE_WINDOW_SYSTEM
-# if (defined USE_GTK || defined HAVE_NS || defined HAVE_XINERAMA \
+# if (defined USE_GTK || defined HAVE_PGTK || defined HAVE_NS || defined HAVE_XINERAMA \
|| defined HAVE_XRANDR)
void
free_monitors (struct MonitorInfo *monitors, int n_monitors)
@@ -5929,6 +5938,10 @@ make_monitor_attribute_list (struct MonitorInfo *monitors,
attributes);
attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)),
attributes);
+#ifdef HAVE_PGTK
+ attributes = Fcons (Fcons (Qscale_factor, make_float (mi->scale_factor)),
+ attributes);
+#endif
attributes = Fcons (Fcons (Qmm_size,
list2i (mi->mm_width, mi->mm_height)),
attributes);
@@ -6018,6 +6031,8 @@ syms_of_frame (void)
DEFSYM (Qw32, "w32");
DEFSYM (Qpc, "pc");
DEFSYM (Qns, "ns");
+ DEFSYM (Qpgtk, "pgtk");
+ DEFSYM (Qhaiku, "haiku");
DEFSYM (Qvisible, "visible");
DEFSYM (Qbuffer_predicate, "buffer-predicate");
DEFSYM (Qbuffer_list, "buffer-list");
@@ -6040,6 +6055,9 @@ syms_of_frame (void)
DEFSYM (Qworkarea, "workarea");
DEFSYM (Qmm_size, "mm-size");
+#ifdef HAVE_PGTK
+ DEFSYM (Qscale_factor, "scale-factor");
+#endif
DEFSYM (Qframes, "frames");
DEFSYM (Qsource, "source");
@@ -6232,7 +6250,10 @@ when the mouse is over clickable text. */);
DEFVAR_LISP ("make-pointer-invisible", Vmake_pointer_invisible,
doc: /* If non-nil, make mouse pointer invisible while typing.
-The pointer becomes visible again when the mouse is moved. */);
+The pointer becomes visible again when the mouse is moved.
+
+When using this, you might also want to disable highlighting of
+clickable text. See `mouse-highlight'. */);
Vmake_pointer_invisible = Qt;
DEFVAR_LISP ("move-frame-functions", Vmove_frame_functions,
diff --git a/src/frame.h b/src/frame.h
index a8ad011889d..4060ee65c42 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -449,8 +449,8 @@ struct frame
/* Non-zero if this frame's faces need to be recomputed. */
bool_bf face_change : 1;
- /* Non-zero if this frame's image cache cannot be freed because the
- frame is in the process of being redisplayed. */
+ /* Non-zero if this frame's image cache and face cache cannot be
+ freed because the frame is in the process of being redisplayed. */
bool_bf inhibit_clear_image_cache : 1;
/* True when new_width or new_height were set by change_frame_size,
@@ -585,6 +585,8 @@ struct frame
struct x_output *x; /* From xterm.h. */
struct w32_output *w32; /* From w32term.h. */
struct ns_output *ns; /* From nsterm.h. */
+ struct pgtk_output *pgtk; /* From pgtkterm.h. */
+ struct haiku_output *haiku; /* From haikuterm.h. */
}
output_data;
@@ -852,6 +854,16 @@ default_pixels_per_inch_y (void)
#else
#define FRAME_NS_P(f) ((f)->output_method == output_ns)
#endif
+#ifndef HAVE_PGTK
+#define FRAME_PGTK_P(f) false
+#else
+#define FRAME_PGTK_P(f) ((f)->output_method == output_pgtk)
+#endif
+#ifndef HAVE_HAIKU
+#define FRAME_HAIKU_P(f) false
+#else
+#define FRAME_HAIKU_P(f) ((f)->output_method == output_haiku)
+#endif
/* FRAME_WINDOW_P tests whether the frame is a graphical window system
frame. */
@@ -864,6 +876,12 @@ default_pixels_per_inch_y (void)
#ifdef HAVE_NS
#define FRAME_WINDOW_P(f) FRAME_NS_P(f)
#endif
+#ifdef HAVE_PGTK
+#define FRAME_WINDOW_P(f) FRAME_PGTK_P(f)
+#endif
+#ifdef HAVE_HAIKU
+#define FRAME_WINDOW_P(f) FRAME_HAIKU_P (f)
+#endif
#ifndef FRAME_WINDOW_P
#define FRAME_WINDOW_P(f) ((void) (f), false)
#endif
@@ -916,6 +934,8 @@ default_pixels_per_inch_y (void)
/* Scale factor of frame F. */
#if defined HAVE_NS
# define FRAME_SCALE_FACTOR(f) (FRAME_NS_P (f) ? ns_frame_scale_factor (f) : 1)
+#elif defined HAVE_PGTK
+# define FRAME_SCALE_FACTOR(f) (FRAME_PGTK_P (f) ? pgtk_frame_scale_factor (f) : 1)
#else
# define FRAME_SCALE_FACTOR(f) 1
#endif
@@ -1673,7 +1693,7 @@ extern const char *x_get_resource_string (const char *, const char *);
extern void x_sync (struct frame *);
#endif /* HAVE_X_WINDOWS */
-#ifndef HAVE_NS
+#if !defined (HAVE_NS) && !defined (HAVE_PGTK)
/* Set F's bitmap icon, if specified among F's parameters. */
@@ -1709,6 +1729,9 @@ struct MonitorInfo {
Emacs_Rectangle geom, work;
int mm_width, mm_height;
char *name;
+#ifdef HAVE_PGTK
+ double scale_factor;
+#endif
};
extern void free_monitors (struct MonitorInfo *monitors, int n_monitors);
diff --git a/src/fringe.c b/src/fringe.c
index b651a4eb0d9..441146d135d 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -30,6 +30,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "termhooks.h"
#include "pdumper.h"
+#include "pgtkterm.h"
+
/* Fringe bitmaps are represented in three different ways:
Logical bitmaps are used internally to denote things like
@@ -1408,7 +1410,7 @@ If BITMAP overrides a standard fringe bitmap, the original bitmap is restored.
On W32 and MAC (little endian), there's no need to do this.
*/
-#if defined (HAVE_X_WINDOWS)
+#if defined (HAVE_X_WINDOWS) || defined (HAVE_PGTK)
static const unsigned char swap_nibble[16] = {
0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
@@ -1471,6 +1473,25 @@ init_fringe_bitmap (int which, struct fringe_bitmap *fb, int once_p)
#endif /* not USE_CAIRO */
#endif /* HAVE_X_WINDOWS */
+#if !defined(HAVE_X_WINDOWS) && defined (HAVE_PGTK)
+ unsigned short *bits = fb->bits;
+ int j;
+
+ for (j = 0; j < fb->height; j++)
+ {
+ unsigned short b = *bits;
+#ifdef WORDS_BIGENDIAN
+ *bits++ = (b << (16 - fb->width));
+#else
+ b = (unsigned short)((swap_nibble[b & 0xf] << 12)
+ | (swap_nibble[(b>>4) & 0xf] << 8)
+ | (swap_nibble[(b>>8) & 0xf] << 4)
+ | (swap_nibble[(b>>12) & 0xf]));
+ *bits++ = (b >> (16 - fb->width));
+#endif
+ }
+#endif /* !HAVE_X_WINDOWS && HAVE_PGTK */
+
#ifdef HAVE_NTGUI
unsigned short *bits = fb->bits;
int j;
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index db417b3e77d..49b179b0efc 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -22,7 +22,15 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <cairo-ft.h>
#include "lisp.h"
+#ifdef HAVE_X_WINDOWS
#include "xterm.h"
+#elif HAVE_HAIKU
+#include "haikuterm.h"
+#include "haiku_support.h"
+#include "termchar.h"
+#else
+#include "pgtkterm.h"
+#endif
#include "blockinput.h"
#include "charset.h"
#include "composite.h"
@@ -30,6 +38,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "ftfont.h"
#include "pdumper.h"
+#ifdef USE_BE_CAIRO
+#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
+#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
+#define BLUE_FROM_ULONG(color) ((color) & 0xff)
+#endif
+
#define METRICS_NCOLS_PER_ROW (128)
enum metrics_status
@@ -513,11 +527,52 @@ ftcrfont_draw (struct glyph_string *s,
block_input ();
+#ifndef USE_BE_CAIRO
+#ifdef HAVE_X_WINDOWS
cr = x_begin_cr_clip (f, s->gc);
+#else
+ cr = pgtk_begin_cr_clip (f);
+#endif
+#else
+ BView_draw_lock (FRAME_HAIKU_VIEW (f));
+ EmacsWindow_begin_cr_critical_section (FRAME_HAIKU_WINDOW (f));
+ cr = haiku_begin_cr_clip (f, s);
+ if (!cr)
+ {
+ BView_draw_unlock (FRAME_HAIKU_VIEW (f));
+ EmacsWindow_end_cr_critical_section (FRAME_HAIKU_WINDOW (f));
+ unblock_input ();
+ return 0;
+ }
+ BView_cr_dump_clipping (FRAME_HAIKU_VIEW (f), cr);
+
+ if (s->left_overhang && s->clip_head && !s->for_overlaps)
+ {
+ cairo_rectangle (cr, s->clip_head->x, 0,
+ FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+ cairo_clip (cr);
+ }
+#endif
if (with_background)
{
+#ifndef USE_BE_CAIRO
+#ifdef HAVE_X_WINDOWS
x_set_cr_source_with_gc_background (f, s->gc);
+#else
+ pgtk_set_cr_source_with_color (f, s->xgcv.background);
+#endif
+#else
+ struct face *face = s->face;
+
+ uint32_t col = s->hl == DRAW_CURSOR ?
+ FRAME_CURSOR_COLOR (s->f).pixel : face->background;
+
+ cairo_set_source_rgb (cr, RED_FROM_ULONG (col) / 255.0,
+ GREEN_FROM_ULONG (col) / 255.0,
+ BLUE_FROM_ULONG (col) / 255.0);
+#endif
+ s->background_filled_p = 1;
cairo_rectangle (cr, x, y - FONT_BASE (face->font),
s->width, FONT_HEIGHT (face->font));
cairo_fill (cr);
@@ -533,13 +588,33 @@ ftcrfont_draw (struct glyph_string *s,
glyphs[i].index,
NULL));
}
-
+#ifndef USE_BE_CAIRO
+#ifdef HAVE_X_WINDOWS
x_set_cr_source_with_gc_foreground (f, s->gc);
+#else
+ pgtk_set_cr_source_with_color (f, s->xgcv.foreground);
+#endif
+#else
+ uint32_t col = s->hl == DRAW_CURSOR ?
+ FRAME_OUTPUT_DATA (s->f)->cursor_fg : face->foreground;
+
+ cairo_set_source_rgb (cr, RED_FROM_ULONG (col) / 255.0,
+ GREEN_FROM_ULONG (col) / 255.0,
+ BLUE_FROM_ULONG (col) / 255.0);
+#endif
cairo_set_scaled_font (cr, ftcrfont_info->cr_scaled_font);
cairo_show_glyphs (cr, glyphs, len);
-
+#ifndef USE_BE_CAIRO
+#ifdef HAVE_X_WINDOWS
x_end_cr_clip (f);
-
+#else
+ pgtk_end_cr_clip (f);
+#endif
+#else
+ haiku_end_cr_clip (cr);
+ EmacsWindow_end_cr_critical_section (FRAME_HAIKU_WINDOW (f));
+ BView_draw_unlock (FRAME_HAIKU_VIEW (f));
+#endif
unblock_input ();
return len;
diff --git a/src/ftfont.c b/src/ftfont.c
index 12d0d72d276..cf592759ab6 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -225,8 +225,6 @@ ftfont_pattern_entity (FcPattern *p, Lisp_Object extra)
}
if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch)
{
- if (numeric >= FC_WEIGHT_REGULAR && numeric < FC_WEIGHT_MEDIUM)
- numeric = FC_WEIGHT_MEDIUM;
FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX, make_fixnum (numeric));
}
if (FcPatternGetInteger (p, FC_SLANT, 0, &numeric) == FcResultMatch)
@@ -3110,6 +3108,10 @@ syms_of_ftfont (void)
Fput (Qfreetype, Qfont_driver_superseded_by, Qfreetypehb);
#endif /* HAVE_HARFBUZZ */
+#ifdef HAVE_HAIKU
+ DEFSYM (Qmono, "mono");
+#endif
+
/* Fontconfig's generic families and their aliases. */
DEFSYM (Qmonospace, "monospace");
DEFSYM (Qsans_serif, "sans-serif");
diff --git a/src/ftfont.h b/src/ftfont.h
index f771dc159b0..cfab8d3154f 100644
--- a/src/ftfont.h
+++ b/src/ftfont.h
@@ -25,10 +25,15 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_SIZES_H
+#include FT_TRUETYPE_TABLES_H
#ifdef FT_BDF_H
# include FT_BDF_H
#endif
+#ifdef USE_BE_CAIRO
+#include <cairo.h>
+#endif
+
#ifdef HAVE_HARFBUZZ
#include <hb.h>
#include <hb-ft.h>
@@ -62,7 +67,7 @@ struct font_info
hb_font_t *hb_font;
#endif /* HAVE_HARFBUZZ */
-#ifdef USE_CAIRO
+#if defined (USE_CAIRO) || defined (USE_BE_CAIRO)
cairo_scaled_font_t *cr_scaled_font;
/* Scale factor from the bitmap strike metrics in 1/64 pixels, used
as the hb_position_t value in HarfBuzz, to those in (scaled)
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 313cfc82c26..c10b3623705 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -37,7 +37,14 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "dispextern.h"
#include "frame.h"
#include "systime.h"
+#ifndef HAVE_PGTK
#include "xterm.h"
+#define xp x
+typedef struct x_output xp_output;
+#else
+#define xp pgtk
+typedef struct pgtk_output xp_output;
+#endif
#include "blockinput.h"
#include "window.h"
#include "gtkutil.h"
@@ -47,12 +54,18 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <gdk/gdkkeysyms.h>
+#ifdef HAVE_XINPUT2
+#include <X11/extensions/XInput2.h>
+#endif
+
#ifdef HAVE_XFT
#include <X11/Xft/Xft.h>
#endif
#ifdef HAVE_GTK3
+#ifndef HAVE_PGTK
#include <gtk/gtkx.h>
+#endif
#include "emacsgtkfixed.h"
#endif
@@ -127,6 +140,7 @@ static GdkDisplay *gdpy_def;
static void
xg_set_screen (GtkWidget *w, struct frame *f)
{
+#ifndef HAVE_PGTK
if (FRAME_X_DISPLAY (f) != DEFAULT_GDK_DISPLAY ())
{
GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f));
@@ -137,6 +151,17 @@ xg_set_screen (GtkWidget *w, struct frame *f)
else
gtk_window_set_screen (GTK_WINDOW (w), gscreen);
}
+#else
+ if (FRAME_X_DISPLAY (f) != DEFAULT_GDK_DISPLAY ())
+ {
+ GdkScreen *gscreen = gdk_display_get_default_screen (FRAME_X_DISPLAY (f));
+
+ if (GTK_IS_MENU (w))
+ gtk_menu_set_screen (GTK_MENU (w), gscreen);
+ else
+ gtk_window_set_screen (GTK_WINDOW (w), gscreen);
+ }
+#endif
}
@@ -148,12 +173,20 @@ xg_set_screen (GtkWidget *w, struct frame *f)
multiple displays. */
void
+#ifndef HAVE_PGTK
xg_display_open (char *display_name, Display **dpy)
+#else
+xg_display_open (char *display_name, GdkDisplay **dpy)
+#endif
{
GdkDisplay *gdpy;
unrequest_sigio (); /* See comment in x_display_ok, xterm.c. */
+#ifndef HAVE_PGTK
gdpy = gdk_display_open (display_name);
+#else
+ gdpy = gdk_display_open (strlen (display_name) == 0 ? NULL : display_name);
+#endif
request_sigio ();
if (!gdpy_def && gdpy)
{
@@ -162,7 +195,11 @@ xg_display_open (char *display_name, Display **dpy)
gdpy);
}
+#ifndef HAVE_PGTK
*dpy = gdpy ? GDK_DISPLAY_XDISPLAY (gdpy) : NULL;
+#else
+ *dpy = gdpy;
+#endif
}
/* Scaling/HiDPI functions. */
@@ -184,6 +221,9 @@ xg_get_gdk_scale (void)
int
xg_get_scale (struct frame *f)
{
+#ifdef HAVE_PGTK
+ return 1;
+#endif
#ifdef HAVE_GTK3
if (FRAME_GTK_WIDGET (f))
return gtk_widget_get_scale_factor (FRAME_GTK_WIDGET (f));
@@ -194,8 +234,13 @@ xg_get_scale (struct frame *f)
/* Close display DPY. */
void
+#ifndef HAVE_PGTK
xg_display_close (Display *dpy)
+#else
+xg_display_close (GdkDisplay *gdpy)
+#endif
{
+#ifndef HAVE_PGTK
GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpy);
/* If this is the default display, try to change it before closing.
@@ -219,6 +264,31 @@ xg_display_close (Display *dpy)
}
gdk_display_close (gdpy);
+
+#else
+
+ /* If this is the default display, try to change it before closing.
+ If there is no other display to use, gdpy_def is set to NULL, and
+ the next call to xg_display_open resets the default display. */
+ if (gdk_display_get_default () == gdpy)
+ {
+ struct pgtk_display_info *dpyinfo;
+ GdkDisplay *gdpy_new = NULL;
+
+ /* Find another display. */
+ for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
+ if (dpyinfo->gdpy != gdpy)
+ {
+ gdpy_new = dpyinfo->gdpy;
+ gdk_display_manager_set_default_display (gdk_display_manager_get (),
+ gdpy_new);
+ break;
+ }
+ gdpy_def = gdpy_new;
+ }
+
+ gdk_display_close (gdpy);
+#endif
}
@@ -230,12 +300,19 @@ xg_display_close (Display *dpy)
scroll bars on display DPY. */
GdkCursor *
+#ifndef HAVE_PGTK
xg_create_default_cursor (Display *dpy)
+#else
+xg_create_default_cursor (GdkDisplay *gdpy)
+#endif
{
+#ifndef HAVE_PGTK
GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpy);
+#endif
return gdk_cursor_new_for_display (gdpy, GDK_LEFT_PTR);
}
+#ifndef HAVE_PGTK
/* Apply GMASK to GPIX and return a GdkPixbuf with an alpha channel. */
static GdkPixbuf *
@@ -335,6 +412,8 @@ xg_get_pixbuf_from_surface (cairo_surface_t *surface)
}
#endif /* USE_CAIRO && !HAVE_GTK3 */
+#endif /* !HAVE_PGTK */
+
static Lisp_Object
file_for_image (Lisp_Object image)
{
@@ -605,8 +684,13 @@ xg_check_special_colors (struct frame *f,
block_input ();
{
#ifdef HAVE_GTK3
+#ifndef HAVE_PGTK
GtkStyleContext *gsty
= gtk_widget_get_style_context (FRAME_GTK_OUTER_WIDGET (f));
+#else
+ GtkStyleContext *gsty
+ = gtk_widget_get_style_context (FRAME_WIDGET (f));
+#endif
GdkRGBA col;
char buf[sizeof "rgb://rrrr/gggg/bbbb"];
int state = GTK_STATE_FLAG_SELECTED|GTK_STATE_FLAG_FOCUSED;
@@ -630,9 +714,14 @@ xg_check_special_colors (struct frame *f,
r = col.red * 65535,
g = col.green * 65535,
b = col.blue * 65535;
+#ifndef HAVE_PGTK
sprintf (buf, "rgb:%04x/%04x/%04x", r, g, b);
success_p = x_parse_color (f, buf, color) != 0;
#else
+ sprintf (buf, "#%04x%04x%04x", r, g, b);
+ success_p = pgtk_parse_color (f, buf, color) != 0;
+#endif
+#else
GtkStyle *gsty = gtk_widget_get_style (FRAME_GTK_WIDGET (f));
GdkColor *grgb = get_bg
? &gsty->bg[GTK_STATE_SELECTED]
@@ -655,6 +744,9 @@ xg_check_special_colors (struct frame *f,
/***********************************************************************
Tooltips
***********************************************************************/
+
+#ifndef HAVE_PGTK
+
/* Gtk+ calls this callback when the parent of our tooltip dummy changes.
We use that to pop down the tooltip. This happens if Gtk+ for some
reason wants to change or hide the tooltip. */
@@ -665,7 +757,7 @@ hierarchy_ch_cb (GtkWidget *widget,
gpointer user_data)
{
struct frame *f = user_data;
- struct x_output *x = f->output_data.x;
+ xp_output *x = f->output_data.xp;
GtkWidget *top = gtk_widget_get_toplevel (x->ttip_lbl);
if (! top || ! GTK_IS_WINDOW (top))
@@ -687,7 +779,7 @@ qttip_cb (GtkWidget *widget,
gpointer user_data)
{
struct frame *f = user_data;
- struct x_output *x = f->output_data.x;
+ xp_output *x = f->output_data.xp;
if (x->ttip_widget == NULL)
{
GtkWidget *p;
@@ -734,7 +826,7 @@ xg_prepare_tooltip (struct frame *f,
int *width,
int *height)
{
- struct x_output *x = f->output_data.x;
+ xp_output *x = f->output_data.xp;
GtkWidget *widget;
GdkWindow *gwin;
GdkScreen *screen;
@@ -785,13 +877,19 @@ xg_prepare_tooltip (struct frame *f,
void
xg_show_tooltip (struct frame *f, int root_x, int root_y)
{
- struct x_output *x = f->output_data.x;
+ xp_output *x = f->output_data.xp;
if (x->ttip_window)
{
block_input ();
+#ifndef HAVE_PGTK
gtk_window_move (x->ttip_window, root_x / xg_get_scale (f),
root_y / xg_get_scale (f));
gtk_widget_show (GTK_WIDGET (x->ttip_window));
+#else
+ gtk_widget_show (GTK_WIDGET (x->ttip_window));
+ gtk_window_move (x->ttip_window, root_x / xg_get_scale (f),
+ root_y / xg_get_scale (f));
+#endif
unblock_input ();
}
}
@@ -803,10 +901,9 @@ xg_show_tooltip (struct frame *f, int root_x, int root_y)
bool
xg_hide_tooltip (struct frame *f)
{
- if (f->output_data.x->ttip_window)
+ if (f->output_data.xp->ttip_window)
{
- GtkWindow *win = f->output_data.x->ttip_window;
-
+ GtkWindow *win = f->output_data.xp->ttip_window;
block_input ();
gtk_widget_hide (GTK_WIDGET (win));
@@ -824,6 +921,30 @@ xg_hide_tooltip (struct frame *f)
return FALSE;
}
+#else /* HAVE_PGTK */
+
+void
+xg_show_tooltip (struct frame *f,
+ Lisp_Object string)
+{
+ Lisp_Object encoded_string = ENCODE_UTF_8 (string);
+ gtk_widget_set_tooltip_text (FRAME_GTK_OUTER_WIDGET (f)
+ ? FRAME_GTK_OUTER_WIDGET (f)
+ : FRAME_GTK_WIDGET (f),
+ SSDATA (encoded_string));
+}
+
+bool
+xg_hide_tooltip (struct frame *f)
+{
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ gtk_widget_set_tooltip_text (FRAME_GTK_OUTER_WIDGET (f), NULL);
+ gtk_widget_set_tooltip_text (FRAME_GTK_WIDGET (f), NULL);
+ return TRUE;
+}
+
+#endif /* HAVE_PGTK */
+
/***********************************************************************
General functions for creating widgets, resizing, events, e.t.c.
@@ -839,6 +960,27 @@ my_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
}
#endif
+#if defined HAVE_GTK3 && defined HAVE_XINPUT2
+bool
+xg_is_menu_window (Display *dpy, Window wdesc)
+{
+ GtkWidget *gwdesc = xg_win_to_widget (dpy, wdesc);
+
+ if (GTK_IS_WINDOW (gwdesc))
+ {
+ GtkWidget *fw = gtk_bin_get_child (GTK_BIN (gwdesc));
+ if (GTK_IS_MENU (fw))
+ {
+ GtkWidget *parent
+ = gtk_menu_shell_get_parent_shell (GTK_MENU_SHELL (fw));
+ return GTK_IS_MENU_BAR (parent);
+ }
+ }
+
+ return false;
+}
+#endif
+
/* Make a geometry string and pass that to GTK. It seems this is the
only way to get geometry position right if the user explicitly
asked for a position when starting Emacs.
@@ -954,8 +1096,23 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
bool was_visible = false;
bool hide_child_frame;
+#ifndef HAVE_PGTK
gtk_window_get_size (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
&gwidth, &gheight);
+#else
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ gtk_window_get_size (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ &gwidth, &gheight);
+ }
+ else
+ {
+ GtkAllocation alloc;
+ gtk_widget_get_allocation (FRAME_GTK_WIDGET (f), &alloc);
+ gwidth = alloc.width;
+ gheight = alloc.height;
+ }
+#endif
/* Do this before resize, as we don't know yet if we will be resized. */
FRAME_RIF (f)->clear_under_internal_border (f);
@@ -975,11 +1132,37 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
remain unchanged but giving the frame back its normal size will
be broken ... */
if (EQ (fullscreen, Qfullwidth) && width == FRAME_PIXEL_WIDTH (f))
+#ifndef HAVE_PGTK
gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
gwidth, outer_height);
+#else
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ gwidth, outer_height);
+ }
+ else
+ {
+ gtk_widget_set_size_request (FRAME_GTK_WIDGET (f),
+ gwidth, outer_height);
+ }
+#endif
else if (EQ (fullscreen, Qfullheight) && height == FRAME_PIXEL_HEIGHT (f))
+#ifndef HAVE_PGTK
gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
outer_width, gheight);
+#else
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ outer_width, gheight);
+ }
+ else
+ {
+ gtk_widget_set_size_request (FRAME_GTK_WIDGET (f),
+ outer_width, gheight);
+ }
+#endif
else if (FRAME_PARENT_FRAME (f) && FRAME_VISIBLE_P (f))
{
was_visible = true;
@@ -990,17 +1173,38 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
if (hide_child_frame)
{
block_input ();
+#ifndef HAVE_PGTK
gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
+#else
+ gtk_widget_hide (FRAME_WIDGET (f));
+#endif
unblock_input ();
}
+#ifndef HAVE_PGTK
gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
outer_width, outer_height);
+#else
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ outer_width, outer_height);
+ }
+ else
+ {
+ gtk_widget_set_size_request (FRAME_GTK_WIDGET (f),
+ outer_width, outer_height);
+ }
+#endif
if (hide_child_frame)
{
block_input ();
+#ifndef HAVE_PGTK
gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
+#else
+ gtk_widget_show_all (FRAME_WIDGET (f));
+#endif
unblock_input ();
}
@@ -1009,8 +1213,21 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
}
else
{
+#ifndef HAVE_PGTK
gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
outer_width, outer_height);
+#else
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ outer_width, outer_height);
+ }
+ else
+ {
+ gtk_widget_set_size_request (FRAME_GTK_WIDGET (f),
+ outer_width, outer_height);
+ }
+#endif
fullscreen = Qnil;
}
@@ -1035,7 +1252,9 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
/* Must call this to flush out events */
(void)gtk_events_pending ();
gdk_flush ();
+#ifndef HAVE_PGTK
x_wait_for_event (f, ConfigureNotify);
+#endif
if (!NILP (fullscreen))
/* Try to restore fullscreen state. */
@@ -1068,11 +1287,12 @@ xg_height_or_width_changed (struct frame *f)
gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
FRAME_TOTAL_PIXEL_WIDTH (f),
FRAME_TOTAL_PIXEL_HEIGHT (f));
- f->output_data.x->hint_flags = 0;
+ f->output_data.xp->hint_flags = 0;
x_wm_set_size_hint (f, 0, 0);
}
#endif
+#ifndef HAVE_PGTK
/* Convert an X Window WSESC on display DPY to its corresponding GtkWidget.
Must be done like this, because GtkWidget:s can have "hidden"
X Window that aren't accessible.
@@ -1100,6 +1320,7 @@ xg_win_to_widget (Display *dpy, Window wdesc)
unblock_input ();
return gwdesc;
}
+#endif
/* Set the background of widget W to PIXEL. */
@@ -1107,9 +1328,18 @@ static void
xg_set_widget_bg (struct frame *f, GtkWidget *w, unsigned long pixel)
{
#ifdef HAVE_GTK3
- XColor xbg;
+ Emacs_Color xbg;
xbg.pixel = pixel;
+#ifndef HAVE_PGTK
if (XQueryColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &xbg))
+#else
+ xbg.red = (pixel >> 16) & 0xff;
+ xbg.green = (pixel >> 8) & 0xff;
+ xbg.blue = (pixel >> 0) & 0xff;
+ xbg.red |= xbg.red << 8;
+ xbg.green |= xbg.green << 8;
+ xbg.blue |= xbg.blue << 8;
+#endif
{
const char format[] = "* { background-color: #%02x%02x%02x; }";
/* The format is always longer than the resulting string. */
@@ -1144,7 +1374,16 @@ style_changed_cb (GObject *go,
struct input_event event;
GdkDisplay *gdpy = user_data;
const char *display_name = gdk_display_get_name (gdpy);
+#ifndef HAVE_PGTK
Display *dpy = GDK_DISPLAY_XDISPLAY (gdpy);
+#else
+ GdkDisplay *dpy = gdpy;
+#endif
+
+#ifndef HAVE_PGTK
+ if (display_name == NULL)
+ display_name = "";
+#endif
EVENT_INIT (event);
event.kind = CONFIG_CHANGED_EVENT;
@@ -1165,7 +1404,11 @@ style_changed_cb (GObject *go,
{
struct frame *f = XFRAME (frame);
if (FRAME_LIVE_P (f)
+#ifndef HAVE_PGTK
&& FRAME_X_P (f)
+#else
+ && FRAME_PGTK_P (f)
+#endif
&& FRAME_X_DISPLAY (f) == dpy)
{
FRAME_TERMINAL (f)->set_scroll_bar_default_width_hook (f);
@@ -1179,6 +1422,7 @@ style_changed_cb (GObject *go,
/* Called when a delete-event occurs on WIDGET. */
+#ifndef HAVE_PGTK
static gboolean
delete_cb (GtkWidget *widget,
GdkEvent *event,
@@ -1186,6 +1430,7 @@ delete_cb (GtkWidget *widget,
{
return TRUE;
}
+#endif
/* Create and set up the GTK widgets for frame F.
Return true if creation succeeded. */
@@ -1199,17 +1444,27 @@ xg_create_frame_widgets (struct frame *f)
#ifndef HAVE_GTK3
GtkRcStyle *style;
#endif
+ GtkWindowType type = GTK_WINDOW_TOPLEVEL;
char *title = 0;
block_input ();
+#ifndef HAVE_PGTK /* gtk_plug not found. */
if (FRAME_X_EMBEDDED_P (f))
{
GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f));
- wtop = gtk_plug_new_for_display (gdpy, f->output_data.x->parent_desc);
+ wtop = gtk_plug_new_for_display (gdpy, f->output_data.xp->parent_desc);
}
else
- wtop = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ wtop = gtk_window_new (type);
+#else
+ if (f->tooltip)
+ {
+ type = GTK_WINDOW_POPUP;
+ }
+ wtop = gtk_window_new (type);
+ gtk_widget_add_events (wtop, GDK_ALL_EVENTS_MASK);
+#endif
/* gtk_window_set_has_resize_grip is a Gtk+ 3.0 function but Ubuntu
has backported it to Gtk+ 2.0 and they add the resize grip for
@@ -1266,8 +1521,8 @@ xg_create_frame_widgets (struct frame *f)
FRAME_GTK_OUTER_WIDGET (f) = wtop;
FRAME_GTK_WIDGET (f) = wfixed;
- f->output_data.x->vbox_widget = wvbox;
- f->output_data.x->hbox_widget = whbox;
+ f->output_data.xp->vbox_widget = wvbox;
+ f->output_data.xp->hbox_widget = whbox;
gtk_widget_set_has_window (wfixed, TRUE);
@@ -1286,7 +1541,10 @@ xg_create_frame_widgets (struct frame *f)
FIXME: gtk_widget_set_double_buffered is deprecated and might stop
working in the future. We need to migrate away from combining
X and GTK+ drawing to a pure GTK+ build. */
+
+#ifndef HAVE_PGTK
gtk_widget_set_double_buffered (wfixed, FALSE);
+#endif
#if ! GTK_CHECK_VERSION (3, 22, 0)
gtk_window_set_wmclass (GTK_WINDOW (wtop),
@@ -1294,10 +1552,12 @@ xg_create_frame_widgets (struct frame *f)
SSDATA (Vx_resource_class));
#endif
+#ifndef HAVE_PGTK
/* Add callback to do nothing on WM_DELETE_WINDOW. The default in
GTK is to destroy the widget. We want Emacs to do that instead. */
g_signal_connect (G_OBJECT (wtop), "delete-event",
G_CALLBACK (delete_cb), f);
+#endif
/* Convert our geometry parameters into a geometry string
and specify it.
@@ -1308,7 +1568,9 @@ xg_create_frame_widgets (struct frame *f)
gtk_widget_add_events (wfixed,
GDK_POINTER_MOTION_MASK
+#ifndef HAVE_PGTK
| GDK_EXPOSURE_MASK
+#endif
| GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
| GDK_KEY_PRESS_MASK
@@ -1316,13 +1578,19 @@ xg_create_frame_widgets (struct frame *f)
| GDK_LEAVE_NOTIFY_MASK
| GDK_FOCUS_CHANGE_MASK
| GDK_STRUCTURE_MASK
+#ifdef HAVE_PGTK
+ | GDK_SCROLL_MASK
+ | GDK_SMOOTH_SCROLL_MASK
+#endif
| GDK_VISIBILITY_NOTIFY_MASK);
+#ifndef HAVE_PGTK
/* Must realize the windows so the X window gets created. It is used
by callers of this function. */
gtk_widget_realize (wfixed);
FRAME_X_WINDOW (f) = GTK_WIDGET_TO_X_WIN (wfixed);
initial_set_up_x_back_buffer (f);
+#endif
/* Since GTK clears its window by filling with the background color,
we must keep X and GTK background in sync. */
@@ -1339,6 +1607,9 @@ xg_create_frame_widgets (struct frame *f)
gtk_widget_modify_style (wfixed, style);
#else
gtk_widget_set_can_focus (wfixed, TRUE);
+#ifdef HAVE_PGTK
+ gtk_widget_grab_focus (wfixed);
+#endif
gtk_window_set_resizable (GTK_WINDOW (wtop), TRUE);
#endif
@@ -1351,11 +1622,13 @@ xg_create_frame_widgets (struct frame *f)
}
/* Steal a tool tip window we can move ourselves. */
- f->output_data.x->ttip_widget = 0;
- f->output_data.x->ttip_lbl = 0;
- f->output_data.x->ttip_window = 0;
+ f->output_data.xp->ttip_widget = 0;
+ f->output_data.xp->ttip_lbl = 0;
+ f->output_data.xp->ttip_window = 0;
+#ifndef HAVE_PGTK
gtk_widget_set_tooltip_text (wtop, "Dummy text");
g_signal_connect (wtop, "query-tooltip", G_CALLBACK (qttip_cb), f);
+#endif
{
GdkScreen *screen = gtk_widget_get_screen (wtop);
@@ -1378,12 +1651,114 @@ xg_create_frame_widgets (struct frame *f)
return 1;
}
+#ifdef HAVE_PGTK
+void
+xg_create_frame_outer_widgets (struct frame *f)
+{
+ GtkWidget *wtop;
+ GtkWidget *wvbox, *whbox;
+ GtkWindowType type = GTK_WINDOW_TOPLEVEL;
+ char *title = 0;
+
+ block_input ();
+
+ wtop = gtk_window_new (type);
+ gtk_widget_add_events (wtop, GDK_ALL_EVENTS_MASK);
+
+ xg_set_screen (wtop, f);
+
+ wvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ whbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_set_homogeneous (GTK_BOX (wvbox), FALSE);
+ gtk_box_set_homogeneous (GTK_BOX (whbox), FALSE);
+
+ /* Use same names as the Xt port does. I.e. Emacs.pane.emacs by default */
+ gtk_widget_set_name (wtop, EMACS_CLASS);
+ gtk_widget_set_name (wvbox, "pane");
+
+ /* If this frame has a title or name, set it in the title bar. */
+ if (! NILP (f->title))
+ title = SSDATA (ENCODE_UTF_8 (f->title));
+ else if (! NILP (f->name))
+ title = SSDATA (ENCODE_UTF_8 (f->name));
+
+ if (title)
+ gtk_window_set_title (GTK_WINDOW (wtop), title);
+
+ if (FRAME_UNDECORATED (f))
+ {
+ gtk_window_set_decorated (GTK_WINDOW (wtop), FALSE);
+ store_frame_param (f, Qundecorated, Qt);
+ }
+
+ FRAME_GTK_OUTER_WIDGET (f) = wtop;
+ f->output_data.xp->vbox_widget = wvbox;
+ f->output_data.xp->hbox_widget = whbox;
+
+ gtk_container_add (GTK_CONTAINER (wtop), wvbox);
+ gtk_box_pack_start (GTK_BOX (wvbox), whbox, TRUE, TRUE, 0);
+
+ if (FRAME_EXTERNAL_TOOL_BAR (f))
+ update_frame_tool_bar (f);
+
+#if ! GTK_CHECK_VERSION (3, 22, 0)
+ gtk_window_set_wmclass (GTK_WINDOW (wtop),
+ SSDATA (Vx_resource_name),
+ SSDATA (Vx_resource_class));
+#endif
+
+ /* Convert our geometry parameters into a geometry string
+ and specify it.
+ GTK will itself handle calculating the real position this way. */
+ xg_set_geometry (f);
+ f->win_gravity
+ = gtk_window_get_gravity (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
+
+ gtk_window_set_resizable (GTK_WINDOW (wtop), TRUE);
+
+ if (FRAME_OVERRIDE_REDIRECT (f))
+ {
+ GdkWindow *gwin = gtk_widget_get_window (wtop);
+
+ if (gwin)
+ gdk_window_set_override_redirect (gwin, TRUE);
+ }
+
+ /* Steal a tool tip window we can move ourselves. */
+ f->output_data.xp->ttip_widget = 0;
+ f->output_data.xp->ttip_lbl = 0;
+ f->output_data.xp->ttip_window = 0;
+#ifndef HAVE_PGTK
+ gtk_widget_set_tooltip_text (wtop, "Dummy text");
+ g_signal_connect (wtop, "query-tooltip", G_CALLBACK (qttip_cb), f);
+#endif
+
+ {
+ GdkScreen *screen = gtk_widget_get_screen (wtop);
+ GtkSettings *gs = gtk_settings_get_for_screen (screen);
+ /* Only connect this signal once per screen. */
+ if (! g_signal_handler_find (G_OBJECT (gs),
+ G_SIGNAL_MATCH_FUNC,
+ 0, 0, 0,
+ (gpointer) G_CALLBACK (style_changed_cb),
+ 0))
+ {
+ g_signal_connect (G_OBJECT (gs), "notify::gtk-theme-name",
+ G_CALLBACK (style_changed_cb),
+ gdk_screen_get_display (screen));
+ }
+ }
+
+ unblock_input ();
+}
+#endif
+
void
xg_free_frame_widgets (struct frame *f)
{
if (FRAME_GTK_OUTER_WIDGET (f))
{
- struct x_output *x = f->output_data.x;
+ xp_output *x = f->output_data.xp;
struct xg_frame_tb_info *tbinfo
= g_object_get_data (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)),
TB_INFO_KEY);
@@ -1391,10 +1766,14 @@ xg_free_frame_widgets (struct frame *f)
xfree (tbinfo);
/* x_free_frame_resources should have taken care of it */
+#ifndef HAVE_PGTK
eassert (!FRAME_X_DOUBLE_BUFFERED_P (f));
+#endif
gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
FRAME_X_WINDOW (f) = 0; /* Set to avoid XDestroyWindow in xterm.c */
+#ifndef HAVE_PGTK
FRAME_X_RAW_DRAWABLE (f) = 0;
+#endif
FRAME_GTK_OUTER_WIDGET (f) = 0;
if (x->ttip_widget)
{
@@ -1436,9 +1815,12 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
XSETFRAME (frame, f);
fs_state = Fframe_parameter (frame, Qfullscreen);
- if ((EQ (fs_state, Qmaximized) || EQ (fs_state, Qfullboth)) &&
- (x_wm_supports (f, FRAME_DISPLAY_INFO (f)->Xatom_net_wm_state) ||
- x_wm_supports (f, FRAME_DISPLAY_INFO (f)->Xatom_net_wm_state_fullscreen)))
+ if ((EQ (fs_state, Qmaximized) || EQ (fs_state, Qfullboth))
+#ifndef HAVE_PGTK
+ && (x_wm_supports (f, FRAME_DISPLAY_INFO (f)->Xatom_net_wm_state) ||
+ x_wm_supports (f, FRAME_DISPLAY_INFO (f)->Xatom_net_wm_state_fullscreen))
+#endif
+ )
{
/* Don't set hints when maximized or fullscreen. Apparently KWin and
Gtk3 don't get along and the frame shrinks (!).
@@ -1449,14 +1831,14 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
if (flags)
{
memset (&size_hints, 0, sizeof (size_hints));
- f->output_data.x->size_hints = size_hints;
- f->output_data.x->hint_flags = hint_flags;
+ f->output_data.xp->size_hints = size_hints;
+ f->output_data.xp->hint_flags = hint_flags;
}
else
flags = f->size_hint_flags;
- size_hints = f->output_data.x->size_hints;
- hint_flags = f->output_data.x->hint_flags;
+ size_hints = f->output_data.xp->size_hints;
+ hint_flags = f->output_data.xp->hint_flags;
hint_flags |= GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE;
size_hints.width_inc = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f);
@@ -1518,16 +1900,16 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
size_hints.width_inc /= scale;
size_hints.height_inc /= scale;
- if (hint_flags != f->output_data.x->hint_flags
+ if (hint_flags != f->output_data.xp->hint_flags
|| memcmp (&size_hints,
- &f->output_data.x->size_hints,
+ &f->output_data.xp->size_hints,
sizeof (size_hints)) != 0)
{
block_input ();
gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
NULL, &size_hints, hint_flags);
- f->output_data.x->size_hints = size_hints;
- f->output_data.x->hint_flags = hint_flags;
+ f->output_data.xp->size_hints = size_hints;
+ f->output_data.xp->hint_flags = hint_flags;
unblock_input ();
}
}
@@ -1567,6 +1949,10 @@ xg_set_background_color (struct frame *f, unsigned long bg)
void
xg_set_undecorated (struct frame *f, Lisp_Object undecorated)
{
+#ifdef HAVE_PGTK
+ if (!FRAME_GTK_OUTER_WIDGET (f))
+ return;
+#endif
if (FRAME_GTK_WIDGET (f))
{
block_input ();
@@ -1593,7 +1979,11 @@ xg_frame_restack (struct frame *f1, struct frame *f2, bool above_flag)
XSETFRAME (frame2, f2);
gdk_window_restack (gwin1, gwin2, above_flag);
+#ifndef HAVE_PGTK
x_sync (f1);
+#else
+ gdk_flush ();
+#endif
}
unblock_input ();
}
@@ -1604,10 +1994,17 @@ void
xg_set_skip_taskbar (struct frame *f, Lisp_Object skip_taskbar)
{
block_input ();
+#ifndef HAVE_PGTK
if (FRAME_GTK_WIDGET (f))
gdk_window_set_skip_taskbar_hint
(gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f)),
NILP (skip_taskbar) ? FALSE : TRUE);
+#else
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ gdk_window_set_skip_taskbar_hint
+ (gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f)),
+ NILP (skip_taskbar) ? FALSE : TRUE);
+#endif
unblock_input ();
}
@@ -1616,6 +2013,10 @@ xg_set_skip_taskbar (struct frame *f, Lisp_Object skip_taskbar)
void
xg_set_no_focus_on_map (struct frame *f, Lisp_Object no_focus_on_map)
{
+#ifdef HAVE_PGTK
+ if (!FRAME_GTK_OUTER_WIDGET (f))
+ return;
+#endif
block_input ();
if (FRAME_GTK_WIDGET (f))
{
@@ -1631,12 +2032,19 @@ xg_set_no_focus_on_map (struct frame *f, Lisp_Object no_focus_on_map)
void
xg_set_no_accept_focus (struct frame *f, Lisp_Object no_accept_focus)
{
+ gboolean g_no_accept_focus = NILP (no_accept_focus) ? TRUE : FALSE;
+#ifdef HAVE_PGTK
+ if (!FRAME_GTK_OUTER_WIDGET (f))
+ {
+ if (FRAME_WIDGET (f))
+ gtk_widget_set_can_focus (FRAME_WIDGET (f), g_no_accept_focus);
+ return;
+ }
+#endif
block_input ();
if (FRAME_GTK_WIDGET (f))
{
GtkWindow *gwin = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f));
- gboolean g_no_accept_focus = NILP (no_accept_focus) ? TRUE : FALSE;
-
gtk_window_set_accept_focus (gwin, g_no_accept_focus);
}
unblock_input ();
@@ -1657,18 +2065,24 @@ xg_set_override_redirect (struct frame *f, Lisp_Object override_redirect)
unblock_input ();
}
+#ifndef HAVE_PGTK
/* Set the frame icon to ICON_PIXMAP/MASK. This must be done with GTK
functions so GTK does not overwrite the icon. */
void
xg_set_frame_icon (struct frame *f, Pixmap icon_pixmap, Pixmap icon_mask)
{
+#ifdef HAVE_PGTK
+ if (!FRAME_GTK_OUTER_WIDGET (f))
+ return;
+#endif
GdkPixbuf *gp = xg_get_pixbuf_from_pix_and_mask (f,
icon_pixmap,
icon_mask);
if (gp)
gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), gp);
}
+#endif
@@ -2205,6 +2619,11 @@ xg_get_file_name (struct frame *f,
int filesel_done = 0;
xg_get_file_func func;
+#ifdef HAVE_PGTK
+ if (!FRAME_GTK_OUTER_WIDGET (f))
+ error ("Can't open dialog from child frames");
+#endif
+
#ifdef HAVE_GTK_FILE_SELECTION_NEW
if (xg_uses_old_file_dialog ())
@@ -2237,20 +2656,34 @@ xg_get_file_name (struct frame *f,
#ifdef HAVE_GTK3
-#define XG_WEIGHT_TO_SYMBOL(w) \
- (w <= PANGO_WEIGHT_THIN ? Qextra_light \
- : w <= PANGO_WEIGHT_ULTRALIGHT ? Qlight \
- : w <= PANGO_WEIGHT_LIGHT ? Qsemi_light \
- : w < PANGO_WEIGHT_MEDIUM ? Qnormal \
- : w <= PANGO_WEIGHT_SEMIBOLD ? Qsemi_bold \
- : w <= PANGO_WEIGHT_BOLD ? Qbold \
- : w <= PANGO_WEIGHT_HEAVY ? Qextra_bold \
- : Qultra_bold)
-
-#define XG_STYLE_TO_SYMBOL(s) \
- (s == PANGO_STYLE_OBLIQUE ? Qoblique \
- : s == PANGO_STYLE_ITALIC ? Qitalic \
- : Qnormal)
+static
+Lisp_Object xg_weight_to_symbol (PangoWeight w)
+{
+ return
+ (w <= PANGO_WEIGHT_THIN ? Qthin /* 100 */
+ : w <= PANGO_WEIGHT_ULTRALIGHT ? Qultra_light /* 200 */
+ : w <= PANGO_WEIGHT_LIGHT ? Qlight /* 300 */
+#if PANGO_VERSION_CHECK(1, 36, 7)
+ : w <= PANGO_WEIGHT_SEMILIGHT ? Qsemi_light /* 350 */
+#endif
+ : w <= PANGO_WEIGHT_BOOK ? Qbook /* 380 */
+ : w <= PANGO_WEIGHT_NORMAL ? Qnormal /* 400 */
+ : w <= PANGO_WEIGHT_MEDIUM ? Qmedium /* 500 */
+ : w <= PANGO_WEIGHT_SEMIBOLD ? Qsemi_bold /* 600 */
+ : w <= PANGO_WEIGHT_BOLD ? Qbold /* 700 */
+ : w <= PANGO_WEIGHT_ULTRABOLD ? Qultra_bold /* 800 */
+ : w <= PANGO_WEIGHT_HEAVY ? Qblack /* 900 */
+ : Qultra_heavy); /* 1000 */
+}
+
+static
+Lisp_Object xg_style_to_symbol (PangoStyle s)
+{
+ return
+ (s == PANGO_STYLE_OBLIQUE ? Qoblique
+ : s == PANGO_STYLE_ITALIC ? Qitalic
+ : Qnormal);
+}
#endif /* HAVE_GTK3 */
@@ -2288,6 +2721,11 @@ xg_get_font (struct frame *f, const char *default_name)
int done = 0;
Lisp_Object font = Qnil;
+#ifdef HAVE_PGTK
+ if (!FRAME_GTK_OUTER_WIDGET (f))
+ error ("Can't open dialog from child frames");
+#endif
+
w = gtk_font_chooser_dialog_new
("Pick a font", GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
@@ -2341,8 +2779,8 @@ xg_get_font (struct frame *f, const char *default_name)
font = CALLN (Ffont_spec,
QCfamily, build_string (family),
QCsize, make_float (pango_units_to_double (size)),
- QCweight, XG_WEIGHT_TO_SYMBOL (weight),
- QCslant, XG_STYLE_TO_SYMBOL (style));
+ QCweight, xg_weight_to_symbol (weight),
+ QCslant, xg_style_to_symbol (style));
char *font_desc_str = pango_font_description_to_string (desc);
dupstring (&x_last_font_name, font_desc_str);
@@ -2485,7 +2923,7 @@ xg_mark_data (void)
{
struct frame *f = XFRAME (frame);
- if (FRAME_X_P (f) && FRAME_GTK_OUTER_WIDGET (f))
+ if ((FRAME_X_P (f) || FRAME_PGTK_P (f)) && FRAME_GTK_OUTER_WIDGET (f))
{
struct xg_frame_tb_info *tbinfo
= g_object_get_data (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)),
@@ -2649,6 +3087,11 @@ make_menu_item (const char *utf8_label,
if (wtoadd) gtk_container_add (GTK_CONTAINER (w), wtoadd);
if (! item->enabled) gtk_widget_set_sensitive (w, FALSE);
+#ifdef HAVE_PGTK
+ if (!NILP (item->help))
+ gtk_widget_set_tooltip_text (w, SSDATA (item->help));
+#endif
+
return w;
}
@@ -2715,6 +3158,20 @@ xg_create_one_menuitem (widget_value *item,
return w;
}
+#ifdef HAVE_PGTK
+static gboolean
+menu_bar_button_pressed_cb (GtkWidget *widget, GdkEvent *event,
+ gpointer user_data)
+{
+ struct frame *f = user_data;
+
+ if (event->button.button < 4)
+ set_frame_menubar (f, true);
+
+ return false;
+}
+#endif
+
/* Create a full menu tree specified by DATA.
F is the frame the created menu belongs to.
SELECT_CB is the callback to use when a menu item is selected.
@@ -2772,6 +3229,10 @@ create_menus (widget_value *data,
else
{
wmenu = gtk_menu_bar_new ();
+#ifdef HAVE_PGTK
+ g_signal_connect (G_OBJECT (wmenu), "button-press-event",
+ G_CALLBACK (menu_bar_button_pressed_cb), f);
+#endif
/* Set width of menu bar to a small value so it doesn't enlarge
a small initial frame size. The width will be set to the
width of the frame later on when it is added to a container.
@@ -2788,9 +3249,15 @@ create_menus (widget_value *data,
if (name)
gtk_widget_set_name (wmenu, name);
+#ifndef HAVE_PGTK
if (deactivate_cb)
g_signal_connect (G_OBJECT (wmenu),
"selection-done", deactivate_cb, 0);
+#else
+ if (deactivate_cb)
+ g_signal_connect (G_OBJECT (wmenu),
+ "deactivate", deactivate_cb, 0);
+#endif
}
for (item = data; item; item = item->next)
@@ -2932,8 +3399,9 @@ xg_item_label_same_p (GtkMenuItem *witem, const char *label)
char *utf8_label = get_utf8_string (label);
const char *old_label = witem ? xg_get_menu_item_label (witem) : 0;
- bool is_same = (!old_label == !utf8_label
- && (!old_label || strcmp (utf8_label, old_label) == 0));
+ bool is_same = (old_label
+ ? utf8_label && strcmp (utf8_label, old_label) == 0
+ : !utf8_label);
if (utf8_label) g_free (utf8_label);
@@ -3511,7 +3979,7 @@ menubar_map_cb (GtkWidget *w, gpointer user_data)
void
xg_update_frame_menubar (struct frame *f)
{
- struct x_output *x = f->output_data.x;
+ xp_output *x = f->output_data.xp;
GtkRequisition req;
if (!x->menubar_widget || gtk_widget_get_mapped (x->menubar_widget))
@@ -3544,7 +4012,7 @@ xg_update_frame_menubar (struct frame *f)
void
free_frame_menubar (struct frame *f)
{
- struct x_output *x = f->output_data.x;
+ xp_output *x = f->output_data.xp;
if (x->menubar_widget)
{
@@ -3560,6 +4028,7 @@ free_frame_menubar (struct frame *f)
}
}
+#ifndef HAVE_PGTK
bool
xg_event_is_for_menubar (struct frame *f, const XEvent *event)
{
@@ -3574,6 +4043,18 @@ xg_event_is_for_menubar (struct frame *f, const XEvent *event)
if (! x->menubar_widget) return 0;
+#ifdef HAVE_XINPUT2
+ XIDeviceEvent *xev = (XIDeviceEvent *) event->xcookie.data;
+ if (event->type == GenericEvent) /* XI_ButtonPress or XI_ButtonRelease */
+ {
+ if (! (xev->event_x >= 0
+ && xev->event_x < FRAME_PIXEL_WIDTH (f)
+ && xev->event_y >= 0
+ && xev->event_y < FRAME_MENUBAR_HEIGHT (f)))
+ return 0;
+ }
+ else
+#endif
if (! (event->xbutton.x >= 0
&& event->xbutton.x < FRAME_PIXEL_WIDTH (f)
&& event->xbutton.y >= 0
@@ -3582,7 +4063,12 @@ xg_event_is_for_menubar (struct frame *f, const XEvent *event)
return 0;
gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f));
- gw = gdk_x11_window_lookup_for_display (gdpy, event->xbutton.window);
+#ifdef HAVE_XINPUT2
+ if (event->type == GenericEvent)
+ gw = gdk_x11_window_lookup_for_display (gdpy, xev->event);
+ else
+#endif
+ gw = gdk_x11_window_lookup_for_display (gdpy, event->xbutton.window);
if (! gw) return 0;
gevent.any.window = gw;
gevent.any.type = GDK_NOTHING;
@@ -3610,6 +4096,7 @@ xg_event_is_for_menubar (struct frame *f, const XEvent *event)
g_list_free (list);
return iter != 0;
}
+#endif
@@ -3765,6 +4252,7 @@ xg_get_default_scrollbar_height (struct frame *f)
return scroll_bar_width_for_theme * xg_get_scale (f);
}
+#ifndef HAVE_PGTK
/* Return the scrollbar id for X Window WID on display DPY.
Return -1 if WID not in id_to_widget. */
@@ -3785,6 +4273,7 @@ xg_get_scroll_id_for_window (Display *dpy, Window wid)
return -1;
}
+#endif
/* Callback invoked when scroll bar WIDGET is destroyed.
DATA is the index into id_to_widget for WIDGET.
@@ -3834,7 +4323,7 @@ xg_finish_scroll_bar_creation (struct frame *f,
also, which causes flicker. Put an event box between the edit widget
and the scroll bar, so the scroll bar instead draws itself on the
event box window. */
- gtk_fixed_put (GTK_FIXED (f->output_data.x->edit_widget), webox, -1, -1);
+ gtk_fixed_put (GTK_FIXED (f->output_data.xp->edit_widget), webox, -1, -1);
gtk_container_add (GTK_CONTAINER (webox), wscroll);
xg_set_widget_bg (f, webox, FRAME_BACKGROUND_PIXEL (f));
@@ -3844,11 +4333,28 @@ xg_finish_scroll_bar_creation (struct frame *f,
real X window, it and its scroll-bar child try to draw on the
Emacs main window, which we draw over using Xlib. */
gtk_widget_realize (webox);
+#ifdef HAVE_PGTK
+ gtk_widget_show_all (webox);
+#endif
+#ifndef HAVE_PGTK
GTK_WIDGET_TO_X_WIN (webox);
+#endif
/* Set the cursor to an arrow. */
xg_set_cursor (webox, FRAME_DISPLAY_INFO (f)->xg_cursor);
+#ifdef HAVE_PGTK
+ GtkStyleContext *ctxt = gtk_widget_get_style_context (wscroll);
+ gtk_style_context_add_provider (ctxt,
+ GTK_STYLE_PROVIDER (FRAME_OUTPUT_DATA (f)->
+ scrollbar_foreground_css_provider),
+ GTK_STYLE_PROVIDER_PRIORITY_USER);
+ gtk_style_context_add_provider (ctxt,
+ GTK_STYLE_PROVIDER (FRAME_OUTPUT_DATA (f)->
+ scrollbar_background_css_provider),
+ GTK_STYLE_PROVIDER_PRIORITY_USER);
+#endif
+
bar->x_window = scroll_id;
}
@@ -3949,7 +4455,7 @@ xg_update_scrollbar_pos (struct frame *f,
GtkWidget *wscroll = xg_get_widget_from_map (scrollbar_id);
if (wscroll)
{
- GtkWidget *wfixed = f->output_data.x->edit_widget;
+ GtkWidget *wfixed = f->output_data.xp->edit_widget;
GtkWidget *wparent = gtk_widget_get_parent (wscroll);
gint msl;
int scale = xg_get_scale (f);
@@ -3989,7 +4495,11 @@ xg_update_scrollbar_pos (struct frame *f,
/* Clear under old scroll bar position. */
oldw += (scale - 1) * oldw;
oldx -= (scale - 1) * oldw;
+#ifndef HAVE_PGTK
x_clear_area (f, oldx, oldy, oldw, oldh);
+#else
+ pgtk_clear_area (f, oldx, oldy, oldw, oldh);
+#endif
}
if (!hidden)
@@ -3997,15 +4507,23 @@ xg_update_scrollbar_pos (struct frame *f,
GtkWidget *scrollbar = xg_get_widget_from_map (scrollbar_id);
GtkWidget *webox = gtk_widget_get_parent (scrollbar);
+#ifndef HAVE_PGTK
/* Don't obscure any child frames. */
XLowerWindow (FRAME_X_DISPLAY (f), GTK_WIDGET_TO_X_WIN (webox));
+#else
+ gdk_window_lower (gtk_widget_get_window (webox));
+#endif
}
/* GTK does not redraw until the main loop is entered again, but
if there are no X events pending we will not enter it. So we sync
here to get some events. */
+#ifndef HAVE_PGTK
x_sync (f);
+#else
+ gdk_flush ();
+#endif
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
}
@@ -4030,7 +4548,7 @@ xg_update_horizontal_scrollbar_pos (struct frame *f,
if (wscroll)
{
- GtkWidget *wfixed = f->output_data.x->edit_widget;
+ GtkWidget *wfixed = f->output_data.xp->edit_widget;
GtkWidget *wparent = gtk_widget_get_parent (wscroll);
gint msl;
int scale = xg_get_scale (f);
@@ -4066,7 +4584,11 @@ xg_update_horizontal_scrollbar_pos (struct frame *f,
}
if (oldx != -1 && oldw > 0 && oldh > 0)
/* Clear under old scroll bar position. */
+#ifndef HAVE_PGTK
x_clear_area (f, oldx, oldy, oldw, oldh);
+#else
+ pgtk_clear_area (f, oldx, oldy, oldw, oldh);
+#endif
/* GTK does not redraw until the main loop is entered again, but
if there are no X events pending we will not enter it. So we sync
@@ -4077,11 +4599,19 @@ xg_update_horizontal_scrollbar_pos (struct frame *f,
xg_get_widget_from_map (scrollbar_id);
GtkWidget *webox = gtk_widget_get_parent (scrollbar);
+#ifndef HAVE_PGTK
/* Don't obscure any child frames. */
XLowerWindow (FRAME_X_DISPLAY (f), GTK_WIDGET_TO_X_WIN (webox));
+#else
+ gdk_window_lower (gtk_widget_get_window (webox));
+#endif
}
+#ifndef HAVE_PGTK
x_sync (f);
+#else
+ gdk_flush ();
+#endif
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
}
@@ -4225,14 +4755,37 @@ xg_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar,
frame. This function does additional checks. */
bool
-xg_event_is_for_scrollbar (struct frame *f, const XEvent *event)
+xg_event_is_for_scrollbar (struct frame *f, const EVENT *event)
{
bool retval = 0;
- if (f && event->type == ButtonPress && event->xbutton.button < 4)
+#ifdef HAVE_XINPUT2
+ XIDeviceEvent *xev = (XIDeviceEvent *) event->xcookie.data;
+ if (f && ((FRAME_DISPLAY_INFO (f)->supports_xi2
+ && event->type == GenericEvent
+ && (event->xgeneric.extension
+ == FRAME_DISPLAY_INFO (f)->xi2_opcode)
+ && ((event->xgeneric.evtype == XI_ButtonPress
+ && xev->detail < 4)
+ || (event->xgeneric.evtype == XI_Motion)))
+ || (event->type == ButtonPress
+ && event->xbutton.button < 4)))
+#else
+ if (f
+#ifndef HAVE_PGTK
+ && event->type == ButtonPress && event->xbutton.button < 4
+#else
+ && event->type == GDK_BUTTON_PRESS && event->button.button < 4
+#endif
+ )
+#endif /* HAVE_XINPUT2 */
{
/* Check if press occurred outside the edit widget. */
+#ifndef HAVE_PGTK
GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f));
+#else
+ GdkDisplay *gdpy = FRAME_X_DISPLAY (f);
+#endif
GdkWindow *gwin;
#ifdef HAVE_GTK3
#if GTK_CHECK_VERSION (3, 20, 0)
@@ -4246,11 +4799,36 @@ xg_event_is_for_scrollbar (struct frame *f, const XEvent *event)
#else
gwin = gdk_display_get_window_at_pointer (gdpy, NULL, NULL);
#endif
- retval = gwin != gtk_widget_get_window (f->output_data.x->edit_widget);
+ retval = gwin != gtk_widget_get_window (f->output_data.xp->edit_widget);
+#ifdef HAVE_XINPUT2
+ GtkWidget *grab = gtk_grab_get_current ();
+ if (event->type == GenericEvent
+ && event->xgeneric.evtype == XI_Motion)
+ retval = retval || (grab && GTK_IS_SCROLLBAR (grab));
+#endif
}
+#ifdef HAVE_XINPUT2
+ else if (f && ((FRAME_DISPLAY_INFO (f)->supports_xi2
+ && event->type == GenericEvent
+ && (event->xgeneric.extension
+ == FRAME_DISPLAY_INFO (f)->xi2_opcode)
+ && ((event->xgeneric.evtype == XI_ButtonRelease
+ && xev->detail < 4)
+ || (event->xgeneric.evtype == XI_Motion)))
+ || ((event->type == ButtonRelease
+ && event->xbutton.button < 4)
+ || event->type == MotionNotify)))
+#else
else if (f
+#ifndef HAVE_PGTK
&& ((event->type == ButtonRelease && event->xbutton.button < 4)
- || event->type == MotionNotify))
+ || event->type == MotionNotify)
+#else
+ && ((event->type == GDK_BUTTON_RELEASE && event->button.button < 4)
+ || event->type == GDK_MOTION_NOTIFY)
+#endif
+ )
+#endif /* HAVE_XINPUT2 */
{
/* If we are releasing or moving the scroll bar, it has the grab. */
GtkWidget *w = gtk_grab_get_current ();
@@ -4328,7 +4906,11 @@ draw_page (GtkPrintOperation *operation, GtkPrintContext *context,
struct frame *f = XFRAME (Fnth (make_fixnum (page_nr), frames));
cairo_t *cr = gtk_print_context_get_cairo_context (context);
+#ifndef HAVE_PGTK
x_cr_draw_frame (cr, f);
+#else
+ pgtk_cr_draw_frame (cr, f);
+#endif
}
void
@@ -4429,7 +5011,11 @@ xg_tool_bar_callback (GtkWidget *w, gpointer client_data)
/* Convert between the modifier bits GDK uses and the modifier bits
Emacs uses. This assumes GDK and X masks are the same, which they are when
this is written. */
+#ifndef HAVE_PGTK
event.modifiers = x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), mod);
+#else
+ event.modifiers = pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), mod);
+#endif
kbd_buffer_store_event (&event);
/* Return focus to the frame after we have clicked on a detached
@@ -4526,7 +5112,7 @@ xg_tool_bar_item_expose_callback (GtkWidget *w,
static void
xg_pack_tool_bar (struct frame *f, Lisp_Object pos)
{
- struct x_output *x = f->output_data.x;
+ xp_output *x = f->output_data.xp;
bool into_hbox = EQ (pos, Qleft) || EQ (pos, Qright);
GtkWidget *top_widget = x->toolbar_widget;
@@ -4582,7 +5168,7 @@ tb_size_cb (GtkWidget *widget,
static void
xg_create_tool_bar (struct frame *f)
{
- struct x_output *x = f->output_data.x;
+ xp_output *x = f->output_data.xp;
#ifdef HAVE_GTK3
GtkStyleContext *gsty;
#endif
@@ -4821,7 +5407,7 @@ xg_tool_item_stale_p (GtkWidget *wbutton, const char *stock_name,
static bool
xg_update_tool_bar_sizes (struct frame *f)
{
- struct x_output *x = f->output_data.x;
+ xp_output *x = f->output_data.xp;
GtkRequisition req;
int nl = 0, nr = 0, nt = 0, nb = 0;
GtkWidget *top_widget = x->toolbar_widget;
@@ -4907,7 +5493,7 @@ void
update_frame_tool_bar (struct frame *f)
{
int i, j;
- struct x_output *x = f->output_data.x;
+ xp_output *x = f->output_data.xp;
int hmargin = 0, vmargin = 0;
GtkToolbar *wtoolbar;
GtkToolItem *ti;
@@ -4922,6 +5508,11 @@ update_frame_tool_bar (struct frame *f)
if (! FRAME_GTK_WIDGET (f))
return;
+#ifdef HAVE_PGTK
+ if (! FRAME_GTK_OUTER_WIDGET (f))
+ return;
+#endif
+
block_input ();
if (RANGED_FIXNUMP (1, Vtool_bar_button_margin, INT_MAX))
@@ -5217,7 +5808,7 @@ update_frame_tool_bar (struct frame *f)
void
free_frame_tool_bar (struct frame *f)
{
- struct x_output *x = f->output_data.x;
+ xp_output *x = f->output_data.xp;
if (x->toolbar_widget)
{
@@ -5262,7 +5853,7 @@ free_frame_tool_bar (struct frame *f)
void
xg_change_toolbar_position (struct frame *f, Lisp_Object pos)
{
- struct x_output *x = f->output_data.x;
+ xp_output *x = f->output_data.xp;
GtkWidget *top_widget = x->toolbar_widget;
if (! x->toolbar_widget || ! top_widget)
diff --git a/src/gtkutil.h b/src/gtkutil.h
index 31a12cd5d3c..9c6160dd772 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -25,7 +25,13 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <gtk/gtk.h>
#include "../lwlib/lwlib-widget.h"
+#ifdef HAVE_PGTK
+#include "pgtkterm.h"
+#define EVENT GdkEvent
+#else
#include "xterm.h"
+#define EVENT XEvent
+#endif
/* Minimum and maximum values used for GTK scroll bars */
@@ -105,7 +111,7 @@ extern void xg_modify_menubar_widgets (GtkWidget *menubar,
extern void xg_update_frame_menubar (struct frame *f);
-extern bool xg_event_is_for_menubar (struct frame *, const XEvent *);
+extern bool xg_event_is_for_menubar (struct frame *, const EVENT *);
extern ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid);
@@ -142,7 +148,7 @@ extern void xg_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar,
int portion,
int position,
int whole);
-extern bool xg_event_is_for_scrollbar (struct frame *, const XEvent *);
+extern bool xg_event_is_for_scrollbar (struct frame *, const EVENT *);
extern int xg_get_default_scrollbar_width (struct frame *f);
extern int xg_get_default_scrollbar_height (struct frame *f);
@@ -157,9 +163,15 @@ extern void xg_frame_set_char_size (struct frame *f, int width, int height);
extern GtkWidget * xg_win_to_widget (Display *dpy, Window wdesc);
extern int xg_get_scale (struct frame *f);
+#ifndef HAVE_PGTK
extern void xg_display_open (char *display_name, Display **dpy);
extern void xg_display_close (Display *dpy);
extern GdkCursor * xg_create_default_cursor (Display *dpy);
+#else
+extern void xg_display_open (char *display_name, GdkDisplay **dpy);
+extern void xg_display_close (GdkDisplay *gdpy);
+extern GdkCursor * xg_create_default_cursor (GdkDisplay *gdpy);
+#endif
extern bool xg_create_frame_widgets (struct frame *f);
extern void xg_free_frame_widgets (struct frame *f);
@@ -167,10 +179,15 @@ extern void xg_set_background_color (struct frame *f, unsigned long bg);
extern bool xg_check_special_colors (struct frame *f,
const char *color_name,
Emacs_Color *color);
+#ifdef HAVE_PGTK
+extern void xg_create_frame_outer_widgets (struct frame *f);
+#endif
+#ifndef HAVE_PGTK
extern void xg_set_frame_icon (struct frame *f,
Pixmap icon_pixmap,
Pixmap icon_mask);
+#endif
extern void xg_set_undecorated (struct frame *f, Lisp_Object undecorated);
extern void xg_frame_restack (struct frame *f1, struct frame *f2, bool above);
@@ -183,7 +200,11 @@ extern bool xg_prepare_tooltip (struct frame *f,
Lisp_Object string,
int *width,
int *height);
+#ifndef HAVE_PGTK
extern void xg_show_tooltip (struct frame *f, int root_x, int root_y);
+#else
+extern void xg_show_tooltip (struct frame *f, Lisp_Object string);
+#endif
extern bool xg_hide_tooltip (struct frame *f);
#ifdef USE_CAIRO
@@ -192,6 +213,10 @@ extern Lisp_Object xg_get_page_setup (void);
extern void xg_print_frames_dialog (Lisp_Object);
#endif
+#if defined HAVE_GTK3 && defined HAVE_XINPUT2
+extern bool xg_is_menu_window (Display *dpy, Window);
+#endif
+
/* Mark all callback data that are Lisp_object:s during GC. */
extern void xg_mark_data (void);
diff --git a/src/haiku.c b/src/haiku.c
new file mode 100644
index 00000000000..485d86983c2
--- /dev/null
+++ b/src/haiku.c
@@ -0,0 +1,286 @@
+/* Haiku subroutines that are general to the Haiku operating system.
+ Copyright (C) 2021 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/>. */
+
+#include <config.h>
+
+#include "lisp.h"
+#include "process.h"
+#include "coding.h"
+
+#include <kernel/OS.h>
+
+#include <pwd.h>
+#include <stdlib.h>
+
+Lisp_Object
+list_system_processes (void)
+{
+ team_info info;
+ int32 cookie = 0;
+ Lisp_Object lval = Qnil;
+
+ while (get_next_team_info (&cookie, &info) == B_OK)
+ lval = Fcons (make_fixnum (info.team), lval);
+
+ return lval;
+}
+
+Lisp_Object
+system_process_attributes (Lisp_Object pid)
+{
+ CHECK_FIXNUM (pid);
+
+ team_info info;
+ Lisp_Object lval = Qnil;
+ thread_info inf;
+ area_info area;
+ team_id id = (team_id) XFIXNUM (pid);
+ struct passwd *g;
+ size_t mem = 0;
+
+ if (get_team_info (id, &info) != B_OK)
+ return Qnil;
+
+ bigtime_t everything = 0, vsample = 0;
+ bigtime_t cpu_eaten = 0, esample = 0;
+
+ lval = Fcons (Fcons (Qeuid, make_fixnum (info.uid)), lval);
+ lval = Fcons (Fcons (Qegid, make_fixnum (info.gid)), lval);
+ lval = Fcons (Fcons (Qthcount, make_fixnum (info.thread_count)), lval);
+ lval = Fcons (Fcons (Qcomm, build_string_from_utf8 (info.args)), lval);
+
+ g = getpwuid (info.uid);
+
+ if (g && g->pw_name)
+ lval = Fcons (Fcons (Quser, build_string (g->pw_name)), lval);
+
+ /* FIXME: Calculating this makes Emacs show up as using 100% CPU! */
+
+ for (int32 team_cookie = 0;
+ get_next_team_info (&team_cookie, &info) == B_OK;)
+ for (int32 thread_cookie = 0;
+ get_next_thread_info (info.team, &thread_cookie, &inf) == B_OK;)
+ {
+ if (inf.team == id && strncmp (inf.name, "idle thread ", 12))
+ cpu_eaten += inf.user_time + inf.kernel_time;
+ everything += inf.user_time + inf.kernel_time;
+ }
+
+ sleep (0.05);
+
+ for (int32 team_cookie = 0;
+ get_next_team_info (&team_cookie, &info) == B_OK;)
+ for (int32 thread_cookie = 0;
+ get_next_thread_info (info.team, &thread_cookie, &inf) == B_OK;)
+ {
+ if (inf.team == id && strncmp (inf.name, "idle thread ", 12))
+ esample += inf.user_time + inf.kernel_time;
+ vsample += inf.user_time + inf.kernel_time;
+ }
+
+ cpu_eaten = esample - cpu_eaten;
+ everything = vsample - everything;
+
+ if (everything)
+ lval = Fcons (Fcons (Qpcpu, make_float (((double) (cpu_eaten) /
+ (double) (everything)) * 100)),
+ lval);
+ else
+ lval = Fcons (Fcons (Qpcpu, make_float (0.0)), lval);
+
+ for (ssize_t area_cookie = 0;
+ get_next_area_info (id, &area_cookie, &area) == B_OK;)
+ mem += area.ram_size;
+
+ system_info sinfo;
+ get_system_info (&sinfo);
+ int64 max = (int64) sinfo.max_pages * B_PAGE_SIZE;
+
+ lval = Fcons (Fcons (Qpmem, make_float (((double) mem /
+ (double) max) * 100)),
+ lval);
+ lval = Fcons (Fcons (Qrss, make_fixnum (mem / 1024)), lval);
+
+ return lval;
+}
+
+
+/* Borrowed from w32 implementation. */
+
+struct load_sample
+{
+ time_t sample_time;
+ bigtime_t idle;
+ bigtime_t kernel;
+ bigtime_t user;
+};
+
+/* We maintain 1-sec samples for the last 16 minutes in a circular buffer. */
+static struct load_sample samples[16*60];
+static int first_idx = -1, last_idx = -1;
+static int max_idx = ARRAYELTS (samples);
+static unsigned num_of_processors = 0;
+
+static int
+buf_next (int from)
+{
+ int next_idx = from + 1;
+
+ if (next_idx >= max_idx)
+ next_idx = 0;
+
+ return next_idx;
+}
+
+static int
+buf_prev (int from)
+{
+ int prev_idx = from - 1;
+
+ if (prev_idx < 0)
+ prev_idx = max_idx - 1;
+
+ return prev_idx;
+}
+
+static double
+getavg (int which)
+{
+ double retval = -1.0;
+ double tdiff;
+ int idx;
+ double span = (which == 0 ? 1.0 : (which == 1 ? 5.0 : 15.0)) * 60;
+ time_t now = samples[last_idx].sample_time;
+
+ if (first_idx != last_idx)
+ {
+ for (idx = buf_prev (last_idx); ; idx = buf_prev (idx))
+ {
+ tdiff = difftime (now, samples[idx].sample_time);
+ if (tdiff >= span - 2 * DBL_EPSILON * now)
+ {
+ long double sys =
+ (samples[last_idx].kernel + samples[last_idx].user) -
+ (samples[idx].kernel + samples[idx].user);
+ long double idl = samples[last_idx].idle - samples[idx].idle;
+
+ retval = (idl / (sys + idl)) * num_of_processors;
+ break;
+ }
+ if (idx == first_idx)
+ break;
+ }
+ }
+
+ return retval;
+}
+
+static void
+sample_sys_load (bigtime_t *idle, bigtime_t *system, bigtime_t *user)
+{
+ bigtime_t i = 0, s = 0, u = 0;
+ team_info info;
+ thread_info inf;
+
+ for (int32 team_cookie = 0;
+ get_next_team_info (&team_cookie, &info) == B_OK;)
+ for (int32 thread_cookie = 0;
+ get_next_thread_info (info.team, &thread_cookie, &inf) == B_OK;)
+ {
+ if (!strncmp (inf.name, "idle thread ", 12))
+ i += inf.user_time + inf.kernel_time;
+ else
+ s += inf.kernel_time, u += inf.user_time;
+ }
+
+ *idle = i;
+ *system = s;
+ *user = u;
+}
+
+int
+getloadavg (double loadavg[], int nelem)
+{
+ int elem;
+ bigtime_t idle, kernel, user;
+ time_t now = time (NULL);
+
+ if (num_of_processors <= 0)
+ {
+ system_info i;
+ if (get_system_info (&i) == B_OK)
+ num_of_processors = i.cpu_count;
+ }
+
+ /* If system time jumped back for some reason, delete all samples
+ whose time is later than the current wall-clock time. This
+ prevents load average figures from becoming frozen for prolonged
+ periods of time, when system time is reset backwards. */
+ if (last_idx >= 0)
+ {
+ while (difftime (now, samples[last_idx].sample_time) < -1.0)
+ {
+ if (last_idx == first_idx)
+ {
+ first_idx = last_idx = -1;
+ break;
+ }
+ last_idx = buf_prev (last_idx);
+ }
+ }
+
+ /* Store another sample. We ignore samples that are less than 1 sec
+ apart. */
+ if (last_idx < 0
+ || (difftime (now, samples[last_idx].sample_time)
+ >= 1.0 - 2 * DBL_EPSILON * now))
+ {
+ sample_sys_load (&idle, &kernel, &user);
+ last_idx = buf_next (last_idx);
+ samples[last_idx].sample_time = now;
+ samples[last_idx].idle = idle;
+ samples[last_idx].kernel = kernel;
+ samples[last_idx].user = user;
+ /* If the buffer has more that 15 min worth of samples, discard
+ the old ones. */
+ if (first_idx == -1)
+ first_idx = last_idx;
+ while (first_idx != last_idx
+ && (difftime (now, samples[first_idx].sample_time)
+ >= 15.0 * 60 + 2 * DBL_EPSILON * now))
+ first_idx = buf_next (first_idx);
+ }
+
+ for (elem = 0; elem < nelem; elem++)
+ {
+ double avg = getavg (elem);
+
+ if (avg < 0)
+ break;
+ loadavg[elem] = avg;
+ }
+
+ /* Always return at least one element, otherwise load-average
+ returns nil, and Lisp programs might decide we cannot measure
+ system load. For example, jit-lock-stealth-load's defcustom
+ might decide that feature is "unsupported". */
+ if (elem == 0)
+ loadavg[elem++] = 0.09; /* < display-time-load-average-threshold */
+
+ return elem;
+}
diff --git a/src/haiku_draw_support.cc b/src/haiku_draw_support.cc
new file mode 100644
index 00000000000..5b1eccfbe6e
--- /dev/null
+++ b/src/haiku_draw_support.cc
@@ -0,0 +1,488 @@
+/* Haiku window system support. Hey, Emacs, this is -*- C++ -*-
+ Copyright (C) 2021 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/>. */
+
+#include <config.h>
+
+#include <View.h>
+#include <Region.h>
+#include <Font.h>
+#include <Window.h>
+#include <Bitmap.h>
+
+#include <cmath>
+
+#include "haiku_support.h"
+
+#define RGB_TO_UINT32(r, g, b) ((255 << 24) | ((r) << 16) | ((g) << 8) | (b))
+#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
+#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
+#define BLUE_FROM_ULONG(color) ((color) & 0xff)
+
+#define RGB_COLOR_UINT32(r) RGB_TO_UINT32 ((r).red, (r).green, (r).blue)
+
+static void
+rgb32_to_rgb_color (uint32_t rgb, rgb_color *color)
+{
+ color->red = RED_FROM_ULONG (rgb);
+ color->green = GREEN_FROM_ULONG (rgb);
+ color->blue = BLUE_FROM_ULONG (rgb);
+ color->alpha = 255;
+}
+
+static BView *
+get_view (void *vw)
+{
+ BView *view = (BView *) find_appropriate_view_for_draw (vw);
+ return view;
+}
+
+void
+BView_StartClip (void *view)
+{
+ BView *vw = get_view (view);
+ vw->PushState ();
+}
+
+void
+BView_EndClip (void *view)
+{
+ BView *vw = get_view (view);
+ vw->PopState ();
+}
+
+void
+BView_SetHighColor (void *view, uint32_t color)
+{
+ BView *vw = get_view (view);
+ rgb_color col;
+ rgb32_to_rgb_color (color, &col);
+
+ vw->SetHighColor (col);
+}
+
+void
+BView_SetLowColor (void *view, uint32_t color)
+{
+ BView *vw = get_view (view);
+ rgb_color col;
+ rgb32_to_rgb_color (color, &col);
+
+ vw->SetLowColor (col);
+}
+
+void
+BView_SetPenSize (void *view, int u)
+{
+ BView *vw = get_view (view);
+ vw->SetPenSize (u);
+}
+
+void
+BView_FillRectangle (void *view, int x, int y, int width, int height)
+{
+ BView *vw = get_view (view);
+ BRect rect = BRect (x, y, x + width - 1, y + height - 1);
+
+ vw->FillRect (rect);
+}
+
+void
+BView_FillRectangleAbs (void *view, int x, int y, int x1, int y1)
+{
+ BView *vw = get_view (view);
+ BRect rect = BRect (x, y, x1, y1);
+
+ vw->FillRect (rect);
+}
+
+void
+BView_StrokeRectangle (void *view, int x, int y, int width, int height)
+{
+ BView *vw = get_view (view);
+ BRect rect = BRect (x, y, x + width - 1, y + height - 1);
+
+ vw->StrokeRect (rect);
+}
+
+void
+BView_SetViewColor (void *view, uint32_t color)
+{
+ BView *vw = get_view (view);
+ rgb_color col;
+ rgb32_to_rgb_color (color, &col);
+
+#ifndef USE_BE_CAIRO
+ vw->SetViewColor (col);
+#else
+ vw->SetViewColor (B_TRANSPARENT_32_BIT);
+#endif
+}
+
+void
+BView_ClipToRect (void *view, int x, int y, int width, int height)
+{
+ BView *vw = get_view (view);
+ BRect rect = BRect (x, y, x + width - 1, y + height - 1);
+
+ vw->ClipToRect (rect);
+}
+
+void
+BView_ClipToInverseRect (void *view, int x, int y, int width, int height)
+{
+ BView *vw = get_view (view);
+ BRect rect = BRect (x, y, x + width - 1, y + height - 1);
+
+ vw->ClipToInverseRect (rect);
+}
+
+void
+BView_StrokeLine (void *view, int sx, int sy, int tx, int ty)
+{
+ BView *vw = get_view (view);
+ BPoint from = BPoint (sx, sy);
+ BPoint to = BPoint (tx, ty);
+
+ vw->StrokeLine (from, to);
+}
+
+void
+BView_SetFont (void *view, void *font)
+{
+ BView *vw = get_view (view);
+
+ vw->SetFont ((BFont *) font);
+}
+
+void
+BView_MovePenTo (void *view, int x, int y)
+{
+ BView *vw = get_view (view);
+ BPoint pt = BPoint (x, y);
+
+ vw->MovePenTo (pt);
+}
+
+void
+BView_DrawString (void *view, const char *chr, ptrdiff_t len)
+{
+ BView *vw = get_view (view);
+
+ vw->DrawString (chr, len);
+}
+
+void
+BView_DrawChar (void *view, char chr)
+{
+ BView *vw = get_view (view);
+
+ vw->DrawChar (chr);
+}
+
+void
+BView_CopyBits (void *view, int x, int y, int width, int height,
+ int tox, int toy, int towidth, int toheight)
+{
+ BView *vw = get_view (view);
+
+ vw->CopyBits (BRect (x, y, x + width - 1, y + height - 1),
+ BRect (tox, toy, tox + towidth - 1, toy + toheight - 1));
+ vw->Sync ();
+}
+
+/* Convert RGB32 color color from RGB color space to its
+ HSL components pointed to by H, S and L. */
+void
+rgb_color_hsl (uint32_t rgb, double *h, double *s, double *l)
+{
+ rgb_color col;
+ rgb32_to_rgb_color (rgb, &col);
+
+ double red = col.red / 255.0;
+ double green = col.green / 255.0;
+ double blue = col.blue / 255.0;
+
+ double max = std::fmax (std::fmax (red, blue), green);
+ double min = std::fmin (std::fmin (red, blue), green);
+ double delta = max - min;
+ *l = (max + min) / 2.0;
+
+ if (!delta)
+ {
+ *h = 0;
+ *s = 0;
+ return;
+ }
+
+ *s = (*l < 0.5) ? delta / (max + min) :
+ delta / (20 - max - min);
+ double rc = (max - red) / delta;
+ double gc = (max - green) / delta;
+ double bc = (max - blue) / delta;
+
+ if (red == max)
+ *h = bc - gc;
+ else if (green == max)
+ *h = 2.0 + rc + -bc;
+ else
+ *h = 4.0 + gc + -rc;
+ *h = std::fmod (*h / 6, 1.0);
+}
+
+static double
+hue_to_rgb (double v1, double v2, double h)
+{
+ if (h < 1 / 6)
+ return v1 + (v2 - v1) * h * 6.0;
+ else if (h < 0.5)
+ return v2;
+ else if (h < 2.0 / 3)
+ return v1 + (v2 - v1) * (2.0 / 3 - h) * 6.0;
+ return v1;
+}
+
+void
+hsl_color_rgb (double h, double s, double l, uint32_t *rgb)
+{
+ if (!s)
+ *rgb = RGB_TO_UINT32 (std::lrint (l * 255),
+ std::lrint (l * 255),
+ std::lrint (l * 255));
+ else
+ {
+ double m2 = l <= 0.5 ? l * (1 + s) : l + s - l * s;
+ double m1 = 2.0 * l - m2;
+
+ *rgb = RGB_TO_UINT32
+ (std::lrint (hue_to_rgb (m1, m2,
+ std::fmod (h + 1 / 3.0, 1)) * 255),
+ std::lrint (hue_to_rgb (m1, m2, h) * 255),
+ std::lrint (hue_to_rgb (m1, m2,
+ std::fmod (h - 1 / 3.0, 1)) * 255));
+ }
+}
+
+void
+BView_DrawBitmap (void *view, void *bitmap, int x, int y,
+ int width, int height, int vx, int vy, int vwidth,
+ int vheight)
+{
+ BView *vw = get_view (view);
+ BBitmap *bm = (BBitmap *) bitmap;
+
+ vw->PushState ();
+ vw->SetDrawingMode (B_OP_OVER);
+ vw->DrawBitmap (bm, BRect (x, y, x + width - 1, y + height - 1),
+ BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1));
+ vw->PopState ();
+}
+
+void
+BView_DrawBitmapWithEraseOp (void *view, void *bitmap, int x,
+ int y, int width, int height)
+{
+ BView *vw = get_view (view);
+ BBitmap *bm = (BBitmap *) bitmap;
+ BBitmap bc (bm->Bounds (), B_RGBA32);
+ BRect rect (x, y, x + width - 1, y + height - 1);
+
+ if (bc.InitCheck () != B_OK || bc.ImportBits (bm) != B_OK)
+ return;
+
+ uint32_t *bits = (uint32_t *) bc.Bits ();
+ size_t stride = bc.BytesPerRow ();
+
+ if (bm->ColorSpace () == B_GRAY1)
+ {
+ rgb_color low_color = vw->LowColor ();
+ for (int y = 0; y <= bc.Bounds ().Height (); ++y)
+ {
+ for (int x = 0; x <= bc.Bounds ().Width (); ++x)
+ {
+ if (bits[y * (stride / 4) + x] == 0xFF000000)
+ bits[y * (stride / 4) + x] = RGB_COLOR_UINT32 (low_color);
+ else
+ bits[y * (stride / 4) + x] = 0;
+ }
+ }
+ }
+
+ vw->PushState ();
+ vw->SetDrawingMode (bm->ColorSpace () == B_GRAY1 ? B_OP_OVER : B_OP_ERASE);
+ vw->DrawBitmap (&bc, rect);
+ vw->PopState ();
+}
+
+void
+BView_DrawMask (void *src, void *view,
+ int x, int y, int width, int height,
+ int vx, int vy, int vwidth, int vheight,
+ uint32_t color)
+{
+ BBitmap *source = (BBitmap *) src;
+ BBitmap bm (source->Bounds (), B_RGBA32);
+ if (bm.InitCheck () != B_OK)
+ return;
+ for (int y = 0; y <= bm.Bounds ().Height (); ++y)
+ {
+ for (int x = 0; x <= bm.Bounds ().Width (); ++x)
+ {
+ int bit = haiku_get_pixel ((void *) source, x, y);
+
+ if (!bit)
+ haiku_put_pixel ((void *) &bm, x, y, ((uint32_t) 255 << 24) | color);
+ else
+ haiku_put_pixel ((void *) &bm, x, y, 0);
+ }
+ }
+ BView *vw = get_view (view);
+ vw->SetDrawingMode (B_OP_OVER);
+ vw->DrawBitmap (&bm, BRect (x, y, x + width - 1, y + height - 1),
+ BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1));
+}
+
+static BBitmap *
+rotate_bitmap_270 (BBitmap *bmp)
+{
+ BRect r = bmp->Bounds ();
+ BBitmap *bm = new BBitmap (BRect (r.top, r.left, r.bottom, r.right),
+ bmp->ColorSpace (), true);
+ if (bm->InitCheck () != B_OK)
+ gui_abort ("Failed to init bitmap for rotate");
+ int w = bmp->Bounds ().Width () + 1;
+ int h = bmp->Bounds ().Height () + 1;
+
+ for (int y = 0; y < h; ++y)
+ for (int x = 0; x < w; ++x)
+ haiku_put_pixel ((void *) bm, y, w - x - 1,
+ haiku_get_pixel ((void *) bmp, x, y));
+
+ return bm;
+}
+
+static BBitmap *
+rotate_bitmap_90 (BBitmap *bmp)
+{
+ BRect r = bmp->Bounds ();
+ BBitmap *bm = new BBitmap (BRect (r.top, r.left, r.bottom, r.right),
+ bmp->ColorSpace (), true);
+ if (bm->InitCheck () != B_OK)
+ gui_abort ("Failed to init bitmap for rotate");
+ int w = bmp->Bounds ().Width () + 1;
+ int h = bmp->Bounds ().Height () + 1;
+
+ for (int y = 0; y < h; ++y)
+ for (int x = 0; x < w; ++x)
+ haiku_put_pixel ((void *) bm, h - y - 1, x,
+ haiku_get_pixel ((void *) bmp, x, y));
+
+ return bm;
+}
+
+void *
+BBitmap_transform_bitmap (void *bitmap, void *mask, uint32_t m_color,
+ double rot, int desw, int desh)
+{
+ BBitmap *bm = (BBitmap *) bitmap;
+ BBitmap *mk = (BBitmap *) mask;
+ int copied_p = 0;
+
+ if (rot == 90)
+ {
+ copied_p = 1;
+ bm = rotate_bitmap_90 (bm);
+ if (mk)
+ mk = rotate_bitmap_90 (mk);
+ }
+
+ if (rot == 270)
+ {
+ copied_p = 1;
+ bm = rotate_bitmap_270 (bm);
+ if (mk)
+ mk = rotate_bitmap_270 (mk);
+ }
+
+ BRect r = bm->Bounds ();
+ if (r.Width () != desw || r.Height () != desh)
+ {
+ BRect n = BRect (0, 0, desw - 1, desh - 1);
+ BView vw (n, NULL, B_FOLLOW_NONE, 0);
+ BBitmap *dst = new BBitmap (n, bm->ColorSpace (), true);
+ if (dst->InitCheck () != B_OK)
+ if (bm->InitCheck () != B_OK)
+ gui_abort ("Failed to init bitmap for scale");
+ dst->AddChild (&vw);
+
+ if (!vw.LockLooper ())
+ gui_abort ("Failed to lock offscreen view for scale");
+
+ if (rot != 90 && rot != 270)
+ {
+ BAffineTransform tr;
+ tr.RotateBy (BPoint (desw / 2, desh / 2), rot * M_PI / 180.0);
+ vw.SetTransform (tr);
+ }
+
+ vw.MovePenTo (0, 0);
+ vw.DrawBitmap (bm, n);
+ if (mk)
+ BView_DrawMask ((void *) mk, (void *) &vw,
+ 0, 0, mk->Bounds ().Width (),
+ mk->Bounds ().Height (),
+ 0, 0, desw, desh, m_color);
+ vw.Sync ();
+ vw.RemoveSelf ();
+
+ if (copied_p)
+ delete bm;
+ if (copied_p && mk)
+ delete mk;
+ return dst;
+ }
+
+ return bm;
+}
+
+void
+BView_FillTriangle (void *view, int x1, int y1,
+ int x2, int y2, int x3, int y3)
+{
+ BView *vw = get_view (view);
+ vw->FillTriangle (BPoint (x1, y1), BPoint (x2, y2),
+ BPoint (x3, y3));
+}
+
+void
+BView_SetHighColorForVisibleBell (void *view, uint32_t color)
+{
+ BView *vw = (BView *) view;
+ rgb_color col;
+ rgb32_to_rgb_color (color, &col);
+
+ vw->SetHighColor (col);
+}
+
+void
+BView_FillRectangleForVisibleBell (void *view, int x, int y, int width, int height)
+{
+ BView *vw = (BView *) view;
+ BRect rect = BRect (x, y, x + width - 1, y + height - 1);
+
+ vw->FillRect (rect);
+}
diff --git a/src/haiku_font_support.cc b/src/haiku_font_support.cc
new file mode 100644
index 00000000000..9ac0400969b
--- /dev/null
+++ b/src/haiku_font_support.cc
@@ -0,0 +1,596 @@
+/* Haiku window system support. Hey, Emacs, this is -*- C++ -*-
+ Copyright (C) 2021 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/>. */
+
+#include <config.h>
+
+#include <Font.h>
+#include <Rect.h>
+#include <AffineTransform.h>
+
+#include <cstring>
+#include <cmath>
+
+#include "haiku_support.h"
+
+/* 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 uint32_t language_code_points[MAX_LANGUAGE][4] =
+ {{20154, 20754, 22996, 0}, /* Chinese. */
+ {51312, 49440, 44544, 0}, /* Korean. */
+ {26085, 26412, 12371, 0}, /* Japanese. */};
+
+static void
+estimate_font_ascii (BFont *font, int *max_width,
+ int *min_width, int *avg_width)
+{
+ char ch[2];
+ bool tems[1];
+ int total = 0;
+ int count = 0;
+ int min = 0;
+ int max = 0;
+
+ std::memset (ch, 0, sizeof ch);
+ for (ch[0] = 32; ch[0] < 127; ++ch[0])
+ {
+ tems[0] = false;
+ font->GetHasGlyphs (ch, 1, tems);
+ if (tems[0])
+ {
+ int w = font->StringWidth (ch);
+ ++count;
+ total += w;
+
+ if (!min || min > w)
+ min = w;
+ if (max < w)
+ max = w;
+ }
+ }
+
+ *min_width = min;
+ *max_width = max;
+ *avg_width = total / count;
+}
+
+void
+BFont_close (void *font)
+{
+ if (font != (void *) be_fixed_font &&
+ font != (void *) be_plain_font &&
+ font != (void *) be_bold_font)
+ delete (BFont *) font;
+}
+
+void
+BFont_dat (void *font, int *px_size, int *min_width, int *max_width,
+ int *avg_width, int *height, int *space_width, int *ascent,
+ int *descent, int *underline_position, int *underline_thickness)
+{
+ BFont *ft = (BFont *) font;
+ struct font_height fheight;
+ bool have_space_p;
+
+ char atem[1];
+ bool otem[1];
+
+ ft->GetHeight (&fheight);
+ atem[0] = ' ';
+ otem[0] = false;
+ ft->GetHasGlyphs (atem, 1, otem);
+ have_space_p = otem[0];
+
+ estimate_font_ascii (ft, max_width, min_width, avg_width);
+ *ascent = std::lrint (fheight.ascent);
+ *descent = std::lrint (fheight.descent);
+ *height = *ascent + *descent;
+
+ *space_width = have_space_p ? ft->StringWidth (" ") : 0;
+
+ *px_size = std::lrint (ft->Size ());
+ *underline_position = 0;
+ *underline_thickness = 0;
+}
+
+/* Return non-null if FONT contains CHR, a Unicode code-point. */
+int
+BFont_have_char_p (void *font, int32_t chr)
+{
+ BFont *ft = (BFont *) font;
+ return ft->IncludesBlock (chr, chr);
+}
+
+/* Return non-null if font contains a block from BEG to END. */
+int
+BFont_have_char_block (void *font, int32_t beg, int32_t end)
+{
+ BFont *ft = (BFont *) font;
+ return ft->IncludesBlock (beg, end);
+}
+
+/* Compute bounds for MB_STR, a character in multibyte encoding,
+ used with font. The width (in pixels) is returned in ADVANCE,
+ the left bearing in LB, and the right bearing in RB. */
+void
+BFont_char_bounds (void *font, const char *mb_str, int *advance,
+ int *lb, int *rb)
+{
+ BFont *ft = (BFont *) font;
+ edge_info edge_info;
+ float size, escapement;
+ size = ft->Size ();
+
+ ft->GetEdges (mb_str, 1, &edge_info);
+ ft->GetEscapements (mb_str, 1, &escapement);
+ *advance = std::lrint (escapement * size);
+ *lb = std::lrint (edge_info.left * size);
+ *rb = *advance + std::lrint (edge_info.right * size);
+}
+
+/* The same, but for a variable amount of chars. */
+void
+BFont_nchar_bounds (void *font, const char *mb_str, int *advance,
+ int *lb, int *rb, int32_t n)
+{
+ BFont *ft = (BFont *) font;
+ edge_info edge_info[n];
+ float size;
+ float escapement[n];
+
+ size = ft->Size ();
+
+ ft->GetEdges (mb_str, n, edge_info);
+ ft->GetEscapements (mb_str, n, (float *) escapement);
+
+ for (int32_t i = 0; i < n; ++i)
+ {
+ advance[i] = std::lrint (escapement[i] * size);
+ lb[i] = advance[i] - std::lrint (edge_info[i].left * size);
+ rb[i] = advance[i] + std::lrint (edge_info[i].right * size);
+ }
+}
+
+static void
+font_style_to_flags (char *st, struct haiku_font_pattern *pattern)
+{
+ char *style = strdup (st);
+ char *token;
+ pattern->weight = -1;
+ pattern->width = NO_WIDTH;
+ pattern->slant = NO_SLANT;
+ int tok = 0;
+
+ while ((token = std::strtok (!tok ? style : NULL, " ")) && tok < 3)
+ {
+ if (token && !strcmp (token, "Thin"))
+ pattern->weight = HAIKU_THIN;
+ else if (token && !strcmp (token, "UltraLight"))
+ pattern->weight = HAIKU_ULTRALIGHT;
+ else if (token && !strcmp (token, "ExtraLight"))
+ pattern->weight = HAIKU_EXTRALIGHT;
+ else if (token && !strcmp (token, "Light"))
+ pattern->weight = HAIKU_LIGHT;
+ else if (token && !strcmp (token, "SemiLight"))
+ pattern->weight = HAIKU_SEMI_LIGHT;
+ else if (token && !strcmp (token, "Regular"))
+ {
+ if (pattern->slant == NO_SLANT)
+ pattern->slant = SLANT_REGULAR;
+
+ if (pattern->width == NO_WIDTH)
+ pattern->width = NORMAL_WIDTH;
+
+ if (pattern->weight == -1)
+ pattern->weight = HAIKU_REGULAR;
+ }
+ else if (token && !strcmp (token, "SemiBold"))
+ pattern->weight = HAIKU_SEMI_BOLD;
+ else if (token && !strcmp (token, "Bold"))
+ pattern->weight = HAIKU_BOLD;
+ else if (token && (!strcmp (token, "ExtraBold") ||
+ /* This has actually been seen in the wild. */
+ !strcmp (token, "Extrabold")))
+ pattern->weight = HAIKU_EXTRA_BOLD;
+ else if (token && !strcmp (token, "UltraBold"))
+ pattern->weight = HAIKU_ULTRA_BOLD;
+ else if (token && !strcmp (token, "Book"))
+ pattern->weight = HAIKU_BOOK;
+ else if (token && !strcmp (token, "Heavy"))
+ pattern->weight = HAIKU_HEAVY;
+ else if (token && !strcmp (token, "UltraHeavy"))
+ pattern->weight = HAIKU_ULTRA_HEAVY;
+ else if (token && !strcmp (token, "Black"))
+ pattern->weight = HAIKU_BLACK;
+ else if (token && !strcmp (token, "Medium"))
+ pattern->weight = HAIKU_MEDIUM;
+ else if (token && !strcmp (token, "Oblique"))
+ pattern->slant = SLANT_OBLIQUE;
+ else if (token && !strcmp (token, "Italic"))
+ pattern->slant = SLANT_ITALIC;
+ else if (token && !strcmp (token, "UltraCondensed"))
+ pattern->width = ULTRA_CONDENSED;
+ else if (token && !strcmp (token, "ExtraCondensed"))
+ pattern->width = EXTRA_CONDENSED;
+ else if (token && !strcmp (token, "Condensed"))
+ pattern->width = CONDENSED;
+ else if (token && !strcmp (token, "SemiCondensed"))
+ pattern->width = SEMI_CONDENSED;
+ else if (token && !strcmp (token, "SemiExpanded"))
+ pattern->width = SEMI_EXPANDED;
+ else if (token && !strcmp (token, "Expanded"))
+ pattern->width = EXPANDED;
+ else if (token && !strcmp (token, "ExtraExpanded"))
+ pattern->width = EXTRA_EXPANDED;
+ else if (token && !strcmp (token, "UltraExpanded"))
+ pattern->width = ULTRA_EXPANDED;
+ else
+ {
+ tok = 1000;
+ break;
+ }
+ tok++;
+ }
+
+ if (pattern->weight != -1)
+ pattern->specified |= FSPEC_WEIGHT;
+ if (pattern->slant != NO_SLANT)
+ pattern->specified |= FSPEC_SLANT;
+ if (pattern->width != NO_WIDTH)
+ pattern->specified |= FSPEC_WIDTH;
+
+ if (tok > 3)
+ {
+ pattern->specified &= ~FSPEC_SLANT;
+ pattern->specified &= ~FSPEC_WEIGHT;
+ pattern->specified &= ~FSPEC_WIDTH;
+ pattern->specified |= FSPEC_STYLE;
+ std::strncpy ((char *) &pattern->style, st,
+ sizeof pattern->style - 1);
+ }
+
+ free (style);
+}
+
+static bool
+font_check_wanted_chars (struct haiku_font_pattern *pattern, font_family family,
+ char *style)
+{
+ BFont ft;
+
+ if (ft.SetFamilyAndStyle (family, style) != B_OK)
+ return false;
+
+ for (int i = 0; i < pattern->want_chars_len; ++i)
+ if (!ft.IncludesBlock (pattern->wanted_chars[i],
+ pattern->wanted_chars[i]))
+ return false;
+
+ return true;
+}
+
+static bool
+font_check_one_of (struct haiku_font_pattern *pattern, font_family family,
+ char *style)
+{
+ BFont ft;
+
+ if (ft.SetFamilyAndStyle (family, style) != B_OK)
+ return false;
+
+ for (int i = 0; i < pattern->need_one_of_len; ++i)
+ if (ft.IncludesBlock (pattern->need_one_of[i],
+ pattern->need_one_of[i]))
+ return true;
+
+ return false;
+}
+
+static bool
+font_check_language (struct haiku_font_pattern *pattern, font_family family,
+ char *style)
+{
+ BFont ft;
+
+ if (ft.SetFamilyAndStyle (family, style) != B_OK)
+ return false;
+
+ if (pattern->language == MAX_LANGUAGE)
+ return false;
+
+ for (uint32_t *ch = (uint32_t *)
+ &language_code_points[pattern->language]; *ch; ch++)
+ if (!ft.IncludesBlock (*ch, *ch))
+ return false;
+
+ return true;
+}
+
+static bool
+font_family_style_matches_p (font_family family, char *style, uint32_t flags,
+ struct haiku_font_pattern *pattern,
+ int ignore_flags_p = 0)
+{
+ struct haiku_font_pattern m;
+ m.specified = 0;
+
+ if (style)
+ font_style_to_flags (style, &m);
+
+ if ((pattern->specified & FSPEC_FAMILY) &&
+ strcmp ((char *) &pattern->family, family))
+ return false;
+
+ if (!ignore_flags_p && (pattern->specified & FSPEC_SPACING) &&
+ !(pattern->mono_spacing_p) != !(flags & B_IS_FIXED))
+ return false;
+
+ if (pattern->specified & FSPEC_STYLE)
+ return style && !strcmp (style, pattern->style);
+
+ if ((pattern->specified & FSPEC_WEIGHT)
+ && (pattern->weight
+ != ((m.specified & FSPEC_WEIGHT) ? m.weight : HAIKU_REGULAR)))
+ return false;
+
+ if ((pattern->specified & FSPEC_SLANT)
+ && (pattern->slant
+ != ((m.specified & FSPEC_SLANT) ? m.slant : SLANT_REGULAR)))
+ return false;
+
+ if ((pattern->specified & FSPEC_WANTED)
+ && !font_check_wanted_chars (pattern, family, style))
+ return false;
+
+ if ((pattern->specified & FSPEC_WIDTH)
+ && (pattern->width !=
+ ((m.specified & FSPEC_WIDTH) ? m.width : NORMAL_WIDTH)))
+ return false;
+
+ if ((pattern->specified & FSPEC_NEED_ONE_OF)
+ && !font_check_one_of (pattern, family, style))
+ return false;
+
+ if ((pattern->specified & FSPEC_LANGUAGE)
+ && !font_check_language (pattern, family, style))
+ return false;
+
+ return true;
+}
+
+static void
+haiku_font_fill_pattern (struct haiku_font_pattern *pattern,
+ font_family family, char *style,
+ uint32_t flags)
+{
+ if (style)
+ font_style_to_flags (style, pattern);
+
+ pattern->specified |= FSPEC_FAMILY;
+ std::strncpy (pattern->family, family,
+ sizeof pattern->family - 1);
+ pattern->specified |= FSPEC_SPACING;
+ pattern->mono_spacing_p = flags & B_IS_FIXED;
+}
+
+/* Delete every element of the font pattern PT. */
+void
+haiku_font_pattern_free (struct haiku_font_pattern *pt)
+{
+ struct haiku_font_pattern *tem = pt;
+ while (tem)
+ {
+ struct haiku_font_pattern *t = tem;
+ tem = t->next;
+ delete t;
+ }
+}
+
+/* Find all fonts matching the font pattern PT. */
+struct haiku_font_pattern *
+BFont_find (struct haiku_font_pattern *pt)
+{
+ struct haiku_font_pattern *r = NULL;
+ font_family name;
+ font_style sname;
+ uint32 flags;
+ int sty_count;
+ int fam_count = count_font_families ();
+
+ for (int fi = 0; fi < fam_count; ++fi)
+ {
+ if (get_font_family (fi, &name, &flags) == B_OK)
+ {
+ sty_count = count_font_styles (name);
+ if (!sty_count &&
+ font_family_style_matches_p (name, NULL, flags, pt))
+ {
+ struct haiku_font_pattern *p = new struct haiku_font_pattern;
+ p->specified = 0;
+ p->oblique_seen_p = 1;
+ haiku_font_fill_pattern (p, name, NULL, flags);
+ p->next = r;
+ if (p->next)
+ p->next->last = p;
+ p->last = NULL;
+ p->next_family = r;
+ r = p;
+ }
+ else if (sty_count)
+ {
+ for (int si = 0; si < sty_count; ++si)
+ {
+ int oblique_seen_p = 0;
+ struct haiku_font_pattern *head = r;
+ struct haiku_font_pattern *p = NULL;
+
+ if (get_font_style (name, si, &sname, &flags) == B_OK)
+ {
+ if (font_family_style_matches_p (name, (char *) &sname, flags, pt))
+ {
+ p = new struct haiku_font_pattern;
+ p->specified = 0;
+ haiku_font_fill_pattern (p, name, (char *) &sname, flags);
+ if (p->specified & FSPEC_SLANT &&
+ ((p->slant == SLANT_OBLIQUE) || (p->slant == SLANT_ITALIC)))
+ oblique_seen_p = 1;
+
+ p->next = r;
+ if (p->next)
+ p->next->last = p;
+ r = p;
+ p->next_family = head;
+ }
+ }
+
+ if (p)
+ p->last = NULL;
+
+ for (; head; head = head->last)
+ {
+ head->oblique_seen_p = oblique_seen_p;
+ }
+ }
+ }
+ }
+ }
+
+ /* There's a very good chance that this result will get cached if no
+ slant is specified. Thus, we look through each font that hasn't
+ seen an oblique style, and add one. */
+
+ if (!(pt->specified & FSPEC_SLANT))
+ {
+ /* r->last is invalid from here onwards. */
+ for (struct haiku_font_pattern *p = r; p;)
+ {
+ if (!p->oblique_seen_p)
+ {
+ struct haiku_font_pattern *n = new haiku_font_pattern;
+ *n = *p;
+ n->slant = SLANT_OBLIQUE;
+ p->next = n;
+ p = p->next_family;
+ }
+ else
+ p = p->next_family;
+ }
+ }
+
+ return r;
+}
+
+/* Find and open a font matching the pattern PAT, which must have its
+ family set. */
+int
+BFont_open_pattern (struct haiku_font_pattern *pat, void **font, float size)
+{
+ int sty_count;
+ font_family name;
+ font_style sname;
+ uint32 flags = 0;
+ if (!(pat->specified & FSPEC_FAMILY))
+ return 1;
+ strncpy (name, pat->family, sizeof name - 1);
+ sty_count = count_font_styles (name);
+
+ if (!sty_count &&
+ font_family_style_matches_p (name, NULL, flags, pat, 1))
+ {
+ BFont *ft = new BFont;
+ if (ft->SetFamilyAndStyle (name, NULL) != B_OK)
+ {
+ delete ft;
+ return 1;
+ }
+ ft->SetSize (size);
+ ft->SetEncoding (B_UNICODE_UTF8);
+ ft->SetSpacing (B_BITMAP_SPACING);
+ *font = (void *) ft;
+ return 0;
+ }
+ else if (sty_count)
+ {
+ for (int si = 0; si < sty_count; ++si)
+ {
+ if (get_font_style (name, si, &sname, &flags) == B_OK &&
+ font_family_style_matches_p (name, (char *) &sname, flags, pat))
+ {
+ BFont *ft = new BFont;
+ if (ft->SetFamilyAndStyle (name, sname) != B_OK)
+ {
+ delete ft;
+ return 1;
+ }
+ ft->SetSize (size);
+ ft->SetEncoding (B_UNICODE_UTF8);
+ ft->SetSpacing (B_BITMAP_SPACING);
+ *font = (void *) ft;
+ return 0;
+ }
+ }
+ }
+
+ if (pat->specified & FSPEC_SLANT && pat->slant == SLANT_OBLIQUE)
+ {
+ struct haiku_font_pattern copy = *pat;
+ copy.slant = SLANT_REGULAR;
+ int code = BFont_open_pattern (&copy, font, size);
+ if (code)
+ return code;
+ BFont *ft = (BFont *) *font;
+ /* XXX Font measurements don't respect shear. Haiku bug?
+ This apparently worked in BeOS.
+ ft->SetShear (100.0); */
+ ft->SetFace (B_ITALIC_FACE);
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Query the family of the default fixed font. */
+void
+BFont_populate_fixed_family (struct haiku_font_pattern *ptn)
+{
+ font_family f;
+ font_style s;
+ be_fixed_font->GetFamilyAndStyle (&f, &s);
+
+ ptn->specified |= FSPEC_FAMILY;
+ strncpy (ptn->family, f, sizeof ptn->family - 1);
+}
+
+void
+BFont_populate_plain_family (struct haiku_font_pattern *ptn)
+{
+ font_family f;
+ font_style s;
+ be_plain_font->GetFamilyAndStyle (&f, &s);
+
+ ptn->specified |= FSPEC_FAMILY;
+ strncpy (ptn->family, f, sizeof ptn->family - 1);
+}
+
+int
+BFont_string_width (void *font, const char *utf8)
+{
+ return ((BFont *) font)->StringWidth (utf8);
+}
diff --git a/src/haiku_io.c b/src/haiku_io.c
new file mode 100644
index 00000000000..c152d9b086a
--- /dev/null
+++ b/src/haiku_io.c
@@ -0,0 +1,207 @@
+/* Haiku window system support.
+ Copyright (C) 2021 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/>. */
+
+#include <config.h>
+
+#include <signal.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include <OS.h>
+
+#include "haiku_support.h"
+#include "lisp.h"
+#include "haikuterm.h"
+#include "blockinput.h"
+
+#define PORT_CAP 1200
+
+/* The port used to send messages from the application thread to
+ Emacs. */
+port_id port_application_to_emacs;
+
+void
+haiku_io_init (void)
+{
+ port_application_to_emacs = create_port (PORT_CAP, "application emacs port");
+}
+
+static ssize_t
+haiku_len (enum haiku_event_type type)
+{
+ switch (type)
+ {
+ case QUIT_REQUESTED:
+ return sizeof (struct haiku_quit_requested_event);
+ case FRAME_RESIZED:
+ return sizeof (struct haiku_resize_event);
+ case FRAME_EXPOSED:
+ return sizeof (struct haiku_expose_event);
+ case KEY_DOWN:
+ case KEY_UP:
+ return sizeof (struct haiku_key_event);
+ case ACTIVATION:
+ return sizeof (struct haiku_activation_event);
+ case MOUSE_MOTION:
+ return sizeof (struct haiku_mouse_motion_event);
+ case BUTTON_DOWN:
+ case BUTTON_UP:
+ return sizeof (struct haiku_button_event);
+ case ICONIFICATION:
+ return sizeof (struct haiku_iconification_event);
+ case MOVE_EVENT:
+ return sizeof (struct haiku_move_event);
+ case SCROLL_BAR_VALUE_EVENT:
+ return sizeof (struct haiku_scroll_bar_value_event);
+ case SCROLL_BAR_DRAG_EVENT:
+ return sizeof (struct haiku_scroll_bar_drag_event);
+ case WHEEL_MOVE_EVENT:
+ return sizeof (struct haiku_wheel_move_event);
+ case MENU_BAR_RESIZE:
+ return sizeof (struct haiku_menu_bar_resize_event);
+ case MENU_BAR_OPEN:
+ case MENU_BAR_CLOSE:
+ return sizeof (struct haiku_menu_bar_state_event);
+ case MENU_BAR_SELECT_EVENT:
+ return sizeof (struct haiku_menu_bar_select_event);
+ case FILE_PANEL_EVENT:
+ return sizeof (struct haiku_file_panel_event);
+ case MENU_BAR_HELP_EVENT:
+ return sizeof (struct haiku_menu_bar_help_event);
+ case ZOOM_EVENT:
+ return sizeof (struct haiku_zoom_event);
+ case REFS_EVENT:
+ return sizeof (struct haiku_refs_event);
+ case APP_QUIT_REQUESTED_EVENT:
+ return sizeof (struct haiku_app_quit_requested_event);
+ }
+
+ emacs_abort ();
+}
+
+/* Read the size of the next message into len, returning -1 if the
+ query fails or there is no next message. */
+void
+haiku_read_size (ssize_t *len)
+{
+ port_id from = port_application_to_emacs;
+ ssize_t size;
+
+ size = port_buffer_size_etc (from, B_TIMEOUT, 0);
+
+ if (size < B_OK)
+ *len = -1;
+ else
+ *len = size;
+}
+
+/* Read the next message into BUF, putting its type into TYPE,
+ assuming the message is at most LEN long. Return 0 if successful
+ and -1 if the read fails. */
+int
+haiku_read (enum haiku_event_type *type, void *buf, ssize_t len)
+{
+ int32 typ;
+ port_id from = port_application_to_emacs;
+
+ if (read_port (from, &typ, buf, len) < B_OK)
+ return -1;
+
+ *type = (enum haiku_event_type) typ;
+ eassert (len >= haiku_len (typ));
+ return 0;
+}
+
+/* The same as haiku_read, but time out after TIMEOUT microseconds.
+ Input is blocked when an attempt to read is in progress. */
+int
+haiku_read_with_timeout (enum haiku_event_type *type, void *buf, ssize_t len,
+ time_t timeout)
+{
+ int32 typ;
+ port_id from = port_application_to_emacs;
+
+ block_input ();
+ if (read_port_etc (from, &typ, buf, len,
+ B_TIMEOUT, (bigtime_t) timeout) < B_OK)
+ {
+ unblock_input ();
+ return -1;
+ }
+ unblock_input ();
+ *type = (enum haiku_event_type) typ;
+ eassert (len >= haiku_len (typ));
+ return 0;
+}
+
+/* Write a message with type TYPE into BUF. */
+int
+haiku_write (enum haiku_event_type type, void *buf)
+{
+ port_id to = port_application_to_emacs;
+
+ if (write_port (to, (int32_t) type, buf, haiku_len (type)) < B_OK)
+ return -1;
+
+ kill (getpid (), SIGPOLL);
+
+ return 0;
+}
+
+int
+haiku_write_without_signal (enum haiku_event_type type, void *buf)
+{
+ port_id to = port_application_to_emacs;
+
+ if (write_port (to, (int32_t) type, buf, haiku_len (type)) < B_OK)
+ return -1;
+
+ return 0;
+}
+
+void
+haiku_io_init_in_app_thread (void)
+{
+ sigset_t set;
+ sigfillset (&set);
+
+ if (pthread_sigmask (SIG_BLOCK, &set, NULL))
+ perror ("pthread_sigmask");
+}
+
+/* Record an unwind protect from C++ code. */
+void
+record_c_unwind_protect_from_cxx (void (*fn) (void *), void *r)
+{
+ record_unwind_protect_ptr (fn, r);
+}
+
+/* SPECPDL_IDX that is safe from C++ code. */
+ptrdiff_t
+c_specpdl_idx_from_cxx (void)
+{
+ return SPECPDL_INDEX ();
+}
+
+/* unbind_to (IDX, Qnil), but safe from C++ code. */
+void
+c_unbind_to_nil_from_cxx (ptrdiff_t idx)
+{
+ unbind_to (idx, Qnil);
+}
diff --git a/src/haiku_select.cc b/src/haiku_select.cc
new file mode 100644
index 00000000000..6cd6ee879e5
--- /dev/null
+++ b/src/haiku_select.cc
@@ -0,0 +1,229 @@
+/* Haiku window system selection support. Hey Emacs, this is -*- C++ -*-
+ Copyright (C) 2021 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/>. */
+
+#include <config.h>
+
+#include <Clipboard.h>
+
+#include <cstdlib>
+#include <cstring>
+
+#include "haikuselect.h"
+
+
+static BClipboard *primary = NULL;
+static BClipboard *secondary = NULL;
+static BClipboard *system_clipboard = NULL;
+
+int selection_state_flag;
+
+static char *
+BClipboard_find_data (BClipboard *cb, const char *type, ssize_t *len)
+{
+ if (!cb->Lock ())
+ return 0;
+
+ BMessage *dat = cb->Data ();
+ if (!dat)
+ {
+ cb->Unlock ();
+ return 0;
+ }
+
+ const char *ptr;
+ ssize_t bt;
+ dat->FindData (type, B_MIME_TYPE, (const void **) &ptr, &bt);
+
+ if (!ptr)
+ {
+ cb->Unlock ();
+ return NULL;
+ }
+
+ if (len)
+ *len = bt;
+
+ cb->Unlock ();
+
+ return strndup (ptr, bt);
+}
+
+static void
+BClipboard_get_targets (BClipboard *cb, char **buf, int buf_size)
+{
+ BMessage *data;
+ char *name;
+ int32 count_found;
+ type_code type;
+ int32 i;
+ int index;
+
+ if (!cb->Lock ())
+ {
+ buf[0] = NULL;
+ return;
+ }
+
+ data = cb->Data ();
+ index = 0;
+
+ if (!data)
+ {
+ buf[0] = NULL;
+ cb->Unlock ();
+ return;
+ }
+
+ for (i = 0; (data->GetInfo (B_ANY_TYPE, i, &name,
+ &type, &count_found)
+ == B_OK); ++i)
+ {
+ if (type == B_MIME_TYPE)
+ {
+ if (index < (buf_size - 1))
+ {
+ buf[index++] = strdup (name);
+
+ if (!buf[index - 1])
+ break;
+ }
+ }
+ }
+
+ buf[index] = NULL;
+
+ cb->Unlock ();
+}
+
+static void
+BClipboard_set_data (BClipboard *cb, const char *type, const char *dat,
+ ssize_t len, bool clear)
+{
+ if (!cb->Lock ())
+ return;
+
+ if (clear)
+ cb->Clear ();
+
+ BMessage *mdat = cb->Data ();
+ if (!mdat)
+ {
+ cb->Unlock ();
+ return;
+ }
+
+ if (dat)
+ {
+ if (mdat->ReplaceData (type, B_MIME_TYPE, dat, len)
+ == B_NAME_NOT_FOUND)
+ mdat->AddData (type, B_MIME_TYPE, dat, len);
+ }
+ else
+ mdat->RemoveName (type);
+ cb->Commit ();
+ cb->Unlock ();
+}
+
+char *
+BClipboard_find_system_data (const char *type, ssize_t *len)
+{
+ if (!system_clipboard)
+ return 0;
+
+ return BClipboard_find_data (system_clipboard, type, len);
+}
+
+char *
+BClipboard_find_primary_selection_data (const char *type, ssize_t *len)
+{
+ if (!primary)
+ return 0;
+
+ return BClipboard_find_data (primary, type, len);
+}
+
+char *
+BClipboard_find_secondary_selection_data (const char *type, ssize_t *len)
+{
+ if (!secondary)
+ return 0;
+
+ return BClipboard_find_data (secondary, type, len);
+}
+
+void
+BClipboard_set_system_data (const char *type, const char *data,
+ ssize_t len, bool clear)
+{
+ if (!system_clipboard)
+ return;
+
+ BClipboard_set_data (system_clipboard, type, data, len, clear);
+}
+
+void
+BClipboard_set_primary_selection_data (const char *type, const char *data,
+ ssize_t len, bool clear)
+{
+ if (!primary)
+ return;
+
+ BClipboard_set_data (primary, type, data, len, clear);
+}
+
+void
+BClipboard_set_secondary_selection_data (const char *type, const char *data,
+ ssize_t len, bool clear)
+{
+ if (!secondary)
+ return;
+
+ BClipboard_set_data (secondary, type, data, len, clear);
+}
+
+void
+BClipboard_free_data (void *ptr)
+{
+ std::free (ptr);
+}
+
+void
+BClipboard_system_targets (char **buf, int len)
+{
+ BClipboard_get_targets (system_clipboard, buf, len);
+}
+
+void
+BClipboard_primary_targets (char **buf, int len)
+{
+ BClipboard_get_targets (primary, buf, len);
+}
+
+void
+BClipboard_secondary_targets (char **buf, int len)
+{
+ BClipboard_get_targets (secondary, buf, len);
+}
+
+void
+init_haiku_select (void)
+{
+ system_clipboard = new BClipboard ("system");
+ primary = new BClipboard ("primary");
+ secondary = new BClipboard ("secondary");
+}
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
new file mode 100644
index 00000000000..b8f6e84d2c3
--- /dev/null
+++ b/src/haiku_support.cc
@@ -0,0 +1,2928 @@
+/* Haiku window system support. Hey, Emacs, this is -*- C++ -*-
+ Copyright (C) 2021 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/>. */
+
+#include <config.h>
+
+#include <app/Application.h>
+#include <app/Cursor.h>
+#include <app/Messenger.h>
+
+#include <interface/GraphicsDefs.h>
+#include <interface/InterfaceDefs.h>
+#include <interface/Bitmap.h>
+#include <interface/Window.h>
+#include <interface/View.h>
+#include <interface/Screen.h>
+#include <interface/ScrollBar.h>
+#include <interface/Region.h>
+#include <interface/Menu.h>
+#include <interface/MenuItem.h>
+#include <interface/PopUpMenu.h>
+#include <interface/MenuBar.h>
+#include <interface/Alert.h>
+#include <interface/Button.h>
+
+#include <locale/UnicodeChar.h>
+
+#include <game/WindowScreen.h>
+#include <game/DirectWindow.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 <support/Beep.h>
+#include <support/DataIO.h>
+#include <support/Locker.h>
+
+#include <translation/TranslatorRoster.h>
+#include <translation/TranslationDefs.h>
+#include <translation/TranslationUtils.h>
+
+#include <kernel/OS.h>
+#include <kernel/fs_attr.h>
+#include <kernel/scheduler.h>
+
+#include <private/interface/ToolTip.h>
+
+#include <cmath>
+#include <cstring>
+#include <cstdint>
+#include <cstdio>
+#include <csignal>
+#include <cfloat>
+
+#include <pthread.h>
+
+#ifdef USE_BE_CAIRO
+#include <cairo.h>
+#endif
+
+#include "haiku_support.h"
+
+#define SCROLL_BAR_UPDATE 3000
+
+static color_space dpy_color_space = B_NO_COLOR_SPACE;
+static key_map *key_map = NULL;
+static char *key_chars = NULL;
+static BLocker key_map_lock;
+
+extern "C"
+{
+ extern _Noreturn void emacs_abort (void);
+ /* Also defined in haikuterm.h. */
+ extern void be_app_quit (void);
+}
+
+static thread_id app_thread;
+
+_Noreturn void
+gui_abort (const char *msg)
+{
+ fprintf (stderr, "Abort in GUI code: %s\n", msg);
+ fprintf (stderr, "Under Haiku, Emacs cannot recover from errors in GUI code\n");
+ fprintf (stderr, "App Server disconnects usually manifest as bitmap "
+ "initialization failures or lock failures.");
+ emacs_abort ();
+}
+
+#ifdef USE_BE_CAIRO
+static cairo_format_t
+cairo_format_from_color_space (color_space space)
+{
+ switch (space)
+ {
+ case B_RGBA32:
+ return CAIRO_FORMAT_ARGB32;
+ case B_RGB32:
+ return CAIRO_FORMAT_RGB24;
+ case B_RGB16:
+ return CAIRO_FORMAT_RGB16_565;
+ case B_GRAY8:
+ return CAIRO_FORMAT_A8;
+ case B_GRAY1:
+ return CAIRO_FORMAT_A1;
+ default:
+ gui_abort ("Unsupported color space");
+ }
+}
+#endif
+
+static void
+map_key (char *chars, int32 offset, uint32_t *c)
+{
+ int size = chars[offset++];
+ switch (size)
+ {
+ case 0:
+ break;
+
+ case 1:
+ *c = chars[offset];
+ break;
+
+ default:
+ {
+ char str[5];
+ int i = (size <= 4) ? size : 4;
+ strncpy (str, &(chars[offset]), i);
+ str[i] = '0';
+ *c = BUnicodeChar::FromUTF8 ((char *) &str);
+ break;
+ }
+ }
+}
+
+static void
+map_shift (uint32_t kc, uint32_t *ch)
+{
+ if (!key_map_lock.Lock ())
+ gui_abort ("Failed to lock keymap");
+ if (!key_map)
+ get_key_map (&key_map, &key_chars);
+ if (!key_map)
+ return;
+ if (kc >= 128)
+ return;
+
+ int32_t m = key_map->shift_map[kc];
+ map_key (key_chars, m, ch);
+ key_map_lock.Unlock ();
+}
+
+static void
+map_normal (uint32_t kc, uint32_t *ch)
+{
+ if (!key_map_lock.Lock ())
+ gui_abort ("Failed to lock keymap");
+ if (!key_map)
+ get_key_map (&key_map, &key_chars);
+ if (!key_map)
+ return;
+ if (kc >= 128)
+ return;
+
+ int32_t m = key_map->normal_map[kc];
+ map_key (key_chars, m, ch);
+ key_map_lock.Unlock ();
+}
+
+class Emacs : public BApplication
+{
+public:
+ Emacs () : BApplication ("application/x-vnd.GNU-emacs")
+ {
+ }
+
+ void
+ AboutRequested (void)
+ {
+ BAlert *about = new BAlert (PACKAGE_NAME,
+ PACKAGE_STRING
+ "\nThe extensible, self-documenting, real-time display editor.",
+ "Close");
+ about->Go ();
+ }
+
+ bool
+ QuitRequested (void)
+ {
+ struct haiku_app_quit_requested_event rq;
+ haiku_write (APP_QUIT_REQUESTED_EVENT, &rq);
+ return 0;
+ }
+
+ void
+ RefsReceived (BMessage *msg)
+ {
+ struct haiku_refs_event rq;
+ entry_ref ref;
+ BEntry entry;
+ BPath path;
+ int32 cookie = 0;
+ int32 x, y;
+ void *window;
+
+ if ((msg->FindPointer ("window", 0, &window) != B_OK)
+ || (msg->FindInt32 ("x", 0, &x) != B_OK)
+ || (msg->FindInt32 ("y", 0, &y) != B_OK))
+ return;
+
+ rq.window = window;
+ rq.x = x;
+ rq.y = y;
+
+ while (msg->FindRef ("refs", cookie++, &ref) == B_OK)
+ {
+ if (entry.SetTo (&ref, 0) == B_OK
+ && entry.GetPath (&path) == B_OK)
+ {
+ rq.ref = strdup (path.Path ());
+ haiku_write (REFS_EVENT, &rq);
+ }
+ }
+ }
+};
+
+class EmacsWindow : public BDirectWindow
+{
+public:
+ struct child_frame
+ {
+ struct child_frame *next;
+ int xoff, yoff;
+ EmacsWindow *window;
+ } *subset_windows = NULL;
+
+ EmacsWindow *parent = NULL;
+ BRect pre_fullscreen_rect;
+ BRect pre_zoom_rect;
+ int x_before_zoom = INT_MIN;
+ int y_before_zoom = INT_MIN;
+ int fullscreen_p = 0;
+ int zoomed_p = 0;
+ int shown_flag = 0;
+
+#ifdef USE_BE_CAIRO
+ BLocker surface_lock;
+ cairo_surface_t *cr_surface = NULL;
+#endif
+
+ EmacsWindow () : BDirectWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK,
+ B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS)
+ {
+
+ }
+
+ ~EmacsWindow ()
+ {
+ struct child_frame *next;
+ for (struct child_frame *f = subset_windows; f; f = next)
+ {
+ f->window->Unparent ();
+ next = f->next;
+ delete f;
+ }
+
+ if (this->parent)
+ UnparentAndUnlink ();
+
+#ifdef USE_BE_CAIRO
+ if (!surface_lock.Lock ())
+ gui_abort ("Failed to lock cairo surface");
+ if (cr_surface)
+ {
+ cairo_surface_destroy (cr_surface);
+ cr_surface = NULL;
+ }
+ surface_lock.Unlock ();
+#endif
+ }
+
+ void
+ UpwardsSubset (EmacsWindow *w)
+ {
+ for (; w; w = w->parent)
+ AddToSubset (w);
+ }
+
+ void
+ UpwardsSubsetChildren (EmacsWindow *w)
+ {
+ UpwardsSubset (w);
+ for (struct child_frame *f = subset_windows; f;
+ f = f->next)
+ f->window->UpwardsSubsetChildren (w);
+ }
+
+ void
+ UpwardsUnSubset (EmacsWindow *w)
+ {
+ for (; w; w = w->parent)
+ RemoveFromSubset (w);
+ }
+
+ void
+ UpwardsUnSubsetChildren (EmacsWindow *w)
+ {
+ UpwardsUnSubset (w);
+ for (struct child_frame *f = subset_windows; f;
+ f = f->next)
+ f->window->UpwardsUnSubsetChildren (w);
+ }
+
+ void
+ Unparent (void)
+ {
+ this->SetFeel (B_NORMAL_WINDOW_FEEL);
+ UpwardsUnSubsetChildren (parent);
+ this->RemoveFromSubset (this);
+ this->parent = NULL;
+ if (fullscreen_p)
+ {
+ fullscreen_p = 0;
+ MakeFullscreen (1);
+ }
+ }
+
+ void
+ UnparentAndUnlink (void)
+ {
+ this->parent->UnlinkChild (this);
+ this->Unparent ();
+ }
+
+ void
+ UnlinkChild (EmacsWindow *window)
+ {
+ struct child_frame *last = NULL;
+ struct child_frame *tem = subset_windows;
+
+ for (; tem; last = tem, tem = tem->next)
+ {
+ if (tem->window == window)
+ {
+ if (last)
+ last->next = tem->next;
+ if (tem == subset_windows)
+ subset_windows = NULL;
+ delete tem;
+ return;
+ }
+ }
+
+ gui_abort ("Failed to unlink child frame");
+ }
+
+ void
+ ParentTo (EmacsWindow *window)
+ {
+ if (this->parent)
+ UnparentAndUnlink ();
+
+ this->parent = window;
+ this->SetFeel (B_FLOATING_SUBSET_WINDOW_FEEL);
+ this->AddToSubset (this);
+ if (!IsHidden () && this->parent)
+ UpwardsSubsetChildren (parent);
+ if (fullscreen_p)
+ {
+ fullscreen_p = 0;
+ MakeFullscreen (1);
+ }
+ this->Sync ();
+ window->LinkChild (this);
+ }
+
+ void
+ LinkChild (EmacsWindow *window)
+ {
+ struct child_frame *f = new struct child_frame;
+
+ for (struct child_frame *f = subset_windows; f;
+ f = f->next)
+ {
+ if (window == f->window)
+ gui_abort ("Trying to link a child frame that is already present");
+ }
+
+ f->window = window;
+ f->next = subset_windows;
+ f->xoff = -1;
+ f->yoff = -1;
+
+ subset_windows = f;
+ }
+
+ void
+ DoMove (struct child_frame *f)
+ {
+ BRect frame = this->Frame ();
+ f->window->MoveTo (frame.left + f->xoff,
+ frame.top + f->yoff);
+ this->Sync ();
+ }
+
+ void
+ DoUpdateWorkspace (struct child_frame *f)
+ {
+ f->window->SetWorkspaces (this->Workspaces ());
+ }
+
+ void
+ MoveChild (EmacsWindow *window, int xoff, int yoff,
+ int weak_p)
+ {
+ for (struct child_frame *f = subset_windows; f;
+ f = f->next)
+ {
+ if (window == f->window)
+ {
+ f->xoff = xoff;
+ f->yoff = yoff;
+ if (!weak_p)
+ DoMove (f);
+ return;
+ }
+ }
+
+ gui_abort ("Trying to move a child frame that doesn't exist");
+ }
+
+ void
+ WindowActivated (bool activated)
+ {
+ struct haiku_activation_event rq;
+ rq.window = this;
+ rq.activated_p = activated;
+
+ haiku_write (ACTIVATION, &rq);
+ }
+
+ void
+ DirectConnected (direct_buffer_info *info)
+ {
+#ifdef USE_BE_CAIRO
+ if (!surface_lock.Lock ())
+ gui_abort ("Failed to lock window direct cr surface");
+ if (cr_surface)
+ {
+ cairo_surface_destroy (cr_surface);
+ cr_surface = NULL;
+ }
+
+ if (info->buffer_state != B_DIRECT_STOP)
+ {
+ int left, top, right, bottom;
+ left = info->clip_bounds.left;
+ top = info->clip_bounds.top;
+ right = info->clip_bounds.right;
+ bottom = info->clip_bounds.bottom;
+
+ unsigned char *bits = (unsigned char *) info->bits;
+ if ((info->bits_per_pixel % 8) == 0)
+ {
+ bits += info->bytes_per_row * top;
+ bits += (left * info->bits_per_pixel / 8);
+ cr_surface = cairo_image_surface_create_for_data
+ (bits,
+ cairo_format_from_color_space (info->pixel_format),
+ right - left + 1,
+ bottom - top + 1,
+ info->bytes_per_row);
+ }
+ }
+ surface_lock.Unlock ();
+#endif
+ }
+
+ void
+ MessageReceived (BMessage *msg)
+ {
+ int32 old_what = 0;
+
+ if (msg->WasDropped ())
+ {
+ entry_ref ref;
+ BPoint whereto;
+
+ if (msg->FindRef ("refs", &ref) == B_OK)
+ {
+ msg->what = B_REFS_RECEIVED;
+ msg->AddPointer ("window", this);
+ if (msg->FindPoint ("_drop_point_", &whereto) == B_OK)
+ {
+ this->ConvertFromScreen (&whereto);
+ msg->AddInt32 ("x", whereto.x);
+ msg->AddInt32 ("y", whereto.y);
+ }
+ be_app->PostMessage (msg);
+ msg->SendReply (B_OK);
+ }
+ }
+ else if (msg->GetPointer ("menuptr"))
+ {
+ struct haiku_menu_bar_select_event rq;
+ rq.window = this;
+ rq.ptr = (void *) msg->GetPointer ("menuptr");
+ haiku_write (MENU_BAR_SELECT_EVENT, &rq);
+ }
+ else if (msg->what == 'FPSE'
+ || ((msg->FindInt32 ("old_what", &old_what) == B_OK
+ && old_what == 'FPSE')))
+ {
+ struct haiku_file_panel_event rq;
+ BEntry entry;
+ BPath path;
+ entry_ref ref;
+
+ rq.ptr = NULL;
+
+ if (msg->FindRef ("refs", &ref) == B_OK &&
+ entry.SetTo (&ref, 0) == B_OK &&
+ entry.GetPath (&path) == B_OK)
+ {
+ const char *str_path = path.Path ();
+ if (str_path)
+ rq.ptr = strdup (str_path);
+ }
+
+ if (msg->FindRef ("directory", &ref),
+ entry.SetTo (&ref, 0) == B_OK &&
+ entry.GetPath (&path) == B_OK)
+ {
+ const char *name = msg->GetString ("name");
+ const char *str_path = path.Path ();
+
+ if (name)
+ {
+ char str_buf[std::strlen (str_path)
+ + std::strlen (name) + 2];
+ snprintf ((char *) &str_buf,
+ std::strlen (str_path)
+ + std::strlen (name) + 2, "%s/%s",
+ str_path, name);
+ rq.ptr = strdup (str_buf);
+ }
+ }
+
+ haiku_write (FILE_PANEL_EVENT, &rq);
+ }
+ else
+ BDirectWindow::MessageReceived (msg);
+ }
+
+ void
+ DispatchMessage (BMessage *msg, BHandler *handler)
+ {
+ if (msg->what == B_KEY_DOWN || msg->what == B_KEY_UP)
+ {
+ struct haiku_key_event rq;
+ rq.window = this;
+
+ int32_t code = msg->GetInt32 ("raw_char", 0);
+
+ rq.modifiers = 0;
+ uint32_t mods = modifiers ();
+
+ if (mods & B_SHIFT_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_SHIFT;
+
+ if (mods & B_CONTROL_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_CTRL;
+
+ if (mods & B_COMMAND_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_ALT;
+
+ if (mods & B_OPTION_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_SUPER;
+
+ rq.mb_char = code;
+ rq.kc = msg->GetInt32 ("key", -1);
+ rq.unraw_mb_char =
+ BUnicodeChar::FromUTF8 (msg->GetString ("bytes"));
+
+ if ((mods & B_SHIFT_KEY) && rq.kc >= 0)
+ map_shift (rq.kc, &rq.unraw_mb_char);
+ else if (rq.kc >= 0)
+ map_normal (rq.kc, &rq.unraw_mb_char);
+
+ haiku_write (msg->what == B_KEY_DOWN ? KEY_DOWN : KEY_UP, &rq);
+ }
+ else if (msg->what == B_MOUSE_WHEEL_CHANGED)
+ {
+ struct haiku_wheel_move_event rq;
+ rq.window = this;
+ rq.modifiers = 0;
+
+ uint32_t mods = modifiers ();
+
+ if (mods & B_SHIFT_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_SHIFT;
+
+ if (mods & B_CONTROL_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_CTRL;
+
+ if (mods & B_COMMAND_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_ALT;
+
+ if (mods & B_OPTION_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_SUPER;
+
+ float dx, dy;
+ if (msg->FindFloat ("be:wheel_delta_x", &dx) == B_OK &&
+ msg->FindFloat ("be:wheel_delta_y", &dy) == B_OK)
+ {
+ rq.delta_x = dx;
+ rq.delta_y = dy;
+
+ haiku_write (WHEEL_MOVE_EVENT, &rq);
+ };
+ }
+ else
+ BDirectWindow::DispatchMessage (msg, handler);
+ }
+
+ void
+ MenusBeginning ()
+ {
+ struct haiku_menu_bar_state_event rq;
+ rq.window = this;
+
+ haiku_write (MENU_BAR_OPEN, &rq);
+ }
+
+ void
+ MenusEnded ()
+ {
+ struct haiku_menu_bar_state_event rq;
+ rq.window = this;
+
+ haiku_write (MENU_BAR_CLOSE, &rq);
+ }
+
+ void
+ FrameResized (float newWidth, float newHeight)
+ {
+ struct haiku_resize_event rq;
+ rq.window = this;
+ rq.px_heightf = newHeight + 1.0f;
+ rq.px_widthf = newWidth + 1.0f;
+
+ haiku_write (FRAME_RESIZED, &rq);
+ BDirectWindow::FrameResized (newWidth, newHeight);
+ }
+
+ void
+ FrameMoved (BPoint newPosition)
+ {
+ struct haiku_move_event rq;
+ rq.window = this;
+ rq.x = std::lrint (newPosition.x);
+ rq.y = std::lrint (newPosition.y);
+
+ haiku_write (MOVE_EVENT, &rq);
+
+ for (struct child_frame *f = subset_windows;
+ f; f = f->next)
+ DoMove (f);
+ BDirectWindow::FrameMoved (newPosition);
+ }
+
+ void
+ WorkspacesChanged (uint32_t old, uint32_t n)
+ {
+ for (struct child_frame *f = subset_windows;
+ f; f = f->next)
+ DoUpdateWorkspace (f);
+ }
+
+ void
+ EmacsMoveTo (int x, int y)
+ {
+ if (!this->parent)
+ this->MoveTo (x, y);
+ else
+ this->parent->MoveChild (this, x, y, 0);
+ }
+
+ bool
+ QuitRequested ()
+ {
+ struct haiku_quit_requested_event rq;
+ rq.window = this;
+ haiku_write (QUIT_REQUESTED, &rq);
+ return false;
+ }
+
+ void
+ Minimize (bool minimized_p)
+ {
+ BDirectWindow::Minimize (minimized_p);
+ struct haiku_iconification_event rq;
+ rq.window = this;
+ rq.iconified_p = !parent && minimized_p;
+
+ haiku_write (ICONIFICATION, &rq);
+ }
+
+ void
+ EmacsHide (void)
+ {
+ if (this->IsHidden ())
+ return;
+ Hide ();
+ if (this->parent)
+ UpwardsUnSubsetChildren (this->parent);
+ }
+
+ void
+ EmacsShow (void)
+ {
+ if (!this->IsHidden ())
+ return;
+ if (this->parent)
+ shown_flag = 1;
+ Show ();
+ if (this->parent)
+ UpwardsSubsetChildren (this->parent);
+ }
+
+ void
+ Zoom (BPoint o, float w, float h)
+ {
+ struct haiku_zoom_event rq;
+ rq.window = this;
+
+ rq.x = o.x;
+ rq.y = o.y;
+
+ rq.width = w + 1;
+ rq.height = h + 1;
+
+ if (fullscreen_p)
+ MakeFullscreen (0);
+
+ if (o.x != x_before_zoom ||
+ o.y != y_before_zoom)
+ {
+ x_before_zoom = Frame ().left;
+ y_before_zoom = Frame ().top;
+ pre_zoom_rect = Frame ();
+ zoomed_p = 1;
+ haiku_write (ZOOM_EVENT, &rq);
+ }
+ else
+ {
+ zoomed_p = 0;
+ x_before_zoom = y_before_zoom = INT_MIN;
+ }
+
+ BDirectWindow::Zoom (o, w, h);
+ }
+
+ void
+ UnZoom (void)
+ {
+ if (!zoomed_p)
+ return;
+ zoomed_p = 0;
+
+ EmacsMoveTo (pre_zoom_rect.left, pre_zoom_rect.top);
+ ResizeTo (pre_zoom_rect.Width (),
+ pre_zoom_rect.Height ());
+ }
+
+ void
+ GetParentWidthHeight (int *width, int *height)
+ {
+ if (parent)
+ {
+ *width = parent->Frame ().Width ();
+ *height = parent->Frame ().Height ();
+ }
+ else
+ {
+ BScreen s (this);
+ *width = s.Frame ().Width ();
+ *height = s.Frame ().Height ();
+ }
+ }
+
+ void
+ OffsetChildRect (BRect *r, EmacsWindow *c)
+ {
+ for (struct child_frame *f; f; f = f->next)
+ if (f->window == c)
+ {
+ r->top -= f->yoff;
+ r->bottom -= f->yoff;
+ r->left -= f->xoff;
+ r->right -= f->xoff;
+ return;
+ }
+
+ gui_abort ("Trying to calculate offsets for a child frame that doesn't exist");
+ }
+
+ void
+ MakeFullscreen (int make_fullscreen_p)
+ {
+ BScreen screen (this);
+
+ if (!screen.IsValid ())
+ gui_abort ("Trying to make a window fullscreen without a screen");
+
+ if (make_fullscreen_p == fullscreen_p)
+ return;
+
+ fullscreen_p = make_fullscreen_p;
+ uint32 flags = Flags ();
+ if (fullscreen_p)
+ {
+ if (zoomed_p)
+ UnZoom ();
+
+ flags |= B_NOT_MOVABLE | B_NOT_ZOOMABLE;
+ pre_fullscreen_rect = Frame ();
+ if (parent)
+ parent->OffsetChildRect (&pre_fullscreen_rect, this);
+
+ int w, h;
+ EmacsMoveTo (0, 0);
+ GetParentWidthHeight (&w, &h);
+ ResizeTo (w, h);
+ }
+ else
+ {
+ flags &= ~(B_NOT_MOVABLE | B_NOT_ZOOMABLE);
+ EmacsMoveTo (pre_fullscreen_rect.left,
+ pre_fullscreen_rect.top);
+ ResizeTo (pre_fullscreen_rect.Width (),
+ pre_fullscreen_rect.Height ());
+ }
+ SetFlags (flags);
+ }
+};
+
+class EmacsMenuBar : public BMenuBar
+{
+public:
+ EmacsMenuBar () : BMenuBar (BRect (0, 0, 0, 0), NULL)
+ {
+ }
+
+ void
+ FrameResized (float newWidth, float newHeight)
+ {
+ struct haiku_menu_bar_resize_event rq;
+ rq.window = this->Window ();
+ rq.height = std::lrint (newHeight);
+ rq.width = std::lrint (newWidth);
+
+ haiku_write (MENU_BAR_RESIZE, &rq);
+ BMenuBar::FrameResized (newWidth, newHeight);
+ }
+};
+
+class EmacsView : public BView
+{
+public:
+ uint32_t visible_bell_color = 0;
+ uint32_t previous_buttons = 0;
+ int looper_locked_count = 0;
+ BRegion sb_region;
+
+ BView *offscreen_draw_view = NULL;
+ BBitmap *offscreen_draw_bitmap_1 = NULL;
+ BBitmap *copy_bitmap = NULL;
+
+#ifdef USE_BE_CAIRO
+ cairo_surface_t *cr_surface = NULL;
+ BLocker cr_surface_lock;
+#endif
+
+ BPoint tt_absl_pos;
+
+ color_space cspace;
+
+ EmacsView () : BView (BRect (0, 0, 0, 0), "Emacs", B_FOLLOW_NONE, B_WILL_DRAW)
+ {
+
+ }
+
+ ~EmacsView ()
+ {
+ TearDownDoubleBuffering ();
+ }
+
+ void
+ AttachedToWindow (void)
+ {
+ cspace = B_RGBA32;
+ }
+
+#ifdef USE_BE_CAIRO
+ void
+ DetachCairoSurface (void)
+ {
+ if (!cr_surface_lock.Lock ())
+ gui_abort ("Could not lock cr surface during detachment");
+ if (!cr_surface)
+ gui_abort ("Trying to detach window cr surface when none exists");
+ cairo_surface_destroy (cr_surface);
+ cr_surface = NULL;
+ cr_surface_lock.Unlock ();
+ }
+
+ void
+ AttachCairoSurface (void)
+ {
+ if (!cr_surface_lock.Lock ())
+ gui_abort ("Could not lock cr surface during attachment");
+ if (cr_surface)
+ gui_abort ("Trying to attach cr surface when one already exists");
+ cr_surface = cairo_image_surface_create_for_data
+ ((unsigned char *) offscreen_draw_bitmap_1->Bits (),
+ CAIRO_FORMAT_ARGB32, offscreen_draw_bitmap_1->Bounds ().Width (),
+ offscreen_draw_bitmap_1->Bounds ().Height (),
+ offscreen_draw_bitmap_1->BytesPerRow ());
+ if (!cr_surface)
+ gui_abort ("Cr surface allocation failed for double-buffered view");
+ cr_surface_lock.Unlock ();
+ }
+#endif
+
+ void
+ TearDownDoubleBuffering (void)
+ {
+ if (offscreen_draw_view)
+ {
+ if (Window ())
+ ClearViewBitmap ();
+ if (copy_bitmap)
+ {
+ delete copy_bitmap;
+ copy_bitmap = NULL;
+ }
+ if (!looper_locked_count)
+ if (!offscreen_draw_view->LockLooper ())
+ gui_abort ("Failed to lock offscreen draw view");
+#ifdef USE_BE_CAIRO
+ if (cr_surface)
+ DetachCairoSurface ();
+#endif
+ offscreen_draw_view->RemoveSelf ();
+ delete offscreen_draw_view;
+ offscreen_draw_view = NULL;
+ delete offscreen_draw_bitmap_1;
+ offscreen_draw_bitmap_1 = NULL;
+ }
+ }
+
+ void
+ AfterResize (void)
+ {
+ if (offscreen_draw_view)
+ {
+ if (!LockLooper ())
+ gui_abort ("Failed to lock looper after resize");
+
+ if (!offscreen_draw_view->LockLooper ())
+ gui_abort ("Failed to lock offscreen draw view after resize");
+#ifdef USE_BE_CAIRO
+ DetachCairoSurface ();
+#endif
+ offscreen_draw_view->RemoveSelf ();
+ delete offscreen_draw_bitmap_1;
+ offscreen_draw_bitmap_1 = new BBitmap (Frame (), cspace, 1);
+ if (offscreen_draw_bitmap_1->InitCheck () != B_OK)
+ gui_abort ("Offscreen draw bitmap initialization failed");
+
+ offscreen_draw_view->MoveTo (Frame ().left, Frame ().top);
+ offscreen_draw_view->ResizeTo (Frame ().Width (), Frame ().Height ());
+ offscreen_draw_bitmap_1->AddChild (offscreen_draw_view);
+#ifdef USE_BE_CAIRO
+ AttachCairoSurface ();
+#endif
+
+ if (looper_locked_count)
+ {
+ offscreen_draw_bitmap_1->Lock ();
+ }
+
+ UnlockLooper ();
+ }
+ }
+
+ void
+ Pulse (void)
+ {
+ visible_bell_color = 0;
+ SetFlags (Flags () & ~B_PULSE_NEEDED);
+ Window ()->SetPulseRate (0);
+ Invalidate ();
+ }
+
+ void
+ Draw (BRect expose_bounds)
+ {
+ struct haiku_expose_event rq;
+ EmacsWindow *w = (EmacsWindow *) Window ();
+
+ if (visible_bell_color > 0)
+ {
+ PushState ();
+ BView_SetHighColorForVisibleBell (this, visible_bell_color);
+ FillRect (Frame ());
+ PopState ();
+ return;
+ }
+
+ if (w->shown_flag)
+ {
+ PushState ();
+ SetDrawingMode (B_OP_ERASE);
+ FillRect (Frame ());
+ PopState ();
+ return;
+ }
+
+ if (!offscreen_draw_view)
+ {
+ if (sb_region.Contains (std::lrint (expose_bounds.left),
+ std::lrint (expose_bounds.top)) &&
+ sb_region.Contains (std::lrint (expose_bounds.right),
+ std::lrint (expose_bounds.top)) &&
+ sb_region.Contains (std::lrint (expose_bounds.left),
+ std::lrint (expose_bounds.bottom)) &&
+ sb_region.Contains (std::lrint (expose_bounds.right),
+ std::lrint (expose_bounds.bottom)))
+ return;
+
+ rq.x = std::floor (expose_bounds.left);
+ rq.y = std::floor (expose_bounds.top);
+ rq.width = std::ceil (expose_bounds.right - expose_bounds.left + 1);
+ rq.height = std::ceil (expose_bounds.bottom - expose_bounds.top + 1);
+ if (!rq.width)
+ rq.width = 1;
+ if (!rq.height)
+ rq.height = 1;
+ rq.window = this->Window ();
+
+ haiku_write (FRAME_EXPOSED, &rq);
+ }
+ }
+
+ void
+ DoVisibleBell (uint32_t color)
+ {
+ if (!LockLooper ())
+ gui_abort ("Failed to lock looper during visible bell");
+ visible_bell_color = color | (255 << 24);
+ SetFlags (Flags () | B_PULSE_NEEDED);
+ Window ()->SetPulseRate (100 * 1000);
+ Invalidate ();
+ UnlockLooper ();
+ }
+
+ void
+ FlipBuffers (void)
+ {
+ if (!LockLooper ())
+ gui_abort ("Failed to lock looper during buffer flip");
+ if (!offscreen_draw_view)
+ gui_abort ("Failed to lock offscreen view during buffer flip");
+
+ offscreen_draw_view->Flush ();
+ offscreen_draw_view->Sync ();
+
+ EmacsWindow *w = (EmacsWindow *) Window ();
+ w->shown_flag = 0;
+
+ if (copy_bitmap &&
+ copy_bitmap->Bounds () != offscreen_draw_bitmap_1->Bounds ())
+ {
+ delete copy_bitmap;
+ copy_bitmap = NULL;
+ }
+ if (!copy_bitmap)
+ copy_bitmap = new BBitmap (offscreen_draw_bitmap_1);
+ else
+ copy_bitmap->ImportBits (offscreen_draw_bitmap_1);
+
+ if (copy_bitmap->InitCheck () != B_OK)
+ gui_abort ("Failed to init copy bitmap during buffer flip");
+
+ SetViewBitmap (copy_bitmap,
+ Frame (), Frame (), B_FOLLOW_NONE, 0);
+
+ Invalidate ();
+ UnlockLooper ();
+ return;
+ }
+
+ void
+ SetUpDoubleBuffering (void)
+ {
+ if (!LockLooper ())
+ gui_abort ("Failed to lock self setting up double buffering");
+ if (offscreen_draw_view)
+ gui_abort ("Failed to lock offscreen view setting up double buffering");
+
+ offscreen_draw_bitmap_1 = new BBitmap (Frame (), cspace, 1);
+ if (offscreen_draw_bitmap_1->InitCheck () != B_OK)
+ gui_abort ("Failed to init offscreen bitmap");
+#ifdef USE_BE_CAIRO
+ AttachCairoSurface ();
+#endif
+ offscreen_draw_view = new BView (Frame (), NULL, B_FOLLOW_NONE, B_WILL_DRAW);
+ offscreen_draw_bitmap_1->AddChild (offscreen_draw_view);
+
+ if (looper_locked_count)
+ {
+ if (!offscreen_draw_bitmap_1->Lock ())
+ gui_abort ("Failed to lock bitmap after double buffering was set up.");
+ }
+
+ UnlockLooper ();
+ Invalidate ();
+ }
+
+ void
+ MouseMoved (BPoint point, uint32 transit, const BMessage *msg)
+ {
+ struct haiku_mouse_motion_event rq;
+
+ rq.just_exited_p = transit == B_EXITED_VIEW;
+ rq.x = point.x;
+ rq.y = point.y;
+ rq.be_code = transit;
+ rq.window = this->Window ();
+
+ if (ToolTip ())
+ ToolTip ()->SetMouseRelativeLocation (BPoint (-(point.x - tt_absl_pos.x),
+ -(point.y - tt_absl_pos.y)));
+
+ haiku_write (MOUSE_MOTION, &rq);
+ }
+
+ void
+ MouseDown (BPoint point)
+ {
+ struct haiku_button_event rq;
+ uint32 buttons;
+
+ this->GetMouse (&point, &buttons, false);
+
+ rq.window = this->Window ();
+ rq.btn_no = 0;
+
+ if (!(previous_buttons & B_PRIMARY_MOUSE_BUTTON) &&
+ (buttons & B_PRIMARY_MOUSE_BUTTON))
+ rq.btn_no = 0;
+ else if (!(previous_buttons & B_SECONDARY_MOUSE_BUTTON) &&
+ (buttons & B_SECONDARY_MOUSE_BUTTON))
+ rq.btn_no = 2;
+ else if (!(previous_buttons & B_TERTIARY_MOUSE_BUTTON) &&
+ (buttons & B_TERTIARY_MOUSE_BUTTON))
+ rq.btn_no = 1;
+ previous_buttons = buttons;
+
+ rq.x = point.x;
+ rq.y = point.y;
+
+ uint32_t mods = modifiers ();
+
+ rq.modifiers = 0;
+ if (mods & B_SHIFT_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_SHIFT;
+
+ if (mods & B_CONTROL_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_CTRL;
+
+ if (mods & B_COMMAND_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_ALT;
+
+ if (mods & B_OPTION_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_SUPER;
+
+ SetMouseEventMask (B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
+
+ haiku_write (BUTTON_DOWN, &rq);
+ }
+
+ void
+ MouseUp (BPoint point)
+ {
+ struct haiku_button_event rq;
+ uint32 buttons;
+
+ this->GetMouse (&point, &buttons, false);
+
+ rq.window = this->Window ();
+ rq.btn_no = 0;
+
+ if ((previous_buttons & B_PRIMARY_MOUSE_BUTTON)
+ && !(buttons & B_PRIMARY_MOUSE_BUTTON))
+ rq.btn_no = 0;
+ else if ((previous_buttons & B_SECONDARY_MOUSE_BUTTON)
+ && !(buttons & B_SECONDARY_MOUSE_BUTTON))
+ rq.btn_no = 2;
+ else if ((previous_buttons & B_TERTIARY_MOUSE_BUTTON)
+ && !(buttons & B_TERTIARY_MOUSE_BUTTON))
+ rq.btn_no = 1;
+ previous_buttons = buttons;
+
+ rq.x = point.x;
+ rq.y = point.y;
+
+ uint32_t mods = modifiers ();
+
+ rq.modifiers = 0;
+ if (mods & B_SHIFT_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_SHIFT;
+
+ if (mods & B_CONTROL_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_CTRL;
+
+ if (mods & B_COMMAND_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_ALT;
+
+ if (mods & B_OPTION_KEY)
+ rq.modifiers |= HAIKU_MODIFIER_SUPER;
+
+ if (!buttons)
+ SetMouseEventMask (0, 0);
+
+ haiku_write (BUTTON_UP, &rq);
+ }
+};
+
+class EmacsScrollBar : public BScrollBar
+{
+public:
+ void *scroll_bar;
+
+ EmacsScrollBar (int x, int y, int x1, int y1, bool horizontal_p) :
+ BScrollBar (BRect (x, y, x1, y1), NULL, NULL, 0, 0, horizontal_p ?
+ B_HORIZONTAL : B_VERTICAL)
+ {
+ BView *vw = (BView *) this;
+ vw->SetResizingMode (B_FOLLOW_NONE);
+ }
+
+ void
+ MessageReceived (BMessage *msg)
+ {
+ if (msg->what == SCROLL_BAR_UPDATE)
+ {
+ this->SetRange (0, msg->GetInt32 ("emacs:range", 0));
+ this->SetValue (msg->GetInt32 ("emacs:units", 0));
+ }
+
+ BScrollBar::MessageReceived (msg);
+ }
+
+ void
+ ValueChanged (float new_value)
+ {
+ struct haiku_scroll_bar_value_event rq;
+ rq.scroll_bar = scroll_bar;
+ rq.position = new_value;
+
+ haiku_write (SCROLL_BAR_VALUE_EVENT, &rq);
+ }
+
+ void
+ MouseDown (BPoint pt)
+ {
+ struct haiku_scroll_bar_drag_event rq;
+ rq.dragging_p = 1;
+ rq.scroll_bar = scroll_bar;
+
+ haiku_write (SCROLL_BAR_DRAG_EVENT, &rq);
+ BScrollBar::MouseDown (pt);
+ }
+
+ void
+ MouseUp (BPoint pt)
+ {
+ struct haiku_scroll_bar_drag_event rq;
+ rq.dragging_p = 0;
+ rq.scroll_bar = scroll_bar;
+
+ haiku_write (SCROLL_BAR_DRAG_EVENT, &rq);
+ BScrollBar::MouseUp (pt);
+ }
+};
+
+class EmacsTitleMenuItem : public BMenuItem
+{
+public:
+ EmacsTitleMenuItem (const char *str) : BMenuItem (str, NULL)
+ {
+ SetEnabled (0);
+ }
+
+ void
+ DrawContent (void)
+ {
+ BMenu *menu = Menu ();
+
+ menu->PushState ();
+ menu->SetFont (be_bold_font);
+ BView_SetHighColorForVisibleBell (menu, 0);
+ BMenuItem::DrawContent ();
+ menu->PopState ();
+ }
+};
+
+class EmacsMenuItem : public BMenuItem
+{
+public:
+ int menu_bar_id = -1;
+ void *wind_ptr = NULL;
+ char *key = NULL;
+ char *help = NULL;
+
+ EmacsMenuItem (const char *ky,
+ const char *str,
+ const char *help,
+ BMessage *message = NULL) : BMenuItem (str, message)
+ {
+ if (ky)
+ {
+ key = strdup (ky);
+ if (!key)
+ gui_abort ("strdup failed");
+ }
+
+ if (help)
+ {
+ this->help = strdup (help);
+ if (!this->help)
+ gui_abort ("strdup failed");
+ }
+ }
+
+ ~EmacsMenuItem ()
+ {
+ if (key)
+ free (key);
+ if (help)
+ free (help);
+ }
+
+ void
+ DrawContent (void)
+ {
+ BMenu *menu = Menu ();
+
+ BMenuItem::DrawContent ();
+
+ if (key)
+ {
+ BRect r = menu->Frame ();
+ int w = menu->StringWidth (key);
+ menu->MovePenTo (BPoint (r.Width () - w - 4,
+ menu->PenLocation ().y));
+ menu->DrawString (key);
+ }
+ }
+
+ void
+ GetContentSize (float *w, float *h)
+ {
+ BMenuItem::GetContentSize (w, h);
+ if (Menu () && key)
+ *w += 4 + Menu ()->StringWidth (key);
+ }
+
+ void
+ Highlight (bool highlight_p)
+ {
+ struct haiku_menu_bar_help_event rq;
+
+ if (menu_bar_id >= 0)
+ {
+ rq.window = wind_ptr;
+ rq.mb_idx = highlight_p ? menu_bar_id : -1;
+
+ haiku_write (MENU_BAR_HELP_EVENT, &rq);
+ }
+ else if (help)
+ {
+ Menu ()->SetToolTip (highlight_p ? help : NULL);
+ }
+
+ BMenuItem::Highlight (highlight_p);
+ }
+};
+
+class EmacsPopUpMenu : public BPopUpMenu
+{
+public:
+ EmacsPopUpMenu (const char *name) : BPopUpMenu (name, 0)
+ {
+
+ }
+
+ void
+ FrameResized (float w, float h)
+ {
+ Invalidate ();
+ BPopUpMenu::FrameResized (w, h);
+ }
+};
+
+static int32
+start_running_application (void *data)
+{
+ haiku_io_init_in_app_thread ();
+
+ if (!((Emacs *) data)->Lock ())
+ gui_abort ("Failed to lock application");
+
+ ((Emacs *) data)->Run ();
+ ((Emacs *) data)->Unlock ();
+ return 0;
+}
+
+/* Take BITMAP, a reference to a BBitmap, and return a pointer to its
+ data. */
+void *
+BBitmap_data (void *bitmap)
+{
+ return ((BBitmap *) bitmap)->Bits ();
+}
+
+/* Convert bitmap if required, placing the new bitmap in NEW_BITMAP,
+ and return non-null if bitmap was successfully converted. Bitmaps
+ should be freed with `BBitmap_free'. */
+int
+BBitmap_convert (void *_bitmap, void **new_bitmap)
+{
+ BBitmap *bitmap = (BBitmap *) _bitmap;
+ if (bitmap->ColorSpace () == B_RGBA32)
+ return -1;
+ BRect bounds = bitmap->Bounds ();
+ BBitmap *bmp = new (std::nothrow) BBitmap (bounds, B_RGBA32);
+ if (!bmp || bmp->InitCheck () != B_OK)
+ {
+ if (bmp)
+ delete bmp;
+ return 0;
+ }
+ if (bmp->ImportBits (bitmap) != B_OK)
+ {
+ delete bmp;
+ return 0;
+ }
+ *(BBitmap **) new_bitmap = bmp;
+ return 1;
+}
+
+void
+BBitmap_free (void *bitmap)
+{
+ delete (BBitmap *) bitmap;
+}
+
+/* Create new bitmap in RGB32 format, or in GRAY1 if MONO_P is
+ non-zero. */
+void *
+BBitmap_new (int width, int height, int mono_p)
+{
+ BBitmap *bn = new (std::nothrow) BBitmap (BRect (0, 0, width - 1, height - 1),
+ mono_p ? B_GRAY1 : B_RGB32);
+
+ return bn->InitCheck () == B_OK ? (void *) bn : (void *) (delete bn, NULL);
+}
+
+void
+BBitmap_dimensions (void *bitmap, int *left, int *top,
+ int *right, int *bottom,
+ int32_t *bytes_per_row, int *mono_p)
+{
+ BRect rect = ((BBitmap *) bitmap)->Bounds ();
+ *left = rect.left;
+ *top = rect.top;
+ *right = rect.right;
+ *bottom = rect.bottom;
+
+ *bytes_per_row = ((BBitmap *) bitmap)->BytesPerRow ();
+ *mono_p = (((BBitmap *) bitmap)->ColorSpace () == B_GRAY1);
+}
+
+/* Set up an application and return it. If starting the application
+ thread fails, abort Emacs. */
+void *
+BApplication_setup (void)
+{
+ if (be_app)
+ return be_app;
+ thread_id id;
+ Emacs *app;
+
+ app = new Emacs;
+ app->Unlock ();
+ if ((id = spawn_thread (start_running_application, "Emacs app thread",
+ B_DEFAULT_MEDIA_PRIORITY, app)) < 0)
+ gui_abort ("spawn_thread failed");
+
+ resume_thread (id);
+
+ app_thread = id;
+ return app;
+}
+
+/* Set up and return a window with its view put in VIEW. */
+void *
+BWindow_new (void *_view)
+{
+ BWindow *window = new (std::nothrow) EmacsWindow;
+ BView **v = (BView **) _view;
+ if (!window)
+ {
+ *v = NULL;
+ return window;
+ }
+
+ BView *vw = new (std::nothrow) EmacsView;
+ if (!vw)
+ {
+ *v = NULL;
+ window->Lock ();
+ window->Quit ();
+ return NULL;
+ }
+ window->AddChild (vw);
+ *v = vw;
+ return window;
+}
+
+void
+BWindow_quit (void *window)
+{
+ ((BWindow *) window)->Lock ();
+ ((BWindow *) window)->Quit ();
+}
+
+/* Set WINDOW's offset to X, Y. */
+void
+BWindow_set_offset (void *window, int x, int y)
+{
+ BWindow *wn = (BWindow *) window;
+ EmacsWindow *w = dynamic_cast<EmacsWindow *> (wn);
+ if (w)
+ {
+ if (!w->LockLooper ())
+ gui_abort ("Failed to lock window looper setting offset");
+ w->EmacsMoveTo (x, y);
+ w->UnlockLooper ();
+ }
+ else
+ wn->MoveTo (x, y);
+}
+
+/* Iconify WINDOW. */
+void
+BWindow_iconify (void *window)
+{
+ if (((BWindow *) window)->IsHidden ())
+ BWindow_set_visible (window, true);
+ ((BWindow *) window)->Minimize (true);
+}
+
+/* Show or hide WINDOW. */
+void
+BWindow_set_visible (void *window, int visible_p)
+{
+ EmacsWindow *win = (EmacsWindow *) window;
+ if (visible_p)
+ {
+ if (win->IsMinimized ())
+ win->Minimize (false);
+ win->EmacsShow ();
+ }
+ else if (!win->IsHidden ())
+ {
+ if (win->IsMinimized ())
+ win->Minimize (false);
+ win->EmacsHide ();
+ }
+ win->Sync ();
+}
+
+/* Change the title of WINDOW to the multibyte string TITLE. */
+void
+BWindow_retitle (void *window, const char *title)
+{
+ ((BWindow *) window)->SetTitle (title);
+}
+
+/* Resize WINDOW to WIDTH by HEIGHT. */
+void
+BWindow_resize (void *window, int width, int height)
+{
+ ((BWindow *) window)->ResizeTo (width, height);
+}
+
+/* Activate WINDOW, making it the subject of keyboard focus and
+ bringing it to the front of the screen. */
+void
+BWindow_activate (void *window)
+{
+ ((BWindow *) window)->Activate ();
+}
+
+/* Return the pixel dimensions of the main screen in WIDTH and
+ HEIGHT. */
+void
+BScreen_px_dim (int *width, int *height)
+{
+ BScreen screen;
+ if (!screen.IsValid ())
+ gui_abort ("Invalid screen");
+ BRect frame = screen.Frame ();
+
+ *width = frame.right - frame.left;
+ *height = frame.bottom - frame.top;
+}
+
+/* Resize VIEW to WIDTH, HEIGHT. */
+void
+BView_resize_to (void *view, int width, int height)
+{
+ EmacsView *vw = (EmacsView *) view;
+ if (!vw->LockLooper ())
+ gui_abort ("Failed to lock view for resize");
+ vw->ResizeTo (width, height);
+ vw->AfterResize ();
+ vw->UnlockLooper ();
+}
+
+void *
+BCursor_create_default (void)
+{
+ return new BCursor (B_CURSOR_ID_SYSTEM_DEFAULT);
+}
+
+void *
+BCursor_create_modeline (void)
+{
+ return new BCursor (B_CURSOR_ID_CONTEXT_MENU);
+}
+
+void *
+BCursor_from_id (enum haiku_cursor cursor)
+{
+ return new BCursor ((enum BCursorID) cursor);
+}
+
+void *
+BCursor_create_i_beam (void)
+{
+ return new BCursor (B_CURSOR_ID_I_BEAM);
+}
+
+void *
+BCursor_create_progress_cursor (void)
+{
+ return new BCursor (B_CURSOR_ID_PROGRESS);
+}
+
+void *
+BCursor_create_grab (void)
+{
+ return new BCursor (B_CURSOR_ID_GRAB);
+}
+
+void
+BCursor_delete (void *cursor)
+{
+ delete (BCursor *) cursor;
+}
+
+void
+BView_set_view_cursor (void *view, void *cursor)
+{
+ if (!((BView *) view)->LockLooper ())
+ gui_abort ("Failed to lock view setting cursor");
+ ((BView *) view)->SetViewCursor ((BCursor *) cursor);
+ ((BView *) view)->UnlockLooper ();
+}
+
+void
+BWindow_Flush (void *window)
+{
+ ((BWindow *) window)->Flush ();
+}
+
+/* Map the keycode KC, storing the result in CODE and 1 in
+ NON_ASCII_P if it should be used. */
+void
+BMapKey (uint32_t kc, int *non_ascii_p, unsigned *code)
+{
+ if (*code == 10 && kc != 0x42)
+ {
+ *code = XK_Return;
+ *non_ascii_p = 1;
+ return;
+ }
+
+ switch (kc)
+ {
+ default:
+ *non_ascii_p = 0;
+ if (kc < 0xe && kc > 0x1)
+ {
+ *code = XK_F1 + kc - 2;
+ *non_ascii_p = 1;
+ }
+ return;
+ case 0x1e:
+ *code = XK_BackSpace;
+ break;
+ case 0x61:
+ *code = XK_Left;
+ break;
+ case 0x63:
+ *code = XK_Right;
+ break;
+ case 0x57:
+ *code = XK_Up;
+ break;
+ case 0x62:
+ *code = XK_Down;
+ break;
+ case 0x64:
+ *code = XK_Insert;
+ break;
+ case 0x65:
+ *code = XK_Delete;
+ break;
+ case 0x37:
+ *code = XK_Home;
+ break;
+ case 0x58:
+ *code = XK_End;
+ break;
+ case 0x39:
+ *code = XK_Page_Up;
+ break;
+ case 0x5a:
+ *code = XK_Page_Down;
+ break;
+ case 0x1:
+ *code = XK_Escape;
+ break;
+ case 0x68:
+ *code = XK_Menu;
+ break;
+ }
+ *non_ascii_p = 1;
+}
+
+/* Make a scrollbar, attach it to VIEW's window, and return it. */
+void *
+BScrollBar_make_for_view (void *view, int horizontal_p,
+ int x, int y, int x1, int y1,
+ void *scroll_bar_ptr)
+{
+ EmacsScrollBar *sb = new EmacsScrollBar (x, y, x1, y1, horizontal_p);
+ sb->scroll_bar = scroll_bar_ptr;
+
+ BView *vw = (BView *) view;
+ BView *sv = (BView *) sb;
+ if (!vw->LockLooper ())
+ gui_abort ("Failed to lock scrollbar owner");
+ vw->AddChild ((BView *) sb);
+ sv->WindowActivated (vw->Window ()->IsActive ());
+ vw->UnlockLooper ();
+ return sb;
+}
+
+void
+BScrollBar_delete (void *sb)
+{
+ BView *view = (BView *) sb;
+ BView *pr = view->Parent ();
+
+ if (!pr->LockLooper ())
+ gui_abort ("Failed to lock scrollbar parent");
+ pr->RemoveChild (view);
+ pr->UnlockLooper ();
+
+ delete (EmacsScrollBar *) sb;
+}
+
+void
+BView_move_frame (void *view, int x, int y, int x1, int y1)
+{
+ BView *vw = (BView *) view;
+
+ if (!vw->LockLooper ())
+ gui_abort ("Failed to lock view moving frame");
+ vw->MoveTo (x, y);
+ vw->ResizeTo (x1 - x, y1 - y);
+ vw->Flush ();
+ vw->Sync ();
+ vw->UnlockLooper ();
+}
+
+void
+BView_scroll_bar_update (void *sb, int portion, int whole, int position)
+{
+ BScrollBar *bar = (BScrollBar *) sb;
+ BMessage msg = BMessage (SCROLL_BAR_UPDATE);
+ BMessenger mr = BMessenger (bar);
+ msg.AddInt32 ("emacs:range", whole);
+ msg.AddInt32 ("emacs:units", position);
+
+ mr.SendMessage (&msg);
+}
+
+/* Return the default scrollbar size. */
+int
+BScrollBar_default_size (int horizontal_p)
+{
+ return horizontal_p ? B_H_SCROLL_BAR_HEIGHT : B_V_SCROLL_BAR_WIDTH;
+}
+
+/* Invalidate VIEW, causing it to be drawn again. */
+void
+BView_invalidate (void *view)
+{
+ BView *vw = (BView *) view;
+ if (!vw->LockLooper ())
+ gui_abort ("Couldn't lock view while invalidating it");
+ vw->Invalidate ();
+ vw->UnlockLooper ();
+}
+
+/* Lock VIEW in preparation for drawing operations. This should be
+ called before any attempt to draw onto VIEW or to lock it for Cairo
+ drawing. `BView_draw_unlock' should be called afterwards. */
+void
+BView_draw_lock (void *view)
+{
+ EmacsView *vw = (EmacsView *) view;
+ if (vw->looper_locked_count)
+ {
+ vw->looper_locked_count++;
+ return;
+ }
+ BView *v = (BView *) find_appropriate_view_for_draw (vw);
+ if (v != vw)
+ {
+ if (!vw->offscreen_draw_bitmap_1->Lock ())
+ gui_abort ("Failed to lock offscreen bitmap while acquiring draw lock");
+ }
+ else if (!v->LockLooper ())
+ gui_abort ("Failed to lock draw view while acquiring draw lock");
+
+ if (v != vw && !vw->LockLooper ())
+ gui_abort ("Failed to lock view while acquiring draw lock");
+ vw->looper_locked_count++;
+}
+
+void
+BView_draw_unlock (void *view)
+{
+ EmacsView *vw = (EmacsView *) view;
+ if (--vw->looper_locked_count)
+ return;
+
+ BView *v = (BView *) find_appropriate_view_for_draw (view);
+ if (v == vw)
+ vw->UnlockLooper ();
+ else
+ {
+ vw->offscreen_draw_bitmap_1->Unlock ();
+ vw->UnlockLooper ();
+ }
+}
+
+void
+BWindow_center_on_screen (void *window)
+{
+ BWindow *w = (BWindow *) window;
+ w->CenterOnScreen ();
+}
+
+/* Tell VIEW it has been clicked at X by Y. */
+void
+BView_mouse_down (void *view, int x, int y)
+{
+ BView *vw = (BView *) view;
+ if (vw->LockLooper ())
+ {
+ vw->MouseDown (BPoint (x, y));
+ vw->UnlockLooper ();
+ }
+}
+
+/* Tell VIEW the mouse has been released at X by Y. */
+void
+BView_mouse_up (void *view, int x, int y)
+{
+ BView *vw = (BView *) view;
+ if (vw->LockLooper ())
+ {
+ vw->MouseUp (BPoint (x, y));
+ vw->UnlockLooper ();
+ }
+}
+
+/* Tell VIEW that the mouse has moved to Y by Y. */
+void
+BView_mouse_moved (void *view, int x, int y, uint32_t transit)
+{
+ BView *vw = (BView *) view;
+ if (vw->LockLooper ())
+ {
+ vw->MouseMoved (BPoint (x, y), transit, NULL);
+ vw->UnlockLooper ();
+ }
+}
+
+/* Import BITS into BITMAP using the B_GRAY1 colorspace. */
+void
+BBitmap_import_mono_bits (void *bitmap, void *bits, int wd, int h)
+{
+ BBitmap *bmp = (BBitmap *) bitmap;
+ unsigned char *data = (unsigned char *) bmp->Bits ();
+ unsigned short *bts = (unsigned short *) bits;
+
+ for (int i = 0; i < (h * (wd / 8)); i++)
+ {
+ *((unsigned short *) data) = bts[i];
+ data += bmp->BytesPerRow ();
+ }
+}
+
+/* Make a scrollbar at X, Y known to the view VIEW. */
+void
+BView_publish_scroll_bar (void *view, int x, int y, int width, int height)
+{
+ EmacsView *vw = (EmacsView *) view;
+ if (vw->LockLooper ())
+ {
+ vw->sb_region.Include (BRect (x, y, x - 1 + width,
+ y - 1 + height));
+ vw->UnlockLooper ();
+ }
+}
+
+void
+BView_forget_scroll_bar (void *view, int x, int y, int width, int height)
+{
+ EmacsView *vw = (EmacsView *) view;
+ if (vw->LockLooper ())
+ {
+ vw->sb_region.Exclude (BRect (x, y, x - 1 + width,
+ y - 1 + height));
+ vw->UnlockLooper ();
+ }
+}
+
+void
+BView_get_mouse (void *view, int *x, int *y)
+{
+ BPoint l;
+ BView *vw = (BView *) view;
+ if (!vw->LockLooper ())
+ gui_abort ("Failed to lock view in BView_get_mouse");
+ vw->GetMouse (&l, NULL, 1);
+ vw->UnlockLooper ();
+
+ *x = std::lrint (l.x);
+ *y = std::lrint (l.y);
+}
+
+/* Perform an in-place conversion of X and Y from VIEW's coordinate
+ system to its screen's coordinate system. */
+void
+BView_convert_to_screen (void *view, int *x, int *y)
+{
+ BPoint l = BPoint (*x, *y);
+ BView *vw = (BView *) view;
+ if (!vw->LockLooper ())
+ gui_abort ("Failed to lock view in convert_to_screen");
+ vw->ConvertToScreen (&l);
+ vw->UnlockLooper ();
+
+ *x = std::lrint (l.x);
+ *y = std::lrint (l.y);
+}
+
+void
+BView_convert_from_screen (void *view, int *x, int *y)
+{
+ BPoint l = BPoint (*x, *y);
+ BView *vw = (BView *) view;
+ if (!vw->LockLooper ())
+ gui_abort ("Failed to lock view in convert_from_screen");
+ vw->ConvertFromScreen (&l);
+ vw->UnlockLooper ();
+
+ *x = std::lrint (l.x);
+ *y = std::lrint (l.y);
+}
+
+/* Decorate or undecorate WINDOW depending on DECORATE_P. */
+void
+BWindow_change_decoration (void *window, int decorate_p)
+{
+ BWindow *w = (BWindow *) window;
+ if (!w->LockLooper ())
+ gui_abort ("Failed to lock window while changing its decorations");
+ if (decorate_p)
+ w->SetLook (B_TITLED_WINDOW_LOOK);
+ else
+ w->SetLook (B_NO_BORDER_WINDOW_LOOK);
+ w->UnlockLooper ();
+}
+
+/* Decorate WINDOW appropriately for use as a tooltip. */
+void
+BWindow_set_tooltip_decoration (void *window)
+{
+ BWindow *w = (BWindow *) window;
+ if (!w->LockLooper ())
+ gui_abort ("Failed to lock window while setting ttip decoration");
+ w->SetLook (B_BORDERED_WINDOW_LOOK);
+ w->SetFeel (B_FLOATING_APP_WINDOW_FEEL);
+ w->UnlockLooper ();
+}
+
+/* Set B_AVOID_FOCUS on WINDOW if AVOID_FOCUS_P is non-nil, or clear
+ it otherwise. */
+void
+BWindow_set_avoid_focus (void *window, int avoid_focus_p)
+{
+ BWindow *w = (BWindow *) window;
+ if (!w->LockLooper ())
+ gui_abort ("Failed to lock window while setting avoid focus");
+
+ if (!avoid_focus_p)
+ w->SetFlags (w->Flags () & ~B_AVOID_FOCUS);
+ else
+ w->SetFlags (w->Flags () | B_AVOID_FOCUS);
+ w->Sync ();
+ w->UnlockLooper ();
+}
+
+void
+BView_emacs_delete (void *view)
+{
+ EmacsView *vw = (EmacsView *) view;
+ if (!vw->LockLooper ())
+ gui_abort ("Failed to lock view while deleting it");
+ vw->RemoveSelf ();
+ delete vw;
+}
+
+/* Return the current workspace. */
+uint32_t
+haiku_current_workspace (void)
+{
+ return current_workspace ();
+}
+
+/* Return a bitmask consisting of workspaces WINDOW is on. */
+uint32_t
+BWindow_workspaces (void *window)
+{
+ return ((BWindow *) window)->Workspaces ();
+}
+
+/* Create a popup menu. */
+void *
+BPopUpMenu_new (const char *name)
+{
+ BPopUpMenu *menu = new EmacsPopUpMenu (name);
+ menu->SetRadioMode (0);
+ return menu;
+}
+
+/* Add a title item to MENU. These items cannot be highlighted or
+ triggered, and their labels will display as bold text. */
+void
+BMenu_add_title (void *menu, const char *text)
+{
+ EmacsTitleMenuItem *it = new EmacsTitleMenuItem (text);
+ BMenu *mn = (BMenu *) menu;
+ mn->AddItem (it);
+}
+
+/* Add an item to the menu MENU. */
+void
+BMenu_add_item (void *menu, const char *label, void *ptr, bool enabled_p,
+ bool marked_p, bool mbar_p, void *mbw_ptr, const char *key,
+ const char *help)
+{
+ BMenu *m = (BMenu *) menu;
+ BMessage *msg;
+ if (ptr)
+ msg = new BMessage ();
+ EmacsMenuItem *it = new EmacsMenuItem (key, label, help, ptr ? msg : NULL);
+ it->SetTarget (m->Window ());
+ it->SetEnabled (enabled_p);
+ it->SetMarked (marked_p);
+ if (mbar_p)
+ {
+ it->menu_bar_id = (intptr_t) ptr;
+ it->wind_ptr = mbw_ptr;
+ }
+ if (ptr)
+ msg->AddPointer ("menuptr", ptr);
+ m->AddItem (it);
+}
+
+/* Add a separator to the menu MENU. */
+void
+BMenu_add_separator (void *menu)
+{
+ BMenu *m = (BMenu *) menu;
+
+ m->AddSeparatorItem ();
+}
+
+/* Create a submenu and attach it to MENU. */
+void *
+BMenu_new_submenu (void *menu, const char *label, bool enabled_p)
+{
+ BMenu *m = (BMenu *) menu;
+ BMenu *mn = new BMenu (label, B_ITEMS_IN_COLUMN);
+ mn->SetRadioMode (0);
+ BMenuItem *i = new BMenuItem (mn);
+ i->SetEnabled (enabled_p);
+ m->AddItem (i);
+ return mn;
+}
+
+/* Create a submenu that notifies Emacs upon opening. */
+void *
+BMenu_new_menu_bar_submenu (void *menu, const char *label)
+{
+ BMenu *m = (BMenu *) menu;
+ BMenu *mn = new BMenu (label, B_ITEMS_IN_COLUMN);
+ mn->SetRadioMode (0);
+ BMenuItem *i = new BMenuItem (mn);
+ i->SetEnabled (1);
+ m->AddItem (i);
+ return mn;
+}
+
+/* Run MENU, waiting for it to close, and return a pointer to the
+ data of the selected item (if one exists), or NULL. X, Y should
+ be in the screen coordinate system. */
+void *
+BMenu_run (void *menu, int x, int y)
+{
+ BPopUpMenu *mn = (BPopUpMenu *) menu;
+ mn->SetRadioMode (0);
+ BMenuItem *it = mn->Go (BPoint (x, y));
+ if (it)
+ {
+ BMessage *mg = it->Message ();
+ if (mg)
+ return (void *) mg->GetPointer ("menuptr");
+ else
+ return NULL;
+ }
+ return NULL;
+}
+
+/* Delete the entire menu hierarchy of MENU, and then delete MENU
+ itself. */
+void
+BPopUpMenu_delete (void *menu)
+{
+ delete (BPopUpMenu *) menu;
+}
+
+/* Create a menubar, attach it to VIEW, and return it. */
+void *
+BMenuBar_new (void *view)
+{
+ BView *vw = (BView *) view;
+ EmacsMenuBar *bar = new EmacsMenuBar ();
+
+ if (!vw->LockLooper ())
+ gui_abort ("Failed to lock menu bar parent");
+ vw->AddChild ((BView *) bar);
+ vw->UnlockLooper ();
+
+ return bar;
+}
+
+/* Delete MENUBAR along with all subitems. */
+void
+BMenuBar_delete (void *menubar)
+{
+ BView *vw = (BView *) menubar;
+ BView *p = vw->Parent ();
+ if (!p->LockLooper ())
+ gui_abort ("Failed to lock menu bar parent while removing menubar");
+ vw->RemoveSelf ();
+ p->UnlockLooper ();
+ delete vw;
+}
+
+/* Delete all items from MENU. */
+void
+BMenu_delete_all (void *menu)
+{
+ BMenu *mn = (BMenu *) menu;
+ mn->RemoveItems (0, mn->CountItems (), true);
+}
+
+/* Delete COUNT items from MENU starting from START. */
+void
+BMenu_delete_from (void *menu, int start, int count)
+{
+ BMenu *mn = (BMenu *) menu;
+ mn->RemoveItems (start, count, true);
+}
+
+/* Count items in menu MENU. */
+int
+BMenu_count_items (void *menu)
+{
+ return ((BMenu *) menu)->CountItems ();
+}
+
+/* Find the item in MENU at IDX. */
+void *
+BMenu_item_at (void *menu, int idx)
+{
+ return ((BMenu *) menu)->ItemAt (idx);
+}
+
+/* Set ITEM's label to LABEL. */
+void
+BMenu_item_set_label (void *item, const char *label)
+{
+ ((BMenuItem *) item)->SetLabel (label);
+}
+
+/* Get ITEM's menu. */
+void *
+BMenu_item_get_menu (void *item)
+{
+ return ((BMenuItem *) item)->Submenu ();
+}
+
+/* Emit a beep noise. */
+void
+haiku_ring_bell (void)
+{
+ beep ();
+}
+
+/* Create a BAlert with TEXT. */
+void *
+BAlert_new (const char *text, enum haiku_alert_type type)
+{
+ return new BAlert (NULL, text, NULL, NULL, NULL, B_WIDTH_AS_USUAL,
+ (enum alert_type) type);
+}
+
+/* Add a button to ALERT and return the button. */
+void *
+BAlert_add_button (void *alert, const char *text)
+{
+ BAlert *al = (BAlert *) alert;
+ al->AddButton (text);
+ return al->ButtonAt (al->CountButtons () - 1);
+}
+
+/* Run ALERT, returning the number of the button that was selected,
+ or -1 if no button was selected before the alert was closed. */
+int32_t
+BAlert_go (void *alert)
+{
+ return ((BAlert *) alert)->Go ();
+}
+
+/* Enable or disable BUTTON depending on ENABLED_P. */
+void
+BButton_set_enabled (void *button, int enabled_p)
+{
+ ((BButton *) button)->SetEnabled (enabled_p);
+}
+
+/* Set VIEW's tooltip to TOOLTIP. */
+void
+BView_set_tooltip (void *view, const char *tooltip)
+{
+ ((BView *) view)->SetToolTip (tooltip);
+}
+
+/* Set VIEW's tooltip to a sticky tooltip at X by Y. */
+void
+BView_set_and_show_sticky_tooltip (void *view, const char *tooltip,
+ int x, int y)
+{
+ BToolTip *tip;
+ BView *vw = (BView *) view;
+ if (!vw->LockLooper ())
+ gui_abort ("Failed to lock view while showing sticky tooltip");
+ vw->SetToolTip (tooltip);
+ tip = vw->ToolTip ();
+ BPoint pt;
+ EmacsView *ev = dynamic_cast<EmacsView *> (vw);
+ if (ev)
+ ev->tt_absl_pos = BPoint (x, y);
+
+ vw->GetMouse (&pt, NULL, 1);
+ pt.x -= x;
+ pt.y -= y;
+
+ pt.x = -pt.x;
+ pt.y = -pt.y;
+
+ tip->SetMouseRelativeLocation (pt);
+ tip->SetSticky (1);
+ vw->ShowToolTip (tip);
+ vw->UnlockLooper ();
+}
+
+/* Delete ALERT. */
+void
+BAlert_delete (void *alert)
+{
+ delete (BAlert *) alert;
+}
+
+/* Place the resolution of the monitor in DPI in RSSX and RSSY. */
+void
+BScreen_res (double *rrsx, double *rrsy)
+{
+ BScreen s (B_MAIN_SCREEN_ID);
+ if (!s.IsValid ())
+ gui_abort ("Invalid screen for resolution checks");
+ monitor_info i;
+
+ if (s.GetMonitorInfo (&i) == B_OK)
+ {
+ *rrsx = (double) i.width / (double) 2.54;
+ *rrsy = (double) i.height / (double) 2.54;
+ }
+ else
+ {
+ *rrsx = 72.27;
+ *rrsy = 72.27;
+ }
+}
+
+/* Add WINDOW to OTHER_WINDOW's subset and parent it to
+ OTHER_WINDOW. */
+void
+EmacsWindow_parent_to (void *window, void *other_window)
+{
+ EmacsWindow *w = (EmacsWindow *) window;
+ if (!w->LockLooper ())
+ gui_abort ("Failed to lock window while parenting");
+ w->ParentTo ((EmacsWindow *) other_window);
+ w->UnlockLooper ();
+}
+
+void
+EmacsWindow_unparent (void *window)
+{
+ EmacsWindow *w = (EmacsWindow *) window;
+ if (!w->LockLooper ())
+ gui_abort ("Failed to lock window while unparenting");
+ w->UnparentAndUnlink ();
+ w->UnlockLooper ();
+}
+
+/* Place text describing the current version of Haiku in VERSION,
+ which should be a buffer LEN bytes wide. */
+void
+be_get_version_string (char *version, int len)
+{
+ std::strncpy (version, "Unknown Haiku release", len - 1);
+ BPath path;
+ if (find_directory (B_BEOS_LIB_DIRECTORY, &path) == B_OK)
+ {
+ path.Append ("libbe.so");
+
+ BAppFileInfo appFileInfo;
+ version_info versionInfo;
+ BFile file;
+ if (file.SetTo (path.Path (), B_READ_ONLY) == B_OK
+ && appFileInfo.SetTo (&file) == B_OK
+ && appFileInfo.GetVersionInfo (&versionInfo,
+ B_APP_VERSION_KIND) == B_OK
+ && versionInfo.short_info[0] != '\0')
+ std::strncpy (version, versionInfo.short_info, len - 1);
+ }
+}
+
+/* Return the amount of color planes in the current display. */
+int
+be_get_display_planes (void)
+{
+ color_space space = dpy_color_space;
+ if (space == B_NO_COLOR_SPACE)
+ {
+ BScreen screen; /* This is actually a very slow operation. */
+ if (!screen.IsValid ())
+ gui_abort ("Invalid screen");
+ space = dpy_color_space = screen.ColorSpace ();
+ }
+
+ if (space == B_RGB32 || space == B_RGB24)
+ return 24;
+ if (space == B_RGB16)
+ return 16;
+ if (space == B_RGB15)
+ return 15;
+ if (space == B_CMAP8)
+ return 8;
+
+ gui_abort ("Bad colorspace for screen");
+ /* https://www.haiku-os.org/docs/api/classBScreen.html
+ says a valid screen can't be anything else. */
+ return -1;
+}
+
+/* Return the amount of colors the display can handle. */
+int
+be_get_display_color_cells (void)
+{
+ color_space space = dpy_color_space;
+ if (space == B_NO_COLOR_SPACE)
+ {
+ BScreen screen;
+ if (!screen.IsValid ())
+ gui_abort ("Invalid screen");
+ space = dpy_color_space = screen.ColorSpace ();
+ }
+
+ if (space == B_RGB32 || space == B_RGB24)
+ return 1677216;
+ if (space == B_RGB16)
+ return 65536;
+ if (space == B_RGB15)
+ return 32768;
+ if (space == B_CMAP8)
+ return 256;
+
+ gui_abort ("Bad colorspace for screen");
+ return -1;
+}
+
+/* Warp the pointer to X by Y. */
+void
+be_warp_pointer (int x, int y)
+{
+ /* We're not supposed to use the following function without a
+ BWindowScreen object, but in Haiku nothing actually prevents us
+ from doing so. */
+
+ set_mouse_position (x, y);
+}
+
+/* Update the position of CHILD in WINDOW without actually moving
+ it. */
+void
+EmacsWindow_move_weak_child (void *window, void *child, int xoff, int yoff)
+{
+ EmacsWindow *w = (EmacsWindow *) window;
+ EmacsWindow *c = (EmacsWindow *) child;
+
+ if (!w->LockLooper ())
+ gui_abort ("Couldn't lock window for weak move");
+ w->MoveChild (c, xoff, yoff, 1);
+ w->UnlockLooper ();
+}
+
+/* Find an appropriate view to draw onto. If VW is double-buffered,
+ this will be the view used for double buffering instead of VW
+ itself. */
+void *
+find_appropriate_view_for_draw (void *vw)
+{
+ BView *v = (BView *) vw;
+ EmacsView *ev = dynamic_cast<EmacsView *>(v);
+ if (!ev)
+ return v;
+
+ return ev->offscreen_draw_view ? ev->offscreen_draw_view : vw;
+}
+
+/* Set up double buffering for VW. */
+void
+EmacsView_set_up_double_buffering (void *vw)
+{
+ EmacsView *view = (EmacsView *) vw;
+ if (!view->LockLooper ())
+ gui_abort ("Couldn't lock view while setting up double buffering");
+ if (view->offscreen_draw_view)
+ {
+ view->UnlockLooper ();
+ return;
+ }
+ view->SetUpDoubleBuffering ();
+ view->UnlockLooper ();
+}
+
+/* Flip and invalidate the view VW. */
+void
+EmacsView_flip_and_blit (void *vw)
+{
+ EmacsView *view = (EmacsView *) vw;
+ if (!view->offscreen_draw_view)
+ return;
+ if (!view->LockLooper ())
+ gui_abort ("Couldn't lock view in flip_and_blit");
+ view->FlipBuffers ();
+ view->UnlockLooper ();
+}
+
+/* Disable double buffering for VW. */
+void
+EmacsView_disable_double_buffering (void *vw)
+{
+ EmacsView *view = (EmacsView *) vw;
+ if (!view->LockLooper ())
+ gui_abort ("Couldn't lock view tearing down double buffering");
+ view->TearDownDoubleBuffering ();
+ view->UnlockLooper ();
+}
+
+/* Return non-0 if VW is double-buffered. */
+int
+EmacsView_double_buffered_p (void *vw)
+{
+ EmacsView *view = (EmacsView *) vw;
+ if (!view->LockLooper ())
+ gui_abort ("Couldn't lock view testing double buffering status");
+ int db_p = !!view->offscreen_draw_view;
+ view->UnlockLooper ();
+ return db_p;
+}
+
+struct popup_file_dialog_data
+{
+ BMessage *msg;
+ BFilePanel *panel;
+ BEntry *entry;
+};
+
+static void
+unwind_popup_file_dialog (void *ptr)
+{
+ struct popup_file_dialog_data *data =
+ (struct popup_file_dialog_data *) ptr;
+ BFilePanel *panel = data->panel;
+ delete panel;
+ delete data->entry;
+ delete data->msg;
+}
+
+static void
+be_popup_file_dialog_safe_set_target (BFilePanel *dialog, BWindow *window)
+{
+ dialog->SetTarget (BMessenger (window));
+}
+
+/* Popup a file dialog. */
+char *
+be_popup_file_dialog (int open_p, const char *default_dir, int must_match_p, int dir_only_p,
+ void *window, const char *save_text, const char *prompt,
+ void (*block_input_function) (void),
+ void (*unblock_input_function) (void))
+{
+ ptrdiff_t idx = c_specpdl_idx_from_cxx ();
+ /* setjmp/longjmp is UB with automatic objects. */
+ block_input_function ();
+ BWindow *w = (BWindow *) window;
+ uint32_t mode = dir_only_p ? B_DIRECTORY_NODE : B_FILE_NODE | B_DIRECTORY_NODE;
+ BEntry *path = new BEntry;
+ BMessage *msg = new BMessage ('FPSE');
+ BFilePanel *panel = new BFilePanel (open_p ? B_OPEN_PANEL : B_SAVE_PANEL,
+ NULL, NULL, mode);
+ unblock_input_function ();
+
+ struct popup_file_dialog_data dat;
+ dat.entry = path;
+ dat.msg = msg;
+ dat.panel = panel;
+
+ record_c_unwind_protect_from_cxx (unwind_popup_file_dialog, &dat);
+ if (default_dir)
+ {
+ if (path->SetTo (default_dir, 0) != B_OK)
+ default_dir = NULL;
+ }
+
+ panel->SetMessage (msg);
+ if (default_dir)
+ panel->SetPanelDirectory (path);
+ if (save_text)
+ panel->SetSaveText (save_text);
+ panel->SetHideWhenDone (0);
+ panel->Window ()->SetTitle (prompt);
+ be_popup_file_dialog_safe_set_target (panel, w);
+
+ panel->Show ();
+ panel->Window ()->Show ();
+
+ void *buf = alloca (200);
+ while (1)
+ {
+ enum haiku_event_type type;
+ char *ptr = NULL;
+
+ if (!haiku_read_with_timeout (&type, buf, 200, 100000))
+ {
+ if (type != FILE_PANEL_EVENT)
+ haiku_write (type, buf);
+ else if (!ptr)
+ ptr = (char *) ((struct haiku_file_panel_event *) buf)->ptr;
+ }
+
+ ssize_t b_s;
+ haiku_read_size (&b_s);
+ if (!b_s || b_s == -1 || ptr || panel->Window ()->IsHidden ())
+ {
+ c_unbind_to_nil_from_cxx (idx);
+ return ptr;
+ }
+ }
+}
+
+void
+be_app_quit (void)
+{
+ if (be_app)
+ {
+ while (!be_app->Lock ());
+ be_app->Quit ();
+ }
+}
+
+/* Temporarily fill VIEW with COLOR. */
+void
+EmacsView_do_visible_bell (void *view, uint32_t color)
+{
+ EmacsView *vw = (EmacsView *) view;
+ vw->DoVisibleBell (color);
+}
+
+/* Zoom WINDOW. */
+void
+BWindow_zoom (void *window)
+{
+ BWindow *w = (BWindow *) window;
+ w->Zoom ();
+}
+
+/* Make WINDOW fullscreen if FULLSCREEN_P. */
+void
+EmacsWindow_make_fullscreen (void *window, int fullscreen_p)
+{
+ EmacsWindow *w = (EmacsWindow *) window;
+ w->MakeFullscreen (fullscreen_p);
+}
+
+/* Unzoom (maximize) WINDOW. */
+void
+EmacsWindow_unzoom (void *window)
+{
+ EmacsWindow *w = (EmacsWindow *) window;
+ w->UnZoom ();
+}
+
+/* Move the pointer into MBAR and start tracking. */
+void
+BMenuBar_start_tracking (void *mbar)
+{
+ EmacsMenuBar *mb = (EmacsMenuBar *) mbar;
+ if (!mb->LockLooper ())
+ gui_abort ("Couldn't lock menubar");
+ BRect frame = mb->Frame ();
+ BPoint pt = frame.LeftTop ();
+ BPoint l = pt;
+ mb->Parent ()->ConvertToScreen (&pt);
+ set_mouse_position (pt.x, pt.y);
+ mb->MouseDown (l);
+ mb->UnlockLooper ();
+}
+
+#ifdef HAVE_NATIVE_IMAGE_API
+int
+be_can_translate_type_to_bitmap_p (const char *mime)
+{
+ BTranslatorRoster *r = BTranslatorRoster::Default ();
+ translator_id *ids;
+ int32 id_len;
+
+ if (r->GetAllTranslators (&ids, &id_len) != B_OK)
+ return 0;
+
+ int found_in = 0;
+ int found_out = 0;
+
+ for (int i = 0; i < id_len; ++i)
+ {
+ found_in = 0;
+ found_out = 0;
+ const translation_format *i_fmts;
+ const translation_format *o_fmts;
+
+ int32 i_count, o_count;
+
+ if (r->GetInputFormats (ids[i], &i_fmts, &i_count) != B_OK)
+ continue;
+
+ if (r->GetOutputFormats (ids[i], &o_fmts, &o_count) != B_OK)
+ continue;
+
+ for (int x = 0; x < i_count; ++x)
+ {
+ if (!strcmp (i_fmts[x].MIME, mime))
+ {
+ found_in = 1;
+ break;
+ }
+ }
+
+ for (int x = 0; x < i_count; ++x)
+ {
+ if (!strcmp (o_fmts[x].MIME, "image/x-be-bitmap") ||
+ !strcmp (o_fmts[x].MIME, "image/x-vnd.Be-bitmap"))
+ {
+ found_out = 1;
+ break;
+ }
+ }
+
+ if (found_in && found_out)
+ break;
+ }
+
+ delete [] ids;
+
+ return found_in && found_out;
+}
+
+void *
+be_translate_bitmap_from_file_name (const char *filename)
+{
+ BBitmap *bm = BTranslationUtils::GetBitmap (filename);
+ return bm;
+}
+
+void *
+be_translate_bitmap_from_memory (const void *buf, size_t bytes)
+{
+ BMemoryIO io (buf, bytes);
+ BBitmap *bm = BTranslationUtils::GetBitmap (&io);
+ return bm;
+}
+#endif
+
+/* Return the size of BITMAP's data, in bytes. */
+size_t
+BBitmap_bytes_length (void *bitmap)
+{
+ BBitmap *bm = (BBitmap *) bitmap;
+ return bm->BitsLength ();
+}
+
+/* Show VIEW's tooltip. */
+void
+BView_show_tooltip (void *view)
+{
+ BView *vw = (BView *) view;
+ if (vw->LockLooper ())
+ {
+ vw->ShowToolTip (vw->ToolTip ());
+ vw->UnlockLooper ();
+ }
+}
+
+
+#ifdef USE_BE_CAIRO
+/* Return VIEW's cairo surface. */
+cairo_surface_t *
+EmacsView_cairo_surface (void *view)
+{
+ EmacsView *vw = (EmacsView *) view;
+ EmacsWindow *wn = (EmacsWindow *) vw->Window ();
+ return vw->cr_surface ? vw->cr_surface : wn->cr_surface;
+}
+
+/* Transfer each clip rectangle in VIEW to the cairo context
+ CTX. */
+void
+BView_cr_dump_clipping (void *view, cairo_t *ctx)
+{
+ BView *vw = (BView *) find_appropriate_view_for_draw (view);
+ BRegion cr;
+ vw->GetClippingRegion (&cr);
+
+ for (int i = 0; i < cr.CountRects (); ++i)
+ {
+ BRect r = cr.RectAt (i);
+ cairo_rectangle (ctx, r.left, r.top, r.Width () + 1,
+ r.Height () + 1);
+ }
+
+ cairo_clip (ctx);
+}
+
+/* Lock WINDOW in preparation for drawing using Cairo. */
+void
+EmacsWindow_begin_cr_critical_section (void *window)
+{
+ EmacsWindow *w = (EmacsWindow *) window;
+ if (!w->surface_lock.Lock ())
+ gui_abort ("Couldn't lock cairo surface");
+
+ BView *vw = (BView *) w->FindView ("Emacs");
+ EmacsView *ev = dynamic_cast <EmacsView *> (vw);
+ if (ev && !ev->cr_surface_lock.Lock ())
+ gui_abort ("Couldn't lock view cairo surface");
+}
+
+/* Unlock WINDOW in preparation for drawing using Cairo. */
+void
+EmacsWindow_end_cr_critical_section (void *window)
+{
+ EmacsWindow *w = (EmacsWindow *) window;
+ w->surface_lock.Unlock ();
+ BView *vw = (BView *) w->FindView ("Emacs");
+ EmacsView *ev = dynamic_cast <EmacsView *> (vw);
+ if (ev)
+ ev->cr_surface_lock.Unlock ();
+}
+#endif
+
+/* Get the width of STR in the plain font. */
+int
+be_string_width_with_plain_font (const char *str)
+{
+ return be_plain_font->StringWidth (str);
+}
+
+/* Get the ascent + descent of the plain font. */
+int
+be_plain_font_height (void)
+{
+ struct font_height fheight;
+ be_plain_font->GetHeight (&fheight);
+
+ return fheight.ascent + fheight.descent;
+}
+
+/* Return the number of physical displays connected. */
+int
+be_get_display_screens (void)
+{
+ int count = 1;
+ BScreen scr;
+
+ if (!scr.IsValid ())
+ gui_abort ("Main screen vanished!");
+ while (scr.SetToNext () == B_OK && scr.IsValid ())
+ ++count;
+
+ return count;
+}
+
+/* Set the minimum width the user can resize WINDOW to. */
+void
+BWindow_set_min_size (void *window, int width, int height)
+{
+ BWindow *w = (BWindow *) window;
+
+ if (!w->LockLooper ())
+ gui_abort ("Failed to lock window looper setting min size");
+ w->SetSizeLimits (width, -1, height, -1);
+ w->UnlockLooper ();
+}
+
+/* Set the alignment of WINDOW's dimensions. */
+void
+BWindow_set_size_alignment (void *window, int align_width, int align_height)
+{
+ BWindow *w = (BWindow *) window;
+
+ if (!w->LockLooper ())
+ gui_abort ("Failed to lock window looper setting alignment");
+#if 0 /* Haiku does not currently implement SetWindowAlignment. */
+ if (w->SetWindowAlignment (B_PIXEL_ALIGNMENT, -1, -1, align_width,
+ align_width, -1, -1, align_height,
+ align_height) != B_NO_ERROR)
+ gui_abort ("Invalid pixel alignment");
+#endif
+ w->UnlockLooper ();
+}
diff --git a/src/haiku_support.h b/src/haiku_support.h
new file mode 100644
index 00000000000..9f5f3c77e3d
--- /dev/null
+++ b/src/haiku_support.h
@@ -0,0 +1,869 @@
+/* Haiku window system support. Hey Emacs, this is -*- C++ -*-
+ Copyright (C) 2021 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/>. */
+
+#ifndef _HAIKU_SUPPORT_H
+#define _HAIKU_SUPPORT_H
+
+#include <stdint.h>
+
+#ifdef HAVE_FREETYPE
+#include <ft2build.h>
+#include <fontconfig/fontconfig.h>
+#include FT_FREETYPE_H
+#include FT_SIZES_H
+#endif
+
+#ifdef USE_BE_CAIRO
+#include <cairo.h>
+#endif
+
+enum haiku_cursor
+ {
+ CURSOR_ID_NO_CURSOR = 12,
+ CURSOR_ID_RESIZE_NORTH = 15,
+ CURSOR_ID_RESIZE_EAST = 16,
+ CURSOR_ID_RESIZE_SOUTH = 17,
+ CURSOR_ID_RESIZE_WEST = 18,
+ CURSOR_ID_RESIZE_NORTH_EAST = 19,
+ CURSOR_ID_RESIZE_NORTH_WEST = 20,
+ CURSOR_ID_RESIZE_SOUTH_EAST = 21,
+ CURSOR_ID_RESIZE_SOUTH_WEST = 22,
+ CURSOR_ID_RESIZE_NORTH_SOUTH = 23,
+ CURSOR_ID_RESIZE_EAST_WEST = 24,
+ CURSOR_ID_RESIZE_NORTH_EAST_SOUTH_WEST = 25,
+ CURSOR_ID_RESIZE_NORTH_WEST_SOUTH_EAST = 26
+ };
+
+enum haiku_alert_type
+ {
+ HAIKU_EMPTY_ALERT = 0,
+ HAIKU_INFO_ALERT,
+ HAIKU_IDEA_ALERT,
+ HAIKU_WARNING_ALERT,
+ HAIKU_STOP_ALERT
+ };
+
+enum haiku_event_type
+ {
+ QUIT_REQUESTED,
+ FRAME_RESIZED,
+ FRAME_EXPOSED,
+ KEY_DOWN,
+ KEY_UP,
+ ACTIVATION,
+ MOUSE_MOTION,
+ BUTTON_DOWN,
+ BUTTON_UP,
+ ICONIFICATION,
+ MOVE_EVENT,
+ SCROLL_BAR_VALUE_EVENT,
+ SCROLL_BAR_DRAG_EVENT,
+ WHEEL_MOVE_EVENT,
+ MENU_BAR_RESIZE,
+ MENU_BAR_OPEN,
+ MENU_BAR_SELECT_EVENT,
+ MENU_BAR_CLOSE,
+ FILE_PANEL_EVENT,
+ MENU_BAR_HELP_EVENT,
+ ZOOM_EVENT,
+ REFS_EVENT,
+ APP_QUIT_REQUESTED_EVENT
+ };
+
+struct haiku_quit_requested_event
+{
+ void *window;
+};
+
+struct haiku_resize_event
+{
+ void *window;
+ float px_heightf;
+ float px_widthf;
+};
+
+struct haiku_expose_event
+{
+ void *window;
+ int x;
+ int y;
+ int width;
+ int height;
+};
+
+struct haiku_refs_event
+{
+ void *window;
+ int x, y;
+ /* Free this with free! */
+ char *ref;
+};
+
+struct haiku_app_quit_requested_event
+{
+ char dummy;
+};
+
+#define HAIKU_MODIFIER_ALT (1)
+#define HAIKU_MODIFIER_CTRL (1 << 1)
+#define HAIKU_MODIFIER_SHIFT (1 << 2)
+#define HAIKU_MODIFIER_SUPER (1 << 3)
+
+struct haiku_key_event
+{
+ void *window;
+ int modifiers;
+ uint32_t mb_char;
+ uint32_t unraw_mb_char;
+ short kc;
+};
+
+struct haiku_activation_event
+{
+ void *window;
+ int activated_p;
+};
+
+struct haiku_mouse_motion_event
+{
+ void *window;
+ bool just_exited_p;
+ int x;
+ int y;
+ uint32_t be_code;
+};
+
+struct haiku_button_event
+{
+ void *window;
+ int btn_no;
+ int modifiers;
+ int x;
+ int y;
+};
+
+struct haiku_iconification_event
+{
+ void *window;
+ int iconified_p;
+};
+
+struct haiku_move_event
+{
+ void *window;
+ int x;
+ int y;
+};
+
+struct haiku_wheel_move_event
+{
+ void *window;
+ int modifiers;
+ float delta_x;
+ float delta_y;
+};
+
+struct haiku_menu_bar_select_event
+{
+ void *window;
+ void *ptr;
+};
+
+struct haiku_file_panel_event
+{
+ void *ptr;
+};
+
+struct haiku_menu_bar_help_event
+{
+ void *window;
+ int mb_idx;
+};
+
+struct haiku_zoom_event
+{
+ void *window;
+ int x;
+ int y;
+ int width;
+ int height;
+};
+
+#define FSPEC_FAMILY 1
+#define FSPEC_STYLE (1 << 1)
+#define FSPEC_SLANT (1 << 2)
+#define FSPEC_WEIGHT (1 << 3)
+#define FSPEC_SPACING (1 << 4)
+#define FSPEC_WANTED (1 << 5)
+#define FSPEC_NEED_ONE_OF (1 << 6)
+#define FSPEC_WIDTH (1 << 7)
+#define FSPEC_LANGUAGE (1 << 8)
+
+typedef char haiku_font_family_or_style[64];
+
+enum haiku_font_slant
+ {
+ NO_SLANT = -1,
+ SLANT_OBLIQUE,
+ SLANT_REGULAR,
+ SLANT_ITALIC
+ };
+
+enum haiku_font_width
+ {
+ NO_WIDTH = -1,
+ ULTRA_CONDENSED,
+ EXTRA_CONDENSED,
+ CONDENSED,
+ SEMI_CONDENSED,
+ NORMAL_WIDTH,
+ SEMI_EXPANDED,
+ EXPANDED,
+ EXTRA_EXPANDED,
+ ULTRA_EXPANDED
+ };
+
+enum haiku_font_language
+ {
+ LANGUAGE_CN,
+ LANGUAGE_KO,
+ LANGUAGE_JP,
+ MAX_LANGUAGE /* This isn't a language. */
+ };
+
+struct haiku_font_pattern
+{
+ int specified;
+ struct haiku_font_pattern *next;
+ /* The next two fields are only temporarily used during the font
+ discovery process! Do not rely on them being correct outside
+ BFont_find. */
+ struct haiku_font_pattern *last;
+ struct haiku_font_pattern *next_family;
+ haiku_font_family_or_style family;
+ haiku_font_family_or_style style;
+ int weight;
+ int mono_spacing_p;
+ int want_chars_len;
+ int need_one_of_len;
+ enum haiku_font_slant slant;
+ enum haiku_font_width width;
+ enum haiku_font_language language;
+ uint32_t *wanted_chars;
+ uint32_t *need_one_of;
+
+ int oblique_seen_p;
+};
+
+struct haiku_scroll_bar_value_event
+{
+ void *scroll_bar;
+ int position;
+};
+
+struct haiku_scroll_bar_drag_event
+{
+ void *scroll_bar;
+ int dragging_p;
+};
+
+struct haiku_menu_bar_resize_event
+{
+ void *window;
+ int width;
+ int height;
+};
+
+struct haiku_menu_bar_state_event
+{
+ void *window;
+};
+
+#define HAIKU_THIN 0
+#define HAIKU_ULTRALIGHT 20
+#define HAIKU_EXTRALIGHT 40
+#define HAIKU_LIGHT 50
+#define HAIKU_SEMI_LIGHT 75
+#define HAIKU_REGULAR 100
+#define HAIKU_SEMI_BOLD 180
+#define HAIKU_BOLD 200
+#define HAIKU_EXTRA_BOLD 205
+#define HAIKU_ULTRA_BOLD 210
+#define HAIKU_BOOK 400
+#define HAIKU_HEAVY 800
+#define HAIKU_ULTRA_HEAVY 900
+#define HAIKU_BLACK 1000
+#define HAIKU_MEDIUM 2000
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <pthread.h>
+#include <OS.h>
+
+#ifdef __cplusplus
+ typedef void *haiku;
+
+ extern void
+ haiku_put_pixel (haiku bitmap, int x, int y, unsigned long pixel);
+
+ extern unsigned long
+ haiku_get_pixel (haiku bitmap, int x, int y);
+#endif
+
+ extern port_id port_application_to_emacs;
+
+ extern void haiku_io_init (void);
+ extern void haiku_io_init_in_app_thread (void);
+
+ extern void
+ haiku_read_size (ssize_t *len);
+
+ extern int
+ haiku_read (enum haiku_event_type *type, void *buf, ssize_t len);
+
+ extern int
+ haiku_read_with_timeout (enum haiku_event_type *type, void *buf, ssize_t len,
+ time_t timeout);
+
+ extern int
+ haiku_write (enum haiku_event_type type, void *buf);
+
+ extern int
+ haiku_write_without_signal (enum haiku_event_type type, void *buf);
+
+ extern void
+ rgb_color_hsl (uint32_t rgb, double *h, double *s, double *l);
+
+ extern void
+ hsl_color_rgb (double h, double s, double l, uint32_t *rgb);
+
+ extern void *
+ BBitmap_new (int width, int height, int mono_p);
+
+ extern void *
+ BBitmap_data (void *bitmap);
+
+ extern int
+ BBitmap_convert (void *bitmap, void **new_bitmap);
+
+ extern void
+ BBitmap_free (void *bitmap);
+
+ extern void
+ BBitmap_dimensions (void *bitmap, int *left, int *top,
+ int *right, int *bottom, int32_t *bytes_per_row,
+ int *mono_p);
+
+ extern void *
+ BApplication_setup (void);
+
+ extern void *
+ BWindow_new (void *view);
+
+ extern void
+ BWindow_quit (void *window);
+
+ extern void
+ BWindow_set_offset (void *window, int x, int y);
+
+ extern void
+ BWindow_iconify (void *window);
+
+ extern void
+ BWindow_set_visible (void *window, int visible_p);
+
+ extern void
+ BFont_close (void *font);
+
+ extern void
+ BFont_dat (void *font, int *px_size, int *min_width, int *max_width,
+ int *avg_width, int *height, int *space_width, int *ascent,
+ int *descent, int *underline_position, int *underline_thickness);
+
+ extern int
+ BFont_have_char_p (void *font, int32_t chr);
+
+ extern int
+ BFont_have_char_block (void *font, int32_t beg, int32_t end);
+
+ extern void
+ BFont_char_bounds (void *font, const char *mb_str, int *advance,
+ int *lb, int *rb);
+
+ extern void
+ BFont_nchar_bounds (void *font, const char *mb_str, int *advance,
+ int *lb, int *rb, int32_t n);
+
+ extern void
+ BWindow_retitle (void *window, const char *title);
+
+ extern void
+ BWindow_resize (void *window, int width, int height);
+
+ extern void
+ BWindow_activate (void *window);
+
+ extern void
+ BView_StartClip (void *view);
+
+ extern void
+ BView_EndClip (void *view);
+
+ extern void
+ BView_SetHighColor (void *view, uint32_t color);
+
+ extern void
+ BView_SetHighColorForVisibleBell (void *view, uint32_t color);
+
+ extern void
+ BView_FillRectangleForVisibleBell (void *view, int x, int y, int width,
+ int height);
+
+ extern void
+ BView_SetLowColor (void *view, uint32_t color);
+
+ extern void
+ BView_SetPenSize (void *view, int u);
+
+ extern void
+ BView_SetFont (void *view, void *font);
+
+ extern void
+ BView_MovePenTo (void *view, int x, int y);
+
+ extern void
+ BView_DrawString (void *view, const char *chr, ptrdiff_t len);
+
+ extern void
+ BView_DrawChar (void *view, char chr);
+
+ extern void
+ BView_FillRectangle (void *view, int x, int y, int width, int height);
+
+ extern void
+ BView_FillRectangleAbs (void *view, int x, int y, int x1, int y1);
+
+ extern void
+ BView_FillTriangle (void *view, int x1, int y1,
+ int x2, int y2, int x3, int y3);
+
+ extern void
+ BView_StrokeRectangle (void *view, int x, int y, int width, int height);
+
+ extern void
+ BView_SetViewColor (void *view, uint32_t color);
+
+ extern void
+ BView_ClipToRect (void *view, int x, int y, int width, int height);
+
+ extern void
+ BView_ClipToInverseRect (void *view, int x, int y, int width, int height);
+
+ extern void
+ BView_StrokeLine (void *view, int sx, int sy, int tx, int ty);
+
+ extern void
+ BView_CopyBits (void *view, int x, int y, int width, int height,
+ int tox, int toy, int towidth, int toheight);
+
+ extern void
+ BView_DrawBitmap (void *view, void *bitmap, int x, int y,
+ int width, int height, int vx, int vy, int vwidth,
+ int vheight);
+
+ extern void
+ BView_DrawBitmapWithEraseOp (void *view, void *bitmap, int x,
+ int y, int width, int height);
+
+ extern void
+ BView_DrawMask (void *src, void *view,
+ int x, int y, int width, int height,
+ int vx, int vy, int vwidth, int vheight,
+ uint32_t color);
+
+ extern void *
+ BBitmap_transform_bitmap (void *bitmap, void *mask, uint32_t m_color,
+ double rot, int desw, int desh);
+
+ extern void
+ BScreen_px_dim (int *width, int *height);
+
+ extern void
+ BView_resize_to (void *view, int width, int height);
+
+ /* Functions for creating and freeing cursors. */
+ extern void *
+ BCursor_create_default (void);
+
+ extern void *
+ BCursor_from_id (enum haiku_cursor cursor);
+
+ extern void *
+ BCursor_create_modeline (void);
+
+ extern void *
+ BCursor_create_i_beam (void);
+
+ extern void *
+ BCursor_create_progress_cursor (void);
+
+ extern void *
+ BCursor_create_grab (void);
+
+ extern void
+ BCursor_delete (void *cursor);
+
+ extern void
+ BView_set_view_cursor (void *view, void *cursor);
+
+ extern void
+ BWindow_Flush (void *window);
+
+ extern void
+ BMapKey (uint32_t kc, int *non_ascii_p, unsigned *code);
+
+ extern void *
+ BScrollBar_make_for_view (void *view, int horizontal_p,
+ int x, int y, int x1, int y1,
+ void *scroll_bar_ptr);
+
+ extern void
+ BScrollBar_delete (void *sb);
+
+ extern void
+ BView_move_frame (void *view, int x, int y, int x1, int y1);
+
+ extern void
+ BView_scroll_bar_update (void *sb, int portion, int whole, int position);
+
+ extern int
+ BScrollBar_default_size (int horizontal_p);
+
+ extern void
+ BView_invalidate (void *view);
+
+ extern void
+ BView_draw_lock (void *view);
+
+ extern void
+ BView_draw_unlock (void *view);
+
+ extern void
+ BWindow_center_on_screen (void *window);
+
+ extern void
+ BView_mouse_moved (void *view, int x, int y, uint32_t transit);
+
+ extern void
+ BView_mouse_down (void *view, int x, int y);
+
+ extern void
+ BView_mouse_up (void *view, int x, int y);
+
+ extern void
+ BBitmap_import_mono_bits (void *bitmap, void *bits, int wd, int h);
+
+ extern void
+ haiku_font_pattern_free (struct haiku_font_pattern *pt);
+
+ extern struct haiku_font_pattern *
+ BFont_find (struct haiku_font_pattern *pt);
+
+ extern int
+ BFont_open_pattern (struct haiku_font_pattern *pat, void **font, float size);
+
+ extern void
+ BFont_populate_fixed_family (struct haiku_font_pattern *ptn);
+
+ extern void
+ BFont_populate_plain_family (struct haiku_font_pattern *ptn);
+
+ extern void
+ BView_publish_scroll_bar (void *view, int x, int y, int width, int height);
+
+ extern void
+ BView_forget_scroll_bar (void *view, int x, int y, int width, int height);
+
+ extern void
+ BView_get_mouse (void *view, int *x, int *y);
+
+ extern void
+ BView_convert_to_screen (void *view, int *x, int *y);
+
+ extern void
+ BView_convert_from_screen (void *view, int *x, int *y);
+
+ extern void
+ BWindow_change_decoration (void *window, int decorate_p);
+
+ extern void
+ BWindow_set_tooltip_decoration (void *window);
+
+ extern void
+ BWindow_set_avoid_focus (void *window, int avoid_focus_p);
+
+ extern void
+ BView_emacs_delete (void *view);
+
+ extern uint32_t
+ haiku_current_workspace (void);
+
+ extern uint32_t
+ BWindow_workspaces (void *window);
+
+ extern void *
+ BPopUpMenu_new (const char *name);
+
+ extern void
+ BMenu_add_item (void *menu, const char *label, void *ptr, bool enabled_p,
+ bool marked_p, bool mbar_p, void *mbw_ptr, const char *key,
+ const char *help);
+
+ extern void
+ BMenu_add_separator (void *menu);
+
+ extern void *
+ BMenu_new_submenu (void *menu, const char *label, bool enabled_p);
+
+ extern void *
+ BMenu_new_menu_bar_submenu (void *menu, const char *label);
+
+ extern int
+ BMenu_count_items (void *menu);
+
+ extern void *
+ BMenu_item_at (void *menu, int idx);
+
+ extern void *
+ BMenu_run (void *menu, int x, int y);
+
+ extern void
+ BPopUpMenu_delete (void *menu);
+
+ extern void *
+ BMenuBar_new (void *view);
+
+ extern void
+ BMenu_delete_all (void *menu);
+
+ extern void
+ BMenuBar_delete (void *menubar);
+
+ extern void
+ BMenu_item_set_label (void *item, const char *label);
+
+ extern void *
+ BMenu_item_get_menu (void *item);
+
+ extern void
+ BMenu_delete_from (void *menu, int start, int count);
+
+ extern void
+ haiku_ring_bell (void);
+
+ extern void *
+ BAlert_new (const char *text, enum haiku_alert_type type);
+
+ extern void *
+ BAlert_add_button (void *alert, const char *text);
+
+ extern int32_t
+ BAlert_go (void *alert);
+
+ extern void
+ BButton_set_enabled (void *button, int enabled_p);
+
+ extern void
+ BView_set_tooltip (void *view, const char *tooltip);
+
+ extern void
+ BAlert_delete (void *alert);
+
+ extern void
+ BScreen_res (double *rrsx, double *rrsy);
+
+ extern void
+ EmacsWindow_parent_to (void *window, void *other_window);
+
+ extern void
+ EmacsWindow_unparent (void *window);
+
+ extern int
+ BFont_string_width (void *font, const char *utf8);
+
+ extern void
+ be_get_version_string (char *version, int len);
+
+ extern int
+ be_get_display_planes (void);
+
+ extern int
+ be_get_display_color_cells (void);
+
+ extern void
+ be_warp_pointer (int x, int y);
+
+ extern void
+ EmacsWindow_move_weak_child (void *window, void *child, int xoff, int yoff);
+
+ extern void
+ EmacsView_set_up_double_buffering (void *vw);
+
+ extern void
+ EmacsView_disable_double_buffering (void *vw);
+
+ extern void
+ EmacsView_flip_and_blit (void *vw);
+
+ extern int
+ EmacsView_double_buffered_p (void *vw);
+
+ extern char *
+ be_popup_file_dialog (int open_p, const char *default_dir, int must_match_p,
+ int dir_only_p, void *window, const char *save_text,
+ const char *prompt,
+ void (*block_input_function) (void),
+ void (*unblock_input_function) (void));
+
+ extern void
+ record_c_unwind_protect_from_cxx (void (*) (void *), void *);
+
+ extern ptrdiff_t
+ c_specpdl_idx_from_cxx (void);
+
+ extern void
+ c_unbind_to_nil_from_cxx (ptrdiff_t idx);
+
+ extern void
+ EmacsView_do_visible_bell (void *view, uint32_t color);
+
+ extern void
+ BWindow_zoom (void *window);
+
+ extern void
+ EmacsWindow_make_fullscreen (void *window, int fullscreen_p);
+
+ extern void
+ EmacsWindow_unzoom (void *window);
+
+#ifdef HAVE_NATIVE_IMAGE_API
+ extern int
+ be_can_translate_type_to_bitmap_p (const char *mime);
+
+ extern void *
+ be_translate_bitmap_from_file_name (const char *filename);
+
+ extern void *
+ be_translate_bitmap_from_memory (const void *buf, size_t bytes);
+#endif
+
+ extern void
+ BMenuBar_start_tracking (void *mbar);
+
+ extern size_t
+ BBitmap_bytes_length (void *bitmap);
+
+ extern void
+ BView_show_tooltip (void *view);
+
+#ifdef USE_BE_CAIRO
+ extern cairo_surface_t *
+ EmacsView_cairo_surface (void *view);
+
+ extern void
+ BView_cr_dump_clipping (void *view, cairo_t *ctx);
+
+ extern void
+ EmacsWindow_begin_cr_critical_section (void *window);
+
+ extern void
+ EmacsWindow_end_cr_critical_section (void *window);
+#endif
+
+ extern void
+ BView_set_and_show_sticky_tooltip (void *view, const char *tooltip,
+ int x, int y);
+
+ extern void
+ BMenu_add_title (void *menu, const char *text);
+
+ extern int
+ be_plain_font_height (void);
+
+ extern int
+ be_string_width_with_plain_font (const char *str);
+
+ extern int
+ be_get_display_screens (void);
+
+ extern void
+ BWindow_set_min_size (void *window, int width, int height);
+
+ extern void
+ BWindow_set_size_alignment (void *window, int align_width, int align_height);
+
+#ifdef __cplusplus
+ extern void *
+ find_appropriate_view_for_draw (void *vw);
+}
+
+extern _Noreturn void
+gui_abort (const char *msg);
+#endif /* _cplusplus */
+
+/* Borrowed from X.Org keysymdef.h */
+#define XK_BackSpace 0xff08 /* Back space, back char */
+#define XK_Tab 0xff09
+#define XK_Linefeed 0xff0a /* Linefeed, LF */
+#define XK_Clear 0xff0b
+#define XK_Return 0xff0d /* Return, enter */
+#define XK_Pause 0xff13 /* Pause, hold */
+#define XK_Scroll_Lock 0xff14
+#define XK_Sys_Req 0xff15
+#define XK_Escape 0xff1b
+#define XK_Delete 0xffff /* Delete, rubout */
+#define XK_Home 0xff50
+#define XK_Left 0xff51 /* Move left, left arrow */
+#define XK_Up 0xff52 /* Move up, up arrow */
+#define XK_Right 0xff53 /* Move right, right arrow */
+#define XK_Down 0xff54 /* Move down, down arrow */
+#define XK_Prior 0xff55 /* Prior, previous */
+#define XK_Page_Up 0xff55
+#define XK_Next 0xff56 /* Next */
+#define XK_Page_Down 0xff56
+#define XK_End 0xff57 /* EOL */
+#define XK_Begin 0xff58 /* BOL */
+#define XK_Select 0xff60 /* Select, mark */
+#define XK_Print 0xff61
+#define XK_Execute 0xff62 /* Execute, run, do */
+#define XK_Insert 0xff63 /* Insert, insert here */
+#define XK_Undo 0xff65
+#define XK_Redo 0xff66 /* Redo, again */
+#define XK_Menu 0xff67
+#define XK_Find 0xff68 /* Find, search */
+#define XK_Cancel 0xff69 /* Cancel, stop, abort, exit */
+#define XK_Help 0xff6a /* Help */
+#define XK_Break 0xff6b
+#define XK_Mode_switch 0xff7e /* Character set switch */
+#define XK_script_switch 0xff7e /* Alias for mode_switch */
+#define XK_Num_Lock 0xff7f
+#define XK_F1 0xffbe
+
+#endif /* _HAIKU_SUPPORT_H_ */
diff --git a/src/haikufns.c b/src/haikufns.c
new file mode 100644
index 00000000000..737b0338994
--- /dev/null
+++ b/src/haikufns.c
@@ -0,0 +1,2449 @@
+/* Haiku window system support
+ Copyright (C) 2021 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/>. */
+
+#include <config.h>
+
+#include <math.h>
+
+#include "lisp.h"
+#include "frame.h"
+#include "blockinput.h"
+#include "termchar.h"
+#include "font.h"
+#include "keyboard.h"
+#include "buffer.h"
+#include "dispextern.h"
+
+#include "haikugui.h"
+#include "haikuterm.h"
+#include "haiku_support.h"
+#include "termhooks.h"
+
+#include <stdlib.h>
+
+#include <kernel/OS.h>
+
+#define RGB_TO_ULONG(r, g, b) \
+ (((r) << 16) | ((g) << 8) | (b));
+#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
+#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
+#define BLUE_FROM_ULONG(color) ((color) & 0xff)
+
+/* The frame of the currently visible tooltip. */
+static Lisp_Object tip_frame;
+
+/* The window-system window corresponding to the frame of the
+ currently visible tooltip. */
+static Window tip_window;
+
+/* A timer that hides or deletes the currently visible tooltip when it
+ fires. */
+static Lisp_Object tip_timer;
+
+/* STRING argument of last `x-show-tip' call. */
+static Lisp_Object tip_last_string;
+
+/* Normalized FRAME argument of last `x-show-tip' call. */
+static Lisp_Object tip_last_frame;
+
+/* PARMS argument of last `x-show-tip' call. */
+static Lisp_Object tip_last_parms;
+
+static void
+haiku_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval);
+static void
+haiku_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name);
+
+static ptrdiff_t image_cache_refcount;
+
+static Lisp_Object
+get_geometry_from_preferences (struct haiku_display_info *dpyinfo,
+ Lisp_Object parms)
+{
+ struct {
+ const char *val;
+ const char *cls;
+ Lisp_Object tem;
+ } r[] = {
+ { "width", "Width", Qwidth },
+ { "height", "Height", Qheight },
+ { "left", "Left", Qleft },
+ { "top", "Top", Qtop },
+ };
+
+ int i;
+ for (i = 0; i < ARRAYELTS (r); ++i)
+ {
+ if (NILP (Fassq (r[i].tem, parms)))
+ {
+ Lisp_Object value
+ = gui_display_get_arg (dpyinfo, parms, r[i].tem, r[i].val, r[i].cls,
+ RES_TYPE_NUMBER);
+ if (! EQ (value, Qunbound))
+ parms = Fcons (Fcons (r[i].tem, value), parms);
+ }
+ }
+
+ return parms;
+}
+
+void
+haiku_change_tool_bar_height (struct frame *f, int height)
+{
+ int unit = FRAME_LINE_HEIGHT (f);
+ int old_height = FRAME_TOOL_BAR_HEIGHT (f);
+ int lines = (height + unit - 1) / unit;
+ Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
+
+ /* Make sure we redisplay all windows in this frame. */
+ fset_redisplay (f);
+
+ FRAME_TOOL_BAR_HEIGHT (f) = height;
+ FRAME_TOOL_BAR_LINES (f) = lines;
+ store_frame_param (f, Qtool_bar_lines, make_fixnum (lines));
+
+ if (FRAME_HAIKU_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
+ {
+ clear_frame (f);
+ clear_current_matrices (f);
+ }
+
+ if ((height < old_height) && WINDOWP (f->tool_bar_window))
+ clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
+
+ if (!f->tool_bar_resized)
+ {
+ /* As long as tool_bar_resized is false, effectively try to change
+ F's native height. */
+ if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
+ adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+ 1, false, Qtool_bar_lines);
+ else
+ adjust_frame_size (f, -1, -1, 4, false, Qtool_bar_lines);
+
+ f->tool_bar_resized = f->tool_bar_redisplayed;
+ }
+ else
+ /* Any other change may leave the native size of F alone. */
+ adjust_frame_size (f, -1, -1, 3, false, Qtool_bar_lines);
+
+ /* adjust_frame_size might not have done anything, garbage frame
+ here. */
+ adjust_frame_glyphs (f);
+ SET_FRAME_GARBAGED (f);
+
+ if (FRAME_HAIKU_WINDOW (f))
+ haiku_clear_under_internal_border (f);
+}
+
+void
+haiku_change_tab_bar_height (struct frame *f, int height)
+{
+ int unit = FRAME_LINE_HEIGHT (f);
+ int old_height = FRAME_TAB_BAR_HEIGHT (f);
+ int lines = (height + unit - 1) / unit;
+ Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
+
+ /* Make sure we redisplay all windows in this frame. */
+ fset_redisplay (f);
+
+ /* Recalculate tab bar and frame text sizes. */
+ FRAME_TAB_BAR_HEIGHT (f) = height;
+ FRAME_TAB_BAR_LINES (f) = lines;
+ store_frame_param (f, Qtab_bar_lines, make_fixnum (lines));
+
+ if (FRAME_HAIKU_WINDOW (f) && FRAME_TAB_BAR_HEIGHT (f) == 0)
+ {
+ clear_frame (f);
+ clear_current_matrices (f);
+ }
+
+ if ((height < old_height) && WINDOWP (f->tab_bar_window))
+ clear_glyph_matrix (XWINDOW (f->tab_bar_window)->current_matrix);
+
+ if (!f->tab_bar_resized)
+ {
+ /* As long as tab_bar_resized is false, effectively try to change
+ F's native height. */
+ if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
+ adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+ 1, false, Qtab_bar_lines);
+ else
+ adjust_frame_size (f, -1, -1, 4, false, Qtab_bar_lines);
+
+ f->tab_bar_resized = f->tab_bar_redisplayed;
+ }
+ else
+ /* Any other change may leave the native size of F alone. */
+ adjust_frame_size (f, -1, -1, 3, false, Qtab_bar_lines);
+
+ /* adjust_frame_size might not have done anything, garbage frame
+ here. */
+ adjust_frame_glyphs (f);
+ SET_FRAME_GARBAGED (f);
+ if (FRAME_HAIKU_WINDOW (f))
+ haiku_clear_under_internal_border (f);
+}
+
+static void
+haiku_set_no_focus_on_map (struct frame *f, Lisp_Object value,
+ Lisp_Object oldval)
+{
+ if (!EQ (value, oldval))
+ FRAME_NO_FOCUS_ON_MAP (f) = !NILP (value);
+}
+
+static void
+haiku_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
+{
+ if (FRAME_TOOLTIP_P (f))
+ return;
+ int nlines;
+
+ /* Treat tool bars like menu bars. */
+ if (FRAME_MINIBUF_ONLY_P (f))
+ return;
+
+ /* Use VALUE only if an int >= 0. */
+ if (RANGED_FIXNUMP (0, value, INT_MAX))
+ nlines = XFIXNAT (value);
+ else
+ nlines = 0;
+
+ haiku_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
+}
+
+static void
+haiku_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
+{
+ if (FRAME_TOOLTIP_P (f))
+ return;
+ int olines = FRAME_TAB_BAR_LINES (f);
+ int nlines;
+
+ /* Treat tab bars like menu bars. */
+ if (FRAME_MINIBUF_ONLY_P (f))
+ return;
+
+ /* Use VALUE only if an int >= 0. */
+ if (RANGED_FIXNUMP (0, value, INT_MAX))
+ nlines = XFIXNAT (value);
+ else
+ nlines = 0;
+
+ if (nlines != olines && (olines == 0 || nlines == 0))
+ haiku_change_tab_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
+}
+
+
+int
+haiku_get_color (const char *name, Emacs_Color *color)
+{
+ unsigned short r16, g16, b16;
+ Lisp_Object tem;
+
+ if (parse_color_spec (name, &r16, &g16, &b16))
+ {
+ color->pixel = RGB_TO_ULONG (r16 / 256, g16 / 256, b16 / 256);
+ color->red = r16;
+ color->green = g16;
+ color->blue = b16;
+ return 0;
+ }
+ else
+ {
+ block_input ();
+ eassert (x_display_list && !NILP (x_display_list->color_map));
+ tem = x_display_list->color_map;
+ for (; CONSP (tem); tem = XCDR (tem))
+ {
+ Lisp_Object col = XCAR (tem);
+ if (CONSP (col) && !xstrcasecmp (SSDATA (XCAR (col)), name))
+ {
+ int32_t clr = XFIXNUM (XCDR (col));
+ color->pixel = clr;
+ color->red = RED_FROM_ULONG (clr) * 257;
+ color->green = GREEN_FROM_ULONG (clr) * 257;
+ color->blue = BLUE_FROM_ULONG (clr) * 257;
+ unblock_input ();
+ return 0;
+ }
+ }
+
+ unblock_input ();
+ }
+
+ return 1;
+}
+
+static struct haiku_display_info *
+haiku_display_info_for_name (Lisp_Object name)
+{
+ CHECK_STRING (name);
+
+ if (!NILP (Fstring_equal (name, build_string ("be"))))
+ {
+ if (!x_display_list)
+ return x_display_list;
+
+ error ("Be windowing not initialized");
+ }
+
+ error ("Be displays can only be named \"be\"");
+}
+
+static struct haiku_display_info *
+check_haiku_display_info (Lisp_Object object)
+{
+ struct haiku_display_info *dpyinfo = NULL;
+
+ if (NILP (object))
+ {
+ struct frame *sf = XFRAME (selected_frame);
+
+ if (FRAME_HAIKU_P (sf) && FRAME_LIVE_P (sf))
+ dpyinfo = FRAME_DISPLAY_INFO (sf);
+ else if (x_display_list)
+ dpyinfo = x_display_list;
+ else
+ error ("Be windowing not present");
+ }
+ else if (TERMINALP (object))
+ {
+ struct terminal *t = decode_live_terminal (object);
+
+ if (t->type != output_haiku)
+ error ("Terminal %d is not a Be display", t->id);
+
+ dpyinfo = t->display_info.haiku;
+ }
+ else if (STRINGP (object))
+ dpyinfo = haiku_display_info_for_name (object);
+ else
+ {
+ struct frame *f = decode_window_system_frame (object);
+ dpyinfo = FRAME_DISPLAY_INFO (f);
+ }
+
+ return dpyinfo;
+}
+
+static void
+haiku_set_title_bar_text (struct frame *f, Lisp_Object text)
+{
+ if (FRAME_HAIKU_WINDOW (f))
+ {
+ block_input ();
+ BWindow_retitle (FRAME_HAIKU_WINDOW (f), SSDATA (ENCODE_UTF_8 (text)));
+ unblock_input ();
+ }
+}
+
+static void
+haiku_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
+{
+ /* Don't change the title if it's already NAME. */
+ if (EQ (name, f->title))
+ return;
+
+ update_mode_lines = 26;
+
+ fset_title (f, name);
+
+ if (NILP (name))
+ name = f->name;
+
+ haiku_set_title_bar_text (f, name);
+}
+
+static void
+haiku_set_child_frame_border_width (struct frame *f,
+ Lisp_Object arg, Lisp_Object oldval)
+{
+ int border;
+
+ if (NILP (arg))
+ border = -1;
+ else if (RANGED_FIXNUMP (0, arg, INT_MAX))
+ border = XFIXNAT (arg);
+ else
+ signal_error ("Invalid child frame border width", arg);
+
+ if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f))
+ {
+ f->child_frame_border_width = border;
+
+ if (FRAME_HAIKU_WINDOW (f))
+ adjust_frame_size (f, -1, -1, 3, 0, Qchild_frame_border_width);
+
+ SET_FRAME_GARBAGED (f);
+ }
+}
+
+static void
+haiku_set_parent_frame (struct frame *f,
+ Lisp_Object new_value, Lisp_Object old_value)
+{
+ struct frame *p = NULL;
+ block_input ();
+ if (!NILP (new_value)
+ && (!FRAMEP (new_value)
+ || !FRAME_LIVE_P (p = XFRAME (new_value))
+ || !FRAME_HAIKU_P (p)))
+ {
+ store_frame_param (f, Qparent_frame, old_value);
+ unblock_input ();
+ error ("Invalid specification of `parent-frame'");
+ }
+
+ if (EQ (new_value, old_value))
+ {
+ unblock_input ();
+ return;
+ }
+
+ if (!NILP (old_value))
+ EmacsWindow_unparent (FRAME_HAIKU_WINDOW (f));
+ if (!NILP (new_value))
+ {
+ EmacsWindow_parent_to (FRAME_HAIKU_WINDOW (f),
+ FRAME_HAIKU_WINDOW (p));
+ BWindow_set_offset (FRAME_HAIKU_WINDOW (f),
+ f->left_pos, f->top_pos);
+ }
+ fset_parent_frame (f, new_value);
+ unblock_input ();
+}
+
+static void
+haiku_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ haiku_set_name (f, arg, 1);
+}
+
+static void
+haiku_set_no_accept_focus (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
+{
+ block_input ();
+ if (!EQ (new_value, old_value))
+ FRAME_NO_ACCEPT_FOCUS (f) = !NILP (new_value);
+
+ if (FRAME_HAIKU_WINDOW (f))
+ {
+ BWindow_set_avoid_focus (FRAME_HAIKU_WINDOW (f),
+ FRAME_NO_ACCEPT_FOCUS (f));
+ }
+ unblock_input ();
+}
+
+static void
+unwind_create_frame (Lisp_Object frame)
+{
+ struct frame *f = XFRAME (frame);
+
+ /* If frame is already dead, nothing to do. This can happen if the
+ display is disconnected after the frame has become official, but
+ before x_create_frame removes the unwind protect. */
+ if (!FRAME_LIVE_P (f))
+ return;
+
+ /* If frame is ``official'', nothing to do. */
+ if (NILP (Fmemq (frame, Vframe_list)))
+ {
+#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
+ struct haiku_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+#endif
+
+ /* If the frame's image cache refcount is still the same as our
+ private shadow variable, it means we are unwinding a frame
+ for which we didn't yet call init_frame_faces, where the
+ refcount is incremented. Therefore, we increment it here, so
+ that free_frame_faces, called in free_frame_resources later,
+ will not mistakenly decrement the counter that was not
+ incremented yet to account for this new frame. */
+ if (FRAME_IMAGE_CACHE (f) != NULL
+ && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount)
+ FRAME_IMAGE_CACHE (f)->refcount++;
+
+ haiku_free_frame_resources (f);
+ free_glyphs (f);
+
+#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
+ /* Check that reference counts are indeed correct. */
+ if (dpyinfo->terminal->image_cache)
+ eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount);
+#endif
+ }
+}
+
+static void
+unwind_create_tip_frame (Lisp_Object frame)
+{
+ unwind_create_frame (frame);
+ tip_window = NULL;
+ tip_frame = Qnil;
+}
+
+static void
+haiku_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ struct haiku_output *output = FRAME_OUTPUT_DATA (f);
+ unsigned long old_fg;
+
+ Emacs_Color color;
+
+ if (haiku_get_color (SSDATA (arg), &color))
+ {
+ store_frame_param (f, Qforeground_color, oldval);
+ unblock_input ();
+ error ("Bad color");
+ }
+
+ old_fg = FRAME_FOREGROUND_PIXEL (f);
+ FRAME_FOREGROUND_PIXEL (f) = color.pixel;
+
+ if (FRAME_HAIKU_WINDOW (f))
+ {
+
+ block_input ();
+ if (output->cursor_color.pixel == old_fg)
+ {
+ output->cursor_color.pixel = old_fg;
+ output->cursor_color.red = RED_FROM_ULONG (old_fg);
+ output->cursor_color.green = GREEN_FROM_ULONG (old_fg);
+ output->cursor_color.blue = BLUE_FROM_ULONG (old_fg);
+ }
+
+ unblock_input ();
+
+ update_face_from_frame_parameter (f, Qforeground_color, arg);
+
+ if (FRAME_VISIBLE_P (f))
+ redraw_frame (f);
+ }
+}
+
+static void
+unwind_popup (void)
+{
+ if (!popup_activated_p)
+ emacs_abort ();
+ --popup_activated_p;
+}
+
+static Lisp_Object
+haiku_create_frame (Lisp_Object parms, int ttip_p)
+{
+ struct frame *f;
+ Lisp_Object frame, tem;
+ Lisp_Object name;
+ bool minibuffer_only = false;
+ bool face_change_before = face_change;
+ long window_prompting = 0;
+ ptrdiff_t count = SPECPDL_INDEX ();
+ Lisp_Object display;
+ struct haiku_display_info *dpyinfo = NULL;
+ struct kboard *kb;
+
+ parms = Fcopy_alist (parms);
+
+ Vx_resource_name = Vinvocation_name;
+
+ display = gui_display_get_arg (dpyinfo, parms, Qterminal, 0, 0,
+ RES_TYPE_STRING);
+ if (EQ (display, Qunbound))
+ display = Qnil;
+ dpyinfo = check_haiku_display_info (display);
+ kb = dpyinfo->terminal->kboard;
+
+ if (!dpyinfo->terminal->name)
+ error ("Terminal is not live, can't create new frames on it");
+
+ name = gui_display_get_arg (dpyinfo, parms, Qname, 0, 0,
+ RES_TYPE_STRING);
+ if (!STRINGP (name)
+ && ! EQ (name, Qunbound)
+ && ! NILP (name))
+ error ("Invalid frame name--not a string or nil");
+
+ if (STRINGP (name))
+ Vx_resource_name = name;
+
+ block_input ();
+
+ /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
+ /* No need to protect DISPLAY because that's not used after passing
+ it to make_frame_without_minibuffer. */
+ frame = Qnil;
+ tem = gui_display_get_arg (dpyinfo, parms, Qminibuffer,
+ "minibuffer", "Minibuffer",
+ RES_TYPE_SYMBOL);
+ if (ttip_p)
+ f = make_frame (0);
+ else if (EQ (tem, Qnone) || NILP (tem))
+ f = make_frame_without_minibuffer (Qnil, kb, display);
+ else if (EQ (tem, Qonly))
+ {
+ f = make_minibuffer_frame ();
+ minibuffer_only = 1;
+ }
+ else if (WINDOWP (tem))
+ f = make_frame_without_minibuffer (tem, kb, display);
+ else
+ f = make_frame (1);
+ XSETFRAME (frame, f);
+
+ f->terminal = dpyinfo->terminal;
+
+ f->output_method = output_haiku;
+ f->output_data.haiku = xzalloc (sizeof *f->output_data.haiku);
+
+ f->output_data.haiku->pending_zoom_x = INT_MIN;
+ f->output_data.haiku->pending_zoom_y = INT_MIN;
+ f->output_data.haiku->pending_zoom_width = INT_MIN;
+ f->output_data.haiku->pending_zoom_height = INT_MIN;
+
+ if (ttip_p)
+ f->wants_modeline = false;
+
+ fset_icon_name (f, gui_display_get_arg (dpyinfo, parms, Qicon_name,
+ "iconName", "Title",
+ RES_TYPE_STRING));
+ if (! STRINGP (f->icon_name) || ttip_p)
+ fset_icon_name (f, Qnil);
+
+ FRAME_DISPLAY_INFO (f) = dpyinfo;
+
+ /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
+ if (!ttip_p)
+ record_unwind_protect (unwind_create_frame, frame);
+ else
+ record_unwind_protect (unwind_create_tip_frame, frame);
+
+ FRAME_OUTPUT_DATA (f)->parent_desc = NULL;
+ FRAME_OUTPUT_DATA (f)->explicit_parent = 0;
+
+ /* Set the name; the functions to which we pass f expect the name to
+ be set. */
+ if (EQ (name, Qunbound) || NILP (name) || ! STRINGP (name))
+ {
+ fset_name (f, Vinvocation_name);
+ f->explicit_name = 0;
+ }
+ else
+ {
+ fset_name (f, name);
+ f->explicit_name = 1;
+ specbind (Qx_resource_name, name);
+ }
+
+#ifdef USE_BE_CAIRO
+ register_font_driver (&ftcrfont_driver, f);
+#ifdef HAVE_HARFBUZZ
+ register_font_driver (&ftcrhbfont_driver, f);
+#endif
+#endif
+ register_font_driver (&haikufont_driver, f);
+
+ f->tooltip = ttip_p;
+
+ image_cache_refcount =
+ FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
+
+ gui_default_parameter (f, parms, Qfont_backend, Qnil,
+ "fontBackend", "FontBackend", RES_TYPE_STRING);
+
+ FRAME_RIF (f)->default_font_parameter (f, parms);
+
+ unblock_input ();
+
+ gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
+ "borderwidth", "BorderWidth", RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (ttip_p ? 1 : 2),
+ "internalBorderWidth", "InternalBorderWidth",
+ RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qchild_frame_border_width, Qnil,
+ "childFrameBorderWidth", "childFrameBorderWidth",
+ RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0),
+ NULL, NULL, RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
+ NULL, NULL, RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qvertical_scroll_bars, !ttip_p ? Qt : Qnil,
+ "verticalScrollBars", "VerticalScrollBars",
+ RES_TYPE_SYMBOL);
+ gui_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil,
+ "horizontalScrollBars", "HorizontalScrollBars",
+ RES_TYPE_SYMBOL);
+ gui_default_parameter (f, parms, Qforeground_color, build_string ("black"),
+ "foreground", "Foreground", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qbackground_color, build_string ("white"),
+ "background", "Background", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qline_spacing, Qnil,
+ "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qleft_fringe, Qnil,
+ "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qright_fringe, Qnil,
+ "rightFringe", "RightFringe", RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qno_special_glyphs, ttip_p ? Qnil : Qt,
+ NULL, NULL, RES_TYPE_BOOLEAN);
+
+ init_frame_faces (f);
+
+ /* Read comment about this code in corresponding place in xfns.c. */
+ tem = gui_display_get_arg (dpyinfo, parms, Qmin_width, NULL, NULL,
+ RES_TYPE_NUMBER);
+ if (FIXNUMP (tem))
+ store_frame_param (f, Qmin_width, tem);
+ tem = gui_display_get_arg (dpyinfo, parms, Qmin_height, NULL, NULL,
+ RES_TYPE_NUMBER);
+ if (FIXNUMP (tem))
+ store_frame_param (f, Qmin_height, tem);
+ adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
+ FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1,
+ Qx_create_frame_1);
+
+ if (!ttip_p)
+ {
+ gui_default_parameter (f, parms, Qz_group, Qnil, NULL, NULL, RES_TYPE_SYMBOL);
+ gui_default_parameter (f, parms, Qno_focus_on_map, Qnil,
+ NULL, NULL, RES_TYPE_BOOLEAN);
+ gui_default_parameter (f, parms, Qno_accept_focus, Qnil,
+ NULL, NULL, RES_TYPE_BOOLEAN);
+
+ /* The resources controlling the menu-bar, tool-bar, and tab-bar are
+ processed specially at startup, and reflected in the mode
+ variables; ignore them here. */
+ gui_default_parameter (f, parms, Qmenu_bar_lines,
+ NILP (Vmenu_bar_mode)
+ ? make_fixnum (0) : make_fixnum (1),
+ NULL, NULL, RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qtab_bar_lines,
+ NILP (Vtab_bar_mode)
+ ? make_fixnum (0) : make_fixnum (1),
+ NULL, NULL, RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qtool_bar_lines,
+ NILP (Vtool_bar_mode)
+ ? make_fixnum (0) : make_fixnum (1),
+ NULL, NULL, RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qbuffer_predicate, Qnil, "bufferPredicate",
+ "BufferPredicate", RES_TYPE_SYMBOL);
+ gui_default_parameter (f, parms, Qtitle, Qnil, "title", "Title",
+ RES_TYPE_STRING);
+ }
+
+ parms = get_geometry_from_preferences (dpyinfo, parms);
+ window_prompting = gui_figure_window_size (f, parms, false, true);
+
+ if (ttip_p)
+ {
+ /* No fringes on tip frame. */
+ f->fringe_cols = 0;
+ f->left_fringe_width = 0;
+ f->right_fringe_width = 0;
+ /* No dividers on tip frame. */
+ f->right_divider_width = 0;
+ f->bottom_divider_width = 0;
+ }
+
+ tem = gui_display_get_arg (dpyinfo, parms, Qunsplittable, 0, 0,
+ RES_TYPE_BOOLEAN);
+ f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !NILP (tem));
+
+ /* Add `tooltip' frame parameter's default value. */
+ if (NILP (Fframe_parameter (frame, Qtooltip)) && ttip_p)
+ Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
+
+#define ASSIGN_CURSOR(cursor, be_cursor) \
+ (FRAME_OUTPUT_DATA (f)->cursor = be_cursor)
+
+ ASSIGN_CURSOR (text_cursor, BCursor_create_i_beam ());
+ ASSIGN_CURSOR (nontext_cursor, BCursor_create_default ());
+ ASSIGN_CURSOR (modeline_cursor, BCursor_create_modeline ());
+ ASSIGN_CURSOR (hand_cursor, BCursor_create_grab ());
+ ASSIGN_CURSOR (hourglass_cursor, BCursor_create_progress_cursor ());
+ ASSIGN_CURSOR (horizontal_drag_cursor,
+ BCursor_from_id (CURSOR_ID_RESIZE_EAST_WEST));
+ ASSIGN_CURSOR (vertical_drag_cursor,
+ BCursor_from_id (CURSOR_ID_RESIZE_NORTH_SOUTH));
+ ASSIGN_CURSOR (left_edge_cursor,
+ BCursor_from_id (CURSOR_ID_RESIZE_WEST));
+ ASSIGN_CURSOR (top_left_corner_cursor,
+ BCursor_from_id (CURSOR_ID_RESIZE_NORTH_WEST));
+ ASSIGN_CURSOR (top_edge_cursor,
+ BCursor_from_id (CURSOR_ID_RESIZE_NORTH));
+ ASSIGN_CURSOR (top_right_corner_cursor,
+ BCursor_from_id (CURSOR_ID_RESIZE_NORTH_EAST));
+ ASSIGN_CURSOR (right_edge_cursor,
+ BCursor_from_id (CURSOR_ID_RESIZE_EAST));
+ ASSIGN_CURSOR (bottom_right_corner_cursor,
+ BCursor_from_id (CURSOR_ID_RESIZE_SOUTH_EAST));
+ ASSIGN_CURSOR (bottom_edge_cursor,
+ BCursor_from_id (CURSOR_ID_RESIZE_SOUTH));
+ ASSIGN_CURSOR (bottom_left_corner_cursor,
+ BCursor_from_id (CURSOR_ID_RESIZE_SOUTH_WEST));
+ ASSIGN_CURSOR (no_cursor,
+ BCursor_from_id (CURSOR_ID_NO_CURSOR));
+
+ ASSIGN_CURSOR (current_cursor, FRAME_OUTPUT_DATA (f)->text_cursor);
+#undef ASSIGN_CURSOR
+
+
+ if (ttip_p)
+ f->no_split = true;
+ f->terminal->reference_count++;
+
+ FRAME_OUTPUT_DATA (f)->window = BWindow_new (&FRAME_OUTPUT_DATA (f)->view);
+ if (!FRAME_OUTPUT_DATA (f)->window)
+ xsignal1 (Qerror, build_unibyte_string ("Could not create window"));
+
+ if (!minibuffer_only && !ttip_p && FRAME_EXTERNAL_MENU_BAR (f))
+ initialize_frame_menubar (f);
+
+ FRAME_OUTPUT_DATA (f)->window_desc = FRAME_OUTPUT_DATA (f)->window;
+
+ Vframe_list = Fcons (frame, Vframe_list);
+
+ Lisp_Object parent_frame = gui_display_get_arg (dpyinfo, parms, Qparent_frame, NULL, NULL,
+ RES_TYPE_SYMBOL);
+
+ if (EQ (parent_frame, Qunbound)
+ || NILP (parent_frame)
+ || !FRAMEP (parent_frame)
+ || !FRAME_LIVE_P (XFRAME (parent_frame)))
+ parent_frame = Qnil;
+
+ fset_parent_frame (f, parent_frame);
+ store_frame_param (f, Qparent_frame, parent_frame);
+
+ if (!NILP (parent_frame))
+ haiku_set_parent_frame (f, parent_frame, Qnil);
+
+ gui_default_parameter (f, parms, Qundecorated, Qnil, NULL, NULL, RES_TYPE_BOOLEAN);
+
+ gui_default_parameter (f, parms, Qicon_type, Qnil,
+ "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
+ if (ttip_p)
+ {
+ gui_default_parameter (f, parms, Qundecorated, Qt, NULL, NULL, RES_TYPE_BOOLEAN);
+ gui_default_parameter (f, parms, Qno_accept_focus, Qt, NULL, NULL,
+ RES_TYPE_BOOLEAN);
+ }
+ else
+ {
+ gui_default_parameter (f, parms, Qauto_raise, Qnil,
+ "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
+ gui_default_parameter (f, parms, Qauto_lower, Qnil,
+ "autoLower", "AutoLower", RES_TYPE_BOOLEAN);
+ gui_default_parameter (f, parms, Qcursor_type, Qbox,
+ "cursorType", "CursorType", RES_TYPE_SYMBOL);
+ gui_default_parameter (f, parms, Qscroll_bar_width, Qnil,
+ "scrollBarWidth", "ScrollBarWidth",
+ RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qscroll_bar_height, Qnil,
+ "scrollBarHeight", "ScrollBarHeight",
+ RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qalpha, Qnil,
+ "alpha", "Alpha", RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qfullscreen, Qnil,
+ "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
+ }
+
+ gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil,
+ "inhibitDoubleBuffering", "InhibitDoubleBuffering",
+ RES_TYPE_BOOLEAN);
+
+ if (ttip_p)
+ {
+ Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
+
+ call2 (Qface_set_after_frame_default, frame, Qnil);
+
+ if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
+ {
+ AUTO_FRAME_ARG (arg, Qbackground_color, bg);
+ Fmodify_frame_parameters (frame, arg);
+ }
+ }
+
+ if (ttip_p)
+ face_change = face_change_before;
+
+ f->can_set_window_size = true;
+
+ adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+ 0, true, ttip_p ? Qtip_frame : Qx_create_frame_2);
+
+ if (!FRAME_OUTPUT_DATA (f)->explicit_parent && !ttip_p)
+ {
+ Lisp_Object visibility;
+
+ visibility = gui_display_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
+ RES_TYPE_SYMBOL);
+ if (EQ (visibility, Qunbound))
+ visibility = Qt;
+ if (EQ (visibility, Qicon))
+ haiku_iconify_frame (f);
+ else if (!NILP (visibility))
+ haiku_visualize_frame (f);
+ else /* Qnil */
+ {
+ f->was_invisible = true;
+ }
+ }
+
+ if (!ttip_p)
+ {
+ if (FRAME_HAS_MINIBUF_P (f)
+ && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
+ || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
+ kset_default_minibuffer_frame (kb, frame);
+ }
+
+ for (tem = parms; CONSP (tem); tem = XCDR (tem))
+ if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
+ fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
+
+ if (window_prompting & (USPosition | PPosition))
+ haiku_set_offset (f, f->left_pos, f->top_pos, 1);
+ else
+ BWindow_center_on_screen (FRAME_HAIKU_WINDOW (f));
+
+ /* Make sure windows on this frame appear in calls to next-window
+ and similar functions. */
+ Vwindow_list = Qnil;
+
+ if (ttip_p)
+ adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+ 0, true, Qtip_frame);
+
+ return unbind_to (count, frame);
+}
+
+static void
+compute_tip_xy (struct frame *f,
+ Lisp_Object parms, Lisp_Object dx, Lisp_Object dy,
+ int width, int height, int *root_x, int *root_y)
+{
+ Lisp_Object left, top, right, bottom;
+ int min_x = 0, min_y = 0, max_x = 0, max_y = 0;
+
+ /* User-specified position? */
+ left = Fcdr (Fassq (Qleft, parms));
+ top = Fcdr (Fassq (Qtop, parms));
+ right = Fcdr (Fassq (Qright, parms));
+ bottom = Fcdr (Fassq (Qbottom, parms));
+
+ /* Move the tooltip window where the mouse pointer is. Resize and
+ show it. */
+ if ((!FIXNUMP (left) && !FIXNUMP (right))
+ || (!FIXNUMP (top) && !FIXNUMP (bottom)))
+ {
+ int x, y;
+
+ /* Default min and max values. */
+ min_x = 0;
+ min_y = 0;
+ BScreen_px_dim (&max_x, &max_y);
+
+ block_input ();
+ BView_get_mouse (FRAME_HAIKU_VIEW (f), &x, &y);
+ BView_convert_to_screen (FRAME_HAIKU_VIEW (f), &x, &y);
+ *root_x = x;
+ *root_y = y;
+ unblock_input ();
+ }
+
+ if (FIXNUMP (top))
+ *root_y = XFIXNUM (top);
+ else if (FIXNUMP (bottom))
+ *root_y = XFIXNUM (bottom) - height;
+ else if (*root_y + XFIXNUM (dy) <= min_y)
+ *root_y = min_y; /* Can happen for negative dy */
+ else if (*root_y + XFIXNUM (dy) + height <= max_y)
+ /* It fits below the pointer */
+ *root_y += XFIXNUM (dy);
+ else if (height + XFIXNUM (dy) + min_y <= *root_y)
+ /* It fits above the pointer. */
+ *root_y -= height + XFIXNUM (dy);
+ else
+ /* Put it on the top. */
+ *root_y = min_y;
+
+ if (FIXNUMP (left))
+ *root_x = XFIXNUM (left);
+ else if (FIXNUMP (right))
+ *root_x = XFIXNUM (right) - width;
+ else if (*root_x + XFIXNUM (dx) <= min_x)
+ *root_x = 0; /* Can happen for negative dx */
+ else if (*root_x + XFIXNUM (dx) + width <= max_x)
+ /* It fits to the right of the pointer. */
+ *root_x += XFIXNUM (dx);
+ else if (width + XFIXNUM (dx) + min_x <= *root_x)
+ /* It fits to the left of the pointer. */
+ *root_x -= width + XFIXNUM (dx);
+ else
+ /* Put it left justified on the screen -- it ought to fit that way. */
+ *root_x = min_x;
+}
+
+static Lisp_Object
+haiku_hide_tip (bool delete)
+{
+ if (!NILP (tip_timer))
+ {
+ call1 (Qcancel_timer, tip_timer);
+ tip_timer = Qnil;
+ }
+
+ Lisp_Object it, frame;
+ FOR_EACH_FRAME (it, frame)
+ if (FRAME_WINDOW_P (XFRAME (frame)) &&
+ FRAME_HAIKU_VIEW (XFRAME (frame)))
+ BView_set_tooltip (FRAME_HAIKU_VIEW (XFRAME (frame)), NULL);
+
+ if (NILP (tip_frame)
+ || (!delete && !NILP (tip_frame)
+ && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
+ return Qnil;
+ else
+ {
+ ptrdiff_t count;
+ Lisp_Object was_open = Qnil;
+
+ count = SPECPDL_INDEX ();
+ specbind (Qinhibit_redisplay, Qt);
+ specbind (Qinhibit_quit, Qt);
+
+ if (!NILP (tip_frame))
+ {
+ if (FRAME_LIVE_P (XFRAME (tip_frame)))
+ {
+ if (delete)
+ {
+ delete_frame (tip_frame, Qnil);
+ tip_frame = Qnil;
+ }
+ else
+ haiku_unvisualize_frame (XFRAME (tip_frame));
+
+ was_open = Qt;
+ }
+ else
+ tip_frame = Qnil;
+ }
+ else
+ tip_frame = Qnil;
+
+ return unbind_to (count, was_open);
+ }
+}
+
+static void
+haiku_set_undecorated (struct frame *f, Lisp_Object new_value,
+ Lisp_Object old_value)
+{
+ if (EQ (new_value, old_value))
+ return;
+
+ block_input ();
+ FRAME_UNDECORATED (f) = !NILP (new_value);
+ BWindow_change_decoration (FRAME_HAIKU_WINDOW (f), NILP (new_value));
+ unblock_input ();
+}
+
+static void
+haiku_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
+{
+ if (FRAME_TOOLTIP_P (f))
+ return;
+ int nlines;
+ if (TYPE_RANGED_FIXNUMP (int, value))
+ nlines = XFIXNUM (value);
+ else
+ nlines = 0;
+
+ fset_redisplay (f);
+
+ FRAME_MENU_BAR_LINES (f) = 0;
+ FRAME_MENU_BAR_HEIGHT (f) = 0;
+
+ if (nlines)
+ {
+ FRAME_EXTERNAL_MENU_BAR (f) = 1;
+ if (FRAME_HAIKU_P (f) && !FRAME_HAIKU_MENU_BAR (f))
+ XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = 1;
+ }
+ else
+ {
+ if (FRAME_EXTERNAL_MENU_BAR (f))
+ free_frame_menubar (f);
+ FRAME_EXTERNAL_MENU_BAR (f) = 0;
+ if (FRAME_HAIKU_P (f))
+ FRAME_HAIKU_MENU_BAR (f) = 0;
+ }
+
+ adjust_frame_glyphs (f);
+}
+
+/* Return geometric attributes of FRAME. According to the value of
+ ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the inner
+ edges of FRAME, the root window edges of frame (Qroot_edges). Any
+ other value means to return the geometry as returned by
+ Fx_frame_geometry. */
+static Lisp_Object
+frame_geometry (Lisp_Object frame, Lisp_Object attribute)
+{
+ struct frame *f = decode_live_frame (frame);
+ check_window_system (f);
+
+ if (EQ (attribute, Qouter_edges))
+ return list4i (f->left_pos, f->top_pos,
+ f->left_pos, f->top_pos);
+ else if (EQ (attribute, Qnative_edges))
+ return list4i (f->left_pos, f->top_pos,
+ f->left_pos + FRAME_PIXEL_WIDTH (f),
+ f->top_pos + FRAME_PIXEL_HEIGHT (f));
+ else if (EQ (attribute, Qinner_edges))
+ return list4i (f->left_pos + FRAME_INTERNAL_BORDER_WIDTH (f),
+ f->top_pos + FRAME_INTERNAL_BORDER_WIDTH (f) +
+ FRAME_MENU_BAR_HEIGHT (f) + FRAME_TOOL_BAR_HEIGHT (f),
+ f->left_pos - FRAME_INTERNAL_BORDER_WIDTH (f) +
+ FRAME_PIXEL_WIDTH (f),
+ f->top_pos + FRAME_PIXEL_HEIGHT (f) -
+ FRAME_INTERNAL_BORDER_WIDTH (f));
+
+ else
+ return
+ list (Fcons (Qouter_position,
+ Fcons (make_fixnum (f->left_pos),
+ make_fixnum (f->top_pos))),
+ Fcons (Qouter_size,
+ Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)),
+ make_fixnum (FRAME_PIXEL_HEIGHT (f)))),
+ Fcons (Qexternal_border_size,
+ Fcons (make_fixnum (0), make_fixnum (0))),
+ Fcons (Qtitle_bar_size,
+ Fcons (make_fixnum (0), make_fixnum (0))),
+ Fcons (Qmenu_bar_external, Qnil),
+ Fcons (Qmenu_bar_size, Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f) -
+ (FRAME_INTERNAL_BORDER_WIDTH (f) * 2)),
+ make_fixnum (FRAME_MENU_BAR_HEIGHT (f)))),
+ Fcons (Qtool_bar_external, Qnil),
+ Fcons (Qtool_bar_position, Qtop),
+ Fcons (Qtool_bar_size, Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f) -
+ (FRAME_INTERNAL_BORDER_WIDTH (f) * 2)),
+ make_fixnum (FRAME_TOOL_BAR_HEIGHT (f)))),
+ Fcons (Qinternal_border_width, make_fixnum (FRAME_INTERNAL_BORDER_WIDTH (f))));
+}
+
+void
+haiku_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ CHECK_STRING (arg);
+
+ block_input ();
+ Emacs_Color color;
+
+ if (haiku_get_color (SSDATA (arg), &color))
+ {
+ store_frame_param (f, Qbackground_color, oldval);
+ unblock_input ();
+ error ("Bad color");
+ }
+
+ FRAME_OUTPUT_DATA (f)->cursor_fg = color.pixel;
+ FRAME_BACKGROUND_PIXEL (f) = color.pixel;
+
+ if (FRAME_HAIKU_VIEW (f))
+ {
+ struct face *defface;
+
+ BView_draw_lock (FRAME_HAIKU_VIEW (f));
+ BView_SetViewColor (FRAME_HAIKU_VIEW (f), color.pixel);
+ BView_draw_unlock (FRAME_HAIKU_VIEW (f));
+
+ defface = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID);
+ if (defface)
+ {
+ defface->background = color.pixel;
+ update_face_from_frame_parameter (f, Qbackground_color, arg);
+ clear_frame (f);
+ }
+ }
+
+ if (FRAME_VISIBLE_P (f))
+ SET_FRAME_GARBAGED (f);
+ unblock_input ();
+}
+
+void
+haiku_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ CHECK_STRING (arg);
+
+ block_input ();
+ Emacs_Color color;
+
+ if (haiku_get_color (SSDATA (arg), &color))
+ {
+ store_frame_param (f, Qcursor_color, oldval);
+ unblock_input ();
+ error ("Bad color");
+ }
+
+ FRAME_CURSOR_COLOR (f) = color;
+ if (FRAME_VISIBLE_P (f))
+ {
+ gui_update_cursor (f, 0);
+ gui_update_cursor (f, 1);
+ }
+ update_face_from_frame_parameter (f, Qcursor_color, arg);
+ unblock_input ();
+}
+
+void
+haiku_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ set_frame_cursor_types (f, arg);
+}
+
+unsigned long
+haiku_get_pixel (haiku bitmap, int x, int y)
+{
+ unsigned char *data;
+ int32_t bytes_per_row;
+ int mono_p;
+ int left;
+ int right;
+ int top;
+ int bottom;
+
+ data = BBitmap_data (bitmap);
+ BBitmap_dimensions (bitmap, &left, &top, &right, &bottom,
+ &bytes_per_row, &mono_p);
+
+ if (x < left || x > right || y < top || y > bottom)
+ emacs_abort ();
+
+ if (!mono_p)
+ return ((uint32_t *) (data + (bytes_per_row * y)))[x];
+
+ int byte = y * bytes_per_row + x / 8;
+ return data[byte] & (1 << (x % 8));
+}
+
+void
+haiku_put_pixel (haiku bitmap, int x, int y, unsigned long pixel)
+{
+ unsigned char *data;
+ int32_t bytes_per_row;
+ int mono_p;
+ int left;
+ int right;
+ int top;
+ int bottom;
+
+ data = BBitmap_data (bitmap);
+ BBitmap_dimensions (bitmap, &left, &top, &right, &bottom,
+ &bytes_per_row, &mono_p);
+
+ if (x < left || x > right || y < top || y > bottom)
+ emacs_abort ();
+
+ if (mono_p)
+ {
+ ptrdiff_t off = y * bytes_per_row;
+ ptrdiff_t bit = x % 8;
+ ptrdiff_t xoff = x / 8;
+
+ unsigned char *byte = data + off + xoff;
+ if (!pixel)
+ *byte &= ~(1 << bit);
+ else
+ *byte |= 1 << bit;
+ }
+ else
+ ((uint32_t *) (data + (bytes_per_row * y)))[x] = pixel;
+}
+
+void
+haiku_free_frame_resources (struct frame *f)
+{
+ haiku window, drawable, mbar;
+ Mouse_HLInfo *hlinfo;
+ struct haiku_display_info *dpyinfo;
+ Lisp_Object bar;
+ struct scroll_bar *b;
+
+ block_input ();
+ check_window_system (f);
+
+ hlinfo = MOUSE_HL_INFO (f);
+ window = FRAME_HAIKU_WINDOW (f);
+ drawable = FRAME_HAIKU_VIEW (f);
+ mbar = FRAME_HAIKU_MENU_BAR (f);
+ dpyinfo = FRAME_DISPLAY_INFO (f);
+
+ free_frame_faces (f);
+
+ /* Free scroll bars */
+ for (bar = FRAME_SCROLL_BARS (f); !NILP (bar); bar = b->next)
+ {
+ b = XSCROLL_BAR (bar);
+ haiku_scroll_bar_remove (b);
+ }
+
+ if (f == dpyinfo->highlight_frame)
+ dpyinfo->highlight_frame = 0;
+ if (f == dpyinfo->focused_frame)
+ dpyinfo->focused_frame = 0;
+ if (f == dpyinfo->last_mouse_motion_frame)
+ dpyinfo->last_mouse_motion_frame = NULL;
+ if (f == dpyinfo->last_mouse_frame)
+ dpyinfo->last_mouse_frame = NULL;
+ if (f == dpyinfo->focus_event_frame)
+ dpyinfo->focus_event_frame = NULL;
+
+ if (f == hlinfo->mouse_face_mouse_frame)
+ reset_mouse_highlight (hlinfo);
+
+ if (mbar)
+ {
+ BMenuBar_delete (mbar);
+ if (f->output_data.haiku->menu_bar_open_p)
+ {
+ --popup_activated_p;
+ f->output_data.haiku->menu_bar_open_p = 0;
+ }
+ }
+
+ if (drawable)
+ BView_emacs_delete (drawable);
+
+ if (window)
+ BWindow_quit (window);
+
+ /* Free cursors */
+
+ BCursor_delete (f->output_data.haiku->text_cursor);
+ BCursor_delete (f->output_data.haiku->nontext_cursor);
+ BCursor_delete (f->output_data.haiku->modeline_cursor);
+ BCursor_delete (f->output_data.haiku->hand_cursor);
+ BCursor_delete (f->output_data.haiku->hourglass_cursor);
+ BCursor_delete (f->output_data.haiku->horizontal_drag_cursor);
+ BCursor_delete (f->output_data.haiku->vertical_drag_cursor);
+ BCursor_delete (f->output_data.haiku->left_edge_cursor);
+ BCursor_delete (f->output_data.haiku->top_left_corner_cursor);
+ BCursor_delete (f->output_data.haiku->top_edge_cursor);
+ BCursor_delete (f->output_data.haiku->top_right_corner_cursor);
+ BCursor_delete (f->output_data.haiku->right_edge_cursor);
+ BCursor_delete (f->output_data.haiku->bottom_right_corner_cursor);
+ BCursor_delete (f->output_data.haiku->bottom_edge_cursor);
+ BCursor_delete (f->output_data.haiku->bottom_left_corner_cursor);
+ BCursor_delete (f->output_data.haiku->no_cursor);
+
+ xfree (FRAME_OUTPUT_DATA (f));
+ FRAME_OUTPUT_DATA (f) = NULL;
+
+ unblock_input ();
+}
+
+void
+haiku_iconify_frame (struct frame *frame)
+{
+ if (FRAME_ICONIFIED_P (frame))
+ return;
+
+ block_input ();
+
+ SET_FRAME_VISIBLE (frame, false);
+ SET_FRAME_ICONIFIED (frame, true);
+
+ BWindow_iconify (FRAME_HAIKU_WINDOW (frame));
+
+ unblock_input ();
+}
+
+void
+haiku_visualize_frame (struct frame *f)
+{
+ block_input ();
+
+ if (!FRAME_VISIBLE_P (f))
+ {
+ if (FRAME_NO_FOCUS_ON_MAP (f))
+ BWindow_set_avoid_focus (FRAME_HAIKU_WINDOW (f), 1);
+ BWindow_set_visible (FRAME_HAIKU_WINDOW (f), 1);
+ if (FRAME_NO_FOCUS_ON_MAP (f) &&
+ !FRAME_NO_ACCEPT_FOCUS (f))
+ BWindow_set_avoid_focus (FRAME_HAIKU_WINDOW (f), 0);
+
+ haiku_set_offset (f, f->left_pos, f->top_pos, 0);
+
+ SET_FRAME_VISIBLE (f, 1);
+ SET_FRAME_ICONIFIED (f, 0);
+ }
+
+ unblock_input ();
+}
+
+void
+haiku_unvisualize_frame (struct frame *f)
+{
+ block_input ();
+
+ BWindow_set_visible (FRAME_HAIKU_WINDOW (f), 0);
+ SET_FRAME_VISIBLE (f, 0);
+ SET_FRAME_ICONIFIED (f, 0);
+
+ unblock_input ();
+}
+
+void
+haiku_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ int old_width = FRAME_INTERNAL_BORDER_WIDTH (f);
+ int new_width = check_int_nonnegative (arg);
+
+ if (new_width == old_width)
+ return;
+ f->internal_border_width = new_width;
+
+ if (FRAME_HAIKU_WINDOW (f))
+ {
+ adjust_frame_size (f, -1, -1, 3, 0, Qinternal_border_width);
+ haiku_clear_under_internal_border (f);
+ }
+
+ SET_FRAME_GARBAGED (f);
+}
+
+void
+haiku_set_frame_visible_invisible (struct frame *f, bool visible_p)
+{
+ if (visible_p)
+ haiku_visualize_frame (f);
+ else
+ haiku_unvisualize_frame (f);
+}
+
+void
+frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
+{
+ block_input ();
+
+ BView_convert_to_screen (FRAME_HAIKU_VIEW (f), &pix_x, &pix_y);
+ be_warp_pointer (pix_x, pix_y);
+
+ unblock_input ();
+}
+
+void
+haiku_query_color (uint32_t col, Emacs_Color *color_def)
+{
+ color_def->red = RED_FROM_ULONG (col) * 257;
+ color_def->green = GREEN_FROM_ULONG (col) * 257;
+ color_def->blue = BLUE_FROM_ULONG (col) * 257;
+
+ color_def->pixel = col;
+}
+
+Display_Info *
+check_x_display_info (Lisp_Object object)
+{
+ return check_haiku_display_info (object);
+}
+
+/* Rename frame F to NAME. If NAME is nil, set F's name to "GNU
+ Emacs". If EXPLICIT_P is non-zero, that indicates Lisp code is
+ setting the name, not redisplay; in that case, set F's name to NAME
+ and set F->explicit_name; if NAME is nil, clear F->explicit_name.
+
+ If EXPLICIT_P is zero, it means redisplay is setting the name; the
+ name provided will be ignored if explicit_name is set. */
+void
+haiku_set_name (struct frame *f, Lisp_Object name, bool explicit_p)
+{
+ if (explicit_p)
+ {
+ if (f->explicit_name && NILP (name))
+ update_mode_lines = 24;
+
+ f->explicit_name = !NILP (name);
+ }
+ else if (f->explicit_name)
+ return;
+
+ if (NILP (name))
+ name = build_unibyte_string ("GNU Emacs");
+
+ if (!NILP (Fstring_equal (name, f->name)))
+ return;
+
+ fset_name (f, name);
+
+ if (!NILP (f->title))
+ name = f->title;
+
+ haiku_set_title_bar_text (f, name);
+}
+
+static void
+haiku_set_inhibit_double_buffering (struct frame *f,
+ Lisp_Object new_value,
+ Lisp_Object old_value)
+{
+ block_input ();
+ if (FRAME_HAIKU_WINDOW (f))
+ {
+ if (NILP (new_value))
+ {
+ EmacsView_set_up_double_buffering (FRAME_HAIKU_VIEW (f));
+ if (!NILP (old_value))
+ {
+ SET_FRAME_GARBAGED (f);
+ expose_frame (f, 0, 0, 0, 0);
+ }
+ }
+ else
+ EmacsView_disable_double_buffering (FRAME_HAIKU_VIEW (f));
+ }
+ unblock_input ();
+}
+
+
+
+DEFUN ("haiku-set-mouse-absolute-pixel-position",
+ Fhaiku_set_mouse_absolute_pixel_position,
+ Shaiku_set_mouse_absolute_pixel_position, 2, 2, 0,
+ doc: /* Move mouse pointer to a pixel position at (X, Y). The
+coordinates X and Y are interpreted to start from the top-left
+corner of the screen. */)
+ (Lisp_Object x, Lisp_Object y)
+{
+ int xval = check_integer_range (x, INT_MIN, INT_MAX);
+ int yval = check_integer_range (y, INT_MIN, INT_MAX);
+
+ if (!x_display_list)
+ error ("Window system not initialized");
+
+ block_input ();
+ be_warp_pointer (xval, yval);
+ unblock_input ();
+ return Qnil;
+}
+
+DEFUN ("haiku-mouse-absolute-pixel-position", Fhaiku_mouse_absolute_pixel_position,
+ Shaiku_mouse_absolute_pixel_position, 0, 0, 0,
+ doc: /* Return absolute position of mouse cursor in pixels.
+The position is returned as a cons cell (X . Y) of the coordinates of
+the mouse cursor position in pixels relative to a position (0, 0) of the
+selected frame's display. */)
+ (void)
+{
+ if (!x_display_list)
+ return Qnil;
+
+ struct frame *f = SELECTED_FRAME ();
+
+ if (FRAME_INITIAL_P (f) || !FRAME_HAIKU_P (f)
+ || !FRAME_HAIKU_VIEW (f))
+ return Qnil;
+
+ block_input ();
+ void *view = FRAME_HAIKU_VIEW (f);
+
+ int x, y;
+ BView_get_mouse (view, &x, &y);
+ BView_convert_to_screen (view, &x, &y);
+ unblock_input ();
+
+ return Fcons (make_fixnum (x), make_fixnum (y));
+}
+
+DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object terminal)
+{
+ return Qt;
+}
+
+DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object color, Lisp_Object frame)
+{
+ Emacs_Color col;
+ CHECK_STRING (color);
+ decode_window_system_frame (frame);
+
+ return haiku_get_color (SSDATA (color), &col) ? Qnil : Qt;
+}
+
+DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object color, Lisp_Object frame)
+{
+ Emacs_Color col;
+ CHECK_STRING (color);
+ decode_window_system_frame (frame);
+
+ block_input ();
+ if (haiku_get_color (SSDATA (color), &col))
+ {
+ unblock_input ();
+ return Qnil;
+ }
+ unblock_input ();
+ return list3i (lrint (col.red), lrint (col.green), lrint (col.blue));
+}
+
+DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
+ 0, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object terminal)
+{
+ return Qnil;
+}
+
+DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
+ 1, 3, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object display, Lisp_Object resource_string, Lisp_Object must_succeed)
+{
+ struct haiku_display_info *dpy_info;
+ CHECK_STRING (display);
+
+ if (NILP (Fstring_equal (display, build_string ("be"))))
+ !NILP (must_succeed) ? fatal ("Bad display") : error ("Bad display");
+ dpy_info = haiku_term_init ();
+
+ if (!dpy_info)
+ !NILP (must_succeed) ? fatal ("Display not responding") :
+ error ("Display not responding");
+
+ return Qnil;
+}
+
+DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
+ 0, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object terminal)
+
+{
+ check_haiku_display_info (terminal);
+
+ int width, height;
+ BScreen_px_dim (&width, &height);
+ return make_fixnum (width);
+}
+
+DEFUN ("x-display-pixel-height", Fx_display_pixel_height, Sx_display_pixel_height,
+ 0, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object terminal)
+
+{
+ check_haiku_display_info (terminal);
+
+ int width, height;
+ BScreen_px_dim (&width, &height);
+ return make_fixnum (width);
+}
+
+DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object terminal)
+{
+ struct haiku_display_info *dpyinfo = check_haiku_display_info (terminal);
+
+ int width, height;
+ BScreen_px_dim (&width, &height);
+
+ return make_fixnum (height / (dpyinfo->resy / 25.4));
+}
+
+
+DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object terminal)
+{
+ struct haiku_display_info *dpyinfo = check_haiku_display_info (terminal);
+
+ int width, height;
+ BScreen_px_dim (&width, &height);
+
+ return make_fixnum (height / (dpyinfo->resy / 25.4));
+}
+
+DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
+ 1, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object parms)
+{
+ return haiku_create_frame (parms, 0);
+}
+
+DEFUN ("x-display-visual-class", Fx_display_visual_class,
+ Sx_display_visual_class, 0, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object terminal)
+{
+ check_haiku_display_info (terminal);
+
+ int planes = be_get_display_planes ();
+
+ if (planes == 8)
+ return intern ("static-color");
+ else if (planes == 16 || planes == 15)
+ return intern ("pseudo-color");
+
+ return intern ("direct-color");
+}
+
+DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object string, Lisp_Object frame, Lisp_Object parms,
+ Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
+{
+ struct frame *tip_f;
+ struct window *w;
+ int root_x, root_y;
+ struct buffer *old_buffer;
+ struct text_pos pos;
+ int width, height;
+ int old_windows_or_buffers_changed = windows_or_buffers_changed;
+ ptrdiff_t count = SPECPDL_INDEX ();
+ ptrdiff_t count_1;
+ Lisp_Object window, size, tip_buf;
+
+ AUTO_STRING (tip, " *tip*");
+
+ specbind (Qinhibit_redisplay, Qt);
+
+ CHECK_STRING (string);
+
+ if (NILP (frame))
+ frame = selected_frame;
+ decode_window_system_frame (frame);
+
+ if (NILP (timeout))
+ timeout = make_fixnum (5);
+ else
+ CHECK_FIXNAT (timeout);
+
+ if (NILP (dx))
+ dx = make_fixnum (5);
+ else
+ CHECK_FIXNUM (dx);
+
+ if (NILP (dy))
+ dy = make_fixnum (-10);
+ else
+ CHECK_FIXNUM (dy);
+
+ if (haiku_use_system_tooltips)
+ {
+ int root_x, root_y;
+ CHECK_STRING (string);
+ if (STRING_MULTIBYTE (string))
+ string = ENCODE_UTF_8 (string);
+
+ if (NILP (frame))
+ frame = selected_frame;
+
+ struct frame *f = decode_window_system_frame (frame);
+ block_input ();
+
+ char *str = xstrdup (SSDATA (string));
+ int height = be_plain_font_height ();
+ int width;
+ char *tok = strtok (str, "\n");
+ width = be_string_width_with_plain_font (tok);
+
+ while ((tok = strtok (NULL, "\n")))
+ {
+ height = be_plain_font_height ();
+ int w = be_string_width_with_plain_font (tok);
+ if (w > width)
+ w = width;
+ }
+ free (str);
+
+ height += 16; /* Default margin. */
+ width += 16; /* Ditto. Unfortunately there isn't a more
+ reliable way to get it. */
+ compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
+ BView_convert_from_screen (FRAME_HAIKU_VIEW (f), &root_x, &root_y);
+ BView_set_and_show_sticky_tooltip (FRAME_HAIKU_VIEW (f), SSDATA (string),
+ root_x, root_y);
+ unblock_input ();
+ goto start_timer;
+ }
+
+ if (!NILP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
+ {
+ if (FRAME_VISIBLE_P (XFRAME (tip_frame))
+ && EQ (frame, tip_last_frame)
+ && !NILP (Fequal_including_properties (string, tip_last_string))
+ && !NILP (Fequal (parms, tip_last_parms)))
+ {
+ /* Only DX and DY have changed. */
+ tip_f = XFRAME (tip_frame);
+ if (!NILP (tip_timer))
+ {
+ Lisp_Object timer = tip_timer;
+
+ tip_timer = Qnil;
+ call1 (Qcancel_timer, timer);
+ }
+
+ block_input ();
+ compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
+ FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
+ haiku_set_offset (tip_f, root_x, root_y, 1);
+ haiku_visualize_frame (tip_f);
+ unblock_input ();
+
+ goto start_timer;
+ }
+ else if (tooltip_reuse_hidden_frame && EQ (frame, tip_last_frame))
+ {
+ bool delete = false;
+ Lisp_Object tail, elt, parm, last;
+
+ /* Check if every parameter in PARMS has the same value in
+ tip_last_parms. This may destruct tip_last_parms
+ which, however, will be recreated below. */
+ for (tail = parms; CONSP (tail); tail = XCDR (tail))
+ {
+ elt = XCAR (tail);
+ parm = Fcar (elt);
+ /* The left, top, right and bottom parameters are handled
+ by compute_tip_xy so they can be ignored here. */
+ if (!EQ (parm, Qleft) && !EQ (parm, Qtop)
+ && !EQ (parm, Qright) && !EQ (parm, Qbottom))
+ {
+ last = Fassq (parm, tip_last_parms);
+ if (NILP (Fequal (Fcdr (elt), Fcdr (last))))
+ {
+ /* We lost, delete the old tooltip. */
+ delete = true;
+ break;
+ }
+ else
+ tip_last_parms =
+ call2 (Qassq_delete_all, parm, tip_last_parms);
+ }
+ else
+ tip_last_parms =
+ call2 (Qassq_delete_all, parm, tip_last_parms);
+ }
+
+ /* Now check if there's a parameter left in tip_last_parms with a
+ non-nil value. */
+ for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail))
+ {
+ elt = XCAR (tail);
+ parm = Fcar (elt);
+ if (!EQ (parm, Qleft) && !EQ (parm, Qtop) && !EQ (parm, Qright)
+ && !EQ (parm, Qbottom) && !NILP (Fcdr (elt)))
+ {
+ /* We lost, delete the old tooltip. */
+ delete = true;
+ break;
+ }
+ }
+
+ haiku_hide_tip (delete);
+ }
+ else
+ haiku_hide_tip (true);
+ }
+ else
+ haiku_hide_tip (true);
+
+ tip_last_frame = frame;
+ tip_last_string = string;
+ tip_last_parms = parms;
+
+ /* Block input until the tip has been fully drawn, to avoid crashes
+ when drawing tips in menus. */
+ block_input ();
+
+ if (NILP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
+ {
+ /* Add default values to frame parameters. */
+ if (NILP (Fassq (Qname, parms)))
+ parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
+ if (NILP (Fassq (Qinternal_border_width, parms)))
+ parms = Fcons (Fcons (Qinternal_border_width, make_fixnum (3)), parms);
+ if (NILP (Fassq (Qborder_width, parms)))
+ parms = Fcons (Fcons (Qborder_width, make_fixnum (1)), parms);
+ if (NILP (Fassq (Qborder_color, parms)))
+ parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")),
+ parms);
+ if (NILP (Fassq (Qbackground_color, parms)))
+ parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
+ parms);
+
+ /* Create a frame for the tooltip and record it in the global
+ variable tip_frame. */
+
+ if (NILP (tip_frame = haiku_create_frame (parms, 1)))
+ {
+ /* Creating the tip frame failed. */
+ unblock_input ();
+ return unbind_to (count, Qnil);
+ }
+ }
+
+ tip_f = XFRAME (tip_frame);
+ window = FRAME_ROOT_WINDOW (tip_f);
+ tip_buf = Fget_buffer_create (tip, Qnil);
+ /* We will mark the tip window a "pseudo-window" below, and such
+ windows cannot have display margins. */
+ bset_left_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
+ bset_right_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
+ set_window_buffer (window, tip_buf, false, false);
+ w = XWINDOW (window);
+ w->pseudo_window_p = true;
+ /* Try to avoid that `other-window' select us (Bug#47207). */
+ Fset_window_parameter (window, Qno_other_window, Qt);
+
+ /* Set up the frame's root window. Note: The following code does not
+ try to size the window or its frame correctly. Its only purpose is
+ to make the subsequent text size calculations work. The right
+ sizes should get installed when the toolkit gets back to us. */
+ w->left_col = 0;
+ w->top_line = 0;
+ w->pixel_left = 0;
+ w->pixel_top = 0;
+
+ if (CONSP (Vx_max_tooltip_size)
+ && RANGED_FIXNUMP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
+ && RANGED_FIXNUMP (1, XCDR (Vx_max_tooltip_size), INT_MAX))
+ {
+ w->total_cols = XFIXNAT (XCAR (Vx_max_tooltip_size));
+ w->total_lines = XFIXNAT (XCDR (Vx_max_tooltip_size));
+ }
+ else
+ {
+ w->total_cols = 80;
+ w->total_lines = 40;
+ }
+
+ w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (tip_f);
+ w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (tip_f);
+ FRAME_TOTAL_COLS (tip_f) = WINDOW_TOTAL_COLS (w);
+ adjust_frame_glyphs (tip_f);
+
+ /* Insert STRING into the root window's buffer and fit the frame to
+ the buffer. */
+ count_1 = SPECPDL_INDEX ();
+ old_buffer = current_buffer;
+ set_buffer_internal_1 (XBUFFER (w->contents));
+ bset_truncate_lines (current_buffer, Qnil);
+ specbind (Qinhibit_read_only, Qt);
+ specbind (Qinhibit_modification_hooks, Qt);
+ specbind (Qinhibit_point_motion_hooks, Qt);
+ Ferase_buffer ();
+ Finsert (1, &string);
+ clear_glyph_matrix (w->desired_matrix);
+ clear_glyph_matrix (w->current_matrix);
+ SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
+ try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
+ /* Calculate size of tooltip window. */
+ size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil,
+ make_fixnum (w->pixel_height), Qnil,
+ Qnil);
+ /* Add the frame's internal border to calculated size. */
+ width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
+ height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
+ /* Calculate position of tooltip frame. */
+ compute_tip_xy (tip_f, parms, dx, dy, width, height, &root_x, &root_y);
+ BWindow_resize (FRAME_HAIKU_WINDOW (tip_f), width, height);
+ haiku_set_offset (tip_f, root_x, root_y, 1);
+ BWindow_set_tooltip_decoration (FRAME_HAIKU_WINDOW (tip_f));
+ BView_set_view_cursor (FRAME_HAIKU_VIEW (tip_f),
+ FRAME_OUTPUT_DATA (XFRAME (frame))->current_cursor);
+ SET_FRAME_VISIBLE (tip_f, 1);
+ BWindow_set_visible (FRAME_HAIKU_WINDOW (tip_f), 1);
+
+ w->must_be_updated_p = true;
+ flush_frame (tip_f);
+ update_single_window (w);
+ set_buffer_internal_1 (old_buffer);
+ unbind_to (count_1, Qnil);
+ unblock_input ();
+ windows_or_buffers_changed = old_windows_or_buffers_changed;
+
+ start_timer:
+ /* Let the tip disappear after timeout seconds. */
+ tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
+ intern ("x-hide-tip"));
+
+ return unbind_to (count, Qnil);
+}
+
+DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (void)
+{
+ return haiku_hide_tip (!tooltip_reuse_hidden_frame);
+}
+
+DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection, 1, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */
+ attributes: noreturn)
+ (Lisp_Object terminal)
+{
+ check_haiku_display_info (terminal);
+
+ error ("Cannot close Haiku displays");
+}
+
+DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (void)
+{
+ if (!x_display_list)
+ return Qnil;
+
+ return list1 (XCAR (x_display_list->name_list_element));
+}
+
+DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object terminal)
+{
+ check_haiku_display_info (terminal);
+ return build_string ("Haiku, Inc.");
+}
+
+DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object terminal)
+{
+ check_haiku_display_info (terminal);
+ return list3i (5, 1, 1);
+}
+
+DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object terminal)
+{
+ check_haiku_display_info (terminal);
+ return make_fixnum (be_get_display_screens ());
+}
+
+DEFUN ("haiku-get-version-string", Fhaiku_get_version_string,
+ Shaiku_get_version_string, 0, 0, 0,
+ doc: /* Return a string describing the current Haiku version. */)
+ (void)
+{
+ char buf[1024];
+
+ be_get_version_string ((char *) &buf, sizeof buf);
+ return build_string (buf);
+}
+
+DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
+ 0, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object terminal)
+{
+ check_haiku_display_info (terminal);
+
+ return make_fixnum (be_get_display_color_cells ());
+}
+
+DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
+ 0, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object terminal)
+{
+ check_haiku_display_info (terminal);
+
+ return make_fixnum (be_get_display_planes ());
+}
+
+DEFUN ("x-double-buffered-p", Fx_double_buffered_p, Sx_double_buffered_p,
+ 0, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object frame)
+{
+ struct frame *f = decode_live_frame (frame);
+ check_window_system (f);
+
+ return EmacsView_double_buffered_p (FRAME_HAIKU_VIEW (f)) ? Qt : Qnil;
+}
+
+DEFUN ("x-display-backing-store", Fx_display_backing_store, Sx_display_backing_store,
+ 0, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object terminal)
+{
+ if (FRAMEP (terminal))
+ {
+ CHECK_LIVE_FRAME (terminal);
+ struct frame *f = decode_window_system_frame (terminal);
+
+ if (FRAME_HAIKU_VIEW (f) &&
+ EmacsView_double_buffered_p (FRAME_HAIKU_VIEW (f)))
+ return FRAME_PARENT_FRAME (f) ? Qwhen_mapped : Qalways;
+ else
+ return Qnot_useful;
+ }
+ else
+ {
+ check_haiku_display_info (terminal);
+ return Qnot_useful;
+ }
+}
+
+DEFUN ("haiku-frame-geometry", Fhaiku_frame_geometry, Shaiku_frame_geometry, 0, 1, 0,
+ doc: /* Return geometric attributes of FRAME.
+FRAME must be a live frame and defaults to the selected one. The return
+value is an association list of the attributes listed below. All height
+and width values are in pixels.
+
+`outer-position' is a cons of the outer left and top edges of FRAME
+ relative to the origin - the position (0, 0) - of FRAME's display.
+
+`outer-size' is a cons of the outer width and height of FRAME. The
+ outer size includes the title bar and the external borders as well as
+ any menu and/or tool bar of frame.
+
+`external-border-size' is a cons of the horizontal and vertical width of
+ FRAME's external borders as supplied by the window manager.
+
+`title-bar-size' is a cons of the width and height of the title bar of
+ FRAME as supplied by the window manager. If both of them are zero,
+ FRAME has no title bar. If only the width is zero, Emacs was not
+ able to retrieve the width information.
+
+`menu-bar-external', if non-nil, means the menu bar is external (never
+ included in the inner edges of FRAME).
+
+`menu-bar-size' is a cons of the width and height of the menu bar of
+ FRAME.
+
+`tool-bar-external', if non-nil, means the tool bar is external (never
+ included in the inner edges of FRAME).
+
+`tool-bar-position' tells on which side the tool bar on FRAME is and can
+ be one of `left', `top', `right' or `bottom'. If this is nil, FRAME
+ has no tool bar.
+
+`tool-bar-size' is a cons of the width and height of the tool bar of
+ FRAME.
+
+`internal-border-width' is the width of the internal border of
+ FRAME. */)
+ (Lisp_Object frame)
+{
+ return frame_geometry (frame, Qnil);
+}
+
+DEFUN ("haiku-frame-edges", Fhaiku_frame_edges, Shaiku_frame_edges, 0, 2, 0,
+ doc: /* Return edge coordinates of FRAME.
+FRAME must be a live frame and defaults to the selected one. The return
+value is a list of the form (LEFT, TOP, RIGHT, BOTTOM). All values are
+in pixels relative to the origin - the position (0, 0) - of FRAME's
+display.
+
+If optional argument TYPE is the symbol `outer-edges', return the outer
+edges of FRAME. The outer edges comprise the decorations of the window
+manager (like the title bar or external borders) as well as any external
+menu or tool bar of FRAME. If optional argument TYPE is the symbol
+`native-edges' or nil, return the native edges of FRAME. The native
+edges exclude the decorations of the window manager and any external
+menu or tool bar of FRAME. If TYPE is the symbol `inner-edges', return
+the inner edges of FRAME. These edges exclude title bar, any borders,
+menu bar or tool bar of FRAME. */)
+ (Lisp_Object frame, Lisp_Object type)
+{
+ return frame_geometry (frame, ((EQ (type, Qouter_edges)
+ || EQ (type, Qinner_edges))
+ ? type
+ : Qnative_edges));
+}
+
+DEFUN ("haiku-read-file-name", Fhaiku_read_file_name, Shaiku_read_file_name, 1, 6, 0,
+ doc: /* Use a graphical panel to read a file name, using prompt PROMPT.
+Optional arg FRAME specifies a frame on which to display the file panel.
+If it is nil, the current frame is used instead.
+The frame being used will be brought to the front of
+the display after the file panel is closed.
+Optional arg DIR, if non-nil, supplies a default directory.
+Optional arg MUSTMATCH, if non-nil, means the returned file or
+directory must exist.
+Optional arg DIR_ONLY_P, if non-nil, means choose only directories.
+Optional arg SAVE_TEXT, if non-nil, specifies some text to show in the entry field. */)
+ (Lisp_Object prompt, Lisp_Object frame,
+ Lisp_Object dir, Lisp_Object mustmatch,
+ Lisp_Object dir_only_p, Lisp_Object save_text)
+{
+ ptrdiff_t idx;
+ if (!x_display_list)
+ error ("Be windowing not initialized");
+
+ if (!NILP (dir))
+ CHECK_STRING (dir);
+
+ if (!NILP (save_text))
+ CHECK_STRING (save_text);
+
+ if (NILP (frame))
+ frame = selected_frame;
+
+ CHECK_STRING (prompt);
+
+ CHECK_LIVE_FRAME (frame);
+ check_window_system (XFRAME (frame));
+
+ idx = SPECPDL_INDEX ();
+ record_unwind_protect_void (unwind_popup);
+
+ struct frame *f = XFRAME (frame);
+
+ FRAME_DISPLAY_INFO (f)->focus_event_frame = f;
+
+ ++popup_activated_p;
+ char *fn = be_popup_file_dialog (!NILP (mustmatch) || !NILP (dir_only_p),
+ !NILP (dir) ? SSDATA (ENCODE_UTF_8 (dir)) : NULL,
+ !NILP (mustmatch), !NILP (dir_only_p),
+ FRAME_HAIKU_WINDOW (f),
+ !NILP (save_text) ? SSDATA (ENCODE_UTF_8 (save_text)) : NULL,
+ SSDATA (ENCODE_UTF_8 (prompt)),
+ block_input, unblock_input);
+
+ unbind_to (idx, Qnil);
+
+ block_input ();
+ BWindow_activate (FRAME_HAIKU_WINDOW (f));
+ unblock_input ();
+
+ if (!fn)
+ return Qnil;
+
+ Lisp_Object p = build_string_from_utf8 (fn);
+ free (fn);
+ return p;
+}
+
+DEFUN ("haiku-put-resource", Fhaiku_put_resource, Shaiku_put_resource,
+ 2, 2, 0, doc: /* Place STRING by the key RESOURCE in the resource database.
+It can later be retrieved with `x-get-resource'. */)
+ (Lisp_Object resource, Lisp_Object string)
+{
+ CHECK_STRING (resource);
+ if (!NILP (string))
+ CHECK_STRING (string);
+
+ put_xrm_resource (resource, string);
+ return Qnil;
+}
+
+DEFUN ("haiku-frame-list-z-order", Fhaiku_frame_list_z_order,
+ Shaiku_frame_list_z_order, 0, 1, 0,
+ doc: /* Return list of Emacs' frames, in Z (stacking) order.
+If TERMINAL is non-nil and specifies a live frame, return the child
+frames of that frame in Z (stacking) order.
+
+As it is impossible to reliably determine the frame stacking order on
+Haiku, the selected frame is always the first element of the returned
+list, while the rest are not guaranteed to be in any particular order.
+
+Frames are listed from topmost (first) to bottommost (last). */)
+ (Lisp_Object terminal)
+{
+ Lisp_Object frames = Qnil;
+ Lisp_Object head, tail;
+ Lisp_Object sel = Qnil;
+
+ FOR_EACH_FRAME (head, tail)
+ {
+ struct frame *f = XFRAME (tail);
+ if (!FRAME_HAIKU_P (f) ||
+ (FRAMEP (terminal) &&
+ FRAME_LIVE_P (XFRAME (terminal)) &&
+ !EQ (terminal, get_frame_param (f, Qparent_frame))))
+ continue;
+
+ if (EQ (tail, selected_frame))
+ sel = tail;
+ else
+ frames = Fcons (tail, frames);
+ }
+
+ if (NILP (sel))
+ return frames;
+ return Fcons (sel, frames);
+}
+
+DEFUN ("x-display-save-under", Fx_display_save_under,
+ Sx_display_save_under, 0, 1, 0,
+ doc: /* SKIP: real doc in xfns.c. */)
+ (Lisp_Object terminal)
+{
+ check_haiku_display_info (terminal);
+
+ if (FRAMEP (terminal))
+ {
+ struct frame *f = decode_window_system_frame (terminal);
+ return FRAME_HAIKU_VIEW (f) && EmacsView_double_buffered_p (FRAME_HAIKU_VIEW (f)) ?
+ Qt : Qnil;
+ }
+
+ return Qnil;
+}
+
+frame_parm_handler haiku_frame_parm_handlers[] =
+ {
+ gui_set_autoraise,
+ gui_set_autolower,
+ haiku_set_background_color,
+ NULL, /* x_set_border_color */
+ gui_set_border_width,
+ haiku_set_cursor_color,
+ haiku_set_cursor_type,
+ gui_set_font,
+ haiku_set_foreground_color,
+ NULL, /* set icon name */
+ NULL, /* set icon type */
+ haiku_set_child_frame_border_width,
+ haiku_set_internal_border_width,
+ gui_set_right_divider_width,
+ gui_set_bottom_divider_width,
+ haiku_set_menu_bar_lines,
+ NULL, /* set mouse color */
+ haiku_explicitly_set_name,
+ gui_set_scroll_bar_width,
+ gui_set_scroll_bar_height,
+ haiku_set_title,
+ gui_set_unsplittable,
+ gui_set_vertical_scroll_bars,
+ gui_set_horizontal_scroll_bars,
+ gui_set_visibility,
+ haiku_set_tab_bar_lines,
+ haiku_set_tool_bar_lines,
+ NULL, /* set scroll bar fg */
+ NULL, /* set scroll bar bkg */
+ gui_set_screen_gamma,
+ gui_set_line_spacing,
+ gui_set_left_fringe,
+ gui_set_right_fringe,
+ NULL, /* x wait for wm */
+ gui_set_fullscreen,
+ gui_set_font_backend,
+ gui_set_alpha,
+ NULL, /* set sticky */
+ NULL, /* set tool bar pos */
+ haiku_set_inhibit_double_buffering,
+ haiku_set_undecorated,
+ haiku_set_parent_frame,
+ NULL, /* set skip taskbar */
+ haiku_set_no_focus_on_map,
+ haiku_set_no_accept_focus,
+ NULL, /* set z group */
+ NULL, /* set override redir */
+ gui_set_no_special_glyphs
+ };
+
+void
+syms_of_haikufns (void)
+{
+ DEFSYM (Qfont_parameter, "font-parameter");
+ DEFSYM (Qcancel_timer, "cancel-timer");
+ DEFSYM (Qassq_delete_all, "assq-delete-all");
+
+ DEFSYM (Qalways, "always");
+ DEFSYM (Qnot_useful, "not-useful");
+ DEFSYM (Qwhen_mapped, "when-mapped");
+
+ defsubr (&Sx_hide_tip);
+ defsubr (&Sxw_display_color_p);
+ defsubr (&Sx_display_grayscale_p);
+ defsubr (&Sx_open_connection);
+ defsubr (&Sx_create_frame);
+ defsubr (&Sx_display_pixel_width);
+ defsubr (&Sx_display_pixel_height);
+ defsubr (&Sxw_color_values);
+ defsubr (&Sxw_color_defined_p);
+ defsubr (&Sx_display_visual_class);
+ defsubr (&Sx_show_tip);
+ defsubr (&Sx_display_mm_height);
+ defsubr (&Sx_display_mm_width);
+ defsubr (&Sx_close_connection);
+ defsubr (&Sx_display_list);
+ defsubr (&Sx_server_vendor);
+ defsubr (&Sx_server_version);
+ defsubr (&Sx_display_screens);
+ defsubr (&Shaiku_get_version_string);
+ defsubr (&Sx_display_color_cells);
+ defsubr (&Sx_display_planes);
+ defsubr (&Shaiku_set_mouse_absolute_pixel_position);
+ defsubr (&Shaiku_mouse_absolute_pixel_position);
+ defsubr (&Shaiku_frame_geometry);
+ defsubr (&Shaiku_frame_edges);
+ defsubr (&Sx_double_buffered_p);
+ defsubr (&Sx_display_backing_store);
+ defsubr (&Shaiku_read_file_name);
+ defsubr (&Shaiku_put_resource);
+ defsubr (&Shaiku_frame_list_z_order);
+ defsubr (&Sx_display_save_under);
+
+ tip_timer = Qnil;
+ staticpro (&tip_timer);
+ tip_frame = Qnil;
+ staticpro (&tip_frame);
+ tip_last_frame = Qnil;
+ staticpro (&tip_last_frame);
+ tip_last_string = Qnil;
+ staticpro (&tip_last_string);
+ tip_last_parms = Qnil;
+ staticpro (&tip_last_parms);
+
+ DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size,
+ doc: /* SKIP: real doc in xfns.c. */);
+ Vx_max_tooltip_size = Fcons (make_fixnum (80), make_fixnum (40));
+
+ DEFVAR_BOOL ("haiku-use-system-tooltips", haiku_use_system_tooltips,
+ doc: /* When non-nil, Emacs will display tooltips using the App Kit.
+This can avoid a great deal of consing that does not play
+well with the Haiku memory allocator, but comes with the
+disadvantage of not being able to use special display properties
+within tooltips. */);
+ haiku_use_system_tooltips = 1;
+
+#ifdef USE_BE_CAIRO
+ DEFVAR_LISP ("cairo-version-string", Vcairo_version_string,
+ doc: /* Version info for cairo. */);
+ {
+ char cairo_version[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
+ int len = sprintf (cairo_version, "%d.%d.%d",
+ CAIRO_VERSION_MAJOR, CAIRO_VERSION_MINOR,
+ CAIRO_VERSION_MICRO);
+ Vcairo_version_string = make_pure_string (cairo_version, len, len, false);
+ }
+#endif
+
+ return;
+}
diff --git a/src/haikufont.c b/src/haikufont.c
new file mode 100644
index 00000000000..811fa62a848
--- /dev/null
+++ b/src/haikufont.c
@@ -0,0 +1,1072 @@
+/* Font support for Haiku windowing
+
+Copyright (C) 2021 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/>. */
+
+#include <config.h>
+
+#include "lisp.h"
+#include "dispextern.h"
+#include "composite.h"
+#include "blockinput.h"
+#include "charset.h"
+#include "frame.h"
+#include "window.h"
+#include "fontset.h"
+#include "haikuterm.h"
+#include "character.h"
+#include "font.h"
+#include "termchar.h"
+#include "pdumper.h"
+#include "haiku_support.h"
+
+#include <math.h>
+#include <stdlib.h>
+
+static Lisp_Object font_cache;
+
+#define METRICS_NCOLS_PER_ROW (128)
+
+enum metrics_status
+ {
+ METRICS_INVALID = -1, /* metrics entry is invalid */
+ };
+
+#define METRICS_STATUS(metrics) ((metrics)->ascent + (metrics)->descent)
+#define METRICS_SET_STATUS(metrics, status) \
+ ((metrics)->ascent = 0, (metrics)->descent = (status))
+
+static struct
+{
+ /* registry name */
+ const char *name;
+ /* characters to distinguish the charset from the others */
+ int uniquifier[6];
+ /* additional constraint by language */
+ const char *lang;
+} em_charset_table[] =
+ { { "iso8859-1", { 0x00A0, 0x00A1, 0x00B4, 0x00BC, 0x00D0 } },
+ { "iso8859-2", { 0x00A0, 0x010E }},
+ { "iso8859-3", { 0x00A0, 0x0108 }},
+ { "iso8859-4", { 0x00A0, 0x00AF, 0x0128, 0x0156, 0x02C7 }},
+ { "iso8859-5", { 0x00A0, 0x0401 }},
+ { "iso8859-6", { 0x00A0, 0x060C }},
+ { "iso8859-7", { 0x00A0, 0x0384 }},
+ { "iso8859-8", { 0x00A0, 0x05D0 }},
+ { "iso8859-9", { 0x00A0, 0x00A1, 0x00BC, 0x011E }},
+ { "iso8859-10", { 0x00A0, 0x00D0, 0x0128, 0x2015 }},
+ { "iso8859-11", { 0x00A0, 0x0E01 }},
+ { "iso8859-13", { 0x00A0, 0x201C }},
+ { "iso8859-14", { 0x00A0, 0x0174 }},
+ { "iso8859-15", { 0x00A0, 0x00A1, 0x00D0, 0x0152 }},
+ { "iso8859-16", { 0x00A0, 0x0218}},
+ { "gb2312.1980-0", { 0x4E13 }, "zh-cn"},
+ { "big5-0", { 0x9C21 }, "zh-tw" },
+ { "jisx0208.1983-0", { 0x4E55 }, "ja"},
+ { "ksc5601.1985-0", { 0xAC00 }, "ko"},
+ { "cns11643.1992-1", { 0xFE32 }, "zh-tw"},
+ { "cns11643.1992-2", { 0x4E33, 0x7934 }},
+ { "cns11643.1992-3", { 0x201A9 }},
+ { "cns11643.1992-4", { 0x20057 }},
+ { "cns11643.1992-5", { 0x20000 }},
+ { "cns11643.1992-6", { 0x20003 }},
+ { "cns11643.1992-7", { 0x20055 }},
+ { "gbk-0", { 0x4E06 }, "zh-cn"},
+ { "jisx0212.1990-0", { 0x4E44 }},
+ { "jisx0213.2000-1", { 0xFA10 }, "ja"},
+ { "jisx0213.2000-2", { 0xFA49 }},
+ { "jisx0213.2004-1", { 0x20B9F }},
+ { "viscii1.1-1", { 0x1EA0, 0x1EAE, 0x1ED2 }, "vi"},
+ { "tis620.2529-1", { 0x0E01 }, "th"},
+ { "microsoft-cp1251", { 0x0401, 0x0490 }, "ru"},
+ { "koi8-r", { 0x0401, 0x2219 }, "ru"},
+ { "mulelao-1", { 0x0E81 }, "lo"},
+ { "unicode-sip", { 0x20000 }},
+ { "mulearabic-0", { 0x628 }},
+ { "mulearabic-1", { 0x628 }},
+ { "mulearabic-2", { 0x628 }},
+ { NULL }
+ };
+
+static void
+haikufont_apply_registry (struct haiku_font_pattern *pattern,
+ Lisp_Object registry)
+{
+ char *str = SSDATA (SYMBOL_NAME (registry));
+ USE_SAFE_ALLOCA;
+ char *re = SAFE_ALLOCA (SBYTES (SYMBOL_NAME (registry)) * 2 + 1);
+ int i, j;
+
+ for (i = j = 0; i < SBYTES (SYMBOL_NAME (registry)); i++, j++)
+ {
+ if (str[i] == '.')
+ re[j++] = '\\';
+ else if (str[i] == '*')
+ re[j++] = '.';
+ re[j] = str[i];
+ if (re[j] == '?')
+ re[j] = '.';
+ }
+ re[j] = '\0';
+ AUTO_STRING_WITH_LEN (regexp, re, j);
+ for (i = 0; em_charset_table[i].name; i++)
+ if (fast_c_string_match_ignore_case
+ (regexp, em_charset_table[i].name,
+ strlen (em_charset_table[i].name)) >= 0)
+ break;
+ SAFE_FREE ();
+ if (!em_charset_table[i].name)
+ return;
+ int *uniquifier = em_charset_table[i].uniquifier;
+ int l;
+
+ for (l = 0; uniquifier[l]; ++l);
+
+ uint32_t *a = xmalloc (l * sizeof *a);
+ for (l = 0; uniquifier[l]; ++l)
+ a[l] = uniquifier[l];
+
+ if (pattern->specified & FSPEC_WANTED)
+ {
+ int old_l = l;
+ l += pattern->want_chars_len;
+ a = xrealloc (a, l * sizeof *a);
+ memcpy (&a[old_l], pattern->wanted_chars, (l - old_l) * sizeof *a);
+ xfree (pattern->wanted_chars);
+ }
+ pattern->specified |= FSPEC_WANTED;
+ pattern->want_chars_len = l;
+ pattern->wanted_chars = a;
+
+ if (em_charset_table[i].lang)
+ {
+ if (!strncmp (em_charset_table[i].lang, "zh", 2))
+ {
+ pattern->specified |= FSPEC_LANGUAGE;
+ pattern->language = LANGUAGE_CN;
+ }
+ else if (!strncmp (em_charset_table[i].lang, "ko", 2))
+ {
+ pattern->specified |= FSPEC_LANGUAGE;
+ pattern->language = LANGUAGE_KO;
+ }
+ else if (!strncmp (em_charset_table[i].lang, "ja", 2))
+ {
+ pattern->specified |= FSPEC_LANGUAGE;
+ pattern->language = LANGUAGE_JP;
+ }
+ }
+
+ return;
+}
+
+static Lisp_Object
+haikufont_get_fallback_entity (void)
+{
+ Lisp_Object ent = font_make_entity ();
+ ASET (ent, FONT_TYPE_INDEX, Qhaiku);
+ ASET (ent, FONT_FOUNDRY_INDEX, Qhaiku);
+ ASET (ent, FONT_FAMILY_INDEX, Qnil);
+ ASET (ent, FONT_ADSTYLE_INDEX, Qnil);
+ ASET (ent, FONT_REGISTRY_INDEX, Qutf_8);
+ ASET (ent, FONT_SIZE_INDEX, make_fixnum (0));
+ ASET (ent, FONT_AVGWIDTH_INDEX, make_fixnum (0));
+ ASET (ent, FONT_SPACING_INDEX, make_fixnum (FONT_SPACING_MONO));
+ FONT_SET_STYLE (ent, FONT_WIDTH_INDEX, Qnil);
+ FONT_SET_STYLE (ent, FONT_WEIGHT_INDEX, Qnil);
+ FONT_SET_STYLE (ent, FONT_SLANT_INDEX, Qnil);
+
+ return ent;
+}
+
+static Lisp_Object
+haikufont_get_cache (struct frame *frame)
+{
+ return font_cache;
+}
+
+static Lisp_Object
+haikufont_weight_to_lisp (int weight)
+{
+ switch (weight)
+ {
+ case HAIKU_THIN:
+ return Qthin;
+ case HAIKU_ULTRALIGHT:
+ return Qultra_light;
+ case HAIKU_EXTRALIGHT:
+ return Qextra_light;
+ case HAIKU_LIGHT:
+ return Qlight;
+ case HAIKU_SEMI_LIGHT:
+ return Qsemi_light;
+ case HAIKU_REGULAR:
+ return Qnormal;
+ case HAIKU_SEMI_BOLD:
+ return Qsemi_bold;
+ case HAIKU_BOLD:
+ return Qbold;
+ case HAIKU_EXTRA_BOLD:
+ return Qextra_bold;
+ case HAIKU_ULTRA_BOLD:
+ return Qultra_bold;
+ case HAIKU_BOOK:
+ return Qbook;
+ case HAIKU_HEAVY:
+ return Qheavy;
+ case HAIKU_ULTRA_HEAVY:
+ return Qultra_heavy;
+ case HAIKU_BLACK:
+ return Qblack;
+ case HAIKU_MEDIUM:
+ return Qmedium;
+ }
+ emacs_abort ();
+}
+
+static int
+haikufont_lisp_to_weight (Lisp_Object weight)
+{
+ if (EQ (weight, Qthin))
+ return HAIKU_THIN;
+ if (EQ (weight, Qultra_light))
+ return HAIKU_ULTRALIGHT;
+ if (EQ (weight, Qextra_light))
+ return HAIKU_EXTRALIGHT;
+ if (EQ (weight, Qlight))
+ return HAIKU_LIGHT;
+ if (EQ (weight, Qsemi_light))
+ return HAIKU_SEMI_LIGHT;
+ if (EQ (weight, Qnormal))
+ return HAIKU_REGULAR;
+ if (EQ (weight, Qsemi_bold))
+ return HAIKU_SEMI_BOLD;
+ if (EQ (weight, Qbold))
+ return HAIKU_BOLD;
+ if (EQ (weight, Qextra_bold))
+ return HAIKU_EXTRA_BOLD;
+ if (EQ (weight, Qultra_bold))
+ return HAIKU_ULTRA_BOLD;
+ if (EQ (weight, Qbook))
+ return HAIKU_BOOK;
+ if (EQ (weight, Qheavy))
+ return HAIKU_HEAVY;
+ if (EQ (weight, Qultra_heavy))
+ return HAIKU_ULTRA_HEAVY;
+ if (EQ (weight, Qblack))
+ return HAIKU_BLACK;
+ if (EQ (weight, Qmedium))
+ return HAIKU_MEDIUM;
+
+ emacs_abort ();
+}
+
+static Lisp_Object
+haikufont_slant_to_lisp (enum haiku_font_slant slant)
+{
+ switch (slant)
+ {
+ case NO_SLANT:
+ emacs_abort ();
+ case SLANT_ITALIC:
+ return Qitalic;
+ case SLANT_REGULAR:
+ return Qnormal;
+ case SLANT_OBLIQUE:
+ return Qoblique;
+ }
+ emacs_abort ();
+}
+
+static enum haiku_font_slant
+haikufont_lisp_to_slant (Lisp_Object slant)
+{
+ if (EQ (slant, Qitalic) ||
+ EQ (slant, Qreverse_italic))
+ return SLANT_ITALIC;
+ if (EQ (slant, Qoblique) ||
+ EQ (slant, Qreverse_oblique))
+ return SLANT_OBLIQUE;
+ if (EQ (slant, Qnormal))
+ return SLANT_REGULAR;
+ emacs_abort ();
+}
+
+static Lisp_Object
+haikufont_width_to_lisp (enum haiku_font_width width)
+{
+ switch (width)
+ {
+ case NO_WIDTH:
+ emacs_abort ();
+ case ULTRA_CONDENSED:
+ return Qultra_condensed;
+ case EXTRA_CONDENSED:
+ return Qextra_condensed;
+ case CONDENSED:
+ return Qcondensed;
+ case SEMI_CONDENSED:
+ return Qsemi_condensed;
+ case NORMAL_WIDTH:
+ return Qnormal;
+ case SEMI_EXPANDED:
+ return Qsemi_expanded;
+ case EXPANDED:
+ return Qexpanded;
+ case EXTRA_EXPANDED:
+ return Qextra_expanded;
+ case ULTRA_EXPANDED:
+ return Qultra_expanded;
+ }
+
+ emacs_abort ();
+}
+
+static enum haiku_font_width
+haikufont_lisp_to_width (Lisp_Object lisp)
+{
+ if (EQ (lisp, Qultra_condensed))
+ return ULTRA_CONDENSED;
+ if (EQ (lisp, Qextra_condensed))
+ return EXTRA_CONDENSED;
+ if (EQ (lisp, Qcondensed))
+ return CONDENSED;
+ if (EQ (lisp, Qsemi_condensed))
+ return SEMI_CONDENSED;
+ if (EQ (lisp, Qnormal))
+ return NORMAL_WIDTH;
+ if (EQ (lisp, Qexpanded))
+ return EXPANDED;
+ if (EQ (lisp, Qextra_expanded))
+ return EXTRA_EXPANDED;
+ if (EQ (lisp, Qultra_expanded))
+ return ULTRA_EXPANDED;
+ emacs_abort ();
+}
+
+static int
+haikufont_maybe_handle_special_family (Lisp_Object family,
+ struct haiku_font_pattern *ptn)
+{
+ CHECK_SYMBOL (family);
+
+ if (EQ (family, Qmonospace) || EQ (family, Qfixed) ||
+ EQ (family, Qdefault))
+ {
+ BFont_populate_fixed_family (ptn);
+ return 1;
+ }
+ else if (EQ (family, intern ("Sans Serif")))
+ {
+ BFont_populate_plain_family (ptn);
+ return 1;
+ }
+ return 0;
+}
+
+static Lisp_Object
+haikufont_pattern_to_entity (struct haiku_font_pattern *ptn)
+{
+ Lisp_Object ent = font_make_entity ();
+ ASET (ent, FONT_TYPE_INDEX, Qhaiku);
+ ASET (ent, FONT_FOUNDRY_INDEX, Qhaiku);
+ ASET (ent, FONT_FAMILY_INDEX, Qdefault);
+ ASET (ent, FONT_ADSTYLE_INDEX, Qnil);
+ ASET (ent, FONT_REGISTRY_INDEX, Qutf_8);
+ ASET (ent, FONT_SIZE_INDEX, make_fixnum (0));
+ ASET (ent, FONT_AVGWIDTH_INDEX, make_fixnum (0));
+ ASET (ent, FONT_SPACING_INDEX, make_fixnum (FONT_SPACING_MONO));
+ FONT_SET_STYLE (ent, FONT_WIDTH_INDEX, Qnormal);
+ FONT_SET_STYLE (ent, FONT_WEIGHT_INDEX, Qnormal);
+ FONT_SET_STYLE (ent, FONT_SLANT_INDEX, Qnormal);
+
+ if (ptn->specified & FSPEC_FAMILY)
+ ASET (ent, FONT_FAMILY_INDEX, intern (ptn->family));
+ else
+ ASET (ent, FONT_FAMILY_INDEX, Qdefault);
+
+ if (ptn->specified & FSPEC_STYLE)
+ ASET (ent, FONT_ADSTYLE_INDEX, intern (ptn->style));
+ else
+ {
+ if (ptn->specified & FSPEC_WEIGHT)
+ FONT_SET_STYLE (ent, FONT_WEIGHT_INDEX,
+ haikufont_weight_to_lisp (ptn->weight));
+ if (ptn->specified & FSPEC_SLANT)
+ FONT_SET_STYLE (ent, FONT_SLANT_INDEX,
+ haikufont_slant_to_lisp (ptn->slant));
+ if (ptn->specified & FSPEC_WIDTH)
+ FONT_SET_STYLE (ent, FONT_WIDTH_INDEX,
+ haikufont_width_to_lisp (ptn->width));
+ }
+
+ if (ptn->specified & FSPEC_SPACING)
+ ASET (ent, FONT_SPACING_INDEX,
+ make_fixnum (ptn->mono_spacing_p ?
+ FONT_SPACING_MONO : FONT_SPACING_PROPORTIONAL));
+ return ent;
+}
+
+static void
+haikufont_spec_or_entity_to_pattern (Lisp_Object ent,
+ int list_p,
+ struct haiku_font_pattern *ptn)
+{
+ Lisp_Object tem;
+ ptn->specified = 0;
+
+ tem = AREF (ent, FONT_ADSTYLE_INDEX);
+ if (!NILP (tem))
+ {
+ ptn->specified |= FSPEC_STYLE;
+ strncpy ((char *) &ptn->style,
+ SSDATA (SYMBOL_NAME (tem)),
+ sizeof ptn->style - 1);
+ }
+
+ tem = FONT_SLANT_SYMBOLIC (ent);
+ if (!NILP (tem))
+ {
+ ptn->specified |= FSPEC_SLANT;
+ ptn->slant = haikufont_lisp_to_slant (tem);
+ }
+
+ tem = FONT_WEIGHT_SYMBOLIC (ent);
+ if (!NILP (tem))
+ {
+ ptn->specified |= FSPEC_WEIGHT;
+ ptn->weight = haikufont_lisp_to_weight (tem);
+ }
+
+ tem = FONT_WIDTH_SYMBOLIC (ent);
+ if (!NILP (tem))
+ {
+ ptn->specified |= FSPEC_WIDTH;
+ ptn->width = haikufont_lisp_to_width (tem);
+ }
+
+ tem = AREF (ent, FONT_SPACING_INDEX);
+ if (FIXNUMP (tem))
+ {
+ ptn->specified |= FSPEC_SPACING;
+ ptn->mono_spacing_p = XFIXNUM (tem) != FONT_SPACING_PROPORTIONAL;
+ }
+
+ tem = AREF (ent, FONT_FAMILY_INDEX);
+ if (!NILP (tem) &&
+ (list_p && !haikufont_maybe_handle_special_family (tem, ptn)))
+ {
+ ptn->specified |= FSPEC_FAMILY;
+ strncpy ((char *) &ptn->family,
+ SSDATA (SYMBOL_NAME (tem)),
+ sizeof ptn->family - 1);
+ }
+
+ tem = assq_no_quit (QCscript, AREF (ent, FONT_EXTRA_INDEX));
+ if (!NILP (tem))
+ {
+ tem = assq_no_quit (XCDR (tem), Vscript_representative_chars);
+
+ if (CONSP (tem) && VECTORP (XCDR (tem)))
+ {
+ tem = XCDR (tem);
+
+ int count = 0;
+
+ for (int j = 0; j < ASIZE (tem); ++j)
+ if (TYPE_RANGED_FIXNUMP (uint32_t, AREF (tem, j)))
+ ++count;
+
+ if (count)
+ {
+ ptn->specified |= FSPEC_NEED_ONE_OF;
+ ptn->need_one_of_len = count;
+ ptn->need_one_of = xmalloc (count * sizeof *ptn->need_one_of);
+ count = 0;
+ for (int j = 0; j < ASIZE (tem); ++j)
+ if (TYPE_RANGED_FIXNUMP (uint32_t, AREF (tem, j)))
+ {
+ ptn->need_one_of[j] = XFIXNAT (AREF (tem, j));
+ ++count;
+ }
+ }
+ }
+ else if (CONSP (tem) && CONSP (XCDR (tem)))
+ {
+ int count = 0;
+
+ for (Lisp_Object it = XCDR (tem); CONSP (it); it = XCDR (it))
+ if (TYPE_RANGED_FIXNUMP (uint32_t, XCAR (it)))
+ ++count;
+
+ if (count)
+ {
+ ptn->specified |= FSPEC_WANTED;
+ ptn->want_chars_len = count;
+ ptn->wanted_chars = xmalloc (count * sizeof *ptn->wanted_chars);
+ count = 0;
+
+ for (tem = XCDR (tem); CONSP (tem); tem = XCDR (tem))
+ if (TYPE_RANGED_FIXNUMP (uint32_t, XCAR (tem)))
+ {
+ ptn->wanted_chars[count] = XFIXNAT (XCAR (tem));
+ ++count;
+ }
+ }
+ }
+ }
+
+ tem = assq_no_quit (QClang, AREF (ent, FONT_EXTRA_INDEX));
+ if (CONSP (tem))
+ {
+ tem = XCDR (tem);
+ if (EQ (tem, Qzh))
+ {
+ ptn->specified |= FSPEC_LANGUAGE;
+ ptn->language = LANGUAGE_CN;
+ }
+ else if (EQ (tem, Qko))
+ {
+ ptn->specified |= FSPEC_LANGUAGE;
+ ptn->language = LANGUAGE_KO;
+ }
+ else if (EQ (tem, Qjp))
+ {
+ ptn->specified |= FSPEC_LANGUAGE;
+ ptn->language = LANGUAGE_JP;
+ }
+ }
+
+ tem = AREF (ent, FONT_REGISTRY_INDEX);
+ if (SYMBOLP (tem))
+ haikufont_apply_registry (ptn, tem);
+}
+
+static void
+haikufont_done_with_query_pattern (struct haiku_font_pattern *ptn)
+{
+ if (ptn->specified & FSPEC_WANTED)
+ xfree (ptn->wanted_chars);
+
+ if (ptn->specified & FSPEC_NEED_ONE_OF)
+ xfree (ptn->need_one_of);
+}
+
+static Lisp_Object
+haikufont_match (struct frame *f, Lisp_Object font_spec)
+{
+ block_input ();
+ Lisp_Object tem = Qnil;
+ struct haiku_font_pattern ptn;
+ haikufont_spec_or_entity_to_pattern (font_spec, 0, &ptn);
+ ptn.specified &= ~FSPEC_FAMILY;
+ struct haiku_font_pattern *found = BFont_find (&ptn);
+ haikufont_done_with_query_pattern (&ptn);
+ if (found)
+ {
+ tem = haikufont_pattern_to_entity (found);
+ haiku_font_pattern_free (found);
+ }
+ unblock_input ();
+ return !NILP (tem) ? tem : haikufont_get_fallback_entity ();
+}
+
+static Lisp_Object
+haikufont_list (struct frame *f, Lisp_Object font_spec)
+{
+ block_input ();
+ Lisp_Object lst = Qnil;
+
+ /* Returning irrelevant results on receiving an OTF form will cause
+ fontset.c to loop over and over, making displaying some
+ characters very slow. */
+ Lisp_Object tem = assq_no_quit (QCotf, AREF (font_spec, FONT_EXTRA_INDEX));
+ if (CONSP (tem) && !NILP (XCDR (tem)))
+ {
+ unblock_input ();
+ return Qnil;
+ }
+
+ struct haiku_font_pattern ptn;
+ haikufont_spec_or_entity_to_pattern (font_spec, 1, &ptn);
+ struct haiku_font_pattern *found = BFont_find (&ptn);
+ haikufont_done_with_query_pattern (&ptn);
+ if (found)
+ {
+ for (struct haiku_font_pattern *pt = found;
+ pt; pt = pt->next)
+ lst = Fcons (haikufont_pattern_to_entity (pt), lst);
+ haiku_font_pattern_free (found);
+ }
+ unblock_input ();
+ return lst;
+}
+
+static void
+haiku_bulk_encode (struct haikufont_info *font_info, int block)
+{
+ unsigned short *unichars = xmalloc (0x101 * sizeof (*unichars));
+ unsigned int i, idx;
+
+ block_input ();
+
+ font_info->glyphs[block] = unichars;
+ if (!unichars)
+ emacs_abort ();
+
+ for (idx = block << 8, i = 0; i < 0x100; idx++, i++)
+ unichars[i] = idx;
+ unichars[0x100] = 0;
+
+
+ /* If the font contains the entire block, just store it. */
+ if (!BFont_have_char_block (font_info->be_font,
+ unichars[0], unichars[0xff]))
+ {
+ for (int i = 0; i < 0x100; ++i)
+ if (!BFont_have_char_p (font_info->be_font, unichars[i]))
+ unichars[i] = 0xFFFF;
+ }
+
+ unblock_input ();
+}
+
+static unsigned int
+haikufont_encode_char (struct font *font, int c)
+{
+ struct haikufont_info *font_info = (struct haikufont_info *) font;
+ unsigned char high = (c & 0xff00) >> 8, low = c & 0x00ff;
+ unsigned short g;
+
+ if (c > 0xFFFF)
+ return FONT_INVALID_CODE;
+
+ if (!font_info->glyphs[high])
+ haiku_bulk_encode (font_info, high);
+ g = font_info->glyphs[high][low];
+ return g == 0xFFFF ? FONT_INVALID_CODE : g;
+}
+
+static Lisp_Object
+haikufont_open (struct frame *f, Lisp_Object font_entity, int x)
+{
+ struct haikufont_info *font_info;
+ struct haiku_font_pattern ptn;
+ struct font *font;
+ void *be_font;
+ Lisp_Object font_object;
+ Lisp_Object tem;
+
+ block_input ();
+ if (x <= 0)
+ {
+ /* Get pixel size from frame instead. */
+ tem = get_frame_param (f, Qfontsize);
+ x = NILP (tem) ? 0 : XFIXNAT (tem);
+ }
+
+ haikufont_spec_or_entity_to_pattern (font_entity, 1, &ptn);
+
+ if (BFont_open_pattern (&ptn, &be_font, x))
+ {
+ haikufont_done_with_query_pattern (&ptn);
+ unblock_input ();
+ return Qnil;
+ }
+
+ haikufont_done_with_query_pattern (&ptn);
+
+ font_object = font_make_object (VECSIZE (struct haikufont_info),
+ font_entity, x);
+
+ ASET (font_object, FONT_TYPE_INDEX, Qhaiku);
+ font_info = (struct haikufont_info *) XFONT_OBJECT (font_object);
+ font = (struct font *) font_info;
+
+ if (!font)
+ {
+ unblock_input ();
+ return Qnil;
+ }
+
+ font_info->be_font = be_font;
+ font_info->glyphs = xzalloc (0x100 * sizeof *font_info->glyphs);
+
+ font->pixel_size = 0;
+ font->driver = &haikufont_driver;
+ font->encoding_charset = -1;
+ font->repertory_charset = -1;
+ font->default_ascent = 0;
+ font->vertical_centering = 0;
+ font->baseline_offset = 0;
+ font->relative_compose = 0;
+
+ font_info->metrics = NULL;
+ font_info->metrics_nrows = 0;
+
+ int px_size, min_width, max_width,
+ avg_width, height, space_width, ascent,
+ descent, underline_pos, underline_thickness;
+
+ BFont_dat (be_font, &px_size, &min_width,
+ &max_width, &avg_width, &height,
+ &space_width, &ascent, &descent,
+ &underline_pos, &underline_thickness);
+
+ font->pixel_size = px_size;
+ font->min_width = min_width;
+ font->max_width = max_width;
+ font->average_width = avg_width;
+ font->height = height;
+ font->space_width = space_width;
+ font->ascent = ascent;
+ font->descent = descent;
+ font->default_ascent = ascent;
+ font->underline_position = underline_pos;
+ font->underline_thickness = underline_thickness;
+
+ font->vertical_centering = 0;
+ font->baseline_offset = 0;
+ font->relative_compose = 0;
+
+ font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil);
+
+ unblock_input ();
+ return font_object;
+}
+
+static void
+haikufont_close (struct font *font)
+{
+ if (font_data_structures_may_be_ill_formed ())
+ return;
+ struct haikufont_info *info = (struct haikufont_info *) font;
+
+ block_input ();
+ if (info && info->be_font)
+ BFont_close (info->be_font);
+
+ for (int i = 0; i < info->metrics_nrows; i++)
+ if (info->metrics[i])
+ xfree (info->metrics[i]);
+ if (info->metrics)
+ xfree (info->metrics);
+ for (int i = 0; i < 0x100; ++i)
+ if (info->glyphs[i])
+ xfree (info->glyphs[i]);
+ xfree (info->glyphs);
+ unblock_input ();
+}
+
+static void
+haikufont_prepare_face (struct frame *f, struct face *face)
+{
+
+}
+
+static void
+haikufont_glyph_extents (struct font *font, unsigned code,
+ struct font_metrics *metrics)
+{
+ struct haikufont_info *info = (struct haikufont_info *) font;
+
+ struct font_metrics *cache;
+ int row, col;
+
+ row = code / METRICS_NCOLS_PER_ROW;
+ col = code % METRICS_NCOLS_PER_ROW;
+ if (row >= info->metrics_nrows)
+ {
+ info->metrics =
+ xrealloc (info->metrics,
+ sizeof (struct font_metrics *) * (row + 1));
+ memset (info->metrics + info->metrics_nrows, 0,
+ (sizeof (struct font_metrics *)
+ * (row + 1 - info->metrics_nrows)));
+ info->metrics_nrows = row + 1;
+ }
+
+ if (info->metrics[row] == NULL)
+ {
+ struct font_metrics *new;
+ int i;
+
+ new = xmalloc (sizeof (struct font_metrics) * METRICS_NCOLS_PER_ROW);
+ for (i = 0; i < METRICS_NCOLS_PER_ROW; i++)
+ METRICS_SET_STATUS (new + i, METRICS_INVALID);
+ info->metrics[row] = new;
+ }
+ cache = info->metrics[row] + col;
+
+ if (METRICS_STATUS (cache) == METRICS_INVALID)
+ {
+ unsigned char utf8[MAX_MULTIBYTE_LENGTH];
+ memset (utf8, 0, MAX_MULTIBYTE_LENGTH);
+ CHAR_STRING (code, utf8);
+ int advance, lb, rb;
+ BFont_char_bounds (info->be_font, (const char *) utf8, &advance, &lb, &rb);
+
+ cache->lbearing = lb;
+ cache->rbearing = rb;
+ cache->width = advance;
+ cache->ascent = font->ascent;
+ cache->descent = font->descent;
+ }
+
+ if (metrics)
+ *metrics = *cache;
+}
+
+static void
+haikufont_text_extents (struct font *font, const unsigned int *code,
+ int nglyphs, struct font_metrics *metrics)
+{
+ int totalwidth = 0;
+ memset (metrics, 0, sizeof (struct font_metrics));
+
+ block_input ();
+ for (int i = 0; i < nglyphs; i++)
+ {
+ struct font_metrics m;
+ haikufont_glyph_extents (font, code[i], &m);
+ if (metrics)
+ {
+ if (totalwidth + m.lbearing < metrics->lbearing)
+ metrics->lbearing = totalwidth + m.lbearing;
+ if (totalwidth + m.rbearing > metrics->rbearing)
+ metrics->rbearing = totalwidth + m.rbearing;
+ if (m.ascent > metrics->ascent)
+ metrics->ascent = m.ascent;
+ if (m.descent > metrics->descent)
+ metrics->descent = m.descent;
+ }
+ totalwidth += m.width;
+ }
+
+ unblock_input ();
+
+ if (metrics)
+ metrics->width = totalwidth;
+}
+
+static Lisp_Object
+haikufont_shape (Lisp_Object lgstring, Lisp_Object direction)
+{
+ struct haikufont_info *font =
+ (struct haikufont_info *) CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
+ int *advance, *lb, *rb;
+ ptrdiff_t glyph_len, len, i, b_len;
+ Lisp_Object tem;
+ char *b;
+ uint32_t *mb_buf;
+
+ glyph_len = LGSTRING_GLYPH_LEN (lgstring);
+ for (i = 0; i < glyph_len; ++i)
+ {
+ tem = LGSTRING_GLYPH (lgstring, i);
+
+ if (NILP (tem))
+ break;
+ }
+
+ len = i;
+
+ if (INT_MAX / 2 < len)
+ memory_full (SIZE_MAX);
+
+ block_input ();
+
+ b_len = 0;
+ b = xmalloc (b_len);
+ mb_buf = alloca (len * sizeof *mb_buf);
+
+ for (i = b_len; i < len; ++i)
+ {
+ uint32_t c = LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, i));
+ mb_buf[i] = c;
+ unsigned char mb[MAX_MULTIBYTE_LENGTH];
+ int slen = CHAR_STRING (c, mb);
+
+ b = xrealloc (b, b_len = (b_len + slen));
+ if (len == 1)
+ b[b_len - slen] = mb[0];
+ else
+ memcpy (b + b_len - slen, mb, slen);
+ }
+
+ advance = alloca (len * sizeof *advance);
+ lb = alloca (len * sizeof *lb);
+ rb = alloca (len * sizeof *rb);
+
+ eassert (font->be_font);
+ BFont_nchar_bounds (font->be_font, b, advance, lb, rb, len);
+ xfree (b);
+
+ for (i = 0; i < len; ++i)
+ {
+ tem = LGSTRING_GLYPH (lgstring, i);
+ if (NILP (tem))
+ {
+ tem = LGLYPH_NEW ();
+ LGSTRING_SET_GLYPH (lgstring, i, tem);
+ }
+
+ LGLYPH_SET_FROM (tem, i);
+ LGLYPH_SET_TO (tem, i);
+ LGLYPH_SET_CHAR (tem, mb_buf[i]);
+ LGLYPH_SET_CODE (tem, mb_buf[i]);
+
+ LGLYPH_SET_WIDTH (tem, advance[i]);
+ LGLYPH_SET_LBEARING (tem, lb[i]);
+ LGLYPH_SET_RBEARING (tem, rb[i]);
+ LGLYPH_SET_ASCENT (tem, font->font.ascent);
+ LGLYPH_SET_DESCENT (tem, font->font.descent);
+ }
+
+ unblock_input ();
+
+ return make_fixnum (len);
+}
+
+static int
+haikufont_draw (struct glyph_string *s, int from, int to,
+ int x, int y, bool with_background)
+{
+ struct frame *f = s->f;
+ struct face *face = s->face;
+ struct font_info *info = (struct font_info *) s->font;
+ unsigned char mb[MAX_MULTIBYTE_LENGTH];
+ void *view = FRAME_HAIKU_VIEW (f);
+
+ block_input ();
+ prepare_face_for_display (s->f, face);
+
+ BView_draw_lock (view);
+ BView_StartClip (view);
+ if (with_background)
+ {
+ int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font);
+
+ /* Font's global height and ascent values might be
+ preposterously large for some fonts. We fix here the case
+ when those fonts are used for display of glyphless
+ characters, because drawing background with font dimensions
+ in those cases makes the display illegible. There's only one
+ more call to the draw method with with_background set to
+ true, and that's in x_draw_glyph_string_foreground, when
+ drawing the cursor, where we have no such heuristics
+ available. FIXME. */
+ if (s->first_glyph->type == GLYPHLESS_GLYPH
+ && (s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE
+ || s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM))
+ height = ascent =
+ s->first_glyph->slice.glyphless.lower_yoff
+ - s->first_glyph->slice.glyphless.upper_yoff;
+
+ BView_SetHighColor (view, s->hl == DRAW_CURSOR ?
+ FRAME_CURSOR_COLOR (s->f).pixel : face->background);
+
+ BView_FillRectangle (view, x, y - ascent, s->width, height);
+ s->background_filled_p = 1;
+ }
+
+ if (s->left_overhang && s->clip_head && !s->for_overlaps)
+ {
+ /* XXX: Why is this neccessary? */
+ BView_ClipToRect (view, s->clip_head->x, 0,
+ FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+ }
+
+ if (s->hl == DRAW_CURSOR)
+ BView_SetHighColor (view, FRAME_OUTPUT_DATA (s->f)->cursor_fg);
+ else
+ BView_SetHighColor (view, face->foreground);
+
+ BView_MovePenTo (view, x, y);
+ BView_SetFont (view, ((struct haikufont_info *) info)->be_font);
+
+ if (from == to)
+ {
+ int len = CHAR_STRING (s->char2b[from], mb);
+ BView_DrawString (view, (char *) mb, len);
+ }
+ else
+ {
+ ptrdiff_t b_len = 0;
+ char *b = xmalloc (b_len);
+
+ for (int idx = from; idx < to; ++idx)
+ {
+ int len = CHAR_STRING (s->char2b[idx], mb);
+ b = xrealloc (b, b_len = (b_len + len));
+ if (len == 1)
+ b[b_len - len] = mb[0];
+ else
+ memcpy (b + b_len - len, mb, len);
+ }
+
+ BView_DrawString (view, b, b_len);
+ xfree (b);
+ }
+ BView_EndClip (view);
+ BView_draw_unlock (view);
+ unblock_input ();
+ return 1;
+}
+
+struct font_driver const haikufont_driver =
+ {
+ .type = LISPSYM_INITIALLY (Qhaiku),
+ .case_sensitive = true,
+ .get_cache = haikufont_get_cache,
+ .list = haikufont_list,
+ .match = haikufont_match,
+ .draw = haikufont_draw,
+ .open_font = haikufont_open,
+ .close_font = haikufont_close,
+ .prepare_face = haikufont_prepare_face,
+ .encode_char = haikufont_encode_char,
+ .text_extents = haikufont_text_extents,
+ .shape = haikufont_shape
+ };
+
+void
+syms_of_haikufont (void)
+{
+ DEFSYM (Qfontsize, "fontsize");
+ DEFSYM (Qfixed, "fixed");
+ DEFSYM (Qplain, "plain");
+ DEFSYM (Qultra_light, "ultra-light");
+ DEFSYM (Qthin, "thin");
+ DEFSYM (Qreverse_italic, "reverse-italic");
+ DEFSYM (Qreverse_oblique, "reverse-oblique");
+ DEFSYM (Qmonospace, "monospace");
+ DEFSYM (Qultra_condensed, "ultra-condensed");
+ DEFSYM (Qextra_condensed, "extra-condensed");
+ DEFSYM (Qcondensed, "condensed");
+ DEFSYM (Qsemi_condensed, "semi-condensed");
+ DEFSYM (Qsemi_expanded, "semi-expanded");
+ DEFSYM (Qexpanded, "expanded");
+ DEFSYM (Qextra_expanded, "extra-expanded");
+ DEFSYM (Qultra_expanded, "ultra-expanded");
+ DEFSYM (Qzh, "zh");
+ DEFSYM (Qko, "ko");
+ DEFSYM (Qjp, "jp");
+
+ font_cache = list (Qnil);
+ staticpro (&font_cache);
+}
diff --git a/src/haikugui.h b/src/haikugui.h
new file mode 100644
index 00000000000..cfc693fb552
--- /dev/null
+++ b/src/haikugui.h
@@ -0,0 +1,106 @@
+/* Haiku window system support
+ Copyright (C) 2021 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/>. */
+
+#ifndef _HAIKU_GUI_H_
+#define _HAIKU_GUI_H_
+
+#ifdef _cplusplus
+extern "C"
+{
+#endif
+
+typedef struct haiku_char_struct
+{
+ int rbearing;
+ int lbearing;
+ int width;
+ int ascent;
+ int descent;
+} XCharStruct;
+
+struct haiku_rect
+{
+ int x, y;
+ int width, height;
+};
+
+typedef void *haiku;
+
+typedef haiku Emacs_Pixmap;
+typedef haiku Emacs_Window;
+typedef haiku Emacs_Cursor;
+typedef haiku Drawable;
+
+#define NativeRectangle struct haiku_rect
+#define CONVERT_TO_EMACS_RECT(xr, nr) \
+ ((xr).x = (nr).x, \
+ (xr).y = (nr).y, \
+ (xr).width = (nr).width, \
+ (xr).height = (nr).height)
+
+#define CONVERT_FROM_EMACS_RECT(xr, nr) \
+ ((nr).x = (xr).x, \
+ (nr).y = (xr).y, \
+ (nr).width = (xr).width, \
+ (nr).height = (xr).height)
+
+#define STORE_NATIVE_RECT(nr, px, py, pwidth, pheight) \
+ ((nr).x = (px), \
+ (nr).y = (py), \
+ (nr).width = (pwidth), \
+ (nr).height = (pheight))
+
+#define ForgetGravity 0
+#define NorthWestGravity 1
+#define NorthGravity 2
+#define NorthEastGravity 3
+#define WestGravity 4
+#define CenterGravity 5
+#define EastGravity 6
+#define SouthWestGravity 7
+#define SouthGravity 8
+#define SouthEastGravity 9
+#define StaticGravity 10
+
+#define NoValue 0x0000
+#define XValue 0x0001
+#define YValue 0x0002
+#define WidthValue 0x0004
+#define HeightValue 0x0008
+#define AllValues 0x000F
+#define XNegative 0x0010
+#define YNegative 0x0020
+
+#define USPosition (1L << 0) /* user specified x, y */
+#define USSize (1L << 1) /* user specified width, height */
+#define PPosition (1L << 2) /* program specified position */
+#define PSize (1L << 3) /* program specified size */
+#define PMinSize (1L << 4) /* program specified minimum size */
+#define PMaxSize (1L << 5) /* program specified maximum size */
+#define PResizeInc (1L << 6) /* program specified resize increments */
+#define PAspect (1L << 7) /* program specified min, max aspect ratios */
+#define PBaseSize (1L << 8) /* program specified base for incrementing */
+#define PWinGravity (1L << 9) /* program specified window gravity */
+
+typedef haiku Window;
+typedef int Display;
+
+#ifdef _cplusplus
+};
+#endif
+#endif /* _HAIKU_GUI_H_ */
diff --git a/src/haikuimage.c b/src/haikuimage.c
new file mode 100644
index 00000000000..138e5b84e6a
--- /dev/null
+++ b/src/haikuimage.c
@@ -0,0 +1,109 @@
+/* Haiku window system support.
+ Copyright (C) 2021 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/>. */
+
+#include <config.h>
+
+#include "lisp.h"
+#include "dispextern.h"
+#include "haikuterm.h"
+#include "coding.h"
+
+#include "haiku_support.h"
+
+bool
+haiku_can_use_native_image_api (Lisp_Object type)
+{
+ const char *mime_type = NULL;
+
+ if (EQ (type, Qnative_image))
+ return 1;
+
+#ifdef HAVE_RSVG
+ if (EQ (type, Qsvg))
+ return 0;
+#endif
+
+ if (EQ (type, Qjpeg))
+ mime_type = "image/jpeg";
+ else if (EQ (type, Qpng))
+ mime_type = "image/png";
+ else if (EQ (type, Qgif))
+ mime_type = "image/gif";
+ else if (EQ (type, Qtiff))
+ mime_type = "image/tiff";
+ else if (EQ (type, Qbmp))
+ mime_type = "image/bmp";
+ else if (EQ (type, Qsvg))
+ mime_type = "image/svg";
+ else if (EQ (type, Qpbm))
+ mime_type = "image/pbm";
+
+ if (!mime_type)
+ return 0;
+
+ return be_can_translate_type_to_bitmap_p (mime_type);
+}
+
+extern int
+haiku_load_image (struct frame *f, struct image *img,
+ Lisp_Object spec_file, Lisp_Object spec_data)
+{
+ eassert (valid_image_p (img->spec));
+
+ void *pixmap = NULL;
+
+ if (STRINGP (spec_file))
+ {
+ pixmap = be_translate_bitmap_from_file_name
+ (SSDATA (ENCODE_UTF_8 (spec_file)));
+ }
+ else if (STRINGP (spec_data))
+ {
+ pixmap = be_translate_bitmap_from_memory
+ (SSDATA (spec_data), SBYTES (spec_data));
+ }
+
+ void *conv = NULL;
+
+ if (!pixmap || !BBitmap_convert (pixmap, &conv))
+ {
+ add_to_log ("Unable to load image %s", img->spec);
+ return 0;
+ }
+
+ if (conv)
+ {
+ BBitmap_free (pixmap);
+ pixmap = conv;
+ }
+
+ int left, top, right, bottom, stride, mono_p;
+ BBitmap_dimensions (pixmap, &left, &top, &right, &bottom, &stride, &mono_p);
+
+ img->width = (1 + right - left);
+ img->height = (1 + bottom - top);
+ img->pixmap = pixmap;
+
+ return 1;
+}
+
+void
+syms_of_haikuimage (void)
+{
+ DEFSYM (Qbmp, "bmp");
+}
diff --git a/src/haikumenu.c b/src/haikumenu.c
new file mode 100644
index 00000000000..698da9d639c
--- /dev/null
+++ b/src/haikumenu.c
@@ -0,0 +1,656 @@
+/* Haiku window system support
+ Copyright (C) 2021 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/>. */
+
+#include <config.h>
+
+#include "lisp.h"
+#include "frame.h"
+#include "keyboard.h"
+#include "menu.h"
+#include "buffer.h"
+#include "blockinput.h"
+
+#include "haikuterm.h"
+#include "haiku_support.h"
+
+static Lisp_Object *volatile menu_item_selection;
+
+int popup_activated_p = 0;
+
+struct submenu_stack_cell
+{
+ void *parent_menu;
+ void *pane;
+};
+
+static void
+digest_menu_items (void *first_menu, int start, int menu_items_used,
+ int mbar_p)
+{
+ void **menus, **panes;
+ ssize_t menu_len = (menu_items_used + 1 - start) * sizeof *menus;
+ ssize_t pane_len = (menu_items_used + 1 - start) * sizeof *panes;
+
+ menus = alloca (menu_len);
+ panes = alloca (pane_len);
+
+ int i = start, menu_depth = 0;
+
+ memset (menus, 0, menu_len);
+ memset (panes, 0, pane_len);
+
+ void *menu = first_menu;
+
+ menus[0] = first_menu;
+
+ void *window = NULL;
+ if (FRAMEP (Vmenu_updating_frame) &&
+ FRAME_LIVE_P (XFRAME (Vmenu_updating_frame)) &&
+ FRAME_HAIKU_P (XFRAME (Vmenu_updating_frame)))
+ window = FRAME_HAIKU_WINDOW (XFRAME (Vmenu_updating_frame));
+
+ while (i < menu_items_used)
+ {
+ if (NILP (AREF (menu_items, i)))
+ {
+ menus[++menu_depth] = menu;
+ i++;
+ }
+ else if (EQ (AREF (menu_items, i), Qlambda))
+ {
+ panes[menu_depth] = NULL;
+ menu = panes[--menu_depth] ? panes[menu_depth] : menus[menu_depth];
+ i++;
+ }
+ else if (EQ (AREF (menu_items, i), Qquote))
+ i += 1;
+ else if (EQ (AREF (menu_items, i), Qt))
+ {
+ Lisp_Object pane_name, prefix;
+ const char *pane_string;
+
+ if (menu_items_n_panes == 1)
+ {
+ i += MENU_ITEMS_PANE_LENGTH;
+ continue;
+ }
+
+ pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
+ prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
+
+ if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
+ {
+ pane_name = ENCODE_UTF_8 (pane_name);
+ ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
+ }
+
+ pane_string = (NILP (pane_name)
+ ? "" : SSDATA (pane_name));
+ if (!NILP (prefix))
+ pane_string++;
+
+ if (strcmp (pane_string, ""))
+ {
+ panes[menu_depth] =
+ menu = BMenu_new_submenu (menus[menu_depth], pane_string, 1);
+ }
+
+ i += MENU_ITEMS_PANE_LENGTH;
+ }
+ else
+ {
+ Lisp_Object item_name, enable, descrip, def, selected, help;
+ item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
+ enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
+ descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
+ def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION);
+ selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
+ help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
+
+ if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
+ {
+ item_name = ENCODE_UTF_8 (item_name);
+ ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
+ }
+
+ if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
+ {
+ descrip = ENCODE_UTF_8 (descrip);
+ ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
+ }
+
+ if (STRINGP (help) && STRING_MULTIBYTE (help))
+ {
+ help = ENCODE_UTF_8 (help);
+ ASET (menu_items, i + MENU_ITEMS_ITEM_HELP, help);
+ }
+
+ if (i + MENU_ITEMS_ITEM_LENGTH < menu_items_used &&
+ NILP (AREF (menu_items, i + MENU_ITEMS_ITEM_LENGTH)))
+ menu = BMenu_new_submenu (menu, SSDATA (item_name), !NILP (enable));
+ else if (NILP (def) && menu_separator_name_p (SSDATA (item_name)))
+ BMenu_add_separator (menu);
+ else if (!mbar_p)
+ BMenu_add_item (menu, SSDATA (item_name),
+ !NILP (def) ? aref_addr (menu_items, i) : NULL,
+ !NILP (enable), !NILP (selected), 0, window,
+ !NILP (descrip) ? SSDATA (descrip) : NULL,
+ STRINGP (help) ? SSDATA (help) : NULL);
+ else
+ BMenu_add_item (menu, SSDATA (item_name),
+ !NILP (def) ? (void *) (intptr_t) i : NULL,
+ !NILP (enable), !NILP (selected), 1, window,
+ !NILP (descrip) ? SSDATA (descrip) : NULL,
+ STRINGP (help) ? SSDATA (help) : NULL);
+
+ i += MENU_ITEMS_ITEM_LENGTH;
+ }
+ }
+}
+
+static Lisp_Object
+haiku_dialog_show (struct frame *f, Lisp_Object title,
+ Lisp_Object header, const char **error_name)
+{
+ int i, nb_buttons = 0;
+
+ *error_name = NULL;
+
+ if (menu_items_n_panes > 1)
+ {
+ *error_name = "Multiple panes in dialog box";
+ return Qnil;
+ }
+
+ Lisp_Object pane_name = AREF (menu_items, MENU_ITEMS_PANE_NAME);
+ i = MENU_ITEMS_PANE_LENGTH;
+
+ if (STRING_MULTIBYTE (pane_name))
+ pane_name = ENCODE_UTF_8 (pane_name);
+
+ block_input ();
+ void *alert = BAlert_new (SSDATA (pane_name), NILP (header) ? HAIKU_INFO_ALERT :
+ HAIKU_IDEA_ALERT);
+
+ Lisp_Object vals[10];
+
+ while (i < menu_items_used)
+ {
+ Lisp_Object item_name, enable, descrip, value;
+ item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
+ enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
+ descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
+ value = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
+
+ if (NILP (item_name))
+ {
+ BAlert_delete (alert);
+ *error_name = "Submenu in dialog items";
+ unblock_input ();
+ return Qnil;
+ }
+
+ if (EQ (item_name, Qquote))
+ {
+ i++;
+ }
+
+ if (nb_buttons >= 9)
+ {
+ BAlert_delete (alert);
+ *error_name = "Too many dialog items";
+ unblock_input ();
+ return Qnil;
+ }
+
+ if (STRING_MULTIBYTE (item_name))
+ item_name = ENCODE_UTF_8 (item_name);
+ if (!NILP (descrip) && STRING_MULTIBYTE (descrip))
+ descrip = ENCODE_UTF_8 (descrip);
+
+ void *button = BAlert_add_button (alert, SSDATA (item_name));
+
+ BButton_set_enabled (button, !NILP (enable));
+ if (!NILP (descrip))
+ BView_set_tooltip (button, SSDATA (descrip));
+
+ vals[nb_buttons] = value;
+ ++nb_buttons;
+ i += MENU_ITEMS_ITEM_LENGTH;
+ }
+
+ int32_t val = BAlert_go (alert);
+ unblock_input ();
+
+ if (val < 0)
+ quit ();
+ else
+ return vals[val];
+
+ return Qnil;
+}
+
+Lisp_Object
+haiku_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
+{
+ Lisp_Object title;
+ const char *error_name = NULL;
+ Lisp_Object selection;
+ ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+
+ check_window_system (f);
+
+ /* Decode the dialog items from what was specified. */
+ title = Fcar (contents);
+ CHECK_STRING (title);
+ record_unwind_protect_void (unuse_menu_items);
+
+ if (NILP (Fcar (Fcdr (contents))))
+ /* No buttons specified, add an "Ok" button so users can pop down
+ the dialog. Also, the lesstif/motif version crashes if there are
+ no buttons. */
+ contents = list2 (title, Fcons (build_string ("Ok"), Qt));
+
+ list_of_panes (list1 (contents));
+
+ /* Display them in a dialog box. */
+ block_input ();
+ selection = haiku_dialog_show (f, title, header, &error_name);
+ unblock_input ();
+
+ unbind_to (specpdl_count, Qnil);
+ discard_menu_items ();
+
+ if (error_name)
+ error ("%s", error_name);
+ return selection;
+}
+
+Lisp_Object
+haiku_menu_show (struct frame *f, int x, int y, int menuflags,
+ Lisp_Object title, const char **error_name)
+{
+ int i = 0, submenu_depth = 0;
+ void *view = FRAME_HAIKU_VIEW (f);
+ void *menu;
+
+ Lisp_Object *subprefix_stack =
+ alloca (menu_items_used * sizeof (Lisp_Object));
+
+ eassert (FRAME_HAIKU_P (f));
+
+ *error_name = NULL;
+
+ if (menu_items_used <= MENU_ITEMS_PANE_LENGTH)
+ {
+ *error_name = "Empty menu";
+ return Qnil;
+ }
+
+ block_input ();
+ if (STRINGP (title) && STRING_MULTIBYTE (title))
+ title = ENCODE_UTF_8 (title);
+
+ menu = BPopUpMenu_new (STRINGP (title) ? SSDATA (title) : NULL);
+ if (STRINGP (title))
+ {
+ BMenu_add_title (menu, SSDATA (title));
+ BMenu_add_separator (menu);
+ }
+ digest_menu_items (menu, 0, menu_items_used, 0);
+ BView_convert_to_screen (view, &x, &y);
+ unblock_input ();
+
+ menu_item_selection = BMenu_run (menu, x, y);
+
+ FRAME_DISPLAY_INFO (f)->grabbed = 0;
+
+ if (menu_item_selection)
+ {
+ Lisp_Object prefix, entry;
+
+ prefix = entry = Qnil;
+ i = 0;
+ while (i < menu_items_used)
+ {
+ if (NILP (AREF (menu_items, i)))
+ {
+ subprefix_stack[submenu_depth++] = prefix;
+ prefix = entry;
+ i++;
+ }
+ else if (EQ (AREF (menu_items, i), Qlambda))
+ {
+ prefix = subprefix_stack[--submenu_depth];
+ i++;
+ }
+ else if (EQ (AREF (menu_items, i), Qt))
+ {
+ prefix
+ = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
+ i += MENU_ITEMS_PANE_LENGTH;
+ }
+ /* Ignore a nil in the item list.
+ It's meaningful only for dialog boxes. */
+ else if (EQ (AREF (menu_items, i), Qquote))
+ i += 1;
+ else
+ {
+ entry
+ = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
+ if (menu_item_selection == aref_addr (menu_items, i))
+ {
+ if (menuflags & MENU_KEYMAPS)
+ {
+ int j;
+
+ entry = list1 (entry);
+ if (!NILP (prefix))
+ entry = Fcons (prefix, entry);
+ for (j = submenu_depth - 1; j >= 0; j--)
+ if (!NILP (subprefix_stack[j]))
+ entry = Fcons (subprefix_stack[j], entry);
+ }
+ BPopUpMenu_delete (menu);
+ return entry;
+ }
+ i += MENU_ITEMS_ITEM_LENGTH;
+ }
+ }
+ }
+ else if (!(menuflags & MENU_FOR_CLICK))
+ {
+ BPopUpMenu_delete (menu);
+ quit ();
+ }
+ BPopUpMenu_delete (menu);
+ return Qnil;
+}
+
+void
+free_frame_menubar (struct frame *f)
+{
+ FRAME_MENU_BAR_LINES (f) = 0;
+ FRAME_MENU_BAR_HEIGHT (f) = 0;
+ FRAME_EXTERNAL_MENU_BAR (f) = 0;
+
+ block_input ();
+ void *mbar = FRAME_HAIKU_MENU_BAR (f);
+ if (mbar)
+ BMenuBar_delete (mbar);
+ if (FRAME_OUTPUT_DATA (f)->menu_bar_open_p)
+ --popup_activated_p;
+ FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 0;
+ unblock_input ();
+
+ adjust_frame_size (f, -1, -1, 2, false, Qmenu_bar_lines);
+}
+
+void
+initialize_frame_menubar (struct frame *f)
+{
+ /* This function is called before the first chance to redisplay
+ the frame. It has to be, so the frame will have the right size. */
+ fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
+ set_frame_menubar (f, true);
+}
+
+void
+set_frame_menubar (struct frame *f, bool deep_p)
+{
+ void *mbar = FRAME_HAIKU_MENU_BAR (f);
+ void *view = FRAME_HAIKU_VIEW (f);
+
+ int first_time_p = 0;
+
+ if (!mbar)
+ {
+ mbar = FRAME_HAIKU_MENU_BAR (f) = BMenuBar_new (view);
+ first_time_p = 1;
+ }
+
+ Lisp_Object items;
+ struct buffer *prev = current_buffer;
+ Lisp_Object buffer;
+ ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+ int previous_menu_items_used = f->menu_bar_items_used;
+ Lisp_Object *previous_items
+ = alloca (previous_menu_items_used * sizeof *previous_items);
+
+ XSETFRAME (Vmenu_updating_frame, f);
+
+ if (!deep_p)
+ {
+ FRAME_OUTPUT_DATA (f)->menu_up_to_date_p = 0;
+ items = FRAME_MENU_BAR_ITEMS (f);
+ Lisp_Object string;
+
+ block_input ();
+ int count = BMenu_count_items (mbar);
+
+ int i;
+ for (i = 0; i < ASIZE (items); i += 4)
+ {
+ string = AREF (items, i + 1);
+
+ if (!STRINGP (string))
+ break;
+
+ if (STRING_MULTIBYTE (string))
+ string = ENCODE_UTF_8 (string);
+
+ if (i / 4 < count)
+ {
+ void *it = BMenu_item_at (mbar, i / 4);
+ BMenu_item_set_label (it, SSDATA (string));
+ }
+ else
+ BMenu_new_menu_bar_submenu (mbar, SSDATA (string));
+ }
+
+ if (i / 4 < count)
+ BMenu_delete_from (mbar, i / 4, count - i / 4 + 1);
+ unblock_input ();
+
+ f->menu_bar_items_used = 0;
+ }
+ else
+ {
+ /* If we are making a new widget, its contents are empty,
+ do always reinitialize them. */
+ if (first_time_p)
+ previous_menu_items_used = 0;
+ buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
+ specbind (Qinhibit_quit, Qt);
+ /* Don't let the debugger step into this code
+ because it is not reentrant. */
+ specbind (Qdebug_on_next_call, Qnil);
+
+ record_unwind_save_match_data ();
+ if (NILP (Voverriding_local_map_menu_flag))
+ {
+ specbind (Qoverriding_terminal_local_map, Qnil);
+ specbind (Qoverriding_local_map, Qnil);
+ }
+
+ set_buffer_internal_1 (XBUFFER (buffer));
+
+ /* Run the Lucid hook. */
+ safe_run_hooks (Qactivate_menubar_hook);
+
+ /* If it has changed current-menubar from previous value,
+ really recompute the menubar from the value. */
+ if (! NILP (Vlucid_menu_bar_dirty_flag))
+ call0 (Qrecompute_lucid_menubar);
+ safe_run_hooks (Qmenu_bar_update_hook);
+ fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
+
+ items = FRAME_MENU_BAR_ITEMS (f);
+
+ /* Save the frame's previous menu bar contents data. */
+ if (previous_menu_items_used)
+ memcpy (previous_items, xvector_contents (f->menu_bar_vector),
+ previous_menu_items_used * word_size);
+
+ /* Fill in menu_items with the current menu bar contents.
+ This can evaluate Lisp code. */
+ save_menu_items ();
+ menu_items = f->menu_bar_vector;
+ menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
+ init_menu_items ();
+ int i;
+ int count = BMenu_count_items (mbar);
+ int subitems = ASIZE (items) / 4;
+
+ int *submenu_start, *submenu_end, *submenu_n_panes;
+ Lisp_Object *submenu_names;
+
+ submenu_start = alloca ((subitems + 1) * sizeof *submenu_start);
+ submenu_end = alloca (subitems * sizeof *submenu_end);
+ submenu_n_panes = alloca (subitems * sizeof *submenu_n_panes);
+ submenu_names = alloca (subitems * sizeof (Lisp_Object));
+
+ for (i = 0; i < subitems; ++i)
+ {
+ Lisp_Object key, string, maps;
+
+ key = AREF (items, i * 4);
+ string = AREF (items, i * 4 + 1);
+ maps = AREF (items, i * 4 + 2);
+
+ if (NILP (string))
+ break;
+
+ if (STRINGP (string) && STRING_MULTIBYTE (string))
+ string = ENCODE_UTF_8 (string);
+
+ submenu_start[i] = menu_items_used;
+ menu_items_n_panes = 0;
+ parse_single_submenu (key, string, maps);
+ submenu_n_panes[i] = menu_items_n_panes;
+ submenu_end[i] = menu_items_used;
+ submenu_names[i] = string;
+ }
+ finish_menu_items ();
+ submenu_start[i] = -1;
+
+ block_input ();
+ for (i = 0; submenu_start[i] >= 0; ++i)
+ {
+ void *mn = NULL;
+ if (i < count)
+ mn = BMenu_item_get_menu (BMenu_item_at (mbar, i));
+ if (mn)
+ BMenu_delete_all (mn);
+ else
+ mn = BMenu_new_menu_bar_submenu (mbar, SSDATA (submenu_names[i]));
+
+ menu_items_n_panes = submenu_n_panes[i];
+ digest_menu_items (mn, submenu_start[i], submenu_end[i], 1);
+ }
+ unblock_input ();
+
+ set_buffer_internal_1 (prev);
+
+ FRAME_OUTPUT_DATA (f)->menu_up_to_date_p = 1;
+ fset_menu_bar_vector (f, menu_items);
+ f->menu_bar_items_used = menu_items_used;
+ }
+ unbind_to (specpdl_count, Qnil);
+}
+
+void
+run_menu_bar_help_event (struct frame *f, int mb_idx)
+{
+ Lisp_Object frame;
+ Lisp_Object vec;
+ Lisp_Object help;
+
+ block_input ();
+ if (!FRAME_OUTPUT_DATA (f)->menu_up_to_date_p)
+ {
+ unblock_input ();
+ return;
+ }
+
+ XSETFRAME (frame, f);
+
+ if (mb_idx < 0)
+ {
+ kbd_buffer_store_help_event (frame, Qnil);
+ unblock_input ();
+ return;
+ }
+
+ vec = f->menu_bar_vector;
+ if (mb_idx >= ASIZE (vec))
+ emacs_abort ();
+
+ help = AREF (vec, mb_idx + MENU_ITEMS_ITEM_HELP);
+ if (STRINGP (help) || NILP (help))
+ kbd_buffer_store_help_event (frame, help);
+ unblock_input ();
+}
+
+DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p,
+ 0, 0, 0, doc: /* SKIP: real doc in xmenu.c. */)
+ (void)
+{
+ return popup_activated_p ? Qt : Qnil;
+}
+
+DEFUN ("haiku-menu-bar-open", Fhaiku_menu_bar_open, Shaiku_menu_bar_open, 0, 1, "i",
+ doc: /* Show the menu bar in FRAME.
+
+Move the mouse pointer onto the first element of FRAME's menu bar, and
+cause it to be opened. If FRAME is nil or not given, use the selected
+frame. If FRAME has no menu bar, a pop-up is displayed at the position
+of the last non-menu event instead. */)
+ (Lisp_Object frame)
+{
+ struct frame *f = decode_window_system_frame (frame);
+
+ if (FRAME_EXTERNAL_MENU_BAR (f))
+ {
+ if (!FRAME_OUTPUT_DATA (f)->menu_up_to_date_p)
+ set_frame_menubar (f, 1);
+ }
+ else
+ {
+ return call2 (Qpopup_menu, call0 (Qmouse_menu_bar_map),
+ last_nonmenu_event);
+ }
+
+ block_input ();
+ BMenuBar_start_tracking (FRAME_HAIKU_MENU_BAR (f));
+ unblock_input ();
+
+ return Qnil;
+}
+
+void
+syms_of_haikumenu (void)
+{
+ DEFSYM (Qdebug_on_next_call, "debug-on-next-call");
+ DEFSYM (Qpopup_menu, "popup-menu");
+ DEFSYM (Qmouse_menu_bar_map, "mouse-menu-bar-map");
+
+ defsubr (&Smenu_or_popup_active_p);
+ defsubr (&Shaiku_menu_bar_open);
+ return;
+}
diff --git a/src/haikuselect.c b/src/haikuselect.c
new file mode 100644
index 00000000000..38cceb1de74
--- /dev/null
+++ b/src/haikuselect.c
@@ -0,0 +1,180 @@
+/* Haiku window system selection support.
+ Copyright (C) 2021 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/>. */
+
+#include <config.h>
+
+#include "lisp.h"
+#include "blockinput.h"
+#include "coding.h"
+#include "haikuselect.h"
+#include "haikuterm.h"
+
+static Lisp_Object
+haiku_selection_data_1 (Lisp_Object clipboard)
+{
+ Lisp_Object result = Qnil;
+ char *targets[256];
+
+ block_input ();
+ if (EQ (clipboard, QPRIMARY))
+ BClipboard_primary_targets ((char **) &targets, 256);
+ else if (EQ (clipboard, QSECONDARY))
+ BClipboard_secondary_targets ((char **) &targets, 256);
+ else if (EQ (clipboard, QCLIPBOARD))
+ BClipboard_system_targets ((char **) &targets, 256);
+ else
+ {
+ unblock_input ();
+ signal_error ("Bad clipboard", clipboard);
+ }
+
+ for (int i = 0; targets[i]; ++i)
+ {
+ result = Fcons (build_unibyte_string (targets[i]),
+ result);
+ free (targets[i]);
+ }
+ unblock_input ();
+
+ return result;
+}
+
+DEFUN ("haiku-selection-targets", Fhaiku_selection_targets,
+ Shaiku_selection_targets, 1, 1, 0,
+ doc: /* Find the types of data available from CLIPBOARD.
+CLIPBOARD should be the symbol `PRIMARY', `SECONDARY' or `CLIPBOARD'.
+Return the available types as a list of strings. */)
+ (Lisp_Object clipboard)
+{
+ return haiku_selection_data_1 (clipboard);
+}
+
+DEFUN ("haiku-selection-data", Fhaiku_selection_data, Shaiku_selection_data,
+ 2, 2, 0,
+ doc: /* Retrieve content typed as NAME from the clipboard
+CLIPBOARD. CLIPBOARD is the symbol `PRIMARY', `SECONDARY' or
+`CLIPBOARD'. NAME is a MIME type denoting the type of the data to
+fetch. */)
+ (Lisp_Object clipboard, Lisp_Object name)
+{
+ CHECK_SYMBOL (clipboard);
+ CHECK_STRING (name);
+ char *dat;
+ ssize_t len;
+
+ block_input ();
+ if (EQ (clipboard, QPRIMARY))
+ dat = BClipboard_find_primary_selection_data (SSDATA (name), &len);
+ else if (EQ (clipboard, QSECONDARY))
+ dat = BClipboard_find_secondary_selection_data (SSDATA (name), &len);
+ else if (EQ (clipboard, QCLIPBOARD))
+ dat = BClipboard_find_system_data (SSDATA (name), &len);
+ else
+ {
+ unblock_input ();
+ signal_error ("Bad clipboard", clipboard);
+ }
+ unblock_input ();
+
+ if (!dat)
+ return Qnil;
+
+ Lisp_Object str = make_unibyte_string (dat, len);
+ Lisp_Object lispy_type = Qnil;
+
+ if (!strcmp (SSDATA (name), "text/utf-8") ||
+ !strcmp (SSDATA (name), "text/plain"))
+ {
+ if (string_ascii_p (str))
+ lispy_type = QSTRING;
+ else
+ lispy_type = QUTF8_STRING;
+ }
+
+ if (!NILP (lispy_type))
+ Fput_text_property (make_fixnum (0), make_fixnum (len),
+ Qforeign_selection, lispy_type, str);
+
+ block_input ();
+ BClipboard_free_data (dat);
+ unblock_input ();
+
+ return str;
+}
+
+DEFUN ("haiku-selection-put", Fhaiku_selection_put, Shaiku_selection_put,
+ 3, 4, 0,
+ doc: /* Add or remove content from the clipboard CLIPBOARD.
+CLIPBOARD is the symbol `PRIMARY', `SECONDARY' or `CLIPBOARD'. NAME
+is a MIME type denoting the type of the data to add. DATA is the
+string that will be placed in the clipboard, or nil if the content is
+to be removed. If NAME is the string "text/utf-8" or the string
+"text/plain", encode it as UTF-8 before storing it into the clipboard.
+CLEAR, if non-nil, means to erase all the previous contents of the
+clipboard. */)
+ (Lisp_Object clipboard, Lisp_Object name, Lisp_Object data,
+ Lisp_Object clear)
+{
+ CHECK_SYMBOL (clipboard);
+ CHECK_STRING (name);
+ if (!NILP (data))
+ CHECK_STRING (data);
+
+ block_input ();
+ /* It seems that Haiku applications counter-intuitively expect
+ UTF-8 data in both text/utf-8 and text/plain. */
+ if (!NILP (data) && STRING_MULTIBYTE (data) &&
+ (!strcmp (SSDATA (name), "text/utf-8") ||
+ !strcmp (SSDATA (name), "text/plain")))
+ data = ENCODE_UTF_8 (data);
+
+ char *dat = !NILP (data) ? SSDATA (data) : NULL;
+ ptrdiff_t len = !NILP (data) ? SBYTES (data) : 0;
+
+ if (EQ (clipboard, QPRIMARY))
+ BClipboard_set_primary_selection_data (SSDATA (name), dat, len,
+ !NILP (clear));
+ else if (EQ (clipboard, QSECONDARY))
+ BClipboard_set_secondary_selection_data (SSDATA (name), dat, len,
+ !NILP (clear));
+ else if (EQ (clipboard, QCLIPBOARD))
+ BClipboard_set_system_data (SSDATA (name), dat, len, !NILP (clear));
+ else
+ {
+ unblock_input ();
+ signal_error ("Bad clipboard", clipboard);
+ }
+ unblock_input ();
+
+ return Qnil;
+}
+
+void
+syms_of_haikuselect (void)
+{
+ DEFSYM (QSECONDARY, "SECONDARY");
+ DEFSYM (QCLIPBOARD, "CLIPBOARD");
+ DEFSYM (QSTRING, "STRING");
+ DEFSYM (QUTF8_STRING, "UTF8_STRING");
+ DEFSYM (Qforeign_selection, "foreign-selection");
+ DEFSYM (QTARGETS, "TARGETS");
+
+ defsubr (&Shaiku_selection_data);
+ defsubr (&Shaiku_selection_put);
+ defsubr (&Shaiku_selection_targets);
+}
diff --git a/src/haikuselect.h b/src/haikuselect.h
new file mode 100644
index 00000000000..1a3a945f98d
--- /dev/null
+++ b/src/haikuselect.h
@@ -0,0 +1,74 @@
+/* Haiku window system selection support. Hey Emacs, this is -*- C++ -*-
+ Copyright (C) 2021 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/>. */
+
+#ifndef _HAIKU_SELECT_H_
+#define _HAIKU_SELECT_H_
+
+#ifdef __cplusplus
+#include <cstdio>
+#endif
+
+#ifdef __cplusplus
+#include <stdio.h>
+extern "C"
+{
+ extern void init_haiku_select (void);
+#endif
+
+ /* Whether or not the selection was recently changed. */
+ extern int selection_state_flag;
+
+ /* Find a string with the MIME type TYPE in the system clipboard. */
+ extern char *
+ BClipboard_find_system_data (const char *type, ssize_t *len);
+
+ /* Ditto, but for the primary selection and not clipboard. */
+ extern char *
+ BClipboard_find_primary_selection_data (const char *type, ssize_t *len);
+
+ /* Ditto, this time for the secondary selection. */
+ extern char *
+ BClipboard_find_secondary_selection_data (const char *type, ssize_t *len);
+
+ extern void
+ BClipboard_set_system_data (const char *type, const char *data, ssize_t len,
+ bool clear);
+
+ extern void
+ BClipboard_set_primary_selection_data (const char *type, const char *data,
+ ssize_t len, bool clear);
+
+ extern void
+ BClipboard_set_secondary_selection_data (const char *type, const char *data,
+ ssize_t len, bool clear);
+
+ extern void
+ BClipboard_system_targets (char **buf, int len);
+
+ extern void
+ BClipboard_primary_targets (char **buf, int len);
+
+ extern void
+ BClipboard_secondary_targets (char **buf, int len);
+
+ /* Free the returned data. */
+ extern void BClipboard_free_data (void *ptr);
+#ifdef __cplusplus
+};
+#endif
+#endif /* _HAIKU_SELECT_H_ */
diff --git a/src/haikuterm.c b/src/haikuterm.c
new file mode 100644
index 00000000000..24fa44b01d0
--- /dev/null
+++ b/src/haikuterm.c
@@ -0,0 +1,3647 @@
+/* Haiku window system support
+ Copyright (C) 2021 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/>. */
+
+#include <config.h>
+
+#include "dispextern.h"
+#include "frame.h"
+#include "lisp.h"
+#include "haikugui.h"
+#include "keyboard.h"
+#include "haikuterm.h"
+#include "blockinput.h"
+#include "termchar.h"
+#include "termhooks.h"
+#include "menu.h"
+#include "buffer.h"
+#include "haiku_support.h"
+#include "thread.h"
+#include "window.h"
+
+#include <math.h>
+#include <stdlib.h>
+
+#ifdef USE_BE_CAIRO
+#include <cairo.h>
+#endif
+
+struct haiku_display_info *x_display_list = NULL;
+extern frame_parm_handler haiku_frame_parm_handlers[];
+
+static void **fringe_bmps;
+static int fringe_bitmap_fillptr = 0;
+
+static Lisp_Object rdb;
+
+struct unhandled_event
+{
+ struct unhandled_event *next;
+ enum haiku_event_type type;
+ uint8_t buffer[200];
+};
+
+char *
+get_keysym_name (int keysym)
+{
+ static char value[16];
+ sprintf (value, "%d", keysym);
+ return value;
+}
+
+static struct frame *
+haiku_window_to_frame (void *window)
+{
+ Lisp_Object tail, tem;
+ struct frame *f;
+
+ FOR_EACH_FRAME (tail, tem)
+ {
+ f = XFRAME (tem);
+ if (!FRAME_HAIKU_P (f))
+ continue;
+
+ eassert (FRAME_DISPLAY_INFO (f) == x_display_list);
+
+ if (FRAME_HAIKU_WINDOW (f) == window)
+ return f;
+ }
+
+ return 0;
+}
+
+static void
+haiku_coords_from_parent (struct frame *f, int *x, int *y)
+{
+ struct frame *p = FRAME_PARENT_FRAME (f);
+ eassert (p);
+
+ for (struct frame *parent = p; parent;
+ parent = FRAME_PARENT_FRAME (parent))
+ {
+ *x -= parent->left_pos;
+ *y -= parent->top_pos;
+ }
+}
+
+static void
+haiku_delete_terminal (struct terminal *terminal)
+{
+ emacs_abort ();
+}
+
+static const char *
+get_string_resource (void *ignored, const char *name, const char *class)
+{
+ if (!name)
+ return NULL;
+
+ Lisp_Object lval = assoc_no_quit (build_string (name), rdb);
+
+ if (!NILP (lval))
+ return SSDATA (XCDR (lval));
+
+ return NULL;
+}
+
+static void
+haiku_update_size_hints (struct frame *f)
+{
+ int base_width, base_height;
+ eassert (FRAME_HAIKU_P (f) && FRAME_HAIKU_WINDOW (f));
+
+ base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
+ base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
+
+ block_input ();
+ BWindow_set_size_alignment (FRAME_HAIKU_WINDOW (f),
+ frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f),
+ frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f));
+ BWindow_set_min_size (FRAME_HAIKU_WINDOW (f), base_width,
+ base_height
+ + FRAME_TOOL_BAR_HEIGHT (f)
+ + FRAME_MENU_BAR_HEIGHT (f));
+ unblock_input ();
+}
+
+static void
+haiku_clip_to_string (struct glyph_string *s)
+{
+ struct haiku_rect r[2];
+ int n = get_glyph_string_clip_rects (s, (struct haiku_rect *) &r, 2);
+
+ if (n)
+ BView_ClipToRect (FRAME_HAIKU_VIEW (s->f), r[0].x, r[0].y,
+ r[0].width, r[0].height);
+ if (n > 1)
+ {
+ BView_ClipToRect (FRAME_HAIKU_VIEW (s->f), r[1].x, r[1].y,
+ r[1].width, r[1].height);
+ }
+
+ s->num_clips = n;
+}
+
+static void
+haiku_clip_to_string_exactly (struct glyph_string *s, struct glyph_string *dst)
+{
+ BView_ClipToRect (FRAME_HAIKU_VIEW (s->f), s->x, s->y,
+ s->width, s->height);
+ dst->num_clips = 1;
+}
+
+static void
+haiku_flip_buffers (struct frame *f)
+{
+ void *view = FRAME_OUTPUT_DATA (f)->view;
+ block_input ();
+
+ BView_draw_lock (view);
+ FRAME_DIRTY_P (f) = 0;
+ EmacsView_flip_and_blit (view);
+ BView_draw_unlock (view);
+
+ unblock_input ();
+}
+
+static void
+haiku_frame_up_to_date (struct frame *f)
+{
+ block_input ();
+ FRAME_MOUSE_UPDATE (f);
+ if (FRAME_DIRTY_P (f) && !buffer_flipping_blocked_p ())
+ haiku_flip_buffers (f);
+ unblock_input ();
+}
+
+static void
+haiku_buffer_flipping_unblocked_hook (struct frame *f)
+{
+ if (FRAME_DIRTY_P (f))
+ haiku_flip_buffers (f);
+}
+
+static void
+haiku_clear_frame_area (struct frame *f, int x, int y,
+ int width, int height)
+{
+ void *vw = FRAME_HAIKU_VIEW (f);
+ block_input ();
+ BView_draw_lock (vw);
+ BView_StartClip (vw);
+ BView_ClipToRect (vw, x, y, width, height);
+ BView_SetHighColor (vw, FRAME_BACKGROUND_PIXEL (f));
+ BView_FillRectangle (vw, x, y, width, height);
+ BView_EndClip (vw);
+ BView_draw_unlock (vw);
+ unblock_input ();
+}
+
+static void
+haiku_clear_frame (struct frame *f)
+{
+ void *view = FRAME_HAIKU_VIEW (f);
+ block_input ();
+ BView_draw_lock (view);
+ BView_StartClip (view);
+ BView_ClipToRect (view, 0, 0, FRAME_PIXEL_WIDTH (f) + 1,
+ FRAME_PIXEL_HEIGHT (f) + 1);
+ BView_SetHighColor (view, FRAME_BACKGROUND_PIXEL (f));
+ BView_FillRectangle (view, 0, 0, FRAME_PIXEL_WIDTH (f) + 1,
+ FRAME_PIXEL_HEIGHT (f) + 1);
+ BView_EndClip (view);
+ BView_draw_unlock (view);
+ unblock_input ();
+}
+
+/* Give frame F the font FONT-OBJECT as its default font. The return
+ value is FONT-OBJECT. FONTSET is an ID of the fontset for the
+ frame. If it is negative, generate a new fontset from
+ FONT-OBJECT. */
+
+static Lisp_Object
+haiku_new_font (struct frame *f, Lisp_Object font_object, int fontset)
+{
+ struct font *font = XFONT_OBJECT (font_object);
+ if (fontset < 0)
+ fontset = fontset_from_font (font_object);
+
+ FRAME_FONTSET (f) = fontset;
+ if (FRAME_FONT (f) == font)
+ return font_object;
+
+ FRAME_FONT (f) = font;
+ FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
+ FRAME_COLUMN_WIDTH (f) = font->average_width;
+
+ int ascent, descent;
+ get_font_ascent_descent (font, &ascent, &descent);
+ FRAME_LINE_HEIGHT (f) = ascent + descent;
+ FRAME_TAB_BAR_HEIGHT (f) = FRAME_TAB_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
+
+ int unit = FRAME_COLUMN_WIDTH (f);
+ if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
+ FRAME_CONFIG_SCROLL_BAR_COLS (f)
+ = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
+ else
+ FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
+
+ if (FRAME_HAIKU_WINDOW (f))
+ {
+ adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
+ FRAME_LINES (f) * FRAME_LINE_HEIGHT (f),
+ 3, false, Qfont);
+
+ haiku_clear_under_internal_border (f);
+ }
+ return font_object;
+}
+
+static int
+haiku_valid_modifier_p (Lisp_Object sym)
+{
+ return EQ (sym, Qcommand) || EQ (sym, Qshift)
+ || EQ (sym, Qcontrol) || EQ (sym, Qoption);
+}
+
+#define MODIFIER_OR(obj, def) (haiku_valid_modifier_p (obj) ? obj : def)
+
+static void
+haiku_add_modifier (int modifier, int toput, Lisp_Object qtem, int *modifiers)
+{
+ if ((modifier & HAIKU_MODIFIER_ALT && EQ (qtem, Qcommand))
+ || (modifier & HAIKU_MODIFIER_SHIFT && EQ (qtem, Qshift))
+ || (modifier & HAIKU_MODIFIER_CTRL && EQ (qtem, Qcontrol))
+ || (modifier & HAIKU_MODIFIER_SUPER && EQ (qtem, Qoption)))
+ *modifiers |= toput;
+}
+
+static int
+haiku_modifiers_to_emacs (int haiku_key)
+{
+ int modifiers = 0;
+ haiku_add_modifier (haiku_key, shift_modifier,
+ MODIFIER_OR (Vhaiku_shift_keysym, Qshift), &modifiers);
+ haiku_add_modifier (haiku_key, super_modifier,
+ MODIFIER_OR (Vhaiku_super_keysym, Qoption), &modifiers);
+ haiku_add_modifier (haiku_key, meta_modifier,
+ MODIFIER_OR (Vhaiku_meta_keysym, Qcommand), &modifiers);
+ haiku_add_modifier (haiku_key, ctrl_modifier,
+ MODIFIER_OR (Vhaiku_control_keysym, Qcontrol), &modifiers);
+ return modifiers;
+}
+
+#undef MODIFIER_OR
+
+static void
+haiku_rehighlight (void)
+{
+ eassert (x_display_list && !x_display_list->next);
+
+ block_input ();
+
+ struct frame *old_hl = x_display_list->highlight_frame;
+
+ if (x_display_list->focused_frame)
+ {
+ x_display_list->highlight_frame
+ = ((FRAMEP (FRAME_FOCUS_FRAME (x_display_list->focused_frame)))
+ ? XFRAME (FRAME_FOCUS_FRAME (x_display_list->focused_frame))
+ : x_display_list->focused_frame);
+ if (!FRAME_LIVE_P (x_display_list->highlight_frame))
+ {
+ fset_focus_frame (x_display_list->focused_frame, Qnil);
+ x_display_list->highlight_frame = x_display_list->focused_frame;
+ }
+ }
+ else
+ x_display_list->highlight_frame = 0;
+
+ if (old_hl)
+ gui_update_cursor (old_hl, true);
+
+ if (x_display_list->highlight_frame)
+ gui_update_cursor (x_display_list->highlight_frame, true);
+ unblock_input ();
+}
+
+static void
+haiku_frame_raise_lower (struct frame *f, bool raise_p)
+{
+ if (raise_p)
+ {
+ block_input ();
+ BWindow_activate (FRAME_HAIKU_WINDOW (f));
+ flush_frame (f);
+ unblock_input ();
+ }
+}
+
+/* Unfortunately, NOACTIVATE is not implementable on Haiku. */
+static void
+haiku_focus_frame (struct frame *frame, bool noactivate)
+{
+ if (x_display_list->focused_frame != frame)
+ haiku_frame_raise_lower (frame, 1);
+}
+
+static void
+haiku_new_focus_frame (struct frame *frame)
+{
+ eassert (x_display_list && !x_display_list->next);
+
+ block_input ();
+ if (frame != x_display_list->focused_frame)
+ {
+ if (x_display_list->focused_frame &&
+ x_display_list->focused_frame->auto_lower)
+ haiku_frame_raise_lower (x_display_list->focused_frame, 0);
+
+ x_display_list->focused_frame = frame;
+
+ if (frame && frame->auto_raise)
+ haiku_frame_raise_lower (frame, 1);
+ }
+ unblock_input ();
+
+ haiku_rehighlight ();
+}
+
+static void
+haiku_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ haiku_set_name (f, arg, 0);
+}
+
+static void
+haiku_query_frame_background_color (struct frame *f, Emacs_Color *bgcolor)
+{
+ haiku_query_color (FRAME_BACKGROUND_PIXEL (f), bgcolor);
+}
+
+static bool
+haiku_defined_color (struct frame *f,
+ const char *name,
+ Emacs_Color *color,
+ bool alloc,
+ bool make_index)
+{
+ return !haiku_get_color (name, color);
+}
+
+/* Adapted from xterm `x_draw_box_rect'. */
+static void
+haiku_draw_box_rect (struct glyph_string *s,
+ int left_x, int top_y, int right_x, int bottom_y, int hwidth,
+ int vwidth, bool left_p, bool right_p, struct haiku_rect *clip_rect)
+{
+ void *view = FRAME_HAIKU_VIEW (s->f);
+ struct face *face = s->face;
+
+ BView_StartClip (view);
+ BView_SetHighColor (view, face->box_color);
+ if (clip_rect)
+ BView_ClipToRect (view, clip_rect->x, clip_rect->y, clip_rect->width,
+ clip_rect->height);
+ BView_FillRectangle (view, left_x, top_y, right_x - left_x + 1, hwidth);
+ if (left_p)
+ BView_FillRectangle (view, left_x, top_y, vwidth, bottom_y - top_y + 1);
+
+ BView_FillRectangle (view, left_x, bottom_y - hwidth + 1,
+ right_x - left_x + 1, hwidth);
+ if (right_p)
+ BView_FillRectangle (view, right_x - vwidth + 1,
+ top_y, vwidth, bottom_y - top_y + 1);
+ BView_EndClip (view);
+}
+
+static void
+haiku_calculate_relief_colors (struct glyph_string *s,
+ uint32_t *rgbout_w, uint32_t *rgbout_b,
+ uint32_t *rgbout_c)
+{
+ struct face *face = s->face;
+
+ prepare_face_for_display (s->f, s->face);
+
+ uint32_t rgbin = face->use_box_color_for_shadows_p
+ ? face->box_color : face->background;
+
+ if (s->hl == DRAW_CURSOR)
+ rgbin = FRAME_CURSOR_COLOR (s->f).pixel;
+
+ double h, cs, l;
+ rgb_color_hsl (rgbin, &h, &cs, &l);
+
+ hsl_color_rgb (h, cs, fmin (1.0, fmax (0.2, l) * 0.6), rgbout_b);
+ hsl_color_rgb (h, cs, fmin (1.0, fmax (0.2, l) * 1.2), rgbout_w);
+ hsl_color_rgb (h, cs, fmin (1.0, fmax (0.2, l) * 1.8), rgbout_c);
+}
+
+static void
+haiku_draw_relief_rect (struct glyph_string *s,
+ int left_x, int top_y, int right_x, int bottom_y,
+ int hwidth, int vwidth, bool raised_p, bool top_p, bool bot_p,
+ bool left_p, bool right_p,
+ struct haiku_rect *clip_rect, bool fancy_p)
+{
+ uint32_t color_white;
+ uint32_t color_black;
+ uint32_t color_corner;
+
+ haiku_calculate_relief_colors (s, &color_white, &color_black,
+ &color_corner);
+
+ void *view = FRAME_HAIKU_VIEW (s->f);
+ BView_StartClip (view);
+
+ BView_SetHighColor (view, raised_p ? color_white : color_black);
+ if (clip_rect)
+ BView_ClipToRect (view, clip_rect->x, clip_rect->y, clip_rect->width,
+ clip_rect->height);
+ if (top_p)
+ BView_FillRectangle (view, left_x, top_y, right_x - left_x + 1, hwidth);
+ if (left_p)
+ BView_FillRectangle (view, left_x, top_y, vwidth, bottom_y - top_y + 1);
+ BView_SetHighColor (view, !raised_p ? color_white : color_black);
+
+ if (bot_p)
+ BView_FillRectangle (view, left_x, bottom_y - hwidth + 1,
+ right_x - left_x + 1, hwidth);
+ if (right_p)
+ BView_FillRectangle (view, right_x - vwidth + 1, top_y,
+ vwidth, bottom_y - top_y + 1);
+
+ /* Draw the triangle for the bottom-left corner. */
+ if (bot_p && left_p)
+ {
+ BView_SetHighColor (view, raised_p ? color_white : color_black);
+ BView_FillTriangle (view, left_x, bottom_y - hwidth, left_x + vwidth,
+ bottom_y - hwidth, left_x, bottom_y);
+ }
+
+ /* Now draw the triangle for the top-right corner. */
+ if (top_p && right_p)
+ {
+ BView_SetHighColor (view, raised_p ? color_white : color_black);
+ BView_FillTriangle (view, right_x - vwidth, top_y,
+ right_x, top_y,
+ right_x - vwidth, top_y + hwidth);
+ }
+
+ /* If (h/v)width is > 1, we draw the outer-most line on each side in the
+ black relief color. */
+
+ BView_SetHighColor (view, color_black);
+
+ if (hwidth > 1 && top_p)
+ BView_StrokeLine (view, left_x, top_y, right_x, top_y);
+ if (hwidth > 1 && bot_p)
+ BView_StrokeLine (view, left_x, bottom_y, right_x, bottom_y);
+ if (vwidth > 1 && left_p)
+ BView_StrokeLine (view, left_x, top_y, left_x, bottom_y);
+ if (vwidth > 1 && right_p)
+ BView_StrokeLine (view, right_x, top_y, right_x, bottom_y);
+
+ BView_SetHighColor (view, color_corner);
+
+ /* Omit corner pixels. */
+ if (hwidth > 1 || vwidth > 1)
+ {
+ if (left_p && top_p)
+ BView_FillRectangle (view, left_x, top_y, 1, 1);
+ if (left_p && bot_p)
+ BView_FillRectangle (view, left_x, bottom_y, 1, 1);
+ if (right_p && top_p)
+ BView_FillRectangle (view, right_x, top_y, 1, 1);
+ if (right_p && bot_p)
+ BView_FillRectangle (view, right_x, bottom_y, 1, 1);
+ }
+
+ BView_EndClip (view);
+}
+
+static void
+haiku_draw_underwave (struct glyph_string *s, int width, int x)
+{
+ int wave_height = 3, wave_length = 2;
+ int y, dx, dy, odd, xmax;
+ dx = wave_length;
+ dy = wave_height - 1;
+ y = s->ybase - wave_height + 3;
+
+ float ax, ay, bx, by;
+ xmax = x + width;
+
+ void *view = FRAME_HAIKU_VIEW (s->f);
+
+ BView_StartClip (view);
+ BView_ClipToRect (view, x, y, width, wave_height);
+ ax = x - ((int) (x) % dx) + (float) 0.5;
+ bx = ax + dx;
+ odd = (int) (ax / dx) % 2;
+ ay = by = y + 0.5;
+
+ if (odd)
+ ay += dy;
+ else
+ by += dy;
+
+ while (ax <= xmax)
+ {
+ BView_StrokeLine (view, ax, ay, bx, by);
+ ax = bx, ay = by;
+ bx += dx, by = y + 0.5 + odd * dy;
+ odd = !odd;
+ }
+ BView_EndClip (view);
+}
+
+static void
+haiku_draw_text_decoration (struct glyph_string *s, struct face *face,
+ uint8_t dcol, int width, int x)
+{
+ if (s->for_overlaps)
+ return;
+
+ void *view = FRAME_HAIKU_VIEW (s->f);
+ BView_draw_lock (view);
+ BView_StartClip (view);
+
+ if (face->underline)
+ {
+ if (s->hl == DRAW_CURSOR)
+ BView_SetHighColor (view, FRAME_OUTPUT_DATA (s->f)->cursor_fg);
+ else if (!face->underline_defaulted_p)
+ BView_SetHighColor (view, face->underline_color);
+ else
+ BView_SetHighColor (view, dcol);
+
+ if (face->underline == FACE_UNDER_WAVE)
+ haiku_draw_underwave (s, width, x);
+ else if (face->underline == FACE_UNDER_LINE)
+ {
+ unsigned long thickness, position;
+ int y;
+
+ if (s->prev && s->prev && s->prev->hl == DRAW_MOUSE_FACE)
+ {
+ struct face *prev_face = s->prev->face;
+
+ if (prev_face && prev_face->underline == FACE_UNDER_LINE)
+ {
+ /* We use the same underline style as the previous one. */
+ thickness = s->prev->underline_thickness;
+ position = s->prev->underline_position;
+ }
+ else
+ goto calculate_underline_metrics;
+ }
+ else
+ {
+ calculate_underline_metrics:;
+ struct font *font = font_for_underline_metrics (s);
+ unsigned long minimum_offset;
+ bool underline_at_descent_line;
+ bool use_underline_position_properties;
+ Lisp_Object val = (WINDOW_BUFFER_LOCAL_VALUE
+ (Qunderline_minimum_offset, s->w));
+
+ if (FIXNUMP (val))
+ minimum_offset = max (0, XFIXNUM (val));
+ else
+ minimum_offset = 1;
+
+ val = (WINDOW_BUFFER_LOCAL_VALUE
+ (Qx_underline_at_descent_line, s->w));
+ underline_at_descent_line
+ = !(NILP (val) || EQ (val, Qunbound));
+
+ val = (WINDOW_BUFFER_LOCAL_VALUE
+ (Qx_use_underline_position_properties, s->w));
+ use_underline_position_properties
+ = !(NILP (val) || EQ (val, Qunbound));
+
+ /* Get the underline thickness. Default is 1 pixel. */
+ if (font && font->underline_thickness > 0)
+ thickness = font->underline_thickness;
+ else
+ thickness = 1;
+ if (underline_at_descent_line)
+ position = (s->height - thickness) - (s->ybase - s->y);
+ else
+ {
+ /* Get the underline position. This is the
+ recommended vertical offset in pixels from
+ the baseline to the top of the underline.
+ This is a signed value according to the
+ specs, and its default is
+
+ ROUND ((maximum descent) / 2), with
+ ROUND(x) = floor (x + 0.5) */
+
+ if (use_underline_position_properties
+ && font && font->underline_position >= 0)
+ position = font->underline_position;
+ else if (font)
+ position = (font->descent + 1) / 2;
+ else
+ position = minimum_offset;
+ }
+ position = max (position, minimum_offset);
+ }
+ /* Check the sanity of thickness and position. We should
+ avoid drawing underline out of the current line area. */
+ if (s->y + s->height <= s->ybase + position)
+ position = (s->height - 1) - (s->ybase - s->y);
+ if (s->y + s->height < s->ybase + position + thickness)
+ thickness = (s->y + s->height) - (s->ybase + position);
+ s->underline_thickness = thickness;
+ s->underline_position = position;
+ y = s->ybase + position;
+
+ BView_FillRectangle (view, s->x, y, s->width, thickness);
+ }
+ }
+
+ if (face->overline_p)
+ {
+ unsigned long dy = 0, h = 1;
+ if (s->hl == DRAW_CURSOR)
+ BView_SetHighColor (view, FRAME_OUTPUT_DATA (s->f)->cursor_fg);
+ else if (!face->overline_color_defaulted_p)
+ BView_SetHighColor (view, face->overline_color);
+ else
+ BView_SetHighColor (view, dcol);
+
+ BView_FillRectangle (view, s->x, s->y + dy, s->width, h);
+ }
+
+ if (face->strike_through_p)
+ {
+ /* Y-coordinate and height of the glyph string's first
+ glyph. We cannot use s->y and s->height because those
+ could be larger if there are taller display elements
+ (e.g., characters displayed with a larger font) in the
+ same glyph row. */
+ int glyph_y = s->ybase - s->first_glyph->ascent;
+ int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
+ /* Strike-through width and offset from the glyph string's
+ top edge. */
+ unsigned long h = 1;
+ unsigned long dy = (glyph_height - h) / 2;
+
+ if (s->hl == DRAW_CURSOR)
+ BView_SetHighColor (view, FRAME_OUTPUT_DATA (s->f)->cursor_fg);
+ else if (!face->strike_through_color_defaulted_p)
+ BView_SetHighColor (view, face->strike_through_color);
+ else
+ BView_SetHighColor (view, dcol);
+
+ BView_FillRectangle (view, s->x, glyph_y + dy, s->width, h);
+ }
+
+ BView_EndClip (view);
+ BView_draw_unlock (view);
+}
+
+static void
+haiku_draw_string_box (struct glyph_string *s, int clip_p)
+{
+ int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
+ bool raised_p, left_p, right_p;
+ struct glyph *last_glyph;
+ struct haiku_rect clip_rect;
+
+ struct face *face = s->face;
+
+ last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
+ ? WINDOW_RIGHT_EDGE_X (s->w)
+ : window_box_right (s->w, s->area));
+
+ /* The glyph that may have a right box line. For static
+ compositions and images, the right-box flag is on the first glyph
+ of the glyph string; for other types it's on the last glyph. */
+ if (s->cmp || s->img)
+ last_glyph = s->first_glyph;
+ else if (s->first_glyph->type == COMPOSITE_GLYPH
+ && s->first_glyph->u.cmp.automatic)
+ {
+ /* For automatic compositions, we need to look up the last glyph
+ in the composition. */
+ struct glyph *end = s->row->glyphs[s->area] + s->row->used[s->area];
+ struct glyph *g = s->first_glyph;
+ for (last_glyph = g++;
+ g < end && g->u.cmp.automatic && g->u.cmp.id == s->cmp_id
+ && g->slice.cmp.to < s->cmp_to;
+ last_glyph = g++)
+ ;
+ }
+ else
+ last_glyph = s->first_glyph + s->nchars - 1;
+
+ vwidth = eabs (face->box_vertical_line_width);
+ hwidth = eabs (face->box_horizontal_line_width);
+ raised_p = face->box == FACE_RAISED_BOX;
+ left_x = s->x;
+ right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
+ ? last_x - 1
+ : min (last_x, s->x + s->background_width) - 1);
+
+ top_y = s->y;
+ bottom_y = top_y + s->height - 1;
+
+ left_p = (s->first_glyph->left_box_line_p
+ || (s->hl == DRAW_MOUSE_FACE
+ && (s->prev == NULL
+ || s->prev->hl != s->hl)));
+ right_p = (last_glyph->right_box_line_p
+ || (s->hl == DRAW_MOUSE_FACE
+ && (s->next == NULL
+ || s->next->hl != s->hl)));
+
+ get_glyph_string_clip_rect (s, &clip_rect);
+
+ if (face->box == FACE_SIMPLE_BOX)
+ haiku_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
+ vwidth, left_p, right_p, &clip_rect);
+ else
+ haiku_draw_relief_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
+ vwidth, raised_p, true, true, left_p, right_p,
+ &clip_rect, 1);
+
+ if (clip_p)
+ {
+ void *view = FRAME_HAIKU_VIEW (s->f);
+
+ haiku_draw_text_decoration (s, face, face->foreground, s->width, s->x);
+ BView_ClipToInverseRect (view, left_x, top_y, right_x - left_x + 1, hwidth);
+ if (left_p)
+ BView_ClipToInverseRect (view, left_x, top_y, vwidth, bottom_y - top_y + 1);
+ BView_ClipToInverseRect (view, left_x, bottom_y - hwidth + 1,
+ right_x - left_x + 1, hwidth);
+ if (right_p)
+ BView_ClipToInverseRect (view, right_x - vwidth + 1,
+ top_y, vwidth, bottom_y - top_y + 1);
+ }
+}
+
+static void
+haiku_draw_plain_background (struct glyph_string *s, struct face *face,
+ int box_line_hwidth, int box_line_vwidth)
+{
+ void *view = FRAME_HAIKU_VIEW (s->f);
+ BView_StartClip (view);
+ if (s->hl == DRAW_CURSOR)
+ BView_SetHighColor (view, FRAME_CURSOR_COLOR (s->f).pixel);
+ else
+ BView_SetHighColor (view, face->background_defaulted_p ?
+ FRAME_BACKGROUND_PIXEL (s->f) :
+ face->background);
+
+ BView_FillRectangle (view, s->x,
+ s->y + box_line_hwidth,
+ s->background_width,
+ s->height - 2 * box_line_hwidth);
+ BView_EndClip (view);
+}
+
+static void
+haiku_draw_stipple_background (struct glyph_string *s, struct face *face,
+ int box_line_hwidth, int box_line_vwidth)
+{
+}
+
+static void
+haiku_maybe_draw_background (struct glyph_string *s, int force_p)
+{
+ if ((s->first_glyph->type != IMAGE_GLYPH) && !s->background_filled_p)
+ {
+ struct face *face = s->face;
+ int box_line_width = max (face->box_horizontal_line_width, 0);
+ int box_vline_width = max (face->box_vertical_line_width, 0);
+
+ if (FONT_HEIGHT (s->font) < s->height - 2 * box_vline_width
+ || FONT_TOO_HIGH (s->font)
+ || s->font_not_found_p || s->extends_to_end_of_line_p || force_p)
+ {
+ if (!face->stipple)
+ haiku_draw_plain_background (s, face, box_line_width,
+ box_vline_width);
+ else
+ haiku_draw_stipple_background (s, face, box_line_width,
+ box_vline_width);
+ s->background_filled_p = 1;
+ }
+ }
+}
+
+static void
+haiku_mouse_face_colors (struct glyph_string *s, uint32_t *fg,
+ uint32_t *bg)
+{
+ int face_id;
+ struct face *face;
+
+ /* What face has to be used last for the mouse face? */
+ face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
+ face = FACE_FROM_ID_OR_NULL (s->f, face_id);
+ if (face == NULL)
+ face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+
+ if (s->first_glyph->type == CHAR_GLYPH)
+ face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
+ else
+ face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
+
+ face = FACE_FROM_ID (s->f, face_id);
+ prepare_face_for_display (s->f, s->face);
+
+ if (fg)
+ *fg = face->foreground;
+ if (bg)
+ *bg = face->background;
+}
+
+static void
+haiku_draw_glyph_string_foreground (struct glyph_string *s)
+{
+ struct face *face = s->face;
+
+ int i, x;
+ if (face->box != FACE_NO_BOX
+ && s->first_glyph->left_box_line_p)
+ x = s->x + max (face->box_vertical_line_width, 0);
+ else
+ x = s->x;
+
+ void *view = FRAME_HAIKU_VIEW (s->f);
+
+ if (s->font_not_found_p)
+ {
+ BView_StartClip (view);
+ if (s->hl == DRAW_CURSOR)
+ BView_SetHighColor (view, FRAME_OUTPUT_DATA (s->f)->cursor_fg);
+ else
+ BView_SetHighColor (view, face->foreground);
+ for (i = 0; i < s->nchars; ++i)
+ {
+ struct glyph *g = s->first_glyph + i;
+ BView_StrokeRectangle (view, x, s->y, g->pixel_width,
+ s->height);
+ x += g->pixel_width;
+ }
+ BView_EndClip (view);
+ }
+ else
+ {
+ struct font *ft = s->font;
+ int off = ft->baseline_offset;
+ int y;
+
+ if (ft->vertical_centering)
+ off = VCENTER_BASELINE_OFFSET (ft, s->f) - off;
+ y = s->ybase - off;
+ if (s->for_overlaps || (s->background_filled_p && s->hl != DRAW_CURSOR))
+ ft->driver->draw (s, 0, s->nchars, x, y, false);
+ else
+ ft->driver->draw (s, 0, s->nchars, x, y, true);
+
+ if (face->overstrike)
+ ft->driver->draw (s, 0, s->nchars, x + 1, y, false);
+ }
+}
+
+static void
+haiku_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
+{
+ struct glyph *glyph = s->first_glyph;
+ unsigned char2b[8];
+ int x, i, j;
+ struct face *face = s->face;
+
+ /* If first glyph of S has a left box line, start drawing the text
+ of S to the right of that box line. */
+ if (face && face->box != FACE_NO_BOX
+ && s->first_glyph->left_box_line_p)
+ x = s->x + max (face->box_vertical_line_width, 0);
+ else
+ x = s->x;
+
+ s->char2b = char2b;
+
+ for (i = 0; i < s->nchars; i++, glyph++)
+ {
+#ifdef GCC_LINT
+ enum { PACIFY_GCC_BUG_81401 = 1 };
+#else
+ enum { PACIFY_GCC_BUG_81401 = 0 };
+#endif
+ char buf[7 + PACIFY_GCC_BUG_81401];
+ char *str = NULL;
+ int len = glyph->u.glyphless.len;
+
+ if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
+ {
+ if (len > 0
+ && CHAR_TABLE_P (Vglyphless_char_display)
+ && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
+ >= 1))
+ {
+ Lisp_Object acronym
+ = (! glyph->u.glyphless.for_no_font
+ ? CHAR_TABLE_REF (Vglyphless_char_display,
+ glyph->u.glyphless.ch)
+ : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
+ if (STRINGP (acronym))
+ str = SSDATA (acronym);
+ }
+ }
+ else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
+ {
+ unsigned int ch = glyph->u.glyphless.ch;
+ eassume (ch <= MAX_CHAR);
+ sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch);
+ str = buf;
+ }
+
+ if (str)
+ {
+ int upper_len = (len + 1) / 2;
+
+ /* It is assured that all LEN characters in STR is ASCII. */
+ for (j = 0; j < len; j++)
+ char2b[j] = s->font->driver->encode_char (s->font, str[j]) & 0xFFFF;
+
+ s->font->driver->draw (s, 0, upper_len,
+ x + glyph->slice.glyphless.upper_xoff,
+ s->ybase + glyph->slice.glyphless.upper_yoff,
+ false);
+ s->font->driver->draw (s, upper_len, len,
+ x + glyph->slice.glyphless.lower_xoff,
+ s->ybase + glyph->slice.glyphless.lower_yoff,
+ false);
+ }
+ BView_StartClip (FRAME_HAIKU_VIEW (s->f));
+ if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
+ BView_FillRectangle (FRAME_HAIKU_VIEW (s->f),
+ x, s->ybase - glyph->ascent,
+ glyph->pixel_width - 1,
+ glyph->ascent + glyph->descent - 1);
+ BView_EndClip (FRAME_HAIKU_VIEW (s->f));
+ x += glyph->pixel_width;
+ }
+}
+
+static void
+haiku_draw_stretch_glyph_string (struct glyph_string *s)
+{
+ eassert (s->first_glyph->type == STRETCH_GLYPH);
+
+ struct face *face = s->face;
+
+ if (s->hl == DRAW_CURSOR && !x_stretch_cursor_p)
+ {
+ int width, background_width = s->background_width;
+ int x = s->x;
+
+ if (!s->row->reversed_p)
+ {
+ int left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ }
+ else
+ {
+ /* In R2L rows, draw the cursor on the right edge of the
+ stretch glyph. */
+ int right_x = window_box_right (s->w, TEXT_AREA);
+ if (x + background_width > right_x)
+ background_width -= x - right_x;
+ x += background_width;
+ }
+
+ width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
+ if (s->row->reversed_p)
+ x -= width;
+
+ void *view = FRAME_HAIKU_VIEW (s->f);
+ BView_StartClip (view);
+ BView_SetHighColor (view, FRAME_CURSOR_COLOR (s->f).pixel);
+ BView_FillRectangle (view, x, s->y, width, s->height);
+ BView_EndClip (view);
+
+ if (width < background_width)
+ {
+ if (!s->row->reversed_p)
+ x += width;
+ else
+ x = s->x;
+
+ int y = s->y;
+ int w = background_width - width, h = s->height;
+
+ if (!face->stipple)
+ {
+ uint32_t bkg;
+ if (s->hl == DRAW_MOUSE_FACE || (s->hl == DRAW_CURSOR
+ && s->row->mouse_face_p
+ && cursor_in_mouse_face_p (s->w)))
+ haiku_mouse_face_colors (s, NULL, &bkg);
+ else
+ bkg = face->background;
+
+ BView_StartClip (view);
+ BView_SetHighColor (view, bkg);
+ BView_FillRectangle (view, x, y, w, h);
+ BView_EndClip (view);
+ }
+ }
+ }
+ else if (!s->background_filled_p)
+ {
+ int background_width = s->background_width;
+ int x = s->x, text_left_x = window_box_left (s->w, TEXT_AREA);
+
+ /* Don't draw into left fringe or scrollbar area except for
+ header line and mode line. */
+ if (s->area == TEXT_AREA
+ && x < text_left_x && !s->row->mode_line_p)
+ {
+ background_width -= text_left_x - x;
+ x = text_left_x;
+ }
+
+ if (background_width > 0)
+ {
+ void *view = FRAME_HAIKU_VIEW (s->f);
+ BView_StartClip (view);
+ uint32_t bkg;
+ if (s->hl == DRAW_MOUSE_FACE)
+ haiku_mouse_face_colors (s, NULL, &bkg);
+ else if (s->hl == DRAW_CURSOR)
+ bkg = FRAME_CURSOR_COLOR (s->f).pixel;
+ else
+ bkg = s->face->background;
+
+ BView_SetHighColor (view, bkg);
+ BView_FillRectangle (view, x, s->y, background_width, s->height);
+ BView_EndClip (view);
+ }
+ }
+ s->background_filled_p = 1;
+}
+
+static void
+haiku_start_clip (struct glyph_string *s)
+{
+ void *view = FRAME_HAIKU_VIEW (s->f);
+ BView_draw_lock (view);
+ BView_StartClip (view);
+}
+
+static void
+haiku_end_clip (struct glyph_string *s)
+{
+ void *view = FRAME_HAIKU_VIEW (s->f);
+ BView_EndClip (view);
+ BView_draw_unlock (view);
+}
+
+static void
+haiku_clip_to_row (struct window *w, struct glyph_row *row,
+ enum glyph_row_area area)
+{
+ struct frame *f = WINDOW_XFRAME (w);
+ int window_x, window_y, window_width;
+ int x, y, width, height;
+
+ window_box (w, area, &window_x, &window_y, &window_width, 0);
+
+ x = window_x;
+ y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y));
+ y = max (y, window_y);
+ width = window_width;
+ height = row->visible_height;
+
+ BView_ClipToRect (FRAME_HAIKU_VIEW (f), x, y, width, height);
+}
+
+static void
+haiku_update_begin (struct frame *f)
+{
+}
+
+static void
+haiku_update_end (struct frame *f)
+{
+ MOUSE_HL_INFO (f)->mouse_face_defer = false;
+ flush_frame (f);
+}
+
+static void
+haiku_draw_composite_glyph_string_foreground (struct glyph_string *s)
+{
+ int i, j, x;
+ struct font *font = s->font;
+ void *view = FRAME_HAIKU_VIEW (s->f);
+ struct face *face = s->face;
+
+ /* If first glyph of S has a left box line, start drawing the text
+ of S to the right of that box line. */
+ if (face && face->box != FACE_NO_BOX
+ && s->first_glyph->left_box_line_p)
+ x = s->x + max (face->box_vertical_line_width, 0);
+ else
+ x = s->x;
+
+ /* S is a glyph string for a composition. S->cmp_from is the index
+ of the first character drawn for glyphs of this composition.
+ S->cmp_from == 0 means we are drawing the very first character of
+ this composition. */
+
+ /* Draw a rectangle for the composition if the font for the very
+ first character of the composition could not be loaded. */
+
+ if (s->font_not_found_p && !s->cmp_from)
+ {
+ BView_StartClip (view);
+ if (s->hl == DRAW_CURSOR)
+ BView_SetHighColor (view, FRAME_OUTPUT_DATA (s->f)->cursor_fg);
+ else
+ BView_SetHighColor (view, s->face->foreground);
+ BView_StrokeRectangle (view, s->x, s->y, s->width - 1, s->height - 1);
+ BView_EndClip (view);
+ }
+ else if (!s->first_glyph->u.cmp.automatic)
+ {
+ int y = s->ybase;
+
+ for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
+ /* TAB in a composition means display glyphs with padding
+ space on the left or right. */
+ if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
+ {
+ int xx = x + s->cmp->offsets[j * 2];
+ int yy = y - s->cmp->offsets[j * 2 + 1];
+
+ font->driver->draw (s, j, j + 1, xx, yy, false);
+ if (face->overstrike)
+ font->driver->draw (s, j, j + 1, xx + 1, yy, false);
+ }
+ }
+ else
+ {
+ Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
+ Lisp_Object glyph;
+ int y = s->ybase;
+ int width = 0;
+
+ for (i = j = s->cmp_from; i < s->cmp_to; i++)
+ {
+ glyph = LGSTRING_GLYPH (gstring, i);
+ if (NILP (LGLYPH_ADJUSTMENT (glyph)))
+ width += LGLYPH_WIDTH (glyph);
+ else
+ {
+ int xoff, yoff, wadjust;
+
+ if (j < i)
+ {
+ font->driver->draw (s, j, i, x, y, false);
+ if (s->face->overstrike)
+ font->driver->draw (s, j, i, x + 1, y, false);
+ x += width;
+ }
+ xoff = LGLYPH_XOFF (glyph);
+ yoff = LGLYPH_YOFF (glyph);
+ wadjust = LGLYPH_WADJUST (glyph);
+ font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
+ if (face->overstrike)
+ font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
+ false);
+ x += wadjust;
+ j = i + 1;
+ width = 0;
+ }
+ }
+ if (j < i)
+ {
+ font->driver->draw (s, j, i, x, y, false);
+ if (face->overstrike)
+ font->driver->draw (s, j, i, x + 1, y, false);
+ }
+ }
+}
+
+static void
+haiku_draw_image_relief (struct glyph_string *s)
+{
+ int x1, y1, thick;
+ bool raised_p, top_p, bot_p, left_p, right_p;
+ int extra_x, extra_y;
+ struct haiku_rect r;
+ int x = s->x;
+ int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
+
+ struct face *face = s->face;
+
+ /* If first glyph of S has a left box line, start drawing it to the
+ right of that line. */
+ if (face->box != FACE_NO_BOX
+ && s->first_glyph->left_box_line_p
+ && s->slice.x == 0)
+ x += max (face->box_vertical_line_width, 0);
+
+ /* If there is a margin around the image, adjust x- and y-position
+ by that margin. */
+ if (s->slice.x == 0)
+ x += s->img->hmargin;
+ if (s->slice.y == 0)
+ y += s->img->vmargin;
+
+ if (s->hl == DRAW_IMAGE_SUNKEN
+ || s->hl == DRAW_IMAGE_RAISED)
+ {
+ if (s->face->id == TAB_BAR_FACE_ID)
+ thick = (tab_bar_button_relief < 0
+ ? DEFAULT_TAB_BAR_BUTTON_RELIEF
+ : min (tab_bar_button_relief, 1000000));
+ else
+ thick = (tool_bar_button_relief < 0
+ ? DEFAULT_TOOL_BAR_BUTTON_RELIEF
+ : min (tool_bar_button_relief, 1000000));
+ raised_p = s->hl == DRAW_IMAGE_RAISED;
+ }
+ else
+ {
+ thick = eabs (s->img->relief);
+ raised_p = s->img->relief > 0;
+ }
+
+ x1 = x + s->slice.width - 1;
+ y1 = y + s->slice.height - 1;
+
+ extra_x = extra_y = 0;
+
+ if (s->face->id == TAB_BAR_FACE_ID)
+ {
+ if (CONSP (Vtab_bar_button_margin)
+ && FIXNUMP (XCAR (Vtab_bar_button_margin))
+ && FIXNUMP (XCDR (Vtab_bar_button_margin)))
+ {
+ extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin)) - thick;
+ extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin)) - thick;
+ }
+ else if (FIXNUMP (Vtab_bar_button_margin))
+ extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin) - thick;
+ }
+
+ if (s->face->id == TOOL_BAR_FACE_ID)
+ {
+ if (CONSP (Vtool_bar_button_margin)
+ && FIXNUMP (XCAR (Vtool_bar_button_margin))
+ && FIXNUMP (XCDR (Vtool_bar_button_margin)))
+ {
+ extra_x = XFIXNUM (XCAR (Vtool_bar_button_margin));
+ extra_y = XFIXNUM (XCDR (Vtool_bar_button_margin));
+ }
+ else if (FIXNUMP (Vtool_bar_button_margin))
+ extra_x = extra_y = XFIXNUM (Vtool_bar_button_margin);
+ }
+
+ top_p = bot_p = left_p = right_p = 0;
+
+ if (s->slice.x == 0)
+ x -= thick + extra_x, left_p = 1;
+ if (s->slice.y == 0)
+ y -= thick + extra_y, top_p = 1;
+ if (s->slice.x + s->slice.width == s->img->width)
+ x1 += thick + extra_x, right_p = 1;
+ if (s->slice.y + s->slice.height == s->img->height)
+ y1 += thick + extra_y, bot_p = 1;
+
+ get_glyph_string_clip_rect (s, &r);
+ haiku_draw_relief_rect (s, x, y, x1, y1, thick, thick, raised_p,
+ top_p, bot_p, left_p, right_p, &r, 0);
+}
+
+static void
+haiku_draw_image_glyph_string (struct glyph_string *s)
+{
+ struct face *face = s->face;
+
+ int box_line_hwidth = max (face->box_vertical_line_width, 0);
+ int box_line_vwidth = max (face->box_horizontal_line_width, 0);
+
+ int x, y;
+ int height, width;
+
+ height = s->height;
+ if (s->slice.y == 0)
+ height -= box_line_vwidth;
+ if (s->slice.y + s->slice.height >= s->img->height)
+ height -= box_line_vwidth;
+
+ width = s->background_width;
+ x = s->x;
+ if (s->first_glyph->left_box_line_p
+ && s->slice.x == 0)
+ {
+ x += box_line_hwidth;
+ width -= box_line_hwidth;
+ }
+
+ y = s->y;
+ if (s->slice.y == 0)
+ y += box_line_vwidth;
+
+ void *view = FRAME_HAIKU_VIEW (s->f);
+ void *bitmap = s->img->pixmap;
+
+ s->stippled_p = face->stipple != 0;
+
+ BView_draw_lock (view);
+ BView_StartClip (view);
+ BView_SetHighColor (view, face->background);
+ BView_FillRectangle (view, x, y, width, height);
+ BView_EndClip (view);
+ BView_draw_unlock (view);
+
+ if (bitmap)
+ {
+ struct haiku_rect nr;
+ Emacs_Rectangle cr, ir, r;
+
+ get_glyph_string_clip_rect (s, &nr);
+ CONVERT_TO_EMACS_RECT (cr, nr);
+ x = s->x;
+ y = s->ybase - image_ascent (s->img, face, &s->slice);
+
+ if (s->slice.x == 0)
+ x += s->img->hmargin;
+ if (s->slice.y == 0)
+ y += s->img->vmargin;
+
+ if (face->box != FACE_NO_BOX
+ && s->first_glyph->left_box_line_p
+ && s->slice.x == 0)
+ x += max (face->box_vertical_line_width, 0);
+
+ ir.x = x;
+ ir.y = y;
+ ir.width = s->slice.width;
+ ir.height = s->slice.height;
+ r = ir;
+
+ void *mask = s->img->mask;
+
+ if (gui_intersect_rectangles (&cr, &ir, &r))
+ {
+ BView_draw_lock (view);
+ BView_StartClip (view);
+
+ haiku_clip_to_string (s);
+ if (s->img->have_be_transforms_p)
+ {
+ bitmap = BBitmap_transform_bitmap (bitmap,
+ s->img->mask,
+ face->background,
+ s->img->be_rotate,
+ s->img->width,
+ s->img->height);
+ mask = NULL;
+ }
+
+ BView_DrawBitmap (view, bitmap,
+ s->slice.x + r.x - x,
+ s->slice.y + r.y - y,
+ r.width, r.height,
+ r.x, r.y, r.width, r.height);
+ if (mask)
+ {
+ BView_DrawMask (mask, view,
+ s->slice.x + r.x - x,
+ s->slice.y + r.y - y,
+ r.width, r.height,
+ r.x, r.y, r.width, r.height,
+ face->background);
+ }
+
+ if (s->img->have_be_transforms_p)
+ BBitmap_free (bitmap);
+ BView_EndClip (view);
+ BView_draw_unlock (view);
+ }
+
+ if (s->hl == DRAW_CURSOR)
+ {
+ BView_draw_lock (view);
+ BView_StartClip (view);
+ BView_SetPenSize (view, 1);
+ BView_SetHighColor (view, FRAME_CURSOR_COLOR (s->f).pixel);
+ BView_StrokeRectangle (view, r.x, r.y, r.width, r.height);
+ BView_EndClip (view);
+ BView_draw_unlock (view);
+ }
+ }
+
+ if (s->img->relief
+ || s->hl == DRAW_IMAGE_RAISED
+ || s->hl == DRAW_IMAGE_SUNKEN)
+ haiku_draw_image_relief (s);
+}
+
+static void
+haiku_draw_glyph_string (struct glyph_string *s)
+{
+ block_input ();
+ prepare_face_for_display (s->f, s->face);
+
+ struct face *face = s->face;
+ if (face != s->face)
+ prepare_face_for_display (s->f, face);
+
+ if (s->next && s->right_overhang && !s->for_overlaps)
+ {
+ int width;
+ struct glyph_string *next;
+
+ for (width = 0, next = s->next;
+ next && width < s->right_overhang;
+ width += next->width, next = next->next)
+ if (next->first_glyph->type != IMAGE_GLYPH)
+ {
+ prepare_face_for_display (s->f, s->next->face);
+ haiku_start_clip (s->next);
+ haiku_clip_to_string (s->next);
+ if (next->first_glyph->type != STRETCH_GLYPH)
+ haiku_maybe_draw_background (s->next, 1);
+ else
+ haiku_draw_stretch_glyph_string (s->next);
+ next->num_clips = 0;
+ haiku_end_clip (s);
+ }
+ }
+
+ haiku_start_clip (s);
+
+ int box_filled_p = 0;
+
+ if (!s->for_overlaps && face->box != FACE_NO_BOX
+ && (s->first_glyph->type == CHAR_GLYPH
+ || s->first_glyph->type == COMPOSITE_GLYPH))
+ {
+ haiku_clip_to_string (s);
+ haiku_maybe_draw_background (s, 1);
+ box_filled_p = 1;
+ haiku_draw_string_box (s, 0);
+ }
+ else if (!s->clip_head && !s->clip_tail &&
+ ((s->prev && s->left_overhang && s->prev->hl != s->hl) ||
+ (s->next && s->right_overhang && s->next->hl != s->hl)))
+ haiku_clip_to_string_exactly (s, s);
+ else
+ haiku_clip_to_string (s);
+
+ if (s->for_overlaps)
+ s->background_filled_p = 1;
+
+ switch (s->first_glyph->type)
+ {
+ case COMPOSITE_GLYPH:
+ if (s->for_overlaps || (s->cmp_from > 0
+ && ! s->first_glyph->u.cmp.automatic))
+ s->background_filled_p = 1;
+ else
+ haiku_maybe_draw_background (s, 1);
+ haiku_draw_composite_glyph_string_foreground (s);
+ break;
+ case CHAR_GLYPH:
+ if (s->for_overlaps)
+ s->background_filled_p = 1;
+ else
+ haiku_maybe_draw_background (s, 0);
+ haiku_draw_glyph_string_foreground (s);
+ break;
+ case STRETCH_GLYPH:
+ haiku_draw_stretch_glyph_string (s);
+ break;
+ case IMAGE_GLYPH:
+ haiku_draw_image_glyph_string (s);
+ break;
+ case GLYPHLESS_GLYPH:
+ if (s->for_overlaps)
+ s->background_filled_p = 1;
+ else
+ haiku_maybe_draw_background (s, 1);
+ haiku_draw_glyphless_glyph_string_foreground (s);
+ break;
+ }
+
+ if (!box_filled_p && face->box != FACE_NO_BOX)
+ haiku_draw_string_box (s, 1);
+ else
+ haiku_draw_text_decoration (s, face, face->foreground, s->width, s->x);
+
+ if (!s->for_overlaps)
+ {
+ if (s->prev)
+ {
+ struct glyph_string *prev;
+
+ for (prev = s->prev; prev; prev = prev->prev)
+ if (prev->hl != s->hl
+ && prev->x + prev->width + prev->right_overhang > s->x)
+ {
+ /* As prev was drawn while clipped to its own area, we
+ must draw the right_overhang part using s->hl now. */
+ enum draw_glyphs_face save = prev->hl;
+ struct face *save_face = prev->face;
+
+ prev->hl = s->hl;
+ prev->face = s->face;
+ haiku_start_clip (s);
+ haiku_clip_to_string_exactly (s, prev);
+ if (prev->first_glyph->type == CHAR_GLYPH)
+ haiku_draw_glyph_string_foreground (prev);
+ else
+ haiku_draw_composite_glyph_string_foreground (prev);
+ haiku_end_clip (s);
+ prev->hl = save;
+ prev->face = save_face;
+ prev->num_clips = 0;
+ }
+ }
+
+ if (s->next)
+ {
+ struct glyph_string *next;
+
+ for (next = s->next; next; next = next->next)
+ if (next->hl != s->hl
+ && next->x - next->left_overhang < s->x + s->width)
+ {
+ /* As next will be drawn while clipped to its own area,
+ we must draw the left_overhang part using s->hl now. */
+ enum draw_glyphs_face save = next->hl;
+ struct face *save_face = next->face;
+
+ next->hl = s->hl;
+ next->face = s->face;
+ haiku_start_clip (s);
+ haiku_clip_to_string_exactly (s, next);
+ if (next->first_glyph->type == CHAR_GLYPH)
+ haiku_draw_glyph_string_foreground (next);
+ else
+ haiku_draw_composite_glyph_string_foreground (next);
+ haiku_end_clip (s);
+
+ next->background_filled_p = 0;
+ next->hl = save;
+ next->face = save_face;
+ next->clip_head = next;
+ next->num_clips = 0;
+ }
+ }
+ }
+ s->num_clips = 0;
+ haiku_end_clip (s);
+ unblock_input ();
+}
+
+static void
+haiku_after_update_window_line (struct window *w,
+ struct glyph_row *desired_row)
+{
+ eassert (w);
+ struct frame *f;
+ int width, height;
+
+ if (!desired_row->mode_line_p && !w->pseudo_window_p)
+ desired_row->redraw_fringe_bitmaps_p = true;
+
+ if (windows_or_buffers_changed
+ && desired_row->full_width_p
+ && (f = XFRAME (w->frame),
+ width = FRAME_INTERNAL_BORDER_WIDTH (f),
+ width != 0)
+ && (height = desired_row->visible_height,
+ height > 0))
+ {
+ int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
+ int face_id =
+ !NILP (Vface_remapping_alist)
+ ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
+ : INTERNAL_BORDER_FACE_ID;
+ struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
+
+ block_input ();
+ if (face)
+ {
+ void *view = FRAME_HAIKU_VIEW (f);
+ BView_draw_lock (view);
+ BView_StartClip (view);
+ BView_SetHighColor (view, face->background_defaulted_p ?
+ FRAME_BACKGROUND_PIXEL (f) : face->background);
+ BView_FillRectangle (view, 0, y, width, height);
+ BView_FillRectangle (view, FRAME_PIXEL_WIDTH (f) - width,
+ y, width, height);
+ BView_EndClip (view);
+ BView_draw_unlock (view);
+ }
+ else
+ {
+ haiku_clear_frame_area (f, 0, y, width, height);
+ haiku_clear_frame_area (f, FRAME_PIXEL_WIDTH (f) - width,
+ y, width, height);
+ }
+ unblock_input ();
+ }
+}
+
+static void
+haiku_set_window_size (struct frame *f, bool change_gravity,
+ int width, int height)
+{
+ haiku_update_size_hints (f);
+
+ if (FRAME_HAIKU_WINDOW (f))
+ {
+ block_input ();
+ BWindow_resize (FRAME_HAIKU_WINDOW (f), width, height);
+ unblock_input ();
+ }
+}
+
+static void
+haiku_draw_window_cursor (struct window *w,
+ struct glyph_row *glyph_row,
+ int x, int y,
+ enum text_cursor_kinds cursor_type,
+ int cursor_width, bool on_p, bool active_p)
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+
+ struct glyph *phys_cursor_glyph;
+ struct glyph *cursor_glyph;
+
+ void *view = FRAME_HAIKU_VIEW (f);
+
+ int fx, fy, h, cursor_height;
+
+ if (!on_p)
+ return;
+
+ if (cursor_type == NO_CURSOR)
+ {
+ w->phys_cursor_width = 0;
+ return;
+ }
+
+ w->phys_cursor_on_p = true;
+ w->phys_cursor_type = cursor_type;
+
+ phys_cursor_glyph = get_phys_cursor_glyph (w);
+
+ if (!phys_cursor_glyph)
+ {
+ if (glyph_row->exact_window_width_line_p
+ && w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])
+ {
+ glyph_row->cursor_in_fringe_p = 1;
+ draw_fringe_bitmap (w, glyph_row, 0);
+ }
+ return;
+ }
+
+ get_phys_cursor_geometry (w, glyph_row, phys_cursor_glyph, &fx, &fy, &h);
+
+ if (cursor_type == BAR_CURSOR)
+ {
+ if (cursor_width < 1)
+ cursor_width = max (FRAME_CURSOR_WIDTH (f), 1);
+ if (cursor_width < w->phys_cursor_width)
+ w->phys_cursor_width = cursor_width;
+ }
+ else if (cursor_type == HBAR_CURSOR)
+ {
+ cursor_height = (cursor_width < 1) ? lrint (0.25 * h) : cursor_width;
+ if (cursor_height > glyph_row->height)
+ cursor_height = glyph_row->height;
+ if (h > cursor_height)
+ fy += h - cursor_height;
+ h = cursor_height;
+ }
+
+ BView_draw_lock (view);
+ BView_StartClip (view);
+ BView_SetHighColor (view, FRAME_CURSOR_COLOR (f).pixel);
+ haiku_clip_to_row (w, glyph_row, TEXT_AREA);
+
+ switch (cursor_type)
+ {
+ default:
+ case DEFAULT_CURSOR:
+ case NO_CURSOR:
+ break;
+ case HBAR_CURSOR:
+ BView_FillRectangle (view, fx, fy, w->phys_cursor_width, h);
+ break;
+ case BAR_CURSOR:
+ cursor_glyph = get_phys_cursor_glyph (w);
+ if (cursor_glyph->resolved_level & 1)
+ BView_FillRectangle (view, fx + cursor_glyph->pixel_width - w->phys_cursor_width,
+ fy, w->phys_cursor_width, h);
+ else
+ BView_FillRectangle (view, fx, fy, w->phys_cursor_width, h);
+ break;
+ case HOLLOW_BOX_CURSOR:
+ if (phys_cursor_glyph->type != IMAGE_GLYPH)
+ {
+ BView_SetPenSize (view, 1);
+ BView_StrokeRectangle (view, fx, fy, w->phys_cursor_width, h);
+ }
+ else
+ draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+ break;
+ case FILLED_BOX_CURSOR:
+ draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+ }
+ BView_EndClip (view);
+ BView_draw_unlock (view);
+}
+
+static void
+haiku_show_hourglass (struct frame *f)
+{
+ if (FRAME_OUTPUT_DATA (f)->hourglass_p)
+ return;
+
+ block_input ();
+ FRAME_OUTPUT_DATA (f)->hourglass_p = 1;
+
+ if (FRAME_HAIKU_VIEW (f))
+ BView_set_view_cursor (FRAME_HAIKU_VIEW (f),
+ FRAME_OUTPUT_DATA (f)->hourglass_cursor);
+ unblock_input ();
+}
+
+static void
+haiku_hide_hourglass (struct frame *f)
+{
+ if (!FRAME_OUTPUT_DATA (f)->hourglass_p)
+ return;
+
+ block_input ();
+ FRAME_OUTPUT_DATA (f)->hourglass_p = 0;
+
+ if (FRAME_HAIKU_VIEW (f))
+ BView_set_view_cursor (FRAME_HAIKU_VIEW (f),
+ FRAME_OUTPUT_DATA (f)->current_cursor);
+ unblock_input ();
+}
+
+static void
+haiku_compute_glyph_string_overhangs (struct glyph_string *s)
+{
+ if (s->cmp == NULL
+ && (s->first_glyph->type == CHAR_GLYPH
+ || s->first_glyph->type == COMPOSITE_GLYPH))
+ {
+ struct font_metrics metrics;
+
+ if (s->first_glyph->type == CHAR_GLYPH)
+ {
+ struct font *font = s->font;
+ font->driver->text_extents (font, s->char2b, s->nchars, &metrics);
+ }
+ else
+ {
+ Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
+
+ composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
+ }
+ s->right_overhang = (metrics.rbearing > metrics.width
+ ? metrics.rbearing - metrics.width : 0);
+ s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
+ }
+ else if (s->cmp)
+ {
+ s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
+ s->left_overhang = - s->cmp->lbearing;
+ }
+}
+
+static void
+haiku_draw_vertical_window_border (struct window *w,
+ int x, int y_0, int y_1)
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+ struct face *face;
+
+ face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
+ void *view = FRAME_HAIKU_VIEW (f);
+ BView_draw_lock (view);
+ BView_StartClip (view);
+ if (face)
+ BView_SetHighColor (view, face->foreground);
+ BView_StrokeLine (view, x, y_0, x, y_1);
+ BView_EndClip (view);
+ BView_draw_unlock (view);
+}
+
+static void
+haiku_set_scroll_bar_default_width (struct frame *f)
+{
+ int unit = FRAME_COLUMN_WIDTH (f);
+ FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = BScrollBar_default_size (0) + 1;
+ FRAME_CONFIG_SCROLL_BAR_COLS (f) =
+ (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
+}
+
+static void
+haiku_set_scroll_bar_default_height (struct frame *f)
+{
+ int height = FRAME_LINE_HEIGHT (f);
+ FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = BScrollBar_default_size (1) + 1;
+ FRAME_CONFIG_SCROLL_BAR_LINES (f) =
+ (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) + height - 1) / height;
+}
+
+static void
+haiku_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+ struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
+ struct face *face_first
+ = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
+ struct face *face_last
+ = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
+ unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
+ unsigned long color_first = (face_first
+ ? face_first->foreground
+ : FRAME_FOREGROUND_PIXEL (f));
+ unsigned long color_last = (face_last
+ ? face_last->foreground
+ : FRAME_FOREGROUND_PIXEL (f));
+ void *view = FRAME_HAIKU_VIEW (f);
+
+ BView_draw_lock (view);
+ BView_StartClip (view);
+
+ if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
+ /* A vertical divider, at least three pixels wide: Draw first and
+ last pixels differently. */
+ {
+ BView_SetHighColor (view, color_first);
+ BView_StrokeLine (view, x0, y0, x0, y1 - 1);
+ BView_SetHighColor (view, color);
+ BView_FillRectangle (view, x0 + 1, y0, x1 - x0 - 2, y1 - y0);
+ BView_SetHighColor (view, color_last);
+ BView_StrokeLine (view, x1 - 1, y0, x1 - 1, y1 - 1);
+ }
+ else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
+ /* A horizontal divider, at least three pixels high: Draw first and
+ last pixels differently. */
+ {
+ BView_SetHighColor (view, color_first);
+ BView_StrokeLine (f, x0, y0, x1 - 1, y0);
+ BView_SetHighColor (view, color);
+ BView_FillRectangle (view, x0, y0 + 1, x1 - x0, y1 - y0 - 2);
+ BView_SetHighColor (view, color_last);
+ BView_StrokeLine (view, x0, y1, x1 - 1, y1);
+ }
+ else
+ {
+ BView_SetHighColor (view, color);
+ BView_FillRectangleAbs (view, x0, y0, x1, y1);
+ }
+ BView_EndClip (view);
+ BView_draw_unlock (view);
+}
+
+static void
+haiku_condemn_scroll_bars (struct frame *frame)
+{
+ if (!NILP (FRAME_SCROLL_BARS (frame)))
+ {
+ if (!NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
+ {
+ /* Prepend scrollbars to already condemned ones. */
+ Lisp_Object last = FRAME_SCROLL_BARS (frame);
+
+ while (!NILP (XSCROLL_BAR (last)->next))
+ last = XSCROLL_BAR (last)->next;
+
+ XSCROLL_BAR (last)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
+ XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = last;
+ }
+
+ fset_condemned_scroll_bars (frame, FRAME_SCROLL_BARS (frame));
+ fset_scroll_bars (frame, Qnil);
+ }
+}
+
+static void
+haiku_redeem_scroll_bar (struct window *w)
+{
+ struct scroll_bar *bar;
+ Lisp_Object barobj;
+ struct frame *f;
+
+ if (!NILP (w->vertical_scroll_bar) && WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
+ {
+ bar = XSCROLL_BAR (w->vertical_scroll_bar);
+ /* Unlink it from the condemned list. */
+ f = XFRAME (WINDOW_FRAME (w));
+ if (NILP (bar->prev))
+ {
+ /* If the prev pointer is nil, it must be the first in one of
+ the lists. */
+ if (EQ (FRAME_SCROLL_BARS (f), w->vertical_scroll_bar))
+ /* It's not condemned. Everything's fine. */
+ goto horizontal;
+ else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
+ w->vertical_scroll_bar))
+ fset_condemned_scroll_bars (f, bar->next);
+ else
+ /* If its prev pointer is nil, it must be at the front of
+ one or the other! */
+ emacs_abort ();
+ }
+ else
+ XSCROLL_BAR (bar->prev)->next = bar->next;
+
+ if (! NILP (bar->next))
+ XSCROLL_BAR (bar->next)->prev = bar->prev;
+
+ bar->next = FRAME_SCROLL_BARS (f);
+ bar->prev = Qnil;
+ XSETVECTOR (barobj, bar);
+ fset_scroll_bars (f, barobj);
+ if (! NILP (bar->next))
+ XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
+ }
+ horizontal:
+ if (!NILP (w->horizontal_scroll_bar) && WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
+ {
+ bar = XSCROLL_BAR (w->horizontal_scroll_bar);
+ /* Unlink it from the condemned list. */
+ f = XFRAME (WINDOW_FRAME (w));
+ if (NILP (bar->prev))
+ {
+ /* If the prev pointer is nil, it must be the first in one of
+ the lists. */
+ if (EQ (FRAME_SCROLL_BARS (f), w->horizontal_scroll_bar))
+ /* It's not condemned. Everything's fine. */
+ return;
+ else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
+ w->horizontal_scroll_bar))
+ fset_condemned_scroll_bars (f, bar->next);
+ else
+ /* If its prev pointer is nil, it must be at the front of
+ one or the other! */
+ emacs_abort ();
+ }
+ else
+ XSCROLL_BAR (bar->prev)->next = bar->next;
+
+ if (! NILP (bar->next))
+ XSCROLL_BAR (bar->next)->prev = bar->prev;
+
+ bar->next = FRAME_SCROLL_BARS (f);
+ bar->prev = Qnil;
+ XSETVECTOR (barobj, bar);
+ fset_scroll_bars (f, barobj);
+ if (! NILP (bar->next))
+ XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
+ }
+}
+
+static void
+haiku_judge_scroll_bars (struct frame *f)
+{
+ Lisp_Object bar, next;
+
+ bar = FRAME_CONDEMNED_SCROLL_BARS (f);
+
+ /* Clear out the condemned list now so we won't try to process any
+ more events on the hapless scroll bars. */
+ fset_condemned_scroll_bars (f, Qnil);
+
+ for (; ! NILP (bar); bar = next)
+ {
+ struct scroll_bar *b = XSCROLL_BAR (bar);
+
+ haiku_scroll_bar_remove (b);
+
+ next = b->next;
+ b->next = b->prev = Qnil;
+ }
+
+ /* Now there should be no references to the condemned scroll bars,
+ and they should get garbage-collected. */
+}
+
+static struct scroll_bar *
+haiku_scroll_bar_create (struct window *w, int left, int top,
+ int width, int height, bool horizontal_p)
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+ Lisp_Object barobj;
+
+ void *sb = NULL;
+ void *vw = FRAME_HAIKU_VIEW (f);
+
+ block_input ();
+ struct scroll_bar *bar
+ = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, prev, PVEC_OTHER);
+
+ XSETWINDOW (bar->window, w);
+ bar->top = top;
+ bar->left = left;
+ bar->width = width;
+ bar->height = height;
+ bar->position = 0;
+ bar->total = 0;
+ bar->dragging = 0;
+ bar->update = -1;
+ bar->horizontal = horizontal_p;
+
+ sb = BScrollBar_make_for_view (vw, horizontal_p,
+ left, top, left + width - 1,
+ top + height - 1, bar);
+
+ BView_publish_scroll_bar (vw, left, top, width, height);
+
+ bar->next = FRAME_SCROLL_BARS (f);
+ bar->prev = Qnil;
+ bar->scroll_bar = sb;
+ XSETVECTOR (barobj, bar);
+ fset_scroll_bars (f, barobj);
+
+ if (!NILP (bar->next))
+ XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
+
+ unblock_input ();
+ return bar;
+}
+
+static void
+haiku_set_horizontal_scroll_bar (struct window *w, int portion, int whole, int position)
+{
+ eassert (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w));
+ Lisp_Object barobj;
+ struct scroll_bar *bar;
+ int top, height, left, width;
+ int window_x, window_width;
+
+ /* Get window dimensions. */
+ window_box (w, ANY_AREA, &window_x, 0, &window_width, 0);
+ left = window_x;
+ width = window_width;
+ top = WINDOW_SCROLL_BAR_AREA_Y (w);
+ height = WINDOW_CONFIG_SCROLL_BAR_HEIGHT (w);
+
+ block_input ();
+
+ if (NILP (w->horizontal_scroll_bar))
+ {
+ bar = haiku_scroll_bar_create (w, left, top, width, height, true);
+ BView_scroll_bar_update (bar->scroll_bar, portion, whole, position);
+ bar->update = position;
+ bar->position = position;
+ bar->total = whole;
+ }
+ else
+ {
+ bar = XSCROLL_BAR (w->horizontal_scroll_bar);
+
+ if (bar->left != left || bar->top != top ||
+ bar->width != width || bar->height != height)
+ {
+ void *view = FRAME_HAIKU_VIEW (WINDOW_XFRAME (w));
+ BView_forget_scroll_bar (view, bar->left, bar->top,
+ bar->width, bar->height);
+ BView_move_frame (bar->scroll_bar, left, top,
+ left + width - 1, top + height - 1);
+ BView_publish_scroll_bar (view, left, top, width, height);
+ bar->left = left;
+ bar->top = top;
+ bar->width = width;
+ bar->height = height;
+ }
+
+ if (!bar->dragging)
+ {
+ BView_scroll_bar_update (bar->scroll_bar, portion, whole, position);
+ BView_invalidate (bar->scroll_bar);
+ }
+ }
+ bar->position = position;
+ bar->total = whole;
+ XSETVECTOR (barobj, bar);
+ wset_horizontal_scroll_bar (w, barobj);
+ unblock_input ();
+}
+
+static void
+haiku_set_vertical_scroll_bar (struct window *w,
+ int portion, int whole, int position)
+{
+ eassert (WINDOW_HAS_VERTICAL_SCROLL_BAR (w));
+ Lisp_Object barobj;
+ struct scroll_bar *bar;
+ int top, height, left, width;
+ int window_y, window_height;
+
+ /* Get window dimensions. */
+ window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
+ top = window_y;
+ height = window_height;
+
+ /* Compute the left edge and the width of the scroll bar area. */
+ left = WINDOW_SCROLL_BAR_AREA_X (w);
+ width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
+ block_input ();
+
+ if (NILP (w->vertical_scroll_bar))
+ {
+ bar = haiku_scroll_bar_create (w, left, top, width, height, false);
+ BView_scroll_bar_update (bar->scroll_bar, portion, whole, position);
+ bar->position = position;
+ bar->total = whole;
+ }
+ else
+ {
+ bar = XSCROLL_BAR (w->vertical_scroll_bar);
+
+ if (bar->left != left || bar->top != top ||
+ bar->width != width || bar->height != height)
+ {
+ void *view = FRAME_HAIKU_VIEW (WINDOW_XFRAME (w));
+ BView_forget_scroll_bar (view, bar->left, bar->top,
+ bar->width, bar->height);
+ BView_move_frame (bar->scroll_bar, left, top,
+ left + width - 1, top + height - 1);
+ flush_frame (WINDOW_XFRAME (w));
+ BView_publish_scroll_bar (view, left, top, width, height);
+ bar->left = left;
+ bar->top = top;
+ bar->width = width;
+ bar->height = height;
+ }
+
+ if (!bar->dragging)
+ {
+ BView_scroll_bar_update (bar->scroll_bar, portion, whole, position);
+ bar->update = position;
+ BView_invalidate (bar->scroll_bar);
+ }
+ }
+
+ bar->position = position;
+ bar->total = whole;
+
+ XSETVECTOR (barobj, bar);
+ wset_vertical_scroll_bar (w, barobj);
+ unblock_input ();
+}
+
+static void
+haiku_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
+ struct draw_fringe_bitmap_params *p)
+{
+ void *view = FRAME_HAIKU_VIEW (XFRAME (WINDOW_FRAME (w)));
+ struct face *face = p->face;
+
+ BView_draw_lock (view);
+ BView_StartClip (view);
+
+ haiku_clip_to_row (w, row, ANY_AREA);
+ if (p->bx >= 0 && !p->overlay_p)
+ {
+ BView_SetHighColor (view, face->background);
+ BView_FillRectangle (view, p->bx, p->by, p->nx, p->ny);
+ }
+
+ if (p->which && p->which < fringe_bitmap_fillptr)
+ {
+ void *bitmap = fringe_bmps[p->which];
+
+ uint32_t col;
+
+ if (!p->cursor_p)
+ col = face->foreground;
+ else if (p->overlay_p)
+ col = face->background;
+ else
+ col = FRAME_CURSOR_COLOR (XFRAME (WINDOW_FRAME (w))).pixel;
+
+ if (!p->overlay_p)
+ {
+ BView_SetHighColor (view, face->background);
+ BView_FillRectangle (view, p->x, p->y, p->wd, p->h);
+ }
+
+ BView_SetLowColor (view, col);
+ BView_DrawBitmapWithEraseOp (view, bitmap, p->x, p->y, p->wd, p->h);
+ }
+ BView_EndClip (view);
+ BView_draw_unlock (view);
+}
+
+static void
+haiku_define_fringe_bitmap (int which, unsigned short *bits,
+ int h, int wd)
+{
+ if (which >= fringe_bitmap_fillptr)
+ {
+ int i = fringe_bitmap_fillptr;
+ fringe_bitmap_fillptr = which + 20;
+ fringe_bmps = !i ? xmalloc (fringe_bitmap_fillptr * sizeof (void *)) :
+ xrealloc (fringe_bmps, fringe_bitmap_fillptr * sizeof (void *));
+
+ while (i < fringe_bitmap_fillptr)
+ fringe_bmps[i++] = NULL;
+ }
+
+ fringe_bmps[which] = BBitmap_new (wd, h, 1);
+ BBitmap_import_mono_bits (fringe_bmps[which], bits, wd, h);
+}
+
+static void
+haiku_destroy_fringe_bitmap (int which)
+{
+ if (which >= fringe_bitmap_fillptr)
+ return;
+
+ if (fringe_bmps[which])
+ BBitmap_free (fringe_bmps[which]);
+ fringe_bmps[which] = NULL;
+}
+
+static void
+haiku_scroll_run (struct window *w, struct run *run)
+{
+ struct frame *f = XFRAME (w->frame);
+ void *view = FRAME_HAIKU_VIEW (f);
+ int x, y, width, height, from_y, to_y, bottom_y;
+ window_box (w, ANY_AREA, &x, &y, &width, &height);
+
+ from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
+ to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
+ bottom_y = y + height;
+
+ if (to_y < from_y)
+ {
+ /* Scrolling up. Make sure we don't copy part of the mode
+ line at the bottom. */
+ if (from_y + run->height > bottom_y)
+ height = bottom_y - from_y;
+ else
+ height = run->height;
+ }
+ else
+ {
+ /* Scrolling down. Make sure we don't copy over the mode line.
+ at the bottom. */
+ if (to_y + run->height > bottom_y)
+ height = bottom_y - to_y;
+ else
+ height = run->height;
+ }
+
+ if (!height)
+ return;
+
+ block_input ();
+ gui_clear_cursor (w);
+ BView_draw_lock (view);
+#ifdef USE_BE_CAIRO
+ if (EmacsView_double_buffered_p (view))
+ {
+#endif
+ BView_StartClip (view);
+ BView_CopyBits (view, x, from_y, width, height,
+ x, to_y, width, height);
+ BView_EndClip (view);
+#ifdef USE_BE_CAIRO
+ }
+ else
+ {
+ EmacsWindow_begin_cr_critical_section (FRAME_HAIKU_WINDOW (f));
+ cairo_surface_t *surface = FRAME_CR_SURFACE (f);
+ cairo_surface_t *s
+ = cairo_surface_create_similar (surface,
+ cairo_surface_get_content (surface),
+ width, height);
+ cairo_t *cr = cairo_create (s);
+ if (surface)
+ {
+ cairo_set_source_surface (cr, surface, -x, -from_y);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cr = haiku_begin_cr_clip (f, NULL);
+ cairo_save (cr);
+ cairo_set_source_surface (cr, s, x, to_y);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, x, to_y, width, height);
+ cairo_fill (cr);
+ cairo_restore (cr);
+ cairo_surface_destroy (s);
+ haiku_end_cr_clip (cr);
+ }
+ EmacsWindow_end_cr_critical_section (FRAME_HAIKU_WINDOW (f));
+ }
+#endif
+ BView_draw_unlock (view);
+
+ unblock_input ();
+}
+
+static void
+haiku_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
+ enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
+ Time *timestamp)
+{
+ if (!fp)
+ return;
+
+ block_input ();
+ Lisp_Object frame, tail;
+ struct frame *f1 = NULL;
+ FOR_EACH_FRAME (tail, frame)
+ XFRAME (frame)->mouse_moved = false;
+
+ if (gui_mouse_grabbed (x_display_list) && !EQ (track_mouse, Qdropping))
+ f1 = x_display_list->last_mouse_frame;
+
+ if (!f1 || FRAME_TOOLTIP_P (f1))
+ f1 = ((EQ (track_mouse, Qdropping) && gui_mouse_grabbed (x_display_list))
+ ? x_display_list->last_mouse_frame
+ : NULL);
+
+ if (!f1 && insist > 0)
+ f1 = SELECTED_FRAME ();
+
+ if (!f1 || (!FRAME_HAIKU_P (f1) && (insist > 0)))
+ FOR_EACH_FRAME (tail, frame)
+ if (FRAME_HAIKU_P (XFRAME (frame)) &&
+ !FRAME_TOOLTIP_P (XFRAME (frame)))
+ f1 = XFRAME (frame);
+
+ if (FRAME_TOOLTIP_P (f1))
+ f1 = NULL;
+
+ if (f1 && FRAME_HAIKU_P (f1))
+ {
+ int sx, sy;
+ void *view = FRAME_HAIKU_VIEW (f1);
+ if (view)
+ {
+ BView_get_mouse (view, &sx, &sy);
+
+ remember_mouse_glyph (f1, sx, sy, &x_display_list->last_mouse_glyph);
+ x_display_list->last_mouse_glyph_frame = f1;
+
+ *bar_window = Qnil;
+ *part = scroll_bar_above_handle;
+ *fp = f1;
+ *timestamp = x_display_list->last_mouse_movement_time;
+ XSETINT (*x, sx);
+ XSETINT (*y, sy);
+ }
+ }
+
+ unblock_input ();
+}
+
+static void
+haiku_flush (struct frame *f)
+{
+ if (FRAME_VISIBLE_P (f))
+ BWindow_Flush (FRAME_HAIKU_WINDOW (f));
+}
+
+static void
+haiku_define_frame_cursor (struct frame *f, Emacs_Cursor cursor)
+{
+ if (f->tooltip)
+ return;
+ block_input ();
+ if (!f->pointer_invisible && FRAME_HAIKU_VIEW (f)
+ && !FRAME_OUTPUT_DATA (f)->hourglass_p)
+ BView_set_view_cursor (FRAME_HAIKU_VIEW (f), cursor);
+ unblock_input ();
+ FRAME_OUTPUT_DATA (f)->current_cursor = cursor;
+}
+
+static void
+haiku_update_window_end (struct window *w, bool cursor_on_p,
+ bool mouse_face_overwritten_p)
+{
+
+}
+
+static void
+haiku_default_font_parameter (struct frame *f, Lisp_Object parms)
+{
+ struct haiku_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+ Lisp_Object font_param = gui_display_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
+ RES_TYPE_STRING);
+ Lisp_Object font = Qnil;
+ if (EQ (font_param, Qunbound))
+ 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;
+
+ if (f->tooltip)
+ BFont_populate_plain_family (&ptn);
+ else
+ BFont_populate_fixed_family (&ptn);
+
+ if (ptn.specified & FSPEC_FAMILY)
+ font = font_open_by_name (f, build_unibyte_string (ptn.family));
+ }
+
+ if (NILP (font))
+ font = !NILP (font_param) ? font_param
+ : gui_display_get_arg (dpyinfo, parms, Qfont, "font", "Font",
+ RES_TYPE_STRING);
+
+ if (! FONTP (font) && ! STRINGP (font))
+ {
+ const char **names = (const char *[]) { "monospace-12",
+ "Noto Sans Mono-12",
+ "Source Code Pro-12",
+ NULL };
+ int i;
+
+ for (i = 0; names[i]; i++)
+ {
+ font
+ = font_open_by_name (f, build_unibyte_string (names[i]));
+ if (!NILP (font))
+ break;
+ }
+ if (NILP (font))
+ error ("No suitable font was found");
+ }
+ else if (!NILP (font_param))
+ {
+ /* Remember the explicit font parameter, so we can re-apply it
+ after we've applied the `default' face settings. */
+ AUTO_FRAME_ARG (arg, Qfont_parameter, font_param);
+ gui_set_frame_parameters (f, arg);
+ }
+
+ gui_default_parameter (f, parms, Qfont, font, "font", "Font",
+ RES_TYPE_STRING);
+}
+
+static struct redisplay_interface haiku_redisplay_interface =
+ {
+ haiku_frame_parm_handlers,
+ gui_produce_glyphs,
+ gui_write_glyphs,
+ gui_insert_glyphs,
+ gui_clear_end_of_line,
+ haiku_scroll_run,
+ haiku_after_update_window_line,
+ NULL,
+ haiku_update_window_end,
+ haiku_flush,
+ gui_clear_window_mouse_face,
+ gui_get_glyph_overhangs,
+ gui_fix_overlapping_area,
+ haiku_draw_fringe_bitmap,
+ haiku_define_fringe_bitmap,
+ haiku_destroy_fringe_bitmap,
+ haiku_compute_glyph_string_overhangs,
+ haiku_draw_glyph_string,
+ haiku_define_frame_cursor,
+ haiku_clear_frame_area,
+ haiku_clear_under_internal_border,
+ haiku_draw_window_cursor,
+ haiku_draw_vertical_window_border,
+ haiku_draw_window_divider,
+ 0, /* shift glyphs for insert */
+ haiku_show_hourglass,
+ haiku_hide_hourglass,
+ haiku_default_font_parameter,
+ };
+
+static void
+haiku_make_fullscreen_consistent (struct frame *f)
+{
+ Lisp_Object lval = get_frame_param (f, Qfullscreen);
+
+ if (!EQ (lval, Qmaximized) && FRAME_OUTPUT_DATA (f)->zoomed_p)
+ lval = Qmaximized;
+ else if (EQ (lval, Qmaximized) && !FRAME_OUTPUT_DATA (f)->zoomed_p)
+ lval = Qnil;
+
+ store_frame_param (f, Qfullscreen, lval);
+}
+
+static void
+flush_dirty_back_buffers (void)
+{
+ block_input ();
+ Lisp_Object tail, frame;
+ FOR_EACH_FRAME (tail, frame)
+ {
+ struct frame *f = XFRAME (frame);
+ if (FRAME_LIVE_P (f) &&
+ FRAME_HAIKU_P (f) &&
+ FRAME_HAIKU_WINDOW (f) &&
+ !FRAME_GARBAGED_P (f) &&
+ !buffer_flipping_blocked_p () &&
+ FRAME_DIRTY_P (f))
+ haiku_flip_buffers (f);
+ }
+ unblock_input ();
+}
+
+static int
+haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
+{
+ block_input ();
+ int message_count = 0;
+ static void *buf = NULL;
+ ssize_t b_size;
+ struct unhandled_event *unhandled_events = NULL;
+ int button_or_motion_p;
+ int need_flush = 0;
+
+ if (!buf)
+ buf = xmalloc (200);
+ haiku_read_size (&b_size);
+ while (b_size >= 0)
+ {
+ enum haiku_event_type type;
+ struct input_event inev, inev2;
+
+ if (b_size > 200)
+ emacs_abort ();
+
+ EVENT_INIT (inev);
+ EVENT_INIT (inev2);
+ inev.kind = NO_EVENT;
+ inev2.kind = NO_EVENT;
+ inev.arg = Qnil;
+ inev2.arg = Qnil;
+
+ button_or_motion_p = 0;
+
+ haiku_read (&type, buf, b_size);
+
+ switch (type)
+ {
+ case QUIT_REQUESTED:
+ {
+ struct haiku_quit_requested_event *b = buf;
+ struct frame *f = haiku_window_to_frame (b->window);
+
+ if (!f)
+ continue;
+
+ inev.kind = DELETE_WINDOW_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
+ break;
+ }
+ case FRAME_RESIZED:
+ {
+ struct haiku_resize_event *b = buf;
+ struct frame *f = haiku_window_to_frame (b->window);
+
+ if (!f)
+ continue;
+
+ int width = lrint (b->px_widthf);
+ int height = lrint (b->px_heightf);
+
+ BView_draw_lock (FRAME_HAIKU_VIEW (f));
+ BView_resize_to (FRAME_HAIKU_VIEW (f), width, height);
+ BView_draw_unlock (FRAME_HAIKU_VIEW (f));
+ if (width != FRAME_PIXEL_WIDTH (f)
+ || height != FRAME_PIXEL_HEIGHT (f)
+ || (f->new_size_p
+ && ((f->new_width >= 0 && width != f->new_width)
+ || (f->new_height >= 0 && height != f->new_height))))
+ {
+ change_frame_size (f, width, height, false, true, false);
+ SET_FRAME_GARBAGED (f);
+ cancel_mouse_face (f);
+ haiku_clear_under_internal_border (f);
+ }
+
+ if (FRAME_OUTPUT_DATA (f)->pending_zoom_width != width ||
+ FRAME_OUTPUT_DATA (f)->pending_zoom_height != height)
+ {
+ FRAME_OUTPUT_DATA (f)->zoomed_p = 0;
+ haiku_make_fullscreen_consistent (f);
+ }
+ else
+ {
+ FRAME_OUTPUT_DATA (f)->zoomed_p = 1;
+ FRAME_OUTPUT_DATA (f)->pending_zoom_width = INT_MIN;
+ FRAME_OUTPUT_DATA (f)->pending_zoom_height = INT_MIN;
+ }
+ break;
+ }
+ case FRAME_EXPOSED:
+ {
+ struct haiku_expose_event *b = buf;
+ struct frame *f = haiku_window_to_frame (b->window);
+
+ if (!f)
+ continue;
+
+ expose_frame (f, b->x, b->y, b->width, b->height);
+
+ haiku_clear_under_internal_border (f);
+ break;
+ }
+ case KEY_DOWN:
+ {
+ struct haiku_key_event *b = buf;
+ struct frame *f = haiku_window_to_frame (b->window);
+ int non_ascii_p;
+ if (!f)
+ continue;
+
+ inev.code = b->unraw_mb_char;
+
+ BMapKey (b->kc, &non_ascii_p, &inev.code);
+
+ if (non_ascii_p)
+ inev.kind = NON_ASCII_KEYSTROKE_EVENT;
+ else
+ inev.kind = inev.code > 127 ? MULTIBYTE_CHAR_KEYSTROKE_EVENT :
+ ASCII_KEYSTROKE_EVENT;
+
+ inev.modifiers = haiku_modifiers_to_emacs (b->modifiers);
+ XSETFRAME (inev.frame_or_window, f);
+ break;
+ }
+ case ACTIVATION:
+ {
+ struct haiku_activation_event *b = buf;
+ struct frame *f = haiku_window_to_frame (b->window);
+
+ if (!f)
+ continue;
+
+ if ((x_display_list->focus_event_frame != f && b->activated_p) ||
+ (x_display_list->focus_event_frame == f && !b->activated_p))
+ {
+ haiku_new_focus_frame (b->activated_p ? f : NULL);
+ if (b->activated_p)
+ x_display_list->focus_event_frame = f;
+ else
+ x_display_list->focus_event_frame = NULL;
+ inev.kind = b->activated_p ? FOCUS_IN_EVENT : FOCUS_OUT_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
+ }
+
+ break;
+ }
+ case MOUSE_MOTION:
+ {
+ struct haiku_mouse_motion_event *b = buf;
+ struct frame *f = haiku_window_to_frame (b->window);
+
+ if (!f)
+ continue;
+
+ Lisp_Object frame;
+ XSETFRAME (frame, f);
+
+ x_display_list->last_mouse_movement_time = time (NULL);
+ button_or_motion_p = 1;
+
+ if (b->just_exited_p)
+ {
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+ if (f == hlinfo->mouse_face_mouse_frame)
+ {
+ /* If we move outside the frame, then we're
+ certainly no longer on any text in the frame. */
+ clear_mouse_face (hlinfo);
+ hlinfo->mouse_face_mouse_frame = 0;
+ }
+
+ haiku_new_focus_frame (x_display_list->focused_frame);
+ help_echo_string = Qnil;
+ gen_help_event (Qnil, frame, Qnil, Qnil, 0);
+ }
+ else
+ {
+ struct haiku_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+ struct haiku_rect r = dpyinfo->last_mouse_glyph;
+
+ dpyinfo->last_mouse_motion_x = b->x;
+ dpyinfo->last_mouse_motion_y = b->y;
+ dpyinfo->last_mouse_motion_frame = f;
+
+ previous_help_echo_string = help_echo_string;
+ help_echo_string = Qnil;
+
+ if (f != dpyinfo->last_mouse_glyph_frame
+ || b->x < r.x || b->x >= r.x + r.width
+ || b->y < r.y || b->y >= r.y + r.height)
+ {
+ f->mouse_moved = true;
+ dpyinfo->last_mouse_scroll_bar = NULL;
+ note_mouse_highlight (f, b->x, b->y);
+ remember_mouse_glyph (f, b->x, b->y,
+ &FRAME_DISPLAY_INFO (f)->last_mouse_glyph);
+ dpyinfo->last_mouse_glyph_frame = f;
+ gen_help_event (help_echo_string, frame, help_echo_window,
+ help_echo_object, help_echo_pos);
+ }
+
+ if (MOUSE_HL_INFO (f)->mouse_face_hidden)
+ {
+ MOUSE_HL_INFO (f)->mouse_face_hidden = 0;
+ clear_mouse_face (MOUSE_HL_INFO (f));
+ }
+
+ if (!NILP (Vmouse_autoselect_window))
+ {
+ static Lisp_Object last_mouse_window;
+ Lisp_Object window = window_from_coordinates (f, b->x, b->y, 0, 0, 0);
+
+ if (WINDOWP (window)
+ && !EQ (window, last_mouse_window)
+ && !EQ (window, selected_window)
+ && (!NILP (focus_follows_mouse)
+ || (EQ (XWINDOW (window)->frame,
+ XWINDOW (selected_window)->frame))))
+ {
+ inev.kind = SELECT_WINDOW_EVENT;
+ inev.frame_or_window = window;
+ }
+
+ last_mouse_window = window;
+ }
+ }
+ break;
+ }
+ case BUTTON_UP:
+ case BUTTON_DOWN:
+ {
+ struct haiku_button_event *b = buf;
+ struct frame *f = haiku_window_to_frame (b->window);
+ Lisp_Object tab_bar_arg = Qnil;
+ int tab_bar_p = 0, tool_bar_p = 0;
+
+ if (!f)
+ continue;
+
+ struct haiku_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+
+ inev.modifiers = haiku_modifiers_to_emacs (b->modifiers);
+
+ x_display_list->last_mouse_glyph_frame = 0;
+ x_display_list->last_mouse_movement_time = time (NULL);
+ button_or_motion_p = 1;
+
+ /* Is this in the tab-bar? */
+ if (WINDOWP (f->tab_bar_window)
+ && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
+ {
+ Lisp_Object window;
+ int x = b->x;
+ int y = b->y;
+
+ window = window_from_coordinates (f, x, y, 0, true, true);
+ tab_bar_p = EQ (window, f->tab_bar_window);
+
+ if (tab_bar_p)
+ {
+ tab_bar_arg = handle_tab_bar_click
+ (f, x, y, type == BUTTON_DOWN, inev.modifiers);
+ need_flush = 1;
+ }
+ }
+
+ if (WINDOWP (f->tool_bar_window)
+ && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
+ {
+ Lisp_Object window;
+ int x = b->x;
+ int y = b->y;
+
+ window = window_from_coordinates (f, x, y, 0, true, true);
+ tool_bar_p = EQ (window, f->tool_bar_window);
+
+ if (tool_bar_p)
+ {
+ handle_tool_bar_click
+ (f, x, y, type == BUTTON_DOWN, inev.modifiers);
+ need_flush = 1;
+ }
+ }
+
+ if (type == BUTTON_UP)
+ {
+ inev.modifiers |= up_modifier;
+ dpyinfo->grabbed &= ~(1 << b->btn_no);
+ }
+ else
+ {
+ inev.modifiers |= down_modifier;
+ dpyinfo->last_mouse_frame = f;
+ dpyinfo->grabbed |= (1 << b->btn_no);
+ if (f && !tab_bar_p)
+ f->last_tab_bar_item = -1;
+ if (f && !tool_bar_p)
+ f->last_tool_bar_item = -1;
+ }
+
+ if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p)
+ inev.kind = MOUSE_CLICK_EVENT;
+ inev.arg = tab_bar_arg;
+ inev.code = b->btn_no;
+
+ f->mouse_moved = false;
+
+ XSETINT (inev.x, b->x);
+ XSETINT (inev.y, b->y);
+
+ XSETFRAME (inev.frame_or_window, f);
+ break;
+ }
+ case ICONIFICATION:
+ {
+ struct haiku_iconification_event *b = buf;
+ struct frame *f = haiku_window_to_frame (b->window);
+
+ if (!f)
+ continue;
+
+ if (!b->iconified_p)
+ {
+ SET_FRAME_VISIBLE (f, 1);
+ SET_FRAME_ICONIFIED (f, 0);
+ inev.kind = DEICONIFY_EVENT;
+
+
+ /* Haiku doesn't expose frames on deiconification, but
+ if we are double-buffered, the previous screen
+ contents should have been preserved. */
+ if (!EmacsView_double_buffered_p (FRAME_HAIKU_VIEW (f)))
+ {
+ SET_FRAME_GARBAGED (f);
+ expose_frame (f, 0, 0, 0, 0);
+ }
+ }
+ else
+ {
+ SET_FRAME_VISIBLE (f, 0);
+ SET_FRAME_ICONIFIED (f, 1);
+ inev.kind = ICONIFY_EVENT;
+ }
+
+ XSETFRAME (inev.frame_or_window, f);
+ break;
+ }
+ case MOVE_EVENT:
+ {
+ struct haiku_move_event *b = buf;
+ struct frame *f = haiku_window_to_frame (b->window);
+
+ if (!f)
+ continue;
+
+ if (FRAME_OUTPUT_DATA (f)->pending_zoom_x != b->x ||
+ FRAME_OUTPUT_DATA (f)->pending_zoom_y != b->y)
+ FRAME_OUTPUT_DATA (f)->zoomed_p = 0;
+ else
+ {
+ FRAME_OUTPUT_DATA (f)->zoomed_p = 1;
+ FRAME_OUTPUT_DATA (f)->pending_zoom_x = INT_MIN;
+ FRAME_OUTPUT_DATA (f)->pending_zoom_y = INT_MIN;
+ }
+
+ if (FRAME_PARENT_FRAME (f))
+ haiku_coords_from_parent (f, &b->x, &b->y);
+
+ if (b->x != f->left_pos || b->y != f->top_pos)
+ {
+ inev.kind = MOVE_FRAME_EVENT;
+
+ XSETINT (inev.x, b->x);
+ XSETINT (inev.y, b->y);
+
+ f->left_pos = b->x;
+ f->top_pos = b->y;
+
+ struct frame *p;
+
+ if ((p = FRAME_PARENT_FRAME (f)))
+ {
+ void *window = FRAME_HAIKU_WINDOW (p);
+ EmacsWindow_move_weak_child (window, b->window, b->x, b->y);
+ }
+
+ XSETFRAME (inev.frame_or_window, f);
+ }
+
+ haiku_make_fullscreen_consistent (f);
+ break;
+ }
+ case SCROLL_BAR_VALUE_EVENT:
+ {
+ struct haiku_scroll_bar_value_event *b = buf;
+ struct scroll_bar *bar = b->scroll_bar;
+
+ struct window *w = XWINDOW (bar->window);
+
+ if (bar->update != -1)
+ {
+ bar->update = -1;
+ break;
+ }
+
+ if (bar->position != b->position)
+ {
+ inev.kind = bar->horizontal ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT :
+ SCROLL_BAR_CLICK_EVENT;
+ inev.part = bar->horizontal ?
+ scroll_bar_horizontal_handle : scroll_bar_handle;
+
+ XSETINT (inev.x, b->position);
+ XSETINT (inev.y, bar->total);
+ XSETWINDOW (inev.frame_or_window, w);
+ }
+ break;
+ }
+ case SCROLL_BAR_DRAG_EVENT:
+ {
+ struct haiku_scroll_bar_drag_event *b = buf;
+ struct scroll_bar *bar = b->scroll_bar;
+
+ bar->dragging = b->dragging_p;
+ if (!b->dragging_p && bar->horizontal)
+ set_horizontal_scroll_bar (XWINDOW (bar->window));
+ else if (!b->dragging_p)
+ set_vertical_scroll_bar (XWINDOW (bar->window));
+ break;
+ }
+ case WHEEL_MOVE_EVENT:
+ {
+ struct haiku_wheel_move_event *b = buf;
+ struct frame *f = haiku_window_to_frame (b->window);
+ int x, y;
+ static float px = 0.0f, py = 0.0f;
+
+ if (!f)
+ continue;
+ BView_get_mouse (FRAME_HAIKU_VIEW (f), &x, &y);
+
+ inev.modifiers = haiku_modifiers_to_emacs (b->modifiers);
+
+ inev2.modifiers = inev.modifiers;
+
+ if (signbit (px) != signbit (b->delta_x))
+ px = 0;
+
+ if (signbit (py) != signbit (b->delta_y))
+ py = 0;
+
+ px += (b->delta_x
+ * powf (FRAME_PIXEL_HEIGHT (f), 2.0f / 3.0f));
+ py += (b->delta_y
+ * powf (FRAME_PIXEL_HEIGHT (f), 2.0f / 3.0f));
+
+ if (fabsf (py) >= FRAME_LINE_HEIGHT (f)
+ || fabsf (px) >= FRAME_COLUMN_WIDTH (f)
+ || !mwheel_coalesce_scroll_events)
+ {
+ inev.kind = (fabsf (px) > fabsf (py)
+ ? HORIZ_WHEEL_EVENT
+ : WHEEL_EVENT);
+ inev.code = 0;
+
+ XSETINT (inev.x, x);
+ XSETINT (inev.y, y);
+ inev.arg = list3 (Qnil, make_float (-px),
+ make_float (-py));
+ XSETFRAME (inev.frame_or_window, f);
+
+ inev.modifiers |= (signbit (inev.kind == HORIZ_WHEEL_EVENT
+ ? px : py)
+ ? up_modifier
+ : down_modifier);
+ py = 0.0f;
+ px = 0.0f;
+ }
+
+ break;
+ }
+
+ case MENU_BAR_RESIZE:
+ {
+ struct haiku_menu_bar_resize_event *b = buf;
+ struct frame *f = haiku_window_to_frame (b->window);
+
+ if (!f || !FRAME_EXTERNAL_MENU_BAR (f))
+ continue;
+
+ int old_height = FRAME_MENU_BAR_HEIGHT (f);
+
+ FRAME_MENU_BAR_HEIGHT (f) = b->height + 1;
+ FRAME_MENU_BAR_LINES (f) =
+ (b->height + FRAME_LINE_HEIGHT (f)) / FRAME_LINE_HEIGHT (f);
+
+ if (old_height != b->height)
+ {
+ adjust_frame_size (f, -1, -1, 3, true, Qmenu_bar_lines);
+ haiku_clear_under_internal_border (f);
+ }
+ break;
+ }
+ case MENU_BAR_OPEN:
+ case MENU_BAR_CLOSE:
+ {
+ struct haiku_menu_bar_state_event *b = buf;
+ struct frame *f = haiku_window_to_frame (b->window);
+
+ if (!f || !FRAME_EXTERNAL_MENU_BAR (f))
+ continue;
+
+ if (type == MENU_BAR_OPEN)
+ {
+ if (!FRAME_OUTPUT_DATA (f)->menu_up_to_date_p)
+ {
+ BView_draw_lock (FRAME_HAIKU_VIEW (f));
+ /* This shouldn't be here, but nsmenu does it, so
+ it should probably be safe. */
+ int was_waiting_for_input_p = waiting_for_input;
+ if (waiting_for_input)
+ waiting_for_input = 0;
+ set_frame_menubar (f, 1);
+ waiting_for_input = was_waiting_for_input_p;
+ BView_draw_unlock (FRAME_HAIKU_VIEW (f));
+ }
+ FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 1;
+ popup_activated_p += 1;
+ }
+ else
+ {
+ if (!popup_activated_p)
+ emacs_abort ();
+ if (FRAME_OUTPUT_DATA (f)->menu_bar_open_p)
+ {
+ FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 0;
+ popup_activated_p -= 1;
+ }
+ }
+ break;
+ }
+ case MENU_BAR_SELECT_EVENT:
+ {
+ struct haiku_menu_bar_select_event *b = buf;
+ struct frame *f = haiku_window_to_frame (b->window);
+
+ if (!f || !FRAME_EXTERNAL_MENU_BAR (f))
+ continue;
+
+ if (FRAME_OUTPUT_DATA (f)->menu_up_to_date_p)
+ find_and_call_menu_selection (f, f->menu_bar_items_used,
+ f->menu_bar_vector, b->ptr);
+ break;
+ }
+ case FILE_PANEL_EVENT:
+ {
+ if (!popup_activated_p)
+ continue;
+
+ struct unhandled_event *ev = xmalloc (sizeof *ev);
+ ev->next = unhandled_events;
+ ev->type = type;
+ memcpy (&ev->buffer, buf, 200);
+
+ unhandled_events = ev;
+ break;
+ }
+ case MENU_BAR_HELP_EVENT:
+ {
+ struct haiku_menu_bar_help_event *b = buf;
+
+ if (!popup_activated_p)
+ continue;
+
+ struct frame *f = haiku_window_to_frame (b->window);
+ if (!f || !FRAME_EXTERNAL_MENU_BAR (f) ||
+ !FRAME_OUTPUT_DATA (f)->menu_bar_open_p)
+ continue;
+
+ run_menu_bar_help_event (f, b->mb_idx);
+
+ break;
+ }
+ case ZOOM_EVENT:
+ {
+ struct haiku_zoom_event *b = buf;
+
+ struct frame *f = haiku_window_to_frame (b->window);
+
+ if (!f)
+ continue;
+
+ FRAME_OUTPUT_DATA (f)->pending_zoom_height = b->height;
+ FRAME_OUTPUT_DATA (f)->pending_zoom_width = b->width;
+ FRAME_OUTPUT_DATA (f)->pending_zoom_x = b->x;
+ FRAME_OUTPUT_DATA (f)->pending_zoom_y = b->y;
+
+ FRAME_OUTPUT_DATA (f)->zoomed_p = 1;
+ haiku_make_fullscreen_consistent (f);
+ break;
+ }
+ case REFS_EVENT:
+ {
+ struct haiku_refs_event *b = buf;
+ struct frame *f = haiku_window_to_frame (b->window);
+
+ if (!f)
+ continue;
+
+ inev.kind = DRAG_N_DROP_EVENT;
+ inev.arg = build_string_from_utf8 (b->ref);
+
+ XSETINT (inev.x, b->x);
+ XSETINT (inev.y, b->y);
+ XSETFRAME (inev.frame_or_window, f);
+
+ /* There should be no problem with calling free here.
+ free on Haiku is thread-safe. */
+ free (b->ref);
+ break;
+ }
+ case APP_QUIT_REQUESTED_EVENT:
+ case KEY_UP:
+ default:
+ break;
+ }
+
+ haiku_read_size (&b_size);
+
+ if (inev.kind != NO_EVENT)
+ {
+ if (inev.kind != HELP_EVENT)
+ inev.timestamp = (button_or_motion_p
+ ? x_display_list->last_mouse_movement_time
+ : time (NULL));
+ kbd_buffer_store_event_hold (&inev, hold_quit);
+ ++message_count;
+ }
+
+ if (inev2.kind != NO_EVENT)
+ {
+ if (inev2.kind != HELP_EVENT)
+ inev2.timestamp = (button_or_motion_p
+ ? x_display_list->last_mouse_movement_time
+ : time (NULL));
+ kbd_buffer_store_event_hold (&inev2, hold_quit);
+ ++message_count;
+ }
+ }
+
+ for (struct unhandled_event *ev = unhandled_events; ev;)
+ {
+ haiku_write_without_signal (ev->type, &ev->buffer);
+ struct unhandled_event *old = ev;
+ ev = old->next;
+ xfree (old);
+ }
+
+ if (need_flush)
+ flush_dirty_back_buffers ();
+
+ unblock_input ();
+ return message_count;
+}
+
+static void
+haiku_frame_rehighlight (struct frame *frame)
+{
+ haiku_rehighlight ();
+}
+
+static void
+haiku_delete_window (struct frame *f)
+{
+ check_window_system (f);
+ haiku_free_frame_resources (f);
+}
+
+static void
+haiku_free_pixmap (struct frame *f, Emacs_Pixmap pixmap)
+{
+ BBitmap_free (pixmap);
+}
+
+static void
+haiku_beep (struct frame *f)
+{
+ if (visible_bell)
+ {
+ void *view = FRAME_HAIKU_VIEW (f);
+ if (view)
+ {
+ block_input ();
+ BView_draw_lock (view);
+ if (!EmacsView_double_buffered_p (view))
+ {
+ BView_SetHighColorForVisibleBell (view, FRAME_FOREGROUND_PIXEL (f));
+ BView_FillRectangleForVisibleBell (view, 0, 0, FRAME_PIXEL_WIDTH (f),
+ FRAME_PIXEL_HEIGHT (f));
+ SET_FRAME_GARBAGED (f);
+ expose_frame (f, 0, 0, 0, 0);
+ }
+ else
+ {
+ EmacsView_do_visible_bell (view, FRAME_FOREGROUND_PIXEL (f));
+ haiku_flip_buffers (f);
+ }
+ BView_draw_unlock (view);
+ unblock_input ();
+ }
+ }
+ else
+ haiku_ring_bell ();
+}
+
+static void
+haiku_toggle_invisible_pointer (struct frame *f, bool invisible_p)
+{
+ void *view = FRAME_HAIKU_VIEW (f);
+
+ if (view)
+ {
+ block_input ();
+ BView_set_view_cursor (view, invisible_p ?
+ FRAME_OUTPUT_DATA (f)->no_cursor :
+ FRAME_OUTPUT_DATA (f)->current_cursor);
+ f->pointer_invisible = invisible_p;
+ unblock_input ();
+ }
+}
+
+static void
+haiku_fullscreen (struct frame *f)
+{
+ if (f->want_fullscreen == FULLSCREEN_MAXIMIZED)
+ {
+ EmacsWindow_make_fullscreen (FRAME_HAIKU_WINDOW (f), 0);
+ BWindow_zoom (FRAME_HAIKU_WINDOW (f));
+ }
+ else if (f->want_fullscreen == FULLSCREEN_BOTH)
+ EmacsWindow_make_fullscreen (FRAME_HAIKU_WINDOW (f), 1);
+ else if (f->want_fullscreen == FULLSCREEN_NONE)
+ {
+ EmacsWindow_make_fullscreen (FRAME_HAIKU_WINDOW (f), 0);
+ EmacsWindow_unzoom (FRAME_HAIKU_WINDOW (f));
+ }
+
+ f->want_fullscreen = FULLSCREEN_NONE;
+
+ haiku_update_size_hints (f);
+}
+
+static struct terminal *
+haiku_create_terminal (struct haiku_display_info *dpyinfo)
+{
+ struct terminal *terminal;
+
+ terminal = create_terminal (output_haiku, &haiku_redisplay_interface);
+
+ terminal->display_info.haiku = dpyinfo;
+ dpyinfo->terminal = terminal;
+ terminal->kboard = allocate_kboard (Qhaiku);
+
+ terminal->iconify_frame_hook = haiku_iconify_frame;
+ terminal->focus_frame_hook = haiku_focus_frame;
+ terminal->ring_bell_hook = haiku_beep;
+ terminal->popup_dialog_hook = haiku_popup_dialog;
+ terminal->frame_visible_invisible_hook = haiku_set_frame_visible_invisible;
+ terminal->set_frame_offset_hook = haiku_set_offset;
+ terminal->delete_terminal_hook = haiku_delete_terminal;
+ terminal->get_string_resource_hook = get_string_resource;
+ terminal->set_new_font_hook = haiku_new_font;
+ terminal->defined_color_hook = haiku_defined_color;
+ terminal->set_window_size_hook = haiku_set_window_size;
+ terminal->read_socket_hook = haiku_read_socket;
+ terminal->implicit_set_name_hook = haiku_implicitly_set_name;
+ terminal->mouse_position_hook = haiku_mouse_position;
+ terminal->delete_frame_hook = haiku_delete_window;
+ terminal->frame_up_to_date_hook = haiku_frame_up_to_date;
+ terminal->buffer_flipping_unblocked_hook = haiku_buffer_flipping_unblocked_hook;
+ terminal->clear_frame_hook = haiku_clear_frame;
+ terminal->change_tab_bar_height_hook = haiku_change_tab_bar_height;
+ terminal->change_tool_bar_height_hook = haiku_change_tool_bar_height;
+ terminal->set_vertical_scroll_bar_hook = haiku_set_vertical_scroll_bar;
+ terminal->set_horizontal_scroll_bar_hook = haiku_set_horizontal_scroll_bar;
+ terminal->set_scroll_bar_default_height_hook = haiku_set_scroll_bar_default_height;
+ terminal->set_scroll_bar_default_width_hook = haiku_set_scroll_bar_default_width;
+ terminal->judge_scroll_bars_hook = haiku_judge_scroll_bars;
+ terminal->condemn_scroll_bars_hook = haiku_condemn_scroll_bars;
+ terminal->redeem_scroll_bar_hook = haiku_redeem_scroll_bar;
+ terminal->update_begin_hook = haiku_update_begin;
+ terminal->update_end_hook = haiku_update_end;
+ terminal->frame_rehighlight_hook = haiku_frame_rehighlight;
+ terminal->query_frame_background_color = haiku_query_frame_background_color;
+ terminal->free_pixmap = haiku_free_pixmap;
+ terminal->frame_raise_lower_hook = haiku_frame_raise_lower;
+ terminal->menu_show_hook = haiku_menu_show;
+ terminal->toggle_invisible_pointer_hook = haiku_toggle_invisible_pointer;
+ terminal->fullscreen_hook = haiku_fullscreen;
+
+ return terminal;
+}
+
+struct haiku_display_info *
+haiku_term_init (void)
+{
+ struct haiku_display_info *dpyinfo;
+ struct terminal *terminal;
+
+ Lisp_Object color_file, color_map;
+
+ block_input ();
+ Fset_input_interrupt_mode (Qnil);
+
+ baud_rate = 19200;
+
+ dpyinfo = xzalloc (sizeof *dpyinfo);
+
+ haiku_io_init ();
+
+ if (port_application_to_emacs < B_OK)
+ emacs_abort ();
+
+ color_file = Fexpand_file_name (build_string ("rgb.txt"),
+ Fsymbol_value (intern ("data-directory")));
+
+ color_map = Fx_load_color_file (color_file);
+ if (NILP (color_map))
+ fatal ("Could not read %s.\n", SDATA (color_file));
+
+ dpyinfo->color_map = color_map;
+
+ dpyinfo->display = BApplication_setup ();
+
+ BScreen_res (&dpyinfo->resx, &dpyinfo->resy);
+
+ dpyinfo->next = x_display_list;
+ dpyinfo->n_planes = be_get_display_planes ();
+ x_display_list = dpyinfo;
+
+ terminal = haiku_create_terminal (dpyinfo);
+ if (current_kboard == initial_kboard)
+ current_kboard = terminal->kboard;
+
+ terminal->kboard->reference_count++;
+ /* Never delete haiku displays -- there can only ever be one,
+ anyhow. */
+ terminal->reference_count++;
+ terminal->name = xstrdup ("be");
+
+ dpyinfo->name_list_element = Fcons (build_string ("be"), Qnil);
+ dpyinfo->smallest_font_height = 1;
+ dpyinfo->smallest_char_width = 1;
+
+ gui_init_fringe (terminal->rif);
+ unblock_input ();
+
+ return dpyinfo;
+}
+
+void
+put_xrm_resource (Lisp_Object name, Lisp_Object val)
+{
+ eassert (STRINGP (name));
+ eassert (STRINGP (val) || NILP (val));
+
+ Lisp_Object lval = assoc_no_quit (name, rdb);
+ if (!NILP (lval))
+ Fsetcdr (lval, val);
+ else
+ rdb = Fcons (Fcons (name, val), rdb);
+}
+
+void
+haiku_clear_under_internal_border (struct frame *f)
+{
+ if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
+ {
+ int border = FRAME_INTERNAL_BORDER_WIDTH (f);
+ int width = FRAME_PIXEL_WIDTH (f);
+ int height = FRAME_PIXEL_HEIGHT (f);
+ int margin = FRAME_TOP_MARGIN_HEIGHT (f);
+ int face_id =
+ (FRAME_PARENT_FRAME (f)
+ ? (!NILP (Vface_remapping_alist)
+ ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
+ : CHILD_FRAME_BORDER_FACE_ID)
+ : (!NILP (Vface_remapping_alist)
+ ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
+ : INTERNAL_BORDER_FACE_ID));
+ struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
+ void *view = FRAME_HAIKU_VIEW (f);
+ block_input ();
+ BView_draw_lock (view);
+ BView_StartClip (view);
+ BView_ClipToRect (view, 0, 0, FRAME_PIXEL_WIDTH (f),
+ FRAME_PIXEL_HEIGHT (f));
+
+ if (face)
+ BView_SetHighColor (view, face->background);
+ else
+ BView_SetHighColor (view, FRAME_BACKGROUND_PIXEL (f));
+
+ BView_FillRectangle (view, 0, margin, width, border);
+ BView_FillRectangle (view, 0, 0, border, height);
+ BView_FillRectangle (view, 0, margin, width, border);
+ BView_FillRectangle (view, width - border, 0, border, height);
+ BView_FillRectangle (view, 0, height - border, width, border);
+ BView_EndClip (view);
+ BView_draw_unlock (view);
+ unblock_input ();
+ }
+}
+
+void
+mark_haiku_display (void)
+{
+ if (x_display_list)
+ mark_object (x_display_list->color_map);
+}
+
+void
+haiku_scroll_bar_remove (struct scroll_bar *bar)
+{
+ block_input ();
+ void *view = FRAME_HAIKU_VIEW (WINDOW_XFRAME (XWINDOW (bar->window)));
+ BView_forget_scroll_bar (view, bar->left, bar->top, bar->width, bar->height);
+ BScrollBar_delete (bar->scroll_bar);
+ expose_frame (WINDOW_XFRAME (XWINDOW (bar->window)),
+ bar->left, bar->top, bar->width, bar->height);
+
+ if (bar->horizontal)
+ wset_horizontal_scroll_bar (XWINDOW (bar->window), Qnil);
+ else
+ wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
+
+ unblock_input ();
+};
+
+void
+haiku_set_offset (struct frame *frame, int x, int y,
+ int change_gravity)
+{
+ if (change_gravity > 0)
+ {
+ frame->top_pos = y;
+ frame->left_pos = x;
+ frame->size_hint_flags &= ~ (XNegative | YNegative);
+ if (x < 0)
+ frame->size_hint_flags |= XNegative;
+ if (y < 0)
+ frame->size_hint_flags |= YNegative;
+ frame->win_gravity = NorthWestGravity;
+ }
+
+ haiku_update_size_hints (frame);
+
+ block_input ();
+ if (change_gravity)
+ BWindow_set_offset (FRAME_HAIKU_WINDOW (frame), x, y);
+ unblock_input ();
+}
+
+#ifdef USE_BE_CAIRO
+cairo_t *
+haiku_begin_cr_clip (struct frame *f, struct glyph_string *s)
+{
+ cairo_surface_t *surface = FRAME_CR_SURFACE (f);
+ if (!surface)
+ return NULL;
+
+ cairo_t *context = cairo_create (surface);
+ return context;
+}
+
+void
+haiku_end_cr_clip (cairo_t *cr)
+{
+ cairo_destroy (cr);
+}
+#endif
+
+void
+syms_of_haikuterm (void)
+{
+ DEFVAR_BOOL ("haiku-initialized", haiku_initialized,
+ doc: /* Non-nil if the Haiku terminal backend has been initialized. */);
+
+ DEFVAR_BOOL ("x-use-underline-position-properties",
+ x_use_underline_position_properties,
+ doc: /* SKIP: real doc in xterm.c. */);
+ x_use_underline_position_properties = 1;
+
+ DEFVAR_BOOL ("x-underline-at-descent-line",
+ x_underline_at_descent_line,
+ doc: /* SKIP: real doc in xterm.c. */);
+ x_underline_at_descent_line = 0;
+
+ DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars,
+ doc: /* SKIP: real doc in xterm.c. */);
+ Vx_toolkit_scroll_bars = Qt;
+
+ DEFVAR_BOOL ("haiku-debug-on-fatal-error", haiku_debug_on_fatal_error,
+ doc: /* If non-nil, Emacs will launch the system debugger upon a fatal error. */);
+ haiku_debug_on_fatal_error = 1;
+
+ DEFSYM (Qshift, "shift");
+ DEFSYM (Qcontrol, "control");
+ DEFSYM (Qoption, "option");
+ DEFSYM (Qcommand, "command");
+
+ 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
+`option', or nil, in which case it is treated as `command'.
+
+Setting it to any other value is equivalent to `command'. */);
+ Vhaiku_meta_keysym = Qnil;
+
+ DEFVAR_LISP ("haiku-control-keysym", Vhaiku_control_keysym,
+ doc: /* Which key Emacs uses as the control modifier.
+This is either one of the symbols `shift', `control', `command', and
+`option', or nil, in which case it is treated as `control'.
+
+Setting it to any other value is equivalent to `control'. */);
+ Vhaiku_control_keysym = Qnil;
+
+ DEFVAR_LISP ("haiku-super-keysym", Vhaiku_super_keysym,
+ doc: /* Which key Emacs uses as the super modifier.
+This is either one of the symbols `shift', `control', `command', and
+`option', or nil, in which case it is treated as `option'.
+
+Setting it to any other value is equivalent to `option'. */);
+ Vhaiku_super_keysym = Qnil;
+
+ DEFVAR_LISP ("haiku-shift-keysym", Vhaiku_shift_keysym,
+ doc: /* Which key Emacs uses as the shift modifier.
+This is either one of the symbols `shift', `control', `command', and
+`option', or nil, in which case it is treated as `shift'.
+
+Setting it to any other value is equivalent to `shift'. */);
+ Vhaiku_shift_keysym = Qnil;
+
+
+ DEFSYM (Qx_use_underline_position_properties,
+ "x-use-underline-position-properties");
+
+ DEFSYM (Qx_underline_at_descent_line, "x-underline-at-descent-line");
+
+ rdb = Qnil;
+ staticpro (&rdb);
+
+ Fprovide (Qhaiku, Qnil);
+#ifdef USE_BE_CAIRO
+ Fprovide (intern_c_string ("cairo"), Qnil);
+#endif
+}
diff --git a/src/haikuterm.h b/src/haikuterm.h
new file mode 100644
index 00000000000..7ed7485ef53
--- /dev/null
+++ b/src/haikuterm.h
@@ -0,0 +1,296 @@
+/* Haiku window system support
+ Copyright (C) 2021 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/>. */
+
+#ifndef _HAIKU_TERM_H_
+#define _HAIKU_TERM_H_
+
+#include <pthread.h>
+
+#ifdef USE_BE_CAIRO
+#include <cairo.h>
+#endif
+
+#include "haikugui.h"
+#include "frame.h"
+#include "character.h"
+#include "dispextern.h"
+#include "font.h"
+#include "systime.h"
+
+#define C_FRAME struct frame *
+#define C_FONT struct font *
+#define C_TERMINAL struct terminal *
+
+#define HAVE_CHAR_CACHE_MAX 65535
+
+extern int popup_activated_p;
+
+extern void be_app_quit (void);
+
+struct haikufont_info
+{
+ struct font font;
+ haiku be_font;
+ struct font_metrics **metrics;
+ short metrics_nrows;
+
+ unsigned short **glyphs;
+};
+
+struct haiku_bitmap_record
+{
+ haiku img;
+ char *file;
+ int refcount;
+ int height, width, depth;
+};
+
+struct haiku_display_info
+{
+ /* Chain of all haiku_display_info structures. */
+ struct haiku_display_info *next;
+ C_TERMINAL terminal;
+
+ Lisp_Object name_list_element;
+ Lisp_Object color_map;
+
+ int n_fonts;
+
+ int smallest_char_width;
+ int smallest_font_height;
+
+ struct frame *focused_frame;
+ struct frame *focus_event_frame;
+ struct frame *last_mouse_glyph_frame;
+
+ struct haiku_bitmap_record *bitmaps;
+ ptrdiff_t bitmaps_size;
+ ptrdiff_t bitmaps_last;
+
+ int grabbed;
+ int n_planes;
+ int color_p;
+
+ Window root_window;
+ Lisp_Object rdb;
+
+ Emacs_Cursor vertical_scroll_bar_cursor;
+ Emacs_Cursor horizontal_scroll_bar_cursor;
+
+ Mouse_HLInfo mouse_highlight;
+
+ C_FRAME highlight_frame;
+ C_FRAME last_mouse_frame;
+ C_FRAME last_mouse_motion_frame;
+
+ int last_mouse_motion_x;
+ int last_mouse_motion_y;
+
+ struct haiku_rect last_mouse_glyph;
+
+ void *last_mouse_scroll_bar;
+
+ haiku display;
+
+ double resx, resy;
+
+ Time last_mouse_movement_time;
+};
+
+struct haiku_output
+{
+ Emacs_Cursor text_cursor;
+ Emacs_Cursor nontext_cursor;
+ Emacs_Cursor modeline_cursor;
+ Emacs_Cursor hand_cursor;
+ Emacs_Cursor hourglass_cursor;
+ Emacs_Cursor horizontal_drag_cursor;
+ Emacs_Cursor vertical_drag_cursor;
+ Emacs_Cursor left_edge_cursor;
+ Emacs_Cursor top_left_corner_cursor;
+ Emacs_Cursor top_edge_cursor;
+ Emacs_Cursor top_right_corner_cursor;
+ Emacs_Cursor right_edge_cursor;
+ Emacs_Cursor bottom_right_corner_cursor;
+ Emacs_Cursor bottom_edge_cursor;
+ Emacs_Cursor bottom_left_corner_cursor;
+ Emacs_Cursor no_cursor;
+
+ Emacs_Cursor current_cursor;
+
+ struct haiku_display_info *display_info;
+
+ int baseline_offset;
+ int fontset;
+
+ Emacs_Color cursor_color;
+
+ Window window_desc, parent_desc;
+ char explicit_parent;
+
+ int titlebar_height;
+ int toolbar_height;
+
+ haiku window;
+ haiku view;
+ haiku menubar;
+
+ int menu_up_to_date_p;
+ int zoomed_p;
+
+ int pending_zoom_x;
+ int pending_zoom_y;
+ int pending_zoom_width;
+ int pending_zoom_height;
+
+ int menu_bar_open_p;
+
+ C_FONT font;
+
+ int hourglass_p;
+ uint32_t cursor_fg;
+ bool dirty_p;
+
+ /* The pending position we're waiting for. */
+ int pending_top, pending_left;
+};
+
+struct x_output
+{
+ /* Unused, makes term.c happy. */
+};
+
+extern struct haiku_display_info *x_display_list;
+extern struct font_driver const haikufont_driver;
+
+struct scroll_bar
+{
+ /* These fields are shared by all vectors. */
+ union vectorlike_header header;
+
+ /* The window we're a scroll bar for. */
+ Lisp_Object window;
+
+ /* The next and previous in the chain of scroll bars in this frame. */
+ Lisp_Object next, prev;
+
+ /* Fields after 'prev' are not traced by the GC. */
+
+ /* The position and size of the scroll bar in pixels, relative to the
+ frame. */
+ int top, left, width, height;
+
+ /* The actual scrollbar. */
+ void *scroll_bar;
+
+ /* Non-nil if the scroll bar handle is currently being dragged by
+ the user. */
+ int dragging;
+
+ /* The update position if we are waiting for a scrollbar update, or
+ -1. */
+ int update;
+
+ /* The last known position of this scrollbar. */
+ int position;
+
+ /* The total number of units inside this scrollbar. */
+ int total;
+
+ /* True if the scroll bar is horizontal. */
+ bool horizontal;
+};
+
+#define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec))
+
+#define FRAME_DIRTY_P(f) (FRAME_OUTPUT_DATA (f)->dirty_p)
+#define MAKE_FRAME_DIRTY(f) (FRAME_DIRTY_P (f) = 1)
+#define FRAME_OUTPUT_DATA(f) ((f)->output_data.haiku)
+#define FRAME_HAIKU_WINDOW(f) (FRAME_OUTPUT_DATA (f)->window)
+#define FRAME_HAIKU_VIEW(f) ((MAKE_FRAME_DIRTY (f)), FRAME_OUTPUT_DATA (f)->view)
+#define FRAME_HAIKU_MENU_BAR(f) (FRAME_OUTPUT_DATA (f)->menubar)
+#define FRAME_DISPLAY_INFO(f) (FRAME_OUTPUT_DATA (f)->display_info)
+#define FRAME_FONT(f) (FRAME_OUTPUT_DATA (f)->font)
+#define FRAME_FONTSET(f) (FRAME_OUTPUT_DATA (f)->fontset)
+#define FRAME_NATIVE_WINDOW(f) (FRAME_OUTPUT_DATA (f)->window)
+#define FRAME_BASELINE_OFFSET(f) (FRAME_OUTPUT_DATA (f)->baseline_offset)
+#define FRAME_CURSOR_COLOR(f) (FRAME_OUTPUT_DATA (f)->cursor_color)
+
+#ifdef USE_BE_CAIRO
+#define FRAME_CR_SURFACE(f) \
+ (FRAME_HAIKU_VIEW (f) ? EmacsView_cairo_surface (FRAME_HAIKU_VIEW (f)) : 0);
+#endif
+
+extern void syms_of_haikuterm (void);
+extern void syms_of_haikufns (void);
+extern void syms_of_haikumenu (void);
+extern void syms_of_haikufont (void);
+extern void syms_of_haikuselect (void);
+extern void init_haiku_select (void);
+
+extern void haiku_iconify_frame (struct frame *);
+extern void haiku_visualize_frame (struct frame *);
+extern void haiku_unvisualize_frame (struct frame *);
+extern void haiku_set_offset (struct frame *, int, int, int);
+extern void haiku_set_frame_visible_invisible (struct frame *, bool);
+extern void haiku_free_frame_resources (struct frame *f);
+extern void haiku_scroll_bar_remove (struct scroll_bar *bar);
+extern void haiku_clear_under_internal_border (struct frame *f);
+extern void haiku_set_name (struct frame *f, Lisp_Object name, bool explicit_p);
+
+extern struct haiku_display_info *haiku_term_init (void);
+
+extern void mark_haiku_display (void);
+
+extern int haiku_get_color (const char *name, Emacs_Color *color);
+extern void haiku_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval);
+extern void haiku_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval);
+extern void haiku_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval);
+extern void haiku_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval);
+extern void haiku_change_tab_bar_height (struct frame *f, int height);
+extern void haiku_change_tool_bar_height (struct frame *f, int height);
+
+extern void haiku_query_color (uint32_t col, Emacs_Color *color);
+
+extern unsigned long haiku_get_pixel (haiku bitmap, int x, int y);
+extern void haiku_put_pixel (haiku bitmap, int x, int y, unsigned long pixel);
+
+extern Lisp_Object haiku_menu_show (struct frame *f, int x, int y, int menu_flags,
+ Lisp_Object title, const char **error_name);
+extern Lisp_Object haiku_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents);
+
+extern void initialize_frame_menubar (struct frame *f);
+
+extern void run_menu_bar_help_event (struct frame *f, int mb_idx);
+extern void put_xrm_resource (Lisp_Object name, Lisp_Object val);
+
+#ifdef HAVE_NATIVE_IMAGE_API
+extern bool haiku_can_use_native_image_api (Lisp_Object type);
+extern int haiku_load_image (struct frame *f, struct image *img,
+ Lisp_Object spec_file, Lisp_Object spec_data);
+extern void syms_of_haikuimage (void);
+#endif
+
+#ifdef USE_BE_CAIRO
+extern cairo_t *
+haiku_begin_cr_clip (struct frame *f, struct glyph_string *s);
+
+extern void
+haiku_end_cr_clip (cairo_t *cr);
+#endif
+#endif /* _HAIKU_TERM_H_ */
diff --git a/src/image.c b/src/image.c
index bcd45eb4514..dd5ea19fc15 100644
--- a/src/image.c
+++ b/src/image.c
@@ -20,6 +20,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <config.h>
#include <fcntl.h>
+#include <math.h>
#include <unistd.h>
/* Include this before including <setjmp.h> to work around bugs with
@@ -30,6 +31,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <setjmp.h>
+#include <math.h>
#include <stdint.h>
#include <c-ctype.h>
#include <flexmember.h>
@@ -99,6 +101,15 @@ static unsigned long image_alloc_image_color (struct frame *, struct image *,
Lisp_Object, unsigned long);
#endif /* USE_CAIRO */
+#if defined HAVE_PGTK && defined HAVE_IMAGEMAGICK
+/* In pgtk, we don't want to create scaled image. If we create scaled
+ * image on scale=2.0 environment, the created image is half size and
+ * Gdk scales it back, and the result is blurry. To avoid this, we
+ * hold original size image as far as we can, and let Gdk to scale it
+ * when it is shown. */
+# define DONT_CREATE_TRANSFORMED_IMAGEMAGICK_IMAGE
+#endif
+
#ifdef HAVE_NTGUI
/* We need (or want) w32.h only when we're _not_ compiling for Cygwin. */
@@ -129,12 +140,37 @@ typedef struct ns_bitmap_record Bitmap_Record;
#endif /* HAVE_NS */
+#ifdef HAVE_PGTK
+typedef struct pgtk_bitmap_record Bitmap_Record;
+#endif /* HAVE_PGTK */
+
#if (defined HAVE_X_WINDOWS \
&& ! (defined HAVE_NTGUI || defined USE_CAIRO || defined HAVE_NS))
/* W32_TODO : Color tables on W32. */
# define COLOR_TABLE_SUPPORT 1
#endif
+#ifdef HAVE_HAIKU
+#include "haiku_support.h"
+typedef struct haiku_bitmap_record Bitmap_Record;
+
+#define GET_PIXEL(ximg, x, y) haiku_get_pixel (ximg, x, y)
+#define PUT_PIXEL haiku_put_pixel
+#define NO_PIXMAP 0
+
+#define PIX_MASK_RETAIN 0
+#define PIX_MASK_DRAW 1
+
+#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))
+#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
+#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
+#define BLUE_FROM_ULONG(color) ((color) & 0xff)
+#define RED16_FROM_ULONG(color) (RED_FROM_ULONG (color) * 0x101)
+#define GREEN16_FROM_ULONG(color) (GREEN_FROM_ULONG (color) * 0x101)
+#define BLUE16_FROM_ULONG(color) (BLUE_FROM_ULONG (color) * 0x101)
+
+#endif
+
static void image_disable_image (struct frame *, struct image *);
static void image_edge_detection (struct frame *, struct image *, Lisp_Object,
Lisp_Object);
@@ -396,6 +432,34 @@ image_reference_bitmap (struct frame *f, ptrdiff_t id)
++FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
}
+#ifdef HAVE_PGTK
+static cairo_pattern_t *
+image_create_pattern_from_pixbuf (struct frame *f, GdkPixbuf * pixbuf)
+{
+ GdkPixbuf *pb = gdk_pixbuf_add_alpha (pixbuf, TRUE, 255, 255, 255);
+ cairo_surface_t *surface =
+ cairo_surface_create_similar_image (cairo_get_target
+ (f->output_data.pgtk->cr_context),
+ CAIRO_FORMAT_A1,
+ gdk_pixbuf_get_width (pb),
+ gdk_pixbuf_get_height (pb));
+
+ cairo_t *cr = cairo_create (surface);
+ gdk_cairo_set_source_pixbuf (cr, pb, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cairo_pattern_t *pat = cairo_pattern_create_for_surface (surface);
+ cairo_pattern_set_extend (pat, CAIRO_EXTEND_REPEAT);
+
+ cairo_surface_destroy (surface);
+ g_object_unref (pb);
+
+ return pat;
+}
+#endif
+
/* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
ptrdiff_t
@@ -430,6 +494,54 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
return -1;
#endif
+#ifdef HAVE_PGTK
+ GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ FALSE,
+ 8,
+ width,
+ height);
+ {
+ char *sp = bits;
+ int mask = 0x01;
+ unsigned char *buf = gdk_pixbuf_get_pixels (pixbuf);
+ int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+ for (int y = 0; y < height; y++)
+ {
+ unsigned char *dp = buf + rowstride * y;
+ for (int x = 0; x < width; x++)
+ {
+ if (*sp & mask)
+ {
+ *dp++ = 0xff;
+ *dp++ = 0xff;
+ *dp++ = 0xff;
+ }
+ else
+ {
+ *dp++ = 0x00;
+ *dp++ = 0x00;
+ *dp++ = 0x00;
+ }
+ if ((mask <<= 1) >= 0x100)
+ {
+ mask = 0x01;
+ sp++;
+ }
+ }
+ if (mask != 0x01)
+ {
+ mask = 0x01;
+ sp++;
+ }
+ }
+ }
+#endif /* HAVE_PGTK */
+
+#ifdef HAVE_HAIKU
+ void *bitmap = BBitmap_new (width, height, 1);
+ BBitmap_import_mono_bits (bitmap, bits, width, height);
+#endif
+
id = image_allocate_bitmap_record (f);
#ifdef HAVE_NS
@@ -437,6 +549,18 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
dpyinfo->bitmaps[id - 1].depth = 1;
#endif
+#ifdef HAVE_PGTK
+ dpyinfo->bitmaps[id - 1].img = pixbuf;
+ dpyinfo->bitmaps[id - 1].depth = 1;
+ dpyinfo->bitmaps[id - 1].pattern =
+ image_create_pattern_from_pixbuf (f, pixbuf);
+#endif
+
+#ifdef HAVE_HAIKU
+ dpyinfo->bitmaps[id - 1].img = bitmap;
+ dpyinfo->bitmaps[id - 1].depth = 1;
+#endif
+
dpyinfo->bitmaps[id - 1].file = NULL;
dpyinfo->bitmaps[id - 1].height = height;
dpyinfo->bitmaps[id - 1].width = width;
@@ -465,7 +589,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
ptrdiff_t
image_create_bitmap_from_file (struct frame *f, Lisp_Object file)
{
-#ifdef HAVE_NTGUI
+#if defined (HAVE_NTGUI) || defined (HAVE_HAIKU)
return -1; /* W32_TODO : bitmap support */
#else
Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
@@ -489,6 +613,30 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file)
return id;
#endif
+#ifdef HAVE_PGTK
+ GError *err = NULL;
+ ptrdiff_t id;
+ void * bitmap = gdk_pixbuf_new_from_file (SSDATA (file), &err);
+
+ if (!bitmap)
+ {
+ g_error_free (err);
+ return -1;
+ }
+
+ id = image_allocate_bitmap_record (f);
+
+ dpyinfo->bitmaps[id - 1].img = bitmap;
+ dpyinfo->bitmaps[id - 1].refcount = 1;
+ dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
+ //dpyinfo->bitmaps[id - 1].depth = 1;
+ dpyinfo->bitmaps[id - 1].height = gdk_pixbuf_get_width (bitmap);
+ dpyinfo->bitmaps[id - 1].width = gdk_pixbuf_get_height (bitmap);
+ dpyinfo->bitmaps[id - 1].pattern
+ = image_create_pattern_from_pixbuf (f, bitmap);
+ return id;
+#endif
+
#ifdef HAVE_X_WINDOWS
unsigned int width, height;
Pixmap bitmap;
@@ -561,6 +709,15 @@ free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm)
ns_release_object (bm->img);
#endif
+#ifdef HAVE_PGTK
+ if (bm->pattern != NULL)
+ cairo_pattern_destroy (bm->pattern);
+#endif
+
+#ifdef HAVE_HAIKU
+ BBitmap_free (bm->img);
+#endif
+
if (bm->file)
{
xfree (bm->file);
@@ -1321,7 +1478,6 @@ image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
return ascent;
}
-
/* Image background colors. */
@@ -1345,6 +1501,7 @@ four_corners_best (Emacs_Pix_Context pimg, int *corners,
corner_pixels[3] = GET_PIXEL (pimg, corners[LEFT_CORNER], corners[BOT_CORNER] - 1);
}
else
+
{
/* Get the colors at the corner_pixels of pimg. */
corner_pixels[0] = GET_PIXEL (pimg, 0, 0);
@@ -1834,6 +1991,11 @@ image_size_in_bytes (struct image *img)
if (img->mask)
size += w32_image_size (img->mask);
+#elif defined HAVE_HAIKU
+ if (img->pixmap)
+ size += BBitmap_bytes_length (img->pixmap);
+ if (img->mask)
+ size += BBitmap_bytes_length (img->mask);
#endif
return size;
@@ -1975,14 +2137,16 @@ postprocess_image (struct frame *f, struct image *img)
safely rounded and clipped to int range. */
static int
-scale_image_size (int size, size_t divisor, size_t multiplier)
+scale_image_size (int size, double divisor, double multiplier)
{
if (divisor != 0)
{
- double s = size;
- double scaled = s * multiplier / divisor + 0.5;
+ double scaled = size * multiplier / divisor;
if (scaled < INT_MAX)
- return scaled;
+ {
+ /* Use ceil, as rounding can discard fractional SVG pixels. */
+ return ceil (scaled);
+ }
}
return INT_MAX;
}
@@ -2003,84 +2167,77 @@ image_get_dimension (struct image *img, Lisp_Object symbol)
if (FIXNATP (value))
return min (XFIXNAT (value), INT_MAX);
if (CONSP (value) && NUMBERP (CAR (value)) && EQ (Qem, CDR (value)))
- return min (img->face_font_size * XFLOATINT (CAR (value)), INT_MAX);
+ return scale_image_size (img->face_font_size, 1, XFLOATINT (CAR (value)));
return -1;
}
/* Compute the desired size of an image with native size WIDTH x HEIGHT.
- Use SPEC to deduce the size. Store the desired size into
+ Use IMG to deduce the size. Store the desired size into
*D_WIDTH x *D_HEIGHT. Store -1 x -1 if the native size is OK. */
static void
-compute_image_size (size_t width, size_t height,
+compute_image_size (double width, double height,
struct image *img,
int *d_width, int *d_height)
{
- Lisp_Object value;
- int int_value;
- int desired_width = -1, desired_height = -1, max_width = -1, max_height = -1;
double scale = 1;
-
- value = image_spec_value (img->spec, QCscale, NULL);
+ Lisp_Object value = image_spec_value (img->spec, QCscale, NULL);
if (NUMBERP (value))
- scale = XFLOATINT (value);
-
- int_value = image_get_dimension (img, QCmax_width);
- if (int_value >= 0)
- max_width = int_value;
-
- int_value = image_get_dimension (img, QCmax_height);
- if (int_value >= 0)
- max_height = int_value;
+ {
+ double dval = XFLOATINT (value);
+ if (0 <= dval)
+ scale = dval;
+ }
/* If width and/or height is set in the display spec assume we want
to scale to those values. If either h or w is unspecified, the
unspecified should be calculated from the specified to preserve
aspect ratio. */
- int_value = image_get_dimension (img, QCwidth);
- if (int_value >= 0)
+ int desired_width = image_get_dimension (img, QCwidth), max_width;
+ if (desired_width < 0)
+ max_width = image_get_dimension (img, QCmax_width);
+ else
{
- desired_width = int_value * scale;
+ desired_width = scale_image_size (desired_width, 1, scale);
/* :width overrides :max-width. */
max_width = -1;
}
- int_value = image_get_dimension (img, QCheight);
- if (int_value >= 0)
+ int desired_height = image_get_dimension (img, QCheight), max_height;
+ if (desired_height < 0)
+ max_height = image_get_dimension (img, QCmax_height);
+ else
{
- desired_height = int_value * scale;
+ desired_height = scale_image_size (desired_height, 1, scale);
/* :height overrides :max-height. */
max_height = -1;
}
/* If we have both width/height set explicitly, we skip past all the
aspect ratio-preserving computations below. */
- if (desired_width != -1 && desired_height != -1)
+ if (0 <= desired_width && 0 <= desired_height)
goto out;
- width = width * scale;
- height = height * scale;
-
- if (desired_width != -1)
+ if (0 <= desired_width)
/* Width known, calculate height. */
desired_height = scale_image_size (desired_width, width, height);
- else if (desired_height != -1)
+ else if (0 <= desired_height)
/* Height known, calculate width. */
desired_width = scale_image_size (desired_height, height, width);
else
{
- desired_width = width;
- desired_height = height;
+ desired_width = scale_image_size (width, 1, scale);
+ desired_height = scale_image_size (height, 1, scale);
}
- if (max_width != -1 && desired_width > max_width)
+ if (0 <= max_width && max_width < desired_width)
{
/* The image is wider than :max-width. */
desired_width = max_width;
desired_height = scale_image_size (desired_width, width, height);
}
- if (max_height != -1 && desired_height > max_height)
+ if (0 <= max_height && max_height < desired_height)
{
/* The image is higher than :max-height. */
desired_height = max_height;
@@ -2173,6 +2330,7 @@ compute_image_size (size_t width, size_t height,
single step, but the maths for each element is much more complex
and performing the steps separately makes for more readable code. */
+#ifndef HAVE_HAIKU
typedef double matrix3x3[3][3];
static void
@@ -2187,6 +2345,7 @@ matrix3x3_mult (matrix3x3 a, matrix3x3 b, matrix3x3 result)
result[i][j] = sum;
}
}
+#endif /* not HAVE_HAIKU */
static void
compute_image_rotation (struct image *img, double *rotation)
@@ -2211,7 +2370,8 @@ compute_image_rotation (struct image *img, double *rotation)
static void
image_set_transform (struct frame *f, struct image *img)
{
-# ifdef HAVE_IMAGEMAGICK
+# if (defined HAVE_IMAGEMAGICK \
+ && !defined DONT_CREATE_TRANSFORMED_IMAGEMAGICK_IMAGE)
/* ImageMagick images already have the correct transform. */
if (EQ (image_spec_value (img->spec, QCtype, NULL), Qimagemagick))
return;
@@ -2244,6 +2404,7 @@ image_set_transform (struct frame *f, struct image *img)
double rotation = 0.0;
compute_image_rotation (img, &rotation);
+#ifndef HAVE_HAIKU
# if defined USE_CAIRO || defined HAVE_XRENDER || defined HAVE_NS
/* We want scale up operations to use a nearest neighbor filter to
show real pixels instead of munging them, but scale down
@@ -2414,6 +2575,34 @@ image_set_transform (struct frame *f, struct image *img)
img->xform.eDx = matrix[2][0];
img->xform.eDy = matrix[2][1];
# endif
+#else
+ if (rotation != 0 &&
+ rotation != 90 &&
+ rotation != 180 &&
+ rotation != 270 &&
+ rotation != 360)
+ {
+ image_error ("No native support for rotation by %g degrees",
+ make_float (rotation));
+ return;
+ }
+
+ rotation = fmod (rotation, 360.0);
+
+ if (rotation == 90 || rotation == 270)
+ {
+ int w = width;
+ width = height;
+ height = w;
+ }
+
+ img->have_be_transforms_p = rotation != 0 || (img->width != width) || (img->height != height);
+ img->be_rotate = rotation;
+ img->be_scale_x = 1.0 / (img->width / (double) width);
+ img->be_scale_y = 1.0 / (img->height / (double) height);
+ img->width = width;
+ img->height = height;
+#endif /* not HAVE_HAIKU */
}
#endif /* HAVE_IMAGEMAGICK || HAVE_NATIVE_TRANSFORMS */
@@ -2820,6 +3009,30 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d
return 1;
#endif /* HAVE_X_WINDOWS */
+#ifdef HAVE_HAIKU
+ if (depth == 0)
+ depth = 24;
+
+ if (depth != 24 && depth != 1)
+ {
+ *pimg = NULL;
+ image_error ("Invalid image bit depth specified");
+ return 0;
+ }
+
+ *pixmap = BBitmap_new (width, height, depth == 1);
+
+ if (*pixmap == NO_PIXMAP)
+ {
+ *pimg = NULL;
+ image_error ("Unable to create pixmap", Qnil, Qnil);
+ return 0;
+ }
+
+ *pimg = *pixmap;
+ return 1;
+#endif
+
#ifdef HAVE_NTGUI
BITMAPINFOHEADER *header;
@@ -2960,7 +3173,7 @@ static void
gui_put_x_image (struct frame *f, Emacs_Pix_Container pimg,
Emacs_Pixmap pixmap, int width, int height)
{
-#ifdef USE_CAIRO
+#if defined USE_CAIRO || defined HAVE_HAIKU
eassert (pimg == pixmap);
#elif defined HAVE_X_WINDOWS
GC gc;
@@ -2972,14 +3185,6 @@ gui_put_x_image (struct frame *f, Emacs_Pix_Container pimg,
XFreeGC (FRAME_X_DISPLAY (f), gc);
#endif /* HAVE_X_WINDOWS */
-#ifdef HAVE_NTGUI
-#if 0 /* I don't think this is necessary looking at where it is used. */
- HDC hdc = get_frame_dc (f);
- SetDIBits (hdc, pixmap, 0, height, pimg->data, &(pimg->info), DIB_RGB_COLORS);
- release_frame_dc (f, hdc);
-#endif
-#endif /* HAVE_NTGUI */
-
#ifdef HAVE_NS
eassert (pimg == pixmap);
ns_retain_object (pimg);
@@ -3087,7 +3292,7 @@ image_unget_x_image_or_dc (struct image *img, bool mask_p,
static Emacs_Pix_Container
image_get_x_image (struct frame *f, struct image *img, bool mask_p)
{
-#ifdef USE_CAIRO
+#if defined USE_CAIRO || defined (HAVE_HAIKU)
return !mask_p ? img->pixmap : img->mask;
#elif defined HAVE_X_WINDOWS
XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img;
@@ -3547,10 +3752,8 @@ convert_mono_to_color_image (struct frame *f, struct image *img,
release_frame_dc (f, hdc);
old_prev = SelectObject (old_img_dc, img->pixmap);
new_prev = SelectObject (new_img_dc, new_pixmap);
- /* Windows convention for mono bitmaps is black = background,
- white = foreground. */
- SetTextColor (new_img_dc, background);
- SetBkColor (new_img_dc, foreground);
+ SetTextColor (new_img_dc, foreground);
+ SetBkColor (new_img_dc, background);
BitBlt (new_img_dc, 0, 0, img->width, img->height, old_img_dc,
0, 0, SRCCOPY);
@@ -4015,6 +4218,13 @@ xbm_load (struct frame *f, struct image *img)
XPM images
***********************************************************************/
+#if defined (HAVE_XPM) || defined (HAVE_NS) || defined (HAVE_PGTK)
+
+static bool xpm_image_p (Lisp_Object object);
+static bool xpm_load (struct frame *f, struct image *img);
+
+#endif /* HAVE_XPM || HAVE_NS */
+
#ifdef HAVE_XPM
#ifdef HAVE_NTGUI
/* Indicate to xpm.h that we don't have Xlib. */
@@ -4038,7 +4248,7 @@ xbm_load (struct frame *f, struct image *img)
#endif /* not HAVE_NTGUI */
#endif /* HAVE_XPM */
-#if defined HAVE_XPM || defined USE_CAIRO || defined HAVE_NS
+#if defined HAVE_XPM || defined USE_CAIRO || defined HAVE_NS || defined HAVE_HAIKU
/* Indices of image specification fields in xpm_format, below. */
@@ -4058,7 +4268,7 @@ enum xpm_keyword_index
XPM_LAST
};
-#if defined HAVE_XPM || defined HAVE_NS
+#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU || defined HAVE_PGTK
/* Vector of image_keyword structures describing the format
of valid XPM image specifications. */
@@ -4076,7 +4286,7 @@ static const struct image_keyword xpm_format[XPM_LAST] =
{":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
-#endif /* HAVE_XPM || HAVE_NS */
+#endif /* HAVE_XPM || HAVE_NS || HAVE_HAIKU || HAVE_PGTK */
#if defined HAVE_X_WINDOWS && !defined USE_CAIRO
@@ -4116,9 +4326,9 @@ struct xpm_cached_color
};
/* The hash table used for the color cache, and its bucket vector
- size. */
+ size (which should be prime). */
-#define XPM_COLOR_CACHE_BUCKETS 1001
+#define XPM_COLOR_CACHE_BUCKETS 1009
static struct xpm_cached_color **xpm_color_cache;
/* Initialize the color cache. */
@@ -4300,7 +4510,7 @@ init_xpm_functions (void)
#endif /* WINDOWSNT */
-#if defined HAVE_XPM || defined HAVE_NS
+#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU || defined HAVE_PGTK
/* Value is true if COLOR_SYMBOLS is a valid color symbols list
for XPM images. Such a list must consist of conses whose car and
cdr are strings. */
@@ -4336,9 +4546,9 @@ xpm_image_p (Lisp_Object object)
&& (! fmt[XPM_COLOR_SYMBOLS].count
|| xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
}
-#endif /* HAVE_XPM || HAVE_NS */
+#endif /* HAVE_XPM || HAVE_NS || HAVE_HAIKU || HAVE_PGTK */
-#endif /* HAVE_XPM || USE_CAIRO || HAVE_NS */
+#endif /* HAVE_XPM || USE_CAIRO || HAVE_NS || HAVE_HAIKU */
#if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK
ptrdiff_t
@@ -4707,9 +4917,11 @@ xpm_load (struct frame *f, struct image *img)
#endif /* HAVE_XPM && !USE_CAIRO */
#if (defined USE_CAIRO && defined HAVE_XPM) \
- || (defined HAVE_NS && !defined HAVE_XPM)
+ || (defined HAVE_NS && !defined HAVE_XPM) \
+ || (defined HAVE_HAIKU && !defined HAVE_XPM) \
+ || (defined HAVE_PGTK && !defined HAVE_XPM)
-/* XPM support functions for NS where libxpm is not available, and for
+/* XPM support functions for NS and Haiku where libxpm is not available, and for
Cairo. Only XPM version 3 (without any extensions) is supported. */
static void xpm_put_color_table_v (Lisp_Object, const char *,
@@ -4906,7 +5118,7 @@ xpm_load_image (struct frame *f,
Lisp_Object (*get_color_table) (Lisp_Object, const char *, int);
Lisp_Object frame, color_symbols, color_table;
int best_key;
-#ifndef HAVE_NS
+#if !defined (HAVE_NS)
bool have_mask = false;
#endif
Emacs_Pix_Container ximg = NULL, mask_img = NULL;
@@ -5446,7 +5658,7 @@ lookup_rgb_color (struct frame *f, int r, int g, int b)
{
#ifdef HAVE_NTGUI
return PALETTERGB (r >> 8, g >> 8, b >> 8);
-#elif defined USE_CAIRO || defined HAVE_NS
+#elif defined USE_CAIRO || defined HAVE_NS || defined HAVE_HAIKU
return RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
#else
xsignal1 (Qfile_error,
@@ -5519,7 +5731,7 @@ image_to_emacs_colors (struct frame *f, struct image *img, bool rgb_p)
p = colors;
for (y = 0; y < img->height; ++y)
{
-#if !defined USE_CAIRO && !defined HAVE_NS
+#if !defined USE_CAIRO && !defined HAVE_NS && !defined HAVE_HAIKU
Emacs_Color *row = p;
for (x = 0; x < img->width; ++x, ++p)
p->pixel = GET_PIXEL (ximg, x, y);
@@ -5527,7 +5739,7 @@ image_to_emacs_colors (struct frame *f, struct image *img, bool rgb_p)
{
FRAME_TERMINAL (f)->query_colors (f, row, img->width);
}
-#else /* USE_CAIRO || HAVE_NS */
+#else /* USE_CAIRO || HAVE_NS || HAVE_HAIKU */
for (x = 0; x < img->width; ++x, ++p)
{
p->pixel = GET_PIXEL (ximg, x, y);
@@ -5841,6 +6053,7 @@ image_disable_image (struct frame *f, struct image *img)
{
#ifndef HAVE_NTGUI
#ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
+#ifndef HAVE_HAIKU
#ifndef USE_CAIRO
#define CrossForeground(f) BLACK_PIX_DEFAULT (f)
@@ -5858,6 +6071,7 @@ image_disable_image (struct frame *f, struct image *img)
if (img->mask)
image_pixmap_draw_cross (f, img->mask, 0, 0, img->width, img->height,
MaskForeground (f));
+#endif /* !HAVE_HAIKU */
#endif /* !HAVE_NS */
#else
HDC hdc, bmpdc;
@@ -6415,15 +6629,16 @@ image_can_use_native_api (Lisp_Object type)
return w32_can_use_native_image_api (type);
# elif defined HAVE_NS
return ns_can_use_native_image_api (type);
+# elif defined HAVE_HAIKU
+ return haiku_can_use_native_image_api (type);
# else
return false;
# endif
}
/*
- * These functions are actually defined in the OS-native implementation
- * file. Currently, for Windows GDI+ interface, w32image.c, but other
- * operating systems can follow suit.
+ * These functions are actually defined in the OS-native implementation file.
+ * Currently, for Windows GDI+ interface, w32image.c, and nsimage.m for macOS.
*/
/* Indices of image specification fields in native format, below. */
@@ -6489,6 +6704,9 @@ native_image_load (struct frame *f, struct image *img)
# elif defined HAVE_NS
return ns_load_image (f, img, image_file,
image_spec_value (img->spec, QCdata, NULL));
+# elif defined HAVE_HAIKU
+ return haiku_load_image (f, img, image_file,
+ image_spec_value (img->spec, QCdata, NULL));
# else
return 0;
# endif
@@ -8233,24 +8451,30 @@ gif_image_p (Lisp_Object object)
# undef DrawText
# endif
-/* Giflib before 5.0 didn't define these macros (used only if HAVE_NTGUI). */
-# ifndef GIFLIB_MINOR
-# define GIFLIB_MINOR 0
-# endif
-# ifndef GIFLIB_RELEASE
-# define GIFLIB_RELEASE 0
-# endif
-
# else /* HAVE_NTGUI */
# include <gif_lib.h>
# endif /* HAVE_NTGUI */
-/* Giflib before 5.0 didn't define these macros. */
+/* Giflib before 4.1.6 didn't define these macros. */
# ifndef GIFLIB_MAJOR
# define GIFLIB_MAJOR 4
# endif
+# ifndef GIFLIB_MINOR
+# define GIFLIB_MINOR 0
+# endif
+# ifndef GIFLIB_RELEASE
+# define GIFLIB_RELEASE 0
+# endif
+/* Giflib before 5.0 didn't define these macros. */
+# if GIFLIB_MAJOR < 5
+# define DISPOSAL_UNSPECIFIED 0 /* No disposal specified. */
+# define DISPOSE_DO_NOT 1 /* Leave image in place. */
+# define DISPOSE_BACKGROUND 2 /* Set area too background color. */
+# define DISPOSE_PREVIOUS 3 /* Restore to previous content. */
+# define NO_TRANSPARENT_COLOR -1
+# endif
/* GifErrorString is declared to return char const * when GIFLIB_MAJOR
and GIFLIB_MINOR indicate 5.1 or later. Do not bother using it in
@@ -8273,6 +8497,8 @@ DEF_DLL_FN (GifFileType *, DGifOpenFileName, (const char *));
# else
DEF_DLL_FN (GifFileType *, DGifOpen, (void *, InputFunc, int *));
DEF_DLL_FN (GifFileType *, DGifOpenFileName, (const char *, int *));
+DEF_DLL_FN (int, DGifSavedExtensionToGCB,
+ (GifFileType *, int, GraphicsControlBlock *));
# endif
# if HAVE_GIFERRORSTRING
DEF_DLL_FN (char const *, GifErrorString, (int));
@@ -8290,6 +8516,9 @@ init_gif_functions (void)
LOAD_DLL_FN (library, DGifSlurp);
LOAD_DLL_FN (library, DGifOpen);
LOAD_DLL_FN (library, DGifOpenFileName);
+# if GIFLIB_MAJOR >= 5
+ LOAD_DLL_FN (library, DGifSavedExtensionToGCB);
+# endif
# if HAVE_GIFERRORSTRING
LOAD_DLL_FN (library, GifErrorString);
# endif
@@ -8300,12 +8529,18 @@ init_gif_functions (void)
# undef DGifOpen
# undef DGifOpenFileName
# undef DGifSlurp
+# if GIFLIB_MAJOR >= 5
+# undef DGifSavedExtensionToGCB
+# endif
# undef GifErrorString
# define DGifCloseFile fn_DGifCloseFile
# define DGifOpen fn_DGifOpen
# define DGifOpenFileName fn_DGifOpenFileName
# define DGifSlurp fn_DGifSlurp
+# if GIFLIB_MAJOR >= 5
+# define DGifSavedExtensionToGCB fn_DGifSavedExtensionToGCB
+# endif
# define GifErrorString fn_GifErrorString
# endif /* WINDOWSNT */
@@ -8383,7 +8618,7 @@ gif_load (struct frame *f, struct image *img)
if (!STRINGP (file))
{
image_error ("Cannot find image file `%s'", specified_file);
- return 0;
+ return false;
}
Lisp_Object encoded_file = ENCODE_FILE (file);
@@ -8406,8 +8641,7 @@ gif_load (struct frame *f, struct image *img)
else
#endif
image_error ("Cannot open `%s'", file);
-
- return 0;
+ return false;
}
}
else
@@ -8415,7 +8649,7 @@ gif_load (struct frame *f, struct image *img)
if (!STRINGP (specified_data))
{
image_error ("Invalid image data `%s'", specified_data);
- return 0;
+ return false;
}
/* Read from memory! */
@@ -8439,7 +8673,7 @@ gif_load (struct frame *f, struct image *img)
else
#endif
image_error ("Cannot open memory source `%s'", img->spec);
- return 0;
+ return false;
}
}
@@ -8447,8 +8681,7 @@ gif_load (struct frame *f, struct image *img)
if (!check_image_size (f, gif->SWidth, gif->SHeight))
{
image_size_error ();
- gif_close (gif, NULL);
- return 0;
+ goto gif_error;
}
/* Read entire contents. */
@@ -8459,8 +8692,7 @@ gif_load (struct frame *f, struct image *img)
image_error ("Error reading `%s'", img->spec);
else
image_error ("Error reading GIF data");
- gif_close (gif, NULL);
- return 0;
+ goto gif_error;
}
/* Which sub-image are we to display? */
@@ -8471,8 +8703,7 @@ gif_load (struct frame *f, struct image *img)
{
image_error ("Invalid image number `%s' in image `%s'",
image_number, img->spec);
- gif_close (gif, NULL);
- return 0;
+ goto gif_error;
}
}
@@ -8489,8 +8720,7 @@ gif_load (struct frame *f, struct image *img)
if (!check_image_size (f, width, height))
{
image_size_error ();
- gif_close (gif, NULL);
- return 0;
+ goto gif_error;
}
/* Check that the selected subimages fit. It's not clear whether
@@ -8507,18 +8737,14 @@ gif_load (struct frame *f, struct image *img)
&& 0 <= subimg_left && subimg_left <= width - subimg_width))
{
image_error ("Subimage does not fit in image");
- gif_close (gif, NULL);
- return 0;
+ goto gif_error;
}
}
/* Create the X image and pixmap. */
Emacs_Pix_Container ximg;
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
- {
- gif_close (gif, NULL);
- return 0;
- }
+ goto gif_error;
/* Clear the part of the screen image not covered by the image.
Full animated GIF support requires more here (see the gif89 spec,
@@ -8577,13 +8803,17 @@ gif_load (struct frame *f, struct image *img)
char *, which invites problems with bytes >= 0x80. */
struct SavedImage *subimage = gif->SavedImages + j;
unsigned char *raster = (unsigned char *) subimage->RasterBits;
- int transparency_color_index = -1;
- int disposal = 0;
int subimg_width = subimage->ImageDesc.Width;
int subimg_height = subimage->ImageDesc.Height;
int subimg_top = subimage->ImageDesc.Top;
int subimg_left = subimage->ImageDesc.Left;
+ /* From gif89a spec: 1 = "keep in place", 2 = "restore
+ to background". Treat any other value like 2. */
+ int disposal = DISPOSAL_UNSPECIFIED;
+ int transparency_color_index = NO_TRANSPARENT_COLOR;
+
+#if GIFLIB_MAJOR < 5
/* Find the Graphic Control Extension block for this sub-image.
Extract the disposal method and transparency color. */
for (i = 0; i < subimage->ExtensionBlockCount; i++)
@@ -8594,24 +8824,29 @@ gif_load (struct frame *f, struct image *img)
&& extblock->ByteCount == 4
&& extblock->Bytes[0] & 1)
{
- /* From gif89a spec: 1 = "keep in place", 2 = "restore
- to background". Treat any other value like 2. */
disposal = (extblock->Bytes[0] >> 2) & 7;
transparency_color_index = (unsigned char) extblock->Bytes[3];
break;
}
}
+#else
+ GraphicsControlBlock gcb;
+ DGifSavedExtensionToGCB (gif, j, &gcb);
+ disposal = gcb.DisposalMode;
+ transparency_color_index = gcb.TransparentColor;
+#endif
/* We can't "keep in place" the first subimage. */
if (j == 0)
- disposal = 2;
+ disposal = DISPOSE_BACKGROUND;
- /* For disposal == 0, the spec says "No disposal specified. The
- decoder is not required to take any action." In practice, it
- seems we need to treat this like "keep in place", see e.g.
+ /* For disposal == 0 (DISPOSAL_UNSPECIFIED), the spec says
+ "No disposal specified. The decoder is not required to take
+ any action." In practice, it seems we need to treat this
+ like "keep in place" (DISPOSE_DO_NOT), see e.g.
https://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */
- if (disposal == 0)
- disposal = 1;
+ if (disposal == DISPOSAL_UNSPECIFIED)
+ disposal = DISPOSE_DO_NOT;
gif_color_map = subimage->ImageDesc.ColorMap;
if (!gif_color_map)
@@ -8650,7 +8885,7 @@ gif_load (struct frame *f, struct image *img)
for (x = 0; x < subimg_width; x++)
{
int c = raster[y * subimg_width + x];
- if (transparency_color_index != c || disposal != 1)
+ if (transparency_color_index != c || disposal != DISPOSE_DO_NOT)
{
PUT_PIXEL (ximg, x + subimg_left, row + subimg_top,
pixel_colors[c]);
@@ -8664,7 +8899,7 @@ gif_load (struct frame *f, struct image *img)
for (x = 0; x < subimg_width; ++x)
{
int c = raster[y * subimg_width + x];
- if (transparency_color_index != c || disposal != 1)
+ if (transparency_color_index != c || disposal != DISPOSE_DO_NOT)
{
PUT_PIXEL (ximg, x + subimg_left, y + subimg_top,
pixel_colors[c]);
@@ -8734,14 +8969,302 @@ gif_load (struct frame *f, struct image *img)
/* Put ximg into the image. */
image_put_x_image (f, img, ximg, 0);
- return 1;
+ return true;
+
+ gif_error:
+ gif_close (gif, NULL);
+ return false;
}
#endif /* HAVE_GIF */
+#ifdef HAVE_WEBP
+
+
+/***********************************************************************
+ WebP
+ ***********************************************************************/
+
+#include "webp/decode.h"
+
+/* Indices of image specification fields in webp_format, below. */
+
+enum webp_keyword_index
+{
+ WEBP_TYPE,
+ WEBP_DATA,
+ WEBP_FILE,
+ WEBP_ASCENT,
+ WEBP_MARGIN,
+ WEBP_RELIEF,
+ WEBP_ALGORITHM,
+ WEBP_HEURISTIC_MASK,
+ WEBP_MASK,
+ WEBP_BACKGROUND,
+ WEBP_LAST
+};
+
+/* Vector of image_keyword structures describing the format
+ of valid user-defined image specifications. */
+
+static const struct image_keyword webp_format[WEBP_LAST] =
+{
+ {":type", IMAGE_SYMBOL_VALUE, 1},
+ {":data", IMAGE_STRING_VALUE, 0},
+ {":file", IMAGE_STRING_VALUE, 0},
+ {":ascent", IMAGE_ASCENT_VALUE, 0},
+ {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":relief", IMAGE_INTEGER_VALUE, 0},
+ {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
+};
+
+/* Return true if OBJECT is a valid WebP image specification. */
+
+static bool
+webp_image_p (Lisp_Object object)
+{
+ struct image_keyword fmt[WEBP_LAST];
+ memcpy (fmt, webp_format, sizeof fmt);
+
+ if (!parse_image_spec (object, fmt, WEBP_LAST, Qwebp))
+ return false;
+
+ /* Must specify either the :data or :file keyword. */
+ return fmt[WEBP_FILE].count + fmt[WEBP_DATA].count == 1;
+}
+
+#ifdef WINDOWSNT
+
+/* WebP library details. */
+
+DEF_DLL_FN (int, WebPGetInfo, (const uint8_t *, size_t, int *, int *));
+/* WebPGetFeatures is a static inline function defined in WebP's
+ decode.h. Since we cannot use that with dynamically-loaded libwebp
+ DLL, we instead load the internal function it calls and redirect to
+ that through a macro. */
+DEF_DLL_FN (VP8StatusCode, WebPGetFeaturesInternal,
+ (const uint8_t *, size_t, WebPBitstreamFeatures *, int));
+DEF_DLL_FN (uint8_t *, WebPDecodeRGBA, (const uint8_t *, size_t, int *, int *));
+DEF_DLL_FN (uint8_t *, WebPDecodeRGB, (const uint8_t *, size_t, int *, int *));
+DEF_DLL_FN (void, WebPFree, (void *));
+
+static bool
+init_webp_functions (void)
+{
+ HMODULE library;
+
+ if (!(library = w32_delayed_load (Qwebp)))
+ return false;
+
+ LOAD_DLL_FN (library, WebPGetInfo);
+ LOAD_DLL_FN (library, WebPGetFeaturesInternal);
+ LOAD_DLL_FN (library, WebPDecodeRGBA);
+ LOAD_DLL_FN (library, WebPDecodeRGB);
+ LOAD_DLL_FN (library, WebPFree);
+ return true;
+}
+
+#undef WebPGetInfo
+#undef WebPGetFeatures
+#undef WebPDecodeRGBA
+#undef WebPDecodeRGB
+#undef WebPFree
+
+#define WebPGetInfo fn_WebPGetInfo
+#define WebPGetFeatures(d,s,f) \
+ fn_WebPGetFeaturesInternal(d,s,f,WEBP_DECODER_ABI_VERSION)
+#define WebPDecodeRGBA fn_WebPDecodeRGBA
+#define WebPDecodeRGB fn_WebPDecodeRGB
+#define WebPFree fn_WebPFree
+
+#endif /* WINDOWSNT */
+
+/* Load WebP image IMG for use on frame F. Value is true if
+ successful. */
+
+static bool
+webp_load (struct frame *f, struct image *img)
+{
+ ptrdiff_t size = 0;
+ uint8_t *contents;
+ Lisp_Object file = Qnil;
+
+ /* Open the WebP file. */
+ Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
+ Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL);
+
+ if (NILP (specified_data))
+ {
+ int fd;
+ file = image_find_image_fd (specified_file, &fd);
+ if (!STRINGP (file))
+ {
+ image_error ("Cannot find image file `%s'", specified_file);
+ return false;
+ }
+
+ contents = (uint8_t *) slurp_file (fd, &size);
+ if (contents == NULL)
+ {
+ image_error ("Error loading WebP image `%s'", file);
+ return false;
+ }
+ }
+ else
+ {
+ if (!STRINGP (specified_data))
+ {
+ image_error ("Invalid image data `%s'", specified_data);
+ return false;
+ }
+ contents = SDATA (specified_data);
+ size = SBYTES (specified_data);
+ }
+
+ /* Validate the WebP image header. */
+ if (!WebPGetInfo (contents, size, NULL, NULL))
+ {
+ if (!NILP (file))
+ image_error ("Not a WebP file: `%s'", file);
+ else
+ image_error ("Invalid header in WebP image data");
+ goto webp_error1;
+ }
+
+ /* Get WebP features. */
+ WebPBitstreamFeatures features;
+ VP8StatusCode result = WebPGetFeatures (contents, size, &features);
+ switch (result)
+ {
+ case VP8_STATUS_OK:
+ break;
+ case VP8_STATUS_NOT_ENOUGH_DATA:
+ case VP8_STATUS_OUT_OF_MEMORY:
+ case VP8_STATUS_INVALID_PARAM:
+ case VP8_STATUS_BITSTREAM_ERROR:
+ case VP8_STATUS_UNSUPPORTED_FEATURE:
+ case VP8_STATUS_SUSPENDED:
+ case VP8_STATUS_USER_ABORT:
+ default:
+ /* Error out in all other cases. */
+ if (!NILP (file))
+ image_error ("Error when interpreting WebP image data: `%s'", file);
+ else
+ image_error ("Error when interpreting WebP image data");
+ goto webp_error1;
+ }
+
+ /* Decode WebP data. */
+ uint8_t *decoded;
+ int width, height;
+ if (features.has_alpha)
+ /* Linear [r0, g0, b0, a0, r1, g1, b1, a1, ...] order. */
+ decoded = WebPDecodeRGBA (contents, size, &width, &height);
+ else
+ /* Linear [r0, g0, b0, r1, g1, b1, ...] order. */
+ decoded = WebPDecodeRGB (contents, size, &width, &height);
+
+ if (!decoded)
+ {
+ image_error ("Error when interpreting WebP image data");
+ goto webp_error1;
+ }
+
+ if (!(width <= INT_MAX && height <= INT_MAX
+ && check_image_size (f, width, height)))
+ {
+ image_size_error ();
+ goto webp_error2;
+ }
+
+ /* Create the x image and pixmap. */
+ Emacs_Pix_Container ximg, mask_img = NULL;
+ if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, false))
+ goto webp_error2;
+
+ /* Create an image and pixmap serving as mask if the WebP image
+ contains an alpha channel. */
+ if (features.has_alpha
+ && !image_create_x_image_and_pixmap (f, img, width, height, 1, &mask_img, true))
+ {
+ image_destroy_x_image (ximg);
+ image_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP);
+ goto webp_error2;
+ }
+
+ /* Fill the X image and mask from WebP data. */
+ init_color_table ();
+
+ uint8_t *p = decoded;
+ for (int y = 0; y < height; ++y)
+ {
+ for (int x = 0; x < width; ++x)
+ {
+ int r = *p++ << 8;
+ int g = *p++ << 8;
+ int b = *p++ << 8;
+ PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, r, g, b));
+
+ /* An alpha channel associates variable transparency with an
+ image. WebP allows up to 256 levels of partial transparency.
+ We handle this like with PNG (which see), using the frame's
+ background color to combine the image with. */
+ if (features.has_alpha)
+ {
+ if (mask_img)
+ PUT_PIXEL (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN);
+ ++p;
+ }
+ }
+ }
+
+#ifdef COLOR_TABLE_SUPPORT
+ /* Remember colors allocated for this image. */
+ img->colors = colors_in_color_table (&img->ncolors);
+ free_color_table ();
+#endif /* COLOR_TABLE_SUPPORT */
+
+ /* Put ximg into the image. */
+ image_put_x_image (f, img, ximg, 0);
+
+ /* Same for the mask. */
+ if (mask_img)
+ {
+ /* Fill in the background_transparent field while we have the
+ mask handy. Casting avoids a GCC warning. */
+ image_background_transparent (img, f, (Emacs_Pix_Context)mask_img);
+
+ image_put_x_image (f, img, mask_img, 1);
+ }
+
+ img->width = width;
+ img->height = height;
+
+ /* Clean up. */
+ WebPFree (decoded);
+ if (NILP (specified_data))
+ xfree (contents);
+ return true;
+
+ webp_error2:
+ WebPFree (decoded);
+
+ webp_error1:
+ if (NILP (specified_data))
+ xfree (contents);
+ return false;
+}
+
+#endif /* HAVE_WEBP */
+
+
#ifdef HAVE_IMAGEMAGICK
+
/***********************************************************************
ImageMagick
***********************************************************************/
@@ -9117,11 +9640,15 @@ imagemagick_load_image (struct frame *f, struct image *img,
PixelWand **pixels, *bg_wand = NULL;
MagickPixelPacket pixel;
Lisp_Object image;
+#ifndef DONT_CREATE_TRANSFORMED_IMAGEMAGICK_IMAGE
Lisp_Object value;
+#endif
Lisp_Object crop;
EMACS_INT ino;
int desired_width, desired_height;
+#ifndef DONT_CREATE_TRANSFORMED_IMAGEMAGICK_IMAGE
double rotation;
+#endif
char hint_buffer[MaxTextExtent];
char *filename_hint = NULL;
imagemagick_initialize ();
@@ -9238,9 +9765,13 @@ imagemagick_load_image (struct frame *f, struct image *img,
PixelSetBlue (bg_wand, (double) bgcolor.blue / 65535);
}
+#ifndef DONT_CREATE_TRANSFORMED_IMAGEMAGICK_IMAGE
compute_image_size (MagickGetImageWidth (image_wand),
MagickGetImageHeight (image_wand),
img, &desired_width, &desired_height);
+#else
+ desired_width = desired_height = -1;
+#endif
if (desired_width != -1 && desired_height != -1)
{
@@ -9284,6 +9815,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
}
}
+#ifndef DONT_CREATE_TRANSFORMED_IMAGEMAGICK_IMAGE
/* Furthermore :rotation. we need background color and angle for
rotation. */
/*
@@ -9302,6 +9834,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
goto imagemagick_error;
}
}
+#endif
/* Set the canvas background color to the frame or specified
background, and flatten the image. Note: as of ImageMagick
@@ -9339,7 +9872,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
init_color_table ();
-#if defined (HAVE_MAGICKEXPORTIMAGEPIXELS) && ! defined (HAVE_NS)
+#if defined (HAVE_MAGICKEXPORTIMAGEPIXELS) && \
+ ! defined (HAVE_NS) && ! defined (HAVE_HAIKU)
if (imagemagick_render_type != 0)
{
/* Magicexportimage is normally faster than pixelpushing. This
@@ -9432,8 +9966,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
color_scale * pixel.red,
color_scale * pixel.green,
color_scale * pixel.blue));
- }
- }
+ }
+ }
DestroyPixelIterator (iterator);
}
@@ -9669,6 +10203,10 @@ DEF_DLL_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **));
DEF_DLL_FN (void, rsvg_handle_set_dpi_x_y,
(RsvgHandle * handle, double dpi_x, double dpi_y));
+# if LIBRSVG_CHECK_VERSION (2, 52, 1)
+DEF_DLL_FN (gboolean, rsvg_handle_get_intrinsic_size_in_pixels,
+ (RsvgHandle *, gdouble *, gdouble *));
+# endif
# if LIBRSVG_CHECK_VERSION (2, 46, 0)
DEF_DLL_FN (void, rsvg_handle_get_intrinsic_dimensions,
(RsvgHandle *, gboolean *, RsvgLength *, gboolean *,
@@ -9676,14 +10214,15 @@ DEF_DLL_FN (void, rsvg_handle_get_intrinsic_dimensions,
DEF_DLL_FN (gboolean, rsvg_handle_get_geometry_for_layer,
(RsvgHandle *, const char *, const RsvgRectangle *,
RsvgRectangle *, RsvgRectangle *, GError **));
+# else
+DEF_DLL_FN (void, rsvg_handle_get_dimensions,
+ (RsvgHandle *, RsvgDimensionData *));
# endif
# if LIBRSVG_CHECK_VERSION (2, 48, 0)
DEF_DLL_FN (gboolean, rsvg_handle_set_stylesheet,
(RsvgHandle *, const guint8 *, gsize, GError **));
# endif
-DEF_DLL_FN (void, rsvg_handle_get_dimensions,
- (RsvgHandle *, RsvgDimensionData *));
DEF_DLL_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *));
DEF_DLL_FN (int, gdk_pixbuf_get_width, (const GdkPixbuf *));
DEF_DLL_FN (int, gdk_pixbuf_get_height, (const GdkPixbuf *));
@@ -9731,14 +10270,18 @@ init_svg_functions (void)
LOAD_DLL_FN (library, rsvg_handle_close);
#endif
LOAD_DLL_FN (library, rsvg_handle_set_dpi_x_y);
+#if LIBRSVG_CHECK_VERSION (2, 52, 1)
+ LOAD_DLL_FN (library, rsvg_handle_get_intrinsic_size_in_pixels);
+#endif
#if LIBRSVG_CHECK_VERSION (2, 46, 0)
LOAD_DLL_FN (library, rsvg_handle_get_intrinsic_dimensions);
LOAD_DLL_FN (library, rsvg_handle_get_geometry_for_layer);
+#else
+ LOAD_DLL_FN (library, rsvg_handle_get_dimensions);
#endif
#if LIBRSVG_CHECK_VERSION (2, 48, 0)
LOAD_DLL_FN (library, rsvg_handle_set_stylesheet);
#endif
- LOAD_DLL_FN (library, rsvg_handle_get_dimensions);
LOAD_DLL_FN (library, rsvg_handle_get_pixbuf);
LOAD_DLL_FN (gdklib, gdk_pixbuf_get_width);
@@ -9773,11 +10316,15 @@ init_svg_functions (void)
# undef g_clear_error
# undef g_object_unref
# undef g_type_init
+# if LIBRSVG_CHECK_VERSION (2, 52, 1)
+# undef rsvg_handle_get_intrinsic_size_in_pixels
+# endif
# if LIBRSVG_CHECK_VERSION (2, 46, 0)
# undef rsvg_handle_get_intrinsic_dimensions
# undef rsvg_handle_get_geometry_for_layer
+# else
+# undef rsvg_handle_get_dimensions
# endif
-# undef rsvg_handle_get_dimensions
# if LIBRSVG_CHECK_VERSION (2, 48, 0)
# undef rsvg_handle_set_stylesheet
# endif
@@ -9807,13 +10354,18 @@ init_svg_functions (void)
# if ! GLIB_CHECK_VERSION (2, 36, 0)
# define g_type_init fn_g_type_init
# endif
+# if LIBRSVG_CHECK_VERSION (2, 52, 1)
+# define rsvg_handle_get_intrinsic_size_in_pixels \
+ fn_rsvg_handle_get_intrinsic_size_in_pixels
+# endif
# if LIBRSVG_CHECK_VERSION (2, 46, 0)
# define rsvg_handle_get_intrinsic_dimensions \
fn_rsvg_handle_get_intrinsic_dimensions
# define rsvg_handle_get_geometry_for_layer \
fn_rsvg_handle_get_geometry_for_layer
+# else
+# define rsvg_handle_get_dimensions fn_rsvg_handle_get_dimensions
# endif
-# define rsvg_handle_get_dimensions fn_rsvg_handle_get_dimensions
# if LIBRSVG_CHECK_VERSION (2, 48, 0)
# define rsvg_handle_set_stylesheet fn_rsvg_handle_set_stylesheet
# endif
@@ -9996,10 +10548,16 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
if (!STRINGP (lcss))
{
/* Generate the CSS for the SVG image. */
- const char *css_spec = "svg{font-family:\"%s\";font-size:%4dpx}";
- int css_len = strlen (css_spec) + strlen (img->face_font_family);
+ /* FIXME: The below calculations leave enough space for a font
+ size up to 9999, if it overflows we just throw an error but
+ should probably increase the buffer size. */
+ const char *css_spec = "svg{font-family:\"%s\";font-size:%dpx}";
+ int css_len = strlen (css_spec) + strlen (img->face_font_family) + 1;
css = xmalloc (css_len);
- snprintf (css, css_len, css_spec, img->face_font_family, img->face_font_size);
+ if (css_len <= snprintf (css, css_len, css_spec,
+ img->face_font_family, img->face_font_size))
+ goto rsvg_error;
+
rsvg_handle_set_stylesheet (rsvg_handle, (guint8 *)css, strlen (css), NULL);
}
else
@@ -10037,72 +10595,85 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
/* Get the image dimensions. */
#if LIBRSVG_CHECK_VERSION (2, 46, 0)
- RsvgRectangle zero_rect, viewbox, out_logical_rect;
-
- /* Try the instrinsic dimensions first. */
- gboolean has_width, has_height, has_viewbox;
- RsvgLength iwidth, iheight;
- double dpi = FRAME_DISPLAY_INFO (f)->resx;
-
- rsvg_handle_get_intrinsic_dimensions (rsvg_handle,
- &has_width, &iwidth,
- &has_height, &iheight,
- &has_viewbox, &viewbox);
+ gdouble gviewbox_width = 0, gviewbox_height = 0;
+ gboolean has_viewbox = FALSE;
+# if LIBRSVG_CHECK_VERSION (2, 52, 1)
+ has_viewbox = rsvg_handle_get_intrinsic_size_in_pixels (rsvg_handle,
+ &gviewbox_width,
+ &gviewbox_height);
+# endif
- if (has_width && has_height)
- {
- /* Success! We can use these values directly. */
- viewbox_width = svg_css_length_to_pixels (iwidth, dpi, img->face_font_size);
- viewbox_height = svg_css_length_to_pixels (iheight, dpi, img->face_font_size);
- }
- else if (has_width && has_viewbox)
- {
- viewbox_width = svg_css_length_to_pixels (iwidth, dpi, img->face_font_size);
- viewbox_height = svg_css_length_to_pixels (iwidth, dpi, img->face_font_size)
- * viewbox.height / viewbox.width;
- }
- else if (has_height && has_viewbox)
- {
- viewbox_height = svg_css_length_to_pixels (iheight, dpi, img->face_font_size);
- viewbox_width = svg_css_length_to_pixels (iheight, dpi, img->face_font_size)
- * viewbox.width / viewbox.height;
- }
- else if (has_viewbox)
+ if (has_viewbox)
{
- viewbox_width = viewbox.width;
- viewbox_height = viewbox.height;
+ viewbox_width = gviewbox_width;
+ viewbox_height = gviewbox_height;
}
else
{
- /* We haven't found a useable set of sizes, so try working out
- the visible area. */
- rsvg_handle_get_geometry_for_layer (rsvg_handle, NULL,
- &zero_rect, &viewbox,
- &out_logical_rect, NULL);
- viewbox_width = viewbox.x + viewbox.width;
- viewbox_height = viewbox.y + viewbox.height;
- }
+ RsvgRectangle zero_rect, viewbox, out_logical_rect;
- if (viewbox_width == 0 || viewbox_height == 0)
-#endif
- {
- /* The functions used above to get the geometry of the visible
- area of the SVG are only available in librsvg 2.46 and above,
- so in certain circumstances this code path can result in some
- parts of the SVG being cropped. */
- RsvgDimensionData dimension_data;
+ /* Try the intrinsic dimensions first. */
+ gboolean has_width, has_height;
+ RsvgLength iwidth, iheight;
+ double dpi = FRAME_DISPLAY_INFO (f)->resx;
- rsvg_handle_get_dimensions (rsvg_handle, &dimension_data);
+ rsvg_handle_get_intrinsic_dimensions (rsvg_handle,
+ &has_width, &iwidth,
+ &has_height, &iheight,
+ &has_viewbox, &viewbox);
- viewbox_width = dimension_data.width;
- viewbox_height = dimension_data.height;
- }
+ if (has_width && has_height)
+ {
+ /* Success! We can use these values directly. */
+ viewbox_width = svg_css_length_to_pixels (iwidth, dpi,
+ img->face_font_size);
+ viewbox_height = svg_css_length_to_pixels (iheight, dpi,
+ img->face_font_size);
+ }
+ else if (has_width && has_viewbox)
+ {
+ viewbox_width = svg_css_length_to_pixels (iwidth, dpi,
+ img->face_font_size);
+ viewbox_height = viewbox_width * viewbox.height / viewbox.width;
+ }
+ else if (has_height && has_viewbox)
+ {
+ viewbox_height = svg_css_length_to_pixels (iheight, dpi,
+ img->face_font_size);
+ viewbox_width = viewbox_height * viewbox.width / viewbox.height;
+ }
+ else if (has_viewbox)
+ {
+ viewbox_width = viewbox.width;
+ viewbox_height = viewbox.height;
+ }
+ else
+ viewbox_width = viewbox_height = 0;
+
+ if (! (0 < viewbox_width && 0 < viewbox_height))
+ {
+ /* We haven't found a usable set of sizes, so try working out
+ the visible area. */
+ rsvg_handle_get_geometry_for_layer (rsvg_handle, NULL,
+ &zero_rect, &viewbox,
+ &out_logical_rect, NULL);
+ viewbox_width = viewbox.x + viewbox.width;
+ viewbox_height = viewbox.y + viewbox.height;
+ }
+ }
+#else
+ /* In librsvg before 2.46.0, guess the viewbox from the image dimensions. */
+ RsvgDimensionData dimension_data;
+ rsvg_handle_get_dimensions (rsvg_handle, &dimension_data);
+ viewbox_width = dimension_data.width;
+ viewbox_height = dimension_data.height;
+#endif
compute_image_size (viewbox_width, viewbox_height, img,
&width, &height);
- width *= FRAME_SCALE_FACTOR (f);
- height *= FRAME_SCALE_FACTOR (f);
+ width = scale_image_size (width, 1, FRAME_SCALE_FACTOR (f));
+ height = scale_image_size (height, 1, FRAME_SCALE_FACTOR (f));
if (! check_image_size (f, width, height))
{
@@ -10157,12 +10728,11 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
wrapped_contents = xmalloc (buffer_size);
- if (!wrapped_contents
- || buffer_size <= snprintf (wrapped_contents, buffer_size, wrapper,
- foreground & 0xFFFFFF, width, height,
- viewbox_width, viewbox_height,
- background & 0xFFFFFF,
- SSDATA (encoded_contents)))
+ if (buffer_size <= snprintf (wrapped_contents, buffer_size, wrapper,
+ foreground & 0xFFFFFF, width, height,
+ viewbox_width, viewbox_height,
+ background & 0xFFFFFF,
+ SSDATA (encoded_contents)))
goto rsvg_error;
wrapped_size = strlen (wrapped_contents);
@@ -10550,16 +11120,6 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f)
free_color_table ();
#endif
XDestroyImage (ximg);
-
-#if 0 /* This doesn't seem to be the case. If we free the colors
- here, we get a BadAccess later in image_clear_image when
- freeing the colors. */
- /* We have allocated colors once, but Ghostscript has also
- allocated colors on behalf of us. So, to get the
- reference counts right, free them once. */
- if (img->ncolors)
- x_free_colors (f, img->colors, img->ncolors);
-#endif
}
else
image_error ("Cannot get X image of `%s'; colors will not be freed",
@@ -10628,7 +11188,8 @@ The list of capabilities can include one or more of the following:
if (FRAME_WINDOW_P (f))
{
#ifdef HAVE_NATIVE_TRANSFORMS
-# if defined HAVE_IMAGEMAGICK || defined (USE_CAIRO) || defined (HAVE_NS)
+# if defined HAVE_IMAGEMAGICK || defined (USE_CAIRO) || defined (HAVE_NS) \
+ || defined (HAVE_HAIKU)
return list2 (Qscale, Qrotate90);
# elif defined (HAVE_X_WINDOWS) && defined (HAVE_XRENDER)
int event_basep, error_basep;
@@ -10718,10 +11279,14 @@ static struct image_type const image_types[] =
{ SYMBOL_INDEX (Qjpeg), jpeg_image_p, jpeg_load, image_clear_image,
IMAGE_TYPE_INIT (init_jpeg_functions) },
#endif
-#if defined HAVE_XPM || defined HAVE_NS
+#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU || defined HAVE_PGTK
{ SYMBOL_INDEX (Qxpm), xpm_image_p, xpm_load, image_clear_image,
IMAGE_TYPE_INIT (init_xpm_functions) },
#endif
+#if defined HAVE_WEBP
+ { SYMBOL_INDEX (Qwebp), webp_image_p, webp_load, image_clear_image,
+ IMAGE_TYPE_INIT (init_webp_functions) },
+#endif
{ SYMBOL_INDEX (Qxbm), xbm_image_p, xbm_load, image_clear_image },
{ SYMBOL_INDEX (Qpbm), pbm_image_p, pbm_load, image_clear_image },
};
@@ -10862,7 +11427,8 @@ non-numeric, there is no explicit limit on the size of images. */);
DEFSYM (Qxbm, "xbm");
add_image_type (Qxbm);
-#if defined (HAVE_XPM) || defined (HAVE_NS)
+#if defined (HAVE_XPM) || defined (HAVE_NS) \
+ || defined (HAVE_HAIKU) || defined (HAVE_PGTK)
DEFSYM (Qxpm, "xpm");
add_image_type (Qxpm);
#endif
@@ -10887,6 +11453,11 @@ non-numeric, there is no explicit limit on the size of images. */);
add_image_type (Qpng);
#endif
+#if defined (HAVE_WEBP)
+ DEFSYM (Qwebp, "webp");
+ add_image_type (Qwebp);
+#endif
+
#if defined (HAVE_IMAGEMAGICK)
DEFSYM (Qimagemagick, "imagemagick");
add_image_type (Qimagemagick);
diff --git a/src/indent.c b/src/indent.c
index de6b4895616..914dabf1e72 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -2051,6 +2051,7 @@ window_column_x (struct window *w, Lisp_Object window,
/* Restore window's buffer and point. */
+/* FIXME: Merge with `with_echo_area_buffer_unwind_data`? */
static void
restore_window_buffer (Lisp_Object list)
{
diff --git a/src/intervals.c b/src/intervals.c
index f88a41f2549..11d5b6bbb6f 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -166,10 +166,11 @@ merge_properties (register INTERVAL source, register INTERVAL target)
}
}
-/* Return true if the two intervals have the same properties. */
+/* Return true if the two intervals have the same properties.
+ If use_equal is true, use Fequal for comparisons instead of EQ. */
-bool
-intervals_equal (INTERVAL i0, INTERVAL i1)
+static bool
+intervals_equal_1 (INTERVAL i0, INTERVAL i1, bool use_equal)
{
Lisp_Object i0_cdr, i0_sym;
Lisp_Object i1_cdr, i1_val;
@@ -204,7 +205,8 @@ intervals_equal (INTERVAL i0, INTERVAL i1)
/* i0 and i1 both have sym, but it has different values in each. */
if (!CONSP (i1_val)
|| (i1_val = XCDR (i1_val), !CONSP (i1_val))
- || !EQ (XCAR (i1_val), XCAR (i0_cdr)))
+ || use_equal ? NILP (Fequal (XCAR (i1_val), XCAR (i0_cdr)))
+ : !EQ (XCAR (i1_val), XCAR (i0_cdr)))
return false;
i0_cdr = XCDR (i0_cdr);
@@ -218,6 +220,14 @@ intervals_equal (INTERVAL i0, INTERVAL i1)
/* Lengths of the two plists were equal. */
return (NILP (i0_cdr) && NILP (i1_cdr));
}
+
+/* Return true if the two intervals have the same properties. */
+
+bool
+intervals_equal (INTERVAL i0, INTERVAL i1)
+{
+ return intervals_equal_1 (i0, i1, false);
+}
/* Traverse an interval tree TREE, performing FUNCTION on each node.
@@ -2291,7 +2301,7 @@ compare_string_intervals (Lisp_Object s1, Lisp_Object s2)
/* If we ever find a mismatch between the strings,
they differ. */
- if (! intervals_equal (i1, i2))
+ if (! intervals_equal_1 (i1, i2, true))
return 0;
/* Advance POS till the end of the shorter interval,
diff --git a/src/keyboard.c b/src/keyboard.c
index 2e4c4e6aabf..821a1b576be 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -375,6 +375,7 @@ static void timer_resume_idle (void);
static void deliver_user_signal (int);
static char *find_user_signal_name (int);
static void store_user_signal_events (void);
+static bool is_ignored_event (union buffered_input_event *);
/* Advance or retreat a buffered input event pointer. */
@@ -753,10 +754,21 @@ DEFUN ("recursive-edit", Frecursive_edit, Srecursive_edit, 0, 0, "",
doc: /* Invoke the editor command loop recursively.
To get out of the recursive edit, a command can throw to `exit' -- for
instance (throw \\='exit nil).
-If you throw a value other than t, `recursive-edit' returns normally
-to the function that called it. Throwing a t value causes
-`recursive-edit' to quit, so that control returns to the command loop
-one level up.
+
+The following values (last argument to `throw') can be used when
+throwing to \\='exit:
+
+- t causes `recursive-edit' to quit, so that control returns to the
+ command loop one level up.
+
+- A string causes `recursive-edit' to signal an error, printing that
+ string as the error message.
+
+- A function causes `recursive-edit' to call that function with no
+ arguments, and then return normally.
+
+- Any other value causes `recursive-edit' to return normally to the
+ function that called it.
This function is called by the editor initialization to begin editing. */)
(void)
@@ -951,6 +963,10 @@ cmd_error (Lisp_Object data)
Vexecuting_kbd_macro = Qnil;
executing_kbd_macro = Qnil;
}
+ else if (!NILP (KVAR (current_kboard, defining_kbd_macro)))
+ /* An `M-x' command that signals a `minibuffer-quit' condition
+ that's part of a kbd macro. */
+ finalize_kbd_macro_chars ();
specbind (Qstandard_output, Qt);
specbind (Qstandard_input, Qt);
@@ -1009,25 +1025,28 @@ Default value of `command-error-function'. */)
(Lisp_Object data, Lisp_Object context, Lisp_Object signal)
{
struct frame *sf = SELECTED_FRAME ();
- Lisp_Object conditions;
+ Lisp_Object conditions = Fget (XCAR (data), Qerror_conditions);
+ int is_minibuffer_quit = !NILP (Fmemq (Qminibuffer_quit, conditions));
CHECK_STRING (context);
/* If the window system or terminal frame hasn't been initialized
- yet, or we're not interactive, write the message to stderr and exit. */
- if (!sf->glyphs_initialized_p
- /* The initial frame is a special non-displaying frame. It
- will be current in daemon mode when there are no frames
- to display, and in non-daemon mode before the real frame
- has finished initializing. If an error is thrown in the
- latter case while creating the frame, then the frame
- will never be displayed, so the safest thing to do is
- write to stderr and quit. In daemon mode, there are
- many other potential errors that do not prevent frames
- from being created, so continuing as normal is better in
- that case. */
- || (!IS_DAEMON && FRAME_INITIAL_P (sf))
- || noninteractive)
+ yet, or we're not interactive, write the message to stderr and exit.
+ Don't do this for the minibuffer-quit condition. */
+ if (!is_minibuffer_quit
+ && (!sf->glyphs_initialized_p
+ /* The initial frame is a special non-displaying frame. It
+ will be current in daemon mode when there are no frames
+ to display, and in non-daemon mode before the real frame
+ has finished initializing. If an error is thrown in the
+ latter case while creating the frame, then the frame
+ will never be displayed, so the safest thing to do is
+ write to stderr and quit. In daemon mode, there are
+ many other potential errors that do not prevent frames
+ from being created, so continuing as normal is better in
+ that case. */
+ || (!IS_DAEMON && FRAME_INITIAL_P (sf))
+ || noninteractive))
{
print_error_message (data, Qexternal_debugging_output,
SSDATA (context), signal);
@@ -1036,12 +1055,10 @@ Default value of `command-error-function'. */)
}
else
{
- conditions = Fget (XCAR (data), Qerror_conditions);
-
clear_message (1, 0);
message_log_maybe_newline ();
- if (!NILP (Fmemq (Qminibuffer_quit, conditions)))
+ if (is_minibuffer_quit)
{
Fding (Qt);
}
@@ -2927,20 +2944,8 @@ read_char (int commandflag, Lisp_Object map,
last_input_event = c;
call4 (Qcommand_execute, tem, Qnil, Fvector (1, &last_input_event), Qt);
- if (CONSP (c)
- && (EQ (XCAR (c), Qselect_window)
- || EQ (XCAR (c), Qfocus_out)
-#ifdef HAVE_DBUS
- || EQ (XCAR (c), Qdbus_event)
-#endif
-#ifdef USE_FILE_NOTIFY
- || EQ (XCAR (c), Qfile_notify)
-#endif
-#ifdef THREADS_ENABLED
- || EQ (XCAR (c), Qthread_event)
-#endif
- || EQ (XCAR (c), Qconfig_changed_event))
- && !end_time)
+ if (CONSP (c) && !NILP (Fmemq (XCAR (c), Vwhile_no_input_ignore_events))
+ && !end_time)
/* We stopped being idle for this event; undo that. This
prevents automatic window selection (under
mouse-autoselect-window) from acting as a real input event, for
@@ -3442,10 +3447,17 @@ readable_events (int flags)
if (flags & READABLE_EVENTS_DO_TIMERS_NOW)
timer_check ();
- /* If the buffer contains only FOCUS_IN/OUT_EVENT events, and
- READABLE_EVENTS_FILTER_EVENTS is set, report it as empty. */
+ /* READABLE_EVENTS_FILTER_EVENTS is meant to be used only by
+ input-pending-p and similar callers, which aren't interested in
+ some input events. If this flag is set, and
+ input-pending-p-filter-events is non-nil, ignore events in
+ while-no-input-ignore-events. If the flag is set and
+ input-pending-p-filter-events is nil, ignore only
+ FOCUS_IN/OUT_EVENT events. */
if (kbd_fetch_ptr != kbd_store_ptr)
{
+ /* See https://lists.gnu.org/r/emacs-devel/2005-05/msg00297.html
+ for why we treat toolkit scroll-bar events specially here. */
if (flags & (READABLE_EVENTS_FILTER_EVENTS
#ifdef USE_TOOLKIT_SCROLL_BARS
| READABLE_EVENTS_IGNORE_SQUEEZABLES
@@ -3460,8 +3472,11 @@ readable_events (int flags)
#ifdef USE_TOOLKIT_SCROLL_BARS
(flags & READABLE_EVENTS_FILTER_EVENTS) &&
#endif
- (event->kind == FOCUS_IN_EVENT
- || event->kind == FOCUS_OUT_EVENT))
+ ((!input_pending_p_filter_events
+ && (event->kind == FOCUS_IN_EVENT
+ || event->kind == FOCUS_OUT_EVENT))
+ || (input_pending_p_filter_events
+ && is_ignored_event (event))))
#ifdef USE_TOOLKIT_SCROLL_BARS
&& !((flags & READABLE_EVENTS_IGNORE_SQUEEZABLES)
&& (event->kind == SCROLL_BAR_CLICK_EVENT
@@ -3643,29 +3658,10 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event,
#endif /* subprocesses */
}
- Lisp_Object ignore_event;
-
- switch (event->kind)
- {
- case FOCUS_IN_EVENT: ignore_event = Qfocus_in; break;
- case FOCUS_OUT_EVENT: ignore_event = Qfocus_out; break;
- case HELP_EVENT: ignore_event = Qhelp_echo; break;
- case ICONIFY_EVENT: ignore_event = Qiconify_frame; break;
- case DEICONIFY_EVENT: ignore_event = Qmake_frame_visible; break;
- case SELECTION_REQUEST_EVENT: ignore_event = Qselection_request; break;
-#ifdef USE_FILE_NOTIFY
- case FILE_NOTIFY_EVENT: ignore_event = Qfile_notify; break;
-#endif
-#ifdef HAVE_DBUS
- case DBUS_EVENT: ignore_event = Qdbus_event; break;
-#endif
- default: ignore_event = Qnil; break;
- }
-
/* If we're inside while-no-input, and this event qualifies
as input, set quit-flag to cause an interrupt. */
if (!NILP (Vthrow_on_input)
- && NILP (Fmemq (ignore_event, Vwhile_no_input_ignore_events)))
+ && !is_ignored_event (event))
Vquit_flag = Vthrow_on_input;
}
@@ -3869,7 +3865,7 @@ kbd_buffer_get_event (KBOARD **kbp,
/* One way or another, wait until input is available; then, if
interrupt handlers have not read it, read it now. */
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
gobble_input ();
#endif
if (kbd_fetch_ptr != kbd_store_ptr)
@@ -3976,6 +3972,9 @@ kbd_buffer_get_event (KBOARD **kbp,
*used_mouse_menu = true;
FALLTHROUGH;
#endif
+#ifdef HAVE_PGTK
+ case PGTK_PREEDIT_TEXT_EVENT:
+#endif
#ifdef HAVE_NTGUI
case END_SESSION_EVENT:
case LANGUAGE_CHANGE_EVENT:
@@ -3997,6 +3996,7 @@ kbd_buffer_get_event (KBOARD **kbp,
#endif
#ifdef HAVE_XWIDGETS
case XWIDGET_EVENT:
+ case XWIDGET_DISPLAY_EVENT:
#endif
case SAVE_SESSION_EVENT:
case NO_EVENT:
@@ -4234,7 +4234,7 @@ decode_timer (Lisp_Object timer, struct timespec *result)
{
Lisp_Object *vec;
- if (! (VECTORP (timer) && ASIZE (timer) == 9))
+ if (! (VECTORP (timer) && ASIZE (timer) == 10))
return false;
vec = XVECTOR (timer)->contents;
if (! NILP (vec[0]))
@@ -4901,7 +4901,7 @@ static const char *const lispy_kana_keys[] =
/* You'll notice that this table is arranged to be conveniently
indexed by X Windows keysym values. */
-static const char *const lispy_function_keys[] =
+const char *const lispy_function_keys[] =
{
/* X Keysym value */
@@ -5087,13 +5087,57 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
enum window_part part;
Lisp_Object posn = Qnil;
Lisp_Object extra_info = Qnil;
+ int mx = XFIXNUM (x), my = XFIXNUM (y);
/* Coordinate pixel positions to return. */
int xret = 0, yret = 0;
/* The window or frame under frame pixel coordinates (x,y) */
Lisp_Object window_or_frame = f
- ? window_from_coordinates (f, XFIXNUM (x), XFIXNUM (y), &part, 0, 0)
+ ? window_from_coordinates (f, mx, my, &part, true, true)
: Qnil;
+ /* Report mouse events on the tab bar and (on GUI frames) on the
+ tool bar. */
+#ifdef HAVE_WINDOW_SYSTEM
+ if ((WINDOWP (f->tab_bar_window)
+ && EQ (window_or_frame, f->tab_bar_window))
+#ifndef HAVE_EXT_TOOL_BAR
+ || (WINDOWP (f->tool_bar_window)
+ && EQ (window_or_frame, f->tool_bar_window))
+#endif
+ )
+ {
+ /* While 'track-mouse' is neither nil nor t, do not report this
+ event as something that happened on the tool or tab bar since
+ that would break mouse drag operations that originate from an
+ ordinary window beneath that bar and expect the window to
+ auto-scroll as soon as the mouse cursor appears above or
+ beneath it (Bug#50993). We do allow reports for t, because
+ applications may have set 'track-mouse' to t and still expect a
+ click on the tool or tab bar to get through (Bug#51794).
+
+ FIXME: This is a preliminary fix for the bugs cited above and
+ awaits a solution that includes a convention for all special
+ values of 'track-mouse' and their documentation in the Elisp
+ manual. */
+ if (NILP (track_mouse) || EQ (track_mouse, Qt))
+ posn = EQ (window_or_frame, f->tab_bar_window) ? Qtab_bar : Qtool_bar;
+ /* Kludge alert: for mouse events on the tab bar and tool bar,
+ keyboard.c wants the frame, not the special-purpose window
+ we use to display those, and it wants frame-relative
+ coordinates. FIXME! */
+ window_or_frame = Qnil;
+ }
+#endif
+ if (f
+ && !FRAME_WINDOW_P (f)
+ && FRAME_TAB_BAR_LINES (f) > 0
+ && my >= FRAME_MENU_BAR_LINES (f)
+ && my < FRAME_MENU_BAR_LINES (f) + FRAME_TAB_BAR_LINES (f))
+ {
+ posn = Qtab_bar;
+ window_or_frame = Qnil; /* see above */
+ }
+
if (WINDOWP (window_or_frame))
{
/* It's a click in window WINDOW at frame coordinates (X,Y) */
@@ -5106,15 +5150,15 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
Lisp_Object object = Qnil;
/* Pixel coordinates relative to the window corner. */
- int wx = XFIXNUM (x) - WINDOW_LEFT_EDGE_X (w);
- int wy = XFIXNUM (y) - WINDOW_TOP_EDGE_Y (w);
+ int wx = mx - WINDOW_LEFT_EDGE_X (w);
+ int wy = my - WINDOW_TOP_EDGE_Y (w);
/* For text area clicks, return X, Y relative to the corner of
this text area. Note that dX, dY etc are set below, by
buffer_posn_from_coords. */
if (part == ON_TEXT)
{
- xret = XFIXNUM (x) - window_box_left (w, TEXT_AREA);
+ xret = mx - window_box_left (w, TEXT_AREA);
yret = wy - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
}
/* For mode line and header line clicks, return X, Y relative to
@@ -5238,7 +5282,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
: (part == ON_RIGHT_FRINGE || part == ON_RIGHT_MARGIN
|| (part == ON_VERTICAL_SCROLL_BAR
&& WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
- ? (XFIXNUM (x) - window_box_left (w, TEXT_AREA))
+ ? (mx - window_box_left (w, TEXT_AREA))
: 0;
int y2 = wy;
@@ -5290,17 +5334,17 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
make_fixnum (row)),
extra_info)));
}
-
else if (f)
{
/* Return mouse pixel coordinates here. */
XSETFRAME (window_or_frame, f);
- xret = XFIXNUM (x);
- yret = XFIXNUM (y);
+ xret = mx;
+ yret = my;
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f)
&& FRAME_LIVE_P (f)
+ && NILP (posn)
&& FRAME_INTERNAL_BORDER_WIDTH (f) > 0
&& !NILP (get_frame_param (f, Qdrag_internal_border)))
{
@@ -5649,6 +5693,11 @@ make_lispy_event (struct input_event *event)
position = make_lispy_position (f, event->x, event->y,
event->timestamp);
+
+ /* For tab-bar clicks, add the propertized string with
+ button information as OBJECT member of POSITION. */
+ if (CONSP (event->arg) && EQ (XCAR (event->arg), Qtab_bar))
+ position = nconc2 (position, Fcons (XCDR (event->arg), Qnil));
}
#ifndef USE_TOOLKIT_SCROLL_BARS
else
@@ -5935,7 +5984,11 @@ make_lispy_event (struct input_event *event)
ASIZE (wheel_syms));
}
- if (NUMBERP (event->arg))
+ if (CONSP (event->arg))
+ return list5 (head, position, make_fixnum (double_click_count),
+ XCAR (event->arg), Fcons (XCAR (XCDR (event->arg)),
+ XCAR (XCDR (XCDR (event->arg)))));
+ else if (NUMBERP (event->arg))
return list4 (head, position, make_fixnum (double_click_count),
event->arg);
else if (event->modifiers & (double_modifier | triple_modifier))
@@ -5944,6 +5997,61 @@ make_lispy_event (struct input_event *event)
return list2 (head, position);
}
+ case TOUCH_END_EVENT:
+ {
+ Lisp_Object position;
+
+ /* Build the position as appropriate for this mouse click. */
+ struct frame *f = XFRAME (event->frame_or_window);
+
+ if (! FRAME_LIVE_P (f))
+ return Qnil;
+
+ position = make_lispy_position (f, event->x, event->y,
+ event->timestamp);
+
+ return list2 (Qtouch_end, position);
+ }
+
+ case TOUCHSCREEN_BEGIN_EVENT:
+ case TOUCHSCREEN_END_EVENT:
+ {
+ Lisp_Object x, y, id, position;
+ struct frame *f = XFRAME (event->frame_or_window);
+
+ id = event->arg;
+ x = event->x;
+ y = event->y;
+
+ position = make_lispy_position (f, x, y, event->timestamp);
+
+ return list2 (((event->kind
+ == TOUCHSCREEN_BEGIN_EVENT)
+ ? Qtouchscreen_begin
+ : Qtouchscreen_end),
+ Fcons (id, position));
+ }
+
+ case TOUCHSCREEN_UPDATE_EVENT:
+ {
+ Lisp_Object x, y, id, position, tem, it, evt;
+ struct frame *f = XFRAME (event->frame_or_window);
+ evt = Qnil;
+
+ for (tem = event->arg; CONSP (tem); tem = XCDR (tem))
+ {
+ it = XCAR (tem);
+
+ x = XCAR (it);
+ y = XCAR (XCDR (it));
+ id = XCAR (XCDR (XCDR (it)));
+
+ position = make_lispy_position (f, x, y, event->timestamp);
+ evt = Fcons (Fcons (id, position), evt);
+ }
+
+ return list2 (Qtouchscreen_update, evt);
+ }
#ifdef USE_TOOLKIT_SCROLL_BARS
@@ -6078,23 +6186,20 @@ make_lispy_event (struct input_event *event)
#ifdef HAVE_DBUS
case DBUS_EVENT:
- {
- return Fcons (Qdbus_event, event->arg);
- }
+ return Fcons (Qdbus_event, event->arg);
#endif /* HAVE_DBUS */
#ifdef THREADS_ENABLED
case THREAD_EVENT:
- {
- return Fcons (Qthread_event, event->arg);
- }
+ return Fcons (Qthread_event, event->arg);
#endif /* THREADS_ENABLED */
#ifdef HAVE_XWIDGETS
case XWIDGET_EVENT:
- {
- return Fcons (Qxwidget_event, event->arg);
- }
+ return Fcons (Qxwidget_event, event->arg);
+
+ case XWIDGET_DISPLAY_EVENT:
+ return Fcons (Qxwidget_display_event, event->arg);
#endif
#ifdef USE_FILE_NOTIFY
@@ -6111,6 +6216,11 @@ make_lispy_event (struct input_event *event)
return list3 (Qconfig_changed_event,
event->arg, event->frame_or_window);
+#ifdef HAVE_PGTK
+ case PGTK_PREEDIT_TEXT_EVENT:
+ return list2 (intern ("pgtk-preedit-text"), event->arg);
+#endif
+
/* The 'kind' field of the event is something we don't recognize. */
default:
emacs_abort ();
@@ -7138,7 +7248,7 @@ tty_read_avail_input (struct terminal *terminal,
static void
handle_async_input (void)
{
-#ifdef USABLE_SIGIO
+#ifndef DOS_NT
while (1)
{
int nread = gobble_input ();
@@ -7201,7 +7311,7 @@ totally_unblock_input (void)
unblock_input_to (0);
}
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
void
handle_input_available_signal (int sig)
@@ -7217,7 +7327,7 @@ deliver_input_available_signal (int sig)
{
deliver_process_signal (sig, handle_input_available_signal);
}
-#endif /* USABLE_SIGIO */
+#endif /* defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL) */
/* User signal events. */
@@ -7287,7 +7397,7 @@ handle_user_signal (int sig)
}
p->npending++;
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
if (interrupt_input)
handle_input_available_signal (sig);
else
@@ -7790,7 +7900,9 @@ parse_menu_item (Lisp_Object item, int inmenubar)
else if (EQ (tem, QCkeys))
{
tem = XCAR (item);
- if (CONSP (tem) || STRINGP (tem))
+ if (FUNCTIONP (tem))
+ ASET (item_properties, ITEM_PROPERTY_KEYEQ, call0 (tem));
+ else if (CONSP (tem) || STRINGP (tem))
ASET (item_properties, ITEM_PROPERTY_KEYEQ, tem);
}
else if (EQ (tem, QCbutton) && CONSP (XCAR (item)))
@@ -9187,8 +9299,7 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt,
/* If the function returned something invalid,
barf--don't ignore it. */
if (! (NILP (next) || VECTORP (next) || STRINGP (next)))
- error ("Function %s returns invalid key sequence",
- SSDATA (SYMBOL_NAME (tem)));
+ signal_error ("Function returns invalid key sequence", tem);
}
return next;
}
@@ -10119,7 +10230,8 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt,
use the corresponding lower-case letter instead. */
if (NILP (current_binding)
&& /* indec.start >= t && fkey.start >= t && */ keytran.start >= t
- && FIXNUMP (key))
+ && FIXNUMP (key)
+ && translate_upper_case_key_bindings)
{
Lisp_Object new_key;
EMACS_INT k = XFIXNUM (key);
@@ -10171,12 +10283,14 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt,
int modifiers
= CONSP (breakdown) ? (XFIXNUM (XCAR (XCDR (breakdown)))) : 0;
- if (modifiers & shift_modifier
- /* Treat uppercase keys as shifted. */
- || (FIXNUMP (key)
- && (KEY_TO_CHAR (key)
- < XCHAR_TABLE (BVAR (current_buffer, downcase_table))->header.size)
- && uppercasep (KEY_TO_CHAR (key))))
+ if (translate_upper_case_key_bindings
+ && (modifiers & shift_modifier
+ /* Treat uppercase keys as shifted. */
+ || (FIXNUMP (key)
+ && (KEY_TO_CHAR (key)
+ < XCHAR_TABLE (BVAR (current_buffer,
+ downcase_table))->header.size)
+ && uppercasep (KEY_TO_CHAR (key)))))
{
Lisp_Object new_key
= (modifiers & shift_modifier
@@ -11053,7 +11167,7 @@ See also `current-input-mode'. */)
(Lisp_Object interrupt)
{
bool new_interrupt_input;
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
#ifdef HAVE_X_WINDOWS
if (x_display_list != NULL)
{
@@ -11064,9 +11178,9 @@ See also `current-input-mode'. */)
else
#endif /* HAVE_X_WINDOWS */
new_interrupt_input = !NILP (interrupt);
-#else /* not USABLE_SIGIO */
+#else /* not USABLE_SIGIO || USABLE_SIGPOLL */
new_interrupt_input = false;
-#endif /* not USABLE_SIGIO */
+#endif /* not USABLE_SIGIO || USABLE_SIGPOLL */
if (new_interrupt_input != interrupt_input)
{
@@ -11283,6 +11397,8 @@ The elements of this list correspond to the arguments of
DEFUN ("posn-at-x-y", Fposn_at_x_y, Sposn_at_x_y, 2, 4, 0,
doc: /* Return position information for pixel coordinates X and Y.
By default, X and Y are relative to text area of the selected window.
+Note that the text area includes the header-line and the tab-line of
+the window, if any of them are present.
Optional third arg FRAME-OR-WINDOW non-nil specifies frame or window.
If optional fourth arg WHOLE is non-nil, X is relative to the left
edge of the window.
@@ -11493,12 +11609,16 @@ init_keyboard (void)
sigaction (SIGQUIT, &action, 0);
#endif /* not DOS_NT */
}
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
if (!noninteractive)
{
struct sigaction action;
emacs_sigaction_init (&action, deliver_input_available_signal);
+#ifdef USABLE_SIGIO
sigaction (SIGIO, &action, 0);
+#else
+ sigaction (SIGPOLL, &action, 0);
+#endif
}
#endif
@@ -11550,6 +11670,52 @@ static const struct event_head head_table[] = {
{SYMBOL_INDEX (Qselect_window), SYMBOL_INDEX (Qswitch_frame)}
};
+static Lisp_Object
+init_while_no_input_ignore_events (void)
+{
+ Lisp_Object events = listn (9, Qselect_window, Qhelp_echo, Qmove_frame,
+ Qiconify_frame, Qmake_frame_visible,
+ Qfocus_in, Qfocus_out, Qconfig_changed_event,
+ Qselection_request);
+
+#ifdef HAVE_DBUS
+ events = Fcons (Qdbus_event, events);
+#endif
+#ifdef USE_FILE_NOTIFY
+ events = Fcons (Qfile_notify, events);
+#endif
+#ifdef THREADS_ENABLED
+ events = Fcons (Qthread_event, events);
+#endif
+
+ return events;
+}
+
+static bool
+is_ignored_event (union buffered_input_event *event)
+{
+ Lisp_Object ignore_event;
+
+ switch (event->kind)
+ {
+ case FOCUS_IN_EVENT: ignore_event = Qfocus_in; break;
+ case FOCUS_OUT_EVENT: ignore_event = Qfocus_out; break;
+ case HELP_EVENT: ignore_event = Qhelp_echo; break;
+ case ICONIFY_EVENT: ignore_event = Qiconify_frame; break;
+ case DEICONIFY_EVENT: ignore_event = Qmake_frame_visible; break;
+ case SELECTION_REQUEST_EVENT: ignore_event = Qselection_request; break;
+#ifdef USE_FILE_NOTIFY
+ case FILE_NOTIFY_EVENT: ignore_event = Qfile_notify; break;
+#endif
+#ifdef HAVE_DBUS
+ case DBUS_EVENT: ignore_event = Qdbus_event; break;
+#endif
+ default: ignore_event = Qnil; break;
+ }
+
+ return !NILP (Fmemq (ignore_event, Vwhile_no_input_ignore_events));
+}
+
static void syms_of_keyboard_for_pdumper (void);
void
@@ -11636,12 +11802,15 @@ syms_of_keyboard (void)
#ifdef HAVE_XWIDGETS
DEFSYM (Qxwidget_event, "xwidget-event");
+ DEFSYM (Qxwidget_display_event, "xwidget-display-event");
#endif
#ifdef USE_FILE_NOTIFY
DEFSYM (Qfile_notify, "file-notify");
#endif /* USE_FILE_NOTIFY */
+ DEFSYM (Qtouch_end, "touch-end");
+
/* Menu and tool bar item parts. */
DEFSYM (QCenable, ":enable");
DEFSYM (QCvisible, ":visible");
@@ -12137,6 +12306,9 @@ See also `pre-command-hook'. */);
doc: /* Normal hook run when clearing the echo area. */);
#endif
DEFSYM (Qecho_area_clear_hook, "echo-area-clear-hook");
+ DEFSYM (Qtouchscreen_begin, "touchscreen-begin");
+ DEFSYM (Qtouchscreen_end, "touchscreen-end");
+ DEFSYM (Qtouchscreen_update, "touchscreen-update");
Fset (Qecho_area_clear_hook, Qnil);
DEFVAR_LISP ("lucid-menu-bar-dirty-flag", Vlucid_menu_bar_dirty_flag,
@@ -12444,7 +12616,35 @@ If nil, Emacs crashes immediately in response to fatal signals. */);
DEFVAR_LISP ("while-no-input-ignore-events",
Vwhile_no_input_ignore_events,
- doc: /* Ignored events from while-no-input. */);
+ doc: /* Ignored events from `while-no-input'.
+Events in this list do not count as pending input while running
+`while-no-input' and do not cause any idle timers to get reset when they
+occur. */);
+ Vwhile_no_input_ignore_events = init_while_no_input_ignore_events ();
+
+ DEFVAR_BOOL ("translate-upper-case-key-bindings",
+ translate_upper_case_key_bindings,
+ doc: /* If non-nil, interpret upper case keys as lower case (when applicable).
+Emacs allows binding both upper and lower case key sequences to
+commands. However, if there is a lower case key sequence bound to a
+command, and the user enters an upper case key sequence that is not
+bound to a command, Emacs will use the lower case binding. Setting
+this variable to nil inhibits this behaviour. */);
+ translate_upper_case_key_bindings = true;
+
+ DEFVAR_BOOL ("input-pending-p-filter-events",
+ input_pending_p_filter_events,
+ doc: /* If non-nil, `input-pending-p' ignores some input events.
+If this variable is non-nil (the default), `input-pending-p' and
+other similar functions ignore input events in `while-no-input-ignore-events'.
+This flag may eventually be removed once this behavior is deemed safe. */);
+ input_pending_p_filter_events = true;
+
+ DEFVAR_BOOL ("mwheel-coalesce-scroll-events", mwheel_coalesce_scroll_events,
+ doc: /* Non-nil means send a wheel event only for scrolling at least one screen line.
+Otherwise, a wheel event will be sent every time the mouse wheel is
+moved. */);
+ mwheel_coalesce_scroll_events = true;
pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper);
}
@@ -12494,6 +12694,8 @@ keys_of_keyboard (void)
"ns-put-working-text");
initial_define_lispy_key (Vspecial_event_map, "ns-unput-working-text",
"ns-unput-working-text");
+ initial_define_lispy_key (Vspecial_event_map, "pgtk-preedit-text",
+ "pgtk-preedit-text");
/* Here we used to use `ignore-event' which would simple set prefix-arg to
current-prefix-arg, as is done in `handle-switch-frame'.
But `handle-switch-frame is not run from the special-map.
diff --git a/src/keyboard.h b/src/keyboard.h
index 8bdffaa2bff..21c51ec3862 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -491,7 +491,7 @@ extern void process_pending_signals (void);
extern struct timespec timer_check (void);
extern void mark_kboards (void);
-#ifdef HAVE_NTGUI
+#if defined HAVE_NTGUI || defined HAVE_X_WINDOWS
extern const char *const lispy_function_keys[];
#endif
diff --git a/src/keymap.c b/src/keymap.c
index fb8eceaec18..0b882958b94 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -65,12 +65,16 @@ static Lisp_Object exclude_keys;
/* Pre-allocated 2-element vector for Fcommand_remapping to use. */
static Lisp_Object command_remapping_vector;
+/* Char table for the backwards-compatibility part in Flookup_key. */
+static Lisp_Object unicode_case_table;
+
/* Hash table used to cache a reverse-map to speed up calls to where-is. */
static Lisp_Object where_is_cache;
/* Which keymaps are reverse-stored in the cache. */
static Lisp_Object where_is_cache_keymaps;
-static Lisp_Object store_in_keymap (Lisp_Object, Lisp_Object, Lisp_Object);
+static Lisp_Object store_in_keymap (Lisp_Object, Lisp_Object, Lisp_Object,
+ bool);
static Lisp_Object define_as_prefix (Lisp_Object, Lisp_Object);
static void describe_vector (Lisp_Object, Lisp_Object, Lisp_Object,
@@ -127,7 +131,8 @@ in case you use it as a menu with `x-popup-menu'. */)
void
initial_define_lispy_key (Lisp_Object keymap, const char *keyname, const char *defname)
{
- store_in_keymap (keymap, intern_c_string (keyname), intern_c_string (defname));
+ store_in_keymap (keymap, intern_c_string (keyname),
+ intern_c_string (defname), false);
}
DEFUN ("keymapp", Fkeymapp, Skeymapp, 1, 1, 0,
@@ -629,6 +634,9 @@ the definition it is bound to. The event may be a character range.
If KEYMAP has a parent, the parent's bindings are included as well.
This works recursively: if the parent has itself a parent, then the
grandparent's bindings are also included and so on.
+
+For more information, see Info node `(elisp) Keymaps'.
+
usage: (map-keymap FUNCTION KEYMAP) */)
(Lisp_Object function, Lisp_Object keymap, Lisp_Object sort_first)
{
@@ -723,7 +731,8 @@ get_keyelt (Lisp_Object object, bool autoload)
}
static Lisp_Object
-store_in_keymap (Lisp_Object keymap, register Lisp_Object idx, Lisp_Object def)
+store_in_keymap (Lisp_Object keymap, register Lisp_Object idx,
+ Lisp_Object def, bool remove)
{
/* Flush any reverse-map cache. */
where_is_cache = Qnil;
@@ -799,21 +808,26 @@ store_in_keymap (Lisp_Object keymap, register Lisp_Object idx, Lisp_Object def)
}
else if (CHAR_TABLE_P (elt))
{
+ Lisp_Object sdef = def;
+ if (remove)
+ sdef = Qnil;
+ /* nil has a special meaning for char-tables, so
+ we use something else to record an explicitly
+ unbound entry. */
+ else if (NILP (sdef))
+ sdef = Qt;
+
/* Character codes with modifiers
are not included in a char-table.
All character codes without modifiers are included. */
if (FIXNATP (idx) && !(XFIXNAT (idx) & CHAR_MODIFIER_MASK))
{
- Faset (elt, idx,
- /* nil has a special meaning for char-tables, so
- we use something else to record an explicitly
- unbound entry. */
- NILP (def) ? Qt : def);
+ Faset (elt, idx, sdef);
return def;
}
else if (CONSP (idx) && CHARACTERP (XCAR (idx)))
{
- Fset_char_table_range (elt, idx, NILP (def) ? Qt : def);
+ Fset_char_table_range (elt, idx, sdef);
return def;
}
insertion_point = tail;
@@ -832,7 +846,12 @@ store_in_keymap (Lisp_Object keymap, register Lisp_Object idx, Lisp_Object def)
else if (EQ (idx, XCAR (elt)))
{
CHECK_IMPURE (elt, XCONS (elt));
- XSETCDR (elt, def);
+ if (remove)
+ /* Remove the element. */
+ insertion_point = Fdelq (elt, insertion_point);
+ else
+ /* Just set the definition. */
+ XSETCDR (elt, def);
return def;
}
else if (CONSP (idx)
@@ -845,7 +864,10 @@ store_in_keymap (Lisp_Object keymap, register Lisp_Object idx, Lisp_Object def)
if (from <= XFIXNAT (XCAR (elt))
&& to >= XFIXNAT (XCAR (elt)))
{
- XSETCDR (elt, def);
+ if (remove)
+ insertion_point = Fdelq (elt, insertion_point);
+ else
+ XSETCDR (elt, def);
if (from == to)
return def;
}
@@ -1024,10 +1046,35 @@ is not copied. */)
/* Simple Keymap mutators and accessors. */
+static Lisp_Object
+possibly_translate_key_sequence (Lisp_Object key, ptrdiff_t *length)
+{
+ if (VECTORP (key) && ASIZE (key) == 1 && STRINGP (AREF (key, 0)))
+ {
+ /* KEY is on the ["C-c"] format, so translate to internal
+ format. */
+ if (NILP (Ffboundp (Qkey_valid_p)))
+ xsignal2 (Qerror,
+ build_string ("`key-valid-p' is not defined, so this syntax can't be used: %s"),
+ key);
+ if (NILP (call1 (Qkey_valid_p, AREF (key, 0))))
+ xsignal2 (Qerror, build_string ("Invalid `key-parse' syntax: %S"), key);
+ key = call1 (Qkey_parse, AREF (key, 0));
+ *length = CHECK_VECTOR_OR_STRING (key);
+ if (*length == 0)
+ xsignal2 (Qerror, build_string ("Invalid `key-parse' syntax: %S"), key);
+ }
+
+ return key;
+}
+
/* GC is possible in this function if it autoloads a keymap. */
-DEFUN ("define-key", Fdefine_key, Sdefine_key, 3, 3, 0,
+DEFUN ("define-key", Fdefine_key, Sdefine_key, 3, 4, 0,
doc: /* In KEYMAP, define key sequence KEY as DEF.
+This is a legacy function; see `keymap-set' for the recommended
+function to use instead.
+
KEYMAP is a keymap.
KEY is a string or a vector of symbols and characters, representing a
@@ -1047,15 +1094,23 @@ DEF is anything that can be a key's definition:
function definition, which should at that time be one of the above,
or another symbol whose function definition is used, etc.),
a cons (STRING . DEFN), meaning that DEFN is the definition
- (DEFN should be a valid definition in its own right),
+ (DEFN should be a valid definition in its own right) and
+ STRING is the menu item name (which is used only if the containing
+ keymap has been created with a menu name, see `make-keymap'),
or a cons (MAP . CHAR), meaning use definition of CHAR in keymap MAP,
or an extended menu item definition.
(See info node `(elisp)Extended Menu Items'.)
+If REMOVE is non-nil, the definition will be removed. This is almost
+the same as setting the definition to nil, but makes a difference if
+the KEYMAP has a parent, and KEY is shadowing the same binding in the
+parent. With REMOVE, subsequent lookups will return the binding in
+the parent, and with a nil DEF, the lookups will return nil.
+
If KEYMAP is a sparse keymap with a binding for KEY, the existing
binding is altered. If there is no binding for KEY, the new pair
binding KEY to DEF is added at the front of KEYMAP. */)
- (Lisp_Object keymap, Lisp_Object key, Lisp_Object def)
+ (Lisp_Object keymap, Lisp_Object key, Lisp_Object def, Lisp_Object remove)
{
bool metized = false;
@@ -1082,6 +1137,8 @@ binding KEY to DEF is added at the front of KEYMAP. */)
def = tmp;
}
+ key = possibly_translate_key_sequence (key, &length);
+
ptrdiff_t idx = 0;
while (1)
{
@@ -1123,7 +1180,7 @@ binding KEY to DEF is added at the front of KEYMAP. */)
message_with_string ("Key sequence contains invalid event %s", c, 1);
if (idx == length)
- return store_in_keymap (keymap, c, def);
+ return store_in_keymap (keymap, c, def, !NILP (remove));
Lisp_Object cmd = access_keymap (keymap, c, 0, 1, 1);
@@ -1180,27 +1237,8 @@ remapping in all currently active keymaps. */)
return FIXNUMP (command) ? Qnil : command;
}
-/* Value is number if KEY is too long; nil if valid but has no definition. */
-/* GC is possible in this function. */
-
-DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 3, 0,
- doc: /* Look up key sequence KEY in KEYMAP. Return the definition.
-A value of nil means undefined. See doc of `define-key'
-for kinds of definitions.
-
-A number as value means KEY is "too long";
-that is, characters or symbols in it except for the last one
-fail to be a valid sequence of prefix characters in KEYMAP.
-The number is how many characters at the front of KEY
-it takes to reach a non-prefix key.
-KEYMAP can also be a list of keymaps.
-
-Normally, `lookup-key' ignores bindings for t, which act as default
-bindings, used when nothing else in the keymap applies; this makes it
-usable as a general function for probing keymaps. However, if the
-third optional argument ACCEPT-DEFAULT is non-nil, `lookup-key' will
-recognize the default bindings, just as `read-key-sequence' does. */)
- (Lisp_Object keymap, Lisp_Object key, Lisp_Object accept_default)
+static Lisp_Object
+lookup_key_1 (Lisp_Object keymap, Lisp_Object key, Lisp_Object accept_default)
{
bool t_ok = !NILP (accept_default);
@@ -1211,6 +1249,8 @@ recognize the default bindings, just as `read-key-sequence' does. */)
if (length == 0)
return keymap;
+ key = possibly_translate_key_sequence (key, &length);
+
ptrdiff_t idx = 0;
while (1)
{
@@ -1240,6 +1280,159 @@ recognize the default bindings, just as `read-key-sequence' does. */)
}
}
+/* Value is number if KEY is too long; nil if valid but has no definition. */
+/* GC is possible in this function. */
+
+DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 3, 0,
+ doc: /* Look up key sequence KEY in KEYMAP. Return the definition.
+This is a legacy function; see `keymap-lookup' for the recommended
+function to use instead.
+
+A value of nil means undefined. See doc of `define-key'
+for kinds of definitions.
+
+A number as value means KEY is "too long";
+that is, characters or symbols in it except for the last one
+fail to be a valid sequence of prefix characters in KEYMAP.
+The number is how many characters at the front of KEY
+it takes to reach a non-prefix key.
+KEYMAP can also be a list of keymaps.
+
+Normally, `lookup-key' ignores bindings for t, which act as default
+bindings, used when nothing else in the keymap applies; this makes it
+usable as a general function for probing keymaps. However, if the
+third optional argument ACCEPT-DEFAULT is non-nil, `lookup-key' will
+recognize the default bindings, just as `read-key-sequence' does. */)
+ (Lisp_Object keymap, Lisp_Object key, Lisp_Object accept_default)
+{
+ Lisp_Object found = lookup_key_1 (keymap, key, accept_default);
+ if (!NILP (found) && !NUMBERP (found))
+ return found;
+
+ /* Menu definitions might use mixed case symbols (notably in old
+ versions of `easy-menu-define'), or use " " instead of "-".
+ The rest of this function is about accepting these variations for
+ backwards-compatibility. (Bug#50752) */
+
+ /* Just skip everything below unless this is a menu item. */
+ if (!VECTORP (key) || !(ASIZE (key) > 0)
+ || !EQ (AREF (key, 0), Qmenu_bar))
+ return found;
+
+ /* Initialize the unicode case table, if it wasn't already. */
+ if (NILP (unicode_case_table))
+ {
+ unicode_case_table = uniprop_table (intern ("lowercase"));
+ /* uni-lowercase.el might be unavailable during bootstrap. */
+ if (NILP (unicode_case_table))
+ return found;
+ staticpro (&unicode_case_table);
+ }
+
+ ptrdiff_t key_len = ASIZE (key);
+ Lisp_Object new_key = make_vector (key_len, Qnil);
+
+ /* Try both the Unicode case table, and the buffer local one.
+ Otherwise, we will fail for e.g. the "Turkish" language
+ environment where 'I' does not downcase to 'i'. */
+ Lisp_Object tables[2] = {unicode_case_table, Fcurrent_case_table ()};
+ for (int tbl_num = 0; tbl_num < 2; tbl_num++)
+ {
+ /* First, let's try converting all symbols like "Foo-Bar-Baz" to
+ "foo-bar-baz". */
+ for (int i = 0; i < key_len; i++)
+ {
+ Lisp_Object item = AREF (key, i);
+ if (!SYMBOLP (item))
+ ASET (new_key, i, item);
+ else
+ {
+ Lisp_Object key_item = Fsymbol_name (item);
+ Lisp_Object new_item;
+ if (!STRING_MULTIBYTE (key_item))
+ new_item = Fdowncase (key_item);
+ else
+ {
+ USE_SAFE_ALLOCA;
+ ptrdiff_t size = SCHARS (key_item), n;
+ if (INT_MULTIPLY_WRAPV (size, MAX_MULTIBYTE_LENGTH, &n))
+ n = PTRDIFF_MAX;
+ unsigned char *dst = SAFE_ALLOCA (n);
+ unsigned char *p = dst;
+ ptrdiff_t j_char = 0, j_byte = 0;
+
+ while (j_char < size)
+ {
+ int ch = fetch_string_char_advance (key_item,
+ &j_char, &j_byte);
+ Lisp_Object ch_conv = CHAR_TABLE_REF (tables[tbl_num],
+ ch);
+ if (!NILP (ch_conv))
+ CHAR_STRING (XFIXNUM (ch_conv), p);
+ else
+ CHAR_STRING (ch, p);
+ p = dst + j_byte;
+ }
+ new_item = make_multibyte_string ((char *) dst,
+ SCHARS (key_item),
+ SBYTES (key_item));
+ SAFE_FREE ();
+ }
+ ASET (new_key, i, Fintern (new_item, Qnil));
+ }
+ }
+
+ /* Check for match. */
+ found = lookup_key_1 (keymap, new_key, accept_default);
+ if (!NILP (found) && !NUMBERP (found))
+ break;
+
+ /* If we still don't have a match, let's convert any spaces in
+ our lowercased string into dashes, e.g. "foo bar baz" to
+ "foo-bar-baz". */
+ for (int i = 0; i < key_len; i++)
+ {
+ if (!SYMBOLP (AREF (new_key, i)))
+ continue;
+
+ Lisp_Object lc_key = Fsymbol_name (AREF (new_key, i));
+
+ /* If there are no spaces in this symbol, just skip it. */
+ if (!strstr (SSDATA (lc_key), " "))
+ continue;
+
+ USE_SAFE_ALLOCA;
+ ptrdiff_t size = SCHARS (lc_key), n;
+ if (INT_MULTIPLY_WRAPV (size, MAX_MULTIBYTE_LENGTH, &n))
+ n = PTRDIFF_MAX;
+ unsigned char *dst = SAFE_ALLOCA (n);
+
+ /* We can walk the string data byte by byte, because UTF-8
+ encoding ensures that no other byte of any multibyte
+ sequence will ever include a 7-bit byte equal to an ASCII
+ single-byte character. */
+ memcpy (dst, SSDATA (lc_key), SBYTES (lc_key));
+ for (int i = 0; i < SBYTES (lc_key); ++i)
+ {
+ if (dst[i] == ' ')
+ dst[i] = '-';
+ }
+ Lisp_Object new_it =
+ make_multibyte_string ((char *) dst,
+ SCHARS (lc_key), SBYTES (lc_key));
+ ASET (new_key, i, Fintern (new_it, Qnil));
+ SAFE_FREE ();
+ }
+
+ /* Check for match. */
+ found = lookup_key_1 (keymap, new_key, accept_default);
+ if (!NILP (found) && !NUMBERP (found))
+ break;
+ }
+
+ return found;
+}
+
/* Make KEYMAP define event C as a keymap (i.e., as a prefix).
Assume that currently it does not define C at all.
Return the keymap. */
@@ -1248,7 +1441,7 @@ static Lisp_Object
define_as_prefix (Lisp_Object keymap, Lisp_Object c)
{
Lisp_Object cmd = Fmake_sparse_keymap (Qnil);
- store_in_keymap (keymap, c, cmd);
+ store_in_keymap (keymap, c, cmd, false);
return cmd;
}
@@ -2768,7 +2961,10 @@ You type Translation\n\
{
if (EQ (start1, BVAR (XBUFFER (buffer), keymap)))
{
- Lisp_Object msg = build_unibyte_string ("\f\nMajor Mode Bindings");
+ Lisp_Object msg =
+ CALLN (Fformat,
+ build_unibyte_string ("\f\n`%s' Major Mode Bindings"),
+ XBUFFER (buffer)->major_mode_);
CALLN (Ffuncall,
Qdescribe_map_tree,
start1, Qt, shadow, prefix,
@@ -2935,7 +3131,7 @@ describe_vector (Lisp_Object vector, Lisp_Object prefix, Lisp_Object args,
Lisp_Object suppress = Qnil;
bool first = true;
/* Range of elements to be handled. */
- int from, to, stop;
+ int to, stop;
if (!keymap_p)
{
@@ -2955,17 +3151,19 @@ describe_vector (Lisp_Object vector, Lisp_Object prefix, Lisp_Object args,
if (partial)
suppress = intern ("suppress-keymap");
- from = 0;
+ /* STOP is a boundary between normal characters (-#x3FFF7F) and
+ 8-bit characters (#x3FFF80-), used below when VECTOR is a
+ char-table. */
if (CHAR_TABLE_P (vector))
stop = MAX_5_BYTE_CHAR + 1, to = MAX_CHAR + 1;
else
stop = to = ASIZE (vector);
- for (int i = from; ; i++)
+ for (int i = 0; ; i++)
{
bool this_shadowed = false;
Lisp_Object shadowed_by = Qnil;
- int range_beg, range_end;
+ int range_beg;
Lisp_Object val, tem2;
maybe_quit ();
@@ -2981,6 +3179,10 @@ describe_vector (Lisp_Object vector, Lisp_Object prefix, Lisp_Object args,
if (CHAR_TABLE_P (vector))
{
+ /* Find the value in VECTOR for the first character in the
+ range [RANGE_BEG..STOP), and update the range to include
+ only the characters whose value is the same as that of
+ the first in the range. */
range_beg = i;
i = stop - 1;
val = char_table_ref_and_range (vector, range_beg, &range_beg, &i);
@@ -3039,33 +3241,26 @@ describe_vector (Lisp_Object vector, Lisp_Object prefix, Lisp_Object args,
insert1 (describe_key_maybe_fontify (kludge, prefix, keymap_p));
/* Find all consecutive characters or rows that have the same
- definition. But, if VECTOR is a char-table, we had better
- put a boundary between normal characters (-#x3FFF7F) and
- 8-bit characters (#x3FFF80-). */
- if (CHAR_TABLE_P (vector))
+ definition. */
+ if (!CHAR_TABLE_P (vector))
{
while (i + 1 < stop
- && (range_beg = i + 1, range_end = stop - 1,
- val = char_table_ref_and_range (vector, range_beg,
- &range_beg, &range_end),
- tem2 = get_keyelt (val, 0),
- !NILP (tem2))
+ && (tem2 = get_keyelt (AREF (vector, i + 1), 0),
+ !NILP (tem2))
&& !NILP (Fequal (tem2, definition)))
- i = range_end;
+ i++;
}
- else
- while (i + 1 < stop
- && (tem2 = get_keyelt (AREF (vector, i + 1), 0),
- !NILP (tem2))
- && !NILP (Fequal (tem2, definition)))
- i++;
/* Make sure found consecutive keys are either not shadowed or,
if they are, that they are shadowed by the same command. */
- if (CHAR_TABLE_P (vector) && i != starting_i)
+ if (!NILP (Vdescribe_bindings_check_shadowing_in_ranges)
+ && CHAR_TABLE_P (vector) && i != starting_i
+ && (!EQ (Vdescribe_bindings_check_shadowing_in_ranges,
+ Qignore_self_insert)
+ || !EQ (definition, Qself_insert_command)))
{
Lisp_Object key = make_nil_vector (1);
- for (int j = starting_i + 1; j <= i; j++)
+ for (int j = range_beg + 1; j <= i; j++)
{
ASET (key, 0, make_fixnum (j));
Lisp_Object tem = shadow_lookup (shadow, key, Qt, 0);
@@ -3181,6 +3376,24 @@ be preferred. */);
Vwhere_is_preferred_modifier = Qnil;
where_is_preferred_modifier = 0;
+ DEFVAR_LISP ("describe-bindings-check-shadowing-in-ranges",
+ Vdescribe_bindings_check_shadowing_in_ranges,
+ doc: /* If non-nil, consider command shadowing when describing ranges of keys.
+If the value is t, describing bindings of consecutive keys will not
+report them as a single range if they are shadowed by different
+minor-mode commands.
+If the value is `ignore-self-insert', assume that consecutive keys
+bound to `self-insert-command' are not all shadowed; this speeds up
+commands such as \\[describe-bindings] and \\[describe-mode], but could miss some shadowing.
+Any other non-nil value is treated is t.
+
+Beware: setting this non-nil could potentially slow down commands
+that describe key bindings. That is why the default is nil. */);
+ Vdescribe_bindings_check_shadowing_in_ranges = Qnil;
+
+ DEFSYM (Qself_insert_command, "self-insert-command");
+ DEFSYM (Qignore_self_insert, "ignore-self-insert");
+
DEFSYM (Qmenu_bar, "menu-bar");
DEFSYM (Qmode_line, "mode-line");
@@ -3244,4 +3457,7 @@ be preferred. */);
defsubr (&Stext_char_description);
defsubr (&Swhere_is_internal);
defsubr (&Sdescribe_buffer_bindings);
+
+ DEFSYM (Qkey_parse, "key-parse");
+ DEFSYM (Qkey_valid_p, "key-valid-p");
}
diff --git a/src/lisp.h b/src/lisp.h
index 7bfc69b647b..92ab05b4228 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -138,7 +138,12 @@ verify (BITS_WORD_MAX >> (BITS_PER_BITS_WORD - 1) == 1);
buffers and strings. Emacs never allocates objects larger than
PTRDIFF_MAX bytes, as they cause problems with pointer subtraction.
In C99, pD can always be "t"; configure it here for the sake of
- pre-C99 libraries such as glibc 2.0 and Solaris 8. */
+ pre-C99 libraries such as glibc 2.0 and Solaris 8.
+
+ On Haiku, the size of ptrdiff_t is inconsistent with the value of
+ PTRDIFF_MAX. In that case, "t" should be sufficient. */
+
+#ifndef HAIKU
#if PTRDIFF_MAX == INT_MAX
# define pD ""
#elif PTRDIFF_MAX == LONG_MAX
@@ -148,6 +153,9 @@ verify (BITS_WORD_MAX >> (BITS_PER_BITS_WORD - 1) == 1);
#else
# define pD "t"
#endif
+#else
+# define pD "t"
+#endif
/* Convenience macro for rarely-used functions that do not return. */
#define AVOID _Noreturn ATTRIBUTE_COLD void
@@ -251,6 +259,11 @@ DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK)
# define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX)
DEFINE_GDB_SYMBOL_END (VALMASK)
+/* Ignore 'alignas' on compilers lacking it. */
+#if !defined alignas && !defined __alignas_is_defined
+# define alignas(a)
+#endif
+
/* Minimum alignment requirement for Lisp objects, imposed by the
internal representation of tagged pointers. It is 2**GCTYPEBITS if
USE_LSB_TAG, 1 otherwise. It must be a literal integer constant,
@@ -1070,6 +1083,7 @@ enum pvec_type
PVEC_CONDVAR,
PVEC_MODULE_FUNCTION,
PVEC_NATIVE_COMP_UNIT,
+ PVEC_SQLITE,
/* These should be last, for internal_equal and sxhash_obj. */
PVEC_COMPILED,
@@ -1555,6 +1569,14 @@ STRING_MULTIBYTE (Lisp_Object str)
/* Convenience functions for dealing with Lisp strings. */
+/* WARNING: Use the 'char *' pointers to string data with care in code
+ that could GC: GC can relocate string data, invalidating such
+ pointers. It is best to use string character or byte index
+ instead, delaying the access through SDATA/SSDATA pointers to the
+ latest possible moment. If you must use the 'char *' pointers
+ (e.g., for speed), be sure to adjust them after any call that could
+ potentially GC. */
+
INLINE unsigned char *
SDATA (Lisp_Object string)
{
@@ -1615,6 +1637,13 @@ STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize)
XSTRING (string)->u.s.size = newsize;
}
+INLINE void
+CHECK_STRING_NULL_BYTES (Lisp_Object string)
+{
+ CHECK_TYPE (memchr (SSDATA (string), '\0', SBYTES (string)) == NULL,
+ Qfilenamep, string);
+}
+
/* A regular vector is just a header plus an array of Lisp_Objects. */
struct Lisp_Vector
@@ -2068,10 +2097,12 @@ struct Lisp_Subr
Lisp_Object native_intspec;
};
EMACS_INT doc;
- Lisp_Object native_comp_u[NATIVE_COMP_FLAG];
- char *native_c_name[NATIVE_COMP_FLAG];
- Lisp_Object lambda_list[NATIVE_COMP_FLAG];
- Lisp_Object type[NATIVE_COMP_FLAG];
+#ifdef HAVE_NATIVE_COMP
+ Lisp_Object native_comp_u;
+ char *native_c_name;
+ Lisp_Object lambda_list;
+ Lisp_Object type;
+#endif
} GCALIGNED_STRUCT;
union Aligned_Lisp_Subr
{
@@ -2540,6 +2571,17 @@ xmint_pointer (Lisp_Object a)
return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Misc_Ptr)->pointer;
}
+struct Lisp_Sqlite
+{
+ union vectorlike_header header;
+ void *db;
+ void *stmt;
+ char *name;
+ void (*finalizer) (void *);
+ bool eof;
+ bool is_statement;
+} GCALIGNED_STRUCT;
+
struct Lisp_User_Ptr
{
union vectorlike_header header;
@@ -2618,6 +2660,31 @@ XUSER_PTR (Lisp_Object a)
}
INLINE bool
+SQLITEP (Lisp_Object x)
+{
+ return PSEUDOVECTORP (x, PVEC_SQLITE);
+}
+
+INLINE bool
+SQLITE (Lisp_Object a)
+{
+ return PSEUDOVECTORP (a, PVEC_SQLITE);
+}
+
+INLINE void
+CHECK_SQLITE (Lisp_Object x)
+{
+ CHECK_TYPE (SQLITE (x), Qsqlitep, x);
+}
+
+INLINE struct Lisp_Sqlite *
+XSQLITE (Lisp_Object a)
+{
+ eassert (SQLITEP (a));
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Sqlite);
+}
+
+INLINE bool
BIGNUMP (Lisp_Object x)
{
return PSEUDOVECTORP (x, PVEC_BIGNUM);
@@ -2812,9 +2879,8 @@ enum Lisp_Compiled
};
/* Flag bits in a character. These also get used in termhooks.h.
- Richard Stallman <rms@gnu.ai.mit.edu> thinks that MULE
- (MUlti-Lingual Emacs) might need 22 bits for the character value
- itself, so we probably shouldn't use any bits lower than 0x0400000. */
+ Emacs needs 22 bits for the character value itself, see MAX_CHAR,
+ so we shouldn't use any bits lower than 0x0400000. */
enum char_bits
{
CHAR_ALT = 0x0400000,
@@ -3316,7 +3382,7 @@ struct frame;
/* Define if the windowing system provides a menu bar. */
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
- || defined (HAVE_NS) || defined (USE_GTK)
+ || defined (HAVE_NS) || defined (USE_GTK) || defined (HAVE_HAIKU)
#define HAVE_EXT_MENU_BAR true
#endif
@@ -3764,6 +3830,9 @@ extern Lisp_Object safe_eval (Lisp_Object);
extern bool pos_visible_p (struct window *, ptrdiff_t, int *,
int *, int *, int *, int *, int *);
+/* Defined in sqlite.c. */
+extern void syms_of_sqlite (void);
+
/* Defined in xsettings.c. */
extern void syms_of_xsettings (void);
@@ -3933,7 +4002,8 @@ build_string (const char *str)
extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object);
extern Lisp_Object make_vector (ptrdiff_t, Lisp_Object);
-extern struct Lisp_Vector *allocate_nil_vector (ptrdiff_t);
+extern struct Lisp_Vector *allocate_nil_vector (ptrdiff_t)
+ ATTRIBUTE_RETURNS_NONNULL;
/* Make an uninitialized vector for SIZE objects. NOTE: you must
be sure that GC cannot happen until the vector is completely
@@ -3946,7 +4016,8 @@ extern struct Lisp_Vector *allocate_nil_vector (ptrdiff_t);
allocate_vector has a similar problem. */
-extern struct Lisp_Vector *allocate_vector (ptrdiff_t);
+extern struct Lisp_Vector *allocate_vector (ptrdiff_t)
+ ATTRIBUTE_RETURNS_NONNULL;
INLINE Lisp_Object
make_uninit_vector (ptrdiff_t size)
@@ -3978,7 +4049,8 @@ make_nil_vector (ptrdiff_t size)
}
extern struct Lisp_Vector *allocate_pseudovector (int, int, int,
- enum pvec_type);
+ enum pvec_type)
+ ATTRIBUTE_RETURNS_NONNULL;
/* Allocate uninitialized pseudovector with no Lisp_Object slots. */
@@ -4010,7 +4082,7 @@ extern void free_cons (struct Lisp_Cons *);
extern void init_alloc_once (void);
extern void init_alloc (void);
extern void syms_of_alloc (void);
-extern struct buffer * allocate_buffer (void);
+extern struct buffer *allocate_buffer (void) ATTRIBUTE_RETURNS_NONNULL;
extern int valid_lisp_object_p (Lisp_Object);
/* Defined in gmalloc.c. */
@@ -4113,7 +4185,6 @@ intern_c_string (const char *str)
}
/* Defined in eval.c. */
-extern EMACS_INT minibuffer_quit_level;
extern Lisp_Object Vautoload_queue;
extern Lisp_Object Vrun_hooks;
extern Lisp_Object Vsignaling_function;
@@ -4169,7 +4240,8 @@ extern Lisp_Object internal_condition_case_n
(Lisp_Object (*) (ptrdiff_t, Lisp_Object *), ptrdiff_t, Lisp_Object *,
Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *));
extern Lisp_Object internal_catch_all (Lisp_Object (*) (void *), void *, Lisp_Object (*) (enum nonlocal_exit, Lisp_Object));
-extern struct handler *push_handler (Lisp_Object, enum handlertype);
+extern struct handler *push_handler (Lisp_Object, enum handlertype)
+ ATTRIBUTE_RETURNS_NONNULL;
extern struct handler *push_handler_nosignal (Lisp_Object, enum handlertype);
extern void specbind (Lisp_Object, Lisp_Object);
extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object);
@@ -4310,9 +4382,10 @@ extern void syms_of_marker (void);
/* Defined in fileio.c. */
-extern char *splice_dir_file (char *, char const *, char const *);
+extern char *splice_dir_file (char *, char const *, char const *)
+ ATTRIBUTE_RETURNS_NONNULL;
extern bool file_name_absolute_p (const char *);
-extern char const *get_homedir (void);
+extern char const *get_homedir (void) ATTRIBUTE_RETURNS_NONNULL;
extern Lisp_Object expand_and_dir_to_file (Lisp_Object);
extern Lisp_Object write_region (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object, Lisp_Object, Lisp_Object,
@@ -4411,7 +4484,7 @@ extern Lisp_Object menu_bar_items (Lisp_Object);
extern Lisp_Object tab_bar_items (Lisp_Object, int *);
extern Lisp_Object tool_bar_items (Lisp_Object, int *);
extern void discard_mouse_events (void);
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
void handle_input_available_signal (int);
#endif
extern Lisp_Object pending_funcalls;
@@ -4466,7 +4539,7 @@ INLINE void fixup_locale (void) {}
INLINE void synchronize_system_messages_locale (void) {}
INLINE void synchronize_system_time_locale (void) {}
#endif
-extern char *emacs_strerror (int);
+extern char *emacs_strerror (int) ATTRIBUTE_RETURNS_NONNULL;
extern void shut_down_emacs (int, Lisp_Object);
/* True means don't do interactive redisplay and don't change tty modes. */
@@ -4532,7 +4605,7 @@ extern void setup_process_coding_systems (Lisp_Object);
extern int emacs_spawn (pid_t *, int, int, int, char **, char **,
const char *, const char *, const sigset_t *);
-extern char **make_environment_block (Lisp_Object);
+extern char **make_environment_block (Lisp_Object) ATTRIBUTE_RETURNS_NONNULL;
extern void init_callproc_1 (void);
extern void init_callproc (void);
extern void set_initial_environment (void);
@@ -4760,19 +4833,19 @@ extern char *emacs_root_dir (void);
INLINE bool
SUBR_NATIVE_COMPILEDP (Lisp_Object a)
{
- return SUBRP (a) && !NILP (XSUBR (a)->native_comp_u[0]);
+ return SUBRP (a) && !NILP (XSUBR (a)->native_comp_u);
}
INLINE bool
SUBR_NATIVE_COMPILED_DYNP (Lisp_Object a)
{
- return SUBR_NATIVE_COMPILEDP (a) && !NILP (XSUBR (a)->lambda_list[0]);
+ return SUBR_NATIVE_COMPILEDP (a) && !NILP (XSUBR (a)->lambda_list);
}
INLINE Lisp_Object
SUBR_TYPE (Lisp_Object a)
{
- return XSUBR (a)->type[0];
+ return XSUBR (a)->type;
}
INLINE struct Lisp_Native_Comp_Unit *
@@ -4801,17 +4874,24 @@ extern char my_edata[];
extern char my_endbss[];
extern char *my_endbss_static;
-extern void *xmalloc (size_t) ATTRIBUTE_MALLOC_SIZE ((1));
-extern void *xzalloc (size_t) ATTRIBUTE_MALLOC_SIZE ((1));
-extern void *xrealloc (void *, size_t) ATTRIBUTE_ALLOC_SIZE ((2));
+extern void *xmalloc (size_t)
+ ATTRIBUTE_MALLOC_SIZE ((1)) ATTRIBUTE_RETURNS_NONNULL;
+extern void *xzalloc (size_t)
+ ATTRIBUTE_MALLOC_SIZE ((1)) ATTRIBUTE_RETURNS_NONNULL;
+extern void *xrealloc (void *, size_t)
+ ATTRIBUTE_ALLOC_SIZE ((2)) ATTRIBUTE_RETURNS_NONNULL;
extern void xfree (void *);
-extern void *xnmalloc (ptrdiff_t, ptrdiff_t) ATTRIBUTE_MALLOC_SIZE ((1,2));
+extern void *xnmalloc (ptrdiff_t, ptrdiff_t)
+ ATTRIBUTE_MALLOC_SIZE ((1,2)) ATTRIBUTE_RETURNS_NONNULL;
extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t)
- ATTRIBUTE_ALLOC_SIZE ((2,3));
-extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t);
-
-extern char *xstrdup (const char *) ATTRIBUTE_MALLOC;
-extern char *xlispstrdup (Lisp_Object) ATTRIBUTE_MALLOC;
+ ATTRIBUTE_ALLOC_SIZE ((2,3)) ATTRIBUTE_RETURNS_NONNULL;
+extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t)
+ ATTRIBUTE_RETURNS_NONNULL;
+
+extern char *xstrdup (char const *)
+ ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL;
+extern char *xlispstrdup (Lisp_Object)
+ ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL;
extern void dupstring (char **, char const *);
/* Make DEST a copy of STRING's data. Return a pointer to DEST's terminating
@@ -4861,7 +4941,8 @@ extern void init_system_name (void);
enum MAX_ALLOCA { MAX_ALLOCA = 16 * 1024 };
-extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
+extern void *record_xmalloc (size_t)
+ ATTRIBUTE_ALLOC_SIZE ((1)) ATTRIBUTE_RETURNS_NONNULL;
#define USE_SAFE_ALLOCA \
ptrdiff_t sa_avail = MAX_ALLOCA; \
diff --git a/src/lread.c b/src/lread.c
index a6c2db5d994..5a2f1bc54e5 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -165,6 +165,12 @@ static void readevalloop (Lisp_Object, struct infile *, Lisp_Object, bool,
Lisp_Object, Lisp_Object);
static void build_load_history (Lisp_Object, bool);
+
+static Lisp_Object oblookup_considering_shorthand (Lisp_Object, const char *,
+ ptrdiff_t, ptrdiff_t,
+ char **, ptrdiff_t *,
+ ptrdiff_t *);
+
/* Functions that read one byte from the current source READCHARFUN
or unreads one byte. If the integer argument C is -1, it returns
@@ -192,7 +198,7 @@ static int readbyte_from_string (int, Lisp_Object);
Qlambda, or a cons, we use this to keep an unread character because
a file stream can't handle multibyte-char unreading. The value -1
means that there's no unread character. */
-static int unread_char;
+static int unread_char = -1;
static int
readchar (Lisp_Object readcharfun, bool *multibyte)
@@ -1039,12 +1045,18 @@ lisp_file_lexically_bound_p (Lisp_Object readcharfun)
safe to load. Only files compiled with Emacs can be loaded. */
static int
-safe_to_load_version (int fd)
+safe_to_load_version (Lisp_Object file, int fd)
{
+ struct stat st;
char buf[512];
int nbytes, i;
int version = 1;
+ /* If the file is not regular, then we cannot safely seek it.
+ Assume that it is not safe to load as a compiled file. */
+ if (fstat (fd, &st) == 0 && !S_ISREG (st.st_mode))
+ return 0;
+
/* Read the first few bytes from the file, and look for a line
specifying the byte compiler version used. */
nbytes = emacs_read_quit (fd, buf, sizeof buf);
@@ -1062,7 +1074,9 @@ safe_to_load_version (int fd)
version = 0;
}
- lseek (fd, 0, SEEK_SET);
+ if (lseek (fd, 0, SEEK_SET) < 0)
+ report_file_error ("Seeking to start of file", file);
+
return version;
}
@@ -1265,7 +1279,10 @@ Return t if the file exists and loads successfully. */)
|| suffix_p (file, MODULES_SECONDARY_SUFFIX)
#endif
#endif
- || (NATIVE_COMP_FLAG && suffix_p (file, NATIVE_ELISP_SUFFIX)))
+#ifdef HAVE_NATIVE_COMP
+ || suffix_p (file, NATIVE_ELISP_SUFFIX)
+#endif
+ )
must_suffix = Qnil;
/* Don't insist on adding a suffix
if the argument includes a directory name. */
@@ -1345,8 +1362,11 @@ Return t if the file exists and loads successfully. */)
bool is_module = false;
#endif
- bool is_native_elisp =
- NATIVE_COMP_FLAG && suffix_p (found, NATIVE_ELISP_SUFFIX) ? true : false;
+#ifdef HAVE_NATIVE_COMP
+ bool is_native_elisp = suffix_p (found, NATIVE_ELISP_SUFFIX);
+#else
+ bool is_native_elisp = false;
+#endif
/* Check if we're stuck in a recursive load cycle.
@@ -1395,7 +1415,7 @@ Return t if the file exists and loads successfully. */)
if (is_elc
/* version = 1 means the file is empty, in which case we can
treat it as not byte-compiled. */
- || (fd >= 0 && (version = safe_to_load_version (fd)) > 1))
+ || (fd >= 0 && (version = safe_to_load_version (file, fd)) > 1))
/* Load .elc files directly, but not when they are
remote and have no handler! */
{
@@ -1404,11 +1424,8 @@ Return t if the file exists and loads successfully. */)
struct stat s1, s2;
int result;
- if (version < 0
- && ! (version = safe_to_load_version (fd)))
- {
- error ("File `%s' was not compiled in Emacs", SDATA (found));
- }
+ if (version < 0 && !(version = safe_to_load_version (file, fd)))
+ error ("File `%s' was not compiled in Emacs", SDATA (found));
compiled = 1;
@@ -1507,6 +1524,7 @@ Return t if the file exists and loads successfully. */)
input.stream = stream;
input.lookahead = 0;
infile = &input;
+ unread_char = -1;
}
if (! NILP (Vpurify_flag))
@@ -2697,7 +2715,7 @@ read_escape (Lisp_Object readcharfun, bool stringp)
c = read_escape (readcharfun, 0);
if ((c & ~CHAR_MODIFIER_MASK) == '?')
return 0177 | (c & CHAR_MODIFIER_MASK);
- else if (! SINGLE_BYTE_CHAR_P ((c & ~CHAR_MODIFIER_MASK)))
+ else if (! ASCII_CHAR_P ((c & ~CHAR_MODIFIER_MASK)))
return c | ctrl_modifier;
/* ASCII control chars are made from letters (both cases),
as well as the non-letters within 0100...0137. */
@@ -2955,7 +2973,6 @@ read_integer (Lisp_Object readcharfun, int radix,
return unbind_to (count, string_to_number (read_buffer, radix, NULL));
}
-
/* If the next token is ')' or ']' or '.', we store that character
in *PCH and the return value is not interesting. Else, we store
zero in *PCH and we read and return one lisp object.
@@ -2967,6 +2984,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
{
int c;
bool uninterned_symbol = false;
+ bool skip_shorthand = false;
bool multibyte;
char stackbuf[stackbufsize];
current_thread->stack_top = stackbuf;
@@ -3362,6 +3380,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
if (c == ':')
{
uninterned_symbol = true;
+ read_hash_prefixed_symbol:
c = READCHAR;
if (!(c > 040
&& c != NO_BREAK_SPACE
@@ -3375,6 +3394,12 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
}
goto read_symbol;
}
+ /* #_foo is really the symbol foo, regardless of shorthands */
+ if (c == '_')
+ {
+ skip_shorthand = true;
+ goto read_hash_prefixed_symbol;
+ }
/* ## is the empty symbol. */
if (c == '#')
return Fintern (empty_unibyte_string, Qnil);
@@ -3755,7 +3780,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
ptrdiff_t nbytes = p - read_buffer;
UNREAD (c);
- if (!quoted && !uninterned_symbol)
+ if (!quoted && !uninterned_symbol && !skip_shorthand)
{
ptrdiff_t len;
Lisp_Object result = string_to_number (read_buffer, 10, &len);
@@ -3785,11 +3810,36 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
Like intern_1 but supports multibyte names. */
Lisp_Object obarray = check_obarray (Vobarray);
- Lisp_Object tem = oblookup (obarray, read_buffer,
- nchars, nbytes);
+
+ char* longhand = NULL;
+ ptrdiff_t longhand_chars = 0;
+ ptrdiff_t longhand_bytes = 0;
+
+ Lisp_Object tem;
+ if (skip_shorthand
+ /* The following ASCII characters are used in the
+ only "core" Emacs Lisp symbols that are comprised
+ entirely of characters that have the 'symbol
+ constituent' syntax. We exempt them from
+ transforming according to shorthands. */
+ || strspn (read_buffer, "^*+-/<=>_|") >= nbytes)
+ tem = oblookup (obarray, read_buffer, nchars, nbytes);
+ else
+ tem = oblookup_considering_shorthand (obarray, read_buffer,
+ nchars, nbytes, &longhand,
+ &longhand_chars,
+ &longhand_bytes);
if (SYMBOLP (tem))
result = tem;
+ else if (longhand)
+ {
+ Lisp_Object name
+ = make_specified_string (longhand, longhand_chars,
+ longhand_bytes, multibyte);
+ xfree (longhand);
+ result = intern_driver (name, obarray, tem);
+ }
else
{
Lisp_Object name
@@ -4338,6 +4388,7 @@ intern_sym (Lisp_Object sym, Lisp_Object obarray, Lisp_Object index)
Lisp_Object
intern_driver (Lisp_Object string, Lisp_Object obarray, Lisp_Object index)
{
+ SET_SYMBOL_VAL (XSYMBOL (Qobarray_cache), Qnil);
return intern_sym (Fmake_symbol (string), obarray, index);
}
@@ -4406,10 +4457,28 @@ it defaults to the value of `obarray'. */)
obarray = check_obarray (NILP (obarray) ? Vobarray : obarray);
CHECK_STRING (string);
- tem = oblookup (obarray, SSDATA (string), SCHARS (string), SBYTES (string));
+
+ char* longhand = NULL;
+ ptrdiff_t longhand_chars = 0;
+ ptrdiff_t longhand_bytes = 0;
+ tem = oblookup_considering_shorthand (obarray, SSDATA (string),
+ SCHARS (string), SBYTES (string),
+ &longhand, &longhand_chars,
+ &longhand_bytes);
+
if (!SYMBOLP (tem))
- tem = intern_driver (NILP (Vpurify_flag) ? string : Fpurecopy (string),
- obarray, tem);
+ {
+ if (longhand)
+ {
+ tem = intern_driver (make_specified_string (longhand, longhand_chars,
+ longhand_bytes, true),
+ obarray, tem);
+ xfree (longhand);
+ }
+ else
+ tem = intern_driver (NILP (Vpurify_flag) ? string : Fpurecopy (string),
+ obarray, tem);
+ }
return tem;
}
@@ -4428,17 +4497,29 @@ it defaults to the value of `obarray'. */)
if (!SYMBOLP (name))
{
+ char *longhand = NULL;
+ ptrdiff_t longhand_chars = 0;
+ ptrdiff_t longhand_bytes = 0;
+
CHECK_STRING (name);
string = name;
+ tem = oblookup_considering_shorthand (obarray, SSDATA (string),
+ SCHARS (string), SBYTES (string),
+ &longhand, &longhand_chars,
+ &longhand_bytes);
+ if (longhand)
+ xfree (longhand);
+ return FIXNUMP (tem) ? Qnil : tem;
}
else
- string = SYMBOL_NAME (name);
-
- tem = oblookup (obarray, SSDATA (string), SCHARS (string), SBYTES (string));
- if (FIXNUMP (tem) || (SYMBOLP (name) && !EQ (name, tem)))
- return Qnil;
- else
- return tem;
+ {
+ /* If already a symbol, we don't do shorthand-longhand translation,
+ as promised in the docstring. */
+ string = SYMBOL_NAME (name);
+ tem
+ = oblookup (obarray, SSDATA (string), SCHARS (string), SBYTES (string));
+ return EQ (name, tem) ? name : Qnil;
+ }
}
DEFUN ("unintern", Funintern, Sunintern, 1, 2, 0,
@@ -4450,7 +4531,8 @@ OBARRAY, if nil, defaults to the value of the variable `obarray'.
usage: (unintern NAME OBARRAY) */)
(Lisp_Object name, Lisp_Object obarray)
{
- register Lisp_Object string, tem;
+ register Lisp_Object tem;
+ Lisp_Object string;
size_t hash;
if (NILP (obarray)) obarray = Vobarray;
@@ -4464,9 +4546,16 @@ usage: (unintern NAME OBARRAY) */)
string = name;
}
- tem = oblookup (obarray, SSDATA (string),
- SCHARS (string),
- SBYTES (string));
+ char *longhand = NULL;
+ ptrdiff_t longhand_chars = 0;
+ ptrdiff_t longhand_bytes = 0;
+ tem = oblookup_considering_shorthand (obarray, SSDATA (string),
+ SCHARS (string), SBYTES (string),
+ &longhand, &longhand_chars,
+ &longhand_bytes);
+ if (longhand)
+ xfree(longhand);
+
if (FIXNUMP (tem))
return Qnil;
/* If arg was a symbol, don't delete anything but that symbol itself. */
@@ -4553,6 +4642,70 @@ oblookup (Lisp_Object obarray, register const char *ptr, ptrdiff_t size, ptrdiff
XSETINT (tem, hash);
return tem;
}
+
+/* Like 'oblookup', but considers 'Vread_symbol_shorthands',
+ potentially recognizing that IN is shorthand for some other
+ longhand name, which is then then placed in OUT. In that case,
+ memory is malloc'ed for OUT (which the caller must free) while
+ SIZE_OUT and SIZE_BYTE_OUT respectively hold the character and byte
+ sizes of the transformed symbol name. If IN is not recognized
+ shorthand for any other symbol, OUT is set to point to NULL and
+ 'oblookup' is called. */
+
+Lisp_Object
+oblookup_considering_shorthand (Lisp_Object obarray, const char *in,
+ ptrdiff_t size, ptrdiff_t size_byte, char **out,
+ ptrdiff_t *size_out, ptrdiff_t *size_byte_out)
+{
+ Lisp_Object tail = Vread_symbol_shorthands;
+
+ /* First, assume no transformation will take place. */
+ *out = NULL;
+ /* Then, iterate each pair in Vread_symbol_shorthands. */
+ FOR_EACH_TAIL_SAFE (tail)
+ {
+ Lisp_Object pair = XCAR (tail);
+ /* Be lenient to 'read-symbol-shorthands': if some element isn't a
+ cons, or some member of that cons isn't a string, just skip
+ to the next element. */
+ if (!CONSP (pair))
+ continue;
+ Lisp_Object sh_prefix = XCAR (pair);
+ Lisp_Object lh_prefix = XCDR (pair);
+ if (!STRINGP (sh_prefix) || !STRINGP (lh_prefix))
+ continue;
+ ptrdiff_t sh_prefix_size = SBYTES (sh_prefix);
+
+ /* Compare the prefix of the transformation pair to the symbol
+ name. If a match occurs, do the renaming and exit the loop.
+ In other words, only one such transformation may take place.
+ Calculate the amount of memory to allocate for the longhand
+ version of the symbol name with xrealloc. This isn't
+ strictly needed, but it could later be used as a way for
+ multiple transformations on a single symbol name. */
+ if (sh_prefix_size <= size_byte
+ && memcmp (SSDATA (sh_prefix), in, sh_prefix_size) == 0)
+ {
+ ptrdiff_t lh_prefix_size = SBYTES (lh_prefix);
+ ptrdiff_t suffix_size = size_byte - sh_prefix_size;
+ *out = xrealloc (*out, lh_prefix_size + suffix_size);
+ memcpy (*out, SSDATA(lh_prefix), lh_prefix_size);
+ memcpy (*out + lh_prefix_size, in + sh_prefix_size, suffix_size);
+ *size_out = SCHARS (lh_prefix) - SCHARS (sh_prefix) + size;
+ *size_byte_out = lh_prefix_size + suffix_size;
+ break;
+ }
+ }
+ /* Now, as promised, call oblookup with the "final" symbol name to
+ lookup. That function remains oblivious to whether a
+ transformation happened here or not, but the caller of this
+ function can tell by inspecting the OUT parameter. */
+ if (*out)
+ return oblookup (obarray, *out, *size_out, *size_byte_out);
+ else
+ return oblookup (obarray, in, size, size_byte);
+}
+
void
map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Object arg)
@@ -5309,4 +5462,11 @@ that are loaded before your customizations are read! */);
DEFSYM (Qrehash_threshold, "rehash-threshold");
DEFSYM (Qchar_from_name, "char-from-name");
+
+ DEFVAR_LISP ("read-symbol-shorthands", Vread_symbol_shorthands,
+ doc: /* Alist of known symbol-name shorthands.
+This variable's value can only be set via file-local variables.
+See Info node `(elisp)Shorthands' for more details. */);
+ Vread_symbol_shorthands = Qnil;
+ DEFSYM (Qobarray_cache, "obarray-cache");
}
diff --git a/src/macfont.m b/src/macfont.m
index d86f09f4850..ce7a5ec8cda 100644
--- a/src/macfont.m
+++ b/src/macfont.m
@@ -613,6 +613,21 @@ get_cgcolor(unsigned long idx, struct frame *f)
return cgColor;
}
+static CGColorRef
+get_cgcolor_from_nscolor (NSColor *nsColor, struct frame *f)
+{
+ [nsColor set];
+ CGColorSpaceRef colorSpace = [[nsColor colorSpace] CGColorSpace];
+ NSInteger noc = [nsColor numberOfComponents];
+ CGFloat *components = xmalloc (sizeof(CGFloat)*(1+noc));
+ CGColorRef cgColor;
+
+ [nsColor getComponents: components];
+ cgColor = CGColorCreate (colorSpace, components);
+ xfree (components);
+ return cgColor;
+}
+
#define CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND(context, face, f) \
do { \
CGColorRef refcol_ = get_cgcolor (NS_FACE_FOREGROUND (face), f); \
@@ -2415,8 +2430,12 @@ macfont_list (struct frame *f, Lisp_Object spec)
continue;
/* Don't use a color bitmap font unless its family is
- explicitly specified. */
- if ((sym_traits & kCTFontTraitColorGlyphs) && NILP (family))
+ explicitly specified or we're looking for a font for
+ emoji. */
+ if ((sym_traits & kCTFontTraitColorGlyphs)
+ && NILP (family)
+ && !EQ (CDR_SAFE (assq_no_quit (QCscript, AREF (spec, FONT_EXTRA_INDEX))),
+ Qemoji))
continue;
if (j > 0
@@ -2907,14 +2926,14 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
if (!CGRectIsNull (background_rect))
{
- if (s->hl == DRAW_MOUSE_FACE)
+ if (s->hl == DRAW_CURSOR)
{
- face = FACE_FROM_ID_OR_NULL (s->f,
- MOUSE_HL_INFO (s->f)->mouse_face_face_id);
- if (!face)
- face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+ CGColorRef colorref = get_cgcolor_from_nscolor (FRAME_CURSOR_COLOR (f), f);
+ CGContextSetFillColorWithColor (context, colorref);
+ CGColorRelease (colorref);
}
- CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND (context, face, f);
+ else
+ CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND (context, face, f);
CGContextFillRects (context, &background_rect, 1);
}
@@ -2923,7 +2942,14 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
CGAffineTransform atfm;
CGContextScaleCTM (context, 1, -1);
- CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND (context, face, s->f);
+ if (s->hl == DRAW_CURSOR)
+ {
+ CGColorRef colorref = get_cgcolor_from_nscolor (FRAME_BACKGROUND_COLOR (f), f);
+ CGContextSetFillColorWithColor (context, colorref);
+ CGColorRelease (colorref);
+ }
+ else
+ CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND (context, face, s->f);
if (macfont_info->synthetic_italic_p)
atfm = synthetic_italic_atfm;
else
diff --git a/src/menu.c b/src/menu.c
index 3b1d7402571..b9da85ef3d5 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -50,7 +50,8 @@ extern AppendMenuW_Proc unicode_append_menu;
static bool
have_boxes (void)
{
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI) || defined(HAVE_NS)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI) || defined (HAVE_NS) \
+ || defined (HAVE_HAIKU)
if (FRAME_WINDOW_P (XFRAME (Vmenu_updating_frame)))
return 1;
#endif
@@ -422,7 +423,8 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
AREF (item_properties, ITEM_PROPERTY_SELECTED),
AREF (item_properties, ITEM_PROPERTY_HELP));
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (HAVE_NTGUI)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) \
+ || defined (HAVE_NTGUI) || defined (HAVE_HAIKU) || defined (HAVE_PGTK)
/* Display a submenu using the toolkit. */
if (FRAME_WINDOW_P (XFRAME (Vmenu_updating_frame))
&& ! (NILP (map) || NILP (enabled)))
@@ -872,6 +874,10 @@ update_submenu_strings (widget_value *first_wv)
}
}
+#endif /* USE_X_TOOLKIT || USE_GTK || HAVE_NS || HAVE_NTGUI */
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) \
+ || defined (HAVE_NTGUI) || defined (HAVE_HAIKU)
+
/* Find the menu selection and store it in the keyboard buffer.
F is the frame the menu is on.
MENU_BAR_ITEMS_USED is the length of VECTOR.
@@ -959,7 +965,7 @@ find_and_call_menu_selection (struct frame *f, int menu_bar_items_used,
SAFE_FREE ();
}
-#endif /* USE_X_TOOLKIT || USE_GTK || HAVE_NS || HAVE_NTGUI */
+#endif /* USE_X_TOOLKIT || USE_GTK || HAVE_NS || HAVE_NTGUI || HAVE_HAIKU */
#ifdef HAVE_NS
/* As above, but return the menu selection instead of storing in kb buffer.
@@ -1107,7 +1113,7 @@ into menu items. */)
Lisp_Object
x_popup_menu_1 (Lisp_Object position, Lisp_Object menu)
{
- Lisp_Object keymap, tem, tem2;
+ Lisp_Object keymap, tem, tem2 = Qnil;
int xpos = 0, ypos = 0;
Lisp_Object title;
const char *error_name = NULL;
@@ -1127,9 +1133,12 @@ x_popup_menu_1 (Lisp_Object position, Lisp_Object menu)
/* Decode the first argument: find the window and the coordinates. */
if (EQ (position, Qt)
- || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
- || EQ (XCAR (position), Qtab_bar)
- || EQ (XCAR (position), Qtool_bar))))
+ || (CONSP (position)
+ && (EQ (XCAR (position), Qmenu_bar)
+ || EQ (XCAR (position), Qtab_bar)
+ || (CONSP (XCDR (position))
+ && EQ (XCAR (XCDR (position)), Qtab_bar))
+ || EQ (XCAR (position), Qtool_bar))))
{
get_current_pos_p = 1;
}
@@ -1243,8 +1252,21 @@ x_popup_menu_1 (Lisp_Object position, Lisp_Object menu)
CHECK_LIVE_WINDOW (window);
f = XFRAME (WINDOW_FRAME (win));
- xpos = WINDOW_LEFT_EDGE_X (win);
- ypos = WINDOW_TOP_EDGE_Y (win);
+ if (FIXNUMP (tem2))
+ {
+ /* Clicks in the text area, where TEM2 is a buffer
+ position, are relative to the top-left edge of the text
+ area, see keyboard.c:make_lispy_position. */
+ xpos = window_box_left (win, TEXT_AREA);
+ ypos = (WINDOW_TOP_EDGE_Y (win)
+ + WINDOW_TAB_LINE_HEIGHT (win)
+ + WINDOW_HEADER_LINE_HEIGHT (win));
+ }
+ else
+ {
+ xpos = WINDOW_LEFT_EDGE_X (win);
+ ypos = WINDOW_TOP_EDGE_Y (win);
+ }
}
else
/* ??? Not really clean; should be CHECK_WINDOW_OR_FRAME,
@@ -1284,12 +1306,16 @@ x_popup_menu_1 (Lisp_Object position, Lisp_Object menu)
/* Search for a string appearing directly as an element of the keymap.
That string is the title of the menu. */
prompt = Fkeymap_prompt (keymap);
- if (!NILP (prompt))
- title = prompt;
-#ifdef HAVE_NS /* Is that needed and NS-specific? --Stef */
+
+#if defined (USE_GTK) || defined (HAVE_NS)
+ if (STRINGP (prompt)
+ && SCHARS (prompt) > 0
+ && !NILP (Fget_text_property (make_fixnum (0), Qhide, prompt)))
+ title = Qnil;
else
- title = build_string ("Select");
#endif
+ if (!NILP (prompt))
+ title = prompt;
/* Make that be the pane title of the first pane. */
if (!NILP (prompt) && menu_items_n_panes >= 0)
@@ -1575,6 +1601,8 @@ syms_of_menu (void)
menu_items = Qnil;
staticpro (&menu_items);
+ DEFSYM (Qhide, "hide");
+
defsubr (&Sx_popup_menu);
defsubr (&Sx_popup_dialog);
defsubr (&Smenu_bar_menu_at_x_y);
diff --git a/src/menu.h b/src/menu.h
index 6c67ab20bb0..30b946c0ea4 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -59,6 +59,12 @@ extern Lisp_Object ns_menu_show (struct frame *, int, int, int,
Lisp_Object, const char **);
extern void ns_activate_menubar (struct frame *);
#endif
+#ifdef HAVE_PGTK
+extern Lisp_Object pgtk_menu_show (struct frame *, int, int, int,
+ Lisp_Object, const char **);
+extern void pgtk_activate_menubar (struct frame *);
+#endif
+
extern Lisp_Object tty_menu_show (struct frame *, int, int, int,
Lisp_Object, const char **);
extern ptrdiff_t menu_item_width (const unsigned char *);
diff --git a/src/minibuf.c b/src/minibuf.c
index c9134eff67f..6c0cd358c50 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -491,8 +491,13 @@ confirm the aborting of the current minibuffer and all contained ones. */)
array[1] = make_fixnum (minibuf_level - minibuf_depth + 1);
if (!NILP (Fyes_or_no_p (Fformat (2, array))))
{
- minibuffer_quit_level = minibuf_depth;
- Fthrow (Qexit, Qt);
+ /* Due to the above check, the current minibuffer is in the
+ most nested command loop, which means that we don't have
+ to abort any extra non-minibuffer recursive edits. Thus,
+ the number of recursive edits we have to abort equals the
+ number of minibuffers we have to abort. */
+ CALLN (Ffuncall, intern ("minibuffer-quit-recursive-edit"),
+ array[1]);
}
}
else
@@ -1000,7 +1005,7 @@ set_minibuffer_mode (Lisp_Object buf, EMACS_INT depth)
if (!NILP (Ffboundp (Qminibuffer_inactive_mode)))
call0 (Qminibuffer_inactive_mode);
else
- Fkill_all_local_variables ();
+ Fkill_all_local_variables (Qnil);
}
buf = unbind_to (count, buf);
}
@@ -1287,8 +1292,8 @@ Fifth arg HIST, if non-nil, specifies a history list and optionally
HISTPOS is the initial position for use by the minibuffer history
commands. For consistency, you should also specify that element of
the history as the value of INITIAL-CONTENTS. Positions are counted
- starting from 1 at the beginning of the list. If HIST is the symbol
- `t', history is not recorded.
+ starting from 1 at the beginning of the list. If HIST is t, history
+ is not recorded.
If `history-add-new-input' is non-nil (the default), the result will
be added to the history list using `add-to-history'.
@@ -1540,6 +1545,27 @@ minibuf_conform_representation (Lisp_Object string, Lisp_Object basis)
return Fstring_make_multibyte (string);
}
+static bool
+match_regexps (Lisp_Object string, Lisp_Object regexps,
+ bool ignore_case)
+{
+ ptrdiff_t val;
+ for (; CONSP (regexps); regexps = XCDR (regexps))
+ {
+ CHECK_STRING (XCAR (regexps));
+
+ val = fast_string_match_internal
+ (XCAR (regexps), string,
+ (ignore_case ? BVAR (current_buffer, case_canon_table) : Qnil));
+
+ if (val == -2)
+ error ("Stack overflow in regexp matcher");
+ if (val < 0)
+ return false;
+ }
+ return true;
+}
+
DEFUN ("try-completion", Ftry_completion, Stry_completion, 2, 3, 0,
doc: /* Return common substring of all completions of STRING in COLLECTION.
Test each possible completion specified by COLLECTION
@@ -1573,6 +1599,7 @@ Additionally to this predicate, `completion-regexp-list'
is used to further constrain the set of candidates. */)
(Lisp_Object string, Lisp_Object collection, Lisp_Object predicate)
{
+
Lisp_Object bestmatch, tail, elt, eltstring;
/* Size in bytes of BESTMATCH. */
ptrdiff_t bestmatchsize = 0;
@@ -1586,7 +1613,6 @@ is used to further constrain the set of candidates. */)
? list_table : function_table));
ptrdiff_t idx = 0, obsize = 0;
int matchcount = 0;
- ptrdiff_t bindcount = -1;
Lisp_Object bucket, zero, end, tem;
CHECK_STRING (string);
@@ -1665,27 +1691,10 @@ is used to further constrain the set of candidates. */)
completion_ignore_case ? Qt : Qnil),
EQ (Qt, tem)))
{
- /* Yes. */
- Lisp_Object regexps;
-
/* Ignore this element if it fails to match all the regexps. */
- {
- for (regexps = Vcompletion_regexp_list; CONSP (regexps);
- regexps = XCDR (regexps))
- {
- if (bindcount < 0)
- {
- bindcount = SPECPDL_INDEX ();
- specbind (Qcase_fold_search,
- completion_ignore_case ? Qt : Qnil);
- }
- tem = Fstring_match (XCAR (regexps), eltstring, zero);
- if (NILP (tem))
- break;
- }
- if (CONSP (regexps))
- continue;
- }
+ if (!match_regexps (eltstring, Vcompletion_regexp_list,
+ completion_ignore_case))
+ continue;
/* Ignore this element if there is a predicate
and the predicate doesn't like it. */
@@ -1696,11 +1705,6 @@ is used to further constrain the set of candidates. */)
tem = Fcommandp (elt, Qnil);
else
{
- if (bindcount >= 0)
- {
- unbind_to (bindcount, Qnil);
- bindcount = -1;
- }
tem = (type == hash_table
? call2 (predicate, elt,
HASH_VALUE (XHASH_TABLE (collection),
@@ -1782,9 +1786,6 @@ is used to further constrain the set of candidates. */)
}
}
- if (bindcount >= 0)
- unbind_to (bindcount, Qnil);
-
if (NILP (bestmatch))
return Qnil; /* No completions found. */
/* If we are ignoring case, and there is no exact match,
@@ -1844,7 +1845,6 @@ with a space are ignored unless STRING itself starts with a space. */)
: VECTORP (collection) ? 2
: NILP (collection) || (CONSP (collection) && !FUNCTIONP (collection));
ptrdiff_t idx = 0, obsize = 0;
- ptrdiff_t bindcount = -1;
Lisp_Object bucket, tem, zero;
CHECK_STRING (string);
@@ -1929,27 +1929,10 @@ with a space are ignored unless STRING itself starts with a space. */)
completion_ignore_case ? Qt : Qnil),
EQ (Qt, tem)))
{
- /* Yes. */
- Lisp_Object regexps;
-
/* Ignore this element if it fails to match all the regexps. */
- {
- for (regexps = Vcompletion_regexp_list; CONSP (regexps);
- regexps = XCDR (regexps))
- {
- if (bindcount < 0)
- {
- bindcount = SPECPDL_INDEX ();
- specbind (Qcase_fold_search,
- completion_ignore_case ? Qt : Qnil);
- }
- tem = Fstring_match (XCAR (regexps), eltstring, zero);
- if (NILP (tem))
- break;
- }
- if (CONSP (regexps))
- continue;
- }
+ if (!match_regexps (eltstring, Vcompletion_regexp_list,
+ completion_ignore_case))
+ continue;
/* Ignore this element if there is a predicate
and the predicate doesn't like it. */
@@ -1960,11 +1943,6 @@ with a space are ignored unless STRING itself starts with a space. */)
tem = Fcommandp (elt, Qnil);
else
{
- if (bindcount >= 0)
- {
- unbind_to (bindcount, Qnil);
- bindcount = -1;
- }
tem = type == 3
? call2 (predicate, elt,
HASH_VALUE (XHASH_TABLE (collection), idx - 1))
@@ -1977,9 +1955,6 @@ with a space are ignored unless STRING itself starts with a space. */)
}
}
- if (bindcount >= 0)
- unbind_to (bindcount, Qnil);
-
return Fnreverse (allmatches);
}
@@ -2032,8 +2007,7 @@ HIST, if non-nil, specifies a history list and optionally the initial
(This is the only case in which you should use INITIAL-INPUT instead
of DEF.) Positions are counted starting from 1 at the beginning of
the list. The variable `history-length' controls the maximum length
- of a history list. If HIST is the symbol `t', history is not
- recorded.
+ of a history list. If HIST is t, history is not recorded.
DEF, if non-nil, is the default value or the list of default values.
@@ -2055,12 +2029,16 @@ See also `completing-read-function'. */)
/* Test whether TXT is an exact completion. */
DEFUN ("test-completion", Ftest_completion, Stest_completion, 2, 3, 0,
doc: /* Return non-nil if STRING is a valid completion.
+For instance, if COLLECTION is a list of strings, STRING is a
+valid completion if it appears in the list and PREDICATE is satisfied.
+
Takes the same arguments as `all-completions' and `try-completion'.
+
If COLLECTION is a function, it is called with three arguments:
the values STRING, PREDICATE and `lambda'. */)
(Lisp_Object string, Lisp_Object collection, Lisp_Object predicate)
{
- Lisp_Object regexps, tail, tem = Qnil;
+ Lisp_Object tail, tem = Qnil;
ptrdiff_t i = 0;
CHECK_STRING (string);
@@ -2146,20 +2124,9 @@ the values STRING, PREDICATE and `lambda'. */)
return call3 (collection, string, predicate, Qlambda);
/* Reject this element if it fails to match all the regexps. */
- if (CONSP (Vcompletion_regexp_list))
- {
- ptrdiff_t count = SPECPDL_INDEX ();
- specbind (Qcase_fold_search, completion_ignore_case ? Qt : Qnil);
- for (regexps = Vcompletion_regexp_list; CONSP (regexps);
- regexps = XCDR (regexps))
- {
- /* We can test against STRING, because if we got here, then
- the element is equivalent to it. */
- if (NILP (Fstring_match (XCAR (regexps), string, Qnil)))
- return unbind_to (count, Qnil);
- }
- unbind_to (count, Qnil);
- }
+ if (!match_regexps (string, Vcompletion_regexp_list,
+ completion_ignore_case))
+ return Qnil;
/* Finally, check the predicate. */
if (!NILP (predicate))
@@ -2477,7 +2444,7 @@ is added with
(set minibuffer-history-variable
(cons STRING (symbol-value minibuffer-history-variable)))
- If the variable is the symbol `t', no history is recorded. */);
+ If the variable is t, no history is recorded. */);
XSETFASTINT (Vminibuffer_history_variable, 0);
DEFVAR_LISP ("minibuffer-history-position", Vminibuffer_history_position,
diff --git a/src/module-env-28.h b/src/module-env-28.h
index f8820b0606b..bea80a5553a 100644
--- a/src/module-env-28.h
+++ b/src/module-env-28.h
@@ -1,7 +1,3 @@
- /* Add module environment functions newly added in Emacs 28 here.
- Before Emacs 28 is released, remove this comment and start
- module-env-29.h on the master branch. */
-
void (*(*EMACS_ATTRIBUTE_NONNULL (1)
get_function_finalizer) (emacs_env *env,
emacs_value arg)) (void *) EMACS_NOEXCEPT;
diff --git a/src/module-env-29.h b/src/module-env-29.h
new file mode 100644
index 00000000000..6ca03773181
--- /dev/null
+++ b/src/module-env-29.h
@@ -0,0 +1,3 @@
+ /* Add module environment functions newly added in Emacs 29 here.
+ Before Emacs 29 is released, remove this comment and start
+ module-env-30.h on the master branch. */
diff --git a/src/msdos.c b/src/msdos.c
index 5da01c9e7ca..2272aba6fde 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -1794,7 +1794,7 @@ internal_terminal_init (void)
}
Vinitial_window_system = Qpc;
- Vwindow_system_version = make_fixnum (28); /* RE Emacs version */
+ Vwindow_system_version = make_fixnum (29); /* RE Emacs version */
tty->terminal->type = output_msdos_raw;
/* If Emacs was dumped on DOS/V machine, forget the stale VRAM
@@ -1874,6 +1874,7 @@ initialize_msdos_display (struct terminal *term)
term->redeem_scroll_bar_hook = 0;
term->judge_scroll_bars_hook = 0;
term->read_socket_hook = &tty_read_avail_input; /* from keyboard.c */
+ term->defined_color_hook = &tty_defined_color; /* from xfaces.c */
}
int
@@ -3915,6 +3916,50 @@ readlinkat (int fd, char const *name, char *buffer, size_t buffer_size)
return readlink (name, buffer, buffer_size);
}
+
+int
+openat (int fd, const char * path, int oflag, int mode)
+{
+ /* Rely on a hack: an open directory is modeled as file descriptor 0,
+ as in fstatat. FIXME: Add proper support for openat. */
+ char fullname[MAXPATHLEN];
+
+ if (fd != AT_FDCWD)
+ {
+ if (strlen (dir_pathname) + strlen (path) + 1 >= MAXPATHLEN)
+ {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+ sprintf (fullname, "%s/%s", dir_pathname, path);
+ path = fullname;
+ }
+
+ return open (path, oflag, mode);
+}
+
+int
+fchmodat (int fd, const char *path, mode_t mode, int flags)
+{
+ /* Rely on a hack: an open directory is modeled as file descriptor 0,
+ as in fstatat. FIXME: Add proper support for openat. */
+ char fullname[MAXPATHLEN];
+
+ if (fd != AT_FDCWD)
+ {
+ if (strlen (dir_pathname) + strlen (path) + 1 >= MAXPATHLEN)
+ {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
+ sprintf (fullname, "%s/%s", dir_pathname, path);
+ path = fullname;
+ }
+
+ return chmod (path, mode);
+}
+
char *
careadlinkat (int fd, char const *filename,
char *buffer, size_t buffer_size,
@@ -3942,6 +3987,63 @@ careadlinkat (int fd, char const *filename,
return buffer;
}
+int
+futimens (int fd, const struct timespec times[2])
+{
+ struct tm *tm;
+ struct ftime ft;
+ time_t t;
+
+ block_input ();
+ if (times[1].tv_sec == UTIME_NOW)
+ t = time (NULL);
+ else
+ t = times[1].tv_sec;
+
+ tm = localtime (&t);
+ ft.ft_tsec = min (29, tm->tm_sec / 2);
+ ft.ft_min = tm->tm_min;
+ ft.ft_hour = tm->tm_hour;
+ ft.ft_day = tm->tm_mday;
+ ft.ft_month = tm->tm_mon + 1;
+ ft.ft_year = max (0, tm->tm_year - 80);
+ unblock_input ();
+
+ return setftime (fd, &ft);
+}
+
+int
+utimensat (int dirfd, const char *pathname,
+ const struct timespec times[2], int flags)
+{
+ int fd, ret;
+ char fullname[MAXPATHLEN];
+
+ /* Rely on a hack: dirfd in its current usage in Emacs is always
+ AT_FDCWD. */
+
+ if (dirfd != AT_FDCWD)
+ {
+ if (strlen (dir_pathname) + strlen (pathname) + 1 >= MAXPATHLEN)
+ {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+ sprintf (fullname, "%s/%s", dir_pathname, pathname);
+ pathname = fullname;
+ }
+
+ fd = open (pathname, O_WRONLY);
+
+ if (fd < 0)
+ return -1;
+
+ ret = futimens (fd, times);
+ close (fd);
+
+ return ret;
+}
+
/* Emulate faccessat(2). */
int
faccessat (int dirfd, const char * path, int mode, int flags)
diff --git a/src/msdos.h b/src/msdos.h
index f7d3b0d7029..d58b60ef5df 100644
--- a/src/msdos.h
+++ b/src/msdos.h
@@ -86,6 +86,8 @@ typedef int GC;
typedef int Pixmap;
typedef int Display;
typedef int Window;
+
+#define FRAME_X_DISPLAY(ignored) NULL
#define PIX_TYPE unsigned long
#define XDISPLAY
diff --git a/src/nsfns.m b/src/nsfns.m
index c40367703db..81019fce09d 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -609,13 +609,72 @@ ns_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
}
}
+void
+ns_change_tab_bar_height (struct frame *f, int height)
+{
+ int unit = FRAME_LINE_HEIGHT (f);
+ int old_height = FRAME_TAB_BAR_HEIGHT (f);
+ int lines = (height + unit - 1) / unit;
+ Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
+
+ /* Make sure we redisplay all windows in this frame. */
+ fset_redisplay (f);
+
+ /* Recalculate tab bar and frame text sizes. */
+ FRAME_TAB_BAR_HEIGHT (f) = height;
+ FRAME_TAB_BAR_LINES (f) = lines;
+ store_frame_param (f, Qtab_bar_lines, make_fixnum (lines));
+
+ if (FRAME_NS_WINDOW (f) && FRAME_TAB_BAR_HEIGHT (f) == 0)
+ {
+ clear_frame (f);
+ clear_current_matrices (f);
+ }
+
+ if ((height < old_height) && WINDOWP (f->tab_bar_window))
+ clear_glyph_matrix (XWINDOW (f->tab_bar_window)->current_matrix);
+
+ if (!f->tab_bar_resized)
+ {
+ /* As long as tab_bar_resized is false, effectively try to change
+ F's native height. */
+ if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
+ adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+ 1, false, Qtab_bar_lines);
+ else
+ adjust_frame_size (f, -1, -1, 4, false, Qtab_bar_lines);
+
+ f->tab_bar_resized = f->tab_bar_redisplayed;
+ }
+ else
+ /* Any other change may leave the native size of F alone. */
+ adjust_frame_size (f, -1, -1, 3, false, Qtab_bar_lines);
+
+ /* adjust_frame_size might not have done anything, garbage frame
+ here. */
+ adjust_frame_glyphs (f);
+ SET_FRAME_GARBAGED (f);
+}
/* tabbar support */
static void
ns_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
{
- /* Currently unimplemented. */
- NSTRACE ("ns_set_tab_bar_lines");
+ int olines = FRAME_TAB_BAR_LINES (f);
+ int nlines;
+
+ /* Treat tab bars like menu bars. */
+ if (FRAME_MINIBUF_ONLY_P (f))
+ return;
+
+ /* Use VALUE only if an int >= 0. */
+ if (RANGED_FIXNUMP (0, value, INT_MAX))
+ nlines = XFIXNAT (value);
+ else
+ nlines = 0;
+
+ if (nlines != olines && (olines == 0 || nlines == 0))
+ ns_change_tab_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
}
@@ -1177,6 +1236,7 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
"fontBackend", "FontBackend", RES_TYPE_STRING);
{
+#ifdef NS_IMPL_COCOA
/* use for default font name */
id font = [NSFont userFixedPitchFontOfSize: -1.0]; /* default */
gui_default_parameter (f, parms, Qfontsize,
@@ -1191,6 +1251,11 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
build_string (fontname),
"font", "Font", RES_TYPE_STRING);
xfree (fontname);
+#else
+ gui_default_parameter (f, parms, Qfont,
+ build_string ("fixed"),
+ "font", "Font", RES_TYPE_STRING);
+#endif
}
unblock_input ();
@@ -1300,6 +1365,10 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
NILP (Vmenu_bar_mode)
? make_fixnum (0) : make_fixnum (1),
NULL, NULL, RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qtab_bar_lines,
+ NILP (Vtab_bar_mode)
+ ? make_fixnum (0) : make_fixnum (1),
+ NULL, NULL, RES_TYPE_NUMBER);
gui_default_parameter (f, parms, Qtool_bar_lines,
NILP (Vtool_bar_mode)
? make_fixnum (0) : make_fixnum (1),
@@ -1343,6 +1412,11 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
f->output_data.ns->in_animation = NO;
+#ifdef NS_IMPL_COCOA
+ /* If the app has previously been disabled, start it up again. */
+ [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
+#endif
+
[[EmacsView alloc] initFrameFromEmacs: f];
ns_icon (f, parms);
@@ -1961,12 +2035,14 @@ is layered in front of the windows of other applications. */)
[NSApp unhide: NSApp];
[NSApp activateIgnoringOtherApps: YES];
}
+#if GNUSTEP_GUI_MAJOR_VERSION > 0 || GNUSTEP_GUI_MINOR_VERSION >= 27
else if (EQ (on, intern ("activate-front")))
{
[NSApp unhide: NSApp];
[[NSRunningApplication currentApplication]
activateWithOptions: NSApplicationActivateIgnoringOtherApps];
}
+#endif
else if (NILP (on))
[NSApp unhide: NSApp];
else
@@ -2286,6 +2362,47 @@ ns_get_string_resource (void *_rdb, const char *name, const char *class)
========================================================================== */
+#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+/* Moving files to the system recycle bin.
+ Used by `move-file-to-trash' instead of the default moving to ~/.Trash */
+DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash,
+ Ssystem_move_file_to_trash, 1, 1, 0,
+ doc: /* Move file or directory named FILENAME to the recycle bin. */)
+ (Lisp_Object filename)
+{
+ Lisp_Object handler;
+ Lisp_Object operation;
+
+ operation = Qdelete_file;
+ if (!NILP (Ffile_directory_p (filename))
+ && NILP (Ffile_symlink_p (filename)))
+ {
+ operation = intern ("delete-directory");
+ filename = Fdirectory_file_name (filename);
+ }
+
+ /* Must have fully qualified file names for moving files to Trash. */
+ filename = Fexpand_file_name (filename, Qnil);
+
+ handler = Ffind_file_name_handler (filename, operation);
+ if (!NILP (handler))
+ return call2 (handler, operation, filename);
+ else
+ {
+ NSFileManager *fm = [NSFileManager defaultManager];
+ BOOL result = NO;
+ NSURL *fileURL = [NSURL fileURLWithPath:[NSString stringWithLispString:filename]
+ isDirectory:!NILP (Ffile_directory_p (filename))];
+ if ([fm respondsToSelector:@selector(trashItemAtURL:resultingItemURL:error:)])
+ result = [fm trashItemAtURL:fileURL resultingItemURL:nil error:nil];
+
+ if (!result)
+ report_file_error ("Removing old name", list1 (filename));
+ }
+ return Qnil;
+}
+#endif
+
DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
doc: /* SKIP: real doc in xfns.c. */)
(Lisp_Object color, Lisp_Object frame)
@@ -3167,6 +3284,10 @@ Default is t. */);
defsubr (&Sx_show_tip);
defsubr (&Sx_hide_tip);
+#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+ defsubr (&Ssystem_move_file_to_trash);
+#endif
+
as_status = 0;
as_script = Qnil;
staticpro (&as_script);
diff --git a/src/nsfont.m b/src/nsfont.m
index 5a9cdfebc01..b3224629f05 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -1,4 +1,4 @@
-/* Font back-end driver for the NeXT/Open/GNUstep and macOS window system.
+/* Font back-end driver for the GNUstep window system.
See font.h
Copyright (C) 2006-2021 Free Software Foundation, Inc.
@@ -38,47 +38,269 @@ Author: Adrian Robert (arobert@cogsci.ucsd.edu)
#include "termchar.h"
#include "pdumper.h"
-/* TODO: Drop once we can assume gnustep-gui 0.17.1. */
+#import <Foundation/NSException.h>
#import <AppKit/NSFontDescriptor.h>
+#import <AppKit/NSLayoutManager.h>
+#import <GNUstepGUI/GSLayoutManager.h>
+#import <GNUstepGUI/GSFontInfo.h>
#define NSFONT_TRACE 0
-#define LCD_SMOOTHING_MARGIN 2
-/* Font glyph and metrics caching functions, implemented at end. */
-static void ns_uni_to_glyphs (struct nsfont_info *font_info,
- unsigned char block);
-static void ns_glyph_metrics (struct nsfont_info *font_info,
- unsigned char block);
+/* Structure used by GS `shape' functions for storing layout
+ information for each glyph. Borrowed from macfont.h. */
+struct ns_glyph_layout
+{
+ /* Range of indices of the characters composed into the group of
+ glyphs that share the cursor position with this glyph. The
+ members `location' and `length' are in UTF-16 indices. */
+ NSRange comp_range;
-#define INVALID_GLYPH 0xFFFF
+ /* UTF-16 index in the source string for the first character
+ associated with this glyph. */
+ NSUInteger string_index;
-/* ==========================================================================
+ /* Horizontal and vertical adjustments of glyph position. The
+ coordinate space is that of Core Text. So, the `baseline_delta'
+ value is negative if the glyph should be placed below the
+ baseline. */
+ CGFloat advance_delta, baseline_delta;
- Utilities
+ /* Typographical width of the glyph. */
+ CGFloat advance;
- ========================================================================== */
+ /* Glyph ID of the glyph. */
+ NSGlyph glyph_id;
+};
+
+
+enum lgstring_direction
+ {
+ DIR_R2L = -1, DIR_UNKNOWN = 0, DIR_L2R = 1
+ };
+
+enum gs_font_slant
+ {
+ GS_FONT_SLANT_ITALIC,
+ GS_FONT_SLANT_REVERSE_ITALIC,
+ GS_FONT_SLANT_NORMAL
+ };
+
+enum gs_font_weight
+ {
+ GS_FONT_WEIGHT_LIGHT,
+ GS_FONT_WEIGHT_BOLD,
+ GS_FONT_WEIGHT_NORMAL
+ };
+
+enum gs_font_width
+ {
+ GS_FONT_WIDTH_CONDENSED,
+ GS_FONT_WIDTH_EXPANDED,
+ GS_FONT_WIDTH_NORMAL
+ };
+
+enum gs_specified
+ {
+ GS_SPECIFIED_SLANT = 1,
+ GS_SPECIFIED_WEIGHT = 1 << 1,
+ GS_SPECIFIED_WIDTH = 1 << 2,
+ GS_SPECIFIED_FAMILY = 1 << 3,
+ GS_SPECIFIED_SPACING = 1 << 4
+ };
+struct gs_font_data
+{
+ int specified;
+ enum gs_font_slant slant;
+ enum gs_font_weight weight;
+ enum gs_font_width width;
+ bool monospace_p;
+ char *family_name;
+};
-/* Replace spaces w/another character so emacs core font parsing routines
- aren't thrown off. */
static void
-ns_escape_name (char *name)
+ns_done_font_data (struct gs_font_data *data)
{
- for (; *name; name++)
- if (*name == ' ')
- *name = '_';
+ if (data->specified & GS_SPECIFIED_FAMILY)
+ xfree (data->family_name);
}
-
-/* Reconstruct spaces in a font family name passed through emacs. */
static void
-ns_unescape_name (char *name)
+ns_get_font_data (NSFontDescriptor *desc, struct gs_font_data *dat)
{
- for (; *name; name++)
- if (*name == '_')
- *name = ' ';
+ NSNumber *tem;
+ NSFontSymbolicTraits traits = [desc symbolicTraits];
+ NSDictionary *dict = [desc objectForKey: NSFontTraitsAttribute];
+ NSString *family = [desc objectForKey: NSFontFamilyAttribute];
+
+ dat->specified = 0;
+
+ if (family != nil)
+ {
+ dat->specified |= GS_SPECIFIED_FAMILY;
+ dat->family_name = xstrdup ([family cStringUsingEncoding: NSUTF8StringEncoding]);
+ }
+
+ tem = [desc objectForKey: NSFontFixedAdvanceAttribute];
+
+ if ((tem != nil && [tem boolValue] != NO)
+ || (traits & NSFontMonoSpaceTrait))
+ {
+ dat->specified |= GS_SPECIFIED_SPACING;
+ dat->monospace_p = true;
+ }
+ else if (tem != nil && [tem boolValue] == NO)
+ {
+ dat->specified |= GS_SPECIFIED_SPACING;
+ dat->monospace_p = false;
+ }
+
+ if (traits & NSFontBoldTrait)
+ {
+ dat->specified |= GS_SPECIFIED_WEIGHT;
+ dat->weight = GS_FONT_WEIGHT_BOLD;
+ }
+
+ if (traits & NSFontItalicTrait)
+ {
+ dat->specified |= GS_SPECIFIED_SLANT;
+ dat->slant = GS_FONT_SLANT_ITALIC;
+ }
+
+ if (traits & NSFontCondensedTrait)
+ {
+ dat->specified |= GS_SPECIFIED_WIDTH;
+ dat->width = GS_FONT_WIDTH_CONDENSED;
+ }
+ else if (traits & NSFontExpandedTrait)
+ {
+ dat->specified |= GS_SPECIFIED_WIDTH;
+ dat->width = GS_FONT_WIDTH_EXPANDED;
+ }
+
+ if (dict != nil)
+ {
+ tem = [dict objectForKey: NSFontSlantTrait];
+
+ if (tem != nil)
+ {
+ dat->specified |= GS_SPECIFIED_SLANT;
+
+ dat->slant = [tem floatValue] > 0
+ ? GS_FONT_SLANT_ITALIC
+ : ([tem floatValue] < 0
+ ? GS_FONT_SLANT_REVERSE_ITALIC
+ : GS_FONT_SLANT_NORMAL);
+ }
+
+ tem = [dict objectForKey: NSFontWeightTrait];
+
+ if (tem != nil)
+ {
+ dat->specified |= GS_SPECIFIED_WEIGHT;
+
+ dat->weight = [tem floatValue] > 0
+ ? GS_FONT_WEIGHT_BOLD
+ : ([tem floatValue] < -0.4f
+ ? GS_FONT_WEIGHT_LIGHT
+ : GS_FONT_WEIGHT_NORMAL);
+ }
+
+ tem = [dict objectForKey: NSFontWidthTrait];
+
+ if (tem != nil)
+ {
+ dat->specified |= GS_SPECIFIED_WIDTH;
+
+ dat->width = [tem floatValue] > 0
+ ? GS_FONT_WIDTH_EXPANDED
+ : ([tem floatValue] < 0
+ ? GS_FONT_WIDTH_NORMAL
+ : GS_FONT_WIDTH_CONDENSED);
+ }
+ }
+}
+
+static bool
+ns_font_descs_match_p (NSFontDescriptor *desc, NSFontDescriptor *target)
+{
+ struct gs_font_data dat;
+ struct gs_font_data t;
+
+ ns_get_font_data (desc, &dat);
+ ns_get_font_data (target, &t);
+
+ if (!(t.specified & GS_SPECIFIED_WIDTH))
+ t.width = GS_FONT_WIDTH_NORMAL;
+ if (!(t.specified & GS_SPECIFIED_WEIGHT))
+ t.weight = GS_FONT_WEIGHT_NORMAL;
+ if (!(t.specified & GS_SPECIFIED_SPACING))
+ t.monospace_p = false;
+ if (!(t.specified & GS_SPECIFIED_SLANT))
+ t.slant = GS_FONT_SLANT_NORMAL;
+
+ if (!(t.specified & GS_SPECIFIED_FAMILY))
+ emacs_abort ();
+
+ bool match_p = true;
+
+ if (dat.specified & GS_SPECIFIED_WIDTH
+ && dat.width != t.width)
+ {
+ match_p = false;
+ goto gout;
+ }
+
+ if (dat.specified & GS_SPECIFIED_WEIGHT
+ && dat.weight != t.weight)
+ {
+ match_p = false;
+ goto gout;
+ }
+
+ if (dat.specified & GS_SPECIFIED_SPACING
+ && dat.monospace_p != t.monospace_p)
+ {
+ match_p = false;
+ goto gout;
+ }
+
+ if (dat.specified & GS_SPECIFIED_SLANT
+ && dat.monospace_p != t.monospace_p)
+ {
+ if (NSFONT_TRACE)
+ printf ("Matching monospace for %s: %d %d\n",
+ t.family_name, dat.monospace_p,
+ t.monospace_p);
+ match_p = false;
+ goto gout;
+ }
+
+ if (dat.specified & GS_SPECIFIED_FAMILY
+ && strcmp (dat.family_name, t.family_name))
+ match_p = false;
+
+ gout:
+ ns_done_font_data (&dat);
+ ns_done_font_data (&t);
+
+ return match_p;
}
+/* Font glyph and metrics caching functions, implemented at end. */
+static void ns_uni_to_glyphs (struct nsfont_info *font_info,
+ unsigned char block);
+static void ns_glyph_metrics (struct nsfont_info *font_info,
+ unsigned int block);
+
+#define INVALID_GLYPH 0xFFFF
+
+/* ==========================================================================
+
+ Utilities
+
+ ========================================================================== */
+
/* Extract family name from a font spec. */
static NSString *
@@ -91,66 +313,116 @@ ns_get_family (Lisp_Object font_spec)
{
char *tmp = xlispstrdup (SYMBOL_NAME (tem));
NSString *family;
- ns_unescape_name (tmp);
family = [NSString stringWithUTF8String: tmp];
xfree (tmp);
return family;
}
}
-
-/* Return 0 if attr not set, else value (which might also be 0).
- On Leopard 0 gets returned even on descriptors where the attribute
- was never set, so there's no way to distinguish between unspecified
- and set to not have. Callers should assume 0 means unspecified. */
-static float
-ns_attribute_fvalue (NSFontDescriptor *fdesc, NSString *trait)
-{
- NSDictionary *tdict = [fdesc objectForKey: NSFontTraitsAttribute];
- NSNumber *val = [tdict objectForKey: trait];
- return val == nil ? 0.0F : [val floatValue];
-}
-
-
/* Converts FONT_WEIGHT, FONT_SLANT, FONT_WIDTH, plus family and script/lang
to NSFont descriptor. Information under extra only needed for matching. */
-#define STYLE_REF 100
static NSFontDescriptor *
ns_spec_to_descriptor (Lisp_Object font_spec)
{
NSFontDescriptor *fdesc;
NSMutableDictionary *fdAttrs = [NSMutableDictionary new];
- NSMutableDictionary *tdict = [NSMutableDictionary new];
NSString *family = ns_get_family (font_spec);
- float n;
-
- /* Add each attr in font_spec to fdAttrs. */
- n = min (FONT_WEIGHT_NUMERIC (font_spec), 200);
- if (n != -1 && n != STYLE_REF)
- [tdict setObject: [NSNumber numberWithFloat: (n - 100.0F) / 100.0F]
- forKey: NSFontWeightTrait];
- n = min (FONT_SLANT_NUMERIC (font_spec), 200);
- if (n != -1 && n != STYLE_REF)
- [tdict setObject: [NSNumber numberWithFloat: (n - 100.0F) / 100.0F]
- forKey: NSFontSlantTrait];
- n = min (FONT_WIDTH_NUMERIC (font_spec), 200);
- if (n > -1 && (n > STYLE_REF + 10 || n < STYLE_REF - 10))
- [tdict setObject: [NSNumber numberWithFloat: (n - 100.0F) / 100.0F]
- forKey: NSFontWidthTrait];
- if ([tdict count] > 0)
- [fdAttrs setObject: tdict forKey: NSFontTraitsAttribute];
+ NSMutableDictionary *tdict = [NSMutableDictionary new];
- fdesc = [[[NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs]
- retain] autorelease];
+ Lisp_Object tem;
+
+ tem = FONT_SLANT_SYMBOLIC (font_spec);
+ if (!NILP (tem))
+ {
+ if (EQ (tem, Qitalic) || EQ (tem, Qoblique))
+ [tdict setObject: [NSNumber numberWithFloat: 1.0]
+ forKey: NSFontSlantTrait];
+ else if (EQ (tem, intern ("reverse-italic")) ||
+ EQ (tem, intern ("reverse-oblique")))
+ [tdict setObject: [NSNumber numberWithFloat: -1.0]
+ forKey: NSFontSlantTrait];
+ else
+ [tdict setObject: [NSNumber numberWithFloat: 0.0]
+ forKey: NSFontSlantTrait];
+ }
+
+ tem = FONT_WIDTH_SYMBOLIC (font_spec);
+ if (!NILP (tem))
+ {
+ if (EQ (tem, Qcondensed))
+ [tdict setObject: [NSNumber numberWithFloat: -1.0]
+ forKey: NSFontWidthTrait];
+ else if (EQ (tem, Qexpanded))
+ [tdict setObject: [NSNumber numberWithFloat: 1.0]
+ forKey: NSFontWidthTrait];
+ else
+ [tdict setObject: [NSNumber numberWithFloat: 0.0]
+ forKey: NSFontWidthTrait];
+ }
+
+ tem = FONT_WEIGHT_SYMBOLIC (font_spec);
+
+ if (!NILP (tem))
+ {
+ if (EQ (tem, Qbold))
+ {
+ [tdict setObject: [NSNumber numberWithFloat: 1.0]
+ forKey: NSFontWeightTrait];
+ }
+ else if (EQ (tem, Qlight))
+ {
+ [tdict setObject: [NSNumber numberWithFloat: -1.0]
+ forKey: NSFontWeightTrait];
+ }
+ else
+ {
+ [tdict setObject: [NSNumber numberWithFloat: 0.0]
+ forKey: NSFontWeightTrait];
+ }
+ }
+
+ tem = AREF (font_spec, FONT_SPACING_INDEX);
if (family != nil)
{
- NSFontDescriptor *fdesc2 = [fdesc fontDescriptorWithFamily: family];
- fdesc = [[fdesc2 retain] autorelease];
+ [fdAttrs setObject: family
+ forKey: NSFontFamilyAttribute];
}
- [fdAttrs release];
+ if (FIXNUMP (tem))
+ {
+ if (XFIXNUM (tem) != FONT_SPACING_PROPORTIONAL)
+ {
+ [fdAttrs setObject: [NSNumber numberWithBool:YES]
+ forKey: NSFontFixedAdvanceAttribute];
+ }
+ else
+ {
+ [fdAttrs setObject: [NSNumber numberWithBool:NO]
+ forKey: NSFontFixedAdvanceAttribute];
+ }
+ }
+
+ /* Handle special families such as ``fixed'' or ``Sans Serif''. */
+
+ if ([family isEqualToString: @"fixed"])
+ {
+ [fdAttrs setObject: [[NSFont userFixedPitchFontOfSize: 0] familyName]
+ forKey: NSFontFamilyAttribute];
+ }
+ else if ([family isEqualToString: @"Sans Serif"])
+ {
+ [fdAttrs setObject: [[NSFont userFontOfSize: 0] familyName]
+ forKey: NSFontFamilyAttribute];
+ }
+
+ [fdAttrs setObject: tdict forKey: NSFontTraitsAttribute];
+
+ fdesc = [[[NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs]
+ retain] autorelease];
+
[tdict release];
+ [fdAttrs release];
return fdesc;
}
@@ -161,61 +433,64 @@ ns_descriptor_to_entity (NSFontDescriptor *desc,
Lisp_Object extra,
const char *style)
{
- Lisp_Object font_entity = font_make_entity ();
- /* NSString *psName = [desc postscriptName]; */
- NSString *family = [desc objectForKey: NSFontFamilyAttribute];
- unsigned int traits = [desc symbolicTraits];
- char *escapedFamily;
-
- /* Shouldn't happen, but on Tiger fallback desc gets name but no family. */
- if (family == nil)
- family = [desc objectForKey: NSFontNameAttribute];
- if (family == nil)
- family = [[NSFont userFixedPitchFontOfSize: 0] familyName];
-
- escapedFamily = xstrdup ([family UTF8String]);
- ns_escape_name (escapedFamily);
-
- ASET (font_entity, FONT_TYPE_INDEX, Qns);
- ASET (font_entity, FONT_FOUNDRY_INDEX, Qapple);
- ASET (font_entity, FONT_FAMILY_INDEX, intern (escapedFamily));
- ASET (font_entity, FONT_ADSTYLE_INDEX, style ? intern (style) : Qnil);
- ASET (font_entity, FONT_REGISTRY_INDEX, Qiso10646_1);
-
- FONT_SET_STYLE (font_entity, FONT_WEIGHT_INDEX,
- traits & NSFontBoldTrait ? Qbold : Qmedium);
-/* FONT_SET_STYLE (font_entity, FONT_WEIGHT_INDEX,
- make_fixnum (100 + 100
- * ns_attribute_fvalue (desc, NSFontWeightTrait)));*/
- FONT_SET_STYLE (font_entity, FONT_SLANT_INDEX,
- traits & NSFontItalicTrait ? Qitalic : Qnormal);
-/* FONT_SET_STYLE (font_entity, FONT_SLANT_INDEX,
- make_fixnum (100 + 100
- * ns_attribute_fvalue (desc, NSFontSlantTrait)));*/
- FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX,
- traits & NSFontCondensedTrait ? Qcondensed :
- traits & NSFontExpandedTrait ? Qexpanded : Qnormal);
-/* FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX,
- make_fixnum (100 + 100
- * ns_attribute_fvalue (desc, NSFontWidthTrait)));*/
-
- ASET (font_entity, FONT_SIZE_INDEX, make_fixnum (0));
- ASET (font_entity, FONT_AVGWIDTH_INDEX, make_fixnum (0));
- ASET (font_entity, FONT_SPACING_INDEX,
- make_fixnum([desc symbolicTraits] & NSFontMonoSpaceTrait
- ? FONT_SPACING_MONO : FONT_SPACING_PROPORTIONAL));
-
- ASET (font_entity, FONT_EXTRA_INDEX, extra);
- ASET (font_entity, FONT_OBJLIST_INDEX, Qnil);
+ Lisp_Object font_entity = font_make_entity ();
+ struct gs_font_data data;
+ ns_get_font_data (desc, &data);
+
+ ASET (font_entity, FONT_TYPE_INDEX, Qns);
+ ASET (font_entity, FONT_FOUNDRY_INDEX, Qns);
+ if (data.specified & GS_SPECIFIED_FAMILY)
+ ASET (font_entity, FONT_FAMILY_INDEX, intern (data.family_name));
+ ASET (font_entity, FONT_ADSTYLE_INDEX, style ? intern (style) : Qnil);
+ ASET (font_entity, FONT_REGISTRY_INDEX, Qiso10646_1);
+
+ if (data.specified & GS_SPECIFIED_WEIGHT)
+ {
+ FONT_SET_STYLE (font_entity, FONT_WEIGHT_INDEX,
+ data.weight == GS_FONT_WEIGHT_BOLD
+ ? Qbold : (data.weight == GS_FONT_WEIGHT_LIGHT
+ ? Qlight : Qnormal));
+ }
+ else
+ FONT_SET_STYLE (font_entity, FONT_WEIGHT_INDEX, Qnormal);
- if (NSFONT_TRACE)
- {
- fputs ("created font_entity:\n ", stderr);
- debug_print (font_entity);
- }
+ if (data.specified & GS_SPECIFIED_SLANT)
+ {
+ FONT_SET_STYLE (font_entity, FONT_SLANT_INDEX,
+ data.slant == GS_FONT_SLANT_ITALIC
+ ? Qitalic : (data.slant == GS_FONT_SLANT_REVERSE_ITALIC
+ ? intern ("reverse-italic") : Qnormal));
+ }
+ else
+ FONT_SET_STYLE (font_entity, FONT_SLANT_INDEX, Qnormal);
+
+ if (data.specified & GS_SPECIFIED_WIDTH)
+ {
+ FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX,
+ data.width == GS_FONT_WIDTH_CONDENSED
+ ? Qcondensed : (data.width == GS_FONT_WIDTH_EXPANDED
+ ? intern ("expanded") : Qnormal));
+ }
+ else
+ FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX, Qnormal);
- xfree (escapedFamily);
- return font_entity;
+ ASET (font_entity, FONT_SIZE_INDEX, make_fixnum (0));
+ ASET (font_entity, FONT_AVGWIDTH_INDEX, make_fixnum (0));
+ ASET (font_entity, FONT_SPACING_INDEX,
+ make_fixnum ((data.specified & GS_SPECIFIED_WIDTH && data.monospace_p)
+ ? FONT_SPACING_MONO : FONT_SPACING_PROPORTIONAL));
+
+ ASET (font_entity, FONT_EXTRA_INDEX, extra);
+ ASET (font_entity, FONT_OBJLIST_INDEX, Qnil);
+
+ if (NSFONT_TRACE)
+ {
+ fputs ("created font_entity:\n ", stderr);
+ debug_print (font_entity);
+ }
+
+ ns_done_font_data (&data);
+ return font_entity;
}
@@ -223,8 +498,7 @@ ns_descriptor_to_entity (NSFontDescriptor *desc,
static Lisp_Object
ns_fallback_entity (void)
{
- return ns_descriptor_to_entity ([[NSFont userFixedPitchFontOfSize: 0]
- fontDescriptor], Qnil, NULL);
+ return ns_descriptor_to_entity ([[NSFont userFixedPitchFontOfSize: 1] fontDescriptor], Qnil, NULL);
}
@@ -510,21 +784,20 @@ static NSSet
return families;
}
+/* GNUstep font matching is very mediocre (it can't even compare
+ symbolic styles correctly), which is why our own font matching
+ mechanism must be implemented. */
-/* Implementation for list() and match(). List() can return nil, match()
-must return something. Strategy is to drop family name from attribute
-matching set for match. */
+/* Implementation for list and match. */
static Lisp_Object
ns_findfonts (Lisp_Object font_spec, BOOL isMatch)
{
Lisp_Object tem, list = Qnil;
- NSFontDescriptor *fdesc, *desc;
- NSMutableSet *fkeys;
- NSArray *matchingDescs;
- NSEnumerator *dEnum;
- NSString *family;
+ NSFontDescriptor *fdesc;
+ NSArray *all_descs;
+ GSFontEnumerator *enumerator = [GSFontEnumerator sharedEnumerator];
+
NSSet *cFamilies;
- BOOL foundItal = NO;
block_input ();
if (NSFONT_TRACE)
@@ -537,43 +810,22 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch)
cFamilies = ns_get_covering_families (ns_get_req_script (font_spec), 0.90);
fdesc = ns_spec_to_descriptor (font_spec);
- fkeys = [NSMutableSet setWithArray: [[fdesc fontAttributes] allKeys]];
- if (isMatch)
- [fkeys removeObject: NSFontFamilyAttribute];
-
- matchingDescs = [fdesc matchingFontDescriptorsWithMandatoryKeys: fkeys];
+ all_descs = [enumerator availableFontDescriptors];
- if (NSFONT_TRACE)
- NSLog(@"Got desc %@ and found %lu matching fonts from it: ", fdesc,
- (unsigned long)[matchingDescs count]);
-
- for (dEnum = [matchingDescs objectEnumerator]; (desc = [dEnum nextObject]);)
+ for (NSFontDescriptor *desc in all_descs)
{
if (![cFamilies containsObject:
[desc objectForKey: NSFontFamilyAttribute]])
continue;
+ if (!ns_font_descs_match_p (fdesc, desc))
+ continue;
+
tem = ns_descriptor_to_entity (desc,
- AREF (font_spec, FONT_EXTRA_INDEX),
+ AREF (font_spec, FONT_EXTRA_INDEX),
NULL);
if (isMatch)
return tem;
list = Fcons (tem, list);
- if (fabs (ns_attribute_fvalue (desc, NSFontSlantTrait)) > 0.05)
- foundItal = YES;
- }
-
- /* Add synthItal member if needed. */
- family = [fdesc objectForKey: NSFontFamilyAttribute];
- if (family != nil && !foundItal && !NILP (list))
- {
- NSFontDescriptor *s1 = [NSFontDescriptor new];
- NSFontDescriptor *sDesc
- = [[s1 fontDescriptorWithSymbolicTraits: NSFontItalicTrait]
- fontDescriptorWithFamily: family];
- list = Fcons (ns_descriptor_to_entity (sDesc,
- AREF (font_spec, FONT_EXTRA_INDEX),
- "synthItal"), list);
- [s1 release];
}
unblock_input ();
@@ -652,7 +904,6 @@ nsfont_list_family (struct frame *f)
objectEnumerator];
while ((family = [families nextObject]))
list = Fcons (intern ([family UTF8String]), list);
- /* FIXME: escape the name? */
if (NSFONT_TRACE)
fprintf (stderr, "nsfont: list families returning %"pD"d entries\n",
@@ -668,18 +919,15 @@ nsfont_list_family (struct frame *f)
static Lisp_Object
nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size)
{
- BOOL synthItal;
- unsigned int traits = 0;
struct nsfont_info *font_info;
struct font *font;
NSFontDescriptor *fontDesc = ns_spec_to_descriptor (font_entity);
NSFontManager *fontMgr = [NSFontManager sharedFontManager];
NSString *family;
NSFont *nsfont, *sfont;
- Lisp_Object tem;
NSRect brect;
Lisp_Object font_object;
- int fixLeopardBug;
+ Lisp_Object tem;
block_input ();
@@ -692,42 +940,20 @@ nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size)
if (pixel_size <= 0)
{
/* try to get it out of frame params */
- Lisp_Object tem = get_frame_param (f, Qfontsize);
- pixel_size = NILP (tem) ? 0 : XFIXNAT (tem);
+ tem = get_frame_param (f, Qfontsize);
+ pixel_size = NILP (tem) ? 0 : XFIXNAT (tem);
}
tem = AREF (font_entity, FONT_ADSTYLE_INDEX);
- synthItal = !NILP (tem) && !strncmp ("synthItal", SSDATA (SYMBOL_NAME (tem)),
- 9);
family = ns_get_family (font_entity);
if (family == nil)
family = [[NSFont userFixedPitchFontOfSize: 0] familyName];
- /* Should be > 0.23 as some font descriptors (e.g. Terminus) set to that
- when setting family in ns_spec_to_descriptor(). */
- if (ns_attribute_fvalue (fontDesc, NSFontWeightTrait) > 0.50F)
- traits |= NSBoldFontMask;
- if (ns_attribute_fvalue (fontDesc, NSFontSlantTrait) > 0.05F)
- traits |= NSItalicFontMask;
-
- /* see https://web.archive.org/web/20100201175731/http://cocoadev.com/forums/comments.php?DiscussionID=74 */
- fixLeopardBug = traits & NSBoldFontMask ? 10 : 5;
- nsfont = [fontMgr fontWithFamily: family
- traits: traits weight: fixLeopardBug
- size: pixel_size];
- /* if didn't find, try synthetic italic */
- if (nsfont == nil && synthItal)
- {
- nsfont = [fontMgr fontWithFamily: family
- traits: traits & ~NSItalicFontMask
- weight: fixLeopardBug size: pixel_size];
- }
+
+ nsfont = [NSFont fontWithDescriptor: fontDesc
+ size: pixel_size];
if (nsfont == nil)
- {
- message_with_string ("*** Warning: font in family `%s' not found",
- build_string ([family UTF8String]), 1);
- nsfont = [NSFont userFixedPitchFontOfSize: pixel_size];
- }
+ nsfont = [NSFont userFixedPitchFontOfSize: pixel_size];
if (NSFONT_TRACE)
NSLog (@"%@\n", nsfont);
@@ -740,7 +966,7 @@ nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size)
if (!font)
{
unblock_input ();
- return Qnil; /* FIXME: other terms do, but returning Qnil causes segfault. */
+ return Qnil;
}
font_info->glyphs = xzalloc (0x100 * sizeof *font_info->glyphs);
@@ -781,7 +1007,7 @@ nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size)
font_info->name = xstrdup (fontName);
font_info->bold = [fontMgr traitsOfFont: nsfont] & NSBoldFontMask;
font_info->ital =
- synthItal || ([fontMgr traitsOfFont: nsfont] & NSItalicFontMask);
+ ([fontMgr traitsOfFont: nsfont] & NSItalicFontMask);
/* Metrics etc.; some fonts return an unusually large max advance, so we
only use it for fonts that have wide characters. */
@@ -808,8 +1034,6 @@ nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size)
lrint (brect.size.width - (CGFloat) font_info->width);
/* set up metrics portion of font struct */
- font->ascent = lrint([sfont ascender]);
- font->descent = -lrint(floor(adjusted_descender));
font->space_width = lrint (ns_char_width (sfont, ' '));
font->max_width = lrint (font_info->max_bounds.width);
font->min_width = font->space_width; /* Approximate. */
@@ -871,7 +1095,7 @@ nsfont_encode_char (struct font *font, int c)
{
struct nsfont_info *font_info = (struct nsfont_info *)font;
unsigned char high = (c & 0xff00) >> 8, low = c & 0x00ff;
- unsigned short g;
+ unsigned int g;
if (c > 0xFFFF)
return FONT_INVALID_CODE;
@@ -934,51 +1158,23 @@ nsfont_text_extents (struct font *font, const unsigned int *code,
static int
nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
bool with_background)
-/* NOTE: focus and clip must be set. */
{
- static unsigned char cbuf[1024];
- unsigned char *c = cbuf;
-#if GNUSTEP_GUI_MAJOR_VERSION > 0 || GNUSTEP_GUI_MINOR_VERSION > 22
- static CGFloat advances[1024];
- CGFloat *adv = advances;
-#else
- static float advances[1024];
- float *adv = advances;
-#endif
+ NSGlyph *c = alloca ((to - from) * sizeof *c);
+
struct face *face;
NSRect r;
struct nsfont_info *font;
- NSColor *col, *bgCol;
- unsigned *t = s->char2b;
- int i, len, flags;
+ NSColor *col;
+ int len = to - from;
char isComposite = s->first_glyph->type == COMPOSITE_GLYPH;
block_input ();
- font = (struct nsfont_info *)s->face->font;
+ font = (struct nsfont_info *) s->font;
if (font == NULL)
font = (struct nsfont_info *)FRAME_FONT (s->f);
- /* Select face based on input flags. */
- flags = s->hl == DRAW_CURSOR ? NS_DUMPGLYPH_CURSOR :
- (s->hl == DRAW_MOUSE_FACE ? NS_DUMPGLYPH_MOUSEFACE :
- (s->for_overlaps ? NS_DUMPGLYPH_FOREGROUND :
- NS_DUMPGLYPH_NORMAL));
-
- switch (flags)
- {
- case NS_DUMPGLYPH_CURSOR:
- face = s->face;
- break;
- case NS_DUMPGLYPH_MOUSEFACE:
- face = FACE_FROM_ID_OR_NULL (s->f,
- MOUSE_HL_INFO (s->f)->mouse_face_face_id);
- if (!face)
- face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
- break;
- default:
- face = s->face;
- }
+ face = s->face;
r.origin.x = s->x;
if (s->face->box != FACE_NO_BOX && s->first_glyph->left_box_line_p)
@@ -987,91 +1183,24 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
r.origin.y = s->y;
r.size.height = FONT_HEIGHT (font);
- /* Convert UTF-16 (?) to UTF-8 and determine advances. Note if we just ask
- NS to render the string, it will come out differently from the individual
- character widths added up because of layout processing. */
- {
- int cwidth, twidth = 0;
- int hi, lo;
- /* FIXME: composition: no vertical displacement is considered. */
- t += from; /* advance into composition */
- for (i = from; i < to; i++, t++)
- {
- hi = (*t & 0xFF00) >> 8;
- lo = *t & 0x00FF;
- if (isComposite)
- {
- if (!s->first_glyph->u.cmp.automatic)
- cwidth = s->cmp->offsets[i * 2] /* (H offset) */ - twidth;
- else
- {
- Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
- Lisp_Object glyph = LGSTRING_GLYPH (gstring, i);
- if (NILP (LGLYPH_ADJUSTMENT (glyph)))
- cwidth = LGLYPH_WIDTH (glyph);
- else
- {
- cwidth = LGLYPH_WADJUST (glyph);
- *(adv-1) += LGLYPH_XOFF (glyph);
- }
- }
- }
- else
- {
- if (!font->metrics[hi]) /* FIXME: why/how can we need this now? */
- ns_glyph_metrics (font, hi);
- cwidth = font->metrics[hi][lo].width;
- }
- twidth += cwidth;
- *adv++ = cwidth;
- c += CHAR_STRING (*t, c); /* This converts the char to UTF-8. */
- }
- len = adv - advances;
- r.size.width = twidth;
- *c = 0;
- }
+ for (int i = from; i < to; ++i)
+ c[i] = s->char2b[i];
/* Fill background if requested. */
if (with_background && !isComposite)
{
- NSRect br = r;
- int fibw = FRAME_INTERNAL_BORDER_WIDTH (s->f);
- int mbox_line_width = max (s->face->box_vertical_line_width, 0);
-
- if (s->row->full_width_p)
- {
- if (br.origin.x <= fibw + 1 + mbox_line_width)
- {
- br.size.width += br.origin.x - mbox_line_width;
- br.origin.x = mbox_line_width;
- }
- if (FRAME_PIXEL_WIDTH (s->f) - (br.origin.x + br.size.width)
- <= fibw+1)
- br.size.width += fibw;
- }
- if (s->face->box == FACE_NO_BOX)
- {
- /* Expand unboxed top row over internal border. */
- if (br.origin.y <= fibw + 1 + mbox_line_width)
- {
- br.size.height += br.origin.y;
- br.origin.y = 0;
- }
- }
- else
- {
- int correction = abs (s->face->box_horizontal_line_width)+1;
- br.origin.y += correction;
- br.size.height -= 2*correction;
- correction = abs (s->face->box_vertical_line_width)+1;
- br.origin.x += correction;
- br.size.width -= 2*correction;
- }
+ NSRect br = NSMakeRect (x, y - FONT_BASE (s->font),
+ s->width, FONT_HEIGHT (s->font));
if (!s->face->stipple)
- [(NS_FACE_BACKGROUND (face) != 0
- ? ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f)
- : FRAME_BACKGROUND_COLOR (s->f)) set];
+ {
+ if (s->hl != DRAW_CURSOR)
+ [(NS_FACE_BACKGROUND (face) != 0
+ ? ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f)
+ : FRAME_BACKGROUND_COLOR (s->f)) set];
+ else
+ [FRAME_CURSOR_COLOR (s->f) set];
+ }
else
{
struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
@@ -1080,43 +1209,32 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
NSRectFill (br);
}
-
/* set up for character rendering */
r.origin.y = y;
- col = (NS_FACE_FOREGROUND (face) != 0
- ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f)
- : FRAME_FOREGROUND_COLOR (s->f));
-
- bgCol = (flags != NS_DUMPGLYPH_FOREGROUND ? nil
- : (NS_FACE_BACKGROUND (face) != 0
- ? ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f)
- : FRAME_BACKGROUND_COLOR (s->f)));
+ if (s->hl == DRAW_CURSOR)
+ col = FRAME_BACKGROUND_COLOR (s->f);
+ else
+ col = (NS_FACE_FOREGROUND (face) != 0
+ ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f)
+ : FRAME_FOREGROUND_COLOR (s->f));
/* render under GNUstep using DPS */
{
- NSGraphicsContext *context = GSCurrentContext ();
-
+ NSGraphicsContext *context = [NSGraphicsContext currentContext];
DPSgsave (context);
- [font->nsfont set];
-
- /* do erase if "foreground" mode */
- if (bgCol != nil)
+ if (s->clip_head)
{
- [bgCol set];
- DPSmoveto (context, r.origin.x, r.origin.y);
-/*[context GSSetTextDrawingMode: GSTextFillStroke]; /// not implemented yet */
- DPSxshow (context, (const char *) cbuf, advances, len);
- DPSstroke (context);
- [col set];
-/*[context GSSetTextDrawingMode: GSTextFill]; /// not implemented yet */
+ DPSrectclip (context, s->clip_head->x, 0,
+ FRAME_PIXEL_WIDTH (s->f),
+ FRAME_PIXEL_HEIGHT (s->f));
}
+ [font->nsfont set];
[col set];
- /* draw with DPSxshow () */
DPSmoveto (context, r.origin.x, r.origin.y);
- DPSxshow (context, (const char *) cbuf, advances, len);
+ GSShowGlyphs (context, c, len);
DPSstroke (context);
DPSgrestore (context);
@@ -1126,6 +1244,360 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
return to-from;
}
+static NSUInteger
+ns_font_shape (NSFont *font, NSString *string,
+ struct ns_glyph_layout *glyph_layouts, NSUInteger glyph_len,
+ enum lgstring_direction dir)
+{
+ NSUInteger i;
+ NSUInteger result = 0;
+ NSTextStorage *textStorage;
+ NSLayoutManager *layoutManager;
+ NSTextContainer *textContainer;
+ NSUInteger stringLength;
+ NSPoint spaceLocation;
+ /* numberOfGlyphs can't actually be 0, but this pacifies GCC */
+ NSUInteger used, numberOfGlyphs = 0;
+
+ textStorage = [[NSTextStorage alloc] initWithString:string];
+ layoutManager = [[NSLayoutManager alloc] init];
+ textContainer = [[NSTextContainer alloc] init];
+
+ /* Append a trailing space to measure baseline position. */
+ [textStorage appendAttributedString:([[[NSAttributedString alloc]
+ initWithString:@" "] autorelease])];
+ [textStorage setFont:font];
+ [textContainer setLineFragmentPadding:0];
+
+ [layoutManager addTextContainer:textContainer];
+ [textContainer release];
+ [textStorage addLayoutManager:layoutManager];
+ [layoutManager release];
+
+ if (!(textStorage && layoutManager && textContainer))
+ emacs_abort ();
+
+ stringLength = [string length];
+
+ /* Force layout. */
+ (void) [layoutManager glyphRangeForTextContainer:textContainer];
+
+ spaceLocation = [layoutManager locationForGlyphAtIndex:stringLength];
+
+ /* Remove the appended trailing space because otherwise it may
+ generate a wrong result for a right-to-left text. */
+ [textStorage beginEditing];
+ [textStorage deleteCharactersInRange:(NSMakeRange (stringLength, 1))];
+ [textStorage endEditing];
+ (void) [layoutManager glyphRangeForTextContainer:textContainer];
+
+ i = 0;
+ while (i < stringLength)
+ {
+ NSRange range;
+ NSFont *fontInTextStorage =
+ [textStorage attribute: NSFontAttributeName
+ atIndex:i
+ longestEffectiveRange: &range
+ inRange: NSMakeRange (0, stringLength)];
+
+ if (!(fontInTextStorage == font
+ || [[fontInTextStorage fontName] isEqualToString:[font fontName]]))
+ break;
+ i = NSMaxRange (range);
+ }
+ if (i < stringLength)
+ /* Make the test `used <= glyph_len' below fail if textStorage
+ contained some fonts other than the specified one. */
+ used = glyph_len + 1;
+ else
+ {
+ NSRange range = NSMakeRange (0, stringLength);
+
+ range = [layoutManager glyphRangeForCharacterRange:range
+ actualCharacterRange:NULL];
+ numberOfGlyphs = NSMaxRange (range);
+ used = numberOfGlyphs;
+ for (i = 0; i < numberOfGlyphs; i++)
+ if ([layoutManager notShownAttributeForGlyphAtIndex:i])
+ used--;
+ }
+
+ if (0 < used && used <= glyph_len)
+ {
+ NSUInteger glyphIndex, prevGlyphIndex;
+ NSUInteger *permutation;
+ NSRange compRange, range;
+ CGFloat totalAdvance;
+
+ glyphIndex = 0;
+ while ([layoutManager notShownAttributeForGlyphAtIndex:glyphIndex])
+ glyphIndex++;
+
+ permutation = NULL;
+#define RIGHT_TO_LEFT_P permutation
+
+ /* Fill the `comp_range' member of struct mac_glyph_layout, and
+ setup a permutation for right-to-left text. */
+ compRange = NSMakeRange (0, 0);
+ for (range = NSMakeRange (0, 0); NSMaxRange (range) < used;
+ range.length++)
+ {
+ struct ns_glyph_layout *gl = glyph_layouts + NSMaxRange (range);
+ NSUInteger characterIndex =
+ [layoutManager characterIndexForGlyphAtIndex:glyphIndex];
+
+ gl->string_index = characterIndex;
+
+ if (characterIndex >= NSMaxRange (compRange))
+ {
+ compRange.location = NSMaxRange (compRange);
+ do
+ {
+ NSRange characterRange =
+ [string
+ rangeOfComposedCharacterSequenceAtIndex:characterIndex];
+
+ compRange.length =
+ NSMaxRange (characterRange) - compRange.location;
+ [layoutManager glyphRangeForCharacterRange:compRange
+ actualCharacterRange:&characterRange];
+ characterIndex = NSMaxRange (characterRange) - 1;
+ }
+ while (characterIndex >= NSMaxRange (compRange));
+
+ if (RIGHT_TO_LEFT_P)
+ for (i = 0; i < range.length; i++)
+ permutation[range.location + i] = NSMaxRange (range) - i - 1;
+
+ range = NSMakeRange (NSMaxRange (range), 0);
+ }
+
+ gl->comp_range.location = compRange.location;
+ gl->comp_range.length = compRange.length;
+
+ while (++glyphIndex < numberOfGlyphs)
+ if (![layoutManager notShownAttributeForGlyphAtIndex:glyphIndex])
+ break;
+ }
+ if (RIGHT_TO_LEFT_P)
+ for (i = 0; i < range.length; i++)
+ permutation[range.location + i] = NSMaxRange (range) - i - 1;
+
+ /* Then fill the remaining members. */
+ glyphIndex = prevGlyphIndex = 0;
+ while ([layoutManager notShownAttributeForGlyphAtIndex:glyphIndex])
+ glyphIndex++;
+
+ if (!RIGHT_TO_LEFT_P)
+ totalAdvance = 0;
+ else
+ {
+ NSUInteger nrects;
+ NSRect *glyphRects =
+ [layoutManager
+ rectArrayForGlyphRange:(NSMakeRange (0, numberOfGlyphs))
+ withinSelectedGlyphRange:(NSMakeRange (NSNotFound, 0))
+ inTextContainer:textContainer rectCount:&nrects];
+
+ totalAdvance = NSMaxX (glyphRects[0]);
+ }
+
+ for (i = 0; i < used; i++)
+ {
+ struct ns_glyph_layout *gl;
+ NSPoint location;
+ NSUInteger nextGlyphIndex;
+ NSRange glyphRange;
+ NSRect *glyphRects;
+ NSUInteger nrects;
+
+ if (!RIGHT_TO_LEFT_P)
+ gl = glyph_layouts + i;
+ else
+ {
+ NSUInteger dest = permutation[i];
+
+ gl = glyph_layouts + dest;
+ if (i < dest)
+ {
+ NSUInteger tmp = gl->string_index;
+
+ gl->string_index = glyph_layouts[i].string_index;
+ glyph_layouts[i].string_index = tmp;
+ }
+ }
+ gl->glyph_id = [layoutManager glyphAtIndex: glyphIndex];
+
+ location = [layoutManager locationForGlyphAtIndex:glyphIndex];
+ gl->baseline_delta = spaceLocation.y - location.y;
+
+ for (nextGlyphIndex = glyphIndex + 1; nextGlyphIndex < numberOfGlyphs;
+ nextGlyphIndex++)
+ if (![layoutManager
+ notShownAttributeForGlyphAtIndex:nextGlyphIndex])
+ break;
+
+ if (!RIGHT_TO_LEFT_P)
+ {
+ CGFloat maxX;
+
+ if (prevGlyphIndex == 0)
+ glyphRange = NSMakeRange (0, nextGlyphIndex);
+ else
+ glyphRange = NSMakeRange (glyphIndex,
+ nextGlyphIndex - glyphIndex);
+ glyphRects =
+ [layoutManager
+ rectArrayForGlyphRange:glyphRange
+ withinSelectedGlyphRange:(NSMakeRange (NSNotFound, 0))
+ inTextContainer:textContainer rectCount:&nrects];
+ maxX = max (NSMaxX (glyphRects[0]), totalAdvance);
+ gl->advance_delta = location.x - totalAdvance;
+ gl->advance = maxX - totalAdvance;
+ totalAdvance = maxX;
+ }
+ else
+ {
+ CGFloat minX;
+
+ if (nextGlyphIndex == numberOfGlyphs)
+ glyphRange = NSMakeRange (prevGlyphIndex,
+ numberOfGlyphs - prevGlyphIndex);
+ else
+ glyphRange = NSMakeRange (prevGlyphIndex,
+ glyphIndex + 1 - prevGlyphIndex);
+ glyphRects =
+ [layoutManager
+ rectArrayForGlyphRange:glyphRange
+ withinSelectedGlyphRange:(NSMakeRange (NSNotFound, 0))
+ inTextContainer:textContainer rectCount:&nrects];
+ minX = min (NSMinX (glyphRects[0]), totalAdvance);
+ gl->advance = totalAdvance - minX;
+ totalAdvance = minX;
+ gl->advance_delta = location.x - totalAdvance;
+ }
+
+ prevGlyphIndex = glyphIndex + 1;
+ glyphIndex = nextGlyphIndex;
+ }
+
+ if (RIGHT_TO_LEFT_P)
+ xfree (permutation);
+
+#undef RIGHT_TO_LEFT_P
+
+ result = used;
+ }
+ [textStorage release];
+
+ return result;
+}
+
+static Lisp_Object
+nsfont_shape (Lisp_Object lgstring, Lisp_Object direction)
+{
+ struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
+ struct nsfont_info *font_info = (struct nsfont_info *) font;
+ struct ns_glyph_layout *glyph_layouts;
+ NSFont *nsfont = font_info->nsfont;
+ ptrdiff_t glyph_len, len, i;
+ Lisp_Object tem;
+ unichar *mb_buf;
+ NSUInteger used;
+
+ glyph_len = LGSTRING_GLYPH_LEN (lgstring);
+ for (i = 0; i < glyph_len; ++i)
+ {
+ tem = LGSTRING_GLYPH (lgstring, i);
+
+ if (NILP (tem))
+ break;
+ }
+
+ len = i;
+
+ if (INT_MAX / 2 < len)
+ memory_full (SIZE_MAX);
+
+ block_input ();
+
+ mb_buf = alloca (len * sizeof *mb_buf);
+
+ for (i = 0; i < len; ++i)
+ {
+ uint32_t c = LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, i));
+ mb_buf[i] = (unichar) c;
+ }
+
+ NSString *string = [NSString stringWithCharacters: mb_buf
+ length: len];
+ unblock_input ();
+
+ if (!string)
+ return Qnil;
+
+ block_input ();
+
+ enum lgstring_direction dir = DIR_UNKNOWN;
+
+ if (EQ (direction, QL2R))
+ dir = DIR_L2R;
+ else if (EQ (direction, QR2L))
+ dir = DIR_R2L;
+ glyph_layouts = alloca (sizeof (struct ns_glyph_layout) * glyph_len);
+ used = ns_font_shape (nsfont, string, glyph_layouts, glyph_len, dir);
+
+ for (i = 0; i < used; i++)
+ {
+ Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
+ struct ns_glyph_layout *gl = glyph_layouts + i;
+ EMACS_INT from, to;
+ struct font_metrics metrics;
+
+ if (NILP (lglyph))
+ {
+ lglyph = LGLYPH_NEW ();
+ LGSTRING_SET_GLYPH (lgstring, i, lglyph);
+ }
+
+ from = gl->comp_range.location;
+ LGLYPH_SET_FROM (lglyph, from);
+
+ to = gl->comp_range.location + gl->comp_range.length;
+ LGLYPH_SET_TO (lglyph, to - 1);
+
+ /* LGLYPH_CHAR is used in `describe-char' for checking whether
+ the composition is trivial. */
+ {
+ UTF32Char c;
+
+ if (mb_buf[gl->string_index] >= 0xD800
+ && mb_buf[gl->string_index] < 0xDC00)
+ c = (((mb_buf[gl->string_index] - 0xD800) << 10)
+ + (mb_buf[gl->string_index + 1] - 0xDC00) + 0x10000);
+ else
+ c = mb_buf[gl->string_index];
+
+ LGLYPH_SET_CHAR (lglyph, c);
+ }
+
+ {
+ unsigned long cc = gl->glyph_id;
+ LGLYPH_SET_CODE (lglyph, cc);
+ }
+
+ nsfont_text_extents (font, &gl->glyph_id, 1, &metrics);
+ LGLYPH_SET_WIDTH (lglyph, metrics.width);
+ LGLYPH_SET_LBEARING (lglyph, metrics.lbearing);
+ LGLYPH_SET_RBEARING (lglyph, metrics.rbearing);
+ LGLYPH_SET_ASCENT (lglyph, metrics.ascent);
+ LGLYPH_SET_DESCENT (lglyph, metrics.descent);
+ }
+ unblock_input ();
+
+ return make_fixnum (used);
+}
/* ==========================================================================
@@ -1134,6 +1606,50 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
========================================================================== */
+static NSGlyph
+ns_uni_to_glyphs_1 (struct nsfont_info *info, unsigned int c)
+{
+ unichar characters[] = { c };
+ NSString *string =
+ [NSString stringWithCharacters: characters
+ length: 1];
+ NSDictionary *attributes =
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ info->nsfont, NSFontAttributeName, nil];
+ NSTextStorage *storage = [[NSTextStorage alloc] initWithString: string
+ attributes: attributes];
+ NSTextContainer *text_container = [[NSTextContainer alloc] init];
+ NSLayoutManager *manager = [[NSLayoutManager alloc] init];
+
+ [manager addTextContainer: text_container];
+ [text_container release]; /* Retained by manager */
+ [storage addLayoutManager: manager];
+ [manager release]; /* Retained by storage */
+
+ NSFont *font_in_storage = [storage attribute: NSFontAttributeName
+ atIndex:0
+ effectiveRange: NULL];
+ NSGlyph glyph = FONT_INVALID_CODE;
+
+ if ((font_in_storage == info->nsfont
+ || [[font_in_storage fontName] isEqualToString: [info->nsfont fontName]]))
+ {
+ @try
+ {
+ glyph = [manager glyphAtIndex: 0];
+ }
+ @catch (NSException *e)
+ {
+ /* GNUstep bug? */
+ glyph = 'X';
+ }
+ }
+
+ [storage release];
+
+ return glyph;
+}
+
/* Find and cache corresponding glyph codes for unicode values in given
hi-byte block of 256. */
static void
@@ -1141,7 +1657,7 @@ ns_uni_to_glyphs (struct nsfont_info *font_info, unsigned char block)
{
unichar *unichars = xmalloc (0x101 * sizeof (unichar));
unsigned int i, g, idx;
- unsigned short *glyphs;
+ unsigned int *glyphs;
if (NSFONT_TRACE)
fprintf (stderr, "%p\tFinding glyphs for glyphs in block %d\n",
@@ -1149,7 +1665,7 @@ ns_uni_to_glyphs (struct nsfont_info *font_info, unsigned char block)
block_input ();
- font_info->glyphs[block] = xmalloc (0x100 * sizeof (unsigned short));
+ font_info->glyphs[block] = xmalloc (0x100 * sizeof (unsigned int));
if (!unichars || !(font_info->glyphs[block]))
emacs_abort ();
@@ -1166,7 +1682,8 @@ ns_uni_to_glyphs (struct nsfont_info *font_info, unsigned char block)
for (i = 0; i < 0x100; i++, glyphs++)
{
g = unichars[i];
- *glyphs = g;
+ NSGlyph glyph = ns_uni_to_glyphs_1 (font_info, g);
+ *glyphs = glyph;
}
}
@@ -1175,18 +1692,19 @@ ns_uni_to_glyphs (struct nsfont_info *font_info, unsigned char block)
}
-/* Determine and cache metrics for corresponding glyph codes in given
- hi-byte block of 256. */
+/* Determine and cache metrics for glyphs in given hi-byte block of
+ 256. */
static void
-ns_glyph_metrics (struct nsfont_info *font_info, unsigned char block)
+ns_glyph_metrics (struct nsfont_info *font_info, unsigned int block)
{
- unsigned int i, g;
+ unsigned int i;
+ NSGlyph g;
unsigned int numGlyphs = [font_info->nsfont numberOfGlyphs];
NSFont *sfont;
struct font_metrics *metrics;
if (NSFONT_TRACE)
- fprintf (stderr, "%p\tComputing metrics for glyphs in block %d\n",
+ fprintf (stderr, "%p\tComputing metrics for glyphs in block %u\n",
font_info, block);
/* not implemented yet (as of startup 0.18), so punt */
@@ -1209,19 +1727,14 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned char block)
w = max ([sfont advancementForGlyph: g].width, 2.0);
metrics->width = lrint (w);
- lb = r.origin.x;
- rb = r.size.width - w;
- // Add to bearing for LCD smoothing. We don't know if it is there.
- if (lb < 0)
- metrics->lbearing = round (lb - LCD_SMOOTHING_MARGIN);
- if (font_info->ital)
- rb += (CGFloat) (0.22F * font_info->height);
- metrics->rbearing = lrint (w + rb + LCD_SMOOTHING_MARGIN);
-
- metrics->descent = r.origin.y < 0 ? -r.origin.y : 0;
- /* lrint (hshrink * [sfont ascender] + expand * hd/2); */
- metrics->ascent = r.size.height - metrics->descent;
- /* -lrint (hshrink* [sfont descender] - expand * hd/2); */
+ lb = NSMinX (r);
+ rb = NSMaxX (r);
+
+ metrics->rbearing = lrint (rb);
+ metrics->lbearing = lrint (lb);
+
+ metrics->descent = NSMinY (r);
+ metrics->ascent = NSMaxY (r);
}
unblock_input ();
}
@@ -1257,6 +1770,7 @@ struct font_driver const nsfont_driver =
.has_char = nsfont_has_char,
.encode_char = nsfont_encode_char,
.text_extents = nsfont_text_extents,
+ .shape = nsfont_shape,
.draw = nsfont_draw,
};
@@ -1265,7 +1779,6 @@ syms_of_nsfont (void)
{
DEFSYM (Qcondensed, "condensed");
DEFSYM (Qexpanded, "expanded");
- DEFSYM (Qapple, "apple");
DEFSYM (Qmedium, "medium");
DEFVAR_LISP ("ns-reg-to-script", Vns_reg_to_script,
doc: /* Internal use: maps font registry to Unicode script. */);
diff --git a/src/nsmenu.m b/src/nsmenu.m
index bb0dd2634d8..29201e69079 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -101,6 +101,15 @@ popup_activated (void)
static void
ns_update_menubar (struct frame *f, bool deep_p)
{
+#ifdef NS_IMPL_GNUSTEP
+ static int inside = 0;
+
+ if (inside)
+ return;
+
+ inside++;
+#endif
+
BOOL needsSet = NO;
id menu = [NSApp mainMenu];
bool owfi;
@@ -120,7 +129,12 @@ ns_update_menubar (struct frame *f, bool deep_p)
NSTRACE ("ns_update_menubar");
if (f != SELECTED_FRAME () || FRAME_EXTERNAL_MENU_BAR (f) == 0)
+ {
+#ifdef NS_IMPL_GNUSTEP
+ inside--;
+#endif
return;
+ }
XSETFRAME (Vmenu_updating_frame, f);
/*fprintf (stderr, "ns_update_menubar: frame: %p\tdeep: %d\tsub: %p\n", f, deep_p, submenu); */
@@ -144,10 +158,6 @@ ns_update_menubar (struct frame *f, bool deep_p)
t = -(1000*tb.time+tb.millitm);
#endif
-#ifdef NS_IMPL_GNUSTEP
- deep_p = 1; /* See comment in menuNeedsUpdate. */
-#endif
-
if (deep_p)
{
/* Make a widget-value tree representing the entire menu trees. */
@@ -275,6 +285,9 @@ ns_update_menubar (struct frame *f, bool deep_p)
free_menubar_widget_value_tree (first_wv);
discard_menu_items ();
unbind_to (specpdl_count, Qnil);
+#ifdef NS_IMPL_GNUSTEP
+ inside--;
+#endif
return;
}
@@ -408,6 +421,10 @@ ns_update_menubar (struct frame *f, bool deep_p)
if (needsSet)
[NSApp setMainMenu: menu];
+#ifdef NS_IMPL_GNUSTEP
+ inside--;
+#endif
+
unblock_input ();
}
@@ -452,17 +469,34 @@ set_frame_menubar (struct frame *f, bool deep_p)
call to ns_update_menubar. */
- (void)menuNeedsUpdate: (NSMenu *)menu
{
+#ifdef NS_IMPL_GNUSTEP
+ static int inside = 0;
+#endif
+
if (!FRAME_LIVE_P (SELECTED_FRAME ()))
return;
-#ifdef NS_IMPL_COCOA
-/* TODO: GNUstep calls this method when the menu is still being built
- which results in a recursive stack overflow. One possible solution
- is to use menuWillOpen instead, but the Apple docs explicitly warn
- against changing the contents of the menu in it. I don't know what
- the right thing to do for GNUstep is. */
+#ifdef NS_IMPL_GNUSTEP
+ /* GNUstep calls this method when the menu is still being built
+ which results in a recursive stack overflow, which this variable
+ prevents. */
+
+ if (!inside)
+ ++inside;
+ else
+ return;
+#endif
+
if (needsUpdate)
- ns_update_menubar (SELECTED_FRAME (), true);
+ {
+#ifdef NS_IMPL_GNUSTEP
+ needsUpdate = NO;
+#endif
+ ns_update_menubar (SELECTED_FRAME (), true);
+ }
+
+#ifdef NS_IMPL_GNUSTEP
+ --inside;
#endif
}
@@ -789,6 +823,9 @@ ns_menu_show (struct frame *f, int x, int y, int menuflags,
p.x = x; p.y = y;
+ /* Don't GC due to a mysterious bug. */
+ inhibit_garbage_collection ();
+
/* now parse stage 2 as in ns_update_menubar */
wv = make_widget_value ("contextmenu", NULL, true, Qnil);
wv->button_type = BUTTON_TYPE_NONE;
@@ -959,16 +996,18 @@ ns_menu_show (struct frame *f, int x, int y, int menuflags,
}
pmenu = [[EmacsMenu alloc] initWithTitle:
- [NSString stringWithLispString: title]];
+ NILP (title) ? @"" : [NSString stringWithLispString: title]];
+ /* On GNUstep, this call makes menu_items nil for whatever reason
+ when displaying a context menu from `context-menu-mode'. */
+ Lisp_Object items = menu_items;
[pmenu fillWithWidgetValue: first_wv->contents];
+ menu_items = items;
free_menubar_widget_value_tree (first_wv);
- unbind_to (specpdl_count, Qnil);
-
popup_activated_flag = 1;
tem = [pmenu runMenuAt: p forFrame: f keymaps: keymaps];
popup_activated_flag = 0;
[[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
-
+ unbind_to (specpdl_count, Qnil);
unblock_input ();
return tem;
}
@@ -995,31 +1034,39 @@ free_frame_tool_bar (struct frame *f)
/* Note: This triggers an animation, which calls windowDidResize
repeatedly. */
f->output_data.ns->in_animation = 1;
- [[[view window] toolbar] setVisible: NO];
+ [[[view window] toolbar] setVisible:NO];
f->output_data.ns->in_animation = 0;
+ [[view window] setToolbar:nil];
+
unblock_input ();
}
void
-update_frame_tool_bar (struct frame *f)
+update_frame_tool_bar_1 (struct frame *f, EmacsToolbar *toolbar)
/* --------------------------------------------------------------------------
Update toolbar contents.
-------------------------------------------------------------------------- */
{
int i, k = 0;
- NSWindow *window = [FRAME_NS_VIEW (f) window];
- EmacsToolbar *toolbar = (EmacsToolbar *)[window toolbar];
NSTRACE ("update_frame_tool_bar");
- if (window == nil || toolbar == nil) return;
block_input ();
#ifdef NS_IMPL_COCOA
[toolbar clearActive];
#else
[toolbar clearAll];
+ /* It takes at least 3 such adjustments to fix an issue where the
+ tool bar is 2x too tall when a frame's tool bar is first shown.
+ This is ugly, but I have no other solution for this problem. */
+ if (FRAME_OUTPUT_DATA (f)->tool_bar_adjusted < 3)
+ {
+ [toolbar setVisible: NO];
+ FRAME_OUTPUT_DATA (f)->tool_bar_adjusted++;
+ [toolbar setVisible: YES];
+ }
#endif
/* Update EmacsToolbar as in GtkUtils, build items list. */
@@ -1033,6 +1080,8 @@ update_frame_tool_bar (struct frame *f)
ptrdiff_t img_id;
struct image *img;
Lisp_Object image;
+ Lisp_Object labelObj;
+ const char *labelText;
Lisp_Object helpObj;
const char *helpText;
@@ -1059,6 +1108,8 @@ update_frame_tool_bar (struct frame *f)
{
idx = -1;
}
+ labelObj = TOOLPROP (TOOL_BAR_ITEM_LABEL);
+ labelText = NILP (labelObj) ? "" : SSDATA (labelObj);
helpObj = TOOLPROP (TOOL_BAR_ITEM_HELP);
if (NILP (helpObj))
helpObj = TOOLPROP (TOOL_BAR_ITEM_CAPTION);
@@ -1084,18 +1135,12 @@ update_frame_tool_bar (struct frame *f)
[toolbar addDisplayItemWithImage: img->pixmap
idx: k++
tag: i
+ labelText: labelText
helpText: helpText
enabled: enabled_p];
#undef TOOLPROP
}
- if ([toolbar isVisible] != FRAME_EXTERNAL_TOOL_BAR (f))
- {
- f->output_data.ns->in_animation = 1;
- [toolbar setVisible: FRAME_EXTERNAL_TOOL_BAR (f)];
- f->output_data.ns->in_animation = 0;
- }
-
#ifdef NS_IMPL_COCOA
if ([toolbar changed])
{
@@ -1119,9 +1164,28 @@ update_frame_tool_bar (struct frame *f)
[newDict release];
}
#endif
+
+ [toolbar setVisible:YES];
unblock_input ();
}
+void
+update_frame_tool_bar (struct frame *f)
+{
+ EmacsWindow *window = (EmacsWindow *)[FRAME_NS_VIEW (f) window];
+ EmacsToolbar *toolbar = (EmacsToolbar *)[window toolbar];
+
+ if (!toolbar)
+ {
+ [window createToolbar:f];
+ return;
+ }
+
+ if (window == nil || toolbar == nil) return;
+
+ update_frame_tool_bar_1 (f, toolbar);
+}
+
/* ==========================================================================
@@ -1188,6 +1252,7 @@ update_frame_tool_bar (struct frame *f)
- (void) addDisplayItemWithImage: (EmacsImage *)img
idx: (int)idx
tag: (int)tag
+ labelText: (const char *)label
helpText: (const char *)help
enabled: (BOOL)enabled
{
@@ -1205,6 +1270,7 @@ update_frame_tool_bar (struct frame *f)
item = [[[NSToolbarItem alloc] initWithItemIdentifier: identifier]
autorelease];
[item setImage: img];
+ [item setLabel: [NSString stringWithUTF8String: label]];
[item setToolTip: [NSString stringWithUTF8String: help]];
[item setTarget: emacsView];
[item setAction: @selector (toolbarClicked:)];
diff --git a/src/nsselect.m b/src/nsselect.m
index 5ab3ef77fec..8b23f6f51ad 100644
--- a/src/nsselect.m
+++ b/src/nsselect.m
@@ -215,9 +215,78 @@ ns_get_local_selection (Lisp_Object selection_name,
static Lisp_Object
ns_get_foreign_selection (Lisp_Object symbol, Lisp_Object target)
{
+ NSDictionary *typeLookup;
id pb;
pb = ns_symbol_to_pb (symbol);
- return pb != nil ? ns_string_from_pasteboard (pb) : Qnil;
+
+ /* Dictionary for looking up NS types from MIME types, and vice versa. */
+ typeLookup
+ = [NSDictionary
+ dictionaryWithObjectsAndKeys:
+ @"text/plain", NSPasteboardTypeURL,
+#if NS_USE_NSPasteboardTypeFileURL
+ @"text/plain", NSPasteboardTypeFileURL,
+#else
+ @"text/plain", NSFilenamesPboardType,
+#endif
+#ifdef NS_IMPL_COCOA
+ /* FIXME: I believe these are actually available in recent
+ versions of GNUstep. */
+ @"text/plain", NSPasteboardTypeMultipleTextSelection,
+ @"image/png", NSPasteboardTypePNG,
+#endif
+ @"text/html", NSPasteboardTypeHTML,
+ @"application/pdf", NSPasteboardTypePDF,
+ @"application/rtf", NSPasteboardTypeRTF,
+ @"application/rtfd", NSPasteboardTypeRTFD,
+ @"STRING", NSPasteboardTypeString,
+ @"text/plain", NSPasteboardTypeTabularText,
+ @"image/tiff", NSPasteboardTypeTIFF,
+ nil];
+
+ if (EQ (target, QTARGETS))
+ {
+ NSMutableArray *types = [NSMutableArray arrayWithCapacity:3];
+
+ NSString *type;
+ NSEnumerator *e = [[pb types] objectEnumerator];
+ while (type = [e nextObject])
+ {
+ NSString *val = [typeLookup valueForKey:type];
+ if (val && ! [types containsObject:val])
+ [types addObject:val];
+ }
+
+ Lisp_Object v = Fmake_vector (make_fixnum ([types count]+1), Qnil);
+ ASET (v, 0, QTARGETS);
+
+ for (int i = 0 ; i < [types count] ; i++)
+ ASET (v, i+1, intern ([[types objectAtIndex:i] UTF8String]));
+
+ return v;
+ }
+ else
+ {
+ NSData *d;
+ NSArray *availableTypes;
+ NSString *result, *t;
+
+ if (!NILP (target))
+ availableTypes
+ = [typeLookup allKeysForObject:
+ [NSString stringWithLispString:SYMBOL_NAME (target)]];
+ else
+ availableTypes = [NSArray arrayWithObject:NSPasteboardTypeString];
+
+ t = [pb availableTypeFromArray:availableTypes];
+
+ result = [pb stringForType:t];
+ if (result)
+ return [result lispString];
+
+ d = [pb dataForType:t];
+ return make_string ([d bytes], [d length]);
+ }
}
@@ -234,8 +303,6 @@ Lisp_Object
ns_string_from_pasteboard (id pb)
{
NSString *type, *str;
- const char *utfStr;
- int length;
type = [pb availableTypeFromArray: ns_return_types];
if (type == nil)
@@ -260,6 +327,14 @@ ns_string_from_pasteboard (id pb)
}
}
+ /* FIXME: Is the below EOL conversion even needed? I've removed it
+ for now so we can see if it causes problems. */
+ return [str lispString];
+
+#if 0
+ const char *utfStr;
+ int length;
+
/* assume UTF8 */
NS_DURING
{
@@ -294,6 +369,7 @@ ns_string_from_pasteboard (id pb)
NS_ENDHANDLER
return make_string (utfStr, length);
+#endif
}
@@ -491,6 +567,8 @@ syms_of_nsselect (void)
DEFSYM (QTEXT, "TEXT");
DEFSYM (QFILE_NAME, "FILE_NAME");
+ DEFSYM (QTARGETS, "TARGETS");
+
defsubr (&Sns_disown_selection_internal);
defsubr (&Sns_get_selection);
defsubr (&Sns_own_selection_internal);
diff --git a/src/nsterm.h b/src/nsterm.h
index 404c7140056..ce8f5949024 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -1,3 +1,4 @@
+/* -*- objc -*- */
/* Definitions and headers for communication with NeXT/Open/GNUstep API.
Copyright (C) 1989, 1993, 2005, 2008-2021 Free Software Foundation,
Inc.
@@ -418,6 +419,7 @@ typedef id instancetype;
- (instancetype)initWithEmacsFrame:(struct frame *)f;
- (instancetype)initWithEmacsFrame:(struct frame *)f fullscreen:(BOOL)fullscreen screen:(NSScreen *)screen;
+- (void)createToolbar:(struct frame *)f;
- (void)setParentChildRelationships;
- (NSInteger)borderWidth;
- (BOOL)restackWindow:(NSWindow *)win above:(BOOL)above;
@@ -488,7 +490,7 @@ typedef id instancetype;
- (void)lockFocus;
- (void)unlockFocus;
#endif
-- (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect;
+- (void)copyRect:(NSRect)srcRect to:(NSPoint)dest;
/* Non-notification versions of NSView methods. Used for direct calls. */
- (void)windowWillEnterFullScreen;
@@ -548,6 +550,7 @@ typedef id instancetype;
- (void) addDisplayItemWithImage: (EmacsImage *)img
idx: (int)idx
tag: (int)tag
+ labelText: (const char *)label
helpText: (const char *)help
enabled: (BOOL)enabled;
@@ -817,7 +820,7 @@ struct nsfont_info
XCharStruct max_bounds;
/* We compute glyph codes and metrics on-demand in blocks of 256 indexed
by hibyte, lobyte. */
- unsigned short **glyphs; /* map Unicode index to glyph */
+ unsigned int **glyphs; /* map Unicode index to glyph */
struct font_metrics **metrics;
};
#endif
@@ -975,6 +978,12 @@ struct ns_output
/* Non-zero if we are doing an animation, e.g. toggling the tool bar. */
int in_animation;
+
+#ifdef NS_IMPL_GNUSTEP
+ /* Zero if this is the first time a toolbar has been updated on this
+ frame. */
+ int tool_bar_adjusted;
+#endif
};
/* This dummy declaration needed to support TTYs. */
@@ -1133,6 +1142,7 @@ extern void ns_implicitly_set_name (struct frame *f, Lisp_Object arg,
Lisp_Object oldval);
extern void ns_set_scroll_bar_default_width (struct frame *f);
extern void ns_set_scroll_bar_default_height (struct frame *f);
+extern void ns_change_tab_bar_height (struct frame *f, int height);
extern const char *ns_get_string_resource (void *_rdb,
const char *name,
const char *class);
@@ -1147,6 +1157,10 @@ extern void ns_init_locale (void);
/* in nsmenu */
extern void update_frame_tool_bar (struct frame *f);
+#ifdef __OBJC__
+extern void update_frame_tool_bar_1 (struct frame *f, EmacsToolbar *toolbar);
+#endif
+
extern void free_frame_tool_bar (struct frame *f);
extern Lisp_Object find_and_return_menu_selection (struct frame *f,
bool keymaps,
@@ -1332,9 +1346,16 @@ enum NSWindowTabbingMode
#if !defined (NS_IMPL_COCOA) || !defined (MAC_OS_X_VERSION_10_14)
/* Deprecated in macOS 10.14. */
+/* FIXME: Some of these new names, if not all, are actually available
+ in some recent version of GNUstep. */
#define NSPasteboardTypeString NSStringPboardType
#define NSPasteboardTypeTabularText NSTabularTextPboardType
#define NSPasteboardTypeURL NSURLPboardType
+#define NSPasteboardTypeHTML NSHTMLPboardType
+#define NSPasteboardTypePDF NSPDFPboardType
+#define NSPasteboardTypeRTF NSRTFPboardType
+#define NSPasteboardTypeRTFD NSRTFDPboardType
+#define NSPasteboardTypeTIFF NSTIFFPboardType
#define NSControlStateValueOn NSOnState
#define NSControlStateValueOff NSOffState
#define NSBezelStyleRounded NSRoundedBezelStyle
diff --git a/src/nsterm.m b/src/nsterm.m
index ba5d81fb6cd..4e5ce5ef700 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -65,6 +65,7 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
#ifdef NS_IMPL_GNUSTEP
#include "process.h"
+#import <GNUstepGUI/GSDisplayServer.h>
#endif
#ifdef NS_IMPL_COCOA
@@ -534,8 +535,11 @@ ns_init_locale (void)
NSTRACE ("ns_init_locale");
- @try
+ /* If we were run from a terminal then assume an unset LANG variable
+ is intentional and don't try to "fix" it. */
+ if (!isatty (STDIN_FILENO))
{
+ char *oldLocale = setlocale (LC_ALL, NULL);
/* It seems macOS should probably use UTF-8 everywhere.
'localeIdentifier' does not specify the encoding, and I can't
find any way to get the OS to tell us which encoding to use,
@@ -543,12 +547,12 @@ ns_init_locale (void)
NSString *localeID = [NSString stringWithFormat:@"%@.UTF-8",
[locale localeIdentifier]];
- /* Set LANG to locale, but not if LANG is already set. */
- setenv("LANG", [localeID UTF8String], 0);
- }
- @catch (NSException *e)
- {
- NSLog (@"Locale detection failed: %@: %@", [e name], [e reason]);
+ /* Check the locale ID is valid and if so set LANG, but not if
+ it is already set. */
+ if (setlocale (LC_ALL, [localeID UTF8String]))
+ setenv("LANG", [localeID UTF8String], 0);
+
+ setlocale (LC_ALL, oldLocale);
}
}
@@ -1021,17 +1025,6 @@ ns_update_begin (struct frame *f)
ns_update_auto_hide_menu_bar ();
-#ifdef NS_IMPL_COCOA
- if ([view isFullscreen] && [view fsIsNative])
- {
- // Fix reappearing tool bar in fullscreen for Mac OS X 10.7
- BOOL tbar_visible = FRAME_EXTERNAL_TOOL_BAR (f) ? YES : NO;
- NSToolbar *toolbar = [[FRAME_NS_VIEW (f) window] toolbar];
- if (! tbar_visible != ! [toolbar isVisible])
- [toolbar setVisible: tbar_visible];
- }
-#endif
-
ns_updating_frame = f;
[view lockFocus];
}
@@ -1088,11 +1081,16 @@ ns_focus (struct frame *f, NSRect *r, int n)
/* clipping */
if (r)
{
- [[NSGraphicsContext currentContext] saveGraphicsState];
+ NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
+ [ctx saveGraphicsState];
+#ifdef NS_IMPL_COCOA
if (n == 2)
NSRectClipList (r, 2);
else
NSRectClip (*r);
+#else
+ GSRectClipList (ctx, r, n);
+#endif
gsaved = YES;
}
}
@@ -2260,13 +2258,19 @@ frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
{
NSTRACE ("frame_set_mouse_pixel_position");
- /* FIXME: what about GNUstep? */
#ifdef NS_IMPL_COCOA
CGPoint mouse_pos =
CGPointMake(f->left_pos + pix_x,
f->top_pos + pix_y +
FRAME_NS_TITLEBAR_HEIGHT(f) + FRAME_TOOLBAR_HEIGHT(f));
CGWarpMouseCursorPosition (mouse_pos);
+#else
+ GSDisplayServer *server = GSServerForWindow ([FRAME_NS_VIEW (f) window]);
+ [server setMouseLocation: NSMakePoint (f->left_pos + pix_x,
+ f->top_pos + pix_y
+ + FRAME_NS_TITLEBAR_HEIGHT(f)
+ + FRAME_TOOLBAR_HEIGHT(f))
+ onScreen: [[[FRAME_NS_VIEW (f) window] screen] screenNumber]];
#endif
}
@@ -2444,9 +2448,6 @@ ns_define_frame_cursor (struct frame *f, Emacs_Cursor cursor)
EmacsView *view = FRAME_NS_VIEW (f);
FRAME_POINTER_TYPE (f) = cursor;
[[view window] invalidateCursorRectsForView: view];
- /* Redisplay assumes this function also draws the changed frame
- cursor, but this function doesn't, so do it explicitly. */
- gui_update_cursor (f, 1);
}
}
@@ -2582,8 +2583,7 @@ ns_get_shifted_character (NSEvent *event)
========================================================================== */
-#if 0
-/* FIXME: Remove this function. */
+#ifdef NS_IMPL_GNUSTEP
static void
ns_redraw_scroll_bars (struct frame *f)
{
@@ -2628,10 +2628,9 @@ ns_clear_frame (struct frame *f)
NSRectFill (r);
ns_unfocus (f);
- /* as of 2006/11 or so this is now needed */
- /* FIXME: I don't see any reason for this and removing it makes no
- difference here. Do we need it for GNUstep? */
- //ns_redraw_scroll_bars (f);
+#ifdef NS_IMPL_GNUSTEP
+ ns_redraw_scroll_bars (f);
+#endif
unblock_input ();
}
@@ -2712,10 +2711,10 @@ ns_scroll_run (struct window *w, struct run *run)
{
NSRect srcRect = NSMakeRect (x, from_y, width, height);
- NSRect dstRect = NSMakeRect (x, to_y, width, height);
+ NSPoint dest = NSMakePoint (x, to_y);
EmacsView *view = FRAME_NS_VIEW (f);
- [view copyRect:srcRect to:dstRect];
+ [view copyRect:srcRect to:dest];
#ifdef NS_IMPL_COCOA
[view setNeedsDisplayInRect:srcRect];
#endif
@@ -2732,11 +2731,10 @@ ns_clear_under_internal_border (struct frame *f)
if (FRAME_LIVE_P (f) && FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
{
- int border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
- NSView *view = FRAME_NS_VIEW (f);
- NSRect edge_rect, frame_rect = [view bounds];
- NSRectEdge edge[] = {NSMinXEdge, NSMinYEdge, NSMaxXEdge, NSMaxYEdge};
-
+ int border = FRAME_INTERNAL_BORDER_WIDTH (f);
+ int width = FRAME_PIXEL_WIDTH (f);
+ int height = FRAME_PIXEL_HEIGHT (f);
+ int margin = FRAME_TOP_MARGIN_HEIGHT (f);
int face_id =
(FRAME_PARENT_FRAME (f)
? (!NILP (Vface_remapping_alist)
@@ -2758,12 +2756,12 @@ ns_clear_under_internal_border (struct frame *f)
ns_focus (f, NULL, 1);
[ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set];
- for (int i = 0; i < 4 ; i++)
- {
- NSDivideRect (frame_rect, &edge_rect, &frame_rect, border_width, edge[i]);
- NSRectFill (edge_rect);
- }
+ NSRectFill (NSMakeRect (0, margin, width, border));
+ NSRectFill (NSMakeRect (0, 0, border, height));
+ NSRectFill (NSMakeRect (0, margin, width, border));
+ NSRectFill (NSMakeRect (width - border, 0, border, height));
+ NSRectFill (NSMakeRect (0, height - border, width, border));
ns_unfocus (f);
}
}
@@ -2837,11 +2835,11 @@ ns_shift_glyphs_for_insert (struct frame *f,
-------------------------------------------------------------------------- */
{
NSRect srcRect = NSMakeRect (x, y, width, height);
- NSRect dstRect = NSMakeRect (x+shift_by, y, width, height);
+ NSPoint dest = NSMakePoint (x+shift_by, y);
NSTRACE ("ns_shift_glyphs_for_insert");
- [FRAME_NS_VIEW (f) copyRect:srcRect to:dstRect];
+ [FRAME_NS_VIEW (f) copyRect:srcRect to:dest];
}
@@ -2859,31 +2857,31 @@ ns_compute_glyph_string_overhangs (struct glyph_string *s)
External (RIF); compute left/right overhang of whole string and set in s
-------------------------------------------------------------------------- */
{
- struct font *font = s->font;
-
- if (s->char2b)
+ if (s->cmp == NULL
+ && (s->first_glyph->type == CHAR_GLYPH
+ || s->first_glyph->type == COMPOSITE_GLYPH))
{
struct font_metrics metrics;
- unsigned int codes[2];
- codes[0] = *(s->char2b);
- codes[1] = *(s->char2b + s->nchars - 1);
- font->driver->text_extents (font, codes, 2, &metrics);
- s->left_overhang = -metrics.lbearing;
- s->right_overhang
- = metrics.rbearing > metrics.width
- ? metrics.rbearing - metrics.width : 0;
+ if (s->first_glyph->type == CHAR_GLYPH)
+ {
+ struct font *font = s->font;
+ font->driver->text_extents (font, s->char2b, s->nchars, &metrics);
+ }
+ else
+ {
+ Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
+
+ composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
+ }
+ s->right_overhang = (metrics.rbearing > metrics.width
+ ? metrics.rbearing - metrics.width : 0);
+ s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
}
- else
+ else if (s->cmp)
{
- s->left_overhang = 0;
-#ifdef NS_IMPL_GNUSTEP
- if (EQ (font->driver->type, Qns))
- s->right_overhang = ((struct nsfont_info *)font)->ital ?
- FONT_HEIGHT (font) * 0.2 : 0;
- else
-#endif
- s->right_overhang = 0;
+ s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
+ s->left_overhang = - s->cmp->lbearing;
}
}
@@ -3023,14 +3021,13 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
struct frame *f = WINDOW_XFRAME (w);
struct glyph *phys_cursor_glyph;
struct glyph *cursor_glyph;
- struct face *face;
- NSColor *hollow_color = FRAME_BACKGROUND_COLOR (f);
/* If cursor is out of bounds, don't draw garbage. This can happen
in mini-buffer windows when switching between echo area glyphs
and mini-buffer. */
- NSTRACE ("ns_draw_window_cursor");
+ NSTRACE ("ns_draw_window_cursor (on = %d, cursor_type = %d)",
+ on_p, cursor_type);
if (!on_p)
return;
@@ -3046,6 +3043,8 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
if ((phys_cursor_glyph = get_phys_cursor_glyph (w)) == NULL)
{
+ NSTRACE_MSG ("No phys cursor glyph was found!");
+
if (glyph_row->exact_window_width_line_p
&& w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])
{
@@ -3055,10 +3054,6 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
return;
}
- /* We draw the cursor (with NSRectFill), then draw the glyph on top
- (other terminals do it the other way round). We must set
- w->phys_cursor_width to the cursor width. For bar cursors, that
- is CURSOR_WIDTH; for box cursors, it is the glyph width. */
get_phys_cursor_geometry (w, glyph_row, phys_cursor_glyph, &fx, &fy, &h);
/* The above get_phys_cursor_geometry call set w->phys_cursor_width
@@ -3090,17 +3085,17 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
/* Prevent the cursor from being drawn outside the text area. */
r = NSIntersectionRect (r, ns_row_rect (w, glyph_row, TEXT_AREA));
- ns_focus (f, &r, 1);
+ ns_focus (f, NULL, 0);
- face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id);
- if (face && NS_FACE_BACKGROUND (face)
- == ns_index_color (FRAME_CURSOR_COLOR (f), f))
- {
- [ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f) set];
- hollow_color = FRAME_CURSOR_COLOR (f);
- }
- else
- [FRAME_CURSOR_COLOR (f) set];
+ NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
+ [ctx saveGraphicsState];
+#ifdef NS_IMPL_GNUSTEP
+ GSRectClipList (ctx, &r, 1);
+#else
+ NSRectClip (r);
+#endif
+
+ [FRAME_CURSOR_COLOR (f) set];
switch (cursor_type)
{
@@ -3108,13 +3103,11 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
case NO_CURSOR:
break;
case FILLED_BOX_CURSOR:
- NSRectFill (r);
+ draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
break;
case HOLLOW_BOX_CURSOR:
- NSRectFill (r);
- [hollow_color set];
- NSRectFill (NSInsetRect (r, 1, 1));
- [FRAME_CURSOR_COLOR (f) set];
+ draw_phys_cursor_glyph (w, glyph_row, DRAW_NORMAL_TEXT);
+ [NSBezierPath strokeRect: r];
break;
case HBAR_CURSOR:
NSRectFill (r);
@@ -3130,12 +3123,9 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
NSRectFill (s);
break;
}
- ns_unfocus (f);
- /* Draw the character under the cursor. Other terms only draw
- the character on top of box cursors, so do the same here. */
- if (cursor_type == FILLED_BOX_CURSOR || cursor_type == HOLLOW_BOX_CURSOR)
- draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+ [ctx restoreGraphicsState];
+ ns_unfocus (f);
}
@@ -3315,14 +3305,17 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face,
if (s->for_overlaps)
return;
+ if (s->hl == DRAW_CURSOR)
+ [FRAME_BACKGROUND_COLOR (s->f) set];
+ else
+ [defaultCol set];
+
/* Do underline. */
if (face->underline)
{
if (s->face->underline == FACE_UNDER_WAVE)
{
- if (face->underline_defaulted_p)
- [defaultCol set];
- else
+ if (!face->underline_defaulted_p)
[ns_lookup_indexed_color (face->underline_color, s->f) set];
ns_draw_underwave (s, width, x);
@@ -3396,9 +3389,7 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face,
r = NSMakeRect (x, s->ybase + position, width, thickness);
- if (face->underline_defaulted_p)
- [defaultCol set];
- else
+ if (!face->underline_defaulted_p)
[ns_lookup_indexed_color (face->underline_color, s->f) set];
NSRectFill (r);
}
@@ -3410,10 +3401,9 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face,
NSRect r;
r = NSMakeRect (x, s->y, width, 1);
- if (face->overline_color_defaulted_p)
- [defaultCol set];
- else
+ if (!face->overline_color_defaulted_p)
[ns_lookup_indexed_color (face->overline_color, s->f) set];
+
NSRectFill (r);
}
@@ -3436,10 +3426,9 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face,
dy = lrint ((glyph_height - h) / 2);
r = NSMakeRect (x, glyph_y + dy, width, 1);
- if (face->strike_through_color_defaulted_p)
- [defaultCol set];
- else
+ if (!face->strike_through_color_defaulted_p)
[ns_lookup_indexed_color (face->strike_through_color, s->f) set];
+
NSRectFill (r);
}
}
@@ -3524,7 +3513,12 @@ ns_draw_relief (NSRect outer, int hthickness, int vthickness, char raised_p,
}
/* Calculate the inner rectangle. */
- inner = NSInsetRect (outer, hthickness, vthickness);
+ inner = NSMakeRect (NSMinX (outer) + (left_p ? hthickness : 0),
+ NSMinY (outer) + (top_p ? vthickness : 0),
+ NSWidth (outer) - (left_p ? hthickness : 0)
+ - (right_p ? hthickness : 0),
+ NSHeight (outer) - (top_p ? vthickness : 0)
+ - (bottom_p ? vthickness : 0));
[(raised_p ? lightCol : darkCol) set];
@@ -3582,17 +3576,7 @@ ns_dumpglyphs_box_or_relief (struct glyph_string *s)
struct glyph *last_glyph;
NSRect r;
int hthickness, vthickness;
- struct face *face;
-
- if (s->hl == DRAW_MOUSE_FACE)
- {
- face = FACE_FROM_ID_OR_NULL (s->f,
- MOUSE_HL_INFO (s->f)->mouse_face_face_id);
- if (!face)
- face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
- }
- else
- face = s->face;
+ struct face *face = s->face;
vthickness = face->box_vertical_line_width;
hthickness = face->box_horizontal_line_width;
@@ -3666,34 +3650,26 @@ ns_maybe_dumpglyphs_background (struct glyph_string *s, char force_p)
|| FONT_TOO_HIGH (s->font)
|| s->font_not_found_p || s->extends_to_end_of_line_p || force_p)
{
- struct face *face;
- if (s->hl == DRAW_MOUSE_FACE)
- {
- face
- = FACE_FROM_ID_OR_NULL (s->f,
- MOUSE_HL_INFO (s->f)->mouse_face_face_id);
- if (!face)
- face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
- }
- else
- face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
+ struct face *face = s->face;
if (!face->stipple)
- [(NS_FACE_BACKGROUND (face) != 0
- ? ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f)
- : FRAME_BACKGROUND_COLOR (s->f)) set];
+ {
+ if (s->hl != DRAW_CURSOR)
+ [(NS_FACE_BACKGROUND (face) != 0
+ ? ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f)
+ : FRAME_BACKGROUND_COLOR (s->f)) set];
+ else
+ [FRAME_CURSOR_COLOR (s->f) set];
+ }
else
{
struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
[[dpyinfo->bitmaps[face->stipple-1].img stippleMask] set];
}
- if (s->hl != DRAW_CURSOR)
- {
- NSRect r = NSMakeRect (s->x, s->y + box_line_width,
- s->background_width,
- s->height-2*box_line_width);
- NSRectFill (r);
- }
+ NSRect r = NSMakeRect (s->x, s->y + box_line_width,
+ s->background_width,
+ s->height-2*box_line_width);
+ NSRectFill (r);
s->background_filled_p = 1;
}
@@ -3714,7 +3690,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
int th;
char raised_p;
NSRect br;
- struct face *face;
+ struct face *face = s->face;
NSColor *tdCol;
NSTRACE ("ns_dumpglyphs_image");
@@ -3735,15 +3711,6 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
/* Draw BG: if we need larger area than image itself cleared, do that,
otherwise, since we composite the image under NS (instead of mucking
with its background color), we must clear just the image area. */
- if (s->hl == DRAW_MOUSE_FACE)
- {
- face = FACE_FROM_ID_OR_NULL (s->f,
- MOUSE_HL_INFO (s->f)->mouse_face_face_id);
- if (!face)
- face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
- }
- else
- face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
[ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f) set];
@@ -3814,16 +3781,8 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
if (s->hl == DRAW_CURSOR)
{
- [FRAME_CURSOR_COLOR (s->f) set];
- if (s->w->phys_cursor_type == FILLED_BOX_CURSOR)
+ [FRAME_CURSOR_COLOR (s->f) set];
tdCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f);
- else
- /* Currently on NS img->mask is always 0. Since
- get_window_cursor_type specifies a hollow box cursor when on
- a non-masked image we never reach this clause. But we put it
- in, in anticipation of better support for image masks on
- NS. */
- tdCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
}
else
{
@@ -3875,66 +3834,39 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
static void
ns_dumpglyphs_stretch (struct glyph_string *s)
{
- NSRect r[2];
NSRect glyphRect;
- int n;
- struct face *face;
+ struct face *face = s->face;
NSColor *fgCol, *bgCol;
if (!s->background_filled_p)
{
- n = ns_get_glyph_string_clip_rect (s, r);
- ns_focus (s->f, r, n);
- if (s->hl == DRAW_MOUSE_FACE)
- {
- face = FACE_FROM_ID_OR_NULL (s->f,
- MOUSE_HL_INFO (s->f)->mouse_face_face_id);
- if (!face)
- face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
- }
- else
- face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
+ face = s->face;
bgCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f);
fgCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
- glyphRect = NSMakeRect (s->x, s->y, s->background_width, s->height);
-
- [bgCol set];
-
- /* NOTE: under NS this is NOT used to draw cursors, but we must avoid
- overwriting cursor (usually when cursor on a tab) */
if (s->hl == DRAW_CURSOR)
- {
- CGFloat x, width;
+ {
+ fgCol = bgCol;
+ bgCol = FRAME_CURSOR_COLOR (s->f);
+ }
- /* FIXME: This looks like it will only work for left to
- right languages. */
- x = NSMinX (glyphRect);
- width = s->w->phys_cursor_width;
- glyphRect.size.width -= width;
- glyphRect.origin.x += width;
+ glyphRect = NSMakeRect (s->x, s->y, s->background_width, s->height);
- NSRectFill (glyphRect);
+ [bgCol set];
- /* Draw overlining, etc. on the cursor. */
- if (s->w->phys_cursor_type == FILLED_BOX_CURSOR)
- ns_draw_text_decoration (s, face, bgCol, width, x);
- else
- ns_draw_text_decoration (s, face, fgCol, width, x);
- }
- else
- {
- NSRectFill (glyphRect);
- }
+ NSRectFill (glyphRect);
- /* Draw overlining, etc. on the stretch glyph (or the part
- of the stretch glyph after the cursor). */
- ns_draw_text_decoration (s, face, fgCol, NSWidth (glyphRect),
- NSMinX (glyphRect));
+ /* 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)
+ ns_draw_text_decoration (s, face, fgCol, NSWidth (glyphRect),
+ NSMinX (glyphRect));
- ns_unfocus (s->f);
s->background_filled_p = 1;
}
}
@@ -3943,7 +3875,7 @@ ns_dumpglyphs_stretch (struct glyph_string *s)
static void
ns_draw_glyph_string_foreground (struct glyph_string *s)
{
- int x, flags;
+ int x;
struct font *font = s->font;
/* If first glyph of S has a left box line, start drawing the text
@@ -3954,15 +3886,9 @@ ns_draw_glyph_string_foreground (struct glyph_string *s)
else
x = s->x;
- flags = s->hl == DRAW_CURSOR ? NS_DUMPGLYPH_CURSOR :
- (s->hl == DRAW_MOUSE_FACE ? NS_DUMPGLYPH_MOUSEFACE :
- (s->for_overlaps ? NS_DUMPGLYPH_FOREGROUND :
- NS_DUMPGLYPH_NORMAL));
-
font->driver->draw
(s, s->cmp_from, s->nchars, x, s->ybase,
- (flags == NS_DUMPGLYPH_NORMAL && !s->background_filled_p)
- || flags == NS_DUMPGLYPH_MOUSEFACE);
+ !s->for_overlaps && !s->background_filled_p);
}
@@ -4069,9 +3995,9 @@ ns_draw_glyph_string (struct glyph_string *s)
struct font *font = s->face->font;
if (! font) font = FRAME_FONT (s->f);
- NSTRACE_WHEN (NSTRACE_GROUP_GLYPHS, "ns_draw_glyph_string");
+ NSTRACE ("ns_draw_glyph_string (hl = %u)", s->hl);
- if (s->next && s->right_overhang && !s->for_overlaps/*&&s->hl!=DRAW_CURSOR*/)
+ if (s->next && s->right_overhang && !s->for_overlaps)
{
int width;
struct glyph_string *next;
@@ -4081,17 +4007,17 @@ ns_draw_glyph_string (struct glyph_string *s)
width += next->width, next = next->next)
if (next->first_glyph->type != IMAGE_GLYPH)
{
+ n = ns_get_glyph_string_clip_rect (s->next, r);
+ ns_focus (s->f, r, n);
if (next->first_glyph->type != STRETCH_GLYPH)
{
- n = ns_get_glyph_string_clip_rect (s->next, r);
- ns_focus (s->f, r, n);
ns_maybe_dumpglyphs_background (s->next, 1);
- ns_unfocus (s->f);
}
else
{
ns_dumpglyphs_stretch (s->next);
}
+ ns_unfocus (s->f);
next->num_clips = 0;
}
}
@@ -4108,14 +4034,21 @@ ns_draw_glyph_string (struct glyph_string *s)
box_drawn_p = 1;
}
+ n = ns_get_glyph_string_clip_rect (s, r);
+
+ if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
+ && !s->clip_tail
+ && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
+ || (s->next && s->next->hl != s->hl && s->right_overhang)))
+ r[0] = NSIntersectionRect (r[0], NSMakeRect (s->x, s->y, s->width, s->height));
+
+ ns_focus (s->f, r, n);
+
switch (s->first_glyph->type)
{
case IMAGE_GLYPH:
- n = ns_get_glyph_string_clip_rect (s, r);
- ns_focus (s->f, r, n);
ns_dumpglyphs_image (s, r[0]);
- ns_unfocus (s->f);
break;
case XWIDGET_GLYPH:
@@ -4128,57 +4061,35 @@ ns_draw_glyph_string (struct glyph_string *s)
case CHAR_GLYPH:
case COMPOSITE_GLYPH:
- n = ns_get_glyph_string_clip_rect (s, r);
- ns_focus (s->f, r, n);
-
- if (s->for_overlaps || (s->cmp_from > 0
- && ! s->first_glyph->u.cmp.automatic))
- s->background_filled_p = 1;
- else
- ns_maybe_dumpglyphs_background
- (s, s->first_glyph->type == COMPOSITE_GLYPH);
-
- if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR)
- {
- unsigned long tmp = NS_FACE_BACKGROUND (s->face);
- NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
- NS_FACE_FOREGROUND (s->face) = tmp;
- }
-
{
- BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH;
+ BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH;
+ if (s->for_overlaps || (isComposite
+ && (s->cmp_from > 0
+ && ! s->first_glyph->u.cmp.automatic)))
+ s->background_filled_p = 1;
+ else
+ ns_maybe_dumpglyphs_background
+ (s, s->first_glyph->type == COMPOSITE_GLYPH);
- if (isComposite)
- ns_draw_composite_glyph_string_foreground (s);
- else
- ns_draw_glyph_string_foreground (s);
- }
+ if (isComposite)
+ ns_draw_composite_glyph_string_foreground (s);
+ else
+ ns_draw_glyph_string_foreground (s);
- {
- NSColor *col = (NS_FACE_FOREGROUND (s->face) != 0
- ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (s->face),
- s->f)
- : FRAME_FOREGROUND_COLOR (s->f));
- [col set];
-
- /* Draw underline, overline, strike-through. */
- ns_draw_text_decoration (s, s->face, col, s->width, s->x);
- }
+ {
+ NSColor *col = (NS_FACE_FOREGROUND (s->face) != 0
+ ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (s->face),
+ s->f)
+ : FRAME_FOREGROUND_COLOR (s->f));
- if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR)
- {
- unsigned long tmp = NS_FACE_BACKGROUND (s->face);
- NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
- NS_FACE_FOREGROUND (s->face) = tmp;
- }
+ /* Draw underline, overline, strike-through. */
+ ns_draw_text_decoration (s, s->face, col, s->width, s->x);
+ }
+ }
- ns_unfocus (s->f);
break;
case GLYPHLESS_GLYPH:
- n = ns_get_glyph_string_clip_rect (s, r);
- ns_focus (s->f, r, n);
-
if (s->for_overlaps || (s->cmp_from > 0
&& ! s->first_glyph->u.cmp.automatic))
s->background_filled_p = 1;
@@ -4188,7 +4099,6 @@ ns_draw_glyph_string (struct glyph_string *s)
/* ... */
/* Not yet implemented. */
/* ... */
- ns_unfocus (s->f);
break;
default:
@@ -4197,13 +4107,102 @@ ns_draw_glyph_string (struct glyph_string *s)
/* Draw box if not done already. */
if (!s->for_overlaps && !box_drawn_p && s->face->box != FACE_NO_BOX)
+ ns_dumpglyphs_box_or_relief (s);
+
+ if (s->face->box != FACE_NO_BOX
+ && s->first_glyph->type == STRETCH_GLYPH)
{
- n = ns_get_glyph_string_clip_rect (s, r);
- ns_focus (s->f, r, n);
- ns_dumpglyphs_box_or_relief (s);
+ NSColor *fg_color;
+
+ fg_color = ns_lookup_indexed_color (NS_FACE_FOREGROUND (s->face), s->f);
+ ns_draw_text_decoration (s, s->face, fg_color,
+ s->background_width, s->x);
+ }
+
+ ns_unfocus (s->f);
+
+ /* Draw surrounding overhangs. */
+ if (s->prev)
+ {
+ ns_focus (s->f, NULL, 0);
+ struct glyph_string *prev;
+
+ for (prev = s->prev; prev; prev = prev->prev)
+ if (prev->hl != s->hl
+ && prev->x + prev->width + prev->right_overhang > s->x)
+ {
+ /* As prev was drawn while clipped to its own area, we
+ must draw the right_overhang part using s->hl now. */
+ enum draw_glyphs_face save = prev->hl;
+ struct face *save_face = prev->face;
+
+ prev->face = s->face;
+ NSRect r = NSMakeRect (s->x, s->y, s->width, s->height);
+ [[NSGraphicsContext currentContext] saveGraphicsState];
+ NSRectClip (r);
+#ifdef NS_IMPL_GNUSTEP
+ DPSgsave ([NSGraphicsContext currentContext]);
+ DPSrectclip ([NSGraphicsContext currentContext], s->x, s->y,
+ s->width, s->height);
+#endif
+ prev->num_clips = 1;
+ prev->hl = s->hl;
+ if (prev->first_glyph->type == CHAR_GLYPH)
+ ns_draw_glyph_string_foreground (prev);
+ else
+ ns_draw_composite_glyph_string_foreground (prev);
+#ifdef NS_IMPL_GNUSTEP
+ DPSgrestore ([NSGraphicsContext currentContext]);
+#endif
+ [[NSGraphicsContext currentContext] restoreGraphicsState];
+ prev->hl = save;
+ prev->face = save_face;
+ prev->num_clips = 0;
+ }
ns_unfocus (s->f);
}
+ if (s->next)
+ {
+ ns_focus (s->f, NULL, 0);
+ struct glyph_string *next;
+
+ for (next = s->next; next; next = next->next)
+ if (next->hl != s->hl
+ && next->x - next->left_overhang < s->x + s->width)
+ {
+ /* As next will be drawn while clipped to its own area,
+ we must draw the left_overhang part using s->hl now. */
+ enum draw_glyphs_face save = next->hl;
+ struct face *save_face = next->face;
+
+ next->hl = s->hl;
+ next->face = s->face;
+ NSRect r = NSMakeRect (s->x, s->y, s->width, s->height);
+ [[NSGraphicsContext currentContext] saveGraphicsState];
+ NSRectClip (r);
+#ifdef NS_IMPL_GNUSTEP
+ DPSgsave ([NSGraphicsContext currentContext]);
+ DPSrectclip ([NSGraphicsContext currentContext], s->x, s->y,
+ s->width, s->height);
+#endif
+ next->num_clips = 1;
+ if (next->first_glyph->type == CHAR_GLYPH)
+ ns_draw_glyph_string_foreground (next);
+ else
+ ns_draw_composite_glyph_string_foreground (next);
+#ifdef NS_IMPL_GNUSTEP
+ DPSgrestore ([NSGraphicsContext currentContext]);
+#endif
+ [[NSGraphicsContext currentContext] restoreGraphicsState];
+ next->hl = save;
+ next->num_clips = 0;
+ next->face = save_face;
+ next->clip_head = next;
+ next->background_filled_p = 0;
+ }
+ ns_unfocus (s->f);
+ }
s->num_clips = 0;
}
@@ -4953,6 +4952,17 @@ ns_default_font_parameter (struct frame *f, Lisp_Object parms)
{
}
+#ifdef NS_IMPL_GNUSTEP
+static void
+ns_update_window_end (struct window *w, bool cursor_on_p,
+ bool mouse_face_overwritten_p)
+{
+ NSTRACE ("ns_update_window_end (cursor_on_p = %d)", cursor_on_p);
+
+ ns_redraw_scroll_bars (WINDOW_XFRAME (w));
+}
+#endif
+
/* This and next define (many of the) public functions in this file. */
/* gui_* are generic versions in xdisp.c that we, and other terms, get away
with using despite presence in the "system dependent" redisplay
@@ -4969,7 +4979,11 @@ static struct redisplay_interface ns_redisplay_interface =
ns_scroll_run,
ns_after_update_window_line,
NULL, /* update_window_begin */
+#ifndef NS_IMPL_GNUSTEP
NULL, /* update_window_end */
+#else
+ ns_update_window_end,
+#endif
0, /* flush_display */
gui_clear_window_mouse_face,
gui_get_glyph_overhangs,
@@ -5014,6 +5028,12 @@ ns_delete_terminal (struct terminal *terminal)
block_input ();
+#ifdef NS_IMPL_COCOA
+ /* Rather than try to clean up the NS environment we can just
+ disable the app and leave it waiting for any new frames. */
+ [NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited];
+#endif
+
image_destroy_all_bitmaps (dpyinfo);
ns_delete_display (dpyinfo);
unblock_input ();
@@ -5071,6 +5091,7 @@ ns_create_terminal (struct ns_display_info *dpyinfo)
terminal->free_pixmap = ns_free_pixmap;
terminal->delete_frame_hook = ns_destroy_window;
terminal->delete_terminal_hook = ns_delete_terminal;
+ terminal->change_tab_bar_height_hook = ns_change_tab_bar_height;
/* Other hooks are NULL by default. */
return terminal;
@@ -6189,9 +6210,11 @@ not_in_argv (NSString *arg)
Lisp_Object kind = fnKeysym ? QCfunction : QCordinary;
emacs_event->modifiers = EV_MODIFIERS2 (flags, kind);
+#ifndef NS_IMPL_GNUSTEP
if (NS_KEYLOG)
fprintf (stderr, "keyDown: code =%x\tfnKey =%x\tflags = %x\tmods = %x\n",
code, fnKeysym, flags, emacs_event->modifiers);
+#endif
/* If it was a function key or had control-like modifiers, pass
it directly to Emacs. */
@@ -6561,6 +6584,7 @@ not_in_argv (NSString *arg)
*/
bool horizontal;
int lines = 0;
+ int x = 0, y = 0;
int scrollUp = NO;
/* FIXME: At the top or bottom of the buffer we should
@@ -6596,23 +6620,33 @@ not_in_argv (NSString *arg)
* reset the total delta for the direction we're NOT
* scrolling so that small movements don't add up. */
if (abs (totalDeltaX) > abs (totalDeltaY)
- && abs (totalDeltaX) > lineHeight)
+ && (!mwheel_coalesce_scroll_events
+ || abs (totalDeltaX) > lineHeight))
{
horizontal = YES;
scrollUp = totalDeltaX > 0;
lines = abs (totalDeltaX / lineHeight);
- totalDeltaX = totalDeltaX % lineHeight;
+ x = totalDeltaX;
+ if (!mwheel_coalesce_scroll_events)
+ totalDeltaX = 0;
+ else
+ totalDeltaX = totalDeltaX % lineHeight;
totalDeltaY = 0;
}
else if (abs (totalDeltaY) >= abs (totalDeltaX)
- && abs (totalDeltaY) > lineHeight)
+ && (!mwheel_coalesce_scroll_events
+ || abs (totalDeltaY) > lineHeight))
{
horizontal = NO;
scrollUp = totalDeltaY > 0;
lines = abs (totalDeltaY / lineHeight);
- totalDeltaY = totalDeltaY % lineHeight;
+ y = totalDeltaY;
+ if (!mwheel_coalesce_scroll_events)
+ totalDeltaY = 0;
+ else
+ totalDeltaY = totalDeltaY % lineHeight;
totalDeltaX = 0;
}
@@ -6638,13 +6672,25 @@ not_in_argv (NSString *arg)
? ceil (fabs (delta)) : 1;
scrollUp = delta > 0;
+ x = ([theEvent scrollingDeltaX]
+ * FRAME_COLUMN_WIDTH (emacsframe));
+ y = ([theEvent scrollingDeltaY]
+ * FRAME_LINE_HEIGHT (emacsframe));
}
- if (lines == 0)
+ if (lines == 0 && mwheel_coalesce_scroll_events)
return;
+ if (NUMBERP (Vns_scroll_event_delta_factor))
+ {
+ x *= XFLOATINT (Vns_scroll_event_delta_factor);
+ y *= XFLOATINT (Vns_scroll_event_delta_factor);
+ }
+
emacs_event->kind = horizontal ? HORIZ_WHEEL_EVENT : WHEEL_EVENT;
- emacs_event->arg = (make_fixnum (lines));
+ emacs_event->arg = list3 (make_fixnum (lines),
+ make_float (x),
+ make_float (y));
emacs_event->code = 0;
emacs_event->modifiers = EV_MODIFIERS (theEvent) |
@@ -6680,10 +6726,35 @@ not_in_argv (NSString *arg)
}
else
{
- emacs_event->kind = MOUSE_CLICK_EVENT;
+ Lisp_Object tab_bar_arg = Qnil;
+ bool tab_bar_p = false;
+
+ if (WINDOWP (emacsframe->tab_bar_window)
+ && WINDOW_TOTAL_LINES (XWINDOW (emacsframe->tab_bar_window)))
+ {
+ Lisp_Object window;
+ int x = lrint (p.x);
+ int y = lrint (p.y);
+
+ window = window_from_coordinates (emacsframe, x, y, 0, true, true);
+ tab_bar_p = EQ (window, emacsframe->tab_bar_window);
+
+ if (tab_bar_p)
+ tab_bar_arg = handle_tab_bar_click (emacsframe, x, y, EV_UDMODIFIERS (theEvent) & down_modifier,
+ EV_MODIFIERS (theEvent) | EV_UDMODIFIERS (theEvent));
+ }
+
+ if (!(tab_bar_p && NILP (tab_bar_arg)))
+ emacs_event->kind = MOUSE_CLICK_EVENT;
+ emacs_event->arg = tab_bar_arg;
emacs_event->code = EV_BUTTON (theEvent);
emacs_event->modifiers = EV_MODIFIERS (theEvent)
| EV_UDMODIFIERS (theEvent);
+
+ if (emacs_event->modifiers & down_modifier)
+ FRAME_DISPLAY_INFO (emacsframe)->grabbed |= 1 << EV_BUTTON (theEvent);
+ else
+ FRAME_DISPLAY_INFO (emacsframe)->grabbed &= ~(1 << EV_BUTTON (theEvent));
}
XSETINT (emacs_event->x, lrint (p.x));
@@ -6979,13 +7050,17 @@ not_in_argv (NSString *arg)
if (! FRAME_LIVE_P (emacsframe))
return;
- frame = [self frame];
+ frame = [[self superview] bounds];
width = (int)NSWidth (frame);
height = (int)NSHeight (frame);
NSTRACE_SIZE ("New size", NSMakeSize (width, height));
- NSTRACE_SIZE ("Original size", size);
+ /* Reset the frame size to match the bounds of the superview (the
+ NSWindow's contentView). We need to do this as sometimes the
+ view's frame isn't resized correctly, or can end up with the
+ wrong origin. */
+ [self setFrame:frame];
change_frame_size (emacsframe, width, height, false, YES, false);
SET_FRAME_GARBAGED (emacsframe);
@@ -7048,6 +7123,7 @@ not_in_argv (NSString *arg)
XSETFRAME (frame, emacsframe);
help_echo_string = Qnil;
gen_help_event (Qnil, frame, Qnil, Qnil, 0);
+ any_help_event_p = NO;
}
if (emacs_event && is_focus_frame)
@@ -7397,7 +7473,6 @@ not_in_argv (NSString *arg)
}
else
{
- BOOL tbar_visible = FRAME_EXTERNAL_TOOL_BAR (emacsframe) ? YES : NO;
#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 \
&& MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
unsigned val = (unsigned)[NSApp presentationOptions];
@@ -7415,7 +7490,6 @@ not_in_argv (NSString *arg)
[NSApp setPresentationOptions: options];
}
#endif
- [[[self window]toolbar] setVisible:tbar_visible];
}
}
@@ -7456,14 +7530,6 @@ not_in_argv (NSString *arg)
#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
[self updateCollectionBehavior];
#endif
- if (FRAME_EXTERNAL_TOOL_BAR (emacsframe))
- {
- [[[self window] toolbar] setVisible:YES];
- update_frame_tool_bar (emacsframe);
- [[self window] display];
- }
- else
- [[[self window] toolbar] setVisible:NO];
if (next_maximized != -1)
[[self window] performZoom:self];
@@ -7869,17 +7935,39 @@ not_in_argv (NSString *arg)
#endif /* NS_IMPL_COCOA */
-- (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect
+- (void)copyRect:(NSRect)srcRect to:(NSPoint)dest
{
NSTRACE ("[EmacsView copyRect:To:]");
NSTRACE_RECT ("Source", srcRect);
- NSTRACE_RECT ("Destination", dstRect);
+ NSTRACE_POINT ("Destination", dest);
+
+ NSRect dstRect = NSMakeRect (dest.x, dest.y, NSWidth (srcRect),
+ NSHeight (srcRect));
+ NSRect frame = [self frame];
+
+ /* TODO: This check is an attempt to debug a rare graphical glitch
+ on macOS and should be removed before the Emacs 28 release. */
+ if (!NSContainsRect (frame, srcRect)
+ || !NSContainsRect (frame, dstRect))
+ {
+ NSLog (@"[EmacsView copyRect:to:] Attempting to copy to or "
+ "from an area outside the graphics buffer.");
+ NSLog (@" Frame: (%f, %f) %f×%f",
+ NSMinX (frame), NSMinY (frame),
+ NSWidth (frame), NSHeight (frame));
+ NSLog (@" Source: (%f, %f) %f×%f",
+ NSMinX (srcRect), NSMinY (srcRect),
+ NSWidth (srcRect), NSHeight (srcRect));
+ NSLog (@" Destination: (%f, %f) %f×%f",
+ NSMinX (dstRect), NSMinY (dstRect),
+ NSWidth (dstRect), NSHeight (dstRect));
+ }
#ifdef NS_IMPL_COCOA
if ([self wantsLayer])
{
double scale = [[self window] backingScaleFactor];
- CGContextRef context = [[NSGraphicsContext currentContext] CGContext];
+ CGContextRef context = [(EmacsLayer *)[self layer] getContext];
int bpp = CGBitmapContextGetBitsPerPixel (context) / 8;
void *pixels = CGBitmapContextGetData (context);
int rowSize = CGBitmapContextGetBytesPerRow (context);
@@ -7888,8 +7976,8 @@ not_in_argv (NSString *arg)
+ (int) (NSMinY (srcRect) * scale * rowSize
+ NSMinX (srcRect) * scale * bpp);
void *dstPixels = (char *) pixels
- + (int) (NSMinY (dstRect) * scale * rowSize
- + NSMinX (dstRect) * scale * bpp);
+ + (int) (dest.y * scale * rowSize
+ + dest.x * scale * bpp);
if (NSIntersectsRect (srcRect, dstRect)
&& NSMinY (srcRect) < NSMinY (dstRect))
@@ -8294,8 +8382,7 @@ not_in_argv (NSString *arg)
[self setOpaque:NO];
/* toolbar support */
- if (! FRAME_UNDECORATED (f))
- [self createToolbar:f];
+ [self createToolbar:f];
/* macOS Sierra automatically enables tabbed windows. We can't
allow this to be enabled until it's available on a Free system.
@@ -8312,14 +8399,17 @@ not_in_argv (NSString *arg)
- (void)createToolbar: (struct frame *)f
{
+ if (FRAME_UNDECORATED (f) || !FRAME_EXTERNAL_TOOL_BAR (f))
+ return;
+
EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f);
EmacsToolbar *toolbar = [[EmacsToolbar alloc]
initForView:view
withIdentifier:[NSString stringWithLispString:f->name]];
- [self setToolbar:toolbar];
- update_frame_tool_bar (f);
+ [self setToolbar:toolbar];
+ update_frame_tool_bar_1 (f, toolbar);
#ifdef NS_IMPL_COCOA
{
@@ -8363,14 +8453,14 @@ not_in_argv (NSString *arg)
#ifdef NS_IMPL_COCOA
- /* We have to set the accesibility subroles and/or the collection
+ /* We have to set the accessibility subroles and/or the collection
behaviors early otherwise child windows may not go fullscreen as
expected later. */
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
if ([child respondsToSelector:@selector(setAccessibilitySubrole:)])
#endif
- /* Set the accessibilty subroles. */
+ /* Set the accessibility subroles. */
if (parentFrame)
[self setAccessibilitySubrole:NSAccessibilityFloatingWindowSubrole];
else
@@ -9394,7 +9484,7 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
if (self)
{
cache = [[NSMutableArray arrayWithCapacity:CACHE_MAX_SIZE] retain];
- colorSpace = cs;
+ [self setColorSpace:cs];
}
else
{
@@ -9409,7 +9499,10 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
{
/* We don't need to clear the cache because the new colorspace will
be used next time we create a new context. */
- colorSpace = cs;
+ if (cs)
+ colorSpace = cs;
+ else
+ colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
}
@@ -9505,6 +9598,12 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
(id)kIOSurfacePixelFormat:[NSNumber numberWithUnsignedInt:'BGRA']});
}
+ if (!surface)
+ {
+ NSLog (@"Failed to create IOSurface for frame %@", [self delegate]);
+ return nil;
+ }
+
IOReturn lockStatus = IOSurfaceLock (surface, 0, nil);
if (lockStatus != kIOReturnSuccess)
NSLog (@"Failed to lock surface: %x", lockStatus);
@@ -9522,6 +9621,15 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
(kCGImageAlphaPremultipliedFirst
| kCGBitmapByteOrder32Host));
+ if (!context)
+ {
+ NSLog (@"Failed to create context for frame %@", [self delegate]);
+ IOSurfaceUnlock (currentSurface, 0, nil);
+ CFRelease (currentSurface);
+ currentSurface = nil;
+ return nil;
+ }
+
CGContextTranslateCTM(context, 0, IOSurfaceGetHeight (currentSurface));
CGContextScaleCTM(context, scale, -scale);
}
@@ -9944,8 +10052,15 @@ This variable is ignored on macOS < 10.7 and GNUstep. Default is t. */);
x_underline_at_descent_line,
doc: /* SKIP: real doc in xterm.c. */);
x_underline_at_descent_line = 0;
+
DEFSYM (Qx_underline_at_descent_line, "x-underline-at-descent-line");
+ DEFVAR_LISP ("ns-scroll-event-delta-factor", Vns_scroll_event_delta_factor,
+ doc: /* A factor to apply to pixel deltas reported in scroll events.
+ This is only effective for pixel deltas generated from touch pads or
+ mice with smooth scrolling capability. */);
+ Vns_scroll_event_delta_factor = make_float (1.0);
+
/* Tell Emacs about this window system. */
Fprovide (Qns, Qnil);
diff --git a/src/pdumper.c b/src/pdumper.c
index 7730ea3d061..554b53020e0 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -312,14 +312,15 @@ dump_reloc_set_offset (struct dump_reloc *reloc, dump_off offset)
error ("dump relocation out of range");
}
-static void
-dump_fingerprint (char const *label,
+void
+dump_fingerprint (FILE *output, char const *label,
unsigned char const xfingerprint[sizeof fingerprint])
{
enum { hexbuf_size = 2 * sizeof fingerprint };
char hexbuf[hexbuf_size];
hexbuf_digest (hexbuf, xfingerprint, sizeof fingerprint);
- fprintf (stderr, "%s: %.*s\n", label, hexbuf_size, hexbuf);
+ fprintf (output, "%s%s%.*s\n", label, *label ? ": " : "",
+ hexbuf_size, hexbuf);
}
/* To be used if some order in the relocation process has to be enforced. */
@@ -799,7 +800,7 @@ dump_tailq_length (const struct dump_tailq *tailq)
return tailq->length;
}
-static void ATTRIBUTE_UNUSED
+static void
dump_tailq_prepend (struct dump_tailq *tailq, Lisp_Object value)
{
Lisp_Object link = Fcons (value, tailq->head);
@@ -809,24 +810,6 @@ dump_tailq_prepend (struct dump_tailq *tailq, Lisp_Object value)
tailq->length += 1;
}
-static void ATTRIBUTE_UNUSED
-dump_tailq_append (struct dump_tailq *tailq, Lisp_Object value)
-{
- Lisp_Object link = Fcons (value, Qnil);
- if (NILP (tailq->head))
- {
- eassert (NILP (tailq->tail));
- tailq->head = tailq->tail = link;
- }
- else
- {
- eassert (!NILP (tailq->tail));
- XSETCDR (tailq->tail, link);
- tailq->tail = link;
- }
- tailq->length += 1;
-}
-
static bool
dump_tailq_empty_p (struct dump_tailq *tailq)
{
@@ -2871,19 +2854,24 @@ dump_bool_vector (struct dump_context *ctx, const struct Lisp_Vector *v)
static dump_off
dump_subr (struct dump_context *ctx, const struct Lisp_Subr *subr)
{
-#if CHECK_STRUCTS && !defined (HASH_Lisp_Subr_AA236F7759)
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Subr_F09D8E8E19)
# error "Lisp_Subr changed. See CHECK_STRUCTS comment in config.h."
#endif
struct Lisp_Subr out;
dump_object_start (ctx, &out, sizeof (out));
DUMP_FIELD_COPY (&out, subr, header.size);
- if (NATIVE_COMP_FLAG && !NILP (subr->native_comp_u[0]))
+#ifdef HAVE_NATIVE_COMP
+ bool native_comp = !NILP (subr->native_comp_u);
+#else
+ bool native_comp = false;
+#endif
+ if (native_comp)
out.function.a0 = NULL;
else
dump_field_emacs_ptr (ctx, &out, subr, &subr->function.a0);
DUMP_FIELD_COPY (&out, subr, min_args);
DUMP_FIELD_COPY (&out, subr, max_args);
- if (NATIVE_COMP_FLAG && !NILP (subr->native_comp_u[0]))
+ if (native_comp)
{
dump_field_fixup_later (ctx, &out, subr, &subr->symbol_name);
dump_remember_cold_op (ctx,
@@ -2897,19 +2885,16 @@ dump_subr (struct dump_context *ctx, const struct Lisp_Subr *subr)
dump_field_emacs_ptr (ctx, &out, subr, &subr->intspec);
}
DUMP_FIELD_COPY (&out, subr, doc);
- if (NATIVE_COMP_FLAG)
- {
- dump_field_lv (ctx, &out, subr, &subr->native_comp_u[0], WEIGHT_NORMAL);
- if (!NILP (subr->native_comp_u[0]))
- dump_field_fixup_later (ctx, &out, subr, &subr->native_c_name[0]);
+#ifdef HAVE_NATIVE_COMP
+ dump_field_lv (ctx, &out, subr, &subr->native_comp_u, WEIGHT_NORMAL);
+ if (!NILP (subr->native_comp_u))
+ dump_field_fixup_later (ctx, &out, subr, &subr->native_c_name);
- dump_field_lv (ctx, &out, subr, &subr->lambda_list[0], WEIGHT_NORMAL);
- dump_field_lv (ctx, &out, subr, &subr->type[0], WEIGHT_NORMAL);
- }
+ dump_field_lv (ctx, &out, subr, &subr->lambda_list, WEIGHT_NORMAL);
+ dump_field_lv (ctx, &out, subr, &subr->type, WEIGHT_NORMAL);
+#endif
dump_off subr_off = dump_object_finish (ctx, &out, sizeof (out));
- if (NATIVE_COMP_FLAG
- && ctx->flags.dump_object_contents
- && !NILP (subr->native_comp_u[0]))
+ if (native_comp && ctx->flags.dump_object_contents)
/* We'll do the final addr relocation during VERY_LATE_RELOCS time
after the compilation units has been loaded. */
dump_push (&ctx->dump_relocs[VERY_LATE_RELOCS],
@@ -2963,7 +2948,7 @@ dump_vectorlike (struct dump_context *ctx,
Lisp_Object lv,
dump_off offset)
{
-#if CHECK_STRUCTS && !defined HASH_pvec_type_F5BA506141
+#if CHECK_STRUCTS && !defined HASH_pvec_type_19F6CF5169
# error "pvec_type changed. See CHECK_STRUCTS comment in config.h."
#endif
const struct Lisp_Vector *v = XVECTOR (lv);
@@ -3043,6 +3028,8 @@ dump_vectorlike (struct dump_context *ctx,
error_unsupported_dump_object (ctx, lv, "mutex");
case PVEC_CONDVAR:
error_unsupported_dump_object (ctx, lv, "condvar");
+ case PVEC_SQLITE:
+ error_unsupported_dump_object (ctx, lv, "sqlite");
case PVEC_MODULE_FUNCTION:
error_unsupported_dump_object (ctx, lv, "module function");
default:
@@ -3190,7 +3177,7 @@ dump_charset (struct dump_context *ctx, int cs_i)
DUMP_FIELD_COPY (&out, cs, hash_index);
DUMP_FIELD_COPY (&out, cs, dimension);
memcpy (out.code_space, &cs->code_space, sizeof (cs->code_space));
- if (cs->code_space_mask)
+ if (cs_i < charset_table_used && cs->code_space_mask)
dump_field_fixup_later (ctx, &out, cs, &cs->code_space_mask);
DUMP_FIELD_COPY (&out, cs, code_linear_p);
DUMP_FIELD_COPY (&out, cs, iso_chars_96);
@@ -3211,7 +3198,7 @@ dump_charset (struct dump_context *ctx, int cs_i)
memcpy (out.fast_map, &cs->fast_map, sizeof (cs->fast_map));
DUMP_FIELD_COPY (&out, cs, code_offset);
dump_off offset = dump_object_finish (ctx, &out, sizeof (out));
- if (cs->code_space_mask)
+ if (cs_i < charset_table_used && cs->code_space_mask)
dump_remember_cold_op (ctx, COLD_OP_CHARSET,
Fcons (dump_off_to_lisp (cs_i),
dump_off_to_lisp (offset)));
@@ -3439,9 +3426,9 @@ dump_cold_native_subr (struct dump_context *ctx, Lisp_Object subr)
dump_remember_fixup_ptr_raw
(ctx,
- subr_offset + dump_offsetof (struct Lisp_Subr, native_c_name[0]),
+ subr_offset + dump_offsetof (struct Lisp_Subr, native_c_name),
ctx->offset);
- const char *c_name = XSUBR (subr)->native_c_name[0];
+ const char *c_name = XSUBR (subr)->native_c_name;
dump_write (ctx, c_name, 1 + strlen (c_name));
}
#endif
@@ -4145,7 +4132,7 @@ types. */)
ctx->header.fingerprint[i] = fingerprint[i];
const dump_off header_start = ctx->offset;
- dump_fingerprint ("Dumping fingerprint", ctx->header.fingerprint);
+ dump_fingerprint (stderr, "Dumping fingerprint", ctx->header.fingerprint);
dump_write (ctx, &ctx->header, sizeof (ctx->header));
const dump_off header_end = ctx->offset;
@@ -4537,15 +4524,28 @@ dump_map_file_w32 (void *base, int fd, off_t offset, size_t size,
uint32_t offset_low = (uint32_t) (full_offset & 0xffffffff);
int error;
+ DWORD protect;
DWORD map_access;
file = (HANDLE) _get_osfhandle (fd);
if (file == INVALID_HANDLE_VALUE)
goto out;
+ switch (protection)
+ {
+ case DUMP_MEMORY_ACCESS_READWRITE:
+ protect = PAGE_WRITECOPY; /* for Windows 9X */
+ break;
+ default:
+ case DUMP_MEMORY_ACCESS_NONE:
+ case DUMP_MEMORY_ACCESS_READ:
+ protect = PAGE_READONLY;
+ break;
+ }
+
section = CreateFileMapping (file,
/*lpAttributes=*/NULL,
- PAGE_READONLY,
+ protect,
/*dwMaximumSizeHigh=*/0,
/*dwMaximumSizeLow=*/0,
/*lpName=*/NULL);
@@ -5300,6 +5300,9 @@ dump_do_dump_relocation (const uintptr_t dump_base,
error ("Trying to load incoherent dumped eln file %s",
SSDATA (comp_u->file));
+ if (!CONSP (comp_u->file))
+ error ("Incoherent compilation unit for dump was dumped");
+
/* emacs_execdir is always unibyte, but the file names in
comp_u->file could be multibyte, so we need to encode
them. */
@@ -5350,7 +5353,7 @@ dump_do_dump_relocation (const uintptr_t dump_base,
their file names through expand-file-name and
decode-coding-string. */
comp_u->file = eln_fname;
- comp_u->handle = dynlib_open (SSDATA (eln_fname));
+ comp_u->handle = dynlib_open_for_eln (SSDATA (eln_fname));
if (!comp_u->handle)
{
fprintf (stderr, "Error using execdir %s:\n",
@@ -5362,20 +5365,16 @@ dump_do_dump_relocation (const uintptr_t dump_base,
}
case RELOC_NATIVE_SUBR:
{
- if (!NATIVE_COMP_FLAG)
- /* This cannot happen. */
- emacs_abort ();
-
/* When resurrecting from a dump given non all the original
native compiled subrs may be still around we can't rely on
a 'top_level_run' mechanism, we revive them one-by-one
here. */
struct Lisp_Subr *subr = dump_ptr (dump_base, reloc_offset);
struct Lisp_Native_Comp_Unit *comp_u =
- XNATIVE_COMP_UNIT (subr->native_comp_u[0]);
+ XNATIVE_COMP_UNIT (subr->native_comp_u);
if (!comp_u->handle)
error ("NULL handle in compilation unit %s", SSDATA (comp_u->file));
- const char *c_name = subr->native_c_name[0];
+ const char *c_name = subr->native_c_name;
eassert (c_name);
void *func = dynlib_sym (comp_u->handle, c_name);
if (!func)
@@ -5601,8 +5600,8 @@ pdumper_load (const char *dump_filename, char *argv0)
desired[i] = fingerprint[i];
if (memcmp (header->fingerprint, desired, sizeof desired) != 0)
{
- dump_fingerprint ("desired fingerprint", desired);
- dump_fingerprint ("found fingerprint", header->fingerprint);
+ dump_fingerprint (stderr, "desired fingerprint", desired);
+ dump_fingerprint (stderr, "found fingerprint", header->fingerprint);
goto out;
}
@@ -5710,6 +5709,7 @@ pdumper_load (const char *dump_filename, char *argv0)
dump_mmap_release (&sections[i]);
if (dump_fd >= 0)
emacs_close (dump_fd);
+
return err;
}
@@ -5794,6 +5794,7 @@ syms_of_pdumper (void)
DEFSYM (Qdumped_with_pdumper, "dumped-with-pdumper");
DEFSYM (Qload_time, "load-time");
DEFSYM (Qdump_file_name, "dump-file-name");
+ DEFSYM (Qafter_pdump_load_hook, "after-pdump-load-hook");
defsubr (&Spdumper_stats);
#endif /* HAVE_PDUMPER */
}
diff --git a/src/pdumper.h b/src/pdumper.h
index deec9af046d..7f1f5e46ad9 100644
--- a/src/pdumper.h
+++ b/src/pdumper.h
@@ -20,6 +20,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#ifndef EMACS_PDUMPER_H
#define EMACS_PDUMPER_H
+#include <stdio.h>
+#include "fingerprint.h"
#include "lisp.h"
INLINE_HEADER_BEGIN
@@ -50,6 +52,9 @@ enum { PDUMPER_NO_OBJECT = -1 };
#define PDUMPER_REMEMBER_SCALAR(thing) \
pdumper_remember_scalar (&(thing), sizeof (thing))
+extern void dump_fingerprint (FILE *output, const char *label,
+ unsigned char const fingerp[sizeof fingerprint]);
+
extern void pdumper_remember_scalar_impl (void *data, ptrdiff_t nbytes);
INLINE void
diff --git a/src/pgtkfns.c b/src/pgtkfns.c
new file mode 100644
index 00000000000..44e3d2a37e2
--- /dev/null
+++ b/src/pgtkfns.c
@@ -0,0 +1,4144 @@
+/* Functions for the pure Gtk+-3.
+
+Copyright (C) 1989, 1992-1994, 2005-2006, 2008-2020 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/>. */
+
+/* This should be the first include, as it may set up #defines affecting
+ interpretation of even the system includes. */
+#include <config.h>
+
+#include <math.h>
+#include <c-strcase.h>
+
+#include "lisp.h"
+#include "blockinput.h"
+#include "gtkutil.h"
+#include "window.h"
+#include "character.h"
+#include "buffer.h"
+#include "keyboard.h"
+#include "termhooks.h"
+#include "fontset.h"
+#include "font.h"
+#include "xsettings.h"
+#include "atimer.h"
+
+
+#ifdef HAVE_PGTK
+
+/* Static variables to handle applescript execution. */
+static Lisp_Object as_script, *as_result;
+static int as_status;
+
+static ptrdiff_t image_cache_refcount;
+
+static int x_decode_color (struct frame *f, Lisp_Object color_name,
+ int mono_color);
+static struct pgtk_display_info *pgtk_display_info_for_name (Lisp_Object);
+
+static const char *pgtk_app_name = "Emacs";
+
+/* Scale factor manually set per monitor. */
+static Lisp_Object monitor_scale_factor_alist;
+
+/* ==========================================================================
+
+ Internal utility functions
+
+ ========================================================================== */
+
+static double
+pgtk_get_monitor_scale_factor (const char *model)
+{
+ if (model == NULL)
+ return 0.0;
+
+ Lisp_Object mdl = build_string (model);
+ Lisp_Object tem = Fassoc (mdl, monitor_scale_factor_alist, Qnil);
+ if (NILP (tem))
+ return 0;
+ Lisp_Object cdr = Fcdr (tem);
+ if (NILP (cdr))
+ return 0;
+ if (FIXNUMP (cdr))
+ return XFIXNUM (cdr);
+ else if (FLOATP (cdr))
+ return XFLOAT_DATA (cdr);
+ else
+ error ("unknown type of scale-factor");
+}
+
+struct pgtk_display_info *
+check_pgtk_display_info (Lisp_Object object)
+{
+ struct pgtk_display_info *dpyinfo = NULL;
+
+ if (NILP (object))
+ {
+ struct frame *sf = XFRAME (selected_frame);
+
+ if (FRAME_PGTK_P (sf) && FRAME_LIVE_P (sf))
+ dpyinfo = FRAME_DISPLAY_INFO (sf);
+ else if (x_display_list != 0)
+ dpyinfo = x_display_list;
+ else
+ error ("Frames are not in use or not initialized");
+ }
+ else if (TERMINALP (object))
+ {
+ struct terminal *t = decode_live_terminal (object);
+
+ if (t->type != output_pgtk)
+ error ("Terminal %d is not a display", t->id);
+
+ dpyinfo = t->display_info.pgtk;
+ }
+ else if (STRINGP (object))
+ dpyinfo = pgtk_display_info_for_name (object);
+ else
+ {
+ struct frame *f = decode_window_system_frame (object);
+ dpyinfo = FRAME_DISPLAY_INFO (f);
+ }
+
+ return dpyinfo;
+}
+
+/* On Wayland, even if without WAYLAND_DISPLAY, --display DISPLAY
+ works, but gdk_display_get_name always return "wayland-0", which
+ may be different from DISPLAY. If with WAYLAND_DISPLAY, then it
+ always returns WAYLAND_DISPLAY. So pgtk Emacs is confused and
+ enters multi display environment. To workaround this situation,
+ treat all the wayland-* as the same display. */
+static Lisp_Object
+is_wayland_display (Lisp_Object dpyname)
+{
+ const char *p = SSDATA (dpyname);
+ if (strncmp (p, "wayland-", 8) != 0)
+ return Qnil;
+ p += 8;
+ do {
+ if (*p < '0' || *p > '9')
+ return Qnil;
+ } while (*++p != '\0');
+ return Qt;
+}
+
+/* Return the X display structure for the display named NAME.
+ Open a new connection if necessary. */
+static struct pgtk_display_info *
+pgtk_display_info_for_name (Lisp_Object name)
+{
+ struct pgtk_display_info *dpyinfo;
+
+ CHECK_STRING (name);
+
+ if (!NILP (is_wayland_display (name)))
+ {
+ for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
+ if (!NILP (is_wayland_display (XCAR (dpyinfo->name_list_element))))
+ return dpyinfo;
+ }
+ else
+ {
+ for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
+ if (!NILP (Fstring_equal (XCAR (dpyinfo->name_list_element), name)))
+ return dpyinfo;
+ }
+
+ /* Use this general default value to start with. */
+ Vx_resource_name = Vinvocation_name;
+
+ validate_x_resource_name ();
+
+ dpyinfo = pgtk_term_init (name, SSDATA (Vx_resource_name));
+
+ if (dpyinfo == 0)
+ error ("Cannot connect to display server %s", SDATA (name));
+
+ XSETFASTINT (Vwindow_system_version, 11);
+
+ return dpyinfo;
+}
+
+/* ==========================================================================
+
+ Frame parameter setters
+
+ ========================================================================== */
+
+
+static void
+x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ unsigned long fg;
+
+ fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
+ FRAME_FOREGROUND_PIXEL (f) = fg;
+ FRAME_X_OUTPUT (f)->foreground_color = fg;
+
+ if (FRAME_GTK_WIDGET (f))
+ {
+ update_face_from_frame_parameter (f, Qforeground_color, arg);
+ if (FRAME_VISIBLE_P (f))
+ SET_FRAME_GARBAGED (f);
+ }
+}
+
+
+static void
+x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ unsigned long bg;
+
+ bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
+ FRAME_BACKGROUND_PIXEL (f) = bg;
+
+ /* Clear the frame. */
+ if (FRAME_VISIBLE_P (f))
+ pgtk_clear_frame (f);
+
+ FRAME_X_OUTPUT (f)->background_color = bg;
+
+ xg_set_background_color (f, bg);
+ update_face_from_frame_parameter (f, Qbackground_color, arg);
+
+ if (FRAME_VISIBLE_P (f))
+ SET_FRAME_GARBAGED (f);
+}
+
+static void
+x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ int pix;
+
+ CHECK_STRING (arg);
+ pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
+ FRAME_X_OUTPUT (f)->border_pixel = pix;
+ pgtk_frame_rehighlight (FRAME_DISPLAY_INFO (f));
+}
+
+static void
+x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ unsigned long fore_pixel, pixel;
+ struct pgtk_output *x = f->output_data.pgtk;
+
+ if (!NILP (Vx_cursor_fore_pixel))
+ {
+ fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
+ WHITE_PIX_DEFAULT (f));
+ }
+ else
+ fore_pixel = FRAME_BACKGROUND_PIXEL (f);
+
+ pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
+
+ /* Make sure that the cursor color differs from the background color. */
+ if (pixel == FRAME_BACKGROUND_PIXEL (f))
+ {
+ pixel = x->mouse_color;
+ if (pixel == fore_pixel)
+ {
+ fore_pixel = FRAME_BACKGROUND_PIXEL (f);
+ }
+ }
+
+ x->cursor_foreground_color = fore_pixel;
+ x->cursor_color = pixel;
+
+ if (FRAME_X_WINDOW (f) != 0)
+ {
+ x->cursor_xgcv.background = x->cursor_color;
+ x->cursor_xgcv.foreground = fore_pixel;
+
+ if (FRAME_VISIBLE_P (f))
+ {
+ gui_update_cursor (f, false);
+ gui_update_cursor (f, true);
+ }
+ }
+
+ update_face_from_frame_parameter (f, Qcursor_color, arg);
+}
+
+static void
+pgtk_set_name_internal (struct frame *f, Lisp_Object name)
+{
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ block_input ();
+ {
+ Lisp_Object encoded_name;
+
+ /* As ENCODE_UTF_8 may cause GC and relocation of string data,
+ we use it before x_encode_text that may return string data. */
+ encoded_name = ENCODE_UTF_8 (name);
+
+ gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ SSDATA (encoded_name));
+ }
+ unblock_input ();
+ }
+}
+
+static void
+pgtk_set_name (struct frame *f, Lisp_Object name, int explicit)
+{
+ /* Make sure that requests from lisp code override requests from
+ Emacs redisplay code. */
+ if (explicit)
+ {
+ /* If we're switching from explicit to implicit, we had better
+ update the mode lines and thereby update the title. */
+ if (f->explicit_name && NILP (name))
+ update_mode_lines = 12;
+
+ f->explicit_name = !NILP (name);
+ }
+ else if (f->explicit_name)
+ return;
+
+ if (NILP (name))
+ name = build_string (pgtk_app_name);
+ else
+ CHECK_STRING (name);
+
+ /* Don't change the name if it's already NAME. */
+ if (!NILP (Fstring_equal (name, f->name)))
+ return;
+
+ fset_name (f, name);
+
+ /* Title overrides explicit name. */
+ if (!NILP (f->title))
+ name = f->title;
+
+ pgtk_set_name_internal (f, name);
+}
+
+
+/* This function should be called when the user's lisp code has
+ specified a name for the frame; the name will override any set by the
+ redisplay code. */
+static void
+x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ pgtk_set_name (f, arg, true);
+}
+
+
+/* This function should be called by Emacs redisplay code to set the
+ name; names set this way will never override names set by the user's
+ lisp code. */
+void
+pgtk_implicitly_set_name (struct frame *f, Lisp_Object arg,
+ Lisp_Object oldval)
+{
+ pgtk_set_name (f, arg, false);
+}
+
+
+/* Change the title of frame F to NAME.
+ If NAME is nil, use the frame name as the title. */
+
+static void
+x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
+{
+ /* Don't change the title if it's already NAME. */
+ if (EQ (name, f->title))
+ return;
+
+ update_mode_lines = 22;
+
+ fset_title (f, name);
+
+ if (NILP (name))
+ name = f->name;
+ else
+ CHECK_STRING (name);
+
+ pgtk_set_name_internal (f, name);
+}
+
+
+void
+pgtk_set_doc_edited (void)
+{
+}
+
+
+static void
+x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
+{
+ int nlines;
+ /* Right now, menu bars don't work properly in minibuf-only frames;
+ most of the commands try to apply themselves to the minibuffer
+ frame itself, and get an error because you can't switch buffers
+ in or split the minibuffer window. */
+ if (FRAME_MINIBUF_ONLY_P (f) || FRAME_PARENT_FRAME (f))
+ return;
+
+ if (TYPE_RANGED_FIXNUMP (int, value))
+ nlines = XFIXNUM (value);
+ else
+ nlines = 0;
+
+ /* Make sure we redisplay all windows in this frame. */
+ fset_redisplay (f);
+
+ FRAME_MENU_BAR_LINES (f) = 0;
+ FRAME_MENU_BAR_HEIGHT (f) = 0;
+ if (nlines)
+ {
+ FRAME_EXTERNAL_MENU_BAR (f) = 1;
+ if (FRAME_PGTK_P (f) && f->output_data.pgtk->menubar_widget == 0)
+ /* Make sure next redisplay shows the menu bar. */
+ XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = true;
+ }
+ else
+ {
+ if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
+ free_frame_menubar (f);
+ FRAME_EXTERNAL_MENU_BAR (f) = 0;
+ if (FRAME_X_P (f))
+ f->output_data.pgtk->menubar_widget = 0;
+ }
+
+ adjust_frame_glyphs (f);
+}
+
+/* Set the number of lines used for the tab bar of frame F to VALUE.
+ VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
+ is the old number of tab bar lines. This function changes the
+ height of all windows on frame F to match the new tab bar height.
+ The frame's height doesn't change. */
+
+static void
+x_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
+{
+ int nlines;
+
+ /* Treat tab bars like menu bars. */
+ if (FRAME_MINIBUF_ONLY_P (f))
+ return;
+
+ /* Use VALUE only if an int >= 0. */
+ if (RANGED_FIXNUMP (0, value, INT_MAX))
+ nlines = XFIXNAT (value);
+ else
+ nlines = 0;
+
+ x_change_tab_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
+}
+
+
+/* Set the pixel height of the tab bar of frame F to HEIGHT. */
+void
+x_change_tab_bar_height (struct frame *f, int height)
+{
+ int unit = FRAME_LINE_HEIGHT (f);
+ int old_height = FRAME_TAB_BAR_HEIGHT (f);
+ int lines = (height + unit - 1) / unit;
+ Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
+
+ /* Make sure we redisplay all windows in this frame. */
+ fset_redisplay (f);
+
+ /* Recalculate tab bar and frame text sizes. */
+ FRAME_TAB_BAR_HEIGHT (f) = height;
+ FRAME_TAB_BAR_LINES (f) = lines;
+ store_frame_param (f, Qtab_bar_lines, make_fixnum (lines));
+
+ if (FRAME_X_WINDOW (f) && FRAME_TAB_BAR_HEIGHT (f) == 0)
+ {
+ clear_frame (f);
+ clear_current_matrices (f);
+ }
+
+ if ((height < old_height) && WINDOWP (f->tab_bar_window))
+ clear_glyph_matrix (XWINDOW (f->tab_bar_window)->current_matrix);
+
+ if (!f->tab_bar_resized)
+ {
+ /* As long as tab_bar_resized is false, effectively try to change
+ F's native height. */
+ if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
+ adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+ 1, false, Qtab_bar_lines);
+ else
+ adjust_frame_size (f, -1, -1, 4, false, Qtab_bar_lines);
+
+ f->tab_bar_resized = f->tab_bar_redisplayed;
+ }
+ else
+ /* Any other change may leave the native size of F alone. */
+ adjust_frame_size (f, -1, -1, 3, false, Qtab_bar_lines);
+
+ /* adjust_frame_size might not have done anything, garbage frame
+ here. */
+ adjust_frame_glyphs (f);
+ SET_FRAME_GARBAGED (f);
+ if (FRAME_X_WINDOW (f))
+ pgtk_clear_under_internal_border (f);
+}
+
+/* Set the pixel height of the tool bar of frame F to HEIGHT. */
+static void
+x_change_tool_bar_height (struct frame *f, int height)
+{
+ FRAME_TOOL_BAR_LINES (f) = 0;
+ FRAME_TOOL_BAR_HEIGHT (f) = 0;
+ if (height)
+ {
+ FRAME_EXTERNAL_TOOL_BAR (f) = true;
+ if (FRAME_X_P (f) && f->output_data.pgtk->toolbar_widget == 0)
+ /* Make sure next redisplay shows the tool bar. */
+ XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = true;
+ update_frame_tool_bar (f);
+ }
+ else
+ {
+ if (FRAME_EXTERNAL_TOOL_BAR (f))
+ free_frame_tool_bar (f);
+ FRAME_EXTERNAL_TOOL_BAR (f) = false;
+ }
+}
+
+/* Toolbar support. */
+static void
+x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
+{
+ int nlines;
+
+ /* Treat tool bars like menu bars. */
+ if (FRAME_MINIBUF_ONLY_P (f))
+ return;
+
+ /* Use VALUE only if an int >= 0. */
+ if (RANGED_FIXNUMP (0, value, INT_MAX))
+ nlines = XFIXNAT (value);
+ else
+ nlines = 0;
+
+ x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
+
+}
+
+static void
+x_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ int border = check_int_nonnegative (arg);
+
+ if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f))
+ {
+ f->child_frame_border_width = border;
+
+ if (FRAME_X_WINDOW (f))
+ {
+ adjust_frame_size (f, -1, -1, 3, false, Qchild_frame_border_width);
+ pgtk_clear_under_internal_border (f);
+ }
+ }
+
+}
+
+static void
+x_set_internal_border_width (struct frame *f, Lisp_Object arg,
+ Lisp_Object oldval)
+{
+ int border = check_int_nonnegative (arg);
+
+ if (border != FRAME_INTERNAL_BORDER_WIDTH (f))
+ {
+ f->internal_border_width = border;
+
+ if (FRAME_X_WINDOW (f))
+ {
+ adjust_frame_size (f, -1, -1, 3, false, Qinternal_border_width);
+ pgtk_clear_under_internal_border (f);
+ }
+ }
+}
+
+static void
+x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ bool result;
+
+ if (STRINGP (arg))
+ {
+ if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
+ return;
+ }
+ else if (!STRINGP (oldval) && NILP (oldval) == NILP (arg))
+ return;
+
+ block_input ();
+ if (NILP (arg))
+ result = pgtk_text_icon (f,
+ SSDATA ((!NILP (f->icon_name)
+ ? f->icon_name : f->name)));
+ else
+ result = FRAME_TERMINAL (f)->set_bitmap_icon_hook (f, arg);
+
+ if (result)
+ {
+ unblock_input ();
+ error ("No icon window available");
+ }
+
+ unblock_input ();
+}
+
+static void
+x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ bool result;
+
+ if (STRINGP (arg))
+ {
+ if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
+ return;
+ }
+ else if (!NILP (arg) || NILP (oldval))
+ return;
+
+ fset_icon_name (f, arg);
+
+ block_input ();
+
+ result = pgtk_text_icon (f,
+ SSDATA ((!NILP (f->icon_name)
+ ? f->icon_name
+ : !NILP (f->title)
+ ? f->title : f->name)));
+
+ if (result)
+ {
+ unblock_input ();
+ error ("No icon window available");
+ }
+
+ unblock_input ();
+}
+
+/* This is the same as the xfns.c definition. */
+static void
+x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ set_frame_cursor_types (f, arg);
+}
+
+/* called to set mouse pointer color, but all other terms use it to
+ initialize pointer types (and don't set the color ;) */
+static void
+x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+}
+
+
+static void
+x_icon (struct frame *f, Lisp_Object parms)
+/* --------------------------------------------------------------------------
+ Strangely-named function to set icon position parameters in frame.
+ This is irrelevant under macOS, but might be needed under GNUstep,
+ depending on the window manager used. Note, this is not a standard
+ frame parameter-setter; it is called directly from x-create-frame.
+ -------------------------------------------------------------------------- */
+{
+#if 0
+ Lisp_Object icon_x, icon_y;
+ struct pgtk_display_info *dpyinfo = check_pgtk_display_info (Qnil);
+
+ FRAME_X_OUTPUT (f)->icon_top = -1;
+ FRAME_X_OUTPUT (f)->icon_left = -1;
+
+ /* Set the position of the icon. */
+ icon_x =
+ gui_display_get_arg (dpyinfo, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
+ icon_y =
+ gui_display_get_arg (dpyinfo, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
+ if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
+ {
+ CHECK_NUMBER (icon_x);
+ CHECK_NUMBER (icon_y);
+ FRAME_X_OUTPUT (f)->icon_top = XFIXNUM (icon_y);
+ FRAME_X_OUTPUT (f)->icon_left = XFIXNUM (icon_x);
+ }
+ else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
+ error ("Both left and top icon corners of icon must be specified");
+#endif
+}
+
+/**
+ * x_set_undecorated:
+ *
+ * Set frame F's `undecorated' parameter. If non-nil, F's window-system
+ * window is drawn without decorations, title, minimize/maximize boxes
+ * and external borders. This usually means that the window cannot be
+ * dragged, resized, iconified, maximized or deleted with the mouse. If
+ * nil, draw the frame with all the elements listed above unless these
+ * have been suspended via window manager settings.
+ *
+ * Some window managers may not honor this parameter.
+ */
+static void
+x_set_undecorated (struct frame *f, Lisp_Object new_value,
+ Lisp_Object old_value)
+{
+ if (!EQ (new_value, old_value))
+ {
+ FRAME_UNDECORATED (f) = NILP (new_value) ? false : true;
+ xg_set_undecorated (f, new_value);
+ }
+}
+
+/**
+ * x_set_skip_taskbar:
+ *
+ * Set frame F's `skip-taskbar' parameter. If non-nil, this should
+ * remove F's icon from the taskbar associated with the display of F's
+ * window-system window and inhibit switching to F's window via
+ * <Alt>-<TAB>. If nil, lift these restrictions.
+ *
+ * Some window managers may not honor this parameter.
+ */
+static void
+x_set_skip_taskbar (struct frame *f, Lisp_Object new_value,
+ Lisp_Object old_value)
+{
+ if (!EQ (new_value, old_value))
+ {
+ xg_set_skip_taskbar (f, new_value);
+ FRAME_SKIP_TASKBAR (f) = !NILP (new_value);
+ }
+}
+
+/**
+ * x_set_override_redirect:
+ *
+ * Set frame F's `override_redirect' parameter which, if non-nil, hints
+ * that the window manager doesn't want to deal with F. Usually, such
+ * frames have no decorations and always appear on top of all frames.
+ *
+ * Some window managers may not honor this parameter.
+ */
+static void
+x_set_override_redirect (struct frame *f, Lisp_Object new_value,
+ Lisp_Object old_value)
+{
+ if (!EQ (new_value, old_value))
+ {
+ /* Here (xfwm) override_redirect can be changed for invisible
+ frames only. */
+ pgtk_make_frame_invisible (f);
+
+ xg_set_override_redirect (f, new_value);
+
+ pgtk_make_frame_visible (f);
+ FRAME_OVERRIDE_REDIRECT (f) = !NILP (new_value);
+ }
+}
+
+/* Set icon from FILE for frame F. By using GTK functions the icon
+ may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
+
+bool
+xg_set_icon (struct frame *f, Lisp_Object file)
+{
+ bool result = false;
+ Lisp_Object found;
+
+ if (!FRAME_GTK_OUTER_WIDGET (f))
+ return false;
+
+ found = image_find_image_file (file);
+
+ if (!NILP (found))
+ {
+ GdkPixbuf *pixbuf;
+ GError *err = NULL;
+ char *filename = SSDATA (ENCODE_FILE (found));
+ block_input ();
+
+ pixbuf = gdk_pixbuf_new_from_file (filename, &err);
+
+ if (pixbuf)
+ {
+ gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ pixbuf);
+ g_object_unref (pixbuf);
+
+ result = true;
+ }
+ else
+ g_error_free (err);
+
+ unblock_input ();
+ }
+
+ return result;
+}
+
+bool
+xg_set_icon_from_xpm_data (struct frame *f, const char **data)
+{
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (data);
+
+ if (!pixbuf)
+ return false;
+
+ if (!FRAME_GTK_OUTER_WIDGET (f))
+ return false;
+
+ gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
+ g_object_unref (pixbuf);
+ return true;
+}
+
+static void
+pgtk_set_sticky (struct frame *f, Lisp_Object new_value,
+ Lisp_Object old_value)
+{
+ if (!FRAME_GTK_OUTER_WIDGET (f))
+ return;
+
+ if (!NILP (new_value))
+ gtk_window_stick (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
+ else
+ gtk_window_unstick (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
+}
+
+static void
+pgtk_set_tool_bar_position (struct frame *f,
+ Lisp_Object new_value, Lisp_Object old_value)
+{
+ Lisp_Object choice = list4 (Qleft, Qright, Qtop, Qbottom);
+
+ if (!NILP (Fmemq (new_value, choice)))
+ {
+ if (!EQ (new_value, old_value))
+ {
+ xg_change_toolbar_position (f, new_value);
+ fset_tool_bar_position (f, new_value);
+ }
+ }
+ else
+ wrong_choice (choice, new_value);
+}
+
+static void
+pgtk_set_scroll_bar_foreground (struct frame *f, Lisp_Object new_value,
+ Lisp_Object old_value)
+{
+ GtkCssProvider *css_provider =
+ FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider;
+
+ if (NILP (new_value))
+ {
+ gtk_css_provider_load_from_data (css_provider, "", -1, NULL);
+ update_face_from_frame_parameter (f, Qscroll_bar_foreground, new_value);
+ }
+ else if (STRINGP (new_value))
+ {
+ Emacs_Color rgb;
+
+ if (!pgtk_parse_color (f, SSDATA (new_value), &rgb))
+ error ("Unknown color.");
+
+ /* On pgtk, this frame parameter should be ignored, and honor gtk theme. */
+#if 0
+ char css[64];
+ sprintf (css, "scrollbar slider { background-color: #%06x; }",
+ (unsigned int) rgb.pixel & 0xffffff);
+ gtk_css_provider_load_from_data (css_provider, css, -1, NULL);
+#endif
+ update_face_from_frame_parameter (f, Qscroll_bar_foreground, new_value);
+
+ }
+ else
+ error ("Invalid scroll-bar-foreground.");
+}
+
+static void
+pgtk_set_scroll_bar_background (struct frame *f, Lisp_Object new_value,
+ Lisp_Object old_value)
+{
+ GtkCssProvider *css_provider =
+ FRAME_X_OUTPUT (f)->scrollbar_background_css_provider;
+
+ if (NILP (new_value))
+ {
+ gtk_css_provider_load_from_data (css_provider, "", -1, NULL);
+ update_face_from_frame_parameter (f, Qscroll_bar_background, new_value);
+ }
+ else if (STRINGP (new_value))
+ {
+ Emacs_Color rgb;
+
+ if (!pgtk_parse_color (f, SSDATA (new_value), &rgb))
+ error ("Unknown color.");
+
+ /* On pgtk, this frame parameter should be ignored, and honor gtk theme. */
+#if 0
+ char css[64];
+ sprintf (css, "scrollbar trough { background-color: #%06x; }",
+ (unsigned int) rgb.pixel & 0xffffff);
+ gtk_css_provider_load_from_data (css_provider, css, -1, NULL);
+#endif
+ update_face_from_frame_parameter (f, Qscroll_bar_background, new_value);
+
+ }
+ else
+ error ("Invalid scroll-bar-background.");
+}
+
+
+/***********************************************************************
+ Printing
+ ***********************************************************************/
+
+
+DEFUN ("x-export-frames", Fx_export_frames, Sx_export_frames, 0, 2, 0,
+ doc: /* Return image data of FRAMES in TYPE format.
+FRAMES should be nil (the selected frame), a frame, or a list of
+frames (each of which corresponds to one page). Each frame should be
+visible. Optional arg TYPE should be either `pdf' (default), `png',
+`postscript', or `svg'. Supported types are determined by the
+compile-time configuration of cairo.
+
+Note: Text drawn with the `x' font backend is shown with hollow boxes
+unless TYPE is `png'. */)
+ (Lisp_Object frames, Lisp_Object type)
+{
+ Lisp_Object rest, tmp;
+ cairo_surface_type_t surface_type;
+
+ if (!CONSP (frames))
+ frames = list1 (frames);
+
+ tmp = Qnil;
+ for (rest = frames; CONSP (rest); rest = XCDR (rest))
+ {
+ struct frame *f = decode_window_system_frame (XCAR (rest));
+ Lisp_Object frame;
+
+ XSETFRAME (frame, f);
+ if (!FRAME_VISIBLE_P (f))
+ error ("Frames to be exported must be visible.");
+ tmp = Fcons (frame, tmp);
+ }
+ frames = Fnreverse (tmp);
+
+#ifdef CAIRO_HAS_PDF_SURFACE
+ if (NILP (type) || EQ (type, Qpdf))
+ surface_type = CAIRO_SURFACE_TYPE_PDF;
+ else
+#endif
+#ifdef CAIRO_HAS_PNG_FUNCTIONS
+ if (EQ (type, Qpng))
+ {
+ if (!NILP (XCDR (frames)))
+ error ("PNG export cannot handle multiple frames.");
+ surface_type = CAIRO_SURFACE_TYPE_IMAGE;
+ }
+ else
+#endif
+#ifdef CAIRO_HAS_PS_SURFACE
+ if (EQ (type, Qpostscript))
+ surface_type = CAIRO_SURFACE_TYPE_PS;
+ else
+#endif
+#ifdef CAIRO_HAS_SVG_SURFACE
+ if (EQ (type, Qsvg))
+ {
+ /* For now, we stick to SVG 1.1. */
+ if (!NILP (XCDR (frames)))
+ error ("SVG export cannot handle multiple frames.");
+ surface_type = CAIRO_SURFACE_TYPE_SVG;
+ }
+ else
+#endif
+ error ("Unsupported export type");
+
+ return pgtk_cr_export_frames (frames, surface_type);
+}
+
+
+/* Note: see frame.c for template, also where generic functions are impl */
+frame_parm_handler pgtk_frame_parm_handlers[] = {
+ gui_set_autoraise, /* generic OK */
+ gui_set_autolower, /* generic OK */
+ x_set_background_color,
+ x_set_border_color,
+ gui_set_border_width,
+ x_set_cursor_color,
+ x_set_cursor_type,
+ gui_set_font, /* generic OK */
+ x_set_foreground_color,
+ x_set_icon_name,
+ x_set_icon_type,
+ x_set_child_frame_border_width,
+ x_set_internal_border_width, /* generic OK */
+ gui_set_right_divider_width,
+ gui_set_bottom_divider_width,
+ x_set_menu_bar_lines,
+ x_set_mouse_color,
+ x_explicitly_set_name,
+ gui_set_scroll_bar_width, /* generic OK */
+ gui_set_scroll_bar_height, /* generic OK */
+ x_set_title,
+ gui_set_unsplittable, /* generic OK */
+ gui_set_vertical_scroll_bars, /* generic OK */
+ gui_set_horizontal_scroll_bars, /* generic OK */
+ gui_set_visibility, /* generic OK */
+ x_set_tab_bar_lines,
+ x_set_tool_bar_lines,
+ pgtk_set_scroll_bar_foreground,
+ pgtk_set_scroll_bar_background,
+ gui_set_screen_gamma, /* generic OK */
+ gui_set_line_spacing, /* generic OK, sets f->extra_line_spacing to int */
+ gui_set_left_fringe, /* generic OK */
+ gui_set_right_fringe, /* generic OK */
+ 0, /* x_set_wait_for_wm */
+ gui_set_fullscreen, /* generic OK */
+ gui_set_font_backend, /* generic OK */
+ gui_set_alpha,
+ pgtk_set_sticky,
+ pgtk_set_tool_bar_position,
+ 0, /* x_set_inhibit_double_buffering */
+ x_set_undecorated,
+ x_set_parent_frame,
+ x_set_skip_taskbar,
+ x_set_no_focus_on_map,
+ x_set_no_accept_focus,
+ x_set_z_group,
+ x_set_override_redirect,
+ gui_set_no_special_glyphs,
+};
+
+
+/* Handler for signals raised during x_create_frame and
+ x_create_tip_frame. FRAME is the frame which is partially
+ constructed. */
+
+static Lisp_Object
+unwind_create_frame (Lisp_Object frame)
+{
+ struct frame *f = XFRAME (frame);
+
+ /* If frame is already dead, nothing to do. This can happen if the
+ display is disconnected after the frame has become official, but
+ before x_create_frame removes the unwind protect. */
+ if (!FRAME_LIVE_P (f))
+ return Qnil;
+
+ /* If frame is ``official'', nothing to do. */
+ if (NILP (Fmemq (frame, Vframe_list)))
+ {
+ /* If the frame's image cache refcount is still the same as our
+ private shadow variable, it means we are unwinding a frame
+ for which we didn't yet call init_frame_faces, where the
+ refcount is incremented. Therefore, we increment it here, so
+ that free_frame_faces, called in x_free_frame_resources
+ below, will not mistakenly decrement the counter that was not
+ incremented yet to account for this new frame. */
+ if (FRAME_IMAGE_CACHE (f) != NULL
+ && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount)
+ FRAME_IMAGE_CACHE (f)->refcount++;
+
+ x_free_frame_resources (f);
+ free_glyphs (f);
+ return Qt;
+ }
+
+ return Qnil;
+}
+
+static void
+do_unwind_create_frame (Lisp_Object frame)
+{
+ unwind_create_frame (frame);
+}
+
+/* Return the pixel color value for color COLOR_NAME on frame F. If F
+ is a monochrome frame, return MONO_COLOR regardless of what ARG says.
+ Signal an error if color can't be allocated. */
+
+static int
+x_decode_color (struct frame *f, Lisp_Object color_name, int mono_color)
+{
+ Emacs_Color cdef;
+
+ CHECK_STRING (color_name);
+
+ /* Return MONO_COLOR for monochrome frames. */
+ if (FRAME_DISPLAY_INFO (f)->n_planes == 1)
+ return mono_color;
+
+ /* x_defined_color is responsible for coping with failures
+ by looking for a near-miss. */
+ if (pgtk_defined_color (f, SSDATA (color_name), &cdef, true, 0))
+ return cdef.pixel;
+
+ signal_error ("Undefined color", color_name);
+}
+
+void
+pgtk_default_font_parameter (struct frame *f, Lisp_Object parms)
+{
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+ Lisp_Object font_param =
+ gui_display_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
+ RES_TYPE_STRING);
+ Lisp_Object font = Qnil;
+ if (EQ (font_param, Qunbound))
+ 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. */
+ const char *system_font = xsettings_get_system_font ();
+ if (system_font)
+ font = font_open_by_name (f, build_unibyte_string (system_font));
+ }
+
+ if (NILP (font))
+ font = !NILP (font_param) ? font_param
+ : gui_display_get_arg (dpyinfo, parms, Qfont, "font", "Font",
+ RES_TYPE_STRING);
+
+ if (!FONTP (font) && !STRINGP (font))
+ {
+ const char *names[] = {
+ "monospace-10",
+ "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
+ "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
+ "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
+ /* This was formerly the first thing tried, but it finds
+ too many fonts and takes too long. */
+ "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
+ /* If those didn't work, look for something which will
+ at least work. */
+ "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
+ "fixed",
+ NULL
+ };
+ int i;
+
+ for (i = 0; names[i]; i++)
+ {
+ font = font_open_by_name (f, build_unibyte_string (names[i]));
+ if (!NILP (font))
+ break;
+ }
+ if (NILP (font))
+ error ("No suitable font was found");
+ }
+ else if (!NILP (font_param))
+ {
+ /* Remember the explicit font parameter, so we can re-apply it after
+ we've applied the `default' face settings. */
+ AUTO_FRAME_ARG (arg, Qfont_parameter, font_param);
+ gui_set_frame_parameters (f, arg);
+ }
+
+ /* This call will make X resources override any system font setting. */
+ gui_default_parameter (f, parms, Qfont, font, "font", "Font",
+ RES_TYPE_STRING);
+}
+
+static void
+update_watched_scale_factor (struct atimer *timer)
+{
+ struct frame *f = timer->client_data;
+ double scale_factor = FRAME_SCALE_FACTOR (f);
+
+ if (scale_factor != FRAME_X_OUTPUT (f)->watched_scale_factor)
+ {
+ FRAME_X_OUTPUT (f)->watched_scale_factor = scale_factor;
+ pgtk_cr_update_surface_desired_size (f,
+ FRAME_CR_SURFACE_DESIRED_WIDTH (f),
+ FRAME_CR_SURFACE_DESIRED_HEIGHT (f),
+ true);
+ }
+}
+
+/* ==========================================================================
+
+ Lisp definitions
+
+ ========================================================================== */
+
+DEFUN ("pgtk-set-monitor-scale-factor", Fpgtk_set_monitor_scale_factor,
+ Spgtk_set_monitor_scale_factor, 2, 2, 0,
+ doc: /* Set monitor MONITOR-MODEL's scale factor to SCALE-FACTOR.
+Since Gdk's scale factor is integer, physical pixel width/height is
+incorrect when you specify fractional scale factor in compositor.
+If you set scale factor by this function, it is used instead of Gdk's one.
+
+Pass nil as SCALE-FACTOR if you want to reset the specified monitor's
+scale factor. */ )
+ (Lisp_Object monitor_model, Lisp_Object scale_factor)
+{
+ CHECK_STRING (monitor_model);
+ if (!NILP (scale_factor))
+ {
+ CHECK_NUMBER (scale_factor);
+ if (FIXNUMP (scale_factor))
+ {
+ if (XFIXNUM (scale_factor) <= 0)
+ error ("scale factor must be > 0.");
+ }
+ else if (FLOATP (scale_factor))
+ {
+ if (XFLOAT_DATA (scale_factor) <= 0.0)
+ error ("scale factor must be > 0.");
+ }
+ else
+ error ("unknown type of scale-factor");
+ }
+
+ Lisp_Object tem = Fassoc (monitor_model, monitor_scale_factor_alist, Qnil);
+ if (NILP (tem))
+ {
+ if (!NILP (scale_factor))
+ monitor_scale_factor_alist = Fcons (Fcons (monitor_model, scale_factor),
+ monitor_scale_factor_alist);
+ }
+ else
+ Fsetcdr (tem, scale_factor);
+
+ return scale_factor;
+}
+
+DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, 1, 1, 0,
+ doc: /* Make a new X window, which is called a "frame" in Emacs terms.
+Return an Emacs frame object. PARMS is an alist of frame parameters.
+If the parameters specify that the frame should not have a minibuffer,
+and do not specify a specific minibuffer window to use, then
+`default-minibuffer-frame' must be a frame whose minibuffer can be
+shared by the new frame.
+
+This function is an internal primitive--use `make-frame' instead. */ )
+ (Lisp_Object parms)
+{
+ struct frame *f;
+ Lisp_Object frame, tem;
+ Lisp_Object name;
+ bool minibuffer_only = false;
+ bool undecorated = false, override_redirect = false;
+ long window_prompting = 0;
+ ptrdiff_t count = SPECPDL_INDEX ();
+ Lisp_Object display;
+ struct pgtk_display_info *dpyinfo = NULL;
+ Lisp_Object parent, parent_frame;
+ struct kboard *kb;
+
+ parms = Fcopy_alist (parms);
+
+ /* Use this general default value to start with
+ until we know if this frame has a specified name. */
+ Vx_resource_name = Vinvocation_name;
+
+ display =
+ gui_display_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
+ if (EQ (display, Qunbound))
+ display =
+ gui_display_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
+ if (EQ (display, Qunbound))
+ display = Qnil;
+ dpyinfo = check_pgtk_display_info (display);
+ kb = dpyinfo->terminal->kboard;
+
+ if (!dpyinfo->terminal->name)
+ error ("Terminal is not live, can't create new frames on it");
+
+ name =
+ gui_display_get_arg (dpyinfo, parms, Qname, "name", "Name",
+ RES_TYPE_STRING);
+ if (!STRINGP (name) && !EQ (name, Qunbound) && !NILP (name))
+ error ("Invalid frame name--not a string or nil");
+
+ if (STRINGP (name))
+ Vx_resource_name = name;
+
+ /* See if parent window is specified. */
+ parent =
+ gui_display_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL,
+ RES_TYPE_NUMBER);
+ if (EQ (parent, Qunbound))
+ parent = Qnil;
+ if (!NILP (parent))
+ CHECK_NUMBER (parent);
+
+ frame = Qnil;
+ tem =
+ gui_display_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer",
+ "Minibuffer", RES_TYPE_SYMBOL);
+ if (EQ (tem, Qnone) || NILP (tem))
+ f = make_frame_without_minibuffer (Qnil, kb, display);
+ else if (EQ (tem, Qonly))
+ {
+ f = make_minibuffer_frame ();
+ minibuffer_only = true;
+ }
+ else if (WINDOWP (tem))
+ f = make_frame_without_minibuffer (tem, kb, display);
+ else
+ f = make_frame (true);
+
+ parent_frame =
+ gui_display_get_arg (dpyinfo, parms, Qparent_frame, NULL, NULL,
+ RES_TYPE_SYMBOL);
+ /* Accept parent-frame iff parent-id was not specified. */
+ if (!NILP (parent)
+ || EQ (parent_frame, Qunbound)
+ || NILP (parent_frame)
+ || !FRAMEP (parent_frame)
+ || !FRAME_LIVE_P (XFRAME (parent_frame))
+ || !FRAME_PGTK_P (XFRAME (parent_frame)))
+ parent_frame = Qnil;
+
+ fset_parent_frame (f, parent_frame);
+ store_frame_param (f, Qparent_frame, parent_frame);
+
+ if (!NILP
+ (tem =
+ (gui_display_get_arg
+ (dpyinfo, parms, Qundecorated, NULL, NULL, RES_TYPE_BOOLEAN)))
+ && !(EQ (tem, Qunbound)))
+ undecorated = true;
+
+ FRAME_UNDECORATED (f) = undecorated;
+ store_frame_param (f, Qundecorated, undecorated ? Qt : Qnil);
+
+ if (!NILP
+ (tem =
+ (gui_display_get_arg
+ (dpyinfo, parms, Qoverride_redirect, NULL, NULL, RES_TYPE_BOOLEAN)))
+ && !(EQ (tem, Qunbound)))
+ override_redirect = true;
+
+ FRAME_OVERRIDE_REDIRECT (f) = override_redirect;
+ store_frame_param (f, Qoverride_redirect, override_redirect ? Qt : Qnil);
+
+ XSETFRAME (frame, f);
+
+ f->terminal = dpyinfo->terminal;
+
+ f->output_method = output_pgtk;
+ FRAME_X_OUTPUT (f) = xzalloc (sizeof *FRAME_X_OUTPUT (f));
+#if 0
+ FRAME_X_OUTPUT (f)->icon_bitmap = -1;
+#endif
+ FRAME_FONTSET (f) = -1;
+ FRAME_X_OUTPUT (f)->white_relief.pixel = -1;
+ FRAME_X_OUTPUT (f)->black_relief.pixel = -1;
+
+ FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider =
+ gtk_css_provider_new ();
+ FRAME_X_OUTPUT (f)->scrollbar_background_css_provider =
+ gtk_css_provider_new ();
+
+ fset_icon_name (f,
+ gui_display_get_arg (dpyinfo, parms, Qicon_name, "iconName",
+ "Title", RES_TYPE_STRING));
+ if (!STRINGP (f->icon_name))
+ fset_icon_name (f, Qnil);
+
+ FRAME_DISPLAY_INFO (f) = dpyinfo;
+
+ /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
+ record_unwind_protect (do_unwind_create_frame, frame);
+
+ /* These colors will be set anyway later, but it's important
+ to get the color reference counts right, so initialize them! */
+ {
+ Lisp_Object black;
+
+ /* Function x_decode_color can signal an error. Make
+ sure to initialize color slots so that we won't try
+ to free colors we haven't allocated. */
+ FRAME_FOREGROUND_PIXEL (f) = -1;
+ FRAME_BACKGROUND_PIXEL (f) = -1;
+ FRAME_X_OUTPUT (f)->cursor_color = -1;
+ FRAME_X_OUTPUT (f)->cursor_foreground_color = -1;
+ FRAME_X_OUTPUT (f)->border_pixel = -1;
+ FRAME_X_OUTPUT (f)->mouse_color = -1;
+
+ black = build_string ("black");
+ FRAME_FOREGROUND_PIXEL (f)
+ = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
+ FRAME_BACKGROUND_PIXEL (f)
+ = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
+ FRAME_X_OUTPUT (f)->cursor_color
+ = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
+ FRAME_X_OUTPUT (f)->cursor_foreground_color
+ = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
+ FRAME_X_OUTPUT (f)->border_pixel
+ = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
+ FRAME_X_OUTPUT (f)->mouse_color
+ = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
+ }
+
+ /* Specify the parent under which to make this X window. */
+ if (!NILP (parent))
+ {
+ FRAME_X_OUTPUT (f)->parent_desc = (Window) XFIXNAT (parent);
+ FRAME_X_OUTPUT (f)->explicit_parent = true;
+ }
+ else
+ {
+ FRAME_X_OUTPUT (f)->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
+ FRAME_X_OUTPUT (f)->explicit_parent = false;
+ }
+
+ /* Set the name; the functions to which we pass f expect the name to
+ be set. */
+ if (EQ (name, Qunbound) || NILP (name))
+ {
+ fset_name (f, build_string (dpyinfo->x_id_name));
+ f->explicit_name = false;
+ }
+ else
+ {
+ fset_name (f, name);
+ f->explicit_name = true;
+ /* Use the frame's title when getting resources for this frame. */
+ specbind (Qx_resource_name, name);
+ }
+
+ register_font_driver (&ftcrfont_driver, f);
+#ifdef HAVE_HARFBUZZ
+ register_font_driver (&ftcrhbfont_driver, f);
+#endif /* HAVE_HARFBUZZ */
+
+ image_cache_refcount =
+ FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
+
+ gui_default_parameter (f, parms, Qfont_backend, Qnil,
+ "fontBackend", "FontBackend", RES_TYPE_STRING);
+
+ /* Extract the window parameters from the supplied values
+ that are needed to determine window geometry. */
+ pgtk_default_font_parameter (f, parms);
+ if (!FRAME_FONT (f))
+ {
+ delete_frame (frame, Qnoelisp);
+ error ("Invalid frame font");
+ }
+
+ /* Frame contents get displaced if an embedded X window has a border. */
+#if 0
+ if (!FRAME_X_EMBEDDED_P (f))
+#endif
+ gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
+ "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
+
+ /* This defaults to 1 in order to match xterm. We recognize either
+ internalBorderWidth or internalBorder (which is what xterm calls
+ it). */
+ if (NILP (Fassq (Qinternal_border_width, parms)))
+ {
+ Lisp_Object value;
+
+ value = gui_display_get_arg (dpyinfo, parms, Qinternal_border_width,
+ "internalBorder", "internalBorder",
+ RES_TYPE_NUMBER);
+ if (!EQ (value, Qunbound))
+ parms = Fcons (Fcons (Qinternal_border_width, value), parms);
+ }
+
+ /* Same for child frames. */
+ if (NILP (Fassq (Qchild_frame_border_width, parms)))
+ {
+ Lisp_Object value;
+
+ value = gui_display_get_arg (dpyinfo, parms, Qchild_frame_border_width,
+ "childFrameBorderWidth", "childFrameBorderWidth",
+ RES_TYPE_NUMBER);
+ if (! EQ (value, Qunbound))
+ parms = Fcons (Fcons (Qchild_frame_border_width, value),
+ parms);
+
+ }
+
+ gui_default_parameter (f, parms, Qchild_frame_border_width,
+ make_fixnum (0),
+ "childFrameBorderWidth", "childFrameBorderWidth",
+ RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qinternal_border_width,
+ make_fixnum (0),
+ "internalBorderWidth", "internalBorderWidth",
+ RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0),
+ NULL, NULL, RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
+ NULL, NULL, RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qvertical_scroll_bars,
+ Qright,
+ "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
+ gui_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil,
+ "horizontalScrollBars", "ScrollBars",
+ RES_TYPE_SYMBOL);
+ /* Also do the stuff which must be set before the window exists. */
+ gui_default_parameter (f, parms, Qforeground_color, build_string ("black"),
+ "foreground", "Foreground", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qbackground_color, build_string ("white"),
+ "background", "Background", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qmouse_color, build_string ("black"),
+ "pointerColor", "Foreground", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qborder_color, build_string ("black"),
+ "borderColor", "BorderColor", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qscreen_gamma, Qnil,
+ "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
+ gui_default_parameter (f, parms, Qline_spacing, Qnil,
+ "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qleft_fringe, Qnil,
+ "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qright_fringe, Qnil,
+ "rightFringe", "RightFringe", RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qno_special_glyphs, Qnil,
+ NULL, NULL, RES_TYPE_BOOLEAN);
+
+ gui_default_parameter (f, parms, Qscroll_bar_foreground, Qnil,
+ "scrollBarForeground", "ScrollBarForeground",
+ RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qscroll_bar_background, Qnil,
+ "scrollBarBackground", "ScrollBarBackground",
+ RES_TYPE_STRING);
+
+ /* Init faces before gui_default_parameter is called for the
+ scroll-bar-width parameter because otherwise we end up in
+ init_iterator with a null face cache, which should not happen. */
+ init_frame_faces (f);
+
+ /* We have to call adjust_frame_size here since otherwise
+ x_set_tool_bar_lines will already work with the character sizes
+ installed by init_frame_faces while the frame's pixel size is still
+ calculated from a character size of 1 and we subsequently hit the
+ (height >= 0) assertion in window_box_height.
+
+ The non-pixelwise code apparently worked around this because it
+ had one frame line vs one toolbar line which left us with a zero
+ root window height which was obviously wrong as well ...
+
+ Also process `min-width' and `min-height' parameters right here
+ because `frame-windows-min-size' needs them. */
+ tem =
+ gui_display_get_arg (dpyinfo, parms, Qmin_width, NULL, NULL,
+ RES_TYPE_NUMBER);
+ if (NUMBERP (tem))
+ store_frame_param (f, Qmin_width, tem);
+ tem =
+ gui_display_get_arg (dpyinfo, parms, Qmin_height, NULL, NULL,
+ RES_TYPE_NUMBER);
+ if (NUMBERP (tem))
+ store_frame_param (f, Qmin_height, tem);
+ adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
+ FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, true,
+ Qx_create_frame_1);
+
+ /* Set the menu-bar-lines and tool-bar-lines parameters. We don't
+ look up the X resources controlling the menu-bar and tool-bar
+ here; they are processed specially at startup, and reflected in
+ the values of the mode variables. */
+
+ gui_default_parameter (f, parms, Qmenu_bar_lines,
+ NILP (Vmenu_bar_mode)
+ ? make_fixnum (0) : make_fixnum (1),
+ NULL, NULL, RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qtab_bar_lines,
+ NILP (Vtab_bar_mode)
+ ? make_fixnum (0) : make_fixnum (1),
+ NULL, NULL, RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qtool_bar_lines,
+ NILP (Vtool_bar_mode)
+ ? make_fixnum (0) : make_fixnum (1),
+ NULL, NULL, RES_TYPE_NUMBER);
+
+ gui_default_parameter (f, parms, Qbuffer_predicate, Qnil,
+ "bufferPredicate", "BufferPredicate",
+ RES_TYPE_SYMBOL);
+ gui_default_parameter (f, parms, Qtitle, Qnil,
+ "title", "Title", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qwait_for_wm, Qt,
+ "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
+ gui_default_parameter (f, parms, Qtool_bar_position,
+ FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL);
+ gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil,
+ "inhibitDoubleBuffering", "InhibitDoubleBuffering",
+ RES_TYPE_BOOLEAN);
+
+ /* Compute the size of the X window. */
+ window_prompting =
+ gui_figure_window_size (f, parms, true, true);
+
+ tem =
+ gui_display_get_arg (dpyinfo, parms, Qunsplittable, 0, 0,
+ RES_TYPE_BOOLEAN);
+ f->no_split = minibuffer_only || EQ (tem, Qt);
+
+#if 0
+ x_icon_verify (f, parms);
+#endif
+
+ /* Create the X widget or window. */
+ /* x_window (f); */
+ xg_create_frame_widgets (f);
+ pgtk_set_event_handler (f);
+
+
+#define INSTALL_CURSOR(FIELD, NAME) \
+ FRAME_X_OUTPUT (f)->FIELD = gdk_cursor_new_for_display (FRAME_X_DISPLAY (f), GDK_ ## NAME)
+
+ INSTALL_CURSOR (text_cursor, XTERM);
+ INSTALL_CURSOR (nontext_cursor, LEFT_PTR);
+ INSTALL_CURSOR (modeline_cursor, XTERM);
+ INSTALL_CURSOR (hand_cursor, HAND2);
+ INSTALL_CURSOR (hourglass_cursor, WATCH);
+ INSTALL_CURSOR (horizontal_drag_cursor, SB_H_DOUBLE_ARROW);
+ INSTALL_CURSOR (vertical_drag_cursor, SB_V_DOUBLE_ARROW);
+ INSTALL_CURSOR (left_edge_cursor, LEFT_SIDE);
+ INSTALL_CURSOR (right_edge_cursor, RIGHT_SIDE);
+ INSTALL_CURSOR (top_edge_cursor, TOP_SIDE);
+ INSTALL_CURSOR (bottom_edge_cursor, BOTTOM_SIDE);
+ INSTALL_CURSOR (top_left_corner_cursor, TOP_LEFT_CORNER);
+ INSTALL_CURSOR (top_right_corner_cursor, TOP_RIGHT_CORNER);
+ INSTALL_CURSOR (bottom_right_corner_cursor, BOTTOM_RIGHT_CORNER);
+ INSTALL_CURSOR (bottom_left_corner_cursor, BOTTOM_LEFT_CORNER);
+
+#undef INSTALL_CURSOR
+
+ x_icon (f, parms);
+#if 0
+ x_make_gc (f);
+#endif
+
+ /* Now consider the frame official. */
+ f->terminal->reference_count++;
+ FRAME_DISPLAY_INFO (f)->reference_count++;
+ Vframe_list = Fcons (frame, Vframe_list);
+
+ /* We need to do this after creating the X window, so that the
+ icon-creation functions can say whose icon they're describing. */
+ gui_default_parameter (f, parms, Qicon_type, Qt,
+ "bitmapIcon", "BitmapIcon", RES_TYPE_BOOLEAN);
+
+ gui_default_parameter (f, parms, Qauto_raise, Qnil,
+ "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
+ gui_default_parameter (f, parms, Qauto_lower, Qnil,
+ "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
+ gui_default_parameter (f, parms, Qcursor_type, Qbox,
+ "cursorType", "CursorType", RES_TYPE_SYMBOL);
+ gui_default_parameter (f, parms, Qscroll_bar_width, Qnil,
+ "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qscroll_bar_height, Qnil,
+ "scrollBarHeight", "ScrollBarHeight",
+ RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qalpha, Qnil,
+ "alpha", "Alpha", RES_TYPE_NUMBER);
+
+ if (!NILP (parent_frame))
+ {
+ struct frame *p = XFRAME (parent_frame);
+
+ block_input ();
+
+ GtkWidget *fixed = FRAME_GTK_WIDGET (f);
+ GtkWidget *fixed_of_p = FRAME_GTK_WIDGET (p);
+ GtkWidget *whbox_of_f = gtk_widget_get_parent (fixed);
+ g_object_ref (fixed);
+ gtk_container_remove (GTK_CONTAINER (whbox_of_f), fixed);
+ gtk_fixed_put (GTK_FIXED (fixed_of_p), fixed, f->left_pos, f->top_pos);
+ gtk_widget_show_all (fixed);
+ g_object_unref (fixed);
+
+ gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
+ FRAME_GTK_OUTER_WIDGET (f) = NULL;
+ FRAME_OUTPUT_DATA (f)->vbox_widget = NULL;
+ FRAME_OUTPUT_DATA (f)->hbox_widget = NULL;
+ FRAME_OUTPUT_DATA (f)->menubar_widget = NULL;
+ FRAME_OUTPUT_DATA (f)->toolbar_widget = NULL;
+ FRAME_OUTPUT_DATA (f)->ttip_widget = NULL;
+ FRAME_OUTPUT_DATA (f)->ttip_lbl = NULL;
+ FRAME_OUTPUT_DATA (f)->ttip_window = NULL;
+
+ unblock_input ();
+ }
+
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ GList *w = gtk_container_get_children (GTK_CONTAINER (FRAME_GTK_OUTER_WIDGET (f)));
+ for (; w != NULL; w = w->next)
+ gtk_widget_show_all (GTK_WIDGET (w->data));
+ }
+
+ gui_default_parameter (f, parms, Qno_focus_on_map, Qnil,
+ NULL, NULL, RES_TYPE_BOOLEAN);
+ gui_default_parameter (f, parms, Qno_accept_focus, Qnil,
+ NULL, NULL, RES_TYPE_BOOLEAN);
+
+ /* Create the menu bar. */
+ if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
+ {
+ /* If this signals an error, we haven't set size hints for the
+ frame and we didn't make it visible. */
+ initialize_frame_menubar (f);
+
+ }
+
+ /* Consider frame official, now. */
+ f->can_set_window_size = true;
+
+ /* Tell the server what size and position, etc, we want, and how
+ badly we want them. This should be done after we have the menu
+ bar so that its size can be taken into account. */
+ block_input ();
+ x_wm_set_size_hint (f, window_prompting, false);
+ unblock_input ();
+
+ adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+ 0, true, Qx_create_frame_2);
+
+ /* Process fullscreen parameter here in the hope that normalizing a
+ fullheight/fullwidth frame will produce the size set by the last
+ adjust_frame_size call. */
+ gui_default_parameter (f, parms, Qfullscreen, Qnil,
+ "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
+
+ /* Make the window appear on the frame and enable display, unless
+ the caller says not to. However, with explicit parent, Emacs
+ cannot control visibility, so don't try. */
+ if (!FRAME_X_OUTPUT (f)->explicit_parent)
+ {
+ Lisp_Object visibility
+ =
+ gui_display_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
+ RES_TYPE_SYMBOL);
+
+ if (EQ (visibility, Qicon))
+ pgtk_iconify_frame (f);
+ else
+ {
+ if (EQ (visibility, Qunbound))
+ visibility = Qt;
+
+ if (!NILP (visibility))
+ pgtk_make_frame_visible (f);
+ }
+
+ store_frame_param (f, Qvisibility, visibility);
+ }
+
+ /* Works iff frame has been already mapped. */
+ gui_default_parameter (f, parms, Qskip_taskbar, Qnil,
+ NULL, NULL, RES_TYPE_BOOLEAN);
+ /* The `z-group' parameter works only for visible frames. */
+ gui_default_parameter (f, parms, Qz_group, Qnil,
+ NULL, NULL, RES_TYPE_SYMBOL);
+
+ /* Initialize `default-minibuffer-frame' in case this is the first
+ frame on this terminal. */
+ if (FRAME_HAS_MINIBUF_P (f)
+ && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
+ || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
+ kset_default_minibuffer_frame (kb, frame);
+
+ /* All remaining specified parameters, which have not been "used"
+ by gui_display_get_arg and friends, now go in the misc. alist of the frame. */
+ for (tem = parms; CONSP (tem); tem = XCDR (tem))
+ if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
+ fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
+
+ FRAME_X_OUTPUT (f)->border_color_css_provider = NULL;
+
+ FRAME_X_OUTPUT (f)->cr_surface_visible_bell = NULL;
+ FRAME_X_OUTPUT (f)->atimer_visible_bell = NULL;
+ FRAME_X_OUTPUT (f)->watched_scale_factor = 1.0;
+ struct timespec ts = make_timespec (1, 0);
+ FRAME_X_OUTPUT (f)->scale_factor_atimer = start_atimer(ATIMER_CONTINUOUS,
+ ts,
+ update_watched_scale_factor,
+ f);
+
+ /* Make sure windows on this frame appear in calls to next-window
+ and similar functions. */
+ Vwindow_list = Qnil;
+
+ return unbind_to (count, frame);
+}
+
+
+#if 0
+static int
+pgtk_window_is_ancestor (PGTKWindow * win, PGTKWindow * candidate)
+/* Test whether CANDIDATE is an ancestor window of WIN. */
+{
+ if (candidate == NULL)
+ return 0;
+ else if (win == candidate)
+ return 1;
+ else
+ return pgtk_window_is_ancestor (win,[candidate parentWindow]);
+}
+#endif
+
+/**
+ * x_frame_restack:
+ *
+ * Restack frame F1 below frame F2, above if ABOVE_FLAG is non-nil. In
+ * practice this is a two-step action: The first step removes F1's
+ * window-system window from the display. The second step reinserts
+ * F1's window below (above if ABOVE_FLAG is true) that of F2.
+ */
+static void
+pgtk_frame_restack (struct frame *f1, struct frame *f2, bool above_flag)
+{
+ block_input ();
+ xg_frame_restack (f1, f2, above_flag);
+ unblock_input ();
+}
+
+
+DEFUN ("pgtk-frame-restack", Fpgtk_frame_restack, Spgtk_frame_restack, 2, 3, 0,
+ doc: /* Restack FRAME1 below FRAME2.
+This means that if both frames are visible and the display areas of
+these frames overlap, FRAME2 (partially) obscures FRAME1. If optional
+third argument ABOVE is non-nil, restack FRAME1 above FRAME2. This
+means that if both frames are visible and the display areas of these
+frames overlap, FRAME1 (partially) obscures FRAME2.
+
+This may be thought of as an atomic action performed in two steps: The
+first step removes FRAME1's window-step window from the display. The
+second step reinserts FRAME1's window below (above if ABOVE is true)
+that of FRAME2. Hence the position of FRAME2 in its display's Z
+\(stacking) order relative to all other frames excluding FRAME1 remains
+unaltered.
+
+Some window managers may refuse to restack windows. */)
+ (Lisp_Object frame1, Lisp_Object frame2, Lisp_Object above)
+{
+ struct frame *f1 = decode_live_frame (frame1);
+ struct frame *f2 = decode_live_frame (frame2);
+
+ if (!(FRAME_GTK_OUTER_WIDGET (f1) && FRAME_GTK_OUTER_WIDGET (f2)))
+ error ("Cannot restack frames");
+ pgtk_frame_restack (f1, f2, !NILP (above));
+ return Qt;
+}
+
+#ifdef HAVE_GSETTINGS
+
+#define RESOURCE_KEY_MAX_LEN 128
+#define SCHEMA_ID "org.gnu.emacs.defaults"
+#define PATH_FOR_CLASS_TYPE "/org/gnu/emacs/defaults-by-class/"
+#define PATH_PREFIX_FOR_NAME_TYPE "/org/gnu/emacs/defaults-by-name/"
+
+static inline int
+pgtk_is_lower_char (int c)
+{
+ return c >= 'a' && c <= 'z';
+}
+
+static inline int
+pgtk_is_upper_char (int c)
+{
+ return c >= 'A' && c <= 'Z';
+}
+
+static inline int
+pgtk_is_numeric_char (int c)
+{
+ return c >= '0' && c <= '9';
+}
+
+static GSettings *
+parse_resource_key (const char *res_key, char *setting_key)
+{
+ char path[32 + RESOURCE_KEY_MAX_LEN];
+ const char *sp = res_key;
+ char *dp;
+
+ /*
+ * res_key="emacs.cursorBlink"
+ * -> path="/org/gnu/emacs/defaults-by-name/emacs/"
+ * setting_key="cursor-blink"
+ *
+ * res_key="Emacs.CursorBlink"
+ * -> path="/org/gnu/emacs/defaults-by-class/"
+ * setting_key="cursor-blink"
+ *
+ * Returns GSettings* if setting_key exists in schema, otherwise NULL.
+ */
+
+ /* generate path */
+ if (pgtk_is_upper_char (*sp))
+ {
+ /* First letter is upper case. It should be "Emacs",
+ * but don't care.
+ */
+ strcpy (path, PATH_FOR_CLASS_TYPE);
+ while (*sp != '\0')
+ {
+ if (*sp == '.')
+ break;
+ sp++;
+ }
+ }
+ else
+ {
+ strcpy (path, PATH_PREFIX_FOR_NAME_TYPE);
+ dp = path + strlen (path);
+ while (*sp != '\0')
+ {
+ int c = *sp;
+ if (c == '.')
+ break;
+ if (pgtk_is_lower_char (c))
+ (void) 0; /* lower -> NOP */
+ else if (pgtk_is_upper_char (c))
+ c = c - 'A' + 'a'; /* upper -> lower */
+ else if (pgtk_is_numeric_char (c))
+ (void) 0; /* numeric -> NOP */
+ else
+ return NULL; /* invalid */
+ *dp++ = c;
+ sp++;
+ }
+ *dp++ = '/'; /* must ends with '/' */
+ *dp = '\0';
+ }
+
+ if (*sp++ != '.')
+ return NULL;
+
+ /* generate setting_key */
+ dp = setting_key;
+ while (*sp != '\0')
+ {
+ int c = *sp;
+ if (pgtk_is_lower_char (c))
+ (void) 0; /* lower -> NOP */
+ else if (pgtk_is_upper_char (c))
+ {
+ c = c - 'A' + 'a'; /* upper -> lower */
+ if (dp != setting_key)
+ *dp++ = '-'; /* store '-' unless first char */
+ }
+ else if (pgtk_is_numeric_char (c))
+ (void) 0; /* numeric -> NOP */
+ else
+ return NULL; /* invalid */
+
+ *dp++ = c;
+ sp++;
+ }
+ *dp = '\0';
+
+ /* check existence of setting_key */
+ GSettingsSchemaSource *ssrc = g_settings_schema_source_get_default ();
+ GSettingsSchema *scm = g_settings_schema_source_lookup (ssrc, SCHEMA_ID, FALSE);
+ if (!scm)
+ return NULL; /* *.schema.xml is not installed. */
+ if (!g_settings_schema_has_key (scm, setting_key))
+ {
+ g_settings_schema_unref (scm);
+ return NULL;
+ }
+
+ /* create GSettings, and return it */
+ GSettings *gs = g_settings_new_full (scm, NULL, path);
+
+ g_settings_schema_unref (scm);
+ return gs;
+}
+
+const char *
+pgtk_get_defaults_value (const char *key)
+{
+ char skey[(RESOURCE_KEY_MAX_LEN + 1) * 2];
+
+ if (strlen (key) >= RESOURCE_KEY_MAX_LEN)
+ error ("resource key too long.");
+
+ GSettings *gs = parse_resource_key (key, skey);
+ if (gs == NULL)
+ {
+ return NULL;
+ }
+
+ gchar *str = g_settings_get_string (gs, skey);
+
+ /* There is no timing to free str.
+ * So, copy it here and free it.
+ *
+ * MEMO: Resource values for emacs shouldn't need such a long string value.
+ */
+ static char holder[128];
+ strncpy (holder, str, 128);
+ holder[127] = '\0';
+
+ g_object_unref (gs);
+ g_free (str);
+ return holder[0] != '\0' ? holder : NULL;
+}
+
+static void
+pgtk_set_defaults_value (const char *key, const char *value)
+{
+ char skey[(RESOURCE_KEY_MAX_LEN + 1) * 2];
+
+ if (strlen (key) >= RESOURCE_KEY_MAX_LEN)
+ error ("resource key too long.");
+
+ GSettings *gs = parse_resource_key (key, skey);
+ if (gs == NULL)
+ error ("unknown resource key.");
+
+ if (value != NULL)
+ {
+ g_settings_set_string (gs, skey, value);
+ }
+ else
+ {
+ g_settings_reset (gs, skey);
+ }
+
+ g_object_unref (gs);
+}
+
+#undef RESOURCE_KEY_MAX_LEN
+#undef SCHEMA_ID
+#undef PATH_FOR_CLASS_TYPE
+#undef PATH_PREFIX_FOR_NAME_TYPE
+
+#else /* not HAVE_GSETTINGS */
+
+const char *
+pgtk_get_defaults_value (const char *key)
+{
+ return NULL;
+}
+
+static void
+pgtk_set_defaults_value (const char *key, const char *value)
+{
+ error ("gsettings not supported.");
+}
+
+#endif
+
+
+DEFUN ("pgtk-set-resource", Fpgtk_set_resource, Spgtk_set_resource, 2, 2, 0,
+ doc: /* Set the value of ATTRIBUTE, of class CLASS, as VALUE, into defaults database. */ )
+ (Lisp_Object attribute, Lisp_Object value)
+{
+ check_window_system (NULL);
+
+ CHECK_STRING (attribute);
+ if (!NILP (value))
+ CHECK_STRING (value);
+
+ char *res = SSDATA (Vx_resource_name);
+ char *attr = SSDATA (attribute);
+ if (attr[0] >= 'A' && attr[0] <= 'Z')
+ res = SSDATA (Vx_resource_class);
+
+ char *key = g_strdup_printf ("%s.%s", res, attr);
+
+ pgtk_set_defaults_value (key, NILP (value) ? NULL : SSDATA (value));
+
+ return Qnil;
+}
+
+
+DEFUN ("x-server-max-request-size", Fx_server_max_request_size, Sx_server_max_request_size, 0, 1, 0,
+ doc: /* This function is a no-op. It is only present for completeness. */ )
+ (Lisp_Object terminal)
+{
+ check_pgtk_display_info (terminal);
+ /* This function has no real equivalent under PGTK. Return nil to
+ indicate this. */
+ return Qnil;
+}
+
+
+DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
+ doc: /* Return the "vendor ID" string of the display server TERMINAL.
+\(Labeling every distributor as a "vendor" embodies the false assumption
+that operating systems cannot be developed and distributed noncommercially.)
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
+{
+ check_pgtk_display_info (terminal);
+ return Qnil;
+}
+
+
+DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
+ doc: /* Return the version numbers of the server of display TERMINAL.
+The value is a list of three integers: the major and minor
+version numbers of the X Protocol in use, and the distributor-specific release
+number. See also the function `x-server-vendor'.
+
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */ )
+ (Lisp_Object terminal)
+{
+ check_pgtk_display_info (terminal);
+ /*NOTE: it is unclear what would best correspond with "protocol";
+ we return 10.3, meaning Panther, since this is roughly the
+ level that GNUstep's APIs correspond to.
+ The last number is where we distinguish between the Apple
+ and GNUstep implementations ("distributor-specific release
+ number") and give int'ized versions of major.minor. */
+ return list3i (0, 0, 0);
+}
+
+
+DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
+ doc: /* Return the number of screens on the display server TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+Note: "screen" here is not in X11's. For the number of physical monitors,
+use `(length \(display-monitor-attributes-list TERMINAL))' instead. */)
+ (Lisp_Object terminal)
+{
+ check_pgtk_display_info (terminal);
+ return make_fixnum (1);
+}
+
+
+DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
+ doc: /* Return the height in millimeters of the the display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the height in millimeters for
+all physical monitors associated with TERMINAL. To get information
+for each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
+{
+ struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
+ GdkDisplay *gdpy;
+ gint n_monitors, i;
+ int height_mm_at_0 = 0, height_mm_at_other = 0;
+
+ block_input ();
+ gdpy = dpyinfo->gdpy;
+ n_monitors = gdk_display_get_n_monitors (gdpy);
+
+ for (i = 0; i < n_monitors; ++i)
+ {
+ GdkRectangle rec;
+
+ GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
+ gdk_monitor_get_geometry (monitor, &rec);
+
+ int mm = gdk_monitor_get_height_mm (monitor);
+
+ if (rec.y == 0)
+ height_mm_at_0 = max (height_mm_at_0, mm);
+ else
+ height_mm_at_other += mm;
+ }
+
+ unblock_input ();
+
+ return make_fixnum (height_mm_at_0 + height_mm_at_other);
+}
+
+
+DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
+ doc: /* Return the width in millimeters of the the display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the width in millimeters for
+all physical monitors associated with TERMINAL. To get information
+for each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
+{
+ struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
+ GdkDisplay *gdpy;
+ gint n_monitors, i;
+ int width_mm_at_0 = 0, width_mm_at_other = 0;
+
+ block_input ();
+ gdpy = dpyinfo->gdpy;
+ n_monitors = gdk_display_get_n_monitors (gdpy);
+
+ for (i = 0; i < n_monitors; ++i)
+ {
+ GdkRectangle rec;
+
+ GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
+ gdk_monitor_get_geometry (monitor, &rec);
+
+ int mm = gdk_monitor_get_width_mm (monitor);
+
+ if (rec.x == 0)
+ width_mm_at_0 = max (width_mm_at_0, mm);
+ else
+ width_mm_at_other += mm;
+ }
+
+ unblock_input ();
+
+ return make_fixnum (width_mm_at_0 + width_mm_at_other);
+}
+
+
+DEFUN ("x-display-backing-store", Fx_display_backing_store, Sx_display_backing_store, 0, 1, 0,
+ doc: /* Return an indication of whether the the display TERMINAL does backing store.
+The value may be `buffered', `retained', or `non-retained'.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
+{
+ check_pgtk_display_info (terminal);
+ return Qnil;
+}
+
+
+DEFUN ("x-display-visual-class", Fx_display_visual_class, Sx_display_visual_class, 0, 1, 0,
+ doc: /* Return the visual class of the the display TERMINAL.
+The value is one of the symbols `static-gray', `gray-scale',
+`static-color', `pseudo-color', `true-color', or `direct-color'.
+
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On PGTK, always return true-color. */)
+ (Lisp_Object terminal)
+{
+ return intern ("true-color");
+}
+
+
+DEFUN ("x-display-save-under", Fx_display_save_under, Sx_display_save_under, 0, 1, 0,
+ doc: /* Return t if TERMINAL supports the save-under feature.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
+{
+ check_pgtk_display_info (terminal);
+ return Qnil;
+}
+
+
+DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection, 1, 3, 0,
+ doc: /* Open a connection to a display server.
+DISPLAY is the name of the display to connect to.
+Optional second arg XRM-STRING is a string of resources in xrdb format.
+If the optional third arg MUST-SUCCEED is non-nil,
+terminate Emacs if we can't open the connection. */)
+ (Lisp_Object display, Lisp_Object resource_string, Lisp_Object must_succeed)
+{
+ struct pgtk_display_info *dpyinfo;
+
+ if (NILP (display))
+ display = build_string ("");
+
+ CHECK_STRING (display);
+
+ nxatoms_of_pgtkselect ();
+ dpyinfo = pgtk_term_init (display, SSDATA (Vx_resource_name));
+ if (dpyinfo == 0)
+ {
+ if (!NILP (must_succeed))
+ fatal ("Display on %s not responding.\n", SSDATA (display));
+ else
+ error ("Display on %s not responding.\n", SSDATA (display));
+ }
+
+ return Qnil;
+}
+
+
+DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection, 1, 1, 0,
+ doc: /* Close the connection to TERMINAL's display server.
+For TERMINAL, specify a terminal object, a frame or a display name (a
+string). If TERMINAL is nil, that stands for the selected frame's
+terminal. */)
+ (Lisp_Object terminal)
+{
+ struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
+
+ if (dpyinfo->reference_count > 0)
+ error ("Display still has frames on it");
+
+ pgtk_delete_terminal (dpyinfo->terminal);
+
+ return Qnil;
+}
+
+
+DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
+ doc: /* Return the list of display names that Emacs has connections to. */)
+ (void)
+{
+ Lisp_Object result = Qnil;
+ struct pgtk_display_info *ndi;
+
+ for (ndi = x_display_list; ndi; ndi = ndi->next)
+ result = Fcons (XCAR (ndi->name_list_element), result);
+
+ return result;
+}
+
+
+DEFUN ("pgtk-hide-others", Fpgtk_hide_others, Spgtk_hide_others, 0, 0, 0,
+ doc: /* Hides all applications other than Emacs. */)
+ (void)
+{
+ check_window_system (NULL);
+ return Qnil;
+}
+
+DEFUN ("pgtk-hide-emacs", Fpgtk_hide_emacs, Spgtk_hide_emacs, 1, 1, 0,
+ doc: /* If ON is non-nil, the entire Emacs application is hidden.
+Otherwise if Emacs is hidden, it is unhidden.
+If ON is equal to `activate', Emacs is unhidden and becomes
+the active application. */)
+ (Lisp_Object on)
+{
+ check_window_system (NULL);
+ return Qnil;
+}
+
+
+DEFUN ("pgtk-font-name", Fpgtk_font_name, Spgtk_font_name, 1, 1, 0,
+ doc: /* Determine font PostScript or family name for font NAME.
+NAME should be a string containing either the font name or an XLFD
+font descriptor. If string contains `fontset' and not
+`fontset-startup', it is left alone. */)
+ (Lisp_Object name)
+{
+ char *nm;
+ CHECK_STRING (name);
+ nm = SSDATA (name);
+
+ if (nm[0] != '-')
+ return name;
+ if (strstr (nm, "fontset") && !strstr (nm, "fontset-startup"))
+ return name;
+
+ char *str = pgtk_xlfd_to_fontname (SSDATA (name));
+ name = build_string (str);
+ xfree (str);
+ return name;
+}
+
+/* ==========================================================================
+
+ Miscellaneous functions not called through hooks
+
+ ========================================================================== */
+
+/* Called from frame.c. */
+struct pgtk_display_info *
+check_x_display_info (Lisp_Object frame)
+{
+ return check_pgtk_display_info (frame);
+}
+
+
+void
+pgtk_set_scroll_bar_default_width (struct frame *f)
+{
+ int unit = FRAME_COLUMN_WIDTH (f);
+ int minw = xg_get_default_scrollbar_width (f);
+ /* A minimum width of 14 doesn't look good for toolkit scroll bars. */
+ FRAME_CONFIG_SCROLL_BAR_COLS (f) = (minw + unit - 1) / unit;
+ FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = minw;
+}
+
+void
+pgtk_set_scroll_bar_default_height (struct frame *f)
+{
+ int height = FRAME_LINE_HEIGHT (f);
+ int min_height = xg_get_default_scrollbar_height (f);
+ /* A minimum height of 14 doesn't look good for toolkit scroll bars. */
+ FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = min_height;
+ FRAME_CONFIG_SCROLL_BAR_LINES (f) = (min_height + height - 1) / height;
+}
+
+/* Terminals implement this instead of x-get-resource directly. */
+const char *
+pgtk_get_string_resource (XrmDatabase rdb, const char *name,
+ const char *class)
+{
+ check_window_system (NULL);
+
+ if (inhibit_x_resources)
+ /* --quick was passed, so this is a no-op. */
+ return NULL;
+
+ const char *res = pgtk_get_defaults_value (name);
+ if (res == NULL)
+ res = pgtk_get_defaults_value (class);
+
+ if (res == NULL)
+ return NULL;
+
+ if (c_strncasecmp (res, "YES", 3) == 0)
+ return "true";
+
+ if (c_strncasecmp (res, "NO", 2) == 0)
+ return "false";
+
+ return res;
+}
+
+
+Lisp_Object
+x_get_focus_frame (struct frame *frame)
+{
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
+ Lisp_Object focus;
+
+ if (!dpyinfo->x_focus_frame)
+ return Qnil;
+
+ XSETFRAME (focus, dpyinfo->x_focus_frame);
+ return focus;
+}
+
+/* ==========================================================================
+
+ Lisp definitions that, for whatever reason, we can't alias as 'ns-XXX'.
+
+ ========================================================================== */
+
+
+DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
+ doc: /* Internal function called by `color-defined-p', which see. */)
+ (Lisp_Object color, Lisp_Object frame)
+{
+ Emacs_Color col;
+ struct frame *f = decode_window_system_frame (frame);
+
+ CHECK_STRING (color);
+
+ if (pgtk_defined_color (f, SSDATA (color), &col, false, false))
+ return Qt;
+ else
+ return Qnil;
+}
+
+
+DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
+ doc: /* Internal function called by `color-values', which see. */)
+ (Lisp_Object color, Lisp_Object frame)
+{
+ Emacs_Color col;
+ struct frame *f = decode_window_system_frame (frame);
+
+ CHECK_STRING (color);
+
+ if (pgtk_defined_color (f, SSDATA (color), &col, false, false))
+ return list3i (col.red, col.green, col.blue);
+ else
+ return Qnil;
+}
+
+
+DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
+ doc: /* Internal function called by `display-color-p', which see. */)
+ (Lisp_Object terminal)
+{
+ check_pgtk_display_info (terminal);
+ return Qt;
+}
+
+
+DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p, 0, 1, 0,
+ doc: /* Return t if the display supports shades of gray.
+Note that color displays do support shades of gray.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
+{
+ return Qnil;
+}
+
+
+DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width, 0, 1, 0,
+ doc: /* Return the width in pixels of the display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the pixel width for all
+physical monitors associated with TERMINAL. To get information for
+each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
+{
+ struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
+ GdkDisplay *gdpy;
+ gint n_monitors, i;
+ int width = 0;
+
+ block_input ();
+ gdpy = dpyinfo->gdpy;
+ n_monitors = gdk_display_get_n_monitors (gdpy);
+
+ for (i = 0; i < n_monitors; ++i)
+ {
+ GdkRectangle rec;
+ double scale = 1;
+
+ GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
+ gdk_monitor_get_geometry (monitor, &rec);
+
+ /* GTK returns scaled sizes for the workareas. */
+ scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (monitor));
+ if (scale == 0.0)
+ scale = gdk_monitor_get_scale_factor (monitor);
+ rec.x = rec.x * scale + 0.5;
+ rec.y = rec.y * scale + 0.5;
+ rec.width = rec.width * scale + 0.5;
+ rec.height = rec.height * scale + 0.5;
+
+ width = max (width, rec.x + rec.width);
+ }
+
+ unblock_input ();
+
+ return make_fixnum (width);
+}
+
+
+DEFUN ("x-display-pixel-height", Fx_display_pixel_height, Sx_display_pixel_height, 0, 1, 0,
+ doc: /* Return the height in pixels of the display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the pixel height for all
+physical monitors associated with TERMINAL. To get information for
+each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
+{
+ struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
+ GdkDisplay *gdpy;
+ gint n_monitors, i;
+ int height = 0;
+
+ block_input ();
+ gdpy = dpyinfo->gdpy;
+ n_monitors = gdk_display_get_n_monitors (gdpy);
+
+ for (i = 0; i < n_monitors; ++i)
+ {
+ GdkRectangle rec;
+ double scale = 1;
+
+ GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
+ gdk_monitor_get_geometry (monitor, &rec);
+
+ /* GTK returns scaled sizes for the workareas. */
+ scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (monitor));
+ if (scale == 0.0)
+ scale = gdk_monitor_get_scale_factor (monitor);
+ rec.x = rec.x * scale + 0.5;
+ rec.y = rec.y * scale + 0.5;
+ rec.width = rec.width * scale + 0.5;
+ rec.height = rec.height * scale + 0.5;
+
+ height = max (height, rec.y + rec.height);
+ }
+
+ unblock_input ();
+
+ return make_fixnum (height);
+}
+
+DEFUN ("pgtk-display-monitor-attributes-list", Fpgtk_display_monitor_attributes_list,
+ Spgtk_display_monitor_attributes_list,
+ 0, 1, 0,
+ doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
+
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+In addition to the standard attribute keys listed in
+`display-monitor-attributes-list', the following keys are contained in
+the attributes:
+
+ source -- String describing the source from which multi-monitor
+ information is obtained, \"Gdk\"
+
+Internal use only, use `display-monitor-attributes-list' instead. */)
+ (Lisp_Object terminal)
+{
+ struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
+ Lisp_Object attributes_list = Qnil;
+
+ GdkDisplay *gdpy;
+ gint primary_monitor = 0, n_monitors, i;
+ Lisp_Object monitor_frames, rest, frame;
+ static const char *source = "Gdk";
+ struct MonitorInfo *monitors;
+
+ block_input ();
+ gdpy = dpyinfo->gdpy;
+ n_monitors = gdk_display_get_n_monitors (gdpy);
+ monitor_frames = make_nil_vector (n_monitors);
+ monitors = xzalloc (n_monitors * sizeof *monitors);
+
+ FOR_EACH_FRAME (rest, frame)
+ {
+ struct frame *f = XFRAME (frame);
+
+ if (FRAME_PGTK_P (f)
+ && FRAME_DISPLAY_INFO (f) == dpyinfo
+ && !FRAME_TOOLTIP_P (f))
+ {
+ GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
+
+ for (i = 0; i < n_monitors; i++)
+ if (gdk_display_get_monitor_at_window (gdpy, gwin)
+ == gdk_display_get_monitor (gdpy, i))
+ break;
+ ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
+ }
+ }
+
+ for (i = 0; i < n_monitors; ++i)
+ {
+ gint width_mm, height_mm;
+ GdkRectangle rec, work;
+ struct MonitorInfo *mi = &monitors[i];
+ double scale = 1;
+
+ GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
+ if (gdk_monitor_is_primary (monitor))
+ primary_monitor = i;
+ gdk_monitor_get_geometry (monitor, &rec);
+
+ width_mm = gdk_monitor_get_width_mm (monitor);
+ height_mm = gdk_monitor_get_height_mm (monitor);
+ gdk_monitor_get_workarea (monitor, &work);
+
+ /* GTK returns scaled sizes for the workareas. */
+ scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (monitor));
+ if (scale == 0.0)
+ scale = gdk_monitor_get_scale_factor (monitor);
+ rec.x = rec.x * scale + 0.5;
+ rec.y = rec.y * scale + 0.5;
+ rec.width = rec.width * scale + 0.5;
+ rec.height = rec.height * scale + 0.5;
+ work.x = work.x * scale + 0.5;
+ work.y = work.y * scale + 0.5;
+ work.width = work.width * scale + 0.5;
+ work.height = work.height * scale + 0.5;
+
+ mi->geom.x = rec.x;
+ mi->geom.y = rec.y;
+ mi->geom.width = rec.width;
+ mi->geom.height = rec.height;
+ mi->work.x = work.x;
+ mi->work.y = work.y;
+ mi->work.width = work.width;
+ mi->work.height = work.height;
+ mi->mm_width = width_mm;
+ mi->mm_height = height_mm;
+ mi->scale_factor = scale;
+
+ dupstring (&mi->name, (gdk_monitor_get_model (monitor)));
+ }
+
+ attributes_list = make_monitor_attribute_list (monitors,
+ n_monitors,
+ primary_monitor,
+ monitor_frames,
+ source);
+ free_monitors (monitors, n_monitors);
+ unblock_input ();
+
+ return attributes_list;
+}
+
+double
+pgtk_frame_scale_factor (struct frame *f)
+{
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+ GdkDisplay *gdpy = dpyinfo->gdpy;
+
+ block_input ();
+
+ GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
+ GdkMonitor *gmon = gdk_display_get_monitor_at_window (gdpy, gwin);
+
+ /* GTK returns scaled sizes for the workareas. */
+ double scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (gmon));
+ if (scale == 0.0)
+ scale = gdk_monitor_get_scale_factor (gmon);
+
+ unblock_input ();
+
+ return scale;
+}
+
+DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes, 0, 1, 0,
+ doc: /* Return the number of bitplanes of the display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
+{
+ check_pgtk_display_info (terminal);
+ return make_fixnum (32);
+}
+
+
+DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells, 0, 1, 0,
+ doc: /* Returns the number of color cells of the display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
+{
+ struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
+ /* We force 24+ bit depths to 24-bit to prevent an overflow. */
+ return make_fixnum (1 << min (dpyinfo->n_planes, 24));
+}
+
+/***********************************************************************
+ Tool tips
+ ***********************************************************************/
+
+/* The frame of the currently visible tooltip. */
+static Lisp_Object tip_frame;
+
+/* The window-system window corresponding to the frame of the
+ currently visible tooltip. */
+GtkWidget *tip_window;
+
+/* A timer that hides or deletes the currently visible tooltip when it
+ fires. */
+static Lisp_Object tip_timer;
+
+/* STRING argument of last `x-show-tip' call. */
+static Lisp_Object tip_last_string;
+
+/* Normalized FRAME argument of last `x-show-tip' call. */
+static Lisp_Object tip_last_frame;
+
+/* PARMS argument of last `x-show-tip' call. */
+static Lisp_Object tip_last_parms;
+
+
+static void
+unwind_create_tip_frame (Lisp_Object frame)
+{
+ Lisp_Object deleted;
+
+ deleted = unwind_create_frame (frame);
+ if (EQ (deleted, Qt))
+ {
+ tip_window = NULL;
+ tip_frame = Qnil;
+ }
+}
+
+
+/* Create a frame for a tooltip on the display described by DPYINFO.
+ PARMS is a list of frame parameters. TEXT is the string to
+ display in the tip frame. Value is the frame.
+
+ Note that functions called here, esp. gui_default_parameter can
+ signal errors, for instance when a specified color name is
+ undefined. We have to make sure that we're in a consistent state
+ when this happens. */
+
+static Lisp_Object
+x_create_tip_frame (struct pgtk_display_info *dpyinfo, Lisp_Object parms, struct frame *p)
+{
+ struct frame *f;
+ Lisp_Object frame;
+ Lisp_Object name;
+ ptrdiff_t count = SPECPDL_INDEX ();
+ bool face_change_before = face_change;
+
+ if (!dpyinfo->terminal->name)
+ error ("Terminal is not live, can't create new frames on it");
+
+ parms = Fcopy_alist (parms);
+
+ /* Get the name of the frame to use for resource lookup. */
+ name = gui_display_get_arg (dpyinfo, parms, Qname, "name", "Name",
+ RES_TYPE_STRING);
+ if (!STRINGP (name)
+ && !EQ (name, Qunbound)
+ && !NILP (name))
+ error ("Invalid frame name--not a string or nil");
+
+ frame = Qnil;
+ f = make_frame (false);
+ f->wants_modeline = false;
+ XSETFRAME (frame, f);
+ record_unwind_protect (unwind_create_tip_frame, frame);
+
+ f->terminal = dpyinfo->terminal;
+
+ /* By setting the output method, we're essentially saying that
+ the frame is live, as per FRAME_LIVE_P. If we get a signal
+ from this point on, x_destroy_window might screw up reference
+ counts etc. */
+ f->output_method = output_pgtk;
+ f->output_data.pgtk = xzalloc (sizeof *f->output_data.pgtk);
+#if 0
+ f->output_data.pgtk->icon_bitmap = -1;
+#endif
+ FRAME_FONTSET (f) = -1;
+ f->output_data.pgtk->white_relief.pixel = -1;
+ f->output_data.pgtk->black_relief.pixel = -1;
+
+ f->tooltip = true;
+ fset_icon_name (f, Qnil);
+ FRAME_DISPLAY_INFO (f) = dpyinfo;
+ f->output_data.pgtk->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
+ f->output_data.pgtk->explicit_parent = false;
+
+ /* These colors will be set anyway later, but it's important
+ to get the color reference counts right, so initialize them! */
+ {
+ Lisp_Object black;
+
+ /* Function x_decode_color can signal an error. Make
+ sure to initialize color slots so that we won't try
+ to free colors we haven't allocated. */
+ FRAME_FOREGROUND_PIXEL (f) = -1;
+ FRAME_BACKGROUND_PIXEL (f) = -1;
+ f->output_data.pgtk->border_pixel = -1;
+
+ black = build_string ("black");
+ FRAME_FOREGROUND_PIXEL (f)
+ = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
+ FRAME_BACKGROUND_PIXEL (f)
+ = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
+ f->output_data.pgtk->border_pixel
+ = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
+ }
+
+ /* Set the name; the functions to which we pass f expect the name to
+ be set. */
+ if (EQ (name, Qunbound) || NILP (name))
+ {
+ fset_name (f, build_string (dpyinfo->x_id_name));
+ f->explicit_name = false;
+ }
+ else
+ {
+ fset_name (f, name);
+ f->explicit_name = true;
+ /* use the frame's title when getting resources for this frame. */
+ specbind (Qx_resource_name, name);
+ }
+
+ register_font_driver (&ftcrfont_driver, f);
+#ifdef HAVE_HARFBUZZ
+ register_font_driver (&ftcrhbfont_driver, f);
+#endif /* HAVE_HARFBUZZ */
+
+ image_cache_refcount =
+ FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
+
+ gui_default_parameter (f, parms, Qfont_backend, Qnil,
+ "fontBackend", "FontBackend", RES_TYPE_STRING);
+
+ /* Extract the window parameters from the supplied values that are
+ needed to determine window geometry. */
+ pgtk_default_font_parameter (f, parms);
+
+ gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
+ "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
+
+ /* This defaults to 2 in order to match xterm. We recognize either
+ internalBorderWidth or internalBorder (which is what xterm calls
+ it). */
+ if (NILP (Fassq (Qinternal_border_width, parms)))
+ {
+ Lisp_Object value;
+
+ value = gui_display_get_arg (dpyinfo, parms, Qinternal_border_width,
+ "internalBorder", "internalBorder",
+ RES_TYPE_NUMBER);
+ if (! EQ (value, Qunbound))
+ parms = Fcons (Fcons (Qinternal_border_width, value),
+ parms);
+ }
+
+ gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (1),
+ "internalBorderWidth", "internalBorderWidth",
+ RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0),
+ NULL, NULL, RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
+ NULL, NULL, RES_TYPE_NUMBER);
+
+ /* Also do the stuff which must be set before the window exists. */
+ gui_default_parameter (f, parms, Qforeground_color, build_string ("black"),
+ "foreground", "Foreground", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qbackground_color, build_string ("white"),
+ "background", "Background", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qmouse_color, build_string ("black"),
+ "pointerColor", "Foreground", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qcursor_color, build_string ("black"),
+ "cursorColor", "Foreground", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qborder_color, build_string ("black"),
+ "borderColor", "BorderColor", RES_TYPE_STRING);
+ gui_default_parameter (f, parms, Qno_special_glyphs, Qnil,
+ NULL, NULL, RES_TYPE_BOOLEAN);
+
+ /* Init faces before gui_default_parameter is called for the
+ scroll-bar-width parameter because otherwise we end up in
+ init_iterator with a null face cache, which should not happen. */
+ init_frame_faces (f);
+
+ f->output_data.pgtk->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
+
+ gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil,
+ "inhibitDoubleBuffering", "InhibitDoubleBuffering",
+ RES_TYPE_BOOLEAN);
+
+ gui_figure_window_size (f, parms, false, false);
+
+ xg_create_frame_widgets (f);
+ pgtk_set_event_handler (f);
+ tip_window = FRAME_GTK_OUTER_WIDGET (f);
+ gtk_window_set_transient_for (GTK_WINDOW (tip_window),
+ GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (p)));
+ gtk_window_set_attached_to (GTK_WINDOW (tip_window), FRAME_GTK_WIDGET (p));
+ gtk_window_set_destroy_with_parent (GTK_WINDOW (tip_window), TRUE);
+ gtk_window_set_decorated (GTK_WINDOW (tip_window), FALSE);
+ gtk_window_set_type_hint (GTK_WINDOW (tip_window), GDK_WINDOW_TYPE_HINT_TOOLTIP);
+ f->output_data.pgtk->current_cursor = f->output_data.pgtk->text_cursor;
+ gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
+ gdk_window_set_cursor (gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f)),
+ f->output_data.pgtk->current_cursor);
+
+#if 0
+ x_make_gc (f);
+#endif
+
+ gui_default_parameter (f, parms, Qauto_raise, Qnil,
+ "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
+ gui_default_parameter (f, parms, Qauto_lower, Qnil,
+ "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
+ gui_default_parameter (f, parms, Qcursor_type, Qbox,
+ "cursorType", "CursorType", RES_TYPE_SYMBOL);
+ gui_default_parameter (f, parms, Qalpha, Qnil,
+ "alpha", "Alpha", RES_TYPE_NUMBER);
+
+ /* Add `tooltip' frame parameter's default value. */
+ if (NILP (Fframe_parameter (frame, Qtooltip)))
+ {
+ AUTO_FRAME_ARG (arg, Qtooltip, Qt);
+ Fmodify_frame_parameters (frame, arg);
+ }
+
+ /* FIXME - can this be done in a similar way to normal frames?
+ https://lists.gnu.org/r/emacs-devel/2007-10/msg00641.html */
+
+ /* Set the `display-type' frame parameter before setting up faces. */
+ {
+ Lisp_Object disptype;
+
+ disptype = intern ("color");
+
+ if (NILP (Fframe_parameter (frame, Qdisplay_type)))
+ {
+ AUTO_FRAME_ARG (arg, Qdisplay_type, disptype);
+ Fmodify_frame_parameters (frame, arg);
+ }
+ }
+
+ /* Set up faces after all frame parameters are known. This call
+ also merges in face attributes specified for new frames.
+
+ Frame parameters may be changed if .Xdefaults contains
+ specifications for the default font. For example, if there is an
+ `Emacs.default.attributeBackground: pink', the `background-color'
+ attribute of the frame get's set, which let's the internal border
+ of the tooltip frame appear in pink. Prevent this. */
+ {
+ Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
+
+ call2 (Qface_set_after_frame_default, frame, Qnil);
+
+ if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
+ {
+ AUTO_FRAME_ARG (arg, Qbackground_color, bg);
+ Fmodify_frame_parameters (frame, arg);
+ }
+ }
+
+ f->no_split = true;
+
+ /* Now that the frame will be official, it counts as a reference to
+ its display and terminal. */
+ FRAME_DISPLAY_INFO (f)->reference_count++;
+ f->terminal->reference_count++;
+
+ /* It is now ok to make the frame official even if we get an error
+ below. And the frame needs to be on Vframe_list or making it
+ visible won't work. */
+ Vframe_list = Fcons (frame, Vframe_list);
+ f->can_set_window_size = true;
+ adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+ 0, true, Qtip_frame);
+
+ /* Setting attributes of faces of the tooltip frame from resources
+ and similar will set face_change, which leads to the clearing of
+ all current matrices. Since this isn't necessary here, avoid it
+ by resetting face_change to the value it had before we created
+ the tip frame. */
+ face_change = face_change_before;
+
+ /* Discard the unwind_protect. */
+ return unbind_to (count, frame);
+}
+
+/* Compute where to display tip frame F. PARMS is the list of frame
+ parameters for F. DX and DY are specified offsets from the current
+ location of the mouse. WIDTH and HEIGHT are the width and height
+ of the tooltip. Return coordinates relative to the root window of
+ the display in *ROOT_X, and *ROOT_Y. */
+
+static void
+compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx,
+ Lisp_Object dy, int width, int height, int *root_x,
+ int *root_y)
+{
+ Lisp_Object left, top, right, bottom;
+ int min_x, min_y, max_x, max_y = -1;
+
+ /* User-specified position? */
+ left = Fcdr (Fassq (Qleft, parms));
+ top = Fcdr (Fassq (Qtop, parms));
+ right = Fcdr (Fassq (Qright, parms));
+ bottom = Fcdr (Fassq (Qbottom, parms));
+
+ /* Move the tooltip window where the mouse pointer is. Resize and
+ show it. */
+ if ((!INTEGERP (left) && !INTEGERP (right))
+ || (!INTEGERP (top) && !INTEGERP (bottom)))
+ {
+ Lisp_Object frame, attributes, monitor, geometry;
+ GdkSeat *seat =
+ gdk_display_get_default_seat (FRAME_DISPLAY_INFO (f)->gdpy);
+ GdkDevice *dev = gdk_seat_get_pointer (seat);
+ GdkScreen *scr;
+
+ block_input ();
+ gdk_device_get_position (dev, &scr, root_x, root_y);
+ unblock_input ();
+
+ XSETFRAME (frame, f);
+ attributes = Fpgtk_display_monitor_attributes_list (frame);
+
+ /* Try to determine the monitor where the mouse pointer is and
+ its geometry. See bug#22549. */
+ while (CONSP (attributes))
+ {
+ monitor = XCAR (attributes);
+ geometry = Fassq (Qgeometry, monitor);
+ if (CONSP (geometry))
+ {
+ min_x = XFIXNUM (Fnth (make_fixnum (1), geometry));
+ min_y = XFIXNUM (Fnth (make_fixnum (2), geometry));
+ max_x = min_x + XFIXNUM (Fnth (make_fixnum (3), geometry));
+ max_y = min_y + XFIXNUM (Fnth (make_fixnum (4), geometry));
+ if (min_x <= *root_x && *root_x < max_x
+ && min_y <= *root_y && *root_y < max_y)
+ {
+ break;
+ }
+ max_y = -1;
+ }
+
+ attributes = XCDR (attributes);
+ }
+ }
+
+ /* It was not possible to determine the monitor's geometry, so we
+ assign some sane defaults here: */
+ if (max_y < 0)
+ {
+ min_x = 0;
+ min_y = 0;
+ max_x = x_display_pixel_width (FRAME_DISPLAY_INFO (f));
+ max_y = x_display_pixel_height (FRAME_DISPLAY_INFO (f));
+ }
+
+ if (INTEGERP (top))
+ *root_y = XFIXNUM (top);
+ else if (INTEGERP (bottom))
+ *root_y = XFIXNUM (bottom) - height;
+ else if (*root_y + XFIXNUM (dy) <= min_y)
+ *root_y = min_y; /* Can happen for negative dy */
+ else if (*root_y + XFIXNUM (dy) + height <= max_y)
+ /* It fits below the pointer */
+ *root_y += XFIXNUM (dy);
+ else if (height + XFIXNUM (dy) + min_y <= *root_y)
+ /* It fits above the pointer. */
+ *root_y -= height + XFIXNUM (dy);
+ else
+ /* Put it on the top. */
+ *root_y = min_y;
+
+ if (INTEGERP (left))
+ *root_x = XFIXNUM (left);
+ else if (INTEGERP (right))
+ *root_x = XFIXNUM (right) - width;
+ else if (*root_x + XFIXNUM (dx) <= min_x)
+ *root_x = 0; /* Can happen for negative dx */
+ else if (*root_x + XFIXNUM (dx) + width <= max_x)
+ /* It fits to the right of the pointer. */
+ *root_x += XFIXNUM (dx);
+ else if (width + XFIXNUM (dx) + min_x <= *root_x)
+ /* It fits to the left of the pointer. */
+ *root_x -= width + XFIXNUM (dx);
+ else
+ /* Put it left justified on the screen -- it ought to fit that way. */
+ *root_x = min_x;
+}
+
+
+/* Hide tooltip. Delete its frame if DELETE is true. */
+static Lisp_Object
+x_hide_tip (bool delete)
+{
+ if (!NILP (tip_timer))
+ {
+ call1 (Qcancel_timer, tip_timer);
+ tip_timer = Qnil;
+ }
+
+ /* Any GTK+ system tooltip can be found via the x_output structure of
+ tip_last_frame, provided that frame is still live. Any Emacs
+ tooltip is found via the tip_frame variable. Note that the current
+ value of x_gtk_use_system_tooltips might not be the same as used
+ for the tooltip we have to hide, see Bug#30399. */
+ if ((NILP (tip_last_frame) && NILP (tip_frame))
+ || (!x_gtk_use_system_tooltips
+ && !delete
+ && FRAMEP (tip_frame)
+ && FRAME_LIVE_P (XFRAME (tip_frame))
+ && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
+ /* Either there's no tooltip to hide or it's an already invisible
+ Emacs tooltip and we don't want to change its type. Return
+ quickly. */
+ return Qnil;
+ else
+ {
+ ptrdiff_t count;
+ Lisp_Object was_open = Qnil;
+
+ count = SPECPDL_INDEX ();
+ specbind (Qinhibit_redisplay, Qt);
+ specbind (Qinhibit_quit, Qt);
+
+ /* Try to hide the GTK+ system tip first. */
+ if (FRAMEP (tip_last_frame))
+ {
+ struct frame *f = XFRAME (tip_last_frame);
+
+ if (FRAME_LIVE_P (f))
+ {
+ if (xg_hide_tooltip (f))
+ was_open = Qt;
+ }
+ }
+
+ /* When using GTK+ system tooltips (compare Bug#41200) reset
+ tip_last_frame. It will be reassigned when showing the next
+ GTK+ system tooltip. */
+ if (x_gtk_use_system_tooltips)
+ tip_last_frame = Qnil;
+
+ /* Now look whether there's an Emacs tip around. */
+ if (FRAMEP (tip_frame))
+ {
+ struct frame *f = XFRAME (tip_frame);
+
+ if (FRAME_LIVE_P (f))
+ {
+ if (delete || x_gtk_use_system_tooltips)
+ {
+ /* Delete the Emacs tooltip frame when DELETE is true
+ or we change the tooltip type from an Emacs one to
+ a GTK+ system one. */
+ delete_frame (tip_frame, Qnil);
+ tip_frame = Qnil;
+ }
+ else
+ pgtk_make_frame_invisible (f);
+
+ was_open = Qt;
+ }
+ else
+ tip_frame = Qnil;
+ }
+ else
+ tip_frame = Qnil;
+
+ return unbind_to (count, was_open);
+ }
+}
+
+DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
+ doc: /* Show STRING in a "tooltip" window on frame FRAME.
+A tooltip window is a small X window displaying a string.
+
+This is an internal function; Lisp code should call `tooltip-show'.
+
+FRAME nil or omitted means use the selected frame.
+
+PARMS is an optional list of frame parameters which can be used to
+change the tooltip's appearance.
+
+Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
+means use the default timeout of 5 seconds.
+
+If the list of frame parameters PARMS contains a `left' parameter,
+display the tooltip at that x-position. If the list of frame parameters
+PARMS contains no `left' but a `right' parameter, display the tooltip
+right-adjusted at that x-position. Otherwise display it at the
+x-position of the mouse, with offset DX added (default is 5 if DX isn't
+specified).
+
+Likewise for the y-position: If a `top' frame parameter is specified, it
+determines the position of the upper edge of the tooltip window. If a
+`bottom' parameter but no `top' frame parameter is specified, it
+determines the position of the lower edge of the tooltip window.
+Otherwise display the tooltip window at the y-position of the mouse,
+with offset DY added (default is -10).
+
+A tooltip's maximum size is specified by `x-max-tooltip-size'.
+Text larger than the specified size is clipped. */)
+ (Lisp_Object string, Lisp_Object frame, Lisp_Object parms,
+ Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
+{
+ struct frame *f, *tip_f;
+ struct window *w;
+ int root_x, root_y;
+ struct buffer *old_buffer;
+ struct text_pos pos;
+ int width, height;
+ int old_windows_or_buffers_changed = windows_or_buffers_changed;
+ ptrdiff_t count = SPECPDL_INDEX ();
+ ptrdiff_t count_1;
+ Lisp_Object window, size, tip_buf;
+ AUTO_STRING (tip, " *tip*");
+
+ specbind (Qinhibit_redisplay, Qt);
+
+ CHECK_STRING (string);
+ if (SCHARS (string) == 0)
+ string = make_unibyte_string (" ", 1);
+
+ if (NILP (frame))
+ frame = selected_frame;
+ f = decode_window_system_frame (frame);
+
+ if (!FRAME_GTK_OUTER_WIDGET (f))
+ return unbind_to (count, Qnil);
+
+ if (NILP (timeout))
+ timeout = make_fixnum (5);
+ else
+ CHECK_FIXNAT (timeout);
+
+ if (NILP (dx))
+ dx = make_fixnum (5);
+ else
+ CHECK_FIXNUM (dx);
+
+ if (NILP (dy))
+ dy = make_fixnum (-10);
+ else
+ CHECK_FIXNUM (dy);
+
+ if (x_gtk_use_system_tooltips)
+ {
+ bool ok;
+
+ /* Hide a previous tip, if any. */
+ Fx_hide_tip ();
+
+ block_input ();
+
+ ok = true;
+ xg_show_tooltip (f, string);
+ tip_last_frame = frame;
+
+ unblock_input ();
+ if (ok) goto start_timer;
+ }
+
+ if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
+ {
+ if (FRAME_VISIBLE_P (XFRAME (tip_frame))
+ && EQ (frame, tip_last_frame)
+ && !NILP (Fequal_including_properties (tip_last_string, string))
+ && !NILP (Fequal (tip_last_parms, parms)))
+ {
+ /* Only DX and DY have changed. */
+ tip_f = XFRAME (tip_frame);
+ if (!NILP (tip_timer))
+ {
+ call1 (Qcancel_timer, tip_timer);
+ tip_timer = Qnil;
+ }
+
+ block_input ();
+ compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
+ FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
+ gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (tip_f)), root_x, root_y);
+ unblock_input ();
+
+ goto start_timer;
+ }
+ else if (tooltip_reuse_hidden_frame && EQ (frame, tip_last_frame))
+ {
+ bool delete = false;
+ Lisp_Object tail, elt, parm, last;
+
+ /* Check if every parameter in PARMS has the same value in
+ tip_last_parms. This may destruct tip_last_parms which,
+ however, will be recreated below. */
+ for (tail = parms; CONSP (tail); tail = XCDR (tail))
+ {
+ elt = XCAR (tail);
+ parm = Fcar (elt);
+ /* The left, top, right and bottom parameters are handled
+ by compute_tip_xy so they can be ignored here. */
+ if (!EQ (parm, Qleft) && !EQ (parm, Qtop)
+ && !EQ (parm, Qright) && !EQ (parm, Qbottom))
+ {
+ last = Fassq (parm, tip_last_parms);
+ if (NILP (Fequal (Fcdr (elt), Fcdr (last))))
+ {
+ /* We lost, delete the old tooltip. */
+ delete = true;
+ break;
+ }
+ else
+ tip_last_parms =
+ call2 (Qassq_delete_all, parm, tip_last_parms);
+ }
+ else
+ tip_last_parms =
+ call2 (Qassq_delete_all, parm, tip_last_parms);
+ }
+
+ /* Now check if every parameter in what is left of
+ tip_last_parms with a non-nil value has an association in
+ PARMS. */
+ for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail))
+ {
+ elt = XCAR (tail);
+ parm = Fcar (elt);
+ if (!EQ (parm, Qleft) && !EQ (parm, Qtop) && !EQ (parm, Qright)
+ && !EQ (parm, Qbottom) && !NILP (Fcdr (elt)))
+ {
+ /* We lost, delete the old tooltip. */
+ delete = true;
+ break;
+ }
+ }
+
+ x_hide_tip (delete);
+ }
+ else
+ x_hide_tip (true);
+ }
+ else
+ x_hide_tip (true);
+
+ tip_last_frame = frame;
+ tip_last_string = string;
+ tip_last_parms = parms;
+
+ if (!FRAMEP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
+ {
+ /* Add default values to frame parameters. */
+ if (NILP (Fassq (Qname, parms)))
+ parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
+ if (NILP (Fassq (Qinternal_border_width, parms)))
+ parms = Fcons (Fcons (Qinternal_border_width, make_fixnum (3)), parms);
+ if (NILP (Fassq (Qborder_width, parms)))
+ parms = Fcons (Fcons (Qborder_width, make_fixnum (1)), parms);
+ if (NILP (Fassq (Qborder_color, parms)))
+ parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
+ if (NILP (Fassq (Qbackground_color, parms)))
+ parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
+ parms);
+
+ /* Create a frame for the tooltip, and record it in the global
+ variable tip_frame. */
+ if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms, f)))
+ /* Creating the tip frame failed. */
+ return unbind_to (count, Qnil);
+ }
+
+ tip_f = XFRAME (tip_frame);
+ window = FRAME_ROOT_WINDOW (tip_f);
+ tip_buf = Fget_buffer_create (tip, Qnil);
+ /* We will mark the tip window a "pseudo-window" below, and such
+ windows cannot have display margins. */
+ bset_left_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
+ bset_right_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
+ set_window_buffer (window, tip_buf, false, false);
+ w = XWINDOW (window);
+ w->pseudo_window_p = true;
+
+ /* Set up the frame's root window. Note: The following code does not
+ try to size the window or its frame correctly. Its only purpose is
+ to make the subsequent text size calculations work. The right
+ sizes should get installed when the toolkit gets back to us. */
+ w->left_col = 0;
+ w->top_line = 0;
+ w->pixel_left = 0;
+ w->pixel_top = 0;
+
+ if (CONSP (Vx_max_tooltip_size)
+ && RANGED_FIXNUMP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
+ && RANGED_FIXNUMP (1, XCDR (Vx_max_tooltip_size), INT_MAX))
+ {
+ w->total_cols = XFIXNAT (XCAR (Vx_max_tooltip_size));
+ w->total_lines = XFIXNAT (XCDR (Vx_max_tooltip_size));
+ }
+ else
+ {
+ w->total_cols = 80;
+ w->total_lines = 40;
+ }
+
+ w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (tip_f);
+ w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (tip_f);
+ FRAME_TOTAL_COLS (tip_f) = w->total_cols;
+ adjust_frame_glyphs (tip_f);
+
+ /* Insert STRING into root window's buffer and fit the frame to the
+ buffer. */
+ count_1 = SPECPDL_INDEX ();
+ old_buffer = current_buffer;
+ set_buffer_internal_1 (XBUFFER (w->contents));
+ bset_truncate_lines (current_buffer, Qnil);
+ specbind (Qinhibit_read_only, Qt);
+ specbind (Qinhibit_modification_hooks, Qt);
+ specbind (Qinhibit_point_motion_hooks, Qt);
+ Ferase_buffer ();
+ Finsert (1, &string);
+ clear_glyph_matrix (w->desired_matrix);
+ clear_glyph_matrix (w->current_matrix);
+ SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
+ try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
+ /* Calculate size of tooltip window. */
+ size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil,
+ make_fixnum (w->pixel_height), Qnil,
+ Qnil);
+ /* Add the frame's internal border to calculated size. */
+ width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
+ height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
+
+ /* Calculate position of tooltip frame. */
+ compute_tip_xy (tip_f, parms, dx, dy, width, height, &root_x, &root_y);
+
+ /* Show tooltip frame. */
+ block_input ();
+ gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (tip_f)), width, height);
+ gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (tip_f)), root_x, root_y);
+ unblock_input ();
+
+ pgtk_cr_update_surface_desired_size (tip_f, width, height, false);
+
+ w->must_be_updated_p = true;
+ update_single_window (w);
+ flush_frame (tip_f);
+ set_buffer_internal_1 (old_buffer);
+ unbind_to (count_1, Qnil);
+ windows_or_buffers_changed = old_windows_or_buffers_changed;
+
+ start_timer:
+ /* Let the tip disappear after timeout seconds. */
+ tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
+ intern ("x-hide-tip"));
+
+ return unbind_to (count, Qnil);
+}
+
+
+DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
+ doc: /* Hide the current tooltip window, if there is any.
+Value is t if tooltip was open, nil otherwise. */)
+ (void)
+{
+ return x_hide_tip (!tooltip_reuse_hidden_frame);
+}
+
+/* Return geometric attributes of FRAME. According to the value of
+ ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the inner
+ edges of FRAME, the root window edges of frame (Qroot_edges). Any
+ other value means to return the geometry as returned by
+ Fx_frame_geometry. */
+static Lisp_Object
+frame_geometry (Lisp_Object frame, Lisp_Object attribute)
+{
+ struct frame *f = decode_live_frame (frame);
+ Lisp_Object fullscreen_symbol = Fframe_parameter (frame, Qfullscreen);
+ bool fullscreen = (EQ (fullscreen_symbol, Qfullboth)
+ || EQ (fullscreen_symbol, Qfullscreen));
+ int border = fullscreen ? 0 : f->border_width;
+ int title_height = 0;
+ int native_width = FRAME_PIXEL_WIDTH (f);
+ int native_height = FRAME_PIXEL_HEIGHT (f);
+ int outer_width = native_width + 2 * border;
+ int outer_height = native_height + 2 * border + title_height;
+
+ /* Get these here because they can't be got in configure_event(). */
+ int left_pos, top_pos;
+
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ gtk_window_get_position (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ &left_pos, &top_pos);
+ }
+ else
+ {
+ GtkAllocation alloc;
+
+ if (FRAME_GTK_WIDGET (f) == NULL)
+ return Qnil; /* This can occur while creating a frame. */
+
+ gtk_widget_get_allocation (FRAME_GTK_WIDGET (f), &alloc);
+ left_pos = alloc.x;
+ top_pos = alloc.y;
+ }
+
+ int native_left = left_pos + border;
+ int native_top = top_pos + border + title_height;
+ int native_right = left_pos + outer_width - border;
+ int native_bottom = top_pos + outer_height - border;
+ int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
+ int tab_bar_height = 0, tab_bar_width = 0;
+ int tool_bar_height = FRAME_TOOLBAR_HEIGHT (f);
+ int tool_bar_width = (tool_bar_height
+ ? outer_width - 2 * internal_border_width : 0);
+
+ tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
+ tab_bar_width = (tab_bar_height
+ ? native_width - 2 * internal_border_width : 0);
+ /* inner_top += tab_bar_height; */
+
+ /* Construct list. */
+ if (EQ (attribute, Qouter_edges))
+ return list4 (make_fixnum (left_pos), make_fixnum (top_pos),
+ make_fixnum (left_pos + outer_width),
+ make_fixnum (top_pos + outer_height));
+ else if (EQ (attribute, Qnative_edges))
+ return list4 (make_fixnum (native_left), make_fixnum (native_top),
+ make_fixnum (native_right), make_fixnum (native_bottom));
+ else if (EQ (attribute, Qinner_edges))
+ return list4 (make_fixnum (native_left + internal_border_width),
+ make_fixnum (native_top
+ + tool_bar_height
+ + internal_border_width),
+ make_fixnum (native_right - internal_border_width),
+ make_fixnum (native_bottom - internal_border_width));
+ else
+ return
+ list (Fcons (Qouter_position,
+ Fcons (make_fixnum (left_pos),
+ make_fixnum (top_pos))),
+ Fcons (Qouter_size,
+ Fcons (make_fixnum (outer_width),
+ make_fixnum (outer_height))),
+ Fcons (Qexternal_border_size,
+ (fullscreen
+ ? Fcons (make_fixnum (0), make_fixnum (0))
+ : Fcons (make_fixnum (border), make_fixnum (border)))),
+ Fcons (Qtitle_bar_size,
+ Fcons (make_fixnum (0), make_fixnum (title_height))),
+ Fcons (Qmenu_bar_external, Qnil),
+ Fcons (Qmenu_bar_size, Fcons (make_fixnum (0), make_fixnum (0))),
+ Fcons (Qtab_bar_size,
+ Fcons (make_fixnum (tab_bar_width),
+ make_fixnum (tab_bar_height))),
+ Fcons (Qtool_bar_external,
+ FRAME_EXTERNAL_TOOL_BAR (f) ? Qt : Qnil),
+ Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
+ Fcons (Qtool_bar_size,
+ Fcons (make_fixnum (tool_bar_width),
+ make_fixnum (tool_bar_height))),
+ Fcons (Qinternal_border_width,
+ make_fixnum (internal_border_width)));
+}
+
+DEFUN ("pgtk-frame-geometry", Fpgtk_frame_geometry, Spgtk_frame_geometry, 0, 1, 0,
+ doc: /* Return geometric attributes of FRAME.
+FRAME must be a live frame and defaults to the selected one. The return
+value is an association list of the attributes listed below. All height
+and width values are in pixels.
+
+`outer-position' is a cons of the outer left and top edges of FRAME
+relative to the origin - the position (0, 0) - of FRAME's display.
+
+`outer-size' is a cons of the outer width and height of FRAME. The
+outer size includes the title bar and the external borders as well as
+any menu and/or tool bar of frame.
+
+`external-border-size' is a cons of the horizontal and vertical width of
+FRAME's external borders as supplied by the window manager.
+
+`title-bar-size' is a cons of the width and height of the title bar of
+FRAME as supplied by the window manager. If both of them are zero,
+FRAME has no title bar. If only the width is zero, Emacs was not
+able to retrieve the width information.
+
+`menu-bar-external', if non-nil, means the menu bar is external (never
+included in the inner edges of FRAME).
+
+`menu-bar-size' is a cons of the width and height of the menu bar of
+FRAME.
+
+`tool-bar-external', if non-nil, means the tool bar is external (never
+included in the inner edges of FRAME).
+
+`tool-bar-position' tells on which side the tool bar on FRAME is and can
+be one of `left', `top', `right' or `bottom'. If this is nil, FRAME
+has no tool bar.
+
+`tool-bar-size' is a cons of the width and height of the tool bar of
+FRAME.
+
+`internal-border-width' is the width of the internal border of
+FRAME. */)
+ (Lisp_Object frame)
+{
+ return frame_geometry (frame, Qnil);
+}
+
+DEFUN ("pgtk-frame-edges", Fpgtk_frame_edges, Spgtk_frame_edges, 0, 2, 0,
+ doc: /* Return edge coordinates of FRAME.
+FRAME must be a live frame and defaults to the selected one. The return
+value is a list of the form (LEFT, TOP, RIGHT, BOTTOM). All values are
+in pixels relative to the origin - the position (0, 0) - of FRAME's
+display.
+
+If optional argument TYPE is the symbol `outer-edges', return the outer
+edges of FRAME. The outer edges comprise the decorations of the window
+manager (like the title bar or external borders) as well as any external
+menu or tool bar of FRAME. If optional argument TYPE is the symbol
+`native-edges' or nil, return the native edges of FRAME. The native
+edges exclude the decorations of the window manager and any external
+menu or tool bar of FRAME. If TYPE is the symbol `inner-edges', return
+the inner edges of FRAME. These edges exclude title bar, any borders,
+menu bar or tool bar of FRAME. */)
+ (Lisp_Object frame, Lisp_Object type)
+{
+ return frame_geometry (frame, ((EQ (type, Qouter_edges)
+ || EQ (type, Qinner_edges))
+ ? type : Qnative_edges));
+}
+
+DEFUN ("pgtk-set-mouse-absolute-pixel-position", Fpgtk_set_mouse_absolute_pixel_position, Spgtk_set_mouse_absolute_pixel_position, 2, 2, 0,
+ doc: /* Move mouse pointer to absolute pixel position (X, Y).
+The coordinates X and Y are interpreted in pixels relative to a position
+\(0, 0) of the selected frame's display. */)
+ (Lisp_Object x, Lisp_Object y)
+{
+ struct frame *f = SELECTED_FRAME ();
+ GtkWidget *widget = gtk_widget_get_toplevel (FRAME_WIDGET (f));
+ GdkWindow *window = gtk_widget_get_window (widget);
+ GdkDisplay *gdpy = gdk_window_get_display (window);
+ GdkScreen *gscr = gdk_window_get_screen (window);
+ GdkSeat *seat = gdk_display_get_default_seat (gdpy);
+ GdkDevice *device = gdk_seat_get_pointer (seat);
+
+ gdk_device_warp (device, gscr, XFIXNUM (x), XFIXNUM (y)); /* No effect on wayland. */
+
+ return Qnil;
+}
+
+DEFUN ("pgtk-mouse-absolute-pixel-position", Fpgtk_mouse_absolute_pixel_position, Spgtk_mouse_absolute_pixel_position, 0, 0, 0,
+ doc: /* Return absolute position of mouse cursor in pixels.
+The position is returned as a cons cell (X . Y) of the
+coordinates of the mouse cursor position in pixels relative to a
+position (0, 0) of the selected frame's terminal. */)
+ (void)
+{
+ struct frame *f = SELECTED_FRAME ();
+ GtkWidget *widget = gtk_widget_get_toplevel (FRAME_WIDGET (f));
+ GdkWindow *window = gtk_widget_get_window (widget);
+ GdkDisplay *gdpy = gdk_window_get_display (window);
+ GdkScreen *gscr;
+ GdkSeat *seat = gdk_display_get_default_seat (gdpy);
+ GdkDevice *device = gdk_seat_get_pointer (seat);
+ int x = 0, y = 0;
+
+ gdk_device_get_position (device, &gscr, &x, &y); /* can't get on wayland? */
+
+ return Fcons (make_fixnum (x), make_fixnum (y));
+}
+
+
+DEFUN ("pgtk-page-setup-dialog", Fpgtk_page_setup_dialog, Spgtk_page_setup_dialog, 0, 0, 0,
+ doc: /* Pop up a page setup dialog.
+The current page setup can be obtained using `x-get-page-setup'. */)
+ (void)
+{
+ block_input ();
+ xg_page_setup_dialog ();
+ unblock_input ();
+
+ return Qnil;
+}
+
+DEFUN ("pgtk-get-page-setup", Fpgtk_get_page_setup, Spgtk_get_page_setup, 0, 0, 0,
+ doc: /* Return the value of the current page setup.
+The return value is an alist containing the following keys:
+
+orientation: page orientation (symbol `portrait', `landscape',
+`reverse-portrait', or `reverse-landscape').
+width, height: page width/height in points not including margins.
+left-margin, right-margin, top-margin, bottom-margin: print margins,
+which is the parts of the page that the printer cannot print
+on, in points.
+
+The paper width can be obtained as the sum of width, left-margin, and
+right-margin values if the page orientation is `portrait' or
+`reverse-portrait'. Otherwise, it is the sum of width, top-margin,
+and bottom-margin values. Likewise, the paper height is the sum of
+height, top-margin, and bottom-margin values if the page orientation
+is `portrait' or `reverse-portrait'. Otherwise, it is the sum of
+height, left-margin, and right-margin values. */)
+ (void)
+{
+ Lisp_Object result;
+
+ block_input ();
+ result = xg_get_page_setup ();
+ unblock_input ();
+
+ return result;
+}
+
+DEFUN ("pgtk-print-frames-dialog", Fpgtk_print_frames_dialog, Spgtk_print_frames_dialog, 0, 1, "",
+ doc: /* Pop up a print dialog to print the current contents of FRAMES.
+FRAMES should be nil (the selected frame), a frame, or a list of
+frames (each of which corresponds to one page). Each frame should be
+visible. */)
+ (Lisp_Object frames)
+{
+ Lisp_Object rest, tmp;
+ int count;
+
+ if (!CONSP (frames))
+ frames = list1 (frames);
+
+ tmp = Qnil;
+ for (rest = frames; CONSP (rest); rest = XCDR (rest))
+ {
+ struct frame *f = decode_window_system_frame (XCAR (rest));
+ Lisp_Object frame;
+
+ XSETFRAME (frame, f);
+ if (!FRAME_VISIBLE_P (f))
+ error ("Frames to be printed must be visible.");
+ tmp = Fcons (frame, tmp);
+ }
+ frames = Fnreverse (tmp);
+
+ /* Make sure the current matrices are up-to-date. */
+ count = SPECPDL_INDEX ();
+ specbind (Qredisplay_dont_pause, Qt);
+ redisplay_preserve_echo_area (32);
+ unbind_to (count, Qnil);
+
+ block_input ();
+ xg_print_frames_dialog (frames);
+ unblock_input ();
+
+ return Qnil;
+}
+
+static void
+clean_up_dialog (void)
+{
+ pgtk_menu_set_in_use (false);
+}
+
+DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
+ doc: /* Read file name, prompting with PROMPT in directory DIR.
+Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
+selection box, if specified. If MUSTMATCH is non-nil, the returned file
+or directory must exist.
+
+This function is defined only on PGTK, NS, MS Windows, and X Windows with the
+Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
+Otherwise, if ONLY-DIR-P is non-nil, the user can select only directories.
+On MS Windows 7 and later, the file selection dialog "remembers" the last
+directory where the user selected a file, and will open that directory
+instead of DIR on subsequent invocations of this function with the same
+value of DIR as in previous invocations; this is standard MS Windows behavior. */)
+ (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename,
+ Lisp_Object mustmatch, Lisp_Object only_dir_p)
+{
+ struct frame *f = SELECTED_FRAME ();
+ char *fn;
+ Lisp_Object file = Qnil;
+ Lisp_Object decoded_file;
+ ptrdiff_t count = SPECPDL_INDEX ();
+ char *cdef_file;
+
+ check_window_system (f);
+
+ if (popup_activated ())
+ error ("Trying to use a menu from within a menu-entry");
+ else
+ pgtk_menu_set_in_use (true);
+
+ CHECK_STRING (prompt);
+ CHECK_STRING (dir);
+
+ /* Prevent redisplay. */
+ specbind (Qinhibit_redisplay, Qt);
+ record_unwind_protect_void (clean_up_dialog);
+
+ block_input ();
+
+ if (STRINGP (default_filename))
+ cdef_file = SSDATA (default_filename);
+ else
+ cdef_file = SSDATA (dir);
+
+ fn = xg_get_file_name (f, SSDATA (prompt), cdef_file,
+ !NILP (mustmatch), !NILP (only_dir_p));
+
+ if (fn)
+ {
+ file = build_string (fn);
+ xfree (fn);
+ }
+
+ unblock_input ();
+
+ /* Make "Cancel" equivalent to C-g. */
+ if (NILP (file))
+ quit ();
+
+ decoded_file = DECODE_FILE (file);
+
+ return unbind_to (count, decoded_file);
+}
+
+DEFUN ("pgtk-backend-display-class", Fpgtk_backend_display_class, Spgtk_backend_display_class, 0, 1, "",
+ doc: /* Return the name of the Gdk backend display class of TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
+{
+ struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
+ GdkDisplay *gdpy = dpyinfo->gdpy;
+ const gchar *type_name = G_OBJECT_TYPE_NAME (G_OBJECT (gdpy));
+ return build_string (type_name);
+}
+
+DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
+ doc: /* Read a font using a GTK dialog and return a font spec.
+
+FRAME is the frame on which to pop up the font chooser. If omitted or
+nil, it defaults to the selected frame. */)
+ (Lisp_Object frame, Lisp_Object ignored)
+{
+ struct frame *f = decode_window_system_frame (frame);
+ Lisp_Object font;
+ Lisp_Object font_param;
+ char *default_name = NULL;
+ ptrdiff_t count = SPECPDL_INDEX ();
+
+ if (popup_activated ())
+ error ("Trying to use a menu from within a menu-entry");
+ else
+ pgtk_menu_set_in_use (true);
+
+ /* Prevent redisplay. */
+ specbind (Qinhibit_redisplay, Qt);
+ record_unwind_protect_void (clean_up_dialog);
+
+ block_input ();
+
+ XSETFONT (font, FRAME_FONT (f));
+ font_param = Ffont_get (font, QCname);
+ if (STRINGP (font_param))
+ default_name = xlispstrdup (font_param);
+ else
+ {
+ font_param = Fframe_parameter (frame, Qfont_parameter);
+ if (STRINGP (font_param))
+ default_name = xlispstrdup (font_param);
+ }
+
+ font = xg_get_font (f, default_name);
+ xfree (default_name);
+
+ unblock_input ();
+
+ if (NILP (font))
+ quit ();
+
+ return unbind_to (count, font);
+}
+
+/* ==========================================================================
+
+ Lisp interface declaration
+
+ ========================================================================== */
+
+void
+syms_of_pgtkfns (void)
+{
+ DEFSYM (Qfont_parameter, "font-parameter");
+ DEFSYM (Qfontsize, "fontsize");
+ DEFSYM (Qcancel_timer, "cancel-timer");
+ DEFSYM (Qframe_title_format, "frame-title-format");
+ DEFSYM (Qicon_title_format, "icon-title-format");
+ DEFSYM (Qdark, "dark");
+ DEFSYM (Qhide, "hide");
+ DEFSYM (Qresize_mode, "resize-mode");
+
+ DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
+ doc: /* A string indicating the foreground color of the cursor box. */);
+ Vx_cursor_fore_pixel = Qnil;
+
+ DEFVAR_LISP ("pgtk-icon-type-alist", Vpgtk_icon_type_alist,
+ doc: /* Alist of elements (REGEXP . IMAGE) for images of icons associated to frames.
+If the title of a frame matches REGEXP, then IMAGE.tiff is
+selected as the image of the icon representing the frame when it's
+miniaturized. If an element is t, then Emacs tries to select an icon
+based on the filetype of the visited file.
+
+The images have to be installed in a folder called English.lproj in the
+Emacs folder. You have to restart Emacs after installing new icons.
+
+Example: Install an icon Gnus.tiff and execute the following code
+
+(setq pgtk-icon-type-alist
+(append pgtk-icon-type-alist
+\\='((\"^\\\\*\\\\(Group\\\\*$\\\\|Summary \\\\|Article\\\\*$\\\\)\"
+. \"Gnus\"))))
+
+When you miniaturize a Group, Summary or Article frame, Gnus.tiff will
+be used as the image of the icon representing the frame. */);
+ Vpgtk_icon_type_alist = list1 (Qt);
+
+
+ /* Provide x-toolkit also for GTK. Internally GTK does not use Xt so it
+ is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
+ But for a user it is a toolkit for X, and indeed, configure
+ accepts --with-x-toolkit=gtk. */
+ Fprovide (intern_c_string ("x-toolkit"), Qnil);
+ Fprovide (intern_c_string ("gtk"), Qnil);
+ Fprovide (intern_c_string ("move-toolbar"), Qnil);
+
+ DEFVAR_LISP ("gtk-version-string", Vgtk_version_string,
+ doc: /* Version info for GTK+. */);
+ {
+ char *ver = g_strdup_printf ("%d.%d.%d",
+ GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
+ GTK_MICRO_VERSION);
+ int len = strlen (ver);
+ Vgtk_version_string = make_pure_string (ver, len, len, false);
+ g_free (ver);
+ }
+
+
+ Fprovide (intern_c_string ("cairo"), Qnil);
+
+ DEFVAR_LISP ("cairo-version-string", Vcairo_version_string,
+ doc: /* Version info for cairo. */);
+ {
+ char *ver = g_strdup_printf ("%d.%d.%d",
+ CAIRO_VERSION_MAJOR, CAIRO_VERSION_MINOR,
+ CAIRO_VERSION_MICRO);
+ int len = strlen (ver);
+ Vcairo_version_string = make_pure_string (ver, len, len, false);
+ g_free (ver);
+ }
+
+
+ defsubr (&Spgtk_set_resource);
+ defsubr (&Sxw_display_color_p); /* this and next called directly by C code */
+ defsubr (&Sx_display_grayscale_p);
+ defsubr (&Spgtk_font_name);
+ defsubr (&Sxw_color_defined_p);
+ defsubr (&Sxw_color_values);
+ defsubr (&Sx_server_max_request_size);
+ defsubr (&Sx_server_vendor);
+ defsubr (&Sx_server_version);
+ defsubr (&Sx_display_pixel_width);
+ defsubr (&Sx_display_pixel_height);
+ defsubr (&Spgtk_display_monitor_attributes_list);
+ defsubr (&Spgtk_frame_geometry);
+ defsubr (&Spgtk_frame_edges);
+ defsubr (&Spgtk_frame_restack);
+ defsubr (&Spgtk_set_mouse_absolute_pixel_position);
+ defsubr (&Spgtk_mouse_absolute_pixel_position);
+ defsubr (&Sx_display_mm_width);
+ defsubr (&Sx_display_mm_height);
+ defsubr (&Sx_display_screens);
+ defsubr (&Sx_display_planes);
+ defsubr (&Sx_display_color_cells);
+ defsubr (&Sx_display_visual_class);
+ defsubr (&Sx_display_backing_store);
+ defsubr (&Sx_display_save_under);
+ defsubr (&Sx_create_frame);
+ defsubr (&Sx_open_connection);
+ defsubr (&Sx_close_connection);
+ defsubr (&Sx_display_list);
+
+ defsubr (&Spgtk_hide_others);
+ defsubr (&Spgtk_hide_emacs);
+
+ defsubr (&Sx_show_tip);
+ defsubr (&Sx_hide_tip);
+
+ defsubr (&Sx_export_frames);
+ defsubr (&Spgtk_page_setup_dialog);
+ defsubr (&Spgtk_get_page_setup);
+ defsubr (&Spgtk_print_frames_dialog);
+ defsubr (&Spgtk_backend_display_class);
+
+ defsubr (&Spgtk_set_monitor_scale_factor);
+
+ defsubr (&Sx_file_dialog);
+ defsubr (&Sx_select_font);
+
+ as_status = 0;
+ as_script = Qnil;
+ as_result = 0;
+
+ monitor_scale_factor_alist = Qnil;
+ staticpro (&monitor_scale_factor_alist);
+
+ tip_timer = Qnil;
+ staticpro (&tip_timer);
+ tip_frame = Qnil;
+ staticpro (&tip_frame);
+ tip_last_frame = Qnil;
+ staticpro (&tip_last_frame);
+ tip_last_string = Qnil;
+ staticpro (&tip_last_string);
+ tip_last_parms = Qnil;
+ staticpro (&tip_last_parms);
+
+ /* This is not ifdef:ed, so other builds than GTK can customize it. */
+ DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog,
+ doc: /* Non-nil means prompt with the old GTK file selection dialog.
+If nil or if the file selection dialog is not available, the new GTK file
+chooser is used instead. To turn off all file dialogs set the
+variable `use-file-dialog'. */);
+ x_gtk_use_old_file_dialog = false;
+
+ DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files,
+ doc: /* If non-nil, the GTK file chooser will by default show hidden files.
+Note that this is just the default, there is a toggle button on the file
+chooser to show or not show hidden files on a case by case basis. */);
+ x_gtk_show_hidden_files = false;
+
+ DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text,
+ doc: /* If non-nil, the GTK file chooser will show additional help text.
+If more space for files in the file chooser dialog is wanted, set this to nil
+to turn the additional text off. */);
+ x_gtk_file_dialog_help_text = true;
+
+ DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips,
+ doc: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
+Otherwise use Emacs own tooltip implementation.
+When using Gtk+ tooltips, the tooltip face is not used. */);
+ x_gtk_use_system_tooltips = true;
+
+ DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size,
+ doc: /* Maximum size for tooltips.
+Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
+ Vx_max_tooltip_size = Fcons (make_fixnum (80), make_fixnum (40));
+
+ DEFVAR_LISP ("x-gtk-resize-child-frames", x_gtk_resize_child_frames,
+ doc: /* If non-nil, resize child frames specially with GTK builds.
+If this is nil, resize child frames like any other frames. This is the
+default and usually works with most desktops. Some desktop environments
+(GNOME shell in particular when using the mutter window manager),
+however, may refuse to resize a child frame when Emacs is built with
+GTK3. For those environments, the two settings below are provided.
+
+If this equals the symbol 'hide', Emacs temporarily hides the child
+frame during resizing. This approach seems to work reliably, may
+however induce some flicker when the frame is made visible again.
+
+If this equals the symbol 'resize-mode', Emacs uses GTK's resize mode to
+always trigger an immediate resize of the child frame. This method is
+deprecated by GTK and may not work in future versions of that toolkit.
+It also may freeze Emacs when used with other desktop environments. It
+avoids, however, the unpleasant flicker induced by the hiding approach.
+
+This variable is considered a temporary workaround and will be hopefully
+eliminated in future versions of Emacs. */);
+ x_gtk_resize_child_frames = Qnil;
+
+
+ DEFSYM (Qmono, "mono");
+ DEFSYM (Qassq_delete_all, "assq-delete-all");
+
+ DEFSYM (Qpdf, "pdf");
+
+ DEFSYM (Qorientation, "orientation");
+ DEFSYM (Qtop_margin, "top-margin");
+ DEFSYM (Qbottom_margin, "bottom-margin");
+ DEFSYM (Qportrait, "portrait");
+ DEFSYM (Qlandscape, "landscape");
+ DEFSYM (Qreverse_portrait, "reverse-portrait");
+ DEFSYM (Qreverse_landscape, "reverse-landscape");
+}
+
+#endif
diff --git a/src/pgtkgui.h b/src/pgtkgui.h
new file mode 100644
index 00000000000..035e0179f67
--- /dev/null
+++ b/src/pgtkgui.h
@@ -0,0 +1,119 @@
+/* Definitions and headers for communication on the pure Gtk+3.
+ Copyright (C) 1995, 2005, 2008-2020 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/>. */
+
+#ifndef __PGTKGUI_H__
+#define __PGTKGUI_H__
+
+/* Emulate XCharStruct. */
+typedef struct _XCharStruct
+{
+ int rbearing;
+ int lbearing;
+ int width;
+ int ascent;
+ int descent;
+} XCharStruct;
+
+/* Fake structure from Xlib.h to represent two-byte characters. */
+typedef unsigned short unichar;
+typedef unichar XChar2b;
+
+#define STORE_XCHAR2B(chp, b1, b2) \
+ (*(chp) = ((XChar2b)((((b1) & 0x00ff) << 8) | ((b2) & 0x00ff))))
+
+#define XCHAR2B_BYTE1(chp) \
+ ((*(chp) & 0xff00) >> 8)
+
+#define XCHAR2B_BYTE2(chp) \
+ (*(chp) & 0x00ff)
+
+
+typedef struct _GdkCursor *Emacs_Cursor;
+
+typedef void *Color;
+typedef int Window;
+typedef struct _GdkDisplay Display;
+
+/* Xism */
+typedef void *XrmDatabase;
+
+
+/* Some sort of attempt to normalize rectangle handling.. seems a bit much
+ for what is accomplished. */
+typedef struct
+{
+ int x, y;
+ unsigned width, height;
+} XRectangle;
+
+/* This stuff is needed by frame.c. */
+#define ForgetGravity 0
+#define NorthWestGravity 1
+#define NorthGravity 2
+#define NorthEastGravity 3
+#define WestGravity 4
+#define CenterGravity 5
+#define EastGravity 6
+#define SouthWestGravity 7
+#define SouthGravity 8
+#define SouthEastGravity 9
+#define StaticGravity 10
+
+#define NoValue 0x0000
+#define XValue 0x0001
+#define YValue 0x0002
+#define WidthValue 0x0004
+#define HeightValue 0x0008
+#define AllValues 0x000F
+#define XNegative 0x0010
+#define YNegative 0x0020
+
+#define USPosition (1L << 0) /* user specified x, y */
+#define USSize (1L << 1) /* user specified width, height */
+
+#define PPosition (1L << 2) /* program specified position */
+#define PSize (1L << 3) /* program specified size */
+#define PMinSize (1L << 4) /* program specified minimum size */
+#define PMaxSize (1L << 5) /* program specified maximum size */
+#define PResizeInc (1L << 6) /* program specified resize increments */
+#define PAspect (1L << 7) /* program specified min, max aspect ratios */
+#define PBaseSize (1L << 8) /* program specified base for incrementing */
+#define PWinGravity (1L << 9) /* program specified window gravity */
+
+
+#define NativeRectangle XRectangle
+
+#define CONVERT_TO_EMACS_RECT(xr, nr) \
+ ((xr).x = (nr).x, \
+ (xr).y = (nr).y, \
+ (xr).width = (nr).width, \
+ (xr).height = (nr).height)
+
+#define CONVERT_FROM_EMACS_RECT(xr, nr) \
+ ((nr).x = (xr).x, \
+ (nr).y = (xr).y, \
+ (nr).width = (xr).width, \
+ (nr).height = (xr).height)
+
+#define STORE_NATIVE_RECT(nr, px, py, pwidth, pheight) \
+ ((nr).x = (px), \
+ (nr).y = (py), \
+ (nr).width = (pwidth), \
+ (nr).height = (pheight))
+
+#endif /* __PGTKGUI_H__ */
diff --git a/src/pgtkim.c b/src/pgtkim.c
new file mode 100644
index 00000000000..c0104ebc0ae
--- /dev/null
+++ b/src/pgtkim.c
@@ -0,0 +1,311 @@
+/* Pure Gtk+-3 communication module.
+
+Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2020 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/>. */
+
+/* This should be the first include, as it may set up #defines affecting
+ interpretation of even the system includes. */
+#include <config.h>
+
+#include "pgtkterm.h"
+
+static void
+im_context_commit_cb (GtkIMContext * imc, gchar * str, gpointer user_data)
+{
+ struct pgtk_display_info *dpyinfo = user_data;
+ struct frame *f = dpyinfo->im.focused_frame;
+
+ if (dpyinfo->im.context == NULL)
+ return;
+ if (f == NULL)
+ return;
+
+ pgtk_enqueue_string (f, str);
+}
+
+static gboolean
+im_context_retrieve_surrounding_cb (GtkIMContext * imc, gpointer user_data)
+{
+ gtk_im_context_set_surrounding (imc, "", -1, 0);
+ return TRUE;
+}
+
+static gboolean
+im_context_delete_surrounding_cb (GtkIMContext * imc, int offset, int n_chars,
+ gpointer user_data)
+{
+ return TRUE;
+}
+
+static Lisp_Object
+make_color_string (PangoAttrColor * pac)
+{
+ char buf[256];
+ sprintf (buf, "#%02x%02x%02x",
+ pac->color.red >> 8, pac->color.green >> 8, pac->color.blue >> 8);
+ return build_string (buf);
+}
+
+static void
+im_context_preedit_changed_cb (GtkIMContext * imc, gpointer user_data)
+{
+ struct pgtk_display_info *dpyinfo = user_data;
+ struct frame *f = dpyinfo->im.focused_frame;
+ char *str;
+ PangoAttrList *attrs;
+ int pos;
+
+ if (dpyinfo->im.context == NULL)
+ return;
+ if (f == NULL)
+ return;
+
+ gtk_im_context_get_preedit_string (imc, &str, &attrs, &pos);
+
+
+ /*
+ * (
+ * (TEXT (ul . COLOR) (bg . COLOR) (fg . COLOR))
+ * ...
+ * )
+ */
+ Lisp_Object list = Qnil;
+
+ PangoAttrIterator *iter;
+ iter = pango_attr_list_get_iterator (attrs);
+ do
+ {
+ int st, ed;
+ int has_underline = 0;
+ Lisp_Object part = Qnil;
+
+ pango_attr_iterator_range (iter, &st, &ed);
+
+ if (ed > strlen (str))
+ ed = strlen (str);
+ if (st >= ed)
+ continue;
+
+ Lisp_Object text = make_string (str + st, ed - st);
+ part = Fcons (text, part);
+
+ PangoAttrInt *ul =
+ (PangoAttrInt *) pango_attr_iterator_get (iter, PANGO_ATTR_UNDERLINE);
+ if (ul != NULL)
+ {
+ if (ul->value != PANGO_UNDERLINE_NONE)
+ has_underline = 1;
+ }
+
+ PangoAttrColor *pac;
+ if (has_underline)
+ {
+ pac =
+ (PangoAttrColor *) pango_attr_iterator_get (iter,
+ PANGO_ATTR_UNDERLINE_COLOR);
+ if (pac != NULL)
+ part = Fcons (Fcons (Qul, make_color_string (pac)), part);
+ else
+ part = Fcons (Fcons (Qul, Qt), part);
+ }
+
+ pac =
+ (PangoAttrColor *) pango_attr_iterator_get (iter,
+ PANGO_ATTR_FOREGROUND);
+ if (pac != NULL)
+ part = Fcons (Fcons (Qfg, make_color_string (pac)), part);
+
+ pac =
+ (PangoAttrColor *) pango_attr_iterator_get (iter,
+ PANGO_ATTR_BACKGROUND);
+ if (pac != NULL)
+ part = Fcons (Fcons (Qbg, make_color_string (pac)), part);
+
+ part = Fnreverse (part);
+ list = Fcons (part, list);
+ }
+ while (pango_attr_iterator_next (iter));
+
+ list = Fnreverse (list);
+ pgtk_enqueue_preedit (f, list);
+
+ g_free (str);
+ pango_attr_list_unref (attrs);
+}
+
+static void
+im_context_preedit_end_cb (GtkIMContext * imc, gpointer user_data)
+{
+ struct pgtk_display_info *dpyinfo = user_data;
+ struct frame *f = dpyinfo->im.focused_frame;
+
+ if (dpyinfo->im.context == NULL)
+ return;
+ if (f == NULL)
+ return;
+
+ pgtk_enqueue_preedit (f, Qnil);
+}
+
+static void
+im_context_preedit_start_cb (GtkIMContext * imc, gpointer user_data)
+{
+}
+
+void
+pgtk_im_focus_in (struct frame *f)
+{
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+ if (dpyinfo->im.context != NULL)
+ {
+ gtk_im_context_reset (dpyinfo->im.context);
+ gtk_im_context_set_client_window (dpyinfo->im.context,
+ gtk_widget_get_window
+ (FRAME_GTK_WIDGET (f)));
+ gtk_im_context_focus_in (dpyinfo->im.context);
+ }
+ dpyinfo->im.focused_frame = f;
+}
+
+void
+pgtk_im_focus_out (struct frame *f)
+{
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+ if (dpyinfo->im.focused_frame == f)
+ {
+ if (dpyinfo->im.context != NULL)
+ {
+ gtk_im_context_reset (dpyinfo->im.context);
+ gtk_im_context_focus_out (dpyinfo->im.context);
+ gtk_im_context_set_client_window (dpyinfo->im.context, NULL);
+ }
+ dpyinfo->im.focused_frame = NULL;
+ }
+}
+
+bool
+pgtk_im_filter_keypress (struct frame *f, GdkEventKey * ev)
+{
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+ if (dpyinfo->im.context != NULL)
+ {
+ if (gtk_im_context_filter_keypress (dpyinfo->im.context, ev))
+ return true;
+ }
+ return false;
+}
+
+void
+pgtk_im_set_cursor_location (struct frame *f, int x, int y, int width,
+ int height)
+{
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+ if (dpyinfo->im.context != NULL && dpyinfo->im.focused_frame == f)
+ {
+ GdkRectangle area = { x, y, width, height };
+ gtk_im_context_set_cursor_location (dpyinfo->im.context, &area);
+ }
+}
+
+static void
+pgtk_im_use_context (struct pgtk_display_info *dpyinfo, bool use_p)
+{
+ if (!use_p)
+ {
+ if (dpyinfo->im.context != NULL)
+ {
+ gtk_im_context_reset (dpyinfo->im.context);
+ gtk_im_context_focus_out (dpyinfo->im.context);
+ gtk_im_context_set_client_window (dpyinfo->im.context, NULL);
+
+ g_object_unref (dpyinfo->im.context);
+ dpyinfo->im.context = NULL;
+ }
+ }
+ else
+ {
+ if (dpyinfo->im.context == NULL)
+ {
+ dpyinfo->im.context = gtk_im_multicontext_new ();
+ g_signal_connect (dpyinfo->im.context, "commit",
+ G_CALLBACK (im_context_commit_cb), dpyinfo);
+ g_signal_connect (dpyinfo->im.context, "retrieve-surrounding",
+ G_CALLBACK (im_context_retrieve_surrounding_cb),
+ dpyinfo);
+ g_signal_connect (dpyinfo->im.context, "delete-surrounding",
+ G_CALLBACK (im_context_delete_surrounding_cb),
+ dpyinfo);
+ g_signal_connect (dpyinfo->im.context, "preedit-changed",
+ G_CALLBACK (im_context_preedit_changed_cb),
+ dpyinfo);
+ g_signal_connect (dpyinfo->im.context, "preedit-end",
+ G_CALLBACK (im_context_preedit_end_cb), dpyinfo);
+ g_signal_connect (dpyinfo->im.context, "preedit-start",
+ G_CALLBACK (im_context_preedit_start_cb),
+ dpyinfo);
+ gtk_im_context_set_use_preedit (dpyinfo->im.context, TRUE);
+
+ if (dpyinfo->im.focused_frame)
+ pgtk_im_focus_in (dpyinfo->im.focused_frame);
+ }
+ }
+}
+
+void
+pgtk_im_init (struct pgtk_display_info *dpyinfo)
+{
+ dpyinfo->im.context = NULL;
+
+ pgtk_im_use_context (dpyinfo, !NILP (Vpgtk_use_im_context_on_new_connection));
+}
+
+void
+pgtk_im_finish (struct pgtk_display_info *dpyinfo)
+{
+ if (dpyinfo->im.context != NULL)
+ g_object_unref (dpyinfo->im.context);
+ dpyinfo->im.context = NULL;
+}
+
+DEFUN ("pgtk-use-im-context", Fpgtk_use_im_context, Spgtk_use_im_context, 1, 2, 0,
+ doc: /* Set whether to use GtkIMContext. */)
+ (Lisp_Object use_p, Lisp_Object terminal)
+{
+ struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
+
+ pgtk_im_use_context (dpyinfo, !NILP (use_p));
+
+ return Qnil;
+}
+
+void
+syms_of_pgtkim (void)
+{
+ defsubr (&Spgtk_use_im_context);
+
+ DEFSYM (Qpgtk_refresh_preedit, "pgtk-refresh-preedit");
+ DEFSYM (Qul, "ul");
+ DEFSYM (Qfg, "fg");
+ DEFSYM (Qbg, "bg");
+
+ DEFVAR_LISP ("pgtk-use-im-context-on-new-connection", Vpgtk_use_im_context_on_new_connection,
+ doc: /* Whether to use GtkIMContext on a new connection.
+If you want to change it after connection, use the `pgtk-use-im-context'
+function. */ );
+ Vpgtk_use_im_context_on_new_connection = Qt;
+}
diff --git a/src/pgtkmenu.c b/src/pgtkmenu.c
new file mode 100644
index 00000000000..fd2c53a1b82
--- /dev/null
+++ b/src/pgtkmenu.c
@@ -0,0 +1,1159 @@
+/* Pure GTK3 menu and toolbar module.
+ Copyright (C) 2019-2020 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/>. */
+
+/*
+ */
+
+
+/* This should be the first include, as it may set up #defines affecting
+ interpretation of even the system includes. */
+#include <config.h>
+
+#include "lisp.h"
+#include "frame.h"
+#include "window.h"
+#include "character.h"
+#include "buffer.h"
+#include "keymap.h"
+#include "coding.h"
+#include "commands.h"
+#include "blockinput.h"
+#include "termhooks.h"
+#include "keyboard.h"
+#include "menu.h"
+#include "pdumper.h"
+#include "xgselect.h"
+
+#include "gtkutil.h"
+#include <gtk/gtk.h>
+
+/* Flag which when set indicates a dialog or menu has been posted by
+ Xt on behalf of one of the widget sets. */
+static int popup_activated_flag;
+
+/* Set menu_items_inuse so no other popup menu or dialog is created. */
+
+void
+pgtk_menu_set_in_use (bool in_use)
+{
+ Lisp_Object frames, frame;
+
+ menu_items_inuse = in_use;
+ popup_activated_flag = in_use;
+
+ /* Don't let frames in `above' z-group obscure popups. */
+ FOR_EACH_FRAME (frames, frame)
+ {
+ struct frame *f = XFRAME (frame);
+
+ if (in_use && FRAME_Z_GROUP_ABOVE (f))
+ x_set_z_group (f, Qabove_suspended, Qabove);
+ else if (!in_use && FRAME_Z_GROUP_ABOVE_SUSPENDED (f))
+ x_set_z_group (f, Qabove, Qabove_suspended);
+ }
+}
+
+DEFUN ("x-menu-bar-open-internal", Fx_menu_bar_open_internal, Sx_menu_bar_open_internal, 0, 1, "i",
+ doc: /* Start key navigation of the menu bar in FRAME.
+ This initially opens the first menu bar item and you can then navigate with the
+ arrow keys, select a menu entry with the return key or cancel with the
+ escape key. If FRAME has no menu bar this function does nothing.
+
+ If FRAME is nil or not given, use the selected frame. */)
+ (Lisp_Object frame)
+{
+ GtkWidget *menubar;
+ struct frame *f;
+
+ block_input ();
+ f = decode_window_system_frame (frame);
+
+ if (FRAME_EXTERNAL_MENU_BAR (f))
+ set_frame_menubar (f, true);
+
+ menubar = FRAME_X_OUTPUT (f)->menubar_widget;
+ if (menubar)
+ {
+ /* Activate the first menu. */
+ GList *children = gtk_container_get_children (GTK_CONTAINER (menubar));
+
+ if (children)
+ {
+ g_signal_emit_by_name (children->data, "activate_item");
+ g_list_free (children);
+ }
+ }
+ unblock_input ();
+
+ return Qnil;
+}
+
+/* Loop util popup_activated_flag is set to zero in a callback.
+ Used for popup menus and dialogs. */
+
+static void
+popup_widget_loop (bool do_timers, GtkWidget *widget)
+{
+ ++popup_activated_flag;
+
+ /* Process events in the Gtk event loop until done. */
+ while (popup_activated_flag)
+ gtk_main_iteration ();
+}
+
+void
+pgtk_activate_menubar (struct frame *f)
+{
+ set_frame_menubar (f, true);
+
+ popup_activated_flag = 1;
+
+ /* f->output_data.pgtk->menubar_active = 1; */
+}
+
+/* This callback is invoked when a dialog or menu is finished being
+ used and has been unposted. */
+
+static void
+popup_deactivate_callback (GtkWidget *widget, gpointer client_data)
+{
+ popup_activated_flag = 0;
+}
+
+/* Function that finds the frame for WIDGET and shows the HELP text
+ for that widget.
+ F is the frame if known, or NULL if not known. */
+static void
+show_help_event (struct frame *f, GtkWidget *widget, Lisp_Object help)
+{
+ /* Don't show this tooltip.
+ * Tooltips are always tied to main widget, so stacking order
+ * on Wayland is:
+ * (above)
+ * - menu
+ * - tooltip
+ * - main widget
+ * (below)
+ * This is applicable to tooltips for menu, and menu tooltips
+ * are shown below menus.
+ * As a workaround, I entrust Gtk with menu tooltips, and
+ * let emacs not to show menu tooltips.
+ */
+
+#if 0
+ Lisp_Object frame;
+
+ if (f)
+ {
+ XSETFRAME (frame, f);
+ kbd_buffer_store_help_event (frame, help);
+ }
+ else
+ show_help_echo (help, Qnil, Qnil, Qnil);
+#endif
+}
+
+/* Callback called when menu items are highlighted/unhighlighted
+ while moving the mouse over them. WIDGET is the menu bar or menu
+ popup widget. ID is its LWLIB_ID. CALL_DATA contains a pointer to
+ the data structure for the menu item, or null in case of
+ unhighlighting. */
+
+static void
+menu_highlight_callback (GtkWidget *widget, gpointer call_data)
+{
+ xg_menu_item_cb_data *cb_data;
+ Lisp_Object help;
+
+ cb_data = g_object_get_data (G_OBJECT (widget), XG_ITEM_DATA);
+ if (!cb_data)
+ return;
+
+ help = call_data ? cb_data->help : Qnil;
+
+ /* If popup_activated_flag is greater than 1 we are in a popup menu.
+ Don't pass the frame to show_help_event for those.
+ Passing frame creates an Emacs event. As we are looping in
+ popup_widget_loop, it won't be handled. Passing NULL shows the tip
+ directly without using an Emacs event. This is what the Lucid code
+ does below. */
+ show_help_event (popup_activated_flag <= 1 ? cb_data->cl_data->f : NULL,
+ widget, help);
+}
+
+/* Gtk calls callbacks just because we tell it what item should be
+ selected in a radio group. If this variable is set to a non-zero
+ value, we are creating menus and don't want callbacks right now.
+*/
+static bool xg_crazy_callback_abort;
+
+/* This callback is called from the menu bar pulldown menu
+ when the user makes a selection.
+ Figure out what the user chose
+ and put the appropriate events into the keyboard buffer. */
+static void
+menubar_selection_callback (GtkWidget *widget, gpointer client_data)
+{
+ xg_menu_item_cb_data *cb_data = client_data;
+
+ if (xg_crazy_callback_abort)
+ return;
+
+ if (!cb_data || !cb_data->cl_data || !cb_data->cl_data->f)
+ return;
+
+ /* For a group of radio buttons, GTK calls the selection callback first
+ for the item that was active before the selection and then for the one that
+ is active after the selection. For C-h k this means we get the help on
+ the deselected item and then the selected item is executed. Prevent that
+ by ignoring the non-active item. */
+ if (GTK_IS_RADIO_MENU_ITEM (widget)
+ && !gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)))
+ return;
+
+ /* When a menu is popped down, X generates a focus event (i.e. focus
+ goes back to the frame below the menu). Since GTK buffers events,
+ we force it out here before the menu selection event. Otherwise
+ sit-for will exit at once if the focus event follows the menu selection
+ event. */
+
+ block_input ();
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+ unblock_input ();
+
+ find_and_call_menu_selection (cb_data->cl_data->f,
+ cb_data->cl_data->menu_bar_items_used,
+ cb_data->cl_data->menu_bar_vector,
+ cb_data->call_data);
+}
+
+/* Recompute all the widgets of frame F, when the menu bar has been
+ changed. */
+
+static void
+update_frame_menubar (struct frame *f)
+{
+ xg_update_frame_menubar (f);
+}
+
+/* Set the contents of the menubar widgets of frame F.
+ The argument FIRST_TIME is currently ignored;
+ it is set the first time this is called, from initialize_frame_menubar. */
+
+void
+set_frame_menubar (struct frame *f, bool deep_p)
+{
+ GtkWidget *menubar_widget;
+ Lisp_Object items;
+ widget_value *wv, *first_wv, *prev_wv = 0;
+ int i;
+ int *submenu_start, *submenu_end;
+ bool *submenu_top_level_items;
+ int *submenu_n_panes;
+
+
+ menubar_widget = f->output_data.pgtk->menubar_widget;
+
+ XSETFRAME (Vmenu_updating_frame, f);
+
+ if (!menubar_widget)
+ deep_p = true;
+
+ if (deep_p)
+ {
+ struct buffer *prev = current_buffer;
+ Lisp_Object buffer;
+ ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+ int previous_menu_items_used = f->menu_bar_items_used;
+ Lisp_Object *previous_items
+ = alloca (previous_menu_items_used * sizeof *previous_items);
+ int subitems;
+
+ /* If we are making a new widget, its contents are empty,
+ do always reinitialize them. */
+ if (!menubar_widget)
+ previous_menu_items_used = 0;
+
+ buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
+ specbind (Qinhibit_quit, Qt);
+ /* Don't let the debugger step into this code
+ because it is not reentrant. */
+ specbind (Qdebug_on_next_call, Qnil);
+
+ record_unwind_save_match_data ();
+ if (NILP (Voverriding_local_map_menu_flag))
+ {
+ specbind (Qoverriding_terminal_local_map, Qnil);
+ specbind (Qoverriding_local_map, Qnil);
+ }
+
+ set_buffer_internal_1 (XBUFFER (buffer));
+
+ /* Run the Lucid hook. */
+ safe_run_hooks (Qactivate_menubar_hook);
+
+ /* If it has changed current-menubar from previous value,
+ really recompute the menubar from the value. */
+ if (!NILP (Vlucid_menu_bar_dirty_flag))
+ call0 (Qrecompute_lucid_menubar);
+ safe_run_hooks (Qmenu_bar_update_hook);
+ fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
+
+ items = FRAME_MENU_BAR_ITEMS (f);
+
+ /* Save the frame's previous menu bar contents data. */
+ if (previous_menu_items_used)
+ memcpy (previous_items, xvector_contents (f->menu_bar_vector),
+ previous_menu_items_used * word_size);
+
+ /* Fill in menu_items with the current menu bar contents.
+ This can evaluate Lisp code. */
+ save_menu_items ();
+
+ menu_items = f->menu_bar_vector;
+ menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
+ subitems = ASIZE (items) / 4;
+ submenu_start = alloca ((subitems + 1) * sizeof *submenu_start);
+ submenu_end = alloca (subitems * sizeof *submenu_end);
+ submenu_n_panes = alloca (subitems * sizeof *submenu_n_panes);
+ submenu_top_level_items = alloca (subitems
+ * sizeof *submenu_top_level_items);
+ init_menu_items ();
+ for (i = 0; i < subitems; i++)
+ {
+ Lisp_Object key, string, maps;
+
+ key = AREF (items, 4 * i);
+ string = AREF (items, 4 * i + 1);
+ maps = AREF (items, 4 * i + 2);
+ if (NILP (string))
+ break;
+
+ submenu_start[i] = menu_items_used;
+
+ menu_items_n_panes = 0;
+ submenu_top_level_items[i]
+ = parse_single_submenu (key, string, maps);
+ submenu_n_panes[i] = menu_items_n_panes;
+
+ submenu_end[i] = menu_items_used;
+ }
+
+ submenu_start[i] = -1;
+ finish_menu_items ();
+
+ /* Convert menu_items into widget_value trees
+ to display the menu. This cannot evaluate Lisp code. */
+
+ wv = make_widget_value ("menubar", NULL, true, Qnil);
+ wv->button_type = BUTTON_TYPE_NONE;
+ first_wv = wv;
+
+ for (i = 0; submenu_start[i] >= 0; i++)
+ {
+ menu_items_n_panes = submenu_n_panes[i];
+ wv = digest_single_submenu (submenu_start[i], submenu_end[i],
+ submenu_top_level_items[i]);
+ if (prev_wv)
+ prev_wv->next = wv;
+ else
+ first_wv->contents = wv;
+ /* Don't set wv->name here; GC during the loop might relocate it. */
+ wv->enabled = true;
+ wv->button_type = BUTTON_TYPE_NONE;
+ prev_wv = wv;
+ }
+
+ set_buffer_internal_1 (prev);
+
+ /* If there has been no change in the Lisp-level contents
+ of the menu bar, skip redisplaying it. Just exit. */
+
+ /* Compare the new menu items with the ones computed last time. */
+ for (i = 0; i < previous_menu_items_used; i++)
+ if (menu_items_used == i
+ || (!EQ (previous_items[i], AREF (menu_items, i))))
+ break;
+ if (i == menu_items_used && i == previous_menu_items_used && i != 0)
+ {
+ /* The menu items have not changed. Don't bother updating
+ the menus in any form, since it would be a no-op. */
+ free_menubar_widget_value_tree (first_wv);
+ discard_menu_items ();
+ unbind_to (specpdl_count, Qnil);
+ return;
+ }
+
+ /* The menu items are different, so store them in the frame. */
+ fset_menu_bar_vector (f, menu_items);
+ f->menu_bar_items_used = menu_items_used;
+
+ /* This undoes save_menu_items. */
+ unbind_to (specpdl_count, Qnil);
+
+ /* Now GC cannot happen during the lifetime of the widget_value,
+ so it's safe to store data from a Lisp_String. */
+ wv = first_wv->contents;
+ for (i = 0; i < ASIZE (items); i += 4)
+ {
+ Lisp_Object string;
+ string = AREF (items, i + 1);
+ if (NILP (string))
+ break;
+ wv->name = SSDATA (string);
+ update_submenu_strings (wv->contents);
+ wv = wv->next;
+ }
+
+ }
+ else
+ {
+ /* Make a widget-value tree containing
+ just the top level menu bar strings. */
+
+ wv = make_widget_value ("menubar", NULL, true, Qnil);
+ wv->button_type = BUTTON_TYPE_NONE;
+ first_wv = wv;
+
+ items = FRAME_MENU_BAR_ITEMS (f);
+ for (i = 0; i < ASIZE (items); i += 4)
+ {
+ Lisp_Object string;
+
+ string = AREF (items, i + 1);
+ if (NILP (string))
+ break;
+
+ wv = make_widget_value (SSDATA (string), NULL, true, Qnil);
+ wv->button_type = BUTTON_TYPE_NONE;
+ /* This prevents lwlib from assuming this
+ menu item is really supposed to be empty. */
+ /* The intptr_t cast avoids a warning.
+ This value just has to be different from small integers. */
+ wv->call_data = (void *) (intptr_t) (-1);
+
+ if (prev_wv)
+ prev_wv->next = wv;
+ else
+ first_wv->contents = wv;
+ prev_wv = wv;
+ }
+
+ /* Forget what we thought we knew about what is in the
+ detailed contents of the menu bar menus.
+ Changing the top level always destroys the contents. */
+ f->menu_bar_items_used = 0;
+ }
+
+ block_input ();
+
+ xg_crazy_callback_abort = true;
+ if (menubar_widget)
+ {
+ /* The fourth arg is DEEP_P, which says to consider the entire
+ menu trees we supply, rather than just the menu bar item names. */
+ xg_modify_menubar_widgets (menubar_widget,
+ f,
+ first_wv,
+ deep_p,
+ G_CALLBACK (menubar_selection_callback),
+ G_CALLBACK (popup_deactivate_callback),
+ G_CALLBACK (menu_highlight_callback));
+ }
+ else
+ {
+ menubar_widget
+ = xg_create_widget ("menubar", "menubar", f, first_wv,
+ G_CALLBACK (menubar_selection_callback),
+ G_CALLBACK (popup_deactivate_callback),
+ G_CALLBACK (menu_highlight_callback));
+
+ f->output_data.pgtk->menubar_widget = menubar_widget;
+ }
+
+ free_menubar_widget_value_tree (first_wv);
+ update_frame_menubar (f);
+
+ xg_crazy_callback_abort = false;
+
+ unblock_input ();
+}
+
+/* Called from Fx_create_frame to create the initial menubar of a frame
+ before it is mapped, so that the window is mapped with the menubar already
+ there instead of us tacking it on later and thrashing the window after it
+ is visible. */
+
+void
+initialize_frame_menubar (struct frame *f)
+{
+ /* This function is called before the first chance to redisplay
+ the frame. It has to be, so the frame will have the right size. */
+ fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
+ set_frame_menubar (f, true);
+}
+
+
+/* x_menu_show actually displays a menu using the panes and items in menu_items
+ and returns the value selected from it.
+ There are two versions of x_menu_show, one for Xt and one for Xlib.
+ Both assume input is blocked by the caller. */
+
+/* F is the frame the menu is for.
+ X and Y are the frame-relative specified position,
+ relative to the inside upper left corner of the frame F.
+ Bitfield MENUFLAGS bits are:
+ MENU_FOR_CLICK is set if this menu was invoked for a mouse click.
+ MENU_KEYMAPS is set if this menu was specified with keymaps;
+ in that case, we return a list containing the chosen item's value
+ and perhaps also the pane's prefix.
+ TITLE is the specified menu title.
+ ERROR is a place to store an error message string in case of failure.
+ (We return nil on failure, but the value doesn't actually matter.) */
+
+/* The item selected in the popup menu. */
+static Lisp_Object *volatile menu_item_selection;
+
+static void
+popup_selection_callback (GtkWidget *widget, gpointer client_data)
+{
+ xg_menu_item_cb_data *cb_data = client_data;
+
+ if (xg_crazy_callback_abort)
+ return;
+ if (cb_data)
+ menu_item_selection = cb_data->call_data;
+}
+
+static void
+pop_down_menu (void *arg)
+{
+ popup_activated_flag = 0;
+ block_input ();
+ gtk_widget_destroy (GTK_WIDGET (arg));
+ unblock_input ();
+}
+
+/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
+ menu pops down.
+ menu_item_selection will be set to the selection. */
+static void
+create_and_show_popup_menu (struct frame *f, widget_value * first_wv,
+ int x, int y, bool for_click)
+{
+ GtkWidget *menu;
+ ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+
+ eassert (FRAME_PGTK_P (f));
+
+ xg_crazy_callback_abort = true;
+ menu = xg_create_widget ("popup", first_wv->name, f, first_wv,
+ G_CALLBACK (popup_selection_callback),
+ G_CALLBACK (popup_deactivate_callback),
+ G_CALLBACK (menu_highlight_callback));
+ xg_crazy_callback_abort = false;
+
+ /* Display the menu. */
+ gtk_widget_show_all (menu);
+
+ if (for_click)
+ gtk_menu_popup_at_pointer (GTK_MENU (menu),
+ FRAME_DISPLAY_INFO (f)->last_click_event);
+ else
+ {
+ GdkRectangle rect;
+ rect.x = x;
+ rect.y = y;
+ rect.width = 1;
+ rect.height = 1;
+ gtk_menu_popup_at_rect (GTK_MENU (menu),
+ gtk_widget_get_window (FRAME_GTK_WIDGET (f)),
+ &rect,
+ GDK_GRAVITY_NORTH_WEST, GDK_GRAVITY_NORTH_WEST,
+ FRAME_DISPLAY_INFO (f)->last_click_event);
+ }
+
+ record_unwind_protect_ptr (pop_down_menu, menu);
+
+ if (gtk_widget_get_mapped (menu))
+ {
+ /* Set this to one. popup_widget_loop increases it by one, so it becomes
+ two. show_help_echo uses this to detect popup menus. */
+ popup_activated_flag = 1;
+ /* Process events that apply to the menu. */
+ popup_widget_loop (true, menu);
+ }
+
+ unbind_to (specpdl_count, Qnil);
+
+ /* Must reset this manually because the button release event is not passed
+ to Emacs event loop. */
+ FRAME_DISPLAY_INFO (f)->grabbed = 0;
+}
+
+static void
+cleanup_widget_value_tree (void *arg)
+{
+ free_menubar_widget_value_tree (arg);
+}
+
+Lisp_Object
+pgtk_menu_show (struct frame *f, int x, int y, int menuflags,
+ Lisp_Object title, const char **error_name)
+{
+ int i;
+ widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
+ widget_value **submenu_stack
+ = alloca (menu_items_used * sizeof *submenu_stack);
+ Lisp_Object *subprefix_stack
+ = alloca (menu_items_used * sizeof *subprefix_stack);
+ int submenu_depth = 0;
+
+ ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+
+ eassert (FRAME_PGTK_P (f));
+
+ *error_name = NULL;
+
+ if (!FRAME_GTK_OUTER_WIDGET (f)) {
+ *error_name = "Can't popup from child frames.";
+ return Qnil;
+ }
+
+ if (menu_items_used <= MENU_ITEMS_PANE_LENGTH)
+ {
+ *error_name = "Empty menu";
+ return Qnil;
+ }
+
+ block_input ();
+
+ /* Create a tree of widget_value objects
+ representing the panes and their items. */
+ wv = make_widget_value ("menu", NULL, true, Qnil);
+ wv->button_type = BUTTON_TYPE_NONE;
+ first_wv = wv;
+ bool first_pane = true;
+
+ /* Loop over all panes and items, filling in the tree. */
+ i = 0;
+ while (i < menu_items_used)
+ {
+ if (NILP (AREF (menu_items, i)))
+ {
+ submenu_stack[submenu_depth++] = save_wv;
+ save_wv = prev_wv;
+ prev_wv = 0;
+ first_pane = true;
+ i++;
+ }
+ else if (EQ (AREF (menu_items, i), Qlambda))
+ {
+ prev_wv = save_wv;
+ save_wv = submenu_stack[--submenu_depth];
+ first_pane = false;
+ i++;
+ }
+ else if (EQ (AREF (menu_items, i), Qt) && submenu_depth != 0)
+ i += MENU_ITEMS_PANE_LENGTH;
+ /* Ignore a nil in the item list.
+ It's meaningful only for dialog boxes. */
+ else if (EQ (AREF (menu_items, i), Qquote))
+ i += 1;
+ else if (EQ (AREF (menu_items, i), Qt))
+ {
+ /* Create a new pane. */
+ Lisp_Object pane_name, prefix;
+ const char *pane_string;
+
+ pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
+ prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
+
+#ifndef HAVE_MULTILINGUAL_MENU
+ if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
+ {
+ pane_name = ENCODE_MENU_STRING (pane_name);
+ ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
+ }
+#endif
+ pane_string = (NILP (pane_name) ? "" : SSDATA (pane_name));
+ /* If there is just one top-level pane, put all its items directly
+ under the top-level menu. */
+ if (menu_items_n_panes == 1)
+ pane_string = "";
+
+ /* If the pane has a meaningful name,
+ make the pane a top-level menu item
+ with its items as a submenu beneath it. */
+ if (!(menuflags & MENU_KEYMAPS) && strcmp (pane_string, ""))
+ {
+ wv = make_widget_value (pane_string, NULL, true, Qnil);
+ if (save_wv)
+ save_wv->next = wv;
+ else
+ first_wv->contents = wv;
+ if ((menuflags & MENU_KEYMAPS) && !NILP (prefix))
+ wv->name++;
+ wv->button_type = BUTTON_TYPE_NONE;
+ save_wv = wv;
+ prev_wv = 0;
+ }
+ else if (first_pane)
+ {
+ save_wv = wv;
+ prev_wv = 0;
+ }
+ first_pane = false;
+ i += MENU_ITEMS_PANE_LENGTH;
+ }
+ else
+ {
+ /* Create a new item within current pane. */
+ Lisp_Object item_name, enable, descrip, def, type, selected, help;
+ item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
+ enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
+ descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
+ def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION);
+ type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE);
+ selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
+ help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
+
+#ifndef HAVE_MULTILINGUAL_MENU
+ if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
+ {
+ item_name = ENCODE_MENU_STRING (item_name);
+ ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
+ }
+
+ if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
+ {
+ descrip = ENCODE_MENU_STRING (descrip);
+ ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
+ }
+#endif /* not HAVE_MULTILINGUAL_MENU */
+
+ wv = make_widget_value (SSDATA (item_name), NULL, !NILP (enable),
+ STRINGP (help) ? help : Qnil);
+ if (prev_wv)
+ prev_wv->next = wv;
+ else
+ save_wv->contents = wv;
+ if (!NILP (descrip))
+ wv->key = SSDATA (descrip);
+ /* If this item has a null value,
+ make the call_data null so that it won't display a box
+ when the mouse is on it. */
+ wv->call_data = !NILP (def) ? aref_addr (menu_items, i) : 0;
+
+ if (NILP (type))
+ wv->button_type = BUTTON_TYPE_NONE;
+ else if (EQ (type, QCtoggle))
+ wv->button_type = BUTTON_TYPE_TOGGLE;
+ else if (EQ (type, QCradio))
+ wv->button_type = BUTTON_TYPE_RADIO;
+ else
+ emacs_abort ();
+
+ wv->selected = !NILP (selected);
+
+ prev_wv = wv;
+
+ i += MENU_ITEMS_ITEM_LENGTH;
+ }
+ }
+
+ /* Deal with the title, if it is non-nil. */
+ if (!NILP (title))
+ {
+ widget_value *wv_title;
+ widget_value *wv_sep1 = make_widget_value ("--", NULL, false, Qnil);
+ widget_value *wv_sep2 = make_widget_value ("--", NULL, false, Qnil);
+
+ wv_sep2->next = first_wv->contents;
+ wv_sep1->next = wv_sep2;
+
+#ifndef HAVE_MULTILINGUAL_MENU
+ if (STRING_MULTIBYTE (title))
+ title = ENCODE_MENU_STRING (title);
+#endif
+
+ wv_title = make_widget_value (SSDATA (title), NULL, true, Qnil);
+ wv_title->button_type = BUTTON_TYPE_NONE;
+ wv_title->next = wv_sep1;
+ first_wv->contents = wv_title;
+ }
+
+ /* No selection has been chosen yet. */
+ menu_item_selection = 0;
+
+ /* Make sure to free the widget_value objects we used to specify the
+ contents even with longjmp. */
+ record_unwind_protect_ptr (cleanup_widget_value_tree, first_wv);
+
+ /* Actually create and show the menu until popped down. */
+ create_and_show_popup_menu (f, first_wv, x, y, menuflags & MENU_FOR_CLICK);
+
+ unbind_to (specpdl_count, Qnil);
+
+ /* Find the selected item, and its pane, to return
+ the proper value. */
+ if (menu_item_selection != 0)
+ {
+ Lisp_Object prefix, entry;
+
+ prefix = entry = Qnil;
+ i = 0;
+ while (i < menu_items_used)
+ {
+ if (NILP (AREF (menu_items, i)))
+ {
+ subprefix_stack[submenu_depth++] = prefix;
+ prefix = entry;
+ i++;
+ }
+ else if (EQ (AREF (menu_items, i), Qlambda))
+ {
+ prefix = subprefix_stack[--submenu_depth];
+ i++;
+ }
+ else if (EQ (AREF (menu_items, i), Qt))
+ {
+ prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
+ i += MENU_ITEMS_PANE_LENGTH;
+ }
+ /* Ignore a nil in the item list.
+ It's meaningful only for dialog boxes. */
+ else if (EQ (AREF (menu_items, i), Qquote))
+ i += 1;
+ else
+ {
+ entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
+ if (menu_item_selection == aref_addr (menu_items, i))
+ {
+ if (menuflags & MENU_KEYMAPS)
+ {
+ int j;
+
+ entry = list1 (entry);
+ if (!NILP (prefix))
+ entry = Fcons (prefix, entry);
+ for (j = submenu_depth - 1; j >= 0; j--)
+ if (!NILP (subprefix_stack[j]))
+ entry = Fcons (subprefix_stack[j], entry);
+ }
+ unblock_input ();
+ return entry;
+ }
+ i += MENU_ITEMS_ITEM_LENGTH;
+ }
+ }
+ }
+ else if (!(menuflags & MENU_FOR_CLICK))
+ {
+ unblock_input ();
+ /* Make "Cancel" equivalent to C-g. */
+ quit ();
+ }
+
+ unblock_input ();
+ return Qnil;
+}
+
+static void
+dialog_selection_callback (GtkWidget *widget, gpointer client_data)
+{
+ /* Treat the pointer as an integer. There's no problem
+ as long as pointers have enough bits to hold small integers. */
+ if ((intptr_t) client_data != -1)
+ menu_item_selection = client_data;
+
+ popup_activated_flag = 0;
+}
+
+/* Pop up the dialog for frame F defined by FIRST_WV and loop until the
+ dialog pops down.
+ menu_item_selection will be set to the selection. */
+static void
+create_and_show_dialog (struct frame *f, widget_value *first_wv)
+{
+ GtkWidget *menu;
+
+ eassert (FRAME_PGTK_P (f));
+
+ menu = xg_create_widget ("dialog", first_wv->name, f, first_wv,
+ G_CALLBACK (dialog_selection_callback),
+ G_CALLBACK (popup_deactivate_callback), 0);
+
+ if (menu)
+ {
+ ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+ record_unwind_protect_ptr (pop_down_menu, menu);
+
+ /* Display the menu. */
+ gtk_widget_show_all (menu);
+
+ /* Process events that apply to the menu. */
+ popup_widget_loop (true, menu);
+
+ unbind_to (specpdl_count, Qnil);
+ }
+}
+
+static const char *button_names[] = {
+ "button1", "button2", "button3", "button4", "button5",
+ "button6", "button7", "button8", "button9", "button10"
+};
+
+Lisp_Object
+pgtk_dialog_show (struct frame *f, Lisp_Object title,
+ Lisp_Object header, const char **error_name)
+{
+ int i, nb_buttons = 0;
+ char dialog_name[6];
+
+ widget_value *wv, *first_wv = 0, *prev_wv = 0;
+
+ /* Number of elements seen so far, before boundary. */
+ int left_count = 0;
+ /* Whether we've seen the boundary between left-hand elts and right-hand. */
+ bool boundary_seen = false;
+
+ ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+
+ eassert (FRAME_PGTK_P (f));
+
+ *error_name = NULL;
+
+ if (!FRAME_GTK_OUTER_WIDGET (f)) {
+ *error_name = "Can't popup from child frames.";
+ return Qnil;
+ }
+
+ if (menu_items_n_panes > 1)
+ {
+ *error_name = "Multiple panes in dialog box";
+ return Qnil;
+ }
+
+ /* Create a tree of widget_value objects
+ representing the text label and buttons. */
+ {
+ Lisp_Object pane_name;
+ const char *pane_string;
+ pane_name = AREF (menu_items, MENU_ITEMS_PANE_NAME);
+ pane_string = (NILP (pane_name) ? "" : SSDATA (pane_name));
+ prev_wv = make_widget_value ("message", (char *) pane_string, true, Qnil);
+ first_wv = prev_wv;
+
+ /* Loop over all panes and items, filling in the tree. */
+ i = MENU_ITEMS_PANE_LENGTH;
+ while (i < menu_items_used)
+ {
+
+ /* Create a new item within current pane. */
+ Lisp_Object item_name, enable, descrip;
+ item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
+ enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
+ descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
+
+ if (NILP (item_name))
+ {
+ free_menubar_widget_value_tree (first_wv);
+ *error_name = "Submenu in dialog items";
+ return Qnil;
+ }
+ if (EQ (item_name, Qquote))
+ {
+ /* This is the boundary between left-side elts
+ and right-side elts. Stop incrementing right_count. */
+ boundary_seen = true;
+ i++;
+ continue;
+ }
+ if (nb_buttons >= 9)
+ {
+ free_menubar_widget_value_tree (first_wv);
+ *error_name = "Too many dialog items";
+ return Qnil;
+ }
+
+ wv = make_widget_value (button_names[nb_buttons],
+ SSDATA (item_name), !NILP (enable), Qnil);
+ prev_wv->next = wv;
+ if (!NILP (descrip))
+ wv->key = SSDATA (descrip);
+ wv->call_data = aref_addr (menu_items, i);
+ prev_wv = wv;
+
+ if (!boundary_seen)
+ left_count++;
+
+ nb_buttons++;
+ i += MENU_ITEMS_ITEM_LENGTH;
+ }
+
+ /* If the boundary was not specified,
+ by default put half on the left and half on the right. */
+ if (!boundary_seen)
+ left_count = nb_buttons - nb_buttons / 2;
+
+ wv = make_widget_value (dialog_name, NULL, false, Qnil);
+
+ /* Frame title: 'Q' = Question, 'I' = Information.
+ Can also have 'E' = Error if, one day, we want
+ a popup for errors. */
+ if (NILP (header))
+ dialog_name[0] = 'Q';
+ else
+ dialog_name[0] = 'I';
+
+ /* Dialog boxes use a really stupid name encoding
+ which specifies how many buttons to use
+ and how many buttons are on the right. */
+ dialog_name[1] = '0' + nb_buttons;
+ dialog_name[2] = 'B';
+ dialog_name[3] = 'R';
+ /* Number of buttons to put on the right. */
+ dialog_name[4] = '0' + nb_buttons - left_count;
+ dialog_name[5] = 0;
+ wv->contents = first_wv;
+ first_wv = wv;
+ }
+
+ /* No selection has been chosen yet. */
+ menu_item_selection = 0;
+
+ /* Make sure to free the widget_value objects we used to specify the
+ contents even with longjmp. */
+ record_unwind_protect_ptr (cleanup_widget_value_tree, first_wv);
+
+ /* Actually create and show the dialog. */
+ create_and_show_dialog (f, first_wv);
+
+ unbind_to (specpdl_count, Qnil);
+
+ /* Find the selected item, and its pane, to return
+ the proper value. */
+ if (menu_item_selection != 0)
+ {
+ i = 0;
+ while (i < menu_items_used)
+ {
+ Lisp_Object entry;
+
+ if (EQ (AREF (menu_items, i), Qt))
+ i += MENU_ITEMS_PANE_LENGTH;
+ else if (EQ (AREF (menu_items, i), Qquote))
+ {
+ /* This is the boundary between left-side elts and
+ right-side elts. */
+ ++i;
+ }
+ else
+ {
+ entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
+ if (menu_item_selection == aref_addr (menu_items, i))
+ return entry;
+ i += MENU_ITEMS_ITEM_LENGTH;
+ }
+ }
+ }
+ else
+ /* Make "Cancel" equivalent to C-g. */
+ quit ();
+
+ return Qnil;
+}
+
+Lisp_Object
+pgtk_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
+{
+ Lisp_Object title;
+ const char *error_name;
+ Lisp_Object selection;
+ ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+
+ check_window_system (f);
+
+ /* Decode the dialog items from what was specified. */
+ title = Fcar (contents);
+ CHECK_STRING (title);
+ record_unwind_protect_void (unuse_menu_items);
+
+ if (NILP (Fcar (Fcdr (contents))))
+ /* No buttons specified, add an "Ok" button so users can pop down
+ the dialog. Also, the lesstif/motif version crashes if there are
+ no buttons. */
+ contents = list2 (title, Fcons (build_string ("Ok"), Qt));
+
+ list_of_panes (list1 (contents));
+
+ /* Display them in a dialog box. */
+ block_input ();
+ selection = pgtk_dialog_show (f, title, header, &error_name);
+ unblock_input ();
+
+ unbind_to (specpdl_count, Qnil);
+ discard_menu_items ();
+
+ if (error_name)
+ error ("%s", error_name);
+ return selection;
+}
+
+/* Detect if a dialog or menu has been posted. MSDOS has its own
+ implementation on msdos.c. */
+
+int
+popup_activated (void)
+{
+ return popup_activated_flag;
+}
+
+/* The following is used by delayed window autoselection. */
+
+DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0,
+ doc: /* Return t if a menu or popup dialog is active.
+\(On MS Windows, this refers to the selected frame.) */)
+ (void)
+{
+ return (popup_activated ())? Qt : Qnil;
+}
+
+static void syms_of_pgtkmenu_for_pdumper (void);
+
+void
+syms_of_pgtkmenu (void)
+{
+ DEFSYM (Qdebug_on_next_call, "debug-on-next-call");
+ defsubr (&Smenu_or_popup_active_p);
+
+ DEFSYM (Qframe_monitor_workarea, "frame-monitor-workarea");
+
+ defsubr (&Sx_menu_bar_open_internal);
+ Ffset (intern_c_string ("accelerate-menu"),
+ intern_c_string (Sx_menu_bar_open_internal.s.symbol_name));
+
+ pdumper_do_now_and_after_load (syms_of_pgtkmenu_for_pdumper);
+}
+
+static void
+syms_of_pgtkmenu_for_pdumper (void)
+{
+}
diff --git a/src/pgtkselect.c b/src/pgtkselect.c
new file mode 100644
index 00000000000..77a563dc3f3
--- /dev/null
+++ b/src/pgtkselect.c
@@ -0,0 +1,632 @@
+/* Gtk selection processing for emacs.
+ Copyright (C) 1993-1994, 2005-2006, 2008-2020 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/>. */
+
+/*
+Originally by Carl Edman
+Updated by Christian Limpach (chris@nice.ch)
+OpenStep/Rhapsody port by Scott Bender (sbender@harmony-ds.com)
+macOS/Aqua port by Christophe de Dinechin (descubes@earthlink.net)
+GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
+*/
+
+/* This should be the first include, as it may set up #defines affecting
+ interpretation of even the system includes. */
+#include <config.h>
+
+#include "lisp.h"
+#include "pgtkterm.h"
+#include "termhooks.h"
+#include "keyboard.h"
+#include "pgtkselect.h"
+#include <gdk/gdk.h>
+
+#if 0
+static Lisp_Object Vselection_alist;
+#endif
+
+static GQuark quark_primary_data = 0;
+static GQuark quark_primary_size = 0;
+static GQuark quark_secondary_data = 0;
+static GQuark quark_secondary_size = 0;
+static GQuark quark_clipboard_data = 0;
+static GQuark quark_clipboard_size = 0;
+
+/* ==========================================================================
+
+ Internal utility functions
+
+ ========================================================================== */
+
+/* From a Lisp_Object, return a suitable frame for selection
+ operations. OBJECT may be a frame, a terminal object, or nil
+ (which stands for the selected frame--or, if that is not an pgtk
+ frame, the first pgtk display on the list). If no suitable frame can
+ be found, return NULL. */
+
+static struct frame *
+frame_for_pgtk_selection (Lisp_Object object)
+{
+ Lisp_Object tail, frame;
+ struct frame *f;
+
+ if (NILP (object))
+ {
+ f = XFRAME (selected_frame);
+ if (FRAME_PGTK_P (f) && FRAME_LIVE_P (f))
+ return f;
+
+ FOR_EACH_FRAME (tail, frame)
+ {
+ f = XFRAME (frame);
+ if (FRAME_PGTK_P (f) && FRAME_LIVE_P (f))
+ return f;
+ }
+ }
+ else if (TERMINALP (object))
+ {
+ struct terminal *t = decode_live_terminal (object);
+
+ if (t->type == output_pgtk)
+ FOR_EACH_FRAME (tail, frame)
+ {
+ f = XFRAME (frame);
+ if (FRAME_LIVE_P (f) && f->terminal == t)
+ return f;
+ }
+ }
+ else if (FRAMEP (object))
+ {
+ f = XFRAME (object);
+ if (FRAME_PGTK_P (f) && FRAME_LIVE_P (f))
+ return f;
+ }
+
+ return NULL;
+}
+
+static GtkClipboard *
+symbol_to_gtk_clipboard (GtkWidget * widget, Lisp_Object symbol)
+{
+ GdkAtom atom;
+
+ CHECK_SYMBOL (symbol);
+ if (NILP (symbol))
+ {
+ atom = GDK_SELECTION_PRIMARY;
+ }
+ else if (EQ (symbol, QCLIPBOARD))
+ {
+ atom = GDK_SELECTION_CLIPBOARD;
+ }
+ else if (EQ (symbol, QPRIMARY))
+ {
+ atom = GDK_SELECTION_PRIMARY;
+ }
+ else if (EQ (symbol, QSECONDARY))
+ {
+ atom = GDK_SELECTION_SECONDARY;
+ }
+ else if (EQ (symbol, Qt))
+ {
+ atom = GDK_SELECTION_SECONDARY;
+ }
+ else
+ {
+ atom = 0;
+ error ("Bad selection");
+ }
+
+ return gtk_widget_get_clipboard (widget, atom);
+}
+
+static void
+selection_type_to_quarks (GdkAtom type, GQuark * quark_data,
+ GQuark * quark_size)
+{
+ if (type == GDK_SELECTION_PRIMARY)
+ {
+ *quark_data = quark_primary_data;
+ *quark_size = quark_primary_size;
+ }
+ else if (type == GDK_SELECTION_SECONDARY)
+ {
+ *quark_data = quark_secondary_data;
+ *quark_size = quark_secondary_size;
+ }
+ else if (type == GDK_SELECTION_CLIPBOARD)
+ {
+ *quark_data = quark_clipboard_data;
+ *quark_size = quark_clipboard_size;
+ }
+ else
+ {
+ /* fixme: Is it safe to use 'error' here? */
+ error ("Unknown selection type.");
+ }
+}
+
+static void
+get_func (GtkClipboard * cb, GtkSelectionData * data, guint info,
+ gpointer user_data_or_owner)
+{
+ GObject *obj = G_OBJECT (user_data_or_owner);
+ const char *str;
+ int size;
+ GQuark quark_data, quark_size;
+
+ selection_type_to_quarks (gtk_clipboard_get_selection (cb), &quark_data,
+ &quark_size);
+
+ str = g_object_get_qdata (obj, quark_data);
+ size = GPOINTER_TO_SIZE (g_object_get_qdata (obj, quark_size));
+ gtk_selection_data_set_text (data, str, size);
+}
+
+static void
+clear_func (GtkClipboard * cb, gpointer user_data_or_owner)
+{
+ GObject *obj = G_OBJECT (user_data_or_owner);
+ GQuark quark_data, quark_size;
+
+ selection_type_to_quarks (gtk_clipboard_get_selection (cb), &quark_data,
+ &quark_size);
+
+ g_object_set_qdata (obj, quark_data, NULL);
+ g_object_set_qdata (obj, quark_size, 0);
+}
+
+
+/* ==========================================================================
+
+ Functions used externally
+
+ ========================================================================== */
+
+void
+pgtk_selection_init (void)
+{
+ if (quark_primary_data == 0)
+ {
+ quark_primary_data = g_quark_from_static_string ("pgtk-primary-data");
+ quark_primary_size = g_quark_from_static_string ("pgtk-primary-size");
+ quark_secondary_data =
+ g_quark_from_static_string ("pgtk-secondary-data");
+ quark_secondary_size =
+ g_quark_from_static_string ("pgtk-secondary-size");
+ quark_clipboard_data =
+ g_quark_from_static_string ("pgtk-clipboard-data");
+ quark_clipboard_size =
+ g_quark_from_static_string ("pgtk-clipboard-size");
+ }
+}
+
+void
+pgtk_selection_lost (GtkWidget * widget, GdkEventSelection * event,
+ gpointer user_data)
+{
+ GQuark quark_data, quark_size;
+
+ selection_type_to_quarks (event->selection, &quark_data, &quark_size);
+
+ g_object_set_qdata (G_OBJECT (widget), quark_data, NULL);
+ g_object_set_qdata (G_OBJECT (widget), quark_size, 0);
+}
+
+static bool
+pgtk_selection_usable (void)
+{
+ if (pgtk_enable_selection_on_multi_display)
+ return true;
+
+ /*
+ * https://github.com/GNOME/gtk/blob/gtk-3-24/gdk/wayland/gdkselection-wayland.c#L1033
+ *
+ * Gdk uses gdk_display_get_default() when handling selections, so
+ * selections don't work properly on multi-display environment.
+ *
+ * ----------------
+ * #include <gtk/gtk.h>
+ *
+ * static GtkWidget *top1, *top2;
+ *
+ * int main (int argc, char **argv)
+ * {
+ * GtkWidget *w;
+ * GtkTextBuffer *buf;
+ *
+ * gtk_init (&argc, &argv);
+ *
+ * static char *text = "\
+ * It is fine today.\n\
+ * It will be fine tomorrow too.\n\
+ * It is too hot.";
+ *
+ * top1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ * gtk_window_set_title (GTK_WINDOW (top1), "default");
+ * gtk_widget_show (top1);
+ * w = gtk_text_view_new ();
+ * gtk_container_add (GTK_CONTAINER (top1), w);
+ * gtk_widget_show (w);
+ * buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (w));
+ * gtk_text_buffer_insert_at_cursor (buf, text, strlen (text));
+ * gtk_text_buffer_add_selection_clipboard (buf, gtk_widget_get_clipboard (w, GDK_SELECTION_PRIMARY));
+ *
+ * unsetenv ("GDK_BACKEND");
+ * GdkDisplay *gdpy;
+ * const char *dpyname2;
+ * if (strcmp (G_OBJECT_TYPE_NAME (gtk_widget_get_window (top1)), "GdkWaylandWindow") == 0)
+ * dpyname2 = ":0";
+ * else
+ * dpyname2 = "wayland-0";
+ * gdpy = gdk_display_open (dpyname2);
+ * top2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ * gtk_window_set_title (GTK_WINDOW (top2), dpyname2);
+ * gtk_window_set_screen (GTK_WINDOW (top2), gdk_display_get_default_screen (gdpy));
+ * gtk_widget_show (top2);
+ * w = gtk_text_view_new ();
+ * gtk_container_add (GTK_CONTAINER (top2), w);
+ * gtk_widget_show (w);
+ * buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (w));
+ * gtk_text_buffer_insert_at_cursor (buf, text, strlen (text));
+ * gtk_text_buffer_add_selection_clipboard (buf, gtk_widget_get_clipboard (w, GDK_SELECTION_PRIMARY));
+ *
+ * gtk_main ();
+ *
+ * return 0;
+ * }
+ * ----------------
+ *
+ * This code fails if
+ * GDK_BACKEND=x11 ./test
+ * and select on both of windows.
+ *
+ * ----------------
+ * (test:15345): GLib-GObject-CRITICAL **: 01:56:38.041: g_object_ref: assertion 'G_IS_OBJECT (object)' failed
+ *
+ * (test:15345): GLib-GObject-CRITICAL **: 01:56:38.042: g_object_ref: assertion 'G_IS_OBJECT (object)' failed
+ *
+ * (test:15345): GLib-GObject-CRITICAL **: 01:56:39.113: g_object_ref: assertion 'G_IS_OBJECT (object)' failed
+ *
+ * (test:15345): GLib-GObject-CRITICAL **: 01:56:39.113: g_object_ref: assertion 'G_IS_OBJECT (object)' failed
+ * ----------------
+ * (gtk-3.24.10)
+ *
+ * This function checks whether selections work by the number of displays.
+ * If you use more than 2 displays, then selection is disabled.
+ */
+
+ GdkDisplayManager *dpyman = gdk_display_manager_get ();
+ GSList *list = gdk_display_manager_list_displays (dpyman);
+ int len = g_slist_length (list);
+ g_slist_free (list);
+ return len < 2;
+}
+
+/* ==========================================================================
+
+ Lisp Defuns
+
+ ========================================================================== */
+
+
+DEFUN ("pgtk-own-selection-internal", Fpgtk_own_selection_internal, Spgtk_own_selection_internal, 2, 3, 0,
+ doc: /* Assert an X selection of type SELECTION and value VALUE.
+SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
+\(Those are literal upper-case symbol names, since that's what X expects.)
+VALUE is typically a string, or a cons of two markers, but may be
+anything that the functions on `selection-converter-alist' know about.
+
+FRAME should be a frame that should own the selection. If omitted or
+nil, it defaults to the selected frame. */)
+ (Lisp_Object selection, Lisp_Object value, Lisp_Object frame)
+{
+ Lisp_Object successful_p = Qnil;
+ Lisp_Object target_symbol, rest;
+ GtkClipboard *cb;
+ struct frame *f;
+ GQuark quark_data, quark_size;
+
+ check_window_system (NULL);
+
+ if (!pgtk_selection_usable ())
+ return Qnil;
+
+ if (NILP (frame))
+ frame = selected_frame;
+ if (!FRAME_LIVE_P (XFRAME (frame)) || !FRAME_PGTK_P (XFRAME (frame)))
+ error ("pgtk selection unavailable for this frame");
+ f = XFRAME (frame);
+
+ cb = symbol_to_gtk_clipboard (FRAME_GTK_WIDGET (f), selection);
+ selection_type_to_quarks (gtk_clipboard_get_selection (cb), &quark_data,
+ &quark_size);
+
+ /* We only support copy of text. */
+ target_symbol = QTEXT;
+ if (STRINGP (value))
+ {
+ GtkTargetList *list;
+ GtkTargetEntry *targets;
+ gint n_targets;
+ GtkWidget *widget;
+
+ list = gtk_target_list_new (NULL, 0);
+ gtk_target_list_add_text_targets (list, 0);
+
+ {
+ /* text/plain: Strings encoded by Gtk are not correctly decoded by Chromium(Wayland). */
+ GdkAtom atom_text_plain = gdk_atom_intern ("text/plain", false);
+ gtk_target_list_remove (list, atom_text_plain);
+ }
+
+ targets = gtk_target_table_new_from_list (list, &n_targets);
+
+ int size = SBYTES (value);
+ gchar *str = xmalloc (size + 1);
+ memcpy (str, SSDATA (value), size);
+ str[size] = '\0';
+
+ widget = FRAME_GTK_WIDGET (f);
+ g_object_set_qdata_full (G_OBJECT (widget), quark_data, str, xfree);
+ g_object_set_qdata_full (G_OBJECT (widget), quark_size,
+ GSIZE_TO_POINTER (size), NULL);
+
+ if (gtk_clipboard_set_with_owner (cb,
+ targets, n_targets,
+ get_func, clear_func,
+ G_OBJECT (FRAME_GTK_WIDGET (f))))
+ {
+ successful_p = Qt;
+ }
+ gtk_clipboard_set_can_store (cb, NULL, 0);
+
+ gtk_target_table_free (targets, n_targets);
+ gtk_target_list_unref (list);
+ }
+
+ if (!EQ (Vpgtk_sent_selection_hooks, Qunbound))
+ {
+ /* FIXME: Use run-hook-with-args! */
+ for (rest = Vpgtk_sent_selection_hooks; CONSP (rest);
+ rest = Fcdr (rest))
+ call3 (Fcar (rest), selection, target_symbol, successful_p);
+ }
+
+ return value;
+}
+
+
+DEFUN ("pgtk-disown-selection-internal", Fpgtk_disown_selection_internal, Spgtk_disown_selection_internal, 1, 3, 0,
+ doc: /* If we own the selection SELECTION, disown it.
+Disowning it means there is no such selection.
+
+Sets the last-change time for the selection to TIME-OBJECT (by default
+the time of the last event).
+
+TERMINAL should be a terminal object or a frame specifying the X
+server to query. If omitted or nil, that stands for the selected
+frame's display, or the first available X display.
+
+On Nextstep, the TIME-OBJECT and TERMINAL arguments are unused.
+On MS-DOS, all this does is return non-nil if we own the selection.
+On PGTK, the TIME-OBJECT is unused. */)
+ (Lisp_Object selection, Lisp_Object time_object, Lisp_Object terminal)
+{
+ struct frame *f = frame_for_pgtk_selection (terminal);
+ GtkClipboard *cb;
+
+ if (!pgtk_selection_usable ())
+ return Qnil;
+
+ if (!f)
+ return Qnil;
+
+ cb = symbol_to_gtk_clipboard (FRAME_GTK_WIDGET (f), selection);
+
+ gtk_clipboard_clear (cb);
+
+ return Qt;
+}
+
+
+DEFUN ("pgtk-selection-exists-p", Fpgtk_selection_exists_p, Spgtk_selection_exists_p, 0, 2, 0,
+ doc: /* Whether there is an owner for the given X selection.
+SELECTION should be the name of the selection in question, typically
+one of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. (X expects
+these literal upper-case names.) The symbol nil is the same as
+`PRIMARY', and t is the same as `SECONDARY'.
+
+TERMINAL should be a terminal object or a frame specifying the X
+server to query. If omitted or nil, that stands for the selected
+frame's display, or the first available X display.
+
+On Nextstep, TERMINAL is unused. */)
+ (Lisp_Object selection, Lisp_Object terminal)
+{
+ struct frame *f = frame_for_pgtk_selection (terminal);
+ GtkClipboard *cb;
+
+ if (!pgtk_selection_usable ())
+ return Qnil;
+
+ if (!f)
+ return Qnil;
+
+ cb = symbol_to_gtk_clipboard (FRAME_GTK_WIDGET (f), selection);
+
+ return gtk_clipboard_wait_is_text_available (cb) ? Qt : Qnil;
+}
+
+
+DEFUN ("pgtk-selection-owner-p", Fpgtk_selection_owner_p, Spgtk_selection_owner_p, 0, 2, 0,
+ doc: /* Whether the current Emacs process owns the given X Selection.
+The arg should be the name of the selection in question, typically one of
+the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
+\(Those are literal upper-case symbol names, since that's what X expects.)
+For convenience, the symbol nil is the same as `PRIMARY',
+and t is the same as `SECONDARY'.
+
+TERMINAL should be a terminal object or a frame specifying the X
+server to query. If omitted or nil, that stands for the selected
+frame's display, or the first available X display.
+
+On Nextstep, TERMINAL is unused. */)
+ (Lisp_Object selection, Lisp_Object terminal)
+{
+ struct frame *f = frame_for_pgtk_selection (terminal);
+ GtkClipboard *cb;
+ GObject *obj;
+ GQuark quark_data, quark_size;
+
+ if (!pgtk_selection_usable ())
+ return Qnil;
+
+ cb = symbol_to_gtk_clipboard (FRAME_GTK_WIDGET (f), selection);
+ selection_type_to_quarks (gtk_clipboard_get_selection (cb), &quark_data,
+ &quark_size);
+
+ obj = gtk_clipboard_get_owner (cb);
+
+ return obj && g_object_get_qdata (obj, quark_data) != NULL ? Qt : Qnil;
+}
+
+
+DEFUN ("pgtk-get-selection-internal", Fpgtk_get_selection_internal, Spgtk_get_selection_internal, 2, 4, 0,
+ doc: /* Return text selected from some X window.
+SELECTION-SYMBOL is typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
+\(Those are literal upper-case symbol names, since that's what X expects.)
+TARGET-TYPE is the type of data desired, typically `STRING'.
+
+TIME-STAMP is the time to use in the XConvertSelection call for foreign
+selections. If omitted, defaults to the time for the last event.
+
+TERMINAL should be a terminal object or a frame specifying the X
+server to query. If omitted or nil, that stands for the selected
+frame's display, or the first available X display.
+
+On Nextstep, TIME-STAMP and TERMINAL are unused.
+On PGTK, TIME-STAMP is unused. */)
+ (Lisp_Object selection_symbol, Lisp_Object target_type,
+ Lisp_Object time_stamp, Lisp_Object terminal)
+{
+ struct frame *f = frame_for_pgtk_selection (terminal);
+ GtkClipboard *cb;
+
+ CHECK_SYMBOL (selection_symbol);
+ CHECK_SYMBOL (target_type);
+ if (EQ (target_type, QMULTIPLE))
+ error ("Retrieving MULTIPLE selections is currently unimplemented");
+ if (!f)
+ error ("PGTK selection unavailable for this frame");
+
+ if (!pgtk_selection_usable ())
+ return Qnil;
+
+ cb = symbol_to_gtk_clipboard (FRAME_GTK_WIDGET (f), selection_symbol);
+
+ GdkAtom target_atom = gdk_atom_intern (SSDATA (SYMBOL_NAME (target_type)), false);
+ GtkSelectionData *seldata = gtk_clipboard_wait_for_contents (cb, target_atom);
+
+ if (seldata == NULL)
+ return Qnil;
+
+ const guchar *sd_data = gtk_selection_data_get_data (seldata);
+ int sd_len = gtk_selection_data_get_length (seldata);
+ int sd_format = gtk_selection_data_get_format (seldata);
+ GdkAtom sd_type = gtk_selection_data_get_data_type (seldata);
+
+ if (sd_format == 8)
+ {
+ Lisp_Object str, lispy_type;
+
+ str = make_unibyte_string ((char *) sd_data, sd_len);
+ /* Indicate that this string is from foreign selection by a text
+ property `foreign-selection' so that the caller of
+ x-get-selection-internal (usually x-get-selection) can know
+ that the string must be decode. */
+ if (sd_type == gdk_atom_intern ("COMPOUND_TEXT", false))
+ lispy_type = QCOMPOUND_TEXT;
+ else if (sd_type == gdk_atom_intern ("UTF8_STRING", false))
+ lispy_type = QUTF8_STRING;
+ else if (sd_type == gdk_atom_intern ("text/plain;charset=utf-8", false))
+ lispy_type = Qtext_plain_charset_utf_8;
+ else
+ lispy_type = QSTRING;
+ Fput_text_property (make_fixnum (0), make_fixnum (sd_len),
+ Qforeign_selection, lispy_type, str);
+
+ gtk_selection_data_free (seldata);
+ return str;
+ }
+
+ gtk_selection_data_free (seldata);
+ return Qnil;
+}
+
+
+void
+nxatoms_of_pgtkselect (void)
+{
+}
+
+void
+syms_of_pgtkselect (void)
+{
+ DEFSYM (QCLIPBOARD, "CLIPBOARD");
+ DEFSYM (QSECONDARY, "SECONDARY");
+ DEFSYM (QTEXT, "TEXT");
+ DEFSYM (QFILE_NAME, "FILE_NAME");
+ DEFSYM (QMULTIPLE, "MULTIPLE");
+
+ DEFSYM (Qforeign_selection, "foreign-selection");
+ DEFSYM (QUTF8_STRING, "UTF8_STRING");
+ DEFSYM (QSTRING, "STRING");
+ DEFSYM (QCOMPOUND_TEXT, "COMPOUND_TEXT");
+ DEFSYM (Qtext_plain_charset_utf_8, "text/plain;charset=utf-8");
+
+ defsubr (&Spgtk_disown_selection_internal);
+ defsubr (&Spgtk_get_selection_internal);
+ defsubr (&Spgtk_own_selection_internal);
+ defsubr (&Spgtk_selection_exists_p);
+ defsubr (&Spgtk_selection_owner_p);
+
+#if 0
+ Vselection_alist = Qnil;
+ staticpro (&Vselection_alist);
+#endif
+
+ DEFVAR_LISP ("pgtk-sent-selection-hooks", Vpgtk_sent_selection_hooks,
+ "A list of functions to be called when Emacs answers a selection request.\n\
+The functions are called with four arguments:\n\
+ - the selection name (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');\n\
+ - the selection-type which Emacs was asked to convert the\n\
+ selection into before sending (for example, `STRING' or `LENGTH');\n\
+ - a flag indicating success or failure for responding to the request.\n\
+We might have failed (and declined the request) for any number of reasons,\n\
+including being asked for a selection that we no longer own, or being asked\n\
+to convert into a type that we don't know about or that is inappropriate.\n\
+This hook doesn't let you change the behavior of Emacs's selection replies,\n\
+it merely informs you that they have happened.");
+ Vpgtk_sent_selection_hooks = Qnil;
+
+ DEFVAR_BOOL ("pgtk-enable-selection-on-multi-display", pgtk_enable_selection_on_multi_display,
+ doc: /* Enable selection on multi display environment.
+This may cause crash. */);
+ pgtk_enable_selection_on_multi_display = false;
+}
diff --git a/src/pgtkselect.h b/src/pgtkselect.h
new file mode 100644
index 00000000000..7ad04c217ac
--- /dev/null
+++ b/src/pgtkselect.h
@@ -0,0 +1,33 @@
+/* Definitions and headers for selection of pure Gtk+3.
+ Copyright (C) 1989, 1993, 2005, 2008-2020 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/>. */
+
+
+#include "dispextern.h"
+#include "frame.h"
+
+#ifdef HAVE_PGTK
+
+#include <gtk/gtk.h>
+
+extern void pgtk_selection_init (void);
+extern void pgtk_selection_lost (GtkWidget * widget,
+ GdkEventSelection * event,
+ gpointer user_data);
+
+#endif /* HAVE_PGTK */
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
new file mode 100644
index 00000000000..bd61c65edde
--- /dev/null
+++ b/src/pgtkterm.c
@@ -0,0 +1,7115 @@
+/* Pure Gtk+-3 communication module. -*- coding: utf-8 -*-
+
+Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2020 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/>. */
+
+/* This should be the first include, as it may set up #defines affecting
+ interpretation of even the system includes. */
+#include <config.h>
+
+#include <cairo.h>
+#include <fcntl.h>
+#include <math.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <time.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <c-ctype.h>
+#include <c-strcase.h>
+#include <ftoastr.h>
+
+#include "lisp.h"
+#include "blockinput.h"
+#include "frame.h"
+#include "sysselect.h"
+#include "gtkutil.h"
+#include "systime.h"
+#include "character.h"
+#include "xwidget.h"
+#include "fontset.h"
+#include "composite.h"
+#include "ccl.h"
+#include "dynlib.h"
+
+#include "termhooks.h"
+#include "termopts.h"
+#include "termchar.h"
+#include "emacs-icon.h"
+#include "menu.h"
+#include "window.h"
+#include "keyboard.h"
+#include "atimer.h"
+#include "buffer.h"
+#include "font.h"
+#include "xsettings.h"
+#include "pgtkselect.h"
+#include "emacsgtkfixed.h"
+
+#ifdef GDK_WINDOWING_WAYLAND
+#include <gdk/gdkwayland.h>
+#endif
+
+#define STORE_KEYSYM_FOR_DEBUG(keysym) ((void)0)
+
+#define FRAME_CR_CONTEXT(f) ((f)->output_data.pgtk->cr_context)
+#define FRAME_CR_ACTIVE_CONTEXT(f) ((f)->output_data.pgtk->cr_active)
+#define FRAME_CR_SURFACE(f) (cairo_get_target (FRAME_CR_CONTEXT (f)))
+
+/* Non-zero means that a HELP_EVENT has been generated since Emacs
+ start. */
+
+static bool any_help_event_p;
+
+struct pgtk_display_info *x_display_list; /* Chain of existing displays */
+extern Lisp_Object tip_frame;
+
+static struct event_queue_t
+{
+ union buffered_input_event *q;
+ int nr, cap;
+} event_q = {
+ NULL, 0, 0,
+};
+
+/* Non-zero timeout value means ignore next mouse click if it arrives
+ before that timeout elapses (i.e. as part of the same sequence of
+ events resulting from clicking on a frame to select it). */
+
+static Time ignore_next_mouse_click_timeout;
+
+static Lisp_Object xg_default_icon_file;
+
+static void pgtk_delete_display (struct pgtk_display_info *dpyinfo);
+static void pgtk_clear_frame_area (struct frame *f, int x, int y, int width,
+ int height);
+static void pgtk_fill_rectangle (struct frame *f, unsigned long color, int x,
+ int y, int width, int height);
+static void pgtk_clip_to_row (struct window *w, struct glyph_row *row,
+ enum glyph_row_area area, cairo_t * cr);
+static struct frame *pgtk_any_window_to_frame (GdkWindow * window);
+
+/*
+ * This is not a flip context in the same sense as gpu rendering
+ * scences, it only occurs when a new context was required due to a
+ * resize or other fundamental change. This is called when that
+ * context's surface has completed drawing
+ */
+
+static void
+flip_cr_context (struct frame *f)
+{
+ cairo_t *cr = FRAME_CR_ACTIVE_CONTEXT (f);
+
+ block_input ();
+ if (cr != FRAME_CR_CONTEXT (f))
+ {
+ cairo_destroy (cr);
+ FRAME_CR_ACTIVE_CONTEXT (f) = cairo_reference (FRAME_CR_CONTEXT (f));
+
+ }
+ unblock_input ();
+}
+
+
+static void
+evq_enqueue (union buffered_input_event *ev)
+{
+ struct event_queue_t *evq = &event_q;
+ if (evq->cap == 0)
+ {
+ evq->cap = 4;
+ evq->q = xmalloc (sizeof *evq->q * evq->cap);
+ }
+
+ if (evq->nr >= evq->cap)
+ {
+ evq->cap += evq->cap / 2;
+ evq->q = xrealloc (evq->q, sizeof *evq->q * evq->cap);
+ }
+
+ evq->q[evq->nr++] = *ev;
+ raise (SIGIO);
+}
+
+static int
+evq_flush (struct input_event *hold_quit)
+{
+ struct event_queue_t *evq = &event_q;
+ int i, n = evq->nr;
+ for (i = 0; i < n; i++)
+ kbd_buffer_store_buffered_event (&evq->q[i], hold_quit);
+ evq->nr = 0;
+ return n;
+}
+
+void
+mark_pgtkterm (void)
+{
+ struct event_queue_t *evq = &event_q;
+ int i, n = evq->nr;
+ for (i = 0; i < n; i++)
+ {
+ union buffered_input_event *ev = &evq->q[i];
+ mark_object (ev->ie.x);
+ mark_object (ev->ie.y);
+ mark_object (ev->ie.frame_or_window);
+ mark_object (ev->ie.arg);
+ }
+}
+
+char *
+get_keysym_name (int keysym)
+/* --------------------------------------------------------------------------
+ Called by keyboard.c. Not sure if the return val is important, except
+ that it be unique.
+ -------------------------------------------------------------------------- */
+{
+ static char value[16];
+ sprintf (value, "%d", keysym);
+ return value;
+}
+
+void
+frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
+/* --------------------------------------------------------------------------
+ Programmatically reposition mouse pointer in pixel coordinates
+ -------------------------------------------------------------------------- */
+{
+}
+
+/* Raise frame F. */
+
+static void
+pgtk_raise_frame (struct frame *f)
+{
+ /* This works only for non-child frames on X.
+ It does not work for child frames on X, and it does not work
+ on Wayland too. */
+ block_input ();
+ if (FRAME_VISIBLE_P (f))
+ gdk_window_raise (gtk_widget_get_window (FRAME_WIDGET (f)));
+ unblock_input ();
+}
+
+/* Lower frame F. */
+
+static void
+pgtk_lower_frame (struct frame *f)
+{
+ if (FRAME_VISIBLE_P (f))
+ {
+ block_input ();
+ gdk_window_lower (gtk_widget_get_window (FRAME_WIDGET (f)));
+ unblock_input ();
+ }
+}
+
+static void
+pgtk_frame_raise_lower (struct frame *f, bool raise_flag)
+{
+ if (raise_flag)
+ pgtk_raise_frame (f);
+ else
+ pgtk_lower_frame (f);
+}
+
+/* Free X resources of frame F. */
+
+void
+x_free_frame_resources (struct frame *f)
+{
+ struct pgtk_display_info *dpyinfo;
+ Mouse_HLInfo *hlinfo;
+
+ check_window_system (f);
+ dpyinfo = FRAME_DISPLAY_INFO (f);
+ hlinfo = MOUSE_HL_INFO (f);
+
+ block_input ();
+
+ free_frame_faces (f);
+
+ if (FRAME_X_OUTPUT (f)->scale_factor_atimer != NULL)
+ {
+ cancel_atimer (FRAME_X_OUTPUT (f)->scale_factor_atimer);
+ FRAME_X_OUTPUT (f)->scale_factor_atimer = NULL;
+ }
+
+#define CLEAR_IF_EQ(FIELD) \
+ do { if (f == dpyinfo->FIELD) dpyinfo->FIELD = 0; } while (false)
+
+ CLEAR_IF_EQ (x_focus_frame);
+ CLEAR_IF_EQ (highlight_frame);
+ CLEAR_IF_EQ (x_focus_event_frame);
+ CLEAR_IF_EQ (last_mouse_frame);
+ CLEAR_IF_EQ (last_mouse_motion_frame);
+ CLEAR_IF_EQ (last_mouse_glyph_frame);
+ CLEAR_IF_EQ (im.focused_frame);
+
+#undef CLEAR_IF_EQ
+
+ if (f == hlinfo->mouse_face_mouse_frame)
+ reset_mouse_highlight (hlinfo);
+
+ g_clear_object (&FRAME_X_OUTPUT (f)->text_cursor);
+ g_clear_object (&FRAME_X_OUTPUT (f)->nontext_cursor);
+ g_clear_object (&FRAME_X_OUTPUT (f)->modeline_cursor);
+ g_clear_object (&FRAME_X_OUTPUT (f)->hand_cursor);
+ g_clear_object (&FRAME_X_OUTPUT (f)->hourglass_cursor);
+ g_clear_object (&FRAME_X_OUTPUT (f)->horizontal_drag_cursor);
+ g_clear_object (&FRAME_X_OUTPUT (f)->vertical_drag_cursor);
+ g_clear_object (&FRAME_X_OUTPUT (f)->left_edge_cursor);
+ g_clear_object (&FRAME_X_OUTPUT (f)->right_edge_cursor);
+ g_clear_object (&FRAME_X_OUTPUT (f)->top_edge_cursor);
+ g_clear_object (&FRAME_X_OUTPUT (f)->bottom_edge_cursor);
+ g_clear_object (&FRAME_X_OUTPUT (f)->top_left_corner_cursor);
+ g_clear_object (&FRAME_X_OUTPUT (f)->top_right_corner_cursor);
+ g_clear_object (&FRAME_X_OUTPUT (f)->bottom_right_corner_cursor);
+ g_clear_object (&FRAME_X_OUTPUT (f)->bottom_left_corner_cursor);
+
+
+ if (FRAME_X_OUTPUT (f)->border_color_css_provider != NULL)
+ {
+ GtkStyleContext *ctxt = gtk_widget_get_style_context (FRAME_WIDGET (f));
+ GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider;
+ gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old));
+ g_object_unref (old);
+ FRAME_X_OUTPUT (f)->border_color_css_provider = NULL;
+ }
+
+ if (FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider != NULL)
+ {
+ GtkCssProvider *old =
+ FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider;
+ g_object_unref (old);
+ FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider = NULL;
+ }
+
+ if (FRAME_X_OUTPUT (f)->scrollbar_background_css_provider != NULL)
+ {
+ GtkCssProvider *old =
+ FRAME_X_OUTPUT (f)->scrollbar_background_css_provider;
+ g_object_unref (old);
+ FRAME_X_OUTPUT (f)->scrollbar_background_css_provider = NULL;
+ }
+
+ gtk_widget_destroy (FRAME_WIDGET (f));
+
+ if (FRAME_X_OUTPUT (f)->cr_surface_visible_bell != NULL)
+ {
+ cairo_surface_destroy (FRAME_X_OUTPUT (f)->cr_surface_visible_bell);
+ FRAME_X_OUTPUT (f)->cr_surface_visible_bell = NULL;
+ }
+
+ if (FRAME_X_OUTPUT (f)->atimer_visible_bell != NULL)
+ {
+ cancel_atimer (FRAME_X_OUTPUT (f)->atimer_visible_bell);
+ FRAME_X_OUTPUT (f)->atimer_visible_bell = NULL;
+ }
+
+ xfree (f->output_data.pgtk);
+ f->output_data.pgtk = NULL;
+
+ unblock_input ();
+}
+
+void
+x_destroy_window (struct frame *f)
+/* --------------------------------------------------------------------------
+ External: Delete the window
+ -------------------------------------------------------------------------- */
+{
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+
+ check_window_system (f);
+ if (dpyinfo->gdpy != NULL)
+ x_free_frame_resources (f);
+
+ dpyinfo->reference_count--;
+}
+
+/* Calculate the absolute position in frame F
+ from its current recorded position values and gravity. */
+
+static void
+x_calc_absolute_position (struct frame *f)
+{
+ int flags = f->size_hint_flags;
+ struct frame *p = FRAME_PARENT_FRAME (f);
+
+ /* We have nothing to do if the current position
+ is already for the top-left corner. */
+ if (! ((flags & XNegative) || (flags & YNegative)))
+ return;
+
+ /* Treat negative positions as relative to the leftmost bottommost
+ position that fits on the screen. */
+ if ((flags & XNegative) && (f->left_pos <= 0))
+ {
+ int width = FRAME_PIXEL_WIDTH (f);
+
+ /* A frame that has been visible at least once should have outer
+ edges. */
+ if (f->output_data.pgtk->has_been_visible && !p)
+ {
+ Lisp_Object frame;
+ Lisp_Object edges = Qnil;
+
+ XSETFRAME (frame, f);
+ edges = Fpgtk_frame_edges (frame, Qouter_edges);
+ if (!NILP (edges))
+ width = (XFIXNUM (Fnth (make_fixnum (2), edges))
+ - XFIXNUM (Fnth (make_fixnum (0), edges)));
+ }
+
+ if (p)
+ f->left_pos = (FRAME_PIXEL_WIDTH (p) - width - 2 * f->border_width
+ + f->left_pos);
+ else
+ f->left_pos = (x_display_pixel_width (FRAME_DISPLAY_INFO (f))
+ - width + f->left_pos);
+
+ }
+
+ if ((flags & YNegative) && (f->top_pos <= 0))
+ {
+ int height = FRAME_PIXEL_HEIGHT (f);
+
+ if (f->output_data.pgtk->has_been_visible && !p)
+ {
+ Lisp_Object frame;
+ Lisp_Object edges = Qnil;
+
+ XSETFRAME (frame, f);
+ if (NILP (edges))
+ edges = Fpgtk_frame_edges (frame, Qouter_edges);
+ if (!NILP (edges))
+ height = (XFIXNUM (Fnth (make_fixnum (3), edges))
+ - XFIXNUM (Fnth (make_fixnum (1), edges)));
+ }
+
+ if (p)
+ f->top_pos = (FRAME_PIXEL_HEIGHT (p) - height - 2 * f->border_width
+ + f->top_pos);
+ else
+ f->top_pos = (x_display_pixel_height (FRAME_DISPLAY_INFO (f))
+ - height + f->top_pos);
+ }
+
+ /* The left_pos and top_pos
+ are now relative to the top and left screen edges,
+ so the flags should correspond. */
+ f->size_hint_flags &= ~ (XNegative | YNegative);
+}
+
+/* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
+ to really change the position, and 0 when calling from
+ x_make_frame_visible (in that case, XOFF and YOFF are the current
+ position values). It is -1 when calling from x_set_frame_parameters,
+ which means, do adjust for borders but don't change the gravity. */
+
+static void
+x_set_offset (struct frame *f, int xoff, int yoff, int change_gravity)
+/* --------------------------------------------------------------------------
+ External: Position the window
+ -------------------------------------------------------------------------- */
+{
+ int modified_top, modified_left;
+
+ if (change_gravity > 0)
+ {
+ f->top_pos = yoff;
+ f->left_pos = xoff;
+ f->size_hint_flags &= ~ (XNegative | YNegative);
+ if (xoff < 0)
+ f->size_hint_flags |= XNegative;
+ if (yoff < 0)
+ f->size_hint_flags |= YNegative;
+ f->win_gravity = NorthWestGravity;
+ }
+
+ x_calc_absolute_position (f);
+
+ block_input ();
+ x_wm_set_size_hint (f, 0, false);
+
+ if (x_gtk_use_window_move)
+ {
+ if (change_gravity != 0)
+ {
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ f->left_pos, f->top_pos);
+ }
+ else
+ {
+ GtkWidget *fixed = FRAME_GTK_WIDGET (f);
+ GtkWidget *parent = gtk_widget_get_parent (fixed);
+ gtk_fixed_move (GTK_FIXED (parent), fixed,
+ f->left_pos, f->top_pos);
+ }
+ }
+ unblock_input ();
+ return;
+ }
+
+ modified_left = f->left_pos;
+ modified_top = f->top_pos;
+
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ modified_left, modified_top);
+ }
+ else
+ {
+ GtkWidget *fixed = FRAME_GTK_WIDGET (f);
+ GtkWidget *parent = gtk_widget_get_parent (fixed);
+ gtk_fixed_move (GTK_FIXED (parent), fixed,
+ modified_left, modified_top);
+ }
+
+ unblock_input ();
+}
+
+static void
+pgtk_set_window_size (struct frame *f, bool change_gravity,
+ int width, int height)
+/* --------------------------------------------------------------------------
+ Adjust window pixel size based on given character grid size
+ Impl is a bit more complex than other terms, need to do some
+ internal clipping.
+ -------------------------------------------------------------------------- */
+{
+ int pixelwidth, pixelheight;
+
+ block_input ();
+
+ gtk_widget_get_size_request (FRAME_GTK_WIDGET (f), &pixelwidth,
+ &pixelheight);
+
+#if 0
+ if (pixelwise)
+ {
+ pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
+ pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
+ }
+ else
+ {
+ pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
+ pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
+ }
+#else
+ pixelwidth = width;
+ pixelheight = height;
+#endif
+
+#if 0
+ frame_size_history_add
+ (f, Qx_set_window_size_1, width, height,
+ list5 (Fcons (make_fixnum (pixelwidth), make_fixnum (pixelheight)),
+ Fcons (make_fixnum (pixelwidth), make_fixnum (pixelheight)),
+ make_fixnum (f->border_width),
+ make_fixnum (FRAME_PGTK_TITLEBAR_HEIGHT (f)),
+ make_fixnum (FRAME_TOOLBAR_HEIGHT (f))));
+#endif
+
+ for (GtkWidget * w = FRAME_GTK_WIDGET (f); w != NULL;
+ w = gtk_widget_get_parent (w))
+ {
+ gint wd, hi;
+ gtk_widget_get_size_request (w, &wd, &hi);
+ }
+
+ f->output_data.pgtk->preferred_width = pixelwidth;
+ f->output_data.pgtk->preferred_height = pixelheight;
+ x_wm_set_size_hint (f, 0, 0);
+ xg_frame_set_char_size (f, pixelwidth, pixelheight);
+ gtk_widget_queue_resize (FRAME_WIDGET (f));
+
+ unblock_input ();
+}
+
+void
+pgtk_iconify_frame (struct frame *f)
+/* --------------------------------------------------------------------------
+ External: Iconify window
+ -------------------------------------------------------------------------- */
+{
+ /* Don't keep the highlight on an invisible frame. */
+ if (FRAME_DISPLAY_INFO (f)->highlight_frame == f)
+ FRAME_DISPLAY_INFO (f)->highlight_frame = 0;
+
+ if (FRAME_ICONIFIED_P (f))
+ return;
+
+ block_input ();
+
+#if 0
+ x_set_bitmap_icon (f);
+#endif
+
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ if (!FRAME_VISIBLE_P (f))
+ gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
+
+ gtk_window_iconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
+ SET_FRAME_VISIBLE (f, 0);
+ SET_FRAME_ICONIFIED (f, true);
+ unblock_input ();
+ return;
+ }
+
+ /* Make sure the X server knows where the window should be positioned,
+ in case the user deiconifies with the window manager. */
+ if (!FRAME_VISIBLE_P (f) && !FRAME_ICONIFIED_P (f)
+#if 0
+ && !FRAME_X_EMBEDDED_P (f)
+#endif
+ )
+ x_set_offset (f, f->left_pos, f->top_pos, 0);
+
+#if 0
+ if (!FRAME_VISIBLE_P (f))
+ {
+ /* If the frame was withdrawn, before, we must map it. */
+ XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+ }
+#endif
+
+ SET_FRAME_ICONIFIED (f, true);
+ SET_FRAME_VISIBLE (f, 0);
+
+ unblock_input ();
+}
+
+static gboolean
+pgtk_make_frame_visible_wait_for_map_event_cb (GtkWidget * widget,
+ GdkEventAny * event,
+ gpointer user_data)
+{
+ int *foundptr = user_data;
+ *foundptr = 1;
+ return FALSE;
+}
+
+static gboolean
+pgtk_make_frame_visible_wait_for_map_event_timeout (gpointer user_data)
+{
+ int *timedoutptr = user_data;
+ *timedoutptr = 1;
+ return FALSE;
+}
+
+static void
+pgtk_wait_for_map_event (struct frame *f, bool multiple_times)
+{
+ if (FLOATP (Vpgtk_wait_for_event_timeout))
+ {
+ guint msec =
+ (guint) (XFLOAT_DATA (Vpgtk_wait_for_event_timeout) * 1000);
+ int found = 0;
+ int timed_out = 0;
+ gulong id =
+ g_signal_connect (FRAME_WIDGET (f), "map-event",
+ G_CALLBACK
+ (pgtk_make_frame_visible_wait_for_map_event_cb),
+ &found);
+ guint src =
+ g_timeout_add (msec,
+ pgtk_make_frame_visible_wait_for_map_event_timeout,
+ &timed_out);
+
+ if (!multiple_times)
+ {
+ while (!found && !timed_out)
+ gtk_main_iteration ();
+ }
+ else
+ {
+ while (!timed_out)
+ gtk_main_iteration ();
+ }
+
+ g_signal_handler_disconnect (FRAME_WIDGET (f), id);
+ if (!timed_out)
+ g_source_remove (src);
+ }
+}
+
+void
+pgtk_make_frame_visible (struct frame *f)
+/* --------------------------------------------------------------------------
+ External: Show the window (X11 semantics)
+ -------------------------------------------------------------------------- */
+{
+ GtkWidget *win = FRAME_GTK_OUTER_WIDGET (f);
+
+ if (!FRAME_VISIBLE_P (f))
+ {
+ gtk_widget_show (FRAME_WIDGET (f));
+ if (win)
+ gtk_window_deiconify (GTK_WINDOW (win));
+
+ pgtk_wait_for_map_event (f, false);
+ }
+}
+
+
+void
+pgtk_make_frame_invisible (struct frame *f)
+/* --------------------------------------------------------------------------
+ External: Hide the window (X11 semantics)
+ -------------------------------------------------------------------------- */
+{
+ gtk_widget_hide (FRAME_WIDGET (f));
+
+ /* Map events are emitted many times, and
+ * map_event() do SET_FRAME_VISIBLE(f, 1).
+ * I expect visible = 0, so process those map events here and
+ * SET_FRAME_VISIBLE(f, 0) after that.
+ */
+ pgtk_wait_for_map_event (f, true);
+
+ SET_FRAME_VISIBLE (f, 0);
+ SET_FRAME_ICONIFIED (f, false);
+}
+
+static void
+pgtk_make_frame_visible_invisible (struct frame *f, bool visible)
+{
+ if (visible)
+ pgtk_make_frame_visible (f);
+ else
+ pgtk_make_frame_invisible (f);
+}
+
+static Lisp_Object
+pgtk_new_font (struct frame *f, Lisp_Object font_object, int fontset)
+{
+ struct font *font = XFONT_OBJECT (font_object);
+ int font_ascent, font_descent;
+
+ if (fontset < 0)
+ fontset = fontset_from_font (font_object);
+ FRAME_FONTSET (f) = fontset;
+
+ if (FRAME_FONT (f) == font)
+ {
+ /* This font is already set in frame F. There's nothing more to
+ do. */
+ return font_object;
+ }
+
+ FRAME_FONT (f) = font;
+
+ FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
+ FRAME_COLUMN_WIDTH (f) = font->average_width;
+ get_font_ascent_descent (font, &font_ascent, &font_descent);
+ FRAME_LINE_HEIGHT (f) = font_ascent + font_descent;
+
+ /* We could use a more elaborate calculation here. */
+ FRAME_TAB_BAR_HEIGHT (f) = FRAME_TAB_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
+
+ /* Compute the scroll bar width in character columns. */
+ if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
+ {
+ int wid = FRAME_COLUMN_WIDTH (f);
+ FRAME_CONFIG_SCROLL_BAR_COLS (f)
+ = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid - 1) / wid;
+ }
+ else
+ {
+ int wid = FRAME_COLUMN_WIDTH (f);
+ FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
+ }
+
+ /* Compute the scroll bar height in character lines. */
+ if (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) > 0)
+ {
+ int height = FRAME_LINE_HEIGHT (f);
+ FRAME_CONFIG_SCROLL_BAR_LINES (f)
+ = (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) + height - 1) / height;
+ }
+ else
+ {
+ int height = FRAME_LINE_HEIGHT (f);
+ FRAME_CONFIG_SCROLL_BAR_LINES (f) = (14 + height - 1) / height;
+ }
+
+ /* Now make the frame display the given font. */
+ if (FRAME_GTK_WIDGET (f) != NULL)
+ adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
+ FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
+ false, Qfont);
+
+ return font_object;
+}
+
+int
+x_display_pixel_height (struct pgtk_display_info *dpyinfo)
+{
+ GdkDisplay *gdpy = dpyinfo->gdpy;
+ GdkScreen *gscr = gdk_display_get_default_screen (gdpy);
+ return gdk_screen_get_height (gscr);
+}
+
+int
+x_display_pixel_width (struct pgtk_display_info *dpyinfo)
+{
+ GdkDisplay *gdpy = dpyinfo->gdpy;
+ GdkScreen *gscr = gdk_display_get_default_screen (gdpy);
+ return gdk_screen_get_width (gscr);
+}
+
+void
+x_set_parent_frame (struct frame *f, Lisp_Object new_value,
+ Lisp_Object old_value)
+/* --------------------------------------------------------------------------
+ Set frame F's `parent-frame' parameter. If non-nil, make F a child
+ frame of the frame specified by that parameter. Technically, this
+ makes F's window-system window a child window of the parent frame's
+ window-system window. If nil, make F's window-system window a
+ top-level window--a child of its display's root window.
+
+ A child frame's `left' and `top' parameters specify positions
+ relative to the top-left corner of its parent frame's native
+ rectangle. On macOS moving a parent frame moves all its child
+ frames too, keeping their position relative to the parent
+ unaltered. When a parent frame is iconified or made invisible, its
+ child frames are made invisible. When a parent frame is deleted,
+ its child frames are deleted too.
+
+ Whether a child frame has a tool bar may be window-system or window
+ manager dependent. It's advisable to disable it via the frame
+ parameter settings.
+
+ Some window managers may not honor this parameter.
+ -------------------------------------------------------------------------- */
+{
+ struct frame *p = NULL;
+
+ if (!NILP (new_value)
+ && (!FRAMEP (new_value)
+ || !FRAME_LIVE_P (p = XFRAME (new_value))
+ || !FRAME_PGTK_P (p)))
+ {
+ store_frame_param (f, Qparent_frame, old_value);
+ error ("Invalid specification of `parent-frame'");
+ }
+
+ if (p != FRAME_PARENT_FRAME (f))
+ {
+ block_input ();
+
+ if (p != NULL)
+ {
+ if (FRAME_DISPLAY_INFO (f) != FRAME_DISPLAY_INFO (p))
+ error ("Cross display reparent.");
+ }
+
+ GtkWidget *fixed = FRAME_GTK_WIDGET (f);
+
+ GtkAllocation alloc;
+ gtk_widget_get_allocation (fixed, &alloc);
+ g_object_ref (fixed);
+
+ /* Remember the css provider, and restore it later. */
+ GtkCssProvider *provider = FRAME_X_OUTPUT (f)->border_color_css_provider;
+ FRAME_X_OUTPUT (f)->border_color_css_provider = NULL;
+ {
+ GtkStyleContext *ctxt = gtk_widget_get_style_context (FRAME_WIDGET (f));
+ if (provider != NULL)
+ gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (provider));
+ }
+
+ {
+ GtkWidget *whbox_of_f = gtk_widget_get_parent (fixed);
+ /* Here, unhighlight can be called and may change border_color_css_provider. */
+ gtk_container_remove (GTK_CONTAINER (whbox_of_f), fixed);
+
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
+ FRAME_GTK_OUTER_WIDGET (f) = NULL;
+ FRAME_OUTPUT_DATA (f)->vbox_widget = NULL;
+ FRAME_OUTPUT_DATA (f)->hbox_widget = NULL;
+ FRAME_OUTPUT_DATA (f)->menubar_widget = NULL;
+ FRAME_OUTPUT_DATA (f)->toolbar_widget = NULL;
+ FRAME_OUTPUT_DATA (f)->ttip_widget = NULL;
+ FRAME_OUTPUT_DATA (f)->ttip_lbl = NULL;
+ FRAME_OUTPUT_DATA (f)->ttip_window = NULL;
+ }
+ }
+
+ if (p == NULL)
+ {
+ xg_create_frame_outer_widgets (f);
+ pgtk_set_event_handler (f);
+ gtk_box_pack_start (GTK_BOX (f->output_data.pgtk->hbox_widget), fixed, TRUE, TRUE, 0);
+ f->output_data.pgtk->preferred_width = alloc.width;
+ f->output_data.pgtk->preferred_height = alloc.height;
+ x_wm_set_size_hint (f, 0, 0);
+ xg_frame_set_char_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, alloc.width),
+ FRAME_PIXEL_TO_TEXT_HEIGHT (f, alloc.height));
+ gtk_widget_queue_resize (FRAME_WIDGET (f));
+ gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
+ }
+ else
+ {
+ GtkWidget *fixed_of_p = FRAME_GTK_WIDGET (p);
+ gtk_fixed_put (GTK_FIXED (fixed_of_p), fixed, f->left_pos, f->top_pos);
+ gtk_widget_set_size_request (fixed, alloc.width, alloc.height);
+ gtk_widget_show_all (fixed);
+ }
+
+ /* Restore css provider. */
+ GtkStyleContext *ctxt = gtk_widget_get_style_context (FRAME_WIDGET (f));
+ GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider;
+ FRAME_X_OUTPUT (f)->border_color_css_provider = provider;
+ if (provider != NULL)
+ {
+ gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (provider),
+ GTK_STYLE_PROVIDER_PRIORITY_USER);
+ }
+ if (old != NULL)
+ {
+ gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old));
+ g_object_unref(old);
+ }
+
+ g_object_unref (fixed);
+
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ if (EQ (x_gtk_resize_child_frames, Qresize_mode))
+ gtk_container_set_resize_mode
+ (GTK_CONTAINER (FRAME_GTK_OUTER_WIDGET (f)),
+ p ? GTK_RESIZE_IMMEDIATE : GTK_RESIZE_QUEUE);
+ }
+
+ unblock_input ();
+
+ fset_parent_frame (f, new_value);
+ }
+}
+
+
+void
+x_set_no_focus_on_map (struct frame *f, Lisp_Object new_value,
+ Lisp_Object old_value)
+/* Set frame F's `no-focus-on-map' parameter which, if non-nil, means
+ * that F's window-system window does not want to receive input focus
+ * when it is mapped. (A frame's window is mapped when the frame is
+ * displayed for the first time and when the frame changes its state
+ * from `iconified' or `invisible' to `visible'.)
+ *
+ * Some window managers may not honor this parameter. */
+{
+ /* doesn't work on wayland. */
+
+ if (!EQ (new_value, old_value))
+ {
+ xg_set_no_focus_on_map (f, new_value);
+ FRAME_NO_FOCUS_ON_MAP (f) = !NILP (new_value);
+ }
+}
+
+void
+x_set_no_accept_focus (struct frame *f, Lisp_Object new_value,
+ Lisp_Object old_value)
+/* Set frame F's `no-accept-focus' parameter which, if non-nil, hints
+ * that F's window-system window does not want to receive input focus
+ * via mouse clicks or by moving the mouse into it.
+ *
+ * If non-nil, this may have the unwanted side-effect that a user cannot
+ * scroll a non-selected frame with the mouse.
+ *
+ * Some window managers may not honor this parameter. */
+{
+ /* doesn't work on wayland. */
+
+ xg_set_no_accept_focus (f, new_value);
+ FRAME_NO_ACCEPT_FOCUS (f) = !NILP (new_value);
+}
+
+void
+x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
+/* Set frame F's `z-group' parameter. If `above', F's window-system
+ window is displayed above all windows that do not have the `above'
+ property set. If nil, F's window is shown below all windows that
+ have the `above' property set and above all windows that have the
+ `below' property set. If `below', F's window is displayed below
+ all windows that do.
+
+ Some window managers may not honor this parameter. */
+{
+ /* doesn't work on wayland. */
+
+ if (!FRAME_GTK_OUTER_WIDGET (f))
+ return;
+
+ if (NILP (new_value))
+ {
+ gtk_window_set_keep_above (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ FALSE);
+ gtk_window_set_keep_below (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ FALSE);
+ FRAME_Z_GROUP (f) = z_group_none;
+ }
+ else if (EQ (new_value, Qabove))
+ {
+ gtk_window_set_keep_above (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ TRUE);
+ gtk_window_set_keep_below (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ FALSE);
+ FRAME_Z_GROUP (f) = z_group_above;
+ }
+ else if (EQ (new_value, Qabove_suspended))
+ {
+ gtk_window_set_keep_above (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ FALSE);
+ FRAME_Z_GROUP (f) = z_group_above_suspended;
+ }
+ else if (EQ (new_value, Qbelow))
+ {
+ gtk_window_set_keep_above (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ FALSE);
+ gtk_window_set_keep_below (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ TRUE);
+ FRAME_Z_GROUP (f) = z_group_below;
+ }
+ else
+ error ("Invalid z-group specification");
+}
+
+static void
+pgtk_initialize_display_info (struct pgtk_display_info *dpyinfo)
+/* --------------------------------------------------------------------------
+ Initialize global info and storage for display.
+ -------------------------------------------------------------------------- */
+{
+ dpyinfo->resx = 96;
+ dpyinfo->resy = 96;
+ dpyinfo->color_p = 1;
+ dpyinfo->n_planes = 32;
+ dpyinfo->root_window = 42; /* a placeholder.. */
+ dpyinfo->highlight_frame = dpyinfo->x_focus_frame = NULL;
+ dpyinfo->n_fonts = 0;
+ dpyinfo->smallest_font_height = 1;
+ dpyinfo->smallest_char_width = 1;
+
+ reset_mouse_highlight (&dpyinfo->mouse_highlight);
+}
+
+/* Set S->gc to a suitable GC for drawing glyph string S in cursor
+ face. */
+
+static void
+x_set_cursor_gc (struct glyph_string *s)
+{
+ if (s->font == FRAME_FONT (s->f)
+ && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
+ && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f) && !s->cmp)
+ s->xgcv = FRAME_X_OUTPUT (s->f)->cursor_xgcv;
+ else
+ {
+ /* Cursor on non-default face: must merge. */
+ Emacs_GC xgcv;
+
+ xgcv.background = FRAME_X_OUTPUT (s->f)->cursor_color;
+ xgcv.foreground = s->face->background;
+
+ /* If the glyph would be invisible, try a different foreground. */
+ if (xgcv.foreground == xgcv.background)
+ xgcv.foreground = s->face->foreground;
+ if (xgcv.foreground == xgcv.background)
+ xgcv.foreground = FRAME_X_OUTPUT (s->f)->cursor_foreground_color;
+ if (xgcv.foreground == xgcv.background)
+ xgcv.foreground = s->face->foreground;
+
+ /* Make sure the cursor is distinct from text in this face. */
+ if (xgcv.background == s->face->background
+ && xgcv.foreground == s->face->foreground)
+ {
+ xgcv.background = s->face->foreground;
+ xgcv.foreground = s->face->background;
+ }
+
+ s->xgcv = xgcv;
+ }
+}
+
+
+/* Set up S->gc of glyph string S for drawing text in mouse face. */
+
+static void
+x_set_mouse_face_gc (struct glyph_string *s)
+{
+ prepare_face_for_display (s->f, s->face);
+
+ if (s->font == s->face->font)
+ {
+ s->xgcv.foreground = s->face->foreground;
+ s->xgcv.background = s->face->background;
+ }
+ else
+ {
+ /* Otherwise construct scratch_cursor_gc with values from FACE
+ except for FONT. */
+ Emacs_GC xgcv;
+
+ xgcv.background = s->face->background;
+ xgcv.foreground = s->face->foreground;
+
+ s->xgcv = xgcv;
+
+ }
+}
+
+
+/* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
+ Faces to use in the mode line have already been computed when the
+ matrix was built, so there isn't much to do, here. */
+
+static void
+x_set_mode_line_face_gc (struct glyph_string *s)
+{
+ s->xgcv.foreground = s->face->foreground;
+ s->xgcv.background = s->face->background;
+}
+
+
+/* Set S->gc of glyph string S for drawing that glyph string. Set
+ S->stippled_p to a non-zero value if the face of S has a stipple
+ pattern. */
+
+static void
+x_set_glyph_string_gc (struct glyph_string *s)
+{
+ prepare_face_for_display (s->f, s->face);
+
+ if (s->hl == DRAW_NORMAL_TEXT)
+ {
+ s->xgcv.foreground = s->face->foreground;
+ s->xgcv.background = s->face->background;
+ s->stippled_p = s->face->stipple != 0;
+ }
+ else if (s->hl == DRAW_INVERSE_VIDEO)
+ {
+ x_set_mode_line_face_gc (s);
+ s->stippled_p = s->face->stipple != 0;
+ }
+ else if (s->hl == DRAW_CURSOR)
+ {
+ x_set_cursor_gc (s);
+ s->stippled_p = false;
+ }
+ else if (s->hl == DRAW_MOUSE_FACE)
+ {
+ x_set_mouse_face_gc (s);
+ s->stippled_p = s->face->stipple != 0;
+ }
+ else if (s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
+ {
+ s->xgcv.foreground = s->face->foreground;
+ s->xgcv.background = s->face->background;
+ s->stippled_p = s->face->stipple != 0;
+ }
+ else
+ emacs_abort ();
+}
+
+
+/* Set clipping for output of glyph string S. S may be part of a mode
+ line or menu if we don't have X toolkit support. */
+
+static void
+x_set_glyph_string_clipping (struct glyph_string *s, cairo_t * cr)
+{
+ XRectangle r[2];
+ int n = get_glyph_string_clip_rects (s, r, 2);
+
+ if (n > 0)
+ {
+ for (int i = 0; i < n; i++)
+ {
+ cairo_rectangle (cr, r[i].x, r[i].y, r[i].width, r[i].height);
+ }
+ cairo_clip (cr);
+ }
+}
+
+
+/* Set SRC's clipping for output of glyph string DST. This is called
+ when we are drawing DST's left_overhang or right_overhang only in
+ the area of SRC. */
+
+static void
+x_set_glyph_string_clipping_exactly (struct glyph_string *src,
+ struct glyph_string *dst, cairo_t * cr)
+{
+ dst->clip[0].x = src->x;
+ dst->clip[0].y = src->y;
+ dst->clip[0].width = src->width;
+ dst->clip[0].height = src->height;
+ dst->num_clips = 1;
+
+ cairo_rectangle (cr, src->x, src->y, src->width, src->height);
+ cairo_clip (cr);
+}
+
+
+/* RIF:
+ Compute left and right overhang of glyph string S. */
+
+static void
+pgtk_compute_glyph_string_overhangs (struct glyph_string *s)
+{
+ if (s->cmp == NULL
+ && (s->first_glyph->type == CHAR_GLYPH
+ || s->first_glyph->type == COMPOSITE_GLYPH))
+ {
+ struct font_metrics metrics;
+
+ if (s->first_glyph->type == CHAR_GLYPH)
+ {
+ unsigned *code = alloca (sizeof (unsigned) * s->nchars);
+ struct font *font = s->font;
+ int i;
+
+ for (i = 0; i < s->nchars; i++)
+ code[i] = s->char2b[i];
+ font->driver->text_extents (font, code, s->nchars, &metrics);
+ }
+ else
+ {
+ Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
+
+ composition_gstring_width (gstring, s->cmp_from, s->cmp_to,
+ &metrics);
+ }
+ s->right_overhang = (metrics.rbearing > metrics.width
+ ? metrics.rbearing - metrics.width : 0);
+ s->left_overhang = metrics.lbearing < 0 ? -metrics.lbearing : 0;
+ }
+ else if (s->cmp)
+ {
+ s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
+ s->left_overhang = -s->cmp->lbearing;
+ }
+}
+
+
+/* Fill rectangle X, Y, W, H with background color of glyph string S. */
+
+static void
+x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
+{
+ pgtk_fill_rectangle (s->f, s->xgcv.background, x, y, w, h);
+}
+
+
+static void
+fill_background_by_face (struct frame *f, struct face *face, int x, int y,
+ int width, int height)
+{
+ cairo_t *cr = pgtk_begin_cr_clip (f);
+
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_clip (cr);
+
+ double r = ((face->background >> 16) & 0xff) / 255.0;
+ double g = ((face->background >> 8) & 0xff) / 255.0;
+ double b = ((face->background >> 0) & 0xff) / 255.0;
+ cairo_set_source_rgb (cr, r, g, b);
+ cairo_paint (cr);
+
+ if (face->stipple != 0)
+ {
+ cairo_pattern_t *mask =
+ FRAME_DISPLAY_INFO (f)->bitmaps[face->stipple - 1].pattern;
+
+ double r = ((face->foreground >> 16) & 0xff) / 255.0;
+ double g = ((face->foreground >> 8) & 0xff) / 255.0;
+ double b = ((face->foreground >> 0) & 0xff) / 255.0;
+ cairo_set_source_rgb (cr, r, g, b);
+ cairo_mask (cr, mask);
+ }
+
+ pgtk_end_cr_clip (f);
+}
+
+static void
+fill_background (struct glyph_string *s, int x, int y, int width, int height)
+{
+ fill_background_by_face (s->f, s->face, x, y, width, height);
+}
+
+/* Draw the background of glyph_string S. If S->background_filled_p
+ is non-zero don't draw it. FORCE_P non-zero means draw the
+ background even if it wouldn't be drawn normally. This is used
+ when a string preceding S draws into the background of S, or S
+ contains the first component of a composition. */
+
+static void
+x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
+{
+ /* Nothing to do if background has already been drawn or if it
+ shouldn't be drawn in the first place. */
+ if (!s->background_filled_p)
+ {
+ int box_line_width = max (s->face->box_horizontal_line_width, 0);
+
+ if (s->stippled_p)
+ {
+ /* Fill background with a stipple pattern. */
+
+ fill_background (s,
+ s->x, s->y + box_line_width,
+ s->background_width,
+ s->height - 2 * box_line_width);
+ s->background_filled_p = true;
+ }
+ else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
+ /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
+ font dimensions, since the actual glyphs might be
+ much smaller. So in that case we always clear the
+ rectangle with background color. */
+ || FONT_TOO_HIGH (s->font)
+ || s->font_not_found_p
+ || s->extends_to_end_of_line_p || force_p)
+ {
+ x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
+ s->background_width,
+ s->height - 2 * box_line_width);
+ s->background_filled_p = true;
+ }
+ }
+}
+
+
+static void
+pgtk_draw_rectangle (struct frame *f, unsigned long color, int x, int y,
+ int width, int height)
+{
+ cairo_t *cr;
+
+ cr = pgtk_begin_cr_clip (f);
+ pgtk_set_cr_source_with_color (f, color);
+ cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
+ cairo_set_line_width (cr, 1);
+ cairo_stroke (cr);
+ pgtk_end_cr_clip (f);
+}
+
+/* Draw the foreground of glyph string S. */
+
+static void
+x_draw_glyph_string_foreground (struct glyph_string *s)
+{
+ int i, x;
+
+ /* If first glyph of S has a left box line, start drawing the text
+ of S to the right of that box line. */
+ if (s->face->box != FACE_NO_BOX && s->first_glyph->left_box_line_p)
+ x = s->x + max (s->face->box_vertical_line_width, 0);
+ else
+ x = s->x;
+
+ /* Draw characters of S as rectangles if S's font could not be
+ loaded. */
+ if (s->font_not_found_p)
+ {
+ for (i = 0; i < s->nchars; ++i)
+ {
+ struct glyph *g = s->first_glyph + i;
+ pgtk_draw_rectangle (s->f,
+ s->face->foreground, x, s->y,
+ g->pixel_width - 1, s->height - 1);
+ x += g->pixel_width;
+ }
+ }
+ else
+ {
+ struct font *font = s->font;
+ int boff = font->baseline_offset;
+ int y;
+
+ if (font->vertical_centering)
+ boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
+
+ y = s->ybase - boff;
+ if (s->for_overlaps || (s->background_filled_p && s->hl != DRAW_CURSOR))
+ font->driver->draw (s, 0, s->nchars, x, y, false);
+ else
+ font->driver->draw (s, 0, s->nchars, x, y, true);
+ if (s->face->overstrike)
+ font->driver->draw (s, 0, s->nchars, x + 1, y, false);
+ }
+}
+
+/* Draw the foreground of composite glyph string S. */
+
+static void
+x_draw_composite_glyph_string_foreground (struct glyph_string *s)
+{
+ int i, j, x;
+ struct font *font = s->font;
+
+ /* If first glyph of S has a left box line, start drawing the text
+ of S to the right of that box line. */
+ if (s->face && s->face->box != FACE_NO_BOX
+ && s->first_glyph->left_box_line_p)
+ x = s->x + max (s->face->box_vertical_line_width, 0);
+ else
+ x = s->x;
+
+ /* S is a glyph string for a composition. S->cmp_from is the index
+ of the first character drawn for glyphs of this composition.
+ S->cmp_from == 0 means we are drawing the very first character of
+ this composition. */
+
+ /* Draw a rectangle for the composition if the font for the very
+ first character of the composition could not be loaded. */
+ if (s->font_not_found_p)
+ {
+ if (s->cmp_from == 0)
+ pgtk_draw_rectangle (s->f, s->face->foreground, x, s->y,
+ s->width - 1, s->height - 1);
+ }
+ else if (!s->first_glyph->u.cmp.automatic)
+ {
+ int y = s->ybase;
+
+ for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
+ /* TAB in a composition means display glyphs with padding
+ space on the left or right. */
+ if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
+ {
+ int xx = x + s->cmp->offsets[j * 2];
+ int yy = y - s->cmp->offsets[j * 2 + 1];
+
+ font->driver->draw (s, j, j + 1, xx, yy, false);
+ if (s->face->overstrike)
+ font->driver->draw (s, j, j + 1, xx + 1, yy, false);
+ }
+ }
+ else
+ {
+ Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
+ Lisp_Object glyph;
+ int y = s->ybase;
+ int width = 0;
+
+ for (i = j = s->cmp_from; i < s->cmp_to; i++)
+ {
+ glyph = LGSTRING_GLYPH (gstring, i);
+ if (NILP (LGLYPH_ADJUSTMENT (glyph)))
+ width += LGLYPH_WIDTH (glyph);
+ else
+ {
+ int xoff, yoff, wadjust;
+
+ if (j < i)
+ {
+ font->driver->draw (s, j, i, x, y, false);
+ if (s->face->overstrike)
+ font->driver->draw (s, j, i, x + 1, y, false);
+ x += width;
+ }
+ xoff = LGLYPH_XOFF (glyph);
+ yoff = LGLYPH_YOFF (glyph);
+ wadjust = LGLYPH_WADJUST (glyph);
+ font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
+ if (s->face->overstrike)
+ font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
+ false);
+ x += wadjust;
+ j = i + 1;
+ width = 0;
+ }
+ }
+ if (j < i)
+ {
+ font->driver->draw (s, j, i, x, y, false);
+ if (s->face->overstrike)
+ font->driver->draw (s, j, i, x + 1, y, false);
+ }
+ }
+}
+
+
+/* Draw the foreground of glyph string S for glyphless characters. */
+
+static void
+x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
+{
+ struct glyph *glyph = s->first_glyph;
+ unsigned char2b[8];
+ int x, i, j;
+
+ /* If first glyph of S has a left box line, start drawing the text
+ of S to the right of that box line. */
+ if (s->face && s->face->box != FACE_NO_BOX
+ && s->first_glyph->left_box_line_p)
+ x = s->x + max (s->face->box_vertical_line_width, 0);
+ else
+ x = s->x;
+
+ s->char2b = char2b;
+
+ for (i = 0; i < s->nchars; i++, glyph++)
+ {
+#ifdef GCC_LINT
+ enum
+ { PACIFY_GCC_BUG_81401 = 1 };
+#else
+ enum
+ { PACIFY_GCC_BUG_81401 = 0 };
+#endif
+ char buf[7 + PACIFY_GCC_BUG_81401];
+ char *str = NULL;
+ int len = glyph->u.glyphless.len;
+
+ if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
+ {
+ if (len > 0
+ && CHAR_TABLE_P (Vglyphless_char_display)
+ &&
+ (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
+ >= 1))
+ {
+ Lisp_Object acronym
+ = (!glyph->u.glyphless.for_no_font
+ ? CHAR_TABLE_REF (Vglyphless_char_display,
+ glyph->u.glyphless.ch)
+ : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
+ if (STRINGP (acronym))
+ str = SSDATA (acronym);
+ }
+ }
+ else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
+ {
+ unsigned int ch = glyph->u.glyphless.ch;
+ eassume (ch <= MAX_CHAR);
+ sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch);
+ str = buf;
+ }
+
+ if (str)
+ {
+ int upper_len = (len + 1) / 2;
+
+ /* It is assured that all LEN characters in STR is ASCII. */
+ for (j = 0; j < len; j++)
+ char2b[j] =
+ s->font->driver->encode_char (s->font, str[j]) & 0xFFFF;
+ s->font->driver->draw (s, 0, upper_len,
+ x + glyph->slice.glyphless.upper_xoff,
+ s->ybase + glyph->slice.glyphless.upper_yoff,
+ false);
+ s->font->driver->draw (s, upper_len, len,
+ x + glyph->slice.glyphless.lower_xoff,
+ s->ybase + glyph->slice.glyphless.lower_yoff,
+ false);
+ }
+ if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
+ pgtk_draw_rectangle (s->f, s->face->foreground,
+ x, s->ybase - glyph->ascent,
+ glyph->pixel_width - 1,
+ glyph->ascent + glyph->descent - 1);
+ x += glyph->pixel_width;
+ }
+}
+
+/* Brightness beyond which a color won't have its highlight brightness
+ boosted.
+
+ Nominally, highlight colors for `3d' faces are calculated by
+ brightening an object's color by a constant scale factor, but this
+ doesn't yield good results for dark colors, so for colors who's
+ brightness is less than this value (on a scale of 0-65535) have an
+ use an additional additive factor.
+
+ The value here is set so that the default menu-bar/mode-line color
+ (grey75) will not have its highlights changed at all. */
+#define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
+
+
+/* Allocate a color which is lighter or darker than *PIXEL by FACTOR
+ or DELTA. Try a color with RGB values multiplied by FACTOR first.
+ If this produces the same color as PIXEL, try a color where all RGB
+ values have DELTA added. Return the allocated color in *PIXEL.
+ DISPLAY is the X display, CMAP is the colormap to operate on.
+ Value is non-zero if successful. */
+
+static bool
+x_alloc_lighter_color (struct frame *f, unsigned long *pixel, double factor,
+ int delta)
+{
+ Emacs_Color color, new;
+ long bright;
+ bool success_p;
+
+ /* Get RGB color values. */
+ color.pixel = *pixel;
+ pgtk_query_color (f, &color);
+
+ /* Change RGB values by specified FACTOR. Avoid overflow! */
+ eassert (factor >= 0);
+ new.red = min (0xffff, factor * color.red);
+ new.green = min (0xffff, factor * color.green);
+ new.blue = min (0xffff, factor * color.blue);
+
+ /* Calculate brightness of COLOR. */
+ bright = (2 * color.red + 3 * color.green + color.blue) / 6;
+
+ /* We only boost colors that are darker than
+ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
+ if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
+ /* Make an additive adjustment to NEW, because it's dark enough so
+ that scaling by FACTOR alone isn't enough. */
+ {
+ /* How far below the limit this color is (0 - 1, 1 being darker). */
+ double dimness = 1 - (double) bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
+ /* The additive adjustment. */
+ int min_delta = delta * dimness * factor / 2;
+
+ if (factor < 1)
+ {
+ new.red = max (0, new.red - min_delta);
+ new.green = max (0, new.green - min_delta);
+ new.blue = max (0, new.blue - min_delta);
+ }
+ else
+ {
+ new.red = min (0xffff, min_delta + new.red);
+ new.green = min (0xffff, min_delta + new.green);
+ new.blue = min (0xffff, min_delta + new.blue);
+ }
+ }
+
+ /* Try to allocate the color. */
+ new.pixel = new.red >> 8 << 16 | new.green >> 8 << 8 | new.blue >> 8;
+ success_p = true;
+ if (success_p)
+ {
+ if (new.pixel == *pixel)
+ {
+ /* If we end up with the same color as before, try adding
+ delta to the RGB values. */
+ new.red = min (0xffff, delta + color.red);
+ new.green = min (0xffff, delta + color.green);
+ new.blue = min (0xffff, delta + color.blue);
+ new.pixel =
+ new.red >> 8 << 16 | new.green >> 8 << 8 | new.blue >> 8;
+ success_p = true;
+ }
+ else
+ success_p = true;
+ *pixel = new.pixel;
+ }
+
+ return success_p;
+}
+
+static void
+x_fill_trapezoid_for_relief (struct frame *f, unsigned long color, int x,
+ int y, int width, int height, int top_p)
+{
+ cairo_t *cr;
+
+ cr = pgtk_begin_cr_clip (f);
+ pgtk_set_cr_source_with_color (f, color);
+ cairo_move_to (cr, top_p ? x : x + height, y);
+ cairo_line_to (cr, x, y + height);
+ cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
+ cairo_line_to (cr, x + width, y);
+ cairo_fill (cr);
+ pgtk_end_cr_clip (f);
+}
+
+enum corners
+{
+ CORNER_BOTTOM_RIGHT, /* 0 -> pi/2 */
+ CORNER_BOTTOM_LEFT, /* pi/2 -> pi */
+ CORNER_TOP_LEFT, /* pi -> 3pi/2 */
+ CORNER_TOP_RIGHT, /* 3pi/2 -> 2pi */
+ CORNER_LAST
+};
+
+static void
+x_erase_corners_for_relief (struct frame *f, unsigned long color, int x,
+ int y, int width, int height, double radius,
+ double margin, int corners)
+{
+ cairo_t *cr;
+ int i;
+
+ cr = pgtk_begin_cr_clip (f);
+ pgtk_set_cr_source_with_color (f, color);
+ for (i = 0; i < CORNER_LAST; i++)
+ if (corners & (1 << i))
+ {
+ double xm, ym, xc, yc;
+
+ if (i == CORNER_TOP_LEFT || i == CORNER_BOTTOM_LEFT)
+ xm = x - margin, xc = xm + radius;
+ else
+ xm = x + width + margin, xc = xm - radius;
+ if (i == CORNER_TOP_LEFT || i == CORNER_TOP_RIGHT)
+ ym = y - margin, yc = ym + radius;
+ else
+ ym = y + height + margin, yc = ym - radius;
+
+ cairo_move_to (cr, xm, ym);
+ cairo_arc (cr, xc, yc, radius, i * M_PI_2, (i + 1) * M_PI_2);
+ }
+ cairo_clip (cr);
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_fill (cr);
+ pgtk_end_cr_clip (f);
+}
+
+/* Set up the foreground color for drawing relief lines of glyph
+ string S. RELIEF is a pointer to a struct relief containing the GC
+ with which lines will be drawn. Use a color that is FACTOR or
+ DELTA lighter or darker than the relief's background which is found
+ in S->f->output_data.pgtk->relief_background. If such a color cannot
+ be allocated, use DEFAULT_PIXEL, instead. */
+
+static void
+x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
+ int delta, unsigned long default_pixel)
+{
+ Emacs_GC xgcv;
+ struct pgtk_output *di = FRAME_X_OUTPUT (f);
+ unsigned long pixel;
+ unsigned long background = di->relief_background;
+
+ /* Allocate new color. */
+ xgcv.foreground = default_pixel;
+ pixel = background;
+ if (x_alloc_lighter_color (f, &pixel, factor, delta))
+ xgcv.foreground = relief->pixel = pixel;
+
+ relief->xgcv = xgcv;
+}
+
+/* Set up colors for the relief lines around glyph string S. */
+
+static void
+x_setup_relief_colors (struct glyph_string *s)
+{
+ struct pgtk_output *di = FRAME_X_OUTPUT (s->f);
+ unsigned long color;
+
+ if (s->face->use_box_color_for_shadows_p)
+ color = s->face->box_color;
+ else if (s->first_glyph->type == IMAGE_GLYPH
+ && s->img->pixmap
+ && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
+ color = IMAGE_BACKGROUND (s->img, s->f, 0);
+ else
+ {
+ /* Get the background color of the face. */
+ color = s->xgcv.background;
+ }
+
+ if (TRUE)
+ {
+ di->relief_background = color;
+ x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
+ WHITE_PIX_DEFAULT (s->f));
+ x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
+ BLACK_PIX_DEFAULT (s->f));
+ }
+}
+
+
+static void
+x_set_clip_rectangles (struct frame *f, cairo_t * cr, XRectangle * rectangles,
+ int n)
+{
+ if (n > 0)
+ {
+ for (int i = 0; i < n; i++)
+ {
+ cairo_rectangle (cr,
+ rectangles[i].x,
+ rectangles[i].y,
+ rectangles[i].width, rectangles[i].height);
+ }
+ cairo_clip (cr);
+ }
+}
+
+/* Draw a relief on frame F inside the rectangle given by LEFT_X,
+ TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
+ to draw, it must be >= 0. RAISED_P means draw a raised
+ relief. LEFT_P means draw a relief on the left side of
+ the rectangle. RIGHT_P means draw a relief on the right
+ side of the rectangle. CLIP_RECT is the clipping rectangle to use
+ when drawing. */
+
+static void
+x_draw_relief_rect (struct frame *f,
+ int left_x, int top_y, int right_x, int bottom_y,
+ int hwidth, int vwidth, bool raised_p, bool top_p,
+ bool bot_p, bool left_p, bool right_p,
+ XRectangle * clip_rect)
+{
+ unsigned long top_left_color, bottom_right_color;
+ int corners = 0;
+
+ cairo_t *cr = pgtk_begin_cr_clip (f);
+
+ if (raised_p)
+ {
+ top_left_color = FRAME_X_OUTPUT (f)->white_relief.xgcv.foreground;
+ bottom_right_color = FRAME_X_OUTPUT (f)->black_relief.xgcv.foreground;
+ }
+ else
+ {
+ top_left_color = FRAME_X_OUTPUT (f)->black_relief.xgcv.foreground;
+ bottom_right_color = FRAME_X_OUTPUT (f)->white_relief.xgcv.foreground;
+ }
+
+ x_set_clip_rectangles (f, cr, clip_rect, 1);
+
+ if (left_p)
+ {
+ pgtk_fill_rectangle (f, top_left_color, left_x, top_y,
+ vwidth, bottom_y + 1 - top_y);
+ if (top_p)
+ corners |= 1 << CORNER_TOP_LEFT;
+ if (bot_p)
+ corners |= 1 << CORNER_BOTTOM_LEFT;
+ }
+ if (right_p)
+ {
+ pgtk_fill_rectangle (f, bottom_right_color, right_x + 1 - vwidth, top_y,
+ vwidth, bottom_y + 1 - top_y);
+ if (top_p)
+ corners |= 1 << CORNER_TOP_RIGHT;
+ if (bot_p)
+ corners |= 1 << CORNER_BOTTOM_RIGHT;
+ }
+ if (top_p)
+ {
+ if (!right_p)
+ pgtk_fill_rectangle (f, top_left_color, left_x, top_y,
+ right_x + 1 - left_x, hwidth);
+ else
+ x_fill_trapezoid_for_relief (f, top_left_color, left_x, top_y,
+ right_x + 1 - left_x, hwidth, 1);
+ }
+ if (bot_p)
+ {
+ if (!left_p)
+ pgtk_fill_rectangle (f, bottom_right_color, left_x,
+ bottom_y + 1 - hwidth, right_x + 1 - left_x,
+ hwidth);
+ else
+ x_fill_trapezoid_for_relief (f, bottom_right_color,
+ left_x, bottom_y + 1 - hwidth,
+ right_x + 1 - left_x, hwidth, 0);
+ }
+ if (left_p && vwidth > 1)
+ pgtk_fill_rectangle (f, bottom_right_color, left_x, top_y,
+ 1, bottom_y + 1 - top_y);
+ if (top_p && hwidth > 1)
+ pgtk_fill_rectangle (f, bottom_right_color, left_x, top_y,
+ right_x + 1 - left_x, 1);
+ if (corners)
+ {
+ x_erase_corners_for_relief (f, FRAME_BACKGROUND_PIXEL (f), left_x,
+ top_y, right_x - left_x + 1,
+ bottom_y - top_y + 1, 6, 1, corners);
+ }
+
+ pgtk_end_cr_clip (f);
+}
+
+/* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
+ RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
+ draw, it must be >= 0. LEFT_P means draw a line on the
+ left side of the rectangle. RIGHT_P means draw a line
+ on the right side of the rectangle. CLIP_RECT is the clipping
+ rectangle to use when drawing. */
+
+static void
+x_draw_box_rect (struct glyph_string *s,
+ int left_x, int top_y, int right_x, int bottom_y, int hwidth,
+ int vwidth, bool left_p, bool right_p,
+ XRectangle * clip_rect)
+{
+ unsigned long foreground_backup;
+
+ cairo_t *cr = pgtk_begin_cr_clip (s->f);
+
+ foreground_backup = s->xgcv.foreground;
+ s->xgcv.foreground = s->face->box_color;
+
+ x_set_clip_rectangles (s->f, cr, clip_rect, 1);
+
+ /* Top. */
+ pgtk_fill_rectangle (s->f, s->xgcv.foreground,
+ left_x, top_y, right_x - left_x + 1, hwidth);
+
+ /* Left. */
+ if (left_p)
+ pgtk_fill_rectangle (s->f, s->xgcv.foreground,
+ left_x, top_y, vwidth, bottom_y - top_y + 1);
+
+ /* Bottom. */
+ pgtk_fill_rectangle (s->f, s->xgcv.foreground,
+ left_x, bottom_y - hwidth + 1, right_x - left_x + 1,
+ hwidth);
+
+ /* Right. */
+ if (right_p)
+ pgtk_fill_rectangle (s->f, s->xgcv.foreground,
+ right_x - vwidth + 1, top_y, vwidth,
+ bottom_y - top_y + 1);
+
+ s->xgcv.foreground = foreground_backup;
+
+ pgtk_end_cr_clip (s->f);
+}
+
+
+/* Draw a box around glyph string S. */
+
+static void
+x_draw_glyph_string_box (struct glyph_string *s)
+{
+ int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
+ bool raised_p, left_p, right_p;
+ struct glyph *last_glyph;
+ XRectangle clip_rect;
+
+ last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
+ ? WINDOW_RIGHT_EDGE_X (s->w) : window_box_right (s->w, s->area));
+
+ /* The glyph that may have a right box line. */
+ last_glyph = (s->cmp || s->img
+ ? s->first_glyph : s->first_glyph + s->nchars - 1);
+
+ vwidth = eabs (s->face->box_vertical_line_width);
+ hwidth = eabs (s->face->box_horizontal_line_width);
+ raised_p = s->face->box == FACE_RAISED_BOX;
+ left_x = s->x;
+ right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
+ ? last_x - 1 : min (last_x, s->x + s->background_width) - 1);
+ top_y = s->y;
+ bottom_y = top_y + s->height - 1;
+
+ left_p = (s->first_glyph->left_box_line_p
+ || (s->hl == DRAW_MOUSE_FACE
+ && (s->prev == NULL || s->prev->hl != s->hl)));
+ right_p = (last_glyph->right_box_line_p
+ || (s->hl == DRAW_MOUSE_FACE
+ && (s->next == NULL || s->next->hl != s->hl)));
+
+ get_glyph_string_clip_rect (s, &clip_rect);
+
+ if (s->face->box == FACE_SIMPLE_BOX)
+ x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
+ vwidth, left_p, right_p, &clip_rect);
+ else
+ {
+ x_setup_relief_colors (s);
+ x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, hwidth,
+ vwidth, raised_p, true, true, left_p, right_p,
+ &clip_rect);
+ }
+}
+
+static void
+x_get_scale_factor (int *scale_x, int *scale_y)
+{
+ *scale_x = *scale_y = 1;
+}
+
+static void
+x_draw_horizontal_wave (struct frame *f, unsigned long color, int x, int y,
+ int width, int height, int wave_length)
+{
+ cairo_t *cr;
+ double dx = wave_length, dy = height - 1;
+ int xoffset, n;
+
+ cr = pgtk_begin_cr_clip (f);
+ pgtk_set_cr_source_with_color (f, color);
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_clip (cr);
+
+ if (x >= 0)
+ {
+ xoffset = x % (wave_length * 2);
+ if (xoffset == 0)
+ xoffset = wave_length * 2;
+ }
+ else
+ xoffset = x % (wave_length * 2) + wave_length * 2;
+ n = (width + xoffset) / wave_length + 1;
+ if (xoffset > wave_length)
+ {
+ xoffset -= wave_length;
+ --n;
+ y += height - 1;
+ dy = -dy;
+ }
+
+ cairo_move_to (cr, x - xoffset + 0.5, y + 0.5);
+ while (--n >= 0)
+ {
+ cairo_rel_line_to (cr, dx, dy);
+ dy = -dy;
+ }
+ cairo_set_line_width (cr, 1);
+ cairo_stroke (cr);
+ pgtk_end_cr_clip (f);
+}
+
+/*
+ Draw a wavy line under S. The wave fills wave_height pixels from y0.
+
+ x0 wave_length = 2
+ --
+ y0 * * * * *
+ |* * * * * * * * *
+ wave_height = 3 | * * * *
+
+*/
+static void
+x_draw_underwave (struct glyph_string *s, unsigned long color)
+{
+ /* Adjust for scale/HiDPI. */
+ int scale_x, scale_y;
+
+ x_get_scale_factor (&scale_x, &scale_y);
+
+ int wave_height = 3 * scale_y, wave_length = 2 * scale_x;
+
+ x_draw_horizontal_wave (s->f, color, s->x, s->ybase - wave_height + 3,
+ s->width, wave_height, wave_length);
+}
+
+/* Draw a relief around the image glyph string S. */
+
+static void
+x_draw_image_relief (struct glyph_string *s)
+{
+ int x1, y1, thick;
+ bool raised_p, top_p, bot_p, left_p, right_p;
+ int extra_x, extra_y;
+ XRectangle r;
+ int x = s->x;
+ int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
+
+ /* If first glyph of S has a left box line, start drawing it to the
+ right of that line. */
+ if (s->face->box != FACE_NO_BOX
+ && s->first_glyph->left_box_line_p
+ && s->slice.x == 0)
+ x += max (s->face->box_vertical_line_width, 0);
+
+ /* If there is a margin around the image, adjust x- and y-position
+ by that margin. */
+ if (s->slice.x == 0)
+ x += s->img->hmargin;
+ if (s->slice.y == 0)
+ y += s->img->vmargin;
+
+ if (s->hl == DRAW_IMAGE_SUNKEN
+ || s->hl == DRAW_IMAGE_RAISED)
+ {
+ if (s->face->id == TAB_BAR_FACE_ID)
+ thick = (tab_bar_button_relief < 0
+ ? DEFAULT_TAB_BAR_BUTTON_RELIEF
+ : min (tab_bar_button_relief, 1000000));
+ else
+ thick = (tool_bar_button_relief < 0
+ ? DEFAULT_TOOL_BAR_BUTTON_RELIEF
+ : min (tool_bar_button_relief, 1000000));
+ raised_p = s->hl == DRAW_IMAGE_RAISED;
+ }
+ else
+ {
+ thick = eabs (s->img->relief);
+ raised_p = s->img->relief > 0;
+ }
+
+ x1 = x + s->slice.width - 1;
+ y1 = y + s->slice.height - 1;
+
+ extra_x = extra_y = 0;
+ if (s->face->id == TAB_BAR_FACE_ID)
+ {
+ if (CONSP (Vtab_bar_button_margin)
+ && FIXNUMP (XCAR (Vtab_bar_button_margin))
+ && FIXNUMP (XCDR (Vtab_bar_button_margin)))
+ {
+ extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin)) - thick;
+ extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin)) - thick;
+ }
+ else if (FIXNUMP (Vtab_bar_button_margin))
+ extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin) - thick;
+ }
+
+ if (s->face->id == TOOL_BAR_FACE_ID)
+ {
+ if (CONSP (Vtool_bar_button_margin)
+ && FIXNUMP (XCAR (Vtool_bar_button_margin))
+ && FIXNUMP (XCDR (Vtool_bar_button_margin)))
+ {
+ extra_x = XFIXNUM (XCAR (Vtool_bar_button_margin));
+ extra_y = XFIXNUM (XCDR (Vtool_bar_button_margin));
+ }
+ else if (FIXNUMP (Vtool_bar_button_margin))
+ extra_x = extra_y = XFIXNUM (Vtool_bar_button_margin);
+ }
+
+ top_p = bot_p = left_p = right_p = false;
+
+ if (s->slice.x == 0)
+ x -= thick + extra_x, left_p = true;
+ if (s->slice.y == 0)
+ y -= thick + extra_y, top_p = true;
+ if (s->slice.x + s->slice.width == s->img->width)
+ x1 += thick + extra_x, right_p = true;
+ if (s->slice.y + s->slice.height == s->img->height)
+ y1 += thick + extra_y, bot_p = true;
+
+ x_setup_relief_colors (s);
+ get_glyph_string_clip_rect (s, &r);
+ x_draw_relief_rect (s->f, x, y, x1, y1, thick, thick, raised_p,
+ top_p, bot_p, left_p, right_p, &r);
+}
+
+/* Draw part of the background of glyph string S. X, Y, W, and H
+ give the rectangle to draw. */
+
+static void
+x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w,
+ int h)
+{
+ if (s->stippled_p)
+ {
+ /* Fill background with a stipple pattern. */
+
+ fill_background (s, x, y, w, h);
+ }
+ else
+ x_clear_glyph_string_rect (s, x, y, w, h);
+}
+
+static void
+x_cr_draw_image (struct frame *f, Emacs_GC *gc, cairo_pattern_t *image,
+ int src_x, int src_y, int width, int height,
+ int dest_x, int dest_y, bool overlay_p)
+{
+ cairo_t *cr = pgtk_begin_cr_clip (f);
+
+ if (overlay_p)
+ cairo_rectangle (cr, dest_x, dest_y, width, height);
+ else
+ {
+ pgtk_set_cr_source_with_gc_background (f, gc);
+ cairo_rectangle (cr, dest_x, dest_y, width, height);
+ cairo_fill_preserve (cr);
+ }
+
+ cairo_translate (cr, dest_x - src_x, dest_y - src_y);
+
+ cairo_surface_t *surface;
+ cairo_pattern_get_surface (image, &surface);
+ cairo_format_t format = cairo_image_surface_get_format (surface);
+ if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
+ {
+ cairo_set_source (cr, image);
+ cairo_fill (cr);
+ }
+ else
+ {
+ pgtk_set_cr_source_with_gc_foreground (f, gc);
+ cairo_clip (cr);
+ cairo_mask (cr, image);
+ }
+
+ pgtk_end_cr_clip (f);
+}
+
+/* Draw foreground of image glyph string S. */
+
+static void
+x_draw_image_foreground (struct glyph_string *s)
+{
+ int x = s->x;
+ int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
+
+ /* If first glyph of S has a left box line, start drawing it to the
+ right of that line. */
+ if (s->face->box != FACE_NO_BOX
+ && s->first_glyph->left_box_line_p
+ && s->slice.x == 0)
+ x += max (s->face->box_vertical_line_width, 0);
+
+ /* If there is a margin around the image, adjust x- and y-position
+ by that margin. */
+ if (s->slice.x == 0)
+ x += s->img->hmargin;
+ if (s->slice.y == 0)
+ y += s->img->vmargin;
+
+ if (s->img->cr_data)
+ {
+ cairo_t *cr = pgtk_begin_cr_clip (s->f);
+ x_set_glyph_string_clipping (s, cr);
+ x_cr_draw_image (s->f, &s->xgcv, s->img->cr_data,
+ s->slice.x, s->slice.y, s->slice.width, s->slice.height,
+ x, y, true);
+ if (!s->img->mask)
+ {
+ /* When the image has a mask, we can expect that at
+ least part of a mouse highlight or a block cursor will
+ be visible. If the image doesn't have a mask, make
+ a block cursor visible by drawing a rectangle around
+ the image. I believe it's looking better if we do
+ nothing here for mouse-face. */
+ if (s->hl == DRAW_CURSOR)
+ {
+ int relief = eabs (s->img->relief);
+ pgtk_draw_rectangle (s->f, s->xgcv.foreground, x - relief, y - relief,
+ s->slice.width + relief*2 - 1,
+ s->slice.height + relief*2 - 1);
+ }
+ }
+ pgtk_end_cr_clip (s->f);
+ }
+ else
+ /* Draw a rectangle if image could not be loaded. */
+ pgtk_draw_rectangle (s->f, s->xgcv.foreground, x, y,
+ s->slice.width - 1, s->slice.height - 1);
+}
+
+/* Draw image glyph string S.
+
+ s->y
+ s->x +-------------------------
+ | s->face->box
+ |
+ | +-------------------------
+ | | s->img->margin
+ | |
+ | | +-------------------
+ | | | the image
+
+ */
+
+static void
+x_draw_image_glyph_string (struct glyph_string *s)
+{
+ int box_line_hwidth = max (s->face->box_vertical_line_width, 0);
+ int box_line_vwidth = max (s->face->box_horizontal_line_width, 0);
+ int height;
+
+ height = s->height;
+ if (s->slice.y == 0)
+ height -= box_line_vwidth;
+ if (s->slice.y + s->slice.height >= s->img->height)
+ height -= box_line_vwidth;
+
+ /* Fill background with face under the image. Do it only if row is
+ taller than image or if image has a clip mask to reduce
+ flickering. */
+ s->stippled_p = s->face->stipple != 0;
+ if (height > s->slice.height
+ || s->img->hmargin
+ || s->img->vmargin
+ || s->img->mask
+ || s->img->pixmap == 0
+ || s->width != s->background_width)
+ {
+ {
+ int x = s->x;
+ int y = s->y;
+ int width = s->background_width;
+
+ if (s->first_glyph->left_box_line_p
+ && s->slice.x == 0)
+ {
+ x += box_line_hwidth;
+ width -= box_line_hwidth;
+ }
+
+ if (s->slice.y == 0)
+ y += box_line_vwidth;
+
+ x_draw_glyph_string_bg_rect (s, x, y, width, height);
+ }
+
+ s->background_filled_p = true;
+ }
+
+ /* Draw the foreground. */
+ x_draw_image_foreground (s);
+
+ /* If we must draw a relief around the image, do it. */
+ if (s->img->relief
+ || s->hl == DRAW_IMAGE_RAISED
+ || s->hl == DRAW_IMAGE_SUNKEN)
+ x_draw_image_relief (s);
+}
+
+/* Draw stretch glyph string S. */
+
+static void
+x_draw_stretch_glyph_string (struct glyph_string *s)
+{
+ eassert (s->first_glyph->type == STRETCH_GLYPH);
+
+ if (s->hl == DRAW_CURSOR && !x_stretch_cursor_p)
+ {
+ /* If `x-stretch-cursor' is nil, don't draw a block cursor as
+ wide as the stretch glyph. */
+ int width, background_width = s->background_width;
+ int x = s->x;
+
+ if (!s->row->reversed_p)
+ {
+ int left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ }
+ else
+ {
+ /* In R2L rows, draw the cursor on the right edge of the
+ stretch glyph. */
+ int right_x = window_box_right (s->w, TEXT_AREA);
+
+ if (x + background_width > right_x)
+ background_width -= x - right_x;
+ x += background_width;
+ }
+ width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
+ if (s->row->reversed_p)
+ x -= width;
+
+ /* Draw cursor. */
+ x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
+
+ /* Clear rest using the GC of the original non-cursor face. */
+ if (width < background_width)
+ {
+ int y = s->y;
+ int w = background_width - width, h = s->height;
+ XRectangle r;
+ unsigned long color;
+
+ if (!s->row->reversed_p)
+ x += width;
+ else
+ x = s->x;
+ if (s->row->mouse_face_p && cursor_in_mouse_face_p (s->w))
+ {
+ x_set_mouse_face_gc (s);
+ color = s->xgcv.foreground;
+ }
+ else
+ color = s->face->background;
+
+ cairo_t *cr = pgtk_begin_cr_clip (s->f);
+
+ get_glyph_string_clip_rect (s, &r);
+ x_set_clip_rectangles (s->f, cr, &r, 1);
+
+ if (s->face->stipple)
+ {
+ /* Fill background with a stipple pattern. */
+ fill_background (s, x, y, w, h);
+ }
+ else
+ {
+ pgtk_fill_rectangle (s->f, color, x, y, w, h);
+ }
+
+ pgtk_end_cr_clip (s->f);
+ }
+ }
+ else if (!s->background_filled_p)
+ {
+ int background_width = s->background_width;
+ int x = s->x, text_left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ /* Don't draw into left fringe or scrollbar area except for
+ header line and mode line. */
+ if (x < text_left_x && !s->row->mode_line_p)
+ {
+ int left_x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (s->w);
+ int right_x = text_left_x;
+
+ if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s->w))
+ left_x += WINDOW_LEFT_FRINGE_WIDTH (s->w);
+ else
+ right_x -= WINDOW_LEFT_FRINGE_WIDTH (s->w);
+
+ /* Adjust X and BACKGROUND_WIDTH to fit inside the space
+ between LEFT_X and RIGHT_X. */
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ if (x + background_width > right_x)
+ background_width = right_x - x;
+ }
+ if (background_width > 0)
+ x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
+ }
+
+ s->background_filled_p = true;
+}
+
+static void
+pgtk_draw_glyph_string (struct glyph_string *s)
+{
+ bool relief_drawn_p = false;
+
+ /* If S draws into the background of its successors, draw the
+ background of the successors first so that S can draw into it.
+ This makes S->next use XDrawString instead of XDrawImageString. */
+ if (s->next && s->right_overhang && !s->for_overlaps)
+ {
+ int width;
+ struct glyph_string *next;
+
+ for (width = 0, next = s->next;
+ next && width < s->right_overhang;
+ width += next->width, next = next->next)
+ if (next->first_glyph->type != IMAGE_GLYPH)
+ {
+ cairo_t *cr = pgtk_begin_cr_clip (next->f);
+ x_set_glyph_string_gc (next);
+ x_set_glyph_string_clipping (next, cr);
+ if (next->first_glyph->type == STRETCH_GLYPH)
+ x_draw_stretch_glyph_string (next);
+ else
+ x_draw_glyph_string_background (next, true);
+ next->num_clips = 0;
+ pgtk_end_cr_clip (next->f);
+ }
+ }
+
+ /* Set up S->gc, set clipping and draw S. */
+ x_set_glyph_string_gc (s);
+
+ cairo_t *cr = pgtk_begin_cr_clip (s->f);
+
+ /* Draw relief (if any) in advance for char/composition so that the
+ glyph string can be drawn over it. */
+ if (!s->for_overlaps
+ && s->face->box != FACE_NO_BOX
+ && (s->first_glyph->type == CHAR_GLYPH
+ || s->first_glyph->type == COMPOSITE_GLYPH))
+
+ {
+ x_set_glyph_string_clipping (s, cr);
+ x_draw_glyph_string_background (s, true);
+ x_draw_glyph_string_box (s);
+ x_set_glyph_string_clipping (s, cr);
+ relief_drawn_p = true;
+ }
+ else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
+ && !s->clip_tail
+ && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
+ || (s->next && s->next->hl != s->hl && s->right_overhang)))
+ /* We must clip just this glyph. left_overhang part has already
+ drawn when s->prev was drawn, and right_overhang part will be
+ drawn later when s->next is drawn. */
+ x_set_glyph_string_clipping_exactly (s, s, cr);
+ else
+ x_set_glyph_string_clipping (s, cr);
+
+ switch (s->first_glyph->type)
+ {
+ case IMAGE_GLYPH:
+ x_draw_image_glyph_string (s);
+ break;
+
+ case XWIDGET_GLYPH:
+ x_draw_xwidget_glyph_string (s);
+ break;
+
+ case STRETCH_GLYPH:
+ x_draw_stretch_glyph_string (s);
+ break;
+
+ case CHAR_GLYPH:
+ if (s->for_overlaps)
+ s->background_filled_p = true;
+ else
+ x_draw_glyph_string_background (s, false);
+ x_draw_glyph_string_foreground (s);
+ break;
+
+ case COMPOSITE_GLYPH:
+ if (s->for_overlaps || (s->cmp_from > 0
+ && !s->first_glyph->u.cmp.automatic))
+ s->background_filled_p = true;
+ else
+ x_draw_glyph_string_background (s, true);
+ x_draw_composite_glyph_string_foreground (s);
+ break;
+
+ case GLYPHLESS_GLYPH:
+ if (s->for_overlaps)
+ s->background_filled_p = true;
+ else
+ x_draw_glyph_string_background (s, true);
+ x_draw_glyphless_glyph_string_foreground (s);
+ break;
+
+ default:
+ emacs_abort ();
+ }
+
+ if (!s->for_overlaps)
+ {
+ /* Draw relief if not yet drawn. */
+ if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
+ x_draw_glyph_string_box (s);
+
+ /* Draw underline. */
+ if (s->face->underline)
+ {
+ if (s->face->underline == FACE_UNDER_WAVE)
+ {
+ if (s->face->underline_defaulted_p)
+ x_draw_underwave (s, s->xgcv.foreground);
+ else
+ {
+ x_draw_underwave (s, s->face->underline_color);
+ }
+ }
+ else if (s->face->underline == FACE_UNDER_LINE)
+ {
+ unsigned long thickness, position;
+ int y;
+
+ if (s->prev && s->prev->face->underline
+ && s->prev->face->underline == FACE_UNDER_LINE)
+ {
+ /* We use the same underline style as the previous one. */
+ thickness = s->prev->underline_thickness;
+ position = s->prev->underline_position;
+ }
+ else
+ {
+ struct font *font = font_for_underline_metrics (s);
+
+ /* Get the underline thickness. Default is 1 pixel. */
+ if (font && font->underline_thickness > 0)
+ thickness = font->underline_thickness;
+ else
+ thickness = 1;
+ if (x_underline_at_descent_line)
+ position = (s->height - thickness) - (s->ybase - s->y);
+ else
+ {
+ /* Get the underline position. This is the recommended
+ vertical offset in pixels from the baseline to the top of
+ the underline. This is a signed value according to the
+ specs, and its default is
+
+ ROUND ((maximum descent) / 2), with
+ ROUND(x) = floor (x + 0.5) */
+
+ if (x_use_underline_position_properties
+ && font && font->underline_position >= 0)
+ position = font->underline_position;
+ else if (font)
+ position = (font->descent + 1) / 2;
+ else
+ position = underline_minimum_offset;
+ }
+ position = max (position, underline_minimum_offset);
+ }
+ /* Check the sanity of thickness and position. We should
+ avoid drawing underline out of the current line area. */
+ if (s->y + s->height <= s->ybase + position)
+ position = (s->height - 1) - (s->ybase - s->y);
+ if (s->y + s->height < s->ybase + position + thickness)
+ thickness = (s->y + s->height) - (s->ybase + position);
+ s->underline_thickness = thickness;
+ s->underline_position = position;
+ y = s->ybase + position;
+ if (s->face->underline_defaulted_p)
+ pgtk_fill_rectangle (s->f, s->xgcv.foreground,
+ s->x, y, s->width, thickness);
+ else
+ {
+ pgtk_fill_rectangle (s->f, s->face->underline_color,
+ s->x, y, s->width, thickness);
+ }
+ }
+ }
+ /* Draw overline. */
+ if (s->face->overline_p)
+ {
+ unsigned long dy = 0, h = 1;
+
+ if (s->face->overline_color_defaulted_p)
+ pgtk_fill_rectangle (s->f, s->xgcv.foreground, s->x, s->y + dy,
+ s->width, h);
+ else
+ {
+ pgtk_fill_rectangle (s->f, s->face->overline_color, s->x,
+ s->y + dy, s->width, h);
+ }
+ }
+
+ /* Draw strike-through. */
+ if (s->face->strike_through_p)
+ {
+ /* Y-coordinate and height of the glyph string's first
+ glyph. We cannot use s->y and s->height because those
+ could be larger if there are taller display elements
+ (e.g., characters displayed with a larger font) in the
+ same glyph row. */
+ int glyph_y = s->ybase - s->first_glyph->ascent;
+ int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
+ /* Strike-through width and offset from the glyph string's
+ top edge. */
+ unsigned long h = 1;
+ unsigned long dy = (glyph_height - h) / 2;
+
+ if (s->face->strike_through_color_defaulted_p)
+ pgtk_fill_rectangle (s->f, s->xgcv.foreground, s->x, glyph_y + dy,
+ s->width, h);
+ else
+ {
+ pgtk_fill_rectangle (s->f, s->face->strike_through_color, s->x,
+ glyph_y + dy, s->width, h);
+ }
+ }
+
+ if (s->prev)
+ {
+ struct glyph_string *prev;
+
+ for (prev = s->prev; prev; prev = prev->prev)
+ if (prev->hl != s->hl
+ && prev->x + prev->width + prev->right_overhang > s->x)
+ {
+ /* As prev was drawn while clipped to its own area, we
+ must draw the right_overhang part using s->hl now. */
+ enum draw_glyphs_face save = prev->hl;
+
+ prev->hl = s->hl;
+ x_set_glyph_string_gc (prev);
+ cairo_save (cr);
+ x_set_glyph_string_clipping_exactly (s, prev, cr);
+ if (prev->first_glyph->type == CHAR_GLYPH)
+ x_draw_glyph_string_foreground (prev);
+ else
+ x_draw_composite_glyph_string_foreground (prev);
+ prev->hl = save;
+ prev->num_clips = 0;
+ cairo_restore (cr);
+ }
+ }
+
+ if (s->next)
+ {
+ struct glyph_string *next;
+
+ for (next = s->next; next; next = next->next)
+ if (next->hl != s->hl
+ && next->x - next->left_overhang < s->x + s->width)
+ {
+ /* As next will be drawn while clipped to its own area,
+ we must draw the left_overhang part using s->hl now. */
+ enum draw_glyphs_face save = next->hl;
+
+ next->hl = s->hl;
+ x_set_glyph_string_gc (next);
+ cairo_save (cr);
+ x_set_glyph_string_clipping_exactly (s, next, cr);
+ if (next->first_glyph->type == CHAR_GLYPH)
+ x_draw_glyph_string_foreground (next);
+ else
+ x_draw_composite_glyph_string_foreground (next);
+ cairo_restore (cr);
+ next->hl = save;
+ next->num_clips = 0;
+ next->clip_head = s->next;
+ }
+ }
+ }
+
+ /* Reset clipping. */
+ pgtk_end_cr_clip (s->f);
+ s->num_clips = 0;
+}
+
+/* RIF: Define cursor CURSOR on frame F. */
+
+static void
+pgtk_define_frame_cursor (struct frame *f, Emacs_Cursor cursor)
+{
+ if (!f->pointer_invisible && FRAME_X_OUTPUT (f)->current_cursor != cursor)
+ gdk_window_set_cursor (gtk_widget_get_window (FRAME_GTK_WIDGET (f)),
+ cursor);
+ FRAME_X_OUTPUT (f)->current_cursor = cursor;
+}
+
+static void
+pgtk_after_update_window_line (struct window *w,
+ struct glyph_row *desired_row)
+{
+ struct frame *f;
+ int width, height;
+
+ /* begin copy from other terms */
+ eassert (w);
+
+ if (!desired_row->mode_line_p && !w->pseudo_window_p)
+ desired_row->redraw_fringe_bitmaps_p = 1;
+
+ /* When a window has disappeared, make sure that no rest of
+ full-width rows stays visible in the internal border. */
+ if (windows_or_buffers_changed
+ && desired_row->full_width_p
+ && (f = XFRAME (w->frame),
+ width = FRAME_INTERNAL_BORDER_WIDTH (f),
+ width != 0) && (height = desired_row->visible_height, height > 0))
+ {
+ int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
+
+ block_input ();
+ pgtk_clear_frame_area (f, 0, y, width, height);
+ pgtk_clear_frame_area (f,
+ FRAME_PIXEL_WIDTH (f) - width, y, width, height);
+ unblock_input ();
+ }
+}
+
+static void
+pgtk_clear_frame_area (struct frame *f, int x, int y, int width, int height)
+{
+ pgtk_clear_area (f, x, y, width, height);
+}
+
+/* Draw a hollow box cursor on window W in glyph row ROW. */
+
+static void
+x_draw_hollow_cursor (struct window *w, struct glyph_row *row)
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+ int x, y, wd, h;
+ struct glyph *cursor_glyph;
+
+ /* Get the glyph the cursor is on. If we can't tell because
+ the current matrix is invalid or such, give up. */
+ cursor_glyph = get_phys_cursor_glyph (w);
+ if (cursor_glyph == NULL)
+ return;
+
+ /* Compute frame-relative coordinates for phys cursor. */
+ get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
+ wd = w->phys_cursor_width - 1;
+
+ /* The foreground of cursor_gc is typically the same as the normal
+ background color, which can cause the cursor box to be invisible. */
+ cairo_t *cr = pgtk_begin_cr_clip (f);
+ pgtk_set_cr_source_with_color (f, FRAME_X_OUTPUT (f)->cursor_color);
+
+ /* When on R2L character, show cursor at the right edge of the
+ glyph, unless the cursor box is as wide as the glyph or wider
+ (the latter happens when x-stretch-cursor is non-nil). */
+ if ((cursor_glyph->resolved_level & 1) != 0
+ && cursor_glyph->pixel_width > wd)
+ {
+ x += cursor_glyph->pixel_width - wd;
+ if (wd > 0)
+ wd -= 1;
+ }
+ /* Set clipping, draw the rectangle, and reset clipping again. */
+ pgtk_clip_to_row (w, row, TEXT_AREA, cr);
+ pgtk_draw_rectangle (f, FRAME_X_OUTPUT (f)->cursor_color, x, y, wd, h - 1);
+ pgtk_end_cr_clip (f);
+}
+
+/* Draw a bar cursor on window W in glyph row ROW.
+
+ Implementation note: One would like to draw a bar cursor with an
+ angle equal to the one given by the font property XA_ITALIC_ANGLE.
+ Unfortunately, I didn't find a font yet that has this property set.
+ --gerd. */
+
+static void
+x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width,
+ enum text_cursor_kinds kind)
+{
+ struct frame *f = XFRAME (w->frame);
+ struct glyph *cursor_glyph;
+
+ /* If cursor is out of bounds, don't draw garbage. This can happen
+ in mini-buffer windows when switching between echo area glyphs
+ and mini-buffer. */
+ cursor_glyph = get_phys_cursor_glyph (w);
+ if (cursor_glyph == NULL)
+ return;
+
+ /* Experimental avoidance of cursor on xwidget. */
+ if (cursor_glyph->type == XWIDGET_GLYPH)
+ return;
+
+ /* If on an image, draw like a normal cursor. That's usually better
+ visible than drawing a bar, esp. if the image is large so that
+ the bar might not be in the window. */
+ if (cursor_glyph->type == IMAGE_GLYPH)
+ {
+ struct glyph_row *r;
+ r = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
+ draw_phys_cursor_glyph (w, r, DRAW_CURSOR);
+ }
+ else
+ {
+ struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
+ unsigned long color;
+
+ cairo_t *cr = pgtk_begin_cr_clip (f);
+
+ /* If the glyph's background equals the color we normally draw
+ the bars cursor in, the bar cursor in its normal color is
+ invisible. Use the glyph's foreground color instead in this
+ case, on the assumption that the glyph's colors are chosen so
+ that the glyph is legible. */
+ if (face->background == FRAME_X_OUTPUT (f)->cursor_color)
+ color = face->foreground;
+ else
+ color = FRAME_X_OUTPUT (f)->cursor_color;
+
+ pgtk_clip_to_row (w, row, TEXT_AREA, cr);
+
+ if (kind == BAR_CURSOR)
+ {
+ int x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+
+ if (width < 0)
+ width = FRAME_CURSOR_WIDTH (f);
+ width = min (cursor_glyph->pixel_width, width);
+
+ w->phys_cursor_width = width;
+
+ /* If the character under cursor is R2L, draw the bar cursor
+ on the right of its glyph, rather than on the left. */
+ if ((cursor_glyph->resolved_level & 1) != 0)
+ x += cursor_glyph->pixel_width - width;
+
+ pgtk_fill_rectangle (f, color, x,
+ WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
+ width, row->height);
+ }
+ else /* HBAR_CURSOR */
+ {
+ int dummy_x, dummy_y, dummy_h;
+ int x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+
+ if (width < 0)
+ width = row->height;
+
+ width = min (row->height, width);
+
+ get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
+ &dummy_y, &dummy_h);
+
+ if ((cursor_glyph->resolved_level & 1) != 0
+ && cursor_glyph->pixel_width > w->phys_cursor_width - 1)
+ x += cursor_glyph->pixel_width - w->phys_cursor_width + 1;
+ pgtk_fill_rectangle (f, color, x,
+ WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
+ row->height - width),
+ w->phys_cursor_width - 1, width);
+ }
+
+ pgtk_end_cr_clip (f);
+ }
+}
+
+/* RIF: Draw cursor on window W. */
+
+static void
+pgtk_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x,
+ int y, enum text_cursor_kinds cursor_type,
+ int cursor_width, bool on_p, bool active_p)
+{
+ struct frame *f = XFRAME (w->frame);
+ if (on_p)
+ {
+ w->phys_cursor_type = cursor_type;
+ w->phys_cursor_on_p = true;
+
+ if (glyph_row->exact_window_width_line_p
+ && (glyph_row->reversed_p
+ ? (w->phys_cursor.hpos < 0)
+ : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
+ {
+ glyph_row->cursor_in_fringe_p = true;
+ draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
+ }
+ else
+ {
+ switch (cursor_type)
+ {
+ case HOLLOW_BOX_CURSOR:
+ x_draw_hollow_cursor (w, glyph_row);
+ break;
+
+ case FILLED_BOX_CURSOR:
+ draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+ break;
+
+ case BAR_CURSOR:
+ x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
+ break;
+
+ case HBAR_CURSOR:
+ x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
+ break;
+
+ case NO_CURSOR:
+ w->phys_cursor_width = 0;
+ break;
+
+ default:
+ emacs_abort ();
+ }
+ }
+
+ if (w == XWINDOW (f->selected_window))
+ {
+ int frame_x =
+ WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w);
+ int frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, y);
+ pgtk_im_set_cursor_location (f, frame_x, frame_y,
+ w->phys_cursor_width,
+ w->phys_cursor_height);
+ }
+ }
+
+}
+
+static void
+pgtk_copy_bits (struct frame *f, cairo_rectangle_t * src_rect,
+ cairo_rectangle_t * dst_rect)
+{
+ cairo_t *cr;
+ cairo_surface_t *surface; /* temporary surface */
+
+ surface =
+ cairo_surface_create_similar (FRAME_CR_SURFACE (f),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ (int) src_rect->width,
+ (int) src_rect->height);
+
+ cr = cairo_create (surface);
+ cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), -src_rect->x,
+ -src_rect->y);
+ cairo_rectangle (cr, 0, 0, src_rect->width, src_rect->height);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cr = pgtk_begin_cr_clip (f);
+ cairo_set_source_surface (cr, surface, dst_rect->x, dst_rect->y);
+ cairo_rectangle (cr, dst_rect->x, dst_rect->y, dst_rect->width,
+ dst_rect->height);
+ cairo_clip (cr);
+ cairo_paint (cr);
+ pgtk_end_cr_clip (f);
+
+ cairo_surface_destroy (surface);
+}
+
+/* Scroll part of the display as described by RUN. */
+
+static void
+pgtk_scroll_run (struct window *w, struct run *run)
+{
+ struct frame *f = XFRAME (w->frame);
+ int x, y, width, height, from_y, to_y, bottom_y;
+
+ /* Get frame-relative bounding box of the text display area of W,
+ without mode lines. Include in this box the left and right
+ fringe of W. */
+ window_box (w, ANY_AREA, &x, &y, &width, &height);
+
+ from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
+ to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
+ bottom_y = y + height;
+
+ if (to_y < from_y)
+ {
+ /* Scrolling up. Make sure we don't copy part of the mode
+ line at the bottom. */
+ if (from_y + run->height > bottom_y)
+ height = bottom_y - from_y;
+ else
+ height = run->height;
+ }
+ else
+ {
+ /* Scrolling down. Make sure we don't copy over the mode line.
+ at the bottom. */
+ if (to_y + run->height > bottom_y)
+ height = bottom_y - to_y;
+ else
+ height = run->height;
+ }
+
+ block_input ();
+
+ /* Cursor off. Will be switched on again in x_update_window_end. */
+ gui_clear_cursor (w);
+
+ {
+ cairo_rectangle_t src_rect = { x, from_y, width, height };
+ cairo_rectangle_t dst_rect = { x, to_y, width, height };
+ pgtk_copy_bits (f, &src_rect, &dst_rect);
+ }
+
+ unblock_input ();
+}
+
+/* Icons. */
+
+/* Make the x-window of frame F use the gnu icon bitmap. */
+
+static bool
+pgtk_bitmap_icon (struct frame *f, Lisp_Object file)
+{
+ ptrdiff_t bitmap_id;
+
+ if (FRAME_GTK_WIDGET (f) == 0)
+ return true;
+
+ /* Free up our existing icon bitmap and mask if any. */
+ if (f->output_data.pgtk->icon_bitmap > 0)
+ image_destroy_bitmap (f, f->output_data.pgtk->icon_bitmap);
+ f->output_data.pgtk->icon_bitmap = 0;
+
+ if (STRINGP (file))
+ {
+ /* Use gtk_window_set_icon_from_file () if available,
+ It's not restricted to bitmaps */
+ if (xg_set_icon (f, file))
+ return false;
+ bitmap_id = image_create_bitmap_from_file (f, file);
+ }
+ else
+ {
+ /* Create the GNU bitmap and mask if necessary. */
+ if (FRAME_DISPLAY_INFO (f)->icon_bitmap_id < 0)
+ {
+ ptrdiff_t rc = -1;
+
+ if (xg_set_icon (f, xg_default_icon_file)
+ || xg_set_icon_from_xpm_data (f, gnu_xpm_bits))
+ {
+ FRAME_DISPLAY_INFO (f)->icon_bitmap_id = -2;
+ return false;
+ }
+
+ /* If all else fails, use the (black and white) xbm image. */
+ if (rc == -1)
+ {
+ rc = image_create_bitmap_from_data (f,
+ (char *) gnu_xbm_bits,
+ gnu_xbm_width,
+ gnu_xbm_height);
+ if (rc == -1)
+ return true;
+
+ FRAME_DISPLAY_INFO (f)->icon_bitmap_id = rc;
+ }
+ }
+
+ /* The first time we create the GNU bitmap and mask,
+ this increments the ref-count one extra time.
+ As a result, the GNU bitmap and mask are never freed.
+ That way, we don't have to worry about allocating it again. */
+ image_reference_bitmap (f, FRAME_DISPLAY_INFO (f)->icon_bitmap_id);
+
+ bitmap_id = FRAME_DISPLAY_INFO (f)->icon_bitmap_id;
+ }
+
+ if (FRAME_DISPLAY_INFO (f)->bitmaps[bitmap_id - 1].img != NULL)
+ {
+ gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ FRAME_DISPLAY_INFO (f)->bitmaps[bitmap_id - 1].img);
+ }
+ f->output_data.pgtk->icon_bitmap = bitmap_id;
+
+ return false;
+}
+
+
+/* Make the x-window of frame F use a rectangle with text.
+ Use ICON_NAME as the text. */
+
+bool
+pgtk_text_icon (struct frame *f, const char *icon_name)
+{
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), NULL);
+ gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), icon_name);
+ }
+
+ return false;
+}
+
+/***********************************************************************
+ Starting and ending an update
+ ***********************************************************************/
+
+/* Start an update of frame F. This function is installed as a hook
+ for update_begin, i.e. it is called when update_begin is called.
+ This function is called prior to calls to x_update_window_begin for
+ each window being updated. Currently, there is nothing to do here
+ because all interesting stuff is done on a window basis. */
+
+static void
+pgtk_update_begin (struct frame *f)
+{
+ pgtk_clear_under_internal_border (f);
+}
+
+/* Draw a vertical window border from (x,y0) to (x,y1) */
+
+static void
+pgtk_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+ struct face *face;
+ cairo_t *cr;
+
+ cr = pgtk_begin_cr_clip (f);
+
+ face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
+ if (face)
+ pgtk_set_cr_source_with_color (f, face->foreground);
+
+ cairo_rectangle (cr, x, y0, 1, y1 - y0);
+ cairo_fill (cr);
+
+ pgtk_end_cr_clip (f);
+}
+
+/* Draw a window divider from (x0,y0) to (x1,y1) */
+
+static void
+pgtk_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+ struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
+ struct face *face_first
+ = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
+ struct face *face_last
+ = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
+ unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
+ unsigned long color_first = (face_first
+ ? face_first->foreground
+ : FRAME_FOREGROUND_PIXEL (f));
+ unsigned long color_last = (face_last
+ ? face_last->foreground
+ : FRAME_FOREGROUND_PIXEL (f));
+ cairo_t *cr = pgtk_begin_cr_clip (f);
+
+ if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
+ /* Vertical. */
+ {
+ pgtk_set_cr_source_with_color (f, color_first);
+ cairo_rectangle (cr, x0, y0, 1, y1 - y0);
+ cairo_fill (cr);
+ pgtk_set_cr_source_with_color (f, color);
+ cairo_rectangle (cr, x0 + 1, y0, x1 - x0 - 2, y1 - y0);
+ cairo_fill (cr);
+ pgtk_set_cr_source_with_color (f, color_last);
+ cairo_rectangle (cr, x1 - 1, y0, 1, y1 - y0);
+ cairo_fill (cr);
+ }
+ else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
+ /* Horizontal. */
+ {
+ pgtk_set_cr_source_with_color (f, color_first);
+ cairo_rectangle (cr, x0, y0, x1 - x0, 1);
+ cairo_fill (cr);
+ pgtk_set_cr_source_with_color (f, color);
+ cairo_rectangle (cr, x0, y0 + 1, x1 - x0, y1 - y0 - 2);
+ cairo_fill (cr);
+ pgtk_set_cr_source_with_color (f, color_last);
+ cairo_rectangle (cr, x0, y1 - 1, x1 - x0, 1);
+ cairo_fill (cr);
+ }
+ else
+ {
+ pgtk_set_cr_source_with_color (f, color);
+ cairo_rectangle (cr, x0, y0, x1 - x0, y1 - y0);
+ cairo_fill (cr);
+ }
+
+ pgtk_end_cr_clip (f);
+}
+
+/* End update of frame F. This function is installed as a hook in
+ update_end. */
+
+static void
+pgtk_update_end (struct frame *f)
+{
+ /* Mouse highlight may be displayed again. */
+ MOUSE_HL_INFO (f)->mouse_face_defer = false;
+}
+
+static void
+pgtk_frame_up_to_date (struct frame *f)
+{
+ block_input ();
+ FRAME_MOUSE_UPDATE (f);
+ if (!buffer_flipping_blocked_p ())
+ {
+ flip_cr_context (f);
+ gtk_widget_queue_draw (FRAME_GTK_WIDGET (f));
+ }
+ unblock_input ();
+}
+
+/* Return the current position of the mouse.
+ *FP should be a frame which indicates which display to ask about.
+
+ If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
+ and *PART to the frame, window, and scroll bar part that the mouse
+ is over. Set *X and *Y to the portion and whole of the mouse's
+ position on the scroll bar.
+
+ If the mouse movement started elsewhere, set *FP to the frame the
+ mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
+ the mouse is over.
+
+ Set *TIMESTAMP to the server time-stamp for the time at which the mouse
+ was at this position.
+
+ Don't store anything if we don't have a valid set of values to report.
+
+ This clears the mouse_moved flag, so we can wait for the next mouse
+ movement. */
+
+static void
+pgtk_mouse_position (struct frame **fp, int insist, Lisp_Object * bar_window,
+ enum scroll_bar_part *part, Lisp_Object * x,
+ Lisp_Object * y, Time * timestamp)
+{
+ struct frame *f1;
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
+ int win_x, win_y;
+ GdkSeat *seat;
+ GdkDevice *device;
+ GdkModifierType mask;
+ GdkWindow *win;
+
+ block_input ();
+
+ Lisp_Object frame, tail;
+
+ /* Clear the mouse-moved flag for every frame on this display. */
+ FOR_EACH_FRAME (tail, frame)
+ if (FRAME_PGTK_P (XFRAME (frame))
+ && FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
+ XFRAME (frame)->mouse_moved = false;
+
+ dpyinfo->last_mouse_scroll_bar = NULL;
+
+ if (gui_mouse_grabbed (dpyinfo))
+ {
+ /* 1.1. use last_mouse_frame as frame where the pointer is on. */
+ f1 = dpyinfo->last_mouse_frame;
+ }
+ else
+ {
+ f1 = *fp;
+ /* 1.2. get frame where the pointer is on. */
+ win = gtk_widget_get_window (FRAME_GTK_WIDGET (*fp));
+ seat = gdk_display_get_default_seat (dpyinfo->gdpy);
+ device = gdk_seat_get_pointer (seat);
+ win =
+ gdk_window_get_device_position (win, device, &win_x, &win_y, &mask);
+ if (win != NULL)
+ f1 = pgtk_any_window_to_frame (win);
+ else
+ {
+ /* crossing display server? */
+ f1 = SELECTED_FRAME ();
+ }
+ }
+
+ /* f1 can be a terminal frame. Bug#50322 */
+ if (f1 == NULL || !FRAME_PGTK_P (f1))
+ {
+ unblock_input ();
+ return;
+ }
+
+ /* 2. get the display and the device. */
+ win = gtk_widget_get_window (FRAME_GTK_WIDGET (f1));
+ GdkDisplay *gdpy = gdk_window_get_display (win);
+ seat = gdk_display_get_default_seat (gdpy);
+ device = gdk_seat_get_pointer (seat);
+
+ /* 3. get x, y relative to edit window of the frame. */
+ win = gdk_window_get_device_position (win, device, &win_x, &win_y, &mask);
+
+ if (f1 != NULL)
+ {
+ dpyinfo = FRAME_DISPLAY_INFO (f1);
+ remember_mouse_glyph (f1, win_x, win_y, &dpyinfo->last_mouse_glyph);
+ dpyinfo->last_mouse_glyph_frame = f1;
+
+ *bar_window = Qnil;
+ *part = 0;
+ *fp = f1;
+ XSETINT (*x, win_x);
+ XSETINT (*y, win_y);
+ *timestamp = dpyinfo->last_mouse_movement_time;
+ }
+
+ unblock_input ();
+}
+
+/* Fringe bitmaps. */
+
+static int max_fringe_bmp = 0;
+static cairo_pattern_t **fringe_bmp = 0;
+
+static void
+pgtk_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
+{
+ int i, stride;
+ cairo_surface_t *surface;
+ unsigned char *data;
+ cairo_pattern_t *pattern;
+
+ if (which >= max_fringe_bmp)
+ {
+ i = max_fringe_bmp;
+ max_fringe_bmp = which + 20;
+ fringe_bmp =
+ (cairo_pattern_t **) xrealloc (fringe_bmp,
+ max_fringe_bmp *
+ sizeof (cairo_pattern_t *));
+ while (i < max_fringe_bmp)
+ fringe_bmp[i++] = 0;
+ }
+
+ block_input ();
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_A1, wd, h);
+ stride = cairo_image_surface_get_stride (surface);
+ data = cairo_image_surface_get_data (surface);
+
+ for (i = 0; i < h; i++)
+ {
+ *((unsigned short *) data) = bits[i];
+ data += stride;
+ }
+
+ cairo_surface_mark_dirty (surface);
+ pattern = cairo_pattern_create_for_surface (surface);
+ cairo_surface_destroy (surface);
+
+ unblock_input ();
+
+ fringe_bmp[which] = pattern;
+}
+
+static void
+pgtk_destroy_fringe_bitmap (int which)
+{
+ if (which >= max_fringe_bmp)
+ return;
+
+ if (fringe_bmp[which])
+ {
+ block_input ();
+ cairo_pattern_destroy (fringe_bmp[which]);
+ unblock_input ();
+ }
+ fringe_bmp[which] = 0;
+}
+
+static void
+pgtk_clip_to_row (struct window *w, struct glyph_row *row,
+ enum glyph_row_area area, cairo_t * cr)
+{
+ int window_x, window_y, window_width;
+ cairo_rectangle_int_t rect;
+
+ window_box (w, area, &window_x, &window_y, &window_width, 0);
+
+ rect.x = window_x;
+ rect.y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y));
+ rect.y = max (rect.y, window_y);
+ rect.width = window_width;
+ rect.height = row->visible_height;
+
+ cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height);
+ cairo_clip (cr);
+}
+
+static void
+pgtk_cr_draw_image (struct frame *f, Emacs_GC * gc, cairo_pattern_t * image,
+ int src_x, int src_y, int width, int height,
+ int dest_x, int dest_y, bool overlay_p)
+{
+ cairo_t *cr = pgtk_begin_cr_clip (f);
+
+ if (overlay_p)
+ cairo_rectangle (cr, dest_x, dest_y, width, height);
+ else
+ {
+ pgtk_set_cr_source_with_gc_background (f, gc);
+ cairo_rectangle (cr, dest_x, dest_y, width, height);
+ cairo_fill_preserve (cr);
+ }
+ cairo_translate (cr, dest_x - src_x, dest_y - src_y);
+
+ cairo_surface_t *surface;
+ cairo_pattern_get_surface (image, &surface);
+ cairo_format_t format = cairo_image_surface_get_format (surface);
+ if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
+ {
+ cairo_set_source (cr, image);
+ cairo_fill (cr);
+ }
+ else
+ {
+ pgtk_set_cr_source_with_gc_foreground (f, gc);
+ cairo_clip (cr);
+ cairo_mask (cr, image);
+ }
+
+ pgtk_end_cr_clip (f);
+}
+
+static void
+pgtk_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
+ struct draw_fringe_bitmap_params *p)
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+ struct face *face = p->face;
+
+ cairo_t *cr = pgtk_begin_cr_clip (f);
+
+ /* Must clip because of partially visible lines. */
+ pgtk_clip_to_row (w, row, ANY_AREA, cr);
+
+ if (p->bx >= 0 && !p->overlay_p)
+ {
+ /* In case the same realized face is used for fringes and
+ for something displayed in the text (e.g. face `region' on
+ mono-displays, the fill style may have been changed to
+ FillSolid in x_draw_glyph_string_background. */
+ if (face->stipple)
+ {
+ fill_background_by_face (f, face, p->bx, p->by, p->nx, p->ny);
+ }
+ else
+ {
+ pgtk_set_cr_source_with_color (f, face->background);
+ cairo_rectangle (cr, p->bx, p->by, p->nx, p->ny);
+ cairo_fill (cr);
+ }
+ }
+
+ if (p->which && p->which < max_fringe_bmp)
+ {
+ Emacs_GC gcv;
+
+ gcv.foreground = (p->cursor_p
+ ? (p->overlay_p ? face->background
+ : FRAME_X_OUTPUT (f)->cursor_color)
+ : face->foreground);
+ gcv.background = face->background;
+ pgtk_cr_draw_image (f, &gcv, fringe_bmp[p->which], 0, p->dh,
+ p->wd, p->h, p->x, p->y, p->overlay_p);
+ }
+
+ pgtk_end_cr_clip (f);
+}
+
+static struct atimer *hourglass_atimer = NULL;
+static int hourglass_enter_count = 0;
+
+static void
+hourglass_cb (struct atimer *timer)
+{
+ /*NOP*/}
+
+static void
+pgtk_show_hourglass (struct frame *f)
+{
+ struct pgtk_output *x = FRAME_X_OUTPUT (f);
+ if (x->hourglass_widget != NULL)
+ gtk_widget_destroy (x->hourglass_widget);
+ x->hourglass_widget = gtk_event_box_new (); /* gtk_event_box is GDK_INPUT_ONLY. */
+ gtk_widget_set_has_window (x->hourglass_widget, true);
+ gtk_fixed_put (GTK_FIXED (FRAME_GTK_WIDGET (f)), x->hourglass_widget, 0, 0);
+ gtk_widget_show (x->hourglass_widget);
+ gtk_widget_set_size_request (x->hourglass_widget, 30000, 30000);
+ gdk_window_raise (gtk_widget_get_window (x->hourglass_widget));
+ gdk_window_set_cursor (gtk_widget_get_window (x->hourglass_widget),
+ x->hourglass_cursor);
+
+ /* For cursor animation, we receive signals, set pending_signals, and dispatch. */
+ if (hourglass_enter_count++ == 0)
+ {
+ struct timespec ts = make_timespec (0, 50 * 1000 * 1000);
+ if (hourglass_atimer != NULL)
+ cancel_atimer (hourglass_atimer);
+ hourglass_atimer =
+ start_atimer (ATIMER_CONTINUOUS, ts, hourglass_cb, NULL);
+ }
+
+ /* Cursor frequently stops animation. gtk's bug? */
+}
+
+static void
+pgtk_hide_hourglass (struct frame *f)
+{
+ struct pgtk_output *x = FRAME_X_OUTPUT (f);
+ if (--hourglass_enter_count == 0)
+ {
+ if (hourglass_atimer != NULL)
+ {
+ cancel_atimer (hourglass_atimer);
+ hourglass_atimer = NULL;
+ }
+ }
+ if (x->hourglass_widget != NULL)
+ {
+ gtk_widget_destroy (x->hourglass_widget);
+ x->hourglass_widget = NULL;
+ }
+}
+
+/* Flushes changes to display. */
+static void
+pgtk_flush_display (struct frame *f)
+{
+}
+
+extern frame_parm_handler pgtk_frame_parm_handlers[];
+
+static struct redisplay_interface pgtk_redisplay_interface = {
+ pgtk_frame_parm_handlers,
+ gui_produce_glyphs,
+ gui_write_glyphs,
+ gui_insert_glyphs,
+ gui_clear_end_of_line,
+ pgtk_scroll_run,
+ pgtk_after_update_window_line,
+ NULL, /* gui_update_window_begin, */
+ NULL, /* gui_update_window_end, */
+ pgtk_flush_display,
+ gui_clear_window_mouse_face,
+ gui_get_glyph_overhangs,
+ gui_fix_overlapping_area,
+ pgtk_draw_fringe_bitmap,
+ pgtk_define_fringe_bitmap,
+ pgtk_destroy_fringe_bitmap,
+ pgtk_compute_glyph_string_overhangs,
+ pgtk_draw_glyph_string,
+ pgtk_define_frame_cursor,
+ pgtk_clear_frame_area,
+ pgtk_clear_under_internal_border,
+ pgtk_draw_window_cursor,
+ pgtk_draw_vertical_window_border,
+ pgtk_draw_window_divider,
+ NULL, /* pgtk_shift_glyphs_for_insert, */
+ pgtk_show_hourglass,
+ pgtk_hide_hourglass,
+ pgtk_default_font_parameter,
+};
+
+static void
+pgtk_redraw_scroll_bars (struct frame *f)
+{
+}
+
+void
+pgtk_clear_frame (struct frame *f)
+/* --------------------------------------------------------------------------
+ External (hook): Erase the entire frame
+ -------------------------------------------------------------------------- */
+{
+ /* comes on initial frame because we have
+ after-make-frame-functions = select-frame */
+ if (!FRAME_DEFAULT_FACE (f))
+ return;
+
+ /* mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f))); */
+
+ block_input ();
+
+ pgtk_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+
+ /* as of 2006/11 or so this is now needed */
+ pgtk_redraw_scroll_bars (f);
+ unblock_input ();
+}
+
+/* Invert the middle quarter of the frame for .15 sec. */
+
+static void
+recover_from_visible_bell (struct atimer *timer)
+{
+ struct frame *f = timer->client_data;
+
+ if (FRAME_X_OUTPUT (f)->cr_surface_visible_bell != NULL)
+ {
+ cairo_surface_destroy (FRAME_X_OUTPUT (f)->cr_surface_visible_bell);
+ FRAME_X_OUTPUT (f)->cr_surface_visible_bell = NULL;
+ }
+
+ if (FRAME_X_OUTPUT (f)->atimer_visible_bell != NULL)
+ FRAME_X_OUTPUT (f)->atimer_visible_bell = NULL;
+}
+
+static void
+pgtk_flash (struct frame *f)
+{
+ block_input ();
+
+ {
+ cairo_surface_t *surface_orig = FRAME_CR_SURFACE (f);
+
+ int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f);
+ int height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f);
+ cairo_surface_t *surface =
+ cairo_surface_create_similar (surface_orig, CAIRO_CONTENT_COLOR_ALPHA,
+ width, height);
+
+ cairo_t *cr = cairo_create (surface);
+ cairo_set_source_surface (cr, surface_orig, 0, 0);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_clip (cr);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
+
+ {
+ /* Get the height not including a menu bar widget. */
+ int height = FRAME_PIXEL_HEIGHT (f);
+ /* Height of each line to flash. */
+ int flash_height = FRAME_LINE_HEIGHT (f);
+ /* These will be the left and right margins of the rectangles. */
+ int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
+ int flash_right =
+ FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
+ int width = flash_right - flash_left;
+
+ /* If window is tall, flash top and bottom line. */
+ if (height > 3 * FRAME_LINE_HEIGHT (f))
+ {
+ cairo_rectangle (cr,
+ flash_left,
+ (FRAME_INTERNAL_BORDER_WIDTH (f)
+ + FRAME_TOP_MARGIN_HEIGHT (f)),
+ width, flash_height);
+ cairo_fill (cr);
+
+ cairo_rectangle (cr,
+ flash_left,
+ (height - flash_height
+ - FRAME_INTERNAL_BORDER_WIDTH (f)),
+ width, flash_height);
+ cairo_fill (cr);
+ }
+ else
+ {
+ /* If it is short, flash it all. */
+ cairo_rectangle (cr,
+ flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
+ width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
+ cairo_fill (cr);
+ }
+
+ FRAME_X_OUTPUT (f)->cr_surface_visible_bell = surface;
+ {
+ struct timespec delay = make_timespec (0, 50 * 1000 * 1000);
+ if (FRAME_X_OUTPUT (f)->atimer_visible_bell != NULL)
+ {
+ cancel_atimer (FRAME_X_OUTPUT (f)->atimer_visible_bell);
+ FRAME_X_OUTPUT (f)->atimer_visible_bell = NULL;
+ }
+ FRAME_X_OUTPUT (f)->atimer_visible_bell =
+ start_atimer (ATIMER_RELATIVE, delay, recover_from_visible_bell, f);
+ }
+
+ }
+
+ cairo_destroy (cr);
+ }
+
+ unblock_input ();
+}
+
+/* Make audible bell. */
+
+static void
+pgtk_ring_bell (struct frame *f)
+{
+ if (visible_bell)
+ {
+ pgtk_flash (f);
+ }
+ else
+ {
+ block_input ();
+ gtk_widget_error_bell (FRAME_GTK_WIDGET (f));
+ unblock_input ();
+ }
+}
+
+/* Read events coming from the X server.
+ Return as soon as there are no more events to be read.
+
+ Return the number of characters stored into the buffer,
+ thus pretending to be `read' (except the characters we store
+ in the keyboard buffer can be multibyte, so are not necessarily
+ C chars). */
+
+static int
+pgtk_read_socket (struct terminal *terminal, struct input_event *hold_quit)
+{
+ GMainContext *context;
+ bool context_acquired = false;
+ int count;
+
+ count = evq_flush (hold_quit);
+ if (count > 0)
+ {
+ return count;
+ }
+
+ context = g_main_context_default ();
+ context_acquired = g_main_context_acquire (context);
+
+ block_input ();
+
+ if (context_acquired)
+ {
+ while (g_main_context_pending (context))
+ {
+ g_main_context_dispatch (context);
+ }
+ }
+
+ unblock_input ();
+
+ if (context_acquired)
+ g_main_context_release (context);
+
+ count = evq_flush (hold_quit);
+ if (count > 0)
+ {
+ return count;
+ }
+
+ return 0;
+}
+
+/* Lisp window being scrolled. Set when starting to interact with
+ a toolkit scroll bar, reset to nil when ending the interaction. */
+
+static Lisp_Object window_being_scrolled;
+
+static void
+pgtk_send_scroll_bar_event (Lisp_Object window, enum scroll_bar_part part,
+ int portion, int whole, bool horizontal)
+{
+ union buffered_input_event inev;
+
+ EVENT_INIT (inev.ie);
+
+ inev.ie.kind =
+ horizontal ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT : SCROLL_BAR_CLICK_EVENT;
+ inev.ie.frame_or_window = window;
+ inev.ie.arg = Qnil;
+ inev.ie.timestamp = 0;
+ inev.ie.code = 0;
+ inev.ie.part = part;
+ inev.ie.x = make_fixnum (portion);
+ inev.ie.y = make_fixnum (whole);
+ inev.ie.modifiers = 0;
+
+ evq_enqueue (&inev);
+}
+
+
+/* Scroll bar callback for GTK scroll bars. WIDGET is the scroll
+ bar widget. DATA is a pointer to the scroll_bar structure. */
+
+static gboolean
+xg_scroll_callback (GtkRange * range,
+ GtkScrollType scroll, gdouble value, gpointer user_data)
+{
+ int whole = 0, portion = 0;
+ struct scroll_bar *bar = user_data;
+ enum scroll_bar_part part = scroll_bar_nowhere;
+ GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range));
+
+ if (xg_ignore_gtk_scrollbar)
+ return false;
+
+ switch (scroll)
+ {
+ case GTK_SCROLL_JUMP:
+#if 0
+ /* Buttons 1 2 or 3 must be grabbed. */
+ if (FRAME_DISPLAY_INFO (f)->grabbed != 0
+ && FRAME_DISPLAY_INFO (f)->grabbed < (1 << 4))
+#endif
+ {
+ if (bar->horizontal)
+ {
+ part = scroll_bar_horizontal_handle;
+ whole = (int) (gtk_adjustment_get_upper (adj) -
+ gtk_adjustment_get_page_size (adj));
+ portion = min ((int) value, whole);
+ bar->dragging = portion;
+ }
+ else
+ {
+ part = scroll_bar_handle;
+ whole = gtk_adjustment_get_upper (adj) -
+ gtk_adjustment_get_page_size (adj);
+ portion = min ((int) value, whole);
+ bar->dragging = portion;
+ }
+ }
+ break;
+ case GTK_SCROLL_STEP_BACKWARD:
+ part = (bar->horizontal ? scroll_bar_left_arrow : scroll_bar_up_arrow);
+ bar->dragging = -1;
+ break;
+ case GTK_SCROLL_STEP_FORWARD:
+ part = (bar->horizontal
+ ? scroll_bar_right_arrow : scroll_bar_down_arrow);
+ bar->dragging = -1;
+ break;
+ case GTK_SCROLL_PAGE_BACKWARD:
+ part = (bar->horizontal
+ ? scroll_bar_before_handle : scroll_bar_above_handle);
+ bar->dragging = -1;
+ break;
+ case GTK_SCROLL_PAGE_FORWARD:
+ part = (bar->horizontal
+ ? scroll_bar_after_handle : scroll_bar_below_handle);
+ bar->dragging = -1;
+ break;
+ default:
+ break;
+ }
+
+ if (part != scroll_bar_nowhere)
+ {
+ window_being_scrolled = bar->window;
+ pgtk_send_scroll_bar_event (bar->window, part, portion, whole,
+ bar->horizontal);
+ }
+
+ return false;
+}
+
+/* Callback for button release. Sets dragging to -1 when dragging is done. */
+
+static gboolean
+xg_end_scroll_callback (GtkWidget * widget,
+ GdkEventButton * event, gpointer user_data)
+{
+ struct scroll_bar *bar = user_data;
+ bar->dragging = -1;
+ if (WINDOWP (window_being_scrolled))
+ {
+ pgtk_send_scroll_bar_event (window_being_scrolled,
+ scroll_bar_end_scroll, 0, 0,
+ bar->horizontal);
+ window_being_scrolled = Qnil;
+ }
+
+ return false;
+}
+
+#define SCROLL_BAR_NAME "verticalScrollBar"
+#define SCROLL_BAR_HORIZONTAL_NAME "horizontalScrollBar"
+
+/* Create the widget for scroll bar BAR on frame F. Record the widget
+ and X window of the scroll bar in BAR. */
+
+static void
+x_create_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
+{
+ const char *scroll_bar_name = SCROLL_BAR_NAME;
+
+ block_input ();
+ xg_create_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
+ G_CALLBACK (xg_end_scroll_callback), scroll_bar_name);
+ unblock_input ();
+}
+
+static void
+x_create_horizontal_toolkit_scroll_bar (struct frame *f,
+ struct scroll_bar *bar)
+{
+ const char *scroll_bar_name = SCROLL_BAR_HORIZONTAL_NAME;
+
+ block_input ();
+ xg_create_horizontal_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
+ G_CALLBACK (xg_end_scroll_callback),
+ scroll_bar_name);
+ unblock_input ();
+}
+
+/* Set the thumb size and position of scroll bar BAR. We are currently
+ displaying PORTION out of a whole WHOLE, and our position POSITION. */
+
+static void
+x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion,
+ int position, int whole)
+{
+ xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
+}
+
+static void
+x_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar,
+ int portion, int position,
+ int whole)
+{
+ xg_set_toolkit_horizontal_scroll_bar_thumb (bar, portion, position, whole);
+}
+
+
+
+/* Create a scroll bar and return the scroll bar vector for it. W is
+ the Emacs window on which to create the scroll bar. TOP, LEFT,
+ WIDTH and HEIGHT are the pixel coordinates and dimensions of the
+ scroll bar. */
+
+static struct scroll_bar *
+x_scroll_bar_create (struct window *w, int top, int left,
+ int width, int height, bool horizontal)
+{
+ struct frame *f = XFRAME (w->frame);
+ struct scroll_bar *bar
+ = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, prev, PVEC_OTHER);
+ Lisp_Object barobj;
+
+ block_input ();
+
+ if (horizontal)
+ x_create_horizontal_toolkit_scroll_bar (f, bar);
+ else
+ x_create_toolkit_scroll_bar (f, bar);
+
+ XSETWINDOW (bar->window, w);
+ bar->top = top;
+ bar->left = left;
+ bar->width = width;
+ bar->height = height;
+ bar->start = 0;
+ bar->end = 0;
+ bar->dragging = -1;
+ bar->horizontal = horizontal;
+
+ /* Add bar to its frame's list of scroll bars. */
+ bar->next = FRAME_SCROLL_BARS (f);
+ bar->prev = Qnil;
+ XSETVECTOR (barobj, bar);
+ fset_scroll_bars (f, barobj);
+ if (!NILP (bar->next))
+ XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
+
+ /* Map the window/widget. */
+ {
+ if (horizontal)
+ xg_update_horizontal_scrollbar_pos (f, bar->x_window, top,
+ left, width, max (height, 1));
+ else
+ xg_update_scrollbar_pos (f, bar->x_window, top,
+ left, width, max (height, 1));
+ }
+
+ unblock_input ();
+ return bar;
+}
+
+/* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
+ nil. */
+
+static void
+x_scroll_bar_remove (struct scroll_bar *bar)
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+ block_input ();
+
+ xg_remove_scroll_bar (f, bar->x_window);
+
+ /* Dissociate this scroll bar from its window. */
+ if (bar->horizontal)
+ wset_horizontal_scroll_bar (XWINDOW (bar->window), Qnil);
+ else
+ wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
+
+ unblock_input ();
+}
+
+/* Set the handle of the vertical scroll bar for WINDOW to indicate
+ that we are displaying PORTION characters out of a total of WHOLE
+ characters, starting at POSITION. If WINDOW has no scroll bar,
+ create one. */
+
+static void
+pgtk_set_vertical_scroll_bar (struct window *w, int portion, int whole,
+ int position)
+{
+ struct frame *f = XFRAME (w->frame);
+ Lisp_Object barobj;
+ struct scroll_bar *bar;
+ int top, height, left, width;
+ int window_y, window_height;
+
+ /* Get window dimensions. */
+ window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
+ top = window_y;
+ height = window_height;
+ left = WINDOW_SCROLL_BAR_AREA_X (w);
+ width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
+
+ /* Does the scroll bar exist yet? */
+ if (NILP (w->vertical_scroll_bar))
+ {
+ if (width > 0 && height > 0)
+ {
+ block_input ();
+ pgtk_clear_area (f, left, top, width, height);
+ unblock_input ();
+ }
+
+ bar = x_scroll_bar_create (w, top, left, width, max (height, 1), false);
+ }
+ else
+ {
+ /* It may just need to be moved and resized. */
+ unsigned int mask = 0;
+
+ bar = XSCROLL_BAR (w->vertical_scroll_bar);
+
+ block_input ();
+
+ if (left != bar->left)
+ mask |= 1;
+ if (top != bar->top)
+ mask |= 1;
+ if (width != bar->width)
+ mask |= 1;
+ if (height != bar->height)
+ mask |= 1;
+
+ /* Move/size the scroll bar widget. */
+ if (mask)
+ {
+ /* Since toolkit scroll bars are smaller than the space reserved
+ for them on the frame, we have to clear "under" them. */
+ if (width > 0 && height > 0)
+ pgtk_clear_area (f, left, top, width, height);
+ xg_update_scrollbar_pos (f, bar->x_window, top,
+ left, width, max (height, 1));
+ }
+
+ /* Remember new settings. */
+ bar->left = left;
+ bar->top = top;
+ bar->width = width;
+ bar->height = height;
+
+ unblock_input ();
+ }
+
+ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
+
+ XSETVECTOR (barobj, bar);
+ wset_vertical_scroll_bar (w, barobj);
+}
+
+
+static void
+pgtk_set_horizontal_scroll_bar (struct window *w, int portion, int whole,
+ int position)
+{
+ struct frame *f = XFRAME (w->frame);
+ Lisp_Object barobj;
+ struct scroll_bar *bar;
+ int top, height, left, width;
+ int window_x, window_width;
+ int pixel_width = WINDOW_PIXEL_WIDTH (w);
+
+ /* Get window dimensions. */
+ window_box (w, ANY_AREA, &window_x, 0, &window_width, 0);
+ left = window_x;
+ width = window_width;
+ top = WINDOW_SCROLL_BAR_AREA_Y (w);
+ height = WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
+
+ /* Does the scroll bar exist yet? */
+ if (NILP (w->horizontal_scroll_bar))
+ {
+ if (width > 0 && height > 0)
+ {
+ block_input ();
+
+ /* Clear also part between window_width and
+ WINDOW_PIXEL_WIDTH. */
+ pgtk_clear_area (f, left, top, pixel_width, height);
+ unblock_input ();
+ }
+
+ bar = x_scroll_bar_create (w, top, left, width, height, true);
+ }
+ else
+ {
+ /* It may just need to be moved and resized. */
+ unsigned int mask = 0;
+
+ bar = XSCROLL_BAR (w->horizontal_scroll_bar);
+
+ block_input ();
+
+ if (left != bar->left)
+ mask |= 1;
+ if (top != bar->top)
+ mask |= 1;
+ if (width != bar->width)
+ mask |= 1;
+ if (height != bar->height)
+ mask |= 1;
+
+ /* Move/size the scroll bar widget. */
+ if (mask)
+ {
+ /* Since toolkit scroll bars are smaller than the space reserved
+ for them on the frame, we have to clear "under" them. */
+ if (width > 0 && height > 0)
+ pgtk_clear_area (f,
+ WINDOW_LEFT_EDGE_X (w), top,
+ pixel_width - WINDOW_RIGHT_DIVIDER_WIDTH (w),
+ height);
+ xg_update_horizontal_scrollbar_pos (f, bar->x_window, top, left,
+ width, height);
+ }
+
+ /* Remember new settings. */
+ bar->left = left;
+ bar->top = top;
+ bar->width = width;
+ bar->height = height;
+
+ unblock_input ();
+ }
+
+ x_set_toolkit_horizontal_scroll_bar_thumb (bar, portion, position, whole);
+
+ XSETVECTOR (barobj, bar);
+ wset_horizontal_scroll_bar (w, barobj);
+}
+
+/* The following three hooks are used when we're doing a thorough
+ redisplay of the frame. We don't explicitly know which scroll bars
+ are going to be deleted, because keeping track of when windows go
+ away is a real pain - "Can you say set-window-configuration, boys
+ and girls?" Instead, we just assert at the beginning of redisplay
+ that *all* scroll bars are to be removed, and then save a scroll bar
+ from the fiery pit when we actually redisplay its window. */
+
+/* Arrange for all scroll bars on FRAME to be removed at the next call
+ to `*judge_scroll_bars_hook'. A scroll bar may be spared if
+ `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
+
+static void
+pgtk_condemn_scroll_bars (struct frame *frame)
+{
+ if (!NILP (FRAME_SCROLL_BARS (frame)))
+ {
+ if (!NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
+ {
+ /* Prepend scrollbars to already condemned ones. */
+ Lisp_Object last = FRAME_SCROLL_BARS (frame);
+
+ while (!NILP (XSCROLL_BAR (last)->next))
+ last = XSCROLL_BAR (last)->next;
+
+ XSCROLL_BAR (last)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
+ XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = last;
+ }
+
+ fset_condemned_scroll_bars (frame, FRAME_SCROLL_BARS (frame));
+ fset_scroll_bars (frame, Qnil);
+ }
+}
+
+
+/* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
+ Note that WINDOW isn't necessarily condemned at all. */
+
+static void
+pgtk_redeem_scroll_bar (struct window *w)
+{
+ struct scroll_bar *bar;
+ Lisp_Object barobj;
+ struct frame *f;
+
+ /* We can't redeem this window's scroll bar if it doesn't have one. */
+ if (NILP (w->vertical_scroll_bar) && NILP (w->horizontal_scroll_bar))
+ emacs_abort ();
+
+ if (!NILP (w->vertical_scroll_bar) && WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
+ {
+ bar = XSCROLL_BAR (w->vertical_scroll_bar);
+ /* Unlink it from the condemned list. */
+ f = XFRAME (WINDOW_FRAME (w));
+ if (NILP (bar->prev))
+ {
+ /* If the prev pointer is nil, it must be the first in one of
+ the lists. */
+ if (EQ (FRAME_SCROLL_BARS (f), w->vertical_scroll_bar))
+ /* It's not condemned. Everything's fine. */
+ goto horizontal;
+ else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
+ w->vertical_scroll_bar))
+ fset_condemned_scroll_bars (f, bar->next);
+ else
+ /* If its prev pointer is nil, it must be at the front of
+ one or the other! */
+ emacs_abort ();
+ }
+ else
+ XSCROLL_BAR (bar->prev)->next = bar->next;
+
+ if (!NILP (bar->next))
+ XSCROLL_BAR (bar->next)->prev = bar->prev;
+
+ bar->next = FRAME_SCROLL_BARS (f);
+ bar->prev = Qnil;
+ XSETVECTOR (barobj, bar);
+ fset_scroll_bars (f, barobj);
+ if (!NILP (bar->next))
+ XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
+ }
+
+horizontal:
+ if (!NILP (w->horizontal_scroll_bar)
+ && WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
+ {
+ bar = XSCROLL_BAR (w->horizontal_scroll_bar);
+ /* Unlink it from the condemned list. */
+ f = XFRAME (WINDOW_FRAME (w));
+ if (NILP (bar->prev))
+ {
+ /* If the prev pointer is nil, it must be the first in one of
+ the lists. */
+ if (EQ (FRAME_SCROLL_BARS (f), w->horizontal_scroll_bar))
+ /* It's not condemned. Everything's fine. */
+ return;
+ else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
+ w->horizontal_scroll_bar))
+ fset_condemned_scroll_bars (f, bar->next);
+ else
+ /* If its prev pointer is nil, it must be at the front of
+ one or the other! */
+ emacs_abort ();
+ }
+ else
+ XSCROLL_BAR (bar->prev)->next = bar->next;
+
+ if (!NILP (bar->next))
+ XSCROLL_BAR (bar->next)->prev = bar->prev;
+
+ bar->next = FRAME_SCROLL_BARS (f);
+ bar->prev = Qnil;
+ XSETVECTOR (barobj, bar);
+ fset_scroll_bars (f, barobj);
+ if (!NILP (bar->next))
+ XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
+ }
+}
+
+/* Remove all scroll bars on FRAME that haven't been saved since the
+ last call to `*condemn_scroll_bars_hook'. */
+
+static void
+pgtk_judge_scroll_bars (struct frame *f)
+{
+ Lisp_Object bar, next;
+
+ bar = FRAME_CONDEMNED_SCROLL_BARS (f);
+
+ /* Clear out the condemned list now so we won't try to process any
+ more events on the hapless scroll bars. */
+ fset_condemned_scroll_bars (f, Qnil);
+
+ for (; !NILP (bar); bar = next)
+ {
+ struct scroll_bar *b = XSCROLL_BAR (bar);
+
+ x_scroll_bar_remove (b);
+
+ next = b->next;
+ b->next = b->prev = Qnil;
+ }
+
+ /* Now there should be no references to the condemned scroll bars,
+ and they should get garbage-collected. */
+}
+
+static void
+set_fullscreen_state (struct frame *f)
+{
+ if (!FRAME_GTK_OUTER_WIDGET (f))
+ return;
+
+ GtkWindow *widget = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f));
+ switch (f->want_fullscreen)
+ {
+ case FULLSCREEN_NONE:
+ gtk_window_unfullscreen (widget);
+ gtk_window_unmaximize (widget);
+ store_frame_param (f, Qfullscreen, Qnil);
+ break;
+
+ case FULLSCREEN_BOTH:
+ gtk_window_unmaximize (widget);
+ gtk_window_fullscreen (widget);
+ store_frame_param (f, Qfullscreen, Qfullboth);
+ break;
+
+ case FULLSCREEN_MAXIMIZED:
+ gtk_window_unfullscreen (widget);
+ gtk_window_maximize (widget);
+ store_frame_param (f, Qfullscreen, Qmaximized);
+ break;
+
+ case FULLSCREEN_WIDTH:
+ case FULLSCREEN_HEIGHT:
+ /* Not supported by gtk. Ignore them. */
+ break;
+ }
+
+ f->want_fullscreen = FULLSCREEN_NONE;
+}
+
+static void
+pgtk_fullscreen_hook (struct frame *f)
+{
+ if (FRAME_VISIBLE_P (f))
+ {
+ block_input ();
+ set_fullscreen_state (f);
+ unblock_input ();
+ }
+}
+
+/* This function is called when the last frame on a display is deleted. */
+void
+pgtk_delete_terminal (struct terminal *terminal)
+{
+ struct pgtk_display_info *dpyinfo = terminal->display_info.pgtk;
+
+ /* Protect against recursive calls. delete_frame in
+ delete_terminal calls us back when it deletes our last frame. */
+ if (!terminal->name)
+ return;
+
+ block_input ();
+
+ pgtk_im_finish (dpyinfo);
+
+ /* Normally, the display is available... */
+ if (dpyinfo->gdpy)
+ {
+ image_destroy_all_bitmaps (dpyinfo);
+
+ g_clear_object (&dpyinfo->xg_cursor);
+ g_clear_object (&dpyinfo->vertical_scroll_bar_cursor);
+ g_clear_object (&dpyinfo->horizontal_scroll_bar_cursor);
+ g_clear_object (&dpyinfo->invisible_cursor);
+ if (dpyinfo->last_click_event != NULL) {
+ gdk_event_free (dpyinfo->last_click_event);
+ dpyinfo->last_click_event = NULL;
+ }
+
+ xg_display_close (dpyinfo->gdpy);
+
+ /* Do not close the connection here because it's already closed
+ by X(t)CloseDisplay (Bug#18403). */
+ dpyinfo->gdpy = NULL;
+ }
+
+ if (dpyinfo->connection >= 0)
+ emacs_close (dpyinfo->connection);
+
+ dpyinfo->connection = -1;
+
+ delete_keyboard_wait_descriptor (0);
+
+ pgtk_delete_display (dpyinfo);
+ unblock_input ();
+}
+
+/* Store F's background color into *BGCOLOR. */
+static void
+pgtk_query_frame_background_color (struct frame *f, Emacs_Color * bgcolor)
+{
+ bgcolor->pixel = FRAME_BACKGROUND_PIXEL (f);
+ pgtk_query_color (f, bgcolor);
+}
+
+static void
+pgtk_free_pixmap (struct frame *_f, Emacs_Pixmap pixmap)
+{
+ if (pixmap)
+ {
+ xfree (pixmap->data);
+ xfree (pixmap);
+ }
+}
+
+void
+pgtk_focus_frame (struct frame *f, bool noactivate)
+{
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+
+ GtkWidget *wid = FRAME_WIDGET (f);
+
+ if (dpyinfo->x_focus_frame != f && wid != NULL)
+ {
+ block_input ();
+ gtk_widget_grab_focus (wid);
+ unblock_input ();
+ }
+}
+
+
+static void
+set_opacity_recursively (GtkWidget * w, gpointer data)
+{
+ gtk_widget_set_opacity (w, *(double *) data);
+ if (GTK_IS_CONTAINER (w))
+ gtk_container_foreach (GTK_CONTAINER (w), set_opacity_recursively, data);
+}
+
+static void
+x_set_frame_alpha (struct frame *f)
+{
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+ double alpha = 1.0;
+ double alpha_min = 1.0;
+
+ if (dpyinfo->highlight_frame == f)
+ alpha = f->alpha[0];
+ else
+ alpha = f->alpha[1];
+
+ if (alpha < 0.0)
+ return;
+
+ if (FLOATP (Vframe_alpha_lower_limit))
+ alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
+ else if (FIXNUMP (Vframe_alpha_lower_limit))
+ alpha_min = (XFIXNUM (Vframe_alpha_lower_limit)) / 100.0;
+
+ if (alpha > 1.0)
+ alpha = 1.0;
+ else if (alpha < alpha_min && alpha_min <= 1.0)
+ alpha = alpha_min;
+
+#if 0
+ /* If there is a parent from the window manager, put the property there
+ also, to work around broken window managers that fail to do that.
+ Do this unconditionally as this function is called on reparent when
+ alpha has not changed on the frame. */
+
+ if (!FRAME_PARENT_FRAME (f))
+ {
+ Window parent = x_find_topmost_parent (f);
+ if (parent != None)
+ XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity,
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) &opac, 1);
+ }
+#endif
+
+ set_opacity_recursively (FRAME_WIDGET (f), &alpha);
+ /* without this, blending mode is strange on wayland. */
+ gtk_widget_queue_resize_no_redraw (FRAME_WIDGET (f));
+}
+
+static void
+frame_highlight (struct frame *f)
+{
+ /* We used to only do this if Vx_no_window_manager was non-nil, but
+ the ICCCM (section 4.1.6) says that the window's border pixmap
+ and border pixel are window attributes which are "private to the
+ client", so we can always change it to whatever we want. */
+ block_input ();
+ /* I recently started to get errors in this XSetWindowBorder, depending on
+ the window-manager in use, tho something more is at play since I've been
+ using that same window-manager binary for ever. Let's not crash just
+ because of this (bug#9310). */
+
+ GtkWidget *w = FRAME_WIDGET (f);
+
+ char *css =
+ g_strdup_printf ("decoration { border: solid %dpx #%06x; }",
+ f->border_width,
+ (unsigned int) FRAME_X_OUTPUT (f)->border_pixel & 0x00ffffff);
+
+ GtkStyleContext *ctxt = gtk_widget_get_style_context (w);
+ GtkCssProvider *css_provider = gtk_css_provider_new ();
+ gtk_css_provider_load_from_data (css_provider, css, -1, NULL);
+ gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (css_provider),
+ GTK_STYLE_PROVIDER_PRIORITY_USER);
+ g_free (css);
+
+ GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider;
+ FRAME_X_OUTPUT (f)->border_color_css_provider = css_provider;
+ if (old != NULL)
+ {
+ gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old));
+ g_object_unref (old);
+ }
+
+ unblock_input ();
+ gui_update_cursor (f, true);
+ x_set_frame_alpha (f);
+}
+
+static void
+frame_unhighlight (struct frame *f)
+{
+ /* We used to only do this if Vx_no_window_manager was non-nil, but
+ the ICCCM (section 4.1.6) says that the window's border pixmap
+ and border pixel are window attributes which are "private to the
+ client", so we can always change it to whatever we want. */
+ block_input ();
+ /* Same as above for XSetWindowBorder (bug#9310). */
+
+ GtkWidget *w = FRAME_WIDGET (f);
+
+ char *css =
+ g_strdup_printf ("decoration { border: dotted %dpx #ffffff; }",
+ f->border_width);
+
+ GtkStyleContext *ctxt = gtk_widget_get_style_context (w);
+ GtkCssProvider *css_provider = gtk_css_provider_new ();
+ gtk_css_provider_load_from_data (css_provider, css, -1, NULL);
+ gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (css_provider),
+ GTK_STYLE_PROVIDER_PRIORITY_USER);
+ g_free (css);
+
+ GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider;
+ FRAME_X_OUTPUT (f)->border_color_css_provider = css_provider;
+ if (old != NULL)
+ {
+ gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old));
+ g_object_unref (old);
+ }
+
+ unblock_input ();
+ gui_update_cursor (f, true);
+ x_set_frame_alpha (f);
+}
+
+
+void
+pgtk_frame_rehighlight (struct pgtk_display_info *dpyinfo)
+{
+ struct frame *old_highlight = dpyinfo->highlight_frame;
+
+ if (dpyinfo->x_focus_frame)
+ {
+ dpyinfo->highlight_frame
+ = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
+ ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
+ : dpyinfo->x_focus_frame);
+ if (!FRAME_LIVE_P (dpyinfo->highlight_frame))
+ {
+ fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
+ dpyinfo->highlight_frame = dpyinfo->x_focus_frame;
+ }
+ }
+ else
+ dpyinfo->highlight_frame = 0;
+
+ if (old_highlight)
+ frame_unhighlight (old_highlight);
+ if (dpyinfo->highlight_frame)
+ frame_highlight (dpyinfo->highlight_frame);
+}
+
+/* The focus has changed, or we have redirected a frame's focus to
+ another frame (this happens when a frame uses a surrogate
+ mini-buffer frame). Shift the highlight as appropriate.
+
+ The FRAME argument doesn't necessarily have anything to do with which
+ frame is being highlighted or un-highlighted; we only use it to find
+ the appropriate X display info. */
+
+static void
+XTframe_rehighlight (struct frame *frame)
+{
+ pgtk_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
+}
+
+
+/* Toggle mouse pointer visibility on frame F by using invisible cursor. */
+
+static void
+x_toggle_visible_pointer (struct frame *f, bool invisible)
+{
+ Emacs_Cursor cursor;
+ if (invisible)
+ cursor = FRAME_DISPLAY_INFO (f)->invisible_cursor;
+ else
+ cursor = f->output_data.pgtk->current_cursor;
+ gdk_window_set_cursor (gtk_widget_get_window (FRAME_GTK_WIDGET (f)),
+ cursor);
+ f->pointer_invisible = invisible;
+}
+
+static void
+x_setup_pointer_blanking (struct pgtk_display_info *dpyinfo)
+{
+ dpyinfo->toggle_visible_pointer = x_toggle_visible_pointer;
+ dpyinfo->invisible_cursor =
+ gdk_cursor_new_for_display (dpyinfo->gdpy, GDK_BLANK_CURSOR);
+}
+
+static void
+XTtoggle_invisible_pointer (struct frame *f, bool invisible)
+{
+ block_input ();
+ FRAME_DISPLAY_INFO (f)->toggle_visible_pointer (f, invisible);
+ unblock_input ();
+}
+
+/* The focus has changed. Update the frames as necessary to reflect
+ the new situation. Note that we can't change the selected frame
+ here, because the Lisp code we are interrupting might become confused.
+ Each event gets marked with the frame in which it occurred, so the
+ Lisp code can tell when the switch took place by examining the events. */
+
+static void
+x_new_focus_frame (struct pgtk_display_info *dpyinfo, struct frame *frame)
+{
+ struct frame *old_focus = dpyinfo->x_focus_frame;
+ /* doesn't work on wayland */
+
+ if (frame != dpyinfo->x_focus_frame)
+ {
+ /* Set this before calling other routines, so that they see
+ the correct value of x_focus_frame. */
+ dpyinfo->x_focus_frame = frame;
+
+ if (old_focus && old_focus->auto_lower)
+ if (FRAME_GTK_OUTER_WIDGET (old_focus))
+ gdk_window_lower (gtk_widget_get_window
+ (FRAME_GTK_OUTER_WIDGET (old_focus)));
+
+ if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
+ if (FRAME_GTK_OUTER_WIDGET (dpyinfo->x_focus_frame))
+ gdk_window_raise (gtk_widget_get_window
+ (FRAME_GTK_OUTER_WIDGET (dpyinfo->x_focus_frame)));
+ }
+
+ pgtk_frame_rehighlight (dpyinfo);
+}
+
+static void
+pgtk_buffer_flipping_unblocked_hook (struct frame *f)
+{
+ block_input ();
+ flip_cr_context (f);
+ gtk_widget_queue_draw (FRAME_GTK_WIDGET (f));
+ unblock_input ();
+}
+
+static struct terminal *
+pgtk_create_terminal (struct pgtk_display_info *dpyinfo)
+/* --------------------------------------------------------------------------
+ Set up use of Gtk before we make the first connection.
+ -------------------------------------------------------------------------- */
+{
+ struct terminal *terminal;
+
+ terminal = create_terminal (output_pgtk, &pgtk_redisplay_interface);
+
+ terminal->display_info.pgtk = dpyinfo;
+ dpyinfo->terminal = terminal;
+
+ terminal->clear_frame_hook = pgtk_clear_frame;
+ terminal->ring_bell_hook = pgtk_ring_bell;
+ terminal->toggle_invisible_pointer_hook = XTtoggle_invisible_pointer;
+ terminal->update_begin_hook = pgtk_update_begin;
+ terminal->update_end_hook = pgtk_update_end;
+ terminal->read_socket_hook = pgtk_read_socket;
+ terminal->frame_up_to_date_hook = pgtk_frame_up_to_date;
+ terminal->mouse_position_hook = pgtk_mouse_position;
+ terminal->frame_rehighlight_hook = XTframe_rehighlight;
+ terminal->buffer_flipping_unblocked_hook = pgtk_buffer_flipping_unblocked_hook;
+ terminal->frame_raise_lower_hook = pgtk_frame_raise_lower;
+ terminal->frame_visible_invisible_hook = pgtk_make_frame_visible_invisible;
+ terminal->fullscreen_hook = pgtk_fullscreen_hook;
+ terminal->menu_show_hook = pgtk_menu_show;
+ terminal->activate_menubar_hook = pgtk_activate_menubar;
+ terminal->popup_dialog_hook = pgtk_popup_dialog;
+ terminal->change_tab_bar_height_hook = x_change_tab_bar_height;
+ terminal->set_vertical_scroll_bar_hook = pgtk_set_vertical_scroll_bar;
+ terminal->set_horizontal_scroll_bar_hook = pgtk_set_horizontal_scroll_bar;
+ terminal->condemn_scroll_bars_hook = pgtk_condemn_scroll_bars;
+ terminal->redeem_scroll_bar_hook = pgtk_redeem_scroll_bar;
+ terminal->judge_scroll_bars_hook = pgtk_judge_scroll_bars;
+ terminal->get_string_resource_hook = pgtk_get_string_resource;
+ terminal->delete_frame_hook = x_destroy_window;
+ terminal->delete_terminal_hook = pgtk_delete_terminal;
+ terminal->query_frame_background_color = pgtk_query_frame_background_color;
+ terminal->defined_color_hook = pgtk_defined_color;
+ terminal->set_new_font_hook = pgtk_new_font;
+ terminal->set_bitmap_icon_hook = pgtk_bitmap_icon;
+ terminal->implicit_set_name_hook = pgtk_implicitly_set_name;
+ terminal->iconify_frame_hook = pgtk_iconify_frame;
+ terminal->set_scroll_bar_default_width_hook =
+ pgtk_set_scroll_bar_default_width;
+ terminal->set_scroll_bar_default_height_hook =
+ pgtk_set_scroll_bar_default_height;
+ terminal->set_window_size_hook = pgtk_set_window_size;
+ terminal->query_colors = pgtk_query_colors;
+ terminal->get_focus_frame = x_get_focus_frame;
+ terminal->focus_frame_hook = pgtk_focus_frame;
+ terminal->set_frame_offset_hook = x_set_offset;
+ terminal->free_pixmap = pgtk_free_pixmap;
+
+ /* Other hooks are NULL by default. */
+
+ return terminal;
+}
+
+struct pgtk_window_is_of_frame_recursive_t
+{
+ GdkWindow *window;
+ bool result;
+ GtkWidget *emacs_gtk_fixed; /* stop on emacsgtkfixed other than this. */
+};
+
+static void
+pgtk_window_is_of_frame_recursive (GtkWidget * widget, gpointer data)
+{
+ struct pgtk_window_is_of_frame_recursive_t *datap = data;
+
+ if (datap->result)
+ return;
+
+ if (EMACS_IS_FIXED (widget) && widget != datap->emacs_gtk_fixed)
+ return;
+
+ if (gtk_widget_get_window (widget) == datap->window)
+ {
+ datap->result = true;
+ return;
+ }
+
+ if (GTK_IS_CONTAINER (widget)) {
+ gtk_container_foreach (GTK_CONTAINER (widget),
+ pgtk_window_is_of_frame_recursive, datap);
+ }
+}
+
+static bool
+pgtk_window_is_of_frame (struct frame *f, GdkWindow * window)
+{
+ struct pgtk_window_is_of_frame_recursive_t data;
+ data.window = window;
+ data.result = false;
+ data.emacs_gtk_fixed = FRAME_GTK_WIDGET (f);
+ pgtk_window_is_of_frame_recursive (FRAME_WIDGET (f), &data);
+ return data.result;
+}
+
+/* Like x_window_to_frame but also compares the window with the widget's
+ windows. */
+static struct frame *
+pgtk_any_window_to_frame (GdkWindow * window)
+{
+ Lisp_Object tail, frame;
+ struct frame *f, *found = NULL;
+
+ if (window == NULL)
+ return NULL;
+
+ FOR_EACH_FRAME (tail, frame)
+ {
+ if (found)
+ break;
+ f = XFRAME (frame);
+ if (FRAME_PGTK_P (f))
+ {
+ if (pgtk_window_is_of_frame (f, window))
+ found = f;
+ }
+ }
+
+ return found;
+}
+
+static gboolean
+pgtk_handle_event (GtkWidget * widget, GdkEvent * event, gpointer * data)
+{
+ return FALSE;
+}
+
+static void
+pgtk_fill_rectangle (struct frame *f, unsigned long color, int x, int y,
+ int width, int height)
+{
+ cairo_t *cr;
+ cr = pgtk_begin_cr_clip (f);
+ pgtk_set_cr_source_with_color (f, color);
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_fill (cr);
+ pgtk_end_cr_clip (f);
+}
+
+void
+pgtk_clear_under_internal_border (struct frame *f)
+{
+ if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
+ {
+ int border = FRAME_INTERNAL_BORDER_WIDTH (f);
+ int width = FRAME_PIXEL_WIDTH (f);
+ int height = FRAME_PIXEL_HEIGHT (f);
+ int margin = FRAME_TOP_MARGIN_HEIGHT (f);
+ int face_id =
+ (FRAME_PARENT_FRAME (f)
+ ? (!NILP (Vface_remapping_alist)
+ ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
+ : CHILD_FRAME_BORDER_FACE_ID)
+ : (!NILP (Vface_remapping_alist)
+ ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
+ : INTERNAL_BORDER_FACE_ID));
+ struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
+
+ block_input ();
+
+ if (face)
+ {
+#define x_fill_rectangle(f, gc, x, y, w, h) \
+ fill_background_by_face (f, face, x, y, w, h)
+ x_fill_rectangle (f, gc, 0, margin, width, border);
+ x_fill_rectangle (f, gc, 0, 0, border, height);
+ x_fill_rectangle (f, gc, width - border, 0, border, height);
+ x_fill_rectangle (f, gc, 0, height - border, width, border);
+#undef x_fill_rectangle
+ }
+ else
+ {
+#define x_clear_area(f, x, y, w, h) pgtk_clear_area (f, x, y, w, h)
+ x_clear_area (f, 0, 0, border, height);
+ x_clear_area (f, 0, margin, width, border);
+ x_clear_area (f, width - border, 0, border, height);
+ x_clear_area (f, 0, height - border, width, border);
+#undef x_clear_area
+ }
+
+ unblock_input ();
+ }
+}
+
+static gboolean
+pgtk_handle_draw (GtkWidget * widget, cairo_t * cr, gpointer * data)
+{
+ struct frame *f;
+
+ GdkWindow *win = gtk_widget_get_window (widget);
+
+ if (win != NULL)
+ {
+ cairo_surface_t *src = NULL;
+ f = pgtk_any_window_to_frame (win);
+ if (f != NULL)
+ {
+ src = FRAME_X_OUTPUT (f)->cr_surface_visible_bell;
+ if (src == NULL && FRAME_CR_ACTIVE_CONTEXT (f) != NULL)
+ src = cairo_get_target (FRAME_CR_ACTIVE_CONTEXT (f));
+ }
+ if (src != NULL)
+ {
+ cairo_set_source_surface (cr, src, 0, 0);
+ cairo_paint (cr);
+ }
+ }
+ return FALSE;
+}
+
+static void
+size_allocate (GtkWidget * widget, GtkAllocation * alloc,
+ gpointer user_data)
+{
+ struct frame *f = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
+
+ /* Between a frame is created and not shown, size is allocated and
+ * this handler is called. When that, since the widget's window is
+ * NULL, we can't get f, pgtk_cr_update_surface_desired_size is not
+ * called, and its size is 0x0. That causes empty frame.
+ *
+ * Fortunately since we know f in pgtk_set_event_handler, we can get
+ * it through user_data;
+ */
+ if (!f)
+ f = user_data;
+
+ if (f)
+ {
+ xg_frame_resized (f, alloc->width, alloc->height);
+ pgtk_cr_update_surface_desired_size (f, alloc->width, alloc->height, false);
+ }
+}
+
+static void
+x_find_modifier_meanings (struct pgtk_display_info *dpyinfo)
+{
+ GdkDisplay *gdpy = dpyinfo->gdpy;
+ GdkKeymap *keymap = gdk_keymap_get_for_display (gdpy);
+ GdkModifierType state = GDK_META_MASK;
+ gboolean r = gdk_keymap_map_virtual_modifiers (keymap, &state);
+ if (r)
+ {
+ /* Meta key exists. */
+ if (state == GDK_META_MASK)
+ {
+ dpyinfo->meta_mod_mask = GDK_MOD1_MASK; /* maybe this is meta. */
+ dpyinfo->alt_mod_mask = 0;
+ }
+ else
+ {
+ dpyinfo->meta_mod_mask = state & ~GDK_META_MASK;
+ if (dpyinfo->meta_mod_mask == GDK_MOD1_MASK)
+ dpyinfo->alt_mod_mask = 0;
+ else
+ dpyinfo->alt_mod_mask = GDK_MOD1_MASK;
+ }
+ }
+ else
+ {
+ dpyinfo->meta_mod_mask = GDK_MOD1_MASK;
+ dpyinfo->alt_mod_mask = 0;
+ }
+
+ state = GDK_SUPER_MASK;
+ r = gdk_keymap_map_virtual_modifiers (keymap, &state);
+ if (r)
+ {
+ /* Super key exists. */
+ if (state == GDK_SUPER_MASK)
+ {
+ dpyinfo->super_mod_mask = GDK_MOD4_MASK; /* maybe this is super. */
+ }
+ else
+ {
+ dpyinfo->super_mod_mask = state & ~GDK_SUPER_MASK;
+ }
+ }
+ else
+ {
+ dpyinfo->super_mod_mask = GDK_MOD4_MASK;
+ }
+
+ state = GDK_HYPER_MASK;
+ r = gdk_keymap_map_virtual_modifiers (keymap, &state);
+ if (r)
+ {
+ /* Hyper key exists. */
+ if (state == GDK_HYPER_MASK)
+ {
+ dpyinfo->hyper_mod_mask = GDK_MOD3_MASK; /* maybe this is hyper. */
+ }
+ else
+ {
+ dpyinfo->hyper_mod_mask = state & ~GDK_HYPER_MASK;
+ }
+ }
+ else
+ {
+ dpyinfo->hyper_mod_mask = GDK_MOD3_MASK;
+ }
+
+ /* If xmodmap says:
+ * $ xmodmap | grep mod4
+ * mod4 Super_L (0x85), Super_R (0x86), Super_L (0xce), Hyper_L (0xcf)
+ * then, when mod4 is pressed, both of super and hyper are recognized ON.
+ * Maybe many people have such configuration, and they don't like such behavior,
+ * so I disable hyper if such configuration is detected.
+ */
+ if (dpyinfo->hyper_mod_mask == dpyinfo->super_mod_mask)
+ dpyinfo->hyper_mod_mask = 0;
+}
+
+static void
+get_modifier_values (int *mod_ctrl,
+ int *mod_meta,
+ int *mod_alt, int *mod_hyper, int *mod_super)
+{
+ Lisp_Object tem;
+
+ *mod_ctrl = ctrl_modifier;
+ *mod_meta = meta_modifier;
+ *mod_alt = alt_modifier;
+ *mod_hyper = hyper_modifier;
+ *mod_super = super_modifier;
+
+ tem = Fget (Vx_ctrl_keysym, Qmodifier_value);
+ if (INTEGERP (tem))
+ *mod_ctrl = XFIXNUM (tem) & INT_MAX;
+ tem = Fget (Vx_alt_keysym, Qmodifier_value);
+ if (INTEGERP (tem))
+ *mod_alt = XFIXNUM (tem) & INT_MAX;
+ tem = Fget (Vx_meta_keysym, Qmodifier_value);
+ if (INTEGERP (tem))
+ *mod_meta = XFIXNUM (tem) & INT_MAX;
+ tem = Fget (Vx_hyper_keysym, Qmodifier_value);
+ if (INTEGERP (tem))
+ *mod_hyper = XFIXNUM (tem) & INT_MAX;
+ tem = Fget (Vx_super_keysym, Qmodifier_value);
+ if (INTEGERP (tem))
+ *mod_super = XFIXNUM (tem) & INT_MAX;
+}
+
+int
+pgtk_gtk_to_emacs_modifiers (struct pgtk_display_info *dpyinfo, int state)
+{
+ int mod_ctrl;
+ int mod_meta;
+ int mod_alt;
+ int mod_hyper;
+ int mod_super;
+ int mod;
+
+ get_modifier_values (&mod_ctrl, &mod_meta, &mod_alt, &mod_hyper,
+ &mod_super);
+
+ mod = 0;
+ if (state & GDK_SHIFT_MASK)
+ mod |= shift_modifier;
+ if (state & GDK_CONTROL_MASK)
+ mod |= mod_ctrl;
+ if (state & dpyinfo->meta_mod_mask)
+ mod |= mod_meta;
+ if (state & dpyinfo->alt_mod_mask)
+ mod |= mod_alt;
+ if (state & dpyinfo->super_mod_mask)
+ mod |= mod_super;
+ if (state & dpyinfo->hyper_mod_mask)
+ mod |= mod_hyper;
+ return mod;
+}
+
+static int
+pgtk_emacs_to_gtk_modifiers (struct pgtk_display_info *dpyinfo, int state)
+{
+ int mod_ctrl;
+ int mod_meta;
+ int mod_alt;
+ int mod_hyper;
+ int mod_super;
+ int mask;
+
+ get_modifier_values (&mod_ctrl, &mod_meta, &mod_alt, &mod_hyper,
+ &mod_super);
+
+ mask = 0;
+ if (state & mod_alt)
+ mask |= dpyinfo->alt_mod_mask;
+ if (state & mod_super)
+ mask |= dpyinfo->super_mod_mask;
+ if (state & mod_hyper)
+ mask |= dpyinfo->hyper_mod_mask;
+ if (state & shift_modifier)
+ mask |= GDK_SHIFT_MASK;
+ if (state & mod_ctrl)
+ mask |= GDK_CONTROL_MASK;
+ if (state & mod_meta)
+ mask |= dpyinfo->meta_mod_mask;
+ return mask;
+}
+
+#define IsCursorKey(keysym) (0xff50 <= (keysym) && (keysym) < 0xff60)
+#define IsMiscFunctionKey(keysym) (0xff60 <= (keysym) && (keysym) < 0xff6c)
+#define IsKeypadKey(keysym) (0xff80 <= (keysym) && (keysym) < 0xffbe)
+#define IsFunctionKey(keysym) (0xffbe <= (keysym) && (keysym) < 0xffe1)
+#define IsModifierKey(keysym) \
+ ((((keysym) >= GDK_KEY_Shift_L) && ((keysym) <= GDK_KEY_Hyper_R)) \
+ || (((keysym) >= GDK_KEY_ISO_Lock) && ((keysym) <= GDK_KEY_ISO_Level5_Lock)) \
+ || ((keysym) == GDK_KEY_Mode_switch) \
+ || ((keysym) == GDK_KEY_Num_Lock))
+
+
+void
+pgtk_enqueue_string (struct frame *f, gchar * str)
+{
+ gunichar *ustr;
+
+ ustr = g_utf8_to_ucs4 (str, -1, NULL, NULL, NULL);
+ if (ustr == NULL)
+ return;
+ for (; *ustr != 0; ustr++)
+ {
+ union buffered_input_event inev;
+ Lisp_Object c = make_fixnum (*ustr);
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c))
+ ? ASCII_KEYSTROKE_EVENT
+ : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+ inev.ie.arg = Qnil;
+ inev.ie.code = XFIXNAT (c);
+ XSETFRAME (inev.ie.frame_or_window, f);
+ inev.ie.modifiers = 0;
+ inev.ie.timestamp = 0;
+ evq_enqueue (&inev);
+ }
+
+}
+
+void
+pgtk_enqueue_preedit (struct frame *f, Lisp_Object preedit)
+{
+ union buffered_input_event inev;
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = PGTK_PREEDIT_TEXT_EVENT;
+ inev.ie.arg = preedit;
+ inev.ie.code = 0;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ inev.ie.modifiers = 0;
+ inev.ie.timestamp = 0;
+ evq_enqueue (&inev);
+}
+
+static gboolean
+key_press_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data)
+{
+ struct coding_system coding;
+ union buffered_input_event inev;
+ ptrdiff_t nbytes = 0;
+ Mouse_HLInfo *hlinfo;
+
+ USE_SAFE_ALLOCA;
+
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = NO_EVENT;
+ inev.ie.arg = Qnil;
+
+ struct frame *f = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
+ hlinfo = MOUSE_HL_INFO (f);
+
+ /* If mouse-highlight is an integer, input clears out
+ mouse highlighting. */
+ if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
+ {
+ clear_mouse_face (hlinfo);
+ hlinfo->mouse_face_hidden = true;
+ }
+
+ if (f != 0)
+ {
+ /* While super is pressed, gtk_im_context_filter_keypress() always process the
+ * key events ignoring super.
+ * As a work around, don't call it while super or hyper are pressed...
+ */
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+ if (!(event->key.state & (dpyinfo->super_mod_mask | dpyinfo->hyper_mod_mask)))
+ {
+ if (pgtk_im_filter_keypress (f, &event->key))
+ return TRUE;
+ }
+ }
+
+ if (f != 0)
+ {
+ guint keysym, orig_keysym;
+ /* al%imercury@uunet.uu.net says that making this 81
+ instead of 80 fixed a bug whereby meta chars made
+ his Emacs hang.
+
+ It seems that some version of XmbLookupString has
+ a bug of not returning XBufferOverflow in
+ status_return even if the input is too long to
+ fit in 81 bytes. So, we must prepare sufficient
+ bytes for copy_buffer. 513 bytes (256 chars for
+ two-byte character set) seems to be a fairly good
+ approximation. -- 2000.8.10 handa@etl.go.jp */
+ unsigned char copy_buffer[513];
+ unsigned char *copy_bufptr = copy_buffer;
+ int copy_bufsiz = sizeof (copy_buffer);
+ int modifiers;
+ Lisp_Object coding_system = Qlatin_1;
+ Lisp_Object c;
+ guint state = event->key.state;
+
+ state |=
+ pgtk_emacs_to_gtk_modifiers (FRAME_DISPLAY_INFO (f),
+ extra_keyboard_modifiers);
+ modifiers = state;
+
+ /* This will have to go some day... */
+
+ /* make_lispy_event turns chars into control chars.
+ Don't do it here because XLookupString is too eager. */
+ state &= ~GDK_CONTROL_MASK;
+ state &= ~(GDK_META_MASK
+ | GDK_SUPER_MASK | GDK_HYPER_MASK | GDK_MOD1_MASK);
+
+ nbytes = event->key.length;
+ if (nbytes > copy_bufsiz)
+ nbytes = copy_bufsiz;
+ memcpy (copy_bufptr, event->key.string, nbytes);
+
+ keysym = event->key.keyval;
+ orig_keysym = keysym;
+
+ /* Common for all keysym input events. */
+ XSETFRAME (inev.ie.frame_or_window, f);
+ inev.ie.modifiers =
+ pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), modifiers);
+ inev.ie.timestamp = event->key.time;
+
+ /* First deal with keysyms which have defined
+ translations to characters. */
+ if (keysym >= 32 && keysym < 128)
+ /* Avoid explicitly decoding each ASCII character. */
+ {
+ inev.ie.kind = ASCII_KEYSTROKE_EVENT;
+ inev.ie.code = keysym;
+ goto done;
+ }
+
+ /* Keysyms directly mapped to Unicode characters. */
+ if (keysym >= 0x01000000 && keysym <= 0x0110FFFF)
+ {
+ if (keysym < 0x01000080)
+ inev.ie.kind = ASCII_KEYSTROKE_EVENT;
+ else
+ inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+ inev.ie.code = keysym & 0xFFFFFF;
+ goto done;
+ }
+
+ /* Now non-ASCII. */
+ if (HASH_TABLE_P (Vpgtk_keysym_table)
+ && (c = Fgethash (make_fixnum (keysym),
+ Vpgtk_keysym_table, Qnil), FIXNATP (c)))
+ {
+ inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c))
+ ? ASCII_KEYSTROKE_EVENT
+ : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+ inev.ie.code = XFIXNAT (c);
+ goto done;
+ }
+
+ /* Random non-modifier sorts of keysyms. */
+ if (((keysym >= GDK_KEY_BackSpace && keysym <= GDK_KEY_Escape)
+ || keysym == GDK_KEY_Delete
+#ifdef GDK_KEY_ISO_Left_Tab
+ || (keysym >= GDK_KEY_ISO_Left_Tab && keysym <= GDK_KEY_ISO_Enter)
+#endif
+ || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */
+ || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */
+#ifdef HPUX
+ /* This recognizes the "extended function
+ keys". It seems there's no cleaner way.
+ Test IsModifierKey to avoid handling
+ mode_switch incorrectly. */
+ || (GDK_KEY_Select <= keysym && keysym < GDK_KEY_KP_Space)
+#endif
+#ifdef GDK_KEY_dead_circumflex
+ || orig_keysym == GDK_KEY_dead_circumflex
+#endif
+#ifdef GDK_KEY_dead_grave
+ || orig_keysym == GDK_KEY_dead_grave
+#endif
+#ifdef GDK_KEY_dead_tilde
+ || orig_keysym == GDK_KEY_dead_tilde
+#endif
+#ifdef GDK_KEY_dead_diaeresis
+ || orig_keysym == GDK_KEY_dead_diaeresis
+#endif
+#ifdef GDK_KEY_dead_macron
+ || orig_keysym == GDK_KEY_dead_macron
+#endif
+#ifdef GDK_KEY_dead_degree
+ || orig_keysym == GDK_KEY_dead_degree
+#endif
+#ifdef GDK_KEY_dead_acute
+ || orig_keysym == GDK_KEY_dead_acute
+#endif
+#ifdef GDK_KEY_dead_cedilla
+ || orig_keysym == GDK_KEY_dead_cedilla
+#endif
+#ifdef GDK_KEY_dead_breve
+ || orig_keysym == GDK_KEY_dead_breve
+#endif
+#ifdef GDK_KEY_dead_ogonek
+ || orig_keysym == GDK_KEY_dead_ogonek
+#endif
+#ifdef GDK_KEY_dead_caron
+ || orig_keysym == GDK_KEY_dead_caron
+#endif
+#ifdef GDK_KEY_dead_doubleacute
+ || orig_keysym == GDK_KEY_dead_doubleacute
+#endif
+#ifdef GDK_KEY_dead_abovedot
+ || orig_keysym == GDK_KEY_dead_abovedot
+#endif
+ || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
+ || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
+ /* Any "vendor-specific" key is ok. */
+ || (orig_keysym & (1 << 28))
+ || (keysym != GDK_KEY_VoidSymbol && nbytes == 0))
+ && !(event->key.is_modifier
+ /* Gtk's modifier keys are different from Xlib's ones.
+ * I need to exclude them.
+ */
+ || IsModifierKey (orig_keysym)
+ /* The symbols from GDK_KEY_ISO_Lock
+ to GDK_KEY_ISO_Last_Group_Lock
+ don't have real modifiers but
+ should be treated similarly to
+ Mode_switch by Emacs. */
+#if defined GDK_KEY_ISO_Lock && defined GDK_KEY_ISO_Last_Group_Lock
+ || (GDK_KEY_ISO_Lock <= orig_keysym
+ && orig_keysym <= GDK_KEY_ISO_Last_Group_Lock)
+#endif
+ ))
+ {
+ STORE_KEYSYM_FOR_DEBUG (keysym);
+ /* make_lispy_event will convert this to a symbolic
+ key. */
+ inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
+ inev.ie.code = keysym;
+ goto done;
+ }
+
+ { /* Raw bytes, not keysym. */
+ ptrdiff_t i;
+ int nchars, len;
+
+ for (i = 0, nchars = 0; i < nbytes; i++)
+ {
+ if (ASCII_CHAR_P (copy_bufptr[i]))
+ nchars++;
+ STORE_KEYSYM_FOR_DEBUG (copy_bufptr[i]);
+ }
+
+ if (nchars < nbytes)
+ {
+ /* Decode the input data. */
+
+ /* The input should be decoded with locale `coding_system'. */
+ if (!NILP (Vlocale_coding_system))
+ coding_system = Vlocale_coding_system;
+ setup_coding_system (coding_system, &coding);
+ coding.src_multibyte = false;
+ coding.dst_multibyte = true;
+ /* The input is converted to events, thus we can't
+ handle composition. Anyway, there's no XIM that
+ gives us composition information. */
+ coding.common_flags &= ~CODING_ANNOTATION_MASK;
+
+ SAFE_NALLOCA (coding.destination, MAX_MULTIBYTE_LENGTH, nbytes);
+ coding.dst_bytes = MAX_MULTIBYTE_LENGTH * nbytes;
+ coding.mode |= CODING_MODE_LAST_BLOCK;
+ decode_coding_c_string (&coding, copy_bufptr, nbytes, Qnil);
+ nbytes = coding.produced;
+ nchars = coding.produced_char;
+ copy_bufptr = coding.destination;
+ }
+
+ /* Convert the input data to a sequence of
+ character events. */
+ for (i = 0; i < nbytes; i += len)
+ {
+ int ch;
+ if (nchars == nbytes)
+ ch = copy_bufptr[i], len = 1;
+ else
+ ch = string_char_and_length (copy_bufptr + i, &len);
+ inev.ie.kind = (SINGLE_BYTE_CHAR_P (ch)
+ ? ASCII_KEYSTROKE_EVENT
+ : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+ inev.ie.code = ch;
+ evq_enqueue (&inev);
+ }
+
+ /* count += nchars; */
+
+ inev.ie.kind = NO_EVENT; /* Already stored above. */
+
+ if (keysym == GDK_KEY_VoidSymbol)
+ goto done;
+ }
+ }
+
+done:
+ if (inev.ie.kind != NO_EVENT)
+ {
+ XSETFRAME (inev.ie.frame_or_window, f);
+ evq_enqueue (&inev);
+ /* count++; */
+ }
+
+ SAFE_FREE ();
+
+ return TRUE;
+}
+
+static gboolean
+key_release_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer *user_data)
+{
+ return TRUE;
+}
+
+static gboolean
+configure_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer *user_data)
+{
+ struct frame *f = pgtk_any_window_to_frame (event->configure.window);
+ if (f && widget == FRAME_GTK_OUTER_WIDGET (f))
+ {
+ if (any_help_event_p)
+ {
+ Lisp_Object frame;
+ if (f)
+ XSETFRAME (frame, f);
+ else
+ frame = Qnil;
+ help_echo_string = Qnil;
+ gen_help_event (Qnil, frame, Qnil, Qnil, 0);
+ }
+ }
+ return FALSE;
+}
+
+static gboolean
+map_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer *user_data)
+{
+ struct frame *f = pgtk_any_window_to_frame (event->any.window);
+ union buffered_input_event inev;
+
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = NO_EVENT;
+ inev.ie.arg = Qnil;
+
+ if (f)
+ {
+ bool iconified = FRAME_ICONIFIED_P (f);
+
+ /* Check if fullscreen was specified before we where mapped the
+ first time, i.e. from the command line. */
+ if (!FRAME_X_OUTPUT (f)->has_been_visible)
+ {
+ set_fullscreen_state (f);
+ }
+
+ if (!iconified)
+ {
+ /* The `z-group' is reset every time a frame becomes
+ invisible. Handle this here. */
+ if (FRAME_Z_GROUP (f) == z_group_above)
+ x_set_z_group (f, Qabove, Qnil);
+ else if (FRAME_Z_GROUP (f) == z_group_below)
+ x_set_z_group (f, Qbelow, Qnil);
+ }
+
+ SET_FRAME_VISIBLE (f, 1);
+ SET_FRAME_ICONIFIED (f, false);
+ FRAME_X_OUTPUT (f)->has_been_visible = true;
+
+ if (iconified)
+ {
+ inev.ie.kind = DEICONIFY_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ }
+ }
+
+ if (inev.ie.kind != NO_EVENT)
+ evq_enqueue (&inev);
+ return FALSE;
+}
+
+static gboolean
+window_state_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer *user_data)
+{
+ struct frame *f = pgtk_any_window_to_frame (event->window_state.window);
+ union buffered_input_event inev;
+
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = NO_EVENT;
+ inev.ie.arg = Qnil;
+
+ if (f)
+ {
+ if (event->window_state.new_window_state & GDK_WINDOW_STATE_FOCUSED)
+ {
+ if (FRAME_ICONIFIED_P (f))
+ {
+ /* Gnome shell does not iconify us when C-z is pressed.
+ It hides the frame. So if our state says we aren't
+ hidden anymore, treat it as deiconified. */
+ SET_FRAME_VISIBLE (f, 1);
+ SET_FRAME_ICONIFIED (f, false);
+ FRAME_X_OUTPUT (f)->has_been_visible = true;
+ inev.ie.kind = DEICONIFY_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ }
+ }
+ }
+
+ if (inev.ie.kind != NO_EVENT)
+ evq_enqueue (&inev);
+ return FALSE;
+}
+
+static gboolean
+delete_event (GtkWidget *widget,
+ GdkEvent *event, gpointer *user_data)
+{
+ struct frame *f = pgtk_any_window_to_frame (event->any.window);
+ union buffered_input_event inev;
+
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = NO_EVENT;
+ inev.ie.arg = Qnil;
+
+ if (f)
+ {
+ inev.ie.kind = DELETE_WINDOW_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ }
+
+ if (inev.ie.kind != NO_EVENT)
+ evq_enqueue (&inev);
+ return TRUE;
+}
+
+/* The focus may have changed. Figure out if it is a real focus change,
+ by checking both FocusIn/Out and Enter/LeaveNotify events.
+
+ Returns FOCUS_IN_EVENT event in *BUFP. */
+
+/* Handle FocusIn and FocusOut state changes for FRAME.
+ If FRAME has focus and there exists more than one frame, puts
+ a FOCUS_IN_EVENT into *BUFP. */
+
+static void
+x_focus_changed (gboolean is_enter, int state,
+ struct pgtk_display_info *dpyinfo, struct frame *frame,
+ union buffered_input_event *bufp)
+{
+ if (is_enter)
+ {
+ if (dpyinfo->x_focus_event_frame != frame)
+ {
+ x_new_focus_frame (dpyinfo, frame);
+ dpyinfo->x_focus_event_frame = frame;
+
+ /* Don't stop displaying the initial startup message
+ for a switch-frame event we don't need. */
+ /* When run as a daemon, Vterminal_frame is always NIL. */
+ bufp->ie.arg = (((NILP (Vterminal_frame)
+ || !FRAME_PGTK_P (XFRAME (Vterminal_frame))
+ || EQ (Fdaemonp (), Qt))
+ && CONSP (Vframe_list)
+ && !NILP (XCDR (Vframe_list))) ? Qt : Qnil);
+ bufp->ie.kind = FOCUS_IN_EVENT;
+ XSETFRAME (bufp->ie.frame_or_window, frame);
+ }
+
+ frame->output_data.pgtk->focus_state |= state;
+
+ }
+ else
+ {
+ frame->output_data.pgtk->focus_state &= ~state;
+
+ if (dpyinfo->x_focus_event_frame == frame)
+ {
+ dpyinfo->x_focus_event_frame = 0;
+ x_new_focus_frame (dpyinfo, 0);
+
+ bufp->ie.kind = FOCUS_OUT_EVENT;
+ XSETFRAME (bufp->ie.frame_or_window, frame);
+ }
+
+ if (frame->pointer_invisible)
+ XTtoggle_invisible_pointer (frame, false);
+ }
+}
+
+static gboolean
+enter_notify_event (GtkWidget *widget, GdkEvent *event,
+ gpointer *user_data)
+{
+ union buffered_input_event inev;
+ struct frame *frame =
+ pgtk_any_window_to_frame (gtk_widget_get_window (widget));
+ if (frame == NULL)
+ return FALSE;
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
+ struct frame *focus_frame = dpyinfo->x_focus_frame;
+ int focus_state
+ = focus_frame ? focus_frame->output_data.pgtk->focus_state : 0;
+
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = NO_EVENT;
+ inev.ie.arg = Qnil;
+
+ if (event->crossing.detail != GDK_NOTIFY_INFERIOR
+ && event->crossing.focus && !(focus_state & FOCUS_EXPLICIT))
+ x_focus_changed (TRUE, FOCUS_IMPLICIT, dpyinfo, frame, &inev);
+ if (inev.ie.kind != NO_EVENT)
+ evq_enqueue (&inev);
+ return TRUE;
+}
+
+static gboolean
+leave_notify_event (GtkWidget *widget, GdkEvent *event,
+ gpointer *user_data)
+{
+ union buffered_input_event inev;
+ struct frame *frame =
+ pgtk_any_window_to_frame (gtk_widget_get_window (widget));
+ if (frame == NULL)
+ return FALSE;
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
+ struct frame *focus_frame = dpyinfo->x_focus_frame;
+ int focus_state
+ = focus_frame ? focus_frame->output_data.pgtk->focus_state : 0;
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (frame);
+
+ if (frame == hlinfo->mouse_face_mouse_frame)
+ {
+ /* If we move outside the frame, then we're
+ certainly no longer on any text in the frame. */
+ clear_mouse_face (hlinfo);
+ hlinfo->mouse_face_mouse_frame = 0;
+ }
+
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = NO_EVENT;
+ inev.ie.arg = Qnil;
+
+ if (event->crossing.detail != GDK_NOTIFY_INFERIOR
+ && event->crossing.focus && !(focus_state & FOCUS_EXPLICIT))
+ x_focus_changed (FALSE, FOCUS_IMPLICIT, dpyinfo, frame, &inev);
+
+ if (frame)
+ {
+ if (any_help_event_p)
+ {
+ Lisp_Object frame_obj;
+ XSETFRAME (frame_obj, frame);
+ help_echo_string = Qnil;
+ gen_help_event (Qnil, frame_obj, Qnil, Qnil, 0);
+ }
+ }
+
+ if (inev.ie.kind != NO_EVENT)
+ evq_enqueue (&inev);
+ return TRUE;
+}
+
+static gboolean
+focus_in_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data)
+{
+ union buffered_input_event inev;
+ struct frame *frame =
+ pgtk_any_window_to_frame (gtk_widget_get_window (widget));
+
+ if (frame == NULL)
+ return TRUE;
+
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = NO_EVENT;
+ inev.ie.arg = Qnil;
+
+ x_focus_changed (TRUE, FOCUS_EXPLICIT,
+ FRAME_DISPLAY_INFO (frame), frame, &inev);
+ if (inev.ie.kind != NO_EVENT)
+ evq_enqueue (&inev);
+
+ pgtk_im_focus_in (frame);
+
+ return TRUE;
+}
+
+static gboolean
+focus_out_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data)
+{
+ union buffered_input_event inev;
+ struct frame *frame =
+ pgtk_any_window_to_frame (gtk_widget_get_window (widget));
+
+ if (frame == NULL)
+ return TRUE;
+
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = NO_EVENT;
+ inev.ie.arg = Qnil;
+
+ x_focus_changed (FALSE, FOCUS_EXPLICIT,
+ FRAME_DISPLAY_INFO (frame), frame, &inev);
+ if (inev.ie.kind != NO_EVENT)
+ evq_enqueue (&inev);
+
+ pgtk_im_focus_out (frame);
+
+ return TRUE;
+}
+
+/* Function to report a mouse movement to the mainstream Emacs code.
+ The input handler calls this.
+
+ We have received a mouse movement event, which is given in *event.
+ If the mouse is over a different glyph than it was last time, tell
+ the mainstream emacs code by setting mouse_moved. If not, ask for
+ another motion event, so we can check again the next time it moves. */
+
+static bool
+note_mouse_movement (struct frame *frame, const GdkEventMotion * event)
+{
+ XRectangle *r;
+ struct pgtk_display_info *dpyinfo;
+
+ if (!FRAME_X_OUTPUT (frame))
+ return false;
+
+ dpyinfo = FRAME_DISPLAY_INFO (frame);
+ dpyinfo->last_mouse_movement_time = event->time;
+ dpyinfo->last_mouse_motion_frame = frame;
+ dpyinfo->last_mouse_motion_x = event->x;
+ dpyinfo->last_mouse_motion_y = event->y;
+
+ if (event->window != gtk_widget_get_window (FRAME_GTK_WIDGET (frame)))
+ {
+ frame->mouse_moved = true;
+ dpyinfo->last_mouse_scroll_bar = NULL;
+ note_mouse_highlight (frame, -1, -1);
+ dpyinfo->last_mouse_glyph_frame = NULL;
+ return true;
+ }
+
+
+ /* Has the mouse moved off the glyph it was on at the last sighting? */
+ r = &dpyinfo->last_mouse_glyph;
+ if (frame != dpyinfo->last_mouse_glyph_frame
+ || event->x < r->x || event->x >= r->x + r->width
+ || event->y < r->y || event->y >= r->y + r->height)
+ {
+ frame->mouse_moved = true;
+ dpyinfo->last_mouse_scroll_bar = NULL;
+ note_mouse_highlight (frame, event->x, event->y);
+ /* Remember which glyph we're now on. */
+ remember_mouse_glyph (frame, event->x, event->y, r);
+ dpyinfo->last_mouse_glyph_frame = frame;
+ return true;
+ }
+
+ return false;
+}
+
+static gboolean
+motion_notify_event (GtkWidget * widget, GdkEvent * event,
+ gpointer * user_data)
+{
+ union buffered_input_event inev;
+ struct frame *f, *frame;
+ struct pgtk_display_info *dpyinfo;
+ Mouse_HLInfo *hlinfo;
+
+ /* This is needed to make pointer visible when motion_notify event */
+ pending_signals = true;
+
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = NO_EVENT;
+ inev.ie.arg = Qnil;
+
+ previous_help_echo_string = help_echo_string;
+ help_echo_string = Qnil;
+
+ frame = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
+ dpyinfo = FRAME_DISPLAY_INFO (frame);
+ f = (gui_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame
+ : pgtk_any_window_to_frame (gtk_widget_get_window (widget)));
+ hlinfo = MOUSE_HL_INFO (f);
+
+ if (hlinfo->mouse_face_hidden)
+ {
+ hlinfo->mouse_face_hidden = false;
+ clear_mouse_face (hlinfo);
+ }
+
+ if (f && xg_event_is_for_scrollbar (f, event))
+ f = 0;
+ if (f)
+ {
+ /* Maybe generate a SELECT_WINDOW_EVENT for
+ `mouse-autoselect-window' but don't let popup menus
+ interfere with this (Bug#1261). */
+ if (!NILP (Vmouse_autoselect_window)
+ /* Don't switch if we're currently in the minibuffer.
+ This tries to work around problems where the
+ minibuffer gets unselected unexpectedly, and where
+ you then have to move your mouse all the way down to
+ the minibuffer to select it. */
+ && !MINI_WINDOW_P (XWINDOW (selected_window))
+ /* With `focus-follows-mouse' non-nil create an event
+ also when the target window is on another frame. */
+ && (f == XFRAME (selected_frame) || !NILP (focus_follows_mouse)))
+ {
+ static Lisp_Object last_mouse_window;
+ Lisp_Object window = window_from_coordinates
+ (f, event->motion.x, event->motion.y, 0, false, false);
+
+ /* A window will be autoselected only when it is not
+ selected now and the last mouse movement event was
+ not in it. The remainder of the code is a bit vague
+ wrt what a "window" is. For immediate autoselection,
+ the window is usually the entire window but for GTK
+ where the scroll bars don't count. For delayed
+ autoselection the window is usually the window's text
+ area including the margins. */
+ if (WINDOWP (window)
+ && !EQ (window, last_mouse_window)
+ && !EQ (window, selected_window))
+ {
+ inev.ie.kind = SELECT_WINDOW_EVENT;
+ inev.ie.frame_or_window = window;
+ }
+
+ /* Remember the last window where we saw the mouse. */
+ last_mouse_window = window;
+ }
+
+ if (!note_mouse_movement (f, &event->motion))
+ help_echo_string = previous_help_echo_string;
+ }
+ else
+ {
+ /* If we move outside the frame, then we're
+ certainly no longer on any text in the frame. */
+ clear_mouse_face (hlinfo);
+ }
+
+ /* If the contents of the global variable help_echo_string
+ has changed, generate a HELP_EVENT. */
+ int do_help = 0;
+ if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
+ do_help = 1;
+
+ if (inev.ie.kind != NO_EVENT)
+ evq_enqueue (&inev);
+
+ if (do_help > 0)
+ {
+ Lisp_Object frame;
+
+ if (f)
+ XSETFRAME (frame, f);
+ else
+ frame = Qnil;
+
+ any_help_event_p = true;
+ gen_help_event (help_echo_string, frame, help_echo_window,
+ help_echo_object, help_echo_pos);
+ }
+
+ return TRUE;
+}
+
+/* Mouse clicks and mouse movement. Rah.
+
+ Formerly, we used PointerMotionHintMask (in standard_event_mask)
+ so that we would have to call XQueryPointer after each MotionNotify
+ event to ask for another such event. However, this made mouse tracking
+ slow, and there was a bug that made it eventually stop.
+
+ Simply asking for MotionNotify all the time seems to work better.
+
+ In order to avoid asking for motion events and then throwing most
+ of them away or busy-polling the server for mouse positions, we ask
+ the server for pointer motion hints. This means that we get only
+ one event per group of mouse movements. "Groups" are delimited by
+ other kinds of events (focus changes and button clicks, for
+ example), or by XQueryPointer calls; when one of these happens, we
+ get another MotionNotify event the next time the mouse moves. This
+ is at least as efficient as getting motion events when mouse
+ tracking is on, and I suspect only negligibly worse when tracking
+ is off. */
+
+/* Prepare a mouse-event in *RESULT for placement in the input queue.
+
+ If the event is a button press, then note that we have grabbed
+ the mouse. */
+
+static Lisp_Object
+construct_mouse_click (struct input_event *result,
+ const GdkEventButton * event, struct frame *f)
+{
+ /* Make the event type NO_EVENT; we'll change that when we decide
+ otherwise. */
+ result->kind = MOUSE_CLICK_EVENT;
+ result->code = event->button - 1;
+ result->timestamp = event->time;
+ result->modifiers =
+ (pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), event->state) |
+ (event->type == GDK_BUTTON_RELEASE ? up_modifier : down_modifier));
+
+ XSETINT (result->x, event->x);
+ XSETINT (result->y, event->y);
+ XSETFRAME (result->frame_or_window, f);
+ result->arg = Qnil;
+ return Qnil;
+}
+
+static gboolean
+button_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data)
+{
+ union buffered_input_event inev;
+ struct frame *f, *frame;
+ struct pgtk_display_info *dpyinfo;
+
+ /* If we decide we want to generate an event to be seen
+ by the rest of Emacs, we put it here. */
+ bool tab_bar_p = false;
+ bool tool_bar_p = false;
+ Lisp_Object tab_bar_arg = Qnil;
+
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = NO_EVENT;
+ inev.ie.arg = Qnil;
+
+ /* ignore double click and triple click. */
+ if (event->type != GDK_BUTTON_PRESS && event->type != GDK_BUTTON_RELEASE)
+ return TRUE;
+
+ frame = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
+ dpyinfo = FRAME_DISPLAY_INFO (frame);
+
+ dpyinfo->last_mouse_glyph_frame = NULL;
+#if 0
+ x_display_set_last_user_time (dpyinfo, event->button.time);
+#endif
+
+ if (gui_mouse_grabbed (dpyinfo))
+ f = dpyinfo->last_mouse_frame;
+ else
+ {
+ f = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
+
+ if (f && event->button.type == GDK_BUTTON_PRESS
+ && !FRAME_NO_ACCEPT_FOCUS (f))
+ {
+ /* When clicking into a child frame or when clicking
+ into a parent frame with the child frame selected and
+ `no-accept-focus' is not set, select the clicked
+ frame. */
+ struct frame *hf = dpyinfo->highlight_frame;
+
+ if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf)))
+ {
+ block_input ();
+ gtk_widget_grab_focus (FRAME_GTK_WIDGET (f));
+
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ gtk_window_present (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
+ unblock_input ();
+ }
+ }
+ }
+
+ /* xg_event_is_for_scrollbar() doesn't work correctly on sway, and
+ * we shouldn't need it.
+ */
+#if 0
+ if (f && xg_event_is_for_scrollbar (f, event))
+ f = 0;
+#endif
+
+ if (f)
+ {
+ /* Is this in the tab-bar? */
+ if (WINDOWP (f->tab_bar_window)
+ && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
+ {
+ Lisp_Object window;
+ int x = event->button.x;
+ int y = event->button.y;
+
+ window = window_from_coordinates (f, x, y, 0, true, true);
+ tab_bar_p = EQ (window, f->tab_bar_window);
+
+ if (tab_bar_p)
+ tab_bar_arg = handle_tab_bar_click
+ (f, x, y, event->type == GDK_BUTTON_PRESS,
+ pgtk_gtk_to_emacs_modifiers (dpyinfo, event->button.state));
+ }
+ }
+
+ if (f)
+ {
+ if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p)
+ {
+ if (ignore_next_mouse_click_timeout)
+ {
+ if (event->type == GDK_BUTTON_PRESS
+ && event->button.time > ignore_next_mouse_click_timeout)
+ {
+ ignore_next_mouse_click_timeout = 0;
+ construct_mouse_click (&inev.ie, &event->button, f);
+ }
+ if (event->type == GDK_BUTTON_RELEASE)
+ ignore_next_mouse_click_timeout = 0;
+ }
+ else
+ construct_mouse_click (&inev.ie, &event->button, f);
+
+ if (!NILP (tab_bar_arg))
+ inev.ie.arg = tab_bar_arg;
+ }
+#if 0
+ if (FRAME_X_EMBEDDED_P (f))
+ xembed_send_message (f, event->button.time,
+ XEMBED_REQUEST_FOCUS, 0, 0, 0);
+#endif
+ }
+
+ if (event->type == GDK_BUTTON_PRESS)
+ {
+ dpyinfo->grabbed |= (1 << event->button.button);
+ dpyinfo->last_mouse_frame = f;
+
+ if (dpyinfo->last_click_event != NULL)
+ gdk_event_free (dpyinfo->last_click_event);
+ dpyinfo->last_click_event = gdk_event_copy (event);
+ }
+ else
+ dpyinfo->grabbed &= ~(1 << event->button.button);
+
+ /* Ignore any mouse motion that happened before this event;
+ any subsequent mouse-movement Emacs events should reflect
+ only motion after the ButtonPress/Release. */
+ if (f != 0)
+ f->mouse_moved = false;
+
+ if (inev.ie.kind != NO_EVENT)
+ evq_enqueue (&inev);
+ return TRUE;
+}
+
+static gboolean
+scroll_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data)
+{
+ union buffered_input_event inev;
+ struct frame *f, *frame;
+ struct pgtk_display_info *dpyinfo;
+ GdkScrollDirection dir;
+ double delta_x, delta_y;
+
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = NO_EVENT;
+ inev.ie.arg = Qnil;
+
+ frame = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
+ dpyinfo = FRAME_DISPLAY_INFO (frame);
+
+ if (gui_mouse_grabbed (dpyinfo))
+ f = dpyinfo->last_mouse_frame;
+ else
+ f = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
+
+ inev.ie.kind = NO_EVENT;
+ inev.ie.timestamp = event->scroll.time;
+ inev.ie.modifiers =
+ pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), event->scroll.state);
+ XSETINT (inev.ie.x, event->scroll.x);
+ XSETINT (inev.ie.y, event->scroll.y);
+ XSETFRAME (inev.ie.frame_or_window, f);
+ inev.ie.arg = Qnil;
+
+ if (gdk_event_is_scroll_stop_event (event))
+ {
+ inev.ie.kind = TOUCH_END_EVENT;
+ evq_enqueue (&inev);
+ return TRUE;
+ }
+
+ if (gdk_event_get_scroll_direction (event, &dir))
+ {
+ switch (dir)
+ {
+ case GDK_SCROLL_UP:
+ inev.ie.kind = WHEEL_EVENT;
+ inev.ie.modifiers |= up_modifier;
+ break;
+ case GDK_SCROLL_DOWN:
+ inev.ie.kind = WHEEL_EVENT;
+ inev.ie.modifiers |= down_modifier;
+ break;
+ case GDK_SCROLL_LEFT:
+ inev.ie.kind = HORIZ_WHEEL_EVENT;
+ inev.ie.modifiers |= up_modifier;
+ break;
+ case GDK_SCROLL_RIGHT:
+ inev.ie.kind = HORIZ_WHEEL_EVENT;
+ inev.ie.modifiers |= down_modifier;
+ break;
+ case GDK_SCROLL_SMOOTH: /* shut up warning */
+ break;
+ }
+ }
+ else if (gdk_event_get_scroll_deltas (event, &delta_x, &delta_y))
+ {
+ dpyinfo->scroll.acc_x += delta_x;
+ dpyinfo->scroll.acc_y += delta_y;
+ if (dpyinfo->scroll.acc_y >= dpyinfo->scroll.y_per_line
+ || !mwheel_coalesce_scroll_events)
+ {
+ int nlines = dpyinfo->scroll.acc_y / dpyinfo->scroll.y_per_line;
+ inev.ie.kind = WHEEL_EVENT;
+ inev.ie.modifiers |= down_modifier;
+ inev.ie.arg = list3 (make_fixnum (nlines),
+ make_float (-dpyinfo->scroll.acc_x * 100),
+ make_float (-dpyinfo->scroll.acc_y * 100));
+ if (!mwheel_coalesce_scroll_events)
+ {
+ dpyinfo->scroll.acc_y = 0;
+ dpyinfo->scroll.acc_x = 0;
+ }
+ else
+ {
+ dpyinfo->scroll.acc_y -= dpyinfo->scroll.y_per_line * nlines;
+ }
+ }
+ else if (dpyinfo->scroll.acc_y <= -dpyinfo->scroll.y_per_line
+ || !mwheel_coalesce_scroll_events)
+ {
+ int nlines = -dpyinfo->scroll.acc_y / dpyinfo->scroll.y_per_line;
+ inev.ie.kind = WHEEL_EVENT;
+ inev.ie.modifiers |= up_modifier;
+ inev.ie.arg = list3 (make_fixnum (nlines),
+ make_float (-dpyinfo->scroll.acc_x * 100),
+ make_float (-dpyinfo->scroll.acc_y * 100));
+
+ if (!mwheel_coalesce_scroll_events)
+ {
+ dpyinfo->scroll.acc_y = 0;
+ dpyinfo->scroll.acc_x = 0;
+ }
+ else
+ dpyinfo->scroll.acc_y -= -dpyinfo->scroll.y_per_line * nlines;
+ }
+ else if (dpyinfo->scroll.acc_x >= dpyinfo->scroll.x_per_char
+ || !mwheel_coalesce_scroll_events)
+ {
+ int nchars = dpyinfo->scroll.acc_x / dpyinfo->scroll.x_per_char;
+ inev.ie.kind = HORIZ_WHEEL_EVENT;
+ inev.ie.modifiers |= up_modifier;
+ inev.ie.arg = list3 (make_fixnum (nchars),
+ make_float (-dpyinfo->scroll.acc_x * 100),
+ make_float (-dpyinfo->scroll.acc_y * 100));
+
+ if (mwheel_coalesce_scroll_events)
+ dpyinfo->scroll.acc_x -= dpyinfo->scroll.x_per_char * nchars;
+ else
+ {
+ dpyinfo->scroll.acc_x = 0;
+ dpyinfo->scroll.acc_y = 0;
+ }
+ }
+ else if (dpyinfo->scroll.acc_x <= -dpyinfo->scroll.x_per_char)
+ {
+ int nchars = -dpyinfo->scroll.acc_x / dpyinfo->scroll.x_per_char;
+ inev.ie.kind = HORIZ_WHEEL_EVENT;
+ inev.ie.modifiers |= down_modifier;
+ inev.ie.arg = list3 (make_fixnum (nchars),
+ make_float (-dpyinfo->scroll.acc_x * 100),
+ make_float (-dpyinfo->scroll.acc_y * 100));
+
+ if (mwheel_coalesce_scroll_events)
+ dpyinfo->scroll.acc_x -= -dpyinfo->scroll.x_per_char * nchars;
+ else
+ {
+ dpyinfo->scroll.acc_x = 0;
+ dpyinfo->scroll.acc_y = 0;
+ }
+ }
+ }
+
+ if (inev.ie.kind != NO_EVENT)
+ evq_enqueue (&inev);
+ return TRUE;
+}
+
+static void
+drag_data_received (GtkWidget * widget, GdkDragContext * context,
+ gint x, gint y,
+ GtkSelectionData * data,
+ guint info, guint time, gpointer user_data)
+{
+ struct frame *f = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
+ gchar **uris = gtk_selection_data_get_uris (data);
+
+ if (uris != NULL)
+ {
+ for (int i = 0; uris[i] != NULL; i++)
+ {
+ union buffered_input_event inev;
+ Lisp_Object arg = Qnil;
+
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = NO_EVENT;
+ inev.ie.arg = Qnil;
+
+ arg = list2 (Qurl, build_string (uris[i]));
+
+ inev.ie.kind = DRAG_N_DROP_EVENT;
+ inev.ie.modifiers = 0;
+ XSETINT (inev.ie.x, x);
+ XSETINT (inev.ie.y, y);
+ XSETFRAME (inev.ie.frame_or_window, f);
+ inev.ie.arg = arg;
+ inev.ie.timestamp = 0;
+
+ evq_enqueue (&inev);
+ }
+ }
+
+ gtk_drag_finish (context, TRUE, FALSE, time);
+}
+
+void
+pgtk_set_event_handler (struct frame *f)
+{
+ if (f->tooltip)
+ {
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "draw",
+ G_CALLBACK (pgtk_handle_draw), NULL);
+ return;
+ }
+
+ gtk_drag_dest_set (FRAME_GTK_WIDGET (f), GTK_DEST_DEFAULT_ALL, NULL, 0,
+ GDK_ACTION_COPY);
+ gtk_drag_dest_add_uri_targets (FRAME_GTK_WIDGET (f));
+
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)),
+ "window-state-event", G_CALLBACK (window_state_event),
+ NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "delete-event",
+ G_CALLBACK (delete_event), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "event",
+ G_CALLBACK (pgtk_handle_event), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "configure-event",
+ G_CALLBACK (configure_event), NULL);
+ }
+
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "map-event",
+ G_CALLBACK (map_event), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "size-allocate",
+ G_CALLBACK (size_allocate), f);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "key-press-event",
+ G_CALLBACK (key_press_event), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "key-release-event",
+ G_CALLBACK (key_release_event), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "focus-in-event",
+ G_CALLBACK (focus_in_event), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "focus-out-event",
+ G_CALLBACK (focus_out_event), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "enter-notify-event",
+ G_CALLBACK (enter_notify_event), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "leave-notify-event",
+ G_CALLBACK (leave_notify_event), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "motion-notify-event",
+ G_CALLBACK (motion_notify_event), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "button-press-event",
+ G_CALLBACK (button_event), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "button-release-event",
+ G_CALLBACK (button_event), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "scroll-event",
+ G_CALLBACK (scroll_event), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "selection-clear-event",
+ G_CALLBACK (pgtk_selection_lost), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "configure-event",
+ G_CALLBACK (configure_event), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "drag-data-received",
+ G_CALLBACK (drag_data_received), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "draw",
+ G_CALLBACK (pgtk_handle_draw), NULL);
+ g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "event",
+ G_CALLBACK (pgtk_handle_event), NULL);
+}
+
+static void
+my_log_handler (const gchar * log_domain, GLogLevelFlags log_level,
+ const gchar * msg, gpointer user_data)
+{
+ if (!strstr (msg, "g_set_prgname"))
+ fprintf (stderr, "%s-WARNING **: %s", log_domain, msg);
+}
+
+/* Test whether two display-name strings agree up to the dot that separates
+ the screen number from the server number. */
+static bool
+same_x_server (const char *name1, const char *name2)
+{
+ bool seen_colon = false;
+ Lisp_Object sysname = Fsystem_name ();
+ const char *system_name = SSDATA (sysname);
+ ptrdiff_t system_name_length = SBYTES (sysname);
+ ptrdiff_t length_until_period = 0;
+
+ while (system_name[length_until_period] != 0
+ && system_name[length_until_period] != '.')
+ length_until_period++;
+
+ /* Treat `unix' like an empty host name. */
+ if (!strncmp (name1, "unix:", 5))
+ name1 += 4;
+ if (!strncmp (name2, "unix:", 5))
+ name2 += 4;
+ /* Treat this host's name like an empty host name. */
+ if (!strncmp (name1, system_name, system_name_length)
+ && name1[system_name_length] == ':')
+ name1 += system_name_length;
+ if (!strncmp (name2, system_name, system_name_length)
+ && name2[system_name_length] == ':')
+ name2 += system_name_length;
+ /* Treat this host's domainless name like an empty host name. */
+ if (!strncmp (name1, system_name, length_until_period)
+ && name1[length_until_period] == ':')
+ name1 += length_until_period;
+ if (!strncmp (name2, system_name, length_until_period)
+ && name2[length_until_period] == ':')
+ name2 += length_until_period;
+
+ for (; *name1 != '\0' && *name1 == *name2; name1++, name2++)
+ {
+ if (*name1 == ':')
+ seen_colon = true;
+ if (seen_colon && *name1 == '.')
+ return true;
+ }
+ return (seen_colon
+ && (*name1 == '.' || *name1 == '\0')
+ && (*name2 == '.' || *name2 == '\0'));
+}
+
+#define GNOME_INTERFACE_SCHEMA "org.gnome.desktop.interface"
+
+static gdouble pgtk_text_scaling_factor (void)
+{
+ GSettingsSchemaSource *schema_source = g_settings_schema_source_get_default ();
+ if (schema_source != NULL)
+ {
+ GSettingsSchema *schema = g_settings_schema_source_lookup (schema_source,
+ GNOME_INTERFACE_SCHEMA, true);
+ if (schema != NULL)
+ {
+ g_settings_schema_unref (schema);
+ GSettings *set = g_settings_new (GNOME_INTERFACE_SCHEMA);
+ return g_settings_get_double (set, "text-scaling-factor");
+ }
+ }
+ return 1;
+}
+
+
+/* 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. */
+
+struct pgtk_display_info *
+pgtk_term_init (Lisp_Object display_name, char *resource_name)
+{
+ GdkDisplay *dpy;
+ struct terminal *terminal;
+ struct pgtk_display_info *dpyinfo;
+ static int x_initialized = 0;
+ static unsigned x_display_id = 0;
+ static char *initial_display = NULL;
+ static dynlib_handle_ptr *handle = NULL;
+ char *dpy_name;
+ Lisp_Object lisp_dpy_name = Qnil;
+
+ block_input ();
+
+ if (!x_initialized)
+ {
+ any_help_event_p = false;
+
+ Fset_input_interrupt_mode (Qt);
+ baud_rate = 19200;
+
+#ifdef USE_CAIRO
+ gui_init_fringe (&pgtk_redisplay_interface);
+#endif
+
+ ++x_initialized;
+ }
+
+ dpy_name = SSDATA (display_name);
+ if (strlen (dpy_name) == 0 && initial_display != NULL)
+ dpy_name = initial_display;
+ lisp_dpy_name = build_string (dpy_name);
+
+ {
+#define NUM_ARGV 10
+ int argc;
+ char *argv[NUM_ARGV];
+ char **argv2 = argv;
+ guint id;
+
+ if (x_initialized++ > 1)
+ {
+ xg_display_open (dpy_name, &dpy);
+ }
+ else
+ {
+ static char display_opt[] = "--display";
+ static char name_opt[] = "--name";
+
+ for (argc = 0; argc < NUM_ARGV; ++argc)
+ argv[argc] = 0;
+
+ argc = 0;
+ argv[argc++] = initial_argv[0];
+
+ if (strlen (dpy_name) != 0)
+ {
+ argv[argc++] = display_opt;
+ argv[argc++] = dpy_name;
+ }
+
+ argv[argc++] = name_opt;
+ argv[argc++] = resource_name;
+
+ /* Work around GLib bug that outputs a faulty warning. See
+ https://bugzilla.gnome.org/show_bug.cgi?id=563627. */
+ id = g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL
+ | G_LOG_FLAG_RECURSION, my_log_handler, NULL);
+
+ /* gtk_init does set_locale. Fix locale before and after. */
+ fixup_locale ();
+ unrequest_sigio (); /* See comment in x_display_ok. */
+ gtk_init (&argc, &argv2);
+ request_sigio ();
+ fixup_locale ();
+
+
+ g_log_remove_handler ("GLib", id);
+
+ xg_initialize ();
+
+ dpy = DEFAULT_GDK_DISPLAY ();
+
+ initial_display = g_strdup (gdk_display_get_name (dpy));
+ dpy_name = initial_display;
+ lisp_dpy_name = build_string (dpy_name);
+ }
+ }
+
+ /* Detect failure. */
+ if (dpy == 0)
+ {
+ unblock_input ();
+ return 0;
+ }
+
+
+ dpyinfo = xzalloc (sizeof *dpyinfo);
+ pgtk_initialize_display_info (dpyinfo);
+ terminal = pgtk_create_terminal (dpyinfo);
+
+ {
+ struct pgtk_display_info *share;
+
+ for (share = x_display_list; share; share = share->next)
+ if (same_x_server (SSDATA (XCAR (share->name_list_element)), dpy_name))
+ break;
+ if (share)
+ terminal->kboard = share->terminal->kboard;
+ else
+ {
+ terminal->kboard = allocate_kboard (Qpgtk);
+
+ /* Don't let the initial kboard remain current longer than necessary.
+ That would cause problems if a file loaded on startup tries to
+ prompt in the mini-buffer. */
+ if (current_kboard == initial_kboard)
+ current_kboard = terminal->kboard;
+ }
+ terminal->kboard->reference_count++;
+ }
+
+ /* Put this display on the chain. */
+ dpyinfo->next = x_display_list;
+ x_display_list = dpyinfo;
+
+ dpyinfo->name_list_element = Fcons (lisp_dpy_name, Qnil);
+ dpyinfo->gdpy = dpy;
+
+ /* https://lists.gnu.org/r/emacs-devel/2015-11/msg00194.html */
+ dpyinfo->smallest_font_height = 1;
+ dpyinfo->smallest_char_width = 1;
+
+ /* Set the name of the terminal. */
+ terminal->name = xlispstrdup (lisp_dpy_name);
+
+ Lisp_Object system_name = Fsystem_name ();
+ ptrdiff_t nbytes;
+ if (INT_ADD_WRAPV (SBYTES (Vinvocation_name), SBYTES (system_name) + 2,
+ &nbytes))
+ memory_full (SIZE_MAX);
+ dpyinfo->x_id = ++x_display_id;
+ dpyinfo->x_id_name = xmalloc (nbytes);
+ char *nametail = lispstpcpy (dpyinfo->x_id_name, Vinvocation_name);
+ *nametail++ = '@';
+ lispstpcpy (nametail, system_name);
+
+ /* Figure out which modifier bits mean what. */
+ x_find_modifier_meanings (dpyinfo);
+
+ /* Get the scroll bar cursor. */
+ /* We must create a GTK cursor, it is required for GTK widgets. */
+ dpyinfo->xg_cursor = xg_create_default_cursor (dpyinfo->gdpy);
+
+ dpyinfo->vertical_scroll_bar_cursor
+ = gdk_cursor_new_for_display (dpyinfo->gdpy, GDK_SB_V_DOUBLE_ARROW);
+
+ dpyinfo->horizontal_scroll_bar_cursor
+ = gdk_cursor_new_for_display (dpyinfo->gdpy, GDK_SB_H_DOUBLE_ARROW);
+
+ dpyinfo->icon_bitmap_id = -1;
+
+ reset_mouse_highlight (&dpyinfo->mouse_highlight);
+
+ {
+ GdkScreen *gscr = gdk_display_get_default_screen (dpyinfo->gdpy);
+
+ gdouble dpi = gdk_screen_get_resolution (gscr);
+ if (dpi < 0)
+ dpi = 96.0;
+
+ dpi *= pgtk_text_scaling_factor ();
+ dpyinfo->resx = dpi;
+ dpyinfo->resy = dpi;
+ }
+
+ /* smooth scroll setting */
+ dpyinfo->scroll.x_per_char = 2;
+ dpyinfo->scroll.y_per_line = 2;
+
+ dpyinfo->connection = -1;
+
+ if (!handle)
+ handle = dynlib_open (NULL);
+
+#ifdef GDK_WINDOWING_X11
+ if (!strcmp (G_OBJECT_TYPE_NAME (dpy), "GdkX11Display") && handle)
+ {
+ void *(*gdk_x11_display_get_xdisplay) (GdkDisplay *)
+ = dynlib_sym (handle, "gdk_x11_display_get_xdisplay");
+ int (*x_connection_number) (void *)
+ = dynlib_sym (handle, "XConnectionNumber");
+
+ if (x_connection_number
+ && gdk_x11_display_get_xdisplay)
+ dpyinfo->connection
+ = x_connection_number (gdk_x11_display_get_xdisplay (dpy));
+ }
+#endif
+
+#ifdef GDK_WINDOWING_WAYLAND
+ if (GDK_IS_WAYLAND_DISPLAY (dpy) && handle)
+ {
+ struct wl_display *wl_dpy = gdk_wayland_display_get_wl_display (dpy);
+ int (*display_get_fd) (struct wl_display *)
+ = dynlib_sym (handle, "wl_display_get_fd");
+
+ if (display_get_fd)
+ dpyinfo->connection = display_get_fd (wl_dpy);
+ }
+#endif
+
+ if (dpyinfo->connection >= 0)
+ {
+ add_keyboard_wait_descriptor (dpyinfo->connection);
+#ifdef F_SETOWN
+ fcntl (dpyinfo->connection, F_SETOWN, getpid ());
+#endif /* ! defined (F_SETOWN) */
+
+ if (interrupt_input)
+ init_sigio (dpyinfo->connection);
+ }
+
+ x_setup_pointer_blanking (dpyinfo);
+
+ xsettings_initialize (dpyinfo);
+
+ pgtk_selection_init ();
+
+ pgtk_im_init (dpyinfo);
+
+ unblock_input ();
+
+ return dpyinfo;
+}
+
+/* Get rid of display DPYINFO, deleting all frames on it,
+ and without sending any more commands to the X server. */
+
+static void
+pgtk_delete_display (struct pgtk_display_info *dpyinfo)
+{
+ struct terminal *t;
+
+ /* Close all frames and delete the generic struct terminal for this
+ X display. */
+ for (t = terminal_list; t; t = t->next_terminal)
+ if (t->type == output_pgtk && t->display_info.pgtk == dpyinfo)
+ {
+ delete_terminal (t);
+ break;
+ }
+
+ if (x_display_list == dpyinfo)
+ x_display_list = dpyinfo->next;
+ else
+ {
+ struct pgtk_display_info *tail;
+
+ for (tail = x_display_list; tail; tail = tail->next)
+ if (tail->next == dpyinfo)
+ tail->next = tail->next->next;
+ }
+
+ xfree (dpyinfo);
+}
+
+char *
+pgtk_xlfd_to_fontname (const char *xlfd)
+/* --------------------------------------------------------------------------
+ Convert an X font name (XLFD) to an Gtk font name.
+ Only family is used.
+ The string returned is temporarily allocated.
+ -------------------------------------------------------------------------- */
+{
+ char *name = xmalloc (180);
+
+ if (!strncmp (xlfd, "--", 2))
+ {
+ if (sscanf (xlfd, "--%179[^-]-", name) != 1)
+ name[0] = '\0';
+ }
+ else
+ {
+ if (sscanf (xlfd, "-%*[^-]-%179[^-]-", name) != 1)
+ name[0] = '\0';
+ }
+
+ /* stopgap for malformed XLFD input */
+ if (strlen (name) == 0)
+ strcpy (name, "Monospace");
+
+ return name;
+}
+
+bool
+pgtk_defined_color (struct frame *f,
+ const char *name,
+ Emacs_Color * color_def, bool alloc, bool makeIndex)
+/* --------------------------------------------------------------------------
+ Return true if named color found, and set color_def rgb accordingly.
+ If makeIndex and alloc are nonzero put the color in the color_table,
+ and set color_def pixel to the resulting index.
+ If makeIndex is zero, set color_def pixel to ARGB.
+ Return false if not found
+ -------------------------------------------------------------------------- */
+{
+ int r;
+
+ block_input ();
+ r = xg_check_special_colors (f, name, color_def);
+ if (!r)
+ r = pgtk_parse_color (f, name, color_def);
+ unblock_input ();
+ return r;
+}
+
+/* On frame F, translate the color name to RGB values. Use cached
+ information, if possible.
+
+ Note that there is currently no way to clean old entries out of the
+ cache. However, it is limited to names in the server's database,
+ and names we've actually looked up; list-colors-display is probably
+ the most color-intensive case we're likely to hit. */
+
+int
+pgtk_parse_color (struct frame *f, const char *color_name,
+ Emacs_Color * color)
+{
+ GdkRGBA rgba;
+ if (gdk_rgba_parse (&rgba, color_name))
+ {
+ color->red = rgba.red * 65535;
+ color->green = rgba.green * 65535;
+ color->blue = rgba.blue * 65535;
+ color->pixel =
+ (color->red >> 8) << 16 |
+ (color->green >> 8) << 8 |
+ (color->blue >> 8) << 0;
+ return 1;
+ }
+ return 0;
+}
+
+/* On frame F, translate pixel colors to RGB values for the NCOLORS
+ colors in COLORS. On W32, we no longer try to map colors to
+ a palette. */
+void
+pgtk_query_colors (struct frame *f, Emacs_Color * colors, int ncolors)
+{
+ int i;
+
+ for (i = 0; i < ncolors; i++)
+ {
+ unsigned long pixel = colors[i].pixel;
+ /* Convert to a 16 bit value in range 0 - 0xffff. */
+#define GetRValue(p) (((p) >> 16) & 0xff)
+#define GetGValue(p) (((p) >> 8) & 0xff)
+#define GetBValue(p) (((p) >> 0) & 0xff)
+ colors[i].red = GetRValue (pixel) * 257;
+ colors[i].green = GetGValue (pixel) * 257;
+ colors[i].blue = GetBValue (pixel) * 257;
+ }
+}
+
+void
+pgtk_query_color (struct frame *f, Emacs_Color * color)
+{
+ pgtk_query_colors (f, color, 1);
+}
+
+void
+pgtk_clear_area (struct frame *f, int x, int y, int width, int height)
+{
+ cairo_t *cr;
+
+ eassert (width > 0 && height > 0);
+
+ cr = pgtk_begin_cr_clip (f);
+ pgtk_set_cr_source_with_color (f, FRAME_X_OUTPUT (f)->background_color);
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_fill (cr);
+ pgtk_end_cr_clip (f);
+}
+
+
+void
+syms_of_pgtkterm (void)
+{
+ /* from 23+ we need to tell emacs what modifiers there are.. */
+ DEFSYM (Qmodifier_value, "modifier-value");
+ DEFSYM (Qalt, "alt");
+ DEFSYM (Qhyper, "hyper");
+ DEFSYM (Qmeta, "meta");
+ DEFSYM (Qsuper, "super");
+ DEFSYM (Qcontrol, "control");
+ DEFSYM (QUTF8_STRING, "UTF8_STRING");
+
+ DEFSYM (Qfile, "file");
+ DEFSYM (Qurl, "url");
+
+ DEFSYM (Qlatin_1, "latin-1");
+
+ xg_default_icon_file =
+ build_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg");
+ staticpro (&xg_default_icon_file);
+
+ DEFSYM (Qx_gtk_map_stock, "x-gtk-map-stock");
+
+
+ Fput (Qalt, Qmodifier_value, make_fixnum (alt_modifier));
+ Fput (Qhyper, Qmodifier_value, make_fixnum (hyper_modifier));
+ Fput (Qmeta, Qmodifier_value, make_fixnum (meta_modifier));
+ Fput (Qsuper, Qmodifier_value, make_fixnum (super_modifier));
+ Fput (Qcontrol, Qmodifier_value, make_fixnum (ctrl_modifier));
+
+ DEFVAR_LISP ("x-ctrl-keysym", Vx_ctrl_keysym,
+ doc: /* Which keys Emacs uses for the ctrl modifier.
+This should be one of the symbols `ctrl', `alt', `hyper', `meta',
+`super'. For example, `ctrl' means use the Ctrl_L and Ctrl_R keysyms.
+The default is nil, which is the same as `ctrl'. */ );
+ Vx_ctrl_keysym = Qnil;
+
+ DEFVAR_LISP ("x-alt-keysym", Vx_alt_keysym,
+ doc: /* Which keys Emacs uses for the alt modifier.
+This should be one of the symbols `ctrl', `alt', `hyper', `meta',
+`super'. For example, `alt' means use the Alt_L and Alt_R keysyms.
+The default is nil, which is the same as `alt'. */ );
+ Vx_alt_keysym = Qnil;
+
+ DEFVAR_LISP ("x-hyper-keysym", Vx_hyper_keysym,
+ doc: /* Which keys Emacs uses for the hyper modifier.
+This should be one of the symbols `ctrl', `alt', `hyper', `meta',
+`super'. For example, `hyper' means use the Hyper_L and Hyper_R
+keysyms. The default is nil, which is the same as `hyper'. */ );
+ Vx_hyper_keysym = Qnil;
+
+ DEFVAR_LISP ("x-meta-keysym", Vx_meta_keysym,
+ doc: /* Which keys Emacs uses for the meta modifier.
+This should be one of the symbols `ctrl', `alt', `hyper', `meta',
+`super'. For example, `meta' means use the Meta_L and Meta_R keysyms.
+The default is nil, which is the same as `meta'. */ );
+ Vx_meta_keysym = Qnil;
+
+ DEFVAR_LISP ("x-super-keysym", Vx_super_keysym,
+ doc: /* Which keys Emacs uses for the super modifier.
+This should be one of the symbols `ctrl', `alt', `hyper', `meta',
+`super'. For example, `super' means use the Super_L and Super_R
+keysyms. The default is nil, which is the same as `super'. */ );
+ Vx_super_keysym = Qnil;
+
+ /* TODO: move to common code */
+ DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars,
+ doc: /* Which toolkit scroll bars Emacs uses, if any.
+A value of nil means Emacs doesn't use toolkit scroll bars.
+With the X Window system, the value is a symbol describing the
+X toolkit. Possible values are: gtk, motif, xaw, or xaw3d.
+With MS Windows or Nextstep, the value is t. */ );
+ /* Vx_toolkit_scroll_bars = Qt; */
+ Vx_toolkit_scroll_bars = intern_c_string ("gtk");
+
+ DEFVAR_BOOL ("x-use-underline-position-properties", x_use_underline_position_properties,
+ doc: /*Non-nil means make use of UNDERLINE_POSITION font properties.
+A value of nil means ignore them. If you encounter fonts with bogus
+UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
+to 4.1, set this to nil. */);
+ x_use_underline_position_properties = 0;
+
+ DEFVAR_BOOL ("x-underline-at-descent-line", x_underline_at_descent_line,
+ doc: /* Non-nil means to draw the underline at the same place as the descent line.
+A value of nil means to draw the underline according to the value of the
+variable `x-use-underline-position-properties', which is usually at the
+baseline level. The default value is nil. */);
+ x_underline_at_descent_line = 0;
+
+ DEFVAR_BOOL ("x-gtk-use-window-move", x_gtk_use_window_move,
+ doc: /* Non-nil means rely on gtk_window_move to set frame positions.
+If this variable is t (the default), the GTK build uses the function
+gtk_window_move to set or store frame positions and disables some time
+consuming frame position adjustments. In newer versions of GTK, Emacs
+always uses gtk_window_move and ignores the value of this variable. */);
+ x_gtk_use_window_move = true;
+
+
+ DEFVAR_LISP ("pgtk-wait-for-event-timeout", Vpgtk_wait_for_event_timeout,
+ doc: /* How long to wait for X events.
+
+Emacs will wait up to this many seconds to receive X events after
+making changes which affect the state of the graphical interface.
+Under some window managers this can take an indefinite amount of time,
+so it is important to limit the wait.
+
+If set to a non-float value, there will be no wait at all. */);
+ Vpgtk_wait_for_event_timeout = make_float (0.1);
+
+ DEFVAR_LISP ("pgtk-keysym-table", Vpgtk_keysym_table,
+ doc: /* Hash table of character codes indexed by X keysym codes. */);
+ Vpgtk_keysym_table =
+ make_hash_table (hashtest_eql, 900, DEFAULT_REHASH_SIZE,
+ DEFAULT_REHASH_THRESHOLD, Qnil, false);
+
+ window_being_scrolled = Qnil;
+ staticpro (&window_being_scrolled);
+
+ /* Tell Emacs about this window system. */
+ Fprovide (Qpgtk, Qnil);
+}
+
+/* Cairo does not allow resizing a surface/context after it is
+ * created, so we need to trash the old context, create a new context
+ * on the next cr_clip_begin with the new dimensions and request a
+ * re-draw.
+ *
+ * This Will leave the active context available to present on screen
+ * until a redrawn frame is completed.
+ */
+void
+pgtk_cr_update_surface_desired_size (struct frame *f, int width, int height, bool force)
+{
+ if (FRAME_CR_SURFACE_DESIRED_WIDTH (f) != width
+ || FRAME_CR_SURFACE_DESIRED_HEIGHT (f) != height
+ || force)
+ {
+ pgtk_cr_destroy_frame_context (f);
+ FRAME_CR_SURFACE_DESIRED_WIDTH (f) = width;
+ FRAME_CR_SURFACE_DESIRED_HEIGHT (f) = height;
+ SET_FRAME_GARBAGED (f);
+ }
+}
+
+
+cairo_t *
+pgtk_begin_cr_clip (struct frame *f)
+{
+ cairo_t *cr = FRAME_CR_CONTEXT (f);
+
+ if (!cr)
+ {
+ cairo_surface_t *surface =
+ gdk_window_create_similar_surface (gtk_widget_get_window
+ (FRAME_GTK_WIDGET (f)),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ FRAME_CR_SURFACE_DESIRED_WIDTH (f),
+ FRAME_CR_SURFACE_DESIRED_HEIGHT
+ (f));
+
+ cr = FRAME_CR_CONTEXT (f) = cairo_create (surface);
+ cairo_surface_destroy (surface);
+ }
+
+ cairo_save (cr);
+
+ return cr;
+}
+
+void
+pgtk_end_cr_clip (struct frame *f)
+{
+ cairo_restore (FRAME_CR_CONTEXT (f));
+}
+
+void
+pgtk_set_cr_source_with_gc_foreground (struct frame *f, Emacs_GC * gc)
+{
+ pgtk_set_cr_source_with_color (f, gc->foreground);
+}
+
+void
+pgtk_set_cr_source_with_gc_background (struct frame *f, Emacs_GC * gc)
+{
+ pgtk_set_cr_source_with_color (f, gc->background);
+}
+
+void
+pgtk_set_cr_source_with_color (struct frame *f, unsigned long color)
+{
+ Emacs_Color col;
+ col.pixel = color;
+ pgtk_query_color (f, &col);
+ cairo_set_source_rgb (FRAME_CR_CONTEXT (f), col.red / 65535.0,
+ col.green / 65535.0, col.blue / 65535.0);
+}
+
+void
+pgtk_cr_draw_frame (cairo_t * cr, struct frame *f)
+{
+ cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0);
+ cairo_paint (cr);
+}
+
+static cairo_status_t
+pgtk_cr_accumulate_data (void *closure, const unsigned char *data,
+ unsigned int length)
+{
+ Lisp_Object *acc = (Lisp_Object *) closure;
+
+ *acc = Fcons (make_unibyte_string ((char const *) data, length), *acc);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+void
+pgtk_cr_destroy_frame_context (struct frame *f)
+{
+ if (FRAME_CR_CONTEXT (f) != NULL)
+ {
+ cairo_destroy (FRAME_CR_CONTEXT (f));
+ FRAME_CR_CONTEXT (f) = NULL;
+ }
+}
+
+static void
+pgtk_cr_destroy (void *cr)
+{
+ block_input ();
+ cairo_destroy (cr);
+ unblock_input ();
+}
+
+
+
+Lisp_Object
+pgtk_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
+{
+ struct frame *f;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ int width, height;
+ void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
+ Lisp_Object acc = Qnil;
+ ptrdiff_t count = SPECPDL_INDEX ();
+
+ specbind (Qredisplay_dont_pause, Qt);
+ redisplay_preserve_echo_area (31);
+
+ f = XFRAME (XCAR (frames));
+ frames = XCDR (frames);
+ width = FRAME_PIXEL_WIDTH (f);
+ height = FRAME_PIXEL_HEIGHT (f);
+
+ block_input ();
+#ifdef CAIRO_HAS_PDF_SURFACE
+ if (surface_type == CAIRO_SURFACE_TYPE_PDF)
+ {
+ surface = cairo_pdf_surface_create_for_stream (pgtk_cr_accumulate_data, &acc,
+ width, height);
+ surface_set_size_func = cairo_pdf_surface_set_size;
+ }
+ else
+#endif
+#ifdef CAIRO_HAS_PNG_FUNCTIONS
+ if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
+ else
+#endif
+#ifdef CAIRO_HAS_PS_SURFACE
+ if (surface_type == CAIRO_SURFACE_TYPE_PS)
+ {
+ surface = cairo_ps_surface_create_for_stream (pgtk_cr_accumulate_data, &acc,
+ width, height);
+ surface_set_size_func = cairo_ps_surface_set_size;
+ }
+ else
+#endif
+#ifdef CAIRO_HAS_SVG_SURFACE
+ if (surface_type == CAIRO_SURFACE_TYPE_SVG)
+ surface = cairo_svg_surface_create_for_stream (pgtk_cr_accumulate_data, &acc,
+ width, height);
+ else
+#endif
+ abort ();
+
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+ record_unwind_protect_ptr (pgtk_cr_destroy, cr);
+
+ while (1)
+ {
+ cairo_t *saved_cr = FRAME_CR_CONTEXT (f);
+ FRAME_CR_CONTEXT (f) = cr;
+ pgtk_clear_area (f, 0, 0, width, height);
+ expose_frame (f, 0, 0, width, height);
+ FRAME_CR_CONTEXT (f) = saved_cr;
+
+ if (NILP (frames))
+ break;
+
+ cairo_surface_show_page (surface);
+ f = XFRAME (XCAR (frames));
+ frames = XCDR (frames);
+ width = FRAME_PIXEL_WIDTH (f);
+ height = FRAME_PIXEL_HEIGHT (f);
+ if (surface_set_size_func)
+ (*surface_set_size_func) (surface, width, height);
+
+ unblock_input ();
+ maybe_quit ();
+ block_input ();
+ }
+
+#ifdef CAIRO_HAS_PNG_FUNCTIONS
+ if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
+ {
+ cairo_surface_flush (surface);
+ cairo_surface_write_to_png_stream (surface, pgtk_cr_accumulate_data, &acc);
+ }
+#endif
+ unblock_input ();
+
+ unbind_to (count, Qnil);
+
+ return CALLN (Fapply, intern ("concat"), Fnreverse (acc));
+}
+
+
+void
+init_pgtkterm (void)
+{
+}
diff --git a/src/pgtkterm.h b/src/pgtkterm.h
new file mode 100644
index 00000000000..e76411cf021
--- /dev/null
+++ b/src/pgtkterm.h
@@ -0,0 +1,664 @@
+/* Definitions and headers for communication with pure Gtk+3.
+ Copyright (C) 1989, 1993, 2005, 2008-2020 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/>. */
+
+
+#include "dispextern.h"
+#include "frame.h"
+#include "character.h"
+#include "font.h"
+#include "sysselect.h"
+
+#ifdef HAVE_PGTK
+
+#include <gtk/gtk.h>
+
+#ifdef CAIRO_HAS_PDF_SURFACE
+#include <cairo-pdf.h>
+#endif
+#ifdef CAIRO_HAS_PS_SURFACE
+#include <cairo-ps.h>
+#endif
+#ifdef CAIRO_HAS_SVG_SURFACE
+#include <cairo-svg.h>
+#endif
+
+/* could use list to store these, but rest of emacs has a big infrastructure
+ for managing a table of bitmap "records" */
+struct pgtk_bitmap_record
+{
+ void *img;
+ char *file;
+ int refcount;
+ int height, width, depth;
+ cairo_pattern_t *pattern;
+};
+
+#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))
+#define ARGB_TO_ULONG(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+
+#define ALPHA_FROM_ULONG(color) ((color) >> 24)
+#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
+#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
+#define BLUE_FROM_ULONG(color) ((color) & 0xff)
+
+struct scroll_bar
+{
+ /* These fields are shared by all vectors. */
+ union vectorlike_header header;
+
+ /* The window we're a scroll bar for. */
+ Lisp_Object window;
+
+ /* The next and previous in the chain of scroll bars in this frame. */
+ Lisp_Object next, prev;
+
+ /* Fields from `x_window' down will not be traced by the GC. */
+
+ /* The X window representing this scroll bar. */
+ Window x_window;
+
+ /* The position and size of the scroll bar in pixels, relative to the
+ frame. */
+ int top, left, width, height;
+
+ /* The starting and ending positions of the handle, relative to the
+ handle area (i.e. zero is the top position, not
+ SCROLL_BAR_TOP_BORDER). If they're equal, that means the handle
+ hasn't been drawn yet.
+
+ These are not actually the locations where the beginning and end
+ are drawn; in order to keep handles from becoming invisible when
+ editing large files, we establish a minimum height by always
+ drawing handle bottoms VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
+ where they would be normally; the bottom and top are in a
+ different co-ordinate system. */
+ int start, end;
+
+ /* If the scroll bar handle is currently being dragged by the user,
+ this is the number of pixels from the top of the handle to the
+ place where the user grabbed it. If the handle isn't currently
+ being dragged, this is -1. */
+ int dragging;
+
+#if defined (USE_TOOLKIT_SCROLL_BARS) && defined (USE_LUCID)
+ /* Last scroll bar part seen in xaw_jump_callback and xaw_scroll_callback. */
+ enum scroll_bar_part last_seen_part;
+#endif
+
+#if defined (USE_TOOLKIT_SCROLL_BARS) && !defined (USE_GTK)
+ /* Last value of whole for horizontal scrollbars. */
+ int whole;
+#endif
+
+ /* True if the scroll bar is horizontal. */
+ bool horizontal;
+};
+
+
+/* init'd in pgtk_initialize_display_info () */
+struct pgtk_display_info
+{
+ /* Chain of all pgtk_display_info structures. */
+ struct pgtk_display_info *next;
+
+ /* The generic display parameters corresponding to this PGTK display. */
+ struct terminal *terminal;
+
+ /* This says how to access this display in Gdk. */
+ GdkDisplay *gdpy;
+
+ /* This is a cons cell of the form (NAME . FONT-LIST-CACHE). */
+ Lisp_Object name_list_element;
+
+ /* Number of frames that are on this display. */
+ int reference_count;
+
+ /* Logical identifier of this display. */
+ unsigned x_id;
+
+ /* Default name for all frames on this display. */
+ char *x_id_name;
+
+ /* The number of fonts loaded. */
+ int n_fonts;
+
+ /* Minimum width over all characters in all fonts in font_table. */
+ int smallest_char_width;
+
+ /* Minimum font height over all fonts in font_table. */
+ int smallest_font_height;
+
+ struct pgtk_bitmap_record *bitmaps;
+ ptrdiff_t bitmaps_size;
+ ptrdiff_t bitmaps_last;
+
+ /* DPI resolution of this screen */
+ double resx, resy;
+
+ /* Mask of things that cause the mouse to be grabbed */
+ int grabbed;
+
+ int n_planes;
+
+ int color_p;
+
+ /* Emacs bitmap-id of the default icon bitmap for this frame.
+ Or -1 if none has been allocated yet. */
+ ptrdiff_t icon_bitmap_id;
+
+ Window root_window;
+
+ /* Xism */
+ XrmDatabase rdb;
+
+ /* The cursor to use for vertical scroll bars. */
+ Emacs_Cursor vertical_scroll_bar_cursor;
+
+ /* The cursor to use for horizontal scroll bars. */
+ Emacs_Cursor horizontal_scroll_bar_cursor;
+
+ /* Information about the range of text currently shown in
+ mouse-face. */
+ Mouse_HLInfo mouse_highlight;
+
+ struct frame *highlight_frame;
+ struct frame *x_focus_frame;
+
+ /* The last frame mentioned in a FocusIn or FocusOut event. This is
+ separate from x_focus_frame, because whether or not LeaveNotify
+ events cause us to lose focus depends on whether or not we have
+ received a FocusIn event for it. */
+ struct frame *x_focus_event_frame;
+
+ /* The frame where the mouse was last time we reported a mouse event. */
+ struct frame *last_mouse_frame;
+
+ /* The frame where the mouse was last time we reported a mouse motion. */
+ struct frame *last_mouse_motion_frame;
+
+ /* Position where the mouse was last time we reported a motion.
+ This is a position on last_mouse_motion_frame. */
+ int last_mouse_motion_x;
+ int last_mouse_motion_y;
+
+ /* Where the mouse was last time we reported a mouse position. */
+ XRectangle last_mouse_glyph;
+
+ /* Time of last mouse movement. */
+ Time last_mouse_movement_time;
+
+ /* The scroll bar in which the last motion event occurred. */
+ void *last_mouse_scroll_bar;
+
+ /* The invisible cursor used for pointer blanking.
+ Unused if this display supports Xfixes extension. */
+ Emacs_Cursor invisible_cursor;
+
+ /* Function used to toggle pointer visibility on this display. */
+ void (*toggle_visible_pointer) (struct frame *, bool);
+
+ /* The GDK cursor for scroll bars and popup menus. */
+ GdkCursor *xg_cursor;
+
+
+ /* The frame where the mouse was last time we reported a mouse position. */
+ struct frame *last_mouse_glyph_frame;
+
+ /* Modifier masks in gdk */
+ int meta_mod_mask, alt_mod_mask, super_mod_mask, hyper_mod_mask;
+
+ /* The last click event. */
+ GdkEvent *last_click_event;
+
+ /* input method */
+ struct
+ {
+ GtkIMContext *context;
+ struct frame *focused_frame;
+ } im;
+
+ struct
+ {
+ double acc_x, acc_y;
+ double x_per_char, y_per_line;
+ } scroll;
+
+ int connection;
+};
+
+/* This is a chain of structures for all the PGTK displays currently in use. */
+extern struct pgtk_display_info *x_display_list;
+
+struct pgtk_output
+{
+#if 0
+ void *view;
+ void *miniimage;
+#endif
+ unsigned long foreground_color;
+ unsigned long background_color;
+ void *toolbar;
+
+ /* Cursors */
+ Emacs_Cursor current_cursor;
+ Emacs_Cursor text_cursor;
+ Emacs_Cursor nontext_cursor;
+ Emacs_Cursor modeline_cursor;
+ Emacs_Cursor hand_cursor;
+ Emacs_Cursor hourglass_cursor;
+ Emacs_Cursor horizontal_drag_cursor;
+ Emacs_Cursor vertical_drag_cursor;
+ Emacs_Cursor left_edge_cursor;
+ Emacs_Cursor top_left_corner_cursor;
+ Emacs_Cursor top_edge_cursor;
+ Emacs_Cursor top_right_corner_cursor;
+ Emacs_Cursor right_edge_cursor;
+ Emacs_Cursor bottom_right_corner_cursor;
+ Emacs_Cursor bottom_edge_cursor;
+ Emacs_Cursor bottom_left_corner_cursor;
+
+ /* PGTK-specific */
+ Emacs_Cursor current_pointer;
+
+ /* border color */
+ unsigned long border_pixel;
+ GtkCssProvider *border_color_css_provider;
+
+ /* scrollbar color */
+ GtkCssProvider *scrollbar_foreground_css_provider;
+ GtkCssProvider *scrollbar_background_css_provider;
+
+ /* Widget whose cursor is hourglass_cursor. This widget is temporarily
+ mapped to display an hourglass cursor. */
+ GtkWidget *hourglass_widget;
+
+ Emacs_GC cursor_xgcv;
+
+ /* lord knows why Emacs needs to know about our Window ids.. */
+ Window window_desc, parent_desc;
+ char explicit_parent;
+
+ /* If >=0, a bitmap index. The indicated bitmap is used for the
+ icon. */
+ ptrdiff_t icon_bitmap;
+
+ struct font *font;
+ int baseline_offset;
+
+ /* If a fontset is specified for this frame instead of font, this
+ value contains an ID of the fontset, else -1. */
+ int fontset; /* only used with font_backend */
+
+ unsigned long mouse_color;
+ unsigned long cursor_color;
+ unsigned long cursor_foreground_color;
+
+ int icon_top;
+ int icon_left;
+
+ /* The size of the extra width currently allotted for vertical
+ scroll bars, in pixels. */
+ int vertical_scroll_bar_extra;
+
+ /* The height of the titlebar decoration (included in PGTKWindow's frame). */
+ int titlebar_height;
+
+ /* The height of the toolbar if displayed, else 0. */
+ int toolbar_height;
+
+ /* This is the Emacs structure for the PGTK display this frame is on. */
+ struct pgtk_display_info *display_info;
+
+ /* Non-zero if we are zooming (maximizing) the frame. */
+ int zooming;
+
+ /* Non-zero if we are doing an animation, e.g. toggling the tool bar. */
+ int in_animation;
+
+ /* The last size hints set. */
+ GdkGeometry size_hints;
+ long hint_flags;
+ int preferred_width, preferred_height;
+
+ /* The widget of this screen. This is the window of a top widget. */
+ GtkWidget *widget;
+ /* The widget of the edit portion of this screen; the window in
+ "window_desc" is inside of this. */
+ GtkWidget *edit_widget;
+ /* The widget used for laying out widgets vertically. */
+ GtkWidget *vbox_widget;
+ /* The widget used for laying out widgets horizontally. */
+ GtkWidget *hbox_widget;
+ /* The menubar in this frame. */
+ GtkWidget *menubar_widget;
+ /* The tool bar in this frame */
+ GtkWidget *toolbar_widget;
+ /* True if tool bar is packed into the hbox widget (i.e. vertical). */
+ bool_bf toolbar_in_hbox:1;
+ bool_bf toolbar_is_packed:1;
+
+ GtkTooltip *ttip_widget;
+ GtkWidget *ttip_lbl;
+ GtkWindow *ttip_window;
+
+ /* Height of menu bar widget, in pixels. This value
+ is not meaningful if the menubar is turned off. */
+ int menubar_height;
+
+ /* Height of tool bar widget, in pixels. top_height is used if tool bar
+ at top, bottom_height if tool bar is at the bottom.
+ Zero if not using an external tool bar or if tool bar is vertical. */
+ int toolbar_top_height, toolbar_bottom_height;
+
+ /* Width of tool bar widget, in pixels. left_width is used if tool bar
+ at left, right_width if tool bar is at the right.
+ Zero if not using an external tool bar or if tool bar is horizontal. */
+ int toolbar_left_width, toolbar_right_width;
+
+#ifdef USE_CAIRO
+ /* Cairo drawing contexts. */
+ cairo_t *cr_context, *cr_active;
+ int cr_surface_desired_width, cr_surface_desired_height;
+ /* Cairo surface for double buffering */
+ cairo_surface_t *cr_surface_visible_bell;
+#endif
+ struct atimer *atimer_visible_bell;
+
+ int has_been_visible;
+
+ /* Relief GCs, colors etc. */
+ struct relief
+ {
+ Emacs_GC xgcv;
+ unsigned long pixel;
+ }
+ black_relief, white_relief;
+
+ /* The background for which the above relief GCs were set up.
+ They are changed only when a different background is involved. */
+ unsigned long relief_background;
+
+ /* Keep track of focus. May be EXPLICIT if we received a FocusIn for this
+ frame, or IMPLICIT if we received an EnterNotify.
+ FocusOut and LeaveNotify clears EXPLICIT/IMPLICIT. */
+ int focus_state;
+
+ /* Keep track of scale factor. If monitor's scale factor is changed, or
+ monitor is switched and scale factor is changed, then recreate cairo_t
+ and cairo_surface_t. I need GTK's such signal, but there isn't, so
+ I watch it periodically with atimer. */
+ double watched_scale_factor;
+ struct atimer *scale_factor_atimer;
+};
+
+/* this dummy decl needed to support TTYs */
+struct x_output
+{
+ int unused;
+};
+
+enum
+{
+ /* Values for focus_state, used as bit mask.
+ EXPLICIT means we received a FocusIn for the frame and know it has
+ the focus. IMPLICIT means we received an EnterNotify and the frame
+ may have the focus if no window manager is running.
+ FocusOut and LeaveNotify clears EXPLICIT/IMPLICIT. */
+ FOCUS_NONE = 0,
+ FOCUS_IMPLICIT = 1,
+ FOCUS_EXPLICIT = 2
+};
+
+/* This gives the pgtk_display_info structure for the display F is on. */
+#define FRAME_X_OUTPUT(f) ((f)->output_data.pgtk)
+#define FRAME_OUTPUT_DATA(f) FRAME_X_OUTPUT (f)
+
+#define FRAME_DISPLAY_INFO(f) (FRAME_X_OUTPUT (f)->display_info)
+#define FRAME_FOREGROUND_COLOR(f) (FRAME_X_OUTPUT (f)->foreground_color)
+#define FRAME_BACKGROUND_COLOR(f) (FRAME_X_OUTPUT (f)->background_color)
+#define FRAME_CURSOR_COLOR(f) (FRAME_X_OUTPUT (f)->cursor_color)
+#define FRAME_POINTER_TYPE(f) (FRAME_X_OUTPUT (f)->current_pointer)
+#define FRAME_FONT(f) (FRAME_X_OUTPUT (f)->font)
+#define FRAME_GTK_OUTER_WIDGET(f) (FRAME_X_OUTPUT (f)->widget)
+#define FRAME_GTK_WIDGET(f) (FRAME_X_OUTPUT (f)->edit_widget)
+#define FRAME_WIDGET(f) (FRAME_GTK_OUTER_WIDGET (f) ? \
+ FRAME_GTK_OUTER_WIDGET (f) : \
+ FRAME_GTK_WIDGET (f))
+
+/* aliases */
+#define FRAME_PGTK_VIEW(f) FRAME_GTK_WIDGET (f)
+#define FRAME_X_WINDOW(f) FRAME_GTK_OUTER_WIDGET (f)
+#define FRAME_NATIVE_WINDOW(f) GTK_WINDOW (FRAME_X_WINDOW (f))
+
+#define FRAME_X_DISPLAY(f) (FRAME_DISPLAY_INFO (f)->gdpy)
+
+#define DEFAULT_GDK_DISPLAY() gdk_display_get_default ()
+
+/* Turning a lisp vector value into a pointer to a struct scroll_bar. */
+#define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec))
+
+#define PGTK_FACE_FOREGROUND(f) ((f)->foreground)
+#define PGTK_FACE_BACKGROUND(f) ((f)->background)
+#define FRAME_DEFAULT_FACE(f) FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID)
+
+/* Compute pixel height of the frame's titlebar. */
+#define FRAME_PGTK_TITLEBAR_HEIGHT(f) 0
+
+/* Compute pixel size for vertical scroll bars */
+#define PGTK_SCROLL_BAR_WIDTH(f) \
+ (FRAME_HAS_VERTICAL_SCROLL_BARS (f) \
+ ? rint (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0 \
+ ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \
+ : (FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f))) \
+ : 0)
+
+/* Compute pixel size for horizontal scroll bars */
+#define PGTK_SCROLL_BAR_HEIGHT(f) \
+ (FRAME_HAS_HORIZONTAL_SCROLL_BARS (f) \
+ ? rint (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) > 0 \
+ ? FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) \
+ : (FRAME_SCROLL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f))) \
+ : 0)
+
+/* Difference btwn char-column-calculated and actual SB widths.
+ This is only a concern for rendering when SB on left. */
+#define PGTK_SCROLL_BAR_ADJUST(w, f) \
+ (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) ? \
+ (FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f) \
+ - PGTK_SCROLL_BAR_WIDTH (f)) : 0)
+
+/* Difference btwn char-line-calculated and actual SB heights.
+ This is only a concern for rendering when SB on top. */
+#define PGTK_SCROLL_BAR_ADJUST_HORIZONTALLY(w, f) \
+ (WINDOW_HAS_HORIZONTAL_SCROLL_BARS (w) ? \
+ (FRAME_SCROLL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f) \
+ - PGTK_SCROLL_BAR_HEIGHT (f)) : 0)
+
+#define FRAME_MENUBAR_HEIGHT(f) (FRAME_X_OUTPUT (f)->menubar_height)
+
+/* Calculate system coordinates of the left and top of the parent
+ window or, if there is no parent window, the screen. */
+#define PGTK_PARENT_WINDOW_LEFT_POS(f) \
+ (FRAME_PARENT_FRAME (f) != NULL \
+ ? [[FRAME_PGTK_VIEW (f) window] parentWindow].frame.origin.x : 0)
+#define PGTK_PARENT_WINDOW_TOP_POS(f) \
+ (FRAME_PARENT_FRAME (f) != NULL \
+ ? ([[FRAME_PGTK_VIEW (f) window] parentWindow].frame.origin.y \
+ + [[FRAME_PGTK_VIEW (f) window] parentWindow].frame.size.height \
+ - FRAME_PGTK_TITLEBAR_HEIGHT (FRAME_PARENT_FRAME (f))) \
+ : [[[PGTKScreen screepgtk] objectAtIndex: 0] frame].size.height)
+
+#define FRAME_PGTK_FONT_TABLE(f) (FRAME_DISPLAY_INFO (f)->font_table)
+
+#define FRAME_TOOLBAR_TOP_HEIGHT(f) ((f)->output_data.pgtk->toolbar_top_height)
+#define FRAME_TOOLBAR_BOTTOM_HEIGHT(f) \
+ ((f)->output_data.pgtk->toolbar_bottom_height)
+#define FRAME_TOOLBAR_HEIGHT(f) \
+ (FRAME_TOOLBAR_TOP_HEIGHT (f) + FRAME_TOOLBAR_BOTTOM_HEIGHT (f))
+#define FRAME_TOOLBAR_LEFT_WIDTH(f) ((f)->output_data.pgtk->toolbar_left_width)
+#define FRAME_TOOLBAR_RIGHT_WIDTH(f) ((f)->output_data.pgtk->toolbar_right_width)
+#define FRAME_TOOLBAR_WIDTH(f) \
+ (FRAME_TOOLBAR_LEFT_WIDTH (f) + FRAME_TOOLBAR_RIGHT_WIDTH (f))
+
+#define FRAME_FONTSET(f) (FRAME_X_OUTPUT (f)->fontset)
+
+#define FRAME_BASELINE_OFFSET(f) (FRAME_X_OUTPUT (f)->baseline_offset)
+#define BLACK_PIX_DEFAULT(f) 0x000000
+#define WHITE_PIX_DEFAULT(f) 0xFFFFFF
+
+/* First position where characters can be shown (instead of scrollbar, if
+ it is on left. */
+#define FIRST_CHAR_POSITION(f) \
+ (! (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f)) ? 0 \
+ : FRAME_SCROLL_BAR_COLS (f))
+
+#define FRAME_CR_SURFACE_DESIRED_WIDTH(f) \
+ ((f)->output_data.pgtk->cr_surface_desired_width)
+#define FRAME_CR_SURFACE_DESIRED_HEIGHT(f) \
+ ((f)->output_data.pgtk->cr_surface_desired_height)
+
+/* Display init/shutdown functions implemented in pgtkterm.c */
+extern struct pgtk_display_info *pgtk_term_init (Lisp_Object display_name,
+ char *resource_name);
+extern void pgtk_term_shutdown (int sig);
+
+/* Implemented in pgtkterm, published in or needed from pgtkfns. */
+extern void pgtk_clear_frame (struct frame *f);
+extern char *pgtk_xlfd_to_fontname (const char *xlfd);
+
+/* Implemented in pgtkfns. */
+extern void pgtk_set_doc_edited (void);
+extern const char *pgtk_get_defaults_value (const char *key);
+extern const char *pgtk_get_string_resource (XrmDatabase rdb,
+ const char *name,
+ const char *class);
+extern void pgtk_implicitly_set_name (struct frame *f, Lisp_Object arg,
+ Lisp_Object oldval);
+
+/* Color management implemented in pgtkterm. */
+extern bool pgtk_defined_color (struct frame *f,
+ const char *name,
+ Emacs_Color * color_def, bool alloc,
+ bool makeIndex);
+extern void pgtk_query_color (struct frame *f, Emacs_Color * color);
+extern void pgtk_query_colors (struct frame *f, Emacs_Color * colors,
+ int ncolors);
+extern int pgtk_parse_color (struct frame *f, const char *color_name,
+ Emacs_Color * color);
+
+/* Implemented in pgtkterm.c */
+extern void pgtk_clear_area (struct frame *f, int x, int y, int width,
+ int height);
+extern int pgtk_gtk_to_emacs_modifiers (struct pgtk_display_info *dpyinfo,
+ int state);
+extern void pgtk_clear_under_internal_border (struct frame *f);
+extern void pgtk_set_event_handler (struct frame *f);
+
+/* Implemented in pgtkterm.c */
+extern int x_display_pixel_height (struct pgtk_display_info *);
+extern int x_display_pixel_width (struct pgtk_display_info *);
+
+/* Implemented in pgtkterm.c */
+extern void x_destroy_window (struct frame *f);
+extern void x_set_parent_frame (struct frame *f, Lisp_Object new_value,
+ Lisp_Object old_value);
+extern void x_set_no_focus_on_map (struct frame *f, Lisp_Object new_value,
+ Lisp_Object old_value);
+extern void x_set_no_accept_focus (struct frame *f, Lisp_Object new_value,
+ Lisp_Object old_value);
+extern void x_set_z_group (struct frame *f, Lisp_Object new_value,
+ Lisp_Object old_value);
+
+/* Cairo related functions implemented in pgtkterm.c */
+extern void pgtk_cr_update_surface_desired_size (struct frame *, int, int, bool);
+extern cairo_t *pgtk_begin_cr_clip (struct frame *f);
+extern void pgtk_end_cr_clip (struct frame *f);
+extern void pgtk_set_cr_source_with_gc_foreground (struct frame *f,
+ Emacs_GC * gc);
+extern void pgtk_set_cr_source_with_gc_background (struct frame *f,
+ Emacs_GC * gc);
+extern void pgtk_set_cr_source_with_color (struct frame *f,
+ unsigned long color);
+extern void pgtk_cr_draw_frame (cairo_t * cr, struct frame *f);
+extern void pgtk_cr_destroy_frame_context (struct frame *f);
+extern Lisp_Object pgtk_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type);
+
+/* Defined in pgtkmenu.c */
+extern Lisp_Object pgtk_popup_dialog (struct frame *f, Lisp_Object header,
+ Lisp_Object contents);
+extern Lisp_Object pgtk_dialog_show (struct frame *f, Lisp_Object title,
+ Lisp_Object header,
+ const char **error_name);
+extern void initialize_frame_menubar (struct frame *);
+
+
+/* Symbol initializations implemented in each pgtk sources. */
+extern void syms_of_pgtkterm (void);
+extern void syms_of_pgtkfns (void);
+extern void syms_of_pgtkmenu (void);
+extern void syms_of_pgtkselect (void);
+extern void syms_of_pgtkim (void);
+
+/* Implemented in pgtkselect. */
+extern void nxatoms_of_pgtkselect (void);
+
+/* Initialization and marking implemented in pgtkterm.c */
+extern void init_pgtkterm (void);
+extern void mark_pgtkterm (void);
+extern void pgtk_delete_terminal (struct terminal *terminal);
+
+extern void pgtk_make_frame_visible (struct frame *f);
+extern void pgtk_make_frame_invisible (struct frame *f);
+extern void x_wm_set_size_hint (struct frame *, long, bool);
+extern void x_free_frame_resources (struct frame *);
+extern void pgtk_iconify_frame (struct frame *f);
+extern void pgtk_focus_frame (struct frame *f, bool noactivate);
+extern void pgtk_set_scroll_bar_default_width (struct frame *f);
+extern void pgtk_set_scroll_bar_default_height (struct frame *f);
+extern Lisp_Object x_get_focus_frame (struct frame *frame);
+
+extern void pgtk_frame_rehighlight (struct pgtk_display_info *dpyinfo);
+
+extern void x_change_tab_bar_height (struct frame *, int);
+
+extern struct pgtk_display_info *check_pgtk_display_info (Lisp_Object object);
+
+extern void pgtk_default_font_parameter (struct frame *f, Lisp_Object parms);
+
+extern void pgtk_menu_set_in_use (bool in_use);
+
+
+extern void pgtk_enqueue_string (struct frame *f, gchar * str);
+extern void pgtk_enqueue_preedit (struct frame *f, Lisp_Object image_data);
+extern void pgtk_im_focus_in (struct frame *f);
+extern void pgtk_im_focus_out (struct frame *f);
+extern bool pgtk_im_filter_keypress (struct frame *f, GdkEventKey * ev);
+extern void pgtk_im_set_cursor_location (struct frame *f, int x, int y,
+ int width, int height);
+extern void pgtk_im_init (struct pgtk_display_info *dpyinfo);
+extern void pgtk_im_finish (struct pgtk_display_info *dpyinfo);
+
+extern bool xg_set_icon (struct frame *, Lisp_Object);
+extern bool xg_set_icon_from_xpm_data (struct frame *f, const char **data);
+
+extern bool pgtk_text_icon (struct frame *f, const char *icon_name);
+
+extern double pgtk_frame_scale_factor (struct frame *);
+
+#endif /* HAVE_PGTK */
diff --git a/src/print.c b/src/print.c
index d4301fd7b64..214f1d12c11 100644
--- a/src/print.c
+++ b/src/print.c
@@ -564,7 +564,7 @@ temp_output_buffer_setup (const char *bufname)
Fset_buffer (Fget_buffer_create (build_string (bufname), Qnil));
- Fkill_all_local_variables ();
+ Fkill_all_local_variables (Qnil);
delete_all_overlays (current_buffer);
bset_directory (current_buffer, BVAR (old, directory));
bset_read_only (current_buffer, Qnil);
@@ -941,7 +941,11 @@ print_error_message (Lisp_Object data, Lisp_Object stream, const char *context,
else
{
Lisp_Object error_conditions = Fget (errname, Qerror_conditions);
- errmsg = call1 (Qsubstitute_command_keys, Fget (errname, Qerror_message));
+ errmsg = Fget (errname, Qerror_message);
+ /* During loadup 'substitute-command-keys' might not be available. */
+ if (!NILP (Ffboundp (Qsubstitute_command_keys)))
+ errmsg = call1 (Qsubstitute_command_keys, errmsg);
+
file_error = Fmemq (Qfile_error, error_conditions);
}
@@ -1517,8 +1521,26 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag,
printchar ('>', printcharfun);
break;
- case PVEC_XWIDGET: case PVEC_XWIDGET_VIEW:
- print_c_string ("#<xwidget ", printcharfun);
+ case PVEC_XWIDGET:
+#ifdef HAVE_XWIDGETS
+ {
+#ifdef USE_GTK
+ int len = sprintf (buf, "#<xwidget %u %p>",
+ XXWIDGET (obj)->xwidget_id,
+ XXWIDGET (obj)->widget_osr);
+#else
+ int len = sprintf (buf, "#<xwidget %u %p>",
+ XXWIDGET (obj)->xwidget_id,
+ XXWIDGET (obj)->xwWidget);
+#endif
+ strout (buf, len, len, printcharfun);
+ break;
+ }
+#else
+ emacs_abort ();
+#endif
+ case PVEC_XWIDGET_VIEW:
+ print_c_string ("#<xwidget view", printcharfun);
printchar ('>', printcharfun);
break;
@@ -1853,6 +1875,22 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag,
}
break;
#endif
+ case PVEC_SQLITE:
+ {
+ print_c_string ("#<sqlite ", printcharfun);
+ int i = sprintf (buf, "db=%p", XSQLITE (obj)->db);
+ strout (buf, i, i, printcharfun);
+ if (XSQLITE (obj)->is_statement)
+ {
+ i = sprintf (buf, " stmt=%p", XSQLITE (obj)->stmt);
+ strout (buf, i, i, printcharfun);
+ }
+ i = sprintf (buf, " name=%s", XSQLITE (obj)->name);
+ strout (buf, i, i, printcharfun);
+ printchar ('>', printcharfun);
+ }
+ break;
+
default:
emacs_abort ();
}
diff --git a/src/process.c b/src/process.c
index c3186eed750..76094988f25 100644
--- a/src/process.c
+++ b/src/process.c
@@ -40,7 +40,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <netinet/in.h>
#include <arpa/inet.h>
-#endif /* subprocesses */
+#else
+#define PIPECONN_P(p) false
+#define PIPECONN1_P(p) false
+#endif
#ifdef HAVE_SETRLIMIT
# include <sys/resource.h>
@@ -90,6 +93,7 @@ static struct rlimit nofile_limit;
#include <c-ctype.h>
#include <flexmember.h>
+#include <nproc.h>
#include <sig2str.h>
#include <verify.h>
@@ -151,6 +155,7 @@ static bool kbd_is_on_hold;
when exiting. */
bool inhibit_sentinels;
+#ifdef subprocesses
union u_sockaddr
{
struct sockaddr sa;
@@ -163,8 +168,6 @@ union u_sockaddr
#endif
};
-#ifdef subprocesses
-
#ifndef SOCK_CLOEXEC
# define SOCK_CLOEXEC 0
#endif
@@ -258,7 +261,7 @@ static bool process_output_skip;
static void start_process_unwind (Lisp_Object);
static void create_process (Lisp_Object, char **, Lisp_Object);
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
static bool keyboard_bit_set (fd_set *);
#endif
static void deactivate_process (Lisp_Object);
@@ -682,6 +685,22 @@ clear_waiting_thread_info (void)
}
}
+/* Return TRUE if the keyboard descriptor is being monitored by the
+ current thread, FALSE otherwise. */
+static bool
+kbd_is_ours (void)
+{
+ for (int fd = 0; fd <= max_desc; ++fd)
+ {
+ if (fd_callback_info[fd].waiting_thread != current_thread)
+ continue;
+ if ((fd_callback_info[fd].flags & (FOR_READ | KEYBOARD_FD))
+ == (FOR_READ | KEYBOARD_FD))
+ return true;
+ }
+ return false;
+}
+
/* Compute the Lisp form of the process status, p->status, from
the numeric status that was returned by `wait'. */
@@ -1718,7 +1737,10 @@ to use a pty, or nil to use the default specified through
:stderr STDERR -- STDERR is either a buffer or a pipe process attached
to the standard error of subprocess. Specifying this implies
`:connection-type' is set to `pipe'. If STDERR is nil, standard error
-is mixed with standard output and sent to BUFFER or FILTER.
+is mixed with standard output and sent to BUFFER or FILTER. (Note
+that specifying :stderr will create a new, separate (but associated)
+process, with its own filter and sentinel. See
+Info node `(elisp) Asynchronous Processes' for more details.)
:file-handler FILE-HANDLER -- If FILE-HANDLER is non-nil, then look
for a file name handler for the current buffer's `default-directory'
@@ -2147,7 +2169,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
p->pty_flag = pty_flag;
pset_status (p, Qrun);
- if (!EQ (p->command, Qt))
+ if (!EQ (p->command, Qt)
+ && !EQ (p->filter, Qt))
add_process_read_fd (inchannel);
ptrdiff_t count = SPECPDL_INDEX ();
@@ -2265,7 +2288,8 @@ create_pty (Lisp_Object process)
pset_status (p, Qrun);
setup_process_coding_systems (process);
- add_process_read_fd (pty_fd);
+ if (!EQ (p->filter, Qt))
+ add_process_read_fd (pty_fd);
pset_tty_name (p, build_string (pty_name));
}
@@ -2374,7 +2398,8 @@ usage: (make-pipe-process &rest ARGS) */)
pset_command (p, Qt);
eassert (! p->pty_flag);
- if (!EQ (p->command, Qt))
+ if (!EQ (p->command, Qt)
+ && !EQ (p->filter, Qt))
add_process_read_fd (inchannel);
p->adaptive_read_buffering
= (NILP (Vprocess_adaptive_read_buffering) ? 0
@@ -3109,7 +3134,8 @@ usage: (make-serial-process &rest ARGS) */)
pset_command (p, Qt);
eassert (! p->pty_flag);
- if (!EQ (p->command, Qt))
+ if (!EQ (p->command, Qt)
+ && !EQ (p->filter, Qt))
add_process_read_fd (fd);
update_process_mark (p);
@@ -4001,7 +4027,7 @@ usage: (make-network-process &rest ARGS) */)
if (!NILP (host))
{
- ptrdiff_t portstringlen ATTRIBUTE_UNUSED;
+ MAYBE_UNUSED ptrdiff_t portstringlen;
/* SERVICE can either be a string or int.
Convert to a C string for later use by getaddrinfo. */
@@ -5308,13 +5334,13 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
wait_reading_process_output_1 ();
}
- /* Cause C-g and alarm signals to take immediate action,
+ /* Cause C-g signals to take immediate action,
and cause input available signals to zero out timeout.
It is important that we do this before checking for process
activity. If we get a SIGCHLD after the explicit checks for
process activity, timeout is the only way we will know. */
- if (read_kbd < 0)
+ if (read_kbd < 0 && kbd_is_ours ())
set_waiting_for_input (&timeout);
/* If status of something has changed, and no input is
@@ -5444,7 +5470,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
{
clear_waiting_for_input ();
redisplay_preserve_echo_area (11);
- if (read_kbd < 0)
+ if (read_kbd < 0 && kbd_is_ours ())
set_waiting_for_input (&timeout);
}
@@ -5564,6 +5590,15 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
timeout = make_timespec (0, 0);
#endif
+#if !defined USABLE_SIGIO && !defined WINDOWSNT
+ /* If we're polling for input, don't get stuck in select for
+ more than 25 msec. */
+ struct timespec short_timeout = make_timespec (0, 25000000);
+ if ((read_kbd || !NILP (wait_for_cell))
+ && timespec_cmp (short_timeout, timeout) < 0)
+ timeout = short_timeout;
+#endif
+
/* Non-macOS HAVE_GLIB builds call thread_select in xgselect.c. */
#if defined HAVE_GLIB && !defined HAVE_NS
nfds = xg_select (max_desc + 1,
@@ -5697,7 +5732,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
break;
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
/* If we think we have keyboard input waiting, but didn't get SIGIO,
go read it. This can happen with X on BSD after logging out.
In that case, there really is no input and no SIGIO,
@@ -5705,7 +5740,11 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
if (read_kbd && interrupt_input
&& keyboard_bit_set (&Available) && ! noninteractive)
+#ifdef USABLE_SIGIO
handle_input_available_signal (SIGIO);
+#else
+ handle_input_available_signal (SIGPOLL);
+#endif
#endif
/* If checking input just got us a size-change event from X,
@@ -5957,7 +5996,8 @@ read_process_output_error_handler (Lisp_Object error_val)
cmd_error_internal (error_val, "error in process filter: ");
Vinhibit_quit = Qt;
update_echo_area ();
- Fsleep_for (make_fixnum (2), Qnil);
+ if (process_error_pause_time > 0)
+ Fsleep_for (make_fixnum (process_error_pause_time), Qnil);
return Qt;
}
@@ -6498,6 +6538,9 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len,
/* Send this batch, using one or more write calls. */
ptrdiff_t written = 0;
int outfd = p->outfd;
+ if (outfd < 0)
+ error ("Output file descriptor of %s is closed",
+ SDATA (p->name));
eassert (0 <= outfd && outfd < FD_SETSIZE);
#ifdef DATAGRAM_SOCKETS
if (DATAGRAM_CHAN_P (outfd))
@@ -6884,7 +6927,7 @@ If CURRENT-GROUP is `lambda', and if the shell owns the terminal,
don't send the signal.
This function calls the functions of `interrupt-process-functions' in
-the order of the list, until one of them returns non-`nil'. */)
+the order of the list, until one of them returns non-nil. */)
(Lisp_Object process, Lisp_Object current_group)
{
return CALLN (Frun_hook_with_args_until_success, Qinterrupt_process_functions,
@@ -7384,7 +7427,8 @@ exec_sentinel_error_handler (Lisp_Object error_val)
cmd_error_internal (error_val, "error in process sentinel: ");
Vinhibit_quit = Qt;
update_echo_area ();
- Fsleep_for (make_fixnum (2), Qnil);
+ if (process_error_pause_time > 0)
+ Fsleep_for (make_fixnum (process_error_pause_time), Qnil);
return Qt;
}
@@ -7699,7 +7743,7 @@ delete_gpm_wait_descriptor (int desc)
# endif
-# ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
/* Return true if *MASK has a bit set
that corresponds to one of the keyboard input descriptors. */
@@ -8209,6 +8253,24 @@ integer or floating point values.
return system_process_attributes (pid);
}
+DEFUN ("num-processors", Fnum_processors, Snum_processors, 0, 1, 0,
+ doc: /* Return the number of processors, a positive integer.
+Each usable thread execution unit counts as a processor.
+By default, count the number of available processors,
+overridable via the OMP_NUM_THREADS environment variable.
+If optional argument QUERY is `current', ignore OMP_NUM_THREADS.
+If QUERY is `all', also count processors not available. */)
+ (Lisp_Object query)
+{
+#ifndef MSDOS
+ return make_uint (num_processors (EQ (query, Qall) ? NPROC_ALL
+ : EQ (query, Qcurrent) ? NPROC_CURRENT
+ : NPROC_CURRENT_OVERRIDABLE));
+#else
+ return make_fixnum (1);
+#endif
+}
+
#ifdef subprocesses
/* Arrange to catch SIGCHLD if this hasn't already been arranged.
Invoke this after init_process_emacs, and after glib and/or GNUstep
@@ -8251,10 +8313,15 @@ open_channel_for_module (Lisp_Object process)
{
CHECK_PROCESS (process);
CHECK_TYPE (PIPECONN_P (process), Qpipe_process_p, process);
+#ifndef MSDOS
int fd = dup (XPROCESS (process)->open_fd[SUBPROCESS_STDOUT]);
if (fd == -1)
report_file_error ("Cannot duplicate file descriptor", Qnil);
return fd;
+#else
+ /* PIPECONN_P returning true shouldn't be possible on MSDOS. */
+ emacs_abort ();
+#endif
}
@@ -8469,6 +8536,8 @@ syms_of_process (void)
DEFSYM (Qpcpu, "pcpu");
DEFSYM (Qpmem, "pmem");
DEFSYM (Qargs, "args");
+ DEFSYM (Qall, "all");
+ DEFSYM (Qcurrent, "current");
DEFVAR_BOOL ("delete-exited-processes", delete_exited_processes,
doc: /* Non-nil means delete processes immediately when they exit.
@@ -8511,7 +8580,7 @@ thus favoring processes with lower descriptors. */);
doc: /* List of functions to be called for `interrupt-process'.
The arguments of the functions are the same as for `interrupt-process'.
These functions are called in the order of the list, until one of them
-returns non-`nil'. */);
+returns non-nil. */);
Vinterrupt_process_functions = list1 (Qinternal_default_interrupt_process);
DEFVAR_LISP ("internal--daemon-sockname", Vinternal__daemon_sockname,
@@ -8524,6 +8593,12 @@ Enlarge the value only if the subprocess generates very large (megabytes)
amounts of data in one go. */);
read_process_output_max = 4096;
+ DEFVAR_INT ("process-error-pause-time", process_error_pause_time,
+ doc: /* The number of seconds to pause after handling process errors.
+This isn't used for all process-related errors, but is used when a
+sentinel or a process filter function has an error. */);
+ process_error_pause_time = 1;
+
DEFSYM (Qinternal_default_interrupt_process,
"internal-default-interrupt-process");
DEFSYM (Qinterrupt_process_functions, "interrupt-process-functions");
@@ -8630,4 +8705,5 @@ amounts of data in one go. */);
defsubr (&Sprocess_inherit_coding_system_flag);
defsubr (&Slist_system_processes);
defsubr (&Sprocess_attributes);
+ defsubr (&Snum_processors);
}
diff --git a/src/regex-emacs.c b/src/regex-emacs.c
index 8350e54b54a..3224f65fa4c 100644
--- a/src/regex-emacs.c
+++ b/src/regex-emacs.c
@@ -2407,7 +2407,7 @@ regex_compile (re_char *pattern, ptrdiff_t size,
if (lower_bound == 0)
{
- /* A succeed_n that starts with 0 is really a
+ /* A succeed_n that starts with 0 is really
a simple on_failure_jump_loop. */
INSERT_JUMP (on_failure_jump_loop, laststart,
b + 3 + nbytes);
@@ -3828,7 +3828,7 @@ mutually_exclusive_p (struct re_pattern_buffer *bufp, re_char *p1,
/* Matching routines. */
/* re_match_2 matches the compiled pattern in BUFP against the
- the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
+ (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
and SIZE2, respectively). We start matching at POS, and stop
matching at STOP.
diff --git a/src/search.c b/src/search.c
index 14adeb58e96..66e77d42b4a 100644
--- a/src/search.c
+++ b/src/search.c
@@ -260,7 +260,7 @@ compile_pattern (Lisp_Object pattern, struct re_registers *regp,
static Lisp_Object
-looking_at_1 (Lisp_Object string, bool posix)
+looking_at_1 (Lisp_Object string, bool posix, bool modify_data)
{
Lisp_Object val;
unsigned char *p1, *p2;
@@ -278,11 +278,11 @@ looking_at_1 (Lisp_Object string, bool posix)
CHECK_STRING (string);
/* Snapshot in case Lisp changes the value. */
- bool preserve_match_data = NILP (Vinhibit_changing_match_data);
+ bool modify_match_data = NILP (Vinhibit_changing_match_data) && modify_data;
struct regexp_cache *cache_entry = compile_pattern (
string,
- preserve_match_data ? &search_regs : NULL,
+ modify_match_data ? &search_regs : NULL,
(!NILP (BVAR (current_buffer, case_fold_search))
? BVAR (current_buffer, case_canon_table) : Qnil),
posix,
@@ -316,7 +316,7 @@ looking_at_1 (Lisp_Object string, bool posix)
re_match_object = Qnil;
i = re_match_2 (&cache_entry->buf, (char *) p1, s1, (char *) p2, s2,
PT_BYTE - BEGV_BYTE,
- preserve_match_data ? &search_regs : NULL,
+ modify_match_data ? &search_regs : NULL,
ZV_BYTE - BEGV_BYTE);
if (i == -2)
@@ -326,7 +326,7 @@ looking_at_1 (Lisp_Object string, bool posix)
}
val = (i >= 0 ? Qt : Qnil);
- if (preserve_match_data && i >= 0)
+ if (modify_match_data && i >= 0)
{
for (i = 0; i < search_regs.num_regs; i++)
if (search_regs.start[i] >= 0)
@@ -343,35 +343,37 @@ looking_at_1 (Lisp_Object string, bool posix)
return unbind_to (count, val);
}
-DEFUN ("looking-at", Flooking_at, Slooking_at, 1, 1, 0,
+DEFUN ("looking-at", Flooking_at, Slooking_at, 1, 2, 0,
doc: /* Return t if text after point matches regular expression REGEXP.
-This function modifies the match data that `match-beginning',
-`match-end' and `match-data' access; save and restore the match
-data if you want to preserve them. */)
- (Lisp_Object regexp)
+By default, this function modifies the match data that
+`match-beginning', `match-end' and `match-data' access. If
+INHIBIT-MODIFY is non-nil, don't modify the match data. */)
+ (Lisp_Object regexp, Lisp_Object inhibit_modify)
{
- return looking_at_1 (regexp, 0);
+ return looking_at_1 (regexp, 0, NILP (inhibit_modify));
}
-DEFUN ("posix-looking-at", Fposix_looking_at, Sposix_looking_at, 1, 1, 0,
+DEFUN ("posix-looking-at", Fposix_looking_at, Sposix_looking_at, 1, 2, 0,
doc: /* Return t if text after point matches REGEXP according to Posix rules.
Find the longest match, in accordance with Posix regular expression rules.
-This function modifies the match data that `match-beginning',
-`match-end' and `match-data' access; save and restore the match
-data if you want to preserve them. */)
- (Lisp_Object regexp)
+
+By default, this function modifies the match data that
+`match-beginning', `match-end' and `match-data' access. If
+INHIBIT-MODIFY is non-nil, don't modify the match data. */)
+ (Lisp_Object regexp, Lisp_Object inhibit_modify)
{
- return looking_at_1 (regexp, 1);
+ return looking_at_1 (regexp, 1, NILP (inhibit_modify));
}
static Lisp_Object
string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
- bool posix)
+ bool posix, bool modify_data)
{
ptrdiff_t val;
struct re_pattern_buffer *bufp;
EMACS_INT pos;
ptrdiff_t pos_byte, i;
+ bool modify_match_data = NILP (Vinhibit_changing_match_data) && modify_data;
if (running_asynch_code)
save_search_regs ();
@@ -400,8 +402,7 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
BVAR (current_buffer, case_eqv_table));
bufp = &compile_pattern (regexp,
- (NILP (Vinhibit_changing_match_data)
- ? &search_regs : NULL),
+ (modify_match_data ? &search_regs : NULL),
(!NILP (BVAR (current_buffer, case_fold_search))
? BVAR (current_buffer, case_canon_table) : Qnil),
posix,
@@ -410,18 +411,17 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
val = re_search (bufp, SSDATA (string),
SBYTES (string), pos_byte,
SBYTES (string) - pos_byte,
- (NILP (Vinhibit_changing_match_data)
- ? &search_regs : NULL));
+ (modify_match_data ? &search_regs : NULL));
/* Set last_thing_searched only when match data is changed. */
- if (NILP (Vinhibit_changing_match_data))
+ if (modify_match_data)
last_thing_searched = Qt;
if (val == -2)
matcher_overflow ();
if (val < 0) return Qnil;
- if (NILP (Vinhibit_changing_match_data))
+ if (modify_match_data)
for (i = 0; i < search_regs.num_regs; i++)
if (search_regs.start[i] >= 0)
{
@@ -434,32 +434,42 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
return make_fixnum (string_byte_to_char (string, val));
}
-DEFUN ("string-match", Fstring_match, Sstring_match, 2, 3, 0,
+DEFUN ("string-match", Fstring_match, Sstring_match, 2, 4, 0,
doc: /* Return index of start of first match for REGEXP in STRING, or nil.
Matching ignores case if `case-fold-search' is non-nil.
If third arg START is non-nil, start search at that index in STRING.
-For index of first char beyond the match, do (match-end 0).
-`match-end' and `match-beginning' also give indices of substrings
-matched by parenthesis constructs in the pattern.
-You can use the function `match-string' to extract the substrings
-matched by the parenthesis constructions in REGEXP. */)
- (Lisp_Object regexp, Lisp_Object string, Lisp_Object start)
+If INHIBIT-MODIFY is non-nil, match data is not changed.
+
+If INHIBIT-MODIFY is nil or missing, match data is changed, and
+`match-end' and `match-beginning' give indices of substrings matched
+by parenthesis constructs in the pattern. You can use the function
+`match-string' to extract the substrings matched by the parenthesis
+constructions in REGEXP. For index of first char beyond the match, do
+(match-end 0). */)
+ (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
+ Lisp_Object inhibit_modify)
{
- return string_match_1 (regexp, string, start, 0);
+ return string_match_1 (regexp, string, start, 0, NILP (inhibit_modify));
}
-DEFUN ("posix-string-match", Fposix_string_match, Sposix_string_match, 2, 3, 0,
+DEFUN ("posix-string-match", Fposix_string_match, Sposix_string_match, 2, 4, 0,
doc: /* Return index of start of first match for Posix REGEXP in STRING, or nil.
Find the longest match, in accord with Posix regular expression rules.
Case is ignored if `case-fold-search' is non-nil in the current buffer.
-If third arg START is non-nil, start search at that index in STRING.
-For index of first char beyond the match, do (match-end 0).
-`match-end' and `match-beginning' also give indices of substrings
-matched by parenthesis constructs in the pattern. */)
- (Lisp_Object regexp, Lisp_Object string, Lisp_Object start)
+
+If INHIBIT-MODIFY is non-nil, match data is not changed.
+
+If INHIBIT-MODIFY is nil or missing, match data is changed, and
+`match-end' and `match-beginning' give indices of substrings matched
+by parenthesis constructs in the pattern. You can use the function
+`match-string' to extract the substrings matched by the parenthesis
+constructions in REGEXP. For index of first char beyond the match, do
+(match-end 0). */)
+ (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
+ Lisp_Object inhibit_modify)
{
- return string_match_1 (regexp, string, start, 1);
+ return string_match_1 (regexp, string, start, 1, NILP (inhibit_modify));
}
/* Match REGEXP against STRING using translation table TABLE,
@@ -2387,6 +2397,13 @@ since only regular expressions have distinguished subexpressions. */)
if (! NILP (string))
CHECK_STRING (string);
+ /* Most replacement texts don't contain any backslash directives in
+ the replacements. Check whether that's the case, which will
+ enable us to take the fast path later. */
+ if (NILP (literal)
+ && !memchr (SSDATA (newtext), '\\', SBYTES (newtext)))
+ literal = Qt;
+
case_action = nochange; /* We tried an initialization */
/* but some C compilers blew it */
diff --git a/src/sound.c b/src/sound.c
index 9041076bdc0..d42bc8550d3 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -299,11 +299,15 @@ sound_perror (const char *msg)
int saved_errno = errno;
turn_on_atimers (1);
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
{
sigset_t unblocked;
sigemptyset (&unblocked);
+#ifdef USABLE_SIGIO
sigaddset (&unblocked, SIGIO);
+#else
+ sigaddset (&unblocked, SIGPOLL);
+#endif
pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
}
#endif
@@ -698,7 +702,7 @@ static void
vox_configure (struct sound_device *sd)
{
int val;
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
sigset_t oldset, blocked;
#endif
@@ -708,9 +712,13 @@ vox_configure (struct sound_device *sd)
interrupted by a signal. Block the ones we know to cause
troubles. */
turn_on_atimers (0);
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
sigemptyset (&blocked);
+#ifdef USABLE_SIGIO
sigaddset (&blocked, SIGIO);
+#else
+ sigaddset (&blocked, SIGPOLL);
+#endif
pthread_sigmask (SIG_BLOCK, &blocked, &oldset);
#endif
@@ -744,7 +752,7 @@ vox_configure (struct sound_device *sd)
}
turn_on_atimers (1);
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
pthread_sigmask (SIG_SETMASK, &oldset, 0);
#endif
}
@@ -760,10 +768,14 @@ vox_close (struct sound_device *sd)
/* On GNU/Linux, it seems that the device driver doesn't like to
be interrupted by a signal. Block the ones we know to cause
troubles. */
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
sigset_t blocked, oldset;
sigemptyset (&blocked);
+#ifdef USABLE_SIGIO
sigaddset (&blocked, SIGIO);
+#else
+ sigaddset (&blocked, SIGPOLL);
+#endif
pthread_sigmask (SIG_BLOCK, &blocked, &oldset);
#endif
turn_on_atimers (0);
@@ -772,7 +784,7 @@ vox_close (struct sound_device *sd)
ioctl (sd->fd, SNDCTL_DSP_SYNC, NULL);
turn_on_atimers (1);
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
pthread_sigmask (SIG_SETMASK, &oldset, 0);
#endif
diff --git a/src/sqlite.c b/src/sqlite.c
new file mode 100644
index 00000000000..428b84b21e7
--- /dev/null
+++ b/src/sqlite.c
@@ -0,0 +1,753 @@
+/*
+Copyright (C) 2021 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/>.
+
+This file is based on the emacs-sqlite3 package written by Syohei
+YOSHIDA <syohex@gmail.com>, which can be found at:
+
+ https://github.com/syohex/emacs-sqlite3
+*/
+
+#include <config.h>
+#include "lisp.h"
+#include "coding.h"
+
+#ifdef HAVE_SQLITE3
+
+#include <sqlite3.h>
+
+#ifdef WINDOWSNT
+
+# include <windows.h>
+# include "w32common.h"
+# include "w32.h"
+
+DEF_DLL_FN (SQLITE_API int, sqlite3_finalize, (sqlite3_stmt*));
+DEF_DLL_FN (SQLITE_API int, sqlite3_close, (sqlite3*));
+DEF_DLL_FN (SQLITE_API int, sqlite3_open_v2,
+ (const char*, sqlite3**, int, const char*));
+DEF_DLL_FN (SQLITE_API int, sqlite3_reset, (sqlite3_stmt*));
+DEF_DLL_FN (SQLITE_API int, sqlite3_bind_text,
+ (sqlite3_stmt*, int, const char*, int, void(*)(void*)));
+DEF_DLL_FN (SQLITE_API int, sqlite3_bind_int64,
+ (sqlite3_stmt*, int, sqlite3_int64));
+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 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*));
+DEF_DLL_FN (SQLITE_API int, sqlite3_column_type, (sqlite3_stmt*, int));
+DEF_DLL_FN (SQLITE_API sqlite3_int64, sqlite3_column_int64,
+ (sqlite3_stmt*, int));
+DEF_DLL_FN (SQLITE_API double, sqlite3_column_double, (sqlite3_stmt*, int));
+DEF_DLL_FN (SQLITE_API const void*, sqlite3_column_blob,
+ (sqlite3_stmt*, int));
+DEF_DLL_FN (SQLITE_API int, sqlite3_column_bytes, (sqlite3_stmt*, int));
+DEF_DLL_FN (SQLITE_API const unsigned char*, sqlite3_column_text,
+ (sqlite3_stmt*, int));
+DEF_DLL_FN (SQLITE_API const char*, sqlite3_column_name, (sqlite3_stmt*, int));
+DEF_DLL_FN (SQLITE_API int, sqlite3_exec,
+ (sqlite3*, const char*, int (*callback)(void*,int,char**,char**),
+ void*, char**));
+DEF_DLL_FN (SQLITE_API int, sqlite3_prepare_v2,
+ (sqlite3*, const char*, int, sqlite3_stmt**, const char**));
+
+# ifdef HAVE_SQLITE3_LOAD_EXTENSION
+DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension,
+ (sqlite3*, const char*, const char*, char**));
+# undef sqlite3_load_extension
+# define sqlite3_load_extension fn_sqlite3_load_extension
+# endif
+
+# undef sqlite3_finalize
+# undef sqlite3_close
+# undef sqlite3_open_v2
+# undef sqlite3_reset
+# undef sqlite3_bind_text
+# undef sqlite3_bind_int64
+# undef sqlite3_bind_double
+# undef sqlite3_bind_null
+# undef sqlite3_bind_int
+# undef sqlite3_errmsg
+# undef sqlite3_step
+# undef sqlite3_changes
+# undef sqlite3_column_count
+# undef sqlite3_column_type
+# undef sqlite3_column_int64
+# undef sqlite3_column_double
+# undef sqlite3_column_blob
+# undef sqlite3_column_bytes
+# undef sqlite3_column_text
+# undef sqlite3_column_name
+# undef sqlite3_exec
+# undef sqlite3_prepare_v2
+
+# define sqlite3_finalize fn_sqlite3_finalize
+# define sqlite3_close fn_sqlite3_close
+# define sqlite3_open_v2 fn_sqlite3_open_v2
+# define sqlite3_reset fn_sqlite3_reset
+# define sqlite3_bind_text fn_sqlite3_bind_text
+# define sqlite3_bind_int64 fn_sqlite3_bind_int64
+# define sqlite3_bind_double fn_sqlite3_bind_double
+# define sqlite3_bind_null fn_sqlite3_bind_null
+# define sqlite3_bind_int fn_sqlite3_bind_int
+# define sqlite3_errmsg fn_sqlite3_errmsg
+# define sqlite3_step fn_sqlite3_step
+# define sqlite3_changes fn_sqlite3_changes
+# define sqlite3_column_count fn_sqlite3_column_count
+# define sqlite3_column_type fn_sqlite3_column_type
+# define sqlite3_column_int64 fn_sqlite3_column_int64
+# define sqlite3_column_double fn_sqlite3_column_double
+# define sqlite3_column_blob fn_sqlite3_column_blob
+# define sqlite3_column_bytes fn_sqlite3_column_bytes
+# define sqlite3_column_text fn_sqlite3_column_text
+# define sqlite3_column_name fn_sqlite3_column_name
+# define sqlite3_exec fn_sqlite3_exec
+# define sqlite3_prepare_v2 fn_sqlite3_prepare_v2
+
+static bool
+load_dll_functions (HMODULE library)
+{
+ LOAD_DLL_FN (library, sqlite3_finalize);
+ LOAD_DLL_FN (library, sqlite3_close);
+ LOAD_DLL_FN (library, sqlite3_open_v2);
+ LOAD_DLL_FN (library, sqlite3_reset);
+ LOAD_DLL_FN (library, sqlite3_bind_text);
+ LOAD_DLL_FN (library, sqlite3_bind_int64);
+ LOAD_DLL_FN (library, sqlite3_bind_double);
+ 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_step);
+ LOAD_DLL_FN (library, sqlite3_changes);
+ LOAD_DLL_FN (library, sqlite3_column_count);
+ LOAD_DLL_FN (library, sqlite3_column_type);
+ LOAD_DLL_FN (library, sqlite3_column_int64);
+ LOAD_DLL_FN (library, sqlite3_column_double);
+ LOAD_DLL_FN (library, sqlite3_column_blob);
+ LOAD_DLL_FN (library, sqlite3_column_bytes);
+ LOAD_DLL_FN (library, sqlite3_column_text);
+ LOAD_DLL_FN (library, sqlite3_column_name);
+ LOAD_DLL_FN (library, sqlite3_exec);
+# ifdef HAVE_SQLITE3_LOAD_EXTENSION
+ LOAD_DLL_FN (library, sqlite3_load_extension);
+# endif
+ LOAD_DLL_FN (library, sqlite3_prepare_v2);
+ return true;
+}
+#endif /* WINDOWSNT */
+
+static bool
+init_sqlite_functions (void)
+{
+#ifdef WINDOWSNT
+ static bool sqlite3_initialized;
+
+ if (!sqlite3_initialized)
+ {
+ HMODULE library = w32_delayed_load (Qsqlite3);
+
+ if (!library)
+ message1 ("sqlite3 library was not found");
+ else if (load_dll_functions (library))
+ {
+ sqlite3_initialized = true;
+ Vlibrary_cache = Fcons (Fcons (Qsqlite3, Qt), Vlibrary_cache);
+ }
+ else
+ {
+ message1 ("sqlite3 library was found, but could not be loaded successfully");
+ Vlibrary_cache = Fcons (Fcons (Qsqlite3, Qnil), Vlibrary_cache);
+ }
+ }
+ return sqlite3_initialized;
+#else /* !WINDOWSNT */
+ return true;
+#endif /* !WINDOWSNT */
+}
+
+
+static void
+sqlite_free (void *arg)
+{
+ struct Lisp_Sqlite *ptr = (struct Lisp_Sqlite *)arg;
+ if (ptr->is_statement)
+ sqlite3_finalize (ptr->stmt);
+ else if (ptr->db)
+ sqlite3_close (ptr->db);
+ xfree (ptr->name);
+ xfree (ptr);
+}
+
+static Lisp_Object
+encode_string (Lisp_Object string)
+{
+ if (STRING_MULTIBYTE (string))
+ return encode_string_utf_8 (string, Qnil, 0, Qt, Qt);
+ else
+ return string;
+}
+
+static Lisp_Object
+make_sqlite (bool is_statement, void *db, void *stmt, char *name)
+{
+ struct Lisp_Sqlite *ptr
+ = ALLOCATE_PLAIN_PSEUDOVECTOR (struct Lisp_Sqlite, PVEC_SQLITE);
+ ptr->is_statement = is_statement;
+ ptr->finalizer = sqlite_free;
+ ptr->db = db;
+ ptr->name = name;
+ ptr->stmt = stmt;
+ ptr->eof = false;
+ return make_lisp_ptr (ptr, Lisp_Vectorlike);
+}
+
+static void
+check_sqlite (Lisp_Object db, bool is_statement)
+{
+ init_sqlite_functions ();
+ CHECK_SQLITE (db);
+ if (is_statement && !XSQLITE (db)->is_statement)
+ xsignal1 (Qerror, build_string ("Invalid set object"));
+ else if (!is_statement && XSQLITE (db)->is_statement)
+ xsignal1 (Qerror, build_string ("Invalid database object"));
+ if (!is_statement && !XSQLITE (db)->db)
+ xsignal1 (Qerror, build_string ("Database closed"));
+ else if (is_statement && !XSQLITE (db)->db)
+ xsignal1 (Qerror, build_string ("Statement closed"));
+}
+
+static int db_count = 0;
+
+DEFUN ("sqlite-open", Fsqlite_open, Ssqlite_open, 0, 1, 0,
+ doc: /* Open FILE as an sqlite database.
+If FILE is nil, an in-memory database will be opened instead. */)
+ (Lisp_Object file)
+{
+ char *name;
+ if (!init_sqlite_functions ())
+ xsignal1 (Qerror, build_string ("sqlite support is not available"));
+
+ if (!NILP (file))
+ {
+ CHECK_STRING (file);
+ file = ENCODE_FILE (Fexpand_file_name (file, Qnil));
+ name = xstrdup (SSDATA (file));
+ }
+ else
+ /* In-memory database. These have to have different names to
+ refer to different databases. */
+ name = xstrdup (SSDATA (CALLN (Fformat, build_string (":memory:%d"),
+ make_int (++db_count))));
+
+ sqlite3 *sdb;
+ int ret = sqlite3_open_v2 (name,
+ &sdb,
+ SQLITE_OPEN_FULLMUTEX
+ | SQLITE_OPEN_READWRITE
+ | SQLITE_OPEN_CREATE
+ | (NILP (file) ? SQLITE_OPEN_MEMORY : 0)
+#ifdef SQLITE_OPEN_URI
+ | SQLITE_OPEN_URI
+#endif
+ | 0, NULL);
+
+ if (ret != SQLITE_OK)
+ return Qnil;
+
+ return make_sqlite (false, sdb, NULL, name);
+}
+
+DEFUN ("sqlite-close", Fsqlite_close, Ssqlite_close, 1, 1, 0,
+ doc: /* Close the sqlite database DB. */)
+ (Lisp_Object db)
+{
+ check_sqlite (db, false);
+ sqlite3_close (XSQLITE (db)->db);
+ XSQLITE (db)->db = NULL;
+ return Qt;
+}
+
+/* Bind values in a statement like
+ "insert into foo values (?, ?, ?)". */
+static const char *
+bind_values (sqlite3 *db, sqlite3_stmt *stmt, Lisp_Object values)
+{
+ sqlite3_reset (stmt);
+ int len;
+ if (VECTORP (values))
+ len = ASIZE (values);
+ else
+ len = list_length (values);
+
+ for (int i = 0; i < len; ++i)
+ {
+ int ret = SQLITE_MISMATCH;
+ Lisp_Object value;
+ if (VECTORP (values))
+ value = AREF (values, i);
+ else
+ {
+ value = XCAR (values);
+ values = XCDR (values);
+ }
+ Lisp_Object type = Ftype_of (value);
+
+ if (EQ (type, Qstring))
+ {
+ Lisp_Object encoded = encode_string (value);
+ ret = sqlite3_bind_text (stmt, i + 1,
+ SSDATA (encoded), SBYTES (encoded),
+ NULL);
+ }
+ else if (EQ (type, Qinteger))
+ {
+ if (BIGNUMP (value))
+ ret = sqlite3_bind_int64 (stmt, i + 1, bignum_to_intmax (value));
+ else
+ ret = sqlite3_bind_int64 (stmt, i + 1, XFIXNUM (value));
+ }
+ else if (EQ (type, Qfloat))
+ ret = sqlite3_bind_double (stmt, i + 1, XFLOAT_DATA (value));
+ else if (NILP (value))
+ ret = sqlite3_bind_null (stmt, i + 1);
+ else if (EQ (value, Qt))
+ ret = sqlite3_bind_int (stmt, i + 1, 1);
+ else if (EQ (value, Qfalse))
+ ret = sqlite3_bind_int (stmt, i + 1, 0);
+ else
+ return "invalid argument";
+
+ if (ret != SQLITE_OK)
+ return sqlite3_errmsg (db);
+ }
+
+ 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)
+{
+ int len = sqlite3_column_count (stmt);
+ Lisp_Object values = Qnil;
+
+ for (int i = 0; i < len; ++i)
+ {
+ Lisp_Object v = Qnil;
+
+ switch (sqlite3_column_type (stmt, i))
+ {
+ case SQLITE_INTEGER:
+ v = make_int (sqlite3_column_int64 (stmt, i));
+ break;
+
+ case SQLITE_FLOAT:
+ v = make_float (sqlite3_column_double (stmt, i));
+ break;
+
+ case SQLITE_BLOB:
+ v =
+ code_convert_string_norecord
+ (make_unibyte_string (sqlite3_column_blob (stmt, i),
+ sqlite3_column_bytes (stmt, i)),
+ Qutf_8, false);
+ break;
+
+ case SQLITE_NULL:
+ v = Qnil;
+ break;
+
+ case SQLITE_TEXT:
+ v =
+ code_convert_string_norecord
+ (make_unibyte_string ((const char *)sqlite3_column_text (stmt, i),
+ sqlite3_column_bytes (stmt, i)),
+ Qutf_8, false);
+ break;
+ }
+
+ values = Fcons (v, values);
+ }
+
+ return Fnreverse (values);
+}
+
+static Lisp_Object
+column_names (sqlite3_stmt *stmt)
+{
+ Lisp_Object columns = Qnil;
+ int count = sqlite3_column_count (stmt);
+ for (int i = 0; i < count; ++i)
+ columns = Fcons (build_string (sqlite3_column_name (stmt, i)), columns);
+
+ return Fnreverse (columns);
+}
+
+DEFUN ("sqlite-select", Fsqlite_select, Ssqlite_select, 2, 4, 0,
+ doc: /* Select data from the database DB that matches QUERY.
+If VALUES is non-nil, it should be a list or a vector specifying the
+values that will be interpolated into a parameterized statement.
+
+By default, the return value is a list where the first element is a
+list of column names, and the rest of the elements are the matching data.
+
+RETURN-TYPE can be either nil (which means that the matching data
+should be returned as a list of rows), or `full' (the same, but the
+first element in the return list will be the column names), or `set',
+which means that we return a set object that can be queried with
+`sqlite-next' and other functions to get the data. */)
+ (Lisp_Object db, Lisp_Object query, Lisp_Object values,
+ Lisp_Object return_type)
+{
+ 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;
+ int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), SBYTES (encoded),
+ &stmt, NULL);
+ if (ret != SQLITE_OK)
+ {
+ if (stmt)
+ sqlite3_finalize (stmt);
+
+ goto exit;
+ }
+
+ /* Query with parameters. */
+ if (!NILP (values))
+ {
+ const char *err = bind_values (sdb, stmt, values);
+ if (err != NULL)
+ {
+ sqlite3_finalize (stmt);
+ errmsg = err;
+ goto exit;
+ }
+ }
+
+ /* Return a handle to get the data. */
+ if (EQ (return_type, Qset))
+ {
+ retval = make_sqlite (true, sdb, stmt, XSQLITE (db)->name);
+ goto exit;
+ }
+
+ /* Return the data directly. */
+ Lisp_Object data = Qnil;
+ while ((ret = sqlite3_step (stmt)) == SQLITE_ROW)
+ data = Fcons (row_to_value (stmt), data);
+
+ if (EQ (return_type, Qfull))
+ retval = Fcons (column_names (stmt), Fnreverse (data));
+ else
+ retval = Fnreverse (data);
+ sqlite3_finalize (stmt);
+
+ exit:
+ if (errmsg != NULL)
+ xsignal1 (Qerror, build_string (errmsg));
+
+ return retval;
+}
+
+static Lisp_Object
+sqlite_exec (sqlite3 *sdb, const char *query)
+{
+ int ret = sqlite3_exec (sdb, query, NULL, NULL, NULL);
+ if (ret != SQLITE_OK)
+ return Qnil;
+
+ return Qt;
+}
+
+DEFUN ("sqlite-transaction", Fsqlite_transaction, Ssqlite_transaction, 1, 1, 0,
+ doc: /* Start a transaction in DB. */)
+ (Lisp_Object db)
+{
+ check_sqlite (db, false);
+ return sqlite_exec (XSQLITE (db)->db, "begin");
+}
+
+DEFUN ("sqlite-commit", Fsqlite_commit, Ssqlite_commit, 1, 1, 0,
+ doc: /* Commit a transaction in DB. */)
+ (Lisp_Object db)
+{
+ check_sqlite (db, false);
+ return sqlite_exec (XSQLITE (db)->db, "commit");
+}
+
+DEFUN ("sqlite-rollback", Fsqlite_rollback, Ssqlite_rollback, 1, 1, 0,
+ doc: /* Roll back a transaction in DB. */)
+ (Lisp_Object db)
+{
+ check_sqlite (db, false);
+ return sqlite_exec (XSQLITE (db)->db, "rollback");
+}
+
+DEFUN ("sqlite-pragma", Fsqlite_pragma, Ssqlite_pragma, 2, 2, 0,
+ doc: /* Execute PRAGMA in DB. */)
+ (Lisp_Object db, Lisp_Object pragma)
+{
+ check_sqlite (db, false);
+ CHECK_STRING (pragma);
+
+ return sqlite_exec (XSQLITE (db)->db,
+ SSDATA (concat2 (build_string ("PRAGMA "), pragma)));
+}
+
+#ifdef HAVE_SQLITE3_LOAD_EXTENSION
+DEFUN ("sqlite-load-extension", Fsqlite_load_extension,
+ Ssqlite_load_extension, 2, 2, 0,
+ doc: /* Load an SQlite MODULE into DB.
+MODULE should be the name of an SQlite module's file, a
+shared library in the system-dependent format and having a
+system-dependent file-name extension.
+
+Only modules on Emacs' list of allowed modules can be loaded. */)
+ (Lisp_Object db, Lisp_Object module)
+{
+ check_sqlite (db, false);
+ CHECK_STRING (module);
+
+ /* Add names of useful and free modules here. */
+ const char *allowlist[3] = { "pcre", "csvtable", NULL };
+ char *name = SSDATA (Ffile_name_nondirectory (module));
+ /* Possibly skip past a common prefix. */
+ const char *prefix = "libsqlite3_mod_";
+ if (!strncmp (name, prefix, strlen (prefix)))
+ name += strlen (prefix);
+
+ bool do_allow = false;
+ for (const char **allow = allowlist; *allow; allow++)
+ {
+ if (strlen (*allow) < strlen (name)
+ && !strncmp (*allow, name, strlen (*allow))
+ && (!strcmp (name + strlen (*allow), ".so")
+ || !strcmp (name + strlen (*allow), ".DLL")))
+ {
+ do_allow = true;
+ break;
+ }
+ }
+
+ if (!do_allow)
+ xsignal (Qerror, build_string ("Module name not on allowlist"));
+
+ int result = sqlite3_load_extension
+ (XSQLITE (db)->db,
+ SSDATA (ENCODE_FILE (Fexpand_file_name (module, Qnil))),
+ NULL, NULL);
+ if (result == SQLITE_OK)
+ return Qt;
+ return Qnil;
+}
+#endif /* HAVE_SQLITE3_LOAD_EXTENSION */
+
+DEFUN ("sqlite-next", Fsqlite_next, Ssqlite_next, 1, 1, 0,
+ doc: /* Return the next result set from SET. */)
+ (Lisp_Object set)
+{
+ check_sqlite (set, true);
+
+ int ret = sqlite3_step (XSQLITE (set)->stmt);
+ if (ret != SQLITE_ROW && ret != SQLITE_OK && ret != SQLITE_DONE)
+ xsignal1 (Qerror, build_string (sqlite3_errmsg (XSQLITE (set)->db)));
+
+ if (ret == SQLITE_DONE)
+ {
+ XSQLITE (set)->eof = true;
+ return Qnil;
+ }
+
+ return row_to_value (XSQLITE (set)->stmt);
+}
+
+DEFUN ("sqlite-columns", Fsqlite_columns, Ssqlite_columns, 1, 1, 0,
+ doc: /* Return the column names of SET. */)
+ (Lisp_Object set)
+{
+ check_sqlite (set, true);
+ return column_names (XSQLITE (set)->stmt);
+}
+
+DEFUN ("sqlite-more-p", Fsqlite_more_p, Ssqlite_more_p, 1, 1, 0,
+ doc: /* Say whether there are any further results in SET. */)
+ (Lisp_Object set)
+{
+ check_sqlite (set, true);
+
+ if (XSQLITE (set)->eof)
+ return Qnil;
+ else
+ return Qt;
+}
+
+DEFUN ("sqlite-finalize", Fsqlite_finalize, Ssqlite_finalize, 1, 1, 0,
+ doc: /* Mark this SET as being finished.
+This will free the resources held by SET. */)
+ (Lisp_Object set)
+{
+ check_sqlite (set, true);
+ sqlite3_finalize (XSQLITE (set)->stmt);
+ XSQLITE (set)->db = NULL;
+ return Qt;
+}
+
+#endif /* HAVE_SQLITE3 */
+
+DEFUN ("sqlitep", Fsqlitep, Ssqlitep, 1, 1, 0,
+ doc: /* Say whether OBJECT is an SQlite object. */)
+ (Lisp_Object object)
+{
+#ifdef HAVE_SQLITE3
+ return SQLITE (object)? Qt: Qnil;
+#else
+ return Qnil;
+#endif
+}
+
+DEFUN ("sqlite-available-p", Fsqlite_available_p, Ssqlite_available_p, 0, 0, 0,
+ doc: /* Return t if sqlite3 support is available in this instance of Emacs.*/)
+ (void)
+{
+#ifdef HAVE_SQLITE3
+# ifdef WINDOWSNT
+ Lisp_Object found = Fassq (Qsqlite3, Vlibrary_cache);
+ if (CONSP (found))
+ return XCDR (found);
+ else
+ return init_sqlite_functions () ? Qt : Qnil;
+# else
+ return Qt;
+#endif
+#else
+ return Qnil;
+#endif
+}
+
+void
+syms_of_sqlite (void)
+{
+#ifdef HAVE_SQLITE3
+ defsubr (&Ssqlite_open);
+ defsubr (&Ssqlite_close);
+ defsubr (&Ssqlite_execute);
+ defsubr (&Ssqlite_select);
+ defsubr (&Ssqlite_transaction);
+ defsubr (&Ssqlite_commit);
+ defsubr (&Ssqlite_rollback);
+ defsubr (&Ssqlite_pragma);
+#ifdef HAVE_SQLITE3_LOAD_EXTENSION
+ defsubr (&Ssqlite_load_extension);
+#endif
+ defsubr (&Ssqlite_next);
+ defsubr (&Ssqlite_columns);
+ defsubr (&Ssqlite_more_p);
+ defsubr (&Ssqlite_finalize);
+ DEFSYM (Qset, "set");
+ DEFSYM (Qfull, "full");
+#endif
+ defsubr (&Ssqlitep);
+ defsubr (&Ssqlite_available_p);
+
+ DEFSYM (Qsqlite_locked_error, "sqlite-locked-error");
+ Fput (Qsqlite_locked_error, Qerror_conditions,
+ Fpurecopy (list2 (Qsqlite_locked_error, Qerror)));
+ Fput (Qsqlite_locked_error, Qerror_message,
+ build_pure_c_string ("Database locked"));
+
+ DEFSYM (Qsqlitep, "sqlitep");
+ DEFSYM (Qfalse, "false");
+ DEFSYM (Qsqlite, "sqlite");
+ DEFSYM (Qsqlite3, "sqlite3");
+}
diff --git a/src/syntax.c b/src/syntax.c
index 7bba336744a..057a4c3b1f5 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -17,7 +17,6 @@ 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/>. */
-
#include <config.h>
#include "lisp.h"
@@ -3547,8 +3546,10 @@ DEFUN ("parse-partial-sexp", Fparse_partial_sexp, Sparse_partial_sexp, 2, 6, 0,
doc: /* Parse Lisp syntax starting at FROM until TO; return status of parse at TO.
Parsing stops at TO or when certain criteria are met;
point is set to where parsing stops.
-If fifth arg OLDSTATE is omitted or nil,
- parsing assumes that FROM is the beginning of a function.
+
+If OLDSTATE is omitted or nil, parsing assumes that FROM is the
+ beginning of a function. If not, OLDSTATE should be the state at
+ FROM.
Value is a list of elements describing final state of parsing:
0. depth in parens.
@@ -3594,6 +3595,9 @@ Sixth arg COMMENTSTOP non-nil means stop after the start of a comment.
else
target = TYPE_MINIMUM (EMACS_INT); /* We won't reach this depth. */
+ if (fix_position (to) < fix_position (from))
+ error ("End position is smaller than start position");
+
validate_region (&from, &to);
internalize_parse_state (oldstate, &state);
scan_sexps_forward (&state, XFIXNUM (from), CHAR_TO_BYTE (XFIXNUM (from)),
diff --git a/src/sysdep.c b/src/sysdep.c
index 8eaee224987..5e13dd097ec 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -678,6 +678,9 @@ sys_subshell (void)
#ifdef USABLE_SIGIO
saved_handlers[3].code = SIGIO;
saved_handlers[4].code = 0;
+#elif defined (USABLE_SIGPOLL)
+ saved_handlers[3].code = SIGPOLL;
+ saved_handlers[4].code = 0;
#else
saved_handlers[3].code = 0;
#endif
@@ -788,6 +791,7 @@ init_sigio (int fd)
}
#ifndef DOS_NT
+#ifdef F_SETOWN
static void
reset_sigio (int fd)
{
@@ -795,12 +799,13 @@ reset_sigio (int fd)
fcntl (fd, F_SETFL, old_fcntl_flags[fd]);
#endif
}
+#endif /* F_SETOWN */
#endif
void
request_sigio (void)
{
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
sigset_t unblocked;
if (noninteractive)
@@ -810,7 +815,11 @@ request_sigio (void)
# ifdef SIGWINCH
sigaddset (&unblocked, SIGWINCH);
# endif
+# ifdef USABLE_SIGIO
sigaddset (&unblocked, SIGIO);
+# else
+ sigaddset (&unblocked, SIGPOLL);
+# endif
pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
interrupts_deferred = 0;
@@ -820,7 +829,7 @@ request_sigio (void)
void
unrequest_sigio (void)
{
-#ifdef USABLE_SIGIO
+#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
sigset_t blocked;
if (noninteractive)
@@ -830,7 +839,11 @@ unrequest_sigio (void)
# ifdef SIGWINCH
sigaddset (&blocked, SIGWINCH);
# endif
+# ifdef USABLE_SIGIO
sigaddset (&blocked, SIGIO);
+# else
+ sigaddset (&blocked, SIGPOLL);
+# endif
pthread_sigmask (SIG_BLOCK, &blocked, 0);
interrupts_deferred = 1;
#endif
@@ -1256,9 +1269,12 @@ init_sys_modes (struct tty_display_info *tty_out)
/* This code added to insure that, if flow-control is not to be used,
we have an unlocked terminal at the start. */
+#ifndef HAIKU /* On Haiku, TCXONC is a no-op and causes spurious
+ compiler warnings. */
#ifdef TCXONC
if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TCXONC, 1);
#endif
+#endif /* HAIKU */
#ifdef TIOCSTART
if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TIOCSTART, 0);
#endif
@@ -1674,6 +1690,8 @@ emacs_sigaction_init (struct sigaction *action, signal_handler_t handler)
sigaddset (&action->sa_mask, SIGQUIT);
#ifdef USABLE_SIGIO
sigaddset (&action->sa_mask, SIGIO);
+#elif defined (USABLE_SIGPOLL)
+ sigaddset (&action->sa_mask, SIGPOLL);
#endif
}
@@ -2772,6 +2790,7 @@ static const struct speed_struct speeds[] =
#ifdef B150
{ 150, B150 },
#endif
+#ifndef HAVE_TINY_SPEED_T
#ifdef B200
{ 200, B200 },
#endif
@@ -2859,6 +2878,7 @@ static const struct speed_struct speeds[] =
#ifdef B4000000
{ 4000000, B4000000 },
#endif
+#endif /* HAVE_TINY_SPEED_T */
};
/* Convert a numerical speed (e.g., 9600) to a Bnnn constant (e.g.,
@@ -3120,8 +3140,9 @@ list_system_processes (void)
}
/* The WINDOWSNT implementation is in w32.c.
- The MSDOS implementation is in dosfns.c. */
-#elif !defined (WINDOWSNT) && !defined (MSDOS)
+ The MSDOS implementation is in dosfns.c.
+ The Haiku implementation is in haiku.c. */
+#elif !defined (WINDOWSNT) && !defined (MSDOS) && !defined (HAIKU)
Lisp_Object
list_system_processes (void)
@@ -4200,8 +4221,9 @@ system_process_attributes (Lisp_Object pid)
}
/* The WINDOWSNT implementation is in w32.c.
- The MSDOS implementation is in dosfns.c. */
-#elif !defined (WINDOWSNT) && !defined (MSDOS)
+ The MSDOS implementation is in dosfns.c.
+ The HAIKU implementation is in haiku.c. */
+#elif !defined (WINDOWSNT) && !defined (MSDOS) && !defined (HAIKU)
Lisp_Object
system_process_attributes (Lisp_Object pid)
diff --git a/src/sysstdio.h b/src/sysstdio.h
index d4df3d74567..d6ebfb455f5 100644
--- a/src/sysstdio.h
+++ b/src/sysstdio.h
@@ -26,7 +26,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <stdio.h>
#include "unlocked-io.h"
-extern FILE *emacs_fopen (char const *, char const *);
+extern FILE *emacs_fopen (char const *, char const *) ATTRIBUTE_MALLOC;
extern void errputc (int);
extern void errwrite (void const *, ptrdiff_t);
extern void close_output_streams (void);
diff --git a/src/systhread.h b/src/systhread.h
index 0f47d7c1a8a..601505f4f86 100644
--- a/src/systhread.h
+++ b/src/systhread.h
@@ -101,14 +101,11 @@ extern void sys_cond_signal (sys_cond_t *);
extern void sys_cond_broadcast (sys_cond_t *);
extern void sys_cond_destroy (sys_cond_t *);
-extern sys_thread_t sys_thread_self (void)
- NODISCARD;
-extern bool sys_thread_equal (sys_thread_t, sys_thread_t)
- NODISCARD;
-
-extern bool sys_thread_create (sys_thread_t *, thread_creation_function *,
- void *)
- NODISCARD;
+NODISCARD extern sys_thread_t sys_thread_self (void);
+NODISCARD extern bool sys_thread_equal (sys_thread_t, sys_thread_t);
+
+NODISCARD extern bool sys_thread_create (sys_thread_t *,
+ thread_creation_function *, void *);
extern void sys_thread_yield (void);
extern void sys_thread_set_name (const char *);
diff --git a/src/systime.h b/src/systime.h
index 08ab5bdde33..ce9403c931d 100644
--- a/src/systime.h
+++ b/src/systime.h
@@ -80,8 +80,7 @@ struct lisp_time
/* Clock count as a Lisp integer. */
Lisp_Object ticks;
- /* Clock frequency (ticks per second) as a positive Lisp integer.
- (TICKS . HZ) is a valid Lisp timestamp unless HZ < 65536. */
+ /* Clock frequency (ticks per second) as a positive Lisp integer. */
Lisp_Object hz;
};
diff --git a/src/term.c b/src/term.c
index 6651b967927..8e106e7c639 100644
--- a/src/term.c
+++ b/src/term.c
@@ -549,13 +549,14 @@ encode_terminal_code (struct glyph *src, int src_len,
{
if (src->type == COMPOSITE_GLYPH)
{
- struct composition *cmp UNINIT;
+ struct composition *cmp;
Lisp_Object gstring UNINIT;
int i;
nbytes = buf - encode_terminal_src;
if (src->u.cmp.automatic)
{
+ cmp = NULL;
gstring = composition_gstring_from_id (src->u.cmp.id);
required = src->slice.cmp.to - src->slice.cmp.from + 1;
}
@@ -575,7 +576,7 @@ encode_terminal_code (struct glyph *src, int src_len,
buf = encode_terminal_src + nbytes;
}
- if (src->u.cmp.automatic)
+ if (!cmp)
for (i = src->slice.cmp.from; i <= src->slice.cmp.to; i++)
{
Lisp_Object g = LGSTRING_GLYPH (gstring, i);
@@ -1357,7 +1358,7 @@ term_get_fkeys_1 (void)
char *sequence = tgetstr (keys[i].cap, address);
if (sequence)
Fdefine_key (KVAR (kboard, Vinput_decode_map), build_string (sequence),
- make_vector (1, intern (keys[i].name)));
+ make_vector (1, intern (keys[i].name)), Qnil);
}
/* The uses of the "k0" capability are inconsistent; sometimes it
@@ -1376,13 +1377,13 @@ term_get_fkeys_1 (void)
/* Define f0 first, so that f10 takes precedence in case the
key sequences happens to be the same. */
Fdefine_key (KVAR (kboard, Vinput_decode_map), build_string (k0),
- make_vector (1, intern ("f0")));
+ make_vector (1, intern ("f0")), Qnil);
Fdefine_key (KVAR (kboard, Vinput_decode_map), build_string (k_semi),
- make_vector (1, intern ("f10")));
+ make_vector (1, intern ("f10")), Qnil);
}
else if (k0)
Fdefine_key (KVAR (kboard, Vinput_decode_map), build_string (k0),
- make_vector (1, intern (k0_name)));
+ make_vector (1, intern (k0_name)), Qnil);
}
/* Set up cookies for numbered function keys above f10. */
@@ -1404,8 +1405,10 @@ term_get_fkeys_1 (void)
if (sequence)
{
sprintf (fkey, "f%d", i);
- Fdefine_key (KVAR (kboard, Vinput_decode_map), build_string (sequence),
- make_vector (1, intern (fkey)));
+ Fdefine_key (KVAR (kboard, Vinput_decode_map),
+ build_string (sequence),
+ make_vector (1, intern (fkey)),
+ Qnil);
}
}
}
@@ -1421,7 +1424,7 @@ term_get_fkeys_1 (void)
char *sequence = tgetstr (cap2, address); \
if (sequence) \
Fdefine_key (KVAR (kboard, Vinput_decode_map), build_string (sequence), \
- make_vector (1, intern (sym))); \
+ make_vector (1, intern (sym)), Qnil); \
}
/* if there's no key_next keycap, map key_npage to `next' keysym */
@@ -2575,21 +2578,8 @@ handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event)
{
f->mouse_moved = 0;
term_mouse_click (&ie, event, f);
- /* eassert (ie.kind == MOUSE_CLICK_EVENT); */
- if (tty_handle_tab_bar_click (f, event->x, event->y,
- (ie.modifiers & down_modifier) != 0, &ie))
- {
- /* eassert (ie.kind == MOUSE_CLICK_EVENT
- * || ie.kind == TAB_BAR_EVENT); */
- /* tty_handle_tab_bar_click stores 2 events in the event
- queue, so we are done here. */
- /* FIXME: Actually, `tty_handle_tab_bar_click` returns true
- without storing any events, when
- (ie.modifiers & down_modifier) != 0 */
- count += 2;
- return count;
- }
- /* eassert (ie.kind == MOUSE_CLICK_EVENT); */
+ ie.arg = tty_handle_tab_bar_click (f, event->x, event->y,
+ (ie.modifiers & down_modifier) != 0, &ie);
kbd_buffer_store_event (&ie);
count++;
}
@@ -4164,10 +4154,12 @@ use the Bourne shell command 'TERM=...; export TERM' (C-shell:\n\
could return 32767. */
tty->TN_max_colors = 16777216;
}
- /* Fall back to xterm+direct (semicolon version) if requested
- by the COLORTERM environment variable. */
- else if ((bg = getenv("COLORTERM")) != NULL
- && strcasecmp(bg, "truecolor") == 0)
+ /* Fall back to xterm+direct (semicolon version) if Tc is set
+ (de-facto standard introduced by tmux) or if requested by
+ the COLORTERM environment variable. */
+ else if ((tigetflag ("Tc") > 0)
+ || ((bg = getenv ("COLORTERM")) != NULL
+ && strcasecmp (bg, "truecolor") == 0))
{
tty->TS_set_foreground = "\033[%?%p1%{8}%<%t3%p1%d%e38;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%d;%p1%{255}%&%d%;m";
tty->TS_set_background = "\033[%?%p1%{8}%<%t4%p1%d%e48;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%d;%p1%{255}%&%d%;m";
diff --git a/src/termchar.h b/src/termchar.h
index f50c1bfb6ea..7ab9337fbe7 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -234,7 +234,7 @@ extern struct tty_display_info *tty_list;
#define CURTTY() FRAME_TTY (SELECTED_FRAME())
struct input_event;
-extern bool tty_handle_tab_bar_click (struct frame *, int, int, bool,
- struct input_event *);
+extern Lisp_Object tty_handle_tab_bar_click (struct frame *, int, int, bool,
+ struct input_event *);
#endif /* EMACS_TERMCHAR_H */
diff --git a/src/termhooks.h b/src/termhooks.h
index 1d3cdc8fe8d..9f22187b841 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -60,7 +60,9 @@ enum output_method
output_x_window,
output_msdos_raw,
output_w32,
- output_ns
+ output_ns,
+ output_pgtk,
+ output_haiku
};
/* Input queue declarations and hooks. */
@@ -119,7 +121,10 @@ enum event_kind
.timestamp gives a timestamp (in
milliseconds) for the event.
.arg may contain the number of
- lines to scroll. */
+ lines to scroll, or a list of
+ the form (NUMBER-OF-LINES . (X Y)) where
+ X and Y are the number of pixels
+ on each axis to scroll by. */
HORIZ_WHEEL_EVENT, /* A wheel event generated by a second
horizontal wheel that is present on some
mice. See WHEEL_EVENT. */
@@ -255,6 +260,8 @@ enum event_kind
#ifdef HAVE_XWIDGETS
/* events generated by xwidgets*/
, XWIDGET_EVENT
+ /* Event generated when WebKit asks us to display another widget. */
+ , XWIDGET_DISPLAY_EVENT
#endif
#ifdef USE_FILE_NOTIFY
@@ -262,6 +269,30 @@ enum event_kind
, FILE_NOTIFY_EVENT
#endif
+#ifdef HAVE_PGTK
+ /* Pre-edit text was changed. */
+ , PGTK_PREEDIT_TEXT_EVENT
+#endif
+
+ /* Either the mouse wheel has been released without it being
+ clicked, or the user has lifted his finger from a touchpad.
+
+ In the future, this may take into account other multi-touch
+ events generated from touchscreens and such. */
+ , TOUCH_END_EVENT
+
+ /* In a TOUCHSCREEN_UPDATE_EVENT, ARG is a list of elements of the
+ form (X Y ID), where X and Y are the coordinates of the
+ touchpoint relative to the top-left corner of the frame, and ID
+ is a unique number identifying the touchpoint.
+
+ In TOUCHSCREEN_BEGIN_EVENT and TOUCHSCREEN_END_EVENT, ARG is the
+ unique ID of the touchpoint, and X and Y are the frame-relative
+ positions of the touchpoint. */
+
+ , TOUCHSCREEN_UPDATE_EVENT
+ , TOUCHSCREEN_BEGIN_EVENT
+ , TOUCHSCREEN_END_EVENT
};
/* Bit width of an enum event_kind tag at the start of structs and unions. */
@@ -442,6 +473,8 @@ struct terminal
struct x_display_info *x; /* xterm.h */
struct w32_display_info *w32; /* w32term.h */
struct ns_display_info *ns; /* nsterm.h */
+ struct pgtk_display_info *pgtk; /* pgtkterm.h */
+ struct haiku_display_info *haiku; /* haikuterm.h */
} display_info;
@@ -515,7 +548,7 @@ struct terminal
BGCOLOR. */
void (*query_frame_background_color) (struct frame *f, Emacs_Color *bgcolor);
-#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
+#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) || defined (HAVE_PGTK)
/* On frame F, translate pixel colors to RGB values for the NCOLORS
colors in COLORS. Use cached information, if available. */
@@ -830,6 +863,12 @@ extern struct terminal *terminal_list;
#elif defined (HAVE_NS)
#define TERMINAL_FONT_CACHE(t) \
(t->type == output_ns ? t->display_info.ns->name_list_element : Qnil)
+#elif defined (HAVE_PGTK)
+#define TERMINAL_FONT_CACHE(t) \
+ (t->type == output_pgtk ? t->display_info.pgtk->name_list_element : Qnil)
+#elif defined (HAVE_HAIKU)
+#define TERMINAL_FONT_CACHE(t) \
+ (t->type == output_haiku ? t->display_info.haiku->name_list_element : Qnil)
#endif
extern struct terminal *decode_live_terminal (Lisp_Object);
diff --git a/src/terminal.c b/src/terminal.c
index b83adc596bb..a9ecb63d85d 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -445,6 +445,10 @@ possible return values. */)
return Qpc;
case output_ns:
return Qns;
+ case output_pgtk:
+ return Qpgtk;
+ case output_haiku:
+ return Qhaiku;
default:
emacs_abort ();
}
diff --git a/src/thread.h b/src/thread.h
index cf3ce922c46..b316e916d1d 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -26,6 +26,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#endif
#ifdef MSDOS
+#include <time.h> /* struct rpl_timespec */
#include <signal.h> /* sigset_t */
#endif
diff --git a/src/timefns.c b/src/timefns.c
index f0e2e97f555..74b5ca8d515 100644
--- a/src/timefns.c
+++ b/src/timefns.c
@@ -19,6 +19,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <config.h>
+/* Work around GCC bug 102671. */
+#if 10 <= __GNUC__
+# pragma GCC diagnostic ignored "-Wanalyzer-null-dereference"
+#endif
+
#include "systime.h"
#include "blockinput.h"
@@ -64,16 +69,6 @@ enum { TM_YEAR_BASE = 1900 };
# define FASTER_TIMEFNS 1
#endif
-/* Whether to warn about Lisp timestamps (TICKS . HZ) that may be
- instances of obsolete-format timestamps (HI . LO) where HI is
- the high-order bits and LO the low-order 16 bits. Currently this
- is true, but it should change to false in a future version of
- Emacs. Compile with -DWARN_OBSOLETE_TIMESTAMPS=0 to see what the
- future will be like. */
-#ifndef WARN_OBSOLETE_TIMESTAMPS
-enum { WARN_OBSOLETE_TIMESTAMPS = true };
-#endif
-
/* Although current-time etc. generate list-format timestamps
(HI LO US PS), the plan is to change these functions to generate
frequency-based timestamps (TICKS . HZ) in a future release.
@@ -812,14 +807,10 @@ decode_time_components (enum timeform form,
return decode_ticks_hz (make_integer_mpz (), hz, result, dresult);
}
-enum { DECODE_SECS_ONLY = WARN_OBSOLETE_TIMESTAMPS + 1 };
-
/* Decode a Lisp timestamp SPECIFIED_TIME that represents a time.
- FLAGS specifies conversion flags. If FLAGS & DECODE_SECS_ONLY,
- ignore and do not validate any sub-second components of an
- old-format SPECIFIED_TIME. If FLAGS & WARN_OBSOLETE_TIMESTAMPS,
- diagnose what could be obsolete (HIGH . LOW) timestamps.
+ If DECODE_SECS_ONLY, ignore and do not validate any sub-second
+ components of an old-format SPECIFIED_TIME.
If RESULT is not null, store into *RESULT the converted time;
otherwise, store into *DRESULT the number of seconds since the
@@ -828,7 +819,7 @@ enum { DECODE_SECS_ONLY = WARN_OBSOLETE_TIMESTAMPS + 1 };
Return the form of SPECIFIED-TIME. Signal an error if unsuccessful. */
static enum timeform
-decode_lisp_time (Lisp_Object specified_time, int flags,
+decode_lisp_time (Lisp_Object specified_time, bool decode_secs_only,
struct lisp_time *result, double *dresult)
{
Lisp_Object high = make_fixnum (0);
@@ -849,7 +840,7 @@ decode_lisp_time (Lisp_Object specified_time, int flags,
{
Lisp_Object low_tail = XCDR (low);
low = XCAR (low);
- if (! (flags & DECODE_SECS_ONLY))
+ if (! decode_secs_only)
{
if (CONSP (low_tail))
{
@@ -872,9 +863,6 @@ decode_lisp_time (Lisp_Object specified_time, int flags,
}
else
{
- if (flags & WARN_OBSOLETE_TIMESTAMPS
- && RANGED_FIXNUMP (0, low, (1 << LO_TIME_BITS) - 1))
- message ("obsolete timestamp with cdr %"pI"d", XFIXNUM (low));
form = TIMEFORM_TICKS_HZ;
}
@@ -1003,8 +991,7 @@ static struct lisp_time
lisp_time_struct (Lisp_Object specified_time, enum timeform *pform)
{
struct lisp_time t;
- enum timeform form
- = decode_lisp_time (specified_time, WARN_OBSOLETE_TIMESTAMPS, &t, 0);
+ enum timeform form = decode_lisp_time (specified_time, false, &t, 0);
if (pform)
*pform = form;
return t;
@@ -1029,9 +1016,8 @@ lisp_time_argument (Lisp_Object specified_time)
static time_t
lisp_seconds_argument (Lisp_Object specified_time)
{
- int flags = WARN_OBSOLETE_TIMESTAMPS | DECODE_SECS_ONLY;
struct lisp_time lt;
- decode_lisp_time (specified_time, flags, &lt, 0);
+ decode_lisp_time (specified_time, true, &lt, 0);
struct timespec t = lisp_to_timespec (lt);
if (! timespec_valid_p (t))
time_overflow ();
@@ -1133,24 +1119,6 @@ time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
mpz_t *ihz = &mpz[0];
mpz_mul (*ihz, *fa, *db);
- /* When warning about obsolete timestamps, if the smaller
- denominator comes from a non-(TICKS . HZ) timestamp and could
- generate a (TICKS . HZ) timestamp that would look obsolete,
- arrange for the result to have a higher HZ to avoid a
- spurious warning by a later consumer of this function's
- returned value. */
- verify (1 << LO_TIME_BITS <= ULONG_MAX);
- if (WARN_OBSOLETE_TIMESTAMPS
- && (da_lt_db ? aform : bform) == TIMEFORM_FLOAT
- && (da_lt_db ? bform : aform) != TIMEFORM_TICKS_HZ
- && mpz_cmp_ui (*hzmin, 1) > 0
- && mpz_cmp_ui (*hzmin, 1 << LO_TIME_BITS) < 0)
- {
- mpz_t *hzmin1 = &mpz[2 - da_lt_db];
- mpz_set_ui (*hzmin1, 1 << LO_TIME_BITS);
- hzmin = hzmin1;
- }
-
/* iticks = (fb * na) OP (fa * nb), where OP is + or -. */
mpz_t const *na = bignum_integer (iticks, ta.ticks);
mpz_mul (*iticks, *fb, *na);
@@ -1172,8 +1140,7 @@ time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
upwards by multiplying the normalized numerator and denominator
so that the resulting denominator becomes at least hzmin.
This rescaling avoids returning a timestamp that is less precise
- than both a and b, or a timestamp that looks obsolete when that
- might be a problem. */
+ than both a and b. */
if (!FASTER_TIMEFNS || mpz_cmp (*ihz, *hzmin) < 0)
{
/* Rescale straightforwardly. Although this might not
@@ -1298,7 +1265,7 @@ or (if you need time as a string) `format-time-string'. */)
(Lisp_Object specified_time)
{
double t;
- decode_lisp_time (specified_time, 0, 0, &t);
+ decode_lisp_time (specified_time, false, 0, &t);
return make_float (t);
}
@@ -1646,12 +1613,11 @@ saving flag to be guessed.
As an obsolescent calling convention, if this function is called with
6 or more arguments, the first 6 arguments are SECOND, MINUTE, HOUR,
-DAY, MONTH, and YEAR, and specify the components of a decoded time,
-where DST assumed to be -1 and FORM is omitted. If there are more
-than 6 arguments the *last* argument is used as ZONE and any other
-extra arguments are ignored, so that (apply #\\='encode-time
-(decode-time ...)) works. In this obsolescent convention, DST and
-ZONE default to -1 and nil respectively.
+DAY, MONTH, and YEAR, and specify the components of a decoded time.
+If there are more than 6 arguments the *last* argument is used as ZONE
+and any other extra arguments are ignored, so that (apply
+#\\='encode-time (decode-time ...)) works. In this obsolescent
+convention, DST and ZONE default to -1 and nil respectively.
Years before 1970 are not guaranteed to work. On some systems,
year values as low as 1901 do work.
@@ -1698,7 +1664,7 @@ usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS) */)
/* Let SEC = floor (LT.ticks / HZ), with SUBSECTICKS the remainder. */
struct lisp_time lt;
- decode_lisp_time (secarg, 0, &lt, 0);
+ decode_lisp_time (secarg, false, &lt, 0);
Lisp_Object hz = lt.hz, sec, subsecticks;
if (FASTER_TIMEFNS && EQ (hz, make_fixnum (1)))
{
@@ -1751,9 +1717,7 @@ Truncate the returned value toward minus infinity.
If FORM is nil (the default), return the same form as `current-time'.
If FORM is a positive integer, return a pair of integers (TICKS . FORM),
where TICKS is the number of clock ticks and FORM is the clock frequency
-in ticks per second. (Currently the positive integer should be at least
-65536 if the returned value is expected to be given to standard functions
-expecting Lisp timestamps.) If FORM is t, return (TICKS . PHZ), where
+in ticks per second. If FORM is t, return (TICKS . PHZ), where
PHZ is a suitable clock frequency in ticks per second. If FORM is
`integer', return an integer count of seconds. If FORM is `list',
return an integer list (HIGH LOW USEC PSEC), where HIGH has the most
@@ -1762,7 +1726,7 @@ bits, and USEC and PSEC are the microsecond and picosecond counts. */)
(Lisp_Object time, Lisp_Object form)
{
struct lisp_time t;
- enum timeform input_form = decode_lisp_time (time, 0, &t, 0);
+ enum timeform input_form = decode_lisp_time (time, false, &t, 0);
if (NILP (form))
form = CURRENT_TIME_LIST ? Qlist : Qt;
if (EQ (form, Qlist))
diff --git a/src/unexcw.c b/src/unexcw.c
index 7a80b05963b..157e9f45607 100644
--- a/src/unexcw.c
+++ b/src/unexcw.c
@@ -48,7 +48,7 @@ static exe_header_t *
read_exe_header (int fd, exe_header_t * exe_header_buffer)
{
int i;
- int ret ATTRIBUTE_UNUSED;
+ MAYBE_UNUSED int ret;
assert (fd >= 0);
assert (exe_header_buffer != 0);
@@ -111,7 +111,7 @@ fixup_executable (int fd)
exe_header_t exe_header_buffer;
exe_header_t *exe_header;
int i;
- int ret ATTRIBUTE_UNUSED;
+ MAYBE_UNUSED int ret;
int found_data = 0;
int found_bss = 0;
@@ -269,7 +269,7 @@ unexec (const char *outfile, const char *infile)
int fd_in;
int fd_out;
int ret;
- int ret2 ATTRIBUTE_UNUSED;
+ MAYBE_UNUSED int ret2;
infile = add_exe_suffix_if_necessary (infile, infile_buffer);
outfile = add_exe_suffix_if_necessary (outfile, outfile_buffer);
diff --git a/src/verbose.mk.in b/src/verbose.mk.in
index 50d6ea32000..9252971acc3 100644
--- a/src/verbose.mk.in
+++ b/src/verbose.mk.in
@@ -23,8 +23,11 @@ ifeq (${V},1)
AM_V_AR =
AM_V_at =
AM_V_CC =
+AM_V_CXX =
AM_V_CCLD =
+AM_V_CXXLD =
AM_V_ELC =
+AM_V_ELN =
AM_V_GEN =
AM_V_GLOBALS =
AM_V_NO_PD =
@@ -33,15 +36,20 @@ else
AM_V_AR = @echo " AR " $@;
AM_V_at = @
AM_V_CC = @echo " CC " $@;
+AM_V_CXX = @echo " CXX " $@;
AM_V_CCLD = @echo " CCLD " $@;
+AM_V_CXXLD = @echo " CXXLD " $@;
ifeq ($(HAVE_NATIVE_COMP),yes)
ifeq ($(NATIVE_DISABLED),1)
AM_V_ELC = @echo " ELC " $@;
+AM_V_ELN =
else
AM_V_ELC = @echo " ELC+ELN " $@;
+AM_V_ELN = @echo " ELN " $@;
endif
else
AM_V_ELC = @echo " ELC " $@;
+AM_V_ELN =
endif
AM_V_GEN = @echo " GEN " $@;
AM_V_GLOBALS = @echo " GEN " globals.h;
diff --git a/src/vm-limit.c b/src/vm-limit.c
index b9058d04352..e0547651bb9 100644
--- a/src/vm-limit.c
+++ b/src/vm-limit.c
@@ -126,7 +126,7 @@ get_lim_data (void)
dos_memory_info (&totalram, &freeram, &totalswap, &freeswap);
lim_data = freeram;
- /* Don't believe they will give us more that 0.5 GB. */
+ /* Don't believe they will give us more than 0.5 GB. */
if (lim_data > 512U * 1024U * 1024U)
lim_data = 512U * 1024U * 1024U;
}
diff --git a/src/w16select.c b/src/w16select.c
index 37239137cf0..bbd2ed4bb97 100644
--- a/src/w16select.c
+++ b/src/w16select.c
@@ -87,7 +87,7 @@ static size_t clipboard_storage_size;
/* C functions to access the Windows 3.1x clipboard from DOS apps.
The information was obtained from the Microsoft Knowledge Base,
- article Q67675 and can be found at:
+ article Q67675 and can be found at: [broken link -- SK 2021-09-27]
http://www.microsoft.com/kb/developr/win_dk/q67675.htm */
/* See also Ralf Brown's Interrupt List.
diff --git a/src/w32.c b/src/w32.c
index 0eb69d4b1d1..1de148f0343 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -39,6 +39,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <sys/time.h>
#include <sys/utime.h>
#include <math.h>
+#include <nproc.h>
/* Include (most) CRT headers *before* ms-w32.h. */
#include <ms-w32.h>
@@ -1962,6 +1963,16 @@ w32_get_nproc (void)
return num_of_processors;
}
+/* Emulate Gnulib's 'num_processors'. We cannot use the Gnulib
+ version because it unconditionally calls APIs that aren't available
+ on old MS-Windows versions. */
+unsigned long
+num_processors (enum nproc_query query)
+{
+ /* We ignore QUERY. */
+ return w32_get_nproc ();
+}
+
static void
sample_system_load (ULONGLONG *idle, ULONGLONG *kernel, ULONGLONG *user)
{
@@ -2809,53 +2820,6 @@ sys_putenv (char *str)
#define REG_ROOT "SOFTWARE\\GNU\\Emacs"
-LPBYTE
-w32_get_resource (const char *key, LPDWORD lpdwtype)
-{
- LPBYTE lpvalue;
- HKEY hrootkey = NULL;
- DWORD cbData;
-
- /* Check both the current user and the local machine to see if
- we have any resources. */
-
- if (RegOpenKeyEx (HKEY_CURRENT_USER, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
- {
- lpvalue = NULL;
-
- if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS
- && (lpvalue = xmalloc (cbData)) != NULL
- && RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
- {
- RegCloseKey (hrootkey);
- return (lpvalue);
- }
-
- xfree (lpvalue);
-
- RegCloseKey (hrootkey);
- }
-
- if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
- {
- lpvalue = NULL;
-
- if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS
- && (lpvalue = xmalloc (cbData)) != NULL
- && RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
- {
- RegCloseKey (hrootkey);
- return (lpvalue);
- }
-
- xfree (lpvalue);
-
- RegCloseKey (hrootkey);
- }
-
- return (NULL);
-}
-
/* The argv[] array holds ANSI-encoded strings, and so this function
works with ANS_encoded strings. */
void
@@ -3066,7 +3030,7 @@ init_environment (char ** argv)
int dont_free = 0;
char bufc[SET_ENV_BUF_SIZE];
- if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL
+ if ((lpval = w32_get_resource (REG_ROOT, env_vars[i].name, &dwType)) == NULL
/* Also ignore empty environment variables. */
|| *lpval == 0)
{
@@ -6584,7 +6548,8 @@ acl_get_file (const char *fname, acl_type_t type)
xfree (psd);
err = GetLastError ();
if (err == ERROR_NOT_SUPPORTED
- || err == ERROR_ACCESS_DENIED)
+ || err == ERROR_ACCESS_DENIED
+ || err == ERROR_INVALID_FUNCTION)
errno = ENOTSUP;
else if (err == ERROR_FILE_NOT_FOUND
|| err == ERROR_PATH_NOT_FOUND
@@ -6603,10 +6568,11 @@ acl_get_file (const char *fname, acl_type_t type)
|| err == ERROR_INVALID_NAME)
errno = ENOENT;
else if (err == ERROR_NOT_SUPPORTED
- /* ERROR_ACCESS_DENIED is what we get for a volume
- mounted by WebDAV, which evidently doesn't
- support ACLs. */
- || err == ERROR_ACCESS_DENIED)
+ /* ERROR_ACCESS_DENIED or ERROR_INVALID_FUNCTION is
+ what we get for a volume mounted by WebDAV,
+ which evidently doesn't support ACLs. */
+ || err == ERROR_ACCESS_DENIED
+ || err == ERROR_INVALID_FUNCTION)
errno = ENOTSUP;
else
errno = EIO;
@@ -8582,7 +8548,7 @@ fcntl (int s, int cmd, int options)
int
sys_close (int fd)
{
- int rc;
+ int rc = -1;
if (fd < 0)
{
@@ -8637,14 +8603,31 @@ sys_close (int fd)
}
}
- if (fd >= 0 && fd < MAXDESC)
- fd_info[fd].flags = 0;
-
/* Note that sockets do not need special treatment here (at least on
NT and Windows 95 using the standard tcp/ip stacks) - it appears that
closesocket is equivalent to CloseHandle, which is to be expected
because socket handles are fully fledged kernel handles. */
- rc = _close (fd);
+ if (fd < MAXDESC)
+ {
+ if ((fd_info[fd].flags & FILE_DONT_CLOSE) == 0)
+ {
+ fd_info[fd].flags = 0;
+ rc = _close (fd);
+ }
+ else
+ {
+ /* We don't close here descriptors open by pipe processes
+ for reading from the pipe, because the reader thread
+ might be stuck in _sys_read_ahead, and then we will hang
+ here. If the reader thread exits normally, it will close
+ the descriptor; otherwise we will leave a zombie thread
+ hanging around. */
+ rc = 0;
+ /* Leave the flag set for the reader thread to close the
+ descriptor. */
+ fd_info[fd].flags = FILE_DONT_CLOSE;
+ }
+ }
return rc;
}
@@ -10932,6 +10915,7 @@ register_aux_fd (int infd)
}
fd_info[ infd ].cp = cp;
fd_info[ infd ].hnd = (HANDLE) _get_osfhandle (infd);
+ fd_info[ infd ].flags |= FILE_DONT_CLOSE;
}
#ifdef HAVE_GNUTLS
diff --git a/src/w32.h b/src/w32.h
index ffa145b1484..bb3ec40324a 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -135,6 +135,7 @@ extern filedesc fd_info [ MAXDESC ];
#define FILE_SOCKET 0x0200
#define FILE_NDELAY 0x0400
#define FILE_SERIAL 0x0800
+#define FILE_DONT_CLOSE 0x1000
extern child_process * new_child (void);
extern void delete_child (child_process *cp);
@@ -155,14 +156,15 @@ extern unsigned int w32_get_short_filename (const char *, char *, int);
/* Prepare our standard handles for proper inheritance by child processes. */
extern void prepare_standard_handles (int in, int out,
- int err, HANDLE handles[4]);
+ int err, HANDLE handles[3]);
/* Reset our standard handles to their original state. */
extern void reset_standard_handles (int in, int out,
- int err, HANDLE handles[4]);
+ int err, HANDLE handles[3]);
-/* Return the string resource associated with KEY of type TYPE. */
-extern LPBYTE w32_get_resource (const char * key, LPDWORD type);
+/* Query Windows Registry and return the resource associated
+ associated with KEY and NAME of type TYPE. */
+extern LPBYTE w32_get_resource (const char * key, const char * name, LPDWORD type);
extern void release_listen_threads (void);
extern void init_ntproc (int);
diff --git a/src/w32fns.c b/src/w32fns.c
index 14d1154a2bc..02a6d78b51c 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -73,6 +73,20 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <imm.h>
#include <windowsx.h>
+/*
+ Internal/undocumented constants for Windows Dark mode.
+ See: https://github.com/microsoft/WindowsAppSDK/issues/41
+*/
+#define DARK_MODE_APP_NAME L"DarkMode_Explorer"
+/* For Windows 10 version 1809, 1903, 1909. */
+#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE_OLD
+#define DWMWA_USE_IMMERSIVE_DARK_MODE_OLD 19
+#endif
+/* For Windows 10 version 2004 and higher, and Windows 11. */
+#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
+#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
+#endif
+
#ifndef FOF_NO_CONNECTED_ELEMENTS
#define FOF_NO_CONNECTED_ELEMENTS 0x2000
#endif
@@ -185,6 +199,11 @@ typedef BOOL (WINAPI *IsDebuggerPresent_Proc) (void);
typedef HRESULT (WINAPI *SetThreadDescription_Proc)
(HANDLE hThread, PCWSTR lpThreadDescription);
+typedef HRESULT (WINAPI * SetWindowTheme_Proc)
+ (IN HWND hwnd, IN LPCWSTR pszSubAppName, IN LPCWSTR pszSubIdList);
+typedef HRESULT (WINAPI * DwmSetWindowAttribute_Proc)
+ (HWND hwnd, DWORD dwAttribute, IN LPCVOID pvAttribute, DWORD cbAttribute);
+
TrackMouseEvent_Proc track_mouse_event_fn = NULL;
ImmGetCompositionString_Proc get_composition_string_fn = NULL;
ImmGetContext_Proc get_ime_context_fn = NULL;
@@ -199,6 +218,8 @@ EnumDisplayMonitors_Proc enum_display_monitors_fn = NULL;
GetTitleBarInfo_Proc get_title_bar_info_fn = NULL;
IsDebuggerPresent_Proc is_debugger_present = NULL;
SetThreadDescription_Proc set_thread_description = NULL;
+SetWindowTheme_Proc SetWindowTheme_fn = NULL;
+DwmSetWindowAttribute_Proc DwmSetWindowAttribute_fn = NULL;
extern AppendMenuW_Proc unicode_append_menu;
@@ -252,6 +273,9 @@ int w32_major_version;
int w32_minor_version;
int w32_build_number;
+/* If the OS is set to use dark mode. */
+BOOL w32_darkmode = FALSE;
+
/* Distinguish between Windows NT and Windows 95. */
int os_subtype;
@@ -2279,10 +2303,36 @@ w32_init_class (HINSTANCE hinst)
}
}
+/* Applies the Windows system theme (light or dark) to the window
+ handle HWND. */
+static void
+w32_applytheme (HWND hwnd)
+{
+ if (w32_darkmode)
+ {
+ /* Set window theme to that of a built-in Windows app (Explorer),
+ because it has dark scroll bars and other UI elements. */
+ if (SetWindowTheme_fn)
+ SetWindowTheme_fn (hwnd, DARK_MODE_APP_NAME, NULL);
+
+ /* Set the titlebar to system dark mode. */
+ if (DwmSetWindowAttribute_fn)
+ {
+ /* Windows 10 version 2004 and up, Windows 11. */
+ DWORD attr = DWMWA_USE_IMMERSIVE_DARK_MODE;
+ /* Windows 10 older than 2004. */
+ if (w32_build_number < 19041)
+ attr = DWMWA_USE_IMMERSIVE_DARK_MODE_OLD;
+ DwmSetWindowAttribute_fn (hwnd, attr,
+ &w32_darkmode, sizeof (w32_darkmode));
+ }
+ }
+}
+
static HWND
w32_createvscrollbar (struct frame *f, struct scroll_bar * bar)
{
- return CreateWindow ("SCROLLBAR", "",
+ HWND hwnd = CreateWindow ("SCROLLBAR", "",
/* Clip siblings so we don't draw over child
frames. Apparently this is not always
sufficient so we also try to make bar windows
@@ -2291,12 +2341,15 @@ w32_createvscrollbar (struct frame *f, struct scroll_bar * bar)
/* Position and size of scroll bar. */
bar->left, bar->top, bar->width, bar->height,
FRAME_W32_WINDOW (f), NULL, hinst, NULL);
+ if (hwnd)
+ w32_applytheme (hwnd);
+ return hwnd;
}
static HWND
w32_createhscrollbar (struct frame *f, struct scroll_bar * bar)
{
- return CreateWindow ("SCROLLBAR", "",
+ HWND hwnd = CreateWindow ("SCROLLBAR", "",
/* Clip siblings so we don't draw over child
frames. Apparently this is not always
sufficient so we also try to make bar windows
@@ -2305,6 +2358,9 @@ w32_createhscrollbar (struct frame *f, struct scroll_bar * bar)
/* Position and size of scroll bar. */
bar->left, bar->top, bar->width, bar->height,
FRAME_W32_WINDOW (f), NULL, hinst, NULL);
+ if (hwnd)
+ w32_applytheme (hwnd);
+ return hwnd;
}
static void
@@ -2390,6 +2446,9 @@ w32_createwindow (struct frame *f, int *coords)
/* Enable drag-n-drop. */
DragAcceptFiles (hwnd, TRUE);
+ /* Enable system light/dark theme. */
+ w32_applytheme (hwnd);
+
/* Do this to discard the default setting specified by our parent. */
ShowWindow (hwnd, SW_HIDE);
@@ -5114,6 +5173,13 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
goto dflt;
+ case WM_SETTINGCHANGE:
+ /* Inform the Lisp thread that some system-wide setting has
+ changed, so if Emacs is interested in some of them, it could
+ update its internal values. */
+ my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+ goto dflt;
+
case WM_SETFOCUS:
dpyinfo->faked_key = 0;
reset_modifiers ();
@@ -7459,7 +7525,8 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
/* Calculate size of tooltip window. */
size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil,
- make_fixnum (w->pixel_height), Qnil);
+ make_fixnum (w->pixel_height), Qnil,
+ Qnil);
/* Add the frame's internal border to calculated size. */
width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
@@ -10257,6 +10324,60 @@ to be converted to forward slashes by the caller. */)
}
#endif /* WINDOWSNT */
+
+/* Query a value from the Windows Registry (under HKCU and HKLM),
+ where `key` is the registry key, `name` is the name, and `lpdwtype`
+ is a pointer to the return value's type. `lpwdtype` can be NULL if
+ you do not care about the type.
+
+ Returns: pointer to the value, or null pointer if the key/name does
+ not exist. */
+LPBYTE
+w32_get_resource (const char *key, const char *name, LPDWORD lpdwtype)
+{
+ LPBYTE lpvalue;
+ HKEY hrootkey = NULL;
+ DWORD cbData;
+
+ /* Check both the current user and the local machine to see if
+ we have any resources. */
+
+ if (RegOpenKeyEx (HKEY_CURRENT_USER, key, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
+ {
+ lpvalue = NULL;
+
+ if (RegQueryValueEx (hrootkey, name, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS
+ && (lpvalue = xmalloc (cbData)) != NULL
+ && RegQueryValueEx (hrootkey, name, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
+ {
+ RegCloseKey (hrootkey);
+ return (lpvalue);
+ }
+
+ xfree (lpvalue);
+
+ RegCloseKey (hrootkey);
+ }
+
+ if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
+ {
+ lpvalue = NULL;
+
+ if (RegQueryValueEx (hrootkey, name, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS
+ && (lpvalue = xmalloc (cbData)) != NULL
+ && RegQueryValueEx (hrootkey, name, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
+ {
+ RegCloseKey (hrootkey);
+ return (lpvalue);
+ }
+
+ xfree (lpvalue);
+
+ RegCloseKey (hrootkey);
+ }
+
+ return (NULL);
+}
/***********************************************************************
Initialization
@@ -11028,6 +11149,37 @@ globals_of_w32fns (void)
set_thread_description = (SetThreadDescription_Proc)
get_proc_addr (hm_kernel32, "SetThreadDescription");
+ /* Support OS dark mode on Windows 10 version 1809 and higher.
+ See `w32_applytheme` which uses appropriate APIs per version of Windows.
+ For future wretches who may need to understand Windows build numbers:
+ https://docs.microsoft.com/en-us/windows/release-health/release-information
+ */
+ if (os_subtype == OS_SUBTYPE_NT
+ && w32_major_version >= 10 && w32_build_number >= 17763)
+ {
+ /* Load dwmapi.dll and uxtheme.dll, which will be needed to set
+ window themes. */
+ HMODULE dwmapi_lib = LoadLibrary("dwmapi.dll");
+ DwmSetWindowAttribute_fn = (DwmSetWindowAttribute_Proc)
+ get_proc_addr (dwmapi_lib, "DwmSetWindowAttribute");
+ HMODULE uxtheme_lib = LoadLibrary("uxtheme.dll");
+ SetWindowTheme_fn = (SetWindowTheme_Proc)
+ get_proc_addr (uxtheme_lib, "SetWindowTheme");
+
+ /* Check Windows Registry for system theme and set w32_darkmode.
+ TODO: "Nice to have" would be to create a lisp setting (which
+ defaults to this Windows Registry value), then read that lisp
+ value here instead. This would allow the user to forcibly
+ override the system theme (which is also user-configurable in
+ Windows settings; see MS-Windows section in Emacs manual). */
+ LPBYTE val =
+ w32_get_resource ("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
+ "AppsUseLightTheme",
+ NULL);
+ if (val && *val == 0)
+ w32_darkmode = TRUE;
+ }
+
except_code = 0;
except_addr = 0;
#ifndef CYGWIN
diff --git a/src/w32font.c b/src/w32font.c
index 6b9ab0468cd..2d09f459f89 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -1974,10 +1974,11 @@ w32_decode_weight (int fnweight)
if (fnweight >= FW_EXTRABOLD) return 205;
if (fnweight >= FW_BOLD) return 200;
if (fnweight >= FW_SEMIBOLD) return 180;
- if (fnweight >= FW_NORMAL) return 100;
- if (fnweight >= FW_LIGHT) return 50;
- if (fnweight >= FW_EXTRALIGHT) return 40;
- if (fnweight > FW_THIN) return 20;
+ if (fnweight >= FW_MEDIUM) return 100;
+ if (fnweight >= FW_NORMAL) return 80;
+ if (fnweight >= FW_LIGHT) return 50;
+ if (fnweight >= FW_EXTRALIGHT) return 40;
+ if (fnweight >= FW_THIN) return 20;
return 0;
}
@@ -1988,10 +1989,11 @@ w32_encode_weight (int n)
if (n >= 205) return FW_EXTRABOLD;
if (n >= 200) return FW_BOLD;
if (n >= 180) return FW_SEMIBOLD;
- if (n >= 100) return FW_NORMAL;
- if (n >= 50) return FW_LIGHT;
- if (n >= 40) return FW_EXTRALIGHT;
- if (n >= 20) return FW_THIN;
+ if (n >= 100) return FW_MEDIUM;
+ if (n >= 80) return FW_NORMAL;
+ if (n >= 50) return FW_LIGHT;
+ if (n >= 40) return FW_EXTRALIGHT;
+ if (n >= 20) return FW_THIN;
return 0;
}
@@ -2000,14 +2002,15 @@ w32_encode_weight (int n)
static Lisp_Object
w32_to_fc_weight (int n)
{
- if (n >= FW_HEAVY) return intern ("black");
- if (n >= FW_EXTRABOLD) return Qextra_bold;
- if (n >= FW_BOLD) return Qbold;
- if (n >= FW_SEMIBOLD) return intern ("demibold");
- if (n >= FW_NORMAL) return intern ("medium");
- if (n >= FW_LIGHT) return Qlight;
+ if (n >= FW_HEAVY) return Qblack;
+ if (n >= FW_EXTRABOLD) return Qextra_bold;
+ if (n >= FW_BOLD) return Qbold;
+ if (n >= FW_SEMIBOLD) return Qsemi_bold;
+ if (n >= FW_MEDIUM) return Qmedium;
+ if (n >= FW_NORMAL) return Qnormal;
+ if (n >= FW_LIGHT) return Qlight;
if (n >= FW_EXTRALIGHT) return Qextra_light;
- return intern ("thin");
+ return Qthin;
}
/* Fill in all the available details of LOGFONT from FONT_SPEC. */
@@ -2019,13 +2022,9 @@ fill_in_logfont (struct frame *f, LOGFONT *logfont, Lisp_Object font_spec)
tmp = AREF (font_spec, FONT_DPI_INDEX);
if (FIXNUMP (tmp))
- {
- dpi = XFIXNUM (tmp);
- }
+ dpi = XFIXNUM (tmp);
else if (FLOATP (tmp))
- {
- dpi = (int) (XFLOAT_DATA (tmp) + 0.5);
- }
+ dpi = (int) (XFLOAT_DATA (tmp) + 0.5);
/* Height */
tmp = AREF (font_spec, FONT_SIZE_INDEX);
diff --git a/src/w32heap.c b/src/w32heap.c
index 0f228bfb221..a0d4c070be3 100644
--- a/src/w32heap.c
+++ b/src/w32heap.c
@@ -189,6 +189,26 @@ malloc_fn the_malloc_fn;
realloc_fn the_realloc_fn;
free_fn the_free_fn;
+static void *
+heap_alloc (size_t size)
+{
+ void *p = size <= PTRDIFF_MAX ? HeapAlloc (heap, 0, size | !size) : NULL;
+ if (!p)
+ errno = ENOMEM;
+ return p;
+}
+
+static void *
+heap_realloc (void *ptr, size_t size)
+{
+ void *p = (size <= PTRDIFF_MAX
+ ? HeapReAlloc (heap, 0, ptr, size | !size)
+ : NULL);
+ if (!p)
+ errno = ENOMEM;
+ return p;
+}
+
/* It doesn't seem to be useful to allocate from a file mapping.
It would be if the memory was shared.
https://stackoverflow.com/questions/307060/what-is-the-purpose-of-allocating-pages-in-the-pagefile-with-createfilemapping */
@@ -346,7 +366,7 @@ void *
malloc_after_dump (size_t size)
{
/* Use the new private heap. */
- void *p = HeapAlloc (heap, 0, size);
+ void *p = heap_alloc (size);
/* After dump, keep track of the "brk value" for sbrk(0). */
if (p)
@@ -356,8 +376,6 @@ malloc_after_dump (size_t size)
if (new_brk > data_region_end)
data_region_end = new_brk;
}
- else
- errno = ENOMEM;
return p;
}
@@ -373,9 +391,7 @@ malloc_before_dump (size_t size)
if (size < MaxBlockSize)
{
/* Use the private heap if possible. */
- p = HeapAlloc (heap, 0, size);
- if (!p)
- errno = ENOMEM;
+ p = heap_alloc (size);
}
else
{
@@ -433,18 +449,14 @@ realloc_after_dump (void *ptr, size_t size)
if (FREEABLE_P (ptr))
{
/* Reallocate the block since it lies in the new heap. */
- p = HeapReAlloc (heap, 0, ptr, size);
- if (!p)
- errno = ENOMEM;
+ p = heap_realloc (ptr, size);
}
else
{
/* If the block lies in the dumped data, do not free it. Only
allocate a new one. */
- p = HeapAlloc (heap, 0, size);
- if (!p)
- errno = ENOMEM;
- else if (ptr)
+ p = heap_alloc (size);
+ if (p && ptr)
CopyMemory (p, ptr, size);
}
/* After dump, keep track of the "brk value" for sbrk(0). */
@@ -467,9 +479,7 @@ realloc_before_dump (void *ptr, size_t size)
if (dumped_data < (unsigned char *)ptr
&& (unsigned char *)ptr < bc_limit && size <= MaxBlockSize)
{
- p = HeapReAlloc (heap, 0, ptr, size);
- if (!p)
- errno = ENOMEM;
+ p = heap_realloc (ptr, size);
}
else
{
diff --git a/src/w32inevt.c b/src/w32inevt.c
index 1255072b7f3..4cc01d31c94 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -420,7 +420,7 @@ w32_console_mouse_position (struct frame **f,
*f = get_frame ();
*bar_window = Qnil;
*part = scroll_bar_above_handle;
- SELECTED_FRAME ()->mouse_moved = 0;
+ (*f)->mouse_moved = 0;
XSETINT (*x, movement_pos.X);
XSETINT (*y, movement_pos.Y);
@@ -436,7 +436,8 @@ mouse_moved_to (int x, int y)
/* If we're in the same place, ignore it. */
if (x != movement_pos.X || y != movement_pos.Y)
{
- SELECTED_FRAME ()->mouse_moved = 1;
+ struct frame *f = get_frame ();
+ f->mouse_moved = 1;
movement_pos.X = x;
movement_pos.Y = y;
movement_time = GetTickCount ();
@@ -470,11 +471,14 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
DWORD but_change, mask, flags = event->dwEventFlags;
int i;
+ /* Mouse didn't move unless MOUSE_MOVED says it did. */
+ struct frame *f = get_frame ();
+ f->mouse_moved = 0;
+
switch (flags)
{
case MOUSE_MOVED:
{
- struct frame *f = get_frame ();
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
int mx = event->dwMousePosition.X, my = event->dwMousePosition.Y;
@@ -533,7 +537,6 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
case MOUSE_WHEELED:
case MOUSE_HWHEELED:
{
- struct frame *f = get_frame ();
/* Mouse positions in console wheel events are reported to
ReadConsoleInput relative to the display's top-left
corner(!), not relative to the origin of the console screen
@@ -585,10 +588,9 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
int x = event->dwMousePosition.X;
int y = event->dwMousePosition.Y;
- struct frame *f = get_frame ();
- if (tty_handle_tab_bar_click (f, x, y, (button_state & mask) != 0,
- emacs_ev))
- return 0; /* tty_handle_tab_bar_click adds the event to queue */
+ emacs_ev->arg = tty_handle_tab_bar_click (f, x, y,
+ (button_state & mask) != 0,
+ emacs_ev);
emacs_ev->modifiers |= ((button_state & mask)
? down_modifier : up_modifier);
@@ -597,7 +599,6 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
XSETFASTINT (emacs_ev->x, x);
XSETFASTINT (emacs_ev->y, y);
XSETFRAME (emacs_ev->frame_or_window, f);
- emacs_ev->arg = Qnil;
return 1;
}
diff --git a/src/w32proc.c b/src/w32proc.c
index 702ea122e65..bfe720eb623 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -1206,6 +1206,7 @@ static DWORD WINAPI
reader_thread (void *arg)
{
child_process *cp;
+ int fd;
/* Our identity */
cp = (child_process *)arg;
@@ -1220,12 +1221,13 @@ reader_thread (void *arg)
{
int rc;
- if (cp->fd >= 0 && (fd_info[cp->fd].flags & FILE_CONNECT) != 0)
- rc = _sys_wait_connect (cp->fd);
- else if (cp->fd >= 0 && (fd_info[cp->fd].flags & FILE_LISTEN) != 0)
- rc = _sys_wait_accept (cp->fd);
+ fd = cp->fd;
+ if (fd >= 0 && (fd_info[fd].flags & FILE_CONNECT) != 0)
+ rc = _sys_wait_connect (fd);
+ else if (fd >= 0 && (fd_info[fd].flags & FILE_LISTEN) != 0)
+ rc = _sys_wait_accept (fd);
else
- rc = _sys_read_ahead (cp->fd);
+ rc = _sys_read_ahead (fd);
/* Don't bother waiting for the event if we already have been
told to exit by delete_child. */
@@ -1238,7 +1240,7 @@ reader_thread (void *arg)
{
DebPrint (("reader_thread.SetEvent(0x%x) failed with %lu for fd %ld (PID %d)\n",
(DWORD_PTR)cp->char_avail, GetLastError (),
- cp->fd, cp->pid));
+ fd, cp->pid));
return 1;
}
@@ -1266,6 +1268,13 @@ reader_thread (void *arg)
if (cp->status == STATUS_READ_ERROR)
break;
}
+ /* If this thread was reading from a pipe process, close the
+ descriptor used for reading, as sys_close doesn't in that case. */
+ if (fd_info[fd].flags == FILE_DONT_CLOSE)
+ {
+ fd_info[fd].flags = 0;
+ _close (fd);
+ }
return 0;
}
@@ -3878,14 +3887,6 @@ w32_compare_strings (const char *s1, const char *s2, char *locname,
return val - 2;
}
-DEFUN ("w32-get-nproc", Fw32_get_nproc,
- Sw32_get_nproc, 0, 0, 0,
- doc: /* Return the number of system's processor execution units. */)
- (void)
-{
- return make_fixnum (w32_get_nproc ());
-}
-
void
syms_of_ntproc (void)
@@ -3920,8 +3921,6 @@ syms_of_ntproc (void)
defsubr (&Sw32_get_keyboard_layout);
defsubr (&Sw32_set_keyboard_layout);
- defsubr (&Sw32_get_nproc);
-
DEFVAR_LISP ("w32-quote-process-args", Vw32_quote_process_args,
doc: /* Non-nil enables quoting of process arguments to ensure correct parsing.
Because Windows does not directly pass argv arrays to child processes,
diff --git a/src/w32term.c b/src/w32term.c
index ad4d1a32829..fdb088deda2 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -164,12 +164,16 @@ int last_scroll_bar_drag_pos;
/* Keyboard code page - may be changed by language-change events. */
int w32_keyboard_codepage;
+/* The number of screen lines to scroll for the default mouse-wheel
+ scroll amount, given by WHEEL_DELTA. */
+static UINT w32_wheel_scroll_lines;
+
#ifdef CYGWIN
int w32_message_fd = -1;
#endif /* CYGWIN */
-static void w32_handle_tab_bar_click (struct frame *,
- struct input_event *);
+static Lisp_Object w32_handle_tab_bar_click (struct frame *,
+ struct input_event *);
static void w32_handle_tool_bar_click (struct frame *,
struct input_event *);
static void w32_define_cursor (Window, Emacs_Cursor);
@@ -272,6 +276,19 @@ XGetGCValues (void *ignore, XGCValues *gc,
#endif
static void
+w32_get_mouse_wheel_vertical_delta (void)
+{
+ if (os_subtype != OS_SUBTYPE_NT)
+ return;
+
+ UINT scroll_lines;
+ BOOL ret = SystemParametersInfo (SPI_GETWHEELSCROLLLINES, 0,
+ &scroll_lines, 0);
+ if (ret)
+ w32_wheel_scroll_lines = scroll_lines;
+}
+
+static void
w32_set_clip_rectangle (HDC hdc, RECT *rect)
{
if (rect)
@@ -954,22 +971,6 @@ w32_set_cursor_gc (struct glyph_string *s)
static void
w32_set_mouse_face_gc (struct glyph_string *s)
{
- int face_id;
- struct face *face;
-
- /* What face has to be used last for the mouse face? */
- face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
- face = FACE_FROM_ID_OR_NULL (s->f, face_id);
- if (face == NULL)
- face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
-
- if (s->first_glyph->type == CHAR_GLYPH)
- face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
- else
- face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
- s->face = FACE_FROM_ID (s->f, face_id);
- prepare_face_for_display (s->f, s->face);
-
/* If font in this face is same as S->font, use it. */
if (s->font == s->face->font)
s->gc = s->face->gc;
@@ -2031,11 +2032,14 @@ w32_draw_image_relief (struct glyph_string *s)
if (s->hl == DRAW_IMAGE_SUNKEN
|| s->hl == DRAW_IMAGE_RAISED)
{
- thick = (tab_bar_button_relief < 0
- ? DEFAULT_TAB_BAR_BUTTON_RELIEF
- : (tool_bar_button_relief < 0
- ? DEFAULT_TOOL_BAR_BUTTON_RELIEF
- : min (tool_bar_button_relief, 1000000)));
+ if (s->face->id == TAB_BAR_FACE_ID)
+ thick = (tab_bar_button_relief < 0
+ ? DEFAULT_TAB_BAR_BUTTON_RELIEF
+ : min (tab_bar_button_relief, 1000000));
+ else
+ thick = (tool_bar_button_relief < 0
+ ? DEFAULT_TOOL_BAR_BUTTON_RELIEF
+ : min (tool_bar_button_relief, 1000000));
raised_p = s->hl == DRAW_IMAGE_RAISED;
}
else
@@ -2054,11 +2058,11 @@ w32_draw_image_relief (struct glyph_string *s)
&& FIXNUMP (XCAR (Vtab_bar_button_margin))
&& FIXNUMP (XCDR (Vtab_bar_button_margin)))
{
- extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin));
- extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin));
+ extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin)) - thick;
+ extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin)) - thick;
}
else if (FIXNUMP (Vtab_bar_button_margin))
- extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin);
+ extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin) - thick;
}
if (s->face->id == TOOL_BAR_FACE_ID)
@@ -2420,29 +2424,15 @@ w32_draw_stretch_glyph_string (struct glyph_string *s)
else if (!s->background_filled_p)
{
int background_width = s->background_width;
- int x = s->x, text_left_x = window_box_left_offset (s->w, TEXT_AREA);
+ int x = s->x, text_left_x = window_box_left (s->w, TEXT_AREA);
/* Don't draw into left fringe or scrollbar area except for
header line and mode line. */
- if (x < text_left_x && !s->row->mode_line_p)
+ if (s->area == TEXT_AREA
+ && x < text_left_x && !s->row->mode_line_p)
{
- int left_x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (s->w);
- int right_x = text_left_x;
-
- if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s->w))
- left_x += WINDOW_LEFT_FRINGE_WIDTH (s->w);
- else
- right_x -= WINDOW_LEFT_FRINGE_WIDTH (s->w);
-
- /* Adjust X and BACKGROUND_WIDTH to fit inside the space
- between LEFT_X and RIGHT_X. */
- if (x < left_x)
- {
- background_width -= left_x - x;
- x = left_x;
- }
- if (x + background_width > right_x)
- background_width = right_x - x;
+ background_width -= text_left_x - x;
+ x = text_left_x;
}
if (background_width > 0)
w32_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
@@ -2550,6 +2540,10 @@ w32_draw_glyph_string (struct glyph_string *s)
if (!s->for_overlaps)
{
+ /* Draw relief if not yet drawn. */
+ if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
+ w32_draw_glyph_string_box (s);
+
/* Draw underline. */
if (s->face->underline)
{
@@ -2693,10 +2687,6 @@ w32_draw_glyph_string (struct glyph_string *s)
}
}
- /* Draw relief if not yet drawn. */
- if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
- w32_draw_glyph_string_box (s);
-
if (s->prev)
{
struct glyph_string *prev;
@@ -3230,32 +3220,94 @@ w32_construct_mouse_wheel (struct input_event *result, W32Msg *msg,
{
POINT p;
int delta;
+ static int sum_delta_y = 0;
result->kind = msg->msg.message == WM_MOUSEHWHEEL ? HORIZ_WHEEL_EVENT
: WHEEL_EVENT;
result->code = 0;
result->timestamp = msg->msg.time;
+ result->arg = Qnil;
/* A WHEEL_DELTA positive value indicates that the wheel was rotated
forward, away from the user (up); a negative value indicates that
the wheel was rotated backward, toward the user (down). */
delta = GET_WHEEL_DELTA_WPARAM (msg->msg.wParam);
+ if (delta == 0)
+ {
+ result->kind = NO_EVENT;
+ return Qnil;
+ }
+
+ /* With multiple monitors, we can legitimately get negative
+ coordinates, so cast to short to interpret them correctly. */
+ p.x = (short) LOWORD (msg->msg.lParam);
+ p.y = (short) HIWORD (msg->msg.lParam);
+
+ if (eabs (delta) < WHEEL_DELTA)
+ {
+ /* This is high-precision mouse wheel, which sends
+ fine-resolution wheel events. Produce a wheel event only if
+ the conditions for sending such an event are fulfilled. */
+ int scroll_unit = max (w32_wheel_scroll_lines, 1), nlines;
+ double value_to_report;
+
+ /* w32_wheel_scroll_lines == UINT_MAX means the user asked for
+ "entire page" to be the scroll unit. We interpret that as
+ the height of the window under the mouse pointer. */
+ if (w32_wheel_scroll_lines == UINT_MAX)
+ {
+ Lisp_Object window = window_from_coordinates (f, p.x, p.y, NULL,
+ false, false);
+ if (!WINDOWP (window))
+ {
+ result->kind = NO_EVENT;
+ return Qnil;
+ }
+ scroll_unit = XWINDOW (window)->pixel_height;
+ if (scroll_unit < 1) /* paranoia */
+ scroll_unit = 1;
+ }
+
+ /* If mwheel-coalesce-scroll-events is non-nil, report a wheel event
+ only when we have accumulated enough delta's for WHEEL_DELTA. */
+ if (mwheel_coalesce_scroll_events)
+ {
+ /* If the user changed the direction, reset the accumulated
+ deltas. */
+ if ((delta > 0) != (sum_delta_y > 0))
+ sum_delta_y = 0;
+ sum_delta_y += delta;
+ /* https://docs.microsoft.com/en-us/previous-versions/ms997498(v=msdn.10) */
+ if (eabs (sum_delta_y) < WHEEL_DELTA)
+ {
+ result->kind = NO_EVENT;
+ return Qnil;
+ }
+ value_to_report =
+ ((double)FRAME_LINE_HEIGHT (f) * scroll_unit)
+ / ((double)WHEEL_DELTA / sum_delta_y);
+ sum_delta_y = 0;
+ }
+ else
+ value_to_report =
+ ((double)FRAME_LINE_HEIGHT (f) * scroll_unit)
+ / ((double)WHEEL_DELTA / delta);
+ nlines = value_to_report / FRAME_LINE_HEIGHT (f) + 0.5;
+ result->arg = list3 (make_fixnum (nlines),
+ make_float (0.0),
+ make_float (value_to_report));
+ }
/* The up and down modifiers indicate if the wheel was rotated up or
down based on WHEEL_DELTA value. */
result->modifiers = (msg->dwModifiers
| ((delta < 0 ) ? down_modifier : up_modifier));
- /* With multiple monitors, we can legitimately get negative
- coordinates, so cast to short to interpret them correctly. */
- p.x = (short) LOWORD (msg->msg.lParam);
- p.y = (short) HIWORD (msg->msg.lParam);
/* For the case that F's w32 window is not msg->msg.hwnd. */
ScreenToClient (FRAME_W32_WINDOW (f), &p);
XSETINT (result->x, p.x);
XSETINT (result->y, p.y);
XSETFRAME (result->frame_or_window, f);
- result->arg = Qnil;
return Qnil;
}
@@ -3684,17 +3736,17 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
frame-relative coordinates X/Y. EVENT_TYPE is either ButtonPress
or ButtonRelease. */
-static void
+static Lisp_Object
w32_handle_tab_bar_click (struct frame *f, struct input_event *button_event)
{
int x = XFIXNAT (button_event->x);
int y = XFIXNAT (button_event->y);
if (button_event->modifiers & down_modifier)
- handle_tab_bar_click (f, x, y, 1, 0);
+ return handle_tab_bar_click (f, x, y, 1, 0);
else
- handle_tab_bar_click (f, x, y, 0,
- button_event->modifiers & ~up_modifier);
+ return handle_tab_bar_click (f, x, y, 0,
+ button_event->modifiers & ~up_modifier);
}
@@ -4932,6 +4984,14 @@ w32_read_socket (struct terminal *terminal,
}
break;
+ case WM_SETTINGCHANGE:
+ /* We are only interested in changes of the number of lines
+ to scroll when the vertical mouse wheel is moved. This
+ is only supported on NT. */
+ if (msg.msg.wParam == SPI_SETWHEELSCROLLLINES)
+ w32_get_mouse_wheel_vertical_delta ();
+ break;
+
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
@@ -5186,6 +5246,7 @@ w32_read_socket (struct terminal *terminal,
{
/* If we decide we want to generate an event to be seen
by the rest of Emacs, we put it here. */
+ Lisp_Object tab_bar_arg = Qnil;
bool tab_bar_p = 0;
bool tool_bar_p = 0;
int button = 0;
@@ -5208,12 +5269,12 @@ w32_read_socket (struct terminal *terminal,
if (EQ (window, f->tab_bar_window))
{
- w32_handle_tab_bar_click (f, &inev);
+ tab_bar_arg = w32_handle_tab_bar_click (f, &inev);
tab_bar_p = 1;
}
}
- if (tab_bar_p
+ if ((tab_bar_p && NILP (tab_bar_arg))
|| (dpyinfo->w32_focus_frame
&& f != dpyinfo->w32_focus_frame
/* This does not help when the click happens in
@@ -5221,6 +5282,9 @@ w32_read_socket (struct terminal *terminal,
&& !frame_ancestor_p (f, dpyinfo->w32_focus_frame)))
inev.kind = NO_EVENT;
+ if (!NILP (tab_bar_arg))
+ inev.arg = tab_bar_arg;
+
/* Is this in the tool-bar? */
if (WINDOWP (f->tool_bar_window)
&& WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
@@ -7545,6 +7609,8 @@ w32_initialize (void)
horizontal_scroll_bar_left_border = horizontal_scroll_bar_right_border
= GetSystemMetrics (SM_CYHSCROLL);
}
+
+ w32_get_mouse_wheel_vertical_delta ();
}
void
diff --git a/src/window.c b/src/window.c
index a6e8ee0d534..e801ff821f1 100644
--- a/src/window.c
+++ b/src/window.c
@@ -20,6 +20,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <config.h>
+/* Work around GCC bug 102671. */
+#if 10 <= __GNUC__
+# pragma GCC diagnostic ignored "-Wanalyzer-null-dereference"
+#endif
+
#include "lisp.h"
#include "buffer.h"
#include "keyboard.h"
@@ -760,6 +765,19 @@ selected one. */)
{
return make_fixnum (decode_live_window (window)->use_time);
}
+
+DEFUN ("window-bump-use-time", Fwindow_bump_use_time,
+ Swindow_bump_use_time, 0, 1, 0,
+ doc: /* Mark WINDOW as having been most recently used.
+WINDOW must be a live window and defaults to the selected one. */)
+ (Lisp_Object window)
+{
+ struct window *w = decode_live_window (window);
+
+ w->use_time = ++window_select_count;
+
+ return Qnil;
+}
DEFUN ("window-pixel-width", Fwindow_pixel_width, Swindow_pixel_width, 0, 1, 0,
doc: /* Return the width of window WINDOW in pixels.
@@ -3194,8 +3212,10 @@ function in a program gives strange scrolling, make sure the
window-start value is reasonable when this function is called. */)
(Lisp_Object window, Lisp_Object root)
{
- struct window *w, *r, *s;
- struct frame *f;
+ struct window *w = decode_valid_window (window);
+ struct window *r, *s;
+ Lisp_Object frame = w->frame;
+ struct frame *f = XFRAME (frame);
Lisp_Object sibling, pwindow, delta;
Lisp_Object swindow UNINIT;
ptrdiff_t startpos UNINIT, startbyte UNINIT;
@@ -3203,9 +3223,7 @@ window-start value is reasonable when this function is called. */)
int new_top;
bool resize_failed = false;
- w = decode_valid_window (window);
XSETWINDOW (window, w);
- f = XFRAME (w->frame);
if (NILP (root))
/* ROOT is the frame's root window. */
@@ -3245,7 +3263,7 @@ window-start value is reasonable when this function is called. */)
/* Make sure WINDOW is the frame's selected window. */
if (!EQ (window, FRAME_SELECTED_WINDOW (f)))
{
- if (EQ (selected_frame, w->frame))
+ if (EQ (selected_frame, frame))
Fselect_window (window, Qnil);
else
/* Do not clear f->select_mini_window_flag here. If the
@@ -3278,7 +3296,7 @@ window-start value is reasonable when this function is called. */)
if (!EQ (swindow, FRAME_SELECTED_WINDOW (f)))
{
- if (EQ (selected_frame, w->frame))
+ if (EQ (selected_frame, frame))
Fselect_window (swindow, Qnil);
else
fset_selected_window (f, swindow);
@@ -3313,18 +3331,12 @@ window-start value is reasonable when this function is called. */)
w->top_line = r->top_line;
resize_root_window (window, delta, Qnil, Qnil, Qt);
if (window_resize_check (w, false))
- {
- window_resize_apply (w, false);
- window_pixel_to_total (w->frame, Qnil);
- }
+ window_resize_apply (w, false);
else
{
resize_root_window (window, delta, Qnil, Qt, Qt);
if (window_resize_check (w, false))
- {
- window_resize_apply (w, false);
- window_pixel_to_total (w->frame, Qnil);
- }
+ window_resize_apply (w, false);
else
resize_failed = true;
}
@@ -3337,18 +3349,12 @@ window-start value is reasonable when this function is called. */)
XSETINT (delta, r->pixel_width - w->pixel_width);
resize_root_window (window, delta, Qt, Qnil, Qt);
if (window_resize_check (w, true))
- {
- window_resize_apply (w, true);
- window_pixel_to_total (w->frame, Qt);
- }
+ window_resize_apply (w, true);
else
{
resize_root_window (window, delta, Qt, Qt, Qt);
if (window_resize_check (w, true))
- {
- window_resize_apply (w, true);
- window_pixel_to_total (w->frame, Qt);
- }
+ window_resize_apply (w, true);
else
resize_failed = true;
}
@@ -3390,6 +3396,12 @@ window-start value is reasonable when this function is called. */)
}
replace_window (root, window, true);
+ /* Assign new total sizes to all windows on FRAME. We can't do that
+ _before_ WINDOW replaces ROOT since 'window--pixel-to-total' works
+ on the whole frame and thus would work on the frame's old window
+ configuration (Bug#51007). */
+ window_pixel_to_total (frame, Qnil);
+ window_pixel_to_total (frame, Qt);
/* This must become SWINDOW anyway ....... */
if (BUFFERP (w->contents) && !resize_failed)
@@ -8123,18 +8135,6 @@ and scrolling positions. */)
return Qt;
return Qnil;
}
-
-DEFUN ("window-bump-use-time", Fwindow_bump_use_time,
- Swindow_bump_use_time, 1, 1, 0,
- doc: /* Mark WINDOW as having been recently used. */)
- (Lisp_Object window)
-{
- struct window *w = decode_valid_window (window);
-
- w->use_time = ++window_select_count;
- return Qnil;
-}
-
static void init_window_once_for_pdumper (void);
diff --git a/src/window.h b/src/window.h
index 2400c422c15..8e9a2eb3177 100644
--- a/src/window.h
+++ b/src/window.h
@@ -756,7 +756,7 @@ wset_next_buffers (struct window *w, Lisp_Object val)
#endif
/* True if W is a tab bar window. */
-#if defined (HAVE_WINDOW_SYSTEM)
+#if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_PGTK)
# define WINDOW_TAB_BAR_P(W) \
(WINDOWP (WINDOW_XFRAME (W)->tab_bar_window) \
&& (W) == XWINDOW (WINDOW_XFRAME (W)->tab_bar_window))
diff --git a/src/xdisp.c b/src/xdisp.c
index e853c8c2232..3a1bc1613f7 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -822,6 +822,9 @@ bool help_echo_showing_p;
/* Functions to mark elements as needing redisplay. */
enum { REDISPLAY_SOME = 2}; /* Arbitrary choice. */
+static bool calc_pixel_width_or_height (double *, struct it *, Lisp_Object,
+ struct font *, bool, int *);
+
void
redisplay_other_windows (void)
{
@@ -1179,7 +1182,13 @@ static void append_stretch_glyph (struct it *, Lisp_Object,
static Lisp_Object get_it_property (struct it *, Lisp_Object);
static Lisp_Object calc_line_height_property (struct it *, Lisp_Object,
struct font *, int, bool);
-
+static int adjust_glyph_width_for_mouse_face (struct glyph *,
+ struct glyph_row *,
+ struct window *, struct face *,
+ struct face *);
+static void get_cursor_offset_for_mouse_face (struct window *w,
+ struct glyph_row *row,
+ int *offset);
#endif /* HAVE_WINDOW_SYSTEM */
static void produce_special_glyphs (struct it *, enum display_element_type);
@@ -1276,8 +1285,8 @@ window_box_height (struct window *w)
if (ml_row && ml_row->mode_line_p)
height -= ml_row->height;
else
- height -= estimate_mode_line_height (f,
- CURRENT_MODE_LINE_FACE_ID (w));
+ height -= estimate_mode_line_height
+ (f, CURRENT_MODE_LINE_ACTIVE_FACE_ID (w));
}
}
@@ -1682,7 +1691,7 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
= window_parameter (w, Qmode_line_format);
w->mode_line_height
- = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
+ = display_mode_line (w, CURRENT_MODE_LINE_ACTIVE_FACE_ID (w),
NILP (window_mode_line_format)
? BVAR (current_buffer, mode_line_format)
: window_mode_line_format);
@@ -1992,7 +2001,17 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
}
*x = top_x;
- *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
+ /* The condition below is a heuristic fix for the situation
+ where move_it_to stops just after finishing the display
+ of a fringe bitmap, which resets it.ascent to zero, and
+ thus causes Y to be offset by it.max_ascent. */
+ if (it.ascent == 0 && it.what == IT_IMAGE
+ && it.method != GET_FROM_IMAGE
+ && it.image_id < 0
+ && it.max_ascent > 0)
+ *y = max (top_y, window_top_y);
+ else
+ *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
*rtop = max (0, window_top_y - top_y);
*rbot = max (0, bottom_y - it.last_visible_y);
*rowh = max (0, (min (bottom_y, it.last_visible_y)
@@ -2020,7 +2039,13 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
RESTORE_IT (&it2, &it2, it2data);
move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
*x = it2.current_x;
- *y = it2.current_y + it2.max_ascent - it2.ascent;
+ if (it2.ascent == 0 && it2.what == IT_IMAGE
+ && it2.method != GET_FROM_IMAGE
+ && it2.image_id < 0
+ && it2.max_ascent > 0)
+ *y = it2.current_y;
+ else
+ *y = it2.current_y + it2.max_ascent - it2.ascent;
*rtop = max (0, -it2.current_y);
*rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
- it.last_visible_y));
@@ -3121,11 +3146,11 @@ CHECK_WINDOW_END (struct window *w)
will produce glyphs in that row.
BASE_FACE_ID is the id of a base face to use. It must be one of
- DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
+ DEFAULT_FACE_ID for normal text, MODE_LINE_ACTIVE_FACE_ID,
MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
- If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
+ If ROW is null and BASE_FACE_ID is equal to MODE_LINE_ACTIVE_FACE_ID,
MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
will be initialized to use the corresponding mode line glyph row of
the desired matrix of W. */
@@ -3171,7 +3196,7 @@ init_iterator (struct it *it, struct window *w,
appropriate. */
if (row == NULL)
{
- if (base_face_id == MODE_LINE_FACE_ID
+ if (base_face_id == MODE_LINE_ACTIVE_FACE_ID
|| base_face_id == MODE_LINE_INACTIVE_FACE_ID)
row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
else if (base_face_id == TAB_LINE_FACE_ID)
@@ -4288,12 +4313,17 @@ handle_fontified_prop (struct it *it)
struct buffer *obuf = current_buffer;
ptrdiff_t begv = BEGV, zv = ZV;
bool old_clip_changed = current_buffer->clip_changed;
+ bool saved_inhibit_flag = it->f->inhibit_clear_image_cache;
val = Vfontification_functions;
specbind (Qfontification_functions, Qnil);
eassert (it->end_charpos == ZV);
+ /* Don't allow Lisp that runs from 'fontification-functions'
+ clear our face and image caches behind our back. */
+ it->f->inhibit_clear_image_cache = true;
+
if (!CONSP (val) || EQ (XCAR (val), Qlambda))
safe_call1 (val, pos);
else
@@ -4327,6 +4357,7 @@ handle_fontified_prop (struct it *it)
}
}
+ it->f->inhibit_clear_image_cache = saved_inhibit_flag;
unbind_to (count, Qnil);
/* Fontification functions routinely call `save-restriction'.
@@ -5129,6 +5160,161 @@ setup_for_ellipsis (struct it *it, int len)
it->ellipsis_p = true;
}
+
+static Lisp_Object
+find_display_property (Lisp_Object disp, Lisp_Object prop)
+{
+ if (NILP (disp))
+ return Qnil;
+ /* We have a vector of display specs. */
+ if (VECTORP (disp))
+ {
+ for (ptrdiff_t i = 0; i < ASIZE (disp); i++)
+ {
+ Lisp_Object elem = AREF (disp, i);
+ if (CONSP (elem)
+ && CONSP (XCDR (elem))
+ && EQ (XCAR (elem), prop))
+ return XCAR (XCDR (elem));
+ }
+ return Qnil;
+ }
+ /* We have a list of display specs. */
+ else if (CONSP (disp)
+ && CONSP (XCAR (disp)))
+ {
+ while (!NILP (disp))
+ {
+ Lisp_Object elem = XCAR (disp);
+ if (CONSP (elem)
+ && CONSP (XCDR (elem))
+ && EQ (XCAR (elem), prop))
+ return XCAR (XCDR (elem));
+
+ /* Check that we have a proper list before going to the next
+ element. */
+ if (CONSP (XCDR (disp)))
+ disp = XCDR (disp);
+ else
+ disp = Qnil;
+ }
+ return Qnil;
+ }
+ /* A simple display spec. */
+ else if (CONSP (disp)
+ && CONSP (XCDR (disp))
+ && EQ (XCAR (disp), prop))
+ return XCAR (XCDR (disp));
+ else
+ return Qnil;
+}
+
+static
+Lisp_Object get_display_property (ptrdiff_t bufpos, Lisp_Object prop,
+ Lisp_Object object)
+{
+ return find_display_property (Fget_text_property (make_fixnum (bufpos),
+ Qdisplay, object),
+ prop);
+}
+
+static void
+display_min_width (struct it *it, ptrdiff_t bufpos,
+ Lisp_Object object, Lisp_Object width_spec)
+{
+ /* We're being called at the end of the `min-width' sequence,
+ probably. */
+ if (!NILP (it->min_width_property)
+ && !EQ (width_spec, it->min_width_property))
+ {
+ if (!it->glyph_row)
+ return;
+
+ /* When called from display_string (i.e., the mode line),
+ we're being called with a string as the object, and we
+ may be called with many sub-strings belonging to the same
+ :propertize run. */
+ if ((bufpos == 0
+ && !EQ (it->min_width_property,
+ get_display_property (0, Qmin_width, object)))
+ /* In a buffer -- check that we're really right after the
+ sequence of characters covered by this `min-width'. */
+ || (bufpos > BEGV
+ && EQ (it->min_width_property,
+ get_display_property (bufpos - 1, Qmin_width, object))))
+ {
+ Lisp_Object w = Qnil;
+ double width;
+#ifdef HAVE_WINDOW_SYSTEM
+ if (FRAME_WINDOW_P (it->f))
+ {
+ struct font *font = NULL;
+ struct face *face = FACE_FROM_ID (it->f, it->face_id);
+ font = face->font ? face->font : FRAME_FONT (it->f);
+ calc_pixel_width_or_height (&width, it,
+ XCAR (it->min_width_property),
+ font, true, NULL);
+ width -= it->current_x - it->min_width_start;
+ w = list1 (make_int (width));
+ }
+ else
+#endif
+ {
+ calc_pixel_width_or_height (&width, it,
+ XCAR (it->min_width_property),
+ NULL, true, NULL);
+ width -= (it->current_x - it->min_width_start) /
+ FRAME_COLUMN_WIDTH (it->f);
+ w = make_int (width);
+ }
+
+ /* Insert the stretch glyph. */
+ it->object = list3 (Qspace, QCwidth, w);
+ produce_stretch_glyph (it);
+ it->min_width_property = Qnil;
+ }
+ }
+
+ /* We're at the start of a `min-width' sequence -- record the
+ position and the property, so that we can later see if we're at
+ the end. */
+ if (CONSP (width_spec))
+ {
+ if (bufpos == BEGV
+ /* Mode line (see above). */
+ || (bufpos == 0
+ && !EQ (it->min_width_property,
+ get_display_property (0, Qmin_width, object)))
+ /* Buffer. */
+ || (bufpos > BEGV
+ && !EQ (width_spec,
+ get_display_property (bufpos - 1, Qmin_width, object))))
+ {
+ it->min_width_property = width_spec;
+ it->min_width_start = it->current_x;
+ }
+ }
+}
+
+DEFUN ("get-display-property", Fget_display_property,
+ Sget_display_property, 2, 4, 0,
+ doc: /* Get the value of the `display' property PROP at POSITION.
+If OBJECT, this should be a buffer or string where the property is
+fetched from. If omitted, OBJECT defaults to the current buffer.
+
+If PROPERTIES, look for value of PROP in PROPERTIES instead of the
+properties at POSITION. */)
+ (Lisp_Object position, Lisp_Object prop, Lisp_Object object,
+ Lisp_Object properties)
+{
+ if (NILP (properties))
+ properties = Fget_text_property (position, Qdisplay, object);
+ else
+ CHECK_LIST (properties);
+
+ return find_display_property (properties, prop);
+}
+
/***********************************************************************
@@ -5177,6 +5363,12 @@ handle_display_prop (struct it *it)
propval = get_char_property_and_overlay (make_fixnum (position->charpos),
Qdisplay, object, &overlay);
+
+ /* Handle min-width ends. */
+ if (!NILP (it->min_width_property)
+ && NILP (find_display_property (propval, Qmin_width)))
+ display_min_width (it, bufpos, object, Qnil);
+
if (NILP (propval))
return HANDLED_NORMALLY;
/* Now OVERLAY is the overlay that gave us this property, or nil
@@ -5238,6 +5430,7 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
&& !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
&& !EQ (XCAR (spec), Qleft_fringe)
&& !EQ (XCAR (spec), Qright_fringe)
+ && !EQ (XCAR (spec), Qmin_width)
&& !NILP (XCAR (spec)))
{
for (; CONSP (spec); spec = XCDR (spec))
@@ -5471,6 +5664,17 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
return 0;
}
+ /* Handle `(min-width (WIDTH))'. */
+ if (CONSP (spec)
+ && EQ (XCAR (spec), Qmin_width)
+ && CONSP (XCDR (spec))
+ && CONSP (XCAR (XCDR (spec))))
+ {
+ if (it)
+ display_min_width (it, bufpos, object, XCAR (XCDR (spec)));
+ return 0;
+ }
+
/* Handle `(slice X Y WIDTH HEIGHT)'. */
if (CONSP (spec)
&& EQ (XCAR (spec), Qslice))
@@ -5618,8 +5822,15 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
if (CONSP (XCDR (XCDR (spec))))
{
Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
- int face_id2 = lookup_derived_face (it->w, it->f, face_name,
- FRINGE_FACE_ID, false);
+ int face_id2;
+ /* Don't allow quitting from lookup_derived_face, for when
+ we are displaying a non-selected window, and the buffer's
+ point was temporarily moved to the window-point. */
+ ptrdiff_t count1 = SPECPDL_INDEX ();
+ specbind (Qinhibit_quit, Qt);
+ face_id2 = lookup_derived_face (it->w, it->f, face_name,
+ FRINGE_FACE_ID, false);
+ unbind_to (count1, Qnil);
if (face_id2 >= 0)
face_id = face_id2;
}
@@ -7174,6 +7385,7 @@ reseat_1 (struct it *it, struct text_pos pos, bool set_stop_p)
}
/* This make the information stored in it->cmp_it invalidate. */
it->cmp_it.id = -1;
+ it->min_width_property = Qnil;
}
@@ -7662,7 +7874,8 @@ get_next_display_element (struct it *it)
/* Merge `nobreak-space' into the current face. */
face_id = merge_faces (it->w, Qnobreak_space, 0,
it->face_id);
- XSETINT (it->ctl_chars[0], it->c);
+ XSETINT (it->ctl_chars[0],
+ nobreak_char_ascii_display ? ' ' : it->c);
ctl_len = 1;
goto display_control;
}
@@ -7675,7 +7888,8 @@ get_next_display_element (struct it *it)
/* Merge `nobreak-space' into the current face. */
face_id = merge_faces (it->w, Qnobreak_hyphen, 0,
it->face_id);
- XSETINT (it->ctl_chars[0], it->c);
+ XSETINT (it->ctl_chars[0],
+ nobreak_char_ascii_display ? '-' : it->c);
ctl_len = 1;
goto display_control;
}
@@ -10065,6 +10279,8 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
case MOVE_NEWLINE_OR_CR:
max_current_x = max (it->current_x, max_current_x);
+ if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
+ it->override_ascent = -1;
set_iterator_to_next (it, true);
it->continuation_lines_width = 0;
break;
@@ -10207,11 +10423,12 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
/* Move iterator IT backward by a specified y-distance DY, DY >= 0.
- If DY > 0, move IT backward at least that many pixels. DY = 0
- means move IT backward to the preceding line start or BEGV. This
- function may move over more than DY pixels if IT->current_y - DY
- ends up in the middle of a line; in this case IT->current_y will be
- set to the top of the line moved to. */
+ If DY > 0, move IT backward that many pixels.
+ DY = 0 means move IT backward to the preceding line start or to BEGV.
+ This function may move over less or more than DY pixels if
+ IT->current_y - DY ends up in the middle of a line; in this case
+ IT->current_y will be set to the top of the line either before or
+ after the exact pixel coordinate. */
void
move_it_vertically_backward (struct it *it, int dy)
@@ -10610,73 +10827,22 @@ in_display_vector_p (struct it *it)
&& it->dpvec + it->current.dpvec_index != it->dpend);
}
-DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
- doc: /* Return the size of the text of WINDOW's buffer in pixels.
-WINDOW must be a live window and defaults to the selected one. The
-return value is a cons of the maximum pixel-width of any text line
-and the pixel-height of all the text lines in the accessible portion
-of buffer text.
-
-This function exists to allow Lisp programs to adjust the dimensions
-of WINDOW to the buffer text it needs to display.
-
-The optional argument FROM, if non-nil, specifies the first text
-position to consider, and defaults to the minimum accessible position
-of the buffer. If FROM is t, it stands for the minimum accessible
-position that starts a non-empty line. TO, if non-nil, specifies the
-last text position and defaults to the maximum accessible position of
-the buffer. If TO is t, it stands for the maximum accessible position
-that ends a non-empty line.
-
-The optional argument X-LIMIT, if non-nil, specifies the maximum X
-coordinate beyond which the text should be ignored. It is therefore
-also the maximum width that the function can return. X-LIMIT nil or
-omitted means to use the pixel-width of WINDOW's body. This default
-means text of truncated lines wider than the window will be ignored;
-specify a large value for X-LIMIT if lines are truncated and you need
-to account for the truncated text. Use nil for X-LIMIT if you want to
-know how high WINDOW should become in order to fit all of its buffer's
-text with the width of WINDOW unaltered. Use the maximum width WINDOW
-may assume if you intend to change WINDOW's width. Since calculating
-the width of long lines can take some time, it's always a good idea to
-make this argument as small as possible; in particular, if the buffer
-contains long lines that shall be truncated anyway.
-
-The optional argument Y-LIMIT, if non-nil, specifies the maximum Y
-coordinate beyond which the text is to be ignored; it is therefore
-also the maximum height that the function can return (excluding the
-height of the mode- or header-line, if any). Y-LIMIT nil or omitted
-means consider all of the accessible portion of buffer text up to the
-position specified by TO. Since calculating the text height of a
-large buffer can take some time, it makes sense to specify this
-argument if the size of the buffer is large or unknown.
-
-Optional argument MODE-AND-HEADER-LINE nil or omitted means do not
-include the height of the mode- or header-line of WINDOW in the return
-value. If it is either the symbol `mode-line' or `header-line', include
-only the height of that line, if present, in the return value. If t,
-include the height of both, if present, in the return value. */)
- (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit,
- Lisp_Object y_limit, Lisp_Object mode_and_header_line)
+/* This is like Fwindow_text_pixel_size but assumes that WINDOW's buffer
+ is the current buffer. Fbuffer_text_pixel_size calls it after it has
+ set WINDOW's buffer to the buffer specified by its BUFFER_OR_NAME
+ argument. */
+static Lisp_Object
+window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to,
+ Lisp_Object x_limit, Lisp_Object y_limit,
+ Lisp_Object mode_lines, Lisp_Object ignore_line_at_end)
{
struct window *w = decode_live_window (window);
- Lisp_Object buffer = w->contents;
- struct buffer *b;
struct it it;
- struct buffer *old_b = NULL;
ptrdiff_t start, end, bpos;
struct text_pos startp;
void *itdata = NULL;
int c, max_x = 0, max_y = 0, x = 0, y = 0;
-
- CHECK_BUFFER (buffer);
- b = XBUFFER (buffer);
-
- if (b != current_buffer)
- {
- old_b = current_buffer;
- set_buffer_internal (b);
- }
+ int doff = 0;
if (NILP (from))
{
@@ -10736,8 +10902,10 @@ include the height of both, if present, in the return value. */)
else
end = clip_to_bounds (start, fix_position (to), ZV);
- if (!NILP (x_limit) && RANGED_FIXNUMP (0, x_limit, INT_MAX))
+ if (RANGED_FIXNUMP (0, x_limit, INT_MAX))
max_x = XFIXNUM (x_limit);
+ else if (!NILP (x_limit))
+ max_x = INT_MAX;
if (NILP (y_limit))
max_y = INT_MAX;
@@ -10803,8 +10971,16 @@ include the height of both, if present, in the return value. */)
if (IT_CHARPOS (it) == end)
{
x += it.pixel_width;
- it.max_ascent = max (it.max_ascent, it.ascent);
- it.max_descent = max (it.max_descent, it.descent);
+
+ /* DTRT if ignore_line_at_end is t. */
+ if (!NILP (ignore_line_at_end))
+ doff = (max (it.max_ascent, it.ascent)
+ + max (it.max_descent, it.descent));
+ else
+ {
+ it.max_ascent = max (it.max_ascent, it.ascent);
+ it.max_descent = max (it.max_descent, it.descent);
+ }
}
}
else
@@ -10825,35 +11001,185 @@ include the height of both, if present, in the return value. */)
/* Subtract height of header-line and tab-line which was counted
automatically by start_display. */
- y = it.current_y + it.max_ascent + it.max_descent
- - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
+ if (!NILP (ignore_line_at_end))
+ y = (it.current_y + doff
+ - WINDOW_TAB_LINE_HEIGHT (w)
+ - WINDOW_HEADER_LINE_HEIGHT (w));
+ else
+ y = (it.current_y + it.max_ascent + it.max_descent + doff
+ - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w));
+
/* Don't return more than Y-LIMIT. */
if (y > max_y)
y = max_y;
- if (EQ (mode_and_header_line, Qtab_line)
- || EQ (mode_and_header_line, Qt))
- /* Re-add height of tab-line as requested. */
- y = y + WINDOW_TAB_LINE_HEIGHT (w);
+ if ((EQ (mode_lines, Qtab_line) || EQ (mode_lines, Qt))
+ && window_wants_tab_line (w))
+ /* Add height of tab-line as requested. */
+ {
+ Lisp_Object window_tab_line_format
+ = window_parameter (w, Qtab_line_format);
- if (EQ (mode_and_header_line, Qheader_line)
- || EQ (mode_and_header_line, Qt))
- /* Re-add height of header-line as requested. */
- y = y + WINDOW_HEADER_LINE_HEIGHT (w);
+ y = y + display_mode_line (w, TAB_LINE_FACE_ID,
+ NILP (window_tab_line_format)
+ ? BVAR (current_buffer, tab_line_format)
+ : window_tab_line_format);
+ }
+
+ if ((EQ (mode_lines, Qheader_line) || EQ (mode_lines, Qt))
+ && window_wants_header_line (w))
+ {
+ Lisp_Object window_header_line_format
+ = window_parameter (w, Qheader_line_format);
- if (EQ (mode_and_header_line, Qmode_line)
- || EQ (mode_and_header_line, Qt))
- /* Add height of mode-line as requested. */
- y = y + WINDOW_MODE_LINE_HEIGHT (w);
+ y = y + display_mode_line (w, HEADER_LINE_FACE_ID,
+ NILP (window_header_line_format)
+ ? BVAR (current_buffer, header_line_format)
+ : window_header_line_format);
+ }
+
+ if ((EQ (mode_lines, Qmode_line) || EQ (mode_lines, Qt))
+ && window_wants_mode_line (w))
+ {
+ Lisp_Object window_mode_line_format
+ = window_parameter (w, Qmode_line_format);
+
+ y = y + display_mode_line (w, CURRENT_MODE_LINE_ACTIVE_FACE_ID (w),
+ NILP (window_mode_line_format)
+ ? BVAR (current_buffer, mode_line_format)
+ : window_mode_line_format);
+ }
bidi_unshelve_cache (itdata, false);
+ return Fcons (make_fixnum (x - start_x), make_fixnum (y));
+}
+
+DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 7, 0,
+ doc: /* Return the size of the text of WINDOW's buffer in pixels.
+WINDOW must be a live window and defaults to the selected one. The
+return value is a cons of the maximum pixel-width of any text line
+and the pixel-height of all the text lines in the accessible portion
+of buffer text.
+
+This function exists to allow Lisp programs to adjust the dimensions
+of WINDOW to the buffer text it needs to display.
+
+The optional argument FROM, if non-nil, specifies the first text
+position to consider, and defaults to the minimum accessible position
+of the buffer. If FROM is t, it stands for the minimum accessible
+position that starts a non-empty line. TO, if non-nil, specifies the
+last text position and defaults to the maximum accessible position of
+the buffer. If TO is t, it stands for the maximum accessible position
+that ends a non-empty line.
+
+The optional argument X-LIMIT, if non-nil, specifies the maximum X
+coordinate beyond which the text should be ignored. It is therefore
+also the maximum width that the function can return. X-LIMIT nil or
+omitted means to use the pixel-width of WINDOW's body. This default
+means text of truncated lines wider than the window will be ignored;
+specify a non-nil value for X-LIMIT if lines are truncated and you need
+to account for the truncated text.
+
+Use nil for X-LIMIT if you want to know how high WINDOW should become in
+order to fit all of its buffer's text with the width of WINDOW
+unaltered. Use the maximum width WINDOW may assume if you intend to
+change WINDOW's width. Use t for the maximum possible value. Since
+calculating the width of long lines can take some time, it's always a
+good idea to make this argument as small as possible; in particular, if
+the buffer contains long lines that shall be truncated anyway.
+
+The optional argument Y-LIMIT, if non-nil, specifies the maximum Y
+coordinate beyond which the text is to be ignored; it is therefore
+also the maximum height that the function can return (excluding the
+height of the mode- or header-line, if any). Y-LIMIT nil or omitted
+means consider all of the accessible portion of buffer text up to the
+position specified by TO. Since calculating the text height of a
+large buffer can take some time, it makes sense to specify this
+argument if the size of the buffer is large or unknown.
+
+Optional argument MODE-LINES nil or omitted means do not include the
+height of the mode-, tab- or header-line of WINDOW in the return value.
+If it is the symbol `mode-line', 'tab-line' or `header-line', include
+only the height of that line, if present, in the return value. If t,
+include the height of any of these, if present, in the return value.
+
+IGNORE-LINE-AT-END, if non-nil, means to not add the height of the
+screen line that includes TO to the returned height of the text. */)
+ (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit,
+ Lisp_Object y_limit, Lisp_Object mode_lines, Lisp_Object ignore_line_at_end)
+{
+ struct window *w = decode_live_window (window);
+ struct buffer *b = XBUFFER (w->contents);
+ struct buffer *old_b = NULL;
+ Lisp_Object value;
+
+ if (b != current_buffer)
+ {
+ old_b = current_buffer;
+ set_buffer_internal_1 (b);
+ }
+
+ value = window_text_pixel_size (window, from, to, x_limit, y_limit, mode_lines,
+ ignore_line_at_end);
+
if (old_b)
- set_buffer_internal (old_b);
+ set_buffer_internal_1 (old_b);
- return Fcons (make_fixnum (x - start_x), make_fixnum (y));
+ return value;
+}
+
+DEFUN ("buffer-text-pixel-size", Fbuffer_text_pixel_size, Sbuffer_text_pixel_size, 0, 4, 0,
+ doc: /* Return size of whole text of BUFFER-OR-NAME in WINDOW.
+BUFFER-OR-NAME must specify a live buffer or the name of a live buffer
+and defaults to the current buffer. WINDOW must be a live window and
+defaults to the selected one. The return value is a cons of the maximum
+pixel-width of any text line and the pixel-height of all the text lines
+of the buffer specified by BUFFER-OR-NAME.
+
+The optional arguments X-LIMIT and Y-LIMIT have the same meaning as with
+`window-text-pixel-size'.
+
+Do not use this function if the buffer specified by BUFFER-OR-NAME is
+already displayed in WINDOW. `window-text-pixel-size' is cheaper in
+that case because it does not have to temporarily show that buffer in
+WINDOW. */)
+ (Lisp_Object buffer_or_name, Lisp_Object window, Lisp_Object x_limit,
+ Lisp_Object y_limit)
+{
+ struct window *w = decode_live_window (window);
+ struct buffer *b = (NILP (buffer_or_name)
+ ? current_buffer
+ : XBUFFER (Fget_buffer (buffer_or_name)));
+ Lisp_Object buffer, value;
+ ptrdiff_t count = SPECPDL_INDEX ();
+
+ XSETBUFFER (buffer, b);
+
+ /* The unwind form of with_echo_area_buffer is what we need here to
+ make WINDOW temporarily show our buffer. */
+ /* FIXME: Can we move this into the `if (!EQ (buffer, w->contents))`? */
+ record_unwind_protect (unwind_with_echo_area_buffer,
+ with_echo_area_buffer_unwind_data (w));
+
+ set_buffer_internal_1 (b);
+
+ if (!EQ (buffer, w->contents))
+ {
+ wset_buffer (w, buffer);
+ set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
+ set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE);
+ }
+
+ value = window_text_pixel_size (window, Qnil, Qnil, x_limit, y_limit, Qnil,
+ Qnil);
+
+ unbind_to (count, Qnil);
+
+ return value;
}
+
DEFUN ("display--line-is-continued-p", Fdisplay__line_is_continued_p,
Sdisplay__line_is_continued_p, 0, 0, 0,
doc: /* Return non-nil if the current screen line is continued on display. */)
@@ -13759,7 +14085,7 @@ get_tab_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
false for button release. MODIFIERS is event modifiers for button
release. */
-void
+Lisp_Object
handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
int modifiers)
{
@@ -13773,16 +14099,13 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
frame_to_window_pixel_xy (w, &x, &y);
ts = get_tab_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx, &close_p);
- if (ts == -1
- /* If the button is released on a tab other than the one where
- it was pressed, don't generate the tab-bar button click event. */
- || (ts != 0 && !down_p))
- return;
+ if (ts == -1)
+ return Fcons (Qtab_bar, Qnil);
/* If item is disabled, do nothing. */
enabled_p = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_ENABLED_P);
if (NILP (enabled_p))
- return;
+ return Qnil;
if (down_p)
{
@@ -13793,24 +14116,24 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
}
else
{
- Lisp_Object key, frame;
- struct input_event event;
- EVENT_INIT (event);
-
/* Show item in released state. */
if (!NILP (Vmouse_highlight))
show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
-
- key = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_KEY);
-
- XSETFRAME (frame, f);
- event.kind = TAB_BAR_EVENT;
- event.frame_or_window = frame;
- event.arg = key;
- event.modifiers = close_p ? ctrl_modifier | modifiers : modifiers;
- kbd_buffer_store_event (&event);
f->last_tab_bar_item = -1;
}
+
+ Lisp_Object caption =
+ Fcopy_sequence (AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_CAPTION));
+
+ AUTO_LIST2 (props, Qmenu_item,
+ list3 (AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_KEY),
+ AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_BINDING),
+ close_p ? Qt : Qnil));
+
+ Fadd_text_properties (make_fixnum (0), make_fixnum (SCHARS (caption)),
+ props, caption);
+
+ return Fcons (Qtab_bar, Fcons (caption, make_fixnum (0)));
}
@@ -13856,15 +14179,18 @@ note_tab_bar_highlight (struct frame *f, int x, int y)
clear_mouse_face (hlinfo);
bool mouse_down_p = false;
-#ifndef HAVE_NS
- /* Mouse is down, but on different tab-bar item? */
+ /* Mouse is down, but on different tab-bar item? Or alternatively,
+ the mouse might've been pressed somewhere we don't know about,
+ and then have moved onto the tab bar. In this case,
+ last_tab_bar_item is -1, so we DTRT and behave like other
+ programs by displaying the item as sunken. */
Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
mouse_down_p = (gui_mouse_grabbed (dpyinfo)
&& f == dpyinfo->last_mouse_frame);
- if (mouse_down_p && f->last_tab_bar_item != prop_idx)
+ if (mouse_down_p && f->last_tab_bar_item != prop_idx
+ && f->last_tab_bar_item != -1)
return;
-#endif
draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
/* If tab-bar item is not enabled, don't highlight it. */
@@ -13908,7 +14234,7 @@ note_tab_bar_highlight (struct frame *f, int x, int y)
/* Find the tab-bar item at X coordinate and return its information. */
static Lisp_Object
-tty_get_tab_bar_item (struct frame *f, int x, int *idx, ptrdiff_t *end)
+tty_get_tab_bar_item (struct frame *f, int x, int *prop_idx, bool *close_p)
{
ptrdiff_t clen = 0;
@@ -13921,8 +14247,11 @@ tty_get_tab_bar_item (struct frame *f, int x, int *idx, ptrdiff_t *end)
clen += SCHARS (caption);
if (x < clen)
{
- *idx = i;
- *end = clen;
+ *prop_idx = i;
+ *close_p = !NILP (Fget_text_property (make_fixnum (SCHARS (caption)
+ - (clen - x)),
+ Qclose_tab,
+ caption));
return caption;
}
}
@@ -13934,61 +14263,45 @@ tty_get_tab_bar_item (struct frame *f, int x, int *idx, ptrdiff_t *end)
structure, store it in keyboard queue, and return true; otherwise
return false. MODIFIERS are event modifiers for generating the tab
release event. */
-bool
+Lisp_Object
tty_handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
struct input_event *event)
{
/* Did they click on the tab bar? */
if (y < FRAME_MENU_BAR_LINES (f)
|| y >= FRAME_MENU_BAR_LINES (f) + FRAME_TAB_BAR_LINES (f))
- return false;
+ return Qnil;
/* Find the tab-bar item where the X,Y coordinates belong. */
int prop_idx;
- ptrdiff_t clen;
- Lisp_Object caption = tty_get_tab_bar_item (f, x, &prop_idx, &clen);
+ bool close_p;
+ Lisp_Object caption = tty_get_tab_bar_item (f, x, &prop_idx, &close_p);
if (NILP (caption))
- return false;
+ return Qnil;
if (NILP (AREF (f->tab_bar_items,
prop_idx * TAB_BAR_ITEM_NSLOTS + TAB_BAR_ITEM_ENABLED_P)))
- return false;
+ return Qnil;
if (down_p)
f->last_tab_bar_item = prop_idx;
else
- {
- /* Force reset of up_modifier bit from the event modifiers. */
- if (event->modifiers & up_modifier)
- event->modifiers &= ~up_modifier;
-
- /* Generate a TAB_BAR_EVENT event. */
- Lisp_Object frame;
- Lisp_Object key = AREF (f->tab_bar_items,
- prop_idx * TAB_BAR_ITEM_NSLOTS
- + TAB_BAR_ITEM_KEY);
- /* Kludge alert: we assume the last two characters of a tab
- label are " x", and treat clicks on those 2 characters as a
- Close Tab command. */
- eassert (STRINGP (caption));
- int lastc = SSDATA (caption)[SCHARS (caption) - 1];
- bool close_p = false;
- if ((x == clen - 1 || (clen > 1 && x == clen - 2)) && lastc == 'x')
- close_p = true;
-
- event->code = 0;
- XSETFRAME (frame, f);
- event->kind = TAB_BAR_EVENT;
- event->frame_or_window = frame;
- event->arg = key;
- if (close_p)
- event->modifiers |= ctrl_modifier;
- kbd_buffer_store_event (event);
- f->last_tab_bar_item = -1;
- }
+ f->last_tab_bar_item = -1;
- return true;
+ caption = Fcopy_sequence (caption);
+
+ AUTO_LIST2 (props, Qmenu_item,
+ list3 (AREF (f->tab_bar_items, prop_idx * TAB_BAR_ITEM_NSLOTS
+ + TAB_BAR_ITEM_KEY),
+ AREF (f->tab_bar_items, prop_idx * TAB_BAR_ITEM_NSLOTS
+ + TAB_BAR_ITEM_BINDING),
+ close_p ? Qt : Qnil));
+
+ Fadd_text_properties (make_fixnum (0), make_fixnum (SCHARS (caption)),
+ props, caption);
+
+ return Fcons (Qtab_bar, Fcons (caption, make_fixnum (0)));
}
@@ -15622,13 +15935,18 @@ redisplay_internal (void)
if (!fr->glyphs_initialized_p)
return;
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
+#if defined (USE_X_TOOLKIT) || (defined (USE_GTK) && !defined (HAVE_PGTK)) || defined (HAVE_NS)
if (popup_activated ())
{
return;
}
#endif
+#if defined (HAVE_HAIKU)
+ if (popup_activated_p)
+ return;
+#endif
+
/* I don't think this happens but let's be paranoid. */
if (redisplaying_p)
return;
@@ -16077,12 +16395,13 @@ redisplay_internal (void)
if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
{
- /* Don't allow freeing images for this frame as long
- as the frame's update wasn't completed. This
- prevents crashes when some Lisp that runs from
- the various hooks or font-lock decides to clear
- the frame's image cache, when the images in that
- cache are referenced by the desired matrix. */
+ /* Don't allow freeing images and faces for this
+ frame as long as the frame's update wasn't
+ completed. This prevents crashes when some Lisp
+ that runs from the various hooks or font-lock
+ decides to clear the frame's image cache and face
+ cache, when the images and faces in those caches
+ are referenced by the desired matrix. */
f->inhibit_clear_image_cache = true;
redisplay_windows (FRAME_ROOT_WINDOW (f));
}
@@ -17409,9 +17728,9 @@ cursor_row_fully_visible_p (struct window *w, bool force_p,
enum
{
- SCROLLING_SUCCESS,
- SCROLLING_FAILED,
- SCROLLING_NEED_LARGER_MATRICES
+ SCROLLING_SUCCESS = 1,
+ SCROLLING_FAILED = 0,
+ SCROLLING_NEED_LARGER_MATRICES = -1
};
/* If scroll-conservatively is more than this, never recenter.
@@ -17785,13 +18104,14 @@ compute_window_start_on_continuation_line (struct window *w)
row, DEFAULT_FACE_ID);
reseat_at_previous_visible_line_start (&it);
- /* If the line start is "too far" away from the window start,
- say it takes too much time to compute a new window start.
- Also, give up if the line start is after point, as in that
- case point will not be visible with any window start we
+ /* Give up (by not using the code in the block below) and say it
+ takes too much time to compute a new window start, if the
+ line start is "too far" away from the window start. Also,
+ give up if the line start is after point, as in that case
+ point will not be visible with any window start we
compute. */
if (IT_CHARPOS (it) <= PT
- || (CHARPOS (start_pos) - IT_CHARPOS (it)
+ && (CHARPOS (start_pos) - IT_CHARPOS (it)
/* PXW: Do we need upper bounds here? */
< WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w)))
{
@@ -24480,7 +24800,7 @@ See also `bidi-paragraph-direction'. */)
DEFUN ("bidi-find-overridden-directionality",
Fbidi_find_overridden_directionality,
- Sbidi_find_overridden_directionality, 2, 3, 0,
+ Sbidi_find_overridden_directionality, 3, 4, 0,
doc: /* Return position between FROM and TO where directionality was overridden.
This function returns the first character position in the specified
@@ -24499,12 +24819,18 @@ a buffer is preferable when the buffer is displayed in some window,
because this function will then be able to correctly account for
window-specific overlays, which can affect the results.
+Optional argument BASE-DIR specifies the base paragraph directory
+of the text. It should be a symbol, either `left-to-right'
+or `right-to-left', and defaults to `left-to-right'.
+
Strong directional characters `L', `R', and `AL' can have their
intrinsic directionality overridden by directional override
-control characters RLO (u+202e) and LRO (u+202d). See the
-function `get-char-code-property' for a way to inquire about
+control characters RLO (u+202E) and LRO (u+202D). They can also
+have their directionality affected by other formatting control
+characters: LRE (u+202A), RLE (u+202B), LRI (u+2066), and RLI (u+2067).
+See the function `get-char-code-property' for a way to inquire about
the `bidi-class' property of a character. */)
- (Lisp_Object from, Lisp_Object to, Lisp_Object object)
+ (Lisp_Object from, Lisp_Object to, Lisp_Object object, Lisp_Object base_dir)
{
struct buffer *buf = current_buffer;
struct buffer *old = buf;
@@ -24601,10 +24927,9 @@ the `bidi-class' property of a character. */)
}
ptrdiff_t found;
+ bidi_dir_t bdir = EQ (base_dir, Qright_to_left) ? R2L : L2R;
do {
- /* For the purposes of this function, the actual base direction of
- the paragraph doesn't matter, so just set it to L2R. */
- bidi_paragraph_init (L2R, &itb, false);
+ bidi_paragraph_init (bdir, &itb, false);
while ((found = bidi_find_first_overridden (&itb)) < from_pos)
;
} while (found == ZV && itb.ch == '\n' && itb.charpos < to_pos);
@@ -25203,6 +25528,11 @@ display_menu_bar (struct window *w)
if (FRAME_W32_P (f))
return;
#endif
+#if defined (HAVE_PGTK)
+ if (FRAME_PGTK_P (f))
+ return;
+#endif
+
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
if (FRAME_X_P (f))
return;
@@ -25213,6 +25543,11 @@ display_menu_bar (struct window *w)
return;
#endif /* HAVE_NS */
+#ifdef HAVE_HAIKU
+ if (FRAME_HAIKU_P (f))
+ return;
+#endif /* HAVE_HAIKU */
+
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
eassert (!FRAME_WINDOW_P (f));
init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
@@ -25513,7 +25848,8 @@ display_mode_lines (struct window *w)
struct window *sel_w = XWINDOW (old_selected_window);
/* Select mode line face based on the real selected window. */
- display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
+ display_mode_line (w,
+ CURRENT_MODE_LINE_ACTIVE_FACE_ID_3 (sel_w, sel_w, w),
NILP (window_mode_line_format)
? BVAR (current_buffer, mode_line_format)
: window_mode_line_format);
@@ -25552,11 +25888,11 @@ display_mode_lines (struct window *w)
}
-/* Display mode or header/tab line of window W. FACE_ID specifies which
- line to display; it is either MODE_LINE_FACE_ID, HEADER_LINE_FACE_ID or
- TAB_LINE_FACE_ID. FORMAT is the mode/header/tab line format to
- display. Value is the pixel height of the mode/header/tab line
- displayed. */
+/* Display mode or header/tab line of window W. FACE_ID specifies
+ which line to display; it is either MODE_LINE_ACTIVE_FACE_ID,
+ HEADER_LINE_FACE_ID or TAB_LINE_FACE_ID. FORMAT is the
+ mode/header/tab line format to display. Value is the pixel height
+ of the mode/header/tab line displayed. */
static int
display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
@@ -25595,7 +25931,8 @@ display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
push_kboard (FRAME_KBOARD (it.f));
record_unwind_save_match_data ();
- if (NILP (Vmode_line_compact))
+ if (NILP (Vmode_line_compact)
+ || face_id == HEADER_LINE_FACE_ID || face_id == TAB_LINE_FACE_ID)
{
mode_line_target = MODE_LINE_DISPLAY;
display_mode_element (&it, 0, 0, 0, format, Qnil, false);
@@ -26348,8 +26685,8 @@ are the selected window and the WINDOW's buffer). */)
face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
: EQ (face, Qt) ? (EQ (window, selected_window)
- ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
- : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
+ ? MODE_LINE_ACTIVE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
+ : EQ (face, Qmode_line_active) ? MODE_LINE_ACTIVE_FACE_ID
: EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
: EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
: EQ (face, Qtab_line) ? TAB_LINE_FACE_ID
@@ -28131,6 +28468,19 @@ fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
s->font = s->face->font;
}
+ if (s->hl == DRAW_MOUSE_FACE
+ || (s->hl == DRAW_CURSOR && cursor_in_mouse_face_p (s->w)))
+ {
+ int c = COMPOSITION_GLYPH (s->cmp, 0);
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (s->f);
+ s->face = FACE_FROM_ID_OR_NULL (s->f, hlinfo->mouse_face_face_id);
+ if (!s->face)
+ s->face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+
+ s->face = FACE_FROM_ID (s->f, FACE_FOR_CHAR (s->f, s->face, c, -1, Qnil));
+ prepare_face_for_display (s->f, s->face);
+ }
+
/* All glyph strings for the same composition has the same width,
i.e. the width set for the first component of the composition. */
s->width = s->first_glyph->pixel_width;
@@ -28167,7 +28517,17 @@ fill_gstring_glyph_string (struct glyph_string *s, int face_id,
s->cmp_id = glyph->u.cmp.id;
s->cmp_from = glyph->slice.cmp.from;
s->cmp_to = glyph->slice.cmp.to + 1;
- s->face = FACE_FROM_ID (s->f, face_id);
+ if (s->hl == DRAW_MOUSE_FACE
+ || (s->hl == DRAW_CURSOR && cursor_in_mouse_face_p (s->w)))
+ {
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (s->f);
+ s->face = FACE_FROM_ID_OR_NULL (s->f, hlinfo->mouse_face_face_id);
+ if (!s->face)
+ s->face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+ prepare_face_for_display (s->f, s->face);
+ }
+ else
+ s->face = FACE_FROM_ID (s->f, face_id);
lgstring = composition_gstring_from_id (s->cmp_id);
s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
/* The width of a composition glyph string is the sum of the
@@ -28223,6 +28583,15 @@ fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
voffset = glyph->voffset;
s->face = FACE_FROM_ID (s->f, face_id);
s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
+ if (s->hl == DRAW_MOUSE_FACE
+ || (s->hl == DRAW_CURSOR && cursor_in_mouse_face_p (s->w)))
+ {
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (s->f);
+ s->face = FACE_FROM_ID_OR_NULL (s->f, hlinfo->mouse_face_face_id);
+ if (!s->face)
+ s->face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+ prepare_face_for_display (s->f, s->face);
+ }
s->nchars = 1;
s->width = glyph->pixel_width;
glyph++;
@@ -28286,6 +28655,19 @@ fill_glyph_string (struct glyph_string *s, int face_id,
s->font = s->face->font;
+ if (s->hl == DRAW_MOUSE_FACE
+ || (s->hl == DRAW_CURSOR && cursor_in_mouse_face_p (s->w)))
+ {
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (s->f);
+ s->face = FACE_FROM_ID_OR_NULL (s->f, hlinfo->mouse_face_face_id);
+ if (!s->face)
+ s->face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+ s->face
+ = FACE_FROM_ID (s->f, FACE_FOR_CHAR (s->f, s->face,
+ s->first_glyph->u.ch, -1, Qnil));
+ prepare_face_for_display (s->f, s->face);
+ }
+
/* If the specified font could not be loaded, use the frame's font,
but record the fact that we couldn't load it in
S->font_not_found_p so that we can draw rectangles for the
@@ -28315,6 +28697,15 @@ fill_image_glyph_string (struct glyph_string *s)
s->slice = s->first_glyph->slice.img;
s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
s->font = s->face->font;
+ if (s->hl == DRAW_MOUSE_FACE
+ || (s->hl == DRAW_CURSOR && cursor_in_mouse_face_p (s->w)))
+ {
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (s->f);
+ s->face = FACE_FROM_ID_OR_NULL (s->f, hlinfo->mouse_face_face_id);
+ if (!s->face)
+ s->face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+ prepare_face_for_display (s->f, s->face);
+ }
s->width = s->first_glyph->pixel_width;
/* Adjust base line for subscript/superscript text. */
@@ -28329,9 +28720,18 @@ fill_xwidget_glyph_string (struct glyph_string *s)
eassert (s->first_glyph->type == XWIDGET_GLYPH);
s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
s->font = s->face->font;
+ if (s->hl == DRAW_MOUSE_FACE
+ || (s->hl == DRAW_CURSOR && cursor_in_mouse_face_p (s->w)))
+ {
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (s->f);
+ s->face = FACE_FROM_ID_OR_NULL (s->f, hlinfo->mouse_face_face_id);
+ if (!s->face)
+ s->face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+ prepare_face_for_display (s->f, s->face);
+ }
s->width = s->first_glyph->pixel_width;
s->ybase += s->first_glyph->voffset;
- s->xwidget = s->first_glyph->u.xwidget;
+ s->xwidget = xwidget_from_id (s->first_glyph->u.xwidget);
}
#endif
/* Fill glyph string S from a sequence of stretch glyphs.
@@ -28354,6 +28754,15 @@ fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
face_id = glyph->face_id;
s->face = FACE_FROM_ID (s->f, face_id);
s->font = s->face->font;
+ if (s->hl == DRAW_MOUSE_FACE
+ || (s->hl == DRAW_CURSOR && cursor_in_mouse_face_p (s->w)))
+ {
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (s->f);
+ s->face = FACE_FROM_ID_OR_NULL (s->f, hlinfo->mouse_face_face_id);
+ if (!s->face)
+ s->face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+ prepare_face_for_display (s->f, s->face);
+ }
s->width = glyph->pixel_width;
s->nchars = 1;
voffset = glyph->voffset;
@@ -28601,7 +29010,12 @@ right_overwriting (struct glyph_string *s)
/* Set background width of glyph string S. START is the index of the
first glyph following S. LAST_X is the right-most x-position + 1
- in the drawing area. */
+ in the drawing area.
+
+ If S->hl is DRAW_CURSOR, S->f is a window system frame, and the
+ cursor in S's window is currently inside mouse face, also update
+ S->width to take into account potentially differing :box
+ properties between the original face and the mouse face. */
static void
set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
@@ -28623,7 +29037,27 @@ set_glyph_string_background_width (struct glyph_string *s, int start, int last_x
if (s->extends_to_end_of_line_p)
s->background_width = last_x - s->x + 1;
else
- s->background_width = s->width;
+ {
+ s->background_width = s->width;
+#ifdef HAVE_WINDOW_SYSTEM
+ if (FRAME_WINDOW_P (s->f)
+ && s->hl == DRAW_CURSOR
+ && cursor_in_mouse_face_p (s->w))
+ {
+ /* Adjust the background width of the glyph string, because
+ if the glyph's face has the :box attribute, its
+ pixel_width might be different when it's displayed in the
+ mouse-face, if that also has the :box attribute. */
+ struct glyph *g = s->first_glyph;
+ struct face *regular_face = FACE_FROM_ID (s->f, g->face_id);
+ s->background_width +=
+ adjust_glyph_width_for_mouse_face (g, s->row, s->w,
+ regular_face, s->face);
+ /* S->width is probably worth adjusting here as well. */
+ s->width = s->background_width;
+ }
+#endif
+ }
}
@@ -29172,7 +29606,6 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
for (s = head; s; s = s->next)
FRAME_RIF (f)->draw_glyph_string (s);
-#ifndef HAVE_NS
/* When focus a sole frame and move horizontally, this clears on_p
causing a failure to erase prev cursor position. */
if (area == TEXT_AREA
@@ -29191,7 +29624,6 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
row->y, MATRIX_ROW_BOTTOM_Y (row));
}
-#endif
/* Value is the x-position up to which drawn, relative to AREA of W.
This doesn't include parts drawn because of overhangs. */
@@ -29524,6 +29956,8 @@ produce_image_glyph (struct it *it)
if (face->box != FACE_NO_BOX)
{
+ /* If you change the logic here, please change it in
+ get_cursor_offset_for_mouse_face as well. */
if (face->box_horizontal_line_width > 0)
{
if (slice.y == 0)
@@ -29700,7 +30134,7 @@ produce_xwidget_glyph (struct it *it)
glyph->padding_p = 0;
glyph->glyph_not_available_p = 0;
glyph->face_id = it->face_id;
- glyph->u.xwidget = it->xwidget;
+ glyph->u.xwidget = it->xwidget->xwidget_id;
glyph->font_type = FONT_TYPE_UNKNOWN;
if (it->bidi_p)
{
@@ -29812,7 +30246,7 @@ append_stretch_glyph (struct it *it, Lisp_Object object,
#endif /* HAVE_WINDOW_SYSTEM */
/* Produce a stretch glyph for iterator IT. IT->object is the value
- of the glyph property displayed. The value must be a list
+ of the display property. The value must be a list of the form
`(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
being recognized:
@@ -29822,7 +30256,7 @@ append_stretch_glyph (struct it *it, Lisp_Object object,
2. `:relative-width FACTOR' specifies that the width of the stretch
should be computed from the width of the first character having the
- `glyph' property, and should be FACTOR times that width.
+ `display' property, and should be FACTOR times that width.
3. `:align-to HPOS' specifies that the space should be wide enough
to reach HPOS, a value in canonical character units.
@@ -29834,7 +30268,7 @@ append_stretch_glyph (struct it *it, Lisp_Object object,
5. `:relative-height FACTOR' specifies that the height of the
stretch should be FACTOR times the height of the characters having
- the glyph property.
+ the display property.
Either none or exactly one of 4 or 5 must be present.
@@ -29855,10 +30289,11 @@ produce_stretch_glyph (struct it *it)
#ifdef HAVE_WINDOW_SYSTEM
int ascent = 0;
bool zero_height_ok_p = false;
+ struct face *face = NULL; /* shut up GCC's -Wmaybe-uninitialized */
if (FRAME_WINDOW_P (it->f))
{
- struct face *face = FACE_FROM_ID (it->f, it->face_id);
+ face = FACE_FROM_ID (it->f, it->face_id);
font = face->font ? face->font : FRAME_FONT (it->f);
prepare_face_for_display (it->f, face);
}
@@ -29879,14 +30314,28 @@ produce_stretch_glyph (struct it *it)
else if (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0)
{
/* Relative width `:relative-width FACTOR' specified and valid.
- Compute the width of the characters having the `glyph'
+ Compute the width of the characters having this `display'
property. */
struct it it2;
- unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
+ Lisp_Object object =
+ it->sp > 0 ? it->stack[it->sp - 1].string : it->string;
+ unsigned char *p = (STRINGP (object)
+ ? SDATA (object) + IT_STRING_BYTEPOS (*it)
+ : BYTE_POS_ADDR (IT_BYTEPOS (*it)));
+ bool multibyte_p =
+ STRINGP (object) ? STRING_MULTIBYTE (object) : it->multibyte_p;
it2 = *it;
- if (it->multibyte_p)
- it2.c = it2.char_to_display = string_char_and_length (p, &it2.len);
+ if (multibyte_p)
+ {
+ it2.c = it2.char_to_display = string_char_and_length (p, &it2.len);
+#ifdef HAVE_WINDOW_SYSTEM
+ if (FRAME_WINDOW_P (it->f) && ! ASCII_CHAR_P (it2.c))
+ it2.face_id = FACE_FOR_CHAR (it->f, face, it2.c,
+ IT_CHARPOS (*it),
+ STRINGP (object)? object : Qnil);
+#endif
+ }
else
{
it2.c = it2.char_to_display = *p, it2.len = 1;
@@ -29971,7 +30420,8 @@ produce_stretch_glyph (struct it *it)
if (width > 0 && height > 0 && it->glyph_row)
{
Lisp_Object o_object = it->object;
- Lisp_Object object = it->stack[it->sp - 1].string;
+ Lisp_Object object =
+ it->sp > 0 ? it->stack[it->sp - 1].string : it->string;
int n = width;
if (!STRINGP (object))
@@ -30786,6 +31236,11 @@ gui_produce_glyphs (struct it *it)
it->max_ascent = max (it->max_ascent, font_ascent);
it->max_descent = max (it->max_descent, font_descent);
}
+
+ if (it->ascent < 0)
+ it->ascent = 0;
+ if (it->descent < 0)
+ it->descent = 0;
}
else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
{
@@ -31825,6 +32280,20 @@ erase_phys_cursor (struct window *w)
&& cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
mouse_face_here_p = true;
+#ifdef HAVE_WINDOW_SYSTEM
+ /* Since erasing the phys cursor will probably lead to corruption of
+ the mouse face display if the glyph's pixel_width is not kept up
+ to date with the :box property of the mouse face, just redraw the
+ mouse face. */
+ if (FRAME_WINDOW_P (WINDOW_XFRAME (w)) && mouse_face_here_p)
+ {
+ w->phys_cursor_on_p = false;
+ w->phys_cursor_type = NO_CURSOR;
+ show_mouse_face (MOUSE_HL_INFO (WINDOW_XFRAME (w)), DRAW_MOUSE_FACE);
+ return;
+ }
+#endif
+
/* Maybe clear the display under the cursor. */
if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
{
@@ -32096,6 +32565,9 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
&& hlinfo->mouse_face_end_row < w->current_matrix->nrows)
{
bool phys_cursor_on_p = w->phys_cursor_on_p;
+#ifdef HAVE_WINDOW_SYSTEM
+ int mouse_off = 0;
+#endif
struct glyph_row *row, *first, *last;
first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
@@ -32169,6 +32641,15 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
row->mouse_face_p
= draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
}
+#ifdef HAVE_WINDOW_SYSTEM
+ /* Compute the cursor offset due to mouse-highlight. */
+ if ((MATRIX_ROW_VPOS (row, w->current_matrix) == w->phys_cursor.vpos)
+ /* But not when highlighting a pseudo window, such as
+ the toolbar, which can't have a cursor anyway. */
+ && !w->pseudo_window_p
+ && draw == DRAW_MOUSE_FACE)
+ get_cursor_offset_for_mouse_face (w, row, &mouse_off);
+#endif
}
/* When we've written over the cursor, arrange for it to
@@ -32178,6 +32659,7 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
{
#ifdef HAVE_WINDOW_SYSTEM
int hpos = w->phys_cursor.hpos;
+ int old_phys_cursor_x = w->phys_cursor.x;
/* When the window is hscrolled, cursor hpos can legitimately be
out of bounds, but we draw the cursor at the corresponding
@@ -32189,7 +32671,11 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
block_input ();
display_and_set_cursor (w, true, hpos, w->phys_cursor.vpos,
- w->phys_cursor.x, w->phys_cursor.y);
+ w->phys_cursor.x + mouse_off,
+ w->phys_cursor.y);
+ /* Restore the original cursor coordinates, perhaps modified
+ to account for mouse-highlight. */
+ w->phys_cursor.x = old_phys_cursor_x;
unblock_input ();
#endif /* HAVE_WINDOW_SYSTEM */
}
@@ -33530,11 +34016,16 @@ note_mouse_highlight (struct frame *f, int x, int y)
struct buffer *b;
/* When a menu is active, don't highlight because this looks odd. */
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
+#if defined (USE_X_TOOLKIT) || (defined (USE_GTK) && !defined (HAVE_PGTK)) || defined (HAVE_NS) || defined (MSDOS)
if (popup_activated ())
return;
#endif
+#if defined (HAVE_HAIKU)
+ if (popup_activated_p)
+ return;
+#endif
+
if (!f->glyphs_initialized_p
|| f->pointer_invisible)
return;
@@ -33569,7 +34060,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
&& y < FRAME_MENU_BAR_LINES (f) + FRAME_TAB_BAR_LINES (f)))
{
int prop_idx;
- ptrdiff_t ignore;
+ bool ignore;
Lisp_Object caption = tty_get_tab_bar_item (f, x, &prop_idx, &ignore);
if (!NILP (caption))
@@ -33652,7 +34143,21 @@ note_mouse_highlight (struct frame *f, int x, int y)
if (EQ (window, f->tab_bar_window))
{
note_tab_bar_highlight (f, x, y);
- return;
+ if (tab_bar__dragging_in_progress)
+ {
+ cursor = FRAME_OUTPUT_DATA (f)->hand_cursor;
+ goto set_cursor;
+ }
+ else
+ return;
+ }
+ else
+ {
+ /* The mouse might have pressed into the tab bar, but might
+ also have been released outside the tab bar, so
+ f->last_tab_bar_item must be reset, in order to make sure the
+ item can be still highlighted again in the future. */
+ f->last_tab_bar_item = -1;
}
#endif
@@ -34848,9 +35353,11 @@ be let-bound around code that needs to disable messages temporarily. */);
defsubr (&Sinvisible_p);
defsubr (&Scurrent_bidi_paragraph_direction);
defsubr (&Swindow_text_pixel_size);
+ defsubr (&Sbuffer_text_pixel_size);
defsubr (&Smove_point_visually);
defsubr (&Sbidi_find_overridden_directionality);
defsubr (&Sdisplay__line_is_continued_p);
+ defsubr (&Sget_display_property);
DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
@@ -35043,6 +35550,26 @@ glyph followed by an ordinary space or hyphen.
A value of nil means no special handling of these characters. */);
Vnobreak_char_display = Qt;
+ DEFVAR_BOOL ("nobreak-char-ascii-display", nobreak_char_ascii_display,
+ doc: /* Control display of non-ASCII space and hyphen chars.
+If the value of this variable is nil, the default, Emacs displays
+non-ASCII chars which have the same appearance as an ASCII space
+or hyphen as themselves, with the `nobreak-space' or `nobreak-hyphen'
+face, respectively.
+
+If the value is t, these characters are displayed as their ASCII
+counterparts: whitespace characters as ASCII space, hyphen characters
+as ASCII hyphen (a.k.a. \"dash\"), using the `nobreak-space' or
+the `nobreak-hyphen' face.
+
+This variable has effect only if `nobreak-char-display' is t;
+otherwise it is ignored.
+
+All of the non-ASCII characters in the Unicode horizontal whitespace
+character class, as well as U+00AD (soft hyphen), U+2010 (hyphen), and
+U+2011 (non-breaking hyphen) are affected. */);
+ nobreak_char_ascii_display = false;
+
DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
doc: /* The pointer shape to show in void text areas.
A value of nil means to show the text pointer. Other options are
@@ -35136,7 +35663,10 @@ not span the full frame width.
A value of nil means to respect the value of `truncate-lines'.
-If `word-wrap' is enabled, you might want to reduce this. */);
+If `word-wrap' is enabled, you might want to reduce the value of this.
+
+Don't set this to a non-nil value when `visual-line-mode' is
+turned on, as it could produce confusing results. */);
Vtruncate_partial_width_windows = make_fixnum (50);
DEFVAR_BOOL("word-wrap-by-category", word_wrap_by_category, doc: /*
@@ -35170,7 +35700,9 @@ line number may be omitted from the mode line. */);
line_number_display_limit_width = 200;
DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
- doc: /* Non-nil means highlight region even in nonselected windows. */);
+ doc: /* Non-nil means highlight active region even in nonselected windows.
+When nil (the default), the active region is only highlighted when
+the window is selected. */);
highlight_nonselected_windows = false;
DEFVAR_BOOL ("multiple-frames", multiple_frames,
@@ -35734,11 +36266,13 @@ message displayed by its counterpart function specified by
Vclear_message_function = Qnil;
DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
- doc: /* */);
+ doc: /* Code of the cause for redisplaying all windows.
+Internal use only. */);
Vredisplay__all_windows_cause = Fmake_hash_table (0, NULL);
DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
- doc: /* */);
+ doc: /* Code of the cause for redisplaying mode lines.
+Internal use only. */);
Vredisplay__mode_lines_cause = Fmake_hash_table (0, NULL);
DEFVAR_BOOL ("redisplay--inhibit-bidi", redisplay__inhibit_bidi,
@@ -35759,11 +36293,16 @@ When nil, mouse-movement events will not be generated as long as the
mouse stays within the extent of a single glyph (except for images). */);
mouse_fine_grained_tracking = false;
+ DEFVAR_BOOL ("tab-bar--dragging-in-progress", tab_bar__dragging_in_progress,
+ doc: /* Non-nil when maybe dragging tab bar item. */);
+ tab_bar__dragging_in_progress = false;
+
DEFVAR_BOOL ("redisplay-skip-initial-frame", redisplay_skip_initial_frame,
- doc: /* Non-nil to skip redisplay in initial frame.
-The initial frame is not displayed anywhere, so skipping it is
-best except in special circumstances such as running redisplay tests
-in batch mode. */);
+ doc: /* Non-nil means skip redisplay of the initial frame.
+The initial frame is the text-mode frame used by Emacs internally during
+the early stages of startup. That frame is not displayed anywhere, so
+skipping it is best except in special circumstances such as running
+redisplay tests in batch mode. */);
redisplay_skip_initial_frame = true;
DEFVAR_BOOL ("redisplay-skip-fontification-on-input",
@@ -35938,4 +36477,121 @@ cancel_hourglass (void)
}
}
+/* Return a correction to be applied to G->pixel_width when it is
+ displayed in MOUSE_FACE. This is needed for the first and the last
+ glyphs of text inside a face with :box when it is displayed with
+ MOUSE_FACE that has a different or no :box attribute.
+ ORIGINAL_FACE is the face G was originally drawn in, and MOUSE_FACE
+ is the face it will be drawn in now. ROW is the G's glyph row and
+ W is its window. */
+static int
+adjust_glyph_width_for_mouse_face (struct glyph *g, struct glyph_row *row,
+ struct window *w,
+ struct face *original_face,
+ struct face *mouse_face)
+{
+ int sum = 0;
+
+ bool do_left_box_p = g->left_box_line_p;
+ bool do_right_box_p = g->right_box_line_p;
+
+ /* This is required because we test some parameters of the image
+ slice before applying the box in produce_image_glyph. */
+ if (g->type == IMAGE_GLYPH)
+ {
+ if (!row->reversed_p)
+ {
+ struct image *img = IMAGE_FROM_ID (WINDOW_XFRAME (w),
+ g->u.img_id);
+ do_left_box_p = g->left_box_line_p &&
+ g->slice.img.x == 0;
+ do_right_box_p = g->right_box_line_p &&
+ g->slice.img.x + g->slice.img.width == img->width;
+ }
+ else
+ {
+ struct image *img = IMAGE_FROM_ID (WINDOW_XFRAME (w),
+ g->u.img_id);
+ do_left_box_p = g->left_box_line_p &&
+ g->slice.img.x + g->slice.img.width == img->width;
+ do_right_box_p = g->right_box_line_p &&
+ g->slice.img.x == 0;
+ }
+ }
+
+ /* If the glyph has a left box line, subtract it from the offset. */
+ if (do_left_box_p)
+ sum -= max (0, original_face->box_vertical_line_width);
+ /* Likewise with the right box line, as there may be a
+ box there as well. */
+ if (do_right_box_p)
+ sum -= max (0, original_face->box_vertical_line_width);
+ /* Now add the line widths from the new face. */
+ if (g->left_box_line_p)
+ sum += max (0, mouse_face->box_vertical_line_width);
+ if (g->right_box_line_p)
+ sum += max (0, mouse_face->box_vertical_line_width);
+
+ return sum;
+}
+
+/* Get the offset due to mouse-highlight to apply before drawing
+ phys_cursor, and return it in OFFSET. ROW should be the row that
+ is under mouse face and contains the phys cursor.
+
+ This is required because the produce_XXX_glyph series of functions
+ add the width of the various vertical box lines to the total width
+ of the glyphs, but that must be updated when the row is put under
+ mouse face, which can have different box dimensions. */
+static void
+get_cursor_offset_for_mouse_face (struct window *w, struct glyph_row *row,
+ int *offset)
+{
+ int sum = 0;
+ /* Return because the mode line can't possibly have a cursor. */
+ if (row->mode_line_p)
+ return;
+
+ block_input ();
+
+ struct frame *f = WINDOW_XFRAME (w);
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+ struct glyph *start, *end;
+ struct face *mouse_face = FACE_FROM_ID (f, hlinfo->mouse_face_face_id);
+ int hpos = w->phys_cursor.hpos;
+ end = &row->glyphs[TEXT_AREA][hpos];
+
+ if (!row->reversed_p)
+ {
+ if (MATRIX_ROW_VPOS (row, w->current_matrix) ==
+ hlinfo->mouse_face_beg_row)
+ start = &row->glyphs[TEXT_AREA][hlinfo->mouse_face_beg_col];
+ else
+ start = row->glyphs[TEXT_AREA];
+ }
+ else
+ {
+ if (MATRIX_ROW_VPOS (row, w->current_matrix) ==
+ hlinfo->mouse_face_end_row)
+ start = &row->glyphs[TEXT_AREA][hlinfo->mouse_face_end_col];
+ else
+ start = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
+ }
+
+ /* Calculate the offset by which to correct phys_cursor x if we are
+ drawing the cursor inside mouse-face highlighted text. */
+
+ for ( ; row->reversed_p ? start > end : start < end;
+ row->reversed_p ? --start : ++start)
+ sum += adjust_glyph_width_for_mouse_face (start, row, w,
+ FACE_FROM_ID (f, start->face_id),
+ mouse_face);
+
+ if (row->reversed_p)
+ sum = -sum;
+
+ *offset = sum;
+
+ unblock_input ();
+}
#endif /* HAVE_WINDOW_SYSTEM */
diff --git a/src/xfaces.c b/src/xfaces.c
index 207f0d6a36e..6f52637e916 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -246,6 +246,14 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#ifdef HAVE_NS
#define GCGraphicsExposures 0
#endif /* HAVE_NS */
+
+#ifdef HAVE_PGTK
+#define GCGraphicsExposures 0
+#endif /* HAVE_PGTK */
+
+#ifdef HAVE_HAIKU
+#define GCGraphicsExposures 0
+#endif /* HAVE_HAIKU */
#endif /* HAVE_WINDOW_SYSTEM */
#include "buffer.h"
@@ -555,8 +563,8 @@ x_free_gc (struct frame *f, Emacs_GC *gc)
#endif /* HAVE_NTGUI */
-#ifdef HAVE_NS
-/* NS emulation of GCs */
+#if defined (HAVE_NS) || defined (HAVE_HAIKU)
+/* NS and Haiku emulation of GCs */
static Emacs_GC *
x_create_gc (struct frame *f,
@@ -575,6 +583,26 @@ x_free_gc (struct frame *f, Emacs_GC *gc)
}
#endif /* HAVE_NS */
+#ifdef HAVE_PGTK
+/* PGTK emulation of GCs */
+
+static Emacs_GC *
+x_create_gc (struct frame *f,
+ unsigned long mask,
+ Emacs_GC *xgcv)
+{
+ Emacs_GC *gc = xmalloc (sizeof *gc);
+ *gc = *xgcv;
+ return gc;
+}
+
+static void
+x_free_gc (struct frame *f, Emacs_GC *gc)
+{
+ xfree (gc);
+}
+#endif /* HAVE_NS */
+
/***********************************************************************
Frames and faces
***********************************************************************/
@@ -674,7 +702,8 @@ clear_face_cache (bool clear_fonts_p)
{
struct frame *f = XFRAME (frame);
if (FRAME_WINDOW_P (f)
- && FRAME_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
+ && FRAME_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS
+ && !f->inhibit_clear_image_cache)
{
clear_font_cache (f);
free_all_realized_faces (frame);
@@ -1415,52 +1444,6 @@ enum xlfd_field
XLFD_LAST
};
-/* An enumerator for each possible slant value of a font. Taken from
- the XLFD specification. */
-
-enum xlfd_slant
-{
- XLFD_SLANT_UNKNOWN,
- XLFD_SLANT_ROMAN,
- XLFD_SLANT_ITALIC,
- XLFD_SLANT_OBLIQUE,
- XLFD_SLANT_REVERSE_ITALIC,
- XLFD_SLANT_REVERSE_OBLIQUE,
- XLFD_SLANT_OTHER
-};
-
-/* Relative font weight according to XLFD documentation. */
-
-enum xlfd_weight
-{
- XLFD_WEIGHT_UNKNOWN,
- XLFD_WEIGHT_ULTRA_LIGHT, /* 10 */
- XLFD_WEIGHT_EXTRA_LIGHT, /* 20 */
- XLFD_WEIGHT_LIGHT, /* 30 */
- XLFD_WEIGHT_SEMI_LIGHT, /* 40: SemiLight, Book, ... */
- XLFD_WEIGHT_MEDIUM, /* 50: Medium, Normal, Regular, ... */
- XLFD_WEIGHT_SEMI_BOLD, /* 60: SemiBold, DemiBold, ... */
- XLFD_WEIGHT_BOLD, /* 70: Bold, ... */
- XLFD_WEIGHT_EXTRA_BOLD, /* 80: ExtraBold, Heavy, ... */
- XLFD_WEIGHT_ULTRA_BOLD /* 90: UltraBold, Black, ... */
-};
-
-/* Relative proportionate width. */
-
-enum xlfd_swidth
-{
- XLFD_SWIDTH_UNKNOWN,
- XLFD_SWIDTH_ULTRA_CONDENSED, /* 10 */
- XLFD_SWIDTH_EXTRA_CONDENSED, /* 20 */
- XLFD_SWIDTH_CONDENSED, /* 30: Condensed, Narrow, Compressed, ... */
- XLFD_SWIDTH_SEMI_CONDENSED, /* 40: semicondensed */
- XLFD_SWIDTH_MEDIUM, /* 50: Medium, Normal, Regular, ... */
- XLFD_SWIDTH_SEMI_EXPANDED, /* 60: SemiExpanded, DemiExpanded, ... */
- XLFD_SWIDTH_EXPANDED, /* 70: Expanded... */
- XLFD_SWIDTH_EXTRA_EXPANDED, /* 80: ExtraExpanded, Wide... */
- XLFD_SWIDTH_ULTRA_EXPANDED /* 90: UltraExpanded... */
-};
-
/* Order by which font selection chooses fonts. The default values
mean `first, find a best match for the font width, then for the
font height, then for weight, then for slant.' This variable can be
@@ -2419,11 +2402,11 @@ evaluate_face_filter (Lisp_Object filter, struct window *w,
/* Determine whether FACE_REF is a "filter" face specification (case
#4 in merge_face_ref). If it is, evaluate the filter, and if the
filter matches, return the filtered face spec. If the filter does
- not match, return `nil'. If FACE_REF is not a filtered face
+ not match, return nil. If FACE_REF is not a filtered face
specification, return FACE_REF.
On error, set *OK to false, having logged an error message if
- ERR_MSGS is true, and return `nil'. Otherwise, *OK is not touched.
+ ERR_MSGS is true, and return nil. Otherwise, *OK is not touched.
W is either NULL or a window used to evaluate filters. If W is
NULL, no window-based face specification filter matches.
@@ -2708,7 +2691,7 @@ merge_face_ref (struct window *w,
{
if (EQ (value, Qt))
value = make_fixnum (1);
- if (FIXNUMP (value)
+ if ((FIXNUMP (value) && XFIXNUM (value) != 0)
|| STRINGP (value)
|| CONSP (value)
|| NILP (value))
@@ -4882,7 +4865,7 @@ lookup_named_face (struct window *w, struct frame *f,
/* Return the display face-id of the basic face whose canonical face-id
is FACE_ID. The return value will usually simply be FACE_ID, unless that
- basic face has bee remapped via Vface_remapping_alist. This function is
+ basic face has been remapped via Vface_remapping_alist. This function is
conservative: if something goes wrong, it will simply return FACE_ID
rather than signal an error. Window W, if non-NULL, is used to filter
face specifications for remapping. */
@@ -4898,7 +4881,7 @@ lookup_basic_face (struct window *w, struct frame *f, int face_id)
switch (face_id)
{
case DEFAULT_FACE_ID: name = Qdefault; break;
- case MODE_LINE_FACE_ID: name = Qmode_line; break;
+ case MODE_LINE_ACTIVE_FACE_ID: name = Qmode_line_active; break;
case MODE_LINE_INACTIVE_FACE_ID: name = Qmode_line_inactive; break;
case HEADER_LINE_FACE_ID: name = Qheader_line; break;
case TAB_LINE_FACE_ID: name = Qtab_line; break;
@@ -5092,8 +5075,8 @@ gui_supports_face_attributes_p (struct frame *f,
{
Lisp_Object *def_attrs = def_face->lface;
- /* Check that other specified attributes are different that the default
- face. */
+ /* Check that other specified attributes are different from the
+ default face. */
if ((!UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
&& face_attr_equal_p (attrs[LFACE_UNDERLINE_INDEX],
def_attrs[LFACE_UNDERLINE_INDEX]))
@@ -5372,6 +5355,10 @@ DEFUN ("display-supports-face-attributes-p",
The optional argument DISPLAY can be a display name, a frame, or
nil (meaning the selected frame's display).
+For instance, to check whether the display supports underlining:
+
+ (display-supports-face-attributes-p \\='(:underline t))
+
The definition of `supported' is somewhat heuristic, but basically means
that a face containing all the attributes in ATTRIBUTES, when merged
with the default face for display, can be represented in a way that's
@@ -5606,6 +5593,7 @@ realize_basic_faces (struct frame *f)
if (realize_default_face (f))
{
realize_named_face (f, Qmode_line, MODE_LINE_FACE_ID);
+ realize_named_face (f, Qmode_line_active, MODE_LINE_ACTIVE_FACE_ID);
realize_named_face (f, Qmode_line_inactive, MODE_LINE_INACTIVE_FACE_ID);
realize_named_face (f, Qtool_bar, TOOL_BAR_FACE_ID);
realize_named_face (f, Qfringe, FRINGE_FACE_ID);
@@ -6409,20 +6397,19 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
int face_id;
if (base_face_id >= 0)
- {
- face_id = base_face_id;
- /* Make sure the base face ID is usable: if someone freed the
- cached faces since we've looked up the base face, we need
- to look it up again. */
- if (!FACE_FROM_ID_OR_NULL (f, face_id))
- face_id = lookup_basic_face (w, f, DEFAULT_FACE_ID);
- }
+ face_id = base_face_id;
else if (NILP (Vface_remapping_alist))
face_id = DEFAULT_FACE_ID;
else
face_id = lookup_basic_face (w, f, DEFAULT_FACE_ID);
- default_face = FACE_FROM_ID (f, face_id);
+ default_face = FACE_FROM_ID_OR_NULL (f, face_id);
+ /* Make sure the default face ID is usable: if someone freed the
+ cached faces since we've looked up these faces, we need to look
+ them up again. */
+ if (!default_face)
+ default_face = FACE_FROM_ID (f,
+ lookup_basic_face (w, f, DEFAULT_FACE_ID));
}
/* Optimize common cases where we can use the default face. */
@@ -6607,7 +6594,9 @@ face_at_string_position (struct window *w, Lisp_Object string,
else
*endptr = -1;
- base_face = FACE_FROM_ID (f, base_face_id);
+ base_face = FACE_FROM_ID_OR_NULL (f, base_face_id);
+ if (!base_face)
+ base_face = FACE_FROM_ID (f, lookup_basic_face (w, f, DEFAULT_FACE_ID));
/* Optimize the default case that there is no face property. */
if (NILP (prop)
@@ -6932,13 +6921,20 @@ syms_of_xfaces (void)
DEFSYM (Qpressed_button, "pressed-button");
DEFSYM (Qflat_button, "flat-button");
DEFSYM (Qnormal, "normal");
+ DEFSYM (Qthin, "thin");
DEFSYM (Qextra_light, "extra-light");
+ DEFSYM (Qultra_light, "ultra-light");
DEFSYM (Qlight, "light");
DEFSYM (Qsemi_light, "semi-light");
+ DEFSYM (Qmedium, "medium");
DEFSYM (Qsemi_bold, "semi-bold");
+ DEFSYM (Qbook, "book");
DEFSYM (Qbold, "bold");
DEFSYM (Qextra_bold, "extra-bold");
DEFSYM (Qultra_bold, "ultra-bold");
+ DEFSYM (Qheavy, "heavy");
+ DEFSYM (Qultra_heavy, "ultra-heavy");
+ DEFSYM (Qblack, "black");
DEFSYM (Qoblique, "oblique");
DEFSYM (Qitalic, "italic");
@@ -6974,6 +6970,7 @@ syms_of_xfaces (void)
DEFSYM (Qborder, "border");
DEFSYM (Qmouse, "mouse");
DEFSYM (Qmode_line_inactive, "mode-line-inactive");
+ DEFSYM (Qmode_line_active, "mode-line-active");
DEFSYM (Qvertical_border, "vertical-border");
DEFSYM (Qwindow_divider, "window-divider");
DEFSYM (Qwindow_divider_first_pixel, "window-divider-first-pixel");
diff --git a/src/xfns.c b/src/xfns.c
index 81349d0b50d..30ed358fb28 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -57,6 +57,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <X11/extensions/Xdbe.h>
#endif
+#ifdef HAVE_XINPUT2
+#include <X11/extensions/XInput2.h>
+#endif
+
#ifdef USE_X_TOOLKIT
#include <X11/Shell.h>
@@ -2912,6 +2916,60 @@ initial_set_up_x_back_buffer (struct frame *f)
unblock_input ();
}
+#if defined HAVE_XINPUT2
+static void
+setup_xi_event_mask (struct frame *f)
+{
+ XIEventMask mask;
+ ptrdiff_t l = XIMaskLen (XI_LASTEVENT);
+ unsigned char *m;
+
+ mask.mask = m = alloca (l);
+ memset (m, 0, l);
+ mask.mask_len = l;
+
+ block_input ();
+#ifndef USE_GTK
+ mask.deviceid = XIAllMasterDevices;
+
+ XISetMask (m, XI_ButtonPress);
+ XISetMask (m, XI_ButtonRelease);
+ XISetMask (m, XI_KeyPress);
+ XISetMask (m, XI_KeyRelease);
+ XISetMask (m, XI_Motion);
+ XISetMask (m, XI_Enter);
+ XISetMask (m, XI_Leave);
+#if 0
+ XISetMask (m, XI_FocusIn);
+ XISetMask (m, XI_FocusOut);
+#endif
+ XISelectEvents (FRAME_X_DISPLAY (f),
+ FRAME_X_WINDOW (f),
+ &mask, 1);
+
+ memset (m, 0, l);
+#endif /* !USE_GTK */
+
+ mask.deviceid = XIAllDevices;
+
+ XISetMask (m, XI_PropertyEvent);
+ XISetMask (m, XI_HierarchyChanged);
+ XISetMask (m, XI_DeviceChanged);
+#ifdef XI_TouchBegin
+ if (FRAME_DISPLAY_INFO (f)->xi2_version >= 2)
+ {
+ XISetMask (m, XI_TouchBegin);
+ XISetMask (m, XI_TouchUpdate);
+ XISetMask (m, XI_TouchEnd);
+ }
+#endif
+ XISelectEvents (FRAME_X_DISPLAY (f),
+ FRAME_X_WINDOW (f),
+ &mask, 1);
+ unblock_input ();
+}
+#endif
+
#ifdef USE_X_TOOLKIT
/* Create and set up the X widget for frame F. */
@@ -3074,6 +3132,11 @@ x_window (struct frame *f, long window_prompting)
class_hints.res_class = SSDATA (Vx_resource_class);
XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
+#ifdef HAVE_XINPUT2
+ if (FRAME_DISPLAY_INFO (f)->supports_xi2)
+ setup_xi_event_mask (f);
+#endif
+
#ifdef HAVE_X_I18N
FRAME_XIC (f) = NULL;
if (use_xim)
@@ -3200,6 +3263,11 @@ x_window (struct frame *f)
unblock_input ();
}
#endif
+
+#ifdef HAVE_XINPUT2
+ if (FRAME_DISPLAY_INFO (f)->supports_xi2)
+ setup_xi_event_mask (f);
+#endif
}
#else /*! USE_GTK */
@@ -3254,6 +3322,11 @@ x_window (struct frame *f)
}
#endif /* HAVE_X_I18N */
+#ifdef HAVE_XINPUT2
+ if (FRAME_DISPLAY_INFO (f)->supports_xi2)
+ setup_xi_event_mask (f);
+#endif
+
validate_x_resource_name ();
class_hints.res_name = SSDATA (Vx_resource_name);
@@ -4416,7 +4489,8 @@ For GNU and Unix system, the first 2 numbers are the version of the X
Protocol used on TERMINAL and the 3rd number is the distributor-specific
release number. For MS Windows, the 3 numbers report the OS major and
minor version and build number. For Nextstep, the first 2 numbers are
-hard-coded and the 3rd represents the OS version.
+hard-coded and the 3rd represents the OS version. For Haiku, all 3
+numbers are hard-coded.
See also the function `x-server-vendor'.
@@ -6222,7 +6296,7 @@ Otherwise, the return value is a vector with the following fields:
static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
Lisp_Object, int, int, int *, int *);
-/* The frame of the currently visible tooltip. */
+/* The frame of the currently visible tooltip, or nil if none. */
static Lisp_Object tip_frame;
/* The window-system window corresponding to the frame of the
@@ -6710,7 +6784,7 @@ x_hide_tip (bool delete)
if ((NILP (tip_last_frame) && NILP (tip_frame))
|| (!x_gtk_use_system_tooltips
&& !delete
- && FRAMEP (tip_frame)
+ && !NILP (tip_frame)
&& FRAME_LIVE_P (XFRAME (tip_frame))
&& !FRAME_VISIBLE_P (XFRAME (tip_frame))))
/* Either there's no tooltip to hide or it's an already invisible
@@ -6727,7 +6801,7 @@ x_hide_tip (bool delete)
specbind (Qinhibit_quit, Qt);
/* Try to hide the GTK+ system tip first. */
- if (FRAMEP (tip_last_frame))
+ if (!NILP (tip_last_frame))
{
struct frame *f = XFRAME (tip_last_frame);
@@ -6745,7 +6819,7 @@ x_hide_tip (bool delete)
tip_last_frame = Qnil;
/* Now look whether there's an Emacs tip around. */
- if (FRAMEP (tip_frame))
+ if (!NILP (tip_frame))
{
struct frame *f = XFRAME (tip_frame);
@@ -6775,7 +6849,7 @@ x_hide_tip (bool delete)
#else /* not USE_GTK */
if (NILP (tip_frame)
|| (!delete
- && FRAMEP (tip_frame)
+ && !NILP (tip_frame)
&& FRAME_LIVE_P (XFRAME (tip_frame))
&& !FRAME_VISIBLE_P (XFRAME (tip_frame))))
return Qnil;
@@ -6788,7 +6862,7 @@ x_hide_tip (bool delete)
specbind (Qinhibit_redisplay, Qt);
specbind (Qinhibit_quit, Qt);
- if (FRAMEP (tip_frame))
+ if (!NILP (tip_frame))
{
struct frame *f = XFRAME (tip_frame);
@@ -6931,7 +7005,7 @@ Text larger than the specified size is clipped. */)
}
#endif /* USE_GTK */
- if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
+ if (!NILP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
{
if (FRAME_VISIBLE_P (XFRAME (tip_frame))
&& EQ (frame, tip_last_frame)
@@ -7016,7 +7090,7 @@ Text larger than the specified size is clipped. */)
tip_last_string = string;
tip_last_parms = parms;
- if (!FRAMEP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
+ if (NILP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
{
/* Add default values to frame parameters. */
if (NILP (Fassq (Qname, parms)))
@@ -7095,7 +7169,8 @@ Text larger than the specified size is clipped. */)
try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
/* Calculate size of tooltip window. */
size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil,
- make_fixnum (w->pixel_height), Qnil);
+ make_fixnum (w->pixel_height), Qnil,
+ Qnil);
/* Add the frame's internal border to calculated size. */
width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
@@ -7374,7 +7449,7 @@ Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
selection box, if specified. If MUSTMATCH is non-nil, the returned file
or directory must exist.
-This function is defined only on NS, MS Windows, and X Windows with the
+This function is defined only on NS, Haiku, MS Windows, and X Windows with the
Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
Otherwise, if ONLY-DIR-P is non-nil, the user can select only directories.
On MS Windows 7 and later, the file selection dialog "remembers" the last
@@ -7836,7 +7911,6 @@ syms_of_xfns (void)
DEFSYM (Qfont_parameter, "font-parameter");
DEFSYM (Qmono, "mono");
DEFSYM (Qassq_delete_all, "assq-delete-all");
- DEFSYM (Qhide, "hide");
DEFSYM (Qresize_mode, "resize-mode");
#ifdef USE_CAIRO
@@ -8039,6 +8113,12 @@ eliminated in future versions of Emacs. */);
/* Tell Emacs about this window system. */
Fprovide (Qx, Qnil);
+#ifdef HAVE_XINPUT2
+ DEFSYM (Qxinput2, "xinput2");
+
+ Fprovide (Qxinput2, Qnil);
+#endif
+
#ifdef USE_X_TOOLKIT
Fprovide (intern_c_string ("x-toolkit"), Qnil);
#ifdef USE_MOTIF
diff --git a/src/xmenu.c b/src/xmenu.c
index a6762236bc4..07255911f97 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -105,7 +105,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
/* Flag which when set indicates a dialog or menu has been posted by
Xt on behalf of one of the widget sets. */
+#ifndef HAVE_XINPUT2
static int popup_activated_flag;
+#else
+int popup_activated_flag;
+#endif
#ifdef USE_X_TOOLKIT
@@ -1603,6 +1607,14 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
STRINGP (help) ? help : Qnil);
if (prev_wv)
prev_wv->next = wv;
+ else if (!save_wv)
+ {
+ /* This emacs_abort call pacifies gcc 11.2.1 when Emacs
+ is configured with --enable-gcc-warnings. FIXME: If
+ save_wv can be null, do something better; otherwise,
+ explain why save_wv cannot be null. */
+ emacs_abort ();
+ }
else
save_wv->contents = wv;
if (!NILP (descrip))
diff --git a/src/xsettings.c b/src/xsettings.c
index 58dfd43ad18..d6a715e1dfc 100644
--- a/src/xsettings.c
+++ b/src/xsettings.c
@@ -26,7 +26,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <byteswap.h>
#include "lisp.h"
+#ifndef HAVE_PGTK
#include "xterm.h"
+#else
+#include "gtkutil.h"
+#endif
#include "xsettings.h"
#include "frame.h"
#include "keyboard.h"
@@ -34,7 +38,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "termhooks.h"
#include "pdumper.h"
+#ifndef HAVE_PGTK
#include <X11/Xproto.h>
+#else
+typedef unsigned short CARD16;
+typedef unsigned int CARD32;
+#endif
#ifdef HAVE_GSETTINGS
#include <glib-object.h>
@@ -55,7 +64,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
static char *current_mono_font;
static char *current_font;
-static struct x_display_info *first_dpyinfo;
+static Display_Info *first_dpyinfo;
static Lisp_Object current_tool_bar_style;
/* Store a config changed event in to the event queue. */
@@ -73,14 +82,18 @@ store_config_changed_event (Lisp_Object arg, Lisp_Object display_name)
/* Return true if DPYINFO is still valid. */
static bool
-dpyinfo_valid (struct x_display_info *dpyinfo)
+dpyinfo_valid (Display_Info *dpyinfo)
{
bool found = false;
if (dpyinfo != NULL)
{
- struct x_display_info *d;
+ Display_Info *d;
for (d = x_display_list; !found && d; d = d->next)
+#ifndef HAVE_PGTK
found = d == dpyinfo && d->display == dpyinfo->display;
+#else
+ found = d == dpyinfo && d->gdpy == dpyinfo->gdpy;
+#endif
}
return found;
}
@@ -149,7 +162,7 @@ map_tool_bar_style (const char *tool_bar_style)
static void
store_tool_bar_style_changed (const char *newstyle,
- struct x_display_info *dpyinfo)
+ Display_Info *dpyinfo)
{
Lisp_Object style = map_tool_bar_style (newstyle);
if (EQ (current_tool_bar_style, style))
@@ -161,10 +174,12 @@ store_tool_bar_style_changed (const char *newstyle,
XCAR (dpyinfo->name_list_element));
}
+#ifndef HAVE_PGTK
#if defined USE_CAIRO || defined HAVE_XFT
#define XSETTINGS_FONT_NAME "Gtk/FontName"
#endif
#define XSETTINGS_TOOL_BAR_STYLE "Gtk/ToolbarStyle"
+#endif
enum {
SEEN_AA = 0x01,
@@ -321,10 +336,11 @@ something_changed_gconfCB (GConfClient *client,
#endif /* USE_CAIRO || HAVE_XFT */
+#ifndef HAVE_PGTK
/* Find the window that contains the XSETTINGS property values. */
static void
-get_prop_window (struct x_display_info *dpyinfo)
+get_prop_window (Display_Info *dpyinfo)
{
Display *dpy = dpyinfo->display;
@@ -339,6 +355,9 @@ get_prop_window (struct x_display_info *dpyinfo)
XUngrabServer (dpy);
}
+#endif
+
+#ifndef HAVE_PGTK
#define PAD(nr) (((nr) + 3) & ~3)
@@ -566,13 +585,15 @@ parse_settings (unsigned char *prop,
return settings_seen;
}
+#endif
+#ifndef HAVE_PGTK
/* Read settings from the XSettings property window on display for DPYINFO.
Store settings read in SETTINGS.
Return true iff successful. */
static bool
-read_settings (struct x_display_info *dpyinfo, struct xsettings *settings)
+read_settings (Display_Info *dpyinfo, struct xsettings *settings)
{
Atom act_type;
int act_form;
@@ -600,12 +621,14 @@ read_settings (struct x_display_info *dpyinfo, struct xsettings *settings)
return got_settings;
}
+#endif
+#ifndef HAVE_PGTK
/* Apply Xft settings in SETTINGS to the Xft library.
Store a Lisp event that Xft settings changed. */
static void
-apply_xft_settings (struct x_display_info *dpyinfo,
+apply_xft_settings (Display_Info *dpyinfo,
struct xsettings *settings)
{
#ifdef HAVE_XFT
@@ -731,12 +754,14 @@ apply_xft_settings (struct x_display_info *dpyinfo,
FcPatternDestroy (pat);
#endif /* HAVE_XFT */
}
+#endif
+#ifndef HAVE_PGTK
/* Read XSettings from the display for DPYINFO.
If SEND_EVENT_P store a Lisp event settings that changed. */
static void
-read_and_apply_settings (struct x_display_info *dpyinfo, bool send_event_p)
+read_and_apply_settings (Display_Info *dpyinfo, bool send_event_p)
{
struct xsettings settings;
@@ -763,11 +788,13 @@ read_and_apply_settings (struct x_display_info *dpyinfo, bool send_event_p)
}
#endif
}
+#endif
+#ifndef HAVE_PGTK
/* Check if EVENT for the display in DPYINFO is XSettings related. */
void
-xft_settings_event (struct x_display_info *dpyinfo, const XEvent *event)
+xft_settings_event (Display_Info *dpyinfo, const XEvent *event)
{
bool check_window_p = false, apply_settings_p = false;
@@ -805,6 +832,7 @@ xft_settings_event (struct x_display_info *dpyinfo, const XEvent *event)
if (apply_settings_p)
read_and_apply_settings (dpyinfo, true);
}
+#endif
/* Initialize GSettings and read startup values. */
@@ -940,10 +968,11 @@ init_gconf (void)
#endif /* HAVE_GCONF */
}
+#ifndef HAVE_PGTK
/* Init Xsettings and read startup values. */
static void
-init_xsettings (struct x_display_info *dpyinfo)
+init_xsettings (Display_Info *dpyinfo)
{
Display *dpy = dpyinfo->display;
@@ -959,13 +988,16 @@ init_xsettings (struct x_display_info *dpyinfo)
unblock_input ();
}
+#endif
void
-xsettings_initialize (struct x_display_info *dpyinfo)
+xsettings_initialize (Display_Info *dpyinfo)
{
if (first_dpyinfo == NULL) first_dpyinfo = dpyinfo;
init_gconf ();
+#ifndef HAVE_PGTK
init_xsettings (dpyinfo);
+#endif
init_gsettings ();
}
diff --git a/src/xsettings.h b/src/xsettings.h
index 26717fc08cb..dae41e8a3b8 100644
--- a/src/xsettings.h
+++ b/src/xsettings.h
@@ -20,12 +20,23 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#ifndef XSETTINGS_H
#define XSETTINGS_H
+#ifndef HAVE_PGTK
#include <X11/Xlib.h>
+#endif
struct x_display_info;
+struct pgtk_display_info;
+
+#ifndef HAVE_PGTK
+typedef struct x_display_info Display_Info;
+#else
+typedef struct pgtk_display_info Display_Info;
+#endif
-extern void xsettings_initialize (struct x_display_info *);
-extern void xft_settings_event (struct x_display_info *, const XEvent *);
+extern void xsettings_initialize (Display_Info *);
+#ifndef HAVE_PGTK
+extern void xft_settings_event (Display_Info *, const XEvent *);
+#endif
extern const char *xsettings_get_system_font (void);
#ifdef USE_LUCID
extern const char *xsettings_get_system_normal_font (void);
diff --git a/src/xterm.c b/src/xterm.c
index 1887c3255d4..7456b3b6beb 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -42,6 +42,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <X11/extensions/Xdbe.h>
#endif
+#ifdef HAVE_XINPUT2
+#include <X11/extensions/XInput2.h>
+#endif
+
/* Load sys/types.h if not already loaded.
In some systems loading it twice is suicidal. */
#ifndef makedev
@@ -223,9 +227,15 @@ static bool x_handle_net_wm_state (struct frame *, const XPropertyEvent *);
static void x_check_fullscreen (struct frame *);
static void x_check_expected_move (struct frame *, int, int);
static void x_sync_with_move (struct frame *, int, int, bool);
+#ifndef HAVE_XINPUT2
static int handle_one_xevent (struct x_display_info *,
const XEvent *, int *,
struct input_event *);
+#else
+static int handle_one_xevent (struct x_display_info *,
+ XEvent *, int *,
+ struct input_event *);
+#endif
#if ! (defined USE_X_TOOLKIT || defined USE_MOTIF) && defined USE_GTK
static int x_dispatch_event (XEvent *, Display *);
#endif
@@ -335,6 +345,336 @@ x_extension_initialize (struct x_display_info *dpyinfo)
dpyinfo->ext_codes = ext_codes;
}
+#endif /* HAVE_CAIRO */
+
+#ifdef HAVE_XINPUT2
+
+/* Free all XI2 devices on dpyinfo. */
+static void
+x_free_xi_devices (struct x_display_info *dpyinfo)
+{
+ struct xi_touch_point_t *tem, *last;
+
+ block_input ();
+
+ if (dpyinfo->num_devices)
+ {
+ for (int i = 0; i < dpyinfo->num_devices; ++i)
+ {
+ XIUngrabDevice (dpyinfo->display, dpyinfo->devices[i].device_id,
+ CurrentTime);
+ xfree (dpyinfo->devices[i].valuators);
+
+ tem = dpyinfo->devices[i].touchpoints;
+ while (tem)
+ {
+ last = tem;
+ tem = tem->next;
+ xfree (last);
+ }
+ }
+
+ xfree (dpyinfo->devices);
+ dpyinfo->devices = NULL;
+ dpyinfo->num_devices = 0;
+ }
+
+ unblock_input ();
+}
+
+/* The code below handles the tracking of scroll valuators on XInput
+ 2, in order to support scroll wheels that report information more
+ granular than a screen line.
+
+ On X, when the XInput 2 extension is being utilized, the states of
+ the mouse wheels in each axis are stored as absolute values inside
+ "valuators" attached to each mouse device. To obtain the delta of
+ the scroll wheel from a motion event (which is used to report that
+ some valuator has changed), it is necessary to iterate over every
+ valuator that changed, and compare its previous value to the
+ current value of the valuator.
+
+ Each individual valuator also has an "interval", which is the
+ amount you must divide that delta by in order to obtain a delta in
+ the terms of scroll units.
+
+ This delta however is still intermediate, to make driver
+ implementations easier. The XInput developers recommend (and most
+ programs use) the following algorithm to convert from scroll unit
+ deltas to pixel deltas:
+
+ pixels_scrolled = pow (window_height, 2.0 / 3.0) * delta; */
+
+/* Setup valuator tracking for XI2 master devices on
+ DPYINFO->display. */
+
+static void
+x_init_master_valuators (struct x_display_info *dpyinfo)
+{
+ int ndevices;
+ XIDeviceInfo *infos;
+
+ block_input ();
+ x_free_xi_devices (dpyinfo);
+ infos = XIQueryDevice (dpyinfo->display,
+ XIAllDevices,
+ &ndevices);
+
+ if (!ndevices)
+ {
+ XIFreeDeviceInfo (infos);
+ unblock_input ();
+ return;
+ }
+
+ int actual_devices = 0;
+ dpyinfo->devices = xmalloc (sizeof *dpyinfo->devices * ndevices);
+
+ for (int i = 0; i < ndevices; ++i)
+ {
+ XIDeviceInfo *device = &infos[i];
+
+ if (device->enabled)
+ {
+ int actual_valuator_count = 0;
+ struct xi_device_t *xi_device = &dpyinfo->devices[actual_devices++];
+ xi_device->device_id = device->deviceid;
+ xi_device->grab = 0;
+ xi_device->valuators =
+ xmalloc (sizeof *xi_device->valuators * device->num_classes);
+ xi_device->touchpoints = NULL;
+ xi_device->master_p = (device->use == XIMasterKeyboard
+ || device->use == XIMasterPointer);
+ xi_device->direct_p = false;
+
+ for (int c = 0; c < device->num_classes; ++c)
+ {
+ switch (device->classes[c]->type)
+ {
+#ifdef XIScrollClass /* XInput 2.1 */
+ case XIScrollClass:
+ {
+ XIScrollClassInfo *info =
+ (XIScrollClassInfo *) device->classes[c];
+ struct xi_scroll_valuator_t *valuator;
+
+ if (xi_device->master_p)
+ {
+ valuator = &xi_device->valuators[actual_valuator_count++];
+ valuator->horizontal
+ = (info->scroll_type == XIScrollTypeHorizontal);
+ valuator->invalid_p = true;
+ valuator->emacs_value = DBL_MIN;
+ valuator->increment = info->increment;
+ valuator->number = info->number;
+ }
+
+ break;
+ }
+#endif
+#ifdef XITouchClass /* XInput 2.2 */
+ case XITouchClass:
+ {
+ XITouchClassInfo *info;
+
+ info = (XITouchClassInfo *) device->classes[c];
+ xi_device->direct_p = info->mode == XIDirectTouch;
+ }
+#endif
+ default:
+ break;
+ }
+ }
+
+ xi_device->scroll_valuator_count = actual_valuator_count;
+ }
+ }
+
+ dpyinfo->num_devices = actual_devices;
+ XIFreeDeviceInfo (infos);
+ unblock_input ();
+}
+
+/* Return the delta of the scroll valuator VALUATOR_NUMBER under
+ DEVICE_ID in the display DPYINFO with VALUE. The valuator's
+ valuator will be set to VALUE afterwards. In case no scroll
+ valuator is found, or if device_id is not known to Emacs, DBL_MAX
+ is returned. Otherwise, the valuator is returned in
+ VALUATOR_RETURN. */
+static double
+x_get_scroll_valuator_delta (struct x_display_info *dpyinfo, int device_id,
+ int valuator_number, double value,
+ struct xi_scroll_valuator_t **valuator_return)
+{
+ block_input ();
+
+ for (int i = 0; i < dpyinfo->num_devices; ++i)
+ {
+ struct xi_device_t *device = &dpyinfo->devices[i];
+
+ if (device->device_id == device_id && device->master_p)
+ {
+ for (int j = 0; j < device->scroll_valuator_count; ++j)
+ {
+ struct xi_scroll_valuator_t *sv = &device->valuators[j];
+
+ if (sv->number == valuator_number)
+ {
+ if (sv->invalid_p)
+ {
+ sv->current_value = value;
+ sv->invalid_p = false;
+ *valuator_return = sv;
+
+ unblock_input ();
+ return 0.0;
+ }
+ else
+ {
+ double delta = (sv->current_value - value) / sv->increment;
+ sv->current_value = value;
+ *valuator_return = sv;
+
+ unblock_input ();
+ return delta;
+ }
+ }
+ }
+
+ unblock_input ();
+ return DBL_MAX;
+ }
+ }
+
+ unblock_input ();
+ return DBL_MAX;
+}
+
+static struct xi_device_t *
+xi_device_from_id (struct x_display_info *dpyinfo, int deviceid)
+{
+ for (int i = 0; i < dpyinfo->num_devices; ++i)
+ {
+ if (dpyinfo->devices[i].device_id == deviceid)
+ return &dpyinfo->devices[i];
+ }
+
+ return NULL;
+}
+
+#ifdef XI_TouchBegin
+
+static void
+xi_link_touch_point (struct xi_device_t *device,
+ int detail, double x, double y)
+{
+ struct xi_touch_point_t *touchpoint;
+
+ touchpoint = xmalloc (sizeof *touchpoint);
+ touchpoint->next = device->touchpoints;
+ touchpoint->x = x;
+ touchpoint->y = y;
+ touchpoint->number = detail;
+
+ device->touchpoints = touchpoint;
+}
+
+static bool
+xi_unlink_touch_point (int detail,
+ struct xi_device_t *device)
+{
+ struct xi_touch_point_t *last, *tem;
+
+ for (last = NULL, tem = device->touchpoints; tem;
+ last = tem, tem = tem->next)
+ {
+ if (tem->number == detail)
+ {
+ if (!last)
+ device->touchpoints = tem->next;
+ else
+ last->next = tem->next;
+
+ xfree (tem);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static struct xi_touch_point_t *
+xi_find_touch_point (struct xi_device_t *device, int detail)
+{
+ struct xi_touch_point_t *point;
+
+ for (point = device->touchpoints; point; point = point->next)
+ {
+ if (point->number == detail)
+ return point;
+ }
+
+ return NULL;
+}
+
+#endif /* XI_TouchBegin */
+
+static void
+xi_grab_or_ungrab_device (struct xi_device_t *device,
+ struct x_display_info *dpyinfo,
+ Window window)
+{
+ XIEventMask mask;
+ ptrdiff_t l = XIMaskLen (XI_LASTEVENT);
+ unsigned char *m;
+ mask.mask = m = alloca (l);
+ memset (m, 0, l);
+ mask.mask_len = l;
+
+ XISetMask (m, XI_ButtonPress);
+ XISetMask (m, XI_ButtonRelease);
+ XISetMask (m, XI_Motion);
+ XISetMask (m, XI_Enter);
+ XISetMask (m, XI_Leave);
+
+ if (device->grab)
+ {
+ XIGrabDevice (dpyinfo->display, device->device_id, window,
+ CurrentTime, None, GrabModeAsync,
+ GrabModeAsync, True, &mask);
+ }
+ else
+ {
+ XIUngrabDevice (dpyinfo->display, device->device_id, CurrentTime);
+ }
+}
+
+static void
+xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo, int id)
+{
+ struct xi_device_t *device = xi_device_from_id (dpyinfo, id);
+ struct xi_scroll_valuator_t *valuator;
+
+ if (!device || !device->master_p)
+ return;
+
+ if (!device->scroll_valuator_count)
+ return;
+
+ for (int i = 0; i < device->scroll_valuator_count; ++i)
+ {
+ valuator = &device->valuators[i];
+ valuator->invalid_p = true;
+ valuator->emacs_value = 0.0;
+ }
+
+ return;
+}
+
+#endif
+
+#ifdef USE_CAIRO
+
void
x_cr_destroy_frame_context (struct frame *f)
{
@@ -1563,22 +1903,6 @@ x_set_cursor_gc (struct glyph_string *s)
static void
x_set_mouse_face_gc (struct glyph_string *s)
{
- int face_id;
- struct face *face;
-
- /* What face has to be used last for the mouse face? */
- face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
- face = FACE_FROM_ID_OR_NULL (s->f, face_id);
- if (face == NULL)
- face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
-
- if (s->first_glyph->type == CHAR_GLYPH)
- face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
- else
- face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
- s->face = FACE_FROM_ID (s->f, face_id);
- prepare_face_for_display (s->f, s->face);
-
if (s->font == s->face->font)
s->gc = s->face->gc;
else
@@ -3209,11 +3533,14 @@ x_draw_image_relief (struct glyph_string *s)
if (s->hl == DRAW_IMAGE_SUNKEN
|| s->hl == DRAW_IMAGE_RAISED)
{
- thick = (tab_bar_button_relief < 0
- ? DEFAULT_TAB_BAR_BUTTON_RELIEF
- : (tool_bar_button_relief < 0
- ? DEFAULT_TOOL_BAR_BUTTON_RELIEF
- : min (tool_bar_button_relief, 1000000)));
+ if (s->face->id == TAB_BAR_FACE_ID)
+ thick = (tab_bar_button_relief < 0
+ ? DEFAULT_TAB_BAR_BUTTON_RELIEF
+ : min (tab_bar_button_relief, 1000000));
+ else
+ thick = (tool_bar_button_relief < 0
+ ? DEFAULT_TOOL_BAR_BUTTON_RELIEF
+ : min (tool_bar_button_relief, 1000000));
raised_p = s->hl == DRAW_IMAGE_RAISED;
}
else
@@ -3232,11 +3559,11 @@ x_draw_image_relief (struct glyph_string *s)
&& FIXNUMP (XCAR (Vtab_bar_button_margin))
&& FIXNUMP (XCDR (Vtab_bar_button_margin)))
{
- extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin));
- extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin));
+ extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin)) - thick;
+ extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin)) - thick;
}
else if (FIXNUMP (Vtab_bar_button_margin))
- extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin);
+ extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin) - thick;
}
if (s->face->id == TOOL_BAR_FACE_ID)
@@ -3585,29 +3912,15 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
else if (!s->background_filled_p)
{
int background_width = s->background_width;
- int x = s->x, text_left_x = window_box_left_offset (s->w, TEXT_AREA);
+ int x = s->x, text_left_x = window_box_left (s->w, TEXT_AREA);
/* Don't draw into left fringe or scrollbar area except for
header line and mode line. */
- if (x < text_left_x && !s->row->mode_line_p)
+ if (s->area == TEXT_AREA
+ && x < text_left_x && !s->row->mode_line_p)
{
- int left_x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (s->w);
- int right_x = text_left_x;
-
- if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s->w))
- left_x += WINDOW_LEFT_FRINGE_WIDTH (s->w);
- else
- right_x -= WINDOW_LEFT_FRINGE_WIDTH (s->w);
-
- /* Adjust X and BACKGROUND_WIDTH to fit inside the space
- between LEFT_X and RIGHT_X. */
- if (x < left_x)
- {
- background_width -= left_x - x;
- x = left_x;
- }
- if (x + background_width > right_x)
- background_width = right_x - x;
+ background_width -= text_left_x - x;
+ x = text_left_x;
}
if (background_width > 0)
x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
@@ -3817,6 +4130,10 @@ x_draw_glyph_string (struct glyph_string *s)
if (!s->for_overlaps)
{
+ /* Draw relief if not yet drawn. */
+ if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
+ x_draw_glyph_string_box (s);
+
/* Draw underline. */
if (s->face->underline)
{
@@ -3972,10 +4289,6 @@ x_draw_glyph_string (struct glyph_string *s)
}
}
- /* Draw relief if not yet drawn. */
- if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
- x_draw_glyph_string_box (s);
-
if (s->prev)
{
struct glyph_string *prev;
@@ -4060,7 +4373,7 @@ x_delete_glyphs (struct frame *f, int n)
/* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
If they are <= 0, this is probably an error. */
-static ATTRIBUTE_UNUSED void
+MAYBE_UNUSED static void
x_clear_area1 (Display *dpy, Window window,
int x, int y, int width, int height, int exposures)
{
@@ -4153,6 +4466,8 @@ x_show_hourglass (struct frame *f)
XMapRaised (dpy, x->hourglass_window);
XFlush (dpy);
+ /* Ensure that the spinning hourglass is shown. */
+ flush_frame (f);
}
}
}
@@ -4416,6 +4731,99 @@ x_scroll_run (struct window *w, struct run *run)
/* Cursor off. Will be switched on again in gui_update_window_end. */
gui_clear_cursor (w);
+#ifdef HAVE_XWIDGETS
+ /* "Copy" xwidget windows in the area that will be scrolled. */
+ Display *dpy = FRAME_X_DISPLAY (f);
+ Window window = FRAME_X_WINDOW (f);
+
+ Window root, parent, *children;
+ unsigned int nchildren;
+
+ if (XQueryTree (dpy, window, &root, &parent, &children, &nchildren))
+ {
+ /* Now find xwidget views situated between from_y and to_y, and
+ attached to w. */
+ for (unsigned int i = 0; i < nchildren; ++i)
+ {
+ Window child = children[i];
+ struct xwidget_view *view = xwidget_view_from_window (child);
+
+ if (view && !view->hidden)
+ {
+ int window_y = view->y + view->clip_top;
+ int window_height = view->clip_bottom - view->clip_top;
+
+ Emacs_Rectangle r1, r2, result;
+ r1.x = w->pixel_left;
+ r1.y = from_y;
+ r1.width = w->pixel_width;
+ r1.height = height;
+ r2 = r1;
+ r2.y = window_y;
+ r2.height = window_height;
+
+ /* The window is offscreen, just unmap it. */
+ if (window_height == 0)
+ {
+ view->hidden = true;
+ XUnmapWindow (dpy, child);
+ continue;
+ }
+
+ bool intersects_p =
+ gui_intersect_rectangles (&r1, &r2, &result);
+
+ if (XWINDOW (view->w) == w && intersects_p)
+ {
+ int y = view->y + (to_y - from_y);
+ int text_area_x, text_area_y, text_area_width, text_area_height;
+ int clip_top, clip_bottom;
+
+ window_box (w, view->area, &text_area_x, &text_area_y,
+ &text_area_width, &text_area_height);
+
+ view->y = y;
+
+ clip_top = 0;
+ clip_bottom = XXWIDGET (view->model)->height;
+
+ if (y < text_area_y)
+ clip_top = text_area_y - y;
+
+ if ((y + clip_bottom) > (text_area_y + text_area_height))
+ {
+ clip_bottom -= (y + clip_bottom) - (text_area_y + text_area_height);
+ }
+
+ view->clip_top = clip_top;
+ view->clip_bottom = clip_bottom;
+
+ /* This means the view has moved offscreen. Unmap
+ it and hide it here. */
+ if ((view->clip_bottom - view->clip_top) <= 0)
+ {
+ view->hidden = true;
+ XUnmapWindow (dpy, child);
+ }
+ else
+ {
+ XMoveResizeWindow (dpy, child, view->x + view->clip_left,
+ view->y + view->clip_top,
+ view->clip_right - view->clip_left,
+ view->clip_bottom - view->clip_top);
+ cairo_xlib_surface_set_size (view->cr_surface,
+ view->clip_right - view->clip_left,
+ view->clip_bottom - view->clip_top);
+ }
+ xwidget_expose (view);
+ XFlush (dpy);
+ }
+ }
+ }
+ XFree (children);
+ }
+#endif
+
#ifdef USE_CAIRO
if (FRAME_CR_CONTEXT (f))
{
@@ -4589,8 +4997,9 @@ x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct fra
}
}
-/* Return the Emacs frame-object corresponding to an X window.
- It could be the frame's main window or an icon window. */
+/* Return the Emacs frame-object corresponding to an X window. It
+ could be the frame's main window, an icon window, or an xwidget
+ window. */
static struct frame *
x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
@@ -4601,6 +5010,13 @@ x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
if (wdesc == None)
return NULL;
+#ifdef HAVE_XWIDGETS
+ struct xwidget_view *xvw = xwidget_view_from_window (wdesc);
+
+ if (xvw && xvw->frame)
+ return xvw->frame;
+#endif
+
FOR_EACH_FRAME (tail, frame)
{
f = XFRAME (frame);
@@ -4692,7 +5108,16 @@ static struct frame *
x_menubar_window_to_frame (struct x_display_info *dpyinfo,
const XEvent *event)
{
- Window wdesc = event->xany.window;
+ Window wdesc;
+#ifdef HAVE_XINPUT2
+ if (event->type == GenericEvent
+ && dpyinfo->supports_xi2
+ && (event->xcookie.evtype == XI_ButtonPress
+ || event->xcookie.evtype == XI_ButtonRelease))
+ wdesc = ((XIDeviceEvent *) event->xcookie.data)->event;
+ else
+#endif
+ wdesc = event->xany.window;
Lisp_Object tail, frame;
struct frame *f;
struct x_output *x;
@@ -4795,6 +5220,37 @@ x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
}
break;
+#ifdef HAVE_XINPUT2
+ case GenericEvent:
+ {
+ XIEvent *xi_event = (XIEvent *) event;
+
+ struct frame *focus_frame = dpyinfo->x_focus_event_frame;
+ int focus_state
+ = focus_frame ? focus_frame->output_data.x->focus_state : 0;
+
+#ifdef USE_GTK
+ if (xi_event->evtype == XI_FocusIn
+ || xi_event->evtype == XI_FocusOut)
+ x_focus_changed ((xi_event->evtype == XI_FocusIn
+ ? FocusIn : FocusOut),
+ FOCUS_EXPLICIT,
+ dpyinfo, frame, bufp);
+ else
+#endif
+ if ((xi_event->evtype == XI_Enter
+ || xi_event->evtype == XI_Leave)
+ && (((XIEnterEvent *) xi_event)->detail
+ != XINotifyInferior)
+ && !(focus_state & FOCUS_EXPLICIT))
+ x_focus_changed ((xi_event->evtype == XI_Enter
+ ? FocusIn : FocusOut),
+ FOCUS_IMPLICIT,
+ dpyinfo, frame, bufp);
+ break;
+ }
+#endif
+
case FocusIn:
case FocusOut:
/* Ignore transient focus events from hotkeys, window manager
@@ -5023,7 +5479,7 @@ x_x_to_emacs_modifiers (struct x_display_info *dpyinfo, int state)
| ((state & dpyinfo->hyper_mod_mask) ? mod_hyper : 0));
}
-static int
+int
x_emacs_to_x_modifiers (struct x_display_info *dpyinfo, intmax_t state)
{
EMACS_INT mod_ctrl = ctrl_modifier;
@@ -7899,7 +8355,11 @@ mouse_or_wdesc_frame (struct x_display_info *dpyinfo, int wdesc)
static int
handle_one_xevent (struct x_display_info *dpyinfo,
+#ifndef HAVE_XINPUT2
const XEvent *event,
+#else
+ XEvent *event,
+#endif
int *finish, struct input_event *hold_quit)
{
union buffered_input_event inev;
@@ -7925,7 +8385,14 @@ handle_one_xevent (struct x_display_info *dpyinfo,
inev.ie.kind = NO_EVENT;
inev.ie.arg = Qnil;
- any = x_any_window_to_frame (dpyinfo, event->xany.window);
+#ifdef HAVE_XINPUT2
+ if (event->type != GenericEvent)
+#endif
+ any = x_any_window_to_frame (dpyinfo, event->xany.window);
+#ifdef HAVE_XINPUT2
+ else
+ any = NULL;
+#endif
if (any && any->wait_event_type == event->type)
any->wait_event_type = 0; /* Indicates we got it. */
@@ -8237,6 +8704,18 @@ handle_one_xevent (struct x_display_info *dpyinfo,
case Expose:
f = x_window_to_frame (dpyinfo, event->xexpose.window);
+#ifdef HAVE_XWIDGETS
+ {
+ struct xwidget_view *xv =
+ xwidget_view_from_window (event->xexpose.window);
+
+ if (xv)
+ {
+ xwidget_expose (xv);
+ goto OTHER;
+ }
+ }
+#endif
if (f)
{
if (!FRAME_VISIBLE_P (f))
@@ -8392,6 +8871,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
goto OTHER;
case MapNotify:
+#if defined HAVE_XINPUT2 && defined HAVE_GTK3
+ if (xg_is_menu_window (dpyinfo->display, event->xmap.window))
+ popup_activated_flag = 1;
+#endif
/* We use x_top_window_to_frame because map events can
come for sub-windows and they don't mean that the
frame is visible. */
@@ -8817,6 +9300,31 @@ handle_one_xevent (struct x_display_info *dpyinfo,
x_display_set_last_user_time (dpyinfo, event->xcrossing.time);
x_detect_focus_change (dpyinfo, any, event, &inev.ie);
+#ifdef HAVE_XWIDGETS
+ {
+ struct xwidget_view *xvw = xwidget_view_from_window (event->xcrossing.window);
+ Mouse_HLInfo *hlinfo;
+
+ if (xvw)
+ {
+ xwidget_motion_or_crossing (xvw, event);
+ hlinfo = MOUSE_HL_INFO (xvw->frame);
+
+ if (xvw->frame == hlinfo->mouse_face_mouse_frame)
+ {
+ clear_mouse_face (hlinfo);
+ hlinfo->mouse_face_mouse_frame = 0;
+ }
+
+ if (any_help_event_p)
+ {
+ do_help = -1;
+ }
+ goto OTHER;
+ }
+ }
+#endif
+
f = any;
if (f && x_mouse_click_focus_ignore_position)
@@ -8860,6 +9368,17 @@ handle_one_xevent (struct x_display_info *dpyinfo,
goto OTHER;
case LeaveNotify:
+#ifdef HAVE_XWIDGETS
+ {
+ struct xwidget_view *xvw = xwidget_view_from_window (event->xcrossing.window);
+
+ if (xvw)
+ {
+ xwidget_motion_or_crossing (xvw, event);
+ goto OTHER;
+ }
+ }
+#endif
x_display_set_last_user_time (dpyinfo, event->xcrossing.time);
x_detect_focus_change (dpyinfo, any, event, &inev.ie);
@@ -8910,6 +9429,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (f && xg_event_is_for_scrollbar (f, event))
f = 0;
#endif
+#ifdef HAVE_XWIDGETS
+ struct xwidget_view *xvw = xwidget_view_from_window (event->xmotion.window);
+
+ if (xvw)
+ xwidget_motion_or_crossing (xvw, event);
+#endif
if (f)
{
/* Maybe generate a SELECT_WINDOW_EVENT for
@@ -9164,8 +9689,27 @@ handle_one_xevent (struct x_display_info *dpyinfo,
case ButtonRelease:
case ButtonPress:
{
+#ifdef HAVE_XWIDGETS
+ struct xwidget_view *xvw = xwidget_view_from_window (event->xmotion.window);
+
+ if (xvw)
+ {
+ xwidget_button (xvw, event->type == ButtonPress,
+ event->xbutton.x, event->xbutton.y,
+ event->xbutton.button, event->xbutton.state,
+ event->xbutton.time);
+
+ if (!EQ (selected_window, xvw->w) && (event->xbutton.button < 4))
+ {
+ inev.ie.kind = SELECT_WINDOW_EVENT;
+ inev.ie.frame_or_window = xvw->w;
+ }
+ goto OTHER;
+ }
+#endif
/* If we decide we want to generate an event to be seen
by the rest of Emacs, we put it here. */
+ Lisp_Object tab_bar_arg = Qnil;
bool tab_bar_p = false;
bool tool_bar_p = false;
@@ -9214,8 +9758,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
window = window_from_coordinates (f, x, y, 0, true, true);
tab_bar_p = EQ (window, f->tab_bar_window);
- if (tab_bar_p && event->xbutton.button < 4)
- handle_tab_bar_click
+ if (tab_bar_p)
+ tab_bar_arg = handle_tab_bar_click
(f, x, y, event->xbutton.type == ButtonPress,
x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state));
}
@@ -9239,7 +9783,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
}
#endif /* !USE_GTK */
- if (!tab_bar_p && !tool_bar_p)
+ if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p)
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
if (! popup_activated ())
#endif
@@ -9257,6 +9801,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
}
else
x_construct_mouse_click (&inev.ie, &event->xbutton, f);
+
+ if (!NILP (tab_bar_arg))
+ inev.ie.arg = tab_bar_arg;
}
if (FRAME_X_EMBEDDED_P (f))
xembed_send_message (f, event->xbutton.time,
@@ -9359,6 +9906,11 @@ handle_one_xevent (struct x_display_info *dpyinfo,
x_find_modifier_meanings (dpyinfo);
FALLTHROUGH;
case MappingKeyboard:
+#ifdef HAVE_XKB
+ if (dpyinfo->xkb_desc)
+ XkbGetUpdatedMap (dpyinfo->display, XkbAllComponentsMask,
+ dpyinfo->xkb_desc);
+#endif
XRefreshKeyboardMapping ((XMappingEvent *) &event->xmapping);
}
goto OTHER;
@@ -9366,6 +9918,1107 @@ handle_one_xevent (struct x_display_info *dpyinfo,
case DestroyNotify:
xft_settings_event (dpyinfo, event);
break;
+#ifdef HAVE_XINPUT2
+ case GenericEvent:
+ {
+ if (!dpyinfo->supports_xi2)
+ goto OTHER;
+ if (event->xgeneric.extension != dpyinfo->xi2_opcode)
+ /* Not an XI2 event. */
+ goto OTHER;
+ bool must_free_data = false;
+ XIEvent *xi_event = (XIEvent *) event->xcookie.data;
+ /* Sometimes the event is already claimed by GTK, which
+ will free its data in due course. */
+ if (!xi_event && XGetEventData (dpyinfo->display, &event->xcookie))
+ {
+ must_free_data = true;
+ xi_event = (XIEvent *) event->xcookie.data;
+ }
+
+ XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
+ XILeaveEvent *leave = (XILeaveEvent *) xi_event;
+ XIEnterEvent *enter = (XIEnterEvent *) xi_event;
+ XIFocusInEvent *focusin = (XIFocusInEvent *) xi_event;
+ XIFocusOutEvent *focusout = (XIFocusOutEvent *) xi_event;
+ XIValuatorState *states;
+ double *values;
+ bool found_valuator = false;
+#ifdef HAVE_XWIDGETS
+ bool any_stop_p = false;
+#endif /* HAVE_XWIDGETS */
+
+ /* A fake XMotionEvent for x_note_mouse_movement. */
+ XMotionEvent ev;
+ /* A fake XButtonEvent for x_construct_mouse_click. */
+ XButtonEvent bv;
+
+ if (!xi_event)
+ {
+ eassert (!must_free_data);
+ goto OTHER;
+ }
+
+ switch (event->xcookie.evtype)
+ {
+ case XI_FocusIn:
+ any = x_any_window_to_frame (dpyinfo, focusin->event);
+#ifndef USE_GTK
+ /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap
+ minimized/iconified windows; thus, for those WMs we won't get
+ a MapNotify when unminimizing/deconifying. Check here if we
+ are deiconizing a window (Bug42655).
+
+ But don't do that on GTK since it may cause a plain invisible
+ frame get reported as iconified, compare
+ https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
+ That is fixed above but bites us here again. */
+ f = any;
+ if (f && FRAME_ICONIFIED_P (f))
+ {
+ SET_FRAME_VISIBLE (f, 1);
+ SET_FRAME_ICONIFIED (f, false);
+ f->output_data.x->has_been_visible = true;
+ inev.ie.kind = DEICONIFY_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ }
+#endif /* USE_GTK */
+ x_detect_focus_change (dpyinfo, any, event, &inev.ie);
+ goto XI_OTHER;
+ case XI_FocusOut:
+ any = x_any_window_to_frame (dpyinfo, focusout->event);
+ x_detect_focus_change (dpyinfo, any, event, &inev.ie);
+ goto XI_OTHER;
+ case XI_Enter:
+ any = x_any_window_to_frame (dpyinfo, enter->event);
+ ev.x = lrint (enter->event_x);
+ ev.y = lrint (enter->event_y);
+ ev.window = leave->event;
+
+ x_display_set_last_user_time (dpyinfo, xi_event->time);
+ x_detect_focus_change (dpyinfo, any, event, &inev.ie);
+
+ /* One problem behind the design of XInput 2 scrolling is
+ that valuators are not unique to each window, but only
+ the window that has grabbed the valuator's device or
+ the window that the device's pointer is on top of can
+ receive motion events. There is also no way to
+ retrieve the value of a valuator outside of each motion
+ event.
+
+ As such, to prevent wildly inaccurate results when the
+ valuators have changed outside Emacs, we reset our
+ records of each valuator's value whenever the pointer
+ re-enters a frame after its valuators have potentially
+ been changed elsewhere. */
+ if (enter->detail != XINotifyInferior
+ && enter->mode != XINotifyPassiveUngrab
+ && enter->mode != XINotifyUngrab && any)
+ xi_reset_scroll_valuators_for_device_id (dpyinfo, enter->deviceid);
+
+ f = any;
+
+ if (f && x_mouse_click_focus_ignore_position)
+ ignore_next_mouse_click_timeout = xi_event->time + 200;
+
+ /* EnterNotify counts as mouse movement,
+ so update things that depend on mouse position. */
+ if (f && !f->output_data.x->hourglass_p)
+ x_note_mouse_movement (f, &ev);
+#ifdef USE_GTK
+ /* We may get an EnterNotify on the buttons in the toolbar. In that
+ case we moved out of any highlighted area and need to note this. */
+ if (!f && dpyinfo->last_mouse_glyph_frame)
+ x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev);
+#endif
+ goto XI_OTHER;
+ case XI_Leave:
+ ev.x = lrint (leave->event_x);
+ ev.y = lrint (leave->event_y);
+ ev.window = leave->event;
+ any = x_any_window_to_frame (dpyinfo, leave->event);
+
+ x_display_set_last_user_time (dpyinfo, xi_event->time);
+ x_detect_focus_change (dpyinfo, any, event, &inev.ie);
+
+ f = x_top_window_to_frame (dpyinfo, leave->event);
+ if (f)
+ {
+ if (f == hlinfo->mouse_face_mouse_frame)
+ {
+ /* If we move outside the frame, then we're
+ certainly no longer on any text in the frame. */
+ clear_mouse_face (hlinfo);
+ hlinfo->mouse_face_mouse_frame = 0;
+ }
+
+ /* Generate a nil HELP_EVENT to cancel a help-echo.
+ Do it only if there's something to cancel.
+ Otherwise, the startup message is cleared when
+ the mouse leaves the frame. */
+ if (any_help_event_p)
+ do_help = -1;
+ }
+#ifdef USE_GTK
+ /* See comment in EnterNotify above */
+ else if (dpyinfo->last_mouse_glyph_frame)
+ x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev);
+#endif
+ goto XI_OTHER;
+ case XI_Motion:
+ {
+ struct xi_device_t *device;
+
+ states = &xev->valuators;
+ values = states->values;
+ device = xi_device_from_id (dpyinfo, xev->deviceid);
+
+ if (!device || !device->master_p)
+ goto XI_OTHER;
+
+#ifdef XI_TouchBegin
+ if (xev->flags & XIPointerEmulated
+ && dpyinfo->xi2_version >= 2)
+ goto XI_OTHER;
+#endif
+
+ x_display_set_last_user_time (dpyinfo, xi_event->time);
+
+#ifdef HAVE_XWIDGETS
+ struct xwidget_view *xv = xwidget_view_from_window (xev->event);
+ double xv_total_x = 0.0;
+ double xv_total_y = 0.0;
+#endif
+
+ for (int i = 0; i < states->mask_len * 8; i++)
+ {
+ if (XIMaskIsSet (states->mask, i))
+ {
+ struct xi_scroll_valuator_t *val;
+ double delta, scroll_unit;
+ int scroll_height;
+ Lisp_Object window;
+
+
+ /* See the comment on top of
+ x_init_master_valuators for more details on how
+ scroll wheel movement is reported on XInput 2. */
+ delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid,
+ i, *values, &val);
+
+ if (delta != DBL_MAX)
+ {
+#ifdef HAVE_XWIDGETS
+ if (xv)
+ {
+ if (val->horizontal)
+ xv_total_x += delta;
+ else
+ xv_total_y += delta;
+
+ found_valuator = true;
+
+ if (delta == 0.0)
+ any_stop_p = true;
+
+ continue;
+ }
+#endif
+ if (!f)
+ {
+ f = x_any_window_to_frame (dpyinfo, xev->event);
+
+ if (!f)
+ goto XI_OTHER;
+ }
+
+ found_valuator = true;
+
+ if (signbit (delta) != signbit (val->emacs_value))
+ val->emacs_value = 0;
+
+ val->emacs_value += delta;
+
+ if (mwheel_coalesce_scroll_events
+ && (fabs (val->emacs_value) < 1)
+ && (fabs (delta) > 0))
+ continue;
+
+ bool s = signbit (val->emacs_value);
+ inev.ie.kind = (fabs (delta) > 0
+ ? (val->horizontal
+ ? HORIZ_WHEEL_EVENT
+ : WHEEL_EVENT)
+ : TOUCH_END_EVENT);
+ inev.ie.timestamp = xev->time;
+
+ XSETINT (inev.ie.x, lrint (xev->event_x));
+ XSETINT (inev.ie.y, lrint (xev->event_y));
+ XSETFRAME (inev.ie.frame_or_window, f);
+
+ if (fabs (delta) > 0)
+ {
+ inev.ie.modifiers = !s ? up_modifier : down_modifier;
+ inev.ie.modifiers
+ |= x_x_to_emacs_modifiers (dpyinfo,
+ xev->mods.effective);
+ }
+
+ window = window_from_coordinates (f, xev->event_x,
+ xev->event_y, NULL,
+ false, false);
+
+ if (WINDOWP (window))
+ scroll_height = XWINDOW (window)->pixel_height;
+ else
+ /* EVENT_X and EVENT_Y can be outside the
+ frame if F holds the input grab, so fall
+ back to the height of the frame instead. */
+ scroll_height = FRAME_PIXEL_HEIGHT (f);
+
+ scroll_unit = pow (scroll_height, 2.0 / 3.0);
+
+ if (NUMBERP (Vx_scroll_event_delta_factor))
+ scroll_unit *= XFLOATINT (Vx_scroll_event_delta_factor);
+
+ if (fabs (delta) > 0)
+ {
+ if (val->horizontal)
+ {
+ inev.ie.arg
+ = list3 (Qnil,
+ make_float (val->emacs_value
+ * scroll_unit),
+ make_float (0));
+ }
+ else
+ {
+ inev.ie.arg = list3 (Qnil, make_float (0),
+ make_float (val->emacs_value
+ * scroll_unit));
+ }
+ }
+ else
+ {
+ inev.ie.arg = Qnil;
+ }
+
+ kbd_buffer_store_event_hold (&inev.ie, hold_quit);
+
+ val->emacs_value = 0;
+ }
+ values++;
+ }
+
+ inev.ie.kind = NO_EVENT;
+ }
+
+#ifdef HAVE_XWIDGETS
+ if (xv)
+ {
+ if (found_valuator)
+ xwidget_scroll (xv, xev->event_x, xev->event_y,
+ xv_total_x, xv_total_y, xev->mods.effective,
+ xev->time, any_stop_p);
+ else
+ xwidget_motion_notify (xv, xev->event_x, xev->event_y,
+ xev->mods.effective, xev->time);
+
+ goto XI_OTHER;
+ }
+#endif
+ if (found_valuator)
+ goto XI_OTHER;
+
+ ev.x = lrint (xev->event_x);
+ ev.y = lrint (xev->event_y);
+ ev.window = xev->event;
+ ev.time = xev->time;
+
+ previous_help_echo_string = help_echo_string;
+ help_echo_string = Qnil;
+
+ if (hlinfo->mouse_face_hidden)
+ {
+ hlinfo->mouse_face_hidden = false;
+ clear_mouse_face (hlinfo);
+ }
+
+ f = mouse_or_wdesc_frame (dpyinfo, xev->event);
+
+#ifdef USE_GTK
+ if (f && xg_event_is_for_scrollbar (f, event))
+ f = 0;
+#endif
+ if (f)
+ {
+ /* Maybe generate a SELECT_WINDOW_EVENT for
+ `mouse-autoselect-window' but don't let popup menus
+ interfere with this (Bug#1261). */
+ if (!NILP (Vmouse_autoselect_window)
+ && !popup_activated ()
+ /* Don't switch if we're currently in the minibuffer.
+ This tries to work around problems where the
+ minibuffer gets unselected unexpectedly, and where
+ you then have to move your mouse all the way down to
+ the minibuffer to select it. */
+ && !MINI_WINDOW_P (XWINDOW (selected_window))
+ /* With `focus-follows-mouse' non-nil create an event
+ also when the target window is on another frame. */
+ && (f == XFRAME (selected_frame)
+ || !NILP (focus_follows_mouse)))
+ {
+ static Lisp_Object last_mouse_window;
+ Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false);
+
+ /* A window will be autoselected only when it is not
+ selected now and the last mouse movement event was
+ not in it. The remainder of the code is a bit vague
+ wrt what a "window" is. For immediate autoselection,
+ the window is usually the entire window but for GTK
+ where the scroll bars don't count. For delayed
+ autoselection the window is usually the window's text
+ area including the margins. */
+ if (WINDOWP (window)
+ && !EQ (window, last_mouse_window)
+ && !EQ (window, selected_window))
+ {
+ inev.ie.kind = SELECT_WINDOW_EVENT;
+ inev.ie.frame_or_window = window;
+ }
+
+ /* Remember the last window where we saw the mouse. */
+ last_mouse_window = window;
+ }
+
+ if (!x_note_mouse_movement (f, &ev))
+ help_echo_string = previous_help_echo_string;
+ }
+ else
+ {
+#ifndef USE_TOOLKIT_SCROLL_BARS
+ struct scroll_bar *bar
+ = x_window_to_scroll_bar (xi_event->display, xev->event, 2);
+
+ if (bar)
+ x_scroll_bar_note_movement (bar, &ev);
+#endif /* USE_TOOLKIT_SCROLL_BARS */
+
+ /* If we move outside the frame, then we're
+ certainly no longer on any text in the frame. */
+ clear_mouse_face (hlinfo);
+ }
+
+ /* If the contents of the global variable help_echo_string
+ has changed, generate a HELP_EVENT. */
+ if (!NILP (help_echo_string)
+ || !NILP (previous_help_echo_string))
+ do_help = 1;
+ goto XI_OTHER;
+ }
+ case XI_ButtonRelease:
+ case XI_ButtonPress:
+ {
+ /* If we decide we want to generate an event to be seen
+ by the rest of Emacs, we put it here. */
+ Lisp_Object tab_bar_arg = Qnil;
+ bool tab_bar_p = false;
+ bool tool_bar_p = false;
+ struct xi_device_t *device;
+
+#ifdef XIPointerEmulated
+ /* Ignore emulated scroll events when XI2 native
+ scroll events are present. */
+ if (dpyinfo->xi2_version >= 1
+ && xev->detail >= 4
+ && xev->detail <= 8
+ && xev->flags & XIPointerEmulated)
+ {
+ *finish = X_EVENT_DROP;
+ goto XI_OTHER;
+ }
+#endif
+
+ device = xi_device_from_id (dpyinfo, xev->deviceid);
+
+ if (!device || !device->master_p)
+ goto XI_OTHER;
+
+ bv.button = xev->detail;
+ bv.type = xev->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease;
+ bv.x = lrint (xev->event_x);
+ bv.y = lrint (xev->event_y);
+ bv.window = xev->event;
+ bv.state = xev->mods.effective;
+ bv.time = xev->time;
+
+ memset (&compose_status, 0, sizeof (compose_status));
+ dpyinfo->last_mouse_glyph_frame = NULL;
+ x_display_set_last_user_time (dpyinfo, xev->time);
+
+ f = mouse_or_wdesc_frame (dpyinfo, xev->event);
+
+ if (f && xev->evtype == XI_ButtonPress
+ && !popup_activated ()
+ && !x_window_to_scroll_bar (xev->display, xev->event, 2)
+ && !FRAME_NO_ACCEPT_FOCUS (f))
+ {
+ /* When clicking into a child frame or when clicking
+ into a parent frame with the child frame selected and
+ `no-accept-focus' is not set, select the clicked
+ frame. */
+ struct frame *hf = dpyinfo->highlight_frame;
+
+ if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf)))
+ {
+ block_input ();
+ XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
+ RevertToParent, CurrentTime);
+ if (FRAME_PARENT_FRAME (f))
+ XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
+ unblock_input ();
+ }
+ }
+
+#ifdef USE_GTK
+ if (f && xg_event_is_for_scrollbar (f, event))
+ f = 0;
+#endif
+
+ if (f)
+ {
+ /* Is this in the tab-bar? */
+ if (WINDOWP (f->tab_bar_window)
+ && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
+ {
+ Lisp_Object window;
+ int x = bv.x;
+ int y = bv.y;
+
+ window = window_from_coordinates (f, x, y, 0, true, true);
+ tab_bar_p = EQ (window, f->tab_bar_window);
+
+ if (tab_bar_p)
+ tab_bar_arg = handle_tab_bar_click
+ (f, x, y, xev->evtype == XI_ButtonPress,
+ x_x_to_emacs_modifiers (dpyinfo, bv.state));
+ }
+
+#if ! defined (USE_GTK)
+ /* Is this in the tool-bar? */
+ if (WINDOWP (f->tool_bar_window)
+ && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
+ {
+ Lisp_Object window;
+ int x = bv.x;
+ int y = bv.y;
+
+ window = window_from_coordinates (f, x, y, 0, true, true);
+ tool_bar_p = EQ (window, f->tool_bar_window);
+
+ if (tool_bar_p && xev->detail < 4)
+ handle_tool_bar_click
+ (f, x, y, xev->evtype == XI_ButtonPress,
+ x_x_to_emacs_modifiers (dpyinfo, bv.state));
+ }
+#endif /* !USE_GTK */
+
+ if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
+ if (! popup_activated ())
+#endif
+ {
+ if (ignore_next_mouse_click_timeout)
+ {
+ if (xev->evtype == XI_ButtonPress
+ && xev->time > ignore_next_mouse_click_timeout)
+ {
+ ignore_next_mouse_click_timeout = 0;
+ x_construct_mouse_click (&inev.ie, &bv, f);
+ }
+ if (xev->evtype == XI_ButtonRelease)
+ ignore_next_mouse_click_timeout = 0;
+ }
+ else
+ x_construct_mouse_click (&inev.ie, &bv, f);
+
+ if (!NILP (tab_bar_arg))
+ inev.ie.arg = tab_bar_arg;
+ }
+ if (FRAME_X_EMBEDDED_P (f))
+ xembed_send_message (f, xev->time,
+ XEMBED_REQUEST_FOCUS, 0, 0, 0);
+ }
+
+ if (xev->evtype == XI_ButtonPress)
+ {
+ dpyinfo->grabbed |= (1 << xev->detail);
+ device->grab |= (1 << xev->detail);
+ dpyinfo->last_mouse_frame = f;
+ if (f && !tab_bar_p)
+ f->last_tab_bar_item = -1;
+#if ! defined (USE_GTK)
+ if (f && !tool_bar_p)
+ f->last_tool_bar_item = -1;
+#endif /* not USE_GTK */
+
+ }
+ else
+ {
+ dpyinfo->grabbed &= ~(1 << xev->detail);
+ device->grab &= ~(1 << xev->detail);
+ }
+
+ xi_grab_or_ungrab_device (device, dpyinfo, xev->event);
+
+ if (f)
+ f->mouse_moved = false;
+
+#if defined (USE_GTK)
+ /* No Xt toolkit currently available has support for XI2.
+ So the code here assumes use of GTK. */
+ f = x_menubar_window_to_frame (dpyinfo, event);
+ if (f /* Gtk+ menus only react to the first three buttons. */
+ && xev->detail < 3)
+ {
+ /* What is done with Core Input ButtonPressed is not
+ possible here, because GenericEvents cannot be saved. */
+ bool was_waiting_for_input = waiting_for_input;
+ /* This hack was adopted from the NS port. Whether
+ or not it is actually safe is a different story
+ altogether. */
+ if (waiting_for_input)
+ waiting_for_input = 0;
+ set_frame_menubar (f, true);
+ waiting_for_input = was_waiting_for_input;
+ }
+#endif
+ goto XI_OTHER;
+ }
+ case XI_KeyPress:
+ {
+ int state = xev->mods.effective;
+ Lisp_Object c;
+#ifdef HAVE_XKB
+ unsigned int mods_rtrn;
+#endif
+ int keycode = xev->detail;
+ KeySym keysym;
+ char copy_buffer[81];
+ char *copy_bufptr = copy_buffer;
+ unsigned char *copy_ubufptr;
+ int copy_bufsiz = sizeof (copy_buffer);
+ ptrdiff_t i;
+ int nchars, len;
+ struct xi_device_t *device;
+
+ device = xi_device_from_id (dpyinfo, xev->deviceid);
+
+ if (!device || !device->master_p)
+ goto XI_OTHER;
+
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
+ /* Dispatch XI_KeyPress events when in menu. */
+ if (popup_activated ())
+ goto XI_OTHER;
+#endif
+
+#ifdef HAVE_X_I18N
+ XKeyPressedEvent xkey;
+
+ memset (&xkey, 0, sizeof xkey);
+
+ xkey.type = KeyPress;
+ xkey.serial = xev->serial;
+ xkey.send_event = xev->send_event;
+ xkey.display = xev->display;
+ xkey.window = xev->event;
+ xkey.root = xev->root;
+ xkey.subwindow = xev->child;
+ xkey.time = xev->time;
+ xkey.state = xev->mods.effective;
+ xkey.keycode = xev->detail;
+ xkey.same_screen = True;
+
+ if (x_filter_event (dpyinfo, (XEvent *) &xkey))
+ {
+ *finish = X_EVENT_DROP;
+ goto XI_OTHER;
+ }
+#endif
+
+#ifdef HAVE_XKB
+ if (dpyinfo->xkb_desc)
+ {
+ if (!XkbTranslateKeyCode (dpyinfo->xkb_desc, keycode,
+ state, &mods_rtrn, &keysym))
+ goto XI_OTHER;
+ }
+ else
+ {
+#endif
+ int keysyms_per_keycode_return;
+ KeySym *ksms = XGetKeyboardMapping (dpyinfo->display, keycode, 1,
+ &keysyms_per_keycode_return);
+ if (!(keysym = ksms[0]))
+ {
+ XFree (ksms);
+ goto XI_OTHER;
+ }
+ XFree (ksms);
+#ifdef HAVE_XKB
+ }
+#endif
+
+ if (keysym == NoSymbol)
+ goto XI_OTHER;
+
+ x_display_set_last_user_time (dpyinfo, xev->time);
+ ignore_next_mouse_click_timeout = 0;
+
+ f = x_any_window_to_frame (dpyinfo, xev->event);
+
+ /* If mouse-highlight is an integer, input clears out
+ mouse highlighting. */
+ if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight)
+ && (f == 0
+#if ! defined (USE_GTK)
+ || !EQ (f->tool_bar_window, hlinfo->mouse_face_window)
+#endif
+ || !EQ (f->tab_bar_window, hlinfo->mouse_face_window))
+ )
+ {
+ clear_mouse_face (hlinfo);
+ hlinfo->mouse_face_hidden = true;
+ }
+
+ if (f != 0)
+ {
+#ifdef USE_GTK
+ /* Don't pass keys to GTK. A Tab will shift focus to the
+ tool bar in GTK 2.4. Keys will still go to menus and
+ dialogs because in that case popup_activated is nonzero
+ (see above). */
+ *finish = X_EVENT_DROP;
+#endif
+ /* If not using XIM/XIC, and a compose sequence is in progress,
+ we break here. Otherwise, chars_matched is always 0. */
+ if (compose_status.chars_matched > 0 && nbytes == 0)
+ goto XI_OTHER;
+
+ memset (&compose_status, 0, sizeof (compose_status));
+
+ XSETFRAME (inev.ie.frame_or_window, f);
+ inev.ie.modifiers
+ = x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), state);
+ inev.ie.timestamp = xev->time;
+
+#ifdef HAVE_X_I18N
+ if (FRAME_XIC (f))
+ {
+ Status status_return;
+ nbytes = XmbLookupString (FRAME_XIC (f),
+ &xkey, (char *) copy_bufptr,
+ copy_bufsiz, &keysym,
+ &status_return);
+
+ if (status_return == XBufferOverflow)
+ {
+ copy_bufsiz = nbytes + 1;
+ copy_bufptr = alloca (copy_bufsiz);
+ nbytes = XmbLookupString (FRAME_XIC (f),
+ &xkey, (char *) copy_bufptr,
+ copy_bufsiz, &keysym,
+ &status_return);
+ }
+
+ if (status_return == XLookupNone)
+ goto xi_done_keysym;
+ else if (status_return == XLookupChars)
+ {
+ keysym = NoSymbol;
+ state = 0;
+ }
+ else if (status_return != XLookupKeySym
+ && status_return != XLookupBoth)
+ emacs_abort ();
+ }
+ else
+#endif
+ {
+#ifdef HAVE_XKB
+ int overflow = 0;
+ KeySym sym = keysym;
+
+ if (dpyinfo->xkb_desc)
+ {
+ nbytes = XkbTranslateKeySym (dpyinfo->display, &sym,
+ state & ~mods_rtrn, copy_bufptr,
+ copy_bufsiz, &overflow);
+ if (overflow)
+ {
+ copy_bufptr = alloca ((copy_bufsiz += overflow)
+ * sizeof *copy_bufptr);
+ overflow = 0;
+ nbytes = XkbTranslateKeySym (dpyinfo->display, &sym,
+ state & ~mods_rtrn, copy_bufptr,
+ copy_bufsiz, &overflow);
+
+ if (overflow)
+ nbytes = 0;
+ }
+ }
+ else
+#endif
+ {
+ nbytes = XLookupString (&xkey, copy_bufptr,
+ copy_bufsiz, &keysym,
+ &compose_status);
+ }
+ }
+
+ /* First deal with keysyms which have defined
+ translations to characters. */
+ if (keysym >= 32 && keysym < 128)
+ /* Avoid explicitly decoding each ASCII character. */
+ {
+ inev.ie.kind = ASCII_KEYSTROKE_EVENT;
+ inev.ie.code = keysym;
+
+ goto xi_done_keysym;
+ }
+
+ /* Keysyms directly mapped to Unicode characters. */
+ if (keysym >= 0x01000000 && keysym <= 0x0110FFFF)
+ {
+ if (keysym < 0x01000080)
+ inev.ie.kind = ASCII_KEYSTROKE_EVENT;
+ else
+ inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+ inev.ie.code = keysym & 0xFFFFFF;
+ goto xi_done_keysym;
+ }
+
+ /* Now non-ASCII. */
+ if (HASH_TABLE_P (Vx_keysym_table)
+ && (c = Fgethash (make_fixnum (keysym),
+ Vx_keysym_table,
+ Qnil),
+ FIXNATP (c)))
+ {
+ inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c))
+ ? ASCII_KEYSTROKE_EVENT
+ : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+ inev.ie.code = XFIXNAT (c);
+ goto xi_done_keysym;
+ }
+
+ /* Random non-modifier sorts of keysyms. */
+ if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
+ || keysym == XK_Delete
+#ifdef XK_ISO_Left_Tab
+ || (keysym >= XK_ISO_Left_Tab
+ && keysym <= XK_ISO_Enter)
+#endif
+ || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */
+ || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */
+#ifdef HPUX
+ /* This recognizes the "extended function
+ keys". It seems there's no cleaner way.
+ Test IsModifierKey to avoid handling
+ mode_switch incorrectly. */
+ || (XK_Select <= keysym && keysym < XK_KP_Space)
+#endif
+#ifdef XK_dead_circumflex
+ || keysym == XK_dead_circumflex
+#endif
+#ifdef XK_dead_grave
+ || keysym == XK_dead_grave
+#endif
+#ifdef XK_dead_tilde
+ || keysym == XK_dead_tilde
+#endif
+#ifdef XK_dead_diaeresis
+ || keysym == XK_dead_diaeresis
+#endif
+#ifdef XK_dead_macron
+ || keysym == XK_dead_macron
+#endif
+#ifdef XK_dead_degree
+ || keysym == XK_dead_degree
+#endif
+#ifdef XK_dead_acute
+ || keysym == XK_dead_acute
+#endif
+#ifdef XK_dead_cedilla
+ || keysym == XK_dead_cedilla
+#endif
+#ifdef XK_dead_breve
+ || keysym == XK_dead_breve
+#endif
+#ifdef XK_dead_ogonek
+ || keysym == XK_dead_ogonek
+#endif
+#ifdef XK_dead_caron
+ || keysym == XK_dead_caron
+#endif
+#ifdef XK_dead_doubleacute
+ || keysym == XK_dead_doubleacute
+#endif
+#ifdef XK_dead_abovedot
+ || keysym == XK_dead_abovedot
+#endif
+ || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
+ || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
+ /* Any "vendor-specific" key is ok. */
+ || (keysym & (1 << 28))
+ || (keysym != NoSymbol && nbytes == 0))
+ && ! (IsModifierKey (keysym)
+ /* The symbols from XK_ISO_Lock
+ to XK_ISO_Last_Group_Lock
+ don't have real modifiers but
+ should be treated similarly to
+ Mode_switch by Emacs. */
+#if defined XK_ISO_Lock && defined XK_ISO_Last_Group_Lock
+ || (XK_ISO_Lock <= keysym
+ && keysym <= XK_ISO_Last_Group_Lock)
+#endif
+ ))
+ {
+ STORE_KEYSYM_FOR_DEBUG (keysym);
+ /* make_lispy_event will convert this to a symbolic
+ key. */
+ inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
+ inev.ie.code = keysym;
+ goto xi_done_keysym;
+ }
+
+ for (i = 0, nchars = 0; i < nbytes; i++)
+ {
+ if (ASCII_CHAR_P (copy_bufptr[i]))
+ nchars++;
+ STORE_KEYSYM_FOR_DEBUG (copy_bufptr[i]);
+ }
+
+ if (nchars < nbytes)
+ {
+ /* Decode the input data. */
+
+ setup_coding_system (Vlocale_coding_system, &coding);
+ coding.src_multibyte = false;
+ coding.dst_multibyte = true;
+ /* The input is converted to events, thus we can't
+ handle composition. Anyway, there's no XIM that
+ gives us composition information. */
+ coding.common_flags &= ~CODING_ANNOTATION_MASK;
+
+ SAFE_NALLOCA (coding.destination, MAX_MULTIBYTE_LENGTH,
+ nbytes);
+ coding.dst_bytes = MAX_MULTIBYTE_LENGTH * nbytes;
+ coding.mode |= CODING_MODE_LAST_BLOCK;
+ decode_coding_c_string (&coding, (unsigned char *) copy_bufptr,
+ nbytes, Qnil);
+ nbytes = coding.produced;
+ nchars = coding.produced_char;
+ copy_bufptr = (char *) coding.destination;
+ }
+
+ copy_ubufptr = (unsigned char *) copy_bufptr;
+
+ /* Convert the input data to a sequence of
+ character events. */
+ for (i = 0; i < nbytes; i += len)
+ {
+ int ch;
+ if (nchars == nbytes)
+ ch = copy_ubufptr[i], len = 1;
+ else
+ ch = string_char_and_length (copy_ubufptr + i, &len);
+ inev.ie.kind = (SINGLE_BYTE_CHAR_P (ch)
+ ? ASCII_KEYSTROKE_EVENT
+ : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+ inev.ie.code = ch;
+ kbd_buffer_store_buffered_event (&inev, hold_quit);
+ }
+
+ inev.ie.kind = NO_EVENT;
+ goto xi_done_keysym;
+ }
+ goto XI_OTHER;
+ }
+ case XI_KeyRelease:
+ x_display_set_last_user_time (dpyinfo, xev->time);
+#ifdef HAVE_X_I18N
+ XKeyPressedEvent xkey;
+
+ memset (&xkey, 0, sizeof xkey);
+
+ xkey.type = KeyRelease;
+ xkey.serial = xev->serial;
+ xkey.send_event = xev->send_event;
+ xkey.display = xev->display;
+ xkey.window = xev->event;
+ xkey.root = xev->root;
+ xkey.subwindow = xev->child;
+ xkey.time = xev->time;
+ xkey.state = xev->mods.effective;
+ xkey.keycode = xev->detail;
+ xkey.same_screen = True;
+
+ x_filter_event (dpyinfo, (XEvent *) &xkey);
+#endif
+ goto XI_OTHER;
+ case XI_PropertyEvent:
+ case XI_HierarchyChanged:
+ case XI_DeviceChanged:
+ x_init_master_valuators (dpyinfo);
+ goto XI_OTHER;
+#ifdef XI_TouchBegin
+ case XI_TouchBegin:
+ {
+ struct xi_device_t *device;
+ device = xi_device_from_id (dpyinfo, xev->deviceid);
+
+ if (!device)
+ goto XI_OTHER;
+
+ if (xi_find_touch_point (device, xev->detail))
+ emacs_abort ();
+
+ f = x_any_window_to_frame (dpyinfo, xev->event);
+
+ if (f && device->direct_p)
+ {
+ x_catch_errors (dpyinfo->display);
+ XIAllowTouchEvents (dpyinfo->display, xev->deviceid,
+ xev->detail, xev->event, XIAcceptTouch);
+ if (!x_had_errors_p (dpyinfo->display))
+ {
+ xi_link_touch_point (device, xev->detail, xev->event_x,
+ xev->event_y);
+
+#ifdef HAVE_GTK3
+ if (FRAME_X_OUTPUT (f)->menubar_widget
+ && xg_event_is_for_menubar (f, event))
+ {
+ bool was_waiting_for_input = waiting_for_input;
+ /* This hack was adopted from the NS port. Whether
+ or not it is actually safe is a different story
+ altogether. */
+ if (waiting_for_input)
+ waiting_for_input = 0;
+ set_frame_menubar (f, true);
+ waiting_for_input = was_waiting_for_input;
+ }
+#endif
+
+ inev.ie.kind = TOUCHSCREEN_BEGIN_EVENT;
+ inev.ie.timestamp = xev->time;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ XSETINT (inev.ie.x, lrint (xev->event_x));
+ XSETINT (inev.ie.y, lrint (xev->event_y));
+ XSETINT (inev.ie.arg, xev->detail);
+ }
+ x_uncatch_errors_after_check ();
+ }
+ else
+ {
+ x_catch_errors (dpyinfo->display);
+ XIAllowTouchEvents (dpyinfo->display, xev->deviceid,
+ xev->detail, xev->event, XIRejectTouch);
+ x_uncatch_errors ();
+ }
+
+ goto XI_OTHER;
+ }
+ case XI_TouchUpdate:
+ {
+ struct xi_device_t *device;
+ struct xi_touch_point_t *touchpoint;
+ Lisp_Object arg = Qnil;
+
+ device = xi_device_from_id (dpyinfo, xev->deviceid);
+
+ if (!device)
+ goto XI_OTHER;
+
+ touchpoint = xi_find_touch_point (device, xev->detail);
+
+ if (!touchpoint)
+ goto XI_OTHER;
+
+ touchpoint->x = xev->event_x;
+ touchpoint->y = xev->event_y;
+
+ f = x_any_window_to_frame (dpyinfo, xev->event);
+
+ if (f && device->direct_p)
+ {
+ inev.ie.kind = TOUCHSCREEN_UPDATE_EVENT;
+ inev.ie.timestamp = xev->time;
+ XSETFRAME (inev.ie.frame_or_window, f);
+
+ for (touchpoint = device->touchpoints;
+ touchpoint; touchpoint = touchpoint->next)
+ {
+ arg = Fcons (list3i (lrint (touchpoint->x),
+ lrint (touchpoint->y),
+ lrint (touchpoint->number)),
+ arg);
+ }
+
+ inev.ie.arg = arg;
+ }
+
+ goto XI_OTHER;
+ }
+ case XI_TouchEnd:
+ {
+ struct xi_device_t *device;
+ bool unlinked_p;
+
+ device = xi_device_from_id (dpyinfo, xev->deviceid);
+
+ if (!device)
+ goto XI_OTHER;
+
+ unlinked_p = xi_unlink_touch_point (xev->detail, device);
+
+ if (unlinked_p)
+ {
+ f = x_any_window_to_frame (dpyinfo, xev->event);
+
+ if (f && device->direct_p)
+ {
+ inev.ie.kind = TOUCHSCREEN_END_EVENT;
+ inev.ie.timestamp = xev->time;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ XSETINT (inev.ie.x, lrint (xev->event_x));
+ XSETINT (inev.ie.y, lrint (xev->event_y));
+ XSETINT (inev.ie.arg, xev->detail);
+ }
+ }
+
+ goto XI_OTHER;
+ }
+#endif
+ default:
+ goto XI_OTHER;
+ }
+ xi_done_keysym:
+#ifdef HAVE_X_I18N
+ if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
+ xic_set_statusarea (f);
+#endif
+ if (must_free_data)
+ XFreeEventData (dpyinfo->display, &event->xcookie);
+ goto done_keysym;
+ XI_OTHER:
+ if (must_free_data)
+ XFreeEventData (dpyinfo->display, &event->xcookie);
+ goto OTHER;
+ }
+#endif
default:
OTHER:
@@ -10140,8 +11793,9 @@ x_connection_closed (Display *dpy, const char *error_message, bool ioerror)
frame on it. */
dpyinfo->reference_count++;
dpyinfo->terminal->reference_count++;
+ if (ioerror)
+ dpyinfo->display = 0;
}
- if (ioerror) dpyinfo->display = 0;
/* First delete frames whose mini-buffers are on frames
that are on the dead display. */
@@ -11570,6 +13224,13 @@ x_lower_frame (struct frame *f)
XFlush (FRAME_X_DISPLAY (f));
unblock_input ();
}
+#ifdef HAVE_XWIDGETS
+ /* Make sure any X windows owned by xwidget views of the parent
+ still display below the lowered frame. */
+
+ if (FRAME_PARENT_FRAME (f))
+ lower_frame_xwidget_views (FRAME_PARENT_FRAME (f));
+#endif
}
static void
@@ -12129,6 +13790,10 @@ x_free_frame_resources (struct frame *f)
xfree (f->shell_position);
#else /* !USE_X_TOOLKIT */
+#ifdef HAVE_XWIDGETS
+ kill_frame_xwidget_views (f);
+#endif
+
#ifdef USE_GTK
xg_free_frame_widgets (f);
#endif /* USE_GTK */
@@ -13035,6 +14700,40 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
dpyinfo->supports_xdbe = true;
#endif
+#ifdef HAVE_XINPUT2
+ dpyinfo->supports_xi2 = false;
+ int rc;
+ int major = 2;
+#ifdef XI_BarrierHit /* XInput 2.3 */
+ int minor = 3;
+#elif defined XI_TouchBegin /* XInput 2.2 */
+ int minor = 2;
+#elif defined XIScrollClass /* XInput 2.1 */
+ int minor = 1;
+#else /* Some old version of XI2 we're not interested in. */
+ int minor = 0;
+#endif
+ int fer, fee;
+
+ if (XQueryExtension (dpyinfo->display, "XInputExtension",
+ &dpyinfo->xi2_opcode, &fer, &fee))
+ {
+ rc = XIQueryVersion (dpyinfo->display, &major, &minor);
+ if (rc == Success)
+ {
+ dpyinfo->supports_xi2 = true;
+ x_init_master_valuators (dpyinfo);
+ }
+ }
+ dpyinfo->xi2_version = minor;
+#endif
+
+#ifdef HAVE_XKB
+ dpyinfo->xkb_desc = XkbGetMap (dpyinfo->display,
+ XkbAllComponentsMask,
+ XkbUseCoreKbd);
+#endif
+
#if defined USE_CAIRO || defined HAVE_XFT
{
/* If we are using Xft, the following precautions should be made:
@@ -13467,6 +15166,14 @@ x_delete_terminal (struct terminal *terminal)
XrmDestroyDatabase (dpyinfo->rdb);
#endif
+#ifdef HAVE_XKB
+ if (dpyinfo->xkb_desc)
+ XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True);
+#endif
+#ifdef HAVE_XINPUT2
+ if (dpyinfo->supports_xi2)
+ x_free_xi_devices (dpyinfo);
+#endif
#ifdef USE_GTK
xg_display_close (dpyinfo->display);
#else
@@ -13626,9 +15333,12 @@ x_initialize (void)
void
init_xterm (void)
{
- /* Emacs can handle only core input events, so make sure
- Gtk doesn't use Xinput or Xinput2 extensions. */
+#ifndef HAVE_XINPUT2
+ /* Emacs can handle only core input events when built without XI2
+ support, so make sure Gtk doesn't use Xinput or Xinput2
+ extensions. */
xputenv ("GDK_CORE_DEVICE_EVENTS=1");
+#endif
}
#endif
@@ -13685,7 +15395,7 @@ selected window or cursor position is preserved. */);
A value of nil means Emacs doesn't use toolkit scroll bars.
With the X Window system, the value is a symbol describing the
X toolkit. Possible values are: gtk, motif, xaw, or xaw3d.
-With MS Windows or Nextstep, the value is t. */);
+With MS Windows, Haiku windowing or Nextstep, the value is t. */);
#ifdef USE_TOOLKIT_SCROLL_BARS
#ifdef USE_MOTIF
Vx_toolkit_scroll_bars = intern_c_string ("motif");
@@ -13785,4 +15495,10 @@ gtk_window_move to set or store frame positions and disables some time
consuming frame position adjustments. In newer versions of GTK, Emacs
always uses gtk_window_move and ignores the value of this variable. */);
x_gtk_use_window_move = true;
+
+ DEFVAR_LISP ("x-scroll-event-delta-factor", Vx_scroll_event_delta_factor,
+ doc: /* A scale to apply to pixel deltas reported in scroll events.
+This option is only effective when Emacs is built with XInput 2
+support. */);
+ Vx_scroll_event_delta_factor = make_float (1.0);
}
diff --git a/src/xterm.h b/src/xterm.h
index de6ea50385d..d9ace002d58 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -88,6 +88,10 @@ typedef GtkWidget *xt_or_gtk_widget;
#include <X11/Xlib-xcb.h>
#endif
+#ifdef HAVE_XKB
+#include <X11/XKBlib.h>
+#endif
+
#include "dispextern.h"
#include "termhooks.h"
@@ -163,6 +167,39 @@ struct color_name_cache_entry
char *name;
};
+#ifdef HAVE_XINPUT2
+struct xi_scroll_valuator_t
+{
+ bool invalid_p;
+ double current_value;
+ double emacs_value;
+ double increment;
+
+ int number;
+ int horizontal;
+};
+
+struct xi_touch_point_t
+{
+ struct xi_touch_point_t *next;
+
+ int number;
+ double x, y;
+};
+
+struct xi_device_t
+{
+ int device_id;
+ int scroll_valuator_count;
+ int grab;
+ bool master_p;
+ bool direct_p;
+
+ struct xi_scroll_valuator_t *valuators;
+ struct xi_touch_point_t *touchpoints;
+};
+#endif
+
Status x_parse_color (struct frame *f, const char *color_name,
XColor *color);
@@ -474,6 +511,19 @@ struct x_display_info
#ifdef HAVE_XDBE
bool supports_xdbe;
#endif
+
+#ifdef HAVE_XINPUT2
+ bool supports_xi2;
+ int xi2_version;
+ int xi2_opcode;
+
+ int num_devices;
+ struct xi_device_t *devices;
+#endif
+
+#ifdef HAVE_XKB
+ XkbDescPtr xkb_desc;
+#endif
};
#ifdef HAVE_X_I18N
@@ -481,6 +531,11 @@ struct x_display_info
extern bool use_xim;
#endif
+#ifdef HAVE_XINPUT2
+/* Defined in xmenu.c. */
+extern int popup_activated_flag;
+#endif
+
/* This is a chain of structures for all the X displays currently in use. */
extern struct x_display_info *x_display_list;
@@ -1108,6 +1163,7 @@ extern void x_mouse_leave (struct x_display_info *);
extern int x_dispatch_event (XEvent *, Display *);
#endif
extern int x_x_to_emacs_modifiers (struct x_display_info *, int);
+extern int x_emacs_to_x_modifiers (struct x_display_info *, intmax_t);
#ifdef USE_CAIRO
extern void x_cr_destroy_frame_context (struct frame *);
extern void x_cr_update_surface_desired_size (struct frame *, int, int);
diff --git a/src/xwidget.c b/src/xwidget.c
index e4b42e6e0c6..63ac0555dbb 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -19,6 +19,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <config.h>
+#include "buffer.h"
+#include "coding.h"
#include "xwidget.h"
#include "lisp.h"
@@ -30,15 +32,41 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "sysstdio.h"
#include "termhooks.h"
#include "window.h"
+#include "process.h"
/* Include xwidget bottom end headers. */
#ifdef USE_GTK
#include <webkit2/webkit2.h>
#include <JavaScriptCore/JavaScript.h>
+#include <cairo.h>
+#include <X11/Xlib.h>
+#ifdef HAVE_XINPUT2
+#include <X11/extensions/XInput2.h>
+#endif
#elif defined NS_IMPL_COCOA
#include "nsxwidget.h"
#endif
+#include <math.h>
+
+static Lisp_Object id_to_xwidget_map;
+static Lisp_Object internal_xwidget_view_list;
+static Lisp_Object internal_xwidget_list;
+static uint32_t xwidget_counter = 0;
+
+#ifdef USE_GTK
+static Lisp_Object x_window_to_xwv_map;
+static gboolean offscreen_damage_event (GtkWidget *, GdkEvent *, gpointer);
+static void synthesize_focus_in_event (GtkWidget *);
+static GdkDevice *find_suitable_keyboard (struct frame *);
+static gboolean webkit_script_dialog_cb (WebKitWebView *, WebKitScriptDialog *,
+ gpointer);
+static void record_osr_embedder (struct xwidget_view *);
+static void from_embedder (GdkWindow *, double, double, gpointer, gpointer, gpointer);
+static void to_embedder (GdkWindow *, double, double, gpointer, gpointer, gpointer);
+static GdkWindow *pick_embedded_child (GdkWindow *, double, double, gpointer);
+#endif
+
static struct xwidget *
allocate_xwidget (void)
{
@@ -56,6 +84,8 @@ allocate_xwidget_view (void)
static struct xwidget_view *xwidget_view_lookup (struct xwidget *,
struct window *);
+static void kill_xwidget (struct xwidget *);
+
#ifdef USE_GTK
static void webkit_view_load_changed_cb (WebKitWebView *,
WebKitLoadEvent,
@@ -64,18 +94,35 @@ static void webkit_javascript_finished_cb (GObject *,
GAsyncResult *,
gpointer);
static gboolean webkit_download_cb (WebKitWebContext *, WebKitDownload *, gpointer);
-
+static GtkWidget *webkit_create_cb (WebKitWebView *, WebKitNavigationAction *, gpointer);
static gboolean
webkit_decide_policy_cb (WebKitWebView *,
WebKitPolicyDecision *,
WebKitPolicyDecisionType,
gpointer);
+static GtkWidget *find_widget_at_pos (GtkWidget *, int, int, int *, int *);
+static gboolean run_file_chooser_cb (WebKitWebView *,
+ WebKitFileChooserRequest *,
+ gpointer);
+
+struct widget_search_data
+{
+ int x;
+ int y;
+ bool foundp;
+ bool first;
+ GtkWidget *data;
+};
+
+static void find_widget (GtkWidget *t, struct widget_search_data *);
+static void mouse_target_changed (WebKitWebView *, WebKitHitTestResult *, guint,
+ gpointer);
#endif
DEFUN ("make-xwidget",
Fmake_xwidget, Smake_xwidget,
- 5, 6, 0,
+ 4, 7, 0,
doc: /* Make an xwidget of TYPE.
If BUFFER is nil, use the current buffer.
If BUFFER is a string and no such buffer exists, create it.
@@ -83,10 +130,13 @@ TYPE is a symbol which can take one of the following values:
- webkit
-Returns the newly constructed xwidget, or nil if construction fails. */)
+RELATED is nil, or an xwidget. When constructing a WebKit widget, it
+will share the same settings and internal subprocess as RELATED.
+Returns the newly constructed xwidget, or nil if construction
+fails. */)
(Lisp_Object type,
Lisp_Object title, Lisp_Object width, Lisp_Object height,
- Lisp_Object arguments, Lisp_Object buffer)
+ Lisp_Object arguments, Lisp_Object buffer, Lisp_Object related)
{
#ifdef USE_GTK
if (!xg_gtk_initialized)
@@ -96,6 +146,11 @@ Returns the newly constructed xwidget, or nil if construction fails. */)
CHECK_FIXNAT (width);
CHECK_FIXNAT (height);
+ if (!EQ (type, Qwebkit))
+ error ("Bad xwidget type");
+
+ Frequire (Qxwidget, Qnil, Qnil);
+
struct xwidget *xw = allocate_xwidget ();
Lisp_Object val;
xw->type = type;
@@ -106,15 +161,22 @@ Returns the newly constructed xwidget, or nil if construction fails. */)
xw->width = XFIXNAT (width);
xw->kill_without_query = false;
XSETXWIDGET (val, xw);
- Vxwidget_list = Fcons (val, Vxwidget_list);
+ internal_xwidget_list = Fcons (val, internal_xwidget_list);
+ Vxwidget_list = Fcopy_sequence (internal_xwidget_list);
xw->plist = Qnil;
+ xw->xwidget_id = ++xwidget_counter;
+ xw->find_text = NULL;
+
+ Fputhash (make_fixnum (xw->xwidget_id), val, id_to_xwidget_map);
#ifdef USE_GTK
xw->widgetwindow_osr = NULL;
xw->widget_osr = NULL;
+ xw->hit_result = 0;
if (EQ (xw->type, Qwebkit))
{
block_input ();
+ WebKitSettings *settings;
WebKitWebContext *webkit_context = webkit_web_context_get_default ();
# if WEBKIT_CHECK_VERSION (2, 26, 0)
@@ -123,23 +185,46 @@ Returns the newly constructed xwidget, or nil if construction fails. */)
# endif
xw->widgetwindow_osr = gtk_offscreen_window_new ();
+#ifndef HAVE_PGTK
gtk_window_resize (GTK_WINDOW (xw->widgetwindow_osr), xw->width,
xw->height);
+#else
+ gtk_container_check_resize (GTK_CONTAINER (xw->widgetwindow_osr));
+#endif
if (EQ (xw->type, Qwebkit))
{
- xw->widget_osr = webkit_web_view_new ();
-
- /* webkitgtk uses GSubprocess which sets sigaction causing
- Emacs to not catch SIGCHLD with its usual handle setup in
- catch_child_signal(). This resets the SIGCHLD
- sigaction. */
- struct sigaction old_action;
- sigaction (SIGCHLD, NULL, &old_action);
- webkit_web_view_load_uri(WEBKIT_WEB_VIEW (xw->widget_osr),
- "about:blank");
- sigaction (SIGCHLD, &old_action, NULL);
- }
+ WebKitWebView *related_view;
+
+ if (NILP (related)
+ || !XWIDGETP (related)
+ || !EQ (XXWIDGET (related)->type, Qwebkit))
+ {
+ WebKitWebContext *ctx = webkit_web_context_new ();
+ xw->widget_osr = webkit_web_view_new_with_context (ctx);
+ g_object_unref (ctx);
+
+ g_signal_connect (G_OBJECT (ctx),
+ "download-started",
+ G_CALLBACK (webkit_download_cb), xw);
+
+ webkit_web_view_load_uri (WEBKIT_WEB_VIEW (xw->widget_osr),
+ "about:blank");
+ /* webkitgtk uses GSubprocess which sets sigaction causing
+ Emacs to not catch SIGCHLD with its usual handle setup in
+ 'catch_child_signal'. This resets the SIGCHLD sigaction. */
+ catch_child_signal ();
+ }
+ else
+ {
+ related_view = WEBKIT_WEB_VIEW (XXWIDGET (related)->widget_osr);
+ xw->widget_osr = webkit_web_view_new_with_related_view (related_view);
+ }
+
+ /* Enable the developer extras. */
+ settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (xw->widget_osr));
+ g_object_set (G_OBJECT (settings), "enable-developer-extras", TRUE, NULL);
+ }
gtk_widget_set_size_request (GTK_WIDGET (xw->widget_osr), xw->width,
xw->height);
@@ -157,6 +242,16 @@ Returns the newly constructed xwidget, or nil if construction fails. */)
gtk_widget_show (xw->widget_osr);
gtk_widget_show (xw->widgetwindow_osr);
+#ifndef HAVE_XINPUT2
+ synthesize_focus_in_event (xw->widgetwindow_osr);
+#endif
+
+ g_signal_connect (G_OBJECT (gtk_widget_get_window (xw->widgetwindow_osr)),
+ "from-embedder", G_CALLBACK (from_embedder), NULL);
+ g_signal_connect (G_OBJECT (gtk_widget_get_window (xw->widgetwindow_osr)),
+ "to-embedder", G_CALLBACK (to_embedder), NULL);
+ g_signal_connect (G_OBJECT (gtk_widget_get_window (xw->widgetwindow_osr)),
+ "pick-embedded-child", G_CALLBACK (pick_embedded_child), NULL);
/* Store some xwidget data in the gtk widgets for convenient
retrieval in the event handlers. */
@@ -170,17 +265,33 @@ Returns the newly constructed xwidget, or nil if construction fails. */)
"load-changed",
G_CALLBACK (webkit_view_load_changed_cb), xw);
- g_signal_connect (G_OBJECT (webkit_context),
- "download-started",
- G_CALLBACK (webkit_download_cb), xw);
-
g_signal_connect (G_OBJECT (xw->widget_osr),
"decide-policy",
G_CALLBACK
(webkit_decide_policy_cb),
xw);
+
+ g_signal_connect (G_OBJECT (xw->widget_osr),
+ "mouse-target-changed",
+ G_CALLBACK (mouse_target_changed),
+ xw);
+ g_signal_connect (G_OBJECT (xw->widget_osr),
+ "create",
+ G_CALLBACK (webkit_create_cb),
+ xw);
+ g_signal_connect (G_OBJECT (xw->widget_osr),
+ "script-dialog",
+ G_CALLBACK (webkit_script_dialog_cb),
+ NULL);
+ g_signal_connect (G_OBJECT (xw->widget_osr),
+ "run-file-chooser",
+ G_CALLBACK (run_file_chooser_cb),
+ NULL);
}
+ g_signal_connect (G_OBJECT (xw->widgetwindow_osr), "damage-event",
+ G_CALLBACK (offscreen_damage_event), xw);
+
unblock_input ();
}
#elif defined NS_IMPL_COCOA
@@ -190,6 +301,180 @@ Returns the newly constructed xwidget, or nil if construction fails. */)
return val;
}
+DEFUN ("xwidget-live-p", Fxwidget_live_p, Sxwidget_live_p,
+ 1, 1, 0, doc: /* Return t if OBJECT is an xwidget that has not been killed.
+Value is nil if OBJECT is not an xwidget or if it has been killed. */)
+ (Lisp_Object object)
+{
+ return ((XWIDGETP (object)
+ && !NILP (XXWIDGET (object)->buffer))
+ ? Qt : Qnil);
+}
+
+#ifdef USE_GTK
+static void
+set_widget_if_text_view (GtkWidget *widget, void *data)
+{
+ GtkWidget **pointer = data;
+
+ if (GTK_IS_TEXT_VIEW (widget))
+ *pointer = widget;
+}
+#endif
+
+DEFUN ("xwidget-perform-lispy-event",
+ Fxwidget_perform_lispy_event, Sxwidget_perform_lispy_event,
+ 2, 3, 0, doc: /* Send a lispy event to XWIDGET.
+EVENT should be the event that will be sent. FRAME should be the
+frame which generated the event, and defaults to the selected frame.
+On X11, modifier keys will not be processed if FRAME is nil and the
+selected frame is not an X-Windows frame. */)
+ (Lisp_Object xwidget, Lisp_Object event, Lisp_Object frame)
+{
+ struct xwidget *xw;
+ struct frame *f = NULL;
+ int character = -1, keycode = -1;
+ int modifiers = 0;
+
+#ifdef USE_GTK
+ GdkEvent *xg_event;
+ GtkContainerClass *klass;
+ GtkWidget *widget;
+ GtkWidget *temp = NULL;
+#ifdef HAVE_XINPUT2
+ GdkWindow *embedder;
+ GdkWindow *osw;
+#endif
+#endif
+
+ CHECK_LIVE_XWIDGET (xwidget);
+ xw = XXWIDGET (xwidget);
+
+ if (!NILP (frame))
+ f = decode_window_system_frame (frame);
+ else if (FRAME_X_P (SELECTED_FRAME ()))
+ f = SELECTED_FRAME ();
+
+#ifdef USE_GTK
+#ifdef HAVE_XINPUT2
+ /* XI2 GDK devices crash if we try this without an embedder set. */
+ if (!f)
+ return Qnil;
+
+ osw = gtk_widget_get_window (xw->widgetwindow_osr);
+ embedder = gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f));
+
+ gdk_offscreen_window_set_embedder (osw, embedder);
+#endif
+ widget = gtk_window_get_focus (GTK_WINDOW (xw->widgetwindow_osr));
+
+ if (!widget)
+ widget = xw->widget_osr;
+
+ if (RANGED_FIXNUMP (0, event, INT_MAX))
+ {
+ character = XFIXNUM (event);
+
+ if (character < 32)
+ modifiers |= ctrl_modifier;
+
+ modifiers |= character & meta_modifier;
+ modifiers |= character & hyper_modifier;
+ modifiers |= character & super_modifier;
+ modifiers |= character & shift_modifier;
+ modifiers |= character & ctrl_modifier;
+
+ character = character & ~(1 << 21);
+
+ if (character < 32)
+ character += '_';
+
+ if (f)
+ modifiers = x_emacs_to_x_modifiers (FRAME_DISPLAY_INFO (f), modifiers);
+ else
+ modifiers = 0;
+ }
+ else if (SYMBOLP (event))
+ {
+ Lisp_Object decoded = parse_modifiers (event);
+ Lisp_Object decoded_name = SYMBOL_NAME (XCAR (decoded));
+
+ int off = 0;
+ bool found = false;
+
+ while (off < 256)
+ {
+ if (lispy_function_keys[off]
+ && !strcmp (lispy_function_keys[off],
+ SSDATA (decoded_name)))
+ {
+ found = true;
+ break;
+ }
+ ++off;
+ }
+
+ if (f)
+ modifiers = x_emacs_to_x_modifiers (FRAME_DISPLAY_INFO (f),
+ XFIXNUM (XCAR (XCDR (decoded))));
+ else
+ modifiers = 0;
+
+ if (found)
+ keycode = off + 0xff00;
+ }
+
+ if (character == -1 && keycode == -1)
+ return Qnil;
+
+ block_input ();
+ xg_event = gdk_event_new (GDK_KEY_PRESS);
+ xg_event->any.window = gtk_widget_get_window (xw->widget_osr);
+ g_object_ref (xg_event->any.window);
+
+ if (character > -1)
+ keycode = gdk_unicode_to_keyval (character);
+
+ xg_event->key.keyval = keycode;
+ xg_event->key.state = modifiers;
+
+ if (keycode > -1)
+ {
+ /* WebKitGTK internals abuse follows. */
+ if (WEBKIT_IS_WEB_VIEW (widget))
+ {
+ /* WebKitGTK relies on an internal GtkTextView object to
+ "translate" keys such as backspace. We must find that
+ widget and activate its binding to this key if any. */
+ klass = GTK_CONTAINER_CLASS (G_OBJECT_GET_CLASS (widget));
+
+ klass->forall (GTK_CONTAINER (xw->widget_osr), TRUE,
+ set_widget_if_text_view, &temp);
+
+ if (GTK_IS_WIDGET (temp))
+ {
+ if (!gtk_widget_get_realized (temp))
+ gtk_widget_realize (temp);
+
+ gtk_bindings_activate (G_OBJECT (temp), keycode, modifiers);
+ }
+ }
+ }
+
+ if (f)
+ gdk_event_set_device (xg_event,
+ find_suitable_keyboard (SELECTED_FRAME ()));
+
+ gtk_main_do_event (xg_event);
+ xg_event->type = GDK_KEY_RELEASE;
+ gtk_main_do_event (xg_event);
+ gdk_event_free (xg_event);
+ unblock_input ();
+#endif
+
+ return Qnil;
+}
+
DEFUN ("get-buffer-xwidgets", Fget_buffer_xwidgets, Sget_buffer_xwidgets,
1, 1, 0,
doc: /* Return a list of xwidgets associated with BUFFER.
@@ -206,7 +491,7 @@ BUFFER may be a buffer or the name of one. */)
xw_list = Qnil;
- for (tail = Vxwidget_list; CONSP (tail); tail = XCDR (tail))
+ for (tail = internal_xwidget_list; CONSP (tail); tail = XCDR (tail))
{
xw = XCAR (tail);
if (XWIDGETP (xw) && EQ (Fxwidget_buffer (xw), buffer))
@@ -221,16 +506,719 @@ xwidget_hidden (struct xwidget_view *xv)
return xv->hidden;
}
+struct xwidget *
+xwidget_from_id (uint32_t id)
+{
+ Lisp_Object key = make_fixnum (id);
+ Lisp_Object xwidget = Fgethash (key, id_to_xwidget_map, Qnil);
+
+ if (NILP (xwidget))
+ emacs_abort ();
+
+ return XXWIDGET (xwidget);
+}
+
#ifdef USE_GTK
+static GdkWindow *
+pick_embedded_child (GdkWindow *window, double x, double y,
+ gpointer user_data)
+{
+ GtkWidget *widget;
+ GtkWidget *child;
+ GdkEvent event;
+ int xout, yout;
+
+ event.any.window = window;
+ event.any.type = GDK_NOTHING;
+
+ widget = gtk_get_event_widget (&event);
+
+ if (!widget)
+ return NULL;
+
+ child = find_widget_at_pos (widget, lrint (x), lrint (y),
+ &xout, &yout);
+
+ if (!child)
+ return NULL;
+
+ return gtk_widget_get_window (child);
+}
+
+static void
+record_osr_embedder (struct xwidget_view *view)
+{
+ struct xwidget *xw;
+ GdkWindow *window, *embedder;
+
+ xw = XXWIDGET (view->model);
+ window = gtk_widget_get_window (xw->widgetwindow_osr);
+ embedder = gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (view->frame));
+
+ gdk_offscreen_window_set_embedder (window, embedder);
+ xw->embedder = view->frame;
+ xw->embedder_view = view;
+}
+
+static struct xwidget *
+find_xwidget_for_offscreen_window (GdkWindow *window)
+{
+ Lisp_Object tem;
+ struct xwidget *xw;
+ GdkWindow *w;
+
+ for (tem = internal_xwidget_list; CONSP (tem); tem = XCDR (tem))
+ {
+ if (XWIDGETP (XCAR (tem)))
+ {
+ xw = XXWIDGET (XCAR (tem));
+ w = gtk_widget_get_window (xw->widgetwindow_osr);
+
+ if (w == window)
+ return xw;
+ }
+ }
+
+ return NULL;
+}
+
+static void
+from_embedder (GdkWindow *window, double x, double y,
+ gpointer x_out_ptr, gpointer y_out_ptr,
+ gpointer user_data)
+{
+ double *xout = x_out_ptr;
+ double *yout = y_out_ptr;
+ struct xwidget *xw = find_xwidget_for_offscreen_window (window);
+ struct xwidget_view *xvw;
+ gint xoff, yoff;
+
+ if (!xw)
+ emacs_abort ();
+
+ xvw = xw->embedder_view;
+
+ if (!xvw)
+ {
+ *xout = x;
+ *yout = y;
+ }
+ else
+ {
+ gtk_widget_translate_coordinates (FRAME_GTK_WIDGET (xvw->frame),
+ FRAME_GTK_OUTER_WIDGET (xvw->frame),
+ 0, 0, &xoff, &yoff);
+
+ *xout = x - xvw->x - xoff;
+ *yout = y - xvw->y - yoff;
+ }
+}
+
+static void
+to_embedder (GdkWindow *window, double x, double y,
+ gpointer x_out_ptr, gpointer y_out_ptr,
+ gpointer user_data)
+{
+ double *xout = x_out_ptr;
+ double *yout = y_out_ptr;
+ struct xwidget *xw = find_xwidget_for_offscreen_window (window);
+ struct xwidget_view *xvw;
+ gint xoff, yoff;
+
+ if (!xw)
+ emacs_abort ();
+
+ xvw = xw->embedder_view;
+
+ if (!xvw)
+ {
+ *xout = x;
+ *yout = y;
+ }
+ else
+ {
+ gtk_widget_translate_coordinates (FRAME_GTK_WIDGET (xvw->frame),
+ FRAME_GTK_OUTER_WIDGET (xvw->frame),
+ 0, 0, &xoff, &yoff);
+
+ *xout = x + xvw->x + xoff;
+ *yout = y + xvw->y + yoff;
+ }
+}
+
+static GdkDevice *
+find_suitable_pointer (struct frame *f)
+{
+ GdkSeat *seat = gdk_display_get_default_seat
+ (gtk_widget_get_display (FRAME_GTK_WIDGET (f)));
+
+ if (!seat)
+ return NULL;
+
+ return gdk_seat_get_pointer (seat);
+}
+
+static GdkDevice *
+find_suitable_keyboard (struct frame *f)
+{
+ GdkSeat *seat = gdk_display_get_default_seat
+ (gtk_widget_get_display (FRAME_GTK_WIDGET (f)));
+
+ if (!seat)
+ return NULL;
+
+ return gdk_seat_get_keyboard (seat);
+}
+
+static void
+find_widget_cb (GtkWidget *widget, void *user)
+{
+ find_widget (widget, user);
+}
+
+static void
+find_widget (GtkWidget *widget,
+ struct widget_search_data *data)
+{
+ GtkAllocation new_allocation;
+ GdkWindow *window;
+ int x_offset = 0;
+ int y_offset = 0;
+
+ gtk_widget_get_allocation (widget, &new_allocation);
+
+ if (gtk_widget_get_has_window (widget))
+ {
+ new_allocation.x = 0;
+ new_allocation.y = 0;
+ }
+
+ if (gtk_widget_get_parent (widget) && !data->first)
+ {
+ window = gtk_widget_get_window (widget);
+ while (window != gtk_widget_get_window (gtk_widget_get_parent (widget)))
+ {
+ gint tx, ty, twidth, theight;
+
+ if (!window)
+ return;
+
+ twidth = gdk_window_get_width (window);
+ theight = gdk_window_get_height (window);
+
+ if (new_allocation.x < 0)
+ {
+ new_allocation.width += new_allocation.x;
+ new_allocation.x = 0;
+ }
+
+ if (new_allocation.y < 0)
+ {
+ new_allocation.height += new_allocation.y;
+ new_allocation.y = 0;
+ }
+
+ if (new_allocation.x + new_allocation.width > twidth)
+ new_allocation.width = twidth - new_allocation.x;
+ if (new_allocation.y + new_allocation.height > theight)
+ new_allocation.height = theight - new_allocation.y;
+
+ gdk_window_get_position (window, &tx, &ty);
+ new_allocation.x += tx;
+ x_offset += tx;
+ new_allocation.y += ty;
+ y_offset += ty;
+
+ window = gdk_window_get_parent (window);
+ }
+ }
+
+ if ((data->x >= new_allocation.x) && (data->y >= new_allocation.y) &&
+ (data->x < new_allocation.x + new_allocation.width) &&
+ (data->y < new_allocation.y + new_allocation.height))
+ {
+ /* First, check if the drag is in a valid drop site in one of
+ our children. */
+ if (GTK_IS_CONTAINER (widget))
+ {
+ struct widget_search_data new_data = *data;
+
+ new_data.x -= x_offset;
+ new_data.y -= y_offset;
+ new_data.foundp = false;
+ new_data.first = false;
+
+ gtk_container_forall (GTK_CONTAINER (widget),
+ find_widget_cb, &new_data);
+
+ data->foundp = new_data.foundp;
+ if (data->foundp)
+ data->data = new_data.data;
+ }
+
+ /* If not, and this widget is registered as a drop site, check
+ to emit "drag_motion" to check if we are actually in a drop
+ site. */
+ if (!data->foundp)
+ {
+ data->foundp = true;
+ data->data = widget;
+ }
+ }
+}
+
+static GtkWidget *
+find_widget_at_pos (GtkWidget *w, int x, int y,
+ int *new_x, int *new_y)
+{
+ struct widget_search_data data;
+
+ data.x = x;
+ data.y = y;
+ data.foundp = false;
+ data.first = true;
+
+ find_widget (w, &data);
+
+ if (data.foundp)
+ {
+ gtk_widget_translate_coordinates (w, data.data, x,
+ y, new_x, new_y);
+ return data.data;
+ }
+
+ *new_x = x;
+ *new_y = y;
+
+ return NULL;
+}
+
+static Emacs_Cursor
+cursor_for_hit (guint result, struct frame *frame)
+{
+ Emacs_Cursor cursor = FRAME_OUTPUT_DATA (frame)->nontext_cursor;
+
+ if ((result & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE)
+ || (result & WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION)
+ || (result & WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT))
+ cursor = FRAME_X_OUTPUT (frame)->text_cursor;
+
+ if (result & WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR)
+ cursor = FRAME_X_OUTPUT (frame)->vertical_drag_cursor;
+
+ if (result & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK)
+ cursor = FRAME_X_OUTPUT (frame)->hand_cursor;
+
+ return cursor;
+}
+
+static void
+define_cursors (struct xwidget *xw, WebKitHitTestResult *res)
+{
+ struct xwidget_view *xvw;
+
+ xw->hit_result = webkit_hit_test_result_get_context (res);
+
+ for (Lisp_Object tem = internal_xwidget_view_list; CONSP (tem);
+ tem = XCDR (tem))
+ {
+ if (XWIDGET_VIEW_P (XCAR (tem)))
+ {
+ xvw = XXWIDGET_VIEW (XCAR (tem));
+
+ if (XXWIDGET (xvw->model) == xw)
+ {
+ xvw->cursor = cursor_for_hit (xw->hit_result, xvw->frame);
+ if (xvw->wdesc != None)
+ XDefineCursor (xvw->dpy, xvw->wdesc, xvw->cursor);
+ }
+ }
+ }
+}
+
+static void
+mouse_target_changed (WebKitWebView *webview,
+ WebKitHitTestResult *hitresult,
+ guint modifiers, gpointer xw)
+{
+ define_cursors (xw, hitresult);
+}
+
+static gboolean
+run_file_chooser_cb (WebKitWebView *webview,
+ WebKitFileChooserRequest *request,
+ gpointer user_data)
+{
+ struct frame *f = SELECTED_FRAME ();
+ GtkFileChooserNative *chooser;
+ GtkFileFilter *filter;
+ bool select_multiple_p;
+ guint response;
+ GSList *filenames;
+ GSList *tem;
+ int i, len;
+ gchar **files;
+
+ /* Return TRUE to prevent WebKit from showing the default script
+ dialog in the offscreen window, which runs a nested main loop
+ Emacs can't respond to, and as such can't pass X events to. */
+ if (!FRAME_WINDOW_P (f))
+ return TRUE;
+
+ chooser = gtk_file_chooser_native_new ("Select file",
+ GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ GTK_FILE_CHOOSER_ACTION_OPEN, "Select",
+ "Cancel");
+ filter = webkit_file_chooser_request_get_mime_types_filter (request);
+ select_multiple_p = webkit_file_chooser_request_get_select_multiple (request);
+
+ gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (chooser),
+ select_multiple_p);
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
+ response = gtk_native_dialog_run (GTK_NATIVE_DIALOG (chooser));
+
+ if (response != GTK_RESPONSE_ACCEPT)
+ {
+ gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (chooser));
+ webkit_file_chooser_request_cancel (request);
+
+ return TRUE;
+ }
+
+ filenames = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (chooser));
+ len = g_slist_length (filenames);
+ files = alloca (sizeof *files * (len + 1));
+
+ for (tem = filenames, i = 0; tem; tem = tem->next, ++i)
+ files[i] = tem->data;
+ files[len] = NULL;
+
+ g_slist_free (filenames);
+ webkit_file_chooser_request_select_files (request, (const gchar **) files);
+
+ for (i = 0; i < len; ++i)
+ g_free (files[i]);
+
+ gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (chooser));
+
+ return TRUE;
+}
+
+
+static void
+xwidget_button_1 (struct xwidget_view *view,
+ bool down_p, int x, int y, int button,
+ int modifier_state, Time time)
+{
+ GdkEvent *xg_event = gdk_event_new (down_p ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
+ struct xwidget *model = XXWIDGET (view->model);
+ GtkWidget *target;
+#ifdef HAVE_XINPUT2
+ struct x_display_info *dpyinfo;
+ struct xi_device_t *xi_device;
+ GdkSeat *seat;
+ GdkDevice *device;
+#endif
+
+ /* X and Y should be relative to the origin of view->wdesc. */
+ x += view->clip_left;
+ y += view->clip_top;
+
+ target = find_widget_at_pos (model->widgetwindow_osr, x, y, &x, &y);
+
+ if (!target)
+ target = model->widget_osr;
+
+ xg_event->any.window = gtk_widget_get_window (target);
+ g_object_ref (xg_event->any.window); /* The window will be unrefed
+ later by gdk_event_free. */
+
+ xg_event->button.x = x;
+ xg_event->button.x_root = x;
+ xg_event->button.y = y;
+ xg_event->button.y_root = y;
+ xg_event->button.button = button;
+ xg_event->button.state = modifier_state;
+ xg_event->button.time = time;
+ xg_event->button.device = find_suitable_pointer (view->frame);
+
+#ifdef HAVE_XINPUT2
+ dpyinfo = FRAME_DISPLAY_INFO (view->frame);
+ device = xg_event->button.device;
+
+ for (int idx = 0; idx < dpyinfo->num_devices; ++idx)
+ {
+ xi_device = &dpyinfo->devices[idx];
+
+ XIUngrabDevice (view->dpy, xi_device->device_id, CurrentTime);
+ }
+
+ if (device)
+ {
+ seat = gdk_device_get_seat (device);
+ gdk_seat_ungrab (seat);
+ }
+#endif
+
+ gtk_main_do_event (xg_event);
+ gdk_event_free (xg_event);
+}
+
+void
+xwidget_button (struct xwidget_view *view,
+ bool down_p, int x, int y, int button,
+ int modifier_state, Time time)
+{
+ if (NILP (XXWIDGET (view->model)->buffer))
+ return;
+
+ record_osr_embedder (view);
+
+ if (button < 4 || button > 8)
+ xwidget_button_1 (view, down_p, x, y, button, modifier_state, time);
+#ifndef HAVE_XINPUT2
+ else
+#else
+ else if (!FRAME_DISPLAY_INFO (view->frame)->supports_xi2
+ || FRAME_DISPLAY_INFO (view->frame)->xi2_version < 1)
+#endif
+ {
+ GdkEvent *xg_event = gdk_event_new (GDK_SCROLL);
+ struct xwidget *model = XXWIDGET (view->model);
+ GtkWidget *target;
+
+ x += view->clip_left;
+ y += view->clip_top;
+
+ target = find_widget_at_pos (model->widgetwindow_osr, x, y, &x, &y);
+
+ if (!target)
+ target = model->widget_osr;
+
+ xg_event->any.window = gtk_widget_get_window (target);
+ g_object_ref (xg_event->any.window); /* The window will be unrefed
+ later by gdk_event_free. */
+ if (button == 4)
+ xg_event->scroll.direction = GDK_SCROLL_UP;
+ else if (button == 5)
+ xg_event->scroll.direction = GDK_SCROLL_DOWN;
+ else if (button == 6)
+ xg_event->scroll.direction = GDK_SCROLL_LEFT;
+ else
+ xg_event->scroll.direction = GDK_SCROLL_RIGHT;
+
+ xg_event->scroll.device = find_suitable_pointer (view->frame);
+
+ xg_event->scroll.x = x;
+ xg_event->scroll.x_root = x;
+ xg_event->scroll.y = y;
+ xg_event->scroll.y_root = y;
+ xg_event->scroll.state = modifier_state;
+ xg_event->scroll.time = time;
+
+ xg_event->scroll.delta_x = 0;
+ xg_event->scroll.delta_y = 0;
+
+ gtk_main_do_event (xg_event);
+ gdk_event_free (xg_event);
+ }
+}
+
+#ifdef HAVE_XINPUT2
+void
+xwidget_motion_notify (struct xwidget_view *view,
+ double x, double y, uint state, Time time)
+{
+ GdkEvent *xg_event;
+ GtkWidget *target;
+ struct xwidget *model = XXWIDGET (view->model);
+ int target_x, target_y;
+
+ if (NILP (model->buffer))
+ return;
+
+ record_osr_embedder (view);
+
+ target = find_widget_at_pos (model->widgetwindow_osr,
+ lrint (x), lrint (y),
+ &target_x, &target_y);
+
+ if (!target)
+ {
+ target_x = lrint (x);
+ target_y = lrint (y);
+ target = model->widget_osr;
+ }
+
+ xg_event = gdk_event_new (GDK_MOTION_NOTIFY);
+ xg_event->any.window = gtk_widget_get_window (target);
+ xg_event->motion.x = target_x;
+ xg_event->motion.y = target_y;
+ xg_event->motion.x_root = lrint (x);
+ xg_event->motion.y_root = lrint (y);
+ xg_event->motion.time = time;
+ xg_event->motion.state = state;
+ xg_event->motion.device = find_suitable_pointer (view->frame);
+
+ g_object_ref (xg_event->any.window);
+
+ gtk_main_do_event (xg_event);
+ gdk_event_free (xg_event);
+}
+
+void
+xwidget_scroll (struct xwidget_view *view, double x, double y,
+ double dx, double dy, uint state, Time time,
+ bool stop_p)
+{
+ GdkEvent *xg_event;
+ GtkWidget *target;
+ struct xwidget *model = XXWIDGET (view->model);
+ int target_x, target_y;
+
+ if (NILP (model->buffer))
+ return;
+
+ record_osr_embedder (view);
+
+ target = find_widget_at_pos (model->widgetwindow_osr,
+ lrint (x), lrint (y),
+ &target_x, &target_y);
+
+ if (!target)
+ {
+ target_x = lrint (x);
+ target_y = lrint (y);
+ target = model->widget_osr;
+ }
+
+ xg_event = gdk_event_new (GDK_SCROLL);
+ xg_event->any.window = gtk_widget_get_window (target);
+ xg_event->scroll.direction = GDK_SCROLL_SMOOTH;
+ xg_event->scroll.x = target_x;
+ xg_event->scroll.y = target_y;
+ xg_event->scroll.x_root = lrint (x);
+ xg_event->scroll.y_root = lrint (y);
+ xg_event->scroll.time = time;
+ xg_event->scroll.state = state;
+ xg_event->scroll.delta_x = dx;
+ xg_event->scroll.delta_y = dy;
+ xg_event->scroll.device = find_suitable_pointer (view->frame);
+ xg_event->scroll.is_stop = stop_p;
+
+ g_object_ref (xg_event->any.window);
+
+ gtk_main_do_event (xg_event);
+ gdk_event_free (xg_event);
+}
+#endif
+
+void
+xwidget_motion_or_crossing (struct xwidget_view *view, const XEvent *event)
+{
+ GdkEvent *xg_event;
+ struct xwidget *model = XXWIDGET (view->model);
+ int x;
+ int y;
+ GtkWidget *target;
+
+ if (NILP (model->buffer))
+ return;
+
+ xg_event = gdk_event_new (event->type == MotionNotify
+ ? GDK_MOTION_NOTIFY
+ : (event->type == LeaveNotify
+ ? GDK_LEAVE_NOTIFY
+ : GDK_ENTER_NOTIFY));
+
+ target = find_widget_at_pos (model->widgetwindow_osr,
+ (event->type == MotionNotify
+ ? event->xmotion.x + view->clip_left
+ : event->xcrossing.x + view->clip_left),
+ (event->type == MotionNotify
+ ? event->xmotion.y + view->clip_top
+ : event->xcrossing.y + view->clip_top),
+ &x, &y);
+
+ if (!target)
+ target = model->widget_osr;
+
+ record_osr_embedder (view);
+ xg_event->any.window = gtk_widget_get_window (target);
+ g_object_ref (xg_event->any.window); /* The window will be unrefed
+ later by gdk_event_free. */
+
+ if (event->type == MotionNotify)
+ {
+ xg_event->motion.x = x;
+ xg_event->motion.y = y;
+ xg_event->motion.x_root = event->xmotion.x_root;
+ xg_event->motion.y_root = event->xmotion.y_root;
+ xg_event->motion.time = event->xmotion.time;
+ xg_event->motion.state = event->xmotion.state;
+ xg_event->motion.device = find_suitable_pointer (view->frame);
+ }
+ else
+ {
+ xg_event->crossing.detail = min (5, event->xcrossing.detail);
+ xg_event->crossing.time = event->xcrossing.time;
+ xg_event->crossing.x = x;
+ xg_event->crossing.y = y;
+ xg_event->crossing.x_root = event->xcrossing.x_root;
+ xg_event->crossing.y_root = event->xcrossing.y_root;
+ gdk_event_set_device (xg_event, find_suitable_pointer (view->frame));
+ }
+
+ gtk_main_do_event (xg_event);
+ gdk_event_free (xg_event);
+}
+
+static void
+synthesize_focus_in_event (GtkWidget *offscreen_window)
+{
+ GdkWindow *wnd;
+ GdkEvent *focus_event;
+
+ if (!gtk_widget_get_realized (offscreen_window))
+ gtk_widget_realize (offscreen_window);
+
+ wnd = gtk_widget_get_window (offscreen_window);
+
+ focus_event = gdk_event_new (GDK_FOCUS_CHANGE);
+ focus_event->focus_change.window = wnd;
+ focus_event->focus_change.in = TRUE;
+
+ if (FRAME_WINDOW_P (SELECTED_FRAME ()))
+ gdk_event_set_device (focus_event,
+ find_suitable_pointer (SELECTED_FRAME ()));
+
+ g_object_ref (wnd);
+
+ gtk_main_do_event (focus_event);
+ gdk_event_free (focus_event);
+}
+
+struct xwidget_view *
+xwidget_view_from_window (Window wdesc)
+{
+ Lisp_Object key = make_fixnum (wdesc);
+ Lisp_Object xwv = Fgethash (key, x_window_to_xwv_map, Qnil);
+
+ if (NILP (xwv))
+ return NULL;
+
+ return XXWIDGET_VIEW (xwv);
+}
+
static void
xwidget_show_view (struct xwidget_view *xv)
{
xv->hidden = false;
- gtk_widget_show (xv->widgetwindow);
- gtk_fixed_move (GTK_FIXED (xv->emacswindow),
- xv->widgetwindow,
- xv->x + xv->clip_left,
- xv->y + xv->clip_top);
+ XMoveWindow (xv->dpy, xv->wdesc,
+ xv->x + xv->clip_left,
+ xv->y + xv->clip_top);
+ XMapWindow (xv->dpy, xv->wdesc);
+ XFlush (xv->dpy);
}
/* Hide an xwidget view. */
@@ -238,28 +1226,74 @@ static void
xwidget_hide_view (struct xwidget_view *xv)
{
xv->hidden = true;
- gtk_fixed_move (GTK_FIXED (xv->emacswindow), xv->widgetwindow,
- 10000, 10000);
+ XUnmapWindow (xv->dpy, xv->wdesc);
+ XFlush (xv->dpy);
+}
+
+static void
+xv_do_draw (struct xwidget_view *xw, struct xwidget *w)
+{
+ GtkOffscreenWindow *wnd;
+ cairo_surface_t *surface;
+
+ if (xw->just_resized)
+ return;
+
+ if (NILP (w->buffer))
+ {
+ XClearWindow (xw->dpy, xw->wdesc);
+ return;
+ }
+
+ block_input ();
+ wnd = GTK_OFFSCREEN_WINDOW (w->widgetwindow_osr);
+ surface = gtk_offscreen_window_get_surface (wnd);
+
+ cairo_save (xw->cr_context);
+ if (surface)
+ {
+ cairo_translate (xw->cr_context, -xw->clip_left, -xw->clip_top);
+ cairo_set_source_surface (xw->cr_context, surface, 0, 0);
+ cairo_set_operator (xw->cr_context, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (xw->cr_context);
+ }
+ cairo_restore (xw->cr_context);
+
+ unblock_input ();
}
/* When the off-screen webkit master view changes this signal is called.
It copies the bitmap from the off-screen instance. */
static gboolean
offscreen_damage_event (GtkWidget *widget, GdkEvent *event,
- gpointer xv_widget)
-{
- /* Queue a redraw of onscreen widget.
- There is a guard against receiving an invalid widget,
- which should only happen if we failed to remove the
- specific signal handler for the damage event. */
- if (GTK_IS_WIDGET (xv_widget))
- gtk_widget_queue_draw (GTK_WIDGET (xv_widget));
- else
- message ("Warning, offscreen_damage_event received invalid xv pointer:%p\n",
- xv_widget);
+ gpointer xwidget)
+{
+ block_input ();
+
+ for (Lisp_Object tail = internal_xwidget_view_list; CONSP (tail);
+ tail = XCDR (tail))
+ {
+ if (XWIDGET_VIEW_P (XCAR (tail)))
+ {
+ struct xwidget_view *view = XXWIDGET_VIEW (XCAR (tail));
+
+ if (view->wdesc && XXWIDGET (view->model) == xwidget)
+ xv_do_draw (view, XXWIDGET (view->model));
+ }
+ }
+
+ unblock_input ();
return FALSE;
}
+
+void
+xwidget_expose (struct xwidget_view *xv)
+{
+ struct xwidget *xw = XXWIDGET (xv->model);
+
+ xv_do_draw (xv, xw);
+}
#endif /* USE_GTK */
void
@@ -313,22 +1347,121 @@ store_xwidget_js_callback_event (struct xwidget *xw,
#ifdef USE_GTK
+static void
+store_xwidget_display_event (struct xwidget *xw,
+ struct xwidget *src)
+{
+ struct input_event evt;
+ Lisp_Object val, src_val;
+
+ XSETXWIDGET (val, xw);
+ XSETXWIDGET (src_val, src);
+ EVENT_INIT (evt);
+ evt.kind = XWIDGET_DISPLAY_EVENT;
+ evt.frame_or_window = Qnil;
+ evt.arg = list2 (val, src_val);
+ kbd_buffer_store_event (&evt);
+}
+
+static void
+webkit_ready_to_show (WebKitWebView *new_view,
+ gpointer user_data)
+{
+ Lisp_Object tem;
+ struct xwidget *xw;
+ struct xwidget *src;
+
+ src = find_xwidget_for_offscreen_window (GDK_WINDOW (user_data));
+
+ for (tem = internal_xwidget_list; CONSP (tem); tem = XCDR (tem))
+ {
+ if (XWIDGETP (XCAR (tem)))
+ {
+ xw = XXWIDGET (XCAR (tem));
+
+ if (EQ (xw->type, Qwebkit)
+ && WEBKIT_WEB_VIEW (xw->widget_osr) == new_view)
+ {
+ /* The source widget was destroyed before we had a
+ chance to display the new widget. */
+ if (!src)
+ kill_xwidget (xw);
+ else
+ store_xwidget_display_event (xw, src);
+ }
+ }
+ }
+}
+
+static GtkWidget *
+webkit_create_cb_1 (WebKitWebView *webview,
+ struct xwidget *xv)
+{
+ Lisp_Object related;
+ Lisp_Object xwidget;
+ GtkWidget *widget;
+
+ XSETXWIDGET (related, xv);
+ xwidget = Fmake_xwidget (Qwebkit, Qnil, make_fixnum (0),
+ make_fixnum (0), Qnil,
+ build_string (" *detached xwidget buffer*"),
+ related);
+
+ if (NILP (xwidget))
+ return NULL;
+
+ widget = XXWIDGET (xwidget)->widget_osr;
+
+ g_signal_connect (G_OBJECT (widget), "ready-to-show",
+ G_CALLBACK (webkit_ready_to_show),
+ gtk_widget_get_window (xv->widgetwindow_osr));
+
+ return widget;
+}
+
+static GtkWidget *
+webkit_create_cb (WebKitWebView *webview,
+ WebKitNavigationAction *nav_action,
+ gpointer user_data)
+{
+ switch (webkit_navigation_action_get_navigation_type (nav_action))
+ {
+ case WEBKIT_NAVIGATION_TYPE_OTHER:
+ return webkit_create_cb_1 (webview, user_data);
+
+ case WEBKIT_NAVIGATION_TYPE_BACK_FORWARD:
+ case WEBKIT_NAVIGATION_TYPE_RELOAD:
+ case WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED:
+ case WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED:
+ case WEBKIT_NAVIGATION_TYPE_LINK_CLICKED:
+ default:
+ return NULL;
+ }
+}
+
void
webkit_view_load_changed_cb (WebKitWebView *webkitwebview,
WebKitLoadEvent load_event,
gpointer data)
{
- switch (load_event) {
- case WEBKIT_LOAD_FINISHED:
+ struct xwidget *xw = g_object_get_data (G_OBJECT (webkitwebview),
+ XG_XWIDGET);
+
+ switch (load_event)
{
- struct xwidget *xw = g_object_get_data (G_OBJECT (webkitwebview),
- XG_XWIDGET);
- store_xwidget_event_string (xw, "load-changed", "");
+ case WEBKIT_LOAD_FINISHED:
+ store_xwidget_event_string (xw, "load-changed", "load-finished");
+ break;
+ case WEBKIT_LOAD_STARTED:
+ store_xwidget_event_string (xw, "load-changed", "load-started");
+ break;
+ case WEBKIT_LOAD_REDIRECTED:
+ store_xwidget_event_string (xw, "load-changed", "load-redirected");
+ break;
+ case WEBKIT_LOAD_COMMITTED:
+ store_xwidget_event_string (xw, "load-changed", "load-committed");
break;
}
- default:
- break;
- }
}
/* Recursively convert a JavaScript value to a Lisp value. */
@@ -419,8 +1552,8 @@ webkit_javascript_finished_cb (GObject *webview,
if (!js_result)
{
- g_warning ("Error running javascript: %s", error->message);
- g_error_free (error);
+ if (error)
+ g_error_free (error);
return;
}
@@ -479,6 +1612,33 @@ webkit_decide_policy_cb (WebKitWebView *webView,
break;
}
case WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION:
+ {
+ WebKitNavigationPolicyDecision *navigation_decision =
+ WEBKIT_NAVIGATION_POLICY_DECISION (decision);
+ WebKitNavigationAction *navigation_action =
+ webkit_navigation_policy_decision_get_navigation_action (navigation_decision);
+ WebKitURIRequest *request =
+ webkit_navigation_action_get_request (navigation_action);
+ WebKitWebView *newview;
+ struct xwidget *xw = g_object_get_data (G_OBJECT (webView), XG_XWIDGET);
+ Lisp_Object val, new_xwidget;
+
+ XSETXWIDGET (val, xw);
+
+ new_xwidget = Fmake_xwidget (Qwebkit, Qnil, make_fixnum (0),
+ make_fixnum (0), Qnil,
+ build_string (" *detached xwidget buffer*"),
+ val);
+
+ if (NILP (new_xwidget))
+ return FALSE;
+
+ newview = WEBKIT_WEB_VIEW (XXWIDGET (new_xwidget)->widget_osr);
+ webkit_web_view_load_request (newview, request);
+
+ store_xwidget_display_event (XXWIDGET (new_xwidget), xw);
+ return TRUE;
+ }
case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION:
{
WebKitNavigationPolicyDecision *navigation_decision =
@@ -499,49 +1659,75 @@ webkit_decide_policy_cb (WebKitWebView *webView,
}
}
-
-/* For gtk3 offscreen rendered widgets. */
static gboolean
-xwidget_osr_draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data)
+webkit_script_dialog_cb (WebKitWebView *webview,
+ WebKitScriptDialog *script_dialog,
+ gpointer user)
{
- struct xwidget *xw = g_object_get_data (G_OBJECT (widget), XG_XWIDGET);
- struct xwidget_view *xv = g_object_get_data (G_OBJECT (widget),
- XG_XWIDGET_VIEW);
+ struct frame *f = SELECTED_FRAME ();
+ WebKitScriptDialogType type;
+ GtkWidget *widget;
+ GtkWidget *dialog;
+ GtkWidget *entry;
+ GtkWidget *content_area;
+ GtkWidget *box;
+ GtkWidget *label;
+ const gchar *content;
+ const gchar *message;
+ gint result;
+
+ /* Return TRUE to prevent WebKit from showing the default script
+ dialog in the offscreen window, which runs a nested main loop
+ Emacs can't respond to, and as such can't pass X events to. */
+ if (!FRAME_WINDOW_P (f))
+ return TRUE;
+
+ type = webkit_script_dialog_get_dialog_type (script_dialog);;
+ widget = FRAME_GTK_OUTER_WIDGET (f);
+ content = webkit_script_dialog_get_message (script_dialog);
+
+ if (type == WEBKIT_SCRIPT_DIALOG_ALERT)
+ dialog = gtk_dialog_new_with_buttons ("Alert", GTK_WINDOW (widget),
+ GTK_DIALOG_MODAL,
+ "Dismiss", 1, NULL);
+ else
+ dialog = gtk_dialog_new_with_buttons ("Question", GTK_WINDOW (widget),
+ GTK_DIALOG_MODAL,
+ "OK", 0, "Cancel", 1, NULL);
- cairo_rectangle (cr, 0, 0, xv->clip_right, xv->clip_bottom);
- cairo_clip (cr);
+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
+ label = gtk_label_new (content);
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ gtk_container_add (GTK_CONTAINER (content_area), box);
- gtk_widget_draw (xw->widget_osr, cr);
- return FALSE;
-}
+ gtk_widget_show (box);
+ gtk_widget_show (label);
-static gboolean
-xwidget_osr_event_forward (GtkWidget *widget, GdkEvent *event,
- gpointer user_data)
-{
- /* Copy events that arrive at the outer widget to the offscreen widget. */
- struct xwidget *xw = g_object_get_data (G_OBJECT (widget), XG_XWIDGET);
- GdkEvent *eventcopy = gdk_event_copy (event);
- eventcopy->any.window = gtk_widget_get_window (xw->widget_osr);
+ gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
- /* TODO: This might leak events. They should be deallocated later,
- perhaps in xwgir_event_cb. */
- gtk_main_do_event (eventcopy);
+ if (type == WEBKIT_SCRIPT_DIALOG_PROMPT)
+ {
+ entry = gtk_entry_new ();
+ message = webkit_script_dialog_prompt_get_default_text (script_dialog);
- /* Don't propagate this event further. */
- return TRUE;
-}
+ gtk_widget_show (entry);
+ gtk_entry_set_text (GTK_ENTRY (entry), message);
+ gtk_box_pack_end (GTK_BOX (box), entry, TRUE, TRUE, 0);
+ }
-static gboolean
-xwidget_osr_event_set_embedder (GtkWidget *widget, GdkEvent *event,
- gpointer data)
-{
- struct xwidget_view *xv = data;
- struct xwidget *xww = XXWIDGET (xv->model);
- gdk_offscreen_window_set_embedder (gtk_widget_get_window
- (xww->widgetwindow_osr),
- gtk_widget_get_window (xv->widget));
- return FALSE;
+ result = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (type == WEBKIT_SCRIPT_DIALOG_CONFIRM
+ || type == WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM)
+ webkit_script_dialog_confirm_set_confirmed (script_dialog, result == 0);
+
+ if (type == WEBKIT_SCRIPT_DIALOG_PROMPT)
+ webkit_script_dialog_prompt_set_text (script_dialog,
+ gtk_entry_get_text (GTK_ENTRY (entry)));
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+
+ return TRUE;
}
#endif /* USE_GTK */
@@ -562,69 +1748,27 @@ xwidget_init_view (struct xwidget *xww,
Lisp_Object val;
XSETXWIDGET_VIEW (val, xv);
- Vxwidget_view_list = Fcons (val, Vxwidget_view_list);
+ internal_xwidget_view_list = Fcons (val, internal_xwidget_view_list);
+ Vxwidget_view_list = Fcopy_sequence (internal_xwidget_view_list);
XSETWINDOW (xv->w, s->w);
XSETXWIDGET (xv->model, xww);
#ifdef USE_GTK
- if (EQ (xww->type, Qwebkit))
- {
- xv->widget = gtk_drawing_area_new ();
- /* Expose event handling. */
- gtk_widget_set_app_paintable (xv->widget, TRUE);
- gtk_widget_add_events (xv->widget, GDK_ALL_EVENTS_MASK);
-
- /* Draw the view on damage-event. */
- g_signal_connect (G_OBJECT (xww->widgetwindow_osr), "damage-event",
- G_CALLBACK (offscreen_damage_event), xv->widget);
+ xv->dpy = FRAME_X_DISPLAY (s->f);
- if (EQ (xww->type, Qwebkit))
- {
- g_signal_connect (G_OBJECT (xv->widget), "button-press-event",
- G_CALLBACK (xwidget_osr_event_forward), NULL);
- g_signal_connect (G_OBJECT (xv->widget), "button-release-event",
- G_CALLBACK (xwidget_osr_event_forward), NULL);
- g_signal_connect (G_OBJECT (xv->widget), "motion-notify-event",
- G_CALLBACK (xwidget_osr_event_forward), NULL);
- }
- else
- {
- /* xwgir debug, orthogonal to forwarding. */
- g_signal_connect (G_OBJECT (xv->widget), "enter-notify-event",
- G_CALLBACK (xwidget_osr_event_set_embedder), xv);
- }
- g_signal_connect (G_OBJECT (xv->widget), "draw",
- G_CALLBACK (xwidget_osr_draw_cb), NULL);
- }
-
- /* Widget realization.
-
- Make container widget first, and put the actual widget inside the
- container later. Drawing should crop container window if necessary
- to handle case where xwidget is partially obscured by other Emacs
- windows. Other containers than gtk_fixed where explored, but
- gtk_fixed had the most predictable behavior so far. */
-
- xv->emacswindow = FRAME_GTK_WIDGET (s->f);
- xv->widgetwindow = gtk_fixed_new ();
- gtk_widget_set_has_window (xv->widgetwindow, TRUE);
- gtk_container_add (GTK_CONTAINER (xv->widgetwindow), xv->widget);
-
- /* Store some xwidget data in the gtk widgets. */
- g_object_set_data (G_OBJECT (xv->widget), XG_FRAME_DATA, s->f);
- g_object_set_data (G_OBJECT (xv->widget), XG_XWIDGET, xww);
- g_object_set_data (G_OBJECT (xv->widget), XG_XWIDGET_VIEW, xv);
- g_object_set_data (G_OBJECT (xv->widgetwindow), XG_XWIDGET, xww);
- g_object_set_data (G_OBJECT (xv->widgetwindow), XG_XWIDGET_VIEW, xv);
-
- gtk_widget_set_size_request (GTK_WIDGET (xv->widget), xww->width,
- xww->height);
- gtk_widget_set_size_request (xv->widgetwindow, xww->width, xww->height);
- gtk_fixed_put (GTK_FIXED (FRAME_GTK_WIDGET (s->f)), xv->widgetwindow, x, y);
xv->x = x;
xv->y = y;
- gtk_widget_show_all (xv->widgetwindow);
+
+ xv->clip_left = 0;
+ xv->clip_right = xww->width;
+ xv->clip_top = 0;
+ xv->clip_bottom = xww->height;
+
+ xv->wdesc = None;
+ xv->frame = s->f;
+ xv->cursor = cursor_for_hit (xww->hit_result, s->f);
+ xv->just_resized = false;
#elif defined NS_IMPL_COCOA
nsxwidget_init_view (xv, xww, s, x, y);
nsxwidget_resize_view(xv, xww->width, xww->height);
@@ -656,6 +1800,8 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
#ifdef USE_GTK
if (!xv)
xv = xwidget_init_view (xww, s, x, y);
+
+ xv->just_resized = false;
#elif defined NS_IMPL_COCOA
if (!xv)
{
@@ -678,21 +1824,10 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
}
#endif
- window_box (s->w, TEXT_AREA, &text_area_x, &text_area_y,
- &text_area_width, &text_area_height);
+ xv->area = s->area;
- /* Resize xwidget webkit if its container window size is changed in
- some ways, for example, a buffer became hidden in small split
- window, then it can appear front in merged whole window. */
- if (EQ (xww->type, Qwebkit)
- && (xww->width != text_area_width || xww->height != text_area_height))
- {
- Lisp_Object xwl;
- XSETXWIDGET (xwl, xww);
- Fxwidget_resize (xwl,
- make_int (text_area_width),
- make_int (text_area_height));
- }
+ window_box (s->w, xv->area, &text_area_x, &text_area_y,
+ &text_area_width, &text_area_height);
clip_left = max (0, text_area_x - x);
clip_right = max (clip_left,
@@ -711,15 +1846,75 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
later. */
bool moved = (xv->x + xv->clip_left != x + clip_left
|| xv->y + xv->clip_top != y + clip_top);
+
+#ifdef USE_GTK
+ bool wdesc_was_none = xv->wdesc == None;
+#endif
xv->x = x;
xv->y = y;
+#ifdef USE_GTK
+ block_input ();
+ if (xv->wdesc == None)
+ {
+ Lisp_Object xvw;
+ XSETXWIDGET_VIEW (xvw, xv);
+ XSetWindowAttributes a;
+ a.event_mask = (ExposureMask | ButtonPressMask | ButtonReleaseMask
+ | PointerMotionMask | EnterWindowMask | LeaveWindowMask);
+
+ if (clip_right - clip_left <= 0
+ || clip_bottom - clip_top <= 0)
+ {
+ unblock_input ();
+ return;
+ }
+
+ xv->wdesc = XCreateWindow (xv->dpy, FRAME_X_WINDOW (s->f),
+ x + clip_left, y + clip_top,
+ clip_right - clip_left,
+ clip_bottom - clip_top, 0,
+ CopyFromParent, CopyFromParent,
+ CopyFromParent, CWEventMask, &a);
+#ifdef HAVE_XINPUT2
+ XIEventMask mask;
+ ptrdiff_t l = XIMaskLen (XI_LASTEVENT);
+ unsigned char *m;
+
+ if (FRAME_DISPLAY_INFO (s->f)->supports_xi2)
+ {
+ mask.mask = m = alloca (l);
+ memset (m, 0, l);
+ mask.mask_len = l;
+ mask.deviceid = XIAllMasterDevices;
+
+ XISetMask (m, XI_Motion);
+ XISelectEvents (xv->dpy, xv->wdesc, &mask, 1);
+ }
+#endif
+ XLowerWindow (xv->dpy, xv->wdesc);
+ XDefineCursor (xv->dpy, xv->wdesc, xv->cursor);
+ xv->cr_surface = cairo_xlib_surface_create (xv->dpy,
+ xv->wdesc,
+ FRAME_DISPLAY_INFO (s->f)->visual,
+ clip_right - clip_left,
+ clip_bottom - clip_top);
+ xv->cr_context = cairo_create (xv->cr_surface);
+ Fputhash (make_fixnum (xv->wdesc), xvw, x_window_to_xwv_map);
+
+ moved = false;
+ }
+#endif
+
/* Has it moved? */
if (moved)
{
#ifdef USE_GTK
- gtk_fixed_move (GTK_FIXED (FRAME_GTK_WIDGET (s->f)),
- xv->widgetwindow, x + clip_left, y + clip_top);
+ XMoveResizeWindow (xv->dpy, xv->wdesc, x + clip_left, y + clip_top,
+ clip_right - clip_left, clip_bottom - clip_top);
+ XFlush (xv->dpy);
+ cairo_xlib_surface_set_size (xv->cr_surface, clip_right - clip_left,
+ clip_bottom - clip_top);
#elif defined NS_IMPL_COCOA
nsxwidget_move_view (xv, x + clip_left, y + clip_top);
#endif
@@ -735,10 +1930,23 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
|| xv->clip_top != clip_top || xv->clip_left != clip_left)
{
#ifdef USE_GTK
- gtk_widget_set_size_request (xv->widgetwindow, clip_right - clip_left,
- clip_bottom - clip_top);
- gtk_fixed_move (GTK_FIXED (xv->widgetwindow), xv->widget, -clip_left,
- -clip_top);
+ if (!wdesc_was_none && !moved)
+ {
+ if (clip_right - clip_left <= 0
+ || clip_bottom - clip_top <= 0)
+ {
+ XUnmapWindow (xv->dpy, xv->wdesc);
+ xv->hidden = true;
+ }
+ else
+ {
+ XResizeWindow (xv->dpy, xv->wdesc, clip_right - clip_left,
+ clip_bottom - clip_top);
+ }
+ XFlush (xv->dpy);
+ cairo_xlib_surface_set_size (xv->cr_surface, clip_right - clip_left,
+ clip_bottom - clip_top);
+ }
#elif defined NS_IMPL_COCOA
nsxwidget_resize_view (xv, clip_right - clip_left,
clip_bottom - clip_top);
@@ -755,37 +1963,45 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
a redraw. It seems its possible to get out of sync with emacs
redraws so emacs background sometimes shows up instead of the
xwidgets background. It's just a visual glitch though. */
- if (!xwidget_hidden (xv))
+ /* When xww->buffer is nil, that means the xwidget has been killed. */
+ if (!NILP (xww->buffer))
{
+ if (!xwidget_hidden (xv))
+ {
#ifdef USE_GTK
- gtk_widget_queue_draw (xv->widgetwindow);
- gtk_widget_queue_draw (xv->widget);
+ gtk_widget_queue_draw (xww->widget_osr);
#elif defined NS_IMPL_COCOA
- nsxwidget_set_needsdisplay (xv);
+ nsxwidget_set_needsdisplay (xv);
#endif
+ }
}
-}
+#ifdef USE_GTK
+ else
+ {
+ XSetWindowBackground (xv->dpy, xv->wdesc,
+ FRAME_BACKGROUND_PIXEL (s->f));
+ }
+#endif
+
+#ifdef HAVE_XINPUT2
+ record_osr_embedder (xv);
+ synthesize_focus_in_event (xww->widget_osr);
+#endif
-static bool
-xwidget_is_web_view (struct xwidget *xw)
-{
#ifdef USE_GTK
- return xw->widget_osr != NULL && WEBKIT_IS_WEB_VIEW (xw->widget_osr);
-#elif defined NS_IMPL_COCOA
- return nsxwidget_is_web_view (xw);
+ unblock_input ();
#endif
}
+#define CHECK_WEBKIT_WIDGET(xw) \
+ if (NILP (xw->buffer) || !EQ (xw->type, Qwebkit)) \
+ error ("Not a WebKit widget")
+
/* Macro that checks xwidget hold webkit web view first. */
#define WEBKIT_FN_INIT() \
- CHECK_XWIDGET (xwidget); \
+ CHECK_LIVE_XWIDGET (xwidget); \
struct xwidget *xw = XXWIDGET (xwidget); \
- if (!xwidget_is_web_view (xw)) \
- { \
- fputs ("ERROR xw->widget_osr does not hold a webkit instance\n", \
- stdout); \
- return Qnil; \
- }
+ CHECK_WEBKIT_WIDGET (xw)
DEFUN ("xwidget-webkit-uri",
Fxwidget_webkit_uri, Sxwidget_webkit_uri,
@@ -796,7 +2012,10 @@ DEFUN ("xwidget-webkit-uri",
WEBKIT_FN_INIT ();
#ifdef USE_GTK
WebKitWebView *wkwv = WEBKIT_WEB_VIEW (xw->widget_osr);
- return build_string (webkit_web_view_get_uri (wkwv));
+ const gchar *uri = webkit_web_view_get_uri (wkwv);
+ if (!uri)
+ return build_string ("");
+ return build_string (uri);
#elif defined NS_IMPL_COCOA
return nsxwidget_webkit_uri (xw);
#endif
@@ -830,6 +2049,7 @@ DEFUN ("xwidget-webkit-goto-uri",
uri = ENCODE_FILE (uri);
#ifdef USE_GTK
webkit_web_view_load_uri (WEBKIT_WEB_VIEW (xw->widget_osr), SSDATA (uri));
+ catch_child_signal ();
#elif defined NS_IMPL_COCOA
nsxwidget_webkit_goto_uri (xw, SSDATA (uri));
#endif
@@ -839,21 +2059,32 @@ DEFUN ("xwidget-webkit-goto-uri",
DEFUN ("xwidget-webkit-goto-history",
Fxwidget_webkit_goto_history, Sxwidget_webkit_goto_history,
2, 2, 0,
- doc: /* Make the XWIDGET webkit load REL-POS (-1, 0, 1) page in browse history. */)
+ doc: /* Make the XWIDGET webkit the REL-POSth element in load history.
+
+If REL-POS is 0, the widget will be just reload the current element in
+history. If REL-POS is more or less than 0, the widget will load the
+REL-POSth element around the current spot in the load history. */)
(Lisp_Object xwidget, Lisp_Object rel_pos)
{
WEBKIT_FN_INIT ();
- /* Should be one of -1, 0, 1 */
- if (XFIXNUM (rel_pos) < -1 || XFIXNUM (rel_pos) > 1)
- args_out_of_range_3 (rel_pos, make_fixnum (-1), make_fixnum (1));
+ CHECK_FIXNUM (rel_pos);
#ifdef USE_GTK
WebKitWebView *wkwv = WEBKIT_WEB_VIEW (xw->widget_osr);
- switch (XFIXNAT (rel_pos))
+ WebKitBackForwardList *list;
+ WebKitBackForwardListItem *it;
+
+ if (XFIXNUM (rel_pos) == 0)
+ webkit_web_view_reload (wkwv);
+ else
{
- case -1: webkit_web_view_go_back (wkwv); break;
- case 0: webkit_web_view_reload (wkwv); break;
- case 1: webkit_web_view_go_forward (wkwv); break;
+ list = webkit_web_view_get_back_forward_list (wkwv);
+ it = webkit_back_forward_list_get_nth_item (list, XFIXNUM (rel_pos));
+
+ if (!it)
+ error ("There is no item at this index");
+
+ webkit_web_view_go_to_back_forward_list_item (wkwv, it);
}
#elif defined NS_IMPL_COCOA
nsxwidget_webkit_goto_history (xw, XFIXNAT (rel_pos));
@@ -946,7 +2177,7 @@ DEFUN ("xwidget-resize", Fxwidget_resize, Sxwidget_resize, 3, 3, 0,
doc: /* Resize XWIDGET to NEW_WIDTH, NEW_HEIGHT. */ )
(Lisp_Object xwidget, Lisp_Object new_width, Lisp_Object new_height)
{
- CHECK_XWIDGET (xwidget);
+ CHECK_LIVE_XWIDGET (xwidget);
int w = check_integer_range (new_width, 0, INT_MAX);
int h = check_integer_range (new_height, 0, INT_MAX);
struct xwidget *xw = XXWIDGET (xwidget);
@@ -954,21 +2185,10 @@ DEFUN ("xwidget-resize", Fxwidget_resize, Sxwidget_resize, 3, 3, 0,
xw->width = w;
xw->height = h;
- /* If there is an offscreen widget resize it first. */
-#ifdef USE_GTK
- if (xw->widget_osr)
- {
- gtk_window_resize (GTK_WINDOW (xw->widgetwindow_osr), xw->width,
- xw->height);
- gtk_container_resize_children (GTK_CONTAINER (xw->widgetwindow_osr));
- gtk_widget_set_size_request (GTK_WIDGET (xw->widget_osr), xw->width,
- xw->height);
- }
-#elif defined NS_IMPL_COCOA
- nsxwidget_resize (xw);
-#endif
+ block_input ();
- for (Lisp_Object tail = Vxwidget_view_list; CONSP (tail); tail = XCDR (tail))
+ for (Lisp_Object tail = internal_xwidget_view_list; CONSP (tail);
+ tail = XCDR (tail))
{
if (XWIDGET_VIEW_P (XCAR (tail)))
{
@@ -976,15 +2196,33 @@ DEFUN ("xwidget-resize", Fxwidget_resize, Sxwidget_resize, 3, 3, 0,
if (XXWIDGET (xv->model) == xw)
{
#ifdef USE_GTK
- gtk_widget_set_size_request (GTK_WIDGET (xv->widget), xw->width,
- xw->height);
-#elif defined NS_IMPL_COCOA
- nsxwidget_resize_view(xv, xw->width, xw->height);
+ xv->just_resized = true;
+ SET_FRAME_GARBAGED (xv->frame);
+#else
+ wset_redisplay (XWINDOW (xv->w));
#endif
}
}
}
+ redisplay ();
+
+ /* If there is an offscreen widget resize it first. */
+#ifdef USE_GTK
+ if (xw->widget_osr)
+ {
+ gtk_window_resize (GTK_WINDOW (xw->widgetwindow_osr), xw->width,
+ xw->height);
+ gtk_widget_set_size_request (GTK_WIDGET (xw->widget_osr), xw->width,
+ xw->height);
+
+ gtk_widget_queue_allocate (GTK_WIDGET (xw->widget_osr));
+ }
+#elif defined NS_IMPL_COCOA
+ nsxwidget_resize (xw);
+#endif
+ unblock_input ();
+
return Qnil;
}
@@ -999,7 +2237,7 @@ This can be used to read the xwidget desired size, and resizes the
Emacs allocated area accordingly. */)
(Lisp_Object xwidget)
{
- CHECK_XWIDGET (xwidget);
+ CHECK_LIVE_XWIDGET (xwidget);
#ifdef USE_GTK
GtkRequisition requisition;
gtk_widget_size_request (XXWIDGET (xwidget)->widget_osr, &requisition);
@@ -1034,7 +2272,7 @@ DEFUN ("xwidget-info",
Currently [TYPE TITLE WIDTH HEIGHT]. */)
(Lisp_Object xwidget)
{
- CHECK_XWIDGET (xwidget);
+ CHECK_LIVE_XWIDGET (xwidget);
struct xwidget *xw = XXWIDGET (xwidget);
return CALLN (Fvector, xw->type, xw->title,
make_fixed_natnum (xw->width), make_fixed_natnum (xw->height));
@@ -1084,18 +2322,34 @@ DEFUN ("delete-xwidget-view",
CHECK_XWIDGET_VIEW (xwidget_view);
struct xwidget_view *xv = XXWIDGET_VIEW (xwidget_view);
#ifdef USE_GTK
- gtk_widget_destroy (xv->widgetwindow);
- /* xv->model still has signals pointing to the view. There can be
- several views. Find the matching signals and delete them all. */
- g_signal_handlers_disconnect_matched (XXWIDGET (xv->model)->widgetwindow_osr,
- G_SIGNAL_MATCH_DATA,
- 0, 0, 0, 0,
- xv->widget);
+ struct xwidget *xw = XXWIDGET (xv->model);
+ GdkWindow *w;
+
+ if (xv->wdesc != None)
+ {
+ block_input ();
+ cairo_destroy (xv->cr_context);
+ cairo_surface_destroy (xv->cr_surface);
+ XDestroyWindow (xv->dpy, xv->wdesc);
+ Fremhash (make_fixnum (xv->wdesc), x_window_to_xwv_map);
+ unblock_input ();
+ }
+
+ if (xw->embedder_view == xv && !NILP (xw->buffer))
+ {
+ w = gtk_widget_get_window (xw->widgetwindow_osr);
+
+ XXWIDGET (xv->model)->embedder_view = NULL;
+ XXWIDGET (xv->model)->embedder = NULL;
+
+ gdk_offscreen_window_set_embedder (w, NULL);
+ }
#elif defined NS_IMPL_COCOA
nsxwidget_delete_view (xv);
#endif
- Vxwidget_view_list = Fdelq (xwidget_view, Vxwidget_view_list);
+ internal_xwidget_view_list = Fdelq (xwidget_view, internal_xwidget_view_list);
+ Vxwidget_view_list = Fcopy_sequence (internal_xwidget_view_list);
return Qnil;
}
@@ -1113,7 +2367,7 @@ Return nil if no association is found. */)
window = Fselected_window ();
CHECK_WINDOW (window);
- for (Lisp_Object tail = Vxwidget_view_list; CONSP (tail);
+ for (Lisp_Object tail = internal_xwidget_view_list; CONSP (tail);
tail = XCDR (tail))
{
Lisp_Object xwidget_view = XCAR (tail);
@@ -1131,7 +2385,7 @@ DEFUN ("xwidget-plist",
doc: /* Return the plist of XWIDGET. */)
(Lisp_Object xwidget)
{
- CHECK_XWIDGET (xwidget);
+ CHECK_LIVE_XWIDGET (xwidget);
return XXWIDGET (xwidget)->plist;
}
@@ -1145,6 +2399,19 @@ DEFUN ("xwidget-buffer",
return XXWIDGET (xwidget)->buffer;
}
+DEFUN ("set-xwidget-buffer",
+ Fset_xwidget_buffer, Sset_xwidget_buffer,
+ 2, 2, 0,
+ doc: /* Set XWIDGET's buffer to BUFFER. */)
+ (Lisp_Object xwidget, Lisp_Object buffer)
+{
+ CHECK_LIVE_XWIDGET (xwidget);
+ CHECK_BUFFER (buffer);
+
+ XXWIDGET (xwidget)->buffer = buffer;
+ return Qnil;
+}
+
DEFUN ("set-xwidget-plist",
Fset_xwidget_plist, Sset_xwidget_plist,
2, 2, 0,
@@ -1152,7 +2419,7 @@ DEFUN ("set-xwidget-plist",
Returns PLIST. */)
(Lisp_Object xwidget, Lisp_Object plist)
{
- CHECK_XWIDGET (xwidget);
+ CHECK_LIVE_XWIDGET (xwidget);
CHECK_LIST (plist);
XXWIDGET (xwidget)->plist = plist;
@@ -1168,7 +2435,7 @@ exiting or killing a buffer if XWIDGET is running.
This function returns FLAG. */)
(Lisp_Object xwidget, Lisp_Object flag)
{
- CHECK_XWIDGET (xwidget);
+ CHECK_LIVE_XWIDGET (xwidget);
XXWIDGET (xwidget)->kill_without_query = NILP (flag);
return flag;
}
@@ -1179,16 +2446,414 @@ DEFUN ("xwidget-query-on-exit-flag",
doc: /* Return the current value of the query-on-exit flag for XWIDGET. */)
(Lisp_Object xwidget)
{
- CHECK_XWIDGET (xwidget);
+ CHECK_LIVE_XWIDGET (xwidget);
return (XXWIDGET (xwidget)->kill_without_query ? Qnil : Qt);
}
+DEFUN ("xwidget-webkit-search", Fxwidget_webkit_search, Sxwidget_webkit_search,
+ 2, 5, 0,
+ doc: /* Begin an incremental search operation in an xwidget.
+QUERY should be a string containing the text to search for. XWIDGET
+should be a WebKit xwidget where the search will take place. When the
+search operation is complete, callers should also call
+`xwidget-webkit-finish-search' to complete the search operation.
+
+CASE-INSENSITIVE, when non-nil, will cause the search to ignore the
+case of characters inside QUERY. BACKWARDS, when non-nil, will cause
+the search to proceed towards the beginning of the widget's contents.
+WRAP-AROUND, when nil, will cause the search to stop upon hitting the
+end of the widget's contents.
+
+It is OK to call this function even when a search is already in
+progress. In that case, the previous search query will be replaced
+with QUERY. */)
+ (Lisp_Object query, Lisp_Object xwidget, Lisp_Object case_insensitive,
+ Lisp_Object backwards, Lisp_Object wrap_around)
+{
+#ifdef USE_GTK
+ WebKitWebView *webview;
+ WebKitFindController *controller;
+ WebKitFindOptions opt;
+ struct xwidget *xw;
+ gchar *g_query;
+#endif
+
+ CHECK_STRING (query);
+ CHECK_LIVE_XWIDGET (xwidget);
+
+#ifdef USE_GTK
+ xw = XXWIDGET (xwidget);
+ CHECK_WEBKIT_WIDGET (xw);
+
+ webview = WEBKIT_WEB_VIEW (xw->widget_osr);
+ query = ENCODE_UTF_8 (query);
+ opt = WEBKIT_FIND_OPTIONS_NONE;
+ g_query = xstrdup (SSDATA (query));
+
+ if (!NILP (case_insensitive))
+ opt |= WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE;
+ if (!NILP (backwards))
+ opt |= WEBKIT_FIND_OPTIONS_BACKWARDS;
+ if (!NILP (wrap_around))
+ opt |= WEBKIT_FIND_OPTIONS_WRAP_AROUND;
+
+ if (xw->find_text)
+ xfree (xw->find_text);
+ xw->find_text = g_query;
+
+ block_input ();
+ controller = webkit_web_view_get_find_controller (webview);
+ webkit_find_controller_search (controller, g_query, opt, G_MAXUINT);
+ unblock_input ();
+#endif
+
+ return Qnil;
+}
+
+DEFUN ("xwidget-webkit-next-result", Fxwidget_webkit_next_result,
+ Sxwidget_webkit_next_result, 1, 1, 0,
+ doc: /* Show the next result matching the current search query.
+
+XWIDGET should be an xwidget that currently has a search query.
+Before calling this function, you should start a search operation
+using `xwidget-webkit-search'. */)
+ (Lisp_Object xwidget)
+{
+ struct xwidget *xw;
+#ifdef USE_GTK
+ WebKitWebView *webview;
+ WebKitFindController *controller;
+#endif
+
+ CHECK_LIVE_XWIDGET (xwidget);
+ xw = XXWIDGET (xwidget);
+ CHECK_WEBKIT_WIDGET (xw);
+
+ if (!xw->find_text)
+ error ("Widget has no ongoing search operation");
+
+#ifdef USE_GTK
+ block_input ();
+ webview = WEBKIT_WEB_VIEW (xw->widget_osr);
+ controller = webkit_web_view_get_find_controller (webview);
+ webkit_find_controller_search_next (controller);
+ unblock_input ();
+#endif
+
+ return Qnil;
+}
+
+DEFUN ("xwidget-webkit-previous-result", Fxwidget_webkit_previous_result,
+ Sxwidget_webkit_previous_result, 1, 1, 0,
+ doc: /* Show the previous result matching the current search query.
+
+XWIDGET should be an xwidget that currently has a search query.
+Before calling this function, you should start a search operation
+using `xwidget-webkit-search'. */)
+ (Lisp_Object xwidget)
+{
+ struct xwidget *xw;
+#ifdef USE_GTK
+ WebKitWebView *webview;
+ WebKitFindController *controller;
+#endif
+
+ CHECK_LIVE_XWIDGET (xwidget);
+ xw = XXWIDGET (xwidget);
+ CHECK_WEBKIT_WIDGET (xw);
+
+ if (!xw->find_text)
+ error ("Widget has no ongoing search operation");
+
+#ifdef USE_GTK
+ block_input ();
+ webview = WEBKIT_WEB_VIEW (xw->widget_osr);
+ controller = webkit_web_view_get_find_controller (webview);
+ webkit_find_controller_search_previous (controller);
+ unblock_input ();
+#endif
+
+ return Qnil;
+}
+
+DEFUN ("xwidget-webkit-finish-search", Fxwidget_webkit_finish_search,
+ Sxwidget_webkit_finish_search, 1, 1, 0,
+ doc: /* Finish XWIDGET's search operation.
+
+XWIDGET should be an xwidget that currently has a search query.
+Before calling this function, you should start a search operation
+using `xwidget-webkit-search'. */)
+ (Lisp_Object xwidget)
+{
+ struct xwidget *xw;
+#ifdef USE_GTK
+ WebKitWebView *webview;
+ WebKitFindController *controller;
+#endif
+
+ CHECK_LIVE_XWIDGET (xwidget);
+ xw = XXWIDGET (xwidget);
+ CHECK_WEBKIT_WIDGET (xw);
+
+ if (!xw->find_text)
+ error ("Widget has no ongoing search operation");
+
+#ifdef USE_GTK
+ block_input ();
+ webview = WEBKIT_WEB_VIEW (xw->widget_osr);
+ controller = webkit_web_view_get_find_controller (webview);
+ webkit_find_controller_search_finish (controller);
+
+ if (xw->find_text)
+ {
+ xfree (xw->find_text);
+ xw->find_text = NULL;
+ }
+ unblock_input ();
+#endif
+
+ return Qnil;
+}
+
+DEFUN ("kill-xwidget", Fkill_xwidget, Skill_xwidget,
+ 1, 1, 0,
+ doc: /* Kill the specified XWIDGET.
+This releases all window system resources associated with XWIDGET,
+removes it from `xwidget-list', and detaches it from its buffer. */)
+ (Lisp_Object xwidget)
+{
+ struct xwidget *xw;
+
+ CHECK_LIVE_XWIDGET (xwidget);
+ xw = XXWIDGET (xwidget);
+
+ block_input ();
+ kill_xwidget (xw);
+ unblock_input ();
+
+ return Qnil;
+}
+
+#ifdef USE_GTK
+DEFUN ("xwidget-webkit-load-html", Fxwidget_webkit_load_html,
+ Sxwidget_webkit_load_html, 2, 3, 0,
+ doc: /* Make XWIDGET's WebKit widget render TEXT.
+XWIDGET should be a WebKit xwidget, that will receive TEXT. TEXT
+should be a string that will be displayed by XWIDGET as HTML markup.
+BASE-URI should be a string containing a URI that is used to locate
+resources with relative URLs, and if not specified, defaults
+to "about:blank". */)
+ (Lisp_Object xwidget, Lisp_Object text, Lisp_Object base_uri)
+{
+ struct xwidget *xw;
+ WebKitWebView *webview;
+ char *data, *uri;
+
+ CHECK_LIVE_XWIDGET (xwidget);
+ CHECK_STRING (text);
+ if (NILP (base_uri))
+ base_uri = build_string ("about:blank");
+ else
+ CHECK_STRING (base_uri);
+
+ base_uri = ENCODE_UTF_8 (base_uri);
+ text = ENCODE_UTF_8 (text);
+ xw = XXWIDGET (xwidget);
+ CHECK_WEBKIT_WIDGET (xw);
+
+ data = SSDATA (text);
+ uri = SSDATA (base_uri);
+ webview = WEBKIT_WEB_VIEW (xw->widget_osr);
+
+ block_input ();
+ webkit_web_view_load_html (webview, data, uri);
+ unblock_input ();
+
+ return Qnil;
+}
+
+DEFUN ("xwidget-webkit-back-forward-list", Fxwidget_webkit_back_forward_list,
+ Sxwidget_webkit_back_forward_list, 1, 2, 0,
+ doc: /* Return the navigation history of XWIDGET, a WebKit xwidget.
+
+Return the history as a list of the form (BACK HERE FORWARD), where
+HERE is the current navigation item, while BACK and FORWARD are lists
+of history items of the form (IDX TITLE URI). Here, IDX is an index
+that can be passed to `xwidget-webkit-goto-history', TITLE is a string
+containing the human-readable title of the history item, and URI is
+the URI of the history item.
+
+BACK, HERE, and FORWARD can all be nil depending on the state of the
+navigation history.
+
+BACK and FORWARD will each not contain more elements than LIMIT. If
+LIMIT is not specified or nil, it is treated as `50'. */)
+ (Lisp_Object xwidget, Lisp_Object limit)
+{
+ struct xwidget *xw;
+ Lisp_Object back, here, forward;
+ WebKitWebView *webview;
+ WebKitBackForwardList *list;
+ WebKitBackForwardListItem *item;
+ GList *parent, *tem;
+ int i;
+ unsigned int lim;
+ Lisp_Object title, uri;
+ const gchar *item_title, *item_uri;
+
+ back = Qnil;
+ here = Qnil;
+ forward = Qnil;
+
+ if (NILP (limit))
+ limit = make_fixnum (50);
+ else
+ CHECK_FIXNAT (limit);
+
+ CHECK_LIVE_XWIDGET (xwidget);
+ xw = XXWIDGET (xwidget);
+
+ webview = WEBKIT_WEB_VIEW (xw->widget_osr);
+ list = webkit_web_view_get_back_forward_list (webview);
+ item = webkit_back_forward_list_get_current_item (list);
+ lim = XFIXNAT (limit);
+
+ if (item)
+ {
+ item_title = webkit_back_forward_list_item_get_title (item);
+ item_uri = webkit_back_forward_list_item_get_uri (item);
+ here = list3 (make_fixnum (0),
+ build_string_from_utf8 (item_title ? item_title : ""),
+ build_string_from_utf8 (item_uri ? item_uri : ""));
+ }
+ parent = webkit_back_forward_list_get_back_list_with_limit (list, lim);
+
+ if (parent)
+ {
+ for (i = 1, tem = parent; tem; tem = tem->next, ++i)
+ {
+ item = tem->data;
+ item_title = webkit_back_forward_list_item_get_title (item);
+ item_uri = webkit_back_forward_list_item_get_uri (item);
+ title = build_string_from_utf8 (item_title ? item_title : "");
+ uri = build_string_from_utf8 (item_uri ? item_uri : "");
+ back = Fcons (list3 (make_fixnum (-i), title, uri), back);
+ }
+ }
+
+ back = Fnreverse (back);
+ g_list_free (parent);
+
+ parent = webkit_back_forward_list_get_forward_list_with_limit (list, lim);
+
+ if (parent)
+ {
+ for (i = 1, tem = parent; tem; tem = tem->next, ++i)
+ {
+ item = tem->data;
+ item_title = webkit_back_forward_list_item_get_title (item);
+ item_uri = webkit_back_forward_list_item_get_uri (item);
+ title = build_string_from_utf8 (item_title ? item_title : "");
+ uri = build_string_from_utf8 (item_uri ? item_uri : "");
+ forward = Fcons (list3 (make_fixnum (i), title, uri), forward);
+ }
+ }
+
+ forward = Fnreverse (forward);
+ g_list_free (parent);
+
+ return list3 (back, here, forward);
+}
+
+DEFUN ("xwidget-webkit-estimated-load-progress",
+ Fxwidget_webkit_estimated_load_progress, Sxwidget_webkit_estimated_load_progress,
+ 1, 1, 0, doc: /* Get the estimated load progress of XWIDGET, a WebKit widget.
+Return a value ranging from 0.0 to 1.0, based on how close XWIDGET
+is to completely loading its page. */)
+ (Lisp_Object xwidget)
+{
+ struct xwidget *xw;
+ WebKitWebView *webview;
+ double value;
+
+ CHECK_LIVE_XWIDGET (xwidget);
+ xw = XXWIDGET (xwidget);
+ CHECK_WEBKIT_WIDGET (xw);
+
+ block_input ();
+ webview = WEBKIT_WEB_VIEW (xw->widget_osr);
+ value = webkit_web_view_get_estimated_load_progress (webview);
+ unblock_input ();
+
+ return make_float (value);
+}
+#endif
+
+DEFUN ("xwidget-webkit-set-cookie-storage-file",
+ Fxwidget_webkit_set_cookie_storage_file, Sxwidget_webkit_set_cookie_storage_file,
+ 2, 2, 0, doc: /* Make the WebKit widget XWIDGET load and store cookies in FILE.
+
+Cookies will be stored as plain text in FILE, which must be an
+absolute file name. All xwidgets related to XWIDGET will also
+store cookies in FILE and load them from there. */)
+ (Lisp_Object xwidget, Lisp_Object file)
+{
+#ifdef USE_GTK
+ struct xwidget *xw;
+ WebKitWebView *webview;
+ WebKitWebContext *context;
+ WebKitCookieManager *manager;
+
+ CHECK_LIVE_XWIDGET (xwidget);
+ xw = XXWIDGET (xwidget);
+ CHECK_WEBKIT_WIDGET (xw);
+ CHECK_STRING (file);
+
+ block_input ();
+ webview = WEBKIT_WEB_VIEW (xw->widget_osr);
+ context = webkit_web_view_get_context (webview);
+ manager = webkit_web_context_get_cookie_manager (context);
+ webkit_cookie_manager_set_persistent_storage (manager,
+ SSDATA (ENCODE_UTF_8 (file)),
+ WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT);
+ unblock_input ();
+#endif
+
+ return Qnil;
+}
+
+DEFUN ("xwidget-webkit-stop-loading", Fxwidget_webkit_stop_loading,
+ Sxwidget_webkit_stop_loading,
+ 1, 1, 0, doc: /* Stop loading data in the WebKit widget XWIDGET.
+This will stop any data transfer that may still be in progress inside
+XWIDGET as part of loading a page. */)
+ (Lisp_Object xwidget)
+{
+#ifdef USE_GTK
+ struct xwidget *xw;
+ WebKitWebView *webview;
+
+ CHECK_LIVE_XWIDGET (xwidget);
+ xw = XXWIDGET (xwidget);
+ CHECK_WEBKIT_WIDGET (xw);
+
+ block_input ();
+ webview = WEBKIT_WEB_VIEW (xw->widget_osr);
+ webkit_web_view_stop_loading (webview);
+ unblock_input ();
+#endif
+
+ return Qnil;
+}
+
void
syms_of_xwidget (void)
{
defsubr (&Smake_xwidget);
defsubr (&Sxwidgetp);
+ defsubr (&Sxwidget_live_p);
DEFSYM (Qxwidgetp, "xwidgetp");
+ DEFSYM (Qxwidget_live_p, "xwidget-live-p");
defsubr (&Sxwidget_view_p);
DEFSYM (Qxwidget_view_p, "xwidget-view-p");
defsubr (&Sxwidget_info);
@@ -1215,6 +2880,20 @@ syms_of_xwidget (void)
defsubr (&Sxwidget_plist);
defsubr (&Sxwidget_buffer);
defsubr (&Sset_xwidget_plist);
+ defsubr (&Sxwidget_perform_lispy_event);
+ defsubr (&Sxwidget_webkit_search);
+ defsubr (&Sxwidget_webkit_finish_search);
+ defsubr (&Sxwidget_webkit_next_result);
+ defsubr (&Sxwidget_webkit_previous_result);
+ defsubr (&Sset_xwidget_buffer);
+ defsubr (&Sxwidget_webkit_set_cookie_storage_file);
+ defsubr (&Sxwidget_webkit_stop_loading);
+#ifdef USE_GTK
+ defsubr (&Sxwidget_webkit_load_html);
+ defsubr (&Sxwidget_webkit_back_forward_list);
+ defsubr (&Sxwidget_webkit_estimated_load_progress);
+#endif
+ defsubr (&Skill_xwidget);
DEFSYM (QCxwidget, ":xwidget");
DEFSYM (QCtitle, ":title");
@@ -1228,14 +2907,29 @@ syms_of_xwidget (void)
DEFSYM (QCplist, ":plist");
DEFVAR_LISP ("xwidget-list", Vxwidget_list,
- doc: /* xwidgets list. */);
+ doc: /* List of all xwidgets that have not been killed. */);
Vxwidget_list = Qnil;
DEFVAR_LISP ("xwidget-view-list", Vxwidget_view_list,
- doc: /* xwidget views list. */);
+ doc: /* List of all xwidget views. */);
Vxwidget_view_list = Qnil;
Fprovide (intern ("xwidget-internal"), Qnil);
+
+ id_to_xwidget_map = CALLN (Fmake_hash_table, QCtest, Qeq,
+ QCweakness, Qvalue);
+ staticpro (&id_to_xwidget_map);
+
+ internal_xwidget_list = Qnil;
+ staticpro (&internal_xwidget_list);
+ internal_xwidget_view_list = Qnil;
+ staticpro (&internal_xwidget_view_list);
+
+#ifdef USE_GTK
+ x_window_to_xwv_map = CALLN (Fmake_hash_table, QCtest, Qeq);
+
+ staticpro (&x_window_to_xwv_map);
+#endif
}
@@ -1276,7 +2970,7 @@ void
xwidget_view_delete_all_in_window (struct window *w)
{
struct xwidget_view *xv = NULL;
- for (Lisp_Object tail = Vxwidget_view_list; CONSP (tail);
+ for (Lisp_Object tail = internal_xwidget_view_list; CONSP (tail);
tail = XCDR (tail))
{
if (XWIDGET_VIEW_P (XCAR (tail)))
@@ -1321,7 +3015,7 @@ lookup_xwidget (Lisp_Object spec)
static void
xwidget_start_redisplay (void)
{
- for (Lisp_Object tail = Vxwidget_view_list; CONSP (tail);
+ for (Lisp_Object tail = internal_xwidget_view_list; CONSP (tail);
tail = XCDR (tail))
{
if (XWIDGET_VIEW_P (XCAR (tail)))
@@ -1374,25 +3068,22 @@ xwidget_end_redisplay (struct window *w, struct glyph_matrix *matrix)
/* The only call to xwidget_end_redisplay is in dispnew.
xwidget_end_redisplay (w->current_matrix); */
struct xwidget_view *xv
- = xwidget_view_lookup (glyph->u.xwidget, w);
-#ifdef USE_GTK
- /* FIXME: Is it safe to assume xwidget_view_lookup
- always succeeds here? If so, this comment can be removed.
- If not, the code probably needs fixing. */
- eassume (xv);
- xwidget_touch (xv);
-#elif defined NS_IMPL_COCOA
- /* In NS xwidget, xv can be NULL for the second or
+ = xwidget_view_lookup (xwidget_from_id (glyph->u.xwidget), w);
+
+ /* In NS xwidget, xv can be NULL for the second or
later views for a model, the result of 1 to 1
- model view relation enforcement. */
+ model view relation enforcement. `xwidget_view_lookup'
+ has also been observed to return NULL here on X-Windows
+ at least once, so stay safe and only touch it if it's
+ not NULL. */
+
if (xv)
xwidget_touch (xv);
-#endif
}
}
}
- for (Lisp_Object tail = Vxwidget_view_list; CONSP (tail);
+ for (Lisp_Object tail = internal_xwidget_view_list; CONSP (tail);
tail = XCDR (tail))
{
if (XWIDGET_VIEW_P (XCAR (tail)))
@@ -1424,6 +3115,78 @@ xwidget_end_redisplay (struct window *w, struct glyph_matrix *matrix)
}
}
+#ifdef USE_GTK
+void
+lower_frame_xwidget_views (struct frame *f)
+{
+ struct xwidget_view *xv;
+
+ for (Lisp_Object tail = internal_xwidget_view_list; CONSP (tail);
+ tail = XCDR (tail))
+ {
+ xv = XXWIDGET_VIEW (XCAR (tail));
+ if (xv->frame == f && xv->wdesc != None)
+ XLowerWindow (xv->dpy, xv->wdesc);
+ }
+}
+
+void
+kill_frame_xwidget_views (struct frame *f)
+{
+ Lisp_Object rem = Qnil;
+
+ for (Lisp_Object tail = internal_xwidget_view_list; CONSP (tail);
+ tail = XCDR (tail))
+ {
+ if (XWIDGET_VIEW_P (XCAR (tail))
+ && XXWIDGET_VIEW (XCAR (tail))->frame == f)
+ rem = Fcons (XCAR (tail), rem);
+ }
+
+ for (; CONSP (rem); rem = XCDR (rem))
+ Fdelete_xwidget_view (XCAR (rem));
+}
+#endif
+
+static void
+kill_xwidget (struct xwidget *xw)
+{
+ Lisp_Object val;
+ XSETXWIDGET (val, xw);
+
+ internal_xwidget_list = Fdelq (val, internal_xwidget_list);
+ Vxwidget_list = Fcopy_sequence (internal_xwidget_list);
+#ifdef USE_GTK
+ xw->buffer = Qnil;
+
+ if (xw->widget_osr && xw->widgetwindow_osr)
+ {
+ gtk_widget_destroy (xw->widget_osr);
+ gtk_widget_destroy (xw->widgetwindow_osr);
+ }
+
+ if (xw->find_text)
+ xfree (xw->find_text);
+
+ if (!NILP (xw->script_callbacks))
+ {
+ for (ptrdiff_t idx = 0; idx < ASIZE (xw->script_callbacks); idx++)
+ {
+ Lisp_Object cb = AREF (xw->script_callbacks, idx);
+ if (!NILP (cb))
+ xfree (xmint_pointer (XCAR (cb)));
+ ASET (xw->script_callbacks, idx, Qnil);
+ }
+ }
+
+ xw->widget_osr = NULL;
+ xw->widgetwindow_osr = NULL;
+ xw->find_text = NULL;
+#elif defined NS_IMPL_COCOA
+ nsxwidget_kill (xw);
+#endif
+}
+
/* Kill all xwidget in BUFFER. */
void
kill_buffer_xwidgets (Lisp_Object buffer)
@@ -1432,28 +3195,11 @@ kill_buffer_xwidgets (Lisp_Object buffer)
for (tail = Fget_buffer_xwidgets (buffer); CONSP (tail); tail = XCDR (tail))
{
xwidget = XCAR (tail);
- Vxwidget_list = Fdelq (xwidget, Vxwidget_list);
- /* TODO free the GTK things in xw. */
{
- CHECK_XWIDGET (xwidget);
+ CHECK_LIVE_XWIDGET (xwidget);
struct xwidget *xw = XXWIDGET (xwidget);
-#ifdef USE_GTK
- if (xw->widget_osr && xw->widgetwindow_osr)
- {
- gtk_widget_destroy (xw->widget_osr);
- gtk_widget_destroy (xw->widgetwindow_osr);
- }
- if (!NILP (xw->script_callbacks))
- for (ptrdiff_t idx = 0; idx < ASIZE (xw->script_callbacks); idx++)
- {
- Lisp_Object cb = AREF (xw->script_callbacks, idx);
- if (!NILP (cb))
- xfree (xmint_pointer (XCAR (cb)));
- ASET (xw->script_callbacks, idx, Qnil);
- }
-#elif defined NS_IMPL_COCOA
- nsxwidget_kill (xw);
-#endif
+
+ kill_xwidget (xw);
}
}
}
diff --git a/src/xwidget.h b/src/xwidget.h
index 591f23489db..a03006fde9a 100644
--- a/src/xwidget.h
+++ b/src/xwidget.h
@@ -32,6 +32,8 @@ struct window;
#if defined (USE_GTK)
#include <gtk/gtk.h>
+#include <X11/Xlib.h>
+#include "xterm.h"
#elif defined (NS_IMPL_COCOA) && defined (__OBJC__)
#import <AppKit/NSView.h>
#import "nsxwidget.h"
@@ -59,11 +61,16 @@ struct xwidget
int height;
int width;
+ uint32_t xwidget_id;
+ char *find_text;
#if defined (USE_GTK)
/* For offscreen widgets, unused if not osr. */
GtkWidget *widget_osr;
GtkWidget *widgetwindow_osr;
+ struct frame *embedder;
+ struct xwidget_view *embedder_view;
+ guint hit_result;
#elif defined (NS_IMPL_COCOA)
# ifdef __OBJC__
/* For offscreen widgets, unused if not osr. */
@@ -97,10 +104,17 @@ struct xwidget_view
/* The "live" instance isn't drawn. */
bool hidden;
+ enum glyph_row_area area;
+
#if defined (USE_GTK)
- GtkWidget *widget;
- GtkWidget *widgetwindow;
- GtkWidget *emacswindow;
+ Display *dpy;
+ Window wdesc;
+ Emacs_Cursor cursor;
+ struct frame *frame;
+
+ cairo_surface_t *cr_surface;
+ cairo_t *cr_context;
+ int just_resized;
#elif defined (NS_IMPL_COCOA)
# ifdef __OBJC__
XvWindow *xvWindow;
@@ -127,9 +141,16 @@ struct xwidget_view
#define XXWIDGET(a) (eassert (XWIDGETP (a)), \
XUNTAG (a, Lisp_Vectorlike, struct xwidget))
+#define XWIDGET_LIVE_P(w) (!NILP ((w)->buffer))
+
#define CHECK_XWIDGET(x) \
CHECK_TYPE (XWIDGETP (x), Qxwidgetp, x)
+#define CHECK_LIVE_XWIDGET(x) \
+ CHECK_TYPE ((XWIDGETP (x) \
+ && XWIDGET_LIVE_P (XXWIDGET (x))), \
+ Qxwidget_live_p, x)
+
/* Test for xwidget_view pseudovector. */
#define XWIDGET_VIEW_P(x) PSEUDOVECTORP (x, PVEC_XWIDGET_VIEW)
#define XXWIDGET_VIEW(a) (eassert (XWIDGET_VIEW_P (a)), \
@@ -162,6 +183,25 @@ void store_xwidget_download_callback_event (struct xwidget *xw,
void store_xwidget_js_callback_event (struct xwidget *xw,
Lisp_Object proc,
Lisp_Object argument);
+
+extern struct xwidget *xwidget_from_id (uint32_t id);
+
+#ifdef HAVE_X_WINDOWS
+struct xwidget_view *xwidget_view_from_window (Window wdesc);
+void xwidget_expose (struct xwidget_view *xv);
+extern void lower_frame_xwidget_views (struct frame *f);
+extern void kill_frame_xwidget_views (struct frame *f);
+extern void xwidget_button (struct xwidget_view *, bool, int,
+ int, int, int, Time);
+extern void xwidget_motion_or_crossing (struct xwidget_view *,
+ const XEvent *);
+#ifdef HAVE_XINPUT2
+extern void xwidget_motion_notify (struct xwidget_view *, double,
+ double, uint, Time);
+extern void xwidget_scroll (struct xwidget_view *, double, double,
+ double, double, uint, Time, bool);
+#endif
+#endif
#else
INLINE_HEADER_BEGIN
INLINE void syms_of_xwidget (void) {}
diff --git a/test/Makefile.in b/test/Makefile.in
index a3412d6b53a..eeda2918fa3 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -31,7 +31,7 @@
SHELL = @SHELL@
srcdir = @srcdir@
-abs_top_srcdir=@abs_top_srcdir@
+abs_top_srcdir = @abs_top_srcdir@
top_builddir = @top_builddir@
VPATH = $(srcdir)
@@ -67,7 +67,7 @@ elpa_opts = $(foreach el,$(elpa_els),$(and $(wildcard $(el)),-L $(dir $(el)) -l
# directory, we can use emacs --chdir.
EMACS = ../src/emacs
-EMACS_EXTRAOPT=
+EMACS_EXTRAOPT =
# Command line flags for Emacs.
# Apparently MSYS bash would convert "-L :" to "-L ;" anyway,
@@ -75,11 +75,16 @@ EMACS_EXTRAOPT=
EMACSOPT = --no-init-file --no-site-file --no-site-lisp -L "$(SEPCHAR)$(srcdir)" $(elpa_opts) $(EMACS_EXTRAOPT)
# Prevent any settings in the user environment causing problems.
-unexport EMACSDATA EMACSDOC EMACSPATH GREP_OPTIONS
+unexport EMACSDATA EMACSDOC EMACSPATH GREP_OPTIONS XDG_CONFIG_HOME
-## To run tests under a debugger, set this to eg: "gdb --args".
+# To run tests under a debugger, set this to eg: "gdb --args".
GDB =
+# Whether a timeout shall be given, writing possibly a core dump.
+ifneq (${EMACS_TEST_TIMEOUT},)
+TEST_TIMEOUT = timeout -s ABRT ${EMACS_TEST_TIMEOUT}
+endif
+
# Set this to 'yes' to run the tests in an interactive instance.
TEST_INTERACTIVE ?= no
@@ -117,7 +122,7 @@ endif
# and prevent locals to influence the text of the errors we expect to receive.
emacs = LANG=C EMACSLOADPATH= \
EMACS_TEST_DIRECTORY=$(abspath $(srcdir)) \
- $(GDB) "$(EMACS)" $(MODULES_EMACSOPT) $(EMACSOPT)
+ $(GDB) $(TEST_TIMEOUT) "$(EMACS)" $(MODULES_EMACSOPT) $(EMACSOPT)
# Set HOME to a nonexistent directory to prevent tests from accessing
# it accidentally (e.g., popping up a gnupg dialog if ~/.authinfo.gpg
@@ -163,11 +168,11 @@ endif
WRITE_LOG = > $@ 2>&1 || { STAT=$$?; cat $@; exit $$STAT; }
## On Hydra or Emba, always show logs for certain problematic tests.
ifdef EMACS_HYDRA_CI
-lisp/net/tramp-tests.log lisp/electric-tests.log \
+lisp/net/tramp-tests.log \
: WRITE_LOG = 2>&1 | tee $@
endif
ifdef EMACS_EMBA_CI
-lisp/filenotify-tests.log lisp/net/tramp-tests.log \
+lisp/filenotify-tests.log lisp/net/tramp-tests.log src/emacs-module-tests.log \
: WRITE_LOG = 2>&1 | tee $@
endif
@@ -247,9 +252,12 @@ endef
$(foreach test,${TESTS},$(eval $(call test_template,${test})))
## Get the tests for only a specific directory.
-SUBDIRS = $(sort $(shell cd ${srcdir} && find lib-src lisp misc src -type d ! -path "*resources*" -print))
+SUBDIRS = $(sort $(shell cd ${srcdir} && find lib-src lisp misc src -type d \
+ ! \( -path "*resources*" -o -path "*auto-save-list" \) -print))
+SUBDIR_TARGETS =
define subdir_template
+ SUBDIR_TARGETS += check-$(subst /,-,$(1))
.PHONY: check-$(subst /,-,$(1))
check-$(subst /,-,$(1)):
@${MAKE} check LOGFILES="$(patsubst %.el,%.log, \
@@ -345,6 +353,7 @@ mostlyclean:
clean:
find . '(' -name '*.log' -o -name '*.log~' ')' $(FIND_DELETE)
+ find . '(' -name '*.xml' -a ! -path '*resources*' ')' $(FIND_DELETE)
rm -f ${srcdir}/lisp/gnus/mml-sec-resources/random_seed
rm -f $(test_module_dir)/*.o $(test_module_dir)/*.so \
$(test_module_dir)/*.dll
@@ -360,5 +369,16 @@ maintainer-clean: distclean bootstrap-clean
.PHONY: check-declare
check-declare:
- $(emacs) -l check-declare \
+ $(emacs) --batch -l check-declare \
--eval '(check-declare-directory "$(srcdir)")'
+
+.PHONY: subdirs subdir-targets generate-test-jobs
+
+subdirs:
+ @echo $(SUBDIRS)
+
+subdir-targets:
+ @echo $(SUBDIR_TARGETS)
+
+generate-test-jobs:
+ @$(MAKE) -C infra generate-test-jobs SUBDIRS="$(SUBDIRS)"
diff --git a/test/README b/test/README
index 97611cf8644..2bd84b5f9b3 100644
--- a/test/README
+++ b/test/README
@@ -22,6 +22,10 @@ following tags are recognized:
to run on a regular basis by users. Instead, it runs on demand
only, or during regression tests.
+* :nativecomp
+ The test runs only if Emacs is configured with Lisp native compiler
+ support.
+
* :unstable
The test is under development. It shall run on demand only.
@@ -110,6 +114,9 @@ mode--only the names of the failed tests are listed. If the
$EMACS_TEST_VERBOSE environment variable is set, the failure summaries
will also include the data from the failing test.
+If the $EMACS_TEST_JUNIT_REPORT environment variable is set to a file
+name, a JUnit test report is generated under this name.
+
Some of the tests require a remote temporary directory
(autorevert-tests.el, filenotify-tests.el, shadowfile-tests.el and
tramp-tests.el). Per default, a mock-up connection method is used
@@ -136,6 +143,11 @@ these test environments.
$EMACS_HYDRA_CI indicates the hydra environment, and $EMACS_EMBA_CI
indicates the emba environment, respectively.
+If tests on these premises take too long, and it is needed to create a
+core dump for further analysis, the environment variable
+$EMACS_TEST_TIMEOUT could set a limit (in seconds) when this shall
+happen.
+
(Also, see etc/compilation.txt for compilation mode font lock tests
and etc/grep.txt for grep mode font lock tests.)
diff --git a/test/data/image/black.gif b/test/data/image/black.gif
new file mode 100644
index 00000000000..6ab623e367e
--- /dev/null
+++ b/test/data/image/black.gif
Binary files differ
diff --git a/test/data/image/black.webp b/test/data/image/black.webp
new file mode 100644
index 00000000000..5dbe716415b
--- /dev/null
+++ b/test/data/image/black.webp
Binary files differ
diff --git a/test/infra/Dockerfile.emba b/test/infra/Dockerfile.emba
index 9f03482c3fd..aef68c6e81e 100644
--- a/test/infra/Dockerfile.emba
+++ b/test/infra/Dockerfile.emba
@@ -28,21 +28,23 @@ FROM debian:stretch as emacs-base
RUN apt-get update && \
apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 \
- libc-dev gcc g++ make autoconf automake libncurses-dev gnutls-dev git texinfo \
+ libc-dev gcc g++ make autoconf automake libncurses-dev gnutls-dev \
+ libdbus-1-dev libacl1-dev acl git texinfo gdb \
&& rm -rf /var/lib/apt/lists/*
FROM emacs-base as emacs-inotify
RUN apt-get update && \
- apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 inotify-tools \
+ apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 \
+ inotify-tools \
&& rm -rf /var/lib/apt/lists/*
COPY . /checkout
WORKDIR /checkout
RUN ./autogen.sh autoconf
RUN ./configure
-RUN make -j4 bootstrap
-RUN make -j4
+# 'make -j4 bootstrap' does not work reliably.
+RUN make bootstrap
FROM emacs-base as emacs-filenotify-gio
@@ -55,13 +57,13 @@ COPY . /checkout
WORKDIR /checkout
RUN ./autogen.sh autoconf
RUN ./configure --with-file-notification=gfile
-RUN make -j4 bootstrap
-RUN make -j4
+RUN make bootstrap
FROM emacs-base as emacs-gnustep
RUN apt-get update && \
- apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 gnustep-devel \
+ apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 \
+ gnustep-devel \
&& rm -rf /var/lib/apt/lists/*
COPY . /checkout
@@ -69,19 +71,35 @@ WORKDIR /checkout
RUN ./autogen.sh autoconf
RUN ./configure --with-ns
RUN make bootstrap
-RUN make -j4
-FROM emacs-base as emacs-native-comp-speed0
+FROM emacs-base as emacs-native-comp
RUN apt-get update && \
- apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 libgccjit-6-dev \
+ apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 \
+ libgccjit-6-dev \
&& rm -rf /var/lib/apt/lists/*
-ARG make_bootstrap_params=""
+FROM emacs-native-comp as emacs-native-comp-speed0
+
+COPY . /checkout
+WORKDIR /checkout
+RUN ./autogen.sh autoconf
+RUN ./configure --with-native-compilation
+RUN make bootstrap -j2 \
+ NATIVE_FULL_AOT=1 BYTE_COMPILE_EXTRA_FLAGS='--eval "(setq comp-speed 0)"'
+
+FROM emacs-native-comp as emacs-native-comp-speed1
+
+COPY . /checkout
+WORKDIR /checkout
+RUN ./autogen.sh autoconf
+RUN ./configure --with-native-compilation
+RUN make bootstrap -j2 BYTE_COMPILE_EXTRA_FLAGS='--eval "(setq comp-speed 1)"'
+
+FROM emacs-native-comp as emacs-native-comp-speed2
COPY . /checkout
WORKDIR /checkout
RUN ./autogen.sh autoconf
-RUN ./configure --with-nativecomp
-RUN make bootstrap -j2 NATIVE_FULL_AOT=1 BYTE_COMPILE_EXTRA_FLAGS='--eval "(setq comp-speed 0)"'
-RUN make -j4
+RUN ./configure --with-native-compilation
+RUN make bootstrap -j2
diff --git a/test/infra/Makefile.in b/test/infra/Makefile.in
new file mode 100644
index 00000000000..368be7392b2
--- /dev/null
+++ b/test/infra/Makefile.in
@@ -0,0 +1,100 @@
+### @configure_input@
+
+# Copyright (C) 2021 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:
+
+## Generate the test-jobs.yml file for emba.
+
+### Code:
+
+SHELL = @SHELL@
+
+top_builddir = @top_builddir@
+
+-include ${top_builddir}/src/verbose.mk
+
+## Get the tests for only a specific directory.
+SUBDIRS ?= $(shell make -s -C .. subdirs)
+SUBDIR_TARGETS =
+FILE = test-jobs.yml
+tn = $$$${test_name}
+cps = $$$$CI_PIPELINE_SOURCE
+
+define subdir_template
+ $(eval target = check-$(subst /,-,$(1)))
+ SUBDIR_TARGETS += $(target)
+
+ $(eval
+ ifeq ($(findstring src, $(1)), src)
+ define changes
+ @echo ' - $(1)/*.{h,c}' >>$(FILE)
+ endef
+ else ifeq ($(findstring eieio, $(1)), eieio)
+ define changes
+ @echo ' - lisp/emacs-lisp/eieio*.el' >>$(FILE)
+ endef
+ else ifeq ($(findstring faceup, $(1)), faceup)
+ define changes
+ @echo ' - lisp/emacs-lisp/faceup*.el' >>$(FILE)
+ endef
+ else ifeq ($(findstring so-long, $(1)), so-long)
+ define changes
+ @echo ' - lisp/so-long*.el' >>$(FILE)
+ endef
+ else ifeq ($(findstring misc, $(1)), misc)
+ define changes
+ @echo ' - admin/*.el' >>$(FILE)
+ endef
+ else
+ define changes
+ @echo ' - $(1)/*.el' >>$(FILE)
+ endef
+ endif)
+
+ $(target):
+ @echo >>$(FILE)
+ @echo 'test-$(subst /,-,$(1))-inotify:' >>$(FILE)
+ @echo ' stage: normal' >>$(FILE)
+ @echo ' extends: [.job-template, .test-template]' >>$(FILE)
+ @echo ' needs:' >>$(FILE)
+ @echo ' - job: build-image-inotify' >>$(FILE)
+ @echo ' optional: true' >>$(FILE)
+ @echo ' rules:' >>$(FILE)
+ @echo " - if: '"'${cps} == "schedule"'"'" >>$(FILE)
+ @echo ' when: never' >>$(FILE)
+ @echo ' - changes:' >>$(FILE)
+ $(changes)
+ @echo ' - test/$(1)/*.el' >>$(FILE)
+ @echo ' - test/$(1)/*resources/**' >>$(FILE)
+ @echo ' variables:' >>$(FILE)
+ @echo ' target: emacs-inotify' >>$(FILE)
+ @echo ' make_params: "-k -C test $(target)"' >>$(FILE)
+endef
+
+$(foreach subdir, $(SUBDIRS), $(eval $(call subdir_template,$(subdir))))
+
+all: generate-test-jobs
+
+.PHONY: generate-test-jobs $(FILE) $(SUBDIR_TARGETS)
+
+generate-test-jobs: $(FILE) $(SUBDIR_TARGETS)
+
+$(FILE):
+ $(AM_V_GEN)
+ @echo "# Generated by \"make generate-test-jobs\", don't edit." >$(FILE)
diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml
index 6876a8b11d8..dd3f517e74a 100644
--- a/test/infra/gitlab-ci.yml
+++ b/test/infra/gitlab-ci.yml
@@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-# GNU Emacs support for the GitLab protocol for CI
+# GNU Emacs support for the GitLab protocol for CI.
# The presence of this file does not imply any FSF/GNU endorsement of
# any particular service that uses that protocol. Also, it is intended for
@@ -44,14 +44,21 @@ workflow:
variables:
GIT_STRATEGY: fetch
EMACS_EMBA_CI: 1
+ EMACS_TEST_JUNIT_REPORT: junit-test-report.xml
+ EMACS_TEST_TIMEOUT: 3600
EMACS_TEST_VERBOSE: 1
- # # Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
+ # Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
# DOCKER_HOST: tcp://docker:2376
# DOCKER_TLS_CERTDIR: "/certs"
- # Put the configuration for each run in a separate directory to avoid conflicts
+ # Put the configuration for each run in a separate directory to
+ # avoid conflicts.
DOCKER_CONFIG: "/.docker-config-${CI_COMMIT_SHA}"
- # We don't use ${CI_COMMIT_SHA} to be able to do one bootstrap across multiple builds
+ DOCKER_BUILDKIT: 1
+ # We don't use ${CI_COMMIT_SHA} to be able to do one bootstrap
+ # across multiple builds.
BUILD_TAG: ${CI_COMMIT_REF_SLUG}
+ # Disable if you don't need it, it can be a security risk.
+ # CI_DEBUG_TRACE: "true"
default:
image: docker:19.03.12
@@ -64,64 +71,46 @@ default:
.job-template:
variables:
test_name: ${CI_JOB_NAME}-${CI_COMMIT_SHORT_SHA}
- rules:
- - changes:
- - "**/Makefile.in"
- - .gitlab-ci.yml
- - aclocal.m4
- - autogen.sh
- - configure.ac
- - lib/*.{h,c}
- - lisp/**/*.el
- - src/*.{h,c}
- - test/infra/*
- - test/lib-src/*.el
- - test/lisp/**/*.el
- - test/src/*.el
- - changes:
- # gfilemonitor, kqueue
- - src/gfilenotify.c
- - src/kqueue.c
- # MS Windows
- - "**/w32*"
- # GNUstep
- - lisp/term/ns-win.el
- - src/ns*.{h,m}
- - src/macfont.{h,m}
- when: never
- # these will be cached across builds
+ # These will be cached across builds.
cache:
key: ${CI_COMMIT_SHA}
paths: []
policy: pull-push
- # these will be saved for followup builds
+ # These will be saved for followup builds.
artifacts:
expire_in: 24 hrs
paths: []
- # using the variables for each job
+ # Using the variables for each job.
script:
- docker pull ${CI_REGISTRY_IMAGE}:${target}-${BUILD_TAG}
- # TODO: with make -j4 several of the tests were failing, for example shadowfile-tests, but passed without it
+ # TODO: with make -j4 several of the tests were failing, for
+ # example shadowfile-tests, but passed without it.
- 'export PWD=$(pwd)'
- - 'docker run -i -e EMACS_EMBA_CI=${EMACS_EMBA_CI} --volumes-from $(docker ps -q -f "label=com.gitlab.gitlab-runner.job.id=${CI_JOB_ID}"):ro --name ${test_name} ${CI_REGISTRY_IMAGE}:${target}-${BUILD_TAG} /bin/bash -c "git fetch ${PWD} HEAD && echo checking out these updated files && git diff --name-only FETCH_HEAD && ( git diff --name-only FETCH_HEAD | xargs git checkout -f FETCH_HEAD ) && make -j4 && make ${make_params}"'
+ - 'docker run -i -e EMACS_EMBA_CI=${EMACS_EMBA_CI} -e EMACS_TEST_JUNIT_REPORT=${EMACS_TEST_JUNIT_REPORT} -e EMACS_TEST_TIMEOUT=${EMACS_TEST_TIMEOUT} -e EMACS_TEST_VERBOSE=${EMACS_TEST_VERBOSE} --volumes-from $(docker ps -q -f "label=com.gitlab.gitlab-runner.job.id=${CI_JOB_ID}"):ro --name ${test_name} ${CI_REGISTRY_IMAGE}:${target}-${BUILD_TAG} /bin/bash -c "git fetch ${PWD} HEAD && echo checking out these updated files && git diff --name-only FETCH_HEAD && ( git diff --name-only FETCH_HEAD | xargs git checkout -f FETCH_HEAD ) && make -j4 && make ${make_params}"'
after_script:
# - docker ps -a
# - printenv
# - test -n "$(docker ps -aq -f name=${test_name})" && ( docker export ${test_name} | tar -tvf - )
+ # Prepare test artifacts.
- test -n "$(docker ps -aq -f name=${test_name})" && docker cp ${test_name}:checkout/test ${test_name}
- test -n "$(docker ps -aq -f name=${test_name})" && docker rm ${test_name}
+ - find ${test_name} ! \( -name "*.log" -o -name ${EMACS_TEST_JUNIT_REPORT} \) -type f -delete
+ # BusyBox find does not know -empty.
+ - find ${test_name} -type d -depth -exec rmdir {} + 2>/dev/null
.build-template:
+ needs: []
rules:
- if: '$CI_PIPELINE_SOURCE == "web"'
when: always
- changes:
- - "**/Makefile.in"
- - .gitlab-ci.yml
+ - "**.in"
+ - GNUmakefile
- aclocal.m4
- autogen.sh
- configure.ac
- lib/*.{h,c}
+ - lib/malloc/*.{h,c}
- lisp/emacs-lisp/*.el
- src/*.{h,c}
- test/infra/*
@@ -130,7 +119,7 @@ default:
- src/gfilenotify.c
- src/kqueue.c
# MS Windows
- - "**/w32*"
+ - "**w32*"
# GNUstep
- lisp/term/ns-win.el
- src/ns*.{h,m}
@@ -141,30 +130,26 @@ default:
- docker push ${CI_REGISTRY_IMAGE}:${target}-${BUILD_TAG}
.test-template:
- # Do not run fast and normal test jobs when scheduled
- rules:
- - if: '$CI_JOB_STAGE =~ "fast|normal" && $CI_PIPELINE_SOURCE == "schedule"'
- when: never
- - when: always
artifacts:
name: ${test_name}
public: true
expire_in: 1 week
+ when: always
paths:
- - "${test_name}/**/*.log"
+ - ${test_name}/
+ reports:
+ junit: ${test_name}/${EMACS_TEST_JUNIT_REPORT}
.gnustep-template:
rules:
- if: '$CI_PIPELINE_SOURCE == "web"'
- if: '$CI_PIPELINE_SOURCE == "schedule"'
changes:
- - "**/Makefile.in"
- - .gitlab-ci.yml
- - configure.ac
+ - "**.in"
- src/ns*.{h,m}
- src/macfont.{h,m}
- lisp/term/ns-win.el
- - nextstep/**/*
+ - nextstep/**
- test/infra/*
.filenotify-gio-template:
@@ -172,8 +157,7 @@ default:
- if: '$CI_PIPELINE_SOURCE == "web"'
- if: '$CI_PIPELINE_SOURCE == "schedule"'
changes:
- - "**/Makefile.in"
- - .gitlab-ci.yml
+ - "**.in"
- lisp/autorevert.el
- lisp/filenotify.el
- lisp/net/tramp-sh.el
@@ -187,8 +171,7 @@ default:
- if: '$CI_PIPELINE_SOURCE == "web"'
- if: '$CI_PIPELINE_SOURCE == "schedule"'
changes:
- - "**/Makefile.in"
- - .gitlab-ci.yml
+ - "**.in"
- lisp/emacs-lisp/comp.el
- lisp/emacs-lisp/comp-cstr.el
- src/comp.{h,m}
@@ -198,132 +181,98 @@ default:
timeout: 8 hours
stages:
- - prep-images
- build-images
- - fast
- normal
- platform-images
- platforms
- native-comp-images
- native-comp
- - slow
-
-prep-image-base:
- stage: prep-images
- extends: [.job-template, .build-template]
- variables:
- target: emacs-base
build-image-inotify:
stage: build-images
extends: [.job-template, .build-template]
- needs: [prep-image-base]
variables:
target: emacs-inotify
-test-fast-inotify:
- stage: fast
- extends: [.job-template, .test-template]
- variables:
- target: emacs-inotify
- make_params: "-C test check"
-
-test-lisp-inotify:
- stage: normal
- extends: [.job-template, .test-template]
- variables:
- target: emacs-inotify
- make_params: "-C test check-lisp"
+include: '/test/infra/test-jobs.yml'
-test-lisp-net-inotify:
+test-all-inotify:
+ # This tests also file monitor libraries inotify and inotifywatch.
stage: normal
extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ # Note there's no "changes" section, so this always runs on a schedule.
+ - if: '$CI_PIPELINE_SOURCE == "web"'
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
variables:
target: emacs-inotify
- make_params: "-C test check-lisp-net"
+ make_params: check-expensive
build-image-filenotify-gio:
stage: platform-images
extends: [.job-template, .build-template, .filenotify-gio-template]
- needs: [prep-image-base]
variables:
target: emacs-filenotify-gio
-build-image-gnustep:
- stage: platform-images
- extends: [.job-template, .build-template, .gnustep-template]
- needs: [prep-image-base]
- variables:
- target: emacs-gnustep
-
test-filenotify-gio:
# This tests file monitor libraries gfilemonitor and gio.
stage: platforms
- needs: [build-image-filenotify-gio]
extends: [.job-template, .test-template, .filenotify-gio-template]
+ needs:
+ - job: build-image-filenotify-gio
+ optional: true
variables:
target: emacs-filenotify-gio
- make_params: "-k -C test autorevert-tests.log filenotify-tests.log"
+ # This is needed in order to get a JUnit test report.
+ make_params: '-k -C test check-expensive LOGFILES="lisp/autorevert-tests.log lisp/filenotify-tests.log"'
+
+build-image-gnustep:
+ stage: platform-images
+ extends: [.job-template, .build-template, .gnustep-template]
+ variables:
+ target: emacs-gnustep
test-gnustep:
- # This tests the GNUstep build process
+ # This tests the GNUstep build process.
stage: platforms
- needs: [build-image-gnustep]
extends: [.job-template, .gnustep-template]
+ needs:
+ - job: build-image-gnustep
+ optional: true
variables:
target: emacs-gnustep
make_params: install
-build-native-bootstrap-speed0:
+build-native-comp-speed0:
stage: native-comp-images
extends: [.job-template, .build-template, .native-comp-template]
- needs: [prep-image-base]
variables:
target: emacs-native-comp-speed0
-# build-native-bootstrap-speed0:
-# # Test a full native bootstrap
-# # Run for now only speed 0 to limit memory usage and compilation time.
-# stage: native-comp-images
-# # Uncomment the following to run it only when scheduled.
-# # only:
-# # - schedules
-# script:
-# - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y -qq -o=Dpkg::Use-Pty=0 libgccjit-6-dev
-# - ./autogen.sh autoconf
-# - ./configure --with-nativecomp
-# - make bootstrap NATIVE_FULL_AOT=1 BYTE_COMPILE_EXTRA_FLAGS='--eval "(setq comp-speed 0)"' -j2
-# timeout: 8 hours
-
-# build-native-bootstrap-speed1:
-# stage: native-comp-images
-# script:
-# - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y -qq -o=Dpkg::Use-Pty=0 libgccjit-6-dev
-# - ./autogen.sh autoconf
-# - ./configure --with-nativecomp
-# - make bootstrap BYTE_COMPILE_EXTRA_FLAGS='--eval "(setq comp-speed 1)"'
-# timeout: 8 hours
+build-native-comp-speed1:
+ stage: native-comp-images
+ extends: [.job-template, .build-template, .native-comp-template]
+ variables:
+ target: emacs-native-comp-speed1
-# build-native-bootstrap-speed2:
-# stage: native-comp-images
-# script:
-# - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y -qq -o=Dpkg::Use-Pty=0 libgccjit-6-dev
-# - ./autogen.sh autoconf
-# - ./configure --with-nativecomp
-# - make bootstrap
-# timeout: 8 hours
+build-native-comp-speed2:
+ stage: native-comp-images
+ extends: [.job-template, .build-template, .native-comp-template]
+ variables:
+ target: emacs-native-comp-speed2
-test-all-inotify:
- # This tests also file monitor libraries inotify and inotifywatch.
- stage: slow
- extends: [.job-template, .test-template]
- rules:
- # note there's no "changes" section, so this always runs on a schedule
- - if: '$CI_PIPELINE_SOURCE == "web"'
- - if: '$CI_PIPELINE_SOURCE == "schedule"'
+test-native-comp-speed0:
+ stage: native-comp
+ extends: [.job-template, .test-template, .native-comp-template]
+ needs:
+ - job: build-native-comp-speed0
+ optional: true
variables:
- target: emacs-inotify
- make_params: check-expensive
+ target: emacs-native-comp-speed0
+ make_params: "-k -C test check SELECTOR='(not (tag :unstable))'"
# Local Variables:
# add-log-current-defun-header-regexp: "^\\([-_.[:alnum:]]+\\)[ \t]*:"
diff --git a/test/infra/test-jobs.yml b/test/infra/test-jobs.yml
new file mode 100644
index 00000000000..51707c181b1
--- /dev/null
+++ b/test/infra/test-jobs.yml
@@ -0,0 +1,545 @@
+# Generated by "make generate-test-jobs", don't edit.
+
+test-lib-src-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lib-src/*.{h,c}
+ - test/lib-src/*.el
+ - test/lib-src/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lib-src"
+
+test-lisp-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/*.el
+ - test/lisp/*.el
+ - test/lisp/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp"
+
+test-lisp-calc-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/calc/*.el
+ - test/lisp/calc/*.el
+ - test/lisp/calc/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-calc"
+
+test-lisp-calendar-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/calendar/*.el
+ - test/lisp/calendar/*.el
+ - test/lisp/calendar/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-calendar"
+
+test-lisp-cedet-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/cedet/*.el
+ - test/lisp/cedet/*.el
+ - test/lisp/cedet/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-cedet"
+
+test-lisp-cedet-semantic-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/cedet/semantic/*.el
+ - test/lisp/cedet/semantic/*.el
+ - test/lisp/cedet/semantic/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-cedet-semantic"
+
+test-lisp-cedet-semantic-bovine-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/cedet/semantic/bovine/*.el
+ - test/lisp/cedet/semantic/bovine/*.el
+ - test/lisp/cedet/semantic/bovine/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-cedet-semantic-bovine"
+
+test-lisp-cedet-srecode-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/cedet/srecode/*.el
+ - test/lisp/cedet/srecode/*.el
+ - test/lisp/cedet/srecode/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-cedet-srecode"
+
+test-lisp-emacs-lisp-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/emacs-lisp/*.el
+ - test/lisp/emacs-lisp/*.el
+ - test/lisp/emacs-lisp/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-emacs-lisp"
+
+test-lisp-emacs-lisp-eieio-tests-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/emacs-lisp/eieio*.el
+ - test/lisp/emacs-lisp/eieio-tests/*.el
+ - test/lisp/emacs-lisp/eieio-tests/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-emacs-lisp-eieio-tests"
+
+test-lisp-emacs-lisp-faceup-tests-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/emacs-lisp/faceup*.el
+ - test/lisp/emacs-lisp/faceup-tests/*.el
+ - test/lisp/emacs-lisp/faceup-tests/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-emacs-lisp-faceup-tests"
+
+test-lisp-emulation-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/emulation/*.el
+ - test/lisp/emulation/*.el
+ - test/lisp/emulation/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-emulation"
+
+test-lisp-erc-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/erc/*.el
+ - test/lisp/erc/*.el
+ - test/lisp/erc/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-erc"
+
+test-lisp-eshell-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/eshell/*.el
+ - test/lisp/eshell/*.el
+ - test/lisp/eshell/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-eshell"
+
+test-lisp-gnus-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/gnus/*.el
+ - test/lisp/gnus/*.el
+ - test/lisp/gnus/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-gnus"
+
+test-lisp-image-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/image/*.el
+ - test/lisp/image/*.el
+ - test/lisp/image/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-image"
+
+test-lisp-international-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/international/*.el
+ - test/lisp/international/*.el
+ - test/lisp/international/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-international"
+
+test-lisp-mail-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/mail/*.el
+ - test/lisp/mail/*.el
+ - test/lisp/mail/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-mail"
+
+test-lisp-mh-e-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/mh-e/*.el
+ - test/lisp/mh-e/*.el
+ - test/lisp/mh-e/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-mh-e"
+
+test-lisp-net-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/net/*.el
+ - test/lisp/net/*.el
+ - test/lisp/net/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-net"
+
+test-lisp-nxml-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/nxml/*.el
+ - test/lisp/nxml/*.el
+ - test/lisp/nxml/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-nxml"
+
+test-lisp-obsolete-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/obsolete/*.el
+ - test/lisp/obsolete/*.el
+ - test/lisp/obsolete/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-obsolete"
+
+test-lisp-org-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/org/*.el
+ - test/lisp/org/*.el
+ - test/lisp/org/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-org"
+
+test-lisp-play-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/play/*.el
+ - test/lisp/play/*.el
+ - test/lisp/play/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-play"
+
+test-lisp-progmodes-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/progmodes/*.el
+ - test/lisp/progmodes/*.el
+ - test/lisp/progmodes/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-progmodes"
+
+test-lisp-so-long-tests-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/so-long*.el
+ - test/lisp/so-long-tests/*.el
+ - test/lisp/so-long-tests/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-so-long-tests"
+
+test-lisp-term-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/term/*.el
+ - test/lisp/term/*.el
+ - test/lisp/term/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-term"
+
+test-lisp-textmodes-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/textmodes/*.el
+ - test/lisp/textmodes/*.el
+ - test/lisp/textmodes/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-textmodes"
+
+test-lisp-url-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/url/*.el
+ - test/lisp/url/*.el
+ - test/lisp/url/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-url"
+
+test-lisp-vc-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - lisp/vc/*.el
+ - test/lisp/vc/*.el
+ - test/lisp/vc/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-lisp-vc"
+
+test-misc-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - admin/*.el
+ - test/misc/*.el
+ - test/misc/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-misc"
+
+test-src-inotify:
+ stage: normal
+ extends: [.job-template, .test-template]
+ needs:
+ - job: build-image-inotify
+ optional: true
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
+ when: never
+ - changes:
+ - src/*.{h,c}
+ - test/src/*.el
+ - test/src/*resources/**
+ variables:
+ target: emacs-inotify
+ make_params: "-k -C test check-src"
diff --git a/test/lisp/abbrev-tests.el b/test/lisp/abbrev-tests.el
index 2a42d5636d3..863806af7b3 100644
--- a/test/lisp/abbrev-tests.el
+++ b/test/lisp/abbrev-tests.el
@@ -28,6 +28,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'abbrev)
(require 'seq)
@@ -106,7 +107,7 @@
(should (abbrev-table-empty-p table))))
(ert-deftest kill-all-abbrevs-test ()
- "Test undefining all defined abbrevs"
+ "Test undefining all defined abbrevs."
(unless noninteractive
(ert-skip "Cannot test kill-all-abbrevs in interactive mode"))
@@ -125,14 +126,14 @@
abbrev-table-name-list))))))
(ert-deftest abbrev-table-name-test ()
- "Test returning name of abbrev-table"
+ "Test returning name of abbrev-table."
(let ((ert-test-abbrevs (setup-test-abbrev-table))
(no-such-table nil))
(should (equal 'ert-test-abbrevs (abbrev-table-name ert-test-abbrevs)))
(should (equal nil (abbrev-table-name no-such-table)))))
(ert-deftest clear-abbrev-table-test ()
- "Test clearing single abbrev table"
+ "Test clearing single abbrev table."
(let ((ert-test-abbrevs (setup-test-abbrev-table)))
(should (equal "abbrev-ert-test" (abbrev-expansion "a-e-t" ert-test-abbrevs)))
(clear-abbrev-table ert-test-abbrevs)
@@ -140,7 +141,7 @@
(should (equal t (abbrev-table-empty-p ert-test-abbrevs)))))
(ert-deftest list-abbrevs-test ()
- "Test generation of abbrev list buffer"
+ "Test generation of abbrev list buffer."
;; Somewhat redundant as prepare-abbrev-list-buffer is also tested.
;; all abbrevs
(let ((abbrev-buffer (prepare-abbrev-list-buffer)))
@@ -152,7 +153,7 @@
(kill-buffer abbrev-buffer)))
(ert-deftest prepare-abbrev-list-buffer-test ()
- "Test generation of abbrev list buffer"
+ "Test generation of abbrev list buffer."
;; all abbrevs
(let ((ert-test-abbrevs (setup-test-abbrev-table)))
(with-current-buffer (prepare-abbrev-list-buffer)
@@ -180,7 +181,7 @@
(kill-buffer "*Abbrevs*"))))
(ert-deftest insert-abbrevs-test ()
- "Test inserting abbrev definitions into buffer"
+ "Test inserting abbrev definitions into buffer."
(with-temp-buffer
(insert-abbrevs)
(should (progn
@@ -188,7 +189,7 @@
(search-forward "global-abbrev-table")))))
(ert-deftest edit-abbrevs-test ()
- "Test editing abbrevs from buffer"
+ "Test editing abbrevs from buffer."
(defvar ert-edit-abbrevs-test-table nil)
(let ((ert-test-abbrevs (setup-test-abbrev-table)))
(with-temp-buffer
@@ -205,7 +206,7 @@
(abbrev-expansion "e-a-t" ert-edit-abbrevs-test-table))))))
(ert-deftest define-abbrevs-test ()
- "Test defining abbrevs from buffer"
+ "Test defining abbrevs from buffer."
(defvar ert-bad-abbrev-table nil)
(defvar ert-good-abbrev-table nil)
(defvar ert-redefine-abbrev-table nil)
@@ -235,45 +236,42 @@
(should (equal nil (abbrev-expansion "g-a-t" ert-good-abbrev-table)))))
(ert-deftest read-write-abbrev-file-test ()
- "Test reading and writing abbrevs from file"
- (let ((temp-test-file (make-temp-file "ert-abbrev-test"))
- (ert-test-abbrevs (setup-test-abbrev-table)))
- (write-abbrev-file temp-test-file)
- (clear-abbrev-table ert-test-abbrevs)
- (should (abbrev-table-empty-p ert-test-abbrevs))
- (read-abbrev-file temp-test-file)
- (should (equal "abbrev-ert-test" (abbrev-expansion "a-e-t" ert-test-abbrevs)))
- (delete-file temp-test-file)))
+ "Test reading and writing abbrevs from file."
+ (ert-with-temp-file temp-test-file
+ (let ((ert-test-abbrevs (setup-test-abbrev-table)))
+ (write-abbrev-file temp-test-file)
+ (clear-abbrev-table ert-test-abbrevs)
+ (should (abbrev-table-empty-p ert-test-abbrevs))
+ (read-abbrev-file temp-test-file)
+ (should (equal "abbrev-ert-test" (abbrev-expansion "a-e-t" ert-test-abbrevs))))))
(ert-deftest read-write-abbrev-file-test-with-props ()
- "Test reading and writing abbrevs from file"
- (let ((temp-test-file (make-temp-file "ert-abbrev-test"))
- (ert-test-abbrevs (setup-test-abbrev-table-with-props)))
- (write-abbrev-file temp-test-file)
- (clear-abbrev-table ert-test-abbrevs)
- (should (abbrev-table-empty-p ert-test-abbrevs))
- (read-abbrev-file temp-test-file)
- (should (equal "fooBar" (abbrev-expansion "fb" ert-test-abbrevs)))
- (delete-file temp-test-file)))
+ "Test reading and writing abbrevs from file."
+ (ert-with-temp-file temp-test-file
+ (let ((ert-test-abbrevs (setup-test-abbrev-table-with-props)))
+ (write-abbrev-file temp-test-file)
+ (clear-abbrev-table ert-test-abbrevs)
+ (should (abbrev-table-empty-p ert-test-abbrevs))
+ (read-abbrev-file temp-test-file)
+ (should (equal "fooBar" (abbrev-expansion "fb" ert-test-abbrevs))))))
(ert-deftest abbrev-edit-save-to-file-test ()
- "Test saving abbrev definitions in buffer to file"
+ "Test saving abbrev definitions in buffer to file."
(defvar ert-save-test-table nil)
- (let ((temp-test-file (make-temp-file "ert-abbrev-test"))
- (ert-test-abbrevs (setup-test-abbrev-table)))
- (with-temp-buffer
- (goto-char (point-min))
- (insert "(ert-save-test-table)\n")
- (insert "\n" "\"s-a-t\"\t" "0\t" "\"save-abbrevs-test\"\n")
- (should (equal "abbrev-ert-test"
- (abbrev-expansion "a-e-t" ert-test-abbrevs)))
- ;; clears abbrev tables
- (abbrev-edit-save-to-file temp-test-file)
- (should-not (abbrev-expansion "a-e-t" ert-test-abbrevs))
- (read-abbrev-file temp-test-file)
- (should (equal "save-abbrevs-test"
- (abbrev-expansion "s-a-t" ert-save-test-table)))
- (delete-file temp-test-file))))
+ (ert-with-temp-file temp-test-file
+ (let ((ert-test-abbrevs (setup-test-abbrev-table)))
+ (with-temp-buffer
+ (goto-char (point-min))
+ (insert "(ert-save-test-table)\n")
+ (insert "\n" "\"s-a-t\"\t" "0\t" "\"save-abbrevs-test\"\n")
+ (should (equal "abbrev-ert-test"
+ (abbrev-expansion "a-e-t" ert-test-abbrevs)))
+ ;; clears abbrev tables
+ (abbrev-edit-save-to-file temp-test-file)
+ (should-not (abbrev-expansion "a-e-t" ert-test-abbrevs))
+ (read-abbrev-file temp-test-file)
+ (should (equal "save-abbrevs-test"
+ (abbrev-expansion "s-a-t" ert-save-test-table)))))))
(ert-deftest inverse-add-abbrev-skips-trailing-nonword ()
"Test that adding an inverse abbrev skips trailing nonword characters."
diff --git a/test/lisp/ansi-color-tests.el b/test/lisp/ansi-color-tests.el
index 107dc8e400b..14a14ca4f06 100644
--- a/test/lisp/ansi-color-tests.el
+++ b/test/lisp/ansi-color-tests.el
@@ -3,7 +3,6 @@
;; Copyright (C) 2020-2021 Free Software Foundation, Inc.
;; Author: Pablo Barbáchano <pablob@amazon.com>
-;; Keywords: ansi
;; This file is part of GNU Emacs.
@@ -25,24 +24,154 @@
;;; Code:
(require 'ansi-color)
+(eval-when-compile (require 'cl-lib))
-(defvar test-strings '(("\e[33mHello World\e[0m" . "Hello World")
- ("\e[1m\e[3m\e[5mbold italics blink\e[0m" . "bold italics blink")))
+(defvar ansi-color-tests--strings
+ (let ((bright-yellow (face-foreground 'ansi-color-bright-yellow nil 'default))
+ (yellow (face-foreground 'ansi-color-yellow nil 'default))
+ (custom-color "#87FFFF"))
+ `(("Hello World" "Hello World")
+ ("\e[33mHello World\e[0m" "Hello World"
+ (:foreground ,yellow))
+ ("\e[43mHello World\e[0m" "Hello World"
+ (:background ,yellow))
+ ("\e[93mHello World\e[0m" "Hello World"
+ (:foreground ,bright-yellow))
+ ("\e[103mHello World\e[0m" "Hello World"
+ (:background ,bright-yellow))
+ ("\e[1;33mHello World\e[0m" "Hello World"
+ (ansi-color-bold (:foreground ,yellow))
+ (ansi-color-bold (:foreground ,bright-yellow)))
+ ("\e[33;1mHello World\e[0m" "Hello World"
+ (ansi-color-bold (:foreground ,yellow))
+ (ansi-color-bold (:foreground ,bright-yellow)))
+ ("\e[1m\e[33mHello World\e[0m" "Hello World"
+ (ansi-color-bold (:foreground ,yellow))
+ (ansi-color-bold (:foreground ,bright-yellow)))
+ ("\e[33m\e[1mHello World\e[0m" "Hello World"
+ (ansi-color-bold (:foreground ,yellow))
+ (ansi-color-bold (:foreground ,bright-yellow)))
+ ("\e[1m\e[3m\e[5mbold italics blink\e[0m" "bold italics blink"
+ (ansi-color-bold ansi-color-italic ansi-color-slow-blink))
+ ("\e[10munrecognized\e[0m" "unrecognized")
+ ("\e[38;5;3;1mHello World\e[0m" "Hello World"
+ (ansi-color-bold (:foreground ,yellow))
+ (ansi-color-bold (:foreground ,bright-yellow)))
+ ("\e[48;5;123;1mHello World\e[0m" "Hello World"
+ (ansi-color-bold (:background ,custom-color)))
+ ("\e[48;2;135;255;255;1mHello World\e[0m" "Hello World"
+ (ansi-color-bold (:background ,custom-color))))))
+
+(defun ansi-color-tests-equal-props (o1 o2)
+ "Return t if two Lisp objects have similar structure and contents.
+While `equal-including-properties' compares text properties of
+strings with `eq', this function compares them with `equal'."
+ (or (equal-including-properties o1 o2)
+ (and (stringp o1)
+ (equal o1 o2)
+ (cl-loop for i below (length o1)
+ always (equal (text-properties-at i o1)
+ (text-properties-at i o2))))))
(ert-deftest ansi-color-apply-on-region-test ()
- (dolist (pair test-strings)
- (with-temp-buffer
- (insert (car pair))
+ (pcase-dolist (`(,input ,text ,face) ansi-color-tests--strings)
+ (with-temp-buffer
+ (insert input)
+ (ansi-color-apply-on-region (point-min) (point-max))
+ (should (equal (buffer-string) text))
+ (should (equal (get-char-property (point-min) 'face) face))
+ (when face
+ (should (overlays-at (point-min)))))))
+
+(ert-deftest ansi-color-apply-on-region-bold-is-bright-test ()
+ (pcase-dolist (`(,input ,text ,normal-face ,bright-face)
+ ansi-color-tests--strings)
+ (with-temp-buffer
+ (let ((ansi-color-bold-is-bright t)
+ (face (or bright-face normal-face)))
+ (insert input)
(ansi-color-apply-on-region (point-min) (point-max))
- (should (equal (buffer-string) (cdr pair)))
- (should (not (equal (overlays-at (point-min)) nil))))))
+ (should (equal (buffer-string) text))
+ (should (equal (get-char-property (point-min) 'face) face))
+ (when face
+ (should (overlays-at (point-min))))))))
(ert-deftest ansi-color-apply-on-region-preserving-test ()
- (dolist (pair test-strings)
- (with-temp-buffer
- (insert (car pair))
- (ansi-color-apply-on-region (point-min) (point-max) t)
- (should (equal (buffer-string) (car pair))))))
+ (dolist (pair ansi-color-tests--strings)
+ (with-temp-buffer
+ (insert (car pair))
+ (ansi-color-apply-on-region (point-min) (point-max) t)
+ (should (equal (buffer-string) (car pair))))))
+
+(ert-deftest ansi-color-incomplete-sequences-test ()
+ (let* ((strs (list "\e[" "2;31m Hello World "
+ "\e" "[108;5;12" "3m" "Greetings"
+ "\e[0m\e[35;6m" "Hello"))
+ (complete-str (apply #'concat strs))
+ (filtered-str)
+ (propertized-str)
+ (ansi-color-apply-face-function
+ #'ansi-color-apply-text-property-face)
+ (ansi-filt (lambda (str) (ansi-color-filter-apply
+ (copy-sequence str))))
+ (ansi-app (lambda (str) (ansi-color-apply
+ (copy-sequence str)))))
+
+ (with-temp-buffer
+ (setq filtered-str
+ (replace-regexp-in-string "\e\\[.*?m" "" complete-str))
+ (setq propertized-str (funcall ansi-app complete-str))
+
+ (should-not (ansi-color-tests-equal-props
+ filtered-str propertized-str))
+ (should (equal filtered-str propertized-str)))
+
+ ;; Tests for `ansi-color-filter-apply'
+ (with-temp-buffer
+ (should (equal-including-properties
+ filtered-str
+ (funcall ansi-filt complete-str))))
+
+ (with-temp-buffer
+ (should (equal-including-properties
+ filtered-str
+ (mapconcat ansi-filt strs ""))))
+
+ ;; Tests for `ansi-color-filter-region'
+ (with-temp-buffer
+ (insert complete-str)
+ (ansi-color-filter-region (point-min) (point-max))
+ (should (equal-including-properties
+ filtered-str (buffer-string))))
+
+ (with-temp-buffer
+ (dolist (str strs)
+ (let ((opoint (point)))
+ (insert str)
+ (ansi-color-filter-region opoint (point))))
+ (should (equal-including-properties
+ filtered-str (buffer-string))))
+
+ ;; Test for `ansi-color-apply'
+ (with-temp-buffer
+ (should (ansi-color-tests-equal-props
+ propertized-str
+ (mapconcat ansi-app strs ""))))
+
+ ;; Tests for `ansi-color-apply-on-region'
+ (with-temp-buffer
+ (insert complete-str)
+ (ansi-color-apply-on-region (point-min) (point-max))
+ (should (ansi-color-tests-equal-props
+ propertized-str (buffer-string))))
+
+ (with-temp-buffer
+ (dolist (str strs)
+ (let ((opoint (point)))
+ (insert str)
+ (ansi-color-apply-on-region opoint (point))))
+ (should (ansi-color-tests-equal-props
+ propertized-str (buffer-string))))))
(provide 'ansi-color-tests)
diff --git a/test/lisp/arc-mode-tests.el b/test/lisp/arc-mode-tests.el
index 5c6af9b45cf..b05a9629c16 100644
--- a/test/lisp/arc-mode-tests.el
+++ b/test/lisp/arc-mode-tests.el
@@ -48,4 +48,4 @@
(provide 'arc-mode-tests)
-;; arc-mode-tests.el ends here
+;;; arc-mode-tests.el ends here
diff --git a/test/lisp/auth-source-pass-tests.el b/test/lisp/auth-source-pass-tests.el
index d050ac5b695..3da6f3e9b7b 100644
--- a/test/lisp/auth-source-pass-tests.el
+++ b/test/lisp/auth-source-pass-tests.el
@@ -56,10 +56,10 @@
("key2" . "please: keep my space after colon"))))))
(defvar auth-source-pass--debug-log nil
- "Contains a list of all messages passed to `auth-source-do-debug`.")
+ "Contains a list of all messages passed to `auth-source-do-debug'.")
(defun auth-source-pass--have-message-matching (regexp)
- "Return non-nil iff at least one `auth-source-do-debug` match REGEXP."
+ "Return non-nil iff at least one `auth-source-do-debug' match REGEXP."
(seq-find (lambda (message)
(string-match regexp message))
auth-source-pass--debug-log))
@@ -75,8 +75,8 @@ REGEXP is the same as in `auth-source-pass--have-message-matching'."
(put #'auth-source-pass--have-message-matching 'ert-explainer #'auth-source-pass--explain--have-message-matching)
(defun auth-source-pass--debug (&rest msg)
- "Format MSG and add that to `auth-source-pass--debug-log`.
-This function is intended to be set to `auth-source-debug`."
+ "Format MSG and add that to `auth-source-pass--debug-log'.
+This function is intended to be set to `auth-source-debug'."
(add-to-list 'auth-source-pass--debug-log (apply #'format msg) t))
(defvar auth-source-pass--parse-log nil)
@@ -97,7 +97,8 @@ This function is intended to be set to `auth-source-debug`."
(defun auth-source-pass--explain-match-entry-p (entry hostname &optional user port)
"Explainer function for `auth-source-pass-match-entry-p'.
-ENTRY, HOSTNAME, USER and PORT are the same as in `auth-source-pass-match-entry-p'."
+ENTRY, HOSTNAME, USER and PORT are the same as in
+`auth-source-pass-match-entry-p'."
`(entry
,entry
store
@@ -122,7 +123,8 @@ HOSTNAME, USER and PORT are passed unchanged to
(defun auth-source-pass--explain-includes-sorted-entries (entries hostname &optional user port)
"Explainer function for `auth-source-pass--includes-sorted-entries'.
-ENTRIES, HOSTNAME, USER and PORT are the same as in `auth-source-pass--includes-sorted-entries'."
+ENTRIES, HOSTNAME, USER and PORT are the same as in
+`auth-source-pass--includes-sorted-entries'."
`(store
,(auth-source-pass-entries)
matching-entries
diff --git a/test/lisp/auth-source-tests.el b/test/lisp/auth-source-tests.el
index 1c4bd8d36d4..34c68b421c9 100644
--- a/test/lisp/auth-source-tests.el
+++ b/test/lisp/auth-source-tests.el
@@ -27,6 +27,7 @@
;;; Code:
(require 'ert)
+(eval-when-compile (require 'ert-x))
(require 'cl-lib)
(require 'auth-source)
(require 'secrets)
@@ -247,7 +248,7 @@
(should-not (auth-source-remembered-p '(:host t)))))
(ert-deftest auth-source-test-searches ()
- "Test auth-source searches with various parameters"
+ "Test auth-source searches with various parameters."
:tags '(auth-source auth-source/netrc)
(let* ((entries '("machine a1 port a2 user a3 password a4"
"machine b1 port b2 user b3 password b4"
@@ -277,34 +278,33 @@
"((:host \"a1\" :port \"a2\" :user \"a3\" :secret \"a4\") (:host \"b1\" :port \"b2\" :user \"b3\" :secret \"b4\") (:host \"c1\" :port \"c2\" :user \"c3\" :secret \"c4\"))"
:host t :max 4)
("host b1, default max is 1"
- "((:host \"b1\" :port \"b2\" :user \"b3\" :secret \"b4\"))"
+ "((:host \"b1\" :port \"b2\" :user \"b3\" :secret \"b4\"))"
:host "b1")
("host b1, port b2, user b3, default max is 1"
- "((:host \"b1\" :port \"b2\" :user \"b3\" :secret \"b4\"))"
+ "((:host \"b1\" :port \"b2\" :user \"b3\" :secret \"b4\"))"
:host "b1" :port "b2" :user "b3")
- ))
-
- (netrc-file (make-temp-file "auth-source-test" nil nil
- (mapconcat 'identity entries "\n")))
- (auth-sources (list netrc-file))
- (auth-source-do-cache nil)
- found found-as-string)
-
- (dolist (test tests)
- (cl-destructuring-bind (testname needed &rest parameters) test
- (setq found (apply #'auth-source-search parameters))
- (when (listp found)
- (dolist (f found)
- (setf f (plist-put f :secret
- (let ((secret (plist-get f :secret)))
- (if (functionp secret)
- (funcall secret)
- secret))))))
-
- (setq found-as-string (format "%s: %S" testname found))
- ;; (message "With parameters %S found: [%s] needed: [%s]" parameters found-as-string needed)
- (should (equal found-as-string (concat testname ": " needed)))))
- (delete-file netrc-file)))
+ )))
+ (ert-with-temp-file netrc-file
+ :text (mapconcat 'identity entries "\n")
+ (let ((auth-sources (list netrc-file))
+ (auth-source-do-cache nil)
+ found found-as-string)
+
+ (dolist (test tests)
+ (cl-destructuring-bind (testname needed &rest parameters) test
+ (setq found (apply #'auth-source-search parameters))
+ (when (listp found)
+ (dolist (f found)
+ (setf f (plist-put f :secret
+ (let ((secret (plist-get f :secret)))
+ (if (functionp secret)
+ (funcall secret)
+ secret))))))
+
+ (setq found-as-string (format "%s: %S" testname found))
+ ;; (message "With parameters %S found: [%s] needed: [%s]"
+ ;; parameters found-as-string needed)
+ (should (equal found-as-string (concat testname ": " needed)))))))))
(ert-deftest auth-source-test-secrets-create-secret ()
(skip-unless secrets-enabled)
@@ -312,59 +312,121 @@
;; Emacs process. Therefore, we don't care to delete it.
(let ((auth-sources '((:source (:secrets "session"))))
(auth-source-save-behavior t)
- (host (md5 (concat (prin1-to-string process-environment)
- (current-time-string))))
- (passwd (md5 (concat (prin1-to-string process-environment)
- (current-time-string) (current-time-string))))
- auth-info auth-passwd)
- ;; Redefine `read-*' in order to avoid interactive input.
- (cl-letf (((symbol-function 'read-passwd) (lambda (_) passwd))
- ((symbol-function 'read-string)
- (lambda (_prompt &optional _initial _history default
- _inherit-input-method)
- default)))
- (setq auth-info
- (car (auth-source-search
- :max 1 :host host :require '(:user :secret) :create t))))
- (should (functionp (plist-get auth-info :save-function)))
- (funcall (plist-get auth-info :save-function))
-
- ;; Check, that the item has been created indeed.
- (auth-source-forget+ :host t)
- (setq auth-info (car (auth-source-search :host host))
- auth-passwd (plist-get auth-info :secret)
- auth-passwd (if (functionp auth-passwd)
- (funcall auth-passwd)
- auth-passwd))
- (should (string-equal (plist-get auth-info :user) (user-login-name)))
- (should (string-equal (plist-get auth-info :host) host))
- (should (string-equal auth-passwd passwd))
-
- ;; Cleanup.
- ;; Should use `auth-source-delete' when implemented for :secrets backend.
- (secrets-delete-item
- "session"
- (format "%s@%s" (plist-get auth-info :user) (plist-get auth-info :host)))))
+ host auth-info auth-passwd)
+ (dolist (passwd '("foo" "" nil))
+ (unwind-protect
+ ;; Redefine `read-*' in order to avoid interactive input.
+ (cl-letf (((symbol-function 'read-passwd) (lambda (_) passwd))
+ ((symbol-function 'read-string)
+ (lambda (_prompt &optional _initial _history default
+ _inherit-input-method)
+ default)))
+ (setq host
+ (md5 (concat (prin1-to-string process-environment) passwd))
+ auth-info
+ (car (auth-source-search
+ :max 1 :host host :require '(:user :secret) :create t))
+ auth-passwd (plist-get auth-info :secret)
+ auth-passwd (if (functionp auth-passwd)
+ (funcall auth-passwd)
+ auth-passwd))
+ (should (string-equal (plist-get auth-info :user) (user-login-name)))
+ (should (string-equal (plist-get auth-info :host) host))
+ (should (equal auth-passwd passwd))
+ (when (functionp (plist-get auth-info :save-function))
+ (funcall (plist-get auth-info :save-function)))
+
+ ;; Check, that the item has been created indeed.
+ (auth-source-forget+ :host t)
+ (setq auth-info (car (auth-source-search :host host))
+ auth-passwd (plist-get auth-info :secret)
+ auth-passwd (if (functionp auth-passwd)
+ (funcall auth-passwd)
+ auth-passwd))
+ (if (zerop (length passwd))
+ (progn
+ (should-not (plist-get auth-info :user))
+ (should-not (plist-get auth-info :host))
+ (should-not auth-passwd))
+ (should
+ (string-equal (plist-get auth-info :user) (user-login-name)))
+ (should (string-equal (plist-get auth-info :host) host))
+ (should (string-equal auth-passwd passwd)))))
+
+ ;; Cleanup.
+ ;; Should use `auth-source-delete' when implemented for :secrets backend.
+ (secrets-delete-item
+ "session"
+ (format "%s@%s" (plist-get auth-info :user) (plist-get auth-info :host))))))
+
+(ert-deftest auth-source-test-netrc-create-secret ()
+ (ert-with-temp-file netrc-file
+ :suffix "auth-source-test"
+ (let* ((auth-sources (list netrc-file))
+ (auth-source-save-behavior t)
+ host auth-info auth-passwd)
+ (dolist (passwd '("foo" "" nil))
+ ;; Redefine `read-*' in order to avoid interactive input.
+ (cl-letf (((symbol-function 'read-passwd) (lambda (_) passwd))
+ ((symbol-function 'read-string)
+ (lambda (_prompt &optional _initial _history default
+ _inherit-input-method)
+ default)))
+ (setq host
+ (md5 (concat (prin1-to-string process-environment) passwd))
+ auth-info
+ (car (auth-source-search
+ :max 1 :host host :require '(:user :secret) :create t))
+ auth-passwd (plist-get auth-info :secret)
+ auth-passwd (if (functionp auth-passwd)
+ (funcall auth-passwd)
+ auth-passwd))
+ (should (string-equal (plist-get auth-info :user) (user-login-name)))
+ (should (string-equal (plist-get auth-info :host) host))
+ (should (equal auth-passwd passwd))
+ (when (functionp (plist-get auth-info :save-function))
+ (funcall (plist-get auth-info :save-function)))
+
+ ;; Check, that the item has been created indeed.
+ (auth-source-forget+ :host t)
+ (setq auth-source-netrc-cache nil)
+ (setq auth-info (car (auth-source-search :host host))
+ auth-passwd (plist-get auth-info :secret)
+ auth-passwd (if (functionp auth-passwd)
+ (funcall auth-passwd)
+ auth-passwd))
+ (with-temp-buffer
+ (insert-file-contents netrc-file)
+ (if (zerop (length passwd))
+ (progn
+ (should-not (plist-get auth-info :user))
+ (should-not (plist-get auth-info :host))
+ (should-not auth-passwd)
+ (should-not (search-forward host nil 'noerror)))
+ (should
+ (string-equal (plist-get auth-info :user) (user-login-name)))
+ (should (string-equal (plist-get auth-info :host) host))
+ (should (string-equal auth-passwd passwd))
+ (should (search-forward host nil 'noerror)))))))))
(ert-deftest auth-source-delete ()
- (let* ((netrc-file (make-temp-file "auth-source-test" nil nil "\
+ (ert-with-temp-file netrc-file
+ :suffix "auth-source-test" :text "\
machine a1 port a2 user a3 password a4
machine b1 port b2 user b3 password b4
-machine c1 port c2 user c3 password c4\n"))
- (auth-sources (list netrc-file))
- (auth-source-do-cache nil)
- (expected '((:host "a1" :port "a2" :user "a3" :secret "a4")))
- (parameters '(:max 1 :host t)))
- (unwind-protect
- (let ((found (apply #'auth-source-delete parameters)))
- (dolist (f found)
- (let ((s (plist-get f :secret)))
- (setf f (plist-put f :secret
- (if (functionp s) (funcall s) s)))))
- ;; Note: The netrc backend doesn't delete anything, so
- ;; this is actually the same as `auth-source-search'.
- (should (equal found expected)))
- (delete-file netrc-file))))
+machine c1 port c2 user c3 password c4\n"
+ (let* ((auth-sources (list netrc-file))
+ (auth-source-do-cache nil)
+ (expected '((:host "a1" :port "a2" :user "a3" :secret "a4")))
+ (parameters '(:max 1 :host t))
+ (found (apply #'auth-source-delete parameters)))
+ (dolist (f found)
+ (let ((s (plist-get f :secret)))
+ (setf f (plist-put f :secret
+ (if (functionp s) (funcall s) s)))))
+ ;; Note: The netrc backend doesn't delete anything, so
+ ;; this is actually the same as `auth-source-search'.
+ (should (equal found expected)))))
(provide 'auth-source-tests)
;;; auth-source-tests.el ends here
diff --git a/test/lisp/autoinsert-tests.el b/test/lisp/autoinsert-tests.el
index 7ec4bf63791..b264323ca15 100644
--- a/test/lisp/autoinsert-tests.el
+++ b/test/lisp/autoinsert-tests.el
@@ -28,6 +28,7 @@
(require 'autoinsert)
(require 'ert)
+(require 'ert-x)
(ert-deftest autoinsert-tests-auto-insert-skeleton ()
(let ((auto-insert-alist '((text-mode nil "f" _ "oo")))
@@ -39,16 +40,14 @@
(should (equal (point) (+ (point-min) 1))))))
(ert-deftest autoinsert-tests-auto-insert-file ()
- (let ((temp-file (make-temp-file "autoinsert-tests" nil nil "foo")))
- (unwind-protect
- (let ((auto-insert-alist `((text-mode . ,temp-file)))
- (auto-insert-query nil))
- (with-temp-buffer
- (text-mode)
- (auto-insert)
- (should (equal (buffer-string) "foo"))))
- (when (file-exists-p temp-file)
- (delete-file temp-file)))))
+ (ert-with-temp-file temp-file
+ :text "foo"
+ (let ((auto-insert-alist `((text-mode . ,temp-file)))
+ (auto-insert-query nil))
+ (with-temp-buffer
+ (text-mode)
+ (auto-insert)
+ (should (equal (buffer-string) "foo"))))))
(ert-deftest autoinsert-tests-auto-insert-function ()
(let ((auto-insert-alist '((text-mode . (lambda () (insert "foo")))))
diff --git a/test/lisp/autorevert-tests.el b/test/lisp/autorevert-tests.el
index 96169c75d3d..b31f0a9afc4 100644
--- a/test/lisp/autorevert-tests.el
+++ b/test/lisp/autorevert-tests.el
@@ -127,7 +127,7 @@ This expects `auto-revert--messages' to be bound by
`ert-with-message-capture' before calling."
;; Remote files do not cooperate well with timers. So we count ourselves.
(let ((ct (current-time)))
- (while (and (< (float-time (time-subtract (current-time) ct))
+ (while (and (< (float-time (time-subtract nil ct))
(auto-revert--timeout))
(null (string-match
(format-message
@@ -167,49 +167,48 @@ This expects `auto-revert--messages' to be bound by
(defun auto-revert-tests--write-file (text file time-delta &optional append)
(write-region text nil file append 'no-message)
- (set-file-times file (time-subtract (current-time) time-delta)))
+ (set-file-times file (time-subtract nil time-delta)))
(ert-deftest auto-revert-test00-auto-revert-mode ()
"Check autorevert for a file."
;; `auto-revert-buffers' runs every 5". And we must wait, until the
;; file has been reverted.
(with-auto-revert-test
- (let ((tmpfile (make-temp-file "auto-revert-test"))
- (times '(60 30 15))
- buf)
- (unwind-protect
- (progn
- (auto-revert-tests--write-file "any text" tmpfile (pop times))
- (setq buf (find-file-noselect tmpfile))
- (with-current-buffer buf
- (ert-with-message-capture auto-revert--messages
- (should (string-equal (buffer-string) "any text"))
- ;; `buffer-stale--default-function' checks for
- ;; `verify-visited-file-modtime'. We must ensure that it
- ;; returns nil.
- (auto-revert-mode 1)
- (should auto-revert-mode)
-
- (auto-revert-tests--write-file "another text" tmpfile (pop times))
-
- ;; Check, that the buffer has been reverted.
- (auto-revert--wait-for-revert buf))
- (should (string-match "another text" (buffer-string)))
-
- ;; When the buffer is modified, it shall not be reverted.
- (ert-with-message-capture auto-revert--messages
- (set-buffer-modified-p t)
- (auto-revert-tests--write-file "any text" tmpfile (pop times))
-
- ;; Check, that the buffer hasn't been reverted.
- (auto-revert--wait-for-revert buf))
- (should-not (string-match "any text" (buffer-string)))))
-
- ;; Exit.
- (ignore-errors
- (with-current-buffer buf (set-buffer-modified-p nil))
- (kill-buffer buf))
- (ignore-errors (delete-file tmpfile))))))
+ (ert-with-temp-file tmpfile
+ (let ((times '(60 30 15))
+ buf)
+ (unwind-protect
+ (progn
+ (auto-revert-tests--write-file "any text" tmpfile (pop times))
+ (setq buf (find-file-noselect tmpfile))
+ (with-current-buffer buf
+ (ert-with-message-capture auto-revert--messages
+ (should (string-equal (buffer-string) "any text"))
+ ;; `buffer-stale--default-function' checks for
+ ;; `verify-visited-file-modtime'. We must ensure that it
+ ;; returns nil.
+ (auto-revert-mode 1)
+ (should auto-revert-mode)
+
+ (auto-revert-tests--write-file "another text" tmpfile (pop times))
+
+ ;; Check, that the buffer has been reverted.
+ (auto-revert--wait-for-revert buf))
+ (should (string-match "another text" (buffer-string)))
+
+ ;; When the buffer is modified, it shall not be reverted.
+ (ert-with-message-capture auto-revert--messages
+ (set-buffer-modified-p t)
+ (auto-revert-tests--write-file "any text" tmpfile (pop times))
+
+ ;; Check, that the buffer hasn't been reverted.
+ (auto-revert--wait-for-revert buf))
+ (should-not (string-match "any text" (buffer-string)))))
+
+ ;; Exit.
+ (ignore-errors
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf)))))))
(auto-revert--deftest-remote auto-revert-test00-auto-revert-mode
"Check autorevert for a remote file.")
@@ -219,63 +218,61 @@ This expects `auto-revert--messages' to be bound by
"Check autorevert for several files at once."
(skip-unless (executable-find "cp" (file-remote-p temporary-file-directory)))
- (with-auto-revert-test
- (let* ((cp (executable-find "cp" (file-remote-p temporary-file-directory)))
- (tmpdir1 (make-temp-file "auto-revert-test" 'dir))
- (tmpdir2 (make-temp-file "auto-revert-test" 'dir))
- (tmpfile1
- (make-temp-file (expand-file-name "auto-revert-test" tmpdir1)))
- (tmpfile2
- (make-temp-file (expand-file-name "auto-revert-test" tmpdir1)))
- (times '(120 60 30 15))
- buf1 buf2)
- (unwind-protect
- (ert-with-message-capture auto-revert--messages
- (auto-revert-tests--write-file "any text" tmpfile1 (pop times))
- (setq buf1 (find-file-noselect tmpfile1))
- (auto-revert-tests--write-file "any text" tmpfile2 (pop times))
- (setq buf2 (find-file-noselect tmpfile2))
-
- (dolist (buf (list buf1 buf2))
- (with-current-buffer buf
- (should (string-equal (buffer-string) "any text"))
- ;; `buffer-stale--default-function' checks for
- ;; `verify-visited-file-modtime'. We must ensure that
- ;; it returns nil.
- (auto-revert-mode 1)
- (should auto-revert-mode)))
-
- ;; Modify files. We wait for a second, in order to have
- ;; another timestamp.
- (auto-revert-tests--write-file
- "another text"
- (expand-file-name (file-name-nondirectory tmpfile1) tmpdir2)
- (pop times))
- (auto-revert-tests--write-file
- "another text"
- (expand-file-name (file-name-nondirectory tmpfile2) tmpdir2)
- (pop times))
- ;;(copy-directory tmpdir2 tmpdir1 nil 'copy-contents)
- ;; Strange, that `copy-directory' does not work as expected.
- ;; The following shell command is not portable on all
- ;; platforms, unfortunately.
- (shell-command
- (format "%s -f %s/* %s"
- cp (file-local-name tmpdir2) (file-local-name tmpdir1)))
-
- ;; Check, that the buffers have been reverted.
- (dolist (buf (list buf1 buf2))
- (with-current-buffer buf
- (auto-revert--wait-for-revert buf)
- (should (string-match "another text" (buffer-string))))))
-
- ;; Exit.
- (ignore-errors
- (dolist (buf (list buf1 buf2))
- (with-current-buffer buf (set-buffer-modified-p nil))
- (kill-buffer buf)))
- (ignore-errors (delete-directory tmpdir1 'recursive))
- (ignore-errors (delete-directory tmpdir2 'recursive))))))
+ (ert-with-temp-directory tmpdir1
+ (ert-with-temp-directory tmpdir2
+ (ert-with-temp-file tmpfile1
+ :prefix (expand-file-name "auto-revert-test" tmpdir1)
+ (ert-with-temp-file tmpfile2
+ :prefix (expand-file-name "auto-revert-test" tmpdir1)
+ (with-auto-revert-test
+ (let* ((cp (executable-find "cp" (file-remote-p temporary-file-directory)))
+ (times '(120 60 30 15))
+ buf1 buf2)
+ (unwind-protect
+ (ert-with-message-capture auto-revert--messages
+ (auto-revert-tests--write-file "any text" tmpfile1 (pop times))
+ (setq buf1 (find-file-noselect tmpfile1))
+ (auto-revert-tests--write-file "any text" tmpfile2 (pop times))
+ (setq buf2 (find-file-noselect tmpfile2))
+
+ (dolist (buf (list buf1 buf2))
+ (with-current-buffer buf
+ (should (string-equal (buffer-string) "any text"))
+ ;; `buffer-stale--default-function' checks for
+ ;; `verify-visited-file-modtime'. We must ensure that
+ ;; it returns nil.
+ (auto-revert-mode 1)
+ (should auto-revert-mode)))
+
+ ;; Modify files. We wait for a second, in order to have
+ ;; another timestamp.
+ (auto-revert-tests--write-file
+ "another text"
+ (expand-file-name (file-name-nondirectory tmpfile1) tmpdir2)
+ (pop times))
+ (auto-revert-tests--write-file
+ "another text"
+ (expand-file-name (file-name-nondirectory tmpfile2) tmpdir2)
+ (pop times))
+ ;;(copy-directory tmpdir2 tmpdir1 nil 'copy-contents)
+ ;; Strange, that `copy-directory' does not work as expected.
+ ;; The following shell command is not portable on all
+ ;; platforms, unfortunately.
+ (shell-command
+ (format "%s -f %s/* %s"
+ cp (file-local-name tmpdir2) (file-local-name tmpdir1)))
+
+ ;; Check, that the buffers have been reverted.
+ (dolist (buf (list buf1 buf2))
+ (with-current-buffer buf
+ (auto-revert--wait-for-revert buf)
+ (should (string-match "another text" (buffer-string))))))
+
+ ;; Exit.
+ (ignore-errors
+ (dolist (buf (list buf1 buf2))
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf)))))))))))
(auto-revert--deftest-remote auto-revert-test01-auto-revert-several-files
"Check autorevert for several remote files at once.")
@@ -285,79 +282,78 @@ This expects `auto-revert--messages' to be bound by
"Check autorevert for a deleted file."
;; Repeated unpredictable failures, bug#32645.
;; Unlikely to be hydra-specific?
-; (skip-unless (not (getenv "EMACS_HYDRA_CI")))
+ ; (skip-unless (not (getenv "EMACS_HYDRA_CI")))
:tags '(:unstable)
(with-auto-revert-test
- (let ((tmpfile (make-temp-file "auto-revert-test"))
- ;; Try to catch bug#32645.
- (auto-revert-debug (getenv "EMACS_HYDRA_CI"))
- (file-notify-debug (getenv "EMACS_HYDRA_CI"))
- (times '(120 60 30 15))
- buf desc)
- (unwind-protect
- (progn
- (auto-revert-tests--write-file "any text" tmpfile (pop times))
- (setq buf (find-file-noselect tmpfile))
- (with-current-buffer buf
- (should-not
- (file-notify-valid-p auto-revert-notify-watch-descriptor))
- (should (string-equal (buffer-string) "any text"))
- ;; `buffer-stale--default-function' checks for
- ;; `verify-visited-file-modtime'. We must ensure that
- ;; it returns nil.
- (auto-revert-mode 1)
- (should auto-revert-mode)
- (setq desc auto-revert-notify-watch-descriptor)
-
- ;; Remove file while reverting. We simulate this by
- ;; modifying `before-revert-hook'.
- (add-hook
- 'before-revert-hook
- (lambda ()
- (when auto-revert-debug
- (message "%s deleted" buffer-file-name))
- (delete-file buffer-file-name))
- nil t)
-
- (ert-with-message-capture auto-revert--messages
- (auto-revert-tests--write-file "another text" tmpfile (pop times))
- (auto-revert--wait-for-revert buf))
- ;; Check, that the buffer hasn't been reverted. File
- ;; notification should be disabled, falling back to
- ;; polling.
- (should (string-match "any text" (buffer-string)))
- ;; With w32notify, and on emba, the `stopped' events are not sent.
- (or (eq file-notify--library 'w32notify)
- (getenv "EMACS_EMBA_CI")
- (should-not
- (file-notify-valid-p auto-revert-notify-watch-descriptor)))
-
- ;; Once the file has been recreated, the buffer shall be
- ;; reverted.
- (kill-local-variable 'before-revert-hook)
- (ert-with-message-capture auto-revert--messages
- (auto-revert-tests--write-file "another text" tmpfile (pop times))
- (auto-revert--wait-for-revert buf))
- ;; Check, that the buffer has been reverted.
- (should (string-match "another text" (buffer-string)))
- ;; When file notification is used, it must be reenabled
- ;; after recreation of the file. We cannot expect that
- ;; the descriptor is the same, so we just check the
- ;; existence.
- (should (eq (null desc) (null auto-revert-notify-watch-descriptor)))
-
- ;; An empty file shall still be reverted.
- (ert-with-message-capture auto-revert--messages
- (auto-revert-tests--write-file "" tmpfile (pop times))
- (auto-revert--wait-for-revert buf))
- ;; Check, that the buffer has been reverted.
- (should (string-equal "" (buffer-string)))))
-
- ;; Exit.
- (ignore-errors
- (with-current-buffer buf (set-buffer-modified-p nil))
- (kill-buffer buf))
- (ignore-errors (delete-file tmpfile))))))
+ (ert-with-temp-file tmpfile
+ (let (;; Try to catch bug#32645.
+ (auto-revert-debug (getenv "EMACS_HYDRA_CI"))
+ (file-notify-debug (getenv "EMACS_HYDRA_CI"))
+ (times '(120 60 30 15))
+ buf desc)
+ (unwind-protect
+ (progn
+ (auto-revert-tests--write-file "any text" tmpfile (pop times))
+ (setq buf (find-file-noselect tmpfile))
+ (with-current-buffer buf
+ (should-not
+ (file-notify-valid-p auto-revert-notify-watch-descriptor))
+ (should (string-equal (buffer-string) "any text"))
+ ;; `buffer-stale--default-function' checks for
+ ;; `verify-visited-file-modtime'. We must ensure that
+ ;; it returns nil.
+ (auto-revert-mode 1)
+ (should auto-revert-mode)
+ (setq desc auto-revert-notify-watch-descriptor)
+
+ ;; Remove file while reverting. We simulate this by
+ ;; modifying `before-revert-hook'.
+ (add-hook
+ 'before-revert-hook
+ (lambda ()
+ (when auto-revert-debug
+ (message "%s deleted" buffer-file-name))
+ (delete-file buffer-file-name))
+ nil t)
+
+ (ert-with-message-capture auto-revert--messages
+ (auto-revert-tests--write-file "another text" tmpfile (pop times))
+ (auto-revert--wait-for-revert buf))
+ ;; Check, that the buffer hasn't been reverted. File
+ ;; notification should be disabled, falling back to
+ ;; polling.
+ (should (string-match "any text" (buffer-string)))
+ ;; With w32notify, and on emba, the `stopped' events are not sent.
+ (or (eq file-notify--library 'w32notify)
+ (getenv "EMACS_EMBA_CI")
+ (should-not
+ (file-notify-valid-p auto-revert-notify-watch-descriptor)))
+
+ ;; Once the file has been recreated, the buffer shall be
+ ;; reverted.
+ (kill-local-variable 'before-revert-hook)
+ (ert-with-message-capture auto-revert--messages
+ (auto-revert-tests--write-file "another text" tmpfile (pop times))
+ (auto-revert--wait-for-revert buf))
+ ;; Check, that the buffer has been reverted.
+ (should (string-match "another text" (buffer-string)))
+ ;; When file notification is used, it must be reenabled
+ ;; after recreation of the file. We cannot expect that
+ ;; the descriptor is the same, so we just check the
+ ;; existence.
+ (should (eq (null desc) (null auto-revert-notify-watch-descriptor)))
+
+ ;; An empty file shall still be reverted.
+ (ert-with-message-capture auto-revert--messages
+ (auto-revert-tests--write-file "" tmpfile (pop times))
+ (auto-revert--wait-for-revert buf))
+ ;; Check, that the buffer has been reverted.
+ (should (string-equal "" (buffer-string)))))
+
+ ;; Exit.
+ (ignore-errors
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf)))))))
(auto-revert--deftest-remote auto-revert-test02-auto-revert-deleted-file
"Check autorevert for a deleted remote file.")
@@ -366,34 +362,33 @@ This expects `auto-revert--messages' to be bound by
"Check autorevert tail mode."
;; `auto-revert-buffers' runs every 5". And we must wait, until the
;; file has been reverted.
- (let ((tmpfile (make-temp-file "auto-revert-test"))
- (times '(30 15))
- buf)
- (unwind-protect
- (ert-with-message-capture auto-revert--messages
- (auto-revert-tests--write-file "any text" tmpfile (pop times))
- (setq buf (find-file-noselect tmpfile))
- (with-current-buffer buf
- ;; `buffer-stale--default-function' checks for
- ;; `verify-visited-file-modtime'. We must ensure that it
- ;; returns nil.
- (auto-revert-tail-mode 1)
- (should auto-revert-tail-mode)
- (erase-buffer)
- (insert "modified text\n")
- (set-buffer-modified-p nil)
-
- ;; Modify file.
- (auto-revert-tests--write-file "another text" tmpfile (pop times) 'append)
-
- ;; Check, that the buffer has been reverted.
- (auto-revert--wait-for-revert buf)
- (should
- (string-match "modified text\nanother text" (buffer-string)))))
-
- ;; Exit.
- (ignore-errors (kill-buffer buf))
- (ignore-errors (delete-file tmpfile)))))
+ (ert-with-temp-file tmpfile
+ (let ((times '(30 15))
+ buf)
+ (unwind-protect
+ (ert-with-message-capture auto-revert--messages
+ (auto-revert-tests--write-file "any text" tmpfile (pop times))
+ (setq buf (find-file-noselect tmpfile))
+ (with-current-buffer buf
+ ;; `buffer-stale--default-function' checks for
+ ;; `verify-visited-file-modtime'. We must ensure that it
+ ;; returns nil.
+ (auto-revert-tail-mode 1)
+ (should auto-revert-tail-mode)
+ (erase-buffer)
+ (insert "modified text\n")
+ (set-buffer-modified-p nil)
+
+ ;; Modify file.
+ (auto-revert-tests--write-file "another text" tmpfile (pop times) 'append)
+
+ ;; Check, that the buffer has been reverted.
+ (auto-revert--wait-for-revert buf)
+ (should
+ (string-match "modified text\nanother text" (buffer-string)))))
+
+ ;; Exit.
+ (ignore-errors (kill-buffer buf))))))
(auto-revert--deftest-remote auto-revert-test03-auto-revert-tail-mode
"Check remote autorevert tail mode.")
@@ -403,46 +398,45 @@ This expects `auto-revert--messages' to be bound by
;; `auto-revert-buffers' runs every 5". And we must wait, until the
;; file has been reverted.
(with-auto-revert-test
- (let* ((tmpfile (make-temp-file "auto-revert-test"))
- (name (file-name-nondirectory tmpfile))
- (times '(30))
- buf)
- (unwind-protect
- (progn
- (setq buf (dired-noselect temporary-file-directory))
- (with-current-buffer buf
- ;; `buffer-stale--default-function' checks for
- ;; `verify-visited-file-modtime'. We must ensure that it
- ;; returns nil.
- (auto-revert-mode 1)
- (should auto-revert-mode)
- (should
- (string-match name (substring-no-properties (buffer-string))))
-
- (ert-with-message-capture auto-revert--messages
- ;; Delete file.
- (delete-file tmpfile)
- (auto-revert--wait-for-revert buf))
- ;; Check, that the buffer has been reverted.
- (should-not
- (string-match name (substring-no-properties (buffer-string))))
-
- (ert-with-message-capture auto-revert--messages
- ;; Make dired buffer modified. Check, that the buffer has
- ;; been still reverted.
- (set-buffer-modified-p t)
- (auto-revert-tests--write-file "any text" tmpfile (pop times))
-
- (auto-revert--wait-for-revert buf))
- ;; Check, that the buffer has been reverted.
- (should
- (string-match name (substring-no-properties (buffer-string))))))
-
- ;; Exit.
- (ignore-errors
- (with-current-buffer buf (set-buffer-modified-p nil))
- (kill-buffer buf))
- (ignore-errors (delete-file tmpfile))))))
+ (ert-with-temp-file tmpfile
+ (let* ((name (file-name-nondirectory tmpfile))
+ (times '(30))
+ buf)
+ (unwind-protect
+ (progn
+ (setq buf (dired-noselect temporary-file-directory))
+ (with-current-buffer buf
+ ;; `buffer-stale--default-function' checks for
+ ;; `verify-visited-file-modtime'. We must ensure that it
+ ;; returns nil.
+ (auto-revert-mode 1)
+ (should auto-revert-mode)
+ (should
+ (string-match name (substring-no-properties (buffer-string))))
+
+ (ert-with-message-capture auto-revert--messages
+ ;; Delete file.
+ (delete-file tmpfile)
+ (auto-revert--wait-for-revert buf))
+ ;; Check, that the buffer has been reverted.
+ (should-not
+ (string-match name (substring-no-properties (buffer-string))))
+
+ (ert-with-message-capture auto-revert--messages
+ ;; Make dired buffer modified. Check, that the buffer has
+ ;; been still reverted.
+ (set-buffer-modified-p t)
+ (auto-revert-tests--write-file "any text" tmpfile (pop times))
+
+ (auto-revert--wait-for-revert buf))
+ ;; Check, that the buffer has been reverted.
+ (should
+ (string-match name (substring-no-properties (buffer-string))))))
+
+ ;; Exit.
+ (ignore-errors
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf)))))))
(auto-revert--deftest-remote auto-revert-test04-auto-revert-mode-dired
"Check remote autorevert for dired.")
@@ -459,7 +453,7 @@ This expects `auto-revert--messages' to be bound by
(defun auto-revert-test--wait-for (pred max-wait)
"Wait until PRED is true, or MAX-WAIT seconds elapsed."
(let ((ct (current-time)))
- (while (and (< (float-time (time-subtract (current-time) ct)) max-wait)
+ (while (and (< (float-time (time-subtract nil ct)) max-wait)
(not (funcall pred)))
(read-event nil nil 0.1))))
@@ -469,86 +463,114 @@ This expects `auto-revert--messages' to be bound by
(lambda () (string-equal (auto-revert-test--buffer-string buffer) string))
max-wait))
+(defun auto-revert-test--instrument-kill-buffer-hook (buffer)
+ "Instrument local `kill-buffer-hook' with messages."
+ (when auto-revert-debug
+ (with-current-buffer buffer
+ (add-hook
+ 'kill-buffer-hook
+ (lambda ()
+ (message
+ "%s killed\n%s" (current-buffer) (with-output-to-string (backtrace))))
+ nil 'local))))
+
(ert-deftest auto-revert-test05-global-notify ()
"Test `global-auto-revert-mode' without polling."
(skip-unless (or file-notify--library
(file-remote-p temporary-file-directory)))
(with-auto-revert-test
- (let* ((auto-revert-use-notify t)
- (auto-revert-avoid-polling t)
- (was-in-global-auto-revert-mode global-auto-revert-mode)
- (file-1 (make-temp-file "global-auto-revert-test-1"))
- (file-2 (make-temp-file "global-auto-revert-test-2"))
- (file-3 (make-temp-file "global-auto-revert-test-3"))
- (file-2b (concat file-2 "-b"))
- require-final-newline buf-1 buf-2 buf-3)
- (unwind-protect
- (progn
- (setq buf-1 (find-file-noselect file-1))
- (setq buf-2 (find-file-noselect file-2))
- (auto-revert-test--write-file "1-a" file-1)
- (should (equal (auto-revert-test--buffer-string buf-1) ""))
-
- (global-auto-revert-mode 1) ; Turn it on.
-
- (should (buffer-local-value
- 'auto-revert-notify-watch-descriptor buf-1))
- (should (buffer-local-value
- 'auto-revert-notify-watch-descriptor buf-2))
-
- ;; buf-1 should have been reverted immediately when the mode
- ;; was enabled.
- (should (equal (auto-revert-test--buffer-string buf-1) "1-a"))
-
- ;; Alter a file.
- (auto-revert-test--write-file "2-a" file-2)
- ;; Allow for some time to handle notification events.
- (auto-revert-test--wait-for-buffer-text buf-2 "2-a" 1)
- (should (equal (auto-revert-test--buffer-string buf-2) "2-a"))
-
- ;; Visit a file, and modify it on disk.
- (setq buf-3 (find-file-noselect file-3))
- ;; Newly opened buffers won't be use notification until the
- ;; first poll cycle; wait for it.
- (auto-revert-test--wait-for
- (lambda () (buffer-local-value
- 'auto-revert-notify-watch-descriptor buf-3))
- (auto-revert--timeout))
- (should (buffer-local-value
- 'auto-revert-notify-watch-descriptor buf-3))
- (auto-revert-test--write-file "3-a" file-3)
- (auto-revert-test--wait-for-buffer-text buf-3 "3-a" 1)
- (should (equal (auto-revert-test--buffer-string buf-3) "3-a"))
-
- ;; Delete a visited file, and re-create it with new contents.
- (delete-file file-1)
- (should (equal (auto-revert-test--buffer-string buf-1) "1-a"))
- (auto-revert-test--write-file "1-b" file-1)
- (auto-revert-test--wait-for-buffer-text
- buf-1 "1-b" (auto-revert--timeout))
- ;; On emba, `buf-1' is a killed buffer.
- (when (buffer-live-p buf-1)
- (should (buffer-local-value
- 'auto-revert-notify-watch-descriptor buf-1)))
-
- ;; Write a buffer to a new file, then modify the new file on disk.
- (with-current-buffer buf-2
- (write-file file-2b))
- (should (equal (auto-revert-test--buffer-string buf-2) "2-a"))
- (auto-revert-test--write-file "2-b" file-2b)
- (auto-revert-test--wait-for-buffer-text
- buf-2 "2-b" (auto-revert--timeout))
- (should (buffer-local-value
- 'auto-revert-notify-watch-descriptor buf-2)))
-
- ;; Clean up.
- (unless was-in-global-auto-revert-mode
- (global-auto-revert-mode 0)) ; Turn it off.
- (dolist (buf (list buf-1 buf-2 buf-3))
- (ignore-errors (kill-buffer buf)))
- (dolist (file (list file-1 file-2 file-2b file-3))
- (ignore-errors (delete-file file)))
- ))))
+ (ert-with-temp-file file-1
+ (ert-with-temp-file file-2
+ (ert-with-temp-file file-3
+ (let* ((auto-revert-use-notify t)
+ (auto-revert-avoid-polling t)
+ (auto-revert-debug (getenv "EMACS_EMBA_CI"))
+ (file-notify-debug (getenv "EMACS_EMBA_CI"))
+ (was-in-global-auto-revert-mode global-auto-revert-mode)
+ (file-2b (concat file-2 "-b"))
+ require-final-newline buf-1 buf-2 buf-3)
+ (unwind-protect
+ (progn
+ (setq buf-1 (find-file-noselect file-1))
+ (auto-revert-test--instrument-kill-buffer-hook buf-1)
+ (setq buf-2 (find-file-noselect file-2))
+ (auto-revert-test--instrument-kill-buffer-hook buf-2)
+ (auto-revert-test--write-file "1-a" file-1)
+ (should (equal (auto-revert-test--buffer-string buf-1) ""))
+
+ (global-auto-revert-mode 1) ; Turn it on.
+
+ (should (buffer-local-value
+ 'auto-revert-notify-watch-descriptor buf-1))
+ (should (buffer-local-value
+ 'auto-revert-notify-watch-descriptor buf-2))
+
+ ;; buf-1 should have been reverted immediately when the mode
+ ;; was enabled.
+ (should (equal (auto-revert-test--buffer-string buf-1) "1-a"))
+
+ ;; Alter a file.
+ (auto-revert-test--write-file "2-a" file-2)
+ ;; Allow for some time to handle notification events.
+ (auto-revert-test--wait-for-buffer-text buf-2 "2-a" 1)
+ (should (equal (auto-revert-test--buffer-string buf-2) "2-a"))
+
+ ;; Visit a file, and modify it on disk.
+ (setq buf-3 (find-file-noselect file-3))
+ (auto-revert-test--instrument-kill-buffer-hook buf-3)
+ ;; Newly opened buffers won't be use notification until the
+ ;; first poll cycle; wait for it.
+ (auto-revert-test--wait-for
+ (lambda () (buffer-local-value
+ 'auto-revert-notify-watch-descriptor buf-3))
+ (auto-revert--timeout))
+ (should (buffer-local-value
+ 'auto-revert-notify-watch-descriptor buf-3))
+ (auto-revert-test--write-file "3-a" file-3)
+ (auto-revert-test--wait-for-buffer-text buf-3 "3-a" 1)
+ (should (equal (auto-revert-test--buffer-string buf-3) "3-a"))
+
+ ;; Delete a visited file, and re-create it with new contents.
+ (when auto-revert-debug (message "Hallo0"))
+ (delete-file file-1)
+ (when auto-revert-debug (message "Hallo1"))
+ (should (equal (auto-revert-test--buffer-string buf-1) "1-a"))
+ (when auto-revert-debug (message "Hallo2"))
+ (auto-revert-test--write-file "1-b" file-1)
+ (when auto-revert-debug (message "Hallo3"))
+ (auto-revert-test--wait-for-buffer-text
+ buf-1 "1-b" (auto-revert--timeout))
+ ;; On emba, `buf-1' is a killed buffer.
+ (when auto-revert-debug
+ (message
+ "Hallo4 %s %s %s %s %s %s %s"
+ buf-1 (buffer-name buf-1) (buffer-live-p buf-1)
+ file-1 (get-file-buffer file-1)
+ (buffer-name (get-file-buffer file-1))
+ (buffer-live-p (get-file-buffer file-1)))
+ (with-current-buffer buf-1
+ (message "Hallo5\n%s" (buffer-local-variables))))
+ (should (buffer-local-value
+ 'auto-revert-notify-watch-descriptor buf-1))
+ (when auto-revert-debug (message "Hallo6"))
+
+ ;; Write a buffer to a new file, then modify the new file on disk.
+ (with-current-buffer buf-2
+ (write-file file-2b))
+ (should (equal (auto-revert-test--buffer-string buf-2) "2-a"))
+ (auto-revert-test--write-file "2-b" file-2b)
+ (auto-revert-test--wait-for-buffer-text
+ buf-2 "2-b" (auto-revert--timeout))
+ (should (buffer-local-value
+ 'auto-revert-notify-watch-descriptor buf-2)))
+
+ ;; Clean up.
+ (unless was-in-global-auto-revert-mode
+ (global-auto-revert-mode 0)) ; Turn it off.
+ (dolist (buf (list buf-1 buf-2 buf-3))
+ (with-current-buffer buf (setq-local kill-buffer-hook nil))
+ (ignore-errors (kill-buffer buf)))
+ (ignore-errors (delete-file file-2b)))))))))
(auto-revert--deftest-remote auto-revert-test05-global-notify
"Test `global-auto-revert-mode' without polling for remote buffers.")
@@ -558,31 +580,30 @@ This expects `auto-revert--messages' to be bound by
(skip-unless (or file-notify--library
(file-remote-p temporary-file-directory)))
(with-auto-revert-test
- (let* ((auto-revert-use-notify t)
- (file-1 (make-temp-file "auto-revert-test"))
- (file-2 (concat file-1 "-2"))
- require-final-newline buf)
- (unwind-protect
- (progn
- (setq buf (find-file-noselect file-1))
- (with-current-buffer buf
- (insert "A")
- (save-buffer)
+ (ert-with-temp-file file-1
+ (let* ((auto-revert-use-notify t)
+ (file-2 (concat file-1 "-2"))
+ require-final-newline buf)
+ (unwind-protect
+ (progn
+ (setq buf (find-file-noselect file-1))
+ (with-current-buffer buf
+ (insert "A")
+ (save-buffer)
- (auto-revert-mode 1)
+ (auto-revert-mode 1)
- (insert "B")
- (write-file file-2)
+ (insert "B")
+ (write-file file-2)
- (auto-revert-test--write-file "C" file-2)
- (auto-revert-test--wait-for-buffer-text
- buf "C" (auto-revert--timeout))
- (should (equal (buffer-string) "C"))))
+ (auto-revert-test--write-file "C" file-2)
+ (auto-revert-test--wait-for-buffer-text
+ buf "C" (auto-revert--timeout))
+ (should (equal (buffer-string) "C"))))
- ;; Clean up.
- (ignore-errors (kill-buffer buf))
- (ignore-errors (delete-file file-1))
- (ignore-errors (delete-file file-2))))))
+ ;; Clean up.
+ (ignore-errors (kill-buffer buf))
+ (ignore-errors (delete-file file-2)))))))
(auto-revert--deftest-remote auto-revert-test06-write-file
"Test `write-file' in `auto-revert-mode' for remote buffers.")
@@ -591,82 +612,81 @@ This expects `auto-revert--messages' to be bound by
(ert-deftest auto-revert-test07-auto-revert-several-buffers ()
"Check autorevert for several buffers visiting the same file."
;; (with-auto-revert-test
- (let ((auto-revert-use-notify t)
- (tmpfile (make-temp-file "auto-revert-test"))
- (times '(120 60 30 15))
- (num-buffers 10)
- require-final-newline buffers)
-
- (unwind-protect
- ;; Check indirect buffers.
- (ert-with-message-capture auto-revert--messages
- (auto-revert-tests--write-file "any text" tmpfile (pop times))
- (push (find-file-noselect tmpfile) buffers)
- (with-current-buffer (car buffers)
- (should (string-equal (buffer-string) "any text"))
- ;; `buffer-stale--default-function' checks for
- ;; `verify-visited-file-modtime'. We must ensure that
- ;; it returns nil.
- (auto-revert-mode 1)
- (should auto-revert-mode))
-
- (dotimes (i num-buffers)
- (push (make-indirect-buffer
- (car buffers)
- (format "%s-%d" (buffer-file-name (car buffers)) i)
- 'clone)
- buffers))
- (setq buffers (nreverse buffers))
- (dolist (buf buffers)
- (with-current-buffer buf
- (should (string-equal (buffer-string) "any text"))
- (should auto-revert-mode)))
-
- (auto-revert-tests--write-file "another text" tmpfile (pop times))
- ;; Check, that the buffer has been reverted.
- (auto-revert--wait-for-revert (car buffers))
- (dolist (buf buffers)
- (with-current-buffer buf
- (should (string-equal (buffer-string) "another text")))))
-
- ;; Exit.
- (ignore-errors
- (dolist (buf buffers)
- (with-current-buffer buf (set-buffer-modified-p nil))
- (kill-buffer buf)))
- (setq buffers nil)
- (ignore-errors (delete-file tmpfile)))
-
- ;; Check direct buffers.
- (unwind-protect
- (ert-with-message-capture auto-revert--messages
- (auto-revert-tests--write-file "any text" tmpfile (pop times))
-
- (dotimes (i num-buffers)
- (push (generate-new-buffer
- (format "%s-%d" (file-name-nondirectory tmpfile) i))
- buffers))
- (setq buffers (nreverse buffers))
- (dolist (buf buffers)
- (with-current-buffer buf
- (insert-file-contents tmpfile 'visit)
- (should (string-equal (buffer-string) "any text"))
- (auto-revert-mode 1)
- (should auto-revert-mode)))
-
- (auto-revert-tests--write-file "another text" tmpfile (pop times))
- ;; Check, that the buffers have been reverted.
- (dolist (buf buffers)
- (auto-revert--wait-for-revert buf)
- (with-current-buffer buf
- (should (string-equal (buffer-string) "another text")))))
-
- ;; Exit.
- (ignore-errors
- (dolist (buf buffers)
- (with-current-buffer buf (set-buffer-modified-p nil))
- (kill-buffer buf)))
- (ignore-errors (delete-file tmpfile)))));)
+ (ert-with-temp-file tmpfile
+ (let ((auto-revert-use-notify t)
+ (times '(120 60 30 15))
+ (num-buffers 10)
+ require-final-newline buffers)
+
+ (unwind-protect
+ ;; Check indirect buffers.
+ (ert-with-message-capture auto-revert--messages
+ (auto-revert-tests--write-file "any text" tmpfile (pop times))
+ (push (find-file-noselect tmpfile) buffers)
+ (with-current-buffer (car buffers)
+ (should (string-equal (buffer-string) "any text"))
+ ;; `buffer-stale--default-function' checks for
+ ;; `verify-visited-file-modtime'. We must ensure that
+ ;; it returns nil.
+ (auto-revert-mode 1)
+ (should auto-revert-mode))
+
+ (dotimes (i num-buffers)
+ (push (make-indirect-buffer
+ (car buffers)
+ (format "%s-%d" (buffer-file-name (car buffers)) i)
+ 'clone)
+ buffers))
+ (setq buffers (nreverse buffers))
+ (dolist (buf buffers)
+ (with-current-buffer buf
+ (should (string-equal (buffer-string) "any text"))
+ (should auto-revert-mode)))
+
+ (auto-revert-tests--write-file "another text" tmpfile (pop times))
+ ;; Check, that the buffer has been reverted.
+ (auto-revert--wait-for-revert (car buffers))
+ (dolist (buf buffers)
+ (with-current-buffer buf
+ (should (string-equal (buffer-string) "another text")))))
+
+ ;; Exit.
+ (ignore-errors
+ (dolist (buf buffers)
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf)))
+ (setq buffers nil)
+ (ignore-errors (delete-file tmpfile)))
+
+ ;; Check direct buffers.
+ (unwind-protect
+ (ert-with-message-capture auto-revert--messages
+ (auto-revert-tests--write-file "any text" tmpfile (pop times))
+
+ (dotimes (i num-buffers)
+ (push (generate-new-buffer
+ (format "%s-%d" (file-name-nondirectory tmpfile) i))
+ buffers))
+ (setq buffers (nreverse buffers))
+ (dolist (buf buffers)
+ (with-current-buffer buf
+ (insert-file-contents tmpfile 'visit)
+ (should (string-equal (buffer-string) "any text"))
+ (auto-revert-mode 1)
+ (should auto-revert-mode)))
+
+ (auto-revert-tests--write-file "another text" tmpfile (pop times))
+ ;; Check, that the buffers have been reverted.
+ (dolist (buf buffers)
+ (auto-revert--wait-for-revert buf)
+ (with-current-buffer buf
+ (should (string-equal (buffer-string) "another text")))))
+
+ ;; Exit.
+ (ignore-errors
+ (dolist (buf buffers)
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf)))))));)
(auto-revert--deftest-remote auto-revert-test07-auto-revert-several-buffers
"Check autorevert for several buffers visiting the same remote file.")
@@ -685,4 +705,4 @@ This expects `auto-revert--messages' to be bound by
(ert-run-tests-batch "^auto-revert-")))
(provide 'auto-revert-tests)
-;;; auto-revert-tests.el ends here
+;;; autorevert-tests.el ends here
diff --git a/test/lisp/bookmark-tests.el b/test/lisp/bookmark-tests.el
index 9c33a27288a..dc2dec68ee3 100644
--- a/test/lisp/bookmark-tests.el
+++ b/test/lisp/bookmark-tests.el
@@ -371,16 +371,14 @@ Same as `with-bookmark-test' but also sets a temporary
`bookmark-default-file', evaluates BODY, and then runs the test
that saves and then loads the bookmark file."
`(with-bookmark-test
- (let ((file (make-temp-file "bookmark-tests-")))
- (unwind-protect
- (let ((bookmark-default-file file)
- (old-alist bookmark-alist))
- ,@body
- (bookmark-save nil file t)
- (setq bookmark-alist nil)
- (bookmark-load file nil t)
- (should (equal bookmark-alist old-alist)))
- (delete-file file)))))
+ (ert-with-temp-file file
+ (let ((bookmark-default-file file)
+ (old-alist bookmark-alist))
+ ,@body
+ (bookmark-save nil file t)
+ (setq bookmark-alist nil)
+ (bookmark-load file nil t)
+ (should (equal bookmark-alist old-alist))))))
(defvar bookmark-tests-non-ascii-data
(concat "Здра́вствуйте!" "中文,普通话,汉语" "åäöøñ"
diff --git a/test/lisp/buff-menu-tests.el b/test/lisp/buff-menu-tests.el
index 18c988656d3..b223a643083 100644
--- a/test/lisp/buff-menu-tests.el
+++ b/test/lisp/buff-menu-tests.el
@@ -24,19 +24,20 @@
;;; Code:
(require 'ert)
+(eval-when-compile (require 'ert-x))
(ert-deftest buff-menu-24962 ()
"Test for https://debbugs.gnu.org/24962 ."
- (let* ((file (make-temp-file "foo"))
- (buf (find-file file)))
- (unwind-protect
- (progn
- (rename-buffer " foo")
- (list-buffers)
- (with-current-buffer "*Buffer List*"
- (should (string= " foo" (buffer-name (Buffer-menu-buffer))))))
- (and (buffer-live-p buf) (kill-buffer buf))
- (and (file-exists-p file) (delete-file file)))))
+ (ert-with-temp-file file
+ :suffix "foo"
+ (let ((buf (find-file file)))
+ (unwind-protect
+ (progn
+ (rename-buffer " foo")
+ (list-buffers)
+ (with-current-buffer "*Buffer List*"
+ (should (string= " foo" (buffer-name (Buffer-menu-buffer))))))
+ (and (buffer-live-p buf) (kill-buffer buf))))))
(provide 'buff-menu-tests)
diff --git a/test/lisp/button-tests.el b/test/lisp/button-tests.el
index e0944afa344..2f5ad795df2 100644
--- a/test/lisp/button-tests.el
+++ b/test/lisp/button-tests.el
@@ -59,6 +59,7 @@
"Test `button--help-echo' with forms."
(with-temp-buffer
;; Test text property buttons with dynamic scoping.
+ (setq lexical-binding nil)
(let* ((help (make-symbol "help"))
(form `(funcall (let ((,help "lexical form"))
(lambda () ,help))))
diff --git a/test/lisp/calc/calc-tests.el b/test/lisp/calc/calc-tests.el
index 13dd228d3b3..3eb6b34c132 100644
--- a/test/lisp/calc/calc-tests.el
+++ b/test/lisp/calc/calc-tests.el
@@ -53,7 +53,7 @@ A and B should be calc expressions."
(defun calc-tests-simple (fun string &rest args)
"Push STRING on the calc stack, then call FUN and return the new top.
-The result is a calc (i.e., lisp) expression, not its string representation.
+The result is a calc (i.e., Lisp) expression, not its string representation.
Also pop the entire stack afterwards.
An existing calc stack is reused, otherwise a new one is created."
(calc-eval string 'push)
@@ -448,7 +448,7 @@ An existing calc stack is reused, otherwise a new one is created."
;; Generalisation for any n, integral k≥0: use falling product
(/ (apply '* (number-sequence n (- n (1- k)) -1))
(calc-tests--fac k)))
- (t (error "case not covered"))))
+ (t (error "Case not covered"))))
(defun calc-tests--calc-to-number (x)
"Convert a Calc object to a Lisp number."
@@ -810,6 +810,12 @@ An existing calc stack is reused, otherwise a new one is created."
(should (equal (calcFunc-test6 3) (* (* 3 2) (- 3 1))))
(should (equal (calcFunc-test7 3) (* 3 2))))
+(ert-deftest calc-nth-root ()
+ ;; bug#51209
+ (let* ((calc-display-working-message nil)
+ (x (calc-tests--calc-to-number (math-pow 8 '(frac 1 6)))))
+ (should (< (abs (- x (sqrt 2.0))) 1.0e-10))))
+
(provide 'calc-tests)
;;; calc-tests.el ends here
diff --git a/test/lisp/calculator-tests.el b/test/lisp/calculator-tests.el
index 9551b1a4c61..f24ca97310c 100644
--- a/test/lisp/calculator-tests.el
+++ b/test/lisp/calculator-tests.el
@@ -48,4 +48,4 @@
(should (equal (calculator-string-to-number str) expected)))))))
(provide 'calculator-tests)
-;; calculator-tests.el ends here
+;;; calculator-tests.el ends here
diff --git a/test/lisp/calendar/cal-french-tests.el b/test/lisp/calendar/cal-french-tests.el
index ab62c1e6fc1..1de5dea0882 100644
--- a/test/lisp/calendar/cal-french-tests.el
+++ b/test/lisp/calendar/cal-french-tests.el
@@ -111,3 +111,4 @@
(should (equal (calendar-french-date-string (list m d y)) str))))
(provide 'cal-french-tests)
+;;; cal-french-tests.el ends here
diff --git a/test/lisp/calendar/icalendar-tests.el b/test/lisp/calendar/icalendar-tests.el
index 6973f7e5c95..1551922028c 100644
--- a/test/lisp/calendar/icalendar-tests.el
+++ b/test/lisp/calendar/icalendar-tests.el
@@ -698,17 +698,18 @@ and ISO style input data must use english month names."
"Actually perform export test.
Argument INPUT input diary string.
Argument EXPECTED-OUTPUT expected iCalendar result string."
- (let ((temp-file (make-temp-file "icalendar-tests-ics")))
+ (ert-with-temp-file temp-file
+ :suffix "icalendar-tests-ics"
(unwind-protect
- (progn
- (with-temp-buffer
- (insert input)
- (icalendar-export-region (point-min) (point-max) temp-file))
- (save-excursion
- (find-file temp-file)
- (goto-char (point-min))
- (cond (expected-output
- (should (re-search-forward "^\\s-*BEGIN:VCALENDAR
+ (progn
+ (with-temp-buffer
+ (insert input)
+ (icalendar-export-region (point-min) (point-max) temp-file))
+ (save-excursion
+ (find-file temp-file)
+ (goto-char (point-min))
+ (cond (expected-output
+ (should (re-search-forward "^\\s-*BEGIN:VCALENDAR
PRODID:-//Emacs//NONSGML icalendar.el//EN
VERSION:2.0
BEGIN:VEVENT
@@ -717,23 +718,22 @@ UID:emacs[0-9]+
END:VEVENT
END:VCALENDAR
\\s-*$"
- nil t))
- (should (string-match
- (concat "^\\s-*"
- (regexp-quote (buffer-substring-no-properties
- (match-beginning 1) (match-end 1)))
- "\\s-*$")
- expected-output)))
- (t
- (should (re-search-forward "^\\s-*BEGIN:VCALENDAR
+ nil t))
+ (should (string-match
+ (concat "^\\s-*"
+ (regexp-quote (buffer-substring-no-properties
+ (match-beginning 1) (match-end 1)))
+ "\\s-*$")
+ expected-output)))
+ (t
+ (should (re-search-forward "^\\s-*BEGIN:VCALENDAR
PRODID:-//Emacs//NONSGML icalendar.el//EN
VERSION:2.0
END:VCALENDAR
\\s-*$"
- nil t))))))
+ nil t))))))
;; cleanup!!
- (kill-buffer (find-buffer-visiting temp-file))
- (delete-file temp-file))))
+ (kill-buffer (find-buffer-visiting temp-file)))))
(ert-deftest icalendar-export-ordinary-no-time ()
"Perform export test."
@@ -1031,7 +1031,8 @@ During import test the timezone is set to Central European Time."
(defun icalendar-tests--do-test-import (expected-output)
"Actually perform import test.
Argument EXPECTED-OUTPUT file containing expected diary string."
- (let ((temp-file (make-temp-file "icalendar-test-diary")))
+ (ert-with-temp-file temp-file
+ :suffix "icalendar-test-diary"
;; Test the Catch-the-mysterious-coding-header logic below.
;; Ruby-mode adds an after-save-hook which inserts the header!
;; (save-excursion
@@ -1061,8 +1062,7 @@ Argument EXPECTED-OUTPUT file containing expected diary string."
(let ((result (buffer-substring-no-properties (point-min) (point-max))))
(should (string= expected-output result)))
- (kill-buffer (find-buffer-visiting temp-file))
- (delete-file temp-file))))
+ (kill-buffer (find-buffer-visiting temp-file)))))
(ert-deftest icalendar-import-non-recurring ()
"Perform standard import tests."
@@ -1240,35 +1240,33 @@ Argument INPUT icalendar event string."
(defun icalendar-tests--do-test-cycle ()
"Actually perform import/export cycle test."
- (let ((temp-diary (make-temp-file "icalendar-test-diary"))
- (temp-ics (make-temp-file "icalendar-test-ics"))
- (org-input (buffer-substring-no-properties (point-min) (point-max))))
-
- (unwind-protect
- (progn
- ;; step 1: import
- (icalendar-import-buffer temp-diary t t)
-
- ;; step 2: export what was just imported
- (save-excursion
- (find-file temp-diary)
- (icalendar-export-region (point-min) (point-max) temp-ics))
-
- ;; compare the output of step 2 with the input of step 1
- (save-excursion
- (find-file temp-ics)
- (goto-char (point-min))
- ;;(when (re-search-forward "\nUID:.*\n" nil t)
- ;;(replace-match "\n"))
- (let ((cycled (buffer-substring-no-properties (point-min) (point-max))))
- (should (string= org-input cycled)))))
- ;; clean up
- (kill-buffer (find-buffer-visiting temp-diary))
- (with-current-buffer (find-buffer-visiting temp-ics)
- (set-buffer-modified-p nil)
- (kill-buffer (current-buffer)))
- (delete-file temp-diary)
- (delete-file temp-ics))))
+ (ert-with-temp-file temp-diary
+ (ert-with-temp-file temp-ics
+ (let ((org-input (buffer-substring-no-properties (point-min) (point-max))))
+
+ (unwind-protect
+ (progn
+ ;; step 1: import
+ (icalendar-import-buffer temp-diary t t)
+
+ ;; step 2: export what was just imported
+ (save-excursion
+ (find-file temp-diary)
+ (icalendar-export-region (point-min) (point-max) temp-ics))
+
+ ;; compare the output of step 2 with the input of step 1
+ (save-excursion
+ (find-file temp-ics)
+ (goto-char (point-min))
+ ;;(when (re-search-forward "\nUID:.*\n" nil t)
+ ;;(replace-match "\n"))
+ (let ((cycled (buffer-substring-no-properties (point-min) (point-max))))
+ (should (string= org-input cycled)))))
+ ;; clean up
+ (kill-buffer (find-buffer-visiting temp-diary))
+ (with-current-buffer (find-buffer-visiting temp-ics)
+ (set-buffer-modified-p nil)
+ (kill-buffer (current-buffer))))))))
(ert-deftest icalendar-cycle ()
"Perform cycling tests.
@@ -1442,6 +1440,13 @@ RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=09;BYMONTHDAY=21
SUMMARY:ff birthday (%d years old)")
+ (icalendar-tests--test-export
+ nil
+ nil
+ "%%(diary-offset '(diary-float t 3 4) 1) asdf"
+ nil)
+
+
;; FIXME!
;; export 2004-10-28 monthly, weekly entries
@@ -1628,28 +1633,32 @@ SUMMARY:NNN Wwwwwwww Wwwww - Aaaaaa Pppppppp rrrrrr ddd oo Nnnnnnnn 30
(let ((time (icalendar--decode-isodatetime string day zone)))
(format-time-string "%FT%T%z" (encode-time time) 0)))
-(defun icalendar-tests--decode-isodatetime (_ical-string)
- "Test icalendar--decode-isodatetime."
- (should (equal (icalendar-test--format "20040917T050910-0200")
- "2004-09-17T03:09:10+0000"))
- (should (equal (icalendar-test--format "20040917T050910")
+(ert-deftest icalendar-tests--decode-isodatetime ()
+ "Test `icalendar--decode-isodatetime'."
+ (should (equal (icalendar-test--format "20040917T050910-02:00")
"2004-09-17T03:09:10+0000"))
+ (let ((orig (icalendar-test--format "20040917T050910")))
+ (unwind-protect
+ (progn
+ (set-time-zone-rule "UTC-02:00")
+ (should (equal (icalendar-test--format "20040917T050910")
+ "2004-09-17T03:09:10+0000"))
+ (should (equal (icalendar-test--format "20040917T0509")
+ "2004-09-17T03:09:00+0000"))
+ (should (equal (icalendar-test--format "20040917")
+ "2004-09-16T22:00:00+0000"))
+ (should (equal (icalendar-test--format "20040917T050910" 1)
+ "2004-09-18T03:09:10+0000"))
+ (should (equal (icalendar-test--format "20040917T050910" 30)
+ "2004-10-17T03:09:10+0000")))
+ (set-time-zone-rule 'wall) ;; (set-time-zone-rule nil) is broken
+ (should (equal orig (icalendar-test--format "20040917T050910")))))
(should (equal (icalendar-test--format "20040917T050910Z")
"2004-09-17T05:09:10+0000"))
- (should (equal (icalendar-test--format "20040917T0509")
- "2004-09-17T03:09:00+0000"))
- (should (equal (icalendar-test--format "20040917")
- "2004-09-16T22:00:00+0000"))
- (should (equal (icalendar-test--format "20040917T050910" 1)
- "2004-09-18T03:09:10+0000"))
- (should (equal (icalendar-test--format "20040917T050910" 30)
- "2004-10-17T03:09:10+0000"))
- (should (equal (icalendar-test--format "20040917T050910" -1)
- "2004-09-16T03:09:10+0000"))
-
+ (should (equal (icalendar-test--format "20040917T050910" -1 0)
+ "2004-09-16T05:09:10+0000"))
(should (equal (icalendar-test--format "20040917T050910" nil -3600)
"2004-09-17T06:09:10+0000")))
-
(provide 'icalendar-tests)
;;; icalendar-tests.el ends here
diff --git a/test/lisp/calendar/solar-tests.el b/test/lisp/calendar/solar-tests.el
index 337deb8ce9a..921be1d2d48 100644
--- a/test/lisp/calendar/solar-tests.el
+++ b/test/lisp/calendar/solar-tests.el
@@ -17,6 +17,8 @@
;; 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 'solar)
@@ -42,3 +44,5 @@
(should (< (abs (- sunset 17.72)) epsilon)))))
(provide 'solar-tests)
+
+;;; solar-tests.el ends here
diff --git a/test/lisp/calendar/time-date-tests.el b/test/lisp/calendar/time-date-tests.el
index 4568947c0b3..ed842e34fd6 100644
--- a/test/lisp/calendar/time-date-tests.el
+++ b/test/lisp/calendar/time-date-tests.el
@@ -41,6 +41,13 @@
(encode-time-value 1 2 3 4 3))
'(1 2 3 4))))
+(ert-deftest test-date-to-time ()
+ (should (equal (format-time-string "%F %T" (date-to-time "2021-12-04"))
+ "2021-12-04 00:00:00")))
+
+(ert-deftest test-days-between ()
+ (should (equal (days-between "2021-10-22" "2020-09-29") 388)))
+
(ert-deftest test-leap-year ()
(should-not (date-leap-year-p 1999))
(should-not (date-leap-year-p 1900))
@@ -48,13 +55,13 @@
(should (date-leap-year-p 2004)))
(ert-deftest test-days-to-time ()
- (should (equal (days-to-time 0) '(0 0)))
- (should (equal (days-to-time 1) '(1 20864)))
- (should (equal (days-to-time 999) '(1317 2688)))
- (should (equal (days-to-time 0.0) '(0 0 0 0)))
- (should (equal (days-to-time 0.5) '(0 43200 0 0)))
- (should (equal (days-to-time 1.0) '(1 20864 0 0)))
- (should (equal (days-to-time 999.0) '(1317 2688 0 0))))
+ (should (time-equal-p (days-to-time 0) '(0 0)))
+ (should (time-equal-p (days-to-time 1) '(1 20864)))
+ (should (time-equal-p (days-to-time 999) '(1317 2688)))
+ (should (time-equal-p (days-to-time 0.0) '(0 0 0 0)))
+ (should (time-equal-p (days-to-time 0.5) '(0 43200 0 0)))
+ (should (time-equal-p (days-to-time 1.0) '(1 20864 0 0)))
+ (should (time-equal-p (days-to-time 999.0) '(1317 2688 0 0))))
(ert-deftest test-seconds-to-string ()
(should (equal (seconds-to-string 0) "0s"))
@@ -163,7 +170,8 @@
(ert-deftest test-time-since ()
(should (time-equal-p 0 (time-since nil)))
- (should (= (cadr (time-since (time-subtract (current-time) 1))) 1)))
+ (should (time-equal-p 1 (time-convert (time-since (time-subtract nil 1))
+ 'integer))))
(ert-deftest test-time-decoded-period ()
(should (equal (decoded-time-period '(nil nil 1 nil nil nil nil nil nil))
diff --git a/test/lisp/calendar/todo-mode-tests.el b/test/lisp/calendar/todo-mode-tests.el
index 6fa2b9d7c35..79978a2041f 100644
--- a/test/lisp/calendar/todo-mode-tests.el
+++ b/test/lisp/calendar/todo-mode-tests.el
@@ -35,27 +35,26 @@
"Todo Archive mode test file.")
(defmacro with-todo-test (&rest body)
- "Set up an isolated todo-mode test environment."
+ "Set up an isolated `todo-mode' test environment."
(declare (debug (body)))
- `(let* ((todo-test-home (make-temp-file "todo-test-home-" t))
- ;; Since we change HOME, clear this to avoid a conflict
- ;; e.g. if Emacs runs within the user's home directory.
- (abbreviated-home-dir nil)
- (process-environment (cons (format "HOME=%s" todo-test-home)
- process-environment))
- (todo-directory (ert-resource-directory))
- (todo-default-todo-file (todo-short-file-name
- (car (funcall todo-files-function)))))
- (unwind-protect
- (progn ,@body)
- ;; Restore pre-test-run state of test files.
- (dolist (f (directory-files todo-directory))
- (let ((buf (get-file-buffer f)))
- (when buf
- (with-current-buffer buf
- (restore-buffer-modified-p nil)
- (kill-buffer)))))
- (delete-directory todo-test-home t))))
+ `(ert-with-temp-directory todo-test-home
+ (let* (;; Since we change HOME, clear this to avoid a conflict
+ ;; e.g. if Emacs runs within the user's home directory.
+ (abbreviated-home-dir nil)
+ (process-environment (cons (format "HOME=%s" todo-test-home)
+ process-environment))
+ (todo-directory (ert-resource-directory))
+ (todo-default-todo-file (todo-short-file-name
+ (car (funcall todo-files-function)))))
+ (unwind-protect
+ (progn ,@body)
+ ;; Restore pre-test-run state of test files.
+ (dolist (f (directory-files todo-directory))
+ (let ((buf (get-file-buffer f)))
+ (when buf
+ (with-current-buffer buf
+ (restore-buffer-modified-p nil)
+ (kill-buffer)))))))))
(defun todo-test--show (num &optional archive)
"Display category NUM of test todo file.
@@ -567,7 +566,7 @@ The remaining arguments (except _ARG, which is ignored) specify
item insertion parameters. This provides a noninteractive API
for todo-insert-item for use in automatic testing."
(cl-letf (((symbol-function 'read-from-minibuffer)
- (lambda (_prompt) item))
+ (lambda (_prompt &rest _) item))
((symbol-function 'read-number) ; For todo-set-item-priority
(lambda (_prompt &optional _default) (or priority 1))))
(todo-insert-item--basic nil diary-type date-type time where)))
diff --git a/test/lisp/cedet/semantic-utest-c.el b/test/lisp/cedet/semantic-utest-c.el
index d08c79cad3e..c5eb5b0ec06 100644
--- a/test/lisp/cedet/semantic-utest-c.el
+++ b/test/lisp/cedet/semantic-utest-c.el
@@ -60,7 +60,7 @@
(semantic-fetch-tags))))
(when (or (not tags-expected) (not tags-actual))
(message "Tried to find test files in: %s" semantic-utest-c-test-directory)
- (error "Failed: Discovered no tags in test files or test file not found."))
+ (error "Failed: Discovered no tags in test files or test file not found"))
;; Now that we have the tags, compare them for SPP accuracy.
(dolist (tag tags-actual)
diff --git a/test/lisp/cedet/semantic-utest-ia.el b/test/lisp/cedet/semantic-utest-ia.el
index 122c431d472..6ea4ca1a16a 100644
--- a/test/lisp/cedet/semantic-utest-ia.el
+++ b/test/lisp/cedet/semantic-utest-ia.el
@@ -489,4 +489,4 @@ tag that contains point, and return that."
(provide 'semantic-ia-utest)
-;;; semantic-ia-utest.el ends here
+;;; semantic-utest-ia.el ends here
diff --git a/test/lisp/cedet/semantic-utest.el b/test/lisp/cedet/semantic-utest.el
index 172ab62f895..3e4cfb0f0cb 100644
--- a/test/lisp/cedet/semantic-utest.el
+++ b/test/lisp/cedet/semantic-utest.el
@@ -29,6 +29,8 @@
(require 'cedet)
(require 'semantic)
+;;; Code:
+
(defvar cedet-utest-directory
(let* ((C (file-name-directory (locate-library "cedet")))
(D (expand-file-name "../../test/manual/cedet/" C)))
@@ -103,7 +105,7 @@ int calc_sv(int);
(defvar semantic-utest-C-filename-h
(concat (file-name-sans-extension semantic-utest-C-filename)
".h")
- "Header file filename for C")
+ "Header file filename for C.")
(defvar semantic-utest-C-name-contents
@@ -424,8 +426,7 @@ class aClass {
nil
(overlay 135 262 "phptest.php"))
)
- "Expected results from the PHP Unit test"
- )
+ "Expected results from the PHP Unit test.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/test/lisp/cedet/semantic/bovine/gcc-tests.el b/test/lisp/cedet/semantic/bovine/gcc-tests.el
index 93677d6c871..ba84ce4d81b 100644
--- a/test/lisp/cedet/semantic/bovine/gcc-tests.el
+++ b/test/lisp/cedet/semantic/bovine/gcc-tests.el
@@ -124,6 +124,12 @@ gcc version 2.95.2 19991024 (release)"
"Test the output parser against the machine currently running Emacs."
(skip-unless (executable-find "gcc"))
(let ((semantic-gcc-test-strings (list (semantic-gcc-query "gcc" "-v"))))
- (semantic-gcc-test-output-parser)))
+ ;; Some macOS machines run llvm when you type gcc. (!)
+ ;; We can't even check if it's a symlink; it's a binary placed in
+ ;; "/usr/bin/gcc". So check the output and just skip this test if
+ ;; it looks like that's the case.
+ (unless (string-match "Apple LLVM\\|Xcode.app"
+ (car semantic-gcc-test-strings))
+ (semantic-gcc-test-output-parser))))
;;; gcc-tests.el ends here
diff --git a/test/lisp/cedet/semantic/fw-tests.el b/test/lisp/cedet/semantic/fw-tests.el
index 7b1cd21bd1b..6a5f3c85fc6 100644
--- a/test/lisp/cedet/semantic/fw-tests.el
+++ b/test/lisp/cedet/semantic/fw-tests.el
@@ -42,4 +42,4 @@
;; retrieve cached data
(should (equal (semantic-get-cache-data 'moose) data)))))
-;;; gw-tests.el ends here
+;;; fw-tests.el ends here
diff --git a/test/lisp/cedet/srecode/fields-tests.el b/test/lisp/cedet/srecode/fields-tests.el
index 5f634a5e4ce..3c66f219bd6 100644
--- a/test/lisp/cedet/srecode/fields-tests.el
+++ b/test/lisp/cedet/srecode/fields-tests.el
@@ -57,8 +57,7 @@ It is filled with some text."
(end-of-line)
(forward-word -1)
- (setq f (srecode-field "Test"
- :name "TEST"
+ (setq f (srecode-field :name "TEST"
:start 6
:end 8))
@@ -99,19 +98,17 @@ It is filled with some text."
(reg nil)
(fields
(list
- (srecode-field "Test1" :name "TEST-1" :start 5 :end 10)
- (srecode-field "Test2" :name "TEST-2" :start 15 :end 20)
- (srecode-field "Test3" :name "TEST-3" :start 25 :end 30)
+ (srecode-field :name "TEST-1" :start 5 :end 10)
+ (srecode-field :name "TEST-2" :start 15 :end 20)
+ (srecode-field :name "TEST-3" :start 25 :end 30)
- (srecode-field "Test4" :name "TEST-4" :start 35 :end 35))
- ))
+ (srecode-field :name "TEST-4" :start 35 :end 35))))
(when (not (= (length srecode-field-archive) 4))
(error "Region Test: Found %d fields. Expected 4"
(length srecode-field-archive)))
- (setq reg (srecode-template-inserted-region "REG"
- :start 4
+ (setq reg (srecode-template-inserted-region :start 4
:end 40))
(srecode-overlaid-activate reg)
@@ -183,10 +180,10 @@ It is filled with some text."
;; Test variable linkage.
(let* ((srecode-field-archive nil)
- (f1 (srecode-field "Test1" :name "TEST" :start 6 :end 8))
- (f2 (srecode-field "Test2" :name "TEST" :start 28 :end 30))
- (f3 (srecode-field "Test3" :name "NOTTEST" :start 35 :end 40))
- (reg (srecode-template-inserted-region "REG" :start 4 :end 40)))
+ (f1 (srecode-field :name "TEST" :start 6 :end 8))
+ (f2 (srecode-field :name "TEST" :start 28 :end 30))
+ (f3 (srecode-field :name "NOTTEST" :start 35 :end 40))
+ (reg (srecode-template-inserted-region :start 4 :end 40)))
(srecode-overlaid-activate reg)
(when (not (string= (srecode-overlaid-text f1)
diff --git a/test/lisp/comint-tests.el b/test/lisp/comint-tests.el
index 8a9a41f452f..0bd5c1e9d15 100644
--- a/test/lisp/comint-tests.el
+++ b/test/lisp/comint-tests.el
@@ -1,4 +1,4 @@
-;;; comint-tests.el -*- lexical-binding:t -*-
+;;; comint-tests.el --- Tests for comint.el -*- lexical-binding:t -*-
;; Copyright (C) 2010-2021 Free Software Foundation, Inc.
@@ -43,6 +43,11 @@
"PIN for user:" ; Bug#35523
"Password (again):"
"Enter password:"
+ "(user@host) Password: " ; openssh-8.6p1
+ "Current password:" ; "passwd" (to change password) in Debian.
+ "Enter encryption key: " ; ccrypt
+ "Enter decryption key: " ; ccrypt
+ "Enter encryption key: (repeat) " ; ccrypt
"Enter Auth Password:" ; OpenVPN (Bug#35724)
"Verify password: " ; zip -e zipfile.zip ... (Bug#47209)
"Mot de Passe :" ; localized (Bug#29729)
@@ -94,4 +99,4 @@ password flow if it returns a nil value."
;; no-byte-compile: t
;; End:
-;;; comint-testsuite.el ends here
+;;; comint-tests.el ends here
diff --git a/test/lisp/cus-edit-tests.el b/test/lisp/cus-edit-tests.el
index 97b3349000c..f7d52834370 100644
--- a/test/lisp/cus-edit-tests.el
+++ b/test/lisp/cus-edit-tests.el
@@ -37,7 +37,7 @@
;;;; showing/hiding obsolete options
-(defgroup cus-edit-tests nil "test"
+(defgroup cus-edit-tests nil "Test."
:group 'test-group)
(defcustom cus-edit-tests--obsolete-option-tag nil
diff --git a/test/lisp/custom-tests.el b/test/lisp/custom-tests.el
index e93c96e1d93..769db6ceab4 100644
--- a/test/lisp/custom-tests.el
+++ b/test/lisp/custom-tests.el
@@ -25,20 +25,9 @@
(require 'wid-edit)
(require 'cus-edit)
-(defmacro custom-tests--with-temp-dir (&rest body)
- "Eval BODY with `temporary-file-directory' bound to a fresh directory.
-Ensure the directory is recursively deleted after the fact."
- (declare (debug t) (indent 0))
- (let ((dir (make-symbol "dir")))
- `(let ((,dir (file-name-as-directory (make-temp-file "custom-tests-" t))))
- (unwind-protect
- (let ((temporary-file-directory ,dir))
- ,@body)
- (delete-directory ,dir t)))))
-
(ert-deftest custom-theme--load-path ()
"Test `custom-theme--load-path' behavior."
- (custom-tests--with-temp-dir
+ (ert-with-temp-directory temporary-file-directory
;; Path is empty.
(let ((custom-theme-load-path ()))
(should (null (custom-theme--load-path))))
@@ -50,28 +39,28 @@ Ensure the directory is recursively deleted after the fact."
(should (null (custom-theme--load-path))))
;; Path comprises existing file.
- (let* ((file (make-temp-file "file"))
- (custom-theme-load-path (list file)))
- (should (file-exists-p file))
- (should (not (file-directory-p file)))
- (should (null (custom-theme--load-path))))
+ (ert-with-temp-file file
+ (let* ((custom-theme-load-path (list file)))
+ (should (file-exists-p file))
+ (should (not (file-directory-p file)))
+ (should (null (custom-theme--load-path)))))
;; Path comprises existing directory.
- (let* ((dir (make-temp-file "dir" t))
- (custom-theme-load-path (list dir)))
- (should (file-directory-p dir))
- (should (equal (custom-theme--load-path) custom-theme-load-path)))
+ (ert-with-temp-directory dir
+ (let* ((custom-theme-load-path (list dir)))
+ (should (file-directory-p dir))
+ (should (equal (custom-theme--load-path) custom-theme-load-path))))
;; Expand `custom-theme-directory' path element.
(let ((custom-theme-load-path '(custom-theme-directory)))
(let ((custom-theme-directory (make-temp-name temporary-file-directory)))
(should (not (file-exists-p custom-theme-directory)))
(should (null (custom-theme--load-path))))
- (let ((custom-theme-directory (make-temp-file "file")))
+ (ert-with-temp-file custom-theme-directory
(should (file-exists-p custom-theme-directory))
(should (not (file-directory-p custom-theme-directory)))
(should (null (custom-theme--load-path))))
- (let ((custom-theme-directory (make-temp-file "dir" t)))
+ (ert-with-temp-directory custom-theme-directory
(should (file-directory-p custom-theme-directory))
(should (equal (custom-theme--load-path)
(list custom-theme-directory)))))
@@ -96,7 +85,8 @@ Ensure the directory is recursively deleted after the fact."
(ert-deftest custom-tests-require-theme ()
"Test `require-theme'."
- (custom-tests--with-temp-dir
+ (require 'warnings)
+ (ert-with-temp-directory temporary-file-directory
(let* ((default-directory temporary-file-directory)
(custom-theme-load-path (list default-directory))
(load-path ()))
diff --git a/test/lisp/dabbrev-tests.el b/test/lisp/dabbrev-tests.el
index 0b20dcf9213..d3fe78b6185 100644
--- a/test/lisp/dabbrev-tests.el
+++ b/test/lisp/dabbrev-tests.el
@@ -29,16 +29,15 @@
(ert-deftest dabbrev-expand-test ()
"Test for bug#1948.
-When DABBREV-ELIMINATE-NEWLINES is non-nil (the default),
-repeated calls to DABBREV-EXPAND can result in the source of
+When `dabbrev-eliminate-newlines' is non-nil (the default),
+repeated calls to `dabbrev-expand' can result in the source of
first expansion being replaced rather than the destination."
(with-temp-buffer
(insert "ab x\na\nab y")
(goto-char 8)
(save-window-excursion
(set-window-buffer nil (current-buffer))
- ;; M-/ SPC M-/ M-/
- (execute-kbd-macro "\257 \257\257"))
+ (execute-kbd-macro (kbd "M-/ SPC M-/ M-/")))
(should (string= (buffer-string) "ab x\nab y\nab y"))))
(ert-deftest dabbrev-completion-test ()
@@ -52,8 +51,7 @@ buffers unless a prefix argument is used."
(goto-char 6)
(save-window-excursion
(set-window-buffer nil (current-buffer))
- ;; C-M-/
- (execute-kbd-macro [201326639]))
+ (execute-kbd-macro (kbd "C-M-/")))
(should (string= (buffer-string) "abc\nabc")))))
(ert-deftest dabbrev-completion-test-with-argument ()
@@ -67,6 +65,7 @@ multiple expansions."
(goto-char 6)
(save-window-excursion
(set-window-buffer nil (current-buffer))
- ;; C-u C-u C-M-/
- (execute-kbd-macro [21 21 201326639]))
+ (execute-kbd-macro (kbd "C-u C-u C-M-/")))
(should (string= (buffer-string) "abc\na")))))
+
+;;; dabbrev-tests.el ends here
diff --git a/test/lisp/descr-text-tests.el b/test/lisp/descr-text-tests.el
index 2052dc0e38c..715fafa44c3 100644
--- a/test/lisp/descr-text-tests.el
+++ b/test/lisp/descr-text-tests.el
@@ -91,4 +91,4 @@
(provide 'descr-text-test)
-;;; descr-text-test.el ends here
+;;; descr-text-tests.el ends here
diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el
index 7f1743f88d7..69fc95ba552 100644
--- a/test/lisp/dired-aux-tests.el
+++ b/test/lisp/dired-aux-tests.el
@@ -19,26 +19,25 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'dired-aux)
(eval-when-compile (require 'cl-lib))
(ert-deftest dired-test-bug27496 ()
"Test for https://debbugs.gnu.org/27496 ."
(skip-unless (executable-find shell-file-name))
- (let* ((foo (make-temp-file "foo"))
- (files (list foo)))
- (unwind-protect
- (cl-letf (((symbol-function 'read-char-from-minibuffer) 'error))
- (dired temporary-file-directory)
- (dired-goto-file foo)
- ;; `dired-do-shell-command' returns nil on success.
- (should-error (dired-do-shell-command "ls ? ./?" nil files))
- (should-error (dired-do-shell-command "ls ./? ?" nil files))
- (should-not (dired-do-shell-command "ls ? ?" nil files))
- (should-error (dired-do-shell-command "ls * ./*" nil files))
- (should-not (dired-do-shell-command "ls * *" nil files))
- (should-not (dired-do-shell-command "ls ? ./`?`" nil files)))
- (delete-file foo))))
+ (ert-with-temp-file foo
+ (let* ((files (list foo)))
+ (cl-letf (((symbol-function 'read-char-from-minibuffer) 'error))
+ (dired temporary-file-directory)
+ (dired-goto-file foo)
+ ;; `dired-do-shell-command' returns nil on success.
+ (should-error (dired-do-shell-command "ls ? ./?" nil files))
+ (should-error (dired-do-shell-command "ls ./? ?" nil files))
+ (should-not (dired-do-shell-command "ls ? ?" nil files))
+ (should-error (dired-do-shell-command "ls * ./*" nil files))
+ (should-not (dired-do-shell-command "ls * *" nil files))
+ (should-not (dired-do-shell-command "ls ? ./`?`" nil files))))))
;; Auxiliary macro for `dired-test-bug28834': it binds
;; `dired-create-destination-dirs' to CREATE-DIRS and execute BODY.
@@ -47,28 +46,25 @@
(defmacro with-dired-bug28834-test (create-dirs yes-or-no &rest body)
(declare (debug (form symbolp body)))
(let ((foo (make-symbol "foo")))
- `(let* ((,foo (make-temp-file "foo" 'dir))
- (dired-create-destination-dirs ,create-dirs))
- (setq from (make-temp-file "from"))
- (setq to-cp
- (expand-file-name
- "foo-cp" (file-name-as-directory (expand-file-name "bar" ,foo))))
- (setq to-mv
- (expand-file-name
- "foo-mv" (file-name-as-directory (expand-file-name "qux" ,foo))))
- (unwind-protect
- (if ,yes-or-no
- (cl-letf (((symbol-function 'yes-or-no-p)
- (lambda (_prompt) (eq ,yes-or-no 'yes))))
- ,@body)
- ,@body)
- ;; clean up
- (delete-directory ,foo 'recursive)
- (delete-file from)))))
+ `(ert-with-temp-directory ,foo
+ (ert-with-temp-file from
+ (let* ((dired-create-destination-dirs ,create-dirs))
+ (setq to-cp
+ (expand-file-name
+ "foo-cp" (file-name-as-directory (expand-file-name "bar" ,foo))))
+ (setq to-mv
+ (expand-file-name
+ "foo-mv" (file-name-as-directory (expand-file-name "qux" ,foo))))
+ (unwind-protect
+ (if ,yes-or-no
+ (cl-letf (((symbol-function 'yes-or-no-p)
+ (lambda (_prompt) (eq ,yes-or-no 'yes))))
+ ,@body)
+ ,@body)))))))
(ert-deftest dired-test-bug28834 ()
"test for https://debbugs.gnu.org/28834 ."
- (let (from to-cp to-mv)
+ (let (to-cp to-mv)
;; `dired-create-destination-dirs' set to 'always.
(with-dired-bug28834-test
'always nil
@@ -159,4 +155,4 @@
(dired-test--check-highlighting (nth 0 lines) '(8))))
(provide 'dired-aux-tests)
-;; dired-aux-tests.el ends here
+;;; dired-aux-tests.el ends here
diff --git a/test/lisp/dired-resources/insert-directory/test_dir/bar b/test/lisp/dired-resources/insert-directory/test_dir/bar
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/test/lisp/dired-resources/insert-directory/test_dir/bar
diff --git a/test/lisp/dired-resources/insert-directory/test_dir/foo b/test/lisp/dired-resources/insert-directory/test_dir/foo
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/test/lisp/dired-resources/insert-directory/test_dir/foo
diff --git a/test/lisp/dired-resources/insert-directory/test_dir_other/bar b/test/lisp/dired-resources/insert-directory/test_dir_other/bar
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/test/lisp/dired-resources/insert-directory/test_dir_other/bar
diff --git a/test/lisp/dired-resources/insert-directory/test_dir_other/foo b/test/lisp/dired-resources/insert-directory/test_dir_other/foo
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/test/lisp/dired-resources/insert-directory/test_dir_other/foo
diff --git a/test/lisp/dired-tests.el b/test/lisp/dired-tests.el
index aac78c64c69..1c4f37bd327 100644
--- a/test/lisp/dired-tests.el
+++ b/test/lisp/dired-tests.el
@@ -19,6 +19,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'dired)
(ert-deftest dired-autoload ()
@@ -141,116 +142,113 @@
(ert-deftest dired-test-bug27243-01 ()
"Test for https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27243#5 ."
- (let* ((test-dir (file-name-as-directory (make-temp-file "test-dir-" t)))
- (save-pos (lambda ()
- (with-current-buffer (car (dired-buffers-for-dir test-dir))
- (dired-save-positions))))
- (dired-auto-revert-buffer t) buffers)
- ;; On MS-Windows, get rid of 8+3 short names in test-dir, if the
- ;; corresponding long file names exist, otherwise such names trip
- ;; dired-buffers-for-dir.
- (if (eq system-type 'windows-nt)
- (setq test-dir (file-truename test-dir)))
- (should-not (dired-buffers-for-dir test-dir))
- (with-current-buffer (find-file-noselect test-dir)
- (make-directory "test-subdir"))
- (message "Saved pos: %S" (funcall save-pos))
- ;; Point must be at end-of-buffer.
- (with-current-buffer (car (dired-buffers-for-dir test-dir))
- (should (eobp)))
- (push (dired test-dir) buffers)
- (message "Saved pos: %S" (funcall save-pos))
- ;; Previous dired call shouldn't create a new buffer: must visit the one
- ;; created by `find-file-noselect' above.
- (should (eq 1 (length (dired-buffers-for-dir test-dir))))
- (unwind-protect
- (let ((buf (current-buffer))
- (pt1 (point))
- (test-file (concat (file-name-as-directory "test-subdir")
- "test-file")))
- (message "Saved pos: %S" (funcall save-pos))
- (write-region "Test" nil test-file nil 'silent nil 'excl)
- (message "Saved pos: %S" (funcall save-pos))
- ;; Sanity check: point should now be on the subdirectory.
- (should (equal (dired-file-name-at-point)
- (concat test-dir (file-name-as-directory "test-subdir"))))
- (message "Saved pos: %S" (funcall save-pos))
- (push (dired-find-file) buffers)
- (let ((pt2 (point))) ; Point is on test-file.
- (pop-to-buffer-same-window buf)
- ;; Sanity check: point should now be back on the subdirectory.
- (should (eq (point) pt1))
+ (ert-with-temp-directory test-dir
+ (let* ((save-pos (lambda ()
+ (with-current-buffer (car (dired-buffers-for-dir test-dir))
+ (dired-save-positions))))
+ (dired-auto-revert-buffer t) buffers)
+ ;; On MS-Windows, get rid of 8+3 short names in test-dir, if the
+ ;; corresponding long file names exist, otherwise such names trip
+ ;; dired-buffers-for-dir.
+ (if (eq system-type 'windows-nt)
+ (setq test-dir (file-truename test-dir)))
+ (should-not (dired-buffers-for-dir test-dir))
+ (with-current-buffer (find-file-noselect test-dir)
+ (make-directory "test-subdir"))
+ (message "Saved pos: %S" (funcall save-pos))
+ ;; Point must be at end-of-buffer.
+ (with-current-buffer (car (dired-buffers-for-dir test-dir))
+ (should (eobp)))
+ (push (dired test-dir) buffers)
+ (message "Saved pos: %S" (funcall save-pos))
+ ;; Previous dired call shouldn't create a new buffer: must visit the one
+ ;; created by `find-file-noselect' above.
+ (should (eq 1 (length (dired-buffers-for-dir test-dir))))
+ (unwind-protect
+ (let ((buf (current-buffer))
+ (pt1 (point))
+ (test-file (concat (file-name-as-directory "test-subdir")
+ "test-file")))
+ (message "Saved pos: %S" (funcall save-pos))
+ (write-region "Test" nil test-file nil 'silent nil 'excl)
+ (message "Saved pos: %S" (funcall save-pos))
+ ;; Sanity check: point should now be on the subdirectory.
+ (should (equal (dired-file-name-at-point)
+ (concat test-dir (file-name-as-directory "test-subdir"))))
+ (message "Saved pos: %S" (funcall save-pos))
(push (dired-find-file) buffers)
- (should (eq (point) pt2))))
- (dolist (buf buffers)
- (when (buffer-live-p buf) (kill-buffer buf)))
- (delete-directory test-dir t))))
+ (let ((pt2 (point))) ; Point is on test-file.
+ (pop-to-buffer-same-window buf)
+ ;; Sanity check: point should now be back on the subdirectory.
+ (should (eq (point) pt1))
+ (push (dired-find-file) buffers)
+ (should (eq (point) pt2))))
+ (dolist (buf buffers)
+ (when (buffer-live-p buf) (kill-buffer buf)))))))
(ert-deftest dired-test-bug27243-02 ()
"Test for https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27243#28 ."
- (let ((test-dir (make-temp-file "test-dir-" t))
- (dired-auto-revert-buffer t) buffers)
- ;; On MS-Windows, get rid of 8+3 short names in test-dir, if the
- ;; corresponding long file names exist, otherwise such names trip
- ;; string comparisons below.
- (if (eq system-type 'windows-nt)
- (setq test-dir (file-truename test-dir)))
- (with-current-buffer (find-file-noselect test-dir)
- (make-directory "test-subdir"))
- (push (dired test-dir) buffers)
- (unwind-protect
- (let ((buf (current-buffer))
- (pt1 (point))
- (test-file (concat (file-name-as-directory "test-subdir")
- "test-file")))
- (write-region "Test" nil test-file nil 'silent nil 'excl)
- ;; Sanity check: point should now be on the subdirectory.
- (should (equal (dired-file-name-at-point)
- (concat (file-name-as-directory test-dir)
- (file-name-as-directory "test-subdir"))))
- (push (dired-find-file) buffers)
- ;; Point is on test-file.
- (switch-to-buffer buf)
- ;; Sanity check: point should now be back on the subdirectory.
- (should (eq (point) pt1))
- (push (dired test-dir) buffers)
- (should (eq (point) pt1)))
- (dolist (buf buffers)
- (when (buffer-live-p buf) (kill-buffer buf)))
- (delete-directory test-dir t))))
+ (ert-with-temp-directory test-dir
+ (let ((dired-auto-revert-buffer t) buffers)
+ ;; On MS-Windows, get rid of 8+3 short names in test-dir, if the
+ ;; corresponding long file names exist, otherwise such names trip
+ ;; string comparisons below.
+ (if (eq system-type 'windows-nt)
+ (setq test-dir (file-truename test-dir)))
+ (with-current-buffer (find-file-noselect test-dir)
+ (make-directory "test-subdir"))
+ (push (dired test-dir) buffers)
+ (unwind-protect
+ (let ((buf (current-buffer))
+ (pt1 (point))
+ (test-file (concat (file-name-as-directory "test-subdir")
+ "test-file")))
+ (write-region "Test" nil test-file nil 'silent nil 'excl)
+ ;; Sanity check: point should now be on the subdirectory.
+ (should (equal (dired-file-name-at-point)
+ (concat (file-name-as-directory test-dir)
+ (file-name-as-directory "test-subdir"))))
+ (push (dired-find-file) buffers)
+ ;; Point is on test-file.
+ (switch-to-buffer buf)
+ ;; Sanity check: point should now be back on the subdirectory.
+ (should (eq (point) pt1))
+ (push (dired test-dir) buffers)
+ (should (eq (point) pt1)))
+ (dolist (buf buffers)
+ (when (buffer-live-p buf) (kill-buffer buf)))))))
(ert-deftest dired-test-bug27243-03 ()
"Test for https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27243#61 ."
- (let ((test-dir (make-temp-file "test-dir-" t))
- (dired-auto-revert-buffer t)
- allbufs)
- (unwind-protect
- (progn
- (with-current-buffer (find-file-noselect test-dir)
- (push (current-buffer) allbufs)
- (make-directory "test-subdir1")
- (make-directory "test-subdir2")
- (let ((test-file1 "test-file1")
- (test-file2 "test-file2"))
- (with-current-buffer (find-file-noselect "test-subdir1")
- (push (current-buffer) allbufs)
- (write-region "Test1" nil test-file1 nil 'silent nil 'excl))
- (with-current-buffer (find-file-noselect "test-subdir2")
- (push (current-buffer) allbufs)
- (write-region "Test2" nil test-file2 nil 'silent nil 'excl))))
- ;; Call find-file with a wild card and test point in each file.
- (let ((buffers (find-file (concat (file-name-as-directory test-dir)
- "*")
- t)))
- (dolist (buf buffers)
- (let ((pt (with-current-buffer buf (point))))
- (switch-to-buffer (find-file-noselect test-dir))
- (find-file (buffer-name buf))
- (should (equal (point) pt))))
- (append buffers allbufs)))
- (dolist (buf allbufs)
- (when (buffer-live-p buf) (kill-buffer buf)))
- (delete-directory test-dir t))))
+ (ert-with-temp-directory test-dir
+ (let ((dired-auto-revert-buffer t)
+ allbufs)
+ (unwind-protect
+ (progn
+ (with-current-buffer (find-file-noselect test-dir)
+ (push (current-buffer) allbufs)
+ (make-directory "test-subdir1")
+ (make-directory "test-subdir2")
+ (let ((test-file1 "test-file1")
+ (test-file2 "test-file2"))
+ (with-current-buffer (find-file-noselect "test-subdir1")
+ (push (current-buffer) allbufs)
+ (write-region "Test1" nil test-file1 nil 'silent nil 'excl))
+ (with-current-buffer (find-file-noselect "test-subdir2")
+ (push (current-buffer) allbufs)
+ (write-region "Test2" nil test-file2 nil 'silent nil 'excl))))
+ ;; Call find-file with a wild card and test point in each file.
+ (let ((buffers (find-file (concat (file-name-as-directory test-dir)
+ "*")
+ t)))
+ (dolist (buf buffers)
+ (let ((pt (with-current-buffer buf (point))))
+ (switch-to-buffer (find-file-noselect test-dir))
+ (find-file (buffer-name buf))
+ (should (equal (point) pt))))
+ (append buffers allbufs)))
+ (dolist (buf allbufs)
+ (when (buffer-live-p buf) (kill-buffer buf)))))))
(ert-deftest dired-test-bug7131 ()
"Test for https://debbugs.gnu.org/7131 ."
@@ -274,22 +272,21 @@
;; ls-lisp-tests.el and em-ls-tests.el.
(skip-unless (and (not (featurep 'ls-lisp))
(not (featurep 'eshell))))
- (let* ((dir (make-temp-file "bug27631" 'dir))
- (dir1 (expand-file-name "dir1" dir))
- (dir2 (expand-file-name "dir2" dir))
- (default-directory dir)
- buf)
- (unwind-protect
- (progn
- (make-directory dir1)
- (make-directory dir2)
- (with-temp-file (expand-file-name "a.txt" dir1))
- (with-temp-file (expand-file-name "b.txt" dir2))
- (setq buf (dired (expand-file-name "dir*/*.txt" dir)))
- (dired-toggle-marks)
- (should (cdr (dired-get-marked-files))))
- (delete-directory dir 'recursive)
- (when (buffer-live-p buf) (kill-buffer buf)))))
+ (ert-with-temp-directory dir
+ (let* ((dir1 (expand-file-name "dir1" dir))
+ (dir2 (expand-file-name "dir2" dir))
+ (default-directory dir)
+ buf)
+ (unwind-protect
+ (progn
+ (make-directory dir1)
+ (make-directory dir2)
+ (with-temp-file (expand-file-name "a.txt" dir1))
+ (with-temp-file (expand-file-name "b.txt" dir2))
+ (setq buf (dired (expand-file-name "dir*/*.txt" dir)))
+ (dired-toggle-marks)
+ (should (cdr (dired-get-marked-files))))
+ (when (buffer-live-p buf) (kill-buffer buf))))))
(ert-deftest dired-test-bug27899 ()
"Test for https://debbugs.gnu.org/27899 ."
@@ -310,72 +307,69 @@
(ert-deftest dired-test-bug27968 ()
"Test for https://debbugs.gnu.org/27968 ."
- (let* ((top-dir (make-temp-file "top-dir" t))
- (subdir (expand-file-name "subdir" top-dir))
- (header-len-fn (lambda ()
- (save-excursion
- (goto-char 1)
- (forward-line 1)
- (- (point-at-eol) (point)))))
- orig-len len diff pos line-nb)
- (make-directory subdir 'parents)
- (unwind-protect
- (with-current-buffer (dired-noselect subdir)
- (setq orig-len (funcall header-len-fn)
- pos (point)
- line-nb (line-number-at-pos))
- ;; Bug arises when the header line changes its length; this may
- ;; happen if the used space has changed: for instance, with the
- ;; creation of additional files.
- (make-directory "subdir" t)
- (dired-revert)
- ;; Change the header line.
- (save-excursion
- (goto-char 1)
- (forward-line 1)
- (let ((inhibit-read-only t)
- (new-header " test-bug27968"))
- (delete-region (point) (point-at-eol))
- (when (= orig-len (length new-header))
- ;; Wow lucky guy! I must buy lottery today.
- (setq new-header (concat new-header " :-)")))
- (insert new-header)))
- (setq len (funcall header-len-fn)
- diff (- len orig-len))
- (should-not (zerop diff)) ; Header length has changed.
- ;; If diff > 0, then the point moves back.
- ;; If diff < 0, then the point moves forward.
- ;; If diff = 0, then the point doesn't move.
- ;; Sometimes this point movement causes
- ;; line-nb != (line-number-at-pos pos), so that we get
- ;; an unexpected file at point if we store buffer points.
- ;; Note that the line number before/after revert
- ;; doesn't change.
- (should (= line-nb
- (line-number-at-pos)
- (line-number-at-pos (+ pos diff))))
- ;; After revert, the point must be in 'subdir' line.
- (should (equal "subdir" (dired-get-filename 'local t))))
- (delete-directory top-dir t))))
+ (ert-with-temp-directory top-dir
+ (let* ((subdir (expand-file-name "subdir" top-dir))
+ (header-len-fn (lambda ()
+ (save-excursion
+ (goto-char 1)
+ (forward-line 1)
+ (- (point-at-eol) (point)))))
+ orig-len len diff pos line-nb)
+ (make-directory subdir 'parents)
+ (with-current-buffer (dired-noselect subdir)
+ (setq orig-len (funcall header-len-fn)
+ pos (point)
+ line-nb (line-number-at-pos))
+ ;; Bug arises when the header line changes its length; this may
+ ;; happen if the used space has changed: for instance, with the
+ ;; creation of additional files.
+ (make-directory "subdir" t)
+ (dired-revert)
+ ;; Change the header line.
+ (save-excursion
+ (goto-char 1)
+ (forward-line 1)
+ (let ((inhibit-read-only t)
+ (new-header " test-bug27968"))
+ (delete-region (point) (point-at-eol))
+ (when (= orig-len (length new-header))
+ ;; Wow lucky guy! I must buy lottery today.
+ (setq new-header (concat new-header " :-)")))
+ (insert new-header)))
+ (setq len (funcall header-len-fn)
+ diff (- len orig-len))
+ (should-not (zerop diff)) ; Header length has changed.
+ ;; If diff > 0, then the point moves back.
+ ;; If diff < 0, then the point moves forward.
+ ;; If diff = 0, then the point doesn't move.
+ ;; Sometimes this point movement causes
+ ;; line-nb != (line-number-at-pos pos), so that we get
+ ;; an unexpected file at point if we store buffer points.
+ ;; Note that the line number before/after revert
+ ;; doesn't change.
+ (should (= line-nb
+ (line-number-at-pos)
+ (line-number-at-pos (+ pos diff))))
+ ;; After revert, the point must be in 'subdir' line.
+ (should (equal "subdir" (dired-get-filename 'local t)))))))
(defmacro dired-test-with-temp-dirs (just-empty-dirs &rest body)
"Helper macro for Bug#27940 test."
(declare (indent 1) (debug body))
(let ((dir (make-symbol "dir")))
- `(let* ((,dir (make-temp-file "bug27940" t))
- (dired-deletion-confirmer (lambda (_) "yes")) ; Suppress prompts.
- (inhibit-message t)
- (default-directory ,dir))
- (dotimes (i 5) (make-directory (format "empty-dir-%d" i)))
- (unless ,just-empty-dirs
- (dotimes (i 5) (make-directory (format "non-empty-%d/foo" i) 'parents)))
- (make-directory "zeta-empty-dir")
- (unwind-protect
- (progn
- ,@body)
- (delete-directory ,dir t)
- (kill-buffer (current-buffer))))))
+ `(ert-with-temp-directory ,dir
+ (let* ((dired-deletion-confirmer (lambda (_) "yes")) ; Suppress prompts.
+ (inhibit-message t)
+ (default-directory ,dir))
+ (dotimes (i 5) (make-directory (format "empty-dir-%d" i)))
+ (unless ,just-empty-dirs
+ (dotimes (i 5) (make-directory (format "non-empty-%d/foo" i) 'parents)))
+ (make-directory "zeta-empty-dir")
+ (unwind-protect
+ (progn
+ ,@body)
+ (kill-buffer (current-buffer)))))))
(ert-deftest dired-test-bug27940 ()
"Test for https://debbugs.gnu.org/27940 ."
@@ -517,5 +511,92 @@
(when (file-directory-p testdir)
(delete-directory testdir t)))))
+;; `dired-insert-directory' output tests.
+(let* ((data-dir "insert-directory")
+ (test-dir (file-name-as-directory
+ (ert-resource-file
+ (concat data-dir "/test_dir"))))
+ (test-dir-other (file-name-as-directory
+ (ert-resource-file
+ (concat data-dir "/test_dir_other"))))
+ (test-files `(,test-dir "foo" "bar")) ;expected files to be found
+ ;; Free space test data for `insert-directory'.
+ ;; Meaning: (path free-space-bytes-to-stub expected-free-space-string)
+ (free-data `((,test-dir 10 "available 10 B")
+ (,test-dir-other 100 "available 100 B")
+ (:default 999 "available 999 B"))))
+
+ (defun files-tests--look-up-free-data (path)
+ "Look up free space test data, with a default for unspecified paths."
+ (let ((path (file-name-as-directory path)))
+ (cdr (or (assoc path free-data)
+ (assoc :default free-data)))))
+
+ (defun files-tests--make-file-system-info-stub (&optional static-path)
+ "Return a stub for `file-system-info' using dynamic or static test data.
+If that data should be static, pass STATIC-PATH to choose which
+path's data to use."
+ (lambda (path)
+ (let* ((path (cond (static-path)
+ ;; file-system-info knows how to handle ".", so we
+ ;; do the same thing
+ ((equal "." path) default-directory)
+ (path)))
+ (return-size
+ ;; It is always defined but this silences the byte-compiler:
+ (when (fboundp 'files-tests--look-up-free-data)
+ (car (files-tests--look-up-free-data path)))))
+ (list return-size return-size return-size))))
+
+ (defun files-tests--insert-directory-output (dir &optional _verbose)
+ "Run `insert-directory' and return its output."
+ (with-current-buffer-window "files-tests--insert-directory" nil nil
+ (let ((dired-free-space 'separate))
+ (dired-insert-directory dir "-l" nil nil t))
+ (buffer-substring-no-properties (point-min) (point-max))))
+
+ (ert-deftest files-tests-insert-directory-shows-files ()
+ "Verify `insert-directory' reports the files in the directory."
+ ;; It is always defined but this silences the byte-compiler:
+ (when (fboundp 'files-tests--insert-directory-output)
+ (let* ((test-dir (car test-files))
+ (files (cdr test-files))
+ (output (files-tests--insert-directory-output test-dir)))
+ (dolist (file files)
+ (should (string-match-p file output))))))
+
+ (defun files-tests--insert-directory-shows-given-free (dir &optional
+ info-func)
+ "Run `insert-directory' and verify it reports the correct available space.
+Stub `file-system-info' to ensure the available space is consistent,
+either with the given stub function or a default one using test data."
+ ;; It is always defined but this silences the byte-compiler:
+ (when (and (fboundp 'files-tests--make-file-system-info-stub)
+ (fboundp 'files-tests--look-up-free-data)
+ (fboundp 'files-tests--insert-directory-output))
+ (cl-letf (((symbol-function 'file-system-info)
+ (or info-func
+ (files-tests--make-file-system-info-stub))))
+ (should (string-match-p (cadr
+ (files-tests--look-up-free-data dir))
+ (files-tests--insert-directory-output dir t))))))
+
+ (ert-deftest files-tests-insert-directory-shows-free ()
+ "Test that verbose `insert-directory' shows the correct available space."
+ ;; It is always defined but this silences the byte-compiler:
+ (when (and (fboundp 'files-tests--insert-directory-shows-given-free)
+ (fboundp 'files-tests--make-file-system-info-stub))
+ (files-tests--insert-directory-shows-given-free
+ test-dir
+ (files-tests--make-file-system-info-stub test-dir))))
+
+ (ert-deftest files-tests-bug-50630 ()
+ "Verify verbose `insert-directory' shows free space of the target directory.
+The current directory at call time should not affect the result (Bug#50630)."
+ ;; It is always defined but this silences the byte-compiler:
+ (when (fboundp 'files-tests--insert-directory-shows-given-free)
+ (let ((default-directory test-dir-other))
+ (files-tests--insert-directory-shows-given-free test-dir)))))
+
(provide 'dired-tests)
-;; dired-tests.el ends here
+;;; dired-tests.el ends here
diff --git a/test/lisp/dired-x-tests.el b/test/lisp/dired-x-tests.el
index 003923d60fa..69c88c060a1 100644
--- a/test/lisp/dired-x-tests.el
+++ b/test/lisp/dired-x-tests.el
@@ -19,6 +19,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'dired-x)
@@ -31,23 +32,20 @@
(append (copy-sequence dirs)
(delete "c" (copy-sequence files)))
#'string<))
- (dir (make-temp-file "Bug25942" 'dir))
(extension "c"))
- (unwind-protect
- (progn
- (dolist (d dirs)
- (make-directory (expand-file-name d dir)))
- (dolist (f files)
- (write-region nil nil (expand-file-name f dir)))
- (dired dir)
- (dired-mark-extension extension)
- (should (equal '("bar.c" "foo.c")
- (sort (dired-get-marked-files 'local) #'string<)))
- (dired-unmark-all-marks)
- (dired-mark-suffix extension)
- (should (equal all-but-c
- (sort (dired-get-marked-files 'local) #'string<))))
- (delete-directory dir 'recursive))))
+ (ert-with-temp-directory dir
+ (dolist (d dirs)
+ (make-directory (expand-file-name d dir)))
+ (dolist (f files)
+ (write-region nil nil (expand-file-name f dir)))
+ (dired dir)
+ (dired-mark-extension extension)
+ (should (equal '("bar.c" "foo.c")
+ (sort (dired-get-marked-files 'local) #'string<)))
+ (dired-unmark-all-marks)
+ (dired-mark-suffix extension)
+ (should (equal all-but-c
+ (sort (dired-get-marked-files 'local) #'string<))))))
(ert-deftest dired-guess-default ()
(let ((dired-guess-shell-alist-user nil)
@@ -62,5 +60,15 @@
(should (equal (dired-guess-default '("/tmp/foo.png" "/tmp/foo.txt"))
nil))))
+(ert-deftest dired-x--string-to-number ()
+ (should (= (dired-x--string-to-number "2.4K") 2457.6))
+ (should (= (dired-x--string-to-number "2400") 2400))
+ (should (= (dired-x--string-to-number "123.4M") 129394278.4))
+ (should (= (dired-x--string-to-number "123.40000M") 129394278.4))
+ (should (= (dired-x--string-to-number "4.134") 4134))
+ (should (= (dired-x--string-to-number "4,134") 4134))
+ (should (= (dired-x--string-to-number "4 134") 4134))
+ (should (= (dired-x--string-to-number "41,52,134") 4152134)))
+
(provide 'dired-x-tests)
-;; dired-x-tests.el ends here
+;;; dired-x-tests.el ends here
diff --git a/test/lisp/edmacro-tests.el b/test/lisp/edmacro-tests.el
new file mode 100644
index 00000000000..974f506a367
--- /dev/null
+++ b/test/lisp/edmacro-tests.el
@@ -0,0 +1,47 @@
+;;; edmacro-tests.el --- Tests for edmacro.el -*- lexical-binding:t -*-
+
+;; Copyright (C) 2021 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 'edmacro)
+
+(ert-deftest edmacro-test-edmacro-parse-keys ()
+ (should (equal (edmacro-parse-keys "") ""))
+ (should (equal (edmacro-parse-keys "x") "x"))
+ (should (equal (edmacro-parse-keys "C-a") "\C-a"))
+
+ ;; comments
+ (should (equal (edmacro-parse-keys ";; foobar") ""))
+ (should (equal (edmacro-parse-keys ";;;") ""))
+ (should (equal (edmacro-parse-keys "; ; ;") ";;;"))
+ (should (equal (edmacro-parse-keys "REM foobar") ""))
+ (should (equal (edmacro-parse-keys "x ;; foobar") "x"))
+ (should (equal (edmacro-parse-keys "x REM foobar") "x"))
+ (should (equal (edmacro-parse-keys "<<goto-line>>")
+ [134217848 103 111 116 111 45 108 105 110 101 13]))
+
+ ;; repetitions
+ (should (equal (edmacro-parse-keys "3*x") "xxx"))
+ (should (equal (edmacro-parse-keys "3*C-m") "\C-m\C-m\C-m"))
+ (should (equal (edmacro-parse-keys "10*foo") "foofoofoofoofoofoofoofoofoofoo")))
+
+;;; edmacro-tests.el ends here
diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el
index c5124aca5ee..85727bd0916 100644
--- a/test/lisp/electric-tests.el
+++ b/test/lisp/electric-tests.el
@@ -35,7 +35,8 @@
(defun call-with-saved-electric-modes (fn)
(let ((saved-electric (if electric-pair-mode 1 -1))
(saved-layout (if electric-layout-mode 1 -1))
- (saved-indent (if electric-indent-mode 1 -1)))
+ (saved-indent (if electric-indent-mode 1 -1))
+ (blink-paren-function nil))
(electric-pair-mode -1)
(electric-layout-mode -1)
(electric-indent-mode -1)
@@ -53,17 +54,18 @@
expected-point mode bindings
fixture-fn &optional doc-string)
(with-temp-buffer
- (funcall mode)
- (insert fixture)
- (save-electric-modes
- (let ((last-command-event char)
- (transient-mark-mode 'lambda))
- (goto-char where)
- (funcall fixture-fn)
- (cl-progv
- (mapcar #'car bindings)
- (mapcar #'cdr bindings)
- (call-interactively (key-binding `[,last-command-event])))))
+ (dlet ((python-indent-guess-indent-offset-verbose nil))
+ (funcall mode)
+ (insert fixture)
+ (save-electric-modes
+ (let ((last-command-event char)
+ (transient-mark-mode 'lambda))
+ (goto-char where)
+ (funcall fixture-fn)
+ (cl-progv
+ (mapcar #'car bindings)
+ (mapcar #'cdr bindings)
+ (call-interactively (key-binding `[,last-command-event]))))))
(when
(and doc-string
(not
@@ -95,23 +97,24 @@
(with-temp-buffer
(cl-progv
;; FIXME: avoid `eval'
- (mapcar #'car (eval bindings))
- (mapcar #'cdr (eval bindings))
- (funcall mode)
- (insert fixture)
- (goto-char (1+ pos))
- (insert char)
- (cond ((eq (aref skip-pair-string pos)
- ?p)
- (insert (cadr (electric-pair-syntax-info char)))
- (backward-char 1))
- ((eq (aref skip-pair-string pos)
- ?s)
- (delete-char -1)
- (forward-char 1)))
- (list
- (buffer-substring-no-properties (point-min) (point-max))
- (point))))
+ (mapcar #'car (eval bindings t))
+ (mapcar #'cdr (eval bindings t))
+ (dlet ((python-indent-guess-indent-offset-verbose nil))
+ (funcall mode)
+ (insert fixture)
+ (goto-char (1+ pos))
+ (insert char)
+ (cond ((eq (aref skip-pair-string pos)
+ ?p)
+ (insert (cadr (electric-pair-syntax-info char)))
+ (backward-char 1))
+ ((eq (aref skip-pair-string pos)
+ ?s)
+ (delete-char -1)
+ (forward-char 1)))
+ (list
+ (buffer-substring-no-properties (point-min) (point-max))
+ (point)))))
(list expected-string expected-point)))
(expected-string (car expected-string-and-point))
(expected-point (cadr expected-string-and-point))
@@ -173,7 +176,7 @@ The buffer's contents should %s:
expected-string
expected-point
bindings
- (modes '(quote (ruby-mode js-mode)))
+ (modes '(quote (ruby-mode js-mode python-mode c-mode)))
(test-in-comments t)
(test-in-strings t)
(test-in-code t)
@@ -184,17 +187,19 @@ The buffer's contents should %s:
(fixture-fn '#'electric-pair-mode))
`(progn
,@(cl-loop
- for mode in (eval modes) ;FIXME: avoid `eval'
+ for mode in (eval modes t) ;FIXME: avoid `eval'
append
(cl-loop
for (prefix suffix extra-desc) in
(append (if test-in-comments
`((,(with-temp-buffer
- (funcall mode)
- (insert "z")
- (comment-region (point-min) (point-max))
- (buffer-substring-no-properties (point-min)
- (1- (point-max))))
+ (dlet ((python-indent-guess-indent-offset-verbose
+ nil))
+ (funcall mode)
+ (insert "z")
+ (comment-region (point-min) (point-max))
+ (buffer-substring-no-properties (point-min)
+ (1- (point-max)))))
""
"-in-comments")))
(if test-in-strings
@@ -296,7 +301,7 @@ The buffer's contents should %s:
;;; Quotes
;;;
(define-electric-pair-test pair-some-quotes-skip-others
- " \"\" " "-\"\"-----" :skip-pair-string "-ps------"
+ " \"\" " "-\"\"-\"---" :skip-pair-string "-ps-p----"
:test-in-strings nil
:bindings `((electric-pair-text-syntax-table
. ,prog-mode-syntax-table)))
@@ -423,7 +428,9 @@ baz\"\""
:bindings '((electric-pair-skip-whitespace . chomp))
:test-in-strings nil
:test-in-code nil
- :test-in-comments t)
+ :test-in-comments t
+ :fixture-fn (lambda () (when (eq major-mode 'c-mode)
+ (c-toggle-comment-style -1))))
(define-electric-pair-test whitespace-skipping-for-quotes-not-outside
" \" \"" "\"-----" :expected-string "\"\" \" \""
@@ -543,16 +550,6 @@ baz\"\""
(electric-indent-mode 1)
(electric-layout-mode 1)))
-(define-electric-pair-test js-mode-braces-with-layout-and-indent
- "" "{" :expected-string "{\n \n}" :expected-point 7
- :modes '(js-mode)
- :test-in-comments nil
- :test-in-strings nil
- :fixture-fn (lambda ()
- (electric-pair-mode 1)
- (electric-indent-mode 1)
- (electric-layout-mode 1)))
-
;;; Backspacing
;;; TODO: better tests
@@ -587,7 +584,6 @@ baz\"\""
;;; Electric newlines between pairs
;;; TODO: better tests
(ert-deftest electric-pair-open-extra-newline ()
- (skip-unless (not (getenv "EMACS_HYDRA_CI")))
(save-electric-modes
(with-temp-buffer
(c-mode)
@@ -871,15 +867,13 @@ baz\"\""
(local-set-key (vector key) 'self-insert-command)))
(defun electric-layout-for-c-style-du-jour (inserted)
- "A function to use in `electric-layout-rules'"
+ "A function to use in `electric-layout-rules'."
(when (memq inserted '(?\{ ?\}))
(save-excursion
(backward-char 2) (c-point-syntax) (forward-char) ; silly, but needed
(c-brace-newlines (c-point-syntax)))))
(ert-deftest electric-layout-plainer-c-mode-use-c-style ()
- ;; FIXME hangs since c4d34d2
- (skip-unless (not (getenv "EMACS_HYDRA_CI")))
(ert-with-test-buffer ()
(plainer-c-mode)
(electric-layout-local-mode 1)
@@ -893,7 +887,6 @@ baz\"\""
(should (equal (buffer-string) "int main ()\n{\n \n}\n"))))
(ert-deftest electric-layout-int-main-kernel-style ()
- (skip-unless (not (getenv "EMACS_HYDRA_CI")))
(ert-with-test-buffer ()
(plainer-c-mode)
(electric-layout-local-mode 1)
@@ -910,7 +903,6 @@ baz\"\""
(ert-deftest electric-layout-control-reindentation ()
"Same as `emacs-lisp-int-main-kernel-style', but checking
Bug#35254."
- (skip-unless (not (getenv "EMACS_HYDRA_CI")))
(ert-with-test-buffer ()
(plainer-c-mode)
(electric-layout-local-mode 1)
@@ -929,7 +921,6 @@ Bug#35254."
(should (equal (buffer-string) "int main () {\n\n \n}"))))
(ert-deftest electric-modes-int-main-allman-style ()
- (skip-unless (not (getenv "EMACS_HYDRA_CI")))
(ert-with-test-buffer ()
(plainer-c-mode)
(electric-layout-local-mode 1)
@@ -944,7 +935,6 @@ Bug#35254."
(should (equal (buffer-string) "int main ()\n{\n \n}"))))
(ert-deftest electric-pair-mode-newline-between-parens ()
- (skip-unless (not (getenv "EMACS_HYDRA_CI")))
(ert-with-test-buffer ()
(plainer-c-mode)
(electric-layout-local-mode -1) ;; ensure e-l-m mode is off
@@ -956,7 +946,6 @@ Bug#35254."
(should (equal (buffer-string) "int main () {\n \n}"))))
(ert-deftest electric-layout-mode-newline-between-parens-without-e-p-m ()
- (skip-unless (not (getenv "EMACS_HYDRA_CI")))
(ert-with-test-buffer ()
(plainer-c-mode)
(electric-layout-local-mode 1)
@@ -978,7 +967,6 @@ Bug#35254."
(should (equal (buffer-string) "int main () {\n \n}"))))
(ert-deftest electric-layout-mode-newline-between-parens-without-e-p-m-2 ()
- (skip-unless (not (getenv "EMACS_HYDRA_CI")))
(ert-with-test-buffer ()
(plainer-c-mode)
(electric-layout-local-mode 1)
diff --git a/test/lisp/emacs-lisp/backtrace-tests.el b/test/lisp/emacs-lisp/backtrace-tests.el
index 5c4e5305ecc..e35a7a729bc 100644
--- a/test/lisp/emacs-lisp/backtrace-tests.el
+++ b/test/lisp/emacs-lisp/backtrace-tests.el
@@ -49,7 +49,7 @@
(setq backtrace-frames (seq-subseq backtrace-frames 0 (1+ this-index))))
(backtrace-print))))
- (eval backtrace-tests--uncompiled-functions))
+ (eval backtrace-tests--uncompiled-functions t))
(defun backtrace-tests--backtrace-lines ()
(if debugger-stack-frame-as-list
diff --git a/test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-ignore-substitutions.el b/test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-ignore-substitutions.el
new file mode 100644
index 00000000000..37cfe463bfe
--- /dev/null
+++ b/test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-ignore-substitutions.el
@@ -0,0 +1,17 @@
+;;; -*- lexical-binding: t -*-
+(defalias 'foo #'ignore
+ "None of this should be considered too wide.
+
+; this should be treated as 60 characters - no warning
+\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]
+
+; 64 * 'x' does not warn
+\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'
+
+; keymaps are just ignored
+\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>
+
+\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}
+
+bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar
+")
diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el
index 80003c264a2..a442eb473be 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -1,4 +1,4 @@
-;;; bytecomp-tests.el -*- lexical-binding:t -*-
+;;; bytecomp-tests.el --- Tests for bytecomp.el -*- lexical-binding:t -*-
;; Copyright (C) 2008-2021 Free Software Foundation, Inc.
@@ -41,6 +41,24 @@
"Identity, but hidden from some optimisations."
x)
+(defmacro bytecomp-test-loop (outer1 outer2 inner1 inner2)
+ "Exercise constant propagation inside `while' loops.
+OUTER1, OUTER2, INNER1 and INNER2 are forms placed in the outer and
+inner loops respectively."
+ `(let ((x 1) (i 3) (res nil))
+ (while (> i 0)
+ (let ((y 2) (j 2))
+ (setq res (cons (list 'outer x y) res))
+ (while (> j 0)
+ (setq res (cons (list 'inner x y) res))
+ ,inner1
+ ,inner2
+ (setq j (1- j)))
+ ,outer1
+ ,outer2)
+ (setq i (1- i)))
+ res))
+
(defconst bytecomp-tests--test-cases
'(
;; some functional tests
@@ -454,6 +472,25 @@
(setq x 10))))
4)
+ ;; Loop constprop: set the inner and outer variables in the inner
+ ;; and outer loops, all combinations.
+ (bytecomp-test-loop nil nil nil nil )
+ (bytecomp-test-loop nil nil nil (setq x 6))
+ (bytecomp-test-loop nil nil (setq x 5) nil )
+ (bytecomp-test-loop nil nil (setq x 5) (setq x 6))
+ (bytecomp-test-loop nil (setq x 4) nil nil )
+ (bytecomp-test-loop nil (setq x 4) nil (setq x 6))
+ (bytecomp-test-loop nil (setq x 4) (setq x 5) nil )
+ (bytecomp-test-loop nil (setq x 4) (setq x 5) (setq x 6))
+ (bytecomp-test-loop (setq x 3) nil nil nil )
+ (bytecomp-test-loop (setq x 3) nil nil (setq x 6))
+ (bytecomp-test-loop (setq x 3) nil (setq x 5) nil )
+ (bytecomp-test-loop (setq x 3) nil (setq x 5) (setq x 6))
+ (bytecomp-test-loop (setq x 3) (setq x 4) nil nil )
+ (bytecomp-test-loop (setq x 3) (setq x 4) nil (setq x 6))
+ (bytecomp-test-loop (setq x 3) (setq x 4) (setq x 5) nil )
+ (bytecomp-test-loop (setq x 3) (setq x 4) (setq x 5) (setq x 6))
+
;; No error, no success handler.
(condition-case x
(list 42)
@@ -536,6 +573,125 @@
(let ((_a 1)
(_b 2))
'z)
+ (let (x y)
+ y)
+ (let* (x y)
+ y)
+ (let (x y)
+ 'a)
+ (let* (x y)
+ 'a)
+
+ ;; Check empty-list optimisations.
+ (mapcar (lambda (x) (member x nil)) '("a" 2 nil))
+ (mapcar (lambda (x) (memql x nil)) '(a 2 nil))
+ (mapcar (lambda (x) (memq x nil)) '(a nil))
+ (let ((n 0))
+ (list (mapcar (lambda (x) (member (setq n (1+ n)) nil)) '(a "nil"))
+ n))
+ (mapcar (lambda (x) (assoc x nil)) '("a" nil))
+ (mapcar (lambda (x) (assq x nil)) '(a nil))
+ (mapcar (lambda (x) (rassoc x nil)) '("a" nil))
+ (mapcar (lambda (x) (rassq x nil)) '(a nil))
+ (let ((n 0))
+ (list (mapcar (lambda (x) (assoc (setq n (1+ n)) nil)) '(a "nil"))
+ n))
+
+ ;; Exercise variable-aliasing optimisations.
+ (let ((a (list 1)))
+ (let ((b a))
+ (let ((a (list 2)))
+ (list a b))))
+
+ (let ((a (list 1)))
+ (let ((a (list 2))
+ (b a))
+ (list a b)))
+
+ (let* ((a (list 1))
+ (b a)
+ (a (list 2)))
+ (condition-case a
+ (list a b)
+ (error (list 'error a b))))
+
+ (let* ((a (list 1))
+ (b a)
+ (a (list 2)))
+ (condition-case a
+ (/ 0)
+ (error (list 'error a b))))
+
+ (let* ((a (list 1))
+ (b a)
+ (a (list 2))
+ (f (list (lambda (x) (list x a)))))
+ (funcall (car f) 3))
+
+ (let* ((a (list 1))
+ (b a)
+ (f (list (lambda (x) (setq a x)))))
+ (funcall (car f) 3)
+ (list a b))
+
+ (let* ((a (list 1))
+ (b a)
+ (a (list 2))
+ (f (list (lambda (x) (setq a x)))))
+ (funcall (car f) 3)
+ (list a b))
+
+ (cond)
+ (mapcar (lambda (x) (cond ((= x 0)))) '(0 1))
+
+ ;; These expressions give different results in lexbind and dynbind modes,
+ ;; but in each the compiler and interpreter should agree!
+ ;; (They look much the same but come in pairs exercising both the
+ ;; `let' and `let*' paths.)
+ (let ((f (lambda (x)
+ (lambda ()
+ (let ((g (lambda () x)))
+ (let ((x 'a))
+ (list x (funcall g))))))))
+ (funcall (funcall f 'b)))
+ (let ((f (lambda (x)
+ (lambda ()
+ (let ((g (lambda () x)))
+ (let* ((x 'a))
+ (list x (funcall g))))))))
+ (funcall (funcall f 'b)))
+ (let ((f (lambda (x)
+ (lambda ()
+ (let ((g (lambda () x)))
+ (setq x (list x x))
+ (let ((x 'a))
+ (list x (funcall g))))))))
+ (funcall (funcall f 'b)))
+ (let ((f (lambda (x)
+ (lambda ()
+ (let ((g (lambda () x)))
+ (setq x (list x x))
+ (let* ((x 'a))
+ (list x (funcall g))))))))
+ (funcall (funcall f 'b)))
+ (let ((f (lambda (x)
+ (let ((g (lambda () x))
+ (h (lambda () (setq x (list x x)))))
+ (let ((x 'a))
+ (list x (funcall g) (funcall h)))))))
+ (funcall (funcall f 'b)))
+ (let ((f (lambda (x)
+ (let ((g (lambda () x))
+ (h (lambda () (setq x (list x x)))))
+ (let* ((x 'a))
+ (list x (funcall g) (funcall h)))))))
+ (funcall (funcall f 'b)))
+
+ ;; Test constant-propagation of access to captured variables.
+ (let* ((x 2)
+ (f (lambda ()
+ (let ((y x)) (list y 3 y)))))
+ (funcall f))
)
"List of expressions for cross-testing interpreted and compiled code.")
@@ -586,24 +742,19 @@ byte-compiled. Run with dynamic binding."
(defun test-byte-comp-compile-and-load (compile &rest forms)
(declare (indent 1))
- (let ((elfile nil)
- (elcfile nil))
- (unwind-protect
- (progn
- (setf elfile (make-temp-file "test-bytecomp" nil ".el"))
- (when compile
- (setf elcfile (make-temp-file "test-bytecomp" nil ".elc")))
- (with-temp-buffer
- (dolist (form forms)
- (print form (current-buffer)))
- (write-region (point-min) (point-max) elfile nil 'silent))
- (if compile
- (let ((byte-compile-dest-file-function
- (lambda (e) elcfile)))
- (byte-compile-file elfile)))
- (load elfile nil 'nomessage))
- (when elfile (delete-file elfile))
- (when elcfile (delete-file elcfile)))))
+ (ert-with-temp-file elfile
+ :suffix ".el"
+ (ert-with-temp-file elcfile
+ :suffix ".elc"
+ (with-temp-buffer
+ (dolist (form forms)
+ (print form (current-buffer)))
+ (write-region (point-min) (point-max) elfile nil 'silent))
+ (if compile
+ (let ((byte-compile-dest-file-function
+ (lambda (e) elcfile)))
+ (byte-compile-file elfile)))
+ (load elfile nil 'nomessage))))
(ert-deftest test-byte-comp-macro-expansion ()
(test-byte-comp-compile-and-load t
@@ -706,8 +857,7 @@ byte-compiled. Run with dynamic binding."
(byte-compile-file ,(ert-resource-file file))
(ert-info ((buffer-string) :prefix "buffer: ")
(,(if reverse 'should-not 'should)
- (re-search-forward ,(string-replace " " "[ \n]+" re-warning)
- nil t))))))
+ (re-search-forward ,re-warning nil t))))))
(bytecomp--define-warning-file-test "error-lexical-var-with-add-hook.el"
"add-hook.*lexical var")
@@ -833,10 +983,9 @@ byte-compiled. Run with dynamic binding."
"warn-wide-docstring-define-obsolete-variable-alias.el"
"defvaralias .foo. docstring wider than .* characters")
-;; TODO: We don't yet issue warnings for defuns.
(bytecomp--define-warning-file-test
"warn-wide-docstring-defun.el"
- "wider than .* characters" 'reverse)
+ "Warning: docstring wider than .* characters")
(bytecomp--define-warning-file-test
"warn-wide-docstring-defvar.el"
@@ -855,6 +1004,10 @@ byte-compiled. Run with dynamic binding."
"defvar .foo-bar. docstring wider than .* characters" 'reverse)
(bytecomp--define-warning-file-test
+ "warn-wide-docstring-ignore-substitutions.el"
+ "defvar .foo-bar. docstring wider than .* characters" 'reverse)
+
+(bytecomp--define-warning-file-test
"warn-wide-docstring-ignore.el"
"defvar .foo-bar. docstring wider than .* characters" 'reverse)
@@ -910,10 +1063,9 @@ byte-compiled. Run with dynamic binding."
(defmacro bytecomp-tests--with-temp-file (file-name-var &rest body)
(declare (indent 1))
(cl-check-type file-name-var symbol)
- `(let ((,file-name-var (make-temp-file "emacs")))
+ `(ert-with-temp-file ,file-name-var
(unwind-protect
(progn ,@body)
- (delete-file ,file-name-var)
(let ((elc (concat ,file-name-var ".elc")))
(if (file-exists-p elc) (delete-file elc))))))
@@ -1140,25 +1292,25 @@ literals (Bug#20852)."
(ert-deftest bytecomp-tests--not-writable-directory ()
"Test that byte compilation works if the output directory isn't
writable (Bug#44631)."
- (let ((directory (make-temp-file "bytecomp-tests-" :directory)))
- (unwind-protect
- (let* ((input-file (expand-file-name "test.el" directory))
- (output-file (expand-file-name "test.elc" directory))
- (byte-compile-dest-file-function
- (lambda (_) output-file))
- (byte-compile-error-on-warn t))
- (write-region "" nil input-file nil nil nil 'excl)
- (write-region "" nil output-file nil nil nil 'excl)
- (set-file-modes input-file #o400)
- (set-file-modes output-file #o200)
- (set-file-modes directory #o500)
- (should (byte-compile-file input-file))
- (should (file-regular-p output-file))
- (should (cl-plusp (file-attribute-size
- (file-attributes output-file)))))
- (with-demoted-errors "Error cleaning up directory: %s"
- (set-file-modes directory #o700)
- (delete-directory directory :recursive)))))
+ (ert-with-temp-directory directory
+ (let* ((input-file (expand-file-name "test.el" directory))
+ (output-file (expand-file-name "test.elc" directory))
+ (byte-compile-dest-file-function
+ (lambda (_) output-file))
+ (byte-compile-error-on-warn t))
+ (unwind-protect
+ (progn
+ (write-region "" nil input-file nil nil nil 'excl)
+ (write-region "" nil output-file nil nil nil 'excl)
+ (set-file-modes input-file #o400)
+ (set-file-modes output-file #o200)
+ (set-file-modes directory #o500)
+ (should (byte-compile-file input-file))
+ (should (file-regular-p output-file))
+ (should (cl-plusp (file-attribute-size
+ (file-attributes output-file)))))
+ ;; Allow the directory to be deleted.
+ (set-file-modes directory #o777)))))
(ert-deftest bytecomp-tests--dest-mountpoint ()
"Test that byte compilation works if the destination file is a
@@ -1170,56 +1322,53 @@ mountpoint (Bug#44631)."
(skip-unless (not (file-remote-p bwrap)))
(skip-unless (file-executable-p emacs))
(skip-unless (not (file-remote-p emacs)))
- (let ((directory (make-temp-file "bytecomp-tests-" :directory)))
- (unwind-protect
- (let* ((input-file (expand-file-name "test.el" directory))
- (output-file (expand-file-name "test.elc" directory))
- (unquoted-file (file-name-unquote output-file))
- (byte-compile-dest-file-function
- (lambda (_) output-file))
- (byte-compile-error-on-warn t))
- (should-not (file-remote-p input-file))
- (should-not (file-remote-p output-file))
- (write-region "" nil input-file nil nil nil 'excl)
- (write-region "" nil output-file nil nil nil 'excl)
- (set-file-modes input-file #o400)
- (set-file-modes output-file #o200)
- (set-file-modes directory #o500)
- (with-temp-buffer
- (let ((status (call-process
- bwrap nil t nil
- "--ro-bind" "/" "/"
- "--bind" unquoted-file unquoted-file
- emacs "--quick" "--batch" "--load=bytecomp"
- (format "--eval=%S"
- `(setq byte-compile-dest-file-function
- (lambda (_) ,output-file)
- byte-compile-error-on-warn t))
- "--funcall=batch-byte-compile" input-file)))
- (unless (eql status 0)
- (ert-fail `((status . ,status)
- (output . ,(buffer-string)))))))
- (should (file-regular-p output-file))
- (should (cl-plusp (file-attribute-size
- (file-attributes output-file)))))
- (with-demoted-errors "Error cleaning up directory: %s"
- (set-file-modes directory #o700)
- (delete-directory directory :recursive))))))
+ (ert-with-temp-directory directory
+ (let* ((input-file (expand-file-name "test.el" directory))
+ (output-file (expand-file-name "test.elc" directory))
+ (unquoted-file (file-name-unquote output-file))
+ (byte-compile-dest-file-function
+ (lambda (_) output-file))
+ (byte-compile-error-on-warn t))
+ (should-not (file-remote-p input-file))
+ (should-not (file-remote-p output-file))
+ (write-region "" nil input-file nil nil nil 'excl)
+ (write-region "" nil output-file nil nil nil 'excl)
+ (unwind-protect
+ (progn
+ (set-file-modes input-file #o400)
+ (set-file-modes output-file #o200)
+ (set-file-modes directory #o500)
+ (with-temp-buffer
+ (let ((status (call-process
+ bwrap nil t nil
+ "--ro-bind" "/" "/"
+ "--bind" unquoted-file unquoted-file
+ emacs "--quick" "--batch" "--load=bytecomp"
+ (format "--eval=%S"
+ `(setq byte-compile-dest-file-function
+ (lambda (_) ,output-file)
+ byte-compile-error-on-warn t))
+ "--funcall=batch-byte-compile" input-file)))
+ (unless (eql status 0)
+ (ert-fail `((status . ,status)
+ (output . ,(buffer-string)))))))
+ (should (file-regular-p output-file))
+ (should (cl-plusp (file-attribute-size
+ (file-attributes output-file)))))
+ ;; Allow the directory to be deleted.
+ (set-file-modes directory #o777))))))
(ert-deftest bytecomp-tests--target-file-no-directory ()
"Check that Bug#45287 is fixed."
- (let ((directory (make-temp-file "bytecomp-tests-" :directory)))
- (unwind-protect
- (let* ((default-directory directory)
- (byte-compile-dest-file-function (lambda (_) "test.elc"))
- (byte-compile-error-on-warn t))
- (write-region "" nil "test.el" nil nil nil 'excl)
- (should (byte-compile-file "test.el"))
- (should (file-regular-p "test.elc"))
- (should (cl-plusp (file-attribute-size
- (file-attributes "test.elc")))))
- (with-demoted-errors "Error cleaning up directory: %s"
- (delete-directory directory :recursive)))))
+ (ert-with-temp-directory directory
+ (let* ((default-directory directory)
+ (byte-compile-dest-file-function (lambda (_) "test.elc"))
+ (byte-compile-error-on-warn t))
+ (write-region "" nil "test.el" nil nil nil 'excl)
+ (should (byte-compile-file "test.el"))
+ (should (file-regular-p "test.elc"))
+ (should (cl-plusp (file-attribute-size
+ (file-attributes "test.elc")))))))
(defun bytecomp-tests--get-vars ()
(list (ignore-errors (symbol-value 'bytecomp-tests--var1))
@@ -1366,9 +1515,33 @@ compiled correctly."
(load-file (concat file "c"))
(should (equal (bc-test-alpha-f 'a) '(nil a)))))
+(ert-deftest bytecomp-tests-byte-compile--wide-docstring-p/func-arg-list ()
+ (should-not (byte-compile--wide-docstring-p "\
+\(dbus-register-property BUS SERVICE PATH INTERFACE PROPERTY ACCESS \
+[TYPE] VALUE &optional EMITS-SIGNAL DONT-REGISTER-SERVICE)" fill-column))
+ (should-not (byte-compile--wide-docstring-p "\
+(fn CMD FLAGS FIS &key (BUF (cvs-temp-buffer)) DONT-CHANGE-DISC CVSARGS \
+POSTPROC)" fill-column))
+ ;; Bug#49007
+ (should-not (byte-compile--wide-docstring-p "\
+(fn (THIS rudel-protocol-backend) TRANSPORT \
+INFO INFO-CALLBACK &optional PROGRESS-CALLBACK)" fill-column))
+ (should-not (byte-compile--wide-docstring-p "\
+\(fn NAME () [DOCSTRING] [:expected-result RESULT-TYPE] \
+[:tags \\='(TAG...)] BODY...)" fill-column))
+ (should-not (byte-compile--wide-docstring-p "\
+(make-soap-xs-element &key NAME NAMESPACE-TAG ID TYPE^ OPTIONAL? MULTIPLE? \
+REFERENCE SUBSTITUTION-GROUP ALTERNATIVES IS-GROUP)" fill-column))
+ (should-not (byte-compile--wide-docstring-p "\
+(fn NAME FIXTURE INPUT &key SKIP-PAIR-STRING EXPECTED-STRING \
+EXPECTED-POINT BINDINGS (MODES \\='\\='(ruby-mode js-mode python-mode)) \
+(TEST-IN-COMMENTS t) (TEST-IN-STRINGS t) (TEST-IN-CODE t) \
+(FIXTURE-FN \\='#\\='electric-pair-mode))" fill-column)))
+
+
;; Local Variables:
;; no-byte-compile: t
;; End:
(provide 'bytecomp-tests)
-;; bytecomp-tests.el ends here.
+;;; bytecomp-tests.el ends here
diff --git a/test/lisp/emacs-lisp/cconv-tests.el b/test/lisp/emacs-lisp/cconv-tests.el
index 5aeed0cc155..0701892b8c4 100644
--- a/test/lisp/emacs-lisp/cconv-tests.el
+++ b/test/lisp/emacs-lisp/cconv-tests.el
@@ -1,4 +1,4 @@
-;;; cconv-tests.el -*- lexical-binding: t -*-
+;;; cconv-tests.el --- Tests for cconv.el -*- lexical-binding: t -*-
;; Copyright (C) 2018-2021 Free Software Foundation, Inc.
@@ -19,6 +19,8 @@
;;; Commentary:
+;;; Code:
+
(require 'ert)
(require 'cl-lib)
@@ -203,5 +205,157 @@
nil 99)
42)))
+(defun cconv-tests--intern-all (x)
+ "Intern all symbols in X."
+ (cond ((symbolp x) (intern (symbol-name x)))
+ ((consp x) (cons (cconv-tests--intern-all (car x))
+ (cconv-tests--intern-all (cdr x))))
+ ;; Assume we don't need to deal with vectors etc.
+ (t x)))
+
+(ert-deftest cconv-closure-convert-remap-var ()
+ ;; Verify that we correctly remap shadowed lambda-lifted variables.
+
+ ;; We intern all symbols for ease of comparison; this works because
+ ;; the `cconv-closure-convert' result should contain no pair of
+ ;; distinct symbols having the same name.
+
+ ;; Sanity check: captured variable, no lambda-lifting or shadowing:
+ (should (equal (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ #'(lambda () x))))
+ '#'(lambda (x)
+ (internal-make-closure
+ nil (x) nil
+ (internal-get-closed-var 0)))))
+
+ ;; Basic case:
+ (should (equal (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ (let ((f #'(lambda () x)))
+ (let ((x 'b))
+ (list x (funcall f)))))))
+ '#'(lambda (x)
+ (let ((f #'(lambda (x) x)))
+ (let ((x 'b)
+ (closed-x x))
+ (list x (funcall f closed-x)))))))
+ (should (equal (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ (let ((f #'(lambda () x)))
+ (let* ((x 'b))
+ (list x (funcall f)))))))
+ '#'(lambda (x)
+ (let ((f #'(lambda (x) x)))
+ (let* ((closed-x x)
+ (x 'b))
+ (list x (funcall f closed-x)))))))
+
+ ;; With the lambda-lifted shadowed variable also being captured:
+ (should (equal
+ (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ #'(lambda ()
+ (let ((f #'(lambda () x)))
+ (let ((x 'a))
+ (list x (funcall f))))))))
+ '#'(lambda (x)
+ (internal-make-closure
+ nil (x) nil
+ (let ((f #'(lambda (x) x)))
+ (let ((x 'a)
+ (closed-x (internal-get-closed-var 0)))
+ (list x (funcall f closed-x))))))))
+ (should (equal
+ (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ #'(lambda ()
+ (let ((f #'(lambda () x)))
+ (let* ((x 'a))
+ (list x (funcall f))))))))
+ '#'(lambda (x)
+ (internal-make-closure
+ nil (x) nil
+ (let ((f #'(lambda (x) x)))
+ (let* ((closed-x (internal-get-closed-var 0))
+ (x 'a))
+ (list x (funcall f closed-x))))))))
+ ;; With lambda-lifted shadowed variable also being mutably captured:
+ (should (equal
+ (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ #'(lambda ()
+ (let ((f #'(lambda () x)))
+ (setq x x)
+ (let ((x 'a))
+ (list x (funcall f))))))))
+ '#'(lambda (x)
+ (let ((x (list x)))
+ (internal-make-closure
+ nil (x) nil
+ (let ((f #'(lambda (x) (car-safe x))))
+ (setcar (internal-get-closed-var 0)
+ (car-safe (internal-get-closed-var 0)))
+ (let ((x 'a)
+ (closed-x (internal-get-closed-var 0)))
+ (list x (funcall f closed-x)))))))))
+ (should (equal
+ (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ #'(lambda ()
+ (let ((f #'(lambda () x)))
+ (setq x x)
+ (let* ((x 'a))
+ (list x (funcall f))))))))
+ '#'(lambda (x)
+ (let ((x (list x)))
+ (internal-make-closure
+ nil (x) nil
+ (let ((f #'(lambda (x) (car-safe x))))
+ (setcar (internal-get-closed-var 0)
+ (car-safe (internal-get-closed-var 0)))
+ (let* ((closed-x (internal-get-closed-var 0))
+ (x 'a))
+ (list x (funcall f closed-x)))))))))
+ ;; Lambda-lifted variable that isn't actually captured where it is shadowed:
+ (should (equal
+ (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ (let ((g #'(lambda () x))
+ (h #'(lambda () (setq x x))))
+ (let ((x 'b))
+ (list x (funcall g) (funcall h)))))))
+ '#'(lambda (x)
+ (let ((x (list x)))
+ (let ((g #'(lambda (x) (car-safe x)))
+ (h #'(lambda (x) (setcar x (car-safe x)))))
+ (let ((x 'b)
+ (closed-x x))
+ (list x (funcall g closed-x) (funcall h closed-x))))))))
+ (should (equal
+ (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ (let ((g #'(lambda () x))
+ (h #'(lambda () (setq x x))))
+ (let* ((x 'b))
+ (list x (funcall g) (funcall h)))))))
+ '#'(lambda (x)
+ (let ((x (list x)))
+ (let ((g #'(lambda (x) (car-safe x)))
+ (h #'(lambda (x) (setcar x (car-safe x)))))
+ (let* ((closed-x x)
+ (x 'b))
+ (list x (funcall g closed-x) (funcall h closed-x))))))))
+ )
+
(provide 'cconv-tests)
-;; cconv-tests.el ends here.
+;;; cconv-tests.el ends here
diff --git a/test/lisp/emacs-lisp/check-declare-tests.el b/test/lisp/emacs-lisp/check-declare-tests.el
index 276530fb4d3..5c9d847e34a 100644
--- a/test/lisp/emacs-lisp/check-declare-tests.el
+++ b/test/lisp/emacs-lisp/check-declare-tests.el
@@ -28,6 +28,7 @@
(require 'check-declare)
(require 'ert)
+(require 'ert-x)
(eval-when-compile (require 'subr-x))
(ert-deftest check-declare-tests-locate ()
@@ -36,62 +37,53 @@
(string-prefix-p "ext:" (check-declare-locate "ext:foo" ""))))
(ert-deftest check-declare-tests-scan ()
- (let ((file (make-temp-file "check-declare-tests-")))
- (unwind-protect
- (progn
- (with-temp-file file
- (insert
- (string-join
- '(";; foo comment"
- "(declare-function ring-insert \"ring\" (ring item))"
- "(let ((foo 'code)) foo)")
- "\n")))
- (let ((res (check-declare-scan file)))
- (should (= (length res) 1))
- (pcase-let ((`((,fnfile ,fn ,arglist ,fileonly)) res))
- (should (string-match-p "ring" fnfile))
- (should (equal "ring-insert" fn))
- (should (equal '(ring item) arglist))
- (should-not fileonly))))
- (delete-file file))))
+ (ert-with-temp-file file
+ (with-temp-file file
+ (insert
+ (string-join
+ '(";; foo comment"
+ "(declare-function ring-insert \"ring\" (ring item))"
+ "(let ((foo 'code)) foo)")
+ "\n")))
+ (let ((res (check-declare-scan file)))
+ (should (= (length res) 1))
+ (pcase-let ((`((,fnfile ,fn ,arglist ,fileonly)) res))
+ (should (string-match-p "ring" fnfile))
+ (should (equal "ring-insert" fn))
+ (should (equal '(ring item) arglist))
+ (should-not fileonly)))))
(ert-deftest check-declare-tests-verify ()
- (let ((file (make-temp-file "check-declare-tests-")))
- (unwind-protect
- (progn
- (with-temp-file file
- (insert
- (string-join
- '(";; foo comment"
- "(defun foo-fun ())"
- "(defun ring-insert (ring item)"
- "\"Insert onto ring RING the item ITEM.\""
- "nil)")
- "\n")))
- (should-not
- (check-declare-verify
- file '(("foo.el" "ring-insert" (ring item))))))
- (delete-file file))))
+ (ert-with-temp-file file
+ (with-temp-file file
+ (insert
+ (string-join
+ '(";; foo comment"
+ "(defun foo-fun ())"
+ "(defun ring-insert (ring item)"
+ "\"Insert onto ring RING the item ITEM.\""
+ "nil)")
+ "\n")))
+ (should-not
+ (check-declare-verify
+ file '(("foo.el" "ring-insert" (ring item)))))))
(ert-deftest check-declare-tests-verify-mismatch ()
- (let ((file (make-temp-file "check-declare-tests-")))
- (unwind-protect
- (progn
- (with-temp-file file
- (insert
- (string-join
- '(";; foo comment"
- "(defun foo-fun ())"
- "(defun ring-insert (ring)"
- "\"Insert onto ring RING the item ITEM.\""
- "nil)")
- "\n")))
- (should
- (equal
- (check-declare-verify
- file '(("foo.el" "ring-insert" (ring item))))
- '(("foo.el" "ring-insert" "arglist mismatch")))))
- (delete-file file))))
+ (ert-with-temp-file file
+ (with-temp-file file
+ (insert
+ (string-join
+ '(";; foo comment"
+ "(defun foo-fun ())"
+ "(defun ring-insert (ring)"
+ "\"Insert onto ring RING the item ITEM.\""
+ "nil)")
+ "\n")))
+ (should
+ (equal
+ (check-declare-verify
+ file '(("foo.el" "ring-insert" (ring item))))
+ '(("foo.el" "ring-insert" "arglist mismatch"))))))
(ert-deftest check-declare-tests-sort ()
(should-not (check-declare-sort '()))
diff --git a/test/lisp/emacs-lisp/checkdoc-tests.el b/test/lisp/emacs-lisp/checkdoc-tests.el
index 2a1d8b27636..ef49e71599a 100644
--- a/test/lisp/emacs-lisp/checkdoc-tests.el
+++ b/test/lisp/emacs-lisp/checkdoc-tests.el
@@ -122,4 +122,100 @@ See the comments in Bug#24998."
(should (looking-at-p "\"baz\")"))
(should-not (checkdoc-next-docstring))))
+(defun checkdoc-tests--abbrev-test (buffer-contents goto-string)
+ (with-temp-buffer
+ (emacs-lisp-mode)
+ (insert buffer-contents)
+ (goto-char (point-min))
+ (re-search-forward goto-string)
+ (checkdoc-in-abbreviation-p (point))))
+
+(ert-deftest checkdoc-tests-in-abbrevation-p/basic-case ()
+ (should (checkdoc-tests--abbrev-test "foo bar e.g. baz" "e.g"))
+ (should (checkdoc-tests--abbrev-test "behavior/errors etc. that" "etc"))
+ (should (checkdoc-tests--abbrev-test "foo vs. bar" "vs"))
+ (should (checkdoc-tests--abbrev-test "spy a.k.a. spy" "a.k.a")))
+
+(ert-deftest checkdoc-tests-in-abbrevation-p/with-parens ()
+ (should (checkdoc-tests--abbrev-test "foo bar (e.g. baz)" "e.g")))
+
+(ert-deftest checkdoc-tests-in-abbrevation-p/with-escaped-parens ()
+ (should (checkdoc-tests--abbrev-test "foo\n\\(e.g. baz)" "e.g")))
+
+(ert-deftest checkdoc-tests-in-abbrevation-p/single-char ()
+ (should (checkdoc-tests--abbrev-test "a. foo bar" "a")))
+
+(ert-deftest checkdoc-tests-in-abbrevation-p/with-em-dash ()
+ (should (checkdoc-tests--abbrev-test "foo bar baz---e.g." "e.g")))
+
+(ert-deftest checkdoc-tests-in-abbrevation-p/incorrect-abbreviation ()
+ (should-not (checkdoc-tests--abbrev-test "foo bar a.b.c." "a.b.c")))
+
+(defun checkdoc-test-error-format-is-good (msg &optional reverse literal)
+ (with-temp-buffer
+ (erase-buffer)
+ (emacs-lisp-mode)
+ (let ((standard-output (current-buffer)))
+ (if literal
+ (print (format "(error \"%s\")" msg))
+ (prin1 `(error ,msg))))
+ (goto-char (length "(error \""))
+ (if reverse
+ (should (checkdoc--error-bad-format-p))
+ (should-not (checkdoc--error-bad-format-p)))))
+
+(defun checkdoc-test-error-format-is-bad (msg &optional literal)
+ (checkdoc-test-error-format-is-good msg t literal))
+
+(ert-deftest checkdoc-tests-error-message-bad-format-p ()
+ (checkdoc-test-error-format-is-good "Foo")
+ (checkdoc-test-error-format-is-good "Foo: bar baz")
+ (checkdoc-test-error-format-is-good "some-symbol: Foo")
+ (checkdoc-test-error-format-is-good "`some-symbol' foo bar")
+ (checkdoc-test-error-format-is-good "%sfoo")
+ (checkdoc-test-error-format-is-good "avl-tree-enter:\\
+ Updated data does not match existing data" nil 'literal))
+
+(ert-deftest checkdoc-tests-error-message-bad-format-p/defined-symbols ()
+ (defvar checkdoc-tests--var-symbol nil)
+ (checkdoc-test-error-format-is-good "checkdoc-tests--var-symbol foo bar baz")
+ (defun checkdoc-tests--fun-symbol ())
+ (checkdoc-test-error-format-is-good "checkdoc-tests--fun-symbol foo bar baz"))
+
+(ert-deftest checkdoc-tests-error-message-bad-format-p/not-capitalized ()
+ (checkdoc-test-error-format-is-bad "foo")
+ (checkdoc-test-error-format-is-bad "some-symbol: foo")
+ (checkdoc-test-error-format-is-bad "avl-tree-enter:\
+ updated data does not match existing data"))
+
+(ert-deftest checkdoc-tests-fix-y-or-n-p ()
+ (with-temp-buffer
+ (emacs-lisp-mode)
+ (let ((standard-output (current-buffer))
+ (checkdoc-autofix-flag 'automatic))
+ (prin1 '(y-or-n-p "foo")) ; "foo"
+ (goto-char (length "(y-or-n-p "))
+ (checkdoc--fix-y-or-n-p)
+ (should (equal (buffer-string) "(y-or-n-p \"foo?\")")))))
+
+(ert-deftest checkdoc-tests-fix-y-or-n-p/no-change ()
+ (with-temp-buffer
+ (emacs-lisp-mode)
+ (let ((standard-output (current-buffer))
+ (checkdoc-autofix-flag 'automatic))
+ (prin1 '(y-or-n-p "foo?")) ; "foo?"
+ (goto-char (length "(y-or-n-p "))
+ (checkdoc--fix-y-or-n-p)
+ (should (equal (buffer-string) "(y-or-n-p \"foo?\")")))))
+
+(ert-deftest checkdoc-tests-fix-y-or-n-p/with-space ()
+ (with-temp-buffer
+ (emacs-lisp-mode)
+ (let ((standard-output (current-buffer))
+ (checkdoc-autofix-flag 'automatic))
+ (prin1 '(y-or-n-p "foo? ")) ; "foo? "
+ (goto-char (length "(y-or-n-p "))
+ (checkdoc--fix-y-or-n-p)
+ (should (equal (buffer-string) "(y-or-n-p \"foo? \")")))))
+
;;; checkdoc-tests.el ends here
diff --git a/test/lisp/emacs-lisp/cl-generic-tests.el b/test/lisp/emacs-lisp/cl-generic-tests.el
index dd7511e9afe..9c285a9facf 100644
--- a/test/lisp/emacs-lisp/cl-generic-tests.el
+++ b/test/lisp/emacs-lisp/cl-generic-tests.el
@@ -200,9 +200,14 @@
(fmakunbound 'cl--generic-1)
(cl-defgeneric cl--generic-1 (x y))
(cl-defmethod cl--generic-1 ((x t) y)
- (list x y (cl-next-method-p)))
+ (list x y
+ (with-suppressed-warnings ((obsolete cl-next-method-p))
+ (cl-next-method-p))))
(cl-defmethod cl--generic-1 ((_x (eql 4)) _y)
- (cl-list* "quatre" (cl-next-method-p) (cl-call-next-method)))
+ (cl-list* "quatre"
+ (with-suppressed-warnings ((obsolete cl-next-method-p))
+ (cl-next-method-p))
+ (cl-call-next-method)))
(should (equal (cl--generic-1 4 5) '("quatre" t 4 5 nil))))
(ert-deftest cl-generic-test-12-context ()
diff --git a/test/lisp/emacs-lisp/cl-lib-tests.el b/test/lisp/emacs-lisp/cl-lib-tests.el
index a5ec62b9c42..a0facc81dbe 100644
--- a/test/lisp/emacs-lisp/cl-lib-tests.el
+++ b/test/lisp/emacs-lisp/cl-lib-tests.el
@@ -353,13 +353,6 @@
(should (= 5 (cl-fifth '(1 2 3 4 5 6))))
(should-error (cl-fifth "12345") :type 'wrong-type-argument))
-(ert-deftest cl-lib-test-fifth ()
- (should (null (cl-fifth '())))
- (should (null (cl-fifth '(1 2 3 4))))
- (should (= 5 (cl-fifth '(1 2 3 4 5))))
- (should (= 5 (cl-fifth '(1 2 3 4 5 6))))
- (should-error (cl-fifth "12345") :type 'wrong-type-argument))
-
(ert-deftest cl-lib-test-sixth ()
(should (null (cl-sixth '())))
(should (null (cl-sixth '(1 2 3 4 5))))
@@ -417,22 +410,6 @@
(should-error (cl-nth-value -1 (cl-values 2 3)) :type 'args-out-of-range)
(should (string= (cl-nth-value 0 "only lists") "only lists")))
-(ert-deftest cl-test-caaar ()
- (should (null (cl-caaar '())))
- (should (null (cl-caaar '(() (2)))))
- (should (null (cl-caaar '((() (2)) (a b)))))
- (should-error (cl-caaar '(1 2)) :type 'wrong-type-argument)
- (should-error (cl-caaar '((1 2))) :type 'wrong-type-argument)
- (should (= 1 (cl-caaar '(((1 2) (3 4))))))
- (should (null (cl-caaar '((() (3 4)))))))
-
-(ert-deftest cl-test-caadr ()
- (should (null (cl-caadr '())))
- (should (null (cl-caadr '(1))))
- (should-error (cl-caadr '(1 2)) :type 'wrong-type-argument)
- (should (= 2 (cl-caadr '(1 (2 3)))))
- (should (equal '((2) (3)) (cl-caadr '((1) (((2) (3))) (4))))))
-
(ert-deftest cl-test-ldiff ()
(let ((l '(1 2 3)))
(should (null (cl-ldiff '() '())))
@@ -574,4 +551,9 @@
(should cl-old-struct-compat-mode)
(cl-old-struct-compat-mode (if saved 1 -1))))
+(ert-deftest cl-constantly ()
+ (should (equal (mapcar (cl-constantly 3) '(a b c d))
+ '(3 3 3 3))))
+
+
;;; cl-lib-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 f4e2e46a019..13da60ec45e 100644
--- a/test/lisp/emacs-lisp/cl-macs-tests.el
+++ b/test/lisp/emacs-lisp/cl-macs-tests.el
@@ -529,7 +529,7 @@ collection clause."
(should-error
;; Use `eval' so the error is signaled when running the test rather than
;; when macroexpanding it.
- (eval '(let ((l (list 1))) (cl-symbol-macrolet ((x 1)) (setq (car l) 0)))))
+ (eval '(let ((l (list 1))) (cl-symbol-macrolet ((x 1)) (setq (car l) 0))) t))
;; Make sure `gv-synthetic-place' isn't macro-expanded before `setf' gets to
;; see its `gv-expander'.
(should (equal (let ((l '(0)))
@@ -637,17 +637,26 @@ collection clause."
(/ 1 (logand n 1))
(arith-error (len3 (cdr xs) (1+ n)))
(:success (len3 (cdr xs) (+ n k))))
- n)))
+ n))
+
+ ;; Tail calls in `cond'.
+ (len4 (xs n)
+ (cond (xs (cond (nil 'nevertrue)
+ ((len4 (cdr xs) (1+ n)))))
+ (t n))))
(should (equal (len nil 0) 0))
(should (equal (len2 nil 0) 0))
(should (equal (len3 nil 0) 0))
+ (should (equal (len4 nil 0) 0))
(should (equal (len list-42 0) 42))
(should (equal (len2 list-42 0) 42))
(should (equal (len3 list-42 0) 42))
+ (should (equal (len4 list-42 0) 42))
;; Should not bump into stack depth limits.
(should (equal (len list-42k 0) 42000))
(should (equal (len2 list-42k 0) 42000))
- (should (equal (len3 list-42k 0) 42000))))
+ (should (equal (len3 list-42k 0) 42000))
+ (should (equal (len4 list-42k 0) 42000))))
;; Check that non-recursive functions are handled more efficiently.
(should (pcase (macroexpand '(cl-labels ((f (x) (+ x 1))) (f 5)))
@@ -660,8 +669,12 @@ collection clause."
(`(function (lambda (,_ ,_) . ,_)) t))))
(ert-deftest cl-macs--progv ()
- (should (= (cl-progv '(test test) '(1 2) test) 2))
- (should (equal (cl-progv '(test1 test2) '(1 2) (list test1 test2))
+ (defvar cl-macs--test)
+ (defvar cl-macs--test1)
+ (defvar cl-macs--test2)
+ (should (= (cl-progv '(cl-macs--test cl-macs--test) '(1 2) cl-macs--test) 2))
+ (should (equal (cl-progv '(cl-macs--test1 cl-macs--test2) '(1 2)
+ (list cl-macs--test1 cl-macs--test2))
'(1 2))))
;;; cl-macs-tests.el ends here
diff --git a/test/lisp/emacs-lisp/derived-tests.el b/test/lisp/emacs-lisp/derived-tests.el
index 9c8e6c33b4c..2647b86826a 100644
--- a/test/lisp/emacs-lisp/derived-tests.el
+++ b/test/lisp/emacs-lisp/derived-tests.el
@@ -24,13 +24,13 @@
(define-derived-mode derived-tests--parent-mode prog-mode "P"
:after-hook
(let ((f (let ((x "S")) (lambda () x))))
- (insert (format "AFP=%s " (let ((x "D")) (funcall f)))))
+ (insert (format "AFP=%s " (let ((x "D")) x (funcall f)))))
(insert "PB "))
(define-derived-mode derived-tests--child-mode derived-tests--parent-mode "C"
:after-hook
(let ((f (let ((x "S")) (lambda () x))))
- (insert (format "AFC=%s " (let ((x "D")) (funcall f)))))
+ (insert (format "AFC=%s " (let ((x "D")) x (funcall f)))))
(insert "CB "))
(ert-deftest derived-tests-after-hook-lexical ()
diff --git a/test/lisp/emacs-lisp/edebug-tests.el b/test/lisp/emacs-lisp/edebug-tests.el
index 2f45050e2eb..210bf24880b 100644
--- a/test/lisp/emacs-lisp/edebug-tests.el
+++ b/test/lisp/emacs-lisp/edebug-tests.el
@@ -107,27 +107,27 @@ back to the top level.")
"Set up the environment for an Edebug test BODY, run it, and clean up."
(declare (debug (body)))
`(edebug-tests-with-default-config
- (let ((edebug-tests-failure-in-post-command nil)
- (edebug-tests-temp-file (make-temp-file "edebug-tests-" nil ".el"))
- (find-file-suppress-same-file-warnings t))
- (edebug-tests-setup-code-file edebug-tests-temp-file)
- (ert-with-message-capture
- edebug-tests-messages
- (unwind-protect
- (with-current-buffer (find-file edebug-tests-temp-file)
- (read-only-mode)
- (setq lexical-binding t)
- (eval-buffer)
- ,@body
- (when edebug-tests-failure-in-post-command
- (signal (car edebug-tests-failure-in-post-command)
- (cdr edebug-tests-failure-in-post-command))))
- (unload-feature 'edebug-test-code)
- (with-current-buffer (find-file-noselect edebug-tests-temp-file)
- (set-buffer-modified-p nil))
- (ignore-errors (kill-buffer (find-file-noselect
- edebug-tests-temp-file)))
- (ignore-errors (delete-file edebug-tests-temp-file)))))))
+ (ert-with-temp-file edebug-tests-temp-file
+ :suffix ".el"
+ (let ((edebug-tests-failure-in-post-command nil)
+ (find-file-suppress-same-file-warnings t))
+ (edebug-tests-setup-code-file edebug-tests-temp-file)
+ (ert-with-message-capture
+ edebug-tests-messages
+ (unwind-protect
+ (with-current-buffer (find-file edebug-tests-temp-file)
+ (read-only-mode)
+ (setq lexical-binding t)
+ (eval-buffer)
+ ,@body
+ (when edebug-tests-failure-in-post-command
+ (signal (car edebug-tests-failure-in-post-command)
+ (cdr edebug-tests-failure-in-post-command))))
+ (unload-feature 'edebug-test-code)
+ (with-current-buffer (find-file-noselect edebug-tests-temp-file)
+ (set-buffer-modified-p nil))
+ (ignore-errors (kill-buffer (find-file-noselect
+ edebug-tests-temp-file)))))))))
;; The following macro and its support functions implement an extension
;; to keyboard macros to allow interleaving of keyboard macro
@@ -723,7 +723,7 @@ test and possibly others should be updated."
(edebug-on-error nil)
error-message
(command-error-function (lambda (&rest args)
- (setq error-message (cl-cadar args)))))
+ (setq error-message (cadar args)))))
(edebug-tests-run-kbd-macro
"@" (edebug-tests-should-be-at "format-node" "start")
"SPC" (edebug-tests-should-be-at "format-node" "vectorp")
@@ -744,7 +744,7 @@ test and possibly others should be updated."
(edebug-on-error nil)
(error-message "")
(command-error-function (lambda (&rest args)
- (setq error-message (cl-cadar args)))))
+ (setq error-message (cadar args)))))
(edebug-tests-run-kbd-macro
"@ SPC SPC SPC SPC SPC"
(edebug-tests-should-be-at "try-flavors" "macro")
@@ -860,7 +860,8 @@ test and possibly others should be updated."
(let ((inhibit-read-only t))
(delete-region (point-min) (point-max))
(insert "`1"))
- (edebug-eval-defun nil)
+ (with-suppressed-warnings ((obsolete edebug-eval-defun))
+ (edebug-eval-defun nil))
;; `eval-defun' outputs its message to the echo area in a rather
;; funny way, so the "1" and the " (#o1, #x1, ?\C-a)" end up placed
;; there in separate pieces (via `print' rather than via `message').
@@ -870,7 +871,8 @@ test and possibly others should be updated."
(setq edebug-initial-mode 'go)
;; In Bug#23651 Edebug would hang reading `1.
- (edebug-eval-defun t)))
+ (with-suppressed-warnings ((obsolete edebug-eval-defun))
+ (edebug-eval-defun t))))
(ert-deftest edebug-tests-trivial-comma ()
"Edebug can read a trivial comma expression (Bug#23651)."
@@ -879,7 +881,8 @@ test and possibly others should be updated."
(delete-region (point-min) (point-max))
(insert ",1")
(read-only-mode)
- (should-error (edebug-eval-defun t))))
+ (with-suppressed-warnings ((obsolete edebug-eval-defun))
+ (should-error (edebug-eval-defun t)))))
(ert-deftest edebug-tests-circular-read-syntax ()
"Edebug can instrument code using circular read object syntax (Bug#23660)."
diff --git a/test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el b/test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el
index 9f9bb73133c..e881e46a2d1 100644
--- a/test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el
+++ b/test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el
@@ -22,22 +22,22 @@
;;; Commentary:
;;
-;; Test method invocation order. From the common lisp reference
-;; manual:
+;; Test method invocation order. From the Common Lisp Reference
+;; Manual:
;;
;; QUOTE:
;; - All the :before methods are called, in most-specific-first
;; order. Their values are ignored. An error is signaled if
;; call-next-method is used in a :before method.
;;
-;; - The most specific primary method is called. Inside the body of a
+;; - The most specific primary method is called. Inside the body of a
;; primary method, call-next-method may be used to call the next
-;; most specific primary method. When that method returns, the
+;; most specific primary method. When that method returns, the
;; previous primary method can execute more code, perhaps based on
-;; the returned value or values. The generic function no-next-method
+;; the returned value or values. The generic function no-next-method
;; is invoked if call-next-method is used and there are no more
-;; applicable primary methods. The function next-method-p may be
-;; used to determine whether a next method exists. If
+;; applicable primary methods. The function next-method-p may be
+;; used to determine whether a next method exists. If
;; call-next-method is not used, only the most specific primary
;; method is called.
;;
@@ -46,12 +46,14 @@
;; call-next-method is used in a :after method.
;;
;;
-;; Also test behavior of `call-next-method'. From clos.org:
+;; Also test behavior of `call-next-method'. From clos.org:
;;
;; QUOTE:
;; When call-next-method is called with no arguments, it passes the
;; current method's original arguments to the next method.
+;;; Code:
+
(require 'eieio)
(require 'ert)
@@ -83,37 +85,40 @@
(defclass eitest-B-base2 () ())
(defclass eitest-B (eitest-B-base1 eitest-B-base2) ())
-(defmethod eitest-F :BEFORE ((_p eitest-B-base1))
- (eieio-test-method-store :BEFORE 'eitest-B-base1))
-
-(defmethod eitest-F :BEFORE ((_p eitest-B-base2))
- (eieio-test-method-store :BEFORE 'eitest-B-base2))
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete call-next-method)
+ (obsolete next-method-p))
+ (defmethod eitest-F :BEFORE ((_p eitest-B-base1))
+ (eieio-test-method-store :BEFORE 'eitest-B-base1))
-(defmethod eitest-F :BEFORE ((_p eitest-B))
- (eieio-test-method-store :BEFORE 'eitest-B))
+ (defmethod eitest-F :BEFORE ((_p eitest-B-base2))
+ (eieio-test-method-store :BEFORE 'eitest-B-base2))
-(defmethod eitest-F ((_p eitest-B))
- (eieio-test-method-store :PRIMARY 'eitest-B)
- (call-next-method))
+ (defmethod eitest-F :BEFORE ((_p eitest-B))
+ (eieio-test-method-store :BEFORE 'eitest-B))
-(defmethod eitest-F ((_p eitest-B-base1))
- (eieio-test-method-store :PRIMARY 'eitest-B-base1)
- (call-next-method))
+ (defmethod eitest-F ((_p eitest-B))
+ (eieio-test-method-store :PRIMARY 'eitest-B)
+ (call-next-method))
-(defmethod eitest-F ((_p eitest-B-base2))
- (eieio-test-method-store :PRIMARY 'eitest-B-base2)
- (when (next-method-p)
+ (defmethod eitest-F ((_p eitest-B-base1))
+ (eieio-test-method-store :PRIMARY 'eitest-B-base1)
(call-next-method))
- )
-(defmethod eitest-F :AFTER ((_p eitest-B-base1))
- (eieio-test-method-store :AFTER 'eitest-B-base1))
+ (defmethod eitest-F ((_p eitest-B-base2))
+ (eieio-test-method-store :PRIMARY 'eitest-B-base2)
+ (when (next-method-p)
+ (call-next-method)))
+
+ (defmethod eitest-F :AFTER ((_p eitest-B-base1))
+ (eieio-test-method-store :AFTER 'eitest-B-base1))
-(defmethod eitest-F :AFTER ((_p eitest-B-base2))
- (eieio-test-method-store :AFTER 'eitest-B-base2))
+ (defmethod eitest-F :AFTER ((_p eitest-B-base2))
+ (eieio-test-method-store :AFTER 'eitest-B-base2))
-(defmethod eitest-F :AFTER ((_p eitest-B))
- (eieio-test-method-store :AFTER 'eitest-B))
+ (defmethod eitest-F :AFTER ((_p eitest-B))
+ (eieio-test-method-store :AFTER 'eitest-B)))
(ert-deftest eieio-test-method-order-list-3 ()
(let ((eieio-test-method-order-list nil)
@@ -136,9 +141,11 @@
;;; Test static invocation
;;
-(defmethod eitest-H :STATIC ((_class eitest-A))
- "No need to do work in here."
- 'moose)
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod eitest-H :STATIC ((_class eitest-A))
+ "No need to do work in here."
+ 'moose))
(ert-deftest eieio-test-method-order-list-4 ()
;; Both of these situations should succeed.
@@ -147,17 +154,19 @@
;;; Return value from :PRIMARY
;;
-(defmethod eitest-I :BEFORE ((_a eitest-A))
- (eieio-test-method-store :BEFORE 'eitest-A)
- ":before")
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod eitest-I :BEFORE ((_a eitest-A))
+ (eieio-test-method-store :BEFORE 'eitest-A)
+ ":before")
-(defmethod eitest-I :PRIMARY ((_a eitest-A))
- (eieio-test-method-store :PRIMARY 'eitest-A)
- ":primary")
+ (defmethod eitest-I :PRIMARY ((_a eitest-A))
+ (eieio-test-method-store :PRIMARY 'eitest-A)
+ ":primary")
-(defmethod eitest-I :AFTER ((_a eitest-A))
- (eieio-test-method-store :AFTER 'eitest-A)
- ":after")
+ (defmethod eitest-I :AFTER ((_a eitest-A))
+ (eieio-test-method-store :AFTER 'eitest-A)
+ ":after"))
(ert-deftest eieio-test-method-order-list-5 ()
(let ((eieio-test-method-order-list nil)
@@ -173,16 +182,18 @@
(defclass C-base2 () ())
(defclass C (C-base1 C-base2) ())
-;; Just use the obsolete name once, to make sure it also works.
-(defmethod constructor :STATIC ((_p C-base1) &rest _args)
- (eieio-test-method-store :STATIC 'C-base1)
- (if (next-method-p) (call-next-method))
- )
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete next-method-p)
+ (obsolete call-next-method))
+ ;; Just use the obsolete name once, to make sure it also works.
+ (defmethod constructor :STATIC ((_p C-base1) &rest _args)
+ (eieio-test-method-store :STATIC 'C-base1)
+ (if (next-method-p) (call-next-method)))
-(defmethod make-instance :STATIC ((_p C-base2) &rest _args)
- (eieio-test-method-store :STATIC 'C-base2)
- (if (next-method-p) (call-next-method))
- )
+ (defmethod make-instance :STATIC ((_p C-base2) &rest _args)
+ (eieio-test-method-store :STATIC 'C-base2)
+ (if (next-method-p) (call-next-method))))
(cl-defmethod make-instance ((_p (subclass C)) &rest _args)
(eieio-test-method-store :STATIC 'C)
@@ -213,29 +224,32 @@
(defclass D-base2 (D-base0) () :method-invocation-order :depth-first)
(defclass D (D-base1 D-base2) () :method-invocation-order :depth-first)
-(defmethod eitest-F ((_p D))
- "D"
- (eieio-test-method-store :PRIMARY 'D)
- (call-next-method))
-
-(defmethod eitest-F ((_p D-base0))
- "D-base0"
- (eieio-test-method-store :PRIMARY 'D-base0)
- ;; This should have no next
- ;; (when (next-method-p) (call-next-method))
- )
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete call-next-method)
+ (obsolete next-method-p))
+ (defmethod eitest-F ((_p D))
+ "D"
+ (eieio-test-method-store :PRIMARY 'D)
+ (call-next-method))
-(defmethod eitest-F ((_p D-base1))
- "D-base1"
- (eieio-test-method-store :PRIMARY 'D-base1)
- (call-next-method))
+ (defmethod eitest-F ((_p D-base0))
+ "D-base0"
+ (eieio-test-method-store :PRIMARY 'D-base0)
+ ;; This should have no next
+ ;; (when (next-method-p) (call-next-method))
+ )
-(defmethod eitest-F ((_p D-base2))
- "D-base2"
- (eieio-test-method-store :PRIMARY 'D-base2)
- (when (next-method-p)
+ (defmethod eitest-F ((_p D-base1))
+ "D-base1"
+ (eieio-test-method-store :PRIMARY 'D-base1)
(call-next-method))
- )
+
+ (defmethod eitest-F ((_p D-base2))
+ "D-base2"
+ (eieio-test-method-store :PRIMARY 'D-base2)
+ (when (next-method-p)
+ (call-next-method))))
(ert-deftest eieio-test-method-order-list-7 ()
(let ((eieio-test-method-order-list nil)
@@ -256,25 +270,27 @@
(defclass E-base2 (E-base0) () :method-invocation-order :breadth-first)
(defclass E (E-base1 E-base2) () :method-invocation-order :breadth-first)
-(defmethod eitest-F ((_p E))
- (eieio-test-method-store :PRIMARY 'E)
- (call-next-method))
-
-(defmethod eitest-F ((_p E-base0))
- (eieio-test-method-store :PRIMARY 'E-base0)
- ;; This should have no next
- ;; (when (next-method-p) (call-next-method))
- )
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete next-method-p)
+ (obsolete call-next-method))
+ (defmethod eitest-F ((_p E))
+ (eieio-test-method-store :PRIMARY 'E)
+ (call-next-method))
-(defmethod eitest-F ((_p E-base1))
- (eieio-test-method-store :PRIMARY 'E-base1)
- (call-next-method))
+ (defmethod eitest-F ((_p E-base0))
+ (eieio-test-method-store :PRIMARY 'E-base0)
+ ;; This should have no next
+ ;; (when (next-method-p) (call-next-method))
+ )
-(defmethod eitest-F ((_p E-base2))
- (eieio-test-method-store :PRIMARY 'E-base2)
- (when (next-method-p)
+ (defmethod eitest-F ((_p E-base1))
+ (eieio-test-method-store :PRIMARY 'E-base1)
(call-next-method))
- )
+
+ (defmethod eitest-F ((_p E-base2))
+ (eieio-test-method-store :PRIMARY 'E-base2)
+ (when (next-method-p)
+ (call-next-method))))
(ert-deftest eieio-test-method-order-list-8 ()
(let ((eieio-test-method-order-list nil)
@@ -293,24 +309,32 @@
(defclass eitest-Ja ()
())
-(defmethod initialize-instance :after ((_this eitest-Ja) &rest _slots)
- ;(message "+Ja")
- ;; FIXME: Using next-method-p in an after-method is invalid!
- (when (next-method-p)
- (call-next-method))
- ;(message "-Ja")
- )
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete next-method-p)
+ (obsolete call-next-method))
+ (defmethod initialize-instance :after ((_this eitest-Ja) &rest _slots)
+ ;;(message "+Ja")
+ ;; FIXME: Using next-method-p in an after-method is invalid!
+ (when (next-method-p)
+ (call-next-method))
+ ;;(message "-Ja")
+ ))
(defclass eitest-Jb ()
())
-(defmethod initialize-instance :after ((_this eitest-Jb) &rest _slots)
- ;(message "+Jb")
- ;; FIXME: Using next-method-p in an after-method is invalid!
- (when (next-method-p)
- (call-next-method))
- ;(message "-Jb")
- )
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete next-method-p)
+ (obsolete call-next-method))
+ (defmethod initialize-instance :after ((_this eitest-Jb) &rest _slots)
+ ;;(message "+Jb")
+ ;; FIXME: Using next-method-p in an after-method is invalid!
+ (when (next-method-p)
+ (call-next-method))
+ ;;(message "-Jb")
+ ))
(defclass eitest-Jc (eitest-Jb)
())
@@ -318,12 +342,16 @@
(defclass eitest-Jd (eitest-Jc eitest-Ja)
())
-(defmethod initialize-instance ((_this eitest-Jd) &rest _slots)
- ;(message "+Jd")
- (when (next-method-p)
- (call-next-method))
- ;(message "-Jd")
- )
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete next-method-p)
+ (obsolete call-next-method))
+ (defmethod initialize-instance ((_this eitest-Jd) &rest _slots)
+ ;;(message "+Jd")
+ (when (next-method-p)
+ (call-next-method))
+ ;;(message "-Jd")
+ ))
(ert-deftest eieio-test-method-order-list-9 ()
(should (eitest-Jd)))
@@ -343,32 +371,36 @@
(defclass CNM-2 (CNM-1-1 CNM-1-2)
())
-(defmethod CNM-M ((this CNM-0) args)
- (push (cons 'CNM-0 (copy-sequence args))
- eieio-test-call-next-method-arguments)
- (when (next-method-p)
- (call-next-method
- this (cons 'CNM-0 args))))
-
-(defmethod CNM-M ((this CNM-1-1) args)
- (push (cons 'CNM-1-1 (copy-sequence args))
- eieio-test-call-next-method-arguments)
- (when (next-method-p)
- (call-next-method
- this (cons 'CNM-1-1 args))))
-
-(defmethod CNM-M ((_this CNM-1-2) args)
- (push (cons 'CNM-1-2 (copy-sequence args))
- eieio-test-call-next-method-arguments)
- (when (next-method-p)
- (call-next-method)))
-
-(defmethod CNM-M ((this CNM-2) args)
- (push (cons 'CNM-2 (copy-sequence args))
- eieio-test-call-next-method-arguments)
- (when (next-method-p)
- (call-next-method
- this (cons 'CNM-2 args))))
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete next-method-p)
+ (obsolete call-next-method))
+ (defmethod CNM-M ((this CNM-0) args)
+ (push (cons 'CNM-0 (copy-sequence args))
+ eieio-test-call-next-method-arguments)
+ (when (next-method-p)
+ (call-next-method
+ this (cons 'CNM-0 args))))
+
+ (defmethod CNM-M ((this CNM-1-1) args)
+ (push (cons 'CNM-1-1 (copy-sequence args))
+ eieio-test-call-next-method-arguments)
+ (when (next-method-p)
+ (call-next-method
+ this (cons 'CNM-1-1 args))))
+
+ (defmethod CNM-M ((_this CNM-1-2) args)
+ (push (cons 'CNM-1-2 (copy-sequence args))
+ eieio-test-call-next-method-arguments)
+ (when (next-method-p)
+ (call-next-method)))
+
+ (defmethod CNM-M ((this CNM-2) args)
+ (push (cons 'CNM-2 (copy-sequence args))
+ eieio-test-call-next-method-arguments)
+ (when (next-method-p)
+ (call-next-method
+ this (cons 'CNM-2 args)))))
(ert-deftest eieio-test-method-order-list-10 ()
(let ((eieio-test-call-next-method-arguments nil))
@@ -403,3 +435,5 @@
(should (equal (eieio-test--1 (make-instance 'CNM-2) 5)
'("CNM-1-1" "CNM-1-2" "CNM-0" 7 5)))
(should (equal (eieio-test--1 'CNM-2 6) '("subclass CNM-1-2" CNM-2 6))))
+
+;;; eieio-test-methodinvoke.el ends here
diff --git a/test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el b/test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el
index ddbef02c35a..fd044ff3734 100644
--- a/test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el
+++ b/test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el
@@ -165,9 +165,9 @@ Assume SLOTVALUE is a symbol of some sort."
((slot1 :initarg :slot1
:initform 1)
(slot2 :initform 2))
- "Class for testing persistent saving of an object that isn't
-persistent. This class is instead used as a slot value in a
-persistent class.")
+ "Class for testing persistent saving of an object that isn't persistent.
+This class is instead used as a slot value in a persistent
+class.")
(defclass persistent-with-objs-slot (eieio-persistent)
((pnp :initarg :pnp
diff --git a/test/lisp/emacs-lisp/eieio-tests/eieio-tests.el b/test/lisp/emacs-lisp/eieio-tests/eieio-tests.el
index 3ec42343443..599d7900c30 100644
--- a/test/lisp/emacs-lisp/eieio-tests/eieio-tests.el
+++ b/test/lisp/emacs-lisp/eieio-tests/eieio-tests.el
@@ -48,13 +48,13 @@
:type (or null class-a)
:documentation "Test self referencing types.")
)
- "Class A")
+ "Class A.")
(defclass class-b ()
((land :initform "Sc"
:type string
:documentation "Detail about land."))
- "Class B")
+ "Class B.")
(defclass class-ab (class-a class-b)
((amphibian :initform "frog"
@@ -160,30 +160,33 @@
;; error
(should-error (abstract-class)))
-(defgeneric generic1 () "First generic function")
+(with-suppressed-warnings ((obsolete defgeneric))
+ (defgeneric generic1 () "First generic function."))
(ert-deftest eieio-test-03-generics ()
- (defun anormalfunction () "A plain function for error testing." nil)
- (should-error
- (progn
- (defgeneric anormalfunction ()
- "Attempt to turn it into a generic.")))
-
- ;; Check that generic-p works
- (should (generic-p 'generic1))
-
- (defmethod generic1 ((c class-a))
- "Method on generic1."
- 'monkey)
-
- (defmethod generic1 (not-an-object)
- "Method generic1 that can take a non-object."
- not-an-object)
-
- (let ((ans-obj (generic1 (class-a)))
- (ans-num (generic1 666)))
- (should (eq ans-obj 'monkey))
- (should (eq ans-num 666))))
+ (with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defun anormalfunction () "A plain function for error testing." nil)
+ (should-error
+ (progn
+ (defgeneric anormalfunction ()
+ "Attempt to turn it into a generic.")))
+
+ ;; Check that generic-p works
+ (should (generic-p 'generic1))
+
+ (defmethod generic1 ((_c class-a))
+ "Method on generic1."
+ 'monkey)
+
+ (defmethod generic1 (not-an-object)
+ "Method generic1 that can take a non-object."
+ not-an-object)
+
+ (let ((ans-obj (generic1 (class-a)))
+ (ans-num (generic1 666)))
+ (should (eq ans-obj 'monkey))
+ (should (eq ans-num 666)))))
(defclass static-method-class ()
((some-slot :initform nil
@@ -191,11 +194,13 @@
:documentation "A slot."))
:documentation "A class used for testing static methods.")
-(defmethod static-method-class-method :STATIC ((c static-method-class) value)
- "Test static methods.
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod static-method-class-method :STATIC ((c static-method-class) value)
+ "Test static methods.
Argument C is the class bound to this static method."
- (if (eieio-object-p c) (setq c (eieio-object-class c)))
- (oset-default c some-slot value))
+ (if (eieio-object-p c) (setq c (eieio-object-class c)))
+ (oset-default c some-slot value)))
(ert-deftest eieio-test-04-static-method ()
;; Call static method on a class and see if it worked
@@ -209,11 +214,13 @@ Argument C is the class bound to this static method."
()
"A second class after the previous for static methods.")
- (defmethod static-method-class-method :STATIC ((c static-method-class-2) value)
- "Test static methods.
+ (with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod static-method-class-method :STATIC ((c static-method-class-2) value)
+ "Test static methods.
Argument C is the class bound to this static method."
- (if (eieio-object-p c) (setq c (eieio-object-class c)))
- (oset-default c some-slot (intern (concat "moose-" (symbol-name value)))))
+ (if (eieio-object-p c) (setq c (eieio-object-class c)))
+ (oset-default c some-slot (intern (concat "moose-" (symbol-name value))))))
(static-method-class-method 'static-method-class-2 'class)
(should (eq (oref-default 'static-method-class-2 some-slot) 'moose-class))
@@ -240,64 +247,71 @@ Argument C is the class bound to this static method."
(should (make-instance 'class-a :water 'cho))
(should (make-instance 'class-b)))
-(defmethod class-cn ((a class-a))
- "Try calling `call-next-method' when there isn't one.
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod class-cn ((_a class-a))
+ "Try calling `call-next-method' when there isn't one.
Argument A is object of type symbol `class-a'."
- (call-next-method))
+ (with-suppressed-warnings ((obsolete call-next-method))
+ (call-next-method)))
-(defmethod no-next-method ((a class-a) &rest args)
- "Override signal throwing for variable `class-a'.
+ (defmethod no-next-method ((_a class-a) &rest _args)
+ "Override signal throwing for variable `class-a'.
Argument A is the object of class variable `class-a'."
- 'moose)
+ 'moose))
(ert-deftest eieio-test-08-call-next-method ()
;; Play with call-next-method
(should (eq (class-cn eitest-ab) 'moose)))
-(defmethod no-applicable-method ((b class-b) method &rest args)
- "No need.
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod no-applicable-method ((_b class-b) _method &rest _args)
+ "No need.
Argument B is for booger.
METHOD is the method that was attempting to be called."
- 'moose)
+ 'moose))
(ert-deftest eieio-test-09-no-applicable-method ()
;; Non-existing methods.
(should (eq (class-cn eitest-b) 'moose)))
-(defmethod class-fun ((a class-a))
- "Fun with class A."
- 'moose)
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod class-fun ((_a class-a))
+ "Fun with class A."
+ 'moose)
-(defmethod class-fun ((b class-b))
- "Fun with class B."
- (error "Class B fun should not be called")
- )
+ (defmethod class-fun ((_b class-b))
+ "Fun with class B."
+ (error "Class B fun should not be called"))
-(defmethod class-fun-foo ((b class-b))
- "Foo Fun with class B."
- 'moose)
+ (defmethod class-fun-foo ((_b class-b))
+ "Foo Fun with class B."
+ 'moose)
-(defmethod class-fun2 ((a class-a))
- "More fun with class A."
- 'moose)
+ (defmethod class-fun2 ((_a class-a))
+ "More fun with class A."
+ 'moose)
-(defmethod class-fun2 ((b class-b))
- "More fun with class B."
- (error "Class B fun2 should not be called")
- )
+ (defmethod class-fun2 ((_b class-b))
+ "More fun with class B."
+ (error "Class B fun2 should not be called"))
-(defmethod class-fun2 ((ab class-ab))
- "More fun with class AB."
- (call-next-method))
+ (defmethod class-fun2 ((_ab class-ab))
+ "More fun with class AB."
+ (with-suppressed-warnings ((obsolete call-next-method))
+ (call-next-method)))
-;; How about if B is the only slot?
-(defmethod class-fun3 ((b class-b))
- "Even More fun with class B."
- 'moose)
+ ;; How about if B is the only slot?
+ (defmethod class-fun3 ((_b class-b))
+ "Even More fun with class B."
+ 'moose)
-(defmethod class-fun3 ((ab class-ab))
- "Even More fun with class AB."
- (call-next-method))
+ (defmethod class-fun3 ((_ab class-ab))
+ "Even More fun with class AB."
+ (with-suppressed-warnings ((obsolete call-next-method))
+ (call-next-method))))
(ert-deftest eieio-test-10-multiple-inheritance ()
;; play with methods and mi
@@ -314,20 +328,22 @@ METHOD is the method that was attempting to be called."
(defvar class-fun-value-seq '())
-(defmethod class-fun-value :BEFORE ((a class-a))
- "Return `before', and push `before' in `class-fun-value-seq'."
- (push 'before class-fun-value-seq)
- 'before)
-
-(defmethod class-fun-value :PRIMARY ((a class-a))
- "Return `primary', and push `primary' in `class-fun-value-seq'."
- (push 'primary class-fun-value-seq)
- 'primary)
-
-(defmethod class-fun-value :AFTER ((a class-a))
- "Return `after', and push `after' in `class-fun-value-seq'."
- (push 'after class-fun-value-seq)
- 'after)
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod class-fun-value :BEFORE ((_a class-a))
+ "Return `before', and push `before' in `class-fun-value-seq'."
+ (push 'before class-fun-value-seq)
+ 'before)
+
+ (defmethod class-fun-value :PRIMARY ((_a class-a))
+ "Return `primary', and push `primary' in `class-fun-value-seq'."
+ (push 'primary class-fun-value-seq)
+ 'primary)
+
+ (defmethod class-fun-value :AFTER ((_a class-a))
+ "Return `after', and push `after' in `class-fun-value-seq'."
+ (push 'after class-fun-value-seq)
+ 'after))
(ert-deftest eieio-test-12-generic-function-call ()
;; Test value of a generic function call
@@ -343,20 +359,23 @@ METHOD is the method that was attempting to be called."
;;
(ert-deftest eieio-test-13-init-methods ()
- (defmethod initialize-instance ((a class-a) &rest slots)
- "Initialize the slots of class-a."
- (call-next-method)
- (if (/= (oref a test-tag) 1)
- (error "shared-initialize test failed."))
- (oset a test-tag 2))
-
- (defmethod shared-initialize ((a class-a) &rest slots)
- "Shared initialize method for class-a."
- (call-next-method)
- (oset a test-tag 1))
-
- (let ((ca (class-a)))
- (should (= (oref ca test-tag) 2))))
+ (with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete call-next-method))
+ (defmethod initialize-instance ((a class-a) &rest _slots)
+ "Initialize the slots of class-a."
+ (call-next-method)
+ (if (/= (oref a test-tag) 1)
+ (error "shared-initialize test failed."))
+ (oset a test-tag 2))
+
+ (defmethod shared-initialize ((a class-a) &rest _slots)
+ "Shared initialize method for class-a."
+ (call-next-method)
+ (oset a test-tag 1))
+
+ (let ((ca (class-a)))
+ (should (= (oref ca test-tag) 2)))))
;;; Perform slot testing
@@ -368,10 +387,11 @@ METHOD is the method that was attempting to be called."
(should (oref eitest-ab amphibian)))
(ert-deftest eieio-test-15-slot-missing ()
-
- (defmethod slot-missing ((ab class-ab) &rest foo)
- "If a slot in AB is unbound, return something cool. FOO."
- 'moose)
+ (with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod slot-missing ((_ab class-ab) &rest _foo)
+ "If a slot in AB is unbound, return something cool. FOO."
+ 'moose))
(should (eq (oref eitest-ab ooga-booga) 'moose))
(should-error (oref eitest-a ooga-booga) :type 'invalid-slot-name))
@@ -391,17 +411,20 @@ METHOD is the method that was attempting to be called."
(defclass virtual-slot-class ()
((base-value :initarg :base-value))
"Class has real slot :base-value and simulated slot :derived-value.")
-(defmethod slot-missing ((vsc virtual-slot-class)
- slot-name operation &optional new-value)
- "Simulate virtual slot derived-value."
- (cond
- ((or (eq slot-name :derived-value)
- (eq slot-name 'derived-value))
- (with-slots (base-value) vsc
- (if (eq operation 'oref)
- (+ base-value 1)
- (setq base-value (- new-value 1)))))
- (t (call-next-method))))
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod slot-missing ((vsc virtual-slot-class)
+ slot-name operation &optional new-value)
+ "Simulate virtual slot derived-value."
+ (cond
+ ((or (eq slot-name :derived-value)
+ (eq slot-name 'derived-value))
+ (with-slots (base-value) vsc
+ (if (eq operation 'oref)
+ (+ base-value 1)
+ (setq base-value (- new-value 1)))))
+ (t (with-suppressed-warnings ((obsolete call-next-method))
+ (call-next-method))))))
(ert-deftest eieio-test-17-virtual-slot ()
(setq eitest-vsca (virtual-slot-class :base-value 1))
@@ -424,35 +447,37 @@ METHOD is the method that was attempting to be called."
(should (= (oref eitest-vscb :derived-value) 5)))
(ert-deftest eieio-test-18-slot-unbound ()
-
- (defmethod slot-unbound ((a class-a) &rest foo)
- "If a slot in A is unbound, ignore FOO."
- 'moose)
-
- (should (eq (oref eitest-a water) 'moose))
-
- ;; Check if oset of unbound works
- (oset eitest-a water 'moose)
- (should (eq (oref eitest-a water) 'moose))
-
- ;; oref/oref-default comparison
- (should-not (eq (oref eitest-a water) (oref-default eitest-a water)))
-
- ;; oset-default -> oref/oref-default comparison
- (oset-default (eieio-object-class eitest-a) water 'moose)
- (should (eq (oref eitest-a water) (oref-default eitest-a water)))
-
- ;; After setting 'water to 'moose, make sure a new object has
- ;; the right stuff.
- (oset-default (eieio-object-class eitest-a) water 'penguin)
- (should (eq (oref (class-a) water) 'penguin))
-
- ;; Revert the above
- (defmethod slot-unbound ((a class-a) &rest foo)
- "If a slot in A is unbound, ignore FOO."
- ;; Disable the old slot-unbound so we can run this test
- ;; more than once
- (call-next-method)))
+ (with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod slot-unbound ((_a class-a) &rest _foo)
+ "If a slot in A is unbound, ignore FOO."
+ 'moose)
+
+ (should (eq (oref eitest-a water) 'moose))
+
+ ;; Check if oset of unbound works
+ (oset eitest-a water 'moose)
+ (should (eq (oref eitest-a water) 'moose))
+
+ ;; oref/oref-default comparison
+ (should-not (eq (oref eitest-a water) (oref-default eitest-a water)))
+
+ ;; oset-default -> oref/oref-default comparison
+ (oset-default (eieio-object-class eitest-a) water 'moose)
+ (should (eq (oref eitest-a water) (oref-default eitest-a water)))
+
+ ;; After setting 'water to 'moose, make sure a new object has
+ ;; the right stuff.
+ (oset-default (eieio-object-class eitest-a) water 'penguin)
+ (should (eq (oref (class-a) water) 'penguin))
+
+ ;; Revert the above
+ (defmethod slot-unbound ((_a class-a) &rest _foo)
+ "If a slot in A is unbound, ignore FOO."
+ ;; Disable the old slot-unbound so we can run this test
+ ;; more than once
+ (with-suppressed-warnings ((obsolete call-next-method))
+ (call-next-method)))))
(ert-deftest eieio-test-19-slot-type-checking ()
;; Slot type checking
@@ -617,12 +642,14 @@ METHOD is the method that was attempting to be called."
()
"Protection testing baseclass.")
-(defmethod prot0-slot-2 ((s2 prot-0))
- "Try to access slot-2 from this class which doesn't have it.
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod prot0-slot-2 ((s2 prot-0))
+ "Try to access slot-2 from this class which doesn't have it.
The object S2 passed in will be of class prot-1, which does have
the slot. This could be allowed, and currently is in EIEIO.
Needed by the eieio persistent base class."
- (oref s2 slot-2))
+ (oref s2 slot-2)))
(defclass prot-1 (prot-0)
((slot-1 :initarg :slot-1
@@ -640,26 +667,28 @@ Needed by the eieio persistent base class."
nil
"A class for testing the :protection option.")
-(defmethod prot1-slot-2 ((s2 prot-1))
- "Try to access slot-2 in S2."
- (oref s2 slot-2))
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod prot1-slot-2 ((s2 prot-1))
+ "Try to access slot-2 in S2."
+ (oref s2 slot-2))
-(defmethod prot1-slot-2 ((s2 prot-2))
- "Try to access slot-2 in S2."
- (oref s2 slot-2))
+ (defmethod prot1-slot-2 ((s2 prot-2))
+ "Try to access slot-2 in S2."
+ (oref s2 slot-2))
-(defmethod prot1-slot-3-only ((s2 prot-1))
- "Try to access slot-3 in S2.
+ (defmethod prot1-slot-3-only ((s2 prot-1))
+ "Try to access slot-3 in S2.
Do not override for `prot-2'."
- (oref s2 slot-3))
+ (oref s2 slot-3))
-(defmethod prot1-slot-3 ((s2 prot-1))
- "Try to access slot-3 in S2."
- (oref s2 slot-3))
+ (defmethod prot1-slot-3 ((s2 prot-1))
+ "Try to access slot-3 in S2."
+ (oref s2 slot-3))
-(defmethod prot1-slot-3 ((s2 prot-2))
- "Try to access slot-3 in S2."
- (oref s2 slot-3))
+ (defmethod prot1-slot-3 ((s2 prot-2))
+ "Try to access slot-3 in S2."
+ (oref s2 slot-3)))
(defvar eitest-p1 nil)
(defvar eitest-p2 nil)
@@ -901,12 +930,12 @@ Subclasses to override slot attributes.")
(defclass opt-test1 ()
()
- "Abstract base class"
+ "Abstract base class."
:abstract t)
(defclass opt-test2 (opt-test1)
()
- "Instantiable child")
+ "Instantiable child.")
(ert-deftest eieio-test-36-build-class-alist ()
(should (= (length (eieio-build-class-alist 'opt-test1 nil)) 2))
@@ -914,8 +943,10 @@ Subclasses to override slot attributes.")
(defclass eieio--testing () ())
-(defmethod constructor :static ((_x eieio--testing) newname &rest _args)
- (list newname 2))
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod constructor :static ((_x eieio--testing) newname &rest _args)
+ (list newname 2)))
(ert-deftest eieio-test-37-obsolete-name-in-constructor ()
;; FIXME repeated intermittent failures on hydra and elsewhere (bug#24503).
@@ -969,6 +1000,21 @@ Subclasses to override slot attributes.")
(should (eieio-instance-inheritor-slot-boundp C :b))
(should-not (eieio-instance-inheritor-slot-boundp C :c))))
+;;;; Interaction with defstruct
+
+(cl-defstruct eieio-test--struct a b (c nil :read-only t))
+
+(ert-deftest eieio-test-defstruct-slot-value ()
+ (let ((x (make-eieio-test--struct :a 'A :b 'B :c 'C)))
+ (should (eq (eieio-test--struct-a x)
+ (slot-value x 'a)))
+ (should (eq (eieio-test--struct-b x)
+ (slot-value x 'b)))
+ (should (eq (eieio-test--struct-c x)
+ (slot-value x 'c)))
+ (setf (slot-value x 'a) 1)
+ (should (eq (eieio-test--struct-a x) 1))
+ (should-error (setf (slot-value x 'c) 3) :type 'eieio-read-only)))
(provide 'eieio-tests)
diff --git a/test/lisp/emacs-lisp/ert-tests.el b/test/lisp/emacs-lisp/ert-tests.el
index 5c9696105e9..1a8c9bf4f08 100644
--- a/test/lisp/emacs-lisp/ert-tests.el
+++ b/test/lisp/emacs-lisp/ert-tests.el
@@ -39,10 +39,11 @@
(defun ert-self-test ()
"Run ERT's self-tests and make sure they actually ran."
(let ((window-configuration (current-window-configuration)))
- (let ((ert--test-body-was-run nil))
+ (let ((ert--test-body-was-run nil)
+ (ert--output-buffer-name " *ert self-tests*"))
;; The buffer name chosen here should not compete with the default
;; results buffer name for completion in `switch-to-buffer'.
- (let ((stats (ert-run-tests-interactively "^ert-" " *ert self-tests*")))
+ (let ((stats (ert-run-tests-interactively "^ert-")))
(cl-assert ert--test-body-was-run)
(if (zerop (ert-stats-completed-unexpected stats))
;; Hide results window only when everything went well.
@@ -519,17 +520,18 @@ This macro is used to test if macroexpansion in `should' works."
:body (lambda () (ert-skip
"skip message")))))
(let ((ert-debug-on-error nil))
- (let* ((buffer-name (generate-new-buffer-name " *ert-test-run-tests*"))
- (messages nil)
- (mock-message-fn
- (lambda (format-string &rest args)
- (push (apply #'format format-string args) messages))))
+ (cl-letf* ((buffer-name (generate-new-buffer-name
+ " *ert-test-run-tests*"))
+ (ert--output-buffer-name buffer-name)
+ (messages nil)
+ ((symbol-function 'message)
+ (lambda (format-string &rest args)
+ (push (apply #'format format-string args) messages))))
(save-window-excursion
(unwind-protect
(let ((case-fold-search nil))
(ert-run-tests-interactively
- `(member ,passing-test ,failing-test, skipped-test) buffer-name
- mock-message-fn)
+ `(member ,passing-test ,failing-test, skipped-test))
(should (equal messages `(,(concat
"Ran 3 tests, 1 results were "
"as expected, 1 unexpected, "
@@ -551,6 +553,68 @@ This macro is used to test if macroexpansion in `should' works."
(when (get-buffer buffer-name)
(kill-buffer buffer-name))))))))
+(ert-deftest ert-test-run-tests-batch ()
+ (let* ((complex-list '((:1 (:2 (:3 (:4 (:5 (:6 "abc"))))))))
+ (long-list (make-list 11 1))
+ (failing-test-1
+ (make-ert-test :name 'failing-test-1
+ :body (lambda () (should (equal complex-list 1)))))
+ (failing-test-2
+ (make-ert-test :name 'failing-test-2
+ :body (lambda () (should (equal long-list 1))))))
+ (let ((ert-debug-on-error nil)
+ messages)
+ (cl-letf* (((symbol-function 'message)
+ (lambda (format-string &rest args)
+ (push (apply #'format format-string args) messages))))
+ (save-window-excursion
+ (unwind-protect
+ (let ((case-fold-search nil)
+ (ert-batch-backtrace-right-margin nil)
+ (ert-batch-print-level 10)
+ (ert-batch-print-length 11))
+ (ert-run-tests-batch
+ `(member ,failing-test-1 ,failing-test-2))))))
+ (let ((long-text "(different-types[ \t\n]+(1 1 1 1 1 1 1 1 1 1 1)[ \t\n]+1)))[ \t\n]*$")
+ (complex-text "(different-types[ \t\n]+((:1[ \t\n]+(:2[ \t\n]+(:3[ \t\n]+(:4[ \t\n]+(:5[ \t\n]+(:6[ \t\n]+\"abc\")))))))[ \t\n]+1)))[ \t\n]*$")
+ found-long
+ found-complex)
+ (cl-loop for msg in (reverse messages)
+ do
+ (unless found-long
+ (setq found-long (string-match long-text msg)))
+ (unless found-complex
+ (setq found-complex (string-match complex-text msg))))
+ (should found-long)
+ (should found-complex)))))
+
+(ert-deftest ert-test-run-tests-batch-expensive ()
+ (let* ((complex-list '((:1 (:2 (:3 (:4 (:5 (:6 "abc"))))))))
+ (failing-test-1
+ (make-ert-test :name 'failing-test-1
+ :body (lambda () (should (equal complex-list 1))))))
+ (let ((ert-debug-on-error nil)
+ messages)
+ (cl-letf* (((symbol-function 'message)
+ (lambda (format-string &rest args)
+ (push (apply #'format format-string args) messages))))
+ (save-window-excursion
+ (unwind-protect
+ (let ((case-fold-search nil)
+ (ert-batch-backtrace-right-margin nil)
+ (ert-batch-backtrace-line-length nil)
+ (ert-batch-print-level 6)
+ (ert-batch-print-length 11))
+ (ert-run-tests-batch
+ `(member ,failing-test-1))))))
+ (let ((frame "ert-fail(((should (equal complex-list 1)) :form (equal ((:1 (:2 (:3 (:4 (:5 (:6 \"abc\"))))))) 1) :value nil :explanation (different-types ((:1 (:2 (:3 (:4 (:5 (:6 \"abc\"))))))) 1)))")
+ found-frame)
+ (cl-loop for msg in (reverse messages)
+ do
+ (unless found-frame
+ (setq found-frame (cl-search frame msg :test 'equal))))
+ (should found-frame)))))
+
(ert-deftest ert-test-special-operator-p ()
(should (ert--special-operator-p 'if))
(should-not (ert--special-operator-p 'car))
@@ -695,49 +759,40 @@ This macro is used to test if macroexpansion in `should' works."
(should (equal (ert--abbreviate-string "bar" 0 t) "")))
(ert-deftest ert-test-explain-equal-string-properties ()
- (should
- (equal (ert--explain-equal-including-properties #("foo" 0 1 (a b))
- "foo")
- '(char 0 "f"
- (different-properties-for-key a (different-atoms b nil))
- context-before ""
- context-after "oo")))
- (should (equal (ert--explain-equal-including-properties
+ (should-not (ert--explain-equal-including-properties-rec "foo" "foo"))
+ (should-not (ert--explain-equal-including-properties-rec
+ #("foo" 0 3 (a b))
+ (propertize "foo" 'a 'b)))
+ (should-not (ert--explain-equal-including-properties-rec
+ #("foo" 0 3 (a b c d))
+ (propertize "foo" 'a 'b 'c 'd)))
+ (should-not (ert--explain-equal-including-properties-rec
+ #("foo" 0 3 (a (t)))
+ (propertize "foo" 'a (list t))))
+
+ (should (equal (ert--explain-equal-including-properties-rec
+ #("foo" 0 3 (a b c e))
+ (propertize "foo" 'a 'b 'c 'd))
+ '(char 0 "f" (different-properties-for-key c (different-atoms e d))
+ context-before ""
+ context-after "oo")))
+ (should (equal (ert--explain-equal-including-properties-rec
+ #("foo" 0 1 (a b))
+ "foo")
+ '(char 0 "f"
+ (different-properties-for-key a (different-atoms b nil))
+ context-before ""
+ context-after "oo")))
+ (should (equal (ert--explain-equal-including-properties-rec
#("foo" 1 3 (a b))
#("goo" 0 1 (c d)))
'(array-elt 0 (different-atoms (?f "#x66" "?f")
(?g "#x67" "?g")))))
- (should
- (equal (ert--explain-equal-including-properties
- #("foo" 0 1 (a b c d) 1 3 (a b))
- #("foo" 0 1 (c d a b) 1 2 (a foo)))
- '(char 1 "o" (different-properties-for-key a (different-atoms b foo))
- context-before "f" context-after "o"))))
-
-(ert-deftest ert-test-equal-including-properties ()
- (should (equal-including-properties "foo" "foo"))
- (should (ert-equal-including-properties "foo" "foo"))
-
- (should (equal-including-properties #("foo" 0 3 (a b))
- (propertize "foo" 'a 'b)))
- (should (ert-equal-including-properties #("foo" 0 3 (a b))
- (propertize "foo" 'a 'b)))
-
- (should (equal-including-properties #("foo" 0 3 (a b c d))
- (propertize "foo" 'a 'b 'c 'd)))
- (should (ert-equal-including-properties #("foo" 0 3 (a b c d))
- (propertize "foo" 'a 'b 'c 'd)))
-
- (should-not (equal-including-properties #("foo" 0 3 (a b c e))
- (propertize "foo" 'a 'b 'c 'd)))
- (should-not (ert-equal-including-properties #("foo" 0 3 (a b c e))
- (propertize "foo" 'a 'b 'c 'd)))
-
- ;; This is bug 6581.
- (should-not (equal-including-properties #("foo" 0 3 (a (t)))
- (propertize "foo" 'a (list t))))
- (should (ert-equal-including-properties #("foo" 0 3 (a (t)))
- (propertize "foo" 'a (list t)))))
+ (should (equal (ert--explain-equal-including-properties-rec
+ #("foo" 0 1 (a b c d) 1 3 (a b))
+ #("foo" 0 1 (c d a b) 1 2 (a foo)))
+ '(char 1 "o" (different-properties-for-key a (different-atoms b foo))
+ context-before "f" context-after "o"))))
(ert-deftest ert-test-stats-set-test-and-result ()
(let* ((test-1 (make-ert-test :name 'test-1
@@ -816,6 +871,10 @@ This macro is used to test if macroexpansion in `should' works."
(should (equal (ert-test-failed-condition result)
'(ert-test-failed "Boo")))))
+(ert-deftest ert-test-deftest-lexical-binding-t ()
+ "Check that `lexical-binding' in `ert-deftest' has the file value."
+ (should (equal lexical-binding t)))
+
(provide 'ert-tests)
diff --git a/test/lisp/emacs-lisp/ert-x-tests.el b/test/lisp/emacs-lisp/ert-x-tests.el
index 9f40a18d343..7106b7abc0c 100644
--- a/test/lisp/emacs-lisp/ert-x-tests.el
+++ b/test/lisp/emacs-lisp/ert-x-tests.el
@@ -90,10 +90,10 @@
"foo baz")))
(ert-deftest ert-propertized-string ()
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(ert-propertized-string "a" '(a b) "b" '(c t) "cd")
#("abcd" 1 2 (a b) 2 4 (c t))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(ert-propertized-string "foo " '(face italic) "bar" " baz" nil
" quux")
#("foo bar baz quux" 4 11 (face italic)))))
@@ -103,23 +103,27 @@
(ert-deftest ert-test-run-tests-interactively-2 ()
:tags '(:causes-redisplay)
- (let* ((passing-test (make-ert-test :name 'passing-test
- :body (lambda () (ert-pass))))
- (failing-test (make-ert-test :name 'failing-test
- :body (lambda ()
- (ert-info ((propertize "foo\nbar"
- 'a 'b))
- (ert-fail
- "failure message")))))
- (skipped-test (make-ert-test :name 'skipped-test
- :body (lambda () (ert-skip
- "skip message"))))
- (ert-debug-on-error nil)
- (buffer-name (generate-new-buffer-name "*ert-test-run-tests*"))
- (messages nil)
- (mock-message-fn
- (lambda (format-string &rest args)
- (push (apply #'format format-string args) messages))))
+ (cl-letf* ((passing-test (make-ert-test
+ :name 'passing-test
+ :body (lambda () (ert-pass))))
+ (failing-test (make-ert-test
+ :name 'failing-test
+ :body (lambda ()
+ (ert-info ((propertize "foo\nbar"
+ 'a 'b))
+ (ert-fail
+ "failure message")))))
+ (skipped-test (make-ert-test
+ :name 'skipped-test
+ :body (lambda () (ert-skip
+ "skip message"))))
+ (ert-debug-on-error nil)
+ (messages nil)
+ (buffer-name (generate-new-buffer-name "*ert-test-run-tests*"))
+ ((symbol-function 'message)
+ (lambda (format-string &rest args)
+ (push (apply #'format format-string args) messages)))
+ (ert--output-buffer-name buffer-name))
(cl-flet ((expected-string (with-font-lock-p)
(ert-propertized-string
"Selector: (member <passing-test> <failing-test> "
@@ -152,21 +156,19 @@
"failing-test"
nil "\n Info: " '(a b) "foo\n"
nil " " '(a b) "bar"
- nil "\n (ert-test-failed \"failure message\")\n\n\n"
- )))
+ nil "\n (ert-test-failed \"failure message\")\n\n\n")))
(save-window-excursion
(unwind-protect
(let ((case-fold-search nil))
(ert-run-tests-interactively
- `(member ,passing-test ,failing-test ,skipped-test) buffer-name
- mock-message-fn)
+ `(member ,passing-test ,failing-test ,skipped-test))
(should (equal messages `(,(concat
"Ran 3 tests, 1 results were "
"as expected, 1 unexpected, "
"1 skipped"))))
(with-current-buffer buffer-name
(font-lock-mode 0)
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(ert-filter-string (buffer-string)
'("Started at:\\(.*\\)$" 1)
'("Finished at:\\(.*\\)$" 1))
@@ -175,7 +177,7 @@
;; pretend we are.
(let ((noninteractive nil))
(font-lock-mode 1))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(ert-filter-string (buffer-string)
'("Started at:\\(.*\\)$" 1)
'("Finished at:\\(.*\\)$" 1))
@@ -271,6 +273,62 @@ desired effect."
(cl-loop for x in '(0 1 2 3 4 t) do
(should (equal (c x) (lisp x))))))
+(ert-deftest ert-x-tests--with-temp-file-generate-suffix ()
+ (should (equal (ert--with-temp-file-generate-suffix "foo.el") "-foo"))
+ (should (equal (ert--with-temp-file-generate-suffix "foo-test.el") "-foo"))
+ (should (equal (ert--with-temp-file-generate-suffix "foo-tests.el") "-foo"))
+ (should (equal (ert--with-temp-file-generate-suffix "foo-bar-baz.el")
+ "-foo-bar-baz"))
+ (should (equal (ert--with-temp-file-generate-suffix "/foo/bar/baz.el")
+ "-baz")))
+
+(ert-deftest ert-x-tests-with-temp-file ()
+ (let (saved)
+ (ert-with-temp-file fil
+ (setq saved fil)
+ (should (file-exists-p fil))
+ (should (file-regular-p fil)))
+ (should-not (file-exists-p saved))))
+
+(ert-deftest ert-x-tests-with-temp-file/handle-error ()
+ (let (saved)
+ (ignore-errors
+ (ert-with-temp-file fil
+ (setq saved fil)
+ (error "foo")))
+ (should-not (file-exists-p saved))))
+
+(ert-deftest ert-x-tests-with-temp-file/prefix-and-suffix-kwarg ()
+ (ert-with-temp-file fil
+ :prefix "foo"
+ :suffix "bar"
+ (should (string-match "foo.*bar" fil))))
+
+(ert-deftest ert-x-tests-with-temp-file/text-kwarg ()
+ (ert-with-temp-file fil
+ :text "foobar3"
+ (let ((buf (find-file-noselect fil)))
+ (unwind-protect
+ (with-current-buffer buf
+ (should (equal (buffer-string) "foobar3")))
+ (kill-buffer buf)))))
+
+(ert-deftest ert-x-tests-with-temp-file/unknown-kwarg-signals-error ()
+ (should-error
+ (ert-with-temp-file fil :foo "foo" nil)))
+
+(ert-deftest ert-x-tests-with-temp-directory ()
+ (let (saved)
+ (ert-with-temp-directory dir
+ (setq saved dir)
+ (should (file-exists-p dir))
+ (should (file-directory-p dir))
+ (should (equal dir (file-name-as-directory dir))))
+ (should-not (file-exists-p saved))))
+
+(ert-deftest ert-x-tests-with-temp-directory/text-signals-error ()
+ (should-error
+ (ert-with-temp-directory dir :text "foo" nil)))
(provide 'ert-x-tests)
diff --git a/test/lisp/emacs-lisp/faceup-resources/faceup-test-this-file-directory.el b/test/lisp/emacs-lisp/faceup-resources/faceup-test-this-file-directory.el
index 3303e7b178d..9fe5fe9218d 100644
--- a/test/lisp/emacs-lisp/faceup-resources/faceup-test-this-file-directory.el
+++ b/test/lisp/emacs-lisp/faceup-resources/faceup-test-this-file-directory.el
@@ -22,7 +22,7 @@
;;; Commentary:
-;; Support file for `faceup-test-basics.el'. This file is used to test
+;; Support file for `faceup-test-basics.el'. This file is used to test
;; `faceup-this-file-directory' in various contexts.
;;; Code:
diff --git a/test/lisp/emacs-lisp/find-func-tests.el b/test/lisp/emacs-lisp/find-func-tests.el
index 28a9a7ecda3..987e4047d35 100644
--- a/test/lisp/emacs-lisp/find-func-tests.el
+++ b/test/lisp/emacs-lisp/find-func-tests.el
@@ -26,7 +26,7 @@
;;; Code:
-(require 'ert-x) ;For `ert-run-keys'.
+(require 'ert-x) ;For `ert-simulate-keys'.
(require 'find-func)
(ert-deftest find-func-tests--library-completion () ;bug#43393
diff --git a/test/lisp/emacs-lisp/generator-tests.el b/test/lisp/emacs-lisp/generator-tests.el
index a1b9f64fdb1..1d2aa7ab374 100644
--- a/test/lisp/emacs-lisp/generator-tests.el
+++ b/test/lisp/emacs-lisp/generator-tests.el
@@ -74,7 +74,7 @@ identical output."
(cps-testcase cps-prog1-b (prog1 1))
(cps-testcase cps-prog1-c (prog2 1 2 3))
(cps-testcase cps-quote (progn 'hello))
-(cps-testcase cps-function (progn #'hello))
+(cps-testcase cps-function (progn #'message))
(cps-testcase cps-and-fail (and 1 nil 2))
(cps-testcase cps-and-succeed (and 1 2 3))
@@ -85,9 +85,9 @@ identical output."
(cps-testcase cps-or-empty (or))
(cps-testcase cps-let* (let* ((i 10)) i))
-(cps-testcase cps-let*-shadow-empty (let* ((i 10)) (let (i) i)))
+(cps-testcase cps-let*-shadow-empty (let* ((i 10)) i (let ((i nil)) i)))
(cps-testcase cps-let (let ((i 10)) i))
-(cps-testcase cps-let-shadow-empty (let ((i 10)) (let (i) i)))
+(cps-testcase cps-let-shadow-empty (let ((i 10)) i (let ((i nil)) i)))
(cps-testcase cps-let-novars (let nil 42))
(cps-testcase cps-let*-novars (let* nil 42))
@@ -95,7 +95,7 @@ identical output."
(let ((a 5) (b 6)) (let ((a b) (b a)) (list a b))))
(cps-testcase cps-let*-parallel
- (let* ((a 5) (b 6)) (let* ((a b) (b a)) (list a b))))
+ (let* ((a 5) (b 6)) a (let* ((a b) (b a)) (list a b))))
(cps-testcase cps-while-dynamic
(setq *cps-test-i* 0)
@@ -219,7 +219,7 @@ identical output."
(should (eql (iter-next it -1) 42))
(should (eql (iter-next it -1) -1))))
-(ert-deftest cps-loop ()
+(ert-deftest cps-loop-2 ()
(should
(equal (cl-loop for x iter-by (mygenerator 42)
collect x)
@@ -271,7 +271,7 @@ identical output."
(unwind-protect
(progn
(iter-yield 1)
- (error "test")
+ (error "Test")
(iter-yield 2))
(cl-incf nr-unwound))))))
(should (equal (iter-next iter) 1))
@@ -307,6 +307,7 @@ identical output."
(1+ it)))))))
-2)))
+(defun generator-tests-edebug ()) ; silence byte-compiler
(ert-deftest generator-tests-edebug ()
"Check that Bug#40434 is fixed."
(with-temp-buffer
diff --git a/test/lisp/emacs-lisp/gv-tests.el b/test/lisp/emacs-lisp/gv-tests.el
index b9850eca8b9..6ee274ae10f 100644
--- a/test/lisp/emacs-lisp/gv-tests.el
+++ b/test/lisp/emacs-lisp/gv-tests.el
@@ -21,22 +21,21 @@
(require 'edebug)
(require 'ert)
+(require 'ert-x)
(eval-when-compile (require 'cl-lib))
(cl-defmacro gv-tests--in-temp-dir ((elvar elcvar)
(&rest filebody)
&rest body)
(declare (indent 2))
- `(let ((default-directory (make-temp-file "gv-test" t)))
- (unwind-protect
- (let ((,elvar "gv-test-deffoo.el")
- (,elcvar "gv-test-deffoo.elc"))
- (with-temp-file ,elvar
- (insert ";; -*- lexical-binding: t; -*-\n")
- (dolist (form ',filebody)
- (pp form (current-buffer))))
- ,@body)
- (delete-directory default-directory t))))
+ `(ert-with-temp-directory default-directory
+ (let ((,elvar "gv-test-deffoo.el")
+ (,elcvar "gv-test-deffoo.elc"))
+ (with-temp-file ,elvar
+ (insert ";; -*- lexical-binding: t; -*-\n")
+ (dolist (form ',filebody)
+ (pp form (current-buffer))))
+ ,@body)))
(ert-deftest gv-define-expander-in-file ()
(gv-tests--in-temp-dir (el elc)
diff --git a/test/lisp/emacs-lisp/let-alist-tests.el b/test/lisp/emacs-lisp/let-alist-tests.el
index d856696da24..bbceb04b49d 100644
--- a/test/lisp/emacs-lisp/let-alist-tests.el
+++ b/test/lisp/emacs-lisp/let-alist-tests.el
@@ -82,7 +82,7 @@
(ert-deftest let-alist-list-to-sexp ()
"Check that multiple dots are handled correctly."
- (should (= 1 (eval (let-alist--list-to-sexp '(a b c d) ''((d (c (b (a . 1)))))))))
+ (should (= 1 (eval (let-alist--list-to-sexp '(a b c d) ''((d (c (b (a . 1)))))) t)))
(should (equal (let-alist--access-sexp '.foo.bar.baz 'var)
'(cdr (assq 'baz (cdr (assq 'bar (cdr (assq 'foo var))))))))
(should (equal (let-alist--access-sexp '..foo.bar.baz 'var) '.foo.bar.baz)))
@@ -100,4 +100,4 @@ See Bug#24641."
`[,(+ .a) ,(+ .a .b .b)])
[1 5])))
-;;; let-alist.el ends here
+;;; let-alist-tests.el ends here
diff --git a/test/lisp/emacs-lisp/lisp-mnt-tests.el b/test/lisp/emacs-lisp/lisp-mnt-tests.el
index 84cdc7205f2..d77804fbe60 100644
--- a/test/lisp/emacs-lisp/lisp-mnt-tests.el
+++ b/test/lisp/emacs-lisp/lisp-mnt-tests.el
@@ -32,5 +32,13 @@
'(("Bob Weiner" . "rsw@gnu.org")
("Mats Lidell" . "matsl@gnu.org")))))
+(ert-deftest lm--tests-lm-website ()
+ (with-temp-buffer
+ (insert ";; URL: https://example.org/foo")
+ (should (string= (lm-website) "https://example.org/foo")))
+ (with-temp-buffer
+ (insert ";; X-URL: <https://example.org/foo>")
+ (should (string= (lm-website) "https://example.org/foo"))))
+
(provide 'lisp-mnt-tests)
;;; lisp-mnt-tests.el ends here
diff --git a/test/lisp/emacs-lisp/lisp-tests.el b/test/lisp/emacs-lisp/lisp-tests.el
index 78ecf3ff03d..7f4d50c5958 100644
--- a/test/lisp/emacs-lisp/lisp-tests.el
+++ b/test/lisp/emacs-lisp/lisp-tests.el
@@ -213,6 +213,7 @@
(should-error (forward-sexp)))) ;; FIXME: Shouldn't be an error.
;; Test some core Elisp rules.
+(defvar c-e-x)
(ert-deftest core-elisp-tests-1-defvar-in-let ()
"Test some core Elisp rules."
(with-temp-buffer
@@ -235,7 +236,7 @@
(should (or (not mark-active) (mark)))))
(ert-deftest core-elisp-tests-3-backquote ()
- (should (eq 3 (eval ``,,'(+ 1 2)))))
+ (should (eq 3 (eval ``,,'(+ 1 2) t))))
;; Test up-list and backward-up-list.
(defun lisp-run-up-list-test (fn data start instructions)
@@ -324,7 +325,7 @@ start."
(declare (indent 1) (debug (def-form body)))
(let* ((var-pos nil)
(text (with-temp-buffer
- (insert (eval contents))
+ (insert (eval contents t))
(goto-char (point-min))
(while (re-search-forward elisp-test-point-position-regex nil t)
(push (list (intern (match-string-no-properties 1))
diff --git a/test/lisp/emacs-lisp/map-tests.el b/test/lisp/emacs-lisp/map-tests.el
index 658ed2e7119..afade8e295b 100644
--- a/test/lisp/emacs-lisp/map-tests.el
+++ b/test/lisp/emacs-lisp/map-tests.el
@@ -85,11 +85,13 @@ Evaluate BODY for each created map."
(should (= 5 (map-elt map 0 5)))))
(ert-deftest test-map-elt-testfn ()
- (let ((map (list (cons "a" 1) (cons "b" 2)))
- ;; Make sure to use a non-eq "a", even when compiled.
- (noneq-key (string ?a)))
- (should-not (map-elt map noneq-key))
- (should (map-elt map noneq-key nil #'equal))))
+ (let* ((a (string ?a))
+ (map `((,a . 0) (,(string ?b) . 1))))
+ (should (= (map-elt map a) 0))
+ (should (= (map-elt map "a") 0))
+ (should (= (map-elt map (string ?a)) 0))
+ (should (= (map-elt map "b") 1))
+ (should (= (map-elt map (string ?b)) 1))))
(ert-deftest test-map-elt-with-nil-value ()
(should-not (map-elt '((a . 1) (b)) 'b 2)))
@@ -129,6 +131,19 @@ Evaluate BODY for each created map."
(setf (map-elt map size) 'v)
(should (eq (map-elt map size) 'v))))))
+(ert-deftest test-map-put!-alist ()
+ "Test `map-put!' test function on alists."
+ (let ((key (string ?a))
+ (val 0)
+ map)
+ (should-error (map-put! map key val) :type 'map-not-inplace)
+ (setq map (list (cons key val)))
+ (map-put! map key (1- val))
+ (should (equal map '(("a" . -1))))
+ (map-put! map (string ?a) (1+ val))
+ (should (equal map '(("a" . 1))))
+ (should-error (map-put! map (string ?a) val #'eq) :type 'map-not-inplace)))
+
(ert-deftest test-map-put-alist-new-key ()
"Regression test for Bug#23105."
(let ((alist (list (cons 0 'a))))
@@ -197,6 +212,15 @@ Evaluate BODY for each created map."
(with-empty-maps-do map
(should (eq map (map-delete map t)))))
+(ert-deftest test-map-delete-alist ()
+ "Test `map-delete' test function on alists."
+ (let* ((a (string ?a))
+ (map `((,a) (,(string ?b)))))
+ (setq map (map-delete map a))
+ (should (equal map '(("b"))))
+ (setq map (map-delete map (string ?b)))
+ (should-not map)))
+
(ert-deftest test-map-nested-elt ()
(let ((vec [a b [c d [e f]]]))
(should (eq (map-nested-elt vec '(2 2 0)) 'e)))
@@ -521,5 +545,14 @@ Evaluate BODY for each created map."
'value2))
(should (equal (map-elt ht 'key) 'value2))))
+(ert-deftest test-setf-map-with-function ()
+ (let ((num 0)
+ (map nil))
+ (setf (map-elt map 'foo)
+ (funcall (lambda ()
+ (cl-incf num))))
+ ;; Check that the function is only called once.
+ (should (= num 1))))
+
(provide 'map-tests)
;;; map-tests.el ends here
diff --git a/test/lisp/emacs-lisp/memory-report-tests.el b/test/lisp/emacs-lisp/memory-report-tests.el
index 0c0297b5fce..d37f09b34f2 100644
--- a/test/lisp/emacs-lisp/memory-report-tests.el
+++ b/test/lisp/emacs-lisp/memory-report-tests.el
@@ -17,6 +17,8 @@
;; 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 'memory-report)
@@ -68,6 +70,14 @@
(vector string string))
124))))
+(ert-deftest memory-report-sizes-structs ()
+ (cl-defstruct memory-report-test-struct
+ (item0 nil)
+ (item1 nil))
+ (let ((s (make-memory-report-test-struct :item0 "hello" :item1 "world")))
+ (should (= (memory-report-object-size s)
+ 90))))
+
(provide 'memory-report-tests)
;;; memory-report-tests.el ends here
diff --git a/test/lisp/emacs-lisp/multisession-tests.el b/test/lisp/emacs-lisp/multisession-tests.el
new file mode 100644
index 00000000000..1bf0a533a70
--- /dev/null
+++ b/test/lisp/emacs-lisp/multisession-tests.el
@@ -0,0 +1,201 @@
+;;; multisession-tests.el --- Tests for multisession.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 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 'multisession)
+(require 'ert)
+(require 'ert-x)
+(require 'cl-lib)
+
+(ert-deftest multi-test-sqlite-simple ()
+ (skip-unless (sqlite-available-p))
+ (ert-with-temp-file dir
+ :directory t
+ (let ((user-init-file "/tmp/foo.el")
+ (multisession-storage 'sqlite)
+ (multisession-directory dir))
+ (unwind-protect
+ (progn
+ (define-multisession-variable multisession--foo 0
+ ""
+ :synchronized t)
+ (should (= (multisession-value multisession--foo) 0))
+ (cl-incf (multisession-value multisession--foo))
+ (should (= (multisession-value multisession--foo) 1))
+ (call-process
+ (concat invocation-directory invocation-name)
+ nil t nil
+ "-Q" "-batch"
+ "--eval" (prin1-to-string
+ `(progn
+ (require 'multisession)
+ (let ((multisession-directory ,dir)
+ (multisession-storage 'sqlite)
+ (user-init-file "/tmp/foo.el"))
+ (define-multisession-variable multisession--foo 0
+ ""
+ :synchronized t)
+ (cl-incf (multisession-value multisession--foo))))))
+ (should (= (multisession-value multisession--foo) 2)))
+ (sqlite-close multisession--db)
+ (setq multisession--db nil)))))
+
+(ert-deftest multi-test-sqlite-busy ()
+ (skip-unless (and t (sqlite-available-p)))
+ (ert-with-temp-file dir
+ :directory t
+ (let ((user-init-file "/tmp/foo.el")
+ (multisession-directory dir)
+ (multisession-storage 'sqlite)
+ proc)
+ (unwind-protect
+ (progn
+ (define-multisession-variable multisession--bar 0
+ ""
+ :synchronized t)
+ (should (= (multisession-value multisession--bar) 0))
+ (cl-incf (multisession-value multisession--bar))
+ (should (= (multisession-value multisession--bar) 1))
+ (setq proc
+ (start-process
+ "other-emacs"
+ nil
+ (concat invocation-directory invocation-name)
+ "-Q" "-batch"
+ "--eval" (prin1-to-string
+ `(progn
+ (require 'multisession)
+ (let ((multisession-directory ,dir)
+ (multisession-storage 'sqlite)
+ (user-init-file "/tmp/bar.el"))
+ (define-multisession-variable multisession--bar 0
+ "" :synchronized t)
+ (dotimes (i 100)
+ (cl-incf (multisession-value multisession--bar))))))))
+ (while (process-live-p proc)
+ (ignore-error 'sqlite-locked-error
+ (message "multisession--bar %s" (multisession-value multisession--bar))
+ ;;(cl-incf (multisession-value multisession--bar))
+ )
+ (sleep-for 0.1))
+ (message "multisession--bar ends up as %s" (multisession-value multisession--bar))
+ (should (< (multisession-value multisession--bar) 1003)))
+ (sqlite-close multisession--db)
+ (setq multisession--db nil)))))
+
+(ert-deftest multi-test-files-simple ()
+ (ert-with-temp-file dir
+ :directory t
+ (let ((user-init-file "/tmp/sfoo.el")
+ (multisession-storage 'files)
+ (multisession-directory dir))
+ (define-multisession-variable multisession--sfoo 0
+ ""
+ :synchronized t)
+ (should (= (multisession-value multisession--sfoo) 0))
+ (cl-incf (multisession-value multisession--sfoo))
+ (should (= (multisession-value multisession--sfoo) 1))
+ (call-process
+ (concat invocation-directory invocation-name)
+ nil t nil
+ "-Q" "-batch"
+ "--eval" (prin1-to-string
+ `(progn
+ (require 'multisession)
+ (let ((multisession-directory ,dir)
+ (multisession-storage 'files)
+ (user-init-file "/tmp/sfoo.el"))
+ (define-multisession-variable multisession--sfoo 0
+ ""
+ :synchronized t)
+ (cl-incf (multisession-value multisession--sfoo))))))
+ (should (= (multisession-value multisession--sfoo) 2)))))
+
+(ert-deftest multi-test-files-busy ()
+ (skip-unless (and t (sqlite-available-p)))
+ (ert-with-temp-file dir
+ :directory t
+ (let ((user-init-file "/tmp/foo.el")
+ (multisession-storage 'files)
+ (multisession-directory dir)
+ proc)
+ (define-multisession-variable multisession--sbar 0
+ ""
+ :synchronized t)
+ (should (= (multisession-value multisession--sbar) 0))
+ (cl-incf (multisession-value multisession--sbar))
+ (should (= (multisession-value multisession--sbar) 1))
+ (setq proc
+ (start-process
+ "other-emacs"
+ nil
+ (concat invocation-directory invocation-name)
+ "-Q" "-batch"
+ "--eval" (prin1-to-string
+ `(progn
+ (require 'multisession)
+ (let ((multisession-directory ,dir)
+ (multisession-storage 'files)
+ (user-init-file "/tmp/sbar.el"))
+ (define-multisession-variable multisession--sbar 0
+ "" :synchronized t)
+ (dotimes (i 1000)
+ (cl-incf (multisession-value multisession--sbar))))))))
+ (while (process-live-p proc)
+ (message "multisession--sbar %s" (multisession-value multisession--sbar))
+ ;;(cl-incf (multisession-value multisession--sbar))
+ (sleep-for 0.1))
+ (message "multisession--sbar ends up as %s" (multisession-value multisession--sbar))
+ (should (< (multisession-value multisession--sbar) 2000)))))
+
+(ert-deftest multi-test-files-some-values ()
+ (ert-with-temp-file dir
+ :directory t
+ (let ((user-init-file "/tmp/sfoo.el")
+ (multisession-storage 'files)
+ (multisession-directory dir))
+ (define-multisession-variable multisession--foo1 nil)
+ (should (eq (multisession-value multisession--foo1) nil))
+ (setf (multisession-value multisession--foo1) nil)
+ (should (eq (multisession-value multisession--foo1) nil))
+ (setf (multisession-value multisession--foo1) t)
+ (should (eq (multisession-value multisession--foo1) t))
+
+ (define-multisession-variable multisession--foo2 t)
+ (setf (multisession-value multisession--foo2) nil)
+ (should (eq (multisession-value multisession--foo2) nil))
+ (setf (multisession-value multisession--foo2) t)
+ (should (eq (multisession-value multisession--foo2) t))
+
+ (define-multisession-variable multisession--foo3 t)
+ (should-error (setf (multisession-value multisession--foo3) (make-marker)))
+
+ (let ((string (with-temp-buffer
+ (set-buffer-multibyte nil)
+ (insert 0 1 2)
+ (buffer-string))))
+ (should-not (multibyte-string-p string))
+ (define-multisession-variable multisession--foo4 nil)
+ (setf (multisession-value multisession--foo4) string)
+ (should (equal (multisession-value multisession--foo4) string))))))
+
+;;; multisession-tests.el ends here
diff --git a/test/lisp/emacs-lisp/nadvice-tests.el b/test/lisp/emacs-lisp/nadvice-tests.el
index 358d9025ad5..ee33bb0fa40 100644
--- a/test/lisp/emacs-lisp/nadvice-tests.el
+++ b/test/lisp/emacs-lisp/nadvice-tests.el
@@ -208,4 +208,4 @@ function being an around advice."
;; no-byte-compile: t
;; End:
-;;; advice-tests.el ends here.
+;;; nadvice-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 5e2ebc55d35..99965723baf 100644
--- a/test/lisp/emacs-lisp/package-resources/key.pub
+++ b/test/lisp/emacs-lisp/package-resources/key.pub
@@ -1,20 +1,17 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
-mI0EX48EbAEEANrsWXyZ4MRZRjVbLAh5jX/+1+31oB/aJ/q/5DkH1qUHJf0La9LC
-sykUSM3H2u5VWLytX/ozrxIRYX13GR2xBxyJlUkDWB209AAVLFrjSp1yUX/Sb5SU
-Kb7p421ZAeHiOxfnLRuErFZkTfzY19mUCyw4cdamw430V3mUC9uns/d9ABEBAAG0
-LUouIFJhbmRvbSBIYWNrZXIgKFRFU1QgS0VZKSA8anJoQGV4YW1wbGUub3JnPojO
-BBMBCgA4FiEEHP310DrP36xrZ1kSMKdkJgeTYhoFAl+PBGwCGwMFCwkIBwIGFQoJ
-CAsCBBYCAwECHgECF4AACgkQMKdkJgeTYhq9MQP7BYkCk8r5G777Ilp8kWjsEIo3
-aDX9jORiNfMAGys/aLjjEajHFAlTQKfSLm/VXLDYtK28c8ACjThQagaDF46MRWqQ
-rFFiH4IAZRgj2ELj+/j1ljQZjGjKR2Yx4BCDhbumz8zeMSPL6yFT5+8LOMUAtdv4
-lEPWXW0AycylbdbE7024jQRfjwRsAQQApjTw9kONmSVouCi8ZIQwwYiA9tLzbSZv
-CYxbJ6KH0icRhBLfdb1hL/Kn8x3k+xll9A0c/ABVkMxRcbQkY98xsFck7E2GcvnC
-sY+w/NdcUUZJYMB3l2MH5ojCbOk5jSAZzxzeFcJhNAhmLqomMHg2LI6KDVey6iYU
-FxyIpIQ3SlkAEQEAAYi2BBgBCgAgFiEEHP310DrP36xrZ1kSMKdkJgeTYhoFAl+P
-BGwCGwwACgkQMKdkJgeTYhrtywQAhoCR/skBSQWWBI10N0qhtdlNxbpvK8ErSPKw
-wS74Pq407Zv0VD9ual/HC3Uet2z8LeG9ZwU4Jd23g96fmJt7AM9CQWrOhC242JYr
-YSqWxANyek8otsvppJNHtt2Stmknv7XbJFFB1JDC8WKo8lVo9/MkmzROxuEFEvOU
-Yn923VI=
-=NRtx
+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
-----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 dbc80f43cb7..5bbac1226ae 100644
--- a/test/lisp/emacs-lisp/package-resources/key.sec
+++ b/test/lisp/emacs-lisp/package-resources/key.sec
@@ -1,35 +1,17 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
-lQIGBF+PBGwBBADa7Fl8meDEWUY1WywIeY1//tft9aAf2if6v+Q5B9alByX9C2vS
-wrMpFEjNx9ruVVi8rV/6M68SEWF9dxkdsQcciZVJA1gdtPQAFSxa40qdclF/0m+U
-lCm+6eNtWQHh4jsX5y0bhKxWZE382NfZlAssOHHWpsON9Fd5lAvbp7P3fQARAQAB
-/gcDAngNw4ppSPBe/w734cz++xNEv0TDgwxGBWp2wGSwWao04Nl1U4LkjiIy+dkc
-uUPwEZMvxXwMcq10PPH26ifP8Xfi/zANXUoLJ0DsG6rtE3BcSC9MPFe3EJENtcIP
-a0jFLsbi72aBzolNEDCZCv93znXFPekaXw/RAeeFLJz8GR2Sx6bHbTJKklXgWPHw
-C5Dw6xr/kEZktgjlhjkx280STpLGaFO4jiiGZ4Obp5ePp7kyOzDUzaimdZgJwClT
-VbZDNQMTzgQrBOP8doXlo9euW4Wo1IYBIOwgeYieM3ZA9YjJAmp4lFnk/KFYt0Ak
-0H9IWzDU8VERcU4B04PSXahzvB1Ii7C7bbHxPyuu6sAfMK8DRkrGjwgAlrhuWNLX
-M07acT/E9Pm+mBlDcdkyKB2LfwgaVb9F3C25sfcFSvc5p+sqgZp1Zx7Qg9pOhQjw
-U7Ln+96c0bUl+iQKdm3TGjOXAFUHYXbRkx2cJ4gxnMVNj0D68xBtBSm0LUouIFJh
-bmRvbSBIYWNrZXIgKFRFU1QgS0VZKSA8anJoQGV4YW1wbGUub3JnPojOBBMBCgA4
-FiEEHP310DrP36xrZ1kSMKdkJgeTYhoFAl+PBGwCGwMFCwkIBwIGFQoJCAsCBBYC
-AwECHgECF4AACgkQMKdkJgeTYhq9MQP7BYkCk8r5G777Ilp8kWjsEIo3aDX9jORi
-NfMAGys/aLjjEajHFAlTQKfSLm/VXLDYtK28c8ACjThQagaDF46MRWqQrFFiH4IA
-ZRgj2ELj+/j1ljQZjGjKR2Yx4BCDhbumz8zeMSPL6yFT5+8LOMUAtdv4lEPWXW0A
-ycylbdbE702dAgYEX48EbAEEAKY08PZDjZklaLgovGSEMMGIgPbS820mbwmMWyei
-h9InEYQS33W9YS/yp/Md5PsZZfQNHPwAVZDMUXG0JGPfMbBXJOxNhnL5wrGPsPzX
-XFFGSWDAd5djB+aIwmzpOY0gGc8c3hXCYTQIZi6qJjB4NiyOig1XsuomFBcciKSE
-N0pZABEBAAH+BwMCXeUOBwcOsxb/AY6rnHmgACNTGwIa5vgelw0qfET0ms/YzVrN
-ufikyV9dEWVxJyuTKav978wanPu7VcCh0pTjL2nTm2nZWyRJN4gb3UIC0MA1xfB2
-yPLTCmsGeJhVOqi4Af/r06mk+NOQ96ivOA2CJuw1LSpcUtuYxB5t/grGyEojYjRP
-s0Htvf2bfN9KbFJ26DGsfYzC8bCxm9szPFHBQjw4NboCigUSAHmkoTW01aWZU9Vq
-brY4cWhdmCqHgfmsQgzP3LfaAQ6kJ/bkuKef7z57lz5XmlyjMQGWcZWp5xf2n81p
-BV6unaIPyavzkKVAXizVfNiHNJgK9PoVoEOJkPLjRfMxVmFSGN/oF7lVTRWfOIwo
-68rtNPhr6UzE4ArGHYv/pK3kijUp5daWmfrySWPcwoVAaR3mIIVs/1rhd9aZrwn6
-Q07Yo5u11rH9b8anZQF3BdTcrnU9pUzLYlFPnfhtyGqhikQILtPTf0iwr8hpG9b2
-Zoi2BBgBCgAgFiEEHP310DrP36xrZ1kSMKdkJgeTYhoFAl+PBGwCGwwACgkQMKdk
-JgeTYhrtywQAhoCR/skBSQWWBI10N0qhtdlNxbpvK8ErSPKwwS74Pq407Zv0VD9u
-al/HC3Uet2z8LeG9ZwU4Jd23g96fmJt7AM9CQWrOhC242JYrYSqWxANyek8otsvp
-pJNHtt2Stmknv7XbJFFB1JDC8WKo8lVo9/MkmzROxuEFEvOUYn923VI=
-=2DW8
+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
-----END PGP PRIVATE KEY BLOCK-----
diff --git a/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin-aux.el b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin-aux.el
new file mode 100644
index 00000000000..724f88ec9ea
--- /dev/null
+++ b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin-aux.el
@@ -0,0 +1,12 @@
+;;; macro-builtin-aux.el --- laksd -*- lexical-binding: t; -*-
+
+;; Author: Artur Malabarba <emacs@endlessparentheses.com>
+
+;;; Code:
+
+(defun macro-builtin-aux-1 ( &rest forms)
+ "Description"
+ `(progn ,@forms))
+
+(provide 'macro-builtin-aux)
+;;; macro-builtin-aux.el ends here
diff --git a/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin.el b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin.el
new file mode 100644
index 00000000000..828968a0576
--- /dev/null
+++ b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin.el
@@ -0,0 +1,21 @@
+;;; macro-builtin.el --- laksd -*- lexical-binding: t; -*-
+
+;; Author: Artur Malabarba <emacs@endlessparentheses.com>
+;; Keywords: tools
+;; Version: 1.0
+
+;;; Code:
+
+(require 'macro-builtin-aux)
+
+(defmacro macro-builtin-1 ( &rest forms)
+ "Description"
+ `(progn ,@forms))
+
+(defun macro-builtin-func ()
+ ""
+ (macro-builtin-1 'a 'b)
+ (macro-builtin-aux-1 'a 'b))
+
+(provide 'macro-builtin)
+;;; macro-builtin.el ends here
diff --git a/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin-aux.el b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin-aux.el
new file mode 100644
index 00000000000..9f257d9d22c
--- /dev/null
+++ b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin-aux.el
@@ -0,0 +1,16 @@
+;;; macro-builtin-aux.el --- laksd -*- lexical-binding: t; -*-
+
+;; Author: Artur Malabarba <emacs@endlessparentheses.com>
+
+;;; Code:
+
+(defmacro macro-builtin-aux-1 ( &rest forms)
+ "Description"
+ `(progn ,@forms))
+
+(defmacro macro-builtin-aux-3 ( &rest _)
+ "Description"
+ 90)
+
+(provide 'macro-builtin-aux)
+;;; macro-builtin-aux.el ends here
diff --git a/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin.el b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin.el
new file mode 100644
index 00000000000..5d241c082d0
--- /dev/null
+++ b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin.el
@@ -0,0 +1,30 @@
+;;; macro-builtin.el --- laksd -*- lexical-binding: t; -*-
+
+;; Author: Artur Malabarba <emacs@endlessparentheses.com>
+;; Keywords: tools
+;; Version: 2.0
+
+;;; Code:
+
+(require 'macro-builtin-aux)
+
+(defmacro macro-builtin-1 ( &rest forms)
+ "Description"
+ `(progn ,(cadr (car forms))))
+
+
+(defun macro-builtin-func ()
+ ""
+ (list (macro-builtin-1 '1 'b)
+ (macro-builtin-aux-1 'a 'b)))
+
+(defmacro macro-builtin-3 (&rest _)
+ "Description"
+ 10)
+
+(defun macro-builtin-10-and-90 ()
+ ""
+ (list (macro-builtin-3 haha) (macro-builtin-aux-3 hehe)))
+
+(provide 'macro-builtin)
+;;; macro-builtin.el ends here
diff --git a/test/lisp/emacs-lisp/package-resources/macro-problem-package-1.0/macro-aux.el b/test/lisp/emacs-lisp/package-resources/macro-problem-package-1.0/macro-aux.el
index f43232224af..ad20a3507a6 100644
--- a/test/lisp/emacs-lisp/package-resources/macro-problem-package-1.0/macro-aux.el
+++ b/test/lisp/emacs-lisp/package-resources/macro-problem-package-1.0/macro-aux.el
@@ -5,7 +5,7 @@
;;; Code:
(defun macro-aux-1 ( &rest forms)
- "Description"
+ "Description."
`(progn ,@forms))
(provide 'macro-aux)
diff --git a/test/lisp/emacs-lisp/package-resources/macro-problem-package-1.0/macro-problem.el b/test/lisp/emacs-lisp/package-resources/macro-problem-package-1.0/macro-problem.el
index 0533b1bd9c4..6e5e54e54fd 100644
--- a/test/lisp/emacs-lisp/package-resources/macro-problem-package-1.0/macro-problem.el
+++ b/test/lisp/emacs-lisp/package-resources/macro-problem-package-1.0/macro-problem.el
@@ -9,11 +9,11 @@
(require 'macro-aux)
(defmacro macro-problem-1 ( &rest forms)
- "Description"
+ "Description."
`(progn ,@forms))
(defun macro-problem-func ()
- ""
+ "Description."
(macro-problem-1 'a 'b)
(macro-aux-1 'a 'b))
diff --git a/test/lisp/emacs-lisp/package-resources/macro-problem-package-2.0/macro-aux.el b/test/lisp/emacs-lisp/package-resources/macro-problem-package-2.0/macro-aux.el
index 6a55a40e3b4..814d77183ab 100644
--- a/test/lisp/emacs-lisp/package-resources/macro-problem-package-2.0/macro-aux.el
+++ b/test/lisp/emacs-lisp/package-resources/macro-problem-package-2.0/macro-aux.el
@@ -5,11 +5,11 @@
;;; Code:
(defmacro macro-aux-1 ( &rest forms)
- "Description"
+ "Description."
`(progn ,@forms))
(defmacro macro-aux-3 ( &rest _)
- "Description"
+ "Description."
90)
(provide 'macro-aux)
diff --git a/test/lisp/emacs-lisp/package-resources/macro-problem-package-2.0/macro-problem.el b/test/lisp/emacs-lisp/package-resources/macro-problem-package-2.0/macro-problem.el
index cad4ed93f19..aef5eda7c6c 100644
--- a/test/lisp/emacs-lisp/package-resources/macro-problem-package-2.0/macro-problem.el
+++ b/test/lisp/emacs-lisp/package-resources/macro-problem-package-2.0/macro-problem.el
@@ -9,21 +9,21 @@
(require 'macro-aux)
(defmacro macro-problem-1 ( &rest forms)
- "Description"
+ "Description."
`(progn ,(cadr (car forms))))
(defun macro-problem-func ()
- ""
+ "Description."
(list (macro-problem-1 '1 'b)
(macro-aux-1 'a 'b)))
(defmacro macro-problem-3 (&rest _)
- "Description"
+ "Description."
10)
(defun macro-problem-10-and-90 ()
- ""
+ "Description."
(list (macro-problem-3 haha) (macro-aux-3 hehe)))
(provide 'macro-problem)
diff --git a/test/lisp/emacs-lisp/package-resources/newer-versions/simple-single-1.4.el b/test/lisp/emacs-lisp/package-resources/newer-versions/simple-single-1.4.el
index 301993deb30..be6bedf8a1c 100644
--- a/test/lisp/emacs-lisp/package-resources/newer-versions/simple-single-1.4.el
+++ b/test/lisp/emacs-lisp/package-resources/newer-versions/simple-single-1.4.el
@@ -7,14 +7,14 @@
;;; Commentary:
;; This package provides a minor mode to frobnicate and/or bifurcate
-;; any flanges you desire. To activate it, type "C-M-r M-3 butterfly"
+;; any flanges you desire. To activate it, type "C-M-r M-3 butterfly"
;; and all your dreams will come true.
;;
;; This is a new, updated version.
;;; Code:
-(defgroup simple-single nil "Simply a file"
+(defgroup simple-single nil "Simply a file."
:group 'lisp)
(defcustom simple-single-super-sunday nil
@@ -29,7 +29,7 @@ Default changed to nil."
;;;###autoload
(define-minor-mode simple-single-mode
- "It does good things to stuff")
+ "It does good things to stuff.")
(provide 'simple-single)
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 dac168b0e4c..b40620a0e89 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-bad-1.0.el b/test/lisp/emacs-lisp/package-resources/signed/signed-bad-1.0.el
index ff070c6526f..781077251e9 100644
--- a/test/lisp/emacs-lisp/package-resources/signed/signed-bad-1.0.el
+++ b/test/lisp/emacs-lisp/package-resources/signed/signed-bad-1.0.el
@@ -8,12 +8,12 @@
;;; Commentary:
;; This package provides a minor mode to frobnicate and/or bifurcate
-;; any flanges you desire. To activate it, type "C-M-r M-3 butterfly"
+;; any flanges you desire. To activate it, type "C-M-r M-3 butterfly"
;; and all your dreams will come true.
;;; Code:
-(defgroup signed-bad nil "Simply a file"
+(defgroup signed-bad nil "Simply a file."
:group 'lisp)
(defcustom signed-bad-super-sunday t
@@ -26,7 +26,7 @@
;;;###autoload
(define-minor-mode signed-bad-mode
- "It does good things to stuff")
+ "It does good things to stuff.")
(provide 'signed-bad)
diff --git a/test/lisp/emacs-lisp/package-resources/signed/signed-good-1.0.el b/test/lisp/emacs-lisp/package-resources/signed/signed-good-1.0.el
index 60b1b8663d9..8a408c1f301 100644
--- a/test/lisp/emacs-lisp/package-resources/signed/signed-good-1.0.el
+++ b/test/lisp/emacs-lisp/package-resources/signed/signed-good-1.0.el
@@ -8,12 +8,12 @@
;;; Commentary:
;; This package provides a minor mode to frobnicate and/or bifurcate
-;; any flanges you desire. To activate it, type "C-M-r M-3 butterfly"
+;; any flanges you desire. To activate it, type "C-M-r M-3 butterfly"
;; and all your dreams will come true.
;;; Code:
-(defgroup signed-good nil "Simply a file"
+(defgroup signed-good nil "Simply a file."
:group 'lisp)
(defcustom signed-good-super-sunday t
@@ -26,7 +26,7 @@
;;;###autoload
(define-minor-mode signed-good-mode
- "It does good things to stuff")
+ "It does good things to stuff.")
(provide 'signed-good)
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 5b1c721e32a..11092411601 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/simple-depend-1.0.el b/test/lisp/emacs-lisp/package-resources/simple-depend-1.0.el
index cb003905bb5..f1ee8627610 100644
--- a/test/lisp/emacs-lisp/package-resources/simple-depend-1.0.el
+++ b/test/lisp/emacs-lisp/package-resources/simple-depend-1.0.el
@@ -12,6 +12,6 @@
;;; Code:
(defvar simple-depend "Value"
- "Some trivial code")
+ "Some trivial code.")
;;; simple-depend.el ends here
diff --git a/test/lisp/emacs-lisp/package-resources/simple-single-1.3.el b/test/lisp/emacs-lisp/package-resources/simple-single-1.3.el
index 9c3f427ff48..459801d78cf 100644
--- a/test/lisp/emacs-lisp/package-resources/simple-single-1.3.el
+++ b/test/lisp/emacs-lisp/package-resources/simple-single-1.3.el
@@ -8,12 +8,12 @@
;;; Commentary:
;; This package provides a minor mode to frobnicate and/or bifurcate
-;; any flanges you desire. To activate it, type "C-M-r M-3 butterfly"
+;; any flanges you desire. To activate it, type "C-M-r M-3 butterfly"
;; and all your dreams will come true.
;;; Code:
-(defgroup simple-single nil "Simply a file"
+(defgroup simple-single nil "Simply a file."
:group 'lisp)
(defcustom simple-single-super-sunday t
@@ -26,7 +26,7 @@
;;;###autoload
(define-minor-mode simple-single-mode
- "It does good things to stuff")
+ "It does good things to stuff.")
(provide 'simple-single)
diff --git a/test/lisp/emacs-lisp/package-resources/simple-two-depend-1.1.el b/test/lisp/emacs-lisp/package-resources/simple-two-depend-1.1.el
index a0a9607350a..8de6141d67a 100644
--- a/test/lisp/emacs-lisp/package-resources/simple-two-depend-1.1.el
+++ b/test/lisp/emacs-lisp/package-resources/simple-two-depend-1.1.el
@@ -12,6 +12,6 @@
;;; Code:
(defvar simple-two-depend "Value"
- "Some trivial code")
+ "Some trivial code.")
;;; simple-two-depend.el ends here
diff --git a/test/lisp/emacs-lisp/package-tests.el b/test/lisp/emacs-lisp/package-tests.el
index 29435799555..efa9f834110 100644
--- a/test/lisp/emacs-lisp/package-tests.el
+++ b/test/lisp/emacs-lisp/package-tests.el
@@ -115,57 +115,55 @@
&rest body)
"Set up temporary locations and variables for testing."
(declare (indent 1) (debug (([&rest form]) body)))
- `(let* ((package-test-user-dir (make-temp-file "pkg-test-user-dir-" t))
- (process-environment (cons (format "HOME=%s" package-test-user-dir)
- process-environment))
- (package-user-dir package-test-user-dir)
- (package-gnupghome-dir (expand-file-name "gnupg" package-user-dir))
- (package-archives `(("gnu" . ,(or ,location package-test-data-dir))))
- (default-directory package-test-file-dir)
- abbreviated-home-dir
- package--initialized
- package-alist
- ,@(if update-news
- '(package-update-news-on-upload t)
- (list (cl-gensym)))
- ,@(if upload-base
- '((package-test-archive-upload-base (make-temp-file "pkg-archive-base-" t))
- (package-archive-upload-base package-test-archive-upload-base))
- (list (cl-gensym)))) ;; Dummy value so `let' doesn't try to bind nil
- (let ((buf (get-buffer "*Packages*")))
- (when (buffer-live-p buf)
- (kill-buffer buf)))
- (unwind-protect
- (progn
- ,(if basedir `(cd ,basedir))
- (unless (file-directory-p package-user-dir)
- (mkdir package-user-dir))
- (cl-letf (((symbol-function 'yes-or-no-p) (lambda (&rest _) t))
- ((symbol-function 'y-or-n-p) (lambda (&rest _) t)))
- ,@(when install
- `((package-initialize)
- (package-refresh-contents)
- (mapc 'package-install ,install)))
- (with-temp-buffer
- ,(if file
- `(insert-file-contents ,file))
- ,@body)))
-
- (when ,upload-base
- (dolist (f '("archive-contents"
- "simple-single-1.3.el"
- "simple-single-1.4.el"
- "simple-single-readme.txt"))
- (ignore-errors
- (delete-file
- (expand-file-name f package-test-archive-upload-base))))
- (delete-directory package-test-archive-upload-base))
- (when (file-directory-p package-test-user-dir)
- (delete-directory package-test-user-dir t))
-
- (when (and (boundp 'package-test-archive-upload-base)
- (file-directory-p package-test-archive-upload-base))
- (delete-directory package-test-archive-upload-base t)))))
+ `(ert-with-temp-directory package-test-user-dir
+ (let* ((process-environment (cons (format "HOME=%s" package-test-user-dir)
+ process-environment))
+ (package-user-dir package-test-user-dir)
+ (package-gnupghome-dir (expand-file-name "gnupg" package-user-dir))
+ (package-archives `(("gnu" . ,(or ,location package-test-data-dir))))
+ (default-directory package-test-file-dir)
+ abbreviated-home-dir
+ package--initialized
+ package-alist
+ ,@(if update-news
+ '(package-update-news-on-upload t)
+ (list (cl-gensym)))
+ ,@(if upload-base
+ '((package-test-archive-upload-base (make-temp-file "pkg-archive-base-" t))
+ (package-archive-upload-base package-test-archive-upload-base))
+ (list (cl-gensym)))) ;; Dummy value so `let' doesn't try to bind nil
+ (let ((buf (get-buffer "*Packages*")))
+ (when (buffer-live-p buf)
+ (kill-buffer buf)))
+ (unwind-protect
+ (progn
+ ,(if basedir `(cd ,basedir))
+ (unless (file-directory-p package-user-dir)
+ (mkdir package-user-dir))
+ (cl-letf (((symbol-function 'yes-or-no-p) (lambda (&rest _) t))
+ ((symbol-function 'y-or-n-p) (lambda (&rest _) t)))
+ ,@(when install
+ `((package-initialize)
+ (package-refresh-contents)
+ (mapc 'package-install ,install)))
+ (with-temp-buffer
+ ,(if file
+ `(insert-file-contents ,file))
+ ,@body)))
+
+ (when ,upload-base
+ (dolist (f '("archive-contents"
+ "simple-single-1.3.el"
+ "simple-single-1.4.el"
+ "simple-single-readme.txt"))
+ (ignore-errors
+ (delete-file
+ (expand-file-name f package-test-archive-upload-base))))
+ (delete-directory package-test-archive-upload-base))
+
+ (when (and (boundp 'package-test-archive-upload-base)
+ (file-directory-p package-test-archive-upload-base))
+ (delete-directory package-test-archive-upload-base t))))))
(defmacro with-fake-help-buffer (&rest body)
"Execute BODY in a temp buffer which is treated as the \"*Help*\" buffer."
@@ -180,7 +178,7 @@
(replace-regexp-in-string "-pkg\\.el\\'" "" (package--description-file dir)))
(defun package-test-suffix-matches (base suffix-list)
- "Return file names matching BASE concatenated with each item in SUFFIX-LIST"
+ "Return file names matching BASE concatenated with each item in SUFFIX-LIST."
(mapcan (lambda (item) (file-expand-wildcards (concat base item)))
suffix-list))
@@ -342,9 +340,13 @@ but with a different end of line convention (bug#48137)."
(declare-function macro-problem-func "macro-problem" ())
(declare-function macro-problem-10-and-90 "macro-problem" ())
+(declare-function macro-builtin-func "macro-builtin" ())
+(declare-function macro-builtin-10-and-90 "macro-builtin" ())
(ert-deftest package-test-macro-compilation ()
- "Install a package which includes a dependency."
+ "\"Activation has to be done before compilation, so that if we're
+ upgrading and macros have changed we load the new definitions
+ before compiling.\" -- package.el"
(with-package-test (:basedir (ert-resource-directory))
(package-install-file (expand-file-name "macro-problem-package-1.0/"))
(require 'macro-problem)
@@ -357,6 +359,32 @@ but with a different end of line convention (bug#48137)."
;; `macro-problem-10-and-90' depends on an entirely new macro from `macro-aux'.
(should (equal (macro-problem-10-and-90) '(10 90)))))
+(ert-deftest package-test-macro-compilation-gz ()
+ "Built-in's can be superseded as well."
+ (with-package-test (:basedir (ert-resource-directory))
+ (let ((dir (expand-file-name "macro-builtin-package-1.0")))
+ (unwind-protect
+ (let ((load-path load-path))
+ (add-to-list 'load-path (directory-file-name dir))
+ (byte-recompile-directory dir 0 t)
+ (mapc (lambda (f) (call-process "gzip" nil nil nil f))
+ (directory-files-recursively dir "\\`[^\\.].*\\.el\\'"))
+ (require 'macro-builtin)
+ (should (member (expand-file-name "macro-builtin-aux.elc" dir)
+ (mapcar #'car load-history)))
+ ;; `macro-builtin-func' uses a macro from `macro-aux'.
+ (should (equal (macro-builtin-func) '(progn a b)))
+ (package-install-file (expand-file-name "macro-builtin-package-2.0/"))
+ ;; After upgrading, `macro-builtin-func' depends on a new version
+ ;; of the macro from `macro-builtin-aux'.
+ (should (equal (macro-builtin-func) '(1 b)))
+ ;; `macro-builtin-10-and-90' depends on an entirely new macro from `macro-aux'.
+ (should (equal (macro-builtin-10-and-90) '(10 90))))
+ (mapc #'delete-file
+ (directory-files-recursively dir "\\`[^\\.].*\\.elc\\'"))
+ (mapc (lambda (f) (call-process "gunzip" nil nil nil f))
+ (directory-files-recursively dir "\\`[^\\.].*\\.el\\.gz\\'"))))))
+
(ert-deftest package-test-install-two-dependencies ()
"Install a package which includes a dependency."
(with-package-test ()
@@ -636,7 +664,7 @@ but with a different end of line convention (bug#48137)."
(save-excursion (should (re-search-forward "Status: Installed in ['`‘]simple-single-1.3/['’] (unsigned)." nil t)))
(save-excursion (should (search-forward "Version: 1.3" nil t)))
(save-excursion (should (search-forward "Summary: A single-file package with no dependencies" nil t)))
- (save-excursion (should (search-forward "Homepage: http://doodles.au" nil t)))
+ (save-excursion (should (search-forward "Website: http://doodles.au" nil t)))
(save-excursion (should (re-search-forward "Keywords: \\[?frobnicate\\]?" nil t)))
(save-excursion (should (search-forward "This package provides a minor mode to frobnicate"
nil t)))
@@ -652,7 +680,7 @@ but with a different end of line convention (bug#48137)."
(with-fake-help-buffer
(describe-package 'multi-file)
(goto-char (point-min))
- (should (search-forward "Homepage: http://puddles.li" nil t))
+ (should (search-forward "Website: http://puddles.li" nil t))
(should (search-forward "This is a bare-bones readme file for the multi-file"
nil t)))))
@@ -665,7 +693,7 @@ but with a different end of line convention (bug#48137)."
(with-fake-help-buffer
(describe-package 'simple-single)
(goto-char (point-min))
- (should (search-forward "Homepage: http://doodles.au" nil t))
+ (should (search-forward "Website: http://doodles.au" nil t))
(should (search-forward "This package provides a minor mode to frobnicate"
nil t)))))
@@ -678,32 +706,30 @@ but with a different end of line convention (bug#48137)."
(with-fake-help-buffer
(describe-package 'multi-file)
(goto-char (point-min))
- (should (search-forward "Homepage: http://puddles.li" nil t))
+ (should (search-forward "Website: http://puddles.li" nil t))
(should (search-forward "This is a bare-bones readme file for the multi-file"
nil t)))))
(defvar epg-config--program-alist) ; Silence byte-compiler.
(ert-deftest package-test-signed ()
"Test verifying package signature."
- (skip-unless (let ((homedir (make-temp-file "package-test" t)))
- (unwind-protect
- (let ((process-environment
- (cons (concat "HOME=" homedir)
- process-environment)))
- (require 'epg-config)
- (defvar epg-config--program-alist)
- (epg-find-configuration
- 'OpenPGP nil
- ;; By default we require gpg2 2.1+ due to some
- ;; practical problems with pinentry. But this
- ;; test works fine with 2.0 as well.
- (let ((prog-alist (copy-tree epg-config--program-alist)))
- (setf (alist-get "gpg2"
- (alist-get 'OpenPGP prog-alist)
- nil nil #'equal)
- "2.0")
- prog-alist)))
- (delete-directory homedir t))))
+ (skip-unless (ert-with-temp-directory homedir
+ (let ((process-environment
+ (cons (concat "HOME=" homedir)
+ process-environment)))
+ (require 'epg-config)
+ (defvar epg-config--program-alist)
+ (epg-find-configuration
+ 'OpenPGP nil
+ ;; By default we require gpg2 2.1+ due to some
+ ;; practical problems with pinentry. But this
+ ;; test works fine with 2.0 as well.
+ (let ((prog-alist (copy-tree epg-config--program-alist)))
+ (setf (alist-get "gpg2"
+ (alist-get 'OpenPGP prog-alist)
+ nil nil #'equal)
+ "2.0")
+ prog-alist)))))
(let* ((keyring (expand-file-name "key.pub" package-test-data-dir))
(package-test-data-dir (ert-resource-file "signed")))
(with-package-test ()
diff --git a/test/lisp/emacs-lisp/pp-resources/code-formats.erts b/test/lisp/emacs-lisp/pp-resources/code-formats.erts
new file mode 100644
index 00000000000..2b2001d0964
--- /dev/null
+++ b/test/lisp/emacs-lisp/pp-resources/code-formats.erts
@@ -0,0 +1,124 @@
+Code:
+ (lambda ()
+ (emacs-lisp-mode)
+ (let ((code (read (current-buffer))))
+ (erase-buffer)
+ (pp-emacs-lisp-code code)
+ (untabify (point-min) (point-max))))
+
+Name: code-formats1
+
+=-=
+(defun foo (bar)
+ "Yes."
+ (let ((a 1)
+ (b 2))
+ (zot 1 2 (funcall bar 2))))
+=-=-=
+
+
+Name: code-formats2
+
+=-=
+(defun pp-emacs-lisp-code (sexp)
+ "Insert SEXP into the current buffer, formatted as Emacs Lisp code."
+ (require 'edebug)
+ (let ((start (point))
+ (standard-output (current-buffer)))
+ (pp--insert-lisp sexp)
+ (insert "\n")
+ (goto-char start)
+ (indent-sexp)))
+=-=-=
+
+
+Name: code-formats3
+
+=-=
+(defun foo (bar)
+ "Yes."
+ (let ((a 1)
+ (b 2))
+ (zot-zot-zot-zot-zot-zot 1 2 (funcall
+ bar-bar-bar-bar-bar-bar-bar-bar-bar-bar
+ 2))))
+=-=-=
+
+
+Name: code-formats4
+
+=-=
+(defun foo (bar)
+ "Yes."
+ (let ((a 1)
+ (b 2)
+ foo bar zotfoo bar zotfoo bar zotfoo bar zotfoo bar zotfoo bar zotfoo
+ bar zot)
+ (zot 1 2 (funcall bar 2))))
+=-=-=
+
+
+Name: code-formats5
+
+=-=
+(defgroup pp ()
+ "Pretty printer for Emacs Lisp."
+ :prefix "pp-"
+ :group 'lisp)
+=-=-=
+
+Name: code-formats6
+
+=-=
+(defcustom pp-escape-newlines t
+ "Value of `print-escape-newlines' used by pp-* functions."
+ :type 'boolean
+ :group 'pp)
+=-=-=
+
+Name: code-formats7
+
+=-=
+(defun pp (object &optional stream)
+ (princ (pp-to-string object) (or stream standard-output)))
+=-=-=
+
+
+Name: code-formats8
+
+=-=
+(defun pp-eval-expression (expression)
+ "Evaluate EXPRESSION and pretty-print its value.
+Also add the value to the front of the list in the variable `values'."
+ (interactive (list (read--expression "Eval: ")))
+ (message "Evaluating...")
+ (let ((result (eval expression lexical-binding)))
+ (values--store-value result)
+ (pp-display-expression result "*Pp Eval Output*")))
+=-=-=
+
+Name: code-formats9
+
+=-=
+(lambda ()
+ (interactive)
+ 1)
+=-=-=
+
+
+Name: code-formats10
+
+=-=
+(funcall foo (concat "zot" (if (length> site 0) site
+ "bar")
+ "+"
+ (string-replace " " "+" query)))
+=-=-=
+
+
+Name: code-formats11
+
+=-=
+(lambda ()
+ [(foo bar) (foo bar)])
+=-=-=
diff --git a/test/lisp/emacs-lisp/pp-tests.el b/test/lisp/emacs-lisp/pp-tests.el
index b04030cc432..4cae1a73775 100644
--- a/test/lisp/emacs-lisp/pp-tests.el
+++ b/test/lisp/emacs-lisp/pp-tests.el
@@ -20,6 +20,7 @@
;;; Code:
(require 'pp)
+(require 'ert-x)
(ert-deftest pp-print-quote ()
(should (string= (pp-to-string 'quote) "quote"))
@@ -32,4 +33,7 @@
(should (string= (pp-to-string '(quotefoo)) "(quotefoo)\n"))
(should (string= (pp-to-string '(a b)) "(a b)\n")))
+(ert-deftest test-indentation ()
+ (ert-test-erts-file (ert-resource-file "code-formats.erts")))
+
;;; pp-tests.el ends here.
diff --git a/test/lisp/emacs-lisp/regexp-opt-tests.el b/test/lisp/emacs-lisp/regexp-opt-tests.el
index 940feb5e828..65494e20df6 100644
--- a/test/lisp/emacs-lisp/regexp-opt-tests.el
+++ b/test/lisp/emacs-lisp/regexp-opt-tests.el
@@ -66,4 +66,4 @@
(should (equal (regexp-opt-charset '()) regexp-unmatchable)))
-;;; regexp-tests.el ends here.
+;;; regexp-opt-tests.el ends here
diff --git a/test/lisp/emacs-lisp/ring-tests.el b/test/lisp/emacs-lisp/ring-tests.el
index 55df4f36685..3ec20a1e8ef 100644
--- a/test/lisp/emacs-lisp/ring-tests.el
+++ b/test/lisp/emacs-lisp/ring-tests.el
@@ -199,7 +199,7 @@
(should (= (ring-size ring) 3))
(should (equal (ring-elements ring) '(5 4 3)))))
-(ert-deftest ring-tests-insert ()
+(ert-deftest ring-tests-insert-2 ()
(let ((ring (make-ring 2)))
(ring-insert+extend ring :a)
(ring-insert+extend ring :b)
diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el
index 4828df0de92..3bc35feb6dd 100644
--- a/test/lisp/emacs-lisp/rx-tests.el
+++ b/test/lisp/emacs-lisp/rx-tests.el
@@ -17,6 +17,8 @@
;; 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 'rx)
@@ -583,3 +585,5 @@
"\\(?3:.+$\\)")))
(provide 'rx-tests)
+
+;;; rx-tests.el ends here
diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el
index 44e855e2cfa..4b940af81f1 100644
--- a/test/lisp/emacs-lisp/seq-tests.el
+++ b/test/lisp/emacs-lisp/seq-tests.el
@@ -173,16 +173,18 @@ Evaluate BODY for each created sequence.
(should (seq-find #'null '(1 2 3) 'sentinel)))
(ert-deftest test-seq-contains ()
- (with-test-sequences (seq '(3 4 5 6))
- (should (seq-contains seq 3))
- (should-not (seq-contains seq 7)))
- (with-test-sequences (seq '())
- (should-not (seq-contains seq 3))
- (should-not (seq-contains seq nil))))
+ (with-suppressed-warnings ((obsolete seq-contains))
+ (with-test-sequences (seq '(3 4 5 6))
+ (should (seq-contains seq 3))
+ (should-not (seq-contains seq 7)))
+ (with-test-sequences (seq '())
+ (should-not (seq-contains seq 3))
+ (should-not (seq-contains seq nil)))))
(ert-deftest test-seq-contains-should-return-the-elt ()
- (with-test-sequences (seq '(3 4 5 6))
- (should (= 5 (seq-contains seq 5)))))
+ (with-suppressed-warnings ((obsolete seq-contains))
+ (with-test-sequences (seq '(3 4 5 6))
+ (should (= 5 (seq-contains seq 5))))))
(ert-deftest test-seq-contains-p ()
(with-test-sequences (seq '(3 4 5 6))
@@ -336,6 +338,33 @@ Evaluate BODY for each created sequence.
(should (same-contents-p list vector))
(should (vectorp vector))))
+(ert-deftest test-seq-union ()
+ (let ((v1 '(1 2 3))
+ (v2 '(3 5)))
+ (should (same-contents-p (seq-union v1 v2)
+ '(1 2 3 5))))
+
+ (let ((v1 '(1 2 3 4 5 6))
+ (v2 '(4 5 6 7 8 9)))
+ (should (same-contents-p (seq-union v1 v2)
+ '(1 2 3 4 5 6 7 8 9))))
+
+ (let ((v1 [1 2 3 4 5])
+ (v2 [4 5 6 "a"]))
+ (should (same-contents-p (seq-union v1 v2)
+ '(1 2 3 4 5 6 "a"))))
+
+ (let ((v1 '("a" "b" "c"))
+ (v2 '("f" "c" "e" "a")))
+ (should (same-contents-p (seq-union v1 v2)
+ '("a" "b" "c" "f" "e"))))
+
+ (let ((v1 '("a"))
+ (v2 '("a"))
+ (testfn #'eq))
+ (should (same-contents-p (seq-union v1 v2 testfn)
+ '("a" "a")))))
+
(ert-deftest test-seq-intersection ()
(let ((v1 [2 3 4 5])
(v2 [1 3 5 6 7]))
@@ -377,7 +406,7 @@ Evaluate BODY for each created sequence.
(let ((seq '(1 (2 (3 (4))))))
(seq-let (_ (_ (_ (a)))) seq
(should (= a 4))))
- (let (seq)
+ (let ((seq nil))
(seq-let (a b c) seq
(should (null a))
(should (null b))
@@ -401,7 +430,7 @@ Evaluate BODY for each created sequence.
(seq '(1 (2 (3 (4))))))
(seq-setq (_ (_ (_ (a)))) seq)
(should (= a 4)))
- (let (seq a b c)
+ (let ((seq nil) a b c)
(seq-setq (a b c) seq)
(should (null a))
(should (null b))
diff --git a/test/lisp/emacs-lisp/shortdoc-tests.el b/test/lisp/emacs-lisp/shortdoc-tests.el
index 3bb3185649b..cfb0b4244bc 100644
--- a/test/lisp/emacs-lisp/shortdoc-tests.el
+++ b/test/lisp/emacs-lisp/shortdoc-tests.el
@@ -17,6 +17,8 @@
;; 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 'shortdoc)
@@ -43,3 +45,5 @@
(setq props (cddr props))))))))
(provide 'shortdoc-tests)
+
+;;; shortdoc-tests.el ends here
diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el
index ef04cde3867..821b6770ba0 100644
--- a/test/lisp/emacs-lisp/subr-x-tests.el
+++ b/test/lisp/emacs-lisp/subr-x-tests.el
@@ -169,13 +169,13 @@
"no")
"no"))
(should (equal
- (let (z)
+ (let ((z nil))
(if-let* (z (a 1) (b 2) (c 3))
"yes"
"no"))
"no"))
(should (equal
- (let (d)
+ (let ((d nil))
(if-let* ((a 1) (b 2) (c 3) d)
"yes"
"no"))
@@ -191,7 +191,7 @@
(ert-deftest subr-x-test-if-let*-and-laziness-is-preserved ()
"Test `if-let' respects `and' laziness."
- (let (a-called b-called c-called)
+ (let ((a-called nil) (b-called nil) c-called)
(should (equal
(if-let* ((a nil)
(b (setq b-called t))
@@ -199,7 +199,7 @@
"yes"
(list a-called b-called c-called))
(list nil nil nil))))
- (let (a-called b-called c-called)
+ (let ((a-called nil) (b-called nil) c-called)
(should (equal
(if-let* ((a (setq a-called t))
(b nil)
@@ -207,12 +207,12 @@
"yes"
(list a-called b-called c-called))
(list t nil nil))))
- (let (a-called b-called c-called)
+ (let ((a-called nil) (b-called nil) c-called)
(should (equal
(if-let* ((a (setq a-called t))
- (b (setq b-called t))
- (c nil)
- (d (setq c-called t)))
+ (b (setq b-called t))
+ (c nil)
+ (d (setq c-called t)))
"yes"
(list a-called b-called c-called))
(list t t nil)))))
@@ -329,12 +329,12 @@
"no")
nil))
(should (equal
- (let (z)
+ (let ((z nil))
(when-let* (z (a 1) (b 2) (c 3))
"no"))
nil))
(should (equal
- (let (d)
+ (let ((d nil))
(when-let* ((a 1) (b 2) (c 3) d)
"no"))
nil)))
@@ -348,7 +348,7 @@
(ert-deftest subr-x-test-when-let*-and-laziness-is-preserved ()
"Test `when-let' respects `and' laziness."
- (let (a-called b-called c-called)
+ (let ((a-called nil) (b-called nil) (c-called nil))
(should (equal
(progn
(when-let* ((a nil)
@@ -357,7 +357,7 @@
"yes")
(list a-called b-called c-called))
(list nil nil nil))))
- (let (a-called b-called c-called)
+ (let ((a-called nil) (b-called nil) (c-called nil))
(should (equal
(progn
(when-let* ((a (setq a-called t))
@@ -366,7 +366,7 @@
"yes")
(list a-called b-called c-called))
(list t nil nil))))
- (let (a-called b-called c-called)
+ (let ((a-called nil) (b-called nil) (c-called nil))
(should (equal
(progn
(when-let* ((a (setq a-called t))
@@ -455,18 +455,18 @@
"Test `thread-first' wraps single function names."
(should (equal (macroexpand
'(thread-first 5
- -))
+ -))
'(- 5)))
(should (equal (macroexpand
'(thread-first (+ 1 2)
- -))
+ -))
'(- (+ 1 2)))))
(ert-deftest subr-x-test-thread-first-expansion ()
"Test `thread-first' expands correctly."
(should (equal
(macroexpand '(thread-first
- 5
+ 5
(+ 20)
(/ 25)
-
@@ -477,13 +477,13 @@
"Test several `thread-first' examples."
(should (equal (thread-first (+ 40 2)) 42))
(should (equal (thread-first
- 5
+ 5
(+ 20)
(/ 25)
-
(+ 40)) 39))
(should (equal (thread-first
- "this-is-a-string"
+ "this-is-a-string"
(split-string "-")
(nbutlast 2)
(append (list "good")))
@@ -500,18 +500,18 @@
"Test `thread-last' wraps single function names."
(should (equal (macroexpand
'(thread-last 5
- -))
+ -))
'(- 5)))
(should (equal (macroexpand
'(thread-last (+ 1 2)
- -))
+ -))
'(- (+ 1 2)))))
(ert-deftest subr-x-test-thread-last-expansion ()
"Test `thread-last' expands correctly."
(should (equal
(macroexpand '(thread-last
- 5
+ 5
(+ 20)
(/ 25)
-
@@ -522,13 +522,13 @@
"Test several `thread-last' examples."
(should (equal (thread-last (+ 40 2)) 42))
(should (equal (thread-last
- 5
+ 5
(+ 20)
(/ 25)
-
(+ 40)) 39))
(should (equal (thread-last
- (list 1 -2 3 -4 5)
+ (list 1 -2 3 -4 5)
(mapcar #'abs)
(cl-reduce #'+)
(format "abs sum is: %s"))
@@ -638,5 +638,79 @@
(should (equal (string-chop-newline "foo\nbar\n") "foo\nbar"))
(should (equal (string-chop-newline "foo\nbar") "foo\nbar")))
+(ert-deftest subr-ensure-empty-lines ()
+ (should
+ (equal
+ (with-temp-buffer
+ (insert "foo")
+ (goto-char (point-min))
+ (ensure-empty-lines 2)
+ (buffer-string))
+ "\n\nfoo"))
+ (should
+ (equal
+ (with-temp-buffer
+ (insert "foo")
+ (ensure-empty-lines 2)
+ (buffer-string))
+ "foo\n\n\n"))
+ (should
+ (equal
+ (with-temp-buffer
+ (insert "foo\n")
+ (ensure-empty-lines 2)
+ (buffer-string))
+ "foo\n\n\n"))
+ (should
+ (equal
+ (with-temp-buffer
+ (insert "foo\n\n\n\n\n")
+ (ensure-empty-lines 2)
+ (buffer-string))
+ "foo\n\n\n"))
+ (should
+ (equal
+ (with-temp-buffer
+ (insert "foo\n\n\n")
+ (ensure-empty-lines 0)
+ (buffer-string))
+ "foo\n")))
+
+(ert-deftest subr-x-test-add-display-text-property ()
+ (with-temp-buffer
+ (insert "Foo bar zot gazonk")
+ (add-display-text-property 4 8 'height 2.0)
+ (add-display-text-property 2 12 'raise 0.5)
+ (should (equal (get-text-property 2 'display) '(raise 0.5)))
+ (should (equal (get-text-property 5 'display)
+ '((raise 0.5) (height 2.0))))
+ (should (equal (get-text-property 9 'display) '(raise 0.5))))
+ (with-temp-buffer
+ (insert "Foo bar zot gazonk")
+ (put-text-property 4 8 'display [(height 2.0)])
+ (add-display-text-property 2 12 'raise 0.5)
+ (should (equal (get-text-property 2 'display) '(raise 0.5)))
+ (should (equal (get-text-property 5 'display)
+ [(raise 0.5) (height 2.0)]))
+ (should (equal (get-text-property 9 'display) '(raise 0.5)))))
+
+(ert-deftest subr-x-named-let ()
+ (let ((funs ()))
+ (named-let loop
+ ((rest '(1 42 3))
+ (sum 0))
+ (when rest
+ ;; Here, we make sure that the variables are distinct in every
+ ;; iteration, since a naive tail-call optimization would tend to end up
+ ;; with a single `sum' variable being shared by all the closures.
+ (push (lambda () sum) funs)
+ ;; Here we add a dummy `sum' variable which shadows the `sum' iteration
+ ;; variable since a naive tail-call optimization could also trip here
+ ;; thinking it can `(setq sum ...)' to set the iteration
+ ;; variable's value.
+ (let ((sum sum))
+ (loop (cdr rest) (+ sum (car rest))))))
+ (should (equal (mapcar #'funcall funs) '(43 1 0)))))
+
(provide 'subr-x-tests)
;;; subr-x-tests.el ends here
diff --git a/test/lisp/emacs-lisp/tabulated-list-test.el b/test/lisp/emacs-lisp/tabulated-list-tests.el
index db1ce312586..e376d2f328d 100644
--- a/test/lisp/emacs-lisp/tabulated-list-test.el
+++ b/test/lisp/emacs-lisp/tabulated-list-tests.el
@@ -1,4 +1,4 @@
-;;; tabulated-list-test.el --- Tests for emacs-lisp/tabulated-list.el -*- lexical-binding: t; -*-
+;;; tabulated-list-tests.el --- Tests for emacs-lisp/tabulated-list.el -*- lexical-binding: t; -*-
;; Copyright (C) 2015-2021 Free Software Foundation, Inc.
@@ -56,10 +56,10 @@
(tabulated-list--test-with-buffer
;; Basic printing.
(should (string= (buffer-substring-no-properties (point-min) (point-max))
- " zzzz-game zzzz-game 2113 installed play zzzz in Emacs
- 4clojure 4clojure 1507 obsolete Open and evaluate 4clojure.com questions
- abc-mode abc-mode 944 available Major mode for editing abc music files
- mode mode 1128 installed A simple mode for editing Actionscript 3 files\n"))
+ " zzzz-game zzzz-game 2113 installed play zzzz in Emacs
+ 4clojure 4clojure 1507 obsolete Open and evaluate 4clojure.com questions
+ abc-mode abc-mode 944 available Major mode for editing abc music files
+ mode mode 1128 installed A simple mode for editing Actionscript 3 files\n"))
;; Preserve position.
(forward-line 3)
(let ((pos (thing-at-point 'line)))
@@ -67,16 +67,16 @@
(tabulated-list-print t)
(should (equal (thing-at-point 'line) pos))
(should (string= (buffer-substring-no-properties (point-min) (point-max))
- " 4clojure 4clojure 1507 obsolete Open and evaluate 4clojure.com questions
- abc-mode abc-mode 944 available Major mode for editing abc music files
- mode mode 1128 installed A simple mode for editing Actionscript 3 files\n"))
+ " 4clojure 4clojure 1507 obsolete Open and evaluate 4clojure.com questions
+ abc-mode abc-mode 944 available Major mode for editing abc music files
+ mode mode 1128 installed A simple mode for editing Actionscript 3 files\n"))
;; Check the UPDATE argument
(pop tabulated-list-entries)
(setf (cdr (car tabulated-list-entries)) (list ["x" "x" "944" "available" " XX"]))
(tabulated-list-print t t)
(should (string= (buffer-substring-no-properties (point-min) (point-max))
- " x x 944 available XX
- mode mode 1128 installed A simple mode for editing Actionscript 3 files\n"))
+ " x x 944 available XX
+ mode mode 1128 installed A simple mode for editing Actionscript 3 files\n"))
(should (equal (thing-at-point 'line) pos)))))
(ert-deftest tabulated-list-sort ()
@@ -86,25 +86,26 @@
(skip-chars-forward "[:blank:]")
(tabulated-list-sort)
(let ((text (buffer-substring-no-properties (point-min) (point-max))))
- (should (string= text " 4clojure 4clojure 1507 obsolete Open and evaluate 4clojure.com questions
- abc-mode abc-mode 944 available Major mode for editing abc music files
- mode mode 1128 installed A simple mode for editing Actionscript 3 files
- zzzz-game zzzz-game 2113 installed play zzzz in Emacs\n"))
+ (should (string= text
+ " 4clojure 4clojure 1507 obsolete Open and evaluate 4clojure.com questions
+ abc-mode abc-mode 944 available Major mode for editing abc music files
+ mode mode 1128 installed A simple mode for editing Actionscript 3 files
+ zzzz-game zzzz-game 2113 installed play zzzz in Emacs\n"))
(skip-chars-forward "^[:blank:]")
(skip-chars-forward "[:blank:]")
(should (equal (get-text-property (point) 'tabulated-list-column-name)
"name-2"))
(tabulated-list-sort)
- ;; Check a `t' as the sorting predicate.
+ ;; Check a t as the sorting predicate.
(should (string= text (buffer-substring-no-properties (point-min) (point-max))))
;; Invert.
(tabulated-list-sort 1)
(should (string= (buffer-substring-no-properties (point-min) (point-max))
- " zzzz-game zzzz-game 2113 installed play zzzz in Emacs
- mode mode 1128 installed A simple mode for editing Actionscript 3 files
- abc-mode abc-mode 944 available Major mode for editing abc music files
- 4clojure 4clojure 1507 obsolete Open and evaluate 4clojure.com questions\n"))
+ " zzzz-game zzzz-game 2113 installed play zzzz in Emacs
+ mode mode 1128 installed A simple mode for editing Actionscript 3 files
+ abc-mode abc-mode 944 available Major mode for editing abc music files
+ 4clojure 4clojure 1507 obsolete Open and evaluate 4clojure.com questions\n"))
;; Again
(tabulated-list-sort 1)
(should (string= text (buffer-substring-no-properties (point-min) (point-max)))))
@@ -114,5 +115,4 @@
(should-error (tabulated-list-sort) :type 'user-error)
(should-error (tabulated-list-sort 4) :type 'user-error)))
-(provide 'tabulated-list-test)
-;;; tabulated-list-test.el ends here
+;;; tabulated-list-tests.el ends here
diff --git a/test/lisp/emacs-lisp/testcover-resources/testcases.el b/test/lisp/emacs-lisp/testcover-resources/testcases.el
index 7ced257c6f9..4d49e5ae70c 100644
--- a/test/lisp/emacs-lisp/testcover-resources/testcases.el
+++ b/test/lisp/emacs-lisp/testcover-resources/testcases.el
@@ -77,12 +77,12 @@
"Testcover doesn't prevent testing of defcustom values."
;; ====
(defgroup testcover-testcase nil
- "Test case for testcover"
+ "Test case for testcover."
:group 'lisp
:prefix "testcover-testcase-"
:version "26.0")
(defcustom testcover-testcase-flag t
- "Test value used by testcover-tests.el"
+ "Test value used by testcover-tests.el."
:type 'boolean
:group 'testcover-testcase)
(defun testcover-testcase-get-flag ()
@@ -111,7 +111,7 @@
"Wrapping a form with noreturn prevents splotching."
;; ====
(defun testcover-testcase-cancel (spacecraft)
- (error "no destination for %s" spacecraft))
+ (error "No destination for %s" spacecraft))
(defun testcover-testcase-launch (spacecraft planet)
(if (null planet)
(noreturn (testcover-testcase-cancel spacecraft%%%))
@@ -220,7 +220,7 @@
(defun testcover-testcase-cc (arg)
(condition-case nil
(if (null arg%%%)%%%
- (error "foo")
+ (error "Foo")
"0")!!!
(error nil)))
(should-not (testcover-testcase-cc nil))
@@ -424,7 +424,7 @@
(defmacro testcover-testcase-nth-case (arg vec)
(declare (indent 1)
(debug (form (vector &rest form))))
- `(eval (aref ,vec%%% ,arg%%%))%%%)
+ `(eval (aref ,vec%%% ,arg%%%) t)%%%)
(defun testcover-testcase-use-nth-case (choice val)
(testcover-testcase-nth-case choice
@@ -510,4 +510,4 @@ regarding the odd-looking coverage result for the quoted form."
(testcover-testcase-cyc2 1 2)
(testcover-testcase-cyc2 1 4)
-;; testcases.el ends here.
+;;; testcases.el ends here
diff --git a/test/lisp/emacs-lisp/testcover-tests.el b/test/lisp/emacs-lisp/testcover-tests.el
index 7854e33e77d..a7e055a28b1 100644
--- a/test/lisp/emacs-lisp/testcover-tests.el
+++ b/test/lisp/emacs-lisp/testcover-tests.el
@@ -45,34 +45,34 @@ testcases.el. This can be used to create test cases if Testcover
is working correctly on a code sample. OPTARGS are optional
arguments for `testcover-start'."
(interactive "r")
- (let ((tempfile (make-temp-file "testcover-tests-" nil ".el"))
- (find-file-suppress-same-file-warnings t)
- (code (buffer-substring beg end))
- (marked-up-code))
- (unwind-protect
- (progn
- (with-temp-file tempfile
- (insert code))
- (save-current-buffer
- (let ((buf (find-file-noselect tempfile)))
- (set-buffer buf)
- (apply 'testcover-start (cons tempfile optargs))
- (testcover-mark-all buf)
- (dolist (overlay (overlays-in (point-min) (point-max)))
- (let ((ov-face (overlay-get overlay 'face)))
- (goto-char (overlay-end overlay))
- (cond
- ((eq ov-face 'testcover-nohits) (insert "!!!"))
- ((eq ov-face 'testcover-1value) (insert "%%%"))
- (t nil))))
- (setq marked-up-code (buffer-string)))
- (set-buffer-modified-p nil)))
- (ignore-errors (kill-buffer (find-file-noselect tempfile)))
- (ignore-errors (delete-file tempfile)))
-
- ;; Now replace the original code with the marked up code.
- (delete-region beg end)
- (insert marked-up-code))))
+ (ert-with-temp-file tempfile
+ :suffix ".el"
+ (let ((find-file-suppress-same-file-warnings t)
+ (code (buffer-substring beg end))
+ (marked-up-code))
+ (unwind-protect
+ (progn
+ (with-temp-file tempfile
+ (insert code))
+ (save-current-buffer
+ (let ((buf (find-file-noselect tempfile)))
+ (set-buffer buf)
+ (apply 'testcover-start (cons tempfile optargs))
+ (testcover-mark-all buf)
+ (dolist (overlay (overlays-in (point-min) (point-max)))
+ (let ((ov-face (overlay-get overlay 'face)))
+ (goto-char (overlay-end overlay))
+ (cond
+ ((eq ov-face 'testcover-nohits) (insert "!!!"))
+ ((eq ov-face 'testcover-1value) (insert "%%%"))
+ (t nil))))
+ (setq marked-up-code (buffer-string)))
+ (set-buffer-modified-p nil)))
+ (ignore-errors (kill-buffer (find-file-noselect tempfile))))
+
+ ;; Now replace the original code with the marked up code.
+ (delete-region beg end)
+ (insert marked-up-code)))))
(eval-and-compile
(defun testcover-tests-unmarkup-region (beg end)
@@ -99,32 +99,32 @@ arguments for `testcover-start'."
(eval-and-compile
(defun testcover-tests-run-test-case (marked-up-code)
"Test the operation of Testcover on the string MARKED-UP-CODE."
- (let ((tempfile (make-temp-file "testcover-tests-" nil ".el"))
- (find-file-suppress-same-file-warnings t))
- (unwind-protect
- (progn
- (with-temp-file tempfile
- (insert marked-up-code))
- ;; Remove the marks and mark the code up again. The original
- ;; and recreated versions should match.
- (save-current-buffer
- (set-buffer (find-file-noselect tempfile))
- ;; Fail the test if the debugger tries to become active,
- ;; which can happen if Testcover fails to attach itself
- ;; correctly. Note that this will prevent debugging
- ;; these tests using Edebug.
- (cl-letf (((symbol-function #'edebug-default-enter)
- (lambda (&rest _args)
- (ert-fail "Debugger invoked during test run"))))
- (dolist (byte-compile '(t nil))
- (testcover-tests-unmarkup-region (point-min) (point-max))
- (unwind-protect
- (testcover-tests-markup-region (point-min) (point-max) byte-compile)
- (set-buffer-modified-p nil))
- (should (string= marked-up-code
- (buffer-string)))))))
- (ignore-errors (kill-buffer (find-file-noselect tempfile)))
- (ignore-errors (delete-file tempfile))))))
+ (ert-with-temp-file tempfile
+ :suffix ".el"
+ (let ((find-file-suppress-same-file-warnings t))
+ (unwind-protect
+ (progn
+ (with-temp-file tempfile
+ (insert marked-up-code))
+ ;; Remove the marks and mark the code up again. The original
+ ;; and recreated versions should match.
+ (save-current-buffer
+ (set-buffer (find-file-noselect tempfile))
+ ;; Fail the test if the debugger tries to become active,
+ ;; which can happen if Testcover fails to attach itself
+ ;; correctly. Note that this will prevent debugging
+ ;; these tests using Edebug.
+ (cl-letf (((symbol-function #'edebug-default-enter)
+ (lambda (&rest _args)
+ (ert-fail "Debugger invoked during test run"))))
+ (dolist (byte-compile '(t nil))
+ (testcover-tests-unmarkup-region (point-min) (point-max))
+ (unwind-protect
+ (testcover-tests-markup-region (point-min) (point-max) byte-compile)
+ (set-buffer-modified-p nil))
+ (should (string= marked-up-code
+ (buffer-string)))))))
+ (ignore-errors (kill-buffer (find-file-noselect tempfile))))))))
;; Convert test case file to ert-defmethod.
diff --git a/test/lisp/emacs-lisp/timer-tests.el b/test/lisp/emacs-lisp/timer-tests.el
index 7856c217f9e..0f5b1a71868 100644
--- a/test/lisp/emacs-lisp/timer-tests.el
+++ b/test/lisp/emacs-lisp/timer-tests.el
@@ -37,7 +37,8 @@
(ert-deftest timer-tests-debug-timer-check ()
;; This function exists only if --enable-checking.
(skip-unless (fboundp 'debug-timer-check))
- (should (debug-timer-check)))
+ (when (fboundp 'debug-timer-check) ; silence byte-compiler
+ (should (debug-timer-check))))
(ert-deftest timer-test-multiple-of-time ()
(should (time-equal-p
diff --git a/test/lisp/emacs-lisp/unsafep-tests.el b/test/lisp/emacs-lisp/unsafep-tests.el
index b2a48d80675..f0d9b032438 100644
--- a/test/lisp/emacs-lisp/unsafep-tests.el
+++ b/test/lisp/emacs-lisp/unsafep-tests.el
@@ -105,7 +105,7 @@
. (variable (x)))
( (let (1) 2)
. (variable 1))
- ( (error "asdf")
+ ( (error "Asdf")
. #'error)
( (signal 'error "asdf")
. #'signal)
diff --git a/test/lisp/emulation/viper-tests.el b/test/lisp/emulation/viper-tests.el
index 0d999763b61..b8efc87ab70 100644
--- a/test/lisp/emulation/viper-tests.el
+++ b/test/lisp/emulation/viper-tests.el
@@ -21,7 +21,8 @@
;;; Code:
-
+(require 'ert)
+(require 'ert-x)
(require 'viper)
(defun viper-test-undo-kmacro (kmacro)
@@ -30,47 +31,42 @@
This function makes as many attempts as possible to clean up
after itself, although it will leave a buffer called
*viper-test-buffer* if it fails (this is deliberate!)."
- (let (
- ;; Viper just turns itself off during batch use.
- (noninteractive nil)
- ;; Switch off start up message or it will chew the key presses.
- (viper-inhibit-startup-message 't)
- ;; Select an expert-level for the same reason.
- (viper-expert-level 5)
- ;; viper loads this even with -q so make sure it's empty!
- (viper-custom-file-name (make-temp-file "viper-tests" nil ".elc"))
- (before-buffer (current-buffer)))
- (unwind-protect
- (progn
- ;; viper-mode is essentially global, so set it here.
- (viper-mode)
- ;; We must switch to buffer because we are using a keyboard macro
- ;; which appears to not go to the current-buffer but what ever is
- ;; currently taking keyboard events. We use a named buffer because
- ;; then we can see what it in it if it all goes wrong.
- (switch-to-buffer
- (get-buffer-create
- "*viper-test-buffer*"))
- (erase-buffer)
- ;; The new buffer fails to enter vi state so set it.
- (viper-change-state-to-vi)
- ;; Run the macro.
- (execute-kbd-macro kmacro)
- (let ((rtn
- (buffer-substring-no-properties
- (point-min)
- (point-max))))
- ;; Kill the buffer iff the macro succeeds.
- (kill-buffer)
- rtn))
- ;; Switch everything off and restore the buffer.
- (toggle-viper-mode)
- (delete-file viper-custom-file-name)
- (switch-to-buffer before-buffer))))
-
-(ert-deftest viper-test-go ()
- "Test that this file is running."
- (should t))
+ (ert-with-temp-file viper-custom-file-name
+ ;; viper loads this even with -q so make sure it's empty!
+ :prefix "emacs-viper-tests" :suffix ".elc"
+ (let (;; Viper just turns itself off during batch use.
+ (noninteractive nil)
+ ;; Switch off start up message or it will chew the key presses.
+ (viper-inhibit-startup-message 't)
+ ;; Select an expert-level for the same reason.
+ (viper-expert-level 5)
+ (before-buffer (current-buffer)))
+ (unwind-protect
+ (progn
+ ;; viper-mode is essentially global, so set it here.
+ (viper-mode)
+ ;; We must switch to buffer because we are using a keyboard macro
+ ;; which appears to not go to the current-buffer but what ever is
+ ;; currently taking keyboard events. We use a named buffer because
+ ;; then we can see what it in it if it all goes wrong.
+ (switch-to-buffer
+ (get-buffer-create
+ "*viper-test-buffer*"))
+ (erase-buffer)
+ ;; The new buffer fails to enter vi state so set it.
+ (viper-change-state-to-vi)
+ ;; Run the macro.
+ (execute-kbd-macro kmacro)
+ (let ((rtn
+ (buffer-substring-no-properties
+ (point-min)
+ (point-max))))
+ ;; Kill the buffer iff the macro succeeds.
+ (kill-buffer)
+ rtn))
+ ;; Switch everything off and restore the buffer.
+ (toggle-viper-mode)
+ (switch-to-buffer before-buffer)))))
(ert-deftest viper-test-fix ()
"Test that the viper kmacro fixture is working."
diff --git a/test/lisp/epg-tests.el b/test/lisp/epg-tests.el
index 741574f0adf..1384221c491 100644
--- a/test/lisp/epg-tests.el
+++ b/test/lisp/epg-tests.el
@@ -58,48 +58,45 @@
(cl-defmacro with-epg-tests ((&optional &key require-passphrase
require-public-key
require-secret-key)
- &rest body)
+ &rest body)
"Set up temporary locations and variables for testing."
(declare (indent 1) (debug (sexp body)))
- `(let* ((epg-tests-home-directory (make-temp-file "epg-tests-homedir" t))
- (process-environment
- (append
- (list "GPG_AGENT_INFO"
- (format "GNUPGHOME=%s" epg-tests-home-directory))
- process-environment)))
- (unwind-protect
- ;; GNUPGHOME is needed to find a usable gpg, so we can't
- ;; check whether to skip any earlier (Bug#23561).
- (let ((epg-config (or (epg-tests-find-usable-gpg-configuration
- ,require-passphrase ,require-public-key)
- (ert-skip "No usable gpg config")))
- (context (epg-make-context 'OpenPGP)))
- (setf (epg-context-program context)
- (alist-get 'program epg-config))
- (setf (epg-context-home-directory context)
- epg-tests-home-directory)
- ,(if require-passphrase
- '(with-temp-file (expand-file-name
- "gpg-agent.conf" epg-tests-home-directory)
- (insert "pinentry-program "
- (ert-resource-file "dummy-pinentry")
- "\n")
- (epg-context-set-passphrase-callback
- context
- #'epg-tests-passphrase-callback)))
- ,(if require-public-key
- '(epg-import-keys-from-file
- context
- (ert-resource-file "pubkey.asc")))
- ,(if require-secret-key
- '(epg-import-keys-from-file
- context
- (ert-resource-file "seckey.asc")))
- (with-temp-buffer
- (setq-local epg-tests-context context)
- ,@body))
- (when (file-directory-p epg-tests-home-directory)
- (delete-directory epg-tests-home-directory t)))))
+ `(ert-with-temp-directory epg-tests-home-directory
+ (let* ((process-environment
+ (append
+ (list "GPG_AGENT_INFO"
+ (format "GNUPGHOME=%s" epg-tests-home-directory))
+ process-environment)))
+ ;; GNUPGHOME is needed to find a usable gpg, so we can't
+ ;; check whether to skip any earlier (Bug#23561).
+ (let ((epg-config (or (epg-tests-find-usable-gpg-configuration
+ ,require-passphrase ,require-public-key)
+ (ert-skip "No usable gpg config")))
+ (context (epg-make-context 'OpenPGP)))
+ (setf (epg-context-program context)
+ (alist-get 'program epg-config))
+ (setf (epg-context-home-directory context)
+ epg-tests-home-directory)
+ ,(if require-passphrase
+ '(with-temp-file (expand-file-name
+ "gpg-agent.conf" epg-tests-home-directory)
+ (insert "pinentry-program "
+ (ert-resource-file "dummy-pinentry")
+ "\n")
+ (epg-context-set-passphrase-callback
+ context
+ #'epg-tests-passphrase-callback)))
+ ,(if require-public-key
+ '(epg-import-keys-from-file
+ context
+ (ert-resource-file "pubkey.asc")))
+ ,(if require-secret-key
+ '(epg-import-keys-from-file
+ context
+ (ert-resource-file "seckey.asc")))
+ (with-temp-buffer
+ (setq-local epg-tests-context context)
+ ,@body)))))
(ert-deftest epg-decrypt-1 ()
:expected-result (if (getenv "EMACS_HYDRA_CI") :failed :passed) ; fixme
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index d13397274aa..b2dbc1012de 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -24,6 +24,7 @@
(require 'ert)
(require 'erc)
(require 'erc-ring)
+(require 'erc-networks)
(ert-deftest erc--read-time-period ()
(cl-letf (((symbol-function 'read-string) (lambda (&rest _) "")))
@@ -47,6 +48,85 @@
(cl-letf (((symbol-function 'read-string) (lambda (&rest _) "1d")))
(should (equal (erc--read-time-period "foo: ") 86400))))
+(ert-deftest erc-with-all-buffers-of-server ()
+ (let (proc-exnet
+ proc-onet
+ erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook)
+
+ (with-current-buffer (get-buffer-create "OtherNet")
+ (erc-mode)
+ (setq proc-onet (start-process "sleep" (current-buffer) "sleep" "1")
+ erc-server-process proc-onet
+ erc-network 'OtherNet)
+ (set-process-query-on-exit-flag erc-server-process nil))
+
+ (with-current-buffer (get-buffer-create "ExampleNet")
+ (erc-mode)
+ (setq proc-exnet (start-process "sleep" (current-buffer) "sleep" "1")
+ erc-server-process proc-exnet
+ erc-network 'ExampleNet)
+ (set-process-query-on-exit-flag erc-server-process nil))
+
+ (with-current-buffer (get-buffer-create "#foo")
+ (erc-mode)
+ (setq erc-server-process proc-exnet)
+ (setq erc-default-recipients '("#foo")))
+
+ (with-current-buffer (get-buffer-create "#spam")
+ (erc-mode)
+ (setq erc-server-process proc-onet)
+ (setq erc-default-recipients '("#spam")))
+
+ (with-current-buffer (get-buffer-create "#bar")
+ (erc-mode)
+ (setq erc-server-process proc-onet)
+ (setq erc-default-recipients '("#bar")))
+
+ (with-current-buffer (get-buffer-create "#baz")
+ (erc-mode)
+ (setq erc-server-process proc-exnet)
+ (setq erc-default-recipients '("#baz")))
+
+ (should (eq (get-buffer-process "ExampleNet") proc-exnet))
+ (erc-with-all-buffers-of-server (get-buffer-process "ExampleNet")
+ nil
+ (kill-buffer))
+
+ (should-not (get-buffer "ExampleNet"))
+ (should-not (get-buffer "#foo"))
+ (should-not (get-buffer "#baz"))
+ (should (get-buffer "OtherNet"))
+ (should (get-buffer "#bar"))
+ (should (get-buffer "#spam"))
+
+ (let* ((test (lambda () (not (string= (buffer-name) "#spam"))))
+ (calls 0)
+ (get-test (lambda () (cl-incf calls) test)))
+
+ (erc-with-all-buffers-of-server proc-onet
+ (funcall get-test)
+ (kill-buffer))
+
+ (should (= calls 1)))
+
+ (should-not (get-buffer "OtherNet"))
+ (should-not (get-buffer "#bar"))
+ (should (get-buffer "#spam"))
+ (kill-buffer "#spam")))
+
+(ert-deftest erc-lurker-maybe-trim ()
+ (let (erc-lurker-trim-nicks
+ (erc-lurker-ignore-chars "_`"))
+
+ (should (string= "nick`" (erc-lurker-maybe-trim "nick`")))
+
+ (setq erc-lurker-trim-nicks t)
+ (should (string= "nick" (erc-lurker-maybe-trim "nick`")))
+ (should (string= "ni`_ck" (erc-lurker-maybe-trim "ni`_ck__``")))
+
+ (setq erc-lurker-ignore-chars "_-`") ; set of chars, not character alts
+ (should (string= "nick" (erc-lurker-maybe-trim "nick-_`")))))
+
(ert-deftest erc-ring-previous-command-base-case ()
(ert-info ("Create ring when nonexistent and do nothing")
(let (erc-input-ring
@@ -61,13 +141,16 @@
(with-current-buffer (get-buffer-create "*#fake*")
(erc-mode)
(insert "\n\n")
- (setq erc-input-marker (make-marker) ; these are all local
- erc-insert-marker (make-marker)
- erc-send-completed-hook nil)
+ (should-not (local-variable-if-set-p 'erc-send-completed-hook))
+ (set (make-local-variable 'erc-send-completed-hook) nil) ; skip t (globals)
+ (setq erc-input-marker (make-marker)
+ erc-insert-marker (make-marker))
(set-marker erc-insert-marker (point-max))
(erc-display-prompt)
(should (= (point) erc-input-marker))
- (add-hook 'erc-pre-send-functions #'erc-add-to-input-ring nil t)
+ ;; Just in case erc-ring-mode is already on
+ (setq-local erc-pre-send-functions nil)
+ (add-hook 'erc-pre-send-functions #'erc-add-to-input-ring)
;;
(cl-letf (((symbol-function 'erc-process-input-line)
(lambda (&rest _)
@@ -109,3 +192,111 @@
(should (looking-at "abc")))))
(when noninteractive
(kill-buffer "*#fake*")))
+
+(ert-deftest erc-log-irc-protocol ()
+ (should-not erc-debug-irc-protocol)
+ (with-temp-buffer
+ (setq erc-server-process (start-process "fake" (current-buffer) "true")
+ erc-server-current-nick "tester"
+ erc-session-server "myproxy.localhost"
+ erc-session-port 6667)
+ (let ((inhibit-message noninteractive))
+ (erc-toggle-debug-irc-protocol)
+ (erc-log-irc-protocol "PASS changeme\r\n" 'outgoing)
+ (setq erc-server-announced-name "irc.gnu.org")
+ (erc-log-irc-protocol ":irc.gnu.org 001 tester :Welcome")
+ (erc-log-irc-protocol ":irc.gnu.org 002 tester :Your host is irc.gnu.org")
+ (setq erc-network 'FooNet)
+ (erc-log-irc-protocol ":irc.gnu.org 422 tester :MOTD missing")
+ (setq erc-network 'BarNet)
+ (erc-log-irc-protocol ":irc.gnu.org 221 tester +i")
+ (set-process-query-on-exit-flag erc-server-process nil)))
+ (with-current-buffer "*erc-protocol*"
+ (goto-char (point-min))
+ (search-forward "Version")
+ (search-forward "\r\n\r\n")
+ (search-forward "myproxy.localhost:6667 >> PASS" (line-end-position))
+ (forward-line)
+ (search-forward "irc.gnu.org << :irc.gnu.org 001" (line-end-position))
+ (forward-line)
+ (search-forward "irc.gnu.org << :irc.gnu.org 002" (line-end-position))
+ (forward-line)
+ (search-forward "FooNet << :irc.gnu.org 422" (line-end-position))
+ (forward-line)
+ (search-forward "BarNet << :irc.gnu.org 221" (line-end-position)))
+ (when noninteractive
+ (kill-buffer "*erc-protocol*")
+ (should-not erc-debug-irc-protocol)))
+
+
+;; The point of this test is to ensure output is handled identically
+;; regardless of whether a command handler is summoned.
+
+(ert-deftest erc-process-input-line ()
+ (let (erc-server-last-sent-time
+ erc-server-flood-queue
+ (orig-erc-cmd-MSG (symbol-function 'erc-cmd-MSG))
+ (erc-default-recipients '("#chan"))
+ calls)
+ (with-temp-buffer
+ (cl-letf (((symbol-function 'erc-cmd-MSG)
+ (lambda (line)
+ (push line calls)
+ (funcall orig-erc-cmd-MSG line)))
+ ((symbol-function 'erc-server-buffer)
+ (lambda () (current-buffer)))
+ ((symbol-function 'erc-server-process-alive)
+ (lambda () t))
+ ((symbol-function 'erc-server-send-queue)
+ #'ignore))
+
+ (ert-info ("Dispatch to user command handler")
+
+ (ert-info ("Baseline")
+ (erc-process-input-line "/msg #chan hi\n")
+ (should (equal (pop calls) " #chan hi"))
+ (should (equal (pop erc-server-flood-queue)
+ '("PRIVMSG #chan :hi\r\n" . utf-8))))
+
+ (ert-info ("Quote preserves line intact")
+ (erc-process-input-line "/QUOTE FAKE foo bar\n")
+ (should (equal (pop erc-server-flood-queue)
+ '("FAKE foo bar\r\n" . utf-8))))
+
+ (ert-info ("Unknown command respected")
+ (erc-process-input-line "/FAKE foo bar\n")
+ (should (equal (pop erc-server-flood-queue)
+ '("FAKE foo bar\r\n" . utf-8))))
+
+ (ert-info ("Spaces preserved")
+ (erc-process-input-line "/msg #chan hi you\n")
+ (should (equal (pop calls) " #chan hi you"))
+ (should (equal (pop erc-server-flood-queue)
+ '("PRIVMSG #chan :hi you\r\n" . utf-8))))
+
+ (ert-info ("Empty line honored")
+ (erc-process-input-line "/msg #chan\n")
+ (should (equal (pop calls) " #chan"))
+ (should (equal (pop erc-server-flood-queue)
+ '("PRIVMSG #chan :\r\n" . utf-8)))))
+
+ (ert-info ("Implicit cmd via `erc-send-input-line-function'")
+
+ (ert-info ("Baseline")
+ (erc-process-input-line "hi")
+ (should (equal (pop erc-server-flood-queue)
+ '("PRIVMSG #chan :hi\r\n" . utf-8))))
+
+ (ert-info ("Spaces preserved")
+ (erc-process-input-line "hi you")
+ (should (equal (pop erc-server-flood-queue)
+ '("PRIVMSG #chan :hi you\r\n" . utf-8))))
+
+ (ert-info ("Empty line transmitted without injected-space kludge")
+ (erc-process-input-line "")
+ (should (equal (pop erc-server-flood-queue)
+ '("PRIVMSG #chan :\r\n" . utf-8))))
+
+ (should-not calls))))))
+
+;;; erc-tests.el ends here
diff --git a/test/lisp/erc/erc-track-tests.el b/test/lisp/erc/erc-track-tests.el
index 0ce93bd45c6..b2687a96ab3 100644
--- a/test/lisp/erc/erc-track-tests.el
+++ b/test/lisp/erc/erc-track-tests.el
@@ -119,3 +119,5 @@
'(bold erc-current-nick-face) str1)
(should (erc-faces-in str0))
(should (erc-faces-in str1)) ))
+
+;;; erc-track-tests.el ends here
diff --git a/test/lisp/eshell/em-hist-tests.el b/test/lisp/eshell/em-hist-tests.el
index 31967a61c3c..5bc5690675d 100644
--- a/test/lisp/eshell/em-hist-tests.el
+++ b/test/lisp/eshell/em-hist-tests.el
@@ -20,19 +20,18 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'em-hist)
(ert-deftest eshell-write-readonly-history ()
"Test that having read-only strings in history is okay."
- (let ((histfile (make-temp-file "eshell-history"))
- (eshell-history-ring (make-ring 2)))
- (ring-insert eshell-history-ring
- (propertize "echo foo" 'read-only t))
- (ring-insert eshell-history-ring
- (propertize "echo bar" 'read-only t))
- (unwind-protect
- (eshell-write-history histfile)
- (delete-file histfile))))
+ (ert-with-temp-file histfile
+ (let ((eshell-history-ring (make-ring 2)))
+ (ring-insert eshell-history-ring
+ (propertize "echo foo" 'read-only t))
+ (ring-insert eshell-history-ring
+ (propertize "echo bar" 'read-only t))
+ (eshell-write-history histfile))))
(provide 'em-hist-test)
diff --git a/test/lisp/eshell/em-ls-tests.el b/test/lisp/eshell/em-ls-tests.el
index 5d1742b76fd..3ea11ab2de1 100644
--- a/test/lisp/eshell/em-ls-tests.el
+++ b/test/lisp/eshell/em-ls-tests.el
@@ -25,30 +25,30 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'em-ls)
(require 'dired)
(ert-deftest em-ls-test-bug27631 ()
"Test for https://debbugs.gnu.org/27631 ."
- (let* ((dir (make-temp-file "bug27631" 'dir))
- (dir1 (expand-file-name "dir1" dir))
- (dir2 (expand-file-name "dir2" dir))
- (default-directory dir)
- (orig eshell-ls-use-in-dired)
- buf)
- (unwind-protect
- (progn
- (customize-set-value 'eshell-ls-use-in-dired t)
- (make-directory dir1)
- (make-directory dir2)
- (with-temp-file (expand-file-name "a.txt" dir1))
- (with-temp-file (expand-file-name "b.txt" dir2))
- (setq buf (dired (expand-file-name "dir*/*.txt" dir)))
- (dired-toggle-marks)
- (should (cdr (dired-get-marked-files))))
- (customize-set-variable 'eshell-ls-use-in-dired orig)
- (delete-directory dir 'recursive)
- (when (buffer-live-p buf) (kill-buffer buf)))))
+ (ert-with-temp-directory dir
+ (let* ((dir1 (expand-file-name "dir1" dir))
+ (dir2 (expand-file-name "dir2" dir))
+ (default-directory dir)
+ (orig eshell-ls-use-in-dired)
+ buf)
+ (unwind-protect
+ (progn
+ (customize-set-value 'eshell-ls-use-in-dired t)
+ (make-directory dir1)
+ (make-directory dir2)
+ (with-temp-file (expand-file-name "a.txt" dir1))
+ (with-temp-file (expand-file-name "b.txt" dir2))
+ (setq buf (dired (expand-file-name "dir*/*.txt" dir)))
+ (dired-toggle-marks)
+ (should (cdr (dired-get-marked-files))))
+ (customize-set-variable 'eshell-ls-use-in-dired orig)
+ (when (buffer-live-p buf) (kill-buffer buf))))))
(ert-deftest em-ls-test-bug27817 ()
"Test for https://debbugs.gnu.org/27817 ."
diff --git a/test/lisp/eshell/eshell-tests.el b/test/lisp/eshell/eshell-tests.el
index 4f0cc9b6785..0974784ef4c 100644
--- a/test/lisp/eshell/eshell-tests.el
+++ b/test/lisp/eshell/eshell-tests.el
@@ -26,23 +26,23 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'esh-mode)
(require 'eshell)
(defmacro with-temp-eshell (&rest body)
"Evaluate BODY in a temporary Eshell buffer."
- `(let* ((eshell-directory-name (make-temp-file "eshell" t))
- ;; We want no history file, so prevent Eshell from falling
- ;; back on $HISTFILE.
- (process-environment (cons "HISTFILE" process-environment))
- (eshell-history-file-name nil)
- (eshell-buffer (eshell t)))
- (unwind-protect
- (with-current-buffer eshell-buffer
- ,@body)
- (let (kill-buffer-query-functions)
- (kill-buffer eshell-buffer)
- (delete-directory eshell-directory-name t)))))
+ `(ert-with-temp-directory eshell-directory-name
+ (let* (;; We want no history file, so prevent Eshell from falling
+ ;; back on $HISTFILE.
+ (process-environment (cons "HISTFILE" process-environment))
+ (eshell-history-file-name nil)
+ (eshell-buffer (eshell t)))
+ (unwind-protect
+ (with-current-buffer eshell-buffer
+ ,@body)
+ (let (kill-buffer-query-functions)
+ (kill-buffer eshell-buffer))))))
(defun eshell-insert-command (text &optional func)
"Insert a command at the end of the buffer."
@@ -65,11 +65,9 @@
(defun eshell-test-command-result (command)
"Like `eshell-command-result', but not using HOME."
- (let ((eshell-directory-name (make-temp-file "eshell" t))
- (eshell-history-file-name nil))
- (unwind-protect
- (eshell-command-result command)
- (delete-directory eshell-directory-name t))))
+ (ert-with-temp-directory eshell-directory-name
+ (let ((eshell-history-file-name nil))
+ (eshell-command-result command))))
;;; Tests:
@@ -262,4 +260,4 @@ chars"
(provide 'eshell-tests)
-;;; tests/eshell-tests.el ends here
+;;; eshell-tests.el ends here
diff --git a/test/lisp/faces-resources/faces-test-dark-theme.el b/test/lisp/faces-resources/faces-test-dark-theme.el
index f3ef6b67fa7..7e8871ec10a 100644
--- a/test/lisp/faces-resources/faces-test-dark-theme.el
+++ b/test/lisp/faces-resources/faces-test-dark-theme.el
@@ -22,7 +22,7 @@
;;; Code:
(deftheme faces-test-dark
- "")
+ "Dark test theme.")
(custom-theme-set-faces
'faces-test-dark
diff --git a/test/lisp/faces-resources/faces-test-light-theme.el b/test/lisp/faces-resources/faces-test-light-theme.el
index 390b8461644..70a75017614 100644
--- a/test/lisp/faces-resources/faces-test-light-theme.el
+++ b/test/lisp/faces-resources/faces-test-light-theme.el
@@ -22,7 +22,7 @@
;;; Code:
(deftheme faces-test-light
- "")
+ "Light test theme.")
(custom-theme-set-faces
'faces-test-light
diff --git a/test/lisp/faces-tests.el b/test/lisp/faces-tests.el
index c0db9c9de17..fe5f3ec95f8 100644
--- a/test/lisp/faces-tests.el
+++ b/test/lisp/faces-tests.el
@@ -25,7 +25,7 @@
(require 'ert)
(require 'ert-x)
-(defgroup faces--test nil ""
+(defgroup faces--test nil "Group to test faces."
:group 'faces--test)
(defface faces--test1
diff --git a/test/lisp/ffap-tests.el b/test/lisp/ffap-tests.el
index f8113bffc1a..df5c264baad 100644
--- a/test/lisp/ffap-tests.el
+++ b/test/lisp/ffap-tests.el
@@ -25,30 +25,29 @@
(require 'cl-lib)
(require 'ert)
+(require 'ert-x)
(require 'ffap)
(ert-deftest ffap-tests-25243 ()
"Test for https://debbugs.gnu.org/25243 ."
- (let ((file (make-temp-file "test-Bug#25243")))
- (unwind-protect
- (with-temp-file file
- (let ((str "diff --git b/lisp/ffap.el a/lisp/ffap.el
+ (ert-with-temp-file file
+ :suffix "-bug25243"
+ (let ((str "diff --git b/lisp/ffap.el a/lisp/ffap.el
index 3d7cebadcf..ad4b70d737 100644
--- b/lisp/ffap.el
+++ a/lisp/ffap.el
@@ -203,6 +203,9 @@ ffap-foo-at-bar-prefix
"))
- (transient-mark-mode 1)
- (when (natnump ffap-max-region-length)
- (insert
- (concat
- str
- (make-string ffap-max-region-length #xa)
- (format "%s ENDS HERE" file)))
- (call-interactively 'mark-whole-buffer)
- (should (equal "" (ffap-string-at-point)))
- (should (equal '(1 1) ffap-string-at-point-region)))))
- (and (file-exists-p file) (delete-file file)))))
+ (transient-mark-mode 1)
+ (when (natnump ffap-max-region-length)
+ (insert
+ (concat
+ str
+ (make-string ffap-max-region-length #xa)
+ (format "%s ENDS HERE" file)))
+ (call-interactively 'mark-whole-buffer)
+ (should (equal "" (ffap-string-at-point)))
+ (should (equal '(1 1) ffap-string-at-point-region))))))
(ert-deftest ffap-gopher-at-point ()
(with-temp-buffer
@@ -133,7 +132,7 @@ left alone when opening a URL in an external browser."
;; Macros in BODY are expanded when the test is defined, not when it
;; is run. If a macro (possibly with side effects) is to be tested,
;; it has to be wrapped in `(eval (quote ...))'.
- (eval (quote (ido-everywhere)))
+ (eval (quote (ido-everywhere)) t)
(let ((read-file-name-function (lambda (&rest args)
(expand-file-name
(nth 4 args)
diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el
index 6125069c6b3..0fe72f278dc 100644
--- a/test/lisp/filenotify-tests.el
+++ b/test/lisp/filenotify-tests.el
@@ -162,9 +162,7 @@ Return nil when any other file notification watch is still active."
(defun file-notify--test-cleanup ()
"Cleanup after a test."
- (file-notify-rm-watch file-notify--test-desc)
- (file-notify-rm-watch file-notify--test-desc1)
- (file-notify-rm-watch file-notify--test-desc2)
+ (file-notify-rm-all-watches)
(ignore-errors
(delete-file (file-newest-backup file-notify--test-tmpfile)))
@@ -421,7 +419,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
;; This test is inspired by Bug#26126 and Bug#26127.
(ert-deftest file-notify-test02-rm-watch ()
- "Check `file-notify-rm-watch'."
+ "Check `file-notify-rm-watch' and `file-notify-rm-all-watches'."
(skip-unless (file-notify--test-local-enabled))
(unwind-protect
@@ -517,6 +515,31 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(file-notify--test-cleanup-p))))
;; Cleanup.
+ (file-notify--test-cleanup))
+
+ (unwind-protect
+ ;; Check `file-notify-rm-all-watches'.
+ (progn
+ (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)
+ file-notify--test-tmpfile1 (file-notify--test-make-temp-name))
+ (write-region "any text" nil file-notify--test-tmpfile nil 'no-message)
+ (write-region "any text" nil file-notify--test-tmpfile1 nil 'no-message)
+ (should
+ (setq file-notify--test-desc
+ (file-notify-add-watch
+ file-notify--test-tmpfile '(change) #'ignore)))
+ (should
+ (setq file-notify--test-desc1
+ (file-notify-add-watch
+ file-notify--test-tmpfile1 '(change) #'ignore)))
+ (file-notify-rm-all-watches)
+ (delete-file file-notify--test-tmpfile)
+ (delete-file file-notify--test-tmpfile1)
+
+ ;; The environment shall be cleaned up.
+ (file-notify--test-cleanup-p))
+
+ ;; Cleanup.
(file-notify--test-cleanup)))
(file-notify--deftest-remote file-notify-test02-rm-watch
@@ -743,7 +766,7 @@ delivered."
;; the directory. Except for
;; GFam{File,Directory}Monitor, GPollFileMonitor and
;; kqueue. And GFam{File,Directory}Monitor and
- ;; GPollFileMonitordo not raise a `changed' event.
+ ;; GPollFileMonitor do not raise a `changed' event.
((memq (file-notify--test-monitor)
'(GFamFileMonitor GFamDirectoryMonitor GPollFileMonitor))
'(created deleted stopped))
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index fb24b98595b..462048802f0 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -136,7 +136,7 @@ form.")
;; Prevent any dir-locals file interfering with the tests.
(enable-dir-local-variables nil))
(hack-local-variables)
- (eval (nth 2 test-settings)))))
+ (eval (nth 2 test-settings) t))))
(ert-deftest files-tests-local-variables ()
"Test the file-local variables implementation."
@@ -154,12 +154,14 @@ form.")
(ert-deftest files-tests-permanent-local-variables ()
(let ((enable-local-variables nil))
(with-temp-buffer
+ (setq lexical-binding nil)
(insert ";;; test-test.el --- tests -*- lexical-binding: t; -*-\n\n")
(hack-local-variables)
(should (eq lexical-binding t))))
(let ((enable-local-variables nil)
(permanently-enabled-local-variables nil))
(with-temp-buffer
+ (setq lexical-binding nil)
(insert ";;; test-test.el --- tests -*- lexical-binding: t; -*-\n\n")
(hack-local-variables)
(should (eq lexical-binding nil)))))
@@ -174,15 +176,14 @@ form.")
;; If called interactively, environment variable
;; $EMACS_TEST_DIRECTORY does not exist.
(skip-unless (file-exists-p files-test-bug-18141-file))
- (let ((tempfile (make-temp-file "files-test-bug-18141" nil ".gz")))
- (unwind-protect
- (progn
- (copy-file files-test-bug-18141-file tempfile t)
- (with-current-buffer (find-file-noselect tempfile)
- (set-buffer-modified-p t)
- (save-buffer)
- (should (eq buffer-file-coding-system 'iso-2022-7bit-unix))))
- (delete-file tempfile))))
+ (ert-with-temp-file tempfile
+ :prefix "emacs-test-files-bug-18141"
+ :suffix ".gz"
+ (copy-file files-test-bug-18141-file tempfile t)
+ (with-current-buffer (find-file-noselect tempfile)
+ (set-buffer-modified-p t)
+ (save-buffer)
+ (should (eq buffer-file-coding-system 'iso-2022-7bit-unix)))))
(ert-deftest files-tests-make-temp-file-empty-prefix ()
"Test make-temp-file with an empty prefix."
@@ -281,22 +282,20 @@ If we are in a directory named `~', the default value should not
be $HOME."
(cl-letf (((symbol-function 'completing-read)
(lambda (_prompt _coll &optional _pred _req init _hist def _)
- (or def init)))
- (dir (make-temp-file "read-file-name-test" t)))
- (unwind-protect
- (let ((subdir (expand-file-name "./~/" dir)))
- (make-directory subdir t)
- (with-temp-buffer
- (setq default-directory subdir)
- (should-not (equal
- (expand-file-name (read-file-name "File: "))
- (expand-file-name "~/")))
- ;; Don't overquote either!
- (setq default-directory (concat "/:" subdir))
- (should-not (equal
- (expand-file-name (read-file-name "File: "))
- (concat "/:/:" subdir)))))
- (delete-directory dir 'recursive))))
+ (or def init))))
+ (ert-with-temp-directory dir
+ (let ((subdir (expand-file-name "./~/" dir)))
+ (make-directory subdir t)
+ (with-temp-buffer
+ (setq default-directory subdir)
+ (should-not (equal
+ (expand-file-name (read-file-name "File: "))
+ (expand-file-name "~/")))
+ ;; Don't overquote either!
+ (setq default-directory (concat "/:" subdir))
+ (should-not (equal
+ (expand-file-name (read-file-name "File: "))
+ (concat "/:/:" subdir))))))))
(ert-deftest files-tests-file-name-non-special-quote-unquote ()
(let (;; Just in case it is quoted, who knows.
@@ -339,14 +338,6 @@ be $HOME."
(progn ,@body)
(advice-remove #',symbol ,function)))))
-(defmacro files-tests--with-temp-file (name &rest body)
- (declare (indent 1) (debug (symbolp body)))
- (cl-check-type name symbol)
- `(let ((,name (make-temp-file "emacs")))
- (unwind-protect
- (progn ,@body)
- (delete-file ,name))))
-
(ert-deftest files-tests-file-name-non-special--buffers ()
"Check that Bug#25951 is fixed.
We call `verify-visited-file-modtime' on a buffer visiting a file
@@ -355,7 +346,7 @@ the buffer current and a nil argument, second passing the buffer
object explicitly. In both cases no error should be raised and
the `file-name-non-special' handler for quoted file names should
be invoked with the right arguments."
- (files-tests--with-temp-file temp-file-name
+ (ert-with-temp-file temp-file-name
(with-temp-buffer
(let* ((buffer-visiting-file (current-buffer))
(actual-args ())
@@ -474,6 +465,15 @@ unquoted file names."
(let (file-name-handler-alist)
(concat (file-name-sans-extension name) part (file-name-extension name t))))
+(ert-deftest files-tests-file-name-non-special-abbreviate-file-name ()
+ (let* ((homedir temporary-file-directory)
+ (process-environment (cons (format "HOME=%s" homedir)
+ process-environment))
+ (abbreviated-home-dir nil))
+ ;; Check that abbreviation doesn't occur for quoted file names.
+ (should (equal (concat "/:" homedir "foo/bar")
+ (abbreviate-file-name (concat "/:" homedir "foo/bar"))))))
+
(ert-deftest files-tests-file-name-non-special-access-file ()
(files-tests--with-temp-non-special (tmpfile nospecial)
;; Both versions of the file name work.
@@ -1237,26 +1237,26 @@ works as expected if the default directory is quoted."
(insert-directory-wildcard-in-dir-p (car path-res)))))))
(ert-deftest files-tests-make-directory ()
- (let* ((dir (make-temp-file "files-mkdir-test" t))
- (dirname (file-name-as-directory dir))
- (file (concat dirname "file"))
- (subdir1 (concat dirname "subdir1"))
- (subdir2 (concat dirname "subdir2"))
- (a/b (concat dirname "a/b")))
- (write-region "" nil file)
- (should-error (make-directory "/"))
- (should-not (make-directory "/" t))
- (should-error (make-directory dir))
- (should-not (make-directory dir t))
- (should-error (make-directory dirname))
- (should-not (make-directory dirname t))
- (should-error (make-directory file))
- (should-error (make-directory file t))
- (should-not (make-directory subdir1))
- (should-not (make-directory subdir2 t))
- (should-error (make-directory a/b))
- (should-not (make-directory a/b t))
- (delete-directory dir 'recursive)))
+ (ert-with-temp-directory dir
+ (let* ((dirname (file-name-as-directory dir))
+ (file (concat dirname "file"))
+ (subdir1 (concat dirname "subdir1"))
+ (subdir2 (concat dirname "subdir2"))
+ (a/b (concat dirname "a/b")))
+ (write-region "" nil file)
+ (should-error (make-directory "/"))
+ (should-not (make-directory "/" t))
+ (should-error (make-directory dir))
+ (should-not (make-directory dir t))
+ (should-error (make-directory dirname))
+ (should-not (make-directory dirname t))
+ (should-error (make-directory file))
+ (should-error (make-directory file t))
+ (should-not (make-directory subdir1))
+ (should-not (make-directory subdir2 t))
+ (should-error (make-directory a/b))
+ (should-not (make-directory a/b t))
+ (delete-directory dir 'recursive))))
(ert-deftest files-tests-file-modes-symbolic-to-number ()
(let ((alist (list (cons "a=rwx" #o777)
@@ -1316,7 +1316,7 @@ name (Bug#28412)."
(set-buffer-modified-p t)
(should-error (save-buffer) :type 'error))
;; Then a buffer visiting a file: should save normally.
- (files-tests--with-temp-file temp-file-name
+ (ert-with-temp-file temp-file-name
(with-current-buffer (find-file-noselect temp-file-name)
(setq write-contents-functions nil)
(insert "p")
@@ -1324,21 +1324,54 @@ name (Bug#28412)."
(should (eq (buffer-size) 1))))))
(ert-deftest files-tests-copy-directory ()
- (let* ((dir (make-temp-file "files-mkdir-test" t))
- (dirname (file-name-as-directory dir))
- (source (concat dirname "source"))
- (dest (concat dirname "dest/new/directory/"))
- (file (concat (file-name-as-directory source) "file"))
- (source2 (concat dirname "source2"))
- (dest2 (concat dirname "dest/new2")))
- (make-directory source)
- (write-region "" nil file)
- (copy-directory source dest t t t)
- (should (file-exists-p (concat dest "file")))
- (make-directory (concat (file-name-as-directory source2) "a") t)
- (copy-directory source2 dest2)
- (should (file-directory-p (concat (file-name-as-directory dest2) "a")))
- (delete-directory dir 'recursive)))
+ (ert-with-temp-directory dir
+ (let* ((dirname (file-name-as-directory dir))
+ (source (concat dirname "source"))
+ (dest (concat dirname "dest/new/directory/"))
+ (file (concat (file-name-as-directory source) "file"))
+ (source2 (concat dirname "source2"))
+ (dest2 (concat dirname "dest/new2")))
+ (make-directory source)
+ (write-region "" nil file)
+ (copy-directory source dest t t t)
+ (should (file-exists-p (concat dest "file")))
+ (make-directory (concat (file-name-as-directory source2) "a") t)
+ (copy-directory source2 dest2)
+ (should (file-directory-p (concat (file-name-as-directory dest2) "a")))
+ (delete-directory dir 'recursive))))
+
+(ert-deftest files-tests-abbreviate-file-name-homedir ()
+ ;; Check homedir abbreviation.
+ (let* ((homedir temporary-file-directory)
+ (process-environment (cons (format "HOME=%s" homedir)
+ process-environment))
+ (abbreviated-home-dir nil))
+ (should (equal "~/foo/bar"
+ (abbreviate-file-name (concat homedir "foo/bar")))))
+ ;; Check that homedir abbreviation doesn't occur when homedir is just /.
+ (let* ((homedir "/")
+ (process-environment (cons (format "HOME=%s" homedir)
+ process-environment))
+ (abbreviated-home-dir nil))
+ (should (equal "/foo/bar"
+ (abbreviate-file-name (concat homedir "foo/bar"))))))
+
+(ert-deftest files-tests-abbreviate-file-name-directory-abbrev-alist ()
+ ;; Check `directory-abbrev-alist' abbreviation.
+ (let ((directory-abbrev-alist '(("\\`/nowhere/special" . "/nw/sp"))))
+ (should (equal "/nw/sp/here"
+ (abbreviate-file-name "/nowhere/special/here"))))
+ ;; Check homedir and `directory-abbrev-alist' abbreviation.
+ (let* ((homedir temporary-file-directory)
+ (process-environment (cons (format "HOME=%s" homedir)
+ process-environment))
+ (abbreviated-home-dir nil)
+ (directory-abbrev-alist
+ `((,(concat "\\`" (regexp-quote homedir) "nowhere/special")
+ . ,(concat homedir "nw/sp")))))
+ (should (equal "~/nw/sp/here"
+ (abbreviate-file-name
+ (concat homedir "nowhere/special/here"))))))
(ert-deftest files-tests-abbreviated-home-dir ()
"Test that changing HOME does not confuse `abbreviate-file-name'.
@@ -1357,43 +1390,40 @@ See <https://debbugs.gnu.org/19657#20>."
(ert-deftest files-tests-executable-find ()
"Test that `executable-find' works also with a relative or remote PATH.
See <https://debbugs.gnu.org/35241>."
- (let ((tmpfile (make-temp-file "files-test" nil (car exec-suffixes))))
- (unwind-protect
- (progn
- (set-file-modes tmpfile #o777)
- (let ((exec-path `(,temporary-file-directory)))
- (should
- (equal tmpfile
- (executable-find (file-name-nondirectory tmpfile)))))
- ;; An empty element of `exec-path' means `default-directory'.
- (let ((default-directory temporary-file-directory)
- (exec-path nil))
- (should
- (equal tmpfile
- (executable-find (file-name-nondirectory tmpfile)))))
- ;; The remote file name shall be quoted, and handled like a
- ;; non-existing directory.
- (let ((default-directory "/ssh::")
- (exec-path (append exec-path `("." ,temporary-file-directory))))
- (should
- (equal tmpfile
- (executable-find (file-name-nondirectory tmpfile))))))
- (delete-file tmpfile))))
+ (ert-with-temp-file tmpfile
+ :suffix (car exec-suffixes)
+ (set-file-modes tmpfile #o755)
+ (let ((exec-path `(,temporary-file-directory)))
+ (should
+ (equal tmpfile
+ (executable-find (file-name-nondirectory tmpfile)))))
+ ;; An empty element of `exec-path' means `default-directory'.
+ (let ((default-directory temporary-file-directory)
+ (exec-path nil))
+ (should
+ (equal tmpfile
+ (executable-find (file-name-nondirectory tmpfile)))))
+ ;; The remote file name shall be quoted, and handled like a
+ ;; non-existing directory.
+ (let ((default-directory "/ssh::")
+ (exec-path (append exec-path `("." ,temporary-file-directory))))
+ (should
+ (equal tmpfile
+ (executable-find (file-name-nondirectory tmpfile)))))))
(ert-deftest files-tests-dont-rewrite-precious-files ()
"Test that `file-precious-flag' forces files to be saved by
renaming only, rather than modified in-place."
- (let* ((temp-file-name (make-temp-file "files-tests"))
- (advice (lambda (_start _end filename &rest _r)
- (should-not (string= filename temp-file-name)))))
- (unwind-protect
- (with-current-buffer (find-file-noselect temp-file-name)
- (advice-add #'write-region :before advice)
- (setq-local file-precious-flag t)
- (insert "foobar")
- (should (null (save-buffer))))
- (ignore-errors (advice-remove #'write-region advice))
- (ignore-errors (delete-file temp-file-name)))))
+ (ert-with-temp-file temp-file-name
+ (let* ((advice (lambda (_start _end filename &rest _r)
+ (should-not (string= filename temp-file-name)))))
+ (unwind-protect
+ (with-current-buffer (find-file-noselect temp-file-name)
+ (advice-add #'write-region :before advice)
+ (setq-local file-precious-flag t)
+ (insert "foobar")
+ (should (null (save-buffer))))
+ (ignore-errors (advice-remove #'write-region advice))))))
(ert-deftest files-test-file-size-human-readable ()
(should (equal (file-size-human-readable 13) "13"))
@@ -1507,26 +1537,32 @@ The door of all subtleties!
(ert-deftest files-tests-revert-buffer ()
"Test that revert-buffer is successful."
- (files-tests--with-temp-file temp-file-name
+ (ert-with-temp-file temp-file-name
(with-temp-buffer
(insert files-tests-lao)
- (write-file temp-file-name)
- (erase-buffer)
- (insert files-tests-tzu)
- (revert-buffer t t t)
+ ;; Disable lock files, since that barfs in
+ ;; userlock--check-content-unchanged on MS-Windows.
+ (let (create-lockfiles)
+ (write-file temp-file-name)
+ (erase-buffer)
+ (insert files-tests-tzu)
+ (revert-buffer t t t))
(should (compare-strings files-tests-lao nil nil
(buffer-substring (point-min) (point-max))
nil nil)))))
(ert-deftest files-tests-revert-buffer-with-fine-grain ()
"Test that revert-buffer-with-fine-grain is successful."
- (files-tests--with-temp-file temp-file-name
+ (ert-with-temp-file temp-file-name
(with-temp-buffer
(insert files-tests-lao)
- (write-file temp-file-name)
- (erase-buffer)
- (insert files-tests-tzu)
- (should (revert-buffer-with-fine-grain t t))
+ ;; Disable lock files, since that barfs in
+ ;; userlock--check-content-unchanged on MS-Windows.
+ (let (create-lockfiles)
+ (write-file temp-file-name)
+ (erase-buffer)
+ (insert files-tests-tzu)
+ (should (revert-buffer-with-fine-grain t t)))
(should (compare-strings files-tests-lao nil nil
(buffer-substring (point-min) (point-max))
nil nil)))))
@@ -1549,6 +1585,14 @@ The door of all subtleties!
(should-error (file-name-with-extension "Jack" "."))
(should-error (file-name-with-extension "/is/a/directory/" "css")))
+(ert-deftest files-tests-file-name-base ()
+ (should (equal (file-name-base "") ""))
+ (should (equal (file-name-base "/foo/") ""))
+ (should (equal (file-name-base "/foo") "foo"))
+ (should (equal (file-name-base "/foo/bar") "bar"))
+ (should (equal (file-name-base "foo") "foo"))
+ (should (equal (file-name-base "foo/bar") "bar")))
+
(ert-deftest files-test-dir-locals-auto-mode-alist ()
"Test an `auto-mode-alist' entry in `.dir-locals.el'"
(find-file (ert-resource-file "whatever.quux"))
@@ -1560,5 +1604,223 @@ The door of all subtleties!
(find-file (ert-resource-file "auto-test.zot3"))
(should (eq major-mode 'fundamental-mode)))
+(defun files-tests--save-some-buffers (pred def-pred-bind exp-1 exp-2)
+ "Helper function to test `save-some-buffers'.
+
+This function creates two file-visiting buffers, BUF-1, BUF-2 in
+different directories at the same level, i.e., none of them is a
+subdir of the other; then it modifies both buffers; finally, it
+calls `save-some-buffers' from BUF-1 with first arg t, second
+arg PRED and `save-some-buffers-default-predicate' let-bound to
+DEF-PRED-BIND.
+
+EXP-1 and EXP-2 are the expected values of calling `buffer-modified-p'
+on BUF-1 and BUF-2 after the `save-some-buffers' call.
+
+The test is repeated with `save-some-buffers-default-predicate'
+let-bound to PRED and passing nil as second arg of
+`save-some-buffers'."
+ (ert-with-temp-directory dir
+ (let* ((file-1 (expand-file-name "subdir-1/file.foo" dir))
+ (file-2 (expand-file-name "subdir-2/file.bar" dir))
+ (inhibit-message t)
+ buf-1 buf-2)
+ (unwind-protect
+ (progn
+ (make-empty-file file-1 'parens)
+ (make-empty-file file-2 'parens)
+ (setq buf-1 (find-file file-1)
+ buf-2 (find-file file-2))
+ (dolist (buf (list buf-1 buf-2))
+ (with-current-buffer buf (insert "foobar\n")))
+ ;; Run the test.
+ (with-current-buffer buf-1
+ (let ((save-some-buffers-default-predicate def-pred-bind))
+ (save-some-buffers t pred))
+ (should (eq exp-1 (buffer-modified-p buf-1)))
+ (should (eq exp-2 (buffer-modified-p buf-2))))
+ ;; Set both buffers as modified to run another test.
+ (dolist (buf (list buf-1 buf-2))
+ (with-current-buffer buf (set-buffer-modified-p t)))
+ ;; The result of this test must be identical as the previous one.
+ (with-current-buffer buf-1
+ (let ((save-some-buffers-default-predicate (or pred def-pred-bind)))
+ (save-some-buffers t nil))
+ (should (eq exp-1 (buffer-modified-p buf-1)))
+ (should (eq exp-2 (buffer-modified-p buf-2)))))
+ ;; Clean up.
+ (dolist (buf (list buf-1 buf-2))
+ (with-current-buffer buf
+ (set-buffer-modified-p nil)
+ (kill-buffer buf)))))))
+
+(ert-deftest files-tests-save-some-buffers ()
+ "Test `save-some-buffers'.
+Test the 3 cases for the second argument PRED, i.e., nil, t, or
+predicate.
+The value of `save-some-buffers-default-predicate' is ignored unless
+PRED is nil."
+ (let* ((foo-file-p (lambda () (string-suffix-p ".foo" buffer-file-name)))
+ (bar-file-p (lambda () (string-suffix-p ".bar" buffer-file-name)))
+ (args-results `((nil nil nil nil)
+ (nil ,foo-file-p nil t)
+ (nil ,bar-file-p t nil)
+ (,foo-file-p nil nil t)
+ (,bar-file-p nil t nil)
+
+ (buffer-modified-p nil nil nil)
+ (t nil nil nil)
+ (t ,foo-file-p nil nil)
+
+ (,foo-file-p save-some-buffers-root nil t)
+ (nil save-some-buffers-root nil t)
+ (,bar-file-p save-some-buffers-root t nil)
+ (t save-some-buffers-root nil nil))))
+ (pcase-dolist (`(,pred ,def-pred-bind ,exp-1 ,exp-2) args-results)
+ (files-tests--save-some-buffers pred def-pred-bind exp-1 exp-2))))
+
+(defmacro files-tests--with-buffer-offer-save (buffers-offer fn-test fn-binders args-results)
+ "Helper macro to test `save-some-buffers' and `save-buffers-kill-emacs'.
+
+This macro creates several non-file-visiting buffers in different
+directories at the same level, i.e., none of them is a subdir of the
+other. Then it modifies the buffers and sets their `buffer-offer-save'
+as specified by BUFFERS-OFFER, a list of elements (BUFFER OFFER-SAVE).
+Finally, it calls FN-TEST from the first buffer.
+
+FN-TEST is the function to test: either `save-some-buffers' or
+`save-buffers-kill-emacs'. This function is called with
+`save-some-buffers-default-predicate' let-bound to a value
+specified inside ARGS-RESULTS.
+
+FN-BINDERS is a list of elements (FUNCTION . BINDING), where FUNCTION
+is a function symbol that this macro temporary binds to BINDING during
+the FN-TEST call.
+
+ARGS-RESULTS is a list of elements (FN-ARGS CALLERS-DIR EXPECTED), where
+FN-ARGS are the arguments for FN-TEST;
+CALLERS-DIR specifies the value to let-bind
+\`save-some-buffers-default-predicate';
+ EXPECTED is the expected result of the test."
+ (declare (debug (form symbol form form)))
+ (let ((dir (gensym "dir"))
+ (buffers (gensym "buffers")))
+ `(let* ((,dir (make-temp-file "testdir" 'dir))
+ (inhibit-message t)
+ (use-dialog-box nil)
+ ,buffers)
+ (pcase-dolist (`(,bufsym ,offer-save) ,buffers-offer)
+ (let* ((buf (generate-new-buffer (symbol-name bufsym)))
+ (subdir (expand-file-name
+ (format "subdir-%s" (buffer-name buf))
+ ,dir)))
+ (make-directory subdir 'parens)
+ (push buf ,buffers)
+ (with-current-buffer buf
+ (cd subdir)
+ (setq buffer-offer-save offer-save)
+ (insert "foobar\n"))))
+ (setq ,buffers (nreverse ,buffers))
+ (let ((nb-saved-buffers 0))
+ (unwind-protect
+ (pcase-dolist (`(,fn-test-args ,callers-dir ,expected)
+ ,args-results)
+ (setq nb-saved-buffers 0)
+ (with-current-buffer (car ,buffers)
+ (cl-letf
+ (,@(mapcar (lambda (pair) `((symbol-function ,(car pair)) ,(cdr pair)))
+ fn-binders)
+ (save-some-buffers-default-predicate callers-dir))
+ (apply #',fn-test fn-test-args)
+ (should (equal nb-saved-buffers expected)))))
+ ;; Clean up.
+ (dolist (buf ,buffers)
+ (with-current-buffer buf
+ (set-buffer-modified-p nil)
+ (kill-buffer buf)))
+ (delete-directory ,dir 'recursive))))))
+
+(defmacro files-tests-with-all-permutations (permutation list &rest body)
+ "Execute BODY forms for all permutations of LIST.
+Execute the forms with the symbol PERMUTATION bound to the current
+permutation."
+ (declare (indent 2) (debug (symbol form body)))
+ (let ((vec (gensym "vec")))
+ `(let ((,vec (vconcat ,list)))
+ (cl-labels ((swap (,vec i j)
+ (let ((tmp (aref ,vec j)))
+ (aset ,vec j (aref ,vec i))
+ (aset ,vec i tmp)))
+ (permute (,vec l r)
+ (if (= l r)
+ (let ((,permutation (append ,vec nil)))
+ ,@body)
+ (cl-loop for idx from l below (1+ r) do
+ (swap ,vec idx l)
+ (permute ,vec (1+ l) r)
+ (swap ,vec idx l)))))
+ (permute ,vec 0 (1- (length ,vec)))))))
+
+(ert-deftest files-tests-buffer-offer-save ()
+ "Test `save-some-buffers' for non-file-visiting buffers.
+Check the behavior of `save-some-buffers' for non-file-visiting
+buffers under several values of `buffer-offer-save'.
+The value of `save-some-buffers-default-predicate' is ignored unless
+PRED is nil."
+ (let* ((buffers-offer-init '((buf-1 t) (buf-2 always) (buf-3 nil)))
+ (nb-might-save
+ (length
+ (cl-remove-if (lambda (l) (null (cadr l))) buffers-offer-init)))
+ (nb-always-save
+ (length
+ (cl-remove-if-not (lambda (l) (eq 'always (cadr l))) buffers-offer-init))))
+ (files-tests-with-all-permutations
+ buffers-offer
+ buffers-offer-init
+ (dolist (pred `(nil t save-some-buffers-root))
+ (dolist (callers-dir `(nil save-some-buffers-root))
+ (let* ((head-offer (cadar buffers-offer))
+ (res (cond ((null pred)
+ (if (null callers-dir) nb-always-save (or (and head-offer 1) 0)))
+ (t
+ ;; Save any buffer with `buffer-offer-save' non-nil.
+ (if (eq pred t) nb-might-save
+ ;; Restrict to caller's dir.
+ (or (and head-offer 1) 0)))))
+ (args-res `(((nil ,pred) ,callers-dir ,res))))
+ (files-tests--with-buffer-offer-save
+ buffers-offer
+ save-some-buffers
+ ;; Increase counter and answer 'n' when prompted to save a buffer.
+ (('read-event . (lambda (&rest _) (cl-incf nb-saved-buffers) ?n)))
+ args-res)))))))
+
+(ert-deftest files-tests-save-buffers-kill-emacs--asks-to-save-buffers ()
+ "Test that `save-buffers-kill-emacs' asks to save buffers as expected.
+Prompt users for any modified buffer with `buffer-offer-save' non-nil."
+ (let* ((buffers-offer-init '((buf-1 t) (buf-2 always) (buf-3 nil)))
+ (nb-might-save
+ (length
+ (cl-remove-if (lambda (l) (null (cadr l))) buffers-offer-init))))
+ (files-tests-with-all-permutations
+ buffers-offer
+ buffers-offer-init
+ (files-tests--with-buffer-offer-save
+ buffers-offer
+ save-buffers-kill-emacs
+ ;; Increase counter and answer 'n' when prompted to save a buffer.
+ (('read-event . (lambda (&rest _) (cl-incf nb-saved-buffers) ?n))
+ ('kill-emacs . #'ignore)) ; Do not kill Emacs.
+ `((nil nil ,nb-might-save)
+ ;; `save-some-buffers-default-predicate' (i.e. the 2nd element) is ignored.
+ (nil save-some-buffers-root ,nb-might-save))))))
+
+(ert-deftest test-file-name-split ()
+ (should (equal (file-name-split "foo/bar") '("foo" "bar")))
+ (should (equal (file-name-split "/foo/bar") '("" "foo" "bar")))
+ (should (equal (file-name-split "/foo/bar/zot") '("" "foo" "bar" "zot")))
+ (should (equal (file-name-split "/foo/bar/") '("" "foo" "bar" "")))
+ (should (equal (file-name-split "foo/bar/") '("foo" "bar" ""))))
+
(provide 'files-tests)
;;; files-tests.el ends here
diff --git a/test/lisp/format-spec-tests.el b/test/lisp/format-spec-tests.el
index ff2abdeaad5..3c6fa540fe8 100644
--- a/test/lisp/format-spec-tests.el
+++ b/test/lisp/format-spec-tests.el
@@ -56,7 +56,7 @@
(ert-deftest format-spec-do-flags-truncate ()
"Test `format-spec--do-flags' truncation."
- (let (flags)
+ (let ((flags nil))
(should (equal (format-spec--do-flags "" flags nil 0) ""))
(should (equal (format-spec--do-flags "" flags nil 1) ""))
(should (equal (format-spec--do-flags "a" flags nil 0) ""))
@@ -75,7 +75,7 @@
(ert-deftest format-spec-do-flags-pad ()
"Test `format-spec--do-flags' padding."
- (let (flags)
+ (let ((flags nil))
(should (equal (format-spec--do-flags "" flags 0 nil) ""))
(should (equal (format-spec--do-flags "" flags 1 nil) " "))
(should (equal (format-spec--do-flags "a" flags 0 nil) "a"))
diff --git a/test/lisp/gnus/gnus-group-tests.el b/test/lisp/gnus/gnus-group-tests.el
new file mode 100644
index 00000000000..ee1e01be4b2
--- /dev/null
+++ b/test/lisp/gnus/gnus-group-tests.el
@@ -0,0 +1,52 @@
+;;; gnus-group-tests.el --- Tests for gnus-group.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 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 'gnus-group)
+(require 'ert)
+
+(ert-deftest gnus-short-group-name ()
+ (map-apply
+ (lambda (input expected)
+ (should (string-equal (gnus-short-group-name input) expected)))
+ '(("nnimap+email@example.com:archives/2020/03" . "email@example:a/2/03")
+ ("nndiary+diary:birthdays" . "diary:birthdays")
+ ("nnimap+email@example.com:test" . "email@example:test")
+ ("nnimap+email@example.com:234" . "email@example:234")
+
+ ;; This is a very aggressive shortening of the left hand side.
+ ("nnimap+email@banana.salesman.example.com:234" . "email@banana:234")
+ ("nntp+some.where.edu:soc.motss" . "some:s.motss")
+ ("nntp+news.gmane.org:gmane.emacs.gnus.general" . "news:g.e.g.general")
+ ("nntp+news.gnus.org:gmane.text.docbook.apps" . "news:g.t.d.apps")
+
+ ;; nnimap groups.
+ ("nnimap+email@example.com:[Invoices]/Bananas" . "email@example:I/Bananas")
+ ("nnimap+email@banana.salesman.example.com:[Invoices]/Bananas"
+ . "email@banana:I/Bananas")
+
+ ;; The "n" from "nnspool" is perhaps not optimal.
+ ("nnspool+alt.binaries.pictures.furniture" . "n.b.p.furniture"))))
+
+;;; gnus-group-tests.el ends here
diff --git a/test/lisp/gnus/gnus-icalendar-tests.el b/test/lisp/gnus/gnus-icalendar-tests.el
index 90c3a34a5c0..1206a976f6e 100644
--- a/test/lisp/gnus/gnus-icalendar-tests.el
+++ b/test/lisp/gnus/gnus-icalendar-tests.el
@@ -216,7 +216,7 @@ RRULE:FREQ=WEEKLY;BYDAY=FR,MO,TH,TU,WE
DTSTAMP:20200915T120627Z
ORGANIZER;CN=anon@anoncompany.com:mailto:anon@anoncompany.com
UID:7b6g3m7iftuo90ei4ul00feqn_R20200915T120000@google.com
-ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE
+ATTENDEE;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED;RSVP=TRUE
;CN=participant@anoncompany.com;X-NUM-GUESTS=0:mailto:participant@anoncompany.com
CREATED:20200325T095723Z
DESCRIPTION:Coffee talk
diff --git a/test/lisp/gnus/gnus-search-tests.el b/test/lisp/gnus/gnus-search-tests.el
index 6148da65621..9f012d4e888 100644
--- a/test/lisp/gnus/gnus-search-tests.el
+++ b/test/lisp/gnus/gnus-search-tests.el
@@ -97,4 +97,4 @@
"more bits"))))
(provide 'gnus-search-tests)
-;;; search-tests.el ends here
+;;; gnus-search-tests.el ends here
diff --git a/test/lisp/gnus/gnus-util-tests.el b/test/lisp/gnus/gnus-util-tests.el
index f8d30f6373e..60a9cde0e7f 100644
--- a/test/lisp/gnus/gnus-util-tests.el
+++ b/test/lisp/gnus/gnus-util-tests.el
@@ -132,4 +132,4 @@
(should (equal '("1") (gnus-setdiff '(2 "1" 2) '(2))))
(should (equal '("1" "1") (gnus-setdiff '(2 "1" 2 "1") '(2)))))
-;;; gnustest-gnus-util.el ends here
+;;; gnus-util-tests.el ends here
diff --git a/test/lisp/gnus/message-tests.el b/test/lisp/gnus/message-tests.el
index b4f2b7f675d..0f42f62f386 100644
--- a/test/lisp/gnus/message-tests.el
+++ b/test/lisp/gnus/message-tests.el
@@ -185,4 +185,4 @@ Hello.
(provide 'message-mode-tests)
-;;; message-mode-tests.el ends here
+;;; message-tests.el ends here
diff --git a/test/lisp/help-fns-tests.el b/test/lisp/help-fns-tests.el
index 513a0c2daea..24a42290a3f 100644
--- a/test/lisp/help-fns-tests.el
+++ b/test/lisp/help-fns-tests.el
@@ -148,7 +148,7 @@ Return first line of the output of (describe-function-1 FUNC)."
(ert-deftest help-fns-test-describe-keymap/value ()
(describe-keymap minibuffer-local-must-match-map)
(with-current-buffer "*Help*"
- (should (looking-at "^key"))))
+ (should (looking-at "\nKey"))))
(ert-deftest help-fns-test-describe-keymap/not-keymap ()
(should-error (describe-keymap nil))
@@ -158,7 +158,7 @@ Return first line of the output of (describe-function-1 FUNC)."
(let ((foobar minibuffer-local-must-match-map))
(describe-keymap foobar)
(with-current-buffer "*Help*"
- (should (looking-at "^key")))))
+ (should (looking-at "\nKey")))))
(ert-deftest help-fns-test-describe-keymap/dynamically-bound-no-file ()
(setq help-fns-test--describe-keymap-foo minibuffer-local-must-match-map)
diff --git a/test/lisp/help-tests.el b/test/lisp/help-tests.el
index 871417da3d2..281d97ee929 100644
--- a/test/lisp/help-tests.el
+++ b/test/lisp/help-tests.el
@@ -65,7 +65,7 @@
result))))
(test-re
(lambda (orig regexp)
- (should (string-match (concat "^" regexp "$")
+ (should (string-match (concat "\\`" regexp "\\'")
(substitute-command-keys orig))))))
,@body))
@@ -88,20 +88,37 @@
(test "\\[emacs-version]\\[next-line]" "M-x emacs-versionC-n")
(test-re "\\[emacs-version]`foo'" "M-x emacs-version[`'‘]foo['’]")))
-(ert-deftest help-tests-substitute-command-keys/keymaps ()
+(ert-deftest help-tests-substitute-command-keys/literal-key-sequence ()
+ "Literal replacement."
(with-substitute-command-keys-test
- (test "\\{minibuffer-local-must-match-map}"
- "\
-key binding
---- -------
+ (test "\\`C-m'" "C-m")
+ (test "\\`C-m'\\`C-j'" "C-mC-j")
+ (test "foo\\`C-m'bar\\`C-j'baz" "fooC-mbarC-jbaz")))
+
+(ert-deftest help-tests-substitute-command-keys/literal-key-sequence-errors ()
+ (should-error (substitute-command-keys "\\`'"))
+ (should-error (substitute-command-keys "\\`c-c'"))
+ (should-error (substitute-command-keys "\\`<foo bar baz>'")))
+
+(ert-deftest help-tests-substitute-key-bindings/face-help-key-binding ()
+ (should (eq (get-text-property 0 'face (substitute-command-keys "\\[next-line]"))
+ 'help-key-binding))
+ (should (eq (get-text-property 0 'face (substitute-command-keys "\\`f'"))
+ 'help-key-binding)))
+
+(ert-deftest help-tests-substitute-command-keys/keymaps ()
+ (with-substitute-command-keys-test
+ (test-re "\\{minibuffer-local-must-match-map}"
+ "
+Key Binding
+-+
C-g abort-minibuffers
TAB minibuffer-complete
C-j minibuffer-complete-and-exit
RET minibuffer-complete-and-exit
-ESC Prefix Command
SPC minibuffer-complete-word
-? minibuffer-completion-help
+\\? minibuffer-completion-help
C-<tab> file-cache-minibuffer-complete
<XF86Back> previous-history-element
<XF86Forward> next-history-element
@@ -110,11 +127,8 @@ C-<tab> file-cache-minibuffer-complete
<prior> switch-to-completions
<up> previous-line-or-history-element
-M-g Prefix Command
M-v switch-to-completions
-M-g ESC Prefix Command
-
M-< minibuffer-beginning-of-buffer
M-n next-history-element
M-p previous-history-element
@@ -122,7 +136,6 @@ M-r previous-matching-history-element
M-s next-matching-history-element
M-g M-c switch-to-completions
-
")))
(ert-deftest help-tests-substitute-command-keys/keymap-change ()
@@ -180,7 +193,7 @@ M-g M-c switch-to-completions
(let ((text-quoting-style 'grave))
(test "\\=`x\\='" "`x'"))))
-(ert-deftest help-tests-substitute-command-keys/no-change ()
+(ert-deftest help-tests-substitute-command-keys/no-change-2 ()
(with-substitute-command-keys-test
(test "\\[foobar" "\\[foobar")
(test "\\=" "\\=")))
@@ -249,11 +262,10 @@ M-g M-c switch-to-completions
(with-substitute-command-keys-test
(with-temp-buffer
(help-tests-major-mode)
- (test "\\{help-tests-major-mode-map}"
- "\
-key binding
---- -------
-
+ (test-re "\\{help-tests-major-mode-map}"
+ "
+Key Binding
+-+
( .. ) short-range
1 .. 4 foo-range
a .. c foo-other-range
@@ -261,7 +273,6 @@ a .. c foo-other-range
C-e foo-something
x foo-original
<F1> foo-function-key1
-
"))))
(ert-deftest help-tests-substitute-command-keys/shadow ()
@@ -269,11 +280,10 @@ x foo-original
(with-temp-buffer
(help-tests-major-mode)
(help-tests-minor-mode)
- (test "\\{help-tests-major-mode-map}"
- "\
-key binding
---- -------
-
+ (test-re "\\{help-tests-major-mode-map}"
+ "
+Key Binding
+-+
( .. ) short-range
1 .. 4 foo-range
a .. c foo-other-range
@@ -283,7 +293,6 @@ C-e foo-something
x foo-original
(this binding is currently shadowed)
<F1> foo-function-key1
-
"))))
(ert-deftest help-tests-substitute-command-keys/command-remap ()
@@ -292,15 +301,11 @@ x foo-original
(with-temp-buffer
(help-tests-major-mode)
(define-key help-tests-major-mode-map [remap foo] 'bar)
- (test "\\{help-tests-major-mode-map}"
- "\
-key binding
---- -------
-
-<remap> Prefix Command
-
+ (test-re "\\{help-tests-major-mode-map}"
+ "
+Key Binding
+-+
<remap> <foo> bar
-
")))))
(ert-deftest help-tests-describe-map-tree/no-menu-t ()
@@ -312,12 +317,11 @@ key binding
:enable mark-active
:help "Help text"))))))
(describe-map-tree map nil nil nil nil t nil nil nil)
- (should (equal (buffer-string) "key binding
---- -------
-
-C-a foo
-
-")))))
+ (should (string-match "
+Key Binding
+-+
+C-a foo\n"
+ (buffer-string))))))
(ert-deftest help-tests-describe-map-tree/no-menu-nil ()
(with-temp-buffer
@@ -328,15 +332,13 @@ C-a foo
:enable mark-active
:help "Help text"))))))
(describe-map-tree map nil nil nil nil nil nil nil nil)
- (should (equal (buffer-string) "key binding
---- -------
-
+ (should (string-match "
+Key Binding
+-+
C-a foo
-<menu-bar> Prefix Command
-<menu-bar> <foo> foo
-
-")))))
+<menu-bar> <foo> foo\n"
+ (buffer-string))))))
(ert-deftest help-tests-describe-map-tree/mention-shadow-t ()
(with-temp-buffer
@@ -345,14 +347,13 @@ C-a foo
(2 . bar))))
(shadow-maps '((keymap . ((1 . baz))))))
(describe-map-tree map t shadow-maps nil nil t nil nil t)
- (should (equal (buffer-string) "key binding
---- -------
-
+ (should (string-match "
+Key Binding
+-+
C-a foo
(this binding is currently shadowed)
-C-b bar
-
-")))))
+C-b bar\n"
+ (buffer-string))))))
(ert-deftest help-tests-describe-map-tree/mention-shadow-nil ()
(with-temp-buffer
@@ -361,12 +362,11 @@ C-b bar
(2 . bar))))
(shadow-maps '((keymap . ((1 . baz))))))
(describe-map-tree map t shadow-maps nil nil t nil nil nil)
- (should (equal (buffer-string) "key binding
---- -------
-
-C-b bar
-
-")))))
+ (should (string-match "
+Key Binding
+-+
+C-b bar\n"
+ (buffer-string))))))
(ert-deftest help-tests-describe-map-tree/partial-t ()
(with-temp-buffer
@@ -374,12 +374,11 @@ C-b bar
(map '(keymap . ((1 . foo)
(2 . undefined)))))
(describe-map-tree map t nil nil nil nil nil nil nil)
- (should (equal (buffer-string) "key binding
---- -------
-
-C-a foo
-
-")))))
+ (should (string-match "
+Key Binding
+-+
+C-a foo\n"
+ (buffer-string))))))
(ert-deftest help-tests-describe-map-tree/partial-nil ()
(with-temp-buffer
@@ -387,13 +386,12 @@ C-a foo
(map '(keymap . ((1 . foo)
(2 . undefined)))))
(describe-map-tree map nil nil nil nil nil nil nil nil)
- (should (equal (buffer-string) "key binding
---- -------
-
+ (should (string-match "
+Key Binding
+-+
C-a foo
-C-b undefined
-
-")))))
+C-b undefined\n"
+ (buffer-string))))))
(defvar help-tests--was-in-buffer nil)
diff --git a/test/lisp/hi-lock-tests.el b/test/lisp/hi-lock-tests.el
index 199512fe7de..200caa7e1ad 100644
--- a/test/lisp/hi-lock-tests.el
+++ b/test/lisp/hi-lock-tests.el
@@ -31,7 +31,8 @@
(with-temp-buffer
(insert "a A b B\n")
(cl-letf (((symbol-function 'completing-read)
- (lambda (_prompt _coll _x _y _z _hist defaults)
+ (lambda (_prompt _coll
+ &optional _x _y _z _hist defaults _inherit)
(car defaults))))
(dotimes (_ 2)
(let ((face (hi-lock-read-face-name)))
@@ -43,7 +44,8 @@
(with-temp-buffer
(insert "foo bar")
(cl-letf (((symbol-function 'completing-read)
- (lambda (_prompt _coll _x _y _z _hist defaults)
+ (lambda (_prompt _coll
+ &optional _x _y _z _hist defaults _inherit)
(car defaults))))
(hi-lock-set-pattern "9999" (hi-lock-read-face-name)) ; No match
(hi-lock-set-pattern "foo" (hi-lock-read-face-name)))
@@ -89,7 +91,8 @@
(let ((search-spaces-regexp search-whitespace-regexp)) (highlight-regexp "a a"))
(should (= (length (overlays-in (point-min) (point-max))) 1))
(cl-letf (((symbol-function 'completing-read)
- (lambda (_prompt _coll _x _y _z _hist defaults)
+ (lambda (_prompt _coll
+ &optional _x _y _z _hist defaults _inherit)
(car defaults))))
(call-interactively 'unhighlight-regexp))
(should (= (length (overlays-in (point-min) (point-max))) 0))
@@ -142,7 +145,8 @@
(font-lock-ensure)
(should (memq 'hi-yellow (get-text-property 1 'face)))
(cl-letf (((symbol-function 'completing-read)
- (lambda (_prompt _coll _x _y _z _hist defaults)
+ (lambda (_prompt _coll
+ &optional _x _y _z _hist defaults _inherit)
(car defaults)))
(font-lock-fontified t))
(call-interactively 'unhighlight-regexp))
@@ -155,7 +159,8 @@
(insert "aAbB\n")
(cl-letf (((symbol-function 'completing-read)
- (lambda (_prompt _coll _x _y _z _hist defaults)
+ (lambda (_prompt _coll
+ &optional _x _y _z _hist defaults _inherit)
(car defaults))))
(highlight-regexp "a")
diff --git a/test/lisp/htmlfontify-tests.el b/test/lisp/htmlfontify-tests.el
index 879131cae32..15798319a13 100644
--- a/test/lisp/htmlfontify-tests.el
+++ b/test/lisp/htmlfontify-tests.el
@@ -43,4 +43,4 @@ available (Bug#25468)."
0)))
(provide 'htmlfontify-tests)
-;; htmlfontify-tests.el ends here
+;;; htmlfontify-tests.el ends here
diff --git a/test/lisp/ibuffer-tests.el b/test/lisp/ibuffer-tests.el
index a51079180a5..9b0327b0ef0 100644
--- a/test/lisp/ibuffer-tests.el
+++ b/test/lisp/ibuffer-tests.el
@@ -826,4 +826,4 @@
(should (equal (ibuffer-unary-operand '(not . a)) 'a)))
(provide 'ibuffer-tests)
-;; ibuffer-tests.el ends here
+;;; ibuffer-tests.el ends here
diff --git a/test/lisp/image-dired-tests.el b/test/lisp/image-dired-tests.el
new file mode 100644
index 00000000000..3f0304ee405
--- /dev/null
+++ b/test/lisp/image-dired-tests.el
@@ -0,0 +1,37 @@
+;;; image-dired-tests.el --- Tests for image-dired.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021 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 'image-dired)
+
+(defun image-dired-test-image-file (name)
+ (expand-file-name
+ name (expand-file-name "data/image"
+ (or (getenv "EMACS_TEST_DIRECTORY")
+ "../"))))
+
+(ert-deftest image-dired-tests-get-exif-file-name ()
+ (skip-unless (image-type-available-p 'jpeg))
+ (let ((img (image-dired-test-image-file "black.jpg")))
+ (should (equal (image-dired-get-exif-file-name img)
+ "2019_09_21_16_22_13_black.jpg"))))
+
+;;; image-dired-tests.el ends here
diff --git a/test/lisp/image-tests.el b/test/lisp/image-tests.el
index aa8600609c4..79b0014f60a 100644
--- a/test/lisp/image-tests.el
+++ b/test/lisp/image-tests.el
@@ -28,6 +28,27 @@
(expand-file-name "images" data-directory)
"Directory containing Emacs images.")
+(defconst image-tests--files
+ `((gif . ,(expand-file-name "test/data/image/black.gif"
+ source-directory))
+ (jpeg . ,(expand-file-name "test/data/image/black.jpg"
+ source-directory))
+ (pbm . ,(expand-file-name "splash.pbm"
+ image-tests--emacs-images-directory))
+ (png . ,(expand-file-name "splash.png"
+ image-tests--emacs-images-directory))
+ (svg . ,(expand-file-name "splash.svg"
+ image-tests--emacs-images-directory))
+ (tiff . ,(expand-file-name
+ "nextstep/GNUstep/Emacs.base/Resources/emacs.tiff"
+ source-directory))
+ (webp . ,(expand-file-name "test/data/image/black.webp"
+ source-directory))
+ (xbm . ,(expand-file-name "gnus/gnus.xbm"
+ image-tests--emacs-images-directory))
+ (xpm . ,(expand-file-name "splash.xpm"
+ image-tests--emacs-images-directory))))
+
(ert-deftest image--set-property ()
"Test `image--set-property' behavior."
(let ((image (list 'image)))
@@ -49,12 +70,14 @@
(should (equal image '(image)))))
(ert-deftest image-find-image ()
- (find-image '((:type xpm :file "undo.xpm")))
- (find-image '((:type png :file "newsticker/rss-feed.png" :ascent center))))
+ (should (listp (find-image '((:type xpm :file "undo.xpm")))))
+ (should (listp (find-image '((:type png :file "newsticker/rss-feed.png" :ascent center)))))
+ (should-not (find-image '((:type png :file "does-not-exist-foo-bar.png")))))
(ert-deftest image-type-from-file-name ()
(should (eq (image-type-from-file-name "foo.jpg") 'jpeg))
- (should (eq (image-type-from-file-name "foo.png") 'png)))
+ (should (eq (image-type-from-file-name "foo.png") 'png))
+ (should (eq (image-type-from-file-name "foo.webp") 'webp)))
(ert-deftest image-type/from-filename ()
;; On emba, `image-types' and `image-load-path' do not exist.
@@ -62,12 +85,37 @@
(bound-and-true-p image-load-path)))
(should (eq (image-type "foo.jpg") 'jpeg)))
-(ert-deftest image-type-from-file-header-test ()
+(defun image-tests--type-from-file-header (type)
"Test image-type-from-file-header."
- (should (eq (if (image-type-available-p 'svg) 'svg)
- (image-type-from-file-header
- (expand-file-name "splash.svg"
- image-tests--emacs-images-directory)))))
+ (should (eq (if (image-type-available-p type) type)
+ (image-type-from-file-header (cdr (assq type image-tests--files))))))
+
+(ert-deftest image-type-from-file-header-test/gif ()
+ (image-tests--type-from-file-header 'gif))
+
+(ert-deftest image-type-from-file-header-test/jpeg ()
+ (image-tests--type-from-file-header 'jpeg))
+
+(ert-deftest image-type-from-file-header-test/pbm ()
+ (image-tests--type-from-file-header 'pbm))
+
+(ert-deftest image-type-from-file-header-test/png ()
+ (image-tests--type-from-file-header 'png))
+
+(ert-deftest image-type-from-file-header-test/svg ()
+ (image-tests--type-from-file-header 'svg))
+
+(ert-deftest image-type-from-file-header-test/tiff ()
+ (image-tests--type-from-file-header 'tiff))
+
+(ert-deftest image-type-from-file-header-test/webp ()
+ (image-tests--type-from-file-header 'webp))
+
+(ert-deftest image-type-from-file-header-test/xbm ()
+ (image-tests--type-from-file-header 'xbm))
+
+(ert-deftest image-type-from-file-header-test/xpm ()
+ (image-tests--type-from-file-header 'xpm))
(ert-deftest image-rotate ()
"Test `image-rotate'."
diff --git a/test/lisp/image/exif-tests.el b/test/lisp/image/exif-tests.el
index ddbee75467e..2357113f630 100644
--- a/test/lisp/image/exif-tests.el
+++ b/test/lisp/image/exif-tests.el
@@ -28,24 +28,19 @@
(or (getenv "EMACS_TEST_DIRECTORY")
"../../"))))
-(defun exif-elem (exif elem)
- (plist-get (seq-find (lambda (e)
- (eq elem (plist-get e :tag-name)))
- exif)
- :value))
-
(ert-deftest test-exif-parse ()
(let ((exif (exif-parse-file (test-image-file "black.jpg"))))
- (should (equal (exif-elem exif 'make) "Panasonic"))
- (should (equal (exif-elem exif 'orientation) 1))
- (should (equal (exif-elem exif 'x-resolution) '(180 . 1)))))
+ (should (equal (exif-field 'make exif) "Panasonic"))
+ (should (equal (exif-field 'orientation exif) 1))
+ (should (equal (exif-field 'x-resolution exif) '(180 . 1)))
+ (should (equal (exif-field 'date-time exif) "2019:09:21 16:22:13"))))
(ert-deftest test-exif-parse-short ()
(let ((exif (exif-parse-file (test-image-file "black-short.jpg"))))
- (should (equal (exif-elem exif 'make) "thr"))
- (should (equal (exif-elem exif 'model) "four"))
- (should (equal (exif-elem exif 'software) "em"))
- (should (equal (exif-elem exif 'artist) "z"))))
+ (should (equal (exif-field 'make exif) "thr"))
+ (should (equal (exif-field 'model exif) "four"))
+ (should (equal (exif-field 'software exif) "em"))
+ (should (equal (exif-field 'artist exif) "z"))))
(ert-deftest test-exit-direct-ascii-value ()
(should (equal (exif--direct-ascii-value 28005 2 t) (string ?e ?m 0)))
diff --git a/test/lisp/info-tests.el b/test/lisp/info-tests.el
new file mode 100644
index 00000000000..3e2aa3e089d
--- /dev/null
+++ b/test/lisp/info-tests.el
@@ -0,0 +1,39 @@
+;;; info-tests.el --- Tests for info.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 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 'info)
+(require 'ert)
+(require 'ert-x)
+
+(ert-deftest test-info-urls ()
+ (should (equal (Info-url-for-node "(emacs)Minibuffer")
+ "https://www.gnu.org/software/emacs/manual/html_node/emacs/Minibuffer.html"))
+ (should (equal (Info-url-for-node "(emacs)Minibuffer File")
+ "https://www.gnu.org/software/emacs/manual/html_node/emacs/Minibuffer-File.html"))
+ (should (equal (Info-url-for-node "(elisp)Backups and Auto-Saving")
+ "https://www.gnu.org/software/emacs/manual/html_node/elisp/Backups-and-Auto_002dSaving.html"))
+ (should-error (Info-url-for-node "(gnus)Minibuffer File")))
+
+;;; info-tests.el ends here
diff --git a/test/lisp/info-xref-tests.el b/test/lisp/info-xref-tests.el
index ecba86146f1..9379a53fe1d 100644
--- a/test/lisp/info-xref-tests.el
+++ b/test/lisp/info-xref-tests.el
@@ -22,6 +22,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'info-xref)
(defun info-xref-test-internal (body result)
@@ -96,15 +97,17 @@ text.
(ert-deftest info-xref-test-makeinfo ()
"Test that info-xref can parse basic makeinfo output."
(skip-unless (executable-find "makeinfo"))
- (let ((tempfile (make-temp-file "info-xref-test" nil ".texi"))
- (tempfile2 (make-temp-file "info-xref-test2" nil ".texi"))
- (errflag t))
- (unwind-protect
- (progn
- ;; tempfile contains xrefs to various things, including tempfile2.
- (info-xref-test-write-file
- tempfile
- (concat "\
+ (ert-with-temp-file tempfile
+ :suffix ".texi"
+ (ert-with-temp-file tempfile2
+ :suffix ".texi"
+ (let ((errflag t))
+ (unwind-protect
+ (progn
+ ;; tempfile contains xrefs to various things, including tempfile2.
+ (info-xref-test-write-file
+ tempfile
+ (concat "\
@xref{nodename,,,missing,Missing Manual}.
@xref{nodename,crossref,title,missing,Missing Manual}.
@@ -114,35 +117,36 @@ text.
@xref{Chapter One,Something}.
"
- (format "@xref{Chapter One,,,%s,Present Manual}.\n"
- (file-name-sans-extension (file-name-nondirectory
- tempfile2)))))
- ;; Something for tempfile to xref to.
- (info-xref-test-write-file tempfile2 "")
- (require 'info)
- (save-window-excursion
- (let ((Info-directory-list
- (list
- (or (file-name-directory tempfile) ".")))
- Info-additional-directory-list)
- (info-xref-check (format "%s.info" (file-name-sans-extension
- tempfile))))
- (should (equal (list info-xref-bad info-xref-good
- info-xref-unavail)
- '(0 1 2)))
- (setq errflag nil)
- ;; If there was an error, we can leave this around.
- (kill-buffer info-xref-output-buffer)))
- ;; Useful diagnostic in case of problems.
- (if errflag
- (with-temp-buffer
- (call-process "makeinfo" nil t nil "--version")
- (message "%s" (buffer-string))))
- (mapc 'delete-file (list tempfile tempfile2
- (format "%s.info" (file-name-sans-extension
- tempfile))
- (format "%s.info" (file-name-sans-extension
- tempfile2)))))))
+ (format "@xref{Chapter One,,,%s,Present Manual}.\n"
+ (file-name-sans-extension (file-name-nondirectory
+ tempfile2)))))
+ ;; Something for tempfile to xref to.
+ (info-xref-test-write-file tempfile2 "")
+ (require 'info)
+ (save-window-excursion
+ (let ((Info-directory-list
+ (list
+ (or (file-name-directory tempfile) ".")))
+ Info-additional-directory-list)
+ (info-xref-check (format "%s.info" (file-name-sans-extension
+ tempfile))))
+ (should (equal (list info-xref-bad info-xref-good
+ info-xref-unavail)
+ '(0 1 2)))
+ (setq errflag nil)
+ ;; If there was an error, we can leave this around.
+ (kill-buffer info-xref-output-buffer)))
+ ;; Useful diagnostic in case of problems.
+ (if errflag
+ (with-temp-buffer
+ (call-process "makeinfo" nil t nil "--version")
+ (message "%s" (buffer-string))))
+ (ignore-errors
+ (delete-file (format "%s.info" (file-name-sans-extension
+ tempfile))))
+ (ignore-errors
+ (delete-file (format "%s.info" (file-name-sans-extension
+ tempfile2)))))))))
(ert-deftest info-xref-test-emacs-manuals ()
"Test that all internal links in the Emacs manuals work."
@@ -161,4 +165,4 @@ text.
(line-end-position)))))))
-;;; info-xref.el ends here
+;;; info-xref-tests.el ends here
diff --git a/test/lisp/international/ccl-tests.el b/test/lisp/international/ccl-tests.el
index 0f765e4ff88..f3da2d88732 100644
--- a/test/lisp/international/ccl-tests.el
+++ b/test/lisp/international/ccl-tests.el
@@ -246,3 +246,5 @@ At EOF:
(registers [17 0 0 0 0 0 0 0]))
(ccl-execute compiled registers)
(should (equal registers [2 16 0 0 0 0 0 1])))))
+
+;;; ccl-tests.el ends here
diff --git a/test/lisp/international/mule-tests.el b/test/lisp/international/mule-tests.el
index 7727c118b2c..8ca1ade771d 100644
--- a/test/lisp/international/mule-tests.el
+++ b/test/lisp/international/mule-tests.el
@@ -23,7 +23,7 @@
;;; Code:
-(require 'ert-x) ;For `ert-run-keys'.
+(require 'ert-x) ;For `ert-simulate-keys'.
(ert-deftest find-auto-coding--bug27391 ()
"Check that Bug#27391 is fixed."
diff --git a/test/lisp/international/ucs-normalize-tests.el b/test/lisp/international/ucs-normalize-tests.el
index 51f4ed3a80e..eb577b97dc4 100644
--- a/test/lisp/international/ucs-normalize-tests.el
+++ b/test/lisp/international/ucs-normalize-tests.el
@@ -123,9 +123,9 @@ The following invariants must be true for all conformant implementations..."
(defsubst ucs-normalize-tests--rule2-holds-p (X)
"Check 2nd conformance rule.
-For every code point X assigned in this version of Unicode that is not specifically
-listed in Part 1, the following invariants must be true for all conformant
-implementations:
+For every code point X assigned in this version of Unicode that
+is not specifically listed in Part 1, the following invariants
+must be true for all conformant implementations:
X == toNFC(X) == toNFD(X) == toNFKC(X) == toNFKD(X)"
(and (ucs-normalize-tests--normalization-chareq-p NFC X X)
@@ -181,27 +181,34 @@ implementations:
(should-not (ucs-normalize-tests--rule1-failing-for-partX 0)))
(defconst ucs-normalize-tests--failing-lines-part1
- (list 2152 2418 15133 15134 15135 15136 15137 15138
- 15139 15140 15141 15142 16152 16153 16154 16155
- 16156 16157 16158 16159 16160 16161 16162 16163
- 16164 16165 16166 16167 16168 16169 16170 16171
- 16172 16173 16174 16175 16176 16177 16178 16179
- 16180 16181 16182 16183 16184 16185 16186 16187
- 16188 16189 16190 16191 16192 16193 16194 16195
- 16196 16197 16198 16199 16200 16201 16202 16203
- 16204 16205 16206 16207 16208 16209 16210 16211
- 16212 16213 16214 16215 16216 16217 16218 16219
- 16220 16221 16222 16223 16224 16225 16226 16227
- 16228 16229 16230 16231 16232 16233 16234 16235
- 16236 16237 16238 16239 16240 16241 16242 16243
- 16244 16245 16246 16247 16248 16249 16250 16251
- 16252 16253 16254 16255 16256 16257 16258 16259
- 16260 16261 16262 16263 16264 16265 16266 16267
- 16268 16269 16270 16271 16272 16273 16274 16275
- 16276 16277 16278 16279 16280 16281 16282 16283
- 16284 16285 16286 16287 16288 16289 16290 16291
- 16292 16429 16430 16431 16432 16433 16434 16435
- 16436 16437 16438))
+ (list 2412 2413 2414 15133 15134 15135 15136 15137
+ 15138 15139 15140 15141 15142 15143 15144 15145
+ 15146 15147 15148 15149 15150 15151 15152 15153
+ 15154 15155 15156 15157 15158 15159 15160 15161
+ 15162 15163 15164 15165 15166 15167 15168 15169
+ 15170 15171 15172 15173 15174 15175 15176 15177
+ 15178 15179 15180 15181 15182 15183 15184 15185
+ 15186 15187 15188 15192 15193 15194 15195 15196
+ 15197 15198 15199 15200 15201 16211 16212 16213
+ 16214 16215 16216 16217 16218 16219 16220 16221
+ 16222 16223 16224 16225 16226 16227 16228 16229
+ 16230 16231 16232 16233 16234 16235 16236 16237
+ 16238 16239 16240 16241 16242 16243 16244 16245
+ 16246 16247 16248 16249 16250 16251 16252 16253
+ 16254 16255 16256 16257 16258 16259 16260 16261
+ 16262 16263 16264 16265 16266 16267 16268 16269
+ 16270 16271 16272 16273 16274 16275 16276 16277
+ 16278 16279 16280 16281 16282 16283 16284 16285
+ 16286 16287 16288 16289 16290 16291 16292 16293
+ 16294 16295 16296 16297 16298 16299 16300 16301
+ 16302 16303 16304 16305 16306 16307 16308 16309
+ 16310 16311 16312 16313 16314 16315 16316 16317
+ 16318 16319 16320 16321 16322 16323 16324 16325
+ 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))
;; Keep a record of failures, for consulting afterwards (the ert
;; backtrace only shows a truncated version of these lists).
@@ -233,6 +240,7 @@ implementations:
(ert-deftest ucs-normalize-part1 ()
:tags '(:expensive-test)
+ (skip-unless (not (getenv "EMACS_HYDRA_CI"))) ; SLOW ~ 1800s
;; This takes a long time, so make sure we're compiled.
(dolist (fun '(ucs-normalize-tests--part1-rule2
ucs-normalize-tests--rule1-failing-for-partX
@@ -259,28 +267,76 @@ implementations:
ucs-normalize-tests--failing-lines-part1)))
(defconst ucs-normalize-tests--failing-lines-part2
- (list 17634 17635 17646 17647 17652 17653 17656 17657
- 17660 17661 17672 17673 17750 17751 17832 17834
- 17836 17837 17862 17863 17868 17869 18222 18270
- 18271 18368 18370 18400 18401 18402 18404 18406
- 18408 18410 18412 18413 18414 18416 18417 18418
- 18420 18421 18422 18423 18424 18426 18427 18428
- 18429 18430 18432 18434 18436 18438 18440 18442
- 18444 18446 18448 18450 18452 18454 18456 18458
- 18459 18460 18462 18464 18465 18466 18468 18469
- 18470 18472 18474 18475 18476 18478 18480 18481
- 18482 18484 18486 18487 18488 18490 18492 18494
- 18496 18498 18499 18500 18502 18504 18506 18508
- 18510 18512 18514 18516 18518 18520 18522 18524
- 18526 18528 18530 18531 18532 18533 18534 18602
- 18604 18606 18608 18610 18612 18614 18616 18618
- 18620 18622 18624 18626 18628 18630 18632 18634
- 18636 18638 18640 18642 18644 18646 18648 18650
- 18652 18654 18656 18658 18660 18662 18664 18666
- 18668 18670 18672 18674 18676 18678 18680 18682
- 18684 18686 18688 18690 18692 18694 18696 18698
- 18700 18702 18704 18706 18708 18710 18712 18714
- 18716 18718 18720 18722 18724 18726 18727))
+ (list 17087 17088 17089 17090 17091 17092 17093 17094
+ 17098 17099 17100 17101 17102 17103 17104 17105
+ 17106 17107 17108 17113 17114 17115 17116 17117
+ 17118 17119 17120 17125 17126 17127 17128 17129
+ 17130 17131 17132 17133 17134 17135 17136 17137
+ 17138 17139 17140 17141 17142 17143 17144 17145
+ 17146 17157 17158 17159 17160 17161 17162 17163
+ 17164 17185 17186 17187 17188 17189 17190 17197
+ 17198 17199 17200 17207 17208 17209 17210 17211
+ 17212 17213 17214 17219 17220 17221 17222 17275
+ 17276 17285 17286 17295 17296 17309 17310 17311
+ 17312 17313 17314 17315 17316 17317 17318 17319
+ 17320 17325 17326 17373 17374 17419 17420 17421
+ 17422 17433 17434 17439 17440 17465 17466 17473
+ 17474 17479 17480 17485 17486 17491 17492 17497
+ 17498 17499 17500 17501 17502 17505 17506 17507
+ 17508 17511 17512 17519 17520 17523 17524 17527
+ 17528 17531 17532 17551 17552 17555 17556 17599
+ 17600 17601 17602 17603 17604 17605 17607 17608
+ 17609 17610 17611 17612 17613 17615 17617 17619
+ 17621 17623 17625 17627 17629 17631 17632 17633
+ 17634 17635 17636 17637 17638 17639 17640 17669
+ 17670 17675 17676 17681 17682 17689 17690 17691
+ 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
+ 18069 18070 18079 18080 18163 18164 18165 18166
+ 18171 18172 18175 18176 18211 18212 18219 18220
+ 18221 18222 18223 18224 18225 18226 18301 18302
+ 18389 18390 18391 18392 18393 18394 18397 18398
+ 18407 18408 18439 18440 18441 18442 18443 18444
+ 18445 18446 18447 18448 18449 18450 18451 18452
+ 18457 18458 18459 18460 18471 18472 18479 18480
+ 18485 18486 18499 18500 18501 18502 18509 18510
+ 18513 18514 18515 18516 18517 18518 18519 18520
+ 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))
(ert-deftest ucs-normalize-part2 ()
:tags '(:expensive-test)
diff --git a/test/lisp/jit-lock-tests.el b/test/lisp/jit-lock-tests.el
index 121966b2b77..a54aad8165c 100644
--- a/test/lisp/jit-lock-tests.el
+++ b/test/lisp/jit-lock-tests.el
@@ -58,3 +58,5 @@
(with-silent-modifications
(put-text-property (point-min) (point-max) 'fontified t))
(jit-lock-fontify-now (point-min) (point-max))))
+
+;;; jit-lock-tests.el ends here
diff --git a/test/lisp/kmacro-tests.el b/test/lisp/kmacro-tests.el
index 8736f7fd2dc..ecd3d5fc22b 100644
--- a/test/lisp/kmacro-tests.el
+++ b/test/lisp/kmacro-tests.el
@@ -834,7 +834,7 @@ and `read-event' and `read-key-sequence' set up to return items from
EVENTS and SEQUENCES respectively. SEQUENCES may be nil, but
EVENTS should not be. EVENTS should be a list of symbols bound
in `kmacro-step-edit-map' or `query-replace' map, and this function
-will do the keymap lookup for you. SEQUENCES should contain
+will do the keymap lookup for you. SEQUENCES should contain
return values for `read-key-sequence'.
Before running the macro, the current buffer will be erased.
diff --git a/test/lisp/ls-lisp-tests.el b/test/lisp/ls-lisp-tests.el
index e386398eea2..9f2c63225b5 100644
--- a/test/lisp/ls-lisp-tests.el
+++ b/test/lisp/ls-lisp-tests.el
@@ -25,6 +25,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'ls-lisp)
(require 'dired)
@@ -53,28 +54,29 @@
(kill-buffer buf)
(setq buf (dired (nconc (list dir) files)))
(should (looking-at "src"))
- (next-line) ; File names must be aligned.
+ (with-suppressed-warnings ((interactive-only next-line))
+ (next-line)) ; File names must be aligned.
(should (looking-at "src")))
(when (buffer-live-p buf) (kill-buffer buf)))))
(ert-deftest ls-lisp-test-bug27631 ()
"Test for https://debbugs.gnu.org/27631 ."
- (let* ((dir (make-temp-file "bug27631" 'dir))
- (dir1 (expand-file-name "dir1" dir))
- (dir2 (expand-file-name "dir2" dir))
- (default-directory dir)
- ls-lisp-use-insert-directory-program buf)
- (unwind-protect
- (progn
- (make-directory dir1)
- (make-directory dir2)
- (with-temp-file (expand-file-name "a.txt" dir1))
- (with-temp-file (expand-file-name "b.txt" dir2))
- (setq buf (dired (expand-file-name "dir*/*.txt" dir)))
- (dired-toggle-marks)
- (should (cdr (dired-get-marked-files))))
- (delete-directory dir 'recursive)
- (when (buffer-live-p buf) (kill-buffer buf)))))
+ (ert-with-temp-directory dir
+ :suffix "bug27631"
+ (let* ((dir1 (expand-file-name "dir1" dir))
+ (dir2 (expand-file-name "dir2" dir))
+ (default-directory dir)
+ ls-lisp-use-insert-directory-program buf)
+ (unwind-protect
+ (progn
+ (make-directory dir1)
+ (make-directory dir2)
+ (with-temp-file (expand-file-name "a.txt" dir1))
+ (with-temp-file (expand-file-name "b.txt" dir2))
+ (setq buf (dired (expand-file-name "dir*/*.txt" dir)))
+ (dired-toggle-marks)
+ (should (cdr (dired-get-marked-files))))
+ (when (buffer-live-p buf) (kill-buffer buf))))))
(ert-deftest ls-lisp-test-bug27693 ()
"Test for https://debbugs.gnu.org/27693 ."
diff --git a/test/lisp/mail/mail-utils-tests.el b/test/lisp/mail/mail-utils-tests.el
index 5b54f2440c7..f75de5c620c 100644
--- a/test/lisp/mail/mail-utils-tests.el
+++ b/test/lisp/mail/mail-utils-tests.el
@@ -85,7 +85,8 @@
"foo@example.org\\|bar@example.org\\|baz@example.org")))
(ert-deftest mail-utils-tests-mail-rfc822-time-zone ()
- (should (stringp (mail-rfc822-time-zone (current-time)))))
+ (with-suppressed-warnings ((obsolete mail-rfc822-time-zone))
+ (should (stringp (mail-rfc822-time-zone (current-time))))))
(ert-deftest mail-utils-test-mail-rfc822-date/contains-year ()
(should (string-match (rx " 20" digit digit " ")
diff --git a/test/lisp/mail/rfc6068-tests.el b/test/lisp/mail/rfc6068-tests.el
new file mode 100644
index 00000000000..caf8230cb1e
--- /dev/null
+++ b/test/lisp/mail/rfc6068-tests.el
@@ -0,0 +1,52 @@
+;;; rfc6068-tests.el --- Tests for rfc6068.el -*- lexical-binding:t -*-
+
+;; Copyright (C) 2020-2021 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 'rfc6068)
+
+(ert-deftest rfc6068-unhexify-string ()
+ (should (equal (rfc6068-unhexify-string "hello%20there") "hello there"))
+ (should (equal (rfc6068-unhexify-string "caf%C3%A9") "café")))
+
+(ert-deftest rfc6068-parse-mailto-url ()
+ (should
+ (equal
+ (rfc6068-parse-mailto-url "mailto:foo@example.org?subject=Foo&bar=baz")
+ '(("To" . "foo@example.org") ("Subject" . "Foo") ("Bar" . "baz"))))
+ (should
+ (equal
+ (rfc6068-parse-mailto-url "mailto:foo@bar.com?to=bar@example.org")
+ '(("To" . "foo@bar.com, bar@example.org"))))
+ (should
+ (equal (rfc6068-parse-mailto-url "mailto:foo@bar.com?subject=bar%20baz")
+ '(("To" . "foo@bar.com") ("Subject" . "bar baz"))))
+ (should
+ (equal (rfc6068-parse-mailto-url "mailto:foo@bar.com?subject=bar%20baz&to=other@bar.com")
+ '(("Subject" . "bar baz") ("To" . "foo@bar.com, other@bar.com"))))
+ (should
+ (equal (rfc6068-parse-mailto-url "mailto:user@example.org?subject=caf%C3%A9&body=caf%C3%A9")
+ '(("To" . "user@example.org") ("Subject" . "café") ("Body" . "café")))))
+
+(provide 'rfc6068-tests)
+
+;;; rfc6068-tests.el ends here
diff --git a/test/lisp/mail/rmail-tests.el b/test/lisp/mail/rmail-tests.el
index f533401496b..826a90455fb 100644
--- a/test/lisp/mail/rmail-tests.el
+++ b/test/lisp/mail/rmail-tests.el
@@ -32,4 +32,4 @@
'rmail-edit-current-message))))
(provide 'rmail-tests)
-;; rmail-tests.el ends here
+;;; rmail-tests.el ends here
diff --git a/test/lisp/mail/rmailmm-tests.el b/test/lisp/mail/rmailmm-tests.el
index a022008b534..d7b3775d6d0 100644
--- a/test/lisp/mail/rmailmm-tests.el
+++ b/test/lisp/mail/rmailmm-tests.el
@@ -114,4 +114,4 @@ This is the epilogue. It is also to be ignored."))
(provide 'rmailmm-tests)
-;; rmailmm-tests.el ends here
+;;; rmailmm-tests.el ends here
diff --git a/test/lisp/mail/uudecode-tests.el b/test/lisp/mail/uudecode-tests.el
index 6ff767562e3..1899ff50f69 100644
--- a/test/lisp/mail/uudecode-tests.el
+++ b/test/lisp/mail/uudecode-tests.el
@@ -35,11 +35,11 @@
(defvar uudecode-tests-encoded-str
(uudecode-tests-read-file (ert-resource-file "uuencoded.txt"))
- "Uuencoded data for bookmark-tests.el
+ "Uuencoded data for bookmark-tests.el.
Same as `uudecode-tests-decoded-str' but uuencoded.")
(defvar uudecode-tests-decoded-str
(uudecode-tests-read-file (ert-resource-file "uudecoded.txt"))
- "Plain text data for bookmark-tests.el
+ "Plain text data for bookmark-tests.el.
Same as `uudecode-tests-encoded-str' but plain text.")
(ert-deftest uudecode-tests-decode-region-internal ()
@@ -50,14 +50,11 @@ Same as `uudecode-tests-encoded-str' but plain text.")
(should (equal (buffer-string) uudecode-tests-decoded-str)))
;; Write to file
(with-temp-buffer
- (let ((tmpfile (make-temp-file "uudecode-tests-")))
- (unwind-protect
- (progn
- (insert uudecode-tests-encoded-str)
- (uudecode-decode-region-internal (point-min) (point-max) tmpfile)
- (should (equal (uudecode-tests-read-file tmpfile)
- uudecode-tests-decoded-str)))
- (delete-file tmpfile)))))
+ (ert-with-temp-file tmpfile
+ (insert uudecode-tests-encoded-str)
+ (uudecode-decode-region-internal (point-min) (point-max) tmpfile)
+ (should (equal (uudecode-tests-read-file tmpfile)
+ uudecode-tests-decoded-str)))))
(ert-deftest uudecode-tests-decode-region-external ()
;; Write to buffer
@@ -68,14 +65,11 @@ Same as `uudecode-tests-encoded-str' but plain text.")
(should (equal (buffer-string) uudecode-tests-decoded-str)))
;; Write to file
(with-temp-buffer
- (let ((tmpfile (make-temp-file "uudecode-tests-")))
- (unwind-protect
- (progn
- (insert uudecode-tests-encoded-str)
- (uudecode-decode-region-external (point-min) (point-max) tmpfile)
- (should (equal (uudecode-tests-read-file tmpfile)
- uudecode-tests-decoded-str)))
- (delete-file tmpfile))))))
+ (ert-with-temp-file tmpfile
+ (insert uudecode-tests-encoded-str)
+ (uudecode-decode-region-external (point-min) (point-max) tmpfile)
+ (should (equal (uudecode-tests-read-file tmpfile)
+ uudecode-tests-decoded-str))))))
(provide 'uudecode-tests)
;;; uudecode-tests.el ends here
diff --git a/test/lisp/mh-e/mh-limit-tests.el b/test/lisp/mh-e/mh-limit-tests.el
new file mode 100644
index 00000000000..982573d9b49
--- /dev/null
+++ b/test/lisp/mh-e/mh-limit-tests.el
@@ -0,0 +1,35 @@
+;;; mh-limit-tests.el --- tests for mh-limit.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021 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 'mh-limit)
+
+(ert-deftest mh-pick-args-list ()
+ "Test `mh-pick-args-list'."
+ (should (equal '() (mh-pick-args-list "")))
+ (should (equal '("-subject" "a") (mh-pick-args-list "-subject a")))
+ (should (equal '("-subject" "a") (mh-pick-args-list " -subject a ")))
+ (should (equal '("-subject" "a" "-from" "b")
+ (mh-pick-args-list "-subject a -from b")))
+ (should (equal '("-subject" "a b" "-from" "c d")
+ (mh-pick-args-list "-subject a b -from c d"))))
+
+;;; mh-limit-tests.el ends here
diff --git a/test/lisp/mh-e/mh-thread-tests.el b/test/lisp/mh-e/mh-thread-tests.el
new file mode 100644
index 00000000000..4f09677e53f
--- /dev/null
+++ b/test/lisp/mh-e/mh-thread-tests.el
@@ -0,0 +1,131 @@
+;;; mh-thread-tests.el --- tests for mh-thread.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021 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 'mh-thread)
+(eval-when-compile (require 'cl-lib))
+
+(defun mh-thread-tests-before-from ()
+ "Generate the fields of a scan line up to where the 'From' field would start.
+The exact contents are not important, but the number of characters is."
+ (concat (make-string mh-cmd-note ?9)
+ (make-string mh-scan-cmd-note-width ?A)
+ (make-string mh-scan-destination-width ?t)
+ (make-string mh-scan-date-width ?/)
+ (make-string mh-scan-date-flag-width ?*)))
+
+;;; Tests of support routines
+
+(ert-deftest mh-thread-current-indentation-level ()
+ "Test that `mh-thread-current-indentation-level' identifies the level."
+ (with-temp-buffer
+ (insert (mh-thread-tests-before-from) "[Sender One] Subject of msg 1\n")
+ (insert (mh-thread-tests-before-from) " [Sender Two] Subject of msg 2\n")
+ (goto-char (point-min))
+ (should (equal 0 (mh-thread-current-indentation-level)))
+ (forward-line)
+ (should (equal 2 (mh-thread-current-indentation-level)))))
+
+(ert-deftest mh-thread-find-children ()
+ "Test `mh-thread-find-children'."
+ (let (expected-start expected-end)
+ (with-temp-buffer
+ (insert (mh-thread-tests-before-from) "[Sender One] line 1\n")
+ (setq expected-start (point))
+ (insert (mh-thread-tests-before-from) " [Sender Two] line 2\n")
+ (insert (mh-thread-tests-before-from) " [Sender Three] line 3\n")
+ (insert (mh-thread-tests-before-from) " [Sender Four] line 4\n")
+ (setq expected-end (1- (point)))
+ (insert (mh-thread-tests-before-from) " [Sender Five] line 5\n")
+ (goto-char (1+ expected-start))
+ (should (equal (list expected-start expected-end)
+ (mh-thread-find-children))))))
+
+(ert-deftest mh-thread-immediate-ancestor ()
+ "Test that `mh-thread-immediate-ancestor' moves to the correct message."
+ (with-temp-buffer
+ (insert (mh-thread-tests-before-from) "[Sender Other] line 1\n")
+ (insert (mh-thread-tests-before-from) "[Sender One] line 2\n")
+ (insert (mh-thread-tests-before-from) " [Sender Two] line 3\n")
+ (insert (mh-thread-tests-before-from) " [Sender Three] line 4\n")
+ (insert (mh-thread-tests-before-from) " [Sender Four] line 5\n")
+ (insert (mh-thread-tests-before-from) " [Sender Five] line 6\n")
+ (forward-line -1)
+ (should (equal (line-number-at-pos) 6))
+ (mh-thread-immediate-ancestor)
+ (should (equal (line-number-at-pos) 4)) ;skips over sibling
+ (mh-thread-immediate-ancestor)
+ (should (equal (line-number-at-pos) 3)) ;goes up only one level at a time
+ (mh-thread-immediate-ancestor)
+ (should (equal (line-number-at-pos) 2))
+ (mh-thread-immediate-ancestor)
+ (should (equal (line-number-at-pos) 2)))) ;no further motion at thread root
+
+;;; Tests of MH-Folder Commands
+
+(ert-deftest mh-thread-sibling-and-ancestor ()
+ "Test motion by `mh-thread-ancestor' and `mh-thread-next-sibling'."
+ (with-temp-buffer
+ (insert (mh-thread-tests-before-from) "[Sender Other] line 1\n")
+ (insert (mh-thread-tests-before-from) "[Sender One] line 2\n")
+ (insert (mh-thread-tests-before-from) " [Sender Two] line 3\n")
+ (insert (mh-thread-tests-before-from) " [Sender Three] line 4\n")
+ (insert (mh-thread-tests-before-from) " [Sender Four] line 5\n")
+ (insert (mh-thread-tests-before-from) " [Sender Five] line 6\n")
+ (forward-line -1)
+ (let ((mh-view-ops '(unthread))
+ (show-count 0))
+ (cl-letf (((symbol-function 'mh-maybe-show)
+ (lambda ()
+ (setq show-count (1+ show-count)))))
+ (should (equal (line-number-at-pos) 6))
+ ;; test mh-thread-ancestor
+ (mh-thread-ancestor)
+ (should (equal (line-number-at-pos) 4)) ;skips over sibling
+ (should (equal show-count 1))
+ (mh-thread-ancestor t)
+ (should (equal (line-number-at-pos) 2)) ;root flag skips to root
+ (should (equal show-count 2))
+ (mh-thread-ancestor)
+ (should (equal (line-number-at-pos) 2)) ;do not move from root
+ (should (equal show-count 2)) ;do not re-show at root
+ ;; test mh-thread-sibling
+ (mh-thread-next-sibling)
+ (should (equal (line-number-at-pos) 2)) ;no next sibling, no motion
+ (should (equal show-count 2)) ;no sibling, no show
+ (mh-thread-next-sibling t)
+ (should (equal (line-number-at-pos) 1))
+ (should (equal show-count 3))
+ (mh-thread-next-sibling t)
+ (should (equal (line-number-at-pos) 1)) ;no previous sibling
+ (should (equal show-count 3))
+ (goto-char (point-max))
+ (forward-line -1)
+ (should (equal (line-number-at-pos) 6))
+ (mh-thread-next-sibling t)
+ (should (equal (line-number-at-pos) 5))
+ (should (equal show-count 4))
+ (mh-thread-next-sibling t)
+ (should (equal (line-number-at-pos) 5)) ;no previous sibling
+ (should (equal show-count 4))
+ ))))
+
+;;; mh-thread-tests.el ends here
diff --git a/test/lisp/mh-e/mh-utils-tests.el b/test/lisp/mh-e/mh-utils-tests.el
new file mode 100644
index 00000000000..f282a0b08f3
--- /dev/null
+++ b/test/lisp/mh-e/mh-utils-tests.el
@@ -0,0 +1,549 @@
+;;; mh-utils-tests.el --- tests for mh-utils.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021 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:
+
+;; This test suite runs tests that use and depend on MH programs
+;; installed on the system.
+
+;; When running such tests, MH-E can use a particular MH variant
+;; installed on the system, or it can use the mocks provided here.
+;; (Setup is done by the `with-mh-test-env' macro.)
+
+;; By setting environment variable TEST_MH_PATH, you can select which of
+;; the installed MH variants to use, or ignore them all and use mocks.
+;; See also the script test-all-mh-variants.sh in this directory.
+
+;; 1. To run these tests against the default MH variant installed on
+;; this system:
+;; cd ../.. && make lisp/mh-e/mh-utils-tests
+
+;; 2. To run these tests against an MH variant installed in a
+;; specific directory, set TEST_MH_PATH, as in this example:
+;; cd ../.. && make lisp/mh-e/mh-utils-tests TEST_MH_PATH=/usr/local/nmh/bin
+
+;; 3. To search for and run these tests against all MH variants
+;; installed on this system:
+;; ./test-all-mh-variants.sh
+
+;; Setting the environment variable TEST_MH_DEBUG or the Lisp variable
+;; mh-test-utils-debug-mocks logs access to the file system during the test.
+
+;;; Code:
+
+(require 'ert)
+(eval-when-compile (require 'cl-lib))
+(require 'mh-utils)
+
+(ert-deftest mh-quote-pick-expr ()
+ "Test `mh-quote-pick-expr'."
+ (should (equal nil (mh-quote-pick-expr nil)))
+ (should (equal '() (mh-quote-pick-expr '())))
+ (should (equal '("foo") (mh-quote-pick-expr '("foo"))))
+ (should (equal '("^\\[foo]?\\*+\\.\\$")
+ (mh-quote-pick-expr '("^[foo]?*+.$"))))
+ (should (equal '("^\\[foo]?\\*+\\.\\$" "bar" "baz\\$")
+ (mh-quote-pick-expr '("^[foo]?*+.$" "bar" "baz$")))))
+
+(ert-deftest mh-normalize-folder-name ()
+ "Test `mh-normalize-folder-name'."
+ (should (equal nil (mh-normalize-folder-name nil)))
+ (should (equal "+" (mh-normalize-folder-name "")))
+ (should (equal "" (mh-normalize-folder-name "" t)))
+ (should (equal nil (mh-normalize-folder-name "" nil nil t)))
+ (should (equal nil (mh-normalize-folder-name "+" nil nil t)))
+ (should (equal nil (mh-normalize-folder-name "+" t t t)))
+ (should (equal "+inbox" (mh-normalize-folder-name "inbox")))
+ (should (equal "+inbox" (mh-normalize-folder-name "+inbox")))
+ (should (equal "+inbox" (mh-normalize-folder-name "+inbox/")))
+ (should (equal "+inbox/" (mh-normalize-folder-name "+inbox/" t t t)))
+ (should (equal "+inbox/" (mh-normalize-folder-name "+inbox/" nil t)))
+ (should (equal "+news" (mh-normalize-folder-name "+inbox////../news")))
+ (should (equal "+news" (mh-normalize-folder-name "+inbox////../news/")))
+ (should (equal "+news/"
+ (mh-normalize-folder-name "+inbox////../news/" nil t)))
+ (should (equal "+inbox/news" (mh-normalize-folder-name "+inbox////./news"))))
+
+(ert-deftest mh-sub-folders-parse-no-folder ()
+ "Test `mh-sub-folders-parse' with no starting folder."
+ (let (others-position)
+ (with-temp-buffer
+ (insert "lines without has-string are ignored\n")
+ (insert "onespace has no messages.\n")
+ (insert "twospace has no messages.\n")
+ (insert " precedingblanks has no messages.\n")
+ (insert ".leadingdot has no messages.\n")
+ (insert "#leadinghash has no messages.\n")
+ (insert ",leadingcomma has no messages.\n")
+ (insert "withothers has no messages ; (others)")
+ (setq others-position (point))
+ (insert ".\n")
+ (insert "curf has no messages.\n")
+ (insert "curf+ has 123 messages.\n")
+ (insert "curf2+ has 17 messages.\n")
+ (insert "\ntotal after blank line is ignored has no messages.\n")
+ (should (equal
+ (mh-sub-folders-parse nil "curf+")
+ (list '("onespace") '("twospace") '("precedingblanks")
+ (cons "withothers" others-position)
+ '("curf") '("curf") '("curf2+")))))))
+
+(ert-deftest mh-sub-folders-parse-relative-folder ()
+ "Test `mh-sub-folders-parse' with folder."
+ (let (others-position)
+ (with-temp-buffer
+ (insert "testf+ has no messages.\n")
+ (insert "testf/sub1 has no messages.\n")
+ (insert "testf/sub2 has no messages ; (others)")
+ (setq others-position (point))
+ (insert ".\n")
+ (should (equal
+ (mh-sub-folders-parse "+testf" "testf+")
+ (list '("sub1") (cons "sub2" others-position)))))))
+
+(ert-deftest mh-sub-folders-parse-root-folder ()
+ "Test `mh-sub-folders-parse' with root folder."
+ (with-temp-buffer
+ (insert "/+ has no messages.\n")
+ (insert "/ has no messages.\n")
+ (insert "//nmh-style has no messages.\n")
+ (insert "/mu-style has no messages.\n")
+ (should (equal
+ (mh-sub-folders-parse "+/" "inbox+")
+ '(("") ("nmh-style") ("mu-style"))))))
+
+
+;; Folder names that are used by the following tests.
+(defvar mh-test-rel-folder "rela-folder")
+(defvar mh-test-abs-folder "/abso-folder")
+(defvar mh-test-no-such-folder "/testdir/none" "A folder that does not exist.")
+
+(defvar mh-test-utils-variants nil
+ "The value of `mh-variants' used for these tests.
+This variable allows setting `mh-variants' to a limited set for targeted
+testing. Its value can be different from the normal value when
+environment variable TEST_MH_PATH is set. By remembering the value, we
+can log the choice only once, which makes the batch log easier to read.")
+
+(defvar mh-test-variant-logged-already nil
+ "Whether `with-mh-test-env' has written the MH variant to the log.")
+
+(defvar mh-test-utils-debug-mocks (> (length (getenv "TEST_MH_DEBUG")) 0)
+ "Whether to log detailed behavior of mock functions.")
+
+(defvar mh-test-call-process-real (symbol-function 'call-process))
+(defvar mh-test-file-directory-p-real (symbol-function 'file-directory-p))
+
+;;; The macro with-mh-test-env wraps tests that touch the file system
+;;; and/or run programs.
+
+(defmacro with-mh-test-env (&rest body)
+ "Evaluate BODY with a test mail environment.
+Functions that touch the file system or run MH programs are either
+mocked out or pointed at a test tree. Uses `mh-test-utils-setup' to
+select which."
+ (declare (indent 0) (debug t))
+ `(cl-letf ((temp-home-dir nil)
+ ;; make local bindings for things we will modify for test env
+ (mh-user-path)
+ (mh-test-abs-folder)
+ ((symbol-function 'call-process))
+ ((symbol-function 'file-directory-p))
+ ;; the test always gets its own sub-folders cache
+ (mh-sub-folders-cache (make-hash-table :test #'equal))
+ ;; Allow envvar TEST_MH_PATH to control mh-variants.
+ (mh-variants mh-test-utils-variants)
+ ;; remember the original value
+ (original-mh-test-variant-logged mh-test-variant-logged-already)
+ (original-mh-path mh-path)
+ (original-mh-sys-path mh-sys-path)
+ (original-exec-path exec-path)
+ (original-mh-variant-in-use mh-variant-in-use)
+ (original-mh-progs mh-progs)
+ (original-mh-lib mh-lib)
+ (original-mh-lib-progs mh-lib-progs)
+ (original-mh-envvar (getenv "MH")))
+ (unwind-protect
+ (progn
+ (setq temp-home-dir (mh-test-utils-setup))
+ ,@body)
+ (unless noninteractive
+ ;; If interactive, forget that we logged the variant and
+ ;; restore any changes TEST_MH_PATH made.
+ (setq mh-test-variant-logged-already original-mh-test-variant-logged
+ mh-path original-mh-path
+ mh-sys-path original-mh-sys-path
+ exec-path original-exec-path
+ mh-variant-in-use original-mh-variant-in-use
+ mh-progs original-mh-progs
+ mh-lib original-mh-lib
+ mh-lib-progs original-mh-lib-progs))
+ (if temp-home-dir (delete-directory temp-home-dir t))
+ (setenv "MH" original-mh-envvar))))
+
+(defun mh-test-utils-setup ()
+ "Set dynamically bound variables needed by mock and/or variants.
+Call `mh-variant-set' to look through the directories named by
+environment variable `TEST_MH_PATH' (default: `mh-path' and `mh-sys-path')
+to find the MH variant to use, if any.
+Return the name of the root of the created directory tree, if any."
+ (when (getenv "TEST_MH_PATH")
+ ;; force mh-variants to use only TEST_MH_PATH
+ (setq mh-path (split-string (getenv "TEST_MH_PATH") path-separator t)
+ mh-sys-path nil
+ exec-path '("/bin" "/usr/bin")))
+ (unless mh-test-variant-logged-already
+ (mh-variant-set mh-variant)
+ (setq mh-test-utils-variants mh-variants)
+ (setq mh-test-variant-logged-already t))
+ (when (native-comp-available-p)
+ ;; As `call-process'' and `file-directory-p' will be redefined, the
+ ;; native compiler will invoke `call-process' to compile the
+ ;; respective trampolines. To avoid interference with the
+ ;; `call-process' mocking, we build these ahead of time.
+ (mapc #'comp-subr-trampoline-install '(call-process file-directory-p)))
+ (if mh-variant-in-use
+ (mh-test-utils-setup-with-variant)
+ (mh-test-utils-setup-with-mocks)))
+
+(defun mh-test-utils-setup-with-mocks ()
+ "Set dynamically bound variables so that MH programs are mocked out.
+The tests use this method if no configured MH variant is found."
+ (setq mh-user-path "/testdir/Mail/")
+ (mh-populate-sub-folders-cache "+")
+ (mh-populate-sub-folders-cache "+rela-folder")
+ (mh-populate-sub-folders-cache "+rela-folder/bar")
+ (mh-populate-sub-folders-cache "+rela-folder/foo")
+ (mh-populate-sub-folders-cache "+rela-folder/food")
+ (fset 'call-process #'mh-test-utils-mock-call-process)
+ (fset 'file-directory-p #'mh-test-utils-mock-file-directory-p)
+ ;; no temp directory created
+ nil)
+
+(defun mh-test-utils-mock-call-process (program
+ &optional _infile _destination _display
+ &rest args)
+ "A mocked version of `call-process' that calls no processes."
+ (let ((argument-responses
+ ;; assoc list of program arguments and lines to output.
+ '((("folder" "-fast") . ("rela-folder"))
+ (("folders" "-noheader" "-norecurse" "-nototal") .
+ ("rela-folder has no messages."))
+ (("folders" "-noheader" "-norecurse" "-nototal" "+rela-folder") .
+ ("rela-folder+ has no messages."
+ "rela-folder/bar has no messages."
+ "rela-folder/foo has no messages."
+ "rela-folder/food has no messages."))
+ (("folders" "-noheader" "-norecurse" "-nototal" "+rela-folder/foo") .
+ ("rela-folder/foo+ has no messages."))
+ (("folders" "-noheader" "-norecurse" "-nototal" "+") .
+ ("+ has no messages."))
+ (("folders" "-noheader" "-norecurse" "-nototal" "+/abso-folder") .
+ ("/abso-folder+ has no messages."
+ "/abso-folder/bar has no messages."
+ "/abso-folder/foo has no messages."
+ "/abso-folder/food has no messages."))
+ (("folders" "-noheader" "-norecurse" "-nototal" "+/") .
+ ("/+ has no messages ; (others)."
+ "/abso-folder has no messages ; (others)."
+ "/tmp has no messages ; (others)."))
+ ))
+ (arglist (cons (file-name-base program) args)))
+ (let ((response-list-cons (assoc arglist argument-responses)))
+ (cond (response-list-cons
+ (let ((response-list (cdr response-list-cons)))
+ (when mh-test-utils-debug-mocks
+ (message "call-process mock arglist %s" arglist)
+ (message " -> response %S" response-list))
+ (while response-list
+ (insert (car response-list) "\n")
+ (setq response-list (cdr response-list))))
+ 0)
+ (t
+ (message "call-process mock unexpected arglist %s" arglist)
+ 1)))))
+
+(defun mh-test-utils-mock-file-directory-p (filename)
+ "A mocked version of `file-directory-p' that does not access the file system."
+ (let ((directories '("" "/" "/tmp" "/abso-folder" "/abso-folder/foo"
+ "/testdir/Mail" "/testdir/Mail/rela-folder"
+ "/testdir/Mail/rela-folder/foo"
+ "rela-folder" "rela-folder/foo"))
+ (non-directories '("/abso-folder/fo" "rela-folder/fo"
+ "/testdir/Mail/rela-folder/fo"
+ "/testdir/Mail/nosuchfolder"
+ "/nosuchfolder" "nosuchfolder")))
+ (cond ((member (directory-file-name filename) directories)
+ (when mh-test-utils-debug-mocks
+ (message "file-directory-p mock: %S -> t" filename))
+ t)
+ ((member (directory-file-name filename) non-directories)
+ (when mh-test-utils-debug-mocks
+ (message "file-directory-p mock: %S -> nil" filename))
+ nil)
+ (t
+ (message "file-directory-p mock unexpected filename: %S" filename)
+ nil))))
+
+(defun mh-test-utils-setup-with-variant ()
+ "Create a temporary directory structure for actual MH programs to read.
+Return the name of the root of the created directory tree.
+Set dynamically bound variables so that MH programs may log.
+The tests use this method if a configured MH variant is found."
+ (let* ((temp-home-dir
+ (make-temp-file "emacs-mh-e-unit-test-" t))
+ (profile (expand-file-name
+ ".mh_profile" temp-home-dir))
+ (mail-dir (expand-file-name "Mail" temp-home-dir))
+ (rela-folder (expand-file-name
+ "rela-folder" mail-dir))
+ (abso-folder (expand-file-name
+ "abso-folder" temp-home-dir)))
+ (with-temp-file profile
+ (insert "Path: " mail-dir "\n" "Welcome: disable\n"))
+ (setenv "MH" profile)
+ (make-directory (expand-file-name "bar" rela-folder) t)
+ (make-directory (expand-file-name "foo" rela-folder) t)
+ (make-directory (expand-file-name "food" rela-folder) t)
+ (setq mh-user-path (file-name-as-directory mail-dir))
+ (make-directory (expand-file-name "bar" abso-folder) t)
+ (make-directory (expand-file-name "foo" abso-folder) t)
+ (make-directory (expand-file-name "food" abso-folder) t)
+ (setq mh-test-abs-folder abso-folder)
+ (fset 'call-process #'mh-test-utils-log-call-process)
+ (fset 'file-directory-p #'mh-test-utils-log-file-directory-p)
+ temp-home-dir))
+
+(defun mh-test-utils-log-call-process (program
+ &optional infile destination display
+ &rest args)
+ "A wrapper around `call-process' that can log the program args and output.
+Both args and output are written with `message' if `mh-test-utils-debug-mocks'
+is non-nil."
+ (let (process-output)
+ (when mh-test-utils-debug-mocks
+ (message "call-process arglist %s" (cons program args)))
+ (with-temp-buffer
+ (apply mh-test-call-process-real program infile destination display args)
+ (setq process-output (buffer-string)))
+ (when mh-test-utils-debug-mocks
+ (message " -> response:\n%s" process-output))
+ (insert process-output)))
+
+(defun mh-test-utils-log-file-directory-p (filename)
+ "A wrapper around `file-directory-p' that can log calls.
+Both FILENAME and the return value are written with `message'
+if `mh-test-utils-debug-mocks' is non-nil."
+ (let ((result (funcall mh-test-file-directory-p-real filename)))
+ (when mh-test-utils-debug-mocks
+ (message "file-directory-p: %S -> %s" filename result))
+ result))
+
+(defun mh-test-variant-handles-plus-slash (variant)
+ "Returns non-nil if this MH variant handles \"folders +/\".
+Mailutils 3.5, 3.7, and 3.13 are known not to."
+ (cond ((not (stringp variant))) ;our mock handles it
+ ((string-search "GNU Mailutils" variant)
+ (let ((mu-version (string-remove-prefix "GNU Mailutils " variant)))
+ (version<= "3.13.91" mu-version)))
+ (t))) ;no other known failures
+
+
+(ert-deftest mh-sub-folders-actual ()
+ "Test `mh-sub-folders-actual'."
+ ;; Note that mh-sub-folders-actual expects the folder to have
+ ;; already been normalized with
+ ;; (mh-normalize-folder-name folder nil nil t)
+ (with-mh-test-env
+ (should (member
+ mh-test-rel-folder
+ (mapcar (lambda (x) (car x)) (mh-sub-folders-actual nil))))
+ ;; Empty string and "+" not tested since mh-normalize-folder-name
+ ;; would change them to nil.
+ (should (member "foo"
+ (mapcar (lambda (x) (car x))
+ (mh-sub-folders-actual
+ (format "+%s" mh-test-rel-folder)))))
+ ;; Folder with trailing slash not tested since
+ ;; mh-normalize-folder-name would strip it.
+ (should (equal
+ nil
+ (mh-sub-folders-actual (format "+%s/foo" mh-test-rel-folder))))
+
+ (should (equal
+ (list (list "bar") (list "foo") (list "food"))
+ (mh-sub-folders-actual (format "+%s" mh-test-abs-folder))))
+
+ (when (mh-test-variant-handles-plus-slash mh-variant-in-use)
+ (should (member "tmp" (mapcar (lambda (x) (car x))
+ (mh-sub-folders-actual "+/")))))
+
+ ;; FIXME: mh-sub-folders-actual doesn't (yet) expect to be given a
+ ;; nonexistent folder.
+ ;; (should (equal nil
+ ;; (mh-sub-folders-actual "+nosuchfolder")))
+ ;; (should (equal nil
+ ;; (mh-sub-folders-actual "+/nosuchfolder")))
+ ))
+
+(ert-deftest mh-sub-folders ()
+ "Test `mh-sub-folders'."
+ (with-mh-test-env
+ (should (member mh-test-rel-folder
+ (mapcar (lambda (x) (car x)) (mh-sub-folders nil))))
+ (should (member mh-test-rel-folder
+ (mapcar (lambda (x) (car x)) (mh-sub-folders ""))))
+ (should-not (member mh-test-no-such-folder
+ (mapcar (lambda (x) (car x)) (mh-sub-folders "+"))))
+ (should (equal (list (list "bar") (list "foo") (list "food"))
+ (mh-sub-folders (format "+%s" mh-test-rel-folder))))
+ (should (equal (list (list "bar") (list "foo") (list "food"))
+ (mh-sub-folders (format "+%s/" mh-test-rel-folder))))
+ (should (equal nil
+ (mh-sub-folders (format "+%s/foo/" mh-test-rel-folder))))
+ (should (equal nil
+ (mh-sub-folders (format "+%s/foo" mh-test-rel-folder))))
+ (should (equal (list (list "bar") (list "foo") (list "food"))
+ (mh-sub-folders (format "+%s" mh-test-abs-folder))))
+ (when (mh-test-variant-handles-plus-slash mh-variant-in-use)
+ (should (member "tmp"
+ (mapcar (lambda (x) (car x)) (mh-sub-folders "+/")))))
+
+ ;; FIXME: mh-sub-folders doesn't (yet) expect to be given a
+ ;; nonexistent folder.
+ ;; (should (equal nil
+ ;; (mh-sub-folders "+nosuchfolder")))
+ ;; (should (equal nil
+ ;; (mh-sub-folders "+/nosuchfolder")))
+ ))
+
+
+(defmacro mh-test-folder-completion-1 (name
+ nil-expected t-expected lambda-expected)
+ "Helper for testing `mh-folder-completion-function'.
+Ask for completion on NAME three times, with three different
+values for the FLAG argument of `mh-folder-completion-function'.
+NIL-EXPECTED is the expected value with FLAG nil.
+T-EXPECTED is the expected value with FLAG t.
+LAMBDA-EXPECTED is the expected value with FLAG lambda."
+ (declare (debug t))
+ `(with-mh-test-env
+ (mh-test-folder-completion-2 ,nil-expected ;case "a"
+ (mh-folder-completion-function ,name nil nil))
+ (mh-test-folder-completion-2 ,t-expected ;case "b"
+ (mh-folder-completion-function ,name nil t))
+ (mh-test-folder-completion-2 ,lambda-expected ;case "c"
+ (mh-folder-completion-function ,name nil
+ 'lambda))))
+
+(defmacro mh-test-folder-completion-2 (expected actual)
+ "Inner helper for testing `mh-folder-completion-function'.
+ACTUAL should evaluate to either EXPECTED or to a list containing EXPECTED.
+ACTUAL may be evaluated twice, but this gives a clearer error on failure,
+and the `should' macro requires idempotent evaluation anyway."
+ (declare (debug t))
+ `(if (and (not (consp ,expected)) (consp ,actual))
+ (should (member ,expected ,actual))
+ (should (equal ,expected ,actual))))
+
+
+(ert-deftest mh-folder-completion-function-02-empty ()
+ "Test `mh-folder-completion-function' with empty name."
+ (mh-test-folder-completion-1 "" "+" (format "%s/" mh-test-rel-folder) nil))
+
+(ert-deftest mh-folder-completion-function-03-plus ()
+ "Test `mh-folder-completion-function' with `+'."
+ (mh-test-folder-completion-1 "+" "+" (format "%s/" mh-test-rel-folder) nil))
+
+(ert-deftest mh-folder-completion-function-04-rel-folder ()
+ "Test `mh-folder-completion-function' with `+rela-folder'."
+ (mh-test-folder-completion-1 (format "+%s" mh-test-rel-folder)
+ (format "+%s/" mh-test-rel-folder)
+ (list (format "%s/" mh-test-rel-folder))
+ t))
+
+(ert-deftest mh-folder-completion-function-05-rel-folder-slash ()
+ "Test `mh-folder-completion-function' with `+rela-folder/'."
+ (mh-test-folder-completion-1 (format "+%s/" mh-test-rel-folder)
+ (format "+%s/" mh-test-rel-folder)
+ (list "bar" "foo" "food")
+ t))
+
+(ert-deftest mh-folder-completion-function-06-rel-folder-slash-foo ()
+ "Test `mh-folder-completion-function' with `+rela-folder/foo'."
+ (mh-test-folder-completion-1 (format "+%s/foo" mh-test-rel-folder)
+ (format "+%s/foo" mh-test-rel-folder)
+ (list "foo" "food")
+ t)
+ (with-mh-test-env
+ (should (equal nil
+ (mh-folder-completion-function
+ (format "+%s/fo" mh-test-rel-folder) nil 'lambda)))))
+
+(ert-deftest mh-folder-completion-function-07-rel-folder-slash-foo-slash ()
+ "Test `mh-folder-completion-function' with `+rela-folder/foo/'."
+ (mh-test-folder-completion-1 (format "+%s/foo/" mh-test-rel-folder)
+ nil
+ nil
+ t))
+
+(ert-deftest mh-folder-completion-function-08-plus-slash ()
+ "Test `mh-folder-completion-function' with `+/'."
+ (with-mh-test-env
+ (skip-unless (mh-test-variant-handles-plus-slash mh-variant-in-use)))
+ (mh-test-folder-completion-1 "+/" "+/" "tmp/" t)
+ ;; case "bb"
+ (with-mh-test-env
+ (should (equal nil
+ (member (format "+%s/" mh-test-rel-folder)
+ (mh-folder-completion-function "+/" nil t))))))
+
+(ert-deftest mh-folder-completion-function-09-plus-slash-tmp ()
+ "Test `mh-folder-completion-function' with `+/tmp'."
+ (with-mh-test-env
+ (skip-unless (mh-test-variant-handles-plus-slash mh-variant-in-use)))
+ (mh-test-folder-completion-1 "+/tmp" "+/tmp/" "tmp/" t))
+
+(ert-deftest mh-folder-completion-function-10-plus-slash-abs-folder ()
+ "Test `mh-folder-completion-function' with `+/abso-folder'."
+ (mh-test-folder-completion-1 (format "+%s/" mh-test-abs-folder)
+ (format "+%s/" mh-test-abs-folder)
+ (list "bar" "foo" "food")
+ t))
+
+(ert-deftest mh-folder-completion-function-11-plus-slash-abs-folder-slash-foo ()
+ "Test `mh-folder-completion-function' with `+/abso-folder/foo'."
+ (mh-test-folder-completion-1 (format "+%s/foo" mh-test-abs-folder)
+ (format "+%s/foo" mh-test-abs-folder)
+ (list "foo" "food")
+ t)
+ (with-mh-test-env
+ (should (equal nil
+ (mh-folder-completion-function
+ (format "+%s/fo" mh-test-abs-folder) nil 'lambda)))))
+
+(ert-deftest mh-folder-completion-function-12-plus-nosuchfolder ()
+ "Test `mh-folder-completion-function' with `+nosuchfolder'."
+ (mh-test-folder-completion-1 "+nosuchfolder" nil nil nil))
+
+(ert-deftest mh-folder-completion-function-13-plus-slash-nosuchfolder ()
+ "Test `mh-folder-completion-function' with `+/nosuchfolder'."
+ (mh-test-folder-completion-1 "+/nosuchfolder" nil nil nil))
+
+;;; mh-utils-tests.el ends here
diff --git a/test/lisp/mh-e/mh-xface-tests.el b/test/lisp/mh-e/mh-xface-tests.el
new file mode 100644
index 00000000000..43355810abe
--- /dev/null
+++ b/test/lisp/mh-e/mh-xface-tests.el
@@ -0,0 +1,50 @@
+;;; mh-xface-tests.el --- tests for mh-xface.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021 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 'mh-xface)
+
+(ert-deftest mh-x-image-url-sane-p ()
+ "Test that `mh-x-image-url-sane-p' accepts a URL exactly if it is sane."
+ (should (equal (mh-x-image-url-sane-p (concat "http://"
+ (make-string 101 ?a)))
+ nil)) ;too long
+ (should (equal (mh-x-image-url-sane-p "http") nil)) ;too short
+ (should (equal (mh-x-image-url-sane-p "http:") t))
+ (should (equal (mh-x-image-url-sane-p "https") nil)) ;too short
+ (should (equal (mh-x-image-url-sane-p "https:") t))
+ (should (equal (mh-x-image-url-sane-p "https://www.example.com/me.png") t))
+ (should (equal (mh-x-image-url-sane-p "abcde:") nil)))
+
+(ert-deftest mh-x-image-url-cache-canonicalize ()
+ "Test `mh-x-image-url-cache-canonicalize'."
+ (should (equal (format "%s/%s" mh-x-image-cache-directory "%21foo%21bar.png")
+ (mh-x-image-url-cache-canonicalize "/foo/bar")))
+ (should (equal (format "%s/%s" mh-x-image-cache-directory
+ "http%3A%21%21domain.com%21foo%21bar.png")
+ (mh-x-image-url-cache-canonicalize
+ "http://domain.com/foo/bar")))
+ ;; All Windows invalid characters.
+ (should (equal (format "%s/%s" mh-x-image-cache-directory
+ "%21%3C%3E%3A%2A%3F%22%5C%7C%21bar.png")
+ (mh-x-image-url-cache-canonicalize "/<>:*?\"\\|/bar"))))
+
+;;; mh-xface-tests.el ends here
diff --git a/test/lisp/mh-e/test-all-mh-variants.sh b/test/lisp/mh-e/test-all-mh-variants.sh
new file mode 100755
index 00000000000..eaee98fcf4d
--- /dev/null
+++ b/test/lisp/mh-e/test-all-mh-variants.sh
@@ -0,0 +1,102 @@
+#! /bin/bash
+# Run the mh-utils-tests against all MH variants found on this system.
+
+# Copyright (C) 2021 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:
+
+# By default runs all tests; test names or Emacs-style regexps may be
+# given on the command line to run just those tests.
+#
+# Option -d turns on Emacs variable mh-test-utils-debug-mocks, which
+# causes the tests to output all interactions with the file system.
+
+# If you want to run the tests for only one MH variant, you don't need
+# to use this script, because "make" can do it. See the commentary at
+# the top of ./mh-utils-tests.el for the recipe.
+
+debug=
+if [[ "$1" = -* ]]; then
+ if [[ "$1" != -d ]]; then
+ echo "Usage: $(basename "$0") [-d] [test ...]" >&2
+ exit 2
+ fi
+ debug=t
+ shift
+fi
+
+shopt -s extglob
+ert_test_list=()
+for tst; do
+ # Guess the type the test spec
+ case $tst in
+ *[\[\].*+\\]*) # Regexp: put in string quotes
+ ert_test_list+=("\"$tst\"")
+ ;;
+ *) # Lisp expression, keyword, or symbol: use as is
+ ert_test_list+=("$tst")
+ ;;
+ esac
+done
+if [[ ${#ert_test_list[@]} -eq 0 ]]; then
+ # t means true for all tests, runs everything
+ ert_test_list=(t)
+fi
+
+# This script is 3 directories down in the Emacs source tree.
+cd "$(dirname "$0")"
+cd ../../..
+emacs=(src/emacs --batch -Q)
+
+# MH-E has a good list of directories where an MH variant might be installed,
+# so we look in each of those.
+read -r -a mh_sys_path \
+ < <("${emacs[@]}" -l mh-e --eval "(princ mh-sys-path)" | sed 's/[()]//g')
+
+have_done_mocked_variant=false
+declare -i tests_total=0 tests_passed=0
+
+for path in "${mh_sys_path[@]}"; do
+ if [[ ! -x "$path/mhparam" ]]; then
+ if [[ "$have_done_mocked_variant" = false ]]; then
+ have_done_mocked_variant=true
+ else
+ continue
+ fi
+ fi
+ echo "** Testing with PATH $path"
+ ((++tests_total))
+ TEST_MH_PATH=$path TEST_MH_DEBUG=$debug \
+ HOME=/nonexistent \
+ "${emacs[@]}" -l ert \
+ --eval "(setq load-prefer-newer t)" \
+ --eval "(load \"$PWD/test/lisp/mh-e/mh-utils-tests\" nil t)" \
+ --eval "(ert-run-tests-batch-and-exit '(or ${ert_test_list[*]}))" \
+ && ((++tests_passed))
+done
+
+if (( tests_total == 0 )); then
+ echo "NO tests run"
+ exit 1
+elif (( tests_total == tests_passed )); then
+ echo "All tested variants pass: $tests_passed/$tests_total"
+else
+ echo "Tested variants passing: $tests_passed/$tests_total," \
+ "FAILING: $((tests_total - tests_passed))/$tests_total"
+ exit 1
+fi
diff --git a/test/lisp/net/browse-url-tests.el b/test/lisp/net/browse-url-tests.el
index 898bef8513b..68c7c349013 100644
--- a/test/lisp/net/browse-url-tests.el
+++ b/test/lisp/net/browse-url-tests.el
@@ -28,6 +28,7 @@
(require 'browse-url)
(require 'ert)
+(require 'ert-x)
(ert-deftest browse-url-tests-browser-kind ()
(should (eq (browse-url--browser-kind #'browse-url-w3 "gnu.org")
@@ -68,11 +69,11 @@
(ert-deftest browse-url-tests-encode-url ()
(should (equal (browse-url-encode-url "") ""))
- (should (equal (browse-url-encode-url "a b c") "a b c"))
+ (should (equal (browse-url-encode-url "a b c") "a%20b%20c"))
(should (equal (browse-url-encode-url "\"a\" \"b\"")
- "\"a%22\"b\""))
- (should (equal (browse-url-encode-url "(a) (b)") "(a%29(b)"))
- (should (equal (browse-url-encode-url "a$ b$") "a%24b$")))
+ "%22a%22%20%22b%22"))
+ (should (equal (browse-url-encode-url "(a) (b)") "%28a%29%20%28b%29"))
+ (should (equal (browse-url-encode-url "a$ b$") "a%24%20b%24")))
(ert-deftest browse-url-tests-url-at-point ()
(with-temp-buffer
@@ -87,11 +88,10 @@
"ftp://foo/")))
(ert-deftest browse-url-tests-delete-temp-file ()
- (let ((browse-url-temp-file-name
- (make-temp-file "browse-url-tests-")))
+ (ert-with-temp-file browse-url-temp-file-name
(browse-url-delete-temp-file)
(should-not (file-exists-p browse-url-temp-file-name)))
- (let ((file (make-temp-file "browse-url-tests-")))
+ (ert-with-temp-file file
(browse-url-delete-temp-file file)
(should-not (file-exists-p file))))
diff --git a/test/lisp/net/dbus-tests.el b/test/lisp/net/dbus-tests.el
index 53c786ada48..cfc380d3029 100644
--- a/test/lisp/net/dbus-tests.el
+++ b/test/lisp/net/dbus-tests.el
@@ -630,16 +630,19 @@ This includes initialization and closing the bus."
:session dbus--test-service dbus--test-path
dbus--test-interface method1 "foo" "bar"))
`(dbus-error ,dbus-error-invalid-args "Wrong arguments (foo bar)")))
- ;; Three arguments, D-Bus error activated by `dbus-error' signal.
+ ;; Three arguments, D-Bus error activated by `dbus-error'
+ ;; signal. On CentOS, it is not guaranteed which format the
+ ;; error message arises. (Bug#51369)
(should
- (equal
+ (member
(should-error
(dbus-call-method
:session dbus--test-service dbus--test-path
dbus--test-interface method1 "foo" "bar" "baz"))
- `(dbus-error
- ,dbus-error-failed
- "D-Bus error: \"D-Bus signal\", \"foo\", \"bar\", \"baz\"")))
+ `((dbus-error "D-Bus signal" "foo" "bar" "baz")
+ (dbus-error
+ ,dbus-error-failed
+ "D-Bus error: \"D-Bus signal\", \"foo\", \"bar\", \"baz\""))))
;; Unregister method.
(should (dbus-unregister-object registered))
diff --git a/test/lisp/net/netrc-tests.el b/test/lisp/net/netrc-tests.el
index f75328a59f7..2f68b9bbb24 100644
--- a/test/lisp/net/netrc-tests.el
+++ b/test/lisp/net/netrc-tests.el
@@ -48,7 +48,7 @@
(should (equal (netrc-credentials "ftp.example.org")
'("jrh" "*baz*")))))
-(ert-deftest test-netrc-credentials ()
+(ert-deftest test-netrc-credentials-2 ()
(let ((netrc-file (ert-resource-file "netrc-folding")))
(should
(equal (netrc-parse netrc-file)
diff --git a/test/lisp/net/network-stream-tests.el b/test/lisp/net/network-stream-tests.el
index 4a0b23dd26f..8f5bddb71fa 100644
--- a/test/lisp/net/network-stream-tests.el
+++ b/test/lisp/net/network-stream-tests.el
@@ -611,7 +611,7 @@
(skip-unless (gnutls-available-p))
(let ((server (make-tls-server 44667))
(times 0)
- nowait
+ (nowait nil) ; Workaround Bug#47080
proc status)
(unwind-protect
(progn
diff --git a/test/lisp/net/puny-tests.el b/test/lisp/net/puny-tests.el
index 28c0d49cbee..9119084209e 100644
--- a/test/lisp/net/puny-tests.el
+++ b/test/lisp/net/puny-tests.el
@@ -61,4 +61,11 @@
;; Only allowed in unrestricted.
(should-not (puny-highly-restrictive-domain-p "I♥NY.org")))
+(ert-deftest puny-normalize ()
+ (should (equal (puny-encode-string (string-glyph-compose "Bä.com"))
+ "xn--b.com-gra"))
+ (should (equal (puny-encode-string "Bä.com")
+ "xn--b.com-gra"))
+ (should (equal (puny-encode-string "Bä.com") "xn--b.com-gra")))
+
;;; puny-tests.el ends here
diff --git a/test/lisp/net/shr-tests.el b/test/lisp/net/shr-tests.el
index ed532af657a..bfb83f25184 100644
--- a/test/lisp/net/shr-tests.el
+++ b/test/lisp/net/shr-tests.el
@@ -67,4 +67,4 @@
(require 'shr)
-;;; shr-stream-tests.el ends here
+;;; shr-tests.el ends here
diff --git a/test/lisp/net/socks-tests.el b/test/lisp/net/socks-tests.el
index 71bdd74890a..7fb885235c0 100644
--- a/test/lisp/net/socks-tests.el
+++ b/test/lisp/net/socks-tests.el
@@ -95,7 +95,7 @@
;; From fedora.org: 2605:bc80:3010:600:dead:beef:cafe:fed9
;; 5004 ~~> Version Status (OK) NOOP Addr-Type (4 -> IPv6)
(socks-filter proc "\5\0\0\4\x26\x05\xbc\x80\x30\x10\x00\x60")
- (ert-info ("State still waiting and response emtpy")
+ (ert-info ("State still waiting and response empty")
(should (eq (process-get proc 'socks-state) socks-state-waiting))
(should-not (process-get proc 'socks-response)))
(ert-info ("Scratch field holds partial payload of pending msg")
@@ -128,7 +128,7 @@
(defvar socks-tests-canned-server-patterns nil
"Alist containing request/response cons pairs to be tried in order.
-Vectors must match verbatim. Strings are considered regex patterns.")
+Vectors must match verbatim. Strings are considered regex patterns.")
(defun socks-tests-canned-server-create ()
"Create and return a fake SOCKS server."
@@ -203,7 +203,7 @@ Vectors must match verbatim. Strings are considered regex patterns.")
(should (equal host "example.com"))
(list 93 184 216 34)))
((symbol-function 'user-full-name)
- (lambda () "foo")))
+ (lambda (&optional _) "foo")))
(socks-tests-perform-hello-world-http-request)))))
;; Replace first pattern below with ([5 3 0 1 2] . [5 2]) to validate
diff --git a/test/lisp/net/tramp-archive-tests.el b/test/lisp/net/tramp-archive-tests.el
index aac1b13bd0e..a307a40157f 100644
--- a/test/lisp/net/tramp-archive-tests.el
+++ b/test/lisp/net/tramp-archive-tests.el
@@ -122,12 +122,6 @@ the origin of the temporary TMPFILE, have no write permissions."
(directory-files tmpfile 'full directory-files-no-dot-files-regexp))
(delete-directory tmpfile)))
-(defun tramp-archive--test-emacs26-p ()
- "Check for Emacs version >= 26.1.
-Some semantics has been changed for there, w/o new functions or
-variables, so we check the Emacs version directly."
- (>= emacs-major-version 26))
-
(defun tramp-archive--test-emacs27-p ()
"Check for Emacs version >= 27.1.
Some semantics has been changed for there, w/o new functions or
@@ -265,21 +259,20 @@ variables, so we check the Emacs version directly."
(concat
(tramp-gvfs-url-file-name
(tramp-make-tramp-file-name
- tramp-archive-method
- ;; User and Domain.
- nil nil
- ;; Host.
- (url-hexify-string
- (concat
- "file://"
- ;; `directory-file-name' does not leave file
- ;; archive boundaries. So we must cut the
- ;; trailing slash ourselves.
- (substring
- (file-name-directory
- (tramp-archive-test-file-archive-hexlified))
- 0 -1)))
- nil "/"))
+ (make-tramp-file-name
+ :method tramp-archive-method
+ :host
+ (url-hexify-string
+ (concat
+ "file://"
+ ;; `directory-file-name' does not leave file
+ ;; archive boundaries. So we must cut the
+ ;; trailing slash ourselves.
+ (substring
+ (file-name-directory
+ (tramp-archive-test-file-archive-hexlified))
+ 0 -1)))
+ :localname "/")))
(file-name-nondirectory tramp-archive-test-file-archive)))))
(should-not port)
(should (string-equal localname "/bar"))
@@ -434,7 +427,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(setq tmp-name
(file-local-copy
(expand-file-name "what" tramp-archive-test-archive)))
- :type tramp-file-missing))
+ :type 'file-missing))
;; Cleanup.
(ignore-errors (tramp-archive--test-delete tmp-name))
@@ -462,7 +455,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(should-error
(insert-file-contents
(expand-file-name "what" tramp-archive-test-archive))
- :type tramp-file-missing))
+ :type 'file-missing))
;; Cleanup.
(tramp-archive-cleanup-hash))))
@@ -553,11 +546,9 @@ This checks also `file-name-as-directory', `file-name-directory',
(should (file-directory-p tmp-name2))
(should (file-exists-p tmp-name4))
;; Target directory does exist already.
- ;; This has been changed in Emacs 26.1.
- (when (tramp-archive--test-emacs26-p)
- (should-error
- (copy-directory tmp-name1 tmp-name2)
- :type 'file-error))
+ (should-error
+ (copy-directory tmp-name1 tmp-name2)
+ :type 'file-error)
(tramp-archive--test-delete tmp-name4)
(copy-directory tmp-name1 (file-name-as-directory tmp-name2))
(should (file-directory-p tmp-name3))
@@ -622,13 +613,11 @@ This checks also `file-name-as-directory', `file-name-directory',
(append '("LANG=C" "LANGUAGE=C" "LC_ALL=C") process-environment)))
(unwind-protect
(progn
- ;; Due to Bug#29423, this works only since for Emacs 26.1.
- (when nil ;; TODO (tramp-archive--test-emacs26-p)
- (with-temp-buffer
- (insert-directory tramp-archive-test-archive nil)
- (goto-char (point-min))
- (should
- (looking-at-p (regexp-quote tramp-archive-test-archive)))))
+ (with-temp-buffer
+ (insert-directory tramp-archive-test-archive nil)
+ (goto-char (point-min))
+ (should
+ (looking-at-p (regexp-quote tramp-archive-test-archive))))
(with-temp-buffer
(insert-directory tramp-archive-test-archive "-al")
(goto-char (point-min))
@@ -656,7 +645,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(should-error
(insert-directory
(expand-file-name "baz" tramp-archive-test-archive) nil)
- :type tramp-file-missing)))
+ :type 'file-missing)))
;; Cleanup.
(tramp-archive-cleanup-hash))))
@@ -716,7 +705,7 @@ This tests also `access-file', `file-readable-p' and `file-regular-p'."
;; Check error case.
(should-error
(access-file tmp-name4 "error")
- :type tramp-file-missing))
+ :type 'file-missing))
;; Cleanup.
(tramp-archive-cleanup-hash))))
@@ -855,38 +844,27 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
;; Cleanup.
(tramp-archive-cleanup-hash))))
-;; The functions were introduced in Emacs 26.1.
(ert-deftest tramp-archive-test40-make-nearby-temp-file ()
"Check `make-nearby-temp-file' and `temporary-file-directory'."
(skip-unless tramp-archive-enabled)
- ;; Since Emacs 26.1.
- (skip-unless
- (and (fboundp 'make-nearby-temp-file) (fboundp 'temporary-file-directory)))
- ;; `make-nearby-temp-file' and `temporary-file-directory' exists
- ;; since Emacs 26.1. We don't want to see compiler warnings for
- ;; older Emacsen.
(let ((default-directory tramp-archive-test-archive)
tmp-file)
;; The file archive shall know a temporary file directory. It is
;; not in the archive itself.
- (should
- (stringp (with-no-warnings (with-no-warnings (temporary-file-directory)))))
- (should-not
- (tramp-archive-file-name-p (with-no-warnings (temporary-file-directory))))
+ (should (stringp (temporary-file-directory)))
+ (should-not (tramp-archive-file-name-p (temporary-file-directory)))
;; A temporary file or directory shall not be located in the
;; archive itself.
- (setq tmp-file
- (with-no-warnings (make-nearby-temp-file "tramp-archive-test")))
+ (setq tmp-file (make-nearby-temp-file "tramp-archive-test"))
(should (file-exists-p tmp-file))
(should (file-regular-p tmp-file))
(should-not (tramp-archive-file-name-p tmp-file))
(delete-file tmp-file)
(should-not (file-exists-p tmp-file))
- (setq tmp-file
- (with-no-warnings (make-nearby-temp-file "tramp-archive-test" 'dir)))
+ (setq tmp-file (make-nearby-temp-file "tramp-archive-test" 'dir))
(should (file-exists-p tmp-file))
(should (file-directory-p tmp-file))
(should-not (tramp-archive-file-name-p tmp-file))
@@ -910,7 +888,7 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
(zerop (nth 1 fsi))
(zerop (nth 2 fsi))))))
-(ert-deftest tramp-archive-test45-auto-load ()
+(ert-deftest tramp-archive-test46-auto-load ()
"Check that `tramp-archive' autoloads properly."
:tags '(:expensive-test)
(skip-unless tramp-archive-enabled)
@@ -923,9 +901,10 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
"(progn \
(message \"tramp-archive loaded: %%s\" \
(featurep 'tramp-archive)) \
- (file-attributes %S \"/\") \
+ (let ((inhibit-message t)) \
+ (file-attributes %S \"/\")) \
(message \"tramp-archive loaded: %%s\" \
- (featurep 'tramp-archive)))"))
+ (featurep 'tramp-archive))))"))
(dolist (default-directory
`(,temporary-file-directory
;; Starting Emacs in a directory which has
@@ -949,7 +928,7 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
(mapconcat #'shell-quote-argument load-path " -L ")
(shell-quote-argument (format code file))))))))))
-(ert-deftest tramp-archive-test45-delay-load ()
+(ert-deftest tramp-archive-test46-delay-load ()
"Check that `tramp-archive' is loaded lazily, only when needed."
:tags '(:expensive-test)
(skip-unless tramp-archive-enabled)
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 3008861f22b..9c65f9a6351 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -43,8 +43,10 @@
(require 'cl-lib)
(require 'dired)
+(require 'dired-aux)
(require 'ert)
(require 'ert-x)
+(require 'seq) ; For `seq-random-elt', autoloaded since Emacs 28.1
(require 'trace)
(require 'tramp)
(require 'vc)
@@ -52,9 +54,9 @@
(require 'vc-git)
(require 'vc-hg)
+(declare-function tramp-check-remote-uname "tramp-sh")
(declare-function tramp-find-executable "tramp-sh")
(declare-function tramp-get-remote-chmod-h "tramp-sh")
-(declare-function tramp-get-remote-gid "tramp-sh")
(declare-function tramp-get-remote-path "tramp-sh")
(declare-function tramp-get-remote-perl "tramp-sh")
(declare-function tramp-get-remote-stat "tramp-sh")
@@ -68,16 +70,12 @@
(defvar tramp-connection-properties)
(defvar tramp-copy-size-limit)
(defvar tramp-display-escape-sequence-regexp)
+(defvar tramp-fuse-unmount-on-cleanup)
(defvar tramp-inline-compress-start-size)
(defvar tramp-persistency-file-name)
(defvar tramp-remote-path)
(defvar tramp-remote-process-environment)
-;; Needed for Emacs 25.
-(defvar connection-local-criteria-alist)
-(defvar connection-local-profile-alist)
-;; Needed for Emacs 26.
-(defvar async-shell-command-width)
;; Needed for Emacs 27.
(defvar process-file-return-signal-string)
(defvar shell-command-dont-erase-buffer)
@@ -177,6 +175,19 @@ The temporary file is not created."
(make-temp-name "tramp-test")
(if local temporary-file-directory tramp-test-temporary-file-directory))))
+;; Method "smb" supports `make-symbolic-link' only if the remote host
+;; has CIFS capabilities. tramp-adb.el, tramp-gvfs.el, tramp-rclone.el
+;; and tramp-sshfs.el do not support symbolic links at all.
+(defmacro tramp--test-ignore-make-symbolic-link-error (&rest body)
+ "Run BODY, ignoring \"make-symbolic-link not supported\" file error."
+ (declare (indent defun) (debug (body)))
+ `(condition-case err
+ (progn ,@body)
+ (file-error
+ (unless (string-equal (error-message-string err)
+ "make-symbolic-link not supported")
+ (signal (car err) (cdr err))))))
+
;; Don't print messages in nested `tramp--test-instrument-test-case' calls.
(defvar tramp--test-instrument-test-case-p nil
"Whether `tramp--test-instrument-test-case' run.
@@ -208,8 +219,7 @@ is greater than 10.
(when (and (null tramp--test-instrument-test-case-p) (> tramp-verbose 3))
(untrace-all)
(dolist (buf (tramp-list-tramp-buffers))
- (with-current-buffer buf
- (message ";; %s\n%s" buf (buffer-string)))
+ (message ";; %s\n%s" buf (tramp-get-buffer-string buf))
(kill-buffer buf))))))
(defsubst tramp--test-message (fmt-string &rest arguments)
@@ -229,8 +239,7 @@ is greater than 10.
(unwind-protect
(progn ,@body)
(tramp--test-message
- "%s %f sec"
- ,message (float-time (time-subtract (current-time) start))))))
+ "%s %f sec" ,message (float-time (time-subtract nil start))))))
;; `always' is introduced with Emacs 28.1.
(defalias 'tramp--test-always
@@ -2069,44 +2078,41 @@ Also see `ignore'."
(substitute-in-file-name "/method:host:/:/path//foo")
"/method:host:/:/path//foo"))
- ;; Forwhatever reasons, the following tests let Emacs crash for
- ;; Emacs 25, occasionally. No idea what's up.
- (when (tramp--test-emacs26-p)
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host://~" foo))
- (concat "/~" foo)))
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host:/~" foo))
- (concat "/method:host:/~" foo)))
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host:/path//~" foo))
- (concat "/~" foo)))
- ;; (substitute-in-file-name "/path/~foo") expands only for a local
- ;; user "foo" to "/~foo"". Otherwise, it doesn't expand.
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host:/path/~" foo))
- (concat "/method:host:/path/~" foo)))
- ;; Quoting local part.
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host:/://~" foo))
- (concat "/method:host:/://~" foo)))
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host:/:/~" foo))
- (concat "/method:host:/:/~" foo)))
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host:/:/path//~" foo))
- (concat "/method:host:/:/path//~" foo)))
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host:/:/path/~" foo))
- (concat "/method:host:/:/path/~" foo))))
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host://~" foo))
+ (concat "/~" foo)))
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host:/~" foo))
+ (concat "/method:host:/~" foo)))
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host:/path//~" foo))
+ (concat "/~" foo)))
+ ;; (substitute-in-file-name "/path/~foo") expands only for a local
+ ;; user "foo" to "/~foo"". Otherwise, it doesn't expand.
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host:/path/~" foo))
+ (concat "/method:host:/path/~" foo)))
+ ;; Quoting local part.
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host:/://~" foo))
+ (concat "/method:host:/://~" foo)))
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host:/:/~" foo))
+ (concat "/method:host:/:/~" foo)))
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host:/:/path//~" foo))
+ (concat "/method:host:/:/path//~" foo)))
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host:/:/path/~" foo))
+ (concat "/method:host:/:/path/~" foo)))
(let (process-environment)
(should
@@ -2280,6 +2286,46 @@ This checks also `file-name-as-directory', `file-name-directory',
(should (string-equal (file-name-directory file) file))
(should (string-equal (file-name-nondirectory file) "")))))))
+(ert-deftest tramp-test07-abbreviate-file-name ()
+ "Check that Tramp abbreviates file names correctly."
+ (skip-unless (tramp--test-enabled))
+ (skip-unless (tramp--test-emacs29-p))
+ (skip-unless (not (tramp--test-ange-ftp-p)))
+
+ (let* ((remote-host (file-remote-p tramp-test-temporary-file-directory))
+ ;; Not all methods can expand "~".
+ (home-dir (ignore-errors (expand-file-name (concat remote-host "~")))))
+ (skip-unless home-dir)
+
+ ;; Check home-dir abbreviation.
+ (unless (string-suffix-p "~" home-dir)
+ (should (equal (abbreviate-file-name (concat home-dir "/foo/bar"))
+ (concat remote-host "~/foo/bar")))
+ (should (equal (abbreviate-file-name
+ (concat remote-host "/nowhere/special"))
+ (concat remote-host "/nowhere/special"))))
+
+ ;; Check `directory-abbrev-alist' abbreviation.
+ (let ((directory-abbrev-alist
+ `((,(concat "\\`" (regexp-quote home-dir) "/foo")
+ . ,(concat home-dir "/f"))
+ (,(concat "\\`" (regexp-quote remote-host) "/nowhere")
+ . ,(concat remote-host "/nw")))))
+ (should (equal (abbreviate-file-name (concat home-dir "/foo/bar"))
+ (concat remote-host "~/f/bar")))
+ (should (equal (abbreviate-file-name
+ (concat remote-host "/nowhere/special"))
+ (concat remote-host "/nw/special"))))
+
+ ;; Check that home-dir abbreviation doesn't occur when home-dir is just "/".
+ (setq home-dir (concat remote-host "/"))
+ ;; The remote home directory is kept in the connection property
+ ;; "home-directory". We fake this setting.
+ (tramp-set-connection-property tramp-test-vec "home-directory" home-dir)
+ (should (equal (concat home-dir "foo/bar")
+ (abbreviate-file-name (concat home-dir "foo/bar"))))
+ (tramp-flush-connection-property tramp-test-vec "home-directory")))
+
(ert-deftest tramp-test07-file-exists-p ()
"Check `file-exist-p', `write-region' and `delete-file'."
(skip-unless (tramp--test-enabled))
@@ -2338,7 +2384,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(delete-file tmp-name2)
(should-error
(setq tmp-name2 (file-local-copy tmp-name1))
- :type tramp-file-missing))
+ :type 'file-missing))
;; Cleanup.
(ignore-errors
@@ -2377,7 +2423,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(delete-file tmp-name)
(should-error
(insert-file-contents tmp-name)
- :type tramp-file-missing))
+ :type 'file-missing))
;; Cleanup.
(ignore-errors (delete-file tmp-name))))))
@@ -2448,23 +2494,20 @@ This checks also `file-name-as-directory', `file-name-directory',
(should (string-equal (buffer-string) "34")))
;; Check message.
- ;; Macro `ert-with-message-capture' was introduced in Emacs 26.1.
- (with-no-warnings (when (symbol-plist 'ert-with-message-capture)
- (let (inhibit-message)
- (dolist
- (noninteractive (unless (tramp--test-ange-ftp-p) '(nil t)))
- (dolist (visit '(nil t "string" no-message))
- (ert-with-message-capture tramp--test-messages
- (write-region "foo" nil tmp-name nil visit)
- ;; We must check the last line. There could be
- ;; other messages from the progress reporter.
- (should
- (string-match-p
- (if (and (null noninteractive)
- (or (eq visit t) (null visit) (stringp visit)))
- (format "^Wrote %s\n\\'" (regexp-quote tmp-name))
- "^\\'")
- tramp--test-messages))))))))
+ (let (inhibit-message)
+ (dolist (noninteractive (unless (tramp--test-ange-ftp-p) '(nil t)))
+ (dolist (visit '(nil t "string" no-message))
+ (ert-with-message-capture tramp--test-messages
+ (write-region "foo" nil tmp-name nil visit)
+ ;; We must check the last line. There could be
+ ;; other messages from the progress reporter.
+ (should
+ (string-match-p
+ (if (and (null noninteractive)
+ (or (eq visit t) (null visit) (stringp visit)))
+ (format "^Wrote %s\n\\'" (regexp-quote tmp-name))
+ "^\\'")
+ tramp--test-messages))))))
;; We do not test lockname here. See
;; `tramp-test39-make-lock-file-name'.
@@ -2474,17 +2517,15 @@ This checks also `file-name-as-directory', `file-name-directory',
;; Ange-FTP.
((symbol-function 'yes-or-no-p) #'tramp--test-always))
(write-region "foo" nil tmp-name nil nil nil 'mustbenew))
- ;; `mustbenew' is passed to Tramp since Emacs 26.1.
- (when (tramp--test-emacs26-p)
- (should-error
- (cl-letf (((symbol-function #'y-or-n-p) #'ignore)
- ;; Ange-FTP.
- ((symbol-function #'yes-or-no-p) #'ignore))
- (write-region "foo" nil tmp-name nil nil nil 'mustbenew))
- :type 'file-already-exists)
- (should-error
- (write-region "foo" nil tmp-name nil nil nil 'excl)
- :type 'file-already-exists)))
+ (should-error
+ (cl-letf (((symbol-function #'y-or-n-p) #'ignore)
+ ;; Ange-FTP.
+ ((symbol-function #'yes-or-no-p) #'ignore))
+ (write-region "foo" nil tmp-name nil nil nil 'mustbenew))
+ :type 'file-already-exists)
+ (should-error
+ (write-region "foo" nil tmp-name nil nil nil 'excl)
+ :type 'file-already-exists))
;; Cleanup.
(ignore-errors (delete-file tmp-name))))))
@@ -2547,7 +2588,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(progn
(should-error
(copy-file source target)
- :type tramp-file-missing)
+ :type 'file-missing)
(write-region "foo" nil source)
(should (file-exists-p source))
(copy-file source target)
@@ -2573,8 +2614,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(should (file-exists-p source))
(make-directory target)
(should (file-directory-p target))
- ;; This has been changed in Emacs 26.1.
- (when (and (tramp--test-expensive-test) (tramp--test-emacs26-p))
+ (when (tramp--test-expensive-test)
(should-error
(copy-file source target)
:type 'file-already-exists)
@@ -2659,7 +2699,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(progn
(should-error
(rename-file source target)
- :type tramp-file-missing)
+ :type 'file-missing)
(write-region "foo" nil source)
(should (file-exists-p source))
(rename-file source target)
@@ -2688,8 +2728,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(should (file-exists-p source))
(make-directory target)
(should (file-directory-p target))
- ;; This has been changed in Emacs 26.1.
- (when (and (tramp--test-expensive-test) (tramp--test-emacs26-p))
+ (when (tramp--test-expensive-test)
(should-error
(rename-file source target)
:type 'file-already-exists)
@@ -2759,21 +2798,31 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
(let* ((tmp-name1 (tramp--test-make-temp-name nil quoted))
- (tmp-name2 (expand-file-name "foo/bar" tmp-name1)))
+ (tmp-name2 (expand-file-name "foo/bar" tmp-name1))
+ (unusual-file-mode-1 #o740)
+ (unusual-file-mode-2 #o710))
(unwind-protect
(progn
- (make-directory tmp-name1)
+ (with-file-modes unusual-file-mode-1
+ (make-directory tmp-name1))
(should-error
(make-directory tmp-name1)
:type 'file-already-exists)
(should (file-directory-p tmp-name1))
(should (file-accessible-directory-p tmp-name1))
+ (when (tramp--test-supports-set-file-modes-p)
+ (should (equal (format "%#o" unusual-file-mode-1)
+ (format "%#o" (file-modes tmp-name1)))))
(should-error
(make-directory tmp-name2)
:type 'file-error)
- (make-directory tmp-name2 'parents)
+ (with-file-modes unusual-file-mode-2
+ (make-directory tmp-name2 'parents))
(should (file-directory-p tmp-name2))
(should (file-accessible-directory-p tmp-name2))
+ (when (tramp--test-supports-set-file-modes-p)
+ (should (equal (format "%#o" unusual-file-mode-2)
+ (format "%#o" (file-modes tmp-name2)))))
;; If PARENTS is non-nil, `make-directory' shall not
;; signal an error when DIR exists already.
(make-directory tmp-name2 'parents))
@@ -2857,7 +2906,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(ert-deftest tramp-test15-copy-directory ()
"Check `copy-directory'."
(skip-unless (tramp--test-enabled))
- (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
+ (skip-unless (not (tramp--test-rclone-p)))
(dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
(let* ((tmp-name1 (tramp--test-make-temp-name nil quoted))
@@ -2866,14 +2915,15 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(file-name-nondirectory tmp-name1) tmp-name2))
(tmp-name4 (expand-file-name "foo" tmp-name1))
(tmp-name5 (expand-file-name "foo" tmp-name2))
- (tmp-name6 (expand-file-name "foo" tmp-name3)))
+ (tmp-name6 (expand-file-name "foo" tmp-name3))
+ (tmp-name7 (tramp--test-make-temp-name nil quoted)))
;; Copy complete directory.
(unwind-protect
(progn
(should-error
(copy-directory tmp-name1 tmp-name2)
- :type tramp-file-missing)
+ :type 'file-missing)
;; Copy empty directory.
(make-directory tmp-name1)
(write-region "foo" nil tmp-name4)
@@ -2883,11 +2933,9 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(should (file-directory-p tmp-name2))
(should (file-exists-p tmp-name5))
;; Target directory does exist already.
- ;; This has been changed in Emacs 26.1.
- (when (tramp--test-emacs26-p)
- (should-error
- (copy-directory tmp-name1 tmp-name2)
- :type 'file-already-exists))
+ (should-error
+ (copy-directory tmp-name1 tmp-name2)
+ :type 'file-already-exists)
(copy-directory tmp-name1 (file-name-as-directory tmp-name2))
(should (file-directory-p tmp-name3))
(should (file-exists-p tmp-name6)))
@@ -2922,7 +2970,48 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
;; Cleanup.
(ignore-errors
(delete-directory tmp-name1 'recursive)
- (delete-directory tmp-name2 'recursive))))))
+ (delete-directory tmp-name2 'recursive)))
+
+ ;; Copy symlink to directory. Implemented since Emacs 28.1.
+ (when (boundp 'copy-directory-create-symlink)
+ (dolist (copy-directory-create-symlink '(nil t))
+ (unwind-protect
+ (tramp--test-ignore-make-symbolic-link-error
+ ;; Copy to file name.
+ (make-directory tmp-name1)
+ (write-region "foo" nil tmp-name4)
+ (make-symbolic-link tmp-name1 tmp-name7)
+ (should (file-directory-p tmp-name1))
+ (should (file-exists-p tmp-name4))
+ (should (file-symlink-p tmp-name7))
+ (copy-directory tmp-name7 tmp-name2)
+ (if copy-directory-create-symlink
+ (should
+ (string-equal
+ (file-symlink-p tmp-name2) (file-symlink-p tmp-name7)))
+ (should (file-directory-p tmp-name2)))
+ ;; Copy to directory name.
+ (delete-directory tmp-name2 'recursive)
+ (make-directory tmp-name2)
+ (should (file-directory-p tmp-name2))
+ (copy-directory tmp-name7 (file-name-as-directory tmp-name2))
+ (if copy-directory-create-symlink
+ (should
+ (string-equal
+ (file-symlink-p
+ (expand-file-name
+ (file-name-nondirectory tmp-name7) tmp-name2))
+ (file-symlink-p tmp-name7)))
+ (should
+ (file-directory-p
+ (expand-file-name
+ (file-name-nondirectory tmp-name7) tmp-name2)))))
+
+ ;; Cleanup.
+ (ignore-errors
+ (delete-directory tmp-name1 'recursive)
+ (delete-directory tmp-name2 'recursive)
+ (delete-directory tmp-name7 'recursive))))))))
(ert-deftest tramp-test16-directory-files ()
"Check `directory-files'."
@@ -2936,7 +3025,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(progn
(should-error
(directory-files tmp-name1)
- :type tramp-file-missing)
+ :type 'file-missing)
(make-directory tmp-name1)
(write-region "foo" nil tmp-name2)
(write-region "bla" nil tmp-name3)
@@ -3059,14 +3148,12 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(insert-directory tmp-name1 nil)
(goto-char (point-min))
(should (looking-at-p (regexp-quote tmp-name1))))
- ;; This has been fixed in Emacs 26.1. See Bug#29423.
- (when (tramp--test-emacs26-p)
- (with-temp-buffer
- (insert-directory (file-name-as-directory tmp-name1) nil)
- (goto-char (point-min))
- (should
- (looking-at-p
- (regexp-quote (file-name-as-directory tmp-name1))))))
+ (with-temp-buffer
+ (insert-directory (file-name-as-directory tmp-name1) nil)
+ (goto-char (point-min))
+ (should
+ (looking-at-p
+ (regexp-quote (file-name-as-directory tmp-name1)))))
(with-temp-buffer
(insert-directory tmp-name1 "-al")
(goto-char (point-min))
@@ -3092,12 +3179,25 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(regexp-opt (directory-files tmp-name1))
(length (directory-files tmp-name1)))))))
- ;; Check error case.
+ ;; Check error cases.
+ (when (and (tramp--test-supports-set-file-modes-p)
+ ;; With "sshfs", directories with zero file
+ ;; modes are still "accessible".
+ (not (tramp--test-sshfs-p))
+ ;; A directory is always accessible for user "root".
+ (not (zerop (file-attribute-user-id
+ (file-attributes tmp-name1)))))
+ (set-file-modes tmp-name1 0)
+ (with-temp-buffer
+ (should-error
+ (insert-directory tmp-name1 nil)
+ :type 'file-error))
+ (set-file-modes tmp-name1 #o777))
(delete-directory tmp-name1 'recursive)
(with-temp-buffer
(should-error
(insert-directory tmp-name1 nil)
- :type tramp-file-missing)))
+ :type 'file-missing)))
;; Cleanup.
(ignore-errors (delete-directory tmp-name1 'recursive))))))
@@ -3111,8 +3211,6 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(skip-unless (not (tramp--test-rsync-p)))
;; Wildcards are not supported in tramp-crypt.el.
(skip-unless (not (tramp--test-crypt-p)))
- ;; Since Emacs 26.1.
- (skip-unless (fboundp 'insert-directory-wildcard-in-dir-p))
(dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
(let* ((tmp-name1
@@ -3241,7 +3339,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(goto-char (point-min))
(while (not (or (eobp)
(string-equal
- (dired-get-filename 'localp 'no-error)
+ (dired-get-filename 'no-dir 'no-error)
(file-name-nondirectory tmp-name2))))
(forward-line 1))
(should-not (eobp))
@@ -3251,14 +3349,14 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
;; Point shall still be the recent file.
(should
(string-equal
- (dired-get-filename 'localp 'no-error)
+ (dired-get-filename 'no-dir 'no-error)
(file-name-nondirectory tmp-name2)))
(should-not (re-search-forward "dired" nil t))
;; The copied file has been inserted the line before.
(forward-line -1)
(should
(string-equal
- (dired-get-filename 'localp 'no-error)
+ (dired-get-filename 'no-dir 'no-error)
(file-name-nondirectory tmp-name3))))
(kill-buffer buffer))
@@ -3266,19 +3364,6 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(ignore-errors (kill-buffer buffer))
(ignore-errors (delete-directory tmp-name1 'recursive))))))
-;; Method "smb" supports `make-symbolic-link' only if the remote host
-;; has CIFS capabilities. tramp-adb.el, tramp-gvfs.el, tramp-rclone.el
-;; and tramp-sshfs.el do not support symbolic links at all.
-(defmacro tramp--test-ignore-make-symbolic-link-error (&rest body)
- "Run BODY, ignoring \"make-symbolic-link not supported\" file error."
- (declare (indent defun) (debug (body)))
- `(condition-case err
- (progn ,@body)
- (file-error
- (unless (string-equal (error-message-string err)
- "make-symbolic-link not supported")
- (signal (car err) (cdr err))))))
-
(ert-deftest tramp-test18-file-attributes ()
"Check `file-attributes'.
This tests also `access-file', `file-readable-p',
@@ -3313,14 +3398,25 @@ This tests also `access-file', `file-readable-p',
(file-modes tramp-test-temporary-file-directory))))
(write-region "foo" nil tmp-name1)
(setq test-file-ownership-preserved-p
- (= (tramp-compat-file-attribute-group-id
- (file-attributes tmp-name1))
+ (= (file-attribute-group-id (file-attributes tmp-name1))
(tramp-get-remote-gid tramp-test-vec 'integer)))
(delete-file tmp-name1))
+ (when (tramp--test-supports-set-file-modes-p)
+ (write-region "foo" nil tmp-name1)
+ ;; A file is always accessible for user "root".
+ (when (not (zerop (file-attribute-user-id
+ (file-attributes tmp-name1))))
+ (set-file-modes tmp-name1 0)
+ (should-error
+ (access-file tmp-name1 "error")
+ :type 'file-error)
+ (set-file-modes tmp-name1 #o777))
+ (delete-file tmp-name1))
(should-error
(access-file tmp-name1 "error")
- :type tramp-file-missing)
+ :type 'file-missing)
+
;; `file-ownership-preserved-p' should return t for
;; non-existing files.
(when test-file-ownership-preserved-p
@@ -3336,33 +3432,29 @@ This tests also `access-file', `file-readable-p',
;; We do not test inodes and device numbers.
(setq attr (file-attributes tmp-name1))
(should (consp attr))
- (should (null (tramp-compat-file-attribute-type attr)))
- (should (numberp (tramp-compat-file-attribute-link-number attr)))
- (should (numberp (tramp-compat-file-attribute-user-id attr)))
- (should (numberp (tramp-compat-file-attribute-group-id attr)))
+ (should (null (file-attribute-type attr)))
+ (should (numberp (file-attribute-link-number attr)))
+ (should (numberp (file-attribute-user-id attr)))
+ (should (numberp (file-attribute-group-id attr)))
(should
- (stringp
- (current-time-string
- (tramp-compat-file-attribute-access-time attr))))
+ (stringp (current-time-string (file-attribute-access-time attr))))
(should
(stringp
- (current-time-string
- (tramp-compat-file-attribute-modification-time attr))))
+ (current-time-string (file-attribute-modification-time attr))))
(should
(stringp
- (current-time-string
- (tramp-compat-file-attribute-status-change-time attr))))
- (should (numberp (tramp-compat-file-attribute-size attr)))
- (should (stringp (tramp-compat-file-attribute-modes attr)))
+ (current-time-string (file-attribute-status-change-time attr))))
+ (should (numberp (file-attribute-size attr)))
+ (should (stringp (file-attribute-modes attr)))
(setq attr (file-attributes tmp-name1 'string))
- (should (stringp (tramp-compat-file-attribute-user-id attr)))
- (should (stringp (tramp-compat-file-attribute-group-id attr)))
+ (should (stringp (file-attribute-user-id attr)))
+ (should (stringp (file-attribute-group-id attr)))
(tramp--test-ignore-make-symbolic-link-error
(should-error
(access-file tmp-name2 "error")
- :type tramp-file-missing)
+ :type 'file-missing)
(when test-file-ownership-preserved-p
(should (file-ownership-preserved-p tmp-name2 'group)))
(make-symbolic-link tmp-name1 tmp-name2)
@@ -3376,7 +3468,7 @@ This tests also `access-file', `file-readable-p',
(string-equal
(funcall
(if quoted #'tramp-compat-file-name-quote #'identity)
- (tramp-compat-file-attribute-type attr))
+ (file-attribute-type attr))
(file-remote-p (file-truename tmp-name1) 'localname)))
(delete-file tmp-name2))
@@ -3395,7 +3487,7 @@ This tests also `access-file', `file-readable-p',
(setq attr (file-attributes tmp-name2))
(should
(string-equal
- (tramp-compat-file-attribute-type attr)
+ (file-attribute-type attr)
(tramp-file-name-localname
(tramp-dissect-file-name tmp-name3))))
(delete-file tmp-name2))
@@ -3411,7 +3503,7 @@ This tests also `access-file', `file-readable-p',
(when test-file-ownership-preserved-p
(should (file-ownership-preserved-p tmp-name1 'group)))
(setq attr (file-attributes tmp-name1))
- (should (eq (tramp-compat-file-attribute-type attr) t)))
+ (should (eq (file-attribute-type attr) t)))
;; Cleanup.
(ignore-errors (delete-directory tmp-name1))
@@ -3429,9 +3521,9 @@ They might differ only in time attributes or directory size."
(start-time (- tramp--test-start-time 10)))
;; Link number. For directories, it includes the number of
;; subdirectories. Set it to 1.
- (when (eq (tramp-compat-file-attribute-type attr1) t)
+ (when (eq (file-attribute-type attr1) t)
(setcar (nthcdr 1 attr1) 1))
- (when (eq (tramp-compat-file-attribute-type attr2) t)
+ (when (eq (file-attribute-type attr2) t)
(setcar (nthcdr 1 attr2) 1))
;; Access time.
(setcar (nthcdr 4 attr1) tramp-time-dont-know)
@@ -3444,42 +3536,33 @@ They might differ only in time attributes or directory size."
;; order to compensate a possible timestamp resolution higher than
;; a second on the remote machine.
(when (or (tramp-compat-time-equal-p
- (tramp-compat-file-attribute-modification-time attr1)
- tramp-time-dont-know)
+ (file-attribute-modification-time attr1) tramp-time-dont-know)
(tramp-compat-time-equal-p
- (tramp-compat-file-attribute-modification-time attr2)
- tramp-time-dont-know))
+ (file-attribute-modification-time attr2) tramp-time-dont-know))
(setcar (nthcdr 5 attr1) tramp-time-dont-know)
(setcar (nthcdr 5 attr2) tramp-time-dont-know))
(when (< start-time
- (float-time (tramp-compat-file-attribute-modification-time attr1)))
+ (float-time (file-attribute-modification-time attr1)))
(setcar (nthcdr 5 attr1) tramp-time-dont-know))
(when (< start-time
- (float-time (tramp-compat-file-attribute-modification-time attr2)))
+ (float-time (file-attribute-modification-time attr2)))
(setcar (nthcdr 5 attr2) tramp-time-dont-know))
;; Status change time. Ditto.
(when (or (tramp-compat-time-equal-p
- (tramp-compat-file-attribute-status-change-time attr1)
- tramp-time-dont-know)
+ (file-attribute-status-change-time attr1) tramp-time-dont-know)
(tramp-compat-time-equal-p
- (tramp-compat-file-attribute-status-change-time attr2)
- tramp-time-dont-know))
+ (file-attribute-status-change-time attr2) tramp-time-dont-know))
(setcar (nthcdr 6 attr1) tramp-time-dont-know)
(setcar (nthcdr 6 attr2) tramp-time-dont-know))
- (when
- (< start-time
- (float-time
- (tramp-compat-file-attribute-status-change-time attr1)))
+ (when (< start-time (float-time (file-attribute-status-change-time attr1)))
(setcar (nthcdr 6 attr1) tramp-time-dont-know))
- (when
- (< start-time
- (float-time (tramp-compat-file-attribute-status-change-time attr2)))
+ (when (< start-time (float-time (file-attribute-status-change-time attr2)))
(setcar (nthcdr 6 attr2) tramp-time-dont-know))
;; Size. Set it to 0 for directories, because it might have
;; changed. For example the upper directory "../".
- (when (eq (tramp-compat-file-attribute-type attr1) t)
+ (when (eq (file-attribute-type attr1) t)
(setcar (nthcdr 7 attr1) 0))
- (when (eq (tramp-compat-file-attribute-type attr2) t)
+ (when (eq (file-attribute-type attr2) t)
(setcar (nthcdr 7 attr2) 0))
;; The check.
(unless (equal attr1 attr2) (tramp--test-message "%S\n%S" attr1 attr2))
@@ -3503,12 +3586,12 @@ They might differ only in time attributes or directory size."
(progn
(should-error
(directory-files-and-attributes tmp-name1)
- :type tramp-file-missing)
+ :type 'file-missing)
(make-directory tmp-name1)
(should (file-directory-p tmp-name1))
(setq tramp--test-start-time
(float-time
- (tramp-compat-file-attribute-modification-time
+ (file-attribute-modification-time
(file-attributes tmp-name1))))
(make-directory tmp-name2)
(should (file-directory-p tmp-name2))
@@ -3548,13 +3631,7 @@ They might differ only in time attributes or directory size."
"Check `file-modes'.
This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
(skip-unless (tramp--test-enabled))
- (skip-unless
- (or (tramp--test-sh-p) (tramp--test-sshfs-p) (tramp--test-sudoedit-p)
- ;; Not all tramp-gvfs.el methods support changing the file mode.
- (and
- (tramp--test-gvfs-p)
- (string-match-p
- "ftp" (file-remote-p tramp-test-temporary-file-directory 'method)))))
+ (skip-unless (tramp--test-supports-set-file-modes-p))
(dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
(let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
@@ -3572,8 +3649,7 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
(should (= (file-modes tmp-name1) #o444))
(should-not (file-executable-p tmp-name1))
;; A file is always writable for user "root".
- (unless (zerop (tramp-compat-file-attribute-user-id
- (file-attributes tmp-name1)))
+ (unless (zerop (file-attribute-user-id (file-attributes tmp-name1)))
(should-not (file-writable-p tmp-name1)))
;; Check the NOFOLLOW arg. It exists since Emacs 28. For
;; regular files, there shouldn't be a difference.
@@ -3647,9 +3723,6 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
"Check `file-symlink-p'.
This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(skip-unless (tramp--test-enabled))
- ;; The semantics have changed heavily in Emacs 26.1. We cannot test
- ;; older Emacsen, therefore.
- (skip-unless (tramp--test-emacs26-p))
(dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
;; We must use `file-truename' for the temporary directory,
@@ -3866,11 +3939,11 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(when (tramp--test-expensive-test)
(should-error
(with-temp-buffer (insert-file-contents tmp-name2))
- :type tramp-file-missing))
+ :type 'file-missing))
(when (tramp--test-expensive-test)
(should-error
(with-temp-buffer (insert-file-contents tmp-name3))
- :type tramp-file-missing))
+ :type 'file-missing))
;; `directory-files' does not show symlinks to
;; non-existing targets in the "smb" case. So we remove
;; the symlinks manually.
@@ -3890,7 +3963,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(make-symbolic-link tmp-name2 tmp-name1)
(should (file-symlink-p tmp-name1))
(if (tramp--test-smb-p)
- ;; The symlink command of `smbclient' detects the
+ ;; The symlink command of "smbclient" detects the
;; cycle already.
(should-error
(make-symbolic-link tmp-name1 tmp-name2)
@@ -3931,7 +4004,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(progn
(write-region "foo" nil tmp-name1)
(should (file-exists-p tmp-name1))
- (should (consp (tramp-compat-file-attribute-modification-time
+ (should (consp (file-attribute-modification-time
(file-attributes tmp-name1))))
;; Skip the test, if the remote handler is not able to set
;; the correct time.
@@ -3939,13 +4012,12 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
;; Dumb remote shells without perl(1) or stat(1) are not
;; able to return the date correctly. They say "don't know".
(unless (tramp-compat-time-equal-p
- (tramp-compat-file-attribute-modification-time
+ (file-attribute-modification-time
(file-attributes tmp-name1))
tramp-time-dont-know)
(should
(tramp-compat-time-equal-p
- (tramp-compat-file-attribute-modification-time
- (file-attributes tmp-name1))
+ (file-attribute-modification-time (file-attributes tmp-name1))
(seconds-to-time 1)))
(write-region "bla" nil tmp-name2)
(should (file-exists-p tmp-name2))
@@ -3960,7 +4032,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(set-file-times tmp-name1 (seconds-to-time 1) 'nofollow)
(should
(tramp-compat-time-equal-p
- (tramp-compat-file-attribute-modification-time
+ (file-attribute-modification-time
(file-attributes tmp-name1))
(seconds-to-time 1)))))))
@@ -4001,6 +4073,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(ert-deftest tramp-test24-file-acl ()
"Check that `file-acl' and `set-file-acl' work proper."
(skip-unless (tramp--test-enabled))
+ ;; The following test checks also whether `set-file-modes' will work.
(skip-unless (file-acl tramp-test-temporary-file-directory))
(skip-unless (not (tramp--test-crypt-p)))
@@ -4239,12 +4312,8 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
;; for completion. We must refill the cache.
(tramp-set-connection-property tramp-test-vec "property" nil)
- (let ;; This is needed for the `simplified' syntax.
- ((method-marker
- (if (zerop (length tramp-method-regexp))
- "" tramp-default-method-marker))
- ;; This is needed for the `separate' syntax.
- (prefix-format (substring tramp-prefix-format 1))
+ (let ;; This is needed for the `separate' syntax.
+ ((prefix-format (substring tramp-prefix-format 1))
;; This is needed for the IPv6 host name syntax.
(ipv6-prefix
(and (string-match-p tramp-ipv6-regexp host)
@@ -4260,22 +4329,6 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(concat prefix-format method tramp-postfix-method-format)
(file-name-all-completions
(concat prefix-format (substring method 0 1)) "/"))))
- ;; Complete host name for default method. With gvfs
- ;; based methods, host name will be determined as
- ;; host.local, so we omit the test.
- (let ((tramp-default-method (or method tramp-default-method)))
- (unless (or (zerop (length host))
- (tramp--test-gvfs-p tramp-default-method))
- (should
- (member
- (concat
- prefix-format method-marker tramp-postfix-method-format
- ipv6-prefix host ipv6-postfix tramp-postfix-host-format)
- (file-name-all-completions
- (concat
- prefix-format method-marker tramp-postfix-method-format
- ipv6-prefix (substring host 0 1))
- "/")))))
;; Complete host name.
(unless (or (zerop (length method))
(zerop (length tramp-method-regexp))
@@ -4388,8 +4441,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
"Check `process-file'."
:tags '(:expensive-test)
(skip-unless (tramp--test-enabled))
- (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p) (tramp--test-sshfs-p)))
- (skip-unless (not (tramp--test-crypt-p)))
+ (skip-unless (tramp--test-supports-processes-p))
(dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
(let* ((tmp-name (tramp--test-make-temp-name nil quoted))
@@ -4431,7 +4483,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(write-region "foo" nil tmp-name)
(should (file-exists-p tmp-name))
(should (zerop (process-file "ls" nil t nil fnnd)))
- ;; `ls' could produce colorized output.
+ ;; "ls" could produce colorized output.
(goto-char (point-min))
(while
(re-search-forward tramp-display-escape-sequence-regexp nil t)
@@ -4439,10 +4491,10 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(should (string-equal (format "%s\n" fnnd) (buffer-string)))
(should-not (get-buffer-window (current-buffer) t))
- ;; Second run. The output must be appended.
+ ;; Second run. The output must be appended.
(goto-char (point-max))
(should (zerop (process-file "ls" nil t t fnnd)))
- ;; `ls' could produce colorized output.
+ ;; "ls" could produce colorized output.
(goto-char (point-min))
(while
(re-search-forward tramp-display-escape-sequence-regexp nil t)
@@ -4455,7 +4507,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
;; Cleanup.
(ignore-errors (delete-file tmp-name))))))
-;; Must be a command, because used as `sigusr' handler.
+;; Must be a command, because used as `sigusr1' handler.
(defun tramp--test-timeout-handler (&rest _ignore)
"Timeout handler, reporting a failed test."
(interactive)
@@ -4469,8 +4521,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
"Check `start-file-process'."
:tags '(:expensive-test)
(skip-unless (tramp--test-enabled))
- (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p) (tramp--test-sshfs-p)))
- (skip-unless (not (tramp--test-crypt-p)))
+ (skip-unless (tramp--test-supports-processes-p))
(dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
(let ((default-directory tramp-test-temporary-file-directory)
@@ -4535,16 +4586,75 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
;; Cleanup.
(ignore-errors (delete-process proc)))
+ ;; "telnet" and "sshfs" do not cooperate with disabled filter.
+ (unless (or (tramp--test-telnet-p) (tramp--test-sshfs-p))
+ (unwind-protect
+ (with-temp-buffer
+ (setq proc (start-file-process "test3" (current-buffer) "cat"))
+ (should (processp proc))
+ (should (equal (process-status proc) 'run))
+ (set-process-filter proc t)
+ (process-send-string proc "foo\n")
+ (process-send-eof proc)
+ ;; Read output.
+ (with-timeout (10 (tramp--test-timeout-handler))
+ (while (process-live-p proc)
+ (while (accept-process-output proc 0 nil t))))
+ ;; No output due to process filter.
+ (should (= (point-min) (point-max))))
+
+ ;; Cleanup.
+ (ignore-errors (delete-process proc))))
+
+ ;; Process connection type.
+ (when (and (tramp--test-sh-p)
+ (not (tramp-direct-async-process-p))
+ ;; `executable-find' has changed the number of
+ ;; parameters in Emacs 27.1, so we use `apply' for
+ ;; older Emacsen.
+ (ignore-errors
+ (with-no-warnings
+ (apply #'executable-find '("hexdump" remote)))))
+ (dolist (process-connection-type '(nil pipe t pty))
+ (unwind-protect
+ (with-temp-buffer
+ (setq proc
+ (start-file-process
+ (format "test4-%s" process-connection-type)
+ (current-buffer) "hexdump" "-v" "-e" "/1 \"%02X\n\""))
+ (should (processp proc))
+ (should (equal (process-status proc) 'run))
+ (process-send-string proc "foo\r\n")
+ (process-send-eof proc)
+ ;; Read output.
+ (with-timeout (10 (tramp--test-timeout-handler))
+ (while (< (- (point-max) (point-min))
+ (length "66\n6F\n6F\n0D\n0A\n"))
+ (while (accept-process-output proc 0 nil t))))
+ (should
+ (string-match-p
+ (if (and (memq process-connection-type '(nil pipe))
+ (not (tramp--test-macos-p)))
+ ;; On macOS, there is always newline conversion.
+ ;; "telnet" converts \r to <CR><NUL> if `crlf'
+ ;; flag is FALSE. See telnet(1) man page.
+ "66\n6F\n6F\n0D\\(\n00\\)?\n0A\n"
+ "66\n6F\n6F\n0A\\(\n00\\)?\n0A\n")
+ (buffer-string))))
+
+ ;; Cleanup.
+ (ignore-errors (delete-process proc)))))
+
;; PTY.
(unwind-protect
(with-temp-buffer
;; It works only for tramp-sh.el, and not direct async processes.
(if (or (not (tramp--test-sh-p)) (tramp-direct-async-process-p))
(should-error
- (start-file-process "test4" (current-buffer) nil)
+ (start-file-process "test5" (current-buffer) nil)
:type 'wrong-type-argument)
- (setq proc (start-file-process "test4" (current-buffer) nil))
+ (setq proc (start-file-process "test5" (current-buffer) nil))
(should (processp proc))
(should (equal (process-status proc) 'run))
;; On MS Windows, `process-tty-name' returns nil.
@@ -4559,8 +4669,9 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
"Define ert test `TEST-direct-async' for direct async processes.
If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(declare (indent 1))
- ;; `make-process' supports file name handlers since Emacs 27.
- (when (let ((file-name-handler-alist '(("" . #'tramp--test-always))))
+ ;; `make-process' supports file name handlers since Emacs 27. We
+ ;; cannot use `tramp--test-always' during compilation of the macro.
+ (when (let ((file-name-handler-alist '(("" . (lambda (&rest _) t)))))
(ignore-errors (make-process :file-handler t)))
`(ert-deftest ,(intern (concat (symbol-name test) "-direct-async")) ()
,docstring
@@ -4589,8 +4700,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
"Check `make-process'."
:tags '(:expensive-test)
(skip-unless (tramp--test-enabled))
- (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p) (tramp--test-sshfs-p)))
- (skip-unless (not (tramp--test-crypt-p)))
+ (skip-unless (tramp--test-supports-processes-p))
;; `make-process' supports file name handlers since Emacs 27.
(skip-unless (tramp--test-emacs27-p))
@@ -4668,6 +4778,30 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
;; Cleanup.
(ignore-errors (delete-process proc)))
+ ;; "telnet" and "sshfs" do not cooperate with disabled filter.
+ (unless (or (tramp--test-telnet-p) (tramp--test-sshfs-p))
+ (unwind-protect
+ (with-temp-buffer
+ (setq proc
+ (with-no-warnings
+ (make-process
+ :name "test3" :buffer (current-buffer) :command '("cat")
+ :filter t
+ :file-handler t)))
+ (should (processp proc))
+ (should (equal (process-status proc) 'run))
+ (process-send-string proc "foo\n")
+ (process-send-eof proc)
+ ;; Read output.
+ (with-timeout (10 (tramp--test-timeout-handler))
+ (while (process-live-p proc)
+ (while (accept-process-output proc 0 nil t))))
+ ;; No output due to process filter.
+ (should (= (point-min) (point-max))))
+
+ ;; Cleanup.
+ (ignore-errors (delete-process proc))))
+
;; Process sentinel.
(unwind-protect
(with-temp-buffer
@@ -4693,8 +4827,9 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
;; Cleanup.
(ignore-errors (delete-process proc)))
- ;; Process with stderr buffer.
- (unless (tramp-direct-async-process-p)
+ ;; Process with stderr buffer. "telnet" does not cooperate with
+ ;; three processes.
+ (unless (or (tramp--test-telnet-p) (tramp-direct-async-process-p))
(let ((stderr (generate-new-buffer "*stderr*")))
(unwind-protect
(with-temp-buffer
@@ -4753,6 +4888,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
;; Process connection type.
(when (and (tramp--test-sh-p)
+ (not (tramp-direct-async-process-p))
;; `executable-find' has changed the number of
;; parameters in Emacs 27.1, so we use `apply' for
;; older Emacsen.
@@ -4760,34 +4896,45 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(with-no-warnings
(apply #'executable-find '("hexdump" remote)))))
(dolist (connection-type '(nil pipe t pty))
- (unwind-protect
- (with-temp-buffer
- (setq proc
- (with-no-warnings
- (make-process
- :name (format "test7-%s" connection-type)
- :buffer (current-buffer)
- :connection-type connection-type
- :command '("hexdump" "-v" "-e" "/1 \"%02X\n\"")
- :file-handler t)))
- (should (processp proc))
- (should (equal (process-status proc) 'run))
- (process-send-string proc "foo\r\n")
- (process-send-eof proc)
- ;; Read output.
- (with-timeout (10 (tramp--test-timeout-handler))
- (while (< (- (point-max) (point-min))
- (length "66\n6F\n6F\n0D\n0A\n"))
- (while (accept-process-output proc 0 nil t))))
- (should
- (string-match-p
- (if (memq connection-type '(nil pipe))
- "66\n6F\n6F\n0D\n0A\n"
- "66\n6F\n6F\n0A\n0A\n")
- (buffer-string))))
+ ;; `process-connection-type' is taken when
+ ;; `:connection-type' is nil.
+ (dolist (process-connection-type
+ (unless connection-type '(nil pipe t pty)))
+ (unwind-protect
+ (with-temp-buffer
+ (setq proc
+ (with-no-warnings
+ (make-process
+ :name
+ (format "test7-%s-%s"
+ connection-type process-connection-type)
+ :buffer (current-buffer)
+ :connection-type connection-type
+ :command '("hexdump" "-v" "-e" "/1 \"%02X\n\"")
+ :file-handler t)))
+ (should (processp proc))
+ (should (equal (process-status proc) 'run))
+ (process-send-string proc "foo\r\n")
+ (process-send-eof proc)
+ ;; Read output.
+ (with-timeout (10 (tramp--test-timeout-handler))
+ (while (< (- (point-max) (point-min))
+ (length "66\n6F\n6F\n0D\n0A\n"))
+ (while (accept-process-output proc 0 nil t))))
+ (should
+ (string-match-p
+ (if (and (memq (or connection-type process-connection-type)
+ '(nil pipe))
+ (not (tramp--test-macos-p)))
+ ;; On macOS, there is always newline conversion.
+ ;; "telnet" converts \r to <CR><NUL> if `crlf'
+ ;; flag is FALSE. See telnet(1) man page.
+ "66\n6F\n6F\n0D\\(\n00\\)?\n0A\n"
+ "66\n6F\n6F\n0A\\(\n00\\)?\n0A\n")
+ (buffer-string))))
- ;; Cleanup.
- (ignore-errors (delete-process proc))))))))
+ ;; Cleanup.
+ (ignore-errors (delete-process proc)))))))))
(tramp--test--deftest-direct-async-process tramp-test30-make-process
"Check direct async `make-process'.")
@@ -4799,8 +4946,6 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-crypt-p)))
- ;; Since Emacs 26.1.
- (skip-unless (boundp 'interrupt-process-functions))
;; We must use `file-truename' for the temporary directory, in
;; order to establish the connection prior running an asynchronous
@@ -4856,11 +5001,11 @@ INPUT, if non-nil, is a string sent to the process."
"Check `shell-command'."
:tags '(:expensive-test)
(skip-unless (tramp--test-enabled))
+ (skip-unless (tramp--test-supports-processes-p))
;; Prior Emacs 27, `shell-file-name' was hard coded as "/bin/sh" for
;; remote processes in Emacs. That doesn't work for tramp-adb.el.
- (skip-unless (or (and (tramp--test-adb-p) (tramp--test-emacs27-p))
- (tramp--test-sh-p) (tramp--test-sshfs-p)))
- (skip-unless (not (tramp--test-crypt-p)))
+ (when (tramp--test-adb-p)
+ (skip-unless (tramp--test-emacs27-p)))
(dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
(let ((tmp-name (tramp--test-make-temp-name nil quoted))
@@ -4884,7 +5029,7 @@ INPUT, if non-nil, is a string sent to the process."
this-shell-command
(format "ls %s" (file-name-nondirectory tmp-name))
(current-buffer))
- ;; `ls' could produce colorized output.
+ ;; "ls" could produce colorized output.
(goto-char (point-min))
(while
(re-search-forward tramp-display-escape-sequence-regexp nil t)
@@ -4907,8 +5052,8 @@ INPUT, if non-nil, is a string sent to the process."
"echo foo >&2; echo bar" (current-buffer) stderr)
(should (string-equal "bar\n" (buffer-string)))
;; Check stderr.
- (with-current-buffer stderr
- (should (string-equal "foo\n" (buffer-string)))))
+ (should
+ (string-equal "foo\n" (tramp-get-buffer-string stderr))))
;; Cleanup.
(ignore-errors (kill-buffer stderr))))))
@@ -4958,8 +5103,7 @@ INPUT, if non-nil, is a string sent to the process."
:tags '(:expensive-test :unstable)
(skip-unless (tramp--test-enabled))
(skip-unless nil)
- (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p) (tramp--test-sshfs-p)))
- (skip-unless (not (tramp--test-crypt-p)))
+ (skip-unless (tramp--test-supports-processes-p))
;; Prior Emacs 27, `shell-command-dont-erase-buffer' wasn't working properly.
(skip-unless (tramp--test-emacs27-p))
@@ -5216,9 +5360,6 @@ Use direct async.")
;; Since Emacs 27.1.
(skip-unless (fboundp 'with-connection-local-variables))
- ;; `connection-local-set-profile-variables' and
- ;; `connection-local-set-profiles' exist since Emacs 26.1. We don't
- ;; want to see compiler warnings for older Emacsen.
(let* ((default-directory tramp-test-temporary-file-directory)
(tmp-name1 (tramp--test-make-temp-name))
(tmp-name2 (expand-file-name "foo" tmp-name1))
@@ -5234,23 +5375,22 @@ Use direct async.")
;; `local-variable' is buffer-local due to explicit setting.
(with-no-warnings
- (defvar-local local-variable 'buffer))
+ (defvar-local local-variable 'buffer))
(with-temp-buffer
(should (eq local-variable 'buffer)))
;; `local-variable' is connection-local due to Tramp.
(write-region "foo" nil tmp-name2)
(should (file-exists-p tmp-name2))
- (with-no-warnings
- (connection-local-set-profile-variables
- 'local-variable-profile
- '((local-variable . connect)))
- (connection-local-set-profiles
- `(:application tramp
- :protocol ,(file-remote-p default-directory 'method)
- :user ,(file-remote-p default-directory 'user)
- :machine ,(file-remote-p default-directory 'host))
- 'local-variable-profile))
+ (connection-local-set-profile-variables
+ 'local-variable-profile
+ '((local-variable . connect)))
+ (connection-local-set-profiles
+ `(:application tramp
+ :protocol ,(file-remote-p default-directory 'method)
+ :user ,(file-remote-p default-directory 'user)
+ :machine ,(file-remote-p default-directory 'host))
+ 'local-variable-profile)
(with-current-buffer (find-file-noselect tmp-name2)
(should (eq local-variable 'connect))
(kill-buffer (current-buffer)))
@@ -5275,23 +5415,16 @@ Use direct async.")
;; Cleanup.
(ignore-errors (delete-directory tmp-name1 'recursive)))))
-;; The functions were introduced in Emacs 26.1.
(ert-deftest tramp-test34-explicit-shell-file-name ()
"Check that connection-local `explicit-shell-file-name' is set."
:tags '(:expensive-test)
(skip-unless (tramp--test-enabled))
+ (skip-unless (tramp--test-supports-processes-p))
;; Prior Emacs 27, `shell-file-name' was hard coded as "/bin/sh" for
;; remote processes in Emacs. That doesn't work for tramp-adb.el.
- (skip-unless (or (and (tramp--test-adb-p) (tramp--test-emacs27-p))
- (tramp--test-sh-p) (tramp--test-sshfs-p)))
- (skip-unless (not (tramp--test-crypt-p)))
- ;; Since Emacs 26.1.
- (skip-unless (and (fboundp 'connection-local-set-profile-variables)
- (fboundp 'connection-local-set-profiles)))
+ (when (tramp--test-adb-p)
+ (skip-unless (tramp--test-emacs27-p)))
- ;; `connection-local-set-profile-variables' and
- ;; `connection-local-set-profiles' exist since Emacs 26.1. We don't
- ;; want to see compiler warnings for older Emacsen.
(let ((default-directory tramp-test-temporary-file-directory)
explicit-shell-file-name kill-buffer-query-functions
connection-local-profile-alist connection-local-criteria-alist)
@@ -5300,19 +5433,16 @@ Use direct async.")
;; `shell-mode' would ruin our test, because it deletes all
;; buffer local variables. Not needed in Emacs 27.1.
(put 'explicit-shell-file-name 'permanent-local t)
- ;; Declare connection-local variables `explicit-shell-file-name'
- ;; and `explicit-sh-args'.
- (with-no-warnings
- (connection-local-set-profile-variables
- 'remote-sh
- `((explicit-shell-file-name . ,(tramp--test-shell-file-name))
- (explicit-sh-args . ("-c" "echo foo"))))
- (connection-local-set-profiles
- `(:application tramp
- :protocol ,(file-remote-p default-directory 'method)
- :user ,(file-remote-p default-directory 'user)
- :machine ,(file-remote-p default-directory 'host))
- 'remote-sh))
+ (connection-local-set-profile-variables
+ 'remote-sh
+ `((explicit-shell-file-name . ,(tramp--test-shell-file-name))
+ (explicit-sh-args . ("-c" "echo foo"))))
+ (connection-local-set-profiles
+ `(:application tramp
+ :protocol ,(file-remote-p default-directory 'method)
+ :user ,(file-remote-p default-directory 'user)
+ :machine ,(file-remote-p default-directory 'host))
+ 'remote-sh)
(put 'explicit-shell-file-name 'safe-local-variable #'identity)
(put 'explicit-sh-args 'safe-local-variable #'identity)
@@ -5339,8 +5469,8 @@ Use direct async.")
(ert-deftest tramp-test35-exec-path ()
"Check `exec-path' and `executable-find'."
(skip-unless (tramp--test-enabled))
- (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p) (tramp--test-sshfs-p)))
- (skip-unless (not (tramp--test-crypt-p)))
+ (skip-unless (tramp--test-supports-processes-p))
+ (skip-unless (tramp--test-supports-set-file-modes-p))
;; Since Emacs 27.1.
(skip-unless (fboundp 'exec-path))
@@ -5361,6 +5491,7 @@ Use direct async.")
;; found.
(write-region "foo" nil tmp-name)
(should (file-exists-p tmp-name))
+
(set-file-modes tmp-name #o777)
(should (file-executable-p tmp-name))
(should
@@ -5429,9 +5560,9 @@ Use direct async.")
;; Ignore trailing newline.
(setq path (substring (shell-command-to-string "echo $PATH") nil -1))
;; The shell doesn't handle such long strings.
- (unless (<= (length path)
- (tramp-get-connection-property
- tramp-test-vec "pipe-buf" 4096))
+ (when (<= (length path)
+ (tramp-get-connection-property
+ tramp-test-vec "pipe-buf" 4096))
;; The last element of `exec-path' is `exec-directory'.
(should
(string-equal
@@ -5614,7 +5745,7 @@ Use direct async.")
;; files, owned by root.
(let ((tramp-auto-save-directory temporary-file-directory))
(write-region "foo" nil tmp-name1)
- (when (zerop (or (tramp-compat-file-attribute-user-id
+ (when (zerop (or (file-attribute-user-id
(file-attributes tmp-name1))
tramp-unknown-id-integer))
(with-temp-buffer
@@ -5761,8 +5892,7 @@ Use direct async.")
(let ((backup-directory-alist `(("." . ,temporary-file-directory)))
tramp-backup-directory-alist)
(write-region "foo" nil tmp-name1)
- (when (zerop (or (tramp-compat-file-attribute-user-id
- (file-attributes tmp-name1))
+ (when (zerop (or (file-attribute-user-id (file-attributes tmp-name1))
tramp-unknown-id-integer))
(tramp-cleanup-connection
tramp-test-vec 'keep-debug 'keep-password)
@@ -5805,10 +5935,7 @@ Use direct async.")
tramp-allow-unsafe-temporary-files
(inhibit-message t)
;; tramp-rclone.el and tramp-sshfs.el cache the mounted files.
- (tramp-cleanup-connection-hook
- (append
- (and (tramp--test-fuse-p) '(tramp-fuse-unmount))
- tramp-cleanup-connection-hook))
+ (tramp-fuse-unmount-on-cleanup t)
auto-save-default
noninteractive)
@@ -5901,8 +6028,7 @@ Use direct async.")
;; files, owned by root.
(let ((lock-file-name-transforms auto-save-file-name-transforms))
(write-region "foo" nil tmp-name1)
- (when (zerop (or (tramp-compat-file-attribute-user-id
- (file-attributes tmp-name1))
+ (when (zerop (or (file-attribute-user-id (file-attributes tmp-name1))
tramp-unknown-id-integer))
(tramp-cleanup-connection
tramp-test-vec 'keep-debug 'keep-password)
@@ -5920,29 +6046,22 @@ Use direct async.")
(ignore-errors (delete-file tmp-name1))
(tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)))))
-;; The functions were introduced in Emacs 26.1.
(ert-deftest tramp-test40-make-nearby-temp-file ()
"Check `make-nearby-temp-file' and `temporary-file-directory'."
(skip-unless (tramp--test-enabled))
(skip-unless (not (tramp--test-ange-ftp-p)))
- ;; Since Emacs 26.1.
- (skip-unless
- (and (fboundp 'make-nearby-temp-file) (fboundp 'temporary-file-directory)))
- ;; `make-nearby-temp-file' and `temporary-file-directory' exists
- ;; since Emacs 26.1. We don't want to see compiler warnings for
- ;; older Emacsen.
(let ((default-directory tramp-test-temporary-file-directory)
tmp-file)
;; The remote host shall know a temporary file directory.
- (should (stringp (with-no-warnings (temporary-file-directory))))
+ (should (stringp (temporary-file-directory)))
(should
(string-equal
(file-remote-p default-directory)
- (file-remote-p (with-no-warnings (temporary-file-directory)))))
+ (file-remote-p (temporary-file-directory))))
;; The temporary file shall be located on the remote host.
- (setq tmp-file (with-no-warnings (make-nearby-temp-file "tramp-test")))
+ (setq tmp-file (make-nearby-temp-file "tramp-test"))
(should (file-exists-p tmp-file))
(should (file-regular-p tmp-file))
(should
@@ -5952,18 +6071,12 @@ Use direct async.")
(delete-file tmp-file)
(should-not (file-exists-p tmp-file))
- (setq tmp-file (with-no-warnings (make-nearby-temp-file "tramp-test" 'dir)))
+ (setq tmp-file (make-nearby-temp-file "tramp-test" 'dir))
(should (file-exists-p tmp-file))
(should (file-directory-p tmp-file))
(delete-directory tmp-file)
(should-not (file-exists-p tmp-file))))
-(defun tramp--test-emacs26-p ()
- "Check for Emacs version >= 26.1.
-Some semantics has been changed for there, w/o new functions or
-variables, so we check the Emacs version directly."
- (>= emacs-major-version 26))
-
(defun tramp--test-emacs27-p ()
"Check for Emacs version >= 27.1.
Some semantics has been changed for there, w/o new functions or
@@ -5976,6 +6089,12 @@ Some semantics has been changed for there, w/o new functions or
variables, so we check the Emacs version directly."
(>= emacs-major-version 28))
+(defun tramp--test-emacs29-p ()
+ "Check for Emacs version >= 29.1.
+Some semantics has been changed for there, w/o new functions or
+variables, so we check the Emacs version directly."
+ (>= emacs-major-version 29))
+
(defun tramp--test-adb-p ()
"Check, whether the remote host runs Android.
This requires restrictions of file name syntax."
@@ -5988,7 +6107,7 @@ This requires restrictions of file name syntax."
'tramp-ftp-file-name-handler))
(defun tramp--test-crypt-p ()
- "Check, whether the remote directory is crypted"
+ "Check, whether the remote directory is crypted."
(tramp-crypt-file-name-p tramp-test-temporary-file-directory))
(defun tramp--test-docker-p ()
@@ -6025,8 +6144,7 @@ If optional METHOD is given, it is checked first."
Several special characters do not work properly there."
;; We must refill the cache. `file-truename' does it.
(file-truename tramp-test-temporary-file-directory)
- (string-match-p
- "^HP-UX" (tramp-get-connection-property tramp-test-vec "uname" "")))
+ (tramp-check-remote-uname tramp-test-vec "^HP-UX"))
(defun tramp--test-ksh-p ()
"Check, whether the remote shell is ksh.
@@ -6037,12 +6155,22 @@ a $'' syntax."
(string-match-p
"ksh$" (tramp-get-connection-property tramp-test-vec "remote-shell" "")))
+(defun tramp--test-macos-p ()
+ "Check, whether the remote host runs macOS."
+ ;; We must refill the cache. `file-truename' does it.
+ (file-truename tramp-test-temporary-file-directory)
+ (tramp-check-remote-uname tramp-test-vec "Darwin"))
+
(defun tramp--test-mock-p ()
"Check, whether the mock method is used.
This does not support external Emacs calls."
(string-equal
"mock" (file-remote-p tramp-test-temporary-file-directory 'method)))
+(defun tramp--test-out-of-band-p ()
+ "Check, whether an out-of-band method is used."
+ (tramp-method-out-of-band-p tramp-test-vec 1))
+
(defun tramp--test-rclone-p ()
"Check, whether the remote host is offered by rclone.
This requires restrictions of file name syntax."
@@ -6085,6 +6213,12 @@ This requires restrictions of file name syntax."
"Check, whether the sudoedit method is used."
(tramp-sudoedit-file-name-p tramp-test-temporary-file-directory))
+(defun tramp--test-telnet-p ()
+ "Check, whether the telnet method is used.
+This does not support special file names."
+ (string-equal
+ "telnet" (file-remote-p tramp-test-temporary-file-directory 'method)))
+
(defun tramp--test-windows-nt-p ()
"Check, whether the locale host runs MS Windows."
(eq system-type 'windows-nt))
@@ -6092,13 +6226,13 @@ This requires restrictions of file name syntax."
(defun tramp--test-windows-nt-and-out-of-band-p ()
"Check, whether the locale host runs MS Windows and an out-of-band method.
This does not support utf8 based file transfer."
- (and (eq system-type 'windows-nt)
- (tramp-method-out-of-band-p tramp-test-vec 1)))
+ (and (tramp--test-windows-nt-p)
+ (tramp--test-out-of-band-p)))
(defun tramp--test-windows-nt-or-smb-p ()
"Check, whether the locale or remote host runs MS Windows.
This requires restrictions of file name syntax."
- (or (eq system-type 'windows-nt)
+ (or (tramp--test-windows-nt-p)
(tramp--test-smb-p)))
(defun tramp--test-smb-p ()
@@ -6106,6 +6240,22 @@ This requires restrictions of file name syntax."
This requires restrictions of file name syntax."
(tramp-smb-file-name-p tramp-test-temporary-file-directory))
+(defun tramp--test-supports-processes-p ()
+ "Return whether the method under test supports external processes."
+ (and (or (tramp--test-adb-p) (tramp--test-sh-p) (tramp--test-sshfs-p))
+ (not (tramp--test-crypt-p))))
+
+(defun tramp--test-supports-set-file-modes-p ()
+ "Return whether the method under test supports setting file modes."
+ ;; "smb" does not unless the SMB server supports "posix" extensions.
+ ;; "adb" does not unless the Android device is rooted.
+ (or (tramp--test-sh-p) (tramp--test-sshfs-p) (tramp--test-sudoedit-p)
+ ;; Not all tramp-gvfs.el methods support changing the file mode.
+ (and
+ (tramp--test-gvfs-p)
+ (string-match-p
+ "ftp" (file-remote-p tramp-test-temporary-file-directory 'method)))))
+
(defun tramp--test-check-files (&rest files)
"Run a simple but comprehensive test over every file in FILES."
;; `filename-non-special' has been fixed in Emacs 27.1, see Bug#29579.
@@ -6160,7 +6310,7 @@ This requires restrictions of file name syntax."
(string-equal
(funcall
(if quoted #'tramp-compat-file-name-quote #'identity)
- (tramp-compat-file-attribute-type (file-attributes file3)))
+ (file-attribute-type (file-attributes file3)))
(file-remote-p (file-truename file1) 'localname)))
;; Check file contents.
(with-temp-buffer
@@ -6191,7 +6341,7 @@ This requires restrictions of file name syntax."
(setq buffer (dired-noselect tmp-name1 "--dired -al"))
(goto-char (point-min))
(while (not (eobp))
- (when-let ((name (dired-get-filename 'localp 'no-error)))
+ (when-let ((name (dired-get-filename 'no-dir 'no-error)))
(unless
(string-match-p name directory-files-no-dot-files-regexp)
(should (member name files))))
@@ -6199,9 +6349,9 @@ This requires restrictions of file name syntax."
(kill-buffer buffer)
;; `substitute-in-file-name' could return different
- ;; values. For `adb', there could be strange file
+ ;; values. For "adb", there could be strange file
;; permissions preventing overwriting a file. We don't
- ;; care in this testcase.
+ ;; care in this test case.
(dolist (elt files)
(let ((file1
(substitute-in-file-name (expand-file-name elt tmp-name1)))
@@ -6358,16 +6508,18 @@ This requires restrictions of file name syntax."
;; These tests are inspired by Bug#17238.
(ert-deftest tramp-test41-special-characters ()
"Check special characters in file names."
+ (skip-unless (not (getenv "EMACS_HYDRA_CI"))) ; SLOW ~ 245s
(skip-unless (tramp--test-enabled))
(skip-unless (not (tramp--test-rsync-p)))
- (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
+ (skip-unless (not (tramp--test-rclone-p)))
(tramp--test-special-characters))
(ert-deftest tramp-test41-special-characters-with-stat ()
"Check special characters in file names.
-Use the `stat' command."
+Use the \"stat\" command."
:tags '(:expensive-test)
+ (skip-unless (not (getenv "EMACS_HYDRA_CI"))) ; SLOW ~ 287s
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-rsync-p)))
@@ -6384,8 +6536,9 @@ Use the `stat' command."
(ert-deftest tramp-test41-special-characters-with-perl ()
"Check special characters in file names.
-Use the `perl' command."
+Use the \"perl\" command."
:tags '(:expensive-test)
+ (skip-unless (not (getenv "EMACS_HYDRA_CI"))) ; SLOW ~ 266s
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-rsync-p)))
@@ -6405,8 +6558,9 @@ Use the `perl' command."
(ert-deftest tramp-test41-special-characters-with-ls ()
"Check special characters in file names.
-Use the `ls' command."
+Use the \"ls\" command."
:tags '(:expensive-test)
+ (skip-unless (not (getenv "EMACS_HYDRA_CI"))) ; SLOW ~ 287s
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-rsync-p)))
@@ -6453,7 +6607,7 @@ Use the `ls' command."
;; Use all available language specific snippets.
(lambda (x)
(and
- (stringp (setq x (eval (get-language-info (car x) 'sample-text))))
+ (stringp (setq x (eval (get-language-info (car x) 'sample-text) t)))
;; Filter out strings which use unencodable characters.
(not (and (or (tramp--test-gvfs-p) (tramp--test-smb-p))
(unencodable-char-position
@@ -6472,6 +6626,7 @@ Use the `ls' command."
(ert-deftest tramp-test42-utf8 ()
"Check UTF8 encoding in file names and file contents."
+ (skip-unless (not (getenv "EMACS_HYDRA_CI"))) ; SLOW ~ 620s
(skip-unless (tramp--test-enabled))
(skip-unless (not (tramp--test-docker-p)))
(skip-unless (not (tramp--test-rsync-p)))
@@ -6479,19 +6634,20 @@ Use the `ls' command."
(skip-unless (not (tramp--test-ksh-p)))
(skip-unless (not (tramp--test-gdrive-p)))
(skip-unless (not (tramp--test-crypt-p)))
- (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
+ (skip-unless (not (tramp--test-rclone-p)))
(tramp--test-utf8))
(ert-deftest tramp-test42-utf8-with-stat ()
"Check UTF8 encoding in file names and file contents.
-Use the `stat' command."
+Use the \"stat\" command."
:tags '(:expensive-test)
+ (skip-unless (not (getenv "EMACS_HYDRA_CI"))) ; SLOW ~ 595s
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-docker-p)))
(skip-unless (not (tramp--test-rsync-p)))
- (skip-unless (not (tramp--test-windows-nt-and-out-of-band-p)))
+ (skip-unless (not (tramp--test-out-of-band-p))) ; SLOW
(skip-unless (not (tramp--test-ksh-p)))
(skip-unless (not (tramp--test-crypt-p)))
;; We cannot use `tramp-test-vec', because this fails during compilation.
@@ -6507,13 +6663,14 @@ Use the `stat' command."
(ert-deftest tramp-test42-utf8-with-perl ()
"Check UTF8 encoding in file names and file contents.
-Use the `perl' command."
+Use the \"perl\" command."
:tags '(:expensive-test)
+ (skip-unless (not (getenv "EMACS_HYDRA_CI"))) ; SLOW ~ 620s
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-docker-p)))
(skip-unless (not (tramp--test-rsync-p)))
- (skip-unless (not (tramp--test-windows-nt-and-out-of-band-p)))
+ (skip-unless (not (tramp--test-out-of-band-p))) ; SLOW
(skip-unless (not (tramp--test-ksh-p)))
(skip-unless (not (tramp--test-crypt-p)))
;; We cannot use `tramp-test-vec', because this fails during compilation.
@@ -6532,13 +6689,14 @@ Use the `perl' command."
(ert-deftest tramp-test42-utf8-with-ls ()
"Check UTF8 encoding in file names and file contents.
-Use the `ls' command."
+Use the \"ls\" command."
:tags '(:expensive-test)
+ (skip-unless (not (getenv "EMACS_HYDRA_CI"))) ; SLOW ~ 690s
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-docker-p)))
(skip-unless (not (tramp--test-rsync-p)))
- (skip-unless (not (tramp--test-windows-nt-and-out-of-band-p)))
+ (skip-unless (not (tramp--test-out-of-band-p))) ; SLOW
(skip-unless (not (tramp--test-ksh-p)))
(skip-unless (not (tramp--test-crypt-p)))
@@ -6618,12 +6776,14 @@ process sentinels. They shall not disturb each other."
:tags (if (getenv "EMACS_EMBA_CI")
'(:expensive-test :unstable) '(:expensive-test))
(skip-unless (tramp--test-enabled))
+ (skip-unless (tramp--test-supports-processes-p))
;; Prior Emacs 27, `shell-file-name' was hard coded as "/bin/sh" for
;; remote processes in Emacs. That doesn't work for tramp-adb.el.
- (skip-unless (or (and (tramp--test-adb-p) (tramp--test-emacs27-p))
- (tramp--test-sh-p)))
- (skip-unless (not (tramp--test-crypt-p)))
+ (when (tramp--test-adb-p)
+ (skip-unless (tramp--test-emacs27-p)))
(skip-unless (not (tramp--test-docker-p)))
+ (skip-unless (not (tramp--test-telnet-p)))
+ (skip-unless (not (tramp--test-sshfs-p)))
(skip-unless (not (tramp--test-windows-nt-p)))
(with-timeout
@@ -6661,11 +6821,6 @@ process sentinels. They shall not disturb each other."
(cond
((getenv "EMACS_HYDRA_CI") 10)
(t 1)))
- ;; We must distinguish due to performance reasons.
- (timer-operation
- (cond
- ((tramp--test-mock-p) #'vc-registered)
- (t #'file-attributes)))
;; This is when all timers start. We check inside the
;; timer function, that we don't exceed timeout.
(timer-start (current-time))
@@ -6691,9 +6846,7 @@ process sentinels. They shall not disturb each other."
(when buffers
(let ((time (float-time))
(default-directory tmp-name)
- (file
- (buffer-name
- (nth (random (length buffers)) buffers)))
+ (file (buffer-name (seq-random-elt buffers)))
;; A remote operation in a timer could
;; confuse Tramp heavily. So we ignore this
;; error here.
@@ -6701,7 +6854,7 @@ process sentinels. They shall not disturb each other."
(cons 'remote-file-error debug-ignored-errors)))
(tramp--test-message
"Start timer %s %s" file (current-time-string))
- (funcall timer-operation file)
+ (vc-registered file)
(tramp--test-message
"Stop timer %s %s" file (current-time-string))
;; Adjust timer if it takes too much time.
@@ -6758,7 +6911,7 @@ process sentinels. They shall not disturb each other."
;; the buffers. Mix with regular operation.
(let ((buffers (copy-sequence buffers)))
(while buffers
- (let* ((buf (nth (random (length buffers)) buffers))
+ (let* ((buf (seq-random-elt buffers))
(proc (get-buffer-process buf))
(file (process-get proc 'foo))
(count (process-get proc 'bar)))
@@ -6814,8 +6967,51 @@ process sentinels. They shall not disturb each other."
;; (tramp--test--deftest-direct-async-process tramp-test44-asynchronous-requests
;; "Check parallel direct asynchronous requests." 'unstable)
+(ert-deftest tramp-test45-dired-compress-file ()
+ "Check that Tramp (un)compresses normal files."
+ (skip-unless (tramp--test-enabled))
+ (skip-unless (tramp--test-sh-p))
+ (skip-unless (not (tramp--test-crypt-p)))
+ ;; Starting with Emacs 29.1, `dired-compress-file' is performed by
+ ;; default handler.
+ (skip-unless (not (tramp--test-emacs29-p)))
+
+ (let ((default-directory tramp-test-temporary-file-directory)
+ (tmp-name (tramp--test-make-temp-name)))
+ (write-region "foo" nil tmp-name)
+ (dired default-directory)
+ (dired-revert)
+ (dired-goto-file tmp-name)
+ (should-not (dired-compress))
+ (should (string= (concat tmp-name ".gz") (dired-get-filename)))
+ (should-not (dired-compress))
+ (should (string= tmp-name (dired-get-filename)))
+ (delete-file tmp-name)))
+
+(ert-deftest tramp-test45-dired-compress-dir ()
+ "Check that Tramp (un)compresses directories."
+ (skip-unless (tramp--test-enabled))
+ (skip-unless (tramp--test-sh-p))
+ (skip-unless (not (tramp--test-crypt-p)))
+ ;; Starting with Emacs 29.1, `dired-compress-file' is performed by
+ ;; default handler.
+ (skip-unless (not (tramp--test-emacs29-p)))
+
+ (let ((default-directory tramp-test-temporary-file-directory)
+ (tmp-name (tramp--test-make-temp-name)))
+ (make-directory tmp-name)
+ (dired default-directory)
+ (dired-revert)
+ (dired-goto-file tmp-name)
+ (should-not (dired-compress))
+ (should (string= (concat tmp-name ".tar.gz") (dired-get-filename)))
+ (should-not (dired-compress))
+ (should (string= tmp-name (dired-get-filename)))
+ (delete-directory tmp-name)
+ (delete-file (concat tmp-name ".tar.gz"))))
+
;; This test is inspired by Bug#29163.
-(ert-deftest tramp-test45-auto-load ()
+(ert-deftest tramp-test46-auto-load ()
"Check that Tramp autoloads properly."
;; If we use another syntax but `default', Tramp is already loaded
;; due to the `tramp-change-syntax' call.
@@ -6840,12 +7036,8 @@ process sentinels. They shall not disturb each other."
(mapconcat #'shell-quote-argument load-path " -L ")
(shell-quote-argument code)))))))
-(ert-deftest tramp-test45-delay-load ()
+(ert-deftest tramp-test46-delay-load ()
"Check that Tramp is loaded lazily, only when needed."
- ;; The autoloaded Tramp objects are different since Emacs 26.1. We
- ;; cannot test older Emacsen, therefore.
- (skip-unless (tramp--test-emacs26-p))
-
;; Tramp is neither loaded at Emacs startup, nor when completing a
;; non-Tramp file name like "/foo". Completing a Tramp-alike file
;; name like "/foo:" autoloads Tramp, when `tramp-mode' is t.
@@ -6873,7 +7065,7 @@ process sentinels. They shall not disturb each other."
(mapconcat #'shell-quote-argument load-path " -L ")
(shell-quote-argument (format code tm)))))))))
-(ert-deftest tramp-test45-recursive-load ()
+(ert-deftest tramp-test46-recursive-load ()
"Check that Tramp does not fail due to recursive load."
(skip-unless (tramp--test-enabled))
@@ -6897,12 +7089,8 @@ process sentinels. They shall not disturb each other."
(mapconcat #'shell-quote-argument load-path " -L ")
(shell-quote-argument code))))))))
-(ert-deftest tramp-test45-remote-load-path ()
+(ert-deftest tramp-test46-remote-load-path ()
"Check that Tramp autoloads its packages with remote `load-path'."
- ;; The autoloaded Tramp objects are different since Emacs 26.1. We
- ;; cannot test older Emacsen, therefore.
- (skip-unless (tramp--test-emacs26-p))
-
;; `tramp-cleanup-all-connections' is autoloaded from tramp-cmds.el.
;; It shall still work, when a remote file name is in the
;; `load-path'.
@@ -6926,15 +7114,11 @@ process sentinels. They shall not disturb each other."
(mapconcat #'shell-quote-argument load-path " -L ")
(shell-quote-argument code)))))))
-(ert-deftest tramp-test46-unload ()
+(ert-deftest tramp-test47-unload ()
"Check that Tramp and its subpackages unload completely.
Since it unloads Tramp, it shall be the last test to run."
:tags '(:expensive-test)
(skip-unless noninteractive)
- ;; The autoloaded Tramp objects are different since Emacs 26.1. We
- ;; cannot test older Emacsen, therefore.
- (skip-unless (tramp--test-emacs26-p))
-
;; We have autoloaded objects from tramp.el and tramp-archive.el.
;; In order to remove them, we first need to load both packages.
(require 'tramp)
@@ -6994,8 +7178,7 @@ If INTERACTIVE is non-nil, the tests are run interactively."
;; TODO:
-;; * dired-compress-file
-;; * dired-uncache
+;; * dired-uncache (partly done in other test functions)
;; * file-equal-p (partly done in `tramp-test21-file-links')
;; * file-in-directory-p
;; * file-name-case-insensitive-p
@@ -7005,8 +7188,8 @@ If INTERACTIVE is non-nil, the tests are run interactively."
;; * Work on skipped tests. Make a comment, when it is impossible.
;; * Revisit expensive tests, once problems in `tramp-error' are solved.
-;; * Fix `tramp-test06-directory-file-name' for `ftp'.
-;; * Implement `tramp-test31-interrupt-process' for `adb', `sshfs' and
+;; * Fix `tramp-test06-directory-file-name' for "ftp".
+;; * Implement `tramp-test31-interrupt-process' for "adb", "sshfs" and
;; for direct async processes.
;; * Check, why direct async processes do not work for
;; `tramp-test44-asynchronous-requests'.
diff --git a/test/lisp/newcomment-tests.el b/test/lisp/newcomment-tests.el
new file mode 100644
index 00000000000..65690e593db
--- /dev/null
+++ b/test/lisp/newcomment-tests.el
@@ -0,0 +1,39 @@
+;;; newcomment-tests.el --- Tests for newcomment.el -*- lexical-binding:t -*-
+
+;; Copyright (C) 2021 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)
+
+(ert-deftest test-uncomment-space-comment-continue ()
+ (let ((comment-style 'multi-line)
+ (comment-continue " ")
+ (text " a\n b"))
+ (should
+ (equal text
+ (with-temp-buffer
+ (c-mode)
+ (insert text)
+ (comment-region (point-min) (point-max))
+ (uncomment-region (point-min) (point-max))
+ (buffer-string))))))
+
+;;; newcomment-tests.el ends here
diff --git a/test/lisp/obsolete/cl-tests.el b/test/lisp/obsolete/cl-tests.el
index 0e02e1ca1bc..659c51ebcf8 100644
--- a/test/lisp/obsolete/cl-tests.el
+++ b/test/lisp/obsolete/cl-tests.el
@@ -25,12 +25,11 @@
(require 'cl))
(require 'ert)
-
-
(ert-deftest labels-function-quoting ()
"Test that #'foo does the right thing in `labels'." ; Bug#31792.
- (should (eq (funcall (labels ((foo () t))
- #'foo))
- t)))
+ (with-suppressed-warnings ((obsolete labels))
+ (should (eq (funcall (labels ((foo () t))
+ #'foo))
+ t))))
;;; cl-tests.el ends here
diff --git a/test/lisp/mail/rfc2368-tests.el b/test/lisp/obsolete/rfc2368-tests.el
index f997ea3ecb4..f997ea3ecb4 100644
--- a/test/lisp/mail/rfc2368-tests.el
+++ b/test/lisp/obsolete/rfc2368-tests.el
diff --git a/test/lisp/org/org-tests.el b/test/lisp/org/org-tests.el
index c1985a46a40..e53b0384081 100644
--- a/test/lisp/org/org-tests.el
+++ b/test/lisp/org/org-tests.el
@@ -29,3 +29,5 @@ Ref <https://debbugs.gnu.org/30310>."
(should (require 'org-version nil t))
(should (equal (version-to-list (org-release))
(cdr (assq 'org package--builtin-versions)))))
+
+;;; org-tests.el ends here
diff --git a/test/lisp/paren-tests.el b/test/lisp/paren-tests.el
index c4bec5d86de..11249ee9bc1 100644
--- a/test/lisp/paren-tests.el
+++ b/test/lisp/paren-tests.el
@@ -117,5 +117,36 @@
(- (point-max) 1) (point-max)
nil)))))
+(ert-deftest paren-tests-open-paren-line ()
+ (cl-flet ((open-paren-line ()
+ (let* ((data (show-paren--default))
+ (here-beg (nth 0 data))
+ (there-beg (nth 2 data)))
+ (blink-paren-open-paren-line-string
+ (min here-beg there-beg)))))
+ ;; Lisp-like
+ (with-temp-buffer
+ (insert "(defun foo ()
+ (dummy))")
+ (goto-char (point-max))
+ (should (string= "(defun foo ()" (open-paren-line))))
+
+ ;; C-like
+ (with-temp-buffer
+ (insert "int foo() {
+ int blah;
+ }")
+ (goto-char (point-max))
+ (should (string= "int foo() {" (open-paren-line))))
+
+ ;; C-like with hanging {
+ (with-temp-buffer
+ (insert "int foo()
+ {
+ int blah;
+ }")
+ (goto-char (point-max))
+ (should (string= "int foo()...{" (open-paren-line))))))
+
(provide 'paren-tests)
;;; paren-tests.el ends here
diff --git a/test/lisp/play/cookie1-tests.el b/test/lisp/play/cookie1-tests.el
index 75dea4e5ef0..2dd73d18028 100644
--- a/test/lisp/play/cookie1-tests.el
+++ b/test/lisp/play/cookie1-tests.el
@@ -37,4 +37,4 @@
(should (= (length (cookie-apropos "false" fortune-file)) 1))))
(provide 'fortune-tests)
-;;; fortune-tests.el ends here
+;;; cookie1-tests.el ends here
diff --git a/test/lisp/progmodes/bug-reference-tests.el b/test/lisp/progmodes/bug-reference-tests.el
new file mode 100644
index 00000000000..7a3ab5fbda0
--- /dev/null
+++ b/test/lisp/progmodes/bug-reference-tests.el
@@ -0,0 +1,128 @@
+;;; bug-reference-tests.el --- Tests for bug-reference.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 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 'bug-reference)
+(require 'ert)
+
+(defun test--get-github-entry (url)
+ (and (string-match
+ (car (bug-reference--build-forge-setup-entry
+ "github.com" 'github "https"))
+ url)
+ (match-string 1 url)))
+
+(defun test--get-gitlab-entry (url)
+ (and (string-match
+ (car (bug-reference--build-forge-setup-entry
+ "gitlab.com" 'gitlab "https"))
+ url)
+ (match-string 1 url)))
+
+(defun test--get-gitea-entry (url)
+ (and (string-match
+ (car (bug-reference--build-forge-setup-entry
+ "gitea.com" 'gitea "https"))
+ url)
+ (match-string 1 url)))
+
+(ert-deftest test-github-entry ()
+ (should
+ (equal
+ (test--get-github-entry "git@github.com:larsmagne/csid.git")
+ "larsmagne/csid"))
+ (should
+ (equal
+ (test--get-github-entry "git@github.com:larsmagne/csid")
+ "larsmagne/csid"))
+ (should
+ (equal
+ (test--get-github-entry "https://github.com/magit/magit.git")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-github-entry "https://github.com/magit/magit.git/")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-github-entry "https://github.com/magit/magit")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-github-entry "https://github.com/magit/magit/")
+ "magit/magit")))
+
+(ert-deftest test-gitlab-entry ()
+ (should
+ (equal
+ (test--get-gitlab-entry "git@gitlab.com:larsmagne/csid.git")
+ "larsmagne/csid"))
+ (should
+ (equal
+ (test--get-gitlab-entry "git@gitlab.com:larsmagne/csid")
+ "larsmagne/csid"))
+ (should
+ (equal
+ (test--get-gitlab-entry "https://gitlab.com/magit/magit.git")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-gitlab-entry "https://gitlab.com/magit/magit.git/")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-gitlab-entry "https://gitlab.com/magit/magit")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-gitlab-entry "https://gitlab.com/magit/magit/")
+ "magit/magit")))
+
+(ert-deftest test-gitea-entry ()
+ (should
+ (equal
+ (test--get-gitea-entry "git@gitea.com:larsmagne/csid.git")
+ "larsmagne/csid"))
+ (should
+ (equal
+ (test--get-gitea-entry "git@gitea.com:larsmagne/csid")
+ "larsmagne/csid"))
+ (should
+ (equal
+ (test--get-gitea-entry "https://gitea.com/magit/magit.git")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-gitea-entry "https://gitea.com/magit/magit.git/")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-gitea-entry "https://gitea.com/magit/magit")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-gitea-entry "https://gitea.com/magit/magit/")
+ "magit/magit")))
+
+;;; bug-reference-tests.el ends here
diff --git a/test/lisp/progmodes/compile-tests.el b/test/lisp/progmodes/compile-tests.el
index 2a3bb3dafae..c87a4453cbd 100644
--- a/test/lisp/progmodes/compile-tests.el
+++ b/test/lisp/progmodes/compile-tests.el
@@ -230,6 +230,7 @@
(gnu "foo.c:8:23:information: message" 1 23 8 "foo.c")
(gnu "foo.c:8.23-45: Informational: message" 1 (23 . 45) (8 . nil) "foo.c")
(gnu "foo.c:8-23: message" 1 nil (8 . 23) "foo.c")
+ (gnu " |foo.c:8: message" 1 nil 8 "foo.c")
;; The next one is not in the GNU standards AFAICS.
;; Here we seem to interpret it as LINE1-LINE2.COL2.
(gnu "foo.c:8-45.3: message" 1 (nil . 3) (8 . 45) "foo.c")
@@ -491,7 +492,7 @@ The test data is in `compile-tests--test-regexps-data'."
(compilation-num-warnings-found 0)
(compilation-num-infos-found 0))
(mapc #'compile--test-error-line compile-tests--test-regexps-data)
- (should (eq compilation-num-errors-found 96))
+ (should (eq compilation-num-errors-found 97))
(should (eq compilation-num-warnings-found 35))
(should (eq compilation-num-infos-found 28)))))
diff --git a/test/lisp/progmodes/cperl-mode-resources/grammar.pl b/test/lisp/progmodes/cperl-mode-resources/grammar.pl
index c05fd7efc2a..96a86993082 100644
--- a/test/lisp/progmodes/cperl-mode-resources/grammar.pl
+++ b/test/lisp/progmodes/cperl-mode-resources/grammar.pl
@@ -1,6 +1,7 @@
use 5.024;
use strict;
use warnings;
+use utf8;
sub outside {
say "Line @{[__LINE__]}: package '@{[__PACKAGE__]}'";
@@ -155,4 +156,17 @@ package :: {
Shoved::elsewhere();
+# Finally, try unicode identifiers.
+package Erdős::Number;
+
+sub erdős_number {
+ my $name = shift;
+ if ($name eq "Erdős Pál") {
+ return 0;
+ }
+ else {
+ die "No access to the database. Sorry.";
+ }
+}
+
1;
diff --git a/test/lisp/progmodes/cperl-mode-resources/here-docs.pl b/test/lisp/progmodes/cperl-mode-resources/here-docs.pl
index 8af4625fff3..bb3d4871a91 100644
--- a/test/lisp/progmodes/cperl-mode-resources/here-docs.pl
+++ b/test/lisp/progmodes/cperl-mode-resources/here-docs.pl
@@ -17,7 +17,7 @@ For each of the HERE documents, the following checks will done:
=item *
-All occurrences of the string "look-here" are fontified correcty.
+All occurrences of the string "look-here" are fontified correctly.
Note that we deliberately test the face, not the syntax property:
Users won't care for the syntax property, but they see the face.
Different implementations with different syntax properties have been
diff --git a/test/lisp/progmodes/cperl-mode-tests.el b/test/lisp/progmodes/cperl-mode-tests.el
index 4d2bac6ee47..29b9e3f6fb9 100644
--- a/test/lisp/progmodes/cperl-mode-tests.el
+++ b/test/lisp/progmodes/cperl-mode-tests.el
@@ -154,16 +154,122 @@ point in the distant past, and is still broken in perl-mode. "
(should (equal (get-text-property (match-beginning 0) 'face)
'font-lock-keyword-face))))
+(ert-deftest cperl-test-fontify-special-variables ()
+ "Test fontification of variables like $^T or ${^ENCODING}.
+These can occur as \"local\" aliases."
+ (skip-unless (eq cperl-test-mode #'cperl-mode))
+ (with-temp-buffer
+ (insert "local ($^I, ${^UNICODE});\n")
+ (goto-char (point-min))
+ (funcall cperl-test-mode)
+ (font-lock-ensure)
+ (search-forward "$")
+ (should (equal (get-text-property (point) 'face)
+ 'font-lock-variable-name-face))
+ (search-forward "$")
+ (should (equal (get-text-property (point) 'face)
+ 'font-lock-variable-name-face))))
+
+(ert-deftest cperl-test-identify-heredoc ()
+ "Test whether a construct containing \"<<\" followed by a
+ bareword is properly identified for a here-document if
+ appropriate."
+ (let ((here-docs
+ '("$text .= <<DELIM;" ; mutator concatenating a here-doc
+ "func($arg) . <<DELIM;" ; concatenating a return value
+ "func 1, <<DELIM;" ; a function taking two arguments
+ ))
+ ;; There forms are currently mishandled in `perl-mode' :-(
+ (here-docs-cperl
+ '("print {a} <<DELIM;" ; printing to a file handle
+ "system $prog <<DELIM;" ; lie about the program's name
+ ))
+ (_undecidable
+ '("foo <<bar") ; could be either "foo() <<bar"
+ ; or "foo(<<bar)"
+ ))
+ (dolist (code (append here-docs (if (eq cperl-test-mode #'cperl-mode)
+ here-docs-cperl)))
+ (with-temp-buffer
+ (insert code "\n\nDELIM\n")
+ (funcall cperl-test-mode)
+ (goto-char (point-min))
+ (forward-line 1)
+ ;; We should now be within a here-doc.
+ (let ((ppss (syntax-ppss)))
+ (should (and (nth 8 ppss) (nth 4 ppss))))
+ ))))
+
+(ert-deftest cperl-test-identify-no-heredoc ()
+ "Test whether a construct containing \"<<\" which is not a
+ here-document is properly rejected."
+ (let (
+ (not-here-docs
+ '("while (<<>>) {" ; double angle bracket operator
+ "expr <<func();" ; left shift by a return value
+ "$var <<func;" ; left shift by a return value
+ "($var+1) <<func;" ; same for an expression
+ "$hash{key} <<func;" ; same for a hash element
+ "or $var <<func;" ; same for an expression
+ "sorted $by <<func" ; _not_ a call to sort
+ ))
+ (_undecidable
+ '("foo <<bar" ; could be either "foo() <<bar"
+ ; or "foo(<<bar)"
+ "$foo = <<;") ; empty delim forbidden since 5.28
+ ))
+ (dolist (code not-here-docs)
+ (with-temp-buffer
+ (insert code "\n\n")
+ (funcall cperl-test-mode)
+ (goto-char (point-min))
+ (forward-line 1)
+ ;; Point is not within a here-doc (nor string nor comment).
+ (let ((ppss (syntax-ppss)))
+ (should-not (nth 8 ppss)))
+ ))))
+
+(ert-deftest cperl-test-here-doc-missing-end ()
+ "Verify that a missing here-document terminator gives a message.
+This message prints the terminator which wasn't found and is only
+issued by CPerl mode."
+ (skip-unless (eq cperl-test-mode #'cperl-mode))
+ (ert-with-message-capture collected-messages
+ (with-temp-buffer
+ (insert "my $foo = <<HERE\n")
+ (insert "some text here\n")
+ (goto-char (point-min))
+ (funcall cperl-test-mode)
+ (cperl-find-pods-heres)
+ (should (string-match "End of here-document [‘'`]HERE[’']"
+ collected-messages))))
+ (ert-with-message-capture collected-messages
+ (with-temp-buffer
+ (insert "my $foo = <<HERE . <<'THERE'\n")
+ (insert "some text here\n")
+ (insert "HERE\n")
+ (insert "more text here\n")
+ (goto-char (point-min))
+ (funcall cperl-test-mode)
+ (cperl-find-pods-heres)
+ (should (string-match "End of here-document [‘'`]THERE[’']"
+ collected-messages)))))
+
(defvar perl-continued-statement-offset)
(defvar perl-indent-level)
+(defconst cperl--tests-heredoc-face
+ (if (equal cperl-test-mode 'perl-mode) 'perl-heredoc
+ 'font-lock-string-face))
+(defconst cperl--tests-heredoc-delim-face
+ (if (equal cperl-test-mode 'perl-mode) 'perl-heredoc
+ 'font-lock-constant-face))
+
(ert-deftest cperl-test-heredocs ()
"Test that HERE-docs are fontified with the appropriate face."
(require 'perl-mode)
(let ((file (ert-resource-file "here-docs.pl"))
(cperl-continued-statement-offset perl-continued-statement-offset)
- (target-font (if (equal cperl-test-mode 'perl-mode) 'perl-heredoc
- 'font-lock-string-face))
(case-fold-search nil))
(with-temp-buffer
(insert-file-contents file)
@@ -176,7 +282,7 @@ point in the distant past, and is still broken in perl-mode. "
(while (search-forward "look-here" nil t)
(should (equal
(get-text-property (match-beginning 0) 'face)
- target-font))
+ cperl--tests-heredoc-face))
(beginning-of-line)
(should (null (looking-at "[ \t]")))
(forward-line 1)))
@@ -205,27 +311,30 @@ the whole string."
(and (string-match regexp string)
(string= (match-string 0 string) string))))))
-(ert-deftest cperl-test-ws-regexp ()
+(ert-deftest cperl-test-ws-rx ()
"Tests capture of very simple regular expressions (yawn)."
+ (skip-unless (eq cperl-test-mode #'cperl-mode))
(let ((valid
'(" " "\t" "\n"))
(invalid
'("a" " " "")))
- (cperl-test--validate-regexp cperl--ws-regexp
+ (cperl-test--validate-regexp (rx (eval cperl--ws-rx))
valid invalid)))
-(ert-deftest cperl-test-ws-or-comment-regexp ()
+(ert-deftest cperl-test-ws+-rx ()
"Tests sequences of whitespace and comment lines."
+ (skip-unless (eq cperl-test-mode #'cperl-mode))
(let ((valid
`(" " "\t#\n" "\n# \n"
,(concat "# comment\n" "# comment\n" "\n" "#comment\n")))
(invalid
'("=head1 NAME\n" )))
- (cperl-test--validate-regexp cperl--ws-or-comment-regexp
+ (cperl-test--validate-regexp (rx (eval cperl--ws+-rx))
valid invalid)))
(ert-deftest cperl-test-version-regexp ()
"Tests the regexp for recommended syntax of versions in Perl."
+ (skip-unless (eq cperl-test-mode #'cperl-mode))
(let ((valid
'("1" "1.1" "1.1_1" "5.032001"
"v120.100.103"))
@@ -241,6 +350,7 @@ the whole string."
(ert-deftest cperl-test-package-regexp ()
"Tests the regular expression of Perl package names with versions.
Also includes valid cases with whitespace in strange places."
+ (skip-unless (eq cperl-test-mode #'cperl-mode))
(let ((valid
'("package Foo"
"package Foo::Bar"
@@ -253,9 +363,287 @@ Also includes valid cases with whitespace in strange places."
"packageFoo" ; not a package declaration
"package Foo1.1" ; invalid package name
"class O3D::Sphere"))) ; class not yet supported
- (cperl-test--validate-regexp cperl--package-regexp
+ (cperl-test--validate-regexp (rx (eval cperl--package-rx))
valid invalid)))
+(ert-deftest cperl-test-identifier-rx ()
+ "Test valid and invalid identifiers (no sigils)."
+ (skip-unless (eq cperl-test-mode #'cperl-mode))
+ (let ((valid
+ '("foo" "FOO" "f_oo" "a123"
+ "manĝis")) ; Unicode is allowed!
+ (invalid
+ '("$foo" ; no sigils allowed (yet)
+ "Foo::bar" ; no package qualifiers allowed
+ "lots_of_€"))) ; € is not alphabetic
+ (cperl-test--validate-regexp (rx (eval cperl--basic-identifier-rx))
+ valid invalid)))
+
+;;; Test unicode identifier in various places
+
+(defun cperl--test-unicode-setup (code string)
+ "Insert CODE, prepare it for tests, and find STRING.
+Invoke the appropriate major mode, ensure fontification, and set
+point after the first occurrence of STRING (no regexp!)."
+ (insert code)
+ (funcall cperl-test-mode)
+ (font-lock-ensure)
+ (goto-char (point-min))
+ (search-forward string))
+
+(ert-deftest cperl-test-unicode-labels ()
+ "Verify that non-ASCII labels are processed correctly."
+ (with-temp-buffer
+ (cperl--test-unicode-setup "LABEł: for ($manĝi) { say; }" "LAB")
+ (should (equal (get-text-property (point) 'face)
+ 'font-lock-constant-face))))
+
+(ert-deftest cperl-test-unicode-sub ()
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ (concat "use strict;\n" ; distinguish bob from b-o-f
+ "sub ℏ {\n"
+ " 6.62607015e-34\n"
+ "};")
+ "sub ") ; point is before "ℏ"
+
+ ;; Testing fontification
+ ;; FIXME 2021-09-10: This tests succeeds because cperl-mode
+ ;; accepts almost anything as a sub name for fontification. For
+ ;; example, it fontifies "sub @ {...;}" which is a syntax error in
+ ;; Perl. I let this pass for the moment.
+ (should (equal (get-text-property (point) 'face)
+ 'font-lock-function-name-face))
+
+ ;; Testing `beginning-of-defun'. Not available in perl-mode,
+ ;; where it jumps to the beginning of the buffer.
+ (when (eq cperl-test-mode #'cperl-mode)
+ (goto-char (point-min))
+ (search-forward "-34")
+ (beginning-of-defun)
+ (should (looking-at "sub")))))
+
+(ert-deftest cperl-test-unicode-varname ()
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ (concat "use strict;\n"
+ "my $π = 3.1415926535897932384626433832795028841971;\n"
+ "\n"
+ "my $manĝi = $π;\n"
+ "__END__\n")
+ "my $") ; perl-mode doesn't fontify the sigil, so include it here
+
+ ;; Testing fontification
+ ;; FIXME 2021-09-10: This test succeeds in cperl-mode because the
+ ;; π character is "not ASCII alphabetic", so it treats $π as a
+ ;; punctuation variable. The following two `should' forms with a
+ ;; longer variable name were added for stronger verification.
+ (should (equal (get-text-property (point) 'face)
+ 'font-lock-variable-name-face))
+ ;; Test both ends of a longer variable name
+ (search-forward "my $") ; again skip the sigil
+ (should (equal (get-text-property (point) 'face)
+ 'font-lock-variable-name-face))
+ (search-forward "manĝi")
+ (should (equal (get-text-property (1- (match-end 0)) 'face)
+ 'font-lock-variable-name-face))))
+
+(ert-deftest cperl-test-unicode-varname-list ()
+ "Verify that all elements of a variable list are fontified."
+
+ (let ((hash-face (if (eq cperl-test-mode #'perl-mode)
+ 'perl-non-scalar-variable
+ 'cperl-hash-face))
+ (array-face (if (eq cperl-test-mode #'perl-mode)
+ 'perl-non-scalar-variable
+ 'cperl-array-face)))
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ "my (%äsh,@ärräy,$scâlâr);" "%")
+ (should (equal (get-text-property (point) 'face)
+ hash-face))
+ (search-forward "@")
+ (should (equal (get-text-property (point) 'face)
+ array-face))
+ (search-forward "scâlâr")
+ (should (equal (get-text-property (match-beginning 0) 'face)
+ 'font-lock-variable-name-face))
+ (should (equal (get-text-property (1- (match-end 0)) 'face)
+ 'font-lock-variable-name-face)))
+
+ ;; Now with package-qualified variables
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ "local (%Søme::äsh,@Søme::ärräy,$Søme::scâlâr);" "%")
+ (should (equal (get-text-property (point) 'face)
+ hash-face))
+ (search-forward "Søme::") ; test basic identifier
+ (should (equal (get-text-property (point) 'face)
+ hash-face))
+ (search-forward "@") ; test package name
+ (should (equal (get-text-property (point) 'face)
+ array-face))
+ (search-forward "Søme::") ; test basic identifier
+ (should (equal (get-text-property (point) 'face)
+ array-face))
+ (search-forward "Søme") ; test package name
+ (should (equal (get-text-property (match-beginning 0) 'face)
+ 'font-lock-variable-name-face))
+ (should (equal (get-text-property (1- (match-end 0)) 'face)
+ 'font-lock-variable-name-face))
+ (search-forward "scâlâr") ; test basic identifier
+ (should (equal (get-text-property (match-beginning 0) 'face)
+ 'font-lock-variable-name-face))
+ (should (equal (get-text-property (1- (match-end 0)) 'face)
+ 'font-lock-variable-name-face)))))
+
+(ert-deftest cperl-test-unicode-arrays ()
+ "Test fontification of array access."
+ ;; Perl mode just looks at the sigil, for element access
+ (skip-unless (eq cperl-test-mode #'cperl-mode))
+ ;; simple array element
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ "$ärräy[1] = 7;" "$")
+ (should (equal (get-text-property (point) 'face)
+ 'cperl-array-face)))
+ ;; array slice
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ "@ärräy[(1..3)] = (4..6);" "@")
+ (should (equal (get-text-property (point) 'face)
+ 'cperl-array-face)))
+ ;; array max index
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ "$#ärräy = 1;" "$")
+ (should (equal (get-text-property (point) 'face)
+ 'cperl-array-face)))
+ ;; array dereference
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ "@$ärräy = (1,2,3)" "@")
+ (should (equal (get-text-property (1- (point)) 'face)
+ 'cperl-array-face))
+ (should (equal (get-text-property (1+ (point)) 'face)
+ 'font-lock-variable-name-face))))
+
+(ert-deftest cperl-test-unicode-hashes ()
+ "Test fontification of hash access."
+ ;; Perl mode just looks at the sigil, for element access
+ (skip-unless (eq cperl-test-mode #'cperl-mode))
+ ;; simple hash element
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ "$häsh{'a'} = 7;" "$")
+ (should (equal (get-text-property (point) 'face)
+ 'cperl-hash-face)))
+ ;; hash array slice
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ "@häsh{(1..3)} = (4..6);" "@")
+ (should (equal (get-text-property (point) 'face)
+ 'cperl-hash-face)))
+ ;; hash subset
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ "my %hash = %häsh{'a',2,3};" "= %")
+ (should (equal (get-text-property (point) 'face)
+ 'cperl-hash-face)))
+ ;; hash dereference
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ "%$äsh = (key => 'value');" "%")
+ (should (equal (get-text-property (1- (point)) 'face)
+ 'cperl-hash-face))
+ (should (equal (get-text-property (1+ (point)) 'face)
+ 'font-lock-variable-name-face))))
+
+(ert-deftest cperl-test-unicode-hashref ()
+ "Verify that a hashref access disambiguates {s}.
+CPerl mode takes the token \"s\" as a substitution unless
+detected otherwise. Not for perl-mode: it doesn't stringify
+bareword hash keys and doesn't recognize a substitution
+\"s}foo}bar}\""
+ (skip-unless (eq cperl-test-mode #'cperl-mode))
+ (with-temp-buffer
+ (cperl--test-unicode-setup "$häshref->{s} # }}" "{")
+ (should (equal (get-text-property (point) 'face)
+ 'font-lock-string-face))
+ (should (equal (get-text-property (1+ (point)) 'face)
+ nil))))
+
+(ert-deftest cperl-test-unicode-proto ()
+ ;; perl-mode doesn't fontify prototypes at all
+ (skip-unless (eq cperl-test-mode #'cperl-mode))
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ (concat "sub prötötyped ($) {\n"
+ " ...;"
+ "}\n")
+ "prötötyped (")
+
+ (should (equal (get-text-property (point) 'face)
+ 'font-lock-string-face))))
+
+(ert-deftest cperl-test-unicode-fhs ()
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ (concat "while (<BAREWÖRD>) {\n"
+ " ...;)\n"
+ "}\n")
+ "while (<") ; point is before the first char of the handle
+ ;; Testing fontification
+ ;; FIXME 2021-09-10: perl-mode.el and cperl-mode.el handle these
+ ;; completely differently. perl-mode interprets barewords as
+ ;; constants, cperl-mode does not fontify them. Both treat
+ ;; non-barewords as globs, which are not fontified by perl-mode,
+ ;; but fontified as strings in cperl-mode. We keep (and test)
+ ;; that behavior "as is" because both bareword filehandles and
+ ;; <glob> syntax are no longer recommended.
+ (let ((bareword-face
+ (if (equal cperl-test-mode 'perl-mode) 'font-lock-constant-face
+ nil)))
+ (should (equal (get-text-property (point) 'face)
+ bareword-face)))))
+
+(ert-deftest cperl-test-unicode-hashkeys ()
+ "Test stringification of bareword hash keys. Not in perl-mode.
+perl-mode generally does not stringify bareword hash keys."
+ (skip-unless (eq cperl-test-mode #'cperl-mode))
+ ;; Plain hash key
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ "$häsh { kéy }" "{ ")
+ (should (equal (get-text-property (point) 'face)
+ 'font-lock-string-face)))
+ ;; Nested hash key
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ "$häsh { kéy } { kèy }" "} { ")
+ (should (equal (get-text-property (point) 'face)
+ 'font-lock-string-face)))
+ ;; Key => value
+ (with-temp-buffer
+ (cperl--test-unicode-setup
+ "( kéy => 'value'," "( ")
+ (should (equal (get-text-property (point) 'face)
+ 'font-lock-string-face))))
+
+(ert-deftest cperl-test-word-at-point ()
+ "Test whether the function captures non-ASCII words."
+ (skip-unless (eq cperl-test-mode #'cperl-mode))
+ (let ((words '("rôle" "café" "ångström"
+ "Data::Dump::dump"
+ "_underscore")))
+ (dolist (word words)
+ (with-temp-buffer
+ (insert " + ") ; this will be the suffix
+ (beginning-of-line)
+ (insert ")") ; A non-word char
+ (insert word)
+ (should (string= word (cperl-word-at-point-hard)))))))
+
;;; Function test: Building an index for imenu
(ert-deftest cperl-test-imenu-index ()
@@ -279,7 +667,8 @@ created by CPerl mode, so skip it for Perl mode."
"Versioned::Package::outer"
"lexical"
"Versioned::Block::signatured"
- "Package::in_package_again")))
+ "Package::in_package_again"
+ "Erdős::Number::erdős_number")))
(dolist (sub expected)
(should (assoc-string sub index)))))))
@@ -339,6 +728,72 @@ under timeout control."
(should (string-match
"poop ('foo', \n 'bar')" (buffer-string))))))
+(ert-deftest cperl-test-bug-14343 ()
+ "Verify that inserting text into a HERE-doc string with Elisp
+does not break fontification."
+ (with-temp-buffer
+ (insert "my $string = <<HERE;\n"
+ "One line of text.\n"
+ "Last line of this string.\n"
+ "HERE\n")
+ (funcall cperl-test-mode)
+ (font-lock-ensure)
+ (goto-char (point-min))
+ (search-forward "One line")
+ (should (equal (get-text-property (point) 'face)
+ cperl--tests-heredoc-face))
+ (beginning-of-line)
+ (insert "Another line if text.\n")
+ (font-lock-ensure)
+ (forward-line -1)
+ (should (equal (get-text-property (point) 'face)
+ cperl--tests-heredoc-face))
+ (search-forward "HERE")
+ (beginning-of-line)
+ (should (equal (get-text-property (point) 'face)
+ cperl--tests-heredoc-delim-face)))
+ ;; insert into an empty here-document
+ (with-temp-buffer
+ (insert "print <<HERE;\n"
+ "HERE\n")
+ (funcall cperl-test-mode)
+ (font-lock-ensure)
+ (goto-char (point-min))
+ (forward-line)
+ (should (equal (get-text-property (point) 'face)
+ cperl--tests-heredoc-delim-face))
+ ;; Insert a newline into the empty here-document
+ (goto-char (point-min))
+ (forward-line)
+ (insert "\n")
+ (search-forward "HERE")
+ (beginning-of-line)
+ (should (equal (get-text-property (point) 'face)
+ cperl--tests-heredoc-delim-face))
+ ;; Insert text at the beginning of the here-doc
+ (goto-char (point-min))
+ (forward-line)
+ (insert "text")
+ (font-lock-ensure)
+ (search-backward "text")
+ (should (equal (get-text-property (point) 'face)
+ cperl--tests-heredoc-face))
+ (search-forward "HERE")
+ (beginning-of-line)
+ (should (equal (get-text-property (point) 'face)
+ cperl--tests-heredoc-delim-face))
+ ;; Insert a new line immediately before the delimiter
+ ;; (That's where the point is anyway)
+ (insert "A new line\n")
+ (font-lock-ensure)
+ ;; The delimiter is still the delimiter
+ (should (equal (get-text-property (point) 'face)
+ cperl--tests-heredoc-delim-face))
+ (forward-line -1)
+ ;; The new line has been "added" to the here-document
+ (should (equal (get-text-property (point) 'face)
+ cperl--tests-heredoc-face))))
+
(ert-deftest cperl-test-bug-16368 ()
"Verify that `cperl-forward-group-in-re' doesn't hide errors."
(skip-unless (eq cperl-test-mode #'cperl-mode))
diff --git a/test/lisp/progmodes/elisp-mode-resources/elisp-indents.erts b/test/lisp/progmodes/elisp-mode-resources/elisp-indents.erts
new file mode 100644
index 00000000000..2c0d51edae8
--- /dev/null
+++ b/test/lisp/progmodes/elisp-mode-resources/elisp-indents.erts
@@ -0,0 +1,88 @@
+Code:
+ (lambda ()
+ (emacs-lisp-mode)
+ (indent-region (point-min) (point-max)))
+
+Name: defun
+
+=-=
+(defun foo ()
+"doc"
+(+ 1 2))
+=-=
+(defun foo ()
+ "doc"
+ (+ 1 2))
+=-=-=
+
+Name: function call
+
+=-=
+(foo zot
+bar
+(zot bar))
+=-=
+(foo zot
+ bar
+ (zot bar))
+=-=-=
+
+Name: lisp data
+
+=-=
+( foo zot
+bar
+(zot bar))
+=-=
+( foo zot
+ bar
+ (zot bar))
+=-=-=
+
+Name: defun-space
+
+=-=
+(defun x ()
+ (print (quote ( thingy great
+ stuff)))
+ (print (quote (thingy great
+ stuff))))
+=-=-=
+
+Name: defvar-keymap
+
+=-=
+(defvar-keymap eww-link-keymap
+ :copy shr-map
+ :foo bar
+ "\r" #'eww-follow-link)
+=-=-=
+
+Name: def-indent1
+
+=-=
+(defzot-does-not-exist 1
+ 2 3)
+=-=-=
+
+Name: def-indent2
+
+=-=
+(define-keymap 1
+ 2 3)
+=-=-=
+
+Name: elisp-indents1
+
+=-=
+(defvar foo
+ ()
+ "bar")
+=-=-=
+
+Name: elisp-indents2
+
+=-=
+(defvar foo ()
+ "bar")
+=-=-=
diff --git a/test/lisp/progmodes/elisp-mode-resources/flet.erts b/test/lisp/progmodes/elisp-mode-resources/flet.erts
new file mode 100644
index 00000000000..da3dcb6ec3e
--- /dev/null
+++ b/test/lisp/progmodes/elisp-mode-resources/flet.erts
@@ -0,0 +1,353 @@
+Name: flet1
+
+=-=
+(cl-flet ()
+ (a (dangerous-position
+ b)))
+=-=-=
+
+Name: flet2
+
+=-=
+(cl-flet wrong-syntax-but-should-not-obstruct-indentation
+ (a (dangerous-position
+ b)))
+=-=-=
+
+Name: flet3
+
+=-=
+(cl-flet ((a (arg-of-flet-a)
+ b
+ c)))
+=-=-=
+
+Name: flet4
+
+=-=
+(cl-flet ((a (arg-of-flet-a)
+ b
+ c
+ (if d
+ e
+ f))
+ (irregular-local-def (form
+ returning
+ lambda))
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet5
+
+=-=
+(cl-flet ((a (arg-of-flet-a)
+ b
+ c
+ (if d
+ e
+ f))
+ (irregular-local-def (form
+ returning
+ lambda))
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet6
+
+=-=
+(cl-flet ((a (arg-of-flet-a)
+ b
+ c
+ (if d
+ e
+ f))
+ (irregular-local-def (form
+ returning
+ lambda))
+ (irregular-local-def (form returning
+ lambda))
+ wrong-syntax-but-should-not-osbtruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet7
+
+=-=
+(cl-flet ((a (arg-of-flet-a)
+ b
+ c
+ (if d
+ e
+ f))
+ (irregular-local-def (form
+ returning
+ lambda))
+ wrong-syntax-but-should-not-osbtruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet8
+
+=-=
+(cl-flet (wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+;; (setf _) not yet supported but looks like it will be
+Name: flet9
+
+=-=
+(cl-flet (((setf a) (new value)
+ stuff)
+ wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet10
+
+=-=
+(cl-flet ( (a (arg-of-flet-a)
+ b
+ c
+ (if d
+ e
+ f))
+ (irregular-local-def (form
+ returning
+ lambda))
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet11
+
+=-=
+(cl-flet ( wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet12
+
+=-=
+(cl-flet ( wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet13
+
+=-=
+(cl-flet (wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i)
+ wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i)))
+=-=-=
+
+Name: flet14
+
+=-=
+(cl-flet (wrong-syntax-but-should-not-obstruct-indentation
+ wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i)
+ wrong-syntax-but-should-not-obstruct-indentation))
+=-=-=
+
+Name: flet15
+
+=-=
+(cl-flet (wrong-syntax-but-should-not-obstruct-indentation
+ wrong-syntax-but-should-not-obstruct-indentation
+ wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i)))
+=-=-=
+
+Name: flet16
+
+=-=
+(cl-flet ((f (x)
+ (g x)))
+ (pcase e
+ ((dangerous-expression)
+ (form))))
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-no-side-effects-1
+Code: (lambda () (emacs-lisp-mode) (setq indent-tabs-mode nil) (newline nil t))
+Point-Char: |
+
+=-=
+(let ((x (and y|
+=-=
+(let ((x (and y
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-no-side-effects-2
+
+=-=
+(let ((x|
+=-=
+(let ((x
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-whitespace-1
+Point-Char: |
+
+=-=
+(cl-flet((f (x)|
+=-=
+(cl-flet((f (x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-whitespace-2
+Point-Char: |
+
+=-=
+(cl-flet((f(x)|
+=-=
+(cl-flet((f(x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-whitespace-3
+
+=-=
+(cl-flet ((f(x)|
+=-=
+(cl-flet ((f(x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-whitespace-4
+
+=-=
+(cl-flet( (f (x)|
+=-=
+(cl-flet( (f (x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-whitespace-5
+
+=-=
+(cl-flet( (f(x)|
+=-=
+(cl-flet( (f(x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-and-excessive-whitespace-1
+
+=-=
+(cl-flet((f (x)|
+=-=
+(cl-flet((f (x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-and-excessive-whitespace-2
+
+=-=
+(cl-flet ((f(x)|
+=-=
+(cl-flet ((f(x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-and-excessive-whitespace-3
+
+=-=
+(cl-flet( (f (x)|
+=-=
+(cl-flet( (f (x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-and-excessive-whitespace-4
+
+=-=
+(cl-flet( (f (x)|
+=-=
+(cl-flet( (f (x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-and-excessive-whitespace-5
+
+=-=
+(cl-flet( (f (x)|
+=-=
+(cl-flet( (f (x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-and-excessive-whitespace-6
+
+=-=
+(cl-flet( (f(x)|
+=-=
+(cl-flet( (f(x)
+ |
+=-=-=
diff --git a/test/lisp/progmodes/elisp-mode-resources/simple-shorthand-test.el b/test/lisp/progmodes/elisp-mode-resources/simple-shorthand-test.el
new file mode 100644
index 00000000000..9b41fb5426c
--- /dev/null
+++ b/test/lisp/progmodes/elisp-mode-resources/simple-shorthand-test.el
@@ -0,0 +1,40 @@
+;;; simple-shorthand-test.el --- -*- lexical-binding: t; -*-
+
+(defun f-test ()
+ (let ((read-symbol-shorthands '(("foo-" . "bar-"))))
+ (with-temp-buffer
+ (insert "(foo-bar)")
+ (goto-char (point-min))
+ (read (current-buffer)))))
+
+(defun f-test2 ()
+ (let ((read-symbol-shorthands '(("foo-" . "bar-"))))
+ (read-from-string "(foo-bar)")))
+
+
+(defun f-test3 ()
+ (let ((read-symbol-shorthands '(("foo-" . "bar-"))))
+ (intern "foo-bar")))
+
+(defvar f-test-complete-me 42)
+
+(elisp--foo-test3)
+
+(defun #_f-test4--- () 84)
+
+(defmacro f-define-test-5 ())
+
+;; should be font locked with both shorthand
+;; highlighting _and_ macro highlighting.
+(f-define-test-5)
+
+(when nil
+ (f-test3)
+ (f-test2)
+ (f-test)
+ (#_f-test4---))
+
+
+;; Local Variables:
+;; read-symbol-shorthands: (("f-" . "elisp--foo-"))
+;; End:
diff --git a/test/lisp/progmodes/elisp-mode-tests.el b/test/lisp/progmodes/elisp-mode-tests.el
index f47d54e59c0..9dc5e8cadcf 100644
--- a/test/lisp/progmodes/elisp-mode-tests.el
+++ b/test/lisp/progmodes/elisp-mode-tests.el
@@ -23,8 +23,10 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'xref)
(eval-when-compile (require 'cl-lib))
+(require 'ert-x)
;;; Completion
@@ -107,7 +109,7 @@
(should (member "backup-inhibited" comps))
(should-not (member "backup-buffer" comps))))))
-(ert-deftest elisp-completes-functions-after-let-bindings ()
+(ert-deftest elisp-completes-functions-after-let-bindings-2 ()
(with-temp-buffer
(emacs-lisp-mode)
(insert "(let ((bar 1) (baz 2)) (ba")
@@ -300,12 +302,9 @@
;; tmp may be on a different filesystem to the tests, but, ehh.
(defvar xref--case-insensitive
- (let ((dir (make-temp-file "xref-test" t)))
- (unwind-protect
- (progn
- (with-temp-file (expand-file-name "hElLo" dir) "hello")
- (file-exists-p (expand-file-name "HELLO" dir)))
- (delete-directory dir t)))
+ (ert-with-temp-directory dir
+ (with-temp-file (expand-file-name "hElLo" dir) "hello")
+ (file-exists-p (expand-file-name "HELLO" dir)))
"Non-nil if file system seems to be case-insensitive.")
(defun xref-elisp-test-run (xrefs expected-xrefs)
@@ -315,27 +314,27 @@
(expected (pop expected-xrefs))
(expected-xref (or (when (consp expected) (car expected)) expected))
(expected-source (when (consp expected) (cdr expected)))
- (xref-file (xref-elisp-location-file (oref xref location)))
+ (xref-file (xref-elisp-location-file (xref-item-location xref)))
(expected-file (xref-elisp-location-file
- (oref expected-xref location))))
+ (xref-item-location expected-xref))))
;; Make sure file names compare as strings.
(when (file-name-absolute-p xref-file)
- (setf (xref-elisp-location-file (oref xref location))
- (file-truename (xref-elisp-location-file (oref xref location)))))
+ (setf (xref-elisp-location-file (xref-item-location xref))
+ (file-truename (xref-elisp-location-file (xref-item-location xref)))))
(when (file-name-absolute-p expected-file)
- (setf (xref-elisp-location-file (oref expected-xref location))
+ (setf (xref-elisp-location-file (xref-item-location expected-xref))
(file-truename (xref-elisp-location-file
- (oref expected-xref location)))))
+ (xref-item-location expected-xref)))))
;; Downcase the filenames for case-insensitive file systems.
(when xref--case-insensitive
- (setf (xref-elisp-location-file (oref xref location))
- (downcase (xref-elisp-location-file (oref xref location))))
+ (setf (xref-elisp-location-file (xref-item-location xref))
+ (downcase (xref-elisp-location-file (xref-item-location xref))))
- (setf (xref-elisp-location-file (oref expected-xref location))
+ (setf (xref-elisp-location-file (xref-item-location expected-xref))
(downcase (xref-elisp-location-file
- (oref expected-xref location)))))
+ (xref-item-location expected-xref)))))
(should (equal xref expected-xref))
@@ -416,8 +415,6 @@ to (xref-elisp-test-descr-to-target xref)."
;; FIXME: defconst
-;; FIXME: eieio defclass
-
;; Possible ways of defining the default method implementation for a
;; generic function. We declare these here, so we know we cover all
;; cases, and we don't rely on other code not changing.
@@ -429,7 +426,7 @@ to (xref-elisp-test-descr-to-target xref)."
slot-1)
(cl-defgeneric xref-elisp-generic-no-methods (arg1 arg2)
- "doc string generic no-methods"
+ "Doc string generic no-methods."
;; No default implementation, no methods, but fboundp is true for
;; this symbol; it calls cl-no-applicable-method
)
@@ -440,45 +437,50 @@ to (xref-elisp-test-descr-to-target xref)."
;; ‘this’. It passes in interactive tests, so I haven't been able to
;; track down the problem.
(cl-defmethod xref-elisp-generic-no-default ((this xref-elisp-root-type) arg2)
- "doc string generic no-default xref-elisp-root-type"
- "non-default for no-default")
+ "Doc string generic no-default xref-elisp-root-type."
+ "non-default for no-default"
+ (list this arg2)) ; silence byte-compiler
;; defgeneric after defmethod in file to ensure the fallback search
;; method of just looking for the function name will fail.
(cl-defgeneric xref-elisp-generic-no-default (arg1 arg2)
- "doc string generic no-default generic"
+ "Doc string generic no-default generic."
;; No default implementation; this function calls the cl-generic
;; dispatching code.
)
(cl-defgeneric xref-elisp-generic-co-located-default (arg1 arg2)
- "doc string generic co-located-default"
+ "Doc string generic co-located-default."
"co-located default")
(cl-defmethod xref-elisp-generic-co-located-default ((this xref-elisp-root-type) arg2)
- "doc string generic co-located-default xref-elisp-root-type"
+ "Doc string generic co-located-default xref-elisp-root-type."
"non-default for co-located-default")
(cl-defgeneric xref-elisp-generic-separate-default (arg1 arg2)
- "doc string generic separate-default"
+ "Doc string generic separate-default."
;; default implementation provided separately
)
(cl-defmethod xref-elisp-generic-separate-default (arg1 arg2)
- "doc string generic separate-default default"
- "separate default")
+ "Doc string generic separate-default default."
+ "separate default"
+ (list arg1 arg2)) ; silence byte-compiler
(cl-defmethod xref-elisp-generic-separate-default ((this xref-elisp-root-type) arg2)
- "doc string generic separate-default xref-elisp-root-type"
- "non-default for separate-default")
+ "Doc string generic separate-default xref-elisp-root-type."
+ "non-default for separate-default"
+ (list this arg2)) ; silence byte-compiler
(cl-defmethod xref-elisp-generic-implicit-generic (arg1 arg2)
- "doc string generic implicit-generic default"
- "default for implicit generic")
+ "Doc string generic implicit-generic default."
+ "default for implicit generic"
+ (list arg1 arg2)) ; silence byte-compiler
(cl-defmethod xref-elisp-generic-implicit-generic ((this xref-elisp-root-type) arg2)
- "doc string generic implicit-generic xref-elisp-root-type"
- "non-default for implicit generic")
+ "Doc string generic implicit-generic xref-elisp-root-type."
+ "non-default for implicit generic"
+ (list this arg2)) ; silence byte-compiler
(xref-elisp-deftest find-defs-defgeneric-no-methods
@@ -604,10 +606,16 @@ to (xref-elisp-test-descr-to-target xref)."
'xref-location-marker nil '(xref-etags-location))
'cl-defmethod
(expand-file-name "../../../lisp/progmodes/etags.el" emacs-test-dir)))
+ (xref-make "(cl-defmethod xref-location-marker ((l xref-etags-apropos-location)))"
+ (xref-make-elisp-location
+ (cl--generic-load-hist-format
+ 'xref-location-marker nil '(xref-etags-apropos-location))
+ 'cl-defmethod
+ (expand-file-name "../../../lisp/progmodes/etags.el" emacs-test-dir)))
))
(xref-elisp-deftest find-defs-defgeneric-eval
- (elisp--xref-find-definitions (eval '(cl-defgeneric stephe-leake-cl-defgeneric ())))
+ (elisp--xref-find-definitions (eval '(cl-defgeneric stephe-leake-cl-defgeneric ()) t))
nil)
;; Define some mode-local overloadable/overridden functions for xref to find
@@ -617,35 +625,35 @@ to (xref-elisp-test-descr-to-target xref)."
(declare-function xref-elisp-overloadable-no-default-default "elisp-mode-tests")
(define-overloadable-function xref-elisp-overloadable-no-methods ()
- "doc string overloadable no-methods")
+ "Doc string overloadable no-methods.")
(define-overloadable-function xref-elisp-overloadable-no-default ()
- "doc string overloadable no-default")
+ "Doc string overloadable no-default.")
(define-mode-local-override xref-elisp-overloadable-no-default c-mode
(_start _end &optional _nonterminal _depth _returnonerror)
- "doc string overloadable no-default c-mode."
+ "Doc string overloadable no-default c-mode."
"result overloadable no-default c-mode.")
(define-overloadable-function xref-elisp-overloadable-co-located-default ()
- "doc string overloadable co-located-default"
+ "Doc string overloadable co-located-default."
"result overloadable co-located-default.")
(define-mode-local-override xref-elisp-overloadable-co-located-default c-mode
(_start _end &optional _nonterminal _depth _returnonerror)
- "doc string overloadable co-located-default c-mode."
+ "Doc string overloadable co-located-default c-mode."
"result overloadable co-located-default c-mode.")
(define-overloadable-function xref-elisp-overloadable-separate-default ()
- "doc string overloadable separate-default.")
+ "Doc string overloadable separate-default.")
(defun xref-elisp-overloadable-separate-default-default ()
- "doc string overloadable separate-default default"
+ "Doc string overloadable separate-default default."
"result overloadable separate-default.")
(define-mode-local-override xref-elisp-overloadable-separate-default c-mode
(_start _end &optional _nonterminal _depth _returnonerror)
- "doc string overloadable separate-default c-mode."
+ "Doc string overloadable separate-default c-mode."
"result overloadable separate-default c-mode.")
(xref-elisp-deftest find-defs-define-overload-no-methods
@@ -709,7 +717,7 @@ to (xref-elisp-test-descr-to-target xref)."
(expand-file-name "../../../lisp/progmodes/xref.el" emacs-test-dir)))))
(xref-elisp-deftest find-defs-defun-eval
- (elisp--xref-find-definitions (eval '(defun stephe-leake-defun ())))
+ (elisp--xref-find-definitions (eval '(defun stephe-leake-defun ()) t))
nil)
(xref-elisp-deftest find-defs-defun-c
@@ -746,15 +754,11 @@ to (xref-elisp-test-descr-to-target xref)."
;; Source for both variable and defun is "(define-minor-mode
;; compilation-minor-mode". There is no way to tell that directly from
;; the symbol, but we can use (memq sym minor-mode-list) to detect
-;; that the symbol is a minor mode. See `elisp--xref-find-definitions'
-;; for more comments.
-;;
-;; IMPROVEME: return defvar instead of defun if source near starting
-;; point indicates the user is searching for a variable, not a
-;; function.
+;; that the symbol is a minor mode. In non-filtering mode we only
+;; return the function.
(require 'compile) ;; not loaded by default at test time
(xref-elisp-deftest find-defs-defun-defvar-el
- (elisp--xref-find-definitions 'compilation-minor-mode)
+ (xref-backend-definitions 'elisp "compilation-minor-mode")
(list
(cons
(xref-make "(defun compilation-minor-mode)"
@@ -764,12 +768,27 @@ to (xref-elisp-test-descr-to-target xref)."
"(define-minor-mode compilation-minor-mode")
))
+;; Returning only defvar because source near point indicates the user
+;; is searching for a variable, not a function.
+(xref-elisp-deftest find-defs-minor-defvar-c
+ (with-temp-buffer
+ (emacs-lisp-mode)
+ (insert "(foo overwrite-mode")
+ (xref-backend-definitions 'elisp
+ (xref-backend-identifier-at-point 'elisp)))
+ (list
+ (cons
+ (xref-make "(defvar overwrite-mode)"
+ (xref-make-elisp-location 'overwrite-mode 'defvar "src/buffer.c"))
+ "DEFVAR_PER_BUFFER (\"overwrite-mode\"")
+ ))
+
(xref-elisp-deftest find-defs-defvar-el
- (elisp--xref-find-definitions 'xref--marker-ring)
+ (elisp--xref-find-definitions 'xref--history)
(list
- (xref-make "(defvar xref--marker-ring)"
+ (xref-make "(defvar xref--history)"
(xref-make-elisp-location
- 'xref--marker-ring 'defvar
+ 'xref--history 'defvar
(expand-file-name "../../../lisp/progmodes/xref.el" emacs-test-dir)))
))
@@ -783,7 +802,7 @@ to (xref-elisp-test-descr-to-target xref)."
"DEFVAR_PER_BUFFER (\"default-directory\"")))
(xref-elisp-deftest find-defs-defvar-eval
- (elisp--xref-find-definitions (eval '(defvar stephe-leake-defvar nil)))
+ (elisp--xref-find-definitions (eval '(defvar stephe-leake-defvar nil) t))
nil)
(xref-elisp-deftest find-defs-face-el
@@ -801,7 +820,7 @@ to (xref-elisp-test-descr-to-target xref)."
))
(xref-elisp-deftest find-defs-face-eval
- (elisp--xref-find-definitions (eval '(defface stephe-leake-defface nil "")))
+ (elisp--xref-find-definitions (eval '(defface stephe-leake-defface nil "") t))
nil)
(xref-elisp-deftest find-defs-feature-el
@@ -816,7 +835,7 @@ to (xref-elisp-test-descr-to-target xref)."
))
(xref-elisp-deftest find-defs-feature-eval
- (elisp--xref-find-definitions (eval '(provide 'stephe-leake-feature)))
+ (elisp--xref-find-definitions (eval '(provide 'stephe-leake-feature) t))
nil)
(ert-deftest elisp--preceding-sexp--char-name ()
@@ -825,25 +844,14 @@ to (xref-elisp-test-descr-to-target xref)."
(insert "?\\N{HEAVY CHECK MARK}")
(should (equal (elisp--preceding-sexp) ?\N{HEAVY CHECK MARK}))))
-(ert-deftest elisp-indent-basic ()
- (with-temp-buffer
- (emacs-lisp-mode)
- (let ((orig "(defun x ()
- (print (quote ( thingy great
- stuff)))
- (print (quote (thingy great
- stuff))))"))
- (insert orig)
- (indent-region (point-min) (point-max))
- (should (equal (buffer-string) orig)))))
-
(defun test--font (form search)
(with-temp-buffer
(emacs-lisp-mode)
(if (stringp form)
(insert form)
(pp form (current-buffer)))
- (font-lock-debug-fontify)
+ (with-suppressed-warnings ((interactive-only font-lock-debug-fontify))
+ (font-lock-debug-fontify))
(goto-char (point-min))
(and (re-search-forward search nil t)
(get-text-property (match-beginning 1) 'face))))
@@ -893,5 +901,218 @@ to (xref-elisp-test-descr-to-target xref)."
"(\\(when\\)")
nil)))
+(defmacro elisp-mode-test--with-buffer (text-with-pos &rest body)
+ "Eval BODY with buffer and variables from TEXT-WITH-POS.
+All occurrences of {NAME} are removed from TEXT-WITH-POS and
+the remaining text put in a buffer in `elisp-mode'.
+Each NAME is then bound to its position in the text during the
+evaluation of BODY."
+ (declare (indent 1))
+ (let* ((annot-text (eval text-with-pos t))
+ (pieces nil)
+ (positions nil)
+ (tlen (length annot-text))
+ (ofs 0)
+ (text-ofs 0))
+ (while
+ (and (< ofs tlen)
+ (let ((m (string-match (rx "{" (group (+ (not "}"))) "}")
+ annot-text ofs)))
+ (and m
+ (let ((var (intern (match-string 1 annot-text))))
+ (push (substring annot-text ofs m) pieces)
+ (setq text-ofs (+ text-ofs (- m ofs)))
+ (push (list var (1+ text-ofs)) positions)
+ (setq ofs (match-end 0))
+ t)))))
+ (push (substring annot-text ofs tlen) pieces)
+ (let ((text (apply #'concat (nreverse pieces)))
+ (bindings (nreverse positions)))
+ `(with-temp-buffer
+ (ert-info (,text :prefix "text: ")
+ (emacs-lisp-mode)
+ (insert ,text)
+ (let ,bindings . ,body))))))
+
+(ert-deftest elisp-mode-with-buffer ()
+ ;; Sanity test of macro, also demonstrating how it works.
+ (elisp-mode-test--with-buffer
+ "{a}123{b}45{c}6"
+ (should (equal a 1))
+ (should (equal b 4))
+ (should (equal c 6))
+ (should (equal (buffer-string) "123456"))))
+
+(ert-deftest elisp-mode-infer-namespace ()
+ (elisp-mode-test--with-buffer
+ (concat " ({p1}alphaX {p2}beta {p3}gamma '{p4}delta\n"
+ " #'{p5}epsilon `{p6}zeta `(,{p7}eta ,@{p8}theta))\n")
+ (should (equal (elisp--xref-infer-namespace p1) 'function))
+ (should (equal (elisp--xref-infer-namespace p2) 'maybe-variable))
+ (should (equal (elisp--xref-infer-namespace p3) 'maybe-variable))
+ (should (equal (elisp--xref-infer-namespace p4) 'any))
+ (should (equal (elisp--xref-infer-namespace p5) 'function))
+ (should (equal (elisp--xref-infer-namespace p6) 'any))
+ (should (equal (elisp--xref-infer-namespace p7) 'variable))
+ (should (equal (elisp--xref-infer-namespace p8) 'variable)))
+
+ (elisp-mode-test--with-buffer
+ (concat "(let ({p1}alpha {p2}beta ({p3}gamma {p4}delta))\n"
+ " ({p5}epsilon {p6}zeta)\n"
+ " {p7}eta)\n")
+ (should (equal (elisp--xref-infer-namespace p1) 'variable))
+ (should (equal (elisp--xref-infer-namespace p2) 'variable))
+ (should (equal (elisp--xref-infer-namespace p3) 'variable))
+ (should (equal (elisp--xref-infer-namespace p4) 'variable))
+ (should (equal (elisp--xref-infer-namespace p5) 'function))
+ (should (equal (elisp--xref-infer-namespace p6) 'maybe-variable))
+ (should (equal (elisp--xref-infer-namespace p7) 'variable)))
+
+ (elisp-mode-test--with-buffer
+ (concat "(let (({p1}alpha {p2}beta)\n"
+ " ({p3}gamma ({p4}delta {p5}epsilon)))\n"
+ " ({p6}zeta))\n")
+ (should (equal (elisp--xref-infer-namespace p1) 'variable))
+ (should (equal (elisp--xref-infer-namespace p2) 'variable))
+ (should (equal (elisp--xref-infer-namespace p3) 'variable))
+ (should (equal (elisp--xref-infer-namespace p4) 'function))
+ (should (equal (elisp--xref-infer-namespace p5) 'maybe-variable))
+ (should (equal (elisp--xref-infer-namespace p6) 'function)))
+
+ (elisp-mode-test--with-buffer
+ (concat "(defun {p1}alpha () {p2}beta)\n"
+ "(defface {p3}gamma ...)\n"
+ "(defvar {p4}delta {p5}epsilon)\n"
+ "(function {p6}zeta)\n")
+ (should (equal (elisp--xref-infer-namespace p1) 'function))
+ (should (equal (elisp--xref-infer-namespace p2) 'variable))
+ (should (equal (elisp--xref-infer-namespace p3) 'face))
+ (should (equal (elisp--xref-infer-namespace p4) 'variable))
+ (should (equal (elisp--xref-infer-namespace p5) 'variable))
+ (should (equal (elisp--xref-infer-namespace p6) 'function)))
+
+ (elisp-mode-test--with-buffer
+ (concat "(require '{p1}alpha)\n"
+ "(fboundp '{p2}beta)\n"
+ "(boundp '{p3}gamma)\n"
+ "(facep '{p4}delta)\n"
+ "(define-key map [f1] '{p5}epsilon)\n")
+ (should (equal (elisp--xref-infer-namespace p1) 'feature))
+ (should (equal (elisp--xref-infer-namespace p2) 'function))
+ (should (equal (elisp--xref-infer-namespace p3) 'variable))
+ (should (equal (elisp--xref-infer-namespace p4) 'face))
+ (should (equal (elisp--xref-infer-namespace p5) 'function)))
+
+ (elisp-mode-test--with-buffer
+ (concat "(list {p1}alpha {p2}beta)\n"
+ "(progn {p3}gamma {p4}delta)\n"
+ "(lambda ({p5}epsilon {p6}zeta) {p7}eta)\n")
+ (should (equal (elisp--xref-infer-namespace p1) 'variable))
+ (should (equal (elisp--xref-infer-namespace p2) 'variable))
+ (should (equal (elisp--xref-infer-namespace p3) 'variable))
+ (should (equal (elisp--xref-infer-namespace p4) 'variable))
+ (should (equal (elisp--xref-infer-namespace p5) 'variable))
+ (should (equal (elisp--xref-infer-namespace p6) 'variable))
+ (should (equal (elisp--xref-infer-namespace p7) 'variable)))
+
+ (elisp-mode-test--with-buffer
+ (concat "'({p1}alpha {p2}beta\n"
+ " ({p3}gamma ({p4}delta)))\n")
+ (should (equal (elisp--xref-infer-namespace p1) 'any))
+ (should (equal (elisp--xref-infer-namespace p2) 'any))
+ (should (equal (elisp--xref-infer-namespace p3) 'any))
+ (should (equal (elisp--xref-infer-namespace p4) 'any))))
+
+
+(ert-deftest elisp-shorthand-read-buffer ()
+ (let* ((gsym (downcase (symbol-name (cl-gensym "sh-"))))
+ (shorthand-sname (format "s-%s" gsym))
+ (expected (intern (format "shorthand-longhand-%s" gsym))))
+ (cl-assert (not (intern-soft shorthand-sname)))
+ (should (equal (let ((read-symbol-shorthands
+ '(("s-" . "shorthand-longhand-"))))
+ (with-temp-buffer
+ (insert shorthand-sname)
+ (goto-char (point-min))
+ (read (current-buffer))))
+ expected))
+ (should (not (intern-soft shorthand-sname)))))
+
+(ert-deftest elisp-shorthand-read-from-string ()
+ (let* ((gsym (downcase (symbol-name (cl-gensym "sh-"))))
+ (shorthand-sname (format "s-%s" gsym))
+ (expected (intern (format "shorthand-longhand-%s" gsym))))
+ (cl-assert (not (intern-soft shorthand-sname)))
+ (should (equal (let ((read-symbol-shorthands
+ '(("s-" . "shorthand-longhand-"))))
+ (car (read-from-string shorthand-sname)))
+ expected))
+ (should (not (intern-soft shorthand-sname)))))
+
+(ert-deftest elisp-shorthand-load-a-file ()
+ (let ((test-file (ert-resource-file "simple-shorthand-test.el")))
+ (mapatoms (lambda (s)
+ (when (string-match "^elisp--foo-" (symbol-name s))
+ (unintern s obarray))))
+ (load test-file)
+ (should (intern-soft "elisp--foo-test"))
+ (should-not (intern-soft "f-test"))))
+
+(ert-deftest elisp-shorthand-byte-compile-a-file ()
+
+ (let ((test-file (ert-resource-file "simple-shorthand-test.el"))
+ (byte-compiled (ert-resource-file "simple-shorthand-test.elc")))
+ (mapatoms (lambda (s)
+ (when (string-match "^elisp--foo-" (symbol-name s))
+ (unintern s obarray))))
+ (byte-compile-file test-file)
+ (should-not (intern-soft "f-test"))
+ (should (intern-soft "elisp--foo-test"))
+ (should-not (fboundp (intern-soft "elisp--foo-test")))
+ (load byte-compiled)
+ (should (intern-soft "elisp--foo-test"))
+ (should-not (intern-soft "f-test"))))
+
+(ert-deftest elisp-shorthand-completion-at-point ()
+ (let ((test-file (ert-resource-file "simple-shorthand-test.el")))
+ (load test-file)
+ (with-current-buffer (find-file-noselect test-file)
+ (revert-buffer t t)
+ (goto-char (point-min))
+ (insert "f-test-compl")
+ (completion-at-point)
+ (goto-char (point-min))
+ (should (search-forward "f-test-complete-me" (line-end-position) t))
+ (goto-char (point-min))
+ (should (string= (symbol-name (read (current-buffer)))
+ "elisp--foo-test-complete-me"))
+ (revert-buffer t t))))
+
+(ert-deftest elisp-shorthand-escape ()
+ (let ((test-file (ert-resource-file "simple-shorthand-test.el")))
+ (load test-file)
+ (should (intern-soft "f-test4---"))
+ (should-not (intern-soft "elisp--foo-test4---"))
+ (should (= 84 (funcall (intern-soft "f-test4---"))))
+ (should (unintern "f-test4---"))))
+
+(ert-deftest elisp-dont-shadow-punctuation-only-symbols ()
+ (let* ((shorthanded-form '(/= 42 (-foo 42)))
+ (expected-longhand-form '(/= 42 (fooey-foo 42)))
+ (observed (let ((read-symbol-shorthands
+ '(("-" . "fooey-"))))
+ (car (read-from-string
+ (with-temp-buffer
+ (print shorthanded-form (current-buffer))
+ (buffer-string)))))))
+ (should (equal observed expected-longhand-form))))
+
+(ert-deftest test-indentation ()
+ (ert-test-erts-file (ert-resource-file "elisp-indents.erts"))
+ (ert-test-erts-file (ert-resource-file "flet.erts")
+ (lambda ()
+ (emacs-lisp-mode)
+ (indent-region (point-min) (point-max)))))
+
(provide 'elisp-mode-tests)
;;; elisp-mode-tests.el ends here
diff --git a/test/lisp/progmodes/etags-tests.el b/test/lisp/progmodes/etags-tests.el
index 35a2592e76f..32b73f101e1 100644
--- a/test/lisp/progmodes/etags-tests.el
+++ b/test/lisp/progmodes/etags-tests.el
@@ -22,6 +22,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'etags)
(eval-when-compile (require 'cl-lib))
@@ -95,19 +96,19 @@
(ert-deftest etags-buffer-local-tags-table-list ()
"Test that a buffer-local value of `tags-table-list' is used."
- (let ((file (make-temp-file "etag-test-tmpfile")))
- (unwind-protect
- (progn
- (set-buffer (find-file-noselect file))
- (fundamental-mode)
- (setq-local tags-table-list
- (list (expand-file-name "manual/etags/ETAGS.good_3"
- etags-tests--test-dir)))
- (cl-letf ((tag-tables tags-table-list)
- (tags-file-name nil)
- ((symbol-function 'read-file-name)
- (lambda (&rest _)
- (error "We should not prompt the user"))))
- (should (visit-tags-table-buffer))
- (should (equal tags-file-name (car tag-tables)))))
- (delete-file file))))
+ (ert-with-temp-file file
+ :suffix "etag-test-tmpfile"
+ (set-buffer (find-file-noselect file))
+ (fundamental-mode)
+ (setq-local tags-table-list
+ (list (expand-file-name "manual/etags/ETAGS.good_3"
+ etags-tests--test-dir)))
+ (cl-letf ((tag-tables tags-table-list)
+ (tags-file-name nil)
+ ((symbol-function 'read-file-name)
+ (lambda (&rest _)
+ (error "We should not prompt the user"))))
+ (should (visit-tags-table-buffer))
+ (should (equal tags-file-name (car tag-tables))))))
+
+;;; etags-tests.el ends here
diff --git a/test/lisp/progmodes/flymake-resources/another-problematic-file.c b/test/lisp/progmodes/flymake-resources/another-problematic-file.c
new file mode 100644
index 00000000000..03eacdd8011
--- /dev/null
+++ b/test/lisp/progmodes/flymake-resources/another-problematic-file.c
@@ -0,0 +1,5 @@
+#include "some-problems.h"
+
+int frob(char* freb) {
+ return 42;
+}
diff --git a/test/lisp/progmodes/flymake-resources/some-problems.h b/test/lisp/progmodes/flymake-resources/some-problems.h
index 165d8dd525e..86ea2de3b0d 100644
--- a/test/lisp/progmodes/flymake-resources/some-problems.h
+++ b/test/lisp/progmodes/flymake-resources/some-problems.h
@@ -2,4 +2,6 @@
strange;
+int frob(char);
+
sint main();
diff --git a/test/lisp/progmodes/flymake-tests.el b/test/lisp/progmodes/flymake-tests.el
index bda1b663c22..4840018236a 100644
--- a/test/lisp/progmodes/flymake-tests.el
+++ b/test/lisp/progmodes/flymake-tests.el
@@ -23,6 +23,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'flymake)
(eval-when-compile (require 'subr-x)) ; string-trim
@@ -60,7 +61,7 @@
(cl-defun flymake-tests--call-with-fixture (fn file
&key (severity-predicate
nil sev-pred-supplied-p))
- "Call FN after flymake setup in FILE, using `flymake-proc`.
+ "Call FN after flymake setup in FILE, using `flymake-proc'.
SEVERITY-PREDICATE is used to setup
`flymake-proc-diagnostic-type-pred'"
(let* ((file (expand-file-name file flymake-tests-data-directory))
@@ -109,7 +110,7 @@ SEVERITY-PREDICATE is used to setup
(face-at-point)))))
(ert-deftest perl-backend ()
- "Test the perl backend"
+ "Test the perl backend."
(skip-unless (executable-find "perl"))
(flymake-tests--with-flymake ("test.pl")
(flymake-goto-next-error)
@@ -120,25 +121,24 @@ SEVERITY-PREDICATE is used to setup
(defvar ruby-mode-hook)
(ert-deftest ruby-backend ()
- "Test the ruby backend"
+ "Test the ruby backend."
(skip-unless (executable-find "ruby"))
;; Some versions of ruby fail if HOME doesn't exist (bug#29187).
- (let* ((tempdir (make-temp-file "flymake-tests-ruby" t))
- (process-environment (cons (format "HOME=%s" tempdir)
- process-environment))
- ;; And see https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19657#20
- ;; for this particular yuckiness
- (abbreviated-home-dir nil))
- (unwind-protect
- (let ((ruby-mode-hook
- (lambda ()
- (setq flymake-diagnostic-functions '(ruby-flymake-simple)))))
- (flymake-tests--with-flymake ("test.rb")
- (flymake-goto-next-error)
- (should (eq 'flymake-warning (face-at-point)))
- (flymake-goto-next-error)
- (should (eq 'flymake-error (face-at-point)))))
- (delete-directory tempdir t))))
+ (ert-with-temp-directory tempdir
+ :suffix "flymake-tests-ruby"
+ (let* ((process-environment (cons (format "HOME=%s" tempdir)
+ process-environment))
+ ;; And see https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19657#20
+ ;; for this particular yuckiness
+ (abbreviated-home-dir nil)
+ (ruby-mode-hook
+ (lambda ()
+ (setq flymake-diagnostic-functions '(ruby-flymake-simple)))))
+ (flymake-tests--with-flymake ("test.rb")
+ (flymake-goto-next-error)
+ (should (eq 'flymake-warning (face-at-point)))
+ (flymake-goto-next-error)
+ (should (eq 'flymake-error (face-at-point)))))))
(ert-deftest different-diagnostic-types ()
"Test GCC warning via function predicate."
@@ -193,7 +193,7 @@ SEVERITY-PREDICATE is used to setup
(defun flymake-tests--diagnose-words
(report-fn type words)
- "Helper. Call REPORT-FN with diagnostics for WORDS in buffer."
+ "Helper. Call REPORT-FN with diagnostics for WORDS in buffer."
(funcall report-fn
(cl-loop
for word in words
@@ -234,7 +234,7 @@ SEVERITY-PREDICATE is used to setup
(lambda (_report-fn)
;; HACK: Shoosh log during tests
(setq-local warning-minimum-log-level :emergency)
- (error "crashed"))))
+ (error "Crashed"))))
(insert "Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt ut labore et dolore
manha aliqua. Ut enim ad minim veniam, quis nostrud
@@ -291,7 +291,7 @@ SEVERITY-PREDICATE is used to setup
(should-error (flymake-goto-next-error nil nil t))))))
(ert-deftest recurrent-backend ()
- "Test a backend that calls REPORT-FN multiple times"
+ "Test a backend that calls REPORT-FN multiple times."
(with-temp-buffer
(let (tick)
(cl-letf
@@ -374,4 +374,4 @@ SEVERITY-PREDICATE is used to setup
(provide 'flymake-tests)
-;;; flymake.el ends here
+;;; flymake-tests.el ends here
diff --git a/test/lisp/progmodes/gdb-mi-tests.el b/test/lisp/progmodes/gdb-mi-tests.el
index ab482214afb..d66df961b63 100644
--- a/test/lisp/progmodes/gdb-mi-tests.el
+++ b/test/lisp/progmodes/gdb-mi-tests.el
@@ -17,6 +17,8 @@
;; 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 'gdb-mi)
@@ -44,3 +46,5 @@
)
(provide 'gdb-mi-tests)
+
+;;; gdb-mi-tests.el ends here
diff --git a/test/lisp/progmodes/opascal-tests.el b/test/lisp/progmodes/opascal-tests.el
index 682f2c6cb6b..ea91479362d 100644
--- a/test/lisp/progmodes/opascal-tests.el
+++ b/test/lisp/progmodes/opascal-tests.el
@@ -17,6 +17,8 @@
;; 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 'opascal)
diff --git a/test/lisp/progmodes/pascal-tests.el b/test/lisp/progmodes/pascal-tests.el
index e9c705806b3..f5202143e20 100644
--- a/test/lisp/progmodes/pascal-tests.el
+++ b/test/lisp/progmodes/pascal-tests.el
@@ -17,6 +17,8 @@
;; 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 'pascal)
@@ -61,3 +63,5 @@
(should (equal (point) 15))))
(provide 'pascal-tests)
+
+;;; pascal-tests.el ends here
diff --git a/test/lisp/progmodes/perl-mode-tests.el b/test/lisp/progmodes/perl-mode-tests.el
index 3f4af5e1f61..b059f539159 100644
--- a/test/lisp/progmodes/perl-mode-tests.el
+++ b/test/lisp/progmodes/perl-mode-tests.el
@@ -37,4 +37,6 @@
(file-name-directory (or load-file-name
buffer-file-name)))))
+(setq ert-load-file-name load-file-name)
+
;;; perl-mode-tests.el ends here
diff --git a/test/lisp/progmodes/project-tests.el b/test/lisp/progmodes/project-tests.el
index 68460a9fa5b..a469414a743 100644
--- a/test/lisp/progmodes/project-tests.el
+++ b/test/lisp/progmodes/project-tests.el
@@ -29,29 +29,17 @@
(require 'cl-lib)
(require 'ert)
+(require 'ert-x) ; ert-with-temp-directory
(require 'grep)
(require 'xref)
-(defmacro project-tests--with-temporary-directory (var &rest body)
- "Create a new temporary directory.
-Bind VAR to the name of the directory, and evaluate BODY. Delete
-the directory after BODY exits."
- (declare (debug (symbolp body)) (indent 1))
- (cl-check-type var symbol)
- (let ((directory (make-symbol "directory")))
- `(let ((,directory (make-temp-file "project-tests-" :directory)))
- (unwind-protect
- (let ((,var ,directory))
- ,@body)
- (delete-directory ,directory :recursive)))))
-
(ert-deftest project/quoted-directory ()
"Check that `project-files' and `project-find-regexp' deal with
quoted directory names (Bug#47799)."
(skip-unless (executable-find find-program))
(skip-unless (executable-find "xargs"))
(skip-unless (executable-find "grep"))
- (project-tests--with-temporary-directory directory
+ (ert-with-temp-directory directory
(let ((default-directory directory)
(project-current-inhibit-prompt t)
(project-find-functions nil)
@@ -95,7 +83,7 @@ quoted directory names (Bug#47799)."
returned by `project-ignores' if the root directory is a
directory name (Bug#48471)."
(skip-unless (executable-find find-program))
- (project-tests--with-temporary-directory dir
+ (ert-with-temp-directory dir
(make-empty-file (expand-file-name "some-file" dir))
(make-empty-file (expand-file-name "ignored-file" dir))
(let* ((project (make-project-tests--trivial
@@ -107,4 +95,19 @@ directory name (Bug#48471)."
collect (file-relative-name file dir))))
(should (equal relative-files '("some-file"))))))
+(ert-deftest project-ignores-bug-50240 ()
+ "Check that `project-files' does not ignore all files.
+When `project-ignores' includes a name matching project dir."
+ (skip-unless (executable-find find-program))
+ (ert-with-temp-directory dir
+ (make-empty-file (expand-file-name "some-file" dir))
+ (let* ((project (make-project-tests--trivial
+ :root (file-name-as-directory dir)
+ :ignores (list (file-name-nondirectory
+ (directory-file-name dir)))))
+ (files (project-files project)))
+ (should (equal files
+ (list
+ (expand-file-name "some-file" dir)))))))
+
;;; project-tests.el ends here
diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el
index 1af579bb7a4..2d1ccdca41d 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -22,6 +22,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'python)
;; Dependencies for testing:
@@ -48,17 +49,17 @@ BODY is code to be executed within the temp buffer. Point is
always located at the beginning of buffer."
(declare (indent 1) (debug t))
;; temp-file never actually used for anything?
- `(let* ((temp-file (make-temp-file "python-tests" nil ".py"))
- (buffer (find-file-noselect temp-file))
- (python-indent-guess-indent-offset nil))
- (unwind-protect
- (with-current-buffer buffer
- (python-mode)
- (insert ,contents)
- (goto-char (point-min))
- ,@body)
- (and buffer (kill-buffer buffer))
- (delete-file temp-file))))
+ `(ert-with-temp-file temp-file
+ :suffix "-python.py"
+ (let ((buffer (find-file-noselect temp-file))
+ (python-indent-guess-indent-offset nil))
+ (unwind-protect
+ (with-current-buffer buffer
+ (python-mode)
+ (insert ,contents)
+ (goto-char (point-min))
+ ,@body)
+ (and buffer (kill-buffer buffer))))))
(defun python-tests-look-at (string &optional num restore-point)
"Move point at beginning of STRING in the current buffer.
@@ -193,7 +194,6 @@ aliqua."
(ert-deftest python-syntax-after-python-backspace ()
;; `python-indent-dedent-line-backspace' garbles syntax
- :expected-result :failed
(python-tests-with-temp-buffer
"\"\"\""
(goto-char (point-max))
@@ -5283,7 +5283,7 @@ urlpatterns = patterns('',
(should (= (current-indentation) 23))))
(or eim (electric-indent-mode -1)))))
-(ert-deftest python-triple-quote-pairing ()
+(ert-deftest python-triple-double-quote-pairing ()
(let ((epm electric-pair-mode))
(unwind-protect
(progn
@@ -5310,6 +5310,33 @@ urlpatterns = patterns('',
"\"\n\"\"\"\n"))))
(or epm (electric-pair-mode -1)))))
+(ert-deftest python-triple-single-quote-pairing ()
+ (let ((epm electric-pair-mode))
+ (unwind-protect
+ (progn
+ (python-tests-with-temp-buffer
+ "''\n"
+ (or epm (electric-pair-mode 1))
+ (goto-char (1- (point-max)))
+ (python-tests-self-insert ?')
+ (should (string= (buffer-string)
+ "''''''\n"))
+ (should (= (point) 4)))
+ (python-tests-with-temp-buffer
+ "\n"
+ (python-tests-self-insert (list ?' ?' ?'))
+ (should (string= (buffer-string)
+ "''''''\n"))
+ (should (= (point) 4)))
+ (python-tests-with-temp-buffer
+ "'\n''\n"
+ (goto-char (1- (point-max)))
+ (python-tests-self-insert ?')
+ (should (= (point) (1- (point-max))))
+ (should (string= (buffer-string)
+ "'\n'''\n"))))
+ (or epm (electric-pair-mode -1)))))
+
;;; Hideshow support
@@ -5422,15 +5449,21 @@ buffer with overlapping strings."
(python-nav-end-of-statement)))
(should (eolp))))
-;; After call `run-python' the buffer running the python process is current.
-(ert-deftest python-tests--bug31398 ()
- "Test for https://debbugs.gnu.org/31398 ."
+;; Interactively, `run-python' focuses the buffer running the
+;; interpreter.
+(ert-deftest python-tests--run-python-selects-window ()
+ "Test for bug#31398. See also bug#44421 and bug#52380."
(skip-unless (executable-find python-tests-shell-interpreter))
- (let ((buffer (process-buffer (run-python nil nil 'show))))
- (should (eq buffer (current-buffer)))
+ (let* ((buffer (process-buffer (run-python nil nil 'show)))
+ (window (get-buffer-window buffer)))
+ ;; We look at `selected-window' rather than `current-buffer'
+ ;; because as `(elisp)Current buffer' says, the latter will only
+ ;; be synchronized with the former when returning to the "command
+ ;; loop"; until then, `current-buffer' can change arbitrarily.
+ (should (eq window (selected-window)))
(pop-to-buffer (other-buffer))
(run-python nil nil 'show)
- (should (eq buffer (current-buffer)))))
+ (should (eq window (selected-window)))))
(ert-deftest python-tests--fill-long-first-line ()
(should
diff --git a/test/lisp/progmodes/ruby-mode-tests.el b/test/lisp/progmodes/ruby-mode-tests.el
index 8bdfdc310f3..2168b38484e 100644
--- a/test/lisp/progmodes/ruby-mode-tests.el
+++ b/test/lisp/progmodes/ruby-mode-tests.el
@@ -357,7 +357,7 @@ VALUES-PLIST is a list with alternating index and value elements."
(let ((ruby-align-chained-calls t))
(ruby-should-indent-buffer
"one.two.three
- | .four
+ | .four
|
|my_array.select { |str| str.size > 5 }
| .map { |str| str.downcase }"
@@ -908,6 +908,33 @@ VALUES-PLIST is a list with alternating index and value elements."
(should (equal (buffer-string) orig))))
(kill-buffer buf))))
+(ert-deftest ruby--test-chained-indentation ()
+ (with-temp-buffer
+ (ruby-mode)
+ (setq-local ruby-align-chained-calls t)
+ (insert "some_variable.where
+.not(x: nil)
+.where(y: 2)
+")
+ (indent-region (point-min) (point-max))
+ (should (equal (buffer-string)
+ "some_variable.where
+ .not(x: nil)
+ .where(y: 2)
+")))
+
+ (with-temp-buffer
+ (ruby-mode)
+ (setq-local ruby-align-chained-calls t)
+ (insert "some_variable.where.not(x: nil)
+.where(y: 2)
+")
+ (indent-region (point-min) (point-max))
+ (should (equal (buffer-string)
+ "some_variable.where.not(x: nil)
+ .where(y: 2)
+"))))
+
(provide 'ruby-mode-tests)
;;; ruby-mode-tests.el ends here
diff --git a/test/lisp/progmodes/sh-script-tests.el b/test/lisp/progmodes/sh-script-tests.el
new file mode 100644
index 00000000000..c21010c8b43
--- /dev/null
+++ b/test/lisp/progmodes/sh-script-tests.el
@@ -0,0 +1,51 @@
+;;; sh-script-tests.el --- Tests for sh-script.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 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 'sh-script)
+(require 'ert)
+
+(ert-deftest test-sh-script-indentation ()
+ (with-temp-buffer
+ (insert "relative-path/to/configure --prefix=$prefix\\
+ --with-x")
+ (shell-script-mode)
+ (goto-char (point-min))
+ (forward-line 1)
+ (indent-for-tab-command)
+ (should (equal
+ (buffer-substring-no-properties (point-min) (point-max))
+ "relative-path/to/configure --prefix=$prefix\\
+ --with-x"))))
+
+(ert-deftest test-basic-sh-indentation ()
+ (with-temp-buffer
+ (insert "myecho () {\necho foo\n}\n")
+ (shell-script-mode)
+ (indent-region (point-min) (point-max))
+ (should (equal (buffer-string)
+ "myecho () {
+ echo foo
+}
+"))))
+
+;;; sh-script-tests.el ends here
diff --git a/test/lisp/progmodes/sql-tests.el b/test/lisp/progmodes/sql-tests.el
index 21dd0649529..1bbe3a95e90 100644
--- a/test/lisp/progmodes/sql-tests.el
+++ b/test/lisp/progmodes/sql-tests.el
@@ -28,6 +28,7 @@
(require 'cl-lib)
(require 'ert)
+(require 'ert-x)
(require 'sql)
(ert-deftest sql-tests-postgres-list-databases ()
@@ -50,7 +51,7 @@
(lambda (_command) t))
((symbol-function 'process-lines)
(lambda (_program &rest _args)
- (error "some error"))))
+ (error "Some error"))))
(should-not (sql-postgres-list-databases))))
;;; Check Connection Password Handling/Wallet
@@ -63,52 +64,49 @@ Identify tests by ID. Set :sql-login dialect attribute to
LOGIN-PARAMS. Provide the CONNECTION parameters and the EXPECTED
string of values passed to the comint function for validation."
(declare (indent 2))
- `(cl-letf
- ((sql-test-login-params ' ,login-params)
- ((symbol-function 'sql-comint-test)
- (lambda (product options &optional buf-name)
- (with-current-buffer (get-buffer-create buf-name)
- (insert (pp-to-string (list product options sql-user sql-password sql-server sql-database))))))
- ((symbol-function 'sql-run-test)
- (lambda (&optional buffer)
- (interactive "P")
- (sql-product-interactive 'sqltest buffer)))
- (sql-user nil)
- (sql-server nil)
- (sql-database nil)
- (sql-product-alist
- '((ansi)
- (sqltest
- :name "SqlTest"
- :sqli-login sql-test-login-params
- :sqli-comint-func sql-comint-test)))
- (sql-connection-alist
- '((,(format "test-%s" id)
- ,@connection)))
- (sql-password-wallet
- (list
- (make-temp-file
- "sql-test-netrc" nil nil
- (mapconcat #'identity
- '("machine aMachine user aUserName password \"netrc-A aPassword\""
- "machine aServer user aUserName password \"netrc-B aPassword\""
- "machine aMachine server aServer user aUserName password \"netrc-C aPassword\""
- "machine aMachine database aDatabase user aUserName password \"netrc-D aPassword\""
- "machine aDatabase user aUserName password \"netrc-E aPassword\""
- "machine aMachine server aServer database aDatabase user aUserName password \"netrc-F aPassword\""
- "machine \"aServer/aDatabase\" user aUserName password \"netrc-G aPassword\""
- ) "\n")))))
-
- (let* ((connection ,(format "test-%s" id))
- (buffername (format "*SQL: ERT TEST <%s>*" connection)))
- (when (get-buffer buffername)
- (kill-buffer buffername))
- (sql-connect connection buffername)
- (should (get-buffer buffername))
- (should (string-equal (with-current-buffer buffername (buffer-string)) ,expected))
- (when (get-buffer buffername)
- (kill-buffer buffername))
- (delete-file (car sql-password-wallet)))))
+ `(ert-with-temp-file tempfile
+ :suffix "sql-test-netrc"
+ :text (concat
+ "machine aMachine user aUserName password \"netrc-A aPassword\""
+ "machine aServer user aUserName password \"netrc-B aPassword\""
+ "machine aMachine server aServer user aUserName password \"netrc-C aPassword\""
+ "machine aMachine database aDatabase user aUserName password \"netrc-D aPassword\""
+ "machine aDatabase user aUserName password \"netrc-E aPassword\""
+ "machine aMachine server aServer database aDatabase user aUserName password \"netrc-F aPassword\""
+ "machine \"aServer/aDatabase\" user aUserName password \"netrc-G aPassword\""
+ "\n")
+ (cl-letf
+ ((sql-test-login-params ' ,login-params)
+ ((symbol-function 'sql-comint-test)
+ (lambda (product options &optional buf-name)
+ (with-current-buffer (get-buffer-create buf-name)
+ (insert (pp-to-string (list product options sql-user sql-password sql-server sql-database))))))
+ ((symbol-function 'sql-run-test)
+ (lambda (&optional buffer)
+ (interactive "P")
+ (sql-product-interactive 'sqltest buffer)))
+ (sql-user nil)
+ (sql-server nil)
+ (sql-database nil)
+ (sql-product-alist
+ '((ansi)
+ (sqltest
+ :name "SqlTest"
+ :sqli-login sql-test-login-params
+ :sqli-comint-func sql-comint-test)))
+ (sql-connection-alist
+ '((,(format "test-%s" id)
+ ,@connection)))
+ (sql-password-wallet (list tempfile)))
+ (let* ((connection ,(format "test-%s" id))
+ (buffername (format "*SQL: ERT TEST <%s>*" connection)))
+ (when (get-buffer buffername)
+ (kill-buffer buffername))
+ (sql-connect connection buffername)
+ (should (get-buffer buffername))
+ (should (string-equal (with-current-buffer buffername (buffer-string)) ,expected))
+ (when (get-buffer buffername)
+ (kill-buffer buffername))))))
(ert-deftest sql-test-connect ()
"Test of basic `sql-connect'."
@@ -416,6 +414,16 @@ The ACTION will be tested after set-up of PRODUCT."
(kill-buffer "*SQL: exist*")))
+(ert-deftest sql-tests-comint-automatic-password ()
+ (let ((sql-password nil))
+ (should-not (sql-comint-automatic-password "Password: ")))
+ (let ((sql-password ""))
+ (should-not (sql-comint-automatic-password "Password: ")))
+ (let ((sql-password "password"))
+ (should (equal "password" (sql-comint-automatic-password "Password: "))))
+ ;; Also, we shouldn't care what the password is - we rely on comint for that.
+ (let ((sql-password "password"))
+ (should (equal "password" (sql-comint-automatic-password "")))))
(provide 'sql-tests)
;;; sql-tests.el ends here
diff --git a/test/lisp/progmodes/xref-tests.el b/test/lisp/progmodes/xref-tests.el
index d29452243b2..b1de1a4df5a 100644
--- a/test/lisp/progmodes/xref-tests.el
+++ b/test/lisp/progmodes/xref-tests.el
@@ -52,6 +52,14 @@
(should (string-match-p "file1\\.txt\\'" (xref-location-group (nth 0 locs))))
(should (string-match-p "file2\\.txt\\'" (xref-location-group (nth 1 locs))))))
+(ert-deftest xref-matches-in-directory-filters-with-ignores ()
+ (let ((locs (xref-matches-in-directory "bar" "*" xref-tests--data-dir
+ '("./file1.*"))))
+ (should (= 1 (length locs)))
+ (should (string-match-p "file2\\.txt\\'" (xref-location-group
+ (xref-item-location
+ (nth 0 locs)))))))
+
(ert-deftest xref-matches-in-directory-finds-two-matches-on-the-same-line ()
(let ((locs (xref-tests--locations-in-data-dir "foo")))
(should (= 2 (length locs)))
@@ -120,8 +128,12 @@
(let ((xref-file-name-display 'abs))
(should (equal
(delete-dups
- (mapcar 'xref-location-group
- (xref-tests--locations-in-data-dir "\\(bar\\|foo\\)")))
+ (mapcar
+ (lambda (loc)
+ (xref--group-name-for-display
+ (xref-location-group loc)
+ nil))
+ (xref-tests--locations-in-data-dir "\\(bar\\|foo\\)")))
(list
(concat xref-tests--data-dir "file1.txt")
(concat xref-tests--data-dir "file2.txt"))))))
@@ -129,8 +141,12 @@
(ert-deftest xref--xref-file-name-display-is-nondirectory ()
(let ((xref-file-name-display 'nondirectory))
(should (equal (delete-dups
- (mapcar 'xref-location-group
- (xref-tests--locations-in-data-dir "\\(bar\\|foo\\)")))
+ (mapcar
+ (lambda (loc)
+ (xref--group-name-for-display
+ (xref-location-group loc)
+ nil))
+ (xref-tests--locations-in-data-dir "\\(bar\\|foo\\)")))
(list
"file1.txt"
"file2.txt")))))
@@ -138,13 +154,15 @@
(ert-deftest xref--xref-file-name-display-is-relative-to-project-root ()
(let* ((data-parent-dir
(file-name-directory (directory-file-name xref-tests--data-dir)))
- (project-find-functions
- (lambda (_) (cons 'transient data-parent-dir)))
(xref-file-name-display 'project-relative))
(should (equal
(delete-dups
- (mapcar 'xref-location-group
- (xref-tests--locations-in-data-dir "\\(bar\\|foo\\)")))
+ (mapcar
+ (lambda (loc)
+ (xref--group-name-for-display
+ (xref-location-group loc)
+ data-parent-dir))
+ (xref-tests--locations-in-data-dir "\\(bar\\|foo\\)")))
(list
"xref-resources/file1.txt"
"xref-resources/file2.txt")))))
diff --git a/test/lisp/ps-print-tests.el b/test/lisp/ps-print-tests.el
index b25e88622d8..d468911dd3d 100644
--- a/test/lisp/ps-print-tests.el
+++ b/test/lisp/ps-print-tests.el
@@ -34,3 +34,5 @@
(autoloadp
(symbol-function
'ps-mule-initialize))))
+
+;;; ps-print-tests.el ends here
diff --git a/test/lisp/repeat-tests.el b/test/lisp/repeat-tests.el
new file mode 100644
index 00000000000..02d9ddbc96e
--- /dev/null
+++ b/test/lisp/repeat-tests.el
@@ -0,0 +1,145 @@
+;;; repeat-tests.el --- Tests for repeat.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Juri Linkov <juri@linkov.net>
+
+;; 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 'repeat)
+
+(defvar repeat-tests-calls nil)
+
+(defun repeat-tests-call-a (&optional arg)
+ (interactive "p")
+ (push `(,arg a) repeat-tests-calls))
+
+(defun repeat-tests-call-b (&optional arg)
+ (interactive "p")
+ (push `(,arg b) repeat-tests-calls))
+
+(defvar repeat-tests-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-x w a") 'repeat-tests-call-a)
+ (define-key map (kbd "M-C-a") 'repeat-tests-call-a)
+ (define-key map (kbd "M-C-z") 'repeat-tests-call-a)
+ map)
+ "Keymap for keys that initiate repeating sequences.")
+
+(defvar repeat-tests-repeat-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "a" 'repeat-tests-call-a)
+ (define-key map "b" 'repeat-tests-call-b)
+ map)
+ "Keymap for repeating sequences.")
+(put 'repeat-tests-call-a 'repeat-map 'repeat-tests-repeat-map)
+(put 'repeat-tests-call-b 'repeat-map repeat-tests-repeat-map)
+
+(defmacro with-repeat-mode (&rest body)
+ "Create environment for testing `repeat-mode'."
+ `(unwind-protect
+ (progn
+ (repeat-mode +1)
+ (with-temp-buffer
+ (save-window-excursion
+ ;; `execute-kbd-macro' applied to window only
+ (set-window-buffer nil (current-buffer))
+ (use-local-map repeat-tests-map)
+ ,@body)))
+ (repeat-mode -1)))
+
+(defun repeat-tests--check (keys calls inserted)
+ (setq repeat-tests-calls nil)
+ (delete-region (point-min) (point-max))
+ (execute-kbd-macro (kbd keys))
+ (should (equal (nreverse repeat-tests-calls) calls))
+ ;; Check for self-inserting keys
+ (should (equal (buffer-string) inserted)))
+
+(ert-deftest repeat-tests-check-key ()
+ (with-repeat-mode
+ (let ((repeat-echo-function 'ignore))
+ (let ((repeat-check-key t))
+ (repeat-tests--check
+ "C-x w a b a c"
+ '((1 a) (1 b) (1 a)) "c")
+ (repeat-tests--check
+ "M-C-a b a c"
+ '((1 a) (1 b) (1 a)) "c")
+ (repeat-tests--check
+ "M-C-z b a c"
+ '((1 a)) "bac")
+ (unwind-protect
+ (progn
+ (put 'repeat-tests-call-a 'repeat-check-key 'no)
+ (repeat-tests--check
+ "M-C-z b a c"
+ '((1 a) (1 b) (1 a)) "c"))
+ (put 'repeat-tests-call-a 'repeat-check-key nil)))
+ (let ((repeat-check-key nil))
+ (repeat-tests--check
+ "M-C-z b a c"
+ '((1 a) (1 b) (1 a)) "c")
+ (unwind-protect
+ (progn
+ (put 'repeat-tests-call-a 'repeat-check-key t)
+ (repeat-tests--check
+ "M-C-z b a c"
+ '((1 a)) "bac"))
+ (put 'repeat-tests-call-a 'repeat-check-key nil))))))
+
+(ert-deftest repeat-tests-exit-key ()
+ (with-repeat-mode
+ (let ((repeat-echo-function 'ignore))
+ (let ((repeat-exit-key nil))
+ (repeat-tests--check
+ "C-x w a b a b RET c"
+ '((1 a) (1 b) (1 a) (1 b)) "\nc"))
+ (let ((repeat-exit-key [return]))
+ (repeat-tests--check
+ "C-x w a b a b <return> c"
+ '((1 a) (1 b) (1 a) (1 b)) "c")))))
+
+(ert-deftest repeat-tests-keep-prefix ()
+ (with-repeat-mode
+ (let ((repeat-echo-function 'ignore))
+ (repeat-tests--check
+ "C-x w a b a b c"
+ '((1 a) (1 b) (1 a) (1 b)) "c")
+ (let ((repeat-keep-prefix nil))
+ (repeat-tests--check
+ "C-2 C-x w a b a b c"
+ '((2 a) (1 b) (1 a) (1 b)) "c")
+ (repeat-tests--check
+ "C-2 C-x w a C-3 c"
+ '((2 a)) "ccc"))
+ ;; TODO: fix and uncomment
+ ;; (let ((repeat-keep-prefix t))
+ ;; (repeat-tests--check
+ ;; "C-2 C-x w a b a b c"
+ ;; '((2 a) (2 b) (2 a) (2 b)) "c")
+ ;; (repeat-tests--check
+ ;; "C-2 C-x w a C-1 C-2 b a C-3 C-4 b c"
+ ;; '((2 a) (12 b) (12 a) (34 b)) "c"))
+ )))
+
+;; TODO: :tags '(:expensive-test) for repeat-exit-timeout
+
+(provide 'repeat-tests)
+;;; repeat-tests.el ends here
diff --git a/test/lisp/replace-tests.el b/test/lisp/replace-tests.el
index 7f62a417a02..dcd5ebb1fe6 100644
--- a/test/lisp/replace-tests.el
+++ b/test/lisp/replace-tests.el
@@ -599,11 +599,12 @@ bound to HIGHLIGHT-LOCUS."
(with-temp-buffer
(insert before)
(goto-char (point-min))
- (replace-regexp
- "\\(\\(L\\)\\|\\(R\\)\\)"
- '(replace-eval-replacement
- replace-quote
- (if (match-string 2) "R" "L")))
+ (with-suppressed-warnings ((interactive-only replace-regexp))
+ (replace-regexp
+ "\\(\\(L\\)\\|\\(R\\)\\)"
+ '(replace-eval-replacement
+ replace-quote
+ (if (match-string 2) "R" "L"))))
(should (equal (buffer-string) after)))))
(ert-deftest test-count-matches ()
diff --git a/test/lisp/saveplace-tests.el b/test/lisp/saveplace-tests.el
index 17199ed443a..190ffb78288 100644
--- a/test/lisp/saveplace-tests.el
+++ b/test/lisp/saveplace-tests.el
@@ -21,6 +21,8 @@
;;; Commentary:
+;;; Code:
+
(require 'ert)
(require 'ert-x)
(require 'saveplace)
@@ -39,49 +41,42 @@
(ert-deftest saveplace-test-save-place-to-alist/file ()
(save-place-mode)
- (let* ((tmpfile (make-temp-file "emacs-test-saveplace-"))
- (tmpfile (file-truename tmpfile))
- (save-place-alist nil)
- (save-place-loaded t)
- (loc tmpfile)
- (pos 4))
- (unwind-protect
- (save-window-excursion
- (find-file loc)
- (insert "abc") ; must insert something
- (save-place-to-alist)
- (should (equal save-place-alist (list (cons tmpfile pos)))))
- (delete-file tmpfile))))
+ (ert-with-temp-file tmpfile
+ (let* ((tmpfile (file-truename tmpfile))
+ (save-place-alist nil)
+ (save-place-loaded t)
+ (loc tmpfile)
+ (pos 4))
+ (save-window-excursion
+ (find-file loc)
+ (insert "abc") ; must insert something
+ (save-place-to-alist)
+ (should (equal save-place-alist (list (cons tmpfile pos))))))))
(ert-deftest saveplace-test-forget-unreadable-files ()
(save-place-mode)
- (let* ((save-place-loaded t)
- (tmpfile (make-temp-file "emacs-test-saveplace-"))
- (alist-orig (list (cons "/this/file/does/not/exist" 10)
- (cons tmpfile 1917)))
- (save-place-alist alist-orig))
- (unwind-protect
- (progn
- (save-place-forget-unreadable-files)
- (should (equal save-place-alist (cdr alist-orig))))
- (delete-file tmpfile))))
+ (ert-with-temp-file tmpfile
+ :suffix "-saveplace"
+ (let* ((save-place-loaded t)
+ (alist-orig (list (cons "/this/file/does/not/exist" 10)
+ (cons tmpfile 1917)))
+ (save-place-alist alist-orig))
+ (save-place-forget-unreadable-files)
+ (should (equal save-place-alist (cdr alist-orig))))))
(ert-deftest saveplace-test-place-alist-to-file ()
(save-place-mode)
- (let* ((tmpfile (make-temp-file "emacs-test-saveplace-"))
- (tmpfile2 (make-temp-file "emacs-test-saveplace-"))
- (save-place-file tmpfile)
- (save-place-alist (list (cons tmpfile2 99))))
- (unwind-protect
- (progn (save-place-alist-to-file)
- (setq save-place-alist nil)
- (save-window-excursion
- (find-file save-place-file)
- (unwind-protect
- (should (string-match tmpfile2 (buffer-string)))
- (kill-buffer))))
- (delete-file tmpfile)
- (delete-file tmpfile2))))
+ (ert-with-temp-file tmpfile
+ (ert-with-temp-file tmpfile2
+ (let* ((save-place-file tmpfile)
+ (save-place-alist (list (cons tmpfile2 99))))
+ (save-place-alist-to-file)
+ (setq save-place-alist nil)
+ (save-window-excursion
+ (find-file save-place-file)
+ (unwind-protect
+ (should (string-match tmpfile2 (buffer-string)))
+ (kill-buffer)))))))
(ert-deftest saveplace-test-load-alist-from-file ()
(save-place-mode)
diff --git a/test/lisp/ses-tests.el b/test/lisp/ses-tests.el
index 04f255dcd4c..932291afcc1 100644
--- a/test/lisp/ses-tests.el
+++ b/test/lisp/ses-tests.el
@@ -24,6 +24,10 @@
(require 'ert)
(require 'ses)
+;; Silence byte-compiler.
+(with-suppressed-warnings ((lexical A2) (lexical A3))
+ (defvar A2)
+ (defvar A3))
;; PLAIN FORMULA TESTS
;; ======================================================================
@@ -175,3 +179,5 @@ to `ses--bar' and inserting a row, makes A2 value empty, and `ses--bar' equal to
(provide 'ses-tests)
+
+;;; ses-tests.el ends here
diff --git a/test/lisp/shadowfile-tests.el b/test/lisp/shadowfile-tests.el
index c571dc3e14b..1ab539f3e42 100644
--- a/test/lisp/shadowfile-tests.el
+++ b/test/lisp/shadowfile-tests.el
@@ -664,7 +664,29 @@ guaranteed by the originator of a cluster definition."
(should (member (format "/%s:%s" cluster2 (file-local-name file2))
(car shadow-literal-groups)))
;; Bug#49596.
- (should (member (concat primary file1) (car shadow-literal-groups))))
+ (should (member (concat primary file1) (car shadow-literal-groups)))
+
+ ;; Error handling.
+ (setq shadow-literal-groups nil)
+ ;; There's no `buffer-file-name'.
+ (with-temp-buffer
+ (call-interactively #'shadow-define-literal-group)
+ (set-buffer-modified-p nil))
+ (should-not shadow-literal-groups)
+ ;; Define an empty literal group.
+ (setq mocked-input `(,(kbd "RET")))
+ (with-temp-buffer
+ (set-visited-file-name file1)
+ (call-interactively #'shadow-define-literal-group)
+ (set-buffer-modified-p nil))
+ (should-not shadow-literal-groups)
+ ;; Use a non-existing site name.
+ (setq mocked-input `("foo" ,(kbd "RET")))
+ (with-temp-buffer
+ (set-visited-file-name file1)
+ (call-interactively #'shadow-define-literal-group)
+ (set-buffer-modified-p nil))
+ (should-not shadow-literal-groups))
;; Cleanup.
(shadow--tests-cleanup))))
diff --git a/test/lisp/shell-tests.el b/test/lisp/shell-tests.el
index 223a18590b1..342b421911f 100644
--- a/test/lisp/shell-tests.el
+++ b/test/lisp/shell-tests.el
@@ -1,4 +1,4 @@
-;;; shell-tests.el -*- lexical-binding:t -*-
+;;; shell-tests.el --- Tests for shell.el -*- lexical-binding:t -*-
;; Copyright (C) 2010-2021 Free Software Foundation, Inc.
diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el
index 3ece61290bc..742da0bde59 100644
--- a/test/lisp/simple-tests.el
+++ b/test/lisp/simple-tests.el
@@ -972,4 +972,4 @@ See Bug#21722."
(should (= (length (delq nil (undo-make-selective-list 6 9))) 0))))
(provide 'simple-test)
-;;; simple-test.el ends here
+;;; simple-tests.el ends here
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 dd2331e6e4a..f542806ac16 100644
--- a/test/lisp/so-long-tests/so-long-tests-helpers.el
+++ b/test/lisp/so-long-tests/so-long-tests-helpers.el
@@ -106,8 +106,8 @@
(defun so-long-tests-remember ()
"Remember the original states of modes and variables.
-Call this after setting up a buffer in the normal (not so-long)
-state for its major mode, so that after triggering a so-long
+Call this after setting up a buffer in the normal (not `so-long')
+state for its major mode, so that after triggering a `so-long'
action we can call `so-long-revert' and compare the reverted
state against this remembered state."
(setq so-long-tests-memory nil)
diff --git a/test/lisp/so-long-tests/so-long-tests.el b/test/lisp/so-long-tests/so-long-tests.el
index 8e4597c946c..cda5ae497fd 100644
--- a/test/lisp/so-long-tests/so-long-tests.el
+++ b/test/lisp/so-long-tests/so-long-tests.el
@@ -32,7 +32,7 @@
;; Running manually:
;;
;; for test in lisp/so-long-tests/*-tests.el; do make ${test%.el}; done \
-;; 2>&1 | egrep -v '^(Loading|Source file|make|Changed to so-long-mode)'
+;; 2>&1 | grep -E -v '^(Loading|Source file|make|Changed to so-long-mode)'
;;
;; Which is equivalent to:
;;
@@ -41,7 +41,7 @@
;; "../src/emacs" --no-init-file --no-site-file --no-site-lisp \
;; -L ":." -l ert -l "$test" --batch --eval \
;; '(ert-run-tests-batch-and-exit (quote (not (tag :unstable))))'; \
-;; done 2>&1 | egrep -v '^(Loading|Source file|Changed to so-long-mode)'
+;; done 2>&1 | grep -E -v '^(Loading|Source file|Changed to so-long-mode)'
;;
;; See also `ert-run-tests-batch-and-exit'.
@@ -229,7 +229,7 @@
((obsolete run-window-configuration-change-hook))
(run-window-configuration-change-hook)))))
(so-long-tests-assert-and-revert 'so-long-mode))
- ;; `so-long-invisible-buffer-function' is `nil'.
+ ;; `so-long-invisible-buffer-function' is nil.
(with-temp-buffer
(insert "#!emacs\n")
(normal-mode)
diff --git a/test/lisp/so-long-tests/spelling-tests.el b/test/lisp/so-long-tests/spelling-tests.el
index f778b646635..b598366ba7a 100644
--- a/test/lisp/so-long-tests/spelling-tests.el
+++ b/test/lisp/so-long-tests/spelling-tests.el
@@ -23,6 +23,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'ispell)
(require 'cl-lib)
@@ -50,20 +51,19 @@
;; The Emacs test Makefile's use of HOME=/nonexistent triggers an error
;; when starting the inferior ispell process, so we set HOME to a valid
;; (but empty) temporary directory for this test.
- (let* ((tmpdir (make-temp-file "so-long." :dir ".ispell"))
- (process-environment (cons (format "HOME=%s" tmpdir)
- process-environment))
- (find-spelling-mistake
- (unwind-protect
- (cl-letf (((symbol-function 'ispell-command-loop)
- (lambda (_miss _guess word _start _end)
- (message "Unrecognised word: %s." word)
- (throw 'mistake t))))
- (catch 'mistake
- (find-library "so-long")
- (ispell-buffer)
- nil))
- (delete-directory tmpdir))))
- (should (not find-spelling-mistake)))))
+ (ert-with-temp-file tmpdir
+ :suffix "so-long.ispell"
+ (let* ((process-environment (cons (format "HOME=%s" tmpdir)
+ process-environment))
+ (find-spelling-mistake
+ (cl-letf (((symbol-function 'ispell-command-loop)
+ (lambda (_miss _guess word _start _end)
+ (message "Unrecognised word: %s." word)
+ (throw 'mistake t))))
+ (catch 'mistake
+ (find-library "so-long")
+ (ispell-buffer)
+ nil))))
+ (should (not find-spelling-mistake))))))
;;; spelling-tests.el ends here
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el
index 21b8a27858e..063c6fe6a7b 100644
--- a/test/lisp/subr-tests.el
+++ b/test/lisp/subr-tests.el
@@ -62,19 +62,259 @@
(0 font-lock-keyword-face))))))))
+;;;; List functions.
+
+(ert-deftest subr-test-caaar ()
+ (should (null (caaar '())))
+ (should (null (caaar '(() (2)))))
+ (should (null (caaar '((() (2)) (a b)))))
+ (should-error (caaar '(1 2)) :type 'wrong-type-argument)
+ (should-error (caaar '((1 2))) :type 'wrong-type-argument)
+ (should (= 1 (caaar '(((1 2) (3 4))))))
+ (should (null (caaar '((() (3 4)))))))
+
+(ert-deftest subr-test-caadr ()
+ (should (null (caadr '())))
+ (should (null (caadr '(1))))
+ (should-error (caadr '(1 2)) :type 'wrong-type-argument)
+ (should (= 2 (caadr '(1 (2 3)))))
+ (should (equal '((2) (3)) (caadr '((1) (((2) (3))) (4))))))
+
+
;;;; Keymap support.
(ert-deftest subr-test-kbd ()
+ (should (equal (kbd "") ""))
(should (equal (kbd "f") "f"))
+ (should (equal (kbd "X") "X"))
+ (should (equal (kbd "foobar") "foobar")) ; 6 characters
+ (should (equal (kbd "return") "return")) ; 6 characters
+
+ (should (equal (kbd "<F2>") [F2]))
+ (should (equal (kbd "<f1> <f2> TAB") [f1 f2 ?\t]))
+ (should (equal (kbd "<f1> RET") [f1 ?\r]))
+ (should (equal (kbd "<f1> SPC") [f1 ? ]))
(should (equal (kbd "<f1>") [f1]))
- (should (equal (kbd "RET") "\C-m"))
+ (should (equal (kbd "<f1>") [f1]))
+ (should (equal (kbd "[f1]") "[f1]"))
+ (should (equal (kbd "<return>") [return]))
+ (should (equal (kbd "< right >") "<right>")) ; 7 characters
+
+ ;; Modifiers:
+ (should (equal (kbd "C-x") "\C-x"))
(should (equal (kbd "C-x a") "\C-xa"))
- ;; Check that kbd handles both new and old style key descriptions
- ;; (bug#45536).
+ (should (equal (kbd "C-;") [?\C-\;]))
+ (should (equal (kbd "C-a") "\C-a"))
+ (should (equal (kbd "C-c SPC") "\C-c "))
+ (should (equal (kbd "C-c TAB") "\C-c\t"))
+ (should (equal (kbd "C-c c") "\C-cc"))
+ (should (equal (kbd "C-x 4 C-f") "\C-x4\C-f"))
+ (should (equal (kbd "C-x C-f") "\C-x\C-f"))
+ (should (equal (kbd "C-M-<down>") [C-M-down]))
+ (should (equal (kbd "<C-M-down>") [C-M-down]))
+ (should (equal (kbd "C-RET") [?\C-\C-m]))
+ (should (equal (kbd "C-SPC") [?\C- ]))
+ (should (equal (kbd "C-TAB") [?\C-\t]))
+ (should (equal (kbd "C-<down>") [C-down]))
+ (should (equal (kbd "C-c C-c C-c") "\C-c\C-c\C-c"))
+
+ (should (equal (kbd "M-a") [?\M-a]))
+ (should (equal (kbd "M-<DEL>") [?\M-\d]))
+ (should (equal (kbd "M-C-a") [?\M-\C-a]))
+ (should (equal (kbd "M-ESC") [?\M-\e]))
+ (should (equal (kbd "M-RET") [?\M-\r]))
+ (should (equal (kbd "M-SPC") [?\M- ]))
+ (should (equal (kbd "M-TAB") [?\M-\t]))
+ (should (equal (kbd "M-x a") [?\M-x ?a]))
+ (should (equal (kbd "M-<up>") [M-up]))
+ (should (equal (kbd "M-c M-c M-c") [?\M-c ?\M-c ?\M-c]))
+
+ (should (equal (kbd "s-SPC") [?\s- ]))
+ (should (equal (kbd "s-a") [?\s-a]))
+ (should (equal (kbd "s-x a") [?\s-x ?a]))
+ (should (equal (kbd "s-c s-c s-c") [?\s-c ?\s-c ?\s-c]))
+
+ (should (equal (kbd "S-H-a") [?\S-\H-a]))
+ (should (equal (kbd "S-a") [?\S-a]))
+ (should (equal (kbd "S-x a") [?\S-x ?a]))
+ (should (equal (kbd "S-c S-c S-c") [?\S-c ?\S-c ?\S-c]))
+
+ (should (equal (kbd "H-<RET>") [?\H-\r]))
+ (should (equal (kbd "H-DEL") [?\H-\d]))
+ (should (equal (kbd "H-a") [?\H-a]))
+ (should (equal (kbd "H-x a") [?\H-x ?a]))
+ (should (equal (kbd "H-c H-c H-c") [?\H-c ?\H-c ?\H-c]))
+
+ (should (equal (kbd "A-H-a") [?\A-\H-a]))
+ (should (equal (kbd "A-SPC") [?\A- ]))
+ (should (equal (kbd "A-TAB") [?\A-\t]))
+ (should (equal (kbd "A-a") [?\A-a]))
+ (should (equal (kbd "A-c A-c A-c") [?\A-c ?\A-c ?\A-c]))
+
+ (should (equal (kbd "C-M-a") [?\C-\M-a]))
+ (should (equal (kbd "C-M-<up>") [C-M-up]))
+
+ ;; Special characters.
+ (should (equal (kbd "DEL") "\d"))
+ (should (equal (kbd "ESC C-a") "\e\C-a"))
+ (should (equal (kbd "ESC") "\e"))
+ (should (equal (kbd "LFD") "\n"))
+ (should (equal (kbd "NUL") "\0"))
+ (should (equal (kbd "RET") "\C-m"))
+ (should (equal (kbd "SPC") "\s"))
+ (should (equal (kbd "TAB") "\t"))
+ (should (equal (kbd "\^i") ""))
+ (should (equal (kbd "^M") "\^M"))
+
+ ;; With numbers.
+ (should (equal (kbd "\177") "\^?"))
+ (should (equal (kbd "\000") "\0"))
+ (should (equal (kbd "\\177") "\^?"))
+ (should (equal (kbd "\\000") "\0"))
+ (should (equal (kbd "C-x \\150") "\C-xh"))
+
+ ;; Multibyte
+ (should (equal (kbd "ñ") [?ñ]))
+ (should (equal (kbd "ü") [?ü]))
+ (should (equal (kbd "ö") [?ö]))
+ (should (equal (kbd "ğ") [?ğ]))
+ (should (equal (kbd "ա") [?ա]))
+ (should (equal (kbd "üüöö") [?ü ?ü ?ö ?ö]))
+ (should (equal (kbd "C-ü") [?\C-ü]))
+ (should (equal (kbd "M-ü") [?\M-ü]))
+ (should (equal (kbd "H-ü") [?\H-ü]))
+
+ ;; Handle both new and old style key descriptions (bug#45536).
(should (equal (kbd "s-<return>") [s-return]))
(should (equal (kbd "<s-return>") [s-return]))
(should (equal (kbd "C-M-<return>") [C-M-return]))
- (should (equal (kbd "<C-M-return>") [C-M-return])))
+ (should (equal (kbd "<C-M-return>") [C-M-return]))
+
+ ;; Error.
+ (should-error (kbd "C-xx"))
+ (should-error (kbd "M-xx"))
+ (should-error (kbd "M-x<TAB>"))
+
+ ;; These should be equivalent:
+ (should (equal (kbd "\C-xf") (kbd "C-x f"))))
+
+(ert-deftest subr-test-key-valid-p ()
+ (should (not (key-valid-p "")))
+ (should (key-valid-p "f"))
+ (should (key-valid-p "X"))
+ (should (not (key-valid-p " X")))
+ (should (key-valid-p "X f"))
+ (should (not (key-valid-p "a b")))
+ (should (not (key-valid-p "foobar")))
+ (should (not (key-valid-p "return")))
+
+ (should (key-valid-p "<F2>"))
+ (should (key-valid-p "<f1> <f2> TAB"))
+ (should (key-valid-p "<f1> RET"))
+ (should (key-valid-p "<f1> SPC"))
+ (should (key-valid-p "<f1>"))
+ (should (not (key-valid-p "[f1]")))
+ (should (key-valid-p "<return>"))
+ (should (not (key-valid-p "< right >")))
+
+ ;; Modifiers:
+ (should (key-valid-p "C-x"))
+ (should (key-valid-p "C-x a"))
+ (should (key-valid-p "C-;"))
+ (should (key-valid-p "C-a"))
+ (should (key-valid-p "C-c SPC"))
+ (should (key-valid-p "C-c TAB"))
+ (should (key-valid-p "C-c c"))
+ (should (key-valid-p "C-x 4 C-f"))
+ (should (key-valid-p "C-x C-f"))
+ (should (key-valid-p "C-M-<down>"))
+ (should (not (key-valid-p "<C-M-down>")))
+ (should (key-valid-p "C-RET"))
+ (should (key-valid-p "C-SPC"))
+ (should (key-valid-p "C-TAB"))
+ (should (key-valid-p "C-<down>"))
+ (should (key-valid-p "C-c C-c C-c"))
+
+ (should (key-valid-p "M-a"))
+ (should (key-valid-p "M-<DEL>"))
+ (should (not (key-valid-p "M-C-a")))
+ (should (key-valid-p "C-M-a"))
+ (should (key-valid-p "M-ESC"))
+ (should (key-valid-p "M-RET"))
+ (should (key-valid-p "M-SPC"))
+ (should (key-valid-p "M-TAB"))
+ (should (key-valid-p "M-x a"))
+ (should (key-valid-p "M-<up>"))
+ (should (key-valid-p "M-c M-c M-c"))
+
+ (should (key-valid-p "s-SPC"))
+ (should (key-valid-p "s-a"))
+ (should (key-valid-p "s-x a"))
+ (should (key-valid-p "s-c s-c s-c"))
+
+ (should (not (key-valid-p "S-H-a")))
+ (should (key-valid-p "S-a"))
+ (should (key-valid-p "S-x a"))
+ (should (key-valid-p "S-c S-c S-c"))
+
+ (should (key-valid-p "H-<RET>"))
+ (should (key-valid-p "H-DEL"))
+ (should (key-valid-p "H-a"))
+ (should (key-valid-p "H-x a"))
+ (should (key-valid-p "H-c H-c H-c"))
+
+ (should (key-valid-p "A-H-a"))
+ (should (key-valid-p "A-SPC"))
+ (should (key-valid-p "A-TAB"))
+ (should (key-valid-p "A-a"))
+ (should (key-valid-p "A-c A-c A-c"))
+
+ (should (key-valid-p "C-M-a"))
+ (should (key-valid-p "C-M-<up>"))
+
+ ;; Special characters.
+ (should (key-valid-p "DEL"))
+ (should (key-valid-p "ESC C-a"))
+ (should (key-valid-p "ESC"))
+ (should (key-valid-p "LFD"))
+ (should (key-valid-p "NUL"))
+ (should (key-valid-p "RET"))
+ (should (key-valid-p "SPC"))
+ (should (key-valid-p "TAB"))
+ (should (not (key-valid-p "\^i")))
+ (should (not (key-valid-p "^M")))
+
+ ;; With numbers.
+ (should (not (key-valid-p "\177")))
+ (should (not (key-valid-p "\000")))
+ (should (not (key-valid-p "\\177")))
+ (should (not (key-valid-p "\\000")))
+ (should (not (key-valid-p "C-x \\150")))
+
+ ;; Multibyte
+ (should (key-valid-p "ñ"))
+ (should (key-valid-p "ü"))
+ (should (key-valid-p "ö"))
+ (should (key-valid-p "ğ"))
+ (should (key-valid-p "ա"))
+ (should (not (key-valid-p "üüöö")))
+ (should (key-valid-p "C-ü"))
+ (should (key-valid-p "M-ü"))
+ (should (key-valid-p "H-ü"))
+
+ ;; Handle both new and old style key descriptions (bug#45536).
+ (should (key-valid-p "s-<return>"))
+ (should (not (key-valid-p "<s-return>")))
+ (should (key-valid-p "C-M-<return>"))
+ (should (not (key-valid-p "<C-M-return>")))
+
+ (should (key-valid-p "<mouse-1>"))
+ (should (key-valid-p "<Scroll_Lock>"))
+
+ (should (not (key-valid-p "c-x")))
+ (should (not (key-valid-p "C-xx")))
+ (should (not (key-valid-p "M-xx")))
+ (should (not (key-valid-p "M-x<TAB>"))))
(ert-deftest subr-test-define-prefix-command ()
(define-prefix-command 'foo-prefix-map)
@@ -371,12 +611,13 @@ indirectly `mapbacktrace'."
(ert-deftest subr-tests--dolist--wrong-number-of-args ()
"Test that `dolist' doesn't accept wrong types or length of SPEC,
cf. Bug#25477."
- (should-error (eval '(dolist (a)))
- :type 'wrong-number-of-arguments)
- (should-error (eval '(dolist (a () 'result 'invalid)) t)
- :type 'wrong-number-of-arguments)
- (should-error (eval '(dolist "foo") t)
- :type 'wrong-type-argument))
+ (dolist (lb '(nil t))
+ (should-error (eval '(dolist (a)) lb)
+ :type 'wrong-number-of-arguments)
+ (should-error (eval '(dolist (a () 'result 'invalid)) lb)
+ :type 'wrong-number-of-arguments)
+ (should-error (eval '(dolist "foo") lb)
+ :type 'wrong-type-argument)))
(ert-deftest subr-tests-bug22027 ()
"Test for https://debbugs.gnu.org/22027 ."
@@ -473,11 +714,11 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350."
(should (equal subr-tests--hook '(f5 f2 f1 f4 f3)))
(add-hook 'subr-tests--hook 'f6)
(should (equal subr-tests--hook '(f5 f6 f2 f1 f4 f3)))
- ;; Make sure `t' is equivalent to 90.
+ ;; Make sure t is equivalent to 90.
(add-hook 'subr-tests--hook 'f7 90)
(add-hook 'subr-tests--hook 'f8 t)
(should (equal subr-tests--hook '(f5 f6 f2 f1 f4 f3 f7 f8)))
- ;; Make sure `nil' is equivalent to 0.
+ ;; Make sure nil is equivalent to 0.
(add-hook 'subr-tests--hook 'f9 0)
(add-hook 'subr-tests--hook 'f10)
(should (equal subr-tests--hook '(f5 f10 f9 f6 f2 f1 f4 f3 f7 f8)))
@@ -685,6 +926,7 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350."
(should-not (apropos-internal "^next-line$" #'keymapp)))
+(defvar test-global-boundp)
(ert-deftest test-buffer-local-boundp ()
(let ((buf (generate-new-buffer "boundp")))
(with-current-buffer buf
@@ -740,5 +982,30 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350."
1))
(should (equal (buffer-string) "new bar zot foobar"))))
+(ert-deftest test-with-existing-directory ()
+ (let ((dir (make-temp-name "/tmp/not-exist-")))
+ (let ((default-directory dir))
+ (should-not (file-exists-p default-directory)))
+ (with-existing-directory
+ (should-not (equal dir default-directory))
+ (should (file-exists-p default-directory)))))
+
+(ert-deftest subr-test-internal--format-docstring-line ()
+ (should
+ (string= (let ((fill-column 70))
+ (internal--format-docstring-line
+ "In addition to any hooks its parent mode might have run, this \
+mode runs the hook ‘foo-bar-baz-very-long-name-indeed-mode-hook’, as the final \
+or penultimate step during initialization."))
+ "In addition to any hooks its parent mode might have run, this mode
+runs the hook ‘foo-bar-baz-very-long-name-indeed-mode-hook’, as the
+final or penultimate step during initialization."))
+ (should-error (internal--format-docstring-line "foo\nbar")))
+
+(ert-deftest test-ensure-list ()
+ (should (equal (ensure-list nil) nil))
+ (should (equal (ensure-list :foo) '(:foo)))
+ (should (equal (ensure-list '(1 2 3)) '(1 2 3))))
+
(provide 'subr-tests)
;;; subr-tests.el ends here
diff --git a/test/lisp/tab-bar-tests.el b/test/lisp/tab-bar-tests.el
new file mode 100644
index 00000000000..7212ce89167
--- /dev/null
+++ b/test/lisp/tab-bar-tests.el
@@ -0,0 +1,51 @@
+;;; tab-bar-tests.el --- Tests for tab-bar.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Juri Linkov <juri@linkov.net>
+
+;; 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)
+
+(defun tab-bar-tests-close-other-tabs (arg)
+ (tab-bar-tabs-set nil)
+ (tab-rename "1")
+ (tab-new) (tab-rename "2") ;; (tab-switch "2")
+ (tab-new) (tab-rename "3") ;; (tab-switch "3")
+ (should (eq (length (tab-bar-tabs)) 3))
+ (should (equal (alist-get 'name (tab-bar--current-tab-find)) "3"))
+ (tab-bar-close-other-tabs arg)
+ (should (equal (alist-get 'name (tab-bar--current-tab-find))
+ (if arg (number-to-string (max 1 (min arg 3))) "3")))
+ (should (eq (length (tab-bar-tabs)) 1))
+ (should (eq (length tab-bar-closed-tabs) 2))
+ (tab-undo)
+ (tab-undo)
+ (should (equal (tab-undo) "No more closed tabs to undo"))
+ (should (eq (length (tab-bar-tabs)) 3))
+ (should (eq (length tab-bar-closed-tabs) 0)))
+
+(ert-deftest tab-bar-tests-close-other-tabs-default ()
+ (tab-bar-tests-close-other-tabs nil))
+
+(ert-deftest tab-bar-tests-close-other-tabs-with-arg ()
+ (dotimes (i 5) (tab-bar-tests-close-other-tabs i)))
+
+(provide 'tab-bar-tests)
+;;; tab-bar-tests.el ends here
diff --git a/test/lisp/tar-mode-tests.el b/test/lisp/tar-mode-tests.el
index 48a127157dd..2e0d1529a57 100644
--- a/test/lisp/tar-mode-tests.el
+++ b/test/lisp/tar-mode-tests.el
@@ -32,7 +32,8 @@
(cons 1024 "-----S---")
(cons 2048 "--S------"))))
(dolist (x alist)
- (should (equal (cdr x) (tar-grind-file-mode (car x)))))))
+ (with-suppressed-warnings ((obsolete tar-grind-file-mode))
+ (should (equal (cdr x) (tar-grind-file-mode (car x))))))))
(ert-deftest tar-mode-test-tar-extract-gz ()
(skip-unless (executable-find "gzip"))
@@ -47,4 +48,4 @@
(provide 'tar-mode-tests)
-;; tar-mode-tests.el ends here
+;;; tar-mode-tests.el ends here
diff --git a/test/lisp/term-tests.el b/test/lisp/term-tests.el
index 50ac370b5b5..73d39cf3b66 100644
--- a/test/lisp/term-tests.el
+++ b/test/lisp/term-tests.el
@@ -28,6 +28,65 @@
(defvar term-height) ; Number of lines in window.
(defvar term-width) ; Number of columns in window.
+(defvar yellow-fg-props
+ `( :foreground ,(face-foreground 'term-color-yellow nil 'default)
+ :background "unspecified-bg" :inverse-video nil))
+(defvar yellow-bg-props
+ `( :foreground "unspecified-fg"
+ :background ,(face-background 'term-color-yellow nil 'default)
+ :inverse-video nil))
+(defvar bright-yellow-fg-props
+ `( :foreground ,(face-foreground 'term-color-bright-yellow nil 'default)
+ :background "unspecified-bg" :inverse-video nil))
+(defvar bright-yellow-bg-props
+ `( :foreground "unspecified-fg"
+ :background ,(face-background 'term-color-bright-yellow nil 'default)
+ :inverse-video nil))
+(defvar custom-color-fg-props
+ `( :foreground "#87FFFF"
+ :background "unspecified-bg" :inverse-video nil))
+
+(defvar ansi-test-strings
+ `(("\e[33mHello World\e[0m"
+ ,(propertize "Hello World" 'font-lock-face `(,yellow-fg-props)))
+ ("\e[43mHello World\e[0m"
+ ,(propertize "Hello World" 'font-lock-face `(,yellow-bg-props)))
+ ("\e[93mHello World\e[0m"
+ ,(propertize "Hello World" 'font-lock-face `(,bright-yellow-fg-props)))
+ ("\e[103mHello World\e[0m"
+ ,(propertize "Hello World" 'font-lock-face `(,bright-yellow-bg-props)))
+ ("\e[1;33mHello World\e[0m"
+ ,(propertize "Hello World" 'font-lock-face
+ `(,yellow-fg-props term-bold))
+ ,(propertize "Hello World" 'font-lock-face
+ `(,bright-yellow-fg-props term-bold)))
+ ("\e[33;1mHello World\e[0m"
+ ,(propertize "Hello World" 'font-lock-face
+ `(,yellow-fg-props term-bold))
+ ,(propertize "Hello World" 'font-lock-face
+ `(,bright-yellow-fg-props term-bold)))
+ ("\e[1m\e[33mHello World\e[0m"
+ ,(propertize "Hello World" 'font-lock-face
+ `(,yellow-fg-props term-bold))
+ ,(propertize "Hello World" 'font-lock-face
+ `(,bright-yellow-fg-props term-bold)))
+ ("\e[33m\e[1mHello World\e[0m"
+ ,(propertize "Hello World" 'font-lock-face
+ `(,yellow-fg-props term-bold))
+ ,(propertize "Hello World" 'font-lock-face
+ `(,bright-yellow-fg-props term-bold)))
+ ("\e[38;5;3;1mHello World\e[0m"
+ ,(propertize "Hello World" 'font-lock-face
+ `(,yellow-fg-props term-bold))
+ ,(propertize "Hello World" 'font-lock-face
+ `(,bright-yellow-fg-props term-bold)))
+ ("\e[38;5;123;1mHello World\e[0m"
+ ,(propertize "Hello World" 'font-lock-face
+ `(,custom-color-fg-props term-bold)))
+ ("\e[38;2;135;255;255;1mHello World\e[0m"
+ ,(propertize "Hello World" 'font-lock-face
+ `(,custom-color-fg-props term-bold)))))
+
(defun term-test-screen-from-input (width height input &optional return-var)
(with-temp-buffer
(term-mode)
@@ -48,7 +107,7 @@
(mapc (lambda (input) (term-emulate-terminal proc input)) input)
(term-emulate-terminal proc input))
(if return-var (buffer-local-value return-var (current-buffer))
- (buffer-substring-no-properties (point-min) (point-max))))))
+ (buffer-substring (point-min) (point-max))))))
(ert-deftest term-simple-lines ()
(skip-unless (not (memq system-type '(windows-nt ms-dos))))
@@ -77,6 +136,24 @@ first line\r_next line\r\n"))
(term-test-screen-from-input 40 12 (let ((str (make-string 30 ?a)))
(list str str))))))
+(ert-deftest term-colors ()
+ (skip-unless (not (memq system-type '(windows-nt ms-dos))))
+ (pcase-dolist (`(,str ,expected) ansi-test-strings)
+ (let ((result (term-test-screen-from-input 40 12 str)))
+ (should (equal result expected))
+ (should (equal (text-properties-at 0 result)
+ (text-properties-at 0 expected))))))
+
+(ert-deftest term-colors-bold-is-bright ()
+ (skip-unless (not (memq system-type '(windows-nt ms-dos))))
+ (let ((ansi-color-bold-is-bright t))
+ (pcase-dolist (`(,str ,expected ,bright-expected) ansi-test-strings)
+ (let ((expected (or bright-expected expected))
+ (result (term-test-screen-from-input 40 12 str)))
+ (should (equal result expected))
+ (should (equal (text-properties-at 0 result)
+ (text-properties-at 0 expected)))))))
+
(ert-deftest term-cursor-movement ()
(skip-unless (not (memq system-type '(windows-nt ms-dos))))
;; Absolute positioning.
diff --git a/test/lisp/term/tty-colors-tests.el b/test/lisp/term/tty-colors-tests.el
index ba29a9c376e..d0e739b5ec9 100644
--- a/test/lisp/term/tty-colors-tests.el
+++ b/test/lisp/term/tty-colors-tests.el
@@ -35,4 +35,4 @@
(provide 'term-tests)
-;;; term-tests.el ends here
+;;; tty-colors-tests.el ends here
diff --git a/test/lisp/textmodes/dns-mode-tests.el b/test/lisp/textmodes/dns-mode-tests.el
index 8bc48732c62..1be5291509f 100644
--- a/test/lisp/textmodes/dns-mode-tests.el
+++ b/test/lisp/textmodes/dns-mode-tests.el
@@ -77,3 +77,5 @@
(insert " ")
(dns-mode-ipv6-to-nibbles nil)
(should (equal (buffer-string) "8.b.d.0.1.0.0.2.ip6.arpa. ")))))
+
+;;; dns-mode-tests.el ends here
diff --git a/test/lisp/textmodes/fill-tests.el b/test/lisp/textmodes/fill-tests.el
index a4c7f447b59..2a1195b87ea 100644
--- a/test/lisp/textmodes/fill-tests.el
+++ b/test/lisp/textmodes/fill-tests.el
@@ -54,7 +54,7 @@
(beg (line-beginning-position))
(end (line-end-position))
(fill-prefix (make-string (- pos beg) ?\s))
- ;; `fill-column' is too small to accomodate the current line
+ ;; `fill-column' is too small to accommodate the current line
(fill-column (- end beg 10)))
(fill-region-as-paragraph beg end nil nil pos))
(should (equal (buffer-string) string)))))
@@ -69,13 +69,35 @@
(beg (line-beginning-position))
(end (line-end-position))
(fill-prefix (make-string (- pos beg) ?\s))
- ;; `fill-column' is too small to accomodate the current line
+ ;; `fill-column' is too small to accommodate the current line
(fill-column (- end beg 10)))
(fill-region-as-paragraph beg end nil nil pos))
(should (equal
(buffer-string)
"aaa = baaaaaaaa aaaaaaaaaa\n aaaaaaaaaa\n")))))
+(ert-deftest test-fill-end-period ()
+ (should
+ (equal
+ (with-temp-buffer
+ (text-mode)
+ (auto-fill-mode)
+ (insert "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eius.")
+ (self-insert-command 1 ?\s)
+ (buffer-string))
+ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eius. "))
+ (should
+ (equal
+ (with-temp-buffer
+ (text-mode)
+ (auto-fill-mode)
+ (insert "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eius.Foo")
+ (forward-char -3)
+ (self-insert-command 1 ?\s)
+ (buffer-string))
+ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
+eius. Foo")))
+
(provide 'fill-tests)
;;; fill-tests.el ends here
diff --git a/test/lisp/textmodes/reftex-tests.el b/test/lisp/textmodes/reftex-tests.el
index b824e05f6d5..cc5b23e1c9c 100644
--- a/test/lisp/textmodes/reftex-tests.el
+++ b/test/lisp/textmodes/reftex-tests.el
@@ -24,6 +24,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
;;; reftex
(require 'reftex)
@@ -33,32 +34,31 @@
(ert-deftest reftex-locate-bibliography-files ()
"Test `reftex-locate-bibliography-files'."
- (let ((temp-dir (make-temp-file "reftex-bib" 'dir))
- (files '("ref1.bib" "ref2.bib"))
- (test '(("\\addbibresource{ref1.bib}\n" . ("ref1.bib"))
- ("\\\\addbibresource[label=x]{ref2.bib}\\n" . ("ref2.bib"))
- ("\\begin{document}\n\\bibliographystyle{plain}\n
+ (ert-with-temp-directory temp-dir
+ (let ((files '("ref1.bib" "ref2.bib"))
+ (test '(("\\addbibresource{ref1.bib}\n" . ("ref1.bib"))
+ ("\\\\addbibresource[label=x]{ref2.bib}\\n" . ("ref2.bib"))
+ ("\\begin{document}\n\\bibliographystyle{plain}\n
\\bibliography{ref1,ref2}\n\\end{document}" . ("ref1.bib" "ref2.bib"))))
- (reftex-bibliography-commands
- ;; Default value: See reftex-vars.el `reftex-bibliography-commands'
- '("bibliography" "nobibliography" "setupbibtex\\[.*?database="
- "addbibresource")))
- (with-temp-buffer
- (insert "test\n")
+ (reftex-bibliography-commands
+ ;; Default value: See reftex-vars.el `reftex-bibliography-commands'
+ '("bibliography" "nobibliography" "setupbibtex\\[.*?database="
+ "addbibresource")))
+ (with-temp-buffer
+ (insert "test\n")
+ (mapc
+ (lambda (file)
+ (write-region (point-min) (point-max) (expand-file-name file
+ temp-dir)))
+ files))
(mapc
- (lambda (file)
- (write-region (point-min) (point-max) (expand-file-name file
- temp-dir)))
- files))
- (mapc
- (lambda (data)
- (with-temp-buffer
- (insert (car data))
- (let ((res (mapcar #'file-name-nondirectory
- (reftex-locate-bibliography-files temp-dir))))
- (should (equal res (cdr data))))))
- test)
- (delete-directory temp-dir 'recursive)))
+ (lambda (data)
+ (with-temp-buffer
+ (insert (car data))
+ (let ((res (mapcar #'file-name-nondirectory
+ (reftex-locate-bibliography-files temp-dir))))
+ (should (equal res (cdr data))))))
+ test))))
(ert-deftest reftex-what-environment-test ()
"Test `reftex-what-environment'."
@@ -102,12 +102,12 @@
;; reason. (An alternative solution would be to use file-equal-p,
;; but I'm too lazy to do that, as one of the tests compares a
;; list.)
- (let* ((temp-dir (file-truename (make-temp-file "reftex-parse" 'dir)))
- (tex-file (expand-file-name "test.tex" temp-dir))
- (bib-file (expand-file-name "ref.bib" temp-dir)))
- (with-temp-buffer
- (insert
-"\\begin{document}
+ (ert-with-temp-directory temp-dir
+ (let* ((tex-file (expand-file-name "test.tex" temp-dir))
+ (bib-file (expand-file-name "ref.bib" temp-dir)))
+ (with-temp-buffer
+ (insert
+ "\\begin{document}
\\section{test}\\label{sec:test}
\\subsection{subtest}
@@ -118,27 +118,26 @@
\\bibliographystyle{plain}
\\bibliography{ref}
\\end{document}")
- (write-region (point-min) (point-max) tex-file))
- (with-temp-buffer
- (insert "test\n")
- (write-region (point-min) (point-max) bib-file))
- (reftex-ensure-compiled-variables)
- (let ((parsed (reftex-parse-from-file tex-file nil temp-dir)))
- (should (equal (car parsed) `(eof ,tex-file)))
- (pop parsed)
- (while parsed
- (let ((entry (pop parsed)))
- (cond
- ((eq (car entry) 'bib)
- (should (string= (cadr entry) bib-file)))
- ((eq (car entry) 'toc)) ;; ...
- ((string= (car entry) "eq:foo"))
- ((string= (car entry) "sec:test"))
- ((eq (car entry) 'bof)
- (should (string= (cadr entry) tex-file))
- (should (null parsed)))
- (t (should-not t)))))
- (delete-directory temp-dir 'recursive))))
+ (write-region (point-min) (point-max) tex-file))
+ (with-temp-buffer
+ (insert "test\n")
+ (write-region (point-min) (point-max) bib-file))
+ (reftex-ensure-compiled-variables)
+ (let ((parsed (reftex-parse-from-file tex-file nil temp-dir)))
+ (should (equal (car parsed) `(eof ,tex-file)))
+ (pop parsed)
+ (while parsed
+ (let ((entry (pop parsed)))
+ (cond
+ ((eq (car entry) 'bib)
+ (should (string= (cadr entry) bib-file)))
+ ((eq (car entry) 'toc)) ;; ...
+ ((string= (car entry) "eq:foo"))
+ ((string= (car entry) "sec:test"))
+ ((eq (car entry) 'bof)
+ (should (string= (cadr entry) tex-file))
+ (should (null parsed)))
+ (t (should-not t)))))))))
;;; reftex-cite
(require 'reftex-cite)
diff --git a/test/lisp/textmodes/texinfo-resources/fill.erts b/test/lisp/textmodes/texinfo-resources/fill.erts
new file mode 100644
index 00000000000..95f3b09eba8
--- /dev/null
+++ b/test/lisp/textmodes/texinfo-resources/fill.erts
@@ -0,0 +1,70 @@
+Code:
+ (lambda ()
+ (texinfo-mode)
+ (fill-paragraph))
+
+Name: fill1
+Point-Char: |
+
+=-=
+@noindent Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+=-=
+@noindent Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+=-=-=
+
+Name: fill2
+Point-Char: |
+
+=-=
+@cindex relative| remapping, faces
+@cindex base remapping, faces
+ The following functions implement a higher-level interface to @code{face-remapping-alist}.
+=-=-=
+
+
+Name: fill3
+Point-Char: |
+
+=-=
+@cindex relative remapping, faces
+@cindex base remapping, faces|
+ The following functions implement a higher-level interface to @code{face-remapping-alist}.
+=-=-=
+
+Name: fill4
+Point-Char: |
+
+=-=
+@cindex relative remapping, faces
+@cindex base remapping, faces
+ The following functions| implement a higher-level interface to @code{face-remapping-alist}.
+=-=
+@cindex relative remapping, faces
+@cindex base remapping, faces
+ The following functions| implement a higher-level interface to
+@code{face-remapping-alist}.
+=-=-=
+
+Name: fill5
+Point-Char: |
+
+=-=
+@defun face-remap-add-relative face &rest specs
+|This function adds the face spec in @var{specs} as relative
+remappings for face @var{face} in the current buffer. The remaining
+arguments, @var{specs}, should form either a list of face names, or a
+property list of attribute/value pairs.
+=-=
+@defun face-remap-add-relative face &rest specs
+This function adds the face spec in @var{specs} as relative remappings
+for face @var{face} in the current buffer. The remaining arguments,
+@var{specs}, should form either a list of face names, or a property
+list of attribute/value pairs.
+=-=-=
+
+Name: fill6
+
+=-=
+@subsection This is a very very very very very very very very very very long subsection name
+=-=-=
diff --git a/test/lisp/textmodes/texinfo-tests.el b/test/lisp/textmodes/texinfo-tests.el
new file mode 100644
index 00000000000..fa0c4de005e
--- /dev/null
+++ b/test/lisp/textmodes/texinfo-tests.el
@@ -0,0 +1,33 @@
+;;; texinfo-tests.el --- Tests for texinfo.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 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 'texinfo)
+(require 'ert)
+(require 'ert-x)
+
+(ert-deftest test-filling ()
+ (ert-test-erts-file (ert-resource-file "fill.erts")))
+
+;;; texinfo-tests.el ends here
diff --git a/test/lisp/thingatpt-tests.el b/test/lisp/thingatpt-tests.el
index fba6f21d5dc..f2031fa79ab 100644
--- a/test/lisp/thingatpt-tests.el
+++ b/test/lisp/thingatpt-tests.el
@@ -70,7 +70,7 @@
;; UUID, only hex is allowed
("01234567-89ab-cdef-ABCD-EF0123456789" 1 uuid "01234567-89ab-cdef-ABCD-EF0123456789")
("01234567-89ab-cdef-ABCD-EF012345678G" 1 uuid nil))
- "List of thing-at-point tests.
+ "List of `thing-at-point' tests.
Each list element should have the form
(STRING POS THING RESULT)
@@ -170,21 +170,13 @@ position to retrieve THING.")
(forward-char -1)
(should (eq (symbol-at-point) 'bar))))
-(ert-deftest test-symbol-thing-2 ()
- (with-temp-buffer
- (insert " bar ")
- (goto-char (point-max))
- (should (eq (symbol-at-point) nil))
- (forward-char -1)
- (should (eq (symbol-at-point) 'bar))))
-
(ert-deftest test-symbol-thing-3 ()
(with-temp-buffer
(insert "bar")
(goto-char 2)
(should (eq (symbol-at-point) 'bar))))
-(ert-deftest test-symbol-thing-3 ()
+(ert-deftest test-symbol-thing-4 ()
(with-temp-buffer
(insert "`[[`(")
(goto-char 2)
@@ -223,4 +215,12 @@ position to retrieve THING.")
(should (equal (test--number "0xf00" 2) 3840))
(should (equal (test--number "0xf00" 3) 3840)))
-;;; thingatpt.el ends here
+(ert-deftest test-fields ()
+ (with-temp-buffer
+ (insert (propertize "foo" 'field 1) "bar" (propertize "zot" 'field 2))
+ (goto-char 1)
+ (should (eq (symbol-at-point) 'foo))
+ (goto-char 5)
+ (should (eq (symbol-at-point) 'bar))))
+
+;;; thingatpt-tests.el ends here
diff --git a/test/lisp/thumbs-tests.el b/test/lisp/thumbs-tests.el
index ee096138453..a9b41d7c00f 100644
--- a/test/lisp/thumbs-tests.el
+++ b/test/lisp/thumbs-tests.el
@@ -20,15 +20,13 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'thumbs)
(ert-deftest thumbs-tests-thumbsdir/create-if-missing ()
- (let ((thumbs-thumbsdir (make-temp-file "thumbs-test" t)))
- (unwind-protect
- (progn
- (delete-directory thumbs-thumbsdir)
- (should (file-directory-p (thumbs-thumbsdir))))
- (delete-directory thumbs-thumbsdir))))
+ (ert-with-temp-directory thumbs-thumbsdir
+ (delete-directory thumbs-thumbsdir)
+ (should (file-directory-p (thumbs-thumbsdir)))))
(provide 'thumbs-tests)
;;; thumbs-tests.el ends here
diff --git a/test/lisp/time-stamp-tests.el b/test/lisp/time-stamp-tests.el
index 4e6fbbba923..a049e5de58a 100644
--- a/test/lisp/time-stamp-tests.el
+++ b/test/lisp/time-stamp-tests.el
@@ -26,7 +26,7 @@
(defmacro with-time-stamp-test-env (&rest body)
"Evaluate BODY with some standard time-stamp test variables bound."
- (declare (indent defun))
+ (declare (indent 0) (debug t))
`(let ((user-login-name "test-logname")
(user-full-name "100%d Tester") ;verify "%" passed unchanged
(buffer-file-name "/emacs/test/time-stamped-file")
@@ -46,7 +46,7 @@
(defmacro with-time-stamp-test-time (reference-time &rest body)
"Force any contained time-stamp call to use time REFERENCE-TIME."
- (declare (indent defun))
+ (declare (indent 1) (debug t))
`(cl-letf*
((orig-time-stamp-string-fn (symbol-function 'time-stamp-string))
((symbol-function 'time-stamp-string)
@@ -56,13 +56,14 @@
(defmacro with-time-stamp-system-name (name &rest body)
"Force (system-name) to return NAME while evaluating BODY."
- (declare (indent defun))
+ (declare (indent 1) (debug t))
`(cl-letf (((symbol-function 'system-name)
(lambda () ,name)))
,@body))
(defmacro time-stamp-should-warn (form)
"Similar to `should' but verifies that a format warning is generated."
+ (declare (debug t))
`(let ((warning-count 0))
(cl-letf (((symbol-function 'time-stamp-conv-warn)
(lambda (_old _new)
@@ -86,7 +87,7 @@
(should (equal (time-stamp-string "%H %Z" ref-time1) "15 GMT")))))
(iter-defun time-stamp-test-pattern-sequential ()
- "Iterate through each possibility for a part of time-stamp-pattern."
+ "Iterate through each possibility for a part of `time-stamp-pattern'."
(let ((pattern-value-parts
'(("4/" "10/" "-4/" "0/" "") ;0: line limit
("stamp<" "") ;1: start
@@ -115,7 +116,7 @@
(extract-part 5))))))))))
(iter-defun time-stamp-test-pattern-multiply ()
- "Iterate through every combination of parts of time-stamp-pattern."
+ "Iterate through every combination of parts of `time-stamp-pattern'."
(let ((line-limit-values '("" "4/"))
(start-values '("" "stamp<"))
(format-values '("%%" "%m"))
@@ -141,9 +142,9 @@
ts-format _format-lines _end-lines)
;; Verify that time-stamp parsed time-stamp-pattern and
;; called us with the correct pieces.
- (let ((limit-number (string-to-number line-limit1)))
- (if (equal line-limit1 "")
- (setq limit-number time-stamp-line-limit))
+ (let ((limit-number (if (equal line-limit1 "")
+ time-stamp-line-limit
+ (string-to-number line-limit1))))
(goto-char (point-min))
(if (> limit-number 0)
(should (= search-limit (line-beginning-position
@@ -594,8 +595,12 @@
;; incorrectly nested parens do not crash us
(should-not (equal (time-stamp-string "%(stuffB" ref-time3) May))
(should-not (equal (time-stamp-string "%)B" ref-time3) May))
+ ;; unterminated format does not crash us
+ (should-not (equal (time-stamp-string "%" ref-time3) May))
;; not all punctuation is allowed
- (should-not (equal (time-stamp-string "%&B" ref-time3) May)))))
+ (should-not (equal (time-stamp-string "%&B" ref-time3) May))
+ (should-not (equal (time-stamp-string "%/B" ref-time3) May))
+ (should-not (equal (time-stamp-string "%;B" ref-time3) May)))))
(ert-deftest time-stamp-format-non-conversions ()
"Test that without a %, the text is copied literally."
@@ -634,8 +639,8 @@
(concat Mon "." Monday "." Mon)))
(should (equal (time-stamp-string "%5z.%5::z.%5z" ref-time1)
"+0000.+00:00:00.+0000"))
- ;; format letter is independent
- (should (equal (time-stamp-string "%H:%M" ref-time1) "15:04")))))
+ ;; format character is independent
+ (should (equal (time-stamp-string "%H:%M%%%S" ref-time1) "15:04%05")))))
(ert-deftest time-stamp-format-string-width ()
"Test time-stamp string width modifiers."
@@ -703,9 +708,10 @@
;;;; Setup for tests of time offset formatting with %z
(defun formatz (format zone)
- "Uses time FORMAT string to format the offset of ZONE, returning the result.
-FORMAT is \"%z\" or a variation.
-ZONE is as the ZONE argument of the `format-time-string' function."
+ "Uses FORMAT to format the offset of ZONE, returning the result.
+FORMAT must be time format \"%z\" or some variation thereof.
+ZONE is as the ZONE argument of the `format-time-string' function.
+This function is called by 99% of the `time-stamp' \"%z\" unit tests."
(with-time-stamp-test-env
(let ((time-stamp-time-zone zone))
;; Call your favorite time formatter here.
@@ -717,9 +723,9 @@ ZONE is as the ZONE argument of the `format-time-string' function."
(defun format-time-offset (format offset-secs)
"Uses FORMAT to format the time zone represented by OFFSET-SECS.
-FORMAT must be \"%z\", possibly with a flag and padding.
+FORMAT must be time format \"%z\" or some variation thereof.
This function is a wrapper around `time-stamp-formatz-from-parsed-options'
-and is used for testing."
+and is called by some low-level `time-stamp' \"%z\" unit tests."
;; This wrapper adds a simple regexp-based parser that handles only
;; %z and variants. In normal use, time-stamp-formatz-from-parsed-options
;; is called from a parser that handles all time string formats.
@@ -761,6 +767,7 @@ and is used for testing."
"Formats ZONE and compares it to EXPECT.
Uses the free variables `form-string' and `pattern-mod'.
The functions in `pattern-mod' are composed left to right."
+ (declare (debug t))
`(let ((result ,expect))
(dolist (fn pattern-mod)
(setq result (funcall fn result)))
@@ -871,7 +878,7 @@ The functions in `pattern-mod' are composed left to right."
(defmacro formatz-generate-tests
(form-strings hour-mod mins-mod secs-mod big-mod secbig-mod)
- "Defines ert-deftest tests for time formats FORM-STRINGS.
+ "Defines tests for time formats FORM-STRINGS.
FORM-STRINGS is a list of formats, each \"%z\" or some variation thereof.
Each of the remaining arguments is an unquoted list of the form
@@ -895,10 +902,11 @@ BIG-MOD is the result for offset +100 hours and modifiers for the other
expected results for hours greater than 99 with a whole number of minutes.
SECBIG-MOD is the result for offset +100 hours 30 seconds and modifiers for
the other expected results for hours greater than 99 with non-zero seconds."
- (declare (indent 1))
+ (declare (indent 1) (debug (&rest sexp)))
;; Generate a form to create a list of tests to define. When this
;; macro is called, the form is evaluated, thus defining the tests.
- (let ((ert-test-list '(list)))
+ ;; We will modify this list, so start with a list consed at runtime.
+ (let ((ert-test-list (list 'list)))
(dolist (form-string form-strings ert-test-list)
(nconc
ert-test-list
diff --git a/test/lisp/time-tests.el b/test/lisp/time-tests.el
index 88b7638d91d..89e6985b842 100644
--- a/test/lisp/time-tests.el
+++ b/test/lisp/time-tests.el
@@ -21,6 +21,8 @@
;;; Commentary:
+;;; Code:
+
(require 'ert)
(require 'ert-x)
(require 'time)
diff --git a/test/lisp/timezone-tests.el b/test/lisp/timezone-tests.el
index 9f6961409e6..9bbe36cfe8a 100644
--- a/test/lisp/timezone-tests.el
+++ b/test/lisp/timezone-tests.el
@@ -21,6 +21,8 @@
;;; Commentary:
+;;; Code:
+
(require 'ert)
(require 'timezone)
diff --git a/test/lisp/url/url-auth-tests.el b/test/lisp/url/url-auth-tests.el
index ff30f100250..05ccfc0d12a 100644
--- a/test/lisp/url/url-auth-tests.el
+++ b/test/lisp/url/url-auth-tests.el
@@ -154,7 +154,7 @@ Essential is how realms and paths are matched."
auth)
(dolist (row (list
- ;; If :expected-user is `nil' it indicates
+ ;; If :expected-user is nil it indicates
;; authentication information shouldn't be found.
;; non-existent server
diff --git a/test/lisp/url/url-handlers-test.el b/test/lisp/url/url-handlers-tests.el
index 7e5a60363da..71e054b1287 100644
--- a/test/lisp/url/url-handlers-test.el
+++ b/test/lisp/url/url-handlers-tests.el
@@ -1,4 +1,4 @@
-;;; url-handlers-test.el --- Test suite for url-handlers.el -*- lexical-binding: t; -*-
+;;; url-handlers-tests.el --- Test suite for url-handlers.el -*- lexical-binding: t; -*-
;; Copyright (C) 2018-2021 Free Software Foundation, Inc.
@@ -73,5 +73,4 @@
(should (equal (file-name-directory "https://foo.org/")
"https://foo.org/"))))
-(provide 'url-handlers-test)
-;;; url-handlers-test.el ends here
+;;; url-handlers-tests.el ends here
diff --git a/test/lisp/url/url-parse-tests.el b/test/lisp/url/url-parse-tests.el
index 2418af40aca..a7f81eba8f5 100644
--- a/test/lisp/url/url-parse-tests.el
+++ b/test/lisp/url/url-parse-tests.el
@@ -23,7 +23,7 @@
;;; Commentary:
;; Test cases covering generic URI syntax as described in RFC3986,
-;; section 3. Syntax Components and 4. Usage. See also appendix
+;; section 3. Syntax Components and 4. Usage. See also appendix
;; A. Collected ABNF for URI, as the example given here are all
;; productions of this grammar.
diff --git a/test/lisp/vc/add-log-tests.el b/test/lisp/vc/add-log-tests.el
index dc2b9961c6c..70e49fe57fe 100644
--- a/test/lisp/vc/add-log-tests.el
+++ b/test/lisp/vc/add-log-tests.el
@@ -29,8 +29,8 @@
content marker expected-defun)
"Generate an ert test for mode-own `add-log-current-defun-function'.
Run `add-log-current-defun' at the point where MARKER specifies
-in a buffer which content is CONTENT under major mode MODE. Then
-it compares the result with EXPECTED-DEFUN."
+in a buffer which content is CONTENT under major mode MODE.
+Then it compares the result with EXPECTED-DEFUN."
(let ((xname (intern (concat "add-log-current-defun-test-"
(symbol-name name)
))))
diff --git a/test/lisp/vc/diff-mode-tests.el b/test/lisp/vc/diff-mode-tests.el
index fefe50d5173..909d5620de6 100644
--- a/test/lisp/vc/diff-mode-tests.el
+++ b/test/lisp/vc/diff-mode-tests.el
@@ -173,35 +173,33 @@ wristwatches
wrongheadedly
wrongheadedness
youthfulness
-")
- (temp-dir (make-temp-file "diff-mode-test" 'dir)))
-
- (let ((buf (find-file-noselect (format "%s/%s" temp-dir "fil" )))
- (buf2 (find-file-noselect (format "%s/%s" temp-dir "fil2"))))
- (unwind-protect
- (progn
- (with-current-buffer buf (insert fil_before) (save-buffer))
- (with-current-buffer buf2 (insert fil2_before) (save-buffer))
-
- (with-temp-buffer
- (cd temp-dir)
- (insert patch)
- (goto-char (point-min))
- (diff-apply-hunk)
- (diff-apply-hunk)
- (diff-apply-hunk))
-
- (should (equal (with-current-buffer buf (buffer-string))
- fil_after))
- (should (equal (with-current-buffer buf2 (buffer-string))
- fil2_after)))
-
- (ignore-errors
- (with-current-buffer buf (set-buffer-modified-p nil))
- (kill-buffer buf)
- (with-current-buffer buf2 (set-buffer-modified-p nil))
- (kill-buffer buf2)
- (delete-directory temp-dir 'recursive))))))
+"))
+ (ert-with-temp-directory temp-dir
+ (let ((buf (find-file-noselect (format "%s/%s" temp-dir "fil" )))
+ (buf2 (find-file-noselect (format "%s/%s" temp-dir "fil2"))))
+ (unwind-protect
+ (progn
+ (with-current-buffer buf (insert fil_before) (save-buffer))
+ (with-current-buffer buf2 (insert fil2_before) (save-buffer))
+
+ (with-temp-buffer
+ (cd temp-dir)
+ (insert patch)
+ (goto-char (point-min))
+ (diff-apply-hunk)
+ (diff-apply-hunk)
+ (diff-apply-hunk))
+
+ (should (equal (with-current-buffer buf (buffer-string))
+ fil_after))
+ (should (equal (with-current-buffer buf2 (buffer-string))
+ fil2_after)))
+
+ (ignore-errors
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf)
+ (with-current-buffer buf2 (set-buffer-modified-p nil))
+ (kill-buffer buf2)))))))
(ert-deftest diff-mode-test-hunk-text-no-newline ()
"Check output of `diff-hunk-text' with no newline at end of file."
@@ -481,3 +479,4 @@ baz"))))
'("/tmp/ange-ftp1351895K.el" "/tmp/ange-ftp13518wvE.el")))))
(provide 'diff-mode-tests)
+;;; diff-mode-tests.el ends here
diff --git a/test/lisp/vc/ediff-ptch-tests.el b/test/lisp/vc/ediff-ptch-tests.el
index a464db2349d..0f09616a816 100644
--- a/test/lisp/vc/ediff-ptch-tests.el
+++ b/test/lisp/vc/ediff-ptch-tests.el
@@ -22,6 +22,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'ediff-ptch)
(ert-deftest ediff-ptch-test-bug25010 ()
@@ -45,34 +46,33 @@ index 6a07f80..6e8e947 100644
"Test for https://debbugs.gnu.org/26084 ."
(skip-unless (executable-find "git"))
(skip-unless (executable-find ediff-patch-program))
- (let* ((tmpdir (make-temp-file "ediff-ptch-test" t))
- (default-directory (file-name-as-directory tmpdir))
- (patch (make-temp-file "ediff-ptch-test"))
- (qux (expand-file-name "qux.txt" tmpdir))
- (bar (expand-file-name "bar.txt" tmpdir))
- (git-program (executable-find "git")))
- ;; Create repository.
- (with-temp-buffer
- (insert "qux here\n")
- (write-region nil nil qux nil 'silent)
- (erase-buffer)
- (insert "bar here\n")
- (write-region nil nil bar nil 'silent))
- (call-process git-program nil nil nil "init")
- (call-process git-program nil nil nil "add" ".")
- (call-process git-program nil nil nil "commit" "-m" "Test repository.")
- ;; Update repo., save the diff and reset to initial state.
- (with-temp-buffer
- (insert "foo here\n")
- (write-region nil nil qux nil 'silent)
- (write-region nil nil bar nil 'silent))
- (call-process git-program nil `(:file ,patch) nil "diff")
- (call-process git-program nil nil nil "reset" "--hard" "HEAD")
- ;; Visit the diff file i.e., patch; extract from it the parts
- ;; affecting just each of the files: store in patch-bar the part
- ;; affecting 'bar', and in patch-qux the part affecting 'qux'.
- (find-file patch)
- (unwind-protect
+ (ert-with-temp-directory tmpdir
+ (ert-with-temp-file patch
+ (let* ((default-directory (file-name-as-directory tmpdir))
+ (qux (expand-file-name "qux.txt" tmpdir))
+ (bar (expand-file-name "bar.txt" tmpdir))
+ (git-program (executable-find "git")))
+ ;; Create repository.
+ (with-temp-buffer
+ (insert "qux here\n")
+ (write-region nil nil qux nil 'silent)
+ (erase-buffer)
+ (insert "bar here\n")
+ (write-region nil nil bar nil 'silent))
+ (call-process git-program nil nil nil "init")
+ (call-process git-program nil nil nil "add" ".")
+ (call-process git-program nil nil nil "commit" "-m" "Test repository.")
+ ;; Update repo., save the diff and reset to initial state.
+ (with-temp-buffer
+ (insert "foo here\n")
+ (write-region nil nil qux nil 'silent)
+ (write-region nil nil bar nil 'silent))
+ (call-process git-program nil `(:file ,patch) nil "diff")
+ (call-process git-program nil nil nil "reset" "--hard" "HEAD")
+ ;; Visit the diff file i.e., patch; extract from it the parts
+ ;; affecting just each of the files: store in patch-bar the part
+ ;; affecting 'bar', and in patch-qux the part affecting 'qux'.
+ (find-file patch)
(let* ((info
(progn (ediff-map-patch-buffer (current-buffer)) ediff-patch-map))
(patch-bar
@@ -116,9 +116,7 @@ index 6a07f80..6e8e947 100644
(buffer-string))
(with-temp-buffer
(insert-file-contents backup)
- (buffer-string)))))))
- (delete-directory tmpdir 'recursive)
- (delete-file patch)))))
+ (buffer-string))))))))))))
(provide 'ediff-ptch-tests)
diff --git a/test/lisp/vc/smerge-mode-tests.el b/test/lisp/vc/smerge-mode-tests.el
index 2c8f48618e5..d7827c7a8cb 100644
--- a/test/lisp/vc/smerge-mode-tests.el
+++ b/test/lisp/vc/smerge-mode-tests.el
@@ -34,3 +34,5 @@
(should (equal (buffer-substring (point-min) (point-max)) ""))))
(provide 'smerge-mode-tests)
+
+;;; smerge-mode-tests.el ends here
diff --git a/test/lisp/vc/vc-bzr-tests.el b/test/lisp/vc/vc-bzr-tests.el
index b02dce8f707..afced819fbc 100644
--- a/test/lisp/vc/vc-bzr-tests.el
+++ b/test/lisp/vc/vc-bzr-tests.el
@@ -25,6 +25,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'vc-bzr)
(require 'vc-dir)
@@ -51,106 +52,97 @@
;; temporary directory.
;; TODO does this means tests should be setting XDG_ variables (not
;; just HOME) to temporary values too?
- (let* ((homedir (make-temp-file "vc-bzr-test" t))
- (bzrdir (expand-file-name "bzr" homedir))
- (ignored-dir (progn
- (make-directory bzrdir)
- (expand-file-name "ignored-dir" bzrdir)))
- (default-directory (file-name-as-directory bzrdir))
- (process-environment (cons (format "HOME=%s" homedir)
- process-environment)))
- (unwind-protect
- (progn
- (make-directory ignored-dir)
- (with-temp-buffer
- (insert (file-name-nondirectory ignored-dir))
- (write-region nil nil (expand-file-name ".bzrignore" bzrdir)
- nil 'silent))
- (skip-unless (eq 0 ; some internal bzr error
- (call-process vc-bzr-program nil nil nil "init")))
- (call-process vc-bzr-program nil nil nil "add")
- (call-process vc-bzr-program nil nil nil "commit" "-m" "Commit 1")
- (with-temp-buffer
- (insert "unregistered file")
- (write-region nil nil (expand-file-name "testfile2" ignored-dir)
- nil 'silent))
- (vc-dir ignored-dir)
- (while (vc-dir-busy)
- (sit-for 0.1))
- ;; FIXME better to explicitly test for error from process sentinel.
- (with-current-buffer "*vc-dir*"
- (goto-char (point-min))
- (should (search-forward "unregistered" nil t))))
- (delete-directory homedir t))))
+ (ert-with-temp-directory homedir
+ (let* ((bzrdir (expand-file-name "bzr" homedir))
+ (ignored-dir (progn
+ (make-directory bzrdir)
+ (expand-file-name "ignored-dir" bzrdir)))
+ (default-directory (file-name-as-directory bzrdir))
+ (process-environment (cons (format "HOME=%s" homedir)
+ process-environment)))
+ (make-directory ignored-dir)
+ (with-temp-buffer
+ (insert (file-name-nondirectory ignored-dir))
+ (write-region nil nil (expand-file-name ".bzrignore" bzrdir)
+ nil 'silent))
+ (skip-unless (eq 0 ; some internal bzr error
+ (call-process vc-bzr-program nil nil nil "init")))
+ (call-process vc-bzr-program nil nil nil "add")
+ (call-process vc-bzr-program nil nil nil "commit" "-m" "Commit 1")
+ (with-temp-buffer
+ (insert "unregistered file")
+ (write-region nil nil (expand-file-name "testfile2" ignored-dir)
+ nil 'silent))
+ (vc-dir ignored-dir)
+ (while (vc-dir-busy)
+ (sit-for 0.1))
+ ;; FIXME better to explicitly test for error from process sentinel.
+ (with-current-buffer "*vc-dir*"
+ (goto-char (point-min))
+ (should (search-forward "unregistered" nil t))))))
;; Not specific to bzr.
(ert-deftest vc-bzr-test-bug9781 ()
"Test for https://debbugs.gnu.org/9781 ."
(skip-unless (executable-find vc-bzr-program))
- (let* ((homedir (make-temp-file "vc-bzr-test" t))
- (bzrdir (expand-file-name "bzr" homedir))
- (subdir (progn
- (make-directory bzrdir)
- (expand-file-name "subdir" bzrdir)))
- (file (expand-file-name "file" bzrdir))
- (default-directory (file-name-as-directory bzrdir))
- (process-environment (cons (format "HOME=%s" homedir)
- process-environment)))
- (unwind-protect
- (progn
- (skip-unless (eq 0 ; some internal bzr error
- (call-process vc-bzr-program nil nil nil "init")))
- (make-directory subdir)
- (with-temp-buffer
- (insert "text")
- (write-region nil nil file nil 'silent)
- (write-region nil nil (expand-file-name "subfile" subdir)
- nil 'silent))
- (call-process vc-bzr-program nil nil nil "add")
- (call-process vc-bzr-program nil nil nil "commit" "-m" "Commit 1")
- (call-process vc-bzr-program nil nil nil "remove" subdir)
- (with-temp-buffer
- (insert "different text")
- (write-region nil nil file nil 'silent))
- (vc-dir bzrdir)
- (while (vc-dir-busy)
- (sit-for 0.1))
- (vc-dir-mark-all-files t)
- (cl-letf (((symbol-function 'y-or-n-p) (lambda (_) t)))
- (vc-next-action nil))
- (should (get-buffer "*vc-log*")))
- (delete-directory homedir t))))
+ (ert-with-temp-directory homedir
+ (let* ((bzrdir (expand-file-name "bzr" homedir))
+ (subdir (progn
+ (make-directory bzrdir)
+ (expand-file-name "subdir" bzrdir)))
+ (file (expand-file-name "file" bzrdir))
+ (default-directory (file-name-as-directory bzrdir))
+ (process-environment (cons (format "HOME=%s" homedir)
+ process-environment)))
+ (skip-unless (eq 0 ; some internal bzr error
+ (call-process vc-bzr-program nil nil nil "init")))
+ (make-directory subdir)
+ (with-temp-buffer
+ (insert "text")
+ (write-region nil nil file nil 'silent)
+ (write-region nil nil (expand-file-name "subfile" subdir)
+ nil 'silent))
+ (call-process vc-bzr-program nil nil nil "add")
+ (call-process vc-bzr-program nil nil nil "commit" "-m" "Commit 1")
+ (call-process vc-bzr-program nil nil nil "remove" subdir)
+ (with-temp-buffer
+ (insert "different text")
+ (write-region nil nil file nil 'silent))
+ (vc-dir bzrdir)
+ (while (vc-dir-busy)
+ (sit-for 0.1))
+ (vc-dir-mark-all-files t)
+ (cl-letf (((symbol-function 'y-or-n-p) (lambda (_) t)))
+ (vc-next-action nil))
+ (should (get-buffer "*vc-log*")))))
;; https://lists.gnu.org/r/help-gnu-emacs/2012-04/msg00145.html
(ert-deftest vc-bzr-test-faulty-bzr-autoloads ()
"Test we can generate autoloads in a bzr directory when bzr is faulty."
(skip-unless (executable-find vc-bzr-program))
- (let* ((homedir (make-temp-file "vc-bzr-test" t))
- (bzrdir (expand-file-name "bzr" homedir))
- (file (progn
- (make-directory bzrdir)
- (expand-file-name "foo.el" bzrdir)))
- (default-directory (file-name-as-directory bzrdir))
- (process-environment (cons (format "HOME=%s" homedir)
- process-environment)))
- (unwind-protect
- (progn
- (call-process vc-bzr-program nil nil nil "init")
- (with-temp-buffer
- (insert ";;;###autoload
+ (ert-with-temp-directory homedir
+ (let* ((bzrdir (expand-file-name "bzr" homedir))
+ (file (progn
+ (make-directory bzrdir)
+ (expand-file-name "foo.el" bzrdir)))
+ (default-directory (file-name-as-directory bzrdir))
+ (process-environment (cons (format "HOME=%s" homedir)
+ process-environment)))
+ (call-process vc-bzr-program nil nil nil "init")
+ (with-temp-buffer
+ (insert ";;;###autoload
\(defun foo () \"foo\" (interactive) (message \"foo!\"))")
- (write-region nil nil file nil 'silent))
- (call-process vc-bzr-program nil nil nil "add")
- (call-process vc-bzr-program nil nil nil "commit" "-m" "Commit 1")
- ;; Deleting dirstate ensures both that vc-bzr's status heuristic
- ;; fails, so it has to call the external bzr status, and
- ;; causes bzr status to fail. This simulates a broken bzr
- ;; installation.
- (delete-file ".bzr/checkout/dirstate")
- (should (progn (make-directory-autoloads
- default-directory
- (expand-file-name "loaddefs.el" bzrdir))
- t)))
- (delete-directory homedir t))))
+ (write-region nil nil file nil 'silent))
+ (call-process vc-bzr-program nil nil nil "add")
+ (call-process vc-bzr-program nil nil nil "commit" "-m" "Commit 1")
+ ;; Deleting dirstate ensures both that vc-bzr's status heuristic
+ ;; fails, so it has to call the external bzr status, and
+ ;; causes bzr status to fail. This simulates a broken bzr
+ ;; installation.
+ (delete-file ".bzr/checkout/dirstate")
+ (should (progn (make-directory-autoloads
+ default-directory
+ (expand-file-name "loaddefs.el" bzrdir))
+ t)))))
-;;; vc-bzr.el ends here
+;;; vc-bzr-tests.el ends here
diff --git a/test/lisp/vc/vc-git-tests.el b/test/lisp/vc/vc-git-tests.el
new file mode 100644
index 00000000000..997ab3c4b5c
--- /dev/null
+++ b/test/lisp/vc/vc-git-tests.el
@@ -0,0 +1,67 @@
+;;; vc-git-tests.el --- tests for vc/vc-git.el -*- lexical-binding:t -*-
+
+;; Copyright (C) 2016-2021 Free Software Foundation, Inc.
+
+;; Author: Justin Schell <justinmschell@gmail.com>
+;; Maintainer: emacs-devel@gnu.org
+
+;; 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 'vc-git)
+
+(ert-deftest vc-git-test-program-version-general ()
+ (vc-git-test--run-program-version-test
+ "git version 2.30.1.0"
+ "2.30.1.0"))
+
+(ert-deftest vc-git-test-program-version-windows ()
+ (vc-git-test--run-program-version-test
+ "git version 2.30.1.1.windows.1"
+ "2.30.1.1"))
+
+(ert-deftest vc-git-test-program-version-apple ()
+ (vc-git-test--run-program-version-test
+ "git version 2.30.1.2 (Apple Git-130)"
+ "2.30.1.2"))
+
+(ert-deftest vc-git-test-program-version-other ()
+ (vc-git-test--run-program-version-test
+ "git version 2.30.1.3.foo.bar"
+ "2.30.1.3"))
+
+(ert-deftest vc-git-test-program-version-invalid-leading-string ()
+ (vc-git-test--run-program-version-test
+ "git version foo.bar.2.30.1.4"
+ "0"))
+
+(ert-deftest vc-git-test-program-version-invalid-leading-dot ()
+ (vc-git-test--run-program-version-test
+ "git version .2.30.1.5"
+ "0"))
+
+(defun vc-git-test--run-program-version-test
+ (mock-version-string expected-output)
+ (cl-letf* (((symbol-function 'vc-git--run-command-string)
+ (lambda (_file _args) mock-version-string))
+ (vc-git--program-version nil)
+ (actual-output (vc-git--program-version)))
+ (should (equal actual-output expected-output))))
+
+;;; vc-git-tests.el ends here
diff --git a/test/lisp/vc/vc-tests.el b/test/lisp/vc/vc-tests.el
index 5430535c5ed..578d7ebb418 100644
--- a/test/lisp/vc/vc-tests.el
+++ b/test/lisp/vc/vc-tests.el
@@ -52,7 +52,7 @@
;; - responsible-p (file)
;; - receive-file (file rev)
;; - unregister (file) DONE
-;; * checkin (files comment)
+;; * checkin (files comment) DONE
;; * find-revision (file rev buffer)
;; * checkout (file &optional rev)
;; * revert (file &optional contents-done)
@@ -75,7 +75,7 @@
;; - show-log-entry (revision)
;; - comment-history (file)
;; - update-changelog (files)
-;; * diff (files &optional async rev1 rev2 buffer)
+;; * diff (files &optional async rev1 rev2 buffer) DONE
;; - revision-completion-table (files)
;; - annotate-command (file buf &optional rev)
;; - annotate-time ()
@@ -100,7 +100,7 @@
;; - log-edit-mode ()
;; - check-headers ()
;; - delete-file (file)
-;; - rename-file (old new)
+;; - rename-file (old new) DONE
;; - find-file-hook ()
;; - extra-menu ()
;; - extra-dir-menu ()
@@ -109,7 +109,9 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'vc)
+(require 'log-edit)
(declare-function w32-application-type "w32proc.c")
@@ -177,41 +179,38 @@ For backends which dont support it, it is emulated."
(defun vc-test--create-repo (backend)
"Create a test repository in `default-directory', a temporary directory."
-
- (let ((vc-handled-backends `(,backend))
- (default-directory
- (file-name-as-directory
- (expand-file-name
- (make-temp-name "vc-test") temporary-file-directory)))
- (process-environment process-environment)
- tempdir
- vc-test--cleanup-hook)
- (when (eq backend 'Bzr)
- (setq tempdir (make-temp-file "vc-test--create-repo" t)
- process-environment (cons (format "BZR_HOME=%s" tempdir)
- process-environment)))
-
- (unwind-protect
- (progn
- ;; Cleanup.
- (add-hook
- 'vc-test--cleanup-hook
- `(lambda () (delete-directory ,default-directory 'recursive)))
-
- ;; Check the revision granularity.
- (should (memq (vc-test--revision-granularity-function backend)
- '(file repository)))
-
- ;; Create empty repository.
- (make-directory default-directory)
- (should (file-directory-p default-directory))
- (vc-test--create-repo-function backend)
- (should (eq (vc-responsible-backend default-directory) backend)))
-
- ;; Save exit.
- (ignore-errors
- (if tempdir (delete-directory tempdir t))
- (run-hooks 'vc-test--cleanup-hook)))))
+ (ert-with-temp-directory tempdir
+ (let ((vc-handled-backends `(,backend))
+ (default-directory
+ (file-name-as-directory
+ (expand-file-name
+ (make-temp-name "vc-test") temporary-file-directory)))
+ (process-environment process-environment)
+ vc-test--cleanup-hook)
+ (when (eq backend 'Bzr)
+ (setq process-environment (cons (format "BZR_HOME=%s" tempdir)
+ process-environment)))
+
+ (unwind-protect
+ (progn
+ ;; Cleanup.
+ (add-hook
+ 'vc-test--cleanup-hook
+ `(lambda () (delete-directory ,default-directory 'recursive)))
+
+ ;; Check the revision granularity.
+ (should (memq (vc-test--revision-granularity-function backend)
+ '(file repository)))
+
+ ;; Create empty repository.
+ (make-directory default-directory)
+ (should (file-directory-p default-directory))
+ (vc-test--create-repo-function backend)
+ (should (eq (vc-responsible-backend default-directory) backend)))
+
+ ;; Save exit.
+ (ignore-errors
+ (run-hooks 'vc-test--cleanup-hook))))))
;; FIXME: Why isn't there `vc-unregister'?
(defun vc-test--unregister-function (backend file)
@@ -234,318 +233,429 @@ Catch the `vc-not-supported' error."
(defun vc-test--register (backend)
"Register and unregister a file.
This checks also `vc-backend' and `vc-responsible-backend'."
-
- (let ((vc-handled-backends `(,backend))
- (default-directory
- (file-name-as-directory
- (expand-file-name
- (make-temp-name "vc-test") temporary-file-directory)))
- (process-environment process-environment)
- tempdir
- vc-test--cleanup-hook)
- (when (eq backend 'Bzr)
- (setq tempdir (make-temp-file "vc-test--register" t)
- process-environment (cons (format "BZR_HOME=%s" tempdir)
- process-environment)))
- (unwind-protect
- (progn
- ;; Cleanup.
- (add-hook
- 'vc-test--cleanup-hook
- `(lambda () (delete-directory ,default-directory 'recursive)))
-
- ;; Create empty repository.
- (make-directory default-directory)
- (vc-test--create-repo-function backend)
- ;; For file oriented backends CVS, RCS and SVN the backend is
- ;; returned, and the directory is registered already.
- (should (if (vc-backend default-directory)
- (vc-registered default-directory)
- (not (vc-registered default-directory))))
- (should (eq (vc-responsible-backend default-directory) backend))
-
- (let ((tmp-name1 (expand-file-name "foo" default-directory))
- (tmp-name2 "bla"))
- ;; Register files. Check for it.
- (write-region "foo" nil tmp-name1 nil 'nomessage)
- (should (file-exists-p tmp-name1))
- (should-not (vc-backend tmp-name1))
- (should (eq (vc-responsible-backend tmp-name1) backend))
- (should-not (vc-registered tmp-name1))
-
- (write-region "bla" nil tmp-name2 nil 'nomessage)
- (should (file-exists-p tmp-name2))
- (should-not (vc-backend tmp-name2))
- (should (eq (vc-responsible-backend tmp-name2) backend))
- (should-not (vc-registered tmp-name2))
-
- (vc-register (list backend (list tmp-name1 tmp-name2)))
- (should (file-exists-p tmp-name1))
- (should (eq (vc-backend tmp-name1) backend))
- (should (eq (vc-responsible-backend tmp-name1) backend))
- (should (vc-registered tmp-name1))
-
- (should (file-exists-p tmp-name2))
- (should (eq (vc-backend tmp-name2) backend))
- (should (eq (vc-responsible-backend tmp-name2) backend))
- (should (vc-registered tmp-name2))
-
- ;; `vc-backend' accepts also a list of files,
- ;; `vc-responsible-backend' doesn't.
- (should (vc-backend (list tmp-name1 tmp-name2)))
-
- ;; Unregister the files.
- (unless (eq (vc-test--run-maybe-unsupported-function
- 'vc-test--unregister-function backend tmp-name1)
- 'vc-not-supported)
+ (ert-with-temp-directory tempdir
+ (let ((vc-handled-backends `(,backend))
+ (default-directory
+ (file-name-as-directory
+ (expand-file-name
+ (make-temp-name "vc-test") temporary-file-directory)))
+ (process-environment process-environment)
+ vc-test--cleanup-hook)
+ (when (eq backend 'Bzr)
+ (setq process-environment (cons (format "BZR_HOME=%s" tempdir)
+ process-environment)))
+ (unwind-protect
+ (progn
+ ;; Cleanup.
+ (add-hook
+ 'vc-test--cleanup-hook
+ `(lambda () (delete-directory ,default-directory 'recursive)))
+
+ ;; Create empty repository.
+ (make-directory default-directory)
+ (vc-test--create-repo-function backend)
+ ;; For file oriented backends CVS, RCS and SVN the backend is
+ ;; returned, and the directory is registered already.
+ (should (if (vc-backend default-directory)
+ (vc-registered default-directory)
+ (not (vc-registered default-directory))))
+ (should (eq (vc-responsible-backend default-directory) backend))
+
+ (let ((tmp-name1 (expand-file-name "foo" default-directory))
+ (tmp-name2 "bla"))
+ ;; Register files. Check for it.
+ (write-region "foo" nil tmp-name1 nil 'nomessage)
+ (should (file-exists-p tmp-name1))
(should-not (vc-backend tmp-name1))
- (should-not (vc-registered tmp-name1)))
- (unless (eq (vc-test--run-maybe-unsupported-function
- 'vc-test--unregister-function backend tmp-name2)
- 'vc-not-supported)
- (should-not (vc-backend tmp-name2))
- (should-not (vc-registered tmp-name2)))
+ (should (eq (vc-responsible-backend tmp-name1) backend))
+ (should-not (vc-registered tmp-name1))
- ;; The files should still exist.
- (should (file-exists-p tmp-name1))
- (should (file-exists-p tmp-name2))))
-
- ;; Save exit.
- (ignore-errors
- (if tempdir (delete-directory tempdir t))
- (run-hooks 'vc-test--cleanup-hook)))))
+ (write-region "bla" nil tmp-name2 nil 'nomessage)
+ (should (file-exists-p tmp-name2))
+ (should-not (vc-backend tmp-name2))
+ (should (eq (vc-responsible-backend tmp-name2) backend))
+ (should-not (vc-registered tmp-name2))
+
+ (vc-register (list backend (list tmp-name1 tmp-name2)))
+ (should (file-exists-p tmp-name1))
+ (should (eq (vc-backend tmp-name1) backend))
+ (should (eq (vc-responsible-backend tmp-name1) backend))
+ (should (vc-registered tmp-name1))
+
+ (should (file-exists-p tmp-name2))
+ (should (eq (vc-backend tmp-name2) backend))
+ (should (eq (vc-responsible-backend tmp-name2) backend))
+ (should (vc-registered tmp-name2))
+
+ ;; `vc-backend' accepts also a list of files,
+ ;; `vc-responsible-backend' doesn't.
+ (should (vc-backend (list tmp-name1 tmp-name2)))
+
+ ;; Unregister the files.
+ (unless (eq (vc-test--run-maybe-unsupported-function
+ 'vc-test--unregister-function backend tmp-name1)
+ 'vc-not-supported)
+ (should-not (vc-backend tmp-name1))
+ (should-not (vc-registered tmp-name1)))
+ (unless (eq (vc-test--run-maybe-unsupported-function
+ 'vc-test--unregister-function backend tmp-name2)
+ 'vc-not-supported)
+ (should-not (vc-backend tmp-name2))
+ (should-not (vc-registered tmp-name2)))
+
+ ;; The files should still exist.
+ (should (file-exists-p tmp-name1))
+ (should (file-exists-p tmp-name2))))
+
+ ;; Save exit.
+ (ignore-errors
+ (run-hooks 'vc-test--cleanup-hook))))))
(defun vc-test--state (backend)
"Check the different states of a file."
-
- (let ((vc-handled-backends `(,backend))
- (default-directory
- (file-name-as-directory
- (expand-file-name
- (make-temp-name "vc-test") temporary-file-directory)))
- (process-environment process-environment)
- tempdir
- vc-test--cleanup-hook)
- (when (eq backend 'Bzr)
- (setq tempdir (make-temp-file "vc-test--state" t)
- process-environment (cons (format "BZR_HOME=%s" tempdir)
- process-environment)))
- (unwind-protect
- (progn
- ;; Cleanup.
- (add-hook
- 'vc-test--cleanup-hook
- `(lambda () (delete-directory ,default-directory 'recursive)))
-
- ;; Create empty repository.
- (make-directory default-directory)
- (vc-test--create-repo-function backend)
-
- (let ((tmp-name (expand-file-name "foo" default-directory)))
- ;; Check state of a nonexistent file.
-
- (message "vc-state2 %s" (vc-state tmp-name))
- (should (null (vc-state tmp-name)))
-
- ;; Write a new file. Check state.
- (write-region "foo" nil tmp-name nil 'nomessage)
-
- ;; nil: Mtn
- ;; unregistered: Bzr CVS Git Hg SVN RCS
- (message "vc-state3 %s %s" backend (vc-state tmp-name backend))
- (should (memq (vc-state tmp-name backend) '(nil unregistered)))
-
- ;; Register a file. Check state.
- (vc-register
- (list backend (list (file-name-nondirectory tmp-name))))
-
- ;; FIXME: nil is definitely wrong.
- ;; nil: SRC
- ;; added: Bzr CVS Git Hg Mtn SVN
- ;; up-to-date: RCS SCCS
- (message "vc-state4 %s" (vc-state tmp-name))
- (should (memq (vc-state tmp-name) '(nil added up-to-date)))
-
- ;; Unregister the file. Check state.
- (if (eq (vc-test--run-maybe-unsupported-function
- 'vc-test--unregister-function backend tmp-name)
- 'vc-not-supported)
- (message "vc-state5 unsupported")
- ;; unregistered: Bzr Git RCS Hg
- ;; unsupported: CVS Mtn SCCS SRC SVN
- (message "vc-state5 %s %s" backend (vc-state tmp-name backend))
- (should (memq (vc-state tmp-name backend)
- '(nil unregistered))))))
-
- ;; Save exit.
- (ignore-errors
- (if tempdir (delete-directory tempdir t))
- (run-hooks 'vc-test--cleanup-hook)))))
+ (ert-with-temp-directory tempdir
+ (let ((vc-handled-backends `(,backend))
+ (default-directory
+ (file-name-as-directory
+ (expand-file-name
+ (make-temp-name "vc-test") temporary-file-directory)))
+ (process-environment process-environment)
+ vc-test--cleanup-hook)
+ (when (eq backend 'Bzr)
+ (setq process-environment (cons (format "BZR_HOME=%s" tempdir)
+ process-environment)))
+ (unwind-protect
+ (progn
+ ;; Cleanup.
+ (add-hook
+ 'vc-test--cleanup-hook
+ `(lambda () (delete-directory ,default-directory 'recursive)))
+
+ ;; Create empty repository.
+ (make-directory default-directory)
+ (vc-test--create-repo-function backend)
+
+ (let ((tmp-name (expand-file-name "foo" default-directory)))
+ ;; Check state of a nonexistent file.
+
+ (message "vc-state2 %s" (vc-state tmp-name))
+ (should (null (vc-state tmp-name)))
+
+ ;; Write a new file. Check state.
+ (write-region "foo" nil tmp-name nil 'nomessage)
+
+ ;; nil: Mtn
+ ;; unregistered: Bzr CVS Git Hg SVN RCS
+ (message "vc-state3 %s %s" backend (vc-state tmp-name backend))
+ (should (memq (vc-state tmp-name backend) '(nil unregistered)))
+
+ ;; Register a file. Check state.
+ (vc-register
+ (list backend (list (file-name-nondirectory tmp-name))))
+
+ ;; FIXME: nil is definitely wrong.
+ ;; nil: SRC
+ ;; added: Bzr CVS Git Hg Mtn SVN
+ ;; up-to-date: RCS SCCS
+ (message "vc-state4 %s" (vc-state tmp-name))
+ (should (memq (vc-state tmp-name) '(nil added up-to-date)))
+
+ ;; Unregister the file. Check state.
+ (if (eq (vc-test--run-maybe-unsupported-function
+ 'vc-test--unregister-function backend tmp-name)
+ 'vc-not-supported)
+ (message "vc-state5 unsupported")
+ ;; unregistered: Bzr Git RCS Hg
+ ;; unsupported: CVS Mtn SCCS SRC SVN
+ (message "vc-state5 %s %s" backend (vc-state tmp-name backend))
+ (should (memq (vc-state tmp-name backend)
+ '(nil unregistered))))))
+
+ ;; Save exit.
+ (ignore-errors
+ (run-hooks 'vc-test--cleanup-hook))))))
(defun vc-test--working-revision (backend)
"Check the working revision of a repository."
-
- (let ((vc-handled-backends `(,backend))
- (default-directory
- (file-name-as-directory
- (expand-file-name
- (make-temp-name "vc-test") temporary-file-directory)))
- (process-environment process-environment)
- tempdir
- vc-test--cleanup-hook)
- (when (eq backend 'Bzr)
- (setq tempdir (make-temp-file "vc-test--working-revision" t)
- process-environment (cons (format "BZR_HOME=%s" tempdir)
- process-environment)))
-
- (unwind-protect
- (progn
- ;; Cleanup.
- (add-hook
- 'vc-test--cleanup-hook
- `(lambda () (delete-directory ,default-directory 'recursive)))
-
- ;; Create empty repository. Check working revision of
- ;; repository, should be nil.
- (make-directory default-directory)
- (vc-test--create-repo-function backend)
-
- ;; FIXME: Is the value for SVN correct?
- ;; nil: Bzr CVS Git Hg Mtn RCS SCCS SRC
- ;; "0": SVN
- (message
- "vc-working-revision1 %s" (vc-working-revision default-directory))
- (should (member (vc-working-revision default-directory) '(nil "0")))
-
- (let ((tmp-name (expand-file-name "foo" default-directory)))
- ;; Check initial working revision, should be nil until
- ;; it's registered.
-
- (message "vc-working-revision2 %s" (vc-working-revision tmp-name))
- (should-not (vc-working-revision tmp-name))
-
- ;; Write a new file. Check working revision.
- (write-region "foo" nil tmp-name nil 'nomessage)
-
- (message "vc-working-revision3 %s" (vc-working-revision tmp-name))
- (should-not (vc-working-revision tmp-name))
-
- ;; Register a file. Check working revision.
- (vc-register
- (list backend (list (file-name-nondirectory tmp-name))))
-
- ;; XXX: nil is fine, at least in Git's case, because
- ;; `vc-register' only makes the file `added' in this case.
- ;; nil: Git Mtn
- ;; "0": Bzr CVS Hg SRC SVN
- ;; "1.1": RCS SCCS
- ;; "-1": Hg versions before 5 (probably)
- (message "vc-working-revision4 %s" (vc-working-revision tmp-name))
- (should (member (vc-working-revision tmp-name) '(nil "0" "1.1" "-1")))
-
- ;; TODO: Call `vc-checkin', and check the resulting
- ;; working revision. None of the return values should be
- ;; nil then.
-
- ;; Unregister the file. Check working revision.
- (if (eq (vc-test--run-maybe-unsupported-function
- 'vc-test--unregister-function backend tmp-name)
- 'vc-not-supported)
- (message "vc-working-revision5 unsupported")
- ;; nil: Bzr Git Hg RCS
- ;; unsupported: CVS Mtn SCCS SRC SVN
- (message "vc-working-revision5 %s" (vc-working-revision tmp-name))
- (should-not (vc-working-revision tmp-name)))))
-
- ;; Save exit.
- (ignore-errors
- (if tempdir (delete-directory tempdir t))
- (run-hooks 'vc-test--cleanup-hook)))))
+ (ert-with-temp-directory tempdir
+ (let ((vc-handled-backends `(,backend))
+ (default-directory
+ (file-name-as-directory
+ (expand-file-name
+ (make-temp-name "vc-test") temporary-file-directory)))
+ (process-environment process-environment)
+ vc-test--cleanup-hook)
+ (when (eq backend 'Bzr)
+ (setq process-environment (cons (format "BZR_HOME=%s" tempdir)
+ process-environment)))
+
+ (unwind-protect
+ (progn
+ ;; Cleanup.
+ (add-hook
+ 'vc-test--cleanup-hook
+ `(lambda () (delete-directory ,default-directory 'recursive)))
+
+ ;; Create empty repository. Check working revision of
+ ;; repository, should be nil.
+ (make-directory default-directory)
+ (vc-test--create-repo-function backend)
+
+ ;; FIXME: Is the value for SVN correct?
+ ;; nil: Bzr CVS Git Hg Mtn RCS SCCS SRC
+ ;; "0": SVN
+ (message
+ "vc-working-revision1 %s" (vc-working-revision default-directory))
+ (should (member (vc-working-revision default-directory) '(nil "0")))
+
+ (let ((tmp-name (expand-file-name "foo" default-directory)))
+ ;; Check initial working revision, should be nil until
+ ;; it's registered.
+
+ (message "vc-working-revision2 %s" (vc-working-revision tmp-name))
+ (should-not (vc-working-revision tmp-name))
+
+ ;; Write a new file. Check working revision.
+ (write-region "foo" nil tmp-name nil 'nomessage)
+
+ (message "vc-working-revision3 %s" (vc-working-revision tmp-name))
+ (should-not (vc-working-revision tmp-name))
+
+ ;; Register a file. Check working revision.
+ (vc-register
+ (list backend (list (file-name-nondirectory tmp-name))))
+
+ ;; XXX: nil is fine, at least in Git's case, because
+ ;; `vc-register' only makes the file `added' in this case.
+ ;; nil: Git Mtn
+ ;; "0": Bzr CVS Hg SRC SVN
+ ;; "1.1": RCS SCCS
+ ;; "-1": Hg versions before 5 (probably)
+ (message "vc-working-revision4 %s" (vc-working-revision tmp-name))
+ (should (member (vc-working-revision tmp-name) '(nil "0" "1.1" "-1")))
+
+ ;; TODO: Call `vc-checkin', and check the resulting
+ ;; working revision. None of the return values should be
+ ;; nil then.
+
+ ;; Unregister the file. Check working revision.
+ (if (eq (vc-test--run-maybe-unsupported-function
+ 'vc-test--unregister-function backend tmp-name)
+ 'vc-not-supported)
+ (message "vc-working-revision5 unsupported")
+ ;; nil: Bzr Git Hg RCS
+ ;; unsupported: CVS Mtn SCCS SRC SVN
+ (message "vc-working-revision5 %s" (vc-working-revision tmp-name))
+ (should-not (vc-working-revision tmp-name)))))
+
+ ;; Save exit.
+ (ignore-errors
+ (run-hooks 'vc-test--cleanup-hook))))))
(defun vc-test--checkout-model (backend)
"Check the checkout model of a repository."
-
- (let ((vc-handled-backends `(,backend))
- (default-directory
- (file-name-as-directory
- (expand-file-name
- (make-temp-name "vc-test") temporary-file-directory)))
- (process-environment process-environment)
- tempdir
- vc-test--cleanup-hook)
- (when (eq backend 'Bzr)
- (setq tempdir (make-temp-file "vc-test--checkout-model" t)
- process-environment (cons (format "BZR_HOME=%s" tempdir)
- process-environment)))
-
- (unwind-protect
- (progn
- ;; Cleanup.
- (add-hook
- 'vc-test--cleanup-hook
- `(lambda () (delete-directory ,default-directory 'recursive)))
-
- ;; Create empty repository. Check repository checkout model.
- (make-directory default-directory)
- (vc-test--create-repo-function backend)
-
- ;; Surprisingly, none of the backends returns 'announce.
- ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
- ;; locking: RCS SCCS
- (message
- "vc-checkout-model1 %s"
- (vc-checkout-model backend default-directory))
- (should (memq (vc-checkout-model backend default-directory)
- '(announce implicit locking)))
-
- (let ((tmp-name (expand-file-name "foo" default-directory)))
- ;; Check checkout model of a nonexistent file.
-
- ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
- ;; locking: RCS SCCS
+ (ert-with-temp-directory tempdir
+ (let ((vc-handled-backends `(,backend))
+ (default-directory
+ (file-name-as-directory
+ (expand-file-name
+ (make-temp-name "vc-test") temporary-file-directory)))
+ (process-environment process-environment)
+ vc-test--cleanup-hook)
+ (when (eq backend 'Bzr)
+ (setq process-environment (cons (format "BZR_HOME=%s" tempdir)
+ process-environment)))
+
+ (unwind-protect
+ (progn
+ ;; Cleanup.
+ (add-hook
+ 'vc-test--cleanup-hook
+ `(lambda () (delete-directory ,default-directory 'recursive)))
+
+ ;; Create empty repository. Check repository checkout model.
+ (make-directory default-directory)
+ (vc-test--create-repo-function backend)
+
+ ;; Surprisingly, none of the backends returns 'announce.
+ ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
+ ;; locking: RCS SCCS
(message
- "vc-checkout-model2 %s" (vc-checkout-model backend tmp-name))
- (should (memq (vc-checkout-model backend tmp-name)
- '(announce implicit locking)))
+ "vc-checkout-model1 %s"
+ (vc-checkout-model backend default-directory))
+ (should (memq (vc-checkout-model backend default-directory)
+ '(announce implicit locking)))
- ;; Write a new file. Check checkout model.
- (write-region "foo" nil tmp-name nil 'nomessage)
+ (let ((tmp-name (expand-file-name "foo" default-directory)))
+ ;; Check checkout model of a nonexistent file.
- ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
- ;; locking: RCS SCCS
- (message
- "vc-checkout-model3 %s" (vc-checkout-model backend tmp-name))
- (should (memq (vc-checkout-model backend tmp-name)
- '(announce implicit locking)))
+ ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
+ ;; locking: RCS SCCS
+ (message
+ "vc-checkout-model2 %s" (vc-checkout-model backend tmp-name))
+ (should (memq (vc-checkout-model backend tmp-name)
+ '(announce implicit locking)))
- ;; Register a file. Check checkout model.
- (vc-register
- (list backend (list (file-name-nondirectory tmp-name))))
+ ;; Write a new file. Check checkout model.
+ (write-region "foo" nil tmp-name nil 'nomessage)
- ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
- ;; locking: RCS SCCS
- (message
- "vc-checkout-model4 %s" (vc-checkout-model backend tmp-name))
- (should (memq (vc-checkout-model backend tmp-name)
- '(announce implicit locking)))
-
- ;; Unregister the file. Check checkout model.
- (if (eq (vc-test--run-maybe-unsupported-function
- 'vc-test--unregister-function backend tmp-name)
- 'vc-not-supported)
- (message "vc-checkout-model5 unsupported")
- ;; implicit: Bzr Git Hg
- ;; locking: RCS
- ;; unsupported: CVS Mtn SCCS SRC SVN
+ ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
+ ;; locking: RCS SCCS
(message
- "vc-checkout-model5 %s" (vc-checkout-model backend tmp-name))
+ "vc-checkout-model3 %s" (vc-checkout-model backend tmp-name))
(should (memq (vc-checkout-model backend tmp-name)
- '(announce implicit locking))))))
+ '(announce implicit locking)))
- ;; Save exit.
- (ignore-errors
- (if tempdir (delete-directory tempdir t))
- (run-hooks 'vc-test--cleanup-hook)))))
+ ;; Register a file. Check checkout model.
+ (vc-register
+ (list backend (list (file-name-nondirectory tmp-name))))
+
+ ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
+ ;; locking: RCS SCCS
+ (message
+ "vc-checkout-model4 %s" (vc-checkout-model backend tmp-name))
+ (should (memq (vc-checkout-model backend tmp-name)
+ '(announce implicit locking)))
+
+ ;; Unregister the file. Check checkout model.
+ (if (eq (vc-test--run-maybe-unsupported-function
+ 'vc-test--unregister-function backend tmp-name)
+ 'vc-not-supported)
+ (message "vc-checkout-model5 unsupported")
+ ;; implicit: Bzr Git Hg
+ ;; locking: RCS
+ ;; unsupported: CVS Mtn SCCS SRC SVN
+ (message
+ "vc-checkout-model5 %s" (vc-checkout-model backend tmp-name))
+ (should (memq (vc-checkout-model backend tmp-name)
+ '(announce implicit locking))))))
+
+ ;; Save exit.
+ (ignore-errors
+ (run-hooks 'vc-test--cleanup-hook))))))
+
+(defun vc-test--rename-file (backend)
+ "Check the rename-file action."
+ (ert-with-temp-directory tempdir
+ (let ((vc-handled-backends `(,backend))
+ (default-directory
+ (file-name-as-directory
+ (expand-file-name
+ (make-temp-name "vc-test") temporary-file-directory)))
+ (process-environment process-environment)
+ vc-test--cleanup-hook)
+ (when (eq backend 'Bzr)
+ (setq process-environment (cons (format "BZR_HOME=%s" tempdir)
+ process-environment)))
+
+ (unwind-protect
+ (progn
+ ;; Cleanup.
+ (add-hook
+ 'vc-test--cleanup-hook
+ `(lambda () (delete-directory ,default-directory 'recursive)))
+
+ ;; Create empty repository.
+ (make-directory default-directory)
+ (vc-test--create-repo-function backend)
+
+ (let ((tmp-name (expand-file-name "foo" default-directory))
+ (new-name (expand-file-name "bar" default-directory)))
+ ;; Write a new file.
+ (write-region "foo" nil tmp-name nil 'nomessage)
+
+ ;; Register it. Renaming can fail otherwise.
+ (vc-register
+ (list backend (list (file-name-nondirectory tmp-name))))
+
+ (vc-rename-file tmp-name new-name)
+
+ (should (not (file-exists-p tmp-name)))
+ (should (file-exists-p new-name))
+
+ (should (equal (vc-state new-name)
+ (if (memq backend '(RCS SCCS))
+ 'up-to-date
+ 'added)))))
+
+ ;; Save exit.
+ (ignore-errors
+ (run-hooks 'vc-test--cleanup-hook))))))
+
+(declare-function log-edit-done "vc/log-edit")
+
+(defun vc-test--version-diff (backend)
+ "Check the diff version of a repository."
+ (ert-with-temp-directory tempdir
+ (let ((vc-handled-backends `(,backend))
+ (default-directory
+ (file-name-as-directory
+ (expand-file-name
+ (make-temp-name "vc-test") temporary-file-directory)))
+ (process-environment process-environment)
+ vc-test--cleanup-hook)
+ (when (eq backend 'Bzr)
+ (setq process-environment (cons (format "BZR_HOME=%s" tempdir)
+ process-environment)))
+ ;; git tries various approaches to guess a user name and email,
+ ;; which can fail depending on how the system is configured.
+ ;; Eg if the user account has no GECOS, git commit can fail with
+ ;; status 128 "fatal: empty ident name".
+ (when (memq backend '(Bzr Git))
+ (setq process-environment (cons "EMAIL=john@doe.ee"
+ process-environment)))
+ (if (eq backend 'Git)
+ (setq process-environment (append '("GIT_AUTHOR_NAME=A"
+ "GIT_COMMITTER_NAME=C")
+ process-environment)))
+ (unwind-protect
+ (progn
+ ;; Cleanup.
+ (add-hook
+ 'vc-test--cleanup-hook
+ `(lambda () (delete-directory ,default-directory 'recursive)))
+
+ ;; Create empty repository. Check repository checkout model.
+ (make-directory default-directory)
+ (vc-test--create-repo-function backend)
+
+ (let* ((tmp-name (expand-file-name "foo" default-directory))
+ (files (list (file-name-nondirectory tmp-name))))
+ ;; Write and register a new file.
+ (write-region "originaltext" nil tmp-name nil 'nomessage)
+ (vc-register (list backend files))
+
+ (let ((buff (find-file tmp-name)))
+ (with-current-buffer buff
+ (progn
+ ;; Optionally checkout file.
+ (when (memq backend '(RCS CVS SCCS))
+ (vc-checkout tmp-name))
+
+ ;; Checkin file.
+ (vc-checkin files backend)
+ (insert "Testing vc-version-diff")
+ (log-edit-done))))
+
+ ;; Modify file content.
+ (when (memq backend '(RCS CVS SCCS))
+ (vc-checkout tmp-name))
+ (write-region "updatedtext" nil tmp-name nil 'nomessage)
+
+ ;; Check version diff.
+ (vc-version-diff files nil nil)
+ (should (bufferp (get-buffer "*vc-diff*")))
+
+ (with-current-buffer "*vc-diff*"
+ (progn
+ (let ((rawtext (buffer-substring-no-properties (point-min)
+ (point-max))))
+ (should (string-search "-originaltext" rawtext))
+ (should (string-search "+updatedtext" rawtext)))))))
+
+ ;; Save exit.
+ (ignore-errors
+ (run-hooks 'vc-test--cleanup-hook))))))
;; Create the test cases.
@@ -648,7 +758,35 @@ This checks also `vc-backend' and `vc-responsible-backend'."
(ert-get-test
',(intern
(format "vc-test-%s01-register" backend-string))))))
- (vc-test--checkout-model ',backend))))))
+ (vc-test--checkout-model ',backend))
+
+ (ert-deftest
+ ,(intern (format "vc-test-%s05-rename-file" backend-string)) ()
+ ,(format "Check `vc-rename-file' for the %s backend."
+ backend-string)
+ (skip-unless
+ (ert-test-passed-p
+ (ert-test-most-recent-result
+ (ert-get-test
+ ',(intern
+ (format "vc-test-%s01-register" backend-string))))))
+ ;; CVS calls vc-delete-file, which insists on prompting
+ ;; "Really want to delete ...?"
+ (skip-unless (not (eq 'CVS ',backend)))
+ (vc-test--rename-file ',backend))
+
+ (ert-deftest
+ ,(intern (format "vc-test-%s06-version-diff" backend-string)) ()
+ ,(format "Check `vc-version-diff' for the %s backend."
+ backend-string)
+ (skip-unless
+ (ert-test-passed-p
+ (ert-test-most-recent-result
+ (ert-get-test
+ ',(intern
+ (format "vc-test-%s01-register" backend-string))))))
+ (vc-test--version-diff ',backend))
+ ))))
(provide 'vc-tests)
;;; vc-tests.el ends here
diff --git a/test/lisp/wdired-tests.el b/test/lisp/wdired-tests.el
index 96a01fc2c7b..47ed26f609d 100644
--- a/test/lisp/wdired-tests.el
+++ b/test/lisp/wdired-tests.el
@@ -20,7 +20,9 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'dired)
+(require 'dired-x)
(require 'wdired)
(defvar dired-query) ; Pacify byte compiler.
@@ -28,108 +30,100 @@
(ert-deftest wdired-test-bug32173-01 ()
"Test using non-nil wdired-use-interactive-rename.
Partially modifying a file name should succeed."
- (let* ((test-dir (make-temp-file "test-dir-" t))
- (test-file (concat (file-name-as-directory test-dir) "foo.c"))
- (replace "bar")
- (new-file (string-replace "foo" replace test-file))
- (wdired-use-interactive-rename t))
- (write-region "" nil test-file nil 'silent)
- (advice-add 'dired-query ; Don't ask confirmation to overwrite a file.
- :override
- (lambda (_sym _prompt &rest _args) (setq dired-query t))
- '((name . "advice-dired-query")))
- (let ((buf (find-file-noselect test-dir)))
- (unwind-protect
- (with-current-buffer buf
- (should (equal (dired-file-name-at-point) test-file))
- (dired-toggle-read-only)
- (kill-region (point) (progn (search-forward ".")
- (forward-char -1) (point)))
- (insert replace)
- (wdired-finish-edit)
- (should (equal (dired-file-name-at-point) new-file)))
- (if buf (kill-buffer buf))
- (delete-directory test-dir t)))))
+ (ert-with-temp-directory test-dir
+ (let* ((test-file (concat (file-name-as-directory test-dir) "foo.c"))
+ (replace "bar")
+ (new-file (string-replace "foo" replace test-file))
+ (wdired-use-interactive-rename t))
+ (write-region "" nil test-file nil 'silent)
+ (advice-add 'dired-query ; Don't ask confirmation to overwrite a file.
+ :override
+ (lambda (_sym _prompt &rest _args) (setq dired-query t))
+ '((name . "advice-dired-query")))
+ (let ((buf (find-file-noselect test-dir)))
+ (unwind-protect
+ (with-current-buffer buf
+ (should (equal (dired-file-name-at-point) test-file))
+ (dired-toggle-read-only)
+ (kill-region (point) (progn (search-forward ".")
+ (forward-char -1) (point)))
+ (insert replace)
+ (wdired-finish-edit)
+ (should (equal (dired-file-name-at-point) new-file)))
+ (if buf (kill-buffer buf)))))))
(ert-deftest wdired-test-bug32173-02 ()
"Test using non-nil wdired-use-interactive-rename.
Aborting an edit should leaving original file name unchanged."
- (let* ((test-dir (make-temp-file "test-dir-" t))
- (test-file (concat (file-name-as-directory test-dir) "foo.c"))
- (wdired-use-interactive-rename t))
- (write-region "" nil test-file nil 'silent)
- ;; Make dired-do-create-files-regexp a noop to mimic typing C-g
- ;; at its prompt before wdired-finish-edit returns.
- (advice-add 'dired-do-create-files-regexp
- :override
- (lambda (&rest _) (ignore))
- '((name . "advice-dired-do-create-files-regexp")))
- (let ((buf (find-file-noselect test-dir)))
- (unwind-protect
- (with-current-buffer buf
- (should (equal (dired-file-name-at-point) test-file))
- (dired-toggle-read-only)
- (kill-region (point) (progn (search-forward ".")
- (forward-char -1) (point)))
- (insert "bar")
- (wdired-finish-edit)
- (should (equal (dired-get-filename) test-file)))
- (if buf (kill-buffer buf))
- (delete-directory test-dir t)))))
+ (ert-with-temp-directory test-dir
+ (let* ((test-file (concat (file-name-as-directory test-dir) "foo.c"))
+ (wdired-use-interactive-rename t))
+ (write-region "" nil test-file nil 'silent)
+ ;; Make dired-do-create-files-regexp a noop to mimic typing C-g
+ ;; at its prompt before wdired-finish-edit returns.
+ (advice-add 'dired-do-create-files-regexp
+ :override
+ (lambda (&rest _) (ignore))
+ '((name . "advice-dired-do-create-files-regexp")))
+ (let ((buf (find-file-noselect test-dir)))
+ (unwind-protect
+ (with-current-buffer buf
+ (should (equal (dired-file-name-at-point) test-file))
+ (dired-toggle-read-only)
+ (kill-region (point) (progn (search-forward ".")
+ (forward-char -1) (point)))
+ (insert "bar")
+ (wdired-finish-edit)
+ (should (equal (dired-get-filename) test-file)))
+ (if buf (kill-buffer buf)))))))
(ert-deftest wdired-test-symlink-name ()
"Test the file name of a symbolic link.
The Dired and WDired functions returning the name should include
only the name before the link arrow."
- (let* ((test-dir (make-temp-file "test-dir-" t))
- (link-name "foo"))
- (let ((buf (find-file-noselect test-dir)))
- (unwind-protect
- (with-current-buffer buf
- (skip-unless
- ;; This check is for wdired, not symbolic links, so skip
- ;; it when make-symbolic-link fails for any reason (like
- ;; insufficient privileges).
- (ignore-errors (make-symbolic-link "./bar/baz" link-name) t))
- (revert-buffer)
- (let* ((file-name (dired-get-filename))
- (dir-part (file-name-directory file-name))
- (lf-name (concat dir-part link-name)))
- (should (equal file-name lf-name))
- (dired-toggle-read-only)
- (should (equal (wdired-get-filename) lf-name))
- (dired-toggle-read-only)))
- (if buf (kill-buffer buf))
- (delete-directory test-dir t)))))
+ (ert-with-temp-directory test-dir
+ (let* ((link-name "foo"))
+ (let ((buf (find-file-noselect test-dir)))
+ (unwind-protect
+ (with-current-buffer buf
+ (skip-unless
+ ;; This check is for wdired, not symbolic links, so skip
+ ;; it when make-symbolic-link fails for any reason (like
+ ;; insufficient privileges).
+ (ignore-errors (make-symbolic-link "./bar/baz" link-name) t))
+ (revert-buffer)
+ (let* ((file-name (dired-get-filename))
+ (dir-part (file-name-directory file-name))
+ (lf-name (concat dir-part link-name)))
+ (should (equal file-name lf-name))
+ (dired-toggle-read-only)
+ (should (equal (wdired-get-filename) lf-name))
+ (dired-toggle-read-only)))
+ (if buf (kill-buffer buf)))))))
(ert-deftest wdired-test-unfinished-edit-01 ()
"Test editing a file name without saving the change.
Finding the new name should be possible while still in
wdired-mode."
- (let* ((test-dir (make-temp-file "test-dir-" t))
- (test-file (concat (file-name-as-directory test-dir) "foo.c"))
- (replace "bar")
- (new-file (string-replace "foo" replace test-file)))
- (write-region "" nil test-file nil 'silent)
- (let ((buf (find-file-noselect test-dir)))
- (unwind-protect
- (with-current-buffer buf
- (should (equal (dired-file-name-at-point) test-file))
- (dired-toggle-read-only)
- (kill-region (point) (progn (search-forward ".")
- (forward-char -1) (point)))
- (insert replace)
- (should (equal (dired-get-filename) new-file)))
- (when buf
- (with-current-buffer buf
- ;; Prevent kill-buffer-query-functions from chiming in.
- (set-buffer-modified-p nil)
- (kill-buffer buf)))
- (delete-directory test-dir t)))))
-
-(defvar server-socket-dir)
-(declare-function dired-smart-shell-command "dired-x"
- (command &optional output-buffer error-buffer))
+ (ert-with-temp-directory test-dir
+ (let* ((test-file (concat (file-name-as-directory test-dir) "foo.c"))
+ (replace "bar")
+ (new-file (string-replace "foo" replace test-file)))
+ (write-region "" nil test-file nil 'silent)
+ (let ((buf (find-file-noselect test-dir)))
+ (unwind-protect
+ (with-current-buffer buf
+ (should (equal (dired-file-name-at-point) test-file))
+ (dired-toggle-read-only)
+ (kill-region (point) (progn (search-forward ".")
+ (forward-char -1) (point)))
+ (insert replace)
+ (should (equal (dired-get-filename) new-file)))
+ (when buf
+ (with-current-buffer buf
+ ;; Prevent kill-buffer-query-functions from chiming in.
+ (set-buffer-modified-p nil)
+ (kill-buffer buf))))))))
(ert-deftest wdired-test-bug34915 ()
"Test editing when dired-listing-switches includes -F.
@@ -139,61 +133,61 @@ dired-move-to-end-of-filename handles indicator characters, it
suffices to compare the return values of dired-get-filename and
wdired-get-filename before and after editing."
;; FIXME: Add a test for a door (indicator ">") only under Solaris?
- (let* ((test-dir (make-temp-file "test-dir-" t))
- (server-socket-dir test-dir)
- (dired-listing-switches "-Fl")
- (dired-ls-F-marks-symlinks (eq system-type 'darwin))
- (buf (find-file-noselect test-dir)))
- (unwind-protect
- (progn
- (with-current-buffer buf
- (dired-create-empty-file "foo")
- (set-file-modes "foo" (file-modes-symbolic-to-number "+x"))
- (make-symbolic-link "foo" "bar")
- (make-directory "foodir")
- (require 'dired-x)
- (dired-smart-shell-command "mkfifo foopipe")
- (server-force-delete)
- ;; FIXME? This seems a heavy-handed way of making a socket.
- (server-start) ; Add a socket file.
- (kill-buffer buf))
- (dired test-dir)
- (dired-toggle-read-only)
- (let (names)
- ;; Test that the file names are the same in Dired and WDired.
- (while (not (eobp))
- (should (equal (dired-get-filename 'no-dir t)
- (wdired-get-filename t)))
- (insert "w")
- (push (wdired-get-filename t) names)
- (dired-next-line 1))
- (wdired-finish-edit)
- ;; Test that editing the file names ignores the indicator
- ;; character.
- (let (dir)
- (while (and (dired-previous-line 1)
- (setq dir (dired-get-filename 'no-dir t)))
- (should (equal dir (pop names)))))))
- (kill-buffer (get-buffer test-dir))
- (server-force-delete)
- (delete-directory test-dir t))))
+ (ert-with-temp-directory test-dir
+ (let* ((dired-listing-switches "-Fl")
+ (dired-ls-F-marks-symlinks (eq system-type 'darwin))
+ (buf (find-file-noselect test-dir))
+ proc)
+ (unwind-protect
+ (progn
+ (with-current-buffer buf
+ (dired-create-empty-file "foo")
+ (set-file-modes "foo" (file-modes-symbolic-to-number "+x"))
+ (make-symbolic-link "foo" "bar")
+ (make-directory "foodir")
+ (dired-smart-shell-command "mkfifo foopipe")
+ (when (featurep 'make-network-process '(:family local))
+ (setq proc (make-network-process
+ :name "foo"
+ :family 'local
+ :server t
+ :service (expand-file-name "foosocket" test-dir))))
+ (kill-buffer buf))
+ (dired test-dir)
+ (dired-toggle-read-only)
+ (let (names)
+ ;; Test that the file names are the same in Dired and WDired.
+ (while (not (eobp))
+ (should (equal (dired-get-filename 'no-dir t)
+ (wdired-get-filename t)))
+ (insert "w")
+ (push (wdired-get-filename t) names)
+ (dired-next-line 1))
+ (wdired-finish-edit)
+ ;; Test that editing the file names ignores the indicator
+ ;; character.
+ (let (dir)
+ (while (and (dired-previous-line 1)
+ (setq dir (dired-get-filename 'no-dir t)))
+ (should (equal dir (pop names)))))))
+ (kill-buffer (get-buffer test-dir))
+ (ignore-errors (delete-process proc))))))
(ert-deftest wdired-test-bug39280 ()
"Test for https://debbugs.gnu.org/39280."
- (let* ((test-dir (make-temp-file "test-dir" 'dir))
- (fname "foo")
- (full-fname (expand-file-name fname test-dir)))
- (make-empty-file full-fname)
- (let ((buf (find-file-noselect test-dir)))
- (unwind-protect
- (with-current-buffer buf
- (dired-toggle-read-only)
- (dolist (old '(t nil))
- (should (equal fname (wdired-get-filename 'nodir old)))
- (should (equal full-fname (wdired-get-filename nil old))))
- (wdired-finish-edit))
- (if buf (kill-buffer buf))
- (delete-directory test-dir t)))))
+ (ert-with-temp-directory test-dir
+ (let* ((fname "foo")
+ (full-fname (expand-file-name fname test-dir)))
+ (make-empty-file full-fname)
+ (let ((buf (find-file-noselect test-dir)))
+ (unwind-protect
+ (with-current-buffer buf
+ (dired-toggle-read-only)
+ (dolist (old '(t nil))
+ (should (equal fname (wdired-get-filename 'nodir old)))
+ (should (equal full-fname (wdired-get-filename nil old))))
+ (wdired-finish-edit))
+ (if buf (kill-buffer buf)))))))
(provide 'wdired-tests)
;;; wdired-tests.el ends here
diff --git a/test/lisp/whitespace-tests.el b/test/lisp/whitespace-tests.el
index 9f54a4fd340..1001476a286 100644
--- a/test/lisp/whitespace-tests.el
+++ b/test/lisp/whitespace-tests.el
@@ -51,7 +51,7 @@
;; We cannot call whitespace-mode because it will do nothing in batch
;; mode. So we call its innards instead.
(defun whitespace-tests-whitespace-mode-on ()
- "Turn whitespace-mode on even in batch mode."
+ "Turn `whitespace-mode' on even in batch mode."
(whitespace-turn-on)
(whitespace-action-when-on)
(setq whitespace-mode t))
diff --git a/test/lisp/xml-tests.el b/test/lisp/xml-tests.el
index b00b58acfc5..7c64ef39f8d 100644
--- a/test/lisp/xml-tests.el
+++ b/test/lisp/xml-tests.el
@@ -78,7 +78,7 @@
;; Bug#16344
"<!----><x>< /x>"
"<a>< b/></a>")
- "List of XML strings that should signal an error in the parser")
+ "List of XML strings that should signal an error in the parser.")
(defvar xml-parse-tests--qnames
'( ;; Test data for name expansion
@@ -199,4 +199,4 @@ Parser is called with and without 'symbol-qnames argument.")
;; no-byte-compile: t
;; End:
-;;; xml-parse-tests.el ends here.
+;;; xml-tests.el ends here
diff --git a/test/manual/BidiCharacterTest.txt b/test/manual/BidiCharacterTest.txt
index 02e2083ee66..c30d0778612 100644
--- a/test/manual/BidiCharacterTest.txt
+++ b/test/manual/BidiCharacterTest.txt
@@ -1,6 +1,6 @@
-# BidiCharacterTest-13.0.0.txt
-# Date: 2019-09-09, 19:32:00 GMT [LI]
-# © 2019 Unicode®, Inc.
+# 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
#
# Unicode Character Database
@@ -87,6 +87,32 @@
0661 0028 0662 0029 0331;0;0;2 1 2 1 1;4 3 2 1 0
0661 0028 0332 0662 0029 0333;0;0;2 1 1 2 1 1;5 4 3 2 1 0
+# Nonspacing marks applied to paired brackets [added to test cases for Unicode 14.0]
+# These cases exercise the ignoring of bc=BN characters (such as ZWJ or ZWSP)
+# that appear between the base bracket character and the nonspacing mark,
+# in a context where the brackets have been forced to a strong R direction.
+#
+# Note that due to an implementation error in the N0 rule in the Bidi Reference C
+# test code for UBA 8.0, versions of that reference test code through UBA 12.0 will fail for
+# precisely these newly added tests. The bug in the implementation of the N0 rule in the Bidi Reference C
+# test code was fixed for Unicode 13.0, and that updated test code now performs correctly
+# for all versions of UBA.
+#
+# These test cases first test a combining mark following a ZWJ after the trailing bracket of a pair:
+0041 200F 005B 05D0 005D 200D 20D6;0;0;0 1 1 1 1 x 1;0 6 4 3 2 1
+0041 200F 005B 05D0 005D 200D 20D6;1;1;2 1 1 1 1 x 1;6 4 3 2 1 0
+# Then a combining mark following a ZWJ after the leading bracket of a pair:
+0041 200F 005B 200D 20D6 05D0 005D;0;0;0 1 1 x 1 1 1;0 6 5 4 2 1
+0041 200F 005B 200D 20D6 05D0 005D;1;1;2 1 1 x 1 1 1;6 5 4 2 1 0
+# Then a combining mark following a ZWJ after both brackets of a pair:
+0041 200F 005B 200D 20D6 05D0 005D 200D 20D6;0;0;0 1 1 x 1 1 1 x 1;0 8 6 5 4 2 1
+0041 200F 005B 200D 20D6 05D0 005D 200D 20D6;1;1;2 1 1 x 1 1 1 x 1;8 6 5 4 2 1 0
+# Then the intervention of a ZWSP in these same sequences.
+# (The ZWSP formally breaks the combining character sequence, but should
+# not block the identification of the combining mark for the application of rule N0.)
+0041 200F 005B 200D 200B 20D6 05D0 005D 200B 200D 20D6;0;0;0 1 1 x x 1 1 1 x x 1;0 10 7 6 5 2 1
+0041 200F 005B 200D 200B 20D6 05D0 005D 200B 200D 20D6;1;1;2 1 1 x x 1 1 1 x x 1;10 7 6 5 2 1 0
+
# Nested bracket pairs that reach and exceed the fixed capacity of the bracket stack
# a ( ( ... ( b ) ) ... ) with 62, 63, and 64 nested bracket pairs
0061 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0028 0062 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029 0029;1;1;2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2;0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
diff --git a/test/manual/biditest.el b/test/manual/biditest.el
index a77fc158807..c84e7ed7310 100644
--- a/test/manual/biditest.el
+++ b/test/manual/biditest.el
@@ -121,3 +121,5 @@ BidiCharacterTest.txt file."
(message "%s" (bidi-resolved-levels)))
(define-key global-map [f8] #'bidi-levels)
+
+;;; biditest.el ends here
diff --git a/test/manual/cedet/cedet-utests.el b/test/manual/cedet/cedet-utests.el
index d68b5b8c090..af6b4defb3c 100644
--- a/test/manual/cedet/cedet-utests.el
+++ b/test/manual/cedet/cedet-utests.el
@@ -252,9 +252,7 @@ Optional argument TITLE is the title of this testing session."
(defun cedet-utest-elapsed-time (start end)
"Copied from elp.el. Was elp-elapsed-time.
Argument START and END bound the time being calculated."
- (+ (* (- (car end) (car start)) 65536.0)
- (- (car (cdr end)) (car (cdr start)))
- (/ (- (car (cdr (cdr end))) (car (cdr (cdr start)))) 1000000.0)))
+ (float-time (time-subtract start end)))
(defun cedet-utest-log-shutdown (title &optional _errorcondition)
"Shut-down a larger test suite.
diff --git a/test/manual/cedet/ede-tests.el b/test/manual/cedet/ede-tests.el
index 2af50860c60..17618381ef2 100644
--- a/test/manual/cedet/ede-tests.el
+++ b/test/manual/cedet/ede-tests.el
@@ -80,4 +80,4 @@ The search is done with the current EDE root."
(ede-locate-file-in-project loc file)
(data-debug-insert-object-slots loc "]")))
-;;; ede-test.el ends here
+;;; ede-tests.el ends here
diff --git a/test/manual/cedet/semantic-tests.el b/test/manual/cedet/semantic-tests.el
index 1561c18dd68..3e416cc6b20 100644
--- a/test/manual/cedet/semantic-tests.el
+++ b/test/manual/cedet/semantic-tests.el
@@ -24,6 +24,8 @@
;; Originally, there are many test functions scattered among the
;; Semantic source files. This file consolidates them.
+;;; Code:
+
(require 'data-debug)
;;; From semantic-complete
@@ -46,7 +48,7 @@
All systems are different. Ask questions along the way."
(interactive)
(let ((doload nil))
- (when (y-or-n-p "Create a system database to test with? ")
+ (when (y-or-n-p "Create a system database to test with?")
(call-interactively 'semanticdb-create-ebrowse-database)
(setq doload t))
;; Should we load in caches
@@ -269,3 +271,5 @@ tag that contains point, and return that."
Lcount (semantic-tag-name target)
(semantic-elapsed-time start nil)))
Lcount)))
+
+;;; semantic-tests.el ends here
diff --git a/test/manual/cedet/tests/test.el b/test/manual/cedet/tests/test.el
index d1d0d1602f4..34c03619f88 100644
--- a/test/manual/cedet/tests/test.el
+++ b/test/manual/cedet/tests/test.el
@@ -19,31 +19,29 @@
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-;;; Require
-;;
+;;; Code:
+
(require 'semantic)
(require 'eieio "../eieio")
;; tags encapsulated in eval-when-compile and eval-and-compile
;; should be expanded out into the outer environment.
(eval-when-compile
- (require 'semantic-imenu)
- )
+ (require 'semantic-imenu))
(eval-and-compile
(defconst const-1 nil)
(defun function-1 (arg)
- nil)
- )
+ nil))
;;; Functions
;;
(defun a-defun (arg1 arg2 &optional arg3)
- "doc a"
+ "Doc a."
nil)
(defun a-defun-interactive (arg1 arg2 &optional arg3)
- "doc a that is a command"
+ "Doc a that is a command."
(interactive "R")
nil)
@@ -52,15 +50,15 @@
nil)
(defsubst a-defsubst (arg1 arg2 &optional arg3)
- "doc a-subst"
+ "Doc a-subst."
nil)
(defmacro a-defmacro (arg1 arg2 &optional arg3)
- "doc a-macro"
+ "Doc a-macro."
nil)
(define-overload a-overload (arg)
- "doc a-overload"
+ "Doc a-overload."
nil)
;;; Methods
@@ -81,16 +79,16 @@
;;; Variables
;;
(defvar a-defvar (cons 1 2)
- "Variable a")
+ "Variable a.")
;; FIXME: This practice is not recommended in recent Emacs. Remove?
(defvar a-defvar-star (cons 1 2)
- "*User visible var a")
+ "*User visible var a.")
-(defconst a-defconst 'a "var doc const")
+(defconst a-defconst 'a "Var doc const.")
(defcustom a-defcustom nil
- "doc custom"
+ "Doc custom."
:group 'a-defgroup
:type 'boolean)
@@ -111,7 +109,7 @@
(defgroup a-defgroup nil
- "Group for `emacs-lisp' regression-test")
+ "Group for `emacs-lisp' regression-test.")
;;; Classes
;;
@@ -154,3 +152,5 @@
"some value")
(provide 'test)
+
+;;; test.el ends here
diff --git a/test/manual/etags/el-src/emacs/lisp/progmodes/etags.el b/test/manual/etags/el-src/emacs/lisp/progmodes/etags.el
index 36f6624472d..86cc8825466 100644
--- a/test/manual/etags/el-src/emacs/lisp/progmodes/etags.el
+++ b/test/manual/etags/el-src/emacs/lisp/progmodes/etags.el
@@ -732,7 +732,7 @@ Returns t if it visits a tags table, or nil if there are no more in the list."
"Return the file name of the file whose tags point is within.
Assumes the tags table is the current buffer.
If RELATIVE is non-nil, file name returned is relative to tags
-table file's directory. If RELATIVE is nil, file name returned
+table file's directory. If RELATIVE is nil, file name returned
is complete."
(funcall file-of-tag-function relative))
diff --git a/test/manual/image-size-tests.el b/test/manual/image-size-tests.el
index 44846a7a67a..067a0bfc8e2 100644
--- a/test/manual/image-size-tests.el
+++ b/test/manual/image-size-tests.el
@@ -17,6 +17,8 @@
;; 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:
+
;; To test: Load the file and eval (image-size-tests).
;; A non-erroring result is a success.
diff --git a/test/manual/image-transforms-tests.el b/test/manual/image-transforms-tests.el
index debb74f2edb..acbaed5c0b6 100644
--- a/test/manual/image-transforms-tests.el
+++ b/test/manual/image-transforms-tests.el
@@ -174,3 +174,5 @@
(test-scaling)
(test-scaling-rotation)
(goto-char (point-min))))
+
+;;; image-transforms-tests.el ends here
diff --git a/test/manual/redisplay-testsuite.el b/test/manual/redisplay-testsuite.el
index 8e90f2d7a5c..8a4828417c8 100644
--- a/test/manual/redisplay-testsuite.el
+++ b/test/manual/redisplay-testsuite.el
@@ -350,3 +350,5 @@ static unsigned char x_bits[] = {0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xbd, 0x81, 0xff
(test-redisplay-4)
(test-redisplay-5)
(goto-char (point-min))))
+
+;;; redisplay-testsuite.el ends here
diff --git a/test/misc/test-custom-libs.el b/test/misc/test-custom-libs.el
index cc2be99dea8..d826dfbcab4 100644
--- a/test/misc/test-custom-libs.el
+++ b/test/misc/test-custom-libs.el
@@ -19,7 +19,7 @@
;;; Commentary:
-;; This file runs for all libraries with autoloads separate emacs
+;; This file runs for all libraries with autoloads separate Emacs
;; processes of the form "emacs -batch -l LIB".
;;; Code:
@@ -45,4 +45,4 @@
(cus-test-libs t)
(should-not cus-test-libs-errors))
-;;; test-custom-deps.el ends here
+;;; test-custom-libs.el ends here
diff --git a/test/src/alloc-tests.el b/test/src/alloc-tests.el
index 1324c2d3b4d..5383c436035 100644
--- a/test/src/alloc-tests.el
+++ b/test/src/alloc-tests.el
@@ -58,3 +58,5 @@
(dolist (c (list 10003 ?b 128 ?c ?d (max-char) ?e))
(aset s 0 c)
(should (equal s (make-string 1 c))))))
+
+;;; alloc-tests.el ends here
diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el
index 118311c4d26..9b7023d18b9 100644
--- a/test/src/buffer-tests.el
+++ b/test/src/buffer-tests.el
@@ -19,6 +19,8 @@
;;; Code:
+(require 'ert)
+(require 'ert-x)
(require 'cl-lib)
(ert-deftest overlay-modification-hooks-message-other-buf ()
@@ -145,7 +147,7 @@ with parameters from the *Messages* buffer modification."
(defmacro deftest-overlayp-1 (id arg-expr should-expr)
(declare (indent 1))
- `(ert-deftest ,(buffer-tests--make-test-name 'overlay-buffer 1 id) ()
+ `(ert-deftest ,(buffer-tests--make-test-name 'overlayp 1 id) ()
(with-temp-buffer
(should (equal ,should-expr (overlayp ,arg-expr))))))
@@ -434,14 +436,14 @@ with parameters from the *Messages* buffer modification."
(deftest-next-overlay-change-1 I 10 (point-max) (10 10))
(deftest-next-overlay-change-1 J 20 (point-max) (10 10))
;; 2 non-empty, non-intersecting
-(deftest-next-overlay-change-1 D 10 20 (20 30) (40 50))
-(deftest-next-overlay-change-1 E 35 40 (20 30) (40 50))
-(deftest-next-overlay-change-1 F 60 (point-max) (20 30) (40 50))
-(deftest-next-overlay-change-1 G 30 40 (20 30) (40 50))
-(deftest-next-overlay-change-1 H 50 (point-max) (20 30) (40 50))
+(deftest-next-overlay-change-1 D2 10 20 (20 30) (40 50))
+(deftest-next-overlay-change-1 E2 35 40 (20 30) (40 50))
+(deftest-next-overlay-change-1 F2 60 (point-max) (20 30) (40 50))
+(deftest-next-overlay-change-1 G2 30 40 (20 30) (40 50))
+(deftest-next-overlay-change-1 H2 50 (point-max) (20 30) (40 50))
;; 2 non-empty, intersecting
-(deftest-next-overlay-change-1 I 10 20 (20 30) (25 35))
-(deftest-next-overlay-change-1 J 20 25 (20 30) (25 35))
+(deftest-next-overlay-change-1 I2 10 20 (20 30) (25 35))
+(deftest-next-overlay-change-1 J2 20 25 (20 30) (25 35))
(deftest-next-overlay-change-1 K 23 25 (20 30) (25 35))
(deftest-next-overlay-change-1 L 25 30 (20 30) (25 35))
(deftest-next-overlay-change-1 M 28 30 (20 30) (25 35))
@@ -471,11 +473,11 @@ with parameters from the *Messages* buffer modification."
(deftest-next-overlay-change-1 k 30 (point-max) (20 20) (20 30))
(deftest-next-overlay-change-1 l 40 (point-max) (20 20) (20 30))
;; 1 empty, 1 non-empty, intersecting at end
-(deftest-next-overlay-change-1 h 10 20 (30 30) (20 30))
-(deftest-next-overlay-change-1 i 20 30 (30 30) (20 30))
-(deftest-next-overlay-change-1 j 25 30 (30 30) (20 30))
-(deftest-next-overlay-change-1 k 30 (point-max) (20 20) (20 30))
-(deftest-next-overlay-change-1 l 40 (point-max) (20 20) (20 30))
+(deftest-next-overlay-change-1 h2 10 20 (30 30) (20 30))
+(deftest-next-overlay-change-1 i2 20 30 (30 30) (20 30))
+(deftest-next-overlay-change-1 j2 25 30 (30 30) (20 30))
+(deftest-next-overlay-change-1 k2 30 (point-max) (20 20) (20 30))
+(deftest-next-overlay-change-1 l2 40 (point-max) (20 20) (20 30))
;; 1 empty, 1 non-empty, intersecting in the middle
(deftest-next-overlay-change-1 m 10 20 (25 25) (20 30))
(deftest-next-overlay-change-1 n 20 25 (25 25) (20 30))
@@ -522,14 +524,14 @@ with parameters from the *Messages* buffer modification."
(deftest-previous-overlay-change-1 I 10 1 (10 10))
(deftest-previous-overlay-change-1 J 20 10 (10 10))
;; 2 non-empty, non-intersecting
-(deftest-previous-overlay-change-1 D 10 1 (20 30) (40 50))
-(deftest-previous-overlay-change-1 E 35 30 (20 30) (40 50))
-(deftest-previous-overlay-change-1 F 60 50 (20 30) (40 50))
-(deftest-previous-overlay-change-1 G 30 20 (20 30) (40 50))
-(deftest-previous-overlay-change-1 H 50 40 (20 30) (40 50))
+(deftest-previous-overlay-change-1 D2 10 1 (20 30) (40 50))
+(deftest-previous-overlay-change-1 E2 35 30 (20 30) (40 50))
+(deftest-previous-overlay-change-1 F2 60 50 (20 30) (40 50))
+(deftest-previous-overlay-change-1 G2 30 20 (20 30) (40 50))
+(deftest-previous-overlay-change-1 H2 50 40 (20 30) (40 50))
;; 2 non-empty, intersecting
-(deftest-previous-overlay-change-1 I 10 1 (20 30) (25 35))
-(deftest-previous-overlay-change-1 J 20 1 (20 30) (25 35))
+(deftest-previous-overlay-change-1 I2 10 1 (20 30) (25 35))
+(deftest-previous-overlay-change-1 J2 20 1 (20 30) (25 35))
(deftest-previous-overlay-change-1 K 23 20 (20 30) (25 35))
(deftest-previous-overlay-change-1 L 25 20 (20 30) (25 35))
(deftest-previous-overlay-change-1 M 28 25 (20 30) (25 35))
@@ -619,28 +621,28 @@ with parameters from the *Messages* buffer modification."
(deftest-overlays-at-1 P 50 () (a 10 20) (b 30 40))
;; 2 non-empty overlays intersecting
-(deftest-overlays-at-1 G 1 () (a 10 30) (b 20 40))
-(deftest-overlays-at-1 H 10 (a) (a 10 30) (b 20 40))
-(deftest-overlays-at-1 I 15 (a) (a 10 30) (b 20 40))
-(deftest-overlays-at-1 K 20 (a b) (a 10 30) (b 20 40))
-(deftest-overlays-at-1 L 25 (a b) (a 10 30) (b 20 40))
-(deftest-overlays-at-1 M 30 (b) (a 10 30) (b 20 40))
-(deftest-overlays-at-1 N 35 (b) (a 10 30) (b 20 40))
-(deftest-overlays-at-1 O 40 () (a 10 30) (b 20 40))
-(deftest-overlays-at-1 P 50 () (a 10 30) (b 20 40))
+(deftest-overlays-at-1 G2 1 () (a 10 30) (b 20 40))
+(deftest-overlays-at-1 H2 10 (a) (a 10 30) (b 20 40))
+(deftest-overlays-at-1 I2 15 (a) (a 10 30) (b 20 40))
+(deftest-overlays-at-1 K2 20 (a b) (a 10 30) (b 20 40))
+(deftest-overlays-at-1 L2 25 (a b) (a 10 30) (b 20 40))
+(deftest-overlays-at-1 M2 30 (b) (a 10 30) (b 20 40))
+(deftest-overlays-at-1 N2 35 (b) (a 10 30) (b 20 40))
+(deftest-overlays-at-1 O2 40 () (a 10 30) (b 20 40))
+(deftest-overlays-at-1 P2 50 () (a 10 30) (b 20 40))
;; 2 non-empty overlays continuous
-(deftest-overlays-at-1 G 1 () (a 10 20) (b 20 30))
-(deftest-overlays-at-1 H 10 (a) (a 10 20) (b 20 30))
-(deftest-overlays-at-1 I 15 (a) (a 10 20) (b 20 30))
-(deftest-overlays-at-1 K 20 (b) (a 10 20) (b 20 30))
-(deftest-overlays-at-1 L 25 (b) (a 10 20) (b 20 30))
-(deftest-overlays-at-1 M 30 () (a 10 20) (b 20 30))
+(deftest-overlays-at-1 G3 1 () (a 10 20) (b 20 30))
+(deftest-overlays-at-1 H3 10 (a) (a 10 20) (b 20 30))
+(deftest-overlays-at-1 I3 15 (a) (a 10 20) (b 20 30))
+(deftest-overlays-at-1 K3 20 (b) (a 10 20) (b 20 30))
+(deftest-overlays-at-1 L3 25 (b) (a 10 20) (b 20 30))
+(deftest-overlays-at-1 M3 30 () (a 10 20) (b 20 30))
;; overlays-at never returns empty overlays.
-(deftest-overlays-at-1 N 1 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
-(deftest-overlays-at-1 O 20 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
-(deftest-overlays-at-1 P 30 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
+(deftest-overlays-at-1 N3 1 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
+(deftest-overlays-at-1 O3 20 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
+(deftest-overlays-at-1 P3 30 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
(deftest-overlays-at-1 Q 40 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
(deftest-overlays-at-1 R 50 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
(deftest-overlays-at-1 S 60 () (a 1 60) (c 1 1) (b 30 30) (d 50 50))
@@ -1107,7 +1109,7 @@ with parameters from the *Messages* buffer modification."
(should (eq ov (car (overlays-in 1 1)))))))))
;; properties
-(ert-deftest test-buffer-swap-text-1 ()
+(ert-deftest test-buffer-swap-text-2 ()
(buffer-tests--with-temp-buffers (buffer other)
(with-current-buffer other
(overlay-put (make-overlay 1 1) 'buffer 'other))
@@ -1420,4 +1422,64 @@ with parameters from the *Messages* buffer modification."
(remove-overlays)
(should (= (length (overlays-in (point-min) (point-max))) 0))))
+(ert-deftest test-kill-buffer-auto-save-default ()
+ (ert-with-temp-file file
+ (let (auto-save)
+ ;; Always answer yes.
+ (cl-letf (((symbol-function #'yes-or-no-p) (lambda (_) t)))
+ (unwind-protect
+ (progn
+ (find-file file)
+ (auto-save-mode t)
+ (insert "foo\n")
+ (should buffer-auto-save-file-name)
+ (setq auto-save buffer-auto-save-file-name)
+ (do-auto-save)
+ (should (file-exists-p auto-save))
+ (kill-buffer (current-buffer))
+ (should (file-exists-p auto-save)))
+ (when auto-save
+ (ignore-errors (delete-file auto-save))))))))
+
+(ert-deftest test-kill-buffer-auto-save-delete ()
+ (ert-with-temp-file file
+ (let (auto-save)
+ (should (file-exists-p file))
+ (setq kill-buffer-delete-auto-save-files t)
+ ;; Always answer yes.
+ (cl-letf (((symbol-function #'yes-or-no-p) (lambda (_) t)))
+ (unwind-protect
+ (progn
+ (find-file file)
+ (auto-save-mode t)
+ (insert "foo\n")
+ (should buffer-auto-save-file-name)
+ (setq auto-save buffer-auto-save-file-name)
+ (do-auto-save)
+ (should (file-exists-p auto-save))
+ ;; This should delete the auto-save file.
+ (kill-buffer (current-buffer))
+ (should-not (file-exists-p auto-save)))
+ (ignore-errors (delete-file file))
+ (when auto-save
+ (ignore-errors (delete-file auto-save)))))
+ ;; Answer no to deletion.
+ (cl-letf (((symbol-function #'yes-or-no-p)
+ (lambda (prompt)
+ (not (string-search "Delete auto-save file" prompt)))))
+ (unwind-protect
+ (progn
+ (find-file file)
+ (auto-save-mode t)
+ (insert "foo\n")
+ (should buffer-auto-save-file-name)
+ (setq auto-save buffer-auto-save-file-name)
+ (do-auto-save)
+ (should (file-exists-p auto-save))
+ ;; This should not delete the auto-save file.
+ (kill-buffer (current-buffer))
+ (should (file-exists-p auto-save)))
+ (when auto-save
+ (ignore-errors (delete-file auto-save))))))))
+
;;; buffer-tests.el ends here
diff --git a/test/src/casefiddle-tests.el b/test/src/casefiddle-tests.el
index 9fa54dcaf43..dbbe9f30925 100644
--- a/test/src/casefiddle-tests.el
+++ b/test/src/casefiddle-tests.el
@@ -278,4 +278,20 @@
(with-temp-buffer
(should-error (upcase-region nil nil t)))))
+(ert-deftest casefiddle-turkish ()
+ (skip-unless (member "tr_TR.utf8" (get-locale-names)))
+ ;; See bug#50752. The point is that unibyte and multibyte strings
+ ;; are upcased differently in the "dotless i" case in Turkish,
+ ;; turning ASCII into non-ASCII, which is very unusual.
+ (with-locale-environment "tr_TR.utf8"
+ (should (string-equal (downcase "I ı") "ı ı"))
+ (should (string-equal (downcase "İ i") "i̇ i"))
+ (should (string-equal (downcase "I") "i"))
+ (should (string-equal (capitalize "bIte") "Bite"))
+ (should (string-equal (capitalize "bIté") "Bıté"))
+ (should (string-equal (capitalize "indIa") "India"))
+ ;; This does not work -- it produces "Indıa".
+ ;;(should (string-equal (capitalize "indIá") "İndıa"))
+ ))
+
;;; casefiddle-tests.el ends here
diff --git a/test/src/character-tests.el b/test/src/character-tests.el
index f630b32a5ee..ba24d49039c 100644
--- a/test/src/character-tests.el
+++ b/test/src/character-tests.el
@@ -43,3 +43,5 @@
(should (= (string-width "áëòç" nil 4) 2))
(should (= (string-width "הַרְבֵּה אַהֲבָה") 9))
(should (= (string-width "הַרְבֵּה אַהֲבָה" nil 8) 4)))
+
+;;; character-tests.el ends here
diff --git a/test/src/charset-tests.el b/test/src/charset-tests.el
index 5c46627c163..23e201ad453 100644
--- a/test/src/charset-tests.el
+++ b/test/src/charset-tests.el
@@ -22,7 +22,9 @@
(require 'ert)
(ert-deftest charset-decode-char ()
- "Test decode-char."
+ "Test `decode-char'."
(should-error (decode-char 'ascii 0.5)))
(provide 'charset-tests)
+
+;;; charset-tests.el ends here
diff --git a/test/src/coding-tests.el b/test/src/coding-tests.el
index 134f5676709..1c585ea5377 100644
--- a/test/src/coding-tests.el
+++ b/test/src/coding-tests.el
@@ -434,4 +434,4 @@
;; End:
(provide 'coding-tests)
-;; coding-tests.el ends here
+;;; coding-tests.el ends here
diff --git a/test/src/comp-resources/comp-test-funcs.el b/test/src/comp-resources/comp-test-funcs.el
index f2a246320ac..6352a7c7e94 100644
--- a/test/src/comp-resources/comp-test-funcs.el
+++ b/test/src/comp-resources/comp-test-funcs.el
@@ -202,7 +202,7 @@
(defun comp-tests-err-arith-f ()
(/ 1 0))
(defun comp-tests-err-foo-f ()
- (error "foo"))
+ (error "Foo"))
(defun comp-tests-condition-case-0-f ()
;; Bpushhandler Bpophandler
@@ -264,7 +264,7 @@
(% a b)))
(defun comp-tests-doc-f ()
- "A nice docstring"
+ "A nice docstring."
t)
(defun comp-test-interactive-form0-f (dir)
@@ -478,6 +478,7 @@
(eq family 'unspecified))
family)))
+;; This function doesn't have a doc string on purpose.
(defun comp-test-46670-1-f (_)
"foo")
@@ -647,7 +648,7 @@
(?> 2))))
(defun comp-test-big-interactive (filename &optional force arg load)
- ;; Check non trivial interactive form using `byte-recompile-file'.
+ "Check non trivial interactive form using `byte-recompile-file'."
(interactive
(let ((file buffer-file-name)
(file-name nil)
@@ -683,17 +684,17 @@
(defun comp-test-no-return-1 (x)
(while x
- (error "foo")))
+ (error "Foo")))
(defun comp-test-no-return-2 (x)
(cond
((eql x '2) t)
- ((error "bar") nil)))
+ ((error "Bar") nil)))
(defun comp-test-no-return-3 ())
(defun comp-test-no-return-4 (x)
(when x
- (error "foo")
+ (error "Foo")
(while (comp-test-no-return-3)
(comp-test-no-return-3))))
diff --git a/test/src/comp-tests.el b/test/src/comp-tests.el
index fb9441eb66e..5b20cf38ec6 100644
--- a/test/src/comp-tests.el
+++ b/test/src/comp-tests.el
@@ -28,17 +28,23 @@
(require 'ert)
(require 'ert-x)
(require 'cl-lib)
+(require 'comp)
+(require 'comp-cstr)
-(defconst comp-test-src (ert-resource-file "comp-test-funcs.el"))
+(eval-and-compile
+ (defconst comp-test-src (ert-resource-file "comp-test-funcs.el"))
+ (defconst comp-test-dyn-src (ert-resource-file "comp-test-funcs-dyn.el")))
-(defconst comp-test-dyn-src (ert-resource-file "comp-test-funcs-dyn.el"))
-
-(when (featurep 'native-compile)
- (require 'comp)
+(when (native-comp-available-p)
(message "Compiling tests...")
(load (native-compile comp-test-src))
(load (native-compile comp-test-dyn-src)))
+;; Load the test code here so the compiler can check the function
+;; names used in this file.
+(require 'comp-test-funcs comp-test-src)
+(require 'comp-test-dyn-funcs comp-test-dyn-src) ;Non-standard feature name!
+
(defmacro comp-deftest (name args &rest docstring-and-body)
"Define a test for the native compiler tagging it as :nativecomp."
(declare (indent defun)
@@ -53,30 +59,32 @@
"Compile the compiler and load it to compile it-self.
Check that the resulting binaries do not differ."
:tags '(:expensive-test :nativecomp)
- (let* ((byte+native-compile t) ; FIXME HACK
- (comp-src (expand-file-name "../../../lisp/emacs-lisp/comp.el"
+ (ert-with-temp-file comp1-src
+ :suffix "-comp-stage1.el"
+ (ert-with-temp-file comp2-src
+ :suffix "-comp-stage2.el"
+ (let* ((byte+native-compile t) ; FIXME HACK
+ (comp-src (expand-file-name "../../../lisp/emacs-lisp/comp.el"
(ert-resource-directory)))
- (comp1-src (make-temp-file "stage1-" nil ".el"))
- (comp2-src (make-temp-file "stage2-" nil ".el"))
- ;; Can't use debug symbols.
- (native-comp-debug 0))
- (copy-file comp-src comp1-src t)
- (copy-file comp-src comp2-src t)
- (let ((load-no-native t))
- (load (concat comp-src "c") nil nil t t))
- (should-not (subr-native-elisp-p (symbol-function #'native-compile)))
- (message "Compiling stage1...")
- (let* ((t0 (current-time))
- (comp1-eln (native-compile comp1-src)))
- (message "Done in %d secs" (float-time (time-since t0)))
- (load comp1-eln nil nil t t)
- (should (subr-native-elisp-p (symbol-function 'native-compile)))
- (message "Compiling stage2...")
- (let ((t0 (current-time))
- (comp2-eln (native-compile comp2-src)))
- (message "Done in %d secs" (float-time (time-since t0)))
- (message "Comparing %s %s" comp1-eln comp2-eln)
- (should (= (call-process "cmp" nil nil nil comp1-eln comp2-eln) 0))))))
+ ;; Can't use debug symbols.
+ (native-comp-debug 0))
+ (copy-file comp-src comp1-src t)
+ (copy-file comp-src comp2-src t)
+ (let ((load-no-native t))
+ (load (concat comp-src "c") nil nil t t))
+ (should-not (subr-native-elisp-p (symbol-function 'native-compile)))
+ (message "Compiling stage1...")
+ (let* ((t0 (current-time))
+ (comp1-eln (native-compile comp1-src)))
+ (message "Done in %d secs" (float-time (time-since t0)))
+ (load comp1-eln nil nil t t)
+ (should (subr-native-elisp-p (symbol-function 'native-compile)))
+ (message "Compiling stage2...")
+ (let ((t0 (current-time))
+ (comp2-eln (native-compile comp2-src)))
+ (message "Done in %d secs" (float-time (time-since t0)))
+ (message "Comparing %s %s" comp1-eln comp2-eln)
+ (should (= (call-process "cmp" nil nil nil comp1-eln comp2-eln) 0))))))))
(comp-deftest provide ()
"Testing top level provide."
@@ -285,7 +293,7 @@ Check that the resulting binaries do not differ."
(should (string= (comp-tests-condition-case-0-f)
"arith-error Arithmetic error catched"))
(should (string= (comp-tests-condition-case-1-f)
- "error foo catched"))
+ "error Foo catched"))
(should (= (comp-tests-catch-f
(lambda () (throw 'foo 3)))
3))
@@ -333,7 +341,7 @@ Check that the resulting binaries do not differ."
(comp-deftest doc ()
(should (string= (documentation #'comp-tests-doc-f)
- "A nice docstring"))
+ "A nice docstring."))
;; Check a preloaded function, we can't use `comp-tests-doc-f' now
;; as this is loaded manually with no .elc.
(should (string-match "\\.*.elc\\'" (symbol-file #'error))))
@@ -350,6 +358,8 @@ Check that the resulting binaries do not differ."
comp-test-interactive-form2-f)))
(should-not (commandp #'comp-tests-doc-f)))
+(declare-function comp-tests-free-fun-f nil)
+
(comp-deftest free-fun ()
"Check we are able to compile a single function."
(eval '(defun comp-tests-free-fun-f ()
@@ -359,7 +369,7 @@ Check that the resulting binaries do not differ."
t)
(native-compile #'comp-tests-free-fun-f)
- (should (subr-native-elisp-p (symbol-function #'comp-tests-free-fun-f)))
+ (should (subr-native-elisp-p (symbol-function 'comp-tests-free-fun-f)))
(should (= (comp-tests-free-fun-f) 3))
(should (string= (documentation #'comp-tests-free-fun-f)
"Some doc."))
@@ -367,11 +377,13 @@ Check that the resulting binaries do not differ."
(should (equal (interactive-form #'comp-tests-free-fun-f)
'(interactive))))
+(declare-function comp-tests/free\fun-f nil)
+
(comp-deftest free-fun-silly-name ()
"Check we are able to compile a single function."
(eval '(defun comp-tests/free\fun-f ()) t)
(native-compile #'comp-tests/free\fun-f)
- (should (subr-native-elisp-p (symbol-function #'comp-tests/free\fun-f))))
+ (should (subr-native-elisp-p (symbol-function 'comp-tests/free\fun-f))))
(comp-deftest bug-40187 ()
"Check function name shadowing.
@@ -382,7 +394,7 @@ https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-03/msg00914.html."
(comp-deftest speed--1 ()
"Check that at speed -1 we do not native compile."
(should (= (comp-test-speed--1-f) 3))
- (should-not (subr-native-elisp-p (symbol-function #'comp-test-speed--1-f))))
+ (should-not (subr-native-elisp-p (symbol-function 'comp-test-speed--1-f))))
(comp-deftest bug-42360 ()
"<https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-07/msg00418.html>."
@@ -431,7 +443,7 @@ https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-03/msg00914.html."
(comp-deftest primitive-redefine ()
"Test effectiveness of primitive redefinition."
(cl-letf ((comp-test-primitive-redefine-args nil)
- ((symbol-function #'-)
+ ((symbol-function '-)
(lambda (&rest args)
(setq comp-test-primitive-redefine-args args)
'xxx)))
@@ -452,11 +464,11 @@ https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-03/msg00914.html."
(comp-deftest comp-test-defsubst ()
;; Bug#42664, Bug#43280, Bug#44209.
- (should-not (subr-native-elisp-p (symbol-function #'comp-test-defsubst-f))))
+ (should-not (subr-native-elisp-p (symbol-function 'comp-test-defsubst-f))))
(comp-deftest primitive-redefine-compile-44221 ()
"Test the compiler still works while primitives are redefined (bug#44221)."
- (cl-letf (((symbol-function #'delete-region)
+ (cl-letf (((symbol-function 'delete-region)
(lambda (_ _))))
(should (subr-native-elisp-p
(native-compile
@@ -492,12 +504,12 @@ https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-03/msg00914.html."
(comp-deftest 45603-1 ()
"<https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-12/msg01994.html>"
(load (native-compile (ert-resource-file "comp-test-45603.el")))
- (should (fboundp #'comp-test-45603--file-local-name)))
+ (should (fboundp 'comp-test-45603--file-local-name)))
(comp-deftest 46670-1 ()
"<https://lists.gnu.org/archive/html/bug-gnu-emacs/2021-02/msg01413.html>"
(should (string= (comp-test-46670-2-f "foo") "foo"))
- (should (equal (subr-type (symbol-function #'comp-test-46670-2-f))
+ (should (equal (subr-type (symbol-function 'comp-test-46670-2-f))
'(function (t) t))))
(comp-deftest 46824-1 ()
@@ -727,7 +739,7 @@ https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-03/msg00914.html."
(comp-deftest dynamic-help-arglist ()
"Test `help-function-arglist' works on lisp/d (bug#42572)."
(should (equal (help-function-arglist
- (symbol-function #'comp-tests-ffuncall-callee-opt-rest-dyn-f)
+ (symbol-function 'comp-tests-ffuncall-callee-opt-rest-dyn-f)
t)
'(a b &optional c &rest d))))
@@ -784,6 +796,8 @@ Return a list of results."
(comp-tests-mentioned-p (comp-c-func-name 'comp-tests-tco-f "F" t)
insn)))))))
+(declare-function comp-tests-tco-f nil)
+
(comp-deftest tco ()
"Check for tail recursion elimination."
(let ((native-comp-speed 3)
@@ -798,7 +812,7 @@ Return a list of results."
(comp-tests-tco-f (+ a b) a (- count 1))))
t)
(native-compile #'comp-tests-tco-f)
- (should (subr-native-elisp-p (symbol-function #'comp-tests-tco-f)))
+ (should (subr-native-elisp-p (symbol-function 'comp-tests-tco-f)))
(should (= (comp-tests-tco-f 1 0 10) 55))))
(defun comp-tests-fw-prop-checker-1 (_)
@@ -812,6 +826,8 @@ Return a list of results."
(or (comp-tests-mentioned-p 'concat insn)
(comp-tests-mentioned-p 'length insn)))))))
+(declare-function comp-tests-fw-prop-1-f nil)
+
(comp-deftest fw-prop-1 ()
"Some tests for forward propagation."
(let ((native-comp-speed 2)
@@ -823,7 +839,7 @@ Return a list of results."
(length c))) ; <= has to optimize
t)
(native-compile #'comp-tests-fw-prop-1-f)
- (should (subr-native-elisp-p (symbol-function #'comp-tests-fw-prop-1-f)))
+ (should (subr-native-elisp-p (symbol-function 'comp-tests-fw-prop-1-f)))
(should (= (comp-tests-fw-prop-1-f) 6))))
(defun comp-tests-check-ret-type-spec (func-form ret-type)
@@ -1167,7 +1183,7 @@ Return a list of results."
;; 49
((defun comp-tests-ret-type-spec-f ()
- (error "foo"))
+ (error "Foo"))
nil)
;; 50
@@ -1373,7 +1389,7 @@ Return a list of results."
(defun comp-tests-pure-checker-1 (_)
"Check that inside `comp-tests-pure-caller-f' `comp-tests-pure-callee-f' is
- folded."
+folded."
(should
(cl-notany
#'identity
@@ -1403,11 +1419,13 @@ Return a list of results."
(comp-post-pass-hooks '((comp-final comp-tests-pure-checker-1
comp-tests-pure-checker-2))))
(load (native-compile (ert-resource-file "comp-test-pure.el")))
+ (declare-function comp-tests-pure-caller-f nil)
+ (declare-function comp-tests-pure-fibn-entry-f nil)
- (should (subr-native-elisp-p (symbol-function #'comp-tests-pure-caller-f)))
+ (should (subr-native-elisp-p (symbol-function 'comp-tests-pure-caller-f)))
(should (= (comp-tests-pure-caller-f) 4))
- (should (subr-native-elisp-p (symbol-function #'comp-tests-pure-fibn-entry-f)))
+ (should (subr-native-elisp-p (symbol-function 'comp-tests-pure-fibn-entry-f)))
(should (= (comp-tests-pure-fibn-entry-f) 6765))))
(defvar comp-tests-cond-rw-checked-function nil
diff --git a/test/src/data-tests.el b/test/src/data-tests.el
index b1e5fa0767c..8cc271b9e1c 100644
--- a/test/src/data-tests.el
+++ b/test/src/data-tests.el
@@ -26,10 +26,10 @@
(defconst data-tests--float-greater-than-fixnums (+ 1.0 most-positive-fixnum)
"A floating-point value that is greater than all fixnums.
It is also as small as conveniently possible, to make the tests sharper.
-Adding 1.0 to most-positive-fixnum should suffice on all
+Adding 1.0 to `most-positive-fixnum' should suffice on all
practical Emacs platforms, since the result is a power of 2 and
this is exactly representable and is greater than
-most-positive-fixnum, which is just less than a power of 2.")
+`most-positive-fixnum', which is just less than a power of 2.")
(ert-deftest data-tests-= ()
(should-error (=))
@@ -204,11 +204,11 @@ most-positive-fixnum, which is just less than a power of 2.")
"")))
(defun test-bool-vector-count-consecutive-tc (desc)
- "Run a test case for bool-vector-count-consecutive.
+ "Run a test case for `bool-vector-count-consecutive'.
DESC is a string describing the test. It is a sequence of
hexadecimal digits describing the bool vector. We exhaustively
test all counts at all possible positions in the vector by
-comparing the subr with a much slower lisp implementation."
+comparing the subr with a much slower Lisp implementation."
(let ((bv (test-bool-vector-bv-from-hex-string desc)))
(cl-loop
for lf in '(nil t)
@@ -338,7 +338,7 @@ comparing the subr with a much slower lisp implementation."
(should (eq binding-test-some-local 'local))))
(ert-deftest binding-test-setq-default ()
- "Test that a setq-default has no effect when there is a local binding."
+ "Test that a `setq-default' has no effect when there is a local binding."
(with-current-buffer binding-test-buffer-B
;; This variable is not local in this buffer.
(let ((binding-test-some-local 'something-else))
@@ -399,28 +399,28 @@ comparing the subr with a much slower lisp implementation."
(eq binding-test-some-local 'outer))))))
(ert-deftest binding-test-defvar-bool ()
- "Test DEFVAR_BOOL"
+ "Test DEFVAR_BOOL."
(let ((display-hourglass 5))
(should (eq display-hourglass t))))
(ert-deftest binding-test-defvar-int ()
- "Test DEFVAR_INT"
+ "Test DEFVAR_INT."
(should-error (setq gc-cons-threshold 5.0) :type 'wrong-type-argument))
(ert-deftest binding-test-set-constant-t ()
- "Test setting the constant t"
+ "Test setting the constant t."
(with-no-warnings (should-error (setq t 'bob) :type 'setting-constant)))
(ert-deftest binding-test-set-constant-nil ()
- "Test setting the constant nil"
+ "Test setting the constant nil."
(with-no-warnings (should-error (setq nil 'bob) :type 'setting-constant)))
(ert-deftest binding-test-set-constant-keyword ()
- "Test setting a keyword constant"
+ "Test setting a keyword constant."
(with-no-warnings (should-error (setq :keyword 'bob) :type 'setting-constant)))
-(ert-deftest binding-test-set-constant-nil ()
- "Test setting a keyword to itself"
+(ert-deftest binding-test-set-constant-itself ()
+ "Test setting a keyword to itself."
(with-no-warnings (should (setq :keyword :keyword))))
(ert-deftest data-tests--set-default-per-buffer ()
@@ -433,26 +433,27 @@ comparing the subr with a much slower lisp implementation."
;; More specifically, test the problem seen in bug#41029 where setting
;; the default value of a variable takes time proportional to the
;; number of buffers.
- (let* ((fun #'error)
- (test (lambda ()
- (with-temp-buffer
- (let ((st (car (current-cpu-time))))
- (dotimes (_ 1000)
- (let ((case-fold-search 'data-test))
- ;; Use an indirection through a mutable var
- ;; to try and make sure the byte-compiler
- ;; doesn't optimize away the let bindings.
- (funcall fun)))
- ;; FIXME: Handle the wraparound, if any.
- (- (car (current-cpu-time)) st)))))
- (_ (setq fun #'ignore))
- (time1 (funcall test))
- (bufs (mapcar (lambda (_) (generate-new-buffer " data-test"))
- (make-list 1000 nil)))
- (time2 (funcall test)))
- (mapc #'kill-buffer bufs)
- ;; Don't divide one time by the other since they may be 0.
- (should (< time2 (* time1 5)))))
+ (when (fboundp 'current-cpu-time) ; silence byte-compiler
+ (let* ((fun #'error)
+ (test (lambda ()
+ (with-temp-buffer
+ (let ((st (car (current-cpu-time))))
+ (dotimes (_ 1000)
+ (let ((case-fold-search 'data-test))
+ ;; Use an indirection through a mutable var
+ ;; to try and make sure the byte-compiler
+ ;; doesn't optimize away the let bindings.
+ (funcall fun)))
+ ;; FIXME: Handle the wraparound, if any.
+ (- (car (current-cpu-time)) st)))))
+ (_ (setq fun #'ignore))
+ (time1 (funcall test))
+ (bufs (mapcar (lambda (_) (generate-new-buffer " data-test"))
+ (make-list 1000 nil)))
+ (time2 (funcall test)))
+ (mapc #'kill-buffer bufs)
+ ;; Don't divide one time by the other since they may be 0.
+ (should (< time2 (* time1 5))))))
;; More tests to write -
;; kill-local-variable
@@ -690,7 +691,7 @@ comparing the subr with a much slower lisp implementation."
(let ((n (* 2 most-negative-fixnum)))
(should (= (logand -1 n) n))))
-(ert-deftest data-tests-logcount ()
+(ert-deftest data-tests-logcount-2 ()
(should (= (logcount (read "#xffffffffffffffffffffffffffffffff")) 128)))
(ert-deftest data-tests-logior ()
@@ -757,7 +758,7 @@ comparing the subr with a much slower lisp implementation."
;; forwarding, but this needs to happen before the var is accessed
;; from the Lisp side and before we switch to another buffer.
;; The trigger in bug#34318 doesn't exist any more because the C code has
- ;; changes. Instead I found the trigger below.
+ ;; changed. Instead I found the trigger below.
(with-temp-buffer
(setq last-coding-system-used 'bug34318)
(make-local-variable 'last-coding-system-used)
diff --git a/test/src/decompress-tests.el b/test/src/decompress-tests.el
index 520445cca5a..1d25cf2f66b 100644
--- a/test/src/decompress-tests.el
+++ b/test/src/decompress-tests.el
@@ -42,4 +42,4 @@
(provide 'decompress-tests)
-;;; decompress-tests.el ends here.
+;;; decompress-tests.el ends here
diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el
index a731a95ccf0..e83dd7c857b 100644
--- a/test/src/editfns-tests.el
+++ b/test/src/editfns-tests.el
@@ -23,16 +23,16 @@
(ert-deftest format-properties ()
;; Bug #23730
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format (propertize "%d" 'face '(:background "red")) 1)
#("1" 0 1 (face (:background "red")))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format (propertize "%2d" 'face '(:background "red")) 1)
#(" 1" 0 2 (face (:background "red")))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format (propertize "%02d" 'face '(:background "red")) 1)
#("01" 0 2 (face (:background "red")))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format (concat (propertize "%2d" 'x 'X)
(propertize "a" 'a 'A)
(propertize "b" 'b 'B))
@@ -40,27 +40,27 @@
#(" 1ab" 0 2 (x X) 2 3 (a A) 3 4 (b B))))
;; Bug #5306
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format "%.10s"
(concat "1234567890aaaa"
(propertize "12345678901234567890" 'xxx 25)))
"1234567890"))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format "%.10s"
(concat "123456789"
(propertize "12345678901234567890" 'xxx 25)))
#("1234567891" 9 10 (xxx 25))))
;; Bug #23859
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format "%4s" (propertize "hi" 'face 'bold))
#(" hi" 2 4 (face bold))))
;; Bug #23897
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format "%s" (concat (propertize "01234" 'face 'bold) "56789"))
#("0123456789" 0 5 (face bold))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format "%s" (concat (propertize "01" 'face 'bold)
(propertize "23" 'face 'underline)
"45"))
@@ -68,63 +68,63 @@
;; The last property range is extended to include padding on the
;; right, but the first range is not extended to the left to include
;; padding on the left!
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format "%12s" (concat (propertize "01234" 'face 'bold) "56789"))
#(" 0123456789" 2 7 (face bold))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format "%-12s" (concat (propertize "01234" 'face 'bold) "56789"))
#("0123456789 " 0 5 (face bold))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format "%10s" (concat (propertize "01" 'face 'bold)
(propertize "23" 'face 'underline)
"45"))
#(" 012345" 4 6 (face bold) 6 8 (face underline))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format "%-10s" (concat (propertize "01" 'face 'bold)
(propertize "23" 'face 'underline)
"45"))
#("012345 " 0 2 (face bold) 2 4 (face underline))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format "%-10s" (concat (propertize "01" 'face 'bold)
(propertize "23" 'face 'underline)
(propertize "45" 'face 'italic)))
#("012345 "
0 2 (face bold) 2 4 (face underline) 4 10 (face italic))))
;; Bug #38191
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format (propertize "‘foo’ %s bar" 'face 'bold) "xxx")
#("‘foo’ xxx bar" 0 13 (face bold))))
;; Bug #32404
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format (concat (propertize "%s" 'face 'bold)
""
(propertize "%s" 'face 'error))
"foo" "bar")
#("foobar" 0 3 (face bold) 3 6 (face error))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format (concat "%s" (propertize "%s" 'face 'error)) "foo" "bar")
#("foobar" 3 6 (face error))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format (concat "%s " (propertize "%s" 'face 'error)) "foo" "bar")
#("foo bar" 4 7 (face error))))
;; Bug #46317
(let ((s (propertize "X" 'prop "val")))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format (concat "%3s/" s) 12)
#(" 12/X" 4 5 (prop "val"))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format (concat "%3S/" s) 12)
#(" 12/X" 4 5 (prop "val"))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format (concat "%3d/" s) 12)
#(" 12/X" 4 5 (prop "val"))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format (concat "%-3s/" s) 12)
#("12 /X" 4 5 (prop "val"))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format (concat "%-3S/" s) 12)
#("12 /X" 4 5 (prop "val"))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(format (concat "%-3d/" s) 12)
#("12 /X" 4 5 (prop "val"))))))
diff --git a/test/src/emacs-module-resources/mod-test.c b/test/src/emacs-module-resources/mod-test.c
index 5720af8c605..4c0b168e34d 100644
--- a/test/src/emacs-module-resources/mod-test.c
+++ b/test/src/emacs-module-resources/mod-test.c
@@ -298,7 +298,10 @@ Fmod_test_userptr_make (emacs_env *env, ptrdiff_t nargs, emacs_value args[],
{
struct super_struct *p = calloc (1, sizeof *p);
if (!p)
- signal_errno (env, "calloc");
+ {
+ signal_errno (env, "calloc");
+ return NULL;
+ }
p->amazing_int = env->extract_integer (env, args[0]);
return env->make_user_ptr (env, free, p);
}
diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el
index a4d858113ed..988b311f5b5 100644
--- a/test/src/emacs-module-tests.el
+++ b/test/src/emacs-module-tests.el
@@ -32,6 +32,11 @@
(require 'help-fns)
(require 'subr-x)
+;; Catch information for bug#50902.
+(when (getenv "EMACS_EMBA_CI")
+ (start-process-shell-command
+ "*timeout*" nil (format "sleep 60; kill -ABRT %d" (emacs-pid))))
+
(defconst mod-test-emacs
(expand-file-name invocation-name invocation-directory)
"File name of the Emacs binary currently running.")
@@ -206,20 +211,6 @@ changes."
(should (equal (help-function-arglist #'mod-test-sum)
'(arg1 arg2))))
-(defmacro module--with-temp-directory (name &rest body)
- "Bind NAME to the name of a temporary directory and evaluate BODY.
-NAME must be a symbol. Delete the temporary directory after BODY
-exits normally or non-locally. NAME will be bound to the
-directory name (not the directory file name) of the temporary
-directory."
- (declare (indent 1))
- (cl-check-type name symbol)
- `(let ((,name (file-name-as-directory
- (make-temp-file "emacs-module-test" :directory))))
- (unwind-protect
- (progn ,@body)
- (delete-directory ,name :recursive))))
-
(defmacro module--test-assertion (pattern &rest body)
"Test that PATTERN matches the assertion triggered by BODY.
Run Emacs as a subprocess, load the test module `mod-test-file',
@@ -228,7 +219,7 @@ assertion message that matches PATTERN. PATTERN is evaluated and
must evaluate to a regular expression string."
(declare (indent 1))
;; To contain any core dumps.
- `(module--with-temp-directory tempdir
+ `(ert-with-temp-directory tempdir
(with-temp-buffer
(let* ((default-directory tempdir)
(status (call-process mod-test-emacs nil t nil
@@ -256,6 +247,7 @@ must evaluate to a regular expression string."
(ert-deftest module--test-assertions--load-non-live-object ()
"Check that -module-assertions verify that non-live objects aren't accessed."
+ :tags (if (getenv "EMACS_EMBA_CI") '(:unstable))
(skip-unless (or (file-executable-p mod-test-emacs)
(and (eq system-type 'windows-nt)
(file-executable-p (concat mod-test-emacs ".exe")))))
@@ -274,6 +266,7 @@ must evaluate to a regular expression string."
This differs from `module--test-assertions-load-non-live-object'
in that it stows away a global reference. The module assertions
should nevertheless detect the invalid load."
+ :tags (if (getenv "EMACS_EMBA_CI") '(:unstable))
(skip-unless (or (file-executable-p mod-test-emacs)
(and (eq system-type 'windows-nt)
(file-executable-p (concat mod-test-emacs ".exe")))))
@@ -290,6 +283,7 @@ should nevertheless detect the invalid load."
(ert-deftest module--test-assertions--call-emacs-from-gc ()
"Check that -module-assertions prevents calling Emacs functions
during garbage collection."
+ :tags (if (getenv "EMACS_EMBA_CI") '(:unstable))
(skip-unless (or (file-executable-p mod-test-emacs)
(and (eq system-type 'windows-nt)
(file-executable-p (concat mod-test-emacs ".exe")))))
@@ -301,7 +295,8 @@ during garbage collection."
(ert-deftest module--test-assertions--globref-invalid-free ()
"Check that -module-assertions detects invalid freeing of a
local reference."
- (skip-unless (or (file-executable-p mod-test-emacs)
+ :tags (if (getenv "EMACS_EMBA_CI") '(:unstable))
+ (skip-unless (or (file-executable-p mod-test-emacs)
(and (eq system-type 'windows-nt)
(file-executable-p (concat mod-test-emacs ".exe")))))
(module--test-assertion
@@ -324,7 +319,9 @@ local reference."
(mod-test-sum a b)
-Return A + B"
+Return A + B
+
+"
module-file-suffix))))))
(ert-deftest module/load-history ()
diff --git a/test/src/emacs-tests.el b/test/src/emacs-tests.el
index ac08e055b55..a1a412423cb 100644
--- a/test/src/emacs-tests.el
+++ b/test/src/emacs-tests.el
@@ -25,6 +25,7 @@
(require 'cl-lib)
(require 'ert)
+(require 'ert-x) ; ert-with-temp-file
(require 'rx)
(require 'subr-x)
@@ -46,22 +47,6 @@
"--seccomp=/does-not-exist.bpf")
0))))
-(cl-defmacro emacs-tests--with-temp-file
- (var (prefix &optional suffix text) &rest body)
- "Evaluate BODY while a new temporary file exists.
-Bind VAR to the name of the file. Pass PREFIX, SUFFIX, and TEXT
-to `make-temp-file', which see."
- (declare (indent 2) (debug (symbolp (form form form) body)))
- (cl-check-type var symbol)
- ;; Use an uninterned symbol so that the code still works if BODY
- ;; changes VAR.
- (let ((filename (make-symbol "filename")))
- `(let ((,filename (make-temp-file ,prefix nil ,suffix ,text)))
- (unwind-protect
- (let ((,var ,filename))
- ,@body)
- (delete-file ,filename)))))
-
(ert-deftest emacs-tests/seccomp/empty-file ()
(skip-unless (string-match-p (rx bow "SECCOMP" eow)
system-configuration-features))
@@ -69,7 +54,8 @@ to `make-temp-file', which see."
(expand-file-name invocation-name invocation-directory))
(process-environment nil))
(skip-unless (file-executable-p emacs))
- (emacs-tests--with-temp-file filter ("seccomp-invalid-" ".bpf")
+ (ert-with-temp-file filter
+ :prefix "seccomp-invalid-" :suffix ".bpf"
;; The --seccomp option is processed early, without filename
;; handlers. Therefore remote or quoted filenames wouldn't
;; work.
@@ -94,9 +80,9 @@ to `make-temp-file', which see."
;; Either 8 or 16, but 16 should be large enough in all cases.
(filter-size 16))
(skip-unless (file-executable-p emacs))
- (emacs-tests--with-temp-file
- filter ("seccomp-too-large-" ".bpf"
- (make-string (* (1+ ushort-max) filter-size) ?a))
+ (ert-with-temp-file filter
+ :prefix "seccomp-too-large-" :suffix ".bpf"
+ :text (make-string (* (1+ ushort-max) filter-size) ?a)
;; The --seccomp option is processed early, without filename
;; handlers. Therefore remote or quoted filenames wouldn't
;; work.
@@ -117,8 +103,8 @@ to `make-temp-file', which see."
(expand-file-name invocation-name invocation-directory))
(process-environment nil))
(skip-unless (file-executable-p emacs))
- (emacs-tests--with-temp-file filter ("seccomp-invalid-" ".bpf"
- "123456")
+ (ert-with-temp-file filter
+ :prefix "seccomp-invalid-" :suffix ".bpf" :text "123456"
;; The --seccomp option is processed early, without filename
;; handlers. Therefore remote or quoted filenames wouldn't
;; work.
diff --git a/test/src/eval-tests.el b/test/src/eval-tests.el
index b2b7dfefda5..727c98aa5fa 100644
--- a/test/src/eval-tests.el
+++ b/test/src/eval-tests.el
@@ -39,31 +39,40 @@
(ert-deftest eval-tests--bugs-24912-and-24913 ()
"Check that Emacs doesn't accept weird argument lists.
Bug#24912 and Bug#24913."
- (dolist (args '((&rest &optional)
- (&rest a &optional) (&rest &optional a)
- (&optional &optional) (&optional &optional a)
- (&optional a &optional b)
- (&rest &rest) (&rest &rest a)
- (&rest a &rest b)))
- (should-error (eval `(funcall (lambda ,args)) t) :type 'invalid-function)
- (should-error (byte-compile-check-lambda-list args))
- (let ((byte-compile-debug t))
- (ert-info ((format "bytecomp: args = %S" args))
- (should-error (eval `(byte-compile (lambda ,args)) t))))))
-
-(ert-deftest eval-tests-accept-empty-optional-rest ()
- "Check that Emacs accepts empty &optional and &rest arglists.
+ (dolist (lb '(t false))
+ (ert-info ((prin1-to-string lb) :prefix "lexical-binding: ")
+ (let ((lexical-binding lb))
+ (dolist (args '((&rest &optional)
+ (&rest a &optional) (&rest &optional a)
+ (&optional &optional) (&optional &optional a)
+ (&optional a &optional b)
+ (&rest &rest) (&rest &rest a)
+ (&rest a &rest b)
+ (&rest) (&optional &rest)
+ ))
+ (ert-info ((prin1-to-string args) :prefix "args: ")
+ (should-error
+ (eval `(funcall (lambda ,args)) lb) :type 'invalid-function)
+ (should-error (byte-compile-check-lambda-list args))
+ (let ((byte-compile-debug t))
+ (should-error (eval `(byte-compile (lambda ,args)) lb)))))))))
+
+(ert-deftest eval-tests-accept-empty-optional ()
+ "Check that Emacs accepts empty &optional arglists.
Bug#24912."
- (dolist (args '((&optional) (&rest) (&optional &rest)
- (&optional &rest a) (&optional a &rest)))
- (let ((fun `(lambda ,args 'ok)))
- (ert-info ("eval")
- (should (eq (funcall (eval fun t)) 'ok)))
- (ert-info ("byte comp check")
- (byte-compile-check-lambda-list args))
- (ert-info ("bytecomp")
- (let ((byte-compile-debug t))
- (should (eq (funcall (byte-compile fun)) 'ok)))))))
+ (dolist (lb '(t false))
+ (ert-info ((prin1-to-string lb) :prefix "lexical-binding: ")
+ (let ((lexical-binding lb))
+ (dolist (args '((&optional) (&optional &rest a)))
+ (ert-info ((prin1-to-string args) :prefix "args: ")
+ (let ((fun `(lambda ,args 'ok)))
+ (ert-info ("eval")
+ (should (eq (funcall (eval fun lb)) 'ok)))
+ (ert-info ("byte comp check")
+ (byte-compile-check-lambda-list args))
+ (ert-info ("bytecomp")
+ (let ((byte-compile-debug t))
+ (should (eq (funcall (byte-compile fun)) 'ok)))))))))))
(dolist (form '(let let*))
@@ -77,23 +86,27 @@ Bug#24912."
(ert-deftest eval-tests--if-dot-string ()
"Check that Emacs rejects (if . \"string\")."
- (should-error (eval '(if . "abc")) :type 'wrong-type-argument)
+ (should-error (eval '(if . "abc") nil) :type 'wrong-type-argument)
+ (should-error (eval '(if . "abc") t) :type 'wrong-type-argument)
(let ((if-tail (list '(setcdr if-tail "abc") t)))
- (should-error (eval (cons 'if if-tail))))
+ (should-error (eval (cons 'if if-tail) nil) :type 'void-variable)
+ (should-error (eval (cons 'if if-tail) t) :type 'void-variable))
(let ((if-tail (list '(progn (setcdr if-tail "abc") nil) t)))
- (should-error (eval (cons 'if if-tail)))))
+ (should-error (eval (cons 'if if-tail) nil) :type 'void-variable)
+ (should-error (eval (cons 'if if-tail) t) :type 'void-variable)))
(ert-deftest eval-tests--let-with-circular-defs ()
"Check that Emacs reports an error for (let VARS ...) when VARS is circular."
(let ((vars (list 'v)))
(setcdr vars vars)
(dolist (let-sym '(let let*))
- (should-error (eval (list let-sym vars))))))
+ (should-error (eval (list let-sym vars) nil)))))
(ert-deftest eval-tests--mutating-cond ()
"Check that Emacs doesn't crash on a cond clause that mutates during eval."
(let ((clauses (list '((progn (setcdr clauses "ouch") nil)))))
- (should-error (eval (cons 'cond clauses)))))
+ (should-error (eval (cons 'cond clauses) nil))
+ (should-error (eval (cons 'cond clauses) t))))
(defun eval-tests--exceed-specbind-limit ()
(defvar eval-tests--var1)
@@ -170,12 +183,13 @@ are found on the stack and therefore not garbage collected."
"Remove the Lisp reference to the byte-compiled object."
(setf (symbol-function #'eval-tests-33014-func) nil))
-(defun eval-tests-19790-backquote-comma-dot-substitution ()
+(ert-deftest eval-tests-19790-backquote-comma-dot-substitution ()
"Regression test for Bug#19790.
Don't handle destructive splicing in backquote expressions (like
in Common Lisp). Instead, make sure substitution in backquote
expressions works for identifiers starting with period."
- (should (equal (let ((.x 'identity)) (eval `(,.x 'ok))) 'ok)))
+ (should (equal (let ((.x 'identity)) (eval `(,.x 'ok) nil)) 'ok))
+ (should (equal (let ((.x 'identity)) (eval `(,.x 'ok) t)) 'ok)))
(ert-deftest eval-tests/backtrace-in-batch-mode ()
(let ((emacs (expand-file-name invocation-name invocation-directory)))
diff --git a/test/src/fileio-tests.el b/test/src/fileio-tests.el
index f4d123b4261..4143503aa18 100644
--- a/test/src/fileio-tests.el
+++ b/test/src/fileio-tests.el
@@ -17,6 +17,8 @@
;; 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)
(defun try-link (target link)
@@ -97,7 +99,7 @@ Also check that an encoding error can appear in a symlink."
(should (equal (file-name-as-directory "D:/abc//") "d:/abc//")))
(ert-deftest fileio-tests--relative-HOME ()
- "Test that expand-file-name works even when HOME is relative."
+ "Test that `expand-file-name' works even when HOME is relative."
(let ((process-environment (copy-sequence process-environment)))
(setenv "HOME" "a/b/c")
(should (equal (expand-file-name "~/foo")
@@ -128,7 +130,7 @@ Also check that an encoding error can appear in a symlink."
(if f (delete-file f)))))
(ert-deftest fileio-tests--relative-default-directory ()
- "Test expand-file-name when default-directory is relative."
+ "Test `expand-file-name' when `default-directory' is relative."
(let ((default-directory "some/relative/name"))
(should (file-name-absolute-p (expand-file-name "foo"))))
(let* ((default-directory "~foo")
@@ -136,8 +138,17 @@ Also check that an encoding error can appear in a symlink."
(should (and (file-name-absolute-p name)
(not (eq (aref name 0) ?~))))))
+(ert-deftest fileio-test--expand-file-name-null-bytes ()
+ "Test that `expand-file-name' checks for null bytes in filenames."
+ (should-error (expand-file-name (concat "file" (char-to-string ?\0) ".txt"))
+ :type 'wrong-type-argument)
+ (should-error (expand-file-name "file.txt" (concat "dir" (char-to-string ?\0)))
+ :type 'wrong-type-argument)
+ (let ((default-directory (concat "dir" (char-to-string ?\0))))
+ (should-error (expand-file-name "file.txt") :type 'wrong-type-argument)))
+
(ert-deftest fileio-tests--file-name-absolute-p ()
- "Test file-name-absolute-p."
+ "Test `file-name-absolute-p'."
(dolist (suffix '("" "/" "//" "/foo" "/foo/" "/foo//" "/foo/bar"))
(unless (string-equal suffix "")
(should (file-name-absolute-p suffix)))
@@ -148,7 +159,7 @@ Also check that an encoding error can appear in a symlink."
(should (not (file-name-absolute-p (concat "~nosuchuser" suffix)))))))
(ert-deftest fileio-tests--circular-after-insert-file-functions ()
- "Test after-insert-file-functions as a circular list."
+ "Test `after-insert-file-functions' as a circular list."
(let ((f (make-temp-file "fileio"))
(after-insert-file-functions (list 'identity)))
(setcdr after-insert-file-functions after-insert-file-functions)
diff --git a/test/src/filelock-tests.el b/test/src/filelock-tests.el
index a96d6d67289..ba001679639 100644
--- a/test/src/filelock-tests.el
+++ b/test/src/filelock-tests.el
@@ -28,6 +28,7 @@
(require 'cl-macs)
(require 'ert)
+(require 'ert-x)
(require 'seq)
(defun filelock-tests--fixture (test-function)
@@ -36,22 +37,20 @@ Create a test directory and a buffer whose `buffer-file-name' and
`buffer-file-truename' are a file within it, then call
TEST-FUNCTION. Finally, delete the buffer and the test
directory."
- (let* ((temp-dir (make-temp-file "filelock-tests" t))
- (name (concat (file-name-as-directory temp-dir)
- "userfile"))
- (create-lockfiles t))
- (unwind-protect
- (with-temp-buffer
- (setq buffer-file-name name
- buffer-file-truename name)
- (unwind-protect
- (save-current-buffer
- (funcall test-function))
- ;; Set `buffer-file-truename' nil to prevent unlocking,
- ;; which might prompt the user and/or signal errors.
- (setq buffer-file-name nil
- buffer-file-truename nil)))
- (delete-directory temp-dir t nil))))
+ (ert-with-temp-directory temp-dir
+ (let ((name (concat (file-name-as-directory temp-dir)
+ "userfile"))
+ (create-lockfiles t))
+ (with-temp-buffer
+ (setq buffer-file-name name
+ buffer-file-truename name)
+ (unwind-protect
+ (save-current-buffer
+ (funcall test-function))
+ ;; Set `buffer-file-truename' nil to prevent unlocking,
+ ;; which might prompt the user and/or signal errors.
+ (setq buffer-file-name nil
+ buffer-file-truename nil))))))
(defun filelock-tests--make-lock-name (file-name)
"Return the lock file name for FILE-NAME.
diff --git a/test/src/floatfns-tests.el b/test/src/floatfns-tests.el
index 4a3c03d833e..a066d2e15e2 100644
--- a/test/src/floatfns-tests.el
+++ b/test/src/floatfns-tests.el
@@ -17,8 +17,72 @@
;; 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)
+(ert-deftest floatfns-tests-cos ()
+ (should (= (cos 0) 1.0))
+ (should (= (cos float-pi) -1.0)))
+
+(ert-deftest floatfns-tests-sin ()
+ (should (= (sin 0) 0.0)))
+
+(ert-deftest floatfns-tests-tan ()
+ (should (= (tan 0) 0.0)))
+
+(ert-deftest floatfns-tests-isnan ()
+ (should (isnan 0.0e+NaN))
+ (should (isnan -0.0e+NaN))
+ (should-error (isnan "foo") :type 'wrong-type-argument))
+
+(ert-deftest floatfns-tests-exp ()
+ (should (= (exp 0) 1.0)))
+
+(ert-deftest floatfns-tests-expt ()
+ (should (= (expt 2 8) 256)))
+
+(ert-deftest floatfns-tests-log ()
+ (should (= (log 1000 10) 3.0)))
+
+(ert-deftest floatfns-tests-sqrt ()
+ (should (= (sqrt 25) 5)))
+
+(ert-deftest floatfns-tests-abs ()
+ (should (= (abs 10) 10))
+ (should (= (abs -10) 10)))
+
+(ert-deftest floatfns-tests-logb ()
+ (should (= (logb 10000) 13)))
+
+(ert-deftest floatfns-tests-ceiling ()
+ (should (= (ceiling 0.5) 1)))
+
+(ert-deftest floatfns-tests-floor ()
+ (should (= (floor 1.5) 1)))
+
+(ert-deftest floatfns-tests-round ()
+ (should (= (round 1.49999999999) 1))
+ (should (= (round 1.50000000000) 2))
+ (should (= (round 1.50000000001) 2)))
+
+(ert-deftest floatfns-tests-truncate ()
+ (should (= (truncate float-pi) 3)))
+
+(ert-deftest floatfns-tests-fceiling ()
+ (should (= (fceiling 0.5) 1.0)))
+
+(ert-deftest floatfns-tests-ffloor ()
+ (should (= (ffloor 1.5) 1.0)))
+
+(ert-deftest floatfns-tests-fround ()
+ (should (= (fround 1.49999999999) 1.0))
+ (should (= (fround 1.50000000000) 2.0))
+ (should (= (fround 1.50000000001) 2.0)))
+
+(ert-deftest floatfns-tests-ftruncate ()
+ (should (= (ftruncate float-pi) 3.0)))
+
(ert-deftest divide-extreme-sign ()
(should (= (ceiling most-negative-fixnum -1.0) (- most-negative-fixnum)))
(should (= (floor most-negative-fixnum -1.0) (- most-negative-fixnum)))
@@ -125,3 +189,5 @@
(ash (1- (ash 1 53)) 2045))))
(provide 'floatfns-tests)
+
+;;; floatfns-tests.el ends here
diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el
index 9f6593a177c..bec5c03f9e7 100644
--- a/test/src/fns-tests.el
+++ b/test/src/fns-tests.el
@@ -23,6 +23,29 @@
(require 'cl-lib)
+(ert-deftest fns-tests-identity ()
+ (let ((num 12345)) (should (eq (identity num) num)))
+ (let ((str "foo")) (should (eq (identity str) str)))
+ (let ((lst '(11))) (should (eq (identity lst) lst))))
+
+(ert-deftest fns-tests-random ()
+ (should (integerp (random)))
+ (should (>= (random 10) 0))
+ (should (< (random 10) 10)))
+
+(ert-deftest fns-tests-length ()
+ (should (= (length nil) 0))
+ (should (= (length '(1 2 3)) 3))
+ (should (= (length '[1 2 3]) 3))
+ (should (= (length "foo") 3))
+ (should-error (length t)))
+
+(ert-deftest fns-tests-safe-length ()
+ (should (= (safe-length '(1 2 3)) 3)))
+
+(ert-deftest fns-tests-string-bytes ()
+ (should (= (string-bytes "abc") 3)))
+
;; Test that equality predicates work correctly on NaNs when combined
;; with hash tables based on those predicates. This was not the case
;; for eql in Emacs 26.
@@ -34,6 +57,33 @@
(puthash nan t h)
(should (eq (funcall test nan -nan) (gethash -nan h))))))
+(ert-deftest fns-tests-equal-including-properties ()
+ (should (equal-including-properties "" ""))
+ (should (equal-including-properties "foo" "foo"))
+ (should (equal-including-properties #("foo" 0 3 (a b))
+ (propertize "foo" 'a 'b)))
+ (should (equal-including-properties #("foo" 0 3 (a b c d))
+ (propertize "foo" 'a 'b 'c 'd)))
+ (should (equal-including-properties #("a" 0 1 (k v))
+ #("a" 0 1 (k v))))
+ (should-not (equal-including-properties #("a" 0 1 (k v))
+ #("a" 0 1 (k x))))
+ (should-not (equal-including-properties #("a" 0 1 (k v))
+ #("b" 0 1 (k v))))
+ (should-not (equal-including-properties #("foo" 0 3 (a b c e))
+ (propertize "foo" 'a 'b 'c 'd))))
+
+(ert-deftest fns-tests-equal-including-properties/string-prop-vals ()
+ "Handle string property values. (Bug#6581)"
+ (should (equal-including-properties #("a" 0 1 (k "v"))
+ #("a" 0 1 (k "v"))))
+ (should (equal-including-properties #("foo" 0 3 (a (t)))
+ (propertize "foo" 'a (list t))))
+ (should-not (equal-including-properties #("a" 0 1 (k "v"))
+ #("a" 0 1 (k "x"))))
+ (should-not (equal-including-properties #("a" 0 1 (k "v"))
+ #("b" 0 1 (k "v")))))
+
(ert-deftest fns-tests-reverse ()
(should-error (reverse))
(should-error (reverse 1))
@@ -430,6 +480,23 @@
(buffer-hash))
(sha1 "foo"))))
+(ert-deftest fns-tests-mapconcat ()
+ (should (string= (mapconcat #'identity '()) ""))
+ (should (string= (mapconcat #'identity '("a" "b")) "ab"))
+ (should (string= (mapconcat #'identity '() "_") ""))
+ (should (string= (mapconcat #'identity '("A") "_") "A"))
+ (should (string= (mapconcat #'identity '("A" "B") "_") "A_B"))
+ (should (string= (mapconcat #'identity '("A" "B" "C") "_") "A_B_C"))
+ ;; non-ASCII strings
+ (should (string= (mapconcat #'identity '("Ä" "ø" "☭" "தமிழ்") "_漢字_")
+ "Ä_漢字_ø_漢字_☭_漢字_தமிழ்"))
+ ;; vector
+ (should (string= (mapconcat #'identity ["a" "b"] "") "ab"))
+ ;; bool-vector
+ (should (string= (mapconcat #'identity [nil nil] "") ""))
+ (should-error (mapconcat #'identity [nil nil t])
+ :type 'wrong-type-argument))
+
(ert-deftest fns-tests-mapcan ()
(should-error (mapcan))
(should-error (mapcan #'identity))
@@ -786,7 +853,15 @@
;; string containing hanzi character, compare by character
(should (equal 2 (string-distance "ab" "ab我她")))
(should (equal 1 (string-distance "ab" "a我b")))
- (should (equal 1 (string-distance "我" "她"))))
+ (should (equal 1 (string-distance "我" "她")))
+
+ ;; correct behaviour with empty strings
+ (should (equal 0 (string-distance "" "")))
+ (should (equal 0 (string-distance "" "" t)))
+ (should (equal 1 (string-distance "x" "")))
+ (should (equal 1 (string-distance "x" "" t)))
+ (should (equal 1 (string-distance "" "x")))
+ (should (equal 1 (string-distance "" "x" t))))
(ert-deftest test-bignum-eql ()
"Test that `eql' works for bignums."
@@ -1106,3 +1181,5 @@
(should (= (line-number-at-pos nil) 11))
(should-error (line-number-at-pos -1))
(should-error (line-number-at-pos 100))))
+
+;;; fns-tests.el ends here
diff --git a/test/src/image-tests.el b/test/src/image-tests.el
new file mode 100644
index 00000000000..2b236086b6f
--- /dev/null
+++ b/test/src/image-tests.el
@@ -0,0 +1,245 @@
+;;; image-tests.el --- Tests for image.c -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Stefan Kangas <stefan@marxist.se>
+
+;; 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:
+
+;; Most of these tests will only run in a GUI session, and not with
+;; "make check". Run them manually in an interactive session with
+;; `M-x eval-buffer' followed by `M-x ert'.
+
+;;; Code:
+
+(require 'ert)
+
+(defmacro image-skip-unless (format)
+ `(skip-unless (and (display-images-p)
+ (image-type-available-p ,format))))
+
+;;;; Images
+
+(defconst image-tests--images
+ `((gif . ,(expand-file-name "test/data/image/black.gif"
+ source-directory))
+ (jpeg . ,(expand-file-name "test/data/image/black.jpg"
+ source-directory))
+ (pbm . ,(find-image '((:file "splash.svg" :type svg))))
+ (png . ,(find-image '((:file "splash.png" :type png))))
+ (svg . ,(find-image '((:file "splash.pbm" :type pbm))))
+ (tiff . ,(expand-file-name
+ "nextstep/GNUstep/Emacs.base/Resources/emacs.tiff"
+ source-directory))
+ (webp . ,(expand-file-name "test/data/image/black.webp"
+ source-directory))
+ (xbm . ,(find-image '((:file "gnus/gnus.xbm" :type xbm))))
+ (xpm . ,(find-image '((:file "splash.xpm" :type xpm))))))
+
+;;;; image-test-size
+
+(ert-deftest image-tests-image-size/gif ()
+ (image-skip-unless 'gif)
+ (pcase (image-size (create-image (cdr (assq 'gif image-tests--images))))
+ (`(,a . ,b)
+ (should (floatp a))
+ (should (floatp b)))))
+
+(ert-deftest image-tests-image-size/jpeg ()
+ (image-skip-unless 'jpeg)
+ (pcase (image-size (create-image (cdr (assq 'jpeg image-tests--images))))
+ (`(,a . ,b)
+ (should (floatp a))
+ (should (floatp b)))))
+
+(ert-deftest image-tests-image-size/pbm ()
+ (image-skip-unless 'pbm)
+ (pcase (image-size (cdr (assq 'pbm image-tests--images)))
+ (`(,a . ,b)
+ (should (floatp a))
+ (should (floatp b)))))
+
+(ert-deftest image-tests-image-size/png ()
+ (image-skip-unless 'png)
+ (pcase (image-size (cdr (assq 'png image-tests--images)))
+ (`(,a . ,b)
+ (should (floatp a))
+ (should (floatp b)))))
+
+(ert-deftest image-tests-image-size/svg ()
+ (image-skip-unless 'svg)
+ (pcase (image-size (cdr (assq 'svg image-tests--images)))
+ (`(,a . ,b)
+ (should (floatp a))
+ (should (floatp b)))))
+
+(ert-deftest image-tests-image-size/tiff ()
+ (image-skip-unless 'tiff)
+ (pcase (image-size (create-image (cdr (assq 'tiff image-tests--images))))
+ (`(,a . ,b)
+ (should (floatp a))
+ (should (floatp b)))))
+
+(ert-deftest image-tests-image-size/webp ()
+ (image-skip-unless 'webp)
+ (pcase (image-size (create-image (cdr (assq 'webp image-tests--images))))
+ (`(,a . ,b)
+ (should (floatp a))
+ (should (floatp b)))))
+
+(ert-deftest image-tests-image-size/xbm ()
+ (image-skip-unless 'xbm)
+ (pcase (image-size (cdr (assq 'xbm image-tests--images)))
+ (`(,a . ,b)
+ (should (floatp a))
+ (should (floatp b)))))
+
+(ert-deftest image-tests-image-size/xpm ()
+ (image-skip-unless 'xpm)
+ (pcase (image-size (cdr (assq 'xpm image-tests--images)))
+ (`(,a . ,b)
+ (should (floatp a))
+ (should (floatp b)))))
+
+(ert-deftest image-tests-image-size/error-on-invalid-spec ()
+ (skip-unless (display-images-p))
+ (should-error (image-size 'invalid-spec)))
+
+(ert-deftest image-tests-image-size/error-on-nongraphical-display ()
+ (skip-unless (not (display-images-p)))
+ (should-error (image-size 'invalid-spec)))
+
+;;;; image-mask-p
+
+(ert-deftest image-tests-image-mask-p/gif ()
+ (image-skip-unless 'gif)
+ (should-not (image-mask-p (create-image
+ (cdr (assq 'gif image-tests--images))))))
+
+(ert-deftest image-tests-image-mask-p/jpeg ()
+ (image-skip-unless 'jpeg)
+ (should-not (image-mask-p (create-image
+ (cdr (assq 'jpeg image-tests--images))))))
+
+(ert-deftest image-tests-image-mask-p/pbm ()
+ (image-skip-unless 'pbm)
+ (should-not (image-mask-p (cdr (assq 'pbm image-tests--images)))))
+
+(ert-deftest image-tests-image-mask-p/png ()
+ (image-skip-unless 'png)
+ (should-not (image-mask-p (cdr (assq 'png image-tests--images)))))
+
+(ert-deftest image-tests-image-mask-p/svg ()
+ (image-skip-unless 'svg)
+ (should-not (image-mask-p (cdr (assq 'svg image-tests--images)))))
+
+(ert-deftest image-tests-image-mask-p/tiff ()
+ (image-skip-unless 'tiff)
+ (should-not (image-mask-p (create-image
+ (cdr (assq 'tiff image-tests--images))))))
+
+(ert-deftest image-tests-image-mask-p/webp ()
+ (image-skip-unless 'webp)
+ (should-not (image-mask-p (create-image
+ (cdr (assq 'webp image-tests--images))))))
+
+(ert-deftest image-tests-image-mask-p/xbm ()
+ (image-skip-unless 'xbm)
+ (should-not (image-mask-p (cdr (assq 'xbm image-tests--images)))))
+
+(ert-deftest image-tests-image-mask-p/xpm ()
+ (image-skip-unless 'xpm)
+ (should-not (image-mask-p (cdr (assq 'xpm image-tests--images)))))
+
+(ert-deftest image-tests-image-mask-p/error-on-invalid-spec ()
+ (skip-unless (display-images-p))
+ (should-error (image-mask-p 'invalid-spec)))
+
+(ert-deftest image-tests-image-mask-p/error-on-nongraphical-display ()
+ (skip-unless (not (display-images-p)))
+ (should-error (image-mask-p (cdr (assq 'xpm image-tests--images)))))
+
+;;;; image-metadata
+
+;; TODO: These tests could be expanded with files that actually
+;; contain metadata.
+
+(ert-deftest image-tests-image-metadata/gif ()
+ (image-skip-unless 'gif)
+ (should-not (image-metadata
+ (create-image (cdr (assq 'gif image-tests--images))))))
+
+(ert-deftest image-tests-image-metadata/jpeg ()
+ (image-skip-unless 'jpeg)
+ (should-not (image-metadata
+ (create-image (cdr (assq 'jpeg image-tests--images))))))
+
+(ert-deftest image-tests-image-metadata/pbm ()
+ (image-skip-unless 'pbm)
+ (should-not (image-metadata (cdr (assq 'pbm image-tests--images)))))
+
+(ert-deftest image-tests-image-metadata/png ()
+ (image-skip-unless 'png)
+ (should-not (image-metadata (cdr (assq 'png image-tests--images)))))
+
+(ert-deftest image-tests-image-metadata/svg ()
+ (image-skip-unless 'svg)
+ (should-not (image-metadata (cdr (assq 'svg image-tests--images)))))
+
+(ert-deftest image-tests-image-metadata/tiff ()
+ (image-skip-unless 'tiff)
+ (should-not (image-metadata
+ (create-image (cdr (assq 'tiff image-tests--images))))))
+
+(ert-deftest image-tests-image-metadata/webp ()
+ (image-skip-unless 'webp)
+ (should-not (image-metadata
+ (create-image (cdr (assq 'webp image-tests--images))))))
+
+(ert-deftest image-tests-image-metadata/xbm ()
+ (image-skip-unless 'xbm)
+ (should-not (image-metadata (cdr (assq 'xbm image-tests--images)))))
+
+(ert-deftest image-tests-image-metadata/xpm ()
+ (image-skip-unless 'xpm)
+ (should-not (image-metadata (cdr (assq 'xpm image-tests--images)))))
+
+(ert-deftest image-tests-image-metadata/nil-on-invalid-spec ()
+ (skip-unless (display-images-p))
+ (should-not (image-metadata 'invalid-spec)))
+
+(ert-deftest image-tests-image-metadata/error-on-nongraphical-display ()
+ (skip-unless (not (display-images-p)))
+ (should-error (image-metadata (cdr (assq 'xpm image-tests--images)))))
+
+;;;; ImageMagick
+
+(ert-deftest image-tests-imagemagick-types ()
+ (skip-unless (fboundp 'imagemagick-types))
+ (when (fboundp 'imagemagick-types)
+ (should (listp (imagemagick-types)))))
+
+;;;; Initialization
+
+(ert-deftest image-tests-init-image-library ()
+ (skip-unless (fboundp 'init-image-library))
+ (should (init-image-library 'pbm)) ; built-in
+ (should (init-image-library 'xpm)) ; built-in
+ (should-not (init-image-library 'invalid-image-type)))
+
+;;; image-tests.el ends here
diff --git a/test/src/indent-tests.el b/test/src/indent-tests.el
index 6a3f1a5c95f..6cfe64c07e4 100644
--- a/test/src/indent-tests.el
+++ b/test/src/indent-tests.el
@@ -57,3 +57,5 @@
(move-to-column 12 t)
(buffer-substring-no-properties 1 14))
"\txxx \tLine")))
+
+;;; indent-tests.el ends here
diff --git a/test/src/inotify-tests.el b/test/src/inotify-tests.el
index 5572c7d7a0f..70330ac8657 100644
--- a/test/src/inotify-tests.el
+++ b/test/src/inotify-tests.el
@@ -24,6 +24,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(declare-function inotify-add-watch "inotify.c" (file-name aspect callback))
(declare-function inotify-rm-watch "inotify.c" (watch-descriptor))
@@ -37,8 +38,7 @@
;; (ert-deftest filewatch-file-watch-aspects-check ()
;; "Test whether `file-watch' properly checks the aspects."
-;; (let ((temp-file (make-temp-file "filewatch-aspects")))
-;; (should (stringp temp-file))
+;; (ert-with-temp-file temp-file
;; (should-error (file-watch temp-file 'wrong nil)
;; :type 'error)
;; (should-error (file-watch temp-file '(modify t) nil)
@@ -50,24 +50,22 @@
(ert-deftest inotify-file-watch-simple ()
"Test if watching a normal file works."
-
(skip-unless (featurep 'inotify))
- (let ((temp-file (make-temp-file "inotify-simple"))
- (events 0))
- (let ((wd
- (inotify-add-watch temp-file t (lambda (_ev)
- (setq events (1+ events))))))
- (unwind-protect
- (progn
- (with-temp-file temp-file
- (insert "Foo\n"))
- (read-event nil nil 5)
- (should (> events 0)))
- (should (inotify-valid-p wd))
- (inotify-rm-watch wd)
- (should-not (inotify-valid-p wd))
- (delete-file temp-file)))))
+ (ert-with-temp-file temp-file
+ (let ((events 0))
+ (let ((wd
+ (inotify-add-watch temp-file t (lambda (_ev)
+ (setq events (1+ events))))))
+ (unwind-protect
+ (progn
+ (with-temp-file temp-file
+ (insert "Foo\n"))
+ (read-event nil nil 5)
+ (should (> events 0)))
+ (should (inotify-valid-p wd))
+ (inotify-rm-watch wd)
+ (should-not (inotify-valid-p wd)))))))
(provide 'inotify-tests)
-;;; inotify-tests.el ends here.
+;;; inotify-tests.el ends here
diff --git a/test/src/keymap-tests.el b/test/src/keymap-tests.el
index a9b0cb502d3..629d6c55849 100644
--- a/test/src/keymap-tests.el
+++ b/test/src/keymap-tests.el
@@ -124,6 +124,55 @@
;; (ert-deftest keymap-lookup-key/accept-default ()
;; ...)
+(ert-deftest keymap-lookup-key/mixed-case ()
+ "Backwards compatibility behaviour (Bug#50752)."
+ (let ((map (make-keymap)))
+ (define-key map [menu-bar foo bar] 'foo)
+ (should (eq (lookup-key map [menu-bar foo bar]) 'foo))
+ (should (eq (lookup-key map [menu-bar Foo Bar]) 'foo)))
+ (let ((map (make-keymap)))
+ (define-key map [menu-bar i-bar] 'foo)
+ (should (eq (lookup-key map [menu-bar I-bar]) 'foo))))
+
+(ert-deftest keymap-lookup-key/mixed-case-multibyte ()
+ "Backwards compatibility behaviour (Bug#50752)."
+ (let ((map (make-keymap)))
+ ;; (downcase "Åäö") => "åäö"
+ (define-key map [menu-bar åäö bar] 'foo)
+ (should (eq (lookup-key map [menu-bar åäö bar]) 'foo))
+ (should (eq (lookup-key map [menu-bar Åäö Bar]) 'foo))
+ ;; (downcase "Γ") => "γ"
+ (define-key map [menu-bar γ bar] 'baz)
+ (should (eq (lookup-key map [menu-bar γ bar]) 'baz))
+ (should (eq (lookup-key map [menu-bar Γ Bar]) 'baz))))
+
+(ert-deftest keymap-lookup-key/menu-non-symbol ()
+ "Test for Bug#51527."
+ (let ((map (make-keymap)))
+ (define-key map [menu-bar buffer 1] 'foo)
+ (should (eq (lookup-key map [menu-bar buffer 1]) 'foo))))
+
+(ert-deftest keymap-lookup-keymap/with-spaces ()
+ "Backwards compatibility behaviour (Bug#50752)."
+ (let ((map (make-keymap)))
+ (define-key map [menu-bar foo-bar] 'foo)
+ (should (eq (lookup-key map [menu-bar Foo\ Bar]) 'foo))))
+
+(ert-deftest keymap-lookup-keymap/with-spaces-multibyte ()
+ "Backwards compatibility behaviour (Bug#50752)."
+ (let ((map (make-keymap)))
+ (define-key map [menu-bar åäö-bar] 'foo)
+ (should (eq (lookup-key map [menu-bar Åäö\ Bar]) 'foo))))
+
+(ert-deftest keymap-lookup-keymap/with-spaces-multibyte-lang-env ()
+ "Backwards compatibility behaviour (Bug#50752)."
+ (let ((lang-env current-language-environment))
+ (set-language-environment "Turkish")
+ (let ((map (make-keymap)))
+ (define-key map [menu-bar i-bar] 'foo)
+ (should (eq (lookup-key map [menu-bar I-bar]) 'foo)))
+ (set-language-environment lang-env)))
+
(ert-deftest describe-buffer-bindings/header-in-current-buffer ()
"Header should be inserted into the current buffer.
https://debbugs.gnu.org/39149#31"
@@ -269,16 +318,17 @@ commit 86c19714b097aa477d339ed99ffb5136c755a046."
(shadow-map (let ((map (make-keymap)))
(define-key map "f" 'bar)
map))
- (text-quoting-style 'grave))
+ (text-quoting-style 'grave)
+ (describe-bindings-check-shadowing-in-ranges 'ignore-self-insert))
(with-temp-buffer
(help--describe-vector (cadr orig-map) nil #'help--describe-command
t shadow-map orig-map t)
- (should (equal (buffer-string)
- "
+ (should (equal (buffer-substring-no-properties (point-min) (point-max))
+ (string-replace "\t" "" "
e foo
f foo (currently shadowed by `bar')
g .. h foo
-")))))
+"))))))
(ert-deftest help--describe-vector/bug-9293-same-command-does-not-shadow ()
"Check that a command can't be shadowed by the same command."
@@ -299,10 +349,10 @@ g .. h foo
(with-temp-buffer
(help--describe-vector (cadr range-map) nil #'help--describe-command
t shadow-map range-map t)
- (should (equal (buffer-string)
- "
+ (should (equal (buffer-substring-no-properties (point-min) (point-max))
+ (string-replace "\t" "" "
0 .. 3 foo
-")))))
+"))))))
(ert-deftest keymap--key-description ()
(should (equal (key-description [right] [?\C-x])
@@ -316,6 +366,47 @@ g .. h foo
(should (equal (single-key-description 'C-s-home)
"C-s-<home>")))
+(ert-deftest keymap-test-lookups ()
+ (should (eq (lookup-key (current-global-map) "\C-x\C-f") 'find-file))
+ (should (eq (lookup-key (current-global-map) [(control x) (control f)])
+ 'find-file))
+ (should (eq (lookup-key (current-global-map) ["C-x C-f"]) 'find-file))
+ (should (eq (lookup-key (current-global-map) [?\C-x ?\C-f]) 'find-file)))
+
+(ert-deftest keymap-removal ()
+ ;; Set to nil.
+ (let ((map (define-keymap "a" 'foo)))
+ (should (equal map '(keymap (97 . foo))))
+ (define-key map "a" nil)
+ (should (equal map '(keymap (97)))))
+ ;; Remove.
+ (let ((map (define-keymap "a" 'foo)))
+ (should (equal map '(keymap (97 . foo))))
+ (define-key map "a" nil t)
+ (should (equal map '(keymap)))))
+
+(ert-deftest keymap-removal-inherit ()
+ ;; Set to nil.
+ (let ((parent (make-sparse-keymap))
+ (child (make-keymap)))
+ (set-keymap-parent child parent)
+ (define-key parent [?a] 'foo)
+ (define-key child [?a] 'bar)
+
+ (should (eq (lookup-key child [?a]) 'bar))
+ (define-key child [?a] nil)
+ (should (eq (lookup-key child [?a]) nil)))
+ ;; Remove.
+ (let ((parent (make-sparse-keymap))
+ (child (make-keymap)))
+ (set-keymap-parent child parent)
+ (define-key parent [?a] 'foo)
+ (define-key child [?a] 'bar)
+
+ (should (eq (lookup-key child [?a]) 'bar))
+ (define-key child [?a] nil t)
+ (should (eq (lookup-key child [?a]) 'foo))))
+
(provide 'keymap-tests)
;;; keymap-tests.el ends here
diff --git a/test/src/lcms-tests.el b/test/src/lcms-tests.el
index 40a48f1e9bb..d2d137e9bd5 100644
--- a/test/src/lcms-tests.el
+++ b/test/src/lcms-tests.el
@@ -95,7 +95,7 @@ B is considered the exact value."
'(0.29902 0.31485 1.0))))
(ert-deftest lcms-roundtrip ()
- "Test accuracy of converting to and from different color spaces"
+ "Test accuracy of converting to and from different color spaces."
(skip-unless (featurep 'lcms2))
(should
(let ((color '(.5 .3 .7)))
@@ -109,7 +109,7 @@ B is considered the exact value."
0.0001))))
(ert-deftest lcms-ciecam02-gold ()
- "Test CIE CAM02 JCh gold values"
+ "Test CIE CAM02 JCh gold values."
(skip-unless (featurep 'lcms2))
(should
(lcms-triple-approx-p
diff --git a/test/src/lread-tests.el b/test/src/lread-tests.el
index dac8f95bc4d..c635c592b28 100644
--- a/test/src/lread-tests.el
+++ b/test/src/lread-tests.el
@@ -115,18 +115,14 @@
(should-error (read "#24r") :type 'invalid-read-syntax)
(should-error (read "#") :type 'invalid-read-syntax))
+(ert-deftest lread-char-modifiers ()
+ (should (eq ?\C-\M-é (+ (- ?\M-a ?a) ?\C-é)))
+ (should (eq (- ?\C-ŗ ?ŗ) (- ?\C-é ?é))))
+
(ert-deftest lread-record-1 ()
(should (equal '(#s(foo) #s(foo))
(read "(#1=#s(foo) #1#)"))))
-(defmacro lread-tests--with-temp-file (file-name-var &rest body)
- (declare (indent 1))
- (cl-check-type file-name-var symbol)
- `(let ((,file-name-var (make-temp-file "emacs")))
- (unwind-protect
- (progn ,@body)
- (delete-file ,file-name-var))))
-
(defun lread-tests--last-message ()
(with-current-buffer "*Messages*"
(save-excursion
@@ -137,7 +133,7 @@
(ert-deftest lread-tests--unescaped-char-literals ()
"Check that loading warns about unescaped character
literals (Bug#20852)."
- (lread-tests--with-temp-file file-name
+ (ert-with-temp-file file-name
(write-region "?) ?( ?; ?\" ?[ ?]" nil file-name)
(should (equal (load file-name nil :nomessage :nosuffix) t))
(should (equal (lread-tests--last-message)
diff --git a/test/src/marker-tests.el b/test/src/marker-tests.el
index 234a0b35ea7..cf8e82cd560 100644
--- a/test/src/marker-tests.el
+++ b/test/src/marker-tests.el
@@ -57,4 +57,4 @@
(set-marker marker-2 marker-1)
(should (goto-char marker-2))))
-;;; marker-tests.el ends here.
+;;; marker-tests.el ends here
diff --git a/test/src/minibuf-tests.el b/test/src/minibuf-tests.el
index c55611eb84b..51d9c67453e 100644
--- a/test/src/minibuf-tests.el
+++ b/test/src/minibuf-tests.el
@@ -406,7 +406,7 @@
(should (equal (try-completion "bar" '("bArfoo" "barbaz"))
(try-completion "bar" '("barbaz" "bArfoo"))))
;; bug#11339
- (should (equal (try-completion "baz" '("baz" "bAz")) "baz")) ;And not `t'!
+ (should (equal (try-completion "baz" '("baz" "bAz")) "baz")) ;And not t!
(should (equal (try-completion "baz" '("bAz" "baz"))
(try-completion "baz" '("baz" "bAz"))))))
@@ -414,8 +414,8 @@
(let ((inhibit-interaction t))
(should-error (read-from-minibuffer "foo: ") :type 'inhibited-interaction)
- (should-error (y-or-n-p "foo: ") :type 'inhibited-interaction)
- (should-error (yes-or-no-p "foo: ") :type 'inhibited-interaction)
+ (should-error (y-or-n-p "Foo?") :type 'inhibited-interaction)
+ (should-error (yes-or-no-p "Foo?") :type 'inhibited-interaction)
(should-error (read-no-blanks-input "foo: ") :type 'inhibited-interaction)
;; See that we get the expected error.
diff --git a/test/src/process-tests.el b/test/src/process-tests.el
index 9bab523708e..f14a460d1a5 100644
--- a/test/src/process-tests.el
+++ b/test/src/process-tests.el
@@ -25,6 +25,7 @@
(require 'cl-lib)
(require 'ert)
+(require 'ert-x) ; ert-with-temp-directory
(require 'puny)
(require 'subr-x)
(require 'dns)
@@ -64,24 +65,22 @@
(when (eq system-type 'windows-nt)
(ert-deftest process-test-quoted-batfile ()
"Check that Emacs hides CreateProcess deficiency (bug#18745)."
- (let (batfile)
- (unwind-protect
- (progn
- ;; CreateProcess will fail when both the bat file and 1st
- ;; argument are quoted, so include spaces in both of those
- ;; to force quoting.
- (setq batfile (make-temp-file "echo args" nil ".bat"))
- (with-temp-file batfile
- (insert "@echo arg1=%1, arg2=%2\n"))
- (with-temp-buffer
- (call-process batfile nil '(t t) t "x &y")
- (should (string= (buffer-string) "arg1=\"x &y\", arg2=\n")))
- (with-temp-buffer
- (call-process-shell-command
- (mapconcat #'shell-quote-argument (list batfile "x &y") " ")
- nil '(t t) t)
- (should (string= (buffer-string) "arg1=\"x &y\", arg2=\n"))))
- (when batfile (delete-file batfile))))))
+ (ert-with-temp-file batfile
+ ;; CreateProcess will fail when both the bat file and 1st
+ ;; argument are quoted, so include spaces in both of those
+ ;; to force quoting.
+ :prefix "echo args"
+ :suffix ".bat"
+ (with-temp-file batfile
+ (insert "@echo arg1=%1, arg2=%2\n"))
+ (with-temp-buffer
+ (call-process batfile nil '(t t) t "x &y")
+ (should (string= (buffer-string) "arg1=\"x &y\", arg2=\n")))
+ (with-temp-buffer
+ (call-process-shell-command
+ (mapconcat #'shell-quote-argument (list batfile "x &y") " ")
+ nil '(t t) t)
+ (should (string= (buffer-string) "arg1=\"x &y\", arg2=\n"))))))
(ert-deftest process-test-stderr-buffer ()
(skip-unless (executable-find "bash"))
@@ -531,18 +530,6 @@ FD_SETSIZE."
(delete-process (pop ,processes))
,@body)))))
-(defmacro process-tests--with-temp-directory (var &rest body)
- "Bind VAR to the name of a new directory and evaluate BODY.
-Afterwards, delete the directory."
- (declare (indent 1) (debug (symbolp body)))
- (cl-check-type var symbol)
- (let ((dir (make-symbol "dir")))
- `(let ((,dir (make-temp-file "emacs-test-" :dir)))
- (unwind-protect
- (let ((,var ,dir))
- ,@body)
- (delete-directory ,dir :recursive)))))
-
;; Tests for FD_SETSIZE overflow (Bug#24325). The following tests
;; generate lots of process objects of the various kinds. Running the
;; tests with assertions enabled should not result in any crashes due
@@ -630,7 +617,7 @@ FD_SETSIZE file descriptors (Bug#24325)."
;; Avoid hang due to connect/accept handshake on Cygwin (bug#49496).
(skip-unless (not (eq system-type 'cygwin)))
(with-timeout (60 (ert-fail "Test timed out"))
- (process-tests--with-temp-directory directory
+ (ert-with-temp-directory directory
(process-tests--with-processes processes
(let* ((num-clients 10)
(socket-name (expand-file-name "socket" directory))
@@ -745,7 +732,7 @@ Return nil if that can't be determined."
process-tests--EMFILE-message)
(ert-deftest process-tests/sentinel-called ()
- "Check that sentinels are called after processes finish"
+ "Check that sentinels are called after processes finish."
(let ((command (process-tests--emacs-command)))
(skip-unless command)
(dolist (conn-type '(pipe pty))
@@ -800,6 +787,7 @@ have written output."
(list (list process "finished\n"))))))))))
(ert-deftest process-tests/multiple-threads-waiting ()
+ :tags (if (getenv "EMACS_EMBA_CI") '(:unstable))
(skip-unless (fboundp 'make-thread))
(with-timeout (60 (ert-fail "Test timed out"))
(process-tests--with-processes processes
@@ -946,5 +934,11 @@ Return nil if FILENAME doesn't exist."
(when buf
(kill-buffer buf)))))
+(ert-deftest process-num-processors ()
+ "Sanity checks for num-processors."
+ (should (equal (num-processors) (num-processors)))
+ (should (integerp (num-processors)))
+ (should (< 0 (num-processors))))
+
(provide 'process-tests)
;;; process-tests.el ends here
diff --git a/test/src/regex-emacs-tests.el b/test/src/regex-emacs-tests.el
index 0607eacf397..71e3189443e 100644
--- a/test/src/regex-emacs-tests.el
+++ b/test/src/regex-emacs-tests.el
@@ -279,11 +279,11 @@ on success"
(defconst regex-tests-re-even-escapes
"\\(?:^\\|[^\\]\\)\\(?:\\\\\\\\\\)*"
- "Regex that matches an even number of \\ characters")
+ "Regex that matches an even number of \\ characters.")
(defconst regex-tests-re-odd-escapes
(concat regex-tests-re-even-escapes "\\\\")
- "Regex that matches an odd number of \\ characters")
+ "Regex that matches an odd number of \\ characters.")
(defun regex-tests-unextend (pattern)
@@ -396,9 +396,9 @@ pattern)"
;; emacs matches non-greedy regex ab.*? non-greedily
639 677 712
]
- "Line numbers in the boost test that should be skipped. These
-are false-positive test failures that represent known/benign
-differences in behavior.")
+ "Line numbers in the boost test that should be skipped.
+These are false-positive test failures that represent
+known/benign differences in behavior.")
;; - Format
;; - Comments are lines starting with ;
@@ -480,9 +480,9 @@ differences in behavior.")
;; ambiguous groupings are ambiguous
610 611 1154 1157 1160 1168 1171 1176 1179 1182 1185 1188 1193 1196 1203
]
- "Line numbers in the PCRE test that should be skipped. These
-are false-positive test failures that represent known/benign
-differences in behavior.")
+ "Line numbers in the PCRE test that should be skipped.
+These are false-positive test failures that represent
+known/benign differences in behavior.")
;; - Format
;;
@@ -562,9 +562,9 @@ differences in behavior.")
;; fails to match
168
]
- "Line numbers in the PTESTS test that should be skipped. These
-are false-positive test failures that represent known/benign
-differences in behavior.")
+ "Line numbers in the PTESTS test that should be skipped.
+These are false-positive test failures that represent
+known/benign differences in behavior.")
;; - Format
;; - fields separated by ¦ (note: this is not a |)
@@ -621,9 +621,9 @@ differences in behavior.")
;; emacs is more stringent with regexes involving unbalanced )
67
]
- "Line numbers in the TESTS test that should be skipped. These
-are false-positive test failures that represent known/benign
-differences in behavior.")
+ "Line numbers in the TESTS test that should be skipped.
+These are false-positive test failures that represent
+known/benign differences in behavior.")
;; - Format
;; - fields separated by :. Watch for [\[:xxx:]]
diff --git a/test/src/search-tests.el b/test/src/search-tests.el
index b7b4ab9a8ff..b5f4730f265 100644
--- a/test/src/search-tests.el
+++ b/test/src/search-tests.el
@@ -28,7 +28,7 @@
(setq ov-set (make-overlay 3 5))
(overlay-put
ov-set 'modification-hooks
- (list (lambda (o after &rest _args)
+ (list (lambda (_o after &rest _args)
(when after
(let ((inhibit-modification-hooks t))
(save-excursion
diff --git a/test/src/sqlite-tests.el b/test/src/sqlite-tests.el
new file mode 100644
index 00000000000..27ba74e9d23
--- /dev/null
+++ b/test/src/sqlite-tests.el
@@ -0,0 +1,218 @@
+;;; sqlite-tests.el --- Tests for sqlite.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 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 'ert-x)
+
+(declare-function sqlite-execute "sqlite.c")
+(declare-function sqlite-close "sqlite.c")
+(declare-function sqlitep "sqlite.c")
+(declare-function sqlite-available-p "sqlite.c")
+(declare-function sqlite-finalize "sqlite.c")
+(declare-function sqlite-next "sqlite.c")
+(declare-function sqlite-more-p "sqlite.c")
+(declare-function sqlite-select "sqlite.c")
+(declare-function sqlite-open "sqlite.c")
+
+(ert-deftest sqlite-select ()
+ (skip-unless (sqlite-available-p))
+ (let ((db (sqlite-open)))
+ (should (eq (type-of db) 'sqlite))
+ (should (sqlitep db))
+ (should-not (sqlitep 'foo))
+
+ (should
+ (zerop
+ (sqlite-execute
+ db "create table if not exists test1 (col1 text, col2 integer, col3 float, col4 blob)")))
+
+ (should-error
+ (sqlite-execute
+ db "insert into test1 (col1, col2, col3, col4) values ('foo', 2, 9.45, 'bar', 'zot')"))
+
+ (should
+ (=
+ (sqlite-execute
+ db "insert into test1 (col1, col2, col3, col4) values ('foo', 2, 9.45, 'bar')")
+ 1))
+
+ (should
+ (equal
+ (sqlite-select db "select * from test1" nil 'full)
+ '(("col1" "col2" "col3" "col4") ("foo" 2 9.45 "bar"))))))
+
+(ert-deftest sqlite-set ()
+ (skip-unless (sqlite-available-p))
+ (let ((db (sqlite-open))
+ set)
+ (should
+ (zerop
+ (sqlite-execute
+ db "create table if not exists test1 (col1 text, col2 integer)")))
+
+ (should
+ (=
+ (sqlite-execute db "insert into test1 (col1, col2) values ('foo', 1)")
+ 1))
+ (should
+ (=
+ (sqlite-execute db "insert into test1 (col1, col2) values ('bar', 2)")
+ 1))
+
+ (setq set (sqlite-select db "select * from test1" nil 'set))
+ (should (sqlitep set))
+ (should (sqlite-more-p set))
+ (should (equal (sqlite-next set)
+ '("foo" 1)))
+ (should (equal (sqlite-next set)
+ '("bar" 2)))
+ (should-not (sqlite-next set))
+ (should-not (sqlite-more-p set))
+ (sqlite-finalize set)
+ (should-error (sqlite-next set))))
+
+(ert-deftest sqlite-chars ()
+ (skip-unless (sqlite-available-p))
+ (let (db)
+ (setq db (sqlite-open))
+ (sqlite-execute
+ db "create table if not exists test2 (col1 text, col2 integer)")
+ (sqlite-execute
+ db "insert into test2 (col1, col2) values ('fóo', 3)")
+ (sqlite-execute
+ db "insert into test2 (col1, col2) values ('fó‚o', 3)")
+ (sqlite-execute
+ db "insert into test2 (col1, col2) values ('f‚o', 4)")
+ (should
+ (equal (sqlite-select db "select * from test2" nil 'full)
+ '(("col1" "col2") ("fóo" 3) ("fó‚o" 3) ("f‚o" 4))))))
+
+(ert-deftest sqlite-numbers ()
+ (skip-unless (sqlite-available-p))
+ (let (db)
+ (setq db (sqlite-open))
+ (sqlite-execute
+ db "create table if not exists test3 (col1 integer)")
+ (let ((big (expt 2 50))
+ (small (expt 2 10)))
+ (sqlite-execute db (format "insert into test3 values (%d)" small))
+ (sqlite-execute db (format "insert into test3 values (%d)" big))
+ (should
+ (equal
+ (sqlite-select db "select * from test3")
+ (list (list small) (list big)))))))
+
+(ert-deftest sqlite-param ()
+ (skip-unless (sqlite-available-p))
+ (let (db)
+ (setq db (sqlite-open))
+ (sqlite-execute
+ db "create table if not exists test4 (col1 text, col2 number)")
+ (sqlite-execute db "insert into test4 values (?, ?)" (list "foo" 1))
+ (should
+ (equal
+ (sqlite-select db "select * from test4 where col2 = ?" '(1))
+ '(("foo" 1))))
+ (should
+ (equal
+ (sqlite-select db "select * from test4 where col2 = ?" [1])
+ '(("foo" 1))))))
+
+(ert-deftest sqlite-binary ()
+ (skip-unless (sqlite-available-p))
+ (let (db)
+ (setq db (sqlite-open))
+ (sqlite-execute
+ db "create table if not exists test5 (col1 text, col2 number)")
+ (let ((string (with-temp-buffer
+ (set-buffer-multibyte nil)
+ (insert 0 1 2)
+ (buffer-string))))
+ (should-not (multibyte-string-p string))
+ (sqlite-execute
+ db "insert into test5 values (?, ?)" (list string 2))
+ (let ((out (caar
+ (sqlite-select db "select col1 from test5 where col2 = 2"))))
+ (should (equal out string))))))
+
+(ert-deftest sqlite-different-dbs ()
+ (skip-unless (sqlite-available-p))
+ (let (db1 db2)
+ (setq db1 (sqlite-open))
+ (setq db2 (sqlite-open))
+ (sqlite-execute
+ db1 "create table if not exists test6 (col1 text, col2 number)")
+ (sqlite-execute
+ db2 "create table if not exists test6 (col1 text, col2 number)")
+ (sqlite-execute
+ db1 "insert into test6 values (?, ?)" '("foo" 2))
+ (should (sqlite-select db1 "select * from test6"))
+ (should-not (sqlite-select db2 "select * from test6"))))
+
+(ert-deftest sqlite-close-dbs ()
+ (skip-unless (sqlite-available-p))
+ (let (db)
+ (setq db (sqlite-open))
+ (sqlite-execute
+ db "create table if not exists test6 (col1 text, col2 number)")
+ (sqlite-execute db "insert into test6 values (?, ?)" '("foo" 2))
+ (should (sqlite-select db "select * from test6"))
+ (sqlite-close db)
+ (should-error (sqlite-select db "select * from test6"))))
+
+(ert-deftest sqlite-load-extension ()
+ (skip-unless (sqlite-available-p))
+ (skip-unless (fboundp 'sqlite-load-extension))
+ (let (db)
+ (setq db (sqlite-open))
+ (should-error
+ (sqlite-load-extension db "/usr/lib/sqlite3/notpcre.so"))
+ (should-error
+ (sqlite-load-extension db "/usr/lib/sqlite3/n"))
+ (should-error
+ (sqlite-load-extension db "/usr/lib/sqlite3/"))
+ (should-error
+ (sqlite-load-extension db "/usr/lib/sqlite3"))
+ (should
+ (memq
+ (sqlite-load-extension db "/usr/lib/sqlite3/pcre.so")
+ '(nil t)))
+
+ (should-error
+ (sqlite-load-extension
+ db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_notcsvtable.so"))
+ (should-error
+ (sqlite-load-extension
+ db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtablen.so"))
+ (should-error
+ (sqlite-load-extension
+ db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable"))
+ (should
+ (memq
+ (sqlite-load-extension
+ db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable.so")
+ '(nil t)))))
+
+;;; sqlite-tests.el ends here
diff --git a/test/src/syntax-tests.el b/test/src/syntax-tests.el
index e4e3054d37a..bd89283dd14 100644
--- a/test/src/syntax-tests.el
+++ b/test/src/syntax-tests.el
@@ -500,4 +500,10 @@ the `parse-partial-sexp's are expected to stop. See
(syntax-pps-comments /* 56 76 77 58)
(syntax-pps-comments /* 60 78 79)
+(ert-deftest test-from-to-parse-partial-sexp ()
+ (with-temp-buffer
+ (insert "foo")
+ (should (parse-partial-sexp 1 1))
+ (should-error (parse-partial-sexp 2 1))))
+
;;; syntax-tests.el ends here
diff --git a/test/src/textprop-tests.el b/test/src/textprop-tests.el
index b083588e645..c001579c474 100644
--- a/test/src/textprop-tests.el
+++ b/test/src/textprop-tests.el
@@ -69,4 +69,4 @@
(null stack)))))
(provide 'textprop-tests)
-;; textprop-tests.el ends here.
+;;; textprop-tests.el ends here
diff --git a/test/src/thread-tests.el b/test/src/thread-tests.el
index fc7bc7441b7..52eace7e9d2 100644
--- a/test/src/thread-tests.el
+++ b/test/src/thread-tests.el
@@ -70,12 +70,12 @@
(thread-live-p (make-thread #'ignore))))
(ert-deftest threads-all-threads ()
- "Simple test for all-threads."
+ "Simple test for `all-threads'."
(skip-unless (featurep 'threads))
(should (listp (all-threads))))
(ert-deftest threads-main-thread ()
- "Simple test for all-threads."
+ "Simple test for `all-threads'."
(skip-unless (featurep 'threads))
(should (eq main-thread (car (all-threads)))))
@@ -155,7 +155,7 @@
(should (eq (type-of (make-mutex)) 'mutex)))
(ert-deftest threads-mutex-lock-unlock ()
- "Test mutex-lock and unlock."
+ "Test `mutex-lock' and unlock."
(skip-unless (featurep 'threads))
(should
(let ((mx (make-mutex)))
@@ -392,4 +392,4 @@
(let ((th (make-thread 'ignore)))
(should-not (equal th main-thread))))
-;;; threads.el ends here
+;;; thread-tests.el ends here
diff --git a/test/src/timefns-tests.el b/test/src/timefns-tests.el
index 0a450a7573f..f801478a9a1 100644
--- a/test/src/timefns-tests.el
+++ b/test/src/timefns-tests.el
@@ -241,3 +241,17 @@ a fixed place on the right and are padded on the left."
(let ((xdiv (/ x divisor)))
(should (= xdiv (float-time (time-convert xdiv t))))))
(setq x (* x 2)))))
+
+(ert-deftest time-convert-forms ()
+ ;; These computations involve numbers that should have exact
+ ;; representations on any Emacs platform.
+ (dolist (time '(-86400 -1 0 1 86400))
+ (dolist (delta '(0 0.0 0.25 3.25 1000 1000.25))
+ (let ((time+ (+ time delta))
+ (time- (- time delta)))
+ (dolist (form '(nil t list 4 1000 1000000 1000000000))
+ (should (time-equal-p time (time-convert time form)))
+ (should (time-equal-p time- (time-convert time- form)))
+ (should (time-equal-p time+ (time-convert time+ form))))))))
+
+;;; timefns-tests.el ends here
diff --git a/test/src/undo-tests.el b/test/src/undo-tests.el
index a658bccf6dc..88fcfad14cc 100644
--- a/test/src/undo-tests.el
+++ b/test/src/undo-tests.el
@@ -46,6 +46,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'facemenu)
(ert-deftest undo-test0 ()
@@ -218,17 +219,14 @@
(ert-deftest undo-test-file-modified ()
"Test undoing marks buffer visiting file unmodified."
- (let ((tempfile (make-temp-file "undo-test")))
- (unwind-protect
- (progn
- (with-current-buffer (find-file-noselect tempfile)
- (insert "1")
- (undo-boundary)
- (set-buffer-modified-p nil)
- (insert "2")
- (undo)
- (should-not (buffer-modified-p))))
- (delete-file tempfile))))
+ (ert-with-temp-file tempfile
+ (with-current-buffer (find-file-noselect tempfile)
+ (insert "1")
+ (undo-boundary)
+ (set-buffer-modified-p nil)
+ (insert "2")
+ (undo)
+ (should-not (buffer-modified-p)))))
(ert-deftest undo-test-region-not-most-recent ()
"Test undo in region of an edit not the most recent."
diff --git a/test/src/xdisp-tests.el b/test/src/xdisp-tests.el
index 4e7d2ad8ab2..ae4aacd9c7c 100644
--- a/test/src/xdisp-tests.el
+++ b/test/src/xdisp-tests.el
@@ -99,4 +99,75 @@
(width-in-chars (/ (car size) char-width)))
(should (equal width-in-chars 3)))))
+(ert-deftest xdisp-tests--find-directional-overrides-case-1 ()
+ (with-temp-buffer
+ (insert "\
+int main() {
+ bool isAdmin = false;
+ /*‮ }⁦if (isAdmin)⁩ ⁦ begin admins only */
+ printf(\"You are an admin.\\n\");
+ /* end admins only ‮ { ⁦*/
+ return 0;
+}")
+ (goto-char (point-min))
+ (should (eq (bidi-find-overridden-directionality (point-min) (point-max)
+ nil)
+ 46))))
+
+(ert-deftest xdisp-tests--find-directional-overrides-case-2 ()
+ (with-temp-buffer
+ (insert "\
+#define is_restricted_user(user) \\
+ !strcmp (user, \"root\") ? 0 : \\
+ !strcmp (user, \"admin\") ? 0 : \\
+ !strcmp (user, \"superuser‮⁦? 0 : 1⁩ ⁦\")⁩‬
+
+int main () {
+ printf (\"root: %d\\n\", is_restricted_user (\"root\"));
+ printf (\"admin: %d\\n\", is_restricted_user (\"admin\"));
+ printf (\"superuser: %d\\n\", is_restricted_user (\"superuser\"));
+ printf (\"luser: %d\\n\", is_restricted_user (\"luser\"));
+ printf (\"nobody: %d\\n\", is_restricted_user (\"nobody\"));
+}")
+ (goto-char (point-min))
+ (should (eq (bidi-find-overridden-directionality (point-min) (point-max)
+ nil)
+ 138))))
+
+(ert-deftest xdisp-tests--find-directional-overrides-case-3 ()
+ (with-temp-buffer
+ (insert "\
+#define is_restricted_user(user) \\
+ !strcmp (user, \"root\") ? 0 : \\
+ !strcmp (user, \"admin\") ? 0 : \\
+ !strcmp (user, \"superuser‮⁦? '#' : '!'⁩ ⁦\")⁩‬
+
+int main () {
+ printf (\"root: %d\\n\", is_restricted_user (\"root\"));
+ printf (\"admin: %d\\n\", is_restricted_user (\"admin\"));
+ printf (\"superuser: %d\\n\", is_restricted_user (\"superuser\"));
+ printf (\"luser: %d\\n\", is_restricted_user (\"luser\"));
+ printf (\"nobody: %d\\n\", is_restricted_user (\"nobody\"));
+}")
+ (goto-char (point-min))
+ (should (eq (bidi-find-overridden-directionality (point-min) (point-max)
+ nil)
+ 138))))
+
+(ert-deftest test-get-display-property ()
+ (with-temp-buffer
+ (insert (propertize "foo" 'face 'bold 'display '(height 2.0)))
+ (should (equal (get-display-property 2 'height) 2.0)))
+ (with-temp-buffer
+ (insert (propertize "foo" 'face 'bold 'display '((height 2.0)
+ (space-width 2.0))))
+ (should (equal (get-display-property 2 'height) 2.0))
+ (should (equal (get-display-property 2 'space-width) 2.0)))
+ (with-temp-buffer
+ (insert (propertize "foo bar" 'face 'bold
+ 'display '[(height 2.0)
+ (space-width 20)]))
+ (should (equal (get-display-property 2 'height) 2.0))
+ (should (equal (get-display-property 2 'space-width) 20))))
+
;;; xdisp-tests.el ends here
diff --git a/test/src/xfaces-tests.el b/test/src/xfaces-tests.el
index 0a7ef55b2b6..cba706f4535 100644
--- a/test/src/xfaces-tests.el
+++ b/test/src/xfaces-tests.el
@@ -17,6 +17,8 @@
;; 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)
(ert-deftest xfaces-color-distance ()
@@ -48,3 +50,5 @@
(should (equal (color-values-from-color-spec "rgbi:0/0.5/10") nil)))
(provide 'xfaces-tests)
+
+;;; xfaces-tests.el ends here
diff --git a/test/src/xml-tests.el b/test/src/xml-tests.el
index a35b4d2ccc8..7c4ca396f70 100644
--- a/test/src/xml-tests.el
+++ b/test/src/xml-tests.el
@@ -52,4 +52,4 @@
(should (equal (cdr test)
(libxml-parse-xml-region (point-min) (point-max)))))))
-;;; libxml-tests.el ends here
+;;; xml-tests.el ends here